summaryrefslogtreecommitdiff
path: root/nss/lib
diff options
context:
space:
mode:
Diffstat (limited to 'nss/lib')
-rw-r--r--nss/lib/Makefile40
-rw-r--r--nss/lib/base/arena.c1213
-rw-r--r--nss/lib/base/base.gyp32
-rw-r--r--nss/lib/base/base.h602
-rw-r--r--nss/lib/base/baset.h39
-rw-r--r--nss/lib/base/error.c196
-rw-r--r--nss/lib/base/errorval.c3
-rw-r--r--nss/lib/base/exports.gyp33
-rw-r--r--nss/lib/base/hash.c345
-rw-r--r--nss/lib/base/hashops.c70
-rw-r--r--nss/lib/base/item.c162
-rw-r--r--nss/lib/base/libc.c111
-rw-r--r--nss/lib/base/list.c263
-rw-r--r--nss/lib/base/nssbase.h95
-rw-r--r--nss/lib/base/nssbaset.h21
-rw-r--r--nss/lib/base/tracker.c345
-rw-r--r--nss/lib/base/utf8.c887
-rw-r--r--nss/lib/certdb/alg1485.c1750
-rw-r--r--nss/lib/certdb/cert.h968
-rw-r--r--nss/lib/certdb/certdb.c2970
-rw-r--r--nss/lib/certdb/certdb.gyp34
-rw-r--r--nss/lib/certdb/certdb.h77
-rw-r--r--nss/lib/certdb/certi.h204
-rw-r--r--nss/lib/certdb/certt.h791
-rw-r--r--nss/lib/certdb/certv3.c143
-rw-r--r--nss/lib/certdb/certxutl.c406
-rw-r--r--nss/lib/certdb/certxutl.h32
-rw-r--r--nss/lib/certdb/crl.c1993
-rw-r--r--nss/lib/certdb/exports.gyp36
-rw-r--r--nss/lib/certdb/genname.c1639
-rw-r--r--nss/lib/certdb/genname.h83
-rw-r--r--nss/lib/certdb/polcyxtn.c681
-rw-r--r--nss/lib/certdb/secname.c700
-rw-r--r--nss/lib/certdb/stanpcertdb.c835
-rw-r--r--nss/lib/certdb/xauthkid.c154
-rw-r--r--nss/lib/certdb/xbsconst.c184
-rw-r--r--nss/lib/certdb/xconst.c189
-rw-r--r--nss/lib/certdb/xconst.h28
-rw-r--r--nss/lib/certhigh/certhigh.c1256
-rw-r--r--nss/lib/certhigh/certhigh.gyp31
-rw-r--r--nss/lib/certhigh/certhtml.c419
-rw-r--r--nss/lib/certhigh/certreq.c193
-rw-r--r--nss/lib/certhigh/certvfy.c2457
-rw-r--r--nss/lib/certhigh/certvfypkix.c1450
-rw-r--r--nss/lib/certhigh/crlv2.c94
-rw-r--r--nss/lib/certhigh/exports.gyp33
-rw-r--r--nss/lib/certhigh/ocsp.c2889
-rw-r--r--nss/lib/certhigh/ocsp.h107
-rw-r--r--nss/lib/certhigh/ocspi.h38
-rw-r--r--nss/lib/certhigh/ocspsig.c371
-rw-r--r--nss/lib/certhigh/ocspt.h128
-rw-r--r--nss/lib/certhigh/ocspti.h113
-rw-r--r--nss/lib/certhigh/xcrldist.c316
-rw-r--r--nss/lib/ckfw/builtins/Makefile2
-rw-r--r--nss/lib/ckfw/builtins/anchor.c2
-rw-r--r--nss/lib/ckfw/builtins/bfind.c392
-rw-r--r--nss/lib/ckfw/builtins/binst.c100
-rw-r--r--nss/lib/ckfw/builtins/bobject.c290
-rw-r--r--nss/lib/ckfw/builtins/bsession.c98
-rw-r--r--nss/lib/ckfw/builtins/bslot.c104
-rw-r--r--nss/lib/ckfw/builtins/btoken.c194
-rw-r--r--nss/lib/ckfw/builtins/builtins.gyp61
-rw-r--r--nss/lib/ckfw/builtins/builtins.h66
-rw-r--r--nss/lib/ckfw/builtins/certdata.perl12
-rw-r--r--nss/lib/ckfw/builtins/certdata.txt6247
-rw-r--r--nss/lib/ckfw/builtins/ckbiver.c3
-rw-r--r--nss/lib/ckfw/builtins/config.mk4
-rw-r--r--nss/lib/ckfw/builtins/constants.c53
-rw-r--r--nss/lib/ckfw/builtins/exports.gyp25
-rw-r--r--nss/lib/ckfw/builtins/nssckbi.h8
-rw-r--r--nss/lib/ckfw/capi/anchor.c2
-rw-r--r--nss/lib/ckfw/capi/cfind.c925
-rw-r--r--nss/lib/ckfw/capi/cinst.c118
-rw-r--r--nss/lib/ckfw/capi/ckcapi.h255
-rw-r--r--nss/lib/ckfw/capi/ckcapiver.c3
-rw-r--r--nss/lib/ckfw/capi/cobject.c3667
-rw-r--r--nss/lib/ckfw/capi/constants.c41
-rw-r--r--nss/lib/ckfw/capi/crsa.c1110
-rw-r--r--nss/lib/ckfw/capi/csession.c124
-rw-r--r--nss/lib/ckfw/capi/cslot.c104
-rw-r--r--nss/lib/ckfw/capi/ctoken.c266
-rw-r--r--nss/lib/ckfw/capi/nsscapi.h4
-rw-r--r--nss/lib/ckfw/capi/staticobj.c23
-rw-r--r--nss/lib/ckfw/ckfw.gyp34
-rw-r--r--nss/lib/ckfw/ckfw.h1621
-rw-r--r--nss/lib/ckfw/ckfwm.h66
-rw-r--r--nss/lib/ckfw/ckfwtm.h2
-rw-r--r--nss/lib/ckfw/ckmd.h26
-rw-r--r--nss/lib/ckfw/crypto.c408
-rw-r--r--nss/lib/ckfw/dbm/anchor.c2
-rw-r--r--nss/lib/ckfw/dbm/ckdbm.h252
-rw-r--r--nss/lib/ckfw/dbm/db.c1728
-rw-r--r--nss/lib/ckfw/dbm/find.c203
-rw-r--r--nss/lib/ckfw/dbm/instance.c220
-rw-r--r--nss/lib/ckfw/dbm/object.c246
-rw-r--r--nss/lib/ckfw/dbm/session.c422
-rw-r--r--nss/lib/ckfw/dbm/slot.c244
-rw-r--r--nss/lib/ckfw/dbm/token.c378
-rw-r--r--nss/lib/ckfw/exports.gyp44
-rw-r--r--nss/lib/ckfw/find.c437
-rw-r--r--nss/lib/ckfw/hash.c302
-rw-r--r--nss/lib/ckfw/instance.c1608
-rw-r--r--nss/lib/ckfw/mechanism.c1280
-rw-r--r--nss/lib/ckfw/mutex.c231
-rw-r--r--nss/lib/ckfw/nssckfw.h284
-rw-r--r--nss/lib/ckfw/nssckfwc.h880
-rw-r--r--nss/lib/ckfw/nssckfwt.h3
-rw-r--r--nss/lib/ckfw/nssckmdt.h3521
-rw-r--r--nss/lib/ckfw/nssckt.h1
-rw-r--r--nss/lib/ckfw/nssmkey/ckmk.h206
-rw-r--r--nss/lib/ckfw/nssmkey/ckmkver.c3
-rw-r--r--nss/lib/ckfw/nssmkey/manchor.c2
-rw-r--r--nss/lib/ckfw/nssmkey/mconstants.c41
-rw-r--r--nss/lib/ckfw/nssmkey/mfind.c591
-rw-r--r--nss/lib/ckfw/nssmkey/minst.c118
-rw-r--r--nss/lib/ckfw/nssmkey/mobject.c2921
-rw-r--r--nss/lib/ckfw/nssmkey/mrsa.c773
-rw-r--r--nss/lib/ckfw/nssmkey/msession.c124
-rw-r--r--nss/lib/ckfw/nssmkey/mslot.c104
-rw-r--r--nss/lib/ckfw/nssmkey/mtoken.c266
-rw-r--r--nss/lib/ckfw/nssmkey/nssmkey.h4
-rw-r--r--nss/lib/ckfw/nssmkey/staticobj.c18
-rw-r--r--nss/lib/ckfw/object.c1199
-rw-r--r--nss/lib/ckfw/session.c3282
-rw-r--r--nss/lib/ckfw/sessobj.c1341
-rw-r--r--nss/lib/ckfw/slot.c779
-rw-r--r--nss/lib/ckfw/token.c2140
-rw-r--r--nss/lib/ckfw/wrap.c9734
-rw-r--r--nss/lib/crmf/asn1cmn.c202
-rw-r--r--nss/lib/crmf/challcli.c170
-rw-r--r--nss/lib/crmf/cmmf.h504
-rw-r--r--nss/lib/crmf/cmmfasn1.c85
-rw-r--r--nss/lib/crmf/cmmfchal.c184
-rw-r--r--nss/lib/crmf/cmmfi.h84
-rw-r--r--nss/lib/crmf/cmmfit.h83
-rw-r--r--nss/lib/crmf/cmmfrec.c204
-rw-r--r--nss/lib/crmf/cmmfresp.c197
-rw-r--r--nss/lib/crmf/cmmft.h24
-rw-r--r--nss/lib/crmf/crmf.gyp43
-rw-r--r--nss/lib/crmf/crmf.h591
-rw-r--r--nss/lib/crmf/crmfcont.c973
-rw-r--r--nss/lib/crmf/crmfdec.c315
-rw-r--r--nss/lib/crmf/crmfenc.c45
-rw-r--r--nss/lib/crmf/crmffut.h172
-rw-r--r--nss/lib/crmf/crmfget.c305
-rw-r--r--nss/lib/crmf/crmfi.h145
-rw-r--r--nss/lib/crmf/crmfit.h140
-rw-r--r--nss/lib/crmf/crmfpop.c459
-rw-r--r--nss/lib/crmf/crmfreq.c519
-rw-r--r--nss/lib/crmf/crmft.h68
-rw-r--r--nss/lib/crmf/crmftmpl.c191
-rw-r--r--nss/lib/crmf/encutil.c13
-rw-r--r--nss/lib/crmf/exports.gyp37
-rw-r--r--nss/lib/crmf/respcli.c75
-rw-r--r--nss/lib/crmf/respcmn.c329
-rw-r--r--nss/lib/crmf/servget.c580
-rw-r--r--nss/lib/cryptohi/cryptohi.gyp27
-rw-r--r--nss/lib/cryptohi/cryptohi.h110
-rw-r--r--nss/lib/cryptohi/cryptoht.h1
-rw-r--r--nss/lib/cryptohi/dsautil.c138
-rw-r--r--nss/lib/cryptohi/exports.gyp37
-rw-r--r--nss/lib/cryptohi/keyhi.h80
-rw-r--r--nss/lib/cryptohi/keyi.h10
-rw-r--r--nss/lib/cryptohi/keythi.h91
-rw-r--r--nss/lib/cryptohi/manifest.mn3
-rw-r--r--nss/lib/cryptohi/sechash.c443
-rw-r--r--nss/lib/cryptohi/sechash.h44
-rw-r--r--nss/lib/cryptohi/seckey.c1998
-rw-r--r--nss/lib/cryptohi/secsign.c451
-rw-r--r--nss/lib/cryptohi/secvfy.c767
-rw-r--r--nss/lib/dbm/include/exports.gyp38
-rw-r--r--nss/lib/dbm/include/extern.h54
-rw-r--r--nss/lib/dbm/include/hash.h416
-rw-r--r--nss/lib/dbm/include/hsearch.h19
-rw-r--r--nss/lib/dbm/include/include.gyp12
-rw-r--r--nss/lib/dbm/include/mcom_db.h317
-rw-r--r--nss/lib/dbm/include/ncompat.h180
-rw-r--r--nss/lib/dbm/include/page.h63
-rw-r--r--nss/lib/dbm/include/queue.h335
-rw-r--r--nss/lib/dbm/include/search.h19
-rw-r--r--nss/lib/dbm/include/winfile.h71
-rw-r--r--nss/lib/dbm/src/db.c100
-rw-r--r--nss/lib/dbm/src/dirent.c432
-rw-r--r--nss/lib/dbm/src/dirent.h66
-rw-r--r--nss/lib/dbm/src/h_bigkey.c1064
-rw-r--r--nss/lib/dbm/src/h_func.c212
-rw-r--r--nss/lib/dbm/src/h_log2.c18
-rw-r--r--nss/lib/dbm/src/h_page.c1876
-rw-r--r--nss/lib/dbm/src/hash.c1683
-rw-r--r--nss/lib/dbm/src/hash_buf.c579
-rw-r--r--nss/lib/dbm/src/memmove.c145
-rw-r--r--nss/lib/dbm/src/mktemp.c138
-rw-r--r--nss/lib/dbm/src/snprintf.c33
-rw-r--r--nss/lib/dbm/src/src.gyp40
-rw-r--r--nss/lib/dbm/src/strerror.c53
-rw-r--r--nss/lib/dbm/tests/lots.c677
-rw-r--r--nss/lib/dev/ckhelper.c580
-rw-r--r--nss/lib/dev/ckhelper.h149
-rw-r--r--nss/lib/dev/dev.gyp26
-rw-r--r--nss/lib/dev/dev.h873
-rw-r--r--nss/lib/dev/devm.h202
-rw-r--r--nss/lib/dev/devslot.c178
-rw-r--r--nss/lib/dev/devt.h89
-rw-r--r--nss/lib/dev/devtm.h2
-rw-r--r--nss/lib/dev/devtoken.c1451
-rw-r--r--nss/lib/dev/devutil.c993
-rw-r--r--nss/lib/dev/exports.gyp31
-rw-r--r--nss/lib/dev/nssdev.h12
-rw-r--r--nss/lib/freebl/Makefile100
-rw-r--r--nss/lib/freebl/aeskeywrap.c358
-rw-r--r--nss/lib/freebl/alg2268.c428
-rw-r--r--nss/lib/freebl/alghmac.c76
-rw-r--r--nss/lib/freebl/alghmac.h34
-rw-r--r--nss/lib/freebl/arcfive.c19
-rw-r--r--nss/lib/freebl/arcfour.c811
-rw-r--r--nss/lib/freebl/blapi.h1201
-rw-r--r--nss/lib/freebl/blapii.h32
-rw-r--r--nss/lib/freebl/blapit.h337
-rw-r--r--nss/lib/freebl/blname.c100
-rw-r--r--nss/lib/freebl/camellia.c2090
-rw-r--r--nss/lib/freebl/camellia.h25
-rw-r--r--nss/lib/freebl/chacha20.c119
-rw-r--r--nss/lib/freebl/chacha20.h26
-rw-r--r--nss/lib/freebl/chacha20_vec.c327
-rw-r--r--nss/lib/freebl/chacha20poly1305.c198
-rw-r--r--nss/lib/freebl/chacha20poly1305.h15
-rw-r--r--nss/lib/freebl/ctr.c175
-rw-r--r--nss/lib/freebl/ctr.h34
-rw-r--r--nss/lib/freebl/cts.c122
-rw-r--r--nss/lib/freebl/cts.h14
-rw-r--r--nss/lib/freebl/des.c995
-rw-r--r--nss/lib/freebl/des.h18
-rw-r--r--nss/lib/freebl/desblapi.c261
-rw-r--r--nss/lib/freebl/det_rng.c67
-rw-r--r--nss/lib/freebl/det_rng.h12
-rw-r--r--nss/lib/freebl/dh.c322
-rw-r--r--nss/lib/freebl/drbg.c1045
-rw-r--r--nss/lib/freebl/dsa.c398
-rw-r--r--nss/lib/freebl/ec.c832
-rw-r--r--nss/lib/freebl/ec.h14
-rw-r--r--nss/lib/freebl/ecdecode.c551
-rw-r--r--nss/lib/freebl/ecl/Makefile195
-rw-r--r--nss/lib/freebl/ecl/README30
-rw-r--r--nss/lib/freebl/ecl/README.FP284
-rw-r--r--nss/lib/freebl/ecl/curve25519_32.c390
-rw-r--r--nss/lib/freebl/ecl/curve25519_64.c514
-rw-r--r--nss/lib/freebl/ecl/ec2.h92
-rw-r--r--nss/lib/freebl/ecl/ec2_163.c223
-rw-r--r--nss/lib/freebl/ecl/ec2_193.c240
-rw-r--r--nss/lib/freebl/ecl/ec2_233.c263
-rw-r--r--nss/lib/freebl/ecl/ec2_aff.c312
-rw-r--r--nss/lib/freebl/ecl/ec2_mont.c238
-rw-r--r--nss/lib/freebl/ecl/ec2_proj.c333
-rw-r--r--nss/lib/freebl/ecl/ec_naf.c85
-rw-r--r--nss/lib/freebl/ecl/ecl-curve.h183
-rw-r--r--nss/lib/freebl/ecl/ecl-exp.h275
-rw-r--r--nss/lib/freebl/ecl/ecl-priv.h271
-rw-r--r--nss/lib/freebl/ecl/ecl.c537
-rw-r--r--nss/lib/freebl/ecl/ecl.h27
-rw-r--r--nss/lib/freebl/ecl/ecl_curve.c122
-rw-r--r--nss/lib/freebl/ecl/ecl_gf.c1569
-rw-r--r--nss/lib/freebl/ecl/ecl_mult.c489
-rw-r--r--nss/lib/freebl/ecl/ecp.h50
-rw-r--r--nss/lib/freebl/ecl/ecp_192.c493
-rw-r--r--nss/lib/freebl/ecl/ecp_224.c352
-rw-r--r--nss/lib/freebl/ecl/ecp_25519.c120
-rw-r--r--nss/lib/freebl/ecl/ecp_256.c673
-rw-r--r--nss/lib/freebl/ecl/ecp_256_32.c1215
-rw-r--r--nss/lib/freebl/ecl/ecp_384.c416
-rw-r--r--nss/lib/freebl/ecl/ecp_521.c178
-rw-r--r--nss/lib/freebl/ecl/ecp_aff.c465
-rw-r--r--nss/lib/freebl/ecl/ecp_fp.c531
-rw-r--r--nss/lib/freebl/ecl/ecp_fp.h372
-rw-r--r--nss/lib/freebl/ecl/ecp_fp160.c145
-rw-r--r--nss/lib/freebl/ecl/ecp_fp192.c143
-rw-r--r--nss/lib/freebl/ecl/ecp_fp224.c156
-rw-r--r--nss/lib/freebl/ecl/ecp_fpinc.c821
-rw-r--r--nss/lib/freebl/ecl/ecp_jac.c864
-rw-r--r--nss/lib/freebl/ecl/ecp_jm.c444
-rw-r--r--nss/lib/freebl/ecl/ecp_mont.c179
-rw-r--r--nss/lib/freebl/ecl/tests/ec2_test.c482
-rw-r--r--nss/lib/freebl/ecl/tests/ec_naft.c178
-rw-r--r--nss/lib/freebl/ecl/tests/ecp_fpt.c1088
-rw-r--r--nss/lib/freebl/ecl/tests/ecp_test.c683
-rw-r--r--nss/lib/freebl/ecl/uint128.c87
-rw-r--r--nss/lib/freebl/ecl/uint128.h35
-rw-r--r--nss/lib/freebl/exports.gyp48
-rw-r--r--nss/lib/freebl/fipsfreebl.c1715
-rw-r--r--nss/lib/freebl/freebl.gyp408
-rw-r--r--nss/lib/freebl/freebl_hash_vector.def34
-rw-r--r--nss/lib/freebl/gcm.c566
-rw-r--r--nss/lib/freebl/gcm.h18
-rw-r--r--nss/lib/freebl/genload.c36
-rw-r--r--nss/lib/freebl/hmacct.c215
-rw-r--r--nss/lib/freebl/intel-aes.h229
-rw-r--r--nss/lib/freebl/intel-aes.s284
-rw-r--r--nss/lib/freebl/intel-gcm-wrap.c91
-rw-r--r--nss/lib/freebl/intel-gcm.h54
-rw-r--r--nss/lib/freebl/jpake.c254
-rw-r--r--nss/lib/freebl/ldvector.c600
-rw-r--r--nss/lib/freebl/loader.c2406
-rw-r--r--nss/lib/freebl/loader.h1256
-rw-r--r--nss/lib/freebl/lowhash_vector.c217
-rw-r--r--nss/lib/freebl/manifest.mn43
-rw-r--r--nss/lib/freebl/md2.c397
-rw-r--r--nss/lib/freebl/md5.c752
-rw-r--r--nss/lib/freebl/mknewpc2.c226
-rw-r--r--nss/lib/freebl/mksp.c142
-rw-r--r--nss/lib/freebl/mpi/README9
-rw-r--r--nss/lib/freebl/mpi/logtab.h35
-rw-r--r--nss/lib/freebl/mpi/mdxptest.c234
-rw-r--r--nss/lib/freebl/mpi/montmulf.c441
-rw-r--r--nss/lib/freebl/mpi/montmulf.h22
-rw-r--r--nss/lib/freebl/mpi/mp_comba.c4391
-rw-r--r--nss/lib/freebl/mpi/mp_gf2m-priv.h48
-rw-r--r--nss/lib/freebl/mpi/mp_gf2m.c447
-rw-r--r--nss/lib/freebl/mpi/mp_gf2m.h12
-rw-r--r--nss/lib/freebl/mpi/mpcpucache.c884
-rw-r--r--nss/lib/freebl/mpi/mpcpucache_x86.s1
-rw-r--r--nss/lib/freebl/mpi/mpi-config.h36
-rw-r--r--nss/lib/freebl/mpi/mpi-priv.h237
-rw-r--r--nss/lib/freebl/mpi/mpi-test.c1952
-rw-r--r--nss/lib/freebl/mpi/mpi.c5804
-rw-r--r--nss/lib/freebl/mpi/mpi.h237
-rw-r--r--nss/lib/freebl/mpi/mpi_amd64.c24
-rw-r--r--nss/lib/freebl/mpi/mpi_arm.c242
-rw-r--r--nss/lib/freebl/mpi/mpi_hp.c65
-rw-r--r--nss/lib/freebl/mpi/mpi_sparc.c288
-rw-r--r--nss/lib/freebl/mpi/mpi_x86_asm.c526
-rw-r--r--nss/lib/freebl/mpi/mplogic.c455
-rw-r--r--nss/lib/freebl/mpi/mplogic.h14
-rw-r--r--nss/lib/freebl/mpi/mpmontg.c1915
-rw-r--r--nss/lib/freebl/mpi/mpprime.c725
-rw-r--r--nss/lib/freebl/mpi/mpprime.h24
-rw-r--r--nss/lib/freebl/mpi/mpv_sparc.c273
-rw-r--r--nss/lib/freebl/mpi/mpvalpha.c266
-rw-r--r--nss/lib/freebl/mpi/mulsqr.c131
-rw-r--r--nss/lib/freebl/mpi/primes.c1643
-rw-r--r--nss/lib/freebl/mpi/target.mk4
-rw-r--r--nss/lib/freebl/mpi/test-arrays.txt1
-rw-r--r--nss/lib/freebl/mpi/test-info.c161
-rw-r--r--nss/lib/freebl/mpi/tests/mptest-1.c27
-rw-r--r--nss/lib/freebl/mpi/tests/mptest-2.c77
-rw-r--r--nss/lib/freebl/mpi/tests/mptest-3.c147
-rw-r--r--nss/lib/freebl/mpi/tests/mptest-3a.c188
-rw-r--r--nss/lib/freebl/mpi/tests/mptest-4.c124
-rw-r--r--nss/lib/freebl/mpi/tests/mptest-4a.c154
-rw-r--r--nss/lib/freebl/mpi/tests/mptest-4b.c111
-rw-r--r--nss/lib/freebl/mpi/tests/mptest-5.c97
-rw-r--r--nss/lib/freebl/mpi/tests/mptest-5a.c207
-rw-r--r--nss/lib/freebl/mpi/tests/mptest-6.c82
-rw-r--r--nss/lib/freebl/mpi/tests/mptest-7.c113
-rw-r--r--nss/lib/freebl/mpi/tests/mptest-8.c61
-rw-r--r--nss/lib/freebl/mpi/tests/mptest-9.c150
-rw-r--r--nss/lib/freebl/mpi/tests/mptest-b.c184
-rw-r--r--nss/lib/freebl/mpi/utils/basecvt.c75
-rw-r--r--nss/lib/freebl/mpi/utils/bbs_rand.c64
-rw-r--r--nss/lib/freebl/mpi/utils/bbs_rand.h4
-rw-r--r--nss/lib/freebl/mpi/utils/bbsrand.c23
-rw-r--r--nss/lib/freebl/mpi/utils/dec2hex.c34
-rw-r--r--nss/lib/freebl/mpi/utils/exptmod.c69
-rw-r--r--nss/lib/freebl/mpi/utils/fact.c92
-rw-r--r--nss/lib/freebl/mpi/utils/gcd.c121
-rw-r--r--nss/lib/freebl/mpi/utils/hex2dec.c34
-rw-r--r--nss/lib/freebl/mpi/utils/identest.c105
-rw-r--r--nss/lib/freebl/mpi/utils/invmod.c88
-rw-r--r--nss/lib/freebl/mpi/utils/isprime.c117
-rw-r--r--nss/lib/freebl/mpi/utils/lap.c104
-rw-r--r--nss/lib/freebl/mpi/utils/makeprime.c140
-rw-r--r--nss/lib/freebl/mpi/utils/metime.c148
-rw-r--r--nss/lib/freebl/mpi/utils/pi.c211
-rw-r--r--nss/lib/freebl/mpi/utils/primegen.c235
-rw-r--r--nss/lib/freebl/mpi/utils/prng.c50
-rw-r--r--nss/lib/freebl/mpi/utils/sieve.c288
-rw-r--r--nss/lib/freebl/mpi/vis_proto.h66
-rw-r--r--nss/lib/freebl/nsslowhash.c352
-rw-r--r--nss/lib/freebl/nsslowhash.h18
-rw-r--r--nss/lib/freebl/os2_rand.c349
-rw-r--r--nss/lib/freebl/poly1305-donna-x64-sse2-incremental-source.c881
-rw-r--r--nss/lib/freebl/poly1305.c314
-rw-r--r--nss/lib/freebl/poly1305.h28
-rw-r--r--nss/lib/freebl/pqg.c1735
-rw-r--r--nss/lib/freebl/pqg.h2
-rw-r--r--nss/lib/freebl/rawhash.c203
-rw-r--r--nss/lib/freebl/rijndael.c1166
-rw-r--r--nss/lib/freebl/rijndael.h18
-rw-r--r--nss/lib/freebl/rijndael_tables.c194
-rw-r--r--nss/lib/freebl/rsa.c1632
-rw-r--r--nss/lib/freebl/rsapkcs.c481
-rw-r--r--nss/lib/freebl/secmpi.h52
-rw-r--r--nss/lib/freebl/secrng.h2
-rw-r--r--nss/lib/freebl/seed.c781
-rw-r--r--nss/lib/freebl/seed.h139
-rw-r--r--nss/lib/freebl/sha256.h8
-rw-r--r--nss/lib/freebl/sha512.c1616
-rw-r--r--nss/lib/freebl/sha_fast.c548
-rw-r--r--nss/lib/freebl/sha_fast.h158
-rw-r--r--nss/lib/freebl/shsign.h8
-rw-r--r--nss/lib/freebl/shvfy.c324
-rw-r--r--nss/lib/freebl/stubs.c338
-rw-r--r--nss/lib/freebl/stubs.h58
-rw-r--r--nss/lib/freebl/sysrand.c26
-rw-r--r--nss/lib/freebl/tlsprfalg.c74
-rw-r--r--nss/lib/freebl/unix_rand.c665
-rw-r--r--nss/lib/freebl/win_rand.c78
-rw-r--r--nss/lib/jar/exports.gyp27
-rw-r--r--nss/lib/jar/jar-ds.c14
-rw-r--r--nss/lib/jar/jar-ds.h67
-rw-r--r--nss/lib/jar/jar.c785
-rw-r--r--nss/lib/jar/jar.gyp76
-rw-r--r--nss/lib/jar/jar.h149
-rw-r--r--nss/lib/jar/jarfile.c968
-rw-r--r--nss/lib/jar/jarfile.h102
-rw-r--r--nss/lib/jar/jarint.c20
-rw-r--r--nss/lib/jar/jarint.h35
-rw-r--r--nss/lib/jar/jarnav.c35
-rw-r--r--nss/lib/jar/jarsign.c169
-rw-r--r--nss/lib/jar/jarver.c1005
-rw-r--r--nss/lib/jar/jzconf.h174
-rw-r--r--nss/lib/jar/jzlib.h284
-rw-r--r--nss/lib/libpkix/include/exports.gyp38
-rw-r--r--nss/lib/libpkix/include/include.gyp12
-rwxr-xr-xnss/lib/libpkix/include/pkix_errorstrings.h3
-rw-r--r--nss/lib/libpkix/pkix/certsel/certsel.gyp24
-rw-r--r--nss/lib/libpkix/pkix/certsel/exports.gyp26
-rw-r--r--nss/lib/libpkix/pkix/checker/checker.gyp35
-rw-r--r--nss/lib/libpkix/pkix/checker/exports.gyp37
-rw-r--r--nss/lib/libpkix/pkix/crlsel/crlsel.gyp24
-rw-r--r--nss/lib/libpkix/pkix/crlsel/exports.gyp26
-rw-r--r--nss/lib/libpkix/pkix/params/exports.gyp28
-rw-r--r--nss/lib/libpkix/pkix/params/params.gyp26
-rw-r--r--nss/lib/libpkix/pkix/results/exports.gyp28
-rw-r--r--nss/lib/libpkix/pkix/results/results.gyp26
-rw-r--r--nss/lib/libpkix/pkix/store/exports.gyp25
-rw-r--r--nss/lib/libpkix/pkix/store/store.gyp23
-rw-r--r--nss/lib/libpkix/pkix/top/exports.gyp27
-rwxr-xr-xnss/lib/libpkix/pkix/top/pkix_build.c12
-rw-r--r--nss/lib/libpkix/pkix/top/top.gyp25
-rw-r--r--nss/lib/libpkix/pkix/util/exports.gyp28
-rwxr-xr-xnss/lib/libpkix/pkix/util/pkix_tools.h4
-rw-r--r--nss/lib/libpkix/pkix/util/util.gyp27
-rw-r--r--nss/lib/libpkix/pkix_pl_nss/module/exports.gyp36
-rw-r--r--nss/lib/libpkix/pkix_pl_nss/module/module.gyp41
-rw-r--r--nss/lib/libpkix/pkix_pl_nss/module/pkix_pl_aiamgr.c2
-rwxr-xr-xnss/lib/libpkix/pkix_pl_nss/module/pkix_pl_httpcertstore.c6
-rw-r--r--nss/lib/libpkix/pkix_pl_nss/module/pkix_pl_socket.c2
-rw-r--r--nss/lib/libpkix/pkix_pl_nss/pki/exports.gyp41
-rw-r--r--nss/lib/libpkix/pkix_pl_nss/pki/pki.gyp39
-rw-r--r--nss/lib/libpkix/pkix_pl_nss/system/exports.gyp37
-rwxr-xr-xnss/lib/libpkix/pkix_pl_nss/system/pkix_pl_lifecycle.c4
-rw-r--r--nss/lib/libpkix/pkix_pl_nss/system/system.gyp36
-rw-r--r--nss/lib/manifest.mn45
-rw-r--r--nss/lib/nss/config.mk12
-rw-r--r--nss/lib/nss/exports.gyp32
-rw-r--r--nss/lib/nss/nss.def7
-rw-r--r--nss/lib/nss/nss.gyp83
-rw-r--r--nss/lib/nss/nss.h212
-rw-r--r--nss/lib/nss/nssinit.c1017
-rw-r--r--nss/lib/nss/nssoptions.c83
-rw-r--r--nss/lib/nss/nssoptions.h3
-rw-r--r--nss/lib/nss/utilwrap.c372
-rw-r--r--nss/lib/pk11wrap/debug_module.c2935
-rw-r--r--nss/lib/pk11wrap/dev3hack.c160
-rw-r--r--nss/lib/pk11wrap/dev3hack.h2
-rw-r--r--nss/lib/pk11wrap/exports.gyp39
-rw-r--r--nss/lib/pk11wrap/pk11akey.c2872
-rw-r--r--nss/lib/pk11wrap/pk11auth.c649
-rw-r--r--nss/lib/pk11wrap/pk11cert.c2375
-rw-r--r--nss/lib/pk11wrap/pk11cxt.c859
-rw-r--r--nss/lib/pk11wrap/pk11err.c182
-rw-r--r--nss/lib/pk11wrap/pk11kea.c157
-rw-r--r--nss/lib/pk11wrap/pk11list.c40
-rw-r--r--nss/lib/pk11wrap/pk11load.c666
-rw-r--r--nss/lib/pk11wrap/pk11mech.c2918
-rw-r--r--nss/lib/pk11wrap/pk11merge.c1228
-rw-r--r--nss/lib/pk11wrap/pk11nobj.c597
-rw-r--r--nss/lib/pk11wrap/pk11obj.c1728
-rw-r--r--nss/lib/pk11wrap/pk11pars.c1619
-rw-r--r--nss/lib/pk11wrap/pk11pbe.c1347
-rw-r--r--nss/lib/pk11wrap/pk11pk12.c515
-rw-r--r--nss/lib/pk11wrap/pk11pqg.c370
-rw-r--r--nss/lib/pk11wrap/pk11pqg.h67
-rw-r--r--nss/lib/pk11wrap/pk11priv.h121
-rw-r--r--nss/lib/pk11wrap/pk11pub.h604
-rw-r--r--nss/lib/pk11wrap/pk11sdr.c570
-rw-r--r--nss/lib/pk11wrap/pk11skey.c2743
-rw-r--r--nss/lib/pk11wrap/pk11slot.c1981
-rw-r--r--nss/lib/pk11wrap/pk11util.c1246
-rw-r--r--nss/lib/pk11wrap/pk11wrap.gyp51
-rw-r--r--nss/lib/pk11wrap/secmod.h128
-rw-r--r--nss/lib/pk11wrap/secmodi.h97
-rw-r--r--nss/lib/pk11wrap/secmodt.h214
-rw-r--r--nss/lib/pk11wrap/secmodti.h168
-rw-r--r--nss/lib/pk11wrap/secpkcs5.h9
-rw-r--r--nss/lib/pkcs12/exports.gyp29
-rw-r--r--nss/lib/pkcs12/p12.h162
-rw-r--r--nss/lib/pkcs12/p12creat.c150
-rw-r--r--nss/lib/pkcs12/p12d.c3368
-rw-r--r--nss/lib/pkcs12/p12dec.c650
-rw-r--r--nss/lib/pkcs12/p12e.c2142
-rw-r--r--nss/lib/pkcs12/p12exp.c1552
-rw-r--r--nss/lib/pkcs12/p12local.c1522
-rw-r--r--nss/lib/pkcs12/p12local.h33
-rw-r--r--nss/lib/pkcs12/p12plcy.c111
-rw-r--r--nss/lib/pkcs12/p12t.h26
-rw-r--r--nss/lib/pkcs12/p12tmpl.c207
-rw-r--r--nss/lib/pkcs12/pkcs12.gyp29
-rw-r--r--nss/lib/pkcs12/pkcs12.h29
-rw-r--r--nss/lib/pkcs12/pkcs12t.h295
-rw-r--r--nss/lib/pkcs7/certread.c575
-rw-r--r--nss/lib/pkcs7/exports.gyp33
-rw-r--r--nss/lib/pkcs7/p7common.c765
-rw-r--r--nss/lib/pkcs7/p7create.c1048
-rw-r--r--nss/lib/pkcs7/p7decode.c2119
-rw-r--r--nss/lib/pkcs7/p7encode.c1324
-rw-r--r--nss/lib/pkcs7/p7local.c1164
-rw-r--r--nss/lib/pkcs7/p7local.h70
-rw-r--r--nss/lib/pkcs7/pkcs7.gyp29
-rw-r--r--nss/lib/pkcs7/pkcs7t.h106
-rw-r--r--nss/lib/pkcs7/secmime.c752
-rw-r--r--nss/lib/pkcs7/secmime.h23
-rw-r--r--nss/lib/pkcs7/secpkcs7.h242
-rw-r--r--nss/lib/pki/asymmkey.c325
-rw-r--r--nss/lib/pki/certdecode.c55
-rw-r--r--nss/lib/pki/certificate.c1114
-rw-r--r--nss/lib/pki/cryptocontext.c841
-rw-r--r--nss/lib/pki/exports.gyp32
-rw-r--r--nss/lib/pki/nsspki.h2291
-rw-r--r--nss/lib/pki/nsspkit.h44
-rw-r--r--nss/lib/pki/pki.gyp32
-rw-r--r--nss/lib/pki/pki.h190
-rw-r--r--nss/lib/pki/pki3hack.c1197
-rw-r--r--nss/lib/pki/pki3hack.h91
-rw-r--r--nss/lib/pki/pkibase.c1269
-rw-r--r--nss/lib/pki/pkim.h534
-rw-r--r--nss/lib/pki/pkistore.c522
-rw-r--r--nss/lib/pki/pkistore.h150
-rw-r--r--nss/lib/pki/pkit.h27
-rw-r--r--nss/lib/pki/pkitm.h42
-rw-r--r--nss/lib/pki/symmkey.c232
-rw-r--r--nss/lib/pki/tdcache.c1003
-rw-r--r--nss/lib/pki/trustdomain.c1127
-rw-r--r--nss/lib/smime/cms.h180
-rw-r--r--nss/lib/smime/cmsarray.c91
-rw-r--r--nss/lib/smime/cmsasn1.c386
-rw-r--r--nss/lib/smime/cmsattr.c236
-rw-r--r--nss/lib/smime/cmscinfo.c244
-rw-r--r--nss/lib/smime/cmscipher.c553
-rw-r--r--nss/lib/smime/cmsdecode.c759
-rw-r--r--nss/lib/smime/cmsdigdata.c56
-rw-r--r--nss/lib/smime/cmsdigest.c163
-rw-r--r--nss/lib/smime/cmsencdata.c96
-rw-r--r--nss/lib/smime/cmsencode.c728
-rw-r--r--nss/lib/smime/cmsenvdata.c143
-rw-r--r--nss/lib/smime/cmslocal.h64
-rw-r--r--nss/lib/smime/cmsmessage.c112
-rw-r--r--nss/lib/smime/cmspubkey.c106
-rw-r--r--nss/lib/smime/cmsrecinfo.c655
-rw-r--r--nss/lib/smime/cmsreclist.c185
-rw-r--r--nss/lib/smime/cmsreclist.h19
-rw-r--r--nss/lib/smime/cmssigdata.c638
-rw-r--r--nss/lib/smime/cmssiginfo.c795
-rw-r--r--nss/lib/smime/cmst.h285
-rw-r--r--nss/lib/smime/cmsudf.c262
-rw-r--r--nss/lib/smime/cmsutil.c266
-rw-r--r--nss/lib/smime/exports.gyp34
-rw-r--r--nss/lib/smime/smime.gyp80
-rw-r--r--nss/lib/smime/smime.h23
-rw-r--r--nss/lib/smime/smimemessage.c71
-rw-r--r--nss/lib/smime/smimesym.c8
-rw-r--r--nss/lib/smime/smimeutil.c616
-rw-r--r--nss/lib/softoken/Makefile10
-rw-r--r--nss/lib/softoken/exports.gyp38
-rw-r--r--nss/lib/softoken/fipsaudt.c312
-rw-r--r--nss/lib/softoken/fipstest.c2460
-rw-r--r--nss/lib/softoken/fipstokn.c1419
-rw-r--r--nss/lib/softoken/jpakesftk.c97
-rw-r--r--nss/lib/softoken/legacydb/cdbhdl.h28
-rw-r--r--nss/lib/softoken/legacydb/dbmshim.c347
-rw-r--r--nss/lib/softoken/legacydb/keydb.c1979
-rw-r--r--nss/lib/softoken/legacydb/keydbi.h27
-rw-r--r--nss/lib/softoken/legacydb/legacydb.gyp66
-rw-r--r--nss/lib/softoken/legacydb/lgattr.c2006
-rw-r--r--nss/lib/softoken/legacydb/lgcreate.c918
-rw-r--r--nss/lib/softoken/legacydb/lgdb.h120
-rw-r--r--nss/lib/softoken/legacydb/lgdestroy.c145
-rw-r--r--nss/lib/softoken/legacydb/lgfind.c1075
-rw-r--r--nss/lib/softoken/legacydb/lgfips.c115
-rw-r--r--nss/lib/softoken/legacydb/lginit.c462
-rw-r--r--nss/lib/softoken/legacydb/lgutil.c230
-rw-r--r--nss/lib/softoken/legacydb/lowcert.c838
-rw-r--r--nss/lib/softoken/legacydb/lowkey.c367
-rw-r--r--nss/lib/softoken/legacydb/lowkeyi.h85
-rw-r--r--nss/lib/softoken/legacydb/lowkeyti.h35
-rw-r--r--nss/lib/softoken/legacydb/manifest.mn7
-rw-r--r--nss/lib/softoken/legacydb/nssdbm.def6
-rw-r--r--nss/lib/softoken/legacydb/pcert.h99
-rw-r--r--nss/lib/softoken/legacydb/pcertdb.c4877
-rw-r--r--nss/lib/softoken/legacydb/pcertt.h270
-rw-r--r--nss/lib/softoken/legacydb/pk11db.c714
-rw-r--r--nss/lib/softoken/lgglue.c298
-rw-r--r--nss/lib/softoken/lgglue.h67
-rw-r--r--nss/lib/softoken/lowkey.c542
-rw-r--r--nss/lib/softoken/lowkeyi.h15
-rw-r--r--nss/lib/softoken/lowkeyti.h29
-rw-r--r--nss/lib/softoken/lowpbe.c1513
-rw-r--r--nss/lib/softoken/lowpbe.h41
-rw-r--r--nss/lib/softoken/manifest.mn6
-rw-r--r--nss/lib/softoken/padbuf.c20
-rw-r--r--nss/lib/softoken/pkcs11.c4700
-rw-r--r--nss/lib/softoken/pkcs11c.c9709
-rw-r--r--nss/lib/softoken/pkcs11i.h593
-rw-r--r--nss/lib/softoken/pkcs11ni.h1
-rw-r--r--nss/lib/softoken/pkcs11u.c1462
-rw-r--r--nss/lib/softoken/sdb.c1608
-rw-r--r--nss/lib/softoken/sdb.h87
-rw-r--r--nss/lib/softoken/sftkdb.c2505
-rw-r--r--nss/lib/softoken/sftkdb.h34
-rw-r--r--nss/lib/softoken/sftkdbt.h2
-rw-r--r--nss/lib/softoken/sftkdbti.h34
-rw-r--r--nss/lib/softoken/sftkhmac.c104
-rw-r--r--nss/lib/softoken/sftkpars.c305
-rw-r--r--nss/lib/softoken/sftkpars.h9
-rw-r--r--nss/lib/softoken/sftkpwd.c843
-rw-r--r--nss/lib/softoken/softkver.h16
-rw-r--r--nss/lib/softoken/softoken.gyp71
-rw-r--r--nss/lib/softoken/softoken.h145
-rw-r--r--nss/lib/softoken/softokn.def6
-rw-r--r--nss/lib/softoken/softoknt.h8
-rw-r--r--nss/lib/softoken/tlsprf.c205
-rw-r--r--nss/lib/sqlite/Makefile1
-rw-r--r--nss/lib/sqlite/README2
-rw-r--r--nss/lib/sqlite/exports.gyp25
-rw-r--r--nss/lib/sqlite/sqlite.gyp50
-rw-r--r--nss/lib/sqlite/sqlite3.c98760
-rw-r--r--nss/lib/sqlite/sqlite3.h3112
-rw-r--r--nss/lib/ssl/Makefile16
-rw-r--r--nss/lib/ssl/SSLerrs.h581
-rw-r--r--nss/lib/ssl/authcert.c124
-rw-r--r--nss/lib/ssl/cmpcert.c121
-rw-r--r--nss/lib/ssl/config.mk38
-rw-r--r--nss/lib/ssl/derive.c896
-rw-r--r--nss/lib/ssl/dhe-param.c15
-rw-r--r--nss/lib/ssl/dtlscon.c506
-rw-r--r--nss/lib/ssl/exports.gyp29
-rw-r--r--nss/lib/ssl/manifest.mn72
-rw-r--r--nss/lib/ssl/notes.txt116
-rw-r--r--nss/lib/ssl/os2_err.c200
-rw-r--r--nss/lib/ssl/os2_err.h4
-rw-r--r--nss/lib/ssl/preenc.h112
-rw-r--r--nss/lib/ssl/prelib.c12
-rw-r--r--nss/lib/ssl/ssl.def36
-rw-r--r--nss/lib/ssl/ssl.gyp98
-rw-r--r--nss/lib/ssl/ssl.h676
-rw-r--r--nss/lib/ssl/ssl3con.c16724
-rw-r--r--nss/lib/ssl/ssl3ecc.c1365
-rw-r--r--nss/lib/ssl/ssl3ext.c2788
-rw-r--r--nss/lib/ssl/ssl3ext.h156
-rw-r--r--nss/lib/ssl/ssl3exthandle.c2579
-rw-r--r--nss/lib/ssl/ssl3exthandle.h95
-rw-r--r--nss/lib/ssl/ssl3gthr.c650
-rw-r--r--nss/lib/ssl/ssl3prot.h248
-rw-r--r--nss/lib/ssl/sslauth.c251
-rw-r--r--nss/lib/ssl/sslcert.c992
-rw-r--r--nss/lib/ssl/sslcert.h59
-rw-r--r--nss/lib/ssl/sslcon.c3615
-rw-r--r--nss/lib/ssl/ssldef.c146
-rw-r--r--nss/lib/ssl/sslenum.c59
-rw-r--r--nss/lib/ssl/sslerr.c32
-rw-r--r--nss/lib/ssl/sslerr.h424
-rw-r--r--nss/lib/ssl/sslerrstrs.c12
-rw-r--r--nss/lib/ssl/sslgathr.c425
-rw-r--r--nss/lib/ssl/sslgrp.c164
-rw-r--r--nss/lib/ssl/sslimpl.h2418
-rw-r--r--nss/lib/ssl/sslinfo.c591
-rw-r--r--nss/lib/ssl/sslinit.c46
-rw-r--r--nss/lib/ssl/sslmutex.c356
-rw-r--r--nss/lib/ssl/sslmutex.h58
-rw-r--r--nss/lib/ssl/sslnonce.c331
-rw-r--r--nss/lib/ssl/sslproto.h180
-rw-r--r--nss/lib/ssl/sslreveal.c146
-rw-r--r--nss/lib/ssl/sslsecur.c1258
-rw-r--r--nss/lib/ssl/sslsnce.c2022
-rw-r--r--nss/lib/ssl/sslsock.c2947
-rw-r--r--nss/lib/ssl/sslt.h344
-rw-r--r--nss/lib/ssl/ssltrace.c257
-rw-r--r--nss/lib/ssl/tls13con.c4509
-rw-r--r--nss/lib/ssl/tls13con.h88
-rw-r--r--nss/lib/ssl/tls13exthandle.c1169
-rw-r--r--nss/lib/ssl/tls13exthandle.h74
-rw-r--r--nss/lib/ssl/tls13hkdf.c270
-rw-r--r--nss/lib/ssl/tls13hkdf.h38
-rw-r--r--nss/lib/ssl/unix_err.c716
-rw-r--r--nss/lib/ssl/unix_err.h4
-rw-r--r--nss/lib/ssl/win32err.c465
-rw-r--r--nss/lib/ssl/win32err.h4
-rw-r--r--nss/lib/sysinit/nsssysinit.c294
-rw-r--r--nss/lib/sysinit/sysinit.gyp31
-rw-r--r--nss/lib/util/Makefile6
-rw-r--r--nss/lib/util/SECerrs.h716
-rw-r--r--nss/lib/util/base64.h2
-rw-r--r--nss/lib/util/ciferfam.h60
-rw-r--r--nss/lib/util/derdec.c232
-rw-r--r--nss/lib/util/derenc.c482
-rw-r--r--nss/lib/util/dersubr.c235
-rw-r--r--nss/lib/util/dertime.c164
-rw-r--r--nss/lib/util/eccutil.h14
-rw-r--r--nss/lib/util/errstrs.c17
-rw-r--r--nss/lib/util/exports.gyp67
-rw-r--r--nss/lib/util/hasht.h30
-rw-r--r--nss/lib/util/manifest.mn1
-rw-r--r--nss/lib/util/nssb64.h30
-rw-r--r--nss/lib/util/nssb64d.c494
-rw-r--r--nss/lib/util/nssb64e.c468
-rw-r--r--nss/lib/util/nssilckt.h58
-rw-r--r--nss/lib/util/nssilock.c425
-rw-r--r--nss/lib/util/nssilock.h269
-rw-r--r--nss/lib/util/nssrwlk.c165
-rw-r--r--nss/lib/util/nssrwlk.h38
-rw-r--r--nss/lib/util/nssrwlkt.h5
-rw-r--r--nss/lib/util/nssutil.def13
-rw-r--r--nss/lib/util/nssutil.h12
-rw-r--r--nss/lib/util/oidstring.c134
-rw-r--r--nss/lib/util/pkcs11.h25
-rw-r--r--nss/lib/util/pkcs11f.h717
-rw-r--r--nss/lib/util/pkcs11n.h340
-rw-r--r--nss/lib/util/pkcs11p.h3
-rw-r--r--nss/lib/util/pkcs11t.h1896
-rw-r--r--nss/lib/util/pkcs11u.h5
-rw-r--r--nss/lib/util/pkcs1sig.c14
-rw-r--r--nss/lib/util/portreg.c480
-rw-r--r--nss/lib/util/portreg.h24
-rw-r--r--nss/lib/util/quickder.c657
-rw-r--r--nss/lib/util/secalgid.c129
-rw-r--r--nss/lib/util/secasn1.h81
-rw-r--r--nss/lib/util/secasn1d.c3610
-rw-r--r--nss/lib/util/secasn1e.c1807
-rw-r--r--nss/lib/util/secasn1t.h195
-rw-r--r--nss/lib/util/secasn1u.c59
-rw-r--r--nss/lib/util/seccomon.h19
-rw-r--r--nss/lib/util/secder.h56
-rw-r--r--nss/lib/util/secdert.h90
-rw-r--r--nss/lib/util/secdig.c89
-rw-r--r--nss/lib/util/secdig.h37
-rw-r--r--nss/lib/util/secdigt.h4
-rw-r--r--nss/lib/util/secerr.h398
-rw-r--r--nss/lib/util/secitem.c326
-rw-r--r--nss/lib/util/secitem.h22
-rw-r--r--nss/lib/util/secload.c40
-rw-r--r--nss/lib/util/secoid.c3384
-rw-r--r--nss/lib/util/secoid.h35
-rw-r--r--nss/lib/util/secoidt.h336
-rw-r--r--nss/lib/util/secplcy.c112
-rw-r--r--nss/lib/util/secplcy.h42
-rw-r--r--nss/lib/util/secport.c548
-rw-r--r--nss/lib/util/secport.h228
-rw-r--r--nss/lib/util/sectime.c78
-rw-r--r--nss/lib/util/templates.c20
-rw-r--r--nss/lib/util/utf8.c1939
-rw-r--r--nss/lib/util/util.gyp59
-rw-r--r--nss/lib/util/utilmod.c787
-rw-r--r--nss/lib/util/utilmodt.h48
-rw-r--r--nss/lib/util/utilpars.c1241
-rw-r--r--nss/lib/util/utilpars.h61
-rw-r--r--nss/lib/util/utilparst.h62
-rw-r--r--nss/lib/util/verref.h5
-rw-r--r--nss/lib/zlib/exports.gyp33
-rw-r--r--nss/lib/zlib/zlib.gyp49
768 files changed, 263942 insertions, 213203 deletions
diff --git a/nss/lib/Makefile b/nss/lib/Makefile
index a28bfd4..8eedad0 100644
--- a/nss/lib/Makefile
+++ b/nss/lib/Makefile
@@ -46,6 +46,14 @@ ifndef NSS_DISABLE_DBM
DBM_SRCDIR = dbm # Add the dbm directory to DIRS.
endif
+ifeq ($(NSS_BUILD_UTIL_ONLY),1)
+SYSINIT_SRCDIR=
+endif
+
+ifndef NSS_DISABLE_LIBPKIX
+LIBPKIX_SRCDIR = libpkix # Add the libpkix directory to DIRS.
+endif
+
#######################################################################
# (5) Execute "global" rules. (OPTIONAL) #
#######################################################################
@@ -62,14 +70,28 @@ include $(CORE_DEPTH)/coreconf/rules.mk
# (7) Execute "local" rules. (OPTIONAL). #
#######################################################################
-ifeq ($(NSS_BUILD_WITHOUT_SOFTOKEN),1)
-# Not included when building nss without softoken
-UTIL_SRCDIR =
-FREEBL_SRCDIR =
-SOFTOKEN_SRCDIR =
+ifeq ($(NSS_BUILD_UTIL_ONLY),1)
+ UTIL_SRCDIR = util
+ FREEBL_SRCDIR =
+ SOFTOKEN_SRCDIR =
else
-# default is to include all
-UTIL_SRCDIR = util
-FREEBL_SRCDIR = freebl
-SOFTOKEN_SRCDIR = softoken
+ ifeq ($(NSS_BUILD_SOFTOKEN_ONLY),1)
+ UTIL_SRCDIR =
+ FREEBL_SRCDIR = freebl
+ SOFTOKEN_SRCDIR = softoken
+ else
+ ifeq ($(NSS_BUILD_WITHOUT_SOFTOKEN),1)
+ # Not included when building nss without softoken
+ # This build type uses the build results of the prior
+ # NSS_BUILD_UTIL_ONLY and NSS_BUILD_SOFTOKEN_ONLY builds
+ UTIL_SRCDIR =
+ FREEBL_SRCDIR =
+ SOFTOKEN_SRCDIR =
+ else
+ # default is to include all
+ UTIL_SRCDIR = util
+ FREEBL_SRCDIR = freebl
+ SOFTOKEN_SRCDIR = softoken
+ endif
+ endif
endif
diff --git a/nss/lib/base/arena.c b/nss/lib/base/arena.c
index 2b83338..b8e6464 100644
--- a/nss/lib/base/arena.c
+++ b/nss/lib/base/arena.c
@@ -41,7 +41,7 @@
* nssArena_Mark
* nssArena_Release
* nssArena_Unmark
- *
+ *
* nss_ZAlloc
* nss_ZFreeIf
* nss_ZRealloc
@@ -54,16 +54,16 @@
*/
struct NSSArenaStr {
- PLArenaPool pool;
- PRLock *lock;
+ PLArenaPool pool;
+ PRLock *lock;
#ifdef ARENA_THREADMARK
- PRThread *marking_thread;
- nssArenaMark *first_mark;
- nssArenaMark *last_mark;
+ 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;
+ struct arena_destructor_node *first_destructor;
+ struct arena_destructor_node *last_destructor;
#endif /* ARENA_DESTRUCTOR_LIST */
};
@@ -74,14 +74,14 @@ struct NSSArenaStr {
*/
struct nssArenaMarkStr {
- PRUint32 magic;
- void *mark;
+ PRUint32 magic;
+ void *mark;
#ifdef ARENA_THREADMARK
- nssArenaMark *next;
+ nssArenaMark *next;
#endif /* ARENA_THREADMARK */
#ifdef ARENA_DESTRUCTOR_LIST
- struct arena_destructor_node *next_destructor;
- struct arena_destructor_node *prev_destructor;
+ struct arena_destructor_node *next_destructor;
+ struct arena_destructor_node *prev_destructor;
#endif /* ARENA_DESTRUCTOR_LIST */
};
@@ -96,45 +96,39 @@ extern const NSSError NSS_ERROR_INTERNAL_ERROR;
static nssPointerTracker arena_pointer_tracker;
static PRStatus
-arena_add_pointer
-(
- const NSSArena *arena
-)
+arena_add_pointer(const NSSArena *arena)
{
- PRStatus rv;
-
- rv = nssPointerTracker_initialize(&arena_pointer_tracker);
- if( PR_SUCCESS != rv ) {
- return rv;
- }
+ PRStatus 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);
+ rv = nssPointerTracker_initialize(&arena_pointer_tracker);
+ if (PR_SUCCESS != rv) {
+ return 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;
+ return PR_SUCCESS;
}
static PRStatus
-arena_remove_pointer
-(
- const NSSArena *arena
-)
+arena_remove_pointer(const NSSArena *arena)
{
- PRStatus rv;
+ PRStatus rv;
- rv = nssPointerTracker_remove(&arena_pointer_tracker, arena);
- if( PR_SUCCESS != rv ) {
- nss_SetError(NSS_ERROR_INTERNAL_ERROR);
- }
+ rv = nssPointerTracker_remove(&arena_pointer_tracker, arena);
+ if (PR_SUCCESS != rv) {
+ nss_SetError(NSS_ERROR_INTERNAL_ERROR);
+ }
- return rv;
+ return rv;
}
/*
@@ -155,45 +149,42 @@ arena_remove_pointer
*/
NSS_IMPLEMENT PRStatus
-nssArena_verifyPointer
-(
- const NSSArena *arena
-)
+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;
- }
+ 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;
- }
+ rv = nssPointerTracker_verify(&arena_pointer_tracker, arena);
+ if (PR_SUCCESS != rv) {
+ nss_SetError(NSS_ERROR_INVALID_ARENA);
+ return PR_FAILURE;
+ }
- return PR_SUCCESS;
+ 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;
+ struct arena_destructor_node *next;
+ struct arena_destructor_node *prev;
+ void (*destructor)(void *argument);
+ void *arg;
};
/*
@@ -208,9 +199,9 @@ struct arena_destructor_node {
* 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
+ * 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:
@@ -223,108 +214,97 @@ struct arena_destructor_node {
*/
NSS_IMPLEMENT PRStatus
-nssArena_registerDestructor
-(
- NSSArena *arena,
- void (*destructor)(void *argument),
- void *arg
-)
+nssArena_registerDestructor(NSSArena *arena, void (*destructor)(void *argument),
+ void *arg)
{
- struct arena_destructor_node *it;
+ struct arena_destructor_node *it;
#ifdef NSSDEBUG
- if( PR_SUCCESS != nssArena_verifyPointer(arena) ) {
- return PR_FAILURE;
- }
+ 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;
+
+ 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
-)
+nssArena_deregisterDestructor(NSSArena *arena,
+ void (*destructor)(void *argument), void *arg)
{
- struct arena_destructor_node *it;
+ struct arena_destructor_node *it;
#ifdef NSSDEBUG
- if( PR_SUCCESS != nssArena_verifyPointer(arena) ) {
- return PR_FAILURE;
- }
+ 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;
+ 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;
- }
+
+ 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;
}
- }
- nss_ZFreeIf(it);
- return PR_SUCCESS;
+ 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
-)
+nss_arena_call_destructor_chain(struct arena_destructor_node *it)
{
- for( ; it ; it = it->next ) {
- (*(it->destructor))(it->arg);
- }
+ for (; it; it = it->next) {
+ (*(it->destructor))(it->arg);
+ }
}
#endif /* ARENA_DESTRUCTOR_LIST */
@@ -344,20 +324,17 @@ nss_arena_call_destructor_chain
*/
NSS_IMPLEMENT NSSArena *
-NSSArena_Create
-(
- void
-)
+NSSArena_Create(void)
{
- nss_ClearErrorStack();
- return nssArena_Create();
+ 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
+ * 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:
@@ -369,66 +346,63 @@ NSSArena_Create
*/
NSS_IMPLEMENT NSSArena *
-nssArena_Create
-(
- void
-)
+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));
+ 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;
+ {
+ 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;
+ return rv;
}
/*
* NSSArena_Destroy
*
* This routine will destroy the specified arena, freeing all memory
- * allocated from it. This routine returns a PRStatus value; if
+ * 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.
*
@@ -441,27 +415,24 @@ nssArena_Create
*/
NSS_IMPLEMENT PRStatus
-NSSArena_Destroy
-(
- NSSArena *arena
-)
+NSSArena_Destroy(NSSArena *arena)
{
- nss_ClearErrorStack();
+ nss_ClearErrorStack();
#ifdef DEBUG
- if( PR_SUCCESS != nssArena_verifyPointer(arena) ) {
- return PR_FAILURE;
- }
+ if (PR_SUCCESS != nssArena_verifyPointer(arena)) {
+ return PR_FAILURE;
+ }
#endif /* DEBUG */
- return nssArena_Destroy(arena);
+ 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
+ * 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.
*
@@ -474,45 +445,42 @@ NSSArena_Destroy
*/
NSS_IMPLEMENT PRStatus
-nssArena_Destroy
-(
- NSSArena *arena
-)
+nssArena_Destroy(NSSArena *arena)
{
- PRLock *lock;
+ PRLock *lock;
#ifdef NSSDEBUG
- if( PR_SUCCESS != nssArena_verifyPointer(arena) ) {
- return PR_FAILURE;
- }
+ 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);
-
+ 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;
- }
+ 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);
+ /* 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;
+ 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);
@@ -523,9 +491,9 @@ static void *nss_zalloc_arena_locked(NSSArena *arena, PRUint32 size);
* 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
+ * 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:
@@ -539,73 +507,70 @@ static void *nss_zalloc_arena_locked(NSSArena *arena, PRUint32 size);
*/
NSS_IMPLEMENT nssArenaMark *
-nssArena_Mark
-(
- NSSArena *arena
-)
+nssArena_Mark(NSSArena *arena)
{
- nssArenaMark *rv;
- void *p;
+ nssArenaMark *rv;
+ void *p;
#ifdef NSSDEBUG
- if( PR_SUCCESS != nssArena_verifyPointer(arena) ) {
- return (nssArenaMark *)NULL;
- }
+ 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);
+ 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;
+ 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 */
+ 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;
- }
+ /* 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;
- }
+ 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;
+ rv->mark = p;
+ rv->magic = MARK_MAGIC;
#ifdef ARENA_DESTRUCTOR_LIST
- rv->prev_destructor = arena->last_destructor;
+ rv->prev_destructor = arena->last_destructor;
#endif /* ARENA_DESTRUCTOR_LIST */
- PR_Unlock(arena->lock);
+ PR_Unlock(arena->lock);
- return rv;
+ return rv;
}
/*
@@ -616,100 +581,98 @@ nssArena_Mark
*/
static PRStatus
-nss_arena_unmark_release
-(
- NSSArena *arena,
- nssArenaMark *arenaMark,
- PRBool release
-)
+nss_arena_unmark_release(NSSArena *arena, nssArenaMark *arenaMark,
+ PRBool release)
{
- void *inner_mark;
+ void *inner_mark;
#ifdef NSSDEBUG
- if( PR_SUCCESS != nssArena_verifyPointer(arena) ) {
- return PR_FAILURE;
- }
+ 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 (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);
+ 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;
+ 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;
+ if (MARK_MAGIC != arenaMark->magic) {
+ /* Just got released */
+ PR_Unlock(arena->lock);
+ nss_SetError(NSS_ERROR_INVALID_ARENA_MARK);
+ return PR_FAILURE;
}
- /* Remember the pointer, then zero it */
- rest = (*pMark)->next;
- *pMark = (nssArenaMark *)NULL;
+ arenaMark->magic = 0;
+ inner_mark = arenaMark->mark;
- 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;
+#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 ) {
+ 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);
+ 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 */
- PL_ARENA_RELEASE(&arena->pool, inner_mark);
- /* No error return */
- }
+ PL_ARENA_RELEASE(&arena->pool, inner_mark);
+ /* No error return */
+ }
- PR_Unlock(arena->lock);
- return PR_SUCCESS;
+ PR_Unlock(arena->lock);
+ return PR_SUCCESS;
}
/*
@@ -732,13 +695,9 @@ nss_arena_unmark_release
*/
NSS_IMPLEMENT PRStatus
-nssArena_Release
-(
- NSSArena *arena,
- nssArenaMark *arenaMark
-)
+nssArena_Release(NSSArena *arena, nssArenaMark *arenaMark)
{
- return nss_arena_unmark_release(arena, arenaMark, PR_TRUE);
+ return nss_arena_unmark_release(arena, arenaMark, PR_TRUE);
}
/*
@@ -764,13 +723,9 @@ nssArena_Release
*/
NSS_IMPLEMENT PRStatus
-nssArena_Unmark
-(
- NSSArena *arena,
- nssArenaMark *arenaMark
-)
+nssArena_Unmark(NSSArena *arena, nssArenaMark *arenaMark)
{
- return nss_arena_unmark_release(arena, arenaMark, PR_FALSE);
+ return nss_arena_unmark_release(arena, arenaMark, PR_FALSE);
}
/*
@@ -782,49 +737,45 @@ nssArena_Unmark
* maybe we should add a magic value?
*/
struct pointer_header {
- NSSArena *arena;
- PRUint32 size;
+ NSSArena *arena;
+ PRUint32 size;
};
static void *
-nss_zalloc_arena_locked
-(
- NSSArena *arena,
- PRUint32 size
-)
+nss_zalloc_arena_locked(NSSArena *arena, PRUint32 size)
{
- void *p;
- void *rv;
- struct pointer_header *h;
- PRUint32 my_size = size + sizeof(struct pointer_header);
- PL_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;
+ void *p;
+ void *rv;
+ struct pointer_header *h;
+ PRUint32 my_size = size + sizeof(struct pointer_header);
+ PL_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
+ * 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
+ * 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.
*
@@ -839,25 +790,21 @@ nss_zalloc_arena_locked
*/
NSS_IMPLEMENT void *
-NSS_ZAlloc
-(
- NSSArena *arenaOpt,
- PRUint32 size
-)
+NSS_ZAlloc(NSSArena *arenaOpt, PRUint32 size)
{
- return nss_ZAlloc(arenaOpt, size);
+ return nss_ZAlloc(arenaOpt, size);
}
/*
* nss_ZAlloc
*
- * This routine allocates and zeroes a section of memory of the
+ * 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
+ * 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.
*
@@ -872,76 +819,72 @@ NSS_ZAlloc
*/
NSS_IMPLEMENT void *
-nss_ZAlloc
-(
- NSSArena *arenaOpt,
- PRUint32 size
-)
+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;
+ 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;
}
- h->arena = (NSSArena *)NULL;
- h->size = size;
- /* We used calloc: it's already zeroed */
+ 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;
+ }
- return (void *)((char *)h + sizeof(struct pointer_header));
- } else {
- void *rv;
- /* Arena allocation */
+ 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;
- }
+ 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);
+ 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;
- }
- }
+ 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);
+ rv = nss_zalloc_arena_locked(arenaOpt, size);
- PR_Unlock(arenaOpt->lock);
- return rv;
- }
- /*NOTREACHED*/
+ 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
+ * 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
+ * If unsuccessful, it will set an error on the error stack and return
* PR_FAILURE.
*
* The error may be one of the following values:
@@ -952,22 +895,19 @@ nss_ZAlloc
* PR_FAILURE
*/
NSS_IMPLEMENT PRStatus
-NSS_ZFreeIf
-(
- void *pointer
-)
+NSS_ZFreeIf(void *pointer)
{
- return nss_ZFreeIf(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
+ * 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
+ * If unsuccessful, it will set an error on the error stack and return
* PR_FAILURE.
*
* The error may be one of the following values:
@@ -979,60 +919,57 @@ NSS_ZFreeIf
*/
NSS_IMPLEMENT PRStatus
-nss_ZFreeIf
-(
- void *pointer
-)
+nss_ZFreeIf(void *pointer)
{
- struct pointer_header *h;
+ struct pointer_header *h;
- if( (void *)NULL == pointer ) {
- return PR_SUCCESS;
- }
+ if ((void *)NULL == pointer) {
+ return PR_SUCCESS;
+ }
- h = (struct pointer_header *)((char *)pointer
- - sizeof(struct pointer_header));
+ h = (struct pointer_header *)((char *)pointer -
+ sizeof(struct pointer_header));
- /* Check any magic here */
+ /* 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 */
+ 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;
- }
+ 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);
+ 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);
+ (void)nsslibc_memset(pointer, 0, h->size);
- /* No way to "free" it within an NSPR arena. */
+ /* No way to "free" it within an NSPR arena. */
- PR_Unlock(h->arena->lock);
- return PR_SUCCESS;
- }
- /*NOTREACHED*/
+ 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
+ * 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
+ * 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:
@@ -1046,11 +983,7 @@ nss_ZFreeIf
*/
NSS_EXTERN void *
-NSS_ZRealloc
-(
- void *pointer,
- PRUint32 newSize
-)
+NSS_ZRealloc(void *pointer, PRUint32 newSize)
{
return nss_ZRealloc(pointer, newSize);
}
@@ -1059,10 +992,10 @@ NSS_ZRealloc
* nss_ZRealloc
*
* This routine reallocates a block of memory obtained by calling
- * nss_ZAlloc or nss_ZRealloc. The portion of memory
+ * 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
+ * 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:
@@ -1076,139 +1009,135 @@ NSS_ZRealloc
*/
NSS_EXTERN void *
-nss_ZRealloc
-(
- void *pointer,
- PRUint32 newSize
-)
+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;
- }
+ NSSArena *arena;
+ struct pointer_header *h, *new_h;
+ PRUint32 my_newSize = newSize + sizeof(struct pointer_header);
+ void *rv;
- new_h->arena = (NSSArena *)NULL;
- new_h->size = newSize;
- rv = (void *)((char *)new_h + sizeof(struct pointer_header));
+ if (my_newSize < sizeof(struct pointer_header)) {
+ /* Wrapped */
+ nss_SetError(NSS_ERROR_NO_MEMORY);
+ return (void *)NULL;
+ }
- 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);
+ if ((void *)NULL == pointer) {
+ nss_SetError(NSS_ERROR_INVALID_POINTER);
+ return (void *)NULL;
}
- (void)nsslibc_memset(pointer, 0, h->size);
- h->size = 0;
- PR_Free(h);
+ h = (struct pointer_header *)((char *)pointer -
+ sizeof(struct pointer_header));
- return rv;
- } else {
- void *p;
- /* Arena */
-#ifdef NSSDEBUG
- if (PR_SUCCESS != nssArena_verifyPointer(arena)) {
- return (void *)NULL;
+ /* 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);
+ 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;
- }
- }
+ 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;
- }
-
- PL_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);
+ 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;
+ }
+
+ PL_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;
}
- (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*/
+ /*NOTREACHED*/
}
-PRStatus
+PRStatus
nssArena_Shutdown(void)
{
- PRStatus rv = PR_SUCCESS;
+ PRStatus rv = PR_SUCCESS;
#ifdef DEBUG
- rv = nssPointerTracker_finalize(&arena_pointer_tracker);
+ rv = nssPointerTracker_finalize(&arena_pointer_tracker);
#endif
- return rv;
+ return rv;
}
diff --git a/nss/lib/base/base.gyp b/nss/lib/base/base.gyp
new file mode 100644
index 0000000..42318c8
--- /dev/null
+++ b/nss/lib/base/base.gyp
@@ -0,0 +1,32 @@
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+{
+ 'includes': [
+ '../../coreconf/config.gypi'
+ ],
+ 'targets': [
+ {
+ 'target_name': 'nssb',
+ 'type': 'static_library',
+ 'sources': [
+ 'arena.c',
+ 'error.c',
+ 'errorval.c',
+ 'hash.c',
+ 'hashops.c',
+ 'item.c',
+ 'libc.c',
+ 'list.c',
+ 'tracker.c',
+ 'utf8.c'
+ ],
+ 'dependencies': [
+ '<(DEPTH)/exports.gyp:nss_exports'
+ ]
+ }
+ ],
+ 'variables': {
+ 'module': 'nss'
+ }
+} \ No newline at end of file
diff --git a/nss/lib/base/base.h b/nss/lib/base/base.h
index deff44c..2033c44 100644
--- a/nss/lib/base/base.h
+++ b/nss/lib/base/base.h
@@ -8,7 +8,7 @@
/*
* base.h
*
- * This header file contains basic prototypes and preprocessor
+ * This header file contains basic prototypes and preprocessor
* definitions used throughout nss but not available publicly.
*/
@@ -64,7 +64,7 @@ PR_BEGIN_EXTERN_C
* 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
+ * 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:
@@ -83,11 +83,7 @@ PR_BEGIN_EXTERN_C
* call (NSSArena_Create) have it too?
*/
-NSS_EXTERN NSSArena *
-nssArena_Create
-(
- void
-);
+NSS_EXTERN NSSArena *nssArena_Create(void);
extern const NSSError NSS_ERROR_NO_MEMORY;
@@ -95,7 +91,7 @@ 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
+ * 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.
*
@@ -107,11 +103,7 @@ extern const NSSError NSS_ERROR_NO_MEMORY;
* PR_FAILURE
*/
-NSS_EXTERN PRStatus
-nssArena_Destroy
-(
- NSSArena *arena
-);
+NSS_EXTERN PRStatus nssArena_Destroy(NSSArena *arena);
extern const NSSError NSS_ERROR_INVALID_ARENA;
@@ -121,9 +113,9 @@ extern const NSSError NSS_ERROR_INVALID_ARENA;
* 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
+ * 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:
@@ -136,11 +128,7 @@ extern const NSSError NSS_ERROR_INVALID_ARENA;
* An nssArenaMark pointer upon success
*/
-NSS_EXTERN nssArenaMark *
-nssArena_Mark
-(
- NSSArena *arena
-);
+NSS_EXTERN nssArenaMark *nssArena_Mark(NSSArena *arena);
extern const NSSError NSS_ERROR_INVALID_ARENA;
extern const NSSError NSS_ERROR_NO_MEMORY;
@@ -165,12 +153,7 @@ extern const NSSError NSS_ERROR_ARENA_MARKED_BY_ANOTHER_THREAD;
* PR_FAILURE
*/
-NSS_EXTERN PRStatus
-nssArena_Release
-(
- NSSArena *arena,
- nssArenaMark *arenaMark
-);
+NSS_EXTERN PRStatus nssArena_Release(NSSArena *arena, nssArenaMark *arenaMark);
extern const NSSError NSS_ERROR_INVALID_ARENA;
extern const NSSError NSS_ERROR_INVALID_ARENA_MARK;
@@ -197,12 +180,7 @@ extern const NSSError NSS_ERROR_INVALID_ARENA_MARK;
* PR_FAILURE
*/
-NSS_EXTERN PRStatus
-nssArena_Unmark
-(
- NSSArena *arena,
- nssArenaMark *arenaMark
-);
+NSS_EXTERN PRStatus nssArena_Unmark(NSSArena *arena, nssArenaMark *arenaMark);
extern const NSSError NSS_ERROR_INVALID_ARENA;
extern const NSSError NSS_ERROR_INVALID_ARENA_MARK;
@@ -222,9 +200,9 @@ extern const NSSError NSS_ERROR_ARENA_MARKED_BY_ANOTHER_THREAD;
* 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
+ * 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:
@@ -236,13 +214,8 @@ extern const NSSError NSS_ERROR_ARENA_MARKED_BY_ANOTHER_THREAD;
* PR_FAILURE
*/
-NSS_EXTERN PRStatus
-nssArena_registerDestructor
-(
- NSSArena *arena,
- void (*destructor)(void *argument),
- void *arg
-);
+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;
@@ -253,8 +226,8 @@ extern const NSSError NSS_ERROR_NO_MEMORY;
* 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
+ * 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:
@@ -266,13 +239,8 @@ extern const NSSError NSS_ERROR_NO_MEMORY;
* PR_FAILURE
*/
-NSS_EXTERN PRStatus
-nssArena_deregisterDestructor
-(
- NSSArena *arena,
- void (*destructor)(void *argument),
- void *arg
-);
+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;
@@ -283,13 +251,13 @@ extern const NSSError NSS_ERROR_NOT_FOUND;
/*
* nss_ZAlloc
*
- * This routine allocates and zeroes a section of memory of the
+ * 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
+ * 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.
*
@@ -303,12 +271,7 @@ extern const NSSError NSS_ERROR_NOT_FOUND;
* A pointer to the new segment of zeroed memory
*/
-NSS_EXTERN void *
-nss_ZAlloc
-(
- NSSArena *arenaOpt,
- PRUint32 size
-);
+NSS_EXTERN void *nss_ZAlloc(NSSArena *arenaOpt, PRUint32 size);
extern const NSSError NSS_ERROR_INVALID_ARENA;
extern const NSSError NSS_ERROR_NO_MEMORY;
@@ -317,11 +280,11 @@ 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
+ * 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
+ * If unsuccessful, it will set an error on the error stack and return
* PR_FAILURE.
*
* The error may be one of the following values:
@@ -332,11 +295,7 @@ extern const NSSError NSS_ERROR_ARENA_MARKED_BY_ANOTHER_THREAD;
* PR_FAILURE
*/
-NSS_EXTERN PRStatus
-nss_ZFreeIf
-(
- void *pointer
-);
+NSS_EXTERN PRStatus nss_ZFreeIf(void *pointer);
extern const NSSError NSS_ERROR_INVALID_POINTER;
@@ -344,10 +303,10 @@ 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
+ * 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
+ * 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:
@@ -360,12 +319,7 @@ extern const NSSError NSS_ERROR_INVALID_POINTER;
* A pointer to the replacement segment of memory
*/
-NSS_EXTERN void *
-nss_ZRealloc
-(
- void *pointer,
- PRUint32 newSize
-);
+NSS_EXTERN void *nss_ZRealloc(void *pointer, PRUint32 newSize);
extern const NSSError NSS_ERROR_INVALID_POINTER;
extern const NSSError NSS_ERROR_NO_MEMORY;
@@ -376,10 +330,10 @@ extern const NSSError NSS_ERROR_ARENA_MARKED_BY_ANOTHER_THREAD;
*
* 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
+ * 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:
@@ -391,7 +345,6 @@ extern const NSSError NSS_ERROR_ARENA_MARKED_BY_ANOTHER_THREAD;
* 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)))
/*
@@ -399,10 +352,10 @@ extern const NSSError NSS_ERROR_ARENA_MARKED_BY_ANOTHER_THREAD;
*
* 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
+ * 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:
@@ -414,15 +367,15 @@ extern const NSSError NSS_ERROR_ARENA_MARKED_BY_ANOTHER_THREAD;
* 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)))
+#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
+ * 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:
@@ -434,7 +387,8 @@ extern const NSSError NSS_ERROR_ARENA_MARKED_BY_ANOTHER_THREAD;
* NULL upon error
* A pointer to the replacement segment of memory
*/
-#define nss_ZREALLOCARRAY(p, type, quantity) ((type *)nss_ZRealloc((p), sizeof(type) * (quantity)))
+#define nss_ZREALLOCARRAY(p, type, quantity) \
+ ((type *)nss_ZRealloc((p), sizeof(type) * (quantity)))
/*
* nssArena_verifyPointer
@@ -454,11 +408,7 @@ extern const NSSError NSS_ERROR_ARENA_MARKED_BY_ANOTHER_THREAD;
*/
#ifdef DEBUG
-NSS_EXTERN PRStatus
-nssArena_verifyPointer
-(
- const NSSArena *arena
-);
+NSS_EXTERN PRStatus nssArena_verifyPointer(const NSSArena *arena);
extern const NSSError NSS_ERROR_INVALID_ARENA;
#endif /* DEBUG */
@@ -479,16 +429,16 @@ extern const NSSError NSS_ERROR_INVALID_ARENA;
#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)
+
+#define nssArena_VERIFYPOINTER(p) \
+ (((NSSArena *)NULL == (p)) ? PR_FAILURE : PR_SUCCESS)
#endif /* DEBUG */
/*
- * Private function to be called by NSS_Shutdown to cleanup nssArena
+ * Private function to be called by NSS_Shutdown to cleanup nssArena
* bookkeeping.
*/
-extern PRStatus
-nssArena_Shutdown(void);
+extern PRStatus nssArena_Shutdown(void);
/*
* nssArenaHashAllocOps
@@ -497,7 +447,7 @@ nssArena_Shutdown(void);
* use with the NSPL routine PL_NewHashTable. For example:
*
* NSSArena *hashTableArena = nssArena_Create();
- * PLHashTable *t = PL_NewHashTable(n, hasher, key_compare,
+ * PLHashTable *t = PL_NewHashTable(n, hasher, key_compare,
* value_compare, nssArenaHashAllocOps, hashTableArena);
*/
@@ -515,16 +465,12 @@ NSS_EXTERN_DATA PLHashAllocOps nssArenaHashAllocOps;
/*
* nss_SetError
*
- * This routine places a new error code on the top of the calling
+ * 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_EXTERN void nss_SetError(PRUint32 error);
/*
* nss_ClearErrorStack
@@ -532,11 +478,7 @@ nss_SetError
* This routine clears the calling thread's error stack.
*/
-NSS_EXTERN void
-nss_ClearErrorStack
-(
- void
-);
+NSS_EXTERN void nss_ClearErrorStack(void);
/*
* nss_DestroyErrorStack
@@ -544,11 +486,7 @@ nss_ClearErrorStack
* This routine frees the calling thread's error stack.
*/
-NSS_EXTERN void
-nss_DestroyErrorStack
-(
- void
-);
+NSS_EXTERN void nss_DestroyErrorStack(void);
/*
* NSSItem
@@ -558,36 +496,16 @@ nss_DestroyErrorStack
* 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
-);
+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
@@ -601,8 +519,8 @@ nssItem_Equal
/*
* nssUTF8_CaseIgnoreMatch
- *
- * Returns true if the two UTF8-encoded strings pointed to by the
+ *
+ * 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:
@@ -614,13 +532,8 @@ nssItem_Equal
* PR_FALSE upon error
*/
-NSS_EXTERN PRBool
-nssUTF8_CaseIgnoreMatch
-(
- const NSSUTF8 *a,
- const NSSUTF8 *b,
- PRStatus *statusOpt
-);
+NSS_EXTERN PRBool nssUTF8_CaseIgnoreMatch(const NSSUTF8 *a, const NSSUTF8 *b,
+ PRStatus *statusOpt);
/*
* nssUTF8_Duplicate
@@ -630,7 +543,7 @@ nssUTF8_CaseIgnoreMatch
* 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
+ * an error will be placed on the error stack and NULL will be
* returned.
*
* The error may be one of the following values:
@@ -639,20 +552,15 @@ nssUTF8_CaseIgnoreMatch
* NSS_ERROR_NO_MEMORY
*/
-NSS_EXTERN NSSUTF8 *
-nssUTF8_Duplicate
-(
- const NSSUTF8 *s,
- NSSArena *arenaOpt
-);
+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,
+ * 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
@@ -668,13 +576,8 @@ nssUTF8_Duplicate
* PR_FALSE upon error
*/
-NSS_EXTERN PRBool
-nssUTF8_PrintableMatch
-(
- const NSSUTF8 *a,
- const NSSUTF8 *b,
- PRStatus *statusOpt
-);
+NSS_EXTERN PRBool nssUTF8_PrintableMatch(const NSSUTF8 *a, const NSSUTF8 *b,
+ PRStatus *statusOpt);
/*
* nssUTF8_Size
@@ -692,12 +595,7 @@ nssUTF8_PrintableMatch
* 0 on error
*/
-NSS_EXTERN PRUint32
-nssUTF8_Size
-(
- const NSSUTF8 *s,
- PRStatus *statusOpt
-);
+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;
@@ -719,12 +617,7 @@ extern const NSSError NSS_ERROR_VALUE_TOO_LARGE;
* 0 on error
*/
-NSS_EXTERN PRUint32
-nssUTF8_Length
-(
- const NSSUTF8 *s,
- PRStatus *statusOpt
-);
+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;
@@ -753,34 +646,24 @@ extern const NSSError NSS_ERROR_INVALID_STRING;
* 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 */
-);
+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
-);
+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
+ * 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
+ * be padded with the specified ASCII character, typically either
* null or space.
*
* Blah, blah, blah.
@@ -789,27 +672,16 @@ nssUTF8_GetEncoding
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
-);
+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
-);
+NSS_EXTERN PRBool nssUTF8_Equal(const NSSUTF8 *a, const NSSUTF8 *b,
+ PRStatus *statusOpt);
/*
* nssList
@@ -826,28 +698,15 @@ nssUTF8_Equal
* If threadsafe is true, the list will be locked during modifications
* and traversals.
*/
-NSS_EXTERN nssList *
-nssList_Create
-(
- NSSArena *arenaOpt,
- PRBool threadSafe
-);
+NSS_EXTERN nssList *nssList_Create(NSSArena *arenaOpt, PRBool threadSafe);
/*
* nssList_Destroy
*/
-NSS_EXTERN PRStatus
-nssList_Destroy
-(
- nssList *list
-);
+NSS_EXTERN PRStatus nssList_Destroy(nssList *list);
-NSS_EXTERN void
-nssList_Clear
-(
- nssList *list,
- nssListElementDestructorFunc destructor
-);
+NSS_EXTERN void nssList_Clear(nssList *list,
+ nssListElementDestructorFunc destructor);
/*
* nssList_SetCompareFunction
@@ -856,34 +715,21 @@ nssList_Clear
* data pointers. By setting this function, the user can control
* how elements are compared.
*/
-NSS_EXTERN void
-nssList_SetCompareFunction
-(
- nssList *list,
- nssListCompareFunc compareFunc
-);
+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
-);
+NSS_EXTERN void nssList_SetSortFunction(nssList *list,
+ nssListSortFunc sortFunc);
/*
* nssList_Add
*/
-NSS_EXTERN PRStatus
-nssList_Add
-(
- nssList *list,
- void *data
-);
+NSS_EXTERN PRStatus nssList_Add(nssList *list, void *data);
/*
* nssList_AddUnique
@@ -891,20 +737,14 @@ nssList_Add
* 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
-);
+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);
+NSS_EXTERN PRStatus nssList_Remove(nssList *list, void *data);
/*
* nssList_Get
@@ -912,21 +752,12 @@ nssList_Remove(nssList *list, void *data);
* Uses the compare function to locate an element. Also serves as
* nssList_Exists.
*/
-NSS_EXTERN void *
-nssList_Get
-(
- nssList *list,
- void *data
-);
+NSS_EXTERN void *nssList_Get(nssList *list, void *data);
/*
* nssList_Count
*/
-NSS_EXTERN PRUint32
-nssList_Count
-(
- nssList *list
-);
+NSS_EXTERN PRUint32 nssList_Count(nssList *list);
/*
* nssList_GetArray
@@ -934,39 +765,22 @@ nssList_Count
* 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
-);
+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 nssListIterator *nssList_CreateIterator(nssList *list);
-NSS_EXTERN nssList *
-nssList_Clone
-(
- nssList *list
-);
+NSS_EXTERN nssList *nssList_Clone(nssList *list);
/*
* nssListIterator_Destroy
*/
-NSS_EXTERN void
-nssListIterator_Destroy
-(
- nssListIterator *iter
-);
+NSS_EXTERN void nssListIterator_Destroy(nssListIterator *iter);
/*
* nssListIterator_Start
@@ -974,22 +788,14 @@ nssListIterator_Destroy
* Begin a list iteration. After this call, if the list is threadSafe,
* the list is *locked*.
*/
-NSS_EXTERN void *
-nssListIterator_Start
-(
- nssListIterator *iter
-);
+NSS_EXTERN void *nssListIterator_Start(nssListIterator *iter);
/*
* nssListIterator_Next
*
* Continue a list iteration.
*/
-NSS_EXTERN void *
-nssListIterator_Next
-(
- nssListIterator *iter
-);
+NSS_EXTERN void *nssListIterator_Next(nssListIterator *iter);
/*
* nssListIterator_Finish
@@ -997,11 +803,7 @@ nssListIterator_Next
* Complete a list iteration. This *must* be called in order for the
* lock to be released.
*/
-NSS_EXTERN PRStatus
-nssListIterator_Finish
-(
- nssListIterator *iter
-);
+NSS_EXTERN PRStatus nssListIterator_Finish(nssListIterator *iter);
/*
* nssHash
@@ -1021,46 +823,24 @@ nssListIterator_Finish
*
*/
-NSS_EXTERN nssHash *
-nssHash_Create
-(
- NSSArena *arenaOpt,
- PRUint32 numBuckets,
- PLHashFunction keyHash,
- PLHashComparator keyCompare,
- PLHashComparator valueCompare
-);
+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_CreatePointer(NSSArena *arenaOpt,
+ PRUint32 numBuckets);
-NSS_EXTERN nssHash *
-nssHash_CreateString
-(
- NSSArena *arenaOpt,
- PRUint32 numBuckets
-);
+NSS_EXTERN nssHash *nssHash_CreateString(NSSArena *arenaOpt,
+ PRUint32 numBuckets);
-NSS_EXTERN nssHash *
-nssHash_CreateItem
-(
- NSSArena *arenaOpt,
- PRUint32 numBuckets
-);
+NSS_EXTERN nssHash *nssHash_CreateItem(NSSArena *arenaOpt, PRUint32 numBuckets);
/*
* nssHash_Destroy
*
*/
-NSS_EXTERN void
-nssHash_Destroy
-(
- nssHash *hash
-);
+NSS_EXTERN void nssHash_Destroy(nssHash *hash);
/*
* nssHash_Add
@@ -1069,75 +849,45 @@ nssHash_Destroy
extern const NSSError NSS_ERROR_HASH_COLLISION;
-NSS_EXTERN PRStatus
-nssHash_Add
-(
- nssHash *hash,
- const void *key,
- const void *value
-);
+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
-);
+NSS_EXTERN void nssHash_Remove(nssHash *hash, const void *it);
/*
* nssHash_Count
*
*/
-NSS_EXTERN PRUint32
-nssHash_Count
-(
- nssHash *hash
-);
+NSS_EXTERN PRUint32 nssHash_Count(nssHash *hash);
/*
* nssHash_Exists
*
*/
-NSS_EXTERN PRBool
-nssHash_Exists
-(
- nssHash *hash,
- const void *it
-);
+NSS_EXTERN PRBool nssHash_Exists(nssHash *hash, const void *it);
/*
* nssHash_Lookup
*
*/
-NSS_EXTERN void *
-nssHash_Lookup
-(
- nssHash *hash,
- const void *it
-);
+NSS_EXTERN void *nssHash_Lookup(nssHash *hash, const void *it);
/*
* nssHash_Iterate
*
*/
-NSS_EXTERN void
-nssHash_Iterate
-(
- nssHash *hash,
- nssHashIterator fcn,
- void *closure
-);
-
+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
@@ -1151,13 +901,13 @@ nssHash_Iterate
* 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
+ * 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:
@@ -1169,11 +919,7 @@ nssHash_Iterate
*/
#ifdef DEBUG
-NSS_EXTERN PRStatus
-nssPointerTracker_initialize
-(
- nssPointerTracker *tracker
-);
+NSS_EXTERN PRStatus nssPointerTracker_initialize(nssPointerTracker *tracker);
extern const NSSError NSS_ERROR_NO_MEMORY;
#endif /* DEBUG */
@@ -1182,7 +928,7 @@ extern const NSSError NSS_ERROR_NO_MEMORY;
* 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
@@ -1202,11 +948,7 @@ extern const NSSError NSS_ERROR_NO_MEMORY;
*/
#ifdef DEBUG
-NSS_EXTERN PRStatus
-nssPointerTracker_finalize
-(
- nssPointerTracker *tracker
-);
+NSS_EXTERN PRStatus nssPointerTracker_finalize(nssPointerTracker *tracker);
extern const NSSError NSS_ERROR_TRACKER_NOT_EMPTY;
#endif /* DEBUG */
@@ -1234,12 +976,8 @@ extern const NSSError NSS_ERROR_TRACKER_NOT_EMPTY;
*/
#ifdef DEBUG
-NSS_EXTERN PRStatus
-nssPointerTracker_add
-(
- nssPointerTracker *tracker,
- const void *pointer
-);
+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;
@@ -1251,12 +989,12 @@ extern const NSSError NSS_ERROR_DUPLICATE_POINTER;
*
* This method is only present in debug builds.
*
- * This routine removes the specified pointer from the
+ * 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
+ * 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:
@@ -1269,12 +1007,8 @@ extern const NSSError NSS_ERROR_DUPLICATE_POINTER;
*/
#ifdef DEBUG
-NSS_EXTERN PRStatus
-nssPointerTracker_remove
-(
- nssPointerTracker *tracker,
- const void *pointer
-);
+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;
@@ -1289,10 +1023,10 @@ extern const NSSError NSS_ERROR_POINTER_NOT_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
+ * 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:
@@ -1304,12 +1038,8 @@ extern const NSSError NSS_ERROR_POINTER_NOT_REGISTERED;
*/
#ifdef DEBUG
-NSS_EXTERN PRStatus
-nssPointerTracker_verify
-(
- nssPointerTracker *tracker,
- const void *pointer
-);
+NSS_EXTERN PRStatus nssPointerTracker_verify(nssPointerTracker *tracker,
+ const void *pointer);
extern const NSSError NSS_ERROR_POINTER_NOT_REGISTERED;
#endif /* DEBUG */
@@ -1333,13 +1063,7 @@ extern const NSSError NSS_ERROR_POINTER_NOT_REGISTERED;
* The destination pointer on success
*/
-NSS_EXTERN void *
-nsslibc_memcpy
-(
- void *dest,
- const void *source,
- PRUint32 n
-);
+NSS_EXTERN void *nsslibc_memcpy(void *dest, const void *source, PRUint32 n);
extern const NSSError NSS_ERROR_INVALID_POINTER;
@@ -1354,13 +1078,7 @@ extern const NSSError NSS_ERROR_INVALID_POINTER;
* The destination pointer on success
*/
-NSS_EXTERN void *
-nsslibc_memset
-(
- void *dest,
- PRUint8 byte,
- PRUint32 n
-);
+NSS_EXTERN void *nsslibc_memset(void *dest, PRUint8 byte, PRUint32 n);
extern const NSSError NSS_ERROR_INVALID_POINTER;
@@ -1376,14 +1094,8 @@ extern const NSSError NSS_ERROR_INVALID_POINTER;
* PR_FALSE upon error
*/
-NSS_EXTERN PRBool
-nsslibc_memequal
-(
- const void *a,
- const void *b,
- PRUint32 len,
- PRStatus *statusOpt
-);
+NSS_EXTERN PRBool nsslibc_memequal(const void *a, const void *b, PRUint32 len,
+ PRStatus *statusOpt);
extern const NSSError NSS_ERROR_INVALID_POINTER;
diff --git a/nss/lib/base/baset.h b/nss/lib/base/baset.h
index 3c9f828..3953a75 100644
--- a/nss/lib/base/baset.h
+++ b/nss/lib/base/baset.h
@@ -32,7 +32,7 @@ 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,
@@ -68,14 +68,13 @@ typedef struct nssArenaMarkStr nssArenaMark;
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 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);
+typedef void(PR_CALLBACK *nssHashIterator)(const void *key, void *value,
+ void *arg);
/*
* nssPointerTracker
@@ -89,9 +88,9 @@ typedef void (PR_CALLBACK *nssHashIterator)(const void *key,
#ifdef DEBUG
struct nssPointerTrackerStr {
- PRCallOnceType once;
- PZLock *lock;
- PLHashTable *table;
+ PRCallOnceType once;
+ PZLock *lock;
+ PLHashTable *table;
};
typedef struct nssPointerTrackerStr nssPointerTracker;
#endif /* DEBUG */
@@ -107,16 +106,16 @@ typedef struct nssPointerTrackerStr nssPointerTracker;
*/
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
+ 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;
diff --git a/nss/lib/base/error.c b/nss/lib/base/error.c
index 807bbd4..ea1d5e3 100644
--- a/nss/lib/base/error.c
+++ b/nss/lib/base/error.c
@@ -5,13 +5,13 @@
/*
* error.c
*
- * This file contains the code implementing the per-thread error
+ * 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 */
+#endif /* BASE_H */
#include <limits.h> /* for UINT_MAX */
#include <string.h> /* for memmove */
@@ -25,13 +25,13 @@
*/
struct stack_header_str {
- PRUint16 space;
- PRUint16 count;
+ PRUint16 space;
+ PRUint16 count;
};
struct error_stack_str {
- struct stack_header_str header;
- PRInt32 stack[1];
+ struct stack_header_str header;
+ PRInt32 stack[1];
};
typedef struct error_stack_str error_stack;
@@ -62,9 +62,9 @@ static PRCallOnceType error_call_once;
* This is the once-called callback.
*/
static PRStatus
-error_once_function ( void)
+error_once_function(void)
{
- return PR_NewThreadPrivateIndex(&error_stack_index, PR_Free);
+ return PR_NewThreadPrivateIndex(&error_stack_index, PR_Free);
}
/*
@@ -76,48 +76,48 @@ error_once_function ( void)
*/
static error_stack *
-error_get_my_stack ( void)
+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;
+ 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);
+
+ 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_stack->header.space = new_size;
- }
- /* Set the value, whether or not the allocation worked */
- PR_SetThreadPrivate(error_stack_index, new_stack);
- return new_stack;
+ 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;
}
/*
@@ -151,19 +151,19 @@ error_get_my_stack ( void)
*/
NSS_IMPLEMENT PRInt32
-NSS_GetError ( void)
+NSS_GetError(void)
{
- error_stack *es = error_get_my_stack();
+ error_stack *es = error_get_my_stack();
- if( (error_stack *)NULL == es ) {
- return NSS_ERROR_NO_MEMORY; /* Good guess! */
- }
+ if ((error_stack *)NULL == es) {
+ return NSS_ERROR_NO_MEMORY; /* Good guess! */
+ }
- if( 0 == es->header.count ) {
- return 0;
- }
+ if (0 == es->header.count) {
+ return 0;
+ }
- return es->stack[ es->header.count-1 ];
+ return es->stack[es->header.count - 1];
}
/*
@@ -174,7 +174,7 @@ NSS_GetError ( void)
* 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
+ * 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.
@@ -185,52 +185,52 @@ NSS_GetError ( void)
*/
NSS_IMPLEMENT PRInt32 *
-NSS_GetErrorStack ( void)
+NSS_GetErrorStack(void)
{
- error_stack *es = error_get_my_stack();
+ error_stack *es = error_get_my_stack();
- if( (error_stack *)NULL == es ) {
- return (PRInt32 *)NULL;
- }
+ if ((error_stack *)NULL == es) {
+ return (PRInt32 *)NULL;
+ }
- /* Make sure it's terminated */
- es->stack[ es->header.count ] = 0;
+ /* Make sure it's terminated */
+ es->stack[es->header.count] = 0;
- return es->stack;
+ return es->stack;
}
/*
* nss_SetError
*
- * This routine places a new error code on the top of the calling
+ * 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)
+nss_SetError(PRUint32 error)
{
- error_stack *es;
+ error_stack *es;
- if( 0 == error ) {
- nss_ClearErrorStack();
- return;
- }
+ if (0 == error) {
+ nss_ClearErrorStack();
+ return;
+ }
- es = error_get_my_stack();
- if( (error_stack *)NULL == es ) {
- /* Oh, well. */
+ 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;
- }
-
- 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;
}
/*
@@ -240,17 +240,17 @@ nss_SetError ( PRUint32 error)
*/
NSS_IMPLEMENT void
-nss_ClearErrorStack ( void)
+nss_ClearErrorStack(void)
{
- error_stack *es = error_get_my_stack();
- if( (error_stack *)NULL == es ) {
- /* Oh, well. */
- return;
- }
+ error_stack *es = error_get_my_stack();
+ if ((error_stack *)NULL == es) {
+ /* Oh, well. */
+ return;
+ }
- es->header.count = 0;
- es->stack[0] = 0;
- return;
+ es->header.count = 0;
+ es->stack[0] = 0;
+ return;
}
/*
@@ -260,10 +260,10 @@ nss_ClearErrorStack ( void)
*/
NSS_IMPLEMENT void
-nss_DestroyErrorStack ( void)
+nss_DestroyErrorStack(void)
{
- if( INVALID_TPD_INDEX != error_stack_index ) {
- PR_SetThreadPrivate(error_stack_index, NULL);
- }
- return;
+ if (INVALID_TPD_INDEX != error_stack_index) {
+ PR_SetThreadPrivate(error_stack_index, NULL);
+ }
+ return;
}
diff --git a/nss/lib/base/errorval.c b/nss/lib/base/errorval.c
index 4e6f555..b7045a3 100644
--- a/nss/lib/base/errorval.c
+++ b/nss/lib/base/errorval.c
@@ -12,6 +12,8 @@
#include "nssbaset.h"
#endif /* NSSBASET_H */
+/* clang-format off */
+
const NSSError NSS_ERROR_NO_ERROR = 0;
const NSSError NSS_ERROR_INTERNAL_ERROR = 1;
const NSSError NSS_ERROR_NO_MEMORY = 2;
@@ -60,3 +62,4 @@ const NSSError NSS_ERROR_ALREADY_INITIALIZED = 37;
const NSSError NSS_ERROR_PKCS11 = 38;
+/* clang-format on */ \ No newline at end of file
diff --git a/nss/lib/base/exports.gyp b/nss/lib/base/exports.gyp
new file mode 100644
index 0000000..394bc1d
--- /dev/null
+++ b/nss/lib/base/exports.gyp
@@ -0,0 +1,33 @@
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+{
+ 'includes': [
+ '../../coreconf/config.gypi'
+ ],
+ 'targets': [
+ {
+ 'target_name': 'lib_base_exports',
+ 'type': 'none',
+ 'copies': [
+ {
+ 'files': [
+ 'nssbase.h',
+ 'nssbaset.h'
+ ],
+ 'destination': '<(nss_public_dist_dir)/<(module)'
+ },
+ {
+ 'files': [
+ 'base.h',
+ 'baset.h'
+ ],
+ 'destination': '<(nss_private_dist_dir)/<(module)'
+ }
+ ]
+ }
+ ],
+ 'variables': {
+ 'module': 'nss'
+ }
+}
diff --git a/nss/lib/base/hash.c b/nss/lib/base/hash.c
index 7eaaf6f..f9ee758 100644
--- a/nss/lib/base/hash.c
+++ b/nss/lib/base/hash.c
@@ -32,48 +32,42 @@
*/
struct nssHashStr {
- NSSArena *arena;
- PRBool i_alloced_arena;
- PRLock *mutex;
+ NSSArena *arena;
+ PRBool i_alloced_arena;
+ PRLock *mutex;
- /*
- * The invariant that mutex protects is:
- * The count accurately reflects the hashtable state.
- */
+ /*
+ * The invariant that mutex protects is:
+ * The count accurately reflects the hashtable state.
+ */
- PLHashTable *plHashTable;
- PRUint32 count;
+ PLHashTable *plHashTable;
+ PRUint32 count;
};
static PLHashNumber
-nss_identity_hash
-(
- const void *key
-)
+nss_identity_hash(const void *key)
{
- return (PLHashNumber)((char *)key - (char *)NULL);
+ return (PLHashNumber)((char *)key - (char *)NULL);
}
static PLHashNumber
-nss_item_hash
-(
- const void *key
-)
+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;
+ 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);
+ PRStatus ignore;
+ return (int)nssItem_Equal((NSSItem *)v1, (NSSItem *)v2, &ignore);
}
/*
@@ -81,60 +75,54 @@ nss_compare_items(const void *v1, const void *v2)
*
*/
NSS_IMPLEMENT nssHash *
-nssHash_Create
-(
- NSSArena *arenaOpt,
- PRUint32 numBuckets,
- PLHashFunction keyHash,
- PLHashComparator keyCompare,
- PLHashComparator valueCompare
-)
+nssHash_Create(NSSArena *arenaOpt, PRUint32 numBuckets, PLHashFunction keyHash,
+ PLHashComparator keyCompare, PLHashComparator valueCompare)
{
- nssHash *rv;
- NSSArena *arena;
- PRBool i_alloced;
+ 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;
- }
+ 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;
+ 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;
+ (void)nss_ZFreeIf(rv);
+ return (nssHash *)NULL;
}
/*
@@ -142,14 +130,10 @@ loser:
*
*/
NSS_IMPLEMENT nssHash *
-nssHash_CreatePointer
-(
- NSSArena *arenaOpt,
- PRUint32 numBuckets
-)
+nssHash_CreatePointer(NSSArena *arenaOpt, PRUint32 numBuckets)
{
- return nssHash_Create(arenaOpt, numBuckets,
- nss_identity_hash, PL_CompareValues, PL_CompareValues);
+ return nssHash_Create(arenaOpt, numBuckets, nss_identity_hash,
+ PL_CompareValues, PL_CompareValues);
}
/*
@@ -157,14 +141,10 @@ nssHash_CreatePointer
*
*/
NSS_IMPLEMENT nssHash *
-nssHash_CreateString
-(
- NSSArena *arenaOpt,
- PRUint32 numBuckets
-)
+nssHash_CreateString(NSSArena *arenaOpt, PRUint32 numBuckets)
{
- return nssHash_Create(arenaOpt, numBuckets,
- PL_HashString, PL_CompareStrings, PL_CompareStrings);
+ return nssHash_Create(arenaOpt, numBuckets, PL_HashString,
+ PL_CompareStrings, PL_CompareStrings);
}
/*
@@ -172,14 +152,10 @@ nssHash_CreateString
*
*/
NSS_IMPLEMENT nssHash *
-nssHash_CreateItem
-(
- NSSArena *arenaOpt,
- PRUint32 numBuckets
-)
+nssHash_CreateItem(NSSArena *arenaOpt, PRUint32 numBuckets)
{
- return nssHash_Create(arenaOpt, numBuckets,
- nss_item_hash, nss_compare_items, PL_CompareValues);
+ return nssHash_Create(arenaOpt, numBuckets, nss_item_hash,
+ nss_compare_items, PL_CompareValues);
}
/*
@@ -187,18 +163,15 @@ nssHash_CreateItem
*
*/
NSS_IMPLEMENT void
-nssHash_Destroy
-(
- nssHash *hash
-)
+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);
- }
+ (void)PZ_DestroyLock(hash->mutex);
+ PL_HashTableDestroy(hash->plHashTable);
+ if (hash->i_alloced_arena) {
+ nssArena_Destroy(hash->arena);
+ } else {
+ nss_ZFreeIf(hash);
+ }
}
/*
@@ -206,31 +179,26 @@ nssHash_Destroy
*
*/
NSS_IMPLEMENT PRStatus
-nssHash_Add
-(
- nssHash *hash,
- const void *key,
- const void *value
-)
+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;
+ 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;
}
/*
@@ -238,23 +206,19 @@ nssHash_Add
*
*/
NSS_IMPLEMENT void
-nssHash_Remove
-(
- nssHash *hash,
- const void *it
-)
+nssHash_Remove(nssHash *hash, const void *it)
{
- PRBool found;
+ PRBool found;
- PZ_Lock(hash->mutex);
+ PZ_Lock(hash->mutex);
- found = PL_HashTableRemove(hash->plHashTable, it);
- if( found ) {
- hash->count--;
- }
+ found = PL_HashTableRemove(hash->plHashTable, it);
+ if (found) {
+ hash->count--;
+ }
- (void)PZ_Unlock(hash->mutex);
- return;
+ (void)PZ_Unlock(hash->mutex);
+ return;
}
/*
@@ -262,20 +226,17 @@ nssHash_Remove
*
*/
NSS_IMPLEMENT PRUint32
-nssHash_Count
-(
- nssHash *hash
-)
+nssHash_Count(nssHash *hash)
{
- PRUint32 count;
+ PRUint32 count;
- PZ_Lock(hash->mutex);
+ PZ_Lock(hash->mutex);
- count = hash->count;
+ count = hash->count;
- (void)PZ_Unlock(hash->mutex);
+ (void)PZ_Unlock(hash->mutex);
- return count;
+ return count;
}
/*
@@ -283,25 +244,21 @@ nssHash_Count
*
*/
NSS_IMPLEMENT PRBool
-nssHash_Exists
-(
- nssHash *hash,
- const void *it
-)
+nssHash_Exists(nssHash *hash, const void *it)
{
- void *value;
+ void *value;
- PZ_Lock(hash->mutex);
+ PZ_Lock(hash->mutex);
- value = PL_HashTableLookup(hash->plHashTable, it);
+ value = PL_HashTableLookup(hash->plHashTable, it);
- (void)PZ_Unlock(hash->mutex);
+ (void)PZ_Unlock(hash->mutex);
- if( (void *)NULL == value ) {
- return PR_FALSE;
- } else {
- return PR_TRUE;
- }
+ if ((void *)NULL == value) {
+ return PR_FALSE;
+ } else {
+ return PR_TRUE;
+ }
}
/*
@@ -309,39 +266,30 @@ nssHash_Exists
*
*/
NSS_IMPLEMENT void *
-nssHash_Lookup
-(
- nssHash *hash,
- const void *it
-)
+nssHash_Lookup(nssHash *hash, const void *it)
{
- void *rv;
+ void *rv;
- PZ_Lock(hash->mutex);
+ PZ_Lock(hash->mutex);
- rv = PL_HashTableLookup(hash->plHashTable, it);
+ rv = PL_HashTableLookup(hash->plHashTable, it);
- (void)PZ_Unlock(hash->mutex);
+ (void)PZ_Unlock(hash->mutex);
- return rv;
+ return rv;
}
struct arg_str {
- nssHashIterator fcn;
- void *closure;
+ nssHashIterator fcn;
+ void *closure;
};
static PRIntn
-nss_hash_enumerator
-(
- PLHashEntry *he,
- PRIntn index,
- void *arg
-)
+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;
+ struct arg_str *as = (struct arg_str *)arg;
+ as->fcn(he->key, he->value, as->closure);
+ return HT_ENUMERATE_NEXT;
}
/*
@@ -350,22 +298,17 @@ nss_hash_enumerator
* NOTE that the iteration function will be called with the hashtable locked.
*/
NSS_IMPLEMENT void
-nssHash_Iterate
-(
- nssHash *hash,
- nssHashIterator fcn,
- void *closure
-)
+nssHash_Iterate(nssHash *hash, nssHashIterator fcn, void *closure)
{
- struct arg_str as;
- as.fcn = fcn;
- as.closure = closure;
+ struct arg_str as;
+ as.fcn = fcn;
+ as.closure = closure;
- PZ_Lock(hash->mutex);
+ PZ_Lock(hash->mutex);
- PL_HashTableEnumerateEntries(hash->plHashTable, nss_hash_enumerator, &as);
+ PL_HashTableEnumerateEntries(hash->plHashTable, nss_hash_enumerator, &as);
- (void)PZ_Unlock(hash->mutex);
+ (void)PZ_Unlock(hash->mutex);
- return;
+ return;
}
diff --git a/nss/lib/base/hashops.c b/nss/lib/base/hashops.c
index dd048ef..57b30dd 100644
--- a/nss/lib/base/hashops.c
+++ b/nss/lib/base/hashops.c
@@ -12,73 +12,53 @@
#include "base.h"
#endif /* BASE_H */
-static void * PR_CALLBACK
-nss_arena_hash_alloc_table
-(
- void *pool,
- PRSize size
-)
+static void *PR_CALLBACK
+nss_arena_hash_alloc_table(void *pool, PRSize size)
{
- NSSArena *arena = (NSSArena *)NULL;
+ NSSArena *arena = (NSSArena *)NULL;
#ifdef NSSDEBUG
- if( (void *)NULL != arena ) {
- if( PR_SUCCESS != nssArena_verifyPointer(arena) ) {
- return (void *)NULL;
+ if ((void *)NULL != arena) {
+ if (PR_SUCCESS != nssArena_verifyPointer(arena)) {
+ return (void *)NULL;
+ }
}
- }
#endif /* NSSDEBUG */
- return nss_ZAlloc(arena, size);
+ return nss_ZAlloc(arena, size);
}
static void PR_CALLBACK
-nss_arena_hash_free_table
-(
- void *pool,
- void *item
-)
+nss_arena_hash_free_table(void *pool, void *item)
{
- (void)nss_ZFreeIf(item);
+ (void)nss_ZFreeIf(item);
}
-static PLHashEntry * PR_CALLBACK
-nss_arena_hash_alloc_entry
-(
- void *pool,
- const void *key
-)
+static PLHashEntry *PR_CALLBACK
+nss_arena_hash_alloc_entry(void *pool, const void *key)
{
- NSSArena *arena = NULL;
+ NSSArena *arena = NULL;
#ifdef NSSDEBUG
- if( (void *)NULL != arena ) {
- if( PR_SUCCESS != nssArena_verifyPointer(arena) ) {
- return (void *)NULL;
+ if ((void *)NULL != arena) {
+ if (PR_SUCCESS != nssArena_verifyPointer(arena)) {
+ return (void *)NULL;
+ }
}
- }
#endif /* NSSDEBUG */
- return nss_ZNEW(arena, PLHashEntry);
+ return nss_ZNEW(arena, PLHashEntry);
}
static void PR_CALLBACK
-nss_arena_hash_free_entry
-(
- void *pool,
- PLHashEntry *he,
- PRUintn flag
-)
+nss_arena_hash_free_entry(void *pool, PLHashEntry *he, PRUintn flag)
{
- if( HT_FREE_ENTRY == flag ) {
- (void)nss_ZFreeIf(he);
- }
+ 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
+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/nss/lib/base/item.c b/nss/lib/base/item.c
index dd463dc..a1bb802 100644
--- a/nss/lib/base/item.c
+++ b/nss/lib/base/item.c
@@ -22,78 +22,69 @@
* 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_Create(NSSArena *arenaOpt, NSSItem *rvOpt, PRUint32 length,
+ const void *data)
{
- NSSItem *rv = (NSSItem *)NULL;
+ NSSItem *rv = (NSSItem *)NULL;
#ifdef DEBUG
- if( (NSSArena *)NULL != arenaOpt ) {
- if( PR_SUCCESS != nssArena_verifyPointer(arenaOpt) ) {
- return (NSSItem *)NULL;
+ 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;
+ 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;
+ if ((NSSItem *)NULL == rvOpt) {
+ rv = (NSSItem *)nss_ZNEW(arenaOpt, NSSItem);
+ if ((NSSItem *)NULL == rv) {
+ goto loser;
+ }
+ } else {
+ rv = rvOpt;
}
- } else {
- rv = rvOpt;
- }
- rv->size = length;
- rv->data = nss_ZAlloc(arenaOpt, length);
- if( (void *)NULL == rv->data ) {
- goto loser;
- }
+ 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);
- }
+ if (length > 0) {
+ (void)nsslibc_memcpy(rv->data, data, length);
+ }
- return rv;
+ return rv;
- loser:
- if( rv != rvOpt ) {
- nss_ZFreeIf(rv);
- }
+loser:
+ if (rv != rvOpt) {
+ nss_ZFreeIf(rv);
+ }
- return (NSSItem *)NULL;
+ return (NSSItem *)NULL;
}
NSS_IMPLEMENT void
-nssItem_Destroy
-(
- NSSItem *item
-)
+nssItem_Destroy(NSSItem *item)
{
- nss_ClearErrorStack();
-
- nss_ZFreeIf(item->data);
- nss_ZFreeIf(item);
+ nss_ClearErrorStack();
+ nss_ZFreeIf(item->data);
+ nss_ZFreeIf(item);
}
/*
@@ -106,34 +97,29 @@ nssItem_Destroy
* 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
-)
+nssItem_Duplicate(NSSItem *obj, NSSArena *arenaOpt, NSSItem *rvOpt)
{
#ifdef DEBUG
- if( (NSSArena *)NULL != arenaOpt ) {
- if( PR_SUCCESS != nssArena_verifyPointer(arenaOpt) ) {
- return (NSSItem *)NULL;
+ 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;
- }
+ if ((NSSItem *)NULL == obj) {
+ nss_SetError(NSS_ERROR_INVALID_ITEM);
+ return (NSSItem *)NULL;
+ }
#endif /* DEBUG */
- return nssItem_Create(arenaOpt, rvOpt, obj->size, obj->data);
+ return nssItem_Create(arenaOpt, rvOpt, obj->size, obj->data);
}
#ifdef DEBUG
@@ -151,18 +137,15 @@ nssItem_Duplicate
*/
NSS_IMPLEMENT PRStatus
-nssItem_verifyPointer
-(
- const NSSItem *item
-)
+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;
- }
+ if (((const NSSItem *)NULL == item) ||
+ (((void *)NULL == item->data) && (item->size > 0))) {
+ nss_SetError(NSS_ERROR_INVALID_ITEM);
+ return PR_FAILURE;
+ }
- return PR_SUCCESS;
+ return PR_SUCCESS;
}
#endif /* DEBUG */
@@ -181,28 +164,23 @@ nssItem_verifyPointer
*/
NSS_IMPLEMENT PRBool
-nssItem_Equal
-(
- const NSSItem *one,
- const NSSItem *two,
- PRStatus *statusOpt
-)
+nssItem_Equal(const NSSItem *one, const NSSItem *two, PRStatus *statusOpt)
{
- if( (PRStatus *)NULL != statusOpt ) {
- *statusOpt = PR_SUCCESS;
- }
+ 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_TRUE;
+ }
- if( ((const NSSItem *)NULL == one) || ((const NSSItem *)NULL == two) ) {
- return PR_FALSE;
- }
+ if (((const NSSItem *)NULL == one) || ((const NSSItem *)NULL == two)) {
+ return PR_FALSE;
+ }
- if( one->size != two->size ) {
- return PR_FALSE;
- }
+ if (one->size != two->size) {
+ return PR_FALSE;
+ }
- return nsslibc_memequal(one->data, two->data, one->size, statusOpt);
+ return nsslibc_memequal(one->data, two->data, one->size, statusOpt);
}
diff --git a/nss/lib/base/libc.c b/nss/lib/base/libc.c
index 93a7627..7954a31 100644
--- a/nss/lib/base/libc.c
+++ b/nss/lib/base/libc.c
@@ -5,10 +5,10 @@
/*
* 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
+ * 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.
*/
@@ -38,21 +38,16 @@
*/
NSS_IMPLEMENT void *
-nsslibc_memcpy
-(
- void *dest,
- const void *source,
- PRUint32 n
-)
+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;
- }
+ 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);
+ return memcpy(dest, source, (size_t)n);
}
/*
@@ -67,21 +62,16 @@ nsslibc_memcpy
*/
NSS_IMPLEMENT void *
-nsslibc_memset
-(
- void *dest,
- PRUint8 byte,
- PRUint32 n
-)
+nsslibc_memset(void *dest, PRUint8 byte, PRUint32 n)
{
#ifdef NSSDEBUG
- if( ((void *)NULL == dest) ) {
- nss_SetError(NSS_ERROR_INVALID_POINTER);
- return (void *)NULL;
- }
+ if (((void *)NULL == dest)) {
+ nss_SetError(NSS_ERROR_INVALID_POINTER);
+ return (void *)NULL;
+ }
#endif /* NSSDEBUG */
- return memset(dest, (int)byte, (size_t)n);
+ return memset(dest, (int)byte, (size_t)n);
}
/*
@@ -97,33 +87,28 @@ nsslibc_memset
*/
NSS_IMPLEMENT PRBool
-nsslibc_memequal
-(
- const void *a,
- const void *b,
- PRUint32 len,
- PRStatus *statusOpt
-)
+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;
+ if ((((void *)NULL == a) || ((void *)NULL == b))) {
+ nss_SetError(NSS_ERROR_INVALID_POINTER);
+ if ((PRStatus *)NULL != statusOpt) {
+ *statusOpt = PR_FAILURE;
+ }
+ return PR_FALSE;
}
- return PR_FALSE;
- }
#endif /* NSSDEBUG */
- if( (PRStatus *)NULL != statusOpt ) {
- *statusOpt = PR_SUCCESS;
- }
+ if ((PRStatus *)NULL != statusOpt) {
+ *statusOpt = PR_SUCCESS;
+ }
- if( 0 == memcmp(a, b, len) ) {
- return PR_TRUE;
- } else {
- return PR_FALSE;
- }
+ if (0 == memcmp(a, b, len)) {
+ return PR_TRUE;
+ } else {
+ return PR_FALSE;
+ }
}
/*
@@ -131,32 +116,26 @@ nsslibc_memequal
*/
NSS_IMPLEMENT PRInt32
-nsslibc_memcmp
-(
- const void *a,
- const void *b,
- PRUint32 len,
- PRStatus *statusOpt
-)
+nsslibc_memcmp(const void *a, const void *b, PRUint32 len, PRStatus *statusOpt)
{
- int v;
+ int v;
#ifdef NSSDEBUG
- if( (((void *)NULL == a) || ((void *)NULL == b)) ) {
- nss_SetError(NSS_ERROR_INVALID_POINTER);
- if( (PRStatus *)NULL != statusOpt ) {
- *statusOpt = PR_FAILURE;
+ if ((((void *)NULL == a) || ((void *)NULL == b))) {
+ nss_SetError(NSS_ERROR_INVALID_POINTER);
+ if ((PRStatus *)NULL != statusOpt) {
+ *statusOpt = PR_FAILURE;
+ }
+ return -2;
}
- return -2;
- }
#endif /* NSSDEBUG */
- if( (PRStatus *)NULL != statusOpt ) {
- *statusOpt = PR_SUCCESS;
- }
+ if ((PRStatus *)NULL != statusOpt) {
+ *statusOpt = PR_SUCCESS;
+ }
- v = memcmp(a, b, len);
- return (PRInt32)v;
+ v = memcmp(a, b, len);
+ return (PRInt32)v;
}
/*
diff --git a/nss/lib/base/list.c b/nss/lib/base/list.c
index 5f34923..e798cf0 100644
--- a/nss/lib/base/list.c
+++ b/nss/lib/base/list.c
@@ -13,19 +13,19 @@
#endif /* BASE_H */
struct nssListElementStr {
- PRCList link;
- void *data;
+ PRCList link;
+ void *data;
};
typedef struct nssListElementStr nssListElement;
struct nssListStr {
- NSSArena *arena;
- PZLock *lock;
+ NSSArena *arena;
+ PZLock *lock;
nssListElement *head;
- PRUint32 count;
+ PRUint32 count;
nssListCompareFunc compareFunc;
- nssListSortFunc sortFunc;
+ nssListSortFunc sortFunc;
PRBool i_alloced_arena;
};
@@ -36,10 +36,12 @@ struct nssListIteratorStr {
};
#define NSSLIST_LOCK_IF(list) \
- if ((list)->lock) PZ_Lock((list)->lock)
+ if ((list)->lock) \
+ PZ_Lock((list)->lock)
#define NSSLIST_UNLOCK_IF(list) \
- if ((list)->lock) PZ_Unlock((list)->lock)
+ if ((list)->lock) \
+ PZ_Unlock((list)->lock)
static PRBool
pointer_compare(void *a, void *b)
@@ -50,65 +52,58 @@ pointer_compare(void *a, void *b)
static nssListElement *
nsslist_get_matching_element(nssList *list, void *data)
{
- PRCList *link;
nssListElement *node;
node = list->head;
if (!node) {
- return NULL;
+ 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);
+ /* using a callback slows things down when it's just compare ... */
+ if (list->compareFunc(node->data, data)) {
+ break;
+ }
+ if (&node->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
-)
+nssList_Create(NSSArena *arenaOpt, PRBool threadSafe)
{
NSSArena *arena;
nssList *list;
PRBool i_alloced;
if (arenaOpt) {
- arena = arenaOpt;
- i_alloced = PR_FALSE;
+ arena = arenaOpt;
+ i_alloced = PR_FALSE;
} else {
- arena = nssArena_Create();
- i_alloced = PR_TRUE;
+ arena = nssArena_Create();
+ i_alloced = PR_TRUE;
}
if (!arena) {
- return (nssList *)NULL;
+ return (nssList *)NULL;
}
list = nss_ZNEW(arena, nssList);
if (!list) {
- if (!arenaOpt) {
- NSSArena_Destroy(arena);
- }
- return (nssList *)NULL;
+ 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->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;
@@ -119,15 +114,18 @@ nssList_Create
NSS_IMPLEMENT PRStatus
nssList_Destroy(nssList *list)
{
+ if (!list) {
+ return PR_SUCCESS;
+ }
if (!list->i_alloced_arena) {
- nssList_Clear(list, NULL);
+ nssList_Clear(list, NULL);
}
if (list->lock) {
- (void)PZ_DestroyLock(list->lock);
+ (void)PZ_DestroyLock(list->lock);
}
if (list->i_alloced_arena) {
- NSSArena_Destroy(list->arena);
- list = NULL;
+ NSSArena_Destroy(list->arena);
+ list = NULL;
}
nss_ZFreeIf(list);
return PR_SUCCESS;
@@ -157,17 +155,21 @@ nssList_Clear(nssList *list, nssListElementDestructorFunc destructor)
{
PRCList *link;
nssListElement *node, *tmp;
+ if (!list) {
+ return;
+ }
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;
+ 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);
}
@@ -177,38 +179,39 @@ nsslist_add_element(nssList *list, void *data)
{
nssListElement *node = nss_ZNEW(list->arena, nssListElement);
if (!node) {
- return PR_FAILURE;
+ 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);
- }
+ 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->head = node;
}
++list->count;
return PR_SUCCESS;
@@ -231,9 +234,9 @@ nssList_AddUnique(nssList *list, void *data)
NSSLIST_LOCK_IF(list);
node = nsslist_get_matching_element(list, data);
if (node) {
- /* already in, finish */
- NSSLIST_UNLOCK_IF(list);
- return PR_SUCCESS;
+ /* already in, finish */
+ NSSLIST_UNLOCK_IF(list);
+ return PR_SUCCESS;
}
nssrv = nsslist_add_element(list, data);
NSSLIST_UNLOCK_IF(list);
@@ -247,14 +250,14 @@ nssList_Remove(nssList *list, void *data)
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;
- }
+ 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;
@@ -284,16 +287,17 @@ nssList_GetArray(nssList *list, void **rvArray, PRUint32 maxElements)
PR_ASSERT(maxElements > 0);
node = list->head;
if (!node) {
- return PR_SUCCESS;
+ 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;
- }
+ 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;
@@ -306,18 +310,18 @@ nssList_Clone(nssList *list)
nssListElement *node;
rvList = nssList_Create(NULL, (list->lock != NULL));
if (!rvList) {
- return NULL;
+ 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;
- }
- }
+ 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;
@@ -329,21 +333,21 @@ nssList_CreateIterator(nssList *list)
nssListIterator *rvIterator;
rvIterator = nss_ZNEW(NULL, nssListIterator);
if (!rvIterator) {
- return NULL;
+ return NULL;
}
rvIterator->list = nssList_Clone(list);
if (!rvIterator->list) {
- nss_ZFreeIf(rvIterator);
- return NULL;
+ 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;
- }
+ rvIterator->lock = PZ_NewLock(nssILockOther);
+ if (!rvIterator->lock) {
+ nssList_Destroy(rvIterator->list);
+ nss_ZFreeIf(rvIterator);
+ rvIterator = NULL;
+ }
}
return rvIterator;
}
@@ -352,9 +356,11 @@ NSS_IMPLEMENT void
nssListIterator_Destroy(nssListIterator *iter)
{
if (iter->lock) {
- (void)PZ_DestroyLock(iter->lock);
+ (void)PZ_DestroyLock(iter->lock);
+ }
+ if (iter->list) {
+ nssList_Destroy(iter->list);
}
- nssList_Destroy(iter->list);
nss_ZFreeIf(iter);
}
@@ -363,7 +369,7 @@ nssListIterator_Start(nssListIterator *iter)
{
NSSLIST_LOCK_IF(iter);
if (iter->list->count == 0) {
- return NULL;
+ return NULL;
}
iter->current = iter->list->head;
return iter->current->data;
@@ -375,17 +381,17 @@ 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;
+ /* 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;
+ /* Signal the end of the list. */
+ iter->current = NULL;
+ return node->data;
}
iter->current = node;
return node->data;
@@ -397,4 +403,3 @@ nssListIterator_Finish(nssListIterator *iter)
iter->current = iter->list->head;
return (iter->lock) ? PZ_Unlock(iter->lock) : PR_SUCCESS;
}
-
diff --git a/nss/lib/base/nssbase.h b/nss/lib/base/nssbase.h
index 4e14d3b..02e285f 100644
--- a/nss/lib/base/nssbase.h
+++ b/nss/lib/base/nssbase.h
@@ -44,11 +44,7 @@ PR_BEGIN_EXTERN_C
* A pointer to an NSSArena upon success
*/
-NSS_EXTERN NSSArena *
-NSSArena_Create
-(
- void
-);
+NSS_EXTERN NSSArena *NSSArena_Create(void);
extern const NSSError NSS_ERROR_NO_MEMORY;
@@ -56,7 +52,7 @@ 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
+ * 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.
*
@@ -68,11 +64,7 @@ extern const NSSError NSS_ERROR_NO_MEMORY;
* PR_FAILURE upon failure
*/
-NSS_EXTERN PRStatus
-NSSArena_Destroy
-(
- NSSArena *arena
-);
+NSS_EXTERN PRStatus NSSArena_Destroy(NSSArena *arena);
extern const NSSError NSS_ERROR_INVALID_ARENA;
@@ -100,25 +92,21 @@ extern const NSSError NSS_ERROR_INVALID_ARENA;
* A nonzero error number
*/
-NSS_EXTERN NSSError
-NSS_GetError
-(
- void
-);
+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 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:
@@ -126,21 +114,17 @@ extern const NSSError NSS_ERROR_NO_ERROR;
* A NON-caller-owned pointer to an array of NSSError values
*/
-NSS_EXTERN NSSError *
-NSS_GetErrorStack
-(
- void
-);
+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
+ * 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:
@@ -152,7 +136,6 @@ NSS_GetErrorStack
* 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)))
/*
@@ -160,10 +143,10 @@ NSS_GetErrorStack
*
* 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
+ * 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:
@@ -175,20 +158,19 @@ NSS_GetErrorStack
* 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)))
-
+#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
+ * 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
+ * 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.
*
@@ -202,21 +184,16 @@ NSS_GetErrorStack
* A pointer to the new segment of zeroed memory
*/
-NSS_EXTERN void *
-NSS_ZAlloc
-(
- NSSArena *arenaOpt,
- PRUint32 size
-);
+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
+ * 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
+ * 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:
@@ -229,13 +206,7 @@ NSS_ZAlloc
* A pointer to the replacement segment of memory
*/
-NSS_EXTERN void *
-NSS_ZRealloc
-(
- void *pointer,
- PRUint32 newSize
-);
-
+NSS_EXTERN void *NSS_ZRealloc(void *pointer, PRUint32 newSize);
/*
* NSS_ZFreeIf
@@ -255,11 +226,7 @@ NSS_ZRealloc
* PR_FAILURE
*/
-NSS_EXTERN PRStatus
-NSS_ZFreeIf
-(
- void *pointer
-);
+NSS_EXTERN PRStatus NSS_ZFreeIf(void *pointer);
PR_END_EXTERN_C
diff --git a/nss/lib/base/nssbaset.h b/nss/lib/base/nssbaset.h
index e5830e1..8bc556e 100644
--- a/nss/lib/base/nssbaset.h
+++ b/nss/lib/base/nssbaset.h
@@ -18,16 +18,16 @@
* 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
+ * 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
+#define DUMMY /* dummy */
+#define NSS_EXTERN extern
+#define NSS_EXTERN_DATA extern
+#define NSS_IMPLEMENT
+#define NSS_IMPLEMENT_DATA
PR_BEGIN_EXTERN_C
@@ -36,7 +36,7 @@ PR_BEGIN_EXTERN_C
*
* 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
+ * may be returned from a function is declared where the function is
* prototyped. All errors are of the following type.
*/
@@ -47,7 +47,7 @@ typedef PRInt32 NSSError;
*
* 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:
+ * 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.
@@ -64,12 +64,11 @@ typedef struct NSSArenaStr NSSArena;
*/
struct NSSItemStr {
- void *data;
- PRUint32 size;
+ void *data;
+ PRUint32 size;
};
typedef struct NSSItemStr NSSItem;
-
/*
* NSSBER
*
diff --git a/nss/lib/base/tracker.c b/nss/lib/base/tracker.c
index 06e2baf..850add7 100644
--- a/nss/lib/base/tracker.c
+++ b/nss/lib/base/tracker.c
@@ -4,7 +4,7 @@
/*
* 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).
@@ -24,12 +24,9 @@
*/
static PLHashNumber PR_CALLBACK
-identity_hash
-(
- const void *key
-)
+identity_hash(const void *key)
{
- return (PLHashNumber)((char *)key - (char *)NULL);
+ return (PLHashNumber)((char *)key - (char *)NULL);
}
/*
@@ -41,44 +38,38 @@ identity_hash
*/
static PRStatus
-trackerOnceFunc
-(
- void *arg
-)
+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 *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
+ * 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:
@@ -90,17 +81,14 @@ trackerOnceFunc
*/
NSS_IMPLEMENT PRStatus
-nssPointerTracker_initialize
-(
- nssPointerTracker *tracker
-)
+nssPointerTracker_initialize(nssPointerTracker *tracker)
{
- PRStatus rv = PR_CallOnceWithArg(&tracker->once, trackerOnceFunc, tracker);
- if( PR_SUCCESS != rv ) {
- nss_SetError(NSS_ERROR_NO_MEMORY);
- }
+ PRStatus rv = PR_CallOnceWithArg(&tracker->once, trackerOnceFunc, tracker);
+ if (PR_SUCCESS != rv) {
+ nss_SetError(NSS_ERROR_NO_MEMORY);
+ }
- return rv;
+ return rv;
}
#ifdef DONT_DESTROY_EMPTY_TABLES
@@ -114,14 +102,9 @@ nssPointerTracker_initialize
*/
static PRIntn PR_CALLBACK
-count_entries
-(
- PLHashEntry *he,
- PRIntn index,
- void *arg
-)
+count_entries(PLHashEntry *he, PRIntn index, void *arg)
{
- return HT_ENUMERATE_NEXT;
+ return HT_ENUMERATE_NEXT;
}
#endif /* DONT_DESTROY_EMPTY_TABLES */
@@ -138,7 +121,7 @@ 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
@@ -160,58 +143,54 @@ static const PRCallOnceType zero_once;
*/
NSS_IMPLEMENT PRStatus
-nssPointerTracker_finalize
-(
- nssPointerTracker *tracker
-)
+nssPointerTracker_finalize(nssPointerTracker *tracker)
{
- PZLock *lock;
+ PZLock *lock;
- if( (nssPointerTracker *)NULL == tracker ) {
- nss_SetError(NSS_ERROR_INVALID_POINTER);
- return PR_FAILURE;
- }
+ 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;
- }
+ if ((PZLock *)NULL == tracker->lock) {
+ nss_SetError(NSS_ERROR_TRACKER_NOT_INITIALIZED);
+ return PR_FAILURE;
+ }
- lock = tracker->lock;
- PZ_Lock(lock);
+ lock = tracker->lock;
+ PZ_Lock(lock);
- if( (PLHashTable *)NULL == tracker->table ) {
- PZ_Unlock(lock);
- nss_SetError(NSS_ERROR_TRACKER_NOT_INITIALIZED);
- return PR_FAILURE;
- }
+ 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;
- }
+ /*
+ * 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;
+ 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);
+ PZ_Unlock(lock);
+ PZ_DestroyLock(lock);
- return PR_SUCCESS;
+ return PR_SUCCESS;
}
/*
@@ -238,63 +217,59 @@ nssPointerTracker_finalize
*/
NSS_IMPLEMENT PRStatus
-nssPointerTracker_add
-(
- nssPointerTracker *tracker,
- const void *pointer
-)
+nssPointerTracker_add(nssPointerTracker *tracker, const void *pointer)
{
- void *check;
- PLHashEntry *entry;
+ void *check;
+ PLHashEntry *entry;
- if( (nssPointerTracker *)NULL == tracker ) {
- nss_SetError(NSS_ERROR_INVALID_POINTER);
- return PR_FAILURE;
- }
+ 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;
- }
+ if ((PZLock *)NULL == tracker->lock) {
+ nss_SetError(NSS_ERROR_TRACKER_NOT_INITIALIZED);
+ return PR_FAILURE;
+ }
- PZ_Lock(tracker->lock);
+ PZ_Lock(tracker->lock);
- if( (PLHashTable *)NULL == tracker->table ) {
- PZ_Unlock(tracker->lock);
- nss_SetError(NSS_ERROR_TRACKER_NOT_INITIALIZED);
- return PR_FAILURE;
- }
+ 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;
- }
+ 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);
+ entry = PL_HashTableAdd(tracker->table, pointer, (void *)pointer);
- PZ_Unlock(tracker->lock);
+ PZ_Unlock(tracker->lock);
- if( (PLHashEntry *)NULL == entry ) {
- nss_SetError(NSS_ERROR_NO_MEMORY);
- return PR_FAILURE;
- }
+ if ((PLHashEntry *)NULL == entry) {
+ nss_SetError(NSS_ERROR_NO_MEMORY);
+ return PR_FAILURE;
+ }
- return PR_SUCCESS;
+ return PR_SUCCESS;
}
-
+
/*
* nssPointerTracker_remove
*
* This method is only present in debug builds.
*
- * This routine removes the specified pointer from the
+ * 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
+ * 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:
@@ -308,41 +283,37 @@ nssPointerTracker_add
*/
NSS_IMPLEMENT PRStatus
-nssPointerTracker_remove
-(
- nssPointerTracker *tracker,
- const void *pointer
-)
+nssPointerTracker_remove(nssPointerTracker *tracker, const void *pointer)
{
- PRBool registered;
+ PRBool registered;
- if( (nssPointerTracker *)NULL == tracker ) {
- nss_SetError(NSS_ERROR_INVALID_POINTER);
- return PR_FAILURE;
- }
+ 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;
- }
+ if ((PZLock *)NULL == tracker->lock) {
+ nss_SetError(NSS_ERROR_TRACKER_NOT_INITIALIZED);
+ return PR_FAILURE;
+ }
- PZ_Lock(tracker->lock);
+ PZ_Lock(tracker->lock);
- if( (PLHashTable *)NULL == tracker->table ) {
- PZ_Unlock(tracker->lock);
- nss_SetError(NSS_ERROR_TRACKER_NOT_INITIALIZED);
- return PR_FAILURE;
- }
+ 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);
+ registered = PL_HashTableRemove(tracker->table, pointer);
+ PZ_Unlock(tracker->lock);
- if( !registered ) {
- nss_SetError(NSS_ERROR_POINTER_NOT_REGISTERED);
- return PR_FAILURE;
- }
+ if (!registered) {
+ nss_SetError(NSS_ERROR_POINTER_NOT_REGISTERED);
+ return PR_FAILURE;
+ }
- return PR_SUCCESS;
+ return PR_SUCCESS;
}
/*
@@ -354,10 +325,10 @@ nssPointerTracker_remove
* 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
+ * 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:
@@ -371,41 +342,37 @@ nssPointerTracker_remove
*/
NSS_IMPLEMENT PRStatus
-nssPointerTracker_verify
-(
- nssPointerTracker *tracker,
- const void *pointer
-)
+nssPointerTracker_verify(nssPointerTracker *tracker, const void *pointer)
{
- void *check;
+ void *check;
- if( (nssPointerTracker *)NULL == tracker ) {
- nss_SetError(NSS_ERROR_INVALID_POINTER);
- return PR_FAILURE;
- }
+ 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;
- }
+ if ((PZLock *)NULL == tracker->lock) {
+ nss_SetError(NSS_ERROR_TRACKER_NOT_INITIALIZED);
+ return PR_FAILURE;
+ }
- PZ_Lock(tracker->lock);
+ PZ_Lock(tracker->lock);
- if( (PLHashTable *)NULL == tracker->table ) {
- PZ_Unlock(tracker->lock);
- nss_SetError(NSS_ERROR_TRACKER_NOT_INITIALIZED);
- return PR_FAILURE;
- }
+ 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);
+ check = PL_HashTableLookup(tracker->table, pointer);
+ PZ_Unlock(tracker->lock);
- if( (void *)NULL == check ) {
- nss_SetError(NSS_ERROR_POINTER_NOT_REGISTERED);
- return PR_FAILURE;
- }
+ if ((void *)NULL == check) {
+ nss_SetError(NSS_ERROR_POINTER_NOT_REGISTERED);
+ return PR_FAILURE;
+ }
- return PR_SUCCESS;
+ return PR_SUCCESS;
}
#endif /* DEBUG */
diff --git a/nss/lib/base/utf8.c b/nss/lib/base/utf8.c
index 490d104..6d7b6a0 100644
--- a/nss/lib/base/utf8.c
+++ b/nss/lib/base/utf8.c
@@ -24,8 +24,8 @@
/*
* nssUTF8_CaseIgnoreMatch
- *
- * Returns true if the two UTF8-encoded strings pointed to by the
+ *
+ * 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:
@@ -38,47 +38,41 @@
*/
NSS_IMPLEMENT PRBool
-nssUTF8_CaseIgnoreMatch
-(
- const NSSUTF8 *a,
- const NSSUTF8 *b,
- PRStatus *statusOpt
-)
+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;
- }
+ 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;
- }
+ 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,
+ * 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
@@ -95,92 +89,86 @@ nssUTF8_CaseIgnoreMatch
*/
NSS_IMPLEMENT PRBool
-nssUTF8_PrintableMatch
-(
- const NSSUTF8 *a,
- const NSSUTF8 *b,
- PRStatus *statusOpt
-)
+nssUTF8_PrintableMatch(const NSSUTF8 *a, const NSSUTF8 *b, PRStatus *statusOpt)
{
- PRUint8 *c;
- PRUint8 *d;
+ 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;
- }
+ 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;
- }
+ if ((PRStatus *)NULL != statusOpt) {
+ *statusOpt = PR_SUCCESS;
+ }
- c = (PRUint8 *)a;
- d = (PRUint8 *)b;
+ c = (PRUint8 *)a;
+ d = (PRUint8 *)b;
- while( ' ' == *c ) {
- c++;
- }
+ while (' ' == *c) {
+ c++;
+ }
- while( ' ' == *d ) {
- d++;
- }
+ while (' ' == *d) {
+ d++;
+ }
- while( ('\0' != *c) && ('\0' != *d) ) {
- PRUint8 e, f;
+ while (('\0' != *c) && ('\0' != *d)) {
+ PRUint8 e, f;
- e = *c;
- f = *d;
-
- if( ('a' <= e) && (e <= 'z') ) {
- e -= ('a' - 'A');
- }
+ e = *c;
+ f = *d;
- if( ('a' <= f) && (f <= 'z') ) {
- f -= ('a' - 'A');
- }
+ if (('a' <= e) && (e <= 'z')) {
+ e -= ('a' - 'A');
+ }
- if( e != f ) {
- return PR_FALSE;
- }
+ if (('a' <= f) && (f <= 'z')) {
+ f -= ('a' - 'A');
+ }
- c++;
- d++;
+ if (e != f) {
+ return PR_FALSE;
+ }
- if( ' ' == *c ) {
- while( ' ' == *c ) {
c++;
- }
- c--;
- }
-
- if( ' ' == *d ) {
- while( ' ' == *d ) {
d++;
- }
- d--;
+
+ if (' ' == *c) {
+ while (' ' == *c) {
+ c++;
+ }
+ c--;
+ }
+
+ if (' ' == *d) {
+ while (' ' == *d) {
+ d++;
+ }
+ d--;
+ }
}
- }
- while( ' ' == *c ) {
- c++;
- }
+ while (' ' == *c) {
+ c++;
+ }
- while( ' ' == *d ) {
- d++;
- }
+ while (' ' == *d) {
+ d++;
+ }
- if( *c == *d ) {
- /* And both '\0', btw */
- return PR_TRUE;
- } else {
- return PR_FALSE;
- }
+ if (*c == *d) {
+ /* And both '\0', btw */
+ return PR_TRUE;
+ } else {
+ return PR_FALSE;
+ }
}
/*
@@ -191,7 +179,7 @@ nssUTF8_PrintableMatch
* 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
+ * an error will be placed on the error stack and NULL will be
* returned.
*
* The error may be one of the following values:
@@ -201,45 +189,41 @@ nssUTF8_PrintableMatch
*/
NSS_IMPLEMENT NSSUTF8 *
-nssUTF8_Duplicate
-(
- const NSSUTF8 *s,
- NSSArena *arenaOpt
-)
+nssUTF8_Duplicate(const NSSUTF8 *s, NSSArena *arenaOpt)
{
- NSSUTF8 *rv;
- PRUint32 len;
+ NSSUTF8 *rv;
+ PRUint32 len;
#ifdef NSSDEBUG
- if( (const NSSUTF8 *)NULL == s ) {
- nss_SetError(NSS_ERROR_INVALID_POINTER);
- return (NSSUTF8 *)NULL;
- }
+ 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;
+ if ((NSSArena *)NULL != arenaOpt) {
+ if (PR_SUCCESS != nssArena_verifyPointer(arenaOpt)) {
+ return (NSSUTF8 *)NULL;
+ }
}
- }
#endif /* NSSDEBUG */
- len = PL_strlen((const char *)s);
+ 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 */
+ 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;
- }
+ rv = nss_ZAlloc(arenaOpt, len);
+ if ((void *)NULL == rv) {
+ return (NSSUTF8 *)NULL;
+ }
- (void)nsslibc_memcpy(rv, s, len);
- return rv;
+ (void)nsslibc_memcpy(rv, s, len);
+ return rv;
}
/*
@@ -259,41 +243,37 @@ nssUTF8_Duplicate
*/
NSS_IMPLEMENT PRUint32
-nssUTF8_Size
-(
- const NSSUTF8 *s,
- PRStatus *statusOpt
-)
+nssUTF8_Size(const NSSUTF8 *s, PRStatus *statusOpt)
{
- PRUint32 sv;
+ PRUint32 sv;
#ifdef NSSDEBUG
- if( (const NSSUTF8 *)NULL == s ) {
- nss_SetError(NSS_ERROR_INVALID_POINTER);
- if( (PRStatus *)NULL != statusOpt ) {
- *statusOpt = PR_FAILURE;
+ if ((const NSSUTF8 *)NULL == s) {
+ nss_SetError(NSS_ERROR_INVALID_POINTER);
+ if ((PRStatus *)NULL != statusOpt) {
+ *statusOpt = PR_FAILURE;
+ }
+ return 0;
}
- return 0;
- }
#endif /* NSSDEBUG */
- sv = PL_strlen((const char *)s) + 1;
+ 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;
+ if ('\0' != ((const char *)s)[sv - 1]) {
+ /* wrapped */
+ nss_SetError(NSS_ERROR_VALUE_TOO_LARGE);
+ if ((PRStatus *)NULL != statusOpt) {
+ *statusOpt = PR_FAILURE;
+ }
+ return 0;
}
- return 0;
- }
#endif /* PEDANTIC */
- if( (PRStatus *)NULL != statusOpt ) {
- *statusOpt = PR_SUCCESS;
- }
+ if ((PRStatus *)NULL != statusOpt) {
+ *statusOpt = PR_SUCCESS;
+ }
- return sv;
+ return sv;
}
/*
@@ -314,91 +294,86 @@ nssUTF8_Size
*/
NSS_IMPLEMENT PRUint32
-nssUTF8_Length
-(
- const NSSUTF8 *s,
- PRStatus *statusOpt
-)
+nssUTF8_Length(const NSSUTF8 *s, PRStatus *statusOpt)
{
- PRUint32 l = 0;
- const PRUint8 *c = (const PRUint8 *)s;
+ PRUint32 l = 0;
+ const PRUint8 *c = (const PRUint8 *)s;
#ifdef NSSDEBUG
- if( (const NSSUTF8 *)NULL == s ) {
- nss_SetError(NSS_ERROR_INVALID_POINTER);
- goto loser;
- }
+ 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;
- }
+ /*
+ * 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;
+ 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;
+ 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;
- }
+ c += incr;
+ }
- if( (PRStatus *)NULL != statusOpt ) {
- *statusOpt = PR_SUCCESS;
- }
+ if ((PRStatus *)NULL != statusOpt) {
+ *statusOpt = PR_SUCCESS;
+ }
- return l;
+ return l;
- loser:
- if( (PRStatus *)NULL != statusOpt ) {
- *statusOpt = PR_FAILURE;
- }
+loser:
+ if ((PRStatus *)NULL != statusOpt) {
+ *statusOpt = PR_FAILURE;
+ }
- return 0;
+ return 0;
}
-
/*
* nssUTF8_Create
*
@@ -425,261 +400,245 @@ nssUTF8_Length
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_Create(NSSArena *arenaOpt, nssStringType type, const void *inputString,
+ PRUint32 size /* in bytes, not characters */
+ )
{
- NSSUTF8 *rv = NULL;
+ NSSUTF8 *rv = NULL;
#ifdef NSSDEBUG
- if( (NSSArena *)NULL != arenaOpt ) {
- if( PR_SUCCESS != nssArena_verifyPointer(arenaOpt) ) {
- return (NSSUTF8 *)NULL;
+ 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 ) {
+ if ((const void *)NULL == inputString) {
+ nss_SetError(NSS_ERROR_INVALID_POINTER);
return (NSSUTF8 *)NULL;
- }
+ }
+#endif /* NSSDEBUG */
- (void)nsslibc_memcpy(rv, inputString, size);
+ 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;
}
- 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;
+ return rv;
}
NSS_IMPLEMENT NSSItem *
-nssUTF8_GetEncoding
-(
- NSSArena *arenaOpt,
- NSSItem *rvOpt,
- nssStringType type,
- NSSUTF8 *string
-)
+nssUTF8_GetEncoding(NSSArena *arenaOpt, NSSItem *rvOpt, nssStringType type,
+ NSSUTF8 *string)
{
- NSSItem *rv = (NSSItem *)NULL;
- PRStatus status = PR_SUCCESS;
+ NSSItem *rv = (NSSItem *)NULL;
+ PRStatus status = PR_SUCCESS;
#ifdef NSSDEBUG
- if( (NSSArena *)NULL != arenaOpt ) {
- if( PR_SUCCESS != nssArena_verifyPointer(arenaOpt) ) {
- return (NSSItem *)NULL;
+ 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;
- }
+ 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;
- }
+ 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;
+ }
- 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;
+ return rv;
}
/*
* nssUTF8_CopyIntoFixedBuffer
*
- * This will copy a UTF8 string into a fixed-length buffer, making
+ * 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
+ * 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
-)
+nssUTF8_CopyIntoFixedBuffer(NSSUTF8 *string, char *buffer, PRUint32 bufferSize,
+ char pad)
{
- PRUint32 stringSize = 0;
+ 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;
- }
+ 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;
+ 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;
}
/*
@@ -688,39 +647,33 @@ nssUTF8_CopyIntoFixedBuffer
*/
NSS_IMPLEMENT PRBool
-nssUTF8_Equal
-(
- const NSSUTF8 *a,
- const NSSUTF8 *b,
- PRStatus *statusOpt
-)
+nssUTF8_Equal(const NSSUTF8 *a, const NSSUTF8 *b, PRStatus *statusOpt)
{
- PRUint32 la, lb;
+ 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;
- }
+ 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;
- }
+ la = nssUTF8_Size(a, statusOpt);
+ if (0 == la) {
+ return PR_FALSE;
+ }
- lb = nssUTF8_Size(b, statusOpt);
- if( 0 == lb ) {
- return PR_FALSE;
- }
+ lb = nssUTF8_Size(b, statusOpt);
+ if (0 == lb) {
+ return PR_FALSE;
+ }
- if( la != lb ) {
- return PR_FALSE;
- }
+ if (la != lb) {
+ return PR_FALSE;
+ }
- return nsslibc_memequal(a, b, la, statusOpt);
+ return nsslibc_memequal(a, b, la, statusOpt);
}
diff --git a/nss/lib/certdb/alg1485.c b/nss/lib/certdb/alg1485.c
index ea1621b..b6736c4 100644
--- a/nss/lib/certdb/alg1485.c
+++ b/nss/lib/certdb/alg1485.c
@@ -13,26 +13,28 @@
#include "secerr.h"
typedef struct NameToKindStr {
- const char * name;
+ const char* name;
unsigned int maxLen; /* max bytes in UTF8 encoded string value */
- SECOidTag kind;
- int valueType;
+ 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
+/* clang-format off */
+
/* 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)
+ * (See: http://www.iana.org/assignments/ldap-parameters)
*/
/* RFC 3280, 4630 MUST SUPPORT */
{ "CN", 640, SEC_OID_AVA_COMMON_NAME, SEC_ASN1_DS},
{ "ST", 128, SEC_OID_AVA_STATE_OR_PROVINCE,
- SEC_ASN1_DS},
+ SEC_ASN1_DS},
{ "O", 128, SEC_OID_AVA_ORGANIZATION_NAME,
- SEC_ASN1_DS},
+ SEC_ASN1_DS},
{ "OU", 128, SEC_OID_AVA_ORGANIZATIONAL_UNIT_NAME,
SEC_ASN1_DS},
{ "dnQualifier", 32767, SEC_OID_AVA_DN_QUALIFIER, SEC_ASN1_PRINTABLE_STRING},
@@ -58,7 +60,7 @@ static const NameToKind name2kinds[] = {
* 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
+ * Maybe this line should be up higher? Say, after the 3280 MUSTs and
* before the 3280 SHOULDs?
*/
@@ -76,11 +78,11 @@ static const NameToKind name2kinds[] = {
/* values defined by the CAB Forum for EV */
{ "incorporationLocality", 128, SEC_OID_EV_INCORPORATION_LOCALITY,
- SEC_ASN1_DS},
+ SEC_ASN1_DS},
{ "incorporationState", 128, SEC_OID_EV_INCORPORATION_STATE,
- SEC_ASN1_DS},
+ SEC_ASN1_DS},
{ "incorporationCountry", 2, SEC_OID_EV_INCORPORATION_COUNTRY,
- SEC_ASN1_PRINTABLE_STRING},
+ SEC_ASN1_PRINTABLE_STRING},
{ "businessCategory", 64, SEC_OID_BUSINESS_CATEGORY, SEC_ASN1_DS},
/* values defined in X.520 */
@@ -91,21 +93,21 @@ static const NameToKind name2kinds[] = {
/* 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,
+/* #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
};
@@ -117,330 +119,330 @@ static const PRInt16 x2b[256] = {
#define C_EQUAL '='
-#define OPTIONAL_SPACE(c) \
+#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) == '#') || \
+#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) == '=') || \
+#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) == '?'))
+/* clang-format on */
+
/* 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_ESCAPE(c) (c == C_DOUBLE_QUOTE || c == C_BACKSLASH)
-#define NEEDS_HEX_ESCAPE(c) \
- ((PRUint8)c < 0x20 || c == 0x7f)
+#define NEEDS_HEX_ESCAPE(c) ((PRUint8)c < 0x20 || c == 0x7f)
int
cert_AVAOidTagToMaxLen(SECOidTag tag)
{
- const NameToKind *n2k = name2kinds;
+ const NameToKind* n2k = name2kinds;
while (n2k->kind != tag && n2k->kind != SEC_OID_UNKNOWN) {
- ++n2k;
+ ++n2k;
}
return (n2k->kind != SEC_OID_UNKNOWN) ? n2k->maxLen : -1;
}
static PRBool
-IsPrintable(unsigned char *data, unsigned len)
+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;
- }
+ ch = *data++;
+ if (!IS_PRINTABLE(ch)) {
+ return PR_FALSE;
+ }
}
return PR_TRUE;
}
static void
-skipSpace(const char **pbp, const char *endptr)
+skipSpace(const char** pbp, const char* endptr)
{
- const char *bp = *pbp;
+ const char* bp = *pbp;
while (bp < endptr && OPTIONAL_SPACE(*bp)) {
- bp++;
+ bp++;
}
*pbp = bp;
}
static SECStatus
-scanTag(const char **pbp, const char *endptr, char *tagBuf, int tagBufSize)
+scanTag(const char** pbp, const char* endptr, char* tagBuf, int tagBufSize)
{
- const char *bp;
- char *tagBufp;
+ 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;
+ /* 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++;
+ 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;
+ /* nothing left */
+ return SECFailure;
}
if (**pbp != C_EQUAL) {
- /* should be an equal sign */
- return SECFailure;
+ /* 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)
+scanVal(const char** pbp, const char* endptr, char* valBuf, int valBufSize)
{
- const char *bp;
- char *valBufp;
+ 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;
+ if (*pbp == endptr) {
+ /* nothing left */
+ return 0;
}
-
+
bp = *pbp;
-
+
/* quoted? */
if (*bp == C_DOUBLE_QUOTE) {
- isQuoted = PR_TRUE;
- /* skip over it */
- bp++;
+ isQuoted = PR_TRUE;
+ /* skip over it */
+ bp++;
} else {
- isQuoted = PR_FALSE;
+ 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 */
+ 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++;
- }
-
+ 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;
- }
-
+ 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);
- }
-
+ /* 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)
+hexToBin(PLArenaPool* pool, SECItem* destItem, const char* src, int len)
{
- PRUint8 * dest;
+ PRUint8* dest;
- destItem->data = NULL;
+ destItem->data = NULL;
if (len <= 0 || (len & 1)) {
- goto loser;
+ goto loser;
}
len >>= 1;
if (!SECITEM_AllocItem(pool, destItem, len))
- goto loser;
+ 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;
+ 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);
+ 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
+ * 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(PLArenaPool *arena, const char **pbp, const char *endptr)
+static CERTAVA*
+ParseRFC1485AVA(PLArenaPool* 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;
+ 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[1024];
PORT_Assert(arena);
if (SECSuccess != scanTag(pbp, endptr, tagBuf, sizeof tagBuf) ||
- !(valLen = scanVal(pbp, endptr, valBuf, sizeof valBuf))) {
- goto loser;
+ !(valLen = scanVal(pbp, endptr, valBuf, sizeof valBuf))) {
+ goto loser;
}
bp = *pbp;
if (bp < endptr) {
- sep = *bp++; /* skip over separator */
+ 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;
+ 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;
+ 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);
+ /* 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);
+ 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;
@@ -450,80 +452,81 @@ loser:
return 0;
}
-static CERTName *
-ParseRFC1485Name(const char *buf, int len)
+static CERTName*
+ParseRFC1485Name(const char* buf, int len)
{
SECStatus rv;
- CERTName *name;
+ CERTName* name;
const char *bp, *e;
- CERTAVA *ava;
- CERTRDN *rdn = NULL;
+ CERTAVA* ava;
+ CERTRDN* rdn = NULL;
name = CERT_CreateName(NULL);
if (name == NULL) {
- return 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);
+ 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;
+ /* 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;
- }
- }
-
+ 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:
+
+loser:
CERT_DestroyName(name);
return NULL;
}
-CERTName *
-CERT_AsciiToName(const char *string)
+CERTName*
+CERT_AsciiToName(const char* string)
{
- CERTName *name;
+ CERTName* name;
name = ParseRFC1485Name(string, PORT_Strlen(string));
return name;
}
@@ -531,7 +534,7 @@ CERT_AsciiToName(const char *string)
/************************************************************************/
typedef struct stringBufStr {
- char *buffer;
+ char* buffer;
unsigned offset;
unsigned size;
} stringBuf;
@@ -539,9 +542,9 @@ typedef struct stringBufStr {
#define DEFAULT_BUFFER_SIZE 200
static SECStatus
-AppendStr(stringBuf *bufp, char *str)
+AppendStr(stringBuf* bufp, char* str)
{
- char *buf;
+ char* buf;
unsigned bufLen, bufSize, len;
int size = 0;
@@ -551,33 +554,34 @@ AppendStr(stringBuf *bufp, char *str)
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;
+ 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;
+ size = bufSize * 2;
+ buf = (char*)PORT_Realloc(buf, size);
+ bufp->size = size;
}
if (!buf) {
- PORT_SetError(SEC_ERROR_NO_MEMORY);
- return SECFailure;
+ 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 */
+ 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 */
+ 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 .
@@ -590,250 +594,251 @@ typedef enum {
* need quoting, then this function changes it to minimalEscape.
*/
static int
-cert_RFC1485_GetRequiredLen(const char *src, int srclen, EQMode *pEQMode)
+cert_RFC1485_GetRequiredLen(const char* src, int srclen, EQMode* pEQMode)
{
- int i, reqLen=0;
+ 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;
+ 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 && srclen > 0 && mode == minimalEscapeAndQuote &&
+ (OPTIONAL_SPACE(src[srclen - 1]) || OPTIONAL_SPACE(src[0]))) {
+ needsQuoting = PR_TRUE;
}
- if (needsQuoting)
- reqLen += 2;
+ if (needsQuoting)
+ reqLen += 2;
if (pEQMode && mode == minimalEscapeAndQuote && !needsQuoting)
- *pEQMode = minimalEscape;
+ *pEQMode = minimalEscape;
return reqLen;
}
static const char hexChars[16] = { "0123456789abcdef" };
static SECStatus
-escapeAndQuote(char *dst, int dstlen, char *src, int srclen, EQMode *pEQMode)
+escapeAndQuote(char* dst, int dstlen, char* src, int srclen, EQMode* pEQMode)
{
- int i, reqLen=0;
+ 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;
+ 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;
- }
+ 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++ = C_DOUBLE_QUOTE;
*dst++ = 0;
if (pEQMode)
- *pEQMode = mode;
+ *pEQMode = mode;
return SECSuccess;
}
SECStatus
-CERT_RFC1485_EscapeAndQuote(char *dst, int dstlen, char *src, int srclen)
+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)
+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;
+ 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;
+ PORT_SetError(SEC_ERROR_INPUT_LEN);
+ return NULL;
}
/* first will point to the next sequence of bytes to decode */
- first = (PRUint8 *)oid->data;
+ first = (PRUint8*)oid->data;
/* stop points to one past the legitimate data */
- stop = &first[ oid->len ];
+ stop = &first[oid->len];
/*
- * Check for our pseudo-encoded single-digit OIDs
- */
+ * 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;
+ /* 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;
- }
+ 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)
+static SECItem*
+get_hex_string(SECItem* data)
{
- SECItem *rv;
+ 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);
+ rv = SECITEM_AllocItem(NULL, NULL, data->len * 2 + 2);
if (!rv) {
- return NULL;
+ 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];
+ 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,
+/* 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
+ * 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
@@ -842,79 +847,79 @@ get_hex_string(SECItem *data)
* Otherwise, we use the OID.N.N=#hexXXXX form.
*
* If the caller prefers maximum human readability to RFC compliance,
- * then
+ * then
* - We print the kind in NAME= string form if we know the name
- * string for the attribute type OID, regardless of whether the
+ * 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
+ * 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
+ * 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 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
+ * 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
+ * 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
+ * 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
+ * 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
+ * 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
+ * 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
+ * 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
+ * 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)
+AppendAVA(stringBuf* bufp, CERTAVA* ava, CertStrictnessLevel strict)
{
#define TMPBUF_LEN 2048
- 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;
+ 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];
+ 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 tagName n2k.name /* non-NULL means use NAME= form */
#define maxBytes n2k.maxLen
-#define tag n2k.kind
-#define vt n2k.valueType
+#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.
- */
+ * 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);
@@ -922,146 +927,145 @@ AppendAVA(stringBuf *bufp, CERTAVA *ava, CertStrictnessLevel strict)
++pn2k;
}
- if (pn2k->kind != endKind ) {
+ 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 */
+ 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 */
- }
- }
+ 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;
- }
+ /* 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));
+ 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;
+ maxName = nameLen;
maxValue = valueLen;
if (len <= sizeof(tmpBuf)) {
- encodedAVA = 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;
- }
+ 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;
+ /* 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] = '.';
+ /* 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 (unknownTag)
+ PR_smprintf_free(unknownTag);
if (strict == CERT_N2A_READABLE && maxValue > maxBytes)
- maxValue = maxBytes;
+ maxValue = maxBytes;
if (valueLen > maxValue) {
- valueLen = maxValue;
- truncateValue = PR_TRUE;
+ 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;
+ 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);
+ 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];
- PORT_Assert(valueLen < sizeof tmpBuf);
- rv = escapeAndQuote(bigTmpBuf, sizeof bigTmpBuf,
- (char *)avaValue->data,
- PR_MIN(avaValue->len, 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);
+ /* must truncate the escaped and quoted value */
+ char bigTmpBuf[TMPBUF_LEN * 3 + 3];
+ PORT_Assert(valueLen < sizeof tmpBuf);
+ rv = escapeAndQuote(bigTmpBuf, sizeof bigTmpBuf, (char*)avaValue->data,
+ PR_MIN(avaValue->len, 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);
+ rv = AppendStr(bufp, encodedAVA);
if (encodedAVA != tmpBuf)
- PORT_Free(encodedAVA);
+ PORT_Free(encodedAVA);
return rv;
}
@@ -1070,63 +1074,66 @@ AppendAVA(stringBuf *bufp, CERTAVA *ava, CertStrictnessLevel strict)
#undef tag
#undef vt
-char *
-CERT_NameToAsciiInvertible(CERTName *name, CertStrictnessLevel strict)
+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;
+ return NULL;
}
-
+
/* find last RDN */
lastRdn = rdns;
- while (*lastRdn) lastRdn++;
+ while (*lastRdn)
+ lastRdn++;
lastRdn--;
-
+
/*
- * Loop over name contents in _reverse_ RDN order appending to string
- */
+ * 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;
- }
+ 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);
+ PORT_Free(strBuf.buffer);
}
return NULL;
}
-char *
-CERT_NameToAscii(CERTName *name)
+char*
+CERT_NameToAscii(CERTName* name)
{
return CERT_NameToAsciiInvertible(name, CERT_N2A_READABLE);
}
@@ -1135,62 +1142,62 @@ CERT_NameToAscii(CERTName *name)
* Return the string representation of a DER encoded distinguished name
* "dername" - The DER encoded name to convert
*/
-char *
-CERT_DerNameToAscii(SECItem *dername)
+char*
+CERT_DerNameToAscii(SECItem* dername)
{
int rv;
- PLArenaPool *arena = NULL;
+ PLArenaPool* arena = NULL;
CERTName name;
- char *retstr = NULL;
-
+ char* retstr = NULL;
+
arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
-
- if ( arena == NULL) {
- goto loser;
+
+ if (arena == NULL) {
+ goto loser;
}
-
+
rv = SEC_QuickDERDecodeItem(arena, &name, CERT_NameTemplate, dername);
-
- if ( rv != SECSuccess ) {
- goto loser;
+
+ if (rv != SECSuccess) {
+ goto loser;
}
retstr = CERT_NameToAscii(&name);
loser:
- if ( arena != NULL ) {
- PORT_FreeArena(arena, PR_FALSE);
+ if (arena != NULL) {
+ PORT_FreeArena(arena, PR_FALSE);
}
-
- return(retstr);
+
+ return (retstr);
}
-static char *
-avaToString(PLArenaPool *arena, CERTAVA *ava)
+static char*
+avaToString(PLArenaPool* arena, CERTAVA* ava)
{
- char * buf = NULL;
- SECItem* avaValue;
- int valueLen;
+ char* buf = NULL;
+ SECItem* avaValue;
+ int valueLen;
avaValue = CERT_DecodeAVAValue(&ava->value);
- if(!avaValue) {
- return buf;
+ if (!avaValue) {
+ return buf;
}
- valueLen = cert_RFC1485_GetRequiredLen((char *)avaValue->data,
- avaValue->len, NULL) + 1;
+ valueLen =
+ cert_RFC1485_GetRequiredLen((char*)avaValue->data, avaValue->len, NULL) + 1;
if (arena) {
- buf = (char *)PORT_ArenaZAlloc(arena, valueLen);
+ buf = (char*)PORT_ArenaZAlloc(arena, valueLen);
} else {
- buf = (char *)PORT_ZAlloc(valueLen);
+ 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;
- }
+ 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;
@@ -1199,22 +1206,22 @@ avaToString(PLArenaPool *arena, CERTAVA *ava)
/* 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(PLArenaPool *arena, const CERTName *name, int wantedTag)
+static char*
+CERT_GetNameElement(PLArenaPool* arena, const CERTName* name, int wantedTag)
{
CERTRDN** rdns = name->rdns;
- CERTRDN* rdn;
- CERTAVA* ava = NULL;
+ 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 */
- }
- }
+ 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;
}
@@ -1223,119 +1230,123 @@ CERT_GetNameElement(PLArenaPool *arena, const CERTName *name, int wantedTag)
* 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(PLArenaPool *arena, const CERTName *name, int wantedTag)
+static char*
+CERT_GetLastNameElement(PLArenaPool* arena, const CERTName* name, int wantedTag)
{
- CERTRDN** rdns = name->rdns;
- CERTRDN* rdn;
- CERTAVA* lastAva = NULL;
-
+ 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;
- }
- }
+ 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*
+CERT_GetCertificateEmailAddress(CERTCertificate* cert)
{
- char *rawEmailAddr = NULL;
+ char* rawEmailAddr = NULL;
SECItem subAltName;
SECStatus rv;
- CERTGeneralName *nameList = NULL;
- CERTGeneralName *current;
- PLArenaPool *arena = NULL;
+ CERTGeneralName* nameList = NULL;
+ CERTGeneralName* current;
+ PLArenaPool* 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);
- }
+ 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]);
- }
- }
+ 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);
+ PORT_FreeArena(arena, PR_FALSE);
}
- if ( subAltName.data ) {
- SECITEM_FreeItem(&subAltName, PR_FALSE);
+ if (subAltName.data) {
+ SECITEM_FreeItem(&subAltName, PR_FALSE);
}
- return(rawEmailAddr);
+ return (rawEmailAddr);
}
-static char *
-appendStringToBuf(char *dest, char *src, PRUint32 *pRemaining)
+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;
+ PRUint32 i;
+ for (i = 0; i < len; ++i)
+ dest[i] = tolower(src[i]);
+ dest[len] = 0;
+ dest += len + 1;
+ *pRemaining -= len + 1;
}
return dest;
}
@@ -1343,112 +1354,118 @@ appendStringToBuf(char *dest, char *src, PRUint32 *pRemaining)
#undef NEEDS_HEX_ESCAPE
#define NEEDS_HEX_ESCAPE(c) (c < 0x20)
-static char *
-appendItemToBuf(char *dest, SECItem *src, PRUint32 *pRemaining)
+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;
- }
+ 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
+/* 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*
+cert_GetCertificateEmailAddresses(CERTCertificate* cert)
{
- char * rawEmailAddr = NULL;
- char * addrBuf = NULL;
- char * pBuf = NULL;
- PLArenaPool * tmpArena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
- PRUint32 maxLen = 0;
- PRInt32 finalLen = 0;
- SECStatus rv;
- SECItem subAltName;
-
- if (!tmpArena)
- return addrBuf;
+ char* rawEmailAddr = NULL;
+ char* addrBuf = NULL;
+ char* pBuf = NULL;
+ PORTCheapArenaPool tmpArena;
+ PRUint32 maxLen = 0;
+ PRInt32 finalLen = 0;
+ SECStatus rv;
+ SECItem subAltName;
+
+ PORT_InitCheapArena(&tmpArena, DER_DEFAULT_CHUNKSIZE);
subAltName.data = NULL;
maxLen = cert->derCert.len;
PORT_Assert(maxLen);
- if (!maxLen)
- maxLen = 2000; /* a guess, should never happen */
+ if (!maxLen)
+ maxLen = 2000; /* a guess, should never happen */
- pBuf = addrBuf = (char *)PORT_ArenaZAlloc(tmpArena, maxLen + 1);
- if (!addrBuf)
- goto loser;
+ pBuf = addrBuf = (char*)PORT_ArenaZAlloc(&tmpArena.arena, maxLen + 1);
+ if (!addrBuf)
+ goto loser;
- rawEmailAddr = CERT_GetNameElement(tmpArena, &cert->subject,
- SEC_OID_PKCS9_EMAIL_ADDRESS);
+ rawEmailAddr = CERT_GetNameElement(&tmpArena.arena, &cert->subject,
+ SEC_OID_PKCS9_EMAIL_ADDRESS);
pBuf = appendStringToBuf(pBuf, rawEmailAddr, &maxLen);
- rawEmailAddr = CERT_GetNameElement(tmpArena, &cert->subject,
- SEC_OID_RFC1274_MAIL);
+ rawEmailAddr = CERT_GetNameElement(&tmpArena.arena, &cert->subject,
+ SEC_OID_RFC1274_MAIL);
pBuf = appendStringToBuf(pBuf, rawEmailAddr, &maxLen);
- rv = CERT_FindCertExtension(cert, SEC_OID_X509_SUBJECT_ALT_NAME,
- &subAltName);
+ 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. */
+ CERTGeneralName* nameList = NULL;
+
+ if (!!(nameList = CERT_DecodeAltNameExtension(&tmpArena.arena, &subAltName))) {
+ CERTGeneralName* current = nameList;
+ do {
+ if (current->type == certDirectoryName) {
+ rawEmailAddr =
+ CERT_GetNameElement(&tmpArena.arena,
+ &current->name.directoryName,
+ SEC_OID_PKCS9_EMAIL_ADDRESS);
+ pBuf =
+ appendStringToBuf(pBuf, rawEmailAddr, &maxLen);
+
+ rawEmailAddr =
+ CERT_GetNameElement(&tmpArena.arena,
+ &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);
- }
+ pBuf = PORT_ArenaAlloc(cert->arena, finalLen);
+ if (pBuf) {
+ PORT_Memcpy(pBuf, addrBuf, finalLen);
+ }
}
loser:
- if (tmpArena)
- PORT_FreeArena(tmpArena, PR_FALSE);
+ PORT_DestroyCheapArena(&tmpArena);
return pBuf;
}
@@ -1457,11 +1474,11 @@ loser:
** 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)
+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 (const char*)cert->emailAddr;
return NULL;
}
@@ -1469,92 +1486,91 @@ CERT_GetFirstEmailAddress(CERTCertificate * cert)
** 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)
+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;
+ 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.
+** subject Alternative Name extensions.
** Returns a string allocated by PORT_StrDup, which the caller must free.
*/
-char *
-CERT_GetCertEmailAddress(const CERTName *name)
+char*
+CERT_GetCertEmailAddress(const CERTName* name)
{
- char *rawEmailAddr;
- char *emailAddr;
+ 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);
+ if (rawEmailAddr == NULL) {
+ rawEmailAddr = CERT_GetNameElement(NULL, name, SEC_OID_RFC1274_MAIL);
}
emailAddr = CERT_FixupEmailAddr(rawEmailAddr);
- if ( rawEmailAddr ) {
- PORT_Free(rawEmailAddr);
+ if (rawEmailAddr) {
+ PORT_Free(rawEmailAddr);
}
- return(emailAddr);
+ return (emailAddr);
}
/* The return value must be freed with PORT_Free. */
-char *
-CERT_GetCommonName(const CERTName *name)
+char*
+CERT_GetCommonName(const CERTName* name)
{
- return(CERT_GetLastNameElement(NULL, name, SEC_OID_AVA_COMMON_NAME));
+ return (CERT_GetLastNameElement(NULL, name, SEC_OID_AVA_COMMON_NAME));
}
-char *
-CERT_GetCountryName(const CERTName *name)
+char*
+CERT_GetCountryName(const CERTName* name)
{
- return(CERT_GetNameElement(NULL, name, SEC_OID_AVA_COUNTRY_NAME));
+ return (CERT_GetNameElement(NULL, name, SEC_OID_AVA_COUNTRY_NAME));
}
-char *
-CERT_GetLocalityName(const CERTName *name)
+char*
+CERT_GetLocalityName(const CERTName* name)
{
- return(CERT_GetNameElement(NULL, name, SEC_OID_AVA_LOCALITY));
+ return (CERT_GetNameElement(NULL, name, SEC_OID_AVA_LOCALITY));
}
-char *
-CERT_GetStateName(const CERTName *name)
+char*
+CERT_GetStateName(const CERTName* name)
{
- return(CERT_GetNameElement(NULL, name, SEC_OID_AVA_STATE_OR_PROVINCE));
+ return (CERT_GetNameElement(NULL, name, SEC_OID_AVA_STATE_OR_PROVINCE));
}
-char *
-CERT_GetOrgName(const CERTName *name)
+char*
+CERT_GetOrgName(const CERTName* name)
{
- return(CERT_GetNameElement(NULL, name, SEC_OID_AVA_ORGANIZATION_NAME));
+ return (CERT_GetNameElement(NULL, name, SEC_OID_AVA_ORGANIZATION_NAME));
}
-char *
-CERT_GetDomainComponentName(const CERTName *name)
+char*
+CERT_GetDomainComponentName(const CERTName* name)
{
- return(CERT_GetNameElement(NULL, name, SEC_OID_AVA_DC));
+ return (CERT_GetNameElement(NULL, name, SEC_OID_AVA_DC));
}
-char *
-CERT_GetOrgUnitName(const CERTName *name)
+char*
+CERT_GetOrgUnitName(const CERTName* name)
{
- return(CERT_GetNameElement(NULL, name, SEC_OID_AVA_ORGANIZATIONAL_UNIT_NAME));
+ return (
+ CERT_GetNameElement(NULL, name, SEC_OID_AVA_ORGANIZATIONAL_UNIT_NAME));
}
-char *
-CERT_GetDnQualifier(const CERTName *name)
+char*
+CERT_GetDnQualifier(const CERTName* name)
{
- return(CERT_GetNameElement(NULL, name, SEC_OID_AVA_DN_QUALIFIER));
+ return (CERT_GetNameElement(NULL, name, SEC_OID_AVA_DN_QUALIFIER));
}
-char *
-CERT_GetCertUid(const CERTName *name)
+char*
+CERT_GetCertUid(const CERTName* name)
{
- return(CERT_GetNameElement(NULL, name, SEC_OID_RFC1274_UID));
+ return (CERT_GetNameElement(NULL, name, SEC_OID_RFC1274_UID));
}
-
diff --git a/nss/lib/certdb/cert.h b/nss/lib/certdb/cert.h
index 4564dc2..e0af65a 100644
--- a/nss/lib/certdb/cert.h
+++ b/nss/lib/certdb/cert.h
@@ -22,7 +22,7 @@
#include "certt.h"
SEC_BEGIN_PROTOS
-
+
/****************************************************************************
*
* RFC1485 ascii to/from X.? RelativeDistinguishedName (aka CERTName)
@@ -47,14 +47,14 @@ extern char *CERT_NameToAscii(CERTName *name);
** Returns a string that must be freed with PORT_Free().
** Caller chooses encoding rules.
*/
-extern char *CERT_NameToAsciiInvertible(CERTName *name,
+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);
+extern char *CERT_GetOidString(const SECItem *oid);
/*
** Examine an AVA and return the tag that refers to it. The AVA tags are
@@ -126,24 +126,24 @@ extern SECComparison CERT_CompareName(const CERTName *a, const CERTName *b);
/*
** Convert a CERTName into something readable
*/
-extern char *CERT_FormatName (CERTName *name);
+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);
+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
+** 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);
+extern SECStatus CERT_RFC1485_EscapeAndQuote(char *dst, int dstlen, char *src,
+ int srclen);
/******************************************************************************
*
@@ -171,14 +171,14 @@ extern void CERT_DestroyValidity(CERTValidity *v);
** before memory is allocated (use CERT_DestroyValidity(v, PR_FALSE) to do
** that).
*/
-extern SECStatus CERT_CopyValidity
- (PLArenaPool *arena, CERTValidity *dest, CERTValidity *src);
+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
+** 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.
+** 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.
@@ -195,9 +195,10 @@ SECStatus CERT_SetSlopTime(PRInt32 slop);
** "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);
+extern CERTCertificate *CERT_CreateCertificate(unsigned long serialNumber,
+ CERTName *issuer,
+ CERTValidity *validity,
+ CERTCertificateRequest *req);
/*
** Destroy a certificate object
@@ -221,9 +222,8 @@ extern CERTCertificate *CERT_DupCertificate(CERTCertificate *c);
** "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);
+extern CERTCertificateRequest *CERT_CreateCertificateRequest(
+ CERTName *name, CERTSubjectPublicKeyInfo *spki, SECItem **attributes);
/*
** Destroy a certificate-request object
@@ -235,22 +235,19 @@ extern void CERT_DestroyCertificateRequest(CERTCertificateRequest *r);
/*
** Start adding extensions to a certificate request.
*/
-void *
-CERT_StartCertificateRequestAttributes(CERTCertificateRequest *req);
+void *CERT_StartCertificateRequestAttributes(CERTCertificateRequest *req);
/*
** Reformat the certificate extension list into a CertificateRequest
** attribute list.
*/
-SECStatus
-CERT_FinishCertificateRequestAttributes(CERTCertificateRequest *req);
+SECStatus CERT_FinishCertificateRequestAttributes(CERTCertificateRequest *req);
/*
** Extract the Extension Requests from a DER CertRequest attribute list.
*/
-SECStatus
-CERT_GetCertificateRequestExtensions(CERTCertificateRequest *req,
- CERTCertExtension ***exts);
+SECStatus CERT_GetCertificateRequestExtensions(CERTCertificateRequest *req,
+ CERTCertExtension ***exts);
/*
** Extract a public key object from a certificate
@@ -261,7 +258,7 @@ extern SECKEYPublicKey *CERT_ExtractPublicKey(CERTCertificate *cert);
** Retrieve the Key Type associated with the cert we're dealing with
*/
-extern KeyType CERT_GetCertKeyType (const CERTSubjectPublicKeyInfo *spki);
+extern KeyType CERT_GetCertKeyType(const CERTSubjectPublicKeyInfo *spki);
/*
** Initialize the certificate database. This is called to create
@@ -278,13 +275,12 @@ 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);
-
+extern CERTCertList *CERT_GetCertChainFromCert(CERTCertificate *cert,
+ PRTime time, SECCertUsage usage);
+extern CERTCertificate *CERT_NewTempCertificate(CERTCertDBHandle *handle,
+ SECItem *derCert,
+ char *nickname, PRBool isperm,
+ PRBool copyDER);
/******************************************************************************
*
@@ -300,8 +296,8 @@ CERT_NewTempCertificate (CERTCertDBHandle *handle, SECItem *derCert,
** DER_T61_STRING
** "value" is the null terminated string containing the value
*/
-extern CERTAVA *CERT_CreateAVA
- (PLArenaPool *arena, SECOidTag kind, int valueType, char *value);
+extern CERTAVA *CERT_CreateAVA(PLArenaPool *arena, SECOidTag kind,
+ int valueType, char *value);
/*
** Extract the Distinguished Name from a DER encoded certificate
@@ -315,18 +311,14 @@ extern SECStatus CERT_NameFromDERCert(SECItem *derCert, SECItem *derName);
** "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);
+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
@@ -339,11 +331,10 @@ 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);
+ SECItem *sn, SECItem *key);
+extern SECStatus CERT_SerialNumberFromDERCert(SECItem *derCert,
+ SECItem *derName);
/*
** Generate a database search key for a crl, based on the
@@ -352,17 +343,18 @@ extern SECStatus CERT_SerialNumberFromDERCert(SECItem *derCert,
** "derCrl" the DER encoded crl
** "key" the returned key
*/
-extern SECStatus CERT_KeyFromDERCrl(PLArenaPool *arena, SECItem *derCrl, SECItem *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);
+ CERTDBNameFunc namecb, void *cbarg);
/* Open the certificate database. Use given filename for database. */
extern SECStatus CERT_OpenCertDBFilename(CERTCertDBHandle *handle,
- char *certdbname, PRBool readOnly);
+ char *certdbname, PRBool readOnly);
/*
** Open and initialize a cert database that is entirely in memory. This
@@ -374,11 +366,11 @@ 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
+** 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);
+extern CERTCertNicknames *CERT_GetValidDNSPatternsFromCert(
+ CERTCertificate *cert);
/*
** Check the hostname to make sure that it matches the shexp that
@@ -391,7 +383,8 @@ extern SECStatus CERT_VerifyCertName(const CERTCertificate *cert,
** 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);
+extern SECStatus CERT_AddOKDomainName(CERTCertificate *cert,
+ const char *hostname);
/*
** Decode a DER encoded certificate into an CERTCertificate structure
@@ -401,30 +394,31 @@ extern SECStatus CERT_AddOKDomainName(CERTCertificate *cert, const char *hostnam
** "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);
+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 */
+#define SEC_CRL_TYPE 1
+#define SEC_KRL_TYPE 0 /* deprecated */
-extern CERTSignedCrl *
-CERT_DecodeDERCrl (PLArenaPool *arena, SECItem *derSignedCrl,int type);
+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);
+extern CERTSignedCrl *CERT_DecodeDERCrlWithFlags(PLArenaPool *narena,
+ SECItem *derSignedCrl,
+ int type, PRInt32 options);
/* CRL options to pass */
-#define CRL_DECODE_DEFAULT_OPTIONS 0x00000000
+#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
@@ -432,33 +426,32 @@ CERT_DecodeDERCrlWithFlags(PLArenaPool *narena, SECItem *derSignedCrl,
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
+#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);
+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
+ * 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 CERTSignedCrl *CERT_ImportCRL(CERTCertDBHandle *handle, SECItem *derCRL,
+ char *url, int type, void *wincx);
-extern void CERT_DestroyCrl (CERTSignedCrl *crl);
+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);
+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)
@@ -468,114 +461,113 @@ void CERT_CRLCacheRefreshIssuer(CERTCertDBHandle* dbhandle, SECItem* crlKey);
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);
+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);
+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);
+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);
+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);
+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);
+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);
+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);
+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);
+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);
+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);
+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);
+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);
+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);
+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);
+extern CERTCertificate *CERT_FindCertBySPKDigest(CERTCertDBHandle *handle,
+ SECItem *spkDigest);
/*
* Find the issuer of a cert
*/
-CERTCertificate *
-CERT_FindCertIssuer(CERTCertificate *cert, PRTime validTime, SECCertUsage usage);
+CERTCertificate *CERT_FindCertIssuer(CERTCertificate *cert, PRTime validTime,
+ SECCertUsage usage);
/*
** Check the validity times of a certificate vs. time 't', allowing
@@ -586,8 +578,8 @@ CERT_FindCertIssuer(CERTCertificate *cert, PRTime validTime, SECCertUsage usage)
** been overridden by the user.
*/
extern SECCertTimeValidity CERT_CheckCertValidTimes(const CERTCertificate *cert,
- PRTime t,
- PRBool allowOverride);
+ PRTime t,
+ PRBool allowOverride);
/*
** WARNING - this function is deprecated, and will either go away or have
@@ -605,15 +597,14 @@ extern SECStatus CERT_CertTimesValid(CERTCertificate *cert);
** "notBefore" is the start of the validity period
** "notAfter" is the end of the validity period
*/
-extern SECStatus
-CERT_GetCertTimes (const CERTCertificate *c, PRTime *notBefore,
- PRTime *notAfter);
+extern SECStatus CERT_GetCertTimes(const CERTCertificate *c, PRTime *notBefore,
+ PRTime *notAfter);
/*
** Extract the issuer and serial number from a certificate
*/
-extern CERTIssuerAndSN *CERT_GetCertIssuerAndSN(PLArenaPool *,
- CERTCertificate *);
+extern CERTIssuerAndSN *CERT_GetCertIssuerAndSN(PLArenaPool *,
+ CERTCertificate *);
/*
** verify the signature of a signed data object with a given certificate
@@ -621,23 +612,20 @@ extern CERTIssuerAndSN *CERT_GetCertIssuerAndSN(PLArenaPool *,
** "cert" the certificate to use to check the signature
*/
extern SECStatus CERT_VerifySignedData(CERTSignedData *sd,
- CERTCertificate *cert,
- PRTime t,
- void *wincx);
+ 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);
+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(const CERTSignedData *sd,
- SECKEYPublicKey *pubKey, void *wincx);
+extern SECStatus CERT_VerifySignedDataWithPublicKey(const CERTSignedData *sd,
+ SECKEYPublicKey *pubKey,
+ void *wincx);
/*
** NEW FUNCTIONS with new bit-field-FIELD SECCertificateUsage - please use
@@ -647,27 +635,31 @@ CERT_VerifySignedDataWithPublicKey(const CERTSignedData *sd,
** "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);
+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);
+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);
+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
@@ -677,20 +669,19 @@ CERT_VerifyCACertForUsage(CERTCertDBHandle *handle, CERTCertificate *cert,
** "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);
+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);
+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);
+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
@@ -709,39 +700,37 @@ extern CERTCertificate *CERT_ConvertAndDecodeCertificate(char *certstr);
*/
extern CERTCertificate *CERT_DecodeCertFromPackage(char *certbuf, int certlen);
-extern SECStatus
-CERT_ImportCAChain (SECItem *certs, int numcerts, SECCertUsage certUsage);
+extern SECStatus CERT_ImportCAChain(SECItem *certs, int numcerts,
+ SECCertUsage certUsage);
-extern SECStatus
-CERT_ImportCAChainTrusted(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
+** 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);
+typedef SECStatus(PR_CALLBACK *CERTImportCertificateFunc)(void *arg,
+ SECItem **certs,
+ int numcerts);
-extern SECStatus
-CERT_DecodeCertPackage(char *certbuf, int certlen, CERTImportCertificateFunc f,
- void *arg);
+extern SECStatus CERT_DecodeCertPackage(char *certbuf, int certlen,
+ CERTImportCertificateFunc f, void *arg);
-/*
-** Returns the value of an AVA. This was a formerly static
+/*
+** 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.
+** 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
@@ -751,10 +740,10 @@ extern char *CERT_GetCertificateEmailAddress(CERTCertificate *cert);
extern char *CERT_GetCertEmailAddress(const CERTName *name);
-extern const char * CERT_GetFirstEmailAddress(CERTCertificate * cert);
+extern const char *CERT_GetFirstEmailAddress(CERTCertificate *cert);
-extern const char * CERT_GetNextEmailAddress(CERTCertificate * cert,
- const char * prev);
+extern const char *CERT_GetNextEmailAddress(CERTCertificate *cert,
+ const char *prev);
/* The return value must be freed with PORT_Free. */
extern char *CERT_GetCommonName(const CERTName *name);
@@ -778,13 +767,13 @@ extern char *CERT_GetCertUid(const CERTName *name);
extern SECStatus CERT_GetCertTrust(const CERTCertificate *cert,
CERTCertTrust *trust);
-extern SECStatus
-CERT_ChangeCertTrust (CERTCertDBHandle *handle, CERTCertificate *cert,
- CERTCertTrust *trust);
+extern SECStatus CERT_ChangeCertTrust(CERTCertDBHandle *handle,
+ CERTCertificate *cert,
+ CERTCertTrust *trust);
-extern SECStatus
-CERT_ChangeCertTrustByUsage(CERTCertDBHandle *certdb, CERTCertificate *cert,
- SECCertUsage usage);
+extern SECStatus CERT_ChangeCertTrustByUsage(CERTCertDBHandle *certdb,
+ CERTCertificate *cert,
+ SECCertUsage usage);
/*************************************************************************
*
@@ -808,23 +797,24 @@ extern void *CERT_StartCertExtensions(CERTCertificate *cert);
** "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_AddExtension(void *exthandle, int idtag, SECItem *value,
+ PRBool critical, PRBool copyData);
-extern SECStatus CERT_EncodeAndAddBitStrExtension
- (void *exthandle, int idtag, SECItem *value, PRBool critical);
+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_EncodeAltNameExtension(PLArenaPool *arena, CERTGeneralName *value, SECItem *encodedValue);
+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
@@ -839,17 +829,15 @@ extern SECStatus CERT_FinishExtensions(void *exthandle);
** 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);
+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 SECStatus CERT_GetExtenCriticality(CERTCertExtension **extensions,
+ int tag, PRBool *isCritical);
-extern void
-CERT_DestroyOidSequence(CERTOidSequence *oidSeq);
+extern void CERT_DestroyOidSequence(CERTOidSequence *oidSeq);
/****************************************************************************
*
@@ -862,28 +850,29 @@ CERT_DestroyOidSequence(CERTOidSequence *oidSeq);
** value - extension value to encode
** encodedValue - output encoded value
*/
-extern SECStatus CERT_EncodeBasicConstraintValue
- (PLArenaPool *arena, CERTBasicConstraints *value, SECItem *encodedValue);
+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);
+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);
+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, const SECItem *encodedValue);
+extern SECStatus CERT_DecodeBasicConstraintValue(CERTBasicConstraints *value,
+ const SECItem *encodedValue);
/* Decodes a DER encoded authorityKeyIdentifier extension value into a
** readable format.
@@ -891,87 +880,84 @@ extern SECStatus CERT_DecodeBasicConstraintValue
** encodedValue - value to be decoded
** Returns a CERTAuthKeyID structure which contains the decoded value
*/
-extern CERTAuthKeyID *CERT_DecodeAuthKeyID
- (PLArenaPool *arena, const SECItem *encodedValue);
+extern CERTAuthKeyID *CERT_DecodeAuthKeyID(PLArenaPool *arena,
+ const SECItem *encodedValue);
-/* Decodes a DER encoded crlDistributionPoints extension value into a
+/* 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
+** Returns a CERTCrlDistributionPoints structure which contains the
** decoded value
*/
-extern CERTCrlDistributionPoints * CERT_DecodeCRLDistributionPoints
- (PLArenaPool *arena, SECItem *der);
+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(const SECItem *seqItem);
-
-
+extern void *CERT_GetGeneralNameByType(CERTGeneralName *genNames,
+ CERTGeneralNameType type,
+ PRBool derFormat);
+extern CERTOidSequence *CERT_DecodeOidSequence(const SECItem *seqItem);
/****************************************************************************
*
- * Find extension values of a certificate
+ * Find extension values of a certificate
*
***************************************************************************/
-extern SECStatus CERT_FindCertExtension
- (const CERTCertificate *cert, int tag, SECItem *value);
+extern SECStatus CERT_FindCertExtension(const CERTCertificate *cert, int tag,
+ SECItem *value);
-extern SECStatus CERT_FindNSCertTypeExtension
- (CERTCertificate *cert, SECItem *value);
+extern SECStatus CERT_FindNSCertTypeExtension(CERTCertificate *cert,
+ SECItem *value);
-extern char * CERT_FindNSStringExtension (CERTCertificate *cert, int oidtag);
+extern char *CERT_FindNSStringExtension(CERTCertificate *cert, int oidtag);
-extern SECStatus CERT_FindCertExtensionByOID
- (CERTCertificate *cert, SECItem *oid, SECItem *value);
+extern SECStatus CERT_FindCertExtensionByOID(CERTCertificate *cert,
+ SECItem *oid, SECItem *value);
/* 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);
+extern CERTAuthKeyID *CERT_FindAuthKeyIDExten(PLArenaPool *arena,
+ CERTCertificate *cert);
/* Returns the decoded value of the basicConstraint extension.
*/
-extern SECStatus CERT_FindBasicConstraintExten
- (CERTCertificate *cert, CERTBasicConstraints *value);
+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);
+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
+/* 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);
+extern SECStatus CERT_FindKeyUsageExtension(CERTCertificate *cert,
+ SECItem *value);
-/* Return the decoded value of the subjectKeyID extension. The caller should
+/* 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);
+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.
+** 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);
+extern SECStatus CERT_CheckCertUsage(CERTCertificate *cert,
+ unsigned char usage);
/****************************************************************************
*
@@ -979,14 +965,12 @@ extern SECStatus CERT_CheckCertUsage (CERTCertificate *cert,
*
****************************************************************************/
-extern SECStatus CERT_FindCRLExtensionByOID
- (CERTCrl *crl, SECItem *oid, SECItem *value);
+extern SECStatus CERT_FindCRLExtensionByOID(CERTCrl *crl, SECItem *oid,
+ SECItem *value);
-extern SECStatus CERT_FindCRLExtension
- (CERTCrl *crl, int tag, SECItem *value);
+extern SECStatus CERT_FindCRLExtension(CERTCrl *crl, int tag, SECItem *value);
-extern SECStatus
- CERT_FindInvalidDateExten (CERTCrl *crl, PRTime *value);
+extern SECStatus CERT_FindInvalidDateExten(CERTCrl *crl, PRTime *value);
/*
** Set up a crl for adding X509v3 extensions. Returns an opaque handle
@@ -1003,17 +987,17 @@ extern void *CERT_StartCRLExtensions(CERTCrl *crl);
*/
extern void *CERT_StartCRLEntryExtensions(CERTCrl *crl, CERTCrlEntry *entry);
-extern CERTCertNicknames *CERT_GetCertNicknames (CERTCertDBHandle *handle,
- int what, void *wincx);
+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_FindCRLNumberExten(PLArenaPool *arena, CERTCrl *crl,
+ SECItem *value);
-extern SECStatus CERT_FindCRLEntryReasonExten (CERTCrlEntry *crlEntry,
- CERTCRLEntryReasonCode *value);
+extern SECStatus CERT_FindCRLEntryReasonExten(CERTCrlEntry *crlEntry,
+ CERTCRLEntryReasonCode *value);
extern void CERT_FreeNicknames(CERTCertNicknames *nicknames);
@@ -1021,7 +1005,7 @@ extern PRBool CERT_CompareCerts(const CERTCertificate *c1,
const CERTCertificate *c2);
extern PRBool CERT_CompareCertsForRedirection(CERTCertificate *c1,
- CERTCertificate *c2);
+ CERTCertificate *c2);
/*
** Generate an array of the Distinguished Names that the given cert database
@@ -1037,8 +1021,8 @@ 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);
+extern CERTDistNames *CERT_DistNamesFromNicknames(CERTCertDBHandle *handle,
+ char **nicknames, int nnames);
/*
** Generate an array of Distinguished names from a list of certs.
@@ -1048,15 +1032,14 @@ 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_CertChainFromCert(CERTCertificate *cert,
+ SECCertUsage usage,
+ PRBool includeRoot);
-extern CERTCertificateList *
-CERT_CertListFromCert(CERTCertificate *cert);
+extern CERTCertificateList *CERT_CertListFromCert(CERTCertificate *cert);
-extern CERTCertificateList *
-CERT_DupCertList(const CERTCertificateList * oldList);
+extern CERTCertificateList *CERT_DupCertList(
+ const CERTCertificateList *oldList);
extern void CERT_DestroyCertificateList(CERTCertificateList *list);
@@ -1064,262 +1047,215 @@ 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);
+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);
+PRBool CERT_IsCertRevoked(CERTCertificate *cert);
-void
-CERT_DestroyCertArray(CERTCertificate **certs, unsigned int ncerts);
+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);
+SECStatus CERT_DecodeTrustString(CERTCertTrust *trust, const char *trusts);
/* encode trust struct into string representation of trust flags */
-char *
-CERT_EncodeTrustString(CERTCertTrust *trust);
+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);
+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);
+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);
+char *CERT_MakeCANickname(CERTCertificate *cert);
-PRBool
-CERT_IsCACert(CERTCertificate *cert, unsigned int *rettype);
+PRBool CERT_IsCACert(CERTCertificate *cert, unsigned int *rettype);
-PRBool
-CERT_IsCADERCert(SECItem *derCert, unsigned int *rettype);
+PRBool CERT_IsCADERCert(SECItem *derCert, unsigned int *rettype);
-PRBool
-CERT_IsRootDERCert(SECItem *derCert);
+PRBool CERT_IsRootDERCert(SECItem *derCert);
-SECStatus
-CERT_SaveSMimeProfile(CERTCertificate *cert, SECItem *emailProfile,
- SECItem *profileTime);
+SECStatus CERT_SaveSMimeProfile(CERTCertificate *cert, SECItem *emailProfile,
+ SECItem *profileTime);
/*
* find the smime symmetric capabilities profile for a given cert
*/
-SECItem *
-CERT_FindSMimeProfile(CERTCertificate *cert);
+SECItem *CERT_FindSMimeProfile(CERTCertificate *cert);
-SECStatus
-CERT_AddNewCerts(CERTCertDBHandle *handle);
+SECStatus CERT_AddNewCerts(CERTCertDBHandle *handle);
-CERTCertificatePolicies *
-CERT_DecodeCertificatePoliciesExtension(const SECItem *extnValue);
+CERTCertificatePolicies *CERT_DecodeCertificatePoliciesExtension(
+ const SECItem *extnValue);
-void
-CERT_DestroyCertificatePoliciesExtension(CERTCertificatePolicies *policies);
+void CERT_DestroyCertificatePoliciesExtension(
+ CERTCertificatePolicies *policies);
-CERTCertificatePolicyMappings *
-CERT_DecodePolicyMappingsExtension(SECItem *encodedCertPolicyMaps);
+CERTCertificatePolicyMappings *CERT_DecodePolicyMappingsExtension(
+ SECItem *encodedCertPolicyMaps);
-SECStatus
-CERT_DestroyPolicyMappingsExtension(CERTCertificatePolicyMappings *mappings);
+SECStatus CERT_DestroyPolicyMappingsExtension(
+ CERTCertificatePolicyMappings *mappings);
-SECStatus
-CERT_DecodePolicyConstraintsExtension(
+SECStatus CERT_DecodePolicyConstraintsExtension(
CERTCertificatePolicyConstraints *decodedValue,
const SECItem *encodedValue);
-SECStatus CERT_DecodeInhibitAnyExtension
- (CERTCertificateInhibitAny *decodedValue, SECItem *extnValue);
+SECStatus CERT_DecodeInhibitAnyExtension(
+ CERTCertificateInhibitAny *decodedValue, SECItem *extnValue);
-CERTUserNotice *
-CERT_DecodeUserNotice(SECItem *noticeItem);
+CERTUserNotice *CERT_DecodeUserNotice(SECItem *noticeItem);
-extern CERTGeneralName *
-CERT_DecodeAltNameExtension(PLArenaPool *reqArena, SECItem *EncodedAltName);
+extern CERTGeneralName *CERT_DecodeAltNameExtension(PLArenaPool *reqArena,
+ SECItem *EncodedAltName);
-extern CERTNameConstraints *
-CERT_DecodeNameConstraintsExtension(PLArenaPool *arena,
- const SECItem *encodedConstraints);
+extern CERTNameConstraints *CERT_DecodeNameConstraintsExtension(
+ PLArenaPool *arena, const SECItem *encodedConstraints);
/* returns addr of a NULL termainated array of pointers to CERTAuthInfoAccess */
-extern CERTAuthInfoAccess **
-CERT_DecodeAuthInfoAccessExtension(PLArenaPool *reqArena,
- const SECItem *encodedExtension);
+extern CERTAuthInfoAccess **CERT_DecodeAuthInfoAccessExtension(
+ PLArenaPool *reqArena, const SECItem *encodedExtension);
-extern CERTPrivKeyUsagePeriod *
-CERT_DecodePrivKeyUsagePeriodExtension(PLArenaPool *arena, SECItem *extnValue);
+extern CERTPrivKeyUsagePeriod *CERT_DecodePrivKeyUsagePeriodExtension(
+ PLArenaPool *arena, SECItem *extnValue);
-extern CERTGeneralName *
-CERT_GetNextGeneralName(CERTGeneralName *current);
+extern CERTGeneralName *CERT_GetNextGeneralName(CERTGeneralName *current);
-extern CERTGeneralName *
-CERT_GetPrevGeneralName(CERTGeneralName *current);
+extern CERTGeneralName *CERT_GetPrevGeneralName(CERTGeneralName *current);
/*
* Look up name constraints for some certs that do not include name constraints
* (Most importantly, root certificates)
*
- * If a matching subject is found, |extensions| will be populated with a copy of the
- * DER-encoded name constraints extension. The data in |extensions| will point to
+ * If a matching subject is found, |extensions| will be populated with a copy of
+ * the
+ * DER-encoded name constraints extension. The data in |extensions| will point
+ * to
* memory that the caller owns.
*
* There is no mechanism to configure imposed name constraints right now. All
* imposed name constraints are built into NSS.
*/
-SECStatus
-CERT_GetImposedNameConstraints(const SECItem *derSubject, SECItem *extensions);
+SECStatus CERT_GetImposedNameConstraints(const SECItem *derSubject,
+ SECItem *extensions);
-CERTNameConstraint *
-CERT_GetNextNameConstraint(CERTNameConstraint *current);
+CERTNameConstraint *CERT_GetNextNameConstraint(CERTNameConstraint *current);
-CERTNameConstraint *
-CERT_GetPrevNameConstraint(CERTNameConstraint *current);
+CERTNameConstraint *CERT_GetPrevNameConstraint(CERTNameConstraint *current);
-void
-CERT_DestroyUserNotice(CERTUserNotice *userNotice);
+void CERT_DestroyUserNotice(CERTUserNotice *userNotice);
-typedef char * (* CERTPolicyStringCallback)(char *org,
- unsigned long noticeNumber,
- void *arg);
-void
-CERT_SetCAPolicyStringCallback(CERTPolicyStringCallback cb, void *cbarg);
+typedef char *(*CERTPolicyStringCallback)(char *org, unsigned long noticeNumber,
+ void *arg);
+void CERT_SetCAPolicyStringCallback(CERTPolicyStringCallback cb, void *cbarg);
-char *
-CERT_GetCertCommentString(CERTCertificate *cert);
+char *CERT_GetCertCommentString(CERTCertificate *cert);
-PRBool
-CERT_GovtApprovedBitSet(CERTCertificate *cert);
+PRBool CERT_GovtApprovedBitSet(CERTCertificate *cert);
-SECStatus
-CERT_AddPermNickname(CERTCertificate *cert, char *nickname);
+SECStatus CERT_AddPermNickname(CERTCertificate *cert, char *nickname);
-CERTCertList *
-CERT_MatchUserCert(CERTCertDBHandle *handle,
- SECCertUsage usage,
- int nCANames, char **caNames,
- void *proto_win);
+CERTCertList *CERT_MatchUserCert(CERTCertDBHandle *handle, SECCertUsage usage,
+ int nCANames, char **caNames, void *proto_win);
-CERTCertList *
-CERT_NewCertList(void);
+CERTCertList *CERT_NewCertList(void);
/* free the cert list and all the certs in the list */
-void
-CERT_DestroyCertList(CERTCertList *certs);
+void CERT_DestroyCertList(CERTCertList *certs);
/* remove the node and free the cert */
-void
-CERT_RemoveCertListNode(CERTCertListNode *node);
+void CERT_RemoveCertListNode(CERTCertListNode *node);
/* equivalent to CERT_AddCertToListTailWithData(certs, cert, NULL) */
-SECStatus
-CERT_AddCertToListTail(CERTCertList *certs, CERTCertificate *cert);
+SECStatus CERT_AddCertToListTail(CERTCertList *certs, CERTCertificate *cert);
/* equivalent to CERT_AddCertToListHeadWithData(certs, cert, NULL) */
-SECStatus
-CERT_AddCertToListHead(CERTCertList *certs, CERTCertificate *cert);
+SECStatus CERT_AddCertToListHead(CERTCertList *certs, CERTCertificate *cert);
/*
* The new cert list node takes ownership of "cert". "cert" is freed
* when the list node is removed.
*/
-SECStatus
-CERT_AddCertToListTailWithData(CERTCertList *certs, CERTCertificate *cert,
- void *appData);
+SECStatus CERT_AddCertToListTailWithData(CERTCertList *certs,
+ CERTCertificate *cert, void *appData);
/*
* The new cert list node takes ownership of "cert". "cert" is freed
* when the list node is removed.
*/
-SECStatus
-CERT_AddCertToListHeadWithData(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);
+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);
+PRBool CERT_SortCBValidity(CERTCertificate *certa, CERTCertificate *certb,
+ void *arg);
-SECStatus
-CERT_CheckForEvilCert(CERTCertificate *cert);
+SECStatus CERT_CheckForEvilCert(CERTCertificate *cert);
-CERTGeneralName *
-CERT_GetCertificateNames(CERTCertificate *cert, PLArenaPool *arena);
+CERTGeneralName *CERT_GetCertificateNames(CERTCertificate *cert,
+ PLArenaPool *arena);
-CERTGeneralName *
-CERT_GetConstrainedCertificateNames(const CERTCertificate *cert,
- PLArenaPool *arena,
- PRBool includeSubjectCommonName);
+CERTGeneralName *CERT_GetConstrainedCertificateNames(
+ const 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,
- const SECItem *name, PRTime sorttime,
- PRBool validOnly);
+CERTCertList *CERT_CreateSubjectCertList(CERTCertList *certList,
+ CERTCertDBHandle *handle,
+ const 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);
+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);
+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);
+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);
+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
@@ -1327,28 +1263,24 @@ CERT_TrustFlagsForCACertUsage(SECCertUsage usage,
* "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);
+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);
+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
@@ -1360,15 +1292,13 @@ CERT_FindUserCertByUsage(CERTCertDBHandle *handle,
* "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);
+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);
+SECStatus CERT_FilterCertListForUserCerts(CERTCertList *certList);
/*
* Collect the nicknames from all certs in a CertList. If the cert is not
@@ -1379,9 +1309,9 @@ CERT_FilterCertListForUserCerts(CERTCertList *certList);
* "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 *CERT_NicknameStringsFromCertList(CERTCertList *certList,
+ char *expiredString,
+ char *notYetGoodString);
/*
* Extract the nickname from a nickmake string that may have either
@@ -1395,9 +1325,8 @@ CERT_NicknameStringsFromCertList(CERTCertList *certList, char *expiredString,
*
* Returns the raw nickname
*/
-char *
-CERT_ExtractNicknameString(char *namestring, char *expiredString,
- char *notYetGoodString);
+char *CERT_ExtractNicknameString(char *namestring, char *expiredString,
+ char *notYetGoodString);
/*
* Given a certificate, return a string containing the nickname, and possibly
@@ -1412,16 +1341,16 @@ CERT_ExtractNicknameString(char *namestring, char *expiredString,
* "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);
+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);
+char *CERT_DerNameToAscii(SECItem *dername);
/*
* Supported usage values and types:
@@ -1433,10 +1362,10 @@ CERT_DerNameToAscii(SECItem *dername);
* certUsageObjectSigner
*/
-CERTCertificate *
-CERT_FindMatchingCert(CERTCertDBHandle *handle, SECItem *derName,
- CERTCertOwner owner, SECCertUsage usage,
- PRBool preferTrusted, PRTime validTime, PRBool validOnly);
+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.
@@ -1446,21 +1375,18 @@ CERT_FindMatchingCert(CERTCertDBHandle *handle, SECItem *derName,
* changing(maybe just adding?) the trust of a cert
* adjusting the reference count of a cert
*/
-void
-CERT_LockDB(CERTCertDBHandle *handle);
+void CERT_LockDB(CERTCertDBHandle *handle);
/*
* Free the global cert database lock.
*/
-void
-CERT_UnlockDB(CERTCertDBHandle *handle);
+void CERT_UnlockDB(CERTCertDBHandle *handle);
/*
* Get the certificate status checking configuratino data for
* the certificate database
*/
-CERTStatusConfig *
-CERT_GetStatusConfig(CERTCertDBHandle *handle);
+CERTStatusConfig *CERT_GetStatusConfig(CERTCertDBHandle *handle);
/*
* Set the certificate status checking information for the
@@ -1468,10 +1394,7 @@ CERT_GetStatusConfig(CERTCertDBHandle *handle);
* database and will be freed by calling the 'Destroy' function in
* the configuration object.
*/
-void
-CERT_SetStatusConfig(CERTCertDBHandle *handle, CERTStatusConfig *config);
-
-
+void CERT_SetStatusConfig(CERTCertDBHandle *handle, CERTStatusConfig *config);
/*
* Acquire the cert reference count lock
@@ -1479,14 +1402,12 @@ CERT_SetStatusConfig(CERTCertDBHandle *handle, CERTStatusConfig *config);
* 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);
+void CERT_LockCertRefCount(CERTCertificate *cert);
/*
* Free the cert reference count lock
*/
-void
-CERT_UnlockCertRefCount(CERTCertificate *cert);
+void CERT_UnlockCertRefCount(CERTCertificate *cert);
/*
* Acquire the cert trust lock
@@ -1494,14 +1415,12 @@ CERT_UnlockCertRefCount(CERTCertificate *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(const CERTCertificate *cert);
+void CERT_LockCertTrust(const CERTCertificate *cert);
/*
* Free the cert trust lock
*/
-void
-CERT_UnlockCertTrust(const CERTCertificate *cert);
+void CERT_UnlockCertTrust(const CERTCertificate *cert);
/*
* Digest the cert's subject public key using the specified algorithm.
@@ -1513,47 +1432,44 @@ CERT_UnlockCertTrust(const CERTCertificate *cert);
* 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_GetSubjectPublicKeyDigest(PLArenaPool *arena, const CERTCertificate *cert,
- SECOidTag digestAlg, SECItem *fill);
+ */
+extern SECItem *CERT_GetSubjectPublicKeyDigest(PLArenaPool *arena,
+ const CERTCertificate *cert,
+ SECOidTag digestAlg,
+ SECItem *fill);
/*
* Digest the cert's subject name using the specified algorithm.
*/
-extern SECItem *
-CERT_GetSubjectNameDigest(PLArenaPool *arena, const CERTCertificate *cert,
- SECOidTag digestAlg, SECItem *fill);
-
-SECStatus CERT_CheckCRL(CERTCertificate* cert, CERTCertificate* issuer,
- const SECItem* dp, PRTime t, void* wincx);
+extern SECItem *CERT_GetSubjectNameDigest(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);
+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);
+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,
- const CERTNameConstraints *constraints,
- const CERTGeneralName *currentName);
+extern SECStatus CERT_CheckNameSpace(PLArenaPool *arena,
+ const CERTNameConstraints *constraints,
+ const CERTGeneralName *currentName);
/*
* Extract and allocate the name constraints extension from the CA cert.
@@ -1561,84 +1477,70 @@ CERT_CheckNameSpace(PLArenaPool *arena,
* CERT_GetImposedNameConstraints returns a name constraints extension
* for the subject of the certificate, then that extension will be returned.
*/
-extern SECStatus
-CERT_FindNameConstraintsExten(PLArenaPool *arena,
- CERTCertificate *cert,
- CERTNameConstraints **constraints);
+extern SECStatus CERT_FindNameConstraintsExten(
+ PLArenaPool *arena, CERTCertificate *cert,
+ CERTNameConstraints **constraints);
/*
* Initialize a new GERTGeneralName fields (link)
*/
-extern CERTGeneralName *
-CERT_NewGeneralName(PLArenaPool *arena, CERTGeneralNameType type);
+extern CERTGeneralName *CERT_NewGeneralName(PLArenaPool *arena,
+ CERTGeneralNameType type);
/*
* Lookup a CERTGeneralNameType constant by its human readable string.
*/
-extern CERTGeneralNameType
-CERT_GetGeneralNameTypeFromString(const char *string);
+extern CERTGeneralNameType CERT_GetGeneralNameTypeFromString(
+ const char *string);
/*
* 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_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);
+ 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);
+extern const CERTRevocationFlags *CERT_GetPKIXVerifyNistRevocationPolicy(void);
/*
* Returns a pointer to a static structure.
*/
-extern const CERTRevocationFlags*
-CERT_GetClassicOCSPEnabledSoftFailurePolicy(void);
+extern const CERTRevocationFlags *CERT_GetClassicOCSPEnabledSoftFailurePolicy(
+ void);
/*
* Returns a pointer to a static structure.
*/
-extern const CERTRevocationFlags*
-CERT_GetClassicOCSPEnabledHardFailurePolicy(void);
+extern const CERTRevocationFlags *CERT_GetClassicOCSPEnabledHardFailurePolicy(
+ void);
/*
* Returns a pointer to a static structure.
*/
-extern const CERTRevocationFlags*
-CERT_GetClassicOCSPDisabledPolicy(void);
+extern const CERTRevocationFlags *CERT_GetClassicOCSPDisabledPolicy(void);
/*
* Verify a Cert with libpkix
@@ -1647,12 +1549,10 @@ CERT_GetClassicOCSPDisabledPolicy(void);
* 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);
+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
@@ -1669,8 +1569,7 @@ extern PRBool CERT_GetUsePKIXForValidation(void);
* and allocate the inner arrays of the given sizes.
* To cleanup call CERT_DestroyCERTRevocationFlags.
*/
-extern CERTRevocationFlags *
-CERT_AllocCERTRevocationFlags(
+extern CERTRevocationFlags *CERT_AllocCERTRevocationFlags(
PRUint32 number_leaf_methods, PRUint32 number_leaf_pref_methods,
PRUint32 number_chain_methods, PRUint32 number_chain_pref_methods);
@@ -1678,8 +1577,7 @@ CERT_AllocCERTRevocationFlags(
* Destroy the arrays inside flags,
* and destroy the object pointed to by flags, too.
*/
-extern void
-CERT_DestroyCERTRevocationFlags(CERTRevocationFlags *flags);
+extern void CERT_DestroyCERTRevocationFlags(CERTRevocationFlags *flags);
SEC_END_PROTOS
diff --git a/nss/lib/certdb/certdb.c b/nss/lib/certdb/certdb.c
index f282bbb..d37334d 100644
--- a/nss/lib/certdb/certdb.c
+++ b/nss/lib/certdb/certdb.c
@@ -26,7 +26,7 @@
#include "secerr.h"
#include "sslerr.h"
#include "pk11func.h"
-#include "xconst.h" /* for CERT_DecodeAltNameExtension */
+#include "xconst.h" /* for CERT_DecodeAltNameExtension */
#include "pki.h"
#include "pki3hack.h"
@@ -41,17 +41,13 @@ 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, }
+ { 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[] = {
@@ -59,80 +55,60 @@ const SEC_ASN1Template CERT_SequenceOfCertExtensionTemplate[] = {
};
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 }
+ { 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 },
+ { 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 },
+ { 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 },
+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) },
+ offsetof(CERTCertificate, signatureWrap.signatureAlgorithm),
+ SEC_ASN1_SUB(SECOID_AlgorithmIDTemplate) },
+ { SEC_ASN1_BIT_STRING, offsetof(CERTCertificate, signatureWrap.signature) },
{ 0 }
};
@@ -140,16 +116,15 @@ const SEC_ASN1Template SEC_SignedCertificateTemplate[] =
* 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_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 }
};
@@ -158,14 +133,13 @@ const SEC_ASN1Template SEC_CertSubjectTemplate[] = {
* 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_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 }
};
@@ -173,12 +147,11 @@ const SEC_ASN1Template SEC_CertIssuerTemplate[] = {
* 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_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 }
};
@@ -189,16 +162,13 @@ const SEC_ASN1Template SEC_CertSerialNumberTemplate[] = {
* 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_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 }
};
@@ -210,17 +180,17 @@ SEC_ASN1_CHOOSER_IMPLEMENT(CERT_SequenceOfCertExtensionTemplate)
SECStatus
CERT_KeyFromIssuerAndSN(PLArenaPool *arena, SECItem *issuer, SECItem *sn,
- SECItem *key)
+ SECItem *key)
{
key->len = sn->len + issuer->len;
if ((sn->data == NULL) || (issuer->data == NULL)) {
- goto loser;
+ goto loser;
}
-
- key->data = (unsigned char*)PORT_ArenaAlloc(arena, key->len);
- if ( !key->data ) {
- goto loser;
+
+ key->data = (unsigned char *)PORT_ArenaAlloc(arena, key->len);
+ if (!key->data) {
+ goto loser;
}
/* copy the serialNumber */
@@ -229,13 +199,12 @@ CERT_KeyFromIssuerAndSN(PLArenaPool *arena, SECItem *issuer, SECItem *sn,
/* copy the issuer */
PORT_Memcpy(&key->data[sn->len], issuer->data, issuer->len);
- return(SECSuccess);
+ return (SECSuccess);
loser:
- return(SECFailure);
+ return (SECFailure);
}
-
/*
* Extract the subject name from a DER certificate
*/
@@ -246,129 +215,122 @@ CERT_NameFromDERCert(SECItem *derCert, SECItem *derName)
PLArenaPool *arena;
CERTSignedData sd;
void *tmpptr;
-
+
arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
-
- if ( ! arena ) {
- return(SECFailure);
+
+ if (!arena) {
+ return (SECFailure);
}
-
+
PORT_Memset(&sd, 0, sizeof(CERTSignedData));
rv = SEC_QuickDERDecodeItem(arena, &sd, CERT_SignedDataTemplate, derCert);
-
- if ( rv ) {
- goto loser;
+
+ if (rv) {
+ goto loser;
}
-
+
PORT_Memset(derName, 0, sizeof(SECItem));
- rv = SEC_QuickDERDecodeItem(arena, derName, SEC_CertSubjectTemplate, &sd.data);
+ rv = SEC_QuickDERDecodeItem(arena, derName, SEC_CertSubjectTemplate,
+ &sd.data);
- if ( rv ) {
- goto loser;
+ if (rv) {
+ goto loser;
}
tmpptr = derName->data;
- derName->data = (unsigned char*)PORT_Alloc(derName->len);
- if ( derName->data == NULL ) {
- goto loser;
+ 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);
+ return (SECSuccess);
loser:
PORT_FreeArena(arena, PR_FALSE);
- return(SECFailure);
+ return (SECFailure);
}
SECStatus
CERT_IssuerNameFromDERCert(SECItem *derCert, SECItem *derName)
{
int rv;
- PLArenaPool *arena;
+ PORTCheapArenaPool tmpArena;
CERTSignedData sd;
void *tmpptr;
-
- arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
-
- if ( ! arena ) {
- return(SECFailure);
- }
-
+
+ PORT_InitCheapArena(&tmpArena, DER_DEFAULT_CHUNKSIZE);
+
PORT_Memset(&sd, 0, sizeof(CERTSignedData));
- rv = SEC_QuickDERDecodeItem(arena, &sd, CERT_SignedDataTemplate, derCert);
-
- if ( rv ) {
- goto loser;
+ rv = SEC_QuickDERDecodeItem(&tmpArena.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;
+ PORT_Memset(derName, 0, sizeof(SECItem));
+ rv = SEC_QuickDERDecodeItem(&tmpArena.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;
+ 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);
+
+ PORT_DestroyCheapArena(&tmpArena);
+ return (SECSuccess);
loser:
- PORT_FreeArena(arena, PR_FALSE);
- return(SECFailure);
+ PORT_DestroyCheapArena(&tmpArena);
+ return (SECFailure);
}
SECStatus
CERT_SerialNumberFromDERCert(SECItem *derCert, SECItem *derName)
{
int rv;
- PLArenaPool *arena;
+ PORTCheapArenaPool tmpArena;
CERTSignedData sd;
void *tmpptr;
-
- arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
-
- if ( ! arena ) {
- return(SECFailure);
- }
-
+
+ PORT_InitCheapArena(&tmpArena, DER_DEFAULT_CHUNKSIZE);
+
PORT_Memset(&sd, 0, sizeof(CERTSignedData));
- rv = SEC_QuickDERDecodeItem(arena, &sd, CERT_SignedDataTemplate, derCert);
-
- if ( rv ) {
- goto loser;
+ rv = SEC_QuickDERDecodeItem(&tmpArena.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;
+ PORT_Memset(derName, 0, sizeof(SECItem));
+ rv = SEC_QuickDERDecodeItem(&tmpArena.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;
+ 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);
+
+ PORT_DestroyCheapArena(&tmpArena);
+ return (SECSuccess);
loser:
- PORT_FreeArena(arena, PR_FALSE);
- return(SECFailure);
+ PORT_DestroyCheapArena(&tmpArena);
+ return (SECFailure);
}
/*
@@ -388,25 +350,25 @@ CERT_KeyFromDERCert(PLArenaPool *reqArena, SECItem *derCert, SECItem *key)
}
PORT_Memset(&sd, 0, sizeof(CERTSignedData));
- rv = SEC_QuickDERDecodeItem(reqArena, &sd, CERT_SignedDataTemplate,
- derCert);
-
- if ( rv ) {
- goto loser;
+ 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;
+ if (rv) {
+ goto loser;
}
- return(CERT_KeyFromIssuerAndSN(reqArena, &certkey.derIssuer,
- &certkey.serialNumber, key));
+ return (CERT_KeyFromIssuerAndSN(reqArena, &certkey.derIssuer,
+ &certkey.serialNumber, key));
loser:
- return(SECFailure);
+ return (SECFailure);
}
/*
@@ -418,32 +380,30 @@ 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;
-
+ 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 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;
+ if (CERT_GovtApprovedBitSet(cert)) {
+ cert->keyUsage |= KU_NS_GOVT_APPROVED;
+ cert->rawKeyUsage |= KU_NS_GOVT_APPROVED;
}
-
- return(SECSuccess);
-}
+ return (SECSuccess);
+}
static SECStatus
findOIDinOIDSeqByTagNum(CERTOidSequence *seq, SECOidTag tagnum)
@@ -451,17 +411,17 @@ 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++;
- }
+ oids = seq->oids;
+ while (oids != NULL && *oids != NULL) {
+ oid = *oids;
+ if (SECOID_FindOIDTag(oid) == tagnum) {
+ rv = SECSuccess;
+ break;
+ }
+ oids++;
+ }
}
return rv;
}
@@ -500,132 +460,121 @@ cert_ComputeCertType(CERTCertificate *cert)
tmpitem.data = NULL;
CERT_FindNSCertTypeExtension(cert, &tmpitem);
encodedExtKeyUsage.data = NULL;
- rv = CERT_FindCertExtension(cert, SEC_OID_X509_EXT_KEY_USAGE,
- &encodedExtKeyUsage);
+ rv = CERT_FindCertExtension(cert, SEC_OID_X509_EXT_KEY_USAGE,
+ &encodedExtKeyUsage);
if (rv == SECSuccess) {
- extKeyUsage = CERT_DecodeOidSequence(&encodedExtKeyUsage);
+ extKeyUsage = CERT_DecodeOidSequence(&encodedExtKeyUsage);
}
rv = CERT_FindBasicConstraintExten(cert, &basicConstraint);
if (rv == SECSuccess) {
- basicConstraintPresent = PR_TRUE;
+ 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;
- }
+ 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 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);
+ PORT_Free(encodedExtKeyUsage.data);
}
if (extKeyUsage != NULL) {
- CERT_DestroyOidSequence(extKeyUsage);
+ CERT_DestroyOidSequence(extKeyUsage);
}
return nsCertType;
}
@@ -638,44 +587,44 @@ 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 (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 ( cert->subjectKeyID.len == 0 ) {
- return(SECFailure);
+ /* 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;
+ }
+ }
}
- return(SECSuccess);
+ if (cert->subjectKeyID.len == 0) {
+ return (SECFailure);
+ }
+ return (SECSuccess);
}
static PRBool
@@ -689,48 +638,48 @@ cert_IsRootCert(CERTCertificate *cert)
/* it MUST be self-issued to be a root */
if (cert->derIssuer.len == 0 ||
- !SECITEM_ItemsAreEqual(&cert->derIssuer, &cert->derSubject))
- {
- return PR_FALSE;
+ !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;
+ /* 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;
@@ -741,7 +690,7 @@ cert_IsRootCert(CERTCertificate *cert)
*/
CERTCertificate *
CERT_DecodeDERCertificate(SECItem *derSignedCert, PRBool copyDER,
- char *nickname)
+ char *nickname)
{
CERTCertificate *cert;
PLArenaPool *arena;
@@ -749,83 +698,83 @@ CERT_DecodeDERCertificate(SECItem *derSignedCert, PRBool copyDER,
int rv;
int len;
char *tmpname;
-
+
/* make a new arena */
arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
-
- if ( !arena ) {
- return 0;
+
+ if (!arena) {
+ return 0;
}
/* allocate the certificate structure */
cert = (CERTCertificate *)PORT_ArenaZAlloc(arena, sizeof(CERTCertificate));
-
- if ( !cert ) {
- goto loser;
+
+ 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);
+
+ 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;
+ /* point to passed in DER data */
+ cert->derCert = *derSignedCert;
}
/* decode the certificate info */
rv = SEC_QuickDERDecodeItem(arena, cert, SEC_SignedCertificateTemplate,
- &cert->derCert);
+ &cert->derCert);
- if ( rv ) {
- goto loser;
+ if (rv) {
+ goto loser;
}
- if (cert_HasUnknownCriticalExten (cert->extensions) == PR_TRUE) {
+ 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;
+ &cert->certKey);
+ if (rv) {
+ goto loser;
}
/* set the nickname */
- if ( nickname == NULL ) {
- cert->nickname = NULL;
+ 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;
- }
+ /* 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);
+ 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;
+ if (rv != SECSuccess) {
+ goto loser;
}
/* initialize keyUsage */
rv = GetKeyUsage(cert);
- if ( rv != SECSuccess ) {
- goto loser;
+ if (rv != SECSuccess) {
+ goto loser;
}
/* determine if this is a root cert */
@@ -833,46 +782,45 @@ CERT_DecodeDERCertificate(SECItem *derSignedCert, PRBool copyDER,
/* initialize the certType */
rv = cert_GetCertType(cert);
- if ( rv != SECSuccess ) {
- goto loser;
+ if (rv != SECSuccess) {
+ goto loser;
}
tmpname = CERT_NameToAscii(&cert->subject);
- if ( tmpname != NULL ) {
- cert->subjectName = PORT_ArenaStrdup(cert->arena, tmpname);
- PORT_Free(tmpname);
+ 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);
+ 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);
-
+
+ return (cert);
+
loser:
- if ( arena ) {
- PORT_FreeArena(arena, PR_FALSE);
+ if (arena) {
+ PORT_FreeArena(arena, PR_FALSE);
}
-
- return(0);
+
+ return (0);
}
CERTCertificate *
__CERT_DecodeDERCertificate(SECItem *derSignedCert, PRBool copyDER,
- char *nickname)
+ char *nickname)
{
return CERT_DecodeDERCertificate(derSignedCert, copyDER, nickname);
}
-
CERTValidity *
CERT_CreateValidity(PRTime notBefore, PRTime notAfter)
{
@@ -881,26 +829,28 @@ CERT_CreateValidity(PRTime notBefore, PRTime notAfter)
PLArenaPool *arena;
if (notBefore > notAfter) {
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- return NULL;
+ PORT_SetError(SEC_ERROR_INVALID_ARGS);
+ return NULL;
}
arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
-
- if ( !arena ) {
- return(0);
+
+ if (!arena) {
+ return (0);
}
-
- v = (CERTValidity*) PORT_ArenaZAlloc(arena, sizeof(CERTValidity));
+
+ 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;
+ 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:
+loser:
CERT_DestroyValidity(v);
return 0;
}
@@ -912,9 +862,10 @@ CERT_CopyValidity(PLArenaPool *arena, CERTValidity *to, CERTValidity *from)
CERT_DestroyValidity(to);
to->arena = arena;
-
+
rv = SECITEM_CopyItem(arena, &to->notBefore, &from->notBefore);
- if (rv) return rv;
+ if (rv)
+ return rv;
rv = SECITEM_CopyItem(arena, &to->notAfter, &from->notAfter);
return rv;
}
@@ -923,7 +874,7 @@ void
CERT_DestroyValidity(CERTValidity *v)
{
if (v && v->arena) {
- PORT_FreeArena(v->arena, PR_FALSE);
+ PORT_FreeArena(v->arena, PR_FALSE);
}
return;
}
@@ -934,20 +885,19 @@ CERT_DestroyValidity(CERTValidity *v)
** 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 */
+#define PENDING_SLOP (24L * 60L * 60L) /* seconds per day */
+static PRInt32 pendingSlop = PENDING_SLOP; /* seconds */
PRInt32
CERT_GetSlopTime(void)
{
- return pendingSlop; /* seconds */
+ return pendingSlop; /* seconds */
}
-SECStatus
-CERT_SetSlopTime(PRInt32 slop) /* seconds */
+SECStatus CERT_SetSlopTime(PRInt32 slop) /* seconds */
{
if (slop < 0)
- return SECFailure;
+ return SECFailure;
pendingSlop = slop;
return SECSuccess;
}
@@ -961,20 +911,20 @@ CERT_GetCertTimes(const CERTCertificate *c, PRTime *notBefore, PRTime *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);
+ return (SECFailure);
}
-
+
/* convert DER not-after time */
rv = DER_DecodeTimeChoice(notAfter, &c->validity.notAfter);
if (rv) {
- return(SECFailure);
+ return (SECFailure);
}
- return(SECSuccess);
+ return (SECSuccess);
}
/*
@@ -989,77 +939,77 @@ CERT_CheckCertValidTimes(const CERTCertificate *c, PRTime t,
if (!c) {
PORT_SetError(SEC_ERROR_INVALID_ARGS);
- return(secCertTimeUndetermined);
+ return (secCertTimeUndetermined);
}
/* if cert is already marked OK, then don't bother to check */
- if ( allowOverride && c->timeOK ) {
- return(secCertTimeValid);
+ 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?*/
+ 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, <, notBefore)) {
+ PORT_SetError(SEC_ERROR_EXPIRED_CERTIFICATE);
+ return (secCertTimeNotValidYet);
}
- if ( LL_CMP( t, >, notAfter) ) {
- PORT_SetError(SEC_ERROR_EXPIRED_CERTIFICATE);
- return(secCertTimeExpired);
+ if (LL_CMP(t, >, notAfter)) {
+ PORT_SetError(SEC_ERROR_EXPIRED_CERTIFICATE);
+ return (secCertTimeExpired);
}
- return(secCertTimeValid);
+ 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);
+ 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);
+ rv = DER_DecodeTimeChoice(notAfter, &date->nextUpdate);
+ if (rv) {
+ return (SECFailure);
+ }
+ } else {
+ LL_I2L(*notAfter, 0L);
}
- return(SECSuccess);
+ return (SECSuccess);
}
/* These routines should probably be combined with the cert
* routines using an common extraction routine.
*/
SECCertTimeValidity
-SEC_CheckCrlTimes(CERTCrl *crl, PRTime t) {
+SEC_CheckCrlTimes(CERTCrl *crl, PRTime t)
+{
PRTime notBefore, notAfter, llPendingSlop, tmp1;
SECStatus rv;
if (!crl) {
PORT_SetError(SEC_ERROR_INVALID_ARGS);
- return(secCertTimeUndetermined);
+ return (secCertTimeUndetermined);
}
rv = SEC_GetCrlTimes(crl, &notBefore, &notAfter);
-
+
if (rv) {
- return(secCertTimeExpired);
+ return (secCertTimeExpired);
}
LL_I2L(llPendingSlop, pendingSlop);
@@ -1067,155 +1017,157 @@ SEC_CheckCrlTimes(CERTCrl *crl, PRTime t) {
LL_I2L(tmp1, PR_USEC_PER_SEC);
LL_MUL(llPendingSlop, llPendingSlop, tmp1);
LL_SUB(notBefore, notBefore, llPendingSlop);
- if ( LL_CMP( t, <, notBefore ) ) {
- PORT_SetError(SEC_ERROR_CRL_EXPIRED);
- return(secCertTimeNotValidYet);
+ if (LL_CMP(t, <, notBefore)) {
+ PORT_SetError(SEC_ERROR_CRL_EXPIRED);
+ 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_IS_ZERO(notAfter)) {
+ return (secCertTimeValid);
}
- if ( LL_CMP( t, >, notAfter) ) {
- PORT_SetError(SEC_ERROR_CRL_EXPIRED);
- return(secCertTimeExpired);
+ if (LL_CMP(t, >, notAfter)) {
+ PORT_SetError(SEC_ERROR_CRL_EXPIRED);
+ return (secCertTimeExpired);
}
- return(secCertTimeValid);
+ return (secCertTimeValid);
}
PRBool
-SEC_CrlIsNewer(CERTCrl *inNew, CERTCrl *old) {
+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;
+ if (rv)
+ return PR_FALSE;
/* problems with the old CRL? replace it */
rv = SEC_GetCrlTimes(old, &oldNotBefore, &oldNotAfter);
- if (rv) return PR_TRUE;
+ 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
+ * return required key usage and cert type based on cert usage
*/
SECStatus
-CERT_KeyUsageAndTypeForCertUsage(SECCertUsage usage,
- PRBool ca,
- unsigned int *retKeyUsage,
- unsigned int *retCertType)
+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;
- }
+
+ 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);
+ 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);
+ return (SECFailure);
}
/*
@@ -1226,60 +1178,60 @@ CERT_CheckKeyUsage(CERTCertificate *cert, unsigned int requiredUsage)
{
if (!cert) {
PORT_SetError(SEC_ERROR_INVALID_ARGS);
- return SECFailure;
+ 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;
- }
+ 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 (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;
+ 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);
+ NSSCertificate *tmp = STAN_GetNSSCertificate(c);
+ nssCertificate_AddRef(tmp);
}
return c;
}
@@ -1294,37 +1246,37 @@ void
CERT_SetDefaultCertDB(CERTCertDBHandle *handle)
{
default_cert_db_handle = handle;
-
+
return;
}
CERTCertDBHandle *
CERT_GetDefaultCertDB(void)
{
- return(default_cert_db_handle);
+ 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;
+ if (s == NULL) {
+ return;
}
-
- while ( *s ) {
- *s = PORT_Tolower(*s);
- s++;
+
+ while (*s) {
+ *s = PORT_Tolower(*s);
+ s++;
}
-
+
return;
}
static PRBool
cert_IsIPAddr(const char *hn)
{
- PRBool isIPaddr = PR_FALSE;
- PRNetAddr netAddr;
+ PRBool isIPaddr = PR_FALSE;
+ PRNetAddr netAddr;
isIPaddr = (PR_SUCCESS == PR_StringToNetAddr(hn, &netAddr));
return isIPaddr;
}
@@ -1337,18 +1289,22 @@ SECStatus
CERT_AddOKDomainName(CERTCertificate *cert, const char *hn)
{
CERTOKDomainName *domainOK;
- int newNameLen;
+ int newNameLen;
if (!hn || !(newNameLen = strlen(hn))) {
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- return SECFailure;
+ PORT_SetError(SEC_ERROR_INVALID_ARGS);
+ return SECFailure;
+ }
+ domainOK = (CERTOKDomainName *)PORT_ArenaZAlloc(cert->arena, sizeof(*domainOK));
+ if (!domainOK) {
+ return SECFailure; /* error code is already set. */
+ }
+ domainOK->name = (char *)PORT_ArenaZAlloc(cert->arena, newNameLen + 1);
+ if (!domainOK->name) {
+ return SECFailure; /* error code is already set. */
}
- domainOK = (CERTOKDomainName *)PORT_ArenaZAlloc(cert->arena,
- (sizeof *domainOK) + newNameLen);
- if (!domainOK)
- return SECFailure; /* error code is already set. */
- PORT_Strcpy(domainOK->name, hn);
+ PORT_Strncpy(domainOK->name, hn, newNameLen + 1);
sec_lower_string(domainOK->name);
/* put at head of list. */
@@ -1364,177 +1320,179 @@ CERT_AddOKDomainName(CERTCertificate *cert, const char *hn)
** This function may modify string cn, so caller must pass a modifiable copy.
*/
static SECStatus
-cert_TestHostName(char * cn, const char * hn)
+cert_TestHostName(char *cn, const char *hn)
{
static int useShellExp = -1;
if (useShellExp < 0) {
- useShellExp = (NULL != PR_GetEnv("NSS_USE_SHEXP_IN_CERT_NAME"));
+ useShellExp = (NULL != PR_GetEnvSecure("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;
- }
+ /* 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 6125. */
- 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, and
- * - must not be preceded by an IDNA ACE prefix (xn--)
- */
- if (wildcard && secondcndot && secondcndot[1] && firsthndot
- && firstcndot - wildcard == 1 /* wildcard is last char in first component */
- && secondcndot - firstcndot > 1 /* second component is non-empty */
- && PORT_Strrchr(cn, '*') == wildcard /* only one wildcard in cn */
- && !PORT_Strncasecmp(cn, hn, wildcard - cn)
- && !PORT_Strcasecmp(firstcndot, firsthndot)
- /* If hn starts with xn--, then cn must start with wildcard */
- && (PORT_Strncasecmp(hn, "xn--", 4) || wildcard == cn)) {
- /* valid wildcard pattern match */
- return SECSuccess;
- }
- }
- /* String cn has no wildcard or shell expression.
- * Compare entire string hn with cert name.
+ /* New approach conforms to RFC 6125. */
+ 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, and
+ * - must not be preceded by an IDNA ACE prefix (xn--)
+ */
+ if (wildcard && secondcndot && secondcndot[1] && firsthndot &&
+ firstcndot - wildcard == 1 /* wildcard is last char in first component */
+ && secondcndot - firstcndot > 1 /* second component is non-empty */
+ && PORT_Strrchr(cn, '*') == wildcard /* only one wildcard in cn */
+ && !PORT_Strncasecmp(cn, hn, wildcard - cn) &&
+ !PORT_Strcasecmp(firstcndot, firsthndot)
+ /* If hn starts with xn--, then cn must start with wildcard */
+ && (PORT_Strncasecmp(hn, "xn--", 4) || wildcard == cn)) {
+ /* 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;
+ return SECSuccess;
}
PORT_SetError(SSL_ERROR_BAD_CERT_DOMAIN);
return SECFailure;
}
-
SECStatus
cert_VerifySubjectAltName(const CERTCertificate *cert, const char *hn)
{
- PLArenaPool * arena = NULL;
- CERTGeneralName * nameList = NULL;
- CERTGeneralName * current;
- char * cn;
- int cnBufLen;
- int DNSextCount = 0;
- int IPextCount = 0;
- PRBool isIPaddr = PR_FALSE;
- SECStatus rv = SECFailure;
- SECItem subAltName;
- PRNetAddr netAddr;
- char cnbuf[128];
+ PLArenaPool *arena = NULL;
+ CERTGeneralName *nameList = NULL;
+ CERTGeneralName *current;
+ char *cn;
+ int cnBufLen;
+ int DNSextCount = 0;
+ int IPextCount = 0;
+ PRBool isIPaddr = PR_FALSE;
+ SECStatus rv = SECFailure;
+ SECItem subAltName;
+ PRNetAddr netAddr;
+ char cnbuf[128];
subAltName.data = NULL;
- cn = cnbuf;
+ cn = cnbuf;
cnBufLen = sizeof cnbuf;
- rv = CERT_FindCertExtension(cert, SEC_OID_X509_SUBJECT_ALT_NAME,
- &subAltName);
+ rv = CERT_FindCertExtension(cert, SEC_OID_X509_SUBJECT_ALT_NAME,
+ &subAltName);
if (rv != SECSuccess) {
- goto fail;
+ goto fail;
}
isIPaddr = (PR_SUCCESS == PR_StringToNetAddr(hn, &netAddr));
- rv = SECFailure;
arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
- if (!arena)
- goto fail;
+ if (!arena)
+ goto fail;
nameList = current = CERT_DecodeAltNameExtension(arena, &subAltName);
if (!current)
- goto fail;
+ 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);
+ 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);
+ /* no relevant value in the extension was found. */
+ PORT_SetError(SEC_ERROR_EXTENSION_NOT_FOUND);
} else {
- PORT_SetError(SSL_ERROR_BAD_CERT_DOMAIN);
+ PORT_SetError(SSL_ERROR_BAD_CERT_DOMAIN);
}
rv = SECFailure;
@@ -1542,11 +1500,11 @@ finish:
/* Don't free nameList, it's part of the arena. */
if (arena) {
- PORT_FreeArena(arena, PR_FALSE);
+ PORT_FreeArena(arena, PR_FALSE);
}
if (subAltName.data) {
- SECITEM_FreeItem(&subAltName, PR_FALSE);
+ SECITEM_FreeItem(&subAltName, PR_FALSE);
}
return rv;
@@ -1562,19 +1520,19 @@ finish:
CERTGeneralName *
cert_GetSubjectAltNameList(const CERTCertificate *cert, PLArenaPool *arena)
{
- CERTGeneralName * nameList = NULL;
- SECStatus rv = SECFailure;
- SECItem subAltName;
+ CERTGeneralName *nameList = NULL;
+ SECStatus rv = SECFailure;
+ SECItem subAltName;
if (!cert || !arena)
- return NULL;
+ return NULL;
subAltName.data = NULL;
- rv = CERT_FindCertExtension(cert, SEC_OID_X509_SUBJECT_ALT_NAME,
+ rv = CERT_FindCertExtension(cert, SEC_OID_X509_SUBJECT_ALT_NAME,
&subAltName);
if (rv != SECSuccess)
- return NULL;
+ return NULL;
nameList = CERT_DecodeAltNameExtension(arena, &subAltName);
SECITEM_FreeItem(&subAltName, PR_FALSE);
@@ -1584,21 +1542,21 @@ cert_GetSubjectAltNameList(const CERTCertificate *cert, PLArenaPool *arena)
PRUint32
cert_CountDNSPatterns(CERTGeneralName *firstName)
{
- CERTGeneralName * current;
+ CERTGeneralName *current;
PRUint32 count = 0;
if (!firstName)
- return 0;
+ return 0;
current = firstName;
do {
switch (current->type) {
- case certDNSName:
- case certIPAddress:
- ++count;
- break;
- default:
- break;
+ case certDNSName:
+ case certIPAddress:
+ ++count;
+ break;
+ default:
+ break;
}
current = CERT_GetNextGeneralName(current);
} while (current != firstName);
@@ -1610,27 +1568,27 @@ cert_CountDNSPatterns(CERTGeneralName *firstName)
#define INET6_ADDRSTRLEN 46
#endif
-/* will fill nickNames,
+/* 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,
+ PRUint32 numberOfGeneralNames,
CERTCertNicknames *nickNames)
{
CERTGeneralName *currentInput;
char **currentOutput;
if (!firstName || !nickNames || !numberOfGeneralNames)
- return SECFailure;
+ return SECFailure;
nickNames->numnicknames = numberOfGeneralNames;
- nickNames->nicknames = PORT_ArenaAlloc(nickNames->arena,
- sizeof(char *) * numberOfGeneralNames);
+ nickNames->nicknames = PORT_ArenaAlloc(
+ nickNames->arena, sizeof(char *) * numberOfGeneralNames);
if (!nickNames->nicknames)
- return SECFailure;
+ return SECFailure;
currentInput = firstName;
currentOutput = nickNames->nicknames;
@@ -1640,47 +1598,49 @@ cert_GetDNSPatternsFromGeneralNames(CERTGeneralName *firstName,
PRNetAddr addr;
if (numberOfGeneralNames < 1) {
- /* internal consistency error */
- return SECFailure;
+ /* 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,
+ 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;
+ 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;
+ *currentOutput = cn;
+ nickNames->totallen += PORT_Strlen(cn);
+ ++currentOutput;
+ --numberOfGeneralNames;
}
currentInput = CERT_GetNextGeneralName(currentInput);
} while (currentInput != firstName);
@@ -1701,16 +1661,16 @@ CERT_GetValidDNSPatternsFromCert(CERTCertificate *cert)
CERTCertNicknames *nickNames;
PLArenaPool *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;
+ PORT_FreeArena(arena, PR_FALSE);
+ return NULL;
}
/* init the structure */
@@ -1722,40 +1682,41 @@ CERT_GetValidDNSPatternsFromCert(CERTCertificate *cert)
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;
+ SECStatus rv_getnames = SECFailure;
+ PRUint32 numNames = cert_CountDNSPatterns(generalNames);
+
+ if (numNames) {
+ rv_getnames = cert_GetDNSPatternsFromGeneralNames(
+ generalNames, numNames, nickNames);
}
- /* failure to produce output */
- PORT_FreeArena(arena, PR_FALSE);
- return NULL;
- }
+ /* 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);
+ 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;
- }
+ /* Did we allocate both the buffer of pointers and the string? */
+ if (nickNames->nicknames && *nickNames->nicknames) {
+ return nickNames;
+ }
}
PORT_FreeArena(arena, PR_FALSE);
@@ -1769,20 +1730,20 @@ CERT_GetValidDNSPatternsFromCert(CERTCertificate *cert)
SECStatus
CERT_VerifyCertName(const CERTCertificate *cert, const char *hn)
{
- char * cn;
+ char *cn;
SECStatus rv;
CERTOKDomainName *domainOK;
if (!hn || !strlen(hn)) {
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- return SECFailure;
+ 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;
- }
+ if (0 == PORT_Strcasecmp(hn, domainOK->name)) {
+ return SECSuccess;
+ }
}
/* Per RFC 2818, if the SubjectAltName extension is present, it must
@@ -1790,14 +1751,14 @@ CERT_VerifyCertName(const CERTCertificate *cert, const char *hn)
*/
rv = cert_VerifySubjectAltName(cert, hn);
if (rv == SECSuccess || PORT_GetError() != SEC_ERROR_EXTENSION_NOT_FOUND)
- return rv;
+ return rv;
cn = CERT_GetCommonName(&cert->subject);
- if ( cn ) {
+ if (cn) {
PRBool isIPaddr = cert_IsIPAddr(hn);
if (isIPaddr) {
if (PORT_Strcasecmp(hn, cn) == 0) {
- rv = SECSuccess;
+ rv = SECSuccess;
} else {
PORT_SetError(SSL_ERROR_BAD_CERT_DOMAIN);
rv = SECFailure;
@@ -1805,9 +1766,9 @@ CERT_VerifyCertName(const CERTCertificate *cert, const char *hn)
} else {
rv = cert_TestHostName(cn, hn);
}
- PORT_Free(cn);
- } else
- PORT_SetError(SSL_ERROR_BAD_CERT_DOMAIN);
+ PORT_Free(cn);
+ } else
+ PORT_SetError(SSL_ERROR_BAD_CERT_DOMAIN);
return rv;
}
@@ -1815,48 +1776,48 @@ PRBool
CERT_CompareCerts(const CERTCertificate *c1, const CERTCertificate *c2)
{
SECComparison comp;
-
+
comp = SECITEM_CompareItem(&c1->derCert, &c2->derCert);
- if ( comp == SECEqual ) { /* certs are the same */
- return(PR_TRUE);
+ if (comp == SECEqual) { /* certs are the same */
+ return (PR_TRUE);
} else {
- return(PR_FALSE);
+ 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 */
+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 */
+
+ if (PORT_Strcmp(s1, s2) != 0) {
+ return (SECFailure); /* not equal */
}
- return(SECSuccess); /* strings are 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);
+ 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);
+ if (comp != SECEqual) { /* different issuer */
+ return (PR_FALSE);
}
/* check country name */
@@ -1865,8 +1826,8 @@ CERT_CompareCertsForRedirection(CERTCertificate *c1, CERTCertificate *c2)
eq = StringsEqual(c1str, c2str);
PORT_Free(c1str);
PORT_Free(c2str);
- if ( eq != SECSuccess ) {
- return(PR_FALSE);
+ if (eq != SECSuccess) {
+ return (PR_FALSE);
}
/* check locality name */
@@ -1875,18 +1836,18 @@ CERT_CompareCertsForRedirection(CERTCertificate *c1, CERTCertificate *c2)
eq = StringsEqual(c1str, c2str);
PORT_Free(c1str);
PORT_Free(c2str);
- if ( eq != SECSuccess ) {
- return(PR_FALSE);
+ 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);
+ if (eq != SECSuccess) {
+ return (PR_FALSE);
}
/* check org name */
@@ -1895,11 +1856,11 @@ CERT_CompareCertsForRedirection(CERTCertificate *c1, CERTCertificate *c2)
eq = StringsEqual(c1str, c2str);
PORT_Free(c1str);
PORT_Free(c2str);
- if ( eq != SECSuccess ) {
- return(PR_FALSE);
+ if (eq != SECSuccess) {
+ return (PR_FALSE);
}
-#ifdef NOTDEF
+#ifdef NOTDEF
/* check orgUnit name */
/*
* We need to revisit this and decide which fields should be allowed to be
@@ -1910,46 +1871,44 @@ CERT_CompareCertsForRedirection(CERTCertificate *c1, CERTCertificate *c2)
eq = StringsEqual(c1str, c2str);
PORT_Free(c1str);
PORT_Free(c2str);
- if ( eq != SECSuccess ) {
- return(PR_FALSE);
+ if (eq != SECSuccess) {
+ return (PR_FALSE);
}
#endif
- return(PR_TRUE); /* all fields but common name are the same */
+ return (PR_TRUE); /* all fields but common name are the same */
}
-
/* CERT_CertChainFromCert and CERT_DestroyCertificateList moved
to certhigh.c */
-
CERTIssuerAndSN *
CERT_GetCertIssuerAndSN(PLArenaPool *arena, CERTCertificate *cert)
{
CERTIssuerAndSN *result;
SECStatus rv;
- if ( arena == NULL ) {
- arena = cert->arena;
+ if (arena == NULL) {
+ arena = cert->arena;
}
-
- result = (CERTIssuerAndSN*)PORT_ArenaZAlloc(arena, sizeof(*result));
+
+ result = (CERTIssuerAndSN *)PORT_ArenaZAlloc(arena, sizeof(*result));
if (result == NULL) {
- PORT_SetError (SEC_ERROR_NO_MEMORY);
- return NULL;
+ PORT_SetError(SEC_ERROR_NO_MEMORY);
+ return NULL;
}
rv = SECITEM_CopyItem(arena, &result->derIssuer, &cert->derIssuer);
if (rv != SECSuccess)
- return NULL;
+ return NULL;
rv = CERT_CopyName(arena, &result->issuer, &cert->issuer);
if (rv != SECSuccess)
- return NULL;
+ return NULL;
rv = SECITEM_CopyItem(arena, &result->serialNumber, &cert->serialNumber);
if (rv != SECSuccess)
- return NULL;
+ return NULL;
return result;
}
@@ -1962,85 +1921,84 @@ CERT_MakeCANickname(CERTCertificate *cert)
char *nickname = NULL;
int count;
CERTCertificate *dummycert;
-
+
firstname = CERT_GetCommonName(&cert->subject);
- if ( firstname == NULL ) {
- firstname = CERT_GetOrgUnitName(&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");
- }
- }
+ 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;
+ 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++;
+ 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 (firstname) {
+ PORT_Free(firstname);
}
- if ( org ) {
- PORT_Free(org);
+ if (org) {
+ PORT_Free(org);
}
-
- return(nickname);
+
+ return (nickname);
}
/* CERT_Import_CAChain moved to certhigh.c */
void
-CERT_DestroyCrl (CERTSignedCrl *crl)
+CERT_DestroyCrl(CERTSignedCrl *crl)
{
- SEC_DestroyCrl (crl);
+ SEC_DestroyCrl(crl);
}
static int
@@ -2048,9 +2006,9 @@ 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;
+ version = DER_GetInteger(&cert->version);
+ if (version < 0)
+ version = 0;
}
return version;
}
@@ -2063,35 +2021,35 @@ cert_ComputeTrustOverrides(CERTCertificate *cert, unsigned int cType)
rv = CERT_GetCertTrust(cert, &trust);
- if (rv == SECSuccess && (trust.sslFlags |
- trust.emailFlags |
- trust.objectSigningFlags)) {
+ 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 (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);
+ 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 (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);
+ 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 (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);
+ if (trust.objectSigningFlags & CERTDB_NOT_TRUSTED)
+ cType &=
+ ~(NS_CERT_TYPE_OBJECT_SIGNING | NS_CERT_TYPE_OBJECT_SIGNING_CA);
#endif
}
return cType;
@@ -2107,48 +2065,45 @@ 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);
- }
- }
+ /*
+ * Check if the constraints are available and it's a CA, OR if it's
+ * a X.509 v1 Root CA.
+ */
+ CERTBasicConstraints constraints;
+ if ((CERT_FindBasicConstraintExten(cert, &constraints) == SECSuccess &&
+ constraints.isCA) ||
+ (cert->isRoot && cert_Version(cert) < SEC_CERTIFICATE_VERSION_3))
+ 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 */
+ /*
+ * 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;
+ NS_CERT_TYPE_OBJECT_SIGNING_CA))
+ ? PR_TRUE
+ : PR_FALSE;
- if (rettype != NULL) {
- *rettype = cType;
+ if (rettype) {
+ *rettype = cType;
}
+
return ret;
}
PRBool
-CERT_IsCADERCert(SECItem *derCert, unsigned int *type) {
+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;
+ if (cert == NULL)
+ return PR_FALSE;
- isCA = CERT_IsCACert(cert,type);
- CERT_DestroyCertificate (cert);
+ isCA = CERT_IsCACert(cert, type);
+ CERT_DestroyCertificate(cert);
return isCA;
}
@@ -2160,51 +2115,51 @@ CERT_IsRootDERCert(SECItem *derCert)
/* This is okay -- only looks at extensions */
cert = CERT_DecodeDERCertificate(derCert, PR_FALSE, NULL);
- if (cert == NULL) return PR_FALSE;
+ if (cert == NULL)
+ return PR_FALSE;
isRoot = cert->isRoot;
- CERT_DestroyCertificate (cert);
+ CERT_DestroyCertificate(cert);
return isRoot;
}
CERTCompareValidityStatus
-CERT_CompareValidityTimes(CERTValidity* val_a, CERTValidity* val_b)
+CERT_CompareValidityTimes(CERTValidity *val_a, CERTValidity *val_b)
{
PRTime notBeforeA, notBeforeB, notAfterA, notAfterB;
- if (!val_a || !val_b)
- {
+ 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) ) {
+ 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)) {
+ if (LL_CMP(notBeforeA, >, notAfterA) || LL_CMP(notBeforeB, >, notAfterB)) {
PORT_SetError(SEC_ERROR_INVALID_TIME);
return certValidityUndetermined;
}
- if (LL_CMP(notAfterA,!=,notAfterB)) {
+ if (LL_CMP(notAfterA, !=, notAfterB)) {
/* one cert validity goes farther into the future, select it */
- return LL_CMP(notAfterA,<,notAfterB) ?
- certValidityChooseB : certValidityChooseA;
+ return LL_CMP(notAfterA, <, notAfterB) ? certValidityChooseB
+ : certValidityChooseA;
}
/* the two certs have the same expiration date */
- PORT_Assert(LL_CMP(notAfterA, == , notAfterB));
+ PORT_Assert(LL_CMP(notAfterA, ==, notAfterB));
/* do they also have the same start date ? */
- if (LL_CMP(notBeforeA,==,notBeforeB)) {
- return certValidityEqual;
+ if (LL_CMP(notBeforeA, ==, notBeforeB)) {
+ return certValidityEqual;
}
/* choose cert with the later start date */
- return LL_CMP(notBeforeA,<,notBeforeB) ?
- certValidityChooseB : certValidityChooseA;
+ return LL_CMP(notBeforeA, <, notBeforeB) ? certValidityChooseB
+ : certValidityChooseA;
}
/*
@@ -2216,52 +2171,52 @@ 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);
+ if (rv != SECSuccess) {
+ return (PR_FALSE);
}
-
+
rv = CERT_GetCertTimes(certb, &notBeforeB, &notAfterB);
- if ( rv != SECSuccess ) {
- return(PR_TRUE);
+ if (rv != SECSuccess) {
+ return (PR_TRUE);
}
newerbefore = PR_FALSE;
- if ( LL_CMP(notBeforeA, >, notBeforeB) ) {
- newerbefore = PR_TRUE;
+ if (LL_CMP(notBeforeA, >, notBeforeB)) {
+ newerbefore = PR_TRUE;
}
newerafter = PR_FALSE;
- if ( LL_CMP(notAfterA, >, notAfterB) ) {
- newerafter = PR_TRUE;
+ if (LL_CMP(notAfterA, >, notAfterB)) {
+ newerafter = PR_TRUE;
}
-
- if ( newerbefore && newerafter ) {
- return(PR_TRUE);
+
+ if (newerbefore && newerafter) {
+ return (PR_TRUE);
}
-
- if ( ( !newerbefore ) && ( !newerafter ) ) {
- return(PR_FALSE);
+
+ 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);
+ 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);
+ /* 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);
}
}
@@ -2269,17 +2224,17 @@ 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);
+ if (certs) {
+ for (i = 0; i < ncerts; i++) {
+ if (certs[i]) {
+ CERT_DestroyCertificate(certs[i]);
+ }
+ }
+
+ PORT_Free(certs);
}
-
+
return;
}
@@ -2289,23 +2244,23 @@ CERT_FixupEmailAddr(const char *emailAddr)
char *retaddr;
char *str;
- if ( emailAddr == NULL ) {
- return(NULL);
+ if (emailAddr == NULL) {
+ return (NULL);
}
-
+
/* copy the string */
str = retaddr = PORT_Strdup(emailAddr);
- if ( str == NULL ) {
- return(NULL);
+ if (str == NULL) {
+ return (NULL);
}
-
+
/* make it lower case */
- while ( *str ) {
- *str = tolower( *str );
- str++;
+ while (*str) {
+ *str = tolower(*str);
+ str++;
}
-
- return(retaddr);
+
+ return (retaddr);
}
/*
@@ -2318,67 +2273,67 @@ CERT_DecodeTrustString(CERTCertTrust *trust, const char *trusts)
unsigned int *pflags;
if (!trust) {
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- return SECFailure;
+ 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;
+ 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:
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- return SECFailure;
- }
+ 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:
+ PORT_SetError(SEC_ERROR_INVALID_ARGS);
+ return SECFailure;
+ }
}
return SECSuccess;
@@ -2388,26 +2343,25 @@ 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_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))
+ PORT_Strcat(trusts, "p");
if (flags & CERTDB_TRUSTED_CA)
- PORT_Strcat(trusts, "C");
+ PORT_Strcat(trusts, "C");
if (flags & CERTDB_TRUSTED_CLIENT_CA)
- PORT_Strcat(trusts, "T");
+ PORT_Strcat(trusts, "T");
if (flags & CERTDB_TRUSTED)
- PORT_Strcat(trusts, "P");
+ PORT_Strcat(trusts, "P");
if (flags & CERTDB_USER)
- PORT_Strcat(trusts, "u");
+ PORT_Strcat(trusts, "u");
if (flags & CERTDB_SEND_WARN)
- PORT_Strcat(trusts, "w");
+ PORT_Strcat(trusts, "w");
if (flags & CERTDB_INVISIBLE_CA)
- PORT_Strcat(trusts, "I");
+ PORT_Strcat(trusts, "I");
if (flags & CERTDB_GOVT_APPROVED_CA)
- PORT_Strcat(trusts, "G");
+ PORT_Strcat(trusts, "G");
return;
}
@@ -2419,96 +2373,93 @@ CERT_EncodeTrustString(CERTCertTrust *trust)
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);
+ 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);
+
+ return (retstr);
}
SECStatus
CERT_ImportCerts(CERTCertDBHandle *certdb, SECCertUsage usage,
- unsigned int ncerts, SECItem **derCerts,
- CERTCertificate ***retCerts, PRBool keepCerts,
- PRBool caOnly, char *nickname)
+ unsigned int ncerts, SECItem **derCerts,
+ CERTCertificate ***retCerts, PRBool keepCerts, PRBool caOnly,
+ char *nickname)
{
unsigned int i;
CERTCertificate **certs = NULL;
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;
+ 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]);
-
+ SECKEY_UpdateCertPQG(certs[i]);
+
isCA = CERT_IsCACert(certs[i], NULL);
- if ( isCA ) {
+ 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
+ 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.
- */
+ */
/* Bug 1192442 - propagate errors from these calls. */
- (void)CERT_AddTempCertToPerm(certs[i], canickname, NULL);
- } else {
- (void)CERT_AddTempCertToPerm(certs[i],
- nickname?nickname:canickname, NULL);
- }
+ (void)CERT_AddTempCertToPerm(certs[i], canickname, NULL);
+ } else {
+ (void)CERT_AddTempCertToPerm(
+ certs[i], nickname ? nickname : canickname, NULL);
+ }
PORT_Free(canickname);
- /* don't care if it fails - keep going */
- }
- }
+ /* don't care if it fails - keep going */
+ }
+ }
}
- if ( retCerts ) {
- *retCerts = certs;
+ if (retCerts) {
+ *retCerts = certs;
} else {
- if (certs) {
- CERT_DestroyCertArray(certs, fcerts);
- }
+ if (certs) {
+ CERT_DestroyCertArray(certs, fcerts);
+ }
}
return (fcerts || !ncerts) ? SECSuccess : SECFailure;
@@ -2523,29 +2474,29 @@ CERT_NewCertList(void)
{
PLArenaPool *arena = NULL;
CERTCertList *ret = NULL;
-
+
arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
- if ( arena == NULL ) {
- goto loser;
+ if (arena == NULL) {
+ goto loser;
}
-
+
ret = (CERTCertList *)PORT_ArenaZAlloc(arena, sizeof(CERTCertList));
- if ( ret == NULL ) {
- goto loser;
+ if (ret == NULL) {
+ goto loser;
}
-
+
ret->arena = arena;
-
+
PR_INIT_CLIST(&ret->list);
-
- return(ret);
+
+ return (ret);
loser:
- if ( arena != NULL ) {
- PORT_FreeArena(arena, PR_FALSE);
+ if (arena != NULL) {
+ PORT_FreeArena(arena, PR_FALSE);
}
-
- return(NULL);
+
+ return (NULL);
}
void
@@ -2553,14 +2504,14 @@ 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);
+ 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;
}
@@ -2572,27 +2523,26 @@ CERT_RemoveCertListNode(CERTCertListNode *node)
return;
}
-
SECStatus
-CERT_AddCertToListTailWithData(CERTCertList *certs,
- CERTCertificate *cert, void *appData)
+CERT_AddCertToListTailWithData(CERTCertList *certs, CERTCertificate *cert,
+ void *appData)
{
CERTCertListNode *node;
-
+
node = (CERTCertListNode *)PORT_ArenaZAlloc(certs->arena,
- sizeof(CERTCertListNode));
- if ( node == NULL ) {
- goto loser;
+ sizeof(CERTCertListNode));
+ if (node == NULL) {
+ goto loser;
}
-
+
PR_INSERT_BEFORE(&node->links, &certs->list);
/* certs->count++; */
node->cert = cert;
node->appData = appData;
- return(SECSuccess);
-
+ return (SECSuccess);
+
loser:
- return(SECFailure);
+ return (SECFailure);
}
SECStatus
@@ -2602,30 +2552,31 @@ CERT_AddCertToListTail(CERTCertList *certs, CERTCertificate *cert)
}
SECStatus
-CERT_AddCertToListHeadWithData(CERTCertList *certs,
- CERTCertificate *cert, void *appData)
+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);
+ if (head == NULL)
+ return CERT_AddCertToListTail(certs, cert);
node = (CERTCertListNode *)PORT_ArenaZAlloc(certs->arena,
- sizeof(CERTCertListNode));
- if ( node == NULL ) {
- goto loser;
+ sizeof(CERTCertListNode));
+ if (node == NULL) {
+ goto loser;
}
-
+
PR_INSERT_BEFORE(&node->links, &head->links);
/* certs->count++; */
node->cert = cert;
node->appData = appData;
- return(SECSuccess);
-
+ return (SECSuccess);
+
loser:
- return(SECFailure);
+ return (SECFailure);
}
SECStatus
@@ -2639,9 +2590,7 @@ CERT_AddCertToListHead(CERTCertList *certs, CERTCertificate *cert)
* Not valid certs are considered older than valid certs.
*/
PRBool
-CERT_SortCBValidity(CERTCertificate *certa,
- CERTCertificate *certb,
- void *arg)
+CERT_SortCBValidity(CERTCertificate *certa, CERTCertificate *certb, void *arg)
{
PRTime sorttime;
PRTime notBeforeA, notAfterA, notBeforeB, notAfterB;
@@ -2650,113 +2599,110 @@ CERT_SortCBValidity(CERTCertificate *certa,
PRBool aNotValid = PR_FALSE, bNotValid = PR_FALSE;
sorttime = *(PRTime *)arg;
-
+
rv = CERT_GetCertTimes(certa, &notBeforeA, &notAfterA);
- if ( rv != SECSuccess ) {
- return(PR_FALSE);
+ if (rv != SECSuccess) {
+ return (PR_FALSE);
}
-
+
rv = CERT_GetCertTimes(certb, &notBeforeB, &notAfterB);
- if ( rv != SECSuccess ) {
- return(PR_TRUE);
+ if (rv != SECSuccess) {
+ return (PR_TRUE);
}
newerbefore = PR_FALSE;
- if ( LL_CMP(notBeforeA, >, notBeforeB) ) {
- newerbefore = PR_TRUE;
+ if (LL_CMP(notBeforeA, >, notBeforeB)) {
+ newerbefore = PR_TRUE;
}
newerafter = PR_FALSE;
- if ( LL_CMP(notAfterA, >, notAfterB) ) {
- newerafter = PR_TRUE;
+ 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;
+ 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;
+ if (CERT_CheckCertValidTimes(certb, sorttime, PR_FALSE) !=
+ secCertTimeValid) {
+ bNotValid = PR_TRUE;
}
/* a is valid, b is not */
- if ( bNotValid && ( ! aNotValid ) ) {
- return(PR_TRUE);
+ if (bNotValid && (!aNotValid)) {
+ return (PR_TRUE);
}
/* b is valid, a is not */
- if ( aNotValid && ( ! bNotValid ) ) {
- return(PR_FALSE);
+ 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_TRUE);
}
-
- if ( ( !newerbefore ) && ( !newerafter ) ) {
- return(PR_FALSE);
+
+ if ((!newerbefore) && (!newerafter)) {
+ return (PR_FALSE);
}
- if ( newerbefore ) {
- /* cert A was issued after cert B, but expires sooner */
- return(PR_TRUE);
+ 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);
+ /* cert B was issued after cert A, but expires sooner */
+ return (PR_FALSE);
}
}
-
SECStatus
-CERT_AddCertToListSorted(CERTCertList *certs,
- CERTCertificate *cert,
- CERTSortCallback f,
- void *arg)
+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;
+ 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);
+
+ 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:
+done:
/* certs->count++; */
node->cert = cert;
- return(SECSuccess);
-
+ return (SECSuccess);
+
loser:
- return(SECFailure);
+ return (SECFailure);
}
/* This routine is here because pcertdb.c still has a call to it.
@@ -2769,74 +2715,75 @@ loser:
*/
SECStatus
CERT_FilterCertListByUsage(CERTCertList *certList, SECCertUsage usage,
- PRBool ca)
+ PRBool ca)
{
unsigned int requiredKeyUsage;
unsigned int requiredCertType;
CERTCertListNode *node, *savenode;
SECStatus rv;
-
- if (certList == NULL) goto loser;
+
+ if (certList == NULL)
+ goto loser;
rv = CERT_KeyUsageAndTypeForCertUsage(usage, ca, &requiredKeyUsage,
- &requiredCertType);
- if ( rv != SECSuccess ) {
- goto loser;
+ &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);
-
+
+ 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);
+ return (SECFailure);
}
-PRBool CERT_IsUserCert(CERTCertificate* cert)
+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 )) ) {
+ ((trust.sslFlags & CERTDB_USER) || (trust.emailFlags & CERTDB_USER) ||
+ (trust.objectSigningFlags & CERTDB_USER))) {
return PR_TRUE;
} else {
return PR_FALSE;
@@ -2854,21 +2801,21 @@ CERT_FilterCertListForUserCerts(CERTCertList *certList)
}
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);
- }
+
+ 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);
+ return (SECSuccess);
}
static PZLock *certRefCountLock = NULL;
@@ -2894,7 +2841,7 @@ void
CERT_UnlockCertRefCount(CERTCertificate *cert)
{
PORT_Assert(certRefCountLock != NULL);
-
+
#ifdef DEBUG
{
PRStatus prstat = PZ_Unlock(certRefCountLock);
@@ -2924,7 +2871,7 @@ CERT_LockCertTrust(const CERTCertificate *cert)
SECStatus
cert_InitLocks(void)
{
- if ( certRefCountLock == NULL ) {
+ if (certRefCountLock == NULL) {
certRefCountLock = PZ_NewLock(nssILockRefLock);
PORT_Assert(certRefCountLock != NULL);
if (!certRefCountLock) {
@@ -2932,7 +2879,7 @@ cert_InitLocks(void)
}
}
- if ( certTrustLock == NULL ) {
+ if (certTrustLock == NULL) {
certTrustLock = PZ_NewLock(nssILockCertDB);
PORT_Assert(certTrustLock != NULL);
if (!certTrustLock) {
@@ -2940,7 +2887,7 @@ cert_InitLocks(void)
certRefCountLock = NULL;
return SECFailure;
}
- }
+ }
return SECSuccess;
}
@@ -2975,7 +2922,7 @@ void
CERT_UnlockCertTrust(const CERTCertificate *cert)
{
PORT_Assert(certTrustLock != NULL);
-
+
#ifdef DEBUG
{
PRStatus prstat = PZ_Unlock(certTrustLock);
@@ -2986,14 +2933,13 @@ CERT_UnlockCertTrust(const CERTCertificate *cert)
#endif
}
-
/*
* Get the StatusConfig data for this handle
*/
CERTStatusConfig *
CERT_GetStatusConfig(CERTCertDBHandle *handle)
{
- return handle->statusConfig;
+ return handle->statusConfig;
}
/*
@@ -3003,8 +2949,8 @@ CERT_GetStatusConfig(CERTCertDBHandle *handle)
void
CERT_SetStatusConfig(CERTCertDBHandle *handle, CERTStatusConfig *statusConfig)
{
- PORT_Assert(handle->statusConfig == NULL);
- handle->statusConfig = statusConfig;
+ PORT_Assert(handle->statusConfig == NULL);
+ handle->statusConfig = statusConfig;
}
/*
@@ -3012,37 +2958,40 @@ CERT_SetStatusConfig(CERTCertDBHandle *handle, CERTStatusConfig *statusConfig)
*/
static PLHashTable *gSubjKeyIDHash = NULL;
-static PRLock *gSubjKeyIDLock = NULL;
+static PRLock *gSubjKeyIDLock = NULL;
static PLHashTable *gSubjKeyIDSlotCheckHash = NULL;
-static PRLock *gSubjKeyIDSlotCheckLock = NULL;
+static PRLock *gSubjKeyIDSlotCheckLock = NULL;
-static void *cert_AllocTable(void *pool, PRSize size)
+static void *
+cert_AllocTable(void *pool, PRSize size)
{
return PORT_Alloc(size);
}
-static void cert_FreeTable(void *pool, void *item)
+static void
+cert_FreeTable(void *pool, void *item)
{
PORT_Free(item);
}
-static PLHashEntry* cert_AllocEntry(void *pool, const void *key)
+static PLHashEntry *
+cert_AllocEntry(void *pool, const void *key)
{
return PORT_New(PLHashEntry);
}
-static void cert_FreeEntry(void *pool, PLHashEntry *he, PRUintn flag)
+static void
+cert_FreeEntry(void *pool, PLHashEntry *he, PRUintn flag)
{
- SECITEM_FreeItem((SECItem*)(he->value), PR_TRUE);
+ SECITEM_FreeItem((SECItem *)(he->value), PR_TRUE);
if (flag == HT_FREE_ENTRY) {
- SECITEM_FreeItem((SECItem*)(he->key), PR_TRUE);
+ SECITEM_FreeItem((SECItem *)(he->key), PR_TRUE);
PORT_Free(he);
}
}
-static PLHashAllocOps cert_AllocOps = {
- cert_AllocTable, cert_FreeTable, cert_AllocEntry, cert_FreeEntry
-};
+static PLHashAllocOps cert_AllocOps = { cert_AllocTable, cert_FreeTable,
+ cert_AllocEntry, cert_FreeEntry };
SECStatus
cert_CreateSubjectKeyIDSlotCheckHash(void)
@@ -3051,10 +3000,9 @@ 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);
+ gSubjKeyIDSlotCheckHash =
+ PL_NewHashTable(0, SECITEM_Hash, SECITEM_HashCompare,
+ SECITEM_HashCompare, &cert_AllocOps, NULL);
if (!gSubjKeyIDSlotCheckHash) {
PORT_SetError(SEC_ERROR_NO_MEMORY);
return SECFailure;
@@ -3073,8 +3021,7 @@ SECStatus
cert_CreateSubjectKeyIDHashTable(void)
{
gSubjKeyIDHash = PL_NewHashTable(0, SECITEM_Hash, SECITEM_HashCompare,
- SECITEM_HashCompare,
- &cert_AllocOps, NULL);
+ SECITEM_HashCompare, &cert_AllocOps, NULL);
if (!gSubjKeyIDHash) {
PORT_SetError(SEC_ERROR_NO_MEMORY);
return SECFailure;
@@ -3088,8 +3035,8 @@ cert_CreateSubjectKeyIDHashTable(void)
}
/* initialize the companion hash (for remembering slot series) */
if (cert_CreateSubjectKeyIDSlotCheckHash() != SECSuccess) {
- cert_DestroySubjectKeyIDHashTable();
- return SECFailure;
+ cert_DestroySubjectKeyIDHashTable();
+ return SECFailure;
}
return SECSuccess;
}
@@ -3101,8 +3048,8 @@ cert_AddSubjectKeyIDMapping(SECItem *subjKeyID, CERTCertificate *cert)
SECStatus rv = SECFailure;
if (!gSubjKeyIDLock) {
- /* If one is created, then both are there. So only check for one. */
- return SECFailure;
+ /* If one is created, then both are there. So only check for one. */
+ return SECFailure;
}
newVal = SECITEM_DupItem(&cert->derCert);
@@ -3118,18 +3065,18 @@ cert_AddSubjectKeyIDMapping(SECItem *subjKeyID, CERTCertificate *cert)
}
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
+ /* 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);
+ oldVal = (SECItem *)PL_HashTableLookup(gSubjKeyIDHash, subjKeyID);
if (oldVal) {
PL_HashTableRemove(gSubjKeyIDHash, subjKeyID);
}
- rv = (PL_HashTableAdd(gSubjKeyIDHash, newKeyID, newVal)) ? SECSuccess :
- SECFailure;
+ rv = (PL_HashTableAdd(gSubjKeyIDHash, newKeyID, newVal)) ? SECSuccess
+ : SECFailure;
PR_Unlock(gSubjKeyIDLock);
done:
return rv;
@@ -3143,8 +3090,8 @@ cert_RemoveSubjectKeyIDMapping(SECItem *subjKeyID)
return SECFailure;
PR_Lock(gSubjKeyIDLock);
- rv = (PL_HashTableRemove(gSubjKeyIDHash, subjKeyID)) ? SECSuccess :
- SECFailure;
+ rv = (PL_HashTableRemove(gSubjKeyIDHash, subjKeyID)) ? SECSuccess
+ : SECFailure;
PR_Unlock(gSubjKeyIDLock);
return rv;
}
@@ -3156,12 +3103,12 @@ cert_UpdateSubjectKeyIDSlotCheck(SECItem *slotid, int series)
SECStatus rv = SECFailure;
if (!gSubjKeyIDSlotCheckLock) {
- return rv;
+ return rv;
}
newSlotid = SECITEM_DupItem(slotid);
newSeries = SECITEM_AllocItem(NULL, NULL, sizeof(int));
- if (!newSlotid || !newSeries ) {
+ if (!newSlotid || !newSeries) {
PORT_SetError(SEC_ERROR_NO_MEMORY);
goto loser;
}
@@ -3170,17 +3117,18 @@ cert_UpdateSubjectKeyIDSlotCheck(SECItem *slotid, int series)
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)
- */
+ /*
+ * 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;
+ rv = (PL_HashTableAdd(gSubjKeyIDSlotCheckHash, newSlotid, newSeries))
+ ? SECSuccess
+ : SECFailure;
PR_Unlock(gSubjKeyIDSlotCheckLock);
if (rv == SECSuccess) {
- return rv;
+ return rv;
}
loser:
@@ -3200,23 +3148,23 @@ cert_SubjectKeyIDSlotCheckSeries(SECItem *slotid)
int series;
if (!gSubjKeyIDSlotCheckLock) {
- PORT_SetError(SEC_ERROR_NOT_INITIALIZED);
- return -1;
+ 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 */
+ /* getting a null series just means we haven't registered one yet,
+ * just return 0 */
if (seriesItem == NULL) {
- return 0;
+ 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_SetError(SEC_ERROR_LIBRARY_FAILURE);
+ return -1;
}
PORT_Memcpy(&series, seriesItem->data, sizeof(int));
return series;
@@ -3251,16 +3199,16 @@ cert_DestroySubjectKeyIDHashTable(void)
return SECSuccess;
}
-SECItem*
+SECItem *
cert_FindDERCertBySubjectKeyID(SECItem *subjKeyID)
{
- SECItem *val;
-
+ SECItem *val;
+
if (!gSubjKeyIDLock)
return NULL;
PR_Lock(gSubjKeyIDLock);
- val = (SECItem*)PL_HashTableLookup(gSubjKeyIDHash, subjKeyID);
+ val = (SECItem *)PL_HashTableLookup(gSubjKeyIDHash, subjKeyID);
if (val) {
val = SECITEM_DupItem(val);
}
@@ -3268,7 +3216,7 @@ cert_FindDERCertBySubjectKeyID(SECItem *subjKeyID)
return val;
}
-CERTCertificate*
+CERTCertificate *
CERT_FindCertBySubjectKeyID(CERTCertDBHandle *handle, SECItem *subjKeyID)
{
CERTCertificate *cert = NULL;
diff --git a/nss/lib/certdb/certdb.gyp b/nss/lib/certdb/certdb.gyp
new file mode 100644
index 0000000..673d56d
--- /dev/null
+++ b/nss/lib/certdb/certdb.gyp
@@ -0,0 +1,34 @@
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+{
+ 'includes': [
+ '../../coreconf/config.gypi'
+ ],
+ 'targets': [
+ {
+ 'target_name': 'certdb',
+ 'type': 'static_library',
+ 'sources': [
+ 'alg1485.c',
+ 'certdb.c',
+ 'certv3.c',
+ 'certxutl.c',
+ 'crl.c',
+ 'genname.c',
+ 'polcyxtn.c',
+ 'secname.c',
+ 'stanpcertdb.c',
+ 'xauthkid.c',
+ 'xbsconst.c',
+ 'xconst.c'
+ ],
+ 'dependencies': [
+ '<(DEPTH)/exports.gyp:nss_exports'
+ ]
+ }
+ ],
+ 'variables': {
+ 'module': 'nss'
+ }
+} \ No newline at end of file
diff --git a/nss/lib/certdb/certdb.h b/nss/lib/certdb/certdb.h
index d358dfd..53d8a39 100644
--- a/nss/lib/certdb/certdb.h
+++ b/nss/lib/certdb/certdb.h
@@ -5,18 +5,17 @@
#ifndef _CERTDB_H_
#define _CERTDB_H_
-
/* common flags for all types of certificates */
-#define CERTDB_TERMINAL_RECORD (1u<<0)
-#define CERTDB_TRUSTED (1u<<1)
-#define CERTDB_SEND_WARN (1u<<2)
-#define CERTDB_VALID_CA (1u<<3)
-#define CERTDB_TRUSTED_CA (1u<<4) /* trusted for issuing server certs */
-#define CERTDB_NS_TRUSTED_CA (1u<<5)
-#define CERTDB_USER (1u<<6)
-#define CERTDB_TRUSTED_CLIENT_CA (1u<<7) /* trusted for issuing client certs */
-#define CERTDB_INVISIBLE_CA (1u<<8) /* don't show in UI */
-#define CERTDB_GOVT_APPROVED_CA (1u<<9) /* can do strong crypto in export ver */
+#define CERTDB_TERMINAL_RECORD (1u << 0)
+#define CERTDB_TRUSTED (1u << 1)
+#define CERTDB_SEND_WARN (1u << 2)
+#define CERTDB_VALID_CA (1u << 3)
+#define CERTDB_TRUSTED_CA (1u << 4) /* trusted for issuing server certs */
+#define CERTDB_NS_TRUSTED_CA (1u << 5)
+#define CERTDB_USER (1u << 6)
+#define CERTDB_TRUSTED_CLIENT_CA (1u << 7) /* trusted for issuing client certs */
+#define CERTDB_INVISIBLE_CA (1u << 8) /* don't show in UI */
+#define CERTDB_GOVT_APPROVED_CA (1u << 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
@@ -26,54 +25,48 @@
#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")));
+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)
+#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
+#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_FindCrlByKey(CERTCertDBHandle *handle, SECItem *crlKey,
+ int type);
-CERTSignedCrl *
-SEC_FindCrlByDERCert(CERTCertDBHandle *handle, SECItem *derCrl, int type);
+CERTSignedCrl *SEC_FindCrlByName(CERTCertDBHandle *handle, SECItem *crlKey,
+ int type);
-PRBool
-SEC_CertNicknameConflict(const char *nickname, const SECItem *derSubject,
- CERTCertDBHandle *handle);
-CERTSignedCrl *
-SEC_NewCrl(CERTCertDBHandle *handle, char *url, SECItem *derCrl, int type);
+CERTSignedCrl *SEC_FindCrlByDERCert(CERTCertDBHandle *handle, SECItem *derCrl,
+ int type);
-SECStatus
-SEC_DeletePermCRL(CERTSignedCrl *crl);
+PRBool SEC_CertNicknameConflict(const char *nickname, const 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_LookupCrls(CERTCertDBHandle *handle, CERTCrlHeadNode **nodes,
+ int type);
-SECStatus
-SEC_DestroyCrl(CERTSignedCrl *crl);
+SECStatus SEC_DestroyCrl(CERTSignedCrl *crl);
-CERTSignedCrl* SEC_DupCrl(CERTSignedCrl* acrl);
+CERTSignedCrl *SEC_DupCrl(CERTSignedCrl *acrl);
-SECStatus
-CERT_AddTempCertToPerm(CERTCertificate *cert, char *nickname,
- CERTCertTrust *trust);
+SECStatus CERT_AddTempCertToPerm(CERTCertificate *cert, char *nickname,
+ CERTCertTrust *trust);
SECStatus SEC_DeletePermCertificate(CERTCertificate *cert);
-PRBool
-SEC_CrlIsNewer(CERTCrl *inNew, CERTCrl *old);
+PRBool SEC_CrlIsNewer(CERTCrl *inNew, CERTCrl *old);
/*
** Extract the validity times from a CRL
@@ -81,8 +74,7 @@ SEC_CrlIsNewer(CERTCrl *inNew, CERTCrl *old);
** "notBefore" is the start of the validity period (last update)
** "notAfter" is the end of the validity period (next update)
*/
-SECStatus
-SEC_GetCrlTimes(CERTCrl *crl, PRTime *notBefore, PRTime *notAfter);
+SECStatus SEC_GetCrlTimes(CERTCrl *crl, PRTime *notBefore, PRTime *notAfter);
/*
** Check the validity times of a crl vs. time 't', allowing
@@ -90,8 +82,7 @@ SEC_GetCrlTimes(CERTCrl *crl, PRTime *notBefore, PRTime *notAfter);
** "crl" is the certificate to be checked
** "t" is the time to check against
*/
-SECCertTimeValidity
-SEC_CheckCrlTimes(CERTCrl *crl, PRTime t);
+SECCertTimeValidity SEC_CheckCrlTimes(CERTCrl *crl, PRTime t);
SEC_END_PROTOS
diff --git a/nss/lib/certdb/certi.h b/nss/lib/certdb/certi.h
index ff7a7b8..1cdf4b8 100644
--- a/nss/lib/certdb/certi.h
+++ b/nss/lib/certdb/certi.h
@@ -38,8 +38,7 @@ struct OpaqueCRLFieldsStr {
typedef struct PreAllocatorStr PreAllocator;
-struct PreAllocatorStr
-{
+struct PreAllocatorStr {
PRSize len;
void* data;
PRSize used;
@@ -56,32 +55,31 @@ struct CRLEntryCacheStr {
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_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 */
+#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 */
+ 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 */
+ 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;
@@ -98,11 +96,11 @@ struct CachedCrlStr {
*/
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 */
+ 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
@@ -116,15 +114,15 @@ struct CRLDPCacheStr {
#else
PRLock* lock;
#endif
- SECItem *issuerDERCert; /* issuer DER cert. Don't hold a reference
- to the actual cert so the trust can be
- updated on the cert automatically.
- XXX there may be multiple issuer certs,
- with different validity dates. Also
- need to deal with SKID/AKID . See
- bugzilla 217387, 233118 */
+ SECItem* issuerDERCert; /* issuer DER cert. Don't hold a reference
+ to the actual cert so the trust can be
+ updated on the cert automatically.
+ XXX there may be multiple issuer certs,
+ with different validity dates. Also
+ need to deal with SKID/AKID . See
+ bugzilla 217387, 233118 */
- CERTCertDBHandle *dbHandle;
+ CERTCertDBHandle* dbHandle;
SECItem* subject; /* DER of issuer subject */
SECItem* distributionPoint; /* DER of distribution point. This may be
@@ -133,31 +131,31 @@ struct CRLDPCacheStr {
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 */
+ 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 */
+ 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 */
+ 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
@@ -168,7 +166,7 @@ struct CRLDPCacheStr {
*/
struct CRLIssuerCacheStr {
- SECItem* subject; /* DER of issuer subject */
+ SECItem* subject; /* DER of issuer subject */
CRLDPCache* dpp;
};
@@ -194,46 +192,40 @@ SECStatus ShutdownCRLCache(void);
** null-terminated strings, terminated by a zero-length string.
** This function is intended to be internal to NSS.
*/
-extern char * cert_GetCertificateEmailAddresses(CERTCertificate *cert);
+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_CreateSubjectKeyIDHashTable(void);
-SECStatus
-cert_AddSubjectKeyIDMapping(SECItem *subjKeyID, CERTCertificate *cert);
+SECStatus cert_AddSubjectKeyIDMapping(SECItem* subjKeyID,
+ CERTCertificate* cert);
-SECStatus
-cert_UpdateSubjectKeyIDSlotCheck(SECItem *slotid, int series);
+SECStatus cert_UpdateSubjectKeyIDSlotCheck(SECItem* slotid, int series);
-int
-cert_SubjectKeyIDSlotCheckSeries(SECItem *slotid);
+int cert_SubjectKeyIDSlotCheckSeries(SECItem* slotid);
/*
* Call this function to remove an entry from the mapping table.
*/
-SECStatus
-cert_RemoveSubjectKeyIDMapping(SECItem *subjKeyID);
+SECStatus cert_RemoveSubjectKeyIDMapping(SECItem* subjKeyID);
-SECStatus
-cert_DestroySubjectKeyIDHashTable(void);
+SECStatus cert_DestroySubjectKeyIDHashTable(void);
-SECItem*
-cert_FindDERCertBySubjectKeyID(SECItem *subjKeyID);
+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(PLArenaPool *pool,
- const SECItem * OID, const SECItem * value);
+extern CERTAVA* CERT_CreateAVAFromRaw(PLArenaPool* pool, const SECItem* OID,
+ const SECItem* value);
/* Make an AVA from binary input specified by SECItem */
-extern CERTAVA * CERT_CreateAVAFromSECItem(PLArenaPool *arena, SECOidTag kind,
- int valueType, SECItem *value);
+extern CERTAVA* CERT_CreateAVAFromSECItem(PLArenaPool* arena, SECOidTag kind,
+ int valueType, SECItem* value);
/*
* get a DPCache object for the given issuer subject and dp
@@ -260,10 +252,11 @@ void CERT_MapStanError();
/* Like CERT_VerifyCert, except with an additional argument, flags. The
* flags are defined immediately below.
*/
-SECStatus
-cert_VerifyCertWithFlags(CERTCertDBHandle *handle, CERTCertificate *cert,
- PRBool checkSig, SECCertUsage certUsage, PRTime t,
- PRUint32 flags, void *wincx, CERTVerifyLog *log);
+SECStatus cert_VerifyCertWithFlags(CERTCertDBHandle* handle,
+ CERTCertificate* cert, PRBool checkSig,
+ SECCertUsage certUsage, PRTime t,
+ PRUint32 flags, void* wincx,
+ CERTVerifyLog* log);
/* Use the default settings.
* cert_VerifyCertWithFlags(..., CERT_VERIFYCERT_USE_DEFAULTS, ...) is
@@ -281,15 +274,10 @@ cert_VerifyCertWithFlags(CERTCertDBHandle *handle, CERTCertificate *cert,
/* 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_VerifyCertChainPkix(CERTCertificate* cert, PRBool checkSig,
+ SECCertUsage requiredUsage, PRTime time,
+ void* wincx, CERTVerifyLog* log,
+ PRBool* sigError, PRBool* revoked);
SECStatus cert_InitLocks(void);
@@ -298,17 +286,16 @@ SECStatus cert_DestroyLocks(void);
/*
* fill in nsCertType field of the cert based on the cert extension
*/
-extern SECStatus cert_GetCertType(CERTCertificate *cert);
+extern SECStatus cert_GetCertType(CERTCertificate* cert);
/*
- * compute and return the value of nsCertType for cert, but do not
+ * compute and return the value of nsCertType for cert, but do not
* update the CERTCertificate.
*/
-extern PRUint32 cert_ComputeCertType(CERTCertificate *cert);
+extern PRUint32 cert_ComputeCertType(CERTCertificate* cert);
-void cert_AddToVerifyLog(CERTVerifyLog *log,CERTCertificate *cert,
- long errorCode, unsigned int depth,
- void *arg);
+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.
*
@@ -323,7 +310,7 @@ void cert_AddToVerifyLog(CERTVerifyLog *log,CERTCertificate *cert,
* 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);
@@ -336,15 +323,15 @@ struct NamedCRLCacheStr {
* and read by cert_FindCRLByGeneralName */
struct NamedCRLCacheEntryStr {
SECItem* canonicalizedName;
- SECItem* crl; /* DER, kept only if CRL
- * is successfully cached */
+ 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 */
+ PRBool badDER; /* ASN.1 error */
+ PRBool dupe; /* matching DER CRL already in CRL cache */
+ PRBool unsupported; /* IDP, delta, any other reason */
};
typedef enum {
@@ -355,12 +342,12 @@ typedef enum {
/* 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_CheckCertRevocationStatus(CERTCertificate* cert,
+ CERTCertificate* issuer,
+ const SECItem* dp, PRTime t,
+ void* wincx,
+ CERTRevocationStatus* revStatus,
+ CERTCRLEntryReasonCode* revReason);
SECStatus cert_AcquireNamedCRLCache(NamedCRLCache** returned);
@@ -374,26 +361,21 @@ SECStatus cert_FindCRLByGeneralName(NamedCRLCache* ncc,
SECStatus cert_ReleaseNamedCRLCache(NamedCRLCache* ncc);
/* This is private for now. Maybe shoule be public. */
-CERTGeneralName *
-cert_GetSubjectAltNameList(const CERTCertificate *cert, PLArenaPool *arena);
+CERTGeneralName* cert_GetSubjectAltNameList(const CERTCertificate* cert,
+ PLArenaPool* arena);
/* Count DNS names and IP addresses in a list of GeneralNames */
-PRUint32
-cert_CountDNSPatterns(CERTGeneralName *firstName);
+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
+ * 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
+ * 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);
+SECStatus cert_CheckLeafTrust(CERTCertificate* cert, SECCertUsage usage,
+ unsigned int* failedFlags, PRBool* isTrusted);
#endif /* _CERTI_H_ */
-
diff --git a/nss/lib/certdb/certt.h b/nss/lib/certdb/certt.h
index d8b559c..797f9f5 100644
--- a/nss/lib/certdb/certt.h
+++ b/nss/lib/certdb/certt.h
@@ -23,49 +23,49 @@ 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;
+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;
@@ -150,10 +150,13 @@ typedef enum SECTrustTypeEnum {
trustTypeNone = 3
} SECTrustType;
-#define SEC_GET_TRUST_FLAGS(trust,type) \
- (((type)==trustSSL)?((trust)->sslFlags): \
- (((type)==trustEmail)?((trust)->emailFlags): \
- (((type)==trustObjectSigning)?((trust)->objectSigningFlags):0)))
+#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
@@ -195,12 +198,12 @@ struct CERTCertificateStr {
/* 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 */
+ 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;
@@ -213,21 +216,21 @@ struct CERTCertificateStr {
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 */
+ 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 */
+ 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
@@ -238,7 +241,7 @@ struct CERTCertificateStr {
PRBool istemp;
char *nickname;
char *dbnickname;
- struct NSSCertificateStr *nssCertificate; /* This is Stan stuff. */
+ struct NSSCertificateStr *nssCertificate; /* This is Stan stuff. */
CERTCertTrust *trust;
/* the reference count is modified whenever someone looks up, dups
@@ -255,8 +258,8 @@ struct CERTCertificateStr {
/* 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 */
+ 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.
@@ -264,33 +267,33 @@ struct CERTCertificateStr {
* data structure. They are only used by the browser right now.
*/
union {
- void* apointer; /* was struct SECSocketNode* authsocketlist */
+ void *apointer; /* was struct SECSocketNode* authsocketlist */
struct {
- unsigned int hasUnsupportedCriticalExt :1;
+ 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 */
+ 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_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 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
+#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;
@@ -318,15 +321,14 @@ struct CERTCertificateRequestStr {
CERTSubjectPublicKeyInfo subjectPublicKeyInfo;
CERTAttribute **attributes;
};
-#define SEC_CERTIFICATE_REQUEST_VERSION 0 /* what we *create* */
-
+#define SEC_CERTIFICATE_REQUEST_VERSION 0 /* what we *create* */
/*
** A certificate list object.
*/
struct CERTCertificateListStr {
SECItem *certs;
- int len; /* number of certs */
+ int len; /* number of certs */
PLArenaPool *arena;
};
@@ -344,13 +346,13 @@ struct CERTCertListStr {
#define CERT_LIST_HEAD(l) ((CERTCertListNode *)PR_LIST_HEAD(&l->list))
#define CERT_LIST_TAIL(l) ((CERTCertListNode *)PR_LIST_TAIL(&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_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;
+ CERTCertExtension **extensions;
};
struct CERTCrlStr {
@@ -360,18 +362,18 @@ struct CERTCrlStr {
SECItem derName;
CERTName name;
SECItem lastUpdate;
- SECItem nextUpdate; /* optional for x.509 CRL */
+ SECItem nextUpdate; /* optional for x.509 CRL */
CERTCrlEntry **entries;
- CERTCertExtension **extensions;
+ 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
- */
+ 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 {
@@ -383,15 +385,14 @@ struct CERTSignedCrlStr {
PRBool istemp;
int referenceCount;
CERTCertDBHandle *dbhandle;
- CERTSignedData signatureWrap; /* XXX */
+ CERTSignedData signatureWrap; /* XXX */
char *url;
SECItem *derCrl;
PK11SlotInfo *slot;
CK_OBJECT_HANDLE pkcs11ID;
- void* opaque; /* do not touch */
+ void *opaque; /* do not touch */
};
-
struct CERTCrlHeadNodeStr {
PLArenaPool *arena;
CERTCertDBHandle *dbhandle;
@@ -399,46 +400,41 @@ struct CERTCrlHeadNodeStr {
CERTCrlNode *last;
};
-
struct CERTCrlNodeStr {
CERTCrlNode *next;
- int type;
+ int type;
CERTSignedCrl *crl;
};
-
/*
* Array of X.500 Distinguished Names
*/
struct CERTDistNamesStr {
PLArenaPool *arena;
int nnames;
- SECItem *names;
+ 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 )
+#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,
@@ -456,19 +452,19 @@ typedef enum SECCertUsageEnum {
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 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
@@ -498,9 +494,8 @@ typedef enum SECCertTimeValidityEnum {
* CERT_CompareValidityTimes.
*/
-typedef enum CERTCompareValidityStatusEnum
-{
- certValidityUndetermined = 0, /* the function is unable to select one cert
+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 */
@@ -512,10 +507,10 @@ typedef enum CERTCompareValidityStatusEnum
*/
/* 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
+#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;
@@ -532,24 +527,19 @@ struct CERTIssuerAndSNStr {
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)
+#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.
@@ -565,40 +555,40 @@ struct CERTIssuerAndSNStr {
/* 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!*/
+#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
- */
+* 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.
- */
+ 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 */
+#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 */
+#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 {
@@ -628,23 +618,20 @@ typedef enum CERTGeneralNameTypeEnum {
certRegisterID = 9
} CERTGeneralNameType;
-
typedef struct OtherNameStr {
- SECItem name;
- SECItem oid;
-}OtherName;
-
-
+ SECItem name;
+ SECItem oid;
+} OtherName;
struct CERTGeneralNameStr {
- CERTGeneralNameType type; /* name type */
+ 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 */
+ 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;
};
@@ -657,22 +644,20 @@ struct CERTGeneralNameListStr {
};
struct CERTNameConstraintStr {
- CERTGeneralName name;
- SECItem DERName;
- SECItem min;
- SECItem max;
- PRCList l;
+ CERTGeneralName name;
+ SECItem DERName;
+ SECItem min;
+ SECItem max;
+ PRCList l;
};
-
struct CERTNameConstraintsStr {
- CERTNameConstraint *permited;
- CERTNameConstraint *excluded;
- SECItem **DERPermited;
- SECItem **DERExcluded;
+ CERTNameConstraint *permited;
+ CERTNameConstraint *excluded;
+ SECItem **DERPermited;
+ SECItem **DERExcluded;
};
-
/* Private Key Usage Period extension struct. */
struct CERTPrivKeyUsagePeriodStr {
SECItem notBefore;
@@ -684,14 +669,14 @@ struct CERTPrivKeyUsagePeriodStr {
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.
- */
+ 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 */
@@ -700,19 +685,19 @@ struct CERTAuthKeyIDStr {
* defined the types of CRL Distribution points
*/
typedef enum DistributionPointTypesEnum {
- generalName = 1, /* only support this for now */
+ generalName = 1, /* only support this for now */
relativeDistinguishedName = 2
} DistributionPointTypes;
struct CRLDistributionPointStr {
DistributionPointTypes distPointType;
union {
- CERTGeneralName *fullName;
- CERTRDN relativeName;
+ CERTGeneralName *fullName;
+ CERTRDN relativeName;
} distPoint;
SECItem reasons;
CERTGeneralName *crlIssuer;
-
+
/* Reserved for internal use only*/
SECItem derDistPoint;
SECItem derRelativeName;
@@ -731,15 +716,14 @@ struct CERTCrlDistributionPointsStr {
* 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 */
+ 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;
@@ -747,36 +731,32 @@ struct CERTVerifyLogStr {
struct CERTVerifyLogNodeStr *tail;
};
-
struct CERTOKDomainNameStr {
CERTOKDomainName *next;
- char name[1]; /* actual length may be longer. */
+ char *name;
};
+typedef SECStatus(PR_CALLBACK *CERTStatusChecker)(CERTCertDBHandle *handle,
+ CERTCertificate *cert,
+ PRTime time, void *pwArg);
-typedef SECStatus (PR_CALLBACK *CERTStatusChecker) (CERTCertDBHandle *handle,
- CERTCertificate *cert,
- PRTime time,
- void *pwArg);
-
-typedef SECStatus (PR_CALLBACK *CERTStatusDestroy) (CERTStatusConfig *handle);
+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 */
+ 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 */
+ 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);
+typedef char *(*CERTDBNameFunc)(void *arg, int dbVersion);
/*
* types of cert packages that we can decode
@@ -875,10 +855,8 @@ typedef struct {
* to indicate an fatal error that will cause path validation to fail
* immediately.
*/
-typedef SECStatus (*CERTChainVerifyCallbackFunc)
- (void *isChainValidArg,
- const CERTCertList *currentChain,
- PRBool *chainOK);
+typedef SECStatus (*CERTChainVerifyCallbackFunc)(
+ void *isChainValidArg, const CERTCertList *currentChain, PRBool *chainOK);
/*
* Note: If extending this structure, it will be necessary to change the
@@ -895,87 +873,91 @@ typedef struct {
*/
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 */
+ 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;
/*
@@ -987,39 +969,39 @@ typedef enum {
* 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 */
+ 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;
@@ -1029,7 +1011,6 @@ typedef enum {
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:
@@ -1042,8 +1023,8 @@ typedef enum {
* 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 0UL
-#define CERT_REV_M_TEST_USING_THIS_METHOD 1UL
+#define CERT_REV_M_DO_NOT_TEST_USING_THIS_METHOD 0UL
+#define CERT_REV_M_TEST_USING_THIS_METHOD 1UL
/*
* Whether or not NSS is allowed to attempt to fetch fresh information
@@ -1051,8 +1032,8 @@ typedef enum {
* (Although fetching will never happen if fresh information for the
* method is already locally available.)
*/
-#define CERT_REV_M_ALLOW_NETWORK_FETCHING 0UL
-#define CERT_REV_M_FORBID_NETWORK_FETCHING 2UL
+#define CERT_REV_M_ALLOW_NETWORK_FETCHING 0UL
+#define CERT_REV_M_FORBID_NETWORK_FETCHING 2UL
/*
* Example for an implicit default source:
@@ -1060,14 +1041,14 @@ typedef enum {
* IGNORE means:
* ignore the implicit default source, whether it's configured or not.
* ALLOW means:
- * if an implicit default source is configured,
+ * 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)
+ * then we continue to use what's available (or not available)
* in the certs.
- */
-#define CERT_REV_M_ALLOW_IMPLICIT_DEFAULT_SOURCE 0UL
-#define CERT_REV_M_IGNORE_IMPLICIT_DEFAULT_SOURCE 4UL
+ */
+#define CERT_REV_M_ALLOW_IMPLICIT_DEFAULT_SOURCE 0UL
+#define CERT_REV_M_IGNORE_IMPLICIT_DEFAULT_SOURCE 4UL
/*
* Defines the behavior if no fresh information is available,
@@ -1075,14 +1056,14 @@ typedef enum {
* 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
+ * 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 0UL
-#define CERT_REV_M_REQUIRE_INFO_ON_MISSING_SOURCE 8UL
+#define CERT_REV_M_SKIP_TEST_ON_MISSING_SOURCE 0UL
+#define CERT_REV_M_REQUIRE_INFO_ON_MISSING_SOURCE 8UL
/*
* Defines the behavior if we are unable to obtain fresh information.
@@ -1091,8 +1072,8 @@ typedef enum {
* FAIL means:
* Return "cert revoked".
*/
-#define CERT_REV_M_IGNORE_MISSING_FRESH_INFO 0UL
-#define CERT_REV_M_FAIL_ON_MISSING_FRESH_INFO 16UL
+#define CERT_REV_M_IGNORE_MISSING_FRESH_INFO 0UL
+#define CERT_REV_M_FAIL_ON_MISSING_FRESH_INFO 16UL
/*
* What should happen if we were able to find fresh information using
@@ -1104,8 +1085,8 @@ typedef enum {
* We will continue and test the next allowed
* specified method.
*/
-#define CERT_REV_M_STOP_TESTING_ON_FRESH_INFO 0UL
-#define CERT_REV_M_CONTINUE_TESTING_ON_FRESH_INFO 32UL
+#define CERT_REV_M_STOP_TESTING_ON_FRESH_INFO 0UL
+#define CERT_REV_M_CONTINUE_TESTING_ON_FRESH_INFO 32UL
/* When this flag is used, libpkix will never attempt to use the GET HTTP
* method for OCSP requests; it will always use POST.
@@ -1131,8 +1112,8 @@ typedef enum {
* 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 0UL
-#define CERT_REV_MI_TEST_ALL_LOCAL_INFORMATION_FIRST 1UL
+#define CERT_REV_MI_TEST_EACH_METHOD_SEPARATELY 0UL
+#define CERT_REV_MI_TEST_ALL_LOCAL_INFORMATION_FIRST 1UL
/*
* Use this flag to specify that it's necessary that fresh information
@@ -1147,10 +1128,9 @@ typedef enum {
* This setting overrides the CERT_REV_M_FAIL_ON_MISSING_FRESH_INFO
* flag on all methods.
*/
-#define CERT_REV_MI_NO_OVERALL_INFO_REQUIREMENT 0UL
+#define CERT_REV_MI_NO_OVERALL_INFO_REQUIREMENT 0UL
#define CERT_REV_MI_REQUIRE_SOME_FRESH_INFO_AVAILABLE 2UL
-
typedef struct {
/*
* The size of the array that cert_rev_flags_per_method points to,
@@ -1163,20 +1143,20 @@ typedef struct {
* 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
+ * 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
+ * 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
+ * This is equivalent to the size of the array that
* preferred_methods points to.
* It's allowed to set this value to zero,
* then NSS will decide which methods to prefer.
@@ -1207,50 +1187,49 @@ typedef struct {
typedef struct CERTValParamInValueStr {
union {
- PRBool b;
- PRInt32 i;
+ PRBool b;
+ PRInt32 i;
PRUint32 ui;
- PRInt64 l;
+ PRInt64 l;
PRUint64 ul;
PRTime time;
} scalar;
union {
- const void* p;
- const char* s;
- const CERTCertificate* cert;
+ const void *p;
+ const char *s;
+ const CERTCertificate *cert;
const CERTCertList *chain;
const CERTRevocationFlags *revocation;
const CERTChainVerifyCallback *chainVerifyCallback;
} pointer;
union {
- const PRInt32 *pi;
+ const PRInt32 *pi;
const PRUint32 *pui;
- const PRInt64 *pl;
+ const PRInt64 *pl;
const PRUint64 *pul;
const SECOidTag *oids;
} array;
int arraySize;
} CERTValParamInValue;
-
typedef struct CERTValParamOutValueStr {
union {
- PRBool b;
- PRInt32 i;
+ PRBool b;
+ PRInt32 i;
PRUint32 ui;
- PRInt64 l;
+ PRInt64 l;
PRUint64 ul;
SECCertificateUsage usages;
} scalar;
union {
- void* p;
- char* s;
+ void *p;
+ char *s;
CERTVerifyLog *log;
- CERTCertificate* cert;
+ CERTCertificate *cert;
CERTCertList *chain;
} pointer;
union {
- void *p;
+ void *p;
SECOidTag *oids;
} array;
int arraySize;
@@ -1270,35 +1249,35 @@ typedef struct {
* 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 */
+ 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
+#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
+#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);
+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 */
+#include "secasn1t.h" /* way down here because I expect template stuff to
+ * move out of here anyway */
SEC_BEGIN_PROTOS
diff --git a/nss/lib/certdb/certv3.c b/nss/lib/certdb/certv3.c
index 1735b5e..bf0bcf9 100644
--- a/nss/lib/certdb/certv3.c
+++ b/nss/lib/certdb/certv3.c
@@ -15,17 +15,15 @@
#include "secerr.h"
SECStatus
-CERT_FindCertExtensionByOID(CERTCertificate *cert, SECItem *oid,
- SECItem *value)
+CERT_FindCertExtensionByOID(CERTCertificate *cert, SECItem *oid, SECItem *value)
{
- return (cert_FindExtensionByOID (cert->extensions, oid, value));
+ return (cert_FindExtensionByOID(cert->extensions, oid, value));
}
-
SECStatus
CERT_FindCertExtension(const CERTCertificate *cert, int tag, SECItem *value)
{
- return (cert_FindExtension (cert->extensions, tag, value));
+ return (cert_FindExtension(cert->extensions, tag, value));
}
static void
@@ -34,13 +32,13 @@ SetExts(void *object, CERTCertExtension **exts)
CERTCertificate *cert = (CERTCertificate *)object;
cert->extensions = exts;
- DER_SetUInteger (cert->arena, &(cert->version), SEC_CERTIFICATE_VERSION_3);
+ DER_SetUInteger(cert->arena, &(cert->version), SEC_CERTIFICATE_VERSION_3);
}
void *
CERT_StartCertExtensions(CERTCertificate *cert)
{
- return (cert_StartExtensions ((void *)cert, cert->arena, SetExts));
+ return (cert_StartExtensions((void *)cert, cert->arena, SetExts));
}
/*
@@ -50,62 +48,60 @@ SECStatus
CERT_FindNSCertTypeExtension(CERTCertificate *cert, SECItem *retItem)
{
- return (CERT_FindBitStringExtension
- (cert->extensions, SEC_OID_NS_CERT_EXT_CERT_TYPE, 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};
+ SECItem wrapperItem, tmpItem = { siBuffer, 0 };
SECStatus rv;
PLArenaPool *arena = NULL;
char *retstring = NULL;
-
+
wrapperItem.data = NULL;
tmpItem.data = NULL;
-
+
arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
-
- if ( ! arena ) {
- goto loser;
+
+ if (!arena) {
+ goto loser;
}
-
- rv = cert_FindExtension(cert->extensions, oidtag,
- &wrapperItem);
- if ( rv != SECSuccess ) {
- 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);
+ rv = SEC_QuickDERDecodeItem(
+ arena, &tmpItem, SEC_ASN1_GET(SEC_IA5StringTemplate), &wrapperItem);
- if ( rv != SECSuccess ) {
- goto loser;
+ if (rv != SECSuccess) {
+ goto loser;
}
- retstring = (char *)PORT_Alloc(tmpItem.len + 1 );
- if ( retstring == NULL ) {
- 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 (arena) {
+ PORT_FreeArena(arena, PR_FALSE);
}
-
- if ( wrapperItem.data ) {
- PORT_Free(wrapperItem.data);
+
+ if (wrapperItem.data) {
+ PORT_Free(wrapperItem.data);
}
- return(retstring);
+ return (retstring);
}
/*
@@ -116,7 +112,7 @@ CERT_FindKeyUsageExtension(CERTCertificate *cert, SECItem *retItem)
{
return (CERT_FindBitStringExtension(cert->extensions,
- SEC_OID_X509_KEY_USAGE, retItem));
+ SEC_OID_X509_KEY_USAGE, retItem));
}
/*
@@ -127,24 +123,21 @@ CERT_FindSubjectKeyIDExtension(CERTCertificate *cert, SECItem *retItem)
{
SECStatus rv;
- SECItem encodedValue = {siBuffer, NULL, 0 };
- SECItem decodedValue = {siBuffer, NULL, 0 };
+ SECItem encodedValue = { siBuffer, NULL, 0 };
+ SECItem decodedValue = { siBuffer, NULL, 0 };
- rv = cert_FindExtension
- (cert->extensions, SEC_OID_X509_SUBJECT_KEY_ID, &encodedValue);
+ 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;
- }
+ PORTCheapArenaPool tmpArena;
+ PORT_InitCheapArena(&tmpArena, DER_DEFAULT_CHUNKSIZE);
+ rv = SEC_QuickDERDecodeItem(&tmpArena.arena, &decodedValue,
+ SEC_ASN1_GET(SEC_OctetStringTemplate),
+ &encodedValue);
+ if (rv == SECSuccess) {
+ rv = SECITEM_CopyItem(NULL, retItem, &decodedValue);
+ }
+ PORT_DestroyCheapArena(&tmpArena);
}
SECITEM_FreeItem(&encodedValue, PR_FALSE);
return rv;
@@ -152,7 +145,7 @@ CERT_FindSubjectKeyIDExtension(CERTCertificate *cert, SECItem *retItem)
SECStatus
CERT_FindBasicConstraintExten(CERTCertificate *cert,
- CERTBasicConstraints *value)
+ CERTBasicConstraints *value)
{
SECItem encodedExtenValue;
SECStatus rv;
@@ -161,42 +154,42 @@ CERT_FindBasicConstraintExten(CERTCertificate *cert,
encodedExtenValue.len = 0;
rv = cert_FindExtension(cert->extensions, SEC_OID_X509_BASIC_CONSTRAINTS,
- &encodedExtenValue);
- if ( rv != SECSuccess ) {
- return (rv);
+ &encodedExtenValue);
+ if (rv != SECSuccess) {
+ return (rv);
}
- rv = CERT_DecodeBasicConstraintValue (value, &encodedExtenValue);
-
+ rv = CERT_DecodeBasicConstraintValue(value, &encodedExtenValue);
+
/* free the raw extension data */
PORT_Free(encodedExtenValue.data);
encodedExtenValue.data = NULL;
-
- return(rv);
+
+ return (rv);
}
CERTAuthKeyID *
-CERT_FindAuthKeyIDExten (PLArenaPool *arena, CERTCertificate *cert)
+CERT_FindAuthKeyIDExten(PLArenaPool *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);
+ &encodedExtenValue);
+ if (rv != SECSuccess) {
+ return (NULL);
}
- ret = CERT_DecodeAuthKeyID (arena, &encodedExtenValue);
+ ret = CERT_DecodeAuthKeyID(arena, &encodedExtenValue);
PORT_Free(encodedExtenValue.data);
encodedExtenValue.data = NULL;
-
- return(ret);
+
+ return (ret);
}
SECStatus
@@ -207,9 +200,9 @@ CERT_CheckCertUsage(CERTCertificate *cert, unsigned char usage)
/* There is no extension, v1 or v2 certificate */
if (cert->extensions == NULL) {
- return (SECSuccess);
+ return (SECSuccess);
}
-
+
keyUsage.data = NULL;
/* This code formerly ignored the Key Usage extension if it was
@@ -218,12 +211,12 @@ CERT_CheckCertUsage(CERTCertificate *cert, unsigned char usage)
*/
rv = CERT_FindKeyUsageExtension(cert, &keyUsage);
if (rv == SECFailure) {
- rv = (PORT_GetError () == SEC_ERROR_EXTENSION_NOT_FOUND) ?
- SECSuccess : 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_SetError(SEC_ERROR_CERT_USAGES_INVALID);
+ rv = SECFailure;
}
- PORT_Free (keyUsage.data);
+ PORT_Free(keyUsage.data);
return (rv);
}
diff --git a/nss/lib/certdb/certxutl.c b/nss/lib/certdb/certxutl.c
index 67dd1a1..c53f15c 100644
--- a/nss/lib/certdb/certxutl.c
+++ b/nss/lib/certdb/certxutl.c
@@ -16,93 +16,93 @@
#include "secerr.h"
#ifdef OLD
-#include "ocspti.h" /* XXX a better extensions interface would not
+#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)
+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);
+ 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)
+cert_FindExtensionByOID(CERTCertExtension **extensions, SECItem *oid,
+ SECItem *value)
{
CERTCertExtension *ext;
SECStatus rv = SECSuccess;
-
- ext = GetExtension (extensions, oid);
+
+ ext = GetExtension(extensions, oid);
if (ext == NULL) {
- PORT_SetError (SEC_ERROR_EXTENSION_NOT_FOUND);
- return (SECFailure);
+ PORT_SetError(SEC_ERROR_EXTENSION_NOT_FOUND);
+ return (SECFailure);
}
if (value)
- rv = SECITEM_CopyItem(NULL, value, &ext->value);
+ rv = SECITEM_CopyItem(NULL, value, &ext->value);
return (rv);
}
-
SECStatus
-CERT_GetExtenCriticality (CERTCertExtension **extensions, int tag, PRBool *isCritical)
+CERT_GetExtenCriticality(CERTCertExtension **extensions, int tag,
+ PRBool *isCritical)
{
CERTCertExtension *ext;
SECOidData *oid;
if (!isCritical)
- return (SECSuccess);
-
+ return (SECSuccess);
+
/* find the extension in the extensions list */
oid = SECOID_FindOIDByTag((SECOidTag)tag);
- if ( !oid ) {
- return(SECFailure);
+ if (!oid) {
+ return (SECFailure);
}
- ext = GetExtension (extensions, &oid->oid);
+ ext = GetExtension(extensions, &oid->oid);
if (ext == NULL) {
- PORT_SetError (SEC_ERROR_EXTENSION_NOT_FOUND);
- return (SECFailure);
+ 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;
+ *isCritical = PR_FALSE;
else
- *isCritical = (ext->critical.data[0] == 0xff) ? PR_TRUE : PR_FALSE;
- return (SECSuccess);
+ *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);
+ if (!oid) {
+ return (SECFailure);
}
- return(cert_FindExtensionByOID(extensions, &oid->oid, value));
+ return (cert_FindExtensionByOID(extensions, &oid->oid, value));
}
-
typedef struct _extNode {
struct _extNode *next;
CERTCertExtension *ext;
@@ -115,7 +115,7 @@ typedef struct {
PLArenaPool *arena;
extNode *head;
int count;
-}extRec;
+} extRec;
/*
* cert_StartExtensions
@@ -125,20 +125,20 @@ typedef struct {
*/
void *
cert_StartExtensions(void *owner, PLArenaPool *ownerArena,
- void (*setExts)(void *object, CERTCertExtension **exts))
+ void (*setExts)(void *object, CERTCertExtension **exts))
{
PLArenaPool *arena;
extRec *handle;
arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
- if ( !arena ) {
- return(0);
+ if (!arena) {
+ return (0);
}
handle = (extRec *)PORT_ArenaAlloc(arena, sizeof(extRec));
- if ( !handle ) {
- PORT_FreeArena(arena, PR_FALSE);
- return(0);
+ if (!handle) {
+ PORT_FreeArena(arena, PR_FALSE);
+ return (0);
}
handle->object = owner;
@@ -148,8 +148,8 @@ cert_StartExtensions(void *owner, PLArenaPool *ownerArena,
handle->arena = arena;
handle->head = 0;
handle->count = 0;
-
- return(handle);
+
+ return (handle);
}
static unsigned char hextrue = 0xff;
@@ -158,77 +158,80 @@ 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)
+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);
+ ext = (CERTCertExtension *)PORT_ArenaZAlloc(handle->ownerArena,
+ sizeof(CERTCertExtension));
+ if (!ext) {
+ return (SECFailure);
}
- node = (extNode*)PORT_ArenaAlloc(handle->arena, sizeof(extNode));
- if ( !node ) {
- 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;
+ 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);
- }
+ /* set object ID of the extension and its value */
+ if (copyData) {
+ rv = SECITEM_CopyItem(handle->ownerArena, &ext->id, oid);
+ if (rv) {
+ return (SECFailure);
+ }
+
+ rv = SECITEM_CopyItem(handle->ownerArena, &ext->value, value);
+ if (rv) {
+ return (SECFailure);
+ }
} else {
- ext->value = *value;
+ ext->id = *oid;
+ ext->value = *value;
}
-
+
handle->count++;
-
- return(SECSuccess);
+ return (SECSuccess);
}
SECStatus
-CERT_AddExtension(void *exthandle, int idtag, SECItem *value,
- PRBool critical, PRBool copyData)
+CERT_AddExtension(void *exthandle, int idtag, SECItem *value, PRBool critical,
+ PRBool copyData)
{
SECOidData *oid;
-
+
oid = SECOID_FindOIDByTag((SECOidTag)idtag);
- if ( !oid ) {
- return(SECFailure);
+ if (!oid) {
+ return (SECFailure);
}
- return(CERT_AddExtensionByOID(exthandle, &oid->oid, value, critical, copyData));
+ return (CERT_AddExtensionByOID(exthandle, &oid->oid, value, critical,
+ copyData));
}
SECStatus
CERT_EncodeAndAddExtension(void *exthandle, int idtag, void *value,
- PRBool critical, const SEC_ASN1Template *atemplate)
+ PRBool critical, const SEC_ASN1Template *atemplate)
{
extRec *handle;
SECItem *encitem;
@@ -236,45 +239,43 @@ CERT_EncodeAndAddExtension(void *exthandle, int idtag, void *value,
handle = (extRec *)exthandle;
encitem = SEC_ASN1EncodeItem(handle->ownerArena, NULL, value, atemplate);
- if ( encitem == NULL ) {
- return(SECFailure);
+ if (encitem == NULL) {
+ return (SECFailure);
}
return CERT_AddExtension(exthandle, idtag, encitem, critical, PR_FALSE);
}
void
-PrepareBitStringForEncoding (SECItem *bitsmap, SECItem *value)
+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;
+ 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)
+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)));
+ SECItem bitsmap;
+
+ PrepareBitStringForEncoding(&bitsmap, value);
+ return (CERT_EncodeAndAddExtension(exthandle, idtag, &bitsmap, critical,
+ SEC_ASN1_GET(SEC_BitStringTemplate)));
}
SECStatus
@@ -284,53 +285,53 @@ CERT_FinishExtensions(void *exthandle)
extNode *node;
CERTCertExtension **exts;
SECStatus rv = SECFailure;
-
+
handle = (extRec *)exthandle;
/* allocate space for extensions array */
exts = PORT_ArenaNewArray(handle->ownerArena, CERTCertExtension *,
- handle->count + 1);
+ handle->count + 1);
if (exts == NULL) {
- goto loser;
+ goto loser;
}
- /* put extensions in owner object and update its version number */
+/* 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;
+ 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++;
+ while (node) {
+ *exts = node->ext;
+
+ node = node->next;
+ exts++;
}
/* terminate the array of extensions */
@@ -352,19 +353,18 @@ CERT_MergeExtensions(void *exthandle, CERTCertExtension **extensions)
SECOidTag tag;
extNode *node;
extRec *handle = exthandle;
-
+
if (!exthandle || !extensions) {
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
+ 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) {
+ for (node = handle->head; node != NULL; node = node->next) {
if (tag == 0) {
if (SECITEM_ItemsAreEqual(&ext->id, &node->ext->id))
break;
- }
- else {
+ } else {
if (SECOID_FindOIDTag(&node->ext->id) == tag) {
break;
}
@@ -372,15 +372,15 @@ CERT_MergeExtensions(void *exthandle, CERTCertExtension **extensions)
}
if (node == NULL) {
PRBool critical = (ext->critical.len != 0 &&
- ext->critical.data[ext->critical.len - 1] != 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;
+ PORT_SetError(SEC_ERROR_UNKNOWN_CRITICAL_EXTENSION);
+ rv = SECFailure;
+ break;
}
/* add to list */
- rv = CERT_AddExtensionByOID (exthandle, &ext->id, &ext->value,
- critical, PR_TRUE);
+ rv = CERT_AddExtensionByOID(exthandle, &ext->id, &ext->value,
+ critical, PR_TRUE);
if (rv != SECSuccess)
break;
}
@@ -392,108 +392,102 @@ CERT_MergeExtensions(void *exthandle, CERTCertExtension **extensions)
* get the value of the Netscape Certificate Type Extension
*/
SECStatus
-CERT_FindBitStringExtension (CERTCertExtension **extensions, int tag,
- SECItem *retItem)
+CERT_FindBitStringExtension(CERTCertExtension **extensions, int tag,
+ SECItem *retItem)
{
- SECItem wrapperItem, tmpItem = {siBuffer,0};
+ SECItem wrapperItem, tmpItem = { siBuffer, 0 };
SECStatus rv;
- PLArenaPool *arena = NULL;
-
+ PORTCheapArenaPool tmpArena;
+
wrapperItem.data = NULL;
tmpItem.data = NULL;
-
- arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
-
- if ( ! arena ) {
- return(SECFailure);
- }
-
+
+ PORT_InitCheapArena(&tmpArena, DER_DEFAULT_CHUNKSIZE);
+
rv = cert_FindExtension(extensions, tag, &wrapperItem);
- if ( rv != SECSuccess ) {
- goto loser;
+ if (rv != SECSuccess) {
+ goto loser;
}
- rv = SEC_QuickDERDecodeItem(arena, &tmpItem,
+ rv = SEC_QuickDERDecodeItem(&tmpArena.arena, &tmpItem,
SEC_ASN1_GET(SEC_BitStringTemplate),
&wrapperItem);
- if ( rv != SECSuccess ) {
- goto loser;
+ if (rv != SECSuccess) {
+ goto loser;
}
- retItem->data = (unsigned char *)PORT_Alloc( ( tmpItem.len + 7 ) >> 3 );
- if ( retItem->data == NULL ) {
- 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);
+
+ 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);
+ PORT_DestroyCheapArena(&tmpArena);
+
+ if (wrapperItem.data) {
+ PORT_Free(wrapperItem.data);
}
- return(rv);
+ return (rv);
}
PRBool
-cert_HasCriticalExtension (CERTCertExtension **extensions)
+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++;
- }
+ 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)
+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.
+ 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++;
- }
+ 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/nss/lib/certdb/certxutl.h b/nss/lib/certdb/certxutl.h
index 05ad572..a8c76b5 100644
--- a/nss/lib/certdb/certxutl.h
+++ b/nss/lib/certdb/certxutl.h
@@ -7,7 +7,6 @@
*
*/
-
#ifndef _CERTXUTL_H_
#define _CERTXUTL_H_
@@ -23,28 +22,23 @@ typedef enum {
} ExtensionsType;
#endif
-extern PRBool
-cert_HasCriticalExtension (CERTCertExtension **extensions);
+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_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_FindExtension(CERTCertExtension **extensions, int tag,
+ SECItem *value);
-extern SECStatus
-cert_FindExtensionByOID (CERTCertExtension **extensions,
- SECItem *oid, SECItem *value);
+extern SECStatus cert_FindExtensionByOID(CERTCertExtension **extensions,
+ SECItem *oid, SECItem *value);
-extern SECStatus
-cert_GetExtenCriticality (CERTCertExtension **extensions,
- int tag, PRBool *isCritical);
+extern SECStatus cert_GetExtenCriticality(CERTCertExtension **extensions,
+ int tag, PRBool *isCritical);
-extern PRBool
-cert_HasUnknownCriticalExten (CERTCertExtension **extensions);
+extern PRBool cert_HasUnknownCriticalExten(CERTCertExtension **extensions);
#endif
diff --git a/nss/lib/certdb/crl.c b/nss/lib/certdb/crl.c
index 05ded13..8746908 100644
--- a/nss/lib/certdb/crl.c
+++ b/nss/lib/certdb/crl.c
@@ -5,7 +5,7 @@
/*
* Moved from secpkcs7.c
*/
-
+
#include "cert.h"
#include "certi.h"
#include "secder.h"
@@ -25,19 +25,16 @@
#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, }
+ { 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}
+ { SEC_ASN1_SEQUENCE_OF, 0, SEC_CERTExtensionTemplate }
};
/*
@@ -46,15 +43,10 @@ static const SEC_ASN1Template SEC_CERTExtensionsTemplate[] = {
*/
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) },
+ { 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 }
};
@@ -62,132 +54,97 @@ 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_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_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_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},
+ 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_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 },
+ 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},
+ 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_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) },
+ 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 },
+ SEC_ASN1_EXPLICIT | 0,
+ offsetof(CERTCrl, extensions), SEC_CERTExtensionsTemplate },
{ 0 }
};
const SEC_ASN1Template CERT_CrlTemplateEntriesOnly[] = {
- { SEC_ASN1_SEQUENCE,
- 0, NULL, sizeof(CERTCrl) },
+ { 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) },
+ 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 */
+ 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) },
+ { 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_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) },
+ offsetof(CERTSignedCrl, signatureWrap.signatureAlgorithm),
+ SEC_ASN1_SUB(SECOID_AlgorithmIDTemplate) },
+ { SEC_ASN1_BIT_STRING, offsetof(CERTSignedCrl, signatureWrap.signature) },
{ 0 }
};
@@ -196,22 +153,23 @@ const SEC_ASN1Template CERT_SetOfSignedCrlTemplate[] = {
};
/* get CRL version */
-int cert_get_crl_version(CERTCrl * crl)
+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);
+ version = (int)DER_GetUInteger(&crl->version);
}
return version;
}
-
/* check the entries in the CRL */
-SECStatus cert_check_crl_entries (CERTCrl *crl)
+SECStatus
+cert_check_crl_entries(CERTCrl* crl)
{
- CERTCrlEntry **entries;
- CERTCrlEntry *entry;
+ CERTCrlEntry** entries;
+ CERTCrlEntry* entry;
PRBool hasCriticalExten = PR_FALSE;
SECStatus rv = SECSuccess;
@@ -229,16 +187,17 @@ SECStatus cert_check_crl_entries (CERTCrl *crl)
*/
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.
- */
+ 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);
+ hasCriticalExten = cert_HasCriticalExtension(entry->extensions);
if (hasCriticalExten) {
- if (cert_get_crl_version(crl) != SEC_CRL_VERSION_2) {
+ 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;
@@ -247,19 +206,19 @@ SECStatus cert_check_crl_entries (CERTCrl *crl)
}
}
- /* 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;
+ /* 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);
+ return (rv);
}
/* Check the version of the CRL. If there is a critical extension in the crl
@@ -267,33 +226,34 @@ SECStatus cert_check_crl_entries (CERTCrl *crl)
the crl contains critical extension(s), then we must recognized the
extension's OID.
*/
-SECStatus cert_check_crl_version (CERTCrl *crl)
+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);
+ 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) {
+ 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);
- }
- }
+ /* 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);
@@ -304,7 +264,7 @@ SECStatus cert_check_crl_version (CERTCrl *crl)
* DER crl.
*/
SECStatus
-CERT_KeyFromDERCrl(PLArenaPool *arena, SECItem *derCrl, SECItem *key)
+CERT_KeyFromDERCrl(PLArenaPool* arena, SECItem* derCrl, SECItem* key)
{
SECStatus rv;
CERTSignedData sd;
@@ -317,11 +277,12 @@ CERT_KeyFromDERCrl(PLArenaPool *arena, SECItem *derCrl, SECItem *key)
} else {
myArena = arena;
}
- PORT_Memset (&sd, 0, sizeof (sd));
- rv = SEC_QuickDERDecodeItem (myArena, &sd, CERT_SignedDataTemplate, derCrl);
+ 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);
+ 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
@@ -339,15 +300,15 @@ CERT_KeyFromDERCrl(PLArenaPool *arena, SECItem *derCrl, SECItem *key)
#define GetOpaqueCRLFields(x) ((OpaqueCRLFields*)x->opaque)
-SECStatus CERT_CompleteCRLDecodeEntries(CERTSignedCrl* crl)
+SECStatus
+CERT_CompleteCRLDecodeEntries(CERTSignedCrl* crl)
{
SECStatus rv = SECSuccess;
SECItem* crldata = NULL;
OpaqueCRLFields* extended = NULL;
- if ( (!crl) ||
- (!(extended = (OpaqueCRLFields*) crl->opaque)) ||
- (PR_TRUE == extended->decodingError) ) {
+ if ((!crl) || (!(extended = (OpaqueCRLFields*)crl->opaque)) ||
+ (PR_TRUE == extended->decodingError)) {
rv = SECFailure;
} else {
if (PR_FALSE == extended->partial) {
@@ -365,10 +326,8 @@ SECStatus CERT_CompleteCRLDecodeEntries(CERTSignedCrl* crl)
}
if (SECSuccess == rv) {
- rv = SEC_QuickDERDecodeItem(crl->arena,
- &crl->crl,
- CERT_CrlTemplateEntriesOnly,
- crldata);
+ rv = SEC_QuickDERDecodeItem(crl->arena, &crl->crl,
+ CERT_CrlTemplateEntriesOnly, crldata);
if (SECSuccess == rv) {
extended->partial = PR_FALSE; /* successful decode, avoid
decoding again */
@@ -391,12 +350,12 @@ SECStatus CERT_CompleteCRLDecodeEntries(CERTSignedCrl* crl)
* take a DER CRL and decode it into a CRL structure
* allow reusing the input DER without making a copy
*/
-CERTSignedCrl *
-CERT_DecodeDERCrlWithFlags(PLArenaPool *narena, SECItem *derSignedCrl,
- int type, PRInt32 options)
+CERTSignedCrl*
+CERT_DecodeDERCrlWithFlags(PLArenaPool* narena, SECItem* derSignedCrl, int type,
+ PRInt32 options)
{
- PLArenaPool *arena;
- CERTSignedCrl *crl;
+ PLArenaPool* arena;
+ CERTSignedCrl* crl;
SECStatus rv;
OpaqueCRLFields* extended = NULL;
const SEC_ASN1Template* crlTemplate = CERT_SignedCrlTemplate;
@@ -408,8 +367,8 @@ CERT_DecodeDERCrlWithFlags(PLArenaPool *narena, SECItem *derSignedCrl,
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.
+ /* 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);
@@ -421,29 +380,29 @@ CERT_DecodeDERCrlWithFlags(PLArenaPool *narena, SECItem *derSignedCrl,
/* make a new arena if needed */
if (narena == NULL) {
- arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
- if ( !arena ) {
- return NULL;
- }
+ arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
+ if (!arena) {
+ return NULL;
+ }
} else {
- arena = narena;
+ arena = narena;
}
/* allocate the CRL structure */
- crl = (CERTSignedCrl *)PORT_ArenaZAlloc(arena, sizeof(CERTSignedCrl));
- if ( !crl ) {
+ crl = (CERTSignedCrl*)PORT_ArenaZAlloc(arena, sizeof(CERTSignedCrl));
+ if (!crl) {
PORT_SetError(SEC_ERROR_NO_MEMORY);
- goto loser;
+ goto loser;
}
crl->arena = arena;
/* allocate opaque fields */
crl->opaque = (void*)PORT_ArenaZAlloc(arena, sizeof(OpaqueCRLFields));
- if ( !crl->opaque ) {
- goto loser;
+ if (!crl->opaque) {
+ goto loser;
}
- extended = (OpaqueCRLFields*) crl->opaque;
+ extended = (OpaqueCRLFields*)crl->opaque;
if (options & CRL_DECODE_ADOPT_HEAP_DER) {
extended->heapDER = PR_TRUE;
}
@@ -452,7 +411,7 @@ CERT_DecodeDERCrlWithFlags(PLArenaPool *narena, SECItem *derSignedCrl,
must keep derSignedCrl until it
destroys the CRL */
} else {
- crl->derCrl = (SECItem *)PORT_ArenaZAlloc(arena,sizeof(SECItem));
+ crl->derCrl = (SECItem*)PORT_ArenaZAlloc(arena, sizeof(SECItem));
if (crl->derCrl == NULL) {
goto loser;
}
@@ -471,45 +430,45 @@ CERT_DecodeDERCrlWithFlags(PLArenaPool *narena, SECItem *derSignedCrl,
/* 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;
- }
+ 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;
- }
+ 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;
- }
+ rv = cert_check_crl_entries(&crl->crl);
+ if (rv != SECSuccess) {
+ extended->badExtensions = PR_TRUE;
+ }
- break;
+ break;
- default:
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- rv = SECFailure;
- break;
+ default:
+ PORT_SetError(SEC_ERROR_INVALID_ARGS);
+ rv = SECFailure;
+ break;
}
if (rv != SECSuccess) {
- goto loser;
+ goto loser;
}
crl->referenceCount = 1;
-
- return(crl);
-
+
+ return (crl);
+
loser:
if (options & CRL_DECODE_KEEP_BAD_CRL) {
if (extended) {
@@ -517,22 +476,22 @@ loser:
}
if (crl) {
crl->referenceCount = 1;
- return(crl);
+ return (crl);
}
}
- if ((narena == NULL) && arena ) {
- PORT_FreeArena(arena, PR_FALSE);
+ if ((narena == NULL) && arena) {
+ PORT_FreeArena(arena, PR_FALSE);
}
-
- return(0);
+
+ return (0);
}
/*
* take a DER CRL and decode it into a CRL structure
*/
-CERTSignedCrl *
-CERT_DecodeDERCrl(PLArenaPool *narena, SECItem *derSignedCrl, int type)
+CERTSignedCrl*
+CERT_DecodeDERCrl(PLArenaPool* narena, SECItem* derSignedCrl, int type)
{
return CERT_DecodeDERCrlWithFlags(narena, derSignedCrl, type,
CRL_DECODE_DEFAULT_OPTIONS);
@@ -555,14 +514,14 @@ CERT_DecodeDERCrl(PLArenaPool *narena, SECItem *derSignedCrl, int type)
* considered to be revoked
*/
static SECStatus
-SEC_FindCrlByKeyOnSlot(PK11SlotInfo *slot, SECItem *crlKey, int type,
+SEC_FindCrlByKeyOnSlot(PK11SlotInfo* slot, SECItem* crlKey, int type,
CERTSignedCrl** decoded, PRInt32 decodeoptions)
{
SECStatus rv = SECSuccess;
- CERTSignedCrl *crl = NULL;
- SECItem *derCrl = NULL;
+ CERTSignedCrl* crl = NULL;
+ SECItem* derCrl = NULL;
CK_OBJECT_HANDLE crlHandle = 0;
- char *url = NULL;
+ char* url = NULL;
PORT_Assert(decoded);
if (!decoded) {
@@ -572,46 +531,46 @@ SEC_FindCrlByKeyOnSlot(PK11SlotInfo *slot, SECItem *crlKey, int type,
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;
+ /* 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
+ 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 */
+ slot = NULL; /* adopt it */
+ derCrl = NULL; /* adopted by the crl struct */
crl->pkcs11ID = crlHandle;
if (url) {
- crl->url = PORT_ArenaStrdup(crl->arena,url);
+ crl->url = PORT_ArenaStrdup(crl->arena, url);
}
} else {
rv = SECFailure;
}
-
+
if (url) {
- PORT_Free(url);
+ PORT_Free(url);
}
if (slot) {
- PK11_FreeSlot(slot);
+ PK11_FreeSlot(slot);
}
loser:
if (derCrl) {
- SECITEM_FreeItem(derCrl, PR_TRUE);
+ SECITEM_FreeItem(derCrl, PR_TRUE);
}
*decoded = crl;
@@ -619,10 +578,9 @@ loser:
return rv;
}
-
-CERTSignedCrl *
-crl_storeCRL (PK11SlotInfo *slot,char *url,
- CERTSignedCrl *newCrl, SECItem *derCrl, int type)
+CERTSignedCrl*
+crl_storeCRL(PK11SlotInfo* slot, char* url, CERTSignedCrl* newCrl,
+ SECItem* derCrl, int type)
{
CERTSignedCrl *oldCrl = NULL, *crl = NULL;
PRBool deleteOldCrl = PR_FALSE;
@@ -639,38 +597,37 @@ crl_storeCRL (PK11SlotInfo *slot,char *url,
/* we can't use the cache here because we must look in the same
token */
- (void)SEC_FindCrlByKeyOnSlot(slot, &newCrl->crl.derName, type,
- &oldCrl, CRL_DECODE_SKIP_ENTRIES);
+ (void)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)) {
+ /* 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;
+ url = oldCrl->url;
}
/* really destroy this crl */
/* first drum it out of the permanment Data base */
- deleteOldCrl = PR_TRUE;
+ deleteOldCrl = PR_TRUE;
}
/* invalidate CRL cache for this issuer */
@@ -678,20 +635,20 @@ crl_storeCRL (PK11SlotInfo *slot,char *url,
/* 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);
- }
+ 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);
+ if (deleteOldCrl && crlHandle != CK_INVALID_HANDLE) {
+ SEC_DeletePermCRL(oldCrl);
+ }
+ SEC_DestroyCrl(oldCrl);
}
return crl;
@@ -704,50 +661,51 @@ done:
* The signature on this CRL must be checked before you
* load it. ???
*/
-CERTSignedCrl *
-SEC_NewCrl(CERTCertDBHandle *handle, char *url, SECItem *derCrl, int type)
+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);
+ 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)
+
+CERTSignedCrl*
+SEC_FindCrlByDERCert(CERTCertDBHandle* handle, SECItem* derCrl, int type)
{
- PLArenaPool *arena;
+ PLArenaPool* arena;
SECItem crlKey;
SECStatus rv;
- CERTSignedCrl *crl = NULL;
-
+ CERTSignedCrl* crl = NULL;
+
/* create a scratch arena */
arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
- if ( arena == NULL ) {
- return(NULL);
+ if (arena == NULL) {
+ return (NULL);
}
-
+
/* extract the database key from the cert */
rv = CERT_KeyFromDERCrl(arena, derCrl, &crlKey);
- if ( rv != SECSuccess ) {
- goto loser;
+ if (rv != SECSuccess) {
+ goto loser;
}
/* find the crl */
crl = SEC_FindCrlByName(handle, &crlKey, type);
-
+
loser:
PORT_FreeArena(arena, PR_FALSE);
- return(crl);
+ return (crl);
}
-CERTSignedCrl* SEC_DupCrl(CERTSignedCrl* acrl)
+CERTSignedCrl*
+SEC_DupCrl(CERTSignedCrl* acrl)
{
- if (acrl)
- {
+ if (acrl) {
PR_ATOMIC_INCREMENT(&acrl->referenceCount);
return acrl;
}
@@ -755,13 +713,13 @@ CERTSignedCrl* SEC_DupCrl(CERTSignedCrl* acrl)
}
SECStatus
-SEC_DestroyCrl(CERTSignedCrl *crl)
+SEC_DestroyCrl(CERTSignedCrl* crl)
{
if (crl) {
- if (PR_ATOMIC_DECREMENT(&crl->referenceCount) < 1) {
- if (crl->slot) {
- PK11_FreeSlot(crl->slot);
- }
+ 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);
@@ -769,7 +727,7 @@ SEC_DestroyCrl(CERTSignedCrl *crl)
if (crl->arena) {
PORT_FreeArena(crl->arena, PR_FALSE);
}
- }
+ }
return SECSuccess;
} else {
return SECFailure;
@@ -777,21 +735,21 @@ SEC_DestroyCrl(CERTSignedCrl *crl)
}
SECStatus
-SEC_LookupCrls(CERTCertDBHandle *handle, CERTCrlHeadNode **nodes, int type)
+SEC_LookupCrls(CERTCertDBHandle* handle, CERTCrlHeadNode** nodes, int type)
{
- CERTCrlHeadNode *head;
- PLArenaPool *arena = NULL;
+ CERTCrlHeadNode* head;
+ PLArenaPool* arena = NULL;
SECStatus rv;
*nodes = NULL;
arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
- if ( arena == NULL ) {
- return SECFailure;
+ if (arena == NULL) {
+ return SECFailure;
}
/* build a head structure */
- head = (CERTCrlHeadNode *)PORT_ArenaAlloc(arena, sizeof(CERTCrlHeadNode));
+ head = (CERTCrlHeadNode*)PORT_ArenaAlloc(arena, sizeof(CERTCrlHeadNode));
head->arena = arena;
head->first = NULL;
head->last = NULL;
@@ -801,12 +759,12 @@ SEC_LookupCrls(CERTCertDBHandle *handle, CERTCrlHeadNode **nodes, int type)
*nodes = head;
rv = PK11_LookupCrls(head, type, NULL);
-
+
if (rv != SECSuccess) {
- if ( arena ) {
- PORT_FreeArena(arena, PR_FALSE);
- *nodes = NULL;
- }
+ if (arena) {
+ PORT_FreeArena(arena, PR_FALSE);
+ *nodes = NULL;
+ }
}
return rv;
@@ -824,7 +782,7 @@ SEC_ASN1_CHOOSER_IMPLEMENT(CERT_SetOfSignedCrlTemplate)
/* constructor */
static SECStatus CachedCrl_Create(CachedCrl** returned, CERTSignedCrl* crl,
- CRLOrigin origin);
+ CRLOrigin origin);
/* destructor */
static SECStatus CachedCrl_Destroy(CachedCrl* crl);
@@ -838,11 +796,11 @@ static SECStatus CachedCrl_Depopulate(CachedCrl* crl);
Or are they the same token object, but with different DER ? */
static SECStatus CachedCrl_Compare(CachedCrl* a, CachedCrl* b, PRBool* isDupe,
- PRBool* isUpdated);
+ PRBool* isUpdated);
/* create a DPCache object */
static SECStatus DPCache_Create(CRLDPCache** returned, CERTCertificate* issuer,
- const SECItem* subject, SECItem* dp);
+ const SECItem* subject, SECItem* dp);
/* destructor for CRL DPCache object */
static SECStatus DPCache_Destroy(CRLDPCache* cache);
@@ -859,7 +817,8 @@ static SECStatus DPCache_FetchFromTokens(CRLDPCache* cache, PRTime vfdate,
/* 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);
+ PRBool readlocked, PRTime vfdate,
+ void* wincx);
/* returns true if there are CRLs from PKCS#11 slots */
static PRBool DPCache_HasTokenCRLs(CRLDPCache* cache);
@@ -872,8 +831,8 @@ 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);
+ CERTCertificate* issuer,
+ const SECItem* subject, const SECItem* dp);
/* destructor for CRL IssuerCache object */
SECStatus IssuerCache_Destroy(CRLIssuerCache* cache);
@@ -881,8 +840,8 @@ 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);
+ const SECItem* subject, const SECItem* dp,
+ CRLDPCache** newdpc);
/* get a particular DPCache object from an IssuerCache */
static CRLDPCache* IssuerCache_GetDPCache(CRLIssuerCache* cache,
@@ -893,37 +852,35 @@ static CRLDPCache* IssuerCache_GetDPCache(CRLIssuerCache* cache,
*/
/* allocate memory for hash table */
-static void * PR_CALLBACK
-PreAllocTable(void *pool, PRSize size)
+static void* PR_CALLBACK
+PreAllocTable(void* pool, PRSize size)
{
PreAllocator* alloc = (PreAllocator*)pool;
PORT_Assert(alloc);
- if (!alloc)
- {
+ if (!alloc) {
/* no allocator, or buffer full */
return NULL;
}
- if (size > (alloc->len - alloc->used))
- {
+ 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;
+ 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)
+PreFreeTable(void* pool, void* item)
{
}
/* allocate memory for hash table */
-static PLHashEntry * PR_CALLBACK
-PreAllocEntry(void *pool, const void *key)
+static PLHashEntry* PR_CALLBACK
+PreAllocEntry(void* pool, const void* key)
{
return PreAllocTable(pool, sizeof(PLHashEntry));
}
@@ -931,55 +888,47 @@ PreAllocEntry(void *pool, const void *key)
/* 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)
+PreFreeEntry(void* pool, PLHashEntry* he, PRUintn flag)
{
}
/* methods required for PL hash table functions */
-static PLHashAllocOps preAllocOps =
-{
- PreAllocTable, PreFreeTable,
- PreAllocEntry, PreFreeEntry
-};
+static PLHashAllocOps preAllocOps = { PreAllocTable, PreFreeTable,
+ PreAllocEntry, PreFreeEntry };
/* destructor for PreAllocator object */
-void PreAllocator_Destroy(PreAllocator* PreAllocator)
+void
+PreAllocator_Destroy(PreAllocator* PreAllocator)
{
- if (!PreAllocator)
- {
+ if (!PreAllocator) {
return;
}
- if (PreAllocator->arena)
- {
+ if (PreAllocator->arena) {
PORT_FreeArena(PreAllocator->arena, PR_TRUE);
}
}
/* constructor for PreAllocator object */
-PreAllocator* PreAllocator_Create(PRSize size)
+PreAllocator*
+PreAllocator_Create(PRSize size)
{
PLArenaPool* arena = NULL;
PreAllocator* prebuffer = NULL;
arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
- if (!arena)
- {
+ if (!arena) {
return NULL;
}
- prebuffer = (PreAllocator*)PORT_ArenaZAlloc(arena,
- sizeof(PreAllocator));
- if (!prebuffer)
- {
+ prebuffer = (PreAllocator*)PORT_ArenaZAlloc(arena, sizeof(PreAllocator));
+ if (!prebuffer) {
PORT_FreeArena(arena, PR_TRUE);
return NULL;
}
prebuffer->arena = arena;
- if (size)
- {
+ if (size) {
prebuffer->len = size;
prebuffer->data = PORT_ArenaAlloc(arena, size);
- if (!prebuffer->data)
- {
+ if (!prebuffer->data) {
PORT_FreeArena(arena, PR_TRUE);
return NULL;
}
@@ -1000,25 +949,24 @@ 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_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)
+SECStatus
+InitCRLCache(void)
{
- if (PR_FALSE == crlcache_initialized)
- {
+ 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)
- {
+ namedCRLCache.entries) {
/* CRL cache already partially initialized */
PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
return SECFailure;
@@ -1030,14 +978,12 @@ SECStatus InitCRLCache(void)
#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);
+ 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)
- {
+ !namedCRLCache.entries) {
+ if (crlcache.lock) {
#ifdef GLOBAL_RWLOCK
NSSRWLock_Destroy(crlcache.lock);
#else
@@ -1045,18 +991,15 @@ SECStatus InitCRLCache(void)
#endif
crlcache.lock = NULL;
}
- if (namedCRLCache.lock)
- {
+ if (namedCRLCache.lock) {
PR_DestroyLock(namedCRLCache.lock);
namedCRLCache.lock = NULL;
}
- if (crlcache.issuers)
- {
+ if (crlcache.issuers) {
PL_HashTableDestroy(crlcache.issuers);
crlcache.issuers = NULL;
}
- if (namedCRLCache.entries)
- {
+ if (namedCRLCache.entries) {
PL_HashTableDestroy(namedCRLCache.entries);
namedCRLCache.entries = NULL;
}
@@ -1065,18 +1008,13 @@ SECStatus InitCRLCache(void)
}
crlcache_initialized = PR_TRUE;
return SECSuccess;
- }
- else
- {
+ } else {
PORT_Assert(crlcache.lock);
PORT_Assert(crlcache.issuers);
- if ( (NULL == crlcache.lock) || (NULL == crlcache.issuers) )
- {
+ if ((NULL == crlcache.lock) || (NULL == crlcache.issuers)) {
/* CRL cache not fully initialized */
return SECFailure;
- }
- else
- {
+ } else {
/* CRL cache already initialized */
return SECSuccess;
}
@@ -1084,56 +1022,47 @@ SECStatus InitCRLCache(void)
}
/* destructor for CRL DPCache object */
-static SECStatus DPCache_Destroy(CRLDPCache* cache)
+static SECStatus
+DPCache_Destroy(CRLDPCache* cache)
{
PRUint32 i = 0;
PORT_Assert(cache);
- if (!cache)
- {
+ if (!cache) {
PORT_Assert(0);
PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
return SECFailure;
}
- if (cache->lock)
- {
+ if (cache->lock) {
#ifdef DPC_RWLOCK
NSSRWLock_Destroy(cache->lock);
#else
PR_DestroyLock(cache->lock);
#endif
- }
- else
- {
+ } else {
PORT_Assert(0);
return SECFailure;
}
/* destroy all our CRL objects */
- for (i=0;i<cache->ncrls;i++)
- {
+ for (i = 0; i < cache->ncrls; i++) {
if (!cache->crls || !cache->crls[i] ||
- SECSuccess != CachedCrl_Destroy(cache->crls[i]))
- {
+ SECSuccess != CachedCrl_Destroy(cache->crls[i])) {
return SECFailure;
}
}
/* free the array of CRLs */
- if (cache->crls)
- {
- PORT_Free(cache->crls);
+ if (cache->crls) {
+ PORT_Free(cache->crls);
}
/* destroy the cert */
- if (cache->issuerDERCert)
- {
+ if (cache->issuerDERCert) {
SECITEM_FreeItem(cache->issuerDERCert, PR_TRUE);
}
/* free the subject */
- if (cache->subject)
- {
+ if (cache->subject) {
SECITEM_FreeItem(cache->subject, PR_TRUE);
}
/* free the distribution points */
- if (cache->distributionPoint)
- {
+ if (cache->distributionPoint) {
SECITEM_FreeItem(cache->distributionPoint, PR_TRUE);
}
PORT_Free(cache);
@@ -1141,38 +1070,32 @@ static SECStatus DPCache_Destroy(CRLDPCache* cache)
}
/* destructor for CRL IssuerCache object */
-SECStatus IssuerCache_Destroy(CRLIssuerCache* cache)
+SECStatus
+IssuerCache_Destroy(CRLIssuerCache* cache)
{
PORT_Assert(cache);
- if (!cache)
- {
+ if (!cache) {
PORT_Assert(0);
PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
return SECFailure;
}
#ifdef XCRL
- if (cache->lock)
- {
+ if (cache->lock) {
NSSRWLock_Destroy(cache->lock);
- }
- else
- {
+ } else {
PORT_Assert(0);
PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
return SECFailure;
}
- if (cache->issuer)
- {
+ if (cache->issuer) {
CERT_DestroyCertificate(cache->issuer);
}
#endif
/* free the subject */
- if (cache->subject)
- {
+ if (cache->subject) {
SECITEM_FreeItem(cache->subject, PR_TRUE);
}
- if (SECSuccess != DPCache_Destroy(cache->dpp))
- {
+ if (SECSuccess != DPCache_Destroy(cache->dpp)) {
PORT_Assert(0);
return SECFailure;
}
@@ -1181,19 +1104,18 @@ SECStatus IssuerCache_Destroy(CRLIssuerCache* cache)
}
/* create a named CRL entry object */
-static SECStatus NamedCRLCacheEntry_Create(NamedCRLCacheEntry** returned)
+static SECStatus
+NamedCRLCacheEntry_Create(NamedCRLCacheEntry** returned)
{
NamedCRLCacheEntry* entry = NULL;
- if (!returned)
- {
+ if (!returned) {
PORT_Assert(0);
PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
return SECFailure;
}
*returned = NULL;
- entry = (NamedCRLCacheEntry*) PORT_ZAlloc(sizeof(NamedCRLCacheEntry));
- if (!entry)
- {
+ entry = (NamedCRLCacheEntry*)PORT_ZAlloc(sizeof(NamedCRLCacheEntry));
+ if (!entry) {
return SECFailure;
}
*returned = entry;
@@ -1201,21 +1123,19 @@ static SECStatus NamedCRLCacheEntry_Create(NamedCRLCacheEntry** returned)
}
/* destroy a named CRL entry object */
-static SECStatus NamedCRLCacheEntry_Destroy(NamedCRLCacheEntry* entry)
+static SECStatus
+NamedCRLCacheEntry_Destroy(NamedCRLCacheEntry* entry)
{
- if (!entry)
- {
+ if (!entry) {
PORT_Assert(0);
PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
return SECFailure;
}
- if (entry->crl)
- {
+ if (entry->crl) {
/* named CRL cache owns DER memory */
SECITEM_ZfreeItem(entry->crl, PR_TRUE);
}
- if (entry->canonicalizedName)
- {
+ if (entry->canonicalizedName) {
SECITEM_FreeItem(entry->canonicalizedName, PR_TRUE);
}
PORT_Free(entry);
@@ -1223,25 +1143,22 @@ static SECStatus NamedCRLCacheEntry_Destroy(NamedCRLCacheEntry* entry)
}
/* callback function used in hash table destructor */
-static PRIntn PR_CALLBACK FreeIssuer(PLHashEntry *he, PRIntn i, void *arg)
+static PRIntn PR_CALLBACK
+FreeIssuer(PLHashEntry* he, PRIntn i, void* arg)
{
CRLIssuerCache* issuer = NULL;
- SECStatus* rv = (SECStatus*) arg;
+ SECStatus* rv = (SECStatus*)arg;
PORT_Assert(he);
- if (!he)
- {
+ if (!he) {
return HT_ENUMERATE_NEXT;
}
- issuer = (CRLIssuerCache*) he->value;
+ issuer = (CRLIssuerCache*)he->value;
PORT_Assert(issuer);
- if (issuer)
- {
- if (SECSuccess != IssuerCache_Destroy(issuer))
- {
+ if (issuer) {
+ if (SECSuccess != IssuerCache_Destroy(issuer)) {
PORT_Assert(rv);
- if (rv)
- {
+ if (rv) {
*rv = SECFailure;
}
return HT_ENUMERATE_NEXT;
@@ -1251,25 +1168,22 @@ static PRIntn PR_CALLBACK FreeIssuer(PLHashEntry *he, PRIntn i, void *arg)
}
/* callback function used in hash table destructor */
-static PRIntn PR_CALLBACK FreeNamedEntries(PLHashEntry *he, PRIntn i, void *arg)
+static PRIntn PR_CALLBACK
+FreeNamedEntries(PLHashEntry* he, PRIntn i, void* arg)
{
NamedCRLCacheEntry* entry = NULL;
- SECStatus* rv = (SECStatus*) arg;
+ SECStatus* rv = (SECStatus*)arg;
PORT_Assert(he);
- if (!he)
- {
+ if (!he) {
return HT_ENUMERATE_NEXT;
}
- entry = (NamedCRLCacheEntry*) he->value;
+ entry = (NamedCRLCacheEntry*)he->value;
PORT_Assert(entry);
- if (entry)
- {
- if (SECSuccess != NamedCRLCacheEntry_Destroy(entry))
- {
+ if (entry) {
+ if (SECSuccess != NamedCRLCacheEntry_Destroy(entry)) {
PORT_Assert(rv);
- if (rv)
- {
+ if (rv) {
*rv = SECFailure;
}
return HT_ENUMERATE_NEXT;
@@ -1279,23 +1193,22 @@ static PRIntn PR_CALLBACK FreeNamedEntries(PLHashEntry *he, PRIntn i, void *arg)
}
/* needs to be called at NSS shutdown time
- This will destroy the global CRL cache, including
+ 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
+ShutdownCRLCache(void)
{
SECStatus rv = SECSuccess;
- if (PR_FALSE == crlcache_initialized &&
- !crlcache.lock && !crlcache.issuers)
- {
+ 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))
- {
+ !namedCRLCache.entries)) {
/* CRL cache has partially been shut down */
PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
return SECFailure;
@@ -1306,7 +1219,7 @@ SECStatus ShutdownCRLCache(void)
/* free the hash table of issuers */
PL_HashTableDestroy(crlcache.issuers);
crlcache.issuers = NULL;
- /* free the global lock */
+/* free the global lock */
#ifdef GLOBAL_RWLOCK
NSSRWLock_Destroy(crlcache.lock);
#else
@@ -1331,57 +1244,49 @@ SECStatus ShutdownCRLCache(void)
/* 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)
+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)
- {
+ 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++)
- {
+ for (i = 0; i < cache->ncrls; i++) {
CachedCrl* existing = NULL;
SECStatus rv = SECSuccess;
PRBool dupe = PR_FALSE, updated = PR_FALSE;
- if (!cache->crls)
- {
+ if (!cache->crls) {
PORT_Assert(0);
return SECFailure;
}
existing = cache->crls[i];
- if (!existing)
- {
+ if (!existing) {
PORT_Assert(0);
return SECFailure;
}
rv = CachedCrl_Compare(existing, newcrl, &dupe, &updated);
- if (SECSuccess != rv)
- {
+ if (SECSuccess != rv) {
PORT_Assert(0);
PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
return SECFailure;
}
- if (PR_TRUE == dupe)
- {
+ if (PR_TRUE == dupe) {
/* dupe */
PORT_SetError(SEC_ERROR_CRL_ALREADY_EXISTS);
return SECSuccess;
}
- if (PR_TRUE == updated)
- {
+ 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))
- {
+ if (SECSuccess != DPCache_RemoveCRL(cache, i)) {
PORT_Assert(0);
PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
return PR_FALSE;
@@ -1389,44 +1294,41 @@ static SECStatus DPCache_AddCRL(CRLDPCache* cache, CachedCrl* newcrl,
}
}
- newcrls = (CachedCrl**)PORT_Realloc(cache->crls,
- (cache->ncrls+1)*sizeof(CachedCrl*));
- if (!newcrls)
- {
+ 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;
+ cache->crls[cache->ncrls - 1] = newcrl;
*added = PR_TRUE;
return SECSuccess;
}
/* remove CRL at offset specified */
-static SECStatus DPCache_RemoveCRL(CRLDPCache* cache, PRUint32 offset)
+static SECStatus
+DPCache_RemoveCRL(CRLDPCache* cache, PRUint32 offset)
{
CachedCrl* acrl = NULL;
PORT_Assert(cache);
- if (!cache || (!cache->crls) || (!(offset<cache->ncrls)) )
- {
+ if (!cache || (!cache->crls) || (!(offset < cache->ncrls))) {
PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
return SECFailure;
}
acrl = cache->crls[offset];
PORT_Assert(acrl);
- if (!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->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))
- {
+ if (SECSuccess != CachedCrl_Destroy(acrl)) {
PORT_Assert(0);
PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
return SECFailure;
@@ -1442,7 +1344,8 @@ static SECStatus DPCache_RemoveCRL(CRLDPCache* cache, PRUint32 offset)
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)
+static PRBool
+TokenCRLStillExists(CERTSignedCrl* crl)
{
NSSItem newsubject;
SECItem subject;
@@ -1455,20 +1358,17 @@ static PRBool TokenCRLStillExists(CERTSignedCrl* crl)
SECItem* oldSubject = NULL;
PORT_Assert(crl);
- if (!crl)
- {
+ if (!crl) {
return PR_FALSE;
}
slot = crl->slot;
PORT_Assert(crl->slot);
- if (!slot)
- {
+ if (!slot) {
return PR_FALSE;
}
oldSubject = &crl->crl.derName;
PORT_Assert(oldSubject);
- if (!oldSubject)
- {
+ if (!oldSubject) {
return PR_FALSE;
}
@@ -1478,14 +1378,12 @@ static PRBool TokenCRLStillExists(CERTSignedCrl* crl)
/* first, make an nssCryptokiObject */
instance.handle = crl->pkcs11ID;
PORT_Assert(instance.handle);
- if (!instance.handle)
- {
+ if (!instance.handle) {
return PR_FALSE;
}
instance.token = PK11Slot_GetNSSToken(slot);
PORT_Assert(instance.token);
- if (!instance.token)
- {
+ if (!instance.token) {
return PR_FALSE;
}
instance.isTokenObject = PR_TRUE;
@@ -1493,34 +1391,25 @@ static PRBool TokenCRLStillExists(CERTSignedCrl* crl)
arena = NSSArena_Create();
PORT_Assert(arena);
- if (!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)
- {
+ 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)
- {
+ if (SECITEM_CompareItem(oldSubject, &subject) != SECEqual) {
xstatus = PR_FALSE;
}
- if (CKO_NETSCAPE_CRL != crl_class)
- {
+ if (CKO_NETSCAPE_CRL != crl_class) {
xstatus = PR_FALSE;
}
- }
- else
- {
+ } else {
xstatus = PR_FALSE;
}
NSSArena_Destroy(arena);
@@ -1528,19 +1417,18 @@ static PRBool TokenCRLStillExists(CERTSignedCrl* crl)
}
/* 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)
+static SECStatus
+CERT_VerifyCRL(CERTSignedCrl* crlobject, CERTCertificate* issuer, PRTime vfdate,
+ void* wincx)
{
- return CERT_VerifySignedData(&crlobject->signatureWrap,
- issuer, vfdate, 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)
+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
@@ -1554,66 +1442,56 @@ static SECStatus CachedCrl_Verify(CRLDPCache* cache, CachedCrl* crlobject,
the issuer certificate becomes available if that causes the
signature to verify */
- if (!cache || !crlobject)
- {
+ if (!cache || !crlobject) {
PORT_Assert(0);
PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
return SECFailure;
}
- if (PR_TRUE == GetOpaqueCRLFields(crlobject->crl)->decodingError)
- {
+ 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
- {
+ } else {
SECStatus signstatus = SECFailure;
- if (cache->issuerDERCert)
- {
- CERTCertificate *issuer = CERT_NewTempCertificate(cache->dbHandle,
- cache->issuerDERCert, NULL, PR_FALSE, PR_TRUE);
-
- if (issuer) {
- signstatus = CERT_VerifyCRL(crlobject->crl, issuer, vfdate,
- wincx);
- CERT_DestroyCertificate(issuer);
- }
- }
- if (SECSuccess != signstatus)
- {
- if (!cache->issuerDERCert)
- {
+ if (cache->issuerDERCert) {
+ CERTCertificate* issuer = CERT_NewTempCertificate(
+ cache->dbHandle, cache->issuerDERCert, NULL, PR_FALSE, PR_TRUE);
+
+ if (issuer) {
+ signstatus =
+ CERT_VerifyCRL(crlobject->crl, issuer, vfdate, wincx);
+ CERT_DestroyCertificate(issuer);
+ }
+ }
+ if (SECSuccess != signstatus) {
+ if (!cache->issuerDERCert) {
/* 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
- {
+ } else {
crlobject->sigChecked = PR_TRUE;
}
PORT_SetError(SEC_ERROR_CRL_BAD_SIGNATURE);
return SECSuccess;
- } else
- {
+ } 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)
+static SECStatus
+DPCache_FetchFromTokens(CRLDPCache* cache, PRTime vfdate, void* wincx)
{
SECStatus rv = SECSuccess;
CERTCrlHeadNode head;
- if (!cache)
- {
+ if (!cache) {
PORT_Assert(0);
PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
return SECFailure;
@@ -1626,67 +1504,52 @@ static SECStatus DPCache_FetchFromTokens(CRLDPCache* cache, PRTime vfdate,
/* 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)
- {
+ if (SECFailure == rv) {
/* fetch failed, add error bit */
cache->invalid |= CRL_CACHE_LAST_FETCH_FAILED;
- } else
- {
+ } 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)
- {
+ if (SECSuccess == rv) {
CERTCrlNode* crlNode = NULL;
- for (crlNode = head.first; crlNode ; crlNode = crlNode->next)
- {
+ for (crlNode = head.first; crlNode; crlNode = crlNode->next) {
CachedCrl* returned = NULL;
CERTSignedCrl* crlobject = crlNode->crl;
- if (!crlobject)
- {
+ if (!crlobject) {
PORT_Assert(0);
continue;
}
rv = CachedCrl_Create(&returned, crlobject, CRL_OriginToken);
- if (SECSuccess == rv)
- {
+ if (SECSuccess == rv) {
PRBool added = PR_FALSE;
rv = DPCache_AddCRL(cache, returned, &added);
- if (PR_TRUE != added)
- {
+ if (PR_TRUE != added) {
rv = CachedCrl_Destroy(returned);
returned = NULL;
- }
- else if (vfdate)
- {
+ } else if (vfdate) {
rv = CachedCrl_Verify(cache, returned, vfdate, wincx);
}
- }
- else
- {
+ } 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)
- {
+ if (SECFailure == rv) {
break;
}
}
}
- if (head.arena)
- {
+ 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)
- {
+ 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 */
@@ -1698,69 +1561,56 @@ static SECStatus DPCache_FetchFromTokens(CRLDPCache* cache, PRTime vfdate,
return rv;
}
-static SECStatus CachedCrl_GetEntry(CachedCrl* crl, const SECItem* sn,
- CERTCrlEntry** returned)
+static SECStatus
+CachedCrl_GetEntry(CachedCrl* crl, const 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)
- {
+ if (!crl || !sn || !returned || !crl->entries) {
PORT_SetError(SEC_ERROR_INVALID_ARGS);
return SECFailure;
}
acrlEntry = PL_HashTableLookup(crl->entries, (void*)sn);
- if (acrlEntry)
- {
+ if (acrlEntry) {
*returned = acrlEntry;
- }
- else
- {
+ } else {
*returned = NULL;
}
return SECSuccess;
}
/* check if a particular SN is in the CRL cache and return its entry */
-dpcacheStatus DPCache_Lookup(CRLDPCache* cache, const SECItem* sn,
- CERTCrlEntry** returned)
+dpcacheStatus
+DPCache_Lookup(CRLDPCache* cache, const SECItem* sn, CERTCrlEntry** returned)
{
SECStatus rv;
- if (!cache || !sn || !returned)
- {
+ 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)
- {
+ 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)
- {
+ 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)
- {
+ if (SECSuccess != rv) {
return dpcacheLookupError;
- }
- else
- {
- if (*returned)
- {
+ } else {
+ if (*returned) {
return dpcacheFoundEntry;
- }
- else
- {
+ } else {
return dpcacheNoEntry;
}
}
@@ -1768,23 +1618,21 @@ dpcacheStatus DPCache_Lookup(CRLDPCache* cache, const SECItem* sn,
#if defined(DPC_RWLOCK)
-#define DPCache_LockWrite() \
-{ \
- if (readlocked) \
- { \
- NSSRWLock_UnlockRead(cache->lock); \
- } \
- NSSRWLock_LockWrite(cache->lock); \
-}
+#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); \
-}
+#define DPCache_UnlockWrite() \
+ { \
+ if (readlocked) { \
+ NSSRWLock_LockRead(cache->lock); \
+ } \
+ NSSRWLock_UnlockWrite(cache->lock); \
+ }
#else
@@ -1792,21 +1640,21 @@ dpcacheStatus DPCache_Lookup(CRLDPCache* cache, const SECItem* sn,
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)
+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
@@ -1821,8 +1669,7 @@ static SECStatus DPCache_GetUpToDate(CRLDPCache* cache, CERTCertificate*
PRTime lastfetch = 0;
PRBool mustunlock = PR_FALSE;
- if (!cache)
- {
+ if (!cache) {
PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
return SECFailure;
}
@@ -1839,36 +1686,32 @@ static SECStatus DPCache_GetUpToDate(CRLDPCache* cache, CERTCertificate*
*/
forcedrefresh = cache->refresh;
lastfetch = cache->lastfetch;
- if (PR_TRUE != forcedrefresh &&
- (!(cache->invalid & CRL_CACHE_LAST_FETCH_FAILED)))
- {
+ if (PR_TRUE != forcedrefresh &&
+ (!(cache->invalid & CRL_CACHE_LAST_FETCH_FAILED))) {
now = PR_Now();
hastokenCRLs = DPCache_HasTokenCRLs(cache);
}
- if ( (0 == lastfetch) ||
+ if ((0 == lastfetch) ||
- (PR_TRUE == forcedrefresh) ||
+ (PR_TRUE == forcedrefresh) ||
- (cache->invalid & CRL_CACHE_LAST_FETCH_FAILED) ||
+ (cache->invalid & CRL_CACHE_LAST_FETCH_FAILED) ||
- ( (PR_FALSE == hastokenCRLs) &&
- ( (now - cache->lastfetch > CRLCache_Empty_TokenFetch_Interval) ||
- (now < cache->lastfetch)) ) ||
+ ((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)) ) )
- {
+ ((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)
- {
+ if (lastfetch == cache->lastfetch) {
/* we are the first */
rv = DPCache_FetchFromTokens(cache, vfdate, wincx);
- if (PR_TRUE == cache->refresh)
- {
+ if (PR_TRUE == cache->refresh) {
cache->refresh = PR_FALSE; /* clear refresh state */
}
dirty = PR_TRUE;
@@ -1881,38 +1724,31 @@ static SECStatus DPCache_GetUpToDate(CRLDPCache* cache, CERTCertificate*
we'll do this inexpensive existence check either
1) if there was a token object fetch
2) every minute */
- if (( PR_TRUE != dirty) && (!now) )
- {
+ if ((PR_TRUE != dirty) && (!now)) {
now = PR_Now();
}
- if ( (PR_TRUE == dirty) ||
- ( (now - cache->lastcheck > CRLCache_ExistenceCheck_Interval) ||
- (now < cache->lastcheck)) )
- {
+ 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++)
- {
+ for (i = 0; (i < cache->ncrls); i++) {
CachedCrl* savcrl = cache->crls[i];
- if ( (!savcrl) || (savcrl && CRL_OriginToken != savcrl->origin))
- {
+ if ((!savcrl) || (savcrl && CRL_OriginToken != savcrl->origin)) {
/* we only want to check token CRLs */
continue;
}
- if ((PR_TRUE != TokenCRLStillExists(savcrl->crl)))
- {
-
+ if ((PR_TRUE != TokenCRLStillExists(savcrl->crl))) {
+
/* this CRL is gone */
- if (PR_TRUE != mustunlock)
- {
+ 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)
- {
+ if (lastcheck == cache->lastcheck) {
/* the CRL is gone. And we are the one to do the update */
DPCache_RemoveCRL(cache, i);
dirty = PR_TRUE;
@@ -1921,8 +1757,7 @@ static SECStatus DPCache_GetUpToDate(CRLDPCache* cache, CERTCertificate*
updates in this thread for the remaining CRLs */
}
}
- if (PR_TRUE == mustunlock)
- {
+ if (PR_TRUE == mustunlock) {
cache->lastcheck = PR_Now();
DPCache_UnlockWrite();
mustunlock = PR_FALSE;
@@ -1931,15 +1766,13 @@ static SECStatus DPCache_GetUpToDate(CRLDPCache* cache, CERTCertificate*
/* add issuer certificate if it was previously unavailable */
if (issuer && (NULL == cache->issuerDERCert) &&
- (SECSuccess == CERT_CheckCertUsage(issuer, KU_CRL_SIGN)))
- {
+ (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->issuerDERCert)
- {
+ if (!cache->issuerDERCert) {
dirty = PR_TRUE;
- cache->dbHandle = issuer->dbhandle;
- cache->issuerDERCert = SECITEM_DupItem(&issuer->derCert);
+ cache->dbHandle = issuer->dbhandle;
+ cache->issuerDERCert = SECITEM_DupItem(&issuer->derCert);
}
DPCache_UnlockWrite();
}
@@ -1950,21 +1783,16 @@ static SECStatus DPCache_GetUpToDate(CRLDPCache* cache, CERTCertificate*
SEC_FindCrlByName, or through manual insertion, rather than through a
certificate verification (CERT_CheckCRL) */
- if (cache->issuerDERCert && vfdate )
- {
- mustunlock = PR_FALSE;
+ if (cache->issuerDERCert && vfdate) {
+ mustunlock = PR_FALSE;
/* re-process all unverified CRLs */
- for (i = 0; i < cache->ncrls ; i++)
- {
+ for (i = 0; i < cache->ncrls; i++) {
CachedCrl* savcrl = cache->crls[i];
- if (!savcrl)
- {
+ if (!savcrl) {
continue;
}
- if (PR_TRUE != savcrl->sigChecked)
- {
- if (!mustunlock)
- {
+ if (PR_TRUE != savcrl->sigChecked) {
+ if (!mustunlock) {
DPCache_LockWrite();
mustunlock = PR_TRUE;
}
@@ -1972,9 +1800,8 @@ static SECStatus DPCache_GetUpToDate(CRLDPCache* cache, CERTCertificate*
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) )
- {
+ 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;
@@ -1982,191 +1809,165 @@ static SECStatus DPCache_GetUpToDate(CRLDPCache* cache, CERTCertificate*
/* stay locked here intentionally so we do all the other
updates in this thread for the remaining CRLs */
}
- if (mustunlock && !dirty)
- {
+ if (mustunlock && !dirty) {
DPCache_UnlockWrite();
mustunlock = PR_FALSE;
}
}
}
- if (dirty || cache->mustchoose)
- {
+ 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;
- }
+ if (!mustunlock) {
+ DPCache_LockWrite();
+ mustunlock = PR_TRUE;
+ }
DPCache_SelectCRL(cache);
cache->mustchoose = PR_FALSE;
}
if (mustunlock)
- DPCache_UnlockWrite();
+ DPCache_UnlockWrite();
return rv;
}
/* callback for qsort to sort by thisUpdate */
-static int SortCRLsByThisUpdate(const void* arg1, const void* arg2)
+static int
+SortCRLsByThisUpdate(const void* arg1, const void* arg2)
{
PRTime timea, timeb;
SECStatus rv = SECSuccess;
- CachedCrl* a, *b;
+ CachedCrl *a, *b;
- a = *(CachedCrl**) arg1;
- b = *(CachedCrl**) arg2;
+ a = *(CachedCrl**)arg1;
+ b = *(CachedCrl**)arg2;
- if (!a || !b)
- {
+ if (!a || !b) {
PORT_Assert(0);
PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
rv = SECFailure;
}
- if (SECSuccess == rv)
- {
+ if (SECSuccess == rv) {
rv = DER_DecodeTimeChoice(&timea, &a->crl->crl.lastUpdate);
- }
- if (SECSuccess == rv)
- {
+ }
+ if (SECSuccess == rv) {
rv = DER_DecodeTimeChoice(&timeb, &b->crl->crl.lastUpdate);
}
- if (SECSuccess == rv)
- {
- if (timea > timeb)
- {
+ if (SECSuccess == rv) {
+ if (timea > timeb) {
return 1; /* a is better than b */
}
- if (timea < timeb )
- {
+ 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;
+ 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)
+static int
+SortImperfectCRLs(const void* arg1, const void* arg2)
{
- CachedCrl* a, *b;
+ CachedCrl *a, *b;
- a = *(CachedCrl**) arg1;
- b = *(CachedCrl**) arg2;
+ a = *(CachedCrl**)arg1;
+ b = *(CachedCrl**)arg2;
- if (!a || !b)
- {
+ if (!a || !b) {
PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
PORT_Assert(0);
- }
- else
- {
+ } else {
PRBool aDecoded = PR_FALSE, bDecoded = PR_FALSE;
- if ( (PR_TRUE == a->sigValid) && (PR_TRUE == b->sigValid) )
- {
+ 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)
- {
+ if (PR_TRUE == a->sigValid) {
return 1; /* a is greater than b */
}
- if (PR_TRUE == b->sigValid)
- {
+ 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) )
- {
+ if ((PR_FALSE == aDecoded) && (PR_FALSE == bDecoded)) {
/* both CRLs are proper DER, choose the latest one */
return SortCRLsByThisUpdate(arg1, arg2);
}
- if (PR_FALSE == aDecoded)
- {
+ if (PR_FALSE == aDecoded) {
return 1; /* a is better than b */
}
- if (PR_FALSE == bDecoded)
- {
+ 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;
+ return a > b ? 1 : -1;
}
-
/* Pick best CRL to use . needs write access */
-static SECStatus DPCache_SelectCRL(CRLDPCache* cache)
+static SECStatus
+DPCache_SelectCRL(CRLDPCache* cache)
{
PRUint32 i;
PRBool valid = PR_TRUE;
CachedCrl* selected = NULL;
PORT_Assert(cache);
- if (!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++)
- {
+ for (i = 0; i < cache->ncrls; i++) {
if (!cache->crls[i] || !cache->crls[i]->sigChecked ||
- !cache->crls[i]->sigValid)
- {
+ !cache->crls[i]->sigValid) {
valid = PR_FALSE;
break;
}
}
- if (PR_TRUE == valid)
- {
+ if (PR_TRUE == valid) {
/* all CRLs are valid, clear this error */
cache->invalid &= (~CRL_CACHE_INVALID_CRLS);
- } else
- {
+ } else {
/* some CRLs are invalid, set this error */
cache->invalid |= CRL_CACHE_INVALID_CRLS;
}
- if (cache->invalid)
- {
+ if (cache->invalid) {
/* cache is in an invalid state, so reset it */
- if (cache->selected)
- {
+ if (cache->selected) {
cache->selected = NULL;
}
/* also sort the CRLs imperfectly */
- qsort(cache->crls, cache->ncrls, sizeof(CachedCrl*),
- SortImperfectCRLs);
+ 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)
- {
+ if (cache->ncrls) {
+ /* all CRLs are good, sort them by thisUpdate */
+ qsort(cache->crls, cache->ncrls, sizeof(CachedCrl*), SortCRLsByThisUpdate);
+
/* pick the newest CRL */
- selected = cache->crls[cache->ncrls-1];
-
+ selected = cache->crls[cache->ncrls - 1];
+
/* and populate the cache */
- if (SECSuccess != CachedCrl_Populate(selected))
- {
+ if (SECSuccess != CachedCrl_Populate(selected)) {
return SECFailure;
}
}
@@ -2177,22 +1978,21 @@ static SECStatus DPCache_SelectCRL(CRLDPCache* cache)
}
/* initialize a DPCache object */
-static SECStatus DPCache_Create(CRLDPCache** returned, CERTCertificate* issuer,
- const SECItem* subject, SECItem* dp)
+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)
- {
+ if (!returned || !subject) {
PORT_Assert(0);
PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
return SECFailure;
}
*returned = NULL;
cache = PORT_ZAlloc(sizeof(CRLDPCache));
- if (!cache)
- {
+ if (!cache) {
return SECFailure;
}
#ifdef DPC_RWLOCK
@@ -2200,15 +2000,13 @@ static SECStatus DPCache_Create(CRLDPCache** returned, CERTCertificate* issuer,
#else
cache->lock = PR_NewLock();
#endif
- if (!cache->lock)
- {
- PORT_Free(cache);
+ if (!cache->lock) {
+ PORT_Free(cache);
return SECFailure;
}
- if (issuer)
- {
- cache->dbHandle = issuer->dbhandle;
- cache->issuerDERCert = SECITEM_DupItem(&issuer->derCert);
+ if (issuer) {
+ cache->dbHandle = issuer->dbhandle;
+ cache->issuerDERCert = SECITEM_DupItem(&issuer->derCert);
}
cache->distributionPoint = SECITEM_DupItem(dp);
cache->subject = SECITEM_DupItem(subject);
@@ -2219,45 +2017,39 @@ static SECStatus DPCache_Create(CRLDPCache** returned, CERTCertificate* issuer,
}
/* create an issuer cache object (per CA subject ) */
-static SECStatus IssuerCache_Create(CRLIssuerCache** returned,
- CERTCertificate* issuer,
- const SECItem* subject, const SECItem* dp)
+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)
- {
+ if (!returned || !subject) {
PORT_Assert(0);
PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
return SECFailure;
}
*returned = NULL;
- cache = (CRLIssuerCache*) PORT_ZAlloc(sizeof(CRLIssuerCache));
- if (!cache)
- {
+ 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)
- {
+ if (!cache->lock) {
rv = SECFailure;
}
- if (SECSuccess == rv && issuer)
- {
+ if (SECSuccess == rv && issuer) {
cache->issuer = CERT_DupCertificate(issuer);
- if (!cache->issuer)
- {
+ if (!cache->issuer) {
rv = SECFailure;
}
}
#endif
- if (SECSuccess != rv)
- {
+ if (SECSuccess != rv) {
PORT_Assert(SECSuccess == IssuerCache_Destroy(cache));
return SECFailure;
}
@@ -2266,31 +2058,25 @@ static SECStatus IssuerCache_Create(CRLIssuerCache** returned,
}
/* add a DPCache to the issuer cache */
-static SECStatus IssuerCache_AddDP(CRLIssuerCache* cache,
- CERTCertificate* issuer,
- const SECItem* subject,
- const SECItem* dp,
- CRLDPCache** newdpc)
+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)
- {
+ if (!cache || !subject || !newdpc) {
PORT_Assert(0);
PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
return SECFailure;
}
- if (!dp)
- {
+ if (!dp) {
/* default distribution point */
SECStatus rv = DPCache_Create(&cache->dpp, issuer, subject, NULL);
- if (SECSuccess == rv)
- {
+ if (SECSuccess == rv) {
*newdpc = cache->dpp;
return SECSuccess;
}
- }
- else
- {
+ } else {
/* we should never hit this until we support multiple DPs */
PORT_Assert(dp);
/* XCRL allocate a new distribution point cache object, initialize it,
@@ -2300,27 +2086,26 @@ static SECStatus IssuerCache_AddDP(CRLIssuerCache* cache,
}
/* add an IssuerCache to the global hash table of issuers */
-static SECStatus CRLCache_AddIssuer(CRLIssuerCache* issuer)
-{
+static SECStatus
+CRLCache_AddIssuer(CRLIssuerCache* issuer)
+{
PORT_Assert(issuer);
PORT_Assert(crlcache.issuers);
- if (!issuer || !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))
- {
+ 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)
+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;
@@ -2328,58 +2113,51 @@ static SECStatus CRLCache_GetIssuerCache(CRLCache* cache,
PORT_Assert(subject);
PORT_Assert(returned);
PORT_Assert(crlcache.issuers);
- if (!cache || !subject || !returned || !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);
+ 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)
+static CERTSignedCrl*
+GetBestCRL(CRLDPCache* cache, PRBool entries)
{
CachedCrl* acrl = NULL;
PORT_Assert(cache);
- if (!cache)
- {
+ if (!cache) {
PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
return NULL;
}
- if (0 == cache->ncrls)
- {
+ 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)
- {
+ if (cache->selected) {
return SEC_DupCrl(cache->selected->crl);
}
/* otherwise, use latest valid DER CRL */
- acrl = cache->crls[cache->ncrls-1];
+ acrl = cache->crls[cache->ncrls - 1];
- if (acrl && (PR_FALSE == GetOpaqueCRLFields(acrl->crl)->decodingError) )
- {
+ if (acrl && (PR_FALSE == GetOpaqueCRLFields(acrl->crl)->decodingError)) {
SECStatus rv = SECSuccess;
- if (PR_TRUE == entries)
- {
+ if (PR_TRUE == entries) {
rv = CERT_CompleteCRLDecodeEntries(acrl->crl);
}
- if (SECSuccess == rv)
- {
+ if (SECSuccess == rv) {
return SEC_DupCrl(acrl->crl);
}
}
@@ -2389,7 +2167,8 @@ static CERTSignedCrl* GetBestCRL(CRLDPCache* cache, PRBool entries)
}
/* get a particular DPCache object from an IssuerCache */
-static CRLDPCache* IssuerCache_GetDPCache(CRLIssuerCache* cache, const SECItem* dp)
+static CRLDPCache*
+IssuerCache_GetDPCache(CRLIssuerCache* cache, const SECItem* dp)
{
CRLDPCache* dpp = NULL;
PORT_Assert(cache);
@@ -2397,8 +2176,7 @@ static CRLDPCache* IssuerCache_GetDPCache(CRLIssuerCache* cache, const SECItem*
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)
- {
+ if (!cache || dp) {
PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
return NULL;
}
@@ -2415,9 +2193,10 @@ static CRLDPCache* IssuerCache_GetDPCache(CRLIssuerCache* cache, const SECItem*
/* 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
+AcquireDPCache(CERTCertificate* issuer, const SECItem* subject,
+ const SECItem* dp, PRTime t, void* wincx, CRLDPCache** dpcache,
+ PRBool* writeLocked)
{
SECStatus rv = SECSuccess;
CRLIssuerCache* issuercache = NULL;
@@ -2425,8 +2204,7 @@ SECStatus AcquireDPCache(CERTCertificate* issuer, const SECItem* subject,
PRBool globalwrite = PR_FALSE;
#endif
PORT_Assert(crlcache.lock);
- if (!crlcache.lock)
- {
+ if (!crlcache.lock) {
/* CRL cache is not initialized */
PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
return SECFailure;
@@ -2437,8 +2215,7 @@ SECStatus AcquireDPCache(CERTCertificate* issuer, const SECItem* subject,
PR_Lock(crlcache.lock);
#endif
rv = CRLCache_GetIssuerCache(&crlcache, subject, &issuercache);
- if (SECSuccess != rv)
- {
+ if (SECSuccess != rv) {
#ifdef GLOBAL_RWLOCK
NSSRWLock_UnlockRead(crlcache.lock);
#else
@@ -2447,28 +2224,24 @@ SECStatus AcquireDPCache(CERTCertificate* issuer, const SECItem* subject,
PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
return SECFailure;
}
- if (!issuercache)
- {
+ 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)
- {
+ if (SECSuccess == rv && !issuercache) {
PORT_Assert(issuercache);
rv = SECFailure;
}
- if (SECSuccess == rv)
- {
+ 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)
- {
+ if (SECSuccess == rv) {
/* lock the DPCache for write to ensure the update happens in this
thread */
*writeLocked = PR_TRUE;
@@ -2478,11 +2251,10 @@ SECStatus AcquireDPCache(CERTCertificate* issuer, const SECItem* subject,
PR_Lock((*dpcache)->lock);
#endif
}
-
- if (SECSuccess == rv)
- {
- /* now add the new issuer cache to the global hash table of
- issuers */
+
+ 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);
@@ -2491,37 +2263,30 @@ SECStatus AcquireDPCache(CERTCertificate* issuer, const SECItem* subject,
NSSRWLock_LockWrite(crlcache.lock);
globalwrite = PR_TRUE;
rv = CRLCache_GetIssuerCache(&crlcache, subject, &existing);
- if (!existing)
- {
+ if (!existing) {
#endif
rv = CRLCache_AddIssuer(issuercache);
- if (SECSuccess != rv)
- {
+ if (SECSuccess != rv) {
/* failure */
rv = SECFailure;
}
#ifdef GLOBAL_RWLOCK
- }
- else
- {
+ } else {
/* somebody else updated before we did */
IssuerCache_Destroy(issuercache); /* destroy the new object */
- issuercache = existing; /* use the existing one */
+ 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 */
+/* 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)
- {
+ if (PR_TRUE == globalwrite) {
NSSRWLock_UnlockWrite(crlcache.lock);
globalwrite = PR_FALSE;
- }
- else
- {
+ } else {
NSSRWLock_UnlockRead(crlcache.lock);
}
#else
@@ -2529,10 +2294,8 @@ SECStatus AcquireDPCache(CERTCertificate* issuer, const SECItem* subject,
#endif
/* if there was a failure adding an issuer cache object, destroy it */
- if (SECSuccess != rv && issuercache)
- {
- if (PR_TRUE == *writeLocked)
- {
+ if (SECSuccess != rv && issuercache) {
+ if (PR_TRUE == *writeLocked) {
#ifdef DPC_RWLOCK
NSSRWLock_UnlockWrite((*dpcache)->lock);
#else
@@ -2543,12 +2306,10 @@ SECStatus AcquireDPCache(CERTCertificate* issuer, const SECItem* subject,
issuercache = NULL;
}
- if (SECSuccess != rv)
- {
+ if (SECSuccess != rv) {
return SECFailure;
}
- } else
- {
+ } else {
#ifdef GLOBAL_RWLOCK
NSSRWLock_UnlockRead(crlcache.lock);
#else
@@ -2558,27 +2319,22 @@ SECStatus AcquireDPCache(CERTCertificate* issuer, const SECItem* subject,
}
/* 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)
- {
+ if (PR_FALSE == *writeLocked) {
#ifdef DPC_RWLOCK
NSSRWLock_LockRead((*dpcache)->lock);
#else
PR_Lock((*dpcache)->lock);
#endif
}
-
- if (SECSuccess == rv)
- {
+
+ if (SECSuccess == rv) {
/* currently there is always one and only one DPCache per issuer */
PORT_Assert(*dpcache);
- if (*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
- {
+ } else {
rv = SECFailure;
}
}
@@ -2586,20 +2342,17 @@ SECStatus AcquireDPCache(CERTCertificate* issuer, const SECItem* subject,
}
/* unlock access to the DPCache */
-void ReleaseDPCache(CRLDPCache* dpcache, PRBool writeLocked)
+void
+ReleaseDPCache(CRLDPCache* dpcache, PRBool writeLocked)
{
- if (!dpcache)
- {
+ if (!dpcache) {
PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
return;
}
#ifdef DPC_RWLOCK
- if (PR_TRUE == writeLocked)
- {
+ if (PR_TRUE == writeLocked) {
NSSRWLock_UnlockWrite(dpcache->lock);
- }
- else
- {
+ } else {
NSSRWLock_UnlockRead(dpcache->lock);
}
#else
@@ -2609,9 +2362,9 @@ void ReleaseDPCache(CRLDPCache* dpcache, PRBool writeLocked)
SECStatus
cert_CheckCertRevocationStatus(CERTCertificate* cert, CERTCertificate* issuer,
- const SECItem* dp, PRTime t, void *wincx,
- CERTRevocationStatus *revStatus,
- CERTCRLEntryReasonCode *revReason)
+ const SECItem* dp, PRTime t, void* wincx,
+ CERTRevocationStatus* revStatus,
+ CERTCRLEntryReasonCode* revReason)
{
PRBool lockedwrite = PR_FALSE;
SECStatus rv = SECSuccess;
@@ -2621,23 +2374,20 @@ cert_CheckCertRevocationStatus(CERTCertificate* cert, CERTCertificate* issuer,
CERTCrlEntry* entry = NULL;
dpcacheStatus ds;
- if (!cert || !issuer)
- {
+ if (!cert || !issuer) {
PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
return SECFailure;
}
- if (revStatus)
- {
+ if (revStatus) {
*revStatus = status;
}
- if (revReason)
- {
+ if (revReason) {
*revReason = reason;
}
- if (t && secCertTimeValid != CERT_CheckCertValidTimes(issuer, t, PR_FALSE))
- {
+ if (t &&
+ secCertTimeValid != 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. */
@@ -2648,50 +2398,39 @@ cert_CheckCertRevocationStatus(CERTCertificate* cert, CERTCertificate* issuer,
rv = AcquireDPCache(issuer, &issuer->derSubject, dp, t, wincx, &dpcache,
&lockedwrite);
PORT_Assert(SECSuccess == rv);
- if (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)
- {
+ switch (ds) {
case dpcacheFoundEntry:
PORT_Assert(entry);
/* check the time if we have one */
- if (entry->revocationDate.data && entry->revocationDate.len)
- {
+ if (entry->revocationDate.data && entry->revocationDate.len) {
PRTime revocationDate = 0;
- if (SECSuccess == DER_DecodeTimeChoice(&revocationDate,
- &entry->revocationDate))
- {
+ 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)
- {
+ if (t >= revocationDate) {
rv = SECFailure;
- }
- else
- {
+ } else {
status = certRevocationStatusValid;
}
- }
- else
- {
+ } else {
/* invalid revocation date, consider the certificate
permanently revoked */
rv = SECFailure;
}
- }
- else
- {
+ } else {
/* no revocation date, certificate is permanently revoked */
rv = SECFailure;
}
- if (SECFailure == rv)
- {
+ if (SECFailure == rv) {
(void)CERT_FindCRLEntryReasonExten(entry, &reason);
PORT_SetError(SEC_ERROR_REVOKED_CERTIFICATE);
}
@@ -2718,12 +2457,10 @@ cert_CheckCertRevocationStatus(CERTCertificate* cert, CERTCertificate* issuer,
}
ReleaseDPCache(dpcache, lockedwrite);
- if (revStatus)
- {
+ if (revStatus) {
*revStatus = status;
}
- if (revReason)
- {
+ if (revReason) {
*revReason = reason;
}
return rv;
@@ -2731,31 +2468,29 @@ cert_CheckCertRevocationStatus(CERTCertificate* cert, CERTCertificate* issuer,
/* check CRL revocation status of given certificate and issuer */
SECStatus
-CERT_CheckCRL(CERTCertificate* cert, CERTCertificate* issuer,
- const SECItem* dp, PRTime t, void* wincx)
+CERT_CheckCRL(CERTCertificate* cert, CERTCertificate* issuer, const SECItem* dp,
+ PRTime t, void* wincx)
{
- return cert_CheckCertRevocationStatus(cert, issuer, dp, t, wincx,
- NULL, NULL);
+ 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*
+SEC_FindCrlByName(CERTCertDBHandle* handle, SECItem* crlKey, int type)
{
CERTSignedCrl* acrl = NULL;
CRLDPCache* dpcache = NULL;
SECStatus rv = SECSuccess;
PRBool writeLocked = PR_FALSE;
- if (!crlKey)
- {
+ if (!crlKey) {
PORT_SetError(SEC_ERROR_INVALID_ARGS);
return NULL;
}
rv = AcquireDPCache(NULL, crlKey, NULL, 0, NULL, &dpcache, &writeLocked);
- if (SECSuccess == rv)
- {
+ if (SECSuccess == rv) {
acrl = GetBestCRL(dpcache, PR_TRUE); /* decode entries, because
SEC_FindCrlByName always returned fully decoded CRLs in the past */
ReleaseDPCache(dpcache, writeLocked);
@@ -2765,24 +2500,24 @@ SEC_FindCrlByName(CERTCertDBHandle *handle, SECItem *crlKey, int type)
/* 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)
+void
+CERT_CRLCacheRefreshIssuer(CERTCertDBHandle* dbhandle, SECItem* crlKey)
{
CRLDPCache* cache = NULL;
SECStatus rv = SECSuccess;
PRBool writeLocked = PR_FALSE;
PRBool readlocked;
- (void) dbhandle; /* silence compiler warnings */
+ (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)
- {
+ if (SECSuccess != rv) {
return;
}
/* we need to invalidate the DPCache here */
- readlocked = (writeLocked == PR_TRUE? PR_FALSE : PR_TRUE);
+ readlocked = (writeLocked == PR_TRUE ? PR_FALSE : PR_TRUE);
DPCache_LockWrite();
cache->refresh = PR_TRUE;
DPCache_UnlockWrite();
@@ -2791,7 +2526,8 @@ void CERT_CRLCacheRefreshIssuer(CERTCertDBHandle* dbhandle, SECItem* crlKey)
}
/* add the specified RAM CRL object to the cache */
-SECStatus CERT_CacheCRL(CERTCertDBHandle* dbhandle, SECItem* newdercrl)
+SECStatus
+CERT_CacheCRL(CERTCertDBHandle* dbhandle, SECItem* newdercrl)
{
CRLDPCache* cache = NULL;
SECStatus rv = SECSuccess;
@@ -2801,9 +2537,8 @@ SECStatus CERT_CacheCRL(CERTCertDBHandle* dbhandle, SECItem* newdercrl)
PRBool added = PR_FALSE;
CERTSignedCrl* newcrl = NULL;
int realerror = 0;
-
- if (!dbhandle || !newdercrl)
- {
+
+ if (!dbhandle || !newdercrl) {
PORT_SetError(SEC_ERROR_INVALID_ARGS);
return SECFailure;
}
@@ -2811,55 +2546,49 @@ SECStatus CERT_CacheCRL(CERTCertDBHandle* dbhandle, SECItem* newdercrl)
/* 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);
+ CRL_DECODE_SKIP_ENTRIES);
- if (!newcrl)
- {
+ 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 = 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)
- {
+ if (SECSuccess == rv && returned) {
DPCache_LockWrite();
rv = DPCache_AddCRL(cache, returned, &added);
- if (PR_TRUE != added)
- {
+ if (PR_TRUE != added) {
realerror = PORT_GetError();
CachedCrl_Destroy(returned);
returned = NULL;
}
DPCache_UnlockWrite();
}
-
+
ReleaseDPCache(cache, writeLocked);
-
- if (!added)
- {
+
+ 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)
- {
+ if (realerror) {
PORT_SetError(realerror);
}
return rv;
}
/* remove the specified RAM CRL object from the cache */
-SECStatus CERT_UncacheCRL(CERTCertDBHandle* dbhandle, SECItem* olddercrl)
+SECStatus
+CERT_UncacheCRL(CERTCertDBHandle* dbhandle, SECItem* olddercrl)
{
CRLDPCache* cache = NULL;
SECStatus rv = SECSuccess;
@@ -2868,9 +2597,8 @@ SECStatus CERT_UncacheCRL(CERTCertDBHandle* dbhandle, SECItem* olddercrl)
PRBool removed = PR_FALSE;
PRUint32 i;
CERTSignedCrl* oldcrl = NULL;
-
- if (!dbhandle || !olddercrl)
- {
+
+ if (!dbhandle || !olddercrl) {
PORT_SetError(SEC_ERROR_INVALID_ARGS);
return SECFailure;
}
@@ -2878,39 +2606,32 @@ SECStatus CERT_UncacheCRL(CERTCertDBHandle* dbhandle, SECItem* olddercrl)
/* 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);
+ CRL_DECODE_SKIP_ENTRIES);
- if (!oldcrl)
- {
+ 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)
- {
+ 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);
-
+ readlocked = (writeLocked == PR_TRUE ? PR_FALSE : PR_TRUE);
+
rv = CachedCrl_Create(&returned, oldcrl, CRL_OriginExplicit);
- if (SECSuccess == rv && returned)
- {
+ if (SECSuccess == rv && returned) {
DPCache_LockWrite();
- for (i=0;i<cache->ncrls;i++)
- {
+ 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)
- {
+ rv = CachedCrl_Compare(returned, cache->crls[i], &dupe,
+ &updated);
+ if (SECSuccess != rv) {
PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
break;
}
- if (PR_TRUE == dupe)
- {
+ if (PR_TRUE == dupe) {
rv = DPCache_RemoveCRL(cache, i); /* got a match */
if (SECSuccess == rv) {
cache->mustchoose = PR_TRUE;
@@ -2919,32 +2640,31 @@ SECStatus CERT_UncacheCRL(CERTCertDBHandle* dbhandle, SECItem* olddercrl)
break;
}
}
-
+
DPCache_UnlockWrite();
- if (SECSuccess != CachedCrl_Destroy(returned) ) {
+ if (SECSuccess != CachedCrl_Destroy(returned)) {
rv = SECFailure;
}
}
ReleaseDPCache(cache, writeLocked);
}
- if (SECSuccess != SEC_DestroyCrl(oldcrl) ) {
+ if (SECSuccess != SEC_DestroyCrl(oldcrl)) {
/* need to do this because object is refcounted */
rv = SECFailure;
}
- if (SECSuccess == rv && PR_TRUE != removed)
- {
+ if (SECSuccess == rv && PR_TRUE != removed) {
PORT_SetError(SEC_ERROR_CRL_NOT_FOUND);
}
return rv;
}
-SECStatus cert_AcquireNamedCRLCache(NamedCRLCache** returned)
+SECStatus
+cert_AcquireNamedCRLCache(NamedCRLCache** returned)
{
PORT_Assert(returned);
- if (!namedCRLCache.lock)
- {
+ if (!namedCRLCache.lock) {
PORT_Assert(0);
return SECFailure;
}
@@ -2956,28 +2676,26 @@ SECStatus cert_AcquireNamedCRLCache(NamedCRLCache** returned)
/* 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)
+SECStatus
+cert_FindCRLByGeneralName(NamedCRLCache* ncc, const SECItem* canonicalizedName,
+ NamedCRLCacheEntry** retEntry)
{
- if (!ncc || !canonicalizedName || !retEntry)
- {
+ if (!ncc || !canonicalizedName || !retEntry) {
PORT_SetError(SEC_ERROR_INVALID_ARGS);
return SECFailure;
}
- *retEntry = (NamedCRLCacheEntry*) PL_HashTableLookup(namedCRLCache.entries,
- (void*) canonicalizedName);
+ *retEntry = (NamedCRLCacheEntry*)PL_HashTableLookup(
+ namedCRLCache.entries, (void*)canonicalizedName);
return SECSuccess;
}
-SECStatus cert_ReleaseNamedCRLCache(NamedCRLCache* ncc)
+SECStatus
+cert_ReleaseNamedCRLCache(NamedCRLCache* ncc)
{
- if (!ncc)
- {
+ if (!ncc) {
return SECFailure;
}
- if (!ncc->lock)
- {
+ if (!ncc->lock) {
PORT_Assert(0);
return SECFailure;
}
@@ -2986,16 +2704,15 @@ SECStatus cert_ReleaseNamedCRLCache(NamedCRLCache* ncc)
}
/* 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)
+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)
- {
+ if (SECSuccess != NamedCRLCacheEntry_Create(newEntry) || !*newEntry) {
/* no need to keep unused CRL around */
SECITEM_ZfreeItem(crl, PR_TRUE);
return SECFailure;
@@ -3004,22 +2721,17 @@ static SECStatus addCRLToCache(CERTCertDBHandle* dbhandle, SECItem* crl,
entry->crl = crl; /* named CRL cache owns DER */
entry->lastAttemptTime = PR_Now();
entry->canonicalizedName = SECITEM_DupItem(canonicalizedName);
- if (!entry->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))
- {
+ if (SECSuccess == CERT_CacheCRL(dbhandle, entry->crl)) {
entry->inCRLCache = PR_TRUE;
entry->successfulInsertionTime = entry->lastAttemptTime;
- }
- else
- {
- switch (PR_GetError())
- {
+ } else {
+ switch (PR_GetError()) {
case SEC_ERROR_CRL_ALREADY_EXISTS:
entry->dupe = PR_TRUE;
break;
@@ -3044,18 +2756,18 @@ static SECStatus addCRLToCache(CERTCertDBHandle* dbhandle, SECItem* crl,
/* 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)
+SECStatus
+cert_CacheCRLByGeneralName(CERTCertDBHandle* dbhandle, SECItem* crl,
+ const SECItem* canonicalizedName)
{
- NamedCRLCacheEntry* oldEntry, * newEntry = NULL;
+ NamedCRLCacheEntry *oldEntry, *newEntry = NULL;
NamedCRLCache* ncc = NULL;
SECStatus rv = SECSuccess;
PORT_Assert(namedCRLCache.lock);
PORT_Assert(namedCRLCache.entries);
- if (!crl || !canonicalizedName)
- {
+ if (!crl || !canonicalizedName) {
PORT_Assert(0);
PORT_SetError(SEC_ERROR_INVALID_ARGS);
return SECFailure;
@@ -3063,106 +2775,84 @@ SECStatus cert_CacheCRLByGeneralName(CERTCertDBHandle* dbhandle, SECItem* crl,
rv = cert_AcquireNamedCRLCache(&ncc);
PORT_Assert(SECSuccess == rv);
- if (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);
+ if (SECSuccess != rv) {
+ (void)cert_ReleaseNamedCRLCache(ncc);
SECITEM_ZfreeItem(crl, PR_TRUE);
return SECFailure;
}
- if (SECSuccess == addCRLToCache(dbhandle, crl, canonicalizedName,
- &newEntry) )
- {
- if (!oldEntry)
- {
+ 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))
- {
+ (void*)newEntry->canonicalizedName,
+ (void*)newEntry)) {
PORT_Assert(0);
NamedCRLCacheEntry_Destroy(newEntry);
rv = SECFailure;
}
- }
- else
- {
+ } else {
PRBool removed;
/* remove the old CRL from the cache if needed */
- if (oldEntry->inCRLCache)
- {
+ if (oldEntry->inCRLCache) {
rv = CERT_UncacheCRL(dbhandle, oldEntry->crl);
PORT_Assert(SECSuccess == rv);
}
removed = PL_HashTableRemove(namedCRLCache.entries,
- (void*) oldEntry->canonicalizedName);
+ (void*)oldEntry->canonicalizedName);
PORT_Assert(removed);
- if (!removed)
- {
+ if (!removed) {
rv = SECFailure;
- /* leak old entry since we couldn't remove it from the hash table */
- }
- else
- {
+ /* leak old entry since we couldn't remove it from the hash
+ * table */
+ } else {
PORT_CheckSuccess(NamedCRLCacheEntry_Destroy(oldEntry));
}
if (NULL == PL_HashTableAdd(namedCRLCache.entries,
- (void*) newEntry->canonicalizedName,
- (void*) newEntry))
- {
+ (void*)newEntry->canonicalizedName,
+ (void*)newEntry)) {
PORT_Assert(0);
rv = SECFailure;
}
}
- } else
- {
+ } else {
/* error adding new CRL to cache */
- if (!oldEntry)
- {
+ 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))
- {
+ (void*)newEntry->canonicalizedName,
+ (void*)newEntry)) {
PORT_Assert(0);
rv = SECFailure;
}
- }
- else
- {
- if (oldEntry->inCRLCache)
- {
+ } else {
+ if (oldEntry->inCRLCache) {
/* previous cache entry was good, keep it and update time */
- oldEntry-> lastAttemptTime = newEntry->lastAttemptTime;
+ oldEntry->lastAttemptTime = newEntry->lastAttemptTime;
/* throw away new bad entry */
rv = NamedCRLCacheEntry_Destroy(newEntry);
PORT_Assert(SECSuccess == rv);
- }
- else
- {
+ } else {
/* previous cache entry was bad, just replace it */
- PRBool removed = PL_HashTableRemove(namedCRLCache.entries,
- (void*) oldEntry->canonicalizedName);
+ 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 */
+ if (!removed) {
+ /* leak old entry since we couldn't remove it from the hash
+ * table */
rv = SECFailure;
- }
- else
- {
+ } else {
PORT_CheckSuccess(NamedCRLCacheEntry_Destroy(oldEntry));
}
if (NULL == PL_HashTableAdd(namedCRLCache.entries,
- (void*) newEntry->canonicalizedName,
- (void*) newEntry))
- {
+ (void*)newEntry->canonicalizedName,
+ (void*)newEntry)) {
PORT_Assert(0);
rv = SECFailure;
}
@@ -3174,18 +2864,16 @@ SECStatus cert_CacheCRLByGeneralName(CERTCertDBHandle* dbhandle, SECItem* crl,
return rv;
}
-static SECStatus CachedCrl_Create(CachedCrl** returned, CERTSignedCrl* crl,
- CRLOrigin origin)
+static SECStatus
+CachedCrl_Create(CachedCrl** returned, CERTSignedCrl* crl, CRLOrigin origin)
{
CachedCrl* newcrl = NULL;
- if (!returned)
- {
+ if (!returned) {
PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
return SECFailure;
}
newcrl = PORT_ZAlloc(sizeof(CachedCrl));
- if (!newcrl)
- {
+ if (!newcrl) {
return SECFailure;
}
newcrl->crl = SEC_DupCrl(crl);
@@ -3195,33 +2883,31 @@ static SECStatus CachedCrl_Create(CachedCrl** returned, CERTSignedCrl* crl,
}
/* empty the cache content */
-static SECStatus CachedCrl_Depopulate(CachedCrl* crl)
+static SECStatus
+CachedCrl_Depopulate(CachedCrl* crl)
{
- if (!crl)
- {
+ if (!crl) {
PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
return SECFailure;
}
- /* destroy the hash table */
- if (crl->entries)
- {
+ /* destroy the hash table */
+ if (crl->entries) {
PL_HashTableDestroy(crl->entries);
crl->entries = NULL;
}
/* free the pre buffer */
- if (crl->prebuffer)
- {
+ if (crl->prebuffer) {
PreAllocator_Destroy(crl->prebuffer);
crl->prebuffer = NULL;
}
return SECSuccess;
}
-static SECStatus CachedCrl_Destroy(CachedCrl* crl)
+static SECStatus
+CachedCrl_Destroy(CachedCrl* crl)
{
- if (!crl)
- {
+ if (!crl) {
PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
return SECFailure;
}
@@ -3232,56 +2918,52 @@ static SECStatus CachedCrl_Destroy(CachedCrl* crl)
}
/* create hash table of CRL entries */
-static SECStatus CachedCrl_Populate(CachedCrl* crlobject)
+static SECStatus
+CachedCrl_Populate(CachedCrl* crlobject)
{
SECStatus rv = SECFailure;
CERTCrlEntry** crlEntry = NULL;
PRUint32 numEntries = 0;
- if (!crlobject)
- {
+ 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)
- {
+ if (SECSuccess != rv) {
crlobject->unbuildable = PR_TRUE; /* don't try to build this again */
return SECFailure;
}
- if (crlobject->entries && crlobject->prebuffer)
- {
+ if (crlobject->entries && crlobject->prebuffer) {
/* cache is already built */
return SECSuccess;
}
- /* build the hash table from the full CRL */
+ /* 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++)
- {
+ crlEntry++) {
numEntries++;
}
- crlobject->prebuffer = PreAllocator_Create(numEntries*sizeof(PLHashEntry));
+ crlobject->prebuffer =
+ PreAllocator_Create(numEntries * sizeof(PLHashEntry));
PORT_Assert(crlobject->prebuffer);
- if (!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);
+ crlobject->entries =
+ PL_NewHashTable(0, SECITEM_Hash, SECITEM_HashCompare, PL_CompareValues,
+ &preAllocOps, crlobject->prebuffer);
PORT_Assert(crlobject->entries);
- if (!crlobject->entries)
- {
+ if (!crlobject->entries) {
return SECFailure;
}
/* add all serial numbers to the hash table */
for (crlEntry = crlobject->crl->crl.entries; crlEntry && *crlEntry;
- crlEntry++)
- {
+ crlEntry++) {
PL_HashTableAdd(crlobject->entries, &(*crlEntry)->serialNumber,
*crlEntry);
}
@@ -3290,14 +2972,13 @@ static SECStatus CachedCrl_Populate(CachedCrl* crlobject)
}
/* returns true if there are CRLs from PKCS#11 slots */
-static PRBool DPCache_HasTokenCRLs(CRLDPCache* cache)
+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) )
- {
+ for (i = 0; i < cache->ncrls; i++) {
+ if (cache->crls[i] && (CRL_OriginToken == cache->crls[i]->origin)) {
answer = PR_TRUE;
break;
}
@@ -3310,63 +2991,53 @@ static PRBool DPCache_HasTokenCRLs(CRLDPCache* cache)
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)
+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)
- {
+ if (!a || !b || !isDupe || !isUpdated || !a->crl || !b->crl) {
PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
return SECFailure;
}
*isDupe = *isUpdated = PR_FALSE;
- if (a == b)
- {
+ if (a == b) {
/* dupe */
*isDupe = PR_TRUE;
*isUpdated = PR_FALSE;
return SECSuccess;
}
- if (b->origin != a->origin)
- {
+ 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)
- {
+ 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) )
- {
+ 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) )
- {
+ if (SECEqual ==
+ SECITEM_CompareItem(b->crl->derCrl, a->crl->derCrl)) {
*isDupe = PR_TRUE;
- }
- else
- {
+ } else {
*isUpdated = PR_TRUE;
}
}
return SECSuccess;
}
- if (CRL_OriginExplicit == b->origin)
- {
+ 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)
- {
+ if (b->crl->derCrl == a->crl->derCrl) {
*isDupe = PR_TRUE;
}
}
diff --git a/nss/lib/certdb/exports.gyp b/nss/lib/certdb/exports.gyp
new file mode 100644
index 0000000..359c930
--- /dev/null
+++ b/nss/lib/certdb/exports.gyp
@@ -0,0 +1,36 @@
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+{
+ 'includes': [
+ '../../coreconf/config.gypi'
+ ],
+ 'targets': [
+ {
+ 'target_name': 'lib_certdb_exports',
+ 'type': 'none',
+ 'copies': [
+ {
+ 'files': [
+ 'cert.h',
+ 'certdb.h',
+ 'certt.h'
+ ],
+ 'destination': '<(nss_public_dist_dir)/<(module)'
+ },
+ {
+ 'files': [
+ 'certi.h',
+ 'certxutl.h',
+ 'genname.h',
+ 'xconst.h'
+ ],
+ 'destination': '<(nss_private_dist_dir)/<(module)'
+ }
+ ]
+ }
+ ],
+ 'variables': {
+ 'module': 'nss'
+ }
+}
diff --git a/nss/lib/certdb/genname.c b/nss/lib/certdb/genname.c
index 6529a6a..b8f6654 100644
--- a/nss/lib/certdb/genname.c
+++ b/nss/lib/certdb/genname.c
@@ -26,13 +26,11 @@ 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, }
+ { 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[] = {
@@ -41,119 +39,108 @@ const SEC_ASN1Template CERT_NameConstraintSubtreeSubTemplate[] = {
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, }
+ { 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_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, }
+ 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,
+ { SEC_ASN1_CONTEXT_SPECIFIC | SEC_ASN1_CONSTRUCTED | 0,
+ offsetof(CERTGeneralName, name.OthName), CERTOthNameTemplate,
sizeof(CERTGeneralName) }
};
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)}
+ { 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)}
+ { 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)}
+ 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)}
+ 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)}
+ 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)}
+ { 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)}
+ { 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)}
+ { 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) }
+ { SEC_ASN1_SEQUENCE_OF | SEC_ASN1_XTRN, 0, SEC_ASN1_SUB(SEC_AnyTemplate) }
};
-
static struct {
CERTGeneralNameType type;
char *name;
-} typesArray[] = {
- { certOtherName, "other" },
- { certRFC822Name, "email" },
- { certRFC822Name, "rfc822" },
- { certDNSName, "dns" },
- { certX400Address, "x400" },
- { certX400Address, "x400addr" },
- { certDirectoryName, "directory" },
- { certDirectoryName, "dn" },
- { certEDIPartyName, "edi" },
- { certEDIPartyName, "ediparty" },
- { certURI, "uri" },
- { certIPAddress, "ip" },
- { certIPAddress, "ipaddr" },
- { certRegisterID, "registerid" }
-};
+} typesArray[] = { { certOtherName, "other" },
+ { certRFC822Name, "email" },
+ { certRFC822Name, "rfc822" },
+ { certDNSName, "dns" },
+ { certX400Address, "x400" },
+ { certX400Address, "x400addr" },
+ { certDirectoryName, "directory" },
+ { certDirectoryName, "dn" },
+ { certEDIPartyName, "edi" },
+ { certEDIPartyName, "ediparty" },
+ { certURI, "uri" },
+ { certIPAddress, "ip" },
+ { certIPAddress, "ipaddr" },
+ { certRegisterID, "registerid" } };
CERTGeneralNameType
CERT_GetGeneralNameTypeFromString(const char *string)
{
- int types_count = sizeof(typesArray)/sizeof(typesArray[0]);
+ int types_count = sizeof(typesArray) / sizeof(typesArray[0]);
int i;
- for (i=0; i < types_count; i++) {
+ for (i = 0; i < types_count; i++) {
if (PORT_Strcasecmp(string, typesArray[i].name) == 0) {
return typesArray[i].type;
}
@@ -164,12 +151,11 @@ CERT_GetGeneralNameTypeFromString(const char *string)
CERTGeneralName *
CERT_NewGeneralName(PLArenaPool *arena, CERTGeneralNameType type)
{
- CERTGeneralName *name = arena
- ? PORT_ArenaZNew(arena, CERTGeneralName)
- : PORT_ZNew(CERTGeneralName);
+ CERTGeneralName *name = arena ? PORT_ArenaZNew(arena, CERTGeneralName)
+ : PORT_ZNew(CERTGeneralName);
if (name) {
- name->type = type;
- name->l.prev = name->l.next = &name->l;
+ name->type = type;
+ name->l.prev = name->l.next = &name->l;
}
return name;
}
@@ -179,9 +165,8 @@ CERT_NewGeneralName(PLArenaPool *arena, CERTGeneralNameType type)
** This function does not change the destinate's GeneralName's list linkage.
*/
SECStatus
-cert_CopyOneGeneralName(PLArenaPool *arena,
- CERTGeneralName *dest,
- CERTGeneralName *src)
+cert_CopyOneGeneralName(PLArenaPool *arena, CERTGeneralName *dest,
+ CERTGeneralName *src)
{
SECStatus rv;
void *mark = NULL;
@@ -192,27 +177,25 @@ cert_CopyOneGeneralName(PLArenaPool *arena,
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;
-
+ 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);
@@ -222,50 +205,50 @@ cert_CopyOneGeneralName(PLArenaPool *arena,
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);
- }
+ 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) {
+CERT_CreateGeneralNameList(CERTGeneralName *name)
+{
PLArenaPool *arena;
CERTGeneralNameList *list = NULL;
arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
if (arena == NULL) {
- goto done;
+ goto done;
}
list = PORT_ArenaZNew(arena, CERTGeneralNameList);
if (!list)
- goto loser;
+ 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;
+ 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;
+ goto loser;
list->arena = arena;
list->refCount = 1;
done:
@@ -280,9 +263,9 @@ CERTGeneralName *
CERT_GetNextGeneralName(CERTGeneralName *current)
{
PRCList *next;
-
+
next = current->l.next;
- return (CERTGeneralName *) (((char *) next) - offsetof(CERTGeneralName, l));
+ return (CERTGeneralName *)(((char *)next) - offsetof(CERTGeneralName, l));
}
CERTGeneralName *
@@ -290,16 +273,17 @@ CERT_GetPrevGeneralName(CERTGeneralName *current)
{
PRCList *prev;
prev = current->l.prev;
- return (CERTGeneralName *) (((char *) prev) - offsetof(CERTGeneralName, l));
+ 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));
+ return (CERTNameConstraint *)(((char *)next) -
+ offsetof(CERTNameConstraint, l));
}
CERTNameConstraint *
@@ -307,58 +291,78 @@ CERT_GetPrevNameConstraint(CERTNameConstraint *current)
{
PRCList *prev;
prev = current->l.prev;
- return (CERTNameConstraint *) (((char *) prev) - offsetof(CERTNameConstraint, l));
+ return (CERTNameConstraint *)(((char *)prev) -
+ offsetof(CERTNameConstraint, l));
}
SECItem *
-CERT_EncodeGeneralName(CERTGeneralName *genName, SECItem *dest, PLArenaPool *arena)
+CERT_EncodeGeneralName(CERTGeneralName *genName, SECItem *dest,
+ PLArenaPool *arena)
{
- const SEC_ASN1Template * template;
+ const SEC_ASN1Template *template;
PORT_Assert(arena);
- if (arena == NULL) {
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- return NULL;
+ if (arena == NULL || !genName) {
+ PORT_SetError(SEC_ERROR_INVALID_ARGS);
+ return NULL;
}
/* TODO: mark arena */
if (dest == NULL) {
- dest = PORT_ArenaZNew(arena, SECItem);
- if (!dest)
- goto loser;
+ 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 (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;
- }
+ }
+ 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;
+ 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;
+ goto loser;
}
/* TODO: unmark arena */
return dest;
@@ -370,34 +374,35 @@ loser:
SECItem **
cert_EncodeGeneralNames(PLArenaPool *arena, CERTGeneralName *names)
{
- CERTGeneralName *current_name;
- SECItem **items = NULL;
- int count = 0;
- int i;
- PRCList *head;
+ CERTGeneralName *current_name;
+ SECItem **items = NULL;
+ int count = 1;
+ int i;
+ PRCList *head;
+
+ if (!names) {
+ return NULL;
+ }
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);
+ ++count;
}
current_name = CERT_GetNextGeneralName(current_name);
items = PORT_ArenaNewArray(arena, SECItem *, count + 1);
if (items == NULL) {
- goto loser;
+ 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] = 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 */
@@ -408,14 +413,13 @@ loser:
}
CERTGeneralName *
-CERT_DecodeGeneralName(PLArenaPool *reqArena,
- SECItem *encodedName,
- CERTGeneralName *genName)
+CERT_DecodeGeneralName(PLArenaPool *reqArena, SECItem *encodedName,
+ CERTGeneralName *genName)
{
- const SEC_ASN1Template * template;
- CERTGeneralNameType genNameType;
- SECStatus rv = SECSuccess;
- SECItem* newEncodedName;
+ const SEC_ASN1Template *template;
+ CERTGeneralNameType genNameType;
+ SECStatus rv = SECSuccess;
+ SECItem *newEncodedName;
if (!reqArena) {
PORT_SetError(SEC_ERROR_INVALID_ARGS);
@@ -430,36 +434,54 @@ CERT_DecodeGeneralName(PLArenaPool *reqArena,
/* TODO: mark arena */
genNameType = (CERTGeneralNameType)((*(newEncodedName->data) & 0x0f) + 1);
if (genName == NULL) {
- genName = CERT_NewGeneralName(reqArena, genNameType);
- if (!genName)
- goto loser;
+ genName = CERT_NewGeneralName(reqArena, genNameType);
+ if (!genName)
+ goto loser;
} else {
- genName->type = genNameType;
- genName->l.prev = genName->l.next = &genName->l;
+ 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;
+ 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 (rv != SECSuccess)
+ goto loser;
if (genNameType == certDirectoryName) {
- rv = SEC_QuickDERDecodeItem(reqArena, &(genName->name.directoryName),
- CERT_NameTemplate,
- &(genName->derDirectoryName));
+ rv = SEC_QuickDERDecodeItem(reqArena, &(genName->name.directoryName),
+ CERT_NameTemplate,
+ &(genName->derDirectoryName));
if (rv != SECSuccess)
- goto loser;
+ goto loser;
}
/* TODO: unmark arena */
@@ -470,35 +492,34 @@ loser:
}
CERTGeneralName *
-cert_DecodeGeneralNames (PLArenaPool *arena,
- SECItem **encodedGenName)
+cert_DecodeGeneralNames(PLArenaPool *arena, SECItem **encodedGenName)
{
- PRCList *head = NULL;
- PRCList *tail = NULL;
- CERTGeneralName *currentName = NULL;
+ PRCList *head = NULL;
+ PRCList *tail = NULL;
+ CERTGeneralName *currentName = NULL;
PORT_Assert(arena);
if (!encodedGenName || !arena) {
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- return NULL;
+ 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++;
+ 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: unmark arena */
+ return CERT_GetNextGeneralName(currentName);
}
/* TODO: release arena to mark */
return NULL;
@@ -513,76 +534,73 @@ CERT_DestroyGeneralName(CERTGeneralName *name)
SECStatus
cert_DestroyGeneralNames(CERTGeneralName *name)
{
- CERTGeneralName *first;
- CERTGeneralName *next = NULL;
-
+ CERTGeneralName *first;
+ CERTGeneralName *next = NULL;
first = name;
do {
- next = CERT_GetNextGeneralName(name);
- PORT_Free(name);
- name = next;
+ next = CERT_GetNextGeneralName(name);
+ PORT_Free(name);
+ name = next;
} while (name != first);
return SECSuccess;
}
static SECItem *
-cert_EncodeNameConstraint(CERTNameConstraint *constraint,
- SECItem *dest,
- PLArenaPool *arena)
+cert_EncodeNameConstraint(CERTNameConstraint *constraint, SECItem *dest,
+ PLArenaPool *arena)
{
PORT_Assert(arena);
if (dest == NULL) {
- dest = PORT_ArenaZNew(arena, SECItem);
- if (dest == NULL) {
- return 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);
+
+ dest =
+ SEC_ASN1EncodeItem(arena, dest, constraint, CERTNameConstraintTemplate);
return dest;
-}
+}
-SECStatus
-cert_EncodeNameConstraintSubTree(CERTNameConstraint *constraints,
- PLArenaPool *arena,
- SECItem ***dest,
- PRBool permited)
+SECStatus
+cert_EncodeNameConstraintSubTree(CERTNameConstraint *constraints,
+ PLArenaPool *arena, SECItem ***dest,
+ PRBool permited)
{
- CERTNameConstraint *current_constraint = constraints;
- SECItem **items = NULL;
- int count = 0;
- int i;
- PRCList *head;
+ 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;
+ count = 1;
}
head = &constraints->l;
while (current_constraint->l.next != head) {
- current_constraint = CERT_GetNextNameConstraint(current_constraint);
- ++count;
+ 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;
+ 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);
+ 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;
+ goto loser;
}
/* TODO: unmark arena */
return SECSuccess;
@@ -591,35 +609,32 @@ loser:
return SECFailure;
}
-SECStatus
-cert_EncodeNameConstraints(CERTNameConstraints *constraints,
- PLArenaPool *arena,
- SECItem *dest)
+SECStatus
+cert_EncodeNameConstraints(CERTNameConstraints *constraints, PLArenaPool *arena,
+ SECItem *dest)
{
- SECStatus rv = SECSuccess;
+ 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;
- }
+ 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;
- }
+ rv = cert_EncodeNameConstraintSubTree(
+ constraints->excluded, arena, &constraints->DERExcluded, PR_FALSE);
+ if (rv == SECFailure) {
+ goto loser;
+ }
}
- dest = SEC_ASN1EncodeItem(arena, dest, constraints,
- CERTNameConstraintsTemplate);
+ dest = SEC_ASN1EncodeItem(arena, dest, constraints,
+ CERTNameConstraintsTemplate);
if (dest == NULL) {
- goto loser;
+ goto loser;
}
/* TODO: unmark arena */
return SECSuccess;
@@ -628,15 +643,13 @@ loser:
return SECFailure;
}
-
CERTNameConstraint *
-cert_DecodeNameConstraint(PLArenaPool *reqArena,
- SECItem *encodedConstraint)
+cert_DecodeNameConstraint(PLArenaPool *reqArena, SECItem *encodedConstraint)
{
- CERTNameConstraint *constraint;
- SECStatus rv = SECSuccess;
- CERTGeneralName *temp;
- SECItem* newEncodedConstraint;
+ CERTNameConstraint *constraint;
+ SECStatus rv = SECSuccess;
+ CERTGeneralName *temp;
+ SECItem *newEncodedConstraint;
if (!reqArena) {
PORT_SetError(SEC_ERROR_INVALID_ARGS);
@@ -649,21 +662,20 @@ cert_DecodeNameConstraint(PLArenaPool *reqArena,
/* TODO: mark arena */
constraint = PORT_ArenaZNew(reqArena, CERTNameConstraint);
if (!constraint)
- goto loser;
- rv = SEC_QuickDERDecodeItem(reqArena, constraint,
- CERTNameConstraintTemplate,
- newEncodedConstraint);
+ goto loser;
+ rv = SEC_QuickDERDecodeItem(
+ reqArena, constraint, CERTNameConstraintTemplate, newEncodedConstraint);
if (rv != SECSuccess) {
- goto loser;
+ goto loser;
}
temp = CERT_DecodeGeneralName(reqArena, &(constraint->DERName),
&(constraint->name));
if (temp != &(constraint->name)) {
- goto loser;
+ goto loser;
}
- /* ### sjlee: since the name constraint contains only one
- * CERTGeneralName, the list within CERTGeneralName shouldn't
+ /* ### 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);
@@ -675,33 +687,34 @@ loser:
}
static CERTNameConstraint *
-cert_DecodeNameConstraintSubTree(PLArenaPool *arena,
- SECItem **subTree,
- PRBool permited)
+cert_DecodeNameConstraintSubTree(PLArenaPool *arena, SECItem **subTree,
+ PRBool permited)
{
- CERTNameConstraint *current = NULL;
- CERTNameConstraint *first = NULL;
- CERTNameConstraint *last = NULL;
- int i = 0;
+ 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 (first == NULL) {
- first = current;
- } else {
- current->l.prev = &(last->l);
- last->l.next = &(current->l);
- }
- last = current;
- i++;
+ current = cert_DecodeNameConstraint(arena, subTree[i]);
+ if (current == NULL) {
+ goto loser;
+ }
+ if (first == NULL) {
+ first = current;
+ } else {
+ current->l.prev = &(last->l);
+ last->l.next = &(current->l);
+ }
+ last = current;
+ i++;
+ }
+ if (first && last) {
+ first->l.prev = &(last->l);
+ last->l.next = &(first->l);
}
- first->l.prev = &(last->l);
- last->l.next = &(first->l);
/* TODO: unmark arena */
return first;
loser:
@@ -710,12 +723,12 @@ loser:
}
CERTNameConstraints *
-cert_DecodeNameConstraints(PLArenaPool *reqArena,
- const SECItem *encodedConstraints)
+cert_DecodeNameConstraints(PLArenaPool *reqArena,
+ const SECItem *encodedConstraints)
{
- CERTNameConstraints *constraints;
- SECStatus rv;
- SECItem* newEncodedConstraints;
+ CERTNameConstraints *constraints;
+ SECStatus rv;
+ SECItem *newEncodedConstraints;
if (!reqArena) {
PORT_SetError(SEC_ERROR_INVALID_ARGS);
@@ -727,33 +740,29 @@ cert_DecodeNameConstraints(PLArenaPool *reqArena,
/* TODO: mark arena */
constraints = PORT_ArenaZNew(reqArena, CERTNameConstraints);
if (constraints == NULL) {
- goto loser;
+ goto loser;
}
rv = SEC_QuickDERDecodeItem(reqArena, constraints,
CERTNameConstraintsTemplate,
newEncodedConstraints);
if (rv != SECSuccess) {
- goto loser;
+ goto loser;
}
- if (constraints->DERPermited != NULL &&
+ if (constraints->DERPermited != NULL &&
constraints->DERPermited[0] != NULL) {
- constraints->permited =
- cert_DecodeNameConstraintSubTree(reqArena,
- constraints->DERPermited,
- PR_TRUE);
- if (constraints->permited == NULL) {
- goto loser;
- }
+ constraints->permited = cert_DecodeNameConstraintSubTree(
+ reqArena, constraints->DERPermited, PR_TRUE);
+ if (constraints->permited == NULL) {
+ goto loser;
+ }
}
- if (constraints->DERExcluded != NULL &&
+ if (constraints->DERExcluded != NULL &&
constraints->DERExcluded[0] != NULL) {
- constraints->excluded =
- cert_DecodeNameConstraintSubTree(reqArena,
- constraints->DERExcluded,
- PR_FALSE);
- if (constraints->excluded == NULL) {
- goto loser;
- }
+ constraints->excluded = cert_DecodeNameConstraintSubTree(
+ reqArena, constraints->DERExcluded, PR_FALSE);
+ if (constraints->excluded == NULL) {
+ goto loser;
+ }
}
/* TODO: unmark arena */
return constraints;
@@ -763,22 +772,21 @@ loser:
}
/* Copy a chain of one or more general names to a destination chain.
-** Caller has allocated at least the first destination GeneralName struct.
+** 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 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
+** 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(PLArenaPool *arena,
- CERTGeneralName *dest,
- CERTGeneralName *src)
+CERT_CopyGeneralName(PLArenaPool *arena, CERTGeneralName *dest,
+ CERTGeneralName *src)
{
SECStatus rv;
CERTGeneralName *destHead = dest;
@@ -786,31 +794,31 @@ CERT_CopyGeneralName(PLArenaPool *arena,
PORT_Assert(dest != NULL);
if (!dest) {
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
+ 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);
- }
- }
+ 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;
@@ -819,49 +827,47 @@ loser:
return SECFailure;
}
-
CERTGeneralNameList *
CERT_DupGeneralNameList(CERTGeneralNameList *list)
{
if (list != NULL) {
- PZ_Lock(list->lock);
- list->refCount++;
- PZ_Unlock(list->lock);
+ PZ_Lock(list->lock);
+ list->refCount++;
+ PZ_Unlock(list->lock);
}
return list;
}
/* Allocate space and copy CERTNameConstraint from src to dest */
CERTNameConstraint *
-CERT_CopyNameConstraint(PLArenaPool *arena,
- CERTNameConstraint *dest,
- CERTNameConstraint *src)
+CERT_CopyNameConstraint(PLArenaPool *arena, CERTNameConstraint *dest,
+ CERTNameConstraint *src)
{
- SECStatus rv;
-
+ 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);
+ 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;
+ goto loser;
}
rv = SECITEM_CopyItem(arena, &dest->DERName, &src->DERName);
if (rv != SECSuccess) {
- goto loser;
+ goto loser;
}
rv = SECITEM_CopyItem(arena, &dest->min, &src->min);
if (rv != SECSuccess) {
- goto loser;
+ goto loser;
}
rv = SECITEM_CopyItem(arena, &dest->max, &src->max);
if (rv != SECSuccess) {
- goto loser;
+ goto loser;
}
dest->l.prev = dest->l.next = &dest->l;
/* TODO: unmark arena */
@@ -871,7 +877,6 @@ loser:
return NULL;
}
-
CERTGeneralName *
cert_CombineNamesLists(CERTGeneralName *list1, CERTGeneralName *list2)
{
@@ -880,54 +885,52 @@ cert_CombineNamesLists(CERTGeneralName *list1, CERTGeneralName *list2)
PRCList *end1;
PRCList *end2;
- if (list1 == NULL){
- return list2;
+ if (list1 == NULL) {
+ return list2;
} else if (list2 == NULL) {
- return list1;
+ 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;
+ 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)
+cert_CombineConstraintsLists(CERTNameConstraint *list1,
+ CERTNameConstraint *list2)
{
PRCList *begin1;
PRCList *begin2;
PRCList *end1;
PRCList *end2;
- if (list1 == NULL){
- return list2;
+ if (list1 == NULL) {
+ return list2;
} else if (list2 == NULL) {
- return list1;
+ 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;
+ 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)
+CERT_AddNameConstraint(CERTNameConstraint *list, CERTNameConstraint *constraint)
{
PORT_Assert(constraint != NULL);
constraint->l.next = constraint->l.prev = &constraint->l;
@@ -935,33 +938,32 @@ CERT_AddNameConstraint(CERTNameConstraint *list,
return list;
}
-
SECStatus
-CERT_GetNameConstraintByType (CERTNameConstraint *constraints,
- CERTGeneralNameType type,
- CERTNameConstraint **returnList,
- PLArenaPool *arena)
+CERT_GetNameConstraintByType(CERTNameConstraint *constraints,
+ CERTGeneralNameType type,
+ CERTNameConstraint **returnList,
+ PLArenaPool *arena)
{
CERTNameConstraint *current = NULL;
- void *mark = NULL;
+ void *mark = NULL;
*returnList = NULL;
if (!constraints)
- return SECSuccess;
+ 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);
+ 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;
@@ -972,39 +974,41 @@ loser:
}
void *
-CERT_GetGeneralNameByType (CERTGeneralName *genNames,
- CERTGeneralNameType type, PRBool derFormat)
+CERT_GetGeneralNameByType(CERTGeneralName *genNames, CERTGeneralNameType type,
+ PRBool derFormat)
{
CERTGeneralName *current;
-
+
if (!genNames)
- return NULL;
+ 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);
+ 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;
}
@@ -1012,62 +1016,63 @@ CERT_GetGeneralNameByType (CERTGeneralName *genNames,
int
CERT_GetNamesLength(CERTGeneralName *names)
{
- int length = 0;
- CERTGeneralName *first;
+ int length = 0;
+ CERTGeneralName *first;
first = names;
if (names != NULL) {
- do {
- length++;
- names = CERT_GetNextGeneralName(names);
- } while (names != first);
+ do {
+ length++;
+ names = CERT_GetNextGeneralName(names);
+ } while (names != first);
}
return length;
}
-/* Creates new GeneralNames for any email addresses found in the
+/* 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;
+ 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;
+ 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;
+ 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 */
+ 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);
+ (void)cert_CombineNamesLists(name, nameList);
/* TODO: unmark arena */
return SECSuccess;
@@ -1076,7 +1081,7 @@ loser:
return SECFailure;
}
-/* Extract all names except Subject Common Name from a cert
+/* Extract all names except Subject Common Name from a cert
** in preparation for a name constraints test.
*/
CERTGeneralName *
@@ -1093,30 +1098,30 @@ CERT_GetConstrainedCertificateNames(const CERTCertificate *cert,
PLArenaPool *arena,
PRBool includeSubjectCommonName)
{
- CERTGeneralName *DN;
- CERTGeneralName *SAN;
- PRUint32 numDNSNames = 0;
- SECStatus rv;
+ CERTGeneralName *DN;
+ CERTGeneralName *SAN;
+ PRUint32 numDNSNames = 0;
+ SECStatus rv;
if (!arena) {
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- return NULL;
+ PORT_SetError(SEC_ERROR_INVALID_ARGS);
+ return NULL;
}
/* TODO: mark arena */
DN = CERT_NewGeneralName(arena, certDirectoryName);
if (DN == NULL) {
- goto loser;
+ goto loser;
}
rv = CERT_CopyName(arena, &DN->name.directoryName, &cert->subject);
if (rv != SECSuccess) {
- goto loser;
+ goto loser;
}
rv = SECITEM_CopyItem(arena, &DN->derDirectoryName, &cert->derSubject);
if (rv != SECSuccess) {
- goto loser;
+ goto loser;
}
- /* Extract email addresses from DN, construct CERTGeneralName structs
- ** for them, add them to the name list
+ /* Extract email addresses from DN, construct CERTGeneralName structs
+ ** for them, add them to the name list
*/
rv = cert_ExtractDNEmailAddrs(DN, arena);
if (rv != SECSuccess)
@@ -1125,35 +1130,35 @@ CERT_GetConstrainedCertificateNames(const CERTCertificate *cert,
/* 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);
+ 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);
- }
+ 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;
+ /* TODO: unmark arena */
+ return DN;
}
loser:
/* TODO: release arena to mark */
return NULL;
}
-/* Returns SECSuccess if name matches constraint per RFC 3280 rules for
+/* 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:
@@ -1177,24 +1182,24 @@ compareURIN2C(const SECItem *name, const SECItem *constraint)
*/
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;
+ 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))
+ if (PL_strncasecmp((char *)(name->data + offset), (char *)constraint->data,
+ constraint->len))
return SECFailure;
- if (!offset ||
+ if (!offset ||
(name->data[offset - 1] == '.') + (constraint->data[0] == '.') == 1)
- return SECSuccess;
+ return SECSuccess;
return SECFailure;
}
@@ -1217,9 +1222,9 @@ compareURIN2C(const SECItem *name, const SECItem *constraint)
** 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
+** .foo.bar.com www..foo.bar.com matches probably not
**
-** We will try to conform to NIST's PKITS tests, and the unstated
+** We will try to conform to NIST's PKITS tests, and the unstated
** rules they imply.
*/
static SECStatus
@@ -1234,12 +1239,12 @@ compareDNSN2C(const SECItem *name, const SECItem *constraint)
if (name->len < constraint->len)
return SECFailure;
offset = name->len - constraint->len;
- if (PL_strncasecmp((char *)(name->data + offset),
- (char *)constraint->data, constraint->len))
+ if (PL_strncasecmp((char *)(name->data + offset), (char *)constraint->data,
+ constraint->len))
return SECFailure;
- if (!offset ||
+ if (!offset ||
(name->data[offset - 1] == '.') + (constraint->data[0] == '.') == 1)
- return SECSuccess;
+ return SECSuccess;
return SECFailure;
}
@@ -1247,7 +1252,7 @@ compareDNSN2C(const SECItem *name, const SECItem *constraint)
** 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,
+** 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.
*/
@@ -1262,16 +1267,17 @@ compareRFC822N2C(const SECItem *name, const SECItem *constraint)
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;
- }
+ 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))
+ if (PL_strncasecmp((char *)(name->data + offset), (char *)constraint->data,
+ constraint->len))
return SECFailure;
if (constraint->data[0] == '.')
return SECSuccess;
@@ -1282,9 +1288,9 @@ compareRFC822N2C(const SECItem *name, const SECItem *constraint)
/* 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
+** 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.
+** Return SECSuccess if they match, SECFailure if they don't.
*/
static SECStatus
compareIPaddrN2C(const SECItem *name, const SECItem *constraint)
@@ -1292,67 +1298,67 @@ 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->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;
+ 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
+/* 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.
+** but do not modify and data at item->data.
** If anything goes wrong, the contents of *item are undefined.
*/
static SECStatus
-parseUriHostname(SECItem * item)
+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;
- }
+ 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)
+ 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;
- }
+ 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; ) {
+ for (i = item->len; --i >= 0;) {
if (item->data[i] == ':') {
- item->len = i;
- break;
- }
+ 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;
- }
+ if (item->data[i] == '@') {
+ ++i;
+ item->data += i;
+ item->len -= i;
+ break;
+ }
}
return item->len ? SECSuccess : SECFailure;
}
@@ -1360,144 +1366,145 @@ parseUriHostname(SECItem * item)
/* 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 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(const CERTGeneralName *name,
- const CERTNameConstraint *constraints,
- PRBool excluded)
+cert_CompareNameWithConstraints(const CERTGeneralName *name,
+ const CERTNameConstraint *constraints,
+ PRBool excluded)
{
- SECStatus rv = SECSuccess;
- SECStatus matched = SECFailure;
+ SECStatus rv = SECSuccess;
+ SECStatus matched = SECFailure;
const CERTNameConstraint *current;
- PORT_Assert(constraints); /* caller should not call with NULL */
+ PORT_Assert(constraints); /* caller should not call with NULL */
if (!constraints) {
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
+ 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((CERTNameConstraint*)current);
+ 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((CERTNameConstraint *)current);
} while (current != constraints);
if (rv == SECSuccess) {
- if (matched == SECSuccess)
- rv = excluded ? SECFailure : SECSuccess;
- else
- rv = excluded ? SECSuccess : SECFailure;
- return rv;
+ if (matched == SECSuccess)
+ rv = excluded ? SECFailure : SECSuccess;
+ else
+ rv = excluded ? SECSuccess : SECFailure;
+ return rv;
}
return SECFailure;
@@ -1524,14 +1531,14 @@ CERT_AddNameConstraintByGeneralName(PLArenaPool *arena,
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);
@@ -1569,51 +1576,56 @@ done:
*
*/
-#define STRING_TO_SECITEM(str) \
-{ siBuffer, (unsigned char*) str, sizeof(str) - 1 }
+#define STRING_TO_SECITEM(str) \
+ { \
+ siBuffer, (unsigned char *)str, sizeof(str) - 1 \
+ }
-#define NAME_CONSTRAINTS_ENTRY(CA) \
- { \
- STRING_TO_SECITEM(CA ## _SUBJECT_DN), \
- STRING_TO_SECITEM(CA ## _NAME_CONSTRAINTS) \
+#define NAME_CONSTRAINTS_ENTRY(CA) \
+ { \
+ STRING_TO_SECITEM(CA##_SUBJECT_DN) \
+ , \
+ STRING_TO_SECITEM(CA##_NAME_CONSTRAINTS) \
}
/* Agence Nationale de la Securite des Systemes d'Information (ANSSI) */
-#define ANSSI_SUBJECT_DN \
- "\x30\x81\x85" \
- "\x31\x0B\x30\x09\x06\x03\x55\x04\x06\x13\x02" "FR" /* C */ \
- "\x31\x0F\x30\x0D\x06\x03\x55\x04\x08\x13\x06" "France" /* ST */ \
- "\x31\x0E\x30\x0C\x06\x03\x55\x04\x07\x13\x05" "Paris" /* L */ \
- "\x31\x10\x30\x0E\x06\x03\x55\x04\x0A\x13\x07" "PM/SGDN" /* O */ \
- "\x31\x0E\x30\x0C\x06\x03\x55\x04\x0B\x13\x05" "DCSSI" /* OU */ \
- "\x31\x0E\x30\x0C\x06\x03\x55\x04\x03\x13\x05" "IGC/A" /* CN */ \
- "\x31\x23\x30\x21\x06\x09\x2A\x86\x48\x86\xF7\x0D\x01\x09\x01" \
- "\x16\x14" "igca@sgdn.pm.gouv.fr" /* emailAddress */ \
-
-#define ANSSI_NAME_CONSTRAINTS \
- "\x30\x5D\xA0\x5B" \
- "\x30\x05\x82\x03" ".fr" \
- "\x30\x05\x82\x03" ".gp" \
- "\x30\x05\x82\x03" ".gf" \
- "\x30\x05\x82\x03" ".mq" \
- "\x30\x05\x82\x03" ".re" \
- "\x30\x05\x82\x03" ".yt" \
- "\x30\x05\x82\x03" ".pm" \
- "\x30\x05\x82\x03" ".bl" \
- "\x30\x05\x82\x03" ".mf" \
- "\x30\x05\x82\x03" ".wf" \
- "\x30\x05\x82\x03" ".pf" \
- "\x30\x05\x82\x03" ".nc" \
- "\x30\x05\x82\x03" ".tf" \
-
-static const SECItem builtInNameConstraints[][2] = {
- NAME_CONSTRAINTS_ENTRY(ANSSI)
-};
+/* clang-format off */
+
+#define ANSSI_SUBJECT_DN \
+ "\x30\x81\x85" \
+ "\x31\x0B\x30\x09\x06\x03\x55\x04\x06\x13\x02" "FR" /* C */ \
+ "\x31\x0F\x30\x0D\x06\x03\x55\x04\x08\x13\x06" "France" /* ST */ \
+ "\x31\x0E\x30\x0C\x06\x03\x55\x04\x07\x13\x05" "Paris" /* L */ \
+ "\x31\x10\x30\x0E\x06\x03\x55\x04\x0A\x13\x07" "PM/SGDN" /* O */ \
+ "\x31\x0E\x30\x0C\x06\x03\x55\x04\x0B\x13\x05" "DCSSI" /* OU */ \
+ "\x31\x0E\x30\x0C\x06\x03\x55\x04\x03\x13\x05" "IGC/A" /* CN */ \
+ "\x31\x23\x30\x21\x06\x09\x2A\x86\x48\x86\xF7\x0D\x01\x09\x01" \
+ "\x16\x14" "igca@sgdn.pm.gouv.fr" /* emailAddress */ \
+
+#define ANSSI_NAME_CONSTRAINTS \
+ "\x30\x5D\xA0\x5B" \
+ "\x30\x05\x82\x03" ".fr" \
+ "\x30\x05\x82\x03" ".gp" \
+ "\x30\x05\x82\x03" ".gf" \
+ "\x30\x05\x82\x03" ".mq" \
+ "\x30\x05\x82\x03" ".re" \
+ "\x30\x05\x82\x03" ".yt" \
+ "\x30\x05\x82\x03" ".pm" \
+ "\x30\x05\x82\x03" ".bl" \
+ "\x30\x05\x82\x03" ".mf" \
+ "\x30\x05\x82\x03" ".wf" \
+ "\x30\x05\x82\x03" ".pf" \
+ "\x30\x05\x82\x03" ".nc" \
+ "\x30\x05\x82\x03" ".tf"
+
+/* clang-format on */
+
+static const SECItem builtInNameConstraints[][2] = { NAME_CONSTRAINTS_ENTRY(
+ ANSSI) };
SECStatus
-CERT_GetImposedNameConstraints(const SECItem *derSubject,
- SECItem *extensions)
+CERT_GetImposedNameConstraints(const SECItem *derSubject, SECItem *extensions)
{
size_t i;
@@ -1624,8 +1636,7 @@ CERT_GetImposedNameConstraints(const SECItem *derSubject,
for (i = 0; i < PR_ARRAY_SIZE(builtInNameConstraints); ++i) {
if (SECITEM_ItemsAreEqual(derSubject, &builtInNameConstraints[i][0])) {
- return SECITEM_CopyItem(NULL,
- extensions,
+ return SECITEM_CopyItem(NULL, extensions,
&builtInNameConstraints[i][1]);
}
}
@@ -1634,24 +1645,23 @@ CERT_GetImposedNameConstraints(const SECItem *derSubject,
return SECFailure;
}
-/*
+/*
* Extract the name constraints extension from the CA cert.
* If the certificate contains no name constraints extension, but
* CERT_GetImposedNameConstraints returns a name constraints extension
* for the subject of the certificate, then that extension will be returned.
*/
SECStatus
-CERT_FindNameConstraintsExten(PLArenaPool *arena,
- CERTCertificate *cert,
+CERT_FindNameConstraintsExten(PLArenaPool *arena, CERTCertificate *cert,
CERTNameConstraints **constraints)
{
- SECStatus rv = SECSuccess;
- SECItem constraintsExtension;
- void *mark = NULL;
-
+ SECStatus rv = SECSuccess;
+ SECItem constraintsExtension;
+ void *mark = NULL;
+
*constraints = NULL;
- rv = CERT_FindCertExtension(cert, SEC_OID_X509_NAME_CONSTRAINTS,
+ rv = CERT_FindCertExtension(cert, SEC_OID_X509_NAME_CONSTRAINTS,
&constraintsExtension);
if (rv != SECSuccess) {
if (PORT_GetError() != SEC_ERROR_EXTENSION_NOT_FOUND) {
@@ -1660,10 +1670,10 @@ CERT_FindNameConstraintsExten(PLArenaPool *arena,
rv = CERT_GetImposedNameConstraints(&cert->derSubject,
&constraintsExtension);
if (rv != SECSuccess) {
- if (PORT_GetError() == SEC_ERROR_EXTENSION_NOT_FOUND) {
- return SECSuccess;
- }
- return rv;
+ if (PORT_GetError() == SEC_ERROR_EXTENSION_NOT_FOUND) {
+ return SECSuccess;
+ }
+ return rv;
}
}
@@ -1673,7 +1683,7 @@ CERT_FindNameConstraintsExten(PLArenaPool *arena,
if (*constraints == NULL) { /* decode failed */
rv = SECFailure;
}
- PORT_Free (constraintsExtension.data);
+ PORT_Free(constraintsExtension.data);
if (rv == SECFailure) {
PORT_ArenaRelease(arena, mark);
@@ -1688,42 +1698,39 @@ CERT_FindNameConstraintsExten(PLArenaPool *arena,
** the name.
*/
SECStatus
-CERT_CheckNameSpace(PLArenaPool *arena,
- const CERTNameConstraints *constraints,
- const CERTGeneralName *currentName)
+CERT_CheckNameSpace(PLArenaPool *arena, const CERTNameConstraints *constraints,
+ const CERTGeneralName *currentName)
{
- CERTNameConstraint *matchingConstraints;
- SECStatus rv = SECSuccess;
-
+ CERTNameConstraint *matchingConstraints;
+ SECStatus rv = SECSuccess;
+
if (constraints->excluded != NULL) {
- rv = CERT_GetNameConstraintByType(constraints->excluded,
- currentName->type,
+ rv = CERT_GetNameConstraintByType(constraints->excluded,
+ currentName->type,
&matchingConstraints, arena);
if (rv == SECSuccess && matchingConstraints != NULL) {
- rv = cert_CompareNameWithConstraints(currentName,
- matchingConstraints,
- PR_TRUE);
+ rv = cert_CompareNameWithConstraints(currentName,
+ matchingConstraints, PR_TRUE);
}
if (rv != SECSuccess) {
- return(rv);
+ return (rv);
}
}
-
+
if (constraints->permited != NULL) {
- rv = CERT_GetNameConstraintByType(constraints->permited,
- currentName->type,
+ rv = CERT_GetNameConstraintByType(constraints->permited,
+ currentName->type,
&matchingConstraints, arena);
if (rv == SECSuccess && matchingConstraints != NULL) {
- rv = cert_CompareNameWithConstraints(currentName,
- matchingConstraints,
- PR_FALSE);
+ rv = cert_CompareNameWithConstraints(currentName,
+ matchingConstraints, PR_FALSE);
}
if (rv != SECSuccess) {
- return(rv);
+ return (rv);
}
}
- return(SECSuccess);
+ return (SECSuccess);
}
/* Extract the name constraints extension from the CA cert.
@@ -1734,45 +1741,43 @@ CERT_CheckNameSpace(PLArenaPool *arena,
** contained that name.
*/
SECStatus
-CERT_CompareNameSpace(CERTCertificate *cert,
- CERTGeneralName *namesList,
- CERTCertificate **certsList,
- PLArenaPool *reqArena,
- CERTCertificate **pBadCert)
+CERT_CompareNameSpace(CERTCertificate *cert, CERTGeneralName *namesList,
+ CERTCertificate **certsList, PLArenaPool *reqArena,
+ CERTCertificate **pBadCert)
{
- SECStatus rv = SECSuccess;
- CERTNameConstraints *constraints;
- CERTGeneralName *currentName;
- int count = 0;
- CERTCertificate *badCert = NULL;
+ 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;
+ goto done;
rv = CERT_FindNameConstraintsExten(reqArena, cert, &constraints);
if (rv != SECSuccess) {
- count = -1;
- goto done;
+ count = -1;
+ goto done;
}
currentName = namesList;
do {
- if (constraints){
- rv = CERT_CheckNameSpace(reqArena, constraints, currentName);
- if (rv != SECSuccess) {
- break;
- }
- }
- currentName = CERT_GetNextGeneralName(currentName);
- count ++;
+ 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;
+ badCert = (count >= 0) ? certsList[count] : cert;
}
if (pBadCert)
- *pBadCert = badCert;
+ *pBadCert = badCert;
return rv;
}
@@ -1789,7 +1794,7 @@ CERT_CompareGeneralName(CERTGeneralName *a, CERTGeneralName *b)
currentA = a;
currentB = b;
if (a != NULL) {
- do {
+ do {
if (currentB == NULL) {
return SECFailure;
}
@@ -1815,14 +1820,14 @@ CERT_CompareGeneralName(CERTGeneralName *a, CERTGeneralName *b)
case certX400Address:
case certURI:
if (SECITEM_CompareItem(&currentA->name.other,
- &currentB->name.other)
+ &currentB->name.other)
== SECEqual) {
found = PR_TRUE;
}
break;
case certOtherName:
if (SECITEM_CompareItem(&currentA->name.OthName.oid,
- &currentB->name.OthName.oid)
+ &currentB->name.OthName.oid)
== SECEqual &&
SECITEM_CompareItem(&currentA->name.OthName.name,
&currentB->name.OthName.name)
@@ -1837,7 +1842,7 @@ CERT_CompareGeneralName(CERTGeneralName *a, CERTGeneralName *b)
found = PR_TRUE;
}
}
-
+
}
currentB = CERT_GetNextGeneralName(currentB);
} while (currentB != b && found != PR_TRUE);
@@ -1880,7 +1885,7 @@ CERT_GetGeneralNameFromListByType(CERTGeneralNameList *list,
CERTGeneralNameType type,
PLArenaPool *arena)
{
- CERTName *name = NULL;
+ CERTName *name = NULL;
SECItem *item = NULL;
OtherName *other = NULL;
OtherName *tmpOther = NULL;
@@ -1902,7 +1907,7 @@ CERT_GetGeneralNameFromListByType(CERTGeneralNameList *list,
if (item != NULL) {
XXX SECITEM_CopyItem(arena, item, (SECItem *) data);
}
- } else {
+ } else {
item = SECITEM_DupItem((SECItem *) data);
}
PZ_Unlock(list->lock);
@@ -1943,7 +1948,7 @@ XXX CERT_CopyName(arena, name, (CERTName *) data);
** that can fail.
*/
void
-CERT_AddGeneralNameToList(CERTGeneralNameList *list,
+CERT_AddGeneralNameToList(CERTGeneralNameList *list,
CERTGeneralNameType type,
void *data, SECItem *oid)
{
diff --git a/nss/lib/certdb/genname.h b/nss/lib/certdb/genname.h
index 091c82c..5824157 100644
--- a/nss/lib/certdb/genname.h
+++ b/nss/lib/certdb/genname.h
@@ -17,89 +17,76 @@ SEC_BEGIN_PROTOS
extern const SEC_ASN1Template CERT_GeneralNamesTemplate[];
-extern SECItem **
-cert_EncodeGeneralNames(PLArenaPool *arena, CERTGeneralName *names);
+extern SECItem **cert_EncodeGeneralNames(PLArenaPool *arena,
+ CERTGeneralName *names);
-extern CERTGeneralName *
-cert_DecodeGeneralNames(PLArenaPool *arena, SECItem **encodedGenName);
+extern CERTGeneralName *cert_DecodeGeneralNames(PLArenaPool *arena,
+ SECItem **encodedGenName);
-extern SECStatus
-cert_DestroyGeneralNames(CERTGeneralName *name);
+extern SECStatus cert_DestroyGeneralNames(CERTGeneralName *name);
-extern SECStatus
-cert_EncodeNameConstraints(CERTNameConstraints *constraints, PLArenaPool *arena,
- SECItem *dest);
+extern SECStatus cert_EncodeNameConstraints(CERTNameConstraints *constraints,
+ PLArenaPool *arena, SECItem *dest);
-extern CERTNameConstraints *
-cert_DecodeNameConstraints(PLArenaPool *arena, const SECItem *encodedConstraints);
+extern CERTNameConstraints *cert_DecodeNameConstraints(
+ PLArenaPool *arena, const SECItem *encodedConstraints);
-extern CERTGeneralName *
-cert_CombineNamesLists(CERTGeneralName *list1, CERTGeneralName *list2);
+extern CERTGeneralName *cert_CombineNamesLists(CERTGeneralName *list1,
+ CERTGeneralName *list2);
-extern CERTNameConstraint *
-cert_CombineConstraintsLists(CERTNameConstraint *list1, CERTNameConstraint *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);
+void CERT_DestroyGeneralName(CERTGeneralName *name);
-SECStatus
-CERT_CompareGeneralName(CERTGeneralName *a, CERTGeneralName *b);
+SECStatus CERT_CompareGeneralName(CERTGeneralName *a, CERTGeneralName *b);
-SECStatus
-CERT_CopyGeneralName(PLArenaPool *arena,
- CERTGeneralName *dest,
- CERTGeneralName *src);
+SECStatus CERT_CopyGeneralName(PLArenaPool *arena, CERTGeneralName *dest,
+ CERTGeneralName *src);
-/* General Name Lists are a thread safe, reference counting layer to
+/* General Name Lists are a thread safe, reference counting layer to
* general names */
/* Destroys a CERTGeneralNameList */
-void
-CERT_DestroyGeneralNameList(CERTGeneralNameList *list);
+void CERT_DestroyGeneralNameList(CERTGeneralNameList *list);
/* Creates a CERTGeneralNameList */
-CERTGeneralNameList *
-CERT_CreateGeneralNameList(CERTGeneralName *name);
+CERTGeneralNameList *CERT_CreateGeneralNameList(CERTGeneralName *name);
/* Compares two CERTGeneralNameList */
-SECStatus
-CERT_CompareGeneralNameLists(CERTGeneralNameList *a, CERTGeneralNameList *b);
+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,
- PLArenaPool *arena);
+void *CERT_GetGeneralNameFromListByType(CERTGeneralNameList *list,
+ CERTGeneralNameType type,
+ PLArenaPool *arena);
/* Adds a name to the tail of the list */
-void
-CERT_AddGeneralNameToList(CERTGeneralNameList *list,
- CERTGeneralNameType type,
- void *data, SECItem *oid);
+void CERT_AddGeneralNameToList(CERTGeneralNameList *list,
+ CERTGeneralNameType type, void *data,
+ SECItem *oid);
/* returns a duplicate of the CERTGeneralNameList */
-CERTGeneralNameList *
-CERT_DupGeneralNameList(CERTGeneralNameList *list);
+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);
+extern int CERT_GetNamesLength(CERTGeneralName *names);
/************************************************************************/
-SECStatus
-CERT_CompareNameSpace(CERTCertificate *cert,
- CERTGeneralName *namesList,
- CERTCertificate **certsList,
- PLArenaPool *reqArena,
- CERTCertificate **pBadCert);
+SECStatus CERT_CompareNameSpace(CERTCertificate *cert,
+ CERTGeneralName *namesList,
+ CERTCertificate **certsList,
+ PLArenaPool *reqArena,
+ CERTCertificate **pBadCert);
SEC_END_PROTOS
diff --git a/nss/lib/certdb/polcyxtn.c b/nss/lib/certdb/polcyxtn.c
index cef4783..aae34e2 100644
--- a/nss/lib/certdb/polcyxtn.c
+++ b/nss/lib/certdb/polcyxtn.c
@@ -20,95 +20,81 @@ 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 },
+ { 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, 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) },
+ offsetof(CERTNoticeReference, noticeNumbers),
+ SEC_ASN1_SUB(SEC_IntegerTemplate) },
{ 0 }
};
const SEC_ASN1Template CERT_UserNoticeTemplate[] = {
- { SEC_ASN1_SEQUENCE,
- 0, NULL, sizeof(CERTUserNotice) },
+ { SEC_ASN1_SEQUENCE, 0, NULL, sizeof(CERTUserNotice) },
{ SEC_ASN1_INLINE | SEC_ASN1_OPTIONAL,
- offsetof(CERTUserNotice, noticeReference),
- CERT_NoticeReferenceTemplate, 0 },
+ offsetof(CERTUserNotice, noticeReference), CERT_NoticeReferenceTemplate,
+ 0 },
{ SEC_ASN1_INLINE | SEC_ASN1_OPTIONAL,
- offsetof(CERTUserNotice, displayText),
- CERT_DisplayTextTypeTemplate, 0 },
+ 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) },
+ { 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, 0, NULL, sizeof(CERTPolicyInfo) },
+ { SEC_ASN1_OBJECT_ID, offsetof(CERTPolicyInfo, policyID) },
{ SEC_ASN1_SEQUENCE_OF | SEC_ASN1_OPTIONAL,
- offsetof(CERTPolicyInfo, policyQualifiers),
- CERT_PolicyQualifierTemplate },
+ offsetof(CERTPolicyInfo, policyQualifiers),
+ CERT_PolicyQualifierTemplate },
{ 0 }
};
const SEC_ASN1Template CERT_CertificatePoliciesTemplate[] = {
- { SEC_ASN1_SEQUENCE_OF,
- offsetof(CERTCertificatePolicies, policyInfos),
- CERT_PolicyInfoTemplate, sizeof(CERTCertificatePolicies) }
+ { 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) },
+ { 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) }
+ { 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) },
+ 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) },
+ offsetof(CERTCertificatePolicyConstraints, inhibitMappingSkipCerts),
+ SEC_ASN1_SUB(SEC_IntegerTemplate) },
{ 0 }
};
const SEC_ASN1Template CERT_InhibitAnyTemplate[] = {
{ SEC_ASN1_INTEGER,
- offsetof(CERTCertificateInhibitAny, inhibitAnySkipCerts),
- NULL, sizeof(CERTCertificateInhibitAny) }
+ offsetof(CERTCertificateInhibitAny, inhibitAnySkipCerts), NULL,
+ sizeof(CERTCertificateInhibitAny) }
};
static void
@@ -118,30 +104,30 @@ breakLines(char *string)
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++;
- }
-
+ 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;
}
@@ -154,69 +140,69 @@ CERT_DecodeCertificatePoliciesExtension(const SECItem *extnValue)
CERTPolicyInfo **policyInfos, *policyInfo;
CERTPolicyQualifier **policyQualifiers, *policyQualifier;
SECItem newExtnValue;
-
+
/* make a new arena */
arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
-
- if ( !arena ) {
- goto loser;
+
+ if (!arena) {
+ goto loser;
}
/* allocate the certificate policies structure */
- policies = (CERTCertificatePolicies *)
- PORT_ArenaZAlloc(arena, sizeof(CERTCertificatePolicies));
-
- if ( policies == NULL ) {
- goto loser;
+ 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;
+ if (rv != SECSuccess) {
+ goto loser;
}
/* decode the policy info */
- rv = SEC_QuickDERDecodeItem(arena, policies, CERT_CertificatePoliciesTemplate,
- &newExtnValue);
+ rv = SEC_QuickDERDecodeItem(
+ arena, policies, CERT_CertificatePoliciesTemplate, &newExtnValue);
- if ( rv != SECSuccess ) {
- goto loser;
+ 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);
-
+ 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);
+ if (arena != NULL) {
+ PORT_FreeArena(arena, PR_FALSE);
}
-
- return(NULL);
+
+ return (NULL);
}
void
CERT_DestroyCertificatePoliciesExtension(CERTCertificatePolicies *policies)
{
- if ( policies != NULL ) {
- PORT_FreeArena(policies->arena, PR_FALSE);
+ if (policies != NULL) {
+ PORT_FreeArena(policies->arena, PR_FALSE);
}
return;
}
@@ -228,17 +214,17 @@ CERT_DecodePolicyMappingsExtension(SECItem *extnValue)
SECStatus rv;
CERTCertificatePolicyMappings *mappings;
SECItem newExtnValue;
-
+
/* make a new arena */
arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
- if ( !arena ) {
+ if (!arena) {
goto loser;
}
/* allocate the policy mappings structure */
- mappings = (CERTCertificatePolicyMappings *)
- PORT_ArenaZAlloc(arena, sizeof(CERTCertificatePolicyMappings));
- if ( mappings == NULL ) {
+ mappings = (CERTCertificatePolicyMappings *)PORT_ArenaZAlloc(
+ arena, sizeof(CERTCertificatePolicyMappings));
+ if (mappings == NULL) {
goto loser;
}
mappings->arena = arena;
@@ -246,40 +232,39 @@ CERT_DecodePolicyMappingsExtension(SECItem *extnValue)
/* 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 ) {
+ if (rv != SECSuccess) {
goto loser;
}
/* decode the policy mappings */
- rv = SEC_QuickDERDecodeItem
- (arena, mappings, CERT_PolicyMappingsTemplate, &newExtnValue);
- if ( rv != SECSuccess ) {
+ rv = SEC_QuickDERDecodeItem(arena, mappings, CERT_PolicyMappingsTemplate,
+ &newExtnValue);
+ if (rv != SECSuccess) {
goto loser;
}
- return(mappings);
-
+ return (mappings);
+
loser:
- if ( arena != NULL ) {
+ if (arena != NULL) {
PORT_FreeArena(arena, PR_FALSE);
}
-
- return(NULL);
+
+ return (NULL);
}
SECStatus
CERT_DestroyPolicyMappingsExtension(CERTCertificatePolicyMappings *mappings)
{
- if ( mappings != NULL ) {
+ if (mappings != NULL) {
PORT_FreeArena(mappings->arena, PR_FALSE);
}
return SECSuccess;
}
SECStatus
-CERT_DecodePolicyConstraintsExtension
- (CERTCertificatePolicyConstraints *decodedValue,
- const SECItem *encodedValue)
+CERT_DecodePolicyConstraintsExtension(
+ CERTCertificatePolicyConstraints *decodedValue, const SECItem *encodedValue)
{
CERTCertificatePolicyConstraints decodeContext;
PLArenaPool *arena = NULL;
@@ -296,10 +281,11 @@ CERT_DecodePolicyConstraintsExtension
do {
/* decode the policy constraints */
- rv = SEC_QuickDERDecodeItem(arena,
- &decodeContext, CERT_PolicyConstraintsTemplate, encodedValue);
+ rv = SEC_QuickDERDecodeItem(arena, &decodeContext,
+ CERT_PolicyConstraintsTemplate,
+ encodedValue);
- if ( rv != SECSuccess ) {
+ if (rv != SECSuccess) {
break;
}
@@ -307,35 +293,36 @@ CERT_DecodePolicyConstraintsExtension
*(PRInt32 *)decodedValue->explicitPolicySkipCerts.data = -1;
} else {
*(PRInt32 *)decodedValue->explicitPolicySkipCerts.data =
- DER_GetInteger(&decodeContext.explicitPolicySkipCerts);
+ DER_GetInteger(&decodeContext.explicitPolicySkipCerts);
}
if (decodeContext.inhibitMappingSkipCerts.len == 0) {
*(PRInt32 *)decodedValue->inhibitMappingSkipCerts.data = -1;
} else {
*(PRInt32 *)decodedValue->inhibitMappingSkipCerts.data =
- DER_GetInteger(&decodeContext.inhibitMappingSkipCerts);
+ DER_GetInteger(&decodeContext.inhibitMappingSkipCerts);
}
if ((*(PRInt32 *)decodedValue->explicitPolicySkipCerts.data ==
- PR_INT32_MIN) ||
+ PR_INT32_MIN) ||
(*(PRInt32 *)decodedValue->explicitPolicySkipCerts.data ==
- PR_INT32_MAX) ||
+ PR_INT32_MAX) ||
(*(PRInt32 *)decodedValue->inhibitMappingSkipCerts.data ==
- PR_INT32_MIN) ||
+ PR_INT32_MIN) ||
(*(PRInt32 *)decodedValue->inhibitMappingSkipCerts.data ==
- PR_INT32_MAX)) {
+ PR_INT32_MAX)) {
rv = SECFailure;
}
-
+
} while (0);
PORT_FreeArena(arena, PR_FALSE);
- return(rv);
+ return (rv);
}
-SECStatus CERT_DecodeInhibitAnyExtension
- (CERTCertificateInhibitAny *decodedValue, SECItem *encodedValue)
+SECStatus
+CERT_DecodeInhibitAnyExtension(CERTCertificateInhibitAny *decodedValue,
+ SECItem *encodedValue)
{
CERTCertificateInhibitAny decodeContext;
PLArenaPool *arena = NULL;
@@ -343,7 +330,7 @@ SECStatus CERT_DecodeInhibitAnyExtension
/* make a new arena */
arena = PORT_NewArena(SEC_ASN1_DEFAULT_ARENA_SIZE);
- if ( !arena ) {
+ if (!arena) {
return SECFailure;
}
@@ -351,20 +338,20 @@ SECStatus CERT_DecodeInhibitAnyExtension
/* decode the policy mappings */
decodeContext.inhibitAnySkipCerts.type = siUnsignedInteger;
- rv = SEC_QuickDERDecodeItem(arena,
- &decodeContext, CERT_InhibitAnyTemplate, encodedValue);
+ rv = SEC_QuickDERDecodeItem(arena, &decodeContext,
+ CERT_InhibitAnyTemplate, encodedValue);
- if ( rv != SECSuccess ) {
+ if (rv != SECSuccess) {
break;
}
*(PRInt32 *)decodedValue->inhibitAnySkipCerts.data =
- DER_GetInteger(&decodeContext.inhibitAnySkipCerts);
+ DER_GetInteger(&decodeContext.inhibitAnySkipCerts);
} while (0);
PORT_FreeArena(arena, PR_FALSE);
- return(rv);
+ return (rv);
}
CERTUserNotice *
@@ -374,37 +361,37 @@ CERT_DecodeUserNotice(SECItem *noticeItem)
SECStatus rv;
CERTUserNotice *userNotice;
SECItem newNoticeItem;
-
+
/* make a new arena */
arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
-
- if ( !arena ) {
- goto loser;
+
+ if (!arena) {
+ goto loser;
}
/* allocate the userNotice structure */
- userNotice = (CERTUserNotice *)PORT_ArenaZAlloc(arena,
- sizeof(CERTUserNotice));
-
- if ( userNotice == NULL ) {
- goto loser;
+ 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;
+ if (rv != SECSuccess) {
+ goto loser;
}
/* decode the user notice */
- rv = SEC_QuickDERDecodeItem(arena, userNotice, CERT_UserNoticeTemplate,
- &newNoticeItem);
+ rv = SEC_QuickDERDecodeItem(arena, userNotice, CERT_UserNoticeTemplate,
+ &newNoticeItem);
- if ( rv != SECSuccess ) {
- goto loser;
+ if (rv != SECSuccess) {
+ goto loser;
}
if (userNotice->derNoticeReference.data != NULL) {
@@ -414,24 +401,24 @@ CERT_DecodeUserNotice(SECItem *noticeItem)
&userNotice->derNoticeReference);
if (rv == SECFailure) {
goto loser;
- }
+ }
}
- return(userNotice);
-
+ return (userNotice);
+
loser:
- if ( arena != NULL ) {
- PORT_FreeArena(arena, PR_FALSE);
+ if (arena != NULL) {
+ PORT_FreeArena(arena, PR_FALSE);
}
-
- return(NULL);
+
+ return (NULL);
}
void
CERT_DestroyUserNotice(CERTUserNotice *userNotice)
{
- if ( userNotice != NULL ) {
- PORT_FreeArena(userNotice->arena, PR_FALSE);
+ if (userNotice != NULL) {
+ PORT_FreeArena(userNotice->arena, PR_FALSE);
}
return;
}
@@ -459,74 +446,73 @@ stringFromUserNotice(SECItem *noticeItem)
SECItem *displayText;
SECItem **noticeNumbers;
unsigned int strnum;
-
+
/* decode the user notice */
userNotice = CERT_DecodeUserNotice(noticeItem);
- if ( userNotice == NULL ) {
- return(NULL);
+ 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';
- }
- }
- }
- }
- }
-
+ 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);
+
+ return (retstr);
}
char *
@@ -540,65 +526,63 @@ CERT_GetCertCommentString(CERTCertificate *cert)
CERTPolicyQualifier **policyQualifiers, *qualifier;
policyItem.data = NULL;
-
+
rv = CERT_FindCertExtension(cert, SEC_OID_X509_CERTIFICATE_POLICIES,
- &policyItem);
- if ( rv != SECSuccess ) {
- goto nopolicy;
+ &policyItem);
+ if (rv != SECSuccess) {
+ goto nopolicy;
}
policies = CERT_DecodeCertificatePoliciesExtension(&policyItem);
- if ( policies == NULL ) {
- goto nopolicy;
+ 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++;
+ 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 (policyItem.data != NULL) {
+ PORT_Free(policyItem.data);
}
- if ( policies != NULL ) {
- CERT_DestroyCertificatePoliciesExtension(policies);
+ if (policies != NULL) {
+ CERT_DestroyCertificatePoliciesExtension(policies);
}
-
- if ( retstring == NULL ) {
- retstring = CERT_FindNSStringExtension(cert,
- SEC_OID_NS_CERT_EXT_COMMENT);
+
+ if (retstring == NULL) {
+ retstring =
+ CERT_FindNSStringExtension(cert, SEC_OID_NS_CERT_EXT_COMMENT);
}
-
- if ( retstring != NULL ) {
- breakLines(retstring);
+
+ if (retstring != NULL) {
+ breakLines(retstring);
}
-
- return(retstring);
-}
+ return (retstring);
+}
const SEC_ASN1Template CERT_OidSeqTemplate[] = {
- { SEC_ASN1_SEQUENCE_OF | SEC_ASN1_XTRN,
- offsetof(CERTOidSequence, oids),
- SEC_ASN1_SUB(SEC_ObjectIDTemplate) }
+ { SEC_ASN1_SEQUENCE_OF | SEC_ASN1_XTRN, offsetof(CERTOidSequence, oids),
+ SEC_ASN1_SUB(SEC_ObjectIDTemplate) }
};
CERTOidSequence *
@@ -608,53 +592,53 @@ CERT_DecodeOidSequence(const SECItem *seqItem)
SECStatus rv;
CERTOidSequence *oidSeq;
SECItem newSeqItem;
-
+
/* make a new arena */
arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
-
- if ( !arena ) {
- goto loser;
+
+ if (!arena) {
+ goto loser;
}
/* allocate the userNotice structure */
- oidSeq = (CERTOidSequence *)PORT_ArenaZAlloc(arena,
- sizeof(CERTOidSequence));
-
- if ( oidSeq == NULL ) {
- goto loser;
+ 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;
+ if (rv != SECSuccess) {
+ goto loser;
}
/* decode the user notice */
- rv = SEC_QuickDERDecodeItem(arena, oidSeq, CERT_OidSeqTemplate, &newSeqItem);
+ rv =
+ SEC_QuickDERDecodeItem(arena, oidSeq, CERT_OidSeqTemplate, &newSeqItem);
- if ( rv != SECSuccess ) {
- goto loser;
+ if (rv != SECSuccess) {
+ goto loser;
}
- return(oidSeq);
-
+ return (oidSeq);
+
loser:
if (arena) {
PORT_FreeArena(arena, PR_FALSE);
}
- return(NULL);
+ return (NULL);
}
-
void
CERT_DestroyOidSequence(CERTOidSequence *oidSeq)
{
- if ( oidSeq != NULL ) {
- PORT_FreeArena(oidSeq->arena, PR_FALSE);
+ if (oidSeq != NULL) {
+ PORT_FreeArena(oidSeq->arena, PR_FALSE);
}
return;
}
@@ -669,29 +653,29 @@ CERT_GovtApprovedBitSet(CERTCertificate *cert)
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;
+ if (rv != SECSuccess) {
+ goto loser;
}
oidSeq = CERT_DecodeOidSequence(&extItem);
- if ( oidSeq == NULL ) {
- goto loser;
+ 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++;
+ while (oids != NULL && *oids != NULL) {
+ oid = *oids;
+
+ oidTag = SECOID_FindOIDTag(oid);
+
+ if (oidTag == SEC_OID_NS_KEY_USAGE_GOVT_APPROVED) {
+ goto success;
+ }
+
+ oids++;
}
loser:
@@ -700,16 +684,15 @@ loser:
success:
ret = PR_TRUE;
done:
- if ( oidSeq != NULL ) {
- CERT_DestroyOidSequence(oidSeq);
+ if (oidSeq != NULL) {
+ CERT_DestroyOidSequence(oidSeq);
}
if (extItem.data != NULL) {
- PORT_Free(extItem.data);
+ PORT_Free(extItem.data);
}
- return(ret);
+ return (ret);
}
-
SECStatus
CERT_EncodePolicyConstraintsExtension(PLArenaPool *arena,
CERTCertificatePolicyConstraints *constr,
@@ -719,14 +702,14 @@ CERT_EncodePolicyConstraintsExtension(PLArenaPool *arena,
PORT_Assert(constr != NULL && dest != NULL);
if (constr == NULL || dest == NULL) {
- return SECFailure;
+ return SECFailure;
}
- if (SEC_ASN1EncodeItem (arena, dest, constr,
- CERT_PolicyConstraintsTemplate) == NULL) {
- rv = SECFailure;
+ if (SEC_ASN1EncodeItem(arena, dest, constr,
+ CERT_PolicyConstraintsTemplate) == NULL) {
+ rv = SECFailure;
}
- return(rv);
+ return (rv);
}
SECStatus
@@ -738,75 +721,69 @@ CERT_EncodePolicyMappingExtension(PLArenaPool *arena,
PORT_Assert(mapping != NULL && dest != NULL);
if (mapping == NULL || dest == NULL) {
- return SECFailure;
+ return SECFailure;
}
- if (SEC_ASN1EncodeItem (arena, dest, mapping,
- CERT_PolicyMappingsTemplate) == NULL) {
- rv = SECFailure;
+ if (SEC_ASN1EncodeItem(arena, dest, mapping, CERT_PolicyMappingsTemplate) ==
+ NULL) {
+ rv = SECFailure;
}
- return(rv);
+ return (rv);
}
-
-
SECStatus
-CERT_EncodeCertPoliciesExtension(PLArenaPool *arena,
- CERTPolicyInfo **info,
+CERT_EncodeCertPoliciesExtension(PLArenaPool *arena, CERTPolicyInfo **info,
SECItem *dest)
{
SECStatus rv = SECSuccess;
PORT_Assert(info != NULL && dest != NULL);
if (info == NULL || dest == NULL) {
- return SECFailure;
+ return SECFailure;
}
- if (SEC_ASN1EncodeItem (arena, dest, info,
- CERT_CertificatePoliciesTemplate) == NULL) {
- rv = SECFailure;
+ if (SEC_ASN1EncodeItem(arena, dest, info,
+ CERT_CertificatePoliciesTemplate) == NULL) {
+ rv = SECFailure;
}
- return(rv);
+ return (rv);
}
SECStatus
-CERT_EncodeUserNotice(PLArenaPool *arena,
- CERTUserNotice *notice,
- SECItem *dest)
+CERT_EncodeUserNotice(PLArenaPool *arena, CERTUserNotice *notice, SECItem *dest)
{
SECStatus rv = SECSuccess;
PORT_Assert(notice != NULL && dest != NULL);
if (notice == NULL || dest == NULL) {
- return SECFailure;
+ return SECFailure;
}
- if (SEC_ASN1EncodeItem(arena, dest,
- notice, CERT_UserNoticeTemplate) == NULL) {
- rv = SECFailure;
+ if (SEC_ASN1EncodeItem(arena, dest, notice, CERT_UserNoticeTemplate) ==
+ NULL) {
+ rv = SECFailure;
}
- return(rv);
+ return (rv);
}
SECStatus
-CERT_EncodeNoticeReference(PLArenaPool *arena,
- CERTNoticeReference *reference,
+CERT_EncodeNoticeReference(PLArenaPool *arena, CERTNoticeReference *reference,
SECItem *dest)
{
SECStatus rv = SECSuccess;
-
+
PORT_Assert(reference != NULL && dest != NULL);
if (reference == NULL || dest == NULL) {
- return SECFailure;
+ return SECFailure;
}
- if (SEC_ASN1EncodeItem (arena, dest, reference,
- CERT_NoticeReferenceTemplate) == NULL) {
- rv = SECFailure;
+ if (SEC_ASN1EncodeItem(arena, dest, reference,
+ CERT_NoticeReferenceTemplate) == NULL) {
+ rv = SECFailure;
}
- return(rv);
+ return (rv);
}
SECStatus
@@ -818,12 +795,12 @@ CERT_EncodeInhibitAnyExtension(PLArenaPool *arena,
PORT_Assert(certInhibitAny != NULL && dest != NULL);
if (certInhibitAny == NULL || dest == NULL) {
- return SECFailure;
+ return SECFailure;
}
- if (SEC_ASN1EncodeItem (arena, dest, certInhibitAny,
- CERT_InhibitAnyTemplate) == NULL) {
- rv = SECFailure;
+ if (SEC_ASN1EncodeItem(arena, dest, certInhibitAny,
+ CERT_InhibitAnyTemplate) == NULL) {
+ rv = SECFailure;
}
- return(rv);
+ return (rv);
}
diff --git a/nss/lib/certdb/secname.c b/nss/lib/certdb/secname.c
index 88a0cf7..6d3e9d3 100644
--- a/nss/lib/certdb/secname.c
+++ b/nss/lib/certdb/secname.c
@@ -4,7 +4,7 @@
#include "cert.h"
#include "secoid.h"
-#include "secder.h" /* XXX remove this when remove the DERTemplates */
+#include "secder.h" /* XXX remove this when remove the DERTemplates */
#include "secasn1.h"
#include "secitem.h"
#include <stdarg.h>
@@ -12,29 +12,25 @@
#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, }
+ { 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) }
+ { SEC_ASN1_SET_OF, offsetof(CERTRDN, avas), cert_AVATemplate,
+ sizeof(CERTRDN) }
};
-
static int
CountArray(void **array)
{
int count = 0;
if (array) {
- while (*array++) {
- count++;
- }
+ while (*array++) {
+ count++;
+ }
}
return count;
}
@@ -49,36 +45,36 @@ AddToArray(PLArenaPool *arena, void **array, void *element)
count = 0;
ap = array;
if (ap) {
- while (*ap++) {
- count++;
- }
+ while (*ap++) {
+ count++;
+ }
}
if (array) {
- array = (void**) PORT_ArenaGrow(arena, array,
- (count + 1) * sizeof(void *),
- (count + 2) * sizeof(void *));
+ array =
+ (void **)PORT_ArenaGrow(arena, array, (count + 1) * sizeof(void *),
+ (count + 2) * sizeof(void *));
} else {
- array = (void**) PORT_ArenaAlloc(arena, (count + 2) * sizeof(void *));
+ array = (void **)PORT_ArenaAlloc(arena, (count + 2) * sizeof(void *));
}
if (array) {
- array[count] = element;
- array[count+1] = 0;
+ array[count] = element;
+ array[count + 1] = 0;
}
return array;
}
-
SECOidTag
CERT_GetAVATag(CERTAVA *ava)
{
SECOidData *oid;
- if (!ava->type.data) return (SECOidTag)-1;
+ if (!ava->type.data)
+ return (SECOidTag)-1;
oid = SECOID_FindOID(&ava->type);
-
- if ( oid ) {
- return(oid->offset);
+
+ if (oid) {
+ return (oid->offset);
}
return (SECOidTag)-1;
}
@@ -89,25 +85,25 @@ SetupAVAType(PLArenaPool *arena, SECOidTag type, SECItem *it, unsigned *maxLenp)
unsigned char *oid;
unsigned oidLen;
unsigned char *cp;
- int maxLen;
+ int maxLen;
SECOidData *oidrec;
oidrec = SECOID_FindOIDByTag(type);
if (oidrec == NULL)
- return SECFailure;
+ 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;
+ PORT_SetError(SEC_ERROR_INVALID_ARGS);
+ return SECFailure;
}
- it->data = cp = (unsigned char*) PORT_ArenaAlloc(arena, oidLen);
+ it->data = cp = (unsigned char *)PORT_ArenaAlloc(arena, oidLen);
if (cp == NULL) {
- return SECFailure;
+ return SECFailure;
}
it->len = oidLen;
PORT_Memcpy(cp, oid, oidLen);
@@ -123,65 +119,66 @@ SetupAVAValue(PLArenaPool *arena, int valueType, const SECItem *in,
unsigned valueLen, valueLenLen, total;
unsigned ucs4Len = 0, ucs4MaxLen;
- value = in->data;
+ 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;
+ 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;
- }
+ PORT_SetError(SEC_ERROR_INVALID_ARGS);
+ return SECFailure;
+ }
valueLenLen = DER_LengthLength(valueLen);
total = 1 + valueLenLen + valueLen;
- cp = (PRUint8*)PORT_ArenaAlloc(arena, total);
+ cp = (PRUint8 *)PORT_ArenaAlloc(arena, total);
if (!cp) {
- return SECFailure;
+ return SECFailure;
}
out->data = cp;
- out->len = total;
+ out->len = total;
cp = (PRUint8 *)DER_StoreHeader(cp, valueType, valueLen);
PORT_Memcpy(cp, value, valueLen);
return SECSuccess;
}
CERTAVA *
-CERT_CreateAVAFromRaw(PLArenaPool *pool, const SECItem * OID,
- const SECItem * value)
+CERT_CreateAVAFromRaw(PLArenaPool *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->type, OID);
+ if (rv)
+ return NULL;
- rv = SECITEM_CopyItem(pool, &ava->value, value);
- if (rv)
- return NULL;
+ rv = SECITEM_CopyItem(pool, &ava->value, value);
+ if (rv)
+ return NULL;
}
return ava;
}
@@ -194,18 +191,18 @@ CERT_CreateAVAFromSECItem(PLArenaPool *arena, SECOidTag kind, int valueType,
int rv;
unsigned maxLen;
- ava = (CERTAVA*) PORT_ArenaZAlloc(arena, sizeof(CERTAVA));
+ 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;
- }
+ 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;
}
@@ -216,7 +213,7 @@ CERT_CreateAVA(PLArenaPool *arena, SECOidTag kind, int valueType, char *value)
SECItem item = { siBuffer, NULL, 0 };
item.data = (PRUint8 *)value;
- item.len = PORT_Strlen(value);
+ item.len = PORT_Strlen(value);
return CERT_CreateAVAFromSECItem(arena, kind, valueType, &item);
}
@@ -227,16 +224,18 @@ CERT_CopyAVA(PLArenaPool *arena, CERTAVA *from)
CERTAVA *ava;
int rv;
- ava = (CERTAVA*) PORT_ArenaZAlloc(arena, sizeof(CERTAVA));
+ 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;
+ 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:
+loser:
return 0;
}
@@ -249,34 +248,34 @@ CERT_CreateRDN(PLArenaPool *arena, CERTAVA *ava0, ...)
unsigned count;
CERTAVA **avap;
- rdn = (CERTRDN*) PORT_ArenaAlloc(arena, sizeof(CERTRDN));
+ 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;
+ /* 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;
}
@@ -284,7 +283,7 @@ CERT_CreateRDN(PLArenaPool *arena, CERTAVA *ava0, ...)
SECStatus
CERT_AddAVA(PLArenaPool *arena, CERTRDN *rdn, CERTAVA *ava)
{
- rdn->avas = (CERTAVA**) AddToArray(arena, (void**) rdn->avas, ava);
+ rdn->avas = (CERTAVA **)AddToArray(arena, (void **)rdn->avas, ava);
return rdn->avas ? SECSuccess : SECFailure;
}
@@ -297,20 +296,20 @@ CERT_CopyRDN(PLArenaPool *arena, CERTRDN *to, CERTRDN *from)
/* 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;
- }
+ 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;
}
@@ -318,8 +317,8 @@ CERT_CopyRDN(PLArenaPool *arena, CERTRDN *to, CERTRDN *from)
/************************************************************************/
const SEC_ASN1Template CERT_NameTemplate[] = {
- { SEC_ASN1_SEQUENCE_OF,
- offsetof(CERTName,rdns), CERT_RDNTemplate, sizeof(CERTName) }
+ { SEC_ASN1_SEQUENCE_OF, offsetof(CERTName, rdns), CERT_RDNTemplate,
+ sizeof(CERTName) }
};
SEC_ASN1_CHOOSER_IMPLEMENT(CERT_NameTemplate)
@@ -333,71 +332,71 @@ CERT_CreateName(CERTRDN *rdn0, ...)
unsigned count;
CERTRDN **rdnp;
PLArenaPool *arena;
-
+
arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
- if ( !arena ) {
- return(0);
+ if (!arena) {
+ return (0);
}
-
- name = (CERTName*) PORT_ArenaAlloc(arena, sizeof(CERTName));
+
+ 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;
+ 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);
+ return (0);
}
void
CERT_DestroyName(CERTName *name)
{
- if (name)
- {
+ if (name) {
PLArenaPool *arena = name->arena;
name->rdns = NULL;
- name->arena = NULL;
- if (arena) PORT_FreeArena(arena, PR_FALSE);
+ 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);
+ name->rdns = (CERTRDN **)AddToArray(name->arena, (void **)name->rdns, rdn);
return name->rdns ? SECSuccess : SECFailure;
}
@@ -408,8 +407,8 @@ CERT_CopyName(PLArenaPool *arena, CERTName *to, const CERTName *from)
SECStatus rv = SECSuccess;
if (!to || !from) {
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- return SECFailure;
+ PORT_SetError(SEC_ERROR_INVALID_ARGS);
+ return SECFailure;
}
CERT_DestroyName(to);
@@ -418,23 +417,23 @@ CERT_CopyName(PLArenaPool *arena, CERTName *to, const CERTName *from)
/* 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;
- }
+ 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;
}
@@ -442,34 +441,35 @@ CERT_CopyName(PLArenaPool *arena, CERTName *to, const CERTName *from)
/************************************************************************/
static void
-canonicalize(SECItem * foo)
+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--;
+ 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++;
+ while (src < len && ((ch = foo->data[src]) == ' ' || ch == '\t' ||
+ ch == '\r' || ch == '\n')) {
+ src++;
}
- dest = 0; lastch = ' ';
+ 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;
+ 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;
}
@@ -479,14 +479,13 @@ 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 *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);
@@ -500,30 +499,30 @@ CERT_CompareAVA(const CERTAVA *a, const CERTAVA *b)
rv = SECITEM_CompareItem(&a->type, &b->type);
if (SECEqual != rv)
- return rv; /* Attribute types don't match. */
+ 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. */
+ 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);
- }
+ /* 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;
}
@@ -543,23 +542,25 @@ CERT_CompareRDN(const CERTRDN *a, const CERTRDN *b)
** 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;
+ 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;
+ 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;
}
@@ -579,19 +580,25 @@ CERT_CompareName(const CERTName *a, const CERTName *b)
** 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;
+ 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;
+ if (!ardns++ || !brdns++) {
+ break;
+ }
+ ardn = *ardns;
+ brdn = *brdns;
+ if (!ardn) {
+ break;
+ }
+ rv = CERT_CompareRDN(ardn, brdn);
+ if (rv)
+ return rv;
}
return rv;
}
@@ -600,102 +607,105 @@ CERT_CompareName(const CERTName *a, const CERTName *b)
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;
+ SECItem *retItem;
+ const SEC_ASN1Template *theTemplate = NULL;
+ enum { conv_none,
+ conv_ucs4,
+ conv_ucs2,
+ conv_iso88591 } convert = conv_none;
+ SECItem avaValue = { siBuffer, 0 };
+ PORTCheapArenaPool tmpArena;
if (!derAVAValue || !derAVAValue->len || !derAVAValue->data) {
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- return NULL;
+ 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;
+ 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) {
+ PORT_InitCheapArena(&tmpArena, DER_DEFAULT_CHUNKSIZE);
+ if (SEC_QuickDERDecodeItem(&tmpArena.arena, &avaValue, theTemplate,
+ derAVAValue) != SECSuccess) {
+ PORT_DestroyCheapArena(&tmpArena);
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);
+ unsigned int utf8ValLen = avaValue.len * 3;
+ unsigned char *utf8Val =
+ (unsigned char *)PORT_ArenaZAlloc(&tmpArena.arena, 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;
+ case conv_ucs4:
+ if (avaValue.len % 4 != 0 ||
+ !PORT_UCS4_UTF8Conversion(PR_FALSE, avaValue.data,
+ avaValue.len, utf8Val, utf8ValLen,
+ &utf8ValLen)) {
+ PORT_DestroyCheapArena(&tmpArena);
+ 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_DestroyCheapArena(&tmpArena);
+ PORT_SetError(SEC_ERROR_INVALID_AVA);
+ return NULL;
+ }
+ break;
+ case conv_iso88591:
+ if (!PORT_ISO88591_UTF8Conversion(avaValue.data, avaValue.len,
+ utf8Val, utf8ValLen,
+ &utf8ValLen)) {
+ PORT_DestroyCheapArena(&tmpArena);
+ 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);
+ PORT_DestroyCheapArena(&tmpArena);
return retItem;
}
diff --git a/nss/lib/certdb/stanpcertdb.c b/nss/lib/certdb/stanpcertdb.c
index 1e1e06c..2b1aa97 100644
--- a/nss/lib/certdb/stanpcertdb.c
+++ b/nss/lib/certdb/stanpcertdb.c
@@ -33,18 +33,18 @@
PRBool
SEC_CertNicknameConflict(const char *nickname, const SECItem *derSubject,
- CERTCertDBHandle *handle)
+ CERTCertDBHandle *handle)
{
CERTCertificate *cert;
PRBool conflict = PR_FALSE;
- cert=CERT_FindCertByNickname(handle, nickname);
+ cert = CERT_FindCertByNickname(handle, nickname);
if (!cert) {
- return conflict;
+ return conflict;
}
- conflict = !SECITEM_ItemsAreEqual(derSubject,&cert->derSubject);
+ conflict = !SECITEM_ItemsAreEqual(derSubject, &cert->derSubject);
CERT_DestroyCertificate(cert);
return conflict;
}
@@ -64,15 +64,15 @@ SEC_DeletePermCertificate(CERTCertificate *cert)
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);
- }
+ 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 */
@@ -91,14 +91,14 @@ CERT_GetCertTrust(const CERTCertificate *cert, CERTCertTrust *trust)
{
SECStatus rv;
CERT_LockCertTrust(cert);
- if ( cert->trust == NULL ) {
- rv = SECFailure;
+ if (cert->trust == NULL) {
+ rv = SECFailure;
} else {
- *trust = *cert->trust;
- rv = SECSuccess;
+ *trust = *cert->trust;
+ rv = SECSuccess;
}
CERT_UnlockCertTrust(cert);
- return(rv);
+ return (rv);
}
extern const NSSError NSS_ERROR_NO_ERROR;
@@ -141,14 +141,11 @@ 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; \
- } \
+#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.
@@ -161,89 +158,81 @@ CERT_MapStanError()
int secError;
int i;
- error = 0;
-
errorStack = NSS_GetErrorStack();
if (errorStack == 0) {
- PORT_SetError(0);
- return;
- }
+ 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];
+ 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;
+ /* 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)
+ CERTCertTrust *trust)
{
SECStatus rv = SECSuccess;
PRStatus ret;
ret = STAN_ChangeCertTrust(cert, trust);
if (ret != PR_SUCCESS) {
- rv = SECFailure;
- CERT_MapStanError();
+ rv = SECFailure;
+ CERT_MapStanError();
}
return rv;
}
@@ -252,7 +241,7 @@ extern const NSSError NSS_ERROR_INVALID_CERTIFICATE;
SECStatus
__CERT_AddTempCertToPerm(CERTCertificate *cert, char *nickname,
- CERTCertTrust *trust)
+ CERTCertTrust *trust)
{
NSSUTF8 *stanNick;
PK11SlotInfo *slot;
@@ -260,31 +249,31 @@ __CERT_AddTempCertToPerm(CERTCertificate *cert, char *nickname,
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};
+ 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();
+ CERT_MapStanError();
return SECFailure;
}
context = c->object.cryptoContext;
if (!context) {
- PORT_SetError(SEC_ERROR_ADDING_CERT);
- return SECFailure; /* wasn't a temp cert */
+ 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;
+ /* different: take the new nickname */
+ cert->nickname = NULL;
nss_ZFreeIf(stanNick);
- stanNick = NULL;
+ stanNick = NULL;
}
if (!stanNick && nickname) {
/* Either there was no nickname yet, or we have a new nickname */
- stanNick = nssUTF8_Duplicate((NSSUTF8 *)nickname, NULL);
+ stanNick = nssUTF8_Duplicate((NSSUTF8 *)nickname, NULL);
} /* else: old stanNick is identical to new nickname */
/* Delete the temp instance */
nssCertificateStore_Lock(context->certStore, &lockTrace);
@@ -294,24 +283,17 @@ __CERT_AddTempCertToPerm(CERTCertificate *cert, char *nickname,
/* 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);
+ 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;
+ 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);
@@ -319,33 +301,33 @@ __CERT_AddTempCertToPerm(CERTCertificate *cert, char *nickname,
cert->nssCertificate = NULL;
cert = STAN_GetCERTCertificateOrRelease(c); /* should return same pointer */
if (!cert) {
- CERT_MapStanError();
+ CERT_MapStanError();
return SECFailure;
}
cert->istemp = PR_FALSE;
cert->isperm = PR_TRUE;
if (!trust) {
- return SECSuccess;
+ return SECSuccess;
}
ret = STAN_ChangeCertTrust(cert, trust);
rv = SECSuccess;
if (ret != PR_SUCCESS) {
- rv = SECFailure;
- CERT_MapStanError();
+ rv = SECFailure;
+ CERT_MapStanError();
}
return rv;
}
SECStatus
CERT_AddTempCertToPerm(CERTCertificate *cert, char *nickname,
- CERTCertTrust *trust)
+ CERTCertTrust *trust)
{
return __CERT_AddTempCertToPerm(cert, nickname, trust);
}
CERTCertificate *
CERT_NewTempCertificate(CERTCertDBHandle *handle, SECItem *derCert,
- char *nickname, PRBool isperm, PRBool copyDER)
+ char *nickname, PRBool isperm, PRBool copyDER)
{
NSSCertificate *c;
CERTCertificate *cc;
@@ -354,52 +336,52 @@ CERT_NewTempCertificate(CERTCertDBHandle *handle, SECItem *derCert,
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;
- }
+ 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;
+ CERT_MapStanError();
+ return NULL;
}
c = nss_ZNEW(pkio->arena, NSSCertificate);
if (!c) {
- CERT_MapStanError();
- nssPKIObject_Destroy(pkio);
- return NULL;
+ CERT_MapStanError();
+ nssPKIObject_Destroy(pkio);
+ return NULL;
}
c->object = *pkio;
if (copyDER) {
- nssItem_Create(c->object.arena, &c->encoding,
- derCert->len, derCert->data);
+ nssItem_Create(c->object.arena, &c->encoding, derCert->len,
+ derCert->data);
} else {
- NSSITEM_FROM_SECITEM(&c->encoding, derCert);
+ NSSITEM_FROM_SECITEM(&c->encoding, derCert);
}
/* Forces a decoding of the cert in order to obtain the parts used
* below
@@ -408,40 +390,40 @@ CERT_NewTempCertificate(CERTCertDBHandle *handle, SECItem *derCert,
* allocated so far for 'c' */
cc = STAN_GetCERTCertificate(c);
if (!cc) {
- CERT_MapStanError();
+ 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);
+ 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);
+ /* 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));
+ 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));
+ 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;
+ CERT_MapStanError();
+ goto loser;
}
/* destroy our copy */
NSSCertificate_Destroy(c);
@@ -449,9 +431,9 @@ CERT_NewTempCertificate(CERTCertDBHandle *handle, SECItem *derCert,
c = tempCert;
cc = STAN_GetCERTCertificateOrRelease(c);
if (!cc) {
- /* STAN_GetCERTCertificateOrRelease destroys c on failure. */
- CERT_MapStanError();
- return NULL;
+ /* STAN_GetCERTCertificateOrRelease destroys c on failure. */
+ CERT_MapStanError();
+ return NULL;
}
cc->istemp = PR_TRUE;
@@ -466,20 +448,20 @@ loser:
/* This symbol is exported for backward compatibility. */
CERTCertificate *
__CERT_NewTempCertificate(CERTCertDBHandle *handle, SECItem *derCert,
- char *nickname, PRBool isperm, PRBool copyDER)
+ char *nickname, PRBool isperm, PRBool copyDER)
{
- return CERT_NewTempCertificate(handle, derCert, nickname,
- isperm, 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)
+CERT_FindCertByIssuerAndSN(CERTCertDBHandle *handle,
+ CERTIssuerAndSN *issuerAndSN)
{
PK11SlotInfo *slot;
CERTCertificate *cert;
- cert = PK11_FindCertByIssuerAndSN(&slot,issuerAndSN,NULL);
+ cert = PK11_FindCertByIssuerAndSN(&slot, issuerAndSN, NULL);
if (cert && slot) {
PK11_FreeSlot(slot);
}
@@ -493,9 +475,9 @@ get_best_temp_or_perm(NSSCertificate *ct, NSSCertificate *cp)
NSSUsage usage;
NSSCertificate *arr[3];
if (!ct) {
- return nssCertificate_AddRef(cp);
+ return nssCertificate_AddRef(cp);
} else if (!cp) {
- return nssCertificate_AddRef(ct);
+ return nssCertificate_AddRef(ct);
}
arr[0] = ct;
arr[1] = cp;
@@ -514,16 +496,16 @@ CERT_FindCertByName(CERTCertDBHandle *handle, SECItem *name)
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);
+ 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));
+ CERT_DestroyCertificate(STAN_GetCERTCertificateOrRelease(ct));
}
if (cp) {
- CERT_DestroyCertificate(STAN_GetCERTCertificateOrRelease(cp));
+ CERT_DestroyCertificate(STAN_GetCERTCertificateOrRelease(cp));
}
return c ? STAN_GetCERTCertificateOrRelease(c) : NULL;
}
@@ -535,19 +517,20 @@ CERT_FindCertByKeyID(CERTCertDBHandle *handle, SECItem *name, SECItem *keyID)
CERTCertificate *cert = NULL;
CERTCertListNode *node, *head;
- list = CERT_CreateSubjectCertList(NULL,handle,name,0,PR_FALSE);
- if (list == NULL) return NULL;
+ 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);
+ 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:
@@ -566,18 +549,18 @@ CERT_FindCertByNickname(CERTCertDBHandle *handle, const char *nickname)
NSSUsage usage;
usage.anyUsage = PR_TRUE;
cc = STAN_GetDefaultCryptoContext();
- ct = NSSCryptoContext_FindBestCertificateByNickname(cc, nickname,
- NULL, &usage, NULL);
+ 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));
- }
+ c = get_best_temp_or_perm(ct, STAN_GetNSSCertificate(cert));
+ CERT_DestroyCertificate(cert);
+ if (ct) {
+ CERT_DestroyCertificate(STAN_GetCERTCertificateOrRelease(ct));
+ }
} else {
- c = ct;
+ c = ct;
}
return c ? STAN_GetCERTCertificateOrRelease(c) : NULL;
}
@@ -592,17 +575,17 @@ CERT_FindCertByDERCert(CERTCertDBHandle *handle, SECItem *derCert)
cc = STAN_GetDefaultCryptoContext();
c = NSSCryptoContext_FindCertificateByEncodedCertificate(cc, &encoding);
if (!c) {
- c = NSSTrustDomain_FindCertificateByEncodedCertificate(handle,
- &encoding);
- if (!c) return NULL;
+ c = NSSTrustDomain_FindCertificateByEncodedCertificate(handle,
+ &encoding);
+ if (!c)
+ return NULL;
}
return STAN_GetCERTCertificateOrRelease(c);
}
static CERTCertificate *
-common_FindCertByNicknameOrEmailAddrForUsage(CERTCertDBHandle *handle,
- const char *name,
- PRBool anyUsage,
+common_FindCertByNicknameOrEmailAddrForUsage(CERTCertDBHandle *handle,
+ const char *name, PRBool anyUsage,
SECCertUsage lookingForUsage)
{
NSSCryptoContext *cc;
@@ -613,63 +596,61 @@ common_FindCertByNicknameOrEmailAddrForUsage(CERTCertDBHandle *handle,
if (NULL == name) {
PORT_SetError(SEC_ERROR_INVALID_ARGS);
- return NULL;
+ return NULL;
}
usage.anyUsage = anyUsage;
if (!anyUsage) {
- usage.nss3lookingForCA = PR_FALSE;
- usage.nss3usage = lookingForUsage;
+ usage.nss3lookingForCA = PR_FALSE;
+ usage.nss3usage = lookingForUsage;
}
cc = STAN_GetDefaultCryptoContext();
- ct = NSSCryptoContext_FindBestCertificateByNickname(cc, name,
- NULL, &usage, NULL);
+ ct = NSSCryptoContext_FindBestCertificateByNickname(cc, name, NULL, &usage,
+ NULL);
if (!ct && PORT_Strchr(name, '@') != NULL) {
- char* lowercaseName = CERT_FixupEmailAddr(name);
+ char *lowercaseName = CERT_FixupEmailAddr(name);
if (lowercaseName) {
- ct = NSSCryptoContext_FindBestCertificateByEmail(cc, lowercaseName,
- NULL, &usage, NULL);
+ 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 = 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);
}
- 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));
- }
+ c = get_best_temp_or_perm(ct, STAN_GetNSSCertificate(cert));
+ CERT_DestroyCertificate(cert);
+ if (ct) {
+ CERT_DestroyCertificate(STAN_GetCERTCertificateOrRelease(ct));
+ }
} else {
- c = ct;
+ c = ct;
}
return c ? STAN_GetCERTCertificateOrRelease(c) : NULL;
}
@@ -677,43 +658,41 @@ common_FindCertByNicknameOrEmailAddrForUsage(CERTCertDBHandle *handle,
CERTCertificate *
CERT_FindCertByNicknameOrEmailAddr(CERTCertDBHandle *handle, const char *name)
{
- return common_FindCertByNicknameOrEmailAddrForUsage(handle, name,
- PR_TRUE, 0);
+ return common_FindCertByNicknameOrEmailAddrForUsage(handle, name, PR_TRUE,
+ 0);
}
CERTCertificate *
-CERT_FindCertByNicknameOrEmailAddrForUsage(CERTCertDBHandle *handle,
- const char *name,
+CERT_FindCertByNicknameOrEmailAddrForUsage(CERTCertDBHandle *handle,
+ const char *name,
SECCertUsage lookingForUsage)
{
- return common_FindCertByNicknameOrEmailAddrForUsage(handle, name,
- PR_FALSE,
- lookingForUsage);
+ return common_FindCertByNicknameOrEmailAddrForUsage(handle, name, PR_FALSE,
+ lookingForUsage);
}
-static void
+static void
add_to_subject_list(CERTCertList *certList, CERTCertificate *cert,
PRBool validOnly, PRTime 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);
- }
+ 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);
+ CERT_DestroyCertificate(cert);
}
}
CERTCertList *
CERT_CreateSubjectCertList(CERTCertList *certList, CERTCertDBHandle *handle,
- const SECItem *name, PRTime sorttime,
- PRBool validOnly)
+ const SECItem *name, PRTime sorttime,
+ PRBool validOnly)
{
NSSCryptoContext *cc;
NSSCertificate **tSubjectCerts, **pSubjectCerts;
@@ -724,45 +703,40 @@ CERT_CreateSubjectCertList(CERTCertList *certList, CERTCertDBHandle *handle,
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);
+ tSubjectCerts =
+ NSSCryptoContext_FindCertificatesBySubject(cc, &subject, NULL, 0, NULL);
+ pSubjectCerts = NSSTrustDomain_FindCertificatesBySubject(handle, &subject,
+ NULL, 0, NULL);
if (!tSubjectCerts && !pSubjectCerts) {
- return NULL;
+ return NULL;
}
if (certList == NULL) {
- certList = CERT_NewCertList();
- myList = PR_TRUE;
- if (!certList) goto loser;
+ 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 */
+ 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);
+ /* NOTE: add_to_subject_list adopts the incoming cert. */
+ add_to_subject_list(certList, cert, validOnly, sorttime);
}
- ci++;
+ 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 */
+ 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);
+ /* NOTE: add_to_subject_list adopts the incoming cert. */
+ add_to_subject_list(certList, cert, validOnly, sorttime);
}
- ci++;
+ ci++;
}
/* all the references have been adopted or freed at this point, just
* free the arrays now */
@@ -774,7 +748,7 @@ loser:
nssCertificateArray_Destroy(tSubjectCerts);
nssCertificateArray_Destroy(pSubjectCerts);
if (myList && certList != NULL) {
- CERT_DestroyCertList(certList);
+ CERT_DestroyCertList(certList);
}
return NULL;
}
@@ -782,19 +756,19 @@ loser:
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);
- }
+ 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;
}
@@ -807,8 +781,8 @@ CERT_GetDBContentVersion(CERTCertDBHandle *handle)
}
SECStatus
-certdb_SaveSingleProfile(CERTCertificate *cert, const char *emailAddr,
- SECItem *emailProfile, SECItem *profileTime)
+certdb_SaveSingleProfile(CERTCertificate *cert, const char *emailAddr,
+ SECItem *emailProfile, SECItem *profileTime)
{
PRTime oldtime;
PRTime newtime;
@@ -824,111 +798,109 @@ certdb_SaveSingleProfile(CERTCertificate *cert, const char *emailAddr,
PRBool freeOldProfile = PR_FALSE;
c = STAN_GetNSSCertificate(cert);
- if (!c) return SECFailure;
+ 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;
- }
+ 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;
+ 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 (emailProfile == NULL) {
+ profileTime = NULL;
+ } else if (profileTime == NULL) {
+ emailProfile = NULL;
}
-
- if ( oldProfileTime == NULL ) {
- saveit = PR_TRUE;
+
+ 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;
- }
+ /* 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);
- }
+ if (cc) {
+ if (stanProfile && profileTime && emailProfile) {
+ /* 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;
+ rv = SECSuccess;
}
loser:
if (oldProfile && freeOldProfile) {
- SECITEM_FreeItem(oldProfile,PR_TRUE);
+ SECITEM_FreeItem(oldProfile, PR_TRUE);
}
if (oldProfileTime && freeOldProfile) {
- SECITEM_FreeItem(oldProfileTime,PR_TRUE);
+ SECITEM_FreeItem(oldProfileTime, PR_TRUE);
}
if (stanProfile) {
- nssSMIMEProfile_Destroy(stanProfile);
+ nssSMIMEProfile_Destroy(stanProfile);
}
if (slot) {
- PK11_FreeSlot(slot);
+ PK11_FreeSlot(slot);
}
-
- return(rv);
+
+ return (rv);
}
/*
@@ -939,7 +911,7 @@ loser:
SECStatus
CERT_SaveSMimeProfile(CERTCertificate *cert, SECItem *emailProfile,
- SECItem *profileTime)
+ SECItem *profileTime)
{
const char *emailAddr;
SECStatus rv;
@@ -948,40 +920,39 @@ CERT_SaveSMimeProfile(CERTCertificate *cert, SECItem *emailProfile,
return SECFailure;
}
- if (cert->slot && !PK11_IsInternal(cert->slot)) {
+ 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();
+ PK11SlotInfo *internalslot = PK11_GetInternalKeySlot();
if (!internalslot) {
return SECFailure;
}
- rv = PK11_ImportCert(internalslot, cert,
- CK_INVALID_HANDLE, NULL, PR_FALSE);
+ rv = PK11_ImportCert(internalslot, cert, CK_INVALID_HANDLE, NULL,
+ PR_FALSE);
PK11_FreeSlot(internalslot);
- if (rv != SECSuccess ) {
+ 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;
+ (!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;
- }
+ emailAddr = CERT_GetNextEmailAddress(cert, emailAddr)) {
+ rv = certdb_SaveSingleProfile(cert, emailAddr, emailProfile,
+ profileTime);
+ if (rv != SECSuccess) {
+ return SECFailure;
+ }
}
return SECSuccess;
-
}
-
SECItem *
CERT_FindSMimeProfile(CERTCertificate *cert)
{
@@ -991,29 +962,30 @@ CERT_FindSMimeProfile(CERTCertificate *cert)
SECItem *rvItem = NULL;
if (!cert || !cert->emailAddr || !cert->emailAddr[0]) {
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- return NULL;
+ PORT_SetError(SEC_ERROR_INVALID_ARGS);
+ return NULL;
}
c = STAN_GetNSSCertificate(cert);
- if (!c) return NULL;
+ 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;
+ 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);
+ PK11_FindSMimeProfile(&slot, cert->emailAddr, &cert->derSubject, NULL);
if (slot) {
- PK11_FreeSlot(slot);
+ PK11_FreeSlot(slot);
}
return rvItem;
}
@@ -1050,23 +1022,18 @@ SECKEY_HashPassword(char *pw, SECItem *salt)
SECStatus
__CERT_TraversePermCertsForSubject(CERTCertDBHandle *handle,
- SECItem *derSubject,
- void *cb, void *cbarg)
+ 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)
+ void *cb, void *cbarg)
{
PORT_Assert("CERT_TraversePermCertsForNickname is Deprecated" == NULL);
PORT_SetError(PR_NOT_IMPLEMENTED_ERROR);
return SECFailure;
}
-
-
-
diff --git a/nss/lib/certdb/xauthkid.c b/nss/lib/certdb/xauthkid.c
index 4faf017..c7ef046 100644
--- a/nss/lib/certdb/xauthkid.c
+++ b/nss/lib/certdb/xauthkid.c
@@ -3,7 +3,7 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
/*
- * X.509 v3 Subject Key Usage Extension
+ * X.509 v3 Subject Key Usage Extension
*
*/
@@ -14,7 +14,7 @@
#include "secasn1t.h"
#include "secasn1.h"
#include "secport.h"
-#include "certt.h"
+#include "certt.h"
#include "genname.h"
#include "secerr.h"
@@ -24,105 +24,105 @@ 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},
+ 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) },
+ offsetof(CERTAuthKeyID, authCertSerialNumber),
+ SEC_ASN1_SUB(SEC_IntegerTemplate) },
{ 0 }
};
-
-
-SECStatus CERT_EncodeAuthKeyID (PLArenaPool *arena, CERTAuthKeyID *value, SECItem *encodedValue)
+SECStatus
+CERT_EncodeAuthKeyID(PLArenaPool *arena, CERTAuthKeyID *value,
+ SECItem *encodedValue)
{
SECStatus rv = SECFailure;
-
- PORT_Assert (value);
- PORT_Assert (arena);
- PORT_Assert (value->DERAuthCertIssuer == NULL);
- PORT_Assert (encodedValue);
+
+ 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;
+
+ /* 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);
+ return (rv);
}
CERTAuthKeyID *
-CERT_DecodeAuthKeyID (PLArenaPool *arena, const SECItem *encodedValue)
+CERT_DecodeAuthKeyID(PLArenaPool *arena, const SECItem *encodedValue)
{
- CERTAuthKeyID * value = NULL;
- SECStatus rv = SECFailure;
- void * mark;
- SECItem newEncodedValue;
+ CERTAuthKeyID *value = NULL;
+ SECStatus rv = SECFailure;
+ void *mark;
+ SECItem newEncodedValue;
+
+ PORT_Assert(arena);
- PORT_Assert (arena);
-
do {
- mark = PORT_ArenaMark (arena);
- value = (CERTAuthKeyID*)PORT_ArenaZAlloc (arena, sizeof (*value));
- if (value == NULL)
- break;
- value->DERAuthCertIssuer = NULL;
+ 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;
+ 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;
- }
+ 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_ArenaRelease(arena, mark);
+ return ((CERTAuthKeyID *)NULL);
+ }
PORT_ArenaUnmark(arena, mark);
return (value);
}
diff --git a/nss/lib/certdb/xbsconst.c b/nss/lib/certdb/xbsconst.c
index 7a3cb1c..4f01f51 100644
--- a/nss/lib/certdb/xbsconst.c
+++ b/nss/lib/certdb/xbsconst.c
@@ -3,11 +3,11 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
/*
- * X.509 v3 Basic Constraints Extension
+ * X.509 v3 Basic Constraints Extension
*/
#include "prtypes.h"
-#include <limits.h> /* for LONG_MAX */
+#include <limits.h> /* for LONG_MAX */
#include "seccomon.h"
#include "secdert.h"
#include "secoidt.h"
@@ -18,128 +18,126 @@
#include "prprf.h"
#include "secerr.h"
-typedef struct EncodedContext{
+typedef struct EncodedContext {
SECItem isCA;
SECItem pathLenConstraint;
SECItem encodedValue;
PLArenaPool *arena;
-}EncodedContext;
+} 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_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, }
+ offsetof(EncodedContext, pathLenConstraint) },
+ { 0 }
};
static unsigned char hexTrue = 0xff;
static unsigned char hexFalse = 0x00;
-#define GEN_BREAK(status) rv = status; break;
+#define GEN_BREAK(status) \
+ rv = status; \
+ break;
-SECStatus CERT_EncodeBasicConstraintValue
- (PLArenaPool *arena, CERTBasicConstraints *value, SECItem *encodedValue)
+SECStatus
+CERT_EncodeBasicConstraintValue(PLArenaPool *arena, CERTBasicConstraints *value,
+ SECItem *encodedValue)
{
EncodedContext encodeContext;
PLArenaPool *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);
- }
+ 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);
- }
+ 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);
-
+ PORT_FreeArena(our_pool, PR_FALSE);
+ return (rv);
}
-SECStatus CERT_DecodeBasicConstraintValue
- (CERTBasicConstraints *value, const SECItem *encodedValue)
+SECStatus
+CERT_DecodeBasicConstraintValue(CERTBasicConstraints *value,
+ const SECItem *encodedValue)
{
EncodedContext decodeContext;
- PLArenaPool *our_pool;
+ PORTCheapArenaPool tmpArena;
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.
+ 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;
- }
-
+ decodeContext.isCA.data = &hexFalse;
+ decodeContext.isCA.len = 1;
+
+ PORT_InitCheapArena(&tmpArena, SEC_ASN1_DEFAULT_ARENA_SIZE);
+
+ rv = SEC_QuickDERDecodeItem(&tmpArena.arena, &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);
+ PORT_DestroyCheapArena(&tmpArena);
+ return (rv);
}
diff --git a/nss/lib/certdb/xconst.c b/nss/lib/certdb/xconst.c
index 495987c..9a5634a 100644
--- a/nss/lib/certdb/xconst.c
+++ b/nss/lib/certdb/xconst.c
@@ -3,7 +3,7 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
/*
- * X.509 Extension Encoding
+ * X.509 Extension Encoding
*/
#include "prtypes.h"
@@ -20,12 +20,10 @@
#include "secasn1.h"
#include "secerr.h"
-
static const SEC_ASN1Template CERTSubjectKeyIDTemplate[] = {
{ SEC_ASN1_OCTET_STRING }
};
-
static const SEC_ASN1Template CERTIA5TypeTemplate[] = {
{ SEC_ASN1_IA5_STRING }
};
@@ -33,40 +31,34 @@ static const SEC_ASN1Template CERTIA5TypeTemplate[] = {
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, }
+ { 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}
+ { 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, }
+ { 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(PLArenaPool *arena, const SECItem* srcString,
+SECStatus
+CERT_EncodeSubjectKeyID(PLArenaPool *arena, const SECItem *srcString,
SECItem *encodedValue)
{
SECStatus rv = SECSuccess;
@@ -75,27 +67,26 @@ CERT_EncodeSubjectKeyID(PLArenaPool *arena, const SECItem* srcString,
PORT_SetError(SEC_ERROR_INVALID_ARGS);
return SECFailure;
}
- if (SEC_ASN1EncodeItem (arena, encodedValue, srcString,
- CERTSubjectKeyIDTemplate) == NULL) {
- rv = SECFailure;
+ if (SEC_ASN1EncodeItem(arena, encodedValue, srcString,
+ CERTSubjectKeyIDTemplate) == NULL) {
+ rv = SECFailure;
}
-
- return(rv);
-}
+ return (rv);
+}
SECStatus
CERT_EncodePrivateKeyUsagePeriod(PLArenaPool *arena,
- CERTPrivKeyUsagePeriod *pkup,
- SECItem *encodedValue)
+ CERTPrivKeyUsagePeriod *pkup,
+ SECItem *encodedValue)
{
SECStatus rv = SECSuccess;
- if (SEC_ASN1EncodeItem (arena, encodedValue, pkup,
- CERTPrivateKeyUsagePeriodTemplate) == NULL) {
- rv = SECFailure;
+ if (SEC_ASN1EncodeItem(arena, encodedValue, pkup,
+ CERTPrivateKeyUsagePeriodTemplate) == NULL) {
+ rv = SECFailure;
}
- return(rv);
+ return (rv);
}
CERTPrivKeyUsagePeriod *
@@ -107,63 +98,62 @@ CERT_DecodePrivKeyUsagePeriodExtension(PLArenaPool *arena, SECItem *extnValue)
/* allocate the certificate policies structure */
pPeriod = PORT_ArenaZNew(arena, CERTPrivKeyUsagePeriod);
- if ( pPeriod == NULL ) {
- goto loser;
+ 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;
+ if (rv != SECSuccess) {
+ goto loser;
}
- rv = SEC_QuickDERDecodeItem(arena, pPeriod,
- CERTPrivateKeyUsagePeriodTemplate,
- &newExtnValue);
- 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(PLArenaPool *arena, char *value, SECItem *encodedValue)
+SECStatus
+CERT_EncodeIA5TypeExtension(PLArenaPool *arena, char *value,
+ SECItem *encodedValue)
{
SECItem encodeContext;
SECStatus rv = SECSuccess;
+ PORT_Memset(&encodeContext, 0, sizeof(encodeContext));
- PORT_Memset (&encodeContext, 0, sizeof (encodeContext));
-
if (value != NULL) {
- encodeContext.data = (unsigned char *)value;
- encodeContext.len = strlen(value);
+ encodeContext.data = (unsigned char *)value;
+ encodeContext.len = strlen(value);
}
- if (SEC_ASN1EncodeItem (arena, encodedValue, &encodeContext,
- CERTIA5TypeTemplate) == NULL) {
- rv = SECFailure;
+ if (SEC_ASN1EncodeItem(arena, encodedValue, &encodeContext,
+ CERTIA5TypeTemplate) == NULL) {
+ rv = SECFailure;
}
-
- return(rv);
+
+ return (rv);
}
SECStatus
-CERT_EncodeAltNameExtension(PLArenaPool *arena, CERTGeneralName *value, SECItem *encodedValue)
+CERT_EncodeAltNameExtension(PLArenaPool *arena, CERTGeneralName *value,
+ SECItem *encodedValue)
{
- SECItem **encodedGenName;
- SECStatus rv = SECSuccess;
+ SECItem **encodedGenName;
+ SECStatus rv = SECSuccess;
encodedGenName = cert_EncodeGeneralNames(arena, value);
- if (SEC_ASN1EncodeItem (arena, encodedValue, &encodedGenName,
- CERT_GeneralNamesTemplate) == NULL) {
- rv = SECFailure;
+ if (SEC_ASN1EncodeItem(arena, encodedValue, &encodedGenName,
+ CERT_GeneralNamesTemplate) == NULL) {
+ rv = SECFailure;
}
return rv;
@@ -172,9 +162,9 @@ CERT_EncodeAltNameExtension(PLArenaPool *arena, CERTGeneralName *value, SECIte
CERTGeneralName *
CERT_DecodeAltNameExtension(PLArenaPool *reqArena, SECItem *EncodedAltName)
{
- SECStatus rv = SECSuccess;
- CERTAltNameEncodedContext encodedContext;
- SECItem* newEncodedAltName;
+ SECStatus rv = SECSuccess;
+ CERTAltNameEncodedContext encodedContext;
+ SECItem *newEncodedAltName;
if (!reqArena) {
PORT_SetError(SEC_ERROR_INVALID_ARGS);
@@ -188,14 +178,13 @@ CERT_DecodeAltNameExtension(PLArenaPool *reqArena, SECItem *EncodedAltName)
encodedContext.encodedGenName = NULL;
PORT_Memset(&encodedContext, 0, sizeof(CERTAltNameEncodedContext));
- rv = SEC_QuickDERDecodeItem (reqArena, &encodedContext,
- CERT_GeneralNamesTemplate, newEncodedAltName);
+ rv = SEC_QuickDERDecodeItem(reqArena, &encodedContext,
+ CERT_GeneralNamesTemplate, newEncodedAltName);
if (rv == SECFailure) {
- goto loser;
+ goto loser;
}
if (encodedContext.encodedGenName && encodedContext.encodedGenName[0])
- return cert_DecodeGeneralNames(reqArena,
- encodedContext.encodedGenName);
+ return cert_DecodeGeneralNames(reqArena, encodedContext.encodedGenName);
/* Extension contained an empty GeneralNames sequence */
/* Treat as extension not found */
PORT_SetError(SEC_ERROR_EXTENSION_NOT_FOUND);
@@ -203,35 +192,32 @@ loser:
return NULL;
}
-
SECStatus
-CERT_EncodeNameConstraintsExtension(PLArenaPool *arena,
- CERTNameConstraints *value,
- SECItem *encodedValue)
+CERT_EncodeNameConstraintsExtension(PLArenaPool *arena,
+ CERTNameConstraints *value,
+ SECItem *encodedValue)
{
- SECStatus rv = SECSuccess;
-
+ SECStatus rv = SECSuccess;
+
rv = cert_EncodeNameConstraints(value, arena, encodedValue);
return rv;
}
-
CERTNameConstraints *
-CERT_DecodeNameConstraintsExtension(PLArenaPool *arena,
- const SECItem *encodedConstraints)
+CERT_DecodeNameConstraintsExtension(PLArenaPool *arena,
+ const SECItem *encodedConstraints)
{
return cert_DecodeNameConstraints(arena, encodedConstraints);
}
-
CERTAuthInfoAccess **
CERT_DecodeAuthInfoAccessExtension(PLArenaPool *reqArena,
- const SECItem *encodedExtension)
+ const SECItem *encodedExtension)
{
CERTAuthInfoAccess **info = NULL;
SECStatus rv;
int i;
- SECItem* newEncodedExtension;
+ SECItem *newEncodedExtension;
if (!reqArena) {
PORT_SetError(SEC_ERROR_INVALID_ARGS);
@@ -243,24 +229,22 @@ CERT_DecodeAuthInfoAccessExtension(PLArenaPool *reqArena,
return NULL;
}
- rv = SEC_QuickDERDecodeItem(reqArena, &info, CERTAuthInfoAccessTemplate,
- newEncodedExtension);
+ rv = SEC_QuickDERDecodeItem(reqArena, &info, CERTAuthInfoAccessTemplate,
+ newEncodedExtension);
if (rv != SECSuccess || info == NULL) {
- return NULL;
+ return NULL;
}
for (i = 0; info[i] != NULL; i++) {
- info[i]->location = CERT_DecodeGeneralName(reqArena,
- &(info[i]->derLocation),
- NULL);
+ info[i]->location =
+ CERT_DecodeGeneralName(reqArena, &(info[i]->derLocation), NULL);
}
return info;
}
SECStatus
-CERT_EncodeInfoAccessExtension(PLArenaPool *arena,
- CERTAuthInfoAccess **info,
- SECItem *dest)
+CERT_EncodeInfoAccessExtension(PLArenaPool *arena, CERTAuthInfoAccess **info,
+ SECItem *dest)
{
SECItem *dummy;
int i;
@@ -268,19 +252,18 @@ CERT_EncodeInfoAccessExtension(PLArenaPool *arena,
PORT_Assert(info != NULL);
PORT_Assert(dest != NULL);
if (info == NULL || dest == NULL) {
- return SECFailure;
+ 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;
+ 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);
+ dummy = SEC_ASN1EncodeItem(arena, dest, &info, CERTAuthInfoAccessTemplate);
if (dummy == NULL) {
- return SECFailure;
+ return SECFailure;
}
return SECSuccess;
}
diff --git a/nss/lib/certdb/xconst.h b/nss/lib/certdb/xconst.h
index 72767c3..8cf2e82 100644
--- a/nss/lib/certdb/xconst.h
+++ b/nss/lib/certdb/xconst.h
@@ -10,27 +10,21 @@ typedef struct CERTAltNameEncodedContextStr {
SECItem **encodedGenName;
} CERTAltNameEncodedContext;
-
-
SEC_BEGIN_PROTOS
-extern SECStatus
-CERT_EncodePrivateKeyUsagePeriod(PLArenaPool *arena,
- CERTPrivKeyUsagePeriod *pkup,
- SECItem *encodedValue);
+extern SECStatus CERT_EncodePrivateKeyUsagePeriod(PLArenaPool *arena,
+ CERTPrivKeyUsagePeriod *pkup,
+ SECItem *encodedValue);
-extern SECStatus
-CERT_EncodeNameConstraintsExtension(PLArenaPool *arena,
- CERTNameConstraints *value,
- SECItem *encodedValue);
+extern SECStatus CERT_EncodeNameConstraintsExtension(PLArenaPool *arena,
+ CERTNameConstraints *value,
+ SECItem *encodedValue);
-extern SECStatus
-CERT_EncodeIA5TypeExtension(PLArenaPool *arena, char *value,
- SECItem *encodedValue);
+extern SECStatus CERT_EncodeIA5TypeExtension(PLArenaPool *arena, char *value,
+ SECItem *encodedValue);
-SECStatus
-cert_EncodeAuthInfoAccessExtension(PLArenaPool *arena,
- CERTAuthInfoAccess **info,
- SECItem *dest);
+SECStatus cert_EncodeAuthInfoAccessExtension(PLArenaPool *arena,
+ CERTAuthInfoAccess **info,
+ SECItem *dest);
SEC_END_PROTOS
#endif
diff --git a/nss/lib/certhigh/certhigh.c b/nss/lib/certhigh/certhigh.c
index b06b7af..5525989 100644
--- a/nss/lib/certhigh/certhigh.c
+++ b/nss/lib/certhigh/certhigh.c
@@ -17,36 +17,36 @@
#include "pkitm.h"
#include "pki3hack.h"
-
PRBool
-CERT_MatchNickname(char *name1, char *name2) {
- char *nickname1= NULL;
+CERT_MatchNickname(char *name1, char *name2)
+{
+ char *nickname1 = NULL;
char *nickname2 = NULL;
char *token1;
char *token2;
/* first deal with the straight comparison */
if (PORT_Strcmp(name1, name2) == 0) {
- return PR_TRUE;
+ 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,':');
+ 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;
+ /* either both token names are specified or neither are, not match */
+ return PR_FALSE;
}
if (token1) {
- nickname1=token1;
- nickname2=name2;
+ nickname1 = token1;
+ nickname2 = name2;
} else {
- nickname1=token2;
- nickname2=name1;
+ nickname1 = token2;
+ nickname2 = name1;
}
nickname1++;
- if (PORT_Strcmp(nickname1,nickname2) != 0) {
- return PR_FALSE;
+ if (PORT_Strcmp(nickname1, nickname2) != 0) {
+ return PR_FALSE;
}
/* Bug 1192443 - compare the other token with the internal slot here */
return PR_TRUE;
@@ -54,20 +54,20 @@ CERT_MatchNickname(char *name1, char *name2) {
/*
* 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
+ *
+ * "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)
+ SECCertUsage usage,
+ PRBool oneCertPerName,
+ PRBool validOnly,
+ void *proto_win)
{
CERTCertNicknames *nicknames = NULL;
char **nnptr;
@@ -79,267 +79,268 @@ CERT_FindUserCertsByUsage(CERTCertDBHandle *handle,
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;
+ 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--;
+ 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;
+ 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);
+ if (oneCertPerName) {
+ PRBool *flags;
+
+ nn = nicknames->numnicknames;
+ nnptr = nicknames->nicknames;
+
+ if (!certList) {
+ goto loser;
+ }
+
+ 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;
+ if (certList != NULL) {
+ CERT_DestroyCertList(certList);
+ certList = NULL;
}
done:
- if ( nicknames != NULL ) {
- CERT_FreeNicknames(nicknames);
+ if (nicknames != NULL) {
+ CERT_FreeNicknames(nicknames);
}
- return(certList);
+ 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
+ *
+ * "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)
+ const char *nickname,
+ SECCertUsage usage,
+ PRBool validOnly,
+ void *proto_win)
{
CERTCertificate *cert = NULL;
CERTCertList *certList = NULL;
SECStatus rv;
PRTime 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);
+ 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);
+ 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 (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;
+
+ if (certList == NULL) {
+ goto loser;
}
-
+
/* remove certs with incorrect usage */
rv = CERT_FilterCertListByUsage(certList, usage, PR_FALSE);
- if ( rv != SECSuccess ) {
- goto loser;
+ if (rv != SECSuccess) {
+ goto loser;
}
- if ( ! CERT_LIST_END(CERT_LIST_HEAD(certList), certList) ) {
- cert = CERT_DupCertificate(CERT_LIST_HEAD(certList)->cert);
+ if (!CERT_LIST_END(CERT_LIST_HEAD(certList), certList)) {
+ cert = CERT_DupCertificate(CERT_LIST_HEAD(certList)->cert);
}
-
+
loser:
- if ( certList != NULL ) {
- CERT_DestroyCertList(certList);
+ if (certList != NULL) {
+ CERT_DestroyCertList(certList);
}
- return(cert);
+ return (cert);
}
CERTCertList *
CERT_MatchUserCert(CERTCertDBHandle *handle,
- SECCertUsage usage,
- int nCANames, char **caNames,
- void *proto_win)
+ 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;
+ proto_win);
+ if (certList == NULL) {
+ goto loser;
}
-
+
rv = CERT_FilterCertListByCANames(certList, nCANames, caNames, usage);
- if ( rv != SECSuccess ) {
- goto loser;
+ if (rv != SECSuccess) {
+ goto loser;
}
-
+
goto done;
-
+
loser:
- if ( certList != NULL ) {
- CERT_DestroyCertList(certList);
- certList = NULL;
+ if (certList != NULL) {
+ CERT_DestroyCertList(certList);
+ certList = NULL;
}
done:
- return(certList);
+ return (certList);
}
-
typedef struct stringNode {
struct stringNode *next;
char *string;
} stringNode;
-
+
static PRStatus
-CollectNicknames( NSSCertificate *c, void *data)
+CollectNicknames(NSSCertificate *c, void *data)
{
CERTCertNicknames *names;
PRBool saveit = PR_FALSE;
@@ -351,103 +352,104 @@ CollectNicknames( NSSCertificate *c, void *data)
#endif
char *stanNickname;
char *nickname = NULL;
-
+
names = (CERTCertNicknames *)data;
- stanNickname = nssCertificate_GetNickname(c,NULL);
-
- if ( stanNickname ) {
+ 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);
- }
+ 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;
- }
- }
+ 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) {
+ 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 (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);
+
+ if (nickname)
+ PORT_Free(nickname);
+ return (PR_SUCCESS);
}
CERTCertNicknames *
@@ -457,16 +459,16 @@ CERT_GetCertNicknames(CERTCertDBHandle *handle, int what, void *wincx)
CERTCertNicknames *names;
int i;
stringNode *node;
-
+
arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
- if ( arena == NULL ) {
- PORT_SetError(SEC_ERROR_NO_MEMORY);
- return(NULL);
+ if (arena == NULL) {
+ PORT_SetError(SEC_ERROR_NO_MEMORY);
+ return (NULL);
}
-
+
names = (CERTCertNicknames *)PORT_ArenaAlloc(arena, sizeof(CERTCertNicknames));
- if ( names == NULL ) {
- goto loser;
+ if (names == NULL) {
+ goto loser;
}
names->arena = arena;
@@ -477,43 +479,44 @@ CERT_GetCertNicknames(CERTCertDBHandle *handle, int what, void *wincx)
names->totallen = 0;
/* make sure we are logged in */
- (void) pk11_TraverseAllSlots(NULL, NULL, PR_TRUE, wincx);
-
+ (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);
+ 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);
-
+ return (names);
+
loser:
PORT_FreeArena(arena, PR_FALSE);
- return(NULL);
+ return (NULL);
}
void
CERT_FreeNicknames(CERTCertNicknames *nicknames)
{
PORT_FreeArena(nicknames->arena, PR_FALSE);
-
+
return;
}
@@ -528,53 +531,53 @@ void
CERT_FreeDistNames(CERTDistNames *names)
{
PORT_FreeArena(names->arena, PR_FALSE);
-
+
return;
}
static SECStatus
-CollectDistNames( CERTCertificate *cert, SECItem *k, void *data)
+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 (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++;
+ 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 (SECSuccess);
}
/*
@@ -587,18 +590,18 @@ CERT_DupDistNames(CERTDistNames *orig)
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);
+ PORT_SetError(SEC_ERROR_NO_MEMORY);
+ return (NULL);
}
-
+
/* allocate the header structure */
names = (CERTDistNames *)PORT_ArenaAlloc(arena, sizeof(CERTDistNames));
if (names == NULL) {
- goto loser;
+ goto loser;
}
/* initialize the header struct */
@@ -606,26 +609,26 @@ CERT_DupDistNames(CERTDistNames *orig)
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++) {
+ 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);
-
+ return (names);
+
loser:
PORT_FreeArena(arena, PR_FALSE);
- return(NULL);
+ return (NULL);
}
CERTDistNames *
@@ -636,18 +639,18 @@ CERT_GetSSLCACerts(CERTCertDBHandle *handle)
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);
+ 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;
+ if (names == NULL) {
+ goto loser;
}
/* initialize the header struct */
@@ -655,48 +658,48 @@ CERT_GetSSLCACerts(CERTCertDBHandle *handle)
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;
+ 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);
+ 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);
-
+ return (names);
+
loser:
PORT_FreeArena(arena, PR_FALSE);
- return(NULL);
+ return (NULL);
}
CERTDistNames *
CERT_DistNamesFromCertList(CERTCertList *certList)
{
- CERTDistNames * dnames = NULL;
- PLArenaPool * arena;
+ CERTDistNames *dnames = NULL;
+ PLArenaPool *arena;
CERTCertListNode *node = NULL;
- SECItem * names = NULL;
- int listLen = 0, i = 0;
+ SECItem *names = NULL;
+ int listLen = 0, i = 0;
if (certList == NULL) {
PORT_SetError(SEC_ERROR_INVALID_ARGS);
@@ -704,23 +707,26 @@ CERT_DistNamesFromCertList(CERTCertList *certList)
}
node = CERT_LIST_HEAD(certList);
- while ( ! CERT_LIST_END(node, 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;
+ if (arena == NULL)
+ goto loser;
dnames = PORT_ArenaZNew(arena, CERTDistNames);
- if (dnames == NULL) goto loser;
+ if (dnames == NULL)
+ goto loser;
dnames->arena = arena;
dnames->nnames = listLen;
dnames->names = names = PORT_ArenaZNewArray(arena, SECItem, listLen);
- if (names == NULL) goto loser;
+ if (names == NULL)
+ goto loser;
node = CERT_LIST_HEAD(certList);
- while ( ! CERT_LIST_END(node, certList) ) {
+ while (!CERT_LIST_END(node, certList)) {
CERTCertificate *cert = node->cert;
SECStatus rv = SECITEM_CopyItem(arena, &names[i++], &cert->derSubject);
if (rv == SECFailure) {
@@ -738,38 +744,43 @@ loser:
CERTDistNames *
CERT_DistNamesFromNicknames(CERTCertDBHandle *handle, char **nicknames,
- int nnames)
+ int nnames)
{
CERTDistNames *dnames = NULL;
PLArenaPool *arena;
int i, rv;
SECItem *names = NULL;
CERTCertificate *cert = NULL;
-
+
arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
- if (arena == NULL) goto loser;
+ if (arena == NULL)
+ goto loser;
dnames = PORT_ArenaZNew(arena, CERTDistNames);
- if (dnames == NULL) goto loser;
+ if (dnames == NULL)
+ goto loser;
dnames->arena = arena;
dnames->nnames = nnames;
dnames->names = names = PORT_ArenaZNewArray(arena, SECItem, nnames);
- if (names == NULL) goto loser;
-
+ 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);
+ 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);
+ CERT_DestroyCertificate(cert);
if (arena != NULL)
- PORT_FreeArena(arena, PR_FALSE);
+ PORT_FreeArena(arena, PR_FALSE);
return NULL;
}
@@ -784,36 +795,36 @@ CERT_FindCertByNameString(CERTCertDBHandle *handle, char *nameStr)
SECItem *nameItem;
CERTCertificate *cert = NULL;
PLArenaPool *arena = NULL;
-
+
arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
-
- if ( arena == NULL ) {
- goto loser;
+
+ if (arena == NULL) {
+ goto loser;
}
-
+
name = CERT_AsciiToName(nameStr);
-
- if ( name ) {
- nameItem = SEC_ASN1EncodeItem (arena, NULL, (void *)name,
- CERT_NameTemplate);
- if ( nameItem != NULL ) {
+
+ if (name) {
+ nameItem = SEC_ASN1EncodeItem(arena, NULL, (void *)name,
+ CERT_NameTemplate);
+ if (nameItem != NULL) {
cert = CERT_FindCertByName(handle, nameItem);
- }
- CERT_DestroyName(name);
+ }
+ CERT_DestroyName(name);
}
loser:
- if ( arena ) {
- PORT_FreeArena(arena, PR_FALSE);
+ if (arena) {
+ PORT_FreeArena(arena, PR_FALSE);
}
-
- return(cert);
+
+ return (cert);
}
/* From certv3.c */
CERTCrlDistributionPoints *
-CERT_FindCRLDistributionPoints (CERTCertificate *cert)
+CERT_FindCRLDistributionPoints(CERTCertificate *cert)
{
SECItem encodedExtenValue;
SECStatus rv;
@@ -823,9 +834,9 @@ CERT_FindCRLDistributionPoints (CERTCertificate *cert)
encodedExtenValue.len = 0;
rv = cert_FindExtension(cert->extensions, SEC_OID_X509_CRL_DIST_POINTS,
- &encodedExtenValue);
- if ( rv != SECSuccess ) {
- return (NULL);
+ &encodedExtenValue);
+ if (rv != SECSuccess) {
+ return (NULL);
}
dps = CERT_DecodeCRLDistributionPoints(cert->arena, &encodedExtenValue);
@@ -836,13 +847,13 @@ CERT_FindCRLDistributionPoints (CERTCertificate *cert)
}
/* From crl.c */
-CERTSignedCrl * CERT_ImportCRL
- (CERTCertDBHandle *handle, SECItem *derCRL, char *url, int type, void *wincx)
+CERTSignedCrl *
+CERT_ImportCRL(CERTCertDBHandle *handle, SECItem *derCRL, char *url, int type, void *wincx)
{
- CERTSignedCrl* retCrl = NULL;
- PK11SlotInfo* slot = PK11_GetInternalKeySlot();
+ CERTSignedCrl *retCrl = NULL;
+ PK11SlotInfo *slot = PK11_GetInternalKeySlot();
retCrl = PK11_ImportCRL(slot, derCRL, url, type, wincx,
- CRL_IMPORT_DEFAULT_OPTIONS, NULL, CRL_DECODE_DEFAULT_OPTIONS);
+ CRL_IMPORT_DEFAULT_OPTIONS, NULL, CRL_DECODE_DEFAULT_OPTIONS);
PK11_FreeSlot(slot);
return retCrl;
@@ -861,110 +872,109 @@ cert_ImportCAChain(SECItem *certs, int numcerts, SECCertUsage certUsage, PRBool
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;
- }
-
+ 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;
@@ -972,18 +982,18 @@ endloop:
loser:
rv = SECFailure;
done:
-
- if ( newcert ) {
- CERT_DestroyCertificate(newcert);
- newcert = NULL;
+
+ if (newcert) {
+ CERT_DestroyCertificate(newcert);
+ newcert = NULL;
}
-
- if ( cert ) {
- CERT_DestroyCertificate(cert);
- cert = NULL;
+
+ if (cert) {
+ CERT_DestroyCertificate(cert);
+ cert = NULL;
}
-
- return(rv);
+
+ return (rv);
}
SECStatus
@@ -993,7 +1003,8 @@ CERT_ImportCAChain(SECItem *certs, int numcerts, SECCertUsage certUsage)
}
SECStatus
-CERT_ImportCAChainTrusted(SECItem *certs, int numcerts, SECCertUsage certUsage) {
+CERT_ImportCAChainTrusted(SECItem *certs, int numcerts, SECCertUsage certUsage)
+{
return cert_ImportCAChain(certs, numcerts, certUsage, PR_TRUE);
}
@@ -1014,7 +1025,7 @@ typedef struct certNode {
CERTCertificateList *
CERT_CertChainFromCert(CERTCertificate *cert, SECCertUsage usage,
- PRBool includeRoot)
+ PRBool includeRoot)
{
CERTCertificateList *chain = NULL;
NSSCertificate **stanChain;
@@ -1022,7 +1033,7 @@ CERT_CertChainFromCert(CERTCertificate *cert, SECCertUsage usage,
PLArenaPool *arena;
NSSUsage nssUsage;
int i, len;
- NSSTrustDomain *td = STAN_GetDefaultTrustDomain();
+ NSSTrustDomain *td = STAN_GetDefaultTrustDomain();
NSSCryptoContext *cc = STAN_GetDefaultCryptoContext();
stanCert = STAN_GetNSSCertificate(cert);
@@ -1034,55 +1045,57 @@ CERT_CertChainFromCert(CERTCertificate *cert, SECCertUsage usage,
nssUsage.nss3usage = usage;
nssUsage.nss3lookingForCA = PR_FALSE;
stanChain = NSSCertificate_BuildChain(stanCert, NULL, &nssUsage, NULL, NULL,
- CERT_MAX_CERT_CHAIN, NULL, NULL, td, cc);
+ CERT_MAX_CERT_CHAIN, NULL, NULL, td, cc);
if (!stanChain) {
- PORT_SetError(SEC_ERROR_UNKNOWN_ISSUER);
- return NULL;
+ PORT_SetError(SEC_ERROR_UNKNOWN_ISSUER);
+ return NULL;
}
len = 0;
stanCert = stanChain[0];
while (stanCert) {
- stanCert = stanChain[++len];
+ stanCert = stanChain[++len];
}
arena = PORT_NewArena(4096);
if (arena == NULL) {
- goto loser;
+ 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;
+ 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);
+ 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;
+ if (!includeRoot && len > 1) {
+ chain->len = len - 1;
} else {
- chain->len = len;
+ chain->len = len;
}
-
+
chain->arena = arena;
nss_ZFreeIf(stanChain);
return chain;
@@ -1090,15 +1103,15 @@ loser:
i = 0;
stanCert = stanChain[i];
while (stanCert) {
- CERTCertificate *cCert = STAN_GetCERTCertificate(stanCert);
- if (cCert) {
- CERT_DestroyCertificate(cCert);
- }
- stanCert = stanChain[++i];
+ CERTCertificate *cCert = STAN_GetCERTCertificate(stanCert);
+ if (cCert) {
+ CERT_DestroyCertificate(cCert);
+ }
+ stanCert = stanChain[++i];
}
nss_ZFreeIf(stanChain);
if (arena) {
- PORT_FreeArena(arena, PR_FALSE);
+ PORT_FreeArena(arena, PR_FALSE);
}
return NULL;
}
@@ -1115,15 +1128,19 @@ CERT_CertListFromCert(CERTCertificate *cert)
/* arena for SecCertificateList */
arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
- if (arena == NULL) goto no_memory;
+ 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;
+ 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;
+ if (rv < 0)
+ goto loser;
chain->len = 1;
chain->arena = arena;
@@ -1133,41 +1150,41 @@ no_memory:
PORT_SetError(SEC_ERROR_NO_MEMORY);
loser:
if (arena != NULL) {
- PORT_FreeArena(arena, PR_FALSE);
+ PORT_FreeArena(arena, PR_FALSE);
}
return NULL;
}
CERTCertificateList *
-CERT_DupCertList(const CERTCertificateList * oldList)
+CERT_DupCertList(const CERTCertificateList *oldList)
{
CERTCertificateList *newList = NULL;
- PLArenaPool *arena = NULL;
- SECItem *newItem;
- SECItem *oldItem;
- int len = oldList->len;
- int rv;
+ PLArenaPool *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;
+ if (arena == NULL)
+ goto no_memory;
/* now build the CERTCertificateList */
newList = PORT_ArenaNew(arena, CERTCertificateList);
- if (newList == NULL)
- goto no_memory;
+ if (newList == NULL)
+ goto no_memory;
newList->arena = arena;
- newItem = (SECItem*)PORT_ArenaAlloc(arena, len * sizeof(SECItem));
- if (newItem == NULL)
- goto no_memory;
+ newItem = (SECItem *)PORT_ArenaAlloc(arena, len * sizeof(SECItem));
+ if (newItem == NULL)
+ goto no_memory;
newList->certs = newItem;
- newList->len = len;
+ newList->len = len;
for (oldItem = oldList->certs; len > 0; --len, ++newItem, ++oldItem) {
- rv = SECITEM_CopyItem(arena, newItem, oldItem);
- if (rv < 0)
- goto loser;
+ rv = SECITEM_CopyItem(arena, newItem, oldItem);
+ if (rv < 0)
+ goto loser;
}
return newList;
@@ -1175,7 +1192,7 @@ no_memory:
PORT_SetError(SEC_ERROR_NO_MEMORY);
loser:
if (arena != NULL) {
- PORT_FreeArena(arena, PR_FALSE);
+ PORT_FreeArena(arena, PR_FALSE);
}
return NULL;
}
@@ -1185,4 +1202,3 @@ CERT_DestroyCertificateList(CERTCertificateList *list)
{
PORT_FreeArena(list->arena, PR_FALSE);
}
-
diff --git a/nss/lib/certhigh/certhigh.gyp b/nss/lib/certhigh/certhigh.gyp
new file mode 100644
index 0000000..5817c3e
--- /dev/null
+++ b/nss/lib/certhigh/certhigh.gyp
@@ -0,0 +1,31 @@
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+{
+ 'includes': [
+ '../../coreconf/config.gypi'
+ ],
+ 'targets': [
+ {
+ 'target_name': 'certhi',
+ 'type': 'static_library',
+ 'sources': [
+ 'certhigh.c',
+ 'certhtml.c',
+ 'certreq.c',
+ 'certvfy.c',
+ 'certvfypkix.c',
+ 'crlv2.c',
+ 'ocsp.c',
+ 'ocspsig.c',
+ 'xcrldist.c'
+ ],
+ 'dependencies': [
+ '<(DEPTH)/exports.gyp:nss_exports'
+ ]
+ }
+ ],
+ 'variables': {
+ 'module': 'nss'
+ }
+} \ No newline at end of file
diff --git a/nss/lib/certhigh/certhtml.c b/nss/lib/certhigh/certhtml.c
index aad66b0..a522f69 100644
--- a/nss/lib/certhigh/certhtml.c
+++ b/nss/lib/certhigh/certhtml.c
@@ -22,31 +22,33 @@ static char *hex = "0123456789ABCDEF";
/*
** Convert a der-encoded integer to a hex printable string form
*/
-char *CERT_Hexify (SECItem *i, int do_colon)
+char *
+CERT_Hexify(SECItem *i, int do_colon)
{
unsigned char *cp, *end;
char *rv, *o;
if (!i->len) {
- return PORT_Strdup("00");
+ return PORT_Strdup("00");
}
- rv = o = (char*) PORT_Alloc(i->len * 3);
- if (!rv) return rv;
+ 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++ = ':';
- }
- }
+ 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 */
+ *o = 0; /* Null terminate the string */
return rv;
}
@@ -58,132 +60,132 @@ char *CERT_Hexify (SECItem *i, int do_colon)
#define MAX_OUS 20
#define MAX_DC MAX_OUS
-
-char *CERT_FormatName (CERTName *name)
+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;
+ 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];
+ 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;
+ 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 += 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;
- }
- }
+ 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 */
@@ -191,109 +193,108 @@ char *CERT_FormatName (CERTName *name)
/* allocate buffer */
buf = (char *)PORT_Alloc(len);
- if ( !buf ) {
- goto loser;
+ 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 (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;
+ 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;
+ 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 (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;
+ 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;
+ 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 (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 (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 (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;
+ if (!first) {
+ PORT_Memcpy(tmpbuf, BREAK, BREAKLEN);
+ tmpbuf += BREAKLEN;
}
*tmpbuf = 0;
- /* fall through and clean */
+/* fall through and clean */
loser:
- if ( cn ) {
- SECITEM_FreeItem(cn, PR_TRUE);
+ if (cn) {
+ SECITEM_FreeItem(cn, PR_TRUE);
}
- if ( email ) {
- SECITEM_FreeItem(email, PR_TRUE);
+ if (email) {
+ SECITEM_FreeItem(email, PR_TRUE);
}
- for (i=ou_count-1; i >= 0; i--) {
- SECITEM_FreeItem(orgunit[i], PR_TRUE);
+ for (i = ou_count - 1; i >= 0; i--) {
+ SECITEM_FreeItem(orgunit[i], PR_TRUE);
}
- if ( dq ) {
- SECITEM_FreeItem(dq, PR_TRUE);
+ if (dq) {
+ SECITEM_FreeItem(dq, PR_TRUE);
}
- if ( org ) {
- SECITEM_FreeItem(org, PR_TRUE);
+ if (org) {
+ SECITEM_FreeItem(org, PR_TRUE);
}
- for (i=dc_count-1; i >= 0; i--) {
- SECITEM_FreeItem(dc[i], PR_TRUE);
+ for (i = dc_count - 1; i >= 0; i--) {
+ SECITEM_FreeItem(dc[i], PR_TRUE);
}
- if ( loc ) {
- SECITEM_FreeItem(loc, PR_TRUE);
+ if (loc) {
+ SECITEM_FreeItem(loc, PR_TRUE);
}
- if ( state ) {
- SECITEM_FreeItem(state, PR_TRUE);
+ if (state) {
+ SECITEM_FreeItem(state, PR_TRUE);
}
- if ( country ) {
- SECITEM_FreeItem(country, PR_TRUE);
+ if (country) {
+ SECITEM_FreeItem(country, PR_TRUE);
}
- return(buf);
+ return (buf);
}
-
diff --git a/nss/lib/certhigh/certreq.c b/nss/lib/certhigh/certreq.c
index f5098a0..4087bc9 100644
--- a/nss/lib/certhigh/certreq.c
+++ b/nss/lib/certhigh/certreq.c
@@ -14,10 +14,10 @@ SEC_ASN1_MKSUB(SEC_AnyTemplate)
const SEC_ASN1Template CERT_AttributeTemplate[] = {
{ SEC_ASN1_SEQUENCE,
- 0, NULL, sizeof(CERTAttribute) },
+ 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) },
+ SEC_ASN1_SUB(SEC_AnyTemplate) },
{ 0 }
};
@@ -27,18 +27,18 @@ const SEC_ASN1Template CERT_SetOfAttributeTemplate[] = {
const SEC_ASN1Template CERT_CertificateRequestTemplate[] = {
{ SEC_ASN1_SEQUENCE,
- 0, NULL, sizeof(CERTCertificateRequest) },
+ 0, NULL, sizeof(CERTCertificateRequest) },
{ SEC_ASN1_INTEGER,
- offsetof(CERTCertificateRequest,version) },
+ offsetof(CERTCertificateRequest, version) },
{ SEC_ASN1_INLINE,
- offsetof(CERTCertificateRequest,subject),
- CERT_NameTemplate },
+ offsetof(CERTCertificateRequest, subject),
+ CERT_NameTemplate },
{ SEC_ASN1_INLINE,
- offsetof(CERTCertificateRequest,subjectPublicKeyInfo),
- CERT_SubjectPublicKeyInfoTemplate },
+ offsetof(CERTCertificateRequest, subjectPublicKeyInfo),
+ CERT_SubjectPublicKeyInfoTemplate },
{ SEC_ASN1_CONSTRUCTED | SEC_ASN1_CONTEXT_SPECIFIC | 0,
- offsetof(CERTCertificateRequest,attributes),
- CERT_SetOfAttributeTemplate },
+ offsetof(CERTCertificateRequest, attributes),
+ CERT_SetOfAttributeTemplate },
{ 0 }
};
@@ -46,25 +46,25 @@ SEC_ASN1_CHOOSER_IMPLEMENT(CERT_CertificateRequestTemplate)
CERTCertificate *
CERT_CreateCertificate(unsigned long serialNumber,
- CERTName *issuer,
- CERTValidity *validity,
- CERTCertificateRequest *req)
+ CERTName *issuer,
+ CERTValidity *validity,
+ CERTCertificateRequest *req)
{
CERTCertificate *c;
int rv;
PLArenaPool *arena;
-
+
arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
-
- if ( !arena ) {
- return(0);
+
+ if (!arena) {
+ return (0);
}
c = (CERTCertificate *)PORT_ArenaZAlloc(arena, sizeof(CERTCertificate));
-
+
if (!c) {
- PORT_FreeArena(arena, PR_FALSE);
- return 0;
+ PORT_FreeArena(arena, PR_FALSE);
+ return 0;
}
c->referenceCount = 1;
@@ -75,44 +75,50 @@ CERT_CreateCertificate(unsigned long serialNumber,
* If extensions are added, it will get changed as appropriate.
*/
rv = DER_SetUInteger(arena, &c->version, SEC_CERTIFICATE_VERSION_1);
- if (rv) goto loser;
+ if (rv)
+ goto loser;
rv = DER_SetUInteger(arena, &c->serialNumber, serialNumber);
- if (rv) goto loser;
+ if (rv)
+ goto loser;
rv = CERT_CopyName(arena, &c->issuer, issuer);
- if (rv) goto loser;
+ if (rv)
+ goto loser;
rv = CERT_CopyValidity(arena, &c->validity, validity);
- if (rv) goto loser;
+ if (rv)
+ goto loser;
rv = CERT_CopyName(arena, &c->subject, &req->subject);
- if (rv) goto loser;
+ if (rv)
+ goto loser;
rv = SECKEY_CopySubjectPublicKeyInfo(arena, &c->subjectPublicKeyInfo,
- &req->subjectPublicKeyInfo);
- if (rv) goto loser;
+ &req->subjectPublicKeyInfo);
+ if (rv)
+ goto loser;
return c;
- loser:
+loser:
CERT_DestroyCertificate(c);
return 0;
}
/************************************************************************/
-/* It's clear from the comments that the original author of this
+/* 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
+ * 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
+ * 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
+ * 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
+ * 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.
@@ -120,95 +126,95 @@ CERT_CreateCertificate(unsigned long serialNumber,
CERTCertificateRequest *
CERT_CreateCertificateRequest(CERTName *subject,
- CERTSubjectPublicKeyInfo *spki,
- SECItem **attributes)
+ CERTSubjectPublicKeyInfo *spki,
+ SECItem **attributes)
{
CERTCertificateRequest *certreq;
PLArenaPool *arena;
- CERTAttribute * attribute;
- SECOidData * oidData;
+ CERTAttribute *attribute;
+ SECOidData *oidData;
SECStatus rv;
int i = 0;
arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
- if ( arena == NULL ) {
- return NULL;
+ if (arena == NULL) {
+ return NULL;
}
-
+
certreq = PORT_ArenaZNew(arena, CERTCertificateRequest);
if (!certreq) {
- PORT_FreeArena(arena, PR_FALSE);
- return NULL;
+ 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);
+ SEC_CERTIFICATE_REQUEST_VERSION);
if (rv != SECSuccess)
- goto loser;
+ goto loser;
rv = CERT_CopyName(arena, &certreq->subject, subject);
if (rv != SECSuccess)
- goto loser;
+ goto loser;
rv = SECKEY_CopySubjectPublicKeyInfo(arena,
- &certreq->subjectPublicKeyInfo,
- spki);
+ &certreq->subjectPublicKeyInfo,
+ spki);
if (rv != SECSuccess)
- goto loser;
+ goto loser;
- certreq->attributes = PORT_ArenaZNewArray(arena, CERTAttribute*, 2);
- if(!certreq->attributes)
- 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;
- }
+ certreq->attributes[0] = NULL;
+ return certreq;
+ }
/* allocate space for attributes */
attribute = PORT_ArenaZNew(arena, CERTAttribute);
- if (!attribute)
- goto loser;
+ if (!attribute)
+ goto loser;
- oidData = SECOID_FindOIDByTag( SEC_OID_PKCS9_EXTENSION_REQUEST );
+ oidData = SECOID_FindOIDByTag(SEC_OID_PKCS9_EXTENSION_REQUEST);
PORT_Assert(oidData);
if (!oidData)
- goto loser;
+ goto loser;
rv = SECITEM_CopyItem(arena, &attribute->attrType, &oidData->oid);
if (rv != SECSuccess)
- goto loser;
+ goto loser;
- for (i = 0; attributes[i] != NULL ; i++)
- ;
- attribute->attrValue = PORT_ArenaZNewArray(arena, SECItem *, i+1);
- if (!attribute->attrValue)
- 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;
+ attribute->attrValue[i] = SECITEM_ArenaDupItem(arena, attributes[i]);
+ if (!attribute->attrValue[i])
+ goto loser;
}
certreq->attributes[0] = attribute;
@@ -224,7 +230,7 @@ void
CERT_DestroyCertificateRequest(CERTCertificateRequest *req)
{
if (req && req->arena) {
- PORT_FreeArena(req->arena, PR_FALSE);
+ PORT_FreeArena(req->arena, PR_FALSE);
}
return;
}
@@ -241,11 +247,11 @@ setCRExt(void *o, CERTCertExtension **exts)
** attribute list by CERT_FinishCRAttributes().
*/
extern void *cert_StartExtensions(void *owner, PLArenaPool *ownerArena,
- void (*setExts)(void *object, CERTCertExtension **exts));
+ void (*setExts)(void *object, CERTCertExtension **exts));
void *
CERT_StartCertificateRequestAttributes(CERTCertificateRequest *req)
{
- return (cert_StartExtensions ((void *)req, req->arena, setCRExt));
+ return (cert_StartExtensions((void *)req, req->arena, setCRExt));
}
/*
@@ -257,38 +263,39 @@ CERT_StartCertificateRequestAttributes(CERTCertificateRequest *req)
*/
SECStatus
CERT_FinishCertificateRequestAttributes(CERTCertificateRequest *req)
-{ SECItem *extlist;
+{
+ SECItem *extlist;
SECOidData *oidrec;
CERTAttribute *attribute;
-
+
if (!req || !req->arena) {
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
+ 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));
+ SEC_ASN1_GET(CERT_SequenceOfCertExtensionTemplate));
if (extlist == NULL)
- return(SECFailure);
+ return (SECFailure);
oidrec = SECOID_FindOIDByTag(SEC_OID_PKCS9_EXTENSION_REQUEST);
if (oidrec == NULL)
- return SECFailure;
+ return SECFailure;
/* now change the list of cert extensions into a list of attributes
*/
- req->attributes = PORT_ArenaZNewArray(req->arena, CERTAttribute*, 2);
+ 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;
+ return SECFailure;
}
- attribute->attrValue = PORT_ArenaZNewArray(req->arena, SECItem*, 2);
+ attribute->attrValue = PORT_ArenaZNewArray(req->arena, SECItem *, 2);
if (attribute->attrValue == NULL)
return SECFailure;
@@ -303,22 +310,22 @@ CERT_FinishCertificateRequestAttributes(CERTCertificateRequest *req)
SECStatus
CERT_GetCertificateRequestExtensions(CERTCertificateRequest *req,
- CERTCertExtension ***exts)
+ CERTCertExtension ***exts)
{
if (req == NULL || exts == NULL) {
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
+ 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);
+ PORT_SetError(SEC_ERROR_INVALID_ARGS);
return SECFailure;
}
- return(SEC_ASN1DecodeItem(req->arena, exts,
- SEC_ASN1_GET(CERT_SequenceOfCertExtensionTemplate),
- (*req->attributes)->attrValue[0]));
+ return (SEC_ASN1DecodeItem(req->arena, exts,
+ SEC_ASN1_GET(CERT_SequenceOfCertExtensionTemplate),
+ (*req->attributes)->attrValue[0]));
}
diff --git a/nss/lib/certhigh/certvfy.c b/nss/lib/certhigh/certvfy.c
index d5dcbe8..ccd38e6 100644
--- a/nss/lib/certhigh/certvfy.c
+++ b/nss/lib/certhigh/certvfy.c
@@ -12,10 +12,13 @@
#include "certdb.h"
#include "certi.h"
#include "cryptohi.h"
+
+#ifndef NSS_DISABLE_LIBPKIX
#include "pkix.h"
-/*#include "pkix_sample_modules.h" */
#include "pkix_pl_cert.h"
-
+#else
+#include "nss.h"
+#endif /* NSS_DISABLE_LIBPKIX */
#include "nsspki.h"
#include "pkitm.h"
@@ -34,9 +37,10 @@ CERT_CertTimesValid(CERTCertificate *c)
return (valid == secCertTimeValid) ? SECSuccess : SECFailure;
}
-SECStatus checkKeyParams(const SECAlgorithmID *sigAlgorithm, const SECKEYPublicKey *key)
+SECStatus
+checkKeyParams(const SECAlgorithmID *sigAlgorithm, const SECKEYPublicKey *key)
{
- SECStatus rv;
+ SECStatus rv;
SECOidTag sigAlg;
SECOidTag curve;
PRUint32 policyFlags = 0;
@@ -44,81 +48,81 @@ SECStatus checkKeyParams(const SECAlgorithmID *sigAlgorithm, const SECKEYPublicK
sigAlg = SECOID_GetAlgorithmTag(sigAlgorithm);
- switch(sigAlg) {
+ switch (sigAlg) {
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:
- if (key->keyType != ecKey) {
- PORT_SetError(SEC_ERROR_INVALID_ALGORITHM);
- return SECFailure;
- }
+ 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:
+ if (key->keyType != ecKey) {
+ PORT_SetError(SEC_ERROR_INVALID_ALGORITHM);
+ return SECFailure;
+ }
curve = SECKEY_GetECCOid(&key->u.ec.DEREncodedParams);
- if (curve != 0) {
- if (NSS_GetAlgorithmPolicy(curve, &policyFlags) == SECFailure ||
- !(policyFlags & NSS_USE_ALG_IN_CERT_SIGNATURE)) {
- PORT_SetError(SEC_ERROR_CERT_SIGNATURE_ALGORITHM_DISABLED);
- return SECFailure;
- } else {
- return SECSuccess;
+ if (curve != 0) {
+ if (NSS_GetAlgorithmPolicy(curve, &policyFlags) == SECFailure ||
+ !(policyFlags & NSS_USE_ALG_IN_CERT_SIGNATURE)) {
+ PORT_SetError(SEC_ERROR_CERT_SIGNATURE_ALGORITHM_DISABLED);
+ return SECFailure;
+ } else {
+ return SECSuccess;
}
} else {
- PORT_SetError(SEC_ERROR_UNSUPPORTED_ELLIPTIC_CURVE);
- return SECFailure;
- }
+ PORT_SetError(SEC_ERROR_UNSUPPORTED_ELLIPTIC_CURVE);
+ return SECFailure;
+ }
return SECSuccess;
- case SEC_OID_PKCS1_MD5_WITH_RSA_ENCRYPTION:
- case SEC_OID_PKCS1_SHA1_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:
- case SEC_OID_PKCS1_RSA_PSS_SIGNATURE:
- case SEC_OID_ISO_SHA_WITH_RSA_SIGNATURE:
- case SEC_OID_ISO_SHA1_WITH_RSA_SIGNATURE:
- if (key->keyType != rsaKey && key->keyType != rsaPssKey) {
- PORT_SetError(SEC_ERROR_INVALID_ALGORITHM);
- return SECFailure;
- }
+ case SEC_OID_PKCS1_MD5_WITH_RSA_ENCRYPTION:
+ case SEC_OID_PKCS1_SHA1_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:
+ case SEC_OID_PKCS1_RSA_PSS_SIGNATURE:
+ case SEC_OID_ISO_SHA_WITH_RSA_SIGNATURE:
+ case SEC_OID_ISO_SHA1_WITH_RSA_SIGNATURE:
+ if (key->keyType != rsaKey && key->keyType != rsaPssKey) {
+ PORT_SetError(SEC_ERROR_INVALID_ALGORITHM);
+ return SECFailure;
+ }
len = 8 * key->u.rsa.modulus.len;
rv = NSS_OptionGet(NSS_RSA_MIN_KEY_SIZE, &minLen);
if (rv != SECSuccess) {
return SECFailure;
- }
+ }
if (len < minLen) {
return SECFailure;
- }
+ }
return SECSuccess;
- case SEC_OID_ANSIX9_DSA_SIGNATURE:
- case SEC_OID_ANSIX9_DSA_SIGNATURE_WITH_SHA1_DIGEST:
- case SEC_OID_BOGUS_DSA_SIGNATURE_WITH_SHA1_DIGEST:
- case SEC_OID_SDN702_DSA_SIGNATURE:
- case SEC_OID_NIST_DSA_SIGNATURE_WITH_SHA224_DIGEST:
- case SEC_OID_NIST_DSA_SIGNATURE_WITH_SHA256_DIGEST:
- if (key->keyType != dsaKey) {
- PORT_SetError(SEC_ERROR_INVALID_ALGORITHM);
- return SECFailure;
- }
+ case SEC_OID_ANSIX9_DSA_SIGNATURE:
+ case SEC_OID_ANSIX9_DSA_SIGNATURE_WITH_SHA1_DIGEST:
+ case SEC_OID_BOGUS_DSA_SIGNATURE_WITH_SHA1_DIGEST:
+ case SEC_OID_SDN702_DSA_SIGNATURE:
+ case SEC_OID_NIST_DSA_SIGNATURE_WITH_SHA224_DIGEST:
+ case SEC_OID_NIST_DSA_SIGNATURE_WITH_SHA256_DIGEST:
+ if (key->keyType != dsaKey) {
+ PORT_SetError(SEC_ERROR_INVALID_ALGORITHM);
+ return SECFailure;
+ }
len = 8 * key->u.dsa.params.prime.len;
rv = NSS_OptionGet(NSS_DSA_MIN_KEY_SIZE, &minLen);
if (rv != SECSuccess) {
return SECFailure;
- }
+ }
if (len < minLen) {
return SECFailure;
- }
+ }
return SECSuccess;
- default:
- return SECSuccess;
+ default:
+ return SECSuccess;
}
}
@@ -128,38 +132,38 @@ SECStatus checkKeyParams(const SECAlgorithmID *sigAlgorithm, const SECKEYPublicK
SECStatus
CERT_VerifySignedDataWithPublicKey(const CERTSignedData *sd,
SECKEYPublicKey *pubKey,
- void *wincx)
+ void *wincx)
{
- SECStatus rv;
- SECItem sig;
- SECOidTag hashAlg = SEC_OID_UNKNOWN;
+ SECStatus rv;
+ SECItem sig;
+ SECOidTag hashAlg = SEC_OID_UNKNOWN;
- if ( !pubKey || !sd ) {
- PORT_SetError(PR_INVALID_ARGUMENT_ERROR);
- return SECFailure;
+ 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);
+ 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 = checkKeyParams(&sd->signatureAlgorithm, pubKey);
- if (rv != SECSuccess) {
- PORT_SetError(SEC_ERROR_CERT_SIGNATURE_ALGORITHM_DISABLED);
- return SECFailure;
- }
-
- rv = NSS_GetAlgorithmPolicy(hashAlg, &policyFlags);
- if (rv == SECSuccess &&
- !(policyFlags & NSS_USE_ALG_IN_CERT_SIGNATURE)) {
- PORT_SetError(SEC_ERROR_CERT_SIGNATURE_ALGORITHM_DISABLED);
- return SECFailure;
- }
+ PRUint32 policyFlags = 0;
+ rv = checkKeyParams(&sd->signatureAlgorithm, pubKey);
+ if (rv != SECSuccess) {
+ PORT_SetError(SEC_ERROR_CERT_SIGNATURE_ALGORITHM_DISABLED);
+ return SECFailure;
+ }
+
+ rv = NSS_GetAlgorithmPolicy(hashAlg, &policyFlags);
+ if (rv == SECSuccess &&
+ !(policyFlags & NSS_USE_ALG_IN_CERT_SIGNATURE)) {
+ PORT_SetError(SEC_ERROR_CERT_SIGNATURE_ALGORITHM_DISABLED);
+ return SECFailure;
+ }
}
return rv;
}
@@ -168,18 +172,18 @@ CERT_VerifySignedDataWithPublicKey(const CERTSignedData *sd,
* verify the signature of a signed data object with the given DER publickey
*/
SECStatus
-CERT_VerifySignedDataWithPublicKeyInfo(CERTSignedData *sd,
+CERT_VerifySignedDataWithPublicKeyInfo(CERTSignedData *sd,
CERTSubjectPublicKeyInfo *pubKeyInfo,
- void *wincx)
+ void *wincx)
{
SECKEYPublicKey *pubKey;
- SECStatus rv = SECFailure;
+ SECStatus rv = SECFailure;
/* get cert's public key */
pubKey = SECKEY_ExtractPublicKey(pubKeyInfo);
if (pubKey) {
- rv = CERT_VerifySignedDataWithPublicKey(sd, pubKey, wincx);
- SECKEY_DestroyPublicKey(pubKey);
+ rv = CERT_VerifySignedDataWithPublicKey(sd, pubKey, wincx);
+ SECKEY_DestroyPublicKey(pubKey);
}
return rv;
}
@@ -189,31 +193,30 @@ CERT_VerifySignedDataWithPublicKeyInfo(CERTSignedData *sd,
*/
SECStatus
CERT_VerifySignedData(CERTSignedData *sd, CERTCertificate *cert,
- PRTime t, void *wincx)
+ PRTime t, void *wincx)
{
SECKEYPublicKey *pubKey = 0;
- SECStatus rv = SECFailure;
+ SECStatus rv = SECFailure;
SECCertTimeValidity validity;
/* check the certificate's validity */
validity = CERT_CheckCertValidTimes(cert, t, PR_FALSE);
- if ( validity != secCertTimeValid ) {
- return rv;
+ 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);
+ rv = CERT_VerifySignedDataWithPublicKey(sd, pubKey, wincx);
+ SECKEY_DestroyPublicKey(pubKey);
}
return rv;
}
-
SECStatus
-SEC_CheckCRL(CERTCertDBHandle *handle,CERTCertificate *cert,
- CERTCertificate *caCert, PRTime t, void * wincx)
+SEC_CheckCRL(CERTCertDBHandle *handle, CERTCertificate *cert,
+ CERTCertificate *caCert, PRTime t, void *wincx)
{
return CERT_CheckCRL(cert, caCert, NULL, t, wincx);
}
@@ -235,33 +238,33 @@ CERT_FindCertIssuer(CERTCertificate *cert, PRTime validTime, SECCertUsage usage)
me = STAN_GetNSSCertificate(cert);
if (!me) {
PORT_SetError(SEC_ERROR_NO_MEMORY);
- return NULL;
+ 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();
+ memset(chain, 0, 3 * sizeof(NSSCertificate *));
+ td = STAN_GetDefaultTrustDomain();
cc = STAN_GetDefaultCryptoContext();
- (void)NSSCertificate_BuildChain(me, nssTime, &nssUsage, NULL,
+ (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 */
- }
+ 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_Assert(me == chain[0]);
+ NSSCertificate_Destroy(chain[0]); /* the first cert in the chain */
}
- PORT_SetError (SEC_ERROR_UNKNOWN_ISSUER);
+ PORT_SetError(SEC_ERROR_UNKNOWN_ISSUER);
return NULL;
}
@@ -270,136 +273,272 @@ CERT_FindCertIssuer(CERTCertificate *cert, PRTime validTime, SECCertUsage usage)
*/
SECStatus
CERT_TrustFlagsForCACertUsage(SECCertUsage usage,
- unsigned int *retFlags,
- SECTrustType *retTrustType)
+ 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);
+ 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);
+ return (SECFailure);
}
void
cert_AddToVerifyLog(CERTVerifyLog *log, CERTCertificate *cert, long error,
- unsigned int depth, void *arg)
+ 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++;
+ 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; \
+ 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); \
+ }
+
+/* /C=CN/O=WoSign CA Limited/CN=CA \xE6\xB2\x83\xE9\x80\x9A\xE6\xA0\xB9\xE8\xAF\x81\xE4\xB9\xA6
+ * Using a consistent naming convention, this would actually be called
+ * 'CA沃通根证书DN', but since GCC 6.2.1 apparently can't handle UTF-8
+ * identifiers, this will have to do.
+ */
+static const unsigned char CAWoSignRootDN[72] = {
+ 0x30, 0x46, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02,
+ 0x43, 0x4E, 0x31, 0x1A, 0x30, 0x18, 0x06, 0x03, 0x55, 0x04, 0x0A, 0x13, 0x11,
+ 0x57, 0x6F, 0x53, 0x69, 0x67, 0x6E, 0x20, 0x43, 0x41, 0x20, 0x4C, 0x69, 0x6D,
+ 0x69, 0x74, 0x65, 0x64, 0x31, 0x1B, 0x30, 0x19, 0x06, 0x03, 0x55, 0x04, 0x03,
+ 0x0C, 0x12, 0x43, 0x41, 0x20, 0xE6, 0xB2, 0x83, 0xE9, 0x80, 0x9A, 0xE6, 0xA0,
+ 0xB9, 0xE8, 0xAF, 0x81, 0xE4, 0xB9, 0xA6,
+};
+
+/* /C=CN/O=WoSign CA Limited/CN=CA WoSign ECC Root */
+static const unsigned char CAWoSignECCRootDN[72] = {
+ 0x30, 0x46, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02,
+ 0x43, 0x4E, 0x31, 0x1A, 0x30, 0x18, 0x06, 0x03, 0x55, 0x04, 0x0A, 0x13, 0x11,
+ 0x57, 0x6F, 0x53, 0x69, 0x67, 0x6E, 0x20, 0x43, 0x41, 0x20, 0x4C, 0x69, 0x6D,
+ 0x69, 0x74, 0x65, 0x64, 0x31, 0x1B, 0x30, 0x19, 0x06, 0x03, 0x55, 0x04, 0x03,
+ 0x13, 0x12, 0x43, 0x41, 0x20, 0x57, 0x6F, 0x53, 0x69, 0x67, 0x6E, 0x20, 0x45,
+ 0x43, 0x43, 0x20, 0x52, 0x6F, 0x6F, 0x74,
+};
+
+/* /C=CN/O=WoSign CA Limited/CN=Certification Authority of WoSign */
+static const unsigned char CertificationAuthorityofWoSignDN[87] = {
+ 0x30, 0x55, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02,
+ 0x43, 0x4E, 0x31, 0x1A, 0x30, 0x18, 0x06, 0x03, 0x55, 0x04, 0x0A, 0x13, 0x11,
+ 0x57, 0x6F, 0x53, 0x69, 0x67, 0x6E, 0x20, 0x43, 0x41, 0x20, 0x4C, 0x69, 0x6D,
+ 0x69, 0x74, 0x65, 0x64, 0x31, 0x2A, 0x30, 0x28, 0x06, 0x03, 0x55, 0x04, 0x03,
+ 0x13, 0x21, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69,
+ 0x6F, 0x6E, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6F, 0x72, 0x69, 0x74, 0x79, 0x20,
+ 0x6F, 0x66, 0x20, 0x57, 0x6F, 0x53, 0x69, 0x67, 0x6E,
+};
+
+/* /C=CN/O=WoSign CA Limited/CN=Certification Authority of WoSign G2 */
+static const unsigned char CertificationAuthorityofWoSignG2DN[90] = {
+ 0x30, 0x58, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02,
+ 0x43, 0x4E, 0x31, 0x1A, 0x30, 0x18, 0x06, 0x03, 0x55, 0x04, 0x0A, 0x13, 0x11,
+ 0x57, 0x6F, 0x53, 0x69, 0x67, 0x6E, 0x20, 0x43, 0x41, 0x20, 0x4C, 0x69, 0x6D,
+ 0x69, 0x74, 0x65, 0x64, 0x31, 0x2D, 0x30, 0x2B, 0x06, 0x03, 0x55, 0x04, 0x03,
+ 0x13, 0x24, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69,
+ 0x6F, 0x6E, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6F, 0x72, 0x69, 0x74, 0x79, 0x20,
+ 0x6F, 0x66, 0x20, 0x57, 0x6F, 0x53, 0x69, 0x67, 0x6E, 0x20, 0x47, 0x32,
+};
+
+/* /C=IL/O=StartCom Ltd./OU=Secure Digital Certificate Signing/CN=StartCom Certification Authority */
+static const unsigned char StartComCertificationAuthorityDN[127] = {
+ 0x30, 0x7D, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02,
+ 0x49, 0x4C, 0x31, 0x16, 0x30, 0x14, 0x06, 0x03, 0x55, 0x04, 0x0A, 0x13, 0x0D,
+ 0x53, 0x74, 0x61, 0x72, 0x74, 0x43, 0x6F, 0x6D, 0x20, 0x4C, 0x74, 0x64, 0x2E,
+ 0x31, 0x2B, 0x30, 0x29, 0x06, 0x03, 0x55, 0x04, 0x0B, 0x13, 0x22, 0x53, 0x65,
+ 0x63, 0x75, 0x72, 0x65, 0x20, 0x44, 0x69, 0x67, 0x69, 0x74, 0x61, 0x6C, 0x20,
+ 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x20, 0x53,
+ 0x69, 0x67, 0x6E, 0x69, 0x6E, 0x67, 0x31, 0x29, 0x30, 0x27, 0x06, 0x03, 0x55,
+ 0x04, 0x03, 0x13, 0x20, 0x53, 0x74, 0x61, 0x72, 0x74, 0x43, 0x6F, 0x6D, 0x20,
+ 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6F, 0x6E,
+ 0x20, 0x41, 0x75, 0x74, 0x68, 0x6F, 0x72, 0x69, 0x74, 0x79,
+};
+
+/* /C=IL/O=StartCom Ltd./CN=StartCom Certification Authority G2 */
+static const unsigned char StartComCertificationAuthorityG2DN[85] = {
+ 0x30, 0x53, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02,
+ 0x49, 0x4C, 0x31, 0x16, 0x30, 0x14, 0x06, 0x03, 0x55, 0x04, 0x0A, 0x13, 0x0D,
+ 0x53, 0x74, 0x61, 0x72, 0x74, 0x43, 0x6F, 0x6D, 0x20, 0x4C, 0x74, 0x64, 0x2E,
+ 0x31, 0x2C, 0x30, 0x2A, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x23, 0x53, 0x74,
+ 0x61, 0x72, 0x74, 0x43, 0x6F, 0x6D, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66,
+ 0x69, 0x63, 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6F,
+ 0x72, 0x69, 0x74, 0x79, 0x20, 0x47, 0x32,
+};
+
+struct DataAndLength {
+ const unsigned char *data;
+ PRUint32 len;
+};
+
+static const struct DataAndLength StartComAndWoSignDNs[] = {
+ { CAWoSignRootDN,
+ sizeof(CAWoSignRootDN) },
+ { CAWoSignECCRootDN,
+ sizeof(CAWoSignECCRootDN) },
+ { CertificationAuthorityofWoSignDN,
+ sizeof(CertificationAuthorityofWoSignDN) },
+ { CertificationAuthorityofWoSignG2DN,
+ sizeof(CertificationAuthorityofWoSignG2DN) },
+ { StartComCertificationAuthorityDN,
+ sizeof(StartComCertificationAuthorityDN) },
+ { StartComCertificationAuthorityG2DN,
+ sizeof(StartComCertificationAuthorityG2DN) },
+};
+
+static PRBool
+CertIsStartComOrWoSign(const CERTCertificate *cert)
+{
+ int i;
+ const struct DataAndLength *dn = StartComAndWoSignDNs;
+
+ for (i = 0; i < sizeof(StartComAndWoSignDNs) / sizeof(struct DataAndLength); ++i, dn++) {
+ if (cert->derSubject.len == dn->len &&
+ memcmp(cert->derSubject.data, dn->data, dn->len) == 0) {
+ return PR_TRUE;
+ }
}
+ return PR_FALSE;
+}
-#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; \
+SECStatus
+isIssuerCertAllowedAtCertIssuanceTime(CERTCertificate *issuerCert,
+ CERTCertificate *referenceCert)
+{
+ if (!issuerCert || !referenceCert) {
+ PORT_SetError(SEC_ERROR_INVALID_ARGS);
+ return SECFailure;
}
-#define LOG_ERROR(log,cert,depth,arg) \
- if ( log != NULL ) { \
- cert_AddToVerifyLog(log, cert, PORT_GetError(), depth, \
- (void *)(PRWord)arg); \
+ if (CertIsStartComOrWoSign(issuerCert)) {
+ /* PRTime is microseconds since the epoch, whereas JS time is milliseconds.
+ * (new Date("2016-10-21T00:00:00Z")).getTime() * 1000
+ */
+ static const PRTime OCTOBER_21_2016 = 1477008000000000;
+
+ PRTime notBefore, notAfter;
+ SECStatus rv;
+
+ rv = CERT_GetCertTimes(referenceCert, &notBefore, &notAfter);
+ if (rv != SECSuccess)
+ return rv;
+
+ if (notBefore > OCTOBER_21_2016) {
+ return SECFailure;
+ }
}
+ return SECSuccess;
+}
+
static SECStatus
cert_VerifyCertChainOld(CERTCertDBHandle *handle, CERTCertificate *cert,
- PRBool checkSig, PRBool* sigerror,
- SECCertUsage certUsage, PRTime t, void *wincx,
- CERTVerifyLog *log, PRBool* revoked)
+ PRBool checkSig, PRBool *sigerror,
+ SECCertUsage certUsage, PRTime t, void *wincx,
+ CERTVerifyLog *log, PRBool *revoked)
{
SECTrustType trustType;
CERTBasicConstraints basicConstraint;
@@ -417,7 +556,7 @@ cert_VerifyCertChainOld(CERTCertDBHandle *handle, CERTCertificate *cert,
unsigned int requiredFlags;
PLArenaPool *arena = NULL;
CERTGeneralName *namesList = NULL;
- CERTCertificate **certsList = NULL;
+ CERTCertificate **certsList = NULL;
int certsListLen = 16;
int namesCount = 0;
PRBool subjectCertIsSelfIssued;
@@ -428,177 +567,178 @@ cert_VerifyCertChainOld(CERTCertDBHandle *handle, CERTCertificate *cert,
}
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;
- }
-
+ &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;
+ if (subjectCert == NULL) {
+ goto loser;
}
arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
if (arena == NULL) {
- goto loser;
+ goto loser;
}
certsList = PORT_ZNewArray(CERTCertificate *, certsListLen);
if (certsList == NULL)
- goto loser;
+ 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);
- }
+ 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 (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);
- }
+ 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);
+ }
/* make sure that the entire chain is within the name space of the
* current issuer certificate.
@@ -611,16 +751,23 @@ cert_VerifyCertChainOld(CERTCertDBHandle *handle, CERTCertificate *cert,
goto loser;
}
- /* XXX - the error logging may need to go down into CRL stuff at some
- * point
- */
- /* check revoked list (issuer) */
+ rv = isIssuerCertAllowedAtCertIssuanceTime(issuerCert, cert);
+ if (rv != SECSuccess) {
+ PORT_SetError(SEC_ERROR_UNTRUSTED_ISSUER);
+ LOG_ERROR(log, issuerCert, count + 1, 0);
+ goto loser;
+ }
+
+ /* 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);
+ 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
@@ -630,163 +777,164 @@ cert_VerifyCertChainOld(CERTCertDBHandle *handle, CERTCertificate *cert,
if (revoked) {
*revoked = PR_TRUE;
}
- LOG_ERROR(log,subjectCert,count,0);
+ 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 {
+ 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;
+ 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 */
+ /* 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);
- }
+ /* 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 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;
+ 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 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);
+ LOG_ERROR(log, subjectCert, count, 0);
loser:
rv = SECFailure;
done:
if (certsList != NULL) {
- PORT_Free(certsList);
+ PORT_Free(certsList);
}
- if ( issuerCert ) {
- CERT_DestroyCertificate(issuerCert);
+ if (issuerCert) {
+ CERT_DestroyCertificate(issuerCert);
}
-
- if ( subjectCert ) {
- CERT_DestroyCertificate(subjectCert);
+
+ if (subjectCert) {
+ CERT_DestroyCertificate(subjectCert);
}
- if ( arena != NULL ) {
- PORT_FreeArena(arena, PR_FALSE);
+ if (arena != NULL) {
+ PORT_FreeArena(arena, PR_FALSE);
}
return rv;
}
SECStatus
cert_VerifyCertChain(CERTCertDBHandle *handle, CERTCertificate *cert,
- PRBool checkSig, PRBool* sigerror,
+ PRBool checkSig, PRBool *sigerror,
SECCertUsage certUsage, PRTime t, void *wincx,
- CERTVerifyLog *log, PRBool* revoked)
+ CERTVerifyLog *log, PRBool *revoked)
{
if (CERT_GetUsePKIXForValidation()) {
return cert_VerifyCertChainPkix(cert, checkSig, certUsage, t,
@@ -798,11 +946,11 @@ cert_VerifyCertChain(CERTCertDBHandle *handle, CERTCertificate *cert,
SECStatus
CERT_VerifyCertChain(CERTCertDBHandle *handle, CERTCertificate *cert,
- PRBool checkSig, SECCertUsage certUsage, PRTime t,
- void *wincx, CERTVerifyLog *log)
+ PRBool checkSig, SECCertUsage certUsage, PRTime t,
+ void *wincx, CERTVerifyLog *log)
{
return cert_VerifyCertChain(handle, cert, checkSig, NULL, certUsage, t,
- wincx, log, NULL);
+ wincx, log, NULL);
}
/*
@@ -810,8 +958,8 @@ CERT_VerifyCertChain(CERTCertDBHandle *handle, CERTCertificate *cert,
*/
SECStatus
CERT_VerifyCACertForUsage(CERTCertDBHandle *handle, CERTCertificate *cert,
- PRBool checkSig, SECCertUsage certUsage, PRTime t,
- void *wincx, CERTVerifyLog *log)
+ PRBool checkSig, SECCertUsage certUsage, PRTime t,
+ void *wincx, CERTVerifyLog *log)
{
SECTrustType trustType;
CERTBasicConstraints basicConstraint;
@@ -826,44 +974,43 @@ CERT_VerifyCACertForUsage(CERTCertDBHandle *handle, CERTCertificate *cert,
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;
- }
-
+ &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
@@ -874,133 +1021,136 @@ CERT_VerifyCACertForUsage(CERTCertDBHandle *handle, CERTCertificate *cert,
*/
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 (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 */
+ /* Check the special case of certUsageStatusResponder */
issuerCert = CERT_FindCertIssuer(cert, t, certUsage);
if (issuerCert) {
- if (SEC_CheckCRL(handle, cert, issuerCert, t, wincx)
- != SECSuccess) {
+ 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;
+ /* 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);
- }
+ /*
+ * 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 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;
+ PORT_SetError(SEC_ERROR_UNTRUSTED_ISSUER);
+ LOG_ERROR(log, cert, 0, 0);
+ goto loser;
}
- return CERT_VerifyCertChain(handle, cert, checkSig, certUsage, t,
- wincx, log);
+ return CERT_VerifyCertChain(handle, cert, checkSig, certUsage, t,
+ wincx, log);
loser:
rv = SECFailure;
done:
return rv;
}
-#define NEXT_USAGE() { \
- i*=2; \
- certUsage++; \
- continue; \
-}
+#define NEXT_USAGE() \
+ { \
+ i *= 2; \
+ certUsage++; \
+ continue; \
+ }
-#define VALID_USAGE() { \
- NEXT_USAGE(); \
-}
+#define VALID_USAGE() \
+ { \
+ NEXT_USAGE(); \
+ }
-#define INVALID_USAGE() { \
- if (returnedUsages) { \
- *returnedUsages &= (~i); \
- } \
- if (PR_TRUE == requiredUsage) { \
- valid = SECFailure; \
- } \
- 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.
+ * 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
@@ -1008,141 +1158,140 @@ done:
*/
SECStatus
cert_CheckLeafTrust(CERTCertificate *cert, SECCertUsage certUsage,
- unsigned int *failedFlags, PRBool *trusted)
+ 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;
- }
+ 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;
}
@@ -1161,8 +1310,8 @@ cert_CheckLeafTrust(CERTCertificate *cert, SECCertUsage certUsage,
*/
SECStatus
CERT_VerifyCertificate(CERTCertDBHandle *handle, CERTCertificate *cert,
- PRBool checkSig, SECCertificateUsage requiredUsages, PRTime t,
- void *wincx, CERTVerifyLog *log, SECCertificateUsage* returnedUsages)
+ PRBool checkSig, SECCertificateUsage requiredUsages, PRTime t,
+ void *wincx, CERTVerifyLog *log, SECCertificateUsage *returnedUsages)
{
SECStatus rv;
SECStatus valid;
@@ -1170,7 +1319,7 @@ CERT_VerifyCertificate(CERTCertDBHandle *handle, CERTCertificate *cert,
unsigned int requiredCertType;
unsigned int flags;
unsigned int certType;
- PRBool allowOverride;
+ PRBool allowOverride;
SECCertTimeValidity validity;
CERTStatusConfig *statusConfig;
PRInt32 i;
@@ -1194,23 +1343,23 @@ CERT_VerifyCertificate(CERTCertDBHandle *handle, CERTCertificate *cert,
so we can skip checks for usages that aren't required */
checkAllUsages = PR_FALSE;
}
- valid = SECSuccess ; /* start off assuming cert is valid */
-
+ 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 ) {
+ if (validity != secCertTimeValid) {
valid = SECFailure;
- LOG_ERROR_OR_EXIT(log,cert,0,validity);
+ 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) ; ) {
+ 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();
@@ -1218,74 +1367,74 @@ CERT_VerifyCertificate(CERTCertDBHandle *handle, CERTCertificate *cert,
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 ) {
+ 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);
- /* 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 (CERT_CheckKeyUsage(cert, requiredKeyUsage) != SECSuccess) {
if (PR_TRUE == requiredUsage) {
PORT_SetError(SEC_ERROR_INADEQUATE_KEY_USAGE);
}
- LOG_ERROR(log,cert,0,requiredKeyUsage);
+ LOG_ERROR(log, cert, 0, requiredKeyUsage);
INVALID_USAGE();
}
- if ( !( certType & requiredCertType ) ) {
+ if (!(certType & requiredCertType)) {
if (PR_TRUE == requiredUsage) {
PORT_SetError(SEC_ERROR_INADEQUATE_CERT_TYPE);
}
- LOG_ERROR(log,cert,0,requiredCertType);
+ 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_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);
+ checkSig, &sigerror,
+ certUsage, t, wincx, log,
+ &revoked);
if (rv != SECSuccess) {
/* EXIT_IF_NOT_LOGGING(log); XXX ???? */
@@ -1306,10 +1455,10 @@ CERT_VerifyCertificate(CERTCertDBHandle *handle, CERTCertificate *cert,
if (requiredUsages != certificateUsageStatusResponder &&
statusConfig != NULL) {
if (statusConfig->statusChecker != NULL) {
- rv = (* statusConfig->statusChecker)(handle, cert,
- t, wincx);
+ rv = (*statusConfig->statusChecker)(handle, cert,
+ t, wincx);
if (rv != SECSuccess) {
- LOG_ERROR(log,cert,0,0);
+ LOG_ERROR(log, cert, 0, 0);
revoked = PR_TRUE;
INVALID_USAGE();
}
@@ -1319,15 +1468,15 @@ CERT_VerifyCertificate(CERTCertDBHandle *handle, CERTCertificate *cert,
NEXT_USAGE();
}
-
+
loser:
- return(valid);
+ return (valid);
}
SECStatus
CERT_VerifyCert(CERTCertDBHandle *handle, CERTCertificate *cert,
- PRBool checkSig, SECCertUsage certUsage, PRTime t,
- void *wincx, CERTVerifyLog *log)
+ PRBool checkSig, SECCertUsage certUsage, PRTime t,
+ void *wincx, CERTVerifyLog *log)
{
return cert_VerifyCertWithFlags(handle, cert, checkSig, certUsage, t,
CERT_VERIFYCERT_USE_DEFAULTS, wincx, log);
@@ -1343,86 +1492,85 @@ cert_VerifyCertWithFlags(CERTCertDBHandle *handle, CERTCertificate *cert,
unsigned int requiredCertType;
unsigned int failedFlags;
unsigned int certType;
- PRBool trusted;
- PRBool allowOverride;
+ PRBool trusted;
+ PRBool allowOverride;
SECCertTimeValidity validity;
CERTStatusConfig *statusConfig;
-
-#ifdef notdef
+
+#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);
+ 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);
+ 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);
+ 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, &failedFlags, &trusted);
- if (rv == SECFailure) {
- PORT_SetError(SEC_ERROR_UNTRUSTED_CERT);
- LOG_ERROR_OR_EXIT(log, cert, 0, failedFlags);
+ if (rv == SECFailure) {
+ PORT_SetError(SEC_ERROR_UNTRUSTED_CERT);
+ LOG_ERROR_OR_EXIT(log, cert, 0, failedFlags);
} else if (trusted) {
- goto done;
+ goto done;
}
-
rv = CERT_VerifyCertChain(handle, cert, checkSig, certUsage,
- t, wincx, log);
+ t, wincx, log);
if (rv != SECSuccess) {
- EXIT_IF_NOT_LOGGING(log);
+ EXIT_IF_NOT_LOGGING(log);
}
/*
@@ -1434,27 +1582,27 @@ cert_VerifyCertWithFlags(CERTCertDBHandle *handle, CERTCertificate *cert,
* code.
*/
if (!(flags & CERT_VERIFYCERT_SKIP_OCSP) &&
- certUsage != certUsageStatusResponder) {
- statusConfig = CERT_GetStatusConfig(handle);
- if (statusConfig && statusConfig->statusChecker) {
- rv = (* statusConfig->statusChecker)(handle, cert,
- t, wincx);
- if (rv != SECSuccess) {
- LOG_ERROR_OR_EXIT(log,cert,0,0);
- }
- }
+ certUsage != certUsageStatusResponder) {
+ statusConfig = CERT_GetStatusConfig(handle);
+ if (statusConfig && statusConfig->statusChecker) {
+ rv = (*statusConfig->statusChecker)(handle, cert,
+ t, wincx);
+ if (rv != SECSuccess) {
+ LOG_ERROR_OR_EXIT(log, cert, 0, 0);
+ }
+ }
}
done:
if (log && log->head) {
- return SECFailure;
+ return SECFailure;
}
- return(SECSuccess);
+ return (SECSuccess);
loser:
rv = SECFailure;
-
- return(rv);
+
+ return (rv);
}
/*
@@ -1463,38 +1611,37 @@ loser:
*/
SECStatus
CERT_VerifyCertificateNow(CERTCertDBHandle *handle, CERTCertificate *cert,
- PRBool checkSig, SECCertificateUsage requiredUsages,
- void *wincx, SECCertificateUsage* returnedUsages)
+ PRBool checkSig, SECCertificateUsage requiredUsages,
+ void *wincx, SECCertificateUsage *returnedUsages)
{
- return(CERT_VerifyCertificate(handle, cert, checkSig,
- requiredUsages, PR_Now(), wincx, NULL, 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)
+ PRBool checkSig, SECCertUsage certUsage, void *wincx)
{
- return(CERT_VerifyCert(handle, cert, checkSig,
- certUsage, PR_Now(), wincx, NULL));
+ 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
+ * certUsageSSLClient
+ * certUsageSSLServer
+ * certUsageSSLServerWithStepUp
+ * certUsageEmailSigner
+ * certUsageEmailRecipient
+ * certUsageObjectSigner
*/
CERTCertificate *
CERT_FindMatchingCert(CERTCertDBHandle *handle, SECItem *derName,
- CERTCertOwner owner, SECCertUsage usage,
- PRBool preferTrusted, PRTime validTime, PRBool validOnly)
+ CERTCertOwner owner, SECCertUsage usage,
+ PRBool preferTrusted, PRTime validTime, PRBool validOnly)
{
CERTCertList *certList = NULL;
CERTCertificate *cert = NULL;
@@ -1502,108 +1649,107 @@ CERT_FindMatchingCert(CERTCertDBHandle *handle, SECItem *derName,
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;
- }
+ 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);
+ 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);
+ if (certList != NULL) {
+ CERT_DestroyCertList(certList);
}
- return(NULL);
+ 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
+ * "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)
+ char **caNames, SECCertUsage usage)
{
CERTCertificate *issuerCert = NULL;
CERTCertificate *subjectCert;
@@ -1613,65 +1759,64 @@ CERT_FilterCertListByCANames(CERTCertList *certList, int nCANames,
char **names;
PRBool found;
PRTime time;
-
- if ( nCANames <= 0 ) {
- return(SECSuccess);
+
+ 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++;
+
+ 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);
+ }
+
+ 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);
}
/*
@@ -1680,70 +1825,70 @@ CERT_FilterCertListByCANames(CERTCertList *certList, int nCANames,
* certificate.
*
* "arena" - arena to allocate returned string from. If NULL, then heap
- * is used.
+ * is used.
* "cert" - the cert to get nickname from
* "expiredString" - the string to append to the nickname if the cert is
- * expired.
+ * expired.
* "notYetGoodString" - the string to append to the nickname if the cert is
- * not yet good.
+ * not yet good.
*/
char *
CERT_GetCertNicknameWithValidity(PLArenaPool *arena, CERTCertificate *cert,
- char *expiredString, char *notYetGoodString)
+ 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;
- }
+ 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);
+
+ /* 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)");
+ 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);
+ 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);
+ return (NULL);
}
/*
@@ -1753,27 +1898,27 @@ loser:
* "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
+ * that is not yet valid
*/
CERTCertNicknames *
CERT_NicknameStringsFromCertList(CERTCertList *certList, char *expiredString,
- char *notYetGoodString)
+ char *notYetGoodString)
{
CERTCertNicknames *names;
PLArenaPool *arena;
CERTCertListNode *node;
char **nn;
-
+
/* allocate an arena */
arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
- if ( arena == NULL ) {
- return(NULL);
+ if (arena == NULL) {
+ return (NULL);
}
-
+
/* allocate the structure */
names = PORT_ArenaAlloc(arena, sizeof(CERTCertNicknames));
- if ( names == NULL ) {
- goto loser;
+ if (names == NULL) {
+ goto loser;
}
/* init the structure */
@@ -1785,49 +1930,49 @@ CERT_NicknameStringsFromCertList(CERTCertList *certList, char *expiredString,
/* count the certs in the list */
node = CERT_LIST_HEAD(certList);
- while ( ! CERT_LIST_END(node, certList) ) {
- names->numnicknames++;
- node = CERT_LIST_NEXT(node);
+ 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;
+ 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 (expiredString == NULL) {
+ expiredString = "";
}
- if ( notYetGoodString == NULL ) {
- notYetGoodString = "";
+ 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;
- }
+ 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);
+ names->totallen += PORT_Strlen(*nn);
+
+ nn++;
+ node = CERT_LIST_NEXT(node);
}
- return(names);
+ return (names);
loser:
PORT_FreeArena(arena, PR_FALSE);
- return(NULL);
+ return (NULL);
}
/*
@@ -1835,63 +1980,63 @@ loser:
* 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
+ * "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)
+ 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 (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);
+ return (retstr);
loser:
- return(NULL);
+ return (NULL);
}
CERTCertList *
@@ -1903,7 +2048,7 @@ CERT_GetCertChainFromCert(CERTCertificate *cert, PRTime time, SECCertUsage usage
if (NULL == cert) {
return NULL;
}
-
+
cert = CERT_DupCertificate(cert);
if (NULL == cert) {
PORT_SetError(SEC_ERROR_NO_MEMORY);
@@ -1917,18 +2062,18 @@ CERT_GetCertChainFromCert(CERTCertificate *cert, PRTime time, SECCertUsage usage
}
while (cert != NULL && ++count <= CERT_MAX_CERT_CHAIN) {
- if (SECSuccess != CERT_AddCertToListTail(chain, cert)) {
+ if (SECSuccess != CERT_AddCertToListTail(chain, cert)) {
/* return partial chain */
PORT_SetError(SEC_ERROR_NO_MEMORY);
return chain;
}
- if (cert->isRoot) {
+ if (cert->isRoot) {
/* return complete chain */
- return chain;
- }
+ return chain;
+ }
- cert = CERT_FindCertIssuer(cert, time, usage);
+ cert = CERT_FindCertIssuer(cert, time, usage);
}
/* return partial chain */
diff --git a/nss/lib/certhigh/certvfypkix.c b/nss/lib/certhigh/certvfypkix.c
index b89fe21..a536c21 100644
--- a/nss/lib/certhigh/certvfypkix.c
+++ b/nss/lib/certhigh/certvfypkix.c
@@ -12,7 +12,7 @@
*/
#include "prerror.h"
#include "prprf.h"
-
+
#include "nspr.h"
#include "pk11func.h"
#include "certdb.h"
@@ -23,6 +23,7 @@
#include "secder.h"
#include "pkit.h"
+#ifndef NSS_DISABLE_LIBPKIX
#include "pkix_pl_common.h"
extern PRLogModuleInfo *pkixLog;
@@ -38,8 +39,8 @@ pkix_pl_lifecycle_ObjectTableUpdate(int *objCountTable);
PRInt32 parallelFnInvocationCount;
#endif /* PKIX_OBJECT_LEAK_TEST */
-
static PRBool usePKIXValidationEngine = PR_FALSE;
+#endif /* NSS_DISABLE_LIBPKIX */
/*
* FUNCTION: CERT_SetUsePKIXForValidation
@@ -59,8 +60,13 @@ static PRBool usePKIXValidationEngine = PR_FALSE;
SECStatus
CERT_SetUsePKIXForValidation(PRBool enable)
{
+#ifdef NSS_DISABLE_LIBPKIX
+ PORT_SetError(PR_NOT_IMPLEMENTED_ERROR);
+ return SECFailure;
+#else
usePKIXValidationEngine = (enable > 0) ? PR_TRUE : PR_FALSE;
return SECSuccess;
+#endif /* NSS_DISABLE_LIBPKIX */
}
/*
@@ -80,9 +86,14 @@ CERT_SetUsePKIXForValidation(PRBool enable)
PRBool
CERT_GetUsePKIXForValidation()
{
+#ifdef NSS_DISABLE_LIBPKIX
+ return PR_FALSE;
+#else
return usePKIXValidationEngine;
+#endif /* NSS_DISABLE_LIBPKIX */
}
+#ifndef NSS_DISABLE_LIBPKIX
#ifdef NOTDEF
/*
* FUNCTION: cert_NssKeyUsagesToPkix
@@ -104,7 +115,7 @@ CERT_GetUsePKIXForValidation()
* Returns NULL if the function succeeds.
* Returns a Fatal Error if the function fails in an unrecoverable way.
*/
-static PKIX_Error*
+static PKIX_Error *
cert_NssKeyUsagesToPkix(
PRUint32 nssKeyUsage,
PKIX_UInt32 *pPkixKeyUsage,
@@ -120,7 +131,7 @@ cert_NssKeyUsagesToPkix(
if (nssKeyUsage & KU_DIGITAL_SIGNATURE) {
pkixKeyUsage |= PKIX_DIGITAL_SIGNATURE;
}
-
+
if (nssKeyUsage & KU_NON_REPUDIATION) {
pkixKeyUsage |= PKIX_NON_REPUDIATION;
}
@@ -128,19 +139,19 @@ cert_NssKeyUsagesToPkix(
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;
}
@@ -148,7 +159,7 @@ cert_NssKeyUsagesToPkix(
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; */
@@ -176,17 +187,17 @@ typedef struct {
} 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},
+ { certUsageSSLClient, ekuIndexSSLClient },
+ { certUsageSSLServer, ekuIndexSSLServer },
+ { certUsageSSLCA, ekuIndexSSLServer },
+ { certUsageEmailSigner, ekuIndexEmail },
+ { certUsageEmailRecipient, ekuIndexEmail },
+ { certUsageObjectSigner, ekuIndexCodeSigner },
+ { certUsageUserCertImport, ekuIndexUnknown },
+ { certUsageVerifyCA, ekuIndexUnknown },
+ { certUsageProtectedObjectSigner, ekuIndexUnknown },
+ { certUsageStatusResponder, ekuIndexStatusResponder },
+ { certUsageAnyCA, ekuIndexUnknown },
};
/*
@@ -200,15 +211,15 @@ const SECCertUsageToEku certUsageEkuStringMap[] = {
* "cert"
* Pointer to CERTCertificate structure of validating cert.
* "requiredCertUsages"
- * Required usage that will be converted to pkix eku and ku.
+ * 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.
+ * 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.
+ * Returned address of pkix required key usages bit field.
* "plContext"
* Platform-specific context pointer.
* THREAD SAFETY:
@@ -218,29 +229,29 @@ const SECCertUsageToEku certUsageEkuStringMap[] = {
* 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*
+static PKIX_Error *
cert_NssCertificateUsageToPkixKUAndEKU(
CERTCertificate *cert,
- SECCertUsage requiredCertUsage,
- PRUint32 requiredKeyUsages,
- PRBool isCA,
- PKIX_List **ppkixEKUList,
- PKIX_UInt32 *ppkixKU,
- void *plContext)
+ 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_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++) {
+ for (; i < PR_ARRAY_SIZE(certUsageEkuStringMap); i++) {
const SECCertUsageToEku *usageToEkuElem =
&certUsageEkuStringMap[i];
if (usageToEkuElem->certUsage == requiredCertUsage) {
@@ -249,25 +260,25 @@ cert_NssCertificateUsageToPkixKUAndEKU(
}
}
if (ekuIndex != ekuIndexUnknown) {
- PRUint32 reqKeyUsage = 0;
- PRUint32 reqCertType = 0;
+ 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);
}
@@ -279,7 +290,7 @@ cert_NssCertificateUsageToPkixKUAndEKU(
ekuOidsList = NULL;
cleanup:
-
+
PKIX_DECREF(ekuOid);
PKIX_DECREF(ekuOidsList);
@@ -313,37 +324,36 @@ cleanup:
* 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*
+static PKIX_Error *
cert_ProcessingParamsSetKeyAndCertUsage(
PKIX_ProcessingParams *procParams,
- SECCertUsage requiredCertUsage,
- PRUint32 requiredKeyUsages,
- void *plContext)
+ SECCertUsage requiredCertUsage,
+ PRUint32 requiredKeyUsages,
+ void *plContext)
{
- PKIX_CertSelector *certSelector = NULL;
+ PKIX_CertSelector *certSelector = NULL;
PKIX_ComCertSelParams *certSelParams = NULL;
- PKIX_PL_NssContext *nssContext = (PKIX_PL_NssContext*)plContext;
-
+ 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);
+ ((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),
@@ -357,7 +367,7 @@ cleanup:
}
/*
- * Unused parameters:
+ * Unused parameters:
*
* CERTCertList *initialChain,
* CERTCertStores certStores,
@@ -398,44 +408,44 @@ cleanup:
* 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*
+static PKIX_Error *
cert_CreatePkixProcessingParams(
- CERTCertificate *cert,
- PRBool checkSig, /* not used yet. See bug 391476 */
- PRTime time,
- void *wincx,
- PRBool useArena,
- PRBool disableOCSPRemoteFetching,
+ CERTCertificate *cert,
+ PRBool checkSig, /* not used yet. See bug 391476 */
+ PRTime time,
+ void *wincx,
+ PRBool useArena,
+ PRBool disableOCSPRemoteFetching,
PKIX_ProcessingParams **pprocParams,
- void **pplContext)
+ void **pplContext)
{
- PKIX_List *anchors = NULL;
- PKIX_PL_Cert *targetCert = NULL;
- PKIX_PL_Date *date = NULL;
+ PKIX_List *anchors = NULL;
+ PKIX_PL_Cert *targetCert = NULL;
+ PKIX_PL_Date *date = NULL;
PKIX_ProcessingParams *procParams = NULL;
- PKIX_CertSelector *certSelector = NULL;
+ PKIX_CertSelector *certSelector = NULL;
PKIX_ComCertSelParams *certSelParams = NULL;
- PKIX_CertStore *certStore = NULL;
- PKIX_List *certStores = NULL;
+ PKIX_CertStore *certStore = NULL;
+ PKIX_List *certStores = NULL;
PKIX_RevocationChecker *revChecker = NULL;
- PKIX_UInt32 methodFlags = 0;
- void *plContext = NULL;
- CERTStatusConfig *statusConfig = 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
+#ifdef PKIX_NOTDEF
/* Functions should be implemented in patch for 390532 */
PKIX_CHECK(
pkix_pl_NssContext_SetCertSignatureCheck(checkSig,
- (PKIX_PL_NssContext*)plContext),
+ (PKIX_PL_NssContext *)plContext),
PKIX_NSSCONTEXTSETCERTSIGNCHECKFAILED);
#endif /* PKIX_NOTDEF */
@@ -443,11 +453,11 @@ cert_CreatePkixProcessingParams(
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);
@@ -456,16 +466,16 @@ cert_CreatePkixProcessingParams(
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),
@@ -482,11 +492,11 @@ cert_CreatePkixProcessingParams(
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),
@@ -507,11 +517,11 @@ cert_CreatePkixProcessingParams(
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_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(
@@ -520,27 +530,27 @@ cert_CreatePkixProcessingParams(
PKIX_PROCESSINGPARAMSSETREVOCATIONCHECKERFAILED);
/* CRL method flags */
- methodFlags =
+ 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_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_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_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.*/
@@ -551,30 +561,30 @@ cert_CreatePkixProcessingParams(
/* 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_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) {
+
+ 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_RevocationMethod_OCSP, methodFlags,
+ 1, NULL, PKIX_TRUE, plContext),
PKIX_REVOCATIONCHECKERADDMETHODFAILED);
}
@@ -585,14 +595,14 @@ cert_CreatePkixProcessingParams(
PKIX_CHECK(
PKIX_ProcessingParams_SetExplicitPolicyRequired(procParams, PR_FALSE,
- plContext),
+ plContext),
PKIX_PROCESSINGPARAMSSETEXPLICITPOLICYREQUIRED);
PKIX_CHECK(
PKIX_ProcessingParams_SetPolicyMappingInhibited(procParams, PR_FALSE,
plContext),
PKIX_PROCESSINGPARAMSSETPOLICYMAPPINGINHIBITED);
-
+
*pprocParams = procParams;
procParams = NULL;
@@ -615,10 +625,10 @@ cleanup:
* DESCRIPTION:
*
* Converts pkix cert list into nss cert list.
- *
+ *
* PARAMETERS:
* "pkixCertChain"
- * Pkix certificate list.
+ * Pkix certificate list.
* "pvalidChain"
* An address of returned nss certificate list.
* "plContext"
@@ -630,18 +640,18 @@ cleanup:
* 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*
+static PKIX_Error *
cert_PkixToNssCertsChain(
- PKIX_List *pkixCertChain,
- CERTCertList **pvalidChain,
+ PKIX_List *pkixCertChain,
+ CERTCertList **pvalidChain,
void *plContext)
{
- PLArenaPool *arena = NULL;
+ PLArenaPool *arena = NULL;
CERTCertificate *nssCert = NULL;
- CERTCertList *validChain = NULL;
- PKIX_PL_Object *certItem = NULL;
- PKIX_UInt32 length = 0;
- PKIX_UInt32 i = 0;
+ 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);
@@ -653,7 +663,7 @@ cert_PkixToNssCertsChain(
if (arena == NULL) {
PKIX_ERROR(PKIX_OUTOFMEMORY);
}
- validChain = (CERTCertList*)PORT_ArenaZAlloc(arena, sizeof(CERTCertList));
+ validChain = (CERTCertList *)PORT_ArenaZAlloc(arena, sizeof(CERTCertList));
if (validChain == NULL) {
PKIX_ERROR(PKIX_PORTARENAALLOCFAILED);
}
@@ -665,22 +675,22 @@ cert_PkixToNssCertsChain(
PKIX_List_GetLength(pkixCertChain, &length, plContext),
PKIX_LISTGETLENGTHFAILED);
- for (i = 0; i < length; i++){
+ 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_PL_Cert_GetCERTCertificate((PKIX_PL_Cert *)certItem, &nssCert,
+ plContext),
PKIX_CERTGETCERTCERTIFICATEFAILED);
-
+
node =
(CERTCertListNode *)PORT_ArenaZAlloc(validChain->arena,
sizeof(CERTCertListNode));
- if ( node == NULL ) {
+ if (node == NULL) {
PKIX_ERROR(PKIX_PORTARENAALLOCFAILED);
}
@@ -695,7 +705,7 @@ cert_PkixToNssCertsChain(
*pvalidChain = validChain;
cleanup:
- if (PKIX_ERROR_RECEIVED){
+ if (PKIX_ERROR_RECEIVED) {
if (validChain) {
CERT_DestroyCertList(validChain);
} else if (arena) {
@@ -710,7 +720,6 @@ cleanup:
PKIX_RETURN(CERTVFYPKIX);
}
-
/*
* FUNCTION: cert_BuildAndValidateChain
* DESCRIPTION:
@@ -738,7 +747,7 @@ cleanup:
* 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*
+static PKIX_Error *
cert_BuildAndValidateChain(
PKIX_ProcessingParams *procParams,
PKIX_BuildResult **pResult,
@@ -746,19 +755,19 @@ cert_BuildAndValidateChain(
void *plContext)
{
PKIX_BuildResult *result = NULL;
- PKIX_VerifyNode *verifyNode = NULL;
- void *nbioContext = NULL;
- void *state = 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;
+ PRPollDesc *pollDesc = (PRPollDesc *)nbioContext;
filesReady = PR_Poll(pollDesc, 1, PR_INTERVAL_NO_TIMEOUT);
if (filesReady <= 0) {
PKIX_ERROR(PKIX_PRPOLLRETBADFILENUM);
@@ -769,7 +778,7 @@ cert_BuildAndValidateChain(
PKIX_BuildChain(procParams, &nbioContext, &state,
&result, &verifyNode, plContext),
PKIX_UNABLETOBUILDCHAIN);
-
+
} while (nbioContext && state);
*pResult = result;
@@ -782,7 +791,6 @@ cleanup:
PKIX_RETURN(CERTVFYPKIX);
}
-
/*
* FUNCTION: cert_PkixErrorToNssCode
* DESCRIPTION:
@@ -817,16 +825,17 @@ cert_PkixErrorToNssCode(
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)
+ break;
}
if (pkixLog) {
-#ifdef PKIX_ERROR_DESCRIPTION
+#ifdef PKIX_ERROR_DESCRIPTION
PR_LOG(pkixLog, 2, ("Error at level %d: %s\n", errLevel,
PKIX_ErrorText[errPtr->errCode]));
#else
@@ -835,7 +844,7 @@ cert_PkixErrorToNssCode(
#endif /* PKIX_ERROR_DESCRIPTION */
}
errPtr = errPtr->cause;
- errLevel += 1;
+ errLevel += 1;
}
PORT_Assert(nssErr);
if (!nssErr) {
@@ -856,7 +865,7 @@ cert_PkixErrorToNssCode(
*
* PARAMETERS:
* "log"
- * Pointed to already allocated CERTVerifyLog structure.
+ * Pointed to already allocated CERTVerifyLog structure.
* "node"
* A node of PKIX_VerifyNode tree.
* "plContext"
@@ -874,7 +883,7 @@ cert_GetLogFromVerifyNode(
PKIX_VerifyNode *node,
void *plContext)
{
- PKIX_List *children = NULL;
+ PKIX_List *children = NULL;
PKIX_VerifyNode *childNode = NULL;
PKIX_ENTER(CERTVFYPKIX, "cert_GetLogFromVerifyNode");
@@ -894,26 +903,26 @@ cert_GetLogFromVerifyNode(
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;
+ PRUint32 i = 0;
+ PKIX_UInt32 length = 0;
PKIX_CHECK(
PKIX_List_GetLength(children, &length, plContext),
PKIX_LISTGETLENGTHFAILED);
-
- for (i = 0; i < length; i++){
+
+ for (i = 0; i < length; i++) {
PKIX_CHECK(
- PKIX_List_GetItem(children, i, (PKIX_PL_Object**)&childNode,
+ PKIX_List_GetItem(children, i, (PKIX_PL_Object **)&childNode,
plContext),
PKIX_LISTGETITEMFAILED);
-
+
PKIX_CHECK(
cert_GetLogFromVerifyNode(log, childNode, plContext),
PKIX_ERRORINRECURSIVEEQUALSCALL);
@@ -943,7 +952,7 @@ cleanup:
* 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.
@@ -968,23 +977,23 @@ cleanup:
* 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*
+static PKIX_Error *
cert_GetBuildResults(
PKIX_BuildResult *buildResult,
- PKIX_VerifyNode *verifyNode,
- PKIX_Error *error,
- CERTVerifyLog *log,
+ PKIX_VerifyNode *verifyNode,
+ PKIX_Error *error,
+ CERTVerifyLog *log,
CERTCertificate **ptrustedRoot,
- CERTCertList **pvalidChain,
- void *plContext)
+ 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;
-
+ CERTCertList *validChain = NULL;
+ CERTCertificate *trustedRoot = NULL;
+ PKIX_TrustAnchor *trustAnchor = NULL;
+ PKIX_PL_Cert *trustedCert = NULL;
+ PKIX_List *pkixCertChain = NULL;
+
PKIX_ENTER(CERTVFYPKIX, "cert_GetBuildResults");
if (buildResult == NULL && error == NULL) {
PKIX_ERROR(PKIX_NULLARGUMENT);
@@ -1036,7 +1045,7 @@ cert_GetBuildResults(
plContext),
PKIX_CERTGETCERTCERTIFICATEFAILED);
}
-
+
PORT_Assert(!PKIX_ERROR_RECEIVED);
if (trustedRoot) {
@@ -1062,9 +1071,10 @@ cleanup:
PKIX_DECREF(error);
PKIX_DECREF(verifyNode);
PKIX_DECREF(buildResult);
-
+
PKIX_RETURN(CERTVFYPKIX);
}
+#endif /* NSS_DISABLE_LIBPKIX */
/*
* FUNCTION: cert_VerifyCertChainPkix
@@ -1103,27 +1113,31 @@ cleanup:
SECStatus
cert_VerifyCertChainPkix(
CERTCertificate *cert,
- PRBool checkSig,
- SECCertUsage requiredUsage,
- PRTime time,
- void *wincx,
- CERTVerifyLog *log,
- PRBool *pSigerror,
- PRBool *pRevoked)
+ PRBool checkSig,
+ SECCertUsage requiredUsage,
+ PRTime time,
+ void *wincx,
+ CERTVerifyLog *log,
+ PRBool *pSigerror,
+ PRBool *pRevoked)
{
+#ifdef NSS_DISABLE_LIBPKIX
+ PORT_SetError(PR_NOT_IMPLEMENTED_ERROR);
+ return SECFailure;
+#else
PKIX_ProcessingParams *procParams = NULL;
- PKIX_BuildResult *result = NULL;
- PKIX_VerifyNode *verifyNode = NULL;
- PKIX_Error *error = NULL;
+ PKIX_BuildResult *result = NULL;
+ PKIX_VerifyNode *verifyNode = NULL;
+ PKIX_Error *error = NULL;
- SECStatus rv = SECFailure;
- void *plContext = NULL;
+ SECStatus rv = SECFailure;
+ void *plContext = NULL;
#ifdef PKIX_OBJECT_LEAK_TEST
- int leakedObjNum = 0;
- int memLeakLoopCount = 0;
- int objCountTable[PKIX_NUMTYPES];
- int fnInvLocalCount = 0;
+ int leakedObjNum = 0;
+ int memLeakLoopCount = 0;
+ int objCountTable[PKIX_NUMTYPES];
+ int fnInvLocalCount = 0;
PKIX_Boolean savedUsePkixEngFlag = usePKIXValidationEngine;
if (usePKIXValidationEngine) {
@@ -1136,145 +1150,153 @@ cert_VerifyCertChainPkix(
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;
+ PKIX_Boolean abortOnLeak =
+ (PR_GetEnvSecure("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;
- errorGenerated = PKIX_FALSE;
- stackPosition = 0;
-
- if (leakedObjNum) {
- pkix_pl_lifecycle_ObjectTableUpdate(objCountTable);
- }
- memLeakLoopCount += 1;
+ do {
+ rv = SECFailure;
+ plContext = NULL;
+ procParams = NULL;
+ result = NULL;
+ verifyNode = NULL;
+ error = NULL;
+ 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_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_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;
+ error =
+ cert_BuildAndValidateChain(procParams, &result, &verifyNode, plContext);
+ if (error) {
+ goto cleanup;
+ }
-cleanup:
- error = cert_GetBuildResults(result, verifyNode, error, log, NULL, NULL,
- plContext);
- if (error) {
- PKIX_PL_Object_DecRef((PKIX_PL_Object *)error, plContext);
- }
- if (procParams) {
- PKIX_PL_Object_DecRef((PKIX_PL_Object *)procParams, plContext);
- }
- if (plContext) {
- PKIX_PL_NssContext_Destroy(plContext);
- }
+ 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, NULL, NULL,
+ plContext);
+ if (error) {
+ PKIX_PL_Object_DecRef((PKIX_PL_Object *)error, plContext);
+ }
+ 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);
- }
+ leakedObjNum =
+ pkix_pl_lifecycle_ObjectLeakCheck(leakedObjNum ? objCountTable : NULL);
-} while (errorGenerated);
+ 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;
+ runningLeakTest = PKIX_FALSE;
PR_ATOMIC_DECREMENT(&parallelFnInvocationCount);
usePKIXValidationEngine = savedUsePkixEngFlag;
#endif /* PKIX_OBJECT_LEAK_TEST */
return rv;
+#endif /* NSS_DISABLE_LIBPKIX */
}
+#ifndef NSS_DISABLE_LIBPKIX
PKIX_CertSelector *
-cert_GetTargetCertConstraints(CERTCertificate *target, void *plContext)
+cert_GetTargetCertConstraints(CERTCertificate *target, void *plContext)
{
PKIX_ComCertSelParams *certSelParams = NULL;
PKIX_CertSelector *certSelector = NULL;
- PKIX_CertSelector *r= 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;
+ if (error != NULL)
+ goto cleanup;
error = PKIX_CertSelector_Create(NULL, NULL, &certSelector, plContext);
- if (error != NULL) goto cleanup;
+ if (error != NULL)
+ goto cleanup;
error = PKIX_ComCertSelParams_Create(&certSelParams, plContext);
- if (error != NULL) goto cleanup;
+ if (error != NULL)
+ goto cleanup;
error = PKIX_ComCertSelParams_SetCertificate(
- certSelParams, eeCert, plContext);
- if (error != NULL) goto cleanup;
+ certSelParams, eeCert, plContext);
+ if (error != NULL)
+ goto cleanup;
- error = PKIX_CertSelector_SetCommonCertSelectorParams
- (certSelector, certSelParams, 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;
+ if (error == NULL)
+ r = certSelector;
cleanup:
- if (certSelParams != NULL)
+ if (certSelParams != NULL)
PKIX_PL_Object_DecRef((PKIX_PL_Object *)certSelParams, plContext);
- if (eeCert != NULL)
+ if (eeCert != NULL)
PKIX_PL_Object_DecRef((PKIX_PL_Object *)eeCert, plContext);
- if (certSelector != NULL)
+ if (certSelector != NULL)
PKIX_PL_Object_DecRef((PKIX_PL_Object *)certSelector, plContext);
if (error != NULL) {
- SECErrorCodes nssErr;
+ SECErrorCodes nssErr;
- cert_PkixErrorToNssCode(error, &nssErr, plContext);
+ cert_PkixErrorToNssCode(error, &nssErr, plContext);
PKIX_PL_Object_DecRef((PKIX_PL_Object *)error, plContext);
- PORT_SetError(nssErr);
+ PORT_SetError(nssErr);
}
return r;
@@ -1289,39 +1311,42 @@ cert_GetCertStores(void *plContext)
PKIX_Error *error = NULL;
error = PKIX_PL_Pk11CertStore_Create(&certStore, plContext);
- if (error != NULL) goto cleanup;
+ if (error != NULL)
+ goto cleanup;
error = PKIX_List_Create(&certStores, plContext);
- if (error != NULL) goto cleanup;
+ if (error != NULL)
+ goto cleanup;
- error = PKIX_List_AppendItem( certStores,
- (PKIX_PL_Object *)certStore, 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;
+ if (error == NULL)
+ r = certStores;
cleanup:
- if (certStores != NULL)
+ if (certStores != NULL)
PKIX_PL_Object_DecRef((PKIX_PL_Object *)certStores, plContext);
- if (certStore != NULL)
+ if (certStore != NULL)
PKIX_PL_Object_DecRef((PKIX_PL_Object *)certStore, plContext);
if (error != NULL) {
- SECErrorCodes nssErr;
+ SECErrorCodes nssErr;
- cert_PkixErrorToNssCode(error, &nssErr, plContext);
+ cert_PkixErrorToNssCode(error, &nssErr, plContext);
PKIX_PL_Object_DecRef((PKIX_PL_Object *)error, plContext);
- PORT_SetError(nssErr);
+ PORT_SetError(nssErr);
}
return r;
}
-
struct fake_PKIX_PL_CertStruct {
- CERTCertificate *nssCert;
+ CERTCertificate *nssCert;
};
/* This needs to be part of the PKIX_PL_* */
@@ -1332,12 +1357,13 @@ cert_NSSCertFromPKIXCert(const PKIX_PL_Cert *pkix_cert)
{
struct fake_PKIX_PL_CertStruct *fcert = NULL;
- fcert = (struct fake_PKIX_PL_CertStruct*)pkix_cert;
+ 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 *
+cert_PKIXMakeOIDList(const SECOidTag *oids, int oidCount, void *plContext)
{
PKIX_List *r = NULL;
PKIX_List *policyList = NULL;
@@ -1347,16 +1373,16 @@ PKIX_List *cert_PKIXMakeOIDList(const SECOidTag *oids, int oidCount, void *plCon
error = PKIX_List_Create(&policyList, plContext);
if (error != NULL) {
- goto cleanup;
+ goto cleanup;
}
- for (i=0; i<oidCount; i++) {
+ 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);
+ error = PKIX_List_AppendItem(policyList,
+ (PKIX_PL_Object *)policyOID, plContext);
if (error != NULL) {
goto cleanup;
}
@@ -1365,19 +1391,21 @@ PKIX_List *cert_PKIXMakeOIDList(const SECOidTag *oids, int oidCount, void *plCon
}
error = PKIX_List_SetImmutable(policyList, plContext);
- if (error != NULL) goto cleanup;
+ if (error != NULL)
+ goto cleanup;
error = PKIX_PL_Object_IncRef((PKIX_PL_Object *)policyList, plContext);
- if (error == NULL) r = policyList;
+ if (error == NULL)
+ r = policyList;
cleanup:
- if (policyOID != NULL) {
+ if (policyOID != NULL) {
PKIX_PL_Object_DecRef((PKIX_PL_Object *)policyOID, plContext);
}
- if (policyList != NULL) {
+ if (policyList != NULL) {
PKIX_PL_Object_DecRef((PKIX_PL_Object *)policyList, plContext);
}
- if (error != NULL) {
+ if (error != NULL) {
PKIX_PL_Object_DecRef((PKIX_PL_Object *)error, plContext);
}
@@ -1393,14 +1421,13 @@ cert_pkix_FindOutputParam(CERTValOutParam *params, const CERTValParamOutType t)
}
for (i = params; i->type != cert_po_end; i++) {
if (i->type == t) {
- return i;
+ return i;
}
}
return NULL;
}
-
-static PKIX_Error*
+static PKIX_Error *
setRevocationMethod(PKIX_RevocationChecker *revChecker,
PKIX_ProcessingParams *procParams,
const CERTRevocationTests *revTest,
@@ -1413,14 +1440,14 @@ setRevocationMethod(PKIX_RevocationChecker *revChecker,
PKIX_UInt32 methodFlags = 0;
PKIX_Error *error = NULL;
PKIX_UInt32 priority = 0;
-
+
if (revTest->number_of_defined_methods <= (PRUint32)certRevMethod) {
return NULL;
}
if (revTest->preferred_methods) {
unsigned int i = 0;
- for (;i < revTest->number_of_preferred_methods;i++) {
- if (revTest->preferred_methods[i] == certRevMethod)
+ for (; i < revTest->number_of_preferred_methods; i++) {
+ if (revTest->preferred_methods[i] == certRevMethod)
break;
}
priority = i;
@@ -1432,19 +1459,18 @@ setRevocationMethod(PKIX_RevocationChecker *revChecker,
}
error =
PKIX_RevocationChecker_CreateAndAddMethod(revChecker, procParams,
- pkixRevMethod, methodFlags,
- priority, NULL,
- isLeafTest, plContext);
+ pkixRevMethod, methodFlags,
+ priority, NULL,
+ isLeafTest, plContext);
return error;
}
-
SECStatus
-cert_pkixSetParam(PKIX_ProcessingParams *procParams,
- const CERTValInParam *param, void *plContext)
+cert_pkixSetParam(PKIX_ProcessingParams *procParams,
+ const CERTValInParam *param, void *plContext)
{
- PKIX_Error * error = NULL;
- SECStatus r=SECSuccess;
+ PKIX_Error *error = NULL;
+ SECStatus r = SECSuccess;
PKIX_PL_Date *date = NULL;
PKIX_List *policyOIDList = NULL;
PKIX_List *certListPkix = NULL;
@@ -1465,22 +1491,22 @@ cert_pkixSetParam(PKIX_ProcessingParams *procParams,
/* needed? */
error = PKIX_ProcessingParams_SetExplicitPolicyRequired(
- procParams, PKIX_TRUE, plContext);
+ procParams, PKIX_TRUE, plContext);
- if (error != NULL) {
+ 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;
- }
+ param->value.arraySize, plContext);
+ if (policyOIDList == NULL) {
+ r = SECFailure;
+ PORT_SetError(SEC_ERROR_INVALID_ARGS);
+ break;
+ }
error = PKIX_ProcessingParams_SetInitialPolicies(
- procParams,policyOIDList,plContext);
+ procParams, policyOIDList, plContext);
break;
case cert_pi_date:
@@ -1492,7 +1518,7 @@ cert_pkixSetParam(PKIX_ProcessingParams *procParams,
}
} else {
error = pkix_pl_Date_CreateFromPRTime(param->value.scalar.time,
- &date, plContext);
+ &date, plContext);
if (error != NULL) {
errCode = SEC_ERROR_INVALID_TIME;
break;
@@ -1505,8 +1531,7 @@ cert_pkixSetParam(PKIX_ProcessingParams *procParams,
}
break;
- case cert_pi_revocationFlags:
- {
+ case cert_pi_revocationFlags: {
PKIX_UInt32 leafIMFlags = 0;
PKIX_UInt32 chainIMFlags = 0;
PKIX_Boolean validatingResponderCert = PKIX_FALSE;
@@ -1518,7 +1543,7 @@ cert_pkixSetParam(PKIX_ProcessingParams *procParams,
break;
}
- leafIMFlags =
+ leafIMFlags =
flags->leafTests.cert_rev_method_independent_flags;
chainIMFlags =
flags->chainTests.cert_rev_method_independent_flags;
@@ -1532,12 +1557,12 @@ cert_pkixSetParam(PKIX_ProcessingParams *procParams,
error =
PKIX_ProcessingParams_SetRevocationChecker(procParams,
- revChecker, plContext);
+ revChecker, plContext);
if (error) {
break;
}
- if (((PKIX_PL_NssContext*)plContext)->certificateUsage &
+ if (((PKIX_PL_NssContext *)plContext)->certificateUsage &
certificateUsageStatusResponder) {
validatingResponderCert = PKIX_TRUE;
}
@@ -1582,8 +1607,7 @@ cert_pkixSetParam(PKIX_ProcessingParams *procParams,
break;
}
- }
- break;
+ } break;
case cert_pi_trustAnchors:
certList = param->value.pointer.chain;
@@ -1596,10 +1620,10 @@ cert_pkixSetParam(PKIX_ProcessingParams *procParams,
if (error != NULL) {
break;
}
- for(node = CERT_LIST_HEAD(certList); !CERT_LIST_END(node, certList);
- node = CERT_LIST_NEXT(node) ) {
+ 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);
+ &certPkix, plContext);
if (error) {
break;
}
@@ -1609,8 +1633,8 @@ cert_pkixSetParam(PKIX_ProcessingParams *procParams,
break;
}
error = PKIX_List_AppendItem(certListPkix,
- (PKIX_PL_Object*)trustAnchor, plContext);
- if (error) {
+ (PKIX_PL_Object *)trustAnchor, plContext);
+ if (error) {
break;
}
PKIX_PL_Object_DecRef((PKIX_PL_Object *)trustAnchor, plContext);
@@ -1626,12 +1650,12 @@ cert_pkixSetParam(PKIX_ProcessingParams *procParams,
case cert_pi_useAIACertFetch:
error =
PKIX_ProcessingParams_SetUseAIAForCertFetching(procParams,
- (PRBool)(param->value.scalar.b != 0),
+ (PRBool)(param->value.scalar.b !=
+ 0),
plContext);
break;
- case cert_pi_chainVerifyCallback:
- {
+ case cert_pi_chainVerifyCallback: {
const CERTChainVerifyCallback *chainVerifyCallback =
param->value.pointer.chainVerifyCallback;
if (!chainVerifyCallback || !chainVerifyCallback->isChainValid) {
@@ -1641,13 +1665,13 @@ cert_pkixSetParam(PKIX_ProcessingParams *procParams,
}
nssContext->chainVerifyCallback = *chainVerifyCallback;
- }
- break;
+ } break;
case cert_pi_useOnlyTrustAnchors:
error =
PKIX_ProcessingParams_SetUseOnlyTrustAnchors(procParams,
- (PRBool)(param->value.scalar.b != 0),
+ (PRBool)(param->value.scalar.b !=
+ 0),
plContext);
break;
@@ -1660,19 +1684,19 @@ cert_pkixSetParam(PKIX_ProcessingParams *procParams,
if (policyOIDList != NULL)
PKIX_PL_Object_DecRef((PKIX_PL_Object *)policyOIDList, plContext);
- if (date != NULL)
+ if (date != NULL)
PKIX_PL_Object_DecRef((PKIX_PL_Object *)date, plContext);
- if (revChecker != NULL)
+ if (revChecker != NULL)
PKIX_PL_Object_DecRef((PKIX_PL_Object *)revChecker, plContext);
- if (certListPkix)
+ if (certListPkix)
PKIX_PL_Object_DecRef((PKIX_PL_Object *)certListPkix, plContext);
- if (trustAnchor)
+ if (trustAnchor)
PKIX_PL_Object_DecRef((PKIX_PL_Object *)trustAnchor, plContext);
- if (certPkix)
+ if (certPkix)
PKIX_PL_Object_DecRef((PKIX_PL_Object *)certPkix, plContext);
if (error != NULL) {
@@ -1681,8 +1705,7 @@ cert_pkixSetParam(PKIX_ProcessingParams *procParams,
r = SECFailure;
}
- return r;
-
+ return r;
}
void
@@ -1695,210 +1718,218 @@ cert_pkixDestroyValOutParam(CERTValOutParam *params)
}
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_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;
+ case cert_po_certList:
+ if (i->value.pointer.chain) {
+ CERT_DestroyCertList(i->value.pointer.chain);
+ i->value.pointer.chain = NULL;
+ }
+ break;
- default:
- 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
+ /* 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
+ /* 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 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
- }
+ { /* 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 }
};
+#endif /* NSS_DISABLE_LIBPKIX */
-extern const CERTRevocationFlags*
+extern const CERTRevocationFlags *
CERT_GetClassicOCSPEnabledSoftFailurePolicy()
{
+#ifdef NSS_DISABLE_LIBPKIX
+ PORT_SetError(PR_NOT_IMPLEMENTED_ERROR);
+ return NULL;
+#else
return &certRev_NSS_3_11_Ocsp_Enabled_Soft_Policy;
+#endif /* NSS_DISABLE_LIBPKIX */
}
-
+#ifndef NSS_DISABLE_LIBPKIX
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
+ /* 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
+ /* 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 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
- }
+ { /* 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 }
};
+#endif /* NSS_DISABLE_LIBPKIX */
-extern const CERTRevocationFlags*
+extern const CERTRevocationFlags *
CERT_GetClassicOCSPEnabledHardFailurePolicy()
{
+#ifdef NSS_DISABLE_LIBPKIX
+ PORT_SetError(PR_NOT_IMPLEMENTED_ERROR);
+ return NULL;
+#else
return &certRev_NSS_3_11_Ocsp_Enabled_Hard_Policy;
+#endif /* NSS_DISABLE_LIBPKIX */
}
-
+#ifndef NSS_DISABLE_LIBPKIX
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
+ /* 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
+ /* 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
- }
+ { /* 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 }
};
+#endif /* NSS_DISABLE_LIBPKIX */
-extern const CERTRevocationFlags*
+extern const CERTRevocationFlags *
CERT_GetClassicOCSPDisabledPolicy()
{
+#ifdef NSS_DISABLE_LIBPKIX
+ PORT_SetError(PR_NOT_IMPLEMENTED_ERROR);
+ return NULL;
+#else
return &certRev_NSS_3_11_Ocsp_Disabled_Policy;
+#endif /* NSS_DISABLE_LIBPKIX */
}
-
+#ifndef NSS_DISABLE_LIBPKIX
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
+ /* 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
+ /* 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
- }
+ { /* leafTests */
+ 2,
+ certRev_PKIX_Verify_Nist_Policy_LeafFlags,
+ 0,
+ 0,
+ 0 },
+ { /* chainTests */
+ 2,
+ certRev_PKIX_Verify_Nist_Policy_ChainFlags,
+ 0,
+ 0,
+ 0 }
};
+#endif /* NSS_DISABLE_LIBPKIX */
-extern const CERTRevocationFlags*
+extern const CERTRevocationFlags *
CERT_GetPKIXVerifyNistRevocationPolicy()
{
+#ifdef NSS_DISABLE_LIBPKIX
+ PORT_SetError(PR_NOT_IMPLEMENTED_ERROR);
+ return NULL;
+#else
return &certRev_PKIX_Verify_Nist_Policy;
+#endif /* NSS_DISABLE_LIBPKIX */
}
CERTRevocationFlags *
@@ -1906,57 +1937,68 @@ CERT_AllocCERTRevocationFlags(
PRUint32 number_leaf_methods, PRUint32 number_leaf_pref_methods,
PRUint32 number_chain_methods, PRUint32 number_chain_pref_methods)
{
+#ifdef NSS_DISABLE_LIBPKIX
+ PORT_SetError(PR_NOT_IMPLEMENTED_ERROR);
+ return NULL;
+#else
CERTRevocationFlags *flags;
-
+
flags = PORT_New(CERTRevocationFlags);
if (!flags)
- return(NULL);
-
+ return (NULL);
+
flags->leafTests.number_of_defined_methods = number_leaf_methods;
- flags->leafTests.cert_rev_flags_per_method =
+ 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 =
+ 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 =
+ 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 =
+ 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) {
+
+ 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;
+#endif /* NSS_DISABLE_LIBPKIX */
}
-void CERT_DestroyCERTRevocationFlags(CERTRevocationFlags *flags)
+void
+CERT_DestroyCERTRevocationFlags(CERTRevocationFlags *flags)
{
+#ifdef NSS_DISABLE_LIBPKIX
+ PORT_SetError(PR_NOT_IMPLEMENTED_ERROR);
+ return;
+#else
if (!flags)
- return;
-
+ 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);
+ PORT_Free(flags);
+#endif /* NSS_DISABLE_LIBPKIX */
}
/*
@@ -1984,36 +2026,41 @@ void CERT_DestroyCERTRevocationFlags(CERTRevocationFlags *flags)
*
* CERT_PKIXVerifyCert(cert, &output, args
*/
-SECStatus CERT_PKIXVerifyCert(
- CERTCertificate *cert,
- SECCertificateUsage usages,
- CERTValInParam *paramsIn,
- CERTValOutParam *paramsOut,
- void *wincx)
+SECStatus
+CERT_PKIXVerifyCert(
+ CERTCertificate *cert,
+ SECCertificateUsage usages,
+ CERTValInParam *paramsIn,
+ CERTValOutParam *paramsOut,
+ void *wincx)
{
- SECStatus r = SECFailure;
- PKIX_Error * error = NULL;
+#ifdef NSS_DISABLE_LIBPKIX
+ PORT_SetError(PR_NOT_IMPLEMENTED_ERROR);
+ return SECFailure;
+#else
+ 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;
+ 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;
+ int leakedObjNum = 0;
+ int memLeakLoopCount = 0;
+ int objCountTable[PKIX_NUMTYPES];
+ int fnInvLocalCount = 0;
PKIX_Boolean savedUsePkixEngFlag = usePKIXValidationEngine;
if (usePKIXValidationEngine) {
@@ -2026,230 +2073,233 @@ SECStatus CERT_PKIXVerifyCert(
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;
+ PKIX_Boolean abortOnLeak =
+ (PR_GetEnvSecure("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;
+ 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(
+ 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;
- }
+ 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_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;
- }
+ 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;
- }
+ /* 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;
+ /* 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++;
}
- 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;
- }
+ certSelector = cert_GetTargetCertConstraints(cert, plContext);
+ if (certSelector == NULL) {
+ goto cleanup;
+ }
+ error = PKIX_ProcessingParams_SetTargetCertConstraints(procParams, certSelector, plContext);
+ if (error != NULL) {
+ goto cleanup;
+ }
- error = PKIX_BuildResult_GetValidateResult( buildResult, &valResult,
- plContext);
- if (error != NULL) {
- goto cleanup;
- }
+ error = PKIX_BuildChain(procParams, &nbioContext,
+ &buildState, &buildResult, &verifyNode,
+ plContext);
+ if (error != NULL) {
+ goto cleanup;
+ }
- error = PKIX_ValidateResult_GetTrustAnchor( valResult, &trustAnchor,
- plContext);
- if (error != NULL) {
- goto cleanup;
- }
+ error = PKIX_BuildResult_GetValidateResult(buildResult, &valResult,
+ plContext);
+ if (error != NULL) {
+ goto cleanup;
+ }
- if (trustAnchor != NULL) {
- error = PKIX_TrustAnchor_GetTrustedCert( trustAnchor, &trustAnchorCert,
- plContext);
+ 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;
+ /* 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 =
+ 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;
+ } else {
+ oparam->value.pointer.cert = NULL;
+ }
}
- }
- error = PKIX_BuildResult_GetCertChain( buildResult, &builtCertList,
- plContext);
- if (error != NULL) {
- goto cleanup;
- }
+ 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;
- }
+ 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;
+ r = SECSuccess;
-cleanup:
- if (verifyNode) {
- /* Return validation log only upon error. */
- oparam = cert_pkix_FindOutputParam(paramsOut, cert_po_errorLog);
+ cleanup:
+ if (verifyNode) {
+ /* Return validation log only upon error. */
+ oparam = cert_pkix_FindOutputParam(paramsOut, cert_po_errorLog);
#ifdef PKIX_OBJECT_LEAK_TEST
- if (!errorGenerated)
+ 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);
- }
+ 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);
}
- PKIX_PL_Object_DecRef((PKIX_PL_Object *)verifyNode, plContext);
- }
- if (procParams != NULL)
- PKIX_PL_Object_DecRef((PKIX_PL_Object *)procParams, 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 (trustAnchorCert != NULL)
+ PKIX_PL_Object_DecRef((PKIX_PL_Object *)trustAnchorCert, plContext);
- if (trustAnchor != NULL)
- PKIX_PL_Object_DecRef((PKIX_PL_Object *)trustAnchor, 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 (valResult != NULL)
+ PKIX_PL_Object_DecRef((PKIX_PL_Object *)valResult, plContext);
- if (buildResult != NULL)
- PKIX_PL_Object_DecRef((PKIX_PL_Object *)buildResult, 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 (certStores != NULL)
+ PKIX_PL_Object_DecRef((PKIX_PL_Object *)certStores, plContext);
- if (certSelector != NULL)
- PKIX_PL_Object_DecRef((PKIX_PL_Object *)certSelector, 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 (builtCertList != NULL)
+ PKIX_PL_Object_DecRef((PKIX_PL_Object *)builtCertList, plContext);
- if (error != NULL) {
- SECErrorCodes nssErrorCode = 0;
+ 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);
- }
+ 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);
+ PKIX_PL_NssContext_Destroy(plContext);
#ifdef PKIX_OBJECT_LEAK_TEST
- leakedObjNum =
- pkix_pl_lifecycle_ObjectLeakCheck(leakedObjNum ? objCountTable : NULL);
+ 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);
+ 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;
+ runningLeakTest = PKIX_FALSE;
PR_ATOMIC_DECREMENT(&parallelFnInvocationCount);
usePKIXValidationEngine = savedUsePkixEngFlag;
#endif /* PKIX_OBJECT_LEAK_TEST */
return r;
+#endif /* NSS_DISABLE_LIBPKIX */
}
diff --git a/nss/lib/certhigh/crlv2.c b/nss/lib/certhigh/crlv2.c
index 7d8dbb9..d58d4e0 100644
--- a/nss/lib/certhigh/crlv2.c
+++ b/nss/lib/certhigh/crlv2.c
@@ -17,17 +17,15 @@
SECStatus
CERT_FindCRLExtensionByOID(CERTCrl *crl, SECItem *oid, SECItem *value)
{
- return (cert_FindExtensionByOID (crl->extensions, oid, value));
+ return (cert_FindExtensionByOID(crl->extensions, oid, value));
}
-
SECStatus
CERT_FindCRLExtension(CERTCrl *crl, int tag, SECItem *value)
{
- return (cert_FindExtension (crl->extensions, tag, value));
+ return (cert_FindExtension(crl->extensions, tag, value));
}
-
/* Callback to set extensions and adjust verison */
static void
SetCrlExts(void *object, CERTCertExtension **exts)
@@ -35,13 +33,13 @@ SetCrlExts(void *object, CERTCertExtension **exts)
CERTCrl *crl = (CERTCrl *)object;
crl->extensions = exts;
- DER_SetUInteger (crl->arena, &crl->version, SEC_CRL_VERSION_2);
+ DER_SetUInteger(crl->arena, &crl->version, SEC_CRL_VERSION_2);
}
void *
CERT_StartCRLExtensions(CERTCrl *crl)
{
- return (cert_StartExtensions ((void *)crl, crl->arena, SetCrlExts));
+ return (cert_StartExtensions((void *)crl, crl->arena, SetCrlExts));
}
static void
@@ -55,11 +53,12 @@ SetCrlEntryExts(void *object, CERTCertExtension **exts)
void *
CERT_StartCRLEntryExtensions(CERTCrl *crl, CERTCrlEntry *entry)
{
- return (cert_StartExtensions (entry, crl->arena, SetCrlEntryExts));
+ return (cert_StartExtensions(entry, crl->arena, SetCrlEntryExts));
}
-SECStatus CERT_FindCRLNumberExten (PLArenaPool *arena, CERTCrl *crl,
- SECItem *value)
+SECStatus
+CERT_FindCRLNumberExten(PLArenaPool *arena, CERTCrl *crl,
+ SECItem *value)
{
SECItem encodedExtenValue;
SECItem *tmpItem = NULL;
@@ -70,22 +69,22 @@ SECStatus CERT_FindCRLNumberExten (PLArenaPool *arena, CERTCrl *crl,
encodedExtenValue.len = 0;
rv = cert_FindExtension(crl->extensions, SEC_OID_X509_CRL_NUMBER,
- &encodedExtenValue);
- if ( rv != SECSuccess )
- return (rv);
+ &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);
+ rv = SEC_QuickDERDecodeItem(arena, value,
+ SEC_ASN1_GET(SEC_IntegerTemplate),
+ tmpItem);
} else {
rv = SECFailure;
}
- PORT_Free (encodedExtenValue.data);
+ PORT_Free(encodedExtenValue.data);
if (rv == SECFailure) {
PORT_ArenaRelease(arena, mark);
} else {
@@ -94,67 +93,68 @@ SECStatus CERT_FindCRLNumberExten (PLArenaPool *arena, CERTCrl *crl,
return (rv);
}
-SECStatus CERT_FindCRLEntryReasonExten (CERTCrlEntry *crlEntry,
- CERTCRLEntryReasonCode *value)
+SECStatus
+CERT_FindCRLEntryReasonExten(CERTCrlEntry *crlEntry,
+ CERTCRLEntryReasonCode *value)
{
- SECItem wrapperItem = {siBuffer,0};
- SECItem tmpItem = {siBuffer,0};
+ SECItem wrapperItem = { siBuffer, 0 };
+ SECItem tmpItem = { siBuffer, 0 };
SECStatus rv;
PLArenaPool *arena = NULL;
- arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
- if ( ! arena ) {
- return(SECFailure);
+ arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
+ if (!arena) {
+ return (SECFailure);
}
-
- rv = cert_FindExtension(crlEntry->extensions, SEC_OID_X509_REASON_CODE,
+
+ rv = cert_FindExtension(crlEntry->extensions, SEC_OID_X509_REASON_CODE,
&wrapperItem);
- if ( rv != SECSuccess ) {
- goto loser;
+ if (rv != SECSuccess) {
+ goto loser;
}
rv = SEC_QuickDERDecodeItem(arena, &tmpItem,
SEC_ASN1_GET(SEC_EnumeratedTemplate),
&wrapperItem);
- if ( rv != SECSuccess ) {
- goto loser;
+ if (rv != SECSuccess) {
+ goto loser;
}
- *value = (CERTCRLEntryReasonCode) DER_GetInteger(&tmpItem);
+ *value = (CERTCRLEntryReasonCode)DER_GetInteger(&tmpItem);
loser:
- if ( arena ) {
- PORT_FreeArena(arena, PR_FALSE);
+ if (arena) {
+ PORT_FreeArena(arena, PR_FALSE);
}
-
- if ( wrapperItem.data ) {
- PORT_Free(wrapperItem.data);
+
+ if (wrapperItem.data) {
+ PORT_Free(wrapperItem.data);
}
return (rv);
}
-SECStatus CERT_FindInvalidDateExten (CERTCrl *crl, PRTime *value)
+SECStatus
+CERT_FindInvalidDateExten(CERTCrl *crl, PRTime *value)
{
SECItem encodedExtenValue;
- SECItem decodedExtenValue = {siBuffer,0};
+ 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 = 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);
+ 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);
+ rv = DER_GeneralizedTimeToTime(value, &encodedExtenValue);
+ PORT_Free(decodedExtenValue.data);
+ PORT_Free(encodedExtenValue.data);
return (rv);
}
diff --git a/nss/lib/certhigh/exports.gyp b/nss/lib/certhigh/exports.gyp
new file mode 100644
index 0000000..b8e2f3e
--- /dev/null
+++ b/nss/lib/certhigh/exports.gyp
@@ -0,0 +1,33 @@
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+{
+ 'includes': [
+ '../../coreconf/config.gypi'
+ ],
+ 'targets': [
+ {
+ 'target_name': 'lib_certhigh_exports',
+ 'type': 'none',
+ 'copies': [
+ {
+ 'files': [
+ 'ocsp.h',
+ 'ocspt.h'
+ ],
+ 'destination': '<(nss_public_dist_dir)/<(module)'
+ },
+ {
+ 'files': [
+ 'ocspi.h',
+ 'ocspti.h'
+ ],
+ 'destination': '<(nss_private_dist_dir)/<(module)'
+ }
+ ]
+ }
+ ],
+ 'variables': {
+ 'module': 'nss'
+ }
+}
diff --git a/nss/lib/certhigh/ocsp.c b/nss/lib/certhigh/ocsp.c
index 86ae0a0..1048513 100644
--- a/nss/lib/certhigh/ocsp.c
+++ b/nss/lib/certhigh/ocsp.c
@@ -33,13 +33,13 @@
#include "ocspi.h"
#include "genname.h"
#include "certxutl.h"
-#include "pk11func.h" /* for PK11_HashBuf */
+#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_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
@@ -89,48 +89,45 @@ static struct OCSPGlobalStruct {
SEC_OcspFailureMode ocspFailureMode;
CERT_StringFromCertFcn alternateOCSPAIAFcn;
PRBool forcePost;
-} OCSP_Global = { NULL,
- NULL,
- DEFAULT_OCSP_CACHE_SIZE,
+} 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},
+ { NULL, 0, NULL, NULL },
ocspMode_FailureIsVerificationFailure,
NULL,
- PR_FALSE
- };
-
-
+ PR_FALSE };
/* Forward declarations */
static SECItem *
-ocsp_GetEncodedOCSPResponseFromRequest(PLArenaPool *arena,
+ocsp_GetEncodedOCSPResponseFromRequest(PLArenaPool *arena,
CERTOCSPRequest *request,
const char *location,
- const char *method,
- PRTime time,
+ const char *method,
+ PRTime time,
PRBool addServiceLocator,
void *pwArg,
CERTOCSPRequest **pRequest);
static SECStatus
-ocsp_GetOCSPStatusFromNetwork(CERTCertDBHandle *handle,
- CERTOCSPCertID *certID,
- CERTCertificate *cert,
- PRTime time,
+ocsp_GetOCSPStatusFromNetwork(CERTCertDBHandle *handle,
+ CERTOCSPCertID *certID,
+ CERTCertificate *cert,
+ PRTime time,
void *pwArg,
PRBool *certIDWasConsumed,
SECStatus *rv_ocsp);
static SECStatus
ocsp_GetDecodedVerifiedSingleResponseForID(CERTCertDBHandle *handle,
- CERTOCSPCertID *certID,
- CERTCertificate *cert,
- PRTime time,
- void *pwArg,
- const SECItem *encodedResponse,
- CERTOCSPResponse **pDecodedResponse,
- CERTOCSPSingleResponse **pSingle);
+ CERTOCSPCertID *certID,
+ CERTCertificate *cert,
+ PRTime time,
+ void *pwArg,
+ const SECItem *encodedResponse,
+ CERTOCSPResponse **pDecodedResponse,
+ CERTOCSPSingleResponse **pSingle);
static SECStatus
ocsp_CertRevokedAfter(ocspRevokedInfo *revokedInfo, PRTime time);
@@ -149,19 +146,20 @@ cert_DupOCSPCertID(const CERTOCSPCertID *src);
#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)
+#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
+wantOcspTrace(void)
{
static PRBool firstTime = PR_TRUE;
static PRBool wantTrace = PR_FALSE;
#ifdef NSS_HAVE_GETENV
if (firstTime) {
- char *ev = getenv("NSS_TRACE_OCSP");
+ char *ev = PR_GetEnvSecure("NSS_TRACE_OCSP");
if (ev && ev[0]) {
wantTrace = PR_TRUE;
}
@@ -176,7 +174,7 @@ ocsp_Trace(const char *format, ...)
{
char buf[2000];
va_list args;
-
+
if (!wantOcspTrace())
return;
va_start(args, format);
@@ -235,10 +233,10 @@ dumpCertificate(CERTCertificate *cert)
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);
+ 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 : "");
}
@@ -261,27 +259,27 @@ SECStatus
SEC_RegisterDefaultHttpClient(const SEC_HttpClientFcn *fcnTable)
{
if (!OCSP_Global.monitor) {
- PORT_SetError(SEC_ERROR_NOT_INITIALIZED);
- return SECFailure;
+ 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 newCallback,
+ CERT_StringFromCertFcn *oldCallback)
{
CERT_StringFromCertFcn old;
if (!OCSP_Global.monitor) {
- PORT_SetError(SEC_ERROR_NOT_INITIALIZED);
- return SECFailure;
+ PORT_SetError(SEC_ERROR_NOT_INITIALIZED);
+ return SECFailure;
}
PR_EnterMonitor(OCSP_Global.monitor);
@@ -289,7 +287,7 @@ CERT_RegisterAlternateOCSPAIAInfoCallBack(
OCSP_Global.alternateOCSPAIAFcn = newCallback;
PR_ExitMonitor(OCSP_Global.monitor);
if (oldCallback)
- *oldCallback = old;
+ *oldCallback = old;
return SECSuccess;
}
@@ -300,18 +298,18 @@ ocsp_CacheKeyHashFunction(const void *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) {
+ 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) {
+ 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) {
+ walk = (unsigned char *)cid->serialNumber.data;
+ for (i = 0; i < cid->serialNumber.len; ++i, ++walk) {
hash += *walk;
}
return hash;
@@ -322,13 +320,13 @@ 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));
+
+ return (SECEqual == SECITEM_CompareItem(&cid1->issuerNameHash,
+ &cid2->issuerNameHash) &&
+ SECEqual == SECITEM_CompareItem(&cid1->issuerKeyHash,
+ &cid2->issuerKeyHash) &&
+ SECEqual == SECITEM_CompareItem(&cid1->serialNumber,
+ &cid2->serialNumber));
}
static SECStatus
@@ -337,32 +335,32 @@ ocsp_CopyRevokedInfo(PLArenaPool *arena, ocspCertStatus *dest,
{
SECStatus rv = SECFailure;
void *mark;
-
+
mark = PORT_ArenaMark(arena);
-
- dest->certStatusInfo.revokedInfo =
- (ocspRevokedInfo *) PORT_ArenaZAlloc(arena, sizeof(ocspRevokedInfo));
+
+ dest->certStatusInfo.revokedInfo =
+ (ocspRevokedInfo *)PORT_ArenaZAlloc(arena, sizeof(ocspRevokedInfo));
if (!dest->certStatusInfo.revokedInfo) {
goto loser;
}
-
- rv = SECITEM_CopyItem(arena,
- &dest->certStatusInfo.revokedInfo->revocationTime,
+
+ rv = SECITEM_CopyItem(arena,
+ &dest->certStatusInfo.revokedInfo->revocationTime,
&src->revocationTime);
if (rv != SECSuccess) {
goto loser;
}
-
+
if (src->revocationReason) {
- dest->certStatusInfo.revokedInfo->revocationReason =
+ dest->certStatusInfo.revokedInfo->revocationReason =
SECITEM_ArenaDupItem(arena, src->revocationReason);
if (!dest->certStatusInfo.revokedInfo->revocationReason) {
goto loser;
}
- } else {
+ } else {
dest->certStatusInfo.revokedInfo->revocationReason = NULL;
}
-
+
PORT_ArenaUnmark(arena, mark);
return SECSuccess;
@@ -373,39 +371,39 @@ loser:
static SECStatus
ocsp_CopyCertStatus(PLArenaPool *arena, ocspCertStatus *dest,
- ocspCertStatus*src)
+ 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;
+ 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;
}
@@ -453,7 +451,7 @@ ocsp_RemoveCacheItemFromLinkedList(OCSPCacheData *cache, OCSPCacheItem *item)
}
PORT_Assert(cache->numberOfEntries > 1);
-
+
if (item == cache->LRUitem) {
PORT_Assert(item != cache->MRUitem);
PORT_Assert(item->lessRecent == NULL);
@@ -461,8 +459,7 @@ ocsp_RemoveCacheItemFromLinkedList(OCSPCacheData *cache, OCSPCacheItem *item)
PORT_Assert(item->moreRecent->lessRecent == item);
cache->LRUitem = item->moreRecent;
cache->LRUitem->lessRecent = NULL;
- }
- else if (item == cache->MRUitem) {
+ } else if (item == cache->MRUitem) {
PORT_Assert(item->moreRecent == NULL);
PORT_Assert(item->lessRecent != NULL);
PORT_Assert(item->lessRecent->moreRecent == item);
@@ -487,7 +484,7 @@ ocsp_RemoveCacheItemFromLinkedList(OCSPCacheData *cache, OCSPCacheItem *item)
static void
ocsp_MakeCacheEntryMostRecent(OCSPCacheData *cache, OCSPCacheItem *new_most_recent)
{
- OCSP_TRACE(("OCSP ocsp_MakeCacheEntryMostRecent THREADID %p\n",
+ OCSP_TRACE(("OCSP ocsp_MakeCacheEntryMostRecent THREADID %p\n",
PR_GetCurrentThread()));
PR_EnterMonitor(OCSP_Global.monitor);
if (cache->MRUitem == new_most_recent) {
@@ -504,7 +501,7 @@ ocsp_MakeCacheEntryMostRecent(OCSPCacheData *cache, OCSPCacheItem *new_most_rece
static PRBool
ocsp_IsCacheDisabled(void)
{
- /*
+ /*
* maxCacheEntries == 0 means unlimited cache entries
* maxCacheEntries < 0 means cache is disabled
*/
@@ -524,12 +521,12 @@ ocsp_FindCacheEntry(OCSPCacheData *cache, CERTOCSPCertID *certID)
PR_EnterMonitor(OCSP_Global.monitor);
if (ocsp_IsCacheDisabled())
goto loser;
-
+
found_ocsp_item = (OCSPCacheItem *)PL_HashTableLookup(
- cache->entries, certID);
+ cache->entries, certID);
if (!found_ocsp_item)
goto loser;
-
+
OCSP_TRACE(("OCSP ocsp_FindCacheEntry FOUND!\n"));
ocsp_MakeCacheEntryMostRecent(cache, found_ocsp_item);
@@ -556,7 +553,7 @@ 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
+ * because of an allocation failure, or it could get removed because we're
* cleaning up.
*/
OCSP_TRACE(("OCSP ocsp_RemoveCacheItem, THREADID %p\n", PR_GetCurrentThread()));
@@ -586,8 +583,8 @@ ocsp_CheckCacheSize(OCSPCacheData *cache)
/* Cache is not disabled. Number of cache entries is limited.
* The monitor ensures that maxCacheEntries remains positive.
*/
- while (cache->numberOfEntries >
- (PRUint32)OCSP_Global.maxCacheEntries) {
+ while (cache->numberOfEntries >
+ (PRUint32)OCSP_Global.maxCacheEntries) {
ocsp_RemoveCacheItem(cache, cache->LRUitem);
}
}
@@ -600,7 +597,7 @@ 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_RemoveCacheItem(&OCSP_Global.cache,
OCSP_Global.cache.LRUitem);
}
PR_ExitMonitor(OCSP_Global.monitor);
@@ -609,30 +606,30 @@ CERT_ClearOCSPCache(void)
static SECStatus
ocsp_CreateCacheItemAndConsumeCertID(OCSPCacheData *cache,
- CERTOCSPCertID *certID,
+ CERTOCSPCertID *certID,
OCSPCacheItem **pCacheItem)
{
PLArenaPool *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,
+ item = (OCSPCacheItem *)PORT_ArenaZAlloc(certID->poolp,
sizeof(OCSPCacheItem));
if (!item) {
- goto loser;
+ goto loser;
}
item->certID = certID;
- new_hash_entry = PL_HashTableAdd(cache->entries, item->certID,
+ new_hash_entry = PL_HashTableAdd(cache->entries, item->certID,
item);
if (!new_hash_entry) {
goto loser;
@@ -644,7 +641,7 @@ ocsp_CreateCacheItemAndConsumeCertID(OCSPCacheData *cache,
PR_ExitMonitor(OCSP_Global.monitor);
return SECSuccess;
-
+
loser:
PORT_ArenaRelease(arena, mark);
PR_ExitMonitor(OCSP_Global.monitor);
@@ -666,7 +663,7 @@ ocsp_SetCacheItemResponse(OCSPCacheItem *item,
if (item->certStatusArena == NULL) {
return SECFailure;
}
- rv = ocsp_CopyCertStatus(item->certStatusArena, &item->certStatus,
+ rv = ocsp_CopyCertStatus(item->certStatusArena, &item->certStatus,
response->certStatus);
if (rv != SECSuccess) {
PORT_FreeArena(item->certStatusArena, PR_FALSE);
@@ -674,11 +671,11 @@ ocsp_SetCacheItemResponse(OCSPCacheItem *item,
return rv;
}
item->missingResponseError = 0;
- rv = DER_GeneralizedTimeToTime(&item->thisUpdate,
+ rv = DER_GeneralizedTimeToTime(&item->thisUpdate,
&response->thisUpdate);
item->haveThisUpdate = (rv == SECSuccess);
if (response->nextUpdate) {
- rv = DER_GeneralizedTimeToTime(&item->nextUpdate,
+ rv = DER_GeneralizedTimeToTime(&item->nextUpdate,
response->nextUpdate);
item->haveNextUpdate = (rv == SECSuccess);
} else {
@@ -694,60 +691,60 @@ 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:",
+ OCSP_Global.maximumSecondsToNextFetchAttempt *
+ MICROSECONDS_PER_SECOND;
+ OCSP_TRACE_TIME("latestTimeWhenResponseIsConsideredFresh:",
latestTimeWhenResponseIsConsideredFresh);
} else {
latestTimeWhenResponseIsConsideredFresh = now +
- OCSP_Global.minimumSecondsToNextFetchAttempt *
- MICROSECONDS_PER_SECOND;
+ OCSP_Global.minimumSecondsToNextFetchAttempt *
+ MICROSECONDS_PER_SECOND;
OCSP_TRACE_TIME("no thisUpdate, "
- "latestTimeWhenResponseIsConsideredFresh:",
+ "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:",
latestTimeWhenResponseIsConsideredFresh);
}
-
+
earliestAllowedNextFetchAttemptTime = now +
- OCSP_Global.minimumSecondsToNextFetchAttempt *
- MICROSECONDS_PER_SECOND;
- OCSP_TRACE_TIME("earliestAllowedNextFetchAttemptTime:",
+ OCSP_Global.minimumSecondsToNextFetchAttempt *
+ MICROSECONDS_PER_SECOND;
+ OCSP_TRACE_TIME("earliestAllowedNextFetchAttemptTime:",
earliestAllowedNextFetchAttemptTime);
-
- if (latestTimeWhenResponseIsConsideredFresh <
+
+ if (latestTimeWhenResponseIsConsideredFresh <
earliestAllowedNextFetchAttemptTime) {
- latestTimeWhenResponseIsConsideredFresh =
+ latestTimeWhenResponseIsConsideredFresh =
earliestAllowedNextFetchAttemptTime;
- OCSP_TRACE_TIME("latest < earliest, setting latest to:",
+ OCSP_TRACE_TIME("latest < earliest, setting latest to:",
latestTimeWhenResponseIsConsideredFresh);
}
-
- cacheItem->nextFetchAttemptTime =
+
+ cacheItem->nextFetchAttemptTime =
latestTimeWhenResponseIsConsideredFresh;
- OCSP_TRACE_TIME("nextFetchAttemptTime",
- latestTimeWhenResponseIsConsideredFresh);
+ OCSP_TRACE_TIME("nextFetchAttemptTime",
+ latestTimeWhenResponseIsConsideredFresh);
PR_ExitMonitor(OCSP_Global.monitor);
}
@@ -776,14 +773,14 @@ ocsp_IsCacheItemFresh(OCSPCacheItem *cacheItem)
}
/*
- * Status in *certIDWasConsumed will always be correct, regardless of
+ * 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,
+ocsp_CreateOrUpdateCacheEntry(OCSPCacheData *cache,
CERTOCSPCertID *certID,
CERTOCSPSingleResponse *single,
PRBool *certIDWasConsumed)
@@ -791,13 +788,13 @@ ocsp_CreateOrUpdateCacheEntry(OCSPCacheData *cache,
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);
/* Don't replace an unknown or revoked entry with an error entry, even if
@@ -867,12 +864,12 @@ 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;
+ case ocspMode_FailureIsVerificationFailure:
+ case ocspMode_FailureIsNotAVerificationFailure:
+ break;
+ default:
+ PORT_SetError(SEC_ERROR_INVALID_ARGS);
+ return SECFailure;
}
PR_EnterMonitor(OCSP_Global.monitor);
@@ -886,14 +883,14 @@ CERT_OCSPCacheSettings(PRInt32 maxCacheEntries,
PRUint32 minimumSecondsToNextFetchAttempt,
PRUint32 maximumSecondsToNextFetchAttempt)
{
- if (minimumSecondsToNextFetchAttempt > maximumSecondsToNextFetchAttempt
- || maxCacheEntries < -1) {
+ 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) {
@@ -901,24 +898,24 @@ CERT_OCSPCacheSettings(PRInt32 maxCacheEntries,
} else {
OCSP_Global.maxCacheEntries = maxCacheEntries;
}
-
- if (minimumSecondsToNextFetchAttempt <
- OCSP_Global.minimumSecondsToNextFetchAttempt
- || maximumSecondsToNextFetchAttempt <
+
+ if (minimumSecondsToNextFetchAttempt <
+ OCSP_Global.minimumSecondsToNextFetchAttempt ||
+ maximumSecondsToNextFetchAttempt <
OCSP_Global.maximumSecondsToNextFetchAttempt) {
/*
- * Ensure our existing cache entries are not used longer than the
+ * 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 =
+
+ OCSP_Global.minimumSecondsToNextFetchAttempt =
minimumSecondsToNextFetchAttempt;
- OCSP_Global.maximumSecondsToNextFetchAttempt =
+ OCSP_Global.maximumSecondsToNextFetchAttempt =
maximumSecondsToNextFetchAttempt;
ocsp_CheckCacheSize(&OCSP_Global.cache);
-
+
PR_ExitMonitor(OCSP_Global.monitor);
return SECSuccess;
}
@@ -932,7 +929,8 @@ CERT_SetOCSPTimeout(PRUint32 seconds)
}
/* this function is called at NSS initialization time */
-SECStatus OCSP_InitGlobal(void)
+SECStatus
+OCSP_InitGlobal(void)
{
SECStatus rv = SECFailure;
@@ -944,12 +942,12 @@ SECStatus OCSP_InitGlobal(void)
PR_EnterMonitor(OCSP_Global.monitor);
if (!OCSP_Global.cache.entries) {
- OCSP_Global.cache.entries =
- PL_NewHashTable(0,
- ocsp_CacheKeyHashFunction,
- ocsp_CacheKeyCompareFunction,
- PL_CompareValues,
- NULL,
+ 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;
@@ -969,7 +967,8 @@ SECStatus OCSP_InitGlobal(void)
return rv;
}
-SECStatus OCSP_ShutdownGlobal(void)
+SECStatus
+OCSP_ShutdownGlobal(void)
{
if (!OCSP_Global.monitor)
return SECSuccess;
@@ -986,12 +985,12 @@ SECStatus OCSP_ShutdownGlobal(void)
OCSP_Global.defaultHttpClientFcn = NULL;
OCSP_Global.maxCacheEntries = DEFAULT_OCSP_CACHE_SIZE;
- OCSP_Global.minimumSecondsToNextFetchAttempt =
- DEFAULT_MINIMUM_SECONDS_TO_NEXT_OCSP_FETCH_ATTEMPT;
+ OCSP_Global.minimumSecondsToNextFetchAttempt =
+ DEFAULT_MINIMUM_SECONDS_TO_NEXT_OCSP_FETCH_ATTEMPT;
OCSP_Global.maximumSecondsToNextFetchAttempt =
- DEFAULT_MAXIMUM_SECONDS_TO_NEXT_OCSP_FETCH_ATTEMPT;
+ DEFAULT_MAXIMUM_SECONDS_TO_NEXT_OCSP_FETCH_ATTEMPT;
OCSP_Global.ocspFailureMode =
- ocspMode_FailureIsVerificationFailure;
+ ocspMode_FailureIsVerificationFailure;
PR_ExitMonitor(OCSP_Global.monitor);
PR_DestroyMonitor(OCSP_Global.monitor);
@@ -1000,22 +999,23 @@ SECStatus OCSP_ShutdownGlobal(void)
}
/*
- * A return value of NULL means:
+ * 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 *
+SEC_GetRegisteredHttpClient(void)
{
const SEC_HttpClientFcn *retval;
if (!OCSP_Global.monitor) {
- PORT_SetError(SEC_ERROR_NOT_INITIALIZED);
- return NULL;
+ PORT_SetError(SEC_ERROR_NOT_INITIALIZED);
+ return NULL;
}
PR_EnterMonitor(OCSP_Global.monitor);
retval = OCSP_Global.defaultHttpClientFcn;
PR_ExitMonitor(OCSP_Global.monitor);
-
+
return retval;
}
@@ -1057,7 +1057,6 @@ extern const SEC_ASN1Template ocsp_SingleRequestTemplate[];
extern const SEC_ASN1Template ocsp_SingleResponseTemplate[];
extern const SEC_ASN1Template ocsp_TBSRequestTemplate[];
-
/*
* Request-related templates...
*/
@@ -1069,14 +1068,14 @@ extern const SEC_ASN1Template ocsp_TBSRequestTemplate[];
*/
static const SEC_ASN1Template ocsp_OCSPRequestTemplate[] = {
{ SEC_ASN1_SEQUENCE,
- 0, NULL, sizeof(CERTOCSPRequest) },
+ 0, NULL, sizeof(CERTOCSPRequest) },
{ SEC_ASN1_POINTER,
- offsetof(CERTOCSPRequest, tbsRequest),
- ocsp_TBSRequestTemplate },
+ offsetof(CERTOCSPRequest, tbsRequest),
+ ocsp_TBSRequestTemplate },
{ SEC_ASN1_OPTIONAL | SEC_ASN1_EXPLICIT |
- SEC_ASN1_CONSTRUCTED | SEC_ASN1_CONTEXT_SPECIFIC | 0,
- offsetof(CERTOCSPRequest, optionalSignature),
- ocsp_PointerToSignatureTemplate },
+ SEC_ASN1_CONSTRUCTED | SEC_ASN1_CONTEXT_SPECIFIC | 0,
+ offsetof(CERTOCSPRequest, optionalSignature),
+ ocsp_PointerToSignatureTemplate },
{ 0 }
};
@@ -1095,22 +1094,22 @@ static const SEC_ASN1Template ocsp_OCSPRequestTemplate[] = {
*/
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) },
+ 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_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 },
+ offsetof(ocspTBSRequest, requestList),
+ ocsp_SingleRequestTemplate },
{ SEC_ASN1_OPTIONAL | SEC_ASN1_EXPLICIT |
- SEC_ASN1_CONSTRUCTED | SEC_ASN1_CONTEXT_SPECIFIC | 2,
- offsetof(ocspTBSRequest, requestExtensions),
- CERT_SequenceOfCertExtensionTemplate },
+ SEC_ASN1_CONSTRUCTED | SEC_ASN1_CONTEXT_SPECIFIC | 2,
+ offsetof(ocspTBSRequest, requestExtensions),
+ CERT_SequenceOfCertExtensionTemplate },
{ 0 }
};
@@ -1122,16 +1121,16 @@ const SEC_ASN1Template ocsp_TBSRequestTemplate[] = {
*/
static const SEC_ASN1Template ocsp_SignatureTemplate[] = {
{ SEC_ASN1_SEQUENCE,
- 0, NULL, sizeof(ocspSignature) },
+ 0, NULL, sizeof(ocspSignature) },
{ SEC_ASN1_INLINE | SEC_ASN1_XTRN,
- offsetof(ocspSignature, signatureAlgorithm),
- SEC_ASN1_SUB(SECOID_AlgorithmIDTemplate) },
+ offsetof(ocspSignature, signatureAlgorithm),
+ SEC_ASN1_SUB(SECOID_AlgorithmIDTemplate) },
{ SEC_ASN1_BIT_STRING,
- offsetof(ocspSignature, signature) },
+ 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) },
+ SEC_ASN1_CONSTRUCTED | SEC_ASN1_CONTEXT_SPECIFIC | SEC_ASN1_XTRN | 0,
+ offsetof(ocspSignature, derCerts),
+ SEC_ASN1_SUB(SEC_SequenceOfAnyTemplate) },
{ 0 }
};
@@ -1157,19 +1156,18 @@ const SEC_ASN1Template ocsp_PointerToSignatureTemplate[] = {
* is the only way it will compile.
*/
const SEC_ASN1Template ocsp_SingleRequestTemplate[] = {
- { SEC_ASN1_SEQUENCE,
- 0, NULL, sizeof(ocspSingleRequest) },
+ { SEC_ASN1_SEQUENCE,
+ 0, NULL, sizeof(ocspSingleRequest) },
{ SEC_ASN1_POINTER,
- offsetof(ocspSingleRequest, reqCert),
- ocsp_CertIDTemplate },
+ offsetof(ocspSingleRequest, reqCert),
+ ocsp_CertIDTemplate },
{ SEC_ASN1_OPTIONAL | SEC_ASN1_EXPLICIT |
- SEC_ASN1_CONSTRUCTED | SEC_ASN1_CONTEXT_SPECIFIC | 0,
- offsetof(ocspSingleRequest, singleRequestExtensions),
- CERT_SequenceOfCertExtensionTemplate },
+ 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.
@@ -1187,21 +1185,20 @@ const SEC_ASN1Template ocsp_SingleRequestTemplate[] = {
* is the only way it will compile.
*/
const SEC_ASN1Template ocsp_CertIDTemplate[] = {
- { SEC_ASN1_SEQUENCE,
- 0, NULL, sizeof(CERTOCSPCertID) },
+ { SEC_ASN1_SEQUENCE,
+ 0, NULL, sizeof(CERTOCSPCertID) },
{ SEC_ASN1_INLINE | SEC_ASN1_XTRN,
- offsetof(CERTOCSPCertID, hashAlgorithm),
- SEC_ASN1_SUB(SECOID_AlgorithmIDTemplate) },
+ offsetof(CERTOCSPCertID, hashAlgorithm),
+ SEC_ASN1_SUB(SECOID_AlgorithmIDTemplate) },
{ SEC_ASN1_OCTET_STRING,
- offsetof(CERTOCSPCertID, issuerNameHash) },
+ offsetof(CERTOCSPCertID, issuerNameHash) },
{ SEC_ASN1_OCTET_STRING,
- offsetof(CERTOCSPCertID, issuerKeyHash) },
- { SEC_ASN1_INTEGER,
- offsetof(CERTOCSPCertID, serialNumber) },
+ offsetof(CERTOCSPCertID, issuerKeyHash) },
+ { SEC_ASN1_INTEGER,
+ offsetof(CERTOCSPCertID, serialNumber) },
{ 0 }
};
-
/*
* Response-related templates...
*/
@@ -1212,14 +1209,14 @@ const SEC_ASN1Template ocsp_CertIDTemplate[] = {
* 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_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 },
+ SEC_ASN1_CONSTRUCTED | SEC_ASN1_CONTEXT_SPECIFIC | 0,
+ offsetof(CERTOCSPResponse, responseBytes),
+ ocsp_PointerToResponseBytesTemplate },
{ 0 }
};
@@ -1230,11 +1227,11 @@ const SEC_ASN1Template ocsp_OCSPResponseTemplate[] = {
*/
const SEC_ASN1Template ocsp_ResponseBytesTemplate[] = {
{ SEC_ASN1_SEQUENCE,
- 0, NULL, sizeof(ocspResponseBytes) },
+ 0, NULL, sizeof(ocspResponseBytes) },
{ SEC_ASN1_OBJECT_ID,
- offsetof(ocspResponseBytes, responseType) },
+ offsetof(ocspResponseBytes, responseType) },
{ SEC_ASN1_OCTET_STRING,
- offsetof(ocspResponseBytes, response) },
+ offsetof(ocspResponseBytes, response) },
{ 0 }
};
@@ -1259,21 +1256,21 @@ const SEC_ASN1Template ocsp_PointerToResponseBytesTemplate[] = {
*/
static const SEC_ASN1Template ocsp_BasicOCSPResponseTemplate[] = {
{ SEC_ASN1_SEQUENCE,
- 0, NULL, sizeof(ocspBasicOCSPResponse) },
+ 0, NULL, sizeof(ocspBasicOCSPResponse) },
{ SEC_ASN1_ANY | SEC_ASN1_SAVE,
- offsetof(ocspBasicOCSPResponse, tbsResponseDataDER) },
+ offsetof(ocspBasicOCSPResponse, tbsResponseDataDER) },
{ SEC_ASN1_POINTER,
- offsetof(ocspBasicOCSPResponse, tbsResponseData),
- ocsp_ResponseDataTemplate },
+ offsetof(ocspBasicOCSPResponse, tbsResponseData),
+ ocsp_ResponseDataTemplate },
{ SEC_ASN1_INLINE | SEC_ASN1_XTRN,
- offsetof(ocspBasicOCSPResponse, responseSignature.signatureAlgorithm),
- SEC_ASN1_SUB(SECOID_AlgorithmIDTemplate) },
+ offsetof(ocspBasicOCSPResponse, responseSignature.signatureAlgorithm),
+ SEC_ASN1_SUB(SECOID_AlgorithmIDTemplate) },
{ SEC_ASN1_BIT_STRING,
- offsetof(ocspBasicOCSPResponse, responseSignature.signature) },
+ 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) },
+ SEC_ASN1_CONSTRUCTED | SEC_ASN1_CONTEXT_SPECIFIC | SEC_ASN1_XTRN | 0,
+ offsetof(ocspBasicOCSPResponse, responseSignature.derCerts),
+ SEC_ASN1_SUB(SEC_SequenceOfAnyTemplate) },
{ 0 }
};
@@ -1291,22 +1288,22 @@ static const SEC_ASN1Template ocsp_BasicOCSPResponseTemplate[] = {
*/
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) },
+ 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) },
+ offsetof(ocspResponseData, derResponderID) },
{ SEC_ASN1_GENERALIZED_TIME,
- offsetof(ocspResponseData, producedAt) },
+ offsetof(ocspResponseData, producedAt) },
{ SEC_ASN1_SEQUENCE_OF,
- offsetof(ocspResponseData, responses),
- ocsp_SingleResponseTemplate },
+ offsetof(ocspResponseData, responses),
+ ocsp_SingleResponseTemplate },
{ SEC_ASN1_OPTIONAL | SEC_ASN1_EXPLICIT |
- SEC_ASN1_CONSTRUCTED | SEC_ASN1_CONTEXT_SPECIFIC | 1,
- offsetof(ocspResponseData, responseExtensions),
- CERT_SequenceOfCertExtensionTemplate },
+ SEC_ASN1_CONSTRUCTED | SEC_ASN1_CONTEXT_SPECIFIC | 1,
+ offsetof(ocspResponseData, responseExtensions),
+ CERT_SequenceOfCertExtensionTemplate },
{ 0 }
};
@@ -1327,24 +1324,25 @@ const SEC_ASN1Template ocsp_ResponseDataTemplate[] = {
*/
const SEC_ASN1Template ocsp_ResponderIDByNameTemplate[] = {
{ SEC_ASN1_EXPLICIT | SEC_ASN1_CONSTRUCTED | SEC_ASN1_CONTEXT_SPECIFIC | 1,
- offsetof(ocspResponderID, responderIDValue.name),
- CERT_NameTemplate }
+ 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) }
+ 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) }
+ 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) }
+ SEC_ASN1_XTRN | 1,
+ 0, SEC_ASN1_SUB(SEC_AnyTemplate) }
};
/*
@@ -1361,22 +1359,22 @@ static const SEC_ASN1Template ocsp_ResponderIDDerNameTemplate[] = {
*/
const SEC_ASN1Template ocsp_SingleResponseTemplate[] = {
{ SEC_ASN1_SEQUENCE,
- 0, NULL, sizeof(CERTOCSPSingleResponse) },
+ 0, NULL, sizeof(CERTOCSPSingleResponse) },
{ SEC_ASN1_POINTER,
- offsetof(CERTOCSPSingleResponse, certID),
- ocsp_CertIDTemplate },
+ offsetof(CERTOCSPSingleResponse, certID),
+ ocsp_CertIDTemplate },
{ SEC_ASN1_ANY,
- offsetof(CERTOCSPSingleResponse, derCertStatus) },
+ offsetof(CERTOCSPSingleResponse, derCertStatus) },
{ SEC_ASN1_GENERALIZED_TIME,
- offsetof(CERTOCSPSingleResponse, thisUpdate) },
+ 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_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 },
+ SEC_ASN1_CONSTRUCTED | SEC_ASN1_CONTEXT_SPECIFIC | 1,
+ offsetof(CERTOCSPSingleResponse, singleExtensions),
+ CERT_SequenceOfCertExtensionTemplate },
{ 0 }
};
@@ -1395,23 +1393,23 @@ const SEC_ASN1Template ocsp_SingleResponseTemplate[] = {
*/
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) }
+ 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 }
+ { 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) }
+ 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) }
+ offsetof(ocspCertStatus, certStatusInfo.otherInfo),
+ SEC_ASN1_SUB(SEC_AnyTemplate) }
};
/*
@@ -1425,18 +1423,17 @@ static const SEC_ASN1Template ocsp_CertStatusOtherTemplate[] = {
*/
const SEC_ASN1Template ocsp_RevokedInfoTemplate[] = {
{ SEC_ASN1_SEQUENCE,
- 0, NULL, sizeof(ocspRevokedInfo) },
+ 0, NULL, sizeof(ocspRevokedInfo) },
{ SEC_ASN1_GENERALIZED_TIME,
- offsetof(ocspRevokedInfo, revocationTime) },
+ 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) },
+ SEC_ASN1_CONSTRUCTED | SEC_ASN1_CONTEXT_SPECIFIC |
+ SEC_ASN1_XTRN | 0,
+ offsetof(ocspRevokedInfo, revocationReason),
+ SEC_ASN1_SUB(SEC_PointerToEnumeratedTemplate) },
{ 0 }
};
-
/*
* OCSP-specific extension templates:
*/
@@ -1448,25 +1445,24 @@ const SEC_ASN1Template ocsp_RevokedInfoTemplate[] = {
*/
static const SEC_ASN1Template ocsp_ServiceLocatorTemplate[] = {
{ SEC_ASN1_SEQUENCE,
- 0, NULL, sizeof(ocspServiceLocator) },
+ 0, NULL, sizeof(ocspServiceLocator) },
{ SEC_ASN1_POINTER,
- offsetof(ocspServiceLocator, issuer),
- CERT_NameTemplate },
+ offsetof(ocspServiceLocator, issuer),
+ CERT_NameTemplate },
{ SEC_ASN1_OPTIONAL | SEC_ASN1_ANY,
- offsetof(ocspServiceLocator, locator) },
+ 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:
+ * INPUTS:
* PLArenaPool *arena
* The return value is allocated from here.
* If a NULL is passed in, allocation is done from the heap instead.
@@ -1482,7 +1478,7 @@ static const SEC_ASN1Template ocsp_ServiceLocatorTemplate[] = {
*/
SECItem *
CERT_EncodeOCSPRequest(PLArenaPool *arena, CERTOCSPRequest *request,
- void *pwArg)
+ void *pwArg)
{
SECStatus rv;
@@ -1491,10 +1487,10 @@ CERT_EncodeOCSPRequest(PLArenaPool *arena, CERTOCSPRequest *request,
PORT_Assert(request->tbsRequest);
if (request->tbsRequest->extensionHandle != NULL) {
- rv = CERT_FinishExtensions(request->tbsRequest->extensionHandle);
- request->tbsRequest->extensionHandle = NULL;
- if (rv != SECSuccess)
- return NULL;
+ rv = CERT_FinishExtensions(request->tbsRequest->extensionHandle);
+ request->tbsRequest->extensionHandle = NULL;
+ if (rv != SECSuccess)
+ return NULL;
}
/*
@@ -1510,7 +1506,6 @@ CERT_EncodeOCSPRequest(PLArenaPool *arena, CERTOCSPRequest *request,
return SEC_ASN1EncodeItem(arena, NULL, request, ocsp_OCSPRequestTemplate);
}
-
/*
* FUNCTION: CERT_DecodeOCSPRequest
* Decode a DER encoded OCSP Request.
@@ -1533,27 +1528,27 @@ CERT_DecodeOCSPRequest(const SECItem *src)
arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
if (arena == NULL) {
- goto loser;
+ goto loser;
}
- dest = (CERTOCSPRequest *) PORT_ArenaZAlloc(arena,
- sizeof(CERTOCSPRequest));
+ dest = (CERTOCSPRequest *)PORT_ArenaZAlloc(arena,
+ sizeof(CERTOCSPRequest));
if (dest == NULL) {
- goto loser;
+ 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;
+ 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;
+ if (PORT_GetError() == SEC_ERROR_BAD_DER)
+ PORT_SetError(SEC_ERROR_OCSP_MALFORMED_REQUEST);
+ goto loser;
}
/*
@@ -1561,24 +1556,24 @@ CERT_DecodeOCSPRequest(const SECItem *src)
* of doing this copying of the arena pointer.
*/
for (i = 0; dest->tbsRequest->requestList[i] != NULL; i++) {
- dest->tbsRequest->requestList[i]->arena = arena;
+ dest->tbsRequest->requestList[i]->arena = arena;
}
return dest;
loser:
if (arena != NULL) {
- PORT_FreeArena(arena, PR_FALSE);
+ PORT_FreeArena(arena, PR_FALSE);
}
return NULL;
}
SECStatus
-CERT_DestroyOCSPCertID(CERTOCSPCertID* certID)
+CERT_DestroyOCSPCertID(CERTOCSPCertID *certID)
{
if (certID && certID->poolp) {
- PORT_FreeArena(certID->poolp, PR_FALSE);
- return SECSuccess;
+ PORT_FreeArena(certID->poolp, PR_FALSE);
+ return SECSuccess;
}
PORT_SetError(SEC_ERROR_INVALID_ARGS);
return SECFailure;
@@ -1593,7 +1588,7 @@ CERT_DestroyOCSPCertID(CERTOCSPCertID* certID)
*/
SECItem *
-ocsp_DigestValue(PLArenaPool *arena, SECOidTag digestAlg,
+ocsp_DigestValue(PLArenaPool *arena, SECOidTag digestAlg,
SECItem *fill, const SECItem *src)
{
const SECHashObject *digestObject;
@@ -1601,27 +1596,27 @@ ocsp_DigestValue(PLArenaPool *arena, SECOidTag digestAlg,
void *mark = NULL;
void *digestBuff = NULL;
- if ( arena != NULL ) {
+ if (arena != NULL) {
mark = PORT_ArenaMark(arena);
}
digestObject = HASH_GetHashObjectByOidTag(digestAlg);
- if ( digestObject == NULL ) {
+ 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;
+ 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 (fill->len < digestObject->length) {
+ PORT_SetError(SEC_ERROR_INVALID_ARGS);
+ goto loser;
+ }
+ digestBuff = fill->data;
}
if (PK11_HashBuf(digestAlg, digestBuff,
@@ -1629,7 +1624,7 @@ ocsp_DigestValue(PLArenaPool *arena, SECOidTag digestAlg,
goto loser;
}
- if ( arena != NULL ) {
+ if (arena != NULL) {
PORT_ArenaUnmark(arena, mark);
}
@@ -1646,7 +1641,7 @@ loser:
SECITEM_FreeItem(result, (fill == NULL) ? PR_TRUE : PR_FALSE);
}
}
- return(NULL);
+ return (NULL);
}
/*
@@ -1713,18 +1708,18 @@ ocsp_CreateCertID(PLArenaPool *arena, CERTCertificate *cert, PRTime time)
certID = PORT_ArenaZNew(arena, CERTOCSPCertID);
if (certID == NULL) {
- goto loser;
+ goto loser;
}
rv = SECOID_SetAlgorithmID(arena, &certID->hashAlgorithm, SEC_OID_SHA1,
- NULL);
+ NULL);
if (rv != SECSuccess) {
- goto loser;
+ goto loser;
}
issuerCert = CERT_FindCertIssuer(cert, time, certUsageAnyCA);
if (issuerCert == NULL) {
- goto loser;
+ goto loser;
}
if (CERT_GetSubjectNameDigest(arena, issuerCert, SEC_OID_SHA1,
@@ -1745,29 +1740,28 @@ ocsp_CreateCertID(PLArenaPool *arena, CERTCertificate *cert, PRTime time)
}
if (CERT_GetSubjectPublicKeyDigest(arena, issuerCert, SEC_OID_SHA1,
- &certID->issuerKeyHash) == NULL) {
- goto loser;
+ &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_GetSubjectPublicKeyDigest(arena, issuerCert, SEC_OID_MD5,
- &certID->issuerMD5KeyHash) == NULL) {
- goto loser;
+ &certID->issuerMD5KeyHash) == NULL) {
+ goto loser;
}
if (CERT_GetSubjectPublicKeyDigest(arena, issuerCert, SEC_OID_MD2,
- &certID->issuerMD2KeyHash) == NULL) {
- goto loser;
+ &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;
+ goto loser;
}
PORT_ArenaUnmark(arena, mark);
@@ -1775,25 +1769,25 @@ ocsp_CreateCertID(PLArenaPool *arena, CERTCertificate *cert, PRTime time)
loser:
if (issuerCert != NULL) {
- CERT_DestroyCertificate(issuerCert);
+ CERT_DestroyCertificate(issuerCert);
}
PORT_ArenaRelease(arena, mark);
return NULL;
}
-CERTOCSPCertID*
+CERTOCSPCertID *
CERT_CreateOCSPCertID(CERTCertificate *cert, PRTime time)
{
PLArenaPool *arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
CERTOCSPCertID *certID;
PORT_Assert(arena != NULL);
if (!arena)
- return NULL;
-
+ return NULL;
+
certID = ocsp_CreateCertID(arena, cert, time);
if (!certID) {
- PORT_FreeArena(arena, PR_FALSE);
- return NULL;
+ PORT_FreeArena(arena, PR_FALSE);
+ return NULL;
}
certID->poolp = arena;
return certID;
@@ -1818,11 +1812,11 @@ cert_DupOCSPCertID(const CERTOCSPCertID *src)
if (!dest)
goto loser;
-#define DUPHELP(element) \
- if (src->element.data && \
- SECITEM_CopyItem(arena, &dest->element, &src->element) \
- != SECSuccess) { \
- goto loser; \
+#define DUPHELP(element) \
+ if (src->element.data && \
+ SECITEM_CopyItem(arena, &dest->element, &src->element) != \
+ SECSuccess) { \
+ goto loser; \
}
DUPHELP(hashAlgorithm.algorithm)
@@ -1850,12 +1844,13 @@ loser:
/*
* Callback to set Extensions in request object
*/
-void SetSingleReqExts(void *object, CERTCertExtension **exts)
+void
+SetSingleReqExts(void *object, CERTCertExtension **exts)
{
- ocspSingleRequest *singleRequest =
- (ocspSingleRequest *)object;
+ ocspSingleRequest *singleRequest =
+ (ocspSingleRequest *)object;
- singleRequest->singleRequestExtensions = exts;
+ singleRequest->singleRequestExtensions = exts;
}
/*
@@ -1866,7 +1861,7 @@ void SetSingleReqExts(void *object, CERTCertExtension **exts)
*/
static SECStatus
ocsp_AddServiceLocatorExtension(ocspSingleRequest *singleRequest,
- CERTCertificate *cert)
+ CERTCertificate *cert)
{
ocspServiceLocator *serviceLocator = NULL;
void *extensionHandle = NULL;
@@ -1874,7 +1869,7 @@ ocsp_AddServiceLocatorExtension(ocspSingleRequest *singleRequest,
serviceLocator = PORT_ZNew(ocspServiceLocator);
if (serviceLocator == NULL)
- goto loser;
+ goto loser;
/*
* Normally it would be a bad idea to do a direct reference like
@@ -1886,10 +1881,10 @@ ocsp_AddServiceLocatorExtension(ocspSingleRequest *singleRequest,
serviceLocator->issuer = &cert->issuer;
rv = CERT_FindCertExtension(cert, SEC_OID_X509_AUTH_INFO_ACCESS,
- &serviceLocator->locator);
+ &serviceLocator->locator);
if (rv != SECSuccess) {
- if (PORT_GetError() != SEC_ERROR_EXTENSION_NOT_FOUND)
- goto loser;
+ if (PORT_GetError() != SEC_ERROR_EXTENSION_NOT_FOUND)
+ goto loser;
}
/* prepare for following loser gotos */
@@ -1897,33 +1892,33 @@ ocsp_AddServiceLocatorExtension(ocspSingleRequest *singleRequest,
PORT_SetError(0);
extensionHandle = cert_StartExtensions(singleRequest,
- singleRequest->arena, SetSingleReqExts);
+ singleRequest->arena, SetSingleReqExts);
if (extensionHandle == NULL)
- goto loser;
+ goto loser;
rv = CERT_EncodeAndAddExtension(extensionHandle,
- SEC_OID_PKIX_OCSP_SERVICE_LOCATOR,
- serviceLocator, PR_FALSE,
- ocsp_ServiceLocatorTemplate);
+ 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;
+ 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);
+ if (serviceLocator->locator.data != NULL)
+ SECITEM_FreeItem(&serviceLocator->locator, PR_FALSE);
+ PORT_Free(serviceLocator);
}
return rv;
@@ -1949,18 +1944,18 @@ ocsp_CreateSingleRequestList(PLArenaPool *arena, CERTCertList *certList,
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;
+ goto loser;
requestList = PORT_ArenaNewArray(arena, ocspSingleRequest *, count + 1);
if (requestList == NULL)
- goto loser;
+ goto loser;
node = CERT_LIST_HEAD(certList);
for (i = 0; !CERT_LIST_END(node, certList); i++) {
@@ -1998,7 +1993,7 @@ loser:
static ocspSingleRequest **
ocsp_CreateRequestFromCert(PLArenaPool *arena,
- CERTOCSPCertID *certID,
+ CERTOCSPCertID *certID,
CERTCertificate *singleCert,
PRTime time,
PRBool includeLocator)
@@ -2016,7 +2011,7 @@ ocsp_CreateRequestFromCert(PLArenaPool *arena,
goto loser;
requestList[0]->arena = arena;
/* certID will live longer than the request */
- requestList[0]->reqCert = certID;
+ requestList[0]->reqCert = certID;
if (includeLocator == PR_TRUE) {
SECStatus rv;
@@ -2067,8 +2062,8 @@ loser:
}
CERTOCSPRequest *
-cert_CreateSingleCertOCSPRequest(CERTOCSPCertID *certID,
- CERTCertificate *singleCert,
+cert_CreateSingleCertOCSPRequest(CERTOCSPCertID *certID,
+ CERTCertificate *singleCert,
PRTime time,
PRBool addServiceLocator,
CERTCertificate *signerCert)
@@ -2091,8 +2086,8 @@ cert_CreateSingleCertOCSPRequest(CERTOCSPCertID *certID,
* 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,
+ request->tbsRequest->requestList =
+ ocsp_CreateRequestFromCert(request->arena,
certID,
singleCert,
time,
@@ -2106,7 +2101,7 @@ cert_CreateSingleCertOCSPRequest(CERTOCSPCertID *certID,
/*
* FUNCTION: CERT_CreateOCSPRequest
- * Creates a CERTOCSPRequest, requesting the status of the certs in
+ * Creates a CERTOCSPRequest, requesting the status of the certs in
* the given list.
* INPUTS:
* CERTCertList *certList
@@ -2118,7 +2113,7 @@ cert_CreateSingleCertOCSPRequest(CERTOCSPCertID *certID,
* 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
+ * 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
@@ -2137,8 +2132,8 @@ cert_CreateSingleCertOCSPRequest(CERTOCSPCertID *certID,
*/
CERTOCSPRequest *
CERT_CreateOCSPRequest(CERTCertList *certList, PRTime time,
- PRBool addServiceLocator,
- CERTCertificate *signerCert)
+ PRBool addServiceLocator,
+ CERTCertificate *signerCert)
{
CERTOCSPRequest *request = NULL;
@@ -2147,7 +2142,7 @@ CERT_CreateOCSPRequest(CERTCertList *certList, PRTime time,
return NULL;
}
/*
- * XXX When we are prepared to put signing of requests back in,
+ * 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"
@@ -2163,8 +2158,8 @@ CERT_CreateOCSPRequest(CERTCertList *certList, PRTime time,
/*
* Now create the list of single requests, one for each cert.
*/
- request->tbsRequest->requestList =
- ocsp_CreateSingleRequestList(request->arena,
+ request->tbsRequest->requestList =
+ ocsp_CreateSingleRequestList(request->arena,
certList,
time,
addServiceLocator);
@@ -2192,16 +2187,21 @@ CERT_CreateOCSPRequest(CERTCertList *certList, PRTime time,
* All errors are internal or low-level problems (e.g. no memory).
*/
-void SetRequestExts(void *object, CERTCertExtension **exts)
+void
+SetRequestExts(void *object, CERTCertExtension **exts)
{
- CERTOCSPRequest *request = (CERTOCSPRequest *)object;
+ CERTOCSPRequest *request = (CERTOCSPRequest *)object;
- request->tbsRequest->requestExtensions = exts;
+ request->tbsRequest->requestExtensions = exts;
}
+#if defined(__GNUC__)
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wvarargs"
+#endif
SECStatus
CERT_AddOCSPAcceptableResponses(CERTOCSPRequest *request,
- SECOidTag responseType0, ...)
+ SECOidTag responseType0, ...)
{
void *extHandle;
va_list ap;
@@ -2213,59 +2213,61 @@ CERT_AddOCSPAcceptableResponses(CERTOCSPRequest *request,
extHandle = request->tbsRequest->extensionHandle;
if (extHandle == NULL) {
- extHandle = cert_StartExtensions(request, request->arena, SetRequestExts);
- if (extHandle == NULL)
- goto loser;
+ 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);
+ 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;
+ 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);
+ 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));
+ &acceptableResponses, PR_FALSE,
+ SEC_ASN1_GET(SEC_SequenceOfObjectIDTemplate));
if (rv != SECSuccess)
- goto loser;
+ goto loser;
PORT_Free(acceptableResponses);
if (request->tbsRequest->extensionHandle == NULL)
- request->tbsRequest->extensionHandle = extHandle;
+ request->tbsRequest->extensionHandle = extHandle;
return SECSuccess;
loser:
if (acceptableResponses != NULL)
- PORT_Free(acceptableResponses);
+ PORT_Free(acceptableResponses);
if (extHandle != NULL)
- (void) CERT_FinishExtensions(extHandle);
+ (void)CERT_FinishExtensions(extHandle);
return rv;
}
-
+#if defined(__GNUC__)
+#pragma GCC diagnostic pop
+#endif
/*
* FUNCTION: CERT_DestroyOCSPRequest
@@ -2280,20 +2282,20 @@ void
CERT_DestroyOCSPRequest(CERTOCSPRequest *request)
{
if (request == NULL)
- return;
+ 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->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);
+ 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
@@ -2308,10 +2310,9 @@ CERT_DestroyOCSPRequest(CERTOCSPRequest *request)
*/
PORT_Assert(request->arena != NULL);
if (request->arena != NULL)
- PORT_FreeArena(request->arena, PR_FALSE);
+ PORT_FreeArena(request->arena, PR_FALSE);
}
-
/*
* RESPONSE SUPPORT FUNCTIONS (encode/create/decode/destroy):
*/
@@ -2326,17 +2327,17 @@ 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;
+ 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;
@@ -2352,20 +2353,20 @@ 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;
+ 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;
@@ -2381,18 +2382,18 @@ 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;
+ 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;
@@ -2407,7 +2408,7 @@ ocsp_CertStatusTypeByTag(int derTag)
*/
static SECStatus
ocsp_FinishDecodingSingleResponses(PLArenaPool *reqArena,
- CERTOCSPSingleResponse **responses)
+ CERTOCSPSingleResponse **responses)
{
ocspCertStatus *certStatus;
ocspCertStatusType certStatusType;
@@ -2421,39 +2422,39 @@ ocsp_FinishDecodingSingleResponses(PLArenaPool *reqArena,
return SECFailure;
}
- if (responses == NULL) /* nothing to do */
- return SECSuccess;
+ if (responses == NULL) /* nothing to do */
+ return SECSuccess;
for (i = 0; responses[i] != NULL; i++) {
- SECItem* newStatus;
- /*
+ 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);
+ 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);
+ 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;
- }
+ 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;
- }
+ 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;
+ certStatus->certStatusType = certStatusType;
+ responses[i]->certStatus = certStatus;
}
return SECSuccess;
@@ -2472,15 +2473,15 @@ 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;
+ case 1:
+ responderIDType = ocspResponderID_byName;
+ break;
+ case 2:
+ responderIDType = ocspResponderID_byKey;
+ break;
+ default:
+ responderIDType = ocspResponderID_other;
+ break;
}
return responderIDType;
@@ -2506,22 +2507,22 @@ ocsp_DecodeBasicOCSPResponse(PLArenaPool *arena, SECItem *src)
basicResponse = PORT_ArenaZAlloc(arena, sizeof(ocspBasicOCSPResponse));
if (basicResponse == NULL) {
- goto loser;
+ 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;
+ if (rv != SECSuccess) {
+ goto loser;
}
rv = SEC_QuickDERDecodeItem(arena, basicResponse,
- ocsp_BasicOCSPResponseTemplate, &newsrc);
+ ocsp_BasicOCSPResponseTemplate, &newsrc);
if (rv != SECSuccess) {
- if (PORT_GetError() == SEC_ERROR_BAD_DER)
- PORT_SetError(SEC_ERROR_OCSP_MALFORMED_RESPONSE);
- goto loser;
+ if (PORT_GetError() == SEC_ERROR_BAD_DER)
+ PORT_SetError(SEC_ERROR_OCSP_MALFORMED_RESPONSE);
+ goto loser;
}
responseData = basicResponse->tbsResponseData;
@@ -2543,15 +2544,15 @@ ocsp_DecodeBasicOCSPResponse(PLArenaPool *arena, SECItem *src)
responderID = PORT_ArenaZAlloc(arena, sizeof(ocspResponderID));
if (responderID == NULL) {
- goto loser;
+ goto loser;
}
rv = SEC_QuickDERDecodeItem(arena, responderID, responderIDTemplate,
- &responseData->derResponderID);
+ &responseData->derResponderID);
if (rv != SECSuccess) {
- if (PORT_GetError() == SEC_ERROR_BAD_DER)
- PORT_SetError(SEC_ERROR_OCSP_MALFORMED_RESPONSE);
- goto loser;
+ if (PORT_GetError() == SEC_ERROR_BAD_DER)
+ PORT_SetError(SEC_ERROR_OCSP_MALFORMED_RESPONSE);
+ goto loser;
}
responderID->responderIDType = responderIDType;
@@ -2563,7 +2564,7 @@ ocsp_DecodeBasicOCSPResponse(PLArenaPool *arena, SECItem *src)
*/
rv = ocsp_FinishDecodingSingleResponses(arena, responseData->responses);
if (rv != SECSuccess) {
- goto loser;
+ goto loser;
}
PORT_ArenaUnmark(arena, mark);
@@ -2574,7 +2575,6 @@ loser:
return NULL;
}
-
/*
* Decode the responseBytes based on the responseType found in "rbytes",
* leaving the resulting translated/decoded information in there as well.
@@ -2583,38 +2583,35 @@ static SECStatus
ocsp_DecodeResponseBytes(PLArenaPool *arena, ocspResponseBytes *rbytes)
{
if (rbytes == NULL) {
- PORT_SetError(SEC_ERROR_OCSP_UNKNOWN_RESPONSE_TYPE);
- return SECFailure;
+ PORT_SetError(SEC_ERROR_OCSP_UNKNOWN_RESPONSE_TYPE);
+ return SECFailure;
}
rbytes->responseTypeTag = SECOID_FindOIDTag(&rbytes->responseType);
switch (rbytes->responseTypeTag) {
- case SEC_OID_PKIX_OCSP_BASIC_RESPONSE:
- {
- ocspBasicOCSPResponse *basicResponse;
+ case SEC_OID_PKIX_OCSP_BASIC_RESPONSE: {
+ ocspBasicOCSPResponse *basicResponse;
- basicResponse = ocsp_DecodeBasicOCSPResponse(arena,
- &rbytes->response);
- if (basicResponse == NULL)
- return SECFailure;
+ basicResponse = ocsp_DecodeBasicOCSPResponse(arena,
+ &rbytes->response);
+ if (basicResponse == NULL)
+ return SECFailure;
- rbytes->decodedResponse.basic = basicResponse;
- }
- break;
+ rbytes->decodedResponse.basic = basicResponse;
+ } break;
- /*
+ /*
* Add new/future response types here.
*/
- default:
- PORT_SetError(SEC_ERROR_OCSP_UNKNOWN_RESPONSE_TYPE);
- return SECFailure;
+ default:
+ PORT_SetError(SEC_ERROR_OCSP_UNKNOWN_RESPONSE_TYPE);
+ return SECFailure;
}
return SECSuccess;
}
-
/*
* FUNCTION: CERT_DecodeOCSPResponse
* Decode a DER encoded OCSP Response.
@@ -2639,37 +2636,37 @@ CERT_DecodeOCSPResponse(const SECItem *src)
arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
if (arena == NULL) {
- goto loser;
+ goto loser;
}
- response = (CERTOCSPResponse *) PORT_ArenaZAlloc(arena,
- sizeof(CERTOCSPResponse));
+ response = (CERTOCSPResponse *)PORT_ArenaZAlloc(arena,
+ sizeof(CERTOCSPResponse));
if (response == NULL) {
- goto loser;
+ 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;
+ 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;
+ if (PORT_GetError() == SEC_ERROR_BAD_DER)
+ PORT_SetError(SEC_ERROR_OCSP_MALFORMED_RESPONSE);
+ goto loser;
}
- sv = (ocspResponseStatus) DER_GetInteger(&response->responseStatus);
+ 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;
+ return response;
}
/*
@@ -2678,14 +2675,14 @@ CERT_DecodeOCSPResponse(const SECItem *src)
*/
rv = ocsp_DecodeResponseBytes(arena, response->responseBytes);
if (rv != SECSuccess) {
- goto loser;
+ goto loser;
}
return response;
loser:
if (arena != NULL) {
- PORT_FreeArena(arena, PR_FALSE);
+ PORT_FreeArena(arena, PR_FALSE);
}
return NULL;
}
@@ -2711,7 +2708,7 @@ loser:
*
* FUNCTION: ocsp_GetResponseData
* Returns ocspResponseData structure and a pointer to tbs response
- * data DER from a valid ocsp response.
+ * data DER from a valid ocsp response.
* INPUTS:
* CERTOCSPResponse *response
* structure of a valid ocsp response
@@ -2729,8 +2726,8 @@ ocsp_GetResponseData(CERTOCSPResponse *response, SECItem **tbsResponseDataDER)
PORT_Assert(response->responseBytes != NULL);
- PORT_Assert(response->responseBytes->responseTypeTag
- == SEC_OID_PKIX_OCSP_BASIC_RESPONSE);
+ PORT_Assert(response->responseBytes->responseTypeTag ==
+ SEC_OID_PKIX_OCSP_BASIC_RESPONSE);
basic = response->responseBytes->decodedResponse.basic;
PORT_Assert(basic != NULL);
@@ -2761,8 +2758,8 @@ ocsp_GetResponseSignature(CERTOCSPResponse *response)
if (NULL == response->responseBytes) {
return NULL;
}
- if (response->responseBytes->responseTypeTag
- != SEC_OID_PKIX_OCSP_BASIC_RESPONSE) {
+ if (response->responseBytes->responseTypeTag !=
+ SEC_OID_PKIX_OCSP_BASIC_RESPONSE) {
return NULL;
}
basic = response->responseBytes->decodedResponse.basic;
@@ -2771,7 +2768,6 @@ ocsp_GetResponseSignature(CERTOCSPResponse *response)
return &(basic->responseSignature);
}
-
/*
* FUNCTION: CERT_DestroyOCSPResponse
* Frees an OCSP Response structure.
@@ -2785,28 +2781,26 @@ void
CERT_DestroyOCSPResponse(CERTOCSPResponse *response)
{
if (response != NULL) {
- ocspSignature *signature = ocsp_GetResponseSignature(response);
- if (signature && signature->cert != NULL)
- CERT_DestroyCertificate(signature->cert);
+ 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);
- }
+ 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.
*
@@ -2822,7 +2816,7 @@ CERT_DestroyOCSPResponse(CERTOCSPResponse *response)
static SECStatus
ocsp_ParseURL(const char *url, char **pHostname, PRUint16 *pPort, char **pPath)
{
- unsigned short port = 80; /* default, in case not in url */
+ unsigned short port = 80; /* default, in case not in url */
char *hostname = NULL;
char *path = NULL;
const char *save;
@@ -2830,25 +2824,25 @@ ocsp_ParseURL(const char *url, char **pHostname, PRUint16 *pPort, char **pPath)
int len;
if (url == NULL)
- goto loser;
+ goto loser;
/*
* Skip beginning whitespace.
*/
c = *url;
while ((c == ' ' || c == '\t') && c != '\0') {
- url++;
- c = *url;
+ url++;
+ c = *url;
}
if (c == '\0')
- goto loser;
+ 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;
+ goto loser;
url += 7;
/*
@@ -2866,13 +2860,13 @@ ocsp_ParseURL(const char *url, char **pHostname, PRUint16 *pPort, char **pPath)
save = url;
c = *url;
while (c != '/' && c != ':' && c != '\0' && c != ' ' && c != '\t') {
- url++;
- c = *url;
+ url++;
+ c = *url;
}
len = url - save;
hostname = PORT_Alloc(len + 1);
if (hostname == NULL)
- goto loser;
+ goto loser;
PORT_Memcpy(hostname, save, len);
hostname[len] = '\0';
@@ -2881,15 +2875,15 @@ ocsp_ParseURL(const char *url, char **pHostname, PRUint16 *pPort, char **pPath)
* 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;
- }
+ 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;
+ }
}
/*
@@ -2897,21 +2891,21 @@ ocsp_ParseURL(const char *url, char **pHostname, PRUint16 *pPort, char **pPath)
* 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';
+ 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;
+ path = PORT_Strdup("/");
+ if (path == NULL)
+ goto loser;
}
*pHostname = hostname;
@@ -2921,7 +2915,7 @@ ocsp_ParseURL(const char *url, char **pHostname, PRUint16 *pPort, char **pPath)
loser:
if (hostname != NULL)
- PORT_Free(hostname);
+ PORT_Free(hostname);
PORT_SetError(SEC_ERROR_CERT_BAD_ACCESS_LOCATION);
return SECFailure;
}
@@ -2940,7 +2934,7 @@ ocsp_ConnectToHost(const char *host, PRUint16 port)
sock = PR_NewTCPSocket();
if (sock == NULL)
- goto loser;
+ goto loser;
/* XXX Some day need a way to set (and get?) the following value */
timeout = PR_SecondsToInterval(30);
@@ -2954,42 +2948,42 @@ ocsp_ConnectToHost(const char *host, PRUint16 port)
* valid numerical IP address from a hostname.
*/
if (PR_StringToNetAddr(host, &addr) != PR_SUCCESS) {
- PRIntn hostIndex;
- PRHostEnt hostEntry;
+ PRIntn hostIndex;
+ PRHostEnt hostEntry;
- netdbbuf = PORT_Alloc(PR_NETDB_BUF_SIZE);
- if (netdbbuf == NULL)
- goto loser;
+ 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;
+ 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);
+ 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);
+ 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;
+ 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);
+ PR_Close(sock);
if (netdbbuf != NULL)
- PORT_Free(netdbbuf);
+ PORT_Free(netdbbuf);
return NULL;
}
@@ -3024,14 +3018,14 @@ ocsp_SendEncodedRequest(const char *location, const SECItem *encodedRequest)
*/
rv = ocsp_ParseURL(location, &hostname, &port, &path);
if (rv != SECSuccess)
- goto loser;
+ goto loser;
PORT_Assert(hostname != NULL);
PORT_Assert(path != NULL);
sock = ocsp_ConnectToHost(hostname, port);
if (sock == NULL)
- goto loser;
+ goto loser;
portstr[0] = '\0';
if (port != 80) {
@@ -3039,38 +3033,37 @@ ocsp_SendEncodedRequest(const char *location, const SECItem *encodedRequest)
}
if (!encodedRequest) {
- header = PR_smprintf("GET %s HTTP/1.0\r\n"
- "Host: %s%s\r\n\r\n",
- path, hostname, portstr);
- 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;
- }
- else {
- 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;
+ header = PR_smprintf("GET %s HTTP/1.0\r\n"
+ "Host: %s%s\r\n\r\n",
+ path, hostname, portstr);
+ 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;
+ } else {
+ 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;
@@ -3078,13 +3071,13 @@ ocsp_SendEncodedRequest(const char *location, const SECItem *encodedRequest)
loser:
if (header != NULL)
- PORT_Free(header);
+ PORT_Free(header);
if (sock != NULL)
- PR_Close(sock);
+ PR_Close(sock);
if (path != NULL)
- PORT_Free(path);
+ PORT_Free(path);
if (hostname != NULL)
- PORT_Free(hostname);
+ PORT_Free(hostname);
return returnSock;
}
@@ -3099,22 +3092,16 @@ ocsp_read(PRFileDesc *fd, char *buf, int toread, PRIntervalTime timeout)
{
int total = 0;
- while (total < toread)
- {
+ while (total < toread) {
PRInt32 got;
- got = PR_Recv(fd, buf + total, (PRInt32) (toread - total), 0, timeout);
- if (got < 0)
- {
- if (0 == total)
- {
+ 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 */
+ } else if (got == 0) { /* EOS */
break;
}
@@ -3126,14 +3113,13 @@ ocsp_read(PRFileDesc *fd, char *buf, int toread, PRIntervalTime timeout)
#define OCSP_BUFSIZE 1024
-#define AbortHttpDecode(error) \
-{ \
- if (inBuffer) \
+#define AbortHttpDecode(error) \
+ { \
+ if (inBuffer) \
PORT_Free(inBuffer); \
- PORT_SetError(error); \
- return NULL; \
-}
-
+ PORT_SetError(error); \
+ return NULL; \
+ }
/*
* Reads on the given socket and returns an encoded response when received.
@@ -3148,92 +3134,81 @@ ocsp_GetEncodedResponse(PLArenaPool *arena, PRFileDesc *sock)
{
/* first read HTTP status line and headers */
- char* inBuffer = NULL;
+ 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 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 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;
+ char *headerEnd = NULL;
PRBool EOS = PR_FALSE;
- const char* httpprotocol = "HTTP/";
+ const char *httpprotocol = "HTTP/";
const PRInt32 httplen = strlen(httpprotocol);
- const char* httpcode = NULL;
- const char* contenttype = NULL;
+ 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;
+ char *statusLineEnd = NULL;
+ char *space = NULL;
+ char *nextHeader = NULL;
+ SECItem *result = NULL;
/* read up to at least the end of the HTTP headers */
- do
- {
+ do {
inBufsize += bufSizeIncrement;
- inBuffer = PORT_Realloc(inBuffer, inBufsize+1);
- if (NULL == inBuffer)
- {
+ 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;
+ 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)
- {
+ 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
- {
+ } else {
/* recv error or EOS */
EOS = PR_TRUE;
}
- } while ( (!headerEnd) && (PR_FALSE == EOS) &&
- (inBufsize < maxBufSize) );
+ } while ((!headerEnd) && (PR_FALSE == EOS) &&
+ (inBufsize < maxBufSize));
- if (!headerEnd)
- {
+ if (!headerEnd) {
AbortHttpDecode(SEC_ERROR_OCSP_BAD_HTTP_RESPONSE);
}
/* parse the HTTP status line */
- statusLineEnd = strstr((const char*)inBuffer, CRLF);
- if (!statusLineEnd)
- {
+ 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 )
- {
+ 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;
+ httpcode = space + 1;
space = strchr(httpcode, ' ');
- if (!space)
- {
+ if (!space) {
AbortHttpDecode(SEC_ERROR_OCSP_BAD_HTTP_RESPONSE);
}
*space = 0;
- if (0 != strcmp(httpcode, "200"))
- {
+ if (0 != strcmp(httpcode, "200")) {
AbortHttpDecode(SEC_ERROR_OCSP_BAD_HTTP_RESPONSE);
}
@@ -3243,14 +3218,12 @@ ocsp_GetEncodedResponse(PLArenaPool *arena, PRFileDesc *sock)
nextHeader = statusLineEnd + CRLFlen;
*headerEnd = '\0'; /* terminate */
- do
- {
- char* thisHeaderEnd = NULL;
- char* value = NULL;
- char* colon = strchr(nextHeader, ':');
-
- if (!colon)
- {
+ do {
+ char *thisHeaderEnd = NULL;
+ char *value = NULL;
+ char *colon = strchr(nextHeader, ':');
+
+ if (!colon) {
AbortHttpDecode(SEC_ERROR_OCSP_BAD_HTTP_RESPONSE);
}
@@ -3263,90 +3236,71 @@ ocsp_GetEncodedResponse(PLArenaPool *arena, PRFileDesc *sock)
and should not be an issue, but it could become one in the
future */
- if (*value != ' ')
- {
+ if (*value != ' ') {
AbortHttpDecode(SEC_ERROR_OCSP_BAD_HTTP_RESPONSE);
}
value++;
- thisHeaderEnd = strstr(value, CRLF);
- if (thisHeaderEnd )
- {
- *thisHeaderEnd = '\0';
+ thisHeaderEnd = strstr(value, CRLF);
+ if (thisHeaderEnd) {
+ *thisHeaderEnd = '\0';
}
- if (0 == PORT_Strcasecmp(nextHeader, "content-type"))
- {
+ if (0 == PORT_Strcasecmp(nextHeader, "content-type")) {
contenttype = value;
- }
- else
- if (0 == PORT_Strcasecmp(nextHeader, "content-length"))
- {
+ } else if (0 == PORT_Strcasecmp(nextHeader, "content-length")) {
contentlength = atoi(value);
}
- if (thisHeaderEnd )
- {
+ if (thisHeaderEnd) {
nextHeader = thisHeaderEnd + CRLFlen;
- }
- else
- {
+ } else {
nextHeader = NULL;
}
- } while (nextHeader && (nextHeader < (headerEnd + CRLFlen) ) );
+ } while (nextHeader && (nextHeader < (headerEnd + CRLFlen)));
/* check content-type */
if (!contenttype ||
- (0 != PORT_Strcasecmp(contenttype, "application/ocsp-response")) )
- {
+ (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)
- {
+ 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 ;
+ inBufsize = (1 + (offset - 1) / bufSizeIncrement) * bufSizeIncrement;
- while ( (PR_FALSE == EOS) &&
- ( (contentlength == 0) || (offset < contentlength) ) &&
- (inBufsize < maxBufSize)
- )
- {
+ 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)
- {
+ 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)
- {
+ if (bytesRead > 0) {
offset += bytesRead;
- if (bytesRead < bufSizeIncrement)
- {
+ if (bytesRead < bufSizeIncrement) {
/* we read less data than requested, therefore we are at
EOS or there was a read error */
EOS = PR_TRUE;
}
- }
- else
- {
+ } else {
/* recv error or EOS */
EOS = PR_TRUE;
}
}
- if (0 == offset)
- {
+ if (0 == offset) {
AbortHttpDecode(SEC_ERROR_OCSP_BAD_HTTP_RESPONSE);
}
@@ -3354,14 +3308,13 @@ ocsp_GetEncodedResponse(PLArenaPool *arena, PRFileDesc *sock)
* Now allocate the item to hold the data.
*/
result = SECITEM_AllocItem(arena, NULL, offset);
- if (NULL == result)
- {
+ 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 */
@@ -3378,7 +3331,7 @@ CERT_ParseURL(const char *url, char **pHostname, PRUint16 *pPort, char **pPath)
/*
* Limit the size of http responses we are willing to accept.
*/
-#define MAX_WANTED_OCSP_RESPONSE_LEN 64*1024
+#define MAX_WANTED_OCSP_RESPONSE_LEN 64 * 1024
/* if (encodedRequest == NULL)
* then location MUST already include the full request,
@@ -3388,9 +3341,9 @@ CERT_ParseURL(const char *url, char **pHostname, PRUint16 *pPort, char **pPath)
* then the request will be sent with POST
*/
static SECItem *
-fetchOcspHttpClientV1(PLArenaPool *arena,
- const SEC_HttpClientFcnV1 *hcv1,
- const char *location,
+fetchOcspHttpClientV1(PLArenaPool *arena,
+ const SEC_HttpClientFcnV1 *hcv1,
+ const char *location,
const SECItem *encodedRequest)
{
char *hostname = NULL;
@@ -3407,13 +3360,13 @@ fetchOcspHttpClientV1(PLArenaPool *arena,
PORT_SetError(SEC_ERROR_OCSP_MALFORMED_REQUEST);
goto loser;
}
-
+
PORT_Assert(hostname != NULL);
PORT_Assert(path != NULL);
if ((*hcv1->createSessionFcn)(
- hostname,
- port,
+ hostname,
+ port,
&pServerSession) != SECSuccess) {
PORT_SetError(SEC_ERROR_OCSP_SERVER_ERROR);
goto loser;
@@ -3439,8 +3392,8 @@ fetchOcspHttpClientV1(PLArenaPool *arena,
if (encodedRequest &&
(*hcv1->setPostDataFcn)(
- pRequestSession,
- (char*)encodedRequest->data,
+ pRequestSession,
+ (char *)encodedRequest->data,
encodedRequest->len,
"application/ocsp-request") != SECSuccess) {
PORT_SetError(SEC_ERROR_OCSP_SERVER_ERROR);
@@ -3453,7 +3406,7 @@ fetchOcspHttpClientV1(PLArenaPool *arena,
OCSP_TRACE(("OCSP trySendAndReceive %s\n", location));
if ((*hcv1->trySendAndReceiveFcn)(
- pRequestSession,
+ pRequestSession,
NULL,
&myHttpResponseCode,
NULL,
@@ -3481,15 +3434,15 @@ fetchOcspHttpClientV1(PLArenaPool *arena,
PORT_Memcpy(encodedResponse->data, myHttpResponseData, myHttpResponseDataLen);
loser:
- if (pRequestSession != NULL)
+ if (pRequestSession != NULL)
(*hcv1->freeFcn)(pRequestSession);
if (pServerSession != NULL)
(*hcv1->freeSessionFcn)(pServerSession);
if (path != NULL)
- PORT_Free(path);
+ PORT_Free(path);
if (hostname != NULL)
- PORT_Free(hostname);
-
+ PORT_Free(hostname);
+
return encodedResponse;
}
@@ -3518,7 +3471,7 @@ loser:
* Additionals methods for http or other protocols might be added
* in the future.
* PRTime time
- * Indicates the time for which the certificate status is to be
+ * 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
@@ -3546,10 +3499,10 @@ loser:
*/
SECItem *
CERT_GetEncodedOCSPResponseByMethod(PLArenaPool *arena, CERTCertList *certList,
- const char *location, const char *method,
- PRTime time, PRBool addServiceLocator,
- CERTCertificate *signerCert, void *pwArg,
- CERTOCSPRequest **pRequest)
+ const char *location, const char *method,
+ PRTime time, PRBool addServiceLocator,
+ CERTCertificate *signerCert, void *pwArg,
+ CERTOCSPRequest **pRequest)
{
CERTOCSPRequest *request;
request = CERT_CreateOCSPRequest(certList, time, addServiceLocator,
@@ -3571,25 +3524,25 @@ CERT_GetEncodedOCSPResponseByMethod(PLArenaPool *arena, CERTCertList *certList,
*/
SECItem *
CERT_GetEncodedOCSPResponse(PLArenaPool *arena, CERTCertList *certList,
- const char *location, PRTime time,
- PRBool addServiceLocator,
- CERTCertificate *signerCert, void *pwArg,
- CERTOCSPRequest **pRequest)
+ const char *location, PRTime time,
+ PRBool addServiceLocator,
+ CERTCertificate *signerCert, void *pwArg,
+ CERTOCSPRequest **pRequest)
{
return CERT_GetEncodedOCSPResponseByMethod(arena, certList, location,
- "POST", time, addServiceLocator,
- signerCert, pwArg, pRequest);
+ "POST", time, addServiceLocator,
+ signerCert, pwArg, pRequest);
}
/* URL encode a buffer that consists of base64-characters, only,
* which means we can use a simple encoding logic.
- *
+ *
* No output buffer size checking is performed.
* You should call the function twice, to calculate the required buffer size.
- *
- * If the outpufBuf parameter is NULL, the function will calculate the
+ *
+ * If the outpufBuf parameter is NULL, the function will calculate the
* required size, including the trailing zero termination char.
- *
+ *
* The function returns the number of bytes calculated or produced.
*/
size_t
@@ -3598,44 +3551,44 @@ ocsp_UrlEncodeBase64Buf(const char *base64Buf, char *outputBuf)
const char *walkInput = NULL;
char *walkOutput = outputBuf;
size_t count = 0;
-
- for (walkInput=base64Buf; *walkInput; ++walkInput) {
- char c = *walkInput;
- if (isspace(c))
- continue;
- switch (c) {
- case '+':
- if (outputBuf) {
- strcpy(walkOutput, "%2B");
- walkOutput += 3;
- }
- count += 3;
- break;
- case '/':
- if (outputBuf) {
- strcpy(walkOutput, "%2F");
- walkOutput += 3;
- }
- count += 3;
- break;
- case '=':
- if (outputBuf) {
- strcpy(walkOutput, "%3D");
- walkOutput += 3;
- }
- count += 3;
- break;
- default:
- if (outputBuf) {
- *walkOutput = *walkInput;
- ++walkOutput;
- }
- ++count;
- break;
- }
+
+ for (walkInput = base64Buf; *walkInput; ++walkInput) {
+ char c = *walkInput;
+ if (isspace(c))
+ continue;
+ switch (c) {
+ case '+':
+ if (outputBuf) {
+ strcpy(walkOutput, "%2B");
+ walkOutput += 3;
+ }
+ count += 3;
+ break;
+ case '/':
+ if (outputBuf) {
+ strcpy(walkOutput, "%2F");
+ walkOutput += 3;
+ }
+ count += 3;
+ break;
+ case '=':
+ if (outputBuf) {
+ strcpy(walkOutput, "%3D");
+ walkOutput += 3;
+ }
+ count += 3;
+ break;
+ default:
+ if (outputBuf) {
+ *walkOutput = *walkInput;
+ ++walkOutput;
+ }
+ ++count;
+ break;
+ }
}
if (outputBuf) {
- *walkOutput = 0;
+ *walkOutput = 0;
}
++count;
return count;
@@ -3644,15 +3597,15 @@ ocsp_UrlEncodeBase64Buf(const char *base64Buf, char *outputBuf)
enum { max_get_request_size = 255 }; /* defined by RFC2560 */
static SECItem *
-cert_GetOCSPResponse(PLArenaPool *arena, const char *location,
+cert_GetOCSPResponse(PLArenaPool *arena, const char *location,
const SECItem *encodedRequest);
static SECItem *
ocsp_GetEncodedOCSPResponseFromRequest(PLArenaPool *arena,
CERTOCSPRequest *request,
const char *location,
- const char *method,
- PRTime time,
+ const char *method,
+ PRTime time,
PRBool addServiceLocator,
void *pwArg,
CERTOCSPRequest **pRequest)
@@ -3665,44 +3618,42 @@ ocsp_GetEncodedOCSPResponseFromRequest(PLArenaPool *arena,
goto loser;
rv = CERT_AddOCSPAcceptableResponses(request,
- SEC_OID_PKIX_OCSP_BASIC_RESPONSE);
+ SEC_OID_PKIX_OCSP_BASIC_RESPONSE);
if (rv != SECSuccess)
- goto loser;
+ goto loser;
encodedRequest = CERT_EncodeOCSPRequest(NULL, request, pwArg);
if (encodedRequest == NULL)
- goto loser;
+ goto loser;
if (!strcmp(method, "GET")) {
encodedResponse = cert_GetOCSPResponse(arena, location, encodedRequest);
- }
- else if (!strcmp(method, "POST")) {
+ } else if (!strcmp(method, "POST")) {
encodedResponse = CERT_PostOCSPRequest(arena, location, encodedRequest);
- }
- else {
- goto loser;
+ } else {
+ goto loser;
}
if (encodedResponse != NULL && pRequest != NULL) {
- *pRequest = request;
- request = NULL; /* avoid destroying below */
+ *pRequest = request;
+ request = NULL; /* avoid destroying below */
}
loser:
if (request != NULL)
- CERT_DestroyOCSPRequest(request);
+ CERT_DestroyOCSPRequest(request);
if (encodedRequest != NULL)
- SECITEM_FreeItem(encodedRequest, PR_TRUE);
+ SECITEM_FreeItem(encodedRequest, PR_TRUE);
return encodedResponse;
}
static SECItem *
-cert_FetchOCSPResponse(PLArenaPool *arena, const char *location,
+cert_FetchOCSPResponse(PLArenaPool *arena, const char *location,
const SECItem *encodedRequest);
/* using HTTP GET method */
static SECItem *
-cert_GetOCSPResponse(PLArenaPool *arena, const char *location,
+cert_GetOCSPResponse(PLArenaPool *arena, const char *location,
const SECItem *encodedRequest)
{
char *walkOutput = NULL;
@@ -3710,49 +3661,49 @@ cert_GetOCSPResponse(PLArenaPool *arena, const char *location,
size_t pathLength;
PRInt32 urlEncodedBufLength;
size_t base64size;
- char b64ReqBuf[max_get_request_size+1];
+ char b64ReqBuf[max_get_request_size + 1];
size_t slashLengthIfNeeded = 0;
size_t getURLLength;
SECItem *item;
if (!location || !*location) {
- return NULL;
+ return NULL;
}
-
+
pathLength = strlen(location);
- if (location[pathLength-1] != '/') {
- slashLengthIfNeeded = 1;
+ if (location[pathLength - 1] != '/') {
+ slashLengthIfNeeded = 1;
}
-
+
/* Calculation as documented by PL_Base64Encode function.
* Use integer conversion to avoid having to use function ceil().
*/
- base64size = (((encodedRequest->len +2)/3) * 4);
+ base64size = (((encodedRequest->len + 2) / 3) * 4);
if (base64size > max_get_request_size) {
- return NULL;
+ return NULL;
}
memset(b64ReqBuf, 0, sizeof(b64ReqBuf));
- PL_Base64Encode((const char*)encodedRequest->data, encodedRequest->len,
- b64ReqBuf);
+ PL_Base64Encode((const char *)encodedRequest->data, encodedRequest->len,
+ b64ReqBuf);
urlEncodedBufLength = ocsp_UrlEncodeBase64Buf(b64ReqBuf, NULL);
getURLLength = pathLength + urlEncodedBufLength + slashLengthIfNeeded;
-
+
/* urlEncodedBufLength already contains room for the zero terminator.
* Add another if we must add the '/' char.
*/
if (arena) {
- fullGetPath = (char*)PORT_ArenaAlloc(arena, getURLLength);
+ fullGetPath = (char *)PORT_ArenaAlloc(arena, getURLLength);
} else {
- fullGetPath = (char*)PORT_Alloc(getURLLength);
+ fullGetPath = (char *)PORT_Alloc(getURLLength);
}
if (!fullGetPath) {
- return NULL;
+ return NULL;
}
-
+
strcpy(fullGetPath, location);
walkOutput = fullGetPath + pathLength;
-
+
if (walkOutput > fullGetPath && slashLengthIfNeeded) {
strcpy(walkOutput, "/");
++walkOutput;
@@ -3761,20 +3712,20 @@ cert_GetOCSPResponse(PLArenaPool *arena, const char *location,
item = cert_FetchOCSPResponse(arena, fullGetPath, NULL);
if (!arena) {
- PORT_Free(fullGetPath);
+ PORT_Free(fullGetPath);
}
return item;
}
SECItem *
-CERT_PostOCSPRequest(PLArenaPool *arena, const char *location,
+CERT_PostOCSPRequest(PLArenaPool *arena, const char *location,
const SECItem *encodedRequest)
{
return cert_FetchOCSPResponse(arena, location, encodedRequest);
}
SECItem *
-cert_FetchOCSPResponse(PLArenaPool *arena, const char *location,
+cert_FetchOCSPResponse(PLArenaPool *arena, const char *location,
const SECItem *encodedRequest)
{
const SEC_HttpClientFcn *registeredHttpClient;
@@ -3784,10 +3735,10 @@ cert_FetchOCSPResponse(PLArenaPool *arena, const char *location,
if (registeredHttpClient && registeredHttpClient->version == 1) {
encodedResponse = fetchOcspHttpClientV1(
- arena,
- &registeredHttpClient->fcnTable.ftable1,
- location,
- encodedRequest);
+ arena,
+ &registeredHttpClient->fcnTable.ftable1,
+ location,
+ encodedRequest);
} else {
/* use internal http client */
PRFileDesc *sock = ocsp_SendEncodedRequest(location, encodedRequest);
@@ -3801,18 +3752,18 @@ cert_FetchOCSPResponse(PLArenaPool *arena, const char *location,
}
static SECItem *
-ocsp_GetEncodedOCSPResponseForSingleCert(PLArenaPool *arena,
- CERTOCSPCertID *certID,
- CERTCertificate *singleCert,
+ocsp_GetEncodedOCSPResponseForSingleCert(PLArenaPool *arena,
+ CERTOCSPCertID *certID,
+ CERTCertificate *singleCert,
const char *location,
- const char *method,
- PRTime time,
+ const char *method,
+ PRTime time,
PRBool addServiceLocator,
void *pwArg,
CERTOCSPRequest **pRequest)
{
CERTOCSPRequest *request;
- request = cert_CreateSingleCertOCSPRequest(certID, singleCert, time,
+ request = cert_CreateSingleCertOCSPRequest(certID, singleCert, time,
addServiceLocator, NULL);
if (!request)
return NULL;
@@ -3833,29 +3784,28 @@ ocsp_CertIsOCSPDesignatedResponder(CERTCertificate *cert)
PRBool retval;
CERTOidSequence *oidSeq = NULL;
-
extItem.data = NULL;
rv = CERT_FindCertExtension(cert, SEC_OID_X509_EXT_KEY_USAGE, &extItem);
- if ( rv != SECSuccess ) {
- goto loser;
+ if (rv != SECSuccess) {
+ goto loser;
}
oidSeq = CERT_DecodeOidSequence(&extItem);
- if ( oidSeq == NULL ) {
- goto loser;
+ 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++;
+ while (*oids != NULL) {
+ oid = *oids;
+
+ oidTag = SECOID_FindOIDTag(oid);
+
+ if (oidTag == SEC_OID_OCSP_RESPONDER) {
+ goto success;
+ }
+
+ oids++;
}
loser:
@@ -3865,42 +3815,41 @@ loser:
success:
retval = PR_TRUE;
done:
- if ( extItem.data != NULL ) {
- PORT_Free(extItem.data);
+ if (extItem.data != NULL) {
+ PORT_Free(extItem.data);
}
- if ( oidSeq != NULL ) {
- CERT_DestroyOidSequence(oidSeq);
+ if (oidSeq != NULL) {
+ CERT_DestroyOidSequence(oidSeq);
}
-
- return(retval);
-}
+ 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!)
- */
+#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);
+
+ rv = CERT_FindCertExtension(cert, SEC_OID_PKIX_OCSP_NO_CHECK,
+ NULL);
if (rv == SECSuccess) {
- return PR_TRUE;
+ return PR_TRUE;
}
return PR_FALSE;
}
-#endif /* LATER */
+#endif /* LATER */
static PRBool
-ocsp_matchcert(SECItem *certIndex,CERTCertificate *testCert)
+ocsp_matchcert(SECItem *certIndex, CERTCertificate *testCert)
{
SECItem item;
unsigned char buf[HASH_LENGTH_MAX];
@@ -3908,33 +3857,33 @@ ocsp_matchcert(SECItem *certIndex,CERTCertificate *testCert)
item.data = buf;
item.len = SHA1_LENGTH;
- if (CERT_GetSubjectPublicKeyDigest(NULL,testCert,SEC_OID_SHA1,
- &item) == NULL) {
- return PR_FALSE;
+ if (CERT_GetSubjectPublicKeyDigest(NULL, testCert, SEC_OID_SHA1,
+ &item) == NULL) {
+ return PR_FALSE;
}
- if (SECITEM_ItemsAreEqual(certIndex,&item)) {
- return PR_TRUE;
+ if (SECITEM_ItemsAreEqual(certIndex, &item)) {
+ return PR_TRUE;
}
- if (CERT_GetSubjectPublicKeyDigest(NULL,testCert,SEC_OID_MD5,
- &item) == NULL) {
- return PR_FALSE;
+ if (CERT_GetSubjectPublicKeyDigest(NULL, testCert, SEC_OID_MD5,
+ &item) == NULL) {
+ return PR_FALSE;
}
- if (SECITEM_ItemsAreEqual(certIndex,&item)) {
- return PR_TRUE;
+ if (SECITEM_ItemsAreEqual(certIndex, &item)) {
+ return PR_TRUE;
}
- if (CERT_GetSubjectPublicKeyDigest(NULL,testCert,SEC_OID_MD2,
- &item) == NULL) {
- return PR_FALSE;
+ if (CERT_GetSubjectPublicKeyDigest(NULL, testCert, SEC_OID_MD2,
+ &item) == NULL) {
+ return PR_FALSE;
}
- if (SECITEM_ItemsAreEqual(certIndex,&item)) {
- return PR_TRUE;
+ if (SECITEM_ItemsAreEqual(certIndex, &item)) {
+ return PR_TRUE;
}
return PR_FALSE;
}
static CERTCertificate *
-ocsp_CertGetDefaultResponder(CERTCertDBHandle *handle,CERTOCSPCertID *certID);
+ocsp_CertGetDefaultResponder(CERTCertDBHandle *handle, CERTOCSPCertID *certID);
CERTCertificate *
ocsp_GetSignerCertificate(CERTCertDBHandle *handle, ocspResponseData *tbsData,
@@ -3949,19 +3898,19 @@ ocsp_GetSignerCertificate(CERTCertDBHandle *handle, ocspResponseData *tbsData,
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;
+ 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;
}
/*
@@ -3972,14 +3921,14 @@ ocsp_GetSignerCertificate(CERTCertDBHandle *handle, ocspResponseData *tbsData,
* 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;
+ 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;
}
/*
@@ -3987,51 +3936,51 @@ ocsp_GetSignerCertificate(CERTCertDBHandle *handle, ocspResponseData *tbsData,
* 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);
- }
+ 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 =
+ /*
+ * 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]);
- }
- }
- if (signerCert == NULL) {
- PORT_SetError(SEC_ERROR_UNKNOWN_CERT);
- }
+ 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]);
+ }
+ }
+ if (signerCert == NULL) {
+ PORT_SetError(SEC_ERROR_UNKNOWN_CERT);
+ }
}
finish:
if (certs != NULL) {
- CERT_DestroyCertArray(certs, certCount);
+ CERT_DestroyCertArray(certs, certCount);
}
return signerCert;
@@ -4067,7 +4016,7 @@ ocsp_VerifyResponseSignature(CERTCertificate *signerCert,
rv = CERT_VerifySignedDataWithPublicKey(&signedData, signerKey, pwArg);
if (rv != SECSuccess &&
- (PORT_GetError() == SEC_ERROR_BAD_SIGNATURE ||
+ (PORT_GetError() == SEC_ERROR_BAD_SIGNATURE ||
PORT_GetError() == SEC_ERROR_CERT_SIGNATURE_ALGORITHM_DISABLED)) {
PORT_SetError(SEC_ERROR_OCSP_BAD_SIGNATURE);
}
@@ -4079,7 +4028,6 @@ ocsp_VerifyResponseSignature(CERTCertificate *signerCert,
return rv;
}
-
/*
* FUNCTION: CERT_VerifyOCSPResponseSignature
* Check the signature on an OCSP Response. Will also perform a
@@ -4110,10 +4058,10 @@ ocsp_VerifyResponseSignature(CERTCertificate *signerCert,
* 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)
+CERT_VerifyOCSPResponseSignature(CERTOCSPResponse *response,
+ CERTCertDBHandle *handle, void *pwArg,
+ CERTCertificate **pSignerCert,
+ CERTCertificate *issuer)
{
SECItem *tbsResponseDataDER;
CERTCertificate *signerCert = NULL;
@@ -4138,24 +4086,24 @@ CERT_VerifyOCSPResponseSignature(CERTOCSPResponse *response,
* 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;
+ 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;
+ 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;
}
/*
@@ -4180,9 +4128,7 @@ CERT_VerifyOCSPResponseSignature(CERTOCSPResponse *response,
* 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 {
+ if (!ocsp_CertIsOCSPDefaultResponder(handle, signerCert)) {
SECCertUsage certUsage;
if (CERT_IsCACert(signerCert, NULL)) {
certUsage = certUsageAnyCA;
@@ -4204,24 +4150,24 @@ CERT_VerifyOCSPResponseSignature(CERTOCSPResponse *response,
finish:
if (signature->wasChecked)
- signature->status = rv;
+ signature->status = rv;
if (rv != SECSuccess) {
- signature->failureReason = PORT_GetError();
- if (signerCert != NULL)
- CERT_DestroyCertificate(signerCert);
+ 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);
- }
+ /*
+ * 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;
@@ -4234,7 +4180,7 @@ finish:
*/
static PRBool
ocsp_CertIDsMatch(CERTOCSPCertID *requestCertID,
- CERTOCSPCertID *responseCertID)
+ CERTOCSPCertID *responseCertID)
{
PRBool match = PR_FALSE;
SECOidTag hashAlg;
@@ -4248,8 +4194,8 @@ ocsp_CertIDsMatch(CERTOCSPCertID *requestCertID,
* We just compare the easier things first.
*/
if (SECITEM_CompareItem(&requestCertID->serialNumber,
- &responseCertID->serialNumber) != SECEqual) {
- goto done;
+ &responseCertID->serialNumber) != SECEqual) {
+ goto done;
}
/*
@@ -4257,48 +4203,49 @@ ocsp_CertIDsMatch(CERTOCSPCertID *requestCertID,
* requestCertID->hashAlgorithm, we don't need to check it.
*/
if (responseCertID->hashAlgorithm.parameters.len > 2) {
- goto done;
+ 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;
+ &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 PR_FALSE;
- }
-
- if ((keyHash != NULL)
- && (SECITEM_CompareItem(nameHash,
- &responseCertID->issuerNameHash) == SECEqual)
- && (SECITEM_CompareItem(keyHash,
- &responseCertID->issuerKeyHash) == SECEqual)) {
- match = PR_TRUE;
+ 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 PR_FALSE;
+ }
+
+ if ((keyHash != NULL) &&
+ (SECITEM_CompareItem(nameHash,
+ &responseCertID->issuerNameHash) == SECEqual) &&
+ (SECITEM_CompareItem(keyHash,
+ &responseCertID->issuerKeyHash) == SECEqual)) {
+ match = PR_TRUE;
}
done:
@@ -4313,27 +4260,27 @@ done:
*/
static CERTOCSPSingleResponse *
ocsp_GetSingleResponseForCertID(CERTOCSPSingleResponse **responses,
- CERTCertDBHandle *handle,
- CERTOCSPCertID *certID)
+ CERTCertDBHandle *handle,
+ CERTOCSPCertID *certID)
{
CERTOCSPSingleResponse *single;
int i;
if (responses == NULL)
- return NULL;
+ return NULL;
for (i = 0; responses[i] != NULL; i++) {
- single = responses[i];
- if (ocsp_CertIDsMatch(certID, single->certID)) {
- return single;
- }
+ single = responses[i];
+ if (ocsp_CertIDsMatch(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?
*/
@@ -4349,19 +4296,19 @@ ocsp_GetCheckingContext(CERTCertDBHandle *handle)
statusConfig = CERT_GetStatusConfig(handle);
if (statusConfig != NULL) {
- ocspcx = statusConfig->statusContext;
+ 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);
+ /*
+ * 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);
+ PORT_SetError(SEC_ERROR_OCSP_NOT_ENABLED);
return ocspcx;
}
@@ -4377,19 +4324,19 @@ ocsp_CertGetDefaultResponder(CERTCertDBHandle *handle, CERTOCSPCertID *certID)
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.
- */
+ 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;
+ PORT_Assert(ocspcx->defaultResponderCert != NULL);
+ return ocspcx->defaultResponderCert;
}
loser:
@@ -4407,19 +4354,19 @@ ocsp_CertIsOCSPDefaultResponder(CERTCertDBHandle *handle, CERTCertificate *cert)
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.
- */
+ 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_TRUE;
}
return PR_FALSE;
@@ -4444,9 +4391,9 @@ ocsp_CertIsOCSPDefaultResponder(CERTCertDBHandle *handle, CERTCertificate *cert)
*/
static PRBool
ocsp_AuthorizedResponderForCertID(CERTCertDBHandle *handle,
- CERTCertificate *signerCert,
- CERTOCSPCertID *certID,
- PRTime thisUpdate)
+ CERTCertificate *signerCert,
+ CERTOCSPCertID *certID,
+ PRTime thisUpdate)
{
CERTCertificate *issuerCert = NULL, *defRespCert;
SECItem *keyHash = NULL;
@@ -4490,7 +4437,7 @@ ocsp_AuthorizedResponderForCertID(CERTCertDBHandle *handle,
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 */
@@ -4498,7 +4445,6 @@ ocsp_AuthorizedResponderForCertID(CERTCertDBHandle *handle,
}
}
-
keyHashEQ = PR_FALSE;
nameHashEQ = PR_FALSE;
@@ -4529,7 +4475,7 @@ ocsp_AuthorizedResponderForCertID(CERTCertDBHandle *handle,
CERT_DestroyCertificate(issuerCert);
if (keyHash != NULL && nameHash != NULL) {
- keyHashEQ =
+ keyHashEQ =
(SECITEM_CompareItem(keyHash,
&certID->issuerKeyHash) == SECEqual);
@@ -4565,7 +4511,7 @@ ocsp_AuthorizedResponderForCertID(CERTCertDBHandle *handle,
* want something from within the last 24 hours. This macro defines that
* number in seconds.
*/
-#define OCSP_ALLOWABLE_LAPSE_SECONDS (24L * 60L * 60L)
+#define OCSP_ALLOWABLE_LAPSE_SECONDS (24L * 60L * 60L)
static PRBool
ocsp_TimeIsRecent(PRTime checkTime)
@@ -4575,19 +4521,19 @@ ocsp_TimeIsRecent(PRTime checkTime)
LL_I2L(lapse, OCSP_ALLOWABLE_LAPSE_SECONDS);
LL_I2L(tmp, PR_USEC_PER_SEC);
- LL_MUL(lapse, lapse, tmp); /* allowable lapse in microseconds */
+ LL_MUL(lapse, lapse, tmp); /* allowable lapse in microseconds */
LL_ADD(checkTime, checkTime, lapse);
if (LL_CMP(now, >, checkTime))
- return PR_FALSE;
+ return PR_FALSE;
return PR_TRUE;
}
-#define OCSP_SLOP (5L*60L) /* OCSP responses are allowed to be 5 minutes
- in the future by default */
+#define OCSP_SLOP (5L * 60L) /* OCSP responses are allowed to be 5 minutes \
+ in the future by default */
-static PRUint32 ocspsloptime = OCSP_SLOP; /* seconds */
+static PRUint32 ocspsloptime = OCSP_SLOP; /* seconds */
/*
* If an old response contains the revoked certificate status, we want
@@ -4610,7 +4556,6 @@ ocsp_HandleOldSingleResponse(CERTOCSPSingleResponse *single, PRTime time)
*/
return SECSuccess;
}
-
}
PORT_SetError(SEC_ERROR_OCSP_OLD_RESPONSE);
return SECFailure;
@@ -4638,19 +4583,19 @@ ocsp_HandleOldSingleResponse(CERTOCSPSingleResponse *single, PRTime time)
* 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,
- PRTime producedAt)
+ CERTCertDBHandle *handle,
+ CERTCertificate *signerCert,
+ PRTime producedAt)
{
CERTOCSPCertID *certID = single->certID;
PRTime now, thisUpdate, nextUpdate, tmstamp, tmp;
SECStatus rv;
- OCSP_TRACE(("OCSP ocsp_VerifySingleResponse, nextUpdate: %d\n",
- ((single->nextUpdate) != 0)));
+ 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,
@@ -4659,7 +4604,7 @@ ocsp_VerifySingleResponse(CERTOCSPSingleResponse *single,
*/
PORT_Assert(single->certStatus != NULL);
if (single->certStatus->certStatusType == ocspCertStatus_unknown)
- return SECSuccess;
+ return SECSuccess;
/*
* We need to extract "thisUpdate" for use below and to pass along
@@ -4668,14 +4613,14 @@ ocsp_VerifySingleResponse(CERTOCSPSingleResponse *single,
*/
rv = DER_GeneralizedTimeToTime(&thisUpdate, &single->thisUpdate);
if (rv != SECSuccess)
- return rv;
+ return rv;
/*
* First confirm that signerCert is authorized to give this status.
*/
if (ocsp_AuthorizedResponderForCertID(handle, signerCert, certID,
- thisUpdate) != PR_TRUE)
- return SECFailure;
+ thisUpdate) != PR_TRUE)
+ return SECFailure;
/*
* Now check the time stuff, as described above.
@@ -4688,25 +4633,24 @@ ocsp_VerifySingleResponse(CERTOCSPSingleResponse *single,
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;
+ PORT_SetError(SEC_ERROR_OCSP_FUTURE_RESPONSE);
+ return SECFailure;
}
if (single->nextUpdate != NULL) {
- rv = DER_GeneralizedTimeToTime(&nextUpdate, single->nextUpdate);
- if (rv != SECSuccess)
- return rv;
+ 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);
+ 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 ocsp_HandleOldSingleResponse(single, now);
}
return SECSuccess;
}
-
/*
* FUNCTION: CERT_GetOCSPAuthorityInfoAccessLocation
* Get the value of the URI of the OCSP responder for the given cert.
@@ -4721,7 +4665,7 @@ ocsp_VerifySingleResponse(CERTOCSPSingleResponse *single,
* 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 *
@@ -4743,13 +4687,13 @@ CERT_GetOCSPAuthorityInfoAccessLocation(const CERTCertificate *cert)
*/
encodedAuthInfoAccess = SECITEM_AllocItem(NULL, NULL, 0);
if (encodedAuthInfoAccess == NULL)
- goto loser;
+ goto loser;
rv = CERT_FindCertExtension(cert, SEC_OID_X509_AUTH_INFO_ACCESS,
- encodedAuthInfoAccess);
+ encodedAuthInfoAccess);
if (rv == SECFailure) {
- PORT_SetError(SEC_ERROR_CERT_BAD_ACCESS_LOCATION);
- goto loser;
+ PORT_SetError(SEC_ERROR_CERT_BAD_ACCESS_LOCATION);
+ goto loser;
}
/*
@@ -4760,16 +4704,16 @@ CERT_GetOCSPAuthorityInfoAccessLocation(const CERTCertificate *cert)
*/
arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
if (arena == NULL)
- goto loser;
+ goto loser;
authInfoAccess = CERT_DecodeAuthInfoAccessExtension(arena,
- encodedAuthInfoAccess);
+ encodedAuthInfoAccess);
if (authInfoAccess == NULL)
- goto loser;
+ goto loser;
for (i = 0; authInfoAccess[i] != NULL; i++) {
- if (SECOID_FindOIDTag(&authInfoAccess[i]->method) == SEC_OID_PKIX_OCSP)
- locname = authInfoAccess[i]->location;
+ if (SECOID_FindOIDTag(&authInfoAccess[i]->method) == SEC_OID_PKIX_OCSP)
+ locname = authInfoAccess[i]->location;
}
/*
@@ -4780,8 +4724,8 @@ CERT_GetOCSPAuthorityInfoAccessLocation(const CERTCertificate *cert)
* not there at all.
*/
if (locname == NULL) {
- PORT_SetError(SEC_ERROR_CERT_BAD_ACCESS_LOCATION);
- goto loser;
+ PORT_SetError(SEC_ERROR_CERT_BAD_ACCESS_LOCATION);
+ goto loser;
}
/*
@@ -4790,15 +4734,15 @@ CERT_GetOCSPAuthorityInfoAccessLocation(const CERTCertificate *cert)
*/
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;
+ /*
+ * 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;
}
/*
@@ -4809,22 +4753,21 @@ CERT_GetOCSPAuthorityInfoAccessLocation(const CERTCertificate *cert)
*/
locURI = PORT_Alloc(location->len + 1);
if (locURI == NULL) {
- goto loser;
+ goto loser;
}
PORT_Memcpy(locURI, location->data, location->len);
locURI[location->len] = '\0';
loser:
if (arena != NULL)
- PORT_FreeArena(arena, PR_FALSE);
+ PORT_FreeArena(arena, PR_FALSE);
if (encodedAuthInfoAccess != NULL)
- SECITEM_FreeItem(encodedAuthInfoAccess, PR_TRUE);
+ 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
@@ -4840,7 +4783,7 @@ loser:
*/
char *
ocsp_GetResponderLocation(CERTCertDBHandle *handle, CERTCertificate *cert,
- PRBool canUseDefault, PRBool *isDefault)
+ PRBool canUseDefault, PRBool *isDefault)
{
ocspCheckingContext *ocspcx = NULL;
char *ocspUrl = NULL;
@@ -4849,15 +4792,15 @@ ocsp_GetResponderLocation(CERTCertDBHandle *handle, CERTCertificate *cert,
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));
+ /*
+ * 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));
}
/*
@@ -4867,16 +4810,16 @@ ocsp_GetResponderLocation(CERTCertDBHandle *handle, CERTCertificate *cert,
*isDefault = PR_FALSE;
ocspUrl = CERT_GetOCSPAuthorityInfoAccessLocation(cert);
if (!ocspUrl) {
- CERT_StringFromCertFcn altFcn;
+ 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;
- }
+ 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;
}
@@ -4893,7 +4836,7 @@ ocsp_CertRevokedAfter(ocspRevokedInfo *revokedInfo, PRTime time)
rv = DER_GeneralizedTimeToTime(&revokedTime, &revokedInfo->revocationTime);
if (rv != SECSuccess)
- return rv;
+ return rv;
/*
* Set the error even if we will return success; someone might care.
@@ -4901,7 +4844,7 @@ ocsp_CertRevokedAfter(ocspRevokedInfo *revokedInfo, PRTime time)
PORT_SetError(SEC_ERROR_REVOKED_CERTIFICATE);
if (LL_CMP(revokedTime, >, time))
- return SECSuccess;
+ return SECSuccess;
return SECFailure;
}
@@ -4915,28 +4858,28 @@ ocsp_CertHasGoodStatus(ocspCertStatus *status, PRTime 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;
+ 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,
+ocsp_SingleResponseCertHasGoodStatus(CERTOCSPSingleResponse *single,
PRTime time)
{
return ocsp_CertHasGoodStatus(single->certStatus, time);
@@ -4963,7 +4906,7 @@ ocsp_GetCachedOCSPResponseStatus(CERTOCSPCertID *certID,
OCSPFreshness *cacheFreshness)
{
OCSPCacheItem *cacheItem = NULL;
-
+
if (!certID || !missingResponseError || !rvOcsp || !cacheFreshness) {
PORT_SetError(SEC_ERROR_INVALID_ARGS);
return SECFailure;
@@ -4971,7 +4914,7 @@ ocsp_GetCachedOCSPResponseStatus(CERTOCSPCertID *certID,
*rvOcsp = SECFailure;
*missingResponseError = 0;
*cacheFreshness = ocspMissing;
-
+
PR_EnterMonitor(OCSP_Global.monitor);
cacheItem = ocsp_FindCacheEntry(&OCSP_Global.cache, certID);
if (cacheItem) {
@@ -4986,13 +4929,13 @@ ocsp_GetCachedOCSPResponseStatus(CERTOCSPCertID *certID,
} else {
/*
* No status cached, the previous attempt failed.
- * If OCSP is required, we never decide based on a failed attempt
+ * 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 (*cacheFreshness == ocspFresh &&
!ignoreGlobalOcspFailureSetting &&
- OCSP_Global.ocspFailureMode ==
+ OCSP_Global.ocspFailureMode ==
ocspMode_FailureIsNotAVerificationFailure) {
*rvOcsp = SECSuccess;
}
@@ -5064,10 +5007,10 @@ ocsp_FetchingFailureIsVerificationFailure(void)
* (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
+ */
+SECStatus
CERT_CheckOCSPStatus(CERTCertDBHandle *handle, CERTCertificate *cert,
- PRTime time, void *pwArg)
+ PRTime time, void *pwArg)
{
CERTOCSPCertID *certID;
PRBool certIDWasConsumed = PR_FALSE;
@@ -5075,10 +5018,10 @@ CERT_CheckOCSPStatus(CERTCertDBHandle *handle, CERTCertificate *cert,
SECStatus rvOcsp;
SECErrorCodes cachedErrorCode;
OCSPFreshness cachedResponseFreshness;
-
+
OCSP_TRACE_CERT(cert);
OCSP_TRACE_TIME("## requested validity time:", time);
-
+
certID = CERT_CreateOCSPCertID(cert, time);
if (!certID)
return SECFailure;
@@ -5098,7 +5041,7 @@ CERT_CheckOCSPStatus(CERTCertDBHandle *handle, CERTCertificate *cert,
}
rv = ocsp_GetOCSPStatusFromNetwork(handle, certID, cert, time, pwArg,
- &certIDWasConsumed,
+ &certIDWasConsumed,
&rvOcsp);
if (rv != SECSuccess) {
PRErrorCode err = PORT_GetError();
@@ -5157,10 +5100,10 @@ CERT_CheckOCSPStatus(CERTCertDBHandle *handle, CERTCertificate *cert,
*/
SECStatus
CERT_CacheOCSPResponseFromSideChannel(CERTCertDBHandle *handle,
- CERTCertificate *cert,
- PRTime time,
- const SECItem *encodedResponse,
- void *pwArg)
+ CERTCertificate *cert,
+ PRTime time,
+ const SECItem *encodedResponse,
+ void *pwArg)
{
CERTOCSPCertID *certID = NULL;
PRBool certIDWasConsumed = PR_FALSE;
@@ -5235,17 +5178,17 @@ CERT_CacheOCSPResponseFromSideChannel(CERTCertDBHandle *handle,
* ocsp_CacheSingleResponse. */
rv = ocsp_GetDecodedVerifiedSingleResponseForID(handle, certID, cert,
- time, pwArg,
- encodedResponse,
- &decodedResponse,
- &singleResponse);
+ time, pwArg,
+ encodedResponse,
+ &decodedResponse,
+ &singleResponse);
if (rv == SECSuccess) {
- rvOcsp = ocsp_SingleResponseCertHasGoodStatus(singleResponse, time);
- /* Cache any valid singleResponse, regardless of status. */
- ocsp_CacheSingleResponse(certID, singleResponse, &certIDWasConsumed);
+ rvOcsp = ocsp_SingleResponseCertHasGoodStatus(singleResponse, time);
+ /* Cache any valid singleResponse, regardless of status. */
+ ocsp_CacheSingleResponse(certID, singleResponse, &certIDWasConsumed);
}
if (decodedResponse) {
- CERT_DestroyOCSPResponse(decodedResponse);
+ CERT_DestroyOCSPResponse(decodedResponse);
}
if (!certIDWasConsumed) {
CERT_DestroyOCSPCertID(certID);
@@ -5254,13 +5197,13 @@ CERT_CacheOCSPResponseFromSideChannel(CERTCertDBHandle *handle,
}
/*
- * Status in *certIDWasConsumed will always be correct, regardless of
+ * Status in *certIDWasConsumed will always be correct, regardless of
* return value.
*/
static SECStatus
-ocsp_GetOCSPStatusFromNetwork(CERTCertDBHandle *handle,
- CERTOCSPCertID *certID,
- CERTCertificate *cert,
+ocsp_GetOCSPStatusFromNetwork(CERTCertDBHandle *handle,
+ CERTOCSPCertID *certID,
+ CERTCertificate *cert,
PRTime time,
void *pwArg,
PRBool *certIDWasConsumed,
@@ -5274,7 +5217,8 @@ ocsp_GetOCSPStatusFromNetwork(CERTCertDBHandle *handle,
CERTOCSPResponse *decodedResponse = NULL;
CERTOCSPSingleResponse *singleResponse = NULL;
- enum { stageGET, stagePOST } currentStage;
+ enum { stageGET,
+ stagePOST } currentStage;
PRBool retry = PR_FALSE;
if (!certIDWasConsumed || !rv_ocsp) {
@@ -5310,14 +5254,14 @@ ocsp_GetOCSPStatusFromNetwork(CERTCertDBHandle *handle,
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;
+ 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;
}
/*
@@ -5343,75 +5287,75 @@ ocsp_GetOCSPStatusFromNetwork(CERTCertDBHandle *handle,
*/
do {
- const char *method;
- PRBool validResponseWithAccurateInfo = PR_FALSE;
- retry = PR_FALSE;
- *rv_ocsp = SECFailure;
-
- if (currentStage == stageGET) {
- method = "GET";
- } else {
- PORT_Assert(currentStage == stagePOST);
- method = "POST";
- }
-
- encodedResponse =
- ocsp_GetEncodedOCSPResponseForSingleCert(NULL, certID, cert,
- location, method,
- time, locationIsDefault,
- pwArg, &request);
-
- if (encodedResponse) {
- rv = ocsp_GetDecodedVerifiedSingleResponseForID(handle, certID, cert,
- time, pwArg,
- encodedResponse,
- &decodedResponse,
- &singleResponse);
- if (rv == SECSuccess) {
- switch (singleResponse->certStatus->certStatusType) {
- case ocspCertStatus_good:
- case ocspCertStatus_revoked:
- validResponseWithAccurateInfo = PR_TRUE;
- break;
- default:
- break;
- }
- *rv_ocsp = ocsp_SingleResponseCertHasGoodStatus(singleResponse, time);
- }
- }
-
- if (currentStage == stageGET) {
- /* only accept GET response if good or revoked */
- if (validResponseWithAccurateInfo) {
- ocsp_CacheSingleResponse(certID, singleResponse,
- certIDWasConsumed);
- } else {
- retry = PR_TRUE;
- currentStage = stagePOST;
- }
- } else {
- /* cache the POST respone, regardless of status */
- if (!singleResponse) {
- cert_RememberOCSPProcessingFailure(certID, certIDWasConsumed);
- } else {
- ocsp_CacheSingleResponse(certID, singleResponse,
- certIDWasConsumed);
- }
- }
-
- if (encodedResponse) {
- SECITEM_FreeItem(encodedResponse, PR_TRUE);
- encodedResponse = NULL;
- }
- if (request) {
- CERT_DestroyOCSPRequest(request);
- request = NULL;
- }
- if (decodedResponse) {
- CERT_DestroyOCSPResponse(decodedResponse);
- decodedResponse = NULL;
- }
- singleResponse = NULL;
+ const char *method;
+ PRBool validResponseWithAccurateInfo = PR_FALSE;
+ retry = PR_FALSE;
+ *rv_ocsp = SECFailure;
+
+ if (currentStage == stageGET) {
+ method = "GET";
+ } else {
+ PORT_Assert(currentStage == stagePOST);
+ method = "POST";
+ }
+
+ encodedResponse =
+ ocsp_GetEncodedOCSPResponseForSingleCert(NULL, certID, cert,
+ location, method,
+ time, locationIsDefault,
+ pwArg, &request);
+
+ if (encodedResponse) {
+ rv = ocsp_GetDecodedVerifiedSingleResponseForID(handle, certID, cert,
+ time, pwArg,
+ encodedResponse,
+ &decodedResponse,
+ &singleResponse);
+ if (rv == SECSuccess) {
+ switch (singleResponse->certStatus->certStatusType) {
+ case ocspCertStatus_good:
+ case ocspCertStatus_revoked:
+ validResponseWithAccurateInfo = PR_TRUE;
+ break;
+ default:
+ break;
+ }
+ *rv_ocsp = ocsp_SingleResponseCertHasGoodStatus(singleResponse, time);
+ }
+ }
+
+ if (currentStage == stageGET) {
+ /* only accept GET response if good or revoked */
+ if (validResponseWithAccurateInfo) {
+ ocsp_CacheSingleResponse(certID, singleResponse,
+ certIDWasConsumed);
+ } else {
+ retry = PR_TRUE;
+ currentStage = stagePOST;
+ }
+ } else {
+ /* cache the POST respone, regardless of status */
+ if (!singleResponse) {
+ cert_RememberOCSPProcessingFailure(certID, certIDWasConsumed);
+ } else {
+ ocsp_CacheSingleResponse(certID, singleResponse,
+ certIDWasConsumed);
+ }
+ }
+
+ if (encodedResponse) {
+ SECITEM_FreeItem(encodedResponse, PR_TRUE);
+ encodedResponse = NULL;
+ }
+ if (request) {
+ CERT_DestroyOCSPRequest(request);
+ request = NULL;
+ }
+ if (decodedResponse) {
+ CERT_DestroyOCSPResponse(decodedResponse);
+ decodedResponse = NULL;
+ }
+ singleResponse = NULL;
} while (retry);
@@ -5454,25 +5398,25 @@ ocsp_GetOCSPStatusFromNetwork(CERTCertDBHandle *handle,
*/
static SECStatus
ocsp_GetDecodedVerifiedSingleResponseForID(CERTCertDBHandle *handle,
- CERTOCSPCertID *certID,
- CERTCertificate *cert,
- PRTime time,
- void *pwArg,
- const SECItem *encodedResponse,
- CERTOCSPResponse **pDecodedResponse,
- CERTOCSPSingleResponse **pSingle)
+ CERTOCSPCertID *certID,
+ CERTCertificate *cert,
+ PRTime time,
+ void *pwArg,
+ const SECItem *encodedResponse,
+ CERTOCSPResponse **pDecodedResponse,
+ CERTOCSPSingleResponse **pSingle)
{
CERTCertificate *signerCert = NULL;
CERTCertificate *issuerCert = NULL;
SECStatus rv = SECFailure;
if (!pSingle || !pDecodedResponse) {
- return SECFailure;
+ return SECFailure;
}
*pSingle = NULL;
*pDecodedResponse = CERT_DecodeOCSPResponse(encodedResponse);
if (!*pDecodedResponse) {
- return SECFailure;
+ return SECFailure;
}
/*
@@ -5485,7 +5429,7 @@ ocsp_GetDecodedVerifiedSingleResponseForID(CERTCertDBHandle *handle,
* in the response.
*/
if (CERT_GetOCSPResponseStatus(*pDecodedResponse) != SECSuccess) {
- goto loser;
+ goto loser;
}
/*
@@ -5496,32 +5440,32 @@ ocsp_GetDecodedVerifiedSingleResponseForID(CERTCertDBHandle *handle,
rv = CERT_VerifyOCSPResponseSignature(*pDecodedResponse, handle, pwArg,
&signerCert, issuerCert);
if (rv != SECSuccess) {
- goto loser;
+ goto loser;
}
- PORT_Assert(signerCert != NULL); /* internal consistency check */
+ 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.
+ * have to determine how to make multiple requests, etc.
*/
- rv = ocsp_GetVerifiedSingleResponseForCertID(handle, *pDecodedResponse, certID,
+ rv = ocsp_GetVerifiedSingleResponseForCertID(handle, *pDecodedResponse, certID,
signerCert, time, pSingle);
loser:
if (issuerCert != NULL)
- CERT_DestroyCertificate(issuerCert);
+ CERT_DestroyCertificate(issuerCert);
if (signerCert != NULL)
- CERT_DestroyCertificate(signerCert);
+ CERT_DestroyCertificate(signerCert);
return rv;
}
/*
* FUNCTION: ocsp_CacheSingleResponse
* This function requires that the caller has checked that the response
- * is valid and verified.
+ * is valid and verified.
* The (positive or negative) valid response will be used to update the cache.
* INPUTS:
* CERTOCSPCertID *certID
@@ -5532,27 +5476,27 @@ loser:
*/
void
ocsp_CacheSingleResponse(CERTOCSPCertID *certID,
- CERTOCSPSingleResponse *single,
- PRBool *certIDWasConsumed)
+ CERTOCSPSingleResponse *single,
+ PRBool *certIDWasConsumed)
{
if (single != NULL) {
- PR_EnterMonitor(OCSP_Global.monitor);
- if (OCSP_Global.maxCacheEntries >= 0) {
- ocsp_CreateOrUpdateCacheEntry(&OCSP_Global.cache, certID, single,
- certIDWasConsumed);
- /* ignore cache update failures */
- }
- PR_ExitMonitor(OCSP_Global.monitor);
+ PR_EnterMonitor(OCSP_Global.monitor);
+ if (OCSP_Global.maxCacheEntries >= 0) {
+ ocsp_CreateOrUpdateCacheEntry(&OCSP_Global.cache, certID, single,
+ certIDWasConsumed);
+ /* ignore cache update failures */
+ }
+ PR_ExitMonitor(OCSP_Global.monitor);
}
}
SECStatus
-ocsp_GetVerifiedSingleResponseForCertID(CERTCertDBHandle *handle,
- CERTOCSPResponse *response,
- CERTOCSPCertID *certID,
- CERTCertificate *signerCert,
- PRTime time,
- CERTOCSPSingleResponse
+ocsp_GetVerifiedSingleResponseForCertID(CERTCertDBHandle *handle,
+ CERTOCSPResponse *response,
+ CERTOCSPCertID *certID,
+ CERTCertificate *signerCert,
+ PRTime time,
+ CERTOCSPSingleResponse
**pSingleResponse)
{
SECStatus rv;
@@ -5596,11 +5540,11 @@ loser:
}
SECStatus
-CERT_GetOCSPStatusForCertID(CERTCertDBHandle *handle,
- CERTOCSPResponse *response,
- CERTOCSPCertID *certID,
- CERTCertificate *signerCert,
- PRTime time)
+CERT_GetOCSPStatusForCertID(CERTCertDBHandle *handle,
+ CERTOCSPResponse *response,
+ CERTOCSPCertID *certID,
+ CERTCertificate *signerCert,
+ PRTime time)
{
/*
* We do not update the cache, because:
@@ -5612,17 +5556,17 @@ CERT_GetOCSPStatusForCertID(CERTCertDBHandle *handle,
* 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
+ * 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
+ * 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,
+ return cert_ProcessOCSPResponse(handle, response, certID,
+ signerCert, time,
NULL, NULL);
}
@@ -5630,23 +5574,23 @@ CERT_GetOCSPStatusForCertID(CERTCertDBHandle *handle,
* The first 5 parameters match the definition of CERT_GetOCSPStatusForCertID.
*/
SECStatus
-cert_ProcessOCSPResponse(CERTCertDBHandle *handle,
- CERTOCSPResponse *response,
- CERTOCSPCertID *certID,
- CERTCertificate *signerCert,
- PRTime time,
- PRBool *certIDWasConsumed,
- SECStatus *cacheUpdateStatus)
+cert_ProcessOCSPResponse(CERTCertDBHandle *handle,
+ CERTOCSPResponse *response,
+ CERTOCSPCertID *certID,
+ CERTCertificate *signerCert,
+ PRTime time,
+ PRBool *certIDWasConsumed,
+ SECStatus *cacheUpdateStatus)
{
SECStatus rv;
SECStatus rv_cache = SECSuccess;
CERTOCSPSingleResponse *single = NULL;
- rv = ocsp_GetVerifiedSingleResponseForCertID(handle, response, certID,
+ rv = ocsp_GetVerifiedSingleResponseForCertID(handle, response, certID,
signerCert, time, &single);
if (rv == SECSuccess) {
/*
- * Check whether the status says revoked, and if so
+ * 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);
@@ -5654,15 +5598,15 @@ cert_ProcessOCSPResponse(CERTCertDBHandle *handle,
if (certIDWasConsumed) {
/*
- * We don't have copy-of-certid implemented. In order to update
- * the cache, the caller must supply an out variable
+ * 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 =
+ rv_cache =
ocsp_CreateOrUpdateCacheEntry(&OCSP_Global.cache, certID,
single, certIDWasConsumed);
}
@@ -5677,12 +5621,12 @@ cert_ProcessOCSPResponse(CERTCertDBHandle *handle,
SECStatus
cert_RememberOCSPProcessingFailure(CERTOCSPCertID *certID,
- PRBool *certIDWasConsumed)
+ PRBool *certIDWasConsumed)
{
SECStatus rv = SECSuccess;
PR_EnterMonitor(OCSP_Global.monitor);
if (OCSP_Global.maxCacheEntries >= 0) {
- rv = ocsp_CreateOrUpdateCacheEntry(&OCSP_Global.cache, certID, NULL,
+ rv = ocsp_CreateOrUpdateCacheEntry(&OCSP_Global.cache, certID, NULL,
certIDWasConsumed);
}
PR_ExitMonitor(OCSP_Global.monitor);
@@ -5705,12 +5649,12 @@ ocsp_DestroyStatusChecking(CERTStatusConfig *statusConfig)
statusContext = statusConfig->statusContext;
PORT_Assert(statusContext != NULL);
if (statusContext == NULL)
- return SECFailure;
+ return SECFailure;
if (statusContext->defaultResponderURI != NULL)
- PORT_Free(statusContext->defaultResponderURI);
+ PORT_Free(statusContext->defaultResponderURI);
if (statusContext->defaultResponderNickname != NULL)
- PORT_Free(statusContext->defaultResponderNickname);
+ PORT_Free(statusContext->defaultResponderNickname);
PORT_Free(statusContext);
statusConfig->statusContext = NULL;
@@ -5720,7 +5664,6 @@ ocsp_DestroyStatusChecking(CERTStatusConfig *statusConfig)
return SECSuccess;
}
-
/*
* FUNCTION: CERT_DisableOCSPChecking
* Turns off OCSP checking for the given certificate database.
@@ -5743,22 +5686,22 @@ CERT_DisableOCSPChecking(CERTCertDBHandle *handle)
ocspCheckingContext *statusContext;
if (handle == NULL) {
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- return SECFailure;
+ PORT_SetError(SEC_ERROR_INVALID_ARGS);
+ return SECFailure;
}
statusConfig = CERT_GetStatusConfig(handle);
statusContext = ocsp_GetCheckingContext(handle);
if (statusContext == NULL)
- return SECFailure;
+ 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;
+ /*
+ * 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 */
@@ -5786,17 +5729,17 @@ ocsp_InitStatusChecking(CERTCertDBHandle *handle)
PORT_Assert(CERT_GetStatusConfig(handle) == NULL);
if (CERT_GetStatusConfig(handle) != NULL) {
- /* XXX or call statusConfig->statusDestroy and continue? */
- return SECFailure;
+ /* XXX or call statusConfig->statusDestroy and continue? */
+ return SECFailure;
}
statusConfig = PORT_ZNew(CERTStatusConfig);
if (statusConfig == NULL)
- goto loser;
+ goto loser;
statusContext = PORT_ZNew(ocspCheckingContext);
if (statusContext == NULL)
- goto loser;
+ goto loser;
statusConfig->statusDestroy = ocsp_DestroyStatusChecking;
statusConfig->statusContext = statusContext;
@@ -5807,11 +5750,10 @@ ocsp_InitStatusChecking(CERTCertDBHandle *handle)
loser:
if (statusConfig != NULL)
- PORT_Free(statusConfig);
+ PORT_Free(statusConfig);
return SECFailure;
}
-
/*
* FUNCTION: CERT_EnableOCSPChecking
* Turns on OCSP checking for the given certificate database.
@@ -5826,23 +5768,23 @@ SECStatus
CERT_EnableOCSPChecking(CERTCertDBHandle *handle)
{
CERTStatusConfig *statusConfig;
-
+
SECStatus rv;
if (handle == NULL) {
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- return SECFailure;
+ PORT_SetError(SEC_ERROR_INVALID_ARGS);
+ return SECFailure;
}
statusConfig = CERT_GetStatusConfig(handle);
if (statusConfig == NULL) {
- rv = ocsp_InitStatusChecking(handle);
- if (rv != SECSuccess)
- return rv;
+ rv = ocsp_InitStatusChecking(handle);
+ if (rv != SECSuccess)
+ return rv;
- /* Get newly established value */
- statusConfig = CERT_GetStatusConfig(handle);
- PORT_Assert(statusConfig != NULL);
+ /* Get newly established value */
+ statusConfig = CERT_GetStatusConfig(handle);
+ PORT_Assert(statusConfig != NULL);
}
/*
@@ -5854,7 +5796,6 @@ CERT_EnableOCSPChecking(CERTCertDBHandle *handle)
return SECSuccess;
}
-
/*
* FUNCTION: CERT_SetOCSPDefaultResponder
* Specify the location and cert of the default responder.
@@ -5881,7 +5822,7 @@ CERT_EnableOCSPChecking(CERTCertDBHandle *handle)
*/
SECStatus
CERT_SetOCSPDefaultResponder(CERTCertDBHandle *handle,
- const char *url, const char *name)
+ const char *url, const char *name)
{
CERTCertificate *cert;
ocspCheckingContext *statusContext;
@@ -5890,12 +5831,12 @@ CERT_SetOCSPDefaultResponder(CERTCertDBHandle *handle,
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;
+ /*
+ * XXX When interface is exported, probably want better errors;
+ * perhaps different one for each parameter.
+ */
+ PORT_SetError(SEC_ERROR_INVALID_ARGS);
+ return SECFailure;
}
/*
@@ -5905,15 +5846,15 @@ CERT_SetOCSPDefaultResponder(CERTCertDBHandle *handle,
* 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);
+ cert = CERT_FindCertByNickname(handle, (char *)name);
if (cert == NULL) {
- /*
- * look for the cert on an external token.
- */
- cert = PK11_FindCertFromNickname((char *)name, NULL);
+ /*
+ * look for the cert on an external token.
+ */
+ cert = PK11_FindCertFromNickname((char *)name, NULL);
}
if (cert == NULL)
- return SECFailure;
+ return SECFailure;
/*
* Make a copy of the url and nickname.
@@ -5921,8 +5862,8 @@ CERT_SetOCSPDefaultResponder(CERTCertDBHandle *handle,
url_copy = PORT_Strdup(url);
name_copy = PORT_Strdup(name);
if (url_copy == NULL || name_copy == NULL) {
- rv = SECFailure;
- goto loser;
+ rv = SECFailure;
+ goto loser;
}
statusContext = ocsp_GetCheckingContext(handle);
@@ -5931,12 +5872,12 @@ CERT_SetOCSPDefaultResponder(CERTCertDBHandle *handle,
* Allocate and init the context if it doesn't already exist.
*/
if (statusContext == NULL) {
- rv = ocsp_InitStatusChecking(handle);
- if (rv != SECSuccess)
- goto loser;
+ rv = ocsp_InitStatusChecking(handle);
+ if (rv != SECSuccess)
+ goto loser;
- statusContext = ocsp_GetCheckingContext(handle);
- PORT_Assert(statusContext != NULL); /* extreme paranoia */
+ statusContext = ocsp_GetCheckingContext(handle);
+ PORT_Assert(statusContext != NULL); /* extreme paranoia */
}
/*
@@ -5949,9 +5890,9 @@ CERT_SetOCSPDefaultResponder(CERTCertDBHandle *handle,
* Get rid of old url and name if there.
*/
if (statusContext->defaultResponderNickname != NULL)
- PORT_Free(statusContext->defaultResponderNickname);
+ PORT_Free(statusContext->defaultResponderNickname);
if (statusContext->defaultResponderURI != NULL)
- PORT_Free(statusContext->defaultResponderURI);
+ PORT_Free(statusContext->defaultResponderURI);
/*
* And replace them with the new ones.
@@ -5966,13 +5907,13 @@ CERT_SetOCSPDefaultResponder(CERTCertDBHandle *handle,
* enabled.
*/
if (statusContext->defaultResponderCert != NULL) {
- CERT_DestroyCertificate(statusContext->defaultResponderCert);
- statusContext->defaultResponderCert = cert;
+ 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);
+ PORT_Assert(statusContext->useDefaultResponder == PR_FALSE);
+ CERT_DestroyCertificate(cert);
/*OCSP currently not enabled, no need to clear cache*/
}
@@ -5981,13 +5922,12 @@ CERT_SetOCSPDefaultResponder(CERTCertDBHandle *handle,
loser:
CERT_DestroyCertificate(cert);
if (url_copy != NULL)
- PORT_Free(url_copy);
+ PORT_Free(url_copy);
if (name_copy != NULL)
- PORT_Free(name_copy);
+ PORT_Free(name_copy);
return rv;
}
-
/*
* FUNCTION: CERT_EnableOCSPDefaultResponder
* Turns on use of a default responder when OCSP checking.
@@ -6014,36 +5954,36 @@ CERT_EnableOCSPDefaultResponder(CERTCertDBHandle *handle)
SECCertificateUsage usage;
if (handle == NULL) {
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- return SECFailure;
+ 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;
+ /*
+ * 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;
+ PORT_SetError(SEC_ERROR_OCSP_NO_DEFAULT_RESPONDER);
+ return SECFailure;
}
if (statusContext->defaultResponderNickname == NULL) {
- PORT_SetError(SEC_ERROR_OCSP_NO_DEFAULT_RESPONDER);
- return SECFailure;
+ PORT_SetError(SEC_ERROR_OCSP_NO_DEFAULT_RESPONDER);
+ return SECFailure;
}
/*
* Find the cert for the nickname.
*/
cert = CERT_FindCertByNickname(handle,
- statusContext->defaultResponderNickname);
+ statusContext->defaultResponderNickname);
if (cert == NULL) {
cert = PK11_FindCertFromNickname(statusContext->defaultResponderNickname,
NULL);
@@ -6054,25 +5994,19 @@ CERT_EnableOCSPDefaultResponder(CERTCertDBHandle *handle)
*/
PORT_Assert(cert != NULL);
if (cert == NULL)
- return SECFailure;
+ 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.
- */
+ /*
+ * 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;
+ if (rv != SECSuccess || (usage & (certificateUsageSSLClient | certificateUsageSSLServer | certificateUsageSSLServerWithStepUp | certificateUsageEmailSigner | certificateUsageObjectSigner | certificateUsageStatusResponder | certificateUsageSSLCA)) == 0) {
+ PORT_SetError(SEC_ERROR_OCSP_RESPONDER_CERT_INVALID);
+ return SECFailure;
}
/*
@@ -6090,7 +6024,6 @@ CERT_EnableOCSPDefaultResponder(CERTCertDBHandle *handle)
return SECSuccess;
}
-
/*
* FUNCTION: CERT_DisableOCSPDefaultResponder
* Turns off use of a default responder when OCSP checking.
@@ -6111,23 +6044,23 @@ CERT_DisableOCSPDefaultResponder(CERTCertDBHandle *handle)
CERTCertificate *tmpCert;
if (handle == NULL) {
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- return SECFailure;
+ PORT_SetError(SEC_ERROR_INVALID_ARGS);
+ return SECFailure;
}
statusConfig = CERT_GetStatusConfig(handle);
if (statusConfig == NULL)
- return SECSuccess;
+ return SECSuccess;
statusContext = ocsp_GetCheckingContext(handle);
PORT_Assert(statusContext != NULL);
if (statusContext == NULL)
- return SECFailure;
+ return SECFailure;
tmpCert = statusContext->defaultResponderCert;
if (tmpCert) {
- statusContext->defaultResponderCert = NULL;
- CERT_DestroyCertificate(tmpCert);
+ statusContext->defaultResponderCert = NULL;
+ CERT_DestroyCertificate(tmpCert);
/* we don't allow a mix of cache entries from different responders */
CERT_ClearOCSPCache();
}
@@ -6159,29 +6092,29 @@ CERT_GetOCSPResponseStatus(CERTOCSPResponse *response)
{
PORT_Assert(response);
if (response->statusValue == ocspResponse_successful)
- return SECSuccess;
+ 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;
+ 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/nss/lib/certhigh/ocsp.h b/nss/lib/certhigh/ocsp.h
index 75225eb..ac9dd64 100644
--- a/nss/lib/certhigh/ocsp.h
+++ b/nss/lib/certhigh/ocsp.h
@@ -9,7 +9,6 @@
#ifndef _OCSP_H_
#define _OCSP_H_
-
#include "plarena.h"
#include "seccomon.h"
#include "secoidt.h"
@@ -17,7 +16,6 @@
#include "certt.h"
#include "ocspt.h"
-
/************************************************************************/
SEC_BEGIN_PROTOS
@@ -134,7 +132,7 @@ CERT_DisableOCSPChecking(CERTCertDBHandle *handle);
*/
extern SECStatus
CERT_SetOCSPDefaultResponder(CERTCertDBHandle *handle,
- const char *url, const char *name);
+ const char *url, const char *name);
/*
* FUNCTION: CERT_EnableOCSPDefaultResponder
@@ -174,7 +172,7 @@ CERT_DisableOCSPDefaultResponder(CERTCertDBHandle *handle);
/* If forcePost is set, OCSP requests will only be sent using the HTTP POST
* method. When forcePost is not set, OCSP requests will be sent using the
* HTTP GET method, with a fallback to POST when we fail to receive a response
- * and/or when we receive an uncacheable response like "Unknown."
+ * and/or when we receive an uncacheable response like "Unknown."
*
* The default is to use GET and fallback to POST.
*/
@@ -191,7 +189,7 @@ extern SECStatus CERT_ForcePostMethodForOCSP(PRBool forcePost);
/*
* FUNCTION: CERT_CreateOCSPRequest
- * Creates a CERTOCSPRequest, requesting the status of the certs in
+ * Creates a CERTOCSPRequest, requesting the status of the certs in
* the given list.
* INPUTS:
* CERTCertList *certList
@@ -203,7 +201,7 @@ extern SECStatus CERT_ForcePostMethodForOCSP(PRBool forcePost);
* 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
+ * 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
@@ -221,9 +219,9 @@ extern SECStatus CERT_ForcePostMethodForOCSP(PRBool forcePost);
* Other errors are low-level problems (no memory, bad database, etc.).
*/
extern CERTOCSPRequest *
-CERT_CreateOCSPRequest(CERTCertList *certList, PRTime time,
- PRBool addServiceLocator,
- CERTCertificate *signerCert);
+CERT_CreateOCSPRequest(CERTCertList *certList, PRTime time,
+ PRBool addServiceLocator,
+ CERTCertificate *signerCert);
/*
* FUNCTION: CERT_AddOCSPAcceptableResponses
@@ -243,13 +241,13 @@ CERT_CreateOCSPRequest(CERTCertList *certList, PRTime time,
*/
extern SECStatus
CERT_AddOCSPAcceptableResponses(CERTOCSPRequest *request,
- SECOidTag responseType0, ...);
+ 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:
+ * INPUTS:
* PLArenaPool *arena
* The return value is allocated from here.
* If a NULL is passed in, allocation is done from the heap instead.
@@ -264,8 +262,8 @@ CERT_AddOCSPAcceptableResponses(CERTOCSPRequest *request,
* (e.g. no memory).
*/
extern SECItem *
-CERT_EncodeOCSPRequest(PLArenaPool *arena, CERTOCSPRequest *request,
- void *pwArg);
+CERT_EncodeOCSPRequest(PLArenaPool *arena, CERTOCSPRequest *request,
+ void *pwArg);
/*
* FUNCTION: CERT_DecodeOCSPRequest
@@ -341,7 +339,7 @@ CERT_DestroyOCSPResponse(CERTOCSPResponse *response);
* const char *location
* The location of the OCSP responder (a URL).
* PRTime time
- * Indicates the time for which the certificate status is to be
+ * 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
@@ -369,10 +367,10 @@ CERT_DestroyOCSPResponse(CERTOCSPResponse *response);
*/
extern SECItem *
CERT_GetEncodedOCSPResponse(PLArenaPool *arena, CERTCertList *certList,
- const char *location, PRTime time,
- PRBool addServiceLocator,
- CERTCertificate *signerCert, void *pwArg,
- CERTOCSPRequest **pRequest);
+ const char *location, PRTime time,
+ PRBool addServiceLocator,
+ CERTCertificate *signerCert, void *pwArg,
+ CERTOCSPRequest **pRequest);
/*
* FUNCTION: CERT_VerifyOCSPResponseSignature
@@ -406,10 +404,10 @@ CERT_GetEncodedOCSPResponse(PLArenaPool *arena, CERTCertList *certList,
* 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);
+CERT_VerifyOCSPResponseSignature(CERTOCSPResponse *response,
+ CERTCertDBHandle *handle, void *pwArg,
+ CERTCertificate **pSignerCert,
+ CERTCertificate *issuerCert);
/*
* FUNCTION: CERT_GetOCSPAuthorityInfoAccessLocation
@@ -425,7 +423,7 @@ CERT_VerifyOCSPResponseSignature(CERTOCSPResponse *response,
* 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 *
@@ -433,21 +431,21 @@ CERT_GetOCSPAuthorityInfoAccessLocation(const 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
+ * 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
+ * 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
+ * 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);
+ CERT_StringFromCertFcn newCallback,
+ CERT_StringFromCertFcn *oldCallback);
/*
* FUNCTION: CERT_ParseURL
@@ -521,10 +519,10 @@ CERT_ParseURL(const char *url, char **pHostname, PRUint16 *pPort, char **pPath);
* (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
+ */
+extern SECStatus
CERT_CheckOCSPStatus(CERTCertDBHandle *handle, CERTCertificate *cert,
- PRTime time, void *pwArg);
+ PRTime time, void *pwArg);
/*
* FUNCTION: CERT_CacheOCSPResponseFromSideChannel
@@ -556,10 +554,10 @@ CERT_CheckOCSPStatus(CERTCertDBHandle *handle, CERTCertificate *cert,
*/
extern SECStatus
CERT_CacheOCSPResponseFromSideChannel(CERTCertDBHandle *handle,
- CERTCertificate *cert,
- PRTime time,
- const SECItem *encodedResponse,
- void *pwArg);
+ CERTCertificate *cert,
+ PRTime time,
+ const SECItem *encodedResponse,
+ void *pwArg);
/*
* FUNCTION: CERT_GetOCSPStatusForCertID
@@ -581,11 +579,11 @@ CERT_CacheOCSPResponseFromSideChannel(CERTCertDBHandle *handle,
* Return values are the same as those for CERT_CheckOCSPStatus
*/
extern SECStatus
-CERT_GetOCSPStatusForCertID(CERTCertDBHandle *handle,
- CERTOCSPResponse *response,
- CERTOCSPCertID *certID,
- CERTCertificate *signerCert,
- PRTime time);
+CERT_GetOCSPStatusForCertID(CERTCertDBHandle *handle,
+ CERTOCSPResponse *response,
+ CERTOCSPCertID *certID,
+ CERTCertificate *signerCert,
+ PRTime time);
/*
* FUNCTION CERT_GetOCSPResponseStatus
@@ -619,10 +617,10 @@ CERT_GetOCSPResponseStatus(CERTOCSPResponse *response);
* 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
+ * should be freed by calling CERT_DestroyOCSPCertID when the
* certID is no longer necessary.
*/
-extern CERTOCSPCertID*
+extern CERTOCSPCertID *
CERT_CreateOCSPCertID(CERTCertificate *cert, PRTime time);
/*
@@ -630,7 +628,7 @@ CERT_CreateOCSPCertID(CERTCertificate *cert, PRTime time);
* Frees the memory associated with the certID passed in.
* INPUTS:
* CERTOCSPCertID* certID
- * The certID that the caller no longer needs and wants to
+ * The certID that the caller no longer needs and wants to
* free the associated memory.
* RETURN:
* SECSuccess if freeing the memory was successful. Returns
@@ -638,31 +636,30 @@ CERT_CreateOCSPCertID(CERTCertificate *cert, PRTime time);
* a call to CERT_CreateOCSPCertID.
*/
extern SECStatus
-CERT_DestroyOCSPCertID(CERTOCSPCertID* certID);
-
+CERT_DestroyOCSPCertID(CERTOCSPCertID *certID);
-extern CERTOCSPSingleResponse*
+extern CERTOCSPSingleResponse *
CERT_CreateOCSPSingleResponseGood(PLArenaPool *arena,
CERTOCSPCertID *id,
PRTime thisUpdate,
const PRTime *nextUpdate);
-extern CERTOCSPSingleResponse*
+extern CERTOCSPSingleResponse *
CERT_CreateOCSPSingleResponseUnknown(PLArenaPool *arena,
CERTOCSPCertID *id,
PRTime thisUpdate,
const PRTime *nextUpdate);
-extern CERTOCSPSingleResponse*
+extern CERTOCSPSingleResponse *
CERT_CreateOCSPSingleResponseRevoked(
PLArenaPool *arena,
CERTOCSPCertID *id,
PRTime thisUpdate,
const PRTime *nextUpdate,
PRTime revocationTime,
- const CERTCRLEntryReasonCode* revocationReason);
+ const CERTCRLEntryReasonCode *revocationReason);
-extern SECItem*
+extern SECItem *
CERT_CreateEncodedOCSPSuccessResponse(
PLArenaPool *arena,
CERTCertificate *responderCert,
@@ -703,7 +700,7 @@ CERT_CreateEncodedOCSPSuccessResponse(
* SEC_ERROR_INVALID_ARGS
* Other errors are low-level problems (no memory, bad database, etc.).
*/
-extern SECItem*
+extern SECItem *
CERT_CreateEncodedOCSPErrorResponse(PLArenaPool *arena, int error);
/* Sends an OCSP request using the HTTP POST method to the location addressed
@@ -717,7 +714,7 @@ CERT_CreateEncodedOCSPErrorResponse(PLArenaPool *arena, int error);
* SEC_RegisterDefaultHttpClient then that client is used. Otherwise, an
* internal HTTP client is used.
*/
-SECItem* CERT_PostOCSPRequest(PLArenaPool *arena, const char *location,
+SECItem *CERT_PostOCSPRequest(PLArenaPool *arena, const char *location,
const SECItem *encodedRequest);
/************************************************************************/
diff --git a/nss/lib/certhigh/ocspi.h b/nss/lib/certhigh/ocspi.h
index 01c20da..c946d9f 100644
--- a/nss/lib/certhigh/ocspi.h
+++ b/nss/lib/certhigh/ocspi.h
@@ -35,13 +35,15 @@ ocsp_VerifyResponseSignature(CERTCertificate *signerCert,
void *pwArg);
CERTOCSPRequest *
-cert_CreateSingleCertOCSPRequest(CERTOCSPCertID *certID,
- CERTCertificate *singleCert,
+cert_CreateSingleCertOCSPRequest(CERTOCSPCertID *certID,
+ CERTCertificate *singleCert,
PRTime time,
PRBool addServiceLocator,
CERTCertificate *signerCert);
-typedef enum { ocspMissing, ocspFresh, ocspStale } OCSPFreshness;
+typedef enum { ocspMissing,
+ ocspFresh,
+ ocspStale } OCSPFreshness;
SECStatus
ocsp_GetCachedOCSPResponseStatus(CERTOCSPCertID *certID,
@@ -84,13 +86,13 @@ ocsp_GetCachedOCSPResponseStatus(CERTOCSPCertID *certID,
*/
SECStatus
-cert_ProcessOCSPResponse(CERTCertDBHandle *handle,
- CERTOCSPResponse *response,
- CERTOCSPCertID *certID,
- CERTCertificate *signerCert,
- PRTime time,
- PRBool *certIDWasConsumed,
- SECStatus *cacheUpdateStatus);
+cert_ProcessOCSPResponse(CERTCertDBHandle *handle,
+ CERTOCSPResponse *response,
+ CERTOCSPCertID *certID,
+ CERTCertificate *signerCert,
+ PRTime time,
+ PRBool *certIDWasConsumed,
+ SECStatus *cacheUpdateStatus);
/*
* FUNCTION: cert_RememberOCSPProcessingFailure
@@ -109,7 +111,7 @@ cert_ProcessOCSPResponse(CERTCertDBHandle *handle,
SECStatus
cert_RememberOCSPProcessingFailure(CERTOCSPCertID *certID,
- PRBool *certIDWasConsumed);
+ PRBool *certIDWasConsumed);
/*
* FUNCTION: ocsp_GetResponderLocation
@@ -146,11 +148,11 @@ size_t
ocsp_UrlEncodeBase64Buf(const char *base64Buf, char *outputBuf);
SECStatus
-ocsp_GetVerifiedSingleResponseForCertID(CERTCertDBHandle *handle,
- CERTOCSPResponse *response,
- CERTOCSPCertID *certID,
- CERTCertificate *signerCert,
- PRTime time,
+ocsp_GetVerifiedSingleResponseForCertID(CERTCertDBHandle *handle,
+ CERTOCSPResponse *response,
+ CERTOCSPCertID *certID,
+ CERTCertificate *signerCert,
+ PRTime time,
CERTOCSPSingleResponse **pSingleResponse);
SECStatus
@@ -158,7 +160,7 @@ ocsp_CertHasGoodStatus(ocspCertStatus *status, PRTime time);
void
ocsp_CacheSingleResponse(CERTOCSPCertID *certID,
- CERTOCSPSingleResponse *single,
- PRBool *certIDWasConsumed);
+ CERTOCSPSingleResponse *single,
+ PRBool *certIDWasConsumed);
#endif /* _OCSPI_H_ */
diff --git a/nss/lib/certhigh/ocspsig.c b/nss/lib/certhigh/ocspsig.c
index 0c4c201..94606ba 100644
--- a/nss/lib/certhigh/ocspsig.c
+++ b/nss/lib/certhigh/ocspsig.c
@@ -19,12 +19,11 @@
#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*
+ocspCertStatus *
ocsp_CreateCertStatus(PLArenaPool *arena,
ocspCertStatusType status,
PRTime revocationTime)
@@ -45,7 +44,7 @@ ocsp_CreateCertStatus(PLArenaPool *arena,
PORT_SetError(SEC_ERROR_INVALID_ARGS);
return NULL;
}
-
+
cs = PORT_ArenaZNew(arena, ocspCertStatus);
if (!cs)
return NULL;
@@ -71,8 +70,9 @@ ocsp_CreateCertStatus(PLArenaPool *arena,
if (!cs->certStatusInfo.revokedInfo->revocationReason)
return NULL;
if (DER_TimeToGeneralizedTimeArena(arena,
- &cs->certStatusInfo.revokedInfo->revocationTime,
- revocationTime) != SECSuccess)
+ &cs->certStatusInfo.revokedInfo->revocationTime,
+ revocationTime) !=
+ SECSuccess)
return NULL;
break;
default:
@@ -91,11 +91,11 @@ static const SEC_ASN1Template mySEC_PointerToEnumeratedTemplate[] = {
static const SEC_ASN1Template ocsp_EncodeRevokedInfoTemplate[] = {
{ SEC_ASN1_GENERALIZED_TIME,
- offsetof(ocspRevokedInfo, revocationTime) },
+ offsetof(ocspRevokedInfo, revocationTime) },
{ SEC_ASN1_OPTIONAL | SEC_ASN1_EXPLICIT |
- SEC_ASN1_CONSTRUCTED | SEC_ASN1_CONTEXT_SPECIFIC| 0,
- offsetof(ocspRevokedInfo, revocationReason),
- mySEC_PointerToEnumeratedTemplate },
+ SEC_ASN1_CONSTRUCTED | SEC_ASN1_CONTEXT_SPECIFIC | 0,
+ offsetof(ocspRevokedInfo, revocationReason),
+ mySEC_PointerToEnumeratedTemplate },
{ 0 }
};
@@ -110,26 +110,26 @@ static const SEC_ASN1Template mySEC_NullTemplate[] = {
static const SEC_ASN1Template ocsp_CertStatusTemplate[] = {
{ SEC_ASN1_CHOICE, offsetof(ocspCertStatus, certStatusType),
- 0, sizeof(ocspCertStatus) },
+ 0, sizeof(ocspCertStatus) },
{ SEC_ASN1_CONTEXT_SPECIFIC | 0,
- 0, mySEC_NullTemplate, ocspCertStatus_good },
+ 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 | 1,
+ offsetof(ocspCertStatus, certStatusInfo.revokedInfo),
+ ocsp_PointerToEncodeRevokedInfoTemplate, ocspCertStatus_revoked },
{ SEC_ASN1_CONTEXT_SPECIFIC | 2,
- 0, mySEC_NullTemplate, ocspCertStatus_unknown },
+ 0, mySEC_NullTemplate, ocspCertStatus_unknown },
{ 0 }
};
static const SEC_ASN1Template mySECOID_AlgorithmIDTemplate[] = {
{ SEC_ASN1_SEQUENCE,
- 0, NULL, sizeof(SECAlgorithmID) },
+ 0, NULL, sizeof(SECAlgorithmID) },
{ SEC_ASN1_OBJECT_ID,
- offsetof(SECAlgorithmID,algorithm), },
+ offsetof(SECAlgorithmID, algorithm) },
{ SEC_ASN1_OPTIONAL | SEC_ASN1_ANY,
- offsetof(SECAlgorithmID,parameters), },
- { 0, }
+ offsetof(SECAlgorithmID, parameters) },
+ { 0 }
};
static const SEC_ASN1Template mySEC_AnyTemplate[] = {
@@ -153,7 +153,7 @@ static const SEC_ASN1Template mySEC_PointerToIntegerTemplate[] = {
};
static const SEC_ASN1Template mySEC_GeneralizedTimeTemplate[] = {
- { SEC_ASN1_GENERALIZED_TIME | SEC_ASN1_MAY_STREAM, 0, NULL, sizeof(SECItem)}
+ { SEC_ASN1_GENERALIZED_TIME | SEC_ASN1_MAY_STREAM, 0, NULL, sizeof(SECItem) }
};
static const SEC_ASN1Template mySEC_PointerToGeneralizedTimeTemplate[] = {
@@ -162,29 +162,29 @@ static const SEC_ASN1Template mySEC_PointerToGeneralizedTimeTemplate[] = {
static const SEC_ASN1Template ocsp_myCertIDTemplate[] = {
{ SEC_ASN1_SEQUENCE,
- 0, NULL, sizeof(CERTOCSPCertID) },
+ 0, NULL, sizeof(CERTOCSPCertID) },
{ SEC_ASN1_INLINE,
- offsetof(CERTOCSPCertID, hashAlgorithm),
- mySECOID_AlgorithmIDTemplate },
+ offsetof(CERTOCSPCertID, hashAlgorithm),
+ mySECOID_AlgorithmIDTemplate },
{ SEC_ASN1_OCTET_STRING,
- offsetof(CERTOCSPCertID, issuerNameHash) },
+ offsetof(CERTOCSPCertID, issuerNameHash) },
{ SEC_ASN1_OCTET_STRING,
- offsetof(CERTOCSPCertID, issuerKeyHash) },
+ offsetof(CERTOCSPCertID, issuerKeyHash) },
{ SEC_ASN1_INTEGER,
- offsetof(CERTOCSPCertID, serialNumber) },
+ offsetof(CERTOCSPCertID, serialNumber) },
{ 0 }
};
static const SEC_ASN1Template myCERT_CertExtensionTemplate[] = {
{ SEC_ASN1_SEQUENCE,
- 0, NULL, sizeof(CERTCertExtension) },
+ 0, NULL, sizeof(CERTCertExtension) },
{ SEC_ASN1_OBJECT_ID,
- offsetof(CERTCertExtension,id) },
- { SEC_ASN1_OPTIONAL | SEC_ASN1_BOOLEAN, /* XXX DER_DEFAULT */
- offsetof(CERTCertExtension,critical) },
+ offsetof(CERTCertExtension, id) },
+ { SEC_ASN1_OPTIONAL | SEC_ASN1_BOOLEAN, /* XXX DER_DEFAULT */
+ offsetof(CERTCertExtension, critical) },
{ SEC_ASN1_OCTET_STRING,
- offsetof(CERTCertExtension,value) },
- { 0, }
+ offsetof(CERTCertExtension, value) },
+ { 0 }
};
static const SEC_ASN1Template myCERT_SequenceOfCertExtensionTemplate[] = {
@@ -197,66 +197,65 @@ static const SEC_ASN1Template myCERT_PointerToSequenceOfCertExtensionTemplate[]
static const SEC_ASN1Template ocsp_mySingleResponseTemplate[] = {
{ SEC_ASN1_SEQUENCE,
- 0, NULL, sizeof(CERTOCSPSingleResponse) },
+ 0, NULL, sizeof(CERTOCSPSingleResponse) },
{ SEC_ASN1_POINTER,
- offsetof(CERTOCSPSingleResponse, certID),
- ocsp_myCertIDTemplate },
+ offsetof(CERTOCSPSingleResponse, certID),
+ ocsp_myCertIDTemplate },
{ SEC_ASN1_ANY,
- offsetof(CERTOCSPSingleResponse, derCertStatus) },
+ offsetof(CERTOCSPSingleResponse, derCertStatus) },
{ SEC_ASN1_GENERALIZED_TIME,
- offsetof(CERTOCSPSingleResponse, thisUpdate) },
+ offsetof(CERTOCSPSingleResponse, thisUpdate) },
{ SEC_ASN1_OPTIONAL | SEC_ASN1_EXPLICIT |
- SEC_ASN1_CONSTRUCTED | SEC_ASN1_CONTEXT_SPECIFIC | 0,
- offsetof(CERTOCSPSingleResponse, nextUpdate),
- mySEC_PointerToGeneralizedTimeTemplate },
+ 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 },
+ 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 },
+ 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) },
+ offsetof(ocspResponseData, derResponderID) },
{ SEC_ASN1_GENERALIZED_TIME,
- offsetof(ocspResponseData, producedAt) },
+ offsetof(ocspResponseData, producedAt) },
{ SEC_ASN1_SEQUENCE_OF,
- offsetof(ocspResponseData, responses),
- ocsp_mySingleResponseTemplate },
+ offsetof(ocspResponseData, responses),
+ ocsp_mySingleResponseTemplate },
{ SEC_ASN1_OPTIONAL | SEC_ASN1_EXPLICIT |
- SEC_ASN1_CONSTRUCTED | SEC_ASN1_CONTEXT_SPECIFIC | 1,
- offsetof(ocspResponseData, responseExtensions),
- myCERT_PointerToSequenceOfCertExtensionTemplate },
+ 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) },
+ 0, NULL, sizeof(ocspBasicOCSPResponse) },
{ SEC_ASN1_POINTER,
- offsetof(ocspBasicOCSPResponse, tbsResponseData),
- ocsp_myResponseDataTemplate },
+ offsetof(ocspBasicOCSPResponse, tbsResponseData),
+ ocsp_myResponseDataTemplate },
{ SEC_ASN1_INLINE,
- offsetof(ocspBasicOCSPResponse, responseSignature.signatureAlgorithm),
- mySECOID_AlgorithmIDTemplate },
+ offsetof(ocspBasicOCSPResponse, responseSignature.signatureAlgorithm),
+ mySECOID_AlgorithmIDTemplate },
{ SEC_ASN1_BIT_STRING,
- offsetof(ocspBasicOCSPResponse, responseSignature.signature) },
+ offsetof(ocspBasicOCSPResponse, responseSignature.signature) },
{ SEC_ASN1_OPTIONAL | SEC_ASN1_EXPLICIT |
- SEC_ASN1_CONSTRUCTED | SEC_ASN1_CONTEXT_SPECIFIC | 0,
- offsetof(ocspBasicOCSPResponse, responseSignature.derCerts),
- mySEC_PointerToSequenceOfAnyTemplate },
+ SEC_ASN1_CONSTRUCTED | SEC_ASN1_CONTEXT_SPECIFIC | 0,
+ offsetof(ocspBasicOCSPResponse, responseSignature.derCerts),
+ mySEC_PointerToSequenceOfAnyTemplate },
{ 0 }
};
-static CERTOCSPSingleResponse*
+static CERTOCSPSingleResponse *
ocsp_CreateSingleResponse(PLArenaPool *arena,
CERTOCSPCertID *id, ocspCertStatus *status,
PRTime thisUpdate, const PRTime *nextUpdate)
@@ -274,25 +273,25 @@ ocsp_CreateSingleResponse(PLArenaPool *arena,
sr->arena = arena;
sr->certID = id;
sr->certStatus = status;
- if (DER_TimeToGeneralizedTimeArena(arena, &sr->thisUpdate, thisUpdate)
- != SECSuccess)
+ 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)
+ if (DER_TimeToGeneralizedTimeArena(arena, sr->nextUpdate, *nextUpdate) !=
+ SECSuccess)
return NULL;
}
- sr->singleExtensions = PORT_ArenaNewArray(arena, CERTCertExtension*, 1);
+ 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;
@@ -300,13 +299,13 @@ ocsp_CreateSingleResponse(PLArenaPool *arena,
return sr;
}
-CERTOCSPSingleResponse*
+CERTOCSPSingleResponse *
CERT_CreateOCSPSingleResponseGood(PLArenaPool *arena,
CERTOCSPCertID *id,
PRTime thisUpdate,
const PRTime *nextUpdate)
{
- ocspCertStatus * cs;
+ ocspCertStatus *cs;
if (!arena) {
PORT_SetError(SEC_ERROR_INVALID_ARGS);
return NULL;
@@ -317,13 +316,13 @@ CERT_CreateOCSPSingleResponseGood(PLArenaPool *arena,
return ocsp_CreateSingleResponse(arena, id, cs, thisUpdate, nextUpdate);
}
-CERTOCSPSingleResponse*
+CERTOCSPSingleResponse *
CERT_CreateOCSPSingleResponseUnknown(PLArenaPool *arena,
CERTOCSPCertID *id,
PRTime thisUpdate,
const PRTime *nextUpdate)
{
- ocspCertStatus * cs;
+ ocspCertStatus *cs;
if (!arena) {
PORT_SetError(SEC_ERROR_INVALID_ARGS);
return NULL;
@@ -334,16 +333,16 @@ CERT_CreateOCSPSingleResponseUnknown(PLArenaPool *arena,
return ocsp_CreateSingleResponse(arena, id, cs, thisUpdate, nextUpdate);
}
-CERTOCSPSingleResponse*
+CERTOCSPSingleResponse *
CERT_CreateOCSPSingleResponseRevoked(
PLArenaPool *arena,
CERTOCSPCertID *id,
PRTime thisUpdate,
const PRTime *nextUpdate,
PRTime revocationTime,
- const CERTCRLEntryReasonCode* revocationReason)
+ const CERTCRLEntryReasonCode *revocationReason)
{
- ocspCertStatus * cs;
+ ocspCertStatus *cs;
/* revocationReason is not yet supported, so it must be NULL. */
if (!arena || revocationReason) {
PORT_SetError(SEC_ERROR_INVALID_ARGS);
@@ -357,7 +356,7 @@ CERT_CreateOCSPSingleResponseRevoked(
/* responderCert == 0 means:
* create a response with an invalid signature (for testing purposes) */
-SECItem*
+SECItem *
CERT_CreateEncodedOCSPSuccessResponse(
PLArenaPool *arena,
CERTCertificate *responderCert,
@@ -373,12 +372,12 @@ CERT_CreateEncodedOCSPSuccessResponse(
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;
@@ -408,114 +407,112 @@ CERT_CreateEncodedOCSPSuccessResponse(
response = PORT_ArenaZNew(tmpArena, CERTOCSPResponse);
if (!response)
goto done;
-
- rd->version.data=NULL;
- rd->version.len=0;
+
+ rd->version.data = NULL;
+ rd->version.len = 0;
rd->responseExtensions = NULL;
rd->responses = responses;
- if (DER_TimeToGeneralizedTimeArena(tmpArena, &rd->producedAt, producedAt)
- != SECSuccess)
+ if (DER_TimeToGeneralizedTimeArena(tmpArena, &rd->producedAt, producedAt) !=
+ SECSuccess)
goto done;
if (!responderCert) {
- /* use invalid signature for testing purposes */
- unsigned 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_GetSubjectPublicKeyDigest(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. */
+ /* use invalid signature for testing purposes */
+ unsigned 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_GetSubjectPublicKeyDigest(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 (SECOID_SetAlgorithmID(tmpArena, &br->responseSignature.signatureAlgorithm, algID, 0) !=
+ SECSuccess)
+ goto done;
if (!SEC_ASN1EncodeItem(tmpArena, &rb->response, br,
ocsp_EncodeBasicOCSPResponseTemplate))
@@ -552,15 +549,15 @@ done:
static const SEC_ASN1Template ocsp_OCSPErrorResponseTemplate[] = {
{ SEC_ASN1_SEQUENCE,
- 0, NULL, sizeof(CERTOCSPResponse) },
+ 0, NULL, sizeof(CERTOCSPResponse) },
{ SEC_ASN1_ENUMERATED,
- offsetof(CERTOCSPResponse, responseStatus) },
+ offsetof(CERTOCSPResponse, responseStatus) },
{ 0, 0,
- mySEC_NullTemplate },
+ mySEC_NullTemplate },
{ 0 }
};
-SECItem*
+SECItem *
CERT_CreateEncodedOCSPErrorResponse(PLArenaPool *arena, int error)
{
CERTOCSPResponse response;
diff --git a/nss/lib/certhigh/ocspt.h b/nss/lib/certhigh/ocspt.h
index 888fd32..db429ff 100644
--- a/nss/lib/certhigh/ocspt.h
+++ b/nss/lib/certhigh/ocspt.h
@@ -46,8 +46,8 @@ typedef struct CERTOCSPSingleResponseStr CERTOCSPSingleResponse;
* dependent, and should be opaque to the user.
*/
-typedef void * SEC_HTTP_SERVER_SESSION;
-typedef void * SEC_HTTP_REQUEST_SESSION;
+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
@@ -61,9 +61,9 @@ typedef void * SEC_HTTP_REQUEST_SESSION;
* after processing is finished.
*/
typedef SECStatus (*SEC_HttpServer_CreateSessionFcn)(
- const char *host,
- PRUint16 portnum,
- SEC_HTTP_SERVER_SESSION *pSession);
+ const char *host,
+ PRUint16 portnum,
+ SEC_HTTP_SERVER_SESSION *pSession);
/*
* This function is called to allow the implementation to attempt to keep
@@ -77,10 +77,10 @@ typedef SECStatus (*SEC_HttpServer_CreateSessionFcn)(
* 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);
+ SEC_HTTP_SERVER_SESSION session,
+ PRPollDesc **pPollDesc);
/*
* This function frees the client SEC_HTTP_SERVER_SESSION object, closes all
@@ -88,9 +88,9 @@ typedef SECStatus (*SEC_HttpServer_KeepAliveSessionFcn)(
* 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);
+ SEC_HTTP_SERVER_SESSION session);
/*
* This function creates a SEC_HTTP_REQUEST_SESSION object. The implementer of a
@@ -111,30 +111,30 @@ typedef SECStatus (*SEC_HttpServer_FreeSessionFcn)(
* 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);
+ 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
+ * 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
+ * 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);
+ 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.
@@ -144,11 +144,11 @@ typedef SECStatus (*SEC_HttpRequest_SetPostDataFcn)(
*
* 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);
+ SEC_HTTP_REQUEST_SESSION request,
+ const char *http_header_name,
+ const char *http_header_value);
/*
* This function initiates or continues an HTTP request. After
@@ -180,10 +180,10 @@ typedef SECStatus (*SEC_HttpRequest_AddHeaderFcn)(
* 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
+ * 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
+ * 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.
@@ -195,64 +195,64 @@ typedef SECStatus (*SEC_HttpRequest_AddHeaderFcn)(
* the completion of the operation.
*
* All returned pointers will be owned by the the HttpClient
- * implementation and will remain valid until the call to
+ * 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);
+ 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
+ * 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
+ * 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);
+ 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
+ *
+ * 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);
+ 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_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;
+ PRInt16 version;
+ union {
+ SEC_HttpClientFcnV1 ftable1;
+ /* SEC_HttpClientFcnV2 ftable2; */
+ /* ... */
+ } fcnTable;
} SEC_HttpClientFcn;
/*
@@ -293,7 +293,7 @@ typedef enum {
*/
typedef enum {
- ocspResponderID_other = -1, /* unknown kind of responderID */
+ ocspResponderID_other = -1, /* unknown kind of responderID */
ocspResponderID_byName = 1,
ocspResponderID_byKey = 2
} CERTOCSPResponderIDType;
diff --git a/nss/lib/certhigh/ocspti.h b/nss/lib/certhigh/ocspti.h
index a2b3852..d9297db 100644
--- a/nss/lib/certhigh/ocspti.h
+++ b/nss/lib/certhigh/ocspti.h
@@ -16,7 +16,6 @@
#include "seccomon.h"
#include "secoidt.h"
-
/*
* Some notes about naming conventions...
*
@@ -49,7 +48,6 @@
* way around (reference before definition).
*/
-
/*
* Forward-declarations of internal-only data structures.
*
@@ -67,12 +65,11 @@ 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 {
- PLArenaPool *arena; /* local; not part of encoding */
+ PLArenaPool *arena; /* local; not part of encoding */
ocspTBSRequest *tbsRequest;
ocspSignature *optionalSignature;
};
@@ -92,12 +89,12 @@ struct CERTOCSPRequestStr {
* 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 */
+ 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 */
+ void *extensionHandle; /* local; not part of encoding */
};
/*
@@ -124,12 +121,12 @@ struct ocspTBSRequestStr {
*/
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 */
+ 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 */
};
/*
@@ -140,11 +137,11 @@ struct ocspSignatureStr {
* 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 {
- PLArenaPool *arena; /* just a copy of the response arena,
+ PLArenaPool *arena; /* just a copy of the response arena,
* needed here for extension handling
* routines, on creation only */
CERTOCSPCertID *reqCert;
@@ -160,14 +157,14 @@ struct ocspSingleRequestStr {
*/
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 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 issuerSHA1KeyHash; /* keep other hashes around when */
+ SECItem issuerMD5KeyHash; /* we have them */
SECItem issuerMD2KeyHash;
PLArenaPool *poolp;
};
@@ -209,10 +206,10 @@ typedef enum {
* type ocspResponseStatus.
*/
struct CERTOCSPResponseStr {
- PLArenaPool *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 */
+ PLArenaPool *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 */
};
/*
@@ -230,12 +227,12 @@ struct CERTOCSPResponseStr {
* 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 */
+ 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 */
+ ocspBasicOCSPResponse *basic; /* when type is id-pkix-ocsp-basic */
+ } decodedResponse; /* local; not part of encoding */
};
/*
@@ -250,7 +247,7 @@ struct ocspResponseBytesStr {
*/
struct ocspBasicOCSPResponseStr {
SECItem tbsResponseDataDER;
- ocspResponseData *tbsResponseData; /* "tbs" == To Be Signed */
+ ocspResponseData *tbsResponseData; /* "tbs" == To Be Signed */
ocspSignature responseSignature;
};
@@ -260,38 +257,38 @@ struct ocspBasicOCSPResponseStr {
* (a per-certificate status).
*/
struct ocspResponseDataStr {
- SECItem version; /* an INTEGER */
+ SECItem version; /* an INTEGER */
SECItem derResponderID;
- ocspResponderID *responderID; /* local; not part of encoding */
- SECItem producedAt; /* a GeneralizedTime */
+ ocspResponderID *responderID; /* local; not part of encoding */
+ SECItem producedAt; /* a GeneralizedTime */
CERTOCSPSingleResponse **responses;
CERTCertExtension **responseExtensions;
};
struct ocspResponderIDStr {
- CERTOCSPResponderIDType responderIDType;/* local; not part of encoding */
+ CERTOCSPResponderIDType responderIDType; /* local; not part of encoding */
union {
- CERTName name; /* when ocspResponderID_byName */
- SECItem keyHash; /* when ocspResponderID_byKey */
- SECItem other; /* when ocspResponderID_other */
+ 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 {
- PLArenaPool *arena; /* just a copy of the response arena,
+ PLArenaPool *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 */
+ ocspCertStatus *certStatus; /* local; not part of encoding */
+ SECItem thisUpdate; /* a GeneralizedTime */
+ SECItem *nextUpdate; /* a GeneralizedTime */
CERTCertExtension **singleExtensions;
};
@@ -313,10 +310,10 @@ struct CERTOCSPSingleResponseStr {
*/
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 */
+ 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;
/*
@@ -327,13 +324,13 @@ typedef enum {
* gives more detailed information.)
*/
struct ocspCertStatusStr {
- ocspCertStatusType certStatusType; /* local; not part of encoding */
+ 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;
+ SECItem *goodInfo; /* when ocspCertStatus_good */
+ ocspRevokedInfo *revokedInfo; /* when ocspCertStatus_revoked */
+ SECItem *unknownInfo; /* when ocspCertStatus_unknown */
+ SECItem *otherInfo; /* when ocspCertStatus_other */
+ } certStatusInfo;
};
/*
@@ -341,8 +338,8 @@ struct ocspCertStatusStr {
* was revoked and why.
*/
struct ocspRevokedInfoStr {
- SECItem revocationTime; /* a GeneralizedTime */
- SECItem *revocationReason; /* a CRLReason; ignored for now */
+ SECItem revocationTime; /* a GeneralizedTime */
+ SECItem *revocationReason; /* a CRLReason; ignored for now */
};
/*
@@ -353,7 +350,7 @@ struct ocspRevokedInfoStr {
*/
struct ocspServiceLocatorStr {
CERTName *issuer;
- SECItem locator; /* DER encoded authInfoAccess extension from cert */
+ SECItem locator; /* DER encoded authInfoAccess extension from cert */
};
#endif /* _OCSPTI_H_ */
diff --git a/nss/lib/certhigh/xcrldist.c b/nss/lib/certhigh/xcrldist.c
index 291a9d8..4f74cdb 100644
--- a/nss/lib/certhigh/xcrldist.c
+++ b/nss/lib/certhigh/xcrldist.c
@@ -12,203 +12,201 @@
SEC_ASN1_MKSUB(SEC_AnyTemplate)
SEC_ASN1_MKSUB(SEC_BitStringTemplate)
-extern void PrepareBitStringForEncoding (SECItem *bitMap, SECItem *value);
+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}
+ { 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}
+ { 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) },
+ 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 },
+ 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},
+ { 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}
+ { SEC_ASN1_SEQUENCE_OF, 0, CRLDistributionPointTemplate }
};
SECStatus
-CERT_EncodeCRLDistributionPoints (PLArenaPool *arena,
- CERTCrlDistributionPoints *value,
- SECItem *derValue)
+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);
+ 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;
-
- 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;
- }
+ 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;
+
+ 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);
+ PORT_FreeArena(ourPool, PR_FALSE);
return rv;
}
CERTCrlDistributionPoints *
-CERT_DecodeCRLDistributionPoints (PLArenaPool *arena, SECItem *encodedValue)
+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;
- }
+ 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);
+ 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/nss/lib/ckfw/builtins/Makefile b/nss/lib/ckfw/builtins/Makefile
index 8ca0d33..22726e2 100644
--- a/nss/lib/ckfw/builtins/Makefile
+++ b/nss/lib/ckfw/builtins/Makefile
@@ -51,4 +51,4 @@ endif
$(OBJDIR)/certdata.c: $(NSS_CERTDATA_TXT) certdata.perl
@$(MAKE_OBJDIR)
- $(PERL) certdata.perl < $(NSS_CERTDATA_TXT) > $@
+ $(PERL) certdata.perl $(NSS_CERTDATA_TXT) $@
diff --git a/nss/lib/ckfw/builtins/anchor.c b/nss/lib/ckfw/builtins/anchor.c
index 51b4a56..af21c6a 100644
--- a/nss/lib/ckfw/builtins/anchor.c
+++ b/nss/lib/ckfw/builtins/anchor.c
@@ -6,7 +6,7 @@
* 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
+ * shared library, which is required for dynamic loading. See the
* comments in nssck.api for more information.
*/
diff --git a/nss/lib/ckfw/builtins/bfind.c b/nss/lib/ckfw/builtins/bfind.c
index df35ed8..3e5da1a 100644
--- a/nss/lib/ckfw/builtins/bfind.c
+++ b/nss/lib/ckfw/builtins/bfind.c
@@ -14,258 +14,248 @@
*/
struct builtinsFOStr {
- NSSArena *arena;
- CK_ULONG n;
- CK_ULONG i;
- builtinsInternalObject **objs;
+ 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
-)
+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);
- }
+ 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;
+ 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
-)
+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;
+ struct builtinsFOStr *fo = (struct builtinsFOStr *)mdFindObjects->etc;
+ builtinsInternalObject *io;
- if( fo->i == fo->n ) {
- *pError = CKR_OK;
- return (NSSCKMDObject *)NULL;
- }
+ if (fo->i == fo->n) {
+ *pError = CKR_OK;
+ return (NSSCKMDObject *)NULL;
+ }
- io = fo->objs[ fo->i ];
- fo->i++;
+ io = fo->objs[fo->i];
+ fo->i++;
- return nss_builtins_CreateMDObject(arena, io, pError);
+ return nss_builtins_CreateMDObject(arena, io, pError);
}
static int
-builtins_derUnwrapInt(unsigned char *src, int size, unsigned char **dest) {
+builtins_derUnwrapInt(unsigned char *src, int size, unsigned char **dest)
+{
unsigned char *start = src;
int len = 0;
- if (*src ++ != 2) {
- return 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++;
- }
+ 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;
+ if (len + (src - start) != size) {
+ return 0;
}
*dest = src;
return len;
}
static CK_BBOOL
-builtins_attrmatch
-(
- CK_ATTRIBUTE_PTR a,
- const NSSItem *b
-)
+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 = NULL;
-
- len = builtins_derUnwrapInt(b->data,b->size,&data);
- if (data &&
- (len == a->ulValueLen) &&
- nsslibc_memequal(a->pValue, data, len, (PRStatus *)NULL)) {
- return CK_TRUE;
- }
+ 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 = NULL;
+
+ len = builtins_derUnwrapInt(b->data, b->size, &data);
+ if (data &&
+ (len == a->ulValueLen) &&
+ nsslibc_memequal(a->pValue, data, len, (PRStatus *)NULL)) {
+ return CK_TRUE;
+ }
+ }
+ return CK_FALSE;
}
- return CK_FALSE;
- }
- prb = nsslibc_memequal(a->pValue, b->data, b->size, (PRStatus *)NULL);
+ prb = nsslibc_memequal(a->pValue, b->data, b->size, (PRStatus *)NULL);
- if( PR_TRUE == prb ) {
- return CK_TRUE;
- } else {
- return CK_FALSE;
- }
+ 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
-)
+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;
+ 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;
+ if (j == o->n) {
+ /* Loop ran to the end: no matching attribute */
+ return CK_FALSE;
+ }
}
- }
- /* Every attribute passed */
- return CK_TRUE;
+ /* Every attribute passed */
+ return CK_TRUE;
}
NSS_IMPLEMENT NSSCKMDFindObjects *
-nss_builtins_FindObjectsInit
-(
- NSSCKFWSession *fwSession,
- CK_ATTRIBUTE_PTR pTemplate,
- CK_ULONG ulAttributeCount,
- CK_RV *pError
-)
+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;
+ /* This could be made more efficient. I'm rather rushed. */
+ NSSArena *arena;
+ NSSCKMDFindObjects *rv = (NSSCKMDFindObjects *)NULL;
+ struct builtinsFOStr *fo = (struct builtinsFOStr *)NULL;
- /*
+/*
* 99% of the time we get 0 or 1 matches. So we start with a small
* stack-allocated array to hold the matches and switch to a heap-allocated
* array later if the number of matches exceeds STACK_BUF_LENGTH.
*/
- #define STACK_BUF_LENGTH 1
- builtinsInternalObject *stackTemp[STACK_BUF_LENGTH];
- builtinsInternalObject **temp = stackTemp;
- PRBool tempIsHeapAllocated = PR_FALSE;
- 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;
-
- for( i = 0; i < nss_builtins_nObjects; i++ ) {
- builtinsInternalObject *o = (builtinsInternalObject *)&nss_builtins_data[i];
-
- if( CK_TRUE == builtins_match(pTemplate, ulAttributeCount, o) ) {
- if( fo->n == STACK_BUF_LENGTH ) {
- /* Switch from the small stack array to a heap-allocated array large
+#define STACK_BUF_LENGTH 1
+ builtinsInternalObject *stackTemp[STACK_BUF_LENGTH];
+ builtinsInternalObject **temp = stackTemp;
+ PRBool tempIsHeapAllocated = PR_FALSE;
+ 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;
+
+ for (i = 0; i < nss_builtins_nObjects; i++) {
+ builtinsInternalObject *o = (builtinsInternalObject *)&nss_builtins_data[i];
+
+ if (CK_TRUE == builtins_match(pTemplate, ulAttributeCount, o)) {
+ if (fo->n == STACK_BUF_LENGTH) {
+ /* Switch from the small stack array to a heap-allocated array large
* enough to handle matches in all remaining cases. */
- temp = nss_ZNEWARRAY((NSSArena *)NULL, builtinsInternalObject *,
- fo->n + nss_builtins_nObjects - i);
- if( (builtinsInternalObject **)NULL == temp ) {
- *pError = CKR_HOST_MEMORY;
- goto loser;
+ temp = nss_ZNEWARRAY((NSSArena *)NULL, builtinsInternalObject *,
+ fo->n + nss_builtins_nObjects - i);
+ if ((builtinsInternalObject **)NULL == temp) {
+ *pError =
+ CKR_HOST_MEMORY;
+ goto loser;
+ }
+ tempIsHeapAllocated = PR_TRUE;
+ (void)nsslibc_memcpy(temp, stackTemp,
+ sizeof(builtinsInternalObject *) * fo->n);
+ }
+
+ temp[fo->n] = o;
+ fo->n++;
}
- tempIsHeapAllocated = PR_TRUE;
- (void)nsslibc_memcpy(temp, stackTemp,
- sizeof(builtinsInternalObject *) * fo->n);
- }
+ }
- 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);
+ if (tempIsHeapAllocated) {
+ nss_ZFreeIf(temp);
+ temp = (builtinsInternalObject **)NULL;
}
- }
-
- 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);
- if (tempIsHeapAllocated) {
- nss_ZFreeIf(temp);
- temp = (builtinsInternalObject **)NULL;
- }
-
- return rv;
-
- loser:
- if (tempIsHeapAllocated) {
- nss_ZFreeIf(temp);
- }
- nss_ZFreeIf(fo);
- nss_ZFreeIf(rv);
- if ((NSSArena *)NULL != arena) {
- NSSArena_Destroy(arena);
- }
- return (NSSCKMDFindObjects *)NULL;
-}
+ return rv;
+
+loser:
+ if (tempIsHeapAllocated) {
+ nss_ZFreeIf(temp);
+ }
+ nss_ZFreeIf(fo);
+ nss_ZFreeIf(rv);
+ if ((NSSArena *)NULL != arena) {
+ NSSArena_Destroy(arena);
+ }
+ return (NSSCKMDFindObjects *)NULL;
+}
diff --git a/nss/lib/ckfw/builtins/binst.c b/nss/lib/ckfw/builtins/binst.c
index 8cb057d..ca1dac8 100644
--- a/nss/lib/ckfw/builtins/binst.c
+++ b/nss/lib/ckfw/builtins/binst.c
@@ -7,7 +7,7 @@
/*
* builtins/instance.c
*
- * This file implements the NSSCKMDInstance object for the
+ * This file implements the NSSCKMDInstance object for the
* "builtin objects" cryptoki module.
*/
@@ -16,84 +16,72 @@
*/
static CK_ULONG
-builtins_mdInstance_GetNSlots
-(
- NSSCKMDInstance *mdInstance,
- NSSCKFWInstance *fwInstance,
- CK_RV *pError
-)
+builtins_mdInstance_GetNSlots(
+ NSSCKMDInstance *mdInstance,
+ NSSCKFWInstance *fwInstance,
+ CK_RV *pError)
{
- return (CK_ULONG)1;
+ return (CK_ULONG)1;
}
static CK_VERSION
-builtins_mdInstance_GetCryptokiVersion
-(
- NSSCKMDInstance *mdInstance,
- NSSCKFWInstance *fwInstance
-)
+builtins_mdInstance_GetCryptokiVersion(
+ NSSCKMDInstance *mdInstance,
+ NSSCKFWInstance *fwInstance)
{
- return nss_builtins_CryptokiVersion;
+ return nss_builtins_CryptokiVersion;
}
static NSSUTF8 *
-builtins_mdInstance_GetManufacturerID
-(
- NSSCKMDInstance *mdInstance,
- NSSCKFWInstance *fwInstance,
- CK_RV *pError
-)
+builtins_mdInstance_GetManufacturerID(
+ NSSCKMDInstance *mdInstance,
+ NSSCKFWInstance *fwInstance,
+ CK_RV *pError)
{
- return (NSSUTF8 *)nss_builtins_ManufacturerID;
+ return (NSSUTF8 *)nss_builtins_ManufacturerID;
}
static NSSUTF8 *
-builtins_mdInstance_GetLibraryDescription
-(
- NSSCKMDInstance *mdInstance,
- NSSCKFWInstance *fwInstance,
- CK_RV *pError
-)
+builtins_mdInstance_GetLibraryDescription(
+ NSSCKMDInstance *mdInstance,
+ NSSCKFWInstance *fwInstance,
+ CK_RV *pError)
{
- return (NSSUTF8 *)nss_builtins_LibraryDescription;
+ return (NSSUTF8 *)nss_builtins_LibraryDescription;
}
static CK_VERSION
-builtins_mdInstance_GetLibraryVersion
-(
- NSSCKMDInstance *mdInstance,
- NSSCKFWInstance *fwInstance
-)
+builtins_mdInstance_GetLibraryVersion(
+ NSSCKMDInstance *mdInstance,
+ NSSCKFWInstance *fwInstance)
{
#define NSS_VERSION_VARIABLE __nss_builtins_version
#include "verref.h"
- return nss_builtins_LibraryVersion;
+ return nss_builtins_LibraryVersion;
}
static CK_RV
-builtins_mdInstance_GetSlots
-(
- NSSCKMDInstance *mdInstance,
- NSSCKFWInstance *fwInstance,
- NSSCKMDSlot *slots[]
-)
+builtins_mdInstance_GetSlots(
+ NSSCKMDInstance *mdInstance,
+ NSSCKFWInstance *fwInstance,
+ NSSCKMDSlot *slots[])
{
- slots[0] = (NSSCKMDSlot *)&nss_builtins_mdSlot;
- return CKR_OK;
+ 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 */
-};
+ 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/nss/lib/ckfw/builtins/bobject.c b/nss/lib/ckfw/builtins/bobject.c
index 55876c0..1c0babd 100644
--- a/nss/lib/ckfw/builtins/bobject.c
+++ b/nss/lib/ckfw/builtins/bobject.c
@@ -24,199 +24,183 @@
*/
static CK_RV
-builtins_mdObject_Destroy
-(
- NSSCKMDObject *mdObject,
- NSSCKFWObject *fwObject,
- NSSCKMDSession *mdSession,
- NSSCKFWSession *fwSession,
- NSSCKMDToken *mdToken,
- NSSCKFWToken *fwToken,
- NSSCKMDInstance *mdInstance,
- NSSCKFWInstance *fwInstance
-)
+builtins_mdObject_Destroy(
+ NSSCKMDObject *mdObject,
+ NSSCKFWObject *fwObject,
+ NSSCKMDSession *mdSession,
+ NSSCKFWSession *fwSession,
+ NSSCKMDToken *mdToken,
+ NSSCKFWToken *fwToken,
+ NSSCKMDInstance *mdInstance,
+ NSSCKFWInstance *fwInstance)
{
- return CKR_SESSION_READ_ONLY;
+ 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
-)
+builtins_mdObject_IsTokenObject(
+ NSSCKMDObject *mdObject,
+ NSSCKFWObject *fwObject,
+ NSSCKMDSession *mdSession,
+ NSSCKFWSession *fwSession,
+ NSSCKMDToken *mdToken,
+ NSSCKFWToken *fwToken,
+ NSSCKMDInstance *mdInstance,
+ NSSCKFWInstance *fwInstance)
{
- return CK_TRUE;
+ 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
-)
+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;
+ 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
-)
+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;
+ builtinsInternalObject *io = (builtinsInternalObject *)mdObject->etc;
+ CK_ULONG i;
- if( io->n != ulCount ) {
- return CKR_BUFFER_TOO_SMALL;
- }
+ if (io->n != ulCount) {
+ return CKR_BUFFER_TOO_SMALL;
+ }
- for( i = 0; i < io->n; i++ ) {
- typeArray[i] = io->types[i];
- }
+ for (i = 0; i < io->n; i++) {
+ typeArray[i] = io->types[i];
+ }
- return CKR_OK;
+ 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
-)
+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;
+ 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);
+ 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;
+ *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
-)
+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;
+ 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;
+ *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
-)
+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);
+ 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;
- }
+ for (i = 0; i < io->n; i++) {
+ rv += sizeof(CK_ATTRIBUTE_TYPE) + sizeof(NSSItem) + io->items[i].size;
+ }
- return rv;
+ 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 */
-};
+ 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
-)
+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;
- }
+ 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;
+ return &io->mdObject;
}
diff --git a/nss/lib/ckfw/builtins/bsession.c b/nss/lib/ckfw/builtins/bsession.c
index 6705bfc..6828a49 100644
--- a/nss/lib/ckfw/builtins/bsession.c
+++ b/nss/lib/ckfw/builtins/bsession.c
@@ -7,69 +7,65 @@
/*
* builtins/session.c
*
- * This file implements the NSSCKMDSession object for the
+ * 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
-)
+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);
+ return nss_builtins_FindObjectsInit(fwSession, pTemplate, ulAttributeCount, pError);
}
NSS_IMPLEMENT NSSCKMDSession *
-nss_builtins_CreateSession
-(
- NSSCKFWSession *fwSession,
- CK_RV *pError
-)
+nss_builtins_CreateSession(
+ NSSCKFWSession *fwSession,
+ CK_RV *pError)
{
- NSSArena *arena;
- NSSCKMDSession *rv;
+ NSSArena *arena;
+ NSSCKMDSession *rv;
- arena = NSSCKFWSession_GetArena(fwSession, pError);
- if( (NSSArena *)NULL == arena ) {
- return (NSSCKMDSession *)NULL;
- }
+ 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 = 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 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 */
+ 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;
+ return rv;
}
diff --git a/nss/lib/ckfw/builtins/bslot.c b/nss/lib/ckfw/builtins/bslot.c
index 7cc9dcd..f2ef1ef 100644
--- a/nss/lib/ckfw/builtins/bslot.c
+++ b/nss/lib/ckfw/builtins/bslot.c
@@ -12,80 +12,70 @@
*/
static NSSUTF8 *
-builtins_mdSlot_GetSlotDescription
-(
- NSSCKMDSlot *mdSlot,
- NSSCKFWSlot *fwSlot,
- NSSCKMDInstance *mdInstance,
- NSSCKFWInstance *fwInstance,
- CK_RV *pError
-)
+builtins_mdSlot_GetSlotDescription(
+ NSSCKMDSlot *mdSlot,
+ NSSCKFWSlot *fwSlot,
+ NSSCKMDInstance *mdInstance,
+ NSSCKFWInstance *fwInstance,
+ CK_RV *pError)
{
- return (NSSUTF8 *)nss_builtins_SlotDescription;
+ return (NSSUTF8 *)nss_builtins_SlotDescription;
}
static NSSUTF8 *
-builtins_mdSlot_GetManufacturerID
-(
- NSSCKMDSlot *mdSlot,
- NSSCKFWSlot *fwSlot,
- NSSCKMDInstance *mdInstance,
- NSSCKFWInstance *fwInstance,
- CK_RV *pError
-)
+builtins_mdSlot_GetManufacturerID(
+ NSSCKMDSlot *mdSlot,
+ NSSCKFWSlot *fwSlot,
+ NSSCKMDInstance *mdInstance,
+ NSSCKFWInstance *fwInstance,
+ CK_RV *pError)
{
- return (NSSUTF8 *)nss_builtins_ManufacturerID;
+ return (NSSUTF8 *)nss_builtins_ManufacturerID;
}
static CK_VERSION
-builtins_mdSlot_GetHardwareVersion
-(
- NSSCKMDSlot *mdSlot,
- NSSCKFWSlot *fwSlot,
- NSSCKMDInstance *mdInstance,
- NSSCKFWInstance *fwInstance
-)
+builtins_mdSlot_GetHardwareVersion(
+ NSSCKMDSlot *mdSlot,
+ NSSCKFWSlot *fwSlot,
+ NSSCKMDInstance *mdInstance,
+ NSSCKFWInstance *fwInstance)
{
- return nss_builtins_HardwareVersion;
+ return nss_builtins_HardwareVersion;
}
static CK_VERSION
-builtins_mdSlot_GetFirmwareVersion
-(
- NSSCKMDSlot *mdSlot,
- NSSCKFWSlot *fwSlot,
- NSSCKMDInstance *mdInstance,
- NSSCKFWInstance *fwInstance
-)
+builtins_mdSlot_GetFirmwareVersion(
+ NSSCKMDSlot *mdSlot,
+ NSSCKFWSlot *fwSlot,
+ NSSCKMDInstance *mdInstance,
+ NSSCKFWInstance *fwInstance)
{
- return nss_builtins_FirmwareVersion;
+ return nss_builtins_FirmwareVersion;
}
static NSSCKMDToken *
-builtins_mdSlot_GetToken
-(
- NSSCKMDSlot *mdSlot,
- NSSCKFWSlot *fwSlot,
- NSSCKMDInstance *mdInstance,
- NSSCKFWInstance *fwInstance,
- CK_RV *pError
-)
+builtins_mdSlot_GetToken(
+ NSSCKMDSlot *mdSlot,
+ NSSCKFWSlot *fwSlot,
+ NSSCKMDInstance *mdInstance,
+ NSSCKFWInstance *fwInstance,
+ CK_RV *pError)
{
- return (NSSCKMDToken *)&nss_builtins_mdToken;
+ 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 */
-};
+ 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/nss/lib/ckfw/builtins/btoken.c b/nss/lib/ckfw/builtins/btoken.c
index a68d511..ae1e138 100644
--- a/nss/lib/ckfw/builtins/btoken.c
+++ b/nss/lib/ckfw/builtins/btoken.c
@@ -12,140 +12,124 @@
*/
static NSSUTF8 *
-builtins_mdToken_GetLabel
-(
- NSSCKMDToken *mdToken,
- NSSCKFWToken *fwToken,
- NSSCKMDInstance *mdInstance,
- NSSCKFWInstance *fwInstance,
- CK_RV *pError
-)
+builtins_mdToken_GetLabel(
+ NSSCKMDToken *mdToken,
+ NSSCKFWToken *fwToken,
+ NSSCKMDInstance *mdInstance,
+ NSSCKFWInstance *fwInstance,
+ CK_RV *pError)
{
- return (NSSUTF8 *)nss_builtins_TokenLabel;
+ return (NSSUTF8 *)nss_builtins_TokenLabel;
}
static NSSUTF8 *
-builtins_mdToken_GetManufacturerID
-(
- NSSCKMDToken *mdToken,
- NSSCKFWToken *fwToken,
- NSSCKMDInstance *mdInstance,
- NSSCKFWInstance *fwInstance,
- CK_RV *pError
-)
+builtins_mdToken_GetManufacturerID(
+ NSSCKMDToken *mdToken,
+ NSSCKFWToken *fwToken,
+ NSSCKMDInstance *mdInstance,
+ NSSCKFWInstance *fwInstance,
+ CK_RV *pError)
{
- return (NSSUTF8 *)nss_builtins_ManufacturerID;
+ return (NSSUTF8 *)nss_builtins_ManufacturerID;
}
static NSSUTF8 *
-builtins_mdToken_GetModel
-(
- NSSCKMDToken *mdToken,
- NSSCKFWToken *fwToken,
- NSSCKMDInstance *mdInstance,
- NSSCKFWInstance *fwInstance,
- CK_RV *pError
-)
+builtins_mdToken_GetModel(
+ NSSCKMDToken *mdToken,
+ NSSCKFWToken *fwToken,
+ NSSCKMDInstance *mdInstance,
+ NSSCKFWInstance *fwInstance,
+ CK_RV *pError)
{
- return (NSSUTF8 *)nss_builtins_TokenModel;
+ return (NSSUTF8 *)nss_builtins_TokenModel;
}
static NSSUTF8 *
-builtins_mdToken_GetSerialNumber
-(
- NSSCKMDToken *mdToken,
- NSSCKFWToken *fwToken,
- NSSCKMDInstance *mdInstance,
- NSSCKFWInstance *fwInstance,
- CK_RV *pError
-)
+builtins_mdToken_GetSerialNumber(
+ NSSCKMDToken *mdToken,
+ NSSCKFWToken *fwToken,
+ NSSCKMDInstance *mdInstance,
+ NSSCKFWInstance *fwInstance,
+ CK_RV *pError)
{
- return (NSSUTF8 *)nss_builtins_TokenSerialNumber;
+ return (NSSUTF8 *)nss_builtins_TokenSerialNumber;
}
static CK_BBOOL
-builtins_mdToken_GetIsWriteProtected
-(
- NSSCKMDToken *mdToken,
- NSSCKFWToken *fwToken,
- NSSCKMDInstance *mdInstance,
- NSSCKFWInstance *fwInstance
-)
+builtins_mdToken_GetIsWriteProtected(
+ NSSCKMDToken *mdToken,
+ NSSCKFWToken *fwToken,
+ NSSCKMDInstance *mdInstance,
+ NSSCKFWInstance *fwInstance)
{
- return CK_TRUE;
+ return CK_TRUE;
}
static CK_VERSION
-builtins_mdToken_GetHardwareVersion
-(
- NSSCKMDToken *mdToken,
- NSSCKFWToken *fwToken,
- NSSCKMDInstance *mdInstance,
- NSSCKFWInstance *fwInstance
-)
+builtins_mdToken_GetHardwareVersion(
+ NSSCKMDToken *mdToken,
+ NSSCKFWToken *fwToken,
+ NSSCKMDInstance *mdInstance,
+ NSSCKFWInstance *fwInstance)
{
- return nss_builtins_HardwareVersion;
+ return nss_builtins_HardwareVersion;
}
static CK_VERSION
-builtins_mdToken_GetFirmwareVersion
-(
- NSSCKMDToken *mdToken,
- NSSCKFWToken *fwToken,
- NSSCKMDInstance *mdInstance,
- NSSCKFWInstance *fwInstance
-)
+builtins_mdToken_GetFirmwareVersion(
+ NSSCKMDToken *mdToken,
+ NSSCKFWToken *fwToken,
+ NSSCKMDInstance *mdInstance,
+ NSSCKFWInstance *fwInstance)
{
- return nss_builtins_FirmwareVersion;
+ 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
-)
+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);
+ 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 */
-};
+ 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/nss/lib/ckfw/builtins/builtins.gyp b/nss/lib/ckfw/builtins/builtins.gyp
new file mode 100644
index 0000000..d854425
--- /dev/null
+++ b/nss/lib/ckfw/builtins/builtins.gyp
@@ -0,0 +1,61 @@
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+{
+ 'includes': [
+ '../../../coreconf/config.gypi'
+ ],
+ 'targets': [
+ {
+ 'target_name': 'nssckbi',
+ 'type': 'shared_library',
+ 'sources': [
+ 'anchor.c',
+ 'bfind.c',
+ 'binst.c',
+ 'bobject.c',
+ 'bsession.c',
+ 'bslot.c',
+ 'btoken.c',
+ 'ckbiver.c',
+ 'constants.c',
+ '<(INTERMEDIATE_DIR)/certdata.c'
+ ],
+ 'dependencies': [
+ '<(DEPTH)/exports.gyp:nss_exports',
+ '<(DEPTH)/lib/ckfw/ckfw.gyp:nssckfw',
+ '<(DEPTH)/lib/base/base.gyp:nssb'
+ ],
+ 'actions': [
+ {
+ 'msvs_cygwin_shell': 0,
+ 'action': [
+ 'perl',
+ 'certdata.perl',
+ 'certdata.txt',
+ '<@(_outputs)',
+ ],
+ 'inputs': [
+ 'certdata.perl',
+ 'certdata.txt'
+ ],
+ 'outputs': [
+ '<(INTERMEDIATE_DIR)/certdata.c'
+ ],
+ 'action_name': 'generate_certdata_c'
+ }
+ ],
+ 'variables': {
+ 'mapfile': 'nssckbi.def'
+ }
+ }
+ ],
+ 'target_defaults': {
+ 'include_dirs': [
+ '.'
+ ]
+ },
+ 'variables': {
+ 'module': 'nss',
+ }
+}
diff --git a/nss/lib/ckfw/builtins/builtins.h b/nss/lib/ckfw/builtins/builtins.h
index a4a90f1..a1693c2 100644
--- a/nss/lib/ckfw/builtins/builtins.h
+++ b/nss/lib/ckfw/builtins/builtins.h
@@ -21,52 +21,46 @@
#endif /* CKT_H */
struct builtinsInternalObjectStr {
- CK_ULONG n;
- const CK_ATTRIBUTE_TYPE *types;
- const NSSItem *items;
- NSSCKMDObject mdObject;
+ 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 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 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 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;
+extern const NSSCKMDSlot nss_builtins_mdSlot;
+extern const NSSCKMDToken nss_builtins_mdToken;
NSS_EXTERN NSSCKMDSession *
-nss_builtins_CreateSession
-(
- NSSCKFWSession *fwSession,
- CK_RV *pError
-);
+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_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
-);
+nss_builtins_CreateMDObject(
+ NSSArena *arena,
+ builtinsInternalObject *io,
+ CK_RV *pError);
diff --git a/nss/lib/ckfw/builtins/certdata.perl b/nss/lib/ckfw/builtins/certdata.perl
index e77decf..502dfb0 100644
--- a/nss/lib/ckfw/builtins/certdata.perl
+++ b/nss/lib/ckfw/builtins/certdata.perl
@@ -14,6 +14,18 @@ my @objsize;
$constants{CK_TRUE} = "static const CK_BBOOL ck_true = CK_TRUE;\n";
$constants{CK_FALSE} = "static const CK_BBOOL ck_false = CK_FALSE;\n";
+if( scalar @ARGV == 0 ) {
+ print STDERR "Usage: $0 <input-file> [output-file]\n";
+ exit 1;
+}
+
+open(STDIN, '<', $ARGV[0])
+ or die "Could not open input file '$ARGV[0]' $!";
+if( scalar @ARGV > 1 ) {
+ open(STDOUT, '>', $ARGV[1])
+ or die "Could not open output file '$ARGV[1]' $!";
+}
+
while(<>) {
my @fields = ();
my $size;
diff --git a/nss/lib/ckfw/builtins/certdata.txt b/nss/lib/ckfw/builtins/certdata.txt
index d6d4b4f..24df334 100644
--- a/nss/lib/ckfw/builtins/certdata.txt
+++ b/nss/lib/ckfw/builtins/certdata.txt
@@ -69,129 +69,6 @@ CKA_PRIVATE CK_BBOOL CK_FALSE
CKA_MODIFIABLE CK_BBOOL CK_FALSE
CKA_LABEL UTF8 "Mozilla Builtin Roots"
-#
-# Certificate "Equifax Secure CA"
-#
-# Issuer: OU=Equifax Secure Certificate Authority,O=Equifax,C=US
-# Serial Number: 903804111 (0x35def4cf)
-# Subject: OU=Equifax Secure Certificate Authority,O=Equifax,C=US
-# Not Valid Before: Sat Aug 22 16:41:51 1998
-# Not Valid After : Wed Aug 22 16:41:51 2018
-# Fingerprint (MD5): 67:CB:9D:C0:13:24:8A:82:9B:B2:17:1E:D1:1B:EC:D4
-# Fingerprint (SHA1): D2:32:09:AD:23:D3:14:23:21:74:E4:0D:7F:9D:62:13:97:86:63:3A
-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"
-# Issuer: OU=Equifax Secure Certificate Authority,O=Equifax,C=US
-# Serial Number: 903804111 (0x35def4cf)
-# Subject: OU=Equifax Secure Certificate Authority,O=Equifax,C=US
-# Not Valid Before: Sat Aug 22 16:41:51 1998
-# Not Valid After : Wed Aug 22 16:41:51 2018
-# Fingerprint (MD5): 67:CB:9D:C0:13:24:8A:82:9B:B2:17:1E:D1:1B:EC:D4
-# Fingerprint (SHA1): D2:32:09:AD:23:D3:14:23:21:74:E4:0D:7F:9D:62:13:97:86:63:3A
-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_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
-
# Distrust "Distrust a pb.com certificate that does not comply with the baseline requirements."
# Issuer: OU=Equifax Secure Certificate Authority,O=Equifax,C=US
# Serial Number: 1407252 (0x157914)
@@ -221,563 +98,6 @@ CKA_TRUST_CODE_SIGNING CK_TRUST CKT_NSS_NOT_TRUSTED
CKA_TRUST_STEP_UP_APPROVED CK_BBOOL CK_FALSE
#
-# Certificate "Verisign Class 3 Public Primary Certification Authority"
-#
-# Issuer: OU=Class 3 Public Primary Certification Authority,O="VeriSign, Inc.",C=US
-# Serial Number:70:ba:e4:1d:10:d9:29:34:b6:38:ca:7b:03:cc:ba:bf
-# Subject: OU=Class 3 Public Primary Certification Authority,O="VeriSign, Inc.",C=US
-# Not Valid Before: Mon Jan 29 00:00:00 1996
-# Not Valid After : Tue Aug 01 23:59:59 2028
-# Fingerprint (MD5): 10:FC:63:5D:F6:26:3E:0D:F3:25:BE:5F:79:CD:67:67
-# Fingerprint (SHA1): 74:2C:31:92:E6:07:E4:24:EB:45:49:54:2B:E1:BB:C5:3E:61:74:E2
-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"
-# Issuer: OU=Class 3 Public Primary Certification Authority,O="VeriSign, Inc.",C=US
-# Serial Number:70:ba:e4:1d:10:d9:29:34:b6:38:ca:7b:03:cc:ba:bf
-# Subject: OU=Class 3 Public Primary Certification Authority,O="VeriSign, Inc.",C=US
-# Not Valid Before: Mon Jan 29 00:00:00 1996
-# Not Valid After : Tue Aug 01 23:59:59 2028
-# Fingerprint (MD5): 10:FC:63:5D:F6:26:3E:0D:F3:25:BE:5F:79:CD:67:67
-# Fingerprint (SHA1): 74:2C:31:92:E6:07:E4:24:EB:45:49:54:2B:E1:BB:C5:3E:61:74:E2
-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_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 1 Public Primary Certification Authority - G2"
-#
-# Issuer: OU=VeriSign Trust Network,OU="(c) 1998 VeriSign, Inc. - For authorized use only",OU=Class 1 Public Primary Certification Authority - G2,O="VeriSign, Inc.",C=US
-# Serial Number:4c:c7:ea:aa:98:3e:71:d3:93:10:f8:3d:3a:89:91:92
-# Subject: OU=VeriSign Trust Network,OU="(c) 1998 VeriSign, Inc. - For authorized use only",OU=Class 1 Public Primary Certification Authority - G2,O="VeriSign, Inc.",C=US
-# Not Valid Before: Mon May 18 00:00:00 1998
-# Not Valid After : Tue Aug 01 23:59:59 2028
-# Fingerprint (MD5): DB:23:3D:F9:69:FA:4B:B9:95:80:44:73:5E:7D:41:83
-# Fingerprint (SHA1): 27:3E:E1:24:57:FD:C4:F9:0C:55:E8:2B:56:16:7F:62:F5:32:E5:47
-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"
-# Issuer: OU=VeriSign Trust Network,OU="(c) 1998 VeriSign, Inc. - For authorized use only",OU=Class 1 Public Primary Certification Authority - G2,O="VeriSign, Inc.",C=US
-# Serial Number:4c:c7:ea:aa:98:3e:71:d3:93:10:f8:3d:3a:89:91:92
-# Subject: OU=VeriSign Trust Network,OU="(c) 1998 VeriSign, Inc. - For authorized use only",OU=Class 1 Public Primary Certification Authority - G2,O="VeriSign, Inc.",C=US
-# Not Valid Before: Mon May 18 00:00:00 1998
-# Not Valid After : Tue Aug 01 23:59:59 2028
-# Fingerprint (MD5): DB:23:3D:F9:69:FA:4B:B9:95:80:44:73:5E:7D:41:83
-# Fingerprint (SHA1): 27:3E:E1:24:57:FD:C4:F9:0C:55:E8:2B:56:16:7F:62:F5:32:E5:47
-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"
-#
-# Issuer: OU=VeriSign Trust Network,OU="(c) 1998 VeriSign, Inc. - For authorized use only",OU=Class 2 Public Primary Certification Authority - G2,O="VeriSign, Inc.",C=US
-# Serial Number:00:b9:2f:60:cc:88:9f:a1:7a:46:09:b8:5b:70:6c:8a:af
-# Subject: OU=VeriSign Trust Network,OU="(c) 1998 VeriSign, Inc. - For authorized use only",OU=Class 2 Public Primary Certification Authority - G2,O="VeriSign, Inc.",C=US
-# Not Valid Before: Mon May 18 00:00:00 1998
-# Not Valid After : Tue Aug 01 23:59:59 2028
-# Fingerprint (MD5): 2D:BB:E5:25:D3:D1:65:82:3A:B7:0E:FA:E6:EB:E2:E1
-# Fingerprint (SHA1): B3:EA:C4:47:76:C9:C8:1C:EA:F2:9D:95:B6:CC:A0:08:1B:67:EC:9D
-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"
-# Issuer: OU=VeriSign Trust Network,OU="(c) 1998 VeriSign, Inc. - For authorized use only",OU=Class 2 Public Primary Certification Authority - G2,O="VeriSign, Inc.",C=US
-# Serial Number:00:b9:2f:60:cc:88:9f:a1:7a:46:09:b8:5b:70:6c:8a:af
-# Subject: OU=VeriSign Trust Network,OU="(c) 1998 VeriSign, Inc. - For authorized use only",OU=Class 2 Public Primary Certification Authority - G2,O="VeriSign, Inc.",C=US
-# Not Valid Before: Mon May 18 00:00:00 1998
-# Not Valid After : Tue Aug 01 23:59:59 2028
-# Fingerprint (MD5): 2D:BB:E5:25:D3:D1:65:82:3A:B7:0E:FA:E6:EB:E2:E1
-# Fingerprint (SHA1): B3:EA:C4:47:76:C9:C8:1C:EA:F2:9D:95:B6:CC:A0:08:1B:67:EC:9D
-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_MUST_VERIFY_TRUST
-CKA_TRUST_STEP_UP_APPROVED CK_BBOOL CK_FALSE
-
-#
-# Certificate "Verisign Class 3 Public Primary Certification Authority - G2"
-#
-# Issuer: OU=VeriSign Trust Network,OU="(c) 1998 VeriSign, Inc. - For authorized use only",OU=Class 3 Public Primary Certification Authority - G2,O="VeriSign, Inc.",C=US
-# Serial Number:7d:d9:fe:07:cf:a8:1e:b7:10:79:67:fb:a7:89:34:c6
-# Subject: OU=VeriSign Trust Network,OU="(c) 1998 VeriSign, Inc. - For authorized use only",OU=Class 3 Public Primary Certification Authority - G2,O="VeriSign, Inc.",C=US
-# Not Valid Before: Mon May 18 00:00:00 1998
-# Not Valid After : Tue Aug 01 23:59:59 2028
-# Fingerprint (MD5): A2:33:9B:4C:74:78:73:D4:6C:E7:C1:F3:8D:CB:5C:E9
-# Fingerprint (SHA1): 85:37:1C:A6:E5:50:14:3D:CE:28:03:47:1B:DE:3A:09:E8:F8:77:0F
-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"
-# Issuer: OU=VeriSign Trust Network,OU="(c) 1998 VeriSign, Inc. - For authorized use only",OU=Class 3 Public Primary Certification Authority - G2,O="VeriSign, Inc.",C=US
-# Serial Number:7d:d9:fe:07:cf:a8:1e:b7:10:79:67:fb:a7:89:34:c6
-# Subject: OU=VeriSign Trust Network,OU="(c) 1998 VeriSign, Inc. - For authorized use only",OU=Class 3 Public Primary Certification Authority - G2,O="VeriSign, Inc.",C=US
-# Not Valid Before: Mon May 18 00:00:00 1998
-# Not Valid After : Tue Aug 01 23:59:59 2028
-# Fingerprint (MD5): A2:33:9B:4C:74:78:73:D4:6C:E7:C1:F3:8D:CB:5C:E9
-# Fingerprint (SHA1): 85:37:1C:A6:E5:50:14:3D:CE:28:03:47:1B:DE:3A:09:E8:F8:77:0F
-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_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 "GlobalSign Root CA"
#
# Issuer: CN=GlobalSign Root CA,OU=Root CA,O=GlobalSign nv-sa,C=BE
@@ -1936,239 +1256,6 @@ 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"
-#
-# Issuer: CN=Equifax Secure Global eBusiness CA-1,O=Equifax Secure Inc.,C=US
-# Serial Number: 1 (0x1)
-# Subject: CN=Equifax Secure Global eBusiness CA-1,O=Equifax Secure Inc.,C=US
-# Not Valid Before: Mon Jun 21 04:00:00 1999
-# Not Valid After : Sun Jun 21 04:00:00 2020
-# Fingerprint (MD5): 8F:5D:77:06:27:C4:98:3C:5B:93:78:E7:D7:7D:9B:CC
-# Fingerprint (SHA1): 7E:78:4A:10:1C:82:65:CC:2D:E1:F1:6D:47:B4:40:CA:D9:0A:19:45
-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"
-# Issuer: CN=Equifax Secure Global eBusiness CA-1,O=Equifax Secure Inc.,C=US
-# Serial Number: 1 (0x1)
-# Subject: CN=Equifax Secure Global eBusiness CA-1,O=Equifax Secure Inc.,C=US
-# Not Valid Before: Mon Jun 21 04:00:00 1999
-# Not Valid After : Sun Jun 21 04:00:00 2020
-# Fingerprint (MD5): 8F:5D:77:06:27:C4:98:3C:5B:93:78:E7:D7:7D:9B:CC
-# Fingerprint (SHA1): 7E:78:4A:10:1C:82:65:CC:2D:E1:F1:6D:47:B4:40:CA:D9:0A:19:45
-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_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 "Equifax Secure eBusiness CA 1"
-#
-# Issuer: CN=Equifax Secure eBusiness CA-1,O=Equifax Secure Inc.,C=US
-# Serial Number: 4 (0x4)
-# Subject: CN=Equifax Secure eBusiness CA-1,O=Equifax Secure Inc.,C=US
-# Not Valid Before: Mon Jun 21 04:00:00 1999
-# Not Valid After : Sun Jun 21 04:00:00 2020
-# Fingerprint (MD5): 64:9C:EF:2E:44:FC:C6:8F:52:07:D0:51:73:8F:CB:3D
-# Fingerprint (SHA1): DA:40:18:8B:91:89:A3:ED:EE:AE:DA:97:FE:2F:9D:F5:B7:D1:8A:41
-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"
-# Issuer: CN=Equifax Secure eBusiness CA-1,O=Equifax Secure Inc.,C=US
-# Serial Number: 4 (0x4)
-# Subject: CN=Equifax Secure eBusiness CA-1,O=Equifax Secure Inc.,C=US
-# Not Valid Before: Mon Jun 21 04:00:00 1999
-# Not Valid After : Sun Jun 21 04:00:00 2020
-# Fingerprint (MD5): 64:9C:EF:2E:44:FC:C6:8F:52:07:D0:51:73:8F:CB:3D
-# Fingerprint (SHA1): DA:40:18:8B:91:89:A3:ED:EE:AE:DA:97:FE:2F:9D:F5:B7:D1:8A:41
-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_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 "AddTrust Low-Value Services Root"
#
# Issuer: CN=AddTrust Class 1 CA Root,OU=AddTrust TTP Network,O=AddTrust AB,C=SE
@@ -2918,132 +2005,6 @@ 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"
-#
-# Issuer: OU=RSA Security 2048 V3,O=RSA Security Inc
-# Serial Number:0a:01:01:01:00:00:02:7c:00:00:00:0a:00:00:00:02
-# Subject: OU=RSA Security 2048 V3,O=RSA Security Inc
-# Not Valid Before: Thu Feb 22 20:39:23 2001
-# Not Valid After : Sun Feb 22 20:39:23 2026
-# Fingerprint (MD5): 77:0D:19:B1:21:FD:00:42:9C:3E:0C:A5:DD:0B:02:8E
-# Fingerprint (SHA1): 25:01:90:19:CF:FB:D9:99:1C:B7:68:25:74:8D:94:5F:30:93:95:42
-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"
-# Issuer: OU=RSA Security 2048 V3,O=RSA Security Inc
-# Serial Number:0a:01:01:01:00:00:02:7c:00:00:00:0a:00:00:00:02
-# Subject: OU=RSA Security 2048 V3,O=RSA Security Inc
-# Not Valid Before: Thu Feb 22 20:39:23 2001
-# Not Valid After : Sun Feb 22 20:39:23 2026
-# Fingerprint (MD5): 77:0D:19:B1:21:FD:00:42:9C:3E:0C:A5:DD:0B:02:8E
-# Fingerprint (SHA1): 25:01:90:19:CF:FB:D9:99:1C:B7:68:25:74:8D:94:5F:30:93:95:42
-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"
#
# Issuer: CN=GeoTrust Global CA,O=GeoTrust Inc.,C=US
@@ -4974,126 +3935,6 @@ 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"
-#
-# Issuer: CN=Sonera Class1 CA,O=Sonera,C=FI
-# Serial Number: 36 (0x24)
-# Subject: CN=Sonera Class1 CA,O=Sonera,C=FI
-# Not Valid Before: Fri Apr 06 10:49:13 2001
-# Not Valid After : Tue Apr 06 10:49:13 2021
-# Fingerprint (MD5): 33:B7:84:F5:5F:27:D7:68:27:DE:14:DE:12:2A:ED:6F
-# Fingerprint (SHA1): 07:47:22:01:99:CE:74:B9:7C:B0:3D:79:B2:64:A2:C8:55:E9:33:FF
-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"
-# Issuer: CN=Sonera Class1 CA,O=Sonera,C=FI
-# Serial Number: 36 (0x24)
-# Subject: CN=Sonera Class1 CA,O=Sonera,C=FI
-# Not Valid Before: Fri Apr 06 10:49:13 2001
-# Not Valid After : Tue Apr 06 10:49:13 2021
-# Fingerprint (MD5): 33:B7:84:F5:5F:27:D7:68:27:DE:14:DE:12:2A:ED:6F
-# Fingerprint (SHA1): 07:47:22:01:99:CE:74:B9:7C:B0:3D:79:B2:64:A2:C8:55:E9:33:FF
-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"
#
# Issuer: CN=Sonera Class2 CA,O=Sonera,C=FI
@@ -5214,141 +4055,6 @@ 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"
-#
-# Issuer: CN=Staat der Nederlanden Root CA,O=Staat der Nederlanden,C=NL
-# Serial Number: 10000010 (0x98968a)
-# Subject: CN=Staat der Nederlanden Root CA,O=Staat der Nederlanden,C=NL
-# Not Valid Before: Tue Dec 17 09:23:49 2002
-# Not Valid After : Wed Dec 16 09:15:38 2015
-# Fingerprint (MD5): 60:84:7C:5A:CE:DB:0C:D4:CB:A7:E9:FE:02:C6:A9:C0
-# Fingerprint (SHA1): 10:1D:FA:3F:D5:0B:CB:BB:9B:B5:60:0C:19:55:A4:1A:F4:73:3A: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 "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"
-# Issuer: CN=Staat der Nederlanden Root CA,O=Staat der Nederlanden,C=NL
-# Serial Number: 10000010 (0x98968a)
-# Subject: CN=Staat der Nederlanden Root CA,O=Staat der Nederlanden,C=NL
-# Not Valid Before: Tue Dec 17 09:23:49 2002
-# Not Valid After : Wed Dec 16 09:15:38 2015
-# Fingerprint (MD5): 60:84:7C:5A:CE:DB:0C:D4:CB:A7:E9:FE:02:C6:A9:C0
-# Fingerprint (SHA1): 10:1D:FA:3F:D5:0B:CB:BB:9B:B5:60:0C:19:55:A4:1A:F4:73:3A: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 "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 "UTN USERFirst Email Root CA"
#
# Issuer: CN=UTN-USERFirst-Client Authentication and Email,OU=http://www.usertrust.com,O=The USERTRUST Network,L=Salt Lake City,ST=UT,C=US
@@ -6159,755 +4865,6 @@ 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"
-#
-# Issuer: E=info@netlock.hu,CN=NetLock Minositett Kozjegyzoi (Class QA) Tanusitvanykiado,OU=Tanusitvanykiadok,O=NetLock Halozatbiztonsagi Kft.,L=Budapest,C=HU
-# Serial Number: 123 (0x7b)
-# Subject: E=info@netlock.hu,CN=NetLock Minositett Kozjegyzoi (Class QA) Tanusitvanykiado,OU=Tanusitvanykiadok,O=NetLock Halozatbiztonsagi Kft.,L=Budapest,C=HU
-# Not Valid Before: Sun Mar 30 01:47:11 2003
-# Not Valid After : Thu Dec 15 01:47:11 2022
-# Fingerprint (MD5): D4:80:65:68:24:F9:89:22:28:DB:F5:A4:9A:17:8F:14
-# Fingerprint (SHA1): 01:68:97:E1:A0:B8:F2:C3:B1:34:66:5C:20:A7:27:B7:A1:58:E2:8F
-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"
-# Issuer: E=info@netlock.hu,CN=NetLock Minositett Kozjegyzoi (Class QA) Tanusitvanykiado,OU=Tanusitvanykiadok,O=NetLock Halozatbiztonsagi Kft.,L=Budapest,C=HU
-# Serial Number: 123 (0x7b)
-# Subject: E=info@netlock.hu,CN=NetLock Minositett Kozjegyzoi (Class QA) Tanusitvanykiado,OU=Tanusitvanykiadok,O=NetLock Halozatbiztonsagi Kft.,L=Budapest,C=HU
-# Not Valid Before: Sun Mar 30 01:47:11 2003
-# Not Valid After : Thu Dec 15 01:47:11 2022
-# Fingerprint (MD5): D4:80:65:68:24:F9:89:22:28:DB:F5:A4:9A:17:8F:14
-# Fingerprint (SHA1): 01:68:97:E1:A0:B8:F2:C3:B1:34:66:5C:20:A7:27:B7:A1:58:E2:8F
-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"
-#
-# Issuer: CN=NetLock Kozjegyzoi (Class A) Tanusitvanykiado,OU=Tanusitvanykiadok,O=NetLock Halozatbiztonsagi Kft.,L=Budapest,ST=Hungary,C=HU
-# Serial Number: 259 (0x103)
-# Subject: CN=NetLock Kozjegyzoi (Class A) Tanusitvanykiado,OU=Tanusitvanykiadok,O=NetLock Halozatbiztonsagi Kft.,L=Budapest,ST=Hungary,C=HU
-# Not Valid Before: Wed Feb 24 23:14:47 1999
-# Not Valid After : Tue Feb 19 23:14:47 2019
-# Fingerprint (MD5): 86:38:6D:5E:49:63:6C:85:5C:DB:6D:DC:94:B7:D0:F7
-# Fingerprint (SHA1): AC:ED:5F:65:53:FD:25:CE:01:5F:1F:7A:48:3B:6A:74:9F:61:78:C6
-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"
-# Issuer: CN=NetLock Kozjegyzoi (Class A) Tanusitvanykiado,OU=Tanusitvanykiadok,O=NetLock Halozatbiztonsagi Kft.,L=Budapest,ST=Hungary,C=HU
-# Serial Number: 259 (0x103)
-# Subject: CN=NetLock Kozjegyzoi (Class A) Tanusitvanykiado,OU=Tanusitvanykiadok,O=NetLock Halozatbiztonsagi Kft.,L=Budapest,ST=Hungary,C=HU
-# Not Valid Before: Wed Feb 24 23:14:47 1999
-# Not Valid After : Tue Feb 19 23:14:47 2019
-# Fingerprint (MD5): 86:38:6D:5E:49:63:6C:85:5C:DB:6D:DC:94:B7:D0:F7
-# Fingerprint (SHA1): AC:ED:5F:65:53:FD:25:CE:01:5F:1F:7A:48:3B:6A:74:9F:61:78:C6
-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"
-#
-# Issuer: CN=NetLock Uzleti (Class B) Tanusitvanykiado,OU=Tanusitvanykiadok,O=NetLock Halozatbiztonsagi Kft.,L=Budapest,C=HU
-# Serial Number: 105 (0x69)
-# Subject: CN=NetLock Uzleti (Class B) Tanusitvanykiado,OU=Tanusitvanykiadok,O=NetLock Halozatbiztonsagi Kft.,L=Budapest,C=HU
-# Not Valid Before: Thu Feb 25 14:10:22 1999
-# Not Valid After : Wed Feb 20 14:10:22 2019
-# Fingerprint (MD5): 39:16:AA:B9:6A:41:E1:14:69:DF:9E:6C:3B:72:DC:B6
-# Fingerprint (SHA1): 87:9F:4B:EE:05:DF:98:58:3B:E3:60:D6:33:E7:0D:3F:FE:98:71:AF
-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"
-# Issuer: CN=NetLock Uzleti (Class B) Tanusitvanykiado,OU=Tanusitvanykiadok,O=NetLock Halozatbiztonsagi Kft.,L=Budapest,C=HU
-# Serial Number: 105 (0x69)
-# Subject: CN=NetLock Uzleti (Class B) Tanusitvanykiado,OU=Tanusitvanykiadok,O=NetLock Halozatbiztonsagi Kft.,L=Budapest,C=HU
-# Not Valid Before: Thu Feb 25 14:10:22 1999
-# Not Valid After : Wed Feb 20 14:10:22 2019
-# Fingerprint (MD5): 39:16:AA:B9:6A:41:E1:14:69:DF:9E:6C:3B:72:DC:B6
-# Fingerprint (SHA1): 87:9F:4B:EE:05:DF:98:58:3B:E3:60:D6:33:E7:0D:3F:FE:98:71:AF
-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_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 "NetLock Express (Class C) Root"
-#
-# Issuer: CN=NetLock Expressz (Class C) Tanusitvanykiado,OU=Tanusitvanykiadok,O=NetLock Halozatbiztonsagi Kft.,L=Budapest,C=HU
-# Serial Number: 104 (0x68)
-# Subject: CN=NetLock Expressz (Class C) Tanusitvanykiado,OU=Tanusitvanykiadok,O=NetLock Halozatbiztonsagi Kft.,L=Budapest,C=HU
-# Not Valid Before: Thu Feb 25 14:08:11 1999
-# Not Valid After : Wed Feb 20 14:08:11 2019
-# Fingerprint (MD5): 4F:EB:F1:F0:70:C2:80:63:5D:58:9F:DA:12:3C:A9:C4
-# Fingerprint (SHA1): E3:92:51:2F:0A:CF:F5:05:DF:F6:DE:06:7F:75:37:E1:65:EA:57:4B
-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"
-# Issuer: CN=NetLock Expressz (Class C) Tanusitvanykiado,OU=Tanusitvanykiadok,O=NetLock Halozatbiztonsagi Kft.,L=Budapest,C=HU
-# Serial Number: 104 (0x68)
-# Subject: CN=NetLock Expressz (Class C) Tanusitvanykiado,OU=Tanusitvanykiadok,O=NetLock Halozatbiztonsagi Kft.,L=Budapest,C=HU
-# Not Valid Before: Thu Feb 25 14:08:11 1999
-# Not Valid After : Wed Feb 20 14:08:11 2019
-# Fingerprint (MD5): 4F:EB:F1:F0:70:C2:80:63:5D:58:9F:DA:12:3C:A9:C4
-# Fingerprint (SHA1): E3:92:51:2F:0A:CF:F5:05:DF:F6:DE:06:7F:75:37:E1:65:EA:57:4B
-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_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 "XRamp Global CA Root"
#
# Issuer: CN=XRamp Global Certification Authority,O=XRamp Security Services Inc,OU=www.xrampsecurity.com,C=US
@@ -10664,155 +8621,6 @@ 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"
-#
-# Issuer: E=igca@sgdn.pm.gouv.fr,CN=IGC/A,OU=DCSSI,O=PM/SGDN,L=Paris,ST=France,C=FR
-# Serial Number:39:11:45:10:94
-# Subject: E=igca@sgdn.pm.gouv.fr,CN=IGC/A,OU=DCSSI,O=PM/SGDN,L=Paris,ST=France,C=FR
-# Not Valid Before: Fri Dec 13 14:29:23 2002
-# Not Valid After : Sat Oct 17 14:29:22 2020
-# Fingerprint (MD5): 0C:7F:DD:6A:F4:2A:B9:C8:9B:BD:20:7E:A9:DB:5C:37
-# Fingerprint (SHA1): 60:D6:89:74:B5:C2:65:9E:8A:0F:C1:88:7C:88:D2:46:69:1B:18:2C
-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"
-# Issuer: E=igca@sgdn.pm.gouv.fr,CN=IGC/A,OU=DCSSI,O=PM/SGDN,L=Paris,ST=France,C=FR
-# Serial Number:39:11:45:10:94
-# Subject: E=igca@sgdn.pm.gouv.fr,CN=IGC/A,OU=DCSSI,O=PM/SGDN,L=Paris,ST=France,C=FR
-# Not Valid Before: Fri Dec 13 14:29:23 2002
-# Not Valid After : Sat Oct 17 14:29:22 2020
-# Fingerprint (MD5): 0C:7F:DD:6A:F4:2A:B9:C8:9B:BD:20:7E:A9:DB:5C:37
-# Fingerprint (SHA1): 60:D6:89:74:B5:C2:65:9E:8A:0F:C1:88:7C:88:D2:46:69:1B:18:2C
-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
-
# Distrust "Distrusted AC DG Tresor SSL"
# Issuer: CN=AC DGTPE Signature Authentification,O=DGTPE,C=FR
# Serial Number: 204199 (0x31da7)
@@ -11127,173 +8935,6 @@ 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"
-#
-# Issuer: CN=S-TRUST Authentication and Encryption Root CA 2005:PN,O=Deutscher Sparkassen Verlag GmbH,L=Stuttgart,ST=Baden-Wuerttemberg (BW),C=DE
-# Serial Number:37:19:18:e6:53:54:7c:1a:b5:b8:cb:59:5a:db:35:b7
-# Subject: CN=S-TRUST Authentication and Encryption Root CA 2005:PN,O=Deutscher Sparkassen Verlag GmbH,L=Stuttgart,ST=Baden-Wuerttemberg (BW),C=DE
-# Not Valid Before: Wed Jun 22 00:00:00 2005
-# Not Valid After : Fri Jun 21 23:59:59 2030
-# Fingerprint (MD5): 04:4B:FD:C9:6C:DA:2A:32:85:7C:59:84:61:46:8A:64
-# Fingerprint (SHA1): BE:B5:A9:95:74:6B:9E:DF:73:8B:56:E6:DF:43:7A:77:BE:10:6B:81
-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"
-# Issuer: CN=S-TRUST Authentication and Encryption Root CA 2005:PN,O=Deutscher Sparkassen Verlag GmbH,L=Stuttgart,ST=Baden-Wuerttemberg (BW),C=DE
-# Serial Number:37:19:18:e6:53:54:7c:1a:b5:b8:cb:59:5a:db:35:b7
-# Subject: CN=S-TRUST Authentication and Encryption Root CA 2005:PN,O=Deutscher Sparkassen Verlag GmbH,L=Stuttgart,ST=Baden-Wuerttemberg (BW),C=DE
-# Not Valid Before: Wed Jun 22 00:00:00 2005
-# Not Valid After : Fri Jun 21 23:59:59 2030
-# Fingerprint (MD5): 04:4B:FD:C9:6C:DA:2A:32:85:7C:59:84:61:46:8A:64
-# Fingerprint (SHA1): BE:B5:A9:95:74:6B:9E:DF:73:8B:56:E6:DF:43:7A:77:BE:10:6B:81
-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"
#
# Issuer: CN=Microsec e-Szigno Root CA,OU=e-Szigno CA,O=Microsec Ltd.,L=Budapest,C=HU
@@ -12862,311 +10503,6 @@ 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"
-#
-# Issuer: CN=Buypass Class 2 CA 1,O=Buypass AS-983163327,C=NO
-# Serial Number: 1 (0x1)
-# Subject: CN=Buypass Class 2 CA 1,O=Buypass AS-983163327,C=NO
-# Not Valid Before: Fri Oct 13 10:25:09 2006
-# Not Valid After : Thu Oct 13 10:25:09 2016
-# Fingerprint (MD5): B8:08:9A:F0:03:CC:1B:0D:C8:6C:0B:76:A1:75:64:23
-# Fingerprint (SHA1): A0:A1:AB:90:C9:FC:84:7B:3B:12:61:E8:97:7D:5F:D3:22:61:D3:CC
-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"
-# Issuer: CN=Buypass Class 2 CA 1,O=Buypass AS-983163327,C=NO
-# Serial Number: 1 (0x1)
-# Subject: CN=Buypass Class 2 CA 1,O=Buypass AS-983163327,C=NO
-# Not Valid Before: Fri Oct 13 10:25:09 2006
-# Not Valid After : Thu Oct 13 10:25:09 2016
-# Fingerprint (MD5): B8:08:9A:F0:03:CC:1B:0D:C8:6C:0B:76:A1:75:64:23
-# Fingerprint (SHA1): A0:A1:AB:90:C9:FC:84:7B:3B:12:61:E8:97:7D:5F:D3:22:61:D3:CC
-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 "EBG Elektronik Sertifika Hizmet Saglayicisi"
-#
-# Issuer: C=TR,O=EBG Bili..im Teknolojileri ve Hizmetleri A....,CN=EBG Elektronik Sertifika Hizmet Sa..lay..c..s..
-# Serial Number:4c:af:73:42:1c:8e:74:02
-# Subject: C=TR,O=EBG Bili..im Teknolojileri ve Hizmetleri A....,CN=EBG Elektronik Sertifika Hizmet Sa..lay..c..s..
-# Not Valid Before: Thu Aug 17 00:21:09 2006
-# Not Valid After : Sun Aug 14 00:31:09 2016
-# Fingerprint (MD5): 2C:20:26:9D:CB:1A:4A:00:85:B5:B7:5A:AE:C2:01:37
-# Fingerprint (SHA1): 8C:96:BA:EB:DD:2B:07:07:48:EE:30:32:66:A0:F3:98:6E:7C:AE:58
-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"
-# Issuer: C=TR,O=EBG Bili..im Teknolojileri ve Hizmetleri A....,CN=EBG Elektronik Sertifika Hizmet Sa..lay..c..s..
-# Serial Number:4c:af:73:42:1c:8e:74:02
-# Subject: C=TR,O=EBG Bili..im Teknolojileri ve Hizmetleri A....,CN=EBG Elektronik Sertifika Hizmet Sa..lay..c..s..
-# Not Valid Before: Thu Aug 17 00:21:09 2006
-# Not Valid After : Sun Aug 14 00:31:09 2016
-# Fingerprint (MD5): 2C:20:26:9D:CB:1A:4A:00:85:B5:B7:5A:AE:C2:01:37
-# Fingerprint (SHA1): 8C:96:BA:EB:DD:2B:07:07:48:EE:30:32:66:A0:F3:98:6E:7C:AE:58
-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"
#
# Issuer: OU=certSIGN ROOT CA,O=certSIGN,C=RO
@@ -14768,298 +12104,6 @@ CKA_TRUST_CODE_SIGNING CK_TRUST CKT_NSS_TRUSTED_DELEGATOR
CKA_TRUST_STEP_UP_APPROVED CK_BBOOL CK_FALSE
#
-# Certificate "CA Disig"
-#
-# Issuer: CN=CA Disig,O=Disig a.s.,L=Bratislava,C=SK
-# Serial Number: 1 (0x1)
-# Subject: CN=CA Disig,O=Disig a.s.,L=Bratislava,C=SK
-# Not Valid Before: Wed Mar 22 01:39:34 2006
-# Not Valid After : Tue Mar 22 01:39:34 2016
-# Fingerprint (MD5): 3F:45:96:39:E2:50:87:F7:BB:FE:98:0C:3C:20:98:E6
-# Fingerprint (SHA1): 2A:C8:D5:8B:57:CE:BF:2F:49:AF:F2:FC:76:8F:51:14:62:90:7A:41
-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"
-# Issuer: CN=CA Disig,O=Disig a.s.,L=Bratislava,C=SK
-# Serial Number: 1 (0x1)
-# Subject: CN=CA Disig,O=Disig a.s.,L=Bratislava,C=SK
-# Not Valid Before: Wed Mar 22 01:39:34 2006
-# Not Valid After : Tue Mar 22 01:39:34 2016
-# Fingerprint (MD5): 3F:45:96:39:E2:50:87:F7:BB:FE:98:0C:3C:20:98:E6
-# Fingerprint (SHA1): 2A:C8:D5:8B:57:CE:BF:2F:49:AF:F2:FC:76:8F:51:14:62:90:7A:41
-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"
-#
-# Issuer: CN=Juur-SK,O=AS Sertifitseerimiskeskus,C=EE,E=pki@sk.ee
-# Serial Number: 999181308 (0x3b8e4bfc)
-# Subject: CN=Juur-SK,O=AS Sertifitseerimiskeskus,C=EE,E=pki@sk.ee
-# Not Valid Before: Thu Aug 30 14:23:01 2001
-# Not Valid After : Fri Aug 26 14:23:01 2016
-# Fingerprint (MD5): AA:8E:5D:D9:F8:DB:0A:58:B7:8D:26:87:6C:82:35:55
-# Fingerprint (SHA1): 40:9D:4B:D9:17:B5:5C:27:B6:9B:64:CB:98:22:44:0D:CD:09:B8:89
-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"
-# Issuer: CN=Juur-SK,O=AS Sertifitseerimiskeskus,C=EE,E=pki@sk.ee
-# Serial Number: 999181308 (0x3b8e4bfc)
-# Subject: CN=Juur-SK,O=AS Sertifitseerimiskeskus,C=EE,E=pki@sk.ee
-# Not Valid Before: Thu Aug 30 14:23:01 2001
-# Not Valid After : Fri Aug 26 14:23:01 2016
-# Fingerprint (MD5): AA:8E:5D:D9:F8:DB:0A:58:B7:8D:26:87:6C:82:35:55
-# Fingerprint (SHA1): 40:9D:4B:D9:17:B5:5C:27:B6:9B:64:CB:98:22:44:0D:CD:09:B8:89
-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"
#
# Issuer: CN=Hongkong Post Root CA 1,O=Hongkong Post,C=HK
@@ -15480,238 +12524,6 @@ CKA_TRUST_STEP_UP_APPROVED CK_BBOOL CK_FALSE
#
-# Certificate "Verisign Class 1 Public Primary Certification Authority"
-#
-# Issuer: OU=Class 1 Public Primary Certification Authority,O="VeriSign, Inc.",C=US
-# Serial Number:3f:69:1e:81:9c:f0:9a:4a:f3:73:ff:b9:48:a2:e4:dd
-# Subject: OU=Class 1 Public Primary Certification Authority,O="VeriSign, Inc.",C=US
-# Not Valid Before: Mon Jan 29 00:00:00 1996
-# Not Valid After : Wed Aug 02 23:59:59 2028
-# Fingerprint (MD5): 86:AC:DE:2B:C5:6D:C3:D9:8C:28:88:D3:8D:16:13:1E
-# Fingerprint (SHA1): CE:6A:64:A3:09:E4:2F:BB:D9:85:1C:45:3E:64:09:EA:E8:7D:60:F1
-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"
-# Issuer: OU=Class 1 Public Primary Certification Authority,O="VeriSign, Inc.",C=US
-# Serial Number:3f:69:1e:81:9c:f0:9a:4a:f3:73:ff:b9:48:a2:e4:dd
-# Subject: OU=Class 1 Public Primary Certification Authority,O="VeriSign, Inc.",C=US
-# Not Valid Before: Mon Jan 29 00:00:00 1996
-# Not Valid After : Wed Aug 02 23:59:59 2028
-# Fingerprint (MD5): 86:AC:DE:2B:C5:6D:C3:D9:8C:28:88:D3:8D:16:13:1E
-# Fingerprint (SHA1): CE:6A:64:A3:09:E4:2F:BB:D9:85:1C:45:3E:64:09:EA:E8:7D:60:F1
-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"
-#
-# Issuer: OU=Class 3 Public Primary Certification Authority,O="VeriSign, Inc.",C=US
-# Serial Number:3c:91:31:cb:1f:f6:d0:1b:0e:9a:b8:d0:44:bf:12:be
-# Subject: OU=Class 3 Public Primary Certification Authority,O="VeriSign, Inc.",C=US
-# Not Valid Before: Mon Jan 29 00:00:00 1996
-# Not Valid After : Wed Aug 02 23:59:59 2028
-# Fingerprint (MD5): EF:5A:F1:33:EF:F1:CD:BB:51:02:EE:12:14:4B:96:C4
-# Fingerprint (SHA1): A1:DB:63:93:91:6F:17:E4:18:55:09:40:04:15:C7:02:40:B0:AE:6B
-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"
-# Issuer: OU=Class 3 Public Primary Certification Authority,O="VeriSign, Inc.",C=US
-# Serial Number:3c:91:31:cb:1f:f6:d0:1b:0e:9a:b8:d0:44:bf:12:be
-# Subject: OU=Class 3 Public Primary Certification Authority,O="VeriSign, Inc.",C=US
-# Not Valid Before: Mon Jan 29 00:00:00 1996
-# Not Valid After : Wed Aug 02 23:59:59 2028
-# Fingerprint (MD5): EF:5A:F1:33:EF:F1:CD:BB:51:02:EE:12:14:4B:96:C4
-# Fingerprint (SHA1): A1:DB:63:93:91:6F:17:E4:18:55:09:40:04:15:C7:02:40:B0:AE:6B
-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_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 2009"
#
# Issuer: E=info@e-szigno.hu,CN=Microsec e-Szigno Root CA 2009,O=Microsec Ltd.,L=Budapest,C=HU
@@ -19732,189 +16544,6 @@ 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"
-#
-# Issuer: CN=Root CA Generalitat Valenciana,OU=PKIGVA,O=Generalitat Valenciana,C=ES
-# Serial Number: 994436456 (0x3b45e568)
-# Subject: CN=Root CA Generalitat Valenciana,OU=PKIGVA,O=Generalitat Valenciana,C=ES
-# Not Valid Before: Fri Jul 06 16:22:47 2001
-# Not Valid After : Thu Jul 01 15:22:47 2021
-# Fingerprint (MD5): 2C:8C:17:5E:B1:54:AB:93:17:B5:36:5A:DB:D1:C6:F2
-# Fingerprint (SHA1): A0:73:E5:C5:BD:43:61:0D:86:4C:21:13:0A:85:58:57:CC:9C:EA:46
-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"
-# Issuer: CN=Root CA Generalitat Valenciana,OU=PKIGVA,O=Generalitat Valenciana,C=ES
-# Serial Number: 994436456 (0x3b45e568)
-# Subject: CN=Root CA Generalitat Valenciana,OU=PKIGVA,O=Generalitat Valenciana,C=ES
-# Not Valid Before: Fri Jul 06 16:22:47 2001
-# Not Valid After : Thu Jul 01 15:22:47 2021
-# Fingerprint (MD5): 2C:8C:17:5E:B1:54:AB:93:17:B5:36:5A:DB:D1:C6:F2
-# Fingerprint (SHA1): A0:73:E5:C5:BD:43:61:0D:86:4C:21:13:0A:85:58:57:CC:9C:EA:46
-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 "TWCA Root Certification Authority"
#
# Issuer: CN=TWCA Root Certification Authority,OU=Root CA,O=TAIWAN-CA,C=TW
@@ -22013,7 +18642,7 @@ 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_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
@@ -30351,3 +26980,2877 @@ 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 "SZAFIR ROOT CA2"
+#
+# Issuer: CN=SZAFIR ROOT CA2,O=Krajowa Izba Rozliczeniowa S.A.,C=PL
+# Serial Number:3e:8a:5d:07:ec:55:d2:32:d5:b7:e3:b6:5f:01:eb:2d:dc:e4:d6:e4
+# Subject: CN=SZAFIR ROOT CA2,O=Krajowa Izba Rozliczeniowa S.A.,C=PL
+# Not Valid Before: Mon Oct 19 07:43:30 2015
+# Not Valid After : Fri Oct 19 07:43:30 2035
+# Fingerprint (SHA-256): A1:33:9D:33:28:1A:0B:56:E5:57:D3:D3:2B:1C:E7:F9:36:7E:B0:94:BD:5F:A7:2A:7E:50:04:C8:DE:D7:CA:FE
+# Fingerprint (SHA1): E2:52:FA:95:3F:ED:DB:24:60:BD:6E:28:F3:9C:CC:CF:5E:B3:3F: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 "SZAFIR ROOT CA2"
+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\120\114\061
+\050\060\046\006\003\125\004\012\014\037\113\162\141\152\157\167
+\141\040\111\172\142\141\040\122\157\172\154\151\143\172\145\156
+\151\157\167\141\040\123\056\101\056\061\030\060\026\006\003\125
+\004\003\014\017\123\132\101\106\111\122\040\122\117\117\124\040
+\103\101\062
+END
+CKA_ID UTF8 "0"
+CKA_ISSUER MULTILINE_OCTAL
+\060\121\061\013\060\011\006\003\125\004\006\023\002\120\114\061
+\050\060\046\006\003\125\004\012\014\037\113\162\141\152\157\167
+\141\040\111\172\142\141\040\122\157\172\154\151\143\172\145\156
+\151\157\167\141\040\123\056\101\056\061\030\060\026\006\003\125
+\004\003\014\017\123\132\101\106\111\122\040\122\117\117\124\040
+\103\101\062
+END
+CKA_SERIAL_NUMBER MULTILINE_OCTAL
+\002\024\076\212\135\007\354\125\322\062\325\267\343\266\137\001
+\353\055\334\344\326\344
+END
+CKA_VALUE MULTILINE_OCTAL
+\060\202\003\162\060\202\002\132\240\003\002\001\002\002\024\076
+\212\135\007\354\125\322\062\325\267\343\266\137\001\353\055\334
+\344\326\344\060\015\006\011\052\206\110\206\367\015\001\001\013
+\005\000\060\121\061\013\060\011\006\003\125\004\006\023\002\120
+\114\061\050\060\046\006\003\125\004\012\014\037\113\162\141\152
+\157\167\141\040\111\172\142\141\040\122\157\172\154\151\143\172
+\145\156\151\157\167\141\040\123\056\101\056\061\030\060\026\006
+\003\125\004\003\014\017\123\132\101\106\111\122\040\122\117\117
+\124\040\103\101\062\060\036\027\015\061\065\061\060\061\071\060
+\067\064\063\063\060\132\027\015\063\065\061\060\061\071\060\067
+\064\063\063\060\132\060\121\061\013\060\011\006\003\125\004\006
+\023\002\120\114\061\050\060\046\006\003\125\004\012\014\037\113
+\162\141\152\157\167\141\040\111\172\142\141\040\122\157\172\154
+\151\143\172\145\156\151\157\167\141\040\123\056\101\056\061\030
+\060\026\006\003\125\004\003\014\017\123\132\101\106\111\122\040
+\122\117\117\124\040\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\267\274\076\120\250\113\315
+\100\265\316\141\347\226\312\264\241\332\014\042\260\372\265\173
+\166\000\167\214\013\317\175\250\206\314\046\121\344\040\075\205
+\014\326\130\343\347\364\052\030\235\332\321\256\046\356\353\123
+\334\364\220\326\023\112\014\220\074\303\364\332\322\216\015\222
+\072\334\261\261\377\070\336\303\272\055\137\200\271\002\275\112
+\235\033\017\264\303\302\301\147\003\335\334\033\234\075\263\260
+\336\000\036\250\064\107\273\232\353\376\013\024\275\066\204\332
+\015\040\277\372\133\313\251\026\040\255\071\140\356\057\165\266
+\347\227\234\371\076\375\176\115\157\115\057\357\210\015\152\372
+\335\361\075\156\040\245\240\022\264\115\160\271\316\327\162\073
+\211\223\247\200\204\034\047\111\162\111\265\377\073\225\236\301
+\314\310\001\354\350\016\212\012\226\347\263\246\207\345\326\371
+\005\053\015\227\100\160\074\272\254\165\132\234\325\115\235\002
+\012\322\113\233\146\113\106\007\027\145\255\237\154\210\000\334
+\042\211\340\341\144\324\147\274\061\171\141\074\273\312\101\315
+\134\152\000\310\074\070\216\130\257\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\056\026
+\251\112\030\265\313\314\365\157\120\363\043\137\370\135\347\254
+\360\310\060\015\006\011\052\206\110\206\367\015\001\001\013\005
+\000\003\202\001\001\000\265\163\370\003\334\131\133\035\166\351
+\243\052\173\220\050\262\115\300\063\117\252\232\261\324\270\344
+\047\377\251\226\231\316\106\340\155\174\114\242\070\244\006\160
+\360\364\101\021\354\077\107\215\077\162\207\371\073\375\244\157
+\053\123\000\340\377\071\271\152\007\016\353\035\034\366\242\162
+\220\313\202\075\021\202\213\322\273\237\052\257\041\346\143\206
+\235\171\031\357\367\273\014\065\220\303\212\355\117\017\365\314
+\022\331\244\076\273\240\374\040\225\137\117\046\057\021\043\203
+\116\165\007\017\277\233\321\264\035\351\020\004\376\312\140\217
+\242\114\270\255\317\341\220\017\315\256\012\307\135\173\267\120
+\322\324\141\372\325\025\333\327\237\207\121\124\353\245\343\353
+\311\205\240\045\040\067\373\216\316\014\064\204\341\074\201\262
+\167\116\103\245\210\137\206\147\241\075\346\264\134\141\266\076
+\333\376\267\050\305\242\007\256\265\312\312\215\052\022\357\227
+\355\302\060\244\311\052\172\373\363\115\043\033\231\063\064\240
+\056\365\251\013\077\324\135\341\317\204\237\342\031\302\137\212
+\326\040\036\343\163\267
+END
+
+# Trust for "SZAFIR ROOT CA2"
+# Issuer: CN=SZAFIR ROOT CA2,O=Krajowa Izba Rozliczeniowa S.A.,C=PL
+# Serial Number:3e:8a:5d:07:ec:55:d2:32:d5:b7:e3:b6:5f:01:eb:2d:dc:e4:d6:e4
+# Subject: CN=SZAFIR ROOT CA2,O=Krajowa Izba Rozliczeniowa S.A.,C=PL
+# Not Valid Before: Mon Oct 19 07:43:30 2015
+# Not Valid After : Fri Oct 19 07:43:30 2035
+# Fingerprint (SHA-256): A1:33:9D:33:28:1A:0B:56:E5:57:D3:D3:2B:1C:E7:F9:36:7E:B0:94:BD:5F:A7:2A:7E:50:04:C8:DE:D7:CA:FE
+# Fingerprint (SHA1): E2:52:FA:95:3F:ED:DB:24:60:BD:6E:28:F3:9C:CC:CF:5E:B3:3F: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 "SZAFIR ROOT CA2"
+CKA_CERT_SHA1_HASH MULTILINE_OCTAL
+\342\122\372\225\077\355\333\044\140\275\156\050\363\234\314\317
+\136\263\077\336
+END
+CKA_CERT_MD5_HASH MULTILINE_OCTAL
+\021\144\301\211\260\044\261\214\261\007\176\211\236\121\236\231
+END
+CKA_ISSUER MULTILINE_OCTAL
+\060\121\061\013\060\011\006\003\125\004\006\023\002\120\114\061
+\050\060\046\006\003\125\004\012\014\037\113\162\141\152\157\167
+\141\040\111\172\142\141\040\122\157\172\154\151\143\172\145\156
+\151\157\167\141\040\123\056\101\056\061\030\060\026\006\003\125
+\004\003\014\017\123\132\101\106\111\122\040\122\117\117\124\040
+\103\101\062
+END
+CKA_SERIAL_NUMBER MULTILINE_OCTAL
+\002\024\076\212\135\007\354\125\322\062\325\267\343\266\137\001
+\353\055\334\344\326\344
+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 "Certum Trusted Network CA 2"
+#
+# Issuer: CN=Certum Trusted Network CA 2,OU=Certum Certification Authority,O=Unizeto Technologies S.A.,C=PL
+# Serial Number:21:d6:d0:4a:4f:25:0f:c9:32:37:fc:aa:5e:12:8d:e9
+# Subject: CN=Certum Trusted Network CA 2,OU=Certum Certification Authority,O=Unizeto Technologies S.A.,C=PL
+# Not Valid Before: Thu Oct 06 08:39:56 2011
+# Not Valid After : Sat Oct 06 08:39:56 2046
+# Fingerprint (SHA-256): B6:76:F2:ED:DA:E8:77:5C:D3:6C:B0:F6:3C:D1:D4:60:39:61:F4:9E:62:65:BA:01:3A:2F:03:07:B6:D0:B8:04
+# Fingerprint (SHA1): D3:DD:48:3E:2B:BF:4C:05:E8:AF:10:F5:FA:76:26:CF:D3:DC:30:92
+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 2"
+CKA_CERTIFICATE_TYPE CK_CERTIFICATE_TYPE CKC_X_509
+CKA_SUBJECT MULTILINE_OCTAL
+\060\201\200\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\044\060
+\042\006\003\125\004\003\023\033\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\040\062
+END
+CKA_ID UTF8 "0"
+CKA_ISSUER MULTILINE_OCTAL
+\060\201\200\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\044\060
+\042\006\003\125\004\003\023\033\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\040\062
+END
+CKA_SERIAL_NUMBER MULTILINE_OCTAL
+\002\020\041\326\320\112\117\045\017\311\062\067\374\252\136\022
+\215\351
+END
+CKA_VALUE MULTILINE_OCTAL
+\060\202\005\322\060\202\003\272\240\003\002\001\002\002\020\041
+\326\320\112\117\045\017\311\062\067\374\252\136\022\215\351\060
+\015\006\011\052\206\110\206\367\015\001\001\015\005\000\060\201
+\200\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\044\060\042\006
+\003\125\004\003\023\033\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\040
+\062\060\042\030\017\062\060\061\061\061\060\060\066\060\070\063
+\071\065\066\132\030\017\062\060\064\066\061\060\060\066\060\070
+\063\071\065\066\132\060\201\200\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\044\060\042\006\003\125\004\003\023\033\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\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\275\371\170\370\346\325\200
+\014\144\235\206\033\226\144\147\077\042\072\036\165\001\175\357
+\373\134\147\214\311\314\134\153\251\221\346\271\102\345\040\113
+\233\332\233\173\271\231\135\331\233\200\113\327\204\100\053\047
+\323\350\272\060\273\076\011\032\247\111\225\357\053\100\044\302
+\227\307\247\356\233\045\357\250\012\000\227\205\132\252\235\334
+\051\311\342\065\007\353\160\115\112\326\301\263\126\270\241\101
+\070\233\321\373\061\177\217\340\137\341\261\077\017\216\026\111
+\140\327\006\215\030\371\252\046\020\253\052\323\320\321\147\215
+\033\106\276\107\060\325\056\162\321\305\143\332\347\143\171\104
+\176\113\143\044\211\206\056\064\077\051\114\122\213\052\247\300
+\342\221\050\211\271\300\133\371\035\331\347\047\255\377\232\002
+\227\301\306\120\222\233\002\054\275\251\271\064\131\012\277\204
+\112\377\337\376\263\237\353\331\236\340\230\043\354\246\153\167
+\026\052\333\314\255\073\034\244\207\334\106\163\136\031\142\150
+\105\127\344\220\202\102\273\102\326\360\141\340\301\243\075\146
+\243\135\364\030\356\210\311\215\027\105\051\231\062\165\002\061
+\356\051\046\310\153\002\346\265\142\105\177\067\025\132\043\150
+\211\324\076\336\116\047\260\360\100\014\274\115\027\313\115\242
+\263\036\320\006\132\335\366\223\317\127\165\231\365\372\206\032
+\147\170\263\277\226\376\064\334\275\347\122\126\345\263\345\165
+\173\327\101\221\005\334\135\151\343\225\015\103\271\374\203\226
+\071\225\173\154\200\132\117\023\162\306\327\175\051\172\104\272
+\122\244\052\325\101\106\011\040\376\042\240\266\133\060\215\274
+\211\014\325\327\160\370\207\122\375\332\357\254\121\056\007\263
+\116\376\320\011\332\160\357\230\372\126\346\155\333\265\127\113
+\334\345\054\045\025\310\236\056\170\116\370\332\234\236\206\054
+\312\127\363\032\345\310\222\213\032\202\226\172\303\274\120\022
+\151\330\016\132\106\213\072\353\046\372\043\311\266\260\201\276
+\102\000\244\370\326\376\060\056\307\322\106\366\345\216\165\375
+\362\314\271\320\207\133\314\006\020\140\273\203\065\267\136\147
+\336\107\354\231\110\361\244\241\025\376\255\214\142\216\071\125
+\117\071\026\271\261\143\235\377\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\266\241
+\124\071\002\303\240\077\216\212\274\372\324\370\034\246\321\072
+\016\375\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\015\005
+\000\003\202\002\001\000\161\245\016\316\344\351\277\077\070\325
+\211\132\304\002\141\373\114\305\024\027\055\213\117\123\153\020
+\027\374\145\204\307\020\111\220\336\333\307\046\223\210\046\157
+\160\326\002\136\071\240\367\217\253\226\265\245\023\134\201\024
+\155\016\201\202\021\033\212\116\306\117\245\335\142\036\104\337
+\011\131\364\133\167\013\067\351\213\040\306\370\012\116\056\130
+\034\353\063\320\317\206\140\311\332\373\200\057\236\114\140\204
+\170\075\041\144\326\373\101\037\030\017\347\311\165\161\275\275
+\134\336\064\207\076\101\260\016\366\271\326\077\011\023\226\024
+\057\336\232\035\132\271\126\316\065\072\260\137\160\115\136\343
+\051\361\043\050\162\131\266\253\302\214\146\046\034\167\054\046
+\166\065\213\050\247\151\240\371\073\365\043\335\205\020\164\311
+\220\003\126\221\347\257\272\107\324\022\227\021\042\343\242\111
+\224\154\347\267\224\113\272\055\244\332\063\213\114\246\104\377
+\132\074\306\035\144\330\265\061\344\246\074\172\250\127\013\333
+\355\141\032\313\361\316\163\167\143\244\207\157\114\121\070\326
+\344\137\307\237\266\201\052\344\205\110\171\130\136\073\370\333
+\002\202\147\301\071\333\303\164\113\075\066\036\371\051\223\210
+\150\133\250\104\031\041\360\247\350\201\015\054\350\223\066\264
+\067\262\312\260\033\046\172\232\045\037\232\232\200\236\113\052
+\077\373\243\232\376\163\062\161\302\236\306\162\341\212\150\047
+\361\344\017\264\304\114\245\141\223\370\227\020\007\052\060\045
+\251\271\310\161\270\357\150\314\055\176\365\340\176\017\202\250
+\157\266\272\154\203\103\167\315\212\222\027\241\236\133\170\026
+\075\105\342\063\162\335\341\146\312\231\323\311\305\046\375\015
+\150\004\106\256\266\331\233\214\276\031\276\261\306\362\031\343
+\134\002\312\054\330\157\112\007\331\311\065\332\100\165\362\304
+\247\031\157\236\102\020\230\165\346\225\213\140\274\355\305\022
+\327\212\316\325\230\134\126\226\003\305\356\167\006\065\377\317
+\344\356\077\023\141\356\333\332\055\205\360\315\256\235\262\030
+\011\105\303\222\241\162\027\374\107\266\240\013\054\361\304\336
+\103\150\010\152\137\073\360\166\143\373\314\006\054\246\306\342
+\016\265\271\276\044\217
+END
+
+# Trust for "Certum Trusted Network CA 2"
+# Issuer: CN=Certum Trusted Network CA 2,OU=Certum Certification Authority,O=Unizeto Technologies S.A.,C=PL
+# Serial Number:21:d6:d0:4a:4f:25:0f:c9:32:37:fc:aa:5e:12:8d:e9
+# Subject: CN=Certum Trusted Network CA 2,OU=Certum Certification Authority,O=Unizeto Technologies S.A.,C=PL
+# Not Valid Before: Thu Oct 06 08:39:56 2011
+# Not Valid After : Sat Oct 06 08:39:56 2046
+# Fingerprint (SHA-256): B6:76:F2:ED:DA:E8:77:5C:D3:6C:B0:F6:3C:D1:D4:60:39:61:F4:9E:62:65:BA:01:3A:2F:03:07:B6:D0:B8:04
+# Fingerprint (SHA1): D3:DD:48:3E:2B:BF:4C:05:E8:AF:10:F5:FA:76:26:CF:D3:DC:30:92
+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 2"
+CKA_CERT_SHA1_HASH MULTILINE_OCTAL
+\323\335\110\076\053\277\114\005\350\257\020\365\372\166\046\317
+\323\334\060\222
+END
+CKA_CERT_MD5_HASH MULTILINE_OCTAL
+\155\106\236\331\045\155\010\043\133\136\164\175\036\047\333\362
+END
+CKA_ISSUER MULTILINE_OCTAL
+\060\201\200\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\044\060
+\042\006\003\125\004\003\023\033\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\040\062
+END
+CKA_SERIAL_NUMBER MULTILINE_OCTAL
+\002\020\041\326\320\112\117\045\017\311\062\067\374\252\136\022
+\215\351
+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 "Hellenic Academic and Research Institutions RootCA 2015"
+#
+# Issuer: CN=Hellenic Academic and Research Institutions RootCA 2015,O=Hellenic Academic and Research Institutions Cert. Authority,L=Athens,C=GR
+# Serial Number: 0 (0x0)
+# Subject: CN=Hellenic Academic and Research Institutions RootCA 2015,O=Hellenic Academic and Research Institutions Cert. Authority,L=Athens,C=GR
+# Not Valid Before: Tue Jul 07 10:11:21 2015
+# Not Valid After : Sat Jun 30 10:11:21 2040
+# Fingerprint (SHA-256): A0:40:92:9A:02:CE:53:B4:AC:F4:F2:FF:C6:98:1C:E4:49:6F:75:5E:6D:45:FE:0B:2A:69:2B:CD:52:52:3F:36
+# Fingerprint (SHA1): 01:0C:06:95:A6:98:19:14:FF:BF:5F:C6:B0:B6:95:EA:29:E9:12:A6
+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 2015"
+CKA_CERTIFICATE_TYPE CK_CERTIFICATE_TYPE CKC_X_509
+CKA_SUBJECT MULTILINE_OCTAL
+\060\201\246\061\013\060\011\006\003\125\004\006\023\002\107\122
+\061\017\060\015\006\003\125\004\007\023\006\101\164\150\145\156
+\163\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\065
+END
+CKA_ID UTF8 "0"
+CKA_ISSUER MULTILINE_OCTAL
+\060\201\246\061\013\060\011\006\003\125\004\006\023\002\107\122
+\061\017\060\015\006\003\125\004\007\023\006\101\164\150\145\156
+\163\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\065
+END
+CKA_SERIAL_NUMBER MULTILINE_OCTAL
+\002\001\000
+END
+CKA_VALUE MULTILINE_OCTAL
+\060\202\006\013\060\202\003\363\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\246\061\013\060\011\006\003\125\004\006\023\002\107\122\061
+\017\060\015\006\003\125\004\007\023\006\101\164\150\145\156\163
+\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\065\060\036\027\015\061\065\060\067
+\060\067\061\060\061\061\062\061\132\027\015\064\060\060\066\063
+\060\061\060\061\061\062\061\132\060\201\246\061\013\060\011\006
+\003\125\004\006\023\002\107\122\061\017\060\015\006\003\125\004
+\007\023\006\101\164\150\145\156\163\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
+\065\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\302\370\251\077\033\211\374\074\074\004\135\075\220\066
+\260\221\072\171\074\146\132\357\155\071\001\111\032\264\267\317
+\177\115\043\123\267\220\000\343\023\052\050\246\061\361\221\000
+\343\050\354\256\041\101\316\037\332\375\175\022\133\001\203\017
+\271\260\137\231\341\362\022\203\200\115\006\076\337\254\257\347
+\241\210\153\061\257\360\213\320\030\063\270\333\105\152\064\364
+\002\200\044\050\012\002\025\225\136\166\052\015\231\072\024\133
+\366\313\313\123\274\023\115\001\210\067\224\045\033\102\274\042
+\330\216\243\226\136\072\331\062\333\076\350\360\020\145\355\164
+\341\057\247\174\257\047\064\273\051\175\233\266\317\011\310\345
+\323\012\374\210\145\145\164\012\334\163\034\134\315\100\261\034
+\324\266\204\214\114\120\317\150\216\250\131\256\302\047\116\202
+\242\065\335\024\364\037\377\262\167\325\207\057\252\156\175\044
+\047\347\306\313\046\346\345\376\147\007\143\330\105\015\335\072
+\131\145\071\130\172\222\231\162\075\234\204\136\210\041\270\325
+\364\054\374\331\160\122\117\170\270\275\074\053\213\225\230\365
+\263\321\150\317\040\024\176\114\134\137\347\213\345\365\065\201
+\031\067\327\021\010\267\146\276\323\112\316\203\127\000\072\303
+\201\370\027\313\222\066\135\321\243\330\165\033\341\213\047\352
+\172\110\101\375\105\031\006\255\047\231\116\301\160\107\335\265
+\237\201\123\022\345\261\214\110\135\061\103\027\343\214\306\172
+\143\226\113\051\060\116\204\116\142\031\136\074\316\227\220\245
+\177\001\353\235\340\370\213\211\335\045\230\075\222\266\176\357
+\331\361\121\121\175\055\046\310\151\131\141\340\254\152\270\052
+\066\021\004\172\120\275\062\204\276\057\334\162\325\327\035\026
+\107\344\107\146\040\077\364\226\305\257\216\001\172\245\017\172
+\144\365\015\030\207\331\256\210\325\372\204\301\072\300\151\050
+\055\362\015\150\121\252\343\245\167\306\244\220\016\241\067\213
+\061\043\107\301\011\010\353\156\367\170\233\327\202\374\204\040
+\231\111\031\266\022\106\261\373\105\125\026\251\243\145\254\234
+\007\017\352\153\334\037\056\006\162\354\206\210\022\344\055\333
+\137\005\057\344\360\003\323\046\063\347\200\302\315\102\241\027
+\064\013\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\161\025\147\310\310\311\275\165\135
+\162\320\070\030\152\235\363\161\044\124\013\060\015\006\011\052
+\206\110\206\367\015\001\001\013\005\000\003\202\002\001\000\165
+\273\155\124\113\252\020\130\106\064\362\142\327\026\066\135\010
+\136\325\154\310\207\275\264\056\106\362\061\370\174\352\102\265
+\223\026\125\334\241\014\022\240\332\141\176\017\130\130\163\144
+\162\307\350\105\216\334\251\362\046\077\306\171\214\261\123\010
+\063\201\260\126\023\276\346\121\134\330\233\012\117\113\234\126
+\123\002\351\117\366\015\140\352\115\102\125\350\174\033\041\041
+\323\033\072\314\167\362\270\220\361\150\307\371\132\376\372\055
+\364\277\311\365\105\033\316\070\020\052\067\212\171\243\264\343
+\011\154\205\206\223\377\211\226\047\170\201\217\147\343\106\164
+\124\216\331\015\151\342\112\364\115\164\003\377\262\167\355\225
+\147\227\344\261\305\253\277\152\043\350\324\224\342\104\050\142
+\304\113\342\360\330\342\051\153\032\160\176\044\141\223\173\117
+\003\062\045\015\105\044\053\226\264\106\152\277\112\013\367\232
+\217\301\254\032\305\147\363\157\064\322\372\163\143\214\357\026
+\260\250\244\106\052\370\353\022\354\162\264\357\370\053\176\214
+\122\300\213\204\124\371\057\076\343\125\250\334\146\261\331\341
+\137\330\263\214\131\064\131\244\253\117\154\273\037\030\333\165
+\253\330\313\222\315\224\070\141\016\007\006\037\113\106\020\361
+\025\276\215\205\134\073\112\053\201\171\017\264\151\237\111\120
+\227\115\367\016\126\135\300\225\152\302\066\303\033\150\311\365
+\052\334\107\232\276\262\316\305\045\350\372\003\271\332\371\026
+\156\221\204\365\034\050\310\374\046\314\327\034\220\126\247\137
+\157\072\004\274\315\170\211\013\216\017\057\243\252\117\242\033
+\022\075\026\010\100\017\361\106\114\327\252\173\010\301\012\365
+\155\047\336\002\217\312\303\265\053\312\351\353\310\041\123\070
+\245\314\073\330\167\067\060\242\117\331\157\321\362\100\255\101
+\172\027\305\326\112\065\211\267\101\325\174\206\177\125\115\203
+\112\245\163\040\300\072\257\220\361\232\044\216\331\216\161\312
+\173\270\206\332\262\217\231\076\035\023\015\022\021\356\324\253
+\360\351\025\166\002\344\340\337\252\040\036\133\141\205\144\100
+\251\220\227\015\255\123\322\132\035\207\152\000\227\145\142\264
+\276\157\152\247\365\054\102\355\062\255\266\041\236\276\274
+END
+
+# Trust for "Hellenic Academic and Research Institutions RootCA 2015"
+# Issuer: CN=Hellenic Academic and Research Institutions RootCA 2015,O=Hellenic Academic and Research Institutions Cert. Authority,L=Athens,C=GR
+# Serial Number: 0 (0x0)
+# Subject: CN=Hellenic Academic and Research Institutions RootCA 2015,O=Hellenic Academic and Research Institutions Cert. Authority,L=Athens,C=GR
+# Not Valid Before: Tue Jul 07 10:11:21 2015
+# Not Valid After : Sat Jun 30 10:11:21 2040
+# Fingerprint (SHA-256): A0:40:92:9A:02:CE:53:B4:AC:F4:F2:FF:C6:98:1C:E4:49:6F:75:5E:6D:45:FE:0B:2A:69:2B:CD:52:52:3F:36
+# Fingerprint (SHA1): 01:0C:06:95:A6:98:19:14:FF:BF:5F:C6:B0:B6:95:EA:29:E9:12:A6
+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 2015"
+CKA_CERT_SHA1_HASH MULTILINE_OCTAL
+\001\014\006\225\246\230\031\024\377\277\137\306\260\266\225\352
+\051\351\022\246
+END
+CKA_CERT_MD5_HASH MULTILINE_OCTAL
+\312\377\342\333\003\331\313\113\351\017\255\204\375\173\030\316
+END
+CKA_ISSUER MULTILINE_OCTAL
+\060\201\246\061\013\060\011\006\003\125\004\006\023\002\107\122
+\061\017\060\015\006\003\125\004\007\023\006\101\164\150\145\156
+\163\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\065
+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_MUST_VERIFY_TRUST
+CKA_TRUST_STEP_UP_APPROVED CK_BBOOL CK_FALSE
+
+#
+# Certificate "Hellenic Academic and Research Institutions ECC RootCA 2015"
+#
+# Issuer: CN=Hellenic Academic and Research Institutions ECC RootCA 2015,O=Hellenic Academic and Research Institutions Cert. Authority,L=Athens,C=GR
+# Serial Number: 0 (0x0)
+# Subject: CN=Hellenic Academic and Research Institutions ECC RootCA 2015,O=Hellenic Academic and Research Institutions Cert. Authority,L=Athens,C=GR
+# Not Valid Before: Tue Jul 07 10:37:12 2015
+# Not Valid After : Sat Jun 30 10:37:12 2040
+# Fingerprint (SHA-256): 44:B5:45:AA:8A:25:E6:5A:73:CA:15:DC:27:FC:36:D2:4C:1C:B9:95:3A:06:65:39:B1:15:82:DC:48:7B:48:33
+# Fingerprint (SHA1): 9F:F1:71:8D:92:D5:9A:F3:7D:74:97:B4:BC:6F:84:68:0B:BA:B6:66
+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 ECC RootCA 2015"
+CKA_CERTIFICATE_TYPE CK_CERTIFICATE_TYPE CKC_X_509
+CKA_SUBJECT MULTILINE_OCTAL
+\060\201\252\061\013\060\011\006\003\125\004\006\023\002\107\122
+\061\017\060\015\006\003\125\004\007\023\006\101\164\150\145\156
+\163\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\104\060\102\006\003\125\004\003
+\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\105\103
+\103\040\122\157\157\164\103\101\040\062\060\061\065
+END
+CKA_ID UTF8 "0"
+CKA_ISSUER MULTILINE_OCTAL
+\060\201\252\061\013\060\011\006\003\125\004\006\023\002\107\122
+\061\017\060\015\006\003\125\004\007\023\006\101\164\150\145\156
+\163\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\104\060\102\006\003\125\004\003
+\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\105\103
+\103\040\122\157\157\164\103\101\040\062\060\061\065
+END
+CKA_SERIAL_NUMBER MULTILINE_OCTAL
+\002\001\000
+END
+CKA_VALUE MULTILINE_OCTAL
+\060\202\002\303\060\202\002\112\240\003\002\001\002\002\001\000
+\060\012\006\010\052\206\110\316\075\004\003\002\060\201\252\061
+\013\060\011\006\003\125\004\006\023\002\107\122\061\017\060\015
+\006\003\125\004\007\023\006\101\164\150\145\156\163\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\104\060\102\006\003\125\004\003\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\105\103\103\040\122\157
+\157\164\103\101\040\062\060\061\065\060\036\027\015\061\065\060
+\067\060\067\061\060\063\067\061\062\132\027\015\064\060\060\066
+\063\060\061\060\063\067\061\062\132\060\201\252\061\013\060\011
+\006\003\125\004\006\023\002\107\122\061\017\060\015\006\003\125
+\004\007\023\006\101\164\150\145\156\163\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\104\060\102\006\003\125\004\003\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\105\103\103\040\122\157\157\164\103
+\101\040\062\060\061\065\060\166\060\020\006\007\052\206\110\316
+\075\002\001\006\005\053\201\004\000\042\003\142\000\004\222\240
+\101\350\113\202\204\134\342\370\061\021\231\206\144\116\011\045
+\057\235\101\057\012\256\065\117\164\225\262\121\144\153\215\153
+\346\077\160\225\360\005\104\107\246\162\070\120\166\225\002\132
+\216\256\050\236\371\055\116\231\357\054\110\157\114\045\051\350
+\321\161\133\337\035\301\165\067\264\327\372\173\172\102\234\152
+\012\126\132\174\151\013\252\200\011\044\154\176\301\106\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\264\042
+\013\202\231\044\001\016\234\273\344\016\375\277\373\227\040\223
+\231\052\060\012\006\010\052\206\110\316\075\004\003\002\003\147
+\000\060\144\002\060\147\316\026\142\070\242\254\142\105\247\251
+\225\044\300\032\047\234\062\073\300\300\325\272\251\347\370\004
+\103\123\205\356\122\041\336\235\365\045\203\076\236\130\113\057
+\327\147\023\016\041\002\060\005\341\165\001\336\150\355\052\037
+\115\114\011\010\015\354\113\255\144\027\050\347\165\316\105\145
+\162\041\027\313\042\101\016\214\023\230\070\232\124\155\233\312
+\342\174\352\002\130\042\221
+END
+
+# Trust for "Hellenic Academic and Research Institutions ECC RootCA 2015"
+# Issuer: CN=Hellenic Academic and Research Institutions ECC RootCA 2015,O=Hellenic Academic and Research Institutions Cert. Authority,L=Athens,C=GR
+# Serial Number: 0 (0x0)
+# Subject: CN=Hellenic Academic and Research Institutions ECC RootCA 2015,O=Hellenic Academic and Research Institutions Cert. Authority,L=Athens,C=GR
+# Not Valid Before: Tue Jul 07 10:37:12 2015
+# Not Valid After : Sat Jun 30 10:37:12 2040
+# Fingerprint (SHA-256): 44:B5:45:AA:8A:25:E6:5A:73:CA:15:DC:27:FC:36:D2:4C:1C:B9:95:3A:06:65:39:B1:15:82:DC:48:7B:48:33
+# Fingerprint (SHA1): 9F:F1:71:8D:92:D5:9A:F3:7D:74:97:B4:BC:6F:84:68:0B:BA:B6:66
+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 ECC RootCA 2015"
+CKA_CERT_SHA1_HASH MULTILINE_OCTAL
+\237\361\161\215\222\325\232\363\175\164\227\264\274\157\204\150
+\013\272\266\146
+END
+CKA_CERT_MD5_HASH MULTILINE_OCTAL
+\201\345\264\027\353\302\365\341\113\015\101\173\111\222\376\357
+END
+CKA_ISSUER MULTILINE_OCTAL
+\060\201\252\061\013\060\011\006\003\125\004\006\023\002\107\122
+\061\017\060\015\006\003\125\004\007\023\006\101\164\150\145\156
+\163\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\104\060\102\006\003\125\004\003
+\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\105\103
+\103\040\122\157\157\164\103\101\040\062\060\061\065
+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_MUST_VERIFY_TRUST
+CKA_TRUST_STEP_UP_APPROVED CK_BBOOL CK_FALSE
+
+#
+# Certificate "Certplus Root CA G1"
+#
+# Issuer: CN=Certplus Root CA G1,O=Certplus,C=FR
+# Serial Number:11:20:55:83:e4:2d:3e:54:56:85:2d:83:37:b7:2c:dc:46:11
+# Subject: CN=Certplus Root CA G1,O=Certplus,C=FR
+# Not Valid Before: Mon May 26 00:00:00 2014
+# Not Valid After : Fri Jan 15 00:00:00 2038
+# Fingerprint (SHA-256): 15:2A:40:2B:FC:DF:2C:D5:48:05:4D:22:75:B3:9C:7F:CA:3E:C0:97:80:78:B0:F0:EA:76:E5:61:A6:C7:43:3E
+# Fingerprint (SHA1): 22:FD:D0:B7:FD:A2:4E:0D:AC:49:2C:A0:AC:A6:7B:6A:1F:E3:F7:66
+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 Root CA G1"
+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\106\122\061
+\021\060\017\006\003\125\004\012\014\010\103\145\162\164\160\154
+\165\163\061\034\060\032\006\003\125\004\003\014\023\103\145\162
+\164\160\154\165\163\040\122\157\157\164\040\103\101\040\107\061
+END
+CKA_ID UTF8 "0"
+CKA_ISSUER MULTILINE_OCTAL
+\060\076\061\013\060\011\006\003\125\004\006\023\002\106\122\061
+\021\060\017\006\003\125\004\012\014\010\103\145\162\164\160\154
+\165\163\061\034\060\032\006\003\125\004\003\014\023\103\145\162
+\164\160\154\165\163\040\122\157\157\164\040\103\101\040\107\061
+END
+CKA_SERIAL_NUMBER MULTILINE_OCTAL
+\002\022\021\040\125\203\344\055\076\124\126\205\055\203\067\267
+\054\334\106\021
+END
+CKA_VALUE MULTILINE_OCTAL
+\060\202\005\153\060\202\003\123\240\003\002\001\002\002\022\021
+\040\125\203\344\055\076\124\126\205\055\203\067\267\054\334\106
+\021\060\015\006\011\052\206\110\206\367\015\001\001\015\005\000
+\060\076\061\013\060\011\006\003\125\004\006\023\002\106\122\061
+\021\060\017\006\003\125\004\012\014\010\103\145\162\164\160\154
+\165\163\061\034\060\032\006\003\125\004\003\014\023\103\145\162
+\164\160\154\165\163\040\122\157\157\164\040\103\101\040\107\061
+\060\036\027\015\061\064\060\065\062\066\060\060\060\060\060\060
+\132\027\015\063\070\060\061\061\065\060\060\060\060\060\060\132
+\060\076\061\013\060\011\006\003\125\004\006\023\002\106\122\061
+\021\060\017\006\003\125\004\012\014\010\103\145\162\164\160\154
+\165\163\061\034\060\032\006\003\125\004\003\014\023\103\145\162
+\164\160\154\165\163\040\122\157\157\164\040\103\101\040\107\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\332\120\207\266\332\270\251\076\235\144\372\126\063\232\126
+\075\026\345\003\225\262\064\034\232\155\142\005\324\330\217\347
+\211\144\237\272\333\144\213\144\346\171\052\141\315\257\217\132
+\211\221\145\271\130\374\264\003\137\221\077\055\020\025\340\176
+\317\274\374\177\103\147\250\255\136\066\043\330\230\263\115\363
+\103\236\071\174\052\374\354\210\325\210\356\160\275\205\026\055
+\352\113\211\074\243\161\102\376\034\375\323\034\055\020\270\206
+\124\352\103\270\333\306\207\332\250\256\200\045\317\172\046\035
+\252\221\260\110\157\256\265\336\236\330\327\372\000\375\306\217
+\320\121\273\142\175\244\261\214\262\377\040\021\272\065\143\005
+\206\107\140\103\063\220\366\107\242\003\117\226\115\235\117\301
+\352\352\234\242\376\064\056\336\267\312\033\166\244\267\255\237
+\351\250\324\170\077\170\376\362\070\011\066\035\322\026\002\310
+\354\052\150\257\365\216\224\357\055\023\172\036\102\112\035\025
+\061\256\014\004\127\374\141\163\363\061\126\206\061\200\240\304
+\021\156\060\166\343\224\360\137\004\304\254\207\162\211\230\305
+\235\314\127\010\232\364\014\374\175\172\005\072\372\107\200\071
+\266\317\204\023\167\157\047\352\377\226\147\027\010\155\351\015
+\326\043\120\060\260\025\164\023\076\345\057\377\016\315\304\013
+\112\135\360\330\000\063\111\146\353\241\030\174\131\056\075\050
+\271\141\161\313\265\245\272\270\352\334\342\160\157\010\152\334
+\207\147\064\357\337\060\162\335\363\311\077\043\377\065\341\276
+\041\051\040\060\201\344\031\245\040\351\045\312\163\061\164\051
+\276\342\102\325\363\262\046\146\307\150\375\031\263\347\040\223
+\231\350\135\340\136\207\347\106\350\045\234\012\051\044\324\315
+\130\206\122\100\044\262\173\017\230\022\040\044\366\220\154\107
+\310\015\273\030\040\056\331\375\374\213\362\051\352\207\164\225
+\340\102\120\170\204\004\101\141\260\364\041\043\217\055\313\050
+\041\362\152\154\364\032\246\305\024\264\067\145\117\225\375\200
+\310\370\162\345\045\153\304\140\261\173\155\216\112\212\163\316
+\131\373\160\172\163\006\023\331\323\164\067\044\101\012\021\157
+\227\334\347\344\176\241\275\025\362\272\207\017\075\150\212\026
+\007\002\003\001\000\001\243\143\060\141\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\250\301\300\233\221\250\103\025\174\135
+\006\047\264\052\121\330\227\013\201\261\060\037\006\003\125\035
+\043\004\030\060\026\200\024\250\301\300\233\221\250\103\025\174
+\135\006\047\264\052\121\330\227\013\201\261\060\015\006\011\052
+\206\110\206\367\015\001\001\015\005\000\003\202\002\001\000\234
+\126\157\001\176\321\275\114\365\212\306\360\046\037\344\340\070
+\030\314\062\303\051\073\235\101\051\064\141\306\327\360\000\241
+\353\244\162\217\224\027\274\023\054\165\264\127\356\012\174\011
+\172\334\325\312\241\320\064\023\370\167\253\237\345\376\330\036
+\164\212\205\007\217\177\314\171\172\312\226\315\315\375\117\373
+\375\043\015\220\365\364\136\323\306\141\175\236\021\340\002\356
+\011\004\331\007\335\246\212\267\014\203\044\273\203\120\222\376
+\140\165\021\076\330\235\260\212\172\265\340\235\233\313\220\122
+\113\260\223\052\324\076\026\063\345\236\306\145\025\076\144\073
+\004\077\333\014\217\137\134\035\151\037\257\363\351\041\214\363
+\357\227\366\232\267\031\266\204\164\234\243\124\265\160\116\143
+\330\127\135\123\041\233\100\222\103\372\326\167\125\063\117\144
+\325\373\320\054\152\216\155\045\246\357\205\350\002\304\123\076
+\271\236\207\274\314\065\032\336\241\351\212\143\207\145\036\021
+\052\333\143\167\227\024\276\232\024\231\021\262\300\356\260\117
+\370\024\041\062\103\117\237\253\242\313\250\017\252\073\006\125
+\306\022\051\127\010\324\067\327\207\047\255\111\131\247\221\253
+\104\172\136\215\160\333\227\316\110\120\261\163\223\366\360\203
+\140\371\315\361\341\061\375\133\174\161\041\143\024\024\252\257
+\305\336\223\176\150\261\354\042\242\252\220\165\236\265\103\162
+\352\144\243\204\113\375\014\250\046\153\161\227\356\126\143\146
+\350\102\124\371\307\035\337\320\217\133\337\310\060\157\210\376
+\015\304\063\034\123\250\243\375\110\020\362\344\012\116\341\025
+\127\374\156\144\060\302\125\021\334\352\251\315\112\124\254\051
+\143\104\317\112\100\240\326\150\131\033\063\371\357\072\213\333
+\040\222\334\102\204\277\001\253\207\300\325\040\202\333\306\271
+\203\205\102\134\017\103\073\152\111\065\325\230\364\025\277\372
+\141\201\014\011\040\030\322\320\027\014\313\110\000\120\351\166
+\202\214\144\327\072\240\007\125\314\036\061\300\357\072\264\145
+\373\343\277\102\153\236\017\250\275\153\230\334\330\333\313\213
+\244\335\327\131\364\156\335\376\252\303\221\320\056\102\007\300
+\014\115\123\315\044\261\114\133\036\121\364\337\351\222\372
+END
+
+# Trust for "Certplus Root CA G1"
+# Issuer: CN=Certplus Root CA G1,O=Certplus,C=FR
+# Serial Number:11:20:55:83:e4:2d:3e:54:56:85:2d:83:37:b7:2c:dc:46:11
+# Subject: CN=Certplus Root CA G1,O=Certplus,C=FR
+# Not Valid Before: Mon May 26 00:00:00 2014
+# Not Valid After : Fri Jan 15 00:00:00 2038
+# Fingerprint (SHA-256): 15:2A:40:2B:FC:DF:2C:D5:48:05:4D:22:75:B3:9C:7F:CA:3E:C0:97:80:78:B0:F0:EA:76:E5:61:A6:C7:43:3E
+# Fingerprint (SHA1): 22:FD:D0:B7:FD:A2:4E:0D:AC:49:2C:A0:AC:A6:7B:6A:1F:E3:F7:66
+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 Root CA G1"
+CKA_CERT_SHA1_HASH MULTILINE_OCTAL
+\042\375\320\267\375\242\116\015\254\111\054\240\254\246\173\152
+\037\343\367\146
+END
+CKA_CERT_MD5_HASH MULTILINE_OCTAL
+\177\011\234\367\331\271\134\151\151\126\325\067\076\024\015\102
+END
+CKA_ISSUER MULTILINE_OCTAL
+\060\076\061\013\060\011\006\003\125\004\006\023\002\106\122\061
+\021\060\017\006\003\125\004\012\014\010\103\145\162\164\160\154
+\165\163\061\034\060\032\006\003\125\004\003\014\023\103\145\162
+\164\160\154\165\163\040\122\157\157\164\040\103\101\040\107\061
+END
+CKA_SERIAL_NUMBER MULTILINE_OCTAL
+\002\022\021\040\125\203\344\055\076\124\126\205\055\203\067\267
+\054\334\106\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 "Certplus Root CA G2"
+#
+# Issuer: CN=Certplus Root CA G2,O=Certplus,C=FR
+# Serial Number:11:20:d9:91:ce:ae:a3:e8:c5:e7:ff:e9:02:af:cf:73:bc:55
+# Subject: CN=Certplus Root CA G2,O=Certplus,C=FR
+# Not Valid Before: Mon May 26 00:00:00 2014
+# Not Valid After : Fri Jan 15 00:00:00 2038
+# Fingerprint (SHA-256): 6C:C0:50:41:E6:44:5E:74:69:6C:4C:FB:C9:F8:0F:54:3B:7E:AB:BB:44:B4:CE:6F:78:7C:6A:99:71:C4:2F:17
+# Fingerprint (SHA1): 4F:65:8E:1F:E9:06:D8:28:02:E9:54:47:41:C9:54:25:5D:69:CC:1A
+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 Root CA G2"
+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\106\122\061
+\021\060\017\006\003\125\004\012\014\010\103\145\162\164\160\154
+\165\163\061\034\060\032\006\003\125\004\003\014\023\103\145\162
+\164\160\154\165\163\040\122\157\157\164\040\103\101\040\107\062
+END
+CKA_ID UTF8 "0"
+CKA_ISSUER MULTILINE_OCTAL
+\060\076\061\013\060\011\006\003\125\004\006\023\002\106\122\061
+\021\060\017\006\003\125\004\012\014\010\103\145\162\164\160\154
+\165\163\061\034\060\032\006\003\125\004\003\014\023\103\145\162
+\164\160\154\165\163\040\122\157\157\164\040\103\101\040\107\062
+END
+CKA_SERIAL_NUMBER MULTILINE_OCTAL
+\002\022\021\040\331\221\316\256\243\350\305\347\377\351\002\257
+\317\163\274\125
+END
+CKA_VALUE MULTILINE_OCTAL
+\060\202\002\034\060\202\001\242\240\003\002\001\002\002\022\021
+\040\331\221\316\256\243\350\305\347\377\351\002\257\317\163\274
+\125\060\012\006\010\052\206\110\316\075\004\003\003\060\076\061
+\013\060\011\006\003\125\004\006\023\002\106\122\061\021\060\017
+\006\003\125\004\012\014\010\103\145\162\164\160\154\165\163\061
+\034\060\032\006\003\125\004\003\014\023\103\145\162\164\160\154
+\165\163\040\122\157\157\164\040\103\101\040\107\062\060\036\027
+\015\061\064\060\065\062\066\060\060\060\060\060\060\132\027\015
+\063\070\060\061\061\065\060\060\060\060\060\060\132\060\076\061
+\013\060\011\006\003\125\004\006\023\002\106\122\061\021\060\017
+\006\003\125\004\012\014\010\103\145\162\164\160\154\165\163\061
+\034\060\032\006\003\125\004\003\014\023\103\145\162\164\160\154
+\165\163\040\122\157\157\164\040\103\101\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\315\017\133\126\202\337\360\105\032\326\255
+\367\171\360\035\311\254\226\326\236\116\234\037\264\102\021\312
+\206\277\155\373\205\243\305\345\031\134\327\356\246\077\151\147
+\330\170\342\246\311\304\333\055\171\056\347\213\215\002\157\061
+\042\115\006\343\140\162\105\235\016\102\167\236\316\317\345\177
+\205\233\030\344\374\314\056\162\323\026\223\116\312\231\143\134
+\241\005\052\154\006\243\143\060\141\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\332\203\143\002\171\216\332\114\306\074\043
+\024\330\217\303\040\253\050\140\131\060\037\006\003\125\035\043
+\004\030\060\026\200\024\332\203\143\002\171\216\332\114\306\074
+\043\024\330\217\303\040\253\050\140\131\060\012\006\010\052\206
+\110\316\075\004\003\003\003\150\000\060\145\002\060\160\376\260
+\013\331\367\203\227\354\363\125\035\324\334\263\006\016\376\063
+\230\235\213\071\220\153\224\041\355\266\327\135\326\114\327\041
+\247\347\277\041\017\053\315\367\052\334\205\007\235\002\061\000
+\206\024\026\345\334\260\145\302\300\216\024\237\277\044\026\150
+\345\274\371\171\151\334\255\105\053\367\266\061\163\314\006\245
+\123\223\221\032\223\256\160\152\147\272\327\236\345\141\032\137
+END
+
+# Trust for "Certplus Root CA G2"
+# Issuer: CN=Certplus Root CA G2,O=Certplus,C=FR
+# Serial Number:11:20:d9:91:ce:ae:a3:e8:c5:e7:ff:e9:02:af:cf:73:bc:55
+# Subject: CN=Certplus Root CA G2,O=Certplus,C=FR
+# Not Valid Before: Mon May 26 00:00:00 2014
+# Not Valid After : Fri Jan 15 00:00:00 2038
+# Fingerprint (SHA-256): 6C:C0:50:41:E6:44:5E:74:69:6C:4C:FB:C9:F8:0F:54:3B:7E:AB:BB:44:B4:CE:6F:78:7C:6A:99:71:C4:2F:17
+# Fingerprint (SHA1): 4F:65:8E:1F:E9:06:D8:28:02:E9:54:47:41:C9:54:25:5D:69:CC:1A
+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 Root CA G2"
+CKA_CERT_SHA1_HASH MULTILINE_OCTAL
+\117\145\216\037\351\006\330\050\002\351\124\107\101\311\124\045
+\135\151\314\032
+END
+CKA_CERT_MD5_HASH MULTILINE_OCTAL
+\247\356\304\170\055\033\356\055\271\051\316\326\247\226\062\061
+END
+CKA_ISSUER MULTILINE_OCTAL
+\060\076\061\013\060\011\006\003\125\004\006\023\002\106\122\061
+\021\060\017\006\003\125\004\012\014\010\103\145\162\164\160\154
+\165\163\061\034\060\032\006\003\125\004\003\014\023\103\145\162
+\164\160\154\165\163\040\122\157\157\164\040\103\101\040\107\062
+END
+CKA_SERIAL_NUMBER MULTILINE_OCTAL
+\002\022\021\040\331\221\316\256\243\350\305\347\377\351\002\257
+\317\163\274\125
+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 "OpenTrust Root CA G1"
+#
+# Issuer: CN=OpenTrust Root CA G1,O=OpenTrust,C=FR
+# Serial Number:11:20:b3:90:55:39:7d:7f:36:6d:64:c2:a7:9f:6b:63:8e:67
+# Subject: CN=OpenTrust Root CA G1,O=OpenTrust,C=FR
+# Not Valid Before: Mon May 26 08:45:50 2014
+# Not Valid After : Fri Jan 15 00:00:00 2038
+# Fingerprint (SHA-256): 56:C7:71:28:D9:8C:18:D9:1B:4C:FD:FF:BC:25:EE:91:03:D4:75:8E:A2:AB:AD:82:6A:90:F3:45:7D:46:0E:B4
+# Fingerprint (SHA1): 79:91:E8:34:F7:E2:EE:DD:08:95:01:52:E9:55:2D:14:E9:58:D5:7E
+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 "OpenTrust Root CA G1"
+CKA_CERTIFICATE_TYPE CK_CERTIFICATE_TYPE CKC_X_509
+CKA_SUBJECT MULTILINE_OCTAL
+\060\100\061\013\060\011\006\003\125\004\006\023\002\106\122\061
+\022\060\020\006\003\125\004\012\014\011\117\160\145\156\124\162
+\165\163\164\061\035\060\033\006\003\125\004\003\014\024\117\160
+\145\156\124\162\165\163\164\040\122\157\157\164\040\103\101\040
+\107\061
+END
+CKA_ID UTF8 "0"
+CKA_ISSUER MULTILINE_OCTAL
+\060\100\061\013\060\011\006\003\125\004\006\023\002\106\122\061
+\022\060\020\006\003\125\004\012\014\011\117\160\145\156\124\162
+\165\163\164\061\035\060\033\006\003\125\004\003\014\024\117\160
+\145\156\124\162\165\163\164\040\122\157\157\164\040\103\101\040
+\107\061
+END
+CKA_SERIAL_NUMBER MULTILINE_OCTAL
+\002\022\021\040\263\220\125\071\175\177\066\155\144\302\247\237
+\153\143\216\147
+END
+CKA_VALUE MULTILINE_OCTAL
+\060\202\005\157\060\202\003\127\240\003\002\001\002\002\022\021
+\040\263\220\125\071\175\177\066\155\144\302\247\237\153\143\216
+\147\060\015\006\011\052\206\110\206\367\015\001\001\013\005\000
+\060\100\061\013\060\011\006\003\125\004\006\023\002\106\122\061
+\022\060\020\006\003\125\004\012\014\011\117\160\145\156\124\162
+\165\163\164\061\035\060\033\006\003\125\004\003\014\024\117\160
+\145\156\124\162\165\163\164\040\122\157\157\164\040\103\101\040
+\107\061\060\036\027\015\061\064\060\065\062\066\060\070\064\065
+\065\060\132\027\015\063\070\060\061\061\065\060\060\060\060\060
+\060\132\060\100\061\013\060\011\006\003\125\004\006\023\002\106
+\122\061\022\060\020\006\003\125\004\012\014\011\117\160\145\156
+\124\162\165\163\164\061\035\060\033\006\003\125\004\003\014\024
+\117\160\145\156\124\162\165\163\164\040\122\157\157\164\040\103
+\101\040\107\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\370\171\106\332\226\305\060\136\212\161\003
+\055\160\244\273\260\305\010\334\315\346\065\300\200\244\021\055
+\335\346\207\256\135\075\221\322\207\154\067\267\332\142\236\233
+\302\044\327\217\361\333\246\246\337\106\157\121\246\161\313\076
+\033\061\147\142\367\021\133\064\047\325\171\116\214\233\130\275
+\042\020\015\134\047\014\335\060\345\250\323\135\041\070\164\027
+\376\343\037\266\117\073\153\055\333\175\140\037\214\175\114\005
+\302\353\001\026\025\230\024\216\321\220\167\042\077\354\302\071
+\270\171\072\360\111\044\342\225\221\334\141\064\222\214\124\164
+\357\261\175\214\001\342\070\175\301\137\152\137\044\262\216\142
+\027\255\171\040\255\253\035\267\340\264\226\110\117\146\103\020
+\006\026\044\003\341\340\234\216\306\106\117\216\032\231\341\217
+\271\216\063\154\151\336\130\255\240\016\247\144\124\021\151\104
+\146\117\114\022\247\216\054\175\304\324\133\305\000\064\060\301
+\331\231\376\062\316\007\204\264\116\315\012\377\066\115\142\361
+\247\143\127\344\333\152\247\256\277\053\271\311\346\262\047\211
+\345\176\232\034\115\150\306\301\030\336\063\053\121\106\113\034
+\216\367\075\014\371\212\064\024\304\373\063\065\043\361\314\361
+\052\307\245\273\260\242\316\376\123\153\115\101\033\146\050\262
+\226\372\247\256\012\116\271\071\063\104\234\164\301\223\034\370
+\340\236\044\045\103\361\233\043\202\252\337\054\040\260\334\066
+\116\003\263\174\002\324\346\173\032\252\207\023\277\076\241\164
+\273\233\016\341\300\223\237\327\244\146\312\273\033\073\343\060
+\364\063\131\212\007\162\003\125\347\163\152\003\061\156\157\226
+\033\343\242\237\257\222\307\355\365\102\267\045\114\073\023\004
+\317\034\226\257\034\042\243\320\253\005\262\114\022\043\122\334
+\375\031\133\047\234\036\073\172\375\102\043\333\043\200\023\360
+\274\121\025\124\224\246\167\076\320\164\121\275\121\024\010\071
+\067\313\037\064\251\060\235\122\204\056\125\220\261\272\337\125
+\000\013\330\126\055\261\111\111\162\200\251\142\327\300\366\030
+\021\004\125\315\164\173\317\141\160\171\364\173\054\134\134\222
+\374\345\270\132\253\114\223\225\241\047\356\245\276\317\161\043
+\102\272\233\166\055\002\003\001\000\001\243\143\060\141\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\227\106\041\127\041\065
+\332\066\125\307\363\361\067\160\345\010\366\223\051\266\060\037
+\006\003\125\035\043\004\030\060\026\200\024\227\106\041\127\041
+\065\332\066\125\307\363\361\067\160\345\010\366\223\051\266\060
+\015\006\011\052\206\110\206\367\015\001\001\013\005\000\003\202
+\002\001\000\035\335\002\140\174\340\065\247\346\230\173\352\104
+\316\147\100\117\362\223\156\146\324\071\211\046\254\323\115\004
+\074\273\207\041\077\067\364\161\045\332\113\272\253\226\202\201
+\221\266\355\331\261\244\145\227\342\157\144\131\244\226\356\140
+\312\037\043\373\105\272\377\217\044\360\312\251\061\177\171\037
+\200\263\055\062\272\144\147\140\257\271\131\315\337\232\111\323
+\250\202\261\371\230\224\212\314\340\273\340\004\033\231\140\261
+\106\145\334\010\242\262\106\236\104\210\352\223\176\127\026\322
+\025\162\137\056\113\253\324\235\143\270\343\110\345\376\204\056
+\130\012\237\103\035\376\267\030\222\206\103\113\016\234\062\206
+\054\140\365\351\110\352\225\355\160\051\361\325\057\375\065\264
+\127\317\333\205\110\231\271\302\157\154\217\315\170\225\254\144
+\050\375\126\260\303\157\303\276\131\122\341\137\204\217\200\362
+\364\015\066\255\166\263\243\265\341\144\166\072\130\334\175\117
+\136\126\154\345\125\131\127\245\337\361\212\146\060\214\324\122
+\142\070\167\264\276\050\327\312\066\304\233\005\360\370\025\333
+\333\361\357\064\235\035\170\112\210\126\147\156\140\377\217\310
+\213\341\216\275\102\251\063\012\131\102\022\022\052\372\261\235
+\103\216\005\233\231\332\142\255\127\066\263\035\266\015\171\055
+\226\270\353\362\014\113\014\245\224\306\060\247\046\031\055\355
+\114\006\120\060\361\375\130\075\271\113\027\137\031\264\152\204
+\124\264\070\117\071\242\015\226\150\303\050\224\375\355\055\037
+\112\153\103\226\056\220\001\020\373\070\246\201\013\320\277\165
+\323\324\271\316\361\077\157\016\034\036\067\161\345\030\207\165
+\031\077\120\271\136\244\105\064\255\260\312\346\345\023\166\017
+\061\024\251\216\055\224\326\325\205\115\163\025\117\113\362\262
+\076\355\154\275\375\016\235\146\163\260\075\264\367\277\250\340
+\021\244\304\256\165\011\112\143\000\110\040\246\306\235\013\011
+\212\264\340\346\316\076\307\076\046\070\351\053\336\246\010\111
+\003\004\220\212\351\217\277\350\266\264\052\243\043\215\034\034
+\262\071\222\250\217\002\134\100\071\165\324\163\101\002\167\336
+\315\340\103\207\326\344\272\112\303\154\022\177\376\052\346\043
+\326\214\161
+END
+
+# Trust for "OpenTrust Root CA G1"
+# Issuer: CN=OpenTrust Root CA G1,O=OpenTrust,C=FR
+# Serial Number:11:20:b3:90:55:39:7d:7f:36:6d:64:c2:a7:9f:6b:63:8e:67
+# Subject: CN=OpenTrust Root CA G1,O=OpenTrust,C=FR
+# Not Valid Before: Mon May 26 08:45:50 2014
+# Not Valid After : Fri Jan 15 00:00:00 2038
+# Fingerprint (SHA-256): 56:C7:71:28:D9:8C:18:D9:1B:4C:FD:FF:BC:25:EE:91:03:D4:75:8E:A2:AB:AD:82:6A:90:F3:45:7D:46:0E:B4
+# Fingerprint (SHA1): 79:91:E8:34:F7:E2:EE:DD:08:95:01:52:E9:55:2D:14:E9:58:D5:7E
+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 "OpenTrust Root CA G1"
+CKA_CERT_SHA1_HASH MULTILINE_OCTAL
+\171\221\350\064\367\342\356\335\010\225\001\122\351\125\055\024
+\351\130\325\176
+END
+CKA_CERT_MD5_HASH MULTILINE_OCTAL
+\166\000\314\201\051\315\125\136\210\152\172\056\367\115\071\332
+END
+CKA_ISSUER MULTILINE_OCTAL
+\060\100\061\013\060\011\006\003\125\004\006\023\002\106\122\061
+\022\060\020\006\003\125\004\012\014\011\117\160\145\156\124\162
+\165\163\164\061\035\060\033\006\003\125\004\003\014\024\117\160
+\145\156\124\162\165\163\164\040\122\157\157\164\040\103\101\040
+\107\061
+END
+CKA_SERIAL_NUMBER MULTILINE_OCTAL
+\002\022\021\040\263\220\125\071\175\177\066\155\144\302\247\237
+\153\143\216\147
+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 "OpenTrust Root CA G2"
+#
+# Issuer: CN=OpenTrust Root CA G2,O=OpenTrust,C=FR
+# Serial Number:11:20:a1:69:1b:bf:bd:b9:bd:52:96:8f:23:e8:48:bf:26:11
+# Subject: CN=OpenTrust Root CA G2,O=OpenTrust,C=FR
+# Not Valid Before: Mon May 26 00:00:00 2014
+# Not Valid After : Fri Jan 15 00:00:00 2038
+# Fingerprint (SHA-256): 27:99:58:29:FE:6A:75:15:C1:BF:E8:48:F9:C4:76:1D:B1:6C:22:59:29:25:7B:F4:0D:08:94:F2:9E:A8:BA:F2
+# Fingerprint (SHA1): 79:5F:88:60:C5:AB:7C:3D:92:E6:CB:F4:8D:E1:45:CD:11:EF:60:0B
+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 "OpenTrust Root CA G2"
+CKA_CERTIFICATE_TYPE CK_CERTIFICATE_TYPE CKC_X_509
+CKA_SUBJECT MULTILINE_OCTAL
+\060\100\061\013\060\011\006\003\125\004\006\023\002\106\122\061
+\022\060\020\006\003\125\004\012\014\011\117\160\145\156\124\162
+\165\163\164\061\035\060\033\006\003\125\004\003\014\024\117\160
+\145\156\124\162\165\163\164\040\122\157\157\164\040\103\101\040
+\107\062
+END
+CKA_ID UTF8 "0"
+CKA_ISSUER MULTILINE_OCTAL
+\060\100\061\013\060\011\006\003\125\004\006\023\002\106\122\061
+\022\060\020\006\003\125\004\012\014\011\117\160\145\156\124\162
+\165\163\164\061\035\060\033\006\003\125\004\003\014\024\117\160
+\145\156\124\162\165\163\164\040\122\157\157\164\040\103\101\040
+\107\062
+END
+CKA_SERIAL_NUMBER MULTILINE_OCTAL
+\002\022\021\040\241\151\033\277\275\271\275\122\226\217\043\350
+\110\277\046\021
+END
+CKA_VALUE MULTILINE_OCTAL
+\060\202\005\157\060\202\003\127\240\003\002\001\002\002\022\021
+\040\241\151\033\277\275\271\275\122\226\217\043\350\110\277\046
+\021\060\015\006\011\052\206\110\206\367\015\001\001\015\005\000
+\060\100\061\013\060\011\006\003\125\004\006\023\002\106\122\061
+\022\060\020\006\003\125\004\012\014\011\117\160\145\156\124\162
+\165\163\164\061\035\060\033\006\003\125\004\003\014\024\117\160
+\145\156\124\162\165\163\164\040\122\157\157\164\040\103\101\040
+\107\062\060\036\027\015\061\064\060\065\062\066\060\060\060\060
+\060\060\132\027\015\063\070\060\061\061\065\060\060\060\060\060
+\060\132\060\100\061\013\060\011\006\003\125\004\006\023\002\106
+\122\061\022\060\020\006\003\125\004\012\014\011\117\160\145\156
+\124\162\165\163\164\061\035\060\033\006\003\125\004\003\014\024
+\117\160\145\156\124\162\165\163\164\040\122\157\157\164\040\103
+\101\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\314\266\127\245\063\224\020\201\062\123\337
+\141\176\017\166\071\317\134\302\123\165\035\111\172\226\070\335
+\242\163\152\361\157\336\136\242\132\271\161\041\276\066\331\241
+\374\274\356\154\250\174\064\032\161\032\350\032\330\137\016\104
+\006\355\247\340\363\322\141\013\340\062\242\226\321\070\360\302
+\332\001\027\374\344\254\117\350\356\211\036\164\253\117\277\036
+\011\266\066\152\126\363\341\356\226\211\146\044\006\344\315\102
+\072\112\335\340\232\260\304\202\105\263\376\311\253\134\174\076
+\311\353\027\057\014\175\156\256\245\217\310\254\045\012\157\372
+\325\105\230\322\065\011\366\003\103\224\376\331\277\040\225\171
+\200\230\212\331\211\065\273\121\033\244\067\175\374\231\073\253
+\377\277\254\015\217\103\261\231\173\026\020\176\035\157\107\304
+\025\217\004\226\010\006\102\004\370\204\326\035\274\221\246\102
+\276\111\325\152\210\077\274\055\121\321\236\215\340\122\314\127
+\335\065\065\130\333\264\217\044\210\344\213\337\334\153\124\322
+\201\053\262\316\222\113\034\037\106\372\035\330\222\313\166\147
+\265\011\231\011\345\254\027\024\125\160\306\074\240\126\012\003
+\263\334\142\031\337\310\265\060\177\365\074\046\165\021\275\327
+\033\263\207\236\007\257\145\161\345\240\317\032\247\011\020\035
+\223\211\146\133\350\074\142\062\265\265\072\156\351\205\001\213
+\236\103\214\147\163\050\131\133\353\343\334\054\314\245\046\162
+\142\022\264\346\234\203\104\366\121\244\342\300\172\044\127\312
+\016\245\077\072\265\073\213\345\166\356\160\346\222\336\026\134
+\050\133\227\031\047\222\376\172\222\124\316\223\071\012\026\207
+\274\143\263\365\261\223\134\340\156\267\320\352\371\142\062\210
+\104\373\277\047\050\266\060\225\135\022\050\271\225\276\217\123
+\030\345\242\030\026\342\126\244\262\054\020\365\035\067\246\370
+\267\366\320\131\134\211\367\302\325\265\224\164\321\325\376\033
+\266\360\346\326\036\173\322\074\313\250\343\365\030\363\041\037
+\156\357\115\150\006\173\055\135\156\103\211\246\300\371\240\277
+\202\036\317\123\177\264\353\054\333\135\366\152\175\100\044\005
+\162\211\070\001\223\313\161\302\071\135\006\021\366\157\170\370
+\067\015\071\204\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\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\071\372\102\042\367
+\346\211\000\115\136\175\063\203\313\270\156\167\206\257\060\037
+\006\003\125\035\043\004\030\060\026\200\024\152\071\372\102\042
+\367\346\211\000\115\136\175\063\203\313\270\156\167\206\257\060
+\015\006\011\052\206\110\206\367\015\001\001\015\005\000\003\202
+\002\001\000\230\313\253\100\074\345\063\002\227\177\055\207\246
+\217\324\136\112\257\270\036\347\273\161\373\200\144\045\251\263
+\032\076\150\135\047\046\247\272\052\341\360\127\203\012\144\117
+\036\042\164\033\351\220\137\360\254\317\377\117\150\172\070\244
+\020\154\015\261\307\244\167\200\030\266\242\050\104\166\247\064
+\235\161\204\057\312\131\322\107\210\231\101\042\311\060\230\141
+\156\075\250\250\005\155\321\037\300\121\104\126\177\047\065\002
+\335\136\230\012\102\353\060\277\215\241\233\121\252\073\352\223
+\106\144\305\000\171\336\041\153\366\127\240\206\327\006\162\354
+\160\106\113\213\163\335\240\041\165\076\334\035\300\217\323\117
+\163\034\205\331\376\177\142\310\225\157\266\323\173\214\272\123
+\302\157\233\104\114\171\320\035\160\263\327\237\002\364\262\007
+\260\307\345\370\255\043\016\246\126\311\051\022\167\110\331\057
+\106\375\073\360\374\164\160\222\245\216\070\010\037\144\060\266
+\267\113\373\066\254\020\216\240\122\063\143\235\003\065\126\305
+\151\275\306\043\132\047\224\366\244\022\370\055\063\074\241\126
+\245\137\326\031\351\355\174\010\275\167\315\047\144\314\224\332
+\116\106\120\207\340\371\301\123\200\036\273\255\373\107\122\213
+\033\375\242\371\336\016\042\267\075\063\131\154\324\336\365\225
+\006\062\015\121\031\101\134\076\117\006\367\271\053\200\047\366
+\243\252\172\174\006\341\103\303\023\071\142\032\066\275\340\050
+\056\224\002\344\051\056\140\125\256\100\075\260\164\222\136\360
+\040\144\226\077\137\105\135\210\265\212\332\002\240\133\105\124
+\336\070\075\011\300\250\112\145\106\026\374\252\277\124\116\115
+\133\276\070\103\267\050\312\213\063\252\032\045\272\045\134\051
+\057\133\112\156\214\352\055\234\052\366\005\166\340\167\227\200
+\210\335\147\023\157\035\150\044\213\117\267\164\201\345\364\140
+\237\172\125\327\076\067\332\026\153\076\167\254\256\030\160\225
+\010\171\051\003\212\376\301\073\263\077\032\017\244\073\136\037
+\130\241\225\311\253\057\163\112\320\055\156\232\131\017\125\030
+\170\055\074\121\246\227\213\346\273\262\160\252\114\021\336\377
+\174\053\067\324\172\321\167\064\217\347\371\102\367\074\201\014
+\113\122\012
+END
+
+# Trust for "OpenTrust Root CA G2"
+# Issuer: CN=OpenTrust Root CA G2,O=OpenTrust,C=FR
+# Serial Number:11:20:a1:69:1b:bf:bd:b9:bd:52:96:8f:23:e8:48:bf:26:11
+# Subject: CN=OpenTrust Root CA G2,O=OpenTrust,C=FR
+# Not Valid Before: Mon May 26 00:00:00 2014
+# Not Valid After : Fri Jan 15 00:00:00 2038
+# Fingerprint (SHA-256): 27:99:58:29:FE:6A:75:15:C1:BF:E8:48:F9:C4:76:1D:B1:6C:22:59:29:25:7B:F4:0D:08:94:F2:9E:A8:BA:F2
+# Fingerprint (SHA1): 79:5F:88:60:C5:AB:7C:3D:92:E6:CB:F4:8D:E1:45:CD:11:EF:60:0B
+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 "OpenTrust Root CA G2"
+CKA_CERT_SHA1_HASH MULTILINE_OCTAL
+\171\137\210\140\305\253\174\075\222\346\313\364\215\341\105\315
+\021\357\140\013
+END
+CKA_CERT_MD5_HASH MULTILINE_OCTAL
+\127\044\266\131\044\153\256\310\376\034\014\040\362\300\116\353
+END
+CKA_ISSUER MULTILINE_OCTAL
+\060\100\061\013\060\011\006\003\125\004\006\023\002\106\122\061
+\022\060\020\006\003\125\004\012\014\011\117\160\145\156\124\162
+\165\163\164\061\035\060\033\006\003\125\004\003\014\024\117\160
+\145\156\124\162\165\163\164\040\122\157\157\164\040\103\101\040
+\107\062
+END
+CKA_SERIAL_NUMBER MULTILINE_OCTAL
+\002\022\021\040\241\151\033\277\275\271\275\122\226\217\043\350
+\110\277\046\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 "OpenTrust Root CA G3"
+#
+# Issuer: CN=OpenTrust Root CA G3,O=OpenTrust,C=FR
+# Serial Number:11:20:e6:f8:4c:fc:24:b0:be:05:40:ac:da:83:1b:34:60:3f
+# Subject: CN=OpenTrust Root CA G3,O=OpenTrust,C=FR
+# Not Valid Before: Mon May 26 00:00:00 2014
+# Not Valid After : Fri Jan 15 00:00:00 2038
+# Fingerprint (SHA-256): B7:C3:62:31:70:6E:81:07:8C:36:7C:B8:96:19:8F:1E:32:08:DD:92:69:49:DD:8F:57:09:A4:10:F7:5B:62:92
+# Fingerprint (SHA1): 6E:26:64:F3:56:BF:34:55:BF:D1:93:3F:7C:01:DE:D8:13:DA:8A:A6
+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 "OpenTrust Root CA G3"
+CKA_CERTIFICATE_TYPE CK_CERTIFICATE_TYPE CKC_X_509
+CKA_SUBJECT MULTILINE_OCTAL
+\060\100\061\013\060\011\006\003\125\004\006\023\002\106\122\061
+\022\060\020\006\003\125\004\012\014\011\117\160\145\156\124\162
+\165\163\164\061\035\060\033\006\003\125\004\003\014\024\117\160
+\145\156\124\162\165\163\164\040\122\157\157\164\040\103\101\040
+\107\063
+END
+CKA_ID UTF8 "0"
+CKA_ISSUER MULTILINE_OCTAL
+\060\100\061\013\060\011\006\003\125\004\006\023\002\106\122\061
+\022\060\020\006\003\125\004\012\014\011\117\160\145\156\124\162
+\165\163\164\061\035\060\033\006\003\125\004\003\014\024\117\160
+\145\156\124\162\165\163\164\040\122\157\157\164\040\103\101\040
+\107\063
+END
+CKA_SERIAL_NUMBER MULTILINE_OCTAL
+\002\022\021\040\346\370\114\374\044\260\276\005\100\254\332\203
+\033\064\140\077
+END
+CKA_VALUE MULTILINE_OCTAL
+\060\202\002\041\060\202\001\246\240\003\002\001\002\002\022\021
+\040\346\370\114\374\044\260\276\005\100\254\332\203\033\064\140
+\077\060\012\006\010\052\206\110\316\075\004\003\003\060\100\061
+\013\060\011\006\003\125\004\006\023\002\106\122\061\022\060\020
+\006\003\125\004\012\014\011\117\160\145\156\124\162\165\163\164
+\061\035\060\033\006\003\125\004\003\014\024\117\160\145\156\124
+\162\165\163\164\040\122\157\157\164\040\103\101\040\107\063\060
+\036\027\015\061\064\060\065\062\066\060\060\060\060\060\060\132
+\027\015\063\070\060\061\061\065\060\060\060\060\060\060\132\060
+\100\061\013\060\011\006\003\125\004\006\023\002\106\122\061\022
+\060\020\006\003\125\004\012\014\011\117\160\145\156\124\162\165
+\163\164\061\035\060\033\006\003\125\004\003\014\024\117\160\145
+\156\124\162\165\163\164\040\122\157\157\164\040\103\101\040\107
+\063\060\166\060\020\006\007\052\206\110\316\075\002\001\006\005
+\053\201\004\000\042\003\142\000\004\112\356\130\256\115\312\146
+\336\006\072\243\021\374\340\030\360\156\034\272\055\060\014\211
+\331\326\356\233\163\203\251\043\025\214\057\131\212\132\335\024
+\352\235\131\053\103\267\006\354\062\266\272\356\101\265\255\135
+\241\205\314\352\035\024\146\243\147\176\106\342\224\363\347\266
+\126\241\025\131\241\117\067\227\271\042\036\275\021\353\364\262
+\037\136\303\024\232\345\331\227\231\243\143\060\141\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\107\167\303\024\213\142\071
+\014\311\157\341\120\115\320\020\130\334\225\210\155\060\037\006
+\003\125\035\043\004\030\060\026\200\024\107\167\303\024\213\142
+\071\014\311\157\341\120\115\320\020\130\334\225\210\155\060\012
+\006\010\052\206\110\316\075\004\003\003\003\151\000\060\146\002
+\061\000\217\250\334\235\272\014\004\027\372\025\351\075\057\051
+\001\227\277\201\026\063\100\223\154\374\371\355\200\160\157\252
+\217\333\204\302\213\365\065\312\006\334\144\157\150\026\341\217
+\221\271\002\061\000\330\113\245\313\302\320\010\154\351\030\373
+\132\335\115\137\044\013\260\000\041\045\357\217\247\004\046\161
+\342\174\151\345\135\232\370\101\037\073\071\223\223\235\125\352
+\315\215\361\373\301
+END
+
+# Trust for "OpenTrust Root CA G3"
+# Issuer: CN=OpenTrust Root CA G3,O=OpenTrust,C=FR
+# Serial Number:11:20:e6:f8:4c:fc:24:b0:be:05:40:ac:da:83:1b:34:60:3f
+# Subject: CN=OpenTrust Root CA G3,O=OpenTrust,C=FR
+# Not Valid Before: Mon May 26 00:00:00 2014
+# Not Valid After : Fri Jan 15 00:00:00 2038
+# Fingerprint (SHA-256): B7:C3:62:31:70:6E:81:07:8C:36:7C:B8:96:19:8F:1E:32:08:DD:92:69:49:DD:8F:57:09:A4:10:F7:5B:62:92
+# Fingerprint (SHA1): 6E:26:64:F3:56:BF:34:55:BF:D1:93:3F:7C:01:DE:D8:13:DA:8A:A6
+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 "OpenTrust Root CA G3"
+CKA_CERT_SHA1_HASH MULTILINE_OCTAL
+\156\046\144\363\126\277\064\125\277\321\223\077\174\001\336\330
+\023\332\212\246
+END
+CKA_CERT_MD5_HASH MULTILINE_OCTAL
+\041\067\264\027\026\222\173\147\106\160\251\226\327\250\023\044
+END
+CKA_ISSUER MULTILINE_OCTAL
+\060\100\061\013\060\011\006\003\125\004\006\023\002\106\122\061
+\022\060\020\006\003\125\004\012\014\011\117\160\145\156\124\162
+\165\163\164\061\035\060\033\006\003\125\004\003\014\024\117\160
+\145\156\124\162\165\163\164\040\122\157\157\164\040\103\101\040
+\107\063
+END
+CKA_SERIAL_NUMBER MULTILINE_OCTAL
+\002\022\021\040\346\370\114\374\044\260\276\005\100\254\332\203
+\033\064\140\077
+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 "ISRG Root X1"
+#
+# Issuer: CN=ISRG Root X1,O=Internet Security Research Group,C=US
+# Serial Number:00:82:10:cf:b0:d2:40:e3:59:44:63:e0:bb:63:82:8b:00
+# Subject: CN=ISRG Root X1,O=Internet Security Research Group,C=US
+# Not Valid Before: Thu Jun 04 11:04:38 2015
+# Not Valid After : Mon Jun 04 11:04:38 2035
+# Fingerprint (SHA-256): 96:BC:EC:06:26:49:76:F3:74:60:77:9A:CF:28:C5:A7:CF:E8:A3:C0:AA:E1:1A:8F:FC:EE:05:C0:BD:DF:08:C6
+# Fingerprint (SHA1): CA:BD:2A:79:A1:07:6A:31:F2:1D:25:36:35:CB:03:9D:43:29:A5:E8
+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 "ISRG Root X1"
+CKA_CERTIFICATE_TYPE CK_CERTIFICATE_TYPE CKC_X_509
+CKA_SUBJECT MULTILINE_OCTAL
+\060\117\061\013\060\011\006\003\125\004\006\023\002\125\123\061
+\051\060\047\006\003\125\004\012\023\040\111\156\164\145\162\156
+\145\164\040\123\145\143\165\162\151\164\171\040\122\145\163\145
+\141\162\143\150\040\107\162\157\165\160\061\025\060\023\006\003
+\125\004\003\023\014\111\123\122\107\040\122\157\157\164\040\130
+\061
+END
+CKA_ID UTF8 "0"
+CKA_ISSUER MULTILINE_OCTAL
+\060\117\061\013\060\011\006\003\125\004\006\023\002\125\123\061
+\051\060\047\006\003\125\004\012\023\040\111\156\164\145\162\156
+\145\164\040\123\145\143\165\162\151\164\171\040\122\145\163\145
+\141\162\143\150\040\107\162\157\165\160\061\025\060\023\006\003
+\125\004\003\023\014\111\123\122\107\040\122\157\157\164\040\130
+\061
+END
+CKA_SERIAL_NUMBER MULTILINE_OCTAL
+\002\021\000\202\020\317\260\322\100\343\131\104\143\340\273\143
+\202\213\000
+END
+CKA_VALUE MULTILINE_OCTAL
+\060\202\005\153\060\202\003\123\240\003\002\001\002\002\021\000
+\202\020\317\260\322\100\343\131\104\143\340\273\143\202\213\000
+\060\015\006\011\052\206\110\206\367\015\001\001\013\005\000\060
+\117\061\013\060\011\006\003\125\004\006\023\002\125\123\061\051
+\060\047\006\003\125\004\012\023\040\111\156\164\145\162\156\145
+\164\040\123\145\143\165\162\151\164\171\040\122\145\163\145\141
+\162\143\150\040\107\162\157\165\160\061\025\060\023\006\003\125
+\004\003\023\014\111\123\122\107\040\122\157\157\164\040\130\061
+\060\036\027\015\061\065\060\066\060\064\061\061\060\064\063\070
+\132\027\015\063\065\060\066\060\064\061\061\060\064\063\070\132
+\060\117\061\013\060\011\006\003\125\004\006\023\002\125\123\061
+\051\060\047\006\003\125\004\012\023\040\111\156\164\145\162\156
+\145\164\040\123\145\143\165\162\151\164\171\040\122\145\163\145
+\141\162\143\150\040\107\162\157\165\160\061\025\060\023\006\003
+\125\004\003\023\014\111\123\122\107\040\122\157\157\164\040\130
+\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\255\350\044\163\364\024\067\363\233\236\053\127\050\034
+\207\276\334\267\337\070\220\214\156\074\346\127\240\170\367\165
+\302\242\376\365\152\156\366\000\117\050\333\336\150\206\154\104
+\223\266\261\143\375\024\022\153\277\037\322\352\061\233\041\176
+\321\063\074\272\110\365\335\171\337\263\270\377\022\361\041\232
+\113\301\212\206\161\151\112\146\146\154\217\176\074\160\277\255
+\051\042\006\363\344\300\346\200\256\342\113\217\267\231\176\224
+\003\237\323\107\227\174\231\110\043\123\350\070\256\117\012\157
+\203\056\321\111\127\214\200\164\266\332\057\320\070\215\173\003
+\160\041\033\165\362\060\074\372\217\256\335\332\143\253\353\026
+\117\302\216\021\113\176\317\013\350\377\265\167\056\364\262\173
+\112\340\114\022\045\014\160\215\003\051\240\341\123\044\354\023
+\331\356\031\277\020\263\112\214\077\211\243\141\121\336\254\207
+\007\224\364\143\161\354\056\342\157\133\230\201\341\211\134\064
+\171\154\166\357\073\220\142\171\346\333\244\232\057\046\305\320
+\020\341\016\336\331\020\216\026\373\267\367\250\367\307\345\002
+\007\230\217\066\010\225\347\342\067\226\015\066\165\236\373\016
+\162\261\035\233\274\003\371\111\005\330\201\335\005\264\052\326
+\101\351\254\001\166\225\012\017\330\337\325\275\022\037\065\057
+\050\027\154\322\230\301\250\011\144\167\156\107\067\272\316\254
+\131\136\150\235\177\162\326\211\305\006\101\051\076\131\076\335
+\046\365\044\311\021\247\132\243\114\100\037\106\241\231\265\247
+\072\121\156\206\073\236\175\162\247\022\005\170\131\355\076\121
+\170\025\013\003\217\215\320\057\005\262\076\173\112\034\113\163
+\005\022\374\306\352\340\120\023\174\103\223\164\263\312\164\347
+\216\037\001\010\320\060\324\133\161\066\264\007\272\301\060\060
+\134\110\267\202\073\230\246\175\140\212\242\243\051\202\314\272
+\275\203\004\033\242\203\003\101\241\326\005\361\033\302\266\360
+\250\174\206\073\106\250\110\052\210\334\166\232\166\277\037\152
+\245\075\031\217\353\070\363\144\336\310\053\015\012\050\377\367
+\333\342\025\102\324\042\320\047\135\341\171\376\030\347\160\210
+\255\116\346\331\213\072\306\335\047\121\156\377\274\144\365\063
+\103\117\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\171\264\131\346\173\266\345\344\001
+\163\200\010\210\310\032\130\366\351\233\156\060\015\006\011\052
+\206\110\206\367\015\001\001\013\005\000\003\202\002\001\000\125
+\037\130\251\274\262\250\120\320\014\261\330\032\151\040\047\051
+\010\254\141\165\134\212\156\370\202\345\151\057\325\366\126\113
+\271\270\163\020\131\323\041\227\176\347\114\161\373\262\322\140
+\255\071\250\013\352\027\041\126\205\361\120\016\131\353\316\340
+\131\351\272\311\025\357\206\235\217\204\200\366\344\351\221\220
+\334\027\233\142\033\105\360\146\225\322\174\157\302\352\073\357
+\037\317\313\326\256\047\361\251\260\310\256\375\175\176\232\372
+\042\004\353\377\331\177\352\221\053\042\261\027\016\217\362\212
+\064\133\130\330\374\001\311\124\271\270\046\314\212\210\063\211
+\114\055\204\074\202\337\356\226\127\005\272\054\273\367\304\267
+\307\116\073\202\276\061\310\042\163\163\222\321\302\200\244\071
+\071\020\063\043\202\114\074\237\206\262\125\230\035\276\051\206
+\214\042\233\236\342\153\073\127\072\202\160\115\334\011\307\211
+\313\012\007\115\154\350\135\216\311\357\316\253\307\273\265\053
+\116\105\326\112\320\046\314\345\162\312\010\152\245\225\343\025
+\241\367\244\355\311\054\137\245\373\377\254\050\002\056\276\327
+\173\273\343\161\173\220\026\323\007\136\106\123\174\067\007\102
+\214\323\304\226\234\325\231\265\052\340\225\032\200\110\256\114
+\071\007\316\314\107\244\122\225\053\272\270\373\255\322\063\123
+\175\345\035\115\155\325\241\261\307\102\157\346\100\047\065\134
+\243\050\267\007\215\347\215\063\220\347\043\237\373\120\234\171
+\154\106\325\264\025\263\226\156\176\233\014\226\072\270\122\055
+\077\326\133\341\373\010\302\204\376\044\250\243\211\332\254\152
+\341\030\052\261\250\103\141\133\323\037\334\073\215\166\362\055
+\350\215\165\337\027\063\154\075\123\373\173\313\101\137\377\334
+\242\320\141\070\341\226\270\254\135\213\067\327\165\325\063\300
+\231\021\256\235\101\301\162\165\204\276\002\101\102\137\147\044
+\110\224\321\233\047\276\007\077\271\270\117\201\164\121\341\172
+\267\355\235\043\342\276\340\325\050\004\023\074\061\003\236\335
+\172\154\217\306\007\030\306\177\336\107\216\077\050\236\004\006
+\317\245\124\064\167\275\354\211\233\351\027\103\337\133\333\137
+\376\216\036\127\242\315\100\235\176\142\042\332\336\030\047
+END
+
+# Trust for "ISRG Root X1"
+# Issuer: CN=ISRG Root X1,O=Internet Security Research Group,C=US
+# Serial Number:00:82:10:cf:b0:d2:40:e3:59:44:63:e0:bb:63:82:8b:00
+# Subject: CN=ISRG Root X1,O=Internet Security Research Group,C=US
+# Not Valid Before: Thu Jun 04 11:04:38 2015
+# Not Valid After : Mon Jun 04 11:04:38 2035
+# Fingerprint (SHA-256): 96:BC:EC:06:26:49:76:F3:74:60:77:9A:CF:28:C5:A7:CF:E8:A3:C0:AA:E1:1A:8F:FC:EE:05:C0:BD:DF:08:C6
+# Fingerprint (SHA1): CA:BD:2A:79:A1:07:6A:31:F2:1D:25:36:35:CB:03:9D:43:29:A5:E8
+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 "ISRG Root X1"
+CKA_CERT_SHA1_HASH MULTILINE_OCTAL
+\312\275\052\171\241\007\152\061\362\035\045\066\065\313\003\235
+\103\051\245\350
+END
+CKA_CERT_MD5_HASH MULTILINE_OCTAL
+\014\322\371\340\332\027\163\351\355\206\115\245\343\160\347\116
+END
+CKA_ISSUER MULTILINE_OCTAL
+\060\117\061\013\060\011\006\003\125\004\006\023\002\125\123\061
+\051\060\047\006\003\125\004\012\023\040\111\156\164\145\162\156
+\145\164\040\123\145\143\165\162\151\164\171\040\122\145\163\145
+\141\162\143\150\040\107\162\157\165\160\061\025\060\023\006\003
+\125\004\003\023\014\111\123\122\107\040\122\157\157\164\040\130
+\061
+END
+CKA_SERIAL_NUMBER MULTILINE_OCTAL
+\002\021\000\202\020\317\260\322\100\343\131\104\143\340\273\143
+\202\213\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 "AC RAIZ FNMT-RCM"
+#
+# Issuer: OU=AC RAIZ FNMT-RCM,O=FNMT-RCM,C=ES
+# Serial Number:5d:93:8d:30:67:36:c8:06:1d:1a:c7:54:84:69:07
+# Subject: OU=AC RAIZ FNMT-RCM,O=FNMT-RCM,C=ES
+# Not Valid Before: Wed Oct 29 15:59:56 2008
+# Not Valid After : Tue Jan 01 00:00:00 2030
+# Fingerprint (SHA-256): EB:C5:57:0C:29:01:8C:4D:67:B1:AA:12:7B:AF:12:F7:03:B4:61:1E:BC:17:B7:DA:B5:57:38:94:17:9B:93:FA
+# Fingerprint (SHA1): EC:50:35:07:B2:15:C4:95:62:19:E2:A8:9A:5B:42:99:2C:4C:2C:20
+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 RAIZ FNMT-RCM"
+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\105\123\061
+\021\060\017\006\003\125\004\012\014\010\106\116\115\124\055\122
+\103\115\061\031\060\027\006\003\125\004\013\014\020\101\103\040
+\122\101\111\132\040\106\116\115\124\055\122\103\115
+END
+CKA_ID UTF8 "0"
+CKA_ISSUER MULTILINE_OCTAL
+\060\073\061\013\060\011\006\003\125\004\006\023\002\105\123\061
+\021\060\017\006\003\125\004\012\014\010\106\116\115\124\055\122
+\103\115\061\031\060\027\006\003\125\004\013\014\020\101\103\040
+\122\101\111\132\040\106\116\115\124\055\122\103\115
+END
+CKA_SERIAL_NUMBER MULTILINE_OCTAL
+\002\017\135\223\215\060\147\066\310\006\035\032\307\124\204\151
+\007
+END
+CKA_VALUE MULTILINE_OCTAL
+\060\202\005\203\060\202\003\153\240\003\002\001\002\002\017\135
+\223\215\060\147\066\310\006\035\032\307\124\204\151\007\060\015
+\006\011\052\206\110\206\367\015\001\001\013\005\000\060\073\061
+\013\060\011\006\003\125\004\006\023\002\105\123\061\021\060\017
+\006\003\125\004\012\014\010\106\116\115\124\055\122\103\115\061
+\031\060\027\006\003\125\004\013\014\020\101\103\040\122\101\111
+\132\040\106\116\115\124\055\122\103\115\060\036\027\015\060\070
+\061\060\062\071\061\065\065\071\065\066\132\027\015\063\060\060
+\061\060\061\060\060\060\060\060\060\132\060\073\061\013\060\011
+\006\003\125\004\006\023\002\105\123\061\021\060\017\006\003\125
+\004\012\014\010\106\116\115\124\055\122\103\115\061\031\060\027
+\006\003\125\004\013\014\020\101\103\040\122\101\111\132\040\106
+\116\115\124\055\122\103\115\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\272\161\200\172\114\206\156\177
+\310\023\155\300\306\175\034\000\227\217\054\014\043\273\020\232
+\100\251\032\267\207\210\370\233\126\152\373\346\173\216\213\222
+\216\247\045\135\131\021\333\066\056\267\121\027\037\251\010\037
+\004\027\044\130\252\067\112\030\337\345\071\324\127\375\327\301
+\054\221\001\221\342\042\324\003\300\130\374\167\107\354\217\076
+\164\103\272\254\064\215\115\070\166\147\216\260\310\157\060\063
+\130\161\134\264\365\153\156\324\001\120\270\023\176\154\112\243
+\111\321\040\031\356\274\300\051\030\145\247\336\376\357\335\012
+\220\041\347\032\147\222\102\020\230\137\117\060\274\076\034\105
+\264\020\327\150\100\024\300\100\372\347\167\027\172\346\013\217
+\145\133\074\331\232\122\333\265\275\236\106\317\075\353\221\005
+\002\300\226\262\166\114\115\020\226\073\222\372\234\177\017\231
+\337\276\043\065\105\036\002\134\376\265\250\233\231\045\332\136
+\363\042\303\071\365\344\052\056\323\306\037\304\154\252\305\034
+\152\001\005\112\057\322\305\301\250\064\046\135\146\245\322\002
+\041\371\030\267\006\365\116\231\157\250\253\114\121\350\317\120
+\030\305\167\310\071\011\054\111\222\062\231\250\273\027\027\171
+\260\132\305\346\243\304\131\145\107\065\203\136\251\350\065\013
+\231\273\344\315\040\306\233\112\006\071\265\150\374\042\272\356
+\125\214\053\116\352\363\261\343\374\266\231\232\325\102\372\161
+\115\010\317\207\036\152\161\175\371\323\264\351\245\161\201\173
+\302\116\107\226\245\366\166\205\243\050\217\351\200\156\201\123
+\245\155\137\270\110\371\302\371\066\246\056\111\377\270\226\302
+\214\007\263\233\210\130\374\353\033\034\336\055\160\342\227\222
+\060\241\211\343\274\125\250\047\326\113\355\220\255\213\372\143
+\045\131\055\250\065\335\312\227\063\274\345\315\307\235\321\354
+\357\136\016\112\220\006\046\143\255\271\331\065\055\007\272\166
+\145\054\254\127\217\175\364\007\224\327\201\002\226\135\243\007
+\111\325\172\320\127\371\033\347\123\106\165\252\260\171\102\313
+\150\161\010\351\140\275\071\151\316\364\257\303\126\100\307\255
+\122\242\011\344\157\206\107\212\037\353\050\047\135\203\040\257
+\004\311\154\126\232\213\106\365\002\003\001\000\001\243\201\203
+\060\201\200\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\367
+\175\305\375\304\350\232\033\167\144\247\365\035\240\314\277\207
+\140\232\155\060\076\006\003\125\035\040\004\067\060\065\060\063
+\006\004\125\035\040\000\060\053\060\051\006\010\053\006\001\005
+\005\007\002\001\026\035\150\164\164\160\072\057\057\167\167\167
+\056\143\145\162\164\056\146\156\155\164\056\145\163\057\144\160
+\143\163\057\060\015\006\011\052\206\110\206\367\015\001\001\013
+\005\000\003\202\002\001\000\007\220\112\337\363\043\116\360\303
+\234\121\145\233\234\042\242\212\014\205\363\163\051\153\115\376
+\001\342\251\014\143\001\277\004\147\245\235\230\137\375\001\023
+\372\354\232\142\351\206\376\266\142\322\156\114\224\373\300\165
+\105\174\145\014\370\262\067\317\254\017\317\215\157\371\031\367
+\217\354\036\362\160\236\360\312\270\357\267\377\166\067\166\133
+\366\156\210\363\257\142\062\042\223\015\072\152\216\024\146\014
+\055\123\164\127\145\036\325\262\335\043\201\073\245\146\043\047
+\147\011\217\341\167\252\103\315\145\121\010\355\121\130\376\346
+\071\371\313\107\204\244\025\361\166\273\244\356\244\073\304\137
+\357\262\063\226\021\030\267\311\145\276\030\341\243\244\334\372
+\030\371\323\274\023\233\071\172\064\272\323\101\373\372\062\212
+\052\267\053\206\013\151\203\070\276\315\212\056\013\160\255\215
+\046\222\356\036\365\001\053\012\331\326\227\233\156\340\250\031
+\034\072\041\213\014\036\100\255\003\347\335\146\176\365\271\040
+\015\003\350\226\371\202\105\324\071\340\240\000\135\327\230\346
+\175\236\147\163\303\232\052\367\253\213\241\072\024\357\064\274
+\122\016\211\230\232\004\100\204\035\176\105\151\223\127\316\353
+\316\370\120\174\117\034\156\004\103\233\371\326\073\043\030\351
+\352\216\321\115\106\215\361\073\344\152\312\272\373\043\267\233
+\372\231\001\051\132\130\132\055\343\371\324\155\016\046\255\301
+\156\064\274\062\370\014\005\372\145\243\333\073\067\203\042\351
+\326\334\162\063\375\135\362\040\275\166\074\043\332\050\367\371
+\033\353\131\144\325\334\137\162\176\040\374\315\211\265\220\147
+\115\142\172\077\116\255\035\303\071\376\172\364\050\026\337\101
+\366\110\200\005\327\017\121\171\254\020\253\324\354\003\146\346
+\152\260\272\061\222\102\100\152\276\072\323\162\341\152\067\125
+\274\254\035\225\267\151\141\362\103\221\164\346\240\323\012\044
+\106\241\010\257\326\332\105\031\226\324\123\035\133\204\171\360
+\300\367\107\357\213\217\305\006\256\235\114\142\235\377\106\004
+\370\323\311\266\020\045\100\165\376\026\252\311\112\140\206\057
+\272\357\060\167\344\124\342\270\204\231\130\200\252\023\213\121
+\072\117\110\366\213\266\263
+END
+
+# Trust for "AC RAIZ FNMT-RCM"
+# Issuer: OU=AC RAIZ FNMT-RCM,O=FNMT-RCM,C=ES
+# Serial Number:5d:93:8d:30:67:36:c8:06:1d:1a:c7:54:84:69:07
+# Subject: OU=AC RAIZ FNMT-RCM,O=FNMT-RCM,C=ES
+# Not Valid Before: Wed Oct 29 15:59:56 2008
+# Not Valid After : Tue Jan 01 00:00:00 2030
+# Fingerprint (SHA-256): EB:C5:57:0C:29:01:8C:4D:67:B1:AA:12:7B:AF:12:F7:03:B4:61:1E:BC:17:B7:DA:B5:57:38:94:17:9B:93:FA
+# Fingerprint (SHA1): EC:50:35:07:B2:15:C4:95:62:19:E2:A8:9A:5B:42:99:2C:4C:2C:20
+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 RAIZ FNMT-RCM"
+CKA_CERT_SHA1_HASH MULTILINE_OCTAL
+\354\120\065\007\262\025\304\225\142\031\342\250\232\133\102\231
+\054\114\054\040
+END
+CKA_CERT_MD5_HASH MULTILINE_OCTAL
+\342\011\004\264\323\275\321\240\024\375\032\322\107\304\127\035
+END
+CKA_ISSUER MULTILINE_OCTAL
+\060\073\061\013\060\011\006\003\125\004\006\023\002\105\123\061
+\021\060\017\006\003\125\004\012\014\010\106\116\115\124\055\122
+\103\115\061\031\060\027\006\003\125\004\013\014\020\101\103\040
+\122\101\111\132\040\106\116\115\124\055\122\103\115
+END
+CKA_SERIAL_NUMBER MULTILINE_OCTAL
+\002\017\135\223\215\060\147\066\310\006\035\032\307\124\204\151
+\007
+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 "Amazon Root CA 1"
+#
+# Issuer: CN=Amazon Root CA 1,O=Amazon,C=US
+# Serial Number:06:6c:9f:cf:99:bf:8c:0a:39:e2:f0:78:8a:43:e6:96:36:5b:ca
+# Subject: CN=Amazon Root CA 1,O=Amazon,C=US
+# Not Valid Before: Tue May 26 00:00:00 2015
+# Not Valid After : Sun Jan 17 00:00:00 2038
+# Fingerprint (SHA-256): 8E:CD:E6:88:4F:3D:87:B1:12:5B:A3:1A:C3:FC:B1:3D:70:16:DE:7F:57:CC:90:4F:E1:CB:97:C6:AE:98:19:6E
+# Fingerprint (SHA1): 8D:A7:F9:65:EC:5E:FC:37:91:0F:1C:6E:59:FD:C1:CC:6A:6E:DE:16
+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 "Amazon Root CA 1"
+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\125\123\061
+\017\060\015\006\003\125\004\012\023\006\101\155\141\172\157\156
+\061\031\060\027\006\003\125\004\003\023\020\101\155\141\172\157
+\156\040\122\157\157\164\040\103\101\040\061
+END
+CKA_ID UTF8 "0"
+CKA_ISSUER MULTILINE_OCTAL
+\060\071\061\013\060\011\006\003\125\004\006\023\002\125\123\061
+\017\060\015\006\003\125\004\012\023\006\101\155\141\172\157\156
+\061\031\060\027\006\003\125\004\003\023\020\101\155\141\172\157
+\156\040\122\157\157\164\040\103\101\040\061
+END
+CKA_SERIAL_NUMBER MULTILINE_OCTAL
+\002\023\006\154\237\317\231\277\214\012\071\342\360\170\212\103
+\346\226\066\133\312
+END
+CKA_VALUE MULTILINE_OCTAL
+\060\202\003\101\060\202\002\051\240\003\002\001\002\002\023\006
+\154\237\317\231\277\214\012\071\342\360\170\212\103\346\226\066
+\133\312\060\015\006\011\052\206\110\206\367\015\001\001\013\005
+\000\060\071\061\013\060\011\006\003\125\004\006\023\002\125\123
+\061\017\060\015\006\003\125\004\012\023\006\101\155\141\172\157
+\156\061\031\060\027\006\003\125\004\003\023\020\101\155\141\172
+\157\156\040\122\157\157\164\040\103\101\040\061\060\036\027\015
+\061\065\060\065\062\066\060\060\060\060\060\060\132\027\015\063
+\070\060\061\061\067\060\060\060\060\060\060\132\060\071\061\013
+\060\011\006\003\125\004\006\023\002\125\123\061\017\060\015\006
+\003\125\004\012\023\006\101\155\141\172\157\156\061\031\060\027
+\006\003\125\004\003\023\020\101\155\141\172\157\156\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\262\170\200\161\312\170\325\343
+\161\257\107\200\120\164\175\156\330\327\210\166\364\231\150\367
+\130\041\140\371\164\204\001\057\254\002\055\206\323\240\103\172
+\116\262\244\320\066\272\001\276\215\333\110\310\007\027\066\114
+\364\356\210\043\307\076\353\067\365\265\031\370\111\150\260\336
+\327\271\166\070\035\141\236\244\376\202\066\245\345\112\126\344
+\105\341\371\375\264\026\372\164\332\234\233\065\071\057\372\260
+\040\120\006\154\172\320\200\262\246\371\257\354\107\031\217\120
+\070\007\334\242\207\071\130\370\272\325\251\371\110\147\060\226
+\356\224\170\136\157\211\243\121\300\060\206\146\241\105\146\272
+\124\353\243\303\221\371\110\334\377\321\350\060\055\175\055\164
+\160\065\327\210\044\367\236\304\131\156\273\163\207\027\362\062
+\106\050\270\103\372\267\035\252\312\264\362\237\044\016\055\113
+\367\161\134\136\151\377\352\225\002\313\070\212\256\120\070\157
+\333\373\055\142\033\305\307\036\124\341\167\340\147\310\017\234
+\207\043\326\077\100\040\177\040\200\304\200\114\076\073\044\046
+\216\004\256\154\232\310\252\015\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\206\060\035\006\003\125\035\016\004\026\004\024\204\030\314
+\205\064\354\274\014\224\224\056\010\131\234\307\262\020\116\012
+\010\060\015\006\011\052\206\110\206\367\015\001\001\013\005\000
+\003\202\001\001\000\230\362\067\132\101\220\241\032\305\166\121
+\050\040\066\043\016\256\346\050\273\252\370\224\256\110\244\060
+\177\033\374\044\215\113\264\310\241\227\366\266\361\172\160\310
+\123\223\314\010\050\343\230\045\317\043\244\371\336\041\323\174
+\205\011\255\116\232\165\072\302\013\152\211\170\166\104\107\030
+\145\154\215\101\216\073\177\232\313\364\265\247\120\327\005\054
+\067\350\003\113\255\351\141\240\002\156\365\362\360\305\262\355
+\133\267\334\372\224\134\167\236\023\245\177\122\255\225\362\370
+\223\073\336\213\134\133\312\132\122\133\140\257\024\367\113\357
+\243\373\237\100\225\155\061\124\374\102\323\307\106\037\043\255
+\331\017\110\160\232\331\165\170\161\321\162\103\064\165\156\127
+\131\302\002\134\046\140\051\317\043\031\026\216\210\103\245\324
+\344\313\010\373\043\021\103\350\103\051\162\142\241\251\135\136
+\010\324\220\256\270\330\316\024\302\320\125\362\206\366\304\223
+\103\167\146\141\300\271\350\101\327\227\170\140\003\156\112\162
+\256\245\321\175\272\020\236\206\154\033\212\271\131\063\370\353
+\304\220\276\361\271
+END
+
+# Trust for "Amazon Root CA 1"
+# Issuer: CN=Amazon Root CA 1,O=Amazon,C=US
+# Serial Number:06:6c:9f:cf:99:bf:8c:0a:39:e2:f0:78:8a:43:e6:96:36:5b:ca
+# Subject: CN=Amazon Root CA 1,O=Amazon,C=US
+# Not Valid Before: Tue May 26 00:00:00 2015
+# Not Valid After : Sun Jan 17 00:00:00 2038
+# Fingerprint (SHA-256): 8E:CD:E6:88:4F:3D:87:B1:12:5B:A3:1A:C3:FC:B1:3D:70:16:DE:7F:57:CC:90:4F:E1:CB:97:C6:AE:98:19:6E
+# Fingerprint (SHA1): 8D:A7:F9:65:EC:5E:FC:37:91:0F:1C:6E:59:FD:C1:CC:6A:6E:DE:16
+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 "Amazon Root CA 1"
+CKA_CERT_SHA1_HASH MULTILINE_OCTAL
+\215\247\371\145\354\136\374\067\221\017\034\156\131\375\301\314
+\152\156\336\026
+END
+CKA_CERT_MD5_HASH MULTILINE_OCTAL
+\103\306\277\256\354\376\255\057\030\306\210\150\060\374\310\346
+END
+CKA_ISSUER MULTILINE_OCTAL
+\060\071\061\013\060\011\006\003\125\004\006\023\002\125\123\061
+\017\060\015\006\003\125\004\012\023\006\101\155\141\172\157\156
+\061\031\060\027\006\003\125\004\003\023\020\101\155\141\172\157
+\156\040\122\157\157\164\040\103\101\040\061
+END
+CKA_SERIAL_NUMBER MULTILINE_OCTAL
+\002\023\006\154\237\317\231\277\214\012\071\342\360\170\212\103
+\346\226\066\133\312
+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 "Amazon Root CA 2"
+#
+# Issuer: CN=Amazon Root CA 2,O=Amazon,C=US
+# Serial Number:06:6c:9f:d2:96:35:86:9f:0a:0f:e5:86:78:f8:5b:26:bb:8a:37
+# Subject: CN=Amazon Root CA 2,O=Amazon,C=US
+# Not Valid Before: Tue May 26 00:00:00 2015
+# Not Valid After : Sat May 26 00:00:00 2040
+# Fingerprint (SHA-256): 1B:A5:B2:AA:8C:65:40:1A:82:96:01:18:F8:0B:EC:4F:62:30:4D:83:CE:C4:71:3A:19:C3:9C:01:1E:A4:6D:B4
+# Fingerprint (SHA1): 5A:8C:EF:45:D7:A6:98:59:76:7A:8C:8B:44:96:B5:78:CF:47:4B:1A
+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 "Amazon Root CA 2"
+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\125\123\061
+\017\060\015\006\003\125\004\012\023\006\101\155\141\172\157\156
+\061\031\060\027\006\003\125\004\003\023\020\101\155\141\172\157
+\156\040\122\157\157\164\040\103\101\040\062
+END
+CKA_ID UTF8 "0"
+CKA_ISSUER MULTILINE_OCTAL
+\060\071\061\013\060\011\006\003\125\004\006\023\002\125\123\061
+\017\060\015\006\003\125\004\012\023\006\101\155\141\172\157\156
+\061\031\060\027\006\003\125\004\003\023\020\101\155\141\172\157
+\156\040\122\157\157\164\040\103\101\040\062
+END
+CKA_SERIAL_NUMBER MULTILINE_OCTAL
+\002\023\006\154\237\322\226\065\206\237\012\017\345\206\170\370
+\133\046\273\212\067
+END
+CKA_VALUE MULTILINE_OCTAL
+\060\202\005\101\060\202\003\051\240\003\002\001\002\002\023\006
+\154\237\322\226\065\206\237\012\017\345\206\170\370\133\046\273
+\212\067\060\015\006\011\052\206\110\206\367\015\001\001\014\005
+\000\060\071\061\013\060\011\006\003\125\004\006\023\002\125\123
+\061\017\060\015\006\003\125\004\012\023\006\101\155\141\172\157
+\156\061\031\060\027\006\003\125\004\003\023\020\101\155\141\172
+\157\156\040\122\157\157\164\040\103\101\040\062\060\036\027\015
+\061\065\060\065\062\066\060\060\060\060\060\060\132\027\015\064
+\060\060\065\062\066\060\060\060\060\060\060\132\060\071\061\013
+\060\011\006\003\125\004\006\023\002\125\123\061\017\060\015\006
+\003\125\004\012\023\006\101\155\141\172\157\156\061\031\060\027
+\006\003\125\004\003\023\020\101\155\141\172\157\156\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\255\226\237\055\234\112\114\112
+\201\171\121\231\354\212\313\153\140\121\023\274\115\155\006\374
+\260\010\215\335\031\020\152\307\046\014\065\330\300\157\040\204
+\351\224\261\233\205\003\303\133\333\112\350\310\370\220\166\331
+\133\117\343\114\350\006\066\115\314\232\254\075\014\220\053\222
+\324\006\031\140\254\067\104\171\205\201\202\255\132\067\340\015
+\314\235\246\114\122\166\352\103\235\267\004\321\120\366\125\340
+\325\322\246\111\205\351\067\351\312\176\256\134\225\115\110\232
+\077\256\040\132\155\210\225\331\064\270\122\032\103\220\260\277
+\154\005\271\266\170\267\352\320\344\072\074\022\123\142\377\112
+\362\173\276\065\005\251\022\064\343\363\144\164\142\054\075\000
+\111\132\050\376\062\104\273\207\335\145\047\002\161\073\332\112
+\367\037\332\315\367\041\125\220\117\017\354\256\202\341\237\153
+\331\105\323\273\360\137\207\355\074\054\071\206\332\077\336\354
+\162\125\353\171\243\255\333\335\174\260\272\034\316\374\336\117
+\065\166\317\017\370\170\037\152\066\121\106\047\141\133\351\236
+\317\360\242\125\175\174\045\212\157\057\264\305\317\204\056\053
+\375\015\121\020\154\373\137\033\274\033\176\305\256\073\230\001
+\061\222\377\013\127\364\232\262\271\127\351\253\357\015\166\321
+\360\356\364\316\206\247\340\156\351\264\151\241\337\151\366\063
+\306\151\056\227\023\236\245\207\260\127\020\201\067\311\123\263
+\273\177\366\222\321\234\320\030\364\222\156\332\203\117\246\143
+\231\114\245\373\136\357\041\144\172\040\137\154\144\205\025\313
+\067\351\142\014\013\052\026\334\001\056\062\332\076\113\365\236
+\072\366\027\100\224\357\236\221\010\206\372\276\143\250\132\063
+\354\313\164\103\225\371\154\151\122\066\307\051\157\374\125\003
+\134\037\373\237\275\107\353\347\111\107\225\013\116\211\042\011
+\111\340\365\141\036\361\277\056\212\162\156\200\131\377\127\072
+\371\165\062\243\116\137\354\355\050\142\331\115\163\362\314\201
+\027\140\355\315\353\334\333\247\312\305\176\002\275\362\124\010
+\124\375\264\055\011\054\027\124\112\230\321\124\341\121\147\010
+\322\355\156\176\157\077\322\055\201\131\051\146\313\220\071\225
+\021\036\164\047\376\335\353\257\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\206\060\035\006\003\125\035\016\004\026\004\024\260\014\360
+\114\060\364\005\130\002\110\375\063\345\122\257\113\204\343\146
+\122\060\015\006\011\052\206\110\206\367\015\001\001\014\005\000
+\003\202\002\001\000\252\250\200\217\016\170\243\340\242\324\315
+\346\365\230\172\073\352\000\003\260\227\016\223\274\132\250\366
+\054\214\162\207\251\261\374\177\163\375\143\161\170\245\207\131
+\317\060\341\015\020\262\023\132\155\202\365\152\346\200\237\240
+\005\013\150\344\107\153\307\152\337\266\375\167\062\162\345\030
+\372\011\364\240\223\054\135\322\214\165\205\166\145\220\014\003
+\171\267\061\043\143\255\170\203\011\206\150\204\312\377\371\317
+\046\232\222\171\347\315\113\305\347\141\247\027\313\363\251\022
+\223\223\153\247\350\057\123\222\304\140\130\260\314\002\121\030
+\133\205\215\142\131\143\266\255\264\336\232\373\046\367\000\047
+\300\135\125\067\164\231\311\120\177\343\131\056\104\343\054\045
+\356\354\114\062\167\264\237\032\351\113\135\040\305\332\375\034
+\207\026\306\103\350\324\273\046\232\105\160\136\251\013\067\123
+\342\106\173\047\375\340\106\362\211\267\314\102\266\313\050\046
+\156\331\245\311\072\310\101\023\140\367\120\214\025\256\262\155
+\032\025\032\127\170\346\222\052\331\145\220\202\077\154\002\257
+\256\022\072\047\226\066\004\327\035\242\200\143\251\233\361\345
+\272\264\174\024\260\116\311\261\037\164\137\070\366\121\352\233
+\372\054\242\021\324\251\055\047\032\105\261\257\262\116\161\015
+\300\130\106\326\151\006\313\123\313\263\376\153\101\315\101\176
+\175\114\017\174\162\171\172\131\315\136\112\016\254\233\251\230
+\163\171\174\264\364\314\271\270\007\014\262\164\134\270\307\157
+\210\241\220\247\364\252\371\277\147\072\364\032\025\142\036\267
+\237\276\075\261\051\257\147\241\022\362\130\020\031\123\003\060
+\033\270\032\211\366\234\275\227\003\216\243\011\363\035\213\041
+\361\264\337\344\034\321\237\145\002\006\352\134\326\023\263\204
+\357\242\245\134\214\167\051\247\150\300\153\256\100\322\250\264
+\352\315\360\215\113\070\234\031\232\033\050\124\270\211\220\357
+\312\165\201\076\036\362\144\044\307\030\257\116\377\107\236\007
+\366\065\145\244\323\012\126\377\365\027\144\154\357\250\042\045
+\111\223\266\337\000\027\332\130\176\135\356\305\033\260\321\321
+\137\041\020\307\371\363\272\002\012\047\007\305\361\326\307\323
+\340\373\011\140\154
+END
+
+# Trust for "Amazon Root CA 2"
+# Issuer: CN=Amazon Root CA 2,O=Amazon,C=US
+# Serial Number:06:6c:9f:d2:96:35:86:9f:0a:0f:e5:86:78:f8:5b:26:bb:8a:37
+# Subject: CN=Amazon Root CA 2,O=Amazon,C=US
+# Not Valid Before: Tue May 26 00:00:00 2015
+# Not Valid After : Sat May 26 00:00:00 2040
+# Fingerprint (SHA-256): 1B:A5:B2:AA:8C:65:40:1A:82:96:01:18:F8:0B:EC:4F:62:30:4D:83:CE:C4:71:3A:19:C3:9C:01:1E:A4:6D:B4
+# Fingerprint (SHA1): 5A:8C:EF:45:D7:A6:98:59:76:7A:8C:8B:44:96:B5:78:CF:47:4B:1A
+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 "Amazon Root CA 2"
+CKA_CERT_SHA1_HASH MULTILINE_OCTAL
+\132\214\357\105\327\246\230\131\166\172\214\213\104\226\265\170
+\317\107\113\032
+END
+CKA_CERT_MD5_HASH MULTILINE_OCTAL
+\310\345\215\316\250\102\342\172\300\052\134\174\236\046\277\146
+END
+CKA_ISSUER MULTILINE_OCTAL
+\060\071\061\013\060\011\006\003\125\004\006\023\002\125\123\061
+\017\060\015\006\003\125\004\012\023\006\101\155\141\172\157\156
+\061\031\060\027\006\003\125\004\003\023\020\101\155\141\172\157
+\156\040\122\157\157\164\040\103\101\040\062
+END
+CKA_SERIAL_NUMBER MULTILINE_OCTAL
+\002\023\006\154\237\322\226\065\206\237\012\017\345\206\170\370
+\133\046\273\212\067
+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 "Amazon Root CA 3"
+#
+# Issuer: CN=Amazon Root CA 3,O=Amazon,C=US
+# Serial Number:06:6c:9f:d5:74:97:36:66:3f:3b:0b:9a:d9:e8:9e:76:03:f2:4a
+# Subject: CN=Amazon Root CA 3,O=Amazon,C=US
+# Not Valid Before: Tue May 26 00:00:00 2015
+# Not Valid After : Sat May 26 00:00:00 2040
+# Fingerprint (SHA-256): 18:CE:6C:FE:7B:F1:4E:60:B2:E3:47:B8:DF:E8:68:CB:31:D0:2E:BB:3A:DA:27:15:69:F5:03:43:B4:6D:B3:A4
+# Fingerprint (SHA1): 0D:44:DD:8C:3C:8C:1A:1A:58:75:64:81:E9:0F:2E:2A:FF:B3:D2:6E
+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 "Amazon Root CA 3"
+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\125\123\061
+\017\060\015\006\003\125\004\012\023\006\101\155\141\172\157\156
+\061\031\060\027\006\003\125\004\003\023\020\101\155\141\172\157
+\156\040\122\157\157\164\040\103\101\040\063
+END
+CKA_ID UTF8 "0"
+CKA_ISSUER MULTILINE_OCTAL
+\060\071\061\013\060\011\006\003\125\004\006\023\002\125\123\061
+\017\060\015\006\003\125\004\012\023\006\101\155\141\172\157\156
+\061\031\060\027\006\003\125\004\003\023\020\101\155\141\172\157
+\156\040\122\157\157\164\040\103\101\040\063
+END
+CKA_SERIAL_NUMBER MULTILINE_OCTAL
+\002\023\006\154\237\325\164\227\066\146\077\073\013\232\331\350
+\236\166\003\362\112
+END
+CKA_VALUE MULTILINE_OCTAL
+\060\202\001\266\060\202\001\133\240\003\002\001\002\002\023\006
+\154\237\325\164\227\066\146\077\073\013\232\331\350\236\166\003
+\362\112\060\012\006\010\052\206\110\316\075\004\003\002\060\071
+\061\013\060\011\006\003\125\004\006\023\002\125\123\061\017\060
+\015\006\003\125\004\012\023\006\101\155\141\172\157\156\061\031
+\060\027\006\003\125\004\003\023\020\101\155\141\172\157\156\040
+\122\157\157\164\040\103\101\040\063\060\036\027\015\061\065\060
+\065\062\066\060\060\060\060\060\060\132\027\015\064\060\060\065
+\062\066\060\060\060\060\060\060\132\060\071\061\013\060\011\006
+\003\125\004\006\023\002\125\123\061\017\060\015\006\003\125\004
+\012\023\006\101\155\141\172\157\156\061\031\060\027\006\003\125
+\004\003\023\020\101\155\141\172\157\156\040\122\157\157\164\040
+\103\101\040\063\060\131\060\023\006\007\052\206\110\316\075\002
+\001\006\010\052\206\110\316\075\003\001\007\003\102\000\004\051
+\227\247\306\101\177\300\015\233\350\001\033\126\306\362\122\245
+\272\055\262\022\350\322\056\327\372\311\305\330\252\155\037\163
+\201\073\073\230\153\071\174\063\245\305\116\206\216\200\027\150
+\142\105\127\175\104\130\035\263\067\345\147\010\353\146\336\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\206\060\035\006\003\125\035\016\004\026\004\024\253
+\266\333\327\006\236\067\254\060\206\007\221\160\307\234\304\031
+\261\170\300\060\012\006\010\052\206\110\316\075\004\003\002\003
+\111\000\060\106\002\041\000\340\205\222\243\027\267\215\371\053
+\006\245\223\254\032\230\150\141\162\372\341\241\320\373\034\170
+\140\246\103\231\305\270\304\002\041\000\234\002\357\361\224\234
+\263\226\371\353\306\052\370\266\054\376\072\220\024\026\327\214
+\143\044\110\034\337\060\175\325\150\073
+END
+
+# Trust for "Amazon Root CA 3"
+# Issuer: CN=Amazon Root CA 3,O=Amazon,C=US
+# Serial Number:06:6c:9f:d5:74:97:36:66:3f:3b:0b:9a:d9:e8:9e:76:03:f2:4a
+# Subject: CN=Amazon Root CA 3,O=Amazon,C=US
+# Not Valid Before: Tue May 26 00:00:00 2015
+# Not Valid After : Sat May 26 00:00:00 2040
+# Fingerprint (SHA-256): 18:CE:6C:FE:7B:F1:4E:60:B2:E3:47:B8:DF:E8:68:CB:31:D0:2E:BB:3A:DA:27:15:69:F5:03:43:B4:6D:B3:A4
+# Fingerprint (SHA1): 0D:44:DD:8C:3C:8C:1A:1A:58:75:64:81:E9:0F:2E:2A:FF:B3:D2:6E
+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 "Amazon Root CA 3"
+CKA_CERT_SHA1_HASH MULTILINE_OCTAL
+\015\104\335\214\074\214\032\032\130\165\144\201\351\017\056\052
+\377\263\322\156
+END
+CKA_CERT_MD5_HASH MULTILINE_OCTAL
+\240\324\357\013\367\265\330\111\225\052\354\365\304\374\201\207
+END
+CKA_ISSUER MULTILINE_OCTAL
+\060\071\061\013\060\011\006\003\125\004\006\023\002\125\123\061
+\017\060\015\006\003\125\004\012\023\006\101\155\141\172\157\156
+\061\031\060\027\006\003\125\004\003\023\020\101\155\141\172\157
+\156\040\122\157\157\164\040\103\101\040\063
+END
+CKA_SERIAL_NUMBER MULTILINE_OCTAL
+\002\023\006\154\237\325\164\227\066\146\077\073\013\232\331\350
+\236\166\003\362\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_MUST_VERIFY_TRUST
+CKA_TRUST_STEP_UP_APPROVED CK_BBOOL CK_FALSE
+
+#
+# Certificate "Amazon Root CA 4"
+#
+# Issuer: CN=Amazon Root CA 4,O=Amazon,C=US
+# Serial Number:06:6c:9f:d7:c1:bb:10:4c:29:43:e5:71:7b:7b:2c:c8:1a:c1:0e
+# Subject: CN=Amazon Root CA 4,O=Amazon,C=US
+# Not Valid Before: Tue May 26 00:00:00 2015
+# Not Valid After : Sat May 26 00:00:00 2040
+# Fingerprint (SHA-256): E3:5D:28:41:9E:D0:20:25:CF:A6:90:38:CD:62:39:62:45:8D:A5:C6:95:FB:DE:A3:C2:2B:0B:FB:25:89:70:92
+# Fingerprint (SHA1): F6:10:84:07:D6:F8:BB:67:98:0C:C2:E2:44:C2:EB:AE:1C:EF:63:BE
+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 "Amazon Root CA 4"
+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\125\123\061
+\017\060\015\006\003\125\004\012\023\006\101\155\141\172\157\156
+\061\031\060\027\006\003\125\004\003\023\020\101\155\141\172\157
+\156\040\122\157\157\164\040\103\101\040\064
+END
+CKA_ID UTF8 "0"
+CKA_ISSUER MULTILINE_OCTAL
+\060\071\061\013\060\011\006\003\125\004\006\023\002\125\123\061
+\017\060\015\006\003\125\004\012\023\006\101\155\141\172\157\156
+\061\031\060\027\006\003\125\004\003\023\020\101\155\141\172\157
+\156\040\122\157\157\164\040\103\101\040\064
+END
+CKA_SERIAL_NUMBER MULTILINE_OCTAL
+\002\023\006\154\237\327\301\273\020\114\051\103\345\161\173\173
+\054\310\032\301\016
+END
+CKA_VALUE MULTILINE_OCTAL
+\060\202\001\362\060\202\001\170\240\003\002\001\002\002\023\006
+\154\237\327\301\273\020\114\051\103\345\161\173\173\054\310\032
+\301\016\060\012\006\010\052\206\110\316\075\004\003\003\060\071
+\061\013\060\011\006\003\125\004\006\023\002\125\123\061\017\060
+\015\006\003\125\004\012\023\006\101\155\141\172\157\156\061\031
+\060\027\006\003\125\004\003\023\020\101\155\141\172\157\156\040
+\122\157\157\164\040\103\101\040\064\060\036\027\015\061\065\060
+\065\062\066\060\060\060\060\060\060\132\027\015\064\060\060\065
+\062\066\060\060\060\060\060\060\132\060\071\061\013\060\011\006
+\003\125\004\006\023\002\125\123\061\017\060\015\006\003\125\004
+\012\023\006\101\155\141\172\157\156\061\031\060\027\006\003\125
+\004\003\023\020\101\155\141\172\157\156\040\122\157\157\164\040
+\103\101\040\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\322\253\212\067
+\117\243\123\015\376\301\212\173\113\250\173\106\113\143\260\142
+\366\055\033\333\010\161\041\322\000\350\143\275\232\047\373\360
+\071\156\135\352\075\245\311\201\252\243\133\040\230\105\135\026
+\333\375\350\020\155\343\234\340\343\275\137\204\142\363\160\144
+\063\240\313\044\057\160\272\210\241\052\240\165\370\201\256\142
+\006\304\201\333\071\156\051\260\036\372\056\134\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
+\206\060\035\006\003\125\035\016\004\026\004\024\323\354\307\072
+\145\156\314\341\332\166\232\126\373\234\363\206\155\127\345\201
+\060\012\006\010\052\206\110\316\075\004\003\003\003\150\000\060
+\145\002\060\072\213\041\361\275\176\021\255\320\357\130\226\057
+\326\353\235\176\220\215\053\317\146\125\303\054\343\050\251\160
+\012\107\016\360\067\131\022\377\055\231\224\050\116\052\117\065
+\115\063\132\002\061\000\352\165\000\116\073\304\072\224\022\221
+\311\130\106\235\041\023\162\247\210\234\212\344\114\112\333\226
+\324\254\213\153\153\111\022\123\063\255\327\344\276\044\374\265
+\012\166\324\245\274\020
+END
+
+# Trust for "Amazon Root CA 4"
+# Issuer: CN=Amazon Root CA 4,O=Amazon,C=US
+# Serial Number:06:6c:9f:d7:c1:bb:10:4c:29:43:e5:71:7b:7b:2c:c8:1a:c1:0e
+# Subject: CN=Amazon Root CA 4,O=Amazon,C=US
+# Not Valid Before: Tue May 26 00:00:00 2015
+# Not Valid After : Sat May 26 00:00:00 2040
+# Fingerprint (SHA-256): E3:5D:28:41:9E:D0:20:25:CF:A6:90:38:CD:62:39:62:45:8D:A5:C6:95:FB:DE:A3:C2:2B:0B:FB:25:89:70:92
+# Fingerprint (SHA1): F6:10:84:07:D6:F8:BB:67:98:0C:C2:E2:44:C2:EB:AE:1C:EF:63:BE
+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 "Amazon Root CA 4"
+CKA_CERT_SHA1_HASH MULTILINE_OCTAL
+\366\020\204\007\326\370\273\147\230\014\302\342\104\302\353\256
+\034\357\143\276
+END
+CKA_CERT_MD5_HASH MULTILINE_OCTAL
+\211\274\047\325\353\027\215\006\152\151\325\375\211\107\264\315
+END
+CKA_ISSUER MULTILINE_OCTAL
+\060\071\061\013\060\011\006\003\125\004\006\023\002\125\123\061
+\017\060\015\006\003\125\004\012\023\006\101\155\141\172\157\156
+\061\031\060\027\006\003\125\004\003\023\020\101\155\141\172\157
+\156\040\122\157\157\164\040\103\101\040\064
+END
+CKA_SERIAL_NUMBER MULTILINE_OCTAL
+\002\023\006\154\237\327\301\273\020\114\051\103\345\161\173\173
+\054\310\032\301\016
+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 "LuxTrust Global Root 2"
+#
+# Issuer: CN=LuxTrust Global Root 2,O=LuxTrust S.A.,C=LU
+# Serial Number:0a:7e:a6:df:4b:44:9e:da:6a:24:85:9e:e6:b8:15:d3:16:7f:bb:b1
+# Subject: CN=LuxTrust Global Root 2,O=LuxTrust S.A.,C=LU
+# Not Valid Before: Thu Mar 05 13:21:57 2015
+# Not Valid After : Mon Mar 05 13:21:57 2035
+# Fingerprint (SHA-256): 54:45:5F:71:29:C2:0B:14:47:C4:18:F9:97:16:8F:24:C5:8F:C5:02:3B:F5:DA:5B:E2:EB:6E:1D:D8:90:2E:D5
+# Fingerprint (SHA1): 1E:0E:56:19:0A:D1:8B:25:98:B2:04:44:FF:66:8A:04:17:99:5F:3F
+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 "LuxTrust Global Root 2"
+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\114\125\061
+\026\060\024\006\003\125\004\012\014\015\114\165\170\124\162\165
+\163\164\040\123\056\101\056\061\037\060\035\006\003\125\004\003
+\014\026\114\165\170\124\162\165\163\164\040\107\154\157\142\141
+\154\040\122\157\157\164\040\062
+END
+CKA_ID UTF8 "0"
+CKA_ISSUER MULTILINE_OCTAL
+\060\106\061\013\060\011\006\003\125\004\006\023\002\114\125\061
+\026\060\024\006\003\125\004\012\014\015\114\165\170\124\162\165
+\163\164\040\123\056\101\056\061\037\060\035\006\003\125\004\003
+\014\026\114\165\170\124\162\165\163\164\040\107\154\157\142\141
+\154\040\122\157\157\164\040\062
+END
+CKA_SERIAL_NUMBER MULTILINE_OCTAL
+\002\024\012\176\246\337\113\104\236\332\152\044\205\236\346\270
+\025\323\026\177\273\261
+END
+CKA_VALUE MULTILINE_OCTAL
+\060\202\005\303\060\202\003\253\240\003\002\001\002\002\024\012
+\176\246\337\113\104\236\332\152\044\205\236\346\270\025\323\026
+\177\273\261\060\015\006\011\052\206\110\206\367\015\001\001\013
+\005\000\060\106\061\013\060\011\006\003\125\004\006\023\002\114
+\125\061\026\060\024\006\003\125\004\012\014\015\114\165\170\124
+\162\165\163\164\040\123\056\101\056\061\037\060\035\006\003\125
+\004\003\014\026\114\165\170\124\162\165\163\164\040\107\154\157
+\142\141\154\040\122\157\157\164\040\062\060\036\027\015\061\065
+\060\063\060\065\061\063\062\061\065\067\132\027\015\063\065\060
+\063\060\065\061\063\062\061\065\067\132\060\106\061\013\060\011
+\006\003\125\004\006\023\002\114\125\061\026\060\024\006\003\125
+\004\012\014\015\114\165\170\124\162\165\163\164\040\123\056\101
+\056\061\037\060\035\006\003\125\004\003\014\026\114\165\170\124
+\162\165\163\164\040\107\154\157\142\141\154\040\122\157\157\164
+\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\327\205\227\277\021\230\351\360\142\203\114\074\207
+\371\123\152\067\013\362\017\074\207\316\157\334\046\051\275\305
+\211\272\311\203\075\367\356\312\133\306\155\111\163\264\311\106
+\243\033\064\023\077\301\211\105\127\364\331\261\373\066\145\113
+\373\010\342\110\161\021\310\156\073\236\235\337\211\145\067\246
+\205\366\073\104\030\266\306\067\060\142\104\222\227\151\175\102
+\060\044\344\015\014\211\153\143\336\305\341\337\116\251\024\154
+\123\340\141\316\366\027\057\035\074\275\346\042\114\035\223\365
+\020\304\241\166\354\152\336\305\154\337\226\264\126\100\102\300
+\142\222\060\241\055\025\224\240\322\040\006\011\156\152\155\345
+\353\267\276\324\360\361\025\174\213\346\116\272\023\314\113\047
+\136\231\074\027\135\217\201\177\063\075\117\323\077\033\354\134
+\077\360\074\114\165\156\362\246\325\235\332\055\007\143\002\306
+\162\351\224\274\114\111\225\117\210\122\310\333\350\151\202\370
+\314\064\133\042\360\206\247\211\275\110\012\155\146\201\155\310
+\310\144\373\001\341\364\341\336\331\236\335\333\133\324\052\231
+\046\025\033\036\114\222\051\202\236\325\222\201\222\101\160\031
+\367\244\345\223\113\274\167\147\061\335\034\375\061\160\015\027
+\231\014\371\014\071\031\052\027\265\060\161\125\325\017\256\130
+\341\075\057\064\233\317\237\366\170\205\302\223\172\162\076\146
+\217\234\026\021\140\217\236\211\157\147\276\340\107\132\073\014
+\232\147\213\317\106\306\256\070\243\362\247\274\346\326\205\153
+\063\044\160\042\113\313\010\233\273\310\370\002\051\035\276\040
+\014\106\277\153\207\233\263\052\146\102\065\106\154\252\272\255
+\371\230\173\351\120\125\024\061\277\261\332\055\355\200\255\150
+\044\373\151\253\330\161\023\060\346\147\263\207\100\375\211\176
+\362\103\321\021\337\057\145\057\144\316\137\024\271\261\277\061
+\275\207\170\132\131\145\210\252\374\131\062\110\206\326\114\271
+\051\113\225\323\166\363\167\045\155\102\034\070\203\115\375\243
+\137\233\177\055\254\171\033\016\102\061\227\143\244\373\212\151
+\325\042\015\064\220\060\056\250\264\340\155\266\224\254\274\213
+\116\327\160\374\305\070\216\144\045\341\115\071\220\316\311\207
+\204\130\161\002\003\001\000\001\243\201\250\060\201\245\060\017
+\006\003\125\035\023\001\001\377\004\005\060\003\001\001\377\060
+\102\006\003\125\035\040\004\073\060\071\060\067\006\007\053\201
+\053\001\001\001\012\060\054\060\052\006\010\053\006\001\005\005
+\007\002\001\026\036\150\164\164\160\163\072\057\057\162\145\160
+\157\163\151\164\157\162\171\056\154\165\170\164\162\165\163\164
+\056\154\165\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
+\377\030\050\166\371\110\005\054\241\256\361\053\033\053\262\123
+\370\113\174\263\060\035\006\003\125\035\016\004\026\004\024\377
+\030\050\166\371\110\005\054\241\256\361\053\033\053\262\123\370
+\113\174\263\060\015\006\011\052\206\110\206\367\015\001\001\013
+\005\000\003\202\002\001\000\152\031\024\355\156\171\301\054\207
+\324\015\160\176\327\366\170\311\013\004\116\304\261\316\223\160
+\376\260\124\300\062\315\231\060\144\027\277\017\345\342\063\375
+\007\066\100\162\016\032\266\152\131\326\000\345\150\040\335\056
+\162\015\037\152\144\061\040\204\175\111\246\132\067\353\105\311
+\205\365\324\307\027\231\007\346\233\125\344\014\350\251\264\316
+\214\133\265\021\134\317\212\016\015\326\254\167\201\376\062\234
+\044\236\162\316\124\363\320\157\242\126\326\354\303\067\054\145
+\130\276\127\000\032\362\065\372\353\173\061\135\302\301\022\075
+\226\201\210\226\211\301\131\134\172\346\177\160\064\347\203\342
+\261\341\341\270\130\357\324\225\344\140\234\360\226\227\162\214
+\353\204\002\056\145\217\244\267\322\177\147\335\310\323\236\134
+\252\251\244\240\045\024\006\233\354\117\176\055\013\177\035\165
+\361\063\330\355\316\270\165\155\076\133\271\230\035\061\015\126
+\330\103\017\060\221\262\004\153\335\126\276\225\200\125\147\276
+\330\315\203\331\030\356\056\017\206\055\222\236\160\023\354\336
+\121\311\103\170\002\245\115\310\371\137\304\221\130\106\026\167
+\132\164\252\100\274\007\237\060\271\261\367\022\027\335\343\377
+\044\100\035\172\152\321\117\030\012\252\220\035\353\100\036\337
+\241\036\104\222\020\232\362\215\341\321\113\106\236\350\105\102
+\227\352\105\231\363\354\146\325\002\372\362\246\112\044\252\336
+\316\271\312\371\077\223\157\371\243\272\352\245\076\231\255\375
+\377\173\231\365\145\356\360\131\050\147\327\220\225\244\023\204
+\251\204\301\350\316\316\165\223\143\032\274\074\352\325\144\037
+\055\052\022\071\306\303\132\062\355\107\221\026\016\274\070\301
+\120\336\217\312\052\220\064\034\356\101\224\234\136\031\056\370
+\105\111\231\164\221\260\004\157\343\004\132\261\253\052\253\376
+\307\320\226\266\332\341\112\144\006\156\140\115\275\102\116\377
+\170\332\044\312\033\264\327\226\071\154\256\361\016\252\247\175
+\110\213\040\114\317\144\326\270\227\106\260\116\321\052\126\072
+\240\223\275\257\200\044\340\012\176\347\312\325\312\350\205\125
+\334\066\052\341\224\150\223\307\146\162\104\017\200\041\062\154
+\045\307\043\200\203\012\353
+END
+
+# Trust for "LuxTrust Global Root 2"
+# Issuer: CN=LuxTrust Global Root 2,O=LuxTrust S.A.,C=LU
+# Serial Number:0a:7e:a6:df:4b:44:9e:da:6a:24:85:9e:e6:b8:15:d3:16:7f:bb:b1
+# Subject: CN=LuxTrust Global Root 2,O=LuxTrust S.A.,C=LU
+# Not Valid Before: Thu Mar 05 13:21:57 2015
+# Not Valid After : Mon Mar 05 13:21:57 2035
+# Fingerprint (SHA-256): 54:45:5F:71:29:C2:0B:14:47:C4:18:F9:97:16:8F:24:C5:8F:C5:02:3B:F5:DA:5B:E2:EB:6E:1D:D8:90:2E:D5
+# Fingerprint (SHA1): 1E:0E:56:19:0A:D1:8B:25:98:B2:04:44:FF:66:8A:04:17:99:5F:3F
+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 "LuxTrust Global Root 2"
+CKA_CERT_SHA1_HASH MULTILINE_OCTAL
+\036\016\126\031\012\321\213\045\230\262\004\104\377\146\212\004
+\027\231\137\077
+END
+CKA_CERT_MD5_HASH MULTILINE_OCTAL
+\262\341\011\000\141\257\367\361\221\157\304\255\215\136\073\174
+END
+CKA_ISSUER MULTILINE_OCTAL
+\060\106\061\013\060\011\006\003\125\004\006\023\002\114\125\061
+\026\060\024\006\003\125\004\012\014\015\114\165\170\124\162\165
+\163\164\040\123\056\101\056\061\037\060\035\006\003\125\004\003
+\014\026\114\165\170\124\162\165\163\164\040\107\154\157\142\141
+\154\040\122\157\157\164\040\062
+END
+CKA_SERIAL_NUMBER MULTILINE_OCTAL
+\002\024\012\176\246\337\113\104\236\332\152\044\205\236\346\270
+\025\323\026\177\273\261
+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 "Symantec Class 1 Public Primary Certification Authority - G6"
+#
+# Issuer: CN=Symantec Class 1 Public Primary Certification Authority - G6,OU=Symantec Trust Network,O=Symantec Corporation,C=US
+# Serial Number:24:32:75:f2:1d:2f:d2:09:33:f7:b4:6a:ca:d0:f3:98
+# Subject: CN=Symantec Class 1 Public Primary Certification Authority - G6,OU=Symantec Trust Network,O=Symantec Corporation,C=US
+# Not Valid Before: Tue Oct 18 00:00:00 2011
+# Not Valid After : Tue Dec 01 23:59:59 2037
+# Fingerprint (SHA-256): 9D:19:0B:2E:31:45:66:68:5B:E8:A8:89:E2:7A:A8:C7:D7:AE:1D:8A:AD:DB:A3:C1:EC:F9:D2:48:63:CD:34:B9
+# Fingerprint (SHA1): 51:7F:61:1E:29:91:6B:53:82:FB:72:E7:44:D9:8D:C3:CC:53:6D:64
+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 "Symantec Class 1 Public Primary Certification Authority - G6"
+CKA_CERTIFICATE_TYPE CK_CERTIFICATE_TYPE CKC_X_509
+CKA_SUBJECT MULTILINE_OCTAL
+\060\201\224\061\013\060\011\006\003\125\004\006\023\002\125\123
+\061\035\060\033\006\003\125\004\012\023\024\123\171\155\141\156
+\164\145\143\040\103\157\162\160\157\162\141\164\151\157\156\061
+\037\060\035\006\003\125\004\013\023\026\123\171\155\141\156\164
+\145\143\040\124\162\165\163\164\040\116\145\164\167\157\162\153
+\061\105\060\103\006\003\125\004\003\023\074\123\171\155\141\156
+\164\145\143\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\066
+END
+CKA_ID UTF8 "0"
+CKA_ISSUER MULTILINE_OCTAL
+\060\201\224\061\013\060\011\006\003\125\004\006\023\002\125\123
+\061\035\060\033\006\003\125\004\012\023\024\123\171\155\141\156
+\164\145\143\040\103\157\162\160\157\162\141\164\151\157\156\061
+\037\060\035\006\003\125\004\013\023\026\123\171\155\141\156\164
+\145\143\040\124\162\165\163\164\040\116\145\164\167\157\162\153
+\061\105\060\103\006\003\125\004\003\023\074\123\171\155\141\156
+\164\145\143\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\066
+END
+CKA_SERIAL_NUMBER MULTILINE_OCTAL
+\002\020\044\062\165\362\035\057\322\011\063\367\264\152\312\320
+\363\230
+END
+CKA_VALUE MULTILINE_OCTAL
+\060\202\003\366\060\202\002\336\240\003\002\001\002\002\020\044
+\062\165\362\035\057\322\011\063\367\264\152\312\320\363\230\060
+\015\006\011\052\206\110\206\367\015\001\001\013\005\000\060\201
+\224\061\013\060\011\006\003\125\004\006\023\002\125\123\061\035
+\060\033\006\003\125\004\012\023\024\123\171\155\141\156\164\145
+\143\040\103\157\162\160\157\162\141\164\151\157\156\061\037\060
+\035\006\003\125\004\013\023\026\123\171\155\141\156\164\145\143
+\040\124\162\165\163\164\040\116\145\164\167\157\162\153\061\105
+\060\103\006\003\125\004\003\023\074\123\171\155\141\156\164\145
+\143\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\066\060\036\027\015\061\061\061\060\061\070\060
+\060\060\060\060\060\132\027\015\063\067\061\062\060\061\062\063
+\065\071\065\071\132\060\201\224\061\013\060\011\006\003\125\004
+\006\023\002\125\123\061\035\060\033\006\003\125\004\012\023\024
+\123\171\155\141\156\164\145\143\040\103\157\162\160\157\162\141
+\164\151\157\156\061\037\060\035\006\003\125\004\013\023\026\123
+\171\155\141\156\164\145\143\040\124\162\165\163\164\040\116\145
+\164\167\157\162\153\061\105\060\103\006\003\125\004\003\023\074
+\123\171\155\141\156\164\145\143\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\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\307\071\327
+\111\144\251\231\202\042\114\352\105\331\007\026\343\173\364\203
+\350\231\163\372\153\261\066\340\232\167\240\100\302\201\215\001
+\307\314\214\275\217\175\367\171\343\172\114\003\115\331\373\375
+\207\070\050\054\335\232\213\124\010\333\147\373\033\214\376\050
+\222\057\276\267\262\110\247\201\241\330\136\210\303\314\071\100
+\101\132\321\334\345\332\020\237\057\332\001\115\375\056\106\174
+\371\056\047\012\151\067\356\221\243\033\152\314\104\277\033\307
+\303\324\021\262\120\140\227\011\275\056\042\365\101\204\146\237
+\315\100\246\251\000\200\301\037\225\222\237\336\363\110\357\333
+\035\167\141\374\177\337\356\226\244\162\320\266\076\377\170\047
+\257\313\222\025\151\010\333\143\020\342\346\227\254\156\334\254
+\366\242\316\036\107\231\271\211\267\022\346\241\324\315\131\021
+\147\303\157\205\330\102\116\050\276\131\125\131\004\225\253\217
+\067\200\277\015\360\374\037\072\144\061\130\201\170\327\342\065
+\366\040\077\051\270\217\026\156\076\110\334\265\114\007\341\362
+\032\352\176\012\171\326\250\275\353\135\206\053\115\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\063\101\350\310\071\022\025\223\110\362\226\062\056\132
+\365\332\224\137\123\140\060\015\006\011\052\206\110\206\367\015
+\001\001\013\005\000\003\202\001\001\000\025\343\163\127\261\027
+\266\137\111\151\104\246\366\136\172\147\254\322\336\165\111\253
+\376\045\125\307\072\311\104\025\020\156\277\061\153\313\331\007
+\223\177\034\205\143\000\343\062\022\340\314\313\373\071\154\217
+\342\123\342\074\100\063\331\244\214\107\346\255\130\373\211\257
+\343\336\206\051\126\064\054\105\270\022\372\104\211\156\055\024
+\045\050\044\001\145\326\352\122\254\005\156\126\022\011\075\320
+\164\364\327\275\006\312\250\072\215\126\102\372\215\162\076\164
+\361\003\162\337\207\033\136\016\172\125\226\054\070\267\230\205
+\315\115\063\104\311\224\217\132\061\060\067\113\243\072\022\263
+\347\066\321\041\150\113\055\070\346\123\256\034\045\126\010\126
+\003\147\204\235\306\303\316\044\142\307\114\066\317\260\006\104
+\267\365\137\002\335\331\124\351\057\220\116\172\310\116\203\100
+\014\232\227\074\067\277\277\354\366\360\264\205\167\050\301\013
+\310\147\202\020\027\070\242\267\006\352\233\277\072\370\351\043
+\007\277\164\340\230\070\025\125\170\356\162\000\134\031\243\364
+\322\063\340\377\275\321\124\071\051\017
+END
+
+# Trust for "Symantec Class 1 Public Primary Certification Authority - G6"
+# Issuer: CN=Symantec Class 1 Public Primary Certification Authority - G6,OU=Symantec Trust Network,O=Symantec Corporation,C=US
+# Serial Number:24:32:75:f2:1d:2f:d2:09:33:f7:b4:6a:ca:d0:f3:98
+# Subject: CN=Symantec Class 1 Public Primary Certification Authority - G6,OU=Symantec Trust Network,O=Symantec Corporation,C=US
+# Not Valid Before: Tue Oct 18 00:00:00 2011
+# Not Valid After : Tue Dec 01 23:59:59 2037
+# Fingerprint (SHA-256): 9D:19:0B:2E:31:45:66:68:5B:E8:A8:89:E2:7A:A8:C7:D7:AE:1D:8A:AD:DB:A3:C1:EC:F9:D2:48:63:CD:34:B9
+# Fingerprint (SHA1): 51:7F:61:1E:29:91:6B:53:82:FB:72:E7:44:D9:8D:C3:CC:53:6D:64
+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 "Symantec Class 1 Public Primary Certification Authority - G6"
+CKA_CERT_SHA1_HASH MULTILINE_OCTAL
+\121\177\141\036\051\221\153\123\202\373\162\347\104\331\215\303
+\314\123\155\144
+END
+CKA_CERT_MD5_HASH MULTILINE_OCTAL
+\057\250\264\332\366\144\113\036\202\371\106\075\124\032\174\260
+END
+CKA_ISSUER MULTILINE_OCTAL
+\060\201\224\061\013\060\011\006\003\125\004\006\023\002\125\123
+\061\035\060\033\006\003\125\004\012\023\024\123\171\155\141\156
+\164\145\143\040\103\157\162\160\157\162\141\164\151\157\156\061
+\037\060\035\006\003\125\004\013\023\026\123\171\155\141\156\164
+\145\143\040\124\162\165\163\164\040\116\145\164\167\157\162\153
+\061\105\060\103\006\003\125\004\003\023\074\123\171\155\141\156
+\164\145\143\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\066
+END
+CKA_SERIAL_NUMBER MULTILINE_OCTAL
+\002\020\044\062\165\362\035\057\322\011\063\367\264\152\312\320
+\363\230
+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 "Symantec Class 2 Public Primary Certification Authority - G6"
+#
+# Issuer: CN=Symantec Class 2 Public Primary Certification Authority - G6,OU=Symantec Trust Network,O=Symantec Corporation,C=US
+# Serial Number:64:82:9e:fc:37:1e:74:5d:fc:97:ff:97:c8:b1:ff:41
+# Subject: CN=Symantec Class 2 Public Primary Certification Authority - G6,OU=Symantec Trust Network,O=Symantec Corporation,C=US
+# Not Valid Before: Tue Oct 18 00:00:00 2011
+# Not Valid After : Tue Dec 01 23:59:59 2037
+# Fingerprint (SHA-256): CB:62:7D:18:B5:8A:D5:6D:DE:33:1A:30:45:6B:C6:5C:60:1A:4E:9B:18:DE:DC:EA:08:E7:DA:AA:07:81:5F:F0
+# Fingerprint (SHA1): 40:B3:31:A0:E9:BF:E8:55:BC:39:93:CA:70:4F:4E:C2:51:D4:1D:8F
+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 "Symantec Class 2 Public Primary Certification Authority - G6"
+CKA_CERTIFICATE_TYPE CK_CERTIFICATE_TYPE CKC_X_509
+CKA_SUBJECT MULTILINE_OCTAL
+\060\201\224\061\013\060\011\006\003\125\004\006\023\002\125\123
+\061\035\060\033\006\003\125\004\012\023\024\123\171\155\141\156
+\164\145\143\040\103\157\162\160\157\162\141\164\151\157\156\061
+\037\060\035\006\003\125\004\013\023\026\123\171\155\141\156\164
+\145\143\040\124\162\165\163\164\040\116\145\164\167\157\162\153
+\061\105\060\103\006\003\125\004\003\023\074\123\171\155\141\156
+\164\145\143\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\066
+END
+CKA_ID UTF8 "0"
+CKA_ISSUER MULTILINE_OCTAL
+\060\201\224\061\013\060\011\006\003\125\004\006\023\002\125\123
+\061\035\060\033\006\003\125\004\012\023\024\123\171\155\141\156
+\164\145\143\040\103\157\162\160\157\162\141\164\151\157\156\061
+\037\060\035\006\003\125\004\013\023\026\123\171\155\141\156\164
+\145\143\040\124\162\165\163\164\040\116\145\164\167\157\162\153
+\061\105\060\103\006\003\125\004\003\023\074\123\171\155\141\156
+\164\145\143\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\066
+END
+CKA_SERIAL_NUMBER MULTILINE_OCTAL
+\002\020\144\202\236\374\067\036\164\135\374\227\377\227\310\261
+\377\101
+END
+CKA_VALUE MULTILINE_OCTAL
+\060\202\003\366\060\202\002\336\240\003\002\001\002\002\020\144
+\202\236\374\067\036\164\135\374\227\377\227\310\261\377\101\060
+\015\006\011\052\206\110\206\367\015\001\001\013\005\000\060\201
+\224\061\013\060\011\006\003\125\004\006\023\002\125\123\061\035
+\060\033\006\003\125\004\012\023\024\123\171\155\141\156\164\145
+\143\040\103\157\162\160\157\162\141\164\151\157\156\061\037\060
+\035\006\003\125\004\013\023\026\123\171\155\141\156\164\145\143
+\040\124\162\165\163\164\040\116\145\164\167\157\162\153\061\105
+\060\103\006\003\125\004\003\023\074\123\171\155\141\156\164\145
+\143\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\066\060\036\027\015\061\061\061\060\061\070\060
+\060\060\060\060\060\132\027\015\063\067\061\062\060\061\062\063
+\065\071\065\071\132\060\201\224\061\013\060\011\006\003\125\004
+\006\023\002\125\123\061\035\060\033\006\003\125\004\012\023\024
+\123\171\155\141\156\164\145\143\040\103\157\162\160\157\162\141
+\164\151\157\156\061\037\060\035\006\003\125\004\013\023\026\123
+\171\155\141\156\164\145\143\040\124\162\165\163\164\040\116\145
+\164\167\157\162\153\061\105\060\103\006\003\125\004\003\023\074
+\123\171\155\141\156\164\145\143\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\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\315\314\351
+\005\310\143\205\313\077\100\143\027\275\030\372\065\346\004\147
+\127\145\230\051\244\117\311\134\217\017\064\322\370\332\250\023
+\142\252\270\036\120\147\170\260\026\114\240\071\251\025\172\256
+\355\322\242\300\360\220\067\051\030\046\134\350\015\074\266\154
+\111\077\301\340\334\331\113\266\024\031\013\246\323\226\341\326
+\011\343\031\046\034\371\037\145\113\371\032\103\034\000\203\326
+\320\252\111\242\324\333\346\142\070\272\120\024\103\155\371\061
+\370\126\026\331\070\002\221\317\353\154\335\273\071\116\231\341
+\060\147\105\361\324\360\215\303\337\376\362\070\007\041\175\000
+\136\126\104\263\344\140\275\221\053\234\253\133\004\162\017\262
+\050\331\162\253\005\040\102\045\251\133\003\152\040\020\314\061
+\360\053\332\065\054\320\373\232\227\116\360\202\113\053\330\137
+\066\243\013\055\257\143\015\035\045\177\241\156\134\142\241\215
+\050\076\241\374\034\040\370\001\057\272\125\232\021\260\031\322
+\310\120\171\153\016\152\005\327\252\004\066\262\243\362\341\137
+\167\247\167\234\345\036\334\351\337\152\301\145\135\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\207\214\040\225\310\230\112\321\326\200\006\112\220\064
+\104\337\034\115\277\260\060\015\006\011\052\206\110\206\367\015
+\001\001\013\005\000\003\202\001\001\000\201\216\262\245\146\226
+\267\041\245\266\357\157\043\132\137\333\201\305\102\245\170\301
+\151\375\364\074\327\371\134\153\160\162\032\374\132\227\115\000
+\200\210\210\202\212\303\161\015\216\305\211\233\054\355\215\013
+\322\162\124\365\175\324\134\103\127\351\363\256\245\002\021\366
+\166\053\201\127\335\175\332\164\060\375\124\107\366\340\026\156
+\246\264\012\110\346\347\165\007\017\051\031\071\316\171\364\266
+\154\305\137\231\325\037\113\372\337\155\054\074\015\124\200\160
+\360\210\013\200\317\306\150\242\270\035\160\331\166\214\374\356
+\245\311\317\255\035\317\231\045\127\132\142\105\313\026\153\275
+\111\315\245\243\214\151\171\045\256\270\114\154\213\100\146\113
+\026\077\317\002\032\335\341\154\153\007\141\152\166\025\051\231
+\177\033\335\210\200\301\277\265\217\163\305\246\226\043\204\246
+\050\206\044\063\152\001\056\127\163\045\266\136\277\217\346\035
+\141\250\100\051\147\035\207\233\035\177\233\237\231\315\061\326
+\124\276\142\273\071\254\150\022\110\221\040\245\313\261\335\376
+\157\374\132\344\202\125\131\257\061\251
+END
+
+# Trust for "Symantec Class 2 Public Primary Certification Authority - G6"
+# Issuer: CN=Symantec Class 2 Public Primary Certification Authority - G6,OU=Symantec Trust Network,O=Symantec Corporation,C=US
+# Serial Number:64:82:9e:fc:37:1e:74:5d:fc:97:ff:97:c8:b1:ff:41
+# Subject: CN=Symantec Class 2 Public Primary Certification Authority - G6,OU=Symantec Trust Network,O=Symantec Corporation,C=US
+# Not Valid Before: Tue Oct 18 00:00:00 2011
+# Not Valid After : Tue Dec 01 23:59:59 2037
+# Fingerprint (SHA-256): CB:62:7D:18:B5:8A:D5:6D:DE:33:1A:30:45:6B:C6:5C:60:1A:4E:9B:18:DE:DC:EA:08:E7:DA:AA:07:81:5F:F0
+# Fingerprint (SHA1): 40:B3:31:A0:E9:BF:E8:55:BC:39:93:CA:70:4F:4E:C2:51:D4:1D:8F
+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 "Symantec Class 2 Public Primary Certification Authority - G6"
+CKA_CERT_SHA1_HASH MULTILINE_OCTAL
+\100\263\061\240\351\277\350\125\274\071\223\312\160\117\116\302
+\121\324\035\217
+END
+CKA_CERT_MD5_HASH MULTILINE_OCTAL
+\175\013\203\345\373\174\255\007\117\040\251\265\337\143\355\171
+END
+CKA_ISSUER MULTILINE_OCTAL
+\060\201\224\061\013\060\011\006\003\125\004\006\023\002\125\123
+\061\035\060\033\006\003\125\004\012\023\024\123\171\155\141\156
+\164\145\143\040\103\157\162\160\157\162\141\164\151\157\156\061
+\037\060\035\006\003\125\004\013\023\026\123\171\155\141\156\164
+\145\143\040\124\162\165\163\164\040\116\145\164\167\157\162\153
+\061\105\060\103\006\003\125\004\003\023\074\123\171\155\141\156
+\164\145\143\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\066
+END
+CKA_SERIAL_NUMBER MULTILINE_OCTAL
+\002\020\144\202\236\374\067\036\164\135\374\227\377\227\310\261
+\377\101
+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 "Symantec Class 1 Public Primary Certification Authority - G4"
+#
+# Issuer: CN=Symantec Class 1 Public Primary Certification Authority - G4,OU=Symantec Trust Network,O=Symantec Corporation,C=US
+# Serial Number:21:6e:33:a5:cb:d3:88:a4:6f:29:07:b4:27:3c:c4:d8
+# Subject: CN=Symantec Class 1 Public Primary Certification Authority - G4,OU=Symantec Trust Network,O=Symantec Corporation,C=US
+# Not Valid Before: Wed Oct 05 00:00:00 2011
+# Not Valid After : Mon Jan 18 23:59:59 2038
+# Fingerprint (SHA-256): 36:3F:3C:84:9E:AB:03:B0:A2:A0:F6:36:D7:B8:6D:04:D3:AC:7F:CF:E2:6A:0A:91:21:AB:97:95:F6:E1:76:DF
+# Fingerprint (SHA1): 84:F2:E3:DD:83:13:3E:A9:1D:19:52:7F:02:D7:29:BF:C1:5F:E6:67
+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 "Symantec Class 1 Public Primary Certification Authority - G4"
+CKA_CERTIFICATE_TYPE CK_CERTIFICATE_TYPE CKC_X_509
+CKA_SUBJECT MULTILINE_OCTAL
+\060\201\224\061\013\060\011\006\003\125\004\006\023\002\125\123
+\061\035\060\033\006\003\125\004\012\023\024\123\171\155\141\156
+\164\145\143\040\103\157\162\160\157\162\141\164\151\157\156\061
+\037\060\035\006\003\125\004\013\023\026\123\171\155\141\156\164
+\145\143\040\124\162\165\163\164\040\116\145\164\167\157\162\153
+\061\105\060\103\006\003\125\004\003\023\074\123\171\155\141\156
+\164\145\143\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\064
+END
+CKA_ID UTF8 "0"
+CKA_ISSUER MULTILINE_OCTAL
+\060\201\224\061\013\060\011\006\003\125\004\006\023\002\125\123
+\061\035\060\033\006\003\125\004\012\023\024\123\171\155\141\156
+\164\145\143\040\103\157\162\160\157\162\141\164\151\157\156\061
+\037\060\035\006\003\125\004\013\023\026\123\171\155\141\156\164
+\145\143\040\124\162\165\163\164\040\116\145\164\167\157\162\153
+\061\105\060\103\006\003\125\004\003\023\074\123\171\155\141\156
+\164\145\143\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\064
+END
+CKA_SERIAL_NUMBER MULTILINE_OCTAL
+\002\020\041\156\063\245\313\323\210\244\157\051\007\264\047\074
+\304\330
+END
+CKA_VALUE MULTILINE_OCTAL
+\060\202\002\250\060\202\002\055\240\003\002\001\002\002\020\041
+\156\063\245\313\323\210\244\157\051\007\264\047\074\304\330\060
+\012\006\010\052\206\110\316\075\004\003\003\060\201\224\061\013
+\060\011\006\003\125\004\006\023\002\125\123\061\035\060\033\006
+\003\125\004\012\023\024\123\171\155\141\156\164\145\143\040\103
+\157\162\160\157\162\141\164\151\157\156\061\037\060\035\006\003
+\125\004\013\023\026\123\171\155\141\156\164\145\143\040\124\162
+\165\163\164\040\116\145\164\167\157\162\153\061\105\060\103\006
+\003\125\004\003\023\074\123\171\155\141\156\164\145\143\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\064\060\036\027\015\061\061\061\060\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\224\061\013\060\011\006\003\125\004\006\023\002
+\125\123\061\035\060\033\006\003\125\004\012\023\024\123\171\155
+\141\156\164\145\143\040\103\157\162\160\157\162\141\164\151\157
+\156\061\037\060\035\006\003\125\004\013\023\026\123\171\155\141
+\156\164\145\143\040\124\162\165\163\164\040\116\145\164\167\157
+\162\153\061\105\060\103\006\003\125\004\003\023\074\123\171\155
+\141\156\164\145\143\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\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\327\146\265\033\333\256\263\140\356\106\352\210\143\165\073
+\052\224\155\363\137\022\366\343\017\236\266\012\024\123\110\122
+\310\334\072\263\313\110\040\046\022\116\372\211\204\324\337\221
+\344\051\175\050\001\331\333\030\103\151\241\037\265\323\206\026
+\334\307\177\147\043\337\337\061\061\203\003\065\160\261\113\267
+\310\027\273\121\313\334\224\027\333\352\011\073\166\022\336\252
+\265\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\145\300\215\045\365\014\272\227\167\220\077\236\056\340\132
+\365\316\325\341\344\060\012\006\010\052\206\110\316\075\004\003
+\003\003\151\000\060\146\002\061\000\245\256\343\106\123\370\230
+\066\343\042\372\056\050\111\015\356\060\176\063\363\354\077\161
+\136\314\125\211\170\231\254\262\375\334\034\134\063\216\051\271
+\153\027\310\021\150\265\334\203\007\002\061\000\234\310\104\332
+\151\302\066\303\124\031\020\205\002\332\235\107\357\101\347\154
+\046\235\011\075\367\155\220\321\005\104\057\260\274\203\223\150
+\362\014\105\111\071\277\231\004\034\323\020\240
+END
+
+# Trust for "Symantec Class 1 Public Primary Certification Authority - G4"
+# Issuer: CN=Symantec Class 1 Public Primary Certification Authority - G4,OU=Symantec Trust Network,O=Symantec Corporation,C=US
+# Serial Number:21:6e:33:a5:cb:d3:88:a4:6f:29:07:b4:27:3c:c4:d8
+# Subject: CN=Symantec Class 1 Public Primary Certification Authority - G4,OU=Symantec Trust Network,O=Symantec Corporation,C=US
+# Not Valid Before: Wed Oct 05 00:00:00 2011
+# Not Valid After : Mon Jan 18 23:59:59 2038
+# Fingerprint (SHA-256): 36:3F:3C:84:9E:AB:03:B0:A2:A0:F6:36:D7:B8:6D:04:D3:AC:7F:CF:E2:6A:0A:91:21:AB:97:95:F6:E1:76:DF
+# Fingerprint (SHA1): 84:F2:E3:DD:83:13:3E:A9:1D:19:52:7F:02:D7:29:BF:C1:5F:E6:67
+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 "Symantec Class 1 Public Primary Certification Authority - G4"
+CKA_CERT_SHA1_HASH MULTILINE_OCTAL
+\204\362\343\335\203\023\076\251\035\031\122\177\002\327\051\277
+\301\137\346\147
+END
+CKA_CERT_MD5_HASH MULTILINE_OCTAL
+\004\345\200\077\125\377\131\207\244\062\322\025\245\345\252\346
+END
+CKA_ISSUER MULTILINE_OCTAL
+\060\201\224\061\013\060\011\006\003\125\004\006\023\002\125\123
+\061\035\060\033\006\003\125\004\012\023\024\123\171\155\141\156
+\164\145\143\040\103\157\162\160\157\162\141\164\151\157\156\061
+\037\060\035\006\003\125\004\013\023\026\123\171\155\141\156\164
+\145\143\040\124\162\165\163\164\040\116\145\164\167\157\162\153
+\061\105\060\103\006\003\125\004\003\023\074\123\171\155\141\156
+\164\145\143\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\064
+END
+CKA_SERIAL_NUMBER MULTILINE_OCTAL
+\002\020\041\156\063\245\313\323\210\244\157\051\007\264\047\074
+\304\330
+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 "Symantec Class 2 Public Primary Certification Authority - G4"
+#
+# Issuer: CN=Symantec Class 2 Public Primary Certification Authority - G4,OU=Symantec Trust Network,O=Symantec Corporation,C=US
+# Serial Number:34:17:65:12:40:3b:b7:56:80:2d:80:cb:79:55:a6:1e
+# Subject: CN=Symantec Class 2 Public Primary Certification Authority - G4,OU=Symantec Trust Network,O=Symantec Corporation,C=US
+# Not Valid Before: Wed Oct 05 00:00:00 2011
+# Not Valid After : Mon Jan 18 23:59:59 2038
+# Fingerprint (SHA-256): FE:86:3D:08:22:FE:7A:23:53:FA:48:4D:59:24:E8:75:65:6D:3D:C9:FB:58:77:1F:6F:61:6F:9D:57:1B:C5:92
+# Fingerprint (SHA1): 67:24:90:2E:48:01:B0:22:96:40:10:46:B4:B1:67:2C:A9:75:FD:2B
+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 "Symantec Class 2 Public Primary Certification Authority - G4"
+CKA_CERTIFICATE_TYPE CK_CERTIFICATE_TYPE CKC_X_509
+CKA_SUBJECT MULTILINE_OCTAL
+\060\201\224\061\013\060\011\006\003\125\004\006\023\002\125\123
+\061\035\060\033\006\003\125\004\012\023\024\123\171\155\141\156
+\164\145\143\040\103\157\162\160\157\162\141\164\151\157\156\061
+\037\060\035\006\003\125\004\013\023\026\123\171\155\141\156\164
+\145\143\040\124\162\165\163\164\040\116\145\164\167\157\162\153
+\061\105\060\103\006\003\125\004\003\023\074\123\171\155\141\156
+\164\145\143\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\064
+END
+CKA_ID UTF8 "0"
+CKA_ISSUER MULTILINE_OCTAL
+\060\201\224\061\013\060\011\006\003\125\004\006\023\002\125\123
+\061\035\060\033\006\003\125\004\012\023\024\123\171\155\141\156
+\164\145\143\040\103\157\162\160\157\162\141\164\151\157\156\061
+\037\060\035\006\003\125\004\013\023\026\123\171\155\141\156\164
+\145\143\040\124\162\165\163\164\040\116\145\164\167\157\162\153
+\061\105\060\103\006\003\125\004\003\023\074\123\171\155\141\156
+\164\145\143\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\064
+END
+CKA_SERIAL_NUMBER MULTILINE_OCTAL
+\002\020\064\027\145\022\100\073\267\126\200\055\200\313\171\125
+\246\036
+END
+CKA_VALUE MULTILINE_OCTAL
+\060\202\002\250\060\202\002\055\240\003\002\001\002\002\020\064
+\027\145\022\100\073\267\126\200\055\200\313\171\125\246\036\060
+\012\006\010\052\206\110\316\075\004\003\003\060\201\224\061\013
+\060\011\006\003\125\004\006\023\002\125\123\061\035\060\033\006
+\003\125\004\012\023\024\123\171\155\141\156\164\145\143\040\103
+\157\162\160\157\162\141\164\151\157\156\061\037\060\035\006\003
+\125\004\013\023\026\123\171\155\141\156\164\145\143\040\124\162
+\165\163\164\040\116\145\164\167\157\162\153\061\105\060\103\006
+\003\125\004\003\023\074\123\171\155\141\156\164\145\143\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\064\060\036\027\015\061\061\061\060\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\224\061\013\060\011\006\003\125\004\006\023\002
+\125\123\061\035\060\033\006\003\125\004\012\023\024\123\171\155
+\141\156\164\145\143\040\103\157\162\160\157\162\141\164\151\157
+\156\061\037\060\035\006\003\125\004\013\023\026\123\171\155\141
+\156\164\145\143\040\124\162\165\163\164\040\116\145\164\167\157
+\162\153\061\105\060\103\006\003\125\004\003\023\074\123\171\155
+\141\156\164\145\143\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\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\321\331\112\216\114\015\204\112\121\272\174\357\323\314\372
+\072\232\265\247\143\023\075\001\340\111\076\372\301\107\311\222
+\263\072\327\376\157\234\367\232\072\017\365\016\012\012\303\077
+\310\347\022\024\216\325\325\155\230\054\263\161\062\012\353\052
+\275\366\327\152\040\013\147\105\234\322\262\277\123\042\146\011
+\135\333\021\363\361\005\063\130\243\342\270\317\174\315\202\233
+\275\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\075\062\363\072\251\014\220\204\371\242\214\151\006\141\124
+\057\207\162\376\005\060\012\006\010\052\206\110\316\075\004\003
+\003\003\151\000\060\146\002\061\000\310\246\251\257\101\177\265
+\311\021\102\026\150\151\114\134\270\047\030\266\230\361\300\177
+\220\155\207\323\214\106\027\360\076\117\374\352\260\010\304\172
+\113\274\010\057\307\342\247\157\145\002\061\000\326\131\336\206
+\316\137\016\312\124\325\306\320\025\016\374\213\224\162\324\216
+\000\130\123\317\176\261\113\015\345\120\206\353\236\153\337\377
+\051\246\330\107\331\240\226\030\333\362\105\263
+END
+
+# Trust for "Symantec Class 2 Public Primary Certification Authority - G4"
+# Issuer: CN=Symantec Class 2 Public Primary Certification Authority - G4,OU=Symantec Trust Network,O=Symantec Corporation,C=US
+# Serial Number:34:17:65:12:40:3b:b7:56:80:2d:80:cb:79:55:a6:1e
+# Subject: CN=Symantec Class 2 Public Primary Certification Authority - G4,OU=Symantec Trust Network,O=Symantec Corporation,C=US
+# Not Valid Before: Wed Oct 05 00:00:00 2011
+# Not Valid After : Mon Jan 18 23:59:59 2038
+# Fingerprint (SHA-256): FE:86:3D:08:22:FE:7A:23:53:FA:48:4D:59:24:E8:75:65:6D:3D:C9:FB:58:77:1F:6F:61:6F:9D:57:1B:C5:92
+# Fingerprint (SHA1): 67:24:90:2E:48:01:B0:22:96:40:10:46:B4:B1:67:2C:A9:75:FD:2B
+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 "Symantec Class 2 Public Primary Certification Authority - G4"
+CKA_CERT_SHA1_HASH MULTILINE_OCTAL
+\147\044\220\056\110\001\260\042\226\100\020\106\264\261\147\054
+\251\165\375\053
+END
+CKA_CERT_MD5_HASH MULTILINE_OCTAL
+\160\325\060\361\332\224\227\324\327\164\337\276\355\150\336\226
+END
+CKA_ISSUER MULTILINE_OCTAL
+\060\201\224\061\013\060\011\006\003\125\004\006\023\002\125\123
+\061\035\060\033\006\003\125\004\012\023\024\123\171\155\141\156
+\164\145\143\040\103\157\162\160\157\162\141\164\151\157\156\061
+\037\060\035\006\003\125\004\013\023\026\123\171\155\141\156\164
+\145\143\040\124\162\165\163\164\040\116\145\164\167\157\162\153
+\061\105\060\103\006\003\125\004\003\023\074\123\171\155\141\156
+\164\145\143\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\064
+END
+CKA_SERIAL_NUMBER MULTILINE_OCTAL
+\002\020\064\027\145\022\100\073\267\126\200\055\200\313\171\125
+\246\036
+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
diff --git a/nss/lib/ckfw/builtins/ckbiver.c b/nss/lib/ckfw/builtins/ckbiver.c
index 41783b2..208066c 100644
--- a/nss/lib/ckfw/builtins/ckbiver.c
+++ b/nss/lib/ckfw/builtins/ckbiver.c
@@ -15,5 +15,4 @@
/*
* Version information
*/
-const char __nss_builtins_version[] = "Version: NSS Builtin Trusted Root CAs "
- NSS_BUILTINS_LIBRARY_VERSION _DEBUG_STRING;
+const char __nss_builtins_version[] = "Version: NSS Builtin Trusted Root CAs " NSS_BUILTINS_LIBRARY_VERSION _DEBUG_STRING;
diff --git a/nss/lib/ckfw/builtins/config.mk b/nss/lib/ckfw/builtins/config.mk
index b385ac6..6bd62f1 100644
--- a/nss/lib/ckfw/builtins/config.mk
+++ b/nss/lib/ckfw/builtins/config.mk
@@ -32,3 +32,7 @@ INCLUDES += -I.
ifeq ($(OS_TARGET),Darwin)
DSO_LDOPTS = -bundle
endif
+
+ifdef USE_GCOV
+DSO_LDOPTS += --coverage
+endif
diff --git a/nss/lib/ckfw/builtins/constants.c b/nss/lib/ckfw/builtins/constants.c
index 71146e6..f5d267b 100644
--- a/nss/lib/ckfw/builtins/constants.c
+++ b/nss/lib/ckfw/builtins/constants.c
@@ -21,41 +21,44 @@
#endif /* NSSCKBI_H */
const CK_VERSION
-nss_builtins_CryptokiVersion = {
- NSS_BUILTINS_CRYPTOKI_VERSION_MAJOR,
- NSS_BUILTINS_CRYPTOKI_VERSION_MINOR };
+ 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};
+ 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 };
+ 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 };
+ nss_builtins_FirmwareVersion = {
+ NSS_BUILTINS_FIRMWARE_VERSION_MAJOR,
+ NSS_BUILTINS_FIRMWARE_VERSION_MINOR
+ };
-const NSSUTF8
-nss_builtins_ManufacturerID[] = { "Mozilla Foundation" };
+const NSSUTF8
+ nss_builtins_ManufacturerID[] = { "Mozilla Foundation" };
-const NSSUTF8
-nss_builtins_LibraryDescription[] = { "NSS Builtin Object Cryptoki Module" };
+const NSSUTF8
+ nss_builtins_LibraryDescription[] = { "NSS Builtin Object Cryptoki Module" };
-const NSSUTF8
-nss_builtins_SlotDescription[] = { "NSS Builtin Objects" };
+const NSSUTF8
+ nss_builtins_SlotDescription[] = { "NSS Builtin Objects" };
-const NSSUTF8
-nss_builtins_TokenLabel[] = { "Builtin Object Token" };
+const NSSUTF8
+ nss_builtins_TokenLabel[] = { "Builtin Object Token" };
-const NSSUTF8
-nss_builtins_TokenModel[] = { "1" };
+const NSSUTF8
+ nss_builtins_TokenModel[] = { "1" };
/* should this be e.g. the certdata.txt RCS revision number? */
-const NSSUTF8
-nss_builtins_TokenSerialNumber[] = { "1" };
-
+const NSSUTF8
+ nss_builtins_TokenSerialNumber[] = { "1" };
diff --git a/nss/lib/ckfw/builtins/exports.gyp b/nss/lib/ckfw/builtins/exports.gyp
new file mode 100644
index 0000000..6a5c38f
--- /dev/null
+++ b/nss/lib/ckfw/builtins/exports.gyp
@@ -0,0 +1,25 @@
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+{
+ 'includes': [
+ '../../../coreconf/config.gypi'
+ ],
+ 'targets': [
+ {
+ 'target_name': 'lib_ckfw_builtins_exports',
+ 'type': 'none',
+ 'copies': [
+ {
+ 'files': [
+ 'nssckbi.h'
+ ],
+ 'destination': '<(nss_public_dist_dir)/<(module)'
+ }
+ ]
+ }
+ ],
+ 'variables': {
+ 'module': 'nss'
+ }
+}
diff --git a/nss/lib/ckfw/builtins/nssckbi.h b/nss/lib/ckfw/builtins/nssckbi.h
index 5ef3a49..4f1e357 100644
--- a/nss/lib/ckfw/builtins/nssckbi.h
+++ b/nss/lib/ckfw/builtins/nssckbi.h
@@ -18,7 +18,7 @@
#define NSS_BUILTINS_CRYPTOKI_VERSION_MAJOR 2
#define NSS_BUILTINS_CRYPTOKI_VERSION_MINOR 20
-/* These version numbers detail the changes
+/* These version numbers detail the changes
* to the list of trusted certificates.
*
* The NSS_BUILTINS_LIBRARY_VERSION_MINOR macro needs to be bumped
@@ -45,14 +45,14 @@
* of the comment in the CK_VERSION type definition.
*/
#define NSS_BUILTINS_LIBRARY_VERSION_MAJOR 2
-#define NSS_BUILTINS_LIBRARY_VERSION_MINOR 6
-#define NSS_BUILTINS_LIBRARY_VERSION "2.6"
+#define NSS_BUILTINS_LIBRARY_VERSION_MINOR 11
+#define NSS_BUILTINS_LIBRARY_VERSION "2.11"
/* 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
+/* 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
diff --git a/nss/lib/ckfw/capi/anchor.c b/nss/lib/ckfw/capi/anchor.c
index 97f3f0d..2d1523e 100644
--- a/nss/lib/ckfw/capi/anchor.c
+++ b/nss/lib/ckfw/capi/anchor.c
@@ -6,7 +6,7 @@
* 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
+ * shared library, which is required for dynamic loading. See the
* comments in nssck.api for more information.
*/
diff --git a/nss/lib/ckfw/capi/cfind.c b/nss/lib/ckfw/capi/cfind.c
index c17ed3c..9ea7fca 100644
--- a/nss/lib/ckfw/capi/cfind.c
+++ b/nss/lib/ckfw/capi/cfind.c
@@ -14,245 +14,234 @@
*/
struct ckcapiFOStr {
- NSSArena *arena;
- CK_ULONG n;
- CK_ULONG i;
- ckcapiInternalObject **objs;
+ 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
-)
+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;
+ 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
-)
+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;
+ struct ckcapiFOStr *fo = (struct ckcapiFOStr *)mdFindObjects->etc;
+ ckcapiInternalObject *io;
- if( fo->i == fo->n ) {
- *pError = CKR_OK;
- return (NSSCKMDObject *)NULL;
- }
+ if (fo->i == fo->n) {
+ *pError = CKR_OK;
+ return (NSSCKMDObject *)NULL;
+ }
- io = fo->objs[ fo->i ];
- fo->i++;
+ io = fo->objs[fo->i];
+ fo->i++;
- return nss_ckcapi_CreateMDObject(arena, io, pError);
+ return nss_ckcapi_CreateMDObject(arena, io, pError);
}
static CK_BBOOL
-ckcapi_attrmatch
-(
- CK_ATTRIBUTE_PTR a,
- ckcapiInternalObject *o
-)
+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;
- }
+ PRBool prb;
+ const NSSItem *b;
+
+ b = nss_ckcapi_FetchAttribute(o, a->type);
+ if (b == NULL) {
+ return CK_FALSE;
}
- return CK_FALSE;
- }
- prb = nsslibc_memequal(a->pValue, b->data, b->size, (PRStatus *)NULL);
+ 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;
+ }
- if( PR_TRUE == prb ) {
- return CK_TRUE;
- } else {
- 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
-)
+ckcapi_match(
+ CK_ATTRIBUTE_PTR pTemplate,
+ CK_ULONG ulAttributeCount,
+ ckcapiInternalObject *o)
{
- CK_ULONG i;
+ CK_ULONG i;
- for( i = 0; i < ulAttributeCount; i++ ) {
- if (CK_FALSE == ckcapi_attrmatch(&pTemplate[i], o)) {
- return CK_FALSE;
+ for (i = 0; i < ulAttributeCount; i++) {
+ if (CK_FALSE == ckcapi_attrmatch(&pTemplate[i], o)) {
+ return CK_FALSE;
+ }
}
- }
- /* Every attribute passed */
- return CK_TRUE;
+ /* 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++; \
- }
-
+#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;
+ 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
-)
+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;
+ 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;
}
- }
- if ((CRYPT_KEY_PROV_INFO *)NULL == keyProvInfo) {
+ PUT_Object(io, error);
+ bcp->size = size;
+ bcp->count = count;
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;
+ if (io) {
+ nss_ckcapi_DestroyInternalObject(io);
+ }
+ nss_ZFreeIf(idData);
+ return 1;
}
/*
@@ -260,30 +249,29 @@ loser:
*/
static PRUint32
collect_bare(
- CK_OBJECT_CLASS objClass,
- CK_ATTRIBUTE_PTR pTemplate,
- CK_ULONG ulAttributeCount,
- ckcapiInternalObject ***listp,
- PRUint32 *sizep,
- PRUint32 count,
- CK_RV *pError
-)
+ CK_OBJECT_CLASS objClass,
+ CK_ATTRIBUTE_PTR pTemplate,
+ CK_ULONG ulAttributeCount,
+ ckcapiInternalObject ***listp,
+ PRUint32 *sizep,
+ PRUint32 count,
+ CK_RV *pError)
{
- BOOL rc;
- BareCollectParams bareCollectParams;
+ BOOL rc;
+ BareCollectParams bareCollectParams;
- bareCollectParams.objClass = objClass;
- bareCollectParams.pTemplate = pTemplate;
- bareCollectParams.ulAttributeCount = ulAttributeCount;
- bareCollectParams.listp = listp;
- bareCollectParams.size = *sizep;
- bareCollectParams.count = count;
+ 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);
+ rc = CryptEnumKeyIdentifierProperties(NULL, CERT_KEY_PROV_INFO_PROP_ID, 0,
+ NULL, NULL, &bareCollectParams, doBareCollect);
- *sizep = bareCollectParams.size;
- return bareCollectParams.count;
+ *sizep = bareCollectParams.size;
+ return bareCollectParams.count;
}
/* find all the certs that represent the appropriate object (cert, priv key, or
@@ -291,291 +279,284 @@ collect_bare(
*/
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
-)
+ 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
+ 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;
- }
-
+ 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));
}
- }
- }
-
- 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;
+ 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
-)
+ 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,
+ 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;
+ 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,
+ckcapi_GetObjectClass(CK_ATTRIBUTE_PTR pTemplate,
CK_ULONG ulAttributeCount)
{
- CK_ULONG i;
+ CK_ULONG i;
- for (i=0; i < ulAttributeCount; i++)
- {
- if (pTemplate[i].type == CKA_CLASS) {
- return *(CK_OBJECT_CLASS *) pTemplate[i].pValue;
+ 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;
+ /* 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
-)
+ 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);
+ 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;
- }
+ /*
+ * 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;
+ return count;
loser:
- nss_ZFreeIf(*listp);
- return 0;
+ nss_ZFreeIf(*listp);
+ return 0;
}
-
-
NSS_IMPLEMENT NSSCKMDFindObjects *
-nss_ckcapi_FindObjectsInit
-(
- NSSCKFWSession *fwSession,
- CK_ATTRIBUTE_PTR pTemplate,
- CK_ULONG ulAttributeCount,
- CK_RV *pError
-)
+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;
-}
+ /* 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/nss/lib/ckfw/capi/cinst.c b/nss/lib/ckfw/capi/cinst.c
index 8aac1ca..937c289 100644
--- a/nss/lib/ckfw/capi/cinst.c
+++ b/nss/lib/ckfw/capi/cinst.c
@@ -7,7 +7,7 @@
/*
* ckcapi/cinstance.c
*
- * This file implements the NSSCKMDInstance object for the
+ * This file implements the NSSCKMDInstance object for the
* "capi" cryptoki module.
*/
@@ -16,96 +16,82 @@
*/
static CK_ULONG
-ckcapi_mdInstance_GetNSlots
-(
- NSSCKMDInstance *mdInstance,
- NSSCKFWInstance *fwInstance,
- CK_RV *pError
-)
+ckcapi_mdInstance_GetNSlots(
+ NSSCKMDInstance *mdInstance,
+ NSSCKFWInstance *fwInstance,
+ CK_RV *pError)
{
- return (CK_ULONG)1;
+ return (CK_ULONG)1;
}
static CK_VERSION
-ckcapi_mdInstance_GetCryptokiVersion
-(
- NSSCKMDInstance *mdInstance,
- NSSCKFWInstance *fwInstance
-)
+ckcapi_mdInstance_GetCryptokiVersion(
+ NSSCKMDInstance *mdInstance,
+ NSSCKFWInstance *fwInstance)
{
- return nss_ckcapi_CryptokiVersion;
+ return nss_ckcapi_CryptokiVersion;
}
static NSSUTF8 *
-ckcapi_mdInstance_GetManufacturerID
-(
- NSSCKMDInstance *mdInstance,
- NSSCKFWInstance *fwInstance,
- CK_RV *pError
-)
+ckcapi_mdInstance_GetManufacturerID(
+ NSSCKMDInstance *mdInstance,
+ NSSCKFWInstance *fwInstance,
+ CK_RV *pError)
{
- return (NSSUTF8 *)nss_ckcapi_ManufacturerID;
+ return (NSSUTF8 *)nss_ckcapi_ManufacturerID;
}
static NSSUTF8 *
-ckcapi_mdInstance_GetLibraryDescription
-(
- NSSCKMDInstance *mdInstance,
- NSSCKFWInstance *fwInstance,
- CK_RV *pError
-)
+ckcapi_mdInstance_GetLibraryDescription(
+ NSSCKMDInstance *mdInstance,
+ NSSCKFWInstance *fwInstance,
+ CK_RV *pError)
{
- return (NSSUTF8 *)nss_ckcapi_LibraryDescription;
+ return (NSSUTF8 *)nss_ckcapi_LibraryDescription;
}
static CK_VERSION
-ckcapi_mdInstance_GetLibraryVersion
-(
- NSSCKMDInstance *mdInstance,
- NSSCKFWInstance *fwInstance
-)
+ckcapi_mdInstance_GetLibraryVersion(
+ NSSCKMDInstance *mdInstance,
+ NSSCKFWInstance *fwInstance)
{
- return nss_ckcapi_LibraryVersion;
+ return nss_ckcapi_LibraryVersion;
}
static CK_RV
-ckcapi_mdInstance_GetSlots
-(
- NSSCKMDInstance *mdInstance,
- NSSCKFWInstance *fwInstance,
- NSSCKMDSlot *slots[]
-)
+ckcapi_mdInstance_GetSlots(
+ NSSCKMDInstance *mdInstance,
+ NSSCKFWInstance *fwInstance,
+ NSSCKMDSlot *slots[])
{
- slots[0] = (NSSCKMDSlot *)&nss_ckcapi_mdSlot;
- return CKR_OK;
+ slots[0] = (NSSCKMDSlot *)&nss_ckcapi_mdSlot;
+ return CKR_OK;
}
static CK_BBOOL
-ckcapi_mdInstance_ModuleHandlesSessionObjects
-(
- NSSCKMDInstance *mdInstance,
- NSSCKFWInstance *fwInstance
-)
+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;
+ /* 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 */
-};
+ 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/nss/lib/ckfw/capi/ckcapi.h b/nss/lib/ckfw/capi/ckcapi.h
index 2ae01e3..2c4b12a 100644
--- a/nss/lib/ckfw/capi/ckcapi.h
+++ b/nss/lib/ckfw/capi/ckcapi.h
@@ -31,28 +31,27 @@
* to this PKCS #11 module.
*/
struct ckcapiRawObjectStr {
- CK_ULONG n;
- const CK_ATTRIBUTE_TYPE *types;
- const NSSItem *items;
+ 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;
+ 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;
@@ -62,11 +61,11 @@ typedef struct ckcapiKeyParamsStr ckcapiKeyParams;
* while the CA is issuing the certificate.
*/
struct ckcapiKeyObjectStr {
- CRYPT_KEY_PROV_INFO provInfo;
- char *provName;
- char *containerName;
- HCRYPTPROV hProv;
- ckcapiKeyParams key;
+ CRYPT_KEY_PROV_INFO provInfo;
+ char *provName;
+ char *containerName;
+ HCRYPTPROV hProv;
+ ckcapiKeyParams key;
};
typedef struct ckcapiKeyObjectStr ckcapiKeyObject;
@@ -74,25 +73,25 @@ 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];
+ 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
+ ckcapiRaw,
+ ckcapiCert,
+ ckcapiBareKey
} ckcapiObjectType;
/*
@@ -100,98 +99,84 @@ typedef enum {
* 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;
+ 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 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_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
-);
+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_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_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_ckcapi_FetchAttribute(
+ ckcapiInternalObject *io,
+ CK_ATTRIBUTE_TYPE type);
NSS_EXTERN void
-nss_ckcapi_DestroyInternalObject
-(
- ckcapiInternalObject *io
-);
+nss_ckcapi_DestroyInternalObject(
+ ckcapiInternalObject *io);
NSS_EXTERN CK_RV
-nss_ckcapi_FetchKeyContainer
-(
- ckcapiInternalObject *iKey,
- HCRYPTPROV *hProv,
- DWORD *keySpec,
- HCRYPTKEY *hKey
-);
+nss_ckcapi_FetchKeyContainer(
+ ckcapiInternalObject *iKey,
+ HCRYPTPROV *hProv,
+ DWORD *keySpec,
+ HCRYPTKEY *hKey);
/*
* generic utilities
@@ -202,70 +187,56 @@ nss_ckcapi_FetchKeyContainer
* Microsoft, we need to byte swap everything coming into and out of CAPI.
*/
void
-ckcapi_ReverseData
-(
- NSSItem *item
-);
+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
-);
+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
-);
+int
+nss_ckcapi_WideSize(
+ LPCWSTR wide);
/*
* Covert a Unicode wide character string to a UTF8 string
*/
char *
-nss_ckcapi_WideToUTF8
-(
- LPCWSTR wide
-);
+nss_ckcapi_WideToUTF8(
+ LPCWSTR wide);
/*
* Return a Wide String duplicated with nss allocated memory.
*/
LPWSTR
-nss_ckcapi_WideDup
-(
- LPCWSTR wide
-);
+nss_ckcapi_WideDup(
+ LPCWSTR wide);
/*
* Covert a UTF8 string to Unicode wide character
*/
LPWSTR
-nss_ckcapi_UTF8ToWide
-(
- char *buf
-);
-
+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
-);
+ 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])))
-#define NSS_CKCAPI_ARRAY_SIZE(x) ((sizeof (x))/(sizeof ((x)[0])))
-
#endif
diff --git a/nss/lib/ckfw/capi/ckcapiver.c b/nss/lib/ckfw/capi/ckcapiver.c
index 54e4887..825b630 100644
--- a/nss/lib/ckfw/capi/ckcapiver.c
+++ b/nss/lib/ckfw/capi/ckcapiver.c
@@ -14,5 +14,4 @@
/*
* Version information
*/
-const char __nss_ckcapi_version[] = "Version: NSS Access to Microsoft Certificate Store "
- NSS_CKCAPI_LIBRARY_VERSION _DEBUG_STRING;
+const char __nss_ckcapi_version[] = "Version: NSS Access to Microsoft Certificate Store " NSS_CKCAPI_LIBRARY_VERSION _DEBUG_STRING;
diff --git a/nss/lib/ckfw/capi/cobject.c b/nss/lib/ckfw/capi/cobject.c
index 1da5f7d..c4b77d2 100644
--- a/nss/lib/ckfw/capi/cobject.c
+++ b/nss/lib/ckfw/capi/cobject.c
@@ -76,22 +76,30 @@ 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_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) };
+ (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};
+ (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.
@@ -101,117 +109,111 @@ static const NSSItem ckcapi_emptyItem = {
* unwrap a single DER value
*/
unsigned char *
-nss_ckcapi_DERUnwrap
-(
- unsigned char *src,
- unsigned int size,
- unsigned int *outSize,
- unsigned char **next
-)
+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;
+ 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
+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;
+ 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
-)
+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;
+ unsigned long count = 0;
+ unsigned long i;
+#define SHIFT ((sizeof(CK_ULONG) - 1) * 8)
+ PRBool first = 0;
- *pError = CKR_OK;
+ *pError = CKR_OK;
- data->data = dataPtr;
- for (i=0; i < sizeof(CK_ULONG); i++) {
- unsigned char digit = (unsigned char)((value >> SHIFT) & 0xff);
+ data->data = dataPtr;
+ for (i = 0; i < sizeof(CK_ULONG); i++) {
+ unsigned char digit = (unsigned char)((value >> SHIFT) & 0xff);
- value = value << 8;
+ value = value << 8;
- /* drop leading zero bytes */
- if (first && (0 == digit)) {
- continue;
+ /* drop leading zero bytes */
+ if (first && (0 == digit)) {
+ continue;
+ }
+ *dataPtr++ = digit;
+ count++;
}
- *dataPtr++ = digit;
- count++;
- }
- data->size = count;
- return count;
+ data->size = count;
+ return count;
}
/*
@@ -219,107 +221,99 @@ nss_ckcapi_IntToData
* 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
-)
+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;
+ 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;
+ 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
-)
+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;
+ 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
-)
+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;
+ 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
-)
+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;
+ 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;
}
/*
@@ -327,104 +321,95 @@ nss_ckcapi_GetStringAttribute
* character
*/
int
-nss_ckcapi_WideSize
-(
- LPCWSTR wide
-)
+nss_ckcapi_WideSize(
+ LPCWSTR wide)
{
- DWORD size;
+ DWORD size;
- if ((LPWSTR)NULL == wide) {
- return 0;
- }
- size = wcslen(wide)+1;
- return size*sizeof(WCHAR);
+ 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
-)
+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;
+ 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
-)
+nss_ckcapi_WideDup(
+ LPCWSTR wide)
{
- DWORD len;
- LPWSTR buf;
+ DWORD len;
+ LPWSTR buf;
- if ((LPWSTR)NULL == wide) {
- return (LPWSTR)NULL;
- }
+ if ((LPWSTR)NULL == wide) {
+ return (LPWSTR)NULL;
+ }
- len = wcslen(wide)+1;
+ len = wcslen(wide) + 1;
- buf = nss_ZNEWARRAY(NULL, WCHAR, len);
- if ((LPWSTR) NULL == buf) {
+ buf = nss_ZNEWARRAY(NULL, WCHAR, len);
+ if ((LPWSTR)NULL == buf) {
+ return buf;
+ }
+ nsslibc_memcpy(buf, wide, len * sizeof(WCHAR));
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
-)
+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;
-}
+ 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
@@ -436,281 +421,272 @@ nss_ckcapi_UTF8ToWide
* this function fails with CKR_KEY_TYPE_INCONSISTENT
*/
NSS_EXTERN CK_RV
-nss_ckcapi_FetchKeyContainer
-(
- ckcapiInternalObject *iKey,
- HCRYPTPROV *hProv,
- DWORD *keySpec,
- HCRYPTKEY *hKey
-)
+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);
+ 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;
- }
- 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;
+ }
+ 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;
+ /* 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
-)
+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;
+ 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];
+ 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_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)
+#define CAPI_PRIVATE_EXP_OFFSET(modSize) ((modSize)*3 + (modSize) / 2)
void
-ckcapi_FetchPublicKey
-(
- ckcapiInternalObject *io
-)
+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);
+ 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;
+ nss_ZFreeIf(buf);
+ if (0 != hKey) {
+ CryptDestroyKey(hKey);
+ }
+ return;
}
void
-ckcapi_FetchPrivateKey
-(
- ckcapiInternalObject *io
-)
+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);
+ 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;
+ nss_ZFreeIf(buf);
+ if (0 != hKey) {
+ CryptDestroyKey(hKey);
+ }
+ return;
}
-
void
-ckcapi_PopulateModulusExponent
-(
- ckcapiInternalObject *io
-)
+ckcapi_PopulateModulusExponent(
+ ckcapiInternalObject *io)
{
- if (ckcapiCert == io->type) {
- ckcapi_CertPopulateModulusExponent(io);
- } else {
- ckcapi_FetchPublicKey(io);
- }
- return;
+ if (ckcapiCert == io->type) {
+ ckcapi_CertPopulateModulusExponent(io);
+ } else {
+ ckcapi_FetchPublicKey(io);
+ }
+ return;
}
/*
@@ -718,442 +694,433 @@ ckcapi_PopulateModulusExponent
* can only be called with ckcapiCert type objects!
*/
void
-ckcapi_FetchLabel
-(
- ckcapiInternalObject *io
-)
+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();
+ 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;
+ 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
-)
+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;
+ 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
-)
+ckcapi_FetchID(
+ ckcapiInternalObject *io)
{
- PCCERT_CONTEXT certContext = io->u.cert.certContext;
- DWORD size = 0;
- BOOL rc;
+ 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, 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;
+ 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;
- }
- io->id.data = io->idData;
- io->id.size = size;
- return;
}
/*
* fetch the hash key.
*/
void
-ckcapi_CertFetchHashKey
-(
- ckcapiInternalObject *io
-)
+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;
+ 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
-)
+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;
+ 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
-)
+ckcapi_FetchHashKey(
+ ckcapiInternalObject *io)
{
- if (ckcapiCert == io->type) {
- ckcapi_CertFetchHashKey(io);
- } else {
- ckcapi_KeyFetchHashKey(io);
- }
- return;
+ if (ckcapiCert == io->type) {
+ ckcapi_CertFetchHashKey(io);
+ } else {
+ ckcapi_KeyFetchHashKey(io);
+ }
+ return;
}
-
+
const NSSItem *
-ckcapi_FetchCertAttribute
-(
- ckcapiInternalObject *io,
- CK_ATTRIBUTE_TYPE type
-)
+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;
+ 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
-)
+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;
+ 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
-)
+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;
- }
+ 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
-)
+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];
- }
+ 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;
- }
- /* 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;
}
/*
@@ -1161,173 +1128,160 @@ nss_ckcapi_FetchAttribute
*/
static PRBool
ckcapi_cert_exists(
- NSSItem *value,
- ckcapiInternalObject **io
-)
+ 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;
+ 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
-)
+ckcapi_cert_hasEmail(
+ PCCERT_CONTEXT certContext)
{
- int count;
+ int count;
- count = CertGetNameString(certContext, CERT_NAME_EMAIL_TYPE,
- 0, NULL, NULL, 0);
+ count = CertGetNameString(certContext, CERT_NAME_EMAIL_TYPE,
+ 0, NULL, NULL, 0);
- return count > 1 ? PR_TRUE : PR_FALSE;
+ return count > 1 ? PR_TRUE : PR_FALSE;
}
static PRBool
-ckcapi_cert_isRoot
-(
- PCCERT_CONTEXT certContext
-)
+ckcapi_cert_isRoot(
+ PCCERT_CONTEXT certContext)
{
- return CertCompareCertificateName(certContext->dwCertEncodingType,
- &certContext->pCertInfo->Issuer, &certContext->pCertInfo->Subject);
+ return CertCompareCertificateName(certContext->dwCertEncodingType,
+ &certContext->pCertInfo->Issuer, &certContext->pCertInfo->Subject);
}
static PRBool
-ckcapi_cert_isCA
-(
- PCCERT_CONTEXT certContext
-)
+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;
+ 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
-)
+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;
+ 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
-)
+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;
+ 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
-);
+ckcapi_removeObjectFromHash(
+ ckcapiInternalObject *io);
/*
* Finalize - unneeded
- * Destroy
+ * Destroy
* IsTokenObject - CK_TRUE
* GetAttributeCount
* GetAttributeTypes
@@ -1338,968 +1292,935 @@ ckcapi_removeObjectFromHash
*/
static CK_RV
-ckcapi_mdObject_Destroy
-(
- NSSCKMDObject *mdObject,
- NSSCKFWObject *fwObject,
- NSSCKMDSession *mdSession,
- NSSCKFWSession *fwSession,
- NSSCKMDToken *mdToken,
- NSSCKFWToken *fwToken,
- NSSCKMDInstance *mdInstance,
- NSSCKFWInstance *fwInstance
-)
+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);
+ 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;
}
- 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);
+ 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 {
- 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);
+ 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);
}
- nss_ZFreeIf(provName);
- nss_ZFreeIf(containerName);
- }
loser:
- if (hStore) {
- CertCloseStore(hStore, 0);
- }
- if (!rc) {
- msError = GetLastError();
- return CKR_GENERAL_ERROR;
- }
+ if (hStore) {
+ CertCloseStore(hStore, 0);
+ }
+ if (!rc) {
+ msError = GetLastError();
+ return CKR_GENERAL_ERROR;
+ }
- /* remove it from the hash */
- ckcapi_removeObjectFromHash(io);
+ /* remove it from the hash */
+ ckcapi_removeObjectFromHash(io);
- /* free the puppy.. */
- nss_ckcapi_DestroyInternalObject(io);
- return CKR_OK;
+ /* 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
-)
+ckcapi_mdObject_IsTokenObject(
+ NSSCKMDObject *mdObject,
+ NSSCKFWObject *fwObject,
+ NSSCKMDSession *mdSession,
+ NSSCKFWSession *fwSession,
+ NSSCKMDToken *mdToken,
+ NSSCKFWToken *fwToken,
+ NSSCKMDInstance *mdInstance,
+ NSSCKFWInstance *fwInstance)
{
- return CK_TRUE;
+ 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
-)
+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;
+ 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
-)
+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;
+ 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
-)
+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;
+ ckcapiInternalObject *io = (ckcapiInternalObject *)mdObject->etc;
- const NSSItem *b;
+ const NSSItem *b;
- b = nss_ckcapi_FetchAttribute(io, attribute);
+ b = nss_ckcapi_FetchAttribute(io, attribute);
- if ((const NSSItem *)NULL == b) {
- *pError = CKR_ATTRIBUTE_TYPE_INVALID;
- return 0;
- }
- return b->size;
+ 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
-)
+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;
+ 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
-)
+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;
+ NSSCKFWItem mdItem;
+ ckcapiInternalObject *io = (ckcapiInternalObject *)mdObject->etc;
- mdItem.needsFreeing = PR_FALSE;
- mdItem.item = (NSSItem*)nss_ckcapi_FetchAttribute(io, attribute);
+ mdItem.needsFreeing = PR_FALSE;
+ mdItem.item = (NSSItem *)nss_ckcapi_FetchAttribute(io, attribute);
- if ((NSSItem *)NULL == mdItem.item) {
- *pError = CKR_ATTRIBUTE_TYPE_INVALID;
- }
+ if ((NSSItem *)NULL == mdItem.item) {
+ *pError = CKR_ATTRIBUTE_TYPE_INVALID;
+ }
- return mdItem;
+ 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
-)
+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;
+ ckcapiInternalObject *io = (ckcapiInternalObject *)mdObject->etc;
+ CK_ULONG rv = 1;
- /* size is irrelevant to this token */
- return rv;
+ /* 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 */
-};
+ 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
-)
+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 ((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 (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;
+ 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
-)
+ckcapi_removeObjectFromHash(
+ ckcapiInternalObject *io)
{
- NSSItem *key = &io->hashKey;
+ NSSItem *key = &io->hashKey;
- if ((nssHash *)NULL == ckcapiInternalObjectHash) {
+ if ((nssHash *)NULL == ckcapiInternalObjectHash) {
+ return;
+ }
+ if (key->size == 0) {
+ ckcapi_FetchHashKey(io);
+ }
+ nssHash_Remove(ckcapiInternalObjectHash, key);
return;
- }
- if (key->size == 0) {
- ckcapi_FetchHashKey(io);
- }
- nssHash_Remove(ckcapiInternalObjectHash, key);
- return;
}
void
-nss_ckcapi_DestroyInternalObject
-(
- ckcapiInternalObject *io
-)
+nss_ckcapi_DestroyInternalObject(
+ ckcapiInternalObject *io)
{
- switch (io->type) {
- case ckcapiRaw:
+ 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;
- 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
-)
+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;
- }
+ 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);
+ *pError = nss_ckcapi_GetAttribute(CKA_ID, pTemplate,
+ ulAttributeCount, &keyID);
- if (CKR_OK != *pError) {
- return (ckcapiInternalObject *)NULL;
- }
+ if (CKR_OK != *pError) {
+ return (ckcapiInternalObject *)NULL;
+ }
- if (ckcapi_cert_exists(&value, &io)) {
- return io;
- }
+ if (ckcapi_cert_exists(&value, &io)) {
+ return io;
+ }
- /* OK, we are creating a new one, figure out what store it belongs to..
+ /* 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;
+ certContext = CertCreateCertificateContext(X509_ASN_ENCODING,
+ value.data, value.size);
+ if ((PCCERT_CONTEXT)NULL == certContext) {
+ msError = GetLastError();
+ *pError = CKR_ATTRIBUTE_VALUE_INVALID;
+ 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;
+
+ /* 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";
}
- }
- 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;
+ /* 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;
+ }
+ }
-loser:
- if (certContext) {
+ 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;
- }
- if (storedCertContext) {
- CertFreeCertificateContext(storedCertContext);
- storedCertContext = NULL;
- }
- if (0 != hStore) {
CertCloseStore(hStore, 0);
- }
- return (ckcapiInternalObject *)NULL;
+ 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
-)
+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;
+ 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
-)
+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;
+ 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
-)
+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;
+ 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;
+ nss_ZFreeIf(keyBlobData);
+ return error;
}
static ckcapiInternalObject *
-nss_ckcapi_CreatePrivateKey
-(
- NSSCKFWSession *fwSession,
- CK_ATTRIBUTE_PTR pTemplate,
- CK_ULONG ulAttributeCount,
- CK_RV *pError
-)
+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 == containerName) {
- 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;
+ 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;
+ }
-loser:
- nss_ZFreeIf(containerName);
- nss_ZFreeIf(providerName);
- nss_ZFreeIf(idData);
- if (0 != hProv) {
- CryptReleaseContext(hProv, 0);
- }
- if (0 != hKey) {
+ 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 == containerName) {
+ 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 (ckcapiInternalObject *)NULL;
-}
+ 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
-)
+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;
- }
+ 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 */
- }
+ 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);
+ 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/nss/lib/ckfw/capi/constants.c b/nss/lib/ckfw/capi/constants.c
index 9b919aa..0d4b701 100644
--- a/nss/lib/ckfw/capi/constants.c
+++ b/nss/lib/ckfw/capi/constants.c
@@ -21,40 +21,43 @@
#endif /* NSSCAPI_H */
NSS_IMPLEMENT_DATA const CK_VERSION
-nss_ckcapi_CryptokiVersion = {
- NSS_CKCAPI_CRYPTOKI_VERSION_MAJOR,
- NSS_CKCAPI_CRYPTOKI_VERSION_MINOR };
+ 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_ckcapi_ManufacturerID = (NSSUTF8 *)"Mozilla Foundation";
NSS_IMPLEMENT_DATA const NSSUTF8 *
-nss_ckcapi_LibraryDescription = (NSSUTF8 *) "NSS Access to Microsoft Certificate Store";
+ 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_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_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_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_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_ckcapi_TokenLabel = (NSSUTF8 *)"Microsoft Certificate Store";
NSS_IMPLEMENT_DATA const NSSUTF8 *
-nss_ckcapi_TokenModel = (NSSUTF8 *) "1";
+ nss_ckcapi_TokenModel = (NSSUTF8 *)"1";
NSS_IMPLEMENT_DATA const NSSUTF8 *
-nss_ckcapi_TokenSerialNumber = (NSSUTF8 *) "1";
-
+ nss_ckcapi_TokenSerialNumber = (NSSUTF8 *)"1";
diff --git a/nss/lib/ckfw/capi/crsa.c b/nss/lib/ckfw/capi/crsa.c
index 9acc7e7..62f90ac 100644
--- a/nss/lib/ckfw/capi/crsa.c
+++ b/nss/lib/ckfw/capi/crsa.c
@@ -5,7 +5,7 @@
#include "ckcapi.h"
#include "secdert.h"
-#define SSL3_SHAMD5_HASH_SIZE 36 /* LEN_MD5 (16) + LEN_SHA1 (20) */
+#define SSL3_SHAMD5_HASH_SIZE 36 /* LEN_MD5 (16) + LEN_SHA1 (20) */
/*
* ckcapi/crsa.c
@@ -21,115 +21,109 @@
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;
-}
+ 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
-)
+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;
-}
+ 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
+ * 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
-)
+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;
- /*
+ 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
@@ -138,73 +132,73 @@ ckcapi_GetRawHash
* 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;
- }
+ 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;
- }
+ /* 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;
+ /* hash looks reasonably consistent, we should be able to sign it now */
+ return CKR_OK;
}
/*
@@ -214,133 +208,125 @@ ckcapi_GetRawHash
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;
+ 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;
+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
-)
+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;
+ 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
-)
+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;
+ 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
-)
+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);
+ ckcapiInternalCryptoOperationRSAPriv *iOperation =
+ (ckcapiInternalCryptoOperationRSAPriv *)mdOperation->etc;
+ const NSSItem *modulus =
+ nss_ckcapi_FetchAttribute(iOperation->iKey, CKA_MODULUS);
- return modulus->size;
+ return modulus->size;
}
-
/*
* ckcapi_mdCryptoOperationRSADecrypt_GetOperationLength
* we won't know the length until we actually decrypt the
@@ -348,86 +334,85 @@ ckcapi_mdCryptoOperationRSA_GetFinalLength
* 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
-)
+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;
+ 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
+ * 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
-)
+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;
+ 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;
}
/*
@@ -435,277 +420,268 @@ ckcapi_mdCryptoOperationRSADecrypt_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
-)
+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;
+ 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;
+ }
-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) {
+ 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 error;
+ 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 */
-};
+ 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 */
-};
+ 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
-)
+ckcapi_mdMechanismRSA_Destroy(
+ NSSCKMDMechanism *mdMechanism,
+ NSSCKFWMechanism *fwMechanism,
+ NSSCKMDInstance *mdInstance,
+ NSSCKFWInstance *fwInstance)
{
- nss_ZFreeIf(fwMechanism);
+ 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
-)
+ckcapi_mdMechanismRSA_GetMinKeySize(
+ NSSCKMDMechanism *mdMechanism,
+ NSSCKFWMechanism *fwMechanism,
+ NSSCKMDToken *mdToken,
+ NSSCKFWToken *fwToken,
+ NSSCKMDInstance *mdInstance,
+ NSSCKFWInstance *fwInstance,
+ CK_RV *pError)
{
- return 384;
+ 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
-)
+ckcapi_mdMechanismRSA_GetMaxKeySize(
+ NSSCKMDMechanism *mdMechanism,
+ NSSCKFWMechanism *fwMechanism,
+ NSSCKMDToken *mdToken,
+ NSSCKFWToken *fwToken,
+ NSSCKMDInstance *mdInstance,
+ NSSCKFWInstance *fwInstance,
+ CK_RV *pError)
{
- return 16384;
+ 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
-)
+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);
+ 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
-)
+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);
+ 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 */
-};
+ 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/nss/lib/ckfw/capi/csession.c b/nss/lib/ckfw/capi/csession.c
index 4c25354..5b268ea 100644
--- a/nss/lib/ckfw/capi/csession.c
+++ b/nss/lib/ckfw/capi/csession.c
@@ -7,87 +7,81 @@
/*
* ckcapi/csession.c
*
- * This file implements the NSSCKMDSession object for the
+ * 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
-)
+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);
+ 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
-)
+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);
+ return nss_ckcapi_CreateObject(fwSession, pTemplate, ulAttributeCount, pError);
}
NSS_IMPLEMENT NSSCKMDSession *
-nss_ckcapi_CreateSession
-(
- NSSCKFWSession *fwSession,
- CK_RV *pError
-)
+nss_ckcapi_CreateSession(
+ NSSCKFWSession *fwSession,
+ CK_RV *pError)
{
- NSSArena *arena;
- NSSCKMDSession *rv;
+ NSSArena *arena;
+ NSSCKMDSession *rv;
- arena = NSSCKFWSession_GetArena(fwSession, pError);
- if( (NSSArena *)NULL == arena ) {
- return (NSSCKMDSession *)NULL;
- }
+ 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 = 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 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 */
+ 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;
+ return rv;
}
diff --git a/nss/lib/ckfw/capi/cslot.c b/nss/lib/ckfw/capi/cslot.c
index 779161f..8a39b78 100644
--- a/nss/lib/ckfw/capi/cslot.c
+++ b/nss/lib/ckfw/capi/cslot.c
@@ -12,80 +12,70 @@
*/
static NSSUTF8 *
-ckcapi_mdSlot_GetSlotDescription
-(
- NSSCKMDSlot *mdSlot,
- NSSCKFWSlot *fwSlot,
- NSSCKMDInstance *mdInstance,
- NSSCKFWInstance *fwInstance,
- CK_RV *pError
-)
+ckcapi_mdSlot_GetSlotDescription(
+ NSSCKMDSlot *mdSlot,
+ NSSCKFWSlot *fwSlot,
+ NSSCKMDInstance *mdInstance,
+ NSSCKFWInstance *fwInstance,
+ CK_RV *pError)
{
- return (NSSUTF8 *)nss_ckcapi_SlotDescription;
+ return (NSSUTF8 *)nss_ckcapi_SlotDescription;
}
static NSSUTF8 *
-ckcapi_mdSlot_GetManufacturerID
-(
- NSSCKMDSlot *mdSlot,
- NSSCKFWSlot *fwSlot,
- NSSCKMDInstance *mdInstance,
- NSSCKFWInstance *fwInstance,
- CK_RV *pError
-)
+ckcapi_mdSlot_GetManufacturerID(
+ NSSCKMDSlot *mdSlot,
+ NSSCKFWSlot *fwSlot,
+ NSSCKMDInstance *mdInstance,
+ NSSCKFWInstance *fwInstance,
+ CK_RV *pError)
{
- return (NSSUTF8 *)nss_ckcapi_ManufacturerID;
+ return (NSSUTF8 *)nss_ckcapi_ManufacturerID;
}
static CK_VERSION
-ckcapi_mdSlot_GetHardwareVersion
-(
- NSSCKMDSlot *mdSlot,
- NSSCKFWSlot *fwSlot,
- NSSCKMDInstance *mdInstance,
- NSSCKFWInstance *fwInstance
-)
+ckcapi_mdSlot_GetHardwareVersion(
+ NSSCKMDSlot *mdSlot,
+ NSSCKFWSlot *fwSlot,
+ NSSCKMDInstance *mdInstance,
+ NSSCKFWInstance *fwInstance)
{
- return nss_ckcapi_HardwareVersion;
+ return nss_ckcapi_HardwareVersion;
}
static CK_VERSION
-ckcapi_mdSlot_GetFirmwareVersion
-(
- NSSCKMDSlot *mdSlot,
- NSSCKFWSlot *fwSlot,
- NSSCKMDInstance *mdInstance,
- NSSCKFWInstance *fwInstance
-)
+ckcapi_mdSlot_GetFirmwareVersion(
+ NSSCKMDSlot *mdSlot,
+ NSSCKFWSlot *fwSlot,
+ NSSCKMDInstance *mdInstance,
+ NSSCKFWInstance *fwInstance)
{
- return nss_ckcapi_FirmwareVersion;
+ return nss_ckcapi_FirmwareVersion;
}
static NSSCKMDToken *
-ckcapi_mdSlot_GetToken
-(
- NSSCKMDSlot *mdSlot,
- NSSCKFWSlot *fwSlot,
- NSSCKMDInstance *mdInstance,
- NSSCKFWInstance *fwInstance,
- CK_RV *pError
-)
+ckcapi_mdSlot_GetToken(
+ NSSCKMDSlot *mdSlot,
+ NSSCKFWSlot *fwSlot,
+ NSSCKMDInstance *mdInstance,
+ NSSCKFWInstance *fwInstance,
+ CK_RV *pError)
{
- return (NSSCKMDToken *)&nss_ckcapi_mdToken;
+ 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 */
-};
+ 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/nss/lib/ckfw/capi/ctoken.c b/nss/lib/ckfw/capi/ctoken.c
index 7f0e633..cc95c17 100644
--- a/nss/lib/ckfw/capi/ctoken.c
+++ b/nss/lib/ckfw/capi/ctoken.c
@@ -12,197 +12,173 @@
*/
static NSSUTF8 *
-ckcapi_mdToken_GetLabel
-(
- NSSCKMDToken *mdToken,
- NSSCKFWToken *fwToken,
- NSSCKMDInstance *mdInstance,
- NSSCKFWInstance *fwInstance,
- CK_RV *pError
-)
+ckcapi_mdToken_GetLabel(
+ NSSCKMDToken *mdToken,
+ NSSCKFWToken *fwToken,
+ NSSCKMDInstance *mdInstance,
+ NSSCKFWInstance *fwInstance,
+ CK_RV *pError)
{
- return (NSSUTF8 *)nss_ckcapi_TokenLabel;
+ return (NSSUTF8 *)nss_ckcapi_TokenLabel;
}
static NSSUTF8 *
-ckcapi_mdToken_GetManufacturerID
-(
- NSSCKMDToken *mdToken,
- NSSCKFWToken *fwToken,
- NSSCKMDInstance *mdInstance,
- NSSCKFWInstance *fwInstance,
- CK_RV *pError
-)
+ckcapi_mdToken_GetManufacturerID(
+ NSSCKMDToken *mdToken,
+ NSSCKFWToken *fwToken,
+ NSSCKMDInstance *mdInstance,
+ NSSCKFWInstance *fwInstance,
+ CK_RV *pError)
{
- return (NSSUTF8 *)nss_ckcapi_ManufacturerID;
+ return (NSSUTF8 *)nss_ckcapi_ManufacturerID;
}
static NSSUTF8 *
-ckcapi_mdToken_GetModel
-(
- NSSCKMDToken *mdToken,
- NSSCKFWToken *fwToken,
- NSSCKMDInstance *mdInstance,
- NSSCKFWInstance *fwInstance,
- CK_RV *pError
-)
+ckcapi_mdToken_GetModel(
+ NSSCKMDToken *mdToken,
+ NSSCKFWToken *fwToken,
+ NSSCKMDInstance *mdInstance,
+ NSSCKFWInstance *fwInstance,
+ CK_RV *pError)
{
- return (NSSUTF8 *)nss_ckcapi_TokenModel;
+ return (NSSUTF8 *)nss_ckcapi_TokenModel;
}
static NSSUTF8 *
-ckcapi_mdToken_GetSerialNumber
-(
- NSSCKMDToken *mdToken,
- NSSCKFWToken *fwToken,
- NSSCKMDInstance *mdInstance,
- NSSCKFWInstance *fwInstance,
- CK_RV *pError
-)
+ckcapi_mdToken_GetSerialNumber(
+ NSSCKMDToken *mdToken,
+ NSSCKFWToken *fwToken,
+ NSSCKMDInstance *mdInstance,
+ NSSCKFWInstance *fwInstance,
+ CK_RV *pError)
{
- return (NSSUTF8 *)nss_ckcapi_TokenSerialNumber;
+ return (NSSUTF8 *)nss_ckcapi_TokenSerialNumber;
}
static CK_BBOOL
-ckcapi_mdToken_GetIsWriteProtected
-(
- NSSCKMDToken *mdToken,
- NSSCKFWToken *fwToken,
- NSSCKMDInstance *mdInstance,
- NSSCKFWInstance *fwInstance
-)
+ckcapi_mdToken_GetIsWriteProtected(
+ NSSCKMDToken *mdToken,
+ NSSCKFWToken *fwToken,
+ NSSCKMDInstance *mdInstance,
+ NSSCKFWInstance *fwInstance)
{
- return CK_FALSE;
+ 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
-)
+ckcapi_mdToken_GetUserPinInitialized(
+ NSSCKMDToken *mdToken,
+ NSSCKFWToken *fwToken,
+ NSSCKMDInstance *mdInstance,
+ NSSCKFWInstance *fwInstance)
{
- return CK_TRUE;
+ return CK_TRUE;
}
static CK_VERSION
-ckcapi_mdToken_GetHardwareVersion
-(
- NSSCKMDToken *mdToken,
- NSSCKFWToken *fwToken,
- NSSCKMDInstance *mdInstance,
- NSSCKFWInstance *fwInstance
-)
+ckcapi_mdToken_GetHardwareVersion(
+ NSSCKMDToken *mdToken,
+ NSSCKFWToken *fwToken,
+ NSSCKMDInstance *mdInstance,
+ NSSCKFWInstance *fwInstance)
{
- return nss_ckcapi_HardwareVersion;
+ return nss_ckcapi_HardwareVersion;
}
static CK_VERSION
-ckcapi_mdToken_GetFirmwareVersion
-(
- NSSCKMDToken *mdToken,
- NSSCKFWToken *fwToken,
- NSSCKMDInstance *mdInstance,
- NSSCKFWInstance *fwInstance
-)
+ckcapi_mdToken_GetFirmwareVersion(
+ NSSCKMDToken *mdToken,
+ NSSCKFWToken *fwToken,
+ NSSCKMDInstance *mdInstance,
+ NSSCKFWInstance *fwInstance)
{
- return nss_ckcapi_FirmwareVersion;
+ 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
-)
+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);
+ return nss_ckcapi_CreateSession(fwSession, pError);
}
static CK_ULONG
-ckcapi_mdToken_GetMechanismCount
-(
- NSSCKMDToken *mdToken,
- NSSCKFWToken *fwToken,
- NSSCKMDInstance *mdInstance,
- NSSCKFWInstance *fwInstance
-)
+ckcapi_mdToken_GetMechanismCount(
+ NSSCKMDToken *mdToken,
+ NSSCKFWToken *fwToken,
+ NSSCKMDInstance *mdInstance,
+ NSSCKFWInstance *fwInstance)
{
- return (CK_ULONG)1;
+ return (CK_ULONG)1;
}
static CK_RV
-ckcapi_mdToken_GetMechanismTypes
-(
- NSSCKMDToken *mdToken,
- NSSCKFWToken *fwToken,
- NSSCKMDInstance *mdInstance,
- NSSCKFWInstance *fwInstance,
- CK_MECHANISM_TYPE types[]
-)
+ckcapi_mdToken_GetMechanismTypes(
+ NSSCKMDToken *mdToken,
+ NSSCKFWToken *fwToken,
+ NSSCKMDInstance *mdInstance,
+ NSSCKFWInstance *fwInstance,
+ CK_MECHANISM_TYPE types[])
{
- types[0] = CKM_RSA_PKCS;
- return CKR_OK;
+ 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
-)
+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;
+ 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 */
-};
+ 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/nss/lib/ckfw/capi/nsscapi.h b/nss/lib/ckfw/capi/nsscapi.h
index d983120..78bf38b 100644
--- a/nss/lib/ckfw/capi/nsscapi.h
+++ b/nss/lib/ckfw/capi/nsscapi.h
@@ -18,7 +18,7 @@
#define NSS_CKCAPI_CRYPTOKI_VERSION_MAJOR 2
#define NSS_CKCAPI_CRYPTOKI_VERSION_MINOR 20
-/* These version numbers detail the changes
+/* 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
@@ -33,7 +33,7 @@
#define NSS_CKCAPI_HARDWARE_VERSION_MAJOR 1
#define NSS_CKCAPI_HARDWARE_VERSION_MINOR 0
-/* These version numbers detail the semantic changes to ckbi itself
+/* 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
diff --git a/nss/lib/ckfw/capi/staticobj.c b/nss/lib/ckfw/capi/staticobj.c
index c14c812..2d67a34 100644
--- a/nss/lib/ckfw/capi/staticobj.c
+++ b/nss/lib/ckfw/capi/staticobj.c
@@ -17,22 +17,23 @@ 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 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 }
+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} ,
- },
+ {
+ ckcapiRaw,
+ { 5, nss_ckcapi_types_1, nss_ckcapi_items_1 },
+ },
};
diff --git a/nss/lib/ckfw/ckfw.gyp b/nss/lib/ckfw/ckfw.gyp
new file mode 100644
index 0000000..40da8d8
--- /dev/null
+++ b/nss/lib/ckfw/ckfw.gyp
@@ -0,0 +1,34 @@
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+{
+ 'includes': [
+ '../../coreconf/config.gypi'
+ ],
+ 'targets': [
+ {
+ 'target_name': 'nssckfw',
+ 'type': 'static_library',
+ 'sources': [
+ 'crypto.c',
+ 'find.c',
+ 'hash.c',
+ 'instance.c',
+ 'mechanism.c',
+ 'mutex.c',
+ 'object.c',
+ 'session.c',
+ 'sessobj.c',
+ 'slot.c',
+ 'token.c',
+ 'wrap.c'
+ ],
+ 'dependencies': [
+ '<(DEPTH)/exports.gyp:nss_exports'
+ ]
+ }
+ ],
+ 'variables': {
+ 'module': 'nss'
+ }
+} \ No newline at end of file
diff --git a/nss/lib/ckfw/ckfw.h b/nss/lib/ckfw/ckfw.h
index e5d2e1b..d4a2ead 100644
--- a/nss/lib/ckfw/ckfw.h
+++ b/nss/lib/ckfw/ckfw.h
@@ -40,7 +40,7 @@
* nssCKFWInstance_MayCreatePthreads
* nssCKFWInstance_CreateMutex
* nssCKFWInstance_GetConfigurationData
- * nssCKFWInstance_GetInitArgs
+ * nssCKFWInstance_GetInitArgs
*
* -- private accessors --
* nssCKFWInstance_CreateSessionHandle
@@ -72,295 +72,240 @@
*
*/
NSS_EXTERN NSSCKFWInstance *
-nssCKFWInstance_Create
-(
- CK_C_INITIALIZE_ARGS_PTR pInitArgs,
- CryptokiLockingState LockingState,
- NSSCKMDInstance *mdInstance,
- CK_RV *pError
-);
+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_Destroy(
+ NSSCKFWInstance *fwInstance);
/*
* nssCKFWInstance_GetMDInstance
*
*/
NSS_EXTERN NSSCKMDInstance *
-nssCKFWInstance_GetMDInstance
-(
- NSSCKFWInstance *fwInstance
-);
+nssCKFWInstance_GetMDInstance(
+ NSSCKFWInstance *fwInstance);
/*
* nssCKFWInstance_GetArena
*
*/
NSS_EXTERN NSSArena *
-nssCKFWInstance_GetArena
-(
- NSSCKFWInstance *fwInstance,
- CK_RV *pError
-);
+nssCKFWInstance_GetArena(
+ NSSCKFWInstance *fwInstance,
+ CK_RV *pError);
/*
* nssCKFWInstance_MayCreatePthreads
*
*/
NSS_EXTERN CK_BBOOL
-nssCKFWInstance_MayCreatePthreads
-(
- NSSCKFWInstance *fwInstance
-);
+nssCKFWInstance_MayCreatePthreads(
+ NSSCKFWInstance *fwInstance);
/*
* nssCKFWInstance_CreateMutex
*
*/
NSS_EXTERN NSSCKFWMutex *
-nssCKFWInstance_CreateMutex
-(
- NSSCKFWInstance *fwInstance,
- NSSArena *arena,
- CK_RV *pError
-);
+nssCKFWInstance_CreateMutex(
+ NSSCKFWInstance *fwInstance,
+ NSSArena *arena,
+ CK_RV *pError);
/*
* nssCKFWInstance_GetConfigurationData
*
*/
NSS_EXTERN NSSUTF8 *
-nssCKFWInstance_GetConfigurationData
-(
- NSSCKFWInstance *fwInstance
-);
+nssCKFWInstance_GetConfigurationData(
+ NSSCKFWInstance *fwInstance);
/*
* nssCKFWInstance_GetInitArgs
*
*/
NSS_EXTERN CK_C_INITIALIZE_ARGS_PTR
-nssCKFWInstance_GetInitArgs
-(
- NSSCKFWInstance *fwInstance
-);
+nssCKFWInstance_GetInitArgs(
+ NSSCKFWInstance *fwInstance);
/*
* nssCKFWInstance_CreateSessionHandle
*
*/
NSS_EXTERN CK_SESSION_HANDLE
-nssCKFWInstance_CreateSessionHandle
-(
- NSSCKFWInstance *fwInstance,
- NSSCKFWSession *fwSession,
- CK_RV *pError
-);
+nssCKFWInstance_CreateSessionHandle(
+ NSSCKFWInstance *fwInstance,
+ NSSCKFWSession *fwSession,
+ CK_RV *pError);
/*
* nssCKFWInstance_ResolveSessionHandle
*
*/
NSS_EXTERN NSSCKFWSession *
-nssCKFWInstance_ResolveSessionHandle
-(
- NSSCKFWInstance *fwInstance,
- CK_SESSION_HANDLE hSession
-);
+nssCKFWInstance_ResolveSessionHandle(
+ NSSCKFWInstance *fwInstance,
+ CK_SESSION_HANDLE hSession);
/*
* nssCKFWInstance_DestroySessionHandle
*
*/
NSS_EXTERN void
-nssCKFWInstance_DestroySessionHandle
-(
- NSSCKFWInstance *fwInstance,
- CK_SESSION_HANDLE hSession
-);
+nssCKFWInstance_DestroySessionHandle(
+ NSSCKFWInstance *fwInstance,
+ CK_SESSION_HANDLE hSession);
/*
* nssCKFWInstance_FindSessionHandle
*
*/
NSS_EXTERN CK_SESSION_HANDLE
-nssCKFWInstance_FindSessionHandle
-(
- NSSCKFWInstance *fwInstance,
- NSSCKFWSession *fwSession
-);
+nssCKFWInstance_FindSessionHandle(
+ NSSCKFWInstance *fwInstance,
+ NSSCKFWSession *fwSession);
/*
* nssCKFWInstance_CreateObjectHandle
*
*/
NSS_EXTERN CK_OBJECT_HANDLE
-nssCKFWInstance_CreateObjectHandle
-(
- NSSCKFWInstance *fwInstance,
- NSSCKFWObject *fwObject,
- CK_RV *pError
-);
+nssCKFWInstance_CreateObjectHandle(
+ NSSCKFWInstance *fwInstance,
+ NSSCKFWObject *fwObject,
+ CK_RV *pError);
/*
* nssCKFWInstance_ResolveObjectHandle
*
*/
NSS_EXTERN NSSCKFWObject *
-nssCKFWInstance_ResolveObjectHandle
-(
- NSSCKFWInstance *fwInstance,
- CK_OBJECT_HANDLE hObject
-);
+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_ReassignObjectHandle(
+ NSSCKFWInstance *fwInstance,
+ CK_OBJECT_HANDLE hObject,
+ NSSCKFWObject *fwObject);
/*
* nssCKFWInstance_DestroyObjectHandle
*
*/
NSS_EXTERN void
-nssCKFWInstance_DestroyObjectHandle
-(
- NSSCKFWInstance *fwInstance,
- CK_OBJECT_HANDLE hObject
-);
+nssCKFWInstance_DestroyObjectHandle(
+ NSSCKFWInstance *fwInstance,
+ CK_OBJECT_HANDLE hObject);
/*
* nssCKFWInstance_FindObjectHandle
*
*/
NSS_EXTERN CK_OBJECT_HANDLE
-nssCKFWInstance_FindObjectHandle
-(
- NSSCKFWInstance *fwInstance,
- NSSCKFWObject *fwObject
-);
+nssCKFWInstance_FindObjectHandle(
+ NSSCKFWInstance *fwInstance,
+ NSSCKFWObject *fwObject);
/*
* nssCKFWInstance_GetNSlots
*
*/
NSS_EXTERN CK_ULONG
-nssCKFWInstance_GetNSlots
-(
- NSSCKFWInstance *fwInstance,
- CK_RV *pError
-);
+nssCKFWInstance_GetNSlots(
+ NSSCKFWInstance *fwInstance,
+ CK_RV *pError);
/*
* nssCKFWInstance_GetCryptokiVersion
*
*/
NSS_EXTERN CK_VERSION
-nssCKFWInstance_GetCryptokiVersion
-(
- NSSCKFWInstance *fwInstance
-);
+nssCKFWInstance_GetCryptokiVersion(
+ NSSCKFWInstance *fwInstance);
/*
* nssCKFWInstance_GetManufacturerID
*
*/
NSS_EXTERN CK_RV
-nssCKFWInstance_GetManufacturerID
-(
- NSSCKFWInstance *fwInstance,
- CK_CHAR manufacturerID[32]
-);
+nssCKFWInstance_GetManufacturerID(
+ NSSCKFWInstance *fwInstance,
+ CK_CHAR manufacturerID[32]);
/*
* nssCKFWInstance_GetFlags
*
*/
NSS_EXTERN CK_ULONG
-nssCKFWInstance_GetFlags
-(
- NSSCKFWInstance *fwInstance
-);
+nssCKFWInstance_GetFlags(
+ NSSCKFWInstance *fwInstance);
/*
* nssCKFWInstance_GetLibraryDescription
*
*/
NSS_EXTERN CK_RV
-nssCKFWInstance_GetLibraryDescription
-(
- NSSCKFWInstance *fwInstance,
- CK_CHAR libraryDescription[32]
-);
+nssCKFWInstance_GetLibraryDescription(
+ NSSCKFWInstance *fwInstance,
+ CK_CHAR libraryDescription[32]);
/*
* nssCKFWInstance_GetLibraryVersion
*
*/
NSS_EXTERN CK_VERSION
-nssCKFWInstance_GetLibraryVersion
-(
- NSSCKFWInstance *fwInstance
-);
+nssCKFWInstance_GetLibraryVersion(
+ NSSCKFWInstance *fwInstance);
/*
* nssCKFWInstance_GetModuleHandlesSessionObjects
*
*/
NSS_EXTERN CK_BBOOL
-nssCKFWInstance_GetModuleHandlesSessionObjects
-(
- NSSCKFWInstance *fwInstance
-);
+nssCKFWInstance_GetModuleHandlesSessionObjects(
+ NSSCKFWInstance *fwInstance);
/*
* nssCKFWInstance_GetSlots
*
*/
NSS_EXTERN NSSCKFWSlot **
-nssCKFWInstance_GetSlots
-(
- NSSCKFWInstance *fwInstance,
- CK_RV *pError
-);
+nssCKFWInstance_GetSlots(
+ NSSCKFWInstance *fwInstance,
+ CK_RV *pError);
/*
* nssCKFWInstance_WaitForSlotEvent
*
*/
NSS_EXTERN NSSCKFWSlot *
-nssCKFWInstance_WaitForSlotEvent
-(
- NSSCKFWInstance *fwInstance,
- CK_BBOOL block,
- CK_RV *pError
-);
+nssCKFWInstance_WaitForSlotEvent(
+ NSSCKFWInstance *fwInstance,
+ CK_BBOOL block,
+ CK_RV *pError);
/*
* nssCKFWInstance_verifyPointer
*
*/
NSS_EXTERN CK_RV
-nssCKFWInstance_verifyPointer
-(
- const NSSCKFWInstance *fwInstance
-);
-
+nssCKFWInstance_verifyPointer(
+ const NSSCKFWInstance *fwInstance);
/*
* NSSCKFWSlot
@@ -393,33 +338,27 @@ nssCKFWInstance_verifyPointer
*
*/
NSS_EXTERN NSSCKFWSlot *
-nssCKFWSlot_Create
-(
- NSSCKFWInstance *fwInstance,
- NSSCKMDSlot *mdSlot,
- CK_SLOT_ID slotID,
- CK_RV *pError
-);
+nssCKFWSlot_Create(
+ NSSCKFWInstance *fwInstance,
+ NSSCKMDSlot *mdSlot,
+ CK_SLOT_ID slotID,
+ CK_RV *pError);
/*
* nssCKFWSlot_Destroy
*
*/
NSS_EXTERN CK_RV
-nssCKFWSlot_Destroy
-(
- NSSCKFWSlot *fwSlot
-);
+nssCKFWSlot_Destroy(
+ NSSCKFWSlot *fwSlot);
/*
* nssCKFWSlot_GetMDSlot
*
*/
NSS_EXTERN NSSCKMDSlot *
-nssCKFWSlot_GetMDSlot
-(
- NSSCKFWSlot *fwSlot
-);
+nssCKFWSlot_GetMDSlot(
+ NSSCKFWSlot *fwSlot);
/*
* nssCKFWSlot_GetFWInstance
@@ -427,10 +366,8 @@ nssCKFWSlot_GetMDSlot
*/
NSS_EXTERN NSSCKFWInstance *
-nssCKFWSlot_GetFWInstance
-(
- NSSCKFWSlot *fwSlot
-);
+nssCKFWSlot_GetFWInstance(
+ NSSCKFWSlot *fwSlot);
/*
* nssCKFWSlot_GetMDInstance
@@ -438,113 +375,91 @@ nssCKFWSlot_GetFWInstance
*/
NSS_EXTERN NSSCKMDInstance *
-nssCKFWSlot_GetMDInstance
-(
- NSSCKFWSlot *fwSlot
-);
+nssCKFWSlot_GetMDInstance(
+ NSSCKFWSlot *fwSlot);
/*
* nssCKFWSlot_GetSlotID
*
*/
NSS_EXTERN CK_SLOT_ID
-nssCKFWSlot_GetSlotID
-(
- NSSCKFWSlot *fwSlot
-);
+nssCKFWSlot_GetSlotID(
+ NSSCKFWSlot *fwSlot);
/*
* nssCKFWSlot_GetSlotDescription
*
*/
NSS_EXTERN CK_RV
-nssCKFWSlot_GetSlotDescription
-(
- NSSCKFWSlot *fwSlot,
- CK_CHAR slotDescription[64]
-);
+nssCKFWSlot_GetSlotDescription(
+ NSSCKFWSlot *fwSlot,
+ CK_CHAR slotDescription[64]);
/*
* nssCKFWSlot_GetManufacturerID
*
*/
NSS_EXTERN CK_RV
-nssCKFWSlot_GetManufacturerID
-(
- NSSCKFWSlot *fwSlot,
- CK_CHAR manufacturerID[32]
-);
+nssCKFWSlot_GetManufacturerID(
+ NSSCKFWSlot *fwSlot,
+ CK_CHAR manufacturerID[32]);
/*
* nssCKFWSlot_GetTokenPresent
*
*/
NSS_EXTERN CK_BBOOL
-nssCKFWSlot_GetTokenPresent
-(
- NSSCKFWSlot *fwSlot
-);
+nssCKFWSlot_GetTokenPresent(
+ NSSCKFWSlot *fwSlot);
/*
* nssCKFWSlot_GetRemovableDevice
*
*/
NSS_EXTERN CK_BBOOL
-nssCKFWSlot_GetRemovableDevice
-(
- NSSCKFWSlot *fwSlot
-);
+nssCKFWSlot_GetRemovableDevice(
+ NSSCKFWSlot *fwSlot);
/*
* nssCKFWSlot_GetHardwareSlot
*
*/
NSS_EXTERN CK_BBOOL
-nssCKFWSlot_GetHardwareSlot
-(
- NSSCKFWSlot *fwSlot
-);
+nssCKFWSlot_GetHardwareSlot(
+ NSSCKFWSlot *fwSlot);
/*
* nssCKFWSlot_GetHardwareVersion
*
*/
NSS_EXTERN CK_VERSION
-nssCKFWSlot_GetHardwareVersion
-(
- NSSCKFWSlot *fwSlot
-);
+nssCKFWSlot_GetHardwareVersion(
+ NSSCKFWSlot *fwSlot);
/*
* nssCKFWSlot_GetFirmwareVersion
*
*/
NSS_EXTERN CK_VERSION
-nssCKFWSlot_GetFirmwareVersion
-(
- NSSCKFWSlot *fwSlot
-);
+nssCKFWSlot_GetFirmwareVersion(
+ NSSCKFWSlot *fwSlot);
/*
* nssCKFWSlot_GetToken
- *
+ *
*/
NSS_EXTERN NSSCKFWToken *
-nssCKFWSlot_GetToken
-(
- NSSCKFWSlot *fwSlot,
- CK_RV *pError
-);
+nssCKFWSlot_GetToken(
+ NSSCKFWSlot *fwSlot,
+ CK_RV *pError);
/*
* nssCKFWSlot_ClearToken
*
*/
NSS_EXTERN void
-nssCKFWSlot_ClearToken
-(
- NSSCKFWSlot *fwSlot
-);
+nssCKFWSlot_ClearToken(
+ NSSCKFWSlot *fwSlot);
/*
* NSSCKFWToken
@@ -606,459 +521,371 @@ nssCKFWSlot_ClearToken
*
*/
NSS_EXTERN NSSCKFWToken *
-nssCKFWToken_Create
-(
- NSSCKFWSlot *fwSlot,
- NSSCKMDToken *mdToken,
- CK_RV *pError
-);
+nssCKFWToken_Create(
+ NSSCKFWSlot *fwSlot,
+ NSSCKMDToken *mdToken,
+ CK_RV *pError);
/*
* nssCKFWToken_Destroy
*
*/
NSS_EXTERN CK_RV
-nssCKFWToken_Destroy
-(
- NSSCKFWToken *fwToken
-);
+nssCKFWToken_Destroy(
+ NSSCKFWToken *fwToken);
/*
* nssCKFWToken_GetMDToken
*
*/
NSS_EXTERN NSSCKMDToken *
-nssCKFWToken_GetMDToken
-(
- NSSCKFWToken *fwToken
-);
+nssCKFWToken_GetMDToken(
+ NSSCKFWToken *fwToken);
/*
* nssCKFWToken_GetArena
*
*/
NSS_EXTERN NSSArena *
-nssCKFWToken_GetArena
-(
- NSSCKFWToken *fwToken,
- CK_RV *pError
-);
+nssCKFWToken_GetArena(
+ NSSCKFWToken *fwToken,
+ CK_RV *pError);
/*
* nssCKFWToken_GetFWSlot
*
*/
NSS_EXTERN NSSCKFWSlot *
-nssCKFWToken_GetFWSlot
-(
- NSSCKFWToken *fwToken
-);
+nssCKFWToken_GetFWSlot(
+ NSSCKFWToken *fwToken);
/*
* nssCKFWToken_GetMDSlot
*
*/
NSS_EXTERN NSSCKMDSlot *
-nssCKFWToken_GetMDSlot
-(
- NSSCKFWToken *fwToken
-);
+nssCKFWToken_GetMDSlot(
+ NSSCKFWToken *fwToken);
/*
* nssCKFWToken_GetSessionState
*
*/
NSS_EXTERN CK_STATE
-nssCKFWToken_GetSessionState
-(
- NSSCKFWToken *fwToken
-);
+nssCKFWToken_GetSessionState(
+ NSSCKFWToken *fwToken);
/*
* nssCKFWToken_InitToken
*
*/
NSS_EXTERN CK_RV
-nssCKFWToken_InitToken
-(
- NSSCKFWToken *fwToken,
- NSSItem *pin,
- NSSUTF8 *label
-);
+nssCKFWToken_InitToken(
+ NSSCKFWToken *fwToken,
+ NSSItem *pin,
+ NSSUTF8 *label);
/*
* nssCKFWToken_GetLabel
*
*/
NSS_EXTERN CK_RV
-nssCKFWToken_GetLabel
-(
- NSSCKFWToken *fwToken,
- CK_CHAR label[32]
-);
+nssCKFWToken_GetLabel(
+ NSSCKFWToken *fwToken,
+ CK_CHAR label[32]);
/*
* nssCKFWToken_GetManufacturerID
*
*/
NSS_EXTERN CK_RV
-nssCKFWToken_GetManufacturerID
-(
- NSSCKFWToken *fwToken,
- CK_CHAR manufacturerID[32]
-);
+nssCKFWToken_GetManufacturerID(
+ NSSCKFWToken *fwToken,
+ CK_CHAR manufacturerID[32]);
/*
* nssCKFWToken_GetModel
*
*/
NSS_EXTERN CK_RV
-nssCKFWToken_GetModel
-(
- NSSCKFWToken *fwToken,
- CK_CHAR model[16]
-);
+nssCKFWToken_GetModel(
+ NSSCKFWToken *fwToken,
+ CK_CHAR model[16]);
/*
* nssCKFWToken_GetSerialNumber
*
*/
NSS_EXTERN CK_RV
-nssCKFWToken_GetSerialNumber
-(
- NSSCKFWToken *fwToken,
- CK_CHAR serialNumber[16]
-);
+nssCKFWToken_GetSerialNumber(
+ NSSCKFWToken *fwToken,
+ CK_CHAR serialNumber[16]);
/*
* nssCKFWToken_GetHasRNG
*
*/
NSS_EXTERN CK_BBOOL
-nssCKFWToken_GetHasRNG
-(
- NSSCKFWToken *fwToken
-);
+nssCKFWToken_GetHasRNG(
+ NSSCKFWToken *fwToken);
/*
* nssCKFWToken_GetIsWriteProtected
*
*/
NSS_EXTERN CK_BBOOL
-nssCKFWToken_GetIsWriteProtected
-(
- NSSCKFWToken *fwToken
-);
+nssCKFWToken_GetIsWriteProtected(
+ NSSCKFWToken *fwToken);
/*
* nssCKFWToken_GetLoginRequired
*
*/
NSS_EXTERN CK_BBOOL
-nssCKFWToken_GetLoginRequired
-(
- NSSCKFWToken *fwToken
-);
+nssCKFWToken_GetLoginRequired(
+ NSSCKFWToken *fwToken);
/*
* nssCKFWToken_GetUserPinInitialized
*
*/
NSS_EXTERN CK_BBOOL
-nssCKFWToken_GetUserPinInitialized
-(
- NSSCKFWToken *fwToken
-);
+nssCKFWToken_GetUserPinInitialized(
+ NSSCKFWToken *fwToken);
/*
* nssCKFWToken_GetRestoreKeyNotNeeded
*
*/
NSS_EXTERN CK_BBOOL
-nssCKFWToken_GetRestoreKeyNotNeeded
-(
- NSSCKFWToken *fwToken
-);
+nssCKFWToken_GetRestoreKeyNotNeeded(
+ NSSCKFWToken *fwToken);
/*
* nssCKFWToken_GetHasClockOnToken
*
*/
NSS_EXTERN CK_BBOOL
-nssCKFWToken_GetHasClockOnToken
-(
- NSSCKFWToken *fwToken
-);
+nssCKFWToken_GetHasClockOnToken(
+ NSSCKFWToken *fwToken);
/*
* nssCKFWToken_GetHasProtectedAuthenticationPath
*
*/
NSS_EXTERN CK_BBOOL
-nssCKFWToken_GetHasProtectedAuthenticationPath
-(
- NSSCKFWToken *fwToken
-);
+nssCKFWToken_GetHasProtectedAuthenticationPath(
+ NSSCKFWToken *fwToken);
/*
* nssCKFWToken_GetSupportsDualCryptoOperations
*
*/
NSS_EXTERN CK_BBOOL
-nssCKFWToken_GetSupportsDualCryptoOperations
-(
- NSSCKFWToken *fwToken
-);
+nssCKFWToken_GetSupportsDualCryptoOperations(
+ NSSCKFWToken *fwToken);
/*
* nssCKFWToken_GetMaxSessionCount
*
*/
NSS_EXTERN CK_ULONG
-nssCKFWToken_GetMaxSessionCount
-(
- NSSCKFWToken *fwToken
-);
+nssCKFWToken_GetMaxSessionCount(
+ NSSCKFWToken *fwToken);
/*
* nssCKFWToken_GetMaxRwSessionCount
*
*/
NSS_EXTERN CK_ULONG
-nssCKFWToken_GetMaxRwSessionCount
-(
- NSSCKFWToken *fwToken
-);
+nssCKFWToken_GetMaxRwSessionCount(
+ NSSCKFWToken *fwToken);
/*
* nssCKFWToken_GetMaxPinLen
*
*/
NSS_EXTERN CK_ULONG
-nssCKFWToken_GetMaxPinLen
-(
- NSSCKFWToken *fwToken
-);
+nssCKFWToken_GetMaxPinLen(
+ NSSCKFWToken *fwToken);
/*
* nssCKFWToken_GetMinPinLen
*
*/
NSS_EXTERN CK_ULONG
-nssCKFWToken_GetMinPinLen
-(
- NSSCKFWToken *fwToken
-);
+nssCKFWToken_GetMinPinLen(
+ NSSCKFWToken *fwToken);
/*
* nssCKFWToken_GetTotalPublicMemory
*
*/
NSS_EXTERN CK_ULONG
-nssCKFWToken_GetTotalPublicMemory
-(
- NSSCKFWToken *fwToken
-);
+nssCKFWToken_GetTotalPublicMemory(
+ NSSCKFWToken *fwToken);
/*
* nssCKFWToken_GetFreePublicMemory
*
*/
NSS_EXTERN CK_ULONG
-nssCKFWToken_GetFreePublicMemory
-(
- NSSCKFWToken *fwToken
-);
+nssCKFWToken_GetFreePublicMemory(
+ NSSCKFWToken *fwToken);
/*
* nssCKFWToken_GetTotalPrivateMemory
*
*/
NSS_EXTERN CK_ULONG
-nssCKFWToken_GetTotalPrivateMemory
-(
- NSSCKFWToken *fwToken
-);
+nssCKFWToken_GetTotalPrivateMemory(
+ NSSCKFWToken *fwToken);
/*
* nssCKFWToken_GetFreePrivateMemory
*
*/
NSS_EXTERN CK_ULONG
-nssCKFWToken_GetFreePrivateMemory
-(
- NSSCKFWToken *fwToken
-);
+nssCKFWToken_GetFreePrivateMemory(
+ NSSCKFWToken *fwToken);
/*
* nssCKFWToken_GetHardwareVersion
*
*/
NSS_EXTERN CK_VERSION
-nssCKFWToken_GetHardwareVersion
-(
- NSSCKFWToken *fwToken
-);
+nssCKFWToken_GetHardwareVersion(
+ NSSCKFWToken *fwToken);
/*
* nssCKFWToken_GetFirmwareVersion
*
*/
NSS_EXTERN CK_VERSION
-nssCKFWToken_GetFirmwareVersion
-(
- NSSCKFWToken *fwToken
-);
+nssCKFWToken_GetFirmwareVersion(
+ NSSCKFWToken *fwToken);
/*
* nssCKFWToken_GetUTCTime
*
*/
NSS_EXTERN CK_RV
-nssCKFWToken_GetUTCTime
-(
- NSSCKFWToken *fwToken,
- CK_CHAR utcTime[16]
-);
+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_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_GetMechanismCount(
+ NSSCKFWToken *fwToken);
/*
* nssCKFWToken_GetMechanismTypes
*
*/
NSS_EXTERN CK_RV
-nssCKFWToken_GetMechanismTypes
-(
- NSSCKFWToken *fwToken,
- CK_MECHANISM_TYPE types[]
-);
+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_GetMechanism(
+ NSSCKFWToken *fwToken,
+ CK_MECHANISM_TYPE which,
+ CK_RV *pError);
/*
* nssCKFWToken_SetSessionState
*
*/
NSS_EXTERN CK_RV
-nssCKFWToken_SetSessionState
-(
- NSSCKFWToken *fwToken,
- CK_STATE newState
-);
+nssCKFWToken_SetSessionState(
+ NSSCKFWToken *fwToken,
+ CK_STATE newState);
/*
* nssCKFWToken_RemoveSession
*
*/
NSS_EXTERN CK_RV
-nssCKFWToken_RemoveSession
-(
- NSSCKFWToken *fwToken,
- NSSCKFWSession *fwSession
-);
+nssCKFWToken_RemoveSession(
+ NSSCKFWToken *fwToken,
+ NSSCKFWSession *fwSession);
/*
* nssCKFWToken_CloseAllSessions
*
*/
NSS_EXTERN CK_RV
-nssCKFWToken_CloseAllSessions
-(
- NSSCKFWToken *fwToken
-);
+nssCKFWToken_CloseAllSessions(
+ NSSCKFWToken *fwToken);
/*
* nssCKFWToken_GetSessionCount
*
*/
NSS_EXTERN CK_ULONG
-nssCKFWToken_GetSessionCount
-(
- NSSCKFWToken *fwToken
-);
+nssCKFWToken_GetSessionCount(
+ NSSCKFWToken *fwToken);
/*
* nssCKFWToken_GetRwSessionCount
*
*/
NSS_EXTERN CK_ULONG
-nssCKFWToken_GetRwSessionCount
-(
- NSSCKFWToken *fwToken
-);
+nssCKFWToken_GetRwSessionCount(
+ NSSCKFWToken *fwToken);
/*
* nssCKFWToken_GetRoSessionCount
*
*/
NSS_EXTERN CK_ULONG
-nssCKFWToken_GetRoSessionCount
-(
- NSSCKFWToken *fwToken
-);
+nssCKFWToken_GetRoSessionCount(
+ NSSCKFWToken *fwToken);
/*
* nssCKFWToken_GetSessionObjectHash
*
*/
NSS_EXTERN nssCKFWHash *
-nssCKFWToken_GetSessionObjectHash
-(
- NSSCKFWToken *fwToken
-);
+nssCKFWToken_GetSessionObjectHash(
+ NSSCKFWToken *fwToken);
/*
* nssCKFWToken_GetMDObjectHash
*
*/
NSS_EXTERN nssCKFWHash *
-nssCKFWToken_GetMDObjectHash
-(
- NSSCKFWToken *fwToken
-);
+nssCKFWToken_GetMDObjectHash(
+ NSSCKFWToken *fwToken);
/*
* nssCKFWToken_GetObjectHandleHash
*
*/
NSS_EXTERN nssCKFWHash *
-nssCKFWToken_GetObjectHandleHash
-(
- NSSCKFWToken *fwToken
-);
+nssCKFWToken_GetObjectHandleHash(
+ NSSCKFWToken *fwToken);
/*
* NSSCKFWMechanism
@@ -1107,24 +934,20 @@ nssCKFWToken_GetObjectHandleHash
*
*/
NSS_EXTERN NSSCKFWMechanism *
-nssCKFWMechanism_Create
-(
- NSSCKMDMechanism *mdMechanism,
- NSSCKMDToken *mdToken,
- NSSCKFWToken *fwToken,
- NSSCKMDInstance *mdInstance,
- NSSCKFWInstance *fwInstance
-);
+nssCKFWMechanism_Create(
+ NSSCKMDMechanism *mdMechanism,
+ NSSCKMDToken *mdToken,
+ NSSCKFWToken *fwToken,
+ NSSCKMDInstance *mdInstance,
+ NSSCKFWInstance *fwInstance);
/*
* nssCKFWMechanism_Destroy
*
*/
NSS_EXTERN void
-nssCKFWMechanism_Destroy
-(
- NSSCKFWMechanism *fwMechanism
-);
+nssCKFWMechanism_Destroy(
+ NSSCKFWMechanism *fwMechanism);
/*
* nssCKFWMechanism_GetMDMechanism
@@ -1132,43 +955,35 @@ nssCKFWMechanism_Destroy
*/
NSS_EXTERN NSSCKMDMechanism *
-nssCKFWMechanism_GetMDMechanism
-(
- NSSCKFWMechanism *fwMechanism
-);
+nssCKFWMechanism_GetMDMechanism(
+ NSSCKFWMechanism *fwMechanism);
/*
* nssCKFWMechanism_GetMinKeySize
*
*/
NSS_EXTERN CK_ULONG
-nssCKFWMechanism_GetMinKeySize
-(
- NSSCKFWMechanism *fwMechanism,
- CK_RV *pError
-);
+nssCKFWMechanism_GetMinKeySize(
+ NSSCKFWMechanism *fwMechanism,
+ CK_RV *pError);
/*
* nssCKFWMechanism_GetMaxKeySize
*
*/
NSS_EXTERN CK_ULONG
-nssCKFWMechanism_GetMaxKeySize
-(
- NSSCKFWMechanism *fwMechanism,
- CK_RV *pError
-);
+nssCKFWMechanism_GetMaxKeySize(
+ NSSCKFWMechanism *fwMechanism,
+ CK_RV *pError);
/*
* nssCKFWMechanism_GetInHardware
*
*/
NSS_EXTERN CK_BBOOL
-nssCKFWMechanism_GetInHardware
-(
- NSSCKFWMechanism *fwMechanism,
- CK_RV *pError
-);
+nssCKFWMechanism_GetInHardware(
+ NSSCKFWMechanism *fwMechanism,
+ CK_RV *pError);
/*
* the following are determined automatically by which of the cryptographic
@@ -1179,305 +994,255 @@ nssCKFWMechanism_GetInHardware
*
*/
NSS_EXTERN CK_BBOOL
-nssCKFWMechanism_GetCanEncrypt
-(
- NSSCKFWMechanism *fwMechanism,
- CK_RV *pError
-);
+nssCKFWMechanism_GetCanEncrypt(
+ NSSCKFWMechanism *fwMechanism,
+ CK_RV *pError);
/*
* nssCKFWMechanism_GetCanDecrypt
*
*/
NSS_EXTERN CK_BBOOL
-nssCKFWMechanism_GetCanDecrypt
-(
- NSSCKFWMechanism *fwMechanism,
- CK_RV *pError
-);
+nssCKFWMechanism_GetCanDecrypt(
+ NSSCKFWMechanism *fwMechanism,
+ CK_RV *pError);
/*
* nssCKFWMechanism_GetCanDigest
*
*/
NSS_EXTERN CK_BBOOL
-nssCKFWMechanism_GetCanDigest
-(
- NSSCKFWMechanism *fwMechanism,
- CK_RV *pError
-);
+nssCKFWMechanism_GetCanDigest(
+ NSSCKFWMechanism *fwMechanism,
+ CK_RV *pError);
/*
* nssCKFWMechanism_GetCanSign
*
*/
NSS_EXTERN CK_BBOOL
-nssCKFWMechanism_GetCanSign
-(
- NSSCKFWMechanism *fwMechanism,
- CK_RV *pError
-);
+nssCKFWMechanism_GetCanSign(
+ NSSCKFWMechanism *fwMechanism,
+ CK_RV *pError);
/*
* nssCKFWMechanism_GetCanSignRecover
*
*/
NSS_EXTERN CK_BBOOL
-nssCKFWMechanism_GetCanSignRecover
-(
- NSSCKFWMechanism *fwMechanism,
- CK_RV *pError
-);
+nssCKFWMechanism_GetCanSignRecover(
+ NSSCKFWMechanism *fwMechanism,
+ CK_RV *pError);
/*
* nssCKFWMechanism_GetCanVerify
*
*/
NSS_EXTERN CK_BBOOL
-nssCKFWMechanism_GetCanVerify
-(
- NSSCKFWMechanism *fwMechanism,
- CK_RV *pError
-);
+nssCKFWMechanism_GetCanVerify(
+ NSSCKFWMechanism *fwMechanism,
+ CK_RV *pError);
/*
* nssCKFWMechanism_GetCanVerifyRecover
*
*/
NSS_EXTERN CK_BBOOL
-nssCKFWMechanism_GetCanVerifyRecover
-(
- NSSCKFWMechanism *fwMechanism,
- CK_RV *pError
-);
+nssCKFWMechanism_GetCanVerifyRecover(
+ NSSCKFWMechanism *fwMechanism,
+ CK_RV *pError);
/*
* nssCKFWMechanism_GetCanGenerate
*
*/
NSS_EXTERN CK_BBOOL
-nssCKFWMechanism_GetCanGenerate
-(
- NSSCKFWMechanism *fwMechanism,
- CK_RV *pError
-);
+nssCKFWMechanism_GetCanGenerate(
+ NSSCKFWMechanism *fwMechanism,
+ CK_RV *pError);
/*
* nssCKFWMechanism_GetCanGenerateKeyPair
*
*/
NSS_EXTERN CK_BBOOL
-nssCKFWMechanism_GetCanGenerateKeyPair
-(
- NSSCKFWMechanism *fwMechanism,
- CK_RV *pError
-);
+nssCKFWMechanism_GetCanGenerateKeyPair(
+ NSSCKFWMechanism *fwMechanism,
+ CK_RV *pError);
/*
* nssCKFWMechanism_GetCanWrap
*
*/
NSS_EXTERN CK_BBOOL
-nssCKFWMechanism_GetCanWrap
-(
- NSSCKFWMechanism *fwMechanism,
- CK_RV *pError
-);
+nssCKFWMechanism_GetCanWrap(
+ NSSCKFWMechanism *fwMechanism,
+ CK_RV *pError);
/*
* nssCKFWMechanism_GetCanUnwrap
*
*/
NSS_EXTERN CK_BBOOL
-nssCKFWMechanism_GetCanUnwrap
-(
- NSSCKFWMechanism *fwMechanism,
- CK_RV *pError
-);
+nssCKFWMechanism_GetCanUnwrap(
+ NSSCKFWMechanism *fwMechanism,
+ CK_RV *pError);
/*
* nssCKFWMechanism_GetCanDerive
*
*/
NSS_EXTERN CK_BBOOL
-nssCKFWMechanism_GetCanDerive
-(
- NSSCKFWMechanism *fwMechanism,
- CK_RV *pError
-);
+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_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_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_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_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_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_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_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_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_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_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_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_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
-);
+nssCKFWMechanism_DeriveKey(
+ NSSCKFWMechanism *fwMechanism,
+ CK_MECHANISM_PTR pMechanism,
+ NSSCKFWSession *fwSession,
+ NSSCKFWObject *fwBaseKeyObject,
+ CK_ATTRIBUTE_PTR pTemplate,
+ CK_ULONG ulAttributeCount,
+ CK_RV *pError);
/*
* NSSCKFWCryptoOperation
@@ -1506,130 +1271,106 @@ nssCKFWMechanism_DeriveKey
* 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_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_Destroy(
+ NSSCKFWCryptoOperation *fwOperation);
/*
* nssCKFWCryptoOperation_GetMDCryptoOperation
*/
NSS_EXTERN NSSCKMDCryptoOperation *
-nssCKFWCryptoOperation_GetMDCryptoOperation
-(
- NSSCKFWCryptoOperation *fwOperation
-);
+nssCKFWCryptoOperation_GetMDCryptoOperation(
+ NSSCKFWCryptoOperation *fwOperation);
/*
* nssCKFWCryptoOperation_GetType
*/
NSS_EXTERN NSSCKFWCryptoOperationType
-nssCKFWCryptoOperation_GetType
-(
- NSSCKFWCryptoOperation *fwOperation
-);
+nssCKFWCryptoOperation_GetType(
+ NSSCKFWCryptoOperation *fwOperation);
/*
* nssCKFWCryptoOperation_GetFinalLength
*/
NSS_EXTERN CK_ULONG
-nssCKFWCryptoOperation_GetFinalLength
-(
- NSSCKFWCryptoOperation *fwOperation,
- CK_RV *pError
-);
+nssCKFWCryptoOperation_GetFinalLength(
+ NSSCKFWCryptoOperation *fwOperation,
+ CK_RV *pError);
/*
* nssCKFWCryptoOperation_GetOperationLength
*/
NSS_EXTERN CK_ULONG
-nssCKFWCryptoOperation_GetOperationLength
-(
- NSSCKFWCryptoOperation *fwOperation,
- NSSItem *inputBuffer,
- CK_RV *pError
-);
+nssCKFWCryptoOperation_GetOperationLength(
+ NSSCKFWCryptoOperation *fwOperation,
+ NSSItem *inputBuffer,
+ CK_RV *pError);
/*
* nssCKFWCryptoOperation_Final
*/
NSS_EXTERN CK_RV
-nssCKFWCryptoOperation_Final
-(
- NSSCKFWCryptoOperation *fwOperation,
- NSSItem *outputBuffer
-);
+nssCKFWCryptoOperation_Final(
+ NSSCKFWCryptoOperation *fwOperation,
+ NSSItem *outputBuffer);
/*
* nssCKFWCryptoOperation_Update
*/
NSS_EXTERN CK_RV
-nssCKFWCryptoOperation_Update
-(
- NSSCKFWCryptoOperation *fwOperation,
- NSSItem *inputBuffer,
- NSSItem *outputBuffer
-);
+nssCKFWCryptoOperation_Update(
+ NSSCKFWCryptoOperation *fwOperation,
+ NSSItem *inputBuffer,
+ NSSItem *outputBuffer);
/*
* nssCKFWCryptoOperation_DigestUpdate
*/
NSS_EXTERN CK_RV
-nssCKFWCryptoOperation_DigestUpdate
-(
- NSSCKFWCryptoOperation *fwOperation,
- NSSItem *inputBuffer
-);
+nssCKFWCryptoOperation_DigestUpdate(
+ NSSCKFWCryptoOperation *fwOperation,
+ NSSItem *inputBuffer);
/*
* nssCKFWCryptoOperation_DigestKey
*/
NSS_EXTERN CK_RV
-nssCKFWCryptoOperation_DigestKey
-(
- NSSCKFWCryptoOperation *fwOperation,
- NSSCKFWObject *fwKey
-);
+nssCKFWCryptoOperation_DigestKey(
+ NSSCKFWCryptoOperation *fwOperation,
+ NSSCKFWObject *fwKey);
/*
* nssCKFWCryptoOperation_UpdateFinal
*/
NSS_EXTERN CK_RV
-nssCKFWCryptoOperation_UpdateFinal
-(
- NSSCKFWCryptoOperation *fwOperation,
- NSSItem *inputBuffer,
- NSSItem *outputBuffer
-);
+nssCKFWCryptoOperation_UpdateFinal(
+ NSSCKFWCryptoOperation *fwOperation,
+ NSSItem *inputBuffer,
+ NSSItem *outputBuffer);
/*
* nssCKFWCryptoOperation_UpdateCombo
*/
NSS_EXTERN CK_RV
-nssCKFWCryptoOperation_UpdateCombo
-(
- NSSCKFWCryptoOperation *fwOperation,
- NSSCKFWCryptoOperation *fwPeerOperation,
- NSSItem *inputBuffer,
- NSSItem *outputBuffer
-);
+nssCKFWCryptoOperation_UpdateCombo(
+ NSSCKFWCryptoOperation *fwOperation,
+ NSSCKFWCryptoOperation *fwPeerOperation,
+ NSSItem *inputBuffer,
+ NSSItem *outputBuffer);
/*
* NSSCKFWSession
@@ -1685,434 +1426,360 @@ nssCKFWCryptoOperation_UpdateCombo
*
*/
NSS_EXTERN NSSCKFWSession *
-nssCKFWSession_Create
-(
- NSSCKFWToken *fwToken,
- CK_BBOOL rw,
- CK_VOID_PTR pApplication,
- CK_NOTIFY Notify,
- CK_RV *pError
-);
+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_Destroy(
+ NSSCKFWSession *fwSession,
+ CK_BBOOL removeFromTokenHash);
/*
* nssCKFWSession_GetMDSession
*
*/
NSS_EXTERN NSSCKMDSession *
-nssCKFWSession_GetMDSession
-(
- NSSCKFWSession *fwSession
-);
+nssCKFWSession_GetMDSession(
+ NSSCKFWSession *fwSession);
/*
* nssCKFWSession_GetArena
*
*/
NSS_EXTERN NSSArena *
-nssCKFWSession_GetArena
-(
- NSSCKFWSession *fwSession,
- CK_RV *pError
-);
+nssCKFWSession_GetArena(
+ NSSCKFWSession *fwSession,
+ CK_RV *pError);
/*
* nssCKFWSession_CallNotification
*
*/
NSS_EXTERN CK_RV
-nssCKFWSession_CallNotification
-(
- NSSCKFWSession *fwSession,
- CK_NOTIFICATION event
-);
+nssCKFWSession_CallNotification(
+ NSSCKFWSession *fwSession,
+ CK_NOTIFICATION event);
/*
* nssCKFWSession_IsRWSession
*
*/
NSS_EXTERN CK_BBOOL
-nssCKFWSession_IsRWSession
-(
- NSSCKFWSession *fwSession
-);
+nssCKFWSession_IsRWSession(
+ NSSCKFWSession *fwSession);
/*
* nssCKFWSession_IsSO
*
*/
NSS_EXTERN CK_BBOOL
-nssCKFWSession_IsSO
-(
- NSSCKFWSession *fwSession
-);
+nssCKFWSession_IsSO(
+ NSSCKFWSession *fwSession);
/*
* nssCKFWSession_GetFWSlot
*
*/
NSS_EXTERN NSSCKFWSlot *
-nssCKFWSession_GetFWSlot
-(
- NSSCKFWSession *fwSession
-);
+nssCKFWSession_GetFWSlot(
+ NSSCKFWSession *fwSession);
/*
* nssCFKWSession_GetSessionState
*
*/
NSS_EXTERN CK_STATE
-nssCKFWSession_GetSessionState
-(
- NSSCKFWSession *fwSession
-);
+nssCKFWSession_GetSessionState(
+ NSSCKFWSession *fwSession);
/*
* nssCKFWSession_SetFWFindObjects
*
*/
NSS_EXTERN CK_RV
-nssCKFWSession_SetFWFindObjects
-(
- NSSCKFWSession *fwSession,
- NSSCKFWFindObjects *fwFindObjects
-);
+nssCKFWSession_SetFWFindObjects(
+ NSSCKFWSession *fwSession,
+ NSSCKFWFindObjects *fwFindObjects);
/*
* nssCKFWSession_GetFWFindObjects
*
*/
NSS_EXTERN NSSCKFWFindObjects *
-nssCKFWSession_GetFWFindObjects
-(
- NSSCKFWSession *fwSesssion,
- CK_RV *pError
-);
+nssCKFWSession_GetFWFindObjects(
+ NSSCKFWSession *fwSesssion,
+ CK_RV *pError);
/*
* nssCKFWSession_SetMDSession
*
*/
NSS_EXTERN CK_RV
-nssCKFWSession_SetMDSession
-(
- NSSCKFWSession *fwSession,
- NSSCKMDSession *mdSession
-);
+nssCKFWSession_SetMDSession(
+ NSSCKFWSession *fwSession,
+ NSSCKMDSession *mdSession);
/*
* nssCKFWSession_SetHandle
*
*/
NSS_EXTERN CK_RV
-nssCKFWSession_SetHandle
-(
- NSSCKFWSession *fwSession,
- CK_SESSION_HANDLE hSession
-);
+nssCKFWSession_SetHandle(
+ NSSCKFWSession *fwSession,
+ CK_SESSION_HANDLE hSession);
/*
* nssCKFWSession_GetHandle
*
*/
NSS_EXTERN CK_SESSION_HANDLE
-nssCKFWSession_GetHandle
-(
- NSSCKFWSession *fwSession
-);
+nssCKFWSession_GetHandle(
+ NSSCKFWSession *fwSession);
/*
* nssCKFWSession_RegisterSessionObject
*
*/
NSS_EXTERN CK_RV
-nssCKFWSession_RegisterSessionObject
-(
- NSSCKFWSession *fwSession,
- NSSCKFWObject *fwObject
-);
+nssCKFWSession_RegisterSessionObject(
+ NSSCKFWSession *fwSession,
+ NSSCKFWObject *fwObject);
/*
* nssCKFWSession_DeregisterSessionObject
*
*/
NSS_EXTERN CK_RV
-nssCKFWSession_DeregisterSessionObject
-(
- NSSCKFWSession *fwSession,
- NSSCKFWObject *fwObject
-);
+nssCKFWSession_DeregisterSessionObject(
+ NSSCKFWSession *fwSession,
+ NSSCKFWObject *fwObject);
/*
* nssCKFWSession_GetDeviceError
*
*/
NSS_EXTERN CK_ULONG
-nssCKFWSession_GetDeviceError
-(
- NSSCKFWSession *fwSession
-);
+nssCKFWSession_GetDeviceError(
+ NSSCKFWSession *fwSession);
/*
* nssCKFWSession_Login
*
*/
NSS_EXTERN CK_RV
-nssCKFWSession_Login
-(
- NSSCKFWSession *fwSession,
- CK_USER_TYPE userType,
- NSSItem *pin
-);
+nssCKFWSession_Login(
+ NSSCKFWSession *fwSession,
+ CK_USER_TYPE userType,
+ NSSItem *pin);
/*
* nssCKFWSession_Logout
*
*/
NSS_EXTERN CK_RV
-nssCKFWSession_Logout
-(
- NSSCKFWSession *fwSession
-);
+nssCKFWSession_Logout(
+ NSSCKFWSession *fwSession);
/*
* nssCKFWSession_InitPIN
*
*/
NSS_EXTERN CK_RV
-nssCKFWSession_InitPIN
-(
- NSSCKFWSession *fwSession,
- NSSItem *pin
-);
+nssCKFWSession_InitPIN(
+ NSSCKFWSession *fwSession,
+ NSSItem *pin);
/*
* nssCKFWSession_SetPIN
*
*/
NSS_EXTERN CK_RV
-nssCKFWSession_SetPIN
-(
- NSSCKFWSession *fwSession,
- NSSItem *newPin,
- NSSItem *oldPin
-);
+nssCKFWSession_SetPIN(
+ NSSCKFWSession *fwSession,
+ NSSItem *newPin,
+ NSSItem *oldPin);
/*
* nssCKFWSession_GetOperationStateLen
*
*/
NSS_EXTERN CK_ULONG
-nssCKFWSession_GetOperationStateLen
-(
- NSSCKFWSession *fwSession,
- CK_RV *pError
-);
+nssCKFWSession_GetOperationStateLen(
+ NSSCKFWSession *fwSession,
+ CK_RV *pError);
/*
* nssCKFWSession_GetOperationState
*
*/
NSS_EXTERN CK_RV
-nssCKFWSession_GetOperationState
-(
- NSSCKFWSession *fwSession,
- NSSItem *buffer
-);
+nssCKFWSession_GetOperationState(
+ NSSCKFWSession *fwSession,
+ NSSItem *buffer);
/*
* nssCKFWSession_SetOperationState
*
*/
NSS_EXTERN CK_RV
-nssCKFWSession_SetOperationState
-(
- NSSCKFWSession *fwSession,
- NSSItem *state,
- NSSCKFWObject *encryptionKey,
- NSSCKFWObject *authenticationKey
-);
+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_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_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_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_SetCurrentCryptoOperation(
+ NSSCKFWSession *fwSession,
+ NSSCKFWCryptoOperation *fwOperation,
+ NSSCKFWCryptoOperationState state);
/*
* nssCKFWSession_GetCurrentCryptoOperation
*/
NSS_IMPLEMENT NSSCKFWCryptoOperation *
-nssCKFWSession_GetCurrentCryptoOperation
-(
- NSSCKFWSession *fwSession,
- NSSCKFWCryptoOperationState state
-);
+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_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_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_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_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_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_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_SeedRandom(
+ NSSCKFWSession *fwSession,
+ NSSItem *seed);
/*
* nssCKFWSession_GetRandom
*
*/
NSS_EXTERN CK_RV
-nssCKFWSession_GetRandom
-(
- NSSCKFWSession *fwSession,
- NSSItem *buffer
-);
+nssCKFWSession_GetRandom(
+ NSSCKFWSession *fwSession,
+ NSSItem *buffer);
/*
* NSSCKFWObject
@@ -2145,123 +1812,101 @@ nssCKFWSession_GetRandom
*
*/
NSS_EXTERN NSSCKFWObject *
-nssCKFWObject_Create
-(
- NSSArena *arena,
- NSSCKMDObject *mdObject,
- NSSCKFWSession *fwSession,
- NSSCKFWToken *fwToken,
- NSSCKFWInstance *fwInstance,
- CK_RV *pError
-);
+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_Finalize(
+ NSSCKFWObject *fwObject,
+ PRBool removeFromHash);
/*
* nssCKFWObject_Destroy
*
*/
NSS_EXTERN void
-nssCKFWObject_Destroy
-(
- NSSCKFWObject *fwObject
-);
+nssCKFWObject_Destroy(
+ NSSCKFWObject *fwObject);
/*
* nssCKFWObject_GetMDObject
*
*/
NSS_EXTERN NSSCKMDObject *
-nssCKFWObject_GetMDObject
-(
- NSSCKFWObject *fwObject
-);
+nssCKFWObject_GetMDObject(
+ NSSCKFWObject *fwObject);
/*
* nssCKFWObject_GetArena
*
*/
NSS_EXTERN NSSArena *
-nssCKFWObject_GetArena
-(
- NSSCKFWObject *fwObject,
- CK_RV *pError
-);
+nssCKFWObject_GetArena(
+ NSSCKFWObject *fwObject,
+ CK_RV *pError);
/*
* nssCKFWObject_SetHandle
*
*/
NSS_EXTERN CK_RV
-nssCKFWObject_SetHandle
-(
- NSSCKFWObject *fwObject,
- CK_OBJECT_HANDLE hObject
-);
+nssCKFWObject_SetHandle(
+ NSSCKFWObject *fwObject,
+ CK_OBJECT_HANDLE hObject);
/*
* nssCKFWObject_GetHandle
*
*/
NSS_EXTERN CK_OBJECT_HANDLE
-nssCKFWObject_GetHandle
-(
- NSSCKFWObject *fwObject
-);
+nssCKFWObject_GetHandle(
+ NSSCKFWObject *fwObject);
/*
* nssCKFWObject_IsTokenObject
*
*/
NSS_EXTERN CK_BBOOL
-nssCKFWObject_IsTokenObject
-(
- NSSCKFWObject *fwObject
-);
+nssCKFWObject_IsTokenObject(
+ NSSCKFWObject *fwObject);
/*
* nssCKFWObject_GetAttributeCount
*
*/
NSS_EXTERN CK_ULONG
-nssCKFWObject_GetAttributeCount
-(
- NSSCKFWObject *fwObject,
- CK_RV *pError
-);
+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_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_GetAttributeSize(
+ NSSCKFWObject *fwObject,
+ CK_ATTRIBUTE_TYPE attribute,
+ CK_RV *pError);
/*
* nssCKFWObject_GetAttribute
@@ -2274,38 +1919,32 @@ nssCKFWObject_GetAttributeSize
* specified.
*/
NSS_EXTERN NSSItem *
-nssCKFWObject_GetAttribute
-(
- NSSCKFWObject *fwObject,
- CK_ATTRIBUTE_TYPE attribute,
- NSSItem *itemOpt,
- NSSArena *arenaOpt,
- CK_RV *pError
-);
+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_SetAttribute(
+ NSSCKFWObject *fwObject,
+ NSSCKFWSession *fwSession,
+ CK_ATTRIBUTE_TYPE attribute,
+ NSSItem *value);
/*
* nssCKFWObject_GetObjectSize
*
*/
NSS_EXTERN CK_ULONG
-nssCKFWObject_GetObjectSize
-(
- NSSCKFWObject *fwObject,
- CK_RV *pError
-);
+nssCKFWObject_GetObjectSize(
+ NSSCKFWObject *fwObject,
+ CK_RV *pError);
/*
* NSSCKFWFindObjects
@@ -2328,47 +1967,39 @@ nssCKFWObject_GetObjectSize
*
*/
NSS_EXTERN NSSCKFWFindObjects *
-nssCKFWFindObjects_Create
-(
- NSSCKFWSession *fwSession,
- NSSCKFWToken *fwToken,
- NSSCKFWInstance *fwInstance,
- NSSCKMDFindObjects *mdFindObjects1,
- NSSCKMDFindObjects *mdFindObjects2,
- CK_RV *pError
-);
+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_Destroy(
+ NSSCKFWFindObjects *fwFindObjects);
/*
* nssCKFWFindObjects_GetMDFindObjects
*
*/
NSS_EXTERN NSSCKMDFindObjects *
-nssCKFWFindObjects_GetMDFindObjects
-(
- NSSCKFWFindObjects *fwFindObjects
-);
+nssCKFWFindObjects_GetMDFindObjects(
+ NSSCKFWFindObjects *fwFindObjects);
/*
* nssCKFWFindObjects_Next
*
*/
NSS_EXTERN NSSCKFWObject *
-nssCKFWFindObjects_Next
-(
- NSSCKFWFindObjects *fwFindObjects,
- NSSArena *arenaOpt,
- CK_RV *pError
-);
+nssCKFWFindObjects_Next(
+ NSSCKFWFindObjects *fwFindObjects,
+ NSSArena *arenaOpt,
+ CK_RV *pError);
/*
* NSSCKFWMutex
@@ -2385,42 +2016,34 @@ nssCKFWFindObjects_Next
*
*/
NSS_EXTERN NSSCKFWMutex *
-nssCKFWMutex_Create
-(
- CK_C_INITIALIZE_ARGS_PTR pInitArgs,
- CryptokiLockingState LockingState,
- NSSArena *arena,
- CK_RV *pError
-);
+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_Destroy(
+ NSSCKFWMutex *mutex);
/*
* nssCKFWMutex_Lock
*
*/
NSS_EXTERN CK_RV
-nssCKFWMutex_Lock
-(
- NSSCKFWMutex *mutex
-);
+nssCKFWMutex_Lock(
+ NSSCKFWMutex *mutex);
/*
* nssCKFWMutex_Unlock
*
*/
NSS_EXTERN CK_RV
-nssCKFWMutex_Unlock
-(
- NSSCKFWMutex *mutex
-);
+nssCKFWMutex_Unlock(
+ NSSCKFWMutex *mutex);
#endif /* CKFW_H */
diff --git a/nss/lib/ckfw/ckfwm.h b/nss/lib/ckfw/ckfwm.h
index ed0aec3..7b14d20 100644
--- a/nss/lib/ckfw/ckfwm.h
+++ b/nss/lib/ckfw/ckfwm.h
@@ -41,88 +41,72 @@
*
*/
NSS_EXTERN nssCKFWHash *
-nssCKFWHash_Create
-(
- NSSCKFWInstance *fwInstance,
- NSSArena *arena,
- CK_RV *pError
-);
+nssCKFWHash_Create(
+ NSSCKFWInstance *fwInstance,
+ NSSArena *arena,
+ CK_RV *pError);
/*
* nssCKFWHash_Destroy
*
*/
NSS_EXTERN void
-nssCKFWHash_Destroy
-(
- nssCKFWHash *hash
-);
+nssCKFWHash_Destroy(
+ nssCKFWHash *hash);
/*
* nssCKFWHash_Add
*
*/
NSS_EXTERN CK_RV
-nssCKFWHash_Add
-(
- nssCKFWHash *hash,
- const void *key,
- const void *value
-);
+nssCKFWHash_Add(
+ nssCKFWHash *hash,
+ const void *key,
+ const void *value);
/*
* nssCKFWHash_Remove
*
*/
NSS_EXTERN void
-nssCKFWHash_Remove
-(
- nssCKFWHash *hash,
- const void *it
-);
+nssCKFWHash_Remove(
+ nssCKFWHash *hash,
+ const void *it);
/*
* nssCKFWHash_Count
*
*/
NSS_EXTERN CK_ULONG
-nssCKFWHash_Count
-(
- nssCKFWHash *hash
-);
+nssCKFWHash_Count(
+ nssCKFWHash *hash);
/*
* nssCKFWHash_Exists
*
*/
NSS_EXTERN CK_BBOOL
-nssCKFWHash_Exists
-(
- nssCKFWHash *hash,
- const void *it
-);
+nssCKFWHash_Exists(
+ nssCKFWHash *hash,
+ const void *it);
/*
* nssCKFWHash_Lookup
*
*/
NSS_EXTERN void *
-nssCKFWHash_Lookup
-(
- nssCKFWHash *hash,
- const void *it
-);
+nssCKFWHash_Lookup(
+ nssCKFWHash *hash,
+ const void *it);
/*
* nssCKFWHash_Iterate
*
*/
NSS_EXTERN void
-nssCKFWHash_Iterate
-(
- nssCKFWHash *hash,
- nssCKFWHashIterator fcn,
- void *closure
-);
+nssCKFWHash_Iterate(
+ nssCKFWHash *hash,
+ nssCKFWHashIterator fcn,
+ void *closure);
#endif /* CKFWM_H */
diff --git a/nss/lib/ckfw/ckfwtm.h b/nss/lib/ckfw/ckfwtm.h
index ac8f550..6702984 100644
--- a/nss/lib/ckfw/ckfwtm.h
+++ b/nss/lib/ckfw/ckfwtm.h
@@ -18,6 +18,6 @@
struct nssCKFWHashStr;
typedef struct nssCKFWHashStr nssCKFWHash;
-typedef void (PR_CALLBACK *nssCKFWHashIterator)(const void *key, void *value, void *closure);
+typedef void(PR_CALLBACK *nssCKFWHashIterator)(const void *key, void *value, void *closure);
#endif /* CKFWTM_H */
diff --git a/nss/lib/ckfw/ckmd.h b/nss/lib/ckfw/ckmd.h
index 0a6dc90..820cf90 100644
--- a/nss/lib/ckfw/ckmd.h
+++ b/nss/lib/ckfw/ckmd.h
@@ -11,22 +11,18 @@
*/
NSS_EXTERN NSSCKMDObject *
-nssCKMDSessionObject_Create
-(
- NSSCKFWToken *fwToken,
- NSSArena *arena,
- CK_ATTRIBUTE_PTR attributes,
- CK_ULONG ulCount,
- CK_RV *pError
-);
+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
-);
+nssCKMDFindSessionObjects_Create(
+ NSSCKFWToken *fwToken,
+ CK_ATTRIBUTE_PTR pTemplate,
+ CK_ULONG ulCount,
+ CK_RV *pError);
#endif /* CKMD_H */
diff --git a/nss/lib/ckfw/crypto.c b/nss/lib/ckfw/crypto.c
index d97cf6c..66afb77 100644
--- a/nss/lib/ckfw/crypto.c
+++ b/nss/lib/ckfw/crypto.c
@@ -35,15 +35,15 @@
*/
struct NSSCKFWCryptoOperationStr {
- /* NSSArena *arena; */
- NSSCKMDCryptoOperation *mdOperation;
- NSSCKMDSession *mdSession;
- NSSCKFWSession *fwSession;
- NSSCKMDToken *mdToken;
- NSSCKFWToken *fwToken;
- NSSCKMDInstance *mdInstance;
- NSSCKFWInstance *fwInstance;
- NSSCKFWCryptoOperationType type;
+ /* NSSArena *arena; */
+ NSSCKMDCryptoOperation *mdOperation;
+ NSSCKMDSession *mdSession;
+ NSSCKFWSession *fwSession;
+ NSSCKMDToken *mdToken;
+ NSSCKFWToken *fwToken;
+ NSSCKMDInstance *mdInstance;
+ NSSCKFWInstance *fwInstance;
+ NSSCKFWCryptoOperationType type;
};
/*
@@ -51,290 +51,268 @@ struct NSSCKFWCryptoOperationStr {
*/
NSS_EXTERN NSSCKFWCryptoOperation *
nssCKFWCryptoOperation_Create(
- NSSCKMDCryptoOperation *mdOperation,
- NSSCKMDSession *mdSession,
- NSSCKFWSession *fwSession,
- NSSCKMDToken *mdToken,
- NSSCKFWToken *fwToken,
- NSSCKMDInstance *mdInstance,
- NSSCKFWInstance *fwInstance,
- NSSCKFWCryptoOperationType type,
- CK_RV *pError
-)
+ 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 *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
-)
+nssCKFWCryptoOperation_Destroy(
+ NSSCKFWCryptoOperation *fwOperation)
{
- if ((NSSCKMDCryptoOperation *) NULL != fwOperation->mdOperation) {
- if (fwOperation->mdOperation->Destroy) {
- fwOperation->mdOperation->Destroy(
- fwOperation->mdOperation,
- fwOperation,
- fwOperation->mdInstance,
- fwOperation->fwInstance);
+ if ((NSSCKMDCryptoOperation *)NULL != fwOperation->mdOperation) {
+ if (fwOperation->mdOperation->Destroy) {
+ fwOperation->mdOperation->Destroy(
+ fwOperation->mdOperation,
+ fwOperation,
+ fwOperation->mdInstance,
+ fwOperation->fwInstance);
+ }
}
- }
- nss_ZFreeIf(fwOperation);
+ nss_ZFreeIf(fwOperation);
}
/*
* nssCKFWCryptoOperation_GetMDCryptoOperation
*/
NSS_EXTERN NSSCKMDCryptoOperation *
-nssCKFWCryptoOperation_GetMDCryptoOperation
-(
- NSSCKFWCryptoOperation *fwOperation
-)
+nssCKFWCryptoOperation_GetMDCryptoOperation(
+ NSSCKFWCryptoOperation *fwOperation)
{
- return fwOperation->mdOperation;
+ return fwOperation->mdOperation;
}
/*
* nssCKFWCryptoOperation_GetType
*/
NSS_EXTERN NSSCKFWCryptoOperationType
-nssCKFWCryptoOperation_GetType
-(
- NSSCKFWCryptoOperation *fwOperation
-)
+nssCKFWCryptoOperation_GetType(
+ NSSCKFWCryptoOperation *fwOperation)
{
- return fwOperation->type;
+ return fwOperation->type;
}
/*
* nssCKFWCryptoOperation_GetFinalLength
*/
NSS_EXTERN CK_ULONG
-nssCKFWCryptoOperation_GetFinalLength
-(
- NSSCKFWCryptoOperation *fwOperation,
- CK_RV *pError
-)
+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);
+ 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
-)
+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);
+ 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
-)
+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);
+ 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
-)
+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);
+ 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
-)
+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);
+ 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 */
-)
+nssCKFWCryptoOperation_DigestKey(
+ NSSCKFWCryptoOperation *fwOperation,
+ NSSCKFWObject *fwObject /* Key */
+ )
{
- NSSCKMDObject *mdObject;
+ 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);
+ 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
-)
+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);
+ 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
-)
+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);
+ 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/nss/lib/ckfw/dbm/anchor.c b/nss/lib/ckfw/dbm/anchor.c
index f004b1e..c904d25 100644
--- a/nss/lib/ckfw/dbm/anchor.c
+++ b/nss/lib/ckfw/dbm/anchor.c
@@ -6,7 +6,7 @@
* 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
+ * shared library, which is required for dynamic loading. See the
* comments in nssck.api for more information.
*/
diff --git a/nss/lib/ckfw/dbm/ckdbm.h b/nss/lib/ckfw/dbm/ckdbm.h
index 4f9df93..8c2607c 100644
--- a/nss/lib/ckfw/dbm/ckdbm.h
+++ b/nss/lib/ckfw/dbm/ckdbm.h
@@ -29,220 +29,182 @@ 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;
+ 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;
+ 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 */
+ 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;
+ 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;
+ 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;
+ 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;
+ 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;
+ 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;
+ 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_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_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_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_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_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_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_dbm_db_close(
+ nss_dbm_db_t *db);
NSS_EXTERN CK_VERSION
-nss_dbm_db_get_format_version
-(
- nss_dbm_db_t *db
-);
+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_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_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_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_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_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_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_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_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_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_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
-);
+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/nss/lib/ckfw/dbm/db.c b/nss/lib/ckfw/dbm/db.c
index 8d0a6cb..bbf2b95 100644
--- a/nss/lib/ckfw/dbm/db.c
+++ b/nss/lib/ckfw/dbm/db.c
@@ -5,303 +5,288 @@
#include "ckdbm.h"
#define PREFIX_METADATA "0000"
-#define PREFIX_OBJECT "0001"
-#define PREFIX_INDEX "0002"
+#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;
+ 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_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_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
-)
+nss_dbm_db_close(
+ nss_dbm_db_t *db)
{
- if( (NSSCKFWMutex *)NULL != db->crustylock ) {
- (void)NSSCKFWMutex_Destroy(db->crustylock);
- }
+ if ((NSSCKFWMutex *)NULL != db->crustylock) {
+ (void)NSSCKFWMutex_Destroy(db->crustylock);
+ }
- if( (DB *)NULL != db->db ) {
- (void)db->db->close(db->db);
- }
+ if ((DB *)NULL != db->db) {
+ (void)db->db->close(db->db);
+ }
- nss_ZFreeIf(db);
+ nss_ZFreeIf(db);
}
NSS_IMPLEMENT CK_VERSION
-nss_dbm_db_get_format_version
-(
- nss_dbm_db_t *db
-)
+nss_dbm_db_get_format_version(
+ nss_dbm_db_t *db)
{
- CK_VERSION rv;
- DBT k, v;
- int dbrv;
- char buffer[64];
+ CK_VERSION rv;
+ DBT k, v;
+ int dbrv;
+ char buffer[64];
+
+ rv.major = rv.minor = 0;
- 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));
- 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;
+ }
- /* 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.. */
+ ;
+ }
- 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);
}
- (void)NSSCKFWMutex_Unlock(db->crustylock);
- }
-
- return rv;
+ return rv;
}
NSS_IMPLEMENT CK_RV
-nss_dbm_db_set_label
-(
- nss_dbm_db_t *db,
- NSSUTF8 *label
-)
+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 */
- {
- rv = NSSCKFWMutex_Lock(db->crustylock);
- if( CKR_OK != rv ) {
- return rv;
- }
+ CK_RV rv;
+ DBT k, v;
+ int dbrv;
- dbrv = db->db->put(db->db, &k, &v, 0);
- if( 0 != dbrv ) {
- rv = CKR_DEVICE_ERROR;
- }
+ 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);
- dbrv = db->db->sync(db->db, 0);
- if( 0 != dbrv ) {
- rv = CKR_DEVICE_ERROR;
- }
+ /* Locked region */
+ {
+ rv = NSSCKFWMutex_Lock(db->crustylock);
+ if (CKR_OK != rv) {
+ 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);
- }
+ (void)NSSCKFWMutex_Unlock(db->crustylock);
+ }
- return rv;
+ return rv;
}
NSS_IMPLEMENT NSSUTF8 *
-nss_dbm_db_get_label
-(
- nss_dbm_db_t *db,
- NSSArena *arena,
- CK_RV *pError
-)
+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);
+ NSSUTF8 *rv = (NSSUTF8 *)NULL;
+ DBT k, v;
+ int dbrv;
- /* Locked region */
- {
- if( CKR_OK != NSSCKFWMutex_Lock(db->crustylock) ) {
- return rv;
- }
+ k.data = PREFIX_METADATA "Label";
+ k.size = nssUTF8_Size((NSSUTF8 *)k.data, (PRStatus *)NULL);
- 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;
- ;
- }
+ /* 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);
- }
+ (void)NSSCKFWMutex_Unlock(db->crustylock);
+ }
- return rv;
+ return rv;
}
NSS_IMPLEMENT CK_RV
-nss_dbm_db_delete_object
-(
- nss_dbm_dbt_t *dbt
-)
+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;
- }
+ CK_RV rv;
+ int dbrv;
- dbrv = dbt->my_db->db->del(dbt->my_db->db, &dbt->dbt, 0);
- if( 0 != dbrv ) {
- rv = CKR_DEVICE_ERROR;
- goto done;
- }
+ /* Locked region */
+ {
+ rv = NSSCKFWMutex_Lock(dbt->my_db->crustylock);
+ if (CKR_OK != rv) {
+ return rv;
+ }
- dbrv = dbt->my_db->db->sync(dbt->my_db->db, 0);
- if( 0 != dbrv ) {
- rv = CKR_DEVICE_ERROR;
- goto done;
- }
+ dbrv = dbt->my_db->db->del(dbt->my_db->db, &dbt->dbt, 0);
+ if (0 != dbrv) {
+ rv = CKR_DEVICE_ERROR;
+ goto done;
+ }
- done:
- (void)NSSCKFWMutex_Unlock(dbt->my_db->crustylock);
- }
+ dbrv = dbt->my_db->db->sync(dbt->my_db->db, 0);
+ if (0 != dbrv) {
+ rv = CKR_DEVICE_ERROR;
+ goto done;
+ }
- return rv;
+ 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
-)
+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;
+ CK_ULONG rv;
+ DBT k, v;
+ CK_ULONG align = 0, id, myid;
+ struct handle *hp;
+
+ if (sizeof(struct handle) != dbt->size) {
+ return EINVAL;
}
- k.data = PREFIX_METADATA "LastID";
- k.size = nssUTF8_Size((NSSUTF8 *)k.data, (PRStatus *)NULL);
- (void)memset(&v, 0, sizeof(v));
+ /* Locked region */
+ {
+ *pError = NSSCKFWMutex_Lock(db->crustylock);
+ if (CKR_OK != *pError) {
+ return EINVAL;
+ }
- 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;
- }
+ 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);
+ 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->put(db->db, &k, &v, 0);
+ if (0 != rv) {
+ goto done;
+ }
- rv = db->db->sync(db->db, 0);
- if( 0 != rv ) {
- goto done;
- }
+ rv = db->db->sync(db->db, 0);
+ if (0 != rv) {
+ goto done;
+ }
- done:
- (void)NSSCKFWMutex_Unlock(db->crustylock);
- }
+ done:
+ (void)NSSCKFWMutex_Unlock(db->crustylock);
+ }
- if( 0 != rv ) {
- return rv;
- }
+ if (0 != rv) {
+ return rv;
+ }
- hp = (struct handle *)dbt->data;
- (void)memcpy(&hp->prefix[0], PREFIX_OBJECT, 4);
- hp->id = myid;
+ hp = (struct handle *)dbt->data;
+ (void)memcpy(&hp->prefix[0], PREFIX_OBJECT, 4);
+ hp->id = myid;
- return 0;
+ return 0;
}
/*
@@ -311,723 +296,774 @@ nss_dbm_db_new_handle
* will have to be augmentable or overridable by a Module.
*/
-enum swap_type { type_byte, type_short, type_long, type_opaque };
+enum swap_type { type_byte,
+ type_short,
+ type_long,
+ type_opaque };
static enum swap_type
-nss_dbm_db_swap_type
-(
- CK_ATTRIBUTE_TYPE 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;
- }
+ 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
-)
+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;
+ 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
-)
+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;
+ 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
-)
+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;
+ 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;
}
-
- 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;
-}
+ 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
-)
+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;
+ 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;
}
- *pdbrv = db->db->put(db->db, &rv->dbt, &object, 0);
- if( 0 != *pdbrv ) {
- *pError = CKR_DEVICE_ERROR;
+ 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;
}
- (void)db->db->sync(db->db, 0);
+ *pdbrv = nss_dbm_db_new_handle(db, &rv->dbt, pError);
+ if (0 != *pdbrv) {
+ return (nss_dbm_dbt_t *)NULL;
+ }
- (void)NSSCKFWMutex_Unlock(db->crustylock);
- }
+ tmparena = NSSArena_Create();
+ if ((NSSArena *)NULL == tmparena) {
+ *pError = CKR_HOST_MEMORY;
+ return (nss_dbm_dbt_t *)NULL;
+ }
- loser:
- if( (NSSArena *)NULL != tmparena ) {
- (void)NSSArena_Destroy(tmparena);
- }
+ *pError = nss_dbm_db_wrap_object(tmparena, pTemplate, ulAttributeCount, &object);
+ if (CKR_OK != *pError) {
+ return (nss_dbm_dbt_t *)NULL;
+ }
- return rv;
-}
+ /* 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
-)
+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;
+ CK_RV rv = CKR_OK;
- if( (nss_dbm_db_t *)NULL != db ) {
- DBT k, v;
+ if ((nss_dbm_db_t *)NULL != db) {
+ DBT k, v;
- rv = NSSCKFWMutex_Lock(db->crustylock);
- if( CKR_OK != rv ) {
- return rv;
- }
+ 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;
+ *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;
}
- if( 0 != memcmp(pTemplate[i].pValue, pt[j].pValue, pt[j].ulValueLen) ) {
- goto nomatch;
+
+ tmparena = NSSArena_Create();
+
+ rv = nss_dbm_db_unwrap_object(tmparena, &v, &pt, &ulac);
+ if (CKR_OK != rv) {
+ goto loser;
}
- break;
- }
- }
- if( j == ulac ) {
- goto nomatch;
- }
- }
- /* entire template matches */
- {
- struct nss_dbm_dbt_node *node;
+ 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;
+ }
+ }
- node = nss_ZNEW(find->arena, struct nss_dbm_dbt_node);
- if( (struct nss_dbm_dbt_node *)NULL == node ) {
- rv = CKR_HOST_MEMORY;
- goto loser;
- }
+ /* 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;
+ }
- node->dbt = nss_ZNEW(find->arena, nss_dbm_dbt_t);
- if( (nss_dbm_dbt_t *)NULL == node->dbt ) {
- rv = CKR_HOST_MEMORY;
- goto loser;
+ nomatch:
+ if ((NSSArena *)NULL != tmparena) {
+ (void)NSSArena_Destroy(tmparena);
+ }
+ *pdbrv = db->db->seq(db->db, &k, &v, R_NEXT);
}
-
- 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;
+
+ if (*pdbrv < 0) {
+ rv = CKR_DEVICE_ERROR;
+ goto loser;
}
- (void)memcpy(node->dbt->dbt.data, k.data, k.size);
+ rv = CKR_OK;
- node->dbt->my_db = db;
+ loser:
+ (void)NSSCKFWMutex_Unlock(db->crustylock);
+ }
- node->next = find->found;
- find->found = node;
- }
+ return rv;
+}
- nomatch:
- if( (NSSArena *)NULL != tmparena ) {
- (void)NSSArena_Destroy(tmparena);
- }
- *pdbrv = db->db->seq(db->db, &k, &v, R_NEXT);
+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;
}
- if( *pdbrv < 0 ) {
- rv = CKR_DEVICE_ERROR;
- goto loser;
+ dbrv = dbt->my_db->db->get(dbt->my_db->db, &dbt->dbt, &object, 0);
+ if (0 == dbrv) {
+ rv = CK_TRUE;
+ } else {
+ rv = CK_FALSE;
}
- rv = CKR_OK;
-
- loser:
- (void)NSSCKFWMutex_Unlock(db->crustylock);
- }
-
- return rv;
-}
+ (void)NSSCKFWMutex_Unlock(dbt->my_db->crustylock);
-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;
+ return rv;
}
NSS_IMPLEMENT CK_ULONG
-nss_dbm_db_get_object_attribute_count
-(
- nss_dbm_dbt_t *dbt,
- CK_RV *pError,
- CK_ULONG *pdbrv
-)
+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;
- }
+ CK_ULONG rv = 0;
+ DBT object;
+ CK_ULONG *pulData;
- *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;
- }
+ /* Locked region */
+ {
+ *pError = NSSCKFWMutex_Lock(dbt->my_db->crustylock);
+ if (CKR_OK != *pError) {
+ return rv;
+ }
- pulData = (CK_ULONG *)object.data;
- rv = ntohl(pulData[0]);
+ *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;
+ }
- done:
- (void)NSSCKFWMutex_Unlock(dbt->my_db->crustylock);
- }
+ pulData = (CK_ULONG *)object.data;
+ rv = ntohl(pulData[0]);
- return rv;
+ 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
-)
+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;
- }
+ CK_RV rv = CKR_OK;
+ DBT object;
+ CK_ULONG *pulData;
+ CK_ULONG n, i;
- *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;
- }
+ /* Locked region */
+ {
+ rv = NSSCKFWMutex_Lock(dbt->my_db->crustylock);
+ if (CKR_OK != rv) {
+ return rv;
+ }
- pulData = (CK_ULONG *)object.data;
- n = ntohl(pulData[0]);
+ *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;
+ }
- if( ulCount < n ) {
- rv = CKR_BUFFER_TOO_SMALL;
- goto done;
- }
+ pulData = (CK_ULONG *)object.data;
+ n = ntohl(pulData[0]);
- for( i = 0; i < n; i++ ) {
- typeArray[i] = ntohl(pulData[1 + i*3]);
- }
+ if (ulCount < n) {
+ rv = CKR_BUFFER_TOO_SMALL;
+ goto done;
+ }
- done:
- (void)NSSCKFWMutex_Unlock(dbt->my_db->crustylock);
- }
+ for (i = 0; i < n; i++) {
+ typeArray[i] = ntohl(pulData[1 + i * 3]);
+ }
+
+ done:
+ (void)NSSCKFWMutex_Unlock(dbt->my_db->crustylock);
+ }
- return rv;
+ 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
-)
+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;
- }
+ CK_ULONG rv = 0;
+ DBT object;
+ CK_ULONG *pulData;
+ CK_ULONG n, i;
- *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;
- }
+ /* Locked region */
+ {
+ *pError = NSSCKFWMutex_Lock(dbt->my_db->crustylock);
+ if (CKR_OK != *pError) {
+ return rv;
+ }
- pulData = (CK_ULONG *)object.data;
- n = ntohl(pulData[0]);
+ *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;
+ }
- for( i = 0; i < n; i++ ) {
- if( type == ntohl(pulData[1 + i*3]) ) {
- rv = ntohl(pulData[2 + i*3]);
- }
- }
+ pulData = (CK_ULONG *)object.data;
+ n = ntohl(pulData[0]);
- if( i == n ) {
- *pError = CKR_ATTRIBUTE_TYPE_INVALID;
- goto done;
- }
+ for (i = 0; i < n; i++) {
+ if (type == ntohl(pulData[1 + i * 3])) {
+ rv = ntohl(pulData[2 + i * 3]);
+ }
+ }
- done:
- (void)NSSCKFWMutex_Unlock(dbt->my_db->crustylock);
- }
+ if (i == n) {
+ *pError = CKR_ATTRIBUTE_TYPE_INVALID;
+ goto done;
+ }
+
+ done:
+ (void)NSSCKFWMutex_Unlock(dbt->my_db->crustylock);
+ }
- return rv;
+ 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
-)
+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;
- }
+ 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;
- }
+ *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;
- }
+ *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;
+ 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;
+ }
}
- rv->size = pTemplate[i].ulValueLen;
- rv->data = nss_ZAlloc(arena, rv->size);
- if( (void *)NULL == rv->data ) {
- *pError = CKR_HOST_MEMORY;
- goto done;
+ if (ulAttributeCount == i) {
+ *pError = CKR_ATTRIBUTE_TYPE_INVALID;
+ 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);
- }
+ done:
+ (void)NSSCKFWMutex_Unlock(dbt->my_db->crustylock);
+ }
- loser:
- if( (NSSArena *)NULL != tmp ) {
- NSSArena_Destroy(tmp);
- }
+loser:
+ if ((NSSArena *)NULL != tmp) {
+ NSSArena_Destroy(tmp);
+ }
- return rv;
+ 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
-)
+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;
- }
+ 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;
- }
+ *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;
- }
+ 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;
- }
- }
+ 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;
- }
+ 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];
- }
+ for (i = 0; i < ulAttributeCount; i++) {
+ npt[i] = pTemplate[i];
+ }
- npt[ulAttributeCount].type = type;
- npt[ulAttributeCount].ulValueLen = value->size;
- npt[ulAttributeCount].pValue = value->data;
+ npt[ulAttributeCount].type = type;
+ npt[ulAttributeCount].ulValueLen = value->size;
+ npt[ulAttributeCount].pValue = value->data;
- pTemplate = npt;
- ulAttributeCount++;
- }
+ pTemplate = npt;
+ ulAttributeCount++;
+ }
- rv = nss_dbm_db_wrap_object(tmp, pTemplate, ulAttributeCount, &object);
- if( CKR_OK != rv ) {
- goto done;
- }
+ 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;
- }
+ *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);
+ (void)dbt->my_db->db->sync(dbt->my_db->db, 0);
- done:
- (void)NSSCKFWMutex_Unlock(dbt->my_db->crustylock);
- }
+ done:
+ (void)NSSCKFWMutex_Unlock(dbt->my_db->crustylock);
+ }
- loser:
- if( (NSSArena *)NULL != tmp ) {
- NSSArena_Destroy(tmp);
- }
+loser:
+ if ((NSSArena *)NULL != tmp) {
+ NSSArena_Destroy(tmp);
+ }
- return rv;
+ return rv;
}
diff --git a/nss/lib/ckfw/dbm/find.c b/nss/lib/ckfw/dbm/find.c
index 575c0ad..8a03855 100644
--- a/nss/lib/ckfw/dbm/find.c
+++ b/nss/lib/ckfw/dbm/find.c
@@ -5,129 +5,122 @@
#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_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;
+ 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);
+ /* 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_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 ) {
+ 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;
- }
-
- 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 */
+ }
+
+ object = nss_ZNEW(arena, nss_dbm_object_t);
+ if ((nss_dbm_object_t *)NULL == object) {
+ *pError = CKR_HOST_MEMORY;
return (NSSCKMDObject *)NULL;
- }
}
- if( (struct nss_dbm_dbt_node *)NULL == node ) {
- break;
+ 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;
}
- if( nss_dbm_db_object_still_exists(node->dbt) ) {
- break;
+ 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;
}
- }
-
- 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;
+
+ (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
-)
+nss_dbm_mdFindObjects_factory(
+ nss_dbm_find_t *find,
+ CK_RV *pError)
{
- NSSCKMDFindObjects *rv;
+ NSSCKMDFindObjects *rv;
- rv = nss_ZNEW(find->arena, NSSCKMDFindObjects);
- if( (NSSCKMDFindObjects *)NULL == rv ) {
- *pError = CKR_HOST_MEMORY;
- return (NSSCKMDFindObjects *)NULL;
- }
+ 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;
+ rv->etc = (void *)find;
+ rv->Final = nss_dbm_mdFindObjects_Final;
+ rv->Next = nss_dbm_mdFindObjects_Next;
- return rv;
+ return rv;
}
diff --git a/nss/lib/ckfw/dbm/instance.c b/nss/lib/ckfw/dbm/instance.c
index 14f7af8..fbb1172 100644
--- a/nss/lib/ckfw/dbm/instance.c
+++ b/nss/lib/ckfw/dbm/instance.c
@@ -5,159 +5,143 @@
#include "ckdbm.h"
static CK_RV
-nss_dbm_mdInstance_Initialize
-(
- NSSCKMDInstance *mdInstance,
- NSSCKFWInstance *fwInstance,
- NSSUTF8 *configurationData
-)
+nss_dbm_mdInstance_Initialize(
+ NSSCKMDInstance *mdInstance,
+ NSSCKFWInstance *fwInstance,
+ NSSUTF8 *configurationData)
{
- CK_RV rv = CKR_OK;
- NSSArena *arena;
- nss_dbm_instance_t *instance;
+ 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;
+ 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_mdInstance_GetNSlots(
+ NSSCKMDInstance *mdInstance,
+ NSSCKFWInstance *fwInstance,
+ CK_RV *pError)
{
- nss_dbm_instance_t *instance = (nss_dbm_instance_t *)mdInstance->etc;
- return instance->nSlots;
+ 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
-)
+nss_dbm_mdInstance_GetCryptokiVersion(
+ NSSCKMDInstance *mdInstance,
+ NSSCKFWInstance *fwInstance)
{
- static CK_VERSION rv = { 2, 1 };
- return rv;
+ static CK_VERSION rv = { 2, 1 };
+ return rv;
}
static NSSUTF8 *
-nss_dbm_mdInstance_GetManufacturerID
-(
- NSSCKMDInstance *mdInstance,
- NSSCKFWInstance *fwInstance,
- CK_RV *pError
-)
+nss_dbm_mdInstance_GetManufacturerID(
+ NSSCKMDInstance *mdInstance,
+ NSSCKFWInstance *fwInstance,
+ CK_RV *pError)
{
- return "Mozilla Foundation";
+ return "Mozilla Foundation";
}
static NSSUTF8 *
-nss_dbm_mdInstance_GetLibraryDescription
-(
- NSSCKMDInstance *mdInstance,
- NSSCKFWInstance *fwInstance,
- CK_RV *pError
-)
+nss_dbm_mdInstance_GetLibraryDescription(
+ NSSCKMDInstance *mdInstance,
+ NSSCKFWInstance *fwInstance,
+ CK_RV *pError)
{
- return "Berkeley Database Module";
+ return "Berkeley Database Module";
}
static CK_VERSION
-nss_dbm_mdInstance_GetLibraryVersion
-(
- NSSCKMDInstance *mdInstance,
- NSSCKFWInstance *fwInstance
-)
+nss_dbm_mdInstance_GetLibraryVersion(
+ NSSCKMDInstance *mdInstance,
+ NSSCKFWInstance *fwInstance)
{
- static CK_VERSION rv = { 1, 0 }; /* My own version number */
- return rv;
+ static CK_VERSION rv = { 1, 0 }; /* My own version number */
+ return rv;
}
static CK_BBOOL
-nss_dbm_mdInstance_ModuleHandlesSessionObjects
-(
- NSSCKMDInstance *mdInstance,
- NSSCKFWInstance *fwInstance
-)
+nss_dbm_mdInstance_ModuleHandlesSessionObjects(
+ NSSCKMDInstance *mdInstance,
+ NSSCKFWInstance *fwInstance)
{
- return CK_TRUE;
+ return CK_TRUE;
}
static CK_RV
-nss_dbm_mdInstance_GetSlots
-(
- NSSCKMDInstance *mdInstance,
- NSSCKFWInstance *fwInstance,
- NSSCKMDSlot *slots[]
-)
+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;
+ 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;
+ 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 */
-};
+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/nss/lib/ckfw/dbm/object.c b/nss/lib/ckfw/dbm/object.c
index 0649d40..4f6e4d4 100644
--- a/nss/lib/ckfw/dbm/object.c
+++ b/nss/lib/ckfw/dbm/object.c
@@ -5,167 +5,151 @@
#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
-)
+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_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);
+ 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_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);
+ 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_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);
+ 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_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);
+ 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_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);
+ 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_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_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
-)
+nss_dbm_mdObject_factory(
+ nss_dbm_object_t *object,
+ CK_RV *pError)
{
- NSSCKMDObject *rv;
+ NSSCKMDObject *rv;
- rv = nss_ZNEW(object->arena, NSSCKMDObject);
- if( (NSSCKMDObject *)NULL == rv ) {
- *pError = CKR_HOST_MEMORY;
- return (NSSCKMDObject *)NULL;
- }
+ 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 */
+ 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;
+ return rv;
}
diff --git a/nss/lib/ckfw/dbm/session.c b/nss/lib/ckfw/dbm/session.c
index 6101c06..a1c2ee5 100644
--- a/nss/lib/ckfw/dbm/session.c
+++ b/nss/lib/ckfw/dbm/session.c
@@ -5,50 +5,46 @@
#include "ckdbm.h"
static void
-nss_dbm_mdSession_Close
-(
- NSSCKMDSession *mdSession,
- NSSCKFWSession *fwSession,
- NSSCKMDToken *mdToken,
- NSSCKFWToken *fwToken,
- NSSCKMDInstance *mdInstance,
- NSSCKFWInstance *fwInstance
-)
+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;
+ nss_dbm_session_t *session = (nss_dbm_session_t *)mdSession->etc;
- struct nss_dbm_dbt_node *w;
+ struct nss_dbm_dbt_node *w;
- /* Lock */
- {
- if( CKR_OK != NSSCKFWMutex_Lock(session->list_lock) ) {
- return;
- }
+ /* 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);
- }
+ 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);
- }
+ 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_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;
+ nss_dbm_session_t *session = (nss_dbm_session_t *)mdSession->etc;
+ return session->deviceError;
}
/* Login isn't needed */
@@ -60,206 +56,200 @@ nss_dbm_mdSession_GetDeviceError
/* 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_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;
+ 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 = nss_ZNEW(handyArenaPointer, nss_dbm_object_t);
+ if ((nss_dbm_object_t *)NULL == object) {
+ *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;
- }
+ object->arena = handyArenaPointer;
+ which_db = isToken ? token->slot->token_db : token->session_db;
- 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);
+ /* 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;
- }
-
- node->next = session->session_objects;
- session->session_objects = node;
-
- *pError = NSSCKFWMutex_Unlock(session->list_lock);
}
- }
- return rv;
+ 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_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;
+ 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
-)
+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;
+ 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/nss/lib/ckfw/dbm/slot.c b/nss/lib/ckfw/dbm/slot.c
index 0b7e645..06824d5 100644
--- a/nss/lib/ckfw/dbm/slot.c
+++ b/nss/lib/ckfw/dbm/slot.c
@@ -5,113 +5,101 @@
#include "ckdbm.h"
static CK_RV
-nss_dbm_mdSlot_Initialize
-(
- NSSCKMDSlot *mdSlot,
- NSSCKFWSlot *fwSlot,
- NSSCKMDInstance *mdInstance,
- NSSCKFWInstance *fwInstance
-)
+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;
+ 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;
+ return rv;
}
static void
-nss_dbm_mdSlot_Destroy
-(
- NSSCKMDSlot *mdSlot,
- NSSCKFWSlot *fwSlot,
- NSSCKMDInstance *mdInstance,
- NSSCKFWInstance *fwInstance
-)
+nss_dbm_mdSlot_Destroy(
+ NSSCKMDSlot *mdSlot,
+ NSSCKFWSlot *fwSlot,
+ NSSCKMDInstance *mdInstance,
+ NSSCKFWInstance *fwInstance)
{
- nss_dbm_slot_t *slot = (nss_dbm_slot_t *)mdSlot->etc;
+ 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;
- }
+ 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
-)
+nss_dbm_mdSlot_GetSlotDescription(
+ NSSCKMDSlot *mdSlot,
+ NSSCKFWSlot *fwSlot,
+ NSSCKMDInstance *mdInstance,
+ NSSCKFWInstance *fwInstance,
+ CK_RV *pError)
{
- return "Database";
+ return "Database";
}
static NSSUTF8 *
-nss_dbm_mdSlot_GetManufacturerID
-(
- NSSCKMDSlot *mdSlot,
- NSSCKFWSlot *fwSlot,
- NSSCKMDInstance *mdInstance,
- NSSCKFWInstance *fwInstance,
- CK_RV *pError
-)
+nss_dbm_mdSlot_GetManufacturerID(
+ NSSCKMDSlot *mdSlot,
+ NSSCKFWSlot *fwSlot,
+ NSSCKMDInstance *mdInstance,
+ NSSCKFWInstance *fwInstance,
+ CK_RV *pError)
{
- return "Berkeley";
+ return "Berkeley";
}
static CK_BBOOL
-nss_dbm_mdSlot_GetTokenPresent
-(
- NSSCKMDSlot *mdSlot,
- NSSCKFWSlot *fwSlot,
- NSSCKMDInstance *mdInstance,
- NSSCKFWInstance *fwInstance
-)
+nss_dbm_mdSlot_GetTokenPresent(
+ NSSCKMDSlot *mdSlot,
+ NSSCKFWSlot *fwSlot,
+ NSSCKMDInstance *mdInstance,
+ NSSCKFWInstance *fwInstance)
{
- nss_dbm_slot_t *slot = (nss_dbm_slot_t *)mdSlot->etc;
+ 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;
- }
+ 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
-)
+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;
+ /*
+ * 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
*
@@ -122,60 +110,56 @@ nss_dbm_mdSlot_GetRemovableDevice
*/
static NSSCKMDToken *
-nss_dbm_mdSlot_GetToken
-(
- NSSCKMDSlot *mdSlot,
- NSSCKFWSlot *fwSlot,
- NSSCKMDInstance *mdInstance,
- NSSCKFWInstance *fwInstance,
- CK_RV *pError
-)
+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_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_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;
+ 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/nss/lib/ckfw/dbm/token.c b/nss/lib/ckfw/dbm/token.c
index e033e15..6873bf0 100644
--- a/nss/lib/ckfw/dbm/token.c
+++ b/nss/lib/ckfw/dbm/token.c
@@ -5,168 +5,154 @@
#include "ckdbm.h"
static CK_RV
-nss_dbm_mdToken_Setup
-(
- NSSCKMDToken *mdToken,
- NSSCKFWToken *fwToken,
- NSSCKMDInstance *mdInstance,
- NSSCKFWInstance *fwInstance
-)
+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;
- }
+ 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? */
+ /* Add a label record if there isn't one? */
- return CKR_OK;
+ return CKR_OK;
}
static void
-nss_dbm_mdToken_Invalidate
-(
- NSSCKMDToken *mdToken,
- NSSCKFWToken *fwToken,
- NSSCKMDInstance *mdInstance,
- NSSCKFWInstance *fwInstance
-)
+nss_dbm_mdToken_Invalidate(
+ NSSCKMDToken *mdToken,
+ NSSCKFWToken *fwToken,
+ NSSCKMDInstance *mdInstance,
+ NSSCKFWInstance *fwInstance)
{
- nss_dbm_token_t *token = (nss_dbm_token_t *)mdToken->etc;
+ 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;
- }
+ 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_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;
- }
+ 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 token object data */
+ /* Wipe the session 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);
+ if ((nss_dbm_db_t *)NULL != token->session_db) {
+ nss_dbm_db_close(token->session_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;
+ 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;
}
- /* PIN is irrelevant */
+ /* Wipe the token object data */
- rv = nss_dbm_db_set_label(token->slot->token_db, label);
- if( CKR_OK != rv ) {
- return rv;
+ 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;
+ return CKR_OK;
}
static NSSUTF8 *
-nss_dbm_mdToken_GetLabel
-(
- NSSCKMDToken *mdToken,
- NSSCKFWToken *fwToken,
- NSSCKMDInstance *mdInstance,
- NSSCKFWInstance *fwInstance,
- CK_RV *pError
-)
+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;
+ 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 ((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;
- }
+ /* If no label has been set, return *something* */
+ if ((NSSUTF8 *)NULL == token->label) {
+ return token->slot->filename;
+ }
- return token->label;
+ return token->label;
}
static NSSUTF8 *
-nss_dbm_mdToken_GetManufacturerID
-(
- NSSCKMDToken *mdToken,
- NSSCKFWToken *fwToken,
- NSSCKMDInstance *mdInstance,
- NSSCKFWInstance *fwInstance,
- CK_RV *pError
-)
+nss_dbm_mdToken_GetManufacturerID(
+ NSSCKMDToken *mdToken,
+ NSSCKFWToken *fwToken,
+ NSSCKMDInstance *mdInstance,
+ NSSCKFWInstance *fwInstance,
+ CK_RV *pError)
{
- return "mozilla.org NSS";
+ return "mozilla.org NSS";
}
static NSSUTF8 *
-nss_dbm_mdToken_GetModel
-(
- NSSCKMDToken *mdToken,
- NSSCKFWToken *fwToken,
- NSSCKMDInstance *mdInstance,
- NSSCKFWInstance *fwInstance,
- CK_RV *pError
-)
+nss_dbm_mdToken_GetModel(
+ NSSCKMDToken *mdToken,
+ NSSCKFWToken *fwToken,
+ NSSCKMDInstance *mdInstance,
+ NSSCKFWInstance *fwInstance,
+ CK_RV *pError)
{
- return "dbm";
+ 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_mdToken_GetIsWriteProtected(
+ NSSCKMDToken *mdToken,
+ NSSCKFWToken *fwToken,
+ NSSCKMDInstance *mdInstance,
+ NSSCKFWInstance *fwInstance)
{
- nss_dbm_token_t *token = (nss_dbm_token_t *)mdToken->etc;
+ nss_dbm_token_t *token = (nss_dbm_token_t *)mdToken->etc;
- if( token->slot->flags & O_RDWR ) {
- return CK_FALSE;
- } else {
- return CK_TRUE;
- }
+ if (token->slot->flags & O_RDWR) {
+ return CK_FALSE;
+ } else {
+ return CK_TRUE;
+ }
}
/* GetLoginRequired defaults to CK_FALSE */
@@ -177,47 +163,41 @@ nss_dbm_mdToken_GetIsWriteProtected
/* GetSupportsDualCryptoOperations is irrelevant */
static CK_ULONG
-nss_dbm_mdToken_effectively_infinite
-(
- NSSCKMDToken *mdToken,
- NSSCKFWToken *fwToken,
- NSSCKMDInstance *mdInstance,
- NSSCKFWInstance *fwInstance
-)
+nss_dbm_mdToken_effectively_infinite(
+ NSSCKMDToken *mdToken,
+ NSSCKFWToken *fwToken,
+ NSSCKMDInstance *mdInstance,
+ NSSCKFWInstance *fwInstance)
{
- return CK_EFFECTIVELY_INFINITE;
+ return CK_EFFECTIVELY_INFINITE;
}
static CK_VERSION
-nss_dbm_mdToken_GetHardwareVersion
-(
- NSSCKMDToken *mdToken,
- NSSCKFWToken *fwToken,
- NSSCKMDInstance *mdInstance,
- NSSCKFWInstance *fwInstance
-)
+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);
+ 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_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);
+ 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 */
@@ -225,58 +205,56 @@ nss_dbm_mdToken_OpenSession
/* GetMechanism is irrelevant */
NSS_IMPLEMENT NSSCKMDToken *
-nss_dbm_mdToken_factory
-(
- nss_dbm_slot_t *slot,
- CK_RV *pError
-)
+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;
+ 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/nss/lib/ckfw/exports.gyp b/nss/lib/ckfw/exports.gyp
new file mode 100644
index 0000000..b986fd8
--- /dev/null
+++ b/nss/lib/ckfw/exports.gyp
@@ -0,0 +1,44 @@
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+{
+ 'includes': [
+ '../../coreconf/config.gypi'
+ ],
+ 'targets': [
+ {
+ 'target_name': 'lib_ckfw_exports',
+ 'type': 'none',
+ 'copies': [
+ {
+ 'files': [
+ 'nssck.api',
+ 'nssckepv.h',
+ 'nssckft.h',
+ 'nssckfw.h',
+ 'nssckfwc.h',
+ 'nssckfwt.h',
+ 'nssckg.h',
+ 'nssckmdt.h',
+ 'nssckt.h'
+ ],
+ 'destination': '<(nss_public_dist_dir)/<(module)'
+ },
+ {
+ 'files': [
+ 'ck.h',
+ 'ckfw.h',
+ 'ckfwm.h',
+ 'ckfwtm.h',
+ 'ckmd.h',
+ 'ckt.h'
+ ],
+ 'destination': '<(nss_private_dist_dir)/<(module)'
+ }
+ ]
+ }
+ ],
+ 'variables': {
+ 'module': 'nss'
+ }
+}
diff --git a/nss/lib/ckfw/find.c b/nss/lib/ckfw/find.c
index 8a8a541..55732e6 100644
--- a/nss/lib/ckfw/find.c
+++ b/nss/lib/ckfw/find.c
@@ -21,7 +21,7 @@
*
* -- public accessors --
* NSSCKFWFindObjects_GetMDFindObjects
- *
+ *
* -- implement public accessors --
* nssCKFWFindObjects_GetMDFindObjects
*
@@ -32,17 +32,17 @@
*/
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 */
+ 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
@@ -58,30 +58,24 @@ struct NSSCKFWFindObjectsStr {
*/
static CK_RV
-findObjects_add_pointer
-(
- const NSSCKFWFindObjects *fwFindObjects
-)
+findObjects_add_pointer(
+ const NSSCKFWFindObjects *fwFindObjects)
{
- return CKR_OK;
+ return CKR_OK;
}
static CK_RV
-findObjects_remove_pointer
-(
- const NSSCKFWFindObjects *fwFindObjects
-)
+findObjects_remove_pointer(
+ const NSSCKFWFindObjects *fwFindObjects)
{
- return CKR_OK;
+ return CKR_OK;
}
NSS_IMPLEMENT CK_RV
-nssCKFWFindObjects_verifyPointer
-(
- const NSSCKFWFindObjects *fwFindObjects
-)
+nssCKFWFindObjects_verifyPointer(
+ const NSSCKFWFindObjects *fwFindObjects)
{
- return CKR_OK;
+ return CKR_OK;
}
#endif /* DEBUG */
@@ -91,128 +85,123 @@ nssCKFWFindObjects_verifyPointer
*
*/
NSS_EXTERN NSSCKFWFindObjects *
-nssCKFWFindObjects_Create
-(
- NSSCKFWSession *fwSession,
- NSSCKFWToken *fwToken,
- NSSCKFWInstance *fwInstance,
- NSSCKMDFindObjects *mdFindObjects1,
- NSSCKMDFindObjects *mdFindObjects2,
- CK_RV *pError
-)
+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;
- }
+ 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;
- }
+ *pError = findObjects_add_pointer(fwFindObjects);
+ if (CKR_OK != *pError) {
+ goto loser;
+ }
#endif /* DEBUG */
- return fwFindObjects;
+ 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);
- }
- }
+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);
- }
- }
+ if (NULL != mdFindObjects2) {
+ if (NULL != mdFindObjects2->Final) {
+ fwFindObjects->mdFindObjects = mdFindObjects2;
+ mdFindObjects2->Final(mdFindObjects2, fwFindObjects, mdSession,
+ fwSession, mdToken, fwToken, mdInstance, fwInstance);
+ }
+ }
- nss_ZFreeIf(fwFindObjects);
- }
+ nss_ZFreeIf(fwFindObjects);
+ }
- if( CKR_OK == *pError ) {
- *pError = CKR_GENERAL_ERROR;
- }
+ if (CKR_OK == *pError) {
+ *pError = CKR_GENERAL_ERROR;
+ }
- return (NSSCKFWFindObjects *)NULL;
+ return (NSSCKFWFindObjects *)NULL;
}
-
/*
* nssCKFWFindObjects_Destroy
*
*/
NSS_EXTERN void
-nssCKFWFindObjects_Destroy
-(
- NSSCKFWFindObjects *fwFindObjects
-)
+nssCKFWFindObjects_Destroy(
+ NSSCKFWFindObjects *fwFindObjects)
{
#ifdef NSSDEBUG
- if( CKR_OK != nssCKFWFindObjects_verifyPointer(fwFindObjects) ) {
- return;
- }
+ if (CKR_OK != nssCKFWFindObjects_verifyPointer(fwFindObjects)) {
+ return;
+ }
#endif /* NSSDEBUG */
- (void)nssCKFWMutex_Destroy(fwFindObjects->mutex);
+ (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->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);
+
+ 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);
+ nss_ZFreeIf(fwFindObjects);
#ifdef DEBUG
- (void)findObjects_remove_pointer(fwFindObjects);
+ (void)findObjects_remove_pointer(fwFindObjects);
#endif /* DEBUG */
- return;
+ return;
}
/*
@@ -220,18 +209,16 @@ nssCKFWFindObjects_Destroy
*
*/
NSS_EXTERN NSSCKMDFindObjects *
-nssCKFWFindObjects_GetMDFindObjects
-(
- NSSCKFWFindObjects *fwFindObjects
-)
+nssCKFWFindObjects_GetMDFindObjects(
+ NSSCKFWFindObjects *fwFindObjects)
{
#ifdef NSSDEBUG
- if( CKR_OK != nssCKFWFindObjects_verifyPointer(fwFindObjects) ) {
- return (NSSCKMDFindObjects *)NULL;
- }
+ if (CKR_OK != nssCKFWFindObjects_verifyPointer(fwFindObjects)) {
+ return (NSSCKMDFindObjects *)NULL;
+ }
#endif /* NSSDEBUG */
- return fwFindObjects->mdFindObjects;
+ return fwFindObjects->mdFindObjects;
}
/*
@@ -239,89 +226,87 @@ nssCKFWFindObjects_GetMDFindObjects
*
*/
NSS_EXTERN NSSCKFWObject *
-nssCKFWFindObjects_Next
-(
- NSSCKFWFindObjects *fwFindObjects,
- NSSArena *arenaOpt,
- CK_RV *pError
-)
+nssCKFWFindObjects_Next(
+ NSSCKFWFindObjects *fwFindObjects,
+ NSSArena *arenaOpt,
+ CK_RV *pError)
{
- NSSCKMDObject *mdObject;
- NSSCKFWObject *fwObject = (NSSCKFWObject *)NULL;
- NSSArena *objArena;
+ 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 */
+ if (!pError) {
+ return (NSSCKFWObject *)NULL;
+ }
- *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;
- }
+ *pError = nssCKFWFindObjects_verifyPointer(fwFindObjects);
+ if (CKR_OK != *pError) {
+ return (NSSCKFWObject *)NULL;
+ }
+#endif /* NSSDEBUG */
- /* 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;
- }
+ *pError = nssCKFWMutex_Lock(fwFindObjects->mutex);
+ if (CKR_OK != *pError) {
+ return (NSSCKFWObject *)NULL;
}
- }
-
- 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;
+
+ 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;
+ }
}
+ }
- /* 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;
- }
+ 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:
- /*
+
+ /* 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.
@@ -336,26 +321,26 @@ nssCKFWFindObjects_Next
* 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;
+ objArena = nssCKFWToken_GetArena(fwFindObjects->fwToken, pError);
+ if (!objArena) {
+ if (CKR_OK == *pError) {
+ *pError = CKR_HOST_MEMORY;
+ }
+ goto done;
}
- goto done;
- }
-
- fwObject = nssCKFWObject_Create(objArena, mdObject,
- NULL, fwFindObjects->fwToken,
- fwFindObjects->fwInstance, pError);
- if (!fwObject) {
- if( CKR_OK == *pError ) {
- *pError = CKR_GENERAL_ERROR;
+
+ 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;
+done:
+ (void)nssCKFWMutex_Unlock(fwFindObjects->mutex);
+ return fwObject;
}
/*
@@ -364,16 +349,14 @@ nssCKFWFindObjects_Next
*/
NSS_EXTERN NSSCKMDFindObjects *
-NSSCKFWFindObjects_GetMDFindObjects
-(
- NSSCKFWFindObjects *fwFindObjects
-)
+NSSCKFWFindObjects_GetMDFindObjects(
+ NSSCKFWFindObjects *fwFindObjects)
{
#ifdef DEBUG
- if( CKR_OK != nssCKFWFindObjects_verifyPointer(fwFindObjects) ) {
- return (NSSCKMDFindObjects *)NULL;
- }
+ if (CKR_OK != nssCKFWFindObjects_verifyPointer(fwFindObjects)) {
+ return (NSSCKMDFindObjects *)NULL;
+ }
#endif /* DEBUG */
- return nssCKFWFindObjects_GetMDFindObjects(fwFindObjects);
+ return nssCKFWFindObjects_GetMDFindObjects(fwFindObjects);
}
diff --git a/nss/lib/ckfw/hash.c b/nss/lib/ckfw/hash.c
index 7d21084..50de4ce 100644
--- a/nss/lib/ckfw/hash.c
+++ b/nss/lib/ckfw/hash.c
@@ -31,24 +31,22 @@
*/
struct nssCKFWHashStr {
- NSSCKFWMutex *mutex;
+ NSSCKFWMutex *mutex;
- /*
- * The invariant that mutex protects is:
- * The count accurately reflects the hashtable state.
- */
+ /*
+ * The invariant that mutex protects is:
+ * The count accurately reflects the hashtable state.
+ */
- PLHashTable *plHashTable;
- CK_ULONG count;
+ PLHashTable *plHashTable;
+ CK_ULONG count;
};
static PLHashNumber
-nss_ckfw_identity_hash
-(
- const void *key
-)
+nss_ckfw_identity_hash(
+ const void *key)
{
- return (PLHashNumber)((char *)key - (char *)NULL);
+ return (PLHashNumber)((char *)key - (char *)NULL);
}
/*
@@ -56,53 +54,51 @@ nss_ckfw_identity_hash
*
*/
NSS_IMPLEMENT nssCKFWHash *
-nssCKFWHash_Create
-(
- NSSCKFWInstance *fwInstance,
- NSSArena *arena,
- CK_RV *pError
-)
+nssCKFWHash_Create(
+ NSSCKFWInstance *fwInstance,
+ NSSArena *arena,
+ CK_RV *pError)
{
- nssCKFWHash *rv;
+ nssCKFWHash *rv;
#ifdef NSSDEBUG
- if (!pError) {
- return (nssCKFWHash *)NULL;
- }
-
- if( PR_SUCCESS != nssArena_verifyPointer(arena) ) {
- *pError = CKR_ARGUMENTS_BAD;
- return (nssCKFWHash *)NULL;
- }
+ 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 = 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) {
+ *pError = CKR_GENERAL_ERROR;
+ }
+ (void)nss_ZFreeIf(rv);
+ return (nssCKFWHash *)NULL;
+ }
- rv->mutex = nssCKFWInstance_CreateMutex(fwInstance, arena, pError);
- if (!rv->mutex) {
- if( CKR_OK == *pError ) {
- *pError = CKR_GENERAL_ERROR;
+ 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;
}
- (void)nss_ZFreeIf(rv);
- 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;
+
+ rv->count = 0;
+
+ return rv;
}
/*
@@ -110,14 +106,12 @@ nssCKFWHash_Create
*
*/
NSS_IMPLEMENT void
-nssCKFWHash_Destroy
-(
- nssCKFWHash *hash
-)
+nssCKFWHash_Destroy(
+ nssCKFWHash *hash)
{
- (void)nssCKFWMutex_Destroy(hash->mutex);
- PL_HashTableDestroy(hash->plHashTable);
- (void)nss_ZFreeIf(hash);
+ (void)nssCKFWMutex_Destroy(hash->mutex);
+ PL_HashTableDestroy(hash->plHashTable);
+ (void)nss_ZFreeIf(hash);
}
/*
@@ -125,31 +119,29 @@ nssCKFWHash_Destroy
*
*/
NSS_IMPLEMENT CK_RV
-nssCKFWHash_Add
-(
- nssCKFWHash *hash,
- const void *key,
- const void *value
-)
+nssCKFWHash_Add(
+ nssCKFWHash *hash,
+ const void *key,
+ const void *value)
{
- CK_RV error = CKR_OK;
- PLHashEntry *he;
+ 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);
- 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;
}
/*
@@ -157,25 +149,23 @@ nssCKFWHash_Add
*
*/
NSS_IMPLEMENT void
-nssCKFWHash_Remove
-(
- nssCKFWHash *hash,
- const void *it
-)
+nssCKFWHash_Remove(
+ nssCKFWHash *hash,
+ const void *it)
{
- PRBool found;
+ PRBool found;
- if( CKR_OK != nssCKFWMutex_Lock(hash->mutex) ) {
- return;
- }
+ if (CKR_OK != nssCKFWMutex_Lock(hash->mutex)) {
+ return;
+ }
- found = PL_HashTableRemove(hash->plHashTable, it);
- if( found ) {
- hash->count--;
- }
+ found = PL_HashTableRemove(hash->plHashTable, it);
+ if (found) {
+ hash->count--;
+ }
- (void)nssCKFWMutex_Unlock(hash->mutex);
- return;
+ (void)nssCKFWMutex_Unlock(hash->mutex);
+ return;
}
/*
@@ -183,22 +173,20 @@ nssCKFWHash_Remove
*
*/
NSS_IMPLEMENT CK_ULONG
-nssCKFWHash_Count
-(
- nssCKFWHash *hash
-)
+nssCKFWHash_Count(
+ nssCKFWHash *hash)
{
- CK_ULONG count;
+ CK_ULONG count;
- if( CKR_OK != nssCKFWMutex_Lock(hash->mutex) ) {
- return (CK_ULONG)0;
- }
+ if (CKR_OK != nssCKFWMutex_Lock(hash->mutex)) {
+ return (CK_ULONG)0;
+ }
- count = hash->count;
+ count = hash->count;
- (void)nssCKFWMutex_Unlock(hash->mutex);
+ (void)nssCKFWMutex_Unlock(hash->mutex);
- return count;
+ return count;
}
/*
@@ -206,27 +194,25 @@ nssCKFWHash_Count
*
*/
NSS_IMPLEMENT CK_BBOOL
-nssCKFWHash_Exists
-(
- nssCKFWHash *hash,
- const void *it
-)
+nssCKFWHash_Exists(
+ nssCKFWHash *hash,
+ const void *it)
{
- void *value;
+ void *value;
- if( CKR_OK != nssCKFWMutex_Lock(hash->mutex) ) {
- return CK_FALSE;
- }
+ if (CKR_OK != nssCKFWMutex_Lock(hash->mutex)) {
+ return CK_FALSE;
+ }
- value = PL_HashTableLookup(hash->plHashTable, it);
+ value = PL_HashTableLookup(hash->plHashTable, it);
- (void)nssCKFWMutex_Unlock(hash->mutex);
+ (void)nssCKFWMutex_Unlock(hash->mutex);
- if (!value) {
- return CK_FALSE;
- } else {
- return CK_TRUE;
- }
+ if (!value) {
+ return CK_FALSE;
+ } else {
+ return CK_TRUE;
+ }
}
/*
@@ -234,41 +220,37 @@ nssCKFWHash_Exists
*
*/
NSS_IMPLEMENT void *
-nssCKFWHash_Lookup
-(
- nssCKFWHash *hash,
- const void *it
-)
+nssCKFWHash_Lookup(
+ nssCKFWHash *hash,
+ const void *it)
{
- void *rv;
+ void *rv;
- if( CKR_OK != nssCKFWMutex_Lock(hash->mutex) ) {
- return (void *)NULL;
- }
+ if (CKR_OK != nssCKFWMutex_Lock(hash->mutex)) {
+ return (void *)NULL;
+ }
- rv = PL_HashTableLookup(hash->plHashTable, it);
+ rv = PL_HashTableLookup(hash->plHashTable, it);
- (void)nssCKFWMutex_Unlock(hash->mutex);
+ (void)nssCKFWMutex_Unlock(hash->mutex);
- return rv;
+ return rv;
}
struct arg_str {
- nssCKFWHashIterator fcn;
- void *closure;
+ nssCKFWHashIterator fcn;
+ void *closure;
};
static PRIntn
-nss_ckfwhash_enumerator
-(
- PLHashEntry *he,
- PRIntn index,
- void *arg
-)
+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;
+ struct arg_str *as = (struct arg_str *)arg;
+ as->fcn(he->key, he->value, as->closure);
+ return HT_ENUMERATE_NEXT;
}
/*
@@ -277,24 +259,22 @@ nss_ckfwhash_enumerator
* NOTE that the iteration function will be called with the hashtable locked.
*/
NSS_IMPLEMENT void
-nssCKFWHash_Iterate
-(
- nssCKFWHash *hash,
- nssCKFWHashIterator fcn,
- void *closure
-)
+nssCKFWHash_Iterate(
+ nssCKFWHash *hash,
+ nssCKFWHashIterator fcn,
+ void *closure)
{
- struct arg_str as;
- as.fcn = fcn;
- as.closure = closure;
+ struct arg_str as;
+ as.fcn = fcn;
+ as.closure = closure;
- if( CKR_OK != nssCKFWMutex_Lock(hash->mutex) ) {
- return;
- }
+ if (CKR_OK != nssCKFWMutex_Lock(hash->mutex)) {
+ return;
+ }
- PL_HashTableEnumerateEntries(hash->plHashTable, nss_ckfwhash_enumerator, &as);
+ PL_HashTableEnumerateEntries(hash->plHashTable, nss_ckfwhash_enumerator, &as);
- (void)nssCKFWMutex_Unlock(hash->mutex);
+ (void)nssCKFWMutex_Unlock(hash->mutex);
- return;
+ return;
}
diff --git a/nss/lib/ckfw/instance.c b/nss/lib/ckfw/instance.c
index b8a5b25..cee56c9 100644
--- a/nss/lib/ckfw/instance.c
+++ b/nss/lib/ckfw/instance.c
@@ -26,6 +26,8 @@
* NSSCKFWInstance_CreateMutex
* NSSCKFWInstance_GetConfigurationData
* NSSCKFWInstance_GetInitArgs
+ * NSSCKFWInstance_DestroySessionHandle
+ * NSSCKFWInstance_FindSessionHandle
*
* -- implement public accessors --
* nssCKFWInstance_GetMDInstance
@@ -33,13 +35,13 @@
* nssCKFWInstance_MayCreatePthreads
* nssCKFWInstance_CreateMutex
* nssCKFWInstance_GetConfigurationData
- * nssCKFWInstance_GetInitArgs
+ * nssCKFWInstance_GetInitArgs
+ * nssCKFWInstance_DestroySessionHandle
+ * nssCKFWInstance_FindSessionHandle
*
* -- private accessors --
* nssCKFWInstance_CreateSessionHandle
* nssCKFWInstance_ResolveSessionHandle
- * nssCKFWInstance_DestroySessionHandle
- * nssCKFWInstance_FindSessionHandle
* nssCKFWInstance_CreateObjectHandle
* nssCKFWInstance_ResolveObjectHandle
* nssCKFWInstance_DestroyObjectHandle
@@ -60,52 +62,52 @@
*/
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;
+ 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
@@ -121,30 +123,24 @@ struct NSSCKFWInstanceStr {
*/
static CK_RV
-instance_add_pointer
-(
- const NSSCKFWInstance *fwInstance
-)
+instance_add_pointer(
+ const NSSCKFWInstance *fwInstance)
{
- return CKR_OK;
+ return CKR_OK;
}
static CK_RV
-instance_remove_pointer
-(
- const NSSCKFWInstance *fwInstance
-)
+instance_remove_pointer(
+ const NSSCKFWInstance *fwInstance)
{
- return CKR_OK;
+ return CKR_OK;
}
NSS_IMPLEMENT CK_RV
-nssCKFWInstance_verifyPointer
-(
- const NSSCKFWInstance *fwInstance
-)
+nssCKFWInstance_verifyPointer(
+ const NSSCKFWInstance *fwInstance)
{
- return CKR_OK;
+ return CKR_OK;
}
#endif /* DEBUG */
@@ -154,191 +150,189 @@ nssCKFWInstance_verifyPointer
*
*/
NSS_IMPLEMENT NSSCKFWInstance *
-nssCKFWInstance_Create
-(
- CK_C_INITIALIZE_ARGS_PTR pInitArgs,
- CryptokiLockingState LockingState,
- NSSCKMDInstance *mdInstance,
- CK_RV *pError
-)
+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;
+ 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 ((CK_RV)NULL == pError) {
+ return (NSSCKFWInstance *)NULL;
+ }
- if (!mdInstance) {
- *pError = CKR_ARGUMENTS_BAD;
- 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;
+ 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->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];
+ fwInstance->mayCreatePthreads = CK_TRUE;
+ }
- if (!mdSlot) {
- *pError = CKR_GENERAL_ERROR;
- goto loser;
+ 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;
}
- fwInstance->fwSlotList[i] = nssCKFWSlot_Create(fwInstance, mdSlot, i, pError);
- if( CKR_OK != *pError ) {
- CK_ULONG j;
+ if (mdInstance->ModuleHandlesSessionObjects) {
+ fwInstance->moduleHandlesSessionObjects =
+ mdInstance->ModuleHandlesSessionObjects(mdInstance, fwInstance);
+ } else {
+ fwInstance->moduleHandlesSessionObjects = CK_FALSE;
+ }
- for( j = 0; j < i; j++ ) {
- (void)nssCKFWSlot_Destroy(fwInstance->fwSlotList[j]);
- }
+ if (!mdInstance->GetNSlots) {
+ /* That routine is required */
+ *pError = CKR_GENERAL_ERROR;
+ goto loser;
+ }
- for( j = i; j < fwInstance->nSlots; j++ ) {
- NSSCKMDSlot *mds = fwInstance->mdSlotList[j];
- if (mds->Destroy) {
- mds->Destroy(mds, (NSSCKFWSlot *)NULL, mdInstance, fwInstance);
+ 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;
+ }
- 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;
- }
+ *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;
+ *pError = CKR_OK;
+ return fwInstance;
- nomem:
- *pError = CKR_HOST_MEMORY;
- /*FALLTHROUGH*/
- loser:
+nomem:
+ *pError = CKR_HOST_MEMORY;
+/*FALLTHROUGH*/
+loser:
- if( CK_TRUE == called_Initialize ) {
- if (mdInstance->Finalize) {
- mdInstance->Finalize(mdInstance, fwInstance);
+ if (CK_TRUE == called_Initialize) {
+ if (mdInstance->Finalize) {
+ mdInstance->Finalize(mdInstance, fwInstance);
+ }
}
- }
- if (fwInstance && fwInstance->mutex) {
- nssCKFWMutex_Destroy(fwInstance->mutex);
- }
+ if (fwInstance && fwInstance->mutex) {
+ nssCKFWMutex_Destroy(fwInstance->mutex);
+ }
- if (arena) {
- (void)NSSArena_Destroy(arena);
- }
- return (NSSCKFWInstance *)NULL;
+ if (arena) {
+ (void)NSSArena_Destroy(arena);
+ }
+ return (NSSCKFWInstance *)NULL;
}
/*
@@ -346,47 +340,45 @@ nssCKFWInstance_Create
*
*/
NSS_IMPLEMENT CK_RV
-nssCKFWInstance_Destroy
-(
- NSSCKFWInstance *fwInstance
-)
+nssCKFWInstance_Destroy(
+ NSSCKFWInstance *fwInstance)
{
#ifdef NSSDEBUG
- CK_RV error = CKR_OK;
+ CK_RV error = CKR_OK;
#endif /* NSSDEBUG */
- CK_ULONG i;
+ CK_ULONG i;
#ifdef NSSDEBUG
- error = nssCKFWInstance_verifyPointer(fwInstance);
- if( CKR_OK != error ) {
- return error;
- }
+ error = nssCKFWInstance_verifyPointer(fwInstance);
+ if (CKR_OK != error) {
+ return error;
+ }
#endif /* NSSDEBUG */
- nssCKFWMutex_Destroy(fwInstance->mutex);
+ nssCKFWMutex_Destroy(fwInstance->mutex);
- for( i = 0; i < fwInstance->nSlots; i++ ) {
- (void)nssCKFWSlot_Destroy(fwInstance->fwSlotList[i]);
- }
+ 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->mdInstance->Finalize) {
+ fwInstance->mdInstance->Finalize(fwInstance->mdInstance, fwInstance);
+ }
- if (fwInstance->sessionHandleHash) {
- nssCKFWHash_Destroy(fwInstance->sessionHandleHash);
- }
+ if (fwInstance->sessionHandleHash) {
+ nssCKFWHash_Destroy(fwInstance->sessionHandleHash);
+ }
- if (fwInstance->objectHandleHash) {
- nssCKFWHash_Destroy(fwInstance->objectHandleHash);
- }
+ if (fwInstance->objectHandleHash) {
+ nssCKFWHash_Destroy(fwInstance->objectHandleHash);
+ }
#ifdef DEBUG
- (void)instance_remove_pointer(fwInstance);
+ (void)instance_remove_pointer(fwInstance);
#endif /* DEBUG */
- (void)NSSArena_Destroy(fwInstance->arena);
- return CKR_OK;
+ (void)NSSArena_Destroy(fwInstance->arena);
+ return CKR_OK;
}
/*
@@ -394,18 +386,16 @@ nssCKFWInstance_Destroy
*
*/
NSS_IMPLEMENT NSSCKMDInstance *
-nssCKFWInstance_GetMDInstance
-(
- NSSCKFWInstance *fwInstance
-)
+nssCKFWInstance_GetMDInstance(
+ NSSCKFWInstance *fwInstance)
{
#ifdef NSSDEBUG
- if( CKR_OK != nssCKFWInstance_verifyPointer(fwInstance) ) {
- return (NSSCKMDInstance *)NULL;
- }
+ if (CKR_OK != nssCKFWInstance_verifyPointer(fwInstance)) {
+ return (NSSCKMDInstance *)NULL;
+ }
#endif /* NSSDEBUG */
- return fwInstance->mdInstance;
+ return fwInstance->mdInstance;
}
/*
@@ -413,25 +403,23 @@ nssCKFWInstance_GetMDInstance
*
*/
NSS_IMPLEMENT NSSArena *
-nssCKFWInstance_GetArena
-(
- NSSCKFWInstance *fwInstance,
- CK_RV *pError
-)
+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;
- }
+ if (!pError) {
+ return (NSSArena *)NULL;
+ }
+
+ *pError = nssCKFWInstance_verifyPointer(fwInstance);
+ if (CKR_OK != *pError) {
+ return (NSSArena *)NULL;
+ }
#endif /* NSSDEBUG */
- *pError = CKR_OK;
- return fwInstance->arena;
+ *pError = CKR_OK;
+ return fwInstance->arena;
}
/*
@@ -439,18 +427,16 @@ nssCKFWInstance_GetArena
*
*/
NSS_IMPLEMENT CK_BBOOL
-nssCKFWInstance_MayCreatePthreads
-(
- NSSCKFWInstance *fwInstance
-)
+nssCKFWInstance_MayCreatePthreads(
+ NSSCKFWInstance *fwInstance)
{
#ifdef NSSDEBUG
- if( CKR_OK != nssCKFWInstance_verifyPointer(fwInstance) ) {
- return CK_FALSE;
- }
+ if (CKR_OK != nssCKFWInstance_verifyPointer(fwInstance)) {
+ return CK_FALSE;
+ }
#endif /* NSSDEBUG */
- return fwInstance->mayCreatePthreads;
+ return fwInstance->mayCreatePthreads;
}
/*
@@ -458,37 +444,35 @@ nssCKFWInstance_MayCreatePthreads
*
*/
NSS_IMPLEMENT NSSCKFWMutex *
-nssCKFWInstance_CreateMutex
-(
- NSSCKFWInstance *fwInstance,
- NSSArena *arena,
- CK_RV *pError
-)
+nssCKFWInstance_CreateMutex(
+ NSSCKFWInstance *fwInstance,
+ NSSArena *arena,
+ CK_RV *pError)
{
- NSSCKFWMutex *mutex;
+ NSSCKFWMutex *mutex;
#ifdef NSSDEBUG
- if (!pError) {
- return (NSSCKFWMutex *)NULL;
- }
-
- *pError = nssCKFWInstance_verifyPointer(fwInstance);
- if( CKR_OK != *pError ) {
- return (NSSCKFWMutex *)NULL;
- }
-#endif /* NSSDEBUG */
+ if (!pError) {
+ return (NSSCKFWMutex *)NULL;
+ }
- mutex = nssCKFWMutex_Create(fwInstance->pInitArgs, fwInstance->LockingState,
- arena, pError);
- if (!mutex) {
- if( CKR_OK == *pError ) {
- *pError = CKR_GENERAL_ERROR;
+ *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 (NSSCKFWMutex *)NULL;
+ }
- return mutex;
+ return mutex;
}
/*
@@ -496,18 +480,16 @@ nssCKFWInstance_CreateMutex
*
*/
NSS_IMPLEMENT NSSUTF8 *
-nssCKFWInstance_GetConfigurationData
-(
- NSSCKFWInstance *fwInstance
-)
+nssCKFWInstance_GetConfigurationData(
+ NSSCKFWInstance *fwInstance)
{
#ifdef NSSDEBUG
- if( CKR_OK != nssCKFWInstance_verifyPointer(fwInstance) ) {
- return (NSSUTF8 *)NULL;
- }
+ if (CKR_OK != nssCKFWInstance_verifyPointer(fwInstance)) {
+ return (NSSUTF8 *)NULL;
+ }
#endif /* NSSDEBUG */
- return fwInstance->configurationData;
+ return fwInstance->configurationData;
}
/*
@@ -515,15 +497,13 @@ nssCKFWInstance_GetConfigurationData
*
*/
CK_C_INITIALIZE_ARGS_PTR
-nssCKFWInstance_GetInitArgs
-(
- NSSCKFWInstance *fwInstance
-)
+nssCKFWInstance_GetInitArgs(
+ NSSCKFWInstance *fwInstance)
{
#ifdef NSSDEBUG
- if( CKR_OK != nssCKFWInstance_verifyPointer(fwInstance) ) {
- return (CK_C_INITIALIZE_ARGS_PTR)NULL;
- }
+ if (CKR_OK != nssCKFWInstance_verifyPointer(fwInstance)) {
+ return (CK_C_INITIALIZE_ARGS_PTR)NULL;
+ }
#endif /* NSSDEBUG */
return fwInstance->pInitArgs;
@@ -534,50 +514,48 @@ nssCKFWInstance_GetInitArgs
*
*/
NSS_IMPLEMENT CK_SESSION_HANDLE
-nssCKFWInstance_CreateSessionHandle
-(
- NSSCKFWInstance *fwInstance,
- NSSCKFWSession *fwSession,
- CK_RV *pError
-)
+nssCKFWInstance_CreateSessionHandle(
+ NSSCKFWInstance *fwInstance,
+ NSSCKFWSession *fwSession,
+ CK_RV *pError)
{
- CK_SESSION_HANDLE hSession;
+ 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;
- }
+ 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;
+ *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;
}
/*
@@ -585,32 +563,30 @@ nssCKFWInstance_CreateSessionHandle
*
*/
NSS_IMPLEMENT NSSCKFWSession *
-nssCKFWInstance_ResolveSessionHandle
-(
- NSSCKFWInstance *fwInstance,
- CK_SESSION_HANDLE hSession
-)
+nssCKFWInstance_ResolveSessionHandle(
+ NSSCKFWInstance *fwInstance,
+ CK_SESSION_HANDLE hSession)
{
- NSSCKFWSession *fwSession;
+ NSSCKFWSession *fwSession;
#ifdef NSSDEBUG
- if( CKR_OK != nssCKFWInstance_verifyPointer(fwInstance) ) {
- return (NSSCKFWSession *)NULL;
- }
+ if (CKR_OK != nssCKFWInstance_verifyPointer(fwInstance)) {
+ return (NSSCKFWSession *)NULL;
+ }
#endif /* NSSDEBUG */
- if( CKR_OK != nssCKFWMutex_Lock(fwInstance->mutex) ) {
- return (NSSCKFWSession *)NULL;
- }
+ if (CKR_OK != nssCKFWMutex_Lock(fwInstance->mutex)) {
+ return (NSSCKFWSession *)NULL;
+ }
- fwSession = (NSSCKFWSession *)nssCKFWHash_Lookup(
- fwInstance->sessionHandleHash, (const void *)hSession);
+ fwSession = (NSSCKFWSession *)nssCKFWHash_Lookup(
+ fwInstance->sessionHandleHash, (const void *)hSession);
- /* Assert(hSession == nssCKFWSession_GetHandle(fwSession)) */
+ /* Assert(hSession == nssCKFWSession_GetHandle(fwSession)) */
- (void)nssCKFWMutex_Unlock(fwInstance->mutex);
+ (void)nssCKFWMutex_Unlock(fwInstance->mutex);
- return fwSession;
+ return fwSession;
}
/*
@@ -618,34 +594,32 @@ nssCKFWInstance_ResolveSessionHandle
*
*/
NSS_IMPLEMENT void
-nssCKFWInstance_DestroySessionHandle
-(
- NSSCKFWInstance *fwInstance,
- CK_SESSION_HANDLE hSession
-)
+nssCKFWInstance_DestroySessionHandle(
+ NSSCKFWInstance *fwInstance,
+ CK_SESSION_HANDLE hSession)
{
- NSSCKFWSession *fwSession;
+ NSSCKFWSession *fwSession;
#ifdef NSSDEBUG
- if( CKR_OK != nssCKFWInstance_verifyPointer(fwInstance) ) {
- return;
- }
+ if (CKR_OK != nssCKFWInstance_verifyPointer(fwInstance)) {
+ return;
+ }
#endif /* NSSDEBUG */
- if( CKR_OK != nssCKFWMutex_Lock(fwInstance->mutex) ) {
- return;
- }
+ 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);
- }
+ 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);
+ (void)nssCKFWMutex_Unlock(fwInstance->mutex);
- return;
+ return;
}
/*
@@ -653,24 +627,22 @@ nssCKFWInstance_DestroySessionHandle
*
*/
NSS_IMPLEMENT CK_SESSION_HANDLE
-nssCKFWInstance_FindSessionHandle
-(
- NSSCKFWInstance *fwInstance,
- NSSCKFWSession *fwSession
-)
+nssCKFWInstance_FindSessionHandle(
+ NSSCKFWInstance *fwInstance,
+ NSSCKFWSession *fwSession)
{
#ifdef NSSDEBUG
- if( CKR_OK != nssCKFWInstance_verifyPointer(fwInstance) ) {
- return (CK_SESSION_HANDLE)0;
- }
+ if (CKR_OK != nssCKFWInstance_verifyPointer(fwInstance)) {
+ return (CK_SESSION_HANDLE)0;
+ }
- if( CKR_OK != nssCKFWSession_verifyPointer(fwSession) ) {
- 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? */
+ return nssCKFWSession_GetHandle(fwSession);
+ /* look it up and assert? */
}
/*
@@ -678,49 +650,47 @@ nssCKFWInstance_FindSessionHandle
*
*/
NSS_IMPLEMENT CK_OBJECT_HANDLE
-nssCKFWInstance_CreateObjectHandle
-(
- NSSCKFWInstance *fwInstance,
- NSSCKFWObject *fwObject,
- CK_RV *pError
-)
+nssCKFWInstance_CreateObjectHandle(
+ NSSCKFWInstance *fwInstance,
+ NSSCKFWObject *fwObject,
+ CK_RV *pError)
{
- CK_OBJECT_HANDLE hObject;
+ 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;
- }
+ 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;
+ *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;
}
/*
@@ -728,31 +698,29 @@ nssCKFWInstance_CreateObjectHandle
*
*/
NSS_IMPLEMENT NSSCKFWObject *
-nssCKFWInstance_ResolveObjectHandle
-(
- NSSCKFWInstance *fwInstance,
- CK_OBJECT_HANDLE hObject
-)
+nssCKFWInstance_ResolveObjectHandle(
+ NSSCKFWInstance *fwInstance,
+ CK_OBJECT_HANDLE hObject)
{
- NSSCKFWObject *fwObject;
+ NSSCKFWObject *fwObject;
#ifdef NSSDEBUG
- if( CKR_OK != nssCKFWInstance_verifyPointer(fwInstance) ) {
- return (NSSCKFWObject *)NULL;
- }
+ if (CKR_OK != nssCKFWInstance_verifyPointer(fwInstance)) {
+ return (NSSCKFWObject *)NULL;
+ }
#endif /* NSSDEBUG */
- if( CKR_OK != nssCKFWMutex_Lock(fwInstance->mutex) ) {
- return (NSSCKFWObject *)NULL;
- }
+ if (CKR_OK != nssCKFWMutex_Lock(fwInstance->mutex)) {
+ return (NSSCKFWObject *)NULL;
+ }
- fwObject = (NSSCKFWObject *)nssCKFWHash_Lookup(
- fwInstance->objectHandleHash, (const void *)hObject);
+ fwObject = (NSSCKFWObject *)nssCKFWHash_Lookup(
+ fwInstance->objectHandleHash, (const void *)hObject);
- /* Assert(hObject == nssCKFWObject_GetHandle(fwObject)) */
+ /* Assert(hObject == nssCKFWObject_GetHandle(fwObject)) */
- (void)nssCKFWMutex_Unlock(fwInstance->mutex);
- return fwObject;
+ (void)nssCKFWMutex_Unlock(fwInstance->mutex);
+ return fwObject;
}
/*
@@ -760,46 +728,44 @@ nssCKFWInstance_ResolveObjectHandle
*
*/
NSS_IMPLEMENT CK_RV
-nssCKFWInstance_ReassignObjectHandle
-(
- NSSCKFWInstance *fwInstance,
- CK_OBJECT_HANDLE hObject,
- NSSCKFWObject *fwObject
-)
+nssCKFWInstance_ReassignObjectHandle(
+ NSSCKFWInstance *fwInstance,
+ CK_OBJECT_HANDLE hObject,
+ NSSCKFWObject *fwObject)
{
- CK_RV error = CKR_OK;
- NSSCKFWObject *oldObject;
+ CK_RV error = CKR_OK;
+ NSSCKFWObject *oldObject;
#ifdef NSSDEBUG
- error = nssCKFWInstance_verifyPointer(fwInstance);
- if( CKR_OK != error ) {
- return error;
- }
+ error = nssCKFWInstance_verifyPointer(fwInstance);
+ if (CKR_OK != error) {
+ return error;
+ }
#endif /* NSSDEBUG */
- error = nssCKFWMutex_Lock(fwInstance->mutex);
- if( CKR_OK != error ) {
+ 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;
- }
-
- 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;
}
/*
@@ -807,34 +773,32 @@ nssCKFWInstance_ReassignObjectHandle
*
*/
NSS_IMPLEMENT void
-nssCKFWInstance_DestroyObjectHandle
-(
- NSSCKFWInstance *fwInstance,
- CK_OBJECT_HANDLE hObject
-)
+nssCKFWInstance_DestroyObjectHandle(
+ NSSCKFWInstance *fwInstance,
+ CK_OBJECT_HANDLE hObject)
{
- NSSCKFWObject *fwObject;
+ NSSCKFWObject *fwObject;
#ifdef NSSDEBUG
- if( CKR_OK != nssCKFWInstance_verifyPointer(fwInstance) ) {
- return;
- }
+ if (CKR_OK != nssCKFWInstance_verifyPointer(fwInstance)) {
+ return;
+ }
#endif /* NSSDEBUG */
- if( CKR_OK != nssCKFWMutex_Lock(fwInstance->mutex) ) {
+ 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;
- }
-
- 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;
}
/*
@@ -842,23 +806,21 @@ nssCKFWInstance_DestroyObjectHandle
*
*/
NSS_IMPLEMENT CK_OBJECT_HANDLE
-nssCKFWInstance_FindObjectHandle
-(
- NSSCKFWInstance *fwInstance,
- NSSCKFWObject *fwObject
-)
+nssCKFWInstance_FindObjectHandle(
+ NSSCKFWInstance *fwInstance,
+ NSSCKFWObject *fwObject)
{
#ifdef NSSDEBUG
- if( CKR_OK != nssCKFWInstance_verifyPointer(fwInstance) ) {
- return (CK_OBJECT_HANDLE)0;
- }
+ if (CKR_OK != nssCKFWInstance_verifyPointer(fwInstance)) {
+ return (CK_OBJECT_HANDLE)0;
+ }
- if( CKR_OK != nssCKFWObject_verifyPointer(fwObject) ) {
- return (CK_OBJECT_HANDLE)0;
- }
+ if (CKR_OK != nssCKFWObject_verifyPointer(fwObject)) {
+ return (CK_OBJECT_HANDLE)0;
+ }
#endif /* NSSDEBUG */
-
- return nssCKFWObject_GetHandle(fwObject);
+
+ return nssCKFWObject_GetHandle(fwObject);
}
/*
@@ -866,70 +828,66 @@ nssCKFWInstance_FindObjectHandle
*
*/
NSS_IMPLEMENT CK_ULONG
-nssCKFWInstance_GetNSlots
-(
- NSSCKFWInstance *fwInstance,
- CK_RV *pError
-)
+nssCKFWInstance_GetNSlots(
+ NSSCKFWInstance *fwInstance,
+ CK_RV *pError)
{
#ifdef NSSDEBUG
- if (!pError) {
- return (CK_ULONG)0;
- }
+ if (!pError) {
+ return (CK_ULONG)0;
+ }
- *pError = nssCKFWInstance_verifyPointer(fwInstance);
- if( CKR_OK != *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;
-}
+ *pError = CKR_OK;
+ return fwInstance->nSlots;
+}
/*
* nssCKFWInstance_GetCryptokiVersion
*
*/
NSS_IMPLEMENT CK_VERSION
-nssCKFWInstance_GetCryptokiVersion
-(
- NSSCKFWInstance *fwInstance
-)
+nssCKFWInstance_GetCryptokiVersion(
+ NSSCKFWInstance *fwInstance)
{
- CK_VERSION rv;
+ CK_VERSION rv;
#ifdef NSSDEBUG
- if( CKR_OK != nssCKFWInstance_verifyPointer(fwInstance) ) {
- rv.major = rv.minor = 0;
- return rv;
- }
+ 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 (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;
+ }
- 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;
+
+done:
+ (void)nssCKFWMutex_Unlock(fwInstance->mutex);
+ return rv;
}
/*
@@ -937,48 +895,46 @@ nssCKFWInstance_GetCryptokiVersion
*
*/
NSS_IMPLEMENT CK_RV
-nssCKFWInstance_GetManufacturerID
-(
- NSSCKFWInstance *fwInstance,
- CK_CHAR manufacturerID[32]
-)
+nssCKFWInstance_GetManufacturerID(
+ NSSCKFWInstance *fwInstance,
+ CK_CHAR manufacturerID[32])
{
- CK_RV error = CKR_OK;
+ CK_RV error = CKR_OK;
#ifdef NSSDEBUG
- if( (CK_CHAR_PTR)NULL == manufacturerID ) {
- return CKR_ARGUMENTS_BAD;
- }
+ if ((CK_CHAR_PTR)NULL == manufacturerID) {
+ return CKR_ARGUMENTS_BAD;
+ }
- error = nssCKFWInstance_verifyPointer(fwInstance);
- if( CKR_OK != error ) {
- return error;
- }
+ error = nssCKFWInstance_verifyPointer(fwInstance);
+ if (CKR_OK != error) {
+ return error;
+ }
#endif /* NSSDEBUG */
- error = nssCKFWMutex_Lock(fwInstance->mutex);
- if( CKR_OK != error ) {
- return error;
- }
+ 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 *) "";
+ 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;
+ (void)nssUTF8_CopyIntoFixedBuffer(fwInstance->manufacturerID, (char *)manufacturerID, 32, ' ');
+ error = CKR_OK;
- done:
- (void)nssCKFWMutex_Unlock(fwInstance->mutex);
- return error;
+done:
+ (void)nssCKFWMutex_Unlock(fwInstance->mutex);
+ return error;
}
/*
@@ -986,19 +942,17 @@ nssCKFWInstance_GetManufacturerID
*
*/
NSS_IMPLEMENT CK_ULONG
-nssCKFWInstance_GetFlags
-(
- NSSCKFWInstance *fwInstance
-)
+nssCKFWInstance_GetFlags(
+ NSSCKFWInstance *fwInstance)
{
#ifdef NSSDEBUG
- if( CKR_OK != nssCKFWInstance_verifyPointer(fwInstance) ) {
- return (CK_ULONG)0;
- }
+ if (CKR_OK != nssCKFWInstance_verifyPointer(fwInstance)) {
+ return (CK_ULONG)0;
+ }
#endif /* NSSDEBUG */
- /* No "instance flags" are yet defined by Cryptoki. */
- return (CK_ULONG)0;
+ /* No "instance flags" are yet defined by Cryptoki. */
+ return (CK_ULONG)0;
}
/*
@@ -1006,48 +960,46 @@ nssCKFWInstance_GetFlags
*
*/
NSS_IMPLEMENT CK_RV
-nssCKFWInstance_GetLibraryDescription
-(
- NSSCKFWInstance *fwInstance,
- CK_CHAR libraryDescription[32]
-)
+nssCKFWInstance_GetLibraryDescription(
+ NSSCKFWInstance *fwInstance,
+ CK_CHAR libraryDescription[32])
{
- CK_RV error = CKR_OK;
+ CK_RV error = CKR_OK;
#ifdef NSSDEBUG
- if( (CK_CHAR_PTR)NULL == libraryDescription ) {
- return CKR_ARGUMENTS_BAD;
- }
+ if ((CK_CHAR_PTR)NULL == libraryDescription) {
+ return CKR_ARGUMENTS_BAD;
+ }
- error = nssCKFWInstance_verifyPointer(fwInstance);
- if( CKR_OK != error ) {
- return error;
- }
+ error = nssCKFWInstance_verifyPointer(fwInstance);
+ if (CKR_OK != error) {
+ return error;
+ }
#endif /* NSSDEBUG */
- error = nssCKFWMutex_Lock(fwInstance->mutex);
- if( CKR_OK != error ) {
- return error;
- }
+ 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 *) "";
+ 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;
+ (void)nssUTF8_CopyIntoFixedBuffer(fwInstance->libraryDescription, (char *)libraryDescription, 32, ' ');
+ error = CKR_OK;
- done:
- (void)nssCKFWMutex_Unlock(fwInstance->mutex);
- return error;
+done:
+ (void)nssCKFWMutex_Unlock(fwInstance->mutex);
+ return error;
}
/*
@@ -1055,43 +1007,41 @@ nssCKFWInstance_GetLibraryDescription
*
*/
NSS_IMPLEMENT CK_VERSION
-nssCKFWInstance_GetLibraryVersion
-(
- NSSCKFWInstance *fwInstance
-)
+nssCKFWInstance_GetLibraryVersion(
+ NSSCKFWInstance *fwInstance)
{
- CK_VERSION rv;
+ CK_VERSION rv;
#ifdef NSSDEBUG
- if( CKR_OK != nssCKFWInstance_verifyPointer(fwInstance) ) {
- rv.major = rv.minor = 0;
- return rv;
- }
+ 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 (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;
+ }
- 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;
+done:
+ (void)nssCKFWMutex_Unlock(fwInstance->mutex);
+ return rv;
}
/*
@@ -1099,18 +1049,16 @@ nssCKFWInstance_GetLibraryVersion
*
*/
NSS_IMPLEMENT CK_BBOOL
-nssCKFWInstance_GetModuleHandlesSessionObjects
-(
- NSSCKFWInstance *fwInstance
-)
+nssCKFWInstance_GetModuleHandlesSessionObjects(
+ NSSCKFWInstance *fwInstance)
{
#ifdef NSSDEBUG
- if( CKR_OK != nssCKFWInstance_verifyPointer(fwInstance) ) {
- return CK_FALSE;
- }
+ if (CKR_OK != nssCKFWInstance_verifyPointer(fwInstance)) {
+ return CK_FALSE;
+ }
#endif /* NSSDEBUG */
- return fwInstance->moduleHandlesSessionObjects;
+ return fwInstance->moduleHandlesSessionObjects;
}
/*
@@ -1118,24 +1066,22 @@ nssCKFWInstance_GetModuleHandlesSessionObjects
*
*/
NSS_IMPLEMENT NSSCKFWSlot **
-nssCKFWInstance_GetSlots
-(
- NSSCKFWInstance *fwInstance,
- CK_RV *pError
-)
+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;
- }
+ if (!pError) {
+ return (NSSCKFWSlot **)NULL;
+ }
+
+ *pError = nssCKFWInstance_verifyPointer(fwInstance);
+ if (CKR_OK != *pError) {
+ return (NSSCKFWSlot **)NULL;
+ }
#endif /* NSSDEBUG */
- return fwInstance->fwSlotList;
+ return fwInstance->fwSlotList;
}
/*
@@ -1143,72 +1089,69 @@ nssCKFWInstance_GetSlots
*
*/
NSS_IMPLEMENT NSSCKFWSlot *
-nssCKFWInstance_WaitForSlotEvent
-(
- NSSCKFWInstance *fwInstance,
- CK_BBOOL block,
- CK_RV *pError
-)
+nssCKFWInstance_WaitForSlotEvent(
+ NSSCKFWInstance *fwInstance,
+ CK_BBOOL block,
+ CK_RV *pError)
{
- NSSCKFWSlot *fwSlot = (NSSCKFWSlot *)NULL;
- NSSCKMDSlot *mdSlot;
- CK_ULONG i, n;
+ 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;
- }
+ 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;
+ 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;
}
/*
@@ -1216,18 +1159,16 @@ nssCKFWInstance_WaitForSlotEvent
*
*/
NSS_IMPLEMENT NSSCKMDInstance *
-NSSCKFWInstance_GetMDInstance
-(
- NSSCKFWInstance *fwInstance
-)
+NSSCKFWInstance_GetMDInstance(
+ NSSCKFWInstance *fwInstance)
{
#ifdef DEBUG
- if( CKR_OK != nssCKFWInstance_verifyPointer(fwInstance) ) {
- return (NSSCKMDInstance *)NULL;
- }
+ if (CKR_OK != nssCKFWInstance_verifyPointer(fwInstance)) {
+ return (NSSCKMDInstance *)NULL;
+ }
#endif /* DEBUG */
- return nssCKFWInstance_GetMDInstance(fwInstance);
+ return nssCKFWInstance_GetMDInstance(fwInstance);
}
/*
@@ -1235,24 +1176,22 @@ NSSCKFWInstance_GetMDInstance
*
*/
NSS_IMPLEMENT NSSArena *
-NSSCKFWInstance_GetArena
-(
- NSSCKFWInstance *fwInstance,
- CK_RV *pError
-)
+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;
- }
+ if (!pError) {
+ return (NSSArena *)NULL;
+ }
+
+ *pError = nssCKFWInstance_verifyPointer(fwInstance);
+ if (CKR_OK != *pError) {
+ return (NSSArena *)NULL;
+ }
#endif /* DEBUG */
- return nssCKFWInstance_GetArena(fwInstance, pError);
+ return nssCKFWInstance_GetArena(fwInstance, pError);
}
/*
@@ -1260,18 +1199,16 @@ NSSCKFWInstance_GetArena
*
*/
NSS_IMPLEMENT CK_BBOOL
-NSSCKFWInstance_MayCreatePthreads
-(
- NSSCKFWInstance *fwInstance
-)
+NSSCKFWInstance_MayCreatePthreads(
+ NSSCKFWInstance *fwInstance)
{
#ifdef DEBUG
- if( CKR_OK != nssCKFWInstance_verifyPointer(fwInstance) ) {
- return CK_FALSE;
- }
+ if (CKR_OK != nssCKFWInstance_verifyPointer(fwInstance)) {
+ return CK_FALSE;
+ }
#endif /* DEBUG */
- return nssCKFWInstance_MayCreatePthreads(fwInstance);
+ return nssCKFWInstance_MayCreatePthreads(fwInstance);
}
/*
@@ -1279,25 +1216,23 @@ NSSCKFWInstance_MayCreatePthreads
*
*/
NSS_IMPLEMENT NSSCKFWMutex *
-NSSCKFWInstance_CreateMutex
-(
- NSSCKFWInstance *fwInstance,
- NSSArena *arena,
- CK_RV *pError
-)
+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;
- }
+ if (!pError) {
+ return (NSSCKFWMutex *)NULL;
+ }
+
+ *pError = nssCKFWInstance_verifyPointer(fwInstance);
+ if (CKR_OK != *pError) {
+ return (NSSCKFWMutex *)NULL;
+ }
#endif /* DEBUG */
- return nssCKFWInstance_CreateMutex(fwInstance, arena, pError);
+ return nssCKFWInstance_CreateMutex(fwInstance, arena, pError);
}
/*
@@ -1305,18 +1240,16 @@ NSSCKFWInstance_CreateMutex
*
*/
NSS_IMPLEMENT NSSUTF8 *
-NSSCKFWInstance_GetConfigurationData
-(
- NSSCKFWInstance *fwInstance
-)
+NSSCKFWInstance_GetConfigurationData(
+ NSSCKFWInstance *fwInstance)
{
#ifdef DEBUG
- if( CKR_OK != nssCKFWInstance_verifyPointer(fwInstance) ) {
- return (NSSUTF8 *)NULL;
- }
+ if (CKR_OK != nssCKFWInstance_verifyPointer(fwInstance)) {
+ return (NSSUTF8 *)NULL;
+ }
#endif /* DEBUG */
- return nssCKFWInstance_GetConfigurationData(fwInstance);
+ return nssCKFWInstance_GetConfigurationData(fwInstance);
}
/*
@@ -1324,17 +1257,38 @@ NSSCKFWInstance_GetConfigurationData
*
*/
NSS_IMPLEMENT CK_C_INITIALIZE_ARGS_PTR
-NSSCKFWInstance_GetInitArgs
-(
- NSSCKFWInstance *fwInstance
-)
+NSSCKFWInstance_GetInitArgs(
+ NSSCKFWInstance *fwInstance)
{
#ifdef DEBUG
- if( CKR_OK != nssCKFWInstance_verifyPointer(fwInstance) ) {
- return (CK_C_INITIALIZE_ARGS_PTR)NULL;
- }
+ if (CKR_OK != nssCKFWInstance_verifyPointer(fwInstance)) {
+ return (CK_C_INITIALIZE_ARGS_PTR)NULL;
+ }
#endif /* DEBUG */
- return nssCKFWInstance_GetInitArgs(fwInstance);
+ return nssCKFWInstance_GetInitArgs(fwInstance);
+}
+
+/*
+ * nssCKFWInstance_DestroySessionHandle
+ *
+ */
+NSS_IMPLEMENT void
+NSSCKFWInstance_DestroySessionHandle(
+ NSSCKFWInstance *fwInstance,
+ CK_SESSION_HANDLE hSession)
+{
+ nssCKFWInstance_DestroySessionHandle(fwInstance, hSession);
}
+/*
+ * nssCKFWInstance_FindSessionHandle
+ *
+ */
+NSS_IMPLEMENT CK_SESSION_HANDLE
+NSSCKFWInstance_FindSessionHandle(
+ NSSCKFWInstance *fwInstance,
+ NSSCKFWSession *fwSession)
+{
+ return nssCKFWInstance_FindSessionHandle(fwInstance, fwSession);
+}
diff --git a/nss/lib/ckfw/mechanism.c b/nss/lib/ckfw/mechanism.c
index 14baf02..fe20aa9 100644
--- a/nss/lib/ckfw/mechanism.c
+++ b/nss/lib/ckfw/mechanism.c
@@ -55,13 +55,12 @@
* nssCKFWMechanism_DeriveKey
*/
-
struct NSSCKFWMechanismStr {
- NSSCKMDMechanism *mdMechanism;
- NSSCKMDToken *mdToken;
- NSSCKFWToken *fwToken;
- NSSCKMDInstance *mdInstance;
- NSSCKFWInstance *fwInstance;
+ NSSCKMDMechanism *mdMechanism;
+ NSSCKMDToken *mdToken;
+ NSSCKFWToken *fwToken;
+ NSSCKMDInstance *mdInstance;
+ NSSCKFWInstance *fwInstance;
};
/*
@@ -69,28 +68,25 @@ struct NSSCKFWMechanismStr {
*
*/
NSS_IMPLEMENT NSSCKFWMechanism *
-nssCKFWMechanism_Create
-(
- NSSCKMDMechanism *mdMechanism,
- NSSCKMDToken *mdToken,
- NSSCKFWToken *fwToken,
- NSSCKMDInstance *mdInstance,
- NSSCKFWInstance *fwInstance
-)
+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 *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;
}
/*
@@ -98,24 +94,22 @@ nssCKFWMechanism_Create
*
*/
NSS_IMPLEMENT void
-nssCKFWMechanism_Destroy
-(
- NSSCKFWMechanism *fwMechanism
-)
+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;
+ /* 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;
}
/*
@@ -123,12 +117,10 @@ nssCKFWMechanism_Destroy
*
*/
NSS_IMPLEMENT NSSCKMDMechanism *
-nssCKFWMechanism_GetMDMechanism
-(
- NSSCKFWMechanism *fwMechanism
-)
+nssCKFWMechanism_GetMDMechanism(
+ NSSCKFWMechanism *fwMechanism)
{
- return fwMechanism->mdMechanism;
+ return fwMechanism->mdMechanism;
}
/*
@@ -136,19 +128,17 @@ nssCKFWMechanism_GetMDMechanism
*
*/
NSS_IMPLEMENT CK_ULONG
-nssCKFWMechanism_GetMinKeySize
-(
- NSSCKFWMechanism *fwMechanism,
- CK_RV *pError
-)
+nssCKFWMechanism_GetMinKeySize(
+ NSSCKFWMechanism *fwMechanism,
+ CK_RV *pError)
{
- if (!fwMechanism->mdMechanism->GetMinKeySize) {
- return 0;
- }
+ if (!fwMechanism->mdMechanism->GetMinKeySize) {
+ return 0;
+ }
- return fwMechanism->mdMechanism->GetMinKeySize(fwMechanism->mdMechanism,
- fwMechanism, fwMechanism->mdToken, fwMechanism->fwToken,
- fwMechanism->mdInstance, fwMechanism->fwInstance, pError);
+ return fwMechanism->mdMechanism->GetMinKeySize(fwMechanism->mdMechanism,
+ fwMechanism, fwMechanism->mdToken, fwMechanism->fwToken,
+ fwMechanism->mdInstance, fwMechanism->fwInstance, pError);
}
/*
@@ -156,19 +146,17 @@ nssCKFWMechanism_GetMinKeySize
*
*/
NSS_IMPLEMENT CK_ULONG
-nssCKFWMechanism_GetMaxKeySize
-(
- NSSCKFWMechanism *fwMechanism,
- CK_RV *pError
-)
+nssCKFWMechanism_GetMaxKeySize(
+ NSSCKFWMechanism *fwMechanism,
+ CK_RV *pError)
{
- if (!fwMechanism->mdMechanism->GetMaxKeySize) {
- return 0;
- }
+ if (!fwMechanism->mdMechanism->GetMaxKeySize) {
+ return 0;
+ }
- return fwMechanism->mdMechanism->GetMaxKeySize(fwMechanism->mdMechanism,
- fwMechanism, fwMechanism->mdToken, fwMechanism->fwToken,
- fwMechanism->mdInstance, fwMechanism->fwInstance, pError);
+ return fwMechanism->mdMechanism->GetMaxKeySize(fwMechanism->mdMechanism,
+ fwMechanism, fwMechanism->mdToken, fwMechanism->fwToken,
+ fwMechanism->mdInstance, fwMechanism->fwInstance, pError);
}
/*
@@ -176,22 +164,19 @@ nssCKFWMechanism_GetMaxKeySize
*
*/
NSS_IMPLEMENT CK_BBOOL
-nssCKFWMechanism_GetInHardware
-(
- NSSCKFWMechanism *fwMechanism,
- CK_RV *pError
-)
+nssCKFWMechanism_GetInHardware(
+ NSSCKFWMechanism *fwMechanism,
+ CK_RV *pError)
{
- if (!fwMechanism->mdMechanism->GetInHardware) {
- return CK_FALSE;
- }
+ if (!fwMechanism->mdMechanism->GetInHardware) {
+ return CK_FALSE;
+ }
- return fwMechanism->mdMechanism->GetInHardware(fwMechanism->mdMechanism,
- fwMechanism, fwMechanism->mdToken, fwMechanism->fwToken,
- fwMechanism->mdInstance, fwMechanism->fwInstance, pError);
+ 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.
@@ -201,16 +186,14 @@ nssCKFWMechanism_GetInHardware
*
*/
NSS_EXTERN CK_BBOOL
-nssCKFWMechanism_GetCanEncrypt
-(
- NSSCKFWMechanism *fwMechanism,
- CK_RV *pError
-)
+nssCKFWMechanism_GetCanEncrypt(
+ NSSCKFWMechanism *fwMechanism,
+ CK_RV *pError)
{
- if (!fwMechanism->mdMechanism->EncryptInit) {
- return CK_FALSE;
- }
- return CK_TRUE;
+ if (!fwMechanism->mdMechanism->EncryptInit) {
+ return CK_FALSE;
+ }
+ return CK_TRUE;
}
/*
@@ -218,16 +201,14 @@ nssCKFWMechanism_GetCanEncrypt
*
*/
NSS_EXTERN CK_BBOOL
-nssCKFWMechanism_GetCanDecrypt
-(
- NSSCKFWMechanism *fwMechanism,
- CK_RV *pError
-)
+nssCKFWMechanism_GetCanDecrypt(
+ NSSCKFWMechanism *fwMechanism,
+ CK_RV *pError)
{
- if (!fwMechanism->mdMechanism->DecryptInit) {
- return CK_FALSE;
- }
- return CK_TRUE;
+ if (!fwMechanism->mdMechanism->DecryptInit) {
+ return CK_FALSE;
+ }
+ return CK_TRUE;
}
/*
@@ -235,16 +216,14 @@ nssCKFWMechanism_GetCanDecrypt
*
*/
NSS_EXTERN CK_BBOOL
-nssCKFWMechanism_GetCanDigest
-(
- NSSCKFWMechanism *fwMechanism,
- CK_RV *pError
-)
+nssCKFWMechanism_GetCanDigest(
+ NSSCKFWMechanism *fwMechanism,
+ CK_RV *pError)
{
- if (!fwMechanism->mdMechanism->DigestInit) {
- return CK_FALSE;
- }
- return CK_TRUE;
+ if (!fwMechanism->mdMechanism->DigestInit) {
+ return CK_FALSE;
+ }
+ return CK_TRUE;
}
/*
@@ -252,16 +231,14 @@ nssCKFWMechanism_GetCanDigest
*
*/
NSS_EXTERN CK_BBOOL
-nssCKFWMechanism_GetCanSign
-(
- NSSCKFWMechanism *fwMechanism,
- CK_RV *pError
-)
+nssCKFWMechanism_GetCanSign(
+ NSSCKFWMechanism *fwMechanism,
+ CK_RV *pError)
{
- if (!fwMechanism->mdMechanism->SignInit) {
- return CK_FALSE;
- }
- return CK_TRUE;
+ if (!fwMechanism->mdMechanism->SignInit) {
+ return CK_FALSE;
+ }
+ return CK_TRUE;
}
/*
@@ -269,16 +246,14 @@ nssCKFWMechanism_GetCanSign
*
*/
NSS_EXTERN CK_BBOOL
-nssCKFWMechanism_GetCanSignRecover
-(
- NSSCKFWMechanism *fwMechanism,
- CK_RV *pError
-)
+nssCKFWMechanism_GetCanSignRecover(
+ NSSCKFWMechanism *fwMechanism,
+ CK_RV *pError)
{
- if (!fwMechanism->mdMechanism->SignRecoverInit) {
- return CK_FALSE;
- }
- return CK_TRUE;
+ if (!fwMechanism->mdMechanism->SignRecoverInit) {
+ return CK_FALSE;
+ }
+ return CK_TRUE;
}
/*
@@ -286,16 +261,14 @@ nssCKFWMechanism_GetCanSignRecover
*
*/
NSS_EXTERN CK_BBOOL
-nssCKFWMechanism_GetCanVerify
-(
- NSSCKFWMechanism *fwMechanism,
- CK_RV *pError
-)
+nssCKFWMechanism_GetCanVerify(
+ NSSCKFWMechanism *fwMechanism,
+ CK_RV *pError)
{
- if (!fwMechanism->mdMechanism->VerifyInit) {
- return CK_FALSE;
- }
- return CK_TRUE;
+ if (!fwMechanism->mdMechanism->VerifyInit) {
+ return CK_FALSE;
+ }
+ return CK_TRUE;
}
/*
@@ -303,16 +276,14 @@ nssCKFWMechanism_GetCanVerify
*
*/
NSS_EXTERN CK_BBOOL
-nssCKFWMechanism_GetCanVerifyRecover
-(
- NSSCKFWMechanism *fwMechanism,
- CK_RV *pError
-)
+nssCKFWMechanism_GetCanVerifyRecover(
+ NSSCKFWMechanism *fwMechanism,
+ CK_RV *pError)
{
- if (!fwMechanism->mdMechanism->VerifyRecoverInit) {
- return CK_FALSE;
- }
- return CK_TRUE;
+ if (!fwMechanism->mdMechanism->VerifyRecoverInit) {
+ return CK_FALSE;
+ }
+ return CK_TRUE;
}
/*
@@ -320,16 +291,14 @@ nssCKFWMechanism_GetCanVerifyRecover
*
*/
NSS_EXTERN CK_BBOOL
-nssCKFWMechanism_GetCanGenerate
-(
- NSSCKFWMechanism *fwMechanism,
- CK_RV *pError
-)
+nssCKFWMechanism_GetCanGenerate(
+ NSSCKFWMechanism *fwMechanism,
+ CK_RV *pError)
{
- if (!fwMechanism->mdMechanism->GenerateKey) {
- return CK_FALSE;
- }
- return CK_TRUE;
+ if (!fwMechanism->mdMechanism->GenerateKey) {
+ return CK_FALSE;
+ }
+ return CK_TRUE;
}
/*
@@ -337,16 +306,14 @@ nssCKFWMechanism_GetCanGenerate
*
*/
NSS_EXTERN CK_BBOOL
-nssCKFWMechanism_GetCanGenerateKeyPair
-(
- NSSCKFWMechanism *fwMechanism,
- CK_RV *pError
-)
+nssCKFWMechanism_GetCanGenerateKeyPair(
+ NSSCKFWMechanism *fwMechanism,
+ CK_RV *pError)
{
- if (!fwMechanism->mdMechanism->GenerateKeyPair) {
- return CK_FALSE;
- }
- return CK_TRUE;
+ if (!fwMechanism->mdMechanism->GenerateKeyPair) {
+ return CK_FALSE;
+ }
+ return CK_TRUE;
}
/*
@@ -354,16 +321,14 @@ nssCKFWMechanism_GetCanGenerateKeyPair
*
*/
NSS_EXTERN CK_BBOOL
-nssCKFWMechanism_GetCanUnwrap
-(
- NSSCKFWMechanism *fwMechanism,
- CK_RV *pError
-)
+nssCKFWMechanism_GetCanUnwrap(
+ NSSCKFWMechanism *fwMechanism,
+ CK_RV *pError)
{
- if (!fwMechanism->mdMechanism->UnwrapKey) {
- return CK_FALSE;
- }
- return CK_TRUE;
+ if (!fwMechanism->mdMechanism->UnwrapKey) {
+ return CK_FALSE;
+ }
+ return CK_TRUE;
}
/*
@@ -371,16 +336,14 @@ nssCKFWMechanism_GetCanUnwrap
*
*/
NSS_EXTERN CK_BBOOL
-nssCKFWMechanism_GetCanWrap
-(
- NSSCKFWMechanism *fwMechanism,
- CK_RV *pError
-)
+nssCKFWMechanism_GetCanWrap(
+ NSSCKFWMechanism *fwMechanism,
+ CK_RV *pError)
{
- if (!fwMechanism->mdMechanism->WrapKey) {
- return CK_FALSE;
- }
- return CK_TRUE;
+ if (!fwMechanism->mdMechanism->WrapKey) {
+ return CK_FALSE;
+ }
+ return CK_TRUE;
}
/*
@@ -388,55 +351,50 @@ nssCKFWMechanism_GetCanWrap
*
*/
NSS_EXTERN CK_BBOOL
-nssCKFWMechanism_GetCanDerive
-(
- NSSCKFWMechanism *fwMechanism,
- CK_RV *pError
-)
+nssCKFWMechanism_GetCanDerive(
+ NSSCKFWMechanism *fwMechanism,
+ CK_RV *pError)
{
- if (!fwMechanism->mdMechanism->DeriveKey) {
- return CK_FALSE;
- }
- return CK_TRUE;
+ 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
-)
+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(
+ 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,
@@ -448,58 +406,54 @@ nssCKFWMechanism_EncryptInit
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);
- }
+ &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;
+ return error;
}
-/*
+/*
* nssCKFWMechanism_DecryptInit
* Start an encryption session.
*/
NSS_EXTERN CK_RV
-nssCKFWMechanism_DecryptInit
-(
- NSSCKFWMechanism *fwMechanism,
- CK_MECHANISM *pMechanism,
- NSSCKFWSession *fwSession,
- NSSCKFWObject *fwObject
-)
+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(
+ 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,
@@ -511,55 +465,51 @@ nssCKFWMechanism_DecryptInit
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);
- }
+ &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;
+ return error;
}
-/*
+/*
* nssCKFWMechanism_DigestInit
* Start an encryption session.
*/
NSS_EXTERN CK_RV
-nssCKFWMechanism_DigestInit
-(
- NSSCKFWMechanism *fwMechanism,
- CK_MECHANISM *pMechanism,
- NSSCKFWSession *fwSession
-)
+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;
- }
+ 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;
- }
+ if (!fwMechanism->mdMechanism->DigestInit) {
+ return CKR_FUNCTION_FAILED;
+ }
- mdSession = nssCKFWSession_GetMDSession(fwSession);
- mdOperation = fwMechanism->mdMechanism->DigestInit(
+ mdSession = nssCKFWSession_GetMDSession(fwSession);
+ mdOperation = fwMechanism->mdMechanism->DigestInit(
fwMechanism->mdMechanism,
fwMechanism,
pMechanism,
@@ -569,58 +519,54 @@ nssCKFWMechanism_DigestInit
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);
- }
+ &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;
+ return error;
}
-/*
+/*
* nssCKFWMechanism_SignInit
* Start an encryption session.
*/
NSS_EXTERN CK_RV
-nssCKFWMechanism_SignInit
-(
- NSSCKFWMechanism *fwMechanism,
- CK_MECHANISM *pMechanism,
- NSSCKFWSession *fwSession,
- NSSCKFWObject *fwObject
-)
+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(
+ 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,
@@ -632,58 +578,54 @@ nssCKFWMechanism_SignInit
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);
- }
+ &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;
+ return error;
}
-/*
+/*
* nssCKFWMechanism_VerifyInit
* Start an encryption session.
*/
NSS_EXTERN CK_RV
-nssCKFWMechanism_VerifyInit
-(
- NSSCKFWMechanism *fwMechanism,
- CK_MECHANISM *pMechanism,
- NSSCKFWSession *fwSession,
- NSSCKFWObject *fwObject
-)
+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(
+ 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,
@@ -695,58 +637,54 @@ nssCKFWMechanism_VerifyInit
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);
- }
+ &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;
+ return error;
}
-/*
+/*
* nssCKFWMechanism_SignRecoverInit
* Start an encryption session.
*/
NSS_EXTERN CK_RV
-nssCKFWMechanism_SignRecoverInit
-(
- NSSCKFWMechanism *fwMechanism,
- CK_MECHANISM *pMechanism,
- NSSCKFWSession *fwSession,
- NSSCKFWObject *fwObject
-)
+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(
+ 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,
@@ -758,58 +696,54 @@ nssCKFWMechanism_SignRecoverInit
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);
- }
+ &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;
+ return error;
}
-/*
+/*
* nssCKFWMechanism_VerifyRecoverInit
* Start an encryption session.
*/
NSS_EXTERN CK_RV
-nssCKFWMechanism_VerifyRecoverInit
-(
- NSSCKFWMechanism *fwMechanism,
- CK_MECHANISM *pMechanism,
- NSSCKFWSession *fwSession,
- NSSCKFWObject *fwObject
-)
+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(
+ 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,
@@ -821,59 +755,56 @@ nssCKFWMechanism_VerifyRecoverInit
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);
- }
+ &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;
+ 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
-)
+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;
+ 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;
}
- return (NSSCKFWObject *)NULL;
- }
- mdSession = nssCKFWSession_GetMDSession(fwSession);
- mdObject = fwMechanism->mdMechanism->GenerateKey(
+ mdSession = nssCKFWSession_GetMDSession(fwSession);
+ mdObject = fwMechanism->mdMechanism->GenerateKey(
fwMechanism->mdMechanism,
fwMechanism,
pMechanism,
@@ -887,53 +818,51 @@ nssCKFWMechanism_GenerateKey
ulAttributeCount,
pError);
- if (!mdObject) {
- return (NSSCKFWObject *)NULL;
- }
+ if (!mdObject) {
+ return (NSSCKFWObject *)NULL;
+ }
- fwObject = nssCKFWObject_Create(arena, mdObject,
- fwSession, fwMechanism->fwToken, fwMechanism->fwInstance, pError);
+ fwObject = nssCKFWObject_Create(arena, mdObject,
+ fwSession, fwMechanism->fwToken, fwMechanism->fwInstance, pError);
- return fwObject;
+ 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
-)
+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;
+ 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;
}
- return error;
- }
- mdSession = nssCKFWSession_GetMDSession(fwSession);
- error = fwMechanism->mdMechanism->GenerateKeyPair(
+ mdSession = nssCKFWSession_GetMDSession(fwSession);
+ error = fwMechanism->mdMechanism->GenerateKeyPair(
fwMechanism->mdMechanism,
fwMechanism,
pMechanism,
@@ -950,48 +879,46 @@ nssCKFWMechanism_GenerateKeyPair
&mdPublicKeyObject,
&mdPrivateKeyObject);
- if (CKR_OK != error) {
- return error;
- }
+ 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);
+ *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;
+ 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
-)
+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(
+ 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,
@@ -1012,28 +939,26 @@ nssCKFWMechanism_GetWrapKeyLength
* nssCKFWMechanism_WrapKey
*/
NSS_EXTERN CK_RV
-nssCKFWMechanism_WrapKey
-(
- NSSCKFWMechanism *fwMechanism,
- CK_MECHANISM_PTR pMechanism,
- NSSCKFWSession *fwSession,
- NSSCKFWObject *fwWrappingKeyObject,
- NSSCKFWObject *fwKeyObject,
- NSSItem *wrappedKey
-)
+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(
+ 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,
@@ -1054,44 +979,42 @@ nssCKFWMechanism_WrapKey
* 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_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
+ 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;
+ *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;
}
- return (NSSCKFWObject *)NULL;
- }
- mdSession = nssCKFWSession_GetMDSession(fwSession);
- mdWrappingKeyObject = nssCKFWObject_GetMDObject(fwWrappingKeyObject);
- mdObject = fwMechanism->mdMechanism->UnwrapKey(
+ mdSession = nssCKFWSession_GetMDSession(fwSession);
+ mdWrappingKeyObject = nssCKFWObject_GetMDObject(fwWrappingKeyObject);
+ mdObject = fwMechanism->mdMechanism->UnwrapKey(
fwMechanism->mdMechanism,
fwMechanism,
pMechanism,
@@ -1108,53 +1031,51 @@ nssCKFWMechanism_UnwrapKey
ulAttributeCount,
pError);
- if (!mdObject) {
- return (NSSCKFWObject *)NULL;
- }
+ if (!mdObject) {
+ return (NSSCKFWObject *)NULL;
+ }
- fwObject = nssCKFWObject_Create(arena, mdObject,
- fwSession, fwMechanism->fwToken, fwMechanism->fwInstance, pError);
+ fwObject = nssCKFWObject_Create(arena, mdObject,
+ fwSession, fwMechanism->fwToken, fwMechanism->fwInstance, pError);
- return fwObject;
+ 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
-)
+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;
+ 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;
}
- return (NSSCKFWObject *)NULL;
- }
- mdSession = nssCKFWSession_GetMDSession(fwSession);
- mdBaseKeyObject = nssCKFWObject_GetMDObject(fwBaseKeyObject);
- mdObject = fwMechanism->mdMechanism->DeriveKey(
+ mdSession = nssCKFWSession_GetMDSession(fwSession);
+ mdBaseKeyObject = nssCKFWObject_GetMDObject(fwBaseKeyObject);
+ mdObject = fwMechanism->mdMechanism->DeriveKey(
fwMechanism->mdMechanism,
fwMechanism,
pMechanism,
@@ -1170,13 +1091,12 @@ nssCKFWMechanism_DeriveKey
ulAttributeCount,
pError);
- if (!mdObject) {
- return (NSSCKFWObject *)NULL;
- }
+ if (!mdObject) {
+ return (NSSCKFWObject *)NULL;
+ }
- fwObject = nssCKFWObject_Create(arena, mdObject,
- fwSession, fwMechanism->fwToken, fwMechanism->fwInstance, pError);
+ fwObject = nssCKFWObject_Create(arena, mdObject,
+ fwSession, fwMechanism->fwToken, fwMechanism->fwInstance, pError);
- return fwObject;
+ return fwObject;
}
-
diff --git a/nss/lib/ckfw/mutex.c b/nss/lib/ckfw/mutex.c
index 0d74cf1..be569e1 100644
--- a/nss/lib/ckfw/mutex.c
+++ b/nss/lib/ckfw/mutex.c
@@ -31,7 +31,7 @@
*/
struct NSSCKFWMutexStr {
- PRLock *lock;
+ PRLock *lock;
};
#ifdef DEBUG
@@ -47,30 +47,24 @@ struct NSSCKFWMutexStr {
*/
static CK_RV
-mutex_add_pointer
-(
- const NSSCKFWMutex *fwMutex
-)
+mutex_add_pointer(
+ const NSSCKFWMutex *fwMutex)
{
- return CKR_OK;
+ return CKR_OK;
}
static CK_RV
-mutex_remove_pointer
-(
- const NSSCKFWMutex *fwMutex
-)
+mutex_remove_pointer(
+ const NSSCKFWMutex *fwMutex)
{
- return CKR_OK;
+ return CKR_OK;
}
NSS_IMPLEMENT CK_RV
-nssCKFWMutex_verifyPointer
-(
- const NSSCKFWMutex *fwMutex
-)
+nssCKFWMutex_verifyPointer(
+ const NSSCKFWMutex *fwMutex)
{
- return CKR_OK;
+ return CKR_OK;
}
#endif /* DEBUG */
@@ -80,78 +74,74 @@ nssCKFWMutex_verifyPointer
*
*/
NSS_EXTERN NSSCKFWMutex *
-nssCKFWMutex_Create
-(
- CK_C_INITIALIZE_ARGS_PTR pInitArgs,
- CryptokiLockingState LockingState,
- NSSArena *arena,
- CK_RV *pError
-)
+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 */
+ 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;
}
- }
-
- 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);
+ *pError = mutex_add_pointer(mutex);
+ if (CKR_OK != *pError) {
+ if (mutex->lock) {
+ PR_DestroyLock(mutex->lock);
+ }
+ (void)nss_ZFreeIf(mutex);
+ return (NSSCKFWMutex *)NULL;
}
- (void)nss_ZFreeIf(mutex);
- return (NSSCKFWMutex *)NULL;
- }
#endif /* DEBUG */
- return mutex;
-}
+ return mutex;
+}
/*
* nssCKFWMutex_Destroy
*
*/
NSS_EXTERN CK_RV
-nssCKFWMutex_Destroy
-(
- NSSCKFWMutex *mutex
-)
+nssCKFWMutex_Destroy(
+ NSSCKFWMutex *mutex)
{
- CK_RV rv = CKR_OK;
+ CK_RV rv = CKR_OK;
#ifdef NSSDEBUG
- rv = nssCKFWMutex_verifyPointer(mutex);
- if( CKR_OK != rv ) {
- return rv;
- }
+ rv = nssCKFWMutex_verifyPointer(mutex);
+ if (CKR_OK != rv) {
+ return rv;
+ }
#endif /* NSSDEBUG */
-
- if (mutex->lock) {
- PR_DestroyLock(mutex->lock);
- }
+
+ if (mutex->lock) {
+ PR_DestroyLock(mutex->lock);
+ }
#ifdef DEBUG
- (void)mutex_remove_pointer(mutex);
+ (void)mutex_remove_pointer(mutex);
#endif /* DEBUG */
- (void)nss_ZFreeIf(mutex);
- return rv;
+ (void)nss_ZFreeIf(mutex);
+ return rv;
}
/*
@@ -159,22 +149,20 @@ nssCKFWMutex_Destroy
*
*/
NSS_EXTERN CK_RV
-nssCKFWMutex_Lock
-(
- NSSCKFWMutex *mutex
-)
+nssCKFWMutex_Lock(
+ NSSCKFWMutex *mutex)
{
#ifdef NSSDEBUG
- CK_RV rv = nssCKFWMutex_verifyPointer(mutex);
- if( CKR_OK != rv ) {
- return rv;
- }
+ CK_RV rv = nssCKFWMutex_verifyPointer(mutex);
+ if (CKR_OK != rv) {
+ return rv;
+ }
#endif /* NSSDEBUG */
- if (mutex->lock) {
- PR_Lock(mutex->lock);
- }
-
- return CKR_OK;
+ if (mutex->lock) {
+ PR_Lock(mutex->lock);
+ }
+
+ return CKR_OK;
}
/*
@@ -182,29 +170,27 @@ nssCKFWMutex_Lock
*
*/
NSS_EXTERN CK_RV
-nssCKFWMutex_Unlock
-(
- NSSCKFWMutex *mutex
-)
+nssCKFWMutex_Unlock(
+ NSSCKFWMutex *mutex)
{
- PRStatus nrv;
+ PRStatus nrv;
#ifdef NSSDEBUG
- CK_RV rv = nssCKFWMutex_verifyPointer(mutex);
+ CK_RV rv = nssCKFWMutex_verifyPointer(mutex);
- if( CKR_OK != rv ) {
- return rv;
- }
+ if (CKR_OK != rv) {
+ return rv;
+ }
#endif /* NSSDEBUG */
- if (!mutex->lock)
- return CKR_OK;
+ if (!mutex->lock)
+ return CKR_OK;
- nrv = PR_Unlock(mutex->lock);
+ 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;
+ /* 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;
}
/*
@@ -212,19 +198,17 @@ nssCKFWMutex_Unlock
*
*/
NSS_EXTERN CK_RV
-NSSCKFWMutex_Destroy
-(
- NSSCKFWMutex *mutex
-)
+NSSCKFWMutex_Destroy(
+ NSSCKFWMutex *mutex)
{
#ifdef DEBUG
- CK_RV rv = nssCKFWMutex_verifyPointer(mutex);
- if( CKR_OK != rv ) {
- return rv;
- }
+ CK_RV rv = nssCKFWMutex_verifyPointer(mutex);
+ if (CKR_OK != rv) {
+ return rv;
+ }
#endif /* DEBUG */
-
- return nssCKFWMutex_Destroy(mutex);
+
+ return nssCKFWMutex_Destroy(mutex);
}
/*
@@ -232,19 +216,17 @@ NSSCKFWMutex_Destroy
*
*/
NSS_EXTERN CK_RV
-NSSCKFWMutex_Lock
-(
- NSSCKFWMutex *mutex
-)
+NSSCKFWMutex_Lock(
+ NSSCKFWMutex *mutex)
{
#ifdef DEBUG
- CK_RV rv = nssCKFWMutex_verifyPointer(mutex);
- if( CKR_OK != rv ) {
- return rv;
- }
+ CK_RV rv = nssCKFWMutex_verifyPointer(mutex);
+ if (CKR_OK != rv) {
+ return rv;
+ }
#endif /* DEBUG */
-
- return nssCKFWMutex_Lock(mutex);
+
+ return nssCKFWMutex_Lock(mutex);
}
/*
@@ -252,18 +234,15 @@ NSSCKFWMutex_Lock
*
*/
NSS_EXTERN CK_RV
-NSSCKFWMutex_Unlock
-(
- NSSCKFWMutex *mutex
-)
+NSSCKFWMutex_Unlock(
+ NSSCKFWMutex *mutex)
{
#ifdef DEBUG
- CK_RV rv = nssCKFWMutex_verifyPointer(mutex);
- if( CKR_OK != rv ) {
- return rv;
- }
+ CK_RV rv = nssCKFWMutex_verifyPointer(mutex);
+ if (CKR_OK != rv) {
+ return rv;
+ }
#endif /* DEBUG */
- return nssCKFWMutex_Unlock(mutex);
+ return nssCKFWMutex_Unlock(mutex);
}
-
diff --git a/nss/lib/ckfw/nssckfw.h b/nss/lib/ckfw/nssckfw.h
index 4343eab..0f93eaa 100644
--- a/nss/lib/ckfw/nssckfw.h
+++ b/nss/lib/ckfw/nssckfw.h
@@ -8,7 +8,7 @@
/*
* nssckfw.h
*
- * This file prototypes the publicly available calls of the
+ * This file prototypes the publicly available calls of the
* NSS Cryptoki Framework.
*/
@@ -32,6 +32,9 @@
* NSSCKFWInstance_MayCreatePthreads
* NSSCKFWInstance_CreateMutex
* NSSCKFWInstance_GetConfigurationData
+ * NSSCKFWInstance_GetInitArgs
+ * NSSCKFWInstance_DestroySessionHandle
+ * NSSCKFWInstance_FindSessionHandle
*/
/*
@@ -40,10 +43,8 @@
*/
NSS_EXTERN NSSCKMDInstance *
-NSSCKFWInstance_GetMDInstance
-(
- NSSCKFWInstance *fwInstance
-);
+NSSCKFWInstance_GetMDInstance(
+ NSSCKFWInstance *fwInstance);
/*
* NSSCKFWInstance_GetArena
@@ -51,11 +52,9 @@ NSSCKFWInstance_GetMDInstance
*/
NSS_EXTERN NSSArena *
-NSSCKFWInstance_GetArena
-(
- NSSCKFWInstance *fwInstance,
- CK_RV *pError
-);
+NSSCKFWInstance_GetArena(
+ NSSCKFWInstance *fwInstance,
+ CK_RV *pError);
/*
* NSSCKFWInstance_MayCreatePthreads
@@ -63,10 +62,8 @@ NSSCKFWInstance_GetArena
*/
NSS_EXTERN CK_BBOOL
-NSSCKFWInstance_MayCreatePthreads
-(
- NSSCKFWInstance *fwInstance
-);
+NSSCKFWInstance_MayCreatePthreads(
+ NSSCKFWInstance *fwInstance);
/*
* NSSCKFWInstance_CreateMutex
@@ -74,12 +71,10 @@ NSSCKFWInstance_MayCreatePthreads
*/
NSS_EXTERN NSSCKFWMutex *
-NSSCKFWInstance_CreateMutex
-(
- NSSCKFWInstance *fwInstance,
- NSSArena *arena,
- CK_RV *pError
-);
+NSSCKFWInstance_CreateMutex(
+ NSSCKFWInstance *fwInstance,
+ NSSArena *arena,
+ CK_RV *pError);
/*
* NSSCKFWInstance_GetConfigurationData
@@ -87,10 +82,8 @@ NSSCKFWInstance_CreateMutex
*/
NSS_EXTERN NSSUTF8 *
-NSSCKFWInstance_GetConfigurationData
-(
- NSSCKFWInstance *fwInstance
-);
+NSSCKFWInstance_GetConfigurationData(
+ NSSCKFWInstance *fwInstance);
/*
* NSSCKFWInstance_GetInitArgs
@@ -98,10 +91,26 @@ NSSCKFWInstance_GetConfigurationData
*/
NSS_EXTERN CK_C_INITIALIZE_ARGS_PTR
-NSSCKFWInstance_GetInitArgs
-(
- NSSCKFWInstance *fwInstance
-);
+NSSCKFWInstance_GetInitArgs(
+ NSSCKFWInstance *fwInstance);
+
+/*
+ * 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);
/*
* NSSCKFWSlot
@@ -109,6 +118,7 @@ NSSCKFWInstance_GetInitArgs
* NSSCKFWSlot_GetMDSlot
* NSSCKFWSlot_GetFWInstance
* NSSCKFWSlot_GetMDInstance
+ * NSSCKFWSlot_GetSlotID
*
*/
@@ -118,10 +128,8 @@ NSSCKFWInstance_GetInitArgs
*/
NSS_EXTERN NSSCKMDSlot *
-NSSCKFWSlot_GetMDSlot
-(
- NSSCKFWSlot *fwSlot
-);
+NSSCKFWSlot_GetMDSlot(
+ NSSCKFWSlot *fwSlot);
/*
* NSSCKFWSlot_GetFWInstance
@@ -129,10 +137,8 @@ NSSCKFWSlot_GetMDSlot
*/
NSS_EXTERN NSSCKFWInstance *
-NSSCKFWSlot_GetFWInstance
-(
- NSSCKFWSlot *fwSlot
-);
+NSSCKFWSlot_GetFWInstance(
+ NSSCKFWSlot *fwSlot);
/*
* NSSCKFWSlot_GetMDInstance
@@ -140,10 +146,17 @@ NSSCKFWSlot_GetFWInstance
*/
NSS_EXTERN NSSCKMDInstance *
-NSSCKFWSlot_GetMDInstance
-(
- NSSCKFWSlot *fwSlot
-);
+NSSCKFWSlot_GetMDInstance(
+ NSSCKFWSlot *fwSlot);
+
+/*
+ * NSSCKFWSlot_GetSlotID
+ *
+ */
+
+NSS_EXTERN CK_SLOT_ID
+NSSCKFWSlot_GetSlotID(
+ NSSCKFWSlot *fwSlot);
/*
* NSSCKFWToken
@@ -161,10 +174,8 @@ NSSCKFWSlot_GetMDInstance
*/
NSS_EXTERN NSSCKMDToken *
-NSSCKFWToken_GetMDToken
-(
- NSSCKFWToken *fwToken
-);
+NSSCKFWToken_GetMDToken(
+ NSSCKFWToken *fwToken);
/*
* NSSCKFWToken_GetArena
@@ -172,11 +183,9 @@ NSSCKFWToken_GetMDToken
*/
NSS_EXTERN NSSArena *
-NSSCKFWToken_GetArena
-(
- NSSCKFWToken *fwToken,
- CK_RV *pError
-);
+NSSCKFWToken_GetArena(
+ NSSCKFWToken *fwToken,
+ CK_RV *pError);
/*
* NSSCKFWToken_GetFWSlot
@@ -184,10 +193,8 @@ NSSCKFWToken_GetArena
*/
NSS_EXTERN NSSCKFWSlot *
-NSSCKFWToken_GetFWSlot
-(
- NSSCKFWToken *fwToken
-);
+NSSCKFWToken_GetFWSlot(
+ NSSCKFWToken *fwToken);
/*
* NSSCKFWToken_GetMDSlot
@@ -195,10 +202,8 @@ NSSCKFWToken_GetFWSlot
*/
NSS_EXTERN NSSCKMDSlot *
-NSSCKFWToken_GetMDSlot
-(
- NSSCKFWToken *fwToken
-);
+NSSCKFWToken_GetMDSlot(
+ NSSCKFWToken *fwToken);
/*
* NSSCKFWToken_GetSessionState
@@ -206,10 +211,8 @@ NSSCKFWToken_GetMDSlot
*/
NSS_EXTERN CK_STATE
-NSSCKFWToken_GetSessionState
-(
- NSSCKFWToken *fwToken
-);
+NSSCKFWToken_GetSessionState(
+ NSSCKFWToken *fwToken);
/*
* NSSCKFWMechanism
@@ -225,10 +228,8 @@ NSSCKFWToken_GetSessionState
*/
NSS_EXTERN NSSCKMDMechanism *
-NSSCKFWMechanism_GetMDMechanism
-(
- NSSCKFWMechanism *fwMechanism
-);
+NSSCKFWMechanism_GetMDMechanism(
+ NSSCKFWMechanism *fwMechanism);
/*
* NSSCKFWMechanism_GetParameter
@@ -236,10 +237,8 @@ NSSCKFWMechanism_GetMDMechanism
*/
NSS_EXTERN NSSItem *
-NSSCKFWMechanism_GetParameter
-(
- NSSCKFWMechanism *fwMechanism
-);
+NSSCKFWMechanism_GetParameter(
+ NSSCKFWMechanism *fwMechanism);
/*
* NSSCKFWSession
@@ -250,6 +249,7 @@ NSSCKFWMechanism_GetParameter
* NSSCKFWSession_IsRWSession
* NSSCKFWSession_IsSO
* NSSCKFWSession_GetCurrentCryptoOperation
+ * NSSCKFWSession_GetFWSlot
*
*/
@@ -259,10 +259,8 @@ NSSCKFWMechanism_GetParameter
*/
NSS_EXTERN NSSCKMDSession *
-NSSCKFWSession_GetMDSession
-(
- NSSCKFWSession *fwSession
-);
+NSSCKFWSession_GetMDSession(
+ NSSCKFWSession *fwSession);
/*
* NSSCKFWSession_GetArena
@@ -270,11 +268,9 @@ NSSCKFWSession_GetMDSession
*/
NSS_EXTERN NSSArena *
-NSSCKFWSession_GetArena
-(
- NSSCKFWSession *fwSession,
- CK_RV *pError
-);
+NSSCKFWSession_GetArena(
+ NSSCKFWSession *fwSession,
+ CK_RV *pError);
/*
* NSSCKFWSession_CallNotification
@@ -282,11 +278,9 @@ NSSCKFWSession_GetArena
*/
NSS_EXTERN CK_RV
-NSSCKFWSession_CallNotification
-(
- NSSCKFWSession *fwSession,
- CK_NOTIFICATION event
-);
+NSSCKFWSession_CallNotification(
+ NSSCKFWSession *fwSession,
+ CK_NOTIFICATION event);
/*
* NSSCKFWSession_IsRWSession
@@ -294,10 +288,8 @@ NSSCKFWSession_CallNotification
*/
NSS_EXTERN CK_BBOOL
-NSSCKFWSession_IsRWSession
-(
- NSSCKFWSession *fwSession
-);
+NSSCKFWSession_IsRWSession(
+ NSSCKFWSession *fwSession);
/*
* NSSCKFWSession_IsSO
@@ -305,10 +297,8 @@ NSSCKFWSession_IsRWSession
*/
NSS_EXTERN CK_BBOOL
-NSSCKFWSession_IsSO
-(
- NSSCKFWSession *fwSession
-);
+NSSCKFWSession_IsSO(
+ NSSCKFWSession *fwSession);
/*
* NSSCKFWSession_GetCurrentCryptoOperation
@@ -316,11 +306,18 @@ NSSCKFWSession_IsSO
*/
NSS_EXTERN NSSCKFWCryptoOperation *
-NSSCKFWSession_GetCurrentCryptoOperation
-(
- NSSCKFWSession *fwSession,
- NSSCKFWCryptoOperationState state
-);
+NSSCKFWSession_GetCurrentCryptoOperation(
+ NSSCKFWSession *fwSession,
+ NSSCKFWCryptoOperationState state);
+
+/*
+ * NSSCKFWSession_GetFWSlot
+ *
+ */
+
+NSS_EXTERN NSSCKFWSlot *
+NSSCKFWSession_GetFWSlot(
+ NSSCKFWSession *fwSession);
/*
* NSSCKFWObject
@@ -340,91 +337,75 @@ NSSCKFWSession_GetCurrentCryptoOperation
*
*/
NSS_EXTERN NSSCKMDObject *
-NSSCKFWObject_GetMDObject
-(
- NSSCKFWObject *fwObject
-);
+NSSCKFWObject_GetMDObject(
+ NSSCKFWObject *fwObject);
/*
* NSSCKFWObject_GetArena
*
*/
NSS_EXTERN NSSArena *
-NSSCKFWObject_GetArena
-(
- NSSCKFWObject *fwObject,
- CK_RV *pError
-);
+NSSCKFWObject_GetArena(
+ NSSCKFWObject *fwObject,
+ CK_RV *pError);
/*
* NSSCKFWObject_IsTokenObject
*
*/
NSS_EXTERN CK_BBOOL
-NSSCKFWObject_IsTokenObject
-(
- NSSCKFWObject *fwObject
-);
+NSSCKFWObject_IsTokenObject(
+ NSSCKFWObject *fwObject);
/*
* NSSCKFWObject_GetAttributeCount
*
*/
NSS_EXTERN CK_ULONG
-NSSCKFWObject_GetAttributeCount
-(
- NSSCKFWObject *fwObject,
- CK_RV *pError
-);
+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_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_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_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
-);
+NSSCKFWObject_GetObjectSize(
+ NSSCKFWObject *fwObject,
+ CK_RV *pError);
/*
* NSSCKFWFindObjects
@@ -439,10 +420,8 @@ NSSCKFWObject_GetObjectSize
*/
NSS_EXTERN NSSCKMDFindObjects *
-NSSCKFWFindObjects_GetMDFindObjects
-(
- NSSCKFWFindObjects *
-);
+NSSCKFWFindObjects_GetMDFindObjects(
+ NSSCKFWFindObjects *);
/*
* NSSCKFWMutex
@@ -459,10 +438,8 @@ NSSCKFWFindObjects_GetMDFindObjects
*/
NSS_EXTERN CK_RV
-NSSCKFWMutex_Destroy
-(
- NSSCKFWMutex *mutex
-);
+NSSCKFWMutex_Destroy(
+ NSSCKFWMutex *mutex);
/*
* NSSCKFWMutex_Lock
@@ -470,10 +447,8 @@ NSSCKFWMutex_Destroy
*/
NSS_EXTERN CK_RV
-NSSCKFWMutex_Lock
-(
- NSSCKFWMutex *mutex
-);
+NSSCKFWMutex_Lock(
+ NSSCKFWMutex *mutex);
/*
* NSSCKFWMutex_Unlock
@@ -481,10 +456,7 @@ NSSCKFWMutex_Lock
*/
NSS_EXTERN CK_RV
-NSSCKFWMutex_Unlock
-(
- NSSCKFWMutex *mutex
-);
+NSSCKFWMutex_Unlock(
+ NSSCKFWMutex *mutex);
#endif /* NSSCKFW_H */
-
diff --git a/nss/lib/ckfw/nssckfwc.h b/nss/lib/ckfw/nssckfwc.h
index 3c11e96..734a67c 100644
--- a/nss/lib/ckfw/nssckfwc.h
+++ b/nss/lib/ckfw/nssckfwc.h
@@ -8,7 +8,7 @@
/*
* nssckfwc.h
*
- * This file prototypes all of the NSS Cryptoki Framework "wrapper"
+ * 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.
@@ -104,34 +104,28 @@
*
*/
NSS_EXTERN CK_RV
-NSSCKFWC_Initialize
-(
- NSSCKFWInstance **pFwInstance,
- NSSCKMDInstance *mdInstance,
- CK_VOID_PTR pInitArgs
-);
+NSSCKFWC_Initialize(
+ NSSCKFWInstance **pFwInstance,
+ NSSCKMDInstance *mdInstance,
+ CK_VOID_PTR pInitArgs);
/*
* NSSCKFWC_Finalize
*
*/
NSS_EXTERN CK_RV
-NSSCKFWC_Finalize
-(
- NSSCKFWInstance **pFwInstance
-);
+NSSCKFWC_Finalize(
+ NSSCKFWInstance **pFwInstance);
/*
* NSSCKFWC_GetInfo
*
*/
NSS_EXTERN CK_RV
-NSSCKFWC_GetInfo
-(
- NSSCKFWInstance *fwInstance,
- CK_INFO_PTR pInfo
-);
-
+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"
@@ -143,871 +137,743 @@ NSSCKFWC_GetInfo
*
*/
NSS_EXTERN CK_RV
-NSSCKFWC_GetSlotList
-(
- NSSCKFWInstance *fwInstance,
- CK_BBOOL tokenPresent,
- CK_SLOT_ID_PTR pSlotList,
- CK_ULONG_PTR pulCount
-);
-
+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_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_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_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_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_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_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_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_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_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_CloseSession(
+ NSSCKFWInstance *fwInstance,
+ CK_SESSION_HANDLE hSession);
/*
* NSSCKFWC_CloseAllSessions
*
*/
NSS_EXTERN CK_RV
-NSSCKFWC_CloseAllSessions
-(
- NSSCKFWInstance *fwInstance,
- CK_SLOT_ID slotID
-);
+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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_GetFunctionStatus(
+ NSSCKFWInstance *fwInstance,
+ CK_SESSION_HANDLE hSession);
/*
* NSSCKFWC_CancelFunction
*
*/
NSS_EXTERN CK_RV
-NSSCKFWC_CancelFunction
-(
- NSSCKFWInstance *fwInstance,
- CK_SESSION_HANDLE hSession
-);
+NSSCKFWC_CancelFunction(
+ NSSCKFWInstance *fwInstance,
+ CK_SESSION_HANDLE hSession);
#endif /* NSSCKFWC_H */
diff --git a/nss/lib/ckfw/nssckfwt.h b/nss/lib/ckfw/nssckfwt.h
index 4c4fad2..cd015d5 100644
--- a/nss/lib/ckfw/nssckfwt.h
+++ b/nss/lib/ckfw/nssckfwt.h
@@ -51,7 +51,6 @@ typedef struct NSSCKFWMechanismStr NSSCKFWMechanism;
struct NSSCKFWCryptoOperationStr;
typedef struct NSSCKFWCryptoOperationStr NSSCKFWCryptoOperation;
-
/*
* NSSCKFWSession
*
@@ -87,7 +86,7 @@ typedef struct NSSCKFWMutexStr NSSCKFWMutex;
typedef enum {
SingleThreaded,
MultiThreaded
-} CryptokiLockingState ;
+} CryptokiLockingState;
/* used as an index into an array, make sure it starts at '0' */
typedef enum {
diff --git a/nss/lib/ckfw/nssckmdt.h b/nss/lib/ckfw/nssckmdt.h
index 2c3aa2e..d98f9b0 100644
--- a/nss/lib/ckfw/nssckmdt.h
+++ b/nss/lib/ckfw/nssckmdt.h
@@ -44,9 +44,9 @@ typedef struct NSSCKMDObjectStr NSSCKMDObject;
*/
typedef struct {
- PRBool needsFreeing;
- NSSItem* item;
-} NSSCKFWItem ;
+ PRBool needsFreeing;
+ NSSItem *item;
+} NSSCKFWItem;
/*
* NSSCKMDInstance
@@ -61,152 +61,147 @@ typedef struct {
*/
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
- );
-
- /*
+ /*
+ * 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
+ * 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;
+ 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
*
@@ -220,165 +215,161 @@ struct NSSCKMDInstanceStr {
*/
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;
+ /*
+ * 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;
};
/*
@@ -394,444 +385,437 @@ struct NSSCKMDSlotStr {
*/
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;
+ /*
+ * 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;
};
/*
@@ -847,279 +831,275 @@ struct NSSCKMDTokenStr {
*/
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;
+ /*
+ * 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;
};
/*
@@ -1135,54 +1115,52 @@ struct NSSCKMDSessionStr {
*/
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;
+ /*
+ * 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;
};
/*
@@ -1199,182 +1177,179 @@ struct NSSCKMDFindObjectsStr {
*/
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;
+ /*
+ * 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;
};
/*
@@ -1383,365 +1358,352 @@ struct NSSCKMDCryptoOperationStr {
*/
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;
+ /*
+ * 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;
};
/*
@@ -1756,190 +1718,187 @@ struct NSSCKMDMechanismStr {
*/
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;
+ /*
+ * 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/nss/lib/ckfw/nssckt.h b/nss/lib/ckfw/nssckt.h
index 5ed534c..b50a88f 100644
--- a/nss/lib/ckfw/nssckt.h
+++ b/nss/lib/ckfw/nssckt.h
@@ -10,4 +10,3 @@ typedef CK_ATTRIBUTE_TYPE CK_PTR CK_ATTRIBUTE_TYPE_PTR;
#define CK_ENTRY
#endif /* _NSSCKT_H_ */
-
diff --git a/nss/lib/ckfw/nssmkey/ckmk.h b/nss/lib/ckfw/nssmkey/ckmk.h
index 9d8202f..4f3ab82 100644
--- a/nss/lib/ckfw/nssmkey/ckmk.h
+++ b/nss/lib/ckfw/nssmkey/ckmk.h
@@ -36,9 +36,9 @@
* to this PKCS #11 module.
*/
struct ckmkRawObjectStr {
- CK_ULONG n;
- const CK_ATTRIBUTE_TYPE *types;
- const NSSItem *items;
+ CK_ULONG n;
+ const CK_ATTRIBUTE_TYPE *types;
+ const NSSItem *items;
};
typedef struct ckmkRawObjectStr ckmkRawObject;
@@ -46,40 +46,40 @@ 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;
+ 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,
+ ckmkRaw,
+ ckmkItem,
} ckmkObjectType;
/*
@@ -87,112 +87,96 @@ typedef enum {
* 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;
+ 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 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_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
-);
+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_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_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_ckmk_FetchAttribute(
+ ckmkInternalObject *io,
+ CK_ATTRIBUTE_TYPE type,
+ CK_RV *pError);
NSS_EXTERN void
-nss_ckmk_DestroyInternalObject
-(
- ckmkInternalObject *io
-);
+nss_ckmk_DestroyInternalObject(
+ ckmkInternalObject *io);
unsigned char *
-nss_ckmk_DERUnwrap
-(
- unsigned char *src,
- int size,
- int *outSize,
- unsigned char **next
-);
+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
-);
+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])))
+#define NSS_CKMK_ARRAY_SIZE(x) ((sizeof(x)) / (sizeof((x)[0])))
#ifdef DEBUG
-#define CKMK_MACERR(str,err) cssmPerror(str,err)
+#define CKMK_MACERR(str, err) cssmPerror(str, err)
#else
-#define CKMK_MACERR(str,err)
+#define CKMK_MACERR(str, err)
#endif
-
+
#endif
diff --git a/nss/lib/ckfw/nssmkey/ckmkver.c b/nss/lib/ckfw/nssmkey/ckmkver.c
index 0f68976..2b99f1e 100644
--- a/nss/lib/ckfw/nssmkey/ckmkver.c
+++ b/nss/lib/ckfw/nssmkey/ckmkver.c
@@ -14,5 +14,4 @@
/*
* Version information
*/
-const char __nss_ckmk_version[] = "Version: NSS Access to the MAC OS X Key Ring "
- NSS_CKMK_LIBRARY_VERSION _DEBUG_STRING;
+const char __nss_ckmk_version[] = "Version: NSS Access to the MAC OS X Key Ring " NSS_CKMK_LIBRARY_VERSION _DEBUG_STRING;
diff --git a/nss/lib/ckfw/nssmkey/manchor.c b/nss/lib/ckfw/nssmkey/manchor.c
index 1b4d70b..3b8bc2d 100644
--- a/nss/lib/ckfw/nssmkey/manchor.c
+++ b/nss/lib/ckfw/nssmkey/manchor.c
@@ -6,7 +6,7 @@
* 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
+ * shared library, which is required for dynamic loading. See the
* comments in nssck.api for more information.
*/
diff --git a/nss/lib/ckfw/nssmkey/mconstants.c b/nss/lib/ckfw/nssmkey/mconstants.c
index 89df4f2..c26298a 100644
--- a/nss/lib/ckfw/nssmkey/mconstants.c
+++ b/nss/lib/ckfw/nssmkey/mconstants.c
@@ -19,40 +19,43 @@
#include "nssmkey.h"
NSS_IMPLEMENT_DATA const CK_VERSION
-nss_ckmk_CryptokiVersion = {
- NSS_CKMK_CRYPTOKI_VERSION_MAJOR,
- NSS_CKMK_CRYPTOKI_VERSION_MINOR };
+ 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_ckmk_ManufacturerID = (NSSUTF8 *)"Mozilla Foundation";
NSS_IMPLEMENT_DATA const NSSUTF8 *
-nss_ckmk_LibraryDescription = (NSSUTF8 *) "NSS Access to Mac OS X Key Ring";
+ 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_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_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_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_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_ckmk_TokenLabel = (NSSUTF8 *)"Mac OS X Key Ring";
NSS_IMPLEMENT_DATA const NSSUTF8 *
-nss_ckmk_TokenModel = (NSSUTF8 *) "1";
+ nss_ckmk_TokenModel = (NSSUTF8 *)"1";
NSS_IMPLEMENT_DATA const NSSUTF8 *
-nss_ckmk_TokenSerialNumber = (NSSUTF8 *) "1";
-
+ nss_ckmk_TokenSerialNumber = (NSSUTF8 *)"1";
diff --git a/nss/lib/ckfw/nssmkey/mfind.c b/nss/lib/ckfw/nssmkey/mfind.c
index 8f22bda..d193a8d 100644
--- a/nss/lib/ckfw/nssmkey/mfind.c
+++ b/nss/lib/ckfw/nssmkey/mfind.c
@@ -14,354 +14,339 @@
*/
struct ckmkFOStr {
- NSSArena *arena;
- CK_ULONG n;
- CK_ULONG i;
- ckmkInternalObject **objs;
+ 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
-)
+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;
+ 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
-)
+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;
+ struct ckmkFOStr *fo = (struct ckmkFOStr *)mdFindObjects->etc;
+ ckmkInternalObject *io;
- if( fo->i == fo->n ) {
- *pError = CKR_OK;
- return (NSSCKMDObject *)NULL;
- }
+ if (fo->i == fo->n) {
+ *pError = CKR_OK;
+ return (NSSCKMDObject *)NULL;
+ }
- io = fo->objs[ fo->i ];
- fo->i++;
+ io = fo->objs[fo->i];
+ fo->i++;
- return nss_ckmk_CreateMDObject(arena, io, pError);
+ return nss_ckmk_CreateMDObject(arena, io, pError);
}
static CK_BBOOL
-ckmk_attrmatch
-(
- CK_ATTRIBUTE_PTR a,
- ckmkInternalObject *o
-)
+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;
- }
+ PRBool prb;
+ const NSSItem *b;
+ CK_RV error;
+
+ b = nss_ckmk_FetchAttribute(o, a->type, &error);
+ if (b == NULL) {
+ return CK_FALSE;
}
- return CK_FALSE;
- }
- prb = nsslibc_memequal(a->pValue, b->data, b->size, (PRStatus *)NULL);
+ 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;
+ }
- if( PR_TRUE == prb ) {
- return CK_TRUE;
- } else {
- 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
-)
+ckmk_match(
+ CK_ATTRIBUTE_PTR pTemplate,
+ CK_ULONG ulAttributeCount,
+ ckmkInternalObject *o)
{
- CK_ULONG i;
+ CK_ULONG i;
- for( i = 0; i < ulAttributeCount; i++ ) {
- if (CK_FALSE == ckmk_attrmatch(&pTemplate[i], o)) {
- return CK_FALSE;
+ for (i = 0; i < ulAttributeCount; i++) {
+ if (CK_FALSE == ckmk_attrmatch(&pTemplate[i], o)) {
+ return CK_FALSE;
+ }
}
- }
- /* Every attribute passed */
- return CK_TRUE;
+ /* 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++; \
- }
-
+#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
-)
+ 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));
+ 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;
+ 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
-)
+ 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);
+ 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;
}
- }
-
- /*
- * 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;
+
+ return count;
loser:
- nss_ZFreeIf(*listp);
- return 0;
+ nss_ZFreeIf(*listp);
+ return 0;
}
-
NSS_IMPLEMENT NSSCKMDFindObjects *
-nss_ckmk_FindObjectsInit
-(
- NSSCKFWSession *fwSession,
- CK_ATTRIBUTE_PTR pTemplate,
- CK_ULONG ulAttributeCount,
- CK_RV *pError
-)
+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;
-}
+ /* 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/nss/lib/ckfw/nssmkey/minst.c b/nss/lib/ckfw/nssmkey/minst.c
index 923ba10..fcb96c6 100644
--- a/nss/lib/ckfw/nssmkey/minst.c
+++ b/nss/lib/ckfw/nssmkey/minst.c
@@ -7,7 +7,7 @@
/*
* nssmkey/minstance.c
*
- * This file implements the NSSCKMDInstance object for the
+ * This file implements the NSSCKMDInstance object for the
* "nssmkey" cryptoki module.
*/
@@ -16,96 +16,82 @@
*/
static CK_ULONG
-ckmk_mdInstance_GetNSlots
-(
- NSSCKMDInstance *mdInstance,
- NSSCKFWInstance *fwInstance,
- CK_RV *pError
-)
+ckmk_mdInstance_GetNSlots(
+ NSSCKMDInstance *mdInstance,
+ NSSCKFWInstance *fwInstance,
+ CK_RV *pError)
{
- return (CK_ULONG)1;
+ return (CK_ULONG)1;
}
static CK_VERSION
-ckmk_mdInstance_GetCryptokiVersion
-(
- NSSCKMDInstance *mdInstance,
- NSSCKFWInstance *fwInstance
-)
+ckmk_mdInstance_GetCryptokiVersion(
+ NSSCKMDInstance *mdInstance,
+ NSSCKFWInstance *fwInstance)
{
- return nss_ckmk_CryptokiVersion;
+ return nss_ckmk_CryptokiVersion;
}
static NSSUTF8 *
-ckmk_mdInstance_GetManufacturerID
-(
- NSSCKMDInstance *mdInstance,
- NSSCKFWInstance *fwInstance,
- CK_RV *pError
-)
+ckmk_mdInstance_GetManufacturerID(
+ NSSCKMDInstance *mdInstance,
+ NSSCKFWInstance *fwInstance,
+ CK_RV *pError)
{
- return (NSSUTF8 *)nss_ckmk_ManufacturerID;
+ return (NSSUTF8 *)nss_ckmk_ManufacturerID;
}
static NSSUTF8 *
-ckmk_mdInstance_GetLibraryDescription
-(
- NSSCKMDInstance *mdInstance,
- NSSCKFWInstance *fwInstance,
- CK_RV *pError
-)
+ckmk_mdInstance_GetLibraryDescription(
+ NSSCKMDInstance *mdInstance,
+ NSSCKFWInstance *fwInstance,
+ CK_RV *pError)
{
- return (NSSUTF8 *)nss_ckmk_LibraryDescription;
+ return (NSSUTF8 *)nss_ckmk_LibraryDescription;
}
static CK_VERSION
-ckmk_mdInstance_GetLibraryVersion
-(
- NSSCKMDInstance *mdInstance,
- NSSCKFWInstance *fwInstance
-)
+ckmk_mdInstance_GetLibraryVersion(
+ NSSCKMDInstance *mdInstance,
+ NSSCKFWInstance *fwInstance)
{
- return nss_ckmk_LibraryVersion;
+ return nss_ckmk_LibraryVersion;
}
static CK_RV
-ckmk_mdInstance_GetSlots
-(
- NSSCKMDInstance *mdInstance,
- NSSCKFWInstance *fwInstance,
- NSSCKMDSlot *slots[]
-)
+ckmk_mdInstance_GetSlots(
+ NSSCKMDInstance *mdInstance,
+ NSSCKFWInstance *fwInstance,
+ NSSCKMDSlot *slots[])
{
- slots[0] = (NSSCKMDSlot *)&nss_ckmk_mdSlot;
- return CKR_OK;
+ slots[0] = (NSSCKMDSlot *)&nss_ckmk_mdSlot;
+ return CKR_OK;
}
static CK_BBOOL
-ckmk_mdInstance_ModuleHandlesSessionObjects
-(
- NSSCKMDInstance *mdInstance,
- NSSCKFWInstance *fwInstance
-)
+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;
+ /* 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 */
-};
+ 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/nss/lib/ckfw/nssmkey/mobject.c b/nss/lib/ckfw/nssmkey/mobject.c
index 2013e7e..b19a8fd 100644
--- a/nss/lib/ckfw/nssmkey/mobject.c
+++ b/nss/lib/ckfw/nssmkey/mobject.c
@@ -90,37 +90,45 @@ 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_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) };
+ (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};
+ (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)
+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);
+ 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
@@ -130,48 +138,46 @@ itemdump(char *str, void *data, int size, CK_RV error)
* the ANS1_Decoder for this work...
*/
unsigned char *
-nss_ckmk_DERUnwrap
-(
- unsigned char *src,
- int size,
- int *outSize,
- unsigned char **next
-)
+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;
+ 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;
}
/*
@@ -179,74 +185,68 @@ nss_ckmk_DERUnwrap
* 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
-)
+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;
+ 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;
+ 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
-)
+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;
+ 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
-)
+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;
+ 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;
}
/*
@@ -254,33 +254,31 @@ nss_ckmk_GetBoolAttribute
* free the string.
*/
char *
-nss_ckmk_GetStringAttribute
-(
- CK_ATTRIBUTE_TYPE type,
- CK_ATTRIBUTE *template,
- CK_ULONG templateSize,
- CK_RV *pError
-)
+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;
+ 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;
}
/*
@@ -291,230 +289,224 @@ nss_ckmk_GetStringAttribute
*/
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;
-}
+{
+ 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
-)
+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;
+ 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;
+ 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
-)
+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;
+ 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
-)
+ckmk_GetDataAttribute(
+ ckmkInternalObject *io,
+ SecItemAttr itemAttr,
+ NSSItem *item,
+ char *dbString)
{
- return ckmk_GetCommonAttribute(io, itemAttr, PR_FALSE, item, 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
-)
+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);
+ 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;
+ 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); \
- } \
+ 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 ;
+ 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)
@@ -527,379 +519,363 @@ loser:
* fetch the unique identifier for each object type.
*/
static void
-ckmk_FetchHashKey
-(
- ckmkInternalObject *io
-)
+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)");
- }
+ 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
-)
+static void
+ckmk_fetchCert(
+ ckmkInternalObject *io)
{
- CK_RV error;
- unsigned char * cert, *next;
- int certSize, thisEntrySize;
+ 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;
- 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) {
+ /* 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;
- }
- /* 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;
+
+ /* 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
-)
+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;
- }
+ 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 */
+ 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
+ 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;
+ io->u.item.modulus.size = modLen;
+ return;
}
const NSSItem *
-ckmk_FetchCertAttribute
-(
- ckmkInternalObject *io,
- CK_ATTRIBUTE_TYPE type,
- CK_RV *pError
-)
+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;
+ 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
-)
+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;
+ 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
-)
+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;
+ 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)
+ /* 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;
- }
+ 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
-)
+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];
- }
+ 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;
}
- *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);
- }
+ if (CKA_ID == type) {
+ itemdump("id: ", value->data, value->size, *pError);
+ }
#endif
- return value;
+ return value;
}
-static void
-ckmk_removeObjectFromHash
-(
- ckmkInternalObject *io
-);
+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
+ * Destroy
* IsTokenObject - CK_TRUE
* GetAttributeCount
* GetAttributeTypes
@@ -910,541 +886,514 @@ ckmk_removeObjectFromHash
*/
static CK_RV
-ckmk_mdObject_Destroy
-(
- NSSCKMDObject *mdObject,
- NSSCKFWObject *fwObject,
- NSSCKMDSession *mdSession,
- NSSCKFWSession *fwSession,
- NSSCKMDToken *mdToken,
- NSSCKFWToken *fwToken,
- NSSCKMDInstance *mdInstance,
- NSSCKFWInstance *fwInstance
-)
+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;
+ 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;
- }
+ 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);
- }
+ /* 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);
+ /* remove it from the hash */
+ ckmk_removeObjectFromHash(io);
- /* free the puppy.. */
- nss_ckmk_DestroyInternalObject(io);
+ /* free the puppy.. */
+ nss_ckmk_DestroyInternalObject(io);
- return CKR_OK;
+ 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
-)
+ckmk_mdObject_IsTokenObject(
+ NSSCKMDObject *mdObject,
+ NSSCKFWObject *fwObject,
+ NSSCKMDSession *mdSession,
+ NSSCKFWSession *fwSession,
+ NSSCKMDToken *mdToken,
+ NSSCKFWToken *fwToken,
+ NSSCKMDInstance *mdInstance,
+ NSSCKFWInstance *fwInstance)
{
- return CK_TRUE;
+ 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
-)
+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;
+ 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
-)
+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;
+ 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
-)
+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;
+ ckmkInternalObject *io = (ckmkInternalObject *)mdObject->etc;
- const NSSItem *b;
+ const NSSItem *b;
- b = nss_ckmk_FetchAttribute(io, attribute, pError);
+ b = nss_ckmk_FetchAttribute(io, attribute, pError);
- if ((const NSSItem *)NULL == b) {
- return 0;
- }
- return b->size;
+ 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
-)
+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");
+ 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);
+ 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;
+ 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
-)
+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);
+ NSSCKFWItem mdItem;
+ ckmkInternalObject *io = (ckmkInternalObject *)mdObject->etc;
+ mdItem.needsFreeing = PR_FALSE;
+ mdItem.item = (NSSItem *)nss_ckmk_FetchAttribute(io, attribute, pError);
- return mdItem;
+ 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
-)
+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;
+ CK_ULONG rv = 1;
- /* size is irrelevant to this token */
- return rv;
+ /* 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 */
-};
+ 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
-)
+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 ((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 (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;
+ 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
-)
+ckmk_removeObjectFromHash(
+ ckmkInternalObject *io)
{
- NSSItem *key = &io->hashKey;
+ NSSItem *key = &io->hashKey;
- if ((nssHash *)NULL == ckmkInternalObjectHash) {
+ if ((nssHash *)NULL == ckmkInternalObjectHash) {
+ return;
+ }
+ if (key->size == 0) {
+ ckmk_FetchHashKey(io);
+ }
+ nssHash_Remove(ckmkInternalObjectHash, key);
return;
- }
- if (key->size == 0) {
- ckmk_FetchHashKey(io);
- }
- nssHash_Remove(ckmkInternalObjectHash, key);
- return;
}
-
void
-nss_ckmk_DestroyInternalObject
-(
- ckmkInternalObject *io
-)
+nss_ckmk_DestroyInternalObject(
+ ckmkInternalObject *io)
{
- switch (io->type) {
- case ckmkRaw:
+ 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;
- 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
-)
+nss_ckmk_NewInternalObject(
+ CK_OBJECT_CLASS objClass,
+ SecKeychainItemRef itemRef,
+ SecItemClass itemClass,
+ CK_RV *pError)
{
- ckmkInternalObject *io = nss_ZNEW(NULL, ckmkInternalObject);
+ ckmkInternalObject *io = nss_ZNEW(NULL, ckmkInternalObject);
- if ((ckmkInternalObject *)NULL == io) {
- *pError = CKR_HOST_MEMORY;
+ 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;
- }
- 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
+ * 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
-)
+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);
+ OSStatus macErr;
+ CFArrayRef searchList = 0;
+ CK_RV error = CKR_OK;
+
+ macErr = SecKeychainCopyDefault(keychainRef);
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? */
- }
+ 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;
+ if (0 != searchList) {
+ CFRelease(searchList);
+ }
+ return error;
}
static ckmkInternalObject *
-nss_ckmk_CreateCertificate
-(
- NSSCKFWSession *fwSession,
- CK_ATTRIBUTE_PTR pTemplate,
- CK_ULONG ulAttributeCount,
- CK_RV *pError
-)
+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;
+ 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("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);
+ CKMK_MACERR("Create cert from data Failed", macErr);
+ *pError = CKR_GENERAL_ERROR; /* need to map macErr */
+ goto loser;
}
- 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");
+
+ *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;
- }
+ 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;
+ if (0 != itemRef) {
+ CFRelease(itemRef);
+ }
+ if (0 != keychainRef) {
+ CFRelease(keychainRef);
+ }
+
+ return io;
}
/*
@@ -1457,8 +1406,8 @@ struct ckmk_AttributeStr {
typedef struct ckmk_AttributeStr ckmk_Attribute;
/*
-** A PKCS#8 private key info object
-*/
+ ** A PKCS#8 private key info object
+ */
struct PrivateKeyInfoStr {
PLArenaPool *arena;
SECItem version;
@@ -1470,23 +1419,23 @@ 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 }
-};
+ { 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 },
+ { SEC_ASN1_SET_OF, offsetof(ckmk_Attribute, attrValue),
+ SEC_AnyTemplate },
{ 0 }
};
@@ -1499,91 +1448,89 @@ 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_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 },
+ offsetof(PrivateKeyInfo, attributes), ckmk_SetOfAttributeTemplate },
{ 0 }
};
#define CKMK_PRIVATE_KEY_INFO_VERSION 0
static CK_RV
-ckmk_CreateRSAKeyBlob
-(
- RSAPrivateKey *lk,
- NSSItem *keyBlob
-)
+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;
+ 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;
+ 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
@@ -1591,334 +1538,324 @@ loser:
*/
#define IMPORTED_NAME "Imported Private Key"
static CK_RV
-ckmk_FindImportedKey
-(
- SecKeychainRef keychainRef,
- SecItemClass itemClass,
- SecKeychainItemRef *outItemRef
-)
+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;
+ SecKeychainSearchRef searchRef = 0;
+ SecKeychainItemRef newItemRef;
- 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! */
+ 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
-)
+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) {
+ 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");
+ fprintf(stderr, "couldn't find key in keychain \n");
#endif
- goto loser;
- }
-
+ goto loser;
+ }
- /* set the CKA_ID and the CKA_LABEL */
- error = nss_ckmk_GetAttribute(CKA_ID, pTemplate,
+ /* 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");
+ 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);
+ 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 {
+ }
+ 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");
- }
+ 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);
- }
+ io = nss_ckmk_NewInternalObject(CKO_PRIVATE_KEY, itemRef,
+ CSSM_DL_DB_RECORD_PRIVATE_KEY, pError);
+ if ((ckmkInternalObject *)NULL == io) {
+ CFRelease(itemRef);
+ }
- return io;
+ 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;
+ /* 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
-)
+nss_ckmk_CreateObject(
+ NSSCKFWSession *fwSession,
+ CK_ATTRIBUTE_PTR pTemplate,
+ CK_ULONG ulAttributeCount,
+ CK_RV *pError)
{
- CK_OBJECT_CLASS objClass;
- ckmkInternalObject *io = NULL;
- 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;
- }
+ CK_OBJECT_CLASS objClass;
+ ckmkInternalObject *io = NULL;
+ 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 */
- }
+ 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);
+ 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/nss/lib/ckfw/nssmkey/mrsa.c b/nss/lib/ckfw/nssmkey/mrsa.c
index 8cf46ad..00175b4 100644
--- a/nss/lib/ckfw/nssmkey/mrsa.c
+++ b/nss/lib/ckfw/nssmkey/mrsa.c
@@ -9,196 +9,183 @@
* 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
-);
+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;
+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
+ 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
-)
+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;
+ 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);
+ 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;
+ 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);
+ 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;
+ 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
-)
+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;
+ 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
-)
+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);
+ ckmkInternalCryptoOperationRSAPriv *iOperation =
+ (ckmkInternalCryptoOperationRSAPriv *)mdOperation->etc;
+ const NSSItem *modulus =
+ nss_ckmk_FetchAttribute(iOperation->iKey, CKA_MODULUS, pError);
- return modulus->size;
+ return modulus->size;
}
-
/*
* ckmk_mdCryptoOperationRSADecrypt_GetOperationLength
* we won't know the length until we actually decrypt the
@@ -206,105 +193,101 @@ ckmk_mdCryptoOperationRSA_GetFinalLength
* 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
-)
+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) {
+ 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;
- }
-
- 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
+ * 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
-)
+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;
+ 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;
}
/*
@@ -312,199 +295,185 @@ ckmk_mdCryptoOperationRSADecrypt_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
-)
+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) {
+ 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);
- return CKR_BUFFER_TOO_SMALL;
- }
- nsslibc_memcpy(output->data, cssmOutput.Data, cssmOutput.Length);
- free(cssmOutput.Data);
- output->size = cssmOutput.Length;
+ output->size = cssmOutput.Length;
- return CKR_OK;
+ 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 */
-};
+ 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 */
-};
+ 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
-)
+ckmk_mdMechanismRSA_Destroy(
+ NSSCKMDMechanism *mdMechanism,
+ NSSCKFWMechanism *fwMechanism,
+ NSSCKMDInstance *mdInstance,
+ NSSCKFWInstance *fwInstance)
{
- nss_ZFreeIf(fwMechanism);
+ 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
-)
+ckmk_mdMechanismRSA_GetMinKeySize(
+ NSSCKMDMechanism *mdMechanism,
+ NSSCKFWMechanism *fwMechanism,
+ NSSCKMDToken *mdToken,
+ NSSCKFWToken *fwToken,
+ NSSCKMDInstance *mdInstance,
+ NSSCKFWInstance *fwInstance,
+ CK_RV *pError)
{
- return 384;
+ 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
-)
+ckmk_mdMechanismRSA_GetMaxKeySize(
+ NSSCKMDMechanism *mdMechanism,
+ NSSCKFWMechanism *fwMechanism,
+ NSSCKMDToken *mdToken,
+ NSSCKFWToken *fwToken,
+ NSSCKMDInstance *mdInstance,
+ NSSCKFWInstance *fwInstance,
+ CK_RV *pError)
{
- return 16384;
+ 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
-)
+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);
+ 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
-)
+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);
+ 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 */
-};
+ 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/nss/lib/ckfw/nssmkey/msession.c b/nss/lib/ckfw/nssmkey/msession.c
index 6e1e195..e6a2924 100644
--- a/nss/lib/ckfw/nssmkey/msession.c
+++ b/nss/lib/ckfw/nssmkey/msession.c
@@ -7,87 +7,81 @@
/*
* nssmkey/msession.c
*
- * This file implements the NSSCKMDSession object for the
+ * 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
-)
+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);
+ 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
-)
+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);
+ return nss_ckmk_CreateObject(fwSession, pTemplate, ulAttributeCount, pError);
}
NSS_IMPLEMENT NSSCKMDSession *
-nss_ckmk_CreateSession
-(
- NSSCKFWSession *fwSession,
- CK_RV *pError
-)
+nss_ckmk_CreateSession(
+ NSSCKFWSession *fwSession,
+ CK_RV *pError)
{
- NSSArena *arena;
- NSSCKMDSession *rv;
+ NSSArena *arena;
+ NSSCKMDSession *rv;
- arena = NSSCKFWSession_GetArena(fwSession, pError);
- if( (NSSArena *)NULL == arena ) {
- return (NSSCKMDSession *)NULL;
- }
+ 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 = 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 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 */
+ 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;
+ return rv;
}
diff --git a/nss/lib/ckfw/nssmkey/mslot.c b/nss/lib/ckfw/nssmkey/mslot.c
index 7a43212..b2747ff 100644
--- a/nss/lib/ckfw/nssmkey/mslot.c
+++ b/nss/lib/ckfw/nssmkey/mslot.c
@@ -12,80 +12,70 @@
*/
static NSSUTF8 *
-ckmk_mdSlot_GetSlotDescription
-(
- NSSCKMDSlot *mdSlot,
- NSSCKFWSlot *fwSlot,
- NSSCKMDInstance *mdInstance,
- NSSCKFWInstance *fwInstance,
- CK_RV *pError
-)
+ckmk_mdSlot_GetSlotDescription(
+ NSSCKMDSlot *mdSlot,
+ NSSCKFWSlot *fwSlot,
+ NSSCKMDInstance *mdInstance,
+ NSSCKFWInstance *fwInstance,
+ CK_RV *pError)
{
- return (NSSUTF8 *)nss_ckmk_SlotDescription;
+ return (NSSUTF8 *)nss_ckmk_SlotDescription;
}
static NSSUTF8 *
-ckmk_mdSlot_GetManufacturerID
-(
- NSSCKMDSlot *mdSlot,
- NSSCKFWSlot *fwSlot,
- NSSCKMDInstance *mdInstance,
- NSSCKFWInstance *fwInstance,
- CK_RV *pError
-)
+ckmk_mdSlot_GetManufacturerID(
+ NSSCKMDSlot *mdSlot,
+ NSSCKFWSlot *fwSlot,
+ NSSCKMDInstance *mdInstance,
+ NSSCKFWInstance *fwInstance,
+ CK_RV *pError)
{
- return (NSSUTF8 *)nss_ckmk_ManufacturerID;
+ return (NSSUTF8 *)nss_ckmk_ManufacturerID;
}
static CK_VERSION
-ckmk_mdSlot_GetHardwareVersion
-(
- NSSCKMDSlot *mdSlot,
- NSSCKFWSlot *fwSlot,
- NSSCKMDInstance *mdInstance,
- NSSCKFWInstance *fwInstance
-)
+ckmk_mdSlot_GetHardwareVersion(
+ NSSCKMDSlot *mdSlot,
+ NSSCKFWSlot *fwSlot,
+ NSSCKMDInstance *mdInstance,
+ NSSCKFWInstance *fwInstance)
{
- return nss_ckmk_HardwareVersion;
+ return nss_ckmk_HardwareVersion;
}
static CK_VERSION
-ckmk_mdSlot_GetFirmwareVersion
-(
- NSSCKMDSlot *mdSlot,
- NSSCKFWSlot *fwSlot,
- NSSCKMDInstance *mdInstance,
- NSSCKFWInstance *fwInstance
-)
+ckmk_mdSlot_GetFirmwareVersion(
+ NSSCKMDSlot *mdSlot,
+ NSSCKFWSlot *fwSlot,
+ NSSCKMDInstance *mdInstance,
+ NSSCKFWInstance *fwInstance)
{
- return nss_ckmk_FirmwareVersion;
+ return nss_ckmk_FirmwareVersion;
}
static NSSCKMDToken *
-ckmk_mdSlot_GetToken
-(
- NSSCKMDSlot *mdSlot,
- NSSCKFWSlot *fwSlot,
- NSSCKMDInstance *mdInstance,
- NSSCKFWInstance *fwInstance,
- CK_RV *pError
-)
+ckmk_mdSlot_GetToken(
+ NSSCKMDSlot *mdSlot,
+ NSSCKFWSlot *fwSlot,
+ NSSCKMDInstance *mdInstance,
+ NSSCKFWInstance *fwInstance,
+ CK_RV *pError)
{
- return (NSSCKMDToken *)&nss_ckmk_mdToken;
+ 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 */
-};
+ 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/nss/lib/ckfw/nssmkey/mtoken.c b/nss/lib/ckfw/nssmkey/mtoken.c
index a027807..e18d612 100644
--- a/nss/lib/ckfw/nssmkey/mtoken.c
+++ b/nss/lib/ckfw/nssmkey/mtoken.c
@@ -12,197 +12,173 @@
*/
static NSSUTF8 *
-ckmk_mdToken_GetLabel
-(
- NSSCKMDToken *mdToken,
- NSSCKFWToken *fwToken,
- NSSCKMDInstance *mdInstance,
- NSSCKFWInstance *fwInstance,
- CK_RV *pError
-)
+ckmk_mdToken_GetLabel(
+ NSSCKMDToken *mdToken,
+ NSSCKFWToken *fwToken,
+ NSSCKMDInstance *mdInstance,
+ NSSCKFWInstance *fwInstance,
+ CK_RV *pError)
{
- return (NSSUTF8 *)nss_ckmk_TokenLabel;
+ return (NSSUTF8 *)nss_ckmk_TokenLabel;
}
static NSSUTF8 *
-ckmk_mdToken_GetManufacturerID
-(
- NSSCKMDToken *mdToken,
- NSSCKFWToken *fwToken,
- NSSCKMDInstance *mdInstance,
- NSSCKFWInstance *fwInstance,
- CK_RV *pError
-)
+ckmk_mdToken_GetManufacturerID(
+ NSSCKMDToken *mdToken,
+ NSSCKFWToken *fwToken,
+ NSSCKMDInstance *mdInstance,
+ NSSCKFWInstance *fwInstance,
+ CK_RV *pError)
{
- return (NSSUTF8 *)nss_ckmk_ManufacturerID;
+ return (NSSUTF8 *)nss_ckmk_ManufacturerID;
}
static NSSUTF8 *
-ckmk_mdToken_GetModel
-(
- NSSCKMDToken *mdToken,
- NSSCKFWToken *fwToken,
- NSSCKMDInstance *mdInstance,
- NSSCKFWInstance *fwInstance,
- CK_RV *pError
-)
+ckmk_mdToken_GetModel(
+ NSSCKMDToken *mdToken,
+ NSSCKFWToken *fwToken,
+ NSSCKMDInstance *mdInstance,
+ NSSCKFWInstance *fwInstance,
+ CK_RV *pError)
{
- return (NSSUTF8 *)nss_ckmk_TokenModel;
+ return (NSSUTF8 *)nss_ckmk_TokenModel;
}
static NSSUTF8 *
-ckmk_mdToken_GetSerialNumber
-(
- NSSCKMDToken *mdToken,
- NSSCKFWToken *fwToken,
- NSSCKMDInstance *mdInstance,
- NSSCKFWInstance *fwInstance,
- CK_RV *pError
-)
+ckmk_mdToken_GetSerialNumber(
+ NSSCKMDToken *mdToken,
+ NSSCKFWToken *fwToken,
+ NSSCKMDInstance *mdInstance,
+ NSSCKFWInstance *fwInstance,
+ CK_RV *pError)
{
- return (NSSUTF8 *)nss_ckmk_TokenSerialNumber;
+ return (NSSUTF8 *)nss_ckmk_TokenSerialNumber;
}
static CK_BBOOL
-ckmk_mdToken_GetIsWriteProtected
-(
- NSSCKMDToken *mdToken,
- NSSCKFWToken *fwToken,
- NSSCKMDInstance *mdInstance,
- NSSCKFWInstance *fwInstance
-)
+ckmk_mdToken_GetIsWriteProtected(
+ NSSCKMDToken *mdToken,
+ NSSCKFWToken *fwToken,
+ NSSCKMDInstance *mdInstance,
+ NSSCKFWInstance *fwInstance)
{
- return CK_FALSE;
+ 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
-)
+ckmk_mdToken_GetUserPinInitialized(
+ NSSCKMDToken *mdToken,
+ NSSCKFWToken *fwToken,
+ NSSCKMDInstance *mdInstance,
+ NSSCKFWInstance *fwInstance)
{
- return CK_TRUE;
+ return CK_TRUE;
}
static CK_VERSION
-ckmk_mdToken_GetHardwareVersion
-(
- NSSCKMDToken *mdToken,
- NSSCKFWToken *fwToken,
- NSSCKMDInstance *mdInstance,
- NSSCKFWInstance *fwInstance
-)
+ckmk_mdToken_GetHardwareVersion(
+ NSSCKMDToken *mdToken,
+ NSSCKFWToken *fwToken,
+ NSSCKMDInstance *mdInstance,
+ NSSCKFWInstance *fwInstance)
{
- return nss_ckmk_HardwareVersion;
+ return nss_ckmk_HardwareVersion;
}
static CK_VERSION
-ckmk_mdToken_GetFirmwareVersion
-(
- NSSCKMDToken *mdToken,
- NSSCKFWToken *fwToken,
- NSSCKMDInstance *mdInstance,
- NSSCKFWInstance *fwInstance
-)
+ckmk_mdToken_GetFirmwareVersion(
+ NSSCKMDToken *mdToken,
+ NSSCKFWToken *fwToken,
+ NSSCKMDInstance *mdInstance,
+ NSSCKFWInstance *fwInstance)
{
- return nss_ckmk_FirmwareVersion;
+ 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
-)
+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);
+ return nss_ckmk_CreateSession(fwSession, pError);
}
static CK_ULONG
-ckmk_mdToken_GetMechanismCount
-(
- NSSCKMDToken *mdToken,
- NSSCKFWToken *fwToken,
- NSSCKMDInstance *mdInstance,
- NSSCKFWInstance *fwInstance
-)
+ckmk_mdToken_GetMechanismCount(
+ NSSCKMDToken *mdToken,
+ NSSCKFWToken *fwToken,
+ NSSCKMDInstance *mdInstance,
+ NSSCKFWInstance *fwInstance)
{
- return (CK_ULONG)1;
+ return (CK_ULONG)1;
}
static CK_RV
-ckmk_mdToken_GetMechanismTypes
-(
- NSSCKMDToken *mdToken,
- NSSCKFWToken *fwToken,
- NSSCKMDInstance *mdInstance,
- NSSCKFWInstance *fwInstance,
- CK_MECHANISM_TYPE types[]
-)
+ckmk_mdToken_GetMechanismTypes(
+ NSSCKMDToken *mdToken,
+ NSSCKFWToken *fwToken,
+ NSSCKMDInstance *mdInstance,
+ NSSCKFWInstance *fwInstance,
+ CK_MECHANISM_TYPE types[])
{
- types[0] = CKM_RSA_PKCS;
- return CKR_OK;
+ 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
-)
+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;
+ 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 */
-};
+ 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/nss/lib/ckfw/nssmkey/nssmkey.h b/nss/lib/ckfw/nssmkey/nssmkey.h
index bce77bf..ba58233 100644
--- a/nss/lib/ckfw/nssmkey/nssmkey.h
+++ b/nss/lib/ckfw/nssmkey/nssmkey.h
@@ -18,7 +18,7 @@
#define NSS_CKMK_CRYPTOKI_VERSION_MAJOR 2
#define NSS_CKMK_CRYPTOKI_VERSION_MINOR 20
-/* These version numbers detail the changes
+/* 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
@@ -33,7 +33,7 @@
#define NSS_CKMK_HARDWARE_VERSION_MAJOR 1
#define NSS_CKMK_HARDWARE_VERSION_MINOR 0
-/* These version numbers detail the semantic changes to ckbi itself
+/* 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
diff --git a/nss/lib/ckfw/nssmkey/staticobj.c b/nss/lib/ckfw/nssmkey/staticobj.c
index 0ccc861..5f3bb7c 100644
--- a/nss/lib/ckfw/nssmkey/staticobj.c
+++ b/nss/lib/ckfw/nssmkey/staticobj.c
@@ -17,20 +17,20 @@ 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 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 }
+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} },
+ { ckmkRaw, { { 5, nss_ckmk_types_1, nss_ckmk_items_1 } }, CKO_DATA, { NULL } },
};
const PRUint32 nss_ckmk_nObjects = 1;
diff --git a/nss/lib/ckfw/object.c b/nss/lib/ckfw/object.c
index 661977e..ff0542e 100644
--- a/nss/lib/ckfw/object.c
+++ b/nss/lib/ckfw/object.c
@@ -50,16 +50,16 @@
*/
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;
+ 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
@@ -75,123 +75,114 @@ struct NSSCKFWObjectStr {
*/
static CK_RV
-object_add_pointer
-(
- const NSSCKFWObject *fwObject
-)
+object_add_pointer(
+ const NSSCKFWObject *fwObject)
{
- return CKR_OK;
+ return CKR_OK;
}
static CK_RV
-object_remove_pointer
-(
- const NSSCKFWObject *fwObject
-)
+object_remove_pointer(
+ const NSSCKFWObject *fwObject)
{
- return CKR_OK;
+ return CKR_OK;
}
NSS_IMPLEMENT CK_RV
-nssCKFWObject_verifyPointer
-(
- const NSSCKFWObject *fwObject
-)
+nssCKFWObject_verifyPointer(
+ const NSSCKFWObject *fwObject)
{
- return CKR_OK;
+ 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_Create(
+ NSSArena *arena,
+ NSSCKMDObject *mdObject,
+ NSSCKFWSession *fwSession,
+ NSSCKFWToken *fwToken,
+ NSSCKFWInstance *fwInstance,
+ CK_RV *pError)
{
- NSSCKFWObject *fwObject;
- nssCKFWHash *mdObjectHash;
+ NSSCKFWObject *fwObject;
+ nssCKFWHash *mdObjectHash;
#ifdef NSSDEBUG
- if (!pError) {
- return (NSSCKFWObject *)NULL;
- }
-
- if( PR_SUCCESS != nssArena_verifyPointer(arena) ) {
- *pError = CKR_ARGUMENTS_BAD;
- return (NSSCKFWObject *)NULL;
- }
+ 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;
+ if (!fwToken) {
+ *pError = CKR_ARGUMENTS_BAD;
+ return (NSSCKFWObject *)NULL;
+ }
+ mdObjectHash = nssCKFWToken_GetMDObjectHash(fwToken);
+ if (!mdObjectHash) {
+ *pError = CKR_GENERAL_ERROR;
+ return (NSSCKFWObject *)NULL;
}
- nss_ZFreeIf(fwObject);
- return (NSSCKFWObject *)NULL;
- }
- *pError = nssCKFWHash_Add(mdObjectHash, mdObject, fwObject);
- if( CKR_OK != *pError ) {
- nss_ZFreeIf(fwObject);
- 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;
+ }
+ nss_ZFreeIf(fwObject);
+ 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;
- }
+ *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;
+ *pError = CKR_OK;
+ return fwObject;
}
/*
@@ -199,45 +190,43 @@ nssCKFWObject_Create
*
*/
NSS_IMPLEMENT void
-nssCKFWObject_Finalize
-(
- NSSCKFWObject *fwObject,
- PRBool removeFromHash
-)
+nssCKFWObject_Finalize(
+ NSSCKFWObject *fwObject,
+ PRBool removeFromHash)
{
- nssCKFWHash *mdObjectHash;
+ nssCKFWHash *mdObjectHash;
#ifdef NSSDEBUG
- if( CKR_OK != nssCKFWObject_verifyPointer(fwObject) ) {
- return;
- }
+ if (CKR_OK != nssCKFWObject_verifyPointer(fwObject)) {
+ return;
+ }
#endif /* NSSDEBUG */
- (void)nssCKFWMutex_Destroy(fwObject->mutex);
+ (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 (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 (removeFromHash) {
+ mdObjectHash = nssCKFWToken_GetMDObjectHash(fwObject->fwToken);
+ if (mdObjectHash) {
+ nssCKFWHash_Remove(mdObjectHash, fwObject->mdObject);
+ }
}
- }
- if (fwObject->fwSession) {
- nssCKFWSession_DeregisterSessionObject(fwObject->fwSession, fwObject);
- }
- nss_ZFreeIf(fwObject);
+ if (fwObject->fwSession) {
+ nssCKFWSession_DeregisterSessionObject(fwObject->fwSession, fwObject);
+ }
+ nss_ZFreeIf(fwObject);
#ifdef DEBUG
- (void)object_remove_pointer(fwObject);
+ (void)object_remove_pointer(fwObject);
#endif /* DEBUG */
- return;
+ return;
}
/*
@@ -245,42 +234,40 @@ nssCKFWObject_Finalize
*
*/
NSS_IMPLEMENT void
-nssCKFWObject_Destroy
-(
- NSSCKFWObject *fwObject
-)
+nssCKFWObject_Destroy(
+ NSSCKFWObject *fwObject)
{
- nssCKFWHash *mdObjectHash;
+ nssCKFWHash *mdObjectHash;
#ifdef NSSDEBUG
- if( CKR_OK != nssCKFWObject_verifyPointer(fwObject) ) {
- return;
- }
+ if (CKR_OK != nssCKFWObject_verifyPointer(fwObject)) {
+ return;
+ }
#endif /* NSSDEBUG */
- (void)nssCKFWMutex_Destroy(fwObject->mutex);
+ (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);
- }
+ 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);
- }
+ mdObjectHash = nssCKFWToken_GetMDObjectHash(fwObject->fwToken);
+ if (mdObjectHash) {
+ nssCKFWHash_Remove(mdObjectHash, fwObject->mdObject);
+ }
- if (fwObject->fwSession) {
- nssCKFWSession_DeregisterSessionObject(fwObject->fwSession, fwObject);
- }
- nss_ZFreeIf(fwObject);
+ if (fwObject->fwSession) {
+ nssCKFWSession_DeregisterSessionObject(fwObject->fwSession, fwObject);
+ }
+ nss_ZFreeIf(fwObject);
#ifdef DEBUG
- (void)object_remove_pointer(fwObject);
+ (void)object_remove_pointer(fwObject);
#endif /* DEBUG */
- return;
+ return;
}
/*
@@ -288,18 +275,16 @@ nssCKFWObject_Destroy
*
*/
NSS_IMPLEMENT NSSCKMDObject *
-nssCKFWObject_GetMDObject
-(
- NSSCKFWObject *fwObject
-)
+nssCKFWObject_GetMDObject(
+ NSSCKFWObject *fwObject)
{
#ifdef NSSDEBUG
- if( CKR_OK != nssCKFWObject_verifyPointer(fwObject) ) {
- return (NSSCKMDObject *)NULL;
- }
+ if (CKR_OK != nssCKFWObject_verifyPointer(fwObject)) {
+ return (NSSCKMDObject *)NULL;
+ }
#endif /* NSSDEBUG */
- return fwObject->mdObject;
+ return fwObject->mdObject;
}
/*
@@ -307,24 +292,22 @@ nssCKFWObject_GetMDObject
*
*/
NSS_IMPLEMENT NSSArena *
-nssCKFWObject_GetArena
-(
- NSSCKFWObject *fwObject,
- CK_RV *pError
-)
+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;
- }
+ if (!pError) {
+ return (NSSArena *)NULL;
+ }
+
+ *pError = nssCKFWObject_verifyPointer(fwObject);
+ if (CKR_OK != *pError) {
+ return (NSSArena *)NULL;
+ }
#endif /* NSSDEBUG */
- return fwObject->arena;
+ return fwObject->arena;
}
/*
@@ -332,30 +315,28 @@ nssCKFWObject_GetArena
*
*/
NSS_IMPLEMENT CK_RV
-nssCKFWObject_SetHandle
-(
- NSSCKFWObject *fwObject,
- CK_OBJECT_HANDLE hObject
-)
+nssCKFWObject_SetHandle(
+ NSSCKFWObject *fwObject,
+ CK_OBJECT_HANDLE hObject)
{
#ifdef NSSDEBUG
- CK_RV error = CKR_OK;
+ CK_RV error = CKR_OK;
#endif /* NSSDEBUG */
#ifdef NSSDEBUG
- error = nssCKFWObject_verifyPointer(fwObject);
- if( CKR_OK != error ) {
- return error;
- }
+ error = nssCKFWObject_verifyPointer(fwObject);
+ if (CKR_OK != error) {
+ return error;
+ }
#endif /* NSSDEBUG */
- if( (CK_OBJECT_HANDLE)0 != fwObject->hObject ) {
- return CKR_GENERAL_ERROR;
- }
+ if ((CK_OBJECT_HANDLE)0 != fwObject->hObject) {
+ return CKR_GENERAL_ERROR;
+ }
- fwObject->hObject = hObject;
+ fwObject->hObject = hObject;
- return CKR_OK;
+ return CKR_OK;
}
/*
@@ -363,18 +344,16 @@ nssCKFWObject_SetHandle
*
*/
NSS_IMPLEMENT CK_OBJECT_HANDLE
-nssCKFWObject_GetHandle
-(
- NSSCKFWObject *fwObject
-)
+nssCKFWObject_GetHandle(
+ NSSCKFWObject *fwObject)
{
#ifdef NSSDEBUG
- if( CKR_OK != nssCKFWObject_verifyPointer(fwObject) ) {
- return (CK_OBJECT_HANDLE)0;
- }
+ if (CKR_OK != nssCKFWObject_verifyPointer(fwObject)) {
+ return (CK_OBJECT_HANDLE)0;
+ }
#endif /* NSSDEBUG */
- return fwObject->hObject;
+ return fwObject->hObject;
}
/*
@@ -382,44 +361,42 @@ nssCKFWObject_GetHandle
*
*/
NSS_IMPLEMENT CK_BBOOL
-nssCKFWObject_IsTokenObject
-(
- NSSCKFWObject *fwObject
-)
+nssCKFWObject_IsTokenObject(
+ NSSCKFWObject *fwObject)
{
- CK_BBOOL b = CK_FALSE;
+ CK_BBOOL b = CK_FALSE;
#ifdef NSSDEBUG
- if( CKR_OK != nssCKFWObject_verifyPointer(fwObject) ) {
- return CK_FALSE;
- }
+ if (CKR_OK != nssCKFWObject_verifyPointer(fwObject)) {
+ return CK_FALSE;
+ }
#endif /* NSSDEBUG */
- if (!fwObject->mdObject->IsTokenObject) {
- NSSItem item;
- NSSItem *pItem;
- CK_RV rv = CKR_OK;
+ if (!fwObject->mdObject->IsTokenObject) {
+ NSSItem item;
+ NSSItem *pItem;
+ CK_RV rv = CKR_OK;
- item.data = (void *)&b;
- item.size = sizeof(b);
+ 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;
- }
+ pItem = nssCKFWObject_GetAttribute(fwObject, CKA_TOKEN, &item,
+ (NSSArena *)NULL, &rv);
+ if (!pItem) {
+ /* Error of some type */
+ b = CK_FALSE;
+ goto done;
+ }
- goto done;
- }
+ goto done;
+ }
- b = fwObject->mdObject->IsTokenObject(fwObject->mdObject, fwObject,
- fwObject->mdSession, fwObject->fwSession, fwObject->mdToken,
- fwObject->fwToken, fwObject->mdInstance, fwObject->fwInstance);
+ b = fwObject->mdObject->IsTokenObject(fwObject->mdObject, fwObject,
+ fwObject->mdSession, fwObject->fwSession, fwObject->mdToken,
+ fwObject->fwToken, fwObject->mdInstance, fwObject->fwInstance);
- done:
- return b;
+done:
+ return b;
}
/*
@@ -427,42 +404,40 @@ nssCKFWObject_IsTokenObject
*
*/
NSS_IMPLEMENT CK_ULONG
-nssCKFWObject_GetAttributeCount
-(
- NSSCKFWObject *fwObject,
- CK_RV *pError
-)
+nssCKFWObject_GetAttributeCount(
+ NSSCKFWObject *fwObject,
+ CK_RV *pError)
{
- CK_ULONG rv;
+ CK_ULONG rv;
#ifdef NSSDEBUG
- if (!pError) {
- return (CK_ULONG)0;
- }
-
- *pError = nssCKFWObject_verifyPointer(fwObject);
- if( CKR_OK != *pError ) {
- return (CK_ULONG)0;
- }
+ 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;
- }
+ 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;
- }
+ *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);
+ 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;
+ (void)nssCKFWMutex_Unlock(fwObject->mutex);
+ return rv;
}
/*
@@ -470,42 +445,40 @@ nssCKFWObject_GetAttributeCount
*
*/
NSS_IMPLEMENT CK_RV
-nssCKFWObject_GetAttributeTypes
-(
- NSSCKFWObject *fwObject,
- CK_ATTRIBUTE_TYPE_PTR typeArray,
- CK_ULONG ulCount
-)
+nssCKFWObject_GetAttributeTypes(
+ NSSCKFWObject *fwObject,
+ CK_ATTRIBUTE_TYPE_PTR typeArray,
+ CK_ULONG ulCount)
{
- CK_RV error = CKR_OK;
+ CK_RV error = CKR_OK;
#ifdef NSSDEBUG
- error = nssCKFWObject_verifyPointer(fwObject);
- if( CKR_OK != error ) {
- return error;
- }
+ error = nssCKFWObject_verifyPointer(fwObject);
+ if (CKR_OK != error) {
+ return error;
+ }
- if( (CK_ATTRIBUTE_TYPE_PTR)NULL == typeArray ) {
- return CKR_ARGUMENTS_BAD;
- }
+ if ((CK_ATTRIBUTE_TYPE_PTR)NULL == typeArray) {
+ return CKR_ARGUMENTS_BAD;
+ }
#endif /* NSSDEBUG */
- if (!fwObject->mdObject->GetAttributeTypes) {
- return CKR_GENERAL_ERROR;
- }
+ if (!fwObject->mdObject->GetAttributeTypes) {
+ return CKR_GENERAL_ERROR;
+ }
- error = nssCKFWMutex_Lock(fwObject->mutex);
- if( CKR_OK != error ) {
- return 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);
+ 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;
+ (void)nssCKFWMutex_Unlock(fwObject->mutex);
+ return error;
}
/*
@@ -513,43 +486,41 @@ nssCKFWObject_GetAttributeTypes
*
*/
NSS_IMPLEMENT CK_ULONG
-nssCKFWObject_GetAttributeSize
-(
- NSSCKFWObject *fwObject,
- CK_ATTRIBUTE_TYPE attribute,
- CK_RV *pError
-)
+nssCKFWObject_GetAttributeSize(
+ NSSCKFWObject *fwObject,
+ CK_ATTRIBUTE_TYPE attribute,
+ CK_RV *pError)
{
- CK_ULONG rv;
+ CK_ULONG rv;
#ifdef NSSDEBUG
- if (!pError) {
- return (CK_ULONG)0;
- }
-
- *pError = nssCKFWObject_verifyPointer(fwObject);
- if( CKR_OK != *pError ) {
- return (CK_ULONG)0;
- }
+ 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;
- }
+ 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;
- }
+ *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);
+ 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;
+ (void)nssCKFWMutex_Unlock(fwObject->mutex);
+ return rv;
}
/*
@@ -563,97 +534,95 @@ nssCKFWObject_GetAttributeSize
* specified.
*/
NSS_IMPLEMENT NSSItem *
-nssCKFWObject_GetAttribute
-(
- NSSCKFWObject *fwObject,
- CK_ATTRIBUTE_TYPE attribute,
- NSSItem *itemOpt,
- NSSArena *arenaOpt,
- CK_RV *pError
-)
+nssCKFWObject_GetAttribute(
+ NSSCKFWObject *fwObject,
+ CK_ATTRIBUTE_TYPE attribute,
+ NSSItem *itemOpt,
+ NSSArena *arenaOpt,
+ CK_RV *pError)
{
- NSSItem *rv = (NSSItem *)NULL;
- NSSCKFWItem mdItem;
+ NSSItem *rv = (NSSItem *)NULL;
+ NSSCKFWItem mdItem;
#ifdef NSSDEBUG
- if (!pError) {
- return (NSSItem *)NULL;
- }
-
- *pError = nssCKFWObject_verifyPointer(fwObject);
- if( CKR_OK != *pError ) {
- return (NSSItem *)NULL;
- }
+ 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;
- }
+ if (!fwObject->mdObject->GetAttribute) {
+ *pError = CKR_GENERAL_ERROR;
+ return (NSSItem *)NULL;
+ }
+
+ *pError = nssCKFWMutex_Lock(fwObject->mutex);
+ if (CKR_OK != *pError) {
+ 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);
- 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;
+ }
- if (!mdItem.item) {
- if( CKR_OK == *pError ) {
- *pError = CKR_GENERAL_ERROR;
+ goto done;
}
- goto done;
- }
-
- if (!itemOpt) {
- rv = nss_ZNEW(arenaOpt, NSSItem);
- if (!rv) {
- *pError = CKR_HOST_MEMORY;
- goto done;
+ if (!itemOpt) {
+ rv = nss_ZNEW(arenaOpt, NSSItem);
+ if (!rv) {
+ *pError = CKR_HOST_MEMORY;
+ goto done;
+ }
+ } else {
+ rv = itemOpt;
}
- } 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;
+ 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 {
- *pError = CKR_BUFFER_TOO_SMALL;
- /* Should we set rv->size to mdItem->size? */
- /* rv can't have been allocated */
- rv = (NSSItem *)NULL;
- goto done;
+ 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);
+ (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);
+ 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;
+done:
+ (void)nssCKFWMutex_Unlock(fwObject->mutex);
+ return rv;
}
/*
@@ -661,128 +630,126 @@ nssCKFWObject_GetAttribute
*
*/
NSS_IMPLEMENT CK_RV
-nssCKFWObject_SetAttribute
-(
- NSSCKFWObject *fwObject,
- NSSCKFWSession *fwSession,
- CK_ATTRIBUTE_TYPE attribute,
- NSSItem *value
-)
+nssCKFWObject_SetAttribute(
+ NSSCKFWObject *fwObject,
+ NSSCKFWSession *fwSession,
+ CK_ATTRIBUTE_TYPE attribute,
+ NSSItem *value)
{
- CK_RV error = CKR_OK;
+ 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 = nssCKFWObject_verifyPointer(fwObject);
+ if (CKR_OK != error) {
+ return error;
}
+#endif /* NSSDEBUG */
- 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);
+ 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 {
- /*
- * 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;
+ /*
+ * 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;
}
-
- 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;
- }
}
/*
@@ -790,42 +757,40 @@ nssCKFWObject_SetAttribute
*
*/
NSS_IMPLEMENT CK_ULONG
-nssCKFWObject_GetObjectSize
-(
- NSSCKFWObject *fwObject,
- CK_RV *pError
-)
+nssCKFWObject_GetObjectSize(
+ NSSCKFWObject *fwObject,
+ CK_RV *pError)
{
- CK_ULONG rv;
+ CK_ULONG rv;
#ifdef NSSDEBUG
- if (!pError) {
- return (CK_ULONG)0;
- }
-
- *pError = nssCKFWObject_verifyPointer(fwObject);
- if( CKR_OK != *pError ) {
- return (CK_ULONG)0;
- }
+ 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;
- }
+ 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;
- }
+ *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);
+ 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;
+ (void)nssCKFWMutex_Unlock(fwObject->mutex);
+ return rv;
}
/*
@@ -833,18 +798,16 @@ nssCKFWObject_GetObjectSize
*
*/
NSS_IMPLEMENT NSSCKMDObject *
-NSSCKFWObject_GetMDObject
-(
- NSSCKFWObject *fwObject
-)
+NSSCKFWObject_GetMDObject(
+ NSSCKFWObject *fwObject)
{
#ifdef DEBUG
- if( CKR_OK != nssCKFWObject_verifyPointer(fwObject) ) {
- return (NSSCKMDObject *)NULL;
- }
+ if (CKR_OK != nssCKFWObject_verifyPointer(fwObject)) {
+ return (NSSCKMDObject *)NULL;
+ }
#endif /* DEBUG */
- return nssCKFWObject_GetMDObject(fwObject);
+ return nssCKFWObject_GetMDObject(fwObject);
}
/*
@@ -852,24 +815,22 @@ NSSCKFWObject_GetMDObject
*
*/
NSS_IMPLEMENT NSSArena *
-NSSCKFWObject_GetArena
-(
- NSSCKFWObject *fwObject,
- CK_RV *pError
-)
+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;
- }
+ if (!pError) {
+ return (NSSArena *)NULL;
+ }
+
+ *pError = nssCKFWObject_verifyPointer(fwObject);
+ if (CKR_OK != *pError) {
+ return (NSSArena *)NULL;
+ }
#endif /* DEBUG */
- return nssCKFWObject_GetArena(fwObject, pError);
+ return nssCKFWObject_GetArena(fwObject, pError);
}
/*
@@ -877,18 +838,16 @@ NSSCKFWObject_GetArena
*
*/
NSS_IMPLEMENT CK_BBOOL
-NSSCKFWObject_IsTokenObject
-(
- NSSCKFWObject *fwObject
-)
+NSSCKFWObject_IsTokenObject(
+ NSSCKFWObject *fwObject)
{
#ifdef DEBUG
- if( CKR_OK != nssCKFWObject_verifyPointer(fwObject) ) {
- return CK_FALSE;
- }
+ if (CKR_OK != nssCKFWObject_verifyPointer(fwObject)) {
+ return CK_FALSE;
+ }
#endif /* DEBUG */
- return nssCKFWObject_IsTokenObject(fwObject);
+ return nssCKFWObject_IsTokenObject(fwObject);
}
/*
@@ -896,24 +855,22 @@ NSSCKFWObject_IsTokenObject
*
*/
NSS_IMPLEMENT CK_ULONG
-NSSCKFWObject_GetAttributeCount
-(
- NSSCKFWObject *fwObject,
- CK_RV *pError
-)
+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;
- }
+ 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);
+ return nssCKFWObject_GetAttributeCount(fwObject, pError);
}
/*
@@ -921,27 +878,25 @@ NSSCKFWObject_GetAttributeCount
*
*/
NSS_IMPLEMENT CK_RV
-NSSCKFWObject_GetAttributeTypes
-(
- NSSCKFWObject *fwObject,
- CK_ATTRIBUTE_TYPE_PTR typeArray,
- CK_ULONG ulCount
-)
+NSSCKFWObject_GetAttributeTypes(
+ NSSCKFWObject *fwObject,
+ CK_ATTRIBUTE_TYPE_PTR typeArray,
+ CK_ULONG ulCount)
{
#ifdef DEBUG
- CK_RV error = CKR_OK;
+ CK_RV error = CKR_OK;
- error = nssCKFWObject_verifyPointer(fwObject);
- if( CKR_OK != error ) {
- return error;
- }
+ error = nssCKFWObject_verifyPointer(fwObject);
+ if (CKR_OK != error) {
+ return error;
+ }
- if( (CK_ATTRIBUTE_TYPE_PTR)NULL == typeArray ) {
- return CKR_ARGUMENTS_BAD;
- }
+ if ((CK_ATTRIBUTE_TYPE_PTR)NULL == typeArray) {
+ return CKR_ARGUMENTS_BAD;
+ }
#endif /* DEBUG */
- return nssCKFWObject_GetAttributeTypes(fwObject, typeArray, ulCount);
+ return nssCKFWObject_GetAttributeTypes(fwObject, typeArray, ulCount);
}
/*
@@ -949,25 +904,23 @@ NSSCKFWObject_GetAttributeTypes
*
*/
NSS_IMPLEMENT CK_ULONG
-NSSCKFWObject_GetAttributeSize
-(
- NSSCKFWObject *fwObject,
- CK_ATTRIBUTE_TYPE attribute,
- CK_RV *pError
-)
+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;
- }
+ 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);
+ return nssCKFWObject_GetAttributeSize(fwObject, attribute, pError);
}
/*
@@ -975,27 +928,25 @@ NSSCKFWObject_GetAttributeSize
*
*/
NSS_IMPLEMENT NSSItem *
-NSSCKFWObject_GetAttribute
-(
- NSSCKFWObject *fwObject,
- CK_ATTRIBUTE_TYPE attribute,
- NSSItem *itemOpt,
- NSSArena *arenaOpt,
- CK_RV *pError
-)
+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;
- }
+ 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);
+ return nssCKFWObject_GetAttribute(fwObject, attribute, itemOpt, arenaOpt, pError);
}
/*
@@ -1003,22 +954,20 @@ NSSCKFWObject_GetAttribute
*
*/
NSS_IMPLEMENT CK_ULONG
-NSSCKFWObject_GetObjectSize
-(
- NSSCKFWObject *fwObject,
- CK_RV *pError
-)
+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;
- }
+ 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);
+ return nssCKFWObject_GetObjectSize(fwObject, pError);
}
diff --git a/nss/lib/ckfw/session.c b/nss/lib/ckfw/session.c
index 1d05262..a311934 100644
--- a/nss/lib/ckfw/session.c
+++ b/nss/lib/ckfw/session.c
@@ -25,6 +25,7 @@
* NSSCKFWSession_CallNotification
* NSSCKFWSession_IsRWSession
* NSSCKFWSession_IsSO
+ * NSSCKFWSession_GetFWSlot
*
* -- implement public accessors --
* nssCKFWSession_GetMDSession
@@ -32,9 +33,9 @@
* nssCKFWSession_CallNotification
* nssCKFWSession_IsRWSession
* nssCKFWSession_IsSO
+ * nssCKFWSession_GetFWSlot
*
* -- private accessors --
- * nssCKFWSession_GetSlot
* nssCKFWSession_GetSessionState
* nssCKFWSession_SetFWFindObjects
* nssCKFWSession_GetFWFindObjects
@@ -61,26 +62,26 @@
*/
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;
+ 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
@@ -96,30 +97,24 @@ struct NSSCKFWSessionStr {
*/
static CK_RV
-session_add_pointer
-(
- const NSSCKFWSession *fwSession
-)
+session_add_pointer(
+ const NSSCKFWSession *fwSession)
{
- return CKR_OK;
+ return CKR_OK;
}
static CK_RV
-session_remove_pointer
-(
- const NSSCKFWSession *fwSession
-)
+session_remove_pointer(
+ const NSSCKFWSession *fwSession)
{
- return CKR_OK;
+ return CKR_OK;
}
NSS_IMPLEMENT CK_RV
-nssCKFWSession_verifyPointer
-(
- const NSSCKFWSession *fwSession
-)
+nssCKFWSession_verifyPointer(
+ const NSSCKFWSession *fwSession)
{
- return CKR_OK;
+ return CKR_OK;
}
#endif /* DEBUG */
@@ -129,95 +124,91 @@ nssCKFWSession_verifyPointer
*
*/
NSS_IMPLEMENT NSSCKFWSession *
-nssCKFWSession_Create
-(
- NSSCKFWToken *fwToken,
- CK_BBOOL rw,
- CK_VOID_PTR pApplication,
- CK_NOTIFY Notify,
- CK_RV *pError
-)
+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;
+ NSSArena *arena = (NSSArena *)NULL;
+ NSSCKFWSession *fwSession;
+ NSSCKFWSlot *fwSlot;
#ifdef NSSDEBUG
- if (!pError) {
- return (NSSCKFWSession *)NULL;
- }
+ if (!pError) {
+ return (NSSCKFWSession *)NULL;
+ }
- *pError = nssCKFWToken_verifyPointer(fwToken);
- if( CKR_OK != *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;
- }
+ 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 = 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);
+ 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);
+ fwSlot = nssCKFWToken_GetFWSlot(fwToken);
+ fwSession->fwInstance = nssCKFWSlot_GetFWInstance(fwSlot);
+ fwSession->mdInstance = nssCKFWSlot_GetMDInstance(fwSlot);
- fwSession->rw = rw;
- fwSession->pApplication = pApplication;
- fwSession->Notify = Notify;
+ fwSession->rw = rw;
+ fwSession->pApplication = pApplication;
+ fwSession->Notify = Notify;
- fwSession->fwFindObjects = (NSSCKFWFindObjects *)NULL;
+ fwSession->fwFindObjects = (NSSCKFWFindObjects *)NULL;
- fwSession->sessionObjectHash = nssCKFWHash_Create(fwSession->fwInstance, arena, pError);
- if (!fwSession->sessionObjectHash) {
- if( CKR_OK == *pError ) {
- *pError = CKR_GENERAL_ERROR;
+ fwSession->sessionObjectHash = nssCKFWHash_Create(fwSession->fwInstance, arena, pError);
+ if (!fwSession->sessionObjectHash) {
+ if (CKR_OK == *pError) {
+ *pError = CKR_GENERAL_ERROR;
+ }
+ goto loser;
}
- goto loser;
- }
#ifdef DEBUG
- *pError = session_add_pointer(fwSession);
- if( CKR_OK != *pError ) {
- goto loser;
- }
+ *pError = session_add_pointer(fwSession);
+ if (CKR_OK != *pError) {
+ goto loser;
+ }
#endif /* DEBUG */
- return fwSession;
+ return fwSession;
- loser:
- if (arena) {
- if (fwSession && fwSession->sessionObjectHash) {
- (void)nssCKFWHash_Destroy(fwSession->sessionObjectHash);
+loser:
+ if (arena) {
+ if (fwSession && fwSession->sessionObjectHash) {
+ (void)nssCKFWHash_Destroy(fwSession->sessionObjectHash);
+ }
+ NSSArena_Destroy(arena);
}
- NSSArena_Destroy(arena);
- }
- return (NSSCKFWSession *)NULL;
+ return (NSSCKFWSession *)NULL;
}
static void
-nss_ckfw_session_object_destroy_iterator
-(
- const void *key,
- void *value,
- void *closure
-)
+nss_ckfw_session_object_destroy_iterator(
+ const void *key,
+ void *value,
+ void *closure)
{
- NSSCKFWObject *fwObject = (NSSCKFWObject *)value;
- nssCKFWObject_Finalize(fwObject, PR_TRUE);
+ NSSCKFWObject *fwObject = (NSSCKFWObject *)value;
+ nssCKFWObject_Finalize(fwObject, PR_TRUE);
}
/*
@@ -225,51 +216,49 @@ nss_ckfw_session_object_destroy_iterator
*
*/
NSS_IMPLEMENT CK_RV
-nssCKFWSession_Destroy
-(
- NSSCKFWSession *fwSession,
- CK_BBOOL removeFromTokenHash
-)
+nssCKFWSession_Destroy(
+ NSSCKFWSession *fwSession,
+ CK_BBOOL removeFromTokenHash)
{
- CK_RV error = CKR_OK;
- nssCKFWHash *sessionObjectHash;
- NSSCKFWCryptoOperationState i;
+ CK_RV error = CKR_OK;
+ nssCKFWHash *sessionObjectHash;
+ NSSCKFWCryptoOperationState i;
#ifdef NSSDEBUG
- error = nssCKFWSession_verifyPointer(fwSession);
- if( CKR_OK != error ) {
- return error;
- }
+ error = nssCKFWSession_verifyPointer(fwSession);
+ if (CKR_OK != error) {
+ return error;
+ }
#endif /* NSSDEBUG */
- if( removeFromTokenHash ) {
- error = nssCKFWToken_RemoveSession(fwSession->fwToken, fwSession);
- }
+ if (removeFromTokenHash) {
+ error = nssCKFWToken_RemoveSession(fwSession->fwToken, fwSession);
+ }
- /*
- * Invalidate session objects
- */
+ /*
+ * Invalidate session objects
+ */
- sessionObjectHash = fwSession->sessionObjectHash;
- fwSession->sessionObjectHash = (nssCKFWHash *)NULL;
+ sessionObjectHash = fwSession->sessionObjectHash;
+ fwSession->sessionObjectHash = (nssCKFWHash *)NULL;
- nssCKFWHash_Iterate(sessionObjectHash,
- nss_ckfw_session_object_destroy_iterator,
- (void *)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]);
+ for (i = 0; i < NSSCKFWCryptoOperationState_Max; i++) {
+ if (fwSession->fwOperationArray[i]) {
+ nssCKFWCryptoOperation_Destroy(fwSession->fwOperationArray[i]);
+ }
}
- }
#ifdef DEBUG
- (void)session_remove_pointer(fwSession);
+ (void)session_remove_pointer(fwSession);
#endif /* DEBUG */
- (void)nssCKFWHash_Destroy(sessionObjectHash);
- NSSArena_Destroy(fwSession->arena);
+ (void)nssCKFWHash_Destroy(sessionObjectHash);
+ NSSArena_Destroy(fwSession->arena);
- return error;
+ return error;
}
/*
@@ -277,18 +266,16 @@ nssCKFWSession_Destroy
*
*/
NSS_IMPLEMENT NSSCKMDSession *
-nssCKFWSession_GetMDSession
-(
- NSSCKFWSession *fwSession
-)
+nssCKFWSession_GetMDSession(
+ NSSCKFWSession *fwSession)
{
#ifdef NSSDEBUG
- if( CKR_OK != nssCKFWSession_verifyPointer(fwSession) ) {
- return (NSSCKMDSession *)NULL;
- }
+ if (CKR_OK != nssCKFWSession_verifyPointer(fwSession)) {
+ return (NSSCKMDSession *)NULL;
+ }
#endif /* NSSDEBUG */
- return fwSession->mdSession;
+ return fwSession->mdSession;
}
/*
@@ -296,24 +283,22 @@ nssCKFWSession_GetMDSession
*
*/
NSS_IMPLEMENT NSSArena *
-nssCKFWSession_GetArena
-(
- NSSCKFWSession *fwSession,
- CK_RV *pError
-)
+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;
- }
+ if (!pError) {
+ return (NSSArena *)NULL;
+ }
+
+ *pError = nssCKFWSession_verifyPointer(fwSession);
+ if (CKR_OK != *pError) {
+ return (NSSArena *)NULL;
+ }
#endif /* NSSDEBUG */
- return fwSession->arena;
+ return fwSession->arena;
}
/*
@@ -321,34 +306,32 @@ nssCKFWSession_GetArena
*
*/
NSS_IMPLEMENT CK_RV
-nssCKFWSession_CallNotification
-(
- NSSCKFWSession *fwSession,
- CK_NOTIFICATION event
-)
+nssCKFWSession_CallNotification(
+ NSSCKFWSession *fwSession,
+ CK_NOTIFICATION event)
{
- CK_RV error = CKR_OK;
- CK_SESSION_HANDLE handle;
+ CK_RV error = CKR_OK;
+ CK_SESSION_HANDLE handle;
#ifdef NSSDEBUG
- error = nssCKFWSession_verifyPointer(fwSession);
- if( CKR_OK != error ) {
- return error;
- }
+ error = nssCKFWSession_verifyPointer(fwSession);
+ if (CKR_OK != error) {
+ return error;
+ }
#endif /* NSSDEBUG */
- if( (CK_NOTIFY)NULL == fwSession->Notify ) {
- return CKR_OK;
- }
+ 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;
- }
+ handle = nssCKFWInstance_FindSessionHandle(fwSession->fwInstance, fwSession);
+ if ((CK_SESSION_HANDLE)0 == handle) {
+ return CKR_GENERAL_ERROR;
+ }
- error = fwSession->Notify(handle, event, fwSession->pApplication);
+ error = fwSession->Notify(handle, event, fwSession->pApplication);
- return error;
+ return error;
}
/*
@@ -356,18 +339,16 @@ nssCKFWSession_CallNotification
*
*/
NSS_IMPLEMENT CK_BBOOL
-nssCKFWSession_IsRWSession
-(
- NSSCKFWSession *fwSession
-)
+nssCKFWSession_IsRWSession(
+ NSSCKFWSession *fwSession)
{
#ifdef NSSDEBUG
- if( CKR_OK != nssCKFWSession_verifyPointer(fwSession) ) {
- return CK_FALSE;
- }
+ if (CKR_OK != nssCKFWSession_verifyPointer(fwSession)) {
+ return CK_FALSE;
+ }
#endif /* NSSDEBUG */
- return fwSession->rw;
+ return fwSession->rw;
}
/*
@@ -375,31 +356,29 @@ nssCKFWSession_IsRWSession
*
*/
NSS_IMPLEMENT CK_BBOOL
-nssCKFWSession_IsSO
-(
- NSSCKFWSession *fwSession
-)
+nssCKFWSession_IsSO(
+ NSSCKFWSession *fwSession)
{
- CK_STATE state;
+ CK_STATE state;
#ifdef NSSDEBUG
- if( CKR_OK != nssCKFWSession_verifyPointer(fwSession) ) {
- return CK_FALSE;
- }
+ 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;
- }
+ 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;
+ }
}
/*
@@ -407,18 +386,16 @@ nssCKFWSession_IsSO
*
*/
NSS_IMPLEMENT NSSCKFWSlot *
-nssCKFWSession_GetFWSlot
-(
- NSSCKFWSession *fwSession
-)
+nssCKFWSession_GetFWSlot(
+ NSSCKFWSession *fwSession)
{
#ifdef NSSDEBUG
- if( CKR_OK != nssCKFWSession_verifyPointer(fwSession) ) {
- return (NSSCKFWSlot *)NULL;
- }
+ if (CKR_OK != nssCKFWSession_verifyPointer(fwSession)) {
+ return (NSSCKFWSlot *)NULL;
+ }
#endif /* NSSDEBUG */
- return nssCKFWToken_GetFWSlot(fwSession->fwToken);
+ return nssCKFWToken_GetFWSlot(fwSession->fwToken);
}
/*
@@ -426,18 +403,16 @@ nssCKFWSession_GetFWSlot
*
*/
NSS_IMPLEMENT CK_STATE
-nssCKFWSession_GetSessionState
-(
- NSSCKFWSession *fwSession
-)
+nssCKFWSession_GetSessionState(
+ NSSCKFWSession *fwSession)
{
#ifdef NSSDEBUG
- if( CKR_OK != nssCKFWSession_verifyPointer(fwSession) ) {
- return CKS_RO_PUBLIC_SESSION; /* whatever */
- }
+ if (CKR_OK != nssCKFWSession_verifyPointer(fwSession)) {
+ return CKS_RO_PUBLIC_SESSION; /* whatever */
+ }
#endif /* NSSDEBUG */
- return nssCKFWToken_GetSessionState(fwSession->fwToken);
+ return nssCKFWToken_GetSessionState(fwSession->fwToken);
}
/*
@@ -445,33 +420,31 @@ nssCKFWSession_GetSessionState
*
*/
NSS_IMPLEMENT CK_RV
-nssCKFWSession_SetFWFindObjects
-(
- NSSCKFWSession *fwSession,
- NSSCKFWFindObjects *fwFindObjects
-)
+nssCKFWSession_SetFWFindObjects(
+ NSSCKFWSession *fwSession,
+ NSSCKFWFindObjects *fwFindObjects)
{
#ifdef NSSDEBUG
- CK_RV error = CKR_OK;
+ CK_RV error = CKR_OK;
#endif /* NSSDEBUG */
#ifdef NSSDEBUG
- error = nssCKFWSession_verifyPointer(fwSession);
- if( CKR_OK != error ) {
- return error;
- }
+ error = nssCKFWSession_verifyPointer(fwSession);
+ if (CKR_OK != error) {
+ return error;
+ }
- /* fwFindObjects may be null */
+/* fwFindObjects may be null */
#endif /* NSSDEBUG */
- if ((fwSession->fwFindObjects) &&
- (fwFindObjects)) {
- return CKR_OPERATION_ACTIVE;
- }
+ if ((fwSession->fwFindObjects) &&
+ (fwFindObjects)) {
+ return CKR_OPERATION_ACTIVE;
+ }
- fwSession->fwFindObjects = fwFindObjects;
+ fwSession->fwFindObjects = fwFindObjects;
- return CKR_OK;
+ return CKR_OK;
}
/*
@@ -479,29 +452,27 @@ nssCKFWSession_SetFWFindObjects
*
*/
NSS_IMPLEMENT NSSCKFWFindObjects *
-nssCKFWSession_GetFWFindObjects
-(
- NSSCKFWSession *fwSession,
- CK_RV *pError
-)
+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;
- }
+ 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;
- }
+ if (!fwSession->fwFindObjects) {
+ *pError = CKR_OPERATION_NOT_INITIALIZED;
+ return (NSSCKFWFindObjects *)NULL;
+ }
- return fwSession->fwFindObjects;
+ return fwSession->fwFindObjects;
}
/*
@@ -509,34 +480,32 @@ nssCKFWSession_GetFWFindObjects
*
*/
NSS_IMPLEMENT CK_RV
-nssCKFWSession_SetMDSession
-(
- NSSCKFWSession *fwSession,
- NSSCKMDSession *mdSession
-)
+nssCKFWSession_SetMDSession(
+ NSSCKFWSession *fwSession,
+ NSSCKMDSession *mdSession)
{
#ifdef NSSDEBUG
- CK_RV error = CKR_OK;
+ CK_RV error = CKR_OK;
#endif /* NSSDEBUG */
#ifdef NSSDEBUG
- error = nssCKFWSession_verifyPointer(fwSession);
- if( CKR_OK != error ) {
- return error;
- }
+ error = nssCKFWSession_verifyPointer(fwSession);
+ if (CKR_OK != error) {
+ return error;
+ }
- if (!mdSession) {
- return CKR_ARGUMENTS_BAD;
- }
+ if (!mdSession) {
+ return CKR_ARGUMENTS_BAD;
+ }
#endif /* NSSDEBUG */
- if (fwSession->mdSession) {
- return CKR_GENERAL_ERROR;
- }
+ if (fwSession->mdSession) {
+ return CKR_GENERAL_ERROR;
+ }
- fwSession->mdSession = mdSession;
+ fwSession->mdSession = mdSession;
- return CKR_OK;
+ return CKR_OK;
}
/*
@@ -544,30 +513,28 @@ nssCKFWSession_SetMDSession
*
*/
NSS_IMPLEMENT CK_RV
-nssCKFWSession_SetHandle
-(
- NSSCKFWSession *fwSession,
- CK_SESSION_HANDLE hSession
-)
+nssCKFWSession_SetHandle(
+ NSSCKFWSession *fwSession,
+ CK_SESSION_HANDLE hSession)
{
#ifdef NSSDEBUG
- CK_RV error = CKR_OK;
+ CK_RV error = CKR_OK;
#endif /* NSSDEBUG */
#ifdef NSSDEBUG
- error = nssCKFWSession_verifyPointer(fwSession);
- if( CKR_OK != error ) {
- return error;
- }
+ error = nssCKFWSession_verifyPointer(fwSession);
+ if (CKR_OK != error) {
+ return error;
+ }
#endif /* NSSDEBUG */
- if( (CK_SESSION_HANDLE)0 != fwSession->hSession ) {
- return CKR_GENERAL_ERROR;
- }
+ if ((CK_SESSION_HANDLE)0 != fwSession->hSession) {
+ return CKR_GENERAL_ERROR;
+ }
- fwSession->hSession = hSession;
+ fwSession->hSession = hSession;
- return CKR_OK;
+ return CKR_OK;
}
/*
@@ -575,18 +542,16 @@ nssCKFWSession_SetHandle
*
*/
NSS_IMPLEMENT CK_SESSION_HANDLE
-nssCKFWSession_GetHandle
-(
- NSSCKFWSession *fwSession
-)
+nssCKFWSession_GetHandle(
+ NSSCKFWSession *fwSession)
{
#ifdef NSSDEBUG
- if( CKR_OK != nssCKFWSession_verifyPointer(fwSession) ) {
- return NULL;
- }
+ if (CKR_OK != nssCKFWSession_verifyPointer(fwSession)) {
+ return NULL;
+ }
#endif /* NSSDEBUG */
- return fwSession->hSession;
+ return fwSession->hSession;
}
/*
@@ -594,25 +559,23 @@ nssCKFWSession_GetHandle
*
*/
NSS_IMPLEMENT CK_RV
-nssCKFWSession_RegisterSessionObject
-(
- NSSCKFWSession *fwSession,
- NSSCKFWObject *fwObject
-)
+nssCKFWSession_RegisterSessionObject(
+ NSSCKFWSession *fwSession,
+ NSSCKFWObject *fwObject)
{
- CK_RV rv = CKR_OK;
+ CK_RV rv = CKR_OK;
#ifdef NSSDEBUG
- if( CKR_OK != nssCKFWSession_verifyPointer(fwSession) ) {
- return CKR_GENERAL_ERROR;
- }
+ if (CKR_OK != nssCKFWSession_verifyPointer(fwSession)) {
+ return CKR_GENERAL_ERROR;
+ }
#endif /* NSSDEBUG */
- if (fwSession->sessionObjectHash) {
- rv = nssCKFWHash_Add(fwSession->sessionObjectHash, fwObject, fwObject);
- }
+ if (fwSession->sessionObjectHash) {
+ rv = nssCKFWHash_Add(fwSession->sessionObjectHash, fwObject, fwObject);
+ }
- return rv;
+ return rv;
}
/*
@@ -620,23 +583,21 @@ nssCKFWSession_RegisterSessionObject
*
*/
NSS_IMPLEMENT CK_RV
-nssCKFWSession_DeregisterSessionObject
-(
- NSSCKFWSession *fwSession,
- NSSCKFWObject *fwObject
-)
+nssCKFWSession_DeregisterSessionObject(
+ NSSCKFWSession *fwSession,
+ NSSCKFWObject *fwObject)
{
#ifdef NSSDEBUG
- if( CKR_OK != nssCKFWSession_verifyPointer(fwSession) ) {
- return CKR_GENERAL_ERROR;
- }
+ if (CKR_OK != nssCKFWSession_verifyPointer(fwSession)) {
+ return CKR_GENERAL_ERROR;
+ }
#endif /* NSSDEBUG */
- if (fwSession->sessionObjectHash) {
- nssCKFWHash_Remove(fwSession->sessionObjectHash, fwObject);
- }
+ if (fwSession->sessionObjectHash) {
+ nssCKFWHash_Remove(fwSession->sessionObjectHash, fwObject);
+ }
- return CKR_OK;
+ return CKR_OK;
}
/*
@@ -644,28 +605,26 @@ nssCKFWSession_DeregisterSessionObject
*
*/
NSS_IMPLEMENT CK_ULONG
-nssCKFWSession_GetDeviceError
-(
- NSSCKFWSession *fwSession
-)
+nssCKFWSession_GetDeviceError(
+ NSSCKFWSession *fwSession)
{
#ifdef NSSDEBUG
- if( CKR_OK != nssCKFWSession_verifyPointer(fwSession) ) {
- return (CK_ULONG)0;
- }
+ if (CKR_OK != nssCKFWSession_verifyPointer(fwSession)) {
+ return (CK_ULONG)0;
+ }
- if (!fwSession->mdSession) {
- return (CK_ULONG)0;
- }
+ if (!fwSession->mdSession) {
+ return (CK_ULONG)0;
+ }
#endif /* NSSDEBUG */
- if (!fwSession->mdSession->GetDeviceError) {
- return (CK_ULONG)0;
- }
+ if (!fwSession->mdSession->GetDeviceError) {
+ return (CK_ULONG)0;
+ }
- return fwSession->mdSession->GetDeviceError(fwSession->mdSession,
- fwSession, fwSession->mdToken, fwSession->fwToken,
- fwSession->mdInstance, fwSession->fwInstance);
+ return fwSession->mdSession->GetDeviceError(fwSession->mdSession,
+ fwSession, fwSession->mdToken, fwSession->fwToken,
+ fwSession->mdInstance, fwSession->fwInstance);
}
/*
@@ -673,116 +632,117 @@ nssCKFWSession_GetDeviceError
*
*/
NSS_IMPLEMENT CK_RV
-nssCKFWSession_Login
-(
- NSSCKFWSession *fwSession,
- CK_USER_TYPE userType,
- NSSItem *pin
-)
+nssCKFWSession_Login(
+ NSSCKFWSession *fwSession,
+ CK_USER_TYPE userType,
+ NSSItem *pin)
{
- CK_RV error = CKR_OK;
- CK_STATE oldState;
- CK_STATE newState;
+ CK_RV error = CKR_OK;
+ CK_STATE oldState;
+ CK_STATE newState;
#ifdef NSSDEBUG
- error = nssCKFWSession_verifyPointer(fwSession);
- if( CKR_OK != error ) {
- return error;
- }
+ 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;
- }
+ 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 (!pin) {
+ if (CK_TRUE != nssCKFWToken_GetHasProtectedAuthenticationPath(fwSession->fwToken)) {
+ return CKR_ARGUMENTS_BAD;
+ }
}
- }
- if (!fwSession->mdSession) {
- return CKR_GENERAL_ERROR;
- }
+ 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) {
+ oldState = nssCKFWToken_GetSessionState(fwSession->fwToken);
+
/*
- * The Module doesn't want to be informed (or check the pin)
- * it'll just rely on the Framework as needed.
+ * 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.
*/
- ;
- } 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;
+
+ 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;
}
/*
@@ -790,74 +750,72 @@ nssCKFWSession_Login
*
*/
NSS_IMPLEMENT CK_RV
-nssCKFWSession_Logout
-(
- NSSCKFWSession *fwSession
-)
+nssCKFWSession_Logout(
+ NSSCKFWSession *fwSession)
{
- CK_RV error = CKR_OK;
- CK_STATE oldState;
- CK_STATE newState;
+ CK_RV error = CKR_OK;
+ CK_STATE oldState;
+ CK_STATE newState;
#ifdef NSSDEBUG
- error = nssCKFWSession_verifyPointer(fwSession);
- if( CKR_OK != error ) {
- return error;
- }
+ error = nssCKFWSession_verifyPointer(fwSession);
+ if (CKR_OK != error) {
+ return error;
+ }
- if (!fwSession->mdSession) {
- return CKR_GENERAL_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) {
+ 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;
+ }
+
/*
- * The Module doesn't want to be informed. Okay.
+ * 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;
*/
- ;
- } 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;
+
+ 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;
}
/*
@@ -865,47 +823,45 @@ nssCKFWSession_Logout
*
*/
NSS_IMPLEMENT CK_RV
-nssCKFWSession_InitPIN
-(
- NSSCKFWSession *fwSession,
- NSSItem *pin
-)
+nssCKFWSession_InitPIN(
+ NSSCKFWSession *fwSession,
+ NSSItem *pin)
{
- CK_RV error = CKR_OK;
- CK_STATE state;
+ CK_RV error = CKR_OK;
+ CK_STATE state;
#ifdef NSSDEBUG
- error = nssCKFWSession_verifyPointer(fwSession);
- if( CKR_OK != error ) {
- return error;
- }
+ error = nssCKFWSession_verifyPointer(fwSession);
+ if (CKR_OK != error) {
+ return error;
+ }
- if (!fwSession->mdSession) {
- return CKR_GENERAL_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;
- }
+ 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 (!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;
- }
+ 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);
+ error = fwSession->mdSession->InitPIN(fwSession->mdSession, fwSession,
+ fwSession->mdToken, fwSession->fwToken, fwSession->mdInstance,
+ fwSession->fwInstance, pin);
- return error;
+ return error;
}
/*
@@ -913,49 +869,47 @@ nssCKFWSession_InitPIN
*
*/
NSS_IMPLEMENT CK_RV
-nssCKFWSession_SetPIN
-(
- NSSCKFWSession *fwSession,
- NSSItem *newPin,
- NSSItem *oldPin
-)
+nssCKFWSession_SetPIN(
+ NSSCKFWSession *fwSession,
+ NSSItem *oldPin,
+ NSSItem *newPin)
{
- CK_RV error = CKR_OK;
+ CK_RV error = CKR_OK;
#ifdef NSSDEBUG
- error = nssCKFWSession_verifyPointer(fwSession);
- if( CKR_OK != error ) {
- return error;
- }
+ error = nssCKFWSession_verifyPointer(fwSession);
+ if (CKR_OK != error) {
+ return error;
+ }
- if (!fwSession->mdSession) {
- return CKR_GENERAL_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 (!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 (!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;
- }
+ 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);
+ error = fwSession->mdSession->SetPIN(fwSession->mdSession, fwSession,
+ fwSession->mdToken, fwSession->fwToken, fwSession->mdInstance,
+ fwSession->fwInstance, oldPin, newPin);
- return error;
+ return error;
}
/*
@@ -963,54 +917,52 @@ nssCKFWSession_SetPIN
*
*/
NSS_IMPLEMENT CK_ULONG
-nssCKFWSession_GetOperationStateLen
-(
- NSSCKFWSession *fwSession,
- CK_RV *pError
-)
+nssCKFWSession_GetOperationStateLen(
+ NSSCKFWSession *fwSession,
+ CK_RV *pError)
{
- CK_ULONG mdAmt;
- CK_ULONG fwAmt;
+ 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;
- }
+ 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;
- }
+ if (!fwSession->mdSession->GetOperationStateLen) {
+ *pError = CKR_STATE_UNSAVEABLE;
+ return (CK_ULONG)0;
+ }
- /*
- * We could check that the session is actually in some state..
- */
+ /*
+ * 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);
+ 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;
- }
+ if (((CK_ULONG)0 == mdAmt) && (CKR_OK != *pError)) {
+ return (CK_ULONG)0;
+ }
- /*
- * Add a bit of sanity-checking
- */
- fwAmt = mdAmt + 2*sizeof(CK_ULONG);
+ /*
+ * Add a bit of sanity-checking
+ */
+ fwAmt = mdAmt + 2 * sizeof(CK_ULONG);
- return fwAmt;
+ return fwAmt;
}
/*
@@ -1018,82 +970,80 @@ nssCKFWSession_GetOperationStateLen
*
*/
NSS_IMPLEMENT CK_RV
-nssCKFWSession_GetOperationState
-(
- NSSCKFWSession *fwSession,
- NSSItem *buffer
-)
+nssCKFWSession_GetOperationState(
+ NSSCKFWSession *fwSession,
+ NSSItem *buffer)
{
- CK_RV error = CKR_OK;
- CK_ULONG fwAmt;
- CK_ULONG *ulBuffer;
- NSSItem i2;
- CK_ULONG n, i;
+ 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;
- }
+ error = nssCKFWSession_verifyPointer(fwSession);
+ if (CKR_OK != error) {
+ return error;
+ }
- if (!buffer) {
- return CKR_ARGUMENTS_BAD;
- }
+ if (!buffer) {
+ return CKR_ARGUMENTS_BAD;
+ }
- if (!buffer->data) {
- return CKR_ARGUMENTS_BAD;
- }
+ if (!buffer->data) {
+ return CKR_ARGUMENTS_BAD;
+ }
- if (!fwSession->mdSession) {
- return CKR_GENERAL_ERROR;
- }
+ if (!fwSession->mdSession) {
+ return CKR_GENERAL_ERROR;
+ }
#endif /* NSSDEBUG */
- if (!fwSession->mdSession->GetOperationState) {
- return CKR_STATE_UNSAVEABLE;
- }
+ if (!fwSession->mdSession->GetOperationState) {
+ return CKR_STATE_UNSAVEABLE;
+ }
- /*
- * Sanity-check the caller's buffer.
- */
+ /*
+ * Sanity-check the caller's buffer.
+ */
- error = CKR_OK;
- fwAmt = nssCKFWSession_GetOperationStateLen(fwSession, &error);
- if( ((CK_ULONG)0 == fwAmt) && (CKR_OK != error) ) {
- return error;
- }
+ 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;
- }
+ if (buffer->size < fwAmt) {
+ return CKR_BUFFER_TOO_SMALL;
+ }
- ulBuffer = (CK_ULONG *)buffer->data;
+ ulBuffer = (CK_ULONG *)buffer->data;
- i2.size = buffer->size - 2*sizeof(CK_ULONG);
- i2.data = (void *)&ulBuffer[2];
+ 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);
+ 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;
+ 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;
}
/*
@@ -1101,126 +1051,122 @@ nssCKFWSession_GetOperationState
*
*/
NSS_IMPLEMENT CK_RV
-nssCKFWSession_SetOperationState
-(
- NSSCKFWSession *fwSession,
- NSSItem *state,
- NSSCKFWObject *encryptionKey,
- NSSCKFWObject *authenticationKey
-)
+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;
+ 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;
- }
+ error = nssCKFWSession_verifyPointer(fwSession);
+ if (CKR_OK != error) {
+ return error;
+ }
- if (!state) {
- return CKR_ARGUMENTS_BAD;
- }
+ if (!state) {
+ return CKR_ARGUMENTS_BAD;
+ }
- if (!state->data) {
- return CKR_ARGUMENTS_BAD;
- }
+ if (!state->data) {
+ return CKR_ARGUMENTS_BAD;
+ }
- if (encryptionKey) {
- error = nssCKFWObject_verifyPointer(encryptionKey);
- if( CKR_OK != error ) {
- return error;
+ 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 (authenticationKey) {
+ error = nssCKFWObject_verifyPointer(authenticationKey);
+ if (CKR_OK != error) {
+ return error;
+ }
}
- }
- if (!fwSession->mdSession) {
- return CKR_GENERAL_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;
- }
+ 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;
+ }
- /*
- * Here'd we restore any session data
- */
-
- return CKR_OK;
+ 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
-)
+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;
- }
+ 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;
+ return CK_FALSE;
}
/*
@@ -1228,133 +1174,132 @@ nss_attributes_form_token_object
*
*/
NSS_IMPLEMENT NSSCKFWObject *
-nssCKFWSession_CreateObject
-(
- NSSCKFWSession *fwSession,
- CK_ATTRIBUTE_PTR pTemplate,
- CK_ULONG ulAttributeCount,
- CK_RV *pError
-)
+nssCKFWSession_CreateObject(
+ NSSCKFWSession *fwSession,
+ CK_ATTRIBUTE_PTR pTemplate,
+ CK_ULONG ulAttributeCount,
+ CK_RV *pError)
{
- NSSArena *arena;
- NSSCKMDObject *mdObject;
- NSSCKFWObject *fwObject;
- CK_BBOOL isTokenObject;
+ 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.
- */
+ if (!pError) {
+ return (NSSCKFWObject *)NULL;
+ }
- isTokenObject = nss_attributes_form_token_object(pTemplate, ulAttributeCount);
- if( CK_TRUE == isTokenObject ) {
- /* === TOKEN OBJECT === */
+ *pError = nssCKFWSession_verifyPointer(fwSession);
+ if (CKR_OK != pError) {
+ return (NSSCKFWObject *)NULL;
+ }
- if (!fwSession->mdSession->CreateObject) {
- *pError = CKR_TOKEN_WRITE_PROTECTED;
- return (NSSCKFWObject *)NULL;
+ if ((CK_ATTRIBUTE_PTR)NULL == pTemplate) {
+ *pError = CKR_ARGUMENTS_BAD;
+ return (NSSCKFWObject *)NULL;
}
- arena = nssCKFWToken_GetArena(fwSession->fwToken, pError);
- if (!arena) {
- if( CKR_OK == *pError ) {
+ if (!fwSession->mdSession) {
*pError = CKR_GENERAL_ERROR;
- }
- return (NSSCKFWObject *)NULL;
+ return (NSSCKFWObject *)NULL;
}
+#endif /* NSSDEBUG */
- goto callmdcreateobject;
- } else {
- /* === SESSION OBJECT === */
+ /*
+ * Here would be an excellent place to sanity-check the object.
+ */
- arena = nssCKFWSession_GetArena(fwSession, pError);
- if (!arena) {
- if( CKR_OK == *pError ) {
- *pError = CKR_GENERAL_ERROR;
- }
- return (NSSCKFWObject *)NULL;
+ 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;
+ }
}
- if( CK_TRUE == nssCKFWInstance_GetModuleHandlesSessionObjects(
- fwSession->fwInstance) ) {
- /* --- module handles the session object -- */
+callmdcreateobject:
+ mdObject = fwSession->mdSession->CreateObject(fwSession->mdSession,
+ fwSession, fwSession->mdToken, fwSession->fwToken,
+ fwSession->mdInstance, fwSession->fwInstance, arena, pTemplate,
+ ulAttributeCount, pError);
- if (!fwSession->mdSession->CreateObject) {
- *pError = CKR_GENERAL_ERROR;
+gotmdobject:
+ if (!mdObject) {
+ if (CKR_OK == *pError) {
+ *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);
+ }
+
+ 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;
- }
}
- }
-
- return fwObject;
+
+ 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;
}
/*
@@ -1362,222 +1307,228 @@ nssCKFWSession_CreateObject
*
*/
NSS_IMPLEMENT NSSCKFWObject *
-nssCKFWSession_CopyObject
-(
- NSSCKFWSession *fwSession,
- NSSCKFWObject *fwObject,
- CK_ATTRIBUTE_PTR pTemplate,
- CK_ULONG ulAttributeCount,
- CK_RV *pError
-)
+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;
+ 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;
- }
+ 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
- */
+ /*
+ * Sanity-check object
+ */
- if (!fwObject) {
- *pError = CKR_ARGUMENTS_BAD;
- return (NSSCKFWObject *)NULL;
- }
+ if (!fwObject) {
+ *pError = CKR_ARGUMENTS_BAD;
+ return (NSSCKFWObject *)NULL;
+ }
- oldIsToken = nssCKFWObject_IsTokenObject(fwObject);
+ 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;
+ 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 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;
+ 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);
+ 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;
- }
+ 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;
- }
+ 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);
+ 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;
+ }
+ }
+ }
- 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;
}
- }
- }
- 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;
+ }
- 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;
+ }
- 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;
+ }
- *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++;
+ }
+ }
- 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;
+ newTemplate = nss_ZNEWARRAY(tmpArena, CK_ATTRIBUTE, newLength);
+ if ((CK_ATTRIBUTE_PTR)NULL == newTemplate) {
+ NSSArena_Destroy(tmpArena);
+ *pError = CKR_HOST_MEMORY;
+ return (NSSCKFWObject *)NULL;
}
- }
- 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;
+
+ 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++;
+ }
}
- }
- 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;
+ /* 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;
}
- 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;
}
-
- NSSArena_Destroy(tmpArena);
- return rv;
- }
}
/*
@@ -1585,135 +1536,140 @@ nssCKFWSession_CopyObject
*
*/
NSS_IMPLEMENT NSSCKFWFindObjects *
-nssCKFWSession_FindObjectsInit
-(
- NSSCKFWSession *fwSession,
- CK_ATTRIBUTE_PTR pTemplate,
- CK_ULONG ulAttributeCount,
- CK_RV *pError
-)
+nssCKFWSession_FindObjectsInit(
+ NSSCKFWSession *fwSession,
+ CK_ATTRIBUTE_PTR pTemplate,
+ CK_ULONG ulAttributeCount,
+ CK_RV *pError)
{
- NSSCKMDFindObjects *mdfo1 = (NSSCKMDFindObjects *)NULL;
- NSSCKMDFindObjects *mdfo2 = (NSSCKMDFindObjects *)NULL;
+ 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?
- */
+ if (!pError) {
+ return (NSSCKFWFindObjects *)NULL;
+ }
- 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));
+ *pError = nssCKFWSession_verifyPointer(fwSession);
+ if (CKR_OK != *pError) {
+ return (NSSCKFWFindObjects *)NULL;
+ }
- if( CK_TRUE == isToken ) {
- /* Pass it on to the module's search routine */
- if (!fwSession->mdSession->FindObjectsInit) {
- goto wrap;
- }
+ if (((CK_ATTRIBUTE_PTR)NULL == pTemplate) && (ulAttributeCount != 0)) {
+ *pError = CKR_ARGUMENTS_BAD;
+ return (NSSCKFWFindObjects *)NULL;
+ }
- 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 (!fwSession->mdSession) {
+ *pError = CKR_GENERAL_ERROR;
+ return (NSSCKFWFindObjects *)NULL;
+ }
+#endif /* NSSDEBUG */
- if (!mdfo1) {
- if( CKR_OK == *pError ) {
- *pError = CKR_GENERAL_ERROR;
- }
- return (NSSCKFWFindObjects *)NULL;
+ 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;
+ }
}
-
- 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 (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;
+ }
- if (!mdfo1) {
- if( CKR_OK == *pError ) {
- *pError = CKR_GENERAL_ERROR;
+ goto wrap;
}
- return (NSSCKFWFindObjects *)NULL;
- }
+ /*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);
- 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);
+ if (!mdfo1) {
+ if (CKR_OK == *pError) {
+ *pError = CKR_GENERAL_ERROR;
+ }
+ return (NSSCKFWFindObjects *)NULL;
}
- 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;
}
- goto wrap;
- }
-
- wrap:
- return nssCKFWFindObjects_Create(fwSession, fwSession->fwToken,
- fwSession->fwInstance, mdfo1, mdfo2, pError);
+wrap:
+ return nssCKFWFindObjects_Create(fwSession, fwSession->fwToken,
+ fwSession->fwInstance, mdfo1, mdfo2, pError);
}
/*
@@ -1721,46 +1677,44 @@ nssCKFWSession_FindObjectsInit
*
*/
NSS_IMPLEMENT CK_RV
-nssCKFWSession_SeedRandom
-(
- NSSCKFWSession *fwSession,
- NSSItem *seed
-)
+nssCKFWSession_SeedRandom(
+ NSSCKFWSession *fwSession,
+ NSSItem *seed)
{
- CK_RV error = CKR_OK;
+ CK_RV error = CKR_OK;
#ifdef NSSDEBUG
- error = nssCKFWSession_verifyPointer(fwSession);
- if( CKR_OK != error ) {
- return error;
- }
+ error = nssCKFWSession_verifyPointer(fwSession);
+ if (CKR_OK != error) {
+ return error;
+ }
- if (!seed) {
- return CKR_ARGUMENTS_BAD;
- }
+ if (!seed) {
+ return CKR_ARGUMENTS_BAD;
+ }
- if (!seed->data) {
- return CKR_ARGUMENTS_BAD;
- }
+ if (!seed->data) {
+ return CKR_ARGUMENTS_BAD;
+ }
- if( 0 == seed->size ) {
- return CKR_ARGUMENTS_BAD;
- }
+ if (0 == seed->size) {
+ return CKR_ARGUMENTS_BAD;
+ }
- if (!fwSession->mdSession) {
- return CKR_GENERAL_ERROR;
- }
+ if (!fwSession->mdSession) {
+ return CKR_GENERAL_ERROR;
+ }
#endif /* NSSDEBUG */
- if (!fwSession->mdSession->SeedRandom) {
- return CKR_RANDOM_SEED_NOT_SUPPORTED;
- }
+ 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);
+ error = fwSession->mdSession->SeedRandom(fwSession->mdSession, fwSession,
+ fwSession->mdToken, fwSession->fwToken, fwSession->mdInstance,
+ fwSession->fwInstance, seed);
- return error;
+ return error;
}
/*
@@ -1768,565 +1722,541 @@ nssCKFWSession_SeedRandom
*
*/
NSS_IMPLEMENT CK_RV
-nssCKFWSession_GetRandom
-(
- NSSCKFWSession *fwSession,
- NSSItem *buffer
-)
+nssCKFWSession_GetRandom(
+ NSSCKFWSession *fwSession,
+ NSSItem *buffer)
{
- CK_RV error = CKR_OK;
+ CK_RV error = CKR_OK;
#ifdef NSSDEBUG
- error = nssCKFWSession_verifyPointer(fwSession);
- if( CKR_OK != error ) {
- return error;
- }
+ error = nssCKFWSession_verifyPointer(fwSession);
+ if (CKR_OK != error) {
+ return error;
+ }
- if (!buffer) {
- return CKR_ARGUMENTS_BAD;
- }
+ if (!buffer) {
+ return CKR_ARGUMENTS_BAD;
+ }
- if (!buffer->data) {
- return CKR_ARGUMENTS_BAD;
- }
+ if (!buffer->data) {
+ return CKR_ARGUMENTS_BAD;
+ }
- if (!fwSession->mdSession) {
- return CKR_GENERAL_ERROR;
- }
+ 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 (!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;
- }
+ if (0 == buffer->size) {
+ return CKR_OK;
+ }
- error = fwSession->mdSession->GetRandom(fwSession->mdSession, fwSession,
- fwSession->mdToken, fwSession->fwToken, fwSession->mdInstance,
- fwSession->fwInstance, buffer);
+ error = fwSession->mdSession->GetRandom(fwSession->mdSession, fwSession,
+ fwSession->mdToken, fwSession->fwToken, fwSession->mdInstance,
+ fwSession->fwInstance, buffer);
- return error;
+ return error;
}
-
/*
* nssCKFWSession_SetCurrentCryptoOperation
*/
NSS_IMPLEMENT void
-nssCKFWSession_SetCurrentCryptoOperation
-(
- NSSCKFWSession *fwSession,
- NSSCKFWCryptoOperation * fwOperation,
- NSSCKFWCryptoOperationState state
-)
+nssCKFWSession_SetCurrentCryptoOperation(
+ NSSCKFWSession *fwSession,
+ NSSCKFWCryptoOperation *fwOperation,
+ NSSCKFWCryptoOperationState state)
{
#ifdef NSSDEBUG
- CK_RV error = CKR_OK;
- error = nssCKFWSession_verifyPointer(fwSession);
- if( CKR_OK != error ) {
- return;
- }
+ CK_RV error = CKR_OK;
+ error = nssCKFWSession_verifyPointer(fwSession);
+ if (CKR_OK != error) {
+ return;
+ }
- if ( state >= NSSCKFWCryptoOperationState_Max) {
- return;
- }
+ if (state >= NSSCKFWCryptoOperationState_Max) {
+ return;
+ }
- if (!fwSession->mdSession) {
- return;
- }
+ if (!fwSession->mdSession) {
+ return;
+ }
#endif /* NSSDEBUG */
- fwSession->fwOperationArray[state] = fwOperation;
- return;
+ fwSession->fwOperationArray[state] = fwOperation;
+ return;
}
/*
* nssCKFWSession_GetCurrentCryptoOperation
*/
NSS_IMPLEMENT NSSCKFWCryptoOperation *
-nssCKFWSession_GetCurrentCryptoOperation
-(
- NSSCKFWSession *fwSession,
- NSSCKFWCryptoOperationState state
-)
+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;
- }
+ 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];
+ 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
-)
+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;
+ NSSCKFWCryptoOperation *fwOperation;
+ NSSItem outputBuffer;
+ CK_RV error = CKR_OK;
#ifdef NSSDEBUG
- error = nssCKFWSession_verifyPointer(fwSession);
- if( CKR_OK != error ) {
- return error;
- }
+ error = nssCKFWSession_verifyPointer(fwSession);
+ if (CKR_OK != error) {
+ return error;
+ }
- if (!fwSession->mdSession) {
- return CKR_GENERAL_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;
+ /* make sure we have a valid operation initialized */
+ fwOperation = nssCKFWSession_GetCurrentCryptoOperation(fwSession, state);
+ if (!fwOperation) {
+ return CKR_OPERATION_NOT_INITIALIZED;
}
- } 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;
+ /* make sure it's the correct type */
+ if (type != nssCKFWCryptoOperation_GetType(fwOperation)) {
+ return CKR_OPERATION_NOT_INITIALIZED;
}
- if (len > maxBufLen) {
- return CKR_BUFFER_TOO_SMALL;
+ /* 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;
+ outputBuffer.data = outBuf;
+ outputBuffer.size = *outBufLen;
- error = nssCKFWCryptoOperation_Final(fwOperation, &outputBuffer);
+ error = nssCKFWCryptoOperation_Final(fwOperation, &outputBuffer);
done:
- if (CKR_BUFFER_TOO_SMALL == error) {
+ if (CKR_BUFFER_TOO_SMALL == error) {
+ return error;
+ }
+ /* clean up our state */
+ nssCKFWCryptoOperation_Destroy(fwOperation);
+ nssCKFWSession_SetCurrentCryptoOperation(fwSession, NULL, state);
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
-)
+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;
+ 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;
- }
+ error = nssCKFWSession_verifyPointer(fwSession);
+ if (CKR_OK != error) {
+ return error;
+ }
- if (!fwSession->mdSession) {
- return CKR_GENERAL_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 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;
- }
+ /* make sure it's the correct type */
+ if (type != nssCKFWCryptoOperation_GetType(fwOperation)) {
+ return CKR_OPERATION_NOT_INITIALIZED;
+ }
- inputBuffer.data = inBuf;
- inputBuffer.size = inBufLen;
+ 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;
+ /* 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;
- }
+ *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;
+ if (len > maxBufLen) {
+ return CKR_BUFFER_TOO_SMALL;
+ }
+ outputBuffer.data = outBuf;
+ outputBuffer.size = *outBufLen;
- return nssCKFWCryptoOperation_Update(fwOperation,
- &inputBuffer, &outputBuffer);
+ 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
-)
+nssCKFWSession_DigestUpdate(
+ NSSCKFWSession *fwSession,
+ NSSCKFWCryptoOperationType type,
+ NSSCKFWCryptoOperationState state,
+ CK_BYTE_PTR inBuf,
+ CK_ULONG inBufLen)
{
- NSSCKFWCryptoOperation *fwOperation;
- NSSItem inputBuffer;
- CK_RV error = CKR_OK;
+ NSSCKFWCryptoOperation *fwOperation;
+ NSSItem inputBuffer;
+ CK_RV error = CKR_OK;
#ifdef NSSDEBUG
- error = nssCKFWSession_verifyPointer(fwSession);
- if( CKR_OK != error ) {
- return error;
- }
+ error = nssCKFWSession_verifyPointer(fwSession);
+ if (CKR_OK != error) {
+ return error;
+ }
- if (!fwSession->mdSession) {
- return CKR_GENERAL_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;
- }
+ /* make sure we have a valid operation initialized */
+ fwOperation = nssCKFWSession_GetCurrentCryptoOperation(fwSession, state);
+ if (!fwOperation) {
+ return CKR_OPERATION_NOT_INITIALIZED;
+ }
- inputBuffer.data = inBuf;
- inputBuffer.size = inBufLen;
+ /* 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;
+ error = nssCKFWCryptoOperation_DigestUpdate(fwOperation, &inputBuffer);
+ return error;
}
/*
* nssCKFWSession_DigestUpdate
*/
NSS_IMPLEMENT CK_RV
-nssCKFWSession_DigestKey
-(
- NSSCKFWSession *fwSession,
- NSSCKFWObject *fwKey
-)
+nssCKFWSession_DigestKey(
+ NSSCKFWSession *fwSession,
+ NSSCKFWObject *fwKey)
{
- NSSCKFWCryptoOperation *fwOperation;
- NSSItem *inputBuffer;
- CK_RV error = CKR_OK;
+ NSSCKFWCryptoOperation *fwOperation;
+ NSSItem *inputBuffer;
+ CK_RV error = CKR_OK;
#ifdef NSSDEBUG
- error = nssCKFWSession_verifyPointer(fwSession);
- if( CKR_OK != error ) {
- return error;
- }
+ error = nssCKFWSession_verifyPointer(fwSession);
+ if (CKR_OK != error) {
+ return error;
+ }
- if (!fwSession->mdSession) {
- return CKR_GENERAL_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;
- }
+ /* 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 */
+ /* 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;
- }
- 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
-)
+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;
+ 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;
- }
+ error = nssCKFWSession_verifyPointer(fwSession);
+ if (CKR_OK != error) {
+ return error;
+ }
- if (!fwSession->mdSession) {
- return CKR_GENERAL_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 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;
- }
+ /* 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)) ;
+ 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;
+ /* 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);
+ len = (isEncryptDecrypt) ? nssCKFWCryptoOperation_GetOperationLength(fwOperation,
+ &inputBuffer, &error)
+ : nssCKFWCryptoOperation_GetFinalLength(fwOperation, &error);
- if (CKR_OK != error) {
- goto done;
- }
+ if (CKR_OK != error) {
+ goto done;
+ }
- *outBufLen = len;
- if ((CK_BYTE_PTR)NULL == outBuf) {
- return CKR_OK;
- }
+ *outBufLen = len;
+ if ((CK_BYTE_PTR)NULL == outBuf) {
+ return CKR_OK;
+ }
- if (len > maxBufLen) {
- return CKR_BUFFER_TOO_SMALL;
+ if (len > maxBufLen) {
+ return CKR_BUFFER_TOO_SMALL;
+ }
}
- }
- outputBuffer.data = outBuf;
- outputBuffer.size = *outBufLen;
+ outputBuffer.data = outBuf;
+ outputBuffer.size = *outBufLen;
- error = nssCKFWCryptoOperation_UpdateFinal(fwOperation,
- &inputBuffer, &outputBuffer);
+ 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);
+ /* 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);
+ 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;
- }
+ 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;
+ /* 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
-)
+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;
+ 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;
- }
+ error = nssCKFWSession_verifyPointer(fwSession);
+ if (CKR_OK != error) {
+ return error;
+ }
- if (!fwSession->mdSession) {
- return CKR_GENERAL_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;
- }
+ /* make sure we have a valid operation initialized */
+ fwOperation = nssCKFWSession_GetCurrentCryptoOperation(fwSession,
+ NSSCKFWCryptoOperationState_EncryptDecrypt);
+ if (!fwOperation) {
+ return CKR_OPERATION_NOT_INITIALIZED;
+ }
- outputBuffer.data = outBuf;
- outputBuffer.size = *outBufLen;
+ /* 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;
+ }
- error = nssCKFWCryptoOperation_UpdateCombo(fwOperation, fwPeerOperation,
- &inputBuffer, &outputBuffer);
- if (CKR_FUNCTION_FAILED == error) {
- PRBool isEncrypt =
- (PRBool) (NSSCKFWCryptoOperationType_Encrypt == encryptType);
+ /* make sure it's the correct type */
+ if (digestType != nssCKFWCryptoOperation_GetType(fwOperation)) {
+ return CKR_OPERATION_NOT_INITIALIZED;
+ }
- if (isEncrypt) {
- error = nssCKFWCryptoOperation_DigestUpdate(fwPeerOperation,
- &inputBuffer);
- if (CKR_OK != error) {
+ inputBuffer.data = inBuf;
+ inputBuffer.size = inBufLen;
+ len = nssCKFWCryptoOperation_GetOperationLength(fwOperation,
+ &inputBuffer, &error);
+ if (CKR_OK != error) {
return error;
- }
}
- error = nssCKFWCryptoOperation_Update(fwOperation,
- &inputBuffer, &outputBuffer);
- if (CKR_OK != error) {
- return error;
+
+ *outBufLen = len;
+ if ((CK_BYTE_PTR)NULL == outBuf) {
+ return CKR_OK;
}
- if (!isEncrypt) {
- error = nssCKFWCryptoOperation_DigestUpdate(fwPeerOperation,
- &outputBuffer);
+
+ if (len > maxBufLen) {
+ return CKR_BUFFER_TOO_SMALL;
}
- }
- return error;
-}
+ 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
@@ -2334,18 +2264,16 @@ nssCKFWSession_UpdateCombo
*/
NSS_IMPLEMENT NSSCKMDSession *
-NSSCKFWSession_GetMDSession
-(
- NSSCKFWSession *fwSession
-)
+NSSCKFWSession_GetMDSession(
+ NSSCKFWSession *fwSession)
{
#ifdef DEBUG
- if( CKR_OK != nssCKFWSession_verifyPointer(fwSession) ) {
- return (NSSCKMDSession *)NULL;
- }
+ if (CKR_OK != nssCKFWSession_verifyPointer(fwSession)) {
+ return (NSSCKMDSession *)NULL;
+ }
#endif /* DEBUG */
- return nssCKFWSession_GetMDSession(fwSession);
+ return nssCKFWSession_GetMDSession(fwSession);
}
/*
@@ -2354,24 +2282,22 @@ NSSCKFWSession_GetMDSession
*/
NSS_IMPLEMENT NSSArena *
-NSSCKFWSession_GetArena
-(
- NSSCKFWSession *fwSession,
- CK_RV *pError
-)
+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;
- }
+ if (!pError) {
+ return (NSSArena *)NULL;
+ }
+
+ *pError = nssCKFWSession_verifyPointer(fwSession);
+ if (CKR_OK != *pError) {
+ return (NSSArena *)NULL;
+ }
#endif /* DEBUG */
- return nssCKFWSession_GetArena(fwSession, pError);
+ return nssCKFWSession_GetArena(fwSession, pError);
}
/*
@@ -2380,22 +2306,20 @@ NSSCKFWSession_GetArena
*/
NSS_IMPLEMENT CK_RV
-NSSCKFWSession_CallNotification
-(
- NSSCKFWSession *fwSession,
- CK_NOTIFICATION event
-)
+NSSCKFWSession_CallNotification(
+ NSSCKFWSession *fwSession,
+ CK_NOTIFICATION event)
{
#ifdef DEBUG
- CK_RV error = CKR_OK;
+ CK_RV error = CKR_OK;
- error = nssCKFWSession_verifyPointer(fwSession);
- if( CKR_OK != error ) {
- return error;
- }
+ error = nssCKFWSession_verifyPointer(fwSession);
+ if (CKR_OK != error) {
+ return error;
+ }
#endif /* DEBUG */
- return nssCKFWSession_CallNotification(fwSession, event);
+ return nssCKFWSession_CallNotification(fwSession, event);
}
/*
@@ -2404,18 +2328,16 @@ NSSCKFWSession_CallNotification
*/
NSS_IMPLEMENT CK_BBOOL
-NSSCKFWSession_IsRWSession
-(
- NSSCKFWSession *fwSession
-)
+NSSCKFWSession_IsRWSession(
+ NSSCKFWSession *fwSession)
{
#ifdef DEBUG
- if( CKR_OK != nssCKFWSession_verifyPointer(fwSession) ) {
- return CK_FALSE;
- }
+ if (CKR_OK != nssCKFWSession_verifyPointer(fwSession)) {
+ return CK_FALSE;
+ }
#endif /* DEBUG */
- return nssCKFWSession_IsRWSession(fwSession);
+ return nssCKFWSession_IsRWSession(fwSession);
}
/*
@@ -2424,37 +2346,45 @@ NSSCKFWSession_IsRWSession
*/
NSS_IMPLEMENT CK_BBOOL
-NSSCKFWSession_IsSO
-(
- NSSCKFWSession *fwSession
-)
+NSSCKFWSession_IsSO(
+ NSSCKFWSession *fwSession)
{
#ifdef DEBUG
- if( CKR_OK != nssCKFWSession_verifyPointer(fwSession) ) {
- return CK_FALSE;
- }
+ if (CKR_OK != nssCKFWSession_verifyPointer(fwSession)) {
+ return CK_FALSE;
+ }
#endif /* DEBUG */
- return nssCKFWSession_IsSO(fwSession);
+ return nssCKFWSession_IsSO(fwSession);
}
NSS_IMPLEMENT NSSCKFWCryptoOperation *
-NSSCKFWSession_GetCurrentCryptoOperation
-(
- NSSCKFWSession *fwSession,
- NSSCKFWCryptoOperationState state
-)
+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;
- }
+ 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);
+ return nssCKFWSession_GetCurrentCryptoOperation(fwSession, state);
+}
+
+/*
+ * NSSCKFWSession_GetFWSlot
+ *
+ */
+
+NSS_IMPLEMENT NSSCKFWSlot *
+NSSCKFWSession_GetFWSlot(
+ NSSCKFWSession *fwSession)
+{
+ return nssCKFWSession_GetFWSlot(fwSession);
}
diff --git a/nss/lib/ckfw/sessobj.c b/nss/lib/ckfw/sessobj.c
index 113b0f4..11721b8 100644
--- a/nss/lib/ckfw/sessobj.c
+++ b/nss/lib/ckfw/sessobj.c
@@ -5,7 +5,7 @@
/*
* sessobj.c
*
- * This file contains an NSSCKMDObject implementation for session
+ * 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.
*/
@@ -32,11 +32,11 @@
*/
struct nssCKMDSessionObjectStr {
- CK_ULONG n;
- NSSArena *arena;
- NSSItem *attributes;
- CK_ATTRIBUTE_TYPE_PTR types;
- nssCKFWHash *hash;
+ CK_ULONG n;
+ NSSArena *arena;
+ NSSItem *attributes;
+ CK_ATTRIBUTE_TYPE_PTR types;
+ nssCKFWHash *hash;
};
typedef struct nssCKMDSessionObjectStr nssCKMDSessionObject;
@@ -53,31 +53,25 @@ typedef struct nssCKMDSessionObjectStr nssCKMDSessionObject;
*/
static CK_RV
-nss_ckmdSessionObject_add_pointer
-(
- const NSSCKMDObject *mdObject
-)
+nss_ckmdSessionObject_add_pointer(
+ const NSSCKMDObject *mdObject)
{
- return CKR_OK;
+ return CKR_OK;
}
static CK_RV
-nss_ckmdSessionObject_remove_pointer
-(
- const NSSCKMDObject *mdObject
-)
+nss_ckmdSessionObject_remove_pointer(
+ const NSSCKMDObject *mdObject)
{
- return CKR_OK;
+ return CKR_OK;
}
#ifdef NSS_DEBUG
static CK_RV
-nss_ckmdSessionObject_verifyPointer
-(
- const NSSCKMDObject *mdObject
-)
+nss_ckmdSessionObject_verifyPointer(
+ const NSSCKMDObject *mdObject)
{
- return CKR_OK;
+ return CKR_OK;
}
#endif
@@ -87,234 +81,214 @@ nss_ckmdSessionObject_verifyPointer
* 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
-);
+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
-);
+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
-);
+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
-);
+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
-);
+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
-);
+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
-);
+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
-);
+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
-);
+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
-)
+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;
+ 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;
}
- (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;
- }
+ if ((*pError = nss_ckmdSessionObject_add_pointer(mdObject)) != CKR_OK) {
+ goto loser;
+ }
#endif /* DEBUG */
- return mdObject;
+ return mdObject;
- loser:
- if (mdso) {
- if (mdso->attributes) {
- for( i = 0; i < ulCount; i++ ) {
- nss_ZFreeIf(mdso->attributes[i].data);
- }
- nss_ZFreeIf(mdso->attributes);
+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(mdso->types);
- nss_ZFreeIf(mdso);
- }
- nss_ZFreeIf(mdObject);
- if (*pError == CKR_OK) {
- *pError = CKR_HOST_MEMORY;
- }
- return (NSSCKMDObject *)NULL;
+ nss_ZFreeIf(mdObject);
+ if (*pError == CKR_OK) {
+ *pError = CKR_HOST_MEMORY;
+ }
+ return (NSSCKMDObject *)NULL;
}
/*
@@ -322,20 +296,18 @@ nssCKMDSessionObject_Create
*
*/
static void
-nss_ckmdSessionObject_Finalize
-(
- NSSCKMDObject *mdObject,
- NSSCKFWObject *fwObject,
- NSSCKMDSession *mdSession,
- NSSCKFWSession *fwSession,
- NSSCKMDToken *mdToken,
- NSSCKFWToken *fwToken,
- NSSCKMDInstance *mdInstance,
- NSSCKFWInstance *fwInstance
-)
+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;
+ /* This shouldn't ever be called */
+ return;
}
/*
@@ -344,48 +316,46 @@ nss_ckmdSessionObject_Finalize
*/
static CK_RV
-nss_ckmdSessionObject_Destroy
-(
- NSSCKMDObject *mdObject,
- NSSCKFWObject *fwObject,
- NSSCKMDSession *mdSession,
- NSSCKFWSession *fwSession,
- NSSCKMDToken *mdToken,
- NSSCKFWToken *fwToken,
- NSSCKMDInstance *mdInstance,
- NSSCKFWInstance *fwInstance
-)
+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;
+ CK_RV error = CKR_OK;
#endif /* NSSDEBUG */
- nssCKMDSessionObject *mdso;
- CK_ULONG i;
+ nssCKMDSessionObject *mdso;
+ CK_ULONG i;
#ifdef NSSDEBUG
- error = nss_ckmdSessionObject_verifyPointer(mdObject);
- if( CKR_OK != error ) {
- return error;
- }
+ error = nss_ckmdSessionObject_verifyPointer(mdObject);
+ if (CKR_OK != error) {
+ return error;
+ }
#endif /* NSSDEBUG */
- mdso = (nssCKMDSessionObject *)mdObject->etc;
+ mdso = (nssCKMDSessionObject *)mdObject->etc;
- nssCKFWHash_Remove(mdso->hash, mdObject);
+ 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);
+ 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);
+ (void)nss_ckmdSessionObject_remove_pointer(mdObject);
#endif /* DEBUG */
- return CKR_OK;
+ return CKR_OK;
}
/*
@@ -394,28 +364,26 @@ nss_ckmdSessionObject_Destroy
*/
static CK_BBOOL
-nss_ckmdSessionObject_IsTokenObject
-(
- NSSCKMDObject *mdObject,
- NSSCKFWObject *fwObject,
- NSSCKMDSession *mdSession,
- NSSCKFWSession *fwSession,
- NSSCKMDToken *mdToken,
- NSSCKFWToken *fwToken,
- NSSCKMDInstance *mdInstance,
- NSSCKFWInstance *fwInstance
-)
+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;
- }
+ if (CKR_OK != nss_ckmdSessionObject_verifyPointer(mdObject)) {
+ return CK_FALSE;
+ }
#endif /* NSSDEBUG */
- /*
- * This implementation is only ever used for session objects.
- */
- return CK_FALSE;
+ /*
+ * This implementation is only ever used for session objects.
+ */
+ return CK_FALSE;
}
/*
@@ -423,37 +391,35 @@ nss_ckmdSessionObject_IsTokenObject
*
*/
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
-)
+nss_ckmdSessionObject_GetAttributeCount(
+ NSSCKMDObject *mdObject,
+ NSSCKFWObject *fwObject,
+ NSSCKMDSession *mdSession,
+ NSSCKFWSession *fwSession,
+ NSSCKMDToken *mdToken,
+ NSSCKFWToken *fwToken,
+ NSSCKMDInstance *mdInstance,
+ NSSCKFWInstance *fwInstance,
+ CK_RV *pError)
{
- nssCKMDSessionObject *obj;
+ nssCKMDSessionObject *obj;
#ifdef NSSDEBUG
- if (!pError) {
- return 0;
- }
+ if (!pError) {
+ return 0;
+ }
- *pError = nss_ckmdSessionObject_verifyPointer(mdObject);
- if( CKR_OK != *pError ) {
- return 0;
- }
+ *pError = nss_ckmdSessionObject_verifyPointer(mdObject);
+ if (CKR_OK != *pError) {
+ return 0;
+ }
- /* We could even check all the other arguments, for sanity. */
+/* We could even check all the other arguments, for sanity. */
#endif /* NSSDEBUG */
- obj = (nssCKMDSessionObject *)mdObject->etc;
+ obj = (nssCKMDSessionObject *)mdObject->etc;
- return obj->n;
+ return obj->n;
}
/*
@@ -461,44 +427,43 @@ nss_ckmdSessionObject_GetAttributeCount
*
*/
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
-)
+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;
+ CK_RV error = CKR_OK;
#endif /* NSSDEBUG */
- nssCKMDSessionObject *obj;
+ nssCKMDSessionObject *obj;
#ifdef NSSDEBUG
- error = nss_ckmdSessionObject_verifyPointer(mdObject);
- if( CKR_OK != error ) {
- return error;
- }
+ error = nss_ckmdSessionObject_verifyPointer(mdObject);
+ if (CKR_OK != error) {
+ return error;
+ }
- /* We could even check all the other arguments, for sanity. */
+/* We could even check all the other arguments, for sanity. */
#endif /* NSSDEBUG */
- obj = (nssCKMDSessionObject *)mdObject->etc;
+ obj = (nssCKMDSessionObject *)mdObject->etc;
- if( ulCount < obj->n ) {
- return CKR_BUFFER_TOO_SMALL;
- }
+ if (ulCount < obj->n) {
+ return CKR_BUFFER_TOO_SMALL;
+ }
- (void)nsslibc_memcpy(typeArray, obj->types,
- sizeof(CK_ATTRIBUTE_TYPE) * obj->n);
+ (void)nsslibc_memcpy(typeArray, obj->types,
+ sizeof(CK_ATTRIBUTE_TYPE) *
+ obj->n);
- return CKR_OK;
+ return CKR_OK;
}
/*
@@ -506,46 +471,44 @@ nss_ckmdSessionObject_GetAttributeTypes
*
*/
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
-)
+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;
+ nssCKMDSessionObject *obj;
+ CK_ULONG i;
#ifdef NSSDEBUG
- if (!pError) {
- return 0;
- }
+ if (!pError) {
+ return 0;
+ }
- *pError = nss_ckmdSessionObject_verifyPointer(mdObject);
- if( CKR_OK != *pError ) {
- return 0;
- }
+ *pError = nss_ckmdSessionObject_verifyPointer(mdObject);
+ if (CKR_OK != *pError) {
+ return 0;
+ }
- /* We could even check all the other arguments, for sanity. */
+/* We could even check all the other arguments, for sanity. */
#endif /* NSSDEBUG */
- obj = (nssCKMDSessionObject *)mdObject->etc;
+ obj = (nssCKMDSessionObject *)mdObject->etc;
- for( i = 0; i < obj->n; i++ ) {
- if( attribute == obj->types[i] ) {
- return (CK_ULONG)(obj->attributes[i].size);
+ 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;
+ *pError = CKR_ATTRIBUTE_TYPE_INVALID;
+ return 0;
}
/*
@@ -553,50 +516,48 @@ nss_ckmdSessionObject_GetAttributeSize
*
*/
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
-)
+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;
+ NSSCKFWItem item;
+ nssCKMDSessionObject *obj;
+ CK_ULONG i;
- item.needsFreeing = PR_FALSE;
- item.item = NULL;
+ item.needsFreeing = PR_FALSE;
+ item.item = NULL;
#ifdef NSSDEBUG
- if (!pError) {
- return item;
- }
+ if (!pError) {
+ return item;
+ }
- *pError = nss_ckmdSessionObject_verifyPointer(mdObject);
- if( CKR_OK != *pError ) {
- return item;
- }
+ *pError = nss_ckmdSessionObject_verifyPointer(mdObject);
+ if (CKR_OK != *pError) {
+ return item;
+ }
- /* We could even check all the other arguments, for sanity. */
+/* We could even check all the other arguments, for sanity. */
#endif /* NSSDEBUG */
- obj = (nssCKMDSessionObject *)mdObject->etc;
+ obj = (nssCKMDSessionObject *)mdObject->etc;
- for( i = 0; i < obj->n; i++ ) {
- if( attribute == obj->types[i] ) {
- item.item = &obj->attributes[i];
- return item;
+ 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;
+ *pError = CKR_ATTRIBUTE_TYPE_INVALID;
+ return item;
}
/*
@@ -612,79 +573,77 @@ nss_ckmdSessionObject_GetAttribute
* 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
-)
+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;
+ nssCKMDSessionObject *obj;
+ CK_ULONG i;
+ NSSItem n;
+ NSSItem *ra;
+ CK_ATTRIBUTE_TYPE_PTR rt;
#ifdef NSSDEBUG
- CK_RV error;
+ CK_RV error;
#endif /* NSSDEBUG */
#ifdef NSSDEBUG
- error = nss_ckmdSessionObject_verifyPointer(mdObject);
- if( CKR_OK != error ) {
- return 0;
- }
+ error = nss_ckmdSessionObject_verifyPointer(mdObject);
+ if (CKR_OK != error) {
+ return 0;
+ }
- /* We could even check all the other arguments, for sanity. */
+/* We could even check all the other arguments, for sanity. */
#endif /* NSSDEBUG */
- obj = (nssCKMDSessionObject *)mdObject->etc;
+ 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);
+ 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;
+ 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;
+
+ /*
+ * 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;
}
/*
@@ -692,47 +651,45 @@ nss_ckmdSessionObject_SetAttribute
*
*/
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
-)
+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;
+ nssCKMDSessionObject *obj;
+ CK_ULONG i;
+ CK_ULONG rv = (CK_ULONG)0;
#ifdef NSSDEBUG
- if (!pError) {
- return 0;
- }
+ if (!pError) {
+ return 0;
+ }
- *pError = nss_ckmdSessionObject_verifyPointer(mdObject);
- if( CKR_OK != *pError ) {
- return 0;
- }
+ *pError = nss_ckmdSessionObject_verifyPointer(mdObject);
+ if (CKR_OK != *pError) {
+ return 0;
+ }
- /* We could even check all the other arguments, for sanity. */
+/* We could even check all the other arguments, for sanity. */
#endif /* NSSDEBUG */
- obj = (nssCKMDSessionObject *)mdObject->etc;
+ obj = (nssCKMDSessionObject *)mdObject->etc;
- for( i = 0; i < obj->n; i++ ) {
- rv += obj->attributes[i].size;
- }
+ 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);
+ rv += sizeof(NSSItem) * obj->n;
+ rv += sizeof(CK_ATTRIBUTE_TYPE) * obj->n;
+ rv += sizeof(nssCKMDSessionObject);
- return rv;
+ return rv;
}
/*
@@ -747,18 +704,17 @@ nss_ckmdSessionObject_GetObjectSize
*/
struct nodeStr {
- struct nodeStr *next;
- NSSCKMDObject *mdObject;
+ struct nodeStr *next;
+ NSSCKMDObject *mdObject;
};
struct nssCKMDFindSessionObjectsStr {
- NSSArena *arena;
- CK_RV error;
- CK_ATTRIBUTE_PTR pTemplate;
- CK_ULONG ulCount;
- struct nodeStr *list;
- nssCKFWHash *hash;
-
+ NSSArena *arena;
+ CK_RV error;
+ CK_ATTRIBUTE_PTR pTemplate;
+ CK_ULONG ulCount;
+ struct nodeStr *list;
+ nssCKFWHash *hash;
};
typedef struct nssCKMDFindSessionObjectsStr nssCKMDFindSessionObjects;
@@ -775,31 +731,25 @@ typedef struct nssCKMDFindSessionObjectsStr nssCKMDFindSessionObjects;
*/
static CK_RV
-nss_ckmdFindSessionObjects_add_pointer
-(
- const NSSCKMDFindObjects *mdFindObjects
-)
+nss_ckmdFindSessionObjects_add_pointer(
+ const NSSCKMDFindObjects *mdFindObjects)
{
- return CKR_OK;
+ return CKR_OK;
}
static CK_RV
-nss_ckmdFindSessionObjects_remove_pointer
-(
- const NSSCKMDFindObjects *mdFindObjects
-)
+nss_ckmdFindSessionObjects_remove_pointer(
+ const NSSCKMDFindObjects *mdFindObjects)
{
- return CKR_OK;
+ return CKR_OK;
}
#ifdef NSS_DEBUG
static CK_RV
-nss_ckmdFindSessionObjects_verifyPointer
-(
- const NSSCKMDFindObjects *mdFindObjects
-)
+nss_ckmdFindSessionObjects_verifyPointer(
+ const NSSCKMDFindObjects *mdFindObjects)
{
- return CKR_OK;
+ return CKR_OK;
}
#endif
@@ -809,104 +759,96 @@ nss_ckmdFindSessionObjects_verifyPointer
* 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
-);
+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
-);
+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
-)
+items_match(
+ NSSItem *a,
+ CK_VOID_PTR pValue,
+ CK_ULONG ulValueLen)
{
- if( a->size != ulValueLen ) {
- return CK_FALSE;
- }
+ 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;
- }
+ 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
-)
+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;
- }
+ 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 (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;
+ }
+ }
+ }
- 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;
}
- }
}
- 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;
}
- }
-
- /* 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;
+ node->mdObject = mdObject;
+ node->next = mdfso->list;
+ mdfso->list = node;
- return;
+ return;
}
/*
@@ -914,162 +856,157 @@ findfcn
*
*/
NSS_IMPLEMENT NSSCKMDFindObjects *
-nssCKMDFindSessionObjects_Create
-(
- NSSCKFWToken *fwToken,
- CK_ATTRIBUTE_PTR pTemplate,
- CK_ULONG ulCount,
- CK_RV *pError
-)
+nssCKMDFindSessionObjects_Create(
+ NSSCKFWToken *fwToken,
+ CK_ATTRIBUTE_PTR pTemplate,
+ CK_ULONG ulCount,
+ CK_RV *pError)
{
- NSSArena *arena;
- nssCKMDFindSessionObjects *mdfso;
- nssCKFWHash *hash;
- NSSCKMDFindObjects *rv;
+ 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;
- }
+ 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;
+ *pError = CKR_OK;
- hash = nssCKFWToken_GetSessionObjectHash(fwToken);
- if (!hash) {
- *pError= CKR_GENERAL_ERROR;
- return (NSSCKMDFindObjects *)NULL;
- }
+ 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;
- }
+ arena = NSSArena_Create();
+ if (!arena) {
+ *pError = CKR_HOST_MEMORY;
+ return (NSSCKMDFindObjects *)NULL;
+ }
- mdfso = nss_ZNEW(arena, nssCKMDFindSessionObjects);
- if (!mdfso) {
- goto loser;
- }
+ mdfso = nss_ZNEW(arena, nssCKMDFindSessionObjects);
+ if (!mdfso) {
+ goto loser;
+ }
- rv = nss_ZNEW(arena, NSSCKMDFindObjects);
- if(rv == NULL) {
- 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;
+ mdfso->error = CKR_OK;
+ mdfso->pTemplate = pTemplate;
+ mdfso->ulCount = ulCount;
+ mdfso->hash = hash;
- nssCKFWHash_Iterate(hash, findfcn, mdfso);
+ nssCKFWHash_Iterate(hash, findfcn, mdfso);
- if( CKR_OK != mdfso->error ) {
- goto loser;
- }
+ if (CKR_OK != mdfso->error) {
+ goto loser;
+ }
- rv->etc = (void *)mdfso;
- rv->Final = nss_ckmdFindSessionObjects_Final;
- rv->Next = nss_ckmdFindSessionObjects_Next;
+ 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;
+ if ((*pError = nss_ckmdFindSessionObjects_add_pointer(rv)) != CKR_OK) {
+ goto loser;
+ }
+#endif /* DEBUG */
+ mdfso->arena = arena;
- return rv;
+ return rv;
loser:
- if (arena) {
- NSSArena_Destroy(arena);
- }
- if (*pError == CKR_OK) {
- *pError = CKR_HOST_MEMORY;
- }
- return NULL;
+ 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
-)
+nss_ckmdFindSessionObjects_Final(
+ NSSCKMDFindObjects *mdFindObjects,
+ NSSCKFWFindObjects *fwFindObjects,
+ NSSCKMDSession *mdSession,
+ NSSCKFWSession *fwSession,
+ NSSCKMDToken *mdToken,
+ NSSCKFWToken *fwToken,
+ NSSCKMDInstance *mdInstance,
+ NSSCKFWInstance *fwInstance)
{
- nssCKMDFindSessionObjects *mdfso;
+ nssCKMDFindSessionObjects *mdfso;
#ifdef NSSDEBUG
- if( CKR_OK != nss_ckmdFindSessionObjects_verifyPointer(mdFindObjects) ) {
- return;
- }
+ if (CKR_OK != nss_ckmdFindSessionObjects_verifyPointer(mdFindObjects)) {
+ return;
+ }
#endif /* NSSDEBUG */
- mdfso = (nssCKMDFindSessionObjects *)mdFindObjects->etc;
- if (mdfso->arena) NSSArena_Destroy(mdfso->arena);
+ mdfso = (nssCKMDFindSessionObjects *)mdFindObjects->etc;
+ if (mdfso->arena)
+ NSSArena_Destroy(mdfso->arena);
#ifdef DEBUG
- (void)nss_ckmdFindSessionObjects_remove_pointer(mdFindObjects);
+ (void)nss_ckmdFindSessionObjects_remove_pointer(mdFindObjects);
#endif /* DEBUG */
- return;
+ 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
-)
+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;
+ nssCKMDFindSessionObjects *mdfso;
+ NSSCKMDObject *rv = (NSSCKMDObject *)NULL;
#ifdef NSSDEBUG
- if( CKR_OK != nss_ckmdFindSessionObjects_verifyPointer(mdFindObjects) ) {
- return (NSSCKMDObject *)NULL;
- }
+ if (CKR_OK != nss_ckmdFindSessionObjects_verifyPointer(mdFindObjects)) {
+ return (NSSCKMDObject *)NULL;
+ }
#endif /* NSSDEBUG */
- mdfso = (nssCKMDFindSessionObjects *)mdFindObjects->etc;
+ mdfso = (nssCKMDFindSessionObjects *)mdFindObjects->etc;
- while (!rv) {
- if( (struct nodeStr *)NULL == mdfso->list ) {
- *pError = CKR_OK;
- return (NSSCKMDObject *)NULL;
- }
+ 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;
- }
+ if (nssCKFWHash_Exists(mdfso->hash, mdfso->list->mdObject)) {
+ rv = mdfso->list->mdObject;
+ }
- mdfso->list = mdfso->list->next;
- }
+ mdfso->list = mdfso->list->next;
+ }
- return rv;
+ return rv;
}
diff --git a/nss/lib/ckfw/slot.c b/nss/lib/ckfw/slot.c
index 658aedb..43d4f0d 100644
--- a/nss/lib/ckfw/slot.c
+++ b/nss/lib/ckfw/slot.c
@@ -23,14 +23,15 @@
* NSSCKFWSlot_GetMDSlot
* NSSCKFWSlot_GetFWInstance
* NSSCKFWSlot_GetMDInstance
+ * NSSCKFWSlot_GetSlotID
*
* -- implement public accessors --
* nssCKFWSlot_GetMDSlot
* nssCKFWSlot_GetFWInstance
* nssCKFWSlot_GetMDInstance
+ * nssCKFWSlot_GetSlotID
*
* -- private accessors --
- * nssCKFWSlot_GetSlotID
* nssCKFWSlot_ClearToken
*
* -- module fronts --
@@ -46,35 +47,35 @@
*/
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;
+ 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
@@ -90,30 +91,24 @@ struct NSSCKFWSlotStr {
*/
static CK_RV
-slot_add_pointer
-(
- const NSSCKFWSlot *fwSlot
-)
+slot_add_pointer(
+ const NSSCKFWSlot *fwSlot)
{
- return CKR_OK;
+ return CKR_OK;
}
static CK_RV
-slot_remove_pointer
-(
- const NSSCKFWSlot *fwSlot
-)
+slot_remove_pointer(
+ const NSSCKFWSlot *fwSlot)
{
- return CKR_OK;
+ return CKR_OK;
}
NSS_IMPLEMENT CK_RV
-nssCKFWSlot_verifyPointer
-(
- const NSSCKFWSlot *fwSlot
-)
+nssCKFWSlot_verifyPointer(
+ const NSSCKFWSlot *fwSlot)
{
- return CKR_OK;
+ return CKR_OK;
}
#endif /* DEBUG */
@@ -123,86 +118,84 @@ nssCKFWSlot_verifyPointer
*
*/
NSS_IMPLEMENT NSSCKFWSlot *
-nssCKFWSlot_Create
-(
- NSSCKFWInstance *fwInstance,
- NSSCKMDSlot *mdSlot,
- CK_SLOT_ID slotID,
- CK_RV *pError
-)
+nssCKFWSlot_Create(
+ NSSCKFWInstance *fwInstance,
+ NSSCKMDSlot *mdSlot,
+ CK_SLOT_ID slotID,
+ CK_RV *pError)
{
- NSSCKFWSlot *fwSlot;
- NSSCKMDInstance *mdInstance;
- NSSArena *arena;
+ 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 */
+ if (!pError) {
+ return (NSSCKFWSlot *)NULL;
+ }
- mdInstance = nssCKFWInstance_GetMDInstance(fwInstance);
- if (!mdInstance) {
- *pError = CKR_GENERAL_ERROR;
- return (NSSCKFWSlot *)NULL;
- }
+ *pError = nssCKFWInstance_verifyPointer(fwInstance);
+ if (CKR_OK != *pError) {
+ return (NSSCKFWSlot *)NULL;
+ }
+#endif /* NSSDEBUG */
- arena = nssCKFWInstance_GetArena(fwInstance, pError);
- if (!arena) {
- if( CKR_OK == *pError ) {
- *pError = CKR_GENERAL_ERROR;
+ mdInstance = nssCKFWInstance_GetMDInstance(fwInstance);
+ if (!mdInstance) {
+ *pError = CKR_GENERAL_ERROR;
+ return (NSSCKFWSlot *)NULL;
}
- }
- fwSlot = nss_ZNEW(arena, NSSCKFWSlot);
- if (!fwSlot) {
- *pError = CKR_HOST_MEMORY;
- return (NSSCKFWSlot *)NULL;
- }
+ arena = nssCKFWInstance_GetArena(fwInstance, pError);
+ if (!arena) {
+ if (CKR_OK == *pError) {
+ *pError = CKR_GENERAL_ERROR;
+ }
+ }
- fwSlot->mdSlot = mdSlot;
- fwSlot->fwInstance = fwInstance;
- fwSlot->mdInstance = mdInstance;
- fwSlot->slotID = slotID;
+ fwSlot = nss_ZNEW(arena, NSSCKFWSlot);
+ if (!fwSlot) {
+ *pError = CKR_HOST_MEMORY;
+ return (NSSCKFWSlot *)NULL;
+ }
- fwSlot->mutex = nssCKFWInstance_CreateMutex(fwInstance, arena, pError);
- if (!fwSlot->mutex) {
- if( CKR_OK == *pError ) {
- *pError = CKR_GENERAL_ERROR;
+ 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;
}
- (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;
+ 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);
+ *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;
}
-
- (void)nssCKFWMutex_Destroy(fwSlot->mutex);
- (void)nss_ZFreeIf(fwSlot);
- return (NSSCKFWSlot *)NULL;
- }
#endif /* DEBUG */
- return fwSlot;
+ return fwSlot;
}
/*
@@ -210,35 +203,33 @@ nssCKFWSlot_Create
*
*/
NSS_IMPLEMENT CK_RV
-nssCKFWSlot_Destroy
-(
- NSSCKFWSlot *fwSlot
-)
+nssCKFWSlot_Destroy(
+ NSSCKFWSlot *fwSlot)
{
- CK_RV error = CKR_OK;
+ CK_RV error = CKR_OK;
#ifdef NSSDEBUG
- error = nssCKFWSlot_verifyPointer(fwSlot);
- if( CKR_OK != error ) {
- return error;
- }
+ error = nssCKFWSlot_verifyPointer(fwSlot);
+ if (CKR_OK != error) {
+ return error;
+ }
#endif /* NSSDEBUG */
- if (fwSlot->fwToken) {
- nssCKFWToken_Destroy(fwSlot->fwToken);
- }
+ if (fwSlot->fwToken) {
+ nssCKFWToken_Destroy(fwSlot->fwToken);
+ }
- (void)nssCKFWMutex_Destroy(fwSlot->mutex);
+ (void)nssCKFWMutex_Destroy(fwSlot->mutex);
- if (fwSlot->mdSlot->Destroy) {
- fwSlot->mdSlot->Destroy(fwSlot->mdSlot, fwSlot,
- fwSlot->mdInstance, fwSlot->fwInstance);
- }
+ if (fwSlot->mdSlot->Destroy) {
+ fwSlot->mdSlot->Destroy(fwSlot->mdSlot, fwSlot,
+ fwSlot->mdInstance, fwSlot->fwInstance);
+ }
#ifdef DEBUG
- error = slot_remove_pointer(fwSlot);
+ error = slot_remove_pointer(fwSlot);
#endif /* DEBUG */
- (void)nss_ZFreeIf(fwSlot);
- return error;
+ (void)nss_ZFreeIf(fwSlot);
+ return error;
}
/*
@@ -246,18 +237,16 @@ nssCKFWSlot_Destroy
*
*/
NSS_IMPLEMENT NSSCKMDSlot *
-nssCKFWSlot_GetMDSlot
-(
- NSSCKFWSlot *fwSlot
-)
+nssCKFWSlot_GetMDSlot(
+ NSSCKFWSlot *fwSlot)
{
#ifdef NSSDEBUG
- if( CKR_OK != nssCKFWSlot_verifyPointer(fwSlot) ) {
- return (NSSCKMDSlot *)NULL;
- }
+ if (CKR_OK != nssCKFWSlot_verifyPointer(fwSlot)) {
+ return (NSSCKMDSlot *)NULL;
+ }
#endif /* NSSDEBUG */
- return fwSlot->mdSlot;
+ return fwSlot->mdSlot;
}
/*
@@ -266,18 +255,16 @@ nssCKFWSlot_GetMDSlot
*/
NSS_IMPLEMENT NSSCKFWInstance *
-nssCKFWSlot_GetFWInstance
-(
- NSSCKFWSlot *fwSlot
-)
+nssCKFWSlot_GetFWInstance(
+ NSSCKFWSlot *fwSlot)
{
#ifdef NSSDEBUG
- if( CKR_OK != nssCKFWSlot_verifyPointer(fwSlot) ) {
- return (NSSCKFWInstance *)NULL;
- }
+ if (CKR_OK != nssCKFWSlot_verifyPointer(fwSlot)) {
+ return (NSSCKFWInstance *)NULL;
+ }
#endif /* NSSDEBUG */
- return fwSlot->fwInstance;
+ return fwSlot->fwInstance;
}
/*
@@ -286,18 +273,16 @@ nssCKFWSlot_GetFWInstance
*/
NSS_IMPLEMENT NSSCKMDInstance *
-nssCKFWSlot_GetMDInstance
-(
- NSSCKFWSlot *fwSlot
-)
+nssCKFWSlot_GetMDInstance(
+ NSSCKFWSlot *fwSlot)
{
#ifdef NSSDEBUG
- if( CKR_OK != nssCKFWSlot_verifyPointer(fwSlot) ) {
- return (NSSCKMDInstance *)NULL;
- }
+ if (CKR_OK != nssCKFWSlot_verifyPointer(fwSlot)) {
+ return (NSSCKMDInstance *)NULL;
+ }
#endif /* NSSDEBUG */
- return fwSlot->mdInstance;
+ return fwSlot->mdInstance;
}
/*
@@ -305,18 +290,16 @@ nssCKFWSlot_GetMDInstance
*
*/
NSS_IMPLEMENT CK_SLOT_ID
-nssCKFWSlot_GetSlotID
-(
- NSSCKFWSlot *fwSlot
-)
+nssCKFWSlot_GetSlotID(
+ NSSCKFWSlot *fwSlot)
{
#ifdef NSSDEBUG
- if( CKR_OK != nssCKFWSlot_verifyPointer(fwSlot) ) {
- return (CK_SLOT_ID)0;
- }
+ if (CKR_OK != nssCKFWSlot_verifyPointer(fwSlot)) {
+ return (CK_SLOT_ID)0;
+ }
#endif /* NSSDEBUG */
- return fwSlot->slotID;
+ return fwSlot->slotID;
}
/*
@@ -324,49 +307,47 @@ nssCKFWSlot_GetSlotID
*
*/
NSS_IMPLEMENT CK_RV
-nssCKFWSlot_GetSlotDescription
-(
- NSSCKFWSlot *fwSlot,
- CK_CHAR slotDescription[64]
-)
+nssCKFWSlot_GetSlotDescription(
+ NSSCKFWSlot *fwSlot,
+ CK_CHAR slotDescription[64])
{
- CK_RV error = CKR_OK;
+ CK_RV error = CKR_OK;
#ifdef NSSDEBUG
- if( (CK_CHAR_PTR)NULL == slotDescription ) {
- return CKR_ARGUMENTS_BAD;
- }
+ if ((CK_CHAR_PTR)NULL == slotDescription) {
+ return CKR_ARGUMENTS_BAD;
+ }
- error = nssCKFWSlot_verifyPointer(fwSlot);
- if( CKR_OK != error ) {
- return error;
- }
+ 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 *) "";
+ error = nssCKFWMutex_Lock(fwSlot->mutex);
+ if (CKR_OK != error) {
+ return error;
}
- }
- (void)nssUTF8_CopyIntoFixedBuffer(fwSlot->slotDescription, (char *)slotDescription, 64, ' ');
- error = CKR_OK;
+ 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;
+done:
+ (void)nssCKFWMutex_Unlock(fwSlot->mutex);
+ return error;
}
/*
@@ -374,49 +355,47 @@ nssCKFWSlot_GetSlotDescription
*
*/
NSS_IMPLEMENT CK_RV
-nssCKFWSlot_GetManufacturerID
-(
- NSSCKFWSlot *fwSlot,
- CK_CHAR manufacturerID[32]
-)
+nssCKFWSlot_GetManufacturerID(
+ NSSCKFWSlot *fwSlot,
+ CK_CHAR manufacturerID[32])
{
- CK_RV error = CKR_OK;
+ CK_RV error = CKR_OK;
#ifdef NSSDEBUG
- if( (CK_CHAR_PTR)NULL == manufacturerID ) {
- return CKR_ARGUMENTS_BAD;
- }
+ if ((CK_CHAR_PTR)NULL == manufacturerID) {
+ return CKR_ARGUMENTS_BAD;
+ }
- error = nssCKFWSlot_verifyPointer(fwSlot);
- if( CKR_OK != error ) {
- return error;
- }
+ 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 *) "";
+ error = nssCKFWMutex_Lock(fwSlot->mutex);
+ if (CKR_OK != error) {
+ return error;
}
- }
- (void)nssUTF8_CopyIntoFixedBuffer(fwSlot->manufacturerID, (char *)manufacturerID, 32, ' ');
- error = CKR_OK;
+ 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;
+done:
+ (void)nssCKFWMutex_Unlock(fwSlot->mutex);
+ return error;
}
/*
@@ -424,23 +403,21 @@ nssCKFWSlot_GetManufacturerID
*
*/
NSS_IMPLEMENT CK_BBOOL
-nssCKFWSlot_GetTokenPresent
-(
- NSSCKFWSlot *fwSlot
-)
+nssCKFWSlot_GetTokenPresent(
+ NSSCKFWSlot *fwSlot)
{
#ifdef NSSDEBUG
- if( CKR_OK != nssCKFWSlot_verifyPointer(fwSlot) ) {
- return CK_FALSE;
- }
+ if (CKR_OK != nssCKFWSlot_verifyPointer(fwSlot)) {
+ return CK_FALSE;
+ }
#endif /* NSSDEBUG */
- if (!fwSlot->mdSlot->GetTokenPresent) {
- return CK_TRUE;
- }
+ if (!fwSlot->mdSlot->GetTokenPresent) {
+ return CK_TRUE;
+ }
- return fwSlot->mdSlot->GetTokenPresent(fwSlot->mdSlot, fwSlot,
- fwSlot->mdInstance, fwSlot->fwInstance);
+ return fwSlot->mdSlot->GetTokenPresent(fwSlot->mdSlot, fwSlot,
+ fwSlot->mdInstance, fwSlot->fwInstance);
}
/*
@@ -448,23 +425,21 @@ nssCKFWSlot_GetTokenPresent
*
*/
NSS_IMPLEMENT CK_BBOOL
-nssCKFWSlot_GetRemovableDevice
-(
- NSSCKFWSlot *fwSlot
-)
+nssCKFWSlot_GetRemovableDevice(
+ NSSCKFWSlot *fwSlot)
{
#ifdef NSSDEBUG
- if( CKR_OK != nssCKFWSlot_verifyPointer(fwSlot) ) {
- return CK_FALSE;
- }
+ if (CKR_OK != nssCKFWSlot_verifyPointer(fwSlot)) {
+ return CK_FALSE;
+ }
#endif /* NSSDEBUG */
- if (!fwSlot->mdSlot->GetRemovableDevice) {
- return CK_FALSE;
- }
+ if (!fwSlot->mdSlot->GetRemovableDevice) {
+ return CK_FALSE;
+ }
- return fwSlot->mdSlot->GetRemovableDevice(fwSlot->mdSlot, fwSlot,
- fwSlot->mdInstance, fwSlot->fwInstance);
+ return fwSlot->mdSlot->GetRemovableDevice(fwSlot->mdSlot, fwSlot,
+ fwSlot->mdInstance, fwSlot->fwInstance);
}
/*
@@ -472,23 +447,21 @@ nssCKFWSlot_GetRemovableDevice
*
*/
NSS_IMPLEMENT CK_BBOOL
-nssCKFWSlot_GetHardwareSlot
-(
- NSSCKFWSlot *fwSlot
-)
+nssCKFWSlot_GetHardwareSlot(
+ NSSCKFWSlot *fwSlot)
{
#ifdef NSSDEBUG
- if( CKR_OK != nssCKFWSlot_verifyPointer(fwSlot) ) {
- return CK_FALSE;
- }
+ if (CKR_OK != nssCKFWSlot_verifyPointer(fwSlot)) {
+ return CK_FALSE;
+ }
#endif /* NSSDEBUG */
- if (!fwSlot->mdSlot->GetHardwareSlot) {
- return CK_FALSE;
- }
+ if (!fwSlot->mdSlot->GetHardwareSlot) {
+ return CK_FALSE;
+ }
- return fwSlot->mdSlot->GetHardwareSlot(fwSlot->mdSlot, fwSlot,
- fwSlot->mdInstance, fwSlot->fwInstance);
+ return fwSlot->mdSlot->GetHardwareSlot(fwSlot->mdSlot, fwSlot,
+ fwSlot->mdInstance, fwSlot->fwInstance);
}
/*
@@ -496,43 +469,41 @@ nssCKFWSlot_GetHardwareSlot
*
*/
NSS_IMPLEMENT CK_VERSION
-nssCKFWSlot_GetHardwareVersion
-(
- NSSCKFWSlot *fwSlot
-)
+nssCKFWSlot_GetHardwareVersion(
+ NSSCKFWSlot *fwSlot)
{
- CK_VERSION rv;
+ CK_VERSION rv;
#ifdef NSSDEBUG
- if( CKR_OK != nssCKFWSlot_verifyPointer(fwSlot) ) {
- rv.major = rv.minor = 0;
- return rv;
- }
+ 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 (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;
+ }
- 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;
+done:
+ (void)nssCKFWMutex_Unlock(fwSlot->mutex);
+ return rv;
}
/*
@@ -540,100 +511,96 @@ nssCKFWSlot_GetHardwareVersion
*
*/
NSS_IMPLEMENT CK_VERSION
-nssCKFWSlot_GetFirmwareVersion
-(
- NSSCKFWSlot *fwSlot
-)
+nssCKFWSlot_GetFirmwareVersion(
+ NSSCKFWSlot *fwSlot)
{
- CK_VERSION rv;
+ CK_VERSION rv;
#ifdef NSSDEBUG
- if( CKR_OK != nssCKFWSlot_verifyPointer(fwSlot) ) {
- rv.major = rv.minor = 0;
- return rv;
- }
+ 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 (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;
+ }
- 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;
+done:
+ (void)nssCKFWMutex_Unlock(fwSlot->mutex);
+ return rv;
}
/*
* nssCKFWSlot_GetToken
- *
+ *
*/
NSS_IMPLEMENT NSSCKFWToken *
-nssCKFWSlot_GetToken
-(
- NSSCKFWSlot *fwSlot,
- CK_RV *pError
-)
+nssCKFWSlot_GetToken(
+ NSSCKFWSlot *fwSlot,
+ CK_RV *pError)
{
- NSSCKMDToken *mdToken;
- NSSCKFWToken *fwToken;
+ 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 (!pError) {
+ return (NSSCKFWToken *)NULL;
+ }
- if (!fwSlot->fwToken) {
- if (!fwSlot->mdSlot->GetToken) {
- *pError = CKR_GENERAL_ERROR;
- fwToken = (NSSCKFWToken *)NULL;
- goto done;
+ *pError = nssCKFWSlot_verifyPointer(fwSlot);
+ if (CKR_OK != *pError) {
+ return (NSSCKFWToken *)NULL;
}
+#endif /* NSSDEBUG */
- 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;
+ *pError = nssCKFWMutex_Lock(fwSlot->mutex);
+ if (CKR_OK != *pError) {
+ return (NSSCKFWToken *)NULL;
}
- fwToken = nssCKFWToken_Create(fwSlot, mdToken, pError);
- fwSlot->fwToken = fwToken;
- } else {
- fwToken = fwSlot->fwToken;
- }
+ 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;
+done:
+ (void)nssCKFWMutex_Unlock(fwSlot->mutex);
+ return fwToken;
}
/*
@@ -641,25 +608,23 @@ nssCKFWSlot_GetToken
*
*/
NSS_IMPLEMENT void
-nssCKFWSlot_ClearToken
-(
- NSSCKFWSlot *fwSlot
-)
+nssCKFWSlot_ClearToken(
+ NSSCKFWSlot *fwSlot)
{
#ifdef NSSDEBUG
- if( CKR_OK != nssCKFWSlot_verifyPointer(fwSlot) ) {
- return;
- }
+ if (CKR_OK != nssCKFWSlot_verifyPointer(fwSlot)) {
+ return;
+ }
#endif /* NSSDEBUG */
- if( CKR_OK != nssCKFWMutex_Lock(fwSlot->mutex) ) {
- /* Now what? */
- return;
- }
+ if (CKR_OK != nssCKFWMutex_Lock(fwSlot->mutex)) {
+ /* Now what? */
+ return;
+ }
- fwSlot->fwToken = (NSSCKFWToken *)NULL;
- (void)nssCKFWMutex_Unlock(fwSlot->mutex);
- return;
+ fwSlot->fwToken = (NSSCKFWToken *)NULL;
+ (void)nssCKFWMutex_Unlock(fwSlot->mutex);
+ return;
}
/*
@@ -668,18 +633,16 @@ nssCKFWSlot_ClearToken
*/
NSS_IMPLEMENT NSSCKMDSlot *
-NSSCKFWSlot_GetMDSlot
-(
- NSSCKFWSlot *fwSlot
-)
+NSSCKFWSlot_GetMDSlot(
+ NSSCKFWSlot *fwSlot)
{
#ifdef DEBUG
- if( CKR_OK != nssCKFWSlot_verifyPointer(fwSlot) ) {
- return (NSSCKMDSlot *)NULL;
- }
+ if (CKR_OK != nssCKFWSlot_verifyPointer(fwSlot)) {
+ return (NSSCKMDSlot *)NULL;
+ }
#endif /* DEBUG */
- return nssCKFWSlot_GetMDSlot(fwSlot);
+ return nssCKFWSlot_GetMDSlot(fwSlot);
}
/*
@@ -688,18 +651,16 @@ NSSCKFWSlot_GetMDSlot
*/
NSS_IMPLEMENT NSSCKFWInstance *
-NSSCKFWSlot_GetFWInstance
-(
- NSSCKFWSlot *fwSlot
-)
+NSSCKFWSlot_GetFWInstance(
+ NSSCKFWSlot *fwSlot)
{
#ifdef DEBUG
- if( CKR_OK != nssCKFWSlot_verifyPointer(fwSlot) ) {
- return (NSSCKFWInstance *)NULL;
- }
+ if (CKR_OK != nssCKFWSlot_verifyPointer(fwSlot)) {
+ return (NSSCKFWInstance *)NULL;
+ }
#endif /* DEBUG */
- return nssCKFWSlot_GetFWInstance(fwSlot);
+ return nssCKFWSlot_GetFWInstance(fwSlot);
}
/*
@@ -708,16 +669,26 @@ NSSCKFWSlot_GetFWInstance
*/
NSS_IMPLEMENT NSSCKMDInstance *
-NSSCKFWSlot_GetMDInstance
-(
- NSSCKFWSlot *fwSlot
-)
+NSSCKFWSlot_GetMDInstance(
+ NSSCKFWSlot *fwSlot)
{
#ifdef DEBUG
- if( CKR_OK != nssCKFWSlot_verifyPointer(fwSlot) ) {
- return (NSSCKMDInstance *)NULL;
- }
+ if (CKR_OK != nssCKFWSlot_verifyPointer(fwSlot)) {
+ return (NSSCKMDInstance *)NULL;
+ }
#endif /* DEBUG */
- return nssCKFWSlot_GetMDInstance(fwSlot);
+ return nssCKFWSlot_GetMDInstance(fwSlot);
+}
+
+/*
+ * NSSCKFWSlot_GetSlotID
+ *
+ */
+
+NSS_IMPLEMENT CK_SLOT_ID
+NSSCKFWSlot_GetSlotID(
+ NSSCKFWSlot *fwSlot)
+{
+ return nssCKFWSlot_GetSlotID(fwSlot);
}
diff --git a/nss/lib/ckfw/token.c b/nss/lib/ckfw/token.c
index 4a97576..4483bb5 100644
--- a/nss/lib/ckfw/token.c
+++ b/nss/lib/ckfw/token.c
@@ -75,49 +75,49 @@
*/
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;
+ 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
@@ -133,30 +133,24 @@ struct NSSCKFWTokenStr {
*/
static CK_RV
-token_add_pointer
-(
- const NSSCKFWToken *fwToken
-)
+token_add_pointer(
+ const NSSCKFWToken *fwToken)
{
- return CKR_OK;
+ return CKR_OK;
}
static CK_RV
-token_remove_pointer
-(
- const NSSCKFWToken *fwToken
-)
+token_remove_pointer(
+ const NSSCKFWToken *fwToken)
{
- return CKR_OK;
+ return CKR_OK;
}
NSS_IMPLEMENT CK_RV
-nssCKFWToken_verifyPointer
-(
- const NSSCKFWToken *fwToken
-)
+nssCKFWToken_verifyPointer(
+ const NSSCKFWToken *fwToken)
{
- return CKR_OK;
+ return CKR_OK;
}
#endif /* DEBUG */
@@ -166,154 +160,148 @@ nssCKFWToken_verifyPointer
*
*/
NSS_IMPLEMENT NSSCKFWToken *
-nssCKFWToken_Create
-(
- NSSCKFWSlot *fwSlot,
- NSSCKMDToken *mdToken,
- CK_RV *pError
-)
+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;
+ 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;
+ fwToken->mdObjectHash = nssCKFWHash_Create(fwToken->fwInstance,
+ arena, pError);
+ if (!fwToken->mdObjectHash) {
+ if (CKR_OK == *pError) {
+ *pError = CKR_GENERAL_ERROR;
+ }
+ goto loser;
}
- goto loser;
- }
- fwToken->mdMechanismHash = nssCKFWHash_Create(fwToken->fwInstance,
- arena, pError);
- if (!fwToken->mdMechanismHash) {
- if( CKR_OK == *pError ) {
- *pError = CKR_GENERAL_ERROR;
+ fwToken->mdMechanismHash = nssCKFWHash_Create(fwToken->fwInstance,
+ arena, pError);
+ if (!fwToken->mdMechanismHash) {
+ if (CKR_OK == *pError) {
+ *pError = CKR_GENERAL_ERROR;
+ }
+ goto loser;
}
- goto loser;
- }
- /* More here */
+ /* More here */
- if (mdToken->Setup) {
- *pError = mdToken->Setup(mdToken, fwToken, fwToken->mdInstance, fwToken->fwInstance);
- if( CKR_OK != *pError ) {
- goto loser;
+ if (mdToken->Setup) {
+ *pError = mdToken->Setup(mdToken, fwToken, fwToken->mdInstance, fwToken->fwInstance);
+ if (CKR_OK != *pError) {
+ goto loser;
+ }
}
- }
- called_setup = CK_TRUE;
+ called_setup = CK_TRUE;
#ifdef DEBUG
- *pError = token_add_pointer(fwToken);
- if( CKR_OK != *pError ) {
- goto loser;
- }
+ *pError = token_add_pointer(fwToken);
+ if (CKR_OK != *pError) {
+ goto loser;
+ }
#endif /* DEBUG */
- *pError = CKR_OK;
- return fwToken;
+ *pError = CKR_OK;
+ return fwToken;
- loser:
+loser:
- if( CK_TRUE == called_setup ) {
- if (mdToken->Invalidate) {
- mdToken->Invalidate(mdToken, fwToken, fwToken->mdInstance, fwToken->fwInstance);
+ if (CK_TRUE == called_setup) {
+ if (mdToken->Invalidate) {
+ mdToken->Invalidate(mdToken, fwToken, fwToken->mdInstance, fwToken->fwInstance);
+ }
}
- }
- if (arena) {
- (void)NSSArena_Destroy(arena);
- }
+ if (arena) {
+ (void)NSSArena_Destroy(arena);
+ }
- return (NSSCKFWToken *)NULL;
+ return (NSSCKFWToken *)NULL;
}
static void
-nss_ckfwtoken_session_iterator
-(
- const void *key,
- void *value,
- void *closure
-)
+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;
+ /*
+ * 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
-)
+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;
+ /*
+ * Remember that the fwToken->mutex is locked
+ */
+ NSSCKFWObject *fwObject = (NSSCKFWObject *)value;
+ (void)nssCKFWObject_Finalize(fwObject, CK_FALSE);
+ return;
}
/*
@@ -321,56 +309,54 @@ nss_ckfwtoken_object_iterator
*
*/
NSS_IMPLEMENT CK_RV
-nssCKFWToken_Destroy
-(
- NSSCKFWToken *fwToken
-)
+nssCKFWToken_Destroy(
+ NSSCKFWToken *fwToken)
{
- CK_RV error = CKR_OK;
+ CK_RV error = CKR_OK;
#ifdef NSSDEBUG
- error = nssCKFWToken_verifyPointer(fwToken);
- if( CKR_OK != error ) {
- return error;
- }
+ 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);
-
+ (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);
+ error = token_remove_pointer(fwToken);
#endif /* DEBUG */
- (void)NSSArena_Destroy(fwToken->arena);
- return error;
+ (void)NSSArena_Destroy(fwToken->arena);
+ return error;
}
/*
@@ -378,18 +364,16 @@ nssCKFWToken_Destroy
*
*/
NSS_IMPLEMENT NSSCKMDToken *
-nssCKFWToken_GetMDToken
-(
- NSSCKFWToken *fwToken
-)
+nssCKFWToken_GetMDToken(
+ NSSCKFWToken *fwToken)
{
#ifdef NSSDEBUG
- if( CKR_OK != nssCKFWToken_verifyPointer(fwToken) ) {
- return (NSSCKMDToken *)NULL;
- }
+ if (CKR_OK != nssCKFWToken_verifyPointer(fwToken)) {
+ return (NSSCKMDToken *)NULL;
+ }
#endif /* NSSDEBUG */
- return fwToken->mdToken;
+ return fwToken->mdToken;
}
/*
@@ -397,24 +381,22 @@ nssCKFWToken_GetMDToken
*
*/
NSS_IMPLEMENT NSSArena *
-nssCKFWToken_GetArena
-(
- NSSCKFWToken *fwToken,
- CK_RV *pError
-)
+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;
- }
+ if (!pError) {
+ return (NSSArena *)NULL;
+ }
+
+ *pError = nssCKFWToken_verifyPointer(fwToken);
+ if (CKR_OK != *pError) {
+ return (NSSArena *)NULL;
+ }
#endif /* NSSDEBUG */
- return fwToken->arena;
+ return fwToken->arena;
}
/*
@@ -422,18 +404,16 @@ nssCKFWToken_GetArena
*
*/
NSS_IMPLEMENT NSSCKFWSlot *
-nssCKFWToken_GetFWSlot
-(
- NSSCKFWToken *fwToken
-)
+nssCKFWToken_GetFWSlot(
+ NSSCKFWToken *fwToken)
{
#ifdef NSSDEBUG
- if( CKR_OK != nssCKFWToken_verifyPointer(fwToken) ) {
- return (NSSCKFWSlot *)NULL;
- }
+ if (CKR_OK != nssCKFWToken_verifyPointer(fwToken)) {
+ return (NSSCKFWSlot *)NULL;
+ }
#endif /* NSSDEBUG */
- return fwToken->fwSlot;
+ return fwToken->fwSlot;
}
/*
@@ -441,18 +421,16 @@ nssCKFWToken_GetFWSlot
*
*/
NSS_IMPLEMENT NSSCKMDSlot *
-nssCKFWToken_GetMDSlot
-(
- NSSCKFWToken *fwToken
-)
+nssCKFWToken_GetMDSlot(
+ NSSCKFWToken *fwToken)
{
#ifdef NSSDEBUG
- if( CKR_OK != nssCKFWToken_verifyPointer(fwToken) ) {
- return (NSSCKMDSlot *)NULL;
- }
+ if (CKR_OK != nssCKFWToken_verifyPointer(fwToken)) {
+ return (NSSCKMDSlot *)NULL;
+ }
#endif /* NSSDEBUG */
- return fwToken->mdSlot;
+ return fwToken->mdSlot;
}
/*
@@ -460,29 +438,27 @@ nssCKFWToken_GetMDSlot
*
*/
NSS_IMPLEMENT CK_STATE
-nssCKFWToken_GetSessionState
-(
- NSSCKFWToken *fwToken
-)
+nssCKFWToken_GetSessionState(
+ NSSCKFWToken *fwToken)
{
#ifdef NSSDEBUG
- if( CKR_OK != nssCKFWToken_verifyPointer(fwToken) ) {
- return CKS_RO_PUBLIC_SESSION; /* whatever */
- }
+ if (CKR_OK != nssCKFWToken_verifyPointer(fwToken)) {
+ return CKS_RO_PUBLIC_SESSION; /* whatever */
+ }
#endif /* NSSDEBUG */
- /*
- * BTW, do not lock the token in this method.
- */
+ /*
+ * 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."
- */
+ /*
+ * 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;
+ return fwToken->state;
}
/*
@@ -490,56 +466,54 @@ nssCKFWToken_GetSessionState
*
*/
NSS_IMPLEMENT CK_RV
-nssCKFWToken_InitToken
-(
- NSSCKFWToken *fwToken,
- NSSItem *pin,
- NSSUTF8 *label
-)
+nssCKFWToken_InitToken(
+ NSSCKFWToken *fwToken,
+ NSSItem *pin,
+ NSSUTF8 *label)
{
- CK_RV error;
+ CK_RV error;
#ifdef NSSDEBUG
- error = nssCKFWToken_verifyPointer(fwToken);
- if( CKR_OK != error ) {
- return CKR_ARGUMENTS_BAD;
- }
+ 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;
- }
+ error = nssCKFWMutex_Lock(fwToken->mutex);
+ if (CKR_OK != error) {
+ return error;
+ }
- if( fwToken->sessionCount > 0 ) {
- error = CKR_SESSION_EXISTS;
- goto done;
- }
+ if (fwToken->sessionCount > 0) {
+ error = CKR_SESSION_EXISTS;
+ goto done;
+ }
- if (!fwToken->mdToken->InitToken) {
- error = CKR_DEVICE_ERROR;
- 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 (!pin) {
+ if (nssCKFWToken_GetHasProtectedAuthenticationPath(fwToken)) {
+ ; /* okay */
+ } else {
+ error = CKR_PIN_INCORRECT;
+ goto done;
+ }
}
- }
- if (!label) {
- label = (NSSUTF8 *) "";
- }
+ if (!label) {
+ label = (NSSUTF8 *)"";
+ }
- error = fwToken->mdToken->InitToken(fwToken->mdToken, fwToken,
- fwToken->mdInstance, fwToken->fwInstance, pin, label);
+ error = fwToken->mdToken->InitToken(fwToken->mdToken, fwToken,
+ fwToken->mdInstance, fwToken->fwInstance, pin, label);
- done:
- (void)nssCKFWMutex_Unlock(fwToken->mutex);
- return error;
+done:
+ (void)nssCKFWMutex_Unlock(fwToken->mutex);
+ return error;
}
/*
@@ -547,48 +521,46 @@ nssCKFWToken_InitToken
*
*/
NSS_IMPLEMENT CK_RV
-nssCKFWToken_GetLabel
-(
- NSSCKFWToken *fwToken,
- CK_CHAR label[32]
-)
+nssCKFWToken_GetLabel(
+ NSSCKFWToken *fwToken,
+ CK_CHAR label[32])
{
- CK_RV error = CKR_OK;
+ CK_RV error = CKR_OK;
#ifdef NSSDEBUG
- if( (CK_CHAR_PTR)NULL == label ) {
- return CKR_ARGUMENTS_BAD;
- }
+ if ((CK_CHAR_PTR)NULL == label) {
+ return CKR_ARGUMENTS_BAD;
+ }
- error = nssCKFWToken_verifyPointer(fwToken);
- if( CKR_OK != error ) {
- return error;
- }
+ error = nssCKFWToken_verifyPointer(fwToken);
+ if (CKR_OK != error) {
+ return error;
+ }
#endif /* NSSDEBUG */
- error = nssCKFWMutex_Lock(fwToken->mutex);
- if( CKR_OK != error ) {
- return error;
- }
+ 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 *) "";
+ 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;
+ (void)nssUTF8_CopyIntoFixedBuffer(fwToken->label, (char *)label, 32, ' ');
+ error = CKR_OK;
- done:
- (void)nssCKFWMutex_Unlock(fwToken->mutex);
- return error;
+done:
+ (void)nssCKFWMutex_Unlock(fwToken->mutex);
+ return error;
}
/*
@@ -596,48 +568,46 @@ nssCKFWToken_GetLabel
*
*/
NSS_IMPLEMENT CK_RV
-nssCKFWToken_GetManufacturerID
-(
- NSSCKFWToken *fwToken,
- CK_CHAR manufacturerID[32]
-)
+nssCKFWToken_GetManufacturerID(
+ NSSCKFWToken *fwToken,
+ CK_CHAR manufacturerID[32])
{
- CK_RV error = CKR_OK;
+ CK_RV error = CKR_OK;
#ifdef NSSDEBUG
- if( (CK_CHAR_PTR)NULL == manufacturerID ) {
- return CKR_ARGUMENTS_BAD;
- }
+ if ((CK_CHAR_PTR)NULL == manufacturerID) {
+ return CKR_ARGUMENTS_BAD;
+ }
- error = nssCKFWToken_verifyPointer(fwToken);
- if( CKR_OK != error ) {
- return error;
- }
+ error = nssCKFWToken_verifyPointer(fwToken);
+ if (CKR_OK != error) {
+ return error;
+ }
#endif /* NSSDEBUG */
- error = nssCKFWMutex_Lock(fwToken->mutex);
- if( CKR_OK != error ) {
- return error;
- }
+ 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 *)"";
+ 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;
+ (void)nssUTF8_CopyIntoFixedBuffer(fwToken->manufacturerID, (char *)manufacturerID, 32, ' ');
+ error = CKR_OK;
- done:
- (void)nssCKFWMutex_Unlock(fwToken->mutex);
- return error;
+done:
+ (void)nssCKFWMutex_Unlock(fwToken->mutex);
+ return error;
}
/*
@@ -645,48 +615,46 @@ nssCKFWToken_GetManufacturerID
*
*/
NSS_IMPLEMENT CK_RV
-nssCKFWToken_GetModel
-(
- NSSCKFWToken *fwToken,
- CK_CHAR model[16]
-)
+nssCKFWToken_GetModel(
+ NSSCKFWToken *fwToken,
+ CK_CHAR model[16])
{
- CK_RV error = CKR_OK;
+ CK_RV error = CKR_OK;
#ifdef NSSDEBUG
- if( (CK_CHAR_PTR)NULL == model ) {
- return CKR_ARGUMENTS_BAD;
- }
+ if ((CK_CHAR_PTR)NULL == model) {
+ return CKR_ARGUMENTS_BAD;
+ }
- error = nssCKFWToken_verifyPointer(fwToken);
- if( CKR_OK != error ) {
- return error;
- }
+ error = nssCKFWToken_verifyPointer(fwToken);
+ if (CKR_OK != error) {
+ return error;
+ }
#endif /* NSSDEBUG */
- error = nssCKFWMutex_Lock(fwToken->mutex);
- if( CKR_OK != error ) {
- return error;
- }
+ 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 *)"";
+ 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;
+ (void)nssUTF8_CopyIntoFixedBuffer(fwToken->model, (char *)model, 16, ' ');
+ error = CKR_OK;
- done:
- (void)nssCKFWMutex_Unlock(fwToken->mutex);
- return error;
+done:
+ (void)nssCKFWMutex_Unlock(fwToken->mutex);
+ return error;
}
/*
@@ -694,73 +662,68 @@ nssCKFWToken_GetModel
*
*/
NSS_IMPLEMENT CK_RV
-nssCKFWToken_GetSerialNumber
-(
- NSSCKFWToken *fwToken,
- CK_CHAR serialNumber[16]
-)
+nssCKFWToken_GetSerialNumber(
+ NSSCKFWToken *fwToken,
+ CK_CHAR serialNumber[16])
{
- CK_RV error = CKR_OK;
+ CK_RV error = CKR_OK;
#ifdef NSSDEBUG
- if( (CK_CHAR_PTR)NULL == serialNumber ) {
- return CKR_ARGUMENTS_BAD;
- }
+ if ((CK_CHAR_PTR)NULL == serialNumber) {
+ return CKR_ARGUMENTS_BAD;
+ }
- error = nssCKFWToken_verifyPointer(fwToken);
- if( CKR_OK != error ) {
- return error;
- }
+ error = nssCKFWToken_verifyPointer(fwToken);
+ if (CKR_OK != error) {
+ return error;
+ }
#endif /* NSSDEBUG */
- error = nssCKFWMutex_Lock(fwToken->mutex);
- if( CKR_OK != error ) {
- return error;
- }
+ 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 *)"";
+ 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;
+ (void)nssUTF8_CopyIntoFixedBuffer(fwToken->serialNumber, (char *)serialNumber, 16, ' ');
+ error = CKR_OK;
- done:
- (void)nssCKFWMutex_Unlock(fwToken->mutex);
- return error;
+done:
+ (void)nssCKFWMutex_Unlock(fwToken->mutex);
+ return error;
}
-
/*
* nssCKFWToken_GetHasRNG
*
*/
NSS_IMPLEMENT CK_BBOOL
-nssCKFWToken_GetHasRNG
-(
- NSSCKFWToken *fwToken
-)
+nssCKFWToken_GetHasRNG(
+ NSSCKFWToken *fwToken)
{
#ifdef NSSDEBUG
- if( CKR_OK != nssCKFWToken_verifyPointer(fwToken) ) {
- return CK_FALSE;
- }
+ if (CKR_OK != nssCKFWToken_verifyPointer(fwToken)) {
+ return CK_FALSE;
+ }
#endif /* NSSDEBUG */
- if (!fwToken->mdToken->GetHasRNG) {
- return CK_FALSE;
- }
+ if (!fwToken->mdToken->GetHasRNG) {
+ return CK_FALSE;
+ }
- return fwToken->mdToken->GetHasRNG(fwToken->mdToken, fwToken,
- fwToken->mdInstance, fwToken->fwInstance);
+ return fwToken->mdToken->GetHasRNG(fwToken->mdToken, fwToken,
+ fwToken->mdInstance, fwToken->fwInstance);
}
/*
@@ -768,23 +731,21 @@ nssCKFWToken_GetHasRNG
*
*/
NSS_IMPLEMENT CK_BBOOL
-nssCKFWToken_GetIsWriteProtected
-(
- NSSCKFWToken *fwToken
-)
+nssCKFWToken_GetIsWriteProtected(
+ NSSCKFWToken *fwToken)
{
#ifdef NSSDEBUG
- if( CKR_OK != nssCKFWToken_verifyPointer(fwToken) ) {
- return CK_FALSE;
- }
+ if (CKR_OK != nssCKFWToken_verifyPointer(fwToken)) {
+ return CK_FALSE;
+ }
#endif /* NSSDEBUG */
- if (!fwToken->mdToken->GetIsWriteProtected) {
- return CK_FALSE;
- }
+ if (!fwToken->mdToken->GetIsWriteProtected) {
+ return CK_FALSE;
+ }
- return fwToken->mdToken->GetIsWriteProtected(fwToken->mdToken, fwToken,
- fwToken->mdInstance, fwToken->fwInstance);
+ return fwToken->mdToken->GetIsWriteProtected(fwToken->mdToken, fwToken,
+ fwToken->mdInstance, fwToken->fwInstance);
}
/*
@@ -792,23 +753,21 @@ nssCKFWToken_GetIsWriteProtected
*
*/
NSS_IMPLEMENT CK_BBOOL
-nssCKFWToken_GetLoginRequired
-(
- NSSCKFWToken *fwToken
-)
+nssCKFWToken_GetLoginRequired(
+ NSSCKFWToken *fwToken)
{
#ifdef NSSDEBUG
- if( CKR_OK != nssCKFWToken_verifyPointer(fwToken) ) {
- return CK_FALSE;
- }
+ if (CKR_OK != nssCKFWToken_verifyPointer(fwToken)) {
+ return CK_FALSE;
+ }
#endif /* NSSDEBUG */
- if (!fwToken->mdToken->GetLoginRequired) {
- return CK_FALSE;
- }
+ if (!fwToken->mdToken->GetLoginRequired) {
+ return CK_FALSE;
+ }
- return fwToken->mdToken->GetLoginRequired(fwToken->mdToken, fwToken,
- fwToken->mdInstance, fwToken->fwInstance);
+ return fwToken->mdToken->GetLoginRequired(fwToken->mdToken, fwToken,
+ fwToken->mdInstance, fwToken->fwInstance);
}
/*
@@ -816,23 +775,21 @@ nssCKFWToken_GetLoginRequired
*
*/
NSS_IMPLEMENT CK_BBOOL
-nssCKFWToken_GetUserPinInitialized
-(
- NSSCKFWToken *fwToken
-)
+nssCKFWToken_GetUserPinInitialized(
+ NSSCKFWToken *fwToken)
{
#ifdef NSSDEBUG
- if( CKR_OK != nssCKFWToken_verifyPointer(fwToken) ) {
- return CK_FALSE;
- }
+ if (CKR_OK != nssCKFWToken_verifyPointer(fwToken)) {
+ return CK_FALSE;
+ }
#endif /* NSSDEBUG */
- if (!fwToken->mdToken->GetUserPinInitialized) {
- return CK_FALSE;
- }
+ if (!fwToken->mdToken->GetUserPinInitialized) {
+ return CK_FALSE;
+ }
- return fwToken->mdToken->GetUserPinInitialized(fwToken->mdToken, fwToken,
- fwToken->mdInstance, fwToken->fwInstance);
+ return fwToken->mdToken->GetUserPinInitialized(fwToken->mdToken, fwToken,
+ fwToken->mdInstance, fwToken->fwInstance);
}
/*
@@ -840,23 +797,21 @@ nssCKFWToken_GetUserPinInitialized
*
*/
NSS_IMPLEMENT CK_BBOOL
-nssCKFWToken_GetRestoreKeyNotNeeded
-(
- NSSCKFWToken *fwToken
-)
+nssCKFWToken_GetRestoreKeyNotNeeded(
+ NSSCKFWToken *fwToken)
{
#ifdef NSSDEBUG
- if( CKR_OK != nssCKFWToken_verifyPointer(fwToken) ) {
- return CK_FALSE;
- }
+ if (CKR_OK != nssCKFWToken_verifyPointer(fwToken)) {
+ return CK_FALSE;
+ }
#endif /* NSSDEBUG */
- if (!fwToken->mdToken->GetRestoreKeyNotNeeded) {
- return CK_FALSE;
- }
+ if (!fwToken->mdToken->GetRestoreKeyNotNeeded) {
+ return CK_FALSE;
+ }
- return fwToken->mdToken->GetRestoreKeyNotNeeded(fwToken->mdToken, fwToken,
- fwToken->mdInstance, fwToken->fwInstance);
+ return fwToken->mdToken->GetRestoreKeyNotNeeded(fwToken->mdToken, fwToken,
+ fwToken->mdInstance, fwToken->fwInstance);
}
/*
@@ -864,23 +819,21 @@ nssCKFWToken_GetRestoreKeyNotNeeded
*
*/
NSS_IMPLEMENT CK_BBOOL
-nssCKFWToken_GetHasClockOnToken
-(
- NSSCKFWToken *fwToken
-)
+nssCKFWToken_GetHasClockOnToken(
+ NSSCKFWToken *fwToken)
{
#ifdef NSSDEBUG
- if( CKR_OK != nssCKFWToken_verifyPointer(fwToken) ) {
- return CK_FALSE;
- }
+ if (CKR_OK != nssCKFWToken_verifyPointer(fwToken)) {
+ return CK_FALSE;
+ }
#endif /* NSSDEBUG */
- if (!fwToken->mdToken->GetHasClockOnToken) {
- return CK_FALSE;
- }
+ if (!fwToken->mdToken->GetHasClockOnToken) {
+ return CK_FALSE;
+ }
- return fwToken->mdToken->GetHasClockOnToken(fwToken->mdToken, fwToken,
- fwToken->mdInstance, fwToken->fwInstance);
+ return fwToken->mdToken->GetHasClockOnToken(fwToken->mdToken, fwToken,
+ fwToken->mdInstance, fwToken->fwInstance);
}
/*
@@ -888,23 +841,21 @@ nssCKFWToken_GetHasClockOnToken
*
*/
NSS_IMPLEMENT CK_BBOOL
-nssCKFWToken_GetHasProtectedAuthenticationPath
-(
- NSSCKFWToken *fwToken
-)
+nssCKFWToken_GetHasProtectedAuthenticationPath(
+ NSSCKFWToken *fwToken)
{
#ifdef NSSDEBUG
- if( CKR_OK != nssCKFWToken_verifyPointer(fwToken) ) {
- return CK_FALSE;
- }
+ if (CKR_OK != nssCKFWToken_verifyPointer(fwToken)) {
+ return CK_FALSE;
+ }
#endif /* NSSDEBUG */
- if (!fwToken->mdToken->GetHasProtectedAuthenticationPath) {
- return CK_FALSE;
- }
+ if (!fwToken->mdToken->GetHasProtectedAuthenticationPath) {
+ return CK_FALSE;
+ }
- return fwToken->mdToken->GetHasProtectedAuthenticationPath(fwToken->mdToken,
- fwToken, fwToken->mdInstance, fwToken->fwInstance);
+ return fwToken->mdToken->GetHasProtectedAuthenticationPath(fwToken->mdToken,
+ fwToken, fwToken->mdInstance, fwToken->fwInstance);
}
/*
@@ -912,23 +863,21 @@ nssCKFWToken_GetHasProtectedAuthenticationPath
*
*/
NSS_IMPLEMENT CK_BBOOL
-nssCKFWToken_GetSupportsDualCryptoOperations
-(
- NSSCKFWToken *fwToken
-)
+nssCKFWToken_GetSupportsDualCryptoOperations(
+ NSSCKFWToken *fwToken)
{
#ifdef NSSDEBUG
- if( CKR_OK != nssCKFWToken_verifyPointer(fwToken) ) {
- return CK_FALSE;
- }
+ if (CKR_OK != nssCKFWToken_verifyPointer(fwToken)) {
+ return CK_FALSE;
+ }
#endif /* NSSDEBUG */
- if (!fwToken->mdToken->GetSupportsDualCryptoOperations) {
- return CK_FALSE;
- }
+ if (!fwToken->mdToken->GetSupportsDualCryptoOperations) {
+ return CK_FALSE;
+ }
- return fwToken->mdToken->GetSupportsDualCryptoOperations(fwToken->mdToken,
- fwToken, fwToken->mdInstance, fwToken->fwInstance);
+ return fwToken->mdToken->GetSupportsDualCryptoOperations(fwToken->mdToken,
+ fwToken, fwToken->mdInstance, fwToken->fwInstance);
}
/*
@@ -936,23 +885,21 @@ nssCKFWToken_GetSupportsDualCryptoOperations
*
*/
NSS_IMPLEMENT CK_ULONG
-nssCKFWToken_GetMaxSessionCount
-(
- NSSCKFWToken *fwToken
-)
+nssCKFWToken_GetMaxSessionCount(
+ NSSCKFWToken *fwToken)
{
#ifdef NSSDEBUG
- if( CKR_OK != nssCKFWToken_verifyPointer(fwToken) ) {
- return CK_UNAVAILABLE_INFORMATION;
- }
+ if (CKR_OK != nssCKFWToken_verifyPointer(fwToken)) {
+ return CK_UNAVAILABLE_INFORMATION;
+ }
#endif /* NSSDEBUG */
- if (!fwToken->mdToken->GetMaxSessionCount) {
- return CK_UNAVAILABLE_INFORMATION;
- }
+ if (!fwToken->mdToken->GetMaxSessionCount) {
+ return CK_UNAVAILABLE_INFORMATION;
+ }
- return fwToken->mdToken->GetMaxSessionCount(fwToken->mdToken, fwToken,
- fwToken->mdInstance, fwToken->fwInstance);
+ return fwToken->mdToken->GetMaxSessionCount(fwToken->mdToken, fwToken,
+ fwToken->mdInstance, fwToken->fwInstance);
}
/*
@@ -960,23 +907,21 @@ nssCKFWToken_GetMaxSessionCount
*
*/
NSS_IMPLEMENT CK_ULONG
-nssCKFWToken_GetMaxRwSessionCount
-(
- NSSCKFWToken *fwToken
-)
+nssCKFWToken_GetMaxRwSessionCount(
+ NSSCKFWToken *fwToken)
{
#ifdef NSSDEBUG
- if( CKR_OK != nssCKFWToken_verifyPointer(fwToken) ) {
- return CK_UNAVAILABLE_INFORMATION;
- }
+ if (CKR_OK != nssCKFWToken_verifyPointer(fwToken)) {
+ return CK_UNAVAILABLE_INFORMATION;
+ }
#endif /* NSSDEBUG */
- if (!fwToken->mdToken->GetMaxRwSessionCount) {
- return CK_UNAVAILABLE_INFORMATION;
- }
+ if (!fwToken->mdToken->GetMaxRwSessionCount) {
+ return CK_UNAVAILABLE_INFORMATION;
+ }
- return fwToken->mdToken->GetMaxRwSessionCount(fwToken->mdToken, fwToken,
- fwToken->mdInstance, fwToken->fwInstance);
+ return fwToken->mdToken->GetMaxRwSessionCount(fwToken->mdToken, fwToken,
+ fwToken->mdInstance, fwToken->fwInstance);
}
/*
@@ -984,23 +929,21 @@ nssCKFWToken_GetMaxRwSessionCount
*
*/
NSS_IMPLEMENT CK_ULONG
-nssCKFWToken_GetMaxPinLen
-(
- NSSCKFWToken *fwToken
-)
+nssCKFWToken_GetMaxPinLen(
+ NSSCKFWToken *fwToken)
{
#ifdef NSSDEBUG
- if( CKR_OK != nssCKFWToken_verifyPointer(fwToken) ) {
- return CK_UNAVAILABLE_INFORMATION;
- }
+ if (CKR_OK != nssCKFWToken_verifyPointer(fwToken)) {
+ return CK_UNAVAILABLE_INFORMATION;
+ }
#endif /* NSSDEBUG */
- if (!fwToken->mdToken->GetMaxPinLen) {
- return CK_UNAVAILABLE_INFORMATION;
- }
+ if (!fwToken->mdToken->GetMaxPinLen) {
+ return CK_UNAVAILABLE_INFORMATION;
+ }
- return fwToken->mdToken->GetMaxPinLen(fwToken->mdToken, fwToken,
- fwToken->mdInstance, fwToken->fwInstance);
+ return fwToken->mdToken->GetMaxPinLen(fwToken->mdToken, fwToken,
+ fwToken->mdInstance, fwToken->fwInstance);
}
/*
@@ -1008,23 +951,21 @@ nssCKFWToken_GetMaxPinLen
*
*/
NSS_IMPLEMENT CK_ULONG
-nssCKFWToken_GetMinPinLen
-(
- NSSCKFWToken *fwToken
-)
+nssCKFWToken_GetMinPinLen(
+ NSSCKFWToken *fwToken)
{
#ifdef NSSDEBUG
- if( CKR_OK != nssCKFWToken_verifyPointer(fwToken) ) {
- return CK_UNAVAILABLE_INFORMATION;
- }
+ if (CKR_OK != nssCKFWToken_verifyPointer(fwToken)) {
+ return CK_UNAVAILABLE_INFORMATION;
+ }
#endif /* NSSDEBUG */
- if (!fwToken->mdToken->GetMinPinLen) {
- return CK_UNAVAILABLE_INFORMATION;
- }
+ if (!fwToken->mdToken->GetMinPinLen) {
+ return CK_UNAVAILABLE_INFORMATION;
+ }
- return fwToken->mdToken->GetMinPinLen(fwToken->mdToken, fwToken,
- fwToken->mdInstance, fwToken->fwInstance);
+ return fwToken->mdToken->GetMinPinLen(fwToken->mdToken, fwToken,
+ fwToken->mdInstance, fwToken->fwInstance);
}
/*
@@ -1032,23 +973,21 @@ nssCKFWToken_GetMinPinLen
*
*/
NSS_IMPLEMENT CK_ULONG
-nssCKFWToken_GetTotalPublicMemory
-(
- NSSCKFWToken *fwToken
-)
+nssCKFWToken_GetTotalPublicMemory(
+ NSSCKFWToken *fwToken)
{
#ifdef NSSDEBUG
- if( CKR_OK != nssCKFWToken_verifyPointer(fwToken) ) {
- return CK_UNAVAILABLE_INFORMATION;
- }
+ if (CKR_OK != nssCKFWToken_verifyPointer(fwToken)) {
+ return CK_UNAVAILABLE_INFORMATION;
+ }
#endif /* NSSDEBUG */
- if (!fwToken->mdToken->GetTotalPublicMemory) {
- return CK_UNAVAILABLE_INFORMATION;
- }
+ if (!fwToken->mdToken->GetTotalPublicMemory) {
+ return CK_UNAVAILABLE_INFORMATION;
+ }
- return fwToken->mdToken->GetTotalPublicMemory(fwToken->mdToken, fwToken,
- fwToken->mdInstance, fwToken->fwInstance);
+ return fwToken->mdToken->GetTotalPublicMemory(fwToken->mdToken, fwToken,
+ fwToken->mdInstance, fwToken->fwInstance);
}
/*
@@ -1056,23 +995,21 @@ nssCKFWToken_GetTotalPublicMemory
*
*/
NSS_IMPLEMENT CK_ULONG
-nssCKFWToken_GetFreePublicMemory
-(
- NSSCKFWToken *fwToken
-)
+nssCKFWToken_GetFreePublicMemory(
+ NSSCKFWToken *fwToken)
{
#ifdef NSSDEBUG
- if( CKR_OK != nssCKFWToken_verifyPointer(fwToken) ) {
- return CK_UNAVAILABLE_INFORMATION;
- }
+ if (CKR_OK != nssCKFWToken_verifyPointer(fwToken)) {
+ return CK_UNAVAILABLE_INFORMATION;
+ }
#endif /* NSSDEBUG */
- if (!fwToken->mdToken->GetFreePublicMemory) {
- return CK_UNAVAILABLE_INFORMATION;
- }
+ if (!fwToken->mdToken->GetFreePublicMemory) {
+ return CK_UNAVAILABLE_INFORMATION;
+ }
- return fwToken->mdToken->GetFreePublicMemory(fwToken->mdToken, fwToken,
- fwToken->mdInstance, fwToken->fwInstance);
+ return fwToken->mdToken->GetFreePublicMemory(fwToken->mdToken, fwToken,
+ fwToken->mdInstance, fwToken->fwInstance);
}
/*
@@ -1080,23 +1017,21 @@ nssCKFWToken_GetFreePublicMemory
*
*/
NSS_IMPLEMENT CK_ULONG
-nssCKFWToken_GetTotalPrivateMemory
-(
- NSSCKFWToken *fwToken
-)
+nssCKFWToken_GetTotalPrivateMemory(
+ NSSCKFWToken *fwToken)
{
#ifdef NSSDEBUG
- if( CKR_OK != nssCKFWToken_verifyPointer(fwToken) ) {
- return CK_UNAVAILABLE_INFORMATION;
- }
+ if (CKR_OK != nssCKFWToken_verifyPointer(fwToken)) {
+ return CK_UNAVAILABLE_INFORMATION;
+ }
#endif /* NSSDEBUG */
- if (!fwToken->mdToken->GetTotalPrivateMemory) {
- return CK_UNAVAILABLE_INFORMATION;
- }
+ if (!fwToken->mdToken->GetTotalPrivateMemory) {
+ return CK_UNAVAILABLE_INFORMATION;
+ }
- return fwToken->mdToken->GetTotalPrivateMemory(fwToken->mdToken, fwToken,
- fwToken->mdInstance, fwToken->fwInstance);
+ return fwToken->mdToken->GetTotalPrivateMemory(fwToken->mdToken, fwToken,
+ fwToken->mdInstance, fwToken->fwInstance);
}
/*
@@ -1104,23 +1039,21 @@ nssCKFWToken_GetTotalPrivateMemory
*
*/
NSS_IMPLEMENT CK_ULONG
-nssCKFWToken_GetFreePrivateMemory
-(
- NSSCKFWToken *fwToken
-)
+nssCKFWToken_GetFreePrivateMemory(
+ NSSCKFWToken *fwToken)
{
#ifdef NSSDEBUG
- if( CKR_OK != nssCKFWToken_verifyPointer(fwToken) ) {
- return CK_UNAVAILABLE_INFORMATION;
- }
+ if (CKR_OK != nssCKFWToken_verifyPointer(fwToken)) {
+ return CK_UNAVAILABLE_INFORMATION;
+ }
#endif /* NSSDEBUG */
- if (!fwToken->mdToken->GetFreePrivateMemory) {
- return CK_UNAVAILABLE_INFORMATION;
- }
+ if (!fwToken->mdToken->GetFreePrivateMemory) {
+ return CK_UNAVAILABLE_INFORMATION;
+ }
- return fwToken->mdToken->GetFreePrivateMemory(fwToken->mdToken, fwToken,
- fwToken->mdInstance, fwToken->fwInstance);
+ return fwToken->mdToken->GetFreePrivateMemory(fwToken->mdToken, fwToken,
+ fwToken->mdInstance, fwToken->fwInstance);
}
/*
@@ -1128,44 +1061,42 @@ nssCKFWToken_GetFreePrivateMemory
*
*/
NSS_IMPLEMENT CK_VERSION
-nssCKFWToken_GetHardwareVersion
-(
- NSSCKFWToken *fwToken
-)
+nssCKFWToken_GetHardwareVersion(
+ NSSCKFWToken *fwToken)
{
- CK_VERSION rv;
+ CK_VERSION rv;
#ifdef NSSDEBUG
- if( CKR_OK != nssCKFWToken_verifyPointer(fwToken) ) {
- rv.major = rv.minor = 0;
- return rv;
- }
+ 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 (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;
+ }
- 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;
+
+done:
+ (void)nssCKFWMutex_Unlock(fwToken->mutex);
+ return rv;
}
/*
@@ -1173,44 +1104,42 @@ nssCKFWToken_GetHardwareVersion
*
*/
NSS_IMPLEMENT CK_VERSION
-nssCKFWToken_GetFirmwareVersion
-(
- NSSCKFWToken *fwToken
-)
+nssCKFWToken_GetFirmwareVersion(
+ NSSCKFWToken *fwToken)
{
- CK_VERSION rv;
+ CK_VERSION rv;
#ifdef NSSDEBUG
- if( CKR_OK != nssCKFWToken_verifyPointer(fwToken) ) {
- rv.major = rv.minor = 0;
- return rv;
- }
+ 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 (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;
+ }
- 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;
+
+done:
+ (void)nssCKFWMutex_Unlock(fwToken->mutex);
+ return rv;
}
/*
@@ -1218,86 +1147,95 @@ nssCKFWToken_GetFirmwareVersion
*
*/
NSS_IMPLEMENT CK_RV
-nssCKFWToken_GetUTCTime
-(
- NSSCKFWToken *fwToken,
- CK_CHAR utcTime[16]
-)
+nssCKFWToken_GetUTCTime(
+ NSSCKFWToken *fwToken,
+ CK_CHAR utcTime[16])
{
- CK_RV error = CKR_OK;
+ CK_RV error = CKR_OK;
#ifdef NSSDEBUG
- error = nssCKFWToken_verifyPointer(fwToken);
- if( CKR_OK != error ) {
- return error;
- }
+ error = nssCKFWToken_verifyPointer(fwToken);
+ if (CKR_OK != error) {
+ return error;
+ }
- if( (CK_CHAR_PTR)NULL == utcTime ) {
- return CKR_ARGUMENTS_BAD;
- }
+ 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;
- 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;
- }
+ if (CK_TRUE != nssCKFWToken_GetHasClockOnToken(fwToken)) {
+ /* return CKR_DEVICE_ERROR; */
+ (void)nssUTF8_CopyIntoFixedBuffer((NSSUTF8 *)NULL, (char *)utcTime, 16, ' ');
+ return CKR_OK;
}
- 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');
-
- 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 (!fwToken->mdToken->GetUTCTime) {
+ /* It said it had one! */
+ return CKR_GENERAL_ERROR;
+ }
- if( (h < 0) || (h > 23) ) goto badtime;
- if( (m < 0) || (m > 60) ) goto badtime;
- if( (s < 0) || (s > 61) ) goto badtime;
+ error = fwToken->mdToken->GetUTCTime(fwToken->mdToken, fwToken,
+ fwToken->mdInstance, fwToken->fwInstance, utcTime);
+ if (CKR_OK != error) {
+ return error;
+ }
- /* 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; */
+ /* Sanity-check the data */
+ {
+ /* Format is YYYYMMDDhhmmss00 */
+ int i;
+ int Y, M, D, h, m, s;
+ 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');
+
+ 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;
+ return CKR_OK;
- badtime:
- return CKR_GENERAL_ERROR;
+badtime:
+ return CKR_GENERAL_ERROR;
}
/*
@@ -1305,108 +1243,106 @@ nssCKFWToken_GetUTCTime
*
*/
NSS_IMPLEMENT NSSCKFWSession *
-nssCKFWToken_OpenSession
-(
- NSSCKFWToken *fwToken,
- CK_BBOOL rw,
- CK_VOID_PTR pApplication,
- CK_NOTIFY Notify,
- CK_RV *pError
-)
+nssCKFWToken_OpenSession(
+ NSSCKFWToken *fwToken,
+ CK_BBOOL rw,
+ CK_VOID_PTR pApplication,
+ CK_NOTIFY Notify,
+ CK_RV *pError)
{
- NSSCKFWSession *fwSession = (NSSCKFWSession *)NULL;
- NSSCKMDSession *mdSession;
+ 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;
- }
+ 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;
- }
+ *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;
+ 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;
+ }
}
- } 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;
}
- }
- /* We could compare sesion counts to any limits we know of, I guess.. */
+ fwSession = nssCKFWSession_Create(fwToken, rw, pApplication, Notify, pError);
+ if (!fwSession) {
+ if (CKR_OK == *pError) {
+ *pError = CKR_GENERAL_ERROR;
+ }
+ goto done;
+ }
- 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;
+ 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;
}
- 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);
+ *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;
}
- (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;
- }
+ *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;
+done:
+ (void)nssCKFWMutex_Unlock(fwToken->mutex);
+ return fwSession;
}
/*
@@ -1414,23 +1350,21 @@ nssCKFWToken_OpenSession
*
*/
NSS_IMPLEMENT CK_ULONG
-nssCKFWToken_GetMechanismCount
-(
- NSSCKFWToken *fwToken
-)
+nssCKFWToken_GetMechanismCount(
+ NSSCKFWToken *fwToken)
{
#ifdef NSSDEBUG
- if( CKR_OK != nssCKFWToken_verifyPointer(fwToken) ) {
- return 0;
- }
+ if (CKR_OK != nssCKFWToken_verifyPointer(fwToken)) {
+ return 0;
+ }
#endif /* NSSDEBUG */
- if (!fwToken->mdToken->GetMechanismCount) {
- return 0;
- }
+ if (!fwToken->mdToken->GetMechanismCount) {
+ return 0;
+ }
- return fwToken->mdToken->GetMechanismCount(fwToken->mdToken, fwToken,
- fwToken->mdInstance, fwToken->fwInstance);
+ return fwToken->mdToken->GetMechanismCount(fwToken->mdToken, fwToken,
+ fwToken->mdInstance, fwToken->fwInstance);
}
/*
@@ -1438,110 +1372,103 @@ nssCKFWToken_GetMechanismCount
*
*/
NSS_IMPLEMENT CK_RV
-nssCKFWToken_GetMechanismTypes
-(
- NSSCKFWToken *fwToken,
- CK_MECHANISM_TYPE types[]
-)
+nssCKFWToken_GetMechanismTypes(
+ NSSCKFWToken *fwToken,
+ CK_MECHANISM_TYPE types[])
{
#ifdef NSSDEBUG
- if( CKR_OK != nssCKFWToken_verifyPointer(fwToken) ) {
- return CKR_ARGUMENTS_BAD;
- }
+ if (CKR_OK != nssCKFWToken_verifyPointer(fwToken)) {
+ return CKR_ARGUMENTS_BAD;
+ }
- if (!types) {
- 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;
- }
+ 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);
+ 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
-)
+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);
+ 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
-)
+nssCKFWToken_SetSessionState(
+ NSSCKFWToken *fwToken,
+ CK_STATE newState)
{
- CK_RV error = CKR_OK;
+ 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;
- }
+ 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;
- }
+ error = nssCKFWMutex_Lock(fwToken->mutex);
+ if (CKR_OK != error) {
+ return error;
+ }
- fwToken->state = newState;
- (void)nssCKFWMutex_Unlock(fwToken->mutex);
- return CKR_OK;
+ fwToken->state = newState;
+ (void)nssCKFWMutex_Unlock(fwToken->mutex);
+ return CKR_OK;
}
/*
@@ -1549,101 +1476,96 @@ nssCKFWToken_SetSessionState
*
*/
NSS_IMPLEMENT CK_RV
-nssCKFWToken_RemoveSession
-(
- NSSCKFWToken *fwToken,
- NSSCKFWSession *fwSession
-)
+nssCKFWToken_RemoveSession(
+ NSSCKFWToken *fwToken,
+ NSSCKFWSession *fwSession)
{
- CK_RV error = CKR_OK;
+ CK_RV error = CKR_OK;
#ifdef NSSDEBUG
- error = nssCKFWToken_verifyPointer(fwToken);
- if( CKR_OK != error ) {
- return error;
- }
+ error = nssCKFWToken_verifyPointer(fwToken);
+ if (CKR_OK != error) {
+ return error;
+ }
- error = nssCKFWSession_verifyPointer(fwSession);
- 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;
- }
+ 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;
- }
+ if (CK_TRUE != nssCKFWHash_Exists(fwToken->sessions, fwSession)) {
+ error = CKR_SESSION_HANDLE_INVALID;
+ goto done;
+ }
- nssCKFWHash_Remove(fwToken->sessions, fwSession);
- fwToken->sessionCount--;
+ nssCKFWHash_Remove(fwToken->sessions, fwSession);
+ fwToken->sessionCount--;
- if( nssCKFWSession_IsRWSession(fwSession) ) {
- fwToken->rwSessionCount--;
- }
+ if (nssCKFWSession_IsRWSession(fwSession)) {
+ fwToken->rwSessionCount--;
+ }
- if( 0 == fwToken->sessionCount ) {
- fwToken->rwSessionCount = 0; /* sanity */
- fwToken->state = CKS_RO_PUBLIC_SESSION; /* some default */
- }
+ if (0 == fwToken->sessionCount) {
+ fwToken->rwSessionCount = 0; /* sanity */
+ fwToken->state = CKS_RO_PUBLIC_SESSION; /* some default */
+ }
- error = CKR_OK;
+ error = CKR_OK;
- done:
- (void)nssCKFWMutex_Unlock(fwToken->mutex);
- return error;
+done:
+ (void)nssCKFWMutex_Unlock(fwToken->mutex);
+ return error;
}
-
/*
* nssCKFWToken_CloseAllSessions
*
*/
NSS_IMPLEMENT CK_RV
-nssCKFWToken_CloseAllSessions
-(
- NSSCKFWToken *fwToken
-)
+nssCKFWToken_CloseAllSessions(
+ NSSCKFWToken *fwToken)
{
- CK_RV error = CKR_OK;
+ CK_RV error = CKR_OK;
#ifdef NSSDEBUG
- error = nssCKFWToken_verifyPointer(fwToken);
- if( CKR_OK != error ) {
- return error;
- }
+ error = nssCKFWToken_verifyPointer(fwToken);
+ if (CKR_OK != error) {
+ return error;
+ }
#endif /* NSSDEBUG */
- error = nssCKFWMutex_Lock(fwToken->mutex);
- if( CKR_OK != error ) {
- return error;
- }
+ error = nssCKFWMutex_Lock(fwToken->mutex);
+ if (CKR_OK != error) {
+ return error;
+ }
- nssCKFWHash_Iterate(fwToken->sessions, nss_ckfwtoken_session_iterator, (void *)NULL);
+ nssCKFWHash_Iterate(fwToken->sessions, nss_ckfwtoken_session_iterator, (void *)NULL);
- nssCKFWHash_Destroy(fwToken->sessions);
+ nssCKFWHash_Destroy(fwToken->sessions);
- fwToken->sessions = nssCKFWHash_Create(fwToken->fwInstance, fwToken->arena, &error);
- if (!fwToken->sessions) {
- if( CKR_OK == error ) {
- error = CKR_GENERAL_ERROR;
+ fwToken->sessions = nssCKFWHash_Create(fwToken->fwInstance, fwToken->arena, &error);
+ if (!fwToken->sessions) {
+ if (CKR_OK == error) {
+ error = CKR_GENERAL_ERROR;
+ }
+ goto done;
}
- goto done;
- }
- fwToken->state = CKS_RO_PUBLIC_SESSION; /* some default */
- fwToken->sessionCount = 0;
- fwToken->rwSessionCount = 0;
+ fwToken->state = CKS_RO_PUBLIC_SESSION; /* some default */
+ fwToken->sessionCount = 0;
+ fwToken->rwSessionCount = 0;
- error = CKR_OK;
+ error = CKR_OK;
- done:
- (void)nssCKFWMutex_Unlock(fwToken->mutex);
- return error;
+done:
+ (void)nssCKFWMutex_Unlock(fwToken->mutex);
+ return error;
}
/*
@@ -1651,26 +1573,24 @@ nssCKFWToken_CloseAllSessions
*
*/
NSS_IMPLEMENT CK_ULONG
-nssCKFWToken_GetSessionCount
-(
- NSSCKFWToken *fwToken
-)
+nssCKFWToken_GetSessionCount(
+ NSSCKFWToken *fwToken)
{
- CK_ULONG rv;
+ CK_ULONG rv;
#ifdef NSSDEBUG
- if( CKR_OK != nssCKFWToken_verifyPointer(fwToken) ) {
- return (CK_ULONG)0;
- }
+ if (CKR_OK != nssCKFWToken_verifyPointer(fwToken)) {
+ return (CK_ULONG)0;
+ }
#endif /* NSSDEBUG */
- if( CKR_OK != nssCKFWMutex_Lock(fwToken->mutex) ) {
- return (CK_ULONG)0;
- }
+ if (CKR_OK != nssCKFWMutex_Lock(fwToken->mutex)) {
+ return (CK_ULONG)0;
+ }
- rv = fwToken->sessionCount;
- (void)nssCKFWMutex_Unlock(fwToken->mutex);
- return rv;
+ rv = fwToken->sessionCount;
+ (void)nssCKFWMutex_Unlock(fwToken->mutex);
+ return rv;
}
/*
@@ -1678,26 +1598,24 @@ nssCKFWToken_GetSessionCount
*
*/
NSS_IMPLEMENT CK_ULONG
-nssCKFWToken_GetRwSessionCount
-(
- NSSCKFWToken *fwToken
-)
+nssCKFWToken_GetRwSessionCount(
+ NSSCKFWToken *fwToken)
{
- CK_ULONG rv;
+ CK_ULONG rv;
#ifdef NSSDEBUG
- if( CKR_OK != nssCKFWToken_verifyPointer(fwToken) ) {
- return (CK_ULONG)0;
- }
+ if (CKR_OK != nssCKFWToken_verifyPointer(fwToken)) {
+ return (CK_ULONG)0;
+ }
#endif /* NSSDEBUG */
- if( CKR_OK != nssCKFWMutex_Lock(fwToken->mutex) ) {
- return (CK_ULONG)0;
- }
+ if (CKR_OK != nssCKFWMutex_Lock(fwToken->mutex)) {
+ return (CK_ULONG)0;
+ }
- rv = fwToken->rwSessionCount;
- (void)nssCKFWMutex_Unlock(fwToken->mutex);
- return rv;
+ rv = fwToken->rwSessionCount;
+ (void)nssCKFWMutex_Unlock(fwToken->mutex);
+ return rv;
}
/*
@@ -1705,26 +1623,24 @@ nssCKFWToken_GetRwSessionCount
*
*/
NSS_IMPLEMENT CK_ULONG
-nssCKFWToken_GetRoSessionCount
-(
- NSSCKFWToken *fwToken
-)
+nssCKFWToken_GetRoSessionCount(
+ NSSCKFWToken *fwToken)
{
- CK_ULONG rv;
+ CK_ULONG rv;
#ifdef NSSDEBUG
- if( CKR_OK != nssCKFWToken_verifyPointer(fwToken) ) {
- return (CK_ULONG)0;
- }
+ if (CKR_OK != nssCKFWToken_verifyPointer(fwToken)) {
+ return (CK_ULONG)0;
+ }
#endif /* NSSDEBUG */
- if( CKR_OK != nssCKFWMutex_Lock(fwToken->mutex) ) {
- return (CK_ULONG)0;
- }
+ if (CKR_OK != nssCKFWMutex_Lock(fwToken->mutex)) {
+ return (CK_ULONG)0;
+ }
- rv = fwToken->sessionCount - fwToken->rwSessionCount;
- (void)nssCKFWMutex_Unlock(fwToken->mutex);
- return rv;
+ rv = fwToken->sessionCount - fwToken->rwSessionCount;
+ (void)nssCKFWMutex_Unlock(fwToken->mutex);
+ return rv;
}
/*
@@ -1732,18 +1648,16 @@ nssCKFWToken_GetRoSessionCount
*
*/
NSS_IMPLEMENT nssCKFWHash *
-nssCKFWToken_GetSessionObjectHash
-(
- NSSCKFWToken *fwToken
-)
+nssCKFWToken_GetSessionObjectHash(
+ NSSCKFWToken *fwToken)
{
#ifdef NSSDEBUG
- if( CKR_OK != nssCKFWToken_verifyPointer(fwToken) ) {
- return (nssCKFWHash *)NULL;
- }
+ if (CKR_OK != nssCKFWToken_verifyPointer(fwToken)) {
+ return (nssCKFWHash *)NULL;
+ }
#endif /* NSSDEBUG */
- return fwToken->sessionObjectHash;
+ return fwToken->sessionObjectHash;
}
/*
@@ -1751,18 +1665,16 @@ nssCKFWToken_GetSessionObjectHash
*
*/
NSS_IMPLEMENT nssCKFWHash *
-nssCKFWToken_GetMDObjectHash
-(
- NSSCKFWToken *fwToken
-)
+nssCKFWToken_GetMDObjectHash(
+ NSSCKFWToken *fwToken)
{
#ifdef NSSDEBUG
- if( CKR_OK != nssCKFWToken_verifyPointer(fwToken) ) {
- return (nssCKFWHash *)NULL;
- }
+ if (CKR_OK != nssCKFWToken_verifyPointer(fwToken)) {
+ return (nssCKFWHash *)NULL;
+ }
#endif /* NSSDEBUG */
- return fwToken->mdObjectHash;
+ return fwToken->mdObjectHash;
}
/*
@@ -1770,18 +1682,16 @@ nssCKFWToken_GetMDObjectHash
*
*/
NSS_IMPLEMENT nssCKFWHash *
-nssCKFWToken_GetObjectHandleHash
-(
- NSSCKFWToken *fwToken
-)
+nssCKFWToken_GetObjectHandleHash(
+ NSSCKFWToken *fwToken)
{
#ifdef NSSDEBUG
- if( CKR_OK != nssCKFWToken_verifyPointer(fwToken) ) {
- return (nssCKFWHash *)NULL;
- }
+ if (CKR_OK != nssCKFWToken_verifyPointer(fwToken)) {
+ return (nssCKFWHash *)NULL;
+ }
#endif /* NSSDEBUG */
- return fwToken->mdObjectHash;
+ return fwToken->mdObjectHash;
}
/*
@@ -1790,18 +1700,16 @@ nssCKFWToken_GetObjectHandleHash
*/
NSS_IMPLEMENT NSSCKMDToken *
-NSSCKFWToken_GetMDToken
-(
- NSSCKFWToken *fwToken
-)
+NSSCKFWToken_GetMDToken(
+ NSSCKFWToken *fwToken)
{
#ifdef DEBUG
- if( CKR_OK != nssCKFWToken_verifyPointer(fwToken) ) {
- return (NSSCKMDToken *)NULL;
- }
+ if (CKR_OK != nssCKFWToken_verifyPointer(fwToken)) {
+ return (NSSCKMDToken *)NULL;
+ }
#endif /* DEBUG */
- return nssCKFWToken_GetMDToken(fwToken);
+ return nssCKFWToken_GetMDToken(fwToken);
}
/*
@@ -1810,24 +1718,22 @@ NSSCKFWToken_GetMDToken
*/
NSS_IMPLEMENT NSSArena *
-NSSCKFWToken_GetArena
-(
- NSSCKFWToken *fwToken,
- CK_RV *pError
-)
+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;
- }
+ 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);
+ return nssCKFWToken_GetArena(fwToken, pError);
}
/*
@@ -1836,18 +1742,16 @@ NSSCKFWToken_GetArena
*/
NSS_IMPLEMENT NSSCKFWSlot *
-NSSCKFWToken_GetFWSlot
-(
- NSSCKFWToken *fwToken
-)
+NSSCKFWToken_GetFWSlot(
+ NSSCKFWToken *fwToken)
{
#ifdef DEBUG
- if( CKR_OK != nssCKFWToken_verifyPointer(fwToken) ) {
- return (NSSCKFWSlot *)NULL;
- }
+ if (CKR_OK != nssCKFWToken_verifyPointer(fwToken)) {
+ return (NSSCKFWSlot *)NULL;
+ }
#endif /* DEBUG */
- return nssCKFWToken_GetFWSlot(fwToken);
+ return nssCKFWToken_GetFWSlot(fwToken);
}
/*
@@ -1856,18 +1760,16 @@ NSSCKFWToken_GetFWSlot
*/
NSS_IMPLEMENT NSSCKMDSlot *
-NSSCKFWToken_GetMDSlot
-(
- NSSCKFWToken *fwToken
-)
+NSSCKFWToken_GetMDSlot(
+ NSSCKFWToken *fwToken)
{
#ifdef DEBUG
- if( CKR_OK != nssCKFWToken_verifyPointer(fwToken) ) {
- return (NSSCKMDSlot *)NULL;
- }
+ if (CKR_OK != nssCKFWToken_verifyPointer(fwToken)) {
+ return (NSSCKMDSlot *)NULL;
+ }
#endif /* DEBUG */
- return nssCKFWToken_GetMDSlot(fwToken);
+ return nssCKFWToken_GetMDSlot(fwToken);
}
/*
@@ -1876,16 +1778,14 @@ NSSCKFWToken_GetMDSlot
*/
NSS_IMPLEMENT CK_STATE
-NSSCKFWSession_GetSessionState
-(
- NSSCKFWToken *fwToken
-)
+NSSCKFWSession_GetSessionState(
+ NSSCKFWToken *fwToken)
{
#ifdef DEBUG
- if( CKR_OK != nssCKFWToken_verifyPointer(fwToken) ) {
- return CKS_RO_PUBLIC_SESSION;
- }
+ if (CKR_OK != nssCKFWToken_verifyPointer(fwToken)) {
+ return CKS_RO_PUBLIC_SESSION;
+ }
#endif /* DEBUG */
- return nssCKFWToken_GetSessionState(fwToken);
+ return nssCKFWToken_GetSessionState(fwToken);
}
diff --git a/nss/lib/ckfw/wrap.c b/nss/lib/ckfw/wrap.c
index 3a0b0df..44c2e8e 100644
--- a/nss/lib/ckfw/wrap.c
+++ b/nss/lib/ckfw/wrap.c
@@ -92,41 +92,46 @@
/* figure out out locking semantics */
static CK_RV
nssCKFW_GetThreadSafeState(CK_C_INITIALIZE_ARGS_PTR pInitArgs,
- CryptokiLockingState *pLocking_state) {
- int functionCount = 0;
+ 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;
- }
+ /* 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;
+ /* 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;
@@ -136,60 +141,58 @@ static PRInt32 liveInstances;
*
*/
NSS_IMPLEMENT CK_RV
-NSSCKFWC_Initialize
-(
- NSSCKFWInstance **pFwInstance,
- NSSCKMDInstance *mdInstance,
- CK_VOID_PTR pInitArgs
-)
+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;
+ 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;
}
/*
@@ -197,59 +200,57 @@ NSSCKFWC_Initialize
*
*/
NSS_IMPLEMENT CK_RV
-NSSCKFWC_Finalize
-(
- NSSCKFWInstance **pFwInstance
-)
+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;
+ 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;
}
/*
@@ -257,57 +258,55 @@ NSSCKFWC_Finalize
*
*/
NSS_IMPLEMENT CK_RV
-NSSCKFWC_GetInfo
-(
- NSSCKFWInstance *fwInstance,
- CK_INFO_PTR pInfo
-)
+NSSCKFWC_GetInfo(
+ NSSCKFWInstance *fwInstance,
+ CK_INFO_PTR pInfo)
{
- CK_RV error = CKR_OK;
+ CK_RV error = CKR_OK;
- if( (CK_INFO_PTR)CK_NULL_PTR == pInfo ) {
- error = CKR_ARGUMENTS_BAD;
- goto loser;
- }
+ 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));
+ /*
+ * A purify error here means a caller error
+ */
+ (void)nsslibc_memset(pInfo, 0, sizeof(CK_INFO));
- pInfo->cryptokiVersion = nssCKFWInstance_GetCryptokiVersion(fwInstance);
+ pInfo->cryptokiVersion = nssCKFWInstance_GetCryptokiVersion(fwInstance);
- error = nssCKFWInstance_GetManufacturerID(fwInstance, pInfo->manufacturerID);
- if( CKR_OK != error ) {
- goto loser;
- }
+ error = nssCKFWInstance_GetManufacturerID(fwInstance, pInfo->manufacturerID);
+ if (CKR_OK != error) {
+ goto loser;
+ }
- pInfo->flags = nssCKFWInstance_GetFlags(fwInstance);
+ pInfo->flags = nssCKFWInstance_GetFlags(fwInstance);
- error = nssCKFWInstance_GetLibraryDescription(fwInstance, pInfo->libraryDescription);
- if( CKR_OK != error ) {
- goto loser;
- }
+ error = nssCKFWInstance_GetLibraryDescription(fwInstance, pInfo->libraryDescription);
+ if (CKR_OK != error) {
+ goto loser;
+ }
- pInfo->libraryVersion = nssCKFWInstance_GetLibraryVersion(fwInstance);
+ pInfo->libraryVersion = nssCKFWInstance_GetLibraryVersion(fwInstance);
- return CKR_OK;
+ 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;
- }
+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;
+ return error;
}
-
+
/*
* C_GetFunctionList is implemented entirely in the Module's file which
* includes the Framework API insert file. It requires no "actual"
@@ -319,179 +318,175 @@ NSSCKFWC_GetInfo
*
*/
NSS_IMPLEMENT CK_RV
-NSSCKFWC_GetSlotList
-(
- NSSCKFWInstance *fwInstance,
- CK_BBOOL tokenPresent,
- CK_SLOT_ID_PTR pSlotList,
- CK_ULONG_PTR pulCount
-)
+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));
+ CK_RV error = CKR_OK;
+ CK_ULONG nSlots;
- 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.
+ 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;
- for( i = 0; i < nSlots; i++ ) {
- pSlotList[i] = i+1;
+ /*
+ * 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;
}
- 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;
+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
-)
+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;
+ 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;
}
/*
@@ -499,156 +494,154 @@ NSSCKFWC_GetSlotInfo
*
*/
NSS_IMPLEMENT CK_RV
-NSSCKFWC_GetTokenInfo
-(
- NSSCKFWInstance *fwInstance,
- CK_SLOT_ID slotID,
- CK_TOKEN_INFO_PTR pInfo
-)
+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;
+ 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;
}
/*
@@ -656,82 +649,80 @@ NSSCKFWC_GetTokenInfo
*
*/
NSS_IMPLEMENT CK_RV
-NSSCKFWC_WaitForSlotEvent
-(
- NSSCKFWInstance *fwInstance,
- CK_FLAGS flags,
- CK_SLOT_ID_PTR pSlot,
- CK_VOID_PTR pReserved
-)
+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;
+ 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;
}
/*
@@ -739,113 +730,111 @@ NSSCKFWC_WaitForSlotEvent
*
*/
NSS_IMPLEMENT CK_RV
-NSSCKFWC_GetMechanismList
-(
- NSSCKFWInstance *fwInstance,
- CK_SLOT_ID slotID,
- CK_MECHANISM_TYPE_PTR pMechanismList,
- CK_ULONG_PTR pulCount
-)
+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;
- }
+ 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));
- 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));
+ if (0 != count) {
+ error = nssCKFWToken_GetMechanismTypes(fwToken, pMechanismList);
+ } else {
+ error = CKR_OK;
+ }
- *pulCount = count;
+ if (CKR_OK == error) {
+ return CKR_OK;
+ }
- if( 0 != count ) {
- error = nssCKFWToken_GetMechanismTypes(fwToken, pMechanismList);
- } else {
- error = 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;
+ }
- 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;
+ return error;
}
/*
@@ -853,139 +842,137 @@ NSSCKFWC_GetMechanismList
*
*/
NSS_IMPLEMENT CK_RV
-NSSCKFWC_GetMechanismInfo
-(
- NSSCKFWInstance *fwInstance,
- CK_SLOT_ID slotID,
- CK_MECHANISM_TYPE type,
- CK_MECHANISM_INFO_PTR pInfo
-)
+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;
+ 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;
}
/*
@@ -993,94 +980,92 @@ NSSCKFWC_GetMechanismInfo
*
*/
NSS_IMPLEMENT CK_RV
-NSSCKFWC_InitToken
-(
- NSSCKFWInstance *fwInstance,
- CK_SLOT_ID slotID,
- CK_CHAR_PTR pPin,
- CK_ULONG ulPinLen,
- CK_CHAR_PTR pLabel
-)
+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;
+ 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;
}
/*
@@ -1088,73 +1073,71 @@ NSSCKFWC_InitToken
*
*/
NSS_IMPLEMENT CK_RV
-NSSCKFWC_InitPIN
-(
- NSSCKFWInstance *fwInstance,
- CK_SESSION_HANDLE hSession,
- CK_CHAR_PTR pPin,
- CK_ULONG ulPinLen
-)
+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;
+ 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;
}
/*
@@ -1162,84 +1145,82 @@ NSSCKFWC_InitPIN
*
*/
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
-)
+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;
+ 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;
}
/*
@@ -1247,128 +1228,126 @@ NSSCKFWC_SetPIN
*
*/
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
-)
+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;
+ 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;
}
/*
@@ -1376,58 +1355,56 @@ NSSCKFWC_OpenSession
*
*/
NSS_IMPLEMENT CK_RV
-NSSCKFWC_CloseSession
-(
- NSSCKFWInstance *fwInstance,
- CK_SESSION_HANDLE hSession
-)
+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;
+ 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;
}
/*
@@ -1435,78 +1412,76 @@ NSSCKFWC_CloseSession
*
*/
NSS_IMPLEMENT CK_RV
-NSSCKFWC_CloseAllSessions
-(
- NSSCKFWInstance *fwInstance,
- CK_SLOT_ID slotID
-)
+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;
+ 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;
}
/*
@@ -1514,80 +1489,78 @@ NSSCKFWC_CloseAllSessions
*
*/
NSS_IMPLEMENT CK_RV
-NSSCKFWC_GetSessionInfo
-(
- NSSCKFWInstance *fwInstance,
- CK_SESSION_HANDLE hSession,
- CK_SESSION_INFO_PTR pInfo
-)
+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;
+ 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;
}
/*
@@ -1595,88 +1568,86 @@ NSSCKFWC_GetSessionInfo
*
*/
NSS_IMPLEMENT CK_RV
-NSSCKFWC_GetOperationState
-(
- NSSCKFWInstance *fwInstance,
- CK_SESSION_HANDLE hSession,
- CK_BYTE_PTR pOperationState,
- CK_ULONG_PTR pulOperationStateLen
-)
+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 ) {
+ 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;
- }
- 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;
+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;
}
/*
@@ -1684,100 +1655,98 @@ NSSCKFWC_GetOperationState
*
*/
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
-)
+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.
- */
+ 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;
+ 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;
}
/*
@@ -1785,77 +1754,75 @@ NSSCKFWC_SetOperationState
*
*/
NSS_IMPLEMENT CK_RV
-NSSCKFWC_Login
-(
- NSSCKFWInstance *fwInstance,
- CK_SESSION_HANDLE hSession,
- CK_USER_TYPE userType,
- CK_CHAR_PTR pPin,
- CK_ULONG ulPinLen
-)
+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;
+ 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;
}
/*
@@ -1863,57 +1830,55 @@ NSSCKFWC_Login
*
*/
NSS_IMPLEMENT CK_RV
-NSSCKFWC_Logout
-(
- NSSCKFWInstance *fwInstance,
- CK_SESSION_HANDLE hSession
-)
+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;
+ 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;
}
/*
@@ -1921,85 +1886,83 @@ NSSCKFWC_Logout
*
*/
NSS_IMPLEMENT CK_RV
-NSSCKFWC_CreateObject
-(
- NSSCKFWInstance *fwInstance,
- CK_SESSION_HANDLE hSession,
- CK_ATTRIBUTE_PTR pTemplate,
- CK_ULONG ulCount,
- CK_OBJECT_HANDLE_PTR phObject
-)
+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;
+ CK_RV error = CKR_OK;
+ NSSCKFWSession *fwSession;
+ NSSCKFWObject *fwObject;
- fwObject = nssCKFWSession_CreateObject(fwSession, pTemplate,
- ulCount, &error);
- if (!fwObject) {
- goto loser;
- }
+ if (!fwInstance) {
+ error = CKR_CRYPTOKI_NOT_INITIALIZED;
+ 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;
+ 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;
}
/*
@@ -2007,94 +1970,92 @@ NSSCKFWC_CreateObject
*
*/
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
-)
+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;
+ 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;
}
/*
@@ -2102,65 +2063,63 @@ NSSCKFWC_CopyObject
*
*/
NSS_IMPLEMENT CK_RV
-NSSCKFWC_DestroyObject
-(
- NSSCKFWInstance *fwInstance,
- CK_SESSION_HANDLE hSession,
- CK_OBJECT_HANDLE hObject
-)
+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;
+ 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;
}
/*
@@ -2168,77 +2127,75 @@ NSSCKFWC_DestroyObject
*
*/
NSS_IMPLEMENT CK_RV
-NSSCKFWC_GetObjectSize
-(
- NSSCKFWInstance *fwInstance,
- CK_SESSION_HANDLE hSession,
- CK_OBJECT_HANDLE hObject,
- CK_ULONG_PTR pulSize
-)
+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;
+ 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;
}
/*
@@ -2246,229 +2203,233 @@ NSSCKFWC_GetObjectSize
*
*/
NSS_IMPLEMENT CK_RV
-NSSCKFWC_GetAttributeValue
-(
- NSSCKFWInstance *fwInstance,
- CK_SESSION_HANDLE hSession,
- CK_OBJECT_HANDLE hObject,
- CK_ATTRIBUTE_PTR pTemplate,
- CK_ULONG ulCount
-)
+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 ) {
+ 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_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_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:
- 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;
+ 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
-)
+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;
+ 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;
}
/*
@@ -2476,85 +2437,83 @@ NSSCKFWC_SetAttributeValue
*
*/
NSS_IMPLEMENT CK_RV
-NSSCKFWC_FindObjectsInit
-(
- NSSCKFWInstance *fwInstance,
- CK_SESSION_HANDLE hSession,
- CK_ATTRIBUTE_PTR pTemplate,
- CK_ULONG ulCount
-)
+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;
+ 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;
}
/*
@@ -2562,93 +2521,91 @@ NSSCKFWC_FindObjectsInit
*
*/
NSS_IMPLEMENT CK_RV
-NSSCKFWC_FindObjects
-(
- NSSCKFWInstance *fwInstance,
- CK_SESSION_HANDLE hSession,
- CK_OBJECT_HANDLE_PTR phObject,
- CK_ULONG ulMaxObjectCount,
- CK_ULONG_PTR pulObjectCount
-)
+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;
+ CK_RV error = CKR_OK;
+ NSSCKFWSession *fwSession;
+ NSSCKFWFindObjects *fwFindObjects;
+ CK_ULONG i;
+
+ if (!fwInstance) {
+ error = CKR_CRYPTOKI_NOT_INITIALIZED;
+ goto loser;
+ }
- fwFindObjects = nssCKFWSession_GetFWFindObjects(fwSession, &error);
- if (!fwFindObjects) {
- goto loser;
- }
+ fwSession = nssCKFWInstance_ResolveSessionHandle(fwInstance, hSession);
+ if (!fwSession) {
+ error = CKR_SESSION_HANDLE_INVALID;
+ 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;
+ 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;
}
/*
@@ -2656,67 +2613,65 @@ NSSCKFWC_FindObjects
*
*/
NSS_IMPLEMENT CK_RV
-NSSCKFWC_FindObjectsFinal
-(
- NSSCKFWInstance *fwInstance,
- CK_SESSION_HANDLE hSession
-)
+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;
+ 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;
}
/*
@@ -2724,97 +2679,95 @@ NSSCKFWC_FindObjectsFinal
*
*/
NSS_IMPLEMENT CK_RV
-NSSCKFWC_EncryptInit
-(
- NSSCKFWInstance *fwInstance,
- CK_SESSION_HANDLE hSession,
- CK_MECHANISM_PTR pMechanism,
- CK_OBJECT_HANDLE hKey
-)
+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;
- }
+ 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;
+ /* 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;
}
/*
@@ -2822,64 +2775,62 @@ loser:
*
*/
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
-)
+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;
- }
+ 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;
+ /* 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;
}
/*
@@ -2887,63 +2838,61 @@ loser:
*
*/
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
-)
+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;
- }
+ 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;
+ /* 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;
}
/*
@@ -2951,61 +2900,59 @@ loser:
*
*/
NSS_IMPLEMENT CK_RV
-NSSCKFWC_EncryptFinal
-(
- NSSCKFWInstance *fwInstance,
- CK_SESSION_HANDLE hSession,
- CK_BYTE_PTR pLastEncryptedPart,
- CK_ULONG_PTR pulLastEncryptedPartLen
-)
+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;
- }
+ 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;
+ /* 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;
}
/*
@@ -3013,97 +2960,95 @@ loser:
*
*/
NSS_IMPLEMENT CK_RV
-NSSCKFWC_DecryptInit
-(
- NSSCKFWInstance *fwInstance,
- CK_SESSION_HANDLE hSession,
- CK_MECHANISM_PTR pMechanism,
- CK_OBJECT_HANDLE hKey
-)
+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;
- }
+ 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;
+ /* 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;
}
/*
@@ -3111,71 +3056,69 @@ loser:
*
*/
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
-)
+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;
- }
+ 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;
+ /* 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;
}
/*
@@ -3183,71 +3126,69 @@ loser:
*
*/
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
-)
+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;
- }
+ 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;
+ /* 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;
}
/*
@@ -3255,69 +3196,67 @@ loser:
*
*/
NSS_IMPLEMENT CK_RV
-NSSCKFWC_DecryptFinal
-(
- NSSCKFWInstance *fwInstance,
- CK_SESSION_HANDLE hSession,
- CK_BYTE_PTR pLastPart,
- CK_ULONG_PTR pulLastPartLen
-)
+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;
- }
+ 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;
+ /* 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;
}
/*
@@ -3325,85 +3264,83 @@ loser:
*
*/
NSS_IMPLEMENT CK_RV
-NSSCKFWC_DigestInit
-(
- NSSCKFWInstance *fwInstance,
- CK_SESSION_HANDLE hSession,
- CK_MECHANISM_PTR pMechanism
-)
+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;
- }
+ 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;
+ /* 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;
}
/*
@@ -3411,62 +3348,60 @@ loser:
*
*/
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
-)
+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;
- }
+ 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;
+ /* 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;
}
/*
@@ -3474,59 +3409,57 @@ loser:
*
*/
NSS_IMPLEMENT CK_RV
-NSSCKFWC_DigestUpdate
-(
- NSSCKFWInstance *fwInstance,
- CK_SESSION_HANDLE hSession,
- CK_BYTE_PTR pData,
- CK_ULONG ulDataLen
-)
+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;
- }
+ 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;
+ /* 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;
}
/*
@@ -3534,64 +3467,62 @@ loser:
*
*/
NSS_IMPLEMENT CK_RV
-NSSCKFWC_DigestKey
-(
- NSSCKFWInstance *fwInstance,
- CK_SESSION_HANDLE hSession,
- CK_OBJECT_HANDLE hKey
-)
+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;
- }
+ 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;
+ /* 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;
}
/*
@@ -3599,60 +3530,58 @@ loser:
*
*/
NSS_IMPLEMENT CK_RV
-NSSCKFWC_DigestFinal
-(
- NSSCKFWInstance *fwInstance,
- CK_SESSION_HANDLE hSession,
- CK_BYTE_PTR pDigest,
- CK_ULONG_PTR pulDigestLen
-)
+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;
- }
+ 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;
+ /* 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;
}
/*
@@ -3660,98 +3589,96 @@ loser:
*
*/
NSS_IMPLEMENT CK_RV
-NSSCKFWC_SignInit
-(
- NSSCKFWInstance *fwInstance,
- CK_SESSION_HANDLE hSession,
- CK_MECHANISM_PTR pMechanism,
- CK_OBJECT_HANDLE hKey
-)
+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;
- }
+ 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;
+ /* 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;
}
/*
@@ -3759,66 +3686,64 @@ loser:
*
*/
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
-)
+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;
- }
+ 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;
+ /* 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;
}
/*
@@ -3826,61 +3751,59 @@ loser:
*
*/
NSS_IMPLEMENT CK_RV
-NSSCKFWC_SignUpdate
-(
- NSSCKFWInstance *fwInstance,
- CK_SESSION_HANDLE hSession,
- CK_BYTE_PTR pPart,
- CK_ULONG ulPartLen
-)
+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;
- }
+ 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;
+ /* 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;
}
/*
@@ -3888,63 +3811,61 @@ loser:
*
*/
NSS_IMPLEMENT CK_RV
-NSSCKFWC_SignFinal
-(
- NSSCKFWInstance *fwInstance,
- CK_SESSION_HANDLE hSession,
- CK_BYTE_PTR pSignature,
- CK_ULONG_PTR pulSignatureLen
-)
+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;
- }
+ 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;
+ /* 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;
}
/*
@@ -3952,98 +3873,96 @@ loser:
*
*/
NSS_IMPLEMENT CK_RV
-NSSCKFWC_SignRecoverInit
-(
- NSSCKFWInstance *fwInstance,
- CK_SESSION_HANDLE hSession,
- CK_MECHANISM_PTR pMechanism,
- CK_OBJECT_HANDLE hKey
-)
+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;
- }
+ 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;
+ /* 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;
}
/*
@@ -4051,65 +3970,63 @@ loser:
*
*/
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
-)
+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;
- }
+ 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;
+ /* 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;
}
/*
@@ -4117,98 +4034,96 @@ loser:
*
*/
NSS_IMPLEMENT CK_RV
-NSSCKFWC_VerifyInit
-(
- NSSCKFWInstance *fwInstance,
- CK_SESSION_HANDLE hSession,
- CK_MECHANISM_PTR pMechanism,
- CK_OBJECT_HANDLE hKey
-)
+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);
+ CK_RV error = CKR_OK;
+ NSSCKFWSession *fwSession;
+ NSSCKFWObject *fwObject;
+ NSSCKFWSlot *fwSlot;
+ NSSCKFWToken *fwToken;
+ NSSCKFWMechanism *fwMechanism;
+
+ if (!fwInstance) {
+ error = CKR_CRYPTOKI_NOT_INITIALIZED;
+ goto loser;
+ }
- nssCKFWMechanism_Destroy(fwMechanism);
+ fwSession = nssCKFWInstance_ResolveSessionHandle(fwInstance, hSession);
+ if (!fwSession) {
+ error = CKR_SESSION_HANDLE_INVALID;
+ goto loser;
+ }
- if (CKR_OK == error) {
- return CKR_OK;
- }
+ 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;
+ /* 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;
}
/*
@@ -4216,65 +4131,63 @@ loser:
*
*/
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
-)
+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;
- }
+ 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;
+ /* 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;
}
/*
@@ -4282,60 +4195,58 @@ loser:
*
*/
NSS_IMPLEMENT CK_RV
-NSSCKFWC_VerifyUpdate
-(
- NSSCKFWInstance *fwInstance,
- CK_SESSION_HANDLE hSession,
- CK_BYTE_PTR pPart,
- CK_ULONG ulPartLen
-)
+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;
- }
+ 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;
+ /* 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;
}
/*
@@ -4343,62 +4254,60 @@ loser:
*
*/
NSS_IMPLEMENT CK_RV
-NSSCKFWC_VerifyFinal
-(
- NSSCKFWInstance *fwInstance,
- CK_SESSION_HANDLE hSession,
- CK_BYTE_PTR pSignature,
- CK_ULONG ulSignatureLen
-)
+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;
- }
+ 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;
+ /* 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;
}
/*
@@ -4406,98 +4315,96 @@ loser:
*
*/
NSS_IMPLEMENT CK_RV
-NSSCKFWC_VerifyRecoverInit
-(
- NSSCKFWInstance *fwInstance,
- CK_SESSION_HANDLE hSession,
- CK_MECHANISM_PTR pMechanism,
- CK_OBJECT_HANDLE hKey
-)
+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;
- }
+ 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;
+ /* 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;
}
/*
@@ -4505,64 +4412,62 @@ loser:
*
*/
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
-)
+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;
- }
+ 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;
+ /* 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;
}
/*
@@ -4570,64 +4475,62 @@ loser:
*
*/
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
-)
+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;
- }
+ 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;
+ /* 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;
}
/*
@@ -4635,71 +4538,69 @@ loser:
*
*/
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
-)
+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;
- }
+ 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;
+ /* 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;
}
/*
@@ -4707,65 +4608,63 @@ loser:
*
*/
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
-)
+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;
- }
+ 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;
+ /* 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;
}
/*
@@ -4773,69 +4672,67 @@ loser:
*
*/
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
-)
+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;
- }
+ 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;
+ /* 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;
}
/*
@@ -4843,106 +4740,104 @@ loser:
*
*/
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
-)
+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;
- }
+ 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;
+ /* 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;
}
/*
@@ -4950,121 +4845,119 @@ loser:
*
*/
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
-)
+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;
- }
+ 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;
+ /* 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;
}
/*
@@ -5072,153 +4965,150 @@ loser:
*
*/
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
-)
+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;
- }
-
- /*
+ 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;
+ 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);
- 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;
- }
+ *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;
+ /* 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;
}
/*
@@ -5226,145 +5116,143 @@ loser:
*
*/
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
-)
+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;
- }
+ 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;
+ /* 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;
}
/*
@@ -5372,119 +5260,117 @@ loser:
*
*/
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
-)
+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;
- }
+ 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;
+ /* 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;
}
/*
@@ -5492,76 +5378,74 @@ loser:
*
*/
NSS_IMPLEMENT CK_RV
-NSSCKFWC_SeedRandom
-(
- NSSCKFWInstance *fwInstance,
- CK_SESSION_HANDLE hSession,
- CK_BYTE_PTR pSeed,
- CK_ULONG ulSeedLen
-)
+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;
+ 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;
}
/*
@@ -5569,78 +5453,76 @@ NSSCKFWC_SeedRandom
*
*/
NSS_IMPLEMENT CK_RV
-NSSCKFWC_GenerateRandom
-(
- NSSCKFWInstance *fwInstance,
- CK_SESSION_HANDLE hSession,
- CK_BYTE_PTR pRandomData,
- CK_ULONG ulRandomLen
-)
+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;
- }
-
- /*
+ 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;
+ (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;
}
/*
@@ -5648,13 +5530,11 @@ NSSCKFWC_GenerateRandom
*
*/
NSS_IMPLEMENT CK_RV
-NSSCKFWC_GetFunctionStatus
-(
- NSSCKFWInstance *fwInstance,
- CK_SESSION_HANDLE hSession
-)
+NSSCKFWC_GetFunctionStatus(
+ NSSCKFWInstance *fwInstance,
+ CK_SESSION_HANDLE hSession)
{
- return CKR_FUNCTION_NOT_PARALLEL;
+ return CKR_FUNCTION_NOT_PARALLEL;
}
/*
@@ -5662,11 +5542,9 @@ NSSCKFWC_GetFunctionStatus
*
*/
NSS_IMPLEMENT CK_RV
-NSSCKFWC_CancelFunction
-(
- NSSCKFWInstance *fwInstance,
- CK_SESSION_HANDLE hSession
-)
+NSSCKFWC_CancelFunction(
+ NSSCKFWInstance *fwInstance,
+ CK_SESSION_HANDLE hSession)
{
- return CKR_FUNCTION_NOT_PARALLEL;
+ return CKR_FUNCTION_NOT_PARALLEL;
}
diff --git a/nss/lib/crmf/asn1cmn.c b/nss/lib/crmf/asn1cmn.c
index af86670..6cf469f 100644
--- a/nss/lib/crmf/asn1cmn.c
+++ b/nss/lib/crmf/asn1cmn.c
@@ -11,94 +11,94 @@ 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,
+ { 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},
+ CMMFCertifiedKeyPairTemplate },
{ 0 }
};
static const SEC_ASN1Template CMMFCertOrEncCertTemplate[] = {
- { SEC_ASN1_ANY, offsetof(CMMFCertOrEncCert, derValue), NULL,
- sizeof(CMMFCertOrEncCert)},
+ { SEC_ASN1_ANY, offsetof(CMMFCertOrEncCert, derValue), NULL,
+ sizeof(CMMFCertOrEncCert) },
{ 0 }
};
const SEC_ASN1Template CMMFCertifiedKeyPairTemplate[] = {
- { SEC_ASN1_SEQUENCE, 0, NULL, sizeof(CMMFCertifiedKeyPair)},
+ { 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),
+ 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)},
+ { 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)}
+ { 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)},
+ { 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,
+ { SEC_ASN1_SEQUENCE_OF | SEC_ASN1_XTRN,
offsetof(CMMFPOPODecKeyRespContent, responses),
- SEC_ASN1_SUB(SEC_IntegerTemplate),
- sizeof(CMMFPOPODecKeyRespContent)},
+ SEC_ASN1_SUB(SEC_IntegerTemplate),
+ sizeof(CMMFPOPODecKeyRespContent) },
{ 0 }
};
const SEC_ASN1Template CMMFCertOrEncCertEncryptedCertTemplate[] = {
{ SEC_ASN1_CONTEXT_SPECIFIC | 1,
0,
- CRMFEncryptedValueTemplate},
+ CRMFEncryptedValueTemplate },
{ 0 }
};
const SEC_ASN1Template CMMFCertOrEncCertCertificateTemplate[] = {
{ SEC_ASN1_CONTEXT_SPECIFIC | SEC_ASN1_XTRN | 0,
0,
- SEC_ASN1_SUB(SEC_SignedCertificateTemplate)},
+ SEC_ASN1_SUB(SEC_SignedCertificateTemplate) },
{ 0 }
};
const SEC_ASN1Template CMMFCertRepContentTemplate[] = {
- { SEC_ASN1_SEQUENCE, 0, NULL, sizeof(CMMFCertRepContent)},
+ { SEC_ASN1_SEQUENCE, 0, NULL, sizeof(CMMFCertRepContent) },
{ SEC_ASN1_CONSTRUCTED | SEC_ASN1_OPTIONAL |
- SEC_ASN1_CONTEXT_SPECIFIC | 1,
+ SEC_ASN1_CONTEXT_SPECIFIC | 1,
offsetof(CMMFCertRepContent, caPubs),
CMMFSequenceOfCertsTemplate },
{ SEC_ASN1_SEQUENCE_OF, offsetof(CMMFCertRepContent, response),
- CMMFCertResponseTemplate},
+ CMMFCertResponseTemplate },
{ 0 }
};
static const SEC_ASN1Template CMMFChallengeTemplate[] = {
- { SEC_ASN1_SEQUENCE, 0, NULL, sizeof(CMMFChallenge)},
- { SEC_ASN1_POINTER | SEC_ASN1_OPTIONAL | SEC_ASN1_XTRN,
+ { 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) },
@@ -109,27 +109,27 @@ static const SEC_ASN1Template CMMFChallengeTemplate[] = {
};
const SEC_ASN1Template CMMFPOPODecKeyChallContentTemplate[] = {
- { SEC_ASN1_SEQUENCE_OF,offsetof(CMMFPOPODecKeyChallContent, challenges),
+ { SEC_ASN1_SEQUENCE_OF, offsetof(CMMFPOPODecKeyChallContent, challenges),
CMMFChallengeTemplate, sizeof(CMMFPOPODecKeyChallContent) },
{ 0 }
};
SECStatus
-cmmf_decode_process_cert_response(PLArenaPool *poolp,
- CERTCertDBHandle *db,
- CMMFCertResponse *inCertResp)
+cmmf_decode_process_cert_response(PLArenaPool *poolp,
+ CERTCertDBHandle *db,
+ CMMFCertResponse *inCertResp)
{
SECStatus rv = SECSuccess;
-
+
if (inCertResp->certifiedKeyPair != NULL) {
- rv = cmmf_decode_process_certified_key_pair(poolp,
- db,
- inCertResp->certifiedKeyPair);
+ rv = cmmf_decode_process_certified_key_pair(poolp,
+ db,
+ inCertResp->certifiedKeyPair);
}
return rv;
}
-static CERTCertificate*
+static CERTCertificate *
cmmf_DecodeDERCertificate(CERTCertDBHandle *db, SECItem *derCert)
{
CERTCertificate *newCert;
@@ -141,80 +141,76 @@ cmmf_DecodeDERCertificate(CERTCertDBHandle *db, SECItem *derCert)
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;
+ 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(PLArenaPool *poolp,
- CERTCertDBHandle *db,
- CMMFCertOrEncCert *inCertOrEncCert)
+cmmf_decode_process_certorenccert(PLArenaPool *poolp,
+ CERTCertDBHandle *db,
+ CMMFCertOrEncCert *inCertOrEncCert)
{
SECStatus rv = SECSuccess;
- inCertOrEncCert->choice =
+ 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;
+ 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(PLArenaPool *poolp,
- CERTCertDBHandle *db,
- CMMFCertifiedKeyPair *inCertKeyPair)
+SECStatus
+cmmf_decode_process_certified_key_pair(PLArenaPool *poolp,
+ CERTCertDBHandle *db,
+ CMMFCertifiedKeyPair *inCertKeyPair)
{
- return cmmf_decode_process_certorenccert (poolp,
- db,
- &inCertKeyPair->certOrEncCert);
+ return cmmf_decode_process_certorenccert(poolp,
+ db,
+ &inCertKeyPair->certOrEncCert);
}
-
-
diff --git a/nss/lib/crmf/challcli.c b/nss/lib/crmf/challcli.c
index eaff349..a928438 100644
--- a/nss/lib/crmf/challcli.c
+++ b/nss/lib/crmf/challcli.c
@@ -10,12 +10,12 @@
#include "secder.h"
#include "sechash.h"
-CMMFPOPODecKeyChallContent*
+CMMFPOPODecKeyChallContent *
CMMF_CreatePOPODecKeyChallContentFromDER(const char *buf, long len)
{
- PLArenaPool *poolp;
+ PLArenaPool *poolp;
CMMFPOPODecKeyChallContent *challContent;
- SECStatus rv;
+ SECStatus rv;
poolp = PORT_NewArena(CRMF_DEFAULT_ARENA_SIZE);
if (poolp == NULL) {
@@ -26,19 +26,19 @@ CMMF_CreatePOPODecKeyChallContentFromDER(const char *buf, long len)
goto loser;
}
challContent->poolp = poolp;
- rv = SEC_ASN1Decode(poolp, challContent,
- CMMFPOPODecKeyChallContentTemplate, buf, len);
+ 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;
+ while (challContent->challenges[challContent->numChallenges] != NULL) {
+ challContent->numChallenges++;
+ }
+ challContent->numAllocated = challContent->numChallenges;
}
return challContent;
- loser:
+loser:
if (poolp != NULL) {
PORT_FreeArena(poolp, PR_FALSE);
}
@@ -46,8 +46,7 @@ CMMF_CreatePOPODecKeyChallContentFromDER(const char *buf, long len)
}
int
-CMMF_POPODecKeyChallContentGetNumChallenges
- (CMMFPOPODecKeyChallContent *inKeyChallCont)
+CMMF_POPODecKeyChallContentGetNumChallenges(CMMFPOPODecKeyChallContent *inKeyChallCont)
{
PORT_Assert(inKeyChallCont != NULL);
if (inKeyChallCont == NULL) {
@@ -56,51 +55,50 @@ CMMF_POPODecKeyChallContentGetNumChallenges
return inKeyChallCont->numChallenges;
}
-SECItem*
-CMMF_POPODecKeyChallContentGetPublicValue
- (CMMFPOPODecKeyChallContent *inKeyChallCont,
- int inIndex)
+SECItem *
+CMMF_POPODecKeyChallContentGetPublicValue(CMMFPOPODecKeyChallContent *inKeyChallCont,
+ int inIndex)
{
PORT_Assert(inKeyChallCont != NULL);
- if (inKeyChallCont == NULL || (inIndex > inKeyChallCont->numChallenges-1)||
- inIndex < 0) {
+ 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)
+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;
+ int i;
+
+ for (i = inIndex; i >= 0; i--) {
+ if (inChalCont->challenges[i]->owf != NULL) {
+ return inChalCont->challenges[i]->owf;
+ }
+ }
+ return NULL;
}
-SECStatus
+SECStatus
CMMF_POPODecKeyChallContDecryptChallenge(CMMFPOPODecKeyChallContent *inChalCont,
- int inIndex,
- SECKEYPrivateKey *inPrivKey)
+ int inIndex,
+ SECKEYPrivateKey *inPrivKey)
{
- CMMFChallenge *challenge;
- SECItem *decryptedRand=NULL;
- PLArenaPool *poolp = NULL;
+ CMMFChallenge *challenge;
+ SECItem *decryptedRand = NULL;
+ PLArenaPool *poolp = NULL;
SECAlgorithmID *owf;
- SECStatus rv = SECFailure;
- SECOidTag tag;
- CMMFRand randStr;
- SECItem hashItem;
- unsigned char hash[HASH_LENGTH_MAX];
+ 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){
+ if (inChalCont == NULL || inIndex < 0 || inIndex > inChalCont->numChallenges ||
+ inPrivKey == NULL) {
return SECFailure;
}
@@ -114,21 +112,21 @@ CMMF_POPODecKeyChallContDecryptChallenge(CMMFPOPODecKeyChallContent *inChalCont,
if (decryptedRand == NULL) {
goto loser;
}
- rv = PK11_PrivDecryptPKCS1(inPrivKey, decryptedRand->data,
- &decryptedRand->len, decryptedRand->len,
- challenge->challenge.data, challenge->challenge.len);
+ 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);
+ 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.
- */
+ * 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 */
@@ -138,7 +136,7 @@ CMMF_POPODecKeyChallContDecryptChallenge(CMMFPOPODecKeyChallContent *inChalCont,
tag = SECOID_FindOIDTag(&owf->algorithm);
hashItem.len = HASH_ResultLenByOidTag(tag);
if (!hashItem.len)
- goto loser; /* error code has been set */
+ goto loser; /* error code has been set */
rv = PK11_HashBuf(tag, hash, randStr.integer.data, randStr.integer.len);
if (rv != SECSuccess) {
@@ -147,46 +145,44 @@ CMMF_POPODecKeyChallContDecryptChallenge(CMMFPOPODecKeyChallContent *inChalCont,
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);
+ * in the challenge. Bail out.
+ */
+ PORT_SetError(SEC_ERROR_BAD_DATA);
rv = SECFailure;
- goto loser;
+ goto loser;
}
- rv = PK11_HashBuf(tag, hash, challenge->senderDER.data,
- challenge->senderDER.len);
+ 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);
+ * in the challenge. Bail out.
+ */
+ PORT_SetError(SEC_ERROR_BAD_DATA);
rv = SECFailure;
- goto loser;
+ 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:
+ &randStr.integer);
+loser:
if (poolp) {
- PORT_FreeArena(poolp, PR_FALSE);
+ PORT_FreeArena(poolp, PR_FALSE);
}
return rv;
}
SECStatus
-CMMF_POPODecKeyChallContentGetRandomNumber
- (CMMFPOPODecKeyChallContent *inKeyChallCont,
- int inIndex,
- long *inDest)
+CMMF_POPODecKeyChallContentGetRandomNumber(CMMFPOPODecKeyChallContent *inKeyChallCont,
+ int inIndex,
+ long *inDest)
{
CMMFChallenge *challenge;
-
+
PORT_Assert(inKeyChallCont != NULL);
- if (inKeyChallCont == NULL || inIndex > 0 || inIndex >=
- inKeyChallCont->numChallenges) {
+ if (inKeyChallCont == NULL || inIndex > 0 || inIndex >= inKeyChallCont->numChallenges) {
return SECFailure;
}
challenge = inKeyChallCont->challenges[inIndex];
@@ -198,16 +194,16 @@ CMMF_POPODecKeyChallContentGetRandomNumber
return (*inDest == -1) ? SECFailure : SECSuccess;
}
-SECStatus
-CMMF_EncodePOPODecKeyRespContent(long *inDecodedRand,
- int inNumRand,
- CRMFEncoderOutputCallback inCallback,
- void *inArg)
+SECStatus
+CMMF_EncodePOPODecKeyRespContent(long *inDecodedRand,
+ int inNumRand,
+ CRMFEncoderOutputCallback inCallback,
+ void *inArg)
{
PLArenaPool *poolp;
CMMFPOPODecKeyRespContent *response;
SECItem *currItem;
- SECStatus rv=SECFailure;
+ SECStatus rv = SECFailure;
int i;
poolp = PORT_NewArena(CRMF_DEFAULT_ARENA_SIZE);
@@ -218,23 +214,23 @@ CMMF_EncodePOPODecKeyRespContent(long *inDecodedRand,
if (response == NULL) {
goto loser;
}
- response->responses = PORT_ArenaZNewArray(poolp, SECItem*, inNumRand+1);
+ 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;
- }
+ 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:
+ CMMFPOPODecKeyRespContentTemplate);
+loser:
if (poolp != NULL) {
PORT_FreeArena(poolp, PR_FALSE);
}
diff --git a/nss/lib/crmf/cmmf.h b/nss/lib/crmf/cmmf.h
index b5b29a6..1e39a8d 100644
--- a/nss/lib/crmf/cmmf.h
+++ b/nss/lib/crmf/cmmf.h
@@ -6,7 +6,7 @@
#ifndef _CMMF_H_
#define _CMMF_H_
/*
- * These are the functions exported by the security library for
+ * 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
@@ -25,20 +25,20 @@ SEC_BEGIN_PROTOS
* INPUTS:
* NONE
* NOTES:
- * This function will create an empty CMMFCertRepContent Structure.
+ * 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,
+ * 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
+ * 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
+ * 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);
+extern CMMFCertRepContent *CMMF_CreateCertRepContent(void);
/*
* FUNCTION: CMMF_CreateCertRepContentFromDER
@@ -46,24 +46,24 @@ extern CMMFCertRepContent* CMMF_CreateCertRepContent(void);
* db
* The certificate database where the certificates will be placed.
* The certificates will be placed in the temporary database associated
- * with the handle.
+ * 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
+ * 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);
+extern CMMFCertRepContent *
+CMMF_CreateCertRepContentFromDER(CERTCertDBHandle *db,
+ const char *buf,
+ long len);
/*
* FUNCTION: CMMF_CreateCertResponse
@@ -73,17 +73,17 @@ extern CMMFCertRepContent*
* 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
+ * 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
+ * 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);
+extern CMMFCertResponse *CMMF_CreateCertResponse(long inCertReqId);
/*
* FUNCTION: CMMF_CreateKeyRecRepContent
@@ -91,7 +91,7 @@ extern CMMFCertResponse* CMMF_CreateCertResponse(long inCertReqId);
* NONE
* NOTES:
* This function creates a new empty CMMFKeyRecRepContent structure.
- * At the very minimum, the user must call
+ * 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
@@ -111,26 +111,26 @@ extern CMMFKeyRecRepContent *CMMF_CreateKeyRecRepContent(void);
* FUNCTION: CMMF_CreateKeyRecRepContentFromDER
* INPUTS:
* db
- * The handle for the certificate database where the decoded
+ * 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
+ * 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
+ * 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);
+extern CMMFKeyRecRepContent *
+CMMF_CreateKeyRecRepContentFromDER(CERTCertDBHandle *db,
+ const char *buf,
+ long len);
/*
* FUNCTION: CMMF_CreatePOPODecKeyChallContent
@@ -139,18 +139,18 @@ extern CMMFKeyRecRepContent*
* 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
+ * 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
+ * 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);
+extern CMMFPOPODecKeyChallContent *
+CMMF_CreatePOPODecKeyChallContent(void);
/*
* FUNCTION: CMMF_CreatePOPODecKeyChallContentFromDER
@@ -161,14 +161,14 @@ extern CMMFPOPODecKeyChallContent*
* The length in bytes of the buffer 'buf'
* NOTES:
* This function passes the buffer to the ASN1 decoder and creates a
- * CMMFPOPODecKeyChallContent structure.
+ * 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);
+extern CMMFPOPODecKeyChallContent *
+CMMF_CreatePOPODecKeyChallContentFromDER(const char *buf, long len);
/*
* FUNCTION: CMMF_CreatePOPODecKeyRespContentFromDER
@@ -178,15 +178,15 @@ extern CMMFPOPODecKeyChallContent*
* len
* The length in bytes of the buffer 'buf'
* NOTES
- * This function passes the buffer to the ASN1 decoder and creates a
+ * 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);
+extern CMMFPOPODecKeyRespContent *
+CMMF_CreatePOPODecKeyRespContentFromDER(const char *buf, long len);
/************************** Set Functions *************************/
@@ -196,16 +196,16 @@ extern CMMFPOPODecKeyRespContent*
* inCertRepContent
* The CMMFCertRepContent to operate on.
* inCertResponses
- * An array of pointers to CMMFCertResponse structures to
+ * 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
+ * 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,
+ * before calling CMMF_EncodeCertRepContent. If the user calls
+ * CMMF_EncodeCertRepContent before calling this function,
* CMMF_EncodeCertRepContent will fail.
*
* RETURN:
@@ -213,10 +213,10 @@ extern CMMFPOPODecKeyRespContent*
* 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);
+extern SECStatus
+CMMF_CertRepContentSetCertResponses(CMMFCertRepContent *inCertRepContent,
+ CMMFCertResponse **inCertResponses,
+ int inNumResponses);
/*
* FUNCTION: CMMF_CertRepContentSetCAPubs
@@ -228,19 +228,19 @@ extern SECStatus
* 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
+ * 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
+ * Any other return value indicates an error while adding 'inCAPubs' to the
* CMMFCertRepContent structure.
- *
+ *
*/
-extern SECStatus
- CMMF_CertRepContentSetCAPubs (CMMFCertRepContent *inCertRepContent,
- CERTCertList *inCAPubs);
+extern SECStatus
+CMMF_CertRepContentSetCAPubs(CMMFCertRepContent *inCertRepContent,
+ CERTCertList *inCAPubs);
/*
* FUNCTION: CMMF_CertResponseSetPKIStatusInfoStatus
@@ -250,7 +250,7 @@ extern SECStatus
* inPKIStatus
* The value to set for the PKIStatusInfo.status field.
* NOTES:
- * This function will set the CertResponse.status.status field of
+ * 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
@@ -260,9 +260,9 @@ extern SECStatus
* 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);
+extern SECStatus
+CMMF_CertResponseSetPKIStatusInfoStatus(CMMFCertResponse *inCertResp,
+ CMMFPKIStatus inPKIStatus);
/*
* FUNCTION: CMMF_CertResponseSetCertificate
@@ -270,7 +270,7 @@ extern SECStatus
* inCertResp
* The CMMFCertResponse to operate on.
* inCertificate
- * The certificate to add to the
+ * 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
@@ -282,13 +282,13 @@ extern SECStatus
* Any other return value indicates an error in adding the certificate to
* the CertResponse.
*/
-extern SECStatus
- CMMF_CertResponseSetCertificate (CMMFCertResponse *inCertResp,
- CERTCertificate *inCertificate);
+extern SECStatus
+CMMF_CertResponseSetCertificate(CMMFCertResponse *inCertResp,
+ CERTCertificate *inCertificate);
/*
* FUNCTION: CMMF_KeyRecRepContentSetPKIStatusInfoStatus
- * INPUTS:
+ * INPUTS:
* inKeyRecRep
* The CMMFKeyRecRepContent to operate on.
* inPKIStatus
@@ -296,17 +296,17 @@ extern SECStatus
* 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.
+ * 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
+extern SECStatus
CMMF_KeyRecRepContentSetPKIStatusInfoStatus(CMMFKeyRecRepContent *inKeyRecRep,
- CMMFPKIStatus inPKIStatus);
+ CMMFPKIStatus inPKIStatus);
/*
* FUNCTION: CMMF_KeyRecRepContentSetNewSignCert
@@ -320,13 +320,13 @@ CMMF_KeyRecRepContentSetPKIStatusInfoStatus(CMMFKeyRecRepContent *inKeyRecRep,
* structure.
*
* RETURN:
- * SECSuccess if setting the new signing cert was successful. Any other
+ * 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);
+extern SECStatus
+CMMF_KeyRecRepContentSetNewSignCert(CMMFKeyRecRepContent *inKeyRecRep,
+ CERTCertificate *inNewSignCert);
/*
* FUNCTION: CMMF_KeyRecRepContentSetCACerts
@@ -334,21 +334,21 @@ extern SECStatus
* inKeyRecRep
* The CMMFKeyRecRepContent to operate on.
* inCACerts
- * The list of CA certificates required to construct a valid
+ * 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
+ * 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);
+extern SECStatus
+CMMF_KeyRecRepContentSetCACerts(CMMFKeyRecRepContent *inKeyRecRep,
+ CERTCertList *inCACerts);
/*
* FUNCTION: CMMF_KeyRecRepContentSetCertifiedKeyPair
@@ -362,21 +362,21 @@ extern SECStatus
* 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
+ * 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
+ * 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);
+extern SECStatus
+CMMF_KeyRecRepContentSetCertifiedKeyPair(CMMFKeyRecRepContent *inKeyRecRep,
+ CERTCertificate *inCert,
+ SECKEYPrivateKey *inPrivKey,
+ SECKEYPublicKey *inPubKey);
/*
* FUNCTION: CMMF_POPODecKeyChallContentSetNextChallenge
@@ -392,15 +392,15 @@ extern SECStatus
* 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
+ * 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
+ * library will use SHA1 as the one-way function for generating the
* witess field of the challenge.
*
* RETURN:
@@ -409,13 +409,11 @@ extern SECStatus
* while trying to generate the challenge.
*/
extern SECStatus
-CMMF_POPODecKeyChallContentSetNextChallenge
- (CMMFPOPODecKeyChallContent *inDecKeyChall,
- long inRandom,
- CERTGeneralName *inSender,
- SECKEYPublicKey *inPubKey,
- void *passwdArg);
-
+CMMF_POPODecKeyChallContentSetNextChallenge(CMMFPOPODecKeyChallContent *inDecKeyChall,
+ long inRandom,
+ CERTGeneralName *inSender,
+ SECKEYPublicKey *inPubKey,
+ void *passwdArg);
/************************** Encoding Functions *************************/
@@ -425,30 +423,30 @@ CMMF_POPODecKeyChallContentSetNextChallenge
* 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
+ * 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
+ * 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.
+ * 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
+ * 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
+ * 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);
+extern SECStatus
+CMMF_EncodeCertRepContent(CMMFCertRepContent *inCertRepContent,
+ CRMFEncoderOutputCallback inCallback,
+ void *inArg);
/*
* FUNCTION: CMMF_EncodeKeyRecRepContent
@@ -456,30 +454,30 @@ extern SECStatus
* 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
+ * 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
+ * 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.
+ * 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
+ * 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
+ * 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);
+CMMF_EncodeKeyRecRepContent(CMMFKeyRecRepContent *inKeyRecRep,
+ CRMFEncoderOutputCallback inCallback,
+ void *inArg);
/*
* FUNCTION: CMMF_EncodePOPODecKeyChallContent
@@ -487,19 +485,19 @@ extern SECStatus
* 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
+ * 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
+ * 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.
+ * 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
+ * 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
@@ -509,34 +507,34 @@ extern SECStatus
* SECSuccess if encoding was successful. Any other return value indicates
* an error in trying to encode the Challenges.
*/
-extern SECStatus
+extern SECStatus
CMMF_EncodePOPODecKeyChallContent(CMMFPOPODecKeyChallContent *inDecKeyChall,
- CRMFEncoderOutputCallback inCallback,
- void *inArg);
+ CRMFEncoderOutputCallback inCallback,
+ void *inArg);
/*
* FUNCTION: CMMF_EncodePOPODecKeyRespContent
* INPUTS:
* inDecodedRand
- * An array of integers to encode as the responses to
+ * 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
+ * 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
+ * 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.
+ * 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
+ * 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.
*
@@ -544,11 +542,11 @@ CMMF_EncodePOPODecKeyChallContent(CMMFPOPODecKeyChallContent *inDecKeyChall,
* 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);
+extern SECStatus
+CMMF_EncodePOPODecKeyRespContent(long *inDecodedRand,
+ int inNumRand,
+ CRMFEncoderOutputCallback inCallback,
+ void *inArg);
/*************** Accessor function ***********************************/
@@ -560,27 +558,26 @@ extern SECStatus
* 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.
+ * 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.
+ * 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
+ * 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
+ * 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.
+ * were available in the CMMFCertRepContent structure.
*/
-extern CERTCertList*
- CMMF_CertRepContentGetCAPubs (CMMFCertRepContent *inCertRepContent);
-
+extern CERTCertList *
+CMMF_CertRepContentGetCAPubs(CMMFCertRepContent *inCertRepContent);
/*
* FUNCTION: CMMF_CertRepContentGetNumResponses
@@ -590,12 +587,12 @@ extern CERTCertList*
* 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);
+extern int
+CMMF_CertRepContentGetNumResponses(CMMFCertRepContent *inCertRepContent);
/*
* FUNCTION: CMMF_CertRepContentGetResponseAtIndex
@@ -605,20 +602,20 @@ extern int
* inIndex
* The index of the CMMFCertResponse the user wants a copy of.
* NOTES:
- * This function creates a copy of the CMMFCertResponse at the index
+ * 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
+ * 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
+ * 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);
+extern CMMFCertResponse *
+CMMF_CertRepContentGetResponseAtIndex(CMMFCertRepContent *inCertRepContent,
+ int inIndex);
/*
* FUNCTION: CMMF_CertResponseGetCertReqId
@@ -626,11 +623,11 @@ CMMF_CertRepContentGetResponseAtIndex (CMMFCertRepContent *inCertRepContent,
* inCertResp
* The CMMFCertResponse to operate on.
* NOTES:
- * This function returns the CertResponse.certReqId from the
+ * 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
+ * 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.
*/
@@ -642,7 +639,7 @@ extern long CMMF_CertResponseGetCertReqId(CMMFCertResponse *inCertResp);
* inCertResp
* The CMMFCertResponse to operate on.
* NOTES:
- * This function returns the CertResponse.status.status field of the
+ * This function returns the CertResponse.status.status field of the
* CMMFCertResponse structure.
*
* RETURN:
@@ -650,8 +647,8 @@ extern long CMMF_CertResponseGetCertReqId(CMMFCertResponse *inCertResp);
* draft. See the CMMF draft for the definition of PKIStatus. See crmft.h
* for the definition of CMMFPKIStatus.
*/
-extern CMMFPKIStatus
- CMMF_CertResponseGetPKIStatusInfoStatus(CMMFCertResponse *inCertResp);
+extern CMMFPKIStatus
+CMMF_CertResponseGetPKIStatusInfoStatus(CMMFCertResponse *inCertResp);
/*
* FUNCTION: CMMF_CertResponseGetCertificate
@@ -664,18 +661,18 @@ extern CMMFPKIStatus
* 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
+ * 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
+ * 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);
+extern CERTCertificate *
+CMMF_CertResponseGetCertificate(CMMFCertResponse *inCertResp,
+ CERTCertDBHandle *inCertdb);
/*
* FUNCTION: CMMF_KeyRecRepContentGetPKIStatusInfoStatus
@@ -683,13 +680,13 @@ extern CERTCertificate*
* inKeyRecRep
* The CMMFKeyRecRepContent structure to operate on.
* NOTES:
- * This function retrieves the KeyRecRepContent.status.status field of
+ * This function retrieves the KeyRecRepContent.status.status field of
* the CMMFKeyRecRepContent structure.
* RETURN:
- * The CMMFPKIStatus corresponding to the value held in the
+ * The CMMFPKIStatus corresponding to the value held in the
* CMMFKeyRecRepContent structure.
*/
-extern CMMFPKIStatus
+extern CMMFPKIStatus
CMMF_KeyRecRepContentGetPKIStatusInfoStatus(CMMFKeyRecRepContent *inKeyRecRep);
/*
@@ -699,15 +696,15 @@ CMMF_KeyRecRepContentGetPKIStatusInfoStatus(CMMFKeyRecRepContent *inKeyRecRep);
* The CMMFKeyRecRepContent to operate on.
* NOTES:
* This function retrieves the KeyRecRepContent.newSignCert field of the
- * CMMFKeyRecRepContent structure. The user must call
+ * 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
+ * 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);
+extern CERTCertificate *
+CMMF_KeyRecRepContentGetNewSignCert(CMMFKeyRecRepContent *inKeyRecRep);
/*
* FUNCTION: CMMF_KeyRecRepContentGetCACerts
@@ -715,22 +712,22 @@ extern CERTCertificate*
* inKeyRecRep
* The CMMFKeyRecRepContent to operate on.
* NOTES:
- * This function returns a CERTCertList which contains all of the
+ * 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
+ * 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
+ * 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
+ * CMMF_KeyRecRepContentHasCACerts to find out if there are any caCerts
* included in 'inKeyRecRep'.
*/
-extern CERTCertList*
- CMMF_KeyRecRepContentGetCACerts(CMMFKeyRecRepContent *inKeyRecRep);
+extern CERTCertList *
+CMMF_KeyRecRepContentGetCACerts(CMMFKeyRecRepContent *inKeyRecRep);
/*
* FUNCTION: CMMF_KeyRecRepContentGetNumKeyPairs
@@ -741,8 +738,8 @@ extern CERTCertList*
* This function returns the number of CMMFCertifiedKeyPair structures that
* that are stored in the KeyRecRepContent structure.
*/
-extern int
- CMMF_KeyRecRepContentGetNumKeyPairs(CMMFKeyRecRepContent *inKeyRecRep);
+extern int
+CMMF_KeyRecRepContentGetNumKeyPairs(CMMFKeyRecRepContent *inKeyRecRep);
/*
* FUNCTION: CMMF_KeyRecRepContentGetCertKeyAtIndex
@@ -753,17 +750,17 @@ extern int
* 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
+ * '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
+ * of NULL indicates an error in extracting the Certified Key Pair at the
* desired index.
*/
-extern CMMFCertifiedKeyPair*
- CMMF_KeyRecRepContentGetCertKeyAtIndex(CMMFKeyRecRepContent *inKeyRecRep,
- int inIndex);
+extern CMMFCertifiedKeyPair *
+CMMF_KeyRecRepContentGetCertKeyAtIndex(CMMFKeyRecRepContent *inKeyRecRep,
+ int inIndex);
/*
* FUNCTION: CMMF_CertifiedKeyPairGetCertificate
@@ -774,21 +771,21 @@ extern CMMFCertifiedKeyPair*
* The database handle for the database you want this certificate
* to wind up in.
* NOTES:
- * This function retrieves the certificate at
+ * 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
+ * A return value of NULL indicates an error in creating the copy of the
* certificate.
*/
-extern CERTCertificate*
- CMMF_CertifiedKeyPairGetCertificate(CMMFCertifiedKeyPair *inCertKeyPair,
- CERTCertDBHandle *inCertdb);
+extern CERTCertificate *
+CMMF_CertifiedKeyPairGetCertificate(CMMFCertifiedKeyPair *inCertKeyPair,
+ CERTCertDBHandle *inCertdb);
/*
* FUNCTION: CMMF_POPODecKeyChallContentGetNumChallenges
@@ -796,11 +793,10 @@ extern CERTCertificate*
* inKeyChallCont
* The CMMFPOPODecKeyChallContent to operate on.
* RETURN:
- * This function returns the number of CMMFChallenges are contained in
+ * This function returns the number of CMMFChallenges are contained in
* the CMMFPOPODecKeyChallContent structure.
*/
-extern int CMMF_POPODecKeyChallContentGetNumChallenges
- (CMMFPOPODecKeyChallContent *inKeyChallCont);
+extern int CMMF_POPODecKeyChallContentGetNumChallenges(CMMFPOPODecKeyChallContent *inKeyChallCont);
/*
* FUNCTION: CMMF_POPODecKeyChallContentGetPublicValue
@@ -816,14 +812,12 @@ extern int CMMF_POPODecKeyChallContentGetNumChallenges
* 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
+ * 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);
-
+extern SECItem *CMMF_POPODecKeyChallContentGetPublicValue(CMMFPOPODecKeyChallContent *inKeyChallCont,
+ int inIndex);
/*
* FUNCTION: CMMF_POPODecKeyChallContentGetRandomNumber
@@ -839,9 +833,9 @@ extern SECItem* CMMF_POPODecKeyChallContentGetPublicValue
* 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
+ * 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:
@@ -850,10 +844,9 @@ extern SECItem* CMMF_POPODecKeyChallContentGetPublicValue
* 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);
+extern SECStatus CMMF_POPODecKeyChallContentGetRandomNumber(CMMFPOPODecKeyChallContent *inKeyChallCont,
+ int inIndex,
+ long *inDest);
/*
* FUNCTION: CMMF_POPODecKeyRespContentGetNumResponses
@@ -863,8 +856,8 @@ extern SECStatus CMMF_POPODecKeyChallContentGetRandomNumber
* RETURN:
* This function returns the number of responses contained in inRespContent.
*/
-extern int
- CMMF_POPODecKeyRespContentGetNumResponses(CMMFPOPODecKeyRespContent *inRespCont);
+extern int
+CMMF_POPODecKeyRespContentGetNumResponses(CMMFPOPODecKeyRespContent *inRespCont);
/*
* FUNCTION: CMMF_POPODecKeyRespContentGetResponse
@@ -876,22 +869,22 @@ extern int
* 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
+ * 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
+ * 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
+ * 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);
+CMMF_POPODecKeyRespContentGetResponse(CMMFPOPODecKeyRespContent *inRespCont,
+ int inIndex,
+ long *inDest);
/************************* Destructor Functions ******************************/
@@ -918,12 +911,12 @@ extern SECStatus CMMF_DestroyCertResponse(CMMFCertResponse *inCertResp);
* 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
+ * 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);
+extern SECStatus
+CMMF_DestroyCertRepContent(CMMFCertRepContent *inCertRepContent);
/*
* FUNCTION: CMMF_DestroyKeyRecRepContent
@@ -931,22 +924,22 @@ extern SECStatus
* inKeyRecRep
* The CMMFKeyRecRepContent to destroy.
* NOTES:
- * This function destroys all the memory associated with the
+ * This function destroys all the memory associated with the
* CMMFKeyRecRepContent passed in.
*
* RETURN:
- * SECSuccess if freeing all the memory is successful. Any other 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);
+extern SECStatus
+CMMF_DestroyKeyRecRepContent(CMMFKeyRecRepContent *inKeyRecRep);
/*
* FUNCTION: CMMF_DestroyCertifiedKeyPair
* INPUTS:
* inCertKeyPair
* The CMMFCertifiedKeyPair to operate on.
- * NOTES:
+ * NOTES:
* This function frees up all the memory associated with 'inCertKeyPair'
*
* RETURN:
@@ -954,8 +947,8 @@ extern SECStatus
* is successful. Any other return value indicates an error while trying
* to free the memory.
*/
-extern SECStatus
- CMMF_DestroyCertifiedKeyPair(CMMFCertifiedKeyPair *inCertKeyPair);
+extern SECStatus
+CMMF_DestroyCertifiedKeyPair(CMMFCertifiedKeyPair *inCertKeyPair);
/*
* FUNCTION: CMMF_DestroyPOPODecKeyRespContent
@@ -963,7 +956,7 @@ extern SECStatus
* inDecKeyResp
* The CMMFPOPODecKeyRespContent structure to free.
* NOTES:
- * This function frees up all the memory associate with the
+ * This function frees up all the memory associate with the
* CMMFPOPODecKeyRespContent.
*
* RETURN:
@@ -972,11 +965,10 @@ extern SECStatus
* return value indicates an error while freeing the memory.
*/
extern SECStatus
- CMMF_DestroyPOPODecKeyRespContent(CMMFPOPODecKeyRespContent *inDecKeyResp);
-
+CMMF_DestroyPOPODecKeyRespContent(CMMFPOPODecKeyRespContent *inDecKeyResp);
/************************** Miscellaneous Functions *************************/
-
+
/*
* FUNCTION: CMMF_CertifiedKeyPairUnwrapPrivKey
* INPUTS:
@@ -997,25 +989,25 @@ extern SECStatus
* 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
+ * contained within the CMMFCertifiedKeyPair structure. After this
* function successfully returns, the private key has been unwrapped and
- * placed in the specified slot.
+ * placed in the specified slot.
*
* RETURN:
- * SECSuccess if unwrapping the private key was successful. Any other
+ * 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);
+extern SECStatus
+CMMF_CertifiedKeyPairUnwrapPrivKey(CMMFCertifiedKeyPair *inKeyPair,
+ SECKEYPrivateKey *inPrivKey,
+ SECItem *inNickName,
+ PK11SlotInfo *inSlot,
+ CERTCertDBHandle *inCertdb,
+ SECKEYPrivateKey **destPrivKey,
+ void *wincx);
/*
* FUNCTION: CMMF_KeyRecRepContentHasCACerts
@@ -1023,13 +1015,13 @@ extern SECStatus
* inKeyRecRecp
* The CMMFKeyRecRepContent to operate on.
* RETURN:
- * This function returns PR_TRUE if there are one or more certificates in
+ * 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);
+extern PRBool
+CMMF_KeyRecRepContentHasCACerts(CMMFKeyRecRepContent *inKeyRecRep);
/*
* FUNCTION: CMMF_POPODecKeyChallContDecryptChallenge
@@ -1043,12 +1035,12 @@ extern PRBool
* 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
+ * 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
+ * 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
@@ -1057,17 +1049,17 @@ extern PRBool
*
* 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
+ * 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);
+extern SECStatus
+CMMF_POPODecKeyChallContDecryptChallenge(CMMFPOPODecKeyChallContent *inChalCont,
+ int inIndex,
+ SECKEYPrivateKey *inPrivKey);
/*
* FUNCTION: CMMF_DestroyPOPODecKeyChallContent
@@ -1075,16 +1067,16 @@ extern SECStatus
* inDecKeyCont
* The CMMFPOPODecKeyChallContent to free
* NOTES:
- * This function frees up all the memory associated with the
- * CMMFPOPODecKeyChallContent
+ * This function frees up all the memory associated with the
+ * CMMFPOPODecKeyChallContent
* RETURN:
- * SECSuccess if freeing up all the memory associatd with the
+ * 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);
+extern SECStatus
+CMMF_DestroyPOPODecKeyChallContent(CMMFPOPODecKeyChallContent *inDecKeyCont);
SEC_END_PROTOS
#endif /* _CMMF_H_ */
diff --git a/nss/lib/crmf/cmmfasn1.c b/nss/lib/crmf/cmmfasn1.c
index 711d4ab..64915b3 100644
--- a/nss/lib/crmf/cmmfasn1.c
+++ b/nss/lib/crmf/cmmfasn1.c
@@ -11,50 +11,50 @@
SEC_ASN1_MKSUB(SEC_SignedCertificateTemplate)
static const SEC_ASN1Template CMMFSequenceOfCertifiedKeyPairsTemplate[] = {
- { SEC_ASN1_SEQUENCE_OF, 0, CMMFCertifiedKeyPairTemplate}
+ { 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,
+ { 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_SUB(SEC_SignedCertificateTemplate) },
{ SEC_ASN1_CONSTRUCTED | SEC_ASN1_OPTIONAL | SEC_ASN1_CONTEXT_SPECIFIC | 1,
offsetof(CMMFKeyRecRepContent, caCerts),
- CMMFSequenceOfCertsTemplate},
+ CMMFSequenceOfCertsTemplate },
{ SEC_ASN1_CONSTRUCTED | SEC_ASN1_OPTIONAL | SEC_ASN1_CONTEXT_SPECIFIC | 2,
offsetof(CMMFKeyRecRepContent, keyPairHist),
- CMMFSequenceOfCertifiedKeyPairsTemplate},
+ CMMFSequenceOfCertifiedKeyPairsTemplate },
{ 0 }
};
SECStatus
-CMMF_EncodeCertRepContent (CMMFCertRepContent *inCertRepContent,
- CRMFEncoderOutputCallback inCallback,
- void *inArg)
+CMMF_EncodeCertRepContent(CMMFCertRepContent *inCertRepContent,
+ CRMFEncoderOutputCallback inCallback,
+ void *inArg)
{
return cmmf_user_encode(inCertRepContent, inCallback, inArg,
- CMMFCertRepContentTemplate);
+ CMMFCertRepContentTemplate);
}
SECStatus
CMMF_EncodePOPODecKeyChallContent(CMMFPOPODecKeyChallContent *inDecKeyChall,
- CRMFEncoderOutputCallback inCallback,
- void *inArg)
+ CRMFEncoderOutputCallback inCallback,
+ void *inArg)
{
return cmmf_user_encode(inDecKeyChall, inCallback, inArg,
- CMMFPOPODecKeyChallContentTemplate);
+ CMMFPOPODecKeyChallContentTemplate);
}
-CMMFPOPODecKeyRespContent*
+CMMFPOPODecKeyRespContent *
CMMF_CreatePOPODecKeyRespContentFromDER(const char *buf, long len)
{
- PLArenaPool *poolp;
+ PLArenaPool *poolp;
CMMFPOPODecKeyRespContent *decKeyResp;
- SECStatus rv;
+ SECStatus rv;
poolp = PORT_NewArena(CRMF_DEFAULT_ARENA_SIZE);
if (poolp == NULL) {
@@ -66,13 +66,13 @@ CMMF_CreatePOPODecKeyRespContentFromDER(const char *buf, long len)
}
decKeyResp->poolp = poolp;
rv = SEC_ASN1Decode(poolp, decKeyResp, CMMFPOPODecKeyRespContentTemplate,
- buf, len);
+ buf, len);
if (rv != SECSuccess) {
goto loser;
}
return decKeyResp;
-
- loser:
+
+loser:
if (poolp != NULL) {
PORT_FreeArena(poolp, PR_FALSE);
}
@@ -80,21 +80,21 @@ CMMF_CreatePOPODecKeyRespContentFromDER(const char *buf, long len)
}
SECStatus
-CMMF_EncodeKeyRecRepContent(CMMFKeyRecRepContent *inKeyRecRep,
- CRMFEncoderOutputCallback inCallback,
- void *inArg)
+CMMF_EncodeKeyRecRepContent(CMMFKeyRecRepContent *inKeyRecRep,
+ CRMFEncoderOutputCallback inCallback,
+ void *inArg)
{
return cmmf_user_encode(inKeyRecRep, inCallback, inArg,
- CMMFKeyRecRepContentTemplate);
+ CMMFKeyRecRepContentTemplate);
}
-CMMFKeyRecRepContent*
-CMMF_CreateKeyRecRepContentFromDER(CERTCertDBHandle *db, const char *buf,
- long len)
+CMMFKeyRecRepContent *
+CMMF_CreateKeyRecRepContentFromDER(CERTCertDBHandle *db, const char *buf,
+ long len)
{
- PLArenaPool *poolp;
+ PLArenaPool *poolp;
CMMFKeyRecRepContent *keyRecContent;
- SECStatus rv;
+ SECStatus rv;
poolp = PORT_NewArena(CRMF_DEFAULT_ARENA_SIZE);
if (poolp == NULL) {
@@ -106,27 +106,26 @@ CMMF_CreateKeyRecRepContentFromDER(CERTCertDBHandle *db, const char *buf,
}
keyRecContent->poolp = poolp;
rv = SEC_ASN1Decode(poolp, keyRecContent, CMMFKeyRecRepContentTemplate,
- buf, len);
+ 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;
+ 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:
+loser:
if (poolp != NULL) {
PORT_FreeArena(poolp, PR_FALSE);
}
return NULL;
}
-
diff --git a/nss/lib/crmf/cmmfchal.c b/nss/lib/crmf/cmmfchal.c
index bf0b7ba..2fee983 100644
--- a/nss/lib/crmf/cmmfchal.c
+++ b/nss/lib/crmf/cmmfchal.c
@@ -14,51 +14,52 @@
#include "keyhi.h"
static int
-cmmf_create_witness_and_challenge(PLArenaPool *poolp,
- CMMFChallenge *challenge,
- long inRandom,
- SECItem *senderDER,
- SECKEYPublicKey *inPubKey,
- void *passwdArg)
+cmmf_create_witness_and_challenge(PLArenaPool *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;
+ 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;
CERTSubjectPublicKeyInfo *spki = NULL;
-
encodedRandNum = SEC_ASN1EncodeInteger(poolp, &challenge->randomNumber,
- inRandom);
- encodedRandNum = &challenge->randomNumber;
- randHash = PORT_ArenaNewArray(poolp, unsigned char, SHA1_LENGTH);
+ inRandom);
+ if (!encodedRandNum) {
+ goto loser;
+ }
+ 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);
+ 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);
+ (PRUint32)senderDER->len);
if (rv != SECSuccess) {
goto loser;
}
challenge->witness.data = randHash;
- challenge->witness.len = SHA1_LENGTH;
+ challenge->witness.len = SHA1_LENGTH;
- randStr.integer = *encodedRandNum;
+ randStr.integer = *encodedRandNum;
randStr.senderHash.data = senderHash;
- randStr.senderHash.len = SHA1_LENGTH;
- dummy = SEC_ASN1EncodeItem(NULL, &encodedRandStr, &randStr,
- CMMFRandTemplate);
+ randStr.senderHash.len = SHA1_LENGTH;
+ dummy = SEC_ASN1EncodeItem(NULL, &encodedRandStr, &randStr,
+ CMMFRandTemplate);
if (dummy != &encodedRandStr) {
rv = SECFailure;
goto loser;
@@ -70,7 +71,7 @@ cmmf_create_witness_and_challenge(PLArenaPool *poolp,
rv = SECFailure;
goto loser;
}
- slot =PK11_GetBestSlotWithAttributes(CKM_RSA_PKCS, CKF_WRAP, 0, passwdArg);
+ slot = PK11_GetBestSlotWithAttributes(CKM_RSA_PKCS, CKF_WRAP, 0, passwdArg);
if (slot == NULL) {
rv = SECFailure;
goto loser;
@@ -83,23 +84,23 @@ cmmf_create_witness_and_challenge(PLArenaPool *poolp,
* the PK11 libraries depend on.
*/
symKey = PK11_ImportSymKey(slot, CKM_RSA_PKCS, PK11_OriginGenerated,
- CKA_VALUE, &encodedRandStr, passwdArg);
+ CKA_VALUE, &encodedRandStr, passwdArg);
if (symKey == NULL) {
rv = SECFailure;
- goto loser;
+ goto loser;
}
challenge->challenge.data = encChal;
- challenge->challenge.len = modulusLen;
- rv = PK11_PubWrapSymKey(CKM_RSA_PKCS, inPubKey, symKey,
- &challenge->challenge);
+ challenge->challenge.len = modulusLen;
+ rv = PK11_PubWrapSymKey(CKM_RSA_PKCS, inPubKey, symKey,
+ &challenge->challenge);
PK11_FreeSlot(slot);
if (rv != SECSuccess) {
- goto loser;
+ goto loser;
}
rv = SECITEM_CopyItem(poolp, &challenge->senderDER, senderDER);
crmf_get_public_value(inPubKey, &challenge->key);
- /* Fall through */
- loser:
+/* Fall through */
+loser:
if (spki != NULL) {
SECKEY_DestroySubjectPublicKeyInfo(spki);
}
@@ -116,17 +117,17 @@ cmmf_create_witness_and_challenge(PLArenaPool *poolp,
}
static SECStatus
-cmmf_create_first_challenge(CMMFPOPODecKeyChallContent *challContent,
- long inRandom,
- SECItem *senderDER,
- SECKEYPublicKey *inPubKey,
- void *passwdArg)
+cmmf_create_first_challenge(CMMFPOPODecKeyChallContent *challContent,
+ long inRandom,
+ SECItem *senderDER,
+ SECKEYPublicKey *inPubKey,
+ void *passwdArg)
{
- SECOidData *oidData;
- CMMFChallenge *challenge;
+ SECOidData *oidData;
+ CMMFChallenge *challenge;
SECAlgorithmID *algId;
- PLArenaPool *poolp;
- SECStatus rv;
+ PLArenaPool *poolp;
+ SECStatus rv;
oidData = SECOID_FindOIDByTag(SEC_OID_SHA1);
if (oidData == NULL) {
@@ -145,15 +146,15 @@ cmmf_create_first_challenge(CMMFPOPODecKeyChallContent *challContent,
if (rv != SECSuccess) {
return SECFailure;
}
- rv = cmmf_create_witness_and_challenge(poolp, challenge, inRandom,
- senderDER, inPubKey, passwdArg);
+ rv = cmmf_create_witness_and_challenge(poolp, challenge, inRandom,
+ senderDER, inPubKey, passwdArg);
challContent->challenges[0] = (rv == SECSuccess) ? challenge : NULL;
challContent->numChallenges++;
- return rv ;
+ return rv;
}
-CMMFPOPODecKeyChallContent*
-CMMF_CreatePOPODecKeyChallContent (void)
+CMMFPOPODecKeyChallContent *
+CMMF_CreatePOPODecKeyChallContent(void)
{
PLArenaPool *poolp;
CMMFPOPODecKeyChallContent *challContent;
@@ -165,32 +166,31 @@ CMMF_CreatePOPODecKeyChallContent (void)
challContent = PORT_ArenaZNew(poolp, CMMFPOPODecKeyChallContent);
if (challContent == NULL) {
PORT_FreeArena(poolp, PR_FALSE);
- return NULL;
+ return NULL;
}
challContent->poolp = poolp;
return challContent;
}
SECStatus
-CMMF_POPODecKeyChallContentSetNextChallenge
- (CMMFPOPODecKeyChallContent *inDecKeyChall,
- long inRandom,
- CERTGeneralName *inSender,
- SECKEYPublicKey *inPubKey,
- void *passwdArg)
+CMMF_POPODecKeyChallContentSetNextChallenge(CMMFPOPODecKeyChallContent *inDecKeyChall,
+ long inRandom,
+ CERTGeneralName *inSender,
+ SECKEYPublicKey *inPubKey,
+ void *passwdArg)
{
- CMMFChallenge *curChallenge;
- PLArenaPool *genNamePool = NULL, *poolp;
- SECStatus rv;
- SECItem *genNameDER;
- void *mark;
+ CMMFChallenge *curChallenge;
+ PLArenaPool *genNamePool = NULL, *poolp;
+ SECStatus rv;
+ SECItem *genNameDER;
+ void *mark;
- PORT_Assert (inDecKeyChall != NULL &&
- inSender != NULL &&
- inPubKey != NULL);
+ PORT_Assert(inDecKeyChall != NULL &&
+ inSender != NULL &&
+ inPubKey != NULL);
- if (inDecKeyChall == NULL ||
- inSender == NULL || inPubKey == NULL) {
+ if (inDecKeyChall == NULL ||
+ inSender == NULL || inPubKey == NULL) {
return SECFailure;
}
poolp = inDecKeyChall->poolp;
@@ -204,8 +204,8 @@ CMMF_POPODecKeyChallContentSetNextChallenge
}
if (inDecKeyChall->challenges == NULL) {
inDecKeyChall->challenges =
- PORT_ArenaZNewArray(poolp, CMMFChallenge*,(CMMF_MAX_CHALLENGES+1));
- inDecKeyChall->numAllocated = CMMF_MAX_CHALLENGES;
+ PORT_ArenaZNewArray(poolp, CMMFChallenge *, (CMMF_MAX_CHALLENGES + 1));
+ inDecKeyChall->numAllocated = CMMF_MAX_CHALLENGES;
}
if (inDecKeyChall->numChallenges >= inDecKeyChall->numAllocated) {
@@ -214,22 +214,22 @@ CMMF_POPODecKeyChallContentSetNextChallenge
}
if (inDecKeyChall->numChallenges == 0) {
- rv = cmmf_create_first_challenge(inDecKeyChall, inRandom,
- genNameDER, inPubKey, passwdArg);
+ 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 (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;
@@ -238,7 +238,7 @@ CMMF_POPODecKeyChallContentSetNextChallenge
PORT_FreeArena(genNamePool, PR_FALSE);
return SECSuccess;
- loser:
+loser:
PORT_ArenaRelease(poolp, mark);
if (genNamePool != NULL) {
PORT_FreeArena(genNamePool, PR_FALSE);
@@ -257,7 +257,7 @@ CMMF_DestroyPOPODecKeyRespContent(CMMFPOPODecKeyRespContent *inDecKeyResp)
return SECSuccess;
}
-int
+int
CMMF_POPODecKeyRespContentGetNumResponses(CMMFPOPODecKeyRespContent *inRespCont)
{
int numResponses = 0;
@@ -268,20 +268,20 @@ CMMF_POPODecKeyRespContentGetNumResponses(CMMFPOPODecKeyRespContent *inRespCont)
}
while (inRespCont->responses[numResponses] != NULL) {
- numResponses ++;
+ numResponses++;
}
return numResponses;
}
SECStatus
-CMMF_POPODecKeyRespContentGetResponse (CMMFPOPODecKeyRespContent *inRespCont,
- int inIndex,
- long *inDest)
+CMMF_POPODecKeyRespContentGetResponse(CMMFPOPODecKeyRespContent *inRespCont,
+ int inIndex,
+ long *inDest)
{
PORT_Assert(inRespCont != NULL);
-
- if (inRespCont == NULL || inIndex < 0 ||
- inIndex >= CMMF_POPODecKeyRespContentGetNumResponses(inRespCont)) {
+
+ if (inRespCont == NULL || inIndex < 0 ||
+ inIndex >= CMMF_POPODecKeyRespContentGetNumResponses(inRespCont)) {
return SECFailure;
}
*inDest = DER_GetInteger(inRespCont->responses[inIndex]);
diff --git a/nss/lib/crmf/cmmfi.h b/nss/lib/crmf/cmmfi.h
index bfe3cb0..9336ccf 100644
--- a/nss/lib/crmf/cmmfi.h
+++ b/nss/lib/crmf/cmmfi.h
@@ -14,7 +14,7 @@
#include "crmfi.h"
#define CMMF_MAX_CHALLENGES 10
-#define CMMF_MAX_KEY_PAIRS 50
+#define CMMF_MAX_KEY_PAIRS 50
/*
* Some templates that the code will need to implement CMMF.
@@ -27,72 +27,66 @@ 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
+ * Some utility functions that are shared by multiple files in this
* implementation.
*/
-extern SECStatus cmmf_CopyCertResponse (PLArenaPool *poolp,
- CMMFCertResponse *dest,
- CMMFCertResponse *src);
+extern SECStatus cmmf_CopyCertResponse(PLArenaPool *poolp,
+ CMMFCertResponse *dest,
+ CMMFCertResponse *src);
-extern SECStatus cmmf_CopyPKIStatusInfo (PLArenaPool *poolp,
- CMMFPKIStatusInfo *dest,
- CMMFPKIStatusInfo *src);
+extern SECStatus cmmf_CopyPKIStatusInfo(PLArenaPool *poolp,
+ CMMFPKIStatusInfo *dest,
+ CMMFPKIStatusInfo *src);
-extern SECStatus cmmf_CopyCertifiedKeyPair(PLArenaPool *poolp,
- CMMFCertifiedKeyPair *dest,
- CMMFCertifiedKeyPair *src);
+extern SECStatus cmmf_CopyCertifiedKeyPair(PLArenaPool *poolp,
+ CMMFCertifiedKeyPair *dest,
+ CMMFCertifiedKeyPair *src);
-extern SECStatus cmmf_DestroyPKIStatusInfo(CMMFPKIStatusInfo *info,
- PRBool freeit);
+extern SECStatus cmmf_DestroyPKIStatusInfo(CMMFPKIStatusInfo *info,
+ PRBool freeit);
-extern SECStatus cmmf_DestroyCertOrEncCert(CMMFCertOrEncCert *certOrEncCert,
- PRBool freeit);
+extern SECStatus cmmf_DestroyCertOrEncCert(CMMFCertOrEncCert *certOrEncCert,
+ PRBool freeit);
-extern SECStatus cmmf_PKIStatusInfoSetStatus(CMMFPKIStatusInfo *statusInfo,
- PLArenaPool *poolp,
- CMMFPKIStatus inStatus);
+extern SECStatus cmmf_PKIStatusInfoSetStatus(CMMFPKIStatusInfo *statusInfo,
+ PLArenaPool *poolp,
+ CMMFPKIStatus inStatus);
-extern SECStatus cmmf_ExtractCertsFromList(CERTCertList *inCertList,
- PLArenaPool *poolp,
- CERTCertificate ***certArray);
+extern SECStatus cmmf_ExtractCertsFromList(CERTCertList *inCertList,
+ PLArenaPool *poolp,
+ CERTCertificate ***certArray);
-extern SECStatus
- cmmf_CertOrEncCertSetCertificate(CMMFCertOrEncCert *certOrEncCert,
- PLArenaPool *poolp,
- CERTCertificate *inCert);
+extern SECStatus
+cmmf_CertOrEncCertSetCertificate(CMMFCertOrEncCert *certOrEncCert,
+ PLArenaPool *poolp,
+ CERTCertificate *inCert);
-extern CMMFPKIStatus
- cmmf_PKIStatusInfoGetStatus(CMMFPKIStatusInfo *inStatus);
+extern CMMFPKIStatus
+cmmf_PKIStatusInfoGetStatus(CMMFPKIStatusInfo *inStatus);
-extern CERTCertList*
- cmmf_MakeCertList(CERTCertificate **inCerts);
+extern CERTCertList *
+cmmf_MakeCertList(CERTCertificate **inCerts);
-extern CERTCertificate*
+extern CERTCertificate *
cmmf_CertOrEncCertGetCertificate(CMMFCertOrEncCert *certOrEncCert,
- CERTCertDBHandle *certdb);
+ CERTCertDBHandle *certdb);
extern SECStatus
-cmmf_decode_process_cert_response(PLArenaPool *poolp,
- CERTCertDBHandle *db,
- CMMFCertResponse *inCertResp);
+cmmf_decode_process_cert_response(PLArenaPool *poolp,
+ CERTCertDBHandle *db,
+ CMMFCertResponse *inCertResp);
extern SECStatus
-cmmf_decode_process_certified_key_pair(PLArenaPool *poolp,
- CERTCertDBHandle *db,
- CMMFCertifiedKeyPair *inCertKeyPair);
+cmmf_decode_process_certified_key_pair(PLArenaPool *poolp,
+ CERTCertDBHandle *db,
+ CMMFCertifiedKeyPair *inCertKeyPair);
extern SECStatus
cmmf_user_encode(void *src, CRMFEncoderOutputCallback inCallback, void *inArg,
- const SEC_ASN1Template *inTemplate);
+ const SEC_ASN1Template *inTemplate);
extern SECStatus
-cmmf_copy_secitem (PLArenaPool *poolp, SECItem *dest, SECItem *src);
+cmmf_copy_secitem(PLArenaPool *poolp, SECItem *dest, SECItem *src);
#endif /*_CMMFI_H_*/
-
-
-
-
-
diff --git a/nss/lib/crmf/cmmfit.h b/nss/lib/crmf/cmmfit.h
index 84f81c3..014413f 100644
--- a/nss/lib/crmf/cmmfit.h
+++ b/nss/lib/crmf/cmmfit.h
@@ -14,23 +14,23 @@
* ------------- -------
* 0 granted- got exactly what you asked for.
*
- * 1 grantedWithMods-got something like what you asked
+ * 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
+ * 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
+ * 3 waiting-the request body part has not yet been
* processed, expect to hear more later.
*
- * 4 revocationWarning-this message contains a warning
+ * 4 revocationWarning-this message contains a warning
* that a revocation is imminent.
*
- * 5 revocationNotification-notification that a
+ * 5 revocationNotification-notification that a
* revocation has occurred.
*
- * 6 keyUpdateWarning-update already done for the
+ * 6 keyUpdateWarning-update already done for the
* oldCertId specified in FullCertTemplate.
*/
@@ -41,76 +41,75 @@ struct CMMFPKIStatusInfoStr {
};
struct CMMFCertOrEncCertStr {
- union {
- CERTCertificate *certificate;
+ union {
+ CERTCertificate *certificate;
CRMFEncryptedValue *encryptedCert;
} cert;
CMMFCertOrEncCertChoice choice;
- SECItem derValue;
+ SECItem derValue;
};
struct CMMFCertifiedKeyPairStr {
- CMMFCertOrEncCert certOrEncCert;
+ 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 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*/
+ SECItem certReqId;
+ CMMFPKIStatusInfo status; /*PKIStatusInfo*/
CMMFCertifiedKeyPair *certifiedKeyPair;
};
struct CMMFCertRepContentStr {
- CERTCertificate **caPubs;
+ CERTCertificate **caPubs;
CMMFCertResponse **response;
- PLArenaPool *poolp;
- PRBool isDecoded;
+ PLArenaPool *poolp;
+ PRBool isDecoded;
};
struct CMMFChallengeStr {
- SECAlgorithmID *owf;
- SECItem witness;
- SECItem senderDER;
- SECItem key;
- SECItem challenge;
- SECItem randomNumber;
+ SECAlgorithmID *owf;
+ SECItem witness;
+ SECItem senderDER;
+ SECItem key;
+ SECItem challenge;
+ SECItem randomNumber;
};
struct CMMFRandStr {
- SECItem integer;
- SECItem senderHash;
+ SECItem integer;
+ SECItem senderHash;
CERTGeneralName *sender;
};
struct CMMFPOPODecKeyChallContentStr {
CMMFChallenge **challenges;
- PLArenaPool *poolp;
- int numChallenges;
- int numAllocated;
+ PLArenaPool *poolp;
+ int numChallenges;
+ int numAllocated;
};
struct CMMFPOPODecKeyRespContentStr {
- SECItem **responses;
- PLArenaPool *poolp;
+ SECItem **responses;
+ PLArenaPool *poolp;
};
struct CMMFKeyRecRepContentStr {
- CMMFPKIStatusInfo status; /* PKIStatusInfo */
- CERTCertificate *newSigCert;
- CERTCertificate **caCerts;
+ CMMFPKIStatusInfo status; /* PKIStatusInfo */
+ CERTCertificate *newSigCert;
+ CERTCertificate **caCerts;
CMMFCertifiedKeyPair **keyPairHist;
- PLArenaPool *poolp;
- int numKeyPairs;
- int allocKeyPairs;
- PRBool isDecoded;
+ PLArenaPool *poolp;
+ int numKeyPairs;
+ int allocKeyPairs;
+ PRBool isDecoded;
};
#endif /* _CMMFIT_H_ */
-
diff --git a/nss/lib/crmf/cmmfrec.c b/nss/lib/crmf/cmmfrec.c
index 880e846..5dfe1fc 100644
--- a/nss/lib/crmf/cmmfrec.c
+++ b/nss/lib/crmf/cmmfrec.c
@@ -4,7 +4,7 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
/*
- * This file will implement the functions related to key recovery in
+ * This file will implement the functions related to key recovery in
* CMMF
*/
@@ -13,10 +13,10 @@
#include "secitem.h"
#include "keyhi.h"
-CMMFKeyRecRepContent*
+CMMFKeyRecRepContent *
CMMF_CreateKeyRecRepContent(void)
{
- PLArenaPool *poolp;
+ PLArenaPool *poolp;
CMMFKeyRecRepContent *keyRecContent;
poolp = PORT_NewArena(CRMF_DEFAULT_ARENA_SIZE);
@@ -26,7 +26,7 @@ CMMF_CreateKeyRecRepContent(void)
keyRecContent = PORT_ArenaZNew(poolp, CMMFKeyRecRepContent);
if (keyRecContent == NULL) {
PORT_FreeArena(poolp, PR_FALSE);
- return NULL;
+ return NULL;
}
keyRecContent->poolp = poolp;
return keyRecContent;
@@ -37,25 +37,24 @@ CMMF_DestroyKeyRecRepContent(CMMFKeyRecRepContent *inKeyRecRep)
{
PORT_Assert(inKeyRecRep != NULL);
if (inKeyRecRep != NULL && inKeyRecRep->poolp != NULL) {
- int i;
+ 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);
- }
- }
- }
+ 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;
@@ -63,49 +62,49 @@ CMMF_DestroyKeyRecRepContent(CMMFKeyRecRepContent *inKeyRecRep)
SECStatus
CMMF_KeyRecRepContentSetPKIStatusInfoStatus(CMMFKeyRecRepContent *inKeyRecRep,
- CMMFPKIStatus inPKIStatus)
+ CMMFPKIStatus inPKIStatus)
{
PORT_Assert(inKeyRecRep != NULL && inPKIStatus >= cmmfGranted &&
- inPKIStatus < cmmfNumPKIStatus);
+ inPKIStatus < cmmfNumPKIStatus);
if (inKeyRecRep == NULL) {
return SECFailure;
}
-
- return cmmf_PKIStatusInfoSetStatus(&inKeyRecRep->status,
- inKeyRecRep->poolp,
- inPKIStatus);
+
+ return cmmf_PKIStatusInfoSetStatus(&inKeyRecRep->status,
+ inKeyRecRep->poolp,
+ inPKIStatus);
}
SECStatus
CMMF_KeyRecRepContentSetNewSignCert(CMMFKeyRecRepContent *inKeyRecRep,
- CERTCertificate *inNewSignCert)
+ CERTCertificate *inNewSignCert)
{
- PORT_Assert (inKeyRecRep != NULL && inNewSignCert != NULL);
+ PORT_Assert(inKeyRecRep != NULL && inNewSignCert != NULL);
if (inKeyRecRep == NULL || inNewSignCert == NULL) {
return SECFailure;
}
if (!inKeyRecRep->isDecoded && inKeyRecRep->newSigCert) {
- CERT_DestroyCertificate(inKeyRecRep->newSigCert);
+ CERT_DestroyCertificate(inKeyRecRep->newSigCert);
}
inKeyRecRep->isDecoded = PR_FALSE;
inKeyRecRep->newSigCert = CERT_DupCertificate(inNewSignCert);
- return (inKeyRecRep->newSigCert == NULL) ? SECFailure : SECSuccess;
+ return (inKeyRecRep->newSigCert == NULL) ? SECFailure : SECSuccess;
}
SECStatus
CMMF_KeyRecRepContentSetCACerts(CMMFKeyRecRepContent *inKeyRecRep,
- CERTCertList *inCACerts)
+ CERTCertList *inCACerts)
{
SECStatus rv;
void *mark;
- PORT_Assert (inKeyRecRep != NULL && inCACerts != NULL);
+ 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);
+ &inKeyRecRep->caCerts);
if (rv != SECSuccess) {
PORT_ArenaRelease(inKeyRecRep->poolp, mark);
} else {
@@ -116,49 +115,49 @@ CMMF_KeyRecRepContentSetCACerts(CMMFKeyRecRepContent *inKeyRecRep,
SECStatus
CMMF_KeyRecRepContentSetCertifiedKeyPair(CMMFKeyRecRepContent *inKeyRecRep,
- CERTCertificate *inCert,
- SECKEYPrivateKey *inPrivKey,
- SECKEYPublicKey *inPubKey)
+ CERTCertificate *inCert,
+ SECKEYPrivateKey *inPrivKey,
+ SECKEYPublicKey *inPubKey)
{
CMMFCertifiedKeyPair *keyPair;
- CRMFEncryptedValue *dummy;
- PLArenaPool *poolp;
- void *mark;
- SECStatus rv;
+ CRMFEncryptedValue *dummy;
+ PLArenaPool *poolp;
+ void *mark;
+ SECStatus rv;
- PORT_Assert (inKeyRecRep != NULL &&
- inCert != NULL &&
- inPrivKey != NULL &&
- inPubKey != NULL);
+ PORT_Assert(inKeyRecRep != NULL &&
+ inCert != NULL &&
+ inPrivKey != NULL &&
+ inPubKey != NULL);
if (inKeyRecRep == NULL ||
- inCert == NULL ||
- inPrivKey == NULL ||
- inPubKey == 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;
+ 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);
+ poolp, inCert);
if (rv != SECSuccess) {
goto loser;
}
@@ -166,12 +165,12 @@ CMMF_KeyRecRepContentSetCertifiedKeyPair(CMMFKeyRecRepContent *inKeyRecRep,
if (keyPair->privateKey == NULL) {
goto loser;
}
- dummy = crmf_create_encrypted_value_wrapped_privkey(inPrivKey, inPubKey,
- keyPair->privateKey);
+ 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;
+ goto loser;
}
inKeyRecRep->keyPairHist[inKeyRecRep->numKeyPairs] = keyPair;
inKeyRecRep->numKeyPairs++;
@@ -179,7 +178,7 @@ CMMF_KeyRecRepContentSetCertifiedKeyPair(CMMFKeyRecRepContent *inKeyRecRep,
PORT_ArenaUnmark(poolp, mark);
return SECSuccess;
- loser:
+loser:
PORT_ArenaRelease(poolp, mark);
return SECFailure;
}
@@ -194,12 +193,12 @@ CMMF_KeyRecRepContentGetPKIStatusInfoStatus(CMMFKeyRecRepContent *inKeyRecRep)
return cmmf_PKIStatusInfoGetStatus(&inKeyRecRep->status);
}
-CERTCertificate*
+CERTCertificate *
CMMF_KeyRecRepContentGetNewSignCert(CMMFKeyRecRepContent *inKeyRecRep)
{
PORT_Assert(inKeyRecRep != NULL);
- if (inKeyRecRep == NULL ||
- inKeyRecRep->newSigCert == NULL) {
+ if (inKeyRecRep == NULL ||
+ inKeyRecRep->newSigCert == NULL) {
return NULL;
}
/* newSigCert may not be a real certificate, it may be a hand decoded
@@ -208,12 +207,12 @@ CMMF_KeyRecRepContentGetNewSignCert(CMMFKeyRecRepContent *inKeyRecRep)
* 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);
+ return CERT_NewTempCertificate(CERT_GetDefaultCertDB(),
+ &inKeyRecRep->newSigCert->signatureWrap.data,
+ NULL, PR_FALSE, PR_TRUE);
}
-CERTCertList*
+CERTCertList *
CMMF_KeyRecRepContentGetCACerts(CMMFKeyRecRepContent *inKeyRecRep)
{
PORT_Assert(inKeyRecRep != NULL);
@@ -223,7 +222,7 @@ CMMF_KeyRecRepContentGetCACerts(CMMFKeyRecRepContent *inKeyRecRep)
return cmmf_MakeCertList(inKeyRecRep->caCerts);
}
-int
+int
CMMF_KeyRecRepContentGetNumKeyPairs(CMMFKeyRecRepContent *inKeyRecRep)
{
PORT_Assert(inKeyRecRep != NULL);
@@ -232,87 +231,86 @@ CMMF_KeyRecRepContentGetNumKeyPairs(CMMFKeyRecRepContent *inKeyRecRep)
PRBool
cmmf_KeyRecRepContentIsValidIndex(CMMFKeyRecRepContent *inKeyRecRep,
- int inIndex)
+ int inIndex)
{
int numKeyPairs = CMMF_KeyRecRepContentGetNumKeyPairs(inKeyRecRep);
-
+
return (PRBool)(inIndex >= 0 && inIndex < numKeyPairs);
}
-CMMFCertifiedKeyPair*
+CMMFCertifiedKeyPair *
CMMF_KeyRecRepContentGetCertKeyAtIndex(CMMFKeyRecRepContent *inKeyRecRep,
- int inIndex)
+ int inIndex)
{
CMMFCertifiedKeyPair *newKeyPair;
- SECStatus rv;
+ SECStatus rv;
PORT_Assert(inKeyRecRep != NULL &&
- cmmf_KeyRecRepContentIsValidIndex(inKeyRecRep, inIndex));
+ cmmf_KeyRecRepContentIsValidIndex(inKeyRecRep, inIndex));
if (inKeyRecRep == NULL ||
- !cmmf_KeyRecRepContentIsValidIndex(inKeyRecRep, inIndex)) {
+ !cmmf_KeyRecRepContentIsValidIndex(inKeyRecRep, inIndex)) {
return NULL;
}
newKeyPair = PORT_ZNew(CMMFCertifiedKeyPair);
if (newKeyPair == NULL) {
return NULL;
}
- rv = cmmf_CopyCertifiedKeyPair(NULL, newKeyPair,
- inKeyRecRep->keyPairHist[inIndex]);
+ rv = cmmf_CopyCertifiedKeyPair(NULL, newKeyPair,
+ inKeyRecRep->keyPairHist[inIndex]);
if (rv != SECSuccess) {
CMMF_DestroyCertifiedKeyPair(newKeyPair);
- newKeyPair = NULL;
+ newKeyPair = NULL;
}
return newKeyPair;
}
-SECStatus
+SECStatus
CMMF_CertifiedKeyPairUnwrapPrivKey(CMMFCertifiedKeyPair *inKeyPair,
- SECKEYPrivateKey *inPrivKey,
- SECItem *inNickName,
- PK11SlotInfo *inSlot,
- CERTCertDBHandle *inCertdb,
- SECKEYPrivateKey **destPrivKey,
- void *wincx)
+ SECKEYPrivateKey *inPrivKey,
+ SECItem *inNickName,
+ PK11SlotInfo *inSlot,
+ CERTCertDBHandle *inCertdb,
+ SECKEYPrivateKey **destPrivKey,
+ void *wincx)
{
CERTCertificate *cert;
- SECItem keyUsageValue = {siBuffer, NULL, 0};
+ 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) {
+ 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);
+ 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);
+ inPrivKey, pubKey,
+ inNickName, inSlot, keyUsage,
+ destPrivKey, wincx);
SECKEY_DestroyPublicKey(pubKey);
CERT_DestroyCertificate(cert);
return rv;
}
-
-PRBool
+PRBool
CMMF_KeyRecRepContentHasCACerts(CMMFKeyRecRepContent *inKeyRecRep)
{
PORT_Assert(inKeyRecRep != NULL);
if (inKeyRecRep == NULL) {
return PR_FALSE;
}
- return (PRBool)(inKeyRecRep->caCerts != NULL &&
- inKeyRecRep->caCerts[0] != NULL);
+ return (PRBool)(inKeyRecRep->caCerts != NULL &&
+ inKeyRecRep->caCerts[0] != NULL);
}
diff --git a/nss/lib/crmf/cmmfresp.c b/nss/lib/crmf/cmmfresp.c
index 420bbe4..c4b59b8 100644
--- a/nss/lib/crmf/cmmfresp.c
+++ b/nss/lib/crmf/cmmfresp.c
@@ -4,7 +4,7 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
/*
- * This file will contain all routines dealing with creating a
+ * This file will contain all routines dealing with creating a
* CMMFCertRepContent structure through Create/Set functions.
*/
@@ -15,11 +15,11 @@
#include "secitem.h"
#include "secder.h"
-CMMFCertRepContent*
+CMMFCertRepContent *
CMMF_CreateCertRepContent(void)
{
CMMFCertRepContent *retCertRep;
- PLArenaPool *poolp;
+ PLArenaPool *poolp;
poolp = PORT_NewArena(CRMF_DEFAULT_ARENA_SIZE);
if (poolp == NULL) {
@@ -31,47 +31,47 @@ CMMF_CreateCertRepContent(void)
}
retCertRep->poolp = poolp;
return retCertRep;
- loser:
+loser:
if (poolp != NULL) {
PORT_FreeArena(poolp, PR_FALSE);
}
return NULL;
}
-SECStatus
+SECStatus
cmmf_CertOrEncCertSetCertificate(CMMFCertOrEncCert *certOrEncCert,
- PLArenaPool *poolp,
- CERTCertificate *inCert)
+ PLArenaPool *poolp,
+ CERTCertificate *inCert)
{
- SECItem *derDest = NULL;
- SECStatus rv = SECFailure;
+ SECItem *derDest = NULL;
+ SECStatus rv = SECFailure;
if (inCert->derCert.data == NULL) {
- derDest = SEC_ASN1EncodeItem(NULL, NULL, inCert,
- CMMFCertOrEncCertCertificateTemplate);
- if (derDest == NULL) {
- goto loser;
- }
+ derDest = SEC_ASN1EncodeItem(NULL, NULL, inCert,
+ CMMFCertOrEncCertCertificateTemplate);
+ if (derDest == NULL) {
+ goto loser;
+ }
} else {
derDest = SECITEM_DupItem(&inCert->derCert);
- if (derDest == NULL) {
- goto loser;
- }
+ 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;
- }
+ if (rv != SECSuccess) {
+ goto loser;
+ }
} else {
certOrEncCert->derValue = *derDest;
}
PORT_Free(derDest);
return SECSuccess;
- loser:
+loser:
if (derDest != NULL) {
SECITEM_FreeItem(derDest, PR_TRUE);
}
@@ -79,41 +79,39 @@ cmmf_CertOrEncCertSetCertificate(CMMFCertOrEncCert *certOrEncCert,
}
SECStatus
-cmmf_ExtractCertsFromList(CERTCertList *inCertList,
- PLArenaPool *poolp,
- CERTCertificate ***certArray)
+cmmf_ExtractCertsFromList(CERTCertList *inCertList,
+ PLArenaPool *poolp,
+ CERTCertificate ***certArray)
{
- CERTCertificate **arrayLocalCopy;
- CERTCertListNode *node;
- int numNodes = 0, i;
+ CERTCertificate **arrayLocalCopy;
+ CERTCertListNode *node;
+ int numNodes = 0, i;
for (node = CERT_LIST_HEAD(inCertList); !CERT_LIST_END(node, inCertList);
- node = CERT_LIST_NEXT(node)) {
+ node = CERT_LIST_NEXT(node)) {
numNodes++;
}
- arrayLocalCopy = *certArray = (poolp == NULL) ?
- PORT_NewArray(CERTCertificate*, (numNodes+1)) :
- PORT_ArenaNewArray(poolp, CERTCertificate*, (numNodes+1));
+ 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++) {
+ 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;
- }
+ 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;
@@ -121,56 +119,56 @@ cmmf_ExtractCertsFromList(CERTCertList *inCertList,
SECStatus
CMMF_CertRepContentSetCertResponses(CMMFCertRepContent *inCertRepContent,
- CMMFCertResponse **inCertResponses,
- int inNumResponses)
+ CMMFCertResponse **inCertResponses,
+ int inNumResponses)
{
- PLArenaPool *poolp;
+ PLArenaPool *poolp;
CMMFCertResponse **respArr, *newResp;
- void *mark;
- SECStatus rv;
- int i;
+ void *mark;
+ SECStatus rv;
+ int i;
- PORT_Assert (inCertRepContent != NULL &&
- inCertResponses != NULL &&
- inNumResponses > 0);
+ PORT_Assert(inCertRepContent != NULL &&
+ inCertResponses != NULL &&
+ inNumResponses > 0);
if (inCertRepContent == NULL ||
- inCertResponses == NULL ||
- inCertRepContent->response != NULL) {
+ inCertResponses == NULL ||
+ inCertRepContent->response != NULL) {
return SECFailure;
}
poolp = inCertRepContent->poolp;
mark = PORT_ArenaMark(poolp);
- respArr = inCertRepContent->response =
- PORT_ArenaZNewArray(poolp, CMMFCertResponse*, (inNumResponses+1));
+ respArr = inCertRepContent->response =
+ PORT_ArenaZNewArray(poolp, CMMFCertResponse *, (inNumResponses + 1));
if (respArr == NULL) {
goto loser;
}
- for (i=0; i<inNumResponses; i++) {
+ for (i = 0; i < inNumResponses; i++) {
newResp = PORT_ArenaZNew(poolp, CMMFCertResponse);
- if (newResp == NULL) {
- goto loser;
- }
+ if (newResp == NULL) {
+ goto loser;
+ }
rv = cmmf_CopyCertResponse(poolp, newResp, inCertResponses[i]);
- if (rv != SECSuccess) {
- goto loser;
- }
- respArr[i] = newResp;
+ if (rv != SECSuccess) {
+ goto loser;
+ }
+ respArr[i] = newResp;
}
respArr[inNumResponses] = NULL;
PORT_ArenaUnmark(poolp, mark);
return SECSuccess;
- loser:
+loser:
PORT_ArenaRelease(poolp, mark);
return SECFailure;
}
-CMMFCertResponse*
+CMMFCertResponse *
CMMF_CreateCertResponse(long inCertReqId)
{
- SECItem *dummy;
+ SECItem *dummy;
CMMFCertResponse *newResp;
-
+
newResp = PORT_ZNew(CMMFCertResponse);
if (newResp == NULL) {
goto loser;
@@ -181,7 +179,7 @@ CMMF_CreateCertResponse(long inCertReqId)
}
return newResp;
- loser:
+loser:
if (newResp != NULL) {
CMMF_DestroyCertResponse(newResp);
}
@@ -190,32 +188,32 @@ CMMF_CreateCertResponse(long inCertReqId)
SECStatus
CMMF_CertResponseSetPKIStatusInfoStatus(CMMFCertResponse *inCertResp,
- CMMFPKIStatus inPKIStatus)
+ CMMFPKIStatus inPKIStatus)
{
- PORT_Assert (inCertResp != NULL && inPKIStatus >= cmmfGranted
- && inPKIStatus < cmmfNumPKIStatus);
+ PORT_Assert(inCertResp != NULL && inPKIStatus >= cmmfGranted &&
+ inPKIStatus < cmmfNumPKIStatus);
- if (inCertResp == NULL) {
+ if (inCertResp == NULL) {
return SECFailure;
}
return cmmf_PKIStatusInfoSetStatus(&inCertResp->status, NULL,
- inPKIStatus);
+ inPKIStatus);
}
SECStatus
-CMMF_CertResponseSetCertificate (CMMFCertResponse *inCertResp,
- CERTCertificate *inCertificate)
+CMMF_CertResponseSetCertificate(CMMFCertResponse *inCertResp,
+ CERTCertificate *inCertificate)
{
CMMFCertifiedKeyPair *keyPair = NULL;
- SECStatus rv = SECFailure;
+ 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);
+ keyPair = inCertResp->certifiedKeyPair =
+ PORT_ZNew(CMMFCertifiedKeyPair);
} else {
keyPair = inCertResp->certifiedKeyPair;
}
@@ -223,36 +221,35 @@ CMMF_CertResponseSetCertificate (CMMFCertResponse *inCertResp,
goto loser;
}
rv = cmmf_CertOrEncCertSetCertificate(&keyPair->certOrEncCert, NULL,
- inCertificate);
+ inCertificate);
if (rv != SECSuccess) {
goto loser;
}
return SECSuccess;
- loser:
+loser:
if (keyPair) {
if (keyPair->certOrEncCert.derValue.data) {
- PORT_Free(keyPair->certOrEncCert.derValue.data);
- }
- PORT_Free(keyPair);
+ PORT_Free(keyPair->certOrEncCert.derValue.data);
+ }
+ PORT_Free(keyPair);
}
return rv;
}
-
SECStatus
CMMF_CertRepContentSetCAPubs(CMMFCertRepContent *inCertRepContent,
- CERTCertList *inCAPubs)
+ CERTCertList *inCAPubs)
{
- PLArenaPool *poolp;
- void *mark;
- SECStatus rv;
+ PLArenaPool *poolp;
+ void *mark;
+ SECStatus rv;
PORT_Assert(inCertRepContent != NULL &&
- inCAPubs != NULL &&
- inCertRepContent->caPubs == NULL);
-
+ inCAPubs != NULL &&
+ inCertRepContent->caPubs == NULL);
+
if (inCertRepContent == NULL ||
- inCAPubs == NULL || inCertRepContent == NULL) {
+ inCAPubs == NULL || inCertRepContent == NULL) {
return SECFailure;
}
@@ -260,7 +257,7 @@ CMMF_CertRepContentSetCAPubs(CMMFCertRepContent *inCertRepContent,
mark = PORT_ArenaMark(poolp);
rv = cmmf_ExtractCertsFromList(inCAPubs, poolp,
- &inCertRepContent->caPubs);
+ &inCertRepContent->caPubs);
if (rv != SECSuccess) {
PORT_ArenaRelease(poolp, mark);
@@ -270,14 +267,14 @@ CMMF_CertRepContentSetCAPubs(CMMFCertRepContent *inCertRepContent,
return rv;
}
-CERTCertificate*
+CERTCertificate *
CMMF_CertifiedKeyPairGetCertificate(CMMFCertifiedKeyPair *inCertKeyPair,
- CERTCertDBHandle *inCertdb)
+ CERTCertDBHandle *inCertdb)
{
PORT_Assert(inCertKeyPair != NULL);
if (inCertKeyPair == NULL) {
return NULL;
}
return cmmf_CertOrEncCertGetCertificate(&inCertKeyPair->certOrEncCert,
- inCertdb);
+ inCertdb);
}
diff --git a/nss/lib/crmf/cmmft.h b/nss/lib/crmf/cmmft.h
index aea64b0..e39f19e 100644
--- a/nss/lib/crmf/cmmft.h
+++ b/nss/lib/crmf/cmmft.h
@@ -19,7 +19,7 @@ typedef enum {
} CMMFCertOrEncCertChoice;
/*
- * This is the enumeration and the corresponding values used to
+ * This is the enumeration and the corresponding values used to
* represent the CMMF type PKIStatus
*/
typedef enum {
@@ -51,19 +51,19 @@ typedef enum {
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 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;
+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
+/* 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.
*/
diff --git a/nss/lib/crmf/crmf.gyp b/nss/lib/crmf/crmf.gyp
new file mode 100644
index 0000000..f8fa8a4
--- /dev/null
+++ b/nss/lib/crmf/crmf.gyp
@@ -0,0 +1,43 @@
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+{
+ 'includes': [
+ '../../coreconf/config.gypi'
+ ],
+ 'targets': [
+ {
+ 'target_name': 'crmf',
+ 'type': 'static_library',
+ 'sources': [
+ 'asn1cmn.c',
+ 'challcli.c',
+ 'cmmfasn1.c',
+ 'cmmfchal.c',
+ 'cmmfrec.c',
+ 'cmmfresp.c',
+ 'crmfcont.c',
+ 'crmfdec.c',
+ 'crmfenc.c',
+ 'crmfget.c',
+ 'crmfpop.c',
+ 'crmfreq.c',
+ 'crmftmpl.c',
+ 'encutil.c',
+ 'respcli.c',
+ 'respcmn.c',
+ 'servget.c'
+ ],
+ 'dependencies': [
+ '<(DEPTH)/exports.gyp:nss_exports'
+ ],
+ 'variables': {
+ # This is purely for the use of the Mozilla build system.
+ 'no_expand_libs': 1,
+ },
+ }
+ ],
+ 'variables': {
+ 'module': 'nss'
+ }
+}
diff --git a/nss/lib/crmf/crmf.h b/nss/lib/crmf/crmf.h
index 9f36c28..c56e289 100644
--- a/nss/lib/crmf/crmf.h
+++ b/nss/lib/crmf/crmf.h
@@ -3,7 +3,6 @@
* License, v. 2.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_
@@ -27,16 +26,16 @@ SEC_BEGIN_PROTOS
* 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
+ * 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);
+extern SECStatus
+CRMF_EncodeCertReqMsg(CRMFCertReqMsg *inCertReqMsg,
+ CRMFEncoderOutputCallback fn,
+ void *arg);
/*
* FUNCTION: CRMF_EncoderCertRequest
@@ -49,17 +48,17 @@ extern SECStatus
* 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
+ * 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
+ * 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);
+extern SECStatus CRMF_EncodeCertRequest(CRMFCertRequest *inCertReq,
+ CRMFEncoderOutputCallback fn,
+ void *arg);
/*
* FUNCTION: CRMF_EncodeCertReqMessages
* INPUTS:
@@ -77,25 +76,24 @@ extern SECStatus CRMF_EncodeCertRequest (CRMFCertRequest *inCertReq,
*
* 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
+ * 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
+ * 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.
+ * 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);
-
+extern SECStatus
+CRMF_EncodeCertReqMessages(CRMFCertReqMsg **inCertReqMsgs,
+ CRMFEncoderOutputCallback fn,
+ void *arg);
/*
* FUNCTION: CRMF_CreateCertReqMsg
@@ -104,19 +102,19 @@ extern SECStatus
* OUTPUT:
* An empty CRMF Certificate Request Message.
* Before encoding this message, the user must set
- * the ProofOfPossession field and the certificate
+ * 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
+ * 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);
+extern CRMFCertReqMsg *CRMF_CreateCertReqMsg(void);
/*
* FUNCTION: CRMF_DestroyCertReqMsg
@@ -127,12 +125,12 @@ extern CRMFCertReqMsg* CRMF_CreateCertReqMsg(void);
* 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.
+ * 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);
@@ -151,14 +149,14 @@ extern SECStatus CRMF_DestroyCertReqMsg(CRMFCertReqMsg *inCertReqMsg);
* the user must not call this function until the Certificate Request
* has been fully built and is ready to be encoded.
* RETURN:
- * SECSuccess
+ * 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);
+extern SECStatus CRMF_CertReqMsgSetCertRequest(CRMFCertReqMsg *inCertReqMsg,
+ CRMFCertRequest *inCertReq);
/*
* FUNCTION: CRMF_CreateCertRequest
@@ -176,7 +174,7 @@ extern SECStatus CRMF_CertReqMsgSetCertRequest(CRMFCertReqMsg *inCertReqMsg,
* 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);
+extern CRMFCertRequest *CRMF_CreateCertRequest(PRUint32 inRequestID);
/*
* FUNCTION: CRMF_DestroyCertRequest
@@ -185,12 +183,12 @@ extern CRMFCertRequest *CRMF_CreateCertRequest (PRUint32 inRequestID);
* The Certificate Request that will be destroyed.
* RETURN:
* SECSuccess
- * If freeing the memory associated with the certificate request
+ * If freeing the memory associated with the certificate request
* was successful.
- * Any other return value indicates an error while trying to free the
+ * Any other return value indicates an error while trying to free the
* memory.
*/
-extern SECStatus CRMF_DestroyCertRequest (CRMFCertRequest *inCertReq);
+extern SECStatus CRMF_DestroyCertRequest(CRMFCertRequest *inCertReq);
/*
* FUNCTION: CRMF_CreateCertExtension
@@ -201,16 +199,16 @@ extern SECStatus CRMF_DestroyCertRequest (CRMFCertRequest *inCertReq);
* 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
+ * 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
+ * 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.
*
@@ -218,9 +216,9 @@ extern SECStatus CRMF_DestroyCertRequest (CRMFCertRequest *inCertReq);
* 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);
+extern CRMFCertExtension *CRMF_CreateCertExtension(SECOidTag id,
+ PRBool isCritical,
+ SECItem *data);
/*
* FUNCTION: CMRF_DestroyCertExtension
@@ -232,12 +230,12 @@ extern CRMFCertExtension *CRMF_CreateCertExtension(SECOidTag id,
*
* RETURN:
* SECSuccess if freeing the memory associated with the certificate extension
- * was successful. Any other error indicates an error while freeing the
+ * was successful. Any other error indicates an error while freeing the
* memory.
*/
extern SECStatus CRMF_DestroyCertExtension(CRMFCertExtension *inExtension);
-/*
+/*
* FUNCTION: CRMF_CertRequestSetTemplateField
* INPUTS:
* inCertReq
@@ -255,7 +253,7 @@ extern SECStatus CRMF_DestroyCertExtension(CRMFCertExtension *inExtension);
* 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
@@ -267,23 +265,23 @@ extern SECStatus CRMF_DestroyCertExtension(CRMFCertExtension *inExtension);
* 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
+ * 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
+ * be present. A NULL pointer
* in the structure indicates
- * that member should not be
+ * that member should not be
* added.
*
- * crmfSubject CERTName * Certificate Library
+ * crmfSubject CERTName * Certificate Library
* representation of the ASN1 type
* Name from X.509
*
@@ -301,23 +299,23 @@ extern SECStatus CRMF_DestroyCertExtension(CRMFCertExtension *inExtension);
* and not the number of bytes.
*
* crmfExtension CRMFCertExtCreationInfo * A pointer to the structure
- * populated with an array of
+ * 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
+ * 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
+ * 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);
+CRMF_CertRequestSetTemplateField(CRMFCertRequest *inCertReq,
+ CRMFCertTemplateField inTemplateField,
+ void *data);
/*
* FUNCTION: CRMF_CertRequestIsFieldPresent
@@ -337,8 +335,8 @@ extern SECStatus
* the function returns PR_FALSE.
*/
extern PRBool
- CRMF_CertRequestIsFieldPresent(CRMFCertRequest *inCertReq,
- CRMFCertTemplateField inTemplateField);
+CRMF_CertRequestIsFieldPresent(CRMFCertRequest *inCertReq,
+ CRMFCertTemplateField inTemplateField);
/*
* FUNCTION: CRMF_CertRequestIsControlPresent
@@ -363,9 +361,8 @@ extern PRBool
* does not exist, the function will return PR_FALSE.
*/
extern PRBool
- CRMF_CertRequestIsControlPresent(CRMFCertRequest *inCertReq,
- CRMFControlType inControlType);
-
+CRMF_CertRequestIsControlPresent(CRMFCertRequest *inCertReq,
+ CRMFControlType inControlType);
/*
* FUNCTION: CRMF_CertRequestSetRegTokenControl
@@ -376,7 +373,7 @@ extern PRBool
* 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
+ * 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.
@@ -387,7 +384,7 @@ extern PRBool
*
*/
extern SECStatus CRMF_CertRequestSetRegTokenControl(CRMFCertRequest *inCertReq,
- SECItem *value);
+ SECItem *value);
/*
* FUNCTION: CRMF_CertRequestSetAuthenticatorControl
@@ -398,7 +395,7 @@ extern SECStatus CRMF_CertRequestSetRegTokenControl(CRMFCertRequest *inCertReq,
* 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
+ * 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.
@@ -407,31 +404,31 @@ extern SECStatus CRMF_CertRequestSetRegTokenControl(CRMFCertRequest *inCertReq,
* Any other return value indicates an unsuccessful attempt to add the
* control.
*/
-extern SECStatus
- CRMF_CertRequestSetAuthenticatorControl (CRMFCertRequest *inCertReq,
- SECItem *value);
+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.
+ * 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
+ * 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
+ * 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);
+extern CRMFEncryptedKey *
+CRMF_CreateEncryptedKeyWithEncryptedValue(SECKEYPrivateKey *inPrivKey,
+ CERTCertificate *inCACert);
/*
* FUNCTION: CRMF_DestroyEncryptedKey
@@ -445,12 +442,12 @@ extern CRMFEncryptedKey*
* 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
+ * An enumeration value indicating which option for
* PKIArchiveOptions to use.
* data
* A pointer that will be type-cast and de-referenced according
@@ -470,9 +467,9 @@ extern SECStatus CRMF_DestroyEncryptedKey(CRMFEncryptedKey *inEncrKey);
* Request. A NULL pointer indicates an error occurred while creating
* the CRMFPKIArchiveOptions Structure.
*/
-extern CRMFPKIArchiveOptions*
- CRMF_CreatePKIArchiveOptions(CRMFPKIArchiveOptionsType inType,
- void *data);
+extern CRMFPKIArchiveOptions *
+CRMF_CreatePKIArchiveOptions(CRMFPKIArchiveOptionsType inType,
+ void *data);
/*
* FUNCTION: CRMF_DestroyPKIArchiveOptions
* INPUTS:
@@ -484,8 +481,8 @@ extern CRMFPKIArchiveOptions*
* 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);
+extern SECStatus
+CRMF_DestroyPKIArchiveOptions(CRMFPKIArchiveOptions *inArchOpt);
/*
* FUNCTION: CRMF_CertRequestSetPKIArchiveOptions
@@ -503,9 +500,9 @@ extern SECStatus
* 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);
+extern SECStatus
+CRMF_CertRequestSetPKIArchiveOptions(CRMFCertRequest *inCertReq,
+ CRMFPKIArchiveOptions *inOptions);
/*
* FUNCTION: CRMF_CertReqMsgGetPOPType
@@ -530,11 +527,11 @@ extern CRMFPOPChoice CRMF_CertReqMsgGetPOPType(CRMFCertReqMsg *inCertReqMsg);
* 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
+ * 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.
+ * 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.
*/
@@ -551,7 +548,7 @@ extern SECStatus CRMF_CertReqMsgSetRAVerifiedPOP(CRMFCertReqMsg *inCertReqMsg);
* inPubKey
* The Public Key which corresponds to the Private Key passed in.
* inCertForInput
- * A Certificate that in the future may be used to create
+ * 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
@@ -560,13 +557,13 @@ extern SECStatus CRMF_CertReqMsgSetRAVerifiedPOP(CRMFCertReqMsg *inCertReqMsg);
* 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,
+ * 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
+ * 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
*
@@ -583,8 +580,8 @@ extern SECStatus CRMF_CertReqMsgSetRAVerifiedPOP(CRMFCertReqMsg *inCertReqMsg);
* 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
+ * 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.
*
@@ -593,13 +590,13 @@ extern SECStatus CRMF_CertReqMsgSetRAVerifiedPOP(CRMFCertReqMsg *inCertReqMsg);
* 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);
+extern SECStatus
+CRMF_CertReqMsgSetSignaturePOP(CRMFCertReqMsg *inCertReqMsg,
+ SECKEYPrivateKey *inPrivKey,
+ SECKEYPublicKey *inPubKey,
+ CERTCertificate *inCertForInput,
+ CRMFMACPasswordCallback fn,
+ void *arg);
/*
* FUNCTION: CRMF_CertReqMsgSetKeyEnciphermentPOP
@@ -610,7 +607,7 @@ extern SECStatus
* An enumeration indicating which POPOPrivKey Choice to use
* in constructing the KeyEnciphermentPOP.
* subseqMess
- * This parameter must be provided iff inKeyChoice is
+ * 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.
@@ -618,7 +615,7 @@ extern SECStatus
* 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.
@@ -651,11 +648,11 @@ extern SECStatus
* 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);
+extern SECStatus
+CRMF_CertReqMsgSetKeyEnciphermentPOP(CRMFCertReqMsg *inCertReqMsg,
+ CRMFPOPOPrivKeyChoice inKeyChoice,
+ CRMFSubseqMessOptions subseqMess,
+ SECItem *encPrivKey);
/*
* FUNCTION: CRMF_CertReqMsgSetKeyAgreementPOP
@@ -666,7 +663,7 @@ extern SECStatus
* An enumeration indicating which POPOPrivKey Choice to use
* in constructing the KeyAgreementPOP.
* subseqMess
- * This parameter must be provided iff inKeyChoice is
+ * 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.
@@ -700,11 +697,11 @@ extern SECStatus
*
* crmfDHMAC This option is not supported.
*/
-extern SECStatus
- CRMF_CertReqMsgSetKeyAgreementPOP(CRMFCertReqMsg *inCertReqMsg,
- CRMFPOPOPrivKeyChoice inKeyChoice,
- CRMFSubseqMessOptions subseqMess,
- SECItem *encPrivKey);
+extern SECStatus
+CRMF_CertReqMsgSetKeyAgreementPOP(CRMFCertReqMsg *inCertReqMsg,
+ CRMFPOPOPrivKeyChoice inKeyChoice,
+ CRMFSubseqMessOptions subseqMess,
+ SECItem *encPrivKey);
/*
* FUNCTION: CRMF_CreateCertReqMsgFromDER
@@ -714,16 +711,16 @@ extern SECStatus
* len
* The length in bytes of the buffer 'buf'
* NOTES:
- * This function passes the buffer to the ASN1 decoder and creates a
+ * 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
+ * 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);
+extern CRMFCertReqMsg *CRMF_CreateCertReqMsgFromDER(const char *buf, long len);
/*
* FUNCTION: CRMF_CreateCertReqMessagesFromDER
@@ -733,19 +730,19 @@ extern CRMFCertReqMsg* CRMF_CreateCertReqMsgFromDER(const char *buf, long len);
* len
* The length in bytes of buf
* NOTES:
- * This function passes the buffer to the ASN1 decoder and creates a
+ * 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
+ * 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
+ * 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);
+ */
+extern CRMFCertReqMessages *
+CRMF_CreateCertReqMessagesFromDER(const char *buf, long len);
/*
* FUNCTION: CRMF_DestroyCertReqMessages
@@ -755,9 +752,9 @@ extern CRMFCertReqMessages*
* 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);
+ */
+extern SECStatus
+CRMF_DestroyCertReqMessages(CRMFCertReqMessages *inCertReqMsgs);
/*
* FUNCTION: CRMF_CertReqMessagesGetNumMessages
@@ -765,11 +762,11 @@ extern SECStatus
* inCertReqMsgs
* The Request Messages to operate on.
* RETURN:
- * The number of messages contained in the in the Request Messages
+ * The number of messages contained in the in the Request Messages
* strucure.
*/
-extern int
- CRMF_CertReqMessagesGetNumMessages(CRMFCertReqMessages *inCertReqMsgs);
+extern int
+CRMF_CertReqMessagesGetNumMessages(CRMFCertReqMessages *inCertReqMsgs);
/*
* FUNCTION: CRMF_CertReqMessagesGetCertReqMsgAtIndex
@@ -779,9 +776,9 @@ extern int
* 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
+ * 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
+ * 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.
*
@@ -790,10 +787,9 @@ extern int
* Any other return value indicates an invalid index or error while copying
* the single request message.
*/
-extern CRMFCertReqMsg*
- CRMF_CertReqMessagesGetCertReqMsgAtIndex(CRMFCertReqMessages *inReqMsgs,
- int index);
-
+extern CRMFCertReqMsg *
+CRMF_CertReqMessagesGetCertReqMsgAtIndex(CRMFCertReqMessages *inReqMsgs,
+ int index);
/*
* FUNCTION: CRMF_CertReqMsgGetID
@@ -805,12 +801,12 @@ extern CRMFCertReqMsg*
* 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
+ * in *destId is un-reliable and should not be used by the caller of this
* function.
- *
+ *
*/
-extern SECStatus CRMF_CertReqMsgGetID(CRMFCertReqMsg *inCertReqMsg,
- long *destID);
+extern SECStatus CRMF_CertReqMsgGetID(CRMFCertReqMsg *inCertReqMsg,
+ long *destID);
/*
* FUNCTION: CRMF_DoesRequestHaveField
@@ -823,7 +819,7 @@ extern SECStatus CRMF_CertReqMsgGetID(CRMFCertReqMsg *inCertReqMsg,
* 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
+ * definition of CRMFCertTemplateField for possible values for possible
* querying.
*
* RETURN:
@@ -831,10 +827,10 @@ extern SECStatus CRMF_CertReqMsgGetID(CRMFCertReqMsg *inCertReqMsg,
* 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);
+extern PRBool CRMF_DoesRequestHaveField(CRMFCertRequest *inCertReq,
+ CRMFCertTemplateField inField);
/*
* FUNCTION: CRMF_CertReqMsgGetCertRequest
@@ -849,11 +845,11 @@ extern PRBool CRMF_DoesRequestHaveField(CRMFCertRequest *inCertReq,
* 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
+ * A NULL return value indicates an error occurred while copying the
* certificate request.
*/
extern CRMFCertRequest *
- CRMF_CertReqMsgGetCertRequest(CRMFCertReqMsg *inCertReqMsg);
+CRMF_CertReqMsgGetCertRequest(CRMFCertReqMsg *inCertReqMsg);
/*
* FUNCTION: CRMF_CertRequestGetCertTemplateVersion
@@ -864,15 +860,15 @@ extern CRMFCertRequest *
* 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
+ * 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);
+extern SECStatus
+CRMF_CertRequestGetCertTemplateVersion(CRMFCertRequest *inCertReq,
+ long *version);
/*
* FUNCTION: CRMF_CertRequestGetCertTemplateSerialNumber
@@ -883,15 +879,15 @@ extern SECStatus
* 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
+ * 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);
+extern SECStatus
+CRMF_CertRequestGetCertTemplateSerialNumber(CRMFCertRequest *inCertReq,
+ long *serialNumber);
/*
* FUNCTION: CRMF_CertRequestGetCertTemplateSigningAlg
@@ -903,14 +899,14 @@ extern SECStatus
* 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
+ * 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);
+extern SECStatus
+CRMF_CertRequestGetCertTemplateSigningAlg(CRMFCertRequest *inCertReq,
+ SECAlgorithmID *destAlg);
/*
* FUNCTION: CRMF_CertRequestGetCertTemplateIssuer
* INPUTS:
@@ -920,14 +916,14 @@ extern SECStatus
* 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
+ * 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);
+extern SECStatus
+CRMF_CertRequestGetCertTemplateIssuer(CRMFCertRequest *inCertReq,
+ CERTName *destIssuer);
/*
* FUNCTION: CRMF_CertRequestGetCertTemplateValidity
@@ -938,28 +934,28 @@ extern SECStatus
* 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:
+ * 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
+ * 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);
+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
+ * The function will free the memory allocated by the function
* CRMF_CertRequestGetCertTemplateValidity. That means only memory pointed
- * to within the CRMFGetValidity structure. Since
+ * 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
@@ -969,8 +965,8 @@ extern SECStatus
* SECSuccess if freeing the memory was successful. Any other return value
* indicates an error while freeing the memory.
*/
-extern SECStatus
- CRMF_DestroyGetValidity(CRMFGetValidity *inValidity);
+extern SECStatus
+CRMF_DestroyGetValidity(CRMFGetValidity *inValidity);
/*
* FUNCTION: CRMF_CertRequestGetCertTemplateSubject
@@ -981,15 +977,15 @@ extern SECStatus
* 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
+ * 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);
+extern SECStatus
+CRMF_CertRequestGetCertTemplateSubject(CRMFCertRequest *inCertReq,
+ CERTName *destSubject);
/*
* FUNCTION: CRMF_CertRequestGetCertTemplatePublicKey
@@ -1006,9 +1002,9 @@ extern SECStatus
* 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);
+extern SECStatus
+CRMF_CertRequestGetCertTemplatePublicKey(CRMFCertRequest *inCertReq,
+ CERTSubjectPublicKeyInfo *destPublicKey);
/*
* FUNCTION: CRMF_CertRequestGetCertTemplateIssuerUID
@@ -1019,7 +1015,7 @@ extern SECStatus
* A pointer to where the library can store a copy of the request's
* cert template destIssuerUID.
*
- * NOTES:
+ * 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.
@@ -1031,9 +1027,9 @@ extern SECStatus
* If there is no issuerUID, the function returns SECFailure and the value
* *destIssuerUID is unchanged.
*/
-extern SECStatus
- CRMF_CertRequestGetCertTemplateIssuerUID(CRMFCertRequest *inCertReq,
- SECItem *destIssuerUID);
+extern SECStatus
+CRMF_CertRequestGetCertTemplateIssuerUID(CRMFCertRequest *inCertReq,
+ SECItem *destIssuerUID);
/*
* FUNCTION: CRMF_CertRequestGetCertTemplateSubjectUID
@@ -1043,7 +1039,7 @@ extern SECStatus
* A pointer to where the library can store a copy of the request's
* cert template destIssuerUID.
*
- * NOTES:
+ * 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.
@@ -1056,7 +1052,7 @@ extern SECStatus
* *destIssuerUID is unchanged.
*/
extern SECStatus CRMF_GetCertTemplateSubjectUID(CRMFCertRequest *inCertReq,
- SECItem *destSubjectUID);
+ SECItem *destSubjectUID);
/*
* FUNCTION: CRMF_CertRequestGetNumberOfExtensions
@@ -1076,20 +1072,20 @@ extern int CRMF_CertRequestGetNumberOfExtensions(CRMFCertRequest *inCertReq);
* 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.
+ * 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
+ * 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);
+CRMF_CertRequestGetExtensionAtIndex(CRMFCertRequest *inCertReq,
+ int index);
/*
* FUNCTION: CRMF_CertExtensionGetOidTag
* INPUTS:
@@ -1112,7 +1108,7 @@ extern SECOidTag CRMF_CertExtensionGetOidTag(CRMFCertExtension *inExtension);
* PR_FALSE if the extension is not critical.
*/
extern PRBool CRMF_CertExtensionGetIsCritical(CRMFCertExtension *inExt);
-
+
/*
* FUNCTION: CRMF_CertExtensionGetValue
* INPUT:
@@ -1127,7 +1123,7 @@ extern PRBool CRMF_CertExtensionGetIsCritical(CRMFCertExtension *inExt);
* 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);
+extern SECItem *CRMF_CertExtensionGetValue(CRMFCertExtension *inExtension);
/*
* FUNCTION: CRMF_CertReqMsgGetPOPOSigningKey
@@ -1136,20 +1132,20 @@ extern SECItem* CRMF_CertExtensionGetValue(CRMFCertExtension *inExtension);
* 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
+ * a copy of the Proof Of Possession Signing Key used
* by the message.
*
* RETURN:
- * Get the POPOSigningKey associated with this CRMFCertReqMsg.
+ * 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
+ * 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);
+extern SECStatus
+CRMF_CertReqMsgGetPOPOSigningKey(CRMFCertReqMsg *inCertReqMsg,
+ CRMFPOPOSigningKey **destKey);
/*
* FUNCTION: CRMF_DestroyPOPOSigningKey
@@ -1161,7 +1157,7 @@ extern SECStatus
* SECSuccess if freeing the memory was successful. Any other return value
* indicates an error while freeing memory.
*/
-extern SECStatus CRMF_DestroyPOPOSigningKey (CRMFPOPOSigningKey *inKey);
+extern SECStatus CRMF_DestroyPOPOSigningKey(CRMFPOPOSigningKey *inKey);
/*
* FUNCTION: CRMF_POPOSigningKeyGetAlgID
@@ -1173,8 +1169,8 @@ extern SECStatus CRMF_DestroyPOPOSigningKey (CRMFPOPOSigningKey *inKey);
* call SECOID_DestroyAlgorithmID(destID, PR_TRUE) when done using the
* return value.
*/
-extern SECAlgorithmID*
- CRMF_POPOSigningKeyGetAlgID(CRMFPOPOSigningKey *inSignKey);
+extern SECAlgorithmID *
+CRMF_POPOSigningKeyGetAlgID(CRMFPOPOSigningKey *inSignKey);
/*
* FUNCTION: CRMF_POPOSigningKeyGetSignature
@@ -1182,13 +1178,13 @@ extern SECAlgorithmID*
* inSignKey
* The Signing Key to operate on.
*
- * RETURN:
+ * 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
+ * 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);
+extern SECItem *CRMF_POPOSigningKeyGetSignature(CRMFPOPOSigningKey *inSignKey);
/*
* FUNCTION: CRMF_POPOSigningKeyGetInput
@@ -1196,7 +1192,7 @@ extern SECItem* CRMF_POPOSigningKeyGetSignature(CRMFPOPOSigningKey *inSignKey);
* inSignKey
* The Signing Key to operate on.
* NOTES:
- * This function will return the der encoded input that was read in while
+ * 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.
*
@@ -1208,7 +1204,7 @@ extern SECItem* CRMF_POPOSigningKeyGetSignature(CRMFPOPOSigningKey *inSignKey);
* 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);
+extern SECItem *CRMF_POPOSigningKeyGetInput(CRMFPOPOSigningKey *inSignKey);
/*
* FUNCTION: CRMF_CertReqMsgGetPOPKeyEncipherment
@@ -1216,12 +1212,12 @@ extern SECItem* CRMF_POPOSigningKeyGetInput(CRMFPOPOSigningKey *inSignKey);
* 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
+ * 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.
+ * 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
@@ -1231,9 +1227,9 @@ extern SECItem* CRMF_POPOSigningKeyGetInput(CRMFPOPOSigningKey *inSignKey);
* function returns SECSuccess and places the POPOPrivKey representing the
* Key Encipherment Proof Of Possessin at *destKey.
*/
-extern SECStatus
- CRMF_CertReqMsgGetPOPKeyEncipherment(CRMFCertReqMsg *inCertReqMsg,
- CRMFPOPOPrivKey **destKey);
+extern SECStatus
+CRMF_CertReqMsgGetPOPKeyEncipherment(CRMFCertReqMsg *inCertReqMsg,
+ CRMFPOPOPrivKey **destKey);
/*
* FUNCTION: CRMF_CertReqMsgGetPOPKeyAgreement
@@ -1241,12 +1237,12 @@ extern SECStatus
* 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
+ * 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.
+ * This function gets the POPOPrivKey associated with this CRMFCertReqMsg for
+ * Key Agreement.
*
* RETURN:
* If the CertReqMsg used Key Agreement for Proof Of Possession, the
@@ -1256,11 +1252,11 @@ extern SECStatus
* 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);
+extern SECStatus
+CRMF_CertReqMsgGetPOPKeyAgreement(CRMFCertReqMsg *inCertReqMsg,
+ CRMFPOPOPrivKey **destKey);
-/*
+/*
* FUNCTION: CRMF_DestroyPOPOPrivKey
* INPUTS:
* inPrivKey
@@ -1271,12 +1267,12 @@ extern SECStatus
*
* RETURN:
* SECSuccess on successful destruction of the POPOPrivKey.
- * Any other return value indicates an error in freeing the
+ * Any other return value indicates an error in freeing the
* memory.
*/
extern SECStatus CRMF_DestroyPOPOPrivKey(CRMFPOPOPrivKey *inPrivKey);
-/*
+/*
* FUNCTION: CRMF_POPOPrivKeyGetChoice
* INPUT:
* inKey
@@ -1298,7 +1294,7 @@ extern CRMFPOPOPrivKeyChoice CRMF_POPOPrivKeyGetChoice(CRMFPOPOPrivKey *inKey);
* field stored in the POPOPrivKey
*
* RETURN:
- * Returns the field thisMessage from the POPOPrivKey.
+ * 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.
*
@@ -1307,8 +1303,8 @@ extern CRMFPOPOPrivKeyChoice CRMF_POPOPrivKeyGetChoice(CRMFPOPOPrivKey *inKey);
* 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);
+extern SECStatus CRMF_POPOPrivKeyGetThisMessage(CRMFPOPOPrivKey *inKey,
+ SECItem *destString);
/*
* FUNCTION: CRMF_POPOPrivKeyGetSubseqMess
@@ -1316,20 +1312,20 @@ extern SECStatus CRMF_POPOPrivKeyGetThisMessage(CRMFPOPOPrivKey *inKey,
* inKey
* The POPOPrivKey to operate on.
* destOpt
- * A pointer to where the library can place the value of the
+ * 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
+ * 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);
+extern SECStatus CRMF_POPOPrivKeyGetSubseqMess(CRMFPOPOPrivKey *inKey,
+ CRMFSubseqMessOptions *destOpt);
/*
* FUNCTION: CRMF_POPOPrivKeyGetDHMAC
@@ -1339,9 +1335,9 @@ extern SECStatus CRMF_POPOPrivKeyGetSubseqMess(CRMFPOPOPrivKey *inKey,
* 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
+ * Returns the field dhMAC from the POPOPrivKey. The populated SECItem
* is in BIT STRING format.
*
* RETURN:
@@ -1352,20 +1348,20 @@ extern SECStatus CRMF_POPOPrivKeyGetSubseqMess(CRMFPOPOPrivKey *inKey,
*
* 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);
+ SECItem *destMAC);
/*
* FUNCTION: CRMF_CertRequestGetNumControls
- * INPUTS:
+ * INPUTS:
* inCertReq
* The Certificate Request to operate on.
* RETURN:
* Returns the number of Controls registered with this CertRequest.
*/
-extern int CRMF_CertRequestGetNumControls (CRMFCertRequest *inCertReq);
+extern int CRMF_CertRequestGetNumControls(CRMFCertRequest *inCertReq);
/*
* FUNCTION: CRMF_CertRequestGetControlAtIndex
@@ -1375,18 +1371,18 @@ extern int CRMF_CertRequestGetNumControls (CRMFCertRequest *inCertReq);
* index
* The index of the control the user wants a copy of.
* NOTES:
- * Function retrieves the Control at located at index. The Controls
+ * 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
+ * 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);
+extern CRMFControl *
+CRMF_CertRequestGetControlAtIndex(CRMFCertRequest *inCertReq,
+ int index);
/*
* FUNCTION: CRMF_DestroyControl
@@ -1431,11 +1427,11 @@ extern CRMFControlType CRMF_ControlGetControlType(CRMFControl *inControl);
* 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
+ * (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);
+extern SECItem *CRMF_ControlGetRegTokenControlValue(CRMFControl *inControl);
/*
* FUNCTION: CRMF_ControlGetAuthenticatorControlValue
@@ -1451,11 +1447,11 @@ extern SECItem* CRMF_ControlGetRegTokenControlValue(CRMFControl *inControl);
* 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
+ * (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);
+extern SECItem *CRMF_ControlGetAuthicatorControlValue(CRMFControl *inControl);
/*
* FUNCTION: CRMF_ControlGetPKIArchiveOptions
@@ -1468,12 +1464,12 @@ extern SECItem* CRMF_ControlGetAuthicatorControlValue(CRMFControl *inControl);
*
* RETURN:
* Get the PKIArchiveOptions associated with the Control. A return
- * value of NULL indicates the Control was not a PKIArchiveOptions
+ * value of NULL indicates the Control was not a PKIArchiveOptions
* Control.
*/
-extern CRMFPKIArchiveOptions*
- CRMF_ControlGetPKIArchiveOptions(CRMFControl *inControl);
-
+extern CRMFPKIArchiveOptions *
+CRMF_ControlGetPKIArchiveOptions(CRMFControl *inControl);
+
/*
* FUNCTION: CMRF_DestroyPKIArchiveOptions
* INPUTS:
@@ -1483,12 +1479,12 @@ extern CRMFPKIArchiveOptions*
* Destroy the CRMFPKIArchiveOptions structure.
*
* RETURN:
- * SECSuccess if successful in freeing all the memory associated with
+ * 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);
+extern SECStatus
+CRMF_DestroyPKIArchiveOptions(CRMFPKIArchiveOptions *inOptions);
/*
* FUNCTION: CRMF_PKIArchiveOptionsGetOptionType
@@ -1500,14 +1496,14 @@ extern SECStatus
* of CRMFPKIArchiveOptionsType in crmft.h for possible return values.
*/
extern CRMFPKIArchiveOptionsType
- CRMF_PKIArchiveOptionsGetOptionType(CRMFPKIArchiveOptions *inOptions);
+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.
@@ -1517,8 +1513,8 @@ extern CRMFPKIArchiveOptionsType
* A return value of NULL indicates that encryptedPrivKey was not used as
* the choice for this PKIArchiveOptions.
*/
-extern CRMFEncryptedKey*
- CRMF_PKIArchiveOptionsGetEncryptedPrivKey(CRMFPKIArchiveOptions *inOpts);
+extern CRMFEncryptedKey *
+CRMF_PKIArchiveOptionsGetEncryptedPrivKey(CRMFPKIArchiveOptions *inOpts);
/*
* FUNCTION: CRMF_EncryptedKeyGetChoice
@@ -1530,13 +1526,12 @@ extern CRMFEncryptedKey*
* Get the choice used for representing the EncryptedKey.
*
* RETURN:
- * Returns the Choice used in representing the EncryptedKey. Look in
+ * 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);
-
+extern CRMFEncryptedKeyChoice
+CRMF_EncryptedKeyGetChoice(CRMFEncryptedKey *inEncrKey);
/*
* FUNCTION: CRMF_EncryptedKeyGetEncryptedValue
@@ -1545,15 +1540,15 @@ extern CRMFEncryptedKeyChoice
* The EncryptedKey to operate on.
*
* NOTES:
- * The user must call CRMF_DestroyEncryptedValue passing in
+ * 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);
+extern CRMFEncryptedValue *
+CRMF_EncryptedKeyGetEncryptedValue(CRMFEncryptedKey *inKey);
/*
* FUNCTION: CRMF_DestroyEncryptedValue
@@ -1586,7 +1581,7 @@ extern SECStatus CRMF_DestroyEncryptedValue(CRMFEncryptedValue *inEncrValue);
* 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);
+extern SECItem *CRMF_EncryptedValueGetEncValue(CRMFEncryptedValue *inEncValue);
/*
* FUNCTION: CRMF_EncryptedValueGetIntendedAlg
@@ -1603,9 +1598,8 @@ extern SECItem* CRMF_EncryptedValueGetEncValue(CRMFEncryptedValue *inEncValue);
* 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);
-
+extern SECAlgorithmID *
+CRMF_EncryptedValueGetIntendedAlg(CRMFEncryptedValue *inEncValue);
/*
* FUNCTION: CRMF_EncryptedValueGetSymmAlg
@@ -1622,9 +1616,8 @@ extern SECAlgorithmID*
* 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);
-
+extern SECAlgorithmID *
+CRMF_EncryptedValueGetSymmAlg(CRMFEncryptedValue *inEncValue);
/*
* FUNCTION: CRMF_EncryptedValueGetKeyAlg
@@ -1641,8 +1634,8 @@ extern SECAlgorithmID*
* 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);
+extern SECAlgorithmID *
+CRMF_EncryptedValueGetKeyAlg(CRMFEncryptedValue *inEncValue);
/*
* FUNCTION: CRMF_EncryptedValueGetValueHint
@@ -1662,12 +1655,12 @@ extern SECAlgorithmID*
* value indicates the optional valueHint field is not present in the
* EncryptedValue.
*/
-extern SECItem*
- CRMF_EncryptedValueGetValueHint(CRMFEncryptedValue *inEncValue);
+extern SECItem *
+CRMF_EncryptedValueGetValueHint(CRMFEncryptedValue *inEncValue);
/*
* FUNCTION: CRMF_EncrypteValueGetEncSymmKey
- * INPUTS:
+ * INPUTS:
* inEncValue
* The EncryptedValue to operate on.
*
@@ -1676,19 +1669,19 @@ extern SECItem*
* 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
+ * 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
+ * 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);
+extern SECItem *
+CRMF_EncryptedValueGetEncSymmKey(CRMFEncryptedValue *inEncValue);
/*
* FUNCTION: CRMF_PKIArchiveOptionsGetKeyGenParameters
@@ -1697,19 +1690,19 @@ extern SECItem*
* The PKiArchiveOptions to operate on.
*
* NOTES:
- * User must call SECITEM_FreeItem(retVal, PR_TRUE) after the return
+ * 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
+ * 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);
+extern SECItem *
+CRMF_PKIArchiveOptionsGetKeyGenParameters(CRMFPKIArchiveOptions *inOptions);
/*
* FUNCTION: CRMF_PKIArchiveOptionsGetArchiveRemGenPrivKey
@@ -1717,34 +1710,32 @@ extern SECItem*
* inOpt
* The PKIArchiveOptions to operate on.
* destVal
- * A pointer to where the library can place the value for
+ * 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.
+ * 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);
+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);
+extern CK_MECHANISM_TYPE CRMF_GetBestWrapPadMechanism(PK11SlotInfo *slot);
/*
- * A helper function to get a randomly generated IV from a mechanism
+ * A helper function to get a randomly generated IV from a mechanism
* type.
*/
-extern SECItem* CRMF_GetIVFromMechanism(CK_MECHANISM_TYPE mechType);
-
+extern SECItem *CRMF_GetIVFromMechanism(CK_MECHANISM_TYPE mechType);
+
SEC_END_PROTOS
#endif /*_CRMF_H_*/
-
-
diff --git a/nss/lib/crmf/crmfcont.c b/nss/lib/crmf/crmfcont.c
index 4e274d3..5df2bd8 100644
--- a/nss/lib/crmf/crmfcont.c
+++ b/nss/lib/crmf/crmfcont.c
@@ -10,32 +10,32 @@
#include "secoid.h"
static SECStatus
-crmf_modify_control_array (CRMFCertRequest *inCertReq, int count)
+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;
+ 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);
+ inCertReq->controls = PORT_ZNewArray(CRMFControl *, 2);
}
- return (inCertReq->controls == NULL) ? SECFailure : SECSuccess ;
+ return (inCertReq->controls == NULL) ? SECFailure : SECSuccess;
}
static SECStatus
-crmf_add_new_control(CRMFCertRequest *inCertReq,SECOidTag inTag,
- CRMFControl **destControl)
+crmf_add_new_control(CRMFCertRequest *inCertReq, SECOidTag inTag,
+ CRMFControl **destControl)
{
- SECOidData *oidData;
- SECStatus rv;
+ SECOidData *oidData;
+ SECStatus rv;
PLArenaPool *poolp;
- int numControls = 0;
+ int numControls = 0;
CRMFControl *newControl;
CRMFControl **controls;
- void *mark;
+ void *mark;
poolp = inCertReq->poolp;
if (poolp == NULL) {
@@ -44,7 +44,7 @@ crmf_add_new_control(CRMFCertRequest *inCertReq,SECOidTag inTag,
mark = PORT_ArenaMark(poolp);
if (inCertReq->controls != NULL) {
while (inCertReq->controls[numControls] != NULL)
- numControls++;
+ numControls++;
}
rv = crmf_modify_control_array(inCertReq, numControls);
if (rv != SECSuccess) {
@@ -52,7 +52,7 @@ crmf_add_new_control(CRMFCertRequest *inCertReq,SECOidTag inTag,
}
controls = inCertReq->controls;
oidData = SECOID_FindOIDByTag(inTag);
- newControl = *destControl = PORT_ArenaZNew(poolp,CRMFControl);
+ newControl = *destControl = PORT_ArenaZNew(poolp, CRMFControl);
if (newControl == NULL) {
goto loser;
}
@@ -62,24 +62,23 @@ crmf_add_new_control(CRMFCertRequest *inCertReq,SECOidTag inTag,
}
newControl->tag = inTag;
controls[numControls] = newControl;
- controls[numControls+1] = NULL;
+ controls[numControls + 1] = NULL;
PORT_ArenaUnmark(poolp, mark);
return SECSuccess;
- loser:
+loser:
PORT_ArenaRelease(poolp, mark);
*destControl = NULL;
return SECFailure;
-
}
static SECStatus
crmf_add_secitem_control(CRMFCertRequest *inCertReq, SECItem *value,
- SECOidTag inTag)
+ SECOidTag inTag)
{
- SECStatus rv;
+ SECStatus rv;
CRMFControl *newControl;
- void *mark;
+ void *mark;
rv = crmf_add_new_control(inCertReq, inTag, &newControl);
if (rv != SECSuccess) {
@@ -89,7 +88,7 @@ crmf_add_secitem_control(CRMFCertRequest *inCertReq, SECItem *value,
rv = SECITEM_CopyItem(inCertReq->poolp, &newControl->derValue, value);
if (rv != SECSuccess) {
PORT_ArenaRelease(inCertReq->poolp, mark);
- return rv;
+ return rv;
}
PORT_ArenaUnmark(inCertReq->poolp, mark);
return SECSuccess;
@@ -98,16 +97,16 @@ crmf_add_secitem_control(CRMFCertRequest *inCertReq, SECItem *value,
SECStatus
CRMF_CertRequestSetRegTokenControl(CRMFCertRequest *inCertReq, SECItem *value)
{
- return crmf_add_secitem_control(inCertReq, value,
- SEC_OID_PKIX_REGCTRL_REGTOKEN);
+ return crmf_add_secitem_control(inCertReq, value,
+ SEC_OID_PKIX_REGCTRL_REGTOKEN);
}
SECStatus
-CRMF_CertRequestSetAuthenticatorControl (CRMFCertRequest *inCertReq,
- SECItem *value)
+CRMF_CertRequestSetAuthenticatorControl(CRMFCertRequest *inCertReq,
+ SECItem *value)
{
- return crmf_add_secitem_control(inCertReq, value,
- SEC_OID_PKIX_REGCTRL_AUTHENTICATOR);
+ return crmf_add_secitem_control(inCertReq, value,
+ SEC_OID_PKIX_REGCTRL_AUTHENTICATOR);
}
SECStatus
@@ -115,32 +114,32 @@ 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;
- }
+ 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;
- }
+ 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);
- }
+ PORT_Free(inEncrValue->encValue.data);
+ inEncrValue->encValue.data = NULL;
+ }
+ if (freeit) {
+ PORT_Free(inEncrValue);
+ }
}
return SECSuccess;
}
@@ -152,19 +151,18 @@ CRMF_DestroyEncryptedValue(CRMFEncryptedValue *inEncrValue)
}
SECStatus
-crmf_copy_encryptedvalue_secalg(PLArenaPool *poolp,
- SECAlgorithmID *srcAlgId,
- SECAlgorithmID **destAlgId)
+crmf_copy_encryptedvalue_secalg(PLArenaPool *poolp,
+ SECAlgorithmID *srcAlgId,
+ SECAlgorithmID **destAlgId)
{
SECAlgorithmID *newAlgId;
SECStatus rv;
- newAlgId = (poolp != NULL) ? PORT_ArenaZNew(poolp, SECAlgorithmID) :
- PORT_ZNew(SECAlgorithmID);
+ 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) {
@@ -173,121 +171,120 @@ crmf_copy_encryptedvalue_secalg(PLArenaPool *poolp,
return rv;
}
*destAlgId = newAlgId;
-
+
return rv;
}
SECStatus
-crmf_copy_encryptedvalue(PLArenaPool *poolp,
- CRMFEncryptedValue *srcValue,
- CRMFEncryptedValue *destValue)
+crmf_copy_encryptedvalue(PLArenaPool *poolp,
+ CRMFEncryptedValue *srcValue,
+ CRMFEncryptedValue *destValue)
{
- SECStatus rv;
+ SECStatus rv;
if (srcValue->intendedAlg != NULL) {
rv = crmf_copy_encryptedvalue_secalg(poolp,
- srcValue->intendedAlg,
- &destValue->intendedAlg);
- if (rv != SECSuccess) {
- goto loser;
- }
+ 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;
- }
+ 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;
- }
+ 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;
- }
+ 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;
- }
+ 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;
- }
+ &destValue->encValue,
+ &srcValue->encValue);
+ if (rv != SECSuccess) {
+ goto loser;
+ }
}
return SECSuccess;
- loser:
+loser:
if (poolp == NULL && destValue != NULL) {
crmf_destroy_encrypted_value(destValue, PR_FALSE);
}
return SECFailure;
}
-SECStatus
-crmf_copy_encryptedkey(PLArenaPool *poolp,
- CRMFEncryptedKey *srcEncrKey,
- CRMFEncryptedKey *destEncrKey)
+SECStatus
+crmf_copy_encryptedkey(PLArenaPool *poolp,
+ CRMFEncryptedKey *srcEncrKey,
+ CRMFEncryptedKey *destEncrKey)
{
- SECStatus rv;
- void *mark = NULL;
+ 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;
+ 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);
+ PORT_ArenaUnmark(poolp, mark);
}
return SECSuccess;
- loser:
+loser:
if (mark) {
PORT_ArenaRelease(poolp, mark);
}
return SECFailure;
}
-static CRMFPKIArchiveOptions*
+static CRMFPKIArchiveOptions *
crmf_create_encr_pivkey_option(CRMFEncryptedKey *inEncryptedKey)
{
CRMFPKIArchiveOptions *newArchOpt;
- SECStatus rv;
+ SECStatus rv;
newArchOpt = PORT_ZNew(CRMFPKIArchiveOptions);
if (newArchOpt == NULL) {
@@ -295,25 +292,25 @@ crmf_create_encr_pivkey_option(CRMFEncryptedKey *inEncryptedKey)
}
rv = crmf_copy_encryptedkey(NULL, inEncryptedKey,
- &newArchOpt->option.encryptedKey);
-
+ &newArchOpt->option.encryptedKey);
+
if (rv != SECSuccess) {
- goto loser;
+ goto loser;
}
newArchOpt->archOption = crmfEncryptedPrivateKey;
return newArchOpt;
- loser:
+loser:
if (newArchOpt != NULL) {
CRMF_DestroyPKIArchiveOptions(newArchOpt);
}
return NULL;
}
-static CRMFPKIArchiveOptions*
+static CRMFPKIArchiveOptions *
crmf_create_keygen_param_option(SECItem *inKeyGenParams)
{
CRMFPKIArchiveOptions *newArchOptions;
- SECStatus rv;
+ SECStatus rv;
newArchOptions = PORT_ZNew(CRMFPKIArchiveOptions);
if (newArchOptions == NULL) {
@@ -321,23 +318,23 @@ crmf_create_keygen_param_option(SECItem *inKeyGenParams)
}
newArchOptions->archOption = crmfKeyGenParameters;
rv = SECITEM_CopyItem(NULL, &newArchOptions->option.keyGenParameters,
- inKeyGenParams);
+ inKeyGenParams);
if (rv != SECSuccess) {
goto loser;
}
return newArchOptions;
- loser:
+loser:
if (newArchOptions != NULL) {
CRMF_DestroyPKIArchiveOptions(newArchOptions);
}
return NULL;
}
-static CRMFPKIArchiveOptions*
+static CRMFPKIArchiveOptions *
crmf_create_arch_rem_gen_privkey(PRBool archiveRemGenPrivKey)
{
- unsigned char value;
- SECItem *dummy;
+ unsigned char value;
+ SECItem *dummy;
CRMFPKIArchiveOptions *newArchOptions;
value = (archiveRemGenPrivKey) ? hexTrue : hexFalse;
@@ -345,63 +342,63 @@ crmf_create_arch_rem_gen_privkey(PRBool archiveRemGenPrivKey)
if (newArchOptions == NULL) {
goto loser;
}
- dummy = SEC_ASN1EncodeItem(NULL,
- &newArchOptions->option.archiveRemGenPrivKey,
- &value, SEC_ASN1_GET(SEC_BooleanTemplate));
- PORT_Assert (dummy == &newArchOptions->option.archiveRemGenPrivKey);
+ 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;
+ SECITEM_FreeItem(dummy, PR_TRUE);
+ goto loser;
}
newArchOptions->archOption = crmfArchiveRemGenPrivKey;
return newArchOptions;
- loser:
+loser:
if (newArchOptions != NULL) {
CRMF_DestroyPKIArchiveOptions(newArchOptions);
}
return NULL;
}
-CRMFPKIArchiveOptions*
+CRMFPKIArchiveOptions *
CRMF_CreatePKIArchiveOptions(CRMFPKIArchiveOptionsType inType, void *data)
{
- CRMFPKIArchiveOptions* retOptions;
+ 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;
+ 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;
+ 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);
@@ -410,37 +407,37 @@ crmf_destroy_encrypted_key(CRMFEncryptedKey *inEncrKey, PRBool freeit)
return SECSuccess;
}
-SECStatus
-crmf_destroy_pkiarchiveoptions(CRMFPKIArchiveOptions *inArchOptions,
- PRBool freeit)
+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);
- }
+ 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)
+CRMF_DestroyPKIArchiveOptions(CRMFPKIArchiveOptions *inArchOptions)
{
return crmf_destroy_pkiarchiveoptions(inArchOptions, PR_TRUE);
}
@@ -449,24 +446,24 @@ 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;
+ 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;
}
@@ -474,8 +471,8 @@ crmf_get_non_pad_mechanism(CK_MECHANISM_TYPE type)
static CK_MECHANISM_TYPE
crmf_get_pad_mech_from_tag(SECOidTag oidTag)
{
- CK_MECHANISM_TYPE mechType;
- SECOidData *oidData;
+ CK_MECHANISM_TYPE mechType;
+ SECOidData *oidData;
oidData = SECOID_FindOIDByTag(oidTag);
mechType = (CK_MECHANISM_TYPE)oidData->mechanism;
@@ -483,24 +480,24 @@ crmf_get_pad_mech_from_tag(SECOidTag oidTag)
}
static CK_MECHANISM_TYPE
-crmf_get_best_privkey_wrap_mechanism(PK11SlotInfo *slot)
+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]);
+ 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++) {
+ for (i = 0; i < mechCount; i++) {
if (PK11_DoesMechanism(slot, privKeyPadMechs[i])) {
- return privKeyPadMechs[i];
- }
+ return privKeyPadMechs[i];
+ }
}
return CKM_INVALID_MECHANISM;
}
@@ -511,12 +508,12 @@ CRMF_GetBestWrapPadMechanism(PK11SlotInfo *slot)
return crmf_get_best_privkey_wrap_mechanism(slot);
}
-static SECItem*
+static SECItem *
crmf_get_iv(CK_MECHANISM_TYPE mechType)
{
- int iv_size = PK11_GetIVLength(mechType);
- SECItem *iv;
- SECStatus rv;
+ int iv_size = PK11_GetIVLength(mechType);
+ SECItem *iv;
+ SECStatus rv;
iv = PORT_ZNew(SECItem);
if (iv == NULL) {
@@ -524,25 +521,25 @@ crmf_get_iv(CK_MECHANISM_TYPE mechType)
}
if (iv_size == 0) {
iv->data = NULL;
- iv->len = 0;
- return iv;
+ iv->len = 0;
+ return iv;
}
iv->data = PORT_NewArray(unsigned char, iv_size);
if (iv->data == NULL) {
iv->len = 0;
- return iv;
+ 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;
+ iv->data = NULL;
+ iv->len = 0;
}
return iv;
}
-SECItem*
+SECItem *
CRMF_GetIVFromMechanism(CK_MECHANISM_TYPE mechType)
{
return crmf_get_iv(mechType);
@@ -552,8 +549,7 @@ CK_MECHANISM_TYPE
crmf_get_mechanism_from_public_key(SECKEYPublicKey *inPubKey)
{
CERTSubjectPublicKeyInfo *spki = NULL;
- SECOidTag tag;
-
+ SECOidTag tag;
spki = SECKEY_CreateSubjectPublicKeyInfo(inPubKey);
if (spki == NULL) {
@@ -565,58 +561,58 @@ crmf_get_mechanism_from_public_key(SECKEYPublicKey *inPubKey)
return PK11_AlgtagToMechanism(tag);
}
-SECItem*
+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;
+ 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;
+ PORT_SetError(SEC_ERROR_INVALID_ARGS);
+ return NULL;
}
if (dest != NULL) {
- SECStatus rv = SECITEM_CopyItem(NULL, dest, src);
- if (rv != SECSuccess) {
- dest = NULL;
- }
+ SECStatus rv = SECITEM_CopyItem(NULL, dest, src);
+ if (rv != SECSuccess) {
+ dest = NULL;
+ }
} else {
dest = SECITEM_ArenaDupItem(NULL, src);
}
return dest;
}
-static SECItem*
+static SECItem *
crmf_decode_params(SECItem *inParams)
{
- SECItem *params;
- SECStatus rv = SECFailure;
+ SECItem *params;
+ SECStatus rv = SECFailure;
PLArenaPool *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);
+ rv = SEC_ASN1DecodeItem(poolp, params,
+ SEC_ASN1_GET(SEC_OctetStringTemplate),
+ inParams);
}
params = (rv == SECSuccess) ? SECITEM_ArenaDupItem(NULL, params) : NULL;
PORT_FreeArena(poolp, PR_FALSE);
@@ -629,37 +625,38 @@ 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;
+ 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(PLArenaPool *poolp,
- CRMFEncryptedValue *encValue,
- SECKEYPrivateKey *privKey,
- SECKEYPublicKey *newPubKey,
- SECItem *nickname,
- PK11SlotInfo *slot,
- unsigned char keyUsage,
- SECKEYPrivateKey **unWrappedKey,
- void *wincx)
+crmf_encrypted_value_unwrap_priv_key(PLArenaPool *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;
+ 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 };
+ CKA_UNWRAP, CKA_DECRYPT, CKA_SIGN, CKA_SIGN_RECOVER
+ };
CK_ATTRIBUTE_TYPE dsaUsage[] = { CKA_SIGN };
CK_ATTRIBUTE_TYPE dhUsage[] = { CKA_DERIVE };
int usageCount = 0;
@@ -667,108 +664,109 @@ crmf_encrypted_value_unwrap_priv_key(PLArenaPool *poolp,
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);
+ 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;
+ } /* 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;
+ 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 KU_DIGITAL_SIGNATURE:
- usage = &rsaUsage[2];
- usageCount = 2;
+ case dhKey:
+ keyType = CKK_DH;
+ usage = dhUsage;
+ usageCount = sizeof(dhUsage) / sizeof(dhUsage[0]);
break;
- case KU_KEY_ENCIPHERMENT|KU_DIGITAL_SIGNATURE:
- case 0: /* default to everything */
- usage = rsaUsage;
- usageCount = 4;
+ case dsaKey:
+ keyType = CKK_DSA;
+ usage = dsaUsage;
+ usageCount = sizeof(dsaUsage) / sizeof(dsaUsage[0]);
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, 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(publicValue, PR_TRUE);
+ if (params != NULL) {
SECITEM_FreeItem(params, PR_TRUE);
- }
+ }
PK11_FreeSymKey(wrappingKey);
return SECSuccess;
- loser:
+loser:
*unWrappedKey = NULL;
return SECFailure;
}
CRMFEncryptedValue *
-crmf_create_encrypted_value_wrapped_privkey(SECKEYPrivateKey *inPrivKey,
- SECKEYPublicKey *inCAKey,
- CRMFEncryptedValue *destValue)
+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;
+ 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);
+ 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;
- }
+ 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.
- */
+ /* 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;
+ slot = inPrivKey->pkcs11Slot;
PORT_Assert(slot != NULL);
symKeyType = crmf_get_best_privkey_wrap_mechanism(slot);
symKey = PK11_KeyGen(slot, symKeyType, NULL, 0, NULL);
@@ -777,7 +775,7 @@ crmf_create_encrypted_value_wrapped_privkey(SECKEYPrivateKey *inPrivKey,
}
wrappedSymKey.data = wrappedSymKeyBits;
- wrappedSymKey.len = MAX_WRAPPED_KEY_LEN;
+ wrappedSymKey.len = MAX_WRAPPED_KEY_LEN;
rv = PK11_PubWrapSymKey(pubMechType, inCAKey, symKey, &wrappedSymKey);
if (rv != SECSuccess) {
goto loser;
@@ -786,26 +784,26 @@ crmf_create_encrypted_value_wrapped_privkey(SECKEYPrivateKey *inPrivKey,
wrappedSymKey.len <<= 3;
wrappedPrivKey.data = wrappedPrivKeyBits;
- wrappedPrivKey.len = MAX_WRAPPED_KEY_LEN;
+ wrappedPrivKey.len = MAX_WRAPPED_KEY_LEN;
iv = crmf_get_iv(symKeyType);
- rv = PK11_WrapPrivKey(slot, symKey, inPrivKey, symKeyType, iv,
- &wrappedPrivKey, NULL);
+ 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);
+ rv = crmf_make_bitstring_copy(NULL,
+ &destValue->encValue,
+ &wrappedPrivKey);
if (rv != SECSuccess) {
goto loser;
}
rv = crmf_make_bitstring_copy(NULL,
- &destValue->encSymmKey,
- &wrappedSymKey);
+ &destValue->encSymmKey,
+ &wrappedSymKey);
if (rv != SECSuccess) {
goto loser;
}
@@ -814,11 +812,11 @@ crmf_create_encrypted_value_wrapped_privkey(SECKEYPrivateKey *inPrivKey,
goto loser;
}
- dummy = SEC_ASN1EncodeItem(NULL, &encodedParam, iv,
+ dummy = SEC_ASN1EncodeItem(NULL, &encodedParam, iv,
SEC_ASN1_GET(SEC_OctetStringTemplate));
if (dummy != &encodedParam) {
SECITEM_FreeItem(dummy, PR_TRUE);
- goto loser;
+ goto loser;
}
symKeyType = crmf_get_non_pad_mechanism(symKeyType);
@@ -832,9 +830,9 @@ crmf_create_encrypted_value_wrapped_privkey(SECKEYPrivateKey *inPrivKey,
PORT_Free(wrappedSymKeyBits);
SECITEM_FreeItem(iv, PR_TRUE);
return destValue;
- loser:
+loser:
if (iv != NULL) {
- SECITEM_FreeItem(iv, PR_TRUE);
+ SECITEM_FreeItem(iv, PR_TRUE);
}
if (myEncrValue != NULL) {
crmf_destroy_encrypted_value(myEncrValue, PR_TRUE);
@@ -846,17 +844,17 @@ crmf_create_encrypted_value_wrapped_privkey(SECKEYPrivateKey *inPrivKey,
PORT_Free(wrappedPrivKeyBits);
}
if (encodedParam.data != NULL) {
- SECITEM_FreeItem(&encodedParam, PR_FALSE);
+ SECITEM_FreeItem(&encodedParam, PR_FALSE);
}
return NULL;
}
-CRMFEncryptedKey*
-CRMF_CreateEncryptedKeyWithEncryptedValue (SECKEYPrivateKey *inPrivKey,
- CERTCertificate *inCACert)
+CRMFEncryptedKey *
+CRMF_CreateEncryptedKeyWithEncryptedValue(SECKEYPrivateKey *inPrivKey,
+ CERTCertificate *inCACert)
{
- SECKEYPublicKey *caPubKey = NULL;
- CRMFEncryptedKey *encKey = NULL;
+ SECKEYPublicKey *caPubKey = NULL;
+ CRMFEncryptedKey *encKey = NULL;
PORT_Assert(inPrivKey != NULL && inCACert != NULL);
if (inPrivKey == NULL || inCACert == NULL) {
@@ -883,13 +881,13 @@ CRMF_CreateEncryptedKeyWithEncryptedValue (SECKEYPrivateKey *inPrivKey,
crmf_create_encrypted_value_wrapped_privkey(
inPrivKey, caPubKey, &encKey->value.encryptedValue);
#endif
- /* We won't add the der value here, but rather when it
+ /* 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:
+loser:
if (encKey != NULL) {
CRMF_DestroyEncryptedKey(encKey);
}
@@ -906,29 +904,29 @@ CRMF_DestroyEncryptedKey(CRMFEncryptedKey *inEncrKey)
}
SECStatus
-crmf_copy_pkiarchiveoptions(PLArenaPool *poolp,
- CRMFPKIArchiveOptions *destOpt,
- CRMFPKIArchiveOptions *srcOpt)
+crmf_copy_pkiarchiveoptions(PLArenaPool *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;
+ 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;
}
@@ -940,23 +938,23 @@ crmf_check_and_adjust_archoption(CRMFControl *inControl)
options = &inControl->value.archiveOptions;
if (options->archOption == crmfNoArchiveOptions) {
- /* It hasn't been set, so figure it out from the
- * der.
- */
+ /* 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;
- }
+ 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;
}
@@ -965,10 +963,10 @@ static const SEC_ASN1Template *
crmf_get_pkiarchive_subtemplate(CRMFControl *inControl)
{
const SEC_ASN1Template *retTemplate;
- SECStatus rv;
+ 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
+ * archOption field will not be set. Let's check it and set
* it accordingly.
*/
@@ -978,38 +976,38 @@ crmf_get_pkiarchive_subtemplate(CRMFControl *inControl)
}
switch (inControl->value.archiveOptions.archOption) {
- case crmfEncryptedPrivateKey:
- retTemplate = CRMFEncryptedKeyWithEncryptedValueTemplate;
- inControl->value.archiveOptions.option.encryptedKey.encKeyChoice =
- crmfEncryptedValueChoice;
- break;
- default:
- retTemplate = NULL;
+ case crmfEncryptedPrivateKey:
+ retTemplate = CRMFEncryptedKeyWithEncryptedValueTemplate;
+ inControl->value.archiveOptions.option.encryptedKey.encKeyChoice =
+ crmfEncryptedValueChoice;
+ break;
+ default:
+ retTemplate = NULL;
}
return retTemplate;
}
-const SEC_ASN1Template*
+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;
+ 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;
}
@@ -1020,7 +1018,7 @@ crmf_encode_pkiarchiveoptions(PLArenaPool *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
+ /* 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.
*/
@@ -1031,46 +1029,46 @@ crmf_encode_pkiarchiveoptions(PLArenaPool *poolp, CRMFControl *inControl)
goto loser;
}
return SECSuccess;
- loser:
+loser:
return SECFailure;
}
SECStatus
-CRMF_CertRequestSetPKIArchiveOptions(CRMFCertRequest *inCertReq,
- CRMFPKIArchiveOptions *inOptions)
+CRMF_CertRequestSetPKIArchiveOptions(CRMFCertRequest *inCertReq,
+ CRMFPKIArchiveOptions *inOptions)
{
CRMFControl *newControl;
PLArenaPool *poolp;
- SECStatus rv;
- void *mark;
-
+ 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);
+ 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);
+ rv = crmf_copy_pkiarchiveoptions(poolp,
+ &newControl->value.archiveOptions,
+ inOptions);
if (rv != SECSuccess) {
goto loser;
}
- rv = crmf_encode_pkiarchiveoptions(poolp, newControl);
+ rv = crmf_encode_pkiarchiveoptions(poolp, newControl);
if (rv != SECSuccess) {
goto loser;
}
PORT_ArenaUnmark(poolp, mark);
return SECSuccess;
- loser:
+loser:
PORT_ArenaRelease(poolp, mark);
return SECFailure;
}
@@ -1082,25 +1080,25 @@ crmf_destroy_control(CRMFControl *inControl, PRBool freeit)
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);
- }
+ /* 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;
}
@@ -1116,49 +1114,48 @@ 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;
+ 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)
+ CRMFControlType inControlType)
{
SECOidTag controlTag;
- int i;
+ 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++) {
+ for (i = 0; inCertReq->controls[i] != NULL; i++) {
if (inCertReq->controls[i]->tag == controlTag) {
- return PR_TRUE;
- }
+ return PR_TRUE;
+ }
}
return PR_FALSE;
}
-
diff --git a/nss/lib/crmf/crmfdec.c b/nss/lib/crmf/crmfdec.c
index 6be165f..ac6e872 100644
--- a/nss/lib/crmf/crmfdec.c
+++ b/nss/lib/crmf/crmfdec.c
@@ -3,7 +3,6 @@
* License, v. 2.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"
@@ -14,35 +13,35 @@ 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;
+ 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;
+ pop->popChoice.raVerified.len = 0;
return SECSuccess;
}
@@ -51,14 +50,14 @@ crmf_decode_process_signature(CRMFCertReqMsg *inCertReqMsg)
{
PORT_Assert(inCertReqMsg->poolp);
if (!inCertReqMsg->poolp) {
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- return SECFailure;
+ 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);
+ &inCertReqMsg->pop->popChoice.signature,
+ CRMFPOPOSigningKeyTemplate,
+ (const char *)inCertReqMsg->derPOP.data,
+ inCertReqMsg->derPOP.len);
}
static CRMFPOPOPrivKeyChoice
@@ -67,17 +66,17 @@ 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;
+ case 0:
+ retChoice = crmfThisMessage;
+ break;
+ case 1:
+ retChoice = crmfSubsequentMessage;
+ break;
+ case 2:
+ retChoice = crmfDHMAC;
+ break;
+ default:
+ retChoice = crmfNoMessage;
}
return retChoice;
}
@@ -86,13 +85,13 @@ 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
+ * struct is the same as having a pointer to the other
* one.
*/
- CRMFPOPOPrivKey *popoPrivKey =
- &inCertReqMsg->pop->popChoice.keyEncipherment;
- SECItem *derPOP, privKeyDer;
- SECStatus rv;
+ CRMFPOPOPrivKey *popoPrivKey =
+ &inCertReqMsg->pop->popChoice.keyEncipherment;
+ SECItem *derPOP, privKeyDer;
+ SECStatus rv;
derPOP = &inCertReqMsg->derPOP;
popoPrivKey->messageChoice = crmf_get_messagechoice_from_der(derPOP);
@@ -101,37 +100,36 @@ crmf_decode_process_popoprivkey(CRMFCertReqMsg *inCertReqMsg)
}
/* 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;
+ 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);
+ rv = SECITEM_CopyItem(inCertReqMsg->poolp,
+ &popoPrivKey->message.subsequentMessage,
+ &privKeyDer);
if (rv != SECSuccess) {
return rv;
}
if (popoPrivKey->messageChoice == crmfThisMessage ||
- popoPrivKey->messageChoice == crmfDHMAC) {
+ popoPrivKey->messageChoice == crmfDHMAC) {
- popoPrivKey->message.thisMessage.len =
- CRMF_BYTES_TO_BITS(privKeyDer.len) - (int)derPOP->data[4];
-
+ popoPrivKey->message.thisMessage.len =
+ CRMF_BYTES_TO_BITS(privKeyDer.len) - (int)derPOP->data[4];
}
- return SECSuccess;
+ return SECSuccess;
}
static SECStatus
@@ -149,11 +147,11 @@ crmf_decode_process_keyencipherment(CRMFCertReqMsg *inCertReqMsg)
if (rv != SECSuccess) {
return rv;
}
- if (inCertReqMsg->pop->popChoice.keyEncipherment.messageChoice ==
- crmfDHMAC) {
+ if (inCertReqMsg->pop->popChoice.keyEncipherment.messageChoice ==
+ crmfDHMAC) {
/* Key Encipherment can not use the dhMAC option for
- * POPOPrivKey.
- */
+ * POPOPrivKey.
+ */
return SECFailure;
}
return SECSuccess;
@@ -162,100 +160,99 @@ crmf_decode_process_keyencipherment(CRMFCertReqMsg *inCertReqMsg)
static SECStatus
crmf_decode_process_pop(CRMFCertReqMsg *inCertReqMsg)
{
- SECItem *derPOP;
- PLArenaPool *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;
-
+ SECItem *derPOP;
+ PLArenaPool *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(PLArenaPool *poolp,
- CRMFControl *inControl)
+ 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);
+ PORT_Assert(asn1Template != NULL);
+ PORT_Assert(poolp != NULL);
if (!asn1Template || !poolp) {
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- return SECFailure;
+ 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);
+ return SEC_ASN1Decode(poolp, &inControl->value.archiveOptions,
+ asn1Template, (const char *)inControl->derValue.data,
+ inControl->derValue.len);
}
-static SECStatus
+static SECStatus
crmf_decode_process_controls(CRMFCertReqMsg *inCertReqMsg)
{
- int i, numControls;
- SECStatus rv;
- PLArenaPool *poolp;
+ int i, numControls;
+ SECStatus rv;
+ PLArenaPool *poolp;
CRMFControl **controls;
-
+
numControls = CRMF_CertRequestGetNumControls(inCertReqMsg->certReq);
controls = inCertReqMsg->certReq->controls;
- poolp = inCertReqMsg->poolp;
- for (i=0; i < numControls; i++) {
+ poolp = inCertReqMsg->poolp;
+ for (i = 0; i < numControls; i++) {
rv = crmf_decode_process_single_control(poolp, controls[i]);
- if (rv != SECSuccess) {
- return SECFailure;
- }
+ if (rv != SECSuccess) {
+ return SECFailure;
+ }
}
return SECSuccess;
}
@@ -274,26 +271,26 @@ crmf_decode_process_single_reqmsg(CRMFCertReqMsg *inCertReqMsg)
if (rv != SECSuccess) {
goto loser;
}
- inCertReqMsg->certReq->certTemplate.numExtensions =
+ inCertReqMsg->certReq->certTemplate.numExtensions =
CRMF_CertRequestGetNumberOfExtensions(inCertReqMsg->certReq);
inCertReqMsg->isDecoded = PR_TRUE;
rv = SECSuccess;
- loser:
+loser:
return rv;
}
-CRMFCertReqMsg*
-CRMF_CreateCertReqMsgFromDER (const char * buf, long len)
+CRMFCertReqMsg *
+CRMF_CreateCertReqMsgFromDER(const char *buf, long len)
{
- PLArenaPool *poolp;
+ PLArenaPool *poolp;
CRMFCertReqMsg *certReqMsg;
- SECStatus rv;
+ SECStatus rv;
poolp = PORT_NewArena(CRMF_DEFAULT_ARENA_SIZE);
if (poolp == NULL) {
goto loser;
}
- certReqMsg = PORT_ArenaZNew (poolp, CRMFCertReqMsg);
+ certReqMsg = PORT_ArenaZNew(poolp, CRMFCertReqMsg);
if (certReqMsg == NULL) {
goto loser;
}
@@ -309,27 +306,27 @@ CRMF_CreateCertReqMsgFromDER (const char * buf, long len)
}
return certReqMsg;
- loser:
+loser:
if (poolp != NULL) {
PORT_FreeArena(poolp, PR_FALSE);
}
return NULL;
}
-CRMFCertReqMessages*
+CRMFCertReqMessages *
CRMF_CreateCertReqMessagesFromDER(const char *buf, long len)
{
- long arenaSize;
- int i;
- SECStatus rv;
- PLArenaPool *poolp;
+ long arenaSize;
+ int i;
+ SECStatus rv;
+ PLArenaPool *poolp;
CRMFCertReqMessages *certReqMsgs;
- PORT_Assert (buf != NULL);
+ 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;
+ arenaSize = len + len / 2;
poolp = PORT_NewArena(arenaSize);
if (poolp == NULL) {
return NULL;
@@ -340,24 +337,24 @@ CRMF_CreateCertReqMessagesFromDER(const char *buf, long len)
}
certReqMsgs->poolp = poolp;
rv = SEC_ASN1Decode(poolp, certReqMsgs, CRMFCertReqMessagesTemplate,
- buf, len);
+ 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.
- */
+ 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;
- }
+ if (rv != SECSuccess) {
+ goto loser;
+ }
certReqMsgs->messages[i]->poolp = NULL;
}
return certReqMsgs;
- loser:
+loser:
PORT_FreeArena(poolp, PR_FALSE);
return NULL;
}
diff --git a/nss/lib/crmf/crmfenc.c b/nss/lib/crmf/crmfenc.c
index bf36018..6d01a45 100644
--- a/nss/lib/crmf/crmfenc.c
+++ b/nss/lib/crmf/crmfenc.c
@@ -3,53 +3,46 @@
* License, v. 2.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)
+SECStatus
+CRMF_EncodeCertReqMsg(CRMFCertReqMsg *inCertReqMsg,
+ CRMFEncoderOutputCallback fn,
+ void *arg)
{
struct crmfEncoderOutput output;
- output.fn = fn;
+ output.fn = fn;
output.outputArg = arg;
- return SEC_ASN1Encode(inCertReqMsg,CRMFCertReqMsgTemplate,
- crmf_encoder_out, &output);
-
+ return SEC_ASN1Encode(inCertReqMsg, CRMFCertReqMsgTemplate,
+ crmf_encoder_out, &output);
}
-
SECStatus
-CRMF_EncodeCertRequest(CRMFCertRequest *inCertReq,
- CRMFEncoderOutputCallback fn,
- void *arg)
+CRMF_EncodeCertRequest(CRMFCertRequest *inCertReq,
+ CRMFEncoderOutputCallback fn,
+ void *arg)
{
struct crmfEncoderOutput output;
- output.fn = fn;
+ output.fn = fn;
output.outputArg = arg;
- return SEC_ASN1Encode(inCertReq, CRMFCertRequestTemplate,
- crmf_encoder_out, &output);
+ return SEC_ASN1Encode(inCertReq, CRMFCertRequestTemplate,
+ crmf_encoder_out, &output);
}
SECStatus
-CRMF_EncodeCertReqMessages(CRMFCertReqMsg **inCertReqMsgs,
- CRMFEncoderOutputCallback fn,
- void *arg)
+CRMF_EncodeCertReqMessages(CRMFCertReqMsg **inCertReqMsgs,
+ CRMFEncoderOutputCallback fn,
+ void *arg)
{
struct crmfEncoderOutput output;
CRMFCertReqMessages msgs;
-
- output.fn = fn;
+
+ output.fn = fn;
output.outputArg = arg;
msgs.messages = inCertReqMsgs;
return SEC_ASN1Encode(&msgs, CRMFCertReqMessagesTemplate,
- crmf_encoder_out, &output);
+ crmf_encoder_out, &output);
}
-
-
-
-
diff --git a/nss/lib/crmf/crmffut.h b/nss/lib/crmf/crmffut.h
index bde8241..d6f9374 100644
--- a/nss/lib/crmf/crmffut.h
+++ b/nss/lib/crmf/crmffut.h
@@ -8,112 +8,111 @@
*/
/*
- * Use this function to create the CRMFSinglePubInfo* variables that will
+ * 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
+ * "pubLocation" is a representation of the location where
*/
-extern CRMFSinglePubInfo*
- CRMF_CreateSinglePubInfo(CRMFPublicationMethod inPubMethod,
- CRMFGeneralName *pubLocation);
+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);
+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_DestroyPKIPublicationInfo(CRMFPKIPublicationInfo *inPubInfo);
-extern SECStatus CRMF_AddPubInfoControl(CRMFCertRequest *inCertReq,
- CRMFPKIPublicationInfo *inPubInfo);
+extern SECStatus CRMF_AddPubInfoControl(CRMFCertRequest *inCertReq,
+ CRMFPKIPublicationInfo *inPubInfo);
/*
- * This is to create a Cert ID Control which can later be added to
+ * 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 CRMFCertID *CRMF_CreateCertID(CRMFGeneralName *issuer,
+ long serialNumber);
-extern SECStatus CRMF_DestroyCertID(CRMFCertID* certID);
+extern SECStatus CRMF_DestroyCertID(CRMFCertID *certID);
extern SECStatus CRMF_AddCertIDControl(CRMFCertRequest *inCertReq,
- CRMFCertID *certID);
+ CRMFCertID *certID);
-extern SECStatus
- CRMF_AddProtocolEncryptioKeyControl(CRMFCertRequest *inCertReq,
- CERTSubjectPublicKeyInfo *spki);
+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);
+CRMF_AddUTF8PairsRegInfo(CRMFCertRequest *inCertReq,
+ SECItem *asciiPairs);
/*
- * This takes a CertRequest and adds it to another CertRequest.
+ * This takes a CertRequest and adds it to another CertRequest.
*/
extern SECStatus
- CRMF_AddCertReqToRegInfo(CRMFCertRequest *certReqToAddTo,
- CRMFCertRequest *certReqBeingAdded);
+CRMF_AddCertReqToRegInfo(CRMFCertRequest *certReqToAddTo,
+ CRMFCertRequest *certReqBeingAdded);
/*
* Returns which option was used for the authInfo field of POPOSigningKeyInput
*/
-extern CRMFPOPOSkiInputAuthChoice
- CRMF_GetSignKeyInputAuthChoice(CRMFPOPOSigningKeyInput *inKeyInput);
+extern CRMFPOPOSkiInputAuthChoice
+CRMF_GetSignKeyInputAuthChoice(CRMFPOPOSigningKeyInput *inKeyInput);
/*
* Gets the PKMACValue associated with the POPOSigningKeyInput.
- * If the POPOSigningKeyInput did not use authInfo.publicKeyMAC
+ * 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);
+extern SECStatus
+CRMF_GetSignKeyInputPKMACValue(CRMFPOPOSigningKeyInput *inKeyInput,
+ CRMFPKMACValue **destValue);
/*
* Gets the SubjectPublicKeyInfo from the POPOSigningKeyInput
*/
extern CERTSubjectPublicKeyInfo *
- CRMF_GetSignKeyInputPublicKey(CRMFPOPOSigningKeyInput *inKeyInput);
-
+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
+ * 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);
+extern CRMFPKIPublicationInfo *CRMF_GetPKIPubInfo(CRMFControl *inControl);
/*
* Free up a CRMFPKIPublicationInfo structure.
*/
-extern SECStatus
- CRMF_DestroyPKIPublicationInfo(CRMFPKIPublicationInfo *inPubInfo);
+extern SECStatus
+CRMF_DestroyPKIPublicationInfo(CRMFPKIPublicationInfo *inPubInfo);
/*
* Get the choice used for action in this PKIPublicationInfo.
*/
-extern CRMFPublicationAction
- CRMF_GetPublicationAction(CRMFPKIPublicationInfo *inPubInfo);
+extern CRMFPublicationAction
+CRMF_GetPublicationAction(CRMFPKIPublicationInfo *inPubInfo);
/*
* Get the number of pubInfos are stored in the PKIPubicationInfo.
@@ -124,9 +123,9 @@ 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);
+extern CRMFSinglePubInfo *
+CRMF_GetPubInfoAtIndex(CRMFPKIPublicationInfo *inPubInfo,
+ int index);
/*
* Destroy the CRMFSinglePubInfo.
@@ -136,15 +135,15 @@ extern SECStatus CRMF_DestroySinglePubInfo(CRMFSinglePubInfo *inPubInfo);
/*
* Get the pubMethod used by the SinglePubInfo.
*/
-extern CRMFPublicationMethod
- CRMF_GetPublicationMethod(CRMFSinglePubInfo *inPubInfo);
+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);
+extern CRMFGeneralName *CRMF_GetPubLocation(CRMFSinglePubInfo *inPubInfo);
/*
* Get the authInfo.sender field out of the POPOSigningKeyInput.
@@ -155,7 +154,7 @@ extern CRMFGeneralName* CRMF_GetPubLocation(CRMFSinglePubInfo *inPubInfo);
* SECSuccess and puts the authInfo.sender at *destName/
*/
extern SECStatus CRMF_GetSignKeyInputSender(CRMFPOPOSigningKeyInput *keyInput,
- CRMFGeneralName **destName);
+ CRMFGeneralName **destName);
/**************** CMMF Functions that need to be added. **********************/
@@ -175,7 +174,7 @@ extern SECStatus CRMF_GetSignKeyInputSender(CRMFPOPOSigningKeyInput *keyInput,
* 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
+ * library will use SHA1 as the one-way function for generating the
* witess field of the challenge.
*
* RETURN:
@@ -184,11 +183,10 @@ extern SECStatus CRMF_GetSignKeyInputSender(CRMFPOPOSigningKeyInput *keyInput,
* while trying to generate the challenge.
*/
extern SECStatus
-CMMF_POPODecKeyChallContentSetNextChallenge
- (CMMFPOPODecKeyChallContent *inDecKeyChall,
- long inRandom,
- CERTGeneralName *inSender,
- SECKEYPublicKey *inPubKey);
+CMMF_POPODecKeyChallContentSetNextChallenge(CMMFPOPODecKeyChallContent *inDecKeyChall,
+ long inRandom,
+ CERTGeneralName *inSender,
+ SECKEYPublicKey *inPubKey);
/*
* FUNCTION: CMMF_POPODecKeyChallContentGetNumChallenges
@@ -196,11 +194,10 @@ CMMF_POPODecKeyChallContentSetNextChallenge
* inKeyChallCont
* The CMMFPOPODecKeyChallContent to operate on.
* RETURN:
- * This function returns the number of CMMFChallenges are contained in
+ * This function returns the number of CMMFChallenges are contained in
* the CMMFPOPODecKeyChallContent structure.
*/
-extern int CMMF_POPODecKeyChallContentGetNumChallenges
- (CMMFPOPODecKeyChallContent *inKeyChallCont);
+extern int CMMF_POPODecKeyChallContentGetNumChallenges(CMMFPOPODecKeyChallContent *inKeyChallCont);
/*
* FUNCTION: CMMF_ChallengeGetRandomNumber
@@ -213,9 +210,9 @@ extern int CMMF_POPODecKeyChallContentGetNumChallenges
* 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
+ * 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:
@@ -225,7 +222,7 @@ extern int CMMF_POPODecKeyChallContentGetNumChallenges
* is not a valid value.
*/
extern SECStatus CMMF_ChallengeGetRandomNumber(CMMFChallenge *inChallenge,
- long *inDest);
+ long *inDest);
/*
* FUNCTION: CMMF_ChallengeGetSender
@@ -234,8 +231,8 @@ extern SECStatus CMMF_ChallengeGetRandomNumber(CMMFChallenge *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
+ * 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.
@@ -245,7 +242,7 @@ extern SECStatus CMMF_ChallengeGetRandomNumber(CMMFChallenge *inChallenge,
* 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);
+extern CERTGeneralName *CMMF_ChallengeGetSender(CMMFChallenge *inChallenge);
/*
* FUNCTION: CMMF_ChallengeGetAlgId
@@ -256,19 +253,19 @@ extern CERTGeneralName* CMMF_ChallengeGetSender(CMMFChallenge *inChallenge);
* 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
+ * 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
+ * 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);
+extern SECStatus CMMF_ChallengeGetAlgId(CMMFChallenge *inChallenge,
+ SECAlgorithmID *inAlgId);
/*
* FUNCTION: CMMF_DestroyChallenge
@@ -276,14 +273,14 @@ extern SECStatus CMMF_ChallengeGetAlgId(CMMFChallenge *inChallenge,
* inChallenge
* The CMMFChallenge to free up.
* NOTES:
- * This function frees up all the memory associated with the CMMFChallenge
+ * 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
+ * passed in is successful. Any other return value indicates an error
* while freeing the memory.
*/
-extern SECStatus CMMF_DestroyChallenge (CMMFChallenge *inChallenge);
+extern SECStatus CMMF_DestroyChallenge(CMMFChallenge *inChallenge);
/*
* FUNCTION: CMMF_DestroyPOPODecKeyRespContent
@@ -291,7 +288,7 @@ extern SECStatus CMMF_DestroyChallenge (CMMFChallenge *inChallenge);
* inDecKeyResp
* The CMMFPOPODecKeyRespContent structure to free.
* NOTES:
- * This function frees up all the memory associate with the
+ * This function frees up all the memory associate with the
* CMMFPOPODecKeyRespContent.
*
* RETURN:
@@ -300,7 +297,7 @@ extern SECStatus CMMF_DestroyChallenge (CMMFChallenge *inChallenge);
* return value indicates an error while freeing the memory.
*/
extern SECStatus
- CMMF_DestroyPOPODecKeyRespContent(CMMFPOPODecKeyRespContent *inDecKeyResp);
+CMMF_DestroyPOPODecKeyRespContent(CMMFPOPODecKeyRespContent *inDecKeyResp);
/*
* FUNCTION: CMMF_ChallengeDecryptWitness
@@ -312,7 +309,7 @@ extern SECStatus
* 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
+ * 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
@@ -320,15 +317,15 @@ extern SECStatus
*
* 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
+ * 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);
+extern SECStatus CMMF_ChallengeDecryptWitness(CMMFChallenge *inChallenge,
+ SECKEYPrivateKey *inPrivKey);
/*
* FUNCTION: CMMF_ChallengeIsDecrypted
@@ -336,8 +333,8 @@ extern SECStatus CMMF_ChallengeDecryptWitness(CMMFChallenge *inChallenge,
* 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
+ * 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);
@@ -348,14 +345,13 @@ extern PRBool CMMF_ChallengeIsDecrypted(CMMFChallenge *inChallenge);
* inDecKeyCont
* The CMMFPOPODecKeyChallContent to free
* NOTES:
- * This function frees up all the memory associated with the
- * CMMFPOPODecKeyChallContent
+ * This function frees up all the memory associated with the
+ * CMMFPOPODecKeyChallContent
* RETURN:
- * SECSuccess if freeing up all the memory associatd with the
+ * 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);
-
+extern SECStatus
+CMMF_DestroyPOPODecKeyChallContent(CMMFPOPODecKeyChallContent *inDecKeyCont);
diff --git a/nss/lib/crmf/crmfget.c b/nss/lib/crmf/crmfget.c
index 4886cda..5c1d2aa 100644
--- a/nss/lib/crmf/crmfget.c
+++ b/nss/lib/crmf/crmfget.c
@@ -8,7 +8,6 @@
#include "keyhi.h"
#include "secder.h"
-
CRMFPOPChoice
CRMF_CertReqMsgGetPOPType(CRMFCertReqMsg *inCertReqMsg)
{
@@ -22,50 +21,49 @@ CRMF_CertReqMsgGetPOPType(CRMFCertReqMsg *inCertReqMsg)
static SECStatus
crmf_destroy_validity(CRMFOptionalValidity *inValidity, PRBool freeit)
{
- if (inValidity != NULL){
+ 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);
- }
+ 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(PLArenaPool *poolp,
- CRMFOptionalValidity **destValidity,
- CRMFOptionalValidity *srcValidity)
+static SECStatus
+crmf_copy_cert_request_validity(PLArenaPool *poolp,
+ CRMFOptionalValidity **destValidity,
+ CRMFOptionalValidity *srcValidity)
{
CRMFOptionalValidity *myValidity = NULL;
- SECStatus rv;
+ SECStatus rv;
- *destValidity = myValidity = (poolp == NULL) ?
- PORT_ZNew(CRMFOptionalValidity) :
- PORT_ArenaZNew(poolp, CRMFOptionalValidity);
+ *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;
- }
+ 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;
- }
+ rv = SECITEM_CopyItem(poolp, &myValidity->notAfter,
+ &srcValidity->notAfter);
+ if (rv != SECSuccess) {
+ goto loser;
+ }
}
return SECSuccess;
- loser:
+loser:
if (myValidity != NULL && poolp == NULL) {
crmf_destroy_validity(myValidity, PR_TRUE);
}
@@ -73,11 +71,11 @@ crmf_copy_cert_request_validity(PLArenaPool *poolp,
}
static SECStatus
-crmf_copy_extensions(PLArenaPool *poolp,
- CRMFCertTemplate *destTemplate,
- CRMFCertExtension **srcExt)
+crmf_copy_extensions(PLArenaPool *poolp,
+ CRMFCertTemplate *destTemplate,
+ CRMFCertExtension **srcExt)
{
- int numExt = 0, i;
+ int numExt = 0, i;
CRMFCertExtension **myExtArray = NULL;
while (srcExt[numExt] != NULL) {
@@ -86,32 +84,32 @@ crmf_copy_extensions(PLArenaPool *poolp,
if (numExt == 0) {
/*No extensions to copy.*/
destTemplate->extensions = NULL;
- destTemplate->numExtensions = 0;
+ destTemplate->numExtensions = 0;
return SECSuccess;
}
- destTemplate->extensions = myExtArray =
- PORT_NewArray(CRMFCertExtension*, numExt+1);
+ destTemplate->extensions = myExtArray =
+ PORT_NewArray(CRMFCertExtension *, numExt + 1);
if (myExtArray == NULL) {
goto loser;
}
-
- for (i=0; i<numExt; i++) {
+
+ for (i = 0; i < numExt; i++) {
myExtArray[i] = crmf_copy_cert_extension(poolp, srcExt[i]);
- if (myExtArray[i] == NULL) {
- goto loser;
- }
+ if (myExtArray[i] == NULL) {
+ goto loser;
+ }
}
destTemplate->numExtensions = numExt;
myExtArray[numExt] = NULL;
return SECSuccess;
- loser:
+loser:
if (myExtArray != NULL) {
if (poolp == NULL) {
- for (i=0; myExtArray[i] != NULL; i++) {
- CRMF_DestroyCertExtension(myExtArray[i]);
- }
- }
- PORT_Free(myExtArray);
+ for (i = 0; myExtArray[i] != NULL; i++) {
+ CRMF_DestroyCertExtension(myExtArray[i]);
+ }
+ }
+ PORT_Free(myExtArray);
}
destTemplate->extensions = NULL;
destTemplate->numExtensions = 0;
@@ -119,95 +117,94 @@ crmf_copy_extensions(PLArenaPool *poolp,
}
static SECStatus
-crmf_copy_cert_request_template(PLArenaPool *poolp,
- CRMFCertTemplate *destTemplate,
- CRMFCertTemplate *srcTemplate)
+crmf_copy_cert_request_template(PLArenaPool *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;
- }
+ 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;
- }
+ &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;
- }
+ 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;
- }
+ 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;
- }
+ 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;
- }
+ 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;
- }
+ 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;
- }
+ &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;
- }
+ &srcTemplate->subjectUID);
+ if (rv != SECSuccess) {
+ goto loser;
+ }
}
if (srcTemplate->extensions != NULL) {
rv = crmf_copy_extensions(poolp, destTemplate,
- srcTemplate->extensions);
- if (rv != SECSuccess) {
- goto loser;
- }
+ srcTemplate->extensions);
+ if (rv != SECSuccess) {
+ goto loser;
+ }
}
return SECSuccess;
- loser:
+loser:
return SECFailure;
}
-static CRMFControl*
+static CRMFControl *
crmf_copy_control(PLArenaPool *poolp, CRMFControl *srcControl)
{
CRMFControl *newControl;
- SECStatus rv;
+ SECStatus rv;
- newControl = (poolp == NULL) ? PORT_ZNew(CRMFControl) :
- PORT_ArenaZNew(poolp, CRMFControl);
+ newControl = (poolp == NULL) ? PORT_ZNew(CRMFControl) : PORT_ArenaZNew(poolp, CRMFControl);
if (newControl == NULL) {
goto loser;
}
@@ -225,20 +222,20 @@ crmf_copy_control(PLArenaPool *poolp, CRMFControl *srcControl)
* 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;
+ 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:
+loser:
if (poolp == NULL && newControl != NULL) {
CRMF_DestroyControl(newControl);
}
@@ -246,11 +243,11 @@ crmf_copy_control(PLArenaPool *poolp, CRMFControl *srcControl)
}
static SECStatus
-crmf_copy_cert_request_controls(PLArenaPool *poolp,
- CRMFCertRequest *destReq,
- CRMFCertRequest *srcReq)
+crmf_copy_cert_request_controls(PLArenaPool *poolp,
+ CRMFCertRequest *destReq,
+ CRMFCertRequest *srcReq)
{
- int numControls, i;
+ int numControls, i;
CRMFControl **myControls = NULL;
numControls = CRMF_CertRequestGetNumControls(srcReq);
@@ -258,43 +255,41 @@ crmf_copy_cert_request_controls(PLArenaPool *poolp,
/* No Controls To Copy*/
return SECSuccess;
}
- myControls = destReq->controls = PORT_NewArray(CRMFControl*,
- numControls+1);
+ myControls = destReq->controls = PORT_NewArray(CRMFControl *,
+ numControls + 1);
if (myControls == NULL) {
goto loser;
}
- for (i=0; i<numControls; i++) {
+ for (i = 0; i < numControls; i++) {
myControls[i] = crmf_copy_control(poolp, srcReq->controls[i]);
- if (myControls[i] == NULL) {
- goto loser;
- }
+ if (myControls[i] == NULL) {
+ goto loser;
+ }
}
myControls[numControls] = NULL;
return SECSuccess;
- loser:
+loser:
if (myControls != NULL) {
if (poolp == NULL) {
- for (i=0; myControls[i] != NULL; i++) {
- CRMF_DestroyControl(myControls[i]);
- }
- }
- PORT_Free(myControls);
+ for (i = 0; myControls[i] != NULL; i++) {
+ CRMF_DestroyControl(myControls[i]);
+ }
+ }
+ PORT_Free(myControls);
}
return SECFailure;
}
-
-CRMFCertRequest*
+CRMFCertRequest *
crmf_copy_cert_request(PLArenaPool *poolp, CRMFCertRequest *srcReq)
{
CRMFCertRequest *newReq = NULL;
- SECStatus rv;
+ SECStatus rv;
if (srcReq == NULL) {
return NULL;
}
- newReq = (poolp == NULL) ? PORT_ZNew(CRMFCertRequest) :
- PORT_ArenaZNew(poolp, CRMFCertRequest);
+ newReq = (poolp == NULL) ? PORT_ZNew(CRMFCertRequest) : PORT_ArenaZNew(poolp, CRMFCertRequest);
if (newReq == NULL) {
goto loser;
}
@@ -302,8 +297,8 @@ crmf_copy_cert_request(PLArenaPool *poolp, CRMFCertRequest *srcReq)
if (rv != SECSuccess) {
goto loser;
}
- rv = crmf_copy_cert_request_template(poolp, &newReq->certTemplate,
- &srcReq->certTemplate);
+ rv = crmf_copy_cert_request_template(poolp, &newReq->certTemplate,
+ &srcReq->certTemplate);
if (rv != SECSuccess) {
goto loser;
}
@@ -312,7 +307,7 @@ crmf_copy_cert_request(PLArenaPool *poolp, CRMFCertRequest *srcReq)
goto loser;
}
return newReq;
- loser:
+loser:
if (newReq != NULL && poolp == NULL) {
CRMF_DestroyCertRequest(newReq);
PORT_Free(newReq);
@@ -320,19 +315,19 @@ crmf_copy_cert_request(PLArenaPool *poolp, CRMFCertRequest *srcReq)
return NULL;
}
-SECStatus
+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;
- }
+ PORT_Free(inValidity->notAfter);
+ inValidity->notAfter = NULL;
+ }
+ if (inValidity->notBefore) {
+ PORT_Free(inValidity->notBefore);
+ inValidity->notBefore = NULL;
+ }
}
return SECSuccess;
}
@@ -346,7 +341,7 @@ crmf_make_bitstring_copy(PLArenaPool *arena, SECItem *dest, SECItem *src)
origLenBits = src->len;
bytesToCopy = CRMF_BITS_TO_BYTES(origLenBits);
- src->len = bytesToCopy;
+ src->len = bytesToCopy;
rv = SECITEM_CopyItem(arena, dest, src);
src->len = origLenBits;
if (rv != SECSuccess) {
@@ -361,11 +356,11 @@ CRMF_CertRequestGetNumberOfExtensions(CRMFCertRequest *inCertReq)
{
CRMFCertTemplate *certTemplate;
int count = 0;
-
+
certTemplate = &inCertReq->certTemplate;
if (certTemplate->extensions) {
while (certTemplate->extensions[count] != NULL)
- count++;
+ count++;
}
return count;
}
@@ -390,17 +385,16 @@ CRMF_CertExtensionGetIsCritical(CRMFCertExtension *inExt)
return inExt->critical.data != NULL;
}
-SECItem*
+SECItem *
CRMF_CertExtensionGetValue(CRMFCertExtension *inExtension)
{
PORT_Assert(inExtension != NULL);
if (inExtension == NULL) {
return NULL;
}
-
+
return SECITEM_DupItem(&inExtension->value);
}
-
SECStatus
CRMF_DestroyPOPOSigningKey(CRMFPOPOSigningKey *inKey)
@@ -408,15 +402,15 @@ 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);
+ 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;
}
@@ -427,7 +421,7 @@ CRMF_DestroyPOPOPrivKey(CRMFPOPOPrivKey *inPrivKey)
PORT_Assert(inPrivKey != NULL);
if (inPrivKey != NULL) {
SECITEM_FreeItem(&inPrivKey->message.thisMessage, PR_FALSE);
- PORT_Free(inPrivKey);
+ PORT_Free(inPrivKey);
}
return SECSuccess;
}
@@ -435,7 +429,7 @@ CRMF_DestroyPOPOPrivKey(CRMFPOPOPrivKey *inPrivKey)
int
CRMF_CertRequestGetNumControls(CRMFCertRequest *inCertReq)
{
- int count = 0;
+ int count = 0;
PORT_Assert(inCertReq != NULL);
if (inCertReq == NULL) {
@@ -443,8 +437,7 @@ CRMF_CertRequestGetNumControls(CRMFCertRequest *inCertReq)
}
if (inCertReq->controls) {
while (inCertReq->controls[count] != NULL)
- count++;
+ count++;
}
return count;
}
-
diff --git a/nss/lib/crmf/crmfi.h b/nss/lib/crmf/crmfi.h
index fd27a9b..badfd2b 100644
--- a/nss/lib/crmf/crmfi.h
+++ b/nss/lib/crmf/crmfi.h
@@ -3,11 +3,10 @@
* License, v. 2.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
+/* 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.
*/
@@ -16,38 +15,38 @@
#include "secerr.h"
#include "blapit.h"
-#define CRMF_DEFAULT_ARENA_SIZE 1024
+#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 MAX_WRAPPED_KEY_LEN RSA_MAX_MODULUS_BITS
-#define CRMF_BITS_TO_BYTES(bits) (((bits)+7)/8)
+#define CRMF_BITS_TO_BYTES(bits) (((bits) + 7) / 8)
#define CRMF_BYTES_TO_BITS(bytes) ((bytes)*8)
struct crmfEncoderArg {
@@ -61,30 +60,30 @@ struct crmfEncoderOutput {
};
/*
- * This function is used by the API for encoding functions that are
+ * 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);
+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);
+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
+ * 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);
+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.
@@ -109,76 +108,76 @@ extern const unsigned char hexFalse;
* Prototypes for helper routines used internally by multiple files.
*/
extern SECStatus crmf_encode_integer(PLArenaPool *poolp, SECItem *dest,
- long value);
+ long value);
extern SECStatus crmf_make_bitstring_copy(PLArenaPool *arena, SECItem *dest,
- SECItem *src);
-
-extern SECStatus crmf_copy_pkiarchiveoptions(PLArenaPool *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(PLArenaPool *poolp,
- CRMFEncryptedKey *srcEncrKey,
- CRMFEncryptedKey *destEncrKey);
+ SECItem *src);
+
+extern SECStatus crmf_copy_pkiarchiveoptions(PLArenaPool *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(PLArenaPool *poolp,
+ CRMFEncryptedKey *srcEncrKey,
+ CRMFEncryptedKey *destEncrKey);
extern SECStatus
-crmf_copy_encryptedvalue(PLArenaPool *poolp,
- CRMFEncryptedValue *srcValue,
- CRMFEncryptedValue *destValue);
+crmf_copy_encryptedvalue(PLArenaPool *poolp,
+ CRMFEncryptedValue *srcValue,
+ CRMFEncryptedValue *destValue);
extern SECStatus
-crmf_copy_encryptedvalue_secalg(PLArenaPool *poolp,
- SECAlgorithmID *srcAlgId,
- SECAlgorithmID **destAlgId);
+crmf_copy_encryptedvalue_secalg(PLArenaPool *poolp,
+ SECAlgorithmID *srcAlgId,
+ SECAlgorithmID **destAlgId);
extern SECStatus crmf_template_copy_secalg(PLArenaPool *poolp,
- SECAlgorithmID **dest,
- SECAlgorithmID *src);
+ SECAlgorithmID **dest,
+ SECAlgorithmID *src);
extern SECStatus crmf_copy_cert_name(PLArenaPool *poolp, CERTName **dest,
- CERTName *src);
+ CERTName *src);
-extern SECStatus crmf_template_add_public_key(PLArenaPool *poolp,
- CERTSubjectPublicKeyInfo **dest,
- CERTSubjectPublicKeyInfo *pubKey);
+extern SECStatus crmf_template_add_public_key(PLArenaPool *poolp,
+ CERTSubjectPublicKeyInfo **dest,
+ CERTSubjectPublicKeyInfo *pubKey);
-extern CRMFCertExtension* crmf_create_cert_extension(PLArenaPool *poolp,
- SECOidTag tag,
- PRBool isCritical,
- SECItem *data);
-extern CRMFCertRequest*
+extern CRMFCertExtension *crmf_create_cert_extension(PLArenaPool *poolp,
+ SECOidTag tag,
+ PRBool isCritical,
+ SECItem *data);
+extern CRMFCertRequest *
crmf_copy_cert_request(PLArenaPool *poolp, CRMFCertRequest *srcReq);
-extern SECStatus crmf_destroy_encrypted_value(CRMFEncryptedValue *inEncrValue,
- PRBool freeit);
+extern SECStatus crmf_destroy_encrypted_value(CRMFEncryptedValue *inEncrValue,
+ PRBool freeit);
extern CRMFEncryptedValue *
-crmf_create_encrypted_value_wrapped_privkey(SECKEYPrivateKey *inPrivKey,
- SECKEYPublicKey *inPubKey,
- CRMFEncryptedValue *destValue);
+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 CK_MECHANISM_TYPE
+crmf_get_mechanism_from_public_key(SECKEYPublicKey *inPubKey);
extern SECStatus
-crmf_encrypted_value_unwrap_priv_key(PLArenaPool *poolp,
- CRMFEncryptedValue *encValue,
- SECKEYPrivateKey *privKey,
- SECKEYPublicKey *newPubKey,
- SECItem *nickname,
- PK11SlotInfo *slot,
- unsigned char keyUsage,
- SECKEYPrivateKey **unWrappedKey,
- void *wincx);
-
-extern SECItem*
+crmf_encrypted_value_unwrap_priv_key(PLArenaPool *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*
+extern CRMFCertExtension *
crmf_copy_cert_extension(PLArenaPool *poolp, CRMFCertExtension *inExtension);
extern SECStatus
diff --git a/nss/lib/crmf/crmfit.h b/nss/lib/crmf/crmfit.h
index a8defcd..c5c4b96 100644
--- a/nss/lib/crmf/crmfit.h
+++ b/nss/lib/crmf/crmfit.h
@@ -3,13 +3,12 @@
* License, v. 2.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;
- PLArenaPool *poolp;
+ PLArenaPool *poolp;
};
struct CRMFCertExtensionStr {
@@ -18,49 +17,48 @@ struct CRMFCertExtensionStr {
SECItem value;
};
-
struct CRMFOptionalValidityStr {
- SECItem notBefore;
+ SECItem notBefore;
SECItem notAfter;
};
struct CRMFCertTemplateStr {
- SECItem version;
- SECItem serialNumber;
- SECAlgorithmID *signingAlg;
- CERTName *issuer;
- CRMFOptionalValidity *validity;
- CERTName *subject;
+ SECItem version;
+ SECItem serialNumber;
+ SECAlgorithmID *signingAlg;
+ CERTName *issuer;
+ CRMFOptionalValidity *validity;
+ CERTName *subject;
CERTSubjectPublicKeyInfo *publicKey;
- SECItem issuerUID;
- SECItem subjectUID;
- CRMFCertExtension **extensions;
- int numExtensions;
+ SECItem issuerUID;
+ SECItem subjectUID;
+ CRMFCertExtension **extensions;
+ int numExtensions;
};
struct CRMFCertIDStr {
- SECItem issuer; /* General Name */
+ SECItem issuer; /* General Name */
SECItem serialNumber; /*INTEGER*/
};
struct CRMFEncryptedValueStr {
SECAlgorithmID *intendedAlg;
SECAlgorithmID *symmAlg;
- SECItem encSymmKey; /*BIT STRING */
+ SECItem encSymmKey; /*BIT STRING */
SECAlgorithmID *keyAlg;
- SECItem valueHint; /*OCTET STRING */
- SECItem encValue; /*BIT STRING */
+ 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.
+ * from a der blob.
*/
struct CRMFEncryptedKeyStr {
union {
- SEC_PKCS7ContentInfo *envelopedData;
- CRMFEncryptedValue encryptedValue;
+ SEC_PKCS7ContentInfo *envelopedData;
+ CRMFEncryptedValue encryptedValue;
} value;
CRMFEncryptedKeyChoice encKeyChoice;
SECItem derValue;
@@ -69,9 +67,9 @@ struct CRMFEncryptedKeyStr {
/* ASN1 must only have one of the following 3 options. */
struct CRMFPKIArchiveOptionsStr {
union {
- CRMFEncryptedKey encryptedKey;
- SECItem keyGenParameters;
- SECItem archiveRemGenPrivKey; /* BOOLEAN */
+ CRMFEncryptedKey encryptedKey;
+ SECItem keyGenParameters;
+ SECItem archiveRemGenPrivKey; /* BOOLEAN */
} option;
CRMFPKIArchiveOptionsType archOption;
};
@@ -79,39 +77,39 @@ struct CRMFPKIArchiveOptionsStr {
struct CRMFPKIPublicationInfoStr {
SECItem action; /* Possible values */
/* dontPublish (0), pleasePublish (1) */
- CRMFSinglePubInfo **pubInfos;
+ CRMFSinglePubInfo **pubInfos;
};
struct CRMFControlStr {
- SECOidTag tag;
- SECItem derTag;
- SECItem derValue;
- /* These will be C structures used to represent the various
+ 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;
+ CRMFCertID oldCertId;
+ CRMFPKIArchiveOptions archiveOptions;
+ CRMFPKIPublicationInfo pubInfo;
+ CRMFProtocolEncrKey protEncrKey;
} value;
};
struct CRMFCertRequestStr {
- SECItem certReqId;
- CRMFCertTemplate certTemplate;
- CRMFControl **controls;
+ SECItem certReqId;
+ CRMFCertTemplate certTemplate;
+ CRMFControl **controls;
/* The following members are used by the internal implementation, but
* are not part of the encoding.
*/
PLArenaPool *poolp;
- PRUint32 requestID; /* This is the value that will be encoded into
- * the certReqId field.
- */
-};
+ PRUint32 requestID; /* This is the value that will be encoded into
+ * the certReqId field.
+ */
+};
struct CRMFAttributeStr {
SECItem derTag;
@@ -119,41 +117,41 @@ struct CRMFAttributeStr {
};
struct CRMFCertReqMsgStr {
- CRMFCertRequest *certReq;
- CRMFProofOfPossession *pop;
- CRMFAttribute **regInfo;
- SECItem derPOP;
+ CRMFCertRequest *certReq;
+ CRMFProofOfPossession *pop;
+ CRMFAttribute **regInfo;
+ SECItem derPOP;
/* This arena will be used for allocating memory when decoding.
*/
PLArenaPool *poolp;
- PRBool isDecoded;
+ PRBool isDecoded;
};
struct CRMFPOPOSigningKeyInputStr {
/* ASN1 must have only one of the next 2 options */
union {
- SECItem sender; /*General Name*/
- CRMFPKMACValue *publicKeyMAC;
- }authInfo;
+ 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. */
+ 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*/
+ SECItem thisMessage; /* BIT STRING */
+ SECItem subsequentMessage; /*INTEGER*/
+ SECItem dhMAC; /*BIT STRING*/
} message;
CRMFPOPOPrivKeyChoice messageChoice;
};
@@ -161,26 +159,26 @@ struct CRMFPOPOPrivKeyStr {
/* ASN1 must only have one of these options. */
struct CRMFProofOfPossessionStr {
union {
- SECItem raVerified;
- CRMFPOPOSigningKey signature;
- CRMFPOPOPrivKey keyEncipherment;
- CRMFPOPOPrivKey keyAgreement;
+ SECItem raVerified;
+ CRMFPOPOSigningKey signature;
+ CRMFPOPOPrivKey keyEncipherment;
+ CRMFPOPOPrivKey keyAgreement;
} popChoice;
- CRMFPOPChoice popUsed; /*Not part of encoding*/
+ CRMFPOPChoice popUsed; /*Not part of encoding*/
};
struct CRMFPKMACValueStr {
SECAlgorithmID algID;
- SECItem value; /*BIT STRING*/
+ SECItem value; /*BIT STRING*/
};
struct CRMFSinglePubInfoStr {
- SECItem pubMethod; /* Possible Values:
- * dontCare (0)
- * x500 (1)
- * web (2)
- * ldap (3)
- */
+ SECItem pubMethod; /* Possible Values:
+ * dontCare (0)
+ * x500 (1)
+ * web (2)
+ * ldap (3)
+ */
CERTGeneralName *pubLocation; /* General Name */
};
diff --git a/nss/lib/crmf/crmfpop.c b/nss/lib/crmf/crmfpop.c
index 2d4e326..725f8c7 100644
--- a/nss/lib/crmf/crmfpop.c
+++ b/nss/lib/crmf/crmfpop.c
@@ -3,7 +3,6 @@
* License, v. 2.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"
@@ -13,8 +12,8 @@
#define CRMF_DEFAULT_ALLOC_SIZE 1024U
SECStatus
-crmf_init_encoder_callback_arg (struct crmfEncoderArg *encoderArg,
- SECItem *derDest)
+crmf_init_encoder_callback_arg(struct crmfEncoderArg *encoderArg,
+ SECItem *derDest)
{
derDest->data = PORT_ZNewArray(unsigned char, CRMF_DEFAULT_ALLOC_SIZE);
if (derDest->data == NULL) {
@@ -24,18 +23,17 @@ crmf_init_encoder_callback_arg (struct crmfEncoderArg *encoderArg,
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
+SECStatus
CRMF_CertReqMsgSetRAVerifiedPOP(CRMFCertReqMsg *inCertReqMsg)
{
CRMFProofOfPossession *pop;
- PLArenaPool *poolp;
- void *mark;
+ PLArenaPool *poolp;
+ void *mark;
PORT_Assert(inCertReqMsg != NULL && inCertReqMsg->pop == NULL);
poolp = inCertReqMsg->poolp;
@@ -49,13 +47,13 @@ CRMF_CertReqMsgSetRAVerifiedPOP(CRMFCertReqMsg *inCertReqMsg)
}
pop->popUsed = crmfRAVerified;
pop->popChoice.raVerified.data = NULL;
- pop->popChoice.raVerified.len = 0;
+ pop->popChoice.raVerified.len = 0;
inCertReqMsg->pop = pop;
(void)SEC_ASN1EncodeItem(poolp, &(inCertReqMsg->derPOP),
&(pop->popChoice.raVerified),
CRMFRAVerifiedTemplate);
return SECSuccess;
- loser:
+loser:
PORT_ArenaRelease(poolp, mark);
return SECFailure;
}
@@ -71,14 +69,14 @@ crmf_get_key_sign_tag(SECKEYPublicKey *inPubKey)
return SEC_GetSignatureAlgorithmOidTag(inPubKey->keyType, SEC_OID_UNKNOWN);
}
-static SECAlgorithmID*
-crmf_create_poposignkey_algid(PLArenaPool *poolp,
- SECKEYPublicKey *inPubKey)
+static SECAlgorithmID *
+crmf_create_poposignkey_algid(PLArenaPool *poolp,
+ SECKEYPublicKey *inPubKey)
{
SECAlgorithmID *algID;
- SECOidTag tag;
- SECStatus rv;
- void *mark;
+ SECOidTag tag;
+ SECStatus rv;
+ void *mark;
mark = PORT_ArenaMark(poolp);
algID = PORT_ArenaZNew(poolp, SECAlgorithmID);
@@ -95,83 +93,85 @@ crmf_create_poposignkey_algid(PLArenaPool *poolp,
}
PORT_ArenaUnmark(poolp, mark);
return algID;
- loser:
+loser:
PORT_ArenaRelease(poolp, mark);
return NULL;
}
-static CRMFPOPOSigningKeyInput*
+static CRMFPOPOSigningKeyInput *
crmf_create_poposigningkeyinput(PLArenaPool *poolp, CERTCertificate *inCert,
- CRMFMACPasswordCallback fn, void *arg)
+ CRMFMACPasswordCallback fn, void *arg)
{
- /* PSM isn't going to do this, so we'll fail here for now.*/
- return NULL;
+ /* 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)
+crmf_generic_encoder_callback(void *arg, const char *buf, unsigned long len,
+ int depth, SEC_ASN1EncodingPart data_kind)
{
- struct crmfEncoderArg *encoderArg = (struct crmfEncoderArg*)arg;
+ 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;
+
+ 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;
+ 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;
+ if (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);
+ 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);
+ return SEC_ASN1Encode(inCertReq, CRMFCertRequestTemplate,
+ crmf_generic_encoder_callback, &encoderArg);
}
static SECStatus
-crmf_sign_certreq(PLArenaPool *poolp,
- CRMFPOPOSigningKey *crmfSignKey,
- CRMFCertRequest *certReq,
- SECKEYPrivateKey *inKey,
- SECAlgorithmID *inAlgId)
+crmf_sign_certreq(PLArenaPool *poolp,
+ CRMFPOPOSigningKey *crmfSignKey,
+ CRMFCertRequest *certReq,
+ SECKEYPrivateKey *inKey,
+ SECAlgorithmID *inAlgId)
{
- SECItem derCertReq = { siBuffer, NULL, 0 };
- SECItem certReqSig = { siBuffer, NULL, 0 };
- SECStatus rv = SECSuccess;
+ SECItem derCertReq = { siBuffer, NULL, 0 };
+ SECItem certReqSig = { siBuffer, NULL, 0 };
+ SECStatus rv = SECSuccess;
rv = crmf_encode_certreq(certReq, &derCertReq);
if (rv != SECSuccess) {
- goto loser;
+ goto loser;
}
rv = SEC_SignData(&certReqSig, derCertReq.data, derCertReq.len,
- inKey,SECOID_GetAlgorithmTag(inAlgId));
+ 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:
+ crmfSignKey->signature.len <<= 3;
+
+loser:
if (derCertReq.data != NULL) {
PORT_Free(derCertReq.data);
}
@@ -182,87 +182,87 @@ crmf_sign_certreq(PLArenaPool *poolp,
}
static SECStatus
-crmf_create_poposignkey(PLArenaPool *poolp,
- CRMFCertReqMsg *inCertReqMsg,
- CRMFPOPOSigningKeyInput *signKeyInput,
- SECKEYPrivateKey *inPrivKey,
- SECAlgorithmID *inAlgID,
- CRMFPOPOSigningKey *signKey)
+crmf_create_poposignkey(PLArenaPool *poolp,
+ CRMFCertReqMsg *inCertReqMsg,
+ CRMFPOPOSigningKeyInput *signKeyInput,
+ SECKEYPrivateKey *inPrivKey,
+ SECAlgorithmID *inAlgID,
+ CRMFPOPOSigningKey *signKey)
{
- CRMFCertRequest *certReq;
- void *mark;
- PRBool useSignKeyInput;
- SECStatus rv;
-
+ 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));
+ useSignKeyInput = !(CRMF_DoesRequestHaveField(certReq, crmfSubject) &&
+ CRMF_DoesRequestHaveField(certReq, crmfPublicKey));
if (useSignKeyInput) {
- goto loser;
+ goto loser;
} else {
- rv = crmf_sign_certreq(poolp, signKey, certReq,inPrivKey, inAlgID);
- if (rv != SECSuccess) {
- goto loser;
- }
+ rv = crmf_sign_certreq(poolp, signKey, certReq, inPrivKey, inAlgID);
+ if (rv != SECSuccess) {
+ goto loser;
+ }
}
- PORT_ArenaUnmark(poolp,mark);
+ PORT_ArenaUnmark(poolp, mark);
return SECSuccess;
- loser:
- PORT_ArenaRelease(poolp,mark);
+loser:
+ PORT_ArenaRelease(poolp, mark);
return SECFailure;
}
SECStatus
-CRMF_CertReqMsgSetSignaturePOP(CRMFCertReqMsg *inCertReqMsg,
- SECKEYPrivateKey *inPrivKey,
- SECKEYPublicKey *inPubKey,
- CERTCertificate *inCertForInput,
- CRMFMACPasswordCallback fn,
- void *arg)
+CRMF_CertReqMsgSetSignaturePOP(CRMFCertReqMsg *inCertReqMsg,
+ SECKEYPrivateKey *inPrivKey,
+ SECKEYPublicKey *inPubKey,
+ CERTCertificate *inCertForInput,
+ CRMFMACPasswordCallback fn,
+ void *arg)
{
- SECAlgorithmID *algID;
- PLArenaPool *poolp;
- SECItem derTemp = {siBuffer, NULL, 0};
- void *mark;
- SECStatus rv;
+ SECAlgorithmID *algID;
+ PLArenaPool *poolp;
+ SECItem derTemp = { siBuffer, NULL, 0 };
+ void *mark;
+ SECStatus rv;
CRMFPOPOSigningKeyInput *signKeyInput = NULL;
- CRMFCertRequest *certReq;
- CRMFProofOfPossession *pop;
- struct crmfEncoderArg encoderArg;
+ CRMFCertRequest *certReq;
+ CRMFProofOfPossession *pop;
+ struct crmfEncoderArg encoderArg;
PORT_Assert(inCertReqMsg != NULL && inCertReqMsg->certReq != NULL &&
- inCertReqMsg->pop == NULL);
+ inCertReqMsg->pop == NULL);
certReq = inCertReqMsg->certReq;
- if (CRMF_CertReqMsgGetPOPType(inCertReqMsg) != crmfNoPOPChoice ||
- !CRMF_DoesRequestHaveField(certReq, crmfPublicKey)) {
+ 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)) {
+ if (!CRMF_DoesRequestHaveField(certReq, crmfSubject)) {
signKeyInput = crmf_create_poposigningkeyinput(poolp, inCertForInput,
- fn, arg);
- if (signKeyInput == NULL) {
- goto loser;
- }
+ 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));
+
+ rv = crmf_create_poposignkey(poolp, inCertReqMsg,
+ signKeyInput, inPrivKey, algID,
+ &(pop->popChoice.signature));
if (rv != SECSuccess) {
goto loser;
}
@@ -270,14 +270,14 @@ CRMF_CertReqMsgSetSignaturePOP(CRMFCertReqMsg *inCertReqMsg,
pop->popUsed = crmfSignature;
pop->popChoice.signature.algorithmIdentifier = algID;
inCertReqMsg->pop = pop;
-
- rv = crmf_init_encoder_callback_arg (&encoderArg, &derTemp);
+
+ 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);
+ rv = SEC_ASN1Encode(&pop->popChoice.signature,
+ CRMFPOPOSigningKeyTemplate,
+ crmf_generic_encoder_callback, &encoderArg);
if (rv != SECSuccess) {
goto loser;
}
@@ -285,49 +285,49 @@ CRMF_CertReqMsgSetSignaturePOP(CRMFCertReqMsg *inCertReqMsg,
if (rv != SECSuccess) {
goto loser;
}
- PORT_Free (derTemp.data);
- PORT_ArenaUnmark(poolp,mark);
+ PORT_Free(derTemp.data);
+ PORT_ArenaUnmark(poolp, mark);
return SECSuccess;
- loser:
- PORT_ArenaRelease(poolp,mark);
+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)
+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;
+ 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(PLArenaPool *poolp,
- CRMFCertReqMsg *inCertReqMsg,
- CRMFPOPOPrivKey *popoPrivKey,
- const SEC_ASN1Template *privKeyTemplate)
+crmf_encode_popoprivkey(PLArenaPool *poolp,
+ CRMFCertReqMsg *inCertReqMsg,
+ CRMFPOPOPrivKey *popoPrivKey,
+ const SEC_ASN1Template *privKeyTemplate)
{
- struct crmfEncoderArg encoderArg;
- SECItem derTemp = { siBuffer, NULL, 0 };
- SECStatus rv;
- void *mark;
+ struct crmfEncoderArg encoderArg;
+ SECItem derTemp = { siBuffer, NULL, 0 };
+ SECStatus rv;
+ void *mark;
const SEC_ASN1Template *subDerTemplate;
mark = PORT_ArenaMark(poolp);
@@ -336,21 +336,21 @@ crmf_encode_popoprivkey(PLArenaPool *poolp,
goto loser;
}
subDerTemplate = crmf_get_popoprivkey_subtemplate(popoPrivKey);
- /* We've got a union, so a pointer to one item is a pointer to
+ /* 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);
+ 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;
+ 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
@@ -367,7 +367,7 @@ crmf_encode_popoprivkey(PLArenaPool *poolp,
PORT_Free(derTemp.data);
PORT_ArenaUnmark(poolp, mark);
return SECSuccess;
- loser:
+loser:
PORT_ArenaRelease(poolp, mark);
if (derTemp.data) {
PORT_Free(derTemp.data);
@@ -375,29 +375,29 @@ crmf_encode_popoprivkey(PLArenaPool *poolp,
return SECFailure;
}
-static const SEC_ASN1Template*
-crmf_get_template_for_privkey(CRMFPOPChoice inChoice)
+static const SEC_ASN1Template *
+crmf_get_template_for_privkey(CRMFPOPChoice inChoice)
{
switch (inChoice) {
- case crmfKeyAgreement:
- return CRMFPOPOKeyAgreementTemplate;
- case crmfKeyEncipherment:
- return CRMFPOPOKeyEnciphermentTemplate;
- default:
- break;
+ case crmfKeyAgreement:
+ return CRMFPOPOKeyAgreementTemplate;
+ case crmfKeyEncipherment:
+ return CRMFPOPOKeyEnciphermentTemplate;
+ default:
+ break;
}
return NULL;
}
static SECStatus
crmf_add_privkey_thismessage(CRMFCertReqMsg *inCertReqMsg, SECItem *encPrivKey,
- CRMFPOPChoice inChoice)
+ CRMFPOPChoice inChoice)
{
- PLArenaPool *poolp;
- void *mark;
- CRMFPOPOPrivKey *popoPrivKey;
+ PLArenaPool *poolp;
+ void *mark;
+ CRMFPOPOPrivKey *popoPrivKey;
CRMFProofOfPossession *pop;
- SECStatus rv;
+ SECStatus rv;
PORT_Assert(inCertReqMsg != NULL && encPrivKey != NULL);
poolp = inCertReqMsg->poolp;
@@ -409,14 +409,14 @@ crmf_add_privkey_thismessage(CRMFCertReqMsg *inCertReqMsg, SECItem *encPrivKey,
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
+ * 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);
+ encPrivKey);
if (rv != SECSuccess) {
goto loser;
}
@@ -424,27 +424,27 @@ crmf_add_privkey_thismessage(CRMFCertReqMsg *inCertReqMsg, SECItem *encPrivKey,
popoPrivKey->messageChoice = crmfThisMessage;
inCertReqMsg->pop = pop;
rv = crmf_encode_popoprivkey(poolp, inCertReqMsg, popoPrivKey,
- crmf_get_template_for_privkey(inChoice));
+ crmf_get_template_for_privkey(inChoice));
if (rv != SECSuccess) {
goto loser;
}
PORT_ArenaUnmark(poolp, mark);
return SECSuccess;
-
- loser:
+
+loser:
PORT_ArenaRelease(poolp, mark);
return SECFailure;
}
static SECStatus
crmf_add_privkey_dhmac(CRMFCertReqMsg *inCertReqMsg, SECItem *dhmac,
- CRMFPOPChoice inChoice)
+ CRMFPOPChoice inChoice)
{
- PLArenaPool *poolp;
- void *mark;
- CRMFPOPOPrivKey *popoPrivKey;
+ PLArenaPool *poolp;
+ void *mark;
+ CRMFPOPOPrivKey *popoPrivKey;
CRMFProofOfPossession *pop;
- SECStatus rv;
+ SECStatus rv;
PORT_Assert(inCertReqMsg != NULL && dhmac != NULL);
poolp = inCertReqMsg->poolp;
@@ -471,22 +471,22 @@ crmf_add_privkey_dhmac(CRMFCertReqMsg *inCertReqMsg, SECItem *dhmac,
}
PORT_ArenaUnmark(poolp, mark);
return SECSuccess;
-
- loser:
+
+loser:
PORT_ArenaRelease(poolp, mark);
return SECFailure;
}
static SECStatus
-crmf_add_privkey_subseqmessage(CRMFCertReqMsg *inCertReqMsg,
- CRMFSubseqMessOptions subsequentMessage,
- CRMFPOPChoice inChoice)
+crmf_add_privkey_subseqmessage(CRMFCertReqMsg *inCertReqMsg,
+ CRMFSubseqMessOptions subsequentMessage,
+ CRMFPOPChoice inChoice)
{
- void *mark;
- PLArenaPool *poolp;
+ void *mark;
+ PLArenaPool *poolp;
CRMFProofOfPossession *pop;
- CRMFPOPOPrivKey *popoPrivKey;
- SECStatus rv;
+ CRMFPOPOPrivKey *popoPrivKey;
+ SECStatus rv;
const SEC_ASN1Template *privKeyTemplate;
if (subsequentMessage == crmfNoSubseqMess) {
@@ -500,25 +500,25 @@ crmf_add_privkey_subseqmessage(CRMFCertReqMsg *inCertReqMsg,
}
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;
+ 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;
@@ -527,23 +527,23 @@ crmf_add_privkey_subseqmessage(CRMFCertReqMsg *inCertReqMsg,
privKeyTemplate = crmf_get_template_for_privkey(inChoice);
inCertReqMsg->pop = pop;
rv = crmf_encode_popoprivkey(poolp, inCertReqMsg, popoPrivKey,
- privKeyTemplate);
+ privKeyTemplate);
if (rv != SECSuccess) {
goto loser;
}
PORT_ArenaUnmark(poolp, mark);
return SECSuccess;
- loser:
+loser:
PORT_ArenaRelease(poolp, mark);
return SECFailure;
}
-SECStatus
-CRMF_CertReqMsgSetKeyEnciphermentPOP(CRMFCertReqMsg *inCertReqMsg,
- CRMFPOPOPrivKeyChoice inKeyChoice,
- CRMFSubseqMessOptions subseqMess,
- SECItem *encPrivKey)
+SECStatus
+CRMF_CertReqMsgSetKeyEnciphermentPOP(CRMFCertReqMsg *inCertReqMsg,
+ CRMFPOPOPrivKeyChoice inKeyChoice,
+ CRMFSubseqMessOptions subseqMess,
+ SECItem *encPrivKey)
{
SECStatus rv;
@@ -551,49 +551,48 @@ CRMF_CertReqMsgSetKeyEnciphermentPOP(CRMFCertReqMsg *inCertReqMsg,
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;
+ 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
+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;
+ 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/nss/lib/crmf/crmfreq.c b/nss/lib/crmf/crmfreq.c
index 7da81cd..e89f182 100644
--- a/nss/lib/crmf/crmfreq.c
+++ b/nss/lib/crmf/crmfreq.c
@@ -14,17 +14,16 @@
*/
#define IS_NOT_NULL(ptr) ((ptr) == NULL) ? PR_FALSE : PR_TRUE
-const unsigned char hexTrue = 0xff;
+const unsigned char hexTrue = 0xff;
const unsigned char hexFalse = 0x00;
-
SECStatus
crmf_encode_integer(PLArenaPool *poolp, SECItem *dest, long value)
{
SECItem *dummy;
dummy = SEC_ASN1EncodeInteger(poolp, dest, value);
- PORT_Assert (dummy == dest);
+ PORT_Assert(dummy == dest);
if (dummy == NULL) {
return SECFailure;
}
@@ -33,12 +32,12 @@ crmf_encode_integer(PLArenaPool *poolp, SECItem *dest, long value)
SECStatus
crmf_encode_unsigned_integer(PLArenaPool *poolp, SECItem *dest,
- unsigned long value)
+ unsigned long value)
{
SECItem *dummy;
dummy = SEC_ASN1EncodeUnsignedInteger(poolp, dest, value);
- PORT_Assert (dummy == dest);
+ PORT_Assert(dummy == dest);
if (dummy != dest) {
return SECFailure;
}
@@ -46,73 +45,73 @@ crmf_encode_unsigned_integer(PLArenaPool *poolp, SECItem *dest,
}
static SECStatus
-crmf_copy_secitem (PLArenaPool *poolp, SECItem *dest, SECItem *src)
+crmf_copy_secitem(PLArenaPool *poolp, SECItem *dest, SECItem *src)
{
- return SECITEM_CopyItem (poolp, dest, src);
+ return SECITEM_CopyItem(poolp, dest, src);
}
PRBool
-CRMF_DoesRequestHaveField (CRMFCertRequest *inCertReq,
- CRMFCertTemplateField inField)
+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;
+ 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)
+CRMF_CreateCertRequest(PRUint32 inRequestID)
{
- PLArenaPool *poolp;
+ PLArenaPool *poolp;
CRMFCertRequest *certReq;
- SECStatus rv;
-
+ SECStatus rv;
+
poolp = PORT_NewArena(CRMF_DEFAULT_ARENA_SIZE);
if (poolp == NULL) {
goto loser;
}
-
- certReq=PORT_ArenaZNew(poolp,CRMFCertRequest);
+
+ certReq = PORT_ArenaZNew(poolp, CRMFCertRequest);
if (certReq == NULL) {
goto loser;
}
certReq->poolp = poolp;
certReq->requestID = inRequestID;
-
- rv = crmf_encode_unsigned_integer(poolp, &(certReq->certReqId),
+
+ rv = crmf_encode_unsigned_integer(poolp, &(certReq->certReqId),
inRequestID);
if (rv != SECSuccess) {
goto loser;
}
return certReq;
- loser:
+loser:
if (poolp) {
PORT_FreeArena(poolp, PR_FALSE);
}
@@ -125,18 +124,18 @@ 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);
- }
+ 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;
}
@@ -154,12 +153,12 @@ crmf_template_add_serialnumber(PLArenaPool *poolp, SECItem *dest, long serial)
}
SECStatus
-crmf_template_copy_secalg (PLArenaPool *poolp, SECAlgorithmID **dest,
- SECAlgorithmID* src)
+crmf_template_copy_secalg(PLArenaPool *poolp, SECAlgorithmID **dest,
+ SECAlgorithmID *src)
{
- SECStatus rv;
- void *mark = NULL;
- SECAlgorithmID *mySecAlg;
+ SECStatus rv;
+ void *mark = NULL;
+ SECAlgorithmID *mySecAlg;
if (!poolp) {
PORT_SetError(SEC_ERROR_INVALID_ARGS);
@@ -180,7 +179,7 @@ crmf_template_copy_secalg (PLArenaPool *poolp, SECAlgorithmID **dest,
}
return SECSuccess;
- loser:
+loser:
*dest = NULL;
if (mark) {
PORT_ArenaRelease(poolp, mark);
@@ -190,11 +189,11 @@ crmf_template_copy_secalg (PLArenaPool *poolp, SECAlgorithmID **dest,
SECStatus
crmf_copy_cert_name(PLArenaPool *poolp, CERTName **dest,
- CERTName *src)
+ CERTName *src)
{
CERTName *newName;
SECStatus rv;
- void *mark;
+ void *mark;
mark = PORT_ArenaMark(poolp);
*dest = newName = PORT_ArenaZNew(poolp, CERTName);
@@ -204,91 +203,88 @@ crmf_copy_cert_name(PLArenaPool *poolp, CERTName **dest,
rv = CERT_CopyName(poolp, newName, src);
if (rv != SECSuccess) {
- goto loser;
+ goto loser;
}
PORT_ArenaUnmark(poolp, mark);
return SECSuccess;
- loser:
+loser:
PORT_ArenaRelease(poolp, mark);
*dest = NULL;
return SECFailure;
}
static SECStatus
-crmf_template_add_issuer (PLArenaPool *poolp, CERTName **dest,
- CERTName* issuerName)
+crmf_template_add_issuer(PLArenaPool *poolp, CERTName **dest,
+ CERTName *issuerName)
{
return crmf_copy_cert_name(poolp, dest, issuerName);
}
-
static SECStatus
-crmf_template_add_validity (PLArenaPool *poolp, CRMFOptionalValidity **dest,
- CRMFValidityCreationInfo *info)
+crmf_template_add_validity(PLArenaPool *poolp, CRMFOptionalValidity **dest,
+ CRMFValidityCreationInfo *info)
{
- SECStatus rv;
- void *mark;
+ 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)) {
+ if (!info || (!info->notBefore && !info->notAfter)) {
return SECFailure;
}
- mark = PORT_ArenaMark (poolp);
+ 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;
- }
+ 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;
- }
+ rv = DER_EncodeTimeChoice(poolp, &myValidity->notAfter,
+ *info->notAfter);
+ if (rv != SECSuccess) {
+ goto loser;
+ }
}
PORT_ArenaUnmark(poolp, mark);
return SECSuccess;
- loser:
+loser:
PORT_ArenaRelease(poolp, mark);
*dest = NULL;
return SECFailure;
}
static SECStatus
-crmf_template_add_subject (PLArenaPool *poolp, CERTName **dest,
- CERTName *subject)
+crmf_template_add_subject(PLArenaPool *poolp, CERTName **dest,
+ CERTName *subject)
{
return crmf_copy_cert_name(poolp, dest, subject);
}
SECStatus
crmf_template_add_public_key(PLArenaPool *poolp,
- CERTSubjectPublicKeyInfo **dest,
- CERTSubjectPublicKeyInfo *pubKey)
+ CERTSubjectPublicKeyInfo **dest,
+ CERTSubjectPublicKeyInfo *pubKey)
{
CERTSubjectPublicKeyInfo *spki;
SECStatus rv;
- *dest = spki = (poolp == NULL) ?
- PORT_ZNew(CERTSubjectPublicKeyInfo) :
- PORT_ArenaZNew (poolp, CERTSubjectPublicKeyInfo);
+ *dest = spki = (poolp == NULL) ? PORT_ZNew(CERTSubjectPublicKeyInfo) : PORT_ArenaZNew(poolp, CERTSubjectPublicKeyInfo);
if (spki == NULL) {
goto loser;
}
- rv = SECKEY_CopySubjectPublicKeyInfo (poolp, spki, pubKey);
+ rv = SECKEY_CopySubjectPublicKeyInfo(poolp, spki, pubKey);
if (rv != SECSuccess) {
goto loser;
}
return SECSuccess;
- loser:
+loser:
if (poolp == NULL && spki != NULL) {
SECKEY_DestroySubjectPublicKeyInfo(spki);
}
@@ -297,11 +293,11 @@ crmf_template_add_public_key(PLArenaPool *poolp,
}
static SECStatus
-crmf_copy_bitstring (PLArenaPool *poolp, SECItem *dest, const SECItem *src)
+crmf_copy_bitstring(PLArenaPool *poolp, SECItem *dest, const SECItem *src)
{
SECStatus rv;
- SECItem byteSrc;
-
+ SECItem byteSrc;
+
byteSrc = *src;
byteSrc.len = CRMF_BITS_TO_BYTES(byteSrc.len);
rv = crmf_copy_secitem(poolp, dest, &byteSrc);
@@ -311,23 +307,23 @@ crmf_copy_bitstring (PLArenaPool *poolp, SECItem *dest, const SECItem *src)
static SECStatus
crmf_template_add_issuer_uid(PLArenaPool *poolp, SECItem *dest,
- const SECItem *issuerUID)
+ const SECItem *issuerUID)
{
- return crmf_copy_bitstring (poolp, dest, issuerUID);
+ return crmf_copy_bitstring(poolp, dest, issuerUID);
}
static SECStatus
crmf_template_add_subject_uid(PLArenaPool *poolp, SECItem *dest,
- const SECItem *subjectUID)
+ const SECItem *subjectUID)
{
- return crmf_copy_bitstring (poolp, dest, subjectUID);
+ return crmf_copy_bitstring(poolp, dest, subjectUID);
}
static void
-crmf_zeroize_new_extensions (CRMFCertExtension **extensions,
- int numToZeroize)
+crmf_zeroize_new_extensions(CRMFCertExtension **extensions,
+ int numToZeroize)
{
- PORT_Memset((void*)extensions, 0, sizeof(CERTCertExtension*)*numToZeroize);
+ PORT_Memset((void *)extensions, 0, sizeof(CERTCertExtension *) * numToZeroize);
}
/*
@@ -342,72 +338,71 @@ crmf_zeroize_new_extensions (CRMFCertExtension **extensions,
*/
static SECStatus
crmf_template_add_extensions(PLArenaPool *poolp, CRMFCertTemplate *inTemplate,
- CRMFCertExtCreationInfo *extensions)
+ CRMFCertExtCreationInfo *extensions)
{
- void *mark;
- int newSize, oldSize, i;
- SECStatus rv;
+ void *mark;
+ int newSize, oldSize, i;
+ SECStatus rv;
CRMFCertExtension **extArray;
- CRMFCertExtension *newExt, *currExt;
+ CRMFCertExtension *newExt, *currExt;
mark = PORT_ArenaMark(poolp);
if (inTemplate->extensions == NULL) {
newSize = extensions->numExtensions;
- extArray = PORT_ZNewArray(CRMFCertExtension*,newSize+1);
+ extArray = PORT_ZNewArray(CRMFCertExtension *, newSize + 1);
} else {
newSize = inTemplate->numExtensions + extensions->numExtensions;
- extArray = PORT_Realloc(inTemplate->extensions,
- sizeof(CRMFCertExtension*)*(newSize+1));
+ extArray = PORT_Realloc(inTemplate->extensions,
+ sizeof(CRMFCertExtension *) * (newSize + 1));
}
if (extArray == NULL) {
goto loser;
}
- oldSize = inTemplate->numExtensions;
- inTemplate->extensions = extArray;
+ oldSize = inTemplate->numExtensions;
+ inTemplate->extensions = extArray;
inTemplate->numExtensions = newSize;
- for (i=oldSize; i < newSize; i++) {
+ 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;
+ 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);
+loser2:
+ crmf_zeroize_new_extensions(&(inTemplate->extensions[oldSize]),
+ extensions->numExtensions);
inTemplate->numExtensions = oldSize;
- loser:
+loser:
PORT_ArenaRelease(poolp, mark);
return SECFailure;
}
SECStatus
-CRMF_CertRequestSetTemplateField(CRMFCertRequest *inCertReq,
- CRMFCertTemplateField inTemplateField,
- void *data)
+CRMF_CertRequestSetTemplateField(CRMFCertRequest *inCertReq,
+ CRMFCertTemplateField inTemplateField,
+ void *data)
{
CRMFCertTemplate *certTemplate;
- PLArenaPool *poolp;
- SECStatus rv = SECFailure;
- void *mark;
-
+ PLArenaPool *poolp;
+ SECStatus rv = SECFailure;
+ void *mark;
if (inCertReq == NULL) {
return SECFailure;
@@ -418,47 +413,47 @@ CRMF_CertRequestSetTemplateField(CRMFCertRequest *inCertReq,
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;
+ 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);
@@ -469,22 +464,22 @@ CRMF_CertRequestSetTemplateField(CRMFCertRequest *inCertReq,
}
SECStatus
-CRMF_CertReqMsgSetCertRequest (CRMFCertReqMsg *inCertReqMsg,
- CRMFCertRequest *inCertReq)
+CRMF_CertReqMsgSetCertRequest(CRMFCertReqMsg *inCertReqMsg,
+ CRMFCertRequest *inCertReq)
{
- PORT_Assert (inCertReqMsg != NULL && inCertReq != NULL);
+ PORT_Assert(inCertReqMsg != NULL && inCertReq != NULL);
if (inCertReqMsg == NULL || inCertReq == NULL) {
return SECFailure;
}
inCertReqMsg->certReq = crmf_copy_cert_request(inCertReqMsg->poolp,
- inCertReq);
+ inCertReq);
return (inCertReqMsg->certReq == NULL) ? SECFailure : SECSuccess;
}
-CRMFCertReqMsg*
+CRMFCertReqMsg *
CRMF_CreateCertReqMsg(void)
{
- PLArenaPool *poolp;
+ PLArenaPool *poolp;
CRMFCertReqMsg *reqMsg;
poolp = PORT_NewArena(CRMF_DEFAULT_ARENA_SIZE);
@@ -497,49 +492,48 @@ CRMF_CreateCertReqMsg(void)
}
reqMsg->poolp = poolp;
return reqMsg;
-
- loser:
+
+loser:
if (poolp) {
PORT_FreeArena(poolp, PR_FALSE);
}
return NULL;
}
-SECStatus
+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_Free(inCertReqMsg->certReq->certTemplate.extensions);
+ }
+ if (inCertReqMsg->certReq->controls != NULL) {
+ PORT_Free(inCertReqMsg->certReq->controls);
+ }
}
PORT_FreeArena(inCertReqMsg->poolp, PR_TRUE);
return SECSuccess;
}
-CRMFCertExtension*
+CRMFCertExtension *
crmf_create_cert_extension(PLArenaPool *poolp,
- SECOidTag id,
- PRBool isCritical,
- SECItem *data)
+ SECOidTag id,
+ PRBool isCritical,
+ SECItem *data)
{
CRMFCertExtension *newExt;
- SECOidData *oidData;
- SECStatus rv;
+ SECOidData *oidData;
+ SECStatus rv;
- newExt = (poolp == NULL) ? PORT_ZNew(CRMFCertExtension) :
- PORT_ArenaZNew(poolp, CRMFCertExtension);
+ 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;
+ if (oidData == NULL ||
+ oidData->supportedExtension != SUPPORTED_CERT_EXTENSION) {
+ goto loser;
}
rv = SECITEM_CopyItem(poolp, &(newExt->id), &(oidData->oid));
@@ -553,17 +547,16 @@ crmf_create_cert_extension(PLArenaPool *poolp,
}
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;
+ 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:
+loser:
if (newExt != NULL && poolp == NULL) {
CRMF_DestroyCertExtension(newExt);
}
@@ -572,8 +565,8 @@ crmf_create_cert_extension(PLArenaPool *poolp,
CRMFCertExtension *
CRMF_CreateCertExtension(SECOidTag id,
- PRBool isCritical,
- SECItem *data)
+ PRBool isCritical,
+ SECItem *data)
{
return crmf_create_cert_extension(NULL, id, isCritical, data);
}
@@ -582,12 +575,12 @@ 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);
- }
+ 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;
}
@@ -599,9 +592,9 @@ CRMF_DestroyCertExtension(CRMFCertExtension *inExtension)
}
SECStatus
-CRMF_DestroyCertReqMessages(CRMFCertReqMessages *inCertReqMsgs)
+CRMF_DestroyCertReqMessages(CRMFCertReqMessages *inCertReqMsgs)
{
- PORT_Assert (inCertReqMsgs != NULL);
+ PORT_Assert(inCertReqMsgs != NULL);
if (inCertReqMsgs != NULL) {
PORT_FreeArena(inCertReqMsgs->poolp, PR_TRUE);
}
@@ -618,53 +611,53 @@ crmf_item_has_data(SECItem *item)
}
PRBool
-CRMF_CertRequestIsFieldPresent(CRMFCertRequest *inCertReq,
- CRMFCertTemplateField inTemplateField)
+CRMF_CertRequestIsFieldPresent(CRMFCertRequest *inCertReq,
+ CRMFCertTemplateField inTemplateField)
{
- PRBool retVal;
+ 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.
- */
+ /* 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;
+ 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/nss/lib/crmf/crmft.h b/nss/lib/crmf/crmft.h
index e12aa02..8d83cf1 100644
--- a/nss/lib/crmf/crmft.h
+++ b/nss/lib/crmf/crmft.h
@@ -3,8 +3,7 @@
* License, v. 2.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
+/* Header file with all of the structures and types that will be exported
* by the security library for implementation of CRMF.
*/
@@ -47,7 +46,7 @@ typedef enum {
} CRMFPublicationAction;
/*
- * An enumeration for the possible for pubMethod which is a part of
+ * An enumeration for the possible for pubMethod which is a part of
* the SinglePubInfo ASN1 type.
*/
typedef enum {
@@ -79,7 +78,7 @@ typedef enum {
} CRMFPOPChoice;
/*
- * An enumertion type for options for the authInfo field of the
+ * An enumertion type for options for the authInfo field of the
* CRMFPOPOSigningKeyInput structure.
*/
typedef enum {
@@ -132,41 +131,41 @@ typedef enum {
* The number of DER encoded bytes to write out.
*
*/
-typedef void (*CRMFEncoderOutputCallback) (void *arg,
- const char *buf,
- unsigned long len);
+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;
+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;
@@ -184,5 +183,4 @@ struct CRMFCertExtCreationInfoStr {
extern const SEC_ASN1Template CRMFCertReqMessagesTemplate[];
extern const SEC_ASN1Template CRMFCertRequestTemplate[];
-
#endif /*_CRMFT_H_*/
diff --git a/nss/lib/crmf/crmftmpl.c b/nss/lib/crmf/crmftmpl.c
index 320d524..265a15d 100644
--- a/nss/lib/crmf/crmftmpl.c
+++ b/nss/lib/crmf/crmftmpl.c
@@ -18,27 +18,27 @@ 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_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) },
+ 0, NULL, sizeof(CRMFCertExtension) },
{ SEC_ASN1_OBJECT_ID,
- offsetof(CRMFCertExtension,id) },
+ offsetof(CRMFCertExtension, id) },
{ SEC_ASN1_OPTIONAL | SEC_ASN1_BOOLEAN,
- offsetof(CRMFCertExtension,critical) },
+ offsetof(CRMFCertExtension, critical) },
{ SEC_ASN1_OCTET_STRING,
- offsetof(CRMFCertExtension,value) },
- { 0, }
+ offsetof(CRMFCertExtension, value) },
+ { 0 }
};
static const SEC_ASN1Template CRMFSequenceOfCertExtensionTemplate[] = {
@@ -46,78 +46,78 @@ static const SEC_ASN1Template CRMFSequenceOfCertExtensionTemplate[] = {
};
static const SEC_ASN1Template CRMFOptionalValidityTemplate[] = {
- { SEC_ASN1_SEQUENCE, 0, NULL, sizeof (CRMFOptionalValidity) },
+ { 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_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_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)},
+ { 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 }
+ { 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_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_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)*/
+ offsetof(CRMFCertRequest, controls),
+ CRMFControlTemplate }, /* SEQUENCE SIZE (1...MAX)*/
{ 0 }
};
@@ -128,35 +128,34 @@ const SEC_ASN1Template CRMFCertReqMsgTemplate[] = {
{ SEC_ASN1_ANY | SEC_ASN1_OPTIONAL,
offsetof(CRMFCertReqMsg, derPOP) },
{ SEC_ASN1_OPTIONAL | SEC_ASN1_SEQUENCE_OF,
- offsetof(CRMFCertReqMsg, regInfo),
- CRMFAttributeTemplate}, /* SEQUENCE SIZE (1...MAX)*/
+ offsetof(CRMFCertReqMsg, regInfo),
+ CRMFAttributeTemplate }, /* SEQUENCE SIZE (1...MAX)*/
{ 0 }
};
const SEC_ASN1Template CRMFCertReqMessagesTemplate[] = {
- { SEC_ASN1_SEQUENCE_OF, offsetof(CRMFCertReqMessages, messages),
- CRMFCertReqMsgTemplate, sizeof (CRMFCertReqMessages)}
+ { SEC_ASN1_SEQUENCE_OF, offsetof(CRMFCertReqMessages, messages),
+ CRMFCertReqMsgTemplate, sizeof(CRMFCertReqMessages) }
};
const SEC_ASN1Template CRMFRAVerifiedTemplate[] = {
- { SEC_ASN1_CONTEXT_SPECIFIC | 0 | SEC_ASN1_XTRN,
+ { 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_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,
+ { SEC_ASN1_POINTER | SEC_ASN1_XTRN,
offsetof(CRMFPOPOSigningKey, algorithmIdentifier),
SEC_ASN1_SUB(SECOID_AlgorithmIDTemplate) },
- { SEC_ASN1_BIT_STRING | SEC_ASN1_XTRN,
+ { SEC_ASN1_BIT_STRING | SEC_ASN1_XTRN,
offsetof(CRMFPOPOSigningKey, signature),
SEC_ASN1_SUB(SEC_BitStringTemplate) },
{ 0 }
@@ -165,7 +164,7 @@ static const SEC_ASN1Template crmfPOPOSigningKeyTemplate[] = {
const SEC_ASN1Template CRMFPOPOSigningKeyTemplate[] = {
{ SEC_ASN1_CONTEXT_SPECIFIC | 1,
0,
- crmfPOPOSigningKeyTemplate},
+ crmfPOPOSigningKeyTemplate },
{ 0 }
};
@@ -178,7 +177,7 @@ const SEC_ASN1Template CRMFThisMessageTemplate[] = {
const SEC_ASN1Template CRMFSubsequentMessageTemplate[] = {
{ SEC_ASN1_CONTEXT_SPECIFIC | SEC_ASN1_XTRN | 1,
- 0,
+ 0,
SEC_ASN1_SUB(SEC_IntegerTemplate) },
{ 0 }
};
@@ -191,51 +190,51 @@ const SEC_ASN1Template CRMFDHMACTemplate[] = {
};
const SEC_ASN1Template CRMFPOPOKeyEnciphermentTemplate[] = {
- { SEC_ASN1_EXPLICIT | SEC_ASN1_CONSTRUCTED |
- SEC_ASN1_CONTEXT_SPECIFIC | SEC_ASN1_XTRN | 2,
+ { 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,
+ { SEC_ASN1_EXPLICIT | SEC_ASN1_CONSTRUCTED |
+ SEC_ASN1_CONTEXT_SPECIFIC | SEC_ASN1_XTRN | 3,
0,
- SEC_ASN1_SUB(SEC_AnyTemplate)},
+ 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_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_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_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_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,
+ { 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,
+const SEC_ASN1Template CRMFEncryptedKeyWithEncryptedValueTemplate[] = {
+ { SEC_ASN1_EXPLICIT | SEC_ASN1_CONSTRUCTED |
+ SEC_ASN1_CONTEXT_SPECIFIC | 0,
0,
- CRMFEncryptedValueTemplate},
+ CRMFEncryptedValueTemplate },
{ 0 }
};
diff --git a/nss/lib/crmf/encutil.c b/nss/lib/crmf/encutil.c
index ffa99ed..8ca7007 100644
--- a/nss/lib/crmf/encutil.c
+++ b/nss/lib/crmf/encutil.c
@@ -9,17 +9,17 @@
void
crmf_encoder_out(void *arg, const char *buf, unsigned long len,
- int depth, SEC_ASN1EncodingPart data_kind)
+ int depth, SEC_ASN1EncodingPart data_kind)
{
struct crmfEncoderOutput *output;
- output = (struct crmfEncoderOutput*) arg;
- output->fn (output->outputArg, buf, len);
+ output = (struct crmfEncoderOutput *)arg;
+ output->fn(output->outputArg, buf, len);
}
SECStatus
cmmf_user_encode(void *src, CRMFEncoderOutputCallback inCallback, void *inArg,
- const SEC_ASN1Template *inTemplate)
+ const SEC_ASN1Template *inTemplate)
{
struct crmfEncoderOutput output;
@@ -27,8 +27,7 @@ cmmf_user_encode(void *src, CRMFEncoderOutputCallback inCallback, void *inArg,
if (src == NULL) {
return SECFailure;
}
- output.fn = inCallback;
+ output.fn = inCallback;
output.outputArg = inArg;
- return SEC_ASN1Encode(src, inTemplate, crmf_encoder_out, &output);
+ return SEC_ASN1Encode(src, inTemplate, crmf_encoder_out, &output);
}
-
diff --git a/nss/lib/crmf/exports.gyp b/nss/lib/crmf/exports.gyp
new file mode 100644
index 0000000..fca0097
--- /dev/null
+++ b/nss/lib/crmf/exports.gyp
@@ -0,0 +1,37 @@
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+{
+ 'includes': [
+ '../../coreconf/config.gypi'
+ ],
+ 'targets': [
+ {
+ 'target_name': 'lib_crmf_exports',
+ 'type': 'none',
+ 'copies': [
+ {
+ 'files': [
+ 'cmmf.h',
+ 'cmmft.h',
+ 'crmf.h',
+ 'crmft.h'
+ ],
+ 'destination': '<(nss_public_dist_dir)/<(module)'
+ },
+ {
+ 'files': [
+ 'cmmfi.h',
+ 'cmmfit.h',
+ 'crmfi.h',
+ 'crmfit.h'
+ ],
+ 'destination': '<(nss_private_dist_dir)/<(module)'
+ }
+ ]
+ }
+ ],
+ 'variables': {
+ 'module': 'nss'
+ }
+}
diff --git a/nss/lib/crmf/respcli.c b/nss/lib/crmf/respcli.c
index 5525aaf..aaec013 100644
--- a/nss/lib/crmf/respcli.c
+++ b/nss/lib/crmf/respcli.c
@@ -3,9 +3,8 @@
* License, v. 2.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
+ * This file will contain all routines needed by a client that has
* to parse a CMMFCertRepContent structure and retirieve the appropriate
* data.
*/
@@ -18,14 +17,14 @@
#include "secder.h"
#include "secasn1.h"
-CMMFCertRepContent*
-CMMF_CreateCertRepContentFromDER(CERTCertDBHandle *db, const char *buf,
- long len)
+CMMFCertRepContent *
+CMMF_CreateCertRepContentFromDER(CERTCertDBHandle *db, const char *buf,
+ long len)
{
- PLArenaPool *poolp;
+ PLArenaPool *poolp;
CMMFCertRepContent *certRepContent;
- SECStatus rv;
- int i;
+ SECStatus rv;
+ int i;
poolp = PORT_NewArena(CRMF_DEFAULT_ARENA_SIZE);
if (poolp == NULL) {
@@ -37,22 +36,22 @@ CMMF_CreateCertRepContentFromDER(CERTCertDBHandle *db, const char *buf,
}
certRepContent->poolp = poolp;
rv = SEC_ASN1Decode(poolp, certRepContent, CMMFCertRepContentTemplate,
- buf, len);
+ 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;
- }
- }
+ 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:
+loser:
PORT_FreeArena(poolp, PR_FALSE);
return NULL;
}
@@ -69,7 +68,7 @@ CMMF_CertResponseGetCertReqId(CMMFCertResponse *inCertResp)
PRBool
cmmf_CertRepContentIsIndexValid(CMMFCertRepContent *inCertRepContent,
- int inIndex)
+ int inIndex)
{
int numResponses;
@@ -78,27 +77,27 @@ cmmf_CertRepContentIsIndexValid(CMMFCertRepContent *inCertRepContent,
return (PRBool)(inIndex >= 0 && inIndex < numResponses);
}
-CMMFCertResponse*
+CMMFCertResponse *
CMMF_CertRepContentGetResponseAtIndex(CMMFCertRepContent *inCertRepContent,
- int inIndex)
+ int inIndex)
{
CMMFCertResponse *certResponse;
- SECStatus rv;
+ SECStatus rv;
PORT_Assert(inCertRepContent != NULL &&
- cmmf_CertRepContentIsIndexValid(inCertRepContent, inIndex));
+ cmmf_CertRepContentIsIndexValid(inCertRepContent, inIndex));
if (inCertRepContent == NULL ||
- !cmmf_CertRepContentIsIndexValid(inCertRepContent, inIndex)) {
+ !cmmf_CertRepContentIsIndexValid(inCertRepContent, inIndex)) {
return NULL;
}
certResponse = PORT_ZNew(CMMFCertResponse);
- if (certResponse){
- rv = cmmf_CopyCertResponse(NULL, certResponse,
- inCertRepContent->response[inIndex]);
- if (rv != SECSuccess) {
- CMMF_DestroyCertResponse(certResponse);
- certResponse = NULL;
- }
+ if (certResponse) {
+ rv = cmmf_CopyCertResponse(NULL, certResponse,
+ inCertRepContent->response[inIndex]);
+ if (rv != SECSuccess) {
+ CMMF_DestroyCertResponse(certResponse);
+ certResponse = NULL;
+ }
}
return certResponse;
}
@@ -113,27 +112,25 @@ CMMF_CertResponseGetPKIStatusInfoStatus(CMMFCertResponse *inCertResp)
return cmmf_PKIStatusInfoGetStatus(&inCertResp->status);
}
-CERTCertificate*
+CERTCertificate *
CMMF_CertResponseGetCertificate(CMMFCertResponse *inCertResp,
- CERTCertDBHandle *inCertdb)
+ CERTCertDBHandle *inCertdb)
{
PORT_Assert(inCertResp != NULL);
if (inCertResp == NULL || inCertResp->certifiedKeyPair == NULL) {
return NULL;
}
-
+
return cmmf_CertOrEncCertGetCertificate(
- &inCertResp->certifiedKeyPair->certOrEncCert, inCertdb);
-
+ &inCertResp->certifiedKeyPair->certOrEncCert, inCertdb);
}
-CERTCertList*
-CMMF_CertRepContentGetCAPubs (CMMFCertRepContent *inCertRepContent)
+CERTCertList *
+CMMF_CertRepContentGetCAPubs(CMMFCertRepContent *inCertRepContent)
{
- PORT_Assert (inCertRepContent != NULL);
+ PORT_Assert(inCertRepContent != NULL);
if (inCertRepContent == NULL || inCertRepContent->caPubs == NULL) {
return NULL;
}
return cmmf_MakeCertList(inCertRepContent->caPubs);
}
-
diff --git a/nss/lib/crmf/respcmn.c b/nss/lib/crmf/respcmn.c
index 1353d36..f9e4155 100644
--- a/nss/lib/crmf/respcmn.c
+++ b/nss/lib/crmf/respcmn.c
@@ -8,8 +8,8 @@
#include "secitem.h"
#include "secder.h"
-SECStatus
-cmmf_DestroyPKIStatusInfo (CMMFPKIStatusInfo *info, PRBool freeit)
+SECStatus
+cmmf_DestroyPKIStatusInfo(CMMFPKIStatusInfo *info, PRBool freeit)
{
if (info->status.data != NULL) {
PORT_Free(info->status.data);
@@ -35,13 +35,13 @@ 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);
+ PORT_Free(inCertResp->certReqId.data);
+ }
+ cmmf_DestroyPKIStatusInfo(&inCertResp->status, PR_FALSE);
+ if (inCertResp->certifiedKeyPair != NULL) {
+ CMMF_DestroyCertifiedKeyPair(inCertResp->certifiedKeyPair);
+ }
+ PORT_Free(inCertResp);
}
return SECSuccess;
}
@@ -51,32 +51,31 @@ CMMF_DestroyCertRepContent(CMMFCertRepContent *inCertRepContent)
{
PORT_Assert(inCertRepContent != NULL);
if (inCertRepContent != NULL) {
- CMMFCertResponse **pResponse = inCertRepContent->response;
+ 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 &&
+ 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;
+ 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);
- }
+ 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;
}
@@ -94,73 +93,73 @@ CMMF_DestroyPOPODecKeyChallContent(CMMFPOPODecKeyChallContent *inDecKeyCont)
SECStatus
crmf_create_prtime(SECItem *src, PRTime **dest)
{
- *dest = PORT_ZNew(PRTime);
+ *dest = PORT_ZNew(PRTime);
return DER_DecodeTimeChoice(*dest, src);
}
-CRMFCertExtension*
+CRMFCertExtension *
crmf_copy_cert_extension(PLArenaPool *poolp, CRMFCertExtension *inExtension)
{
- PRBool isCritical;
- SECOidTag id;
- SECItem *data;
+ PRBool isCritical;
+ SECOidTag id;
+ SECItem *data;
CRMFCertExtension *newExt;
PORT_Assert(inExtension != NULL);
if (inExtension == NULL) {
return NULL;
}
- id = CRMF_CertExtensionGetOidTag(inExtension);
+ id = CRMF_CertExtensionGetOidTag(inExtension);
isCritical = CRMF_CertExtensionGetIsCritical(inExtension);
- data = CRMF_CertExtensionGetValue(inExtension);
- newExt = crmf_create_cert_extension(poolp, id,
- isCritical,
- data);
+ data = CRMF_CertExtensionGetValue(inExtension);
+ newExt = crmf_create_cert_extension(poolp, id,
+ isCritical,
+ data);
SECITEM_FreeItem(data, PR_TRUE);
- return newExt;
+ return newExt;
}
-static SECItem*
+static SECItem *
cmmf_encode_certificate(CERTCertificate *inCert)
{
- return SEC_ASN1EncodeItem(NULL, NULL, inCert,
- SEC_ASN1_GET(SEC_SignedCertificateTemplate));
+ return SEC_ASN1EncodeItem(NULL, NULL, inCert,
+ SEC_ASN1_GET(SEC_SignedCertificateTemplate));
}
-CERTCertList*
+CERTCertList *
cmmf_MakeCertList(CERTCertificate **inCerts)
{
- CERTCertList *certList;
+ CERTCertList *certList;
CERTCertificate *currCert;
- SECItem *derCert, *freeCert = NULL;
- SECStatus rv;
- int i;
+ SECItem *derCert, *freeCert = NULL;
+ SECStatus rv;
+ int i;
certList = CERT_NewCertList();
if (certList == NULL) {
return NULL;
}
- for (i=0; inCerts[i] != NULL; i++) {
+ 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;
- }
+ 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:
+loser:
CERT_DestroyCertList(certList);
return NULL;
}
@@ -181,31 +180,30 @@ int
CMMF_CertRepContentGetNumResponses(CMMFCertRepContent *inCertRepContent)
{
int numResponses = 0;
- PORT_Assert (inCertRepContent != NULL);
+ PORT_Assert(inCertRepContent != NULL);
if (inCertRepContent != NULL && inCertRepContent->response != NULL) {
while (inCertRepContent->response[numResponses] != NULL) {
- numResponses++;
- }
+ 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;
+ 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);
@@ -214,7 +212,7 @@ cmmf_DestroyCertOrEncCert(CMMFCertOrEncCert *certOrEncCert, PRBool freeit)
}
SECStatus
-cmmf_copy_secitem (PLArenaPool *poolp, SECItem *dest, SECItem *src)
+cmmf_copy_secitem(PLArenaPool *poolp, SECItem *dest, SECItem *src)
{
SECStatus rv;
@@ -222,8 +220,8 @@ cmmf_copy_secitem (PLArenaPool *poolp, SECItem *dest, SECItem *src)
rv = SECITEM_CopyItem(poolp, dest, src);
} else {
dest->data = NULL;
- dest->len = 0;
- rv = SECSuccess;
+ dest->len = 0;
+ rv = SECSuccess;
}
return rv;
}
@@ -246,161 +244,156 @@ CMMF_DestroyCertifiedKeyPair(CMMFCertifiedKeyPair *inCertKeyPair)
}
SECStatus
-cmmf_CopyCertResponse(PLArenaPool *poolp,
- CMMFCertResponse *dest,
- CMMFCertResponse *src)
+cmmf_CopyCertResponse(PLArenaPool *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;
- }
+ 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;
+ 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(PLArenaPool *poolp, CMMFCertOrEncCert *dest,
- CMMFCertOrEncCert *src)
+ CMMFCertOrEncCert *src)
{
- SECStatus rv = SECSuccess;
+ 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;
+ 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(PLArenaPool *poolp, CMMFCertifiedKeyPair *dest,
- CMMFCertifiedKeyPair *src)
+ CMMFCertifiedKeyPair *src)
{
SECStatus rv;
- rv = cmmf_CopyCertOrEncCert(poolp, &dest->certOrEncCert,
- &src->certOrEncCert);
+ 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;
+ 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);
+ rv = cmmf_copy_secitem(poolp, &dest->derPublicationInfo,
+ &src->derPublicationInfo);
return rv;
}
SECStatus
cmmf_CopyPKIStatusInfo(PLArenaPool *poolp, CMMFPKIStatusInfo *dest,
- CMMFPKIStatusInfo *src)
+ CMMFPKIStatusInfo *src)
{
SECStatus rv;
- rv = cmmf_copy_secitem (poolp, &dest->status, &src->status);
+ rv = cmmf_copy_secitem(poolp, &dest->status, &src->status);
if (rv != SECSuccess) {
return rv;
}
- rv = cmmf_copy_secitem (poolp, &dest->statusString, &src->statusString);
+ rv = cmmf_copy_secitem(poolp, &dest->statusString, &src->statusString);
if (rv != SECSuccess) {
return rv;
}
- rv = cmmf_copy_secitem (poolp, &dest->failInfo, &src->failInfo);
+ rv = cmmf_copy_secitem(poolp, &dest->failInfo, &src->failInfo);
return rv;
}
-CERTCertificate*
+CERTCertificate *
cmmf_CertOrEncCertGetCertificate(CMMFCertOrEncCert *certOrEncCert,
- CERTCertDBHandle *certdb)
+ CERTCertDBHandle *certdb)
{
- if (certOrEncCert->choice != cmmfCertificate ||
- certOrEncCert->cert.certificate == NULL) {
+ if (certOrEncCert->choice != cmmfCertificate ||
+ certOrEncCert->cert.certificate == NULL) {
return NULL;
}
return CERT_NewTempCertificate(certdb,
- &certOrEncCert->cert.certificate->derCert,
- NULL, PR_FALSE, PR_TRUE);
+ &certOrEncCert->cert.certificate->derCert,
+ NULL, PR_FALSE, PR_TRUE);
}
-SECStatus
-cmmf_PKIStatusInfoSetStatus(CMMFPKIStatusInfo *statusInfo,
- PLArenaPool *poolp,
- CMMFPKIStatus inStatus)
+SECStatus
+cmmf_PKIStatusInfoSetStatus(CMMFPKIStatusInfo *statusInfo,
+ PLArenaPool *poolp,
+ CMMFPKIStatus inStatus)
{
SECItem *dummy;
-
- if (inStatus <cmmfGranted || inStatus >= cmmfNumPKIStatus) {
+
+ if (inStatus < cmmfGranted || inStatus >= cmmfNumPKIStatus) {
return SECFailure;
}
- dummy = SEC_ASN1EncodeInteger(poolp, &statusInfo->status, inStatus);
+ dummy = SEC_ASN1EncodeInteger(poolp, &statusInfo->status, inStatus);
PORT_Assert(dummy == &statusInfo->status);
if (dummy != &statusInfo->status) {
SECITEM_FreeItem(dummy, PR_TRUE);
- return SECFailure;
+ return SECFailure;
}
return SECSuccess;
}
-
-
diff --git a/nss/lib/crmf/servget.c b/nss/lib/crmf/servget.c
index d19c829..6d576f8 100644
--- a/nss/lib/crmf/servget.c
+++ b/nss/lib/crmf/servget.c
@@ -3,7 +3,6 @@
* License, v. 2.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"
@@ -20,15 +19,15 @@ CRMF_EncryptedKeyGetChoice(CRMFEncryptedKey *inEncrKey)
return inEncrKey->encKeyChoice;
}
-CRMFEncryptedValue*
+CRMFEncryptedValue *
CRMF_EncryptedKeyGetEncryptedValue(CRMFEncryptedKey *inEncrKey)
{
CRMFEncryptedValue *newEncrValue = NULL;
- SECStatus rv;
+ SECStatus rv;
PORT_Assert(inEncrKey != NULL);
if (inEncrKey == NULL ||
- CRMF_EncryptedKeyGetChoice(inEncrKey) != crmfEncryptedValueChoice) {
+ CRMF_EncryptedKeyGetChoice(inEncrKey) != crmfEncryptedValueChoice) {
goto loser;
}
newEncrValue = PORT_ZNew(CRMFEncryptedValue);
@@ -36,24 +35,24 @@ CRMF_EncryptedKeyGetEncryptedValue(CRMFEncryptedKey *inEncrKey)
goto loser;
}
rv = crmf_copy_encryptedvalue(NULL, &inEncrKey->value.encryptedValue,
- newEncrValue);
+ newEncrValue);
if (rv != SECSuccess) {
goto loser;
}
return newEncrValue;
- loser:
+loser:
if (newEncrValue != NULL) {
CRMF_DestroyEncryptedValue(newEncrValue);
}
return NULL;
}
-static SECItem*
+static SECItem *
crmf_get_encvalue_bitstring(SECItem *srcItem)
{
- SECItem *newItem = NULL;
+ SECItem *newItem = NULL;
SECStatus rv;
-
+
if (srcItem->data == NULL) {
return NULL;
}
@@ -66,14 +65,14 @@ crmf_get_encvalue_bitstring(SECItem *srcItem)
goto loser;
}
return newItem;
- loser:
+loser:
if (newItem != NULL) {
SECITEM_FreeItem(newItem, PR_TRUE);
}
return NULL;
}
-SECItem*
+SECItem *
CRMF_EncryptedValueGetEncSymmKey(CRMFEncryptedValue *inEncValue)
{
if (inEncValue == NULL) {
@@ -82,7 +81,7 @@ CRMF_EncryptedValueGetEncSymmKey(CRMFEncryptedValue *inEncValue)
return crmf_get_encvalue_bitstring(&inEncValue->encSymmKey);
}
-SECItem*
+SECItem *
CRMF_EncryptedValueGetEncValue(CRMFEncryptedValue *inEncrValue)
{
if (inEncrValue == NULL || inEncrValue->encValue.data == NULL) {
@@ -91,12 +90,12 @@ CRMF_EncryptedValueGetEncValue(CRMFEncryptedValue *inEncrValue)
return crmf_get_encvalue_bitstring(&inEncrValue->encValue);
}
-static SECAlgorithmID*
+static SECAlgorithmID *
crmf_get_encvalue_algid(SECAlgorithmID *srcAlg)
{
- SECStatus rv;
+ SECStatus rv;
SECAlgorithmID *newAlgID;
-
+
if (srcAlg == NULL) {
return NULL;
}
@@ -107,7 +106,7 @@ crmf_get_encvalue_algid(SECAlgorithmID *srcAlg)
return newAlgID;
}
-SECAlgorithmID*
+SECAlgorithmID *
CRMF_EncryptedValueGetIntendedAlg(CRMFEncryptedValue *inEncValue)
{
if (inEncValue == NULL) {
@@ -116,7 +115,7 @@ CRMF_EncryptedValueGetIntendedAlg(CRMFEncryptedValue *inEncValue)
return crmf_get_encvalue_algid(inEncValue->intendedAlg);
}
-SECAlgorithmID*
+SECAlgorithmID *
CRMF_EncryptedValueGetKeyAlg(CRMFEncryptedValue *inEncValue)
{
if (inEncValue == NULL) {
@@ -125,7 +124,7 @@ CRMF_EncryptedValueGetKeyAlg(CRMFEncryptedValue *inEncValue)
return crmf_get_encvalue_algid(inEncValue->keyAlg);
}
-SECAlgorithmID*
+SECAlgorithmID *
CRMF_EncryptedValueGetSymmAlg(CRMFEncryptedValue *inEncValue)
{
if (inEncValue == NULL) {
@@ -134,7 +133,7 @@ CRMF_EncryptedValueGetSymmAlg(CRMFEncryptedValue *inEncValue)
return crmf_get_encvalue_algid(inEncValue->symmAlg);
}
-SECItem*
+SECItem *
CRMF_EncryptedValueGetValueHint(CRMFEncryptedValue *inEncValue)
{
if (inEncValue == NULL || inEncValue->valueHint.data == NULL) {
@@ -144,28 +143,28 @@ CRMF_EncryptedValueGetValueHint(CRMFEncryptedValue *inEncValue)
}
SECStatus
-CRMF_PKIArchiveOptionsGetArchiveRemGenPrivKey(CRMFPKIArchiveOptions *inOpt,
- PRBool *destVal)
+CRMF_PKIArchiveOptionsGetArchiveRemGenPrivKey(CRMFPKIArchiveOptions *inOpt,
+ PRBool *destVal)
{
if (inOpt == NULL || destVal == NULL ||
- CRMF_PKIArchiveOptionsGetOptionType(inOpt) != crmfArchiveRemGenPrivKey){
+ CRMF_PKIArchiveOptionsGetOptionType(inOpt) != crmfArchiveRemGenPrivKey) {
return SECFailure;
}
- *destVal = (inOpt->option.archiveRemGenPrivKey.data[0] == hexFalse)
- ? PR_FALSE:
- PR_TRUE;
+ *destVal = (inOpt->option.archiveRemGenPrivKey.data[0] == hexFalse)
+ ? PR_FALSE
+ : PR_TRUE;
return SECSuccess;
}
-
-CRMFEncryptedKey*
+
+CRMFEncryptedKey *
CRMF_PKIArchiveOptionsGetEncryptedPrivKey(CRMFPKIArchiveOptions *inOpts)
{
CRMFEncryptedKey *newEncrKey = NULL;
- SECStatus rv;
+ SECStatus rv;
PORT_Assert(inOpts != NULL);
if (inOpts == NULL ||
- CRMF_PKIArchiveOptionsGetOptionType(inOpts) != crmfEncryptedPrivateKey){
+ CRMF_PKIArchiveOptionsGetOptionType(inOpts) != crmfEncryptedPrivateKey) {
return NULL;
}
newEncrKey = PORT_ZNew(CRMFEncryptedKey);
@@ -173,24 +172,24 @@ CRMF_PKIArchiveOptionsGetEncryptedPrivKey(CRMFPKIArchiveOptions *inOpts)
goto loser;
}
rv = crmf_copy_encryptedkey(NULL, &inOpts->option.encryptedKey,
- newEncrKey);
+ newEncrKey);
if (rv != SECSuccess) {
goto loser;
}
return newEncrKey;
- loser:
+loser:
if (newEncrKey != NULL) {
CRMF_DestroyEncryptedKey(newEncrKey);
}
return NULL;
}
-SECItem*
+SECItem *
CRMF_PKIArchiveOptionsGetKeyGenParameters(CRMFPKIArchiveOptions *inOptions)
{
if (inOptions == NULL ||
- CRMF_PKIArchiveOptionsGetOptionType(inOptions) != crmfKeyGenParameters ||
- inOptions->option.keyGenParameters.data == NULL) {
+ CRMF_PKIArchiveOptionsGetOptionType(inOptions) != crmfKeyGenParameters ||
+ inOptions->option.keyGenParameters.data == NULL) {
return NULL;
}
return SECITEM_DupItem(&inOptions->option.keyGenParameters);
@@ -199,7 +198,7 @@ CRMF_PKIArchiveOptionsGetKeyGenParameters(CRMFPKIArchiveOptions *inOptions)
CRMFPKIArchiveOptionsType
CRMF_PKIArchiveOptionsGetOptionType(CRMFPKIArchiveOptions *inOptions)
{
- PORT_Assert (inOptions != NULL);
+ PORT_Assert(inOptions != NULL);
if (inOptions == NULL) {
return crmfNoArchiveOptions;
}
@@ -214,30 +213,30 @@ crmf_extract_long_from_item(SECItem *intItem, long *destLong)
}
SECStatus
-CRMF_POPOPrivGetKeySubseqMess(CRMFPOPOPrivKey *inKey,
- CRMFSubseqMessOptions *destOpt)
+CRMF_POPOPrivGetKeySubseqMess(CRMFPOPOPrivKey *inKey,
+ CRMFSubseqMessOptions *destOpt)
{
- long value;
+ long value;
SECStatus rv;
PORT_Assert(inKey != NULL);
if (inKey == NULL ||
- inKey->messageChoice != crmfSubsequentMessage) {
+ inKey->messageChoice != crmfSubsequentMessage) {
return SECFailure;
}
- rv = crmf_extract_long_from_item(&inKey->message.subsequentMessage,&value);
+ 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;
+ case 0:
+ *destOpt = crmfEncrCert;
+ break;
+ case 1:
+ *destOpt = crmfChallengeResp;
+ break;
+ default:
+ rv = SECFailure;
}
if (rv != SECSuccess) {
return rv;
@@ -266,24 +265,24 @@ CRMF_POPOPrivKeyGetDHMAC(CRMFPOPOPrivKey *inKey, SECItem *destMAC)
}
SECStatus
-CRMF_POPOPrivKeyGetThisMessage(CRMFPOPOPrivKey *inKey,
- SECItem *destString)
+CRMF_POPOPrivKeyGetThisMessage(CRMFPOPOPrivKey *inKey,
+ SECItem *destString)
{
PORT_Assert(inKey != NULL);
- if (inKey == NULL ||
- inKey->messageChoice != crmfThisMessage) {
+ if (inKey == NULL ||
+ inKey->messageChoice != crmfThisMessage) {
return SECFailure;
}
- return crmf_make_bitstring_copy(NULL, destString,
- &inKey->message.thisMessage);
+ return crmf_make_bitstring_copy(NULL, destString,
+ &inKey->message.thisMessage);
}
-SECAlgorithmID*
+SECAlgorithmID *
CRMF_POPOSigningKeyGetAlgID(CRMFPOPOSigningKey *inSignKey)
{
SECAlgorithmID *newAlgId = NULL;
- SECStatus rv;
+ SECStatus rv;
PORT_Assert(inSignKey != NULL);
if (inSignKey == NULL) {
@@ -293,21 +292,21 @@ CRMF_POPOSigningKeyGetAlgID(CRMFPOPOSigningKey *inSignKey)
if (newAlgId == NULL) {
goto loser;
}
- rv = SECOID_CopyAlgorithmID(NULL, newAlgId,
- inSignKey->algorithmIdentifier);
+ rv = SECOID_CopyAlgorithmID(NULL, newAlgId,
+ inSignKey->algorithmIdentifier);
if (rv != SECSuccess) {
goto loser;
}
return newAlgId;
- loser:
+loser:
if (newAlgId != NULL) {
SECOID_DestroyAlgorithmID(newAlgId, PR_TRUE);
}
return NULL;
}
-SECItem*
+SECItem *
CRMF_POPOSigningKeyGetInput(CRMFPOPOSigningKey *inSignKey)
{
PORT_Assert(inSignKey != NULL);
@@ -317,11 +316,11 @@ CRMF_POPOSigningKeyGetInput(CRMFPOPOSigningKey *inSignKey)
return SECITEM_DupItem(&inSignKey->derInput);
}
-SECItem*
+SECItem *
CRMF_POPOSigningKeyGetSignature(CRMFPOPOSigningKey *inSignKey)
{
- SECItem *newSig = NULL;
- SECStatus rv;
+ SECItem *newSig = NULL;
+ SECStatus rv;
PORT_Assert(inSignKey != NULL);
if (inSignKey == NULL) {
@@ -336,47 +335,49 @@ CRMF_POPOSigningKeyGetSignature(CRMFPOPOSigningKey *inSignKey)
goto loser;
}
return newSig;
- loser:
+loser:
if (newSig != NULL) {
SECITEM_FreeItem(newSig, PR_TRUE);
}
return NULL;
}
-static SECStatus
-crmf_copy_poposigningkey(PLArenaPool *poolp,
- CRMFPOPOSigningKey *inPopoSignKey,
- CRMFPOPOSigningKey *destPopoSignKey)
+static SECStatus
+crmf_copy_poposigningkey(PLArenaPool *poolp,
+ CRMFPOPOSigningKey *inPopoSignKey,
+ CRMFPOPOSigningKey *destPopoSignKey)
{
SECStatus rv;
- /* We don't support use of the POPOSigningKeyInput, so we'll only
+ /* 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);
+ rv = SECITEM_CopyItem(poolp, &destPopoSignKey->derInput,
+ &inPopoSignKey->derInput);
+ if (rv != SECSuccess) {
+ goto loser;
+ }
}
- destPopoSignKey->algorithmIdentifier = (poolp == NULL) ?
- PORT_ZNew(SECAlgorithmID) :
- PORT_ArenaZNew(poolp, SECAlgorithmID);
+ 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);
+ inPopoSignKey->algorithmIdentifier);
if (rv != SECSuccess) {
goto loser;
}
-
- rv = crmf_make_bitstring_copy(poolp, &destPopoSignKey->signature,
- &inPopoSignKey->signature);
+
+ rv = crmf_make_bitstring_copy(poolp, &destPopoSignKey->signature,
+ &inPopoSignKey->signature);
if (rv != SECSuccess) {
goto loser;
}
return SECSuccess;
- loser:
+loser:
if (poolp == NULL) {
CRMF_DestroyPOPOSigningKey(destPopoSignKey);
}
@@ -384,28 +385,28 @@ crmf_copy_poposigningkey(PLArenaPool *poolp,
}
static SECStatus
-crmf_copy_popoprivkey(PLArenaPool *poolp,
- CRMFPOPOPrivKey *srcPrivKey,
- CRMFPOPOPrivKey *destPrivKey)
+crmf_copy_popoprivkey(PLArenaPool *poolp,
+ CRMFPOPOPrivKey *srcPrivKey,
+ CRMFPOPOPrivKey *destPrivKey)
{
- SECStatus rv;
+ 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;
+ 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) {
@@ -414,13 +415,13 @@ crmf_copy_popoprivkey(PLArenaPool *poolp,
return rv;
}
-static CRMFProofOfPossession*
+static CRMFProofOfPossession *
crmf_copy_pop(PLArenaPool *poolp, CRMFProofOfPossession *srcPOP)
{
CRMFProofOfPossession *newPOP;
- SECStatus rv;
+ SECStatus rv;
- /*
+ /*
* Proof Of Possession structures are always part of the Request
* message, so there will always be an arena for allocating memory.
*/
@@ -432,43 +433,43 @@ crmf_copy_pop(PLArenaPool *poolp, CRMFProofOfPossession *srcPOP)
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;
+ 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:
+loser:
return NULL;
}
-static CRMFCertReqMsg*
+static CRMFCertReqMsg *
crmf_copy_cert_req_msg(CRMFCertReqMsg *srcReqMsg)
{
CRMFCertReqMsg *newReqMsg;
- PLArenaPool *poolp;
+ PLArenaPool *poolp;
poolp = PORT_NewArena(CRMF_DEFAULT_ARENA_SIZE);
if (poolp == NULL) {
@@ -494,16 +495,14 @@ crmf_copy_cert_req_msg(CRMFCertReqMsg *srcReqMsg)
*/
return newReqMsg;
- loser:
- if (newReqMsg != NULL) {
- CRMF_DestroyCertReqMsg(newReqMsg);
- }
+loser:
+ CRMF_DestroyCertReqMsg(newReqMsg);
return NULL;
}
-CRMFCertReqMsg*
+CRMFCertReqMsg *
CRMF_CertReqMessagesGetCertReqMsgAtIndex(CRMFCertReqMessages *inReqMsgs,
- int index)
+ int index)
{
int numMsgs;
@@ -533,10 +532,10 @@ CRMF_CertReqMessagesGetNumMessages(CRMFCertReqMessages *inCertReqMsgs)
return numMessages;
}
-CRMFCertRequest*
+CRMFCertRequest *
CRMF_CertReqMsgGetCertRequest(CRMFCertReqMsg *inCertReqMsg)
{
- PLArenaPool *poolp = NULL;
+ PLArenaPool *poolp = NULL;
CRMFCertRequest *newCertReq = NULL;
PORT_Assert(inCertReqMsg != NULL);
@@ -551,7 +550,7 @@ CRMF_CertReqMsgGetCertRequest(CRMFCertReqMsg *inCertReqMsg)
}
newCertReq->poolp = poolp;
return newCertReq;
- loser:
+loser:
if (poolp != NULL) {
PORT_FreeArena(poolp, PR_FALSE);
}
@@ -565,17 +564,17 @@ CRMF_CertReqMsgGetID(CRMFCertReqMsg *inCertReqMsg, long *destID)
if (inCertReqMsg == NULL || inCertReqMsg->certReq == NULL) {
return SECFailure;
}
- return crmf_extract_long_from_item(&inCertReqMsg->certReq->certReqId,
- destID);
+ return crmf_extract_long_from_item(&inCertReqMsg->certReq->certReqId,
+ destID);
}
SECStatus
-CRMF_CertReqMsgGetPOPKeyAgreement(CRMFCertReqMsg *inCertReqMsg,
- CRMFPOPOPrivKey **destKey)
+CRMF_CertReqMsgGetPOPKeyAgreement(CRMFCertReqMsg *inCertReqMsg,
+ CRMFPOPOPrivKey **destKey)
{
PORT_Assert(inCertReqMsg != NULL && destKey != NULL);
if (inCertReqMsg == NULL || destKey == NULL ||
- CRMF_CertReqMsgGetPOPType(inCertReqMsg) != crmfKeyAgreement) {
+ CRMF_CertReqMsgGetPOPType(inCertReqMsg) != crmfKeyAgreement) {
return SECFailure;
}
*destKey = PORT_ZNew(CRMFPOPOPrivKey);
@@ -583,38 +582,39 @@ CRMF_CertReqMsgGetPOPKeyAgreement(CRMFCertReqMsg *inCertReqMsg,
return SECFailure;
}
return crmf_copy_popoprivkey(NULL,
- &inCertReqMsg->pop->popChoice.keyAgreement,
- *destKey);
+ &inCertReqMsg->pop->popChoice.keyAgreement,
+ *destKey);
}
SECStatus
-CRMF_CertReqMsgGetPOPKeyEncipherment(CRMFCertReqMsg *inCertReqMsg,
- CRMFPOPOPrivKey **destKey)
+CRMF_CertReqMsgGetPOPKeyEncipherment(CRMFCertReqMsg *inCertReqMsg,
+ CRMFPOPOPrivKey **destKey)
{
PORT_Assert(inCertReqMsg != NULL && destKey != NULL);
if (inCertReqMsg == NULL || destKey == NULL ||
- CRMF_CertReqMsgGetPOPType(inCertReqMsg) != crmfKeyEncipherment) {
+ CRMF_CertReqMsgGetPOPType(inCertReqMsg) != crmfKeyEncipherment) {
return SECFailure;
}
*destKey = PORT_ZNew(CRMFPOPOPrivKey);
if (*destKey == NULL) {
- return SECFailure;
+ return SECFailure;
}
return crmf_copy_popoprivkey(NULL,
- &inCertReqMsg->pop->popChoice.keyEncipherment,
- *destKey);
+ &inCertReqMsg->pop->popChoice.keyEncipherment,
+ *destKey);
}
SECStatus
-CRMF_CertReqMsgGetPOPOSigningKey(CRMFCertReqMsg *inCertReqMsg,
- CRMFPOPOSigningKey **destKey)
+CRMF_CertReqMsgGetPOPOSigningKey(CRMFCertReqMsg *inCertReqMsg,
+ CRMFPOPOSigningKey **destKey)
{
CRMFProofOfPossession *pop;
PORT_Assert(inCertReqMsg != NULL);
- if (inCertReqMsg == NULL) {
+ if (inCertReqMsg == NULL) {
return SECFailure;
}
- pop = inCertReqMsg->pop;;
+ pop = inCertReqMsg->pop;
+ ;
if (pop->popUsed != crmfSignature) {
return SECFailure;
}
@@ -622,50 +622,50 @@ CRMF_CertReqMsgGetPOPOSigningKey(CRMFCertReqMsg *inCertReqMsg,
if (*destKey == NULL) {
return SECFailure;
}
- return crmf_copy_poposigningkey(NULL,&pop->popChoice.signature, *destKey);
+ return crmf_copy_poposigningkey(NULL, &pop->popChoice.signature, *destKey);
}
static SECStatus
crmf_copy_name(CERTName *destName, CERTName *srcName)
{
- PLArenaPool *poolp = NULL;
- SECStatus rv;
+ PLArenaPool *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;
+ 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)
+ 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 crmf_copy_name(destIssuer,
+ inCertReq->certTemplate.issuer);
}
return SECFailure;
}
-SECStatus
+SECStatus
CRMF_CertRequestGetCertTemplateIssuerUID(CRMFCertRequest *inCertReq,
- SECItem *destIssuerUID)
+ SECItem *destIssuerUID)
{
PORT_Assert(inCertReq != NULL);
if (inCertReq == NULL) {
@@ -673,146 +673,145 @@ CRMF_CertRequestGetCertTemplateIssuerUID(CRMFCertRequest *inCertReq,
}
if (CRMF_DoesRequestHaveField(inCertReq, crmfIssuerUID)) {
return crmf_make_bitstring_copy(NULL, destIssuerUID,
- &inCertReq->certTemplate.issuerUID);
+ &inCertReq->certTemplate.issuerUID);
}
return SECFailure;
}
SECStatus
-CRMF_CertRequestGetCertTemplatePublicKey(CRMFCertRequest *inCertReq,
- CERTSubjectPublicKeyInfo *destPublicKey)
+CRMF_CertRequestGetCertTemplatePublicKey(CRMFCertRequest *inCertReq,
+ CERTSubjectPublicKeyInfo *destPublicKey)
{
- PORT_Assert (inCertReq != NULL);
+ PORT_Assert(inCertReq != NULL);
if (inCertReq == NULL) {
return SECFailure;
}
if (CRMF_DoesRequestHaveField(inCertReq, crmfPublicKey)) {
return SECKEY_CopySubjectPublicKeyInfo(NULL, destPublicKey,
- inCertReq->certTemplate.publicKey);
+ inCertReq->certTemplate.publicKey);
}
return SECFailure;
}
SECStatus
CRMF_CertRequestGetCertTemplateSerialNumber(CRMFCertRequest *inCertReq,
- long *serialNumber)
+ 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 crmf_extract_long_from_item(&inCertReq->certTemplate.serialNumber,
+ serialNumber);
}
return SECFailure;
}
SECStatus
CRMF_CertRequestGetCertTemplateSigningAlg(CRMFCertRequest *inCertReq,
- SECAlgorithmID *destAlg)
+ 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 SECOID_CopyAlgorithmID(NULL, destAlg,
+ inCertReq->certTemplate.signingAlg);
}
return SECFailure;
}
-SECStatus
+SECStatus
CRMF_CertRequestGetCertTemplateSubject(CRMFCertRequest *inCertReq,
- CERTName *destSubject)
+ 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;
+ 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)
+ 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 crmf_make_bitstring_copy(NULL, destSubjectUID,
+ &inCertReq->certTemplate.subjectUID);
}
return SECFailure;
}
-SECStatus
-CRMF_CertRequestGetCertTemplateVersion(CRMFCertRequest *inCertReq,
- long *version)
+SECStatus
+CRMF_CertRequestGetCertTemplateVersion(CRMFCertRequest *inCertReq,
+ long *version)
{
- PORT_Assert (inCertReq != NULL);
+ PORT_Assert(inCertReq != NULL);
if (inCertReq == NULL) {
return SECFailure;
}
if (CRMF_DoesRequestHaveField(inCertReq, crmfVersion)) {
return crmf_extract_long_from_item(&inCertReq->certTemplate.version,
- version);
- }
+ version);
+ }
return SECFailure;
}
static SECStatus
-crmf_copy_validity(CRMFGetValidity *destValidity,
- CRMFOptionalValidity *src)
+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;
- }
+ 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;
- }
+ &destValidity->notAfter);
+ if (rv != SECSuccess) {
+ return rv;
+ }
}
return SECSuccess;
}
-SECStatus
+SECStatus
CRMF_CertRequestGetCertTemplateValidity(CRMFCertRequest *inCertReq,
- CRMFGetValidity *destValidity)
+ 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 crmf_copy_validity(destValidity,
+ inCertReq->certTemplate.validity);
}
return SECFailure;
}
-CRMFControl*
+CRMFControl *
CRMF_CertRequestGetControlAtIndex(CRMFCertRequest *inCertReq, int index)
{
CRMFControl *newControl, *srcControl;
- int numControls;
- SECStatus rv;
+ int numControls;
+ SECStatus rv;
PORT_Assert(inCertReq != NULL);
if (inCertReq == NULL) {
@@ -828,63 +827,61 @@ CRMF_CertRequestGetControlAtIndex(CRMFCertRequest *inCertReq, int index)
}
srcControl = inCertReq->controls[index];
newControl->tag = srcControl->tag;
- rv = SECITEM_CopyItem (NULL, &newControl->derTag, &srcControl->derTag);
+ rv = SECITEM_CopyItem(NULL, &newControl->derTag, &srcControl->derTag);
if (rv != SECSuccess) {
goto loser;
}
- rv = SECITEM_CopyItem(NULL, &newControl->derValue,
- &srcControl->derValue);
+ 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;
+ 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);
- }
+loser:
+ CRMF_DestroyControl(newControl);
return NULL;
}
-static SECItem*
+static SECItem *
crmf_copy_control_value(CRMFControl *inControl)
{
return SECITEM_DupItem(&inControl->derValue);
}
-SECItem*
+SECItem *
CRMF_ControlGetAuthenticatorControlValue(CRMFControl *inControl)
{
- PORT_Assert (inControl!= NULL);
+ PORT_Assert(inControl != NULL);
if (inControl == NULL ||
- CRMF_ControlGetControlType(inControl) != crmfAuthenticatorControl) {
+ CRMF_ControlGetControlType(inControl) != crmfAuthenticatorControl) {
return NULL;
}
return crmf_copy_control_value(inControl);
@@ -897,31 +894,31 @@ CRMF_ControlGetControlType(CRMFControl *inControl)
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;
+ 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*
+CRMFPKIArchiveOptions *
CRMF_ControlGetPKIArchiveOptions(CRMFControl *inControl)
{
CRMFPKIArchiveOptions *newOpt = NULL;
@@ -929,40 +926,41 @@ CRMF_ControlGetPKIArchiveOptions(CRMFControl *inControl)
PORT_Assert(inControl != NULL);
if (inControl == NULL ||
- CRMF_ControlGetControlType(inControl) != crmfPKIArchiveOptionsControl){
+ CRMF_ControlGetControlType(inControl) != crmfPKIArchiveOptionsControl) {
goto loser;
}
newOpt = PORT_ZNew(CRMFPKIArchiveOptions);
if (newOpt == NULL) {
goto loser;
}
- rv = crmf_copy_pkiarchiveoptions(NULL, newOpt,
- &inControl->value.archiveOptions);
+ rv = crmf_copy_pkiarchiveoptions(NULL, newOpt,
+ &inControl->value.archiveOptions);
if (rv != SECSuccess) {
goto loser;
}
- loser:
+loser:
if (newOpt != NULL) {
CRMF_DestroyPKIArchiveOptions(newOpt);
}
return NULL;
}
-SECItem*
+SECItem *
CRMF_ControlGetRegTokenControlValue(CRMFControl *inControl)
{
PORT_Assert(inControl != NULL);
if (inControl == NULL ||
- CRMF_ControlGetControlType(inControl) != crmfRegTokenControl) {
+ CRMF_ControlGetControlType(inControl) != crmfRegTokenControl) {
return NULL;
}
- return crmf_copy_control_value(inControl);;
+ return crmf_copy_control_value(inControl);
+ ;
}
-CRMFCertExtension*
+CRMFCertExtension *
CRMF_CertRequestGetExtensionAtIndex(CRMFCertRequest *inCertReq,
- int index)
+ int index)
{
int numExtensions;
@@ -971,8 +969,6 @@ CRMF_CertRequestGetExtensionAtIndex(CRMFCertRequest *inCertReq,
if (index >= numExtensions || index < 0) {
return NULL;
}
- return
- crmf_copy_cert_extension(NULL,
- inCertReq->certTemplate.extensions[index]);
+ return crmf_copy_cert_extension(NULL,
+ inCertReq->certTemplate.extensions[index]);
}
-
diff --git a/nss/lib/cryptohi/cryptohi.gyp b/nss/lib/cryptohi/cryptohi.gyp
new file mode 100644
index 0000000..ef9e63f
--- /dev/null
+++ b/nss/lib/cryptohi/cryptohi.gyp
@@ -0,0 +1,27 @@
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+{
+ 'includes': [
+ '../../coreconf/config.gypi'
+ ],
+ 'targets': [
+ {
+ 'target_name': 'cryptohi',
+ 'type': 'static_library',
+ 'sources': [
+ 'dsautil.c',
+ 'sechash.c',
+ 'seckey.c',
+ 'secsign.c',
+ 'secvfy.c'
+ ],
+ 'dependencies': [
+ '<(DEPTH)/exports.gyp:nss_exports'
+ ]
+ }
+ ],
+ 'variables': {
+ 'module': 'nss'
+ }
+} \ No newline at end of file
diff --git a/nss/lib/cryptohi/cryptohi.h b/nss/lib/cryptohi/cryptohi.h
index 6661b66..f658daa 100644
--- a/nss/lib/cryptohi/cryptohi.h
+++ b/nss/lib/cryptohi/cryptohi.h
@@ -17,10 +17,8 @@
#include "keyt.h"
#include "certt.h"
-
SEC_BEGIN_PROTOS
-
/****************************************/
/*
** DER encode/decode (EC)DSA signatures
@@ -39,14 +37,14 @@ extern SECItem *DSAU_DecodeDerSig(const SECItem *item);
* 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
+ * 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 SECStatus DSAU_EncodeDerSigWithLen(SECItem *dest, SECItem *src,
+ unsigned int len);
extern SECItem *DSAU_DecodeDerSigToLen(const SECItem *item, unsigned int len);
/****************************************/
@@ -81,7 +79,7 @@ extern SECStatus SGN_Begin(SGNContext *cx);
** "inputLen" the length of the input data
*/
extern SECStatus SGN_Update(SGNContext *cx, const unsigned char *input,
- unsigned int inputLen);
+ unsigned int inputLen);
/*
** Finish the signature process. Use either k0 or k1 to sign the data
@@ -100,12 +98,12 @@ extern SECStatus SGN_End(SGNContext *cx, SECItem *result);
** "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
+** "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);
+ const unsigned char *buf, int len,
+ SECKEYPrivateKey *pk, SECOidTag algid);
/*
** Sign a pre-digested block of data using private key encryption, encoding
@@ -116,7 +114,7 @@ extern SECStatus SEC_SignData(SECItem *result,
** "algtag" The algorithm tag to encode (need for RSA only)
*/
extern SECStatus SGN_Digest(SECKEYPrivateKey *privKey,
- SECOidTag algtag, SECItem *result, SECItem *digest);
+ SECOidTag algtag, SECItem *result, SECItem *digest);
/*
** DER sign a single block of data using private key encryption and the
@@ -130,8 +128,8 @@ extern SECStatus SGN_Digest(SECKEYPrivateKey *privKey,
** "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);
+ const unsigned char *buf, int len,
+ SECKEYPrivateKey *pk, SECOidTag algid);
/*
** Destroy a signed-data object.
@@ -155,18 +153,18 @@ extern SECOidTag SEC_GetSignatureAlgorithmOidTag(KeyType keyType,
/*
** Create a signature verification context. This version is deprecated,
-** This function is deprecated. Use VFY_CreateContextDirect or
+** 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
+** "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);
+ SECOidTag sigAlg, void *wincx);
/*
** Create a signature verification context.
** "key" the public key to verify with
@@ -174,9 +172,9 @@ extern VFYContext *VFY_CreateContext(SECKEYPublicKey *key, SECItem *sig,
** 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
+** raw algorithm without any hash specified. This must match the key
** type.
-** "hashAlg" specifies the hashing algorithm used. If the key is an
+** "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.
@@ -186,10 +184,10 @@ extern VFYContext *VFY_CreateContext(SECKEYPublicKey *key, SECItem *sig,
** "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);
+ 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
@@ -198,15 +196,15 @@ extern VFYContext *VFY_CreateContextDirect(const SECKEYPublicKey *key,
** 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
+** "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);
+extern VFYContext *VFY_CreateContextWithAlgorithmID(const SECKEYPublicKey *key,
+ const SECItem *sig,
+ const SECAlgorithmID *algid,
+ SECOidTag *hash,
+ void *wincx);
/*
** Destroy a verification-context object.
@@ -226,7 +224,7 @@ extern SECStatus VFY_Begin(VFYContext *cx);
** "inputLen" the amount of input data
*/
extern SECStatus VFY_Update(VFYContext *cx, const unsigned char *input,
- unsigned int inputLen);
+ unsigned int inputLen);
/*
** Finish the verification process. The return value is a status which
@@ -243,19 +241,18 @@ extern SECStatus VFY_End(VFYContext *cx);
** 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.
+** 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
+** This function is deprecated. Use VFY_VerifyDigestDirect or
** VFY_VerifyDigestWithAlgorithmID instead.
** "dig" the digest
** "key" the public key to check the signature with
@@ -265,7 +262,7 @@ extern SECStatus VFY_EndWithSignature(VFYContext *cx, SECItem *sig);
** "wincx" void pointer to the window context
**/
extern SECStatus VFY_VerifyDigest(SECItem *dig, SECKEYPublicKey *key,
- SECItem *sig, SECOidTag sigAlg, void *wincx);
+ 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
@@ -274,15 +271,15 @@ extern SECStatus VFY_VerifyDigest(SECItem *dig, SECKEYPublicKey *key,
** "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
+** 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);
+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
@@ -297,15 +294,15 @@ extern SECStatus VFY_VerifyDigestDirect(const SECItem *dig,
** 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);
+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
+** This function is deprecated. Use VFY_VerifyDataDirect or
** VFY_VerifyDataWithAlgorithmID instead.
** "buf" the input data
** "len" the length of the input data
@@ -316,8 +313,8 @@ extern SECStatus VFY_VerifyDigestWithAlgorithmID(const SECItem *dig,
** "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);
+ 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.
@@ -326,9 +323,9 @@ extern SECStatus VFY_VerifyData(const unsigned char *buf, int len,
** "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
+** raw algorithm without any hash specified. This must match the key
** type.
-** "hashAlg" specifies the hashing algorithm used. If the key is an
+** "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.
@@ -338,10 +335,10 @@ extern SECStatus VFY_VerifyData(const unsigned char *buf, int len,
** "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);
+ 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
@@ -352,16 +349,15 @@ extern SECStatus VFY_VerifyDataDirect(const unsigned char *buf, int len,
** "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
+** "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);
-
+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
diff --git a/nss/lib/cryptohi/cryptoht.h b/nss/lib/cryptohi/cryptoht.h
index aca4899..5780bf4 100644
--- a/nss/lib/cryptohi/cryptoht.h
+++ b/nss/lib/cryptohi/cryptoht.h
@@ -11,5 +11,4 @@
typedef struct SGNContextStr SGNContext;
typedef struct VFYContextStr VFYContext;
-
#endif /* _CRYPTOHT_H_ */
diff --git a/nss/lib/cryptohi/dsautil.c b/nss/lib/cryptohi/dsautil.c
index 5606379..db397df 100644
--- a/nss/lib/cryptohi/dsautil.c
+++ b/nss/lib/cryptohi/dsautil.c
@@ -7,7 +7,7 @@
#include "prerr.h"
#ifndef DSA1_SUBPRIME_LEN
-#define DSA1_SUBPRIME_LEN 20 /* bytes */
+#define DSA1_SUBPRIME_LEN 20 /* bytes */
#endif
typedef struct {
@@ -16,16 +16,16 @@ typedef struct {
} 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, }
-};
+ {
+ { 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.
+** 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.
@@ -37,21 +37,21 @@ DSAU_ConvertUnsignedToSigned(SECItem *dest, SECItem *src)
{
unsigned char *pSrc = src->data;
unsigned char *pDst = dest->data;
- unsigned int cntSrc = src->len;
+ unsigned int cntSrc = src->len;
/* skip any leading zeros. */
- while (cntSrc && !(*pSrc)) {
- pSrc++;
- cntSrc--;
+ while (cntSrc && !(*pSrc)) {
+ pSrc++;
+ cntSrc--;
}
if (!cntSrc) {
- *pDst = 0;
- dest->len = 1;
- return;
+ *pDst = 0;
+ dest->len = 1;
+ return;
}
if (*pSrc & 0x80)
- *pDst++ = 0;
+ *pDst++ = 0;
PORT_Memcpy(pDst, pSrc, cntSrc);
dest->len = (pDst - dest->data) + cntSrc;
@@ -71,27 +71,27 @@ 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;
+ 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;
+ 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;
- }
+ /* 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 );
+ PORT_SetError(PR_INVALID_ARGUMENT_ERROR);
return SECFailure;
}
@@ -101,52 +101,56 @@ loser:
static SECStatus
common_EncodeDerSig(SECItem *dest, SECItem *src)
{
- SECItem * item;
- SECItem srcItem;
+ SECItem *item;
+ SECItem srcItem;
DSA_ASN1Signature sig;
- unsigned char *signedR;
- unsigned char *signedS;
+ 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);
+ 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;
+ 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.
+ ** 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.r.len = sizeof signedR;
sig.s.type = siUnsignedInteger;
sig.s.data = signedS;
- sig.s.len = sizeof signedR;
+ sig.s.len = sizeof signedR;
srcItem.data = src->data;
- srcItem.len = len;
+ 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 (signedR)
+ PORT_Free(signedR);
+ if (signedS)
+ PORT_Free(signedS);
if (item == NULL)
- return SECFailure;
+ return SECFailure;
/* XXX leak item? */
return SECSuccess;
@@ -161,54 +165,54 @@ common_EncodeDerSig(SECItem *dest, SECItem *src)
static SECItem *
common_DecodeDerSig(const SECItem *item, unsigned int len)
{
- SECItem * result = NULL;
- SECStatus status;
+ SECItem *result = NULL;
+ SECStatus status;
DSA_ASN1Signature sig;
- SECItem dst;
+ SECItem dst;
PORT_Memset(&sig, 0, sizeof(sig));
result = PORT_ZNew(SECItem);
if (result == NULL)
- goto loser;
+ goto loser;
- result->len = 2 * len;
- result->data = (unsigned char*)PORT_Alloc(2 * len);
+ result->len = 2 * len;
+ result->data = (unsigned char *)PORT_Alloc(2 * len);
if (result->data == NULL)
- goto loser;
+ goto loser;
sig.r.type = siUnsignedInteger;
sig.s.type = siUnsignedInteger;
status = SEC_ASN1DecodeItem(NULL, &sig, DSA_SignatureTemplate, item);
if (status != SECSuccess)
- goto loser;
+ goto loser;
- /* Convert sig.r and sig.s from variable length signed integers to
+ /* Convert sig.r and sig.s from variable length signed integers to
** fixed length unsigned integers.
*/
dst.data = result->data;
- dst.len = len;
+ dst.len = len;
status = DSAU_ConvertSignedToFixedUnsigned(&dst, &sig.r);
if (status != SECSuccess)
- goto loser;
+ goto loser;
dst.data += len;
status = DSAU_ConvertSignedToFixedUnsigned(&dst, &sig.s);
if (status != SECSuccess)
- goto loser;
+ goto loser;
done:
if (sig.r.data != NULL)
- PORT_Free(sig.r.data);
+ PORT_Free(sig.r.data);
if (sig.s.data != NULL)
- PORT_Free(sig.s.data);
+ PORT_Free(sig.s.data);
return result;
loser:
if (result != NULL) {
- SECITEM_FreeItem(result, PR_TRUE);
- result = NULL;
+ SECITEM_FreeItem(result, PR_TRUE);
+ result = NULL;
}
goto done;
}
@@ -221,8 +225,8 @@ 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;
+ PORT_SetError(PR_INVALID_ARGUMENT_ERROR);
+ return SECFailure;
}
return common_EncodeDerSig(dest, src);
@@ -237,8 +241,8 @@ 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;
+ PORT_SetError(PR_INVALID_ARGUMENT_ERROR);
+ return SECFailure;
}
return common_EncodeDerSig(dest, src);
@@ -263,5 +267,5 @@ DSAU_DecodeDerSig(const SECItem *item)
SECItem *
DSAU_DecodeDerSigToLen(const SECItem *item, unsigned int len)
{
- return common_DecodeDerSig(item, len/2);
+ return common_DecodeDerSig(item, len / 2);
}
diff --git a/nss/lib/cryptohi/exports.gyp b/nss/lib/cryptohi/exports.gyp
new file mode 100644
index 0000000..bb91059
--- /dev/null
+++ b/nss/lib/cryptohi/exports.gyp
@@ -0,0 +1,37 @@
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+{
+ 'includes': [
+ '../../coreconf/config.gypi'
+ ],
+ 'variables': {
+ 'module': 'nss'
+ },
+ 'targets': [
+ {
+ 'target_name': 'lib_cryptohi_exports',
+ 'type': 'none',
+ 'copies': [
+ {
+ 'files': [
+ 'cryptohi.h',
+ 'cryptoht.h',
+ 'key.h',
+ 'keyhi.h',
+ 'keyt.h',
+ 'keythi.h',
+ 'sechash.h'
+ ],
+ 'destination': '<(nss_public_dist_dir)/<(module)'
+ },
+ {
+ 'files': [
+ 'keyi.h',
+ ],
+ 'destination': '<(nss_private_dist_dir)/<(module)'
+ }
+ ]
+ }
+ ],
+}
diff --git a/nss/lib/cryptohi/keyhi.h b/nss/lib/cryptohi/keyhi.h
index 0ed3698..1809900 100644
--- a/nss/lib/cryptohi/keyhi.h
+++ b/nss/lib/cryptohi/keyhi.h
@@ -16,7 +16,6 @@
SEC_BEGIN_PROTOS
-
/*
** Destroy a subject-public-key-info object.
*/
@@ -27,15 +26,15 @@ extern void SECKEY_DestroySubjectPublicKeyInfo(CERTSubjectPublicKeyInfo *spki);
** appropriately (memory is allocated for each of the sub objects).
*/
extern SECStatus SECKEY_CopySubjectPublicKeyInfo(PLArenaPool *arena,
- CERTSubjectPublicKeyInfo *dst,
- CERTSubjectPublicKeyInfo *src);
+ 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);
+SECKEY_UpdateCertPQG(CERTCertificate *subjectCert);
/*
** Return the number of bits in the provided big integer. This assumes that the
@@ -77,19 +76,19 @@ 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);
-
+ SECKEYPublicKey **pubk, void *cx);
+
/*
* create a new DH key pair. The private Key is returned...
*/
SECKEYPrivateKey *SECKEY_CreateDHPrivateKey(SECKEYDHParams *param,
- SECKEYPublicKey **pubk, void *cx);
+ SECKEYPublicKey **pubk, void *cx);
/*
* create a new EC key pair. The private Key is returned...
*/
SECKEYPrivateKey *SECKEY_CreateECPrivateKey(SECKEYECParams *param,
- SECKEYPublicKey **pubk, void *cx);
+ SECKEYPublicKey **pubk, void *cx);
/*
** Create a subject-public-key-info based on a public key.
@@ -103,11 +102,11 @@ SECKEY_CreateSubjectPublicKeyInfo(const SECKEYPublicKey *k);
*/
extern CERTSubjectPublicKeyInfo *
SECKEY_ConvertAndDecodePublicKeyAndChallenge(char *pkacstr, char *challenge,
- void *cx);
+ void *cx);
/*
** Encode a CERTSubjectPublicKeyInfo structure. into a
-** DER encoded subject public key info.
+** DER encoded subject public key info.
*/
SECItem *
SECKEY_EncodeDERSubjectPublicKeyInfo(const SECKEYPublicKey *pubk);
@@ -139,7 +138,6 @@ SECKEY_ExtractPublicKey(const CERTSubjectPublicKeyInfo *);
*/
extern void SECKEY_DestroyPrivateKey(SECKEYPrivateKey *key);
-
/*
** Destroy a public key object.
** "key" the object
@@ -147,54 +145,54 @@ extern void SECKEY_DestroyPrivateKey(SECKEYPrivateKey *key);
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.
+ * 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.
+ * 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.
+ * 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);
+ PRBool freeit);
-/* Copy private key info structure.
+/* 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
+ * 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,
- const SECKEYPrivateKeyInfo *from);
+ SECKEYPrivateKeyInfo *to,
+ const SECKEYPrivateKeyInfo *from);
extern SECStatus
-SECKEY_CacheStaticFlags(SECKEYPrivateKey* key);
+SECKEY_CacheStaticFlags(SECKEYPrivateKey *key);
-/* Copy encrypted private key info structure.
+/* 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
+ * 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,
- const SECKEYEncryptedPrivateKeyInfo *from);
+ SECKEYEncryptedPrivateKeyInfo *to,
+ const SECKEYEncryptedPrivateKeyInfo *from);
/*
* Accessor functions for key type of public and private keys.
*/
@@ -205,10 +203,10 @@ KeyType SECKEY_GetPublicKeyType(const SECKEYPublicKey *pubKey);
* Creates a PublicKey from its DER encoding.
* Currently only supports RSA, DSA, and DH keys.
*/
-SECKEYPublicKey*
+SECKEYPublicKey *
SECKEY_ImportDERPublicKey(const SECItem *derKey, CK_KEY_TYPE type);
-SECKEYPrivateKeyList*
+SECKEYPrivateKeyList *
SECKEY_NewPrivateKeyList(void);
void
@@ -218,14 +216,14 @@ void
SECKEY_RemovePrivateKeyListNode(SECKEYPrivateKeyListNode *node);
SECStatus
-SECKEY_AddPrivateKeyToListTail( SECKEYPrivateKeyList *list,
- SECKEYPrivateKey *key);
+SECKEY_AddPrivateKeyToListTail(SECKEYPrivateKeyList *list,
+ SECKEYPrivateKey *key);
-#define PRIVKEY_LIST_HEAD(l) ((SECKEYPrivateKeyListNode*)PR_LIST_HEAD(&l->list))
+#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))
+#define PRIVKEY_LIST_END(n, l) (((void *)n) == ((void *)&l->list))
-SECKEYPublicKeyList*
+SECKEYPublicKeyList *
SECKEY_NewPublicKeyList(void);
void
@@ -235,12 +233,12 @@ void
SECKEY_RemovePublicKeyListNode(SECKEYPublicKeyListNode *node);
SECStatus
-SECKEY_AddPublicKeyToListTail( SECKEYPublicKeyList *list,
- SECKEYPublicKey *key);
+SECKEY_AddPublicKeyToListTail(SECKEYPublicKeyList *list,
+ SECKEYPublicKey *key);
-#define PUBKEY_LIST_HEAD(l) ((SECKEYPublicKeyListNode*)PR_LIST_HEAD(&l->list))
+#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))
+#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
@@ -266,7 +264,7 @@ extern int SECKEY_ECParamsToBasePointOrderLen(const SECItem *params);
*
* Return 0 on failure (unknown EC domain parameters).
*/
-SECOidTag SECKEY_GetECCOid(const SECKEYECParams * params);
+SECOidTag SECKEY_GetECCOid(const SECKEYECParams *params);
SEC_END_PROTOS
diff --git a/nss/lib/cryptohi/keyi.h b/nss/lib/cryptohi/keyi.h
index 7d0304e..374a4ad 100644
--- a/nss/lib/cryptohi/keyi.h
+++ b/nss/lib/cryptohi/keyi.h
@@ -5,7 +5,6 @@
#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
@@ -16,7 +15,14 @@ KeyType seckey_GetKeyType(SECOidTag pubKeyOid);
* 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);
+ const SECItem *param, SECOidTag *encalg, SECOidTag *hashalg);
+
+/*
+ * Set the point encoding of a SECKEYPublicKey from the OID.
+ * This has to be called on any SECKEYPublicKey holding a SECKEYECPublicKey
+ * before it can be used. The encoding is used to dermine the public key size.
+ */
+SECStatus seckey_SetPointEncoding(PLArenaPool *arena, SECKEYPublicKey *pubKey);
SEC_END_PROTOS
diff --git a/nss/lib/cryptohi/keythi.h b/nss/lib/cryptohi/keythi.h
index 9b9a278..1555ce2 100644
--- a/nss/lib/cryptohi/keythi.h
+++ b/nss/lib/cryptohi/keythi.h
@@ -4,6 +4,7 @@
#ifndef _KEYTHI_H_
#define _KEYTHI_H_ 1
+#include "eccutil.h"
#include "plarena.h"
#include "pkcs11t.h"
#include "secmodt.h"
@@ -21,14 +22,14 @@
**
** 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,
+typedef enum {
+ nullKey = 0,
+ rsaKey = 1,
+ dsaKey = 2,
fortezzaKey = 3, /* deprecated */
- dhKey = 4,
+ dhKey = 4,
keaKey = 5, /* deprecated */
ecKey = 6,
rsaPssKey = 7,
@@ -54,20 +55,19 @@ 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
+** member names from PKCS#1, section 7.1
*/
struct SECKEYRSAPublicKeyStr {
- PLArenaPool * arena;
+ PLArenaPool *arena;
SECItem modulus;
SECItem publicExponent;
};
typedef struct SECKEYRSAPublicKeyStr SECKEYRSAPublicKey;
-/*
+/*
** RSA-PSS parameters
*/
struct SECKEYRSAPSSParamsStr {
@@ -97,20 +97,19 @@ struct SECKEYDSAPublicKeyStr {
};
typedef struct SECKEYDSAPublicKeyStr SECKEYDSAPublicKey;
-
/*
** Diffie-Hellman Public Key structure
** Structure member names suggested by PKCS#3.
*/
struct SECKEYDHParamsStr {
- PLArenaPool * arena;
+ PLArenaPool *arena;
SECItem prime; /* p */
- SECItem base; /* g */
+ SECItem base; /* g */
};
typedef struct SECKEYDHParamsStr SECKEYDHParams;
struct SECKEYDHPublicKeyStr {
- PLArenaPool * arena;
+ PLArenaPool *arena;
SECItem prime;
SECItem base;
SECItem publicValue;
@@ -126,14 +125,9 @@ 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.
- */
+ int size; /* size in bits */
+ SECItem publicValue; /* encoded point */
+ ECPointEncoding encoding;
};
typedef struct SECKEYECPublicKeyStr SECKEYECPublicKey;
@@ -141,9 +135,9 @@ typedef struct SECKEYECPublicKeyStr SECKEYECPublicKey;
** FORTEZZA Public Key structures
*/
struct SECKEYFortezzaPublicKeyStr {
- int KEAversion;
- int DSSversion;
- unsigned char KMID[8];
+ int KEAversion;
+ int DSSversion;
+ unsigned char KMID[8];
SECItem clearance;
SECItem KEApriviledge;
SECItem DSSpriviledge;
@@ -173,7 +167,7 @@ struct SECKEYKEAParamsStr {
SECItem hash;
};
typedef struct SECKEYKEAParamsStr SECKEYKEAParams;
-
+
struct SECKEYKEAPublicKeyStr {
SECKEYKEAParams params;
SECItem publicValue;
@@ -190,48 +184,44 @@ struct SECKEYPublicKeyStr {
CK_OBJECT_HANDLE pkcs11ID;
union {
SECKEYRSAPublicKey rsa;
- SECKEYDSAPublicKey dsa;
- SECKEYDHPublicKey dh;
+ SECKEYDSAPublicKey dsa;
+ SECKEYDHPublicKey dh;
SECKEYKEAPublicKey kea;
SECKEYFortezzaPublicKey fortezza;
- SECKEYECPublicKey ec;
+ 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 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))
+ (0 != (key->staticflags & SECKEY_Attributes_Cached))
-#define SECKEY_ATTRIBUTE_VALUE(key,attribute) \
- (0 != (key->staticflags & SECKEY_##attribute))
+#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(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)
+#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 */
+ 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;
@@ -255,4 +245,3 @@ typedef struct {
PLArenaPool *arena;
} SECKEYPublicKeyList;
#endif /* _KEYTHI_H_ */
-
diff --git a/nss/lib/cryptohi/manifest.mn b/nss/lib/cryptohi/manifest.mn
index 2050b15..896c7ad 100644
--- a/nss/lib/cryptohi/manifest.mn
+++ b/nss/lib/cryptohi/manifest.mn
@@ -6,6 +6,8 @@ CORE_DEPTH = ../..
MODULE = nss
+REQUIRES = nssutil
+
LIBRARY_NAME = cryptohi
EXPORTS = \
@@ -19,6 +21,7 @@ EXPORTS = \
$(NULL)
PRIVATE_EXPORTS = \
+ keyi.h \
$(NULL)
CSRCS = \
diff --git a/nss/lib/cryptohi/sechash.c b/nss/lib/cryptohi/sechash.c
index b9476c4..b126211 100644
--- a/nss/lib/cryptohi/sechash.c
+++ b/nss/lib/cryptohi/sechash.c
@@ -5,7 +5,7 @@
#include "secoidt.h"
#include "secerr.h"
#include "blapi.h"
-#include "pk11func.h" /* for the PK11_ calls below. */
+#include "pk11func.h" /* for the PK11_ calls below. */
static void *
null_hash_new_context(void)
@@ -32,7 +32,7 @@ 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)
+ unsigned int maxOut)
{
*outLen = 0;
}
@@ -43,134 +43,132 @@ null_hash_destroy_context(void *v, PRBool b)
PORT_Assert(v == NULL);
}
-
static void *
-md2_NewContext(void) {
- return (void *) PK11_CreateDigestContext(SEC_OID_MD2);
+md2_NewContext(void)
+{
+ return (void *)PK11_CreateDigestContext(SEC_OID_MD2);
}
static void *
-md5_NewContext(void) {
- return (void *) PK11_CreateDigestContext(SEC_OID_MD5);
+md5_NewContext(void)
+{
+ return (void *)PK11_CreateDigestContext(SEC_OID_MD5);
}
static void *
-sha1_NewContext(void) {
- return (void *) PK11_CreateDigestContext(SEC_OID_SHA1);
+sha1_NewContext(void)
+{
+ return (void *)PK11_CreateDigestContext(SEC_OID_SHA1);
}
static void *
-sha224_NewContext(void) {
- return (void *) PK11_CreateDigestContext(SEC_OID_SHA224);
+sha224_NewContext(void)
+{
+ return (void *)PK11_CreateDigestContext(SEC_OID_SHA224);
}
static void *
-sha256_NewContext(void) {
- return (void *) PK11_CreateDigestContext(SEC_OID_SHA256);
+sha256_NewContext(void)
+{
+ return (void *)PK11_CreateDigestContext(SEC_OID_SHA256);
}
static void *
-sha384_NewContext(void) {
- return (void *) PK11_CreateDigestContext(SEC_OID_SHA384);
+sha384_NewContext(void)
+{
+ return (void *)PK11_CreateDigestContext(SEC_OID_SHA384);
}
static void *
-sha512_NewContext(void) {
- return (void *) PK11_CreateDigestContext(SEC_OID_SHA512);
+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
- },
+ { 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 *
+const SECHashObject *
HASH_GetHashObject(HASH_HashType type)
{
return &SECHashObjects[type];
@@ -179,19 +177,34 @@ HASH_GetHashObject(HASH_HashType 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;
+ 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;
}
@@ -201,17 +214,28 @@ 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;
+ 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;
}
@@ -221,25 +245,36 @@ 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;
+ 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 *
+const SECHashObject *
HASH_GetHashObjectByOidTag(SECOidTag hashOid)
{
- HASH_HashType ht = HASH_GetHashTypeByOidTag(hashOid);
+ HASH_HashType ht = HASH_GetHashTypeByOidTag(hashOid);
return (ht == HASH_AlgNULL) ? NULL : &SECHashObjects[ht];
}
@@ -248,11 +283,11 @@ HASH_GetHashObjectByOidTag(SECOidTag hashOid)
unsigned int
HASH_ResultLenByOidTag(SECOidTag hashOid)
{
- const SECHashObject * hashObject = HASH_GetHashObjectByOidTag(hashOid);
- unsigned int resultLen = 0;
+ const SECHashObject *hashObject = HASH_GetHashObjectByOidTag(hashOid);
+ unsigned int resultLen = 0;
if (hashObject)
- resultLen = hashObject->length;
+ resultLen = hashObject->length;
return resultLen;
}
@@ -260,45 +295,43 @@ HASH_ResultLenByOidTag(SECOidTag hashOid)
unsigned int
HASH_ResultLen(HASH_HashType type)
{
- if ( ( type < HASH_AlgNULL ) || ( type >= HASH_AlgTOTAL ) ) {
- PORT_SetError(SEC_ERROR_INVALID_ALGORITHM);
- return(0);
+ if ((type < HASH_AlgNULL) || (type >= HASH_AlgTOTAL)) {
+ PORT_SetError(SEC_ERROR_INVALID_ALGORITHM);
+ return (0);
}
-
- return(SECHashObjects[type].length);
+
+ return (SECHashObjects[type].length);
}
unsigned int
HASH_ResultLenContext(HASHContext *context)
{
- return(context->hashobj->length);
+ return (context->hashobj->length);
}
-
-
SECStatus
HASH_HashBuf(HASH_HashType type,
- unsigned char *dest,
- const unsigned char *src,
- PRUint32 src_len)
+ unsigned char *dest,
+ const unsigned char *src,
+ PRUint32 src_len)
{
HASHContext *cx;
unsigned int part;
-
- if ( ( type < HASH_AlgNULL ) || ( type >= HASH_AlgTOTAL ) ) {
- return(SECFailure);
+
+ if ((type < HASH_AlgNULL) || (type >= HASH_AlgTOTAL)) {
+ return (SECFailure);
}
-
+
cx = HASH_Create(type);
- if ( cx == NULL ) {
- return(SECFailure);
+ 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);
+ return (SECSuccess);
}
HASHContext *
@@ -306,104 +339,100 @@ HASH_Create(HASH_HashType type)
{
void *hash_context = NULL;
HASHContext *ret = NULL;
-
- if ( ( type < HASH_AlgNULL ) || ( type >= HASH_AlgTOTAL ) ) {
- return(NULL);
+
+ if ((type < HASH_AlgNULL) || (type >= HASH_AlgTOTAL)) {
+ return (NULL);
}
-
- hash_context = (* SECHashObjects[type].create)();
- if ( hash_context == NULL ) {
- goto loser;
+
+ hash_context = (*SECHashObjects[type].create)();
+ if (hash_context == NULL) {
+ goto loser;
}
ret = (HASHContext *)PORT_Alloc(sizeof(HASHContext));
- if ( ret == NULL ) {
- goto loser;
+ if (ret == NULL) {
+ goto loser;
}
ret->hash_context = hash_context;
ret->hashobj = &SECHashObjects[type];
-
- return(ret);
-
+
+ return (ret);
+
loser:
- if ( hash_context != NULL ) {
- (* SECHashObjects[type].destroy)(hash_context, PR_TRUE);
+ if (hash_context != NULL) {
+ (*SECHashObjects[type].destroy)(hash_context, PR_TRUE);
}
-
- return(NULL);
-}
+ 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;
+
+ 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;
+ if (ret == NULL) {
+ goto loser;
}
ret->hash_context = hash_context;
ret->hashobj = context->hashobj;
-
- return(ret);
-
+
+ return (ret);
+
loser:
- if ( hash_context != NULL ) {
- (* context->hashobj->destroy)(hash_context, PR_TRUE);
+ if (hash_context != NULL) {
+ (*context->hashobj->destroy)(hash_context, PR_TRUE);
}
-
- return(NULL);
+ return (NULL);
}
void
HASH_Destroy(HASHContext *context)
{
- (* context->hashobj->destroy)(context->hash_context, PR_TRUE);
+ (*context->hashobj->destroy)(context->hash_context, PR_TRUE);
PORT_Free(context);
return;
}
-
void
HASH_Begin(HASHContext *context)
{
- (* context->hashobj->begin)(context->hash_context);
+ (*context->hashobj->begin)(context->hash_context);
return;
}
-
void
HASH_Update(HASHContext *context,
- const unsigned char *src,
- unsigned int len)
+ const unsigned char *src,
+ unsigned int len)
{
- (* context->hashobj->update)(context->hash_context, src, 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)
+ unsigned char *result,
+ unsigned int *result_len,
+ unsigned int max_result_len)
{
- (* context->hashobj->end)(context->hash_context, result, result_len,
- 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);
+ return (context->hashobj->type);
}
diff --git a/nss/lib/cryptohi/sechash.h b/nss/lib/cryptohi/sechash.h
index 5c58551..94ff7ed 100644
--- a/nss/lib/cryptohi/sechash.h
+++ b/nss/lib/cryptohi/sechash.h
@@ -12,42 +12,42 @@
SEC_BEGIN_PROTOS
/*
-** Generic hash api.
+** Generic hash api.
*/
-extern unsigned int HASH_ResultLen(HASH_HashType type);
+extern unsigned int HASH_ResultLen(HASH_HashType type);
-extern unsigned int HASH_ResultLenContext(HASHContext *context);
+extern unsigned int HASH_ResultLenContext(HASHContext *context);
-extern unsigned int HASH_ResultLenByOidTag(SECOidTag hashOid);
+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 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_Create(HASH_HashType type);
-extern HASHContext * HASH_Clone(HASHContext *context);
+extern HASHContext *HASH_Clone(HASHContext *context);
-extern void HASH_Destroy(HASHContext *context);
+extern void HASH_Destroy(HASHContext *context);
-extern void HASH_Begin(HASHContext *context);
+extern void HASH_Begin(HASHContext *context);
-extern void HASH_Update(HASHContext *context,
- const unsigned char *src,
- unsigned int len);
+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 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_GetHashObject(HASH_HashType type);
-extern const SECHashObject * HASH_GetHashObjectByOidTag(SECOidTag hashOid);
+extern const SECHashObject *HASH_GetHashObjectByOidTag(SECOidTag hashOid);
extern HASH_HashType HASH_GetHashTypeByOidTag(SECOidTag hashOid);
extern SECOidTag HASH_GetHashOidTagByHMACOidTag(SECOidTag hmacOid);
diff --git a/nss/lib/cryptohi/seckey.c b/nss/lib/cryptohi/seckey.c
index 1fcd408..1f053e5 100644
--- a/nss/lib/cryptohi/seckey.c
+++ b/nss/lib/cryptohi/seckey.c
@@ -20,28 +20,28 @@ SEC_ASN1_MKSUB(SEC_IntegerTemplate)
const SEC_ASN1Template CERT_SubjectPublicKeyInfoTemplate[] = {
{ SEC_ASN1_SEQUENCE,
- 0, NULL, sizeof(CERTSubjectPublicKeyInfo) },
+ 0, NULL, sizeof(CERTSubjectPublicKeyInfo) },
{ SEC_ASN1_INLINE | SEC_ASN1_XTRN,
- offsetof(CERTSubjectPublicKeyInfo,algorithm),
- SEC_ASN1_SUB(SECOID_AlgorithmIDTemplate) },
+ offsetof(CERTSubjectPublicKeyInfo, algorithm),
+ SEC_ASN1_SUB(SECOID_AlgorithmIDTemplate) },
{ SEC_ASN1_BIT_STRING,
- offsetof(CERTSubjectPublicKeyInfo,subjectPublicKey), },
- { 0, }
+ 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 }
-};
+ {
+ { 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, }
+ { SEC_ASN1_INTEGER, offsetof(SECKEYPublicKey, u.rsa.modulus) },
+ { SEC_ASN1_INTEGER, offsetof(SECKEYPublicKey, u.rsa.publicExponent) },
+ { 0 }
};
static const SEC_ASN1Template seckey_PointerToAlgorithmIDTemplate[] = {
@@ -51,52 +51,52 @@ static const SEC_ASN1Template seckey_PointerToAlgorithmIDTemplate[] = {
/* 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 }
-};
+ {
+ { 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, }
+ { 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, }
+ { 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, }
+ { 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), },
+ { 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, }
+ { 0 }
};
SEC_ASN1_CHOOSER_IMPLEMENT(SECKEY_DSAPublicKeyTemplate)
@@ -142,33 +142,33 @@ prepare_dh_pub_key_for_asn1(SECKEYPublicKey *pubk)
}
/* Create an RSA key pair is any slot able to do so.
-** The created keys are "session" (temporary), not "token" (permanent),
+** 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)
+SECKEY_CreateRSAPrivateKey(int keySizeInBits, SECKEYPublicKey **pubk, void *cx)
{
SECKEYPrivateKey *privk;
PK11RSAGenParams param;
- PK11SlotInfo *slot = PK11_GetBestSlot(CKM_RSA_PKCS_KEY_PAIR_GEN,cx);
+ PK11SlotInfo *slot = PK11_GetBestSlot(CKM_RSA_PKCS_KEY_PAIR_GEN, cx);
if (!slot) {
- return NULL;
+ 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);
+
+ privk = PK11_GenerateKeyPair(slot, CKM_RSA_PKCS_KEY_PAIR_GEN, &param, pubk,
+ PR_FALSE, PR_TRUE, cx);
PK11_FreeSlot(slot);
- return(privk);
+ return (privk);
}
-/* Create a DH key pair in any slot able to do so,
-** This is a "session" (temporary), not "token" (permanent) key.
+/* 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
+** to create this key pair without the "sensitive" attribute, but revert to
** creating a "sensitive" key if necessary.
*/
SECKEYPrivateKey *
@@ -180,72 +180,77 @@ SECKEY_CreateDHPrivateKey(SECKEYDHParams *param, SECKEYPublicKey **pubk, void *c
if (!param || !param->base.data || !param->prime.data ||
SECKEY_BigIntegerBitLength(&param->prime) < DH_MIN_P_BITS ||
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;
+ (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);
+ slot = PK11_GetBestSlot(CKM_DH_PKCS_KEY_PAIR_GEN, cx);
if (!slot) {
- return NULL;
+ return NULL;
}
- privk = PK11_GenerateKeyPair(slot, CKM_DH_PKCS_KEY_PAIR_GEN, param,
+ 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);
+ if (!privk)
+ privk = PK11_GenerateKeyPair(slot, CKM_DH_PKCS_KEY_PAIR_GEN, param,
+ pubk, PR_FALSE, PR_TRUE, cx);
PK11_FreeSlot(slot);
- return(privk);
+ return (privk);
}
-/* Create an EC key pair in any slot able to do so,
-** This is a "session" (temporary), not "token" (permanent) key.
+/* 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
+** 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);
+ PK11SlotInfo *slot = PK11_GetBestSlot(CKM_EC_KEY_PAIR_GEN, cx);
if (!slot) {
- return NULL;
+ 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);
+ 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);
+ 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);
- }
+ 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);
+ }
}
}
@@ -253,39 +258,39 @@ 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);
- }
+ 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(PLArenaPool *arena,
- CERTSubjectPublicKeyInfo *to,
- CERTSubjectPublicKeyInfo *from)
+ 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;
- }
+ /*
+ * 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;
@@ -301,55 +306,53 @@ SECKEY_CopySubjectPublicKeyInfo(PLArenaPool *arena,
* pqg parameters that has a parent that is not a DSA cert. */
static SECStatus
-seckey_UpdateCertPQGChain(CERTCertificate * subjectCert, int count)
+seckey_UpdateCertPQGChain(CERTCertificate *subjectCert, int count)
{
SECStatus rv;
- SECOidData *oid=NULL;
+ SECOidData *oid = NULL;
int tag;
- CERTSubjectPublicKeyInfo * subjectSpki=NULL;
- CERTSubjectPublicKeyInfo * issuerSpki=NULL;
+ 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;
+ return SECFailure;
}
- oid = SECOID_FindOID(&subjectCert->subjectPublicKeyInfo.algorithm.algorithm);
- if (oid != NULL) {
+ 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) ) {
-
+ *
+ * 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 */
+ return SECFailure; /* return failure if oid is NULL */
}
/* if cert has PQG parameters, return success */
- subjectSpki=&subjectCert->subjectPublicKeyInfo;
+ subjectSpki = &subjectCert->subjectPublicKeyInfo;
if (subjectSpki->algorithm.parameters.len != 0) {
return SECSuccess;
@@ -357,42 +360,41 @@ seckey_UpdateCertPQGChain(CERTCertificate * subjectCert, int count)
/* check if the cert is self-signed */
if (subjectCert->isRoot) {
- /* fail since cert is self-signed and has no pqg params. */
- return SECFailure;
+ /* 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 (!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) {
+ 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) ) {
+ 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 */
+ 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. */
@@ -405,9 +407,9 @@ seckey_UpdateCertPQGChain(CERTCertificate * subjectCert, int count)
/* ensure issuer has pqg parameters */
- issuerSpki=&issuerCert->subjectPublicKeyInfo;
+ issuerSpki = &issuerCert->subjectPublicKeyInfo;
if (issuerSpki->algorithm.parameters.len == 0) {
- rv = SECFailure;
+ rv = SECFailure;
}
/* if update was successful and pqg params present, then copy the
@@ -415,8 +417,8 @@ seckey_UpdateCertPQGChain(CERTCertificate * subjectCert, int count)
if (rv == SECSuccess) {
rv = SECITEM_CopyItem(subjectCert->arena,
- &subjectSpki->algorithm.parameters,
- &issuerSpki->algorithm.parameters);
+ &subjectSpki->algorithm.parameters,
+ &issuerSpki->algorithm.parameters);
}
loser:
@@ -424,35 +426,35 @@ loser:
CERT_DestroyCertificate(issuerCert);
}
return rv;
-
}
-
SECStatus
-SECKEY_UpdateCertPQG(CERTCertificate * subjectCert)
+SECKEY_UpdateCertPQG(CERTCertificate *subjectCert)
{
if (!subjectCert) {
PORT_SetError(SEC_ERROR_INVALID_ARGS);
- return SECFailure;
+ return SECFailure;
}
- return seckey_UpdateCertPQGChain(subjectCert,0);
+ 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. */
+ * a V3 certificate data structure. */
static SECStatus
seckey_DSADecodePQG(PLArenaPool *arena, SECKEYPublicKey *pubk,
- const SECItem *params) {
+ const SECItem *params)
+{
SECStatus rv;
SECItem newparams;
- if (params == NULL) return SECFailure;
-
- if (params->data == NULL) return SECFailure;
+ if (params == NULL)
+ return SECFailure;
+
+ if (params->data == NULL)
+ return SECFailure;
PORT_Assert(arena);
@@ -467,13 +469,13 @@ seckey_DSADecodePQG(PLArenaPool *arena, SECKEYPublicKey *pubk,
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);
+ /* 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 {
@@ -486,61 +488,61 @@ seckey_DSADecodePQG(PLArenaPool *arena, SECKEYPublicKey *pubk,
return rv;
}
-
/* Function used to make an oid tag to a key type */
-KeyType
-seckey_GetKeyType (SECOidTag tag) {
+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;
+ 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 (const CERTSubjectPublicKeyInfo *spki)
+KeyType
+CERT_GetCertKeyType(const CERTSubjectPublicKeyInfo *spki)
{
return seckey_GetKeyType(SECOID_GetAlgorithmTag(&spki->algorithm));
}
@@ -554,95 +556,104 @@ seckey_ExtractPublicKey(const CERTSubjectPublicKeyInfo *spki)
PLArenaPool *arena;
SECOidTag tag;
- arena = PORT_NewArena (DER_DEFAULT_CHUNKSIZE);
+ arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
if (arena == NULL)
- return NULL;
+ return NULL;
- pubk = (SECKEYPublicKey *) PORT_ArenaZAlloc(arena, sizeof(SECKEYPublicKey));
+ pubk = (SECKEYPublicKey *)PORT_ArenaZAlloc(arena, sizeof(SECKEYPublicKey));
if (pubk == NULL) {
- PORT_FreeArena (arena, PR_FALSE);
- return 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);
+ 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;
- }
+ if (rv == SECSuccess)
+ switch (tag) {
+ case SEC_OID_X500_RSA_ENCRYPTION:
+ case SEC_OID_PKCS1_RSA_ENCRYPTION:
+ case SEC_OID_PKCS1_RSA_PSS_SIGNATURE:
+ 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) {
+ break;
+ }
+ rv = seckey_SetPointEncoding(arena, pubk);
+ if (rv == SECSuccess) {
+ return pubk;
+ }
+ break;
+
+ default:
+ PORT_SetError(SEC_ERROR_UNSUPPORTED_KEYALG);
+ break;
+ }
- SECKEY_DestroyPublicKey (pubk);
+ SECKEY_DestroyPublicKey(pubk);
return NULL;
}
-
/* required for JSS */
SECKEYPublicKey *
SECKEY_ExtractPublicKey(const CERTSubjectPublicKeyInfo *spki)
@@ -653,15 +664,6 @@ SECKEY_ExtractPublicKey(const CERTSubjectPublicKeyInfo *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);
}
@@ -669,128 +671,131 @@ int
SECKEY_ECParamsToKeySize(const SECItem *encodedParams)
{
SECOidTag tag;
- SECItem oid = { siBuffer, NULL, 0};
-
+ 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;
+ 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;
+ 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;
+
+ case SEC_OID_CURVE25519:
+ return 255;
+
+ default:
+ PORT_SetError(SEC_ERROR_UNSUPPORTED_ELLIPTIC_CURVE);
+ return 0;
}
}
@@ -798,146 +803,149 @@ int
SECKEY_ECParamsToBasePointOrderLen(const SECItem *encodedParams)
{
SECOidTag tag;
- SECItem oid = { siBuffer, NULL, 0};
-
+ 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;
+ 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;
+ 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;
+
+ case SEC_OID_CURVE25519:
+ return 255;
+
+ default:
+ PORT_SetError(SEC_ERROR_UNSUPPORTED_ELLIPTIC_CURVE);
+ return 0;
}
}
@@ -994,21 +1002,21 @@ SECKEY_PublicKeyStrengthInBits(const SECKEYPublicKey *pubk)
/* interpret modulus length as key strength */
switch (pubk->keyType) {
- case rsaKey:
- bitSize = SECKEY_BigIntegerBitLength(&pubk->u.rsa.modulus);
- break;
- case dsaKey:
- bitSize = SECKEY_BigIntegerBitLength(&pubk->u.dsa.publicValue);
- break;
- case dhKey:
- bitSize = SECKEY_BigIntegerBitLength(&pubk->u.dh.publicValue);
- break;
- case ecKey:
- bitSize = SECKEY_ECParamsToKeySize(&pubk->u.ec.DEREncodedParams);
- break;
- default:
- PORT_SetError(SEC_ERROR_INVALID_KEY);
- break;
+ case rsaKey:
+ bitSize = SECKEY_BigIntegerBitLength(&pubk->u.rsa.modulus);
+ break;
+ case dsaKey:
+ bitSize = SECKEY_BigIntegerBitLength(&pubk->u.dsa.params.prime);
+ break;
+ case dhKey:
+ bitSize = SECKEY_BigIntegerBitLength(&pubk->u.dh.prime);
+ break;
+ case ecKey:
+ bitSize = SECKEY_ECParamsToKeySize(&pubk->u.ec.DEREncodedParams);
+ break;
+ default:
+ PORT_SetError(SEC_ERROR_INVALID_KEY);
+ break;
}
return bitSize;
}
@@ -1021,18 +1029,18 @@ SECKEY_SignatureLen(const SECKEYPublicKey *pubk)
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;
+ 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;
@@ -1043,44 +1051,45 @@ SECKEY_CopyPrivateKey(const SECKEYPrivateKey *privk)
{
SECKEYPrivateKey *copyk;
PLArenaPool *arena;
-
+
if (!privk || !privk->pkcs11Slot) {
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- return NULL;
+ PORT_SetError(SEC_ERROR_INVALID_ARGS);
+ return NULL;
}
-
+
arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
if (arena == NULL) {
- return NULL;
+ return NULL;
}
- copyk = (SECKEYPrivateKey *) PORT_ArenaZAlloc (arena, sizeof (SECKEYPrivateKey));
+ 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;
+ 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);
+ PORT_SetError(SEC_ERROR_NO_MEMORY);
}
fail:
- PORT_FreeArena (arena, PR_FALSE);
+ PORT_FreeArena(arena, PR_FALSE);
return NULL;
}
@@ -1093,82 +1102,93 @@ SECKEY_CopyPublicKey(const SECKEYPublicKey *pubk)
arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
if (arena == NULL) {
- PORT_SetError (SEC_ERROR_NO_MEMORY);
- return NULL;
+ PORT_SetError(SEC_ERROR_NO_MEMORY);
+ return NULL;
}
- copyk = (SECKEYPublicKey *) PORT_ArenaZAlloc (arena, sizeof (SECKEYPublicKey));
+ copyk = (SECKEYPublicKey *)PORT_ArenaZAlloc(arena, sizeof(SECKEYPublicKey));
if (!copyk) {
- PORT_FreeArena (arena, PR_FALSE);
- PORT_SetError (SEC_ERROR_NO_MEMORY);
+ 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)) {
+ 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->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;
+ 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 = seckey_SetPointEncoding(arena, copyk);
+ if (rv != SECSuccess) {
+ break;
+ }
+ PORT_Assert(copyk->u.ec.encoding == pubk->u.ec.encoding);
+ 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);
+ SECKEY_DestroyPublicKey(copyk);
return NULL;
}
-
SECKEYPublicKey *
SECKEY_ConvertToPublicKey(SECKEYPrivateKey *privk)
{
@@ -1182,49 +1202,51 @@ SECKEY_ConvertToPublicKey(SECKEYPrivateKey *privk)
*/
cert = PK11_GetCertFromPrivateKey(privk);
if (cert) {
- pubk = CERT_ExtractPublicKey(cert);
- CERT_DestroyCertificate(cert);
- return pubk;
+ 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);
+ arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
if (arena == NULL) {
- PORT_SetError (SEC_ERROR_NO_MEMORY);
- return NULL;
+ PORT_SetError(SEC_ERROR_NO_MEMORY);
+ return NULL;
}
pubk = (SECKEYPublicKey *)PORT_ArenaZAlloc(arena,
- sizeof (SECKEYPublicKey));
+ sizeof(SECKEYPublicKey));
if (pubk == NULL) {
- PORT_FreeArena(arena,PR_FALSE);
- return 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);
+ 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;
}
@@ -1237,105 +1259,107 @@ seckey_CreateSubjectPublicKeyInfo_helper(SECKEYPublicKey *pubk)
arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
if (arena == NULL) {
- PORT_SetError(SEC_ERROR_NO_MEMORY);
- return NULL;
+ PORT_SetError(SEC_ERROR_NO_MEMORY);
+ return NULL;
}
- spki = (CERTSubjectPublicKeyInfo *) PORT_ArenaZAlloc(arena, sizeof (*spki));
+ 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;
- }
+ 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_SetError(SEC_ERROR_NO_MEMORY);
}
PORT_FreeArena(arena, PR_FALSE);
@@ -1366,25 +1390,25 @@ void
SECKEY_DestroySubjectPublicKeyInfo(CERTSubjectPublicKeyInfo *spki)
{
if (spki && spki->arena) {
- PORT_FreeArena(spki->arena, PR_FALSE);
+ PORT_FreeArena(spki->arena, PR_FALSE);
}
}
SECItem *
SECKEY_EncodeDERSubjectPublicKeyInfo(const SECKEYPublicKey *pubk)
{
- CERTSubjectPublicKeyInfo *spki=NULL;
- SECItem *spkiDER=NULL;
+ CERTSubjectPublicKeyInfo *spki = NULL;
+ SECItem *spkiDER = NULL;
/* get the subjectpublickeyinfo */
spki = SECKEY_CreateSubjectPublicKeyInfo(pubk);
- if( spki == NULL ) {
- goto finish;
+ if (spki == NULL) {
+ goto finish;
}
/* DER-encode the subjectpublickeyinfo */
- spkiDER = SEC_ASN1EncodeItem(NULL /*arena*/, NULL/*dest*/, spki,
- CERT_SubjectPublicKeyInfoTemplate);
+ spkiDER = SEC_ASN1EncodeItem(NULL /*arena*/, NULL /*dest*/, spki,
+ CERT_SubjectPublicKeyInfoTemplate);
SECKEY_DestroySubjectPublicKeyInfo(spki);
@@ -1392,7 +1416,6 @@ finish:
return spkiDER;
}
-
CERTSubjectPublicKeyInfo *
SECKEY_DecodeDERSubjectPublicKeyInfo(const SECItem *spkider)
{
@@ -1403,26 +1426,26 @@ SECKEY_DecodeDERSubjectPublicKeyInfo(const SECItem *spkider)
arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
if (arena == NULL) {
- PORT_SetError(SEC_ERROR_NO_MEMORY);
- return NULL;
+ PORT_SetError(SEC_ERROR_NO_MEMORY);
+ return NULL;
}
spki = (CERTSubjectPublicKeyInfo *)
- PORT_ArenaZAlloc(arena, sizeof (CERTSubjectPublicKeyInfo));
+ PORT_ArenaZAlloc(arena, sizeof(CERTSubjectPublicKeyInfo));
if (spki != NULL) {
- spki->arena = arena;
+ 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) {
+ rv = SEC_QuickDERDecodeItem(arena, spki,
+ CERT_SubjectPublicKeyInfoTemplate, &newSpkider);
}
- if (rv == SECSuccess)
- return spki;
+ if (rv == SECSuccess)
+ return spki;
} else {
- PORT_SetError(SEC_ERROR_NO_MEMORY);
+ PORT_SetError(SEC_ERROR_NO_MEMORY);
}
PORT_FreeArena(arena, PR_FALSE);
@@ -1441,7 +1464,7 @@ SECKEY_ConvertAndDecodeSubjectPublicKeyInfo(const char *spkistr)
rv = ATOB_ConvertAsciiToItem(&der, spkistr);
if (rv != SECSuccess)
- return NULL;
+ return NULL;
spki = SECKEY_DecodeDERSubjectPublicKeyInfo(&der);
@@ -1455,7 +1478,7 @@ SECKEY_ConvertAndDecodeSubjectPublicKeyInfo(const char *spkistr)
*/
CERTSubjectPublicKeyInfo *
SECKEY_ConvertAndDecodePublicKeyAndChallenge(char *pkacstr, char *challenge,
- void *wincx)
+ void *wincx)
{
CERTSubjectPublicKeyInfo *spki = NULL;
CERTPublicKeyAndChallenge pkac;
@@ -1466,171 +1489,171 @@ SECKEY_ConvertAndDecodePublicKeyAndChallenge(char *pkacstr, char *challenge,
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;
+ goto loser;
}
/* create an arena */
arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
if (arena == NULL) {
- goto loser;
+ 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;
+ 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;
+ 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;
+ if (spki == NULL) {
+ goto loser;
}
-
+
/* get the public key */
pubKey = seckey_ExtractPublicKey(spki);
- if ( pubKey == NULL ) {
- goto loser;
+ 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;
+ &(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;
- }
+ 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);
+ if (spki) {
+ SECKEY_DestroySubjectPublicKeyInfo(spki);
}
spki = NULL;
-
+
done:
- if ( signedItem.data ) {
- PORT_Free(signedItem.data);
+ if (signedItem.data) {
+ PORT_Free(signedItem.data);
}
- if ( arena ) {
- PORT_FreeArena(arena, PR_FALSE);
+ if (arena) {
+ PORT_FreeArena(arena, PR_FALSE);
}
- if ( pubKey ) {
- SECKEY_DestroyPublicKey(pubKey);
+ if (pubKey) {
+ SECKEY_DestroyPublicKey(pubKey);
}
-
+
return spki;
}
void
SECKEY_DestroyPrivateKeyInfo(SECKEYPrivateKeyInfo *pvk,
- PRBool freeit)
+ PRBool freeit)
{
PLArenaPool *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(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(pvk, 0, sizeof(*pvk));
- if(freeit == PR_TRUE) {
- PORT_Free(pvk);
- }
- }
+ 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(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(pvk, 0, sizeof(*pvk));
+ if (freeit == PR_TRUE) {
+ PORT_Free(pvk);
+ }
+ }
}
}
void
SECKEY_DestroyEncryptedPrivateKeyInfo(SECKEYEncryptedPrivateKeyInfo *epki,
- PRBool freeit)
+ PRBool freeit)
{
PLArenaPool *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(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(epki, 0, sizeof(*epki));
- if(freeit == PR_TRUE) {
- PORT_Free(epki);
- }
- }
+ 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(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(epki, 0, sizeof(*epki));
+ if (freeit == PR_TRUE) {
+ PORT_Free(epki);
+ }
+ }
}
}
SECStatus
SECKEY_CopyPrivateKeyInfo(PLArenaPool *poolp,
- SECKEYPrivateKeyInfo *to,
- const SECKEYPrivateKeyInfo *from)
+ SECKEYPrivateKeyInfo *to,
+ const SECKEYPrivateKeyInfo *from)
{
SECStatus rv = SECFailure;
- if((to == NULL) || (from == NULL)) {
- return SECFailure;
+ if ((to == NULL) || (from == NULL)) {
+ return SECFailure;
}
rv = SECOID_CopyAlgorithmID(poolp, &to->algorithm, &from->algorithm);
- if(rv != SECSuccess) {
- return SECFailure;
+ if (rv != SECSuccess) {
+ return SECFailure;
}
rv = SECITEM_CopyItem(poolp, &to->privateKey, &from->privateKey);
- if(rv != SECSuccess) {
- return SECFailure;
+ if (rv != SECSuccess) {
+ return SECFailure;
}
rv = SECITEM_CopyItem(poolp, &to->version, &from->version);
@@ -1639,18 +1662,18 @@ SECKEY_CopyPrivateKeyInfo(PLArenaPool *poolp,
SECStatus
SECKEY_CopyEncryptedPrivateKeyInfo(PLArenaPool *poolp,
- SECKEYEncryptedPrivateKeyInfo *to,
- const SECKEYEncryptedPrivateKeyInfo *from)
+ SECKEYEncryptedPrivateKeyInfo *to,
+ const SECKEYEncryptedPrivateKeyInfo *from)
{
SECStatus rv = SECFailure;
- if((to == NULL) || (from == NULL)) {
- return SECFailure;
+ if ((to == NULL) || (from == NULL)) {
+ return SECFailure;
}
rv = SECOID_CopyAlgorithmID(poolp, &to->algorithm, &from->algorithm);
- if(rv != SECSuccess) {
- return SECFailure;
+ if (rv != SECSuccess) {
+ return SECFailure;
}
rv = SECITEM_CopyItem(poolp, &to->encryptedData, &from->encryptedData);
@@ -1660,16 +1683,16 @@ SECKEY_CopyEncryptedPrivateKeyInfo(PLArenaPool *poolp,
KeyType
SECKEY_GetPrivateKeyType(const SECKEYPrivateKey *privKey)
{
- return privKey->keyType;
+ return privKey->keyType;
}
KeyType
SECKEY_GetPublicKeyType(const SECKEYPublicKey *pubKey)
{
- return pubKey->keyType;
+ return pubKey->keyType;
}
-SECKEYPublicKey*
+SECKEYPublicKey *
SECKEY_ImportDERPublicKey(const SECItem *derKey, CK_KEY_TYPE type)
{
SECKEYPublicKey *pubk = NULL;
@@ -1679,11 +1702,11 @@ SECKEY_ImportDERPublicKey(const SECItem *derKey, CK_KEY_TYPE type)
if (!derKey) {
return NULL;
- }
+ }
arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
if (arena == NULL) {
- PORT_SetError(SEC_ERROR_NO_MEMORY);
+ PORT_SetError(SEC_ERROR_NO_MEMORY);
goto finish;
}
@@ -1701,25 +1724,25 @@ SECKEY_ImportDERPublicKey(const SECItem *derKey, CK_KEY_TYPE type)
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;
+ 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:
@@ -1732,20 +1755,20 @@ finish:
return pubk;
}
-SECKEYPrivateKeyList*
+SECKEYPrivateKeyList *
SECKEY_NewPrivateKeyList(void)
{
PLArenaPool *arena = NULL;
SECKEYPrivateKeyList *ret = NULL;
arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
- if ( arena == NULL ) {
+ if (arena == NULL) {
goto loser;
}
ret = (SECKEYPrivateKeyList *)PORT_ArenaZAlloc(arena,
- sizeof(SECKEYPrivateKeyList));
- if ( ret == NULL ) {
+ sizeof(SECKEYPrivateKeyList));
+ if (ret == NULL) {
goto loser;
}
@@ -1753,22 +1776,22 @@ SECKEY_NewPrivateKeyList(void)
PR_INIT_CLIST(&ret->list);
- return(ret);
+ return (ret);
loser:
- if ( arena != NULL ) {
+ if (arena != NULL) {
PORT_FreeArena(arena, PR_FALSE);
}
- return(NULL);
+ return (NULL);
}
void
SECKEY_DestroyPrivateKeyList(SECKEYPrivateKeyList *keys)
{
- while( !PR_CLIST_IS_EMPTY(&keys->list) ) {
+ while (!PR_CLIST_IS_EMPTY(&keys->list)) {
SECKEY_RemovePrivateKeyListNode(
- (SECKEYPrivateKeyListNode*)(PR_LIST_HEAD(&keys->list)) );
+ (SECKEYPrivateKeyListNode *)(PR_LIST_HEAD(&keys->list)));
}
PORT_FreeArena(keys->arena, PR_FALSE);
@@ -1776,7 +1799,6 @@ SECKEY_DestroyPrivateKeyList(SECKEYPrivateKeyList *keys)
return;
}
-
void
SECKEY_RemovePrivateKeyListNode(SECKEYPrivateKeyListNode *node)
{
@@ -1785,44 +1807,42 @@ SECKEY_RemovePrivateKeyListNode(SECKEYPrivateKeyListNode *node)
node->key = NULL;
PR_REMOVE_LINK(&node->links);
return;
-
}
SECStatus
-SECKEY_AddPrivateKeyToListTail( SECKEYPrivateKeyList *list,
- SECKEYPrivateKey *key)
+SECKEY_AddPrivateKeyToListTail(SECKEYPrivateKeyList *list,
+ SECKEYPrivateKey *key)
{
SECKEYPrivateKeyListNode *node;
node = (SECKEYPrivateKeyListNode *)PORT_ArenaZAlloc(list->arena,
- sizeof(SECKEYPrivateKeyListNode));
- if ( node == NULL ) {
+ sizeof(SECKEYPrivateKeyListNode));
+ if (node == NULL) {
goto loser;
}
PR_INSERT_BEFORE(&node->links, &list->list);
node->key = key;
- return(SECSuccess);
+ return (SECSuccess);
loser:
- return(SECFailure);
+ return (SECFailure);
}
-
-SECKEYPublicKeyList*
+SECKEYPublicKeyList *
SECKEY_NewPublicKeyList(void)
{
PLArenaPool *arena = NULL;
SECKEYPublicKeyList *ret = NULL;
arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
- if ( arena == NULL ) {
+ if (arena == NULL) {
goto loser;
}
ret = (SECKEYPublicKeyList *)PORT_ArenaZAlloc(arena,
- sizeof(SECKEYPublicKeyList));
- if ( ret == NULL ) {
+ sizeof(SECKEYPublicKeyList));
+ if (ret == NULL) {
goto loser;
}
@@ -1830,22 +1850,22 @@ SECKEY_NewPublicKeyList(void)
PR_INIT_CLIST(&ret->list);
- return(ret);
+ return (ret);
loser:
- if ( arena != NULL ) {
+ if (arena != NULL) {
PORT_FreeArena(arena, PR_FALSE);
}
- return(NULL);
+ return (NULL);
}
void
SECKEY_DestroyPublicKeyList(SECKEYPublicKeyList *keys)
{
- while( !PR_CLIST_IS_EMPTY(&keys->list) ) {
+ while (!PR_CLIST_IS_EMPTY(&keys->list)) {
SECKEY_RemovePublicKeyListNode(
- (SECKEYPublicKeyListNode*)(PR_LIST_HEAD(&keys->list)) );
+ (SECKEYPublicKeyListNode *)(PR_LIST_HEAD(&keys->list)));
}
PORT_FreeArena(keys->arena, PR_FALSE);
@@ -1853,7 +1873,6 @@ SECKEY_DestroyPublicKeyList(SECKEYPublicKeyList *keys)
return;
}
-
void
SECKEY_RemovePublicKeyListNode(SECKEYPublicKeyListNode *node)
{
@@ -1862,38 +1881,37 @@ SECKEY_RemovePublicKeyListNode(SECKEYPublicKeyListNode *node)
node->key = NULL;
PR_REMOVE_LINK(&node->links);
return;
-
}
SECStatus
-SECKEY_AddPublicKeyToListTail( SECKEYPublicKeyList *list,
- SECKEYPublicKey *key)
+SECKEY_AddPublicKeyToListTail(SECKEYPublicKeyList *list,
+ SECKEYPublicKey *key)
{
SECKEYPublicKeyListNode *node;
node = (SECKEYPublicKeyListNode *)PORT_ArenaZAlloc(list->arena,
- sizeof(SECKEYPublicKeyListNode));
- if ( node == NULL ) {
+ sizeof(SECKEYPublicKeyListNode));
+ if (node == NULL) {
goto loser;
}
PR_INSERT_BEFORE(&node->links, &list->list);
node->key = key;
- return(SECSuccess);
+ return (SECSuccess);
loser:
- return(SECFailure);
+ return (SECFailure);
}
-#define SECKEY_CacheAttribute(key, attribute) \
+#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); \
+ key->staticflags |= SECKEY_##attribute; \
+ } else { \
+ key->staticflags &= (~SECKEY_##attribute); \
}
SECStatus
-SECKEY_CacheStaticFlags(SECKEYPrivateKey* key)
+SECKEY_CacheStaticFlags(SECKEYPrivateKey *key)
{
SECStatus rv = SECFailure;
if (key && key->pkcs11Slot && key->pkcs11ID) {
@@ -1906,20 +1924,58 @@ SECKEY_CacheStaticFlags(SECKEYPrivateKey* key)
}
SECOidTag
-SECKEY_GetECCOid(const SECKEYECParams * params)
+SECKEY_GetECCOid(const SECKEYECParams *params)
{
- SECItem oid = { siBuffer, NULL, 0};
+ SECItem oid = { siBuffer, NULL, 0 };
SECOidData *oidData = NULL;
- /*
+ /*
* 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 0;
+ if (params->data[0] != SEC_ASN1_OBJECT_ID)
+ return 0;
oid.len = params->len - 2;
oid.data = params->data + 2;
- if ((oidData = SECOID_FindOID(&oid)) == NULL) return 0;
+ if ((oidData = SECOID_FindOID(&oid)) == NULL)
+ return 0;
return oidData->offset;
}
+
+/* Set curve encoding in SECKEYECPublicKey in pubKey from OID.
+ * If the encoding is not set, determining the key size of EC public keys will
+ * fail.
+ */
+SECStatus
+seckey_SetPointEncoding(PLArenaPool *arena, SECKEYPublicKey *pubKey)
+{
+ SECItem oid;
+ SECOidTag tag;
+ SECStatus rv;
+
+ /* decode the OID tag */
+ rv = SEC_QuickDERDecodeItem(arena, &oid, SEC_ASN1_GET(SEC_ObjectIDTemplate),
+ &pubKey->u.ec.DEREncodedParams);
+ if (rv != SECSuccess) {
+ return SECFailure;
+ }
+
+ tag = SECOID_FindOIDTag(&oid);
+ switch (tag) {
+ case SEC_OID_CURVE25519:
+ pubKey->u.ec.encoding = ECPoint_XOnly;
+ break;
+ case SEC_OID_SECG_EC_SECP256R1:
+ /* fall through */
+ case SEC_OID_SECG_EC_SECP384R1:
+ /* fall through */
+ case SEC_OID_SECG_EC_SECP521R1:
+ /* fall through */
+ default:
+ /* unknown curve, default to uncompressed */
+ pubKey->u.ec.encoding = ECPoint_Uncompressed;
+ }
+ return SECSuccess;
+}
diff --git a/nss/lib/cryptohi/secsign.c b/nss/lib/cryptohi/secsign.c
index fa4bf5f..1bbdd53 100644
--- a/nss/lib/cryptohi/secsign.c
+++ b/nss/lib/cryptohi/secsign.c
@@ -40,25 +40,25 @@ SGN_NewContext(SECOidTag alg, SECKEYPrivateKey *key)
* it may just support CKM_SHA1_RSA_PKCS and/or CKM_MD5_RSA_PKCS.
*/
/* we have a private key, not a public key, so don't pass it in */
- rv = sec_DecodeSigAlg(NULL, alg, NULL, &signalg, &hashalg);
+ rv = sec_DecodeSigAlg(NULL, alg, NULL, &signalg, &hashalg);
if (rv != SECSuccess) {
- PORT_SetError(SEC_ERROR_INVALID_ALGORITHM);
- return 0;
+ 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;
+ !((key->keyType == dsaKey) && (keyType == fortezzaKey))) {
+ PORT_SetError(SEC_ERROR_INVALID_ALGORITHM);
+ return 0;
}
- cx = (SGNContext*) PORT_ZAlloc(sizeof(SGNContext));
+ cx = (SGNContext *)PORT_ZAlloc(sizeof(SGNContext));
if (cx) {
- cx->hashalg = hashalg;
- cx->signalg = signalg;
- cx->key = key;
+ cx->hashalg = hashalg;
+ cx->signalg = signalg;
+ cx->key = key;
}
return cx;
}
@@ -67,13 +67,13 @@ 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));
- }
+ if (cx->hashcx != NULL) {
+ (*cx->hashobj->destroy)(cx->hashcx, PR_TRUE);
+ cx->hashcx = NULL;
+ }
+ if (freeit) {
+ PORT_ZFree(cx, sizeof(SGNContext));
+ }
}
}
@@ -81,17 +81,17 @@ SECStatus
SGN_Begin(SGNContext *cx)
{
if (cx->hashcx != NULL) {
- (*cx->hashobj->destroy)(cx->hashcx, PR_TRUE);
- 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 */
+ return SECFailure; /* error code is already set */
cx->hashcx = (*cx->hashobj->create)();
if (cx->hashcx == NULL)
- return SECFailure;
+ return SECFailure;
(*cx->hashobj->begin)(cx->hashcx);
return SECSuccess;
@@ -101,8 +101,8 @@ SECStatus
SGN_Update(SGNContext *cx, const unsigned char *input, unsigned int inputLen)
{
if (cx->hashcx == NULL) {
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- return SECFailure;
+ PORT_SetError(SEC_ERROR_INVALID_ARGS);
+ return SECFailure;
}
(*cx->hashobj->update)(cx->hashcx, input, inputLen);
return SECSuccess;
@@ -111,12 +111,12 @@ SGN_Update(SGNContext *cx, const unsigned char *input, unsigned int inputLen)
/* XXX Old template; want to expunge it eventually. */
static DERTemplate SECAlgorithmIDTemplate[] = {
{ DER_SEQUENCE,
- 0, NULL, sizeof(SECAlgorithmID) },
+ 0, NULL, sizeof(SECAlgorithmID) },
{ DER_OBJECT_ID,
- offsetof(SECAlgorithmID,algorithm), },
+ offsetof(SECAlgorithmID, algorithm) },
{ DER_OPTIONAL | DER_ANY,
- offsetof(SECAlgorithmID,parameters), },
- { 0, }
+ offsetof(SECAlgorithmID, parameters) },
+ { 0 }
};
/*
@@ -125,13 +125,13 @@ static DERTemplate SECAlgorithmIDTemplate[] = {
*/
static DERTemplate SGNDigestInfoTemplate[] = {
{ DER_SEQUENCE,
- 0, NULL, sizeof(SGNDigestInfo) },
+ 0, NULL, sizeof(SGNDigestInfo) },
{ DER_INLINE,
- offsetof(SGNDigestInfo,digestAlgorithm),
- SECAlgorithmIDTemplate, },
+ offsetof(SGNDigestInfo, digestAlgorithm),
+ SECAlgorithmIDTemplate },
{ DER_OCTET_STRING,
- offsetof(SGNDigestInfo,digest), },
- { 0, }
+ offsetof(SGNDigestInfo, digest) },
+ { 0 }
};
SECStatus
@@ -151,36 +151,35 @@ SGN_End(SGNContext *cx, SECItem *result)
/* Finish up digest function */
if (cx->hashcx == NULL) {
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- return SECFailure;
+ 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 */
+ 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;
- }
+ if (rv != SECSuccess) {
+ goto loser;
+ }
} else {
- digder.data = digest;
- digder.len = part1;
+ digder.data = digest;
+ digder.len = part1;
}
/*
@@ -189,41 +188,41 @@ SGN_End(SGNContext *cx, SECItem *result)
*/
signatureLen = PK11_SignatureLen(privKey);
if (signatureLen <= 0) {
- PORT_SetError(SEC_ERROR_INVALID_KEY);
- rv = SECFailure;
- goto loser;
+ PORT_SetError(SEC_ERROR_INVALID_KEY);
+ rv = SECFailure;
+ goto loser;
}
sigitem.len = signatureLen;
- sigitem.data = (unsigned char*) PORT_Alloc(signatureLen);
+ sigitem.data = (unsigned char *)PORT_Alloc(signatureLen);
if (sigitem.data == NULL) {
- rv = SECFailure;
- goto loser;
+ rv = SECFailure;
+ goto loser;
}
rv = PK11_Sign(privKey, &sigitem, &digder);
if (rv != SECSuccess) {
- PORT_Free(sigitem.data);
- sigitem.data = NULL;
- goto loser;
+ 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;
+ 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;
+ result->len = sigitem.len;
+ result->data = sigitem.data;
}
- loser:
+loser:
SGN_DestroyDigestInfo(di);
if (arena != NULL) {
- PORT_FreeArena(arena, PR_FALSE);
+ PORT_FreeArena(arena, PR_FALSE);
}
return rv;
}
@@ -236,71 +235,69 @@ SGN_End(SGNContext *cx, SECItem *result)
*/
SECStatus
SEC_SignData(SECItem *res, const unsigned char *buf, int len,
- SECKEYPrivateKey *pk, SECOidTag algid)
+ SECKEYPrivateKey *pk, SECOidTag algid)
{
SECStatus rv;
SGNContext *sgn;
-
sgn = SGN_NewContext(algid, pk);
if (sgn == NULL)
- return SECFailure;
+ return SECFailure;
rv = SGN_Begin(sgn);
if (rv != SECSuccess)
- goto loser;
+ goto loser;
rv = SGN_Update(sgn, buf, len);
if (rv != SECSuccess)
- goto loser;
+ goto loser;
rv = SGN_End(sgn, res);
- loser:
+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, }
-};
+ {
+ { 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_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(PLArenaPool *arena, SECItem *result,
- const unsigned char *buf, int len, SECKEYPrivateKey *pk,
- SECOidTag algID)
+ const unsigned char *buf, int len, SECKEYPrivateKey *pk,
+ SECOidTag algID)
{
SECItem it;
CERTSignedData sd;
@@ -313,58 +310,60 @@ SEC_DerSignData(PLArenaPool *arena, SECItem *result,
*/
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;
- }
+ 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;
+ if (rv)
+ goto loser;
/* Fill out SignedData object */
PORT_Memset(&sd, 0, sizeof(sd));
- sd.data.data = (unsigned char*) buf;
+ 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 */
+ sd.signature.len = it.len << 3; /* convert to bit string */
rv = SECOID_SetAlgorithmID(arena, &sd.signatureAlgorithm, algID, 0);
- if (rv) goto loser;
+ if (rv)
+ goto loser;
/* DER encode the signed data object */
rv = DER_Encode(arena, result, CERTSignedDataTemplate, &sd);
- /* FALL THROUGH */
+/* FALL THROUGH */
- loser:
+loser:
PORT_Free(it.data);
return rv;
}
SECStatus
SGN_Digest(SECKEYPrivateKey *privKey,
- SECOidTag algtag, SECItem *result, SECItem *digest)
+ SECOidTag algtag, SECItem *result, SECItem *digest)
{
int modulusLen;
SECStatus rv;
@@ -372,33 +371,32 @@ SGN_Digest(SECKEYPrivateKey *privKey,
PLArenaPool *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 */
+ 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;
- }
+ if (rv != SECSuccess) {
+ goto loser;
+ }
} else {
- digder.data = digest->data;
- digder.len = digest->len;
+ digder.data = digest->data;
+ digder.len = digest->len;
}
/*
@@ -407,29 +405,29 @@ SGN_Digest(SECKEYPrivateKey *privKey,
*/
modulusLen = PK11_SignatureLen(privKey);
if (modulusLen <= 0) {
- PORT_SetError(SEC_ERROR_INVALID_KEY);
- rv = SECFailure;
- goto loser;
+ PORT_SetError(SEC_ERROR_INVALID_KEY);
+ rv = SECFailure;
+ goto loser;
}
result->len = modulusLen;
- result->data = (unsigned char*) PORT_Alloc(modulusLen);
+ result->data = (unsigned char *)PORT_Alloc(modulusLen);
result->type = siBuffer;
if (result->data == NULL) {
- rv = SECFailure;
- goto loser;
+ rv = SECFailure;
+ goto loser;
}
rv = PK11_Sign(privKey, result, &digder);
if (rv != SECSuccess) {
- PORT_Free(result->data);
- result->data = NULL;
+ PORT_Free(result->data);
+ result->data = NULL;
}
- loser:
+loser:
SGN_DestroyDigestInfo(di);
if (arena != NULL) {
- PORT_FreeArena(arena, PR_FALSE);
+ PORT_FreeArena(arena, PR_FALSE);
}
return rv;
}
@@ -440,58 +438,73 @@ 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_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_UNKNOWN: /* default for RSA if not specified */
- 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;
+ 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_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_UNKNOWN: /* default for RSA if not specified */
+ 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/nss/lib/cryptohi/secvfy.c b/nss/lib/cryptohi/secvfy.c
index c869167..2ac21ab 100644
--- a/nss/lib/cryptohi/secvfy.c
+++ b/nss/lib/cryptohi/secvfy.c
@@ -35,13 +35,13 @@
*/
static SECStatus
recoverPKCS1DigestInfo(SECOidTag givenDigestAlg,
- /*out*/ SECOidTag* digestAlgOut,
- /*out*/ unsigned char** digestInfo,
- /*out*/ unsigned int* digestInfoLen,
- SECKEYPublicKey* key,
- const SECItem* sig, void* wincx)
+ /*out*/ SECOidTag *digestAlgOut,
+ /*out*/ unsigned char **digestInfo,
+ /*out*/ unsigned int *digestInfoLen,
+ SECKEYPublicKey *key,
+ const SECItem *sig, void *wincx)
{
- SGNDigestInfo* di = NULL;
+ SGNDigestInfo *di = NULL;
SECItem it;
PRBool rv = SECSuccess;
@@ -53,11 +53,11 @@ recoverPKCS1DigestInfo(SECOidTag givenDigestAlg,
PORT_Assert(sig);
it.data = NULL;
- it.len = SECKEY_PublicKeyStrength(key);
+ it.len = SECKEY_PublicKeyStrength(key);
if (it.len != 0) {
it.data = (unsigned char *)PORT_Alloc(it.len);
}
- if (it.len == 0 || it.data == NULL ) {
+ if (it.len == 0 || it.data == NULL) {
rv = SECFailure;
}
@@ -65,7 +65,7 @@ recoverPKCS1DigestInfo(SECOidTag givenDigestAlg,
/* decrypt the block */
rv = PK11_VerifyRecover(key, sig, &it, wincx);
}
-
+
if (rv == SECSuccess) {
if (givenDigestAlg != SEC_OID_UNKNOWN) {
/* We don't need to parse the DigestInfo if the caller gave us the
@@ -74,7 +74,7 @@ recoverPKCS1DigestInfo(SECOidTag givenDigestAlg,
* that the DigestInfo is encoded absolutely correctly.
*/
*digestInfoLen = it.len;
- *digestInfo = (unsigned char*)it.data;
+ *digestInfo = (unsigned char *)it.data;
*digestAlgOut = givenDigestAlg;
return SECSuccess;
}
@@ -104,7 +104,7 @@ recoverPKCS1DigestInfo(SECOidTag givenDigestAlg,
if (rv == SECSuccess) {
*digestInfoLen = it.len;
- *digestInfo = (unsigned char*)it.data;
+ *digestInfo = (unsigned char *)it.data;
} else {
if (it.data) {
PORT_Free(it.data);
@@ -118,7 +118,7 @@ recoverPKCS1DigestInfo(SECOidTag givenDigestAlg,
}
struct VFYContextStr {
- SECOidTag hashAlg; /* the hash algorithm */
+ SECOidTag hashAlg; /* the hash algorithm */
SECKEYPublicKey *key;
/*
* This buffer holds either the digest or the full signature
@@ -130,35 +130,35 @@ struct VFYContextStr {
* the size of the union or some other union member instead.
*/
union {
- unsigned char buffer[1];
+ unsigned char buffer[1];
- /* the full DSA signature... 40 bytes */
- unsigned char dsasig[DSA_MAX_SIGNATURE_LEN];
- /* the full ECDSA signature */
- unsigned char ecdsasig[2 * MAX_ECKEY_LEN];
+ /* 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 pkcs1RSADigestInfoLen;
/* the encoded DigestInfo from a RSA PKCS#1 signature */
unsigned char *pkcs1RSADigestInfo;
- void * wincx;
+ 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. */
+ 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. */
};
static SECStatus
-verifyPKCS1DigestInfo(const VFYContext* cx, const SECItem* digest)
+verifyPKCS1DigestInfo(const VFYContext *cx, const SECItem *digest)
{
- SECItem pkcs1DigestInfo;
- pkcs1DigestInfo.data = cx->pkcs1RSADigestInfo;
- pkcs1DigestInfo.len = cx->pkcs1RSADigestInfoLen;
- return _SGN_VerifyPKCS1DigestInfo(
- cx->hashAlg, digest, &pkcs1DigestInfo,
- PR_TRUE /*XXX: unsafeAllowMissingParameters*/);
+ SECItem pkcs1DigestInfo;
+ pkcs1DigestInfo.data = cx->pkcs1RSADigestInfo;
+ pkcs1DigestInfo.len = cx->pkcs1RSADigestInfoLen;
+ return _SGN_VerifyPKCS1DigestInfo(
+ cx->hashAlg, digest, &pkcs1DigestInfo,
+ PR_TRUE /*XXX: unsafeAllowMissingParameters*/);
}
/*
@@ -168,47 +168,50 @@ verifyPKCS1DigestInfo(const VFYContext* cx, const SECItem* digest)
*/
static SECStatus
decodeECorDSASignature(SECOidTag algid, const SECItem *sig, unsigned char *dsig,
- unsigned int len) {
+ unsigned int len)
+{
SECItem *dsasig = NULL; /* also used for ECDSA */
- SECStatus rv=SECSuccess;
+ SECStatus rv = SECSuccess;
if ((algid != SEC_OID_ANSIX9_DSA_SIGNATURE) &&
- (algid != SEC_OID_ANSIX962_EC_PUBLIC_KEY) ) {
+ (algid != SEC_OID_ANSIX962_EC_PUBLIC_KEY)) {
if (sig->len != len) {
- PORT_SetError(SEC_ERROR_BAD_DER);
- return SECFailure;
- }
+ PORT_SetError(SEC_ERROR_BAD_DER);
+ return SECFailure;
+ }
- PORT_Memcpy(dsig, sig->data, sig->len);
- return SECSuccess;
+ 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;
- }
+ 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;
+ rv = SECFailure;
} else {
- PORT_Memcpy(dsig, dsasig->data, dsasig->len);
+ PORT_Memcpy(dsig, dsasig->data, dsasig->len);
}
- if (dsasig != NULL) SECITEM_FreeItem(dsasig, PR_TRUE);
- if (rv == SECFailure) PORT_SetError(SEC_ERROR_BAD_DER);
+ 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, }
-};
+ {
+ { 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
@@ -222,160 +225,160 @@ const SEC_ASN1Template hashParameterTemplate[] =
* 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)
+sec_DecodeSigAlg(const SECKEYPublicKey *key, SECOidTag sigAlg,
+ const SECItem *param, SECOidTag *encalg, SECOidTag *hashalg)
{
int len;
PLArenaPool *arena;
SECStatus rv;
SECItem oid;
- PR_ASSERT(hashalg!=NULL);
- PR_ASSERT(encalg!=NULL);
+ 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 */
+ /* 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;
+ 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;
}
@@ -388,13 +391,13 @@ sec_DecodeSigAlg(const SECKEYPublicKey *key, SECOidTag sigAlg,
* 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
+ * 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)
+vfy_CreateContext(const SECKEYPublicKey *key, const SECItem *sig,
+ SECOidTag encAlg, SECOidTag hashAlg, SECOidTag *hash, void *wincx)
{
VFYContext *cx;
SECStatus rv;
@@ -405,14 +408,14 @@ vfy_CreateContext(const SECKEYPublicKey *key, const SECItem *sig,
/* 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;
+ ((key->keyType != rsaKey) || (type != rsaPssKey))) {
+ PORT_SetError(SEC_ERROR_PKCS7_KEYALG_MISMATCH);
+ return NULL;
}
- cx = (VFYContext*) PORT_ZAlloc(sizeof(VFYContext));
+ cx = (VFYContext *)PORT_ZAlloc(sizeof(VFYContext));
if (cx == NULL) {
- goto loser;
+ goto loser;
}
cx->wincx = wincx;
@@ -423,81 +426,82 @@ vfy_CreateContext(const SECKEYPublicKey *key, const SECItem *sig,
cx->pkcs1RSADigestInfo = NULL;
rv = SECSuccess;
if (sig) {
- switch (type) {
- case rsaKey:
- rv = recoverPKCS1DigestInfo(hashAlg, &cx->hashAlg,
- &cx->pkcs1RSADigestInfo,
- &cx->pkcs1RSADigestInfoLen,
- cx->key,
- sig, wincx);
- 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;
+ switch (type) {
+ case rsaKey:
+ rv = recoverPKCS1DigestInfo(hashAlg, &cx->hashAlg,
+ &cx->pkcs1RSADigestInfo,
+ &cx->pkcs1RSADigestInfoLen,
+ cx->key,
+ sig, wincx);
+ 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;
+ /* error set by HASH_GetHashTypeByOidTag */
+ goto loser;
}
if (hash) {
- *hash = cx->hashAlg;
+ *hash = cx->hashAlg;
}
return cx;
- loser:
+loser:
if (cx) {
- VFY_DestroyContext(cx, PR_TRUE);
+ VFY_DestroyContext(cx, PR_TRUE);
}
return 0;
}
VFYContext *
VFY_CreateContext(SECKEYPublicKey *key, SECItem *sig, SECOidTag sigAlg,
- void *wincx)
+ void *wincx)
{
SECOidTag encAlg, hashAlg;
SECStatus rv = sec_DecodeSigAlg(key, sigAlg, NULL, &encAlg, &hashAlg);
if (rv != SECSuccess) {
- return NULL;
+ 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)
+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);
+ 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)
+ const SECAlgorithmID *sigAlgorithm, SECOidTag *hash, void *wincx)
{
SECOidTag encAlg, hashAlg;
- SECStatus rv = sec_DecodeSigAlg(key,
- SECOID_GetAlgorithmTag((SECAlgorithmID *)sigAlgorithm),
- &sigAlgorithm->parameters, &encAlg, &hashAlg);
+ SECStatus rv = sec_DecodeSigAlg(key,
+ SECOID_GetAlgorithmTag((SECAlgorithmID *)sigAlgorithm),
+ &sigAlgorithm->parameters, &encAlg, &hashAlg);
if (rv != SECSuccess) {
- return NULL;
+ return NULL;
}
return vfy_CreateContext(key, sig, encAlg, hashAlg, hash, wincx);
}
@@ -506,19 +510,19 @@ 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 (cx->pkcs1RSADigestInfo) {
- PORT_Free(cx->pkcs1RSADigestInfo);
- }
- if (freeit) {
- PORT_ZFree(cx, sizeof(VFYContext));
- }
+ if (cx->hashcx != NULL) {
+ (*cx->hashobj->destroy)(cx->hashcx, PR_TRUE);
+ cx->hashcx = NULL;
+ }
+ if (cx->key) {
+ SECKEY_DestroyPublicKey(cx->key);
+ }
+ if (cx->pkcs1RSADigestInfo) {
+ PORT_Free(cx->pkcs1RSADigestInfo);
+ }
+ if (freeit) {
+ PORT_ZFree(cx, sizeof(VFYContext));
+ }
}
}
@@ -526,17 +530,17 @@ SECStatus
VFY_Begin(VFYContext *cx)
{
if (cx->hashcx != NULL) {
- (*cx->hashobj->destroy)(cx->hashcx, PR_TRUE);
- 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 */
+ if (!cx->hashobj)
+ return SECFailure; /* error code is set */
cx->hashcx = (*cx->hashobj->create)();
if (cx->hashcx == NULL)
- return SECFailure;
+ return SECFailure;
(*cx->hashobj->begin)(cx->hashcx);
return SECSuccess;
@@ -546,8 +550,8 @@ SECStatus
VFY_Update(VFYContext *cx, const unsigned char *input, unsigned inputLen)
{
if (cx->hashcx == NULL) {
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- return SECFailure;
+ PORT_SetError(SEC_ERROR_INVALID_ARGS);
+ return SECFailure;
}
(*cx->hashobj->update)(cx->hashcx, input, inputLen);
return SECSuccess;
@@ -558,65 +562,64 @@ VFY_EndWithSignature(VFYContext *cx, SECItem *sig)
{
unsigned char final[HASH_LENGTH_MAX];
unsigned part;
- SECItem hash,dsasig; /* dsasig is also used for ECDSA */
+ 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;
+ PORT_SetError(SEC_ERROR_INVALID_ARGS);
+ return SECFailure;
}
if (cx->hashcx == NULL) {
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- return SECFailure;
+ 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:
- {
- SECItem digest;
- digest.data = final;
- digest.len = part;
- if (sig) {
- SECOidTag hashid;
- PORT_Assert(cx->hashAlg != SEC_OID_UNKNOWN);
- rv = recoverPKCS1DigestInfo(cx->hashAlg, &hashid,
- &cx->pkcs1RSADigestInfo,
- &cx->pkcs1RSADigestInfoLen,
- cx->key,
- sig, cx->wincx);
- PORT_Assert(cx->hashAlg == hashid);
- if (rv != SECSuccess) {
- return SECFailure;
- }
- }
- return verifyPKCS1DigestInfo(cx, &digest);
- }
- default:
- PORT_SetError(SEC_ERROR_BAD_SIGNATURE);
- return SECFailure; /* shouldn't happen */
+ 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: {
+ SECItem digest;
+ digest.data = final;
+ digest.len = part;
+ if (sig) {
+ SECOidTag hashid;
+ PORT_Assert(cx->hashAlg != SEC_OID_UNKNOWN);
+ rv = recoverPKCS1DigestInfo(cx->hashAlg, &hashid,
+ &cx->pkcs1RSADigestInfo,
+ &cx->pkcs1RSADigestInfoLen,
+ cx->key,
+ sig, cx->wincx);
+ PORT_Assert(cx->hashAlg == hashid);
+ if (rv != SECSuccess) {
+ return SECFailure;
+ }
+ }
+ return verifyPKCS1DigestInfo(cx, &digest);
+ }
+ default:
+ PORT_SetError(SEC_ERROR_BAD_SIGNATURE);
+ return SECFailure; /* shouldn't happen */
}
return SECSuccess;
}
@@ -624,7 +627,7 @@ VFY_EndWithSignature(VFYContext *cx, SECItem *sig)
SECStatus
VFY_End(VFYContext *cx)
{
- return VFY_EndWithSignature(cx,NULL);
+ return VFY_EndWithSignature(cx, NULL);
}
/************************************************************************/
@@ -632,9 +635,9 @@ VFY_End(VFYContext *cx)
* 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)
+vfy_VerifyDigest(const SECItem *digest, const SECKEYPublicKey *key,
+ const SECItem *sig, SECOidTag encAlg, SECOidTag hashAlg,
+ void *wincx)
{
SECStatus rv;
VFYContext *cx;
@@ -644,48 +647,48 @@ vfy_VerifyDigest(const SECItem *digest, const SECKEYPublicKey *key,
cx = vfy_CreateContext(key, sig, encAlg, hashAlg, NULL, wincx);
if (cx != NULL) {
- switch (key->keyType) {
- case rsaKey:
- rv = verifyPKCS1DigestInfo(cx, digest);
- 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);
+ switch (key->keyType) {
+ case rsaKey:
+ rv = verifyPKCS1DigestInfo(cx, digest);
+ 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)
+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 algid, void *wincx)
{
SECOidTag encAlg, hashAlg;
SECStatus rv = sec_DecodeSigAlg(key, algid, NULL, &encAlg, &hashAlg);
if (rv != SECSuccess) {
- return SECFailure;
+ return SECFailure;
}
return vfy_VerifyDigest(digest, key, sig, encAlg, hashAlg, wincx);
}
@@ -695,44 +698,44 @@ VFY_VerifyDigest(SECItem *digest, SECKEYPublicKey *key, SECItem *sig,
* 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)
+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);
+ SECStatus rv = sec_DecodeSigAlg(key,
+ SECOID_GetAlgorithmTag((SECAlgorithmID *)sigAlgorithm),
+ &sigAlgorithm->parameters, &encAlg, &hashAlg);
if (rv != SECSuccess) {
- return rv;
+ return rv;
}
- if ( hashCmp != SEC_OID_UNKNOWN &&
- hashAlg != SEC_OID_UNKNOWN &&
- hashCmp != hashAlg) {
- PORT_SetError(SEC_ERROR_BAD_SIGNATURE);
- return SECFailure;
+ 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)
+ 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;
+ return SECFailure;
rv = VFY_Begin(cx);
if (rv == SECSuccess) {
- rv = VFY_Update(cx, (unsigned char *)buf, len);
- if (rv == SECSuccess)
- rv = VFY_End(cx);
+ rv = VFY_Update(cx, (unsigned char *)buf, len);
+ if (rv == SECSuccess)
+ rv = VFY_End(cx);
}
VFY_DestroyContext(cx, PR_TRUE);
@@ -740,39 +743,39 @@ vfy_VerifyData(const unsigned char *buf, int len, const SECKEYPublicKey *key,
}
SECStatus
-VFY_VerifyDataDirect(const unsigned char *buf, int len,
- const SECKEYPublicKey *key, const SECItem *sig,
- SECOidTag encAlg, SECOidTag hashAlg,
- SECOidTag *hash, void *wincx)
+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)
+ 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 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)
+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);
+ SECStatus rv = sec_DecodeSigAlg(key, sigAlg,
+ &sigAlgorithm->parameters, &encAlg, &hashAlg);
if (rv != SECSuccess) {
- return rv;
+ return rv;
}
return vfy_VerifyData(buf, len, key, sig, encAlg, hashAlg, hash, wincx);
}
diff --git a/nss/lib/dbm/include/exports.gyp b/nss/lib/dbm/include/exports.gyp
new file mode 100644
index 0000000..e80d769
--- /dev/null
+++ b/nss/lib/dbm/include/exports.gyp
@@ -0,0 +1,38 @@
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+{
+ 'includes': [
+ '../../../coreconf/config.gypi'
+ ],
+ 'targets': [
+ {
+ 'target_name': 'lib_dbm_include_exports',
+ 'type': 'none',
+ 'copies': [
+ {
+ 'files': [
+ 'mcom_db.h',
+ 'ncompat.h',
+ 'winfile.h'
+ ],
+ 'destination': '<(nss_public_dist_dir)/<(module)'
+ },
+ {
+ 'files': [
+ 'extern.h',
+ 'hash.h',
+ 'hsearch.h',
+ 'page.h',
+ 'queue.h',
+ 'search.h'
+ ],
+ 'destination': '<(nss_private_dist_dir)/<(module)'
+ }
+ ]
+ }
+ ],
+ 'variables': {
+ 'module': 'dbm'
+ }
+}
diff --git a/nss/lib/dbm/include/extern.h b/nss/lib/dbm/include/extern.h
index cbc9922..897369f 100644
--- a/nss/lib/dbm/include/extern.h
+++ b/nss/lib/dbm/include/extern.h
@@ -1,6 +1,6 @@
/*-
* Copyright (c) 1991, 1993, 1994
- * The Regents of the University of California. All rights reserved.
+ * The Regents of the University of California. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -10,7 +10,7 @@
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
- * 3. ***REMOVED*** - see
+ * 3. ***REMOVED*** - see
* ftp://ftp.cs.berkeley.edu/pub/4bsd/README.Impt.License.Change
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
@@ -28,35 +28,35 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * @(#)extern.h 8.4 (Berkeley) 6/16/94
+ * @(#)extern.h 8.4 (Berkeley) 6/16/94
*/
-BUFHEAD *__add_ovflpage (HTAB *, BUFHEAD *);
-int __addel (HTAB *, BUFHEAD *, const DBT *, const DBT *);
-int __big_delete (HTAB *, BUFHEAD *);
-int __big_insert (HTAB *, BUFHEAD *, const DBT *, const DBT *);
-int __big_keydata (HTAB *, BUFHEAD *, DBT *, DBT *, int);
-int __big_return (HTAB *, BUFHEAD *, int, DBT *, int);
-int __big_split (HTAB *, BUFHEAD *, BUFHEAD *, BUFHEAD *,
- uint32, uint32, SPLIT_RETURN *);
-int __buf_free (HTAB *, int, int);
-void __buf_init (HTAB *, int);
-uint32 __call_hash (HTAB *, char *, size_t);
-int __delpair (HTAB *, BUFHEAD *, int);
-int __expand_table (HTAB *);
-int __find_bigpair (HTAB *, BUFHEAD *, int, char *, int);
-uint16 __find_last_page (HTAB *, BUFHEAD **);
-void __free_ovflpage (HTAB *, BUFHEAD *);
-BUFHEAD *__get_buf (HTAB *, uint32, BUFHEAD *, int);
-int __get_page (HTAB *, char *, uint32, int, int, int);
-int __ibitmap (HTAB *, int, int, int);
-uint32 __log2 (uint32);
-int __put_page (HTAB *, char *, uint32, int, int);
-void __reclaim_buf (HTAB *, BUFHEAD *);
-int __split_page (HTAB *, uint32, uint32);
+BUFHEAD *__add_ovflpage(HTAB *, BUFHEAD *);
+int __addel(HTAB *, BUFHEAD *, const DBT *, const DBT *);
+int __big_delete(HTAB *, BUFHEAD *);
+int __big_insert(HTAB *, BUFHEAD *, const DBT *, const DBT *);
+int __big_keydata(HTAB *, BUFHEAD *, DBT *, DBT *, int);
+int __big_return(HTAB *, BUFHEAD *, int, DBT *, int);
+int __big_split(HTAB *, BUFHEAD *, BUFHEAD *, BUFHEAD *,
+ uint32, uint32, SPLIT_RETURN *);
+int __buf_free(HTAB *, int, int);
+void __buf_init(HTAB *, int);
+uint32 __call_hash(HTAB *, char *, size_t);
+int __delpair(HTAB *, BUFHEAD *, int);
+int __expand_table(HTAB *);
+int __find_bigpair(HTAB *, BUFHEAD *, int, char *, int);
+uint16 __find_last_page(HTAB *, BUFHEAD **);
+void __free_ovflpage(HTAB *, BUFHEAD *);
+BUFHEAD *__get_buf(HTAB *, uint32, BUFHEAD *, int);
+int __get_page(HTAB *, char *, uint32, int, int, int);
+int __ibitmap(HTAB *, int, int, int);
+uint32 __log2(uint32);
+int __put_page(HTAB *, char *, uint32, int, int);
+void __reclaim_buf(HTAB *, BUFHEAD *);
+int __split_page(HTAB *, uint32, uint32);
/* Default hash routine. */
-extern uint32 (*__default_hash) (const void *, size_t);
+extern uint32 (*__default_hash)(const void *, size_t);
#ifdef HASH_STATISTICS
extern int hash_accesses, hash_collisions, hash_expansions, hash_overflows;
diff --git a/nss/lib/dbm/include/hash.h b/nss/lib/dbm/include/hash.h
index 20307b5..7da51dc 100644
--- a/nss/lib/dbm/include/hash.h
+++ b/nss/lib/dbm/include/hash.h
@@ -1,6 +1,6 @@
/*-
* Copyright (c) 1990, 1993, 1994
- * The Regents of the University of California. All rights reserved.
+ * The Regents of the University of California. All rights reserved.
*
* This code is derived from software contributed to Berkeley by
* Margo Seltzer.
@@ -13,7 +13,7 @@
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
- * 3. ***REMOVED*** - see
+ * 3. ***REMOVED*** - see
* ftp://ftp.cs.berkeley.edu/pub/4bsd/README.Impt.License.Change
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
@@ -31,7 +31,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * @(#)hash.h 8.3 (Berkeley) 5/31/94
+ * @(#)hash.h 8.3 (Berkeley) 5/31/94
*/
/* Operations */
@@ -39,134 +39,140 @@
#include <stdio.h>
#include "mcom_db.h"
typedef enum {
- HASH_GET, HASH_PUT, HASH_PUTNEW, HASH_DELETE, HASH_FIRST, HASH_NEXT
+ HASH_GET,
+ HASH_PUT,
+ HASH_PUTNEW,
+ HASH_DELETE,
+ HASH_FIRST,
+ HASH_NEXT
} ACTION;
/* Buffer Management structures */
typedef struct _bufhead BUFHEAD;
struct _bufhead {
- BUFHEAD *prev; /* LRU links */
- BUFHEAD *next; /* LRU links */
- BUFHEAD *ovfl; /* Overflow page buffer header */
- uint32 addr; /* Address of this page */
- char *page; /* Actual page data */
- char is_disk;
- char flags;
-#define BUF_MOD 0x0001
-#define BUF_DISK 0x0002
-#define BUF_BUCKET 0x0004
-#define BUF_PIN 0x0008
+ BUFHEAD *prev; /* LRU links */
+ BUFHEAD *next; /* LRU links */
+ BUFHEAD *ovfl; /* Overflow page buffer header */
+ uint32 addr; /* Address of this page */
+ char *page; /* Actual page data */
+ char is_disk;
+ char flags;
+#define BUF_MOD 0x0001
+#define BUF_DISK 0x0002
+#define BUF_BUCKET 0x0004
+#define BUF_PIN 0x0008
};
-#define IS_BUCKET(X) ((X) & BUF_BUCKET)
+#define IS_BUCKET(X) ((X)&BUF_BUCKET)
typedef BUFHEAD **SEGMENT;
typedef int DBFILE_PTR;
#define NO_FILE -1
#ifdef macintosh
-#define DBFILE_OPEN(path, flag,mode) open((path), flag)
+#define DBFILE_OPEN(path, flag, mode) open((path), flag)
#define EXISTS(path)
#else
-#define DBFILE_OPEN(path, flag,mode) open((path), (flag), (mode))
+#define DBFILE_OPEN(path, flag, mode) open((path), (flag), (mode))
#endif
/* Hash Table Information */
-typedef struct hashhdr { /* Disk resident portion */
- int32 magic; /* Magic NO for hash tables */
- int32 version; /* Version ID */
- uint32 lorder; /* Byte Order */
- int32 bsize; /* Bucket/Page Size */
- int32 bshift; /* Bucket shift */
- int32 dsize; /* Directory Size */
- int32 ssize; /* Segment Size */
- int32 sshift; /* Segment shift */
- int32 ovfl_point; /* Where overflow pages are being
- * allocated */
- int32 last_freed; /* Last overflow page freed */
- int32 max_bucket; /* ID of Maximum bucket in use */
- int32 high_mask; /* Mask to modulo into entire table */
- int32 low_mask; /* Mask to modulo into lower half of
- * table */
- int32 ffactor; /* Fill factor */
- int32 nkeys; /* Number of keys in hash table */
- int32 hdrpages; /* Size of table header */
- uint32 h_charkey; /* value of hash(CHARKEY) */
-#define NCACHED 32 /* number of bit maps and spare
- * points */
- int32 spares[NCACHED];/* spare pages for overflow */
- uint16 bitmaps[NCACHED]; /* address of overflow page
- * bitmaps */
+typedef struct hashhdr { /* Disk resident portion */
+ int32 magic; /* Magic NO for hash tables */
+ int32 version; /* Version ID */
+ uint32 lorder; /* Byte Order */
+ int32 bsize; /* Bucket/Page Size */
+ int32 bshift; /* Bucket shift */
+ int32 dsize; /* Directory Size */
+ int32 ssize; /* Segment Size */
+ int32 sshift; /* Segment shift */
+ int32 ovfl_point; /* Where overflow pages are being
+ * allocated */
+ int32 last_freed; /* Last overflow page freed */
+ int32 max_bucket; /* ID of Maximum bucket in use */
+ int32 high_mask; /* Mask to modulo into entire table */
+ int32 low_mask; /* Mask to modulo into lower half of
+ * table */
+ int32 ffactor; /* Fill factor */
+ int32 nkeys; /* Number of keys in hash table */
+ int32 hdrpages; /* Size of table header */
+ uint32 h_charkey; /* value of hash(CHARKEY) */
+#define NCACHED 32 /* number of bit maps and spare \
+ * points */
+ int32 spares[NCACHED]; /* spare pages for overflow */
+ uint16 bitmaps[NCACHED]; /* address of overflow page
+ * bitmaps */
} HASHHDR;
-typedef struct htab { /* Memory resident data structure */
- HASHHDR hdr; /* Header */
- int nsegs; /* Number of allocated segments */
- int exsegs; /* Number of extra allocated
- * segments */
- uint32 /* Hash function */
- (*hash)(const void *, size_t);
- int flags; /* Flag values */
- DBFILE_PTR fp; /* File pointer */
- char *filename;
- char *tmp_buf; /* Temporary Buffer for BIG data */
- char *tmp_key; /* Temporary Buffer for BIG keys */
- BUFHEAD *cpage; /* Current page */
- int cbucket; /* Current bucket */
- int cndx; /* Index of next item on cpage */
- int dbmerrno; /* Error Number -- for DBM
- * compatability */
- int new_file; /* Indicates if fd is backing store
- * or no */
- int save_file; /* Indicates whether we need to flush
- * file at
- * exit */
- uint32 *mapp[NCACHED]; /* Pointers to page maps */
- int nmaps; /* Initial number of bitmaps */
- int nbufs; /* Number of buffers left to
- * allocate */
- BUFHEAD bufhead; /* Header of buffer lru list */
- SEGMENT *dir; /* Hash Bucket directory */
- off_t file_size; /* in bytes */
- char is_temp; /* unlink file on close */
- char updateEOF; /* force EOF update on flush */
+typedef struct htab { /* Memory resident data structure */
+ HASHHDR hdr; /* Header */
+ int nsegs; /* Number of allocated segments */
+ int exsegs; /* Number of extra allocated
+ * segments */
+ uint32 /* Hash function */
+ (*hash)(const void *, size_t);
+ int flags; /* Flag values */
+ DBFILE_PTR fp; /* File pointer */
+ char *filename;
+ char *tmp_buf; /* Temporary Buffer for BIG data */
+ char *tmp_key; /* Temporary Buffer for BIG keys */
+ BUFHEAD *cpage; /* Current page */
+ int cbucket; /* Current bucket */
+ int cndx; /* Index of next item on cpage */
+ int dbmerrno; /* Error Number -- for DBM
+ * compatability */
+ int new_file; /* Indicates if fd is backing store
+ * or no */
+ int save_file; /* Indicates whether we need to flush
+ * file at
+ * exit */
+ uint32 *mapp[NCACHED]; /* Pointers to page maps */
+ int nmaps; /* Initial number of bitmaps */
+ int nbufs; /* Number of buffers left to
+ * allocate */
+ BUFHEAD bufhead; /* Header of buffer lru list */
+ SEGMENT *dir; /* Hash Bucket directory */
+ off_t file_size; /* in bytes */
+ char is_temp; /* unlink file on close */
+ char updateEOF; /* force EOF update on flush */
} HTAB;
/*
* Constants
*/
-#define DATABASE_CORRUPTED_ERROR -999 /* big ugly abort, delete database */
-#define OLD_MAX_BSIZE 65536 /* 2^16 */
-#define MAX_BSIZE 32l*1024l /* 2^15 */
-#define MIN_BUFFERS 6
-#define MINHDRSIZE 512
-#define DEF_BUFSIZE 65536l /* 64 K */
-#define DEF_BUCKET_SIZE 4096
-#define DEF_BUCKET_SHIFT 12 /* log2(BUCKET) */
-#define DEF_SEGSIZE 256
-#define DEF_SEGSIZE_SHIFT 8 /* log2(SEGSIZE) */
-#define DEF_DIRSIZE 256
-#define DEF_FFACTOR 65536l
-#define MIN_FFACTOR 4
-#define SPLTMAX 8
-#define CHARKEY "%$sniglet^&"
-#define NUMKEY 1038583l
-#define BYTE_SHIFT 3
-#define INT_TO_BYTE 2
-#define INT_BYTE_SHIFT 5
-#define ALL_SET ((uint32)0xFFFFFFFF)
-#define ALL_CLEAR 0
+#define DATABASE_CORRUPTED_ERROR -999 /* big ugly abort, delete database */
+#define OLD_MAX_BSIZE 65536 /* 2^16 */
+#define MAX_BSIZE 32l * 1024l /* 2^15 */
+#define MIN_BUFFERS 6
+#define MINHDRSIZE 512
+#define DEF_BUFSIZE 65536l /* 64 K */
+#define DEF_BUCKET_SIZE 4096
+#define DEF_BUCKET_SHIFT 12 /* log2(BUCKET) */
+#define DEF_SEGSIZE 256
+#define DEF_SEGSIZE_SHIFT 8 /* log2(SEGSIZE) */
+#define DEF_DIRSIZE 256
+#define DEF_FFACTOR 65536l
+#define MIN_FFACTOR 4
+#define SPLTMAX 8
+#define CHARKEY "%$sniglet^&"
+#define NUMKEY 1038583l
+#define BYTE_SHIFT 3
+#define INT_TO_BYTE 2
+#define INT_BYTE_SHIFT 5
+#define ALL_SET ((uint32)0xFFFFFFFF)
+#define ALL_CLEAR 0
-#define PTROF(X) ((ptrdiff_t)(X) == BUF_DISK ? 0 : (X))
-#define ISDISK(X) ((X) ? ((ptrdiff_t)(X) == BUF_DISK ? BUF_DISK \
- : (X)->is_disk) : 0)
+#define PTROF(X) ((ptrdiff_t)(X) == BUF_DISK ? 0 : (X))
+#define ISDISK(X) ((X) ? ((ptrdiff_t)(X) == BUF_DISK ? BUF_DISK \
+ : (X)->is_disk) \
+ : 0)
-#define BITS_PER_MAP 32
+#define BITS_PER_MAP 32
/* Given the address of the beginning of a big map, clear/set the nth bit */
-#define CLRBIT(A, N) ((A)[(N)/BITS_PER_MAP] &= ~(1<<((N)%BITS_PER_MAP)))
-#define SETBIT(A, N) ((A)[(N)/BITS_PER_MAP] |= (1<<((N)%BITS_PER_MAP)))
-#define ISSET(A, N) ((A)[(N)/BITS_PER_MAP] & (1<<((N)%BITS_PER_MAP)))
+#define CLRBIT(A, N) ((A)[(N) / BITS_PER_MAP] &= ~(1 << ((N) % BITS_PER_MAP)))
+#define SETBIT(A, N) ((A)[(N) / BITS_PER_MAP] |= (1 << ((N) % BITS_PER_MAP)))
+#define ISSET(A, N) ((A)[(N) / BITS_PER_MAP] & (1 << ((N) % BITS_PER_MAP)))
/* Overflow management */
/*
@@ -177,16 +183,16 @@ typedef struct htab { /* Memory resident data structure */
* numberered starting with 1).
*/
-#define SPLITSHIFT 11
-#define SPLITMASK 0x7FF
-#define SPLITNUM(N) (((uint32)(N)) >> SPLITSHIFT)
-#define OPAGENUM(N) ((N) & SPLITMASK)
-#define OADDR_OF(S,O) ((uint32)((uint32)(S) << SPLITSHIFT) + (O))
+#define SPLITSHIFT 11
+#define SPLITMASK 0x7FF
+#define SPLITNUM(N) (((uint32)(N)) >> SPLITSHIFT)
+#define OPAGENUM(N) ((N)&SPLITMASK)
+#define OADDR_OF(S, O) ((uint32)((uint32)(S) << SPLITSHIFT) + (O))
#define BUCKET_TO_PAGE(B) \
- (B) + hashp->HDRPAGES + ((B) ? hashp->SPARES[__log2((uint32)((B)+1))-1] : 0)
-#define OADDR_TO_PAGE(B) \
- BUCKET_TO_PAGE ( (1 << SPLITNUM((B))) -1 ) + OPAGENUM((B));
+ (B) + hashp->HDRPAGES + ((B) ? hashp->SPARES[__log2((uint32)((B) + 1)) - 1] : 0)
+#define OADDR_TO_PAGE(B) \
+ BUCKET_TO_PAGE((1 << SPLITNUM((B))) - 1) + OPAGENUM((B));
/*
* page.h contains a detailed description of the page format.
@@ -197,138 +203,138 @@ typedef struct htab { /* Memory resident data structure */
* the following:
*
*
- * OVFLPAGE Rather than a key data pair, this pair contains
- * the address of an overflow page. The format of
- * the pair is:
- * OVERFLOW_PAGE_NUMBER OVFLPAGE
+ * OVFLPAGE Rather than a key data pair, this pair contains
+ * the address of an overflow page. The format of
+ * the pair is:
+ * OVERFLOW_PAGE_NUMBER OVFLPAGE
*
- * PARTIAL_KEY This must be the first key/data pair on a page
- * and implies that page contains only a partial key.
- * That is, the key is too big to fit on a single page
- * so it starts on this page and continues on the next.
- * The format of the page is:
- * KEY_OFF PARTIAL_KEY OVFL_PAGENO OVFLPAGE
- *
- * KEY_OFF -- offset of the beginning of the key
- * PARTIAL_KEY -- 1
- * OVFL_PAGENO - page number of the next overflow page
- * OVFLPAGE -- 0
+ * PARTIAL_KEY This must be the first key/data pair on a page
+ * and implies that page contains only a partial key.
+ * That is, the key is too big to fit on a single page
+ * so it starts on this page and continues on the next.
+ * The format of the page is:
+ * KEY_OFF PARTIAL_KEY OVFL_PAGENO OVFLPAGE
*
- * FULL_KEY This must be the first key/data pair on the page. It
- * is used in two cases.
+ * KEY_OFF -- offset of the beginning of the key
+ * PARTIAL_KEY -- 1
+ * OVFL_PAGENO - page number of the next overflow page
+ * OVFLPAGE -- 0
*
- * Case 1:
- * There is a complete key on the page but no data
- * (because it wouldn't fit). The next page contains
- * the data.
+ * FULL_KEY This must be the first key/data pair on the page. It
+ * is used in two cases.
*
- * Page format it:
- * KEY_OFF FULL_KEY OVFL_PAGENO OVFL_PAGE
+ * Case 1:
+ * There is a complete key on the page but no data
+ * (because it wouldn't fit). The next page contains
+ * the data.
*
- * KEY_OFF -- offset of the beginning of the key
- * FULL_KEY -- 2
- * OVFL_PAGENO - page number of the next overflow page
- * OVFLPAGE -- 0
+ * Page format it:
+ * KEY_OFF FULL_KEY OVFL_PAGENO OVFL_PAGE
*
- * Case 2:
- * This page contains no key, but part of a large
- * data field, which is continued on the next page.
+ * KEY_OFF -- offset of the beginning of the key
+ * FULL_KEY -- 2
+ * OVFL_PAGENO - page number of the next overflow page
+ * OVFLPAGE -- 0
*
- * Page format it:
- * DATA_OFF FULL_KEY OVFL_PAGENO OVFL_PAGE
+ * Case 2:
+ * This page contains no key, but part of a large
+ * data field, which is continued on the next page.
*
- * KEY_OFF -- offset of the beginning of the data on
- * this page
- * FULL_KEY -- 2
- * OVFL_PAGENO - page number of the next overflow page
- * OVFLPAGE -- 0
+ * Page format it:
+ * DATA_OFF FULL_KEY OVFL_PAGENO OVFL_PAGE
*
- * FULL_KEY_DATA
- * This must be the first key/data pair on the page.
- * There are two cases:
+ * KEY_OFF -- offset of the beginning of the data on
+ * this page
+ * FULL_KEY -- 2
+ * OVFL_PAGENO - page number of the next overflow page
+ * OVFLPAGE -- 0
*
- * Case 1:
- * This page contains a key and the beginning of the
- * data field, but the data field is continued on the
- * next page.
+ * FULL_KEY_DATA
+ * This must be the first key/data pair on the page.
+ * There are two cases:
*
- * Page format is:
- * KEY_OFF FULL_KEY_DATA OVFL_PAGENO DATA_OFF
+ * Case 1:
+ * This page contains a key and the beginning of the
+ * data field, but the data field is continued on the
+ * next page.
*
- * KEY_OFF -- offset of the beginning of the key
- * FULL_KEY_DATA -- 3
- * OVFL_PAGENO - page number of the next overflow page
- * DATA_OFF -- offset of the beginning of the data
+ * Page format is:
+ * KEY_OFF FULL_KEY_DATA OVFL_PAGENO DATA_OFF
*
- * Case 2:
- * This page contains the last page of a big data pair.
- * There is no key, only the tail end of the data
- * on this page.
+ * KEY_OFF -- offset of the beginning of the key
+ * FULL_KEY_DATA -- 3
+ * OVFL_PAGENO - page number of the next overflow page
+ * DATA_OFF -- offset of the beginning of the data
*
- * Page format is:
- * DATA_OFF FULL_KEY_DATA <OVFL_PAGENO> <OVFLPAGE>
+ * Case 2:
+ * This page contains the last page of a big data pair.
+ * There is no key, only the tail end of the data
+ * on this page.
*
- * DATA_OFF -- offset of the beginning of the data on
- * this page
- * FULL_KEY_DATA -- 3
- * OVFL_PAGENO - page number of the next overflow page
- * OVFLPAGE -- 0
+ * Page format is:
+ * DATA_OFF FULL_KEY_DATA <OVFL_PAGENO> <OVFLPAGE>
*
- * OVFL_PAGENO and OVFLPAGE are optional (they are
- * not present if there is no next page).
+ * DATA_OFF -- offset of the beginning of the data on
+ * this page
+ * FULL_KEY_DATA -- 3
+ * OVFL_PAGENO - page number of the next overflow page
+ * OVFLPAGE -- 0
+ *
+ * OVFL_PAGENO and OVFLPAGE are optional (they are
+ * not present if there is no next page).
*/
-#define OVFLPAGE 0
-#define PARTIAL_KEY 1
-#define FULL_KEY 2
-#define FULL_KEY_DATA 3
-#define REAL_KEY 4
+#define OVFLPAGE 0
+#define PARTIAL_KEY 1
+#define FULL_KEY 2
+#define FULL_KEY_DATA 3
+#define REAL_KEY 4
/* Short hands for accessing structure */
#undef BSIZE
-#define BSIZE hdr.bsize
+#define BSIZE hdr.bsize
#undef BSHIFT
-#define BSHIFT hdr.bshift
-#define DSIZE hdr.dsize
-#define SGSIZE hdr.ssize
-#define SSHIFT hdr.sshift
-#define LORDER hdr.lorder
-#define OVFL_POINT hdr.ovfl_point
-#define LAST_FREED hdr.last_freed
-#define MAX_BUCKET hdr.max_bucket
-#define FFACTOR hdr.ffactor
-#define HIGH_MASK hdr.high_mask
-#define LOW_MASK hdr.low_mask
-#define NKEYS hdr.nkeys
-#define HDRPAGES hdr.hdrpages
-#define SPARES hdr.spares
-#define BITMAPS hdr.bitmaps
-#define VERSION hdr.version
-#define MAGIC hdr.magic
-#define NEXT_FREE hdr.next_free
-#define H_CHARKEY hdr.h_charkey
+#define BSHIFT hdr.bshift
+#define DSIZE hdr.dsize
+#define SGSIZE hdr.ssize
+#define SSHIFT hdr.sshift
+#define LORDER hdr.lorder
+#define OVFL_POINT hdr.ovfl_point
+#define LAST_FREED hdr.last_freed
+#define MAX_BUCKET hdr.max_bucket
+#define FFACTOR hdr.ffactor
+#define HIGH_MASK hdr.high_mask
+#define LOW_MASK hdr.low_mask
+#define NKEYS hdr.nkeys
+#define HDRPAGES hdr.hdrpages
+#define SPARES hdr.spares
+#define BITMAPS hdr.bitmaps
+#define VERSION hdr.version
+#define MAGIC hdr.magic
+#define NEXT_FREE hdr.next_free
+#define H_CHARKEY hdr.h_charkey
-extern uint32 (*__default_hash) (const void *, size_t);
+extern uint32 (*__default_hash)(const void *, size_t);
void __buf_init(HTAB *hashp, int32 nbytes);
int __big_delete(HTAB *hashp, BUFHEAD *bufp);
-BUFHEAD * __get_buf(HTAB *hashp, uint32 addr, BUFHEAD *prev_bp, int newpage);
+BUFHEAD *__get_buf(HTAB *hashp, uint32 addr, BUFHEAD *prev_bp, int newpage);
uint32 __call_hash(HTAB *hashp, char *k, size_t len);
#include "page.h"
-extern int __big_split(HTAB *hashp, BUFHEAD *op,BUFHEAD *np,
-BUFHEAD *big_keyp,uint32 addr,uint32 obucket, SPLIT_RETURN *ret);
+extern int __big_split(HTAB *hashp, BUFHEAD *op, BUFHEAD *np,
+ BUFHEAD *big_keyp, uint32 addr, uint32 obucket, SPLIT_RETURN *ret);
void __free_ovflpage(HTAB *hashp, BUFHEAD *obufp);
-BUFHEAD * __add_ovflpage(HTAB *hashp, BUFHEAD *bufp);
+BUFHEAD *__add_ovflpage(HTAB *hashp, BUFHEAD *bufp);
int __big_insert(HTAB *hashp, BUFHEAD *bufp, const DBT *key, const DBT *val);
int __expand_table(HTAB *hashp);
uint32 __log2(uint32 num);
void __reclaim_buf(HTAB *hashp, BUFHEAD *bp);
-int __get_page(HTAB *hashp, char * p, uint32 bucket, int is_bucket, int is_disk, int is_bitmap);
+int __get_page(HTAB *hashp, char *p, uint32 bucket, int is_bucket, int is_disk, int is_bitmap);
int __put_page(HTAB *hashp, char *p, uint32 bucket, int is_bucket, int is_bitmap);
int __ibitmap(HTAB *hashp, int pnum, int nbits, int ndx);
int __buf_free(HTAB *hashp, int do_free, int to_disk);
int __find_bigpair(HTAB *hashp, BUFHEAD *bufp, int ndx, char *key, int size);
uint16 __find_last_page(HTAB *hashp, BUFHEAD **bpp);
-int __addel(HTAB *hashp, BUFHEAD *bufp, const DBT *key, const DBT * val);
+int __addel(HTAB *hashp, BUFHEAD *bufp, const DBT *key, const DBT *val);
int __big_return(HTAB *hashp, BUFHEAD *bufp, int ndx, DBT *val, int set_current);
int __delpair(HTAB *hashp, BUFHEAD *bufp, int ndx);
int __big_keydata(HTAB *hashp, BUFHEAD *bufp, DBT *key, DBT *val, int set);
diff --git a/nss/lib/dbm/include/hsearch.h b/nss/lib/dbm/include/hsearch.h
index ae1df1c..d6fe0d9 100644
--- a/nss/lib/dbm/include/hsearch.h
+++ b/nss/lib/dbm/include/hsearch.h
@@ -1,6 +1,6 @@
/*-
* Copyright (c) 1990, 1993
- * The Regents of the University of California. All rights reserved.
+ * The Regents of the University of California. All rights reserved.
*
* This code is derived from software contributed to Berkeley by
* Margo Seltzer.
@@ -13,7 +13,7 @@
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
- * 3. ***REMOVED*** - see
+ * 3. ***REMOVED*** - see
* ftp://ftp.cs.berkeley.edu/pub/4bsd/README.Impt.License.Change
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
@@ -31,19 +31,20 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * @(#)search.h 8.1 (Berkeley) 6/4/93
+ * @(#)search.h 8.1 (Berkeley) 6/4/93
*/
/* Backward compatibility to hsearch interface. */
typedef struct entry {
- char *key;
- char *data;
+ char *key;
+ char *data;
} ENTRY;
typedef enum {
- FIND, ENTER
+ FIND,
+ ENTER
} ACTION;
-int hcreate (unsigned int);
-void hdestroy (void);
-ENTRY *hsearch (ENTRY, ACTION);
+int hcreate(unsigned int);
+void hdestroy(void);
+ENTRY *hsearch(ENTRY, ACTION);
diff --git a/nss/lib/dbm/include/include.gyp b/nss/lib/dbm/include/include.gyp
new file mode 100644
index 0000000..69f9c88
--- /dev/null
+++ b/nss/lib/dbm/include/include.gyp
@@ -0,0 +1,12 @@
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+{
+ 'includes': [
+ '../../../coreconf/config.gypi'
+ ],
+ 'targets': [],
+ 'variables': {
+ 'module': 'dbm'
+ }
+} \ No newline at end of file
diff --git a/nss/lib/dbm/include/mcom_db.h b/nss/lib/dbm/include/mcom_db.h
index 4cca532..0a4f6dc 100644
--- a/nss/lib/dbm/include/mcom_db.h
+++ b/nss/lib/dbm/include/mcom_db.h
@@ -1,7 +1,7 @@
/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/*-
+/*-
* Copyright (c) 1990, 1993, 1994
- * The Regents of the University of California. All rights reserved.
+ * The Regents of the University of California. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -11,7 +11,7 @@
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
- * 3. ***REMOVED*** - see
+ * 3. ***REMOVED*** - see
* ftp://ftp.cs.berkeley.edu/pub/4bsd/README.Impt.License.Change
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
@@ -29,11 +29,11 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * @(#)db.h 8.7 (Berkeley) 6/16/94
+ * @(#)db.h 8.7 (Berkeley) 6/16/94
*/
#ifndef _DB_H_
-#define _DB_H_
+#define _DB_H_
#ifndef macintosh
#include <sys/types.h>
@@ -63,21 +63,21 @@ typedef PRUint32 uint32;
#if defined(__linux) || defined(__BEOS__)
#include <endian.h>
#ifndef BYTE_ORDER
-#define BYTE_ORDER __BYTE_ORDER
-#define BIG_ENDIAN __BIG_ENDIAN
+#define BYTE_ORDER __BYTE_ORDER
+#define BIG_ENDIAN __BIG_ENDIAN
#define LITTLE_ENDIAN __LITTLE_ENDIAN
#endif
#endif /* __linux */
#ifdef __sgi
#define BYTE_ORDER BIG_ENDIAN
-#define BIG_ENDIAN 4321
-#define LITTLE_ENDIAN 1234 /* LSB first: i386, vax, all NT risc */
+#define BIG_ENDIAN 4321
+#define LITTLE_ENDIAN 1234 /* LSB first: i386, vax, all NT risc */
#endif
#ifdef __sun
-#define BIG_ENDIAN 4321
-#define LITTLE_ENDIAN 1234 /* LSB first: i386, vax, all NT risc */
+#define BIG_ENDIAN 4321
+#define LITTLE_ENDIAN 1234 /* LSB first: i386, vax, all NT risc */
#ifndef __SVR4
/* compat.h is only in 4.1.3 machines. - dp */
@@ -112,8 +112,8 @@ typedef PRUint32 uint32;
#if defined(__hpux) || defined(__hppa)
#define BYTE_ORDER BIG_ENDIAN
-#define BIG_ENDIAN 4321
-#define LITTLE_ENDIAN 1234 /* LSB first: i386, vax, all NT risc */
+#define BIG_ENDIAN 4321
+#define LITTLE_ENDIAN 1234 /* LSB first: i386, vax, all NT risc */
#endif
#if defined(AIXV3) || defined(AIX)
@@ -131,8 +131,8 @@ typedef PRUint32 uint32;
#else
/* Alpha NT */
#define BYTE_ORDER LITTLE_ENDIAN
-#define BIG_ENDIAN 4321
-#define LITTLE_ENDIAN 1234
+#define BIG_ENDIAN 4321
+#define LITTLE_ENDIAN 1234
#endif
#endif
@@ -144,17 +144,17 @@ typedef PRUint32 uint32;
#ifdef __QNXNTO__
#include <sys/param.h>
#else
-#define LITTLE_ENDIAN 1234
-#define BIG_ENDIAN 4321
-#define BYTE_ORDER LITTLE_ENDIAN
+#define LITTLE_ENDIAN 1234
+#define BIG_ENDIAN 4321
+#define BYTE_ORDER LITTLE_ENDIAN
#endif
#endif
#ifdef SNI
/* #include <sys/hetero.h> */
#define BYTE_ORDER BIG_ENDIAN
-#define BIG_ENDIAN 4321
-#define LITTLE_ENDIAN 1234
+#define BIG_ENDIAN 4321
+#define LITTLE_ENDIAN 1234
#endif
#ifdef _WINDOWS
@@ -163,8 +163,8 @@ typedef PRUint32 uint32;
#endif
#define BYTE_ORDER LITTLE_ENDIAN
-#define LITTLE_ENDIAN 1234 /* LSB first: i386, vax, all NT risc */
-#define BIG_ENDIAN 4321
+#define LITTLE_ENDIAN 1234 /* LSB first: i386, vax, all NT risc */
+#define BIG_ENDIAN 4321
#endif
#ifdef macintosh
@@ -173,10 +173,10 @@ typedef PRUint32 uint32;
#define BYTE_ORDER BIG_ENDIAN
#endif
-#endif /* __DBINTERFACE_PRIVATE */
+#endif /* __DBINTERFACE_PRIVATE */
#ifdef SCO
-#define MAXPATHLEN 1024
+#define MAXPATHLEN 1024
#endif
#include <fcntl.h>
@@ -185,32 +185,32 @@ typedef PRUint32 uint32;
#include <stdio.h>
#include <io.h>
-#ifndef XP_OS2
-#define MAXPATHLEN 1024
+#ifndef XP_OS2
+#define MAXPATHLEN 1024
#endif
-#define EFTYPE EINVAL /* POSIX 1003.1 format errno. */
+#define EFTYPE EINVAL /* POSIX 1003.1 format errno. */
-#ifndef STDERR_FILENO
-#define STDIN_FILENO 0 /* ANSI C #defines */
-#define STDOUT_FILENO 1
-#define STDERR_FILENO 2
+#ifndef STDERR_FILENO
+#define STDIN_FILENO 0 /* ANSI C #defines */
+#define STDOUT_FILENO 1
+#define STDERR_FILENO 2
#endif
-#ifndef O_ACCMODE /* POSIX 1003.1 access mode mask. */
-#define O_ACCMODE (O_RDONLY|O_WRONLY|O_RDWR)
+#ifndef O_ACCMODE /* POSIX 1003.1 access mode mask. */
+#define O_ACCMODE (O_RDONLY | O_WRONLY | O_RDWR)
#endif
#endif
#ifdef macintosh
#include <stdio.h>
#include "xp_mcom.h"
-#define O_ACCMODE 3 /* Mask for file access modes */
+#define O_ACCMODE 3 /* Mask for file access modes */
#define EFTYPE 2000
PR_BEGIN_EXTERN_C
int mkstemp(const char *path);
PR_END_EXTERN_C
-#endif /* MACINTOSH */
+#endif /* MACINTOSH */
#if !defined(_WINDOWS) && !defined(macintosh)
#include <sys/stat.h>
@@ -219,46 +219,49 @@ PR_END_EXTERN_C
/* define EFTYPE since most don't */
#ifndef EFTYPE
-#define EFTYPE EINVAL /* POSIX 1003.1 format errno. */
+#define EFTYPE EINVAL /* POSIX 1003.1 format errno. */
#endif
-#define RET_ERROR -1 /* Return values. */
-#define RET_SUCCESS 0
-#define RET_SPECIAL 1
+#define RET_ERROR -1 /* Return values. */
+#define RET_SUCCESS 0
+#define RET_SPECIAL 1
-#define MAX_PAGE_NUMBER 0xffffffff /* >= # of pages in a file */
+#define MAX_PAGE_NUMBER 0xffffffff /* >= # of pages in a file */
#ifndef __sgi
-typedef uint32 pgno_t;
+typedef uint32 pgno_t;
#endif
-#define MAX_PAGE_OFFSET 65535 /* >= # of bytes in a page */
-typedef uint16 indx_t;
-#define MAX_REC_NUMBER 0xffffffff /* >= # of records in a tree */
-typedef uint32 recno_t;
+#define MAX_PAGE_OFFSET 65535 /* >= # of bytes in a page */
+typedef uint16 indx_t;
+#define MAX_REC_NUMBER 0xffffffff /* >= # of records in a tree */
+typedef uint32 recno_t;
/* Key/data structure -- a Data-Base Thang. */
typedef struct {
- void *data; /* data */
- size_t size; /* data length */
+ void *data; /* data */
+ size_t size; /* data length */
} DBT;
/* Routine flags. */
-#define R_CURSOR 1 /* del, put, seq */
-#define __R_UNUSED 2 /* UNUSED */
-#define R_FIRST 3 /* seq */
-#define R_IAFTER 4 /* put (RECNO) */
-#define R_IBEFORE 5 /* put (RECNO) */
-#define R_LAST 6 /* seq (BTREE, RECNO) */
-#define R_NEXT 7 /* seq */
-#define R_NOOVERWRITE 8 /* put */
-#define R_PREV 9 /* seq (BTREE, RECNO) */
-#define R_SETCURSOR 10 /* put (RECNO) */
-#define R_RECNOSYNC 11 /* sync (RECNO) */
-
-typedef enum { DB_BTREE, DB_HASH, DB_RECNO } DBTYPE;
-
-typedef enum { LockOutDatabase, UnlockDatabase } DBLockFlagEnum;
+#define R_CURSOR 1 /* del, put, seq */
+#define __R_UNUSED 2 /* UNUSED */
+#define R_FIRST 3 /* seq */
+#define R_IAFTER 4 /* put (RECNO) */
+#define R_IBEFORE 5 /* put (RECNO) */
+#define R_LAST 6 /* seq (BTREE, RECNO) */
+#define R_NEXT 7 /* seq */
+#define R_NOOVERWRITE 8 /* put */
+#define R_PREV 9 /* seq (BTREE, RECNO) */
+#define R_SETCURSOR 10 /* put (RECNO) */
+#define R_RECNOSYNC 11 /* sync (RECNO) */
+
+typedef enum { DB_BTREE,
+ DB_HASH,
+ DB_RECNO } DBTYPE;
+
+typedef enum { LockOutDatabase,
+ UnlockDatabase } DBLockFlagEnum;
/*
* !!!
@@ -274,128 +277,134 @@ typedef enum { LockOutDatabase, UnlockDatabase } DBLockFlagEnum;
* the DB_LOCK flag isn't set.
*/
#if UINT_MAX > 65535
-#define DB_LOCK 0x20000000 /* Do locking. */
-#define DB_SHMEM 0x40000000 /* Use shared memory. */
-#define DB_TXN 0x80000000 /* Do transactions. */
+#define DB_LOCK 0x20000000 /* Do locking. */
+#define DB_SHMEM 0x40000000 /* Use shared memory. */
+#define DB_TXN 0x80000000 /* Do transactions. */
#else
-#define DB_LOCK 0x2000 /* Do locking. */
-#define DB_SHMEM 0x4000 /* Use shared memory. */
-#define DB_TXN 0x8000 /* Do transactions. */
+#define DB_LOCK 0x2000 /* Do locking. */
+#define DB_SHMEM 0x4000 /* Use shared memory. */
+#define DB_TXN 0x8000 /* Do transactions. */
#endif
/* Access method description structure. */
typedef struct __db {
- DBTYPE type; /* Underlying db type. */
- int (*close) (struct __db *);
- int (*del) (const struct __db *, const DBT *, uint);
- int (*get) (const struct __db *, const DBT *, DBT *, uint);
- int (*put) (const struct __db *, DBT *, const DBT *, uint);
- int (*seq) (const struct __db *, DBT *, DBT *, uint);
- int (*sync) (const struct __db *, uint);
- void *internal; /* Access method private. */
- int (*fd) (const struct __db *);
+ DBTYPE type; /* Underlying db type. */
+ int (*close)(struct __db *);
+ int (*del)(const struct __db *, const DBT *, uint);
+ int (*get)(const struct __db *, const DBT *, DBT *, uint);
+ int (*put)(const struct __db *, DBT *, const DBT *, uint);
+ int (*seq)(const struct __db *, DBT *, DBT *, uint);
+ int (*sync)(const struct __db *, uint);
+ void *internal; /* Access method private. */
+ int (*fd)(const struct __db *);
} DB;
-#define BTREEMAGIC 0x053162
-#define BTREEVERSION 3
+#define BTREEMAGIC 0x053162
+#define BTREEVERSION 3
/* Structure used to pass parameters to the btree routines. */
typedef struct {
-#define R_DUP 0x01 /* duplicate keys */
- uint32 flags;
- uint cachesize; /* bytes to cache */
- int maxkeypage; /* maximum keys per page */
- int minkeypage; /* minimum keys per page */
- uint psize; /* page size */
- int (*compare) /* comparison function */
- (const DBT *, const DBT *);
- size_t (*prefix) /* prefix function */
- (const DBT *, const DBT *);
- int lorder; /* byte order */
+#define R_DUP 0x01 /* duplicate keys */
+ uint32 flags;
+ uint cachesize; /* bytes to cache */
+ int maxkeypage; /* maximum keys per page */
+ int minkeypage; /* minimum keys per page */
+ uint psize; /* page size */
+ int(*compare) /* comparison function */
+ (const DBT *, const DBT *);
+ size_t(*prefix) /* prefix function */
+ (const DBT *, const DBT *);
+ int lorder; /* byte order */
} BTREEINFO;
-#define HASHMAGIC 0x061561
-#define HASHVERSION 2
+#define HASHMAGIC 0x061561
+#define HASHVERSION 2
/* Structure used to pass parameters to the hashing routines. */
typedef struct {
- uint bsize; /* bucket size */
- uint ffactor; /* fill factor */
- uint nelem; /* number of elements */
- uint cachesize; /* bytes to cache */
- uint32 /* hash function */
- (*hash) (const void *, size_t);
- int lorder; /* byte order */
+ uint bsize; /* bucket size */
+ uint ffactor; /* fill factor */
+ uint nelem; /* number of elements */
+ uint cachesize; /* bytes to cache */
+ uint32 /* hash function */
+ (*hash)(const void *, size_t);
+ int lorder; /* byte order */
} HASHINFO;
/* Structure used to pass parameters to the record routines. */
typedef struct {
-#define R_FIXEDLEN 0x01 /* fixed-length records */
-#define R_NOKEY 0x02 /* key not required */
-#define R_SNAPSHOT 0x04 /* snapshot the input */
- uint32 flags;
- uint cachesize; /* bytes to cache */
- uint psize; /* page size */
- int lorder; /* byte order */
- size_t reclen; /* record length (fixed-length records) */
- uint8 bval; /* delimiting byte (variable-length records */
- char *bfname; /* btree file name */
+#define R_FIXEDLEN 0x01 /* fixed-length records */
+#define R_NOKEY 0x02 /* key not required */
+#define R_SNAPSHOT 0x04 /* snapshot the input */
+ uint32 flags;
+ uint cachesize; /* bytes to cache */
+ uint psize; /* page size */
+ int lorder; /* byte order */
+ size_t reclen; /* record length (fixed-length records) */
+ uint8 bval; /* delimiting byte (variable-length records */
+ char *bfname; /* btree file name */
} RECNOINFO;
#ifdef __DBINTERFACE_PRIVATE
/*
* Little endian <==> big endian 32-bit swap macros.
- * M_32_SWAP swap a memory location
- * P_32_SWAP swap a referenced memory location
- * P_32_COPY swap from one location to another
+ * M_32_SWAP swap a memory location
+ * P_32_SWAP swap a referenced memory location
+ * P_32_COPY swap from one location to another
*/
-#define M_32_SWAP(a) { \
- uint32 _tmp = a; \
- ((char *)&a)[0] = ((char *)&_tmp)[3]; \
- ((char *)&a)[1] = ((char *)&_tmp)[2]; \
- ((char *)&a)[2] = ((char *)&_tmp)[1]; \
- ((char *)&a)[3] = ((char *)&_tmp)[0]; \
-}
-#define P_32_SWAP(a) { \
- uint32 _tmp = *(uint32 *)a; \
- ((char *)a)[0] = ((char *)&_tmp)[3]; \
- ((char *)a)[1] = ((char *)&_tmp)[2]; \
- ((char *)a)[2] = ((char *)&_tmp)[1]; \
- ((char *)a)[3] = ((char *)&_tmp)[0]; \
-}
-#define P_32_COPY(a, b) { \
- ((char *)&(b))[0] = ((char *)&(a))[3]; \
- ((char *)&(b))[1] = ((char *)&(a))[2]; \
- ((char *)&(b))[2] = ((char *)&(a))[1]; \
- ((char *)&(b))[3] = ((char *)&(a))[0]; \
-}
+#define M_32_SWAP(a) \
+ { \
+ uint32 _tmp = a; \
+ ((char *)&a)[0] = ((char *)&_tmp)[3]; \
+ ((char *)&a)[1] = ((char *)&_tmp)[2]; \
+ ((char *)&a)[2] = ((char *)&_tmp)[1]; \
+ ((char *)&a)[3] = ((char *)&_tmp)[0]; \
+ }
+#define P_32_SWAP(a) \
+ { \
+ uint32 _tmp = *(uint32 *)a; \
+ ((char *)a)[0] = ((char *)&_tmp)[3]; \
+ ((char *)a)[1] = ((char *)&_tmp)[2]; \
+ ((char *)a)[2] = ((char *)&_tmp)[1]; \
+ ((char *)a)[3] = ((char *)&_tmp)[0]; \
+ }
+#define P_32_COPY(a, b) \
+ { \
+ ((char *)&(b))[0] = ((char *)&(a))[3]; \
+ ((char *)&(b))[1] = ((char *)&(a))[2]; \
+ ((char *)&(b))[2] = ((char *)&(a))[1]; \
+ ((char *)&(b))[3] = ((char *)&(a))[0]; \
+ }
/*
* Little endian <==> big endian 16-bit swap macros.
- * M_16_SWAP swap a memory location
- * P_16_SWAP swap a referenced memory location
- * P_16_COPY swap from one location to another
+ * M_16_SWAP swap a memory location
+ * P_16_SWAP swap a referenced memory location
+ * P_16_COPY swap from one location to another
*/
-#define M_16_SWAP(a) { \
- uint16 _tmp = a; \
- ((char *)&a)[0] = ((char *)&_tmp)[1]; \
- ((char *)&a)[1] = ((char *)&_tmp)[0]; \
-}
-#define P_16_SWAP(a) { \
- uint16 _tmp = *(uint16 *)a; \
- ((char *)a)[0] = ((char *)&_tmp)[1]; \
- ((char *)a)[1] = ((char *)&_tmp)[0]; \
-}
-#define P_16_COPY(a, b) { \
- ((char *)&(b))[0] = ((char *)&(a))[1]; \
- ((char *)&(b))[1] = ((char *)&(a))[0]; \
-}
+#define M_16_SWAP(a) \
+ { \
+ uint16 _tmp = a; \
+ ((char *)&a)[0] = ((char *)&_tmp)[1]; \
+ ((char *)&a)[1] = ((char *)&_tmp)[0]; \
+ }
+#define P_16_SWAP(a) \
+ { \
+ uint16 _tmp = *(uint16 *)a; \
+ ((char *)a)[0] = ((char *)&_tmp)[1]; \
+ ((char *)a)[1] = ((char *)&_tmp)[0]; \
+ }
+#define P_16_COPY(a, b) \
+ { \
+ ((char *)&(b))[0] = ((char *)&(a))[1]; \
+ ((char *)&(b))[1] = ((char *)&(a))[0]; \
+ }
#endif
PR_BEGIN_EXTERN_C
extern DB *
-dbopen (const char *, int, int, DBTYPE, const void *);
+dbopen(const char *, int, int, DBTYPE, const void *);
/* set or unset a global lock flag to disable the
* opening of any DBM file
@@ -403,10 +412,10 @@ dbopen (const char *, int, int, DBTYPE, const void *);
void dbSetOrClearDBLock(DBLockFlagEnum type);
#ifdef __DBINTERFACE_PRIVATE
-DB *__bt_open (const char *, int, int, const BTREEINFO *, int);
-DB *__hash_open (const char *, int, int, const HASHINFO *, int);
-DB *__rec_open (const char *, int, int, const RECNOINFO *, int);
-void __dbpanic (DB *dbp);
+DB *__bt_open(const char *, int, int, const BTREEINFO *, int);
+DB *__hash_open(const char *, int, int, const HASHINFO *, int);
+DB *__rec_open(const char *, int, int, const RECNOINFO *, int);
+void __dbpanic(DB *dbp);
#endif
PR_END_EXTERN_C
diff --git a/nss/lib/dbm/include/ncompat.h b/nss/lib/dbm/include/ncompat.h
index b6126f8..9fd4347 100644
--- a/nss/lib/dbm/include/ncompat.h
+++ b/nss/lib/dbm/include/ncompat.h
@@ -1,6 +1,6 @@
/*-
* Copyright (c) 1991, 1993
- * The Regents of the University of California. All rights reserved.
+ * The Regents of the University of California. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -10,7 +10,7 @@
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
- * 3. ***REMOVED*** - see
+ * 3. ***REMOVED*** - see
* ftp://ftp.cs.berkeley.edu/pub/4bsd/README.Impt.License.Change
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
@@ -28,11 +28,11 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * @(#)compat.h 8.13 (Berkeley) 2/21/94
+ * @(#)compat.h 8.13 (Berkeley) 2/21/94
*/
-#ifndef _COMPAT_H_
-#define _COMPAT_H_
+#ifndef _COMPAT_H_
+#define _COMPAT_H_
#include <sys/types.h>
@@ -41,67 +41,61 @@
* the 0 to a 1.
*/
#if 0
-typedef unsigned char u_char; /* 4.[34]BSD names. */
-typedef unsigned int u_int;
-typedef unsigned long u_long;
-typedef unsigned short u_short;
+typedef unsigned char u_char; /* 4.[34]BSD names. */
+typedef unsigned int u_int;
+typedef unsigned long u_long;
+typedef unsigned short u_short;
#endif
/* If your system doesn't typedef size_t, change the 0 to a 1. */
#if 0
-typedef unsigned int size_t; /* POSIX, 4.[34]BSD names. */
+typedef unsigned int size_t; /* POSIX, 4.[34]BSD names. */
#endif
/* If your system doesn't typedef ssize_t, change the 0 to a 1. */
#if 0
-typedef int ssize_t; /* POSIX names. */
+typedef int ssize_t; /* POSIX names. */
#endif
/*
* If your system doesn't have the POSIX type for a signal mask,
* change the 0 to a 1.
*/
-#if 0 /* POSIX 1003.1 signal mask type. */
-typedef unsigned int sigset_t;
+#if 0 /* POSIX 1003.1 signal mask type. */
+typedef unsigned int sigset_t;
#endif
/*
* If your system's vsprintf returns a char *, not an int,
* change the 0 to a 1.
*/
-#if defined (__sun) && !defined(__SVR4) /* SUNOS */
-#define VSPRINTF_CHARSTAR
+#if defined(__sun) && !defined(__SVR4) /* SUNOS */
+#define VSPRINTF_CHARSTAR
#endif
/*
- * If you don't have POSIX 1003.1 signals, the signal code surrounding the
+ * If you don't have POSIX 1003.1 signals, the signal code surrounding the
* temporary file creation is intended to block all of the possible signals
* long enough to create the file and unlink it. All of this stuff is
* intended to use old-style BSD calls to fake POSIX 1003.1 calls.
*/
-#ifdef NO_POSIX_SIGNALS
-#define sigemptyset(set) (*(set) = 0)
-#define sigfillset(set) (*(set) = ~(sigset_t)0, 0)
-#define sigaddset(set,signo) (*(set) |= sigmask(signo), 0)
-#define sigdelset(set,signo) (*(set) &= ~sigmask(signo), 0)
-#define sigismember(set,signo) ((*(set) & sigmask(signo)) != 0)
+#ifdef NO_POSIX_SIGNALS
+#define sigemptyset(set) (*(set) = 0)
+#define sigfillset(set) (*(set) = ~(sigset_t)0, 0)
+#define sigaddset(set, signo) (*(set) |= sigmask(signo), 0)
+#define sigdelset(set, signo) (*(set) &= ~sigmask(signo), 0)
+#define sigismember(set, signo) ((*(set)&sigmask(signo)) != 0)
-#define SIG_BLOCK 1
-#define SIG_UNBLOCK 2
-#define SIG_SETMASK 3
+#define SIG_BLOCK 1
+#define SIG_UNBLOCK 2
+#define SIG_SETMASK 3
-static int __sigtemp; /* For the use of sigprocmask */
+static int __sigtemp; /* For the use of sigprocmask */
/* Repeated test of oset != NULL is to avoid "*0". */
-#define sigprocmask(how, set, oset) \
- ((__sigtemp = \
- (((how) == SIG_BLOCK) ? \
- sigblock(0) | *(set) : \
- (((how) == SIG_UNBLOCK) ? \
- sigblock(0) & ~(*(set)) : \
- ((how) == SIG_SETMASK ? \
- *(set) : sigblock(0))))), \
- ((oset) ? (*(oset ? oset : set) = sigsetmask(__sigtemp)) : \
- sigsetmask(__sigtemp)), 0)
+#define sigprocmask(how, set, oset) \
+ ((__sigtemp = \
+ (((how) == SIG_BLOCK) ? sigblock(0) | *(set) : (((how) == SIG_UNBLOCK) ? sigblock(0) & ~(*(set)) : ((how) == SIG_SETMASK ? *(set) : sigblock(0))))), \
+ ((oset) ? (*(oset ? oset : set) = sigsetmask(__sigtemp)) : sigsetmask(__sigtemp)), 0)
#endif
/*
@@ -109,24 +103,24 @@ static int __sigtemp; /* For the use of sigprocmask */
* byte order set, make sure you specify the correct one.
*/
#ifndef BYTE_ORDER
-#define LITTLE_ENDIAN 1234 /* LSB first: i386, vax */
-#define BIG_ENDIAN 4321 /* MSB first: 68000, ibm, net */
-#define BYTE_ORDER BIG_ENDIAN /* Set for your system. */
+#define LITTLE_ENDIAN 1234 /* LSB first: i386, vax */
+#define BIG_ENDIAN 4321 /* MSB first: 68000, ibm, net */
+#define BYTE_ORDER BIG_ENDIAN /* Set for your system. */
#endif
#if defined(SYSV) || defined(SYSTEM5) || defined(__sun)
-#define index(a, b) strchr(a, b)
-#define rindex(a, b) strrchr(a, b)
-#define bzero(a, b) memset(a, 0, b)
-#define bcmp(a, b, n) memcmp(a, b, n)
-#define bcopy(a, b, n) memmove(b, a, n)
+#define index(a, b) strchr(a, b)
+#define rindex(a, b) strrchr(a, b)
+#define bzero(a, b) memset(a, 0, b)
+#define bcmp(a, b, n) memcmp(a, b, n)
+#define bcopy(a, b, n) memmove(b, a, n)
#endif
#if defined(BSD) || defined(BSD4_3)
-#define strchr(a, b) index(a, b)
-#define strrchr(a, b) rindex(a, b)
-#define memcmp(a, b, n) bcmp(a, b, n)
-#define memmove(a, b, n) bcopy(b, a, n)
+#define strchr(a, b) index(a, b)
+#define strrchr(a, b) rindex(a, b)
+#define memcmp(a, b, n) bcmp(a, b, n)
+#define memmove(a, b, n) bcopy(b, a, n)
#endif
/*
@@ -136,95 +130,95 @@ static int __sigtemp; /* For the use of sigprocmask */
* if you are trying to compile on a different type of system.
*/
#ifndef USHRT_MAX
-#define USHRT_MAX 0xFFFF
-#define ULONG_MAX 0xFFFFFFFF
+#define USHRT_MAX 0xFFFF
+#define ULONG_MAX 0xFFFFFFFF
#endif
-#ifndef O_ACCMODE /* POSIX 1003.1 access mode mask. */
-#define O_ACCMODE (O_RDONLY|O_WRONLY|O_RDWR)
+#ifndef O_ACCMODE /* POSIX 1003.1 access mode mask. */
+#define O_ACCMODE (O_RDONLY | O_WRONLY | O_RDWR)
#endif
-#ifndef _POSIX2_RE_DUP_MAX /* POSIX 1003.2 RE limit. */
-#define _POSIX2_RE_DUP_MAX 255
+#ifndef _POSIX2_RE_DUP_MAX /* POSIX 1003.2 RE limit. */
+#define _POSIX2_RE_DUP_MAX 255
#endif
/*
* If you can't provide lock values in the open(2) call. Note, this
* allows races to happen.
*/
-#ifndef O_EXLOCK /* 4.4BSD extension. */
-#define O_EXLOCK 0
+#ifndef O_EXLOCK /* 4.4BSD extension. */
+#define O_EXLOCK 0
#endif
-#ifndef O_SHLOCK /* 4.4BSD extension. */
-#define O_SHLOCK 0
+#ifndef O_SHLOCK /* 4.4BSD extension. */
+#define O_SHLOCK 0
#endif
#ifndef EFTYPE
-#define EFTYPE EINVAL /* POSIX 1003.1 format errno. */
+#define EFTYPE EINVAL /* POSIX 1003.1 format errno. */
#endif
-#ifndef WCOREDUMP /* 4.4BSD extension */
-#define WCOREDUMP(a) 0
+#ifndef WCOREDUMP /* 4.4BSD extension */
+#define WCOREDUMP(a) 0
#endif
-#ifndef STDERR_FILENO
-#define STDIN_FILENO 0 /* ANSI C #defines */
-#define STDOUT_FILENO 1
-#define STDERR_FILENO 2
+#ifndef STDERR_FILENO
+#define STDIN_FILENO 0 /* ANSI C #defines */
+#define STDOUT_FILENO 1
+#define STDERR_FILENO 2
#endif
#ifndef SEEK_END
-#define SEEK_SET 0 /* POSIX 1003.1 seek values */
-#define SEEK_CUR 1
-#define SEEK_END 2
+#define SEEK_SET 0 /* POSIX 1003.1 seek values */
+#define SEEK_CUR 1
+#define SEEK_END 2
#endif
-#ifndef _POSIX_VDISABLE /* POSIX 1003.1 disabling char. */
-#define _POSIX_VDISABLE 0 /* Some systems used 0. */
+#ifndef _POSIX_VDISABLE /* POSIX 1003.1 disabling char. */
+#define _POSIX_VDISABLE 0 /* Some systems used 0. */
#endif
-#ifndef TCSASOFT /* 4.4BSD extension. */
-#define TCSASOFT 0
+#ifndef TCSASOFT /* 4.4BSD extension. */
+#define TCSASOFT 0
#endif
-#ifndef _POSIX2_RE_DUP_MAX /* POSIX 1003.2 values. */
-#define _POSIX2_RE_DUP_MAX 255
+#ifndef _POSIX2_RE_DUP_MAX /* POSIX 1003.2 values. */
+#define _POSIX2_RE_DUP_MAX 255
#endif
-#ifndef NULL /* ANSI C #defines NULL everywhere. */
-#define NULL 0
+#ifndef NULL /* ANSI C #defines NULL everywhere. */
+#define NULL 0
#endif
-#ifndef MAX /* Usually found in <sys/param.h>. */
-#define MAX(_a,_b) ((_a)<(_b)?(_b):(_a))
+#ifndef MAX /* Usually found in <sys/param.h>. */
+#define MAX(_a, _b) ((_a) < (_b) ? (_b) : (_a))
#endif
-#ifndef MIN /* Usually found in <sys/param.h>. */
-#define MIN(_a,_b) ((_a)<(_b)?(_a):(_b))
+#ifndef MIN /* Usually found in <sys/param.h>. */
+#define MIN(_a, _b) ((_a) < (_b) ? (_a) : (_b))
#endif
/* Default file permissions. */
-#ifndef DEFFILEMODE /* 4.4BSD extension. */
-#define DEFFILEMODE (S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH|S_IWOTH)
+#ifndef DEFFILEMODE /* 4.4BSD extension. */
+#define DEFFILEMODE (S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH)
#endif
#ifndef __sun
-#ifndef S_ISDIR /* POSIX 1003.1 file type tests. */
-#define S_ISDIR(m) ((m & 0170000) == 0040000) /* directory */
-#define S_ISCHR(m) ((m & 0170000) == 0020000) /* char special */
-#define S_ISBLK(m) ((m & 0170000) == 0060000) /* block special */
-#define S_ISREG(m) ((m & 0170000) == 0100000) /* regular file */
-#define S_ISFIFO(m) ((m & 0170000) == 0010000) /* fifo */
+#ifndef S_ISDIR /* POSIX 1003.1 file type tests. */
+#define S_ISDIR(m) ((m & 0170000) == 0040000) /* directory */
+#define S_ISCHR(m) ((m & 0170000) == 0020000) /* char special */
+#define S_ISBLK(m) ((m & 0170000) == 0060000) /* block special */
+#define S_ISREG(m) ((m & 0170000) == 0100000) /* regular file */
+#define S_ISFIFO(m) ((m & 0170000) == 0010000) /* fifo */
#endif
-#ifndef S_ISLNK /* BSD POSIX 1003.1 extensions */
-#define S_ISLNK(m) ((m & 0170000) == 0120000) /* symbolic link */
-#define S_ISSOCK(m) ((m & 0170000) == 0140000) /* socket */
+#ifndef S_ISLNK /* BSD POSIX 1003.1 extensions */
+#define S_ISLNK(m) ((m & 0170000) == 0120000) /* symbolic link */
+#define S_ISSOCK(m) ((m & 0170000) == 0140000) /* socket */
#endif
#endif /* __sun */
/* The type of a va_list. */
-#ifndef _BSD_VA_LIST_ /* 4.4BSD #define. */
-#define _BSD_VA_LIST_ char *
+#ifndef _BSD_VA_LIST_ /* 4.4BSD #define. */
+#define _BSD_VA_LIST_ char*
#endif
#endif /* !_COMPAT_H_ */
diff --git a/nss/lib/dbm/include/page.h b/nss/lib/dbm/include/page.h
index be2446d..1ece42b 100644
--- a/nss/lib/dbm/include/page.h
+++ b/nss/lib/dbm/include/page.h
@@ -1,6 +1,6 @@
/*-
* Copyright (c) 1990, 1993, 1994
- * The Regents of the University of California. All rights reserved.
+ * The Regents of the University of California. All rights reserved.
*
* This code is derived from software contributed to Berkeley by
* Margo Seltzer.
@@ -13,7 +13,7 @@
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
- * 3. ***REMOVED*** - see
+ * 3. ***REMOVED*** - see
* ftp://ftp.cs.berkeley.edu/pub/4bsd/README.Impt.License.Change
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
@@ -31,7 +31,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * @(#)page.h 8.2 (Berkeley) 5/31/94
+ * @(#)page.h 8.2 (Berkeley) 5/31/94
*/
/*
@@ -42,17 +42,17 @@
* routines dealing with a data page
*
* page format:
- * +------------------------------+
- * p | n | keyoff | datoff | keyoff |
- * +------------+--------+--------+
- * | datoff | free | ptr | --> |
- * +--------+---------------------+
- * | F R E E A R E A |
- * +--------------+---------------+
- * | <---- - - - | data |
- * +--------+-----+----+----------+
- * | key | data | key |
- * +--------+----------+----------+
+ * +------------------------------+
+ * p | n | keyoff | datoff | keyoff |
+ * +------------+--------+--------+
+ * | datoff | free | ptr | --> |
+ * +--------+---------------------+
+ * | F R E E A R E A |
+ * +--------------+---------------+
+ * | <---- - - - | data |
+ * +--------+-----+----+----------+
+ * | key | data | key |
+ * +--------+----------+----------+
*
* Pointer to the free space is always: p[p[0] + 2]
* Amount of free space on the page is: p[p[0] + 1]
@@ -60,8 +60,8 @@
/*
* How many bytes required for this pair?
- * 2 shorts in the table at the top of the page + room for the
- * key and room for the data
+ * 2 shorts in the table at the top of the page + room for the
+ * key and room for the data
*
* We prohibit entering a pair on a page unless there is also room to append
* an overflow page. The reason for this it that you can get in a situation
@@ -73,22 +73,21 @@
#ifndef PAGE_H
#define PAGE_H
-#define PAIRSIZE(K,D) (2*sizeof(uint16) + (K)->size + (D)->size)
-#define BIGOVERHEAD (4*sizeof(uint16))
-#define KEYSIZE(K) (4*sizeof(uint16) + (K)->size);
-#define OVFLSIZE (2*sizeof(uint16))
-#define FREESPACE(P) ((P)[(P)[0]+1])
-#define OFFSET(P) ((P)[(P)[0]+2])
-#define PAIRFITS(P,K,D) \
- (((P)[2] >= REAL_KEY) && \
- (PAIRSIZE((K),(D)) + OVFLSIZE) <= FREESPACE((P)))
-#define PAGE_META(N) (((N)+3) * sizeof(uint16))
+#define PAIRSIZE(K, D) (2 * sizeof(uint16) + (K)->size + (D)->size)
+#define BIGOVERHEAD (4 * sizeof(uint16))
+#define KEYSIZE(K) (4 * sizeof(uint16) + (K)->size);
+#define OVFLSIZE (2 * sizeof(uint16))
+#define FREESPACE(P) ((P)[(P)[0] + 1])
+#define OFFSET(P) ((P)[(P)[0] + 2])
+#define PAIRFITS(P, K, D) \
+ (((P)[2] >= REAL_KEY) && \
+ (PAIRSIZE((K), (D)) + OVFLSIZE) <= FREESPACE((P)))
+#define PAGE_META(N) (((N) + 3) * sizeof(uint16))
typedef struct {
- BUFHEAD *newp;
- BUFHEAD *oldp;
- BUFHEAD *nextp;
- uint16 next_addr;
-} SPLIT_RETURN;
+ BUFHEAD *newp;
+ BUFHEAD *oldp;
+ BUFHEAD *nextp;
+ uint16 next_addr;
+} SPLIT_RETURN;
#endif
-
diff --git a/nss/lib/dbm/include/queue.h b/nss/lib/dbm/include/queue.h
index 3b4ffeb..adc2c52 100644
--- a/nss/lib/dbm/include/queue.h
+++ b/nss/lib/dbm/include/queue.h
@@ -1,6 +1,6 @@
-/*
+/*
* Copyright (c) 1991, 1993
- * The Regents of the University of California. All rights reserved.
+ * The Regents of the University of California. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -10,7 +10,7 @@
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
- * 3. ***REMOVED*** - see
+ * 3. ***REMOVED*** - see
* ftp://ftp.cs.berkeley.edu/pub/4bsd/README.Impt.License.Change
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
@@ -28,11 +28,11 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * @(#)queue.h 8.3 (Berkeley) 12/13/93
+ * @(#)queue.h 8.3 (Berkeley) 12/13/93
*/
-#ifndef _QUEUE_H_
-#define _QUEUE_H_
+#ifndef _QUEUE_H_
+#define _QUEUE_H_
/*
* This file defines three types of data structures: lists, tail queues,
@@ -66,178 +66,193 @@
/*
* List definitions.
*/
-#define LIST_HEAD(name, type) \
-struct name { \
- struct type *lh_first; /* first element */ \
-}
+#define LIST_HEAD(name, type) \
+ struct name { \
+ struct type *lh_first; /* first element */ \
+ }
-#define LIST_ENTRY(type) \
-struct { \
- struct type *le_next; /* next element */ \
- struct type **le_prev; /* address of previous next element */ \
-}
+#define LIST_ENTRY(type) \
+ struct { \
+ struct type *le_next; /* next element */ \
+ struct type **le_prev; /* address of previous next element */ \
+ }
/*
* List functions.
*/
-#define LIST_INIT(head) { \
- (head)->lh_first = NULL; \
-}
-
-#define LIST_INSERT_AFTER(listelm, elm, field) { \
- if (((elm)->field.le_next = (listelm)->field.le_next) != NULL) \
- (listelm)->field.le_next->field.le_prev = \
- &(elm)->field.le_next; \
- (listelm)->field.le_next = (elm); \
- (elm)->field.le_prev = &(listelm)->field.le_next; \
-}
-
-#define LIST_INSERT_HEAD(head, elm, field) { \
- if (((elm)->field.le_next = (head)->lh_first) != NULL) \
- (head)->lh_first->field.le_prev = &(elm)->field.le_next;\
- (head)->lh_first = (elm); \
- (elm)->field.le_prev = &(head)->lh_first; \
-}
-
-#define LIST_REMOVE(elm, field) { \
- if ((elm)->field.le_next != NULL) \
- (elm)->field.le_next->field.le_prev = \
- (elm)->field.le_prev; \
- *(elm)->field.le_prev = (elm)->field.le_next; \
-}
+#define LIST_INIT(head) \
+ { \
+ (head)->lh_first = NULL; \
+ }
+
+#define LIST_INSERT_AFTER(listelm, elm, field) \
+ { \
+ if (((elm)->field.le_next = (listelm)->field.le_next) != NULL) \
+ (listelm)->field.le_next->field.le_prev = \
+ &(elm)->field.le_next; \
+ (listelm)->field.le_next = (elm); \
+ (elm)->field.le_prev = &(listelm)->field.le_next; \
+ }
+
+#define LIST_INSERT_HEAD(head, elm, field) \
+ { \
+ if (((elm)->field.le_next = (head)->lh_first) != NULL) \
+ (head)->lh_first->field.le_prev = &(elm)->field.le_next; \
+ (head)->lh_first = (elm); \
+ (elm)->field.le_prev = &(head)->lh_first; \
+ }
+
+#define LIST_REMOVE(elm, field) \
+ { \
+ if ((elm)->field.le_next != NULL) \
+ (elm)->field.le_next->field.le_prev = \
+ (elm)->field.le_prev; \
+ *(elm)->field.le_prev = (elm)->field.le_next; \
+ }
/*
* Tail queue definitions.
*/
-#define TAILQ_HEAD(name, type) \
-struct name { \
- struct type *tqh_first; /* first element */ \
- struct type **tqh_last; /* addr of last next element */ \
-}
-
-#define TAILQ_ENTRY(type) \
-struct { \
- struct type *tqe_next; /* next element */ \
- struct type **tqe_prev; /* address of previous next element */ \
-}
+#define TAILQ_HEAD(name, type) \
+ struct name { \
+ struct type *tqh_first; /* first element */ \
+ struct type **tqh_last; /* addr of last next element */ \
+ }
+
+#define TAILQ_ENTRY(type) \
+ struct { \
+ struct type *tqe_next; /* next element */ \
+ struct type **tqe_prev; /* address of previous next element */ \
+ }
/*
* Tail queue functions.
*/
-#define TAILQ_INIT(head) { \
- (head)->tqh_first = NULL; \
- (head)->tqh_last = &(head)->tqh_first; \
-}
-
-#define TAILQ_INSERT_HEAD(head, elm, field) { \
- if (((elm)->field.tqe_next = (head)->tqh_first) != NULL) \
- (elm)->field.tqe_next->field.tqe_prev = \
- &(elm)->field.tqe_next; \
- else \
- (head)->tqh_last = &(elm)->field.tqe_next; \
- (head)->tqh_first = (elm); \
- (elm)->field.tqe_prev = &(head)->tqh_first; \
-}
-
-#define TAILQ_INSERT_TAIL(head, elm, field) { \
- (elm)->field.tqe_next = NULL; \
- (elm)->field.tqe_prev = (head)->tqh_last; \
- *(head)->tqh_last = (elm); \
- (head)->tqh_last = &(elm)->field.tqe_next; \
-}
-
-#define TAILQ_INSERT_AFTER(head, listelm, elm, field) { \
- if (((elm)->field.tqe_next = (listelm)->field.tqe_next) != NULL)\
- (elm)->field.tqe_next->field.tqe_prev = \
- &(elm)->field.tqe_next; \
- else \
- (head)->tqh_last = &(elm)->field.tqe_next; \
- (listelm)->field.tqe_next = (elm); \
- (elm)->field.tqe_prev = &(listelm)->field.tqe_next; \
-}
-
-#define TAILQ_REMOVE(head, elm, field) { \
- if (((elm)->field.tqe_next) != NULL) \
- (elm)->field.tqe_next->field.tqe_prev = \
- (elm)->field.tqe_prev; \
- else \
- (head)->tqh_last = (elm)->field.tqe_prev; \
- *(elm)->field.tqe_prev = (elm)->field.tqe_next; \
-}
+#define TAILQ_INIT(head) \
+ { \
+ (head)->tqh_first = NULL; \
+ (head)->tqh_last = &(head)->tqh_first; \
+ }
+
+#define TAILQ_INSERT_HEAD(head, elm, field) \
+ { \
+ if (((elm)->field.tqe_next = (head)->tqh_first) != NULL) \
+ (elm)->field.tqe_next->field.tqe_prev = \
+ &(elm)->field.tqe_next; \
+ else \
+ (head)->tqh_last = &(elm)->field.tqe_next; \
+ (head)->tqh_first = (elm); \
+ (elm)->field.tqe_prev = &(head)->tqh_first; \
+ }
+
+#define TAILQ_INSERT_TAIL(head, elm, field) \
+ { \
+ (elm)->field.tqe_next = NULL; \
+ (elm)->field.tqe_prev = (head)->tqh_last; \
+ *(head)->tqh_last = (elm); \
+ (head)->tqh_last = &(elm)->field.tqe_next; \
+ }
+
+#define TAILQ_INSERT_AFTER(head, listelm, elm, field) \
+ { \
+ if (((elm)->field.tqe_next = (listelm)->field.tqe_next) != NULL) \
+ (elm)->field.tqe_next->field.tqe_prev = \
+ &(elm)->field.tqe_next; \
+ else \
+ (head)->tqh_last = &(elm)->field.tqe_next; \
+ (listelm)->field.tqe_next = (elm); \
+ (elm)->field.tqe_prev = &(listelm)->field.tqe_next; \
+ }
+
+#define TAILQ_REMOVE(head, elm, field) \
+ { \
+ if (((elm)->field.tqe_next) != NULL) \
+ (elm)->field.tqe_next->field.tqe_prev = \
+ (elm)->field.tqe_prev; \
+ else \
+ (head)->tqh_last = (elm)->field.tqe_prev; \
+ *(elm)->field.tqe_prev = (elm)->field.tqe_next; \
+ }
/*
* Circular queue definitions.
*/
-#define CIRCLEQ_HEAD(name, type) \
-struct name { \
- struct type *cqh_first; /* first element */ \
- struct type *cqh_last; /* last element */ \
-}
-
-#define CIRCLEQ_ENTRY(type) \
-struct { \
- struct type *cqe_next; /* next element */ \
- struct type *cqe_prev; /* previous element */ \
-}
+#define CIRCLEQ_HEAD(name, type) \
+ struct name { \
+ struct type *cqh_first; /* first element */ \
+ struct type *cqh_last; /* last element */ \
+ }
+
+#define CIRCLEQ_ENTRY(type) \
+ struct { \
+ struct type *cqe_next; /* next element */ \
+ struct type *cqe_prev; /* previous element */ \
+ }
/*
* Circular queue functions.
*/
-#define CIRCLEQ_INIT(head) { \
- (head)->cqh_first = (void *)(head); \
- (head)->cqh_last = (void *)(head); \
-}
-
-#define CIRCLEQ_INSERT_AFTER(head, listelm, elm, field) { \
- (elm)->field.cqe_next = (listelm)->field.cqe_next; \
- (elm)->field.cqe_prev = (listelm); \
- if ((listelm)->field.cqe_next == (void *)(head)) \
- (head)->cqh_last = (elm); \
- else \
- (listelm)->field.cqe_next->field.cqe_prev = (elm); \
- (listelm)->field.cqe_next = (elm); \
-}
-
-#define CIRCLEQ_INSERT_BEFORE(head, listelm, elm, field) { \
- (elm)->field.cqe_next = (listelm); \
- (elm)->field.cqe_prev = (listelm)->field.cqe_prev; \
- if ((listelm)->field.cqe_prev == (void *)(head)) \
- (head)->cqh_first = (elm); \
- else \
- (listelm)->field.cqe_prev->field.cqe_next = (elm); \
- (listelm)->field.cqe_prev = (elm); \
-}
-
-#define CIRCLEQ_INSERT_HEAD(head, elm, field) { \
- (elm)->field.cqe_next = (head)->cqh_first; \
- (elm)->field.cqe_prev = (void *)(head); \
- if ((head)->cqh_last == (void *)(head)) \
- (head)->cqh_last = (elm); \
- else \
- (head)->cqh_first->field.cqe_prev = (elm); \
- (head)->cqh_first = (elm); \
-}
-
-#define CIRCLEQ_INSERT_TAIL(head, elm, field) { \
- (elm)->field.cqe_next = (void *)(head); \
- (elm)->field.cqe_prev = (head)->cqh_last; \
- if ((head)->cqh_first == (void *)(head)) \
- (head)->cqh_first = (elm); \
- else \
- (head)->cqh_last->field.cqe_next = (elm); \
- (head)->cqh_last = (elm); \
-}
-
-#define CIRCLEQ_REMOVE(head, elm, field) { \
- if ((elm)->field.cqe_next == (void *)(head)) \
- (head)->cqh_last = (elm)->field.cqe_prev; \
- else \
- (elm)->field.cqe_next->field.cqe_prev = \
- (elm)->field.cqe_prev; \
- if ((elm)->field.cqe_prev == (void *)(head)) \
- (head)->cqh_first = (elm)->field.cqe_next; \
- else \
- (elm)->field.cqe_prev->field.cqe_next = \
- (elm)->field.cqe_next; \
-}
-#endif /* !_QUEUE_H_ */
+#define CIRCLEQ_INIT(head) \
+ { \
+ (head)->cqh_first = (void *)(head); \
+ (head)->cqh_last = (void *)(head); \
+ }
+
+#define CIRCLEQ_INSERT_AFTER(head, listelm, elm, field) \
+ { \
+ (elm)->field.cqe_next = (listelm)->field.cqe_next; \
+ (elm)->field.cqe_prev = (listelm); \
+ if ((listelm)->field.cqe_next == (void *)(head)) \
+ (head)->cqh_last = (elm); \
+ else \
+ (listelm)->field.cqe_next->field.cqe_prev = (elm); \
+ (listelm)->field.cqe_next = (elm); \
+ }
+
+#define CIRCLEQ_INSERT_BEFORE(head, listelm, elm, field) \
+ { \
+ (elm)->field.cqe_next = (listelm); \
+ (elm)->field.cqe_prev = (listelm)->field.cqe_prev; \
+ if ((listelm)->field.cqe_prev == (void *)(head)) \
+ (head)->cqh_first = (elm); \
+ else \
+ (listelm)->field.cqe_prev->field.cqe_next = (elm); \
+ (listelm)->field.cqe_prev = (elm); \
+ }
+
+#define CIRCLEQ_INSERT_HEAD(head, elm, field) \
+ { \
+ (elm)->field.cqe_next = (head)->cqh_first; \
+ (elm)->field.cqe_prev = (void *)(head); \
+ if ((head)->cqh_last == (void *)(head)) \
+ (head)->cqh_last = (elm); \
+ else \
+ (head)->cqh_first->field.cqe_prev = (elm); \
+ (head)->cqh_first = (elm); \
+ }
+
+#define CIRCLEQ_INSERT_TAIL(head, elm, field) \
+ { \
+ (elm)->field.cqe_next = (void *)(head); \
+ (elm)->field.cqe_prev = (head)->cqh_last; \
+ if ((head)->cqh_first == (void *)(head)) \
+ (head)->cqh_first = (elm); \
+ else \
+ (head)->cqh_last->field.cqe_next = (elm); \
+ (head)->cqh_last = (elm); \
+ }
+
+#define CIRCLEQ_REMOVE(head, elm, field) \
+ { \
+ if ((elm)->field.cqe_next == (void *)(head)) \
+ (head)->cqh_last = (elm)->field.cqe_prev; \
+ else \
+ (elm)->field.cqe_next->field.cqe_prev = \
+ (elm)->field.cqe_prev; \
+ if ((elm)->field.cqe_prev == (void *)(head)) \
+ (head)->cqh_first = (elm)->field.cqe_next; \
+ else \
+ (elm)->field.cqe_prev->field.cqe_next = \
+ (elm)->field.cqe_next; \
+ }
+#endif /* !_QUEUE_H_ */
diff --git a/nss/lib/dbm/include/search.h b/nss/lib/dbm/include/search.h
index ae1df1c..d6fe0d9 100644
--- a/nss/lib/dbm/include/search.h
+++ b/nss/lib/dbm/include/search.h
@@ -1,6 +1,6 @@
/*-
* Copyright (c) 1990, 1993
- * The Regents of the University of California. All rights reserved.
+ * The Regents of the University of California. All rights reserved.
*
* This code is derived from software contributed to Berkeley by
* Margo Seltzer.
@@ -13,7 +13,7 @@
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
- * 3. ***REMOVED*** - see
+ * 3. ***REMOVED*** - see
* ftp://ftp.cs.berkeley.edu/pub/4bsd/README.Impt.License.Change
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
@@ -31,19 +31,20 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * @(#)search.h 8.1 (Berkeley) 6/4/93
+ * @(#)search.h 8.1 (Berkeley) 6/4/93
*/
/* Backward compatibility to hsearch interface. */
typedef struct entry {
- char *key;
- char *data;
+ char *key;
+ char *data;
} ENTRY;
typedef enum {
- FIND, ENTER
+ FIND,
+ ENTER
} ACTION;
-int hcreate (unsigned int);
-void hdestroy (void);
-ENTRY *hsearch (ENTRY, ACTION);
+int hcreate(unsigned int);
+void hdestroy(void);
+ENTRY *hsearch(ENTRY, ACTION);
diff --git a/nss/lib/dbm/include/winfile.h b/nss/lib/dbm/include/winfile.h
index 1fd54d5..da93ec7 100644
--- a/nss/lib/dbm/include/winfile.h
+++ b/nss/lib/dbm/include/winfile.h
@@ -21,35 +21,34 @@
#endif
typedef struct DIR_Struct {
- void * directoryPtr;
- WIN32_FIND_DATA data;
+ void* directoryPtr;
+ WIN32_FIND_DATA data;
} DIR;
#define _ST_FSTYPSZ 16
#if !defined(__BORLANDC__) && !defined(__GNUC__)
- typedef unsigned long mode_t;
- typedef long uid_t;
- typedef long gid_t;
- typedef long off_t;
- typedef unsigned long nlink_t;
-#endif
+typedef unsigned long mode_t;
+typedef long uid_t;
+typedef long gid_t;
+typedef long off_t;
+typedef unsigned long nlink_t;
+#endif
typedef struct timestruc {
- time_t tv_sec; /* seconds */
- long tv_nsec; /* and nanoseconds */
+ time_t tv_sec; /* seconds */
+ long tv_nsec; /* and nanoseconds */
} timestruc_t;
-
-struct dirent { /* data from readdir() */
- ino_t d_ino; /* inode number of entry */
- off_t d_off; /* offset of disk direntory entry */
- unsigned short d_reclen; /* length of this record */
- char d_name[_MAX_FNAME]; /* name of file */
+struct dirent { /* data from readdir() */
+ ino_t d_ino; /* inode number of entry */
+ off_t d_off; /* offset of disk direntory entry */
+ unsigned short d_reclen; /* length of this record */
+ char d_name[_MAX_FNAME]; /* name of file */
};
-#if !defined(__BORLANDC__) && !defined (__GNUC__)
-#define S_ISDIR(s) ((s) & _S_IFDIR)
+#if !defined(__BORLANDC__) && !defined(__GNUC__)
+#define S_ISDIR(s) ((s)&_S_IFDIR)
#endif
#else /* _WIN32 */
@@ -59,43 +58,41 @@ struct dirent { /* data from readdir() */
#include <sys\stat.h>
#include <dos.h>
-
-
/* Getting cocky to support multiple file systems */
-typedef struct dirStruct_tag {
- struct _find_t file_data;
- char c_checkdrive;
+typedef struct dirStruct_tag {
+ struct _find_t file_data;
+ char c_checkdrive;
} dirStruct;
typedef struct DIR_Struct {
- void * directoryPtr;
- dirStruct data;
+ void* directoryPtr;
+ dirStruct data;
} DIR;
#define _ST_FSTYPSZ 16
typedef unsigned long mode_t;
-typedef long uid_t;
-typedef long gid_t;
-typedef long off_t;
+typedef long uid_t;
+typedef long gid_t;
+typedef long off_t;
typedef unsigned long nlink_t;
typedef struct timestruc {
- time_t tv_sec; /* seconds */
- long tv_nsec; /* and nanoseconds */
+ time_t tv_sec; /* seconds */
+ long tv_nsec; /* and nanoseconds */
} timestruc_t;
-struct dirent { /* data from readdir() */
- ino_t d_ino; /* inode number of entry */
- off_t d_off; /* offset of disk direntory entry */
- unsigned short d_reclen; /* length of this record */
+struct dirent { /* data from readdir() */
+ ino_t d_ino; /* inode number of entry */
+ off_t d_off; /* offset of disk direntory entry */
+ unsigned short d_reclen; /* length of this record */
#ifdef XP_WIN32
- char d_name[_MAX_FNAME]; /* name of file */
+ char d_name[_MAX_FNAME]; /* name of file */
#else
- char d_name[20]; /* name of file */
+ char d_name[20]; /* name of file */
#endif
};
-#define S_ISDIR(s) ((s) & _S_IFDIR)
+#define S_ISDIR(s) ((s)&_S_IFDIR)
#endif /* 16-bit windows */
diff --git a/nss/lib/dbm/src/db.c b/nss/lib/dbm/src/db.c
index 264e9fa..5c35bbd 100644
--- a/nss/lib/dbm/src/db.c
+++ b/nss/lib/dbm/src/db.c
@@ -1,6 +1,6 @@
/*-
* Copyright (c) 1991, 1993
- * The Regents of the University of California. All rights reserved.
+ * The Regents of the University of California. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -10,7 +10,7 @@
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
- * 3. ***REMOVED*** - see
+ * 3. ***REMOVED*** - see
* ftp://ftp.cs.berkeley.edu/pub/4bsd/README.Impt.License.Change
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
@@ -30,7 +30,7 @@
*/
#if defined(LIBC_SCCS) && !defined(lint)
-static char sccsid[] = "@(#)db.c 8.4 (Berkeley) 2/21/94";
+static char sccsid[] = "@(#)db.c 8.4 (Berkeley) 2/21/94";
#endif /* LIBC_SCCS and not lint */
#ifndef __DBINTERFACE_PRIVATE
@@ -55,82 +55,80 @@ int all_databases_locked_closed = 0;
/* set or unset a global lock flag to disable the
* opening of any DBM file
*/
-void
+void
dbSetOrClearDBLock(DBLockFlagEnum type)
{
- if(type == LockOutDatabase)
- all_databases_locked_closed = 1;
- else
- all_databases_locked_closed = 0;
+ if (type == LockOutDatabase)
+ all_databases_locked_closed = 1;
+ else
+ all_databases_locked_closed = 0;
}
DB *
-dbopen(const char *fname, int flags,int mode, DBTYPE type, const void *openinfo)
+dbopen(const char *fname, int flags, int mode, DBTYPE type, const void *openinfo)
{
- /* lock out all file databases. Let in-memory databases through
- */
- if(all_databases_locked_closed && fname)
- {
- errno = EINVAL;
- return(NULL);
- }
-
-#define DB_FLAGS (DB_LOCK | DB_SHMEM | DB_TXN)
+ /* lock out all file databases. Let in-memory databases through
+ */
+ if (all_databases_locked_closed && fname) {
+ errno = EINVAL;
+ return (NULL);
+ }
+#define DB_FLAGS (DB_LOCK | DB_SHMEM | DB_TXN)
-#if 0 /* most systems don't have EXLOCK and SHLOCK */
-#define USE_OPEN_FLAGS \
- (O_CREAT | O_EXCL | O_EXLOCK | O_NONBLOCK | O_RDONLY | \
- O_RDWR | O_SHLOCK | O_TRUNC)
+#if 0 /* most systems don't have EXLOCK and SHLOCK */
+#define USE_OPEN_FLAGS \
+ (O_CREAT | O_EXCL | O_EXLOCK | O_NONBLOCK | O_RDONLY | \
+ O_RDWR | O_SHLOCK | O_TRUNC)
#else
-#define USE_OPEN_FLAGS \
- (O_CREAT | O_EXCL | O_RDONLY | \
- O_RDWR | O_TRUNC)
+#define USE_OPEN_FLAGS \
+ (O_CREAT | O_EXCL | O_RDONLY | \
+ O_RDWR | O_TRUNC)
#endif
- if ((flags & ~(USE_OPEN_FLAGS | DB_FLAGS)) == 0)
- switch (type) {
-/* we don't need btree and recno right now */
+ if ((flags & ~(USE_OPEN_FLAGS | DB_FLAGS)) == 0)
+ switch (type) {
+/* we don't need btree and recno right now */
#if 0
- case DB_BTREE:
- return (__bt_open(fname, flags & USE_OPEN_FLAGS,
- mode, openinfo, flags & DB_FLAGS));
- case DB_RECNO:
- return (__rec_open(fname, flags & USE_OPEN_FLAGS,
- mode, openinfo, flags & DB_FLAGS));
+ case DB_BTREE:
+ return (__bt_open(fname, flags & USE_OPEN_FLAGS,
+ mode, openinfo, flags & DB_FLAGS));
+ case DB_RECNO:
+ return (__rec_open(fname, flags & USE_OPEN_FLAGS,
+ mode, openinfo, flags & DB_FLAGS));
#endif
- case DB_HASH:
- return (__hash_open(fname, flags & USE_OPEN_FLAGS,
- mode, (const HASHINFO *)openinfo, flags & DB_FLAGS));
- default:
- break;
- }
- errno = EINVAL;
- return (NULL);
+ case DB_HASH:
+ return (__hash_open(fname, flags & USE_OPEN_FLAGS,
+ mode, (const HASHINFO *)openinfo, flags & DB_FLAGS));
+ default:
+ break;
+ }
+ errno = EINVAL;
+ return (NULL);
}
static int
__dberr()
{
- return (RET_ERROR);
+ return (RET_ERROR);
}
/*
* __DBPANIC -- Stop.
*
* Parameters:
- * dbp: pointer to the DB structure.
+ * dbp: pointer to the DB structure.
*/
void
__dbpanic(DB *dbp)
{
- /* The only thing that can succeed is a close. */
- dbp->del = (int (*)(const struct __db *, const DBT *, uint))__dberr;
- dbp->fd = (int (*)(const struct __db *))__dberr;
- dbp->get = (int (*)(const struct __db *, const DBT *, DBT *, uint))__dberr;
- dbp->put = (int (*)(const struct __db *, DBT *, const DBT *, uint))__dberr;
- dbp->seq = (int (*)(const struct __db *, DBT *, DBT *, uint))__dberr;
- dbp->sync = (int (*)(const struct __db *, uint))__dberr;
+ /* The only thing that can succeed is a close. */
+ dbp->del = (int (*)(const struct __db *, const DBT *, uint))__dberr;
+ dbp->fd = (int (*)(const struct __db *))__dberr;
+ dbp->get = (int (*)(const struct __db *, const DBT *, DBT *, uint))__dberr;
+ dbp->put = (int (*)(const struct __db *, DBT *, const DBT *, uint))__dberr;
+ dbp->seq = (int (*)(const struct __db *, DBT *, DBT *, uint))__dberr;
+ dbp->sync = (int (*)(const struct __db *, uint))__dberr;
}
diff --git a/nss/lib/dbm/src/dirent.c b/nss/lib/dbm/src/dirent.c
index cae92d8..da3e83e 100644
--- a/nss/lib/dbm/src/dirent.c
+++ b/nss/lib/dbm/src/dirent.c
@@ -8,7 +8,7 @@
#include <dirent.h>
#include <errno.h>
-/*#ifndef __EMX__
+/*#ifndef __EMX__
#include <libx.h>
#endif */
@@ -17,9 +17,9 @@
#include <os2.h>
#if OS2 >= 2
-# define FFBUF FILEFINDBUF3
-# define Word ULONG
- /*
+#define FFBUF FILEFINDBUF3
+#define Word ULONG
+/*
* LS20 recommends a request count of 100, but according to the
* APAR text it does not lead to missing files, just to funny
* numbers of returned entries.
@@ -37,34 +37,34 @@
* (each entry is at most 300 bytes long). And ignore the LS20
* effect.
*/
-# define Count 25
-# define BufSz (25 * (sizeof(FILEFINDBUF3)+1))
+#define Count 25
+#define BufSz (25 * (sizeof(FILEFINDBUF3) + 1))
#else
-# define FFBUF FILEFINDBUF
-# define Word USHORT
-# define BufSz 1024
-# define Count 3
+#define FFBUF FILEFINDBUF
+#define Word USHORT
+#define BufSz 1024
+#define Count 3
#endif
#if defined(__IBMC__) || defined(__IBMCPP__)
- #define error(rc) _doserrno = rc, errno = EOS2ERR
+#define error(rc) _doserrno = rc, errno = EOS2ERR
#elif defined(MICROSOFT)
- #define error(rc) _doserrno = rc, errno = 255
+#define error(rc) _doserrno = rc, errno = 255
#else
- #define error(rc) errno = 255
+#define error(rc) errno = 255
#endif
struct _dirdescr {
- HDIR handle; /* DosFindFirst handle */
- char fstype; /* filesystem type */
- Word count; /* valid entries in <ffbuf> */
- long number; /* absolute number of next entry */
- int index; /* relative number of next entry */
- FFBUF * next; /* pointer to next entry */
- char name[MAXPATHLEN+3]; /* directory name */
- unsigned attrmask; /* attribute mask for seekdir */
- struct dirent entry; /* buffer for directory entry */
- BYTE ffbuf[BufSz];
+ HDIR handle; /* DosFindFirst handle */
+ char fstype; /* filesystem type */
+ Word count; /* valid entries in <ffbuf> */
+ long number; /* absolute number of next entry */
+ int index; /* relative number of next entry */
+ FFBUF *next; /* pointer to next entry */
+ char name[MAXPATHLEN + 3]; /* directory name */
+ unsigned attrmask; /* attribute mask for seekdir */
+ struct dirent entry; /* buffer for directory entry */
+ BYTE ffbuf[BufSz];
};
/*
@@ -73,248 +73,245 @@ struct _dirdescr {
static char
getFSType(const char *path)
{
- static char cache[1+26];
- char drive[3], info[512];
- Word unit, infolen;
- char r;
-
- if (isalpha(path[0]) && path[1] == ':') {
- unit = toupper(path[0]) - '@';
- path += 2;
- } else {
- ULONG driveMap;
+ static char cache[1 + 26];
+ char drive[3], info[512];
+ Word unit, infolen;
+ char r;
+
+ if (isalpha(path[0]) && path[1] == ':') {
+ unit = toupper(path[0]) - '@';
+ path += 2;
+ } else {
+ ULONG driveMap;
#if OS2 >= 2
- if (DosQueryCurrentDisk(&unit, &driveMap))
+ if (DosQueryCurrentDisk(&unit, &driveMap))
#else
- if (DosQCurDisk(&unit, &driveMap))
+ if (DosQCurDisk(&unit, &driveMap))
#endif
- return 0;
- }
+ return 0;
+ }
- if ((path[0] == '\\' || path[0] == '/')
- && (path[1] == '\\' || path[1] == '/'))
- return 0;
+ if ((path[0] == '\\' || path[0] == '/') &&
+ (path[1] == '\\' || path[1] == '/'))
+ return 0;
- if (cache [unit])
- return cache [unit];
+ if (cache[unit])
+ return cache[unit];
- drive[0] = '@' + unit;
- drive[1] = ':';
- drive[2] = '\0';
- infolen = sizeof info;
+ drive[0] = '@' + unit;
+ drive[1] = ':';
+ drive[2] = '\0';
+ infolen = sizeof info;
#if OS2 >= 2
- if (DosQueryFSAttach(drive, 0, FSAIL_QUERYNAME, (PVOID)info, &infolen))
- return 0;
- if (infolen >= sizeof(FSQBUFFER2)) {
- FSQBUFFER2 *p = (FSQBUFFER2 *)info;
- r = p->szFSDName[p->cbName];
- } else
+ if (DosQueryFSAttach(drive, 0, FSAIL_QUERYNAME, (PVOID)info, &infolen))
+ return 0;
+ if (infolen >= sizeof(FSQBUFFER2)) {
+ FSQBUFFER2 *p = (FSQBUFFER2 *)info;
+ r = p->szFSDName[p->cbName];
+ } else
#else
- if (DosQFSAttach((PSZ)drive, 0, FSAIL_QUERYNAME, (PVOID)info, &infolen, 0))
- return 0;
- if (infolen >= 9) {
- char *p = info + sizeof(USHORT);
- p += sizeof(USHORT) + *(USHORT *)p + 1 + sizeof(USHORT);
- r = *p;
- } else
+ if (DosQFSAttach((PSZ)drive, 0, FSAIL_QUERYNAME, (PVOID)info, &infolen, 0))
+ return 0;
+ if (infolen >= 9) {
+ char *p = info + sizeof(USHORT);
+ p += sizeof(USHORT) + *(USHORT *)p + 1 + sizeof(USHORT);
+ r = *p;
+ } else
#endif
- r = 0;
- return cache [unit] = r;
+ r = 0;
+ return cache[unit] = r;
}
char *
abs_path(const char *name, char *buffer, int len)
{
- char buf[4];
- if (isalpha(name[0]) && name[1] == ':' && name[2] == '\0') {
- buf[0] = name[0];
- buf[1] = name[1];
- buf[2] = '.';
- buf[3] = '\0';
- name = buf;
- }
+ char buf[4];
+ if (isalpha(name[0]) && name[1] == ':' && name[2] == '\0') {
+ buf[0] = name[0];
+ buf[1] = name[1];
+ buf[2] = '.';
+ buf[3] = '\0';
+ name = buf;
+ }
#if OS2 >= 2
- if (DosQueryPathInfo((PSZ)name, FIL_QUERYFULLNAME, buffer, len))
+ if (DosQueryPathInfo((PSZ)name, FIL_QUERYFULLNAME, buffer, len))
#else
- if (DosQPathInfo((PSZ)name, FIL_QUERYFULLNAME, (PBYTE)buffer, len, 0L))
+ if (DosQPathInfo((PSZ)name, FIL_QUERYFULLNAME, (PBYTE)buffer, len, 0L))
#endif
- return NULL;
- return buffer;
+ return NULL;
+ return buffer;
}
DIR *
openxdir(const char *path, unsigned att_mask)
{
- DIR *dir;
- char name[MAXPATHLEN+3];
- Word rc;
-
- dir = malloc(sizeof(DIR));
- if (dir == NULL) {
- errno = ENOMEM;
- return NULL;
- }
-
- strncpy(name, path, MAXPATHLEN);
- name[MAXPATHLEN] = '\0';
- switch (name[strlen(name)-1]) {
- default:
- strcat(name, "\\");
- case '\\':
- case '/':
- case ':':
- ;
- }
- strcat(name, ".");
- if (!abs_path(name, dir->name, MAXPATHLEN+1))
- strcpy(dir->name, name);
- if (dir->name[strlen(dir->name)-1] == '\\')
- strcat(dir->name, "*");
- else
- strcat(dir->name, "\\*");
-
- dir->fstype = getFSType(dir->name);
- dir->attrmask = att_mask | A_DIR;
-
- dir->handle = HDIR_CREATE;
- dir->count = 100;
+ DIR *dir;
+ char name[MAXPATHLEN + 3];
+ Word rc;
+
+ dir = malloc(sizeof(DIR));
+ if (dir == NULL) {
+ errno = ENOMEM;
+ return NULL;
+ }
+
+ strncpy(name, path, MAXPATHLEN);
+ name[MAXPATHLEN] = '\0';
+ switch (name[strlen(name) - 1]) {
+ default:
+ strcat(name, "\\");
+ case '\\':
+ case '/':
+ case ':':;
+ }
+ strcat(name, ".");
+ if (!abs_path(name, dir->name, MAXPATHLEN + 1))
+ strcpy(dir->name, name);
+ if (dir->name[strlen(dir->name) - 1] == '\\')
+ strcat(dir->name, "*");
+ else
+ strcat(dir->name, "\\*");
+
+ dir->fstype = getFSType(dir->name);
+ dir->attrmask = att_mask | A_DIR;
+
+ dir->handle = HDIR_CREATE;
+ dir->count = 100;
#if OS2 >= 2
- rc = DosFindFirst(dir->name, &dir->handle, dir->attrmask,
- dir->ffbuf, sizeof dir->ffbuf, &dir->count, FIL_STANDARD);
+ rc = DosFindFirst(dir->name, &dir->handle, dir->attrmask,
+ dir->ffbuf, sizeof dir->ffbuf, &dir->count, FIL_STANDARD);
#else
- rc = DosFindFirst((PSZ)dir->name, &dir->handle, dir->attrmask,
- (PFILEFINDBUF)dir->ffbuf, sizeof dir->ffbuf, &dir->count, 0);
+ rc = DosFindFirst((PSZ)dir->name, &dir->handle, dir->attrmask,
+ (PFILEFINDBUF)dir->ffbuf, sizeof dir->ffbuf, &dir->count, 0);
#endif
- switch (rc) {
- default:
- free(dir);
- error(rc);
- return NULL;
- case NO_ERROR:
- case ERROR_NO_MORE_FILES:
- ;
- }
-
- dir->number = 0;
- dir->index = 0;
- dir->next = (FFBUF *)dir->ffbuf;
-
- return (DIR *)dir;
+ switch (rc) {
+ default:
+ free(dir);
+ error(rc);
+ return NULL;
+ case NO_ERROR:
+ case ERROR_NO_MORE_FILES:;
+ }
+
+ dir->number = 0;
+ dir->index = 0;
+ dir->next = (FFBUF *)dir->ffbuf;
+
+ return (DIR *)dir;
}
DIR *
opendir(const char *pathname)
{
- return openxdir(pathname, 0);
+ return openxdir(pathname, 0);
}
struct dirent *
readdir(DIR *dir)
{
- static int dummy_ino = 2;
+ static int dummy_ino = 2;
- if (dir->index == dir->count) {
- Word rc;
- dir->count = 100;
+ if (dir->index == dir->count) {
+ Word rc;
+ dir->count = 100;
#if OS2 >= 2
- rc = DosFindNext(dir->handle, dir->ffbuf,
- sizeof dir->ffbuf, &dir->count);
+ rc = DosFindNext(dir->handle, dir->ffbuf,
+ sizeof dir->ffbuf, &dir->count);
#else
- rc = DosFindNext(dir->handle, (PFILEFINDBUF)dir->ffbuf,
- sizeof dir->ffbuf, &dir->count);
+ rc = DosFindNext(dir->handle, (PFILEFINDBUF)dir->ffbuf,
+ sizeof dir->ffbuf, &dir->count);
#endif
- if (rc) {
- error(rc);
- return NULL;
- }
-
- dir->index = 0;
- dir->next = (FFBUF *)dir->ffbuf;
- }
-
- if (dir->index == dir->count)
- return NULL;
-
- memcpy(dir->entry.d_name, dir->next->achName, dir->next->cchName);
- dir->entry.d_name[dir->next->cchName] = '\0';
- dir->entry.d_ino = dummy_ino++;
- dir->entry.d_reclen = dir->next->cchName;
- dir->entry.d_namlen = dir->next->cchName;
- dir->entry.d_size = dir->next->cbFile;
- dir->entry.d_attribute = dir->next->attrFile;
- dir->entry.d_time = *(USHORT *)&dir->next->ftimeLastWrite;
- dir->entry.d_date = *(USHORT *)&dir->next->fdateLastWrite;
-
- switch (dir->fstype) {
- case 'F': /* FAT */
- case 'C': /* CDFS */
- if (dir->next->attrFile & FILE_DIRECTORY)
- strupr(dir->entry.d_name);
- else
- strlwr(dir->entry.d_name);
- }
+ if (rc) {
+ error(rc);
+ return NULL;
+ }
+
+ dir->index = 0;
+ dir->next = (FFBUF *)dir->ffbuf;
+ }
+
+ if (dir->index == dir->count)
+ return NULL;
+
+ memcpy(dir->entry.d_name, dir->next->achName, dir->next->cchName);
+ dir->entry.d_name[dir->next->cchName] = '\0';
+ dir->entry.d_ino = dummy_ino++;
+ dir->entry.d_reclen = dir->next->cchName;
+ dir->entry.d_namlen = dir->next->cchName;
+ dir->entry.d_size = dir->next->cbFile;
+ dir->entry.d_attribute = dir->next->attrFile;
+ dir->entry.d_time = *(USHORT *)&dir->next->ftimeLastWrite;
+ dir->entry.d_date = *(USHORT *)&dir->next->fdateLastWrite;
+
+ switch (dir->fstype) {
+ case 'F': /* FAT */
+ case 'C': /* CDFS */
+ if (dir->next->attrFile & FILE_DIRECTORY)
+ strupr(dir->entry.d_name);
+ else
+ strlwr(dir->entry.d_name);
+ }
#if OS2 >= 2
- dir->next = (FFBUF *)((BYTE *)dir->next + dir->next->oNextEntryOffset);
+ dir->next = (FFBUF *)((BYTE *)dir->next + dir->next->oNextEntryOffset);
#else
- dir->next = (FFBUF *)((BYTE *)dir->next->achName + dir->next->cchName + 1);
+ dir->next = (FFBUF *)((BYTE *)dir->next->achName + dir->next->cchName + 1);
#endif
- ++dir->number;
- ++dir->index;
+ ++dir->number;
+ ++dir->index;
- return &dir->entry;
+ return &dir->entry;
}
long
telldir(DIR *dir)
{
- return dir->number;
+ return dir->number;
}
void
seekdir(DIR *dir, long off)
{
- if (dir->number > off) {
- char name[MAXPATHLEN+2];
- Word rc;
+ if (dir->number > off) {
+ char name[MAXPATHLEN + 2];
+ Word rc;
- DosFindClose(dir->handle);
+ DosFindClose(dir->handle);
- strcpy(name, dir->name);
- strcat(name, "*");
+ strcpy(name, dir->name);
+ strcat(name, "*");
- dir->handle = HDIR_CREATE;
- dir->count = 32767;
+ dir->handle = HDIR_CREATE;
+ dir->count = 32767;
#if OS2 >= 2
- rc = DosFindFirst(name, &dir->handle, dir->attrmask,
- dir->ffbuf, sizeof dir->ffbuf, &dir->count, FIL_STANDARD);
+ rc = DosFindFirst(name, &dir->handle, dir->attrmask,
+ dir->ffbuf, sizeof dir->ffbuf, &dir->count, FIL_STANDARD);
#else
- rc = DosFindFirst((PSZ)name, &dir->handle, dir->attrmask,
- (PFILEFINDBUF)dir->ffbuf, sizeof dir->ffbuf, &dir->count, 0);
+ rc = DosFindFirst((PSZ)name, &dir->handle, dir->attrmask,
+ (PFILEFINDBUF)dir->ffbuf, sizeof dir->ffbuf, &dir->count, 0);
#endif
- switch (rc) {
- default:
- error(rc);
- return;
- case NO_ERROR:
- case ERROR_NO_MORE_FILES:
- ;
- }
-
- dir->number = 0;
- dir->index = 0;
- dir->next = (FFBUF *)dir->ffbuf;
- }
-
- while (dir->number < off && readdir(dir))
- ;
+ switch (rc) {
+ default:
+ error(rc);
+ return;
+ case NO_ERROR:
+ case ERROR_NO_MORE_FILES:;
+ }
+
+ dir->number = 0;
+ dir->index = 0;
+ dir->next = (FFBUF *)dir->ffbuf;
+ }
+
+ while (dir->number < off && readdir(dir))
+ ;
}
void
closedir(DIR *dir)
{
- DosFindClose(dir->handle);
- free(dir);
+ DosFindClose(dir->handle);
+ free(dir);
}
/*****************************************************************************/
@@ -323,26 +320,25 @@ closedir(DIR *dir)
main(int argc, char **argv)
{
- int i;
- DIR *dir;
- struct dirent *ep;
-
- for (i = 1; i < argc; ++i) {
- dir = opendir(argv[i]);
- if (!dir)
- continue;
- while (ep = readdir(dir))
- if (strchr("\\/:", argv[i] [strlen(argv[i]) - 1]))
- printf("%s%s\n", argv[i], ep->d_name);
- else
- printf("%s/%s\n", argv[i], ep->d_name);
- closedir(dir);
- }
-
- return 0;
+ int i;
+ DIR *dir;
+ struct dirent *ep;
+
+ for (i = 1; i < argc; ++i) {
+ dir = opendir(argv[i]);
+ if (!dir)
+ continue;
+ while (ep = readdir(dir))
+ if (strchr("\\/:", argv[i][strlen(argv[i]) - 1]))
+ printf("%s%s\n", argv[i], ep->d_name);
+ else
+ printf("%s/%s\n", argv[i], ep->d_name);
+ closedir(dir);
+ }
+
+ return 0;
}
#endif
#endif /* OS2 */
-
diff --git a/nss/lib/dbm/src/dirent.h b/nss/lib/dbm/src/dirent.h
index 07a6c0a..0b4ae5d 100644
--- a/nss/lib/dbm/src/dirent.h
+++ b/nss/lib/dbm/src/dirent.h
@@ -13,8 +13,8 @@
*
* Some modifications by Martin Junius 02-14-89
*
- * AK900712
- * AK910410 abs_path - make absolute path
+ * AK900712
+ * AK910410 abs_path - make absolute path
*
*/
@@ -24,9 +24,9 @@
#if defined(__IBMC__) || defined(__IBMCPP__) || defined(XP_W32_MSVC)
#include <stdio.h>
#ifdef MAXPATHLEN
- #undef MAXPATHLEN
+#undef MAXPATHLEN
#endif
-#define MAXPATHLEN (FILENAME_MAX*4)
+#define MAXPATHLEN (FILENAME_MAX * 4)
#define MAXNAMLEN FILENAME_MAX
#else
@@ -40,54 +40,54 @@ extern "C" {
/* attribute stuff */
#ifndef A_RONLY
-# define A_RONLY 0x01
-# define A_HIDDEN 0x02
-# define A_SYSTEM 0x04
-# define A_LABEL 0x08
-# define A_DIR 0x10
-# define A_ARCHIVE 0x20
+#define A_RONLY 0x01
+#define A_HIDDEN 0x02
+#define A_SYSTEM 0x04
+#define A_LABEL 0x08
+#define A_DIR 0x10
+#define A_ARCHIVE 0x20
#endif
struct dirent {
-#if defined(OS2) || defined(WIN32) /* use the layout of EMX to avoid trouble */
- int d_ino; /* Dummy */
- int d_reclen; /* Dummy, same as d_namlen */
- int d_namlen; /* length of name */
- char d_name[MAXNAMLEN + 1];
- unsigned long d_size;
- unsigned short d_attribute; /* attributes (see above) */
- unsigned short d_time; /* modification time */
- unsigned short d_date; /* modification date */
+#if defined(OS2) || defined(WIN32) /* use the layout of EMX to avoid trouble */
+ int d_ino; /* Dummy */
+ int d_reclen; /* Dummy, same as d_namlen */
+ int d_namlen; /* length of name */
+ char d_name[MAXNAMLEN + 1];
+ unsigned long d_size;
+ unsigned short d_attribute; /* attributes (see above) */
+ unsigned short d_time; /* modification time */
+ unsigned short d_date; /* modification date */
#else
- char d_name[MAXNAMLEN + 1]; /* garentee null termination */
- char d_attribute; /* .. extension .. */
- unsigned long d_size; /* .. extension .. */
+ char d_name[MAXNAMLEN + 1]; /* garentee null termination */
+ char d_attribute; /* .. extension .. */
+ unsigned long d_size; /* .. extension .. */
#endif
};
typedef struct _dirdescr DIR;
/* the structs do not have to be defined here */
-extern DIR *opendir(const char *);
-extern DIR *openxdir(const char *, unsigned);
-extern struct dirent *readdir(DIR *);
-extern void seekdir(DIR *, long);
-extern long telldir(DIR *);
-extern void closedir(DIR *);
-#define rewinddir(dirp) seekdir(dirp, 0L)
+extern DIR *opendir(const char *);
+extern DIR *openxdir(const char *, unsigned);
+extern struct dirent *readdir(DIR *);
+extern void seekdir(DIR *, long);
+extern long telldir(DIR *);
+extern void closedir(DIR *);
+#define rewinddir(dirp) seekdir(dirp, 0L)
-extern char * abs_path(const char *name, char *buffer, int len);
+extern char *abs_path(const char *name, char *buffer, int len);
#ifndef S_IFMT
-#define S_IFMT ( S_IFDIR | S_IFREG )
+#define S_IFMT (S_IFDIR | S_IFREG)
#endif
#ifndef S_ISDIR
-#define S_ISDIR( m ) (((m) & S_IFMT) == S_IFDIR)
+#define S_ISDIR(m) (((m)&S_IFMT) == S_IFDIR)
#endif
#ifndef S_ISREG
-#define S_ISREG( m ) (((m) & S_IFMT) == S_IFREG)
+#define S_ISREG(m) (((m)&S_IFMT) == S_IFREG)
#endif
#ifdef __cplusplus
diff --git a/nss/lib/dbm/src/h_bigkey.c b/nss/lib/dbm/src/h_bigkey.c
index ed0c502..6edfe7f 100644
--- a/nss/lib/dbm/src/h_bigkey.c
+++ b/nss/lib/dbm/src/h_bigkey.c
@@ -1,6 +1,6 @@
/*-
* Copyright (c) 1990, 1993, 1994
- * The Regents of the University of California. All rights reserved.
+ * The Regents of the University of California. All rights reserved.
*
* This code is derived from software contributed to Berkeley by
* Margo Seltzer.
@@ -13,7 +13,7 @@
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
- * 3. ***REMOVED*** - see
+ * 3. ***REMOVED*** - see
* ftp://ftp.cs.berkeley.edu/pub/4bsd/README.Impt.License.Change
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
@@ -33,25 +33,25 @@
*/
#if defined(LIBC_SCCS) && !defined(lint)
-static char sccsid[] = "@(#)hash_bigkey.c 8.3 (Berkeley) 5/31/94";
+static char sccsid[] = "@(#)hash_bigkey.c 8.3 (Berkeley) 5/31/94";
#endif /* LIBC_SCCS and not lint */
/*
* PACKAGE: hash
* DESCRIPTION:
- * Big key/data handling for the hashing package.
+ * Big key/data handling for the hashing package.
*
* ROUTINES:
* External
- * __big_keydata
- * __big_split
- * __big_insert
- * __big_return
- * __big_delete
- * __find_last_page
+ * __big_keydata
+ * __big_split
+ * __big_insert
+ * __big_return
+ * __big_delete
+ * __find_last_page
* Internal
- * collect_key
- * collect_data
+ * collect_key
+ * collect_data
*/
#if !defined(_WIN32) && !defined(_WINDOWS) && !defined(macintosh)
@@ -87,87 +87,87 @@ static int collect_data(HTAB *, BUFHEAD *, int, int);
extern int
__big_insert(HTAB *hashp, BUFHEAD *bufp, const DBT *key, const DBT *val)
{
- register uint16 *p;
- uint key_size, n, val_size;
- uint16 space, move_bytes, off;
- char *cp, *key_data, *val_data;
-
- cp = bufp->page; /* Character pointer of p. */
- p = (uint16 *)cp;
-
- key_data = (char *)key->data;
- key_size = key->size;
- val_data = (char *)val->data;
- val_size = val->size;
-
- /* First move the Key */
- for (space = FREESPACE(p) - BIGOVERHEAD; key_size;
- space = FREESPACE(p) - BIGOVERHEAD) {
- move_bytes = PR_MIN(space, key_size);
- off = OFFSET(p) - move_bytes;
- memmove(cp + off, key_data, move_bytes);
- key_size -= move_bytes;
- key_data += move_bytes;
- n = p[0];
- p[++n] = off;
- p[0] = ++n;
- FREESPACE(p) = off - PAGE_META(n);
- OFFSET(p) = off;
- p[n] = PARTIAL_KEY;
- bufp = __add_ovflpage(hashp, bufp);
- if (!bufp)
- return (-1);
- n = p[0];
- if (!key_size) {
- if (FREESPACE(p)) {
- move_bytes = PR_MIN(FREESPACE(p), val_size);
- off = OFFSET(p) - move_bytes;
- p[n] = off;
- memmove(cp + off, val_data, move_bytes);
- val_data += move_bytes;
- val_size -= move_bytes;
- p[n - 2] = FULL_KEY_DATA;
- FREESPACE(p) = FREESPACE(p) - move_bytes;
- OFFSET(p) = off;
- } else
- p[n - 2] = FULL_KEY;
- }
- p = (uint16 *)bufp->page;
- cp = bufp->page;
- bufp->flags |= BUF_MOD;
- }
-
- /* Now move the data */
- for (space = FREESPACE(p) - BIGOVERHEAD; val_size;
- space = FREESPACE(p) - BIGOVERHEAD) {
- move_bytes = PR_MIN(space, val_size);
- /*
- * Here's the hack to make sure that if the data ends on the
- * same page as the key ends, FREESPACE is at least one.
- */
- if (space == val_size && val_size == val->size)
- move_bytes--;
- off = OFFSET(p) - move_bytes;
- memmove(cp + off, val_data, move_bytes);
- val_size -= move_bytes;
- val_data += move_bytes;
- n = p[0];
- p[++n] = off;
- p[0] = ++n;
- FREESPACE(p) = off - PAGE_META(n);
- OFFSET(p) = off;
- if (val_size) {
- p[n] = FULL_KEY;
- bufp = __add_ovflpage(hashp, bufp);
- if (!bufp)
- return (-1);
- cp = bufp->page;
- p = (uint16 *)cp;
- } else
- p[n] = FULL_KEY_DATA;
- bufp->flags |= BUF_MOD;
- }
- return (0);
+ register uint16 *p;
+ uint key_size, n, val_size;
+ uint16 space, move_bytes, off;
+ char *cp, *key_data, *val_data;
+
+ cp = bufp->page; /* Character pointer of p. */
+ p = (uint16 *)cp;
+
+ key_data = (char *)key->data;
+ key_size = key->size;
+ val_data = (char *)val->data;
+ val_size = val->size;
+
+ /* First move the Key */
+ for (space = FREESPACE(p) - BIGOVERHEAD; key_size;
+ space = FREESPACE(p) - BIGOVERHEAD) {
+ move_bytes = PR_MIN(space, key_size);
+ off = OFFSET(p) - move_bytes;
+ memmove(cp + off, key_data, move_bytes);
+ key_size -= move_bytes;
+ key_data += move_bytes;
+ n = p[0];
+ p[++n] = off;
+ p[0] = ++n;
+ FREESPACE(p) = off - PAGE_META(n);
+ OFFSET(p) = off;
+ p[n] = PARTIAL_KEY;
+ bufp = __add_ovflpage(hashp, bufp);
+ if (!bufp)
+ return (-1);
+ n = p[0];
+ if (!key_size) {
+ if (FREESPACE(p)) {
+ move_bytes = PR_MIN(FREESPACE(p), val_size);
+ off = OFFSET(p) - move_bytes;
+ p[n] = off;
+ memmove(cp + off, val_data, move_bytes);
+ val_data += move_bytes;
+ val_size -= move_bytes;
+ p[n - 2] = FULL_KEY_DATA;
+ FREESPACE(p) = FREESPACE(p) - move_bytes;
+ OFFSET(p) = off;
+ } else
+ p[n - 2] = FULL_KEY;
+ }
+ p = (uint16 *)bufp->page;
+ cp = bufp->page;
+ bufp->flags |= BUF_MOD;
+ }
+
+ /* Now move the data */
+ for (space = FREESPACE(p) - BIGOVERHEAD; val_size;
+ space = FREESPACE(p) - BIGOVERHEAD) {
+ move_bytes = PR_MIN(space, val_size);
+ /*
+ * Here's the hack to make sure that if the data ends on the
+ * same page as the key ends, FREESPACE is at least one.
+ */
+ if (space == val_size && val_size == val->size)
+ move_bytes--;
+ off = OFFSET(p) - move_bytes;
+ memmove(cp + off, val_data, move_bytes);
+ val_size -= move_bytes;
+ val_data += move_bytes;
+ n = p[0];
+ p[++n] = off;
+ p[0] = ++n;
+ FREESPACE(p) = off - PAGE_META(n);
+ OFFSET(p) = off;
+ if (val_size) {
+ p[n] = FULL_KEY;
+ bufp = __add_ovflpage(hashp, bufp);
+ if (!bufp)
+ return (-1);
+ cp = bufp->page;
+ p = (uint16 *)cp;
+ } else
+ p[n] = FULL_KEY_DATA;
+ bufp->flags |= BUF_MOD;
+ }
+ return (0);
}
/*
@@ -184,72 +184,72 @@ __big_insert(HTAB *hashp, BUFHEAD *bufp, const DBT *key, const DBT *val)
extern int
__big_delete(HTAB *hashp, BUFHEAD *bufp)
{
- register BUFHEAD *last_bfp, *rbufp;
- uint16 *bp, pageno;
- int key_done, n;
-
- rbufp = bufp;
- last_bfp = NULL;
- bp = (uint16 *)bufp->page;
- pageno = 0;
- key_done = 0;
-
- while (!key_done || (bp[2] != FULL_KEY_DATA)) {
- if (bp[2] == FULL_KEY || bp[2] == FULL_KEY_DATA)
- key_done = 1;
-
- /*
- * If there is freespace left on a FULL_KEY_DATA page, then
- * the data is short and fits entirely on this page, and this
- * is the last page.
- */
- if (bp[2] == FULL_KEY_DATA && FREESPACE(bp))
- break;
- pageno = bp[bp[0] - 1];
- rbufp->flags |= BUF_MOD;
- rbufp = __get_buf(hashp, pageno, rbufp, 0);
- if (last_bfp)
- __free_ovflpage(hashp, last_bfp);
- last_bfp = rbufp;
- if (!rbufp)
- return (-1); /* Error. */
- bp = (uint16 *)rbufp->page;
- }
-
- /*
- * If we get here then rbufp points to the last page of the big
- * key/data pair. Bufp points to the first one -- it should now be
- * empty pointing to the next page after this pair. Can't free it
- * because we don't have the page pointing to it.
- */
-
- /* This is information from the last page of the pair. */
- n = bp[0];
- pageno = bp[n - 1];
-
- /* Now, bp is the first page of the pair. */
- bp = (uint16 *)bufp->page;
- if (n > 2) {
- /* There is an overflow page. */
- bp[1] = pageno;
- bp[2] = OVFLPAGE;
- bufp->ovfl = rbufp->ovfl;
- } else
- /* This is the last page. */
- bufp->ovfl = NULL;
- n -= 2;
- bp[0] = n;
- FREESPACE(bp) = hashp->BSIZE - PAGE_META(n);
- OFFSET(bp) = hashp->BSIZE - 1;
-
- bufp->flags |= BUF_MOD;
- if (rbufp)
- __free_ovflpage(hashp, rbufp);
- if (last_bfp != rbufp)
- __free_ovflpage(hashp, last_bfp);
-
- hashp->NKEYS--;
- return (0);
+ register BUFHEAD *last_bfp, *rbufp;
+ uint16 *bp, pageno;
+ int key_done, n;
+
+ rbufp = bufp;
+ last_bfp = NULL;
+ bp = (uint16 *)bufp->page;
+ pageno = 0;
+ key_done = 0;
+
+ while (!key_done || (bp[2] != FULL_KEY_DATA)) {
+ if (bp[2] == FULL_KEY || bp[2] == FULL_KEY_DATA)
+ key_done = 1;
+
+ /*
+ * If there is freespace left on a FULL_KEY_DATA page, then
+ * the data is short and fits entirely on this page, and this
+ * is the last page.
+ */
+ if (bp[2] == FULL_KEY_DATA && FREESPACE(bp))
+ break;
+ pageno = bp[bp[0] - 1];
+ rbufp->flags |= BUF_MOD;
+ rbufp = __get_buf(hashp, pageno, rbufp, 0);
+ if (last_bfp)
+ __free_ovflpage(hashp, last_bfp);
+ last_bfp = rbufp;
+ if (!rbufp)
+ return (-1); /* Error. */
+ bp = (uint16 *)rbufp->page;
+ }
+
+ /*
+ * If we get here then rbufp points to the last page of the big
+ * key/data pair. Bufp points to the first one -- it should now be
+ * empty pointing to the next page after this pair. Can't free it
+ * because we don't have the page pointing to it.
+ */
+
+ /* This is information from the last page of the pair. */
+ n = bp[0];
+ pageno = bp[n - 1];
+
+ /* Now, bp is the first page of the pair. */
+ bp = (uint16 *)bufp->page;
+ if (n > 2) {
+ /* There is an overflow page. */
+ bp[1] = pageno;
+ bp[2] = OVFLPAGE;
+ bufp->ovfl = rbufp->ovfl;
+ } else
+ /* This is the last page. */
+ bufp->ovfl = NULL;
+ n -= 2;
+ bp[0] = n;
+ FREESPACE(bp) = hashp->BSIZE - PAGE_META(n);
+ OFFSET(bp) = hashp->BSIZE - 1;
+
+ bufp->flags |= BUF_MOD;
+ if (rbufp)
+ __free_ovflpage(hashp, rbufp);
+ if (last_bfp != rbufp)
+ __free_ovflpage(hashp, last_bfp);
+
+ hashp->NKEYS--;
+ return (0);
}
/*
* Returns:
@@ -261,39 +261,39 @@ __big_delete(HTAB *hashp, BUFHEAD *bufp)
extern int
__find_bigpair(HTAB *hashp, BUFHEAD *bufp, int ndx, char *key, int size)
{
- register uint16 *bp;
- register char *p;
- int ksize;
- uint16 bytes;
- char *kkey;
-
- bp = (uint16 *)bufp->page;
- p = bufp->page;
- ksize = size;
- kkey = key;
-
- for (bytes = hashp->BSIZE - bp[ndx];
- bytes <= size && bp[ndx + 1] == PARTIAL_KEY;
- bytes = hashp->BSIZE - bp[ndx]) {
- if (memcmp(p + bp[ndx], kkey, bytes))
- return (-2);
- kkey += bytes;
- ksize -= bytes;
- bufp = __get_buf(hashp, bp[ndx + 2], bufp, 0);
- if (!bufp)
- return (-3);
- p = bufp->page;
- bp = (uint16 *)p;
- ndx = 1;
- }
-
- if (bytes != ksize || memcmp(p + bp[ndx], kkey, bytes)) {
+ register uint16 *bp;
+ register char *p;
+ int ksize;
+ uint16 bytes;
+ char *kkey;
+
+ bp = (uint16 *)bufp->page;
+ p = bufp->page;
+ ksize = size;
+ kkey = key;
+
+ for (bytes = hashp->BSIZE - bp[ndx];
+ bytes <= size && bp[ndx + 1] == PARTIAL_KEY;
+ bytes = hashp->BSIZE - bp[ndx]) {
+ if (memcmp(p + bp[ndx], kkey, bytes))
+ return (-2);
+ kkey += bytes;
+ ksize -= bytes;
+ bufp = __get_buf(hashp, bp[ndx + 2], bufp, 0);
+ if (!bufp)
+ return (-3);
+ p = bufp->page;
+ bp = (uint16 *)p;
+ ndx = 1;
+ }
+
+ if (bytes != ksize || memcmp(p + bp[ndx], kkey, bytes)) {
#ifdef HASH_STATISTICS
- ++hash_collisions;
+ ++hash_collisions;
#endif
- return (-2);
- } else
- return (ndx);
+ return (-2);
+ } else
+ return (ndx);
}
/*
@@ -308,41 +308,41 @@ __find_bigpair(HTAB *hashp, BUFHEAD *bufp, int ndx, char *key, int size)
extern uint16
__find_last_page(HTAB *hashp, BUFHEAD **bpp)
{
- BUFHEAD *bufp;
- uint16 *bp, pageno;
- uint n;
-
- bufp = *bpp;
- bp = (uint16 *)bufp->page;
- for (;;) {
- n = bp[0];
-
- /*
- * This is the last page if: the tag is FULL_KEY_DATA and
- * either only 2 entries OVFLPAGE marker is explicit there
- * is freespace on the page.
- */
- if (bp[2] == FULL_KEY_DATA &&
- ((n == 2) || (bp[n] == OVFLPAGE) || (FREESPACE(bp))))
- break;
-
- /* LJM bound the size of n to reasonable limits
- */
- if(n > hashp->BSIZE/sizeof(uint16))
- return(0);
-
- pageno = bp[n - 1];
- bufp = __get_buf(hashp, pageno, bufp, 0);
- if (!bufp)
- return (0); /* Need to indicate an error! */
- bp = (uint16 *)bufp->page;
- }
-
- *bpp = bufp;
- if (bp[0] > 2)
- return (bp[3]);
- else
- return (0);
+ BUFHEAD *bufp;
+ uint16 *bp, pageno;
+ uint n;
+
+ bufp = *bpp;
+ bp = (uint16 *)bufp->page;
+ for (;;) {
+ n = bp[0];
+
+ /*
+ * This is the last page if: the tag is FULL_KEY_DATA and
+ * either only 2 entries OVFLPAGE marker is explicit there
+ * is freespace on the page.
+ */
+ if (bp[2] == FULL_KEY_DATA &&
+ ((n == 2) || (bp[n] == OVFLPAGE) || (FREESPACE(bp))))
+ break;
+
+ /* LJM bound the size of n to reasonable limits
+ */
+ if (n > hashp->BSIZE / sizeof(uint16))
+ return (0);
+
+ pageno = bp[n - 1];
+ bufp = __get_buf(hashp, pageno, bufp, 0);
+ if (!bufp)
+ return (0); /* Need to indicate an error! */
+ bp = (uint16 *)bufp->page;
+ }
+
+ *bpp = bufp;
+ if (bp[0] > 2)
+ return (bp[3]);
+ else
+ return (0);
}
/*
@@ -351,99 +351,97 @@ __find_last_page(HTAB *hashp, BUFHEAD **bpp)
*/
extern int
__big_return(
- HTAB *hashp,
- BUFHEAD *bufp,
- int ndx,
- DBT *val,
- int set_current)
+ HTAB *hashp,
+ BUFHEAD *bufp,
+ int ndx,
+ DBT *val,
+ int set_current)
{
- BUFHEAD *save_p;
- uint16 *bp, len, off, save_addr;
- char *tp;
- int save_flags;
-
- bp = (uint16 *)bufp->page;
- while (bp[ndx + 1] == PARTIAL_KEY) {
- bufp = __get_buf(hashp, bp[bp[0] - 1], bufp, 0);
- if (!bufp)
- return (-1);
- bp = (uint16 *)bufp->page;
- ndx = 1;
- }
-
- if (bp[ndx + 1] == FULL_KEY) {
- bufp = __get_buf(hashp, bp[bp[0] - 1], bufp, 0);
- if (!bufp)
- return (-1);
- bp = (uint16 *)bufp->page;
- save_p = bufp;
- save_addr = save_p->addr;
- off = bp[1];
- len = 0;
- } else
- if (!FREESPACE(bp)) {
- /*
- * This is a hack. We can't distinguish between
- * FULL_KEY_DATA that contains complete data or
- * incomplete data, so we require that if the data
- * is complete, there is at least 1 byte of free
- * space left.
- */
- off = bp[bp[0]];
- len = bp[1] - off;
- save_p = bufp;
- save_addr = bufp->addr;
- bufp = __get_buf(hashp, bp[bp[0] - 1], bufp, 0);
- if (!bufp)
- return (-1);
- bp = (uint16 *)bufp->page;
- } else {
- /* The data is all on one page. */
- tp = (char *)bp;
- off = bp[bp[0]];
- val->data = (uint8 *)tp + off;
- val->size = bp[1] - off;
- if (set_current) {
- if (bp[0] == 2) { /* No more buckets in
- * chain */
- hashp->cpage = NULL;
- hashp->cbucket++;
- hashp->cndx = 1;
- } else {
- hashp->cpage = __get_buf(hashp,
- bp[bp[0] - 1], bufp, 0);
- if (!hashp->cpage)
- return (-1);
- hashp->cndx = 1;
- if (!((uint16 *)
- hashp->cpage->page)[0]) {
- hashp->cbucket++;
- hashp->cpage = NULL;
- }
- }
- }
- return (0);
- }
-
- /* pin our saved buf so that we don't lose if
- * we run out of buffers */
- save_flags = save_p->flags;
- save_p->flags |= BUF_PIN;
- val->size = collect_data(hashp, bufp, (int)len, set_current);
- save_p->flags = save_flags;
- if (val->size == (size_t)-1)
- return (-1);
- if (save_p->addr != save_addr) {
- /* We are pretty short on buffers. */
- errno = EINVAL; /* OUT OF BUFFERS */
- return (-1);
- }
- memmove(hashp->tmp_buf, (save_p->page) + off, len);
- val->data = (uint8 *)hashp->tmp_buf;
- return (0);
+ BUFHEAD *save_p;
+ uint16 *bp, len, off, save_addr;
+ char *tp;
+ int save_flags;
+
+ bp = (uint16 *)bufp->page;
+ while (bp[ndx + 1] == PARTIAL_KEY) {
+ bufp = __get_buf(hashp, bp[bp[0] - 1], bufp, 0);
+ if (!bufp)
+ return (-1);
+ bp = (uint16 *)bufp->page;
+ ndx = 1;
+ }
+
+ if (bp[ndx + 1] == FULL_KEY) {
+ bufp = __get_buf(hashp, bp[bp[0] - 1], bufp, 0);
+ if (!bufp)
+ return (-1);
+ bp = (uint16 *)bufp->page;
+ save_p = bufp;
+ save_addr = save_p->addr;
+ off = bp[1];
+ len = 0;
+ } else if (!FREESPACE(bp)) {
+ /*
+ * This is a hack. We can't distinguish between
+ * FULL_KEY_DATA that contains complete data or
+ * incomplete data, so we require that if the data
+ * is complete, there is at least 1 byte of free
+ * space left.
+ */
+ off = bp[bp[0]];
+ len = bp[1] - off;
+ save_p = bufp;
+ save_addr = bufp->addr;
+ bufp = __get_buf(hashp, bp[bp[0] - 1], bufp, 0);
+ if (!bufp)
+ return (-1);
+ bp = (uint16 *)bufp->page;
+ } else {
+ /* The data is all on one page. */
+ tp = (char *)bp;
+ off = bp[bp[0]];
+ val->data = (uint8 *)tp + off;
+ val->size = bp[1] - off;
+ if (set_current) {
+ if (bp[0] == 2) { /* No more buckets in
+ * chain */
+ hashp->cpage = NULL;
+ hashp->cbucket++;
+ hashp->cndx = 1;
+ } else {
+ hashp->cpage = __get_buf(hashp,
+ bp[bp[0] - 1], bufp, 0);
+ if (!hashp->cpage)
+ return (-1);
+ hashp->cndx = 1;
+ if (!((uint16 *)
+ hashp->cpage->page)[0]) {
+ hashp->cbucket++;
+ hashp->cpage = NULL;
+ }
+ }
+ }
+ return (0);
+ }
+
+ /* pin our saved buf so that we don't lose if
+ * we run out of buffers */
+ save_flags = save_p->flags;
+ save_p->flags |= BUF_PIN;
+ val->size = collect_data(hashp, bufp, (int)len, set_current);
+ save_p->flags = save_flags;
+ if (val->size == (size_t)-1)
+ return (-1);
+ if (save_p->addr != save_addr) {
+ /* We are pretty short on buffers. */
+ errno = EINVAL; /* OUT OF BUFFERS */
+ return (-1);
+ }
+ memmove(hashp->tmp_buf, (save_p->page) + off, len);
+ val->data = (uint8 *)hashp->tmp_buf;
+ return (0);
}
-
/*
* Count how big the total datasize is by looping through the pages. Then
* allocate a buffer and copy the data in the second loop. NOTE: Our caller
@@ -453,87 +451,87 @@ __big_return(
*/
static int
collect_data(
- HTAB *hashp,
- BUFHEAD *bufp,
- int len, int set)
+ HTAB *hashp,
+ BUFHEAD *bufp,
+ int len, int set)
{
- register uint16 *bp;
- BUFHEAD *save_bufp;
- int save_flags;
- int mylen, totlen;
-
- /*
- * save the input buf head because we need to walk the list twice.
- * pin it to make sure it doesn't leave the buffer pool.
- * This has the effect of growing the buffer pool if necessary.
- */
- save_bufp = bufp;
- save_flags = save_bufp->flags;
- save_bufp->flags |= BUF_PIN;
-
- /* read the length of the buffer */
- for (totlen = len; bufp ; bufp = __get_buf(hashp, bp[bp[0]-1], bufp, 0)) {
- bp = (uint16 *)bufp->page;
- mylen = hashp->BSIZE - bp[1];
-
- /* if mylen ever goes negative it means that the
- * page is screwed up.
- */
- if (mylen < 0) {
- save_bufp->flags = save_flags;
- return (-1);
- }
- totlen += mylen;
- if (bp[2] == FULL_KEY_DATA) { /* End of Data */
- break;
- }
- }
-
- if (!bufp) {
- save_bufp->flags = save_flags;
- return (-1);
- }
-
- /* allocate a temp buf */
- if (hashp->tmp_buf)
- free(hashp->tmp_buf);
- if ((hashp->tmp_buf = (char *)malloc((size_t)totlen)) == NULL) {
- save_bufp->flags = save_flags;
- return (-1);
- }
-
- /* copy the buffers back into temp buf */
- for (bufp = save_bufp; bufp ;
- bufp = __get_buf(hashp, bp[bp[0]-1], bufp, 0)) {
- bp = (uint16 *)bufp->page;
- mylen = hashp->BSIZE - bp[1];
- memmove(&hashp->tmp_buf[len], (bufp->page) + bp[1], (size_t)mylen);
- len += mylen;
- if (bp[2] == FULL_KEY_DATA) {
- break;
- }
- }
-
- /* 'clear' the pin flags */
- save_bufp->flags = save_flags;
-
- /* update the database cursor */
- if (set) {
- hashp->cndx = 1;
- if (bp[0] == 2) { /* No more buckets in chain */
- hashp->cpage = NULL;
- hashp->cbucket++;
- } else {
- hashp->cpage = __get_buf(hashp, bp[bp[0] - 1], bufp, 0);
- if (!hashp->cpage)
- return (-1);
- else if (!((uint16 *)hashp->cpage->page)[0]) {
- hashp->cbucket++;
- hashp->cpage = NULL;
- }
- }
- }
- return (totlen);
+ register uint16 *bp;
+ BUFHEAD *save_bufp;
+ int save_flags;
+ int mylen, totlen;
+
+ /*
+ * save the input buf head because we need to walk the list twice.
+ * pin it to make sure it doesn't leave the buffer pool.
+ * This has the effect of growing the buffer pool if necessary.
+ */
+ save_bufp = bufp;
+ save_flags = save_bufp->flags;
+ save_bufp->flags |= BUF_PIN;
+
+ /* read the length of the buffer */
+ for (totlen = len; bufp; bufp = __get_buf(hashp, bp[bp[0] - 1], bufp, 0)) {
+ bp = (uint16 *)bufp->page;
+ mylen = hashp->BSIZE - bp[1];
+
+ /* if mylen ever goes negative it means that the
+ * page is screwed up.
+ */
+ if (mylen < 0) {
+ save_bufp->flags = save_flags;
+ return (-1);
+ }
+ totlen += mylen;
+ if (bp[2] == FULL_KEY_DATA) { /* End of Data */
+ break;
+ }
+ }
+
+ if (!bufp) {
+ save_bufp->flags = save_flags;
+ return (-1);
+ }
+
+ /* allocate a temp buf */
+ if (hashp->tmp_buf)
+ free(hashp->tmp_buf);
+ if ((hashp->tmp_buf = (char *)malloc((size_t)totlen)) == NULL) {
+ save_bufp->flags = save_flags;
+ return (-1);
+ }
+
+ /* copy the buffers back into temp buf */
+ for (bufp = save_bufp; bufp;
+ bufp = __get_buf(hashp, bp[bp[0] - 1], bufp, 0)) {
+ bp = (uint16 *)bufp->page;
+ mylen = hashp->BSIZE - bp[1];
+ memmove(&hashp->tmp_buf[len], (bufp->page) + bp[1], (size_t)mylen);
+ len += mylen;
+ if (bp[2] == FULL_KEY_DATA) {
+ break;
+ }
+ }
+
+ /* 'clear' the pin flags */
+ save_bufp->flags = save_flags;
+
+ /* update the database cursor */
+ if (set) {
+ hashp->cndx = 1;
+ if (bp[0] == 2) { /* No more buckets in chain */
+ hashp->cpage = NULL;
+ hashp->cbucket++;
+ } else {
+ hashp->cpage = __get_buf(hashp, bp[bp[0] - 1], bufp, 0);
+ if (!hashp->cpage)
+ return (-1);
+ else if (!((uint16 *)hashp->cpage->page)[0]) {
+ hashp->cbucket++;
+ hashp->cpage = NULL;
+ }
+ }
+ }
+ return (totlen);
}
/*
@@ -541,16 +539,16 @@ collect_data(
*/
extern int
__big_keydata(
- HTAB *hashp,
- BUFHEAD *bufp,
- DBT *key, DBT *val,
- int set)
+ HTAB *hashp,
+ BUFHEAD *bufp,
+ DBT *key, DBT *val,
+ int set)
{
- key->size = collect_key(hashp, bufp, 0, val, set);
- if (key->size == (size_t)-1)
- return (-1);
- key->data = (uint8 *)hashp->tmp_key;
- return (0);
+ key->size = collect_key(hashp, bufp, 0, val, set);
+ if (key->size == (size_t)-1)
+ return (-1);
+ key->data = (uint8 *)hashp->tmp_key;
+ return (0);
}
/*
@@ -559,42 +557,42 @@ __big_keydata(
*/
static int
collect_key(
- HTAB *hashp,
- BUFHEAD *bufp,
- int len,
- DBT *val,
- int set)
+ HTAB *hashp,
+ BUFHEAD *bufp,
+ int len,
+ DBT *val,
+ int set)
{
- BUFHEAD *xbp;
- char *p;
- int mylen, totlen;
- uint16 *bp, save_addr;
-
- p = bufp->page;
- bp = (uint16 *)p;
- mylen = hashp->BSIZE - bp[1];
-
- save_addr = bufp->addr;
- totlen = len + mylen;
- if (bp[2] == FULL_KEY || bp[2] == FULL_KEY_DATA) { /* End of Key. */
- if (hashp->tmp_key != NULL)
- free(hashp->tmp_key);
- if ((hashp->tmp_key = (char *)malloc((size_t)totlen)) == NULL)
- return (-1);
- if (__big_return(hashp, bufp, 1, val, set))
- return (-1);
- } else {
- xbp = __get_buf(hashp, bp[bp[0] - 1], bufp, 0);
- if (!xbp || ((totlen =
- collect_key(hashp, xbp, totlen, val, set)) < 1))
- return (-1);
- }
- if (bufp->addr != save_addr) {
- errno = EINVAL; /* MIS -- OUT OF BUFFERS */
- return (-1);
- }
- memmove(&hashp->tmp_key[len], (bufp->page) + bp[1], (size_t)mylen);
- return (totlen);
+ BUFHEAD *xbp;
+ char *p;
+ int mylen, totlen;
+ uint16 *bp, save_addr;
+
+ p = bufp->page;
+ bp = (uint16 *)p;
+ mylen = hashp->BSIZE - bp[1];
+
+ save_addr = bufp->addr;
+ totlen = len + mylen;
+ if (bp[2] == FULL_KEY || bp[2] == FULL_KEY_DATA) { /* End of Key. */
+ if (hashp->tmp_key != NULL)
+ free(hashp->tmp_key);
+ if ((hashp->tmp_key = (char *)malloc((size_t)totlen)) == NULL)
+ return (-1);
+ if (__big_return(hashp, bufp, 1, val, set))
+ return (-1);
+ } else {
+ xbp = __get_buf(hashp, bp[bp[0] - 1], bufp, 0);
+ if (!xbp || ((totlen =
+ collect_key(hashp, xbp, totlen, val, set)) < 1))
+ return (-1);
+ }
+ if (bufp->addr != save_addr) {
+ errno = EINVAL; /* MIS -- OUT OF BUFFERS */
+ return (-1);
+ }
+ memmove(&hashp->tmp_key[len], (bufp->page) + bp[1], (size_t)mylen);
+ return (totlen);
}
/*
@@ -604,106 +602,106 @@ collect_key(
*/
extern int
__big_split(
- HTAB *hashp,
- BUFHEAD *op, /* Pointer to where to put keys that go in old bucket */
- BUFHEAD *np, /* Pointer to new bucket page */
- /* Pointer to first page containing the big key/data */
- BUFHEAD *big_keyp,
- uint32 addr, /* Address of big_keyp */
- uint32 obucket,/* Old Bucket */
- SPLIT_RETURN *ret)
+ HTAB *hashp,
+ BUFHEAD *op, /* Pointer to where to put keys that go in old bucket */
+ BUFHEAD *np, /* Pointer to new bucket page */
+ /* Pointer to first page containing the big key/data */
+ BUFHEAD *big_keyp,
+ uint32 addr, /* Address of big_keyp */
+ uint32 obucket, /* Old Bucket */
+ SPLIT_RETURN *ret)
{
- register BUFHEAD *tmpp;
- register uint16 *tp;
- BUFHEAD *bp;
- DBT key, val;
- uint32 change;
- uint16 free_space, n, off;
-
- bp = big_keyp;
-
- /* Now figure out where the big key/data goes */
- if (__big_keydata(hashp, big_keyp, &key, &val, 0))
- return (-1);
- change = (__call_hash(hashp,(char*) key.data, key.size) != obucket);
-
- if ((ret->next_addr = __find_last_page(hashp, &big_keyp))) {
- if (!(ret->nextp =
- __get_buf(hashp, ret->next_addr, big_keyp, 0)))
- return (-1);;
- } else
- ret->nextp = NULL;
-
- /* Now make one of np/op point to the big key/data pair */
+ register BUFHEAD *tmpp;
+ register uint16 *tp;
+ BUFHEAD *bp;
+ DBT key, val;
+ uint32 change;
+ uint16 free_space, n, off;
+
+ bp = big_keyp;
+
+ /* Now figure out where the big key/data goes */
+ if (__big_keydata(hashp, big_keyp, &key, &val, 0))
+ return (-1);
+ change = (__call_hash(hashp, (char *)key.data, key.size) != obucket);
+
+ if ((ret->next_addr = __find_last_page(hashp, &big_keyp))) {
+ if (!(ret->nextp =
+ __get_buf(hashp, ret->next_addr, big_keyp, 0)))
+ return (-1);
+ ;
+ } else
+ ret->nextp = NULL;
+
+/* Now make one of np/op point to the big key/data pair */
#ifdef DEBUG
- assert(np->ovfl == NULL);
+ assert(np->ovfl == NULL);
#endif
- if (change)
- tmpp = np;
- else
- tmpp = op;
+ if (change)
+ tmpp = np;
+ else
+ tmpp = op;
- tmpp->flags |= BUF_MOD;
+ tmpp->flags |= BUF_MOD;
#ifdef DEBUG1
- (void)fprintf(stderr,
- "BIG_SPLIT: %d->ovfl was %d is now %d\n", tmpp->addr,
- (tmpp->ovfl ? tmpp->ovfl->addr : 0), (bp ? bp->addr : 0));
+ (void)fprintf(stderr,
+ "BIG_SPLIT: %d->ovfl was %d is now %d\n", tmpp->addr,
+ (tmpp->ovfl ? tmpp->ovfl->addr : 0), (bp ? bp->addr : 0));
#endif
- tmpp->ovfl = bp; /* one of op/np point to big_keyp */
- tp = (uint16 *)tmpp->page;
-
+ tmpp->ovfl = bp; /* one of op/np point to big_keyp */
+ tp = (uint16 *)tmpp->page;
-#if 0 /* this get's tripped on database corrupted error */
- assert(FREESPACE(tp) >= OVFLSIZE);
+#if 0 /* this get's tripped on database corrupted error */
+ assert(FREESPACE(tp) >= OVFLSIZE);
#endif
- if(FREESPACE(tp) < OVFLSIZE)
- return(DATABASE_CORRUPTED_ERROR);
-
- n = tp[0];
- off = OFFSET(tp);
- free_space = FREESPACE(tp);
- tp[++n] = (uint16)addr;
- tp[++n] = OVFLPAGE;
- tp[0] = n;
- OFFSET(tp) = off;
- FREESPACE(tp) = free_space - OVFLSIZE;
-
- /*
- * Finally, set the new and old return values. BIG_KEYP contains a
- * pointer to the last page of the big key_data pair. Make sure that
- * big_keyp has no following page (2 elements) or create an empty
- * following page.
- */
-
- ret->newp = np;
- ret->oldp = op;
-
- tp = (uint16 *)big_keyp->page;
- big_keyp->flags |= BUF_MOD;
- if (tp[0] > 2) {
- /*
- * There may be either one or two offsets on this page. If
- * there is one, then the overflow page is linked on normally
- * and tp[4] is OVFLPAGE. If there are two, tp[4] contains
- * the second offset and needs to get stuffed in after the
- * next overflow page is added.
- */
- n = tp[4];
- free_space = FREESPACE(tp);
- off = OFFSET(tp);
- tp[0] -= 2;
- FREESPACE(tp) = free_space + OVFLSIZE;
- OFFSET(tp) = off;
- tmpp = __add_ovflpage(hashp, big_keyp);
- if (!tmpp)
- return (-1);
- tp[4] = n;
- } else
- tmpp = big_keyp;
-
- if (change)
- ret->newp = tmpp;
- else
- ret->oldp = tmpp;
- return (0);
+ if (FREESPACE(tp) < OVFLSIZE)
+ return (DATABASE_CORRUPTED_ERROR);
+
+ n = tp[0];
+ off = OFFSET(tp);
+ free_space = FREESPACE(tp);
+ tp[++n] = (uint16)addr;
+ tp[++n] = OVFLPAGE;
+ tp[0] = n;
+ OFFSET(tp) = off;
+ FREESPACE(tp) = free_space - OVFLSIZE;
+
+ /*
+ * Finally, set the new and old return values. BIG_KEYP contains a
+ * pointer to the last page of the big key_data pair. Make sure that
+ * big_keyp has no following page (2 elements) or create an empty
+ * following page.
+ */
+
+ ret->newp = np;
+ ret->oldp = op;
+
+ tp = (uint16 *)big_keyp->page;
+ big_keyp->flags |= BUF_MOD;
+ if (tp[0] > 2) {
+ /*
+ * There may be either one or two offsets on this page. If
+ * there is one, then the overflow page is linked on normally
+ * and tp[4] is OVFLPAGE. If there are two, tp[4] contains
+ * the second offset and needs to get stuffed in after the
+ * next overflow page is added.
+ */
+ n = tp[4];
+ free_space = FREESPACE(tp);
+ off = OFFSET(tp);
+ tp[0] -= 2;
+ FREESPACE(tp) = free_space + OVFLSIZE;
+ OFFSET(tp) = off;
+ tmpp = __add_ovflpage(hashp, big_keyp);
+ if (!tmpp)
+ return (-1);
+ tp[4] = n;
+ } else
+ tmpp = big_keyp;
+
+ if (change)
+ ret->newp = tmpp;
+ else
+ ret->oldp = tmpp;
+ return (0);
}
diff --git a/nss/lib/dbm/src/h_func.c b/nss/lib/dbm/src/h_func.c
index 688a794..0d8734e 100644
--- a/nss/lib/dbm/src/h_func.c
+++ b/nss/lib/dbm/src/h_func.c
@@ -1,6 +1,6 @@
/*-
* Copyright (c) 1990, 1993
- * The Regents of the University of California. All rights reserved.
+ * The Regents of the University of California. All rights reserved.
*
* This code is derived from software contributed to Berkeley by
* Margo Seltzer.
@@ -13,7 +13,7 @@
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
- * 3. ***REMOVED*** - see
+ * 3. ***REMOVED*** - see
* ftp://ftp.cs.berkeley.edu/pub/4bsd/README.Impt.License.Change
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
@@ -33,7 +33,7 @@
*/
#if defined(LIBC_SCCS) && !defined(lint)
-static char sccsid[] = "@(#)hash_func.c 8.2 (Berkeley) 2/21/94";
+static char sccsid[] = "@(#)hash_func.c 8.2 (Berkeley) 2/21/94";
#endif /* LIBC_SCCS and not lint */
#ifndef macintosh
@@ -63,44 +63,44 @@ uint32 (*__default_hash)(const void *, size_t) = hash4;
* This came from ejb's hsearch.
*/
-#define PRIME1 37
-#define PRIME2 1048583
+#define PRIME1 37
+#define PRIME2 1048583
#if 0
static uint32
hash1(const void *keyarg, register size_t len)
{
- register const uint8 *key;
- register uint32 h;
-
- /* Convert string to integer */
- for (key = (const uint8 *)keyarg, h = 0; len--;)
- h = h * PRIME1 ^ (*key++ - ' ');
- h %= PRIME2;
- return (h);
+ register const uint8 *key;
+ register uint32 h;
+
+ /* Convert string to integer */
+ for (key = (const uint8 *)keyarg, h = 0; len--;)
+ h = h * PRIME1 ^ (*key++ - ' ');
+ h %= PRIME2;
+ return (h);
}
/*
* Phong's linear congruential hash
*/
-#define dcharhash(h, c) ((h) = 0x63c63cd9*(h) + 0x9c39c33d + (c))
+#define dcharhash(h, c) ((h) = 0x63c63cd9 * (h) + 0x9c39c33d + (c))
static uint32
hash2(const void *keyarg, size_t len)
{
- register const uint8 *e, *key;
- register uint32 h;
- register uint8 c;
-
- key = (const uint8 *)keyarg;
- e = key + len;
- for (h = 0; key != e;) {
- c = *key++;
- if (!c && key > e)
- break;
- dcharhash(h, c);
- }
- return (h);
+ register const uint8 *e, *key;
+ register uint32 h;
+ register uint8 c;
+
+ key = (const uint8 *)keyarg;
+ e = key + len;
+ for (h = 0; key != e;) {
+ c = *key++;
+ if (!c && key > e)
+ break;
+ dcharhash(h, c);
+ }
+ return (h);
}
/*
@@ -115,46 +115,46 @@ hash2(const void *keyarg, size_t len)
static uint32
hash3(const void *keyarg, register size_t len)
{
- register const uint8 *key;
- register size_t loop;
- register uint32 h;
-
-#define HASHC h = *key++ + 65599 * h
-
- h = 0;
- key = (const uint8 *)keyarg;
- if (len > 0) {
- loop = (len + 8 - 1) >> 3;
-
- switch (len & (8 - 1)) {
- case 0:
- do {
- HASHC;
- /* FALLTHROUGH */
- case 7:
- HASHC;
- /* FALLTHROUGH */
- case 6:
- HASHC;
- /* FALLTHROUGH */
- case 5:
- HASHC;
- /* FALLTHROUGH */
- case 4:
- HASHC;
- /* FALLTHROUGH */
- case 3:
- HASHC;
- /* FALLTHROUGH */
- case 2:
- HASHC;
- /* FALLTHROUGH */
- case 1:
- HASHC;
- } while (--loop);
- }
- }
- return (h);
+ register const uint8 *key;
+ register size_t loop;
+ register uint32 h;
+
+#define HASHC h = *key++ + 65599 * h
+
+ h = 0;
+ key = (const uint8 *)keyarg;
+ if (len > 0) {
+ loop = (len + 8 - 1) >> 3;
+
+ switch (len & (8 - 1)) {
+ case 0:
+ do {
+ HASHC;
+ /* FALLTHROUGH */
+ case 7:
+ HASHC;
+ /* FALLTHROUGH */
+ case 6:
+ HASHC;
+ /* FALLTHROUGH */
+ case 5:
+ HASHC;
+ /* FALLTHROUGH */
+ case 4:
+ HASHC;
+ /* FALLTHROUGH */
+ case 3:
+ HASHC;
+ /* FALLTHROUGH */
+ case 2:
+ HASHC;
+ /* FALLTHROUGH */
+ case 1:
+ HASHC;
+ } while (--loop);
+ }
+ }
+ return (h);
}
#endif /* 0 */
@@ -162,46 +162,46 @@ hash3(const void *keyarg, register size_t len)
static uint32
hash4(const void *keyarg, register size_t len)
{
- register const uint8 *key;
- register size_t loop;
- register uint32 h;
+ register const uint8 *key;
+ register size_t loop;
+ register uint32 h;
-#define HASH4a h = (h << 5) - h + *key++;
-#define HASH4b h = (h << 5) + h + *key++;
+#define HASH4a h = (h << 5) - h + *key++;
+#define HASH4b h = (h << 5) + h + *key++;
#define HASH4 HASH4b
- h = 0;
- key = (const uint8 *)keyarg;
- if (len > 0) {
- loop = (len + 8 - 1) >> 3;
-
- switch (len & (8 - 1)) {
- case 0:
- do {
- HASH4;
- /* FALLTHROUGH */
- case 7:
- HASH4;
- /* FALLTHROUGH */
- case 6:
- HASH4;
- /* FALLTHROUGH */
- case 5:
- HASH4;
- /* FALLTHROUGH */
- case 4:
- HASH4;
- /* FALLTHROUGH */
- case 3:
- HASH4;
- /* FALLTHROUGH */
- case 2:
- HASH4;
- /* FALLTHROUGH */
- case 1:
- HASH4;
- } while (--loop);
- }
- }
- return (h);
+ h = 0;
+ key = (const uint8 *)keyarg;
+ if (len > 0) {
+ loop = (len + 8 - 1) >> 3;
+
+ switch (len & (8 - 1)) {
+ case 0:
+ do {
+ HASH4;
+ /* FALLTHROUGH */
+ case 7:
+ HASH4;
+ /* FALLTHROUGH */
+ case 6:
+ HASH4;
+ /* FALLTHROUGH */
+ case 5:
+ HASH4;
+ /* FALLTHROUGH */
+ case 4:
+ HASH4;
+ /* FALLTHROUGH */
+ case 3:
+ HASH4;
+ /* FALLTHROUGH */
+ case 2:
+ HASH4;
+ /* FALLTHROUGH */
+ case 1:
+ HASH4;
+ } while (--loop);
+ }
+ }
+ return (h);
}
diff --git a/nss/lib/dbm/src/h_log2.c b/nss/lib/dbm/src/h_log2.c
index 9c8ea06..a42b51a 100644
--- a/nss/lib/dbm/src/h_log2.c
+++ b/nss/lib/dbm/src/h_log2.c
@@ -1,6 +1,6 @@
/*-
* Copyright (c) 1990, 1993, 1994
- * The Regents of the University of California. All rights reserved.
+ * The Regents of the University of California. All rights reserved.
*
* This code is derived from software contributed to Berkeley by
* Margo Seltzer.
@@ -13,7 +13,7 @@
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
- * 3. ***REMOVED*** - see
+ * 3. ***REMOVED*** - see
* ftp://ftp.cs.berkeley.edu/pub/4bsd/README.Impt.License.Change
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
@@ -33,7 +33,7 @@
*/
#if defined(LIBC_SCCS) && !defined(lint)
-static char sccsid[] = "@(#)hash_log2.c 8.2 (Berkeley) 5/31/94";
+static char sccsid[] = "@(#)hash_log2.c 8.2 (Berkeley) 5/31/94";
#endif /* LIBC_SCCS and not lint */
#include <stdio.h>
@@ -42,11 +42,13 @@ static char sccsid[] = "@(#)hash_log2.c 8.2 (Berkeley) 5/31/94";
#endif
#include "mcom_db.h"
-uint32 __log2(uint32 num)
+uint32
+__log2(uint32 num)
{
- register uint32 i, limit;
+ register uint32 i, limit;
- limit = 1;
- for (i = 0; limit < num; limit = limit << 1, i++) {}
- return (i);
+ limit = 1;
+ for (i = 0; limit < num; limit = limit << 1, i++) {
+ }
+ return (i);
}
diff --git a/nss/lib/dbm/src/h_page.c b/nss/lib/dbm/src/h_page.c
index 669f3b3..bf1252a 100644
--- a/nss/lib/dbm/src/h_page.c
+++ b/nss/lib/dbm/src/h_page.c
@@ -1,6 +1,6 @@
/*-
* Copyright (c) 1990, 1993, 1994
- * The Regents of the University of California. All rights reserved.
+ * The Regents of the University of California. All rights reserved.
*
* This code is derived from software contributed to Berkeley by
* Margo Seltzer.
@@ -13,7 +13,7 @@
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
- * 3. ***REMOVED*** - see
+ * 3. ***REMOVED*** - see
* ftp://ftp.cs.berkeley.edu/pub/4bsd/README.Impt.License.Change
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
@@ -40,23 +40,23 @@ extern long new_lseek(int fd, long pos, int start);
#endif
#if defined(LIBC_SCCS) && !defined(lint)
-static char sccsid[] = "@(#)hash_page.c 8.7 (Berkeley) 8/16/94";
+static char sccsid[] = "@(#)hash_page.c 8.7 (Berkeley) 8/16/94";
#endif /* LIBC_SCCS and not lint */
/*
* PACKAGE: hashing
*
* DESCRIPTION:
- * Page manipulation for hashing package.
+ * Page manipulation for hashing package.
*
* ROUTINES:
*
* External
- * __get_page
- * __add_ovflpage
+ * __get_page
+ * __add_ovflpage
* Internal
- * overflow_page
- * open_temp
+ * overflow_page
+ * open_temp
*/
#ifndef macintosh
#include <sys/types.h>
@@ -68,7 +68,7 @@ static char sccsid[] = "@(#)hash_page.c 8.7 (Berkeley) 8/16/94";
#include <errno.h>
#include <fcntl.h>
-#if defined(_WIN32) || defined(_WINDOWS)
+#if defined(_WIN32) || defined(_WINDOWS)
#include <io.h>
#endif
#include <signal.h>
@@ -89,85 +89,83 @@ static char sccsid[] = "@(#)hash_page.c 8.7 (Berkeley) 8/16/94";
extern int mkstempflags(char *path, int extraFlags);
-static uint32 *fetch_bitmap(HTAB *, uint32);
-static uint32 first_free(uint32);
-static int open_temp(HTAB *);
-static uint16 overflow_page(HTAB *);
-static void squeeze_key(uint16 *, const DBT *, const DBT *);
-static int ugly_split(HTAB *, uint32, BUFHEAD *, BUFHEAD *, int, int);
-
-#define PAGE_INIT(P) { \
- ((uint16 *)(P))[0] = 0; \
- ((uint16 *)(P))[1] = hashp->BSIZE - 3 * sizeof(uint16); \
- ((uint16 *)(P))[2] = hashp->BSIZE; \
-}
+static uint32 *fetch_bitmap(HTAB *, uint32);
+static uint32 first_free(uint32);
+static int open_temp(HTAB *);
+static uint16 overflow_page(HTAB *);
+static void squeeze_key(uint16 *, const DBT *, const DBT *);
+static int ugly_split(HTAB *, uint32, BUFHEAD *, BUFHEAD *, int, int);
+
+#define PAGE_INIT(P) \
+ { \
+ ((uint16 *)(P))[0] = 0; \
+ ((uint16 *)(P))[1] = hashp->BSIZE - 3 * sizeof(uint16); \
+ ((uint16 *)(P))[2] = hashp->BSIZE; \
+ }
/* implement a new lseek using lseek that
* writes zero's when extending a file
* beyond the end.
*/
-long new_lseek(int fd, long offset, int origin)
+long
+new_lseek(int fd, long offset, int origin)
{
- long cur_pos=0;
- long end_pos=0;
- long seek_pos=0;
-
- if(origin == SEEK_CUR)
- {
- if(offset < 1)
- return(lseek(fd, offset, SEEK_CUR));
-
- cur_pos = lseek(fd, 0, SEEK_CUR);
-
- if(cur_pos < 0)
- return(cur_pos);
- }
-
- end_pos = lseek(fd, 0, SEEK_END);
- if(end_pos < 0)
- return(end_pos);
-
- if(origin == SEEK_SET)
- seek_pos = offset;
- else if(origin == SEEK_CUR)
- seek_pos = cur_pos + offset;
- else if(origin == SEEK_END)
- seek_pos = end_pos + offset;
- else
- {
- assert(0);
- return(-1);
- }
-
- /* the seek position desired is before the
- * end of the file. We don't need
- * to do anything special except the seek.
- */
- if(seek_pos <= end_pos)
- return(lseek(fd, seek_pos, SEEK_SET));
-
- /* the seek position is beyond the end of the
- * file. Write zero's to the end.
- *
- * we are already at the end of the file so
- * we just need to "write()" zeros for the
- * difference between seek_pos-end_pos and
- * then seek to the position to finish
- * the call
- */
- {
- char buffer[1024];
- long len = seek_pos-end_pos;
- memset(buffer, 0, 1024);
- while(len > 0)
- {
- if(write(fd, buffer, (size_t)(1024 > len ? len : 1024)) < 0)
- return(-1);
- len -= 1024;
- }
- return(lseek(fd, seek_pos, SEEK_SET));
- }
-
+ long cur_pos = 0;
+ long end_pos = 0;
+ long seek_pos = 0;
+
+ if (origin == SEEK_CUR) {
+ if (offset < 1)
+ return (lseek(fd, offset, SEEK_CUR));
+
+ cur_pos = lseek(fd, 0, SEEK_CUR);
+
+ if (cur_pos < 0)
+ return (cur_pos);
+ }
+
+ end_pos = lseek(fd, 0, SEEK_END);
+ if (end_pos < 0)
+ return (end_pos);
+
+ if (origin == SEEK_SET)
+ seek_pos = offset;
+ else if (origin == SEEK_CUR)
+ seek_pos = cur_pos + offset;
+ else if (origin == SEEK_END)
+ seek_pos = end_pos + offset;
+ else {
+ assert(0);
+ return (-1);
+ }
+
+ /* the seek position desired is before the
+ * end of the file. We don't need
+ * to do anything special except the seek.
+ */
+ if (seek_pos <= end_pos)
+ return (lseek(fd, seek_pos, SEEK_SET));
+
+ /* the seek position is beyond the end of the
+ * file. Write zero's to the end.
+ *
+ * we are already at the end of the file so
+ * we just need to "write()" zeros for the
+ * difference between seek_pos-end_pos and
+ * then seek to the position to finish
+ * the call
+ */
+ {
+ char buffer[1024];
+ long len = seek_pos - end_pos;
+ memset(buffer, 0, 1024);
+ while (len > 0) {
+ if (write(fd, buffer, (size_t)(1024 > len ? len : 1024)) < 0)
+ return (-1);
+ len -= 1024;
+ }
+ return (lseek(fd, seek_pos, SEEK_SET));
+ }
}
/*
@@ -176,209 +174,208 @@ long new_lseek(int fd, long offset, int origin)
* stuff on.
*/
static void
-putpair(char *p, const DBT *key, DBT * val)
+putpair(char *p, const DBT *key, DBT *val)
{
- register uint16 *bp, n, off;
+ register uint16 *bp, n, off;
- bp = (uint16 *)p;
+ bp = (uint16 *)p;
- /* Enter the key first. */
- n = bp[0];
+ /* Enter the key first. */
+ n = bp[0];
- off = OFFSET(bp) - key->size;
- memmove(p + off, key->data, key->size);
- bp[++n] = off;
+ off = OFFSET(bp) - key->size;
+ memmove(p + off, key->data, key->size);
+ bp[++n] = off;
- /* Now the data. */
- off -= val->size;
- memmove(p + off, val->data, val->size);
- bp[++n] = off;
+ /* Now the data. */
+ off -= val->size;
+ memmove(p + off, val->data, val->size);
+ bp[++n] = off;
- /* Adjust page info. */
- bp[0] = n;
- bp[n + 1] = off - ((n + 3) * sizeof(uint16));
- bp[n + 2] = off;
+ /* Adjust page info. */
+ bp[0] = n;
+ bp[n + 1] = off - ((n + 3) * sizeof(uint16));
+ bp[n + 2] = off;
}
/*
* Returns:
- * 0 OK
- * -1 error
+ * 0 OK
+ * -1 error
*/
extern int
__delpair(HTAB *hashp, BUFHEAD *bufp, int ndx)
{
- register uint16 *bp, newoff;
- register int n;
- uint16 pairlen;
-
- bp = (uint16 *)bufp->page;
- n = bp[0];
-
- if (bp[ndx + 1] < REAL_KEY)
- return (__big_delete(hashp, bufp));
- if (ndx != 1)
- newoff = bp[ndx - 1];
- else
- newoff = hashp->BSIZE;
- pairlen = newoff - bp[ndx + 1];
-
- if (ndx != (n - 1)) {
- /* Hard Case -- need to shuffle keys */
- register int i;
- register char *src = bufp->page + (int)OFFSET(bp);
- uint32 dst_offset = (uint32)OFFSET(bp) + (uint32)pairlen;
- register char *dst = bufp->page + dst_offset;
- uint32 length = bp[ndx + 1] - OFFSET(bp);
-
- /*
- * +-----------+XXX+---------+XXX+---------+---------> +infinity
- * | | | |
- * 0 src_offset dst_offset BSIZE
- *
- * Dst_offset is > src_offset, so if src_offset were bad, dst_offset
- * would be too, therefore we check only dst_offset.
- *
- * If dst_offset is >= BSIZE, either OFFSET(bp), or pairlen, or both
- * is corrupted.
- *
- * Once we know dst_offset is < BSIZE, we can subtract it from BSIZE
- * to get an upper bound on length.
- */
- if(dst_offset > (uint32)hashp->BSIZE)
- return(DATABASE_CORRUPTED_ERROR);
-
- if(length > (uint32)(hashp->BSIZE - dst_offset))
- return(DATABASE_CORRUPTED_ERROR);
-
- memmove(dst, src, length);
-
- /* Now adjust the pointers */
- for (i = ndx + 2; i <= n; i += 2) {
- if (bp[i + 1] == OVFLPAGE) {
- bp[i - 2] = bp[i];
- bp[i - 1] = bp[i + 1];
- } else {
- bp[i - 2] = bp[i] + pairlen;
- bp[i - 1] = bp[i + 1] + pairlen;
- }
- }
- }
- /* Finally adjust the page data */
- bp[n] = OFFSET(bp) + pairlen;
- bp[n - 1] = bp[n + 1] + pairlen + 2 * sizeof(uint16);
- bp[0] = n - 2;
- hashp->NKEYS--;
-
- bufp->flags |= BUF_MOD;
- return (0);
+ register uint16 *bp, newoff;
+ register int n;
+ uint16 pairlen;
+
+ bp = (uint16 *)bufp->page;
+ n = bp[0];
+
+ if (bp[ndx + 1] < REAL_KEY)
+ return (__big_delete(hashp, bufp));
+ if (ndx != 1)
+ newoff = bp[ndx - 1];
+ else
+ newoff = hashp->BSIZE;
+ pairlen = newoff - bp[ndx + 1];
+
+ if (ndx != (n - 1)) {
+ /* Hard Case -- need to shuffle keys */
+ register int i;
+ register char *src = bufp->page + (int)OFFSET(bp);
+ uint32 dst_offset = (uint32)OFFSET(bp) + (uint32)pairlen;
+ register char *dst = bufp->page + dst_offset;
+ uint32 length = bp[ndx + 1] - OFFSET(bp);
+
+ /*
+ * +-----------+XXX+---------+XXX+---------+---------> +infinity
+ * | | | |
+ * 0 src_offset dst_offset BSIZE
+ *
+ * Dst_offset is > src_offset, so if src_offset were bad, dst_offset
+ * would be too, therefore we check only dst_offset.
+ *
+ * If dst_offset is >= BSIZE, either OFFSET(bp), or pairlen, or both
+ * is corrupted.
+ *
+ * Once we know dst_offset is < BSIZE, we can subtract it from BSIZE
+ * to get an upper bound on length.
+ */
+ if (dst_offset > (uint32)hashp->BSIZE)
+ return (DATABASE_CORRUPTED_ERROR);
+
+ if (length > (uint32)(hashp->BSIZE - dst_offset))
+ return (DATABASE_CORRUPTED_ERROR);
+
+ memmove(dst, src, length);
+
+ /* Now adjust the pointers */
+ for (i = ndx + 2; i <= n; i += 2) {
+ if (bp[i + 1] == OVFLPAGE) {
+ bp[i - 2] = bp[i];
+ bp[i - 1] = bp[i + 1];
+ } else {
+ bp[i - 2] = bp[i] + pairlen;
+ bp[i - 1] = bp[i + 1] + pairlen;
+ }
+ }
+ }
+ /* Finally adjust the page data */
+ bp[n] = OFFSET(bp) + pairlen;
+ bp[n - 1] = bp[n + 1] + pairlen + 2 * sizeof(uint16);
+ bp[0] = n - 2;
+ hashp->NKEYS--;
+
+ bufp->flags |= BUF_MOD;
+ return (0);
}
/*
* Returns:
- * 0 ==> OK
- * -1 ==> Error
+ * 0 ==> OK
+ * -1 ==> Error
*/
extern int
__split_page(HTAB *hashp, uint32 obucket, uint32 nbucket)
{
- register BUFHEAD *new_bufp, *old_bufp;
- register uint16 *ino;
- register uint16 *tmp_uint16_array;
- register char *np;
- DBT key, val;
+ register BUFHEAD *new_bufp, *old_bufp;
+ register uint16 *ino;
+ register uint16 *tmp_uint16_array;
+ register char *np;
+ DBT key, val;
uint16 n, ndx;
- int retval;
- uint16 copyto, diff, moved;
- size_t off;
- char *op;
-
- copyto = (uint16)hashp->BSIZE;
- off = (uint16)hashp->BSIZE;
- old_bufp = __get_buf(hashp, obucket, NULL, 0);
- if (old_bufp == NULL)
- return (-1);
- new_bufp = __get_buf(hashp, nbucket, NULL, 0);
- if (new_bufp == NULL)
- return (-1);
-
- old_bufp->flags |= (BUF_MOD | BUF_PIN);
- new_bufp->flags |= (BUF_MOD | BUF_PIN);
-
- ino = (uint16 *)(op = old_bufp->page);
- np = new_bufp->page;
-
- moved = 0;
-
- for (n = 1, ndx = 1; n < ino[0]; n += 2) {
- if (ino[n + 1] < REAL_KEY) {
- retval = ugly_split(hashp, obucket, old_bufp, new_bufp,
- (int)copyto, (int)moved);
- old_bufp->flags &= ~BUF_PIN;
- new_bufp->flags &= ~BUF_PIN;
- return (retval);
-
- }
- key.data = (uint8 *)op + ino[n];
-
- /* check here for ino[n] being greater than
- * off. If it is then the database has
- * been corrupted.
- */
- if(ino[n] > off)
- return(DATABASE_CORRUPTED_ERROR);
-
- key.size = off - ino[n];
+ int retval;
+ uint16 copyto, diff, moved;
+ size_t off;
+ char *op;
+
+ copyto = (uint16)hashp->BSIZE;
+ off = (uint16)hashp->BSIZE;
+ old_bufp = __get_buf(hashp, obucket, NULL, 0);
+ if (old_bufp == NULL)
+ return (-1);
+ new_bufp = __get_buf(hashp, nbucket, NULL, 0);
+ if (new_bufp == NULL)
+ return (-1);
+
+ old_bufp->flags |= (BUF_MOD | BUF_PIN);
+ new_bufp->flags |= (BUF_MOD | BUF_PIN);
+
+ ino = (uint16 *)(op = old_bufp->page);
+ np = new_bufp->page;
+
+ moved = 0;
+
+ for (n = 1, ndx = 1; n < ino[0]; n += 2) {
+ if (ino[n + 1] < REAL_KEY) {
+ retval = ugly_split(hashp, obucket, old_bufp, new_bufp,
+ (int)copyto, (int)moved);
+ old_bufp->flags &= ~BUF_PIN;
+ new_bufp->flags &= ~BUF_PIN;
+ return (retval);
+ }
+ key.data = (uint8 *)op + ino[n];
+
+ /* check here for ino[n] being greater than
+ * off. If it is then the database has
+ * been corrupted.
+ */
+ if (ino[n] > off)
+ return (DATABASE_CORRUPTED_ERROR);
+
+ key.size = off - ino[n];
#ifdef DEBUG
- /* make sure the size is positive */
- assert(((int)key.size) > -1);
+ /* make sure the size is positive */
+ assert(((int)key.size) > -1);
#endif
- if (__call_hash(hashp, (char *)key.data, key.size) == obucket) {
- /* Don't switch page */
- diff = copyto - off;
- if (diff) {
- copyto = ino[n + 1] + diff;
- memmove(op + copyto, op + ino[n + 1],
- off - ino[n + 1]);
- ino[ndx] = copyto + ino[n] - ino[n + 1];
- ino[ndx + 1] = copyto;
- } else
- copyto = ino[n + 1];
- ndx += 2;
- } else {
- /* Switch page */
- val.data = (uint8 *)op + ino[n + 1];
- val.size = ino[n] - ino[n + 1];
-
- /* if the pair doesn't fit something is horribly
- * wrong. LJM
- */
- tmp_uint16_array = (uint16*)np;
- if(!PAIRFITS(tmp_uint16_array, &key, &val))
- return(DATABASE_CORRUPTED_ERROR);
-
- putpair(np, &key, &val);
- moved += 2;
- }
-
- off = ino[n + 1];
- }
-
- /* Now clean up the page */
- ino[0] -= moved;
- FREESPACE(ino) = copyto - sizeof(uint16) * (ino[0] + 3);
- OFFSET(ino) = copyto;
+ if (__call_hash(hashp, (char *)key.data, key.size) == obucket) {
+ /* Don't switch page */
+ diff = copyto - off;
+ if (diff) {
+ copyto = ino[n + 1] + diff;
+ memmove(op + copyto, op + ino[n + 1],
+ off - ino[n + 1]);
+ ino[ndx] = copyto + ino[n] - ino[n + 1];
+ ino[ndx + 1] = copyto;
+ } else
+ copyto = ino[n + 1];
+ ndx += 2;
+ } else {
+ /* Switch page */
+ val.data = (uint8 *)op + ino[n + 1];
+ val.size = ino[n] - ino[n + 1];
+
+ /* if the pair doesn't fit something is horribly
+ * wrong. LJM
+ */
+ tmp_uint16_array = (uint16 *)np;
+ if (!PAIRFITS(tmp_uint16_array, &key, &val))
+ return (DATABASE_CORRUPTED_ERROR);
+
+ putpair(np, &key, &val);
+ moved += 2;
+ }
+
+ off = ino[n + 1];
+ }
+
+ /* Now clean up the page */
+ ino[0] -= moved;
+ FREESPACE(ino) = copyto - sizeof(uint16) * (ino[0] + 3);
+ OFFSET(ino) = copyto;
#ifdef DEBUG3
- (void)fprintf(stderr, "split %d/%d\n",
- ((uint16 *)np)[0] / 2,
- ((uint16 *)op)[0] / 2);
+ (void)fprintf(stderr, "split %d/%d\n",
+ ((uint16 *)np)[0] / 2,
+ ((uint16 *)op)[0] / 2);
#endif
- /* unpin both pages */
- old_bufp->flags &= ~BUF_PIN;
- new_bufp->flags &= ~BUF_PIN;
- return (0);
+ /* unpin both pages */
+ old_bufp->flags &= ~BUF_PIN;
+ new_bufp->flags &= ~BUF_PIN;
+ return (0);
}
/*
@@ -393,8 +390,8 @@ __split_page(HTAB *hashp, uint32 obucket, uint32 nbucket)
* big key/data pair.
*
* Returns:
- * 0 ==> success
- * -1 ==> failure
+ * 0 ==> success
+ * -1 ==> failure
*/
/* the maximum number of loops we will allow UGLY split to chew
@@ -405,492 +402,479 @@ __split_page(HTAB *hashp, uint32 obucket, uint32 nbucket)
static int
ugly_split(HTAB *hashp, uint32 obucket, BUFHEAD *old_bufp,
- BUFHEAD *new_bufp,/* Same as __split_page. */ int copyto, int moved)
- /* int copyto; First byte on page which contains key/data values. */
- /* int moved; Number of pairs moved to new page. */
+ BUFHEAD *new_bufp, /* Same as __split_page. */ int copyto, int moved)
+/* int copyto; First byte on page which contains key/data values. */
+/* int moved; Number of pairs moved to new page. */
{
- register BUFHEAD *bufp; /* Buffer header for ino */
- register uint16 *ino; /* Page keys come off of */
- register uint16 *np; /* New page */
- register uint16 *op; /* Page keys go on to if they aren't moving */
- uint32 loop_detection=0;
-
- BUFHEAD *last_bfp; /* Last buf header OVFL needing to be freed */
- DBT key, val;
- SPLIT_RETURN ret;
- uint16 n, off, ov_addr, scopyto;
- char *cino; /* Character value of ino */
- int status;
-
- bufp = old_bufp;
- ino = (uint16 *)old_bufp->page;
- np = (uint16 *)new_bufp->page;
- op = (uint16 *)old_bufp->page;
- last_bfp = NULL;
- scopyto = (uint16)copyto; /* ANSI */
-
- n = ino[0] - 1;
- while (n < ino[0]) {
-
-
- /* this function goes nuts sometimes and never returns.
+ register BUFHEAD *bufp; /* Buffer header for ino */
+ register uint16 *ino; /* Page keys come off of */
+ register uint16 *np; /* New page */
+ register uint16 *op; /* Page keys go on to if they aren't moving */
+ uint32 loop_detection = 0;
+
+ BUFHEAD *last_bfp; /* Last buf header OVFL needing to be freed */
+ DBT key, val;
+ SPLIT_RETURN ret;
+ uint16 n, off, ov_addr, scopyto;
+ char *cino; /* Character value of ino */
+ int status;
+
+ bufp = old_bufp;
+ ino = (uint16 *)old_bufp->page;
+ np = (uint16 *)new_bufp->page;
+ op = (uint16 *)old_bufp->page;
+ last_bfp = NULL;
+ scopyto = (uint16)copyto; /* ANSI */
+
+ n = ino[0] - 1;
+ while (n < ino[0]) {
+
+ /* this function goes nuts sometimes and never returns.
* I havent found the problem yet but I need a solution
* so if we loop too often we assume a database curruption error
* :LJM
*/
loop_detection++;
- if(loop_detection > MAX_UGLY_SPLIT_LOOPS)
+ if (loop_detection > MAX_UGLY_SPLIT_LOOPS)
return DATABASE_CORRUPTED_ERROR;
- if (ino[2] < REAL_KEY && ino[2] != OVFLPAGE) {
- if ((status = __big_split(hashp, old_bufp,
- new_bufp, bufp, bufp->addr, obucket, &ret)))
- return (status);
- old_bufp = ret.oldp;
- if (!old_bufp)
- return (-1);
- op = (uint16 *)old_bufp->page;
- new_bufp = ret.newp;
- if (!new_bufp)
- return (-1);
- np = (uint16 *)new_bufp->page;
- bufp = ret.nextp;
- if (!bufp)
- return (0);
- cino = (char *)bufp->page;
- ino = (uint16 *)cino;
- last_bfp = ret.nextp;
- } else if (ino[n + 1] == OVFLPAGE) {
- ov_addr = ino[n];
- /*
- * Fix up the old page -- the extra 2 are the fields
- * which contained the overflow information.
- */
- ino[0] -= (moved + 2);
- FREESPACE(ino) =
- scopyto - sizeof(uint16) * (ino[0] + 3);
- OFFSET(ino) = scopyto;
-
- bufp = __get_buf(hashp, ov_addr, bufp, 0);
- if (!bufp)
- return (-1);
-
- ino = (uint16 *)bufp->page;
- n = 1;
- scopyto = hashp->BSIZE;
- moved = 0;
-
- if (last_bfp)
- __free_ovflpage(hashp, last_bfp);
- last_bfp = bufp;
- }
- /* Move regular sized pairs of there are any */
- off = hashp->BSIZE;
- for (n = 1; (n < ino[0]) && (ino[n + 1] >= REAL_KEY); n += 2) {
- cino = (char *)ino;
- key.data = (uint8 *)cino + ino[n];
- key.size = off - ino[n];
- val.data = (uint8 *)cino + ino[n + 1];
- val.size = ino[n] - ino[n + 1];
- off = ino[n + 1];
-
- if (__call_hash(hashp, (char*)key.data, key.size) == obucket) {
- /* Keep on old page */
- if (PAIRFITS(op, (&key), (&val)))
- putpair((char *)op, &key, &val);
- else {
- old_bufp =
- __add_ovflpage(hashp, old_bufp);
- if (!old_bufp)
- return (-1);
- op = (uint16 *)old_bufp->page;
- putpair((char *)op, &key, &val);
- }
- old_bufp->flags |= BUF_MOD;
- } else {
- /* Move to new page */
- if (PAIRFITS(np, (&key), (&val)))
- putpair((char *)np, &key, &val);
- else {
- new_bufp =
- __add_ovflpage(hashp, new_bufp);
- if (!new_bufp)
- return (-1);
- np = (uint16 *)new_bufp->page;
- putpair((char *)np, &key, &val);
- }
- new_bufp->flags |= BUF_MOD;
- }
- }
- }
- if (last_bfp)
- __free_ovflpage(hashp, last_bfp);
- return (0);
+ if (ino[2] < REAL_KEY && ino[2] != OVFLPAGE) {
+ if ((status = __big_split(hashp, old_bufp,
+ new_bufp, bufp, bufp->addr, obucket, &ret)))
+ return (status);
+ old_bufp = ret.oldp;
+ if (!old_bufp)
+ return (-1);
+ op = (uint16 *)old_bufp->page;
+ new_bufp = ret.newp;
+ if (!new_bufp)
+ return (-1);
+ np = (uint16 *)new_bufp->page;
+ bufp = ret.nextp;
+ if (!bufp)
+ return (0);
+ cino = (char *)bufp->page;
+ ino = (uint16 *)cino;
+ last_bfp = ret.nextp;
+ } else if (ino[n + 1] == OVFLPAGE) {
+ ov_addr = ino[n];
+ /*
+ * Fix up the old page -- the extra 2 are the fields
+ * which contained the overflow information.
+ */
+ ino[0] -= (moved + 2);
+ FREESPACE(ino) =
+ scopyto - sizeof(uint16) * (ino[0] + 3);
+ OFFSET(ino) = scopyto;
+
+ bufp = __get_buf(hashp, ov_addr, bufp, 0);
+ if (!bufp)
+ return (-1);
+
+ ino = (uint16 *)bufp->page;
+ n = 1;
+ scopyto = hashp->BSIZE;
+ moved = 0;
+
+ if (last_bfp)
+ __free_ovflpage(hashp, last_bfp);
+ last_bfp = bufp;
+ }
+ /* Move regular sized pairs of there are any */
+ off = hashp->BSIZE;
+ for (n = 1; (n < ino[0]) && (ino[n + 1] >= REAL_KEY); n += 2) {
+ cino = (char *)ino;
+ key.data = (uint8 *)cino + ino[n];
+ key.size = off - ino[n];
+ val.data = (uint8 *)cino + ino[n + 1];
+ val.size = ino[n] - ino[n + 1];
+ off = ino[n + 1];
+
+ if (__call_hash(hashp, (char *)key.data, key.size) == obucket) {
+ /* Keep on old page */
+ if (PAIRFITS(op, (&key), (&val)))
+ putpair((char *)op, &key, &val);
+ else {
+ old_bufp =
+ __add_ovflpage(hashp, old_bufp);
+ if (!old_bufp)
+ return (-1);
+ op = (uint16 *)old_bufp->page;
+ putpair((char *)op, &key, &val);
+ }
+ old_bufp->flags |= BUF_MOD;
+ } else {
+ /* Move to new page */
+ if (PAIRFITS(np, (&key), (&val)))
+ putpair((char *)np, &key, &val);
+ else {
+ new_bufp =
+ __add_ovflpage(hashp, new_bufp);
+ if (!new_bufp)
+ return (-1);
+ np = (uint16 *)new_bufp->page;
+ putpair((char *)np, &key, &val);
+ }
+ new_bufp->flags |= BUF_MOD;
+ }
+ }
+ }
+ if (last_bfp)
+ __free_ovflpage(hashp, last_bfp);
+ return (0);
}
/*
* Add the given pair to the page
*
* Returns:
- * 0 ==> OK
- * 1 ==> failure
+ * 0 ==> OK
+ * 1 ==> failure
*/
extern int
-__addel(HTAB *hashp, BUFHEAD *bufp, const DBT *key, const DBT * val)
+__addel(HTAB *hashp, BUFHEAD *bufp, const DBT *key, const DBT *val)
{
- register uint16 *bp, *sop;
- int do_expand;
-
- bp = (uint16 *)bufp->page;
- do_expand = 0;
- while (bp[0] && (bp[2] < REAL_KEY || bp[bp[0]] < REAL_KEY))
- /* Exception case */
- if (bp[2] == FULL_KEY_DATA && bp[0] == 2)
- /* This is the last page of a big key/data pair
- and we need to add another page */
- break;
- else if (bp[2] < REAL_KEY && bp[bp[0]] != OVFLPAGE) {
- bufp = __get_buf(hashp, bp[bp[0] - 1], bufp, 0);
- if (!bufp)
- {
+ register uint16 *bp, *sop;
+ int do_expand;
+
+ bp = (uint16 *)bufp->page;
+ do_expand = 0;
+ while (bp[0] && (bp[2] < REAL_KEY || bp[bp[0]] < REAL_KEY))
+ /* Exception case */
+ if (bp[2] == FULL_KEY_DATA && bp[0] == 2)
+ /* This is the last page of a big key/data pair
+ and we need to add another page */
+ break;
+ else if (bp[2] < REAL_KEY && bp[bp[0]] != OVFLPAGE) {
+ bufp = __get_buf(hashp, bp[bp[0] - 1], bufp, 0);
+ if (!bufp) {
#ifdef DEBUG
- assert(0);
+ assert(0);
#endif
- return (-1);
- }
- bp = (uint16 *)bufp->page;
- } else
- /* Try to squeeze key on this page */
- if (FREESPACE(bp) > PAIRSIZE(key, val)) {
- {
- squeeze_key(bp, key, val);
-
- /* LJM: I added this because I think it was
- * left out on accident.
- * if this isn't incremented nkeys will not
- * be the actual number of keys in the db.
- */
- hashp->NKEYS++;
- return (0);
- }
- } else {
- bufp = __get_buf(hashp, bp[bp[0] - 1], bufp, 0);
- if (!bufp)
- {
+ return (-1);
+ }
+ bp = (uint16 *)bufp->page;
+ } else
+ /* Try to squeeze key on this page */
+ if (FREESPACE(bp) > PAIRSIZE(key, val)) {
+ {
+ squeeze_key(bp, key, val);
+
+ /* LJM: I added this because I think it was
+ * left out on accident.
+ * if this isn't incremented nkeys will not
+ * be the actual number of keys in the db.
+ */
+ hashp->NKEYS++;
+ return (0);
+ }
+ } else {
+ bufp = __get_buf(hashp, bp[bp[0] - 1], bufp, 0);
+ if (!bufp) {
#ifdef DEBUG
- assert(0);
+ assert(0);
#endif
- return (-1);
- }
- bp = (uint16 *)bufp->page;
- }
-
- if (PAIRFITS(bp, key, val))
- putpair(bufp->page, key, (DBT *)val);
- else {
- do_expand = 1;
- bufp = __add_ovflpage(hashp, bufp);
- if (!bufp)
- {
+ return (-1);
+ }
+ bp = (uint16 *)bufp->page;
+ }
+
+ if (PAIRFITS(bp, key, val))
+ putpair(bufp->page, key, (DBT *)val);
+ else {
+ do_expand = 1;
+ bufp = __add_ovflpage(hashp, bufp);
+ if (!bufp) {
#ifdef DEBUG
- assert(0);
+ assert(0);
#endif
- return (-1);
- }
- sop = (uint16 *)bufp->page;
-
- if (PAIRFITS(sop, key, val))
- putpair((char *)sop, key, (DBT *)val);
- else
- if (__big_insert(hashp, bufp, key, val))
- {
+ return (-1);
+ }
+ sop = (uint16 *)bufp->page;
+
+ if (PAIRFITS(sop, key, val))
+ putpair((char *)sop, key, (DBT *)val);
+ else if (__big_insert(hashp, bufp, key, val)) {
#ifdef DEBUG
- assert(0);
+ assert(0);
#endif
- return (-1);
- }
- }
- bufp->flags |= BUF_MOD;
- /*
- * If the average number of keys per bucket exceeds the fill factor,
- * expand the table.
- */
- hashp->NKEYS++;
- if (do_expand ||
- (hashp->NKEYS / (hashp->MAX_BUCKET + 1) > hashp->FFACTOR))
- return (__expand_table(hashp));
- return (0);
+ return (-1);
+ }
+ }
+ bufp->flags |= BUF_MOD;
+ /*
+ * If the average number of keys per bucket exceeds the fill factor,
+ * expand the table.
+ */
+ hashp->NKEYS++;
+ if (do_expand ||
+ (hashp->NKEYS / (hashp->MAX_BUCKET + 1) > hashp->FFACTOR))
+ return (__expand_table(hashp));
+ return (0);
}
/*
*
* Returns:
- * pointer on success
- * NULL on error
+ * pointer on success
+ * NULL on error
*/
extern BUFHEAD *
__add_ovflpage(HTAB *hashp, BUFHEAD *bufp)
{
- register uint16 *sp;
- uint16 ndx, ovfl_num;
+ register uint16 *sp;
+ uint16 ndx, ovfl_num;
#ifdef DEBUG1
- int tmp1, tmp2;
+ int tmp1, tmp2;
#endif
- sp = (uint16 *)bufp->page;
-
- /* Check if we are dynamically determining the fill factor */
- if (hashp->FFACTOR == DEF_FFACTOR) {
- hashp->FFACTOR = sp[0] >> 1;
- if (hashp->FFACTOR < MIN_FFACTOR)
- hashp->FFACTOR = MIN_FFACTOR;
- }
- bufp->flags |= BUF_MOD;
- ovfl_num = overflow_page(hashp);
+ sp = (uint16 *)bufp->page;
+
+ /* Check if we are dynamically determining the fill factor */
+ if (hashp->FFACTOR == DEF_FFACTOR) {
+ hashp->FFACTOR = sp[0] >> 1;
+ if (hashp->FFACTOR < MIN_FFACTOR)
+ hashp->FFACTOR = MIN_FFACTOR;
+ }
+ bufp->flags |= BUF_MOD;
+ ovfl_num = overflow_page(hashp);
#ifdef DEBUG1
- tmp1 = bufp->addr;
- tmp2 = bufp->ovfl ? bufp->ovfl->addr : 0;
+ tmp1 = bufp->addr;
+ tmp2 = bufp->ovfl ? bufp->ovfl->addr : 0;
#endif
- if (!ovfl_num || !(bufp->ovfl = __get_buf(hashp, ovfl_num, bufp, 1)))
- return (NULL);
- bufp->ovfl->flags |= BUF_MOD;
+ if (!ovfl_num || !(bufp->ovfl = __get_buf(hashp, ovfl_num, bufp, 1)))
+ return (NULL);
+ bufp->ovfl->flags |= BUF_MOD;
#ifdef DEBUG1
- (void)fprintf(stderr, "ADDOVFLPAGE: %d->ovfl was %d is now %d\n",
- tmp1, tmp2, bufp->ovfl->addr);
+ (void)fprintf(stderr, "ADDOVFLPAGE: %d->ovfl was %d is now %d\n",
+ tmp1, tmp2, bufp->ovfl->addr);
#endif
- ndx = sp[0];
- /*
- * Since a pair is allocated on a page only if there's room to add
- * an overflow page, we know that the OVFL information will fit on
- * the page.
- */
- sp[ndx + 4] = OFFSET(sp);
- sp[ndx + 3] = FREESPACE(sp) - OVFLSIZE;
- sp[ndx + 1] = ovfl_num;
- sp[ndx + 2] = OVFLPAGE;
- sp[0] = ndx + 2;
+ ndx = sp[0];
+ /*
+ * Since a pair is allocated on a page only if there's room to add
+ * an overflow page, we know that the OVFL information will fit on
+ * the page.
+ */
+ sp[ndx + 4] = OFFSET(sp);
+ sp[ndx + 3] = FREESPACE(sp) - OVFLSIZE;
+ sp[ndx + 1] = ovfl_num;
+ sp[ndx + 2] = OVFLPAGE;
+ sp[0] = ndx + 2;
#ifdef HASH_STATISTICS
- hash_overflows++;
+ hash_overflows++;
#endif
- return (bufp->ovfl);
+ return (bufp->ovfl);
}
/*
* Returns:
- * 0 indicates SUCCESS
- * -1 indicates FAILURE
+ * 0 indicates SUCCESS
+ * -1 indicates FAILURE
*/
extern int
__get_page(HTAB *hashp,
- char * p,
- uint32 bucket,
- int is_bucket,
- int is_disk,
- int is_bitmap)
+ char *p,
+ uint32 bucket,
+ int is_bucket,
+ int is_disk,
+ int is_bitmap)
{
- register int fd, page;
- size_t size;
- int rsize;
- uint16 *bp;
-
- fd = hashp->fp;
- size = hashp->BSIZE;
-
- if ((fd == -1) || !is_disk) {
- PAGE_INIT(p);
- return (0);
- }
- if (is_bucket)
- page = BUCKET_TO_PAGE(bucket);
- else
- page = OADDR_TO_PAGE(bucket);
- if ((MY_LSEEK(fd, (off_t)page << hashp->BSHIFT, SEEK_SET) == -1) ||
- ((rsize = read(fd, p, size)) == -1))
- return (-1);
-
- bp = (uint16 *)p;
- if (!rsize)
- bp[0] = 0; /* We hit the EOF, so initialize a new page */
- else
- if ((unsigned)rsize != size) {
- errno = EFTYPE;
- return (-1);
- }
-
- if (!is_bitmap && !bp[0]) {
- PAGE_INIT(p);
- } else {
-
- if (hashp->LORDER != BYTE_ORDER) {
- register int i, max;
-
- if (is_bitmap) {
- max = hashp->BSIZE >> 2; /* divide by 4 */
- for (i = 0; i < max; i++)
- M_32_SWAP(((int *)p)[i]);
- } else {
- M_16_SWAP(bp[0]);
- max = bp[0] + 2;
-
- /* bound the size of max by
- * the maximum number of entries
- * in the array
- */
- if((unsigned)max > (size / sizeof(uint16)))
- return(DATABASE_CORRUPTED_ERROR);
-
- /* do the byte order swap
- */
- for (i = 1; i <= max; i++)
- M_16_SWAP(bp[i]);
- }
- }
-
- /* check the validity of the page here
- * (after doing byte order swaping if necessary)
- */
- if(!is_bitmap && bp[0] != 0)
- {
- uint16 num_keys = bp[0];
- uint16 offset;
- uint16 i;
-
- /* bp[0] is supposed to be the number of
- * entries currently in the page. If
- * bp[0] is too large (larger than the whole
- * page) then the page is corrupted
- */
- if(bp[0] > (size / sizeof(uint16)))
- return(DATABASE_CORRUPTED_ERROR);
-
- /* bound free space */
- if(FREESPACE(bp) > size)
- return(DATABASE_CORRUPTED_ERROR);
-
- /* check each key and data offset to make
- * sure they are all within bounds they
- * should all be less than the previous
- * offset as well.
- */
- offset = size;
- for(i=1 ; i <= num_keys; i+=2)
- {
- /* ignore overflow pages etc. */
- if(bp[i+1] >= REAL_KEY)
- {
-
- if(bp[i] > offset || bp[i+1] > bp[i])
- return(DATABASE_CORRUPTED_ERROR);
-
- offset = bp[i+1];
- }
- else
- {
- /* there are no other valid keys after
- * seeing a non REAL_KEY
- */
- break;
- }
- }
- }
- }
- return (0);
+ register int fd, page;
+ size_t size;
+ int rsize;
+ uint16 *bp;
+
+ fd = hashp->fp;
+ size = hashp->BSIZE;
+
+ if ((fd == -1) || !is_disk) {
+ PAGE_INIT(p);
+ return (0);
+ }
+ if (is_bucket)
+ page = BUCKET_TO_PAGE(bucket);
+ else
+ page = OADDR_TO_PAGE(bucket);
+ if ((MY_LSEEK(fd, (off_t)page << hashp->BSHIFT, SEEK_SET) == -1) ||
+ ((rsize = read(fd, p, size)) == -1))
+ return (-1);
+
+ bp = (uint16 *)p;
+ if (!rsize)
+ bp[0] = 0; /* We hit the EOF, so initialize a new page */
+ else if ((unsigned)rsize != size) {
+ errno = EFTYPE;
+ return (-1);
+ }
+
+ if (!is_bitmap && !bp[0]) {
+ PAGE_INIT(p);
+ } else {
+
+ if (hashp->LORDER != BYTE_ORDER) {
+ register int i, max;
+
+ if (is_bitmap) {
+ max = hashp->BSIZE >> 2; /* divide by 4 */
+ for (i = 0; i < max; i++)
+ M_32_SWAP(((int *)p)[i]);
+ } else {
+ M_16_SWAP(bp[0]);
+ max = bp[0] + 2;
+
+ /* bound the size of max by
+ * the maximum number of entries
+ * in the array
+ */
+ if ((unsigned)max > (size / sizeof(uint16)))
+ return (DATABASE_CORRUPTED_ERROR);
+
+ /* do the byte order swap
+ */
+ for (i = 1; i <= max; i++)
+ M_16_SWAP(bp[i]);
+ }
+ }
+
+ /* check the validity of the page here
+ * (after doing byte order swaping if necessary)
+ */
+ if (!is_bitmap && bp[0] != 0) {
+ uint16 num_keys = bp[0];
+ uint16 offset;
+ uint16 i;
+
+ /* bp[0] is supposed to be the number of
+ * entries currently in the page. If
+ * bp[0] is too large (larger than the whole
+ * page) then the page is corrupted
+ */
+ if (bp[0] > (size / sizeof(uint16)))
+ return (DATABASE_CORRUPTED_ERROR);
+
+ /* bound free space */
+ if (FREESPACE(bp) > size)
+ return (DATABASE_CORRUPTED_ERROR);
+
+ /* check each key and data offset to make
+ * sure they are all within bounds they
+ * should all be less than the previous
+ * offset as well.
+ */
+ offset = size;
+ for (i = 1; i <= num_keys; i += 2) {
+ /* ignore overflow pages etc. */
+ if (bp[i + 1] >= REAL_KEY) {
+
+ if (bp[i] > offset || bp[i + 1] > bp[i])
+ return (DATABASE_CORRUPTED_ERROR);
+
+ offset = bp[i + 1];
+ } else {
+ /* there are no other valid keys after
+ * seeing a non REAL_KEY
+ */
+ break;
+ }
+ }
+ }
+ }
+ return (0);
}
/*
* Write page p to disk
*
* Returns:
- * 0 ==> OK
- * -1 ==>failure
+ * 0 ==> OK
+ * -1 ==>failure
*/
extern int
__put_page(HTAB *hashp, char *p, uint32 bucket, int is_bucket, int is_bitmap)
{
- register int fd, page;
- size_t size;
- int wsize;
- off_t offset;
-
- size = hashp->BSIZE;
- if ((hashp->fp == -1) && open_temp(hashp))
- return (-1);
- fd = hashp->fp;
-
- if (hashp->LORDER != BYTE_ORDER) {
- register int i;
- register int max;
-
- if (is_bitmap) {
- max = hashp->BSIZE >> 2; /* divide by 4 */
- for (i = 0; i < max; i++)
- M_32_SWAP(((int *)p)[i]);
- } else {
- max = ((uint16 *)p)[0] + 2;
+ register int fd, page;
+ size_t size;
+ int wsize;
+ off_t offset;
+
+ size = hashp->BSIZE;
+ if ((hashp->fp == -1) && open_temp(hashp))
+ return (-1);
+ fd = hashp->fp;
+
+ if (hashp->LORDER != BYTE_ORDER) {
+ register int i;
+ register int max;
+
+ if (is_bitmap) {
+ max = hashp->BSIZE >> 2; /* divide by 4 */
+ for (i = 0; i < max; i++)
+ M_32_SWAP(((int *)p)[i]);
+ } else {
+ max = ((uint16 *)p)[0] + 2;
/* bound the size of max by
* the maximum number of entries
* in the array
*/
- if((unsigned)max > (size / sizeof(uint16)))
- return(DATABASE_CORRUPTED_ERROR);
-
- for (i = 0; i <= max; i++)
- M_16_SWAP(((uint16 *)p)[i]);
-
- }
- }
-
- if (is_bucket)
- page = BUCKET_TO_PAGE(bucket);
- else
- page = OADDR_TO_PAGE(bucket);
- offset = (off_t)page << hashp->BSHIFT;
- if ((MY_LSEEK(fd, offset, SEEK_SET) == -1) ||
- ((wsize = write(fd, p, size)) == -1))
- /* Errno is set */
- return (-1);
- if ((unsigned)wsize != size) {
- errno = EFTYPE;
- return (-1);
- }
-#if defined(_WIN32) || defined(_WINDOWS)
- if (offset + size > hashp->file_size) {
- hashp->updateEOF = 1;
- }
+ if ((unsigned)max > (size / sizeof(uint16)))
+ return (DATABASE_CORRUPTED_ERROR);
+
+ for (i = 0; i <= max; i++)
+ M_16_SWAP(((uint16 *)p)[i]);
+ }
+ }
+
+ if (is_bucket)
+ page = BUCKET_TO_PAGE(bucket);
+ else
+ page = OADDR_TO_PAGE(bucket);
+ offset = (off_t)page << hashp->BSHIFT;
+ if ((MY_LSEEK(fd, offset, SEEK_SET) == -1) ||
+ ((wsize = write(fd, p, size)) == -1))
+ /* Errno is set */
+ return (-1);
+ if ((unsigned)wsize != size) {
+ errno = EFTYPE;
+ return (-1);
+ }
+#if defined(_WIN32) || defined(_WINDOWS)
+ if (offset + size > hashp->file_size) {
+ hashp->updateEOF = 1;
+ }
#endif
- /* put the page back the way it was so that it isn't byteswapped
- * if it remains in memory - LJM
- */
- if (hashp->LORDER != BYTE_ORDER) {
- register int i;
- register int max;
-
- if (is_bitmap) {
- max = hashp->BSIZE >> 2; /* divide by 4 */
- for (i = 0; i < max; i++)
- M_32_SWAP(((int *)p)[i]);
- } else {
- uint16 *bp = (uint16 *)p;
-
- M_16_SWAP(bp[0]);
- max = bp[0] + 2;
-
- /* no need to bound the size if max again
- * since it was done already above
- */
-
- /* do the byte order re-swap
- */
- for (i = 1; i <= max; i++)
- M_16_SWAP(bp[i]);
- }
- }
-
- return (0);
+ /* put the page back the way it was so that it isn't byteswapped
+ * if it remains in memory - LJM
+ */
+ if (hashp->LORDER != BYTE_ORDER) {
+ register int i;
+ register int max;
+
+ if (is_bitmap) {
+ max = hashp->BSIZE >> 2; /* divide by 4 */
+ for (i = 0; i < max; i++)
+ M_32_SWAP(((int *)p)[i]);
+ } else {
+ uint16 *bp = (uint16 *)p;
+
+ M_16_SWAP(bp[0]);
+ max = bp[0] + 2;
+
+ /* no need to bound the size if max again
+ * since it was done already above
+ */
+
+ /* do the byte order re-swap
+ */
+ for (i = 1; i <= max; i++)
+ M_16_SWAP(bp[i]);
+ }
+ }
+
+ return (0);
}
-#define BYTE_MASK ((1 << INT_BYTE_SHIFT) -1)
+#define BYTE_MASK ((1 << INT_BYTE_SHIFT) - 1)
/*
* Initialize a new bitmap page. Bitmap pages are left in memory
* once they are read in.
@@ -898,186 +882,187 @@ __put_page(HTAB *hashp, char *p, uint32 bucket, int is_bucket, int is_bitmap)
extern int
__ibitmap(HTAB *hashp, int pnum, int nbits, int ndx)
{
- uint32 *ip;
- size_t clearbytes, clearints;
-
- if ((ip = (uint32 *)malloc((size_t)hashp->BSIZE)) == NULL)
- return (1);
- hashp->nmaps++;
- clearints = ((nbits - 1) >> INT_BYTE_SHIFT) + 1;
- clearbytes = clearints << INT_TO_BYTE;
- (void)memset((char *)ip, 0, clearbytes);
- (void)memset(((char *)ip) + clearbytes, 0xFF,
- hashp->BSIZE - clearbytes);
- ip[clearints - 1] = ALL_SET << (nbits & BYTE_MASK);
- SETBIT(ip, 0);
- hashp->BITMAPS[ndx] = (uint16)pnum;
- hashp->mapp[ndx] = ip;
- return (0);
+ uint32 *ip;
+ size_t clearbytes, clearints;
+
+ if ((ip = (uint32 *)malloc((size_t)hashp->BSIZE)) == NULL)
+ return (1);
+ hashp->nmaps++;
+ clearints = ((nbits - 1) >> INT_BYTE_SHIFT) + 1;
+ clearbytes = clearints << INT_TO_BYTE;
+ (void)memset((char *)ip, 0, clearbytes);
+ (void)memset(((char *)ip) + clearbytes, 0xFF,
+ hashp->BSIZE - clearbytes);
+ ip[clearints - 1] = ALL_SET << (nbits & BYTE_MASK);
+ SETBIT(ip, 0);
+ hashp->BITMAPS[ndx] = (uint16)pnum;
+ hashp->mapp[ndx] = ip;
+ return (0);
}
static uint32
first_free(uint32 map)
{
- register uint32 i, mask;
-
- mask = 0x1;
- for (i = 0; i < BITS_PER_MAP; i++) {
- if (!(mask & map))
- return (i);
- mask = mask << 1;
- }
- return (i);
+ register uint32 i, mask;
+
+ mask = 0x1;
+ for (i = 0; i < BITS_PER_MAP; i++) {
+ if (!(mask & map))
+ return (i);
+ mask = mask << 1;
+ }
+ return (i);
}
static uint16
overflow_page(HTAB *hashp)
{
- register uint32 *freep=NULL;
- register int max_free, offset, splitnum;
- uint16 addr;
- uint32 i;
- int bit, first_page, free_bit, free_page, in_use_bits, j;
+ register uint32 *freep = NULL;
+ register int max_free, offset, splitnum;
+ uint16 addr;
+ uint32 i;
+ int bit, first_page, free_bit, free_page, in_use_bits, j;
#ifdef DEBUG2
- int tmp1, tmp2;
+ int tmp1, tmp2;
#endif
- splitnum = hashp->OVFL_POINT;
- max_free = hashp->SPARES[splitnum];
-
- free_page = (max_free - 1) >> (hashp->BSHIFT + BYTE_SHIFT);
- free_bit = (max_free - 1) & ((hashp->BSIZE << BYTE_SHIFT) - 1);
-
- /* Look through all the free maps to find the first free block */
- first_page = hashp->LAST_FREED >>(hashp->BSHIFT + BYTE_SHIFT);
- for ( i = first_page; i <= (unsigned)free_page; i++ ) {
- if (!(freep = (uint32 *)hashp->mapp[i]) &&
- !(freep = fetch_bitmap(hashp, i)))
- return (0);
- if (i == (unsigned)free_page)
- in_use_bits = free_bit;
- else
- in_use_bits = (hashp->BSIZE << BYTE_SHIFT) - 1;
-
- if (i == (unsigned)first_page) {
- bit = hashp->LAST_FREED &
- ((hashp->BSIZE << BYTE_SHIFT) - 1);
- j = bit / BITS_PER_MAP;
- bit = bit & ~(BITS_PER_MAP - 1);
- } else {
- bit = 0;
- j = 0;
- }
- for (; bit <= in_use_bits; j++, bit += BITS_PER_MAP)
- if (freep[j] != ALL_SET)
- goto found;
- }
-
- /* No Free Page Found */
- hashp->LAST_FREED = hashp->SPARES[splitnum];
- hashp->SPARES[splitnum]++;
- offset = hashp->SPARES[splitnum] -
- (splitnum ? hashp->SPARES[splitnum - 1] : 0);
-
-#define OVMSG "HASH: Out of overflow pages. Increase page size\n"
- if (offset > SPLITMASK) {
- if (++splitnum >= NCACHED) {
+ splitnum = hashp->OVFL_POINT;
+ max_free = hashp->SPARES[splitnum];
+
+ free_page = (max_free - 1) >> (hashp->BSHIFT + BYTE_SHIFT);
+ free_bit = (max_free - 1) & ((hashp->BSIZE << BYTE_SHIFT) - 1);
+
+ /* Look through all the free maps to find the first free block */
+ first_page = hashp->LAST_FREED >> (hashp->BSHIFT + BYTE_SHIFT);
+ for (i = first_page; i <= (unsigned)free_page; i++) {
+ if (!(freep = (uint32 *)hashp->mapp[i]) &&
+ !(freep = fetch_bitmap(hashp, i)))
+ return (0);
+ if (i == (unsigned)free_page)
+ in_use_bits = free_bit;
+ else
+ in_use_bits = (hashp->BSIZE << BYTE_SHIFT) - 1;
+
+ if (i == (unsigned)first_page) {
+ bit = hashp->LAST_FREED &
+ ((hashp->BSIZE << BYTE_SHIFT) - 1);
+ j = bit / BITS_PER_MAP;
+ bit = bit & ~(BITS_PER_MAP - 1);
+ } else {
+ bit = 0;
+ j = 0;
+ }
+ for (; bit <= in_use_bits; j++, bit += BITS_PER_MAP)
+ if (freep[j] != ALL_SET)
+ goto found;
+ }
+
+ /* No Free Page Found */
+ hashp->LAST_FREED = hashp->SPARES[splitnum];
+ hashp->SPARES[splitnum]++;
+ offset = hashp->SPARES[splitnum] -
+ (splitnum ? hashp->SPARES[splitnum - 1] : 0);
+
+#define OVMSG "HASH: Out of overflow pages. Increase page size\n"
+ if (offset > SPLITMASK) {
+ if (++splitnum >= NCACHED) {
#ifndef macintosh
- (void)fwrite(OVMSG, 1, sizeof(OVMSG) - 1, stderr);
+ (void)fwrite(OVMSG, 1, sizeof(OVMSG) - 1, stderr);
#endif
- return (0);
- }
- hashp->OVFL_POINT = splitnum;
- hashp->SPARES[splitnum] = hashp->SPARES[splitnum-1];
- hashp->SPARES[splitnum-1]--;
- offset = 1;
- }
-
- /* Check if we need to allocate a new bitmap page */
- if (free_bit == (hashp->BSIZE << BYTE_SHIFT) - 1) {
- free_page++;
- if (free_page >= NCACHED) {
+ return (0);
+ }
+ hashp->OVFL_POINT = splitnum;
+ hashp->SPARES[splitnum] = hashp->SPARES[splitnum - 1];
+ hashp->SPARES[splitnum - 1]--;
+ offset = 1;
+ }
+
+ /* Check if we need to allocate a new bitmap page */
+ if (free_bit == (hashp->BSIZE << BYTE_SHIFT) - 1) {
+ free_page++;
+ if (free_page >= NCACHED) {
#ifndef macintosh
- (void)fwrite(OVMSG, 1, sizeof(OVMSG) - 1, stderr);
+ (void)fwrite(OVMSG, 1, sizeof(OVMSG) - 1, stderr);
#endif
- return (0);
- }
- /*
- * This is tricky. The 1 indicates that you want the new page
- * allocated with 1 clear bit. Actually, you are going to
- * allocate 2 pages from this map. The first is going to be
- * the map page, the second is the overflow page we were
- * looking for. The init_bitmap routine automatically, sets
- * the first bit of itself to indicate that the bitmap itself
- * is in use. We would explicitly set the second bit, but
- * don't have to if we tell init_bitmap not to leave it clear
- * in the first place.
- */
- if (__ibitmap(hashp,
- (int)OADDR_OF(splitnum, offset), 1, free_page))
- return (0);
- hashp->SPARES[splitnum]++;
+ return (0);
+ }
+ /*
+ * This is tricky. The 1 indicates that you want the new page
+ * allocated with 1 clear bit. Actually, you are going to
+ * allocate 2 pages from this map. The first is going to be
+ * the map page, the second is the overflow page we were
+ * looking for. The init_bitmap routine automatically, sets
+ * the first bit of itself to indicate that the bitmap itself
+ * is in use. We would explicitly set the second bit, but
+ * don't have to if we tell init_bitmap not to leave it clear
+ * in the first place.
+ */
+ if (__ibitmap(hashp,
+ (int)OADDR_OF(splitnum, offset), 1, free_page))
+ return (0);
+ hashp->SPARES[splitnum]++;
#ifdef DEBUG2
- free_bit = 2;
+ free_bit = 2;
#endif
- offset++;
- if (offset > SPLITMASK) {
- if (++splitnum >= NCACHED) {
+ offset++;
+ if (offset > SPLITMASK) {
+ if (++splitnum >= NCACHED) {
#ifndef macintosh
- (void)fwrite(OVMSG, 1, sizeof(OVMSG) - 1, stderr);
+ (void)fwrite(OVMSG, 1, sizeof(OVMSG) - 1, stderr);
#endif
- return (0);
- }
- hashp->OVFL_POINT = splitnum;
- hashp->SPARES[splitnum] = hashp->SPARES[splitnum-1];
- hashp->SPARES[splitnum-1]--;
- offset = 0;
- }
- } else {
- /*
- * Free_bit addresses the last used bit. Bump it to address
- * the first available bit.
- */
- free_bit++;
- SETBIT(freep, free_bit);
- }
-
- /* Calculate address of the new overflow page */
- addr = OADDR_OF(splitnum, offset);
+ return (0);
+ }
+ hashp->OVFL_POINT = splitnum;
+ hashp->SPARES[splitnum] = hashp->SPARES[splitnum - 1];
+ hashp->SPARES[splitnum - 1]--;
+ offset = 0;
+ }
+ } else {
+ /*
+ * Free_bit addresses the last used bit. Bump it to address
+ * the first available bit.
+ */
+ free_bit++;
+ SETBIT(freep, free_bit);
+ }
+
+ /* Calculate address of the new overflow page */
+ addr = OADDR_OF(splitnum, offset);
#ifdef DEBUG2
- (void)fprintf(stderr, "OVERFLOW_PAGE: ADDR: %d BIT: %d PAGE %d\n",
- addr, free_bit, free_page);
+ (void)fprintf(stderr, "OVERFLOW_PAGE: ADDR: %d BIT: %d PAGE %d\n",
+ addr, free_bit, free_page);
#endif
- return (addr);
+ return (addr);
found:
- bit = bit + first_free(freep[j]);
- SETBIT(freep, bit);
+ bit = bit + first_free(freep[j]);
+ SETBIT(freep, bit);
#ifdef DEBUG2
- tmp1 = bit;
- tmp2 = i;
+ tmp1 = bit;
+ tmp2 = i;
#endif
- /*
- * Bits are addressed starting with 0, but overflow pages are addressed
- * beginning at 1. Bit is a bit addressnumber, so we need to increment
- * it to convert it to a page number.
- */
- bit = 1 + bit + (i * (hashp->BSIZE << BYTE_SHIFT));
- if (bit >= hashp->LAST_FREED)
- hashp->LAST_FREED = bit - 1;
-
- /* Calculate the split number for this page */
- for (i = 0; (i < (unsigned)splitnum) && (bit > hashp->SPARES[i]); i++) {}
- offset = (i ? bit - hashp->SPARES[i - 1] : bit);
- if (offset >= SPLITMASK)
- return (0); /* Out of overflow pages */
- addr = OADDR_OF(i, offset);
+ /*
+ * Bits are addressed starting with 0, but overflow pages are addressed
+ * beginning at 1. Bit is a bit addressnumber, so we need to increment
+ * it to convert it to a page number.
+ */
+ bit = 1 + bit + (i * (hashp->BSIZE << BYTE_SHIFT));
+ if (bit >= hashp->LAST_FREED)
+ hashp->LAST_FREED = bit - 1;
+
+ /* Calculate the split number for this page */
+ for (i = 0; (i < (unsigned)splitnum) && (bit > hashp->SPARES[i]); i++) {
+ }
+ offset = (i ? bit - hashp->SPARES[i - 1] : bit);
+ if (offset >= SPLITMASK)
+ return (0); /* Out of overflow pages */
+ addr = OADDR_OF(i, offset);
#ifdef DEBUG2
- (void)fprintf(stderr, "OVERFLOW_PAGE: ADDR: %d BIT: %d PAGE %d\n",
- addr, tmp1, tmp2);
+ (void)fprintf(stderr, "OVERFLOW_PAGE: ADDR: %d BIT: %d PAGE %d\n",
+ addr, tmp1, tmp2);
#endif
- /* Allocate and return the overflow page */
- return (addr);
+ /* Allocate and return the overflow page */
+ return (addr);
}
/*
@@ -1086,119 +1071,118 @@ found:
extern void
__free_ovflpage(HTAB *hashp, BUFHEAD *obufp)
{
- uint16 addr;
- uint32 *freep;
- uint32 bit_address, free_page, free_bit;
- uint16 ndx;
+ uint16 addr;
+ uint32 *freep;
+ uint32 bit_address, free_page, free_bit;
+ uint16 ndx;
- if(!obufp || !obufp->addr)
- return;
+ if (!obufp || !obufp->addr)
+ return;
- addr = obufp->addr;
+ addr = obufp->addr;
#ifdef DEBUG1
- (void)fprintf(stderr, "Freeing %d\n", addr);
+ (void)fprintf(stderr, "Freeing %d\n", addr);
#endif
- ndx = (((uint16)addr) >> SPLITSHIFT);
- bit_address =
- (ndx ? hashp->SPARES[ndx - 1] : 0) + (addr & SPLITMASK) - 1;
- if (bit_address < (uint32)hashp->LAST_FREED)
- hashp->LAST_FREED = bit_address;
- free_page = (bit_address >> (hashp->BSHIFT + BYTE_SHIFT));
- free_bit = bit_address & ((hashp->BSIZE << BYTE_SHIFT) - 1);
+ ndx = (((uint16)addr) >> SPLITSHIFT);
+ bit_address =
+ (ndx ? hashp->SPARES[ndx - 1] : 0) + (addr & SPLITMASK) - 1;
+ if (bit_address < (uint32)hashp->LAST_FREED)
+ hashp->LAST_FREED = bit_address;
+ free_page = (bit_address >> (hashp->BSHIFT + BYTE_SHIFT));
+ free_bit = bit_address & ((hashp->BSIZE << BYTE_SHIFT) - 1);
- if (!(freep = hashp->mapp[free_page]))
- freep = fetch_bitmap(hashp, free_page);
+ if (!(freep = hashp->mapp[free_page]))
+ freep = fetch_bitmap(hashp, free_page);
#ifdef DEBUG
- /*
- * This had better never happen. It means we tried to read a bitmap
- * that has already had overflow pages allocated off it, and we
- * failed to read it from the file.
- */
- if (!freep)
- {
- assert(0);
- return;
- }
+ /*
+ * This had better never happen. It means we tried to read a bitmap
+ * that has already had overflow pages allocated off it, and we
+ * failed to read it from the file.
+ */
+ if (!freep) {
+ assert(0);
+ return;
+ }
#endif
- CLRBIT(freep, free_bit);
+ CLRBIT(freep, free_bit);
#ifdef DEBUG2
- (void)fprintf(stderr, "FREE_OVFLPAGE: ADDR: %d BIT: %d PAGE %d\n",
- obufp->addr, free_bit, free_page);
+ (void)fprintf(stderr, "FREE_OVFLPAGE: ADDR: %d BIT: %d PAGE %d\n",
+ obufp->addr, free_bit, free_page);
#endif
- __reclaim_buf(hashp, obufp);
+ __reclaim_buf(hashp, obufp);
}
/*
* Returns:
- * 0 success
- * -1 failure
+ * 0 success
+ * -1 failure
*/
static int
open_temp(HTAB *hashp)
{
#ifdef XP_OS2
- hashp->fp = mkstemp(NULL);
+ hashp->fp = mkstemp(NULL);
#else
#if !defined(_WIN32) && !defined(_WINDOWS) && !defined(macintosh)
- sigset_t set, oset;
+ sigset_t set, oset;
#endif
#if !defined(macintosh)
- char * tmpdir;
- size_t len;
- char last;
+ char *tmpdir;
+ size_t len;
+ char last;
#endif
- static const char namestr[] = "/_hashXXXXXX";
- char filename[1024];
+ static const char namestr[] = "/_hashXXXXXX";
+ char filename[1024];
#if !defined(_WIN32) && !defined(_WINDOWS) && !defined(macintosh)
- /* Block signals; make sure file goes away at process exit. */
- (void)sigfillset(&set);
- (void)sigprocmask(SIG_BLOCK, &set, &oset);
+ /* Block signals; make sure file goes away at process exit. */
+ (void)sigfillset(&set);
+ (void)sigprocmask(SIG_BLOCK, &set, &oset);
#endif
- filename[0] = 0;
+ filename[0] = 0;
#if defined(macintosh)
- strcat(filename, namestr + 1);
+ strcat(filename, namestr + 1);
#else
- tmpdir = getenv("TMP");
- if (!tmpdir)
- tmpdir = getenv("TMPDIR");
- if (!tmpdir)
- tmpdir = getenv("TEMP");
- if (!tmpdir)
- tmpdir = ".";
- len = strlen(tmpdir);
- if (len && len < (sizeof filename - sizeof namestr)) {
- strcpy(filename, tmpdir);
- }
- len = strlen(filename);
- last = tmpdir[len - 1];
- strcat(filename, (last == '/' || last == '\\') ? namestr + 1 : namestr);
+ tmpdir = getenv("TMP");
+ if (!tmpdir)
+ tmpdir = getenv("TMPDIR");
+ if (!tmpdir)
+ tmpdir = getenv("TEMP");
+ if (!tmpdir)
+ tmpdir = ".";
+ len = strlen(tmpdir);
+ if (len && len < (sizeof filename - sizeof namestr)) {
+ strcpy(filename, tmpdir);
+ }
+ len = strlen(filename);
+ last = tmpdir[len - 1];
+ strcat(filename, (last == '/' || last == '\\') ? namestr + 1 : namestr);
#endif
#if defined(_WIN32) || defined(_WINDOWS)
- if ((hashp->fp = mkstempflags(filename, _O_BINARY|_O_TEMPORARY)) != -1) {
- if (hashp->filename) {
- free(hashp->filename);
- }
- hashp->filename = strdup(filename);
- hashp->is_temp = 1;
- }
+ if ((hashp->fp = mkstempflags(filename, _O_BINARY | _O_TEMPORARY)) != -1) {
+ if (hashp->filename) {
+ free(hashp->filename);
+ }
+ hashp->filename = strdup(filename);
+ hashp->is_temp = 1;
+ }
#else
- if ((hashp->fp = mkstemp(filename)) != -1) {
- (void)unlink(filename);
+ if ((hashp->fp = mkstemp(filename)) != -1) {
+ (void)unlink(filename);
#if !defined(macintosh)
- (void)fcntl(hashp->fp, F_SETFD, 1);
-#endif
- }
+ (void)fcntl(hashp->fp, F_SETFD, 1);
+#endif
+ }
#endif
#if !defined(_WIN32) && !defined(_WINDOWS) && !defined(macintosh)
- (void)sigprocmask(SIG_SETMASK, &oset, (sigset_t *)NULL);
+ (void)sigprocmask(SIG_SETMASK, &oset, (sigset_t *)NULL);
#endif
-#endif /* !OS2 */
- return (hashp->fp != -1 ? 0 : -1);
+#endif /* !OS2 */
+ return (hashp->fp != -1 ? 0 : -1);
}
/*
@@ -1206,63 +1190,63 @@ open_temp(HTAB *hashp)
* an overflow pair, so we need to shift things.
*/
static void
-squeeze_key(uint16 *sp, const DBT * key, const DBT * val)
+squeeze_key(uint16 *sp, const DBT *key, const DBT *val)
{
- register char *p;
- uint16 free_space, n, off, pageno;
-
- p = (char *)sp;
- n = sp[0];
- free_space = FREESPACE(sp);
- off = OFFSET(sp);
-
- pageno = sp[n - 1];
- off -= key->size;
- sp[n - 1] = off;
- memmove(p + off, key->data, key->size);
- off -= val->size;
- sp[n] = off;
- memmove(p + off, val->data, val->size);
- sp[0] = n + 2;
- sp[n + 1] = pageno;
- sp[n + 2] = OVFLPAGE;
- FREESPACE(sp) = free_space - PAIRSIZE(key, val);
- OFFSET(sp) = off;
+ register char *p;
+ uint16 free_space, n, off, pageno;
+
+ p = (char *)sp;
+ n = sp[0];
+ free_space = FREESPACE(sp);
+ off = OFFSET(sp);
+
+ pageno = sp[n - 1];
+ off -= key->size;
+ sp[n - 1] = off;
+ memmove(p + off, key->data, key->size);
+ off -= val->size;
+ sp[n] = off;
+ memmove(p + off, val->data, val->size);
+ sp[0] = n + 2;
+ sp[n + 1] = pageno;
+ sp[n + 2] = OVFLPAGE;
+ FREESPACE(sp) = free_space - PAIRSIZE(key, val);
+ OFFSET(sp) = off;
}
static uint32 *
fetch_bitmap(HTAB *hashp, uint32 ndx)
{
- if (ndx >= (unsigned)hashp->nmaps)
- return (NULL);
- if ((hashp->mapp[ndx] = (uint32 *)malloc((size_t)hashp->BSIZE)) == NULL)
- return (NULL);
- if (__get_page(hashp,
- (char *)hashp->mapp[ndx], hashp->BITMAPS[ndx], 0, 1, 1)) {
- free(hashp->mapp[ndx]);
- hashp->mapp[ndx] = NULL; /* NEW: 9-11-95 */
- return (NULL);
- }
- return (hashp->mapp[ndx]);
+ if (ndx >= (unsigned)hashp->nmaps)
+ return (NULL);
+ if ((hashp->mapp[ndx] = (uint32 *)malloc((size_t)hashp->BSIZE)) == NULL)
+ return (NULL);
+ if (__get_page(hashp,
+ (char *)hashp->mapp[ndx], hashp->BITMAPS[ndx], 0, 1, 1)) {
+ free(hashp->mapp[ndx]);
+ hashp->mapp[ndx] = NULL; /* NEW: 9-11-95 */
+ return (NULL);
+ }
+ return (hashp->mapp[ndx]);
}
#ifdef DEBUG4
int
print_chain(int addr)
{
- BUFHEAD *bufp;
- short *bp, oaddr;
-
- (void)fprintf(stderr, "%d ", addr);
- bufp = __get_buf(hashp, addr, NULL, 0);
- bp = (short *)bufp->page;
- while (bp[0] && ((bp[bp[0]] == OVFLPAGE) ||
- ((bp[0] > 2) && bp[2] < REAL_KEY))) {
- oaddr = bp[bp[0] - 1];
- (void)fprintf(stderr, "%d ", (int)oaddr);
- bufp = __get_buf(hashp, (int)oaddr, bufp, 0);
- bp = (short *)bufp->page;
- }
- (void)fprintf(stderr, "\n");
+ BUFHEAD *bufp;
+ short *bp, oaddr;
+
+ (void)fprintf(stderr, "%d ", addr);
+ bufp = __get_buf(hashp, addr, NULL, 0);
+ bp = (short *)bufp->page;
+ while (bp[0] && ((bp[bp[0]] == OVFLPAGE) ||
+ ((bp[0] > 2) && bp[2] < REAL_KEY))) {
+ oaddr = bp[bp[0] - 1];
+ (void)fprintf(stderr, "%d ", (int)oaddr);
+ bufp = __get_buf(hashp, (int)oaddr, bufp, 0);
+ bp = (short *)bufp->page;
+ }
+ (void)fprintf(stderr, "\n");
}
#endif
diff --git a/nss/lib/dbm/src/hash.c b/nss/lib/dbm/src/hash.c
index b3a904a..b80aad4 100644
--- a/nss/lib/dbm/src/hash.c
+++ b/nss/lib/dbm/src/hash.c
@@ -1,6 +1,6 @@
/*-
* Copyright (c) 1990, 1993, 1994
- * The Regents of the University of California. All rights reserved.
+ * The Regents of the University of California. All rights reserved.
*
* This code is derived from software contributed to Berkeley by
* Margo Seltzer.
@@ -13,7 +13,7 @@
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
- * 3. ***REMOVED*** - see
+ * 3. ***REMOVED*** - see
* ftp://ftp.cs.berkeley.edu/pub/4bsd/README.Impt.License.Change
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
@@ -33,7 +33,7 @@
*/
#if defined(LIBC_SCCS) && !defined(lint)
-static char sccsid[] = "@(#)hash.c 8.9 (Berkeley) 6/16/94";
+static char sccsid[] = "@(#)hash.c 8.9 (Berkeley) 6/16/94";
#endif /* LIBC_SCCS and not lint */
#if !defined(_WIN32) && !defined(_WINDOWS) && !defined(macintosh)
@@ -61,7 +61,7 @@ static char sccsid[] = "@(#)hash.c 8.9 (Berkeley) 6/16/94";
#if !defined(_WIN32) && !defined(_WINDOWS) && !defined(macintosh)
#include <unistd.h>
#endif
-#if defined(_WIN32) || defined(_WINDOWS)
+#if defined(_WIN32) || defined(_WINDOWS)
#include <windows.h>
#endif
@@ -74,34 +74,38 @@ static char sccsid[] = "@(#)hash.c 8.9 (Berkeley) 6/16/94";
/*
#include "extern.h"
*/
-static int alloc_segs(HTAB *, int);
-static int flush_meta(HTAB *);
-static int hash_access(HTAB *, ACTION, DBT *, DBT *);
-static int hash_close(DB *);
-static int hash_delete(const DB *, const DBT *, uint);
-static int hash_fd(const DB *);
-static int hash_get(const DB *, const DBT *, DBT *, uint);
-static int hash_put(const DB *, DBT *, const DBT *, uint);
+static int alloc_segs(HTAB *, int);
+static int flush_meta(HTAB *);
+static int hash_access(HTAB *, ACTION, DBT *, DBT *);
+static int hash_close(DB *);
+static int hash_delete(const DB *, const DBT *, uint);
+static int hash_fd(const DB *);
+static int hash_get(const DB *, const DBT *, DBT *, uint);
+static int hash_put(const DB *, DBT *, const DBT *, uint);
static void *hash_realloc(SEGMENT **, size_t, size_t);
-static int hash_seq(const DB *, DBT *, DBT *, uint);
-static int hash_sync(const DB *, uint);
-static int hdestroy(HTAB *);
+static int hash_seq(const DB *, DBT *, DBT *, uint);
+static int hash_sync(const DB *, uint);
+static int hdestroy(HTAB *);
static HTAB *init_hash(HTAB *, const char *, HASHINFO *);
-static int init_htab(HTAB *, int);
+static int init_htab(HTAB *, int);
#if BYTE_ORDER == LITTLE_ENDIAN
-static void swap_header(HTAB *);
-static void swap_header_copy(HASHHDR *, HASHHDR *);
+static void swap_header(HTAB *);
+static void swap_header_copy(HASHHDR *, HASHHDR *);
#endif
/* Fast arithmetic, relying on powers of 2, */
-#define MOD(x, y) ((x) & ((y) - 1))
+#define MOD(x, y) ((x) & ((y)-1))
-#define RETURN_ERROR(ERR, LOC) { save_errno = ERR; goto LOC; }
+#define RETURN_ERROR(ERR, LOC) \
+ { \
+ save_errno = ERR; \
+ goto LOC; \
+ }
/* Return values */
-#define SUCCESS (0)
-#define DBM_ERROR (-1)
-#define ABNORMAL (1)
+#define SUCCESS (0)
+#define DBM_ERROR (-1)
+#define ABNORMAL (1)
#ifdef HASH_STATISTICS
int hash_accesses, hash_collisions, hash_expansions, hash_overflows;
@@ -109,285 +113,282 @@ int hash_accesses, hash_collisions, hash_expansions, hash_overflows;
/* A new Lou (montulli@mozilla.com) routine.
*
- * The database is screwed.
+ * The database is screwed.
*
* This closes the file, flushing buffers as appropriate.
*/
static void
__remove_database(DB *dbp)
{
- HTAB *hashp = (HTAB *)dbp->internal;
+ HTAB *hashp = (HTAB *)dbp->internal;
- assert(0);
+ assert(0);
- if (!hashp)
- return;
- hdestroy(hashp);
- dbp->internal = NULL;
+ if (!hashp)
+ return;
+ hdestroy(hashp);
+ dbp->internal = NULL;
}
/************************** INTERFACE ROUTINES ***************************/
/* OPEN/CLOSE */
-
extern DB *
__hash_open(const char *file, int flags, int mode, const HASHINFO *info, int dflags)
{
- HTAB *hashp=NULL;
- struct stat statbuf;
- DB *dbp;
- int bpages, hdrsize, new_table, nsegs, save_errno;
-
- if ((flags & O_ACCMODE) == O_WRONLY) {
- errno = EINVAL;
- return NULL;
- }
-
- /* zero the statbuffer so that
- * we can check it for a non-zero
- * date to see if stat succeeded
- */
- memset(&statbuf, 0, sizeof(struct stat));
-
- if (!(hashp = (HTAB *)calloc(1, sizeof(HTAB)))) {
- errno = ENOMEM;
- return NULL;
- }
- hashp->fp = NO_FILE;
- if(file)
- hashp->filename = strdup(file);
-
- /*
- * Even if user wants write only, we need to be able to read
- * the actual file, so we need to open it read/write. But, the
- * field in the hashp structure needs to be accurate so that
- * we can check accesses.
- */
- hashp->flags = flags;
-
- new_table = 0;
- if (!file || (flags & O_TRUNC) || (stat(file, &statbuf) && (errno == ENOENT)))
- {
- if (errno == ENOENT)
- errno = 0; /* Just in case someone looks at errno */
- new_table = 1;
- }
- else if(statbuf.st_mtime && statbuf.st_size == 0)
- {
- /* check for a zero length file and delete it
- * if it exists
- */
- new_table = 1;
- }
- hashp->file_size = statbuf.st_size;
-
- if (file) {
-#if defined(_WIN32) || defined(_WINDOWS) || defined (macintosh) || defined(XP_OS2)
- if ((hashp->fp = DBFILE_OPEN(file, flags | O_BINARY, mode)) == -1)
- RETURN_ERROR(errno, error1);
+ HTAB *hashp = NULL;
+ struct stat statbuf;
+ DB *dbp;
+ int bpages, hdrsize, new_table, nsegs, save_errno;
+
+ if ((flags & O_ACCMODE) == O_WRONLY) {
+ errno = EINVAL;
+ return NULL;
+ }
+
+ /* zero the statbuffer so that
+ * we can check it for a non-zero
+ * date to see if stat succeeded
+ */
+ memset(&statbuf, 0, sizeof(struct stat));
+
+ if (!(hashp = (HTAB *)calloc(1, sizeof(HTAB)))) {
+ errno = ENOMEM;
+ return NULL;
+ }
+ hashp->fp = NO_FILE;
+ if (file)
+ hashp->filename = strdup(file);
+
+ /*
+ * Even if user wants write only, we need to be able to read
+ * the actual file, so we need to open it read/write. But, the
+ * field in the hashp structure needs to be accurate so that
+ * we can check accesses.
+ */
+ hashp->flags = flags;
+
+ new_table = 0;
+ if (!file || (flags & O_TRUNC) || (stat(file, &statbuf) && (errno == ENOENT))) {
+ if (errno == ENOENT)
+ errno = 0; /* Just in case someone looks at errno */
+ new_table = 1;
+ } else if (statbuf.st_mtime && statbuf.st_size == 0) {
+ /* check for a zero length file and delete it
+ * if it exists
+ */
+ new_table = 1;
+ }
+ hashp->file_size = statbuf.st_size;
+
+ if (file) {
+#if defined(_WIN32) || defined(_WINDOWS) || defined(macintosh) || defined(XP_OS2)
+ if ((hashp->fp = DBFILE_OPEN(file, flags | O_BINARY, mode)) == -1)
+ RETURN_ERROR(errno, error1);
#else
- if ((hashp->fp = open(file, flags, mode)) == -1)
- RETURN_ERROR(errno, error1);
- (void)fcntl(hashp->fp, F_SETFD, 1);
+ if ((hashp->fp = open(file, flags, mode)) == -1)
+ RETURN_ERROR(errno, error1);
+ (void)fcntl(hashp->fp, F_SETFD, 1);
#endif
- }
- if (new_table) {
- if (!init_hash(hashp, file, (HASHINFO *)info))
- RETURN_ERROR(errno, error1);
- } else {
- /* Table already exists */
- if (info && info->hash)
- hashp->hash = info->hash;
- else
- hashp->hash = __default_hash;
-
- hdrsize = read(hashp->fp, (char *)&hashp->hdr, sizeof(HASHHDR));
- if (hdrsize == -1)
- RETURN_ERROR(errno, error1);
- if (hdrsize != sizeof(HASHHDR))
- RETURN_ERROR(EFTYPE, error1);
+ }
+ if (new_table) {
+ if (!init_hash(hashp, file, (HASHINFO *)info))
+ RETURN_ERROR(errno, error1);
+ } else {
+ /* Table already exists */
+ if (info && info->hash)
+ hashp->hash = info->hash;
+ else
+ hashp->hash = __default_hash;
+
+ hdrsize = read(hashp->fp, (char *)&hashp->hdr, sizeof(HASHHDR));
+ if (hdrsize == -1)
+ RETURN_ERROR(errno, error1);
+ if (hdrsize != sizeof(HASHHDR))
+ RETURN_ERROR(EFTYPE, error1);
#if BYTE_ORDER == LITTLE_ENDIAN
- swap_header(hashp);
+ swap_header(hashp);
#endif
- /* Verify file type, versions and hash function */
- if (hashp->MAGIC != HASHMAGIC)
- RETURN_ERROR(EFTYPE, error1);
-#define OLDHASHVERSION 1
- if (hashp->VERSION != HASHVERSION &&
- hashp->VERSION != OLDHASHVERSION)
- RETURN_ERROR(EFTYPE, error1);
- if (hashp->hash(CHARKEY, sizeof(CHARKEY)) != hashp->H_CHARKEY)
- RETURN_ERROR(EFTYPE, error1);
- if (hashp->NKEYS < 0) /* Old bad database. */
- RETURN_ERROR(EFTYPE, error1);
-
- /*
- * Figure out how many segments we need. Max_Bucket is the
- * maximum bucket number, so the number of buckets is
- * max_bucket + 1.
- */
- nsegs = (hashp->MAX_BUCKET + 1 + hashp->SGSIZE - 1) /
- hashp->SGSIZE;
- hashp->nsegs = 0;
- if (alloc_segs(hashp, nsegs))
- /* If alloc_segs fails, errno will have been set. */
- RETURN_ERROR(errno, error1);
- /* Read in bitmaps */
- bpages = (hashp->SPARES[hashp->OVFL_POINT] +
- (hashp->BSIZE << BYTE_SHIFT) - 1) >>
- (hashp->BSHIFT + BYTE_SHIFT);
-
- hashp->nmaps = bpages;
- (void)memset(&hashp->mapp[0], 0, bpages * sizeof(uint32 *));
- }
-
- /* Initialize Buffer Manager */
- if (info && info->cachesize)
- __buf_init(hashp, (int32) info->cachesize);
- else
- __buf_init(hashp, DEF_BUFSIZE);
-
- hashp->new_file = new_table;
+ /* Verify file type, versions and hash function */
+ if (hashp->MAGIC != HASHMAGIC)
+ RETURN_ERROR(EFTYPE, error1);
+#define OLDHASHVERSION 1
+ if (hashp->VERSION != HASHVERSION &&
+ hashp->VERSION != OLDHASHVERSION)
+ RETURN_ERROR(EFTYPE, error1);
+ if (hashp->hash(CHARKEY, sizeof(CHARKEY)) != hashp->H_CHARKEY)
+ RETURN_ERROR(EFTYPE, error1);
+ if (hashp->NKEYS < 0) /* Old bad database. */
+ RETURN_ERROR(EFTYPE, error1);
+
+ /*
+ * Figure out how many segments we need. Max_Bucket is the
+ * maximum bucket number, so the number of buckets is
+ * max_bucket + 1.
+ */
+ nsegs = (hashp->MAX_BUCKET + 1 + hashp->SGSIZE - 1) /
+ hashp->SGSIZE;
+ hashp->nsegs = 0;
+ if (alloc_segs(hashp, nsegs))
+ /* If alloc_segs fails, errno will have been set. */
+ RETURN_ERROR(errno, error1);
+ /* Read in bitmaps */
+ bpages = (hashp->SPARES[hashp->OVFL_POINT] +
+ (hashp->BSIZE << BYTE_SHIFT) - 1) >>
+ (hashp->BSHIFT + BYTE_SHIFT);
+
+ hashp->nmaps = bpages;
+ (void)memset(&hashp->mapp[0], 0, bpages * sizeof(uint32 *));
+ }
+
+ /* Initialize Buffer Manager */
+ if (info && info->cachesize)
+ __buf_init(hashp, (int32)info->cachesize);
+ else
+ __buf_init(hashp, DEF_BUFSIZE);
+
+ hashp->new_file = new_table;
#ifdef macintosh
- hashp->save_file = file && !(hashp->flags & O_RDONLY);
+ hashp->save_file = file && !(hashp->flags & O_RDONLY);
#else
- hashp->save_file = file && (hashp->flags & O_RDWR);
+ hashp->save_file = file && (hashp->flags & O_RDWR);
#endif
- hashp->cbucket = -1;
- if (!(dbp = (DB *)malloc(sizeof(DB)))) {
- RETURN_ERROR(ENOMEM, error1);
- }
- dbp->internal = hashp;
- dbp->close = hash_close;
- dbp->del = hash_delete;
- dbp->fd = hash_fd;
- dbp->get = hash_get;
- dbp->put = hash_put;
- dbp->seq = hash_seq;
- dbp->sync = hash_sync;
- dbp->type = DB_HASH;
+ hashp->cbucket = -1;
+ if (!(dbp = (DB *)malloc(sizeof(DB)))) {
+ RETURN_ERROR(ENOMEM, error1);
+ }
+ dbp->internal = hashp;
+ dbp->close = hash_close;
+ dbp->del = hash_delete;
+ dbp->fd = hash_fd;
+ dbp->get = hash_get;
+ dbp->put = hash_put;
+ dbp->seq = hash_seq;
+ dbp->sync = hash_sync;
+ dbp->type = DB_HASH;
#ifdef HASH_STATISTICS
- hash_overflows = hash_accesses = hash_collisions = hash_expansions = 0;
+ hash_overflows = hash_accesses = hash_collisions = hash_expansions = 0;
#endif
- return (dbp);
+ return (dbp);
error1:
- hdestroy(hashp);
- errno = save_errno;
- return (NULL);
+ hdestroy(hashp);
+ errno = save_errno;
+ return (NULL);
}
static int
hash_close(DB *dbp)
{
- HTAB *hashp;
- int retval;
+ HTAB *hashp;
+ int retval;
- if (!dbp)
- return (DBM_ERROR);
+ if (!dbp)
+ return (DBM_ERROR);
- hashp = (HTAB *)dbp->internal;
- if(!hashp)
- return (DBM_ERROR);
+ hashp = (HTAB *)dbp->internal;
+ if (!hashp)
+ return (DBM_ERROR);
- retval = hdestroy(hashp);
- free(dbp);
- return (retval);
+ retval = hdestroy(hashp);
+ free(dbp);
+ return (retval);
}
-static int hash_fd(const DB *dbp)
+static int
+hash_fd(const DB *dbp)
{
- HTAB *hashp;
+ HTAB *hashp;
- if (!dbp)
- return (DBM_ERROR);
+ if (!dbp)
+ return (DBM_ERROR);
- hashp = (HTAB *)dbp->internal;
- if(!hashp)
- return (DBM_ERROR);
+ hashp = (HTAB *)dbp->internal;
+ if (!hashp)
+ return (DBM_ERROR);
- if (hashp->fp == -1) {
- errno = ENOENT;
- return (-1);
- }
- return (hashp->fp);
+ if (hashp->fp == -1) {
+ errno = ENOENT;
+ return (-1);
+ }
+ return (hashp->fp);
}
/************************** LOCAL CREATION ROUTINES **********************/
static HTAB *
init_hash(HTAB *hashp, const char *file, HASHINFO *info)
{
- struct stat statbuf;
- int nelem;
-
- nelem = 1;
- hashp->NKEYS = 0;
- hashp->LORDER = BYTE_ORDER;
- hashp->BSIZE = DEF_BUCKET_SIZE;
- hashp->BSHIFT = DEF_BUCKET_SHIFT;
- hashp->SGSIZE = DEF_SEGSIZE;
- hashp->SSHIFT = DEF_SEGSIZE_SHIFT;
- hashp->DSIZE = DEF_DIRSIZE;
- hashp->FFACTOR = DEF_FFACTOR;
- hashp->hash = __default_hash;
- memset(hashp->SPARES, 0, sizeof(hashp->SPARES));
- memset(hashp->BITMAPS, 0, sizeof (hashp->BITMAPS));
-
- /* Fix bucket size to be optimal for file system */
- if (file != NULL) {
- if (stat(file, &statbuf))
- return (NULL);
+ struct stat statbuf;
+ int nelem;
+
+ nelem = 1;
+ hashp->NKEYS = 0;
+ hashp->LORDER = BYTE_ORDER;
+ hashp->BSIZE = DEF_BUCKET_SIZE;
+ hashp->BSHIFT = DEF_BUCKET_SHIFT;
+ hashp->SGSIZE = DEF_SEGSIZE;
+ hashp->SSHIFT = DEF_SEGSIZE_SHIFT;
+ hashp->DSIZE = DEF_DIRSIZE;
+ hashp->FFACTOR = DEF_FFACTOR;
+ hashp->hash = __default_hash;
+ memset(hashp->SPARES, 0, sizeof(hashp->SPARES));
+ memset(hashp->BITMAPS, 0, sizeof(hashp->BITMAPS));
+
+ /* Fix bucket size to be optimal for file system */
+ if (file != NULL) {
+ if (stat(file, &statbuf))
+ return (NULL);
#if !defined(_WIN32) && !defined(_WINDOWS) && !defined(macintosh) && !defined(XP_OS2)
#if defined(__QNX__) && !defined(__QNXNTO__)
- hashp->BSIZE = 512; /* preferred blk size on qnx4 */
+ hashp->BSIZE = 512; /* preferred blk size on qnx4 */
#else
- hashp->BSIZE = statbuf.st_blksize;
+ hashp->BSIZE = statbuf.st_blksize;
#endif
- /* new code added by Lou to reduce block
- * size down below MAX_BSIZE
- */
- if (hashp->BSIZE > MAX_BSIZE)
- hashp->BSIZE = MAX_BSIZE;
+ /* new code added by Lou to reduce block
+ * size down below MAX_BSIZE
+ */
+ if (hashp->BSIZE > MAX_BSIZE)
+ hashp->BSIZE = MAX_BSIZE;
#endif
- hashp->BSHIFT = __log2((uint32)hashp->BSIZE);
- }
-
- if (info) {
- if (info->bsize) {
- /* Round pagesize up to power of 2 */
- hashp->BSHIFT = __log2(info->bsize);
- hashp->BSIZE = 1 << hashp->BSHIFT;
- if (hashp->BSIZE > MAX_BSIZE) {
- errno = EINVAL;
- return (NULL);
- }
- }
- if (info->ffactor)
- hashp->FFACTOR = info->ffactor;
- if (info->hash)
- hashp->hash = info->hash;
- if (info->nelem)
- nelem = info->nelem;
- if (info->lorder) {
- if (info->lorder != BIG_ENDIAN &&
- info->lorder != LITTLE_ENDIAN) {
- errno = EINVAL;
- return (NULL);
- }
- hashp->LORDER = info->lorder;
- }
- }
- /* init_htab sets errno if it fails */
- if (init_htab(hashp, nelem))
- return (NULL);
- else
- return (hashp);
+ hashp->BSHIFT = __log2((uint32)hashp->BSIZE);
+ }
+
+ if (info) {
+ if (info->bsize) {
+ /* Round pagesize up to power of 2 */
+ hashp->BSHIFT = __log2(info->bsize);
+ hashp->BSIZE = 1 << hashp->BSHIFT;
+ if (hashp->BSIZE > MAX_BSIZE) {
+ errno = EINVAL;
+ return (NULL);
+ }
+ }
+ if (info->ffactor)
+ hashp->FFACTOR = info->ffactor;
+ if (info->hash)
+ hashp->hash = info->hash;
+ if (info->nelem)
+ nelem = info->nelem;
+ if (info->lorder) {
+ if (info->lorder != BIG_ENDIAN &&
+ info->lorder != LITTLE_ENDIAN) {
+ errno = EINVAL;
+ return (NULL);
+ }
+ hashp->LORDER = info->lorder;
+ }
+ }
+ /* init_htab sets errno if it fails */
+ if (init_htab(hashp, nelem))
+ return (NULL);
+ else
+ return (hashp);
}
/*
- * This calls alloc_segs which may run out of memory. Alloc_segs will
+ * This calls alloc_segs which may run out of memory. Alloc_segs will
* set errno, so we just pass the error information along.
*
* Returns 0 on No Error
@@ -395,39 +396,40 @@ init_hash(HTAB *hashp, const char *file, HASHINFO *info)
static int
init_htab(HTAB *hashp, int nelem)
{
- register int nbuckets, nsegs;
- int l2;
-
- /*
- * Divide number of elements by the fill factor and determine a
- * desired number of buckets. Allocate space for the next greater
- * power of two number of buckets.
- */
- nelem = (nelem - 1) / hashp->FFACTOR + 1;
-
- l2 = __log2((uint32)PR_MAX(nelem, 2));
- nbuckets = 1 << l2;
-
- hashp->SPARES[l2] = l2 + 1;
- hashp->SPARES[l2 + 1] = l2 + 1;
- hashp->OVFL_POINT = l2;
- hashp->LAST_FREED = 2;
-
- /* First bitmap page is at: splitpoint l2 page offset 1 */
- if (__ibitmap(hashp, (int)OADDR_OF(l2, 1), l2 + 1, 0))
- return (-1);
-
- hashp->MAX_BUCKET = hashp->LOW_MASK = nbuckets - 1;
- hashp->HIGH_MASK = (nbuckets << 1) - 1;
- hashp->HDRPAGES = ((PR_MAX(sizeof(HASHHDR), MINHDRSIZE) - 1) >>
- hashp->BSHIFT) + 1;
-
- nsegs = (nbuckets - 1) / hashp->SGSIZE + 1;
- nsegs = 1 << __log2((uint32)nsegs);
-
- if (nsegs > hashp->DSIZE)
- hashp->DSIZE = nsegs;
- return (alloc_segs(hashp, nsegs));
+ register int nbuckets, nsegs;
+ int l2;
+
+ /*
+ * Divide number of elements by the fill factor and determine a
+ * desired number of buckets. Allocate space for the next greater
+ * power of two number of buckets.
+ */
+ nelem = (nelem - 1) / hashp->FFACTOR + 1;
+
+ l2 = __log2((uint32)PR_MAX(nelem, 2));
+ nbuckets = 1 << l2;
+
+ hashp->SPARES[l2] = l2 + 1;
+ hashp->SPARES[l2 + 1] = l2 + 1;
+ hashp->OVFL_POINT = l2;
+ hashp->LAST_FREED = 2;
+
+ /* First bitmap page is at: splitpoint l2 page offset 1 */
+ if (__ibitmap(hashp, (int)OADDR_OF(l2, 1), l2 + 1, 0))
+ return (-1);
+
+ hashp->MAX_BUCKET = hashp->LOW_MASK = nbuckets - 1;
+ hashp->HIGH_MASK = (nbuckets << 1) - 1;
+ hashp->HDRPAGES = ((PR_MAX(sizeof(HASHHDR), MINHDRSIZE) - 1) >>
+ hashp->BSHIFT) +
+ 1;
+
+ nsegs = (nbuckets - 1) / hashp->SGSIZE + 1;
+ nsegs = 1 << __log2((uint32)nsegs);
+
+ if (nsegs > hashp->DSIZE)
+ hashp->DSIZE = nsegs;
+ return (alloc_segs(hashp, nsegs));
}
/********************** DESTROY/CLOSE ROUTINES ************************/
@@ -439,120 +441,120 @@ init_htab(HTAB *hashp, int nelem)
static int
hdestroy(HTAB *hashp)
{
- int i, save_errno;
+ int i, save_errno;
- save_errno = 0;
+ save_errno = 0;
#ifdef HASH_STATISTICS
- (void)fprintf(stderr, "hdestroy: accesses %ld collisions %ld\n",
- hash_accesses, hash_collisions);
- (void)fprintf(stderr, "hdestroy: expansions %ld\n",
- hash_expansions);
- (void)fprintf(stderr, "hdestroy: overflows %ld\n",
- hash_overflows);
- (void)fprintf(stderr, "keys %ld maxp %d segmentcount %d\n",
- hashp->NKEYS, hashp->MAX_BUCKET, hashp->nsegs);
-
- for (i = 0; i < NCACHED; i++)
- (void)fprintf(stderr,
- "spares[%d] = %d\n", i, hashp->SPARES[i]);
+ (void)fprintf(stderr, "hdestroy: accesses %ld collisions %ld\n",
+ hash_accesses, hash_collisions);
+ (void)fprintf(stderr, "hdestroy: expansions %ld\n",
+ hash_expansions);
+ (void)fprintf(stderr, "hdestroy: overflows %ld\n",
+ hash_overflows);
+ (void)fprintf(stderr, "keys %ld maxp %d segmentcount %d\n",
+ hashp->NKEYS, hashp->MAX_BUCKET, hashp->nsegs);
+
+ for (i = 0; i < NCACHED; i++)
+ (void)fprintf(stderr,
+ "spares[%d] = %d\n", i, hashp->SPARES[i]);
#endif
- /*
- * Call on buffer manager to free buffers, and if required,
- * write them to disk.
- */
- if (__buf_free(hashp, 1, hashp->save_file))
- save_errno = errno;
- if (hashp->dir) {
- free(*hashp->dir); /* Free initial segments */
- /* Free extra segments */
- while (hashp->exsegs--)
- free(hashp->dir[--hashp->nsegs]);
- free(hashp->dir);
- }
- if (flush_meta(hashp) && !save_errno)
- save_errno = errno;
- /* Free Bigmaps */
- for (i = 0; i < hashp->nmaps; i++)
- if (hashp->mapp[i])
- free(hashp->mapp[i]);
-
- if (hashp->fp != -1)
- (void)close(hashp->fp);
-
- if(hashp->filename) {
+ /*
+ * Call on buffer manager to free buffers, and if required,
+ * write them to disk.
+ */
+ if (__buf_free(hashp, 1, hashp->save_file))
+ save_errno = errno;
+ if (hashp->dir) {
+ free(*hashp->dir); /* Free initial segments */
+ /* Free extra segments */
+ while (hashp->exsegs--)
+ free(hashp->dir[--hashp->nsegs]);
+ free(hashp->dir);
+ }
+ if (flush_meta(hashp) && !save_errno)
+ save_errno = errno;
+ /* Free Bigmaps */
+ for (i = 0; i < hashp->nmaps; i++)
+ if (hashp->mapp[i])
+ free(hashp->mapp[i]);
+
+ if (hashp->fp != -1)
+ (void)close(hashp->fp);
+
+ if (hashp->filename) {
#if defined(_WIN32) || defined(_WINDOWS) || defined(XP_OS2)
- if (hashp->is_temp)
- (void)unlink(hashp->filename);
+ if (hashp->is_temp)
+ (void)unlink(hashp->filename);
#endif
- free(hashp->filename);
- }
- if (hashp->tmp_buf)
- free(hashp->tmp_buf);
- if (hashp->tmp_key)
- free(hashp->tmp_key);
- free(hashp);
- if (save_errno) {
- errno = save_errno;
- return (DBM_ERROR);
- }
- return (SUCCESS);
+ free(hashp->filename);
+ }
+ if (hashp->tmp_buf)
+ free(hashp->tmp_buf);
+ if (hashp->tmp_key)
+ free(hashp->tmp_key);
+ free(hashp);
+ if (save_errno) {
+ errno = save_errno;
+ return (DBM_ERROR);
+ }
+ return (SUCCESS);
}
-#if defined(_WIN32) || defined(_WINDOWS)
+#if defined(_WIN32) || defined(_WINDOWS)
/*
- * Close and reopen file to force file length update on windows.
+ * Close and reopen file to force file length update on windows.
*
* Returns:
- * 0 == OK
- * -1 DBM_ERROR
+ * 0 == OK
+ * -1 DBM_ERROR
*/
static int
update_EOF(HTAB *hashp)
{
#if defined(DBM_REOPEN_ON_FLUSH)
- char * file = hashp->filename;
- off_t file_size;
- int flags;
- int mode = -1;
- struct stat statbuf;
-
- memset(&statbuf, 0, sizeof statbuf);
-
- /* make sure we won't lose the file by closing it. */
- if (!file || (stat(file, &statbuf) && (errno == ENOENT))) {
- /* pretend we did it. */
- return 0;
- }
-
- (void)close(hashp->fp);
-
- flags = hashp->flags & ~(O_TRUNC | O_CREAT | O_EXCL);
-
- if ((hashp->fp = DBFILE_OPEN(file, flags | O_BINARY, mode)) == -1)
- return -1;
- file_size = lseek(hashp->fp, (off_t)0, SEEK_END);
- if (file_size == -1)
- return -1;
- hashp->file_size = file_size;
- return 0;
+ char *file = hashp->filename;
+ off_t file_size;
+ int flags;
+ int mode = -1;
+ struct stat statbuf;
+
+ memset(&statbuf, 0, sizeof statbuf);
+
+ /* make sure we won't lose the file by closing it. */
+ if (!file || (stat(file, &statbuf) && (errno == ENOENT))) {
+ /* pretend we did it. */
+ return 0;
+ }
+
+ (void)close(hashp->fp);
+
+ flags = hashp->flags & ~(O_TRUNC | O_CREAT | O_EXCL);
+
+ if ((hashp->fp = DBFILE_OPEN(file, flags | O_BINARY, mode)) == -1)
+ return -1;
+ file_size = lseek(hashp->fp, (off_t)0, SEEK_END);
+ if (file_size == -1)
+ return -1;
+ hashp->file_size = file_size;
+ return 0;
#else
- int fd = hashp->fp;
- off_t file_size = lseek(fd, (off_t)0, SEEK_END);
- HANDLE handle = (HANDLE)_get_osfhandle(fd);
- BOOL cool = FlushFileBuffers(handle);
+ int fd = hashp->fp;
+ off_t file_size = lseek(fd, (off_t)0, SEEK_END);
+ HANDLE handle = (HANDLE)_get_osfhandle(fd);
+ BOOL cool = FlushFileBuffers(handle);
#ifdef DEBUG3
- if (!cool) {
- DWORD err = GetLastError();
- (void)fprintf(stderr,
- "FlushFileBuffers failed, last error = %d, 0x%08x\n",
- err, err);
- }
+ if (!cool) {
+ DWORD err = GetLastError();
+ (void)fprintf(stderr,
+ "FlushFileBuffers failed, last error = %d, 0x%08x\n",
+ err, err);
+ }
#endif
- if (file_size == -1)
- return -1;
- hashp->file_size = file_size;
- return cool ? 0 : -1;
+ if (file_size == -1)
+ return -1;
+ hashp->file_size = file_size;
+ return cool ? 0 : -1;
#endif
}
#endif
@@ -561,83 +563,82 @@ update_EOF(HTAB *hashp)
* Write modified pages to disk
*
* Returns:
- * 0 == OK
- * -1 DBM_ERROR
+ * 0 == OK
+ * -1 DBM_ERROR
*/
static int
hash_sync(const DB *dbp, uint flags)
{
- HTAB *hashp;
-
- if (flags != 0) {
- errno = EINVAL;
- return (DBM_ERROR);
- }
-
- if (!dbp)
- return (DBM_ERROR);
-
- hashp = (HTAB *)dbp->internal;
- if(!hashp)
- return (DBM_ERROR);
-
- if (!hashp->save_file)
- return (0);
- if (__buf_free(hashp, 0, 1) || flush_meta(hashp))
- return (DBM_ERROR);
-#if defined(_WIN32) || defined(_WINDOWS)
- if (hashp->updateEOF && hashp->filename && !hashp->is_temp) {
- int status = update_EOF(hashp);
- hashp->updateEOF = 0;
- if (status)
- return status;
- }
+ HTAB *hashp;
+
+ if (flags != 0) {
+ errno = EINVAL;
+ return (DBM_ERROR);
+ }
+
+ if (!dbp)
+ return (DBM_ERROR);
+
+ hashp = (HTAB *)dbp->internal;
+ if (!hashp)
+ return (DBM_ERROR);
+
+ if (!hashp->save_file)
+ return (0);
+ if (__buf_free(hashp, 0, 1) || flush_meta(hashp))
+ return (DBM_ERROR);
+#if defined(_WIN32) || defined(_WINDOWS)
+ if (hashp->updateEOF && hashp->filename && !hashp->is_temp) {
+ int status = update_EOF(hashp);
+ hashp->updateEOF = 0;
+ if (status)
+ return status;
+ }
#endif
- hashp->new_file = 0;
- return (0);
+ hashp->new_file = 0;
+ return (0);
}
/*
* Returns:
- * 0 == OK
- * -1 indicates that errno should be set
+ * 0 == OK
+ * -1 indicates that errno should be set
*/
static int
flush_meta(HTAB *hashp)
{
- HASHHDR *whdrp;
+ HASHHDR *whdrp;
#if BYTE_ORDER == LITTLE_ENDIAN
- HASHHDR whdr;
+ HASHHDR whdr;
#endif
- int fp, i, wsize;
+ int fp, i, wsize;
- if (!hashp->save_file)
- return (0);
- hashp->MAGIC = HASHMAGIC;
- hashp->VERSION = HASHVERSION;
- hashp->H_CHARKEY = hashp->hash(CHARKEY, sizeof(CHARKEY));
+ if (!hashp->save_file)
+ return (0);
+ hashp->MAGIC = HASHMAGIC;
+ hashp->VERSION = HASHVERSION;
+ hashp->H_CHARKEY = hashp->hash(CHARKEY, sizeof(CHARKEY));
- fp = hashp->fp;
- whdrp = &hashp->hdr;
+ fp = hashp->fp;
+ whdrp = &hashp->hdr;
#if BYTE_ORDER == LITTLE_ENDIAN
- whdrp = &whdr;
- swap_header_copy(&hashp->hdr, whdrp);
+ whdrp = &whdr;
+ swap_header_copy(&hashp->hdr, whdrp);
#endif
- if ((lseek(fp, (off_t)0, SEEK_SET) == -1) ||
- ((wsize = write(fp, (char*)whdrp, sizeof(HASHHDR))) == -1))
- return (-1);
- else
- if (wsize != sizeof(HASHHDR)) {
- errno = EFTYPE;
- hashp->dbmerrno = errno;
- return (-1);
- }
- for (i = 0; i < NCACHED; i++)
- if (hashp->mapp[i])
- if (__put_page(hashp, (char *)hashp->mapp[i],
- hashp->BITMAPS[i], 0, 1))
- return (-1);
- return (0);
+ if ((lseek(fp, (off_t)0, SEEK_SET) == -1) ||
+ ((wsize = write(fp, (char *)whdrp, sizeof(HASHHDR))) == -1))
+ return (-1);
+ else if (wsize != sizeof(HASHHDR)) {
+ errno = EFTYPE;
+ hashp->dbmerrno = errno;
+ return (-1);
+ }
+ for (i = 0; i < NCACHED; i++)
+ if (hashp->mapp[i])
+ if (__put_page(hashp, (char *)hashp->mapp[i],
+ hashp->BITMAPS[i], 0, 1))
+ return (-1);
+ return (0);
}
/*******************************SEARCH ROUTINES *****************************/
@@ -645,111 +646,109 @@ flush_meta(HTAB *hashp)
* All the access routines return
*
* Returns:
- * 0 on SUCCESS
- * 1 to indicate an external DBM_ERROR (i.e. key not found, etc)
- * -1 to indicate an internal DBM_ERROR (i.e. out of memory, etc)
+ * 0 on SUCCESS
+ * 1 to indicate an external DBM_ERROR (i.e. key not found, etc)
+ * -1 to indicate an internal DBM_ERROR (i.e. out of memory, etc)
*/
static int
hash_get(
- const DB *dbp,
- const DBT *key,
- DBT *data,
- uint flag)
+ const DB *dbp,
+ const DBT *key,
+ DBT *data,
+ uint flag)
{
- HTAB *hashp;
- int rv;
+ HTAB *hashp;
+ int rv;
- hashp = (HTAB *)dbp->internal;
- if (!hashp)
- return (DBM_ERROR);
+ hashp = (HTAB *)dbp->internal;
+ if (!hashp)
+ return (DBM_ERROR);
- if (flag) {
- hashp->dbmerrno = errno = EINVAL;
- return (DBM_ERROR);
- }
+ if (flag) {
+ hashp->dbmerrno = errno = EINVAL;
+ return (DBM_ERROR);
+ }
- rv = hash_access(hashp, HASH_GET, (DBT *)key, data);
+ rv = hash_access(hashp, HASH_GET, (DBT *)key, data);
- if(rv == DATABASE_CORRUPTED_ERROR)
- {
+ if (rv == DATABASE_CORRUPTED_ERROR) {
#if defined(unix) && defined(DEBUG)
- printf("\n\nDBM Database has been corrupted, tell Lou...\n\n");
+ printf("\n\nDBM Database has been corrupted, tell Lou...\n\n");
#endif
- __remove_database((DB *)dbp);
- }
+ __remove_database((DB *)dbp);
+ }
- return(rv);
+ return (rv);
}
static int
hash_put(
- const DB *dbp,
- DBT *key,
- const DBT *data,
- uint flag)
+ const DB *dbp,
+ DBT *key,
+ const DBT *data,
+ uint flag)
{
- HTAB *hashp;
- int rv;
-
- hashp = (HTAB *)dbp->internal;
- if (!hashp)
- return (DBM_ERROR);
-
- if (flag && flag != R_NOOVERWRITE) {
- hashp->dbmerrno = errno = EINVAL;
- return (DBM_ERROR);
- }
- if ((hashp->flags & O_ACCMODE) == O_RDONLY) {
- hashp->dbmerrno = errno = EPERM;
- return (DBM_ERROR);
- }
-
- rv = hash_access(hashp, flag == R_NOOVERWRITE ?
- HASH_PUTNEW : HASH_PUT, (DBT *)key, (DBT *)data);
-
- if(rv == DATABASE_CORRUPTED_ERROR)
- {
+ HTAB *hashp;
+ int rv;
+
+ hashp = (HTAB *)dbp->internal;
+ if (!hashp)
+ return (DBM_ERROR);
+
+ if (flag && flag != R_NOOVERWRITE) {
+ hashp->dbmerrno = errno = EINVAL;
+ return (DBM_ERROR);
+ }
+ if ((hashp->flags & O_ACCMODE) == O_RDONLY) {
+ hashp->dbmerrno = errno = EPERM;
+ return (DBM_ERROR);
+ }
+
+ rv = hash_access(hashp, flag == R_NOOVERWRITE ? HASH_PUTNEW
+ : HASH_PUT,
+ (DBT *)key, (DBT *)data);
+
+ if (rv == DATABASE_CORRUPTED_ERROR) {
#if defined(unix) && defined(DEBUG)
- printf("\n\nDBM Database has been corrupted, tell Lou...\n\n");
+ printf("\n\nDBM Database has been corrupted, tell Lou...\n\n");
#endif
- __remove_database((DB *)dbp);
- }
+ __remove_database((DB *)dbp);
+ }
- return(rv);
+ return (rv);
}
static int
hash_delete(
- const DB *dbp,
- const DBT *key,
- uint flag) /* Ignored */
+ const DB *dbp,
+ const DBT *key,
+ uint flag) /* Ignored */
{
- HTAB *hashp;
- int rv;
-
- hashp = (HTAB *)dbp->internal;
- if (!hashp)
- return (DBM_ERROR);
-
- if (flag && flag != R_CURSOR) {
- hashp->dbmerrno = errno = EINVAL;
- return (DBM_ERROR);
- }
- if ((hashp->flags & O_ACCMODE) == O_RDONLY) {
- hashp->dbmerrno = errno = EPERM;
- return (DBM_ERROR);
- }
- rv = hash_access(hashp, HASH_DELETE, (DBT *)key, NULL);
-
- if(rv == DATABASE_CORRUPTED_ERROR)
- {
+ HTAB *hashp;
+ int rv;
+
+ hashp = (HTAB *)dbp->internal;
+ if (!hashp)
+ return (DBM_ERROR);
+
+ if (flag && flag != R_CURSOR) {
+ hashp->dbmerrno = errno = EINVAL;
+ return (DBM_ERROR);
+ }
+ if ((hashp->flags & O_ACCMODE) == O_RDONLY) {
+ hashp->dbmerrno = errno = EPERM;
+ return (DBM_ERROR);
+ }
+ rv = hash_access(hashp, HASH_DELETE, (DBT *)key, NULL);
+
+ if (rv == DATABASE_CORRUPTED_ERROR) {
#if defined(unix) && defined(DEBUG)
- printf("\n\nDBM Database has been corrupted, tell Lou...\n\n");
+ printf("\n\nDBM Database has been corrupted, tell Lou...\n\n");
#endif
- __remove_database((DB *)dbp);
- }
+ __remove_database((DB *)dbp);
+ }
- return(rv);
+ return (rv);
}
#define MAX_OVERFLOW_HASH_ACCESS_LOOPS 2000
@@ -758,294 +757,292 @@ hash_delete(
*/
static int
hash_access(
- HTAB *hashp,
- ACTION action,
- DBT *key, DBT *val)
+ HTAB *hashp,
+ ACTION action,
+ DBT *key, DBT *val)
{
- register BUFHEAD *rbufp;
- BUFHEAD *bufp, *save_bufp;
- register uint16 *bp;
- register long n, ndx, off;
- register size_t size;
- register char *kp;
- uint16 pageno;
- uint32 ovfl_loop_count=0;
+ register BUFHEAD *rbufp;
+ BUFHEAD *bufp, *save_bufp;
+ register uint16 *bp;
+ register long n, ndx, off;
+ register size_t size;
+ register char *kp;
+ uint16 pageno;
+ uint32 ovfl_loop_count = 0;
int32 last_overflow_page_no = -1;
#ifdef HASH_STATISTICS
- hash_accesses++;
+ hash_accesses++;
#endif
- off = hashp->BSIZE;
- size = key->size;
- kp = (char *)key->data;
- rbufp = __get_buf(hashp, __call_hash(hashp, kp, size), NULL, 0);
- if (!rbufp)
- return (DATABASE_CORRUPTED_ERROR);
- save_bufp = rbufp;
-
- /* Pin the bucket chain */
- rbufp->flags |= BUF_PIN;
- for (bp = (uint16 *)rbufp->page, n = *bp++, ndx = 1; ndx < n;)
- {
-
- if (bp[1] >= REAL_KEY) {
- /* Real key/data pair */
- if (size == (unsigned long)(off - *bp) &&
- memcmp(kp, rbufp->page + *bp, size) == 0)
- goto found;
- off = bp[1];
+ off = hashp->BSIZE;
+ size = key->size;
+ kp = (char *)key->data;
+ rbufp = __get_buf(hashp, __call_hash(hashp, kp, size), NULL, 0);
+ if (!rbufp)
+ return (DATABASE_CORRUPTED_ERROR);
+ save_bufp = rbufp;
+
+ /* Pin the bucket chain */
+ rbufp->flags |= BUF_PIN;
+ for (bp = (uint16 *)rbufp->page, n = *bp++, ndx = 1; ndx < n;) {
+
+ if (bp[1] >= REAL_KEY) {
+ /* Real key/data pair */
+ if (size == (unsigned long)(off - *bp) &&
+ memcmp(kp, rbufp->page + *bp, size) == 0)
+ goto found;
+ off = bp[1];
#ifdef HASH_STATISTICS
- hash_collisions++;
+ hash_collisions++;
#endif
- bp += 2;
- ndx += 2;
- } else if (bp[1] == OVFLPAGE) {
+ bp += 2;
+ ndx += 2;
+ } else if (bp[1] == OVFLPAGE) {
/* database corruption: overflow loop detection */
- if(last_overflow_page_no == (int32)*bp)
- return (DATABASE_CORRUPTED_ERROR);
+ if (last_overflow_page_no == (int32)*bp)
+ return (DATABASE_CORRUPTED_ERROR);
last_overflow_page_no = *bp;
- rbufp = __get_buf(hashp, *bp, rbufp, 0);
- if (!rbufp) {
- save_bufp->flags &= ~BUF_PIN;
- return (DBM_ERROR);
- }
+ rbufp = __get_buf(hashp, *bp, rbufp, 0);
+ if (!rbufp) {
+ save_bufp->flags &= ~BUF_PIN;
+ return (DBM_ERROR);
+ }
ovfl_loop_count++;
- if(ovfl_loop_count > MAX_OVERFLOW_HASH_ACCESS_LOOPS)
- return (DATABASE_CORRUPTED_ERROR);
-
- /* FOR LOOP INIT */
- bp = (uint16 *)rbufp->page;
- n = *bp++;
- ndx = 1;
- off = hashp->BSIZE;
- } else if (bp[1] < REAL_KEY) {
- if ((ndx =
- __find_bigpair(hashp, rbufp, ndx, kp, (int)size)) > 0)
- goto found;
- if (ndx == -2) {
- bufp = rbufp;
- if (!(pageno =
- __find_last_page(hashp, &bufp))) {
- ndx = 0;
- rbufp = bufp;
- break; /* FOR */
- }
- rbufp = __get_buf(hashp, pageno, bufp, 0);
- if (!rbufp) {
- save_bufp->flags &= ~BUF_PIN;
- return (DBM_ERROR);
- }
- /* FOR LOOP INIT */
- bp = (uint16 *)rbufp->page;
- n = *bp++;
- ndx = 1;
- off = hashp->BSIZE;
- } else {
- save_bufp->flags &= ~BUF_PIN;
- return (DBM_ERROR);
-
- }
- }
- }
-
- /* Not found */
- switch (action) {
- case HASH_PUT:
- case HASH_PUTNEW:
- if (__addel(hashp, rbufp, key, val)) {
- save_bufp->flags &= ~BUF_PIN;
- return (DBM_ERROR);
- } else {
- save_bufp->flags &= ~BUF_PIN;
- return (SUCCESS);
- }
- case HASH_GET:
- case HASH_DELETE:
- default:
- save_bufp->flags &= ~BUF_PIN;
- return (ABNORMAL);
- }
+ if (ovfl_loop_count > MAX_OVERFLOW_HASH_ACCESS_LOOPS)
+ return (DATABASE_CORRUPTED_ERROR);
+
+ /* FOR LOOP INIT */
+ bp = (uint16 *)rbufp->page;
+ n = *bp++;
+ ndx = 1;
+ off = hashp->BSIZE;
+ } else if (bp[1] < REAL_KEY) {
+ if ((ndx =
+ __find_bigpair(hashp, rbufp, ndx, kp, (int)size)) > 0)
+ goto found;
+ if (ndx == -2) {
+ bufp = rbufp;
+ if (!(pageno =
+ __find_last_page(hashp, &bufp))) {
+ ndx = 0;
+ rbufp = bufp;
+ break; /* FOR */
+ }
+ rbufp = __get_buf(hashp, pageno, bufp, 0);
+ if (!rbufp) {
+ save_bufp->flags &= ~BUF_PIN;
+ return (DBM_ERROR);
+ }
+ /* FOR LOOP INIT */
+ bp = (uint16 *)rbufp->page;
+ n = *bp++;
+ ndx = 1;
+ off = hashp->BSIZE;
+ } else {
+ save_bufp->flags &= ~BUF_PIN;
+ return (DBM_ERROR);
+ }
+ }
+ }
+
+ /* Not found */
+ switch (action) {
+ case HASH_PUT:
+ case HASH_PUTNEW:
+ if (__addel(hashp, rbufp, key, val)) {
+ save_bufp->flags &= ~BUF_PIN;
+ return (DBM_ERROR);
+ } else {
+ save_bufp->flags &= ~BUF_PIN;
+ return (SUCCESS);
+ }
+ case HASH_GET:
+ case HASH_DELETE:
+ default:
+ save_bufp->flags &= ~BUF_PIN;
+ return (ABNORMAL);
+ }
found:
- switch (action) {
- case HASH_PUTNEW:
- save_bufp->flags &= ~BUF_PIN;
- return (ABNORMAL);
- case HASH_GET:
- bp = (uint16 *)rbufp->page;
- if (bp[ndx + 1] < REAL_KEY) {
- if (__big_return(hashp, rbufp, ndx, val, 0))
- return (DBM_ERROR);
- } else {
- val->data = (uint8 *)rbufp->page + (int)bp[ndx + 1];
- val->size = bp[ndx] - bp[ndx + 1];
- }
- break;
- case HASH_PUT:
- if ((__delpair(hashp, rbufp, ndx)) ||
- (__addel(hashp, rbufp, key, val))) {
- save_bufp->flags &= ~BUF_PIN;
- return (DBM_ERROR);
- }
- break;
- case HASH_DELETE:
- if (__delpair(hashp, rbufp, ndx))
- return (DBM_ERROR);
- break;
- default:
- abort();
- }
- save_bufp->flags &= ~BUF_PIN;
- return (SUCCESS);
+ switch (action) {
+ case HASH_PUTNEW:
+ save_bufp->flags &= ~BUF_PIN;
+ return (ABNORMAL);
+ case HASH_GET:
+ bp = (uint16 *)rbufp->page;
+ if (bp[ndx + 1] < REAL_KEY) {
+ if (__big_return(hashp, rbufp, ndx, val, 0))
+ return (DBM_ERROR);
+ } else {
+ val->data = (uint8 *)rbufp->page + (int)bp[ndx + 1];
+ val->size = bp[ndx] - bp[ndx + 1];
+ }
+ break;
+ case HASH_PUT:
+ if ((__delpair(hashp, rbufp, ndx)) ||
+ (__addel(hashp, rbufp, key, val))) {
+ save_bufp->flags &= ~BUF_PIN;
+ return (DBM_ERROR);
+ }
+ break;
+ case HASH_DELETE:
+ if (__delpair(hashp, rbufp, ndx))
+ return (DBM_ERROR);
+ break;
+ default:
+ abort();
+ }
+ save_bufp->flags &= ~BUF_PIN;
+ return (SUCCESS);
}
static int
hash_seq(
- const DB *dbp,
- DBT *key, DBT *data,
- uint flag)
+ const DB *dbp,
+ DBT *key, DBT *data,
+ uint flag)
{
- register uint32 bucket;
- register BUFHEAD *bufp = NULL;
- HTAB *hashp;
- uint16 *bp, ndx;
-
- hashp = (HTAB *)dbp->internal;
- if (!hashp)
- return (DBM_ERROR);
-
- if (flag && flag != R_FIRST && flag != R_NEXT) {
- hashp->dbmerrno = errno = EINVAL;
- return (DBM_ERROR);
- }
+ register uint32 bucket;
+ register BUFHEAD *bufp = NULL;
+ HTAB *hashp;
+ uint16 *bp, ndx;
+
+ hashp = (HTAB *)dbp->internal;
+ if (!hashp)
+ return (DBM_ERROR);
+
+ if (flag && flag != R_FIRST && flag != R_NEXT) {
+ hashp->dbmerrno = errno = EINVAL;
+ return (DBM_ERROR);
+ }
#ifdef HASH_STATISTICS
- hash_accesses++;
+ hash_accesses++;
#endif
- if ((hashp->cbucket < 0) || (flag == R_FIRST)) {
- hashp->cbucket = 0;
- hashp->cndx = 1;
- hashp->cpage = NULL;
- }
-
- for (bp = NULL; !bp || !bp[0]; ) {
- if (!(bufp = hashp->cpage)) {
- for (bucket = hashp->cbucket;
- bucket <= (uint32)hashp->MAX_BUCKET;
- bucket++, hashp->cndx = 1) {
- bufp = __get_buf(hashp, bucket, NULL, 0);
- if (!bufp)
- return (DBM_ERROR);
- hashp->cpage = bufp;
- bp = (uint16 *)bufp->page;
- if (bp[0])
- break;
- }
- hashp->cbucket = bucket;
- if (hashp->cbucket > hashp->MAX_BUCKET) {
- hashp->cbucket = -1;
- return (ABNORMAL);
- }
- } else
- bp = (uint16 *)hashp->cpage->page;
+ if ((hashp->cbucket < 0) || (flag == R_FIRST)) {
+ hashp->cbucket = 0;
+ hashp->cndx = 1;
+ hashp->cpage = NULL;
+ }
+
+ for (bp = NULL; !bp || !bp[0];) {
+ if (!(bufp = hashp->cpage)) {
+ for (bucket = hashp->cbucket;
+ bucket <= (uint32)hashp->MAX_BUCKET;
+ bucket++, hashp->cndx = 1) {
+ bufp = __get_buf(hashp, bucket, NULL, 0);
+ if (!bufp)
+ return (DBM_ERROR);
+ hashp->cpage = bufp;
+ bp = (uint16 *)bufp->page;
+ if (bp[0])
+ break;
+ }
+ hashp->cbucket = bucket;
+ if (hashp->cbucket > hashp->MAX_BUCKET) {
+ hashp->cbucket = -1;
+ return (ABNORMAL);
+ }
+ } else
+ bp = (uint16 *)hashp->cpage->page;
#ifdef DEBUG
- assert(bp);
- assert(bufp);
+ assert(bp);
+ assert(bufp);
#endif
- while (bp[hashp->cndx + 1] == OVFLPAGE) {
- bufp = hashp->cpage =
- __get_buf(hashp, bp[hashp->cndx], bufp, 0);
- if (!bufp)
- return (DBM_ERROR);
- bp = (uint16 *)(bufp->page);
- hashp->cndx = 1;
- }
- if (!bp[0]) {
- hashp->cpage = NULL;
- ++hashp->cbucket;
- }
- }
- ndx = hashp->cndx;
- if (bp[ndx + 1] < REAL_KEY) {
- if (__big_keydata(hashp, bufp, key, data, 1))
- return (DBM_ERROR);
- } else {
- key->data = (uint8 *)hashp->cpage->page + bp[ndx];
- key->size = (ndx > 1 ? bp[ndx - 1] : hashp->BSIZE) - bp[ndx];
- data->data = (uint8 *)hashp->cpage->page + bp[ndx + 1];
- data->size = bp[ndx] - bp[ndx + 1];
- ndx += 2;
- if (ndx > bp[0]) {
- hashp->cpage = NULL;
- hashp->cbucket++;
- hashp->cndx = 1;
- } else
- hashp->cndx = ndx;
- }
- return (SUCCESS);
+ while (bp[hashp->cndx + 1] == OVFLPAGE) {
+ bufp = hashp->cpage =
+ __get_buf(hashp, bp[hashp->cndx], bufp, 0);
+ if (!bufp)
+ return (DBM_ERROR);
+ bp = (uint16 *)(bufp->page);
+ hashp->cndx = 1;
+ }
+ if (!bp[0]) {
+ hashp->cpage = NULL;
+ ++hashp->cbucket;
+ }
+ }
+ ndx = hashp->cndx;
+ if (bp[ndx + 1] < REAL_KEY) {
+ if (__big_keydata(hashp, bufp, key, data, 1))
+ return (DBM_ERROR);
+ } else {
+ key->data = (uint8 *)hashp->cpage->page + bp[ndx];
+ key->size = (ndx > 1 ? bp[ndx - 1] : hashp->BSIZE) - bp[ndx];
+ data->data = (uint8 *)hashp->cpage->page + bp[ndx + 1];
+ data->size = bp[ndx] - bp[ndx + 1];
+ ndx += 2;
+ if (ndx > bp[0]) {
+ hashp->cpage = NULL;
+ hashp->cbucket++;
+ hashp->cndx = 1;
+ } else
+ hashp->cndx = ndx;
+ }
+ return (SUCCESS);
}
/********************************* UTILITIES ************************/
/*
* Returns:
- * 0 ==> OK
- * -1 ==> Error
+ * 0 ==> OK
+ * -1 ==> Error
*/
extern int
__expand_table(HTAB *hashp)
{
- uint32 old_bucket, new_bucket;
- int new_segnum, spare_ndx;
- size_t dirsize;
+ uint32 old_bucket, new_bucket;
+ int new_segnum, spare_ndx;
+ size_t dirsize;
#ifdef HASH_STATISTICS
- hash_expansions++;
+ hash_expansions++;
#endif
- new_bucket = ++hashp->MAX_BUCKET;
- old_bucket = (hashp->MAX_BUCKET & hashp->LOW_MASK);
-
- new_segnum = new_bucket >> hashp->SSHIFT;
-
- /* Check if we need a new segment */
- if (new_segnum >= hashp->nsegs) {
- /* Check if we need to expand directory */
- if (new_segnum >= hashp->DSIZE) {
- /* Reallocate directory */
- dirsize = hashp->DSIZE * sizeof(SEGMENT *);
- if (!hash_realloc(&hashp->dir, dirsize, dirsize << 1))
- return (-1);
- hashp->DSIZE = dirsize << 1;
- }
- if ((hashp->dir[new_segnum] =
- (SEGMENT)calloc((size_t)hashp->SGSIZE, sizeof(SEGMENT))) == NULL)
- return (-1);
- hashp->exsegs++;
- hashp->nsegs++;
- }
- /*
- * If the split point is increasing (MAX_BUCKET's log base 2
- * * increases), we need to copy the current contents of the spare
- * split bucket to the next bucket.
- */
- spare_ndx = __log2((uint32)(hashp->MAX_BUCKET + 1));
- if (spare_ndx > hashp->OVFL_POINT) {
- hashp->SPARES[spare_ndx] = hashp->SPARES[hashp->OVFL_POINT];
- hashp->OVFL_POINT = spare_ndx;
- }
-
- if (new_bucket > (uint32)hashp->HIGH_MASK) {
- /* Starting a new doubling */
- hashp->LOW_MASK = hashp->HIGH_MASK;
- hashp->HIGH_MASK = new_bucket | hashp->LOW_MASK;
- }
- /* Relocate records to the new bucket */
- return (__split_page(hashp, old_bucket, new_bucket));
+ new_bucket = ++hashp->MAX_BUCKET;
+ old_bucket = (hashp->MAX_BUCKET & hashp->LOW_MASK);
+
+ new_segnum = new_bucket >> hashp->SSHIFT;
+
+ /* Check if we need a new segment */
+ if (new_segnum >= hashp->nsegs) {
+ /* Check if we need to expand directory */
+ if (new_segnum >= hashp->DSIZE) {
+ /* Reallocate directory */
+ dirsize = hashp->DSIZE * sizeof(SEGMENT *);
+ if (!hash_realloc(&hashp->dir, dirsize, dirsize << 1))
+ return (-1);
+ hashp->DSIZE = dirsize << 1;
+ }
+ if ((hashp->dir[new_segnum] =
+ (SEGMENT)calloc((size_t)hashp->SGSIZE, sizeof(BUFHEAD *))) == NULL)
+ return (-1);
+ hashp->exsegs++;
+ hashp->nsegs++;
+ }
+ /*
+ * If the split point is increasing (MAX_BUCKET's log base 2
+ * * increases), we need to copy the current contents of the spare
+ * split bucket to the next bucket.
+ */
+ spare_ndx = __log2((uint32)(hashp->MAX_BUCKET + 1));
+ if (spare_ndx > hashp->OVFL_POINT) {
+ hashp->SPARES[spare_ndx] = hashp->SPARES[hashp->OVFL_POINT];
+ hashp->OVFL_POINT = spare_ndx;
+ }
+
+ if (new_bucket > (uint32)hashp->HIGH_MASK) {
+ /* Starting a new doubling */
+ hashp->LOW_MASK = hashp->HIGH_MASK;
+ hashp->HIGH_MASK = new_bucket | hashp->LOW_MASK;
+ }
+ /* Relocate records to the new bucket */
+ return (__split_page(hashp, old_bucket, new_bucket));
}
/*
@@ -1054,30 +1051,30 @@ __expand_table(HTAB *hashp)
*/
static void *
hash_realloc(
- SEGMENT **p_ptr,
- size_t oldsize, size_t newsize)
+ SEGMENT **p_ptr,
+ size_t oldsize, size_t newsize)
{
- register void *p;
-
- if ((p = malloc(newsize))) {
- memmove(p, *p_ptr, oldsize);
- memset((char *)p + oldsize, 0, newsize - oldsize);
- free(*p_ptr);
- *p_ptr = (SEGMENT *)p;
- }
- return (p);
+ register void *p;
+
+ if ((p = malloc(newsize))) {
+ memmove(p, *p_ptr, oldsize);
+ memset((char *)p + oldsize, 0, newsize - oldsize);
+ free(*p_ptr);
+ *p_ptr = (SEGMENT *)p;
+ }
+ return (p);
}
extern uint32
__call_hash(HTAB *hashp, char *k, size_t len)
{
- uint32 n, bucket;
+ uint32 n, bucket;
- n = hashp->hash(k, len);
- bucket = n & hashp->HIGH_MASK;
- if (bucket > (uint32)hashp->MAX_BUCKET)
- bucket = bucket & hashp->LOW_MASK;
- return (bucket);
+ n = hashp->hash(k, len);
+ bucket = n & hashp->HIGH_MASK;
+ if (bucket > (uint32)hashp->MAX_BUCKET)
+ bucket = bucket & hashp->LOW_MASK;
+ return (bucket);
}
/*
@@ -1087,26 +1084,26 @@ __call_hash(HTAB *hashp, char *k, size_t len)
*/
static int
alloc_segs(
- HTAB *hashp,
- int nsegs)
+ HTAB *hashp,
+ int nsegs)
{
- register int i;
- register SEGMENT store;
-
- if ((hashp->dir =
- (SEGMENT *)calloc((size_t)hashp->DSIZE, sizeof(SEGMENT *))) == NULL) {
- errno = ENOMEM;
- return (-1);
- }
- /* Allocate segments */
- if ((store =
- (SEGMENT)calloc((size_t)nsegs << hashp->SSHIFT, sizeof(SEGMENT))) == NULL) {
- errno = ENOMEM;
- return (-1);
- }
- for (i = 0; i < nsegs; i++, hashp->nsegs++)
- hashp->dir[i] = &store[i << hashp->SSHIFT];
- return (0);
+ register int i;
+ register SEGMENT store;
+
+ if ((hashp->dir =
+ (SEGMENT *)calloc((size_t)hashp->DSIZE, sizeof(SEGMENT))) == NULL) {
+ errno = ENOMEM;
+ return (-1);
+ }
+ /* Allocate segments */
+ if ((store =
+ (SEGMENT)calloc((size_t)nsegs << hashp->SSHIFT, sizeof(BUFHEAD *))) == NULL) {
+ errno = ENOMEM;
+ return (-1);
+ }
+ for (i = 0; i < nsegs; i++, hashp->nsegs++)
+ hashp->dir[i] = &store[i << hashp->SSHIFT];
+ return (0);
}
#if BYTE_ORDER == LITTLE_ENDIAN
@@ -1115,61 +1112,61 @@ alloc_segs(
*/
static void
swap_header_copy(
- HASHHDR *srcp, HASHHDR *destp)
+ HASHHDR *srcp, HASHHDR *destp)
{
- int i;
-
- P_32_COPY(srcp->magic, destp->magic);
- P_32_COPY(srcp->version, destp->version);
- P_32_COPY(srcp->lorder, destp->lorder);
- P_32_COPY(srcp->bsize, destp->bsize);
- P_32_COPY(srcp->bshift, destp->bshift);
- P_32_COPY(srcp->dsize, destp->dsize);
- P_32_COPY(srcp->ssize, destp->ssize);
- P_32_COPY(srcp->sshift, destp->sshift);
- P_32_COPY(srcp->ovfl_point, destp->ovfl_point);
- P_32_COPY(srcp->last_freed, destp->last_freed);
- P_32_COPY(srcp->max_bucket, destp->max_bucket);
- P_32_COPY(srcp->high_mask, destp->high_mask);
- P_32_COPY(srcp->low_mask, destp->low_mask);
- P_32_COPY(srcp->ffactor, destp->ffactor);
- P_32_COPY(srcp->nkeys, destp->nkeys);
- P_32_COPY(srcp->hdrpages, destp->hdrpages);
- P_32_COPY(srcp->h_charkey, destp->h_charkey);
- for (i = 0; i < NCACHED; i++) {
- P_32_COPY(srcp->spares[i], destp->spares[i]);
- P_16_COPY(srcp->bitmaps[i], destp->bitmaps[i]);
- }
+ int i;
+
+ P_32_COPY(srcp->magic, destp->magic);
+ P_32_COPY(srcp->version, destp->version);
+ P_32_COPY(srcp->lorder, destp->lorder);
+ P_32_COPY(srcp->bsize, destp->bsize);
+ P_32_COPY(srcp->bshift, destp->bshift);
+ P_32_COPY(srcp->dsize, destp->dsize);
+ P_32_COPY(srcp->ssize, destp->ssize);
+ P_32_COPY(srcp->sshift, destp->sshift);
+ P_32_COPY(srcp->ovfl_point, destp->ovfl_point);
+ P_32_COPY(srcp->last_freed, destp->last_freed);
+ P_32_COPY(srcp->max_bucket, destp->max_bucket);
+ P_32_COPY(srcp->high_mask, destp->high_mask);
+ P_32_COPY(srcp->low_mask, destp->low_mask);
+ P_32_COPY(srcp->ffactor, destp->ffactor);
+ P_32_COPY(srcp->nkeys, destp->nkeys);
+ P_32_COPY(srcp->hdrpages, destp->hdrpages);
+ P_32_COPY(srcp->h_charkey, destp->h_charkey);
+ for (i = 0; i < NCACHED; i++) {
+ P_32_COPY(srcp->spares[i], destp->spares[i]);
+ P_16_COPY(srcp->bitmaps[i], destp->bitmaps[i]);
+ }
}
static void
swap_header(HTAB *hashp)
{
- HASHHDR *hdrp;
- int i;
-
- hdrp = &hashp->hdr;
-
- M_32_SWAP(hdrp->magic);
- M_32_SWAP(hdrp->version);
- M_32_SWAP(hdrp->lorder);
- M_32_SWAP(hdrp->bsize);
- M_32_SWAP(hdrp->bshift);
- M_32_SWAP(hdrp->dsize);
- M_32_SWAP(hdrp->ssize);
- M_32_SWAP(hdrp->sshift);
- M_32_SWAP(hdrp->ovfl_point);
- M_32_SWAP(hdrp->last_freed);
- M_32_SWAP(hdrp->max_bucket);
- M_32_SWAP(hdrp->high_mask);
- M_32_SWAP(hdrp->low_mask);
- M_32_SWAP(hdrp->ffactor);
- M_32_SWAP(hdrp->nkeys);
- M_32_SWAP(hdrp->hdrpages);
- M_32_SWAP(hdrp->h_charkey);
- for (i = 0; i < NCACHED; i++) {
- M_32_SWAP(hdrp->spares[i]);
- M_16_SWAP(hdrp->bitmaps[i]);
- }
+ HASHHDR *hdrp;
+ int i;
+
+ hdrp = &hashp->hdr;
+
+ M_32_SWAP(hdrp->magic);
+ M_32_SWAP(hdrp->version);
+ M_32_SWAP(hdrp->lorder);
+ M_32_SWAP(hdrp->bsize);
+ M_32_SWAP(hdrp->bshift);
+ M_32_SWAP(hdrp->dsize);
+ M_32_SWAP(hdrp->ssize);
+ M_32_SWAP(hdrp->sshift);
+ M_32_SWAP(hdrp->ovfl_point);
+ M_32_SWAP(hdrp->last_freed);
+ M_32_SWAP(hdrp->max_bucket);
+ M_32_SWAP(hdrp->high_mask);
+ M_32_SWAP(hdrp->low_mask);
+ M_32_SWAP(hdrp->ffactor);
+ M_32_SWAP(hdrp->nkeys);
+ M_32_SWAP(hdrp->hdrpages);
+ M_32_SWAP(hdrp->h_charkey);
+ for (i = 0; i < NCACHED; i++) {
+ M_32_SWAP(hdrp->spares[i]);
+ M_16_SWAP(hdrp->bitmaps[i]);
+ }
}
#endif
diff --git a/nss/lib/dbm/src/hash_buf.c b/nss/lib/dbm/src/hash_buf.c
index d328694..a7cd2d0 100644
--- a/nss/lib/dbm/src/hash_buf.c
+++ b/nss/lib/dbm/src/hash_buf.c
@@ -1,6 +1,6 @@
/*-
* Copyright (c) 1990, 1993, 1994
- * The Regents of the University of California. All rights reserved.
+ * The Regents of the University of California. All rights reserved.
*
* This code is derived from software contributed to Berkeley by
* Margo Seltzer.
@@ -13,7 +13,7 @@
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
- * 3. ***REMOVED*** - see
+ * 3. ***REMOVED*** - see
* ftp://ftp.cs.berkeley.edu/pub/4bsd/README.Impt.License.Change
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
@@ -33,23 +33,23 @@
*/
#if defined(LIBC_SCCS) && !defined(lint)
-static char sccsid[] = "@(#)hash_buf.c 8.5 (Berkeley) 7/15/94";
+static char sccsid[] = "@(#)hash_buf.c 8.5 (Berkeley) 7/15/94";
#endif /* LIBC_SCCS and not lint */
/*
* PACKAGE: hash
*
* DESCRIPTION:
- * Contains buffer management
+ * Contains buffer management
*
* ROUTINES:
* External
- * __buf_init
- * __get_buf
- * __buf_free
- * __reclaim_buf
+ * __buf_init
+ * __get_buf
+ * __buf_free
+ * __reclaim_buf
* Internal
- * newbuf
+ * newbuf
*/
#if !defined(_WIN32) && !defined(_WINDOWS) && !defined(macintosh)
#include <sys/param.h>
@@ -73,24 +73,26 @@ static char sccsid[] = "@(#)hash_buf.c 8.5 (Berkeley) 7/15/94";
static BUFHEAD *newbuf(HTAB *, uint32, BUFHEAD *);
/* Unlink B from its place in the lru */
-#define BUF_REMOVE(B) { \
- (B)->prev->next = (B)->next; \
- (B)->next->prev = (B)->prev; \
-}
+#define BUF_REMOVE(B) \
+ { \
+ (B)->prev->next = (B)->next; \
+ (B)->next->prev = (B)->prev; \
+ }
/* Insert B after P */
-#define BUF_INSERT(B, P) { \
- (B)->next = (P)->next; \
- (B)->prev = (P); \
- (P)->next = (B); \
- (B)->next->prev = (B); \
-}
+#define BUF_INSERT(B, P) \
+ { \
+ (B)->next = (P)->next; \
+ (B)->prev = (P); \
+ (P)->next = (B); \
+ (B)->next->prev = (B); \
+ }
-#define MRU hashp->bufhead.next
-#define LRU hashp->bufhead.prev
+#define MRU hashp->bufhead.next
+#define LRU hashp->bufhead.prev
-#define MRU_INSERT(B) BUF_INSERT((B), &hashp->bufhead)
-#define LRU_INSERT(B) BUF_INSERT((B), LRU)
+#define MRU_INSERT(B) BUF_INSERT((B), &hashp->bufhead)
+#define LRU_INSERT(B) BUF_INSERT((B), LRU)
/*
* We are looking for a buffer with address "addr". If prev_bp is NULL, then
@@ -105,79 +107,76 @@ extern BUFHEAD *
__get_buf(HTAB *hashp, uint32 addr, BUFHEAD *prev_bp, int newpage)
/* If prev_bp set, indicates a new overflow page. */
{
- register BUFHEAD *bp;
- register uint32 is_disk_mask;
- register int is_disk, segment_ndx = 0;
- SEGMENT segp = 0;
-
- is_disk = 0;
- is_disk_mask = 0;
- if (prev_bp) {
- bp = prev_bp->ovfl;
- if (!bp || (bp->addr != addr))
- bp = NULL;
- if (!newpage)
- is_disk = BUF_DISK;
- } else {
- /* Grab buffer out of directory */
- segment_ndx = addr & (hashp->SGSIZE - 1);
-
- /* valid segment ensured by __call_hash() */
- segp = hashp->dir[addr >> hashp->SSHIFT];
+ register BUFHEAD *bp;
+ register uint32 is_disk_mask;
+ register int is_disk, segment_ndx = 0;
+ SEGMENT segp = 0;
+
+ is_disk = 0;
+ is_disk_mask = 0;
+ if (prev_bp) {
+ bp = prev_bp->ovfl;
+ if (!bp || (bp->addr != addr))
+ bp = NULL;
+ if (!newpage)
+ is_disk = BUF_DISK;
+ } else {
+ /* Grab buffer out of directory */
+ segment_ndx = addr & (hashp->SGSIZE - 1);
+
+ /* valid segment ensured by __call_hash() */
+ segp = hashp->dir[addr >> hashp->SSHIFT];
#ifdef DEBUG
- assert(segp != NULL);
-#endif
-
- bp = PTROF(segp[segment_ndx]);
-
- is_disk_mask = ISDISK(segp[segment_ndx]);
- is_disk = is_disk_mask || !hashp->new_file;
- }
-
- if (!bp) {
- bp = newbuf(hashp, addr, prev_bp);
- if (!bp)
- return(NULL);
- if(__get_page(hashp, bp->page, addr, !prev_bp, is_disk, 0))
- {
- /* free bp and its page */
- if(prev_bp)
- {
- /* if prev_bp is set then the new page that
- * failed is hooked onto prev_bp as an overflow page.
- * if we don't remove the pointer to the bad page
- * we may try and access it later and we will die
- * horribly because it will have already been
- * free'd and overwritten with bogus data.
- */
- prev_bp->ovfl = NULL;
- }
- BUF_REMOVE(bp);
- free(bp->page);
- free(bp);
- return (NULL);
- }
-
- if (!prev_bp)
- {
+ assert(segp != NULL);
+#endif
+
+ bp = PTROF(segp[segment_ndx]);
+
+ is_disk_mask = ISDISK(segp[segment_ndx]);
+ is_disk = is_disk_mask || !hashp->new_file;
+ }
+
+ if (!bp) {
+ bp = newbuf(hashp, addr, prev_bp);
+ if (!bp)
+ return (NULL);
+ if (__get_page(hashp, bp->page, addr, !prev_bp, is_disk, 0)) {
+ /* free bp and its page */
+ if (prev_bp) {
+ /* if prev_bp is set then the new page that
+ * failed is hooked onto prev_bp as an overflow page.
+ * if we don't remove the pointer to the bad page
+ * we may try and access it later and we will die
+ * horribly because it will have already been
+ * free'd and overwritten with bogus data.
+ */
+ prev_bp->ovfl = NULL;
+ }
+ BUF_REMOVE(bp);
+ free(bp->page);
+ free(bp);
+ return (NULL);
+ }
+
+ if (!prev_bp) {
#if 0
- /* 16 bit windows and mac can't handle the
- * oring of the is disk flag.
- */
- segp[segment_ndx] =
- (BUFHEAD *)((ptrdiff_t)bp | is_disk_mask);
-#else
- /* set the is_disk thing inside the structure
- */
- bp->is_disk = is_disk_mask;
- segp[segment_ndx] = bp;
+ /* 16 bit windows and mac can't handle the
+ * oring of the is disk flag.
+ */
+ segp[segment_ndx] =
+ (BUFHEAD *)((ptrdiff_t)bp | is_disk_mask);
+#else
+ /* set the is_disk thing inside the structure
+ */
+ bp->is_disk = is_disk_mask;
+ segp[segment_ndx] = bp;
#endif
- }
- } else {
- BUF_REMOVE(bp);
- MRU_INSERT(bp);
- }
- return (bp);
+ }
+ } else {
+ BUF_REMOVE(bp);
+ MRU_INSERT(bp);
+ }
+ return (bp);
}
/*
@@ -189,222 +188,220 @@ __get_buf(HTAB *hashp, uint32 addr, BUFHEAD *prev_bp, int newpage)
static BUFHEAD *
newbuf(HTAB *hashp, uint32 addr, BUFHEAD *prev_bp)
{
- register BUFHEAD *bp; /* The buffer we're going to use */
- register BUFHEAD *xbp; /* Temp pointer */
- register BUFHEAD *next_xbp;
- SEGMENT segp;
- int segment_ndx;
- uint16 oaddr, *shortp;
-
- oaddr = 0;
- bp = LRU;
- /*
- * If LRU buffer is pinned, the buffer pool is too small. We need to
- * allocate more buffers.
- */
- if (hashp->nbufs || (bp->flags & BUF_PIN)) {
- /* Allocate a new one */
- if ((bp = (BUFHEAD *)malloc(sizeof(BUFHEAD))) == NULL)
- return (NULL);
-
- /* this memset is supposedly unnecessary but lets add
- * it anyways.
- */
- memset(bp, 0xff, sizeof(BUFHEAD));
-
- if ((bp->page = (char *)malloc((size_t)hashp->BSIZE)) == NULL) {
- free(bp);
- return (NULL);
- }
-
- /* this memset is supposedly unnecessary but lets add
- * it anyways.
- */
- memset(bp->page, 0xff, (size_t)hashp->BSIZE);
-
- if (hashp->nbufs)
- hashp->nbufs--;
- } else {
- /* Kick someone out */
- BUF_REMOVE(bp);
- /*
- * If this is an overflow page with addr 0, it's already been
- * flushed back in an overflow chain and initialized.
- */
- if ((bp->addr != 0) || (bp->flags & BUF_BUCKET)) {
- /*
- * Set oaddr before __put_page so that you get it
- * before bytes are swapped.
- */
- shortp = (uint16 *)bp->page;
- if (shortp[0])
- {
- if(shortp[0] > (hashp->BSIZE / sizeof(uint16)))
- {
- return(NULL);
- }
- oaddr = shortp[shortp[0] - 1];
- }
- if ((bp->flags & BUF_MOD) && __put_page(hashp, bp->page,
- bp->addr, (int)IS_BUCKET(bp->flags), 0))
- return (NULL);
- /*
- * Update the pointer to this page (i.e. invalidate it).
- *
- * If this is a new file (i.e. we created it at open
- * time), make sure that we mark pages which have been
- * written to disk so we retrieve them from disk later,
- * rather than allocating new pages.
- */
- if (IS_BUCKET(bp->flags)) {
- segment_ndx = bp->addr & (hashp->SGSIZE - 1);
- segp = hashp->dir[bp->addr >> hashp->SSHIFT];
+ register BUFHEAD *bp; /* The buffer we're going to use */
+ register BUFHEAD *xbp; /* Temp pointer */
+ register BUFHEAD *next_xbp;
+ SEGMENT segp;
+ int segment_ndx;
+ uint16 oaddr, *shortp;
+
+ oaddr = 0;
+ bp = LRU;
+ /*
+ * If LRU buffer is pinned, the buffer pool is too small. We need to
+ * allocate more buffers.
+ */
+ if (hashp->nbufs || (bp->flags & BUF_PIN)) {
+ /* Allocate a new one */
+ if ((bp = (BUFHEAD *)malloc(sizeof(BUFHEAD))) == NULL)
+ return (NULL);
+
+ /* this memset is supposedly unnecessary but lets add
+ * it anyways.
+ */
+ memset(bp, 0xff, sizeof(BUFHEAD));
+
+ if ((bp->page = (char *)malloc((size_t)hashp->BSIZE)) == NULL) {
+ free(bp);
+ return (NULL);
+ }
+
+ /* this memset is supposedly unnecessary but lets add
+ * it anyways.
+ */
+ memset(bp->page, 0xff, (size_t)hashp->BSIZE);
+
+ if (hashp->nbufs)
+ hashp->nbufs--;
+ } else {
+ /* Kick someone out */
+ BUF_REMOVE(bp);
+ /*
+ * If this is an overflow page with addr 0, it's already been
+ * flushed back in an overflow chain and initialized.
+ */
+ if ((bp->addr != 0) || (bp->flags & BUF_BUCKET)) {
+ /*
+ * Set oaddr before __put_page so that you get it
+ * before bytes are swapped.
+ */
+ shortp = (uint16 *)bp->page;
+ if (shortp[0]) {
+ if (shortp[0] > (hashp->BSIZE / sizeof(uint16))) {
+ return (NULL);
+ }
+ oaddr = shortp[shortp[0] - 1];
+ }
+ if ((bp->flags & BUF_MOD) && __put_page(hashp, bp->page,
+ bp->addr, (int)IS_BUCKET(bp->flags), 0))
+ return (NULL);
+ /*
+ * Update the pointer to this page (i.e. invalidate it).
+ *
+ * If this is a new file (i.e. we created it at open
+ * time), make sure that we mark pages which have been
+ * written to disk so we retrieve them from disk later,
+ * rather than allocating new pages.
+ */
+ if (IS_BUCKET(bp->flags)) {
+ segment_ndx = bp->addr & (hashp->SGSIZE - 1);
+ segp = hashp->dir[bp->addr >> hashp->SSHIFT];
#ifdef DEBUG
- assert(segp != NULL);
+ assert(segp != NULL);
#endif
- if (hashp->new_file &&
- ((bp->flags & BUF_MOD) ||
- ISDISK(segp[segment_ndx])))
- segp[segment_ndx] = (BUFHEAD *)BUF_DISK;
- else
- segp[segment_ndx] = NULL;
- }
- /*
- * Since overflow pages can only be access by means of
- * their bucket, free overflow pages associated with
- * this bucket.
- */
- for (xbp = bp; xbp->ovfl;) {
- next_xbp = xbp->ovfl;
- xbp->ovfl = 0;
- xbp = next_xbp;
-
- /* leave pinned pages alone, we are still using
- * them. */
- if (xbp->flags & BUF_PIN) {
- continue;
- }
-
- /* Check that ovfl pointer is up date. */
- if (IS_BUCKET(xbp->flags) ||
- (oaddr != xbp->addr))
- break;
-
- shortp = (uint16 *)xbp->page;
- if (shortp[0])
- {
- /* LJM is the number of reported
- * pages way too much?
- */
- if(shortp[0] > hashp->BSIZE/sizeof(uint16))
- return NULL;
- /* set before __put_page */
- oaddr = shortp[shortp[0] - 1];
- }
- if ((xbp->flags & BUF_MOD) && __put_page(hashp,
- xbp->page, xbp->addr, 0, 0))
- return (NULL);
- xbp->addr = 0;
- xbp->flags = 0;
- BUF_REMOVE(xbp);
- LRU_INSERT(xbp);
- }
- }
- }
-
- /* Now assign this buffer */
- bp->addr = addr;
+ if (hashp->new_file &&
+ ((bp->flags & BUF_MOD) ||
+ ISDISK(segp[segment_ndx])))
+ segp[segment_ndx] = (BUFHEAD *)BUF_DISK;
+ else
+ segp[segment_ndx] = NULL;
+ }
+ /*
+ * Since overflow pages can only be access by means of
+ * their bucket, free overflow pages associated with
+ * this bucket.
+ */
+ for (xbp = bp; xbp->ovfl;) {
+ next_xbp = xbp->ovfl;
+ xbp->ovfl = 0;
+ xbp = next_xbp;
+
+ /* leave pinned pages alone, we are still using
+ * them. */
+ if (xbp->flags & BUF_PIN) {
+ continue;
+ }
+
+ /* Check that ovfl pointer is up date. */
+ if (IS_BUCKET(xbp->flags) ||
+ (oaddr != xbp->addr))
+ break;
+
+ shortp = (uint16 *)xbp->page;
+ if (shortp[0]) {
+ /* LJM is the number of reported
+ * pages way too much?
+ */
+ if (shortp[0] > hashp->BSIZE / sizeof(uint16))
+ return NULL;
+ /* set before __put_page */
+ oaddr = shortp[shortp[0] - 1];
+ }
+ if ((xbp->flags & BUF_MOD) && __put_page(hashp,
+ xbp->page, xbp->addr, 0, 0))
+ return (NULL);
+ xbp->addr = 0;
+ xbp->flags = 0;
+ BUF_REMOVE(xbp);
+ LRU_INSERT(xbp);
+ }
+ }
+ }
+
+ /* Now assign this buffer */
+ bp->addr = addr;
#ifdef DEBUG1
- (void)fprintf(stderr, "NEWBUF1: %d->ovfl was %d is now %d\n",
- bp->addr, (bp->ovfl ? bp->ovfl->addr : 0), 0);
+ (void)fprintf(stderr, "NEWBUF1: %d->ovfl was %d is now %d\n",
+ bp->addr, (bp->ovfl ? bp->ovfl->addr : 0), 0);
#endif
- bp->ovfl = NULL;
- if (prev_bp) {
- /*
- * If prev_bp is set, this is an overflow page, hook it in to
- * the buffer overflow links.
- */
+ bp->ovfl = NULL;
+ if (prev_bp) {
+/*
+ * If prev_bp is set, this is an overflow page, hook it in to
+ * the buffer overflow links.
+ */
#ifdef DEBUG1
- (void)fprintf(stderr, "NEWBUF2: %d->ovfl was %d is now %d\n",
- prev_bp->addr, (prev_bp->ovfl ? bp->ovfl->addr : 0),
- (bp ? bp->addr : 0));
+ (void)fprintf(stderr, "NEWBUF2: %d->ovfl was %d is now %d\n",
+ prev_bp->addr, (prev_bp->ovfl ? bp->ovfl->addr : 0),
+ (bp ? bp->addr : 0));
#endif
- prev_bp->ovfl = bp;
- bp->flags = 0;
- } else
- bp->flags = BUF_BUCKET;
- MRU_INSERT(bp);
- return (bp);
+ prev_bp->ovfl = bp;
+ bp->flags = 0;
+ } else
+ bp->flags = BUF_BUCKET;
+ MRU_INSERT(bp);
+ return (bp);
}
-extern void __buf_init(HTAB *hashp, int32 nbytes)
+extern void
+__buf_init(HTAB *hashp, int32 nbytes)
{
- BUFHEAD *bfp;
- int npages;
-
- bfp = &(hashp->bufhead);
- npages = (nbytes + hashp->BSIZE - 1) >> hashp->BSHIFT;
- npages = PR_MAX(npages, MIN_BUFFERS);
-
- hashp->nbufs = npages;
- bfp->next = bfp;
- bfp->prev = bfp;
- /*
- * This space is calloc'd so these are already null.
- *
- * bfp->ovfl = NULL;
- * bfp->flags = 0;
- * bfp->page = NULL;
- * bfp->addr = 0;
- */
+ BUFHEAD *bfp;
+ int npages;
+
+ bfp = &(hashp->bufhead);
+ npages = (nbytes + hashp->BSIZE - 1) >> hashp->BSHIFT;
+ npages = PR_MAX(npages, MIN_BUFFERS);
+
+ hashp->nbufs = npages;
+ bfp->next = bfp;
+ bfp->prev = bfp;
+ /*
+ * This space is calloc'd so these are already null.
+ *
+ * bfp->ovfl = NULL;
+ * bfp->flags = 0;
+ * bfp->page = NULL;
+ * bfp->addr = 0;
+ */
}
extern int
__buf_free(HTAB *hashp, int do_free, int to_disk)
{
- BUFHEAD *bp;
- int status = -1;
-
- /* Need to make sure that buffer manager has been initialized */
- if (!LRU)
- return (0);
- for (bp = LRU; bp != &hashp->bufhead;) {
- /* Check that the buffer is valid */
- if (bp->addr || IS_BUCKET(bp->flags)) {
- if (to_disk && (bp->flags & BUF_MOD) &&
- (status = __put_page(hashp, bp->page,
- bp->addr, IS_BUCKET(bp->flags), 0))) {
-
- if (do_free) {
- if (bp->page)
- free(bp->page);
- BUF_REMOVE(bp);
- free(bp);
- }
-
- return (status);
- }
- }
- /* Check if we are freeing stuff */
- if (do_free) {
- if (bp->page)
- free(bp->page);
- BUF_REMOVE(bp);
- free(bp);
- bp = LRU;
- } else
- bp = bp->prev;
- }
- return (0);
+ BUFHEAD *bp;
+ int status = -1;
+
+ /* Need to make sure that buffer manager has been initialized */
+ if (!LRU)
+ return (0);
+ for (bp = LRU; bp != &hashp->bufhead;) {
+ /* Check that the buffer is valid */
+ if (bp->addr || IS_BUCKET(bp->flags)) {
+ if (to_disk && (bp->flags & BUF_MOD) &&
+ (status = __put_page(hashp, bp->page,
+ bp->addr, IS_BUCKET(bp->flags), 0))) {
+
+ if (do_free) {
+ if (bp->page)
+ free(bp->page);
+ BUF_REMOVE(bp);
+ free(bp);
+ }
+
+ return (status);
+ }
+ }
+ /* Check if we are freeing stuff */
+ if (do_free) {
+ if (bp->page)
+ free(bp->page);
+ BUF_REMOVE(bp);
+ free(bp);
+ bp = LRU;
+ } else
+ bp = bp->prev;
+ }
+ return (0);
}
extern void
__reclaim_buf(HTAB *hashp, BUFHEAD *bp)
{
- bp->ovfl = 0;
- bp->addr = 0;
- bp->flags = 0;
- BUF_REMOVE(bp);
- LRU_INSERT(bp);
+ bp->ovfl = 0;
+ bp->addr = 0;
+ bp->flags = 0;
+ BUF_REMOVE(bp);
+ LRU_INSERT(bp);
}
diff --git a/nss/lib/dbm/src/memmove.c b/nss/lib/dbm/src/memmove.c
index aacf946..135185b 100644
--- a/nss/lib/dbm/src/memmove.c
+++ b/nss/lib/dbm/src/memmove.c
@@ -1,7 +1,7 @@
#if defined(__sun) && !defined(__SVR4)
/*-
* Copyright (c) 1990, 1993
- * The Regents of the University of California. All rights reserved.
+ * The Regents of the University of California. All rights reserved.
*
* This code is derived from software contributed to Berkeley by
* Chris Torek.
@@ -14,7 +14,7 @@
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
- * 3. ***REMOVED*** - see
+ * 3. ***REMOVED*** - see
* ftp://ftp.cs.berkeley.edu/pub/4bsd/README.Impt.License.Change
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
@@ -34,7 +34,7 @@
*/
#if defined(LIBC_SCCS) && !defined(lint)
-static char sccsid[] = "@(#)bcopy.c 8.1 (Berkeley) 6/4/93";
+static char sccsid[] = "@(#)bcopy.c 8.1 (Berkeley) 6/4/93";
#endif /* LIBC_SCCS and not lint */
#include <string.h>
@@ -43,10 +43,10 @@ static char sccsid[] = "@(#)bcopy.c 8.1 (Berkeley) 6/4/93";
* sizeof(word) MUST BE A POWER OF TWO
* SO THAT wmask BELOW IS ALL ONES
*/
-typedef int word; /* "word" used for optimal copy speed */
+typedef int word; /* "word" used for optimal copy speed */
-#define wsize sizeof(word)
-#define wmask (wsize - 1)
+#define wsize sizeof(word)
+#define wmask (wsize - 1)
/*
* Copy a block of memory, handling overlap.
@@ -55,84 +55,89 @@ typedef int word; /* "word" used for optimal copy speed */
*/
#ifdef MEMCOPY
void *
-memcpy(dst0, src0, length)
+ memcpy(dst0, src0, length)
#else
#ifdef MEMMOVE
void *
-memmove(dst0, src0, length)
+ memmove(dst0, src0, length)
#else
void
-bcopy(src0, dst0, length)
+ bcopy(src0, dst0, length)
#endif
#endif
- void *dst0;
- const void *src0;
- register size_t length;
+ void *dst0;
+const void *src0;
+register size_t length;
{
- register char *dst = dst0;
- register const char *src = src0;
- register size_t t;
+ register char *dst = dst0;
+ register const char *src = src0;
+ register size_t t;
- if (length == 0 || dst == src) /* nothing to do */
- goto done;
+ if (length == 0 || dst == src) /* nothing to do */
+ goto done;
- /*
- * Macros: loop-t-times; and loop-t-times, t>0
- */
-#define TLOOP(s) if (t) TLOOP1(s)
-#define TLOOP1(s) do { s; } while (--t)
+/*
+ * Macros: loop-t-times; and loop-t-times, t>0
+ */
+#define TLOOP(s) \
+ if (t) \
+ TLOOP1(s)
+#define TLOOP1(s) \
+ do { \
+ s; \
+ } while (--t)
- if ((unsigned long)dst < (unsigned long)src) {
- /*
- * Copy forward.
- */
- t = (int)src; /* only need low bits */
- if ((t | (int)dst) & wmask) {
- /*
- * Try to align operands. This cannot be done
- * unless the low bits match.
- */
- if ((t ^ (int)dst) & wmask || length < wsize)
- t = length;
- else
- t = wsize - (t & wmask);
- length -= t;
- TLOOP1(*dst++ = *src++);
- }
- /*
- * Copy whole words, then mop up any trailing bytes.
- */
- t = length / wsize;
- TLOOP(*(word *)dst = *(word *)src; src += wsize; dst += wsize);
- t = length & wmask;
- TLOOP(*dst++ = *src++);
- } else {
- /*
- * Copy backwards. Otherwise essentially the same.
- * Alignment works as before, except that it takes
- * (t&wmask) bytes to align, not wsize-(t&wmask).
- */
- src += length;
- dst += length;
- t = (int)src;
- if ((t | (int)dst) & wmask) {
- if ((t ^ (int)dst) & wmask || length <= wsize)
- t = length;
- else
- t &= wmask;
- length -= t;
- TLOOP1(*--dst = *--src);
- }
- t = length / wsize;
- TLOOP(src -= wsize; dst -= wsize; *(word *)dst = *(word *)src);
- t = length & wmask;
- TLOOP(*--dst = *--src);
- }
+ if ((unsigned long)dst < (unsigned long)src) {
+ /*
+ * Copy forward.
+ */
+ t = (int)src; /* only need low bits */
+ if ((t | (int)dst) & wmask) {
+ /*
+ * Try to align operands. This cannot be done
+ * unless the low bits match.
+ */
+ if ((t ^ (int)dst) & wmask || length < wsize)
+ t = length;
+ else
+ t = wsize - (t & wmask);
+ length -= t;
+ TLOOP1(*dst++ = *src++);
+ }
+ /*
+ * Copy whole words, then mop up any trailing bytes.
+ */
+ t = length / wsize;
+ TLOOP(*(word *)dst = *(word *)src; src += wsize; dst += wsize);
+ t = length & wmask;
+ TLOOP(*dst++ = *src++);
+ } else {
+ /*
+ * Copy backwards. Otherwise essentially the same.
+ * Alignment works as before, except that it takes
+ * (t&wmask) bytes to align, not wsize-(t&wmask).
+ */
+ src += length;
+ dst += length;
+ t = (int)src;
+ if ((t | (int)dst) & wmask) {
+ if ((t ^ (int)dst) & wmask || length <= wsize)
+ t = length;
+ else
+ t &= wmask;
+ length -= t;
+ TLOOP1(*--dst = *--src);
+ }
+ t = length / wsize;
+ TLOOP(src -= wsize; dst -= wsize; *(word *)dst = *(word *)src);
+ t = length & wmask;
+ TLOOP(*--dst = *--src);
+ }
done:
#if defined(MEMCOPY) || defined(MEMMOVE)
- return (dst0);
+ return (dst0);
#else
- return;
+ return;
#endif
}
#endif /* no __sgi */
diff --git a/nss/lib/dbm/src/mktemp.c b/nss/lib/dbm/src/mktemp.c
index bbf05cd..b668ece 100644
--- a/nss/lib/dbm/src/mktemp.c
+++ b/nss/lib/dbm/src/mktemp.c
@@ -1,6 +1,6 @@
/*
* Copyright (c) 1987, 1993
- * The Regents of the University of California. All rights reserved.
+ * The Regents of the University of California. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -10,7 +10,7 @@
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
- * 3. ***REMOVED*** - see
+ * 3. ***REMOVED*** - see
* ftp://ftp.cs.berkeley.edu/pub/4bsd/README.Impt.License.Change
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
@@ -30,7 +30,7 @@
*/
#if defined(LIBC_SCCS) && !defined(lint)
-static char sccsid[] = "@(#)mktemp.c 8.1 (Berkeley) 6/4/93";
+static char sccsid[] = "@(#)mktemp.c 8.1 (Berkeley) 6/4/93";
#endif /* LIBC_SCCS and not lint */
#ifdef macintosh
@@ -60,90 +60,90 @@ int
mkstemp(char *path)
{
#ifdef XP_OS2
- FILE *temp = tmpfile();
+ FILE *temp = tmpfile();
- return (temp ? fileno(temp) : -1);
+ return (temp ? fileno(temp) : -1);
#else
- int fd;
+ int fd;
- return (_gettemp(path, &fd, 0) ? fd : -1);
+ return (_gettemp(path, &fd, 0) ? fd : -1);
#endif
}
int
mkstempflags(char *path, int extraFlags)
{
- int fd;
+ int fd;
- return (_gettemp(path, &fd, extraFlags) ? fd : -1);
+ return (_gettemp(path, &fd, extraFlags) ? fd : -1);
}
/* NB: This routine modifies its input string, and does not always restore it.
** returns 1 on success, 0 on failure.
*/
-static int
+static int
_gettemp(char *path, register int *doopen, int extraFlags)
-{
- register char *start, *trv;
- struct stat sbuf;
- unsigned int pid;
+{
+ register char *start, *trv;
+ struct stat sbuf;
+ unsigned int pid;
- pid = getpid();
- for (trv = path; *trv; ++trv); /* extra X's get set to 0's */
- while (*--trv == 'X') {
- *trv = (pid % 10) + '0';
- pid /= 10;
- }
+ pid = getpid();
+ for (trv = path; *trv; ++trv)
+ ; /* extra X's get set to 0's */
+ while (*--trv == 'X') {
+ *trv = (pid % 10) + '0';
+ pid /= 10;
+ }
- /*
- * check the target directory; if you have six X's and it
- * doesn't exist this runs for a *very* long time.
- */
- for (start = trv + 1;; --trv) {
- char saved;
- if (trv <= path)
- break;
- saved = *trv;
- if (saved == '/' || saved == '\\') {
- int rv;
- *trv = '\0';
- rv = stat(path, &sbuf);
- *trv = saved;
- if (rv)
- return(0);
- if (!S_ISDIR(sbuf.st_mode)) {
- errno = ENOTDIR;
- return(0);
- }
- break;
- }
- }
+ /*
+ * check the target directory; if you have six X's and it
+ * doesn't exist this runs for a *very* long time.
+ */
+ for (start = trv + 1;; --trv) {
+ char saved;
+ if (trv <= path)
+ break;
+ saved = *trv;
+ if (saved == '/' || saved == '\\') {
+ int rv;
+ *trv = '\0';
+ rv = stat(path, &sbuf);
+ *trv = saved;
+ if (rv)
+ return (0);
+ if (!S_ISDIR(sbuf.st_mode)) {
+ errno = ENOTDIR;
+ return (0);
+ }
+ break;
+ }
+ }
- for (;;) {
- if (doopen) {
- if ((*doopen =
- open(path, O_CREAT|O_EXCL|O_RDWR|extraFlags, 0600)) >= 0)
- return(1);
- if (errno != EEXIST)
- return(0);
- }
- else if (stat(path, &sbuf))
- return(errno == ENOENT ? 1 : 0);
+ for (;;) {
+ if (doopen) {
+ if ((*doopen =
+ open(path, O_CREAT | O_EXCL | O_RDWR | extraFlags, 0600)) >= 0)
+ return (1);
+ if (errno != EEXIST)
+ return (0);
+ } else if (stat(path, &sbuf))
+ return (errno == ENOENT ? 1 : 0);
- /* tricky little algorithm for backward compatibility */
- for (trv = start;;) {
- if (!*trv)
- return(0);
- if (*trv == 'z')
- *trv++ = 'a';
- else {
- if (isdigit(*trv))
- *trv = 'a';
- else
- ++*trv;
- break;
- }
- }
- }
- /*NOTREACHED*/
+ /* tricky little algorithm for backward compatibility */
+ for (trv = start;;) {
+ if (!*trv)
+ return (0);
+ if (*trv == 'z')
+ *trv++ = 'a';
+ else {
+ if (isdigit(*trv))
+ *trv = 'a';
+ else
+ ++*trv;
+ break;
+ }
+ }
+ }
+ /*NOTREACHED*/
}
diff --git a/nss/lib/dbm/src/snprintf.c b/nss/lib/dbm/src/snprintf.c
index 377a8d8..3cafacf 100644
--- a/nss/lib/dbm/src/snprintf.c
+++ b/nss/lib/dbm/src/snprintf.c
@@ -13,35 +13,34 @@
int
snprintf(char *str, size_t n, const char *fmt, ...)
{
- va_list ap;
+ va_list ap;
#ifdef VSPRINTF_CHARSTAR
- char *rp;
+ char *rp;
#else
- int rval;
+ int rval;
#endif
- va_start(ap, fmt);
+ va_start(ap, fmt);
#ifdef VSPRINTF_CHARSTAR
- rp = vsprintf(str, fmt, ap);
- va_end(ap);
- return (strlen(rp));
+ rp = vsprintf(str, fmt, ap);
+ va_end(ap);
+ return (strlen(rp));
#else
- rval = vsprintf(str, fmt, ap);
- va_end(ap);
- return (rval);
+ rval = vsprintf(str, fmt, ap);
+ va_end(ap);
+ return (rval);
#endif
}
int
-vsnprintf(str, n, fmt, ap)
- char *str;
- size_t n;
- const char *fmt;
- va_list ap;
+ vsnprintf(str, n, fmt, ap) char *str;
+size_t n;
+const char *fmt;
+va_list ap;
{
#ifdef VSPRINTF_CHARSTAR
- return (strlen(vsprintf(str, fmt, ap)));
+ return (strlen(vsprintf(str, fmt, ap)));
#else
- return (vsprintf(str, fmt, ap));
+ return (vsprintf(str, fmt, ap));
#endif
}
diff --git a/nss/lib/dbm/src/src.gyp b/nss/lib/dbm/src/src.gyp
new file mode 100644
index 0000000..a84755e
--- /dev/null
+++ b/nss/lib/dbm/src/src.gyp
@@ -0,0 +1,40 @@
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+{
+ 'includes': [
+ '../../../coreconf/config.gypi'
+ ],
+ 'targets': [
+ {
+ 'target_name': 'dbm',
+ 'type': 'static_library',
+ 'sources': [
+ 'db.c',
+ 'dirent.c',
+ 'h_bigkey.c',
+ 'h_func.c',
+ 'h_log2.c',
+ 'h_page.c',
+ 'hash.c',
+ 'hash_buf.c',
+ 'mktemp.c'
+ ],
+ 'dependencies': [
+ '<(DEPTH)/exports.gyp:dbm_exports'
+ ]
+ }
+ ],
+ 'target_defaults': {
+ 'defines': [
+ 'STDC_HEADERS',
+ 'HAVE_STRERROR',
+ 'HAVE_SNPRINTF',
+ 'MEMMOVE',
+ '__DBINTERFACE_PRIVATE'
+ ]
+ },
+ 'variables': {
+ 'module': 'dbm'
+ }
+} \ No newline at end of file
diff --git a/nss/lib/dbm/src/strerror.c b/nss/lib/dbm/src/strerror.c
index 83d16e7..d64918b 100644
--- a/nss/lib/dbm/src/strerror.c
+++ b/nss/lib/dbm/src/strerror.c
@@ -1,6 +1,6 @@
/*
* Copyright (c) 1988, 1993
- * The Regents of the University of California. All rights reserved.
+ * The Regents of the University of California. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -10,7 +10,7 @@
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
- * 3. ***REMOVED*** - see
+ * 3. ***REMOVED*** - see
* ftp://ftp.cs.berkeley.edu/pub/4bsd/README.Impt.License.Change
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
@@ -30,44 +30,43 @@
*/
#if defined(LIBC_SCCS) && !defined(lint)
-static char sccsid[] = "@(#)strerror.c 8.1 (Berkeley) 6/4/93";
+static char sccsid[] = "@(#)strerror.c 8.1 (Berkeley) 6/4/93";
#endif /* LIBC_SCCS and not lint */
#include <string.h>
#ifdef _DLL
-#define sys_nerr (*_sys_nerr_dll)
+#define sys_nerr (*_sys_nerr_dll)
#endif
#ifndef HAVE_STRERROR
#ifndef _AFXDLL
char *
-strerror(num)
- int num;
+ strerror(num) int num;
{
- extern int sys_nerr;
- extern char *sys_errlist[];
-#define UPREFIX "Unknown error: "
- static char ebuf[40] = UPREFIX; /* 64-bit number + slop */
- register unsigned int errnum;
- register char *p, *t;
- char tmp[40];
+ extern int sys_nerr;
+ extern char *sys_errlist[];
+#define UPREFIX "Unknown error: "
+ static char ebuf[40] = UPREFIX; /* 64-bit number + slop */
+ register unsigned int errnum;
+ register char *p, *t;
+ char tmp[40];
- errnum = num; /* convert to unsigned */
- if (errnum < sys_nerr)
- return(sys_errlist[errnum]);
+ errnum = num; /* convert to unsigned */
+ if (errnum < sys_nerr)
+ return (sys_errlist[errnum]);
- /* Do this by hand, so we don't include stdio(3). */
- t = tmp;
- do {
- *t++ = "0123456789"[errnum % 10];
- } while (errnum /= 10);
- for (p = ebuf + sizeof(UPREFIX) - 1;;) {
- *p++ = *--t;
- if (t <= tmp)
- break;
- }
- return(ebuf);
+ /* Do this by hand, so we don't include stdio(3). */
+ t = tmp;
+ do {
+ *t++ = "0123456789"[errnum % 10];
+ } while (errnum /= 10);
+ for (p = ebuf + sizeof(UPREFIX) - 1;;) {
+ *p++ = *--t;
+ if (t <= tmp)
+ break;
+ }
+ return (ebuf);
}
#endif
diff --git a/nss/lib/dbm/tests/lots.c b/nss/lib/dbm/tests/lots.c
index 54fd397..91bba49 100644
--- a/nss/lib/dbm/tests/lots.c
+++ b/nss/lib/dbm/tests/lots.c
@@ -40,8 +40,8 @@
#include <assert.h>
#include "mcom_db.h"
-DB *database=0;
-int MsgPriority=5;
+DB *database = 0;
+int MsgPriority = 5;
#if defined(_WINDOWS) && !defined(WIN32)
#define int32 long
@@ -52,17 +52,16 @@ int MsgPriority=5;
#endif
typedef enum {
-USE_LARGE_KEY,
-USE_SMALL_KEY
+ USE_LARGE_KEY,
+ USE_SMALL_KEY
} key_type_enum;
-#define TraceMe(priority, msg) \
- do { \
- if(priority <= MsgPriority) \
- { \
- ReportStatus msg; \
- } \
- } while(0)
+#define TraceMe(priority, msg) \
+ do { \
+ if (priority <= MsgPriority) { \
+ ReportStatus msg; \
+ } \
+ } while (0)
int
ReportStatus(char *string, ...)
@@ -77,9 +76,9 @@ ReportStatus(char *string, ...)
vfprintf(stderr, string, args);
va_end(args);
- fprintf (stderr, "\n");
+ fprintf(stderr, "\n");
- return(0);
+ return (0);
}
int
@@ -92,144 +91,139 @@ ReportError(char *string, ...)
#else
va_start(args);
#endif
- fprintf (stderr, "\n ");
+ fprintf(stderr, "\n ");
vfprintf(stderr, string, args);
- fprintf (stderr, "\n");
+ fprintf(stderr, "\n");
va_end(args);
- return(0);
+ return (0);
}
-DBT * MakeLargeKey(int32 num)
+DBT *
+MakeLargeKey(int32 num)
{
- int32 low_bits;
- static DBT rv;
- static char *string_rv=0;
- int rep_char;
- size_t size;
+ int32 low_bits;
+ static DBT rv;
+ static char *string_rv = 0;
+ int rep_char;
+ size_t size;
- if(string_rv)
- free(string_rv);
+ if (string_rv)
+ free(string_rv);
- /* generate a really large text key derived from
+ /* generate a really large text key derived from
* an int32
*/
- low_bits = (num % 10000) + 1;
+ low_bits = (num % 10000) + 1;
- /* get the repeat char from the low 26 */
- rep_char = (char) ((low_bits % 26) + 'a');
+ /* get the repeat char from the low 26 */
+ rep_char = (char)((low_bits % 26) + 'a');
- /* malloc a string low_bits wide */
- size = low_bits*sizeof(char);
- string_rv = (char *)malloc(size);
+ /* malloc a string low_bits wide */
+ size = low_bits * sizeof(char);
+ string_rv = (char *)malloc(size);
- memset(string_rv, rep_char, size);
+ memset(string_rv, rep_char, size);
- rv.data = string_rv;
- rv.size = size;
+ rv.data = string_rv;
+ rv.size = size;
- return(&rv);
+ return (&rv);
}
-DBT * MakeSmallKey(int32 num)
+DBT *
+MakeSmallKey(int32 num)
{
- static DBT rv;
- static char data_string[64];
+ static DBT rv;
+ static char data_string[64];
- rv.data = data_string;
+ rv.data = data_string;
- sprintf(data_string, "%ld", (long)num);
- rv.size = strlen(data_string);
-
- return(&rv);
+ sprintf(data_string, "%ld", (long)num);
+ rv.size = strlen(data_string);
+ return (&rv);
}
-DBT * GenKey(int32 num, key_type_enum key_type)
+DBT *
+GenKey(int32 num, key_type_enum key_type)
{
- DBT *key;
-
- switch(key_type)
- {
- case USE_LARGE_KEY:
- key = MakeLargeKey(num);
- break;
- case USE_SMALL_KEY:
- key = MakeSmallKey(num);
- break;
- default:
- abort();
- break;
- }
-
- return(key);
+ DBT *key;
+
+ switch (key_type) {
+ case USE_LARGE_KEY:
+ key = MakeLargeKey(num);
+ break;
+ case USE_SMALL_KEY:
+ key = MakeSmallKey(num);
+ break;
+ default:
+ abort();
+ break;
+ }
+
+ return (key);
}
int
SeqDatabase()
{
- int status;
- DBT key, data;
+ int status;
+ DBT key, data;
- ReportStatus("SEQuencing through database...");
+ ReportStatus("SEQuencing through database...");
- /* seq through the whole database */
- if(!(status = (*database->seq)(database, &key, &data, R_FIRST)))
- {
- while(!(status = (database->seq) (database, &key, &data, R_NEXT)))
- ; /* null body */
- }
+ /* seq through the whole database */
+ if (!(status = (*database->seq)(database, &key, &data, R_FIRST))) {
+ while (!(status = (database->seq)(database, &key, &data, R_NEXT)))
+ ; /* null body */
+ }
- if(status < 0)
- ReportError("Error seq'ing database");
+ if (status < 0)
+ ReportError("Error seq'ing database");
- return(status);
+ return (status);
}
-int
+int
VerifyData(DBT *data, int32 num, key_type_enum key_type)
{
- int32 count, compare_num;
- size_t size;
- int32 *int32_array;
+ int32 count, compare_num;
+ size_t size;
+ int32 *int32_array;
- /* The first int32 is count
+ /* The first int32 is count
* The other n entries should
* all equal num
*/
- if(data->size < sizeof(int32))
- {
- ReportError("Data size corrupted");
- return -1;
- }
+ if (data->size < sizeof(int32)) {
+ ReportError("Data size corrupted");
+ return -1;
+ }
- memcpy(&count, data->data, sizeof(int32));
+ memcpy(&count, data->data, sizeof(int32));
- size = sizeof(int32)*(count+1);
+ size = sizeof(int32) * (count + 1);
- if(size != data->size)
- {
- ReportError("Data size corrupted");
- return -1;
- }
+ if (size != data->size) {
+ ReportError("Data size corrupted");
+ return -1;
+ }
- int32_array = (int32*)data->data;
+ int32_array = (int32 *)data->data;
- for(;count > 0; count--)
- {
- memcpy(&compare_num, &int32_array[count], sizeof(int32));
+ for (; count > 0; count--) {
+ memcpy(&compare_num, &int32_array[count], sizeof(int32));
- if(compare_num != num)
- {
- ReportError("Data corrupted");
- return -1;
- }
- }
+ if (compare_num != num) {
+ ReportError("Data corrupted");
+ return -1;
+ }
+ }
- return(0);
+ return (0);
}
-
/* verify that a range of number strings exist
* or don't exist. And that the data is valid
*/
@@ -238,94 +232,77 @@ VerifyData(DBT *data, int32 num, key_type_enum key_type)
int
VerifyRange(int32 low, int32 high, int32 should_exist, key_type_enum key_type)
{
- DBT *key, data;
- int32 num;
- int status;
-
- TraceMe(1, ("Verifying: %ld to %ld, using %s keys",
- low, high, key_type == USE_SMALL_KEY ? "SMALL" : "LARGE"));
-
- for(num = low; num <= high; num++)
- {
-
- key = GenKey(num, key_type);
-
- status = (*database->get)(database, key, &data, 0);
-
- if(status == 0)
- {
- /* got the item */
- if(!should_exist)
- {
- ReportError("Item exists but shouldn't: %ld", num);
- }
- else
- {
- /* else verify the data */
- VerifyData(&data, num, key_type);
- }
- }
- else if(status > 0)
- {
- /* item not found */
- if(should_exist)
- {
- ReportError("Item not found but should be: %ld", num);
- }
- }
- else
- {
- /* database error */
- ReportError("Database error");
- return(-1);
- }
-
- }
-
- TraceMe(1, ("Correctly verified: %ld to %ld", low, high));
-
- return(0);
-
+ DBT *key, data;
+ int32 num;
+ int status;
+
+ TraceMe(1, ("Verifying: %ld to %ld, using %s keys",
+ low, high, key_type == USE_SMALL_KEY ? "SMALL" : "LARGE"));
+
+ for (num = low; num <= high; num++) {
+
+ key = GenKey(num, key_type);
+
+ status = (*database->get)(database, key, &data, 0);
+
+ if (status == 0) {
+ /* got the item */
+ if (!should_exist) {
+ ReportError("Item exists but shouldn't: %ld", num);
+ } else {
+ /* else verify the data */
+ VerifyData(&data, num, key_type);
+ }
+ } else if (status > 0) {
+ /* item not found */
+ if (should_exist) {
+ ReportError("Item not found but should be: %ld", num);
+ }
+ } else {
+ /* database error */
+ ReportError("Database error");
+ return (-1);
+ }
+ }
+
+ TraceMe(1, ("Correctly verified: %ld to %ld", low, high));
+
+ return (0);
}
DBT *
GenData(int32 num)
{
- int32 n;
- static DBT *data=0;
- int32 *int32_array;
- size_t size;
+ int32 n;
+ static DBT *data = 0;
+ int32 *int32_array;
+ size_t size;
- if(!data)
- {
- data = (DBT*)malloc(sizeof(DBT));
- data->size = 0;
- data->data = 0;
- }
- else if(data->data)
- {
- free(data->data);
- }
+ if (!data) {
+ data = (DBT *)malloc(sizeof(DBT));
+ data->size = 0;
+ data->data = 0;
+ } else if (data->data) {
+ free(data->data);
+ }
- n = rand();
+ n = rand();
- n = n % 512; /* bound to a 2K size */
+ n = n % 512; /* bound to a 2K size */
-
- size = sizeof(int32)*(n+1);
- int32_array = (int32 *) malloc(size);
+ size = sizeof(int32) * (n + 1);
+ int32_array = (int32 *)malloc(size);
- memcpy(&int32_array[0], &n, sizeof(int32));
+ memcpy(&int32_array[0], &n, sizeof(int32));
- for(; n > 0; n--)
- {
- memcpy(&int32_array[n], &num, sizeof(int32));
- }
+ for (; n > 0; n--) {
+ memcpy(&int32_array[n], &num, sizeof(int32));
+ }
- data->data = (void*)int32_array;
- data->size = size;
+ data->data = (void *)int32_array;
+ data->size = size;
- return(data);
+ return (data);
}
#define ADD_RANGE 1
@@ -334,61 +311,49 @@ GenData(int32 num)
int
AddOrDelRange(int32 low, int32 high, int action, key_type_enum key_type)
{
- DBT *key, *data;
+ DBT *key, *data;
#if 0 /* only do this if your really analy checking the puts */
DBT tmp_data;
-#endif
- int32 num;
- int status;
-
- if(action != ADD_RANGE && action != DELETE_RANGE)
- assert(0);
-
- if(action == ADD_RANGE)
- {
- TraceMe(1, ("Adding: %ld to %ld: %s keys", low, high,
- key_type == USE_SMALL_KEY ? "SMALL" : "LARGE"));
- }
- else
- {
- TraceMe(1, ("Deleting: %ld to %ld: %s keys", low, high,
- key_type == USE_SMALL_KEY ? "SMALL" : "LARGE"));
- }
-
- for(num = low; num <= high; num++)
- {
-
- key = GenKey(num, key_type);
-
- if(action == ADD_RANGE)
- {
- data = GenData(num);
- status = (*database->put)(database, key, data, 0);
- }
- else
- {
- status = (*database->del)(database, key, 0);
- }
-
- if(status < 0)
- {
- ReportError("Database error %s item: %ld",
- action == ADD_RANGE ? "ADDING" : "DELETING",
- num);
- }
- else if(status > 0)
- {
- ReportError("Could not %s item: %ld",
- action == ADD_RANGE ? "ADD" : "DELETE",
- num);
- }
- else if(action == ADD_RANGE)
- {
+#endif
+ int32 num;
+ int status;
+
+ if (action != ADD_RANGE && action != DELETE_RANGE)
+ assert(0);
+
+ if (action == ADD_RANGE) {
+ TraceMe(1, ("Adding: %ld to %ld: %s keys", low, high,
+ key_type == USE_SMALL_KEY ? "SMALL" : "LARGE"));
+ } else {
+ TraceMe(1, ("Deleting: %ld to %ld: %s keys", low, high,
+ key_type == USE_SMALL_KEY ? "SMALL" : "LARGE"));
+ }
+
+ for (num = low; num <= high; num++) {
+
+ key = GenKey(num, key_type);
+
+ if (action == ADD_RANGE) {
+ data = GenData(num);
+ status = (*database->put)(database, key, data, 0);
+ } else {
+ status = (*database->del)(database, key, 0);
+ }
+
+ if (status < 0) {
+ ReportError("Database error %s item: %ld",
+ action == ADD_RANGE ? "ADDING" : "DELETING",
+ num);
+ } else if (status > 0) {
+ ReportError("Could not %s item: %ld",
+ action == ADD_RANGE ? "ADD" : "DELETE",
+ num);
+ } else if (action == ADD_RANGE) {
#define SYNC_EVERY_TIME
#ifdef SYNC_EVERY_TIME
- status = (*database->sync)(database, 0);
- if(status != 0)
- ReportError("Database error syncing after add");
+ status = (*database->sync)(database, 0);
+ if (status != 0)
+ ReportError("Database error syncing after add");
#endif
#if 0 /* only do this if your really analy checking the puts */
@@ -410,197 +375,179 @@ AddOrDelRange(int32 low, int32 high, int action, key_type_enum key_type)
VerifyRange(low, num, SHOULD_EXIST, key_type);
}
#endif
-
- }
- }
-
+ }
+ }
- if(action == ADD_RANGE)
- {
- TraceMe(1, ("Successfully added: %ld to %ld", low, high));
- }
- else
- {
- TraceMe(1, ("Successfully deleted: %ld to %ld", low, high));
- }
+ if (action == ADD_RANGE) {
+ TraceMe(1, ("Successfully added: %ld to %ld", low, high));
+ } else {
+ TraceMe(1, ("Successfully deleted: %ld to %ld", low, high));
+ }
- return(0);
+ return (0);
}
int
TestRange(int32 low, int32 range, key_type_enum key_type)
{
- int status; int32 low_of_range1, high_of_range1; int32 low_of_range2, high_of_range2;
- int32 low_of_range3, high_of_range3;
+ int status;
+ int32 low_of_range1, high_of_range1;
+ int32 low_of_range2, high_of_range2;
+ int32 low_of_range3, high_of_range3;
- status = AddOrDelRange(low, low+range, ADD_RANGE, key_type);
- status = VerifyRange(low, low+range, SHOULD_EXIST, key_type);
+ status = AddOrDelRange(low, low + range, ADD_RANGE, key_type);
+ status = VerifyRange(low, low + range, SHOULD_EXIST, key_type);
- TraceMe(1, ("Finished with sub test 1"));
+ TraceMe(1, ("Finished with sub test 1"));
- SeqDatabase();
+ SeqDatabase();
- low_of_range1 = low;
- high_of_range1 = low+(range/2);
- low_of_range2 = high_of_range1+1;
- high_of_range2 = low+range;
- status = AddOrDelRange(low_of_range1, high_of_range1, DELETE_RANGE, key_type);
- status = VerifyRange(low_of_range1, high_of_range1, SHOULD_NOT_EXIST, key_type);
- status = VerifyRange(low_of_range2, low_of_range2, SHOULD_EXIST, key_type);
+ low_of_range1 = low;
+ high_of_range1 = low + (range / 2);
+ low_of_range2 = high_of_range1 + 1;
+ high_of_range2 = low + range;
+ status = AddOrDelRange(low_of_range1, high_of_range1, DELETE_RANGE, key_type);
+ status = VerifyRange(low_of_range1, high_of_range1, SHOULD_NOT_EXIST, key_type);
+ status = VerifyRange(low_of_range2, low_of_range2, SHOULD_EXIST, key_type);
- TraceMe(1, ("Finished with sub test 2"));
+ TraceMe(1, ("Finished with sub test 2"));
- SeqDatabase();
+ SeqDatabase();
- status = AddOrDelRange(low_of_range1, high_of_range1, ADD_RANGE, key_type);
- /* the whole thing should exist now */
- status = VerifyRange(low, low+range, SHOULD_EXIST, key_type);
+ status = AddOrDelRange(low_of_range1, high_of_range1, ADD_RANGE, key_type);
+ /* the whole thing should exist now */
+ status = VerifyRange(low, low + range, SHOULD_EXIST, key_type);
- TraceMe(1, ("Finished with sub test 3"));
+ TraceMe(1, ("Finished with sub test 3"));
- SeqDatabase();
+ SeqDatabase();
- status = AddOrDelRange(low_of_range2, high_of_range2, DELETE_RANGE, key_type);
- status = VerifyRange(low_of_range1, high_of_range1, SHOULD_EXIST, key_type);
- status = VerifyRange(low_of_range2, high_of_range2, SHOULD_NOT_EXIST, key_type);
+ status = AddOrDelRange(low_of_range2, high_of_range2, DELETE_RANGE, key_type);
+ status = VerifyRange(low_of_range1, high_of_range1, SHOULD_EXIST, key_type);
+ status = VerifyRange(low_of_range2, high_of_range2, SHOULD_NOT_EXIST, key_type);
- TraceMe(1, ("Finished with sub test 4"));
+ TraceMe(1, ("Finished with sub test 4"));
- SeqDatabase();
+ SeqDatabase();
- status = AddOrDelRange(low_of_range2, high_of_range2, ADD_RANGE, key_type);
- /* the whole thing should exist now */
- status = VerifyRange(low, low+range, SHOULD_EXIST, key_type);
+ status = AddOrDelRange(low_of_range2, high_of_range2, ADD_RANGE, key_type);
+ /* the whole thing should exist now */
+ status = VerifyRange(low, low + range, SHOULD_EXIST, key_type);
- TraceMe(1, ("Finished with sub test 5"));
+ TraceMe(1, ("Finished with sub test 5"));
- SeqDatabase();
+ SeqDatabase();
- low_of_range1 = low;
- high_of_range1 = low+(range/3);
- low_of_range2 = high_of_range1+1;
- high_of_range2 = high_of_range1+(range/3);
- low_of_range3 = high_of_range2+1;
- high_of_range3 = low+range;
- /* delete range 2 */
- status = AddOrDelRange(low_of_range2, high_of_range2, DELETE_RANGE, key_type);
- status = VerifyRange(low_of_range1, high_of_range1, SHOULD_EXIST, key_type);
- status = VerifyRange(low_of_range2, low_of_range2, SHOULD_NOT_EXIST, key_type);
- status = VerifyRange(low_of_range3, low_of_range2, SHOULD_EXIST, key_type);
+ low_of_range1 = low;
+ high_of_range1 = low + (range / 3);
+ low_of_range2 = high_of_range1 + 1;
+ high_of_range2 = high_of_range1 + (range / 3);
+ low_of_range3 = high_of_range2 + 1;
+ high_of_range3 = low + range;
+ /* delete range 2 */
+ status = AddOrDelRange(low_of_range2, high_of_range2, DELETE_RANGE, key_type);
+ status = VerifyRange(low_of_range1, high_of_range1, SHOULD_EXIST, key_type);
+ status = VerifyRange(low_of_range2, low_of_range2, SHOULD_NOT_EXIST, key_type);
+ status = VerifyRange(low_of_range3, low_of_range2, SHOULD_EXIST, key_type);
- TraceMe(1, ("Finished with sub test 6"));
+ TraceMe(1, ("Finished with sub test 6"));
- SeqDatabase();
+ SeqDatabase();
- status = AddOrDelRange(low_of_range2, high_of_range2, ADD_RANGE, key_type);
- /* the whole thing should exist now */
- status = VerifyRange(low, low+range, SHOULD_EXIST, key_type);
+ status = AddOrDelRange(low_of_range2, high_of_range2, ADD_RANGE, key_type);
+ /* the whole thing should exist now */
+ status = VerifyRange(low, low + range, SHOULD_EXIST, key_type);
- TraceMe(1, ("Finished with sub test 7"));
+ TraceMe(1, ("Finished with sub test 7"));
- return(0);
+ return (0);
}
#define START_RANGE 109876
int
main(int argc, char **argv)
{
- int32 i, j=0;
+ int32 i, j = 0;
int quick_exit = 0;
int large_keys = 0;
HASHINFO hash_info = {
- 16*1024,
+ 16 * 1024,
0,
0,
0,
0,
- 0};
+ 0
+ };
-
- if(argc > 1)
- {
- while(argc > 1)
- {
- if(!strcmp(argv[argc-1], "-quick"))
+ if (argc > 1) {
+ while (argc > 1) {
+ if (!strcmp(argv[argc - 1], "-quick"))
quick_exit = 1;
- else if(!strcmp(argv[argc-1], "-large"))
- {
+ else if (!strcmp(argv[argc - 1], "-large")) {
large_keys = 1;
- }
+ }
argc--;
- }
- }
+ }
+ }
- database = dbopen("test.db", O_RDWR | O_CREAT, 0644, DB_HASH, &hash_info);
+ database = dbopen("test.db", O_RDWR | O_CREAT, 0644, DB_HASH, &hash_info);
- if(!database)
- {
- ReportError("Could not open database");
+ if (!database) {
+ ReportError("Could not open database");
#ifdef unix
- perror("");
+ perror("");
#endif
- exit(1);
- }
-
- if(quick_exit)
- {
- if(large_keys)
- TestRange(START_RANGE, 200, USE_LARGE_KEY);
- else
- TestRange(START_RANGE, 200, USE_SMALL_KEY);
-
- (*database->sync)(database, 0);
- (*database->close)(database);
+ exit(1);
+ }
+
+ if (quick_exit) {
+ if (large_keys)
+ TestRange(START_RANGE, 200, USE_LARGE_KEY);
+ else
+ TestRange(START_RANGE, 200, USE_SMALL_KEY);
+
+ (*database->sync)(database, 0);
+ (*database->close)(database);
exit(0);
- }
-
- for(i=100; i < 10000000; i+=200)
- {
- if(1 || j)
- {
- TestRange(START_RANGE, i, USE_LARGE_KEY);
- j = 0;
- }
- else
- {
- TestRange(START_RANGE, i, USE_SMALL_KEY);
- j = 1;
- }
-
- if(1 == rand() % 3)
- {
- (*database->sync)(database, 0);
- }
-
- if(1 == rand() % 3)
- {
- /* close and reopen */
- (*database->close)(database);
- database = dbopen("test.db", O_RDWR | O_CREAT, 0644, DB_HASH, 0);
- if(!database)
- {
- ReportError("Could not reopen database");
+ }
+
+ for (i = 100; i < 10000000; i += 200) {
+ if (1 || j) {
+ TestRange(START_RANGE, i, USE_LARGE_KEY);
+ j = 0;
+ } else {
+ TestRange(START_RANGE, i, USE_SMALL_KEY);
+ j = 1;
+ }
+
+ if (1 == rand() % 3) {
+ (*database->sync)(database, 0);
+ }
+
+ if (1 == rand() % 3) {
+ /* close and reopen */
+ (*database->close)(database);
+ database = dbopen("test.db", O_RDWR | O_CREAT, 0644, DB_HASH, 0);
+ if (!database) {
+ ReportError("Could not reopen database");
#ifdef unix
- perror("");
+ perror("");
#endif
- exit(1);
- }
- }
- else
- {
- /* reopen database without closeing the other */
- database = dbopen("test.db", O_RDWR | O_CREAT, 0644, DB_HASH, 0);
- if(!database)
- {
- ReportError("Could not reopen database "
- "after not closing the other");
+ exit(1);
+ }
+ } else {
+ /* reopen database without closeing the other */
+ database = dbopen("test.db", O_RDWR | O_CREAT, 0644, DB_HASH, 0);
+ if (!database) {
+ ReportError("Could not reopen database "
+ "after not closing the other");
#ifdef unix
- perror("");
+ perror("");
#endif
- exit(1);
- }
- }
- }
+ exit(1);
+ }
+ }
+ }
- return(0);
+ return (0);
}
diff --git a/nss/lib/dev/ckhelper.c b/nss/lib/dev/ckhelper.c
index 0ca5654..4f39726 100644
--- a/nss/lib/dev/ckhelper.c
+++ b/nss/lib/dev/ckhelper.c
@@ -16,51 +16,49 @@ 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) };
+ 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) };
+ 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) };
+ 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) };
+ 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) };
+ g_ck_class_privkey = { (CK_VOID_PTR)&s_class_privkey, sizeof(s_class_privkey) };
static PRBool
-is_string_attribute (
- CK_ATTRIBUTE_TYPE aType
-)
+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;
+ 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
-)
+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;
@@ -69,114 +67,111 @@ nssCKObject_GetAttributes (
PRStatus nssrv;
PRBool alloced = PR_FALSE;
void *epv = nssSlot_GetCryptokiEPV(slot);
- hSession = session->handle;
+ hSession = session->handle;
if (arenaOpt) {
- mark = nssArena_Mark(arenaOpt);
- if (!mark) {
- goto loser;
- }
+ 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;
+ /* 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 &&
+ if (ckrv != CKR_OK &&
ckrv != CKR_ATTRIBUTE_TYPE_INVALID &&
- ckrv != CKR_ATTRIBUTE_SENSITIVE)
- {
- nss_SetError(NSS_ERROR_DEVICE_ERROR);
- goto loser;
+ 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);
- }
- }
+ 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);
- }
- }
+ 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
-)
+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,
+ nssrv = nssCKObject_GetAttributes(object, &attr, 1,
arenaOpt, session, slot);
if (nssrv != PR_SUCCESS) {
- return nssrv;
+ return nssrv;
}
rvItem->data = (void *)attr.pValue;
rvItem->size = (PRUint32)attr.ulValueLen;
@@ -184,13 +179,12 @@ nssCKObject_GetAttributeItem (
}
NSS_IMPLEMENT PRBool
-nssCKObject_IsAttributeTrue (
- CK_OBJECT_HANDLE object,
- CK_ATTRIBUTE_TYPE attribute,
- nssSession *session,
- NSSSlot *slot,
- PRStatus *rvStatus
-)
+nssCKObject_IsAttributeTrue(
+ CK_OBJECT_HANDLE object,
+ CK_ATTRIBUTE_TYPE attribute,
+ nssSession *session,
+ NSSSlot *slot,
+ PRStatus *rvStatus)
{
CK_BBOOL bool;
CK_ATTRIBUTE_PTR attr;
@@ -200,50 +194,48 @@ nssCKObject_IsAttributeTrue (
attr = &atemplate;
NSS_CK_SET_ATTRIBUTE_VAR(attr, attribute, bool);
nssSession_EnterMonitor(session);
- ckrv = CKAPI(epv)->C_GetAttributeValue(session->handle, object,
+ 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_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
-)
+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,
+ ckrv = CKAPI(epv)->C_SetAttributeValue(session->handle, object,
obj_template, count);
nssSession_ExitMonitor(session);
if (ckrv == CKR_OK) {
- return PR_SUCCESS;
+ return PR_SUCCESS;
} else {
- return PR_FAILURE;
+ return PR_FAILURE;
}
}
NSS_IMPLEMENT PRBool
-nssCKObject_IsTokenObjectTemplate (
- CK_ATTRIBUTE_PTR objectTemplate,
- CK_ULONG otsize
-)
+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);
- }
+ for (ul = 0; ul < otsize; ul++) {
+ if (objectTemplate[ul].type == CKA_TOKEN) {
+ return (*((CK_BBOOL *)objectTemplate[ul].pValue) == CK_TRUE);
+ }
}
return PR_FALSE;
}
@@ -253,32 +245,31 @@ nss_cert_type_from_ck_attrib(CK_ATTRIBUTE_PTR attrib)
{
CK_CERTIFICATE_TYPE ckCertType;
if (!attrib->pValue) {
- /* default to PKIX */
- return NSSCertificateType_PKIX;
+ /* default to PKIX */
+ return NSSCertificateType_PKIX;
}
ckCertType = *((CK_ULONG *)attrib->pValue);
switch (ckCertType) {
- case CKC_X_509:
- return NSSCertificateType_PKIX;
- default:
- break;
+ 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
-)
+nssCryptokiCertificate_GetAttributes(
+ nssCryptokiObject *certObject,
+ nssSession *sessionOpt,
+ NSSArena *arenaOpt,
+ NSSCertificateType *certTypeOpt,
+ NSSItem *idOpt,
+ NSSDER *encodingOpt,
+ NSSDER *issuerOpt,
+ NSSDER *serialOpt,
+ NSSDER *subjectOpt)
{
PRStatus status;
PRUint32 i;
@@ -290,27 +281,27 @@ nssCryptokiCertificate_GetAttributes (
/* 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);
+ NSS_CK_SET_ATTRIBUTE_NULL(attr, CKA_CERTIFICATE_TYPE);
}
if (idOpt) {
- NSS_CK_SET_ATTRIBUTE_NULL(attr, CKA_ID);
+ NSS_CK_SET_ATTRIBUTE_NULL(attr, CKA_ID);
}
if (encodingOpt) {
- NSS_CK_SET_ATTRIBUTE_NULL(attr, CKA_VALUE);
+ NSS_CK_SET_ATTRIBUTE_NULL(attr, CKA_VALUE);
}
if (issuerOpt) {
- NSS_CK_SET_ATTRIBUTE_NULL(attr, CKA_ISSUER);
+ NSS_CK_SET_ATTRIBUTE_NULL(attr, CKA_ISSUER);
}
if (serialOpt) {
- NSS_CK_SET_ATTRIBUTE_NULL(attr, CKA_SERIAL_NUMBER);
+ NSS_CK_SET_ATTRIBUTE_NULL(attr, CKA_SERIAL_NUMBER);
}
if (subjectOpt) {
- NSS_CK_SET_ATTRIBUTE_NULL(attr, CKA_SUBJECT);
+ 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;
+ /* caller didn't want anything */
+ return PR_SUCCESS;
}
status = nssToken_GetCachedObjectAttributes(certObject->token, arenaOpt,
@@ -318,77 +309,90 @@ nssCryptokiCertificate_GetAttributes (
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;
+ 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++;
+ *certTypeOpt = nss_cert_type_from_ck_attrib(&cert_template[i]);
+ i++;
}
if (idOpt) {
- NSS_CK_ATTRIBUTE_TO_ITEM(&cert_template[i], idOpt); i++;
+ NSS_CK_ATTRIBUTE_TO_ITEM(&cert_template[i], idOpt);
+ i++;
}
if (encodingOpt) {
- NSS_CK_ATTRIBUTE_TO_ITEM(&cert_template[i], encodingOpt); i++;
+ NSS_CK_ATTRIBUTE_TO_ITEM(&cert_template[i], encodingOpt);
+ i++;
}
if (issuerOpt) {
- NSS_CK_ATTRIBUTE_TO_ITEM(&cert_template[i], issuerOpt); i++;
+ NSS_CK_ATTRIBUTE_TO_ITEM(&cert_template[i], issuerOpt);
+ i++;
}
if (serialOpt) {
- NSS_CK_ATTRIBUTE_TO_ITEM(&cert_template[i], serialOpt); i++;
+ NSS_CK_ATTRIBUTE_TO_ITEM(&cert_template[i], serialOpt);
+ i++;
}
if (subjectOpt) {
- NSS_CK_ATTRIBUTE_TO_ITEM(&cert_template[i], subjectOpt); i++;
+ NSS_CK_ATTRIBUTE_TO_ITEM(&cert_template[i], subjectOpt);
+ i++;
}
return PR_SUCCESS;
}
-static nssTrustLevel
-get_nss_trust (
- CK_TRUST ckt
-)
+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;
+ 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
-)
+nssCryptokiTrust_GetAttributes(
+ nssCryptokiObject *trustObject,
+ nssSession *sessionOpt,
+ NSSItem *sha1_hash,
+ nssTrustLevel *serverAuth,
+ nssTrustLevel *clientAuth,
+ nssTrustLevel *codeSigning,
+ nssTrustLevel *emailProtection,
+ PRBool *stepUpApproved)
{
PRStatus status;
NSSSlot *slot;
@@ -406,42 +410,41 @@ nssCryptokiTrust_GetAttributes (
/* 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_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_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_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,
+ 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;
- }
+ 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;
+ /* 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);
@@ -453,16 +456,15 @@ nssCryptokiTrust_GetAttributes (
}
NSS_IMPLEMENT PRStatus
-nssCryptokiCRL_GetAttributes (
- nssCryptokiObject *crlObject,
- nssSession *sessionOpt,
- NSSArena *arenaOpt,
- NSSItem *encodingOpt,
- NSSItem *subjectOpt,
- CK_ULONG* crl_class,
- NSSUTF8 **urlOpt,
- PRBool *isKRLOpt
-)
+nssCryptokiCRL_GetAttributes(
+ nssCryptokiObject *crlObject,
+ nssSession *sessionOpt,
+ NSSArena *arenaOpt,
+ NSSItem *encodingOpt,
+ NSSItem *subjectOpt,
+ CK_ULONG *crl_class,
+ NSSUTF8 **urlOpt,
+ PRBool *isKRLOpt)
{
PRStatus status;
NSSSlot *slot;
@@ -477,69 +479,72 @@ nssCryptokiCRL_GetAttributes (
NSS_CK_SET_ATTRIBUTE_NULL(attr, CKA_CLASS);
}
if (encodingOpt) {
- NSS_CK_SET_ATTRIBUTE_NULL(attr, CKA_VALUE);
+ NSS_CK_SET_ATTRIBUTE_NULL(attr, CKA_VALUE);
}
if (urlOpt) {
- NSS_CK_SET_ATTRIBUTE_NULL(attr, CKA_NSS_URL);
+ NSS_CK_SET_ATTRIBUTE_NULL(attr, CKA_NSS_URL);
}
if (isKRLOpt) {
- NSS_CK_SET_ATTRIBUTE_NULL(attr, CKA_NSS_KRL);
+ NSS_CK_SET_ATTRIBUTE_NULL(attr, CKA_NSS_KRL);
}
if (subjectOpt) {
- NSS_CK_SET_ATTRIBUTE_NULL(attr, CKA_SUBJECT);
+ NSS_CK_SET_ATTRIBUTE_NULL(attr, CKA_SUBJECT);
}
NSS_CK_TEMPLATE_FINISH(crl_template, attr, crl_size);
status = nssToken_GetCachedObjectAttributes(crlObject->token, NULL,
- crlObject,
+ 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;
+ 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++;
+ NSS_CK_ATTRIBUTE_TO_ULONG(&crl_template[i], *crl_class);
+ i++;
}
if (encodingOpt) {
- NSS_CK_ATTRIBUTE_TO_ITEM(&crl_template[i], encodingOpt); i++;
+ NSS_CK_ATTRIBUTE_TO_ITEM(&crl_template[i], encodingOpt);
+ i++;
}
if (urlOpt) {
- NSS_CK_ATTRIBUTE_TO_UTF8(&crl_template[i], *urlOpt); i++;
+ NSS_CK_ATTRIBUTE_TO_UTF8(&crl_template[i], *urlOpt);
+ i++;
}
if (isKRLOpt) {
- NSS_CK_ATTRIBUTE_TO_BOOL(&crl_template[i], *isKRLOpt); i++;
+ NSS_CK_ATTRIBUTE_TO_BOOL(&crl_template[i], *isKRLOpt);
+ i++;
}
if (subjectOpt) {
- NSS_CK_ATTRIBUTE_TO_ITEM(&crl_template[i], subjectOpt); i++;
+ 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
-)
+nssCryptokiPrivateKey_SetCertificate(
+ nssCryptokiObject *keyObject,
+ nssSession *sessionOpt,
+ const NSSUTF8 *nickname,
+ NSSItem *id,
+ NSSDER *subject)
{
CK_RV ckrv;
CK_ATTRIBUTE_PTR attr;
@@ -558,20 +563,20 @@ nssCryptokiPrivateKey_SetCertificate (
NSS_CK_TEMPLATE_FINISH(key_template, attr, key_size);
if (sessionOpt) {
- if (!nssSession_IsReadWrite(sessionOpt)) {
- return PR_FAILURE;
- }
- session = sessionOpt;
+ if (!nssSession_IsReadWrite(sessionOpt)) {
+ return PR_FAILURE;
+ }
+ session = sessionOpt;
} else if (defaultSession && nssSession_IsReadWrite(defaultSession)) {
- session = 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;
+ 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,
@@ -580,9 +585,8 @@ nssCryptokiPrivateKey_SetCertificate (
key_size);
if (createdSession) {
- nssSession_Destroy(session);
+ nssSession_Destroy(session);
}
return (ckrv == CKR_OK) ? PR_SUCCESS : PR_FAILURE;
}
-
diff --git a/nss/lib/dev/ckhelper.h b/nss/lib/dev/ckhelper.h
index cb4b662..169fc20 100644
--- a/nss/lib/dev/ckhelper.h
+++ b/nss/lib/dev/ckhelper.h
@@ -26,38 +26,39 @@ 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; \
+#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; \
+#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; \
+#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)--; \
+ 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); \
+#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; \
+#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]));
+ PR_ASSERT(size <= sizeof(_template) / sizeof(_template[0]));
/* NSS_CK_ATTRIBUTE_TO_ITEM(attrib, item)
*
@@ -65,92 +66,82 @@ NSS_EXTERN_DATA const NSSItem g_ck_class_privkey;
*/
#define NSS_CK_ATTRIBUTE_TO_ITEM(attrib, item) \
if ((CK_LONG)(attrib)->ulValueLen > 0) { \
- (item)->data = (void *)(attrib)->pValue; \
- (item)->size = (PRUint32)(attrib)->ulValueLen; \
+ (item)->data = (void *)(attrib)->pValue; \
+ (item)->size = (PRUint32)(attrib)->ulValueLen; \
} else { \
- (item)->data = 0; \
- (item)->size = 0; \
+ (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_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); \
+#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) \
+#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; \
+#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
-);
+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
-);
+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
-);
+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
-);
+nssCKObject_IsTokenObjectTemplate(
+ CK_ATTRIBUTE_PTR objectTemplate,
+ CK_ULONG otsize);
PR_END_EXTERN_C
diff --git a/nss/lib/dev/dev.gyp b/nss/lib/dev/dev.gyp
new file mode 100644
index 0000000..dfa8f7e
--- /dev/null
+++ b/nss/lib/dev/dev.gyp
@@ -0,0 +1,26 @@
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+{
+ 'includes': [
+ '../../coreconf/config.gypi'
+ ],
+ 'targets': [
+ {
+ 'target_name': 'nssdev',
+ 'type': 'static_library',
+ 'sources': [
+ 'ckhelper.c',
+ 'devslot.c',
+ 'devtoken.c',
+ 'devutil.c'
+ ],
+ 'dependencies': [
+ '<(DEPTH)/exports.gyp:nss_exports'
+ ]
+ }
+ ],
+ 'variables': {
+ 'module': 'nss'
+ }
+} \ No newline at end of file
diff --git a/nss/lib/dev/dev.h b/nss/lib/dev/dev.h
index fa6242a..7e64e76 100644
--- a/nss/lib/dev/dev.h
+++ b/nss/lib/dev/dev.h
@@ -40,64 +40,44 @@ PR_BEGIN_EXTERN_C
*/
NSS_EXTERN PRStatus
-nss_InitializeGlobalModuleList
-(
- void
-);
+nss_InitializeGlobalModuleList(
+ void);
NSS_EXTERN PRStatus
-nss_DestroyGlobalModuleList
-(
- void
-);
+nss_DestroyGlobalModuleList(
+ void);
NSS_EXTERN NSSModule **
-nss_GetLoadedModules
-(
- void
-);
+nss_GetLoadedModules(
+ void);
NSS_EXTERN PRStatus
-nssGlobalModuleList_Add
-(
- NSSModule *module
-);
+nssGlobalModuleList_Add(
+ NSSModule *module);
NSS_EXTERN PRStatus
-nssGlobalModuleList_Remove
-(
- NSSModule *module
-);
+nssGlobalModuleList_Remove(
+ NSSModule *module);
NSS_EXTERN NSSModule *
-nssGlobalModuleList_FindModuleByName
-(
- NSSUTF8 *moduleName
-);
+nssGlobalModuleList_FindModuleByName(
+ NSSUTF8 *moduleName);
NSS_EXTERN NSSSlot *
-nssGlobalModuleList_FindSlotByName
-(
- NSSUTF8 *slotName
-);
+nssGlobalModuleList_FindSlotByName(
+ NSSUTF8 *slotName);
NSS_EXTERN NSSToken *
-nssGlobalModuleList_FindTokenByName
-(
- NSSUTF8 *tokenName
-);
+nssGlobalModuleList_FindTokenByName(
+ NSSUTF8 *tokenName);
NSS_EXTERN NSSToken *
-nss_GetDefaultCryptoToken
-(
- void
-);
+nss_GetDefaultCryptoToken(
+ void);
NSS_EXTERN NSSToken *
-nss_GetDefaultDatabaseToken
-(
- void
-);
+nss_GetDefaultDatabaseToken(
+ void);
/*
* |-----------|<---> NSSSlot <--> NSSToken
@@ -118,66 +98,48 @@ nss_GetDefaultDatabaseToken
*/
NSS_EXTERN NSSModule *
-nssModule_Create
-(
- NSSUTF8 *moduleOpt,
- NSSUTF8 *uriOpt,
- NSSUTF8 *opaqueOpt,
- void *reserved
-);
+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
-);
+nssModule_CreateFromSpec(
+ NSSUTF8 *moduleSpec,
+ NSSModule *parent,
+ PRBool loadSubModules);
NSS_EXTERN PRStatus
-nssModule_Destroy
-(
- NSSModule *mod
-);
+nssModule_Destroy(
+ NSSModule *mod);
NSS_EXTERN NSSModule *
-nssModule_AddRef
-(
- NSSModule *mod
-);
+nssModule_AddRef(
+ NSSModule *mod);
NSS_EXTERN NSSUTF8 *
-nssModule_GetName
-(
- NSSModule *mod
-);
+nssModule_GetName(
+ NSSModule *mod);
NSS_EXTERN NSSSlot **
-nssModule_GetSlots
-(
- NSSModule *mod
-);
+nssModule_GetSlots(
+ NSSModule *mod);
NSS_EXTERN NSSSlot *
-nssModule_FindSlotByName
-(
- NSSModule *mod,
- NSSUTF8 *slotName
-);
+nssModule_FindSlotByName(
+ NSSModule *mod,
+ NSSUTF8 *slotName);
NSS_EXTERN NSSToken *
-nssModule_FindTokenByName
-(
- NSSModule *mod,
- NSSUTF8 *tokenName
-);
+nssModule_FindTokenByName(
+ NSSModule *mod,
+ NSSUTF8 *tokenName);
NSS_EXTERN PRInt32
-nssModule_GetCertOrder
-(
- NSSModule *module
-);
+nssModule_GetCertOrder(
+ NSSModule *module);
/* NSSSlot
*
@@ -199,127 +161,89 @@ nssModule_GetCertOrder
*/
NSS_EXTERN PRStatus
-nssSlot_Destroy
-(
- NSSSlot *slot
-);
+nssSlot_Destroy(
+ NSSSlot *slot);
NSS_EXTERN NSSSlot *
-nssSlot_AddRef
-(
- NSSSlot *slot
-);
+nssSlot_AddRef(
+ NSSSlot *slot);
NSS_EXTERN void
-nssSlot_ResetDelay
-(
- NSSSlot *slot
-);
+nssSlot_ResetDelay(
+ NSSSlot *slot);
NSS_EXTERN NSSUTF8 *
-nssSlot_GetName
-(
- NSSSlot *slot
-);
+nssSlot_GetName(
+ NSSSlot *slot);
NSS_EXTERN NSSUTF8 *
-nssSlot_GetTokenName
-(
- NSSSlot *slot
-);
+nssSlot_GetTokenName(
+ NSSSlot *slot);
NSS_EXTERN NSSModule *
-nssSlot_GetModule
-(
- NSSSlot *slot
-);
+nssSlot_GetModule(
+ NSSSlot *slot);
NSS_EXTERN NSSToken *
-nssSlot_GetToken
-(
- NSSSlot *slot
-);
+nssSlot_GetToken(
+ NSSSlot *slot);
NSS_EXTERN PRBool
-nssSlot_IsTokenPresent
-(
- NSSSlot *slot
-);
+nssSlot_IsTokenPresent(
+ NSSSlot *slot);
NSS_EXTERN PRBool
-nssSlot_IsPermanent
-(
- NSSSlot *slot
-);
+nssSlot_IsPermanent(
+ NSSSlot *slot);
NSS_EXTERN PRBool
-nssSlot_IsFriendly
-(
- NSSSlot *slot
-);
+nssSlot_IsFriendly(
+ NSSSlot *slot);
NSS_EXTERN PRBool
-nssSlot_IsHardware
-(
- NSSSlot *slot
-);
+nssSlot_IsHardware(
+ NSSSlot *slot);
NSS_EXTERN PRBool
-nssSlot_IsLoggedIn
-(
- NSSSlot *slot
-);
+nssSlot_IsLoggedIn(
+ NSSSlot *slot);
NSS_EXTERN PRStatus
-nssSlot_Refresh
-(
- NSSSlot *slot
-);
+nssSlot_Refresh(
+ NSSSlot *slot);
NSS_EXTERN PRStatus
-nssSlot_Login
-(
- NSSSlot *slot,
- NSSCallback *pwcb
-);
+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
-);
+nssSlot_Logout(
+ NSSSlot *slot,
+ nssSession *sessionOpt);
NSS_EXTERN void
-nssSlot_EnterMonitor
-(
- NSSSlot *slot
-);
+nssSlot_EnterMonitor(
+ NSSSlot *slot);
NSS_EXTERN void
-nssSlot_ExitMonitor
-(
- NSSSlot *slot
-);
+nssSlot_ExitMonitor(
+ NSSSlot *slot);
#define NSSSLOT_ASK_PASSWORD_FIRST_TIME -1
-#define NSSSLOT_ASK_PASSWORD_EVERY_TIME 0
+#define NSSSLOT_ASK_PASSWORD_EVERY_TIME 0
NSS_EXTERN void
-nssSlot_SetPasswordDefaults
-(
- NSSSlot *slot,
- PRInt32 askPasswordTimeout
-);
+nssSlot_SetPasswordDefaults(
+ NSSSlot *slot,
+ PRInt32 askPasswordTimeout);
NSS_EXTERN PRStatus
-nssSlot_SetPassword
-(
- NSSSlot *slot,
- NSSUTF8 *oldPasswordOpt,
- NSSUTF8 *newPassword
-);
+nssSlot_SetPassword(
+ NSSSlot *slot,
+ NSSUTF8 *oldPasswordOpt,
+ NSSUTF8 *newPassword);
extern const NSSError NSS_ERROR_INVALID_PASSWORD;
extern const NSSError NSS_ERROR_USER_CANCELED;
@@ -328,12 +252,11 @@ extern const NSSError NSS_ERROR_USER_CANCELED;
*/
NSS_EXTERN nssSession *
-nssSlot_CreateSession
-(
- NSSSlot *slot,
- NSSArena *arenaOpt,
- PRBool readWrite /* so far, this is the only flag used */
-);
+nssSlot_CreateSession(
+ NSSSlot *slot,
+ NSSArena *arenaOpt,
+ PRBool readWrite /* so far, this is the only flag used */
+ );
/* NSSToken
*
@@ -366,251 +289,199 @@ nssSlot_CreateSession
*/
NSS_EXTERN PRStatus
-nssToken_Destroy
-(
- NSSToken *tok
-);
+nssToken_Destroy(
+ NSSToken *tok);
NSS_EXTERN NSSToken *
-nssToken_AddRef
-(
- NSSToken *tok
-);
+nssToken_AddRef(
+ NSSToken *tok);
NSS_EXTERN NSSUTF8 *
-nssToken_GetName
-(
- NSSToken *tok
-);
+nssToken_GetName(
+ NSSToken *tok);
NSS_EXTERN NSSModule *
-nssToken_GetModule
-(
- NSSToken *token
-);
+nssToken_GetModule(
+ NSSToken *token);
NSS_EXTERN NSSSlot *
-nssToken_GetSlot
-(
- NSSToken *tok
-);
+nssToken_GetSlot(
+ NSSToken *tok);
NSS_EXTERN PRBool
-nssToken_NeedsPINInitialization
-(
- NSSToken *token
-);
+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
-);
+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
-);
+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
-);
+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
-);
+nssToken_DeleteStoredObject(
+ nssCryptokiObject *instance);
NSS_EXTERN nssCryptokiObject **
-nssToken_FindObjects
-(
- NSSToken *token,
- nssSession *sessionOpt,
- CK_OBJECT_CLASS objclass,
- nssTokenSearchType searchType,
- PRUint32 maximumOpt,
- PRStatus *statusOpt
-);
+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
-);
+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
-);
+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
-);
+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
-);
+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
-);
+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
-);
+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
-);
+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
-);
+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
-);
+nssToken_FindPrivateKeys(
+ NSSToken *token,
+ nssSession *sessionOpt,
+ nssTokenSearchType searchType,
+ PRUint32 maximumOpt,
+ PRStatus *statusOpt);
NSS_EXTERN nssCryptokiObject *
-nssToken_FindPrivateKeyByID
-(
- NSSToken *token,
- nssSession *sessionOpt,
- NSSItem *keyID
-);
+nssToken_FindPrivateKeyByID(
+ NSSToken *token,
+ nssSession *sessionOpt,
+ NSSItem *keyID);
NSS_EXTERN nssCryptokiObject *
-nssToken_FindPublicKeyByID
-(
- NSSToken *token,
- nssSession *sessionOpt,
- NSSItem *keyID
-);
+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
-);
+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
-);
+nssToken_BeginDigest(
+ NSSToken *tok,
+ nssSession *sessionOpt,
+ NSSAlgorithmAndParameters *ap);
NSS_EXTERN PRStatus
-nssToken_ContinueDigest
-(
- NSSToken *tok,
- nssSession *sessionOpt,
- NSSItem *item
-);
+nssToken_ContinueDigest(
+ NSSToken *tok,
+ nssSession *sessionOpt,
+ NSSItem *item);
NSS_EXTERN NSSItem *
-nssToken_FinishDigest
-(
- NSSToken *tok,
- nssSession *sessionOpt,
- NSSItem *rvOpt,
- NSSArena *arenaOpt
-);
+nssToken_FinishDigest(
+ NSSToken *tok,
+ nssSession *sessionOpt,
+ NSSItem *rvOpt,
+ NSSArena *arenaOpt);
/* nssSession
*
@@ -621,36 +492,28 @@ nssToken_FinishDigest
*/
NSS_EXTERN PRStatus
-nssSession_Destroy
-(
- nssSession *s
-);
+nssSession_Destroy(
+ nssSession *s);
/* would like to inline */
NSS_EXTERN PRStatus
-nssSession_EnterMonitor
-(
- nssSession *s
-);
+nssSession_EnterMonitor(
+ nssSession *s);
/* would like to inline */
NSS_EXTERN PRStatus
-nssSession_ExitMonitor
-(
- nssSession *s
-);
+nssSession_ExitMonitor(
+ nssSession *s);
/* would like to inline */
NSS_EXTERN PRBool
-nssSession_IsReadWrite
-(
- nssSession *s
-);
+nssSession_IsReadWrite(
+ nssSession *s);
/* nssCryptokiObject
*
* An object living on a cryptoki token.
- * Not really proper to mix up the object types just because
+ * Not really proper to mix up the object types just because
* nssCryptokiObject itself is generic, but doing so anyway.
*
* nssCryptokiObject_Destroy
@@ -664,83 +527,67 @@ nssSession_IsReadWrite
*/
NSS_EXTERN void
-nssCryptokiObject_Destroy
-(
- nssCryptokiObject *object
-);
+nssCryptokiObject_Destroy(
+ nssCryptokiObject *object);
NSS_EXTERN PRBool
-nssCryptokiObject_Equal
-(
- nssCryptokiObject *object1,
- nssCryptokiObject *object2
-);
+nssCryptokiObject_Equal(
+ nssCryptokiObject *object1,
+ nssCryptokiObject *object2);
NSS_EXTERN nssCryptokiObject *
-nssCryptokiObject_Clone
-(
- nssCryptokiObject *object
-);
+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
-);
+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
-);
+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
-);
+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
-);
+nssCryptokiPrivateKey_SetCertificate(
+ nssCryptokiObject *keyObject,
+ nssSession *sessionOpt,
+ const NSSUTF8 *nickname,
+ NSSItem *id,
+ NSSDER *subject);
NSS_EXTERN void
-nssModuleArray_Destroy
-(
- NSSModule **modules
-);
+nssModuleArray_Destroy(
+ NSSModule **modules);
/* nssSlotArray
*
@@ -748,10 +595,8 @@ nssModuleArray_Destroy
*/
NSS_EXTERN void
-nssSlotArray_Destroy
-(
- NSSSlot **slots
-);
+nssSlotArray_Destroy(
+ NSSSlot **slots);
/* nssTokenArray
*
@@ -759,23 +604,19 @@ nssSlotArray_Destroy
*/
NSS_EXTERN void
-nssTokenArray_Destroy
-(
- NSSToken **tokens
-);
+nssTokenArray_Destroy(
+ NSSToken **tokens);
/* nssCryptokiObjectArray
*
* nssCryptokiObjectArray_Destroy
*/
NSS_EXTERN void
-nssCryptokiObjectArray_Destroy
-(
- nssCryptokiObject **object
-);
+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, ...?
*
@@ -794,30 +635,24 @@ nssCryptokiObjectArray_Destroy
/* nssSlotList_Create
*/
NSS_EXTERN nssSlotList *
-nssSlotList_Create
-(
- NSSArena *arenaOpt
-);
+nssSlotList_Create(
+ NSSArena *arenaOpt);
/* nssSlotList_Destroy
*/
NSS_EXTERN void
-nssSlotList_Destroy
-(
- nssSlotList *slotList
-);
+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_Add(
+ nssSlotList *slotList,
+ NSSSlot *slot,
+ PRUint32 order);
/* nssSlotList_AddModuleSlots
*
@@ -825,38 +660,30 @@ nssSlotList_Add
* equal weight).
*/
NSS_EXTERN PRStatus
-nssSlotList_AddModuleSlots
-(
- nssSlotList *slotList,
- NSSModule *module,
- PRUint32 order
-);
+nssSlotList_AddModuleSlots(
+ nssSlotList *slotList,
+ NSSModule *module,
+ PRUint32 order);
/* nssSlotList_GetSlots
*/
NSS_EXTERN NSSSlot **
-nssSlotList_GetSlots
-(
- nssSlotList *slotList
-);
+nssSlotList_GetSlots(
+ nssSlotList *slotList);
/* nssSlotList_FindSlotByName
*/
NSS_EXTERN NSSSlot *
-nssSlotList_FindSlotByName
-(
- nssSlotList *slotList,
- NSSUTF8 *slotName
-);
+nssSlotList_FindSlotByName(
+ nssSlotList *slotList,
+ NSSUTF8 *slotName);
/* nssSlotList_FindTokenByName
*/
NSS_EXTERN NSSToken *
-nssSlotList_FindTokenByName
-(
- nssSlotList *slotList,
- NSSUTF8 *tokenName
-);
+nssSlotList_FindTokenByName(
+ nssSlotList *slotList,
+ NSSUTF8 *tokenName);
/* nssSlotList_GetBestSlot
*
@@ -864,74 +691,56 @@ nssSlotList_FindTokenByName
* list.
*/
NSS_EXTERN NSSSlot *
-nssSlotList_GetBestSlot
-(
- nssSlotList *slotList
-);
+nssSlotList_GetBestSlot(
+ nssSlotList *slotList);
/* nssSlotList_GetBestSlotForAlgorithmAndParameters
*
* Highest-ranking slot than can handle algorithm/parameters.
*/
NSS_EXTERN NSSSlot *
-nssSlotList_GetBestSlotForAlgorithmAndParameters
-(
- nssSlotList *slotList,
- NSSAlgorithmAndParameters *ap
-);
+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
-);
+nssSlotList_GetBestSlotForAlgorithmsAndParameters(
+ nssSlotList *slotList,
+ NSSAlgorithmAndParameters **ap);
NSS_EXTERN PRBool
-nssToken_IsPresent
-(
- NSSToken *token
-);
+nssToken_IsPresent(
+ NSSToken *token);
NSS_EXTERN nssSession *
-nssToken_GetDefaultSession
-(
- NSSToken *token
-);
+nssToken_GetDefaultSession(
+ NSSToken *token);
NSS_EXTERN PRStatus
-nssToken_GetTrustOrder
-(
- NSSToken *tok
-);
+nssToken_GetTrustOrder(
+ NSSToken *tok);
NSS_EXTERN PRStatus
-nssToken_NotifyCertsNotVisible
-(
- NSSToken *tok
-);
+nssToken_NotifyCertsNotVisible(
+ NSSToken *tok);
NSS_EXTERN PRStatus
-nssToken_TraverseCertificates
-(
- NSSToken *token,
- nssSession *sessionOpt,
- nssTokenSearchType searchType,
- PRStatus (* callback)(nssCryptokiObject *instance, void *arg),
- void *arg
-);
+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
-);
+nssToken_IsPrivateKeyAvailable(
+ NSSToken *token,
+ NSSCertificate *c,
+ nssCryptokiObject *instance);
PR_END_EXTERN_C
diff --git a/nss/lib/dev/devm.h b/nss/lib/dev/devm.h
index 6485ae2..16acf64 100644
--- a/nss/lib/dev/devm.h
+++ b/nss/lib/dev/devm.h
@@ -24,181 +24,133 @@ PR_BEGIN_EXTERN_C
((CK_FUNCTION_LIST_PTR)(epv))
NSS_EXTERN void
-nssDevice_AddRef
-(
- struct nssDeviceBaseStr *device
-);
+nssDevice_AddRef(
+ struct nssDeviceBaseStr *device);
NSS_EXTERN PRBool
-nssDevice_Destroy
-(
- struct nssDeviceBaseStr *device
-);
+nssDevice_Destroy(
+ struct nssDeviceBaseStr *device);
NSS_EXTERN PRBool
-nssModule_IsThreadSafe
-(
- NSSModule *module
-);
+nssModule_IsThreadSafe(
+ NSSModule *module);
NSS_EXTERN PRBool
-nssModule_IsInternal
-(
- NSSModule *mod
-);
+nssModule_IsInternal(
+ NSSModule *mod);
NSS_EXTERN PRBool
-nssModule_IsModuleDBOnly
-(
- NSSModule *mod
-);
+nssModule_IsModuleDBOnly(
+ NSSModule *mod);
NSS_EXTERN void *
-nssModule_GetCryptokiEPV
-(
- NSSModule *mod
-);
+nssModule_GetCryptokiEPV(
+ NSSModule *mod);
NSS_EXTERN NSSSlot *
-nssSlot_Create
-(
- CK_SLOT_ID slotId,
- NSSModule *parent
-);
+nssSlot_Create(
+ CK_SLOT_ID slotId,
+ NSSModule *parent);
NSS_EXTERN void *
-nssSlot_GetCryptokiEPV
-(
- NSSSlot *slot
-);
+nssSlot_GetCryptokiEPV(
+ NSSSlot *slot);
NSS_EXTERN NSSToken *
-nssToken_Create
-(
- CK_SLOT_ID slotID,
- NSSSlot *peer
-);
+nssToken_Create(
+ CK_SLOT_ID slotID,
+ NSSSlot *peer);
NSS_EXTERN void *
-nssToken_GetCryptokiEPV
-(
- NSSToken *token
-);
+nssToken_GetCryptokiEPV(
+ NSSToken *token);
NSS_EXTERN nssSession *
-nssToken_GetDefaultSession
-(
- NSSToken *token
-);
+nssToken_GetDefaultSession(
+ NSSToken *token);
NSS_EXTERN PRBool
-nssToken_IsLoginRequired
-(
- NSSToken *token
-);
+nssToken_IsLoginRequired(
+ NSSToken *token);
NSS_EXTERN void
-nssToken_Remove
-(
- NSSToken *token
-);
+nssToken_Remove(
+ NSSToken *token);
NSS_EXTERN nssCryptokiObject *
-nssCryptokiObject_Create
-(
- NSSToken *t,
- nssSession *session,
- CK_OBJECT_HANDLE h
-);
+nssCryptokiObject_Create(
+ NSSToken *t,
+ nssSession *session,
+ CK_OBJECT_HANDLE h);
NSS_EXTERN nssTokenObjectCache *
-nssTokenObjectCache_Create
-(
- NSSToken *token,
- PRBool cacheCerts,
- PRBool cacheTrust,
- PRBool cacheCRLs
-);
+nssTokenObjectCache_Create(
+ NSSToken *token,
+ PRBool cacheCerts,
+ PRBool cacheTrust,
+ PRBool cacheCRLs);
NSS_EXTERN void
-nssTokenObjectCache_Destroy
-(
- nssTokenObjectCache *cache
-);
+nssTokenObjectCache_Destroy(
+ nssTokenObjectCache *cache);
NSS_EXTERN void
-nssTokenObjectCache_Clear
-(
- nssTokenObjectCache *cache
-);
+nssTokenObjectCache_Clear(
+ nssTokenObjectCache *cache);
NSS_EXTERN PRBool
-nssTokenObjectCache_HaveObjectClass
-(
- nssTokenObjectCache *cache,
- CK_OBJECT_CLASS objclass
-);
+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
-);
+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
-);
+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
-);
+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
-);
+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
-);
+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
-);
+nssPKCS11String_Length(
+ CK_CHAR *pkcs11str,
+ PRUint32 bufLen);
PR_END_EXTERN_C
diff --git a/nss/lib/dev/devslot.c b/nss/lib/dev/devslot.c
index f49915e..5b0bb37 100644
--- a/nss/lib/dev/devslot.c
+++ b/nss/lib/dev/devslot.c
@@ -20,21 +20,20 @@
/* this should track global and per-transaction login information */
#define NSSSLOT_IS_FRIENDLY(slot) \
- (slot->base.flags & NSSSLOT_FLAGS_FRIENDLY)
+ (slot->base.flags & NSSSLOT_FLAGS_FRIENDLY)
/* measured as interval */
static PRIntervalTime s_token_delay_time = 0;
NSS_IMPLEMENT PRStatus
-nssSlot_Destroy (
- NSSSlot *slot
-)
+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);
- }
+ if (PR_ATOMIC_DECREMENT(&slot->base.refCount) == 0) {
+ PZ_DestroyLock(slot->base.lock);
+ return nssArena_Destroy(slot->base.arena);
+ }
}
return PR_SUCCESS;
}
@@ -43,7 +42,7 @@ void
nssSlot_EnterMonitor(NSSSlot *slot)
{
if (slot->lock) {
- PZ_Lock(slot->lock);
+ PZ_Lock(slot->lock);
}
}
@@ -51,47 +50,42 @@ void
nssSlot_ExitMonitor(NSSSlot *slot)
{
if (slot->lock) {
- PZ_Unlock(slot->lock);
+ PZ_Unlock(slot->lock);
}
}
NSS_IMPLEMENT void
-NSSSlot_Destroy (
- NSSSlot *slot
-)
+NSSSlot_Destroy(
+ NSSSlot *slot)
{
(void)nssSlot_Destroy(slot);
}
NSS_IMPLEMENT NSSSlot *
-nssSlot_AddRef (
- NSSSlot *slot
-)
+nssSlot_AddRef(
+ NSSSlot *slot)
{
PR_ATOMIC_INCREMENT(&slot->base.refCount);
return slot;
}
NSS_IMPLEMENT NSSUTF8 *
-nssSlot_GetName (
- NSSSlot *slot
-)
+nssSlot_GetName(
+ NSSSlot *slot)
{
return slot->base.name;
}
NSS_IMPLEMENT NSSUTF8 *
-nssSlot_GetTokenName (
- NSSSlot *slot
-)
+nssSlot_GetTokenName(
+ NSSSlot *slot)
{
return nssToken_GetName(slot->token);
}
NSS_IMPLEMENT void
-nssSlot_ResetDelay (
- NSSSlot *slot
-)
+nssSlot_ResetDelay(
+ NSSSlot *slot)
{
slot->lastTokenPing = 0;
}
@@ -102,21 +96,20 @@ 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);
+ 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;
+ return PR_TRUE;
}
slot->lastTokenPing = time;
return PR_FALSE;
}
NSS_IMPLEMENT PRBool
-nssSlot_IsTokenPresent (
- NSSSlot *slot
-)
+nssSlot_IsTokenPresent(
+ NSSSlot *slot)
{
CK_RV ckrv;
PRStatus nssrv;
@@ -126,75 +119,77 @@ nssSlot_IsTokenPresent (
void *epv;
/* permanent slots are always present unless they're disabled */
if (nssSlot_IsPermanent(slot)) {
- return !PK11_IsDisabled(slot->pk11slot);
+ 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);
+ return ((slot->ckFlags & CKF_TOKEN_PRESENT) != 0);
}
/* First obtain the slot info */
epv = slot->epv;
if (!epv) {
- return PR_FALSE;
+ 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->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;
+ 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;
- }
+ 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
@@ -212,46 +207,41 @@ nssSlot_IsTokenPresent (
}
NSS_IMPLEMENT void *
-nssSlot_GetCryptokiEPV (
- NSSSlot *slot
-)
+nssSlot_GetCryptokiEPV(
+ NSSSlot *slot)
{
return slot->epv;
}
NSS_IMPLEMENT NSSToken *
-nssSlot_GetToken (
- NSSSlot *slot
-)
+nssSlot_GetToken(
+ NSSSlot *slot)
{
if (nssSlot_IsTokenPresent(slot)) {
- return nssToken_AddRef(slot->token);
+ return nssToken_AddRef(slot->token);
}
return (NSSToken *)NULL;
}
NSS_IMPLEMENT PRStatus
-nssSession_EnterMonitor (
- nssSession *s
-)
+nssSession_EnterMonitor(
+ nssSession *s)
{
- if (s->lock) PZ_Lock(s->lock);
+ if (s->lock)
+ PZ_Lock(s->lock);
return PR_SUCCESS;
}
NSS_IMPLEMENT PRStatus
-nssSession_ExitMonitor (
- nssSession *s
-)
+nssSession_ExitMonitor(
+ nssSession *s)
{
return (s->lock) ? PZ_Unlock(s->lock) : PR_SUCCESS;
}
NSS_EXTERN PRBool
-nssSession_IsReadWrite (
- nssSession *s
-)
+nssSession_IsReadWrite(
+ nssSession *s)
{
return s->isRW;
}
-
diff --git a/nss/lib/dev/devt.h b/nss/lib/dev/devt.h
index c678114..db93deb 100644
--- a/nss/lib/dev/devt.h
+++ b/nss/lib/dev/devt.h
@@ -34,22 +34,20 @@ 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;
+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 NSSTokenStr {
struct nssDeviceBaseStr base;
- NSSSlot *slot; /* Parent (or peer, if you will) */
+ NSSSlot *slot; /* Parent (or peer, if you will) */
CK_FLAGS ckFlags; /* from CK_TOKEN_INFO.flags */
PRUint32 flags;
void *epv;
@@ -61,40 +59,36 @@ struct NSSTokenStr
};
typedef enum {
- nssSlotAskPasswordTimes_FirstTime = 0,
- nssSlotAskPasswordTimes_EveryTime = 1,
- nssSlotAskPasswordTimes_Timeout = 2
-}
-nssSlotAskPasswordTimes;
-
-struct nssSlotAuthInfoStr
-{
- PRTime lastLogin;
- nssSlotAskPasswordTimes askTimes;
- PRIntervalTime askPasswordTimeout;
+ 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 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;
+struct nssSessionStr {
+ PZLock *lock;
+ CK_SESSION_HANDLE handle;
+ NSSSlot *slot;
+ PRBool isRW;
+ PRBool ownLock;
};
typedef enum {
@@ -113,8 +107,7 @@ typedef enum {
typedef struct nssCryptokiInstanceStr nssCryptokiInstance;
-struct nssCryptokiInstanceStr
-{
+struct nssCryptokiInstanceStr {
CK_OBJECT_HANDLE handle;
NSSToken *token;
PRBool isTokenObject;
@@ -132,22 +125,20 @@ typedef enum {
nssTokenSearchType_TokenForced = 3
} nssTokenSearchType;
-struct nssTokenCertSearchStr
-{
+struct nssTokenCertSearchStr {
nssTokenSearchType searchType;
- PRStatus (* callback)(NSSCertificate *c, void *arg);
+ PRStatus (*callback)(NSSCertificate *c, void *arg);
void *cbarg;
nssList *cached;
- /* TODO: add a cache query callback if the list would be large
- * (traversal)
+ /* TODO: add a cache query callback if the list would be large
+ * (traversal)
*/
};
struct nssSlotListStr;
typedef struct nssSlotListStr nssSlotList;
-struct NSSAlgorithmAndParametersStr
-{
+struct NSSAlgorithmAndParametersStr {
CK_MECHANISM mechanism;
};
diff --git a/nss/lib/dev/devtm.h b/nss/lib/dev/devtm.h
index f55c45b..ef3c4c0 100644
--- a/nss/lib/dev/devtm.h
+++ b/nss/lib/dev/devtm.h
@@ -8,7 +8,7 @@
/*
* devtm.h
*
- * This file contains module-private definitions for the low-level
+ * This file contains module-private definitions for the low-level
* cryptoki devices.
*/
diff --git a/nss/lib/dev/devtoken.c b/nss/lib/dev/devtoken.c
index 7223e48..0adbca8 100644
--- a/nss/lib/dev/devtoken.c
+++ b/nss/lib/dev/devtoken.c
@@ -24,115 +24,103 @@ extern const NSSError NSS_ERROR_PKCS11;
#define OBJECT_STACK_SIZE 16
NSS_IMPLEMENT PRStatus
-nssToken_Destroy (
- NSSToken *tok
-)
+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);
- }
+ 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
-)
+nssToken_Remove(
+ NSSToken *tok)
{
nssTokenObjectCache_Clear(tok->cache);
}
NSS_IMPLEMENT void
-NSSToken_Destroy (
- NSSToken *tok
-)
+NSSToken_Destroy(
+ NSSToken *tok)
{
(void)nssToken_Destroy(tok);
}
NSS_IMPLEMENT NSSToken *
-nssToken_AddRef (
- NSSToken *tok
-)
+nssToken_AddRef(
+ NSSToken *tok)
{
PR_ATOMIC_INCREMENT(&tok->base.refCount);
return tok;
}
NSS_IMPLEMENT NSSSlot *
-nssToken_GetSlot (
- NSSToken *tok
-)
+nssToken_GetSlot(
+ NSSToken *tok)
{
return nssSlot_AddRef(tok->slot);
}
NSS_IMPLEMENT void *
-nssToken_GetCryptokiEPV (
- NSSToken *token
-)
+nssToken_GetCryptokiEPV(
+ NSSToken *token)
{
return nssSlot_GetCryptokiEPV(token->slot);
}
NSS_IMPLEMENT nssSession *
-nssToken_GetDefaultSession (
- NSSToken *token
-)
+nssToken_GetDefaultSession(
+ NSSToken *token)
{
return token->defaultSession;
}
NSS_IMPLEMENT NSSUTF8 *
-nssToken_GetName (
- NSSToken *tok
-)
+nssToken_GetName(
+ NSSToken *tok)
{
if (tok == NULL) {
- return "";
+ return "";
}
if (tok->base.name[0] == 0) {
- (void) nssSlot_IsTokenPresent(tok->slot);
- }
+ (void)nssSlot_IsTokenPresent(tok->slot);
+ }
return tok->base.name;
}
NSS_IMPLEMENT NSSUTF8 *
-NSSToken_GetName (
- NSSToken *token
-)
+NSSToken_GetName(
+ NSSToken *token)
{
return nssToken_GetName(token);
}
NSS_IMPLEMENT PRBool
-nssToken_IsLoginRequired (
- NSSToken *token
-)
+nssToken_IsLoginRequired(
+ NSSToken *token)
{
return (token->ckFlags & CKF_LOGIN_REQUIRED);
}
NSS_IMPLEMENT PRBool
-nssToken_NeedsPINInitialization (
- NSSToken *token
-)
+nssToken_NeedsPINInitialization(
+ NSSToken *token)
{
return (!(token->ckFlags & CKF_USER_PIN_INITIALIZED));
}
NSS_IMPLEMENT PRStatus
-nssToken_DeleteStoredObject (
- nssCryptokiObject *instance
-)
+nssToken_DeleteStoredObject(
+ nssCryptokiObject *instance)
{
CK_RV ckrv;
PRStatus status;
@@ -141,43 +129,42 @@ nssToken_DeleteStoredObject (
nssSession *session = NULL;
void *epv = nssToken_GetCryptokiEPV(instance->token);
if (token->cache) {
- nssTokenObjectCache_RemoveObject(token->cache, instance);
+ 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 (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;
+ return PR_FAILURE;
}
nssSession_EnterMonitor(session);
ckrv = CKAPI(epv)->C_DestroyObject(session->handle, instance->handle);
nssSession_ExitMonitor(session);
if (createdSession) {
- nssSession_Destroy(session);
+ 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);
+ 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
-)
+import_object(
+ NSSToken *tok,
+ nssSession *sessionOpt,
+ CK_ATTRIBUTE_PTR objectTemplate,
+ CK_ULONG otsize)
{
nssSession *session = NULL;
PRBool createdSession = PR_FALSE;
@@ -186,79 +173,77 @@ import_object (
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;
- }
+ 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;
+ session = (sessionOpt) ? sessionOpt : tok->defaultSession;
}
if (session == NULL) {
- nss_SetError(NSS_ERROR_INVALID_ARGUMENT);
- return NULL;
+ nss_SetError(NSS_ERROR_INVALID_ARGUMENT);
+ return NULL;
}
nssSession_EnterMonitor(session);
- ckrv = CKAPI(epv)->C_CreateObject(session->handle,
+ ckrv = CKAPI(epv)->C_CreateObject(session->handle,
objectTemplate, otsize,
&handle);
nssSession_ExitMonitor(session);
if (ckrv == CKR_OK) {
- object = nssCryptokiObject_Create(tok, session, handle);
+ object = nssCryptokiObject_Create(tok, session, handle);
} else {
- nss_SetError(ckrv);
- nss_SetError(NSS_ERROR_PKCS11);
+ nss_SetError(ckrv);
+ nss_SetError(NSS_ERROR_PKCS11);
}
if (createdSession) {
- nssSession_Destroy(session);
+ nssSession_Destroy(session);
}
return object;
}
static nssCryptokiObject **
-create_objects_from_handles (
- NSSToken *tok,
- nssSession *session,
- CK_OBJECT_HANDLE *handles,
- PRUint32 numH
-)
+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;
- }
- }
+ 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
-)
+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;
@@ -271,166 +256,169 @@ find_objects (
/* 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;
+ ckrv = CKR_SESSION_HANDLE_INVALID;
+ goto loser;
}
/* the arena is only for the array of object handles */
if (maximumOpt > 0) {
- arraySize = maximumOpt;
+ arraySize = maximumOpt;
} else {
- arraySize = OBJECT_STACK_SIZE;
+ arraySize = OBJECT_STACK_SIZE;
}
numHandles = 0;
if (arraySize <= OBJECT_STACK_SIZE) {
- objectHandles = staticObjects;
+ objectHandles = staticObjects;
} else {
- objectHandles = nss_ZNEWARRAY(NULL, CK_OBJECT_HANDLE, arraySize);
+ objectHandles = nss_ZNEWARRAY(NULL, CK_OBJECT_HANDLE, arraySize);
}
if (!objectHandles) {
- ckrv = CKR_HOST_MEMORY;
- goto loser;
+ ckrv = CKR_HOST_MEMORY;
+ goto loser;
}
nssSession_EnterMonitor(session); /* ==== session lock === */
/* Initialize the find with the template */
- ckrv = CKAPI(epv)->C_FindObjectsInit(session->handle,
+ ckrv = CKAPI(epv)->C_FindObjectsInit(session->handle,
obj_template, otsize);
if (ckrv != CKR_OK) {
- nssSession_ExitMonitor(session);
- goto loser;
+ 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;
- }
+ /* 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;
+ goto loser;
}
if (numHandles > 0) {
- objects = create_objects_from_handles(tok, session,
- objectHandles, numHandles);
+ objects = create_objects_from_handles(tok, session,
+ objectHandles, numHandles);
} else {
- nss_SetError(NSS_ERROR_NOT_FOUND);
- objects = NULL;
+ nss_SetError(NSS_ERROR_NOT_FOUND);
+ objects = NULL;
}
if (objectHandles && objectHandles != staticObjects) {
- nss_ZFreeIf(objectHandles);
+ nss_ZFreeIf(objectHandles);
}
- if (statusOpt) *statusOpt = PR_SUCCESS;
+ if (statusOpt)
+ *statusOpt = PR_SUCCESS;
return objects;
loser:
if (objectHandles && objectHandles != staticObjects) {
- nss_ZFreeIf(objectHandles);
+ 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;
+ (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;
+ 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
-)
+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;
+ 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;
- }
+ 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;
+ 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;
- }
+ 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,
+ objects = find_objects(token, sessionOpt,
+ obj_template, otsize,
maximumOpt, statusOpt);
return objects;
}
@@ -438,19 +426,18 @@ find_objects_by_template (
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
-)
+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;
@@ -461,32 +448,32 @@ nssToken_ImportCertificate (
nssCryptokiObject *rvObject = NULL;
if (!tok) {
- PORT_SetError(SEC_ERROR_NO_TOKEN);
- return NULL;
+ PORT_SetError(SEC_ERROR_NO_TOKEN);
+ return NULL;
}
if (certType == NSSCertificateType_PKIX) {
- cert_type = CKC_X_509;
+ cert_type = CKC_X_509;
} else {
- return (nssCryptokiObject *)NULL;
+ 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;
+ 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);
+ 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_SET_ATTRIBUTE_UTF8(attr, CKA_NSS_EMAIL, email);
}
NSS_CK_TEMPLATE_FINISH(cert_tmpl, attr, ctsize);
/* see if the cert is already there */
@@ -497,67 +484,67 @@ nssToken_ImportCertificate (
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);
+ 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);
+ /* 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);
+ /* The cache will overwrite the attributes if the object already
+ * exists.
+ */
+ nssTokenObjectCache_ImportObject(tok->cache, rvObject,
+ CKO_CERTIFICATE,
+ cert_tmpl, ctsize);
}
return rvObject;
}
@@ -566,14 +553,13 @@ nssToken_ImportCertificate (
* 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
-)
+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];
@@ -582,35 +568,34 @@ nssToken_FindObjects (
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);
+ 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_TOKEN, &g_ck_true);
}
- NSS_CK_SET_ATTRIBUTE_VAR( attr, CKA_CLASS, objclass);
+ 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);
+ 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);
+ 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
-)
+nssToken_FindCertificatesBySubject(
+ NSSToken *token,
+ nssSession *sessionOpt,
+ NSSDER *subject,
+ nssTokenSearchType searchType,
+ PRUint32 maximumOpt,
+ PRStatus *statusOpt)
{
CK_ATTRIBUTE_PTR attr;
CK_ATTRIBUTE subj_template[3];
@@ -619,9 +604,9 @@ nssToken_FindCertificatesBySubject (
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);
+ 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_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);
@@ -634,14 +619,13 @@ nssToken_FindCertificatesBySubject (
}
NSS_IMPLEMENT nssCryptokiObject **
-nssToken_FindCertificatesByNickname (
- NSSToken *token,
- nssSession *sessionOpt,
- const NSSUTF8 *name,
- nssTokenSearchType searchType,
- PRUint32 maximumOpt,
- PRStatus *statusOpt
-)
+nssToken_FindCertificatesByNickname(
+ NSSToken *token,
+ nssSession *sessionOpt,
+ const NSSUTF8 *name,
+ nssTokenSearchType searchType,
+ PRUint32 maximumOpt,
+ PRStatus *statusOpt)
{
CK_ATTRIBUTE_PTR attr;
CK_ATTRIBUTE nick_template[3];
@@ -651,27 +635,27 @@ nssToken_FindCertificatesByNickname (
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);
+ 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_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,
+ 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);
+ /* 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;
}
@@ -683,14 +667,13 @@ nssToken_FindCertificatesByNickname (
* 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
-)
+nssToken_FindCertificatesByEmail(
+ NSSToken *token,
+ nssSession *sessionOpt,
+ NSSASCII7 *email,
+ nssTokenSearchType searchType,
+ PRUint32 maximumOpt,
+ PRStatus *statusOpt)
{
CK_ATTRIBUTE_PTR attr;
CK_ATTRIBUTE email_template[3];
@@ -700,9 +683,9 @@ nssToken_FindCertificatesByEmail (
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);
+ 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_TOKEN, &g_ck_true);
}
NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_CLASS, &g_ck_class_cert);
NSS_CK_TEMPLATE_FINISH(email_template, attr, etsize);
@@ -711,29 +694,28 @@ nssToken_FindCertificatesByEmail (
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);
+ /* 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
-)
+nssToken_FindCertificatesByID(
+ NSSToken *token,
+ nssSession *sessionOpt,
+ NSSItem *id,
+ nssTokenSearchType searchType,
+ PRUint32 maximumOpt,
+ PRStatus *statusOpt)
{
CK_ATTRIBUTE_PTR attr;
CK_ATTRIBUTE id_template[3];
@@ -743,9 +725,9 @@ nssToken_FindCertificatesByID (
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);
+ 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_TOKEN, &g_ck_true);
}
NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_CLASS, &g_ck_class_cert);
NSS_CK_TEMPLATE_FINISH(id_template, attr, idtsize);
@@ -767,46 +749,45 @@ nssToken_decodeSerialItem(NSSItem *serial, NSSItem *serialDecode)
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;
- }
+ /* 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
-)
+nssToken_FindCertificateByIssuerAndSerialNumber(
+ NSSToken *token,
+ nssSession *sessionOpt,
+ NSSDER *issuer,
+ NSSDER *serial,
+ nssTokenSearchType searchType,
+ PRStatus *statusOpt)
{
CK_ATTRIBUTE_PTR attr;
CK_ATTRIBUTE_PTR serialAttr;
@@ -817,37 +798,37 @@ nssToken_FindCertificateByIssuerAndSerialNumber (
NSS_CK_TEMPLATE_START(cert_template, attr, ctsize);
if (!token) {
- PORT_SetError(SEC_ERROR_NO_TOKEN);
- if (statusOpt)
- *statusOpt = PR_FAILURE;
- return NULL;
+ 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);
+ 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_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);
+ 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_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);
+ objects = find_objects(token, sessionOpt,
+ cert_template, ctsize,
+ 1, statusOpt);
} else {
- objects = find_objects_by_template(token, sessionOpt,
- cert_template, ctsize,
- 1, statusOpt);
+ objects = find_objects_by_template(token, sessionOpt,
+ cert_template, ctsize,
+ 1, statusOpt);
}
if (objects) {
- rvObject = objects[0];
- nss_ZFreeIf(objects);
+ rvObject = objects[0];
+ nss_ZFreeIf(objects);
}
/*
@@ -855,39 +836,38 @@ nssToken_FindCertificateByIssuerAndSerialNumber (
* 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);
- }
+ 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
-)
+nssToken_FindCertificateByEncodedCertificate(
+ NSSToken *token,
+ nssSession *sessionOpt,
+ NSSBER *encodedCertificate,
+ nssTokenSearchType searchType,
+ PRStatus *statusOpt)
{
CK_ATTRIBUTE_PTR attr;
CK_ATTRIBUTE cert_template[3];
@@ -897,9 +877,9 @@ nssToken_FindCertificateByEncodedCertificate (
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);
+ 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_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);
@@ -909,20 +889,19 @@ nssToken_FindCertificateByEncodedCertificate (
cert_template, ctsize,
1, statusOpt);
if (objects) {
- rvObject = objects[0];
- nss_ZFreeIf(objects);
+ rvObject = objects[0];
+ nss_ZFreeIf(objects);
}
return rvObject;
}
NSS_IMPLEMENT nssCryptokiObject **
-nssToken_FindPrivateKeys (
- NSSToken *token,
- nssSession *sessionOpt,
- nssTokenSearchType searchType,
- PRUint32 maximumOpt,
- PRStatus *statusOpt
-)
+nssToken_FindPrivateKeys(
+ NSSToken *token,
+ nssSession *sessionOpt,
+ nssTokenSearchType searchType,
+ PRUint32 maximumOpt,
+ PRStatus *statusOpt)
{
CK_ATTRIBUTE_PTR attr;
CK_ATTRIBUTE key_template[2];
@@ -932,25 +911,24 @@ nssToken_FindPrivateKeys (
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);
+ 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_TOKEN, &g_ck_true);
}
NSS_CK_TEMPLATE_FINISH(key_template, attr, ktsize);
objects = find_objects_by_template(token, sessionOpt,
- key_template, ktsize,
+ 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
-)
+nssToken_FindPrivateKeyByID(
+ NSSToken *token,
+ nssSession *sessionOpt,
+ NSSItem *keyID)
{
CK_ATTRIBUTE_PTR attr;
CK_ATTRIBUTE key_template[3];
@@ -965,22 +943,21 @@ nssToken_FindPrivateKeyByID (
NSS_CK_TEMPLATE_FINISH(key_template, attr, ktsize);
objects = find_objects_by_template(token, sessionOpt,
- key_template, ktsize,
+ key_template, ktsize,
1, NULL);
if (objects) {
- rvKey = objects[0];
- nss_ZFreeIf(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
-)
+nssToken_FindPublicKeyByID(
+ NSSToken *token,
+ nssSession *sessionOpt,
+ NSSItem *keyID)
{
CK_ATTRIBUTE_PTR attr;
CK_ATTRIBUTE key_template[3];
@@ -995,11 +972,11 @@ nssToken_FindPublicKeyByID (
NSS_CK_TEMPLATE_FINISH(key_template, attr, ktsize);
objects = find_objects_by_template(token, sessionOpt,
- key_template, ktsize,
+ key_template, ktsize,
1, NULL);
if (objects) {
- rvKey = objects[0];
- nss_ZFreeIf(objects);
+ rvKey = objects[0];
+ nss_ZFreeIf(objects);
}
return rvKey;
}
@@ -1029,38 +1006,47 @@ md5_hash(NSSItem *input, NSSItem *output)
}
static CK_TRUST
-get_ck_trust (
- nssTrustLevel nssTrust
-)
+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;
+ 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
-)
+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;
@@ -1071,8 +1057,10 @@ nssToken_ImportTrust (
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_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);
@@ -1081,46 +1069,45 @@ nssToken_ImportTrust (
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);
+ 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_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_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);
+ 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_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);
+ 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_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);
+ 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
-)
+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;
@@ -1131,38 +1118,37 @@ nssToken_FindTrustForCertificate (
/* 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;
+ 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_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_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);
+ 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
-)
+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;
@@ -1172,39 +1158,38 @@ nssToken_ImportCRL (
NSS_CK_TEMPLATE_START(crl_tmpl, attr, crlsize);
if (asTokenObject) {
- NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_TOKEN, &g_ck_true);
+ 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_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_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);
+ 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_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);
+ 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
-)
+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;
@@ -1215,18 +1200,18 @@ nssToken_FindCRLsBySubject (
/* 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;
+ 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);
+ 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_TOKEN, &g_ck_true);
}
- NSS_CK_SET_ATTRIBUTE_VAR( attr, CKA_CLASS, crlobjc);
+ 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);
@@ -1237,17 +1222,16 @@ nssToken_FindCRLsBySubject (
}
NSS_IMPLEMENT PRStatus
-nssToken_GetCachedObjectAttributes (
- NSSToken *token,
- NSSArena *arenaOpt,
- nssCryptokiObject *object,
- CK_OBJECT_CLASS objclass,
- CK_ATTRIBUTE_PTR atemplate,
- CK_ULONG atlen
-)
+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 PR_FAILURE;
}
return nssTokenObjectCache_GetObjectAttributes(token->cache, arenaOpt,
object, objclass,
@@ -1255,14 +1239,13 @@ nssToken_GetCachedObjectAttributes (
}
NSS_IMPLEMENT NSSItem *
-nssToken_Digest (
- NSSToken *tok,
- nssSession *sessionOpt,
- NSSAlgorithmAndParameters *ap,
- NSSItem *data,
- NSSItem *rvOpt,
- NSSArena *arenaOpt
-)
+nssToken_Digest(
+ NSSToken *tok,
+ nssSession *sessionOpt,
+ NSSAlgorithmAndParameters *ap,
+ NSSItem *data,
+ NSSItem *rvOpt,
+ NSSArena *arenaOpt)
{
CK_RV ckrv;
CK_ULONG digestLen;
@@ -1273,15 +1256,15 @@ nssToken_Digest (
/* 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;
+ 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;
+ nssSession_ExitMonitor(session);
+ return NULL;
}
#if 0
/* XXX the standard says this should work, but it doesn't */
@@ -1294,45 +1277,44 @@ nssToken_Digest (
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 (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,
+ 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;
+ nss_ZFreeIf(digest);
+ return NULL;
}
if (!rvOpt) {
- rvItem = nssItem_Create(arenaOpt, NULL, digestLen, (void *)digest);
+ rvItem = nssItem_Create(arenaOpt, NULL, digestLen, (void *)digest);
}
return rvItem;
}
NSS_IMPLEMENT PRStatus
-nssToken_BeginDigest (
- NSSToken *tok,
- nssSession *sessionOpt,
- NSSAlgorithmAndParameters *ap
-)
+nssToken_BeginDigest(
+ NSSToken *tok,
+ nssSession *sessionOpt,
+ NSSAlgorithmAndParameters *ap)
{
CK_RV ckrv;
void *epv = nssToken_GetCryptokiEPV(tok);
@@ -1340,8 +1322,8 @@ nssToken_BeginDigest (
/* 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;
+ PORT_SetError(SEC_ERROR_NO_TOKEN);
+ return PR_FAILURE;
}
nssSession_EnterMonitor(session);
@@ -1351,11 +1333,10 @@ nssToken_BeginDigest (
}
NSS_IMPLEMENT PRStatus
-nssToken_ContinueDigest (
- NSSToken *tok,
- nssSession *sessionOpt,
- NSSItem *item
-)
+nssToken_ContinueDigest(
+ NSSToken *tok,
+ nssSession *sessionOpt,
+ NSSItem *item)
{
CK_RV ckrv;
void *epv = nssToken_GetCryptokiEPV(tok);
@@ -1363,25 +1344,24 @@ nssToken_ContinueDigest (
/* 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;
+ PORT_SetError(SEC_ERROR_NO_TOKEN);
+ return PR_FAILURE;
}
nssSession_EnterMonitor(session);
- ckrv = CKAPI(epv)->C_DigestUpdate(session->handle,
- (CK_BYTE_PTR)item->data,
+ 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
-)
+nssToken_FinishDigest(
+ NSSToken *tok,
+ nssSession *sessionOpt,
+ NSSItem *rvOpt,
+ NSSArena *arenaOpt)
{
CK_RV ckrv;
CK_ULONG digestLen;
@@ -1392,72 +1372,70 @@ nssToken_FinishDigest (
/* 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;
+ 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;
+ 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 (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;
- }
+ 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;
+ nss_ZFreeIf(digest);
+ return NULL;
}
if (!rvOpt) {
- rvItem = nssItem_Create(arenaOpt, NULL, digestLen, (void *)digest);
+ rvItem = nssItem_Create(arenaOpt, NULL, digestLen, (void *)digest);
}
return rvItem;
}
NSS_IMPLEMENT PRBool
-nssToken_IsPresent (
- NSSToken *token
-)
+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
+ * 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
+ * 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
-)
+nssToken_TraverseCertificates(
+ NSSToken *token,
+ nssSession *sessionOpt,
+ nssTokenSearchType searchType,
+ PRStatus (*callback)(nssCryptokiObject *instance, void *arg),
+ void *arg)
{
CK_RV ckrv;
CK_ULONG count;
@@ -1473,17 +1451,17 @@ nssToken_TraverseCertificates (
/* 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;
+ 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);
+ 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_TOKEN, &g_ck_true);
}
NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_CLASS, &g_ck_class_cert);
NSS_CK_TEMPLATE_FINISH(cert_template, attr, ctsize);
@@ -1491,62 +1469,62 @@ nssToken_TraverseCertificates (
/* the arena is only for the array of object handles */
arena = nssArena_Create();
if (!arena) {
- return PR_FAILURE;
+ return PR_FAILURE;
}
arraySize = OBJECT_STACK_SIZE;
numHandles = 0;
objectHandles = nss_ZNEWARRAY(arena, CK_OBJECT_HANDLE, arraySize);
if (!objectHandles) {
- goto loser;
+ goto loser;
}
nssSession_EnterMonitor(session); /* ==== session lock === */
/* Initialize the find with the template */
- ckrv = CKAPI(epv)->C_FindObjectsInit(session->handle,
+ ckrv = CKAPI(epv)->C_FindObjectsInit(session->handle,
cert_template, ctsize);
if (ckrv != CKR_OK) {
- nssSession_ExitMonitor(session);
- goto loser;
+ 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;
- }
+ /* 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;
+ goto loser;
}
if (numHandles > 0) {
- objects = create_objects_from_handles(token, session,
- objectHandles, numHandles);
- if (objects) {
- nssCryptokiObject **op;
- for (op = objects; *op; op++) {
- (void)(*callback)(*op, arg);
- }
- nss_ZFreeIf(objects);
- }
+ objects = create_objects_from_handles(token, session,
+ objectHandles, numHandles);
+ if (objects) {
+ nssCryptokiObject **op;
+ for (op = objects; *op; op++) {
+ (void)(*callback)(*op, arg);
+ }
+ nss_ZFreeIf(objects);
+ }
}
nssArena_Destroy(arena);
return PR_SUCCESS;
@@ -1556,24 +1534,25 @@ loser:
}
NSS_IMPLEMENT PRBool
-nssToken_IsPrivateKeyAvailable (
- NSSToken *token,
- NSSCertificate *c,
- nssCryptokiObject *instance
-)
+nssToken_IsPrivateKeyAvailable(
+ NSSToken *token,
+ NSSCertificate *c,
+ nssCryptokiObject *instance)
{
CK_OBJECT_CLASS theClass;
- if (token == NULL) return PR_FALSE;
- if (c == NULL) return PR_FALSE;
+ 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;
+ theClass = CKO_PUBLIC_KEY;
}
- if (PK11_MatchItem(token->pk11slot, instance->handle, theClass)
- != CK_INVALID_HANDLE) {
- return PR_TRUE;
+ if (PK11_MatchItem(token->pk11slot, instance->handle, theClass) !=
+ CK_INVALID_HANDLE) {
+ return PR_TRUE;
}
return PR_FALSE;
}
diff --git a/nss/lib/dev/devutil.c b/nss/lib/dev/devutil.c
index 400b69d..b8f82c8 100644
--- a/nss/lib/dev/devutil.c
+++ b/nss/lib/dev/devutil.c
@@ -11,31 +11,30 @@
#endif /* CKHELPER_H */
NSS_IMPLEMENT nssCryptokiObject *
-nssCryptokiObject_Create (
- NSSToken *t,
- nssSession *session,
- CK_OBJECT_HANDLE h
-)
+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 }
+ { 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;
+ /* a failure here indicates a device error */
+ return (nssCryptokiObject *)NULL;
}
object = nss_ZNEW(NULL, nssCryptokiObject);
if (!object) {
- return (nssCryptokiObject *)NULL;
+ return (nssCryptokiObject *)NULL;
}
object->handle = h;
object->token = nssToken_AddRef(t);
@@ -47,40 +46,37 @@ nssCryptokiObject_Create (
}
NSS_IMPLEMENT void
-nssCryptokiObject_Destroy (
- nssCryptokiObject *object
-)
+nssCryptokiObject_Destroy(
+ nssCryptokiObject *object)
{
if (object) {
- nssToken_Destroy(object->token);
- nss_ZFreeIf(object->label);
- nss_ZFreeIf(object);
+ nssToken_Destroy(object->token);
+ nss_ZFreeIf(object->label);
+ nss_ZFreeIf(object);
}
}
NSS_IMPLEMENT nssCryptokiObject *
-nssCryptokiObject_Clone (
- nssCryptokiObject *object
-)
+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);
- }
+ 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
-)
+nssCryptokiObject_Equal(
+ nssCryptokiObject *o1,
+ nssCryptokiObject *o2)
{
return (o1->token == o2->token && o1->handle == o2->handle);
}
@@ -89,9 +85,10 @@ 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;
+ for (i = bufLen - 1; i >= 0;) {
+ if (pkcs11Str[i] != ' ' && pkcs11Str[i] != '\0')
+ break;
+ --i;
}
return (PRUint32)(i + 1);
}
@@ -101,80 +98,75 @@ nssPKCS11String_Length(CK_CHAR *pkcs11Str, PRUint32 bufLen)
*/
NSS_IMPLEMENT NSSSlot **
-nssSlotArray_Clone (
- NSSSlot **slots
-)
+nssSlotArray_Clone(
+ NSSSlot **slots)
{
NSSSlot **rvSlots = NULL;
NSSSlot **sp = slots;
PRUint32 count = 0;
- while (sp && *sp) count++;
+ 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);
- }
- }
+ 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
-)
+nssSlotArray_Destroy(
+ NSSSlot **slots)
{
if (slots) {
- NSSSlot **slotp;
- for (slotp = slots; *slotp; slotp++) {
- nssSlot_Destroy(*slotp);
- }
- nss_ZFreeIf(slots);
+ NSSSlot **slotp;
+ for (slotp = slots; *slotp; slotp++) {
+ nssSlot_Destroy(*slotp);
+ }
+ nss_ZFreeIf(slots);
}
}
NSS_IMPLEMENT void
-NSSSlotArray_Destroy (
- NSSSlot **slots
-)
+NSSSlotArray_Destroy(
+ NSSSlot **slots)
{
nssSlotArray_Destroy(slots);
}
NSS_IMPLEMENT void
-nssTokenArray_Destroy (
- NSSToken **tokens
-)
+nssTokenArray_Destroy(
+ NSSToken **tokens)
{
if (tokens) {
- NSSToken **tokenp;
- for (tokenp = tokens; *tokenp; tokenp++) {
- nssToken_Destroy(*tokenp);
- }
- nss_ZFreeIf(tokens);
+ NSSToken **tokenp;
+ for (tokenp = tokens; *tokenp; tokenp++) {
+ nssToken_Destroy(*tokenp);
+ }
+ nss_ZFreeIf(tokens);
}
}
NSS_IMPLEMENT void
-NSSTokenArray_Destroy (
- NSSToken **tokens
-)
+NSSTokenArray_Destroy(
+ NSSToken **tokens)
{
nssTokenArray_Destroy(tokens);
}
NSS_IMPLEMENT void
-nssCryptokiObjectArray_Destroy (
- nssCryptokiObject **objects
-)
+nssCryptokiObjectArray_Destroy(
+ nssCryptokiObject **objects)
{
if (objects) {
- nssCryptokiObject **op;
- for (op = objects; *op; op++) {
- nssCryptokiObject_Destroy(*op);
- }
- nss_ZFreeIf(objects);
+ nssCryptokiObject **op;
+ for (op = objects; *op; op++) {
+ nssCryptokiObject_Destroy(*op);
+ }
+ nss_ZFreeIf(objects);
}
}
@@ -182,45 +174,42 @@ nssCryptokiObjectArray_Destroy (
typedef struct
{
- NSSArena *arena;
- nssCryptokiObject *object;
- CK_ATTRIBUTE_PTR attributes;
- CK_ULONG numAttributes;
-}
-nssCryptokiObjectAndAttributes;
+ NSSArena *arena;
+ nssCryptokiObject *object;
+ CK_ATTRIBUTE_PTR attributes;
+ CK_ULONG numAttributes;
+} nssCryptokiObjectAndAttributes;
enum {
- cachedCerts = 0,
- cachedTrust = 1,
- cachedCRLs = 2
+ cachedCerts = 0,
+ cachedTrust = 1,
+ cachedCRLs = 2
} cachedObjectType;
-struct nssTokenObjectCacheStr
-{
- NSSToken *token;
- PZLock *lock;
- PRBool loggedIn;
- PRBool doObjectType[3];
- PRBool searchedObjectType[3];
- nssCryptokiObjectAndAttributes **objects[3];
+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_Create(
+ NSSToken *token,
+ PRBool cacheCerts,
+ PRBool cacheTrust,
+ PRBool cacheCRLs)
{
nssTokenObjectCache *rvCache;
rvCache = nss_ZNEW(NULL, nssTokenObjectCache);
if (!rvCache) {
- goto loser;
+ goto loser;
}
rvCache->lock = PZ_NewLock(nssILockOther); /* XXX */
if (!rvCache->lock) {
- goto loser;
+ goto loser;
}
rvCache->doObjectType[cachedCerts] = cacheCerts;
rvCache->doObjectType[cachedTrust] = cacheTrust;
@@ -233,112 +222,114 @@ loser:
}
static void
-clear_cache (
- nssTokenObjectCache *cache
-)
+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;
+ 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
-)
+nssTokenObjectCache_Clear(
+ nssTokenObjectCache *cache)
{
if (cache) {
- PZ_Lock(cache->lock);
- clear_cache(cache);
- PZ_Unlock(cache->lock);
+ PZ_Lock(cache->lock);
+ clear_cache(cache);
+ PZ_Unlock(cache->lock);
}
}
NSS_IMPLEMENT void
-nssTokenObjectCache_Destroy (
- nssTokenObjectCache *cache
-)
+nssTokenObjectCache_Destroy(
+ nssTokenObjectCache *cache)
{
if (cache) {
- clear_cache(cache);
- if (cache->lock) {
- PZ_DestroyLock(cache->lock);
- }
- nss_ZFreeIf(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
-)
+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;
+ 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
-)
+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;
+ *status = PR_SUCCESS;
+ return rvOandA;
}
- while (*objects++) (*numObjects)++;
+ 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;
+ /* 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;
+ 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
-)
+create_object(
+ nssCryptokiObject *object,
+ const CK_ATTRIBUTE_TYPE *types,
+ PRUint32 numTypes,
+ PRStatus *status)
{
PRUint32 j;
NSSArena *arena = NULL;
@@ -358,11 +349,11 @@ create_object (
}
arena = nssArena_Create();
if (!arena) {
- goto loser;
+ goto loser;
}
rvCachedObject = nss_ZNEW(arena, nssCryptokiObjectAndAttributes);
if (!rvCachedObject) {
- goto loser;
+ goto loser;
}
rvCachedObject->arena = arena;
/* The cache is tied to the token, and therefore the objects
@@ -372,10 +363,10 @@ create_object (
rvCachedObject->object = object;
rvCachedObject->attributes = nss_ZNEWARRAY(arena, CK_ATTRIBUTE, numTypes);
if (!rvCachedObject->attributes) {
- goto loser;
+ goto loser;
}
- for (j=0; j<numTypes; j++) {
- rvCachedObject->attributes[j].type = types[j];
+ for (j = 0; j < numTypes; j++) {
+ rvCachedObject->attributes[j].type = types[j];
}
*status = nssCKObject_GetAttributes(object->handle,
rvCachedObject->attributes,
@@ -384,7 +375,7 @@ create_object (
session,
slot);
if (*status != PR_SUCCESS) {
- goto loser;
+ goto loser;
}
rvCachedObject->numAttributes = numTypes;
*status = PR_SUCCESS;
@@ -394,10 +385,10 @@ create_object (
loser:
*status = PR_FAILURE;
if (slot) {
- nssSlot_Destroy(slot);
+ nssSlot_Destroy(slot);
}
if (arena)
- nssArena_Destroy(arena);
+ nssArena_Destroy(arena);
return (nssCryptokiObjectAndAttributes *)NULL;
}
@@ -409,7 +400,7 @@ loser:
* +-------------------------+<----------------------+
* | ^ |
* v | |
- * +----------+ slot friendly | token present +----------+
+ * +----------+ slot friendly | token present +----------+
* | cache | -----------------> % ---------------> | cache |
* | unloaded | | loaded |
* +----------+ +----------+
@@ -424,9 +415,8 @@ loser:
/* This function must not be called with cache->lock locked. */
static PRBool
-token_is_present (
- nssTokenObjectCache *cache
-)
+token_is_present(
+ nssTokenObjectCache *cache)
{
NSSSlot *slot = nssToken_GetSlot(cache->token);
PRBool tokenPresent = nssSlot_IsTokenPresent(slot);
@@ -435,92 +425,88 @@ token_is_present (
}
static PRBool
-search_for_objects (
- nssTokenObjectCache *cache
-)
+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 */
- }
+ 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;
+ /* slot is friendly, thus always available for search */
+ doSearch = PR_TRUE;
}
nssSlot_Destroy(slot);
return doSearch;
}
static nssCryptokiObjectAndAttributes *
-create_cert (
- nssCryptokiObject *object,
- PRStatus *status
-)
+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
+ 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
-)
+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
+ 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
-)
+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
+ 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);
@@ -528,108 +514,103 @@ create_crl (
/* Dispatch to the create function for the object type */
static nssCryptokiObjectAndAttributes *
-create_object_of_type (
- nssCryptokiObject *object,
- PRUint32 objectType,
- PRStatus *status
-)
+create_object_of_type(
+ nssCryptokiObject *object,
+ PRUint32 objectType,
+ PRStatus *status)
{
if (objectType == cachedCerts) {
- return create_cert(object, status);
+ return create_cert(object, status);
}
if (objectType == cachedTrust) {
- return create_trust(object, status);
+ return create_trust(object, status);
}
if (objectType == cachedCRLs) {
- return create_crl(object, status);
+ return create_crl(object, status);
}
return (nssCryptokiObjectAndAttributes *)NULL;
}
static PRStatus
-get_token_objects_for_cache (
- nssTokenObjectCache *cache,
- PRUint32 objectType,
- CK_OBJECT_CLASS objclass
-)
+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;
+ 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;
+ return status;
}
cache->objects[objectType] = create_object_array(objects,
doIt,
&numObjects,
&status);
if (status != PR_SUCCESS) {
- nss_ZFreeIf(objects);
- return status;
+ nss_ZFreeIf(objects);
+ 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;
- }
+ 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);
+ 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);
+ 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
-)
+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];
- }
+ 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
-)
+find_objects_in_array(
+ nssCryptokiObjectAndAttributes **objArray,
+ CK_ATTRIBUTE_PTR ot,
+ CK_ULONG otlen,
+ PRUint32 maximumOpt)
{
PRIntn oi = 0;
PRUint32 i;
@@ -641,65 +622,65 @@ find_objects_in_array (
CK_ATTRIBUTE_PTR attr;
if (!objArray) {
- return (nssCryptokiObject **)NULL;
+ return (nssCryptokiObject **)NULL;
}
arena = nssArena_Create();
if (!arena) {
- return (nssCryptokiObject **)NULL;
+ return (nssCryptokiObject **)NULL;
}
matches = nss_ZNEWARRAY(arena, nssCryptokiObjectAndAttributes *, size);
if (!matches) {
- goto loser;
+ goto loser;
}
- if (maximumOpt == 0) maximumOpt = ~0;
+ 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;
- }
- }
- }
+ 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;
- }
- }
+ 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;
@@ -710,74 +691,78 @@ loser:
}
NSS_IMPLEMENT nssCryptokiObject **
-nssTokenObjectCache_FindObjectsByTemplate (
- nssTokenObjectCache *cache,
- CK_OBJECT_CLASS objclass,
- CK_ATTRIBUTE_PTR otemplate,
- CK_ULONG otlen,
- PRUint32 maximumOpt,
- PRStatus *statusOpt
-)
+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;
+ 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;
+ 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);
- }
+ 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;
+ *statusOpt = status;
}
return rvObjects;
}
static PRBool
-cache_available_for_object_type (
- nssTokenObjectCache *cache,
- PRUint32 objectType
-)
+cache_available_for_object_type(
+ nssTokenObjectCache *cache,
+ PRUint32 objectType)
{
if (!cache->doObjectType[objectType]) {
- /* not caching this object kind */
- return PR_FALSE;
+ /* not caching this object kind */
+ return PR_FALSE;
}
if (!cache->searchedObjectType[objectType]) {
- /* objects are not cached yet */
- return PR_FALSE;
+ /* objects are not cached yet */
+ return PR_FALSE;
}
if (!search_for_objects(cache)) {
- /* not logged in */
- return PR_FALSE;
+ /* 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
-)
+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;
@@ -786,87 +771,91 @@ nssTokenObjectCache_GetObjectAttributes (
nssCryptokiObjectAndAttributes **oa = NULL;
PRUint32 objectType;
if (!token_is_present(cache)) {
- return PR_FAILURE;
+ 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;
+ 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;
+ goto loser;
}
oa = cache->objects[objectType];
if (!oa) {
- goto loser;
+ goto loser;
}
for (; *oa; oa++) {
- if (nssCryptokiObject_Equal((*oa)->object, object)) {
- cachedOA = *oa;
- break;
- }
+ if (nssCryptokiObject_Equal((*oa)->object, object)) {
+ cachedOA = *oa;
+ break;
+ }
}
if (!cachedOA) {
- goto loser; /* don't have this object */
+ 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;
- }
+ 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);
+ nssArena_Unmark(arena, mark);
}
return PR_SUCCESS;
loser:
PZ_Unlock(cache->lock);
if (mark) {
- nssArena_Release(arena, 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
-)
+nssTokenObjectCache_ImportObject(
+ nssTokenObjectCache *cache,
+ nssCryptokiObject *object,
+ CK_OBJECT_CLASS objclass,
+ CK_ATTRIBUTE_PTR ot,
+ CK_ULONG otlen)
{
PRStatus status = PR_SUCCESS;
PRUint32 count;
@@ -875,133 +864,135 @@ nssTokenObjectCache_ImportObject (
PRBool haveIt = PR_FALSE;
if (!token_is_present(cache)) {
- return PR_SUCCESS; /* cache not active, ignored */
+ 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 */
+ 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 */
+ 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 */
+ 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 (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);
+ /* 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);
- }
+ /* 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);
+ nssCryptokiObject *copyObject = nssCryptokiObject_Clone(object);
+ (*otype)[count] = create_object_of_type(copyObject, objectType,
+ &status);
} else {
- status = PR_FAILURE;
+ status = PR_FAILURE;
}
PZ_Unlock(cache->lock);
return status;
}
NSS_IMPLEMENT void
-nssTokenObjectCache_RemoveObject (
- nssTokenObjectCache *cache,
- nssCryptokiObject *object
-)
+nssTokenObjectCache_RemoveObject(
+ nssTokenObjectCache *cache,
+ nssCryptokiObject *object)
{
PRUint32 oType;
nssCryptokiObjectAndAttributes **oa, **swp = NULL;
if (!token_is_present(cache)) {
- return;
+ 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;
+ 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
+** 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_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;
+ rvAP->mechanism.mechanism = CKM_SHA_1;
+ rvAP->mechanism.pParameter = NULL;
+ rvAP->mechanism.ulParameterLen = 0;
}
return rvAP;
}
NSS_IMPLEMENT NSSAlgorithmAndParameters *
-NSSAlgorithmAndParameters_CreateMD5Digest (
- NSSArena *arenaOpt
-)
+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;
+ rvAP->mechanism.mechanism = CKM_MD5;
+ rvAP->mechanism.pParameter = NULL;
+ rvAP->mechanism.ulParameterLen = 0;
}
return rvAP;
}
-
diff --git a/nss/lib/dev/exports.gyp b/nss/lib/dev/exports.gyp
new file mode 100644
index 0000000..92cf756
--- /dev/null
+++ b/nss/lib/dev/exports.gyp
@@ -0,0 +1,31 @@
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+{
+ 'includes': [
+ '../../coreconf/config.gypi'
+ ],
+ 'targets': [
+ {
+ 'target_name': 'lib_dev_exports',
+ 'type': 'none',
+ 'copies': [
+ {
+ 'files': [
+ 'ckhelper.h',
+ 'dev.h',
+ 'devm.h',
+ 'devt.h',
+ 'devtm.h',
+ 'nssdev.h',
+ 'nssdevt.h'
+ ],
+ 'destination': '<(nss_private_dist_dir)/<(module)'
+ }
+ ]
+ }
+ ],
+ 'variables': {
+ 'module': 'nss'
+ }
+}
diff --git a/nss/lib/dev/nssdev.h b/nss/lib/dev/nssdev.h
index 4b3d9a3..1066ec6 100644
--- a/nss/lib/dev/nssdev.h
+++ b/nss/lib/dev/nssdev.h
@@ -24,16 +24,12 @@ PR_BEGIN_EXTERN_C
*/
NSS_EXTERN NSSAlgorithmAndParameters *
-NSSAlgorithmAndParameters_CreateSHA1Digest
-(
- NSSArena *arenaOpt
-);
+NSSAlgorithmAndParameters_CreateSHA1Digest(
+ NSSArena *arenaOpt);
NSS_EXTERN NSSAlgorithmAndParameters *
-NSSAlgorithmAndParameters_CreateMD5Digest
-(
- NSSArena *arenaOpt
-);
+NSSAlgorithmAndParameters_CreateMD5Digest(
+ NSSArena *arenaOpt);
PR_END_EXTERN_C
diff --git a/nss/lib/freebl/Makefile b/nss/lib/freebl/Makefile
index ab0b1e5..0ce1425 100644
--- a/nss/lib/freebl/Makefile
+++ b/nss/lib/freebl/Makefile
@@ -46,13 +46,24 @@ ifeq ($(FREEBL_NO_DEPEND),1)
endif
ifeq ($(FREEBL_LOWHASH),1)
+ DEFINES += -DFREEBL_LOWHASH
LOWHASH_SRCS = nsslowhash.c
LOWHASH_EXPORTS = nsslowhash.h
- MAPFILE_SOURCE = freebl_hash.def
+ MAPFILE_SOURCE = freebl_hash_vector.def
+ NEED_STUB_BUILD = 1
else
MAPFILE_SOURCE = freebl.def
endif
+ifdef USE_STUB_BUILD
+ CSRCS = lowhash_vector.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
+ MAPFILE_SOURCE = freebl_hash.def
+endif
+
# FREEBL_USE_PRELINK
#
# Most modern version of Linux support a speed optimization scheme where an
@@ -87,6 +98,10 @@ ifdef LINUX
DEFINES += -D__GNU_SOURCE=1
endif
endif
+ifdef NSS_NO_INIT_SUPPORT
+ DEFINES += -DNSS_NO_INIT_SUPPORT
+endif
+
ifdef FREEBL_PRELINK_COMMAND
DEFINES +=-DFREEBL_PRELINK_COMMAND=\"$(FREEBL_PRELINK_COMMAND)\"
endif
@@ -112,7 +127,7 @@ ifeq (OS2,$(OS_TARGET))
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
+ DEFINES += -DMP_IS_LITTLE_ENDIAN
endif
ifeq (,$(filter-out WINNT WIN95,$(OS_TARGET)))
@@ -148,7 +163,7 @@ else
endif
else
# -DMP_NO_MP_WORD
- DEFINES += -DMP_CHAR_STORE_SLOW -DMP_IS_LITTLE_ENDIAN
+ DEFINES += -DMP_IS_LITTLE_ENDIAN
ifdef NS_USE_GCC
# Ideally, we should use amd64 assembly code, but it's not yet mingw-w64
# compatible.
@@ -166,6 +181,9 @@ else
DEFINES += -DUSE_HW_AES -DINTEL_GCM
ASFILES += intel-aes-x64-masm.asm intel-gcm-x64-masm.asm
EXTRA_SRCS += intel-gcm-wrap.c
+ ifeq ($(CLANG_CL),1)
+ INTEL_GCM_CLANG_CL = 1
+ endif
endif
MPI_SRCS += mpi_amd64.c
endif
@@ -200,7 +218,7 @@ ifeq ($(CPU_ARCH),x86_64)
ASFLAGS += -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 += -DMP_IS_LITTLE_ENDIAN
# DEFINES += -DMPI_AMD64_ADD
# comment the next four lines to turn off Intel HW acceleration.
DEFINES += -DUSE_HW_AES -DINTEL_GCM
@@ -213,7 +231,7 @@ ifeq ($(CPU_ARCH),x86)
ASFILES = mpi_x86.s
DEFINES += -DMP_ASSEMBLY_MULTIPLY -DMP_ASSEMBLY_SQUARE
DEFINES += -DMP_ASSEMBLY_DIV_2DX1D -DMP_USE_UINT_DIGIT
- DEFINES += -DMP_CHAR_STORE_SLOW -DMP_IS_LITTLE_ENDIAN
+ DEFINES += -DMP_IS_LITTLE_ENDIAN
# The floating point ECC code doesn't work on Linux x86 (bug 311432).
#ECL_USE_FP = 1
endif
@@ -223,6 +241,11 @@ ifeq ($(CPU_ARCH),arm)
DEFINES += -DSHA_NO_LONG_LONG # avoid 64-bit arithmetic in SHA512
MPI_SRCS += mpi_arm.c
endif
+ifeq ($(CPU_ARCH),ppc)
+ifdef USE_64
+ DEFINES += -DNSS_NO_INIT_SUPPORT
+endif # USE_64
+endif # ppc
endif # Linux
ifeq ($(OS_TARGET),AIX)
@@ -451,7 +474,7 @@ else
# Intel acceleration for GCM does not build currently with Studio
endif
DEFINES += -DNSS_BEVAND_ARCFOUR -DMPI_AMD64 -DMP_ASSEMBLY_MULTIPLY
- DEFINES += -DNSS_USE_COMBA -DMP_CHAR_STORE_SLOW -DMP_IS_LITTLE_ENDIAN
+ DEFINES += -DNSS_USE_COMBA -DMP_IS_LITTLE_ENDIAN
# comment the next two lines to turn off Intel HW acceleration
DEFINES += -DUSE_HW_AES
ASFILES += intel-aes.s
@@ -479,6 +502,56 @@ ifndef NSS_DISABLE_ECC
endif
endif
+# poly1305-donna-x64-sse2-incremental-source.c requires __int128 support
+# in GCC 4.6.0.
+ifdef USE_64
+ ifdef CC_IS_CLANG
+ HAVE_INT128_SUPPORT = 1
+ DEFINES += -DHAVE_INT128_SUPPORT
+ else ifeq (1,$(CC_IS_GCC))
+ ifneq (,$(filter 4.6 4.7 4.8 4.9,$(word 1,$(GCC_VERSION)).$(word 2,$(GCC_VERSION))))
+ HAVE_INT128_SUPPORT = 1
+ DEFINES += -DHAVE_INT128_SUPPORT
+ endif
+ ifeq (,$(filter 0 1 2 3 4,$(word 1,$(GCC_VERSION))))
+ HAVE_INT128_SUPPORT = 1
+ DEFINES += -DHAVE_INT128_SUPPORT
+ endif
+ endif
+endif
+
+ifndef NSS_DISABLE_CHACHAPOLY
+ ifeq ($(CPU_ARCH),x86_64)
+ ifdef HAVE_INT128_SUPPORT
+ EXTRA_SRCS += poly1305-donna-x64-sse2-incremental-source.c
+ else
+ EXTRA_SRCS += poly1305.c
+ endif
+
+ ifneq (1,$(CC_IS_GCC))
+ EXTRA_SRCS += chacha20.c
+ else
+ EXTRA_SRCS += chacha20_vec.c
+ endif
+ else
+ EXTRA_SRCS += poly1305.c
+ EXTRA_SRCS += chacha20.c
+ endif # x86_64
+endif # NSS_DISABLE_CHACHAPOLY
+
+ifeq (,$(filter-out i386 x386 x86 x86_64,$(CPU_ARCH)))
+ # All intel architectures get the 64 bit version
+ # With custom uint128 if necessary (faster than generic 32 bit version).
+ ECL_SRCS += curve25519_64.c
+else
+ # All non intel architectures get the generic 32 bit implementation (slow!)
+ ECL_SRCS += curve25519_32.c
+endif
+
+ifndef HAVE_INT128_SUPPORT
+ ECL_SRCS += uint128.c
+endif
+
#######################################################################
# (5) Execute "global" rules. (OPTIONAL) #
#######################################################################
@@ -568,6 +641,17 @@ release_md libs:: $(SINGLE_SHLIB_DIR)
endif
+ifdef NEED_STUB_BUILD
+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 USE_STUB_BUILD=1 \
+ OBJDIR=$(SINGLE_SHLIB_DIR) $@
+endif
+
# multiple shared libraries
######################## ABI32_FPU stuff #########################
@@ -667,8 +751,8 @@ $(OBJDIR)/$(PROG_PREFIX)intel-gcm-wrap$(OBJ_SUFFIX): CFLAGS += -mssse3
# 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,$(shell $(AS) --version)))
-$(OBJDIR)/$(PROG_PREFIX)intel-gcm$(OBJ_SUFFIX): ASFLAGS += -no-integrated-as
+ifdef CC_IS_CLANG
+$(OBJDIR)/$(PROG_PREFIX)intel-gcm$(OBJ_SUFFIX): CFLAGS += -no-integrated-as
endif
endif
diff --git a/nss/lib/freebl/aeskeywrap.c b/nss/lib/freebl/aeskeywrap.c
index c1c95b3..79ff8a8 100644
--- a/nss/lib/freebl/aeskeywrap.c
+++ b/nss/lib/freebl/aeskeywrap.c
@@ -15,15 +15,15 @@
#else
#define BIG_ENDIAN_WITH_64_BIT_REGISTERS 1
#endif
-#include "prtypes.h" /* for PRUintXX */
-#include "secport.h" /* for PORT_XXX */
+#include "prtypes.h" /* for PRUintXX */
+#include "secport.h" /* for PORT_XXX */
#include "secerr.h"
-#include "blapi.h" /* for AES_ functions */
+#include "blapi.h" /* for AES_ functions */
#include "rijndael.h"
struct AESKeyWrapContextStr {
- unsigned char iv[AES_KEY_WRAP_IV_BYTES];
- AESContext aescx;
+ unsigned char iv[AES_KEY_WRAP_IV_BYTES];
+ AESContext aescx;
};
/******************************************/
@@ -31,71 +31,71 @@ struct AESKeyWrapContextStr {
** AES key wrap algorithm, RFC 3394
*/
-AESKeyWrapContext *
+AESKeyWrapContext *
AESKeyWrap_AllocateContext(void)
{
- AESKeyWrapContext * cx = PORT_New(AESKeyWrapContext);
+ 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
+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;
+ PORT_SetError(SEC_ERROR_INVALID_ARGS);
+ return SECFailure;
}
if (iv) {
- memcpy(cx->iv, iv, sizeof cx->iv);
+ memcpy(cx->iv, iv, sizeof cx->iv);
} else {
- memset(cx->iv, 0xA6, sizeof cx->iv);
+ memset(cx->iv, 0xA6, sizeof cx->iv);
}
- rv = AES_InitContext(&cx->aescx, key, keylen, NULL, NSS_AES, encrypt,
- AES_BLOCK_SIZE);
+ 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)
+** "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,
+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 */
+ 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 */
+ 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
+** "cx" the context
+** "freeit" if PR_TRUE then free the object as well as its sub-objects
*/
-extern void
+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);
+ AES_DestroyContext(&cx->aescx, PR_FALSE);
+ /* memset(cx, 0, sizeof *cx); */
+ if (freeit)
+ PORT_Free(cx);
}
}
@@ -112,18 +112,18 @@ AESKeyWrap_DestroyContext(AESKeyWrapContext *cx, PRBool freeit)
/* 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];
+ 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];
@@ -136,30 +136,31 @@ increment_and_xor(unsigned char *A, unsigned char *T)
}
/* 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
+** (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)
+xor_and_decrement(PRUint64 *A, PRUint64 *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]--;
+ unsigned char *TP = (unsigned char *)T;
+ const PRUint64 mask = 0xFF;
+ *A = ((*A & mask << 56) ^ (*T & mask << 56)) |
+ ((*A & mask << 48) ^ (*T & mask << 48)) |
+ ((*A & mask << 40) ^ (*T & mask << 40)) |
+ ((*A & mask << 32) ^ (*T & mask << 32)) |
+ ((*A & mask << 24) ^ (*T & mask << 23)) |
+ ((*A & mask << 16) ^ (*T & mask << 16)) |
+ ((*A & mask << 8) ^ (*T & mask << 8)) |
+ ((*A & mask) ^ (*T & mask));
+ if (!TP[7]--)
+ if (!TP[6]--)
+ if (!TP[5]--)
+ if (!TP[4]--)
+ if (!TP[3]--)
+ if (!TP[2]--)
+ if (!TP[1]--)
+ TP[0]--;
}
/* Given an unsigned long t (in host byte order), store this value as a
@@ -168,13 +169,20 @@ xor_and_decrement(unsigned char *A, unsigned char *T)
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[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;
}
@@ -182,56 +190,56 @@ set_t(unsigned char *pt, unsigned long t)
/*
** 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
+** "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
+extern SECStatus
AESKeyWrap_Encrypt(AESKeyWrapContext *cx, unsigned char *output,
- unsigned int *pOutputLen, unsigned int maxOutputLen,
- const unsigned char *input, unsigned int inputLen)
+ 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;
+ 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];
+ 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;
+ PORT_SetError(SEC_ERROR_INPUT_LEN);
+ return s;
}
#ifdef maybe
- if (!output && pOutputLen) { /* caller is asking for output size */
- *pOutputLen = outLen;
- return SECSuccess;
+ 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;
+ PORT_SetError(SEC_ERROR_OUTPUT_LEN);
+ return s;
}
if (cx == NULL || output == NULL || input == NULL) {
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- return s;
+ 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. */
- /*
+ return s; /* error is already set. */
+ /*
** 1) Initialize variables.
*/
memcpy(&A, cx->iv, AES_KEY_WRAP_IV_BYTES);
@@ -241,35 +249,35 @@ AESKeyWrap_Encrypt(AESKeyWrapContext *cx, unsigned char *output,
#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); */
+ 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;
+ A ^= ++t;
#else
- increment_and_xor((unsigned char *)&A, (unsigned char *)&t);
+ 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;
+ R[0] = A;
+ memcpy(output, &R[0], outLen);
+ if (pOutputLen)
+ *pOutputLen = outLen;
} else if (pOutputLen) {
- *pOutputLen = 0;
+ *pOutputLen = 0;
}
PORT_ZFree(R, outLen);
return s;
@@ -278,104 +286,102 @@ AESKeyWrap_Encrypt(AESKeyWrapContext *cx, unsigned char *output,
/*
** 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
+** "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
+extern SECStatus
AESKeyWrap_Decrypt(AESKeyWrapContext *cx, unsigned char *output,
- unsigned int *pOutputLen, unsigned int maxOutputLen,
- const unsigned char *input, unsigned int inputLen)
+ 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;
+ 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]
+ PRUint64 t;
+ PRUint64 B[2];
/* Check args */
- if (inputLen < 3 * AES_KEY_WRAP_BLOCK_SIZE ||
+ if (inputLen < 3 * AES_KEY_WRAP_BLOCK_SIZE ||
0 != inputLen % AES_KEY_WRAP_BLOCK_SIZE) {
- PORT_SetError(SEC_ERROR_INPUT_LEN);
- return s;
+ 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;
+ 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;
+ PORT_SetError(SEC_ERROR_OUTPUT_LEN);
+ return s;
}
if (cx == NULL || output == NULL || input == NULL) {
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- return s;
+ 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. */
+ return s; /* error is already set. */
nBlocks--;
- /*
+ /*
** 1) Initialize variables.
*/
memcpy(&R[0], input, inputLen);
- A = R[0];
+ B[0] = 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; */
+ 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--;
+ B[0] ^= t--;
#else
- xor_and_decrement((unsigned char *)&A, (unsigned char *)&t);
+ xor_and_decrement(&B[0], &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];
- }
+ 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 {
- s = SECFailure;
- PORT_SetError(SEC_ERROR_BAD_DATA);
- if (pOutputLen)
- *pOutputLen = 0;
- }
+ int bad = memcmp(&B[0], cx->iv, AES_KEY_WRAP_IV_BYTES);
+ if (!bad) {
+ memcpy(output, &R[1], outLen);
+ if (pOutputLen)
+ *pOutputLen = outLen;
+ } else {
+ s = SECFailure;
+ PORT_SetError(SEC_ERROR_BAD_DATA);
+ if (pOutputLen)
+ *pOutputLen = 0;
+ }
} else if (pOutputLen) {
- *pOutputLen = 0;
+ *pOutputLen = 0;
}
PORT_ZFree(R, inputLen);
return s;
diff --git a/nss/lib/freebl/alg2268.c b/nss/lib/freebl/alg2268.c
index ea97f52..54c6f4d 100644
--- a/nss/lib/freebl/alg2268.c
+++ b/nss/lib/freebl/alg2268.c
@@ -10,17 +10,18 @@
#endif
#include "blapi.h"
+#include "blapii.h"
#include "secerr.h"
#ifdef XP_UNIX_XXX
-#include <stddef.h> /* for ptrdiff_t */
+#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);
+typedef SECStatus(rc2Func)(RC2Context *cx, unsigned char *output,
+ const unsigned char *input, unsigned int inputLen);
/* forward declarations */
static rc2Func rc2_EncryptECB;
@@ -29,118 +30,133 @@ static rc2Func rc2_EncryptCBC;
static rc2Func rc2_DecryptCBC;
typedef union {
- PRUint32 l[2];
- PRUint16 s[4];
- PRUint8 b[8];
+ PRUint32 l[2];
+ PRUint16 s[4];
+ PRUint8 b[8];
} RC2Block;
struct RC2ContextStr {
union {
- PRUint8 Kb[128];
- PRUint16 Kw[64];
+ PRUint8 Kb[128];
+ PRUint16 Kw[64];
} u;
- RC2Block iv;
- rc2Func *enc;
- rc2Func *dec;
+ 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 SWAPK(i) cx->K[i] = (tmpS = cx->K[i], BYTESWAP(tmpS))
#define RC2_BLOCK_SIZE 8
-#define LOAD_HARD(R) \
+#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) \
+#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_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 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) }
+#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
+ 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)
+RC2Context *
+RC2_AllocateContext(void)
{
return PORT_ZNew(RC2Context);
}
-SECStatus
+SECStatus
RC2_InitContext(RC2Context *cx, const unsigned char *key, unsigned int len,
- const unsigned char *input, int mode, unsigned int efLen8,
- unsigned int unused)
+ const unsigned char *input, int mode, unsigned int efLen8,
+ unsigned int unused)
{
- PRUint8 *L,*L2;
- int i;
+ PRUint8 *L, *L2;
+ int i;
#if !defined(IS_LITTLE_ENDIAN)
- PRUint16 tmpS;
+ PRUint16 tmpS;
#endif
- PRUint8 tmpB;
+ PRUint8 tmpB;
- if (!key || !cx || !len || len > (sizeof cx->B) ||
- efLen8 > (sizeof cx->B)) {
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- return SECFailure;
+ 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 */
+ /* groovy */
} else if (mode == NSS_RC2_CBC) {
- if (!input) {
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- return SECFailure;
- }
+ if (!input) {
+ PORT_SetError(SEC_ERROR_INVALID_ARGS);
+ return SECFailure;
+ }
} else {
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- return SECFailure;
+ 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);
+ cx->enc = &rc2_EncryptCBC;
+ cx->dec = &rc2_DecryptCBC;
+ LOAD(cx->iv.s);
} else {
- cx->enc = & rc2_EncryptECB;
- cx->dec = & rc2_DecryptECB;
+ cx->enc = &rc2_EncryptECB;
+ cx->dec = &rc2_DecryptECB;
}
/* Step 0. Copy key into table. */
@@ -151,23 +167,23 @@ RC2_InitContext(RC2Context *cx, const unsigned char *key, unsigned int len,
L = L2 + len;
tmpB = L[-1];
for (i = (sizeof cx->B) - len; i > 0; --i) {
- *L++ = tmpB = S[ (PRUint8)(tmpB + *L2++) ];
+ *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 */
+ *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-- ];
+ 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 */
+ SWAPK(i); /* candidate for unrolling */
}
#endif
return SECSuccess;
@@ -175,60 +191,64 @@ RC2_InitContext(RC2Context *cx, const unsigned char *key, unsigned int len,
/*
** 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.
+** "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)
+ 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;
- }
+ 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
+** "cx" the context
+** "freeit" if PR_TRUE then free the object as well as its sub-objects
*/
-void
+void
RC2_DestroyContext(RC2Context *cx, PRBool freeit)
{
if (cx) {
- memset(cx, 0, sizeof *cx);
- if (freeit) {
- PORT_Free(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];\
+#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
+static void
rc2_Encrypt1Block(RC2Context *cx, RC2Block *output, RC2Block *input)
{
register PRUint16 R0, R1, R2, R3;
@@ -279,20 +299,24 @@ rc2_Encrypt1Block(RC2Context *cx, RC2Block *output, RC2Block *input)
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];\
+#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
+static void
rc2_Decrypt1Block(RC2Context *cx, RC2Block *output, RC2Block *input)
{
register PRUint16 R0, R1, R2, R3;
@@ -340,146 +364,146 @@ rc2_Decrypt1Block(RC2Context *cx, RC2Block *output, RC2Block *input)
output->s[3] = R3;
}
-static SECStatus
+static SECStatus NO_SANITIZE_ALIGNMENT
rc2_EncryptECB(RC2Context *cx, unsigned char *output,
- const unsigned char *input, unsigned int inputLen)
+ const unsigned char *input, unsigned int inputLen)
{
- RC2Block iBlock;
+ 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;
+ 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
+static SECStatus NO_SANITIZE_ALIGNMENT
rc2_DecryptECB(RC2Context *cx, unsigned char *output,
- const unsigned char *input, unsigned int inputLen)
+ const unsigned char *input, unsigned int inputLen)
{
- RC2Block iBlock;
+ 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;
+ 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
+static SECStatus NO_SANITIZE_ALIGNMENT
rc2_EncryptCBC(RC2Context *cx, unsigned char *output,
- const unsigned char *input, unsigned int inputLen)
+ const unsigned char *input, unsigned int inputLen)
{
- RC2Block iBlock;
+ 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;
+ 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
+static SECStatus NO_SANITIZE_ALIGNMENT
rc2_DecryptCBC(RC2Context *cx, unsigned char *output,
- const unsigned char *input, unsigned int inputLen)
+ const unsigned char *input, unsigned int inputLen)
{
- RC2Block iBlock;
- RC2Block oBlock;
+ 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;
+ 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
+** "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
+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 (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;
+ *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
+** "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
+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 (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;
+ *outputLen = inputLen;
}
return rv;
}
-
diff --git a/nss/lib/freebl/alghmac.c b/nss/lib/freebl/alghmac.c
index 9b845cf..dd8b73c 100644
--- a/nss/lib/freebl/alghmac.c
+++ b/nss/lib/freebl/alghmac.c
@@ -17,7 +17,7 @@
struct HMACContextStr {
void *hash;
const SECHashObject *hashobj;
- PRBool wasAllocated;
+ PRBool wasAllocated;
unsigned char ipad[HMAC_PAD_SIZE];
unsigned char opad[HMAC_PAD_SIZE];
};
@@ -26,50 +26,50 @@ void
HMAC_Destroy(HMACContext *cx, PRBool freeit)
{
if (cx == NULL)
- return;
+ return;
PORT_Assert(!freeit == !cx->wasAllocated);
if (cx->hash != NULL) {
- cx->hashobj->destroy(cx->hash, PR_TRUE);
- PORT_Memset(cx, 0, sizeof *cx);
+ cx->hashobj->destroy(cx->hash, PR_TRUE);
+ PORT_Memset(cx, 0, sizeof *cx);
}
if (freeit)
- PORT_Free(cx);
+ PORT_Free(cx);
}
SECStatus
-HMAC_Init( HMACContext * cx, const SECHashObject *hash_obj,
- const unsigned char *secret, unsigned int secret_len, PRBool isFIPS)
+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 (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;
+ 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;
+ 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];
+ 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);
@@ -77,8 +77,8 @@ HMAC_Init( HMACContext * cx, const SECHashObject *hash_obj,
/* fold secret into padding */
for (i = 0; i < secret_len; i++) {
- cx->ipad[i] ^= secret[i];
- cx->opad[i] ^= secret[i];
+ cx->ipad[i] ^= secret[i];
+ cx->opad[i] ^= secret[i];
}
PORT_Memset(hashed_secret, 0, sizeof hashed_secret);
return SECSuccess;
@@ -86,23 +86,23 @@ HMAC_Init( HMACContext * cx, const SECHashObject *hash_obj,
loser:
PORT_Memset(hashed_secret, 0, sizeof hashed_secret);
if (cx->hash != NULL)
- cx->hashobj->destroy(cx->hash, PR_TRUE);
+ cx->hashobj->destroy(cx->hash, PR_TRUE);
return SECFailure;
}
HMACContext *
-HMAC_Create(const SECHashObject *hash_obj, const unsigned char *secret,
+HMAC_Create(const SECHashObject *hash_obj, const unsigned char *secret,
unsigned int secret_len, PRBool isFIPS)
{
SECStatus rv;
- HMACContext * cx = PORT_ZNew(HMACContext);
+ HMACContext *cx = PORT_ZNew(HMACContext);
if (cx == NULL)
- return 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;
+ PORT_Free(cx); /* contains no secret info */
+ cx = NULL;
}
return cx;
}
@@ -123,16 +123,16 @@ HMAC_Update(HMACContext *cx, const unsigned char *data, unsigned int data_len)
SECStatus
HMAC_Finish(HMACContext *cx, unsigned char *result, unsigned int *result_len,
- unsigned int max_result_len)
+ unsigned int max_result_len)
{
if (max_result_len < cx->hashobj->length) {
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- return SECFailure;
+ 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;
+ return SECFailure;
cx->hashobj->begin(cx->hash);
cx->hashobj->update(cx->hash, cx->opad, cx->hashobj->blocklength);
@@ -146,15 +146,15 @@ HMAC_Clone(HMACContext *cx)
{
HMACContext *newcx;
- newcx = (HMACContext*)PORT_ZAlloc(sizeof(HMACContext));
+ newcx = (HMACContext *)PORT_ZAlloc(sizeof(HMACContext));
if (newcx == NULL)
- goto loser;
+ goto loser;
newcx->wasAllocated = PR_TRUE;
newcx->hashobj = cx->hashobj;
newcx->hash = cx->hashobj->clone(cx->hash);
if (newcx->hash == NULL)
- goto loser;
+ goto loser;
PORT_Memcpy(newcx->ipad, cx->ipad, cx->hashobj->blocklength);
PORT_Memcpy(newcx->opad, cx->opad, cx->hashobj->blocklength);
return newcx;
diff --git a/nss/lib/freebl/alghmac.h b/nss/lib/freebl/alghmac.h
index e77b311..462526a 100644
--- a/nss/lib/freebl/alghmac.h
+++ b/nss/lib/freebl/alghmac.h
@@ -15,45 +15,45 @@ 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.
+ * 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);
+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);
+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
+/* update HMAC
+ * cx HMAC Context
+ * data the data to perform HMAC on
+ * data_len the length of the data to process
*/
-extern void
+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
+ * 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);
+ 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
+ * need to keep a running hmac but also need to extract portions
* partway through the process.
*/
extern HMACContext *
diff --git a/nss/lib/freebl/arcfive.c b/nss/lib/freebl/arcfive.c
index 410cbed..dda7771 100644
--- a/nss/lib/freebl/arcfive.c
+++ b/nss/lib/freebl/arcfive.c
@@ -40,8 +40,8 @@ RC5_CreateContext(const SECItem *key, unsigned int rounds,
** "cx" the context
** "freeit" if PR_TRUE then free the object as well as its sub-objects
*/
-void
-RC5_DestroyContext(RC5Context *cx, PRBool freeit)
+void
+RC5_DestroyContext(RC5Context *cx, PRBool freeit)
{
PORT_SetError(PR_NOT_IMPLEMENTED_ERROR);
}
@@ -57,10 +57,10 @@ RC5_DestroyContext(RC5Context *cx, PRBool freeit)
** "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)
+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;
@@ -77,12 +77,11 @@ RC5_Encrypt(RC5Context *cx, unsigned char *output, unsigned int *outputLen,
** "input" the input data
** "inputLen" the amount of input data
*/
-SECStatus
-RC5_Decrypt(RC5Context *cx, unsigned char *output, unsigned int *outputLen,
- unsigned int maxOutputLen,
+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/nss/lib/freebl/arcfour.c b/nss/lib/freebl/arcfour.c
index abc9857..e37b458 100644
--- a/nss/lib/freebl/arcfour.c
+++ b/nss/lib/freebl/arcfour.c
@@ -23,8 +23,8 @@
#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
+/* 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
@@ -48,23 +48,22 @@ typedef PRUint8 Stype;
#define MASK1BYTE (WORD)(0xff)
#define SWAP(a, b) \
- tmp = a; \
- a = b; \
- b = tmp;
+ tmp = a; \
+ a = b; \
+ b = tmp;
/*
* State information for stream cipher.
*/
-struct RC4ContextStr
-{
+struct RC4ContextStr {
#if defined(NSS_ARCFOUR_IJ_B4_S) || defined(NSS_BEVAND_ARCFOUR)
- Stype i;
- Stype j;
- Stype S[ARCFOUR_STATE_SIZE];
+ Stype i;
+ Stype j;
+ Stype S[ARCFOUR_STATE_SIZE];
#else
- Stype S[ARCFOUR_STATE_SIZE];
- Stype i;
- Stype j;
+ Stype S[ARCFOUR_STATE_SIZE];
+ Stype i;
+ Stype j;
#endif
};
@@ -72,38 +71,38 @@ struct RC4ContextStr
* 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
+ 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 *
@@ -112,52 +111,51 @@ RC4_AllocateContext(void)
return PORT_ZNew(RC4Context);
}
-SECStatus
+SECStatus
RC4_InitContext(RC4Context *cx, const unsigned char *key, unsigned int len,
- const unsigned char * unused1, int unused2,
- unsigned int unused3, unsigned int unused4)
+ 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;
+ 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;
+ 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.
*/
@@ -166,66 +164,66 @@ 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;
- }
+ SECStatus rv = RC4_InitContext(cx, key, len, NULL, 0, 0, 0);
+ if (rv != SECSuccess) {
+ PORT_ZFree(cx, sizeof(*cx));
+ cx = NULL;
+ }
}
return cx;
}
-void
+void
RC4_DestroyContext(RC4Context *cx, PRBool freeit)
{
- if (freeit)
- PORT_ZFree(cx, sizeof(*cx));
+ 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);
+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;
+ 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
+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;
+ 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
@@ -234,108 +232,130 @@ rc4_no_opt(RC4Context *cx, unsigned char *output,
/*
* Byte-at-a-time ARCFOUR, unrolling the loop into 8 pieces.
*/
-static SECStatus
+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;
+ 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);
+#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 );
+#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); }
+#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); }
+#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); }
+#define ARCFOUR_NEXT_WORD() \
+ { \
+ streamWord = 0; \
+ ARCFOUR_NEXT4BYTES_L(0); \
+ }
#else
-#define ARCFOUR_NEXT_WORD() \
- { streamWord = 0; ARCFOUR_NEXT4BYTES_B(0); }
+#define ARCFOUR_NEXT_WORD() \
+ { \
+ streamWord = 0; \
+ ARCFOUR_NEXT4BYTES_B(0); \
+ }
#endif
#endif
@@ -351,221 +371,222 @@ rc4_unrolled(RC4Context *cx, unsigned char *output,
#define LEFTMOST_BYTE_SHIFT 0
#define NEXT_BYTE_SHIFT(shift) shift + 8
#else
-#define LEFTMOST_BYTE_SHIFT 8*(WORDSIZE - 1)
+#define LEFTMOST_BYTE_SHIFT 8 * (WORDSIZE - 1)
#define NEXT_BYTE_SHIFT(shift) shift - 8
#endif
#ifdef CONVERT_TO_WORDS
-static SECStatus
+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 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) {
- unsigned int 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;
- }
- }
- /*****************************************************************/
- /* 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 (bufShift) {
- /* preloadedByteCount is the number of input bytes pre-loaded
- * in inWord.
- */
- unsigned int preloadedByteCount = bufShift/8;
- for (; inputLen >= preloadedByteCount + 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 - preloadedByteCount;
- } 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;
+ 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 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) {
+ unsigned int 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;
+ }
+ }
+ /*****************************************************************/
+ /* 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 (bufShift) {
+ /* preloadedByteCount is the number of input bytes pre-loaded
+ * in inWord.
+ */
+ unsigned int preloadedByteCount = bufShift / 8;
+ for (; inputLen >= preloadedByteCount + 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 - preloadedByteCount;
+ } 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
+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;
- }
+ 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);
+ 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);
+ /* 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)
+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. */
+ 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);
+ 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);
+ /* Operate on bytes, but unroll the main loop */
+ return rc4_unrolled(cx, output, outputLen, maxOutputLen, input, inputLen);
#endif
}
diff --git a/nss/lib/freebl/blapi.h b/nss/lib/freebl/blapi.h
index 8324714..38c3a9f 100644
--- a/nss/lib/freebl/blapi.h
+++ b/nss/lib/freebl/blapi.h
@@ -23,41 +23,41 @@ 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.
+** 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);
+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.
+** 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);
+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.
+** 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);
+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.
+** 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);
+extern SECStatus RSA_PrivateKeyOpDoubleChecked(RSAPrivateKey *key,
+ unsigned char *output,
+ const unsigned char *input);
/*
** Perform a check of private key parameters for consistency.
@@ -69,7 +69,7 @@ extern SECStatus RSA_PrivateKeyCheck(const RSAPrivateKey *key);
** parameters.
**
**
-** All the entries, including those supplied by the caller, will be
+** 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.
@@ -118,43 +118,43 @@ extern SECStatus RSA_PopulatePrivateKey(RSAPrivateKey *key);
** inputLen MUST be equivalent to the modulus size (in bytes).
*/
extern SECStatus
-RSA_SignRaw(RSAPrivateKey * key,
- unsigned char * output,
- unsigned int * outputLen,
- unsigned int maxOutputLen,
- const unsigned char * input,
- unsigned int inputLen);
+RSA_SignRaw(RSAPrivateKey *key,
+ unsigned char *output,
+ unsigned int *outputLen,
+ unsigned int maxOutputLen,
+ const unsigned char *input,
+ unsigned int inputLen);
extern SECStatus
-RSA_CheckSignRaw(RSAPublicKey * key,
- const unsigned char * sig,
- unsigned int sigLen,
- const unsigned char * hash,
- unsigned int hashLen);
+RSA_CheckSignRaw(RSAPublicKey *key,
+ const unsigned char *sig,
+ unsigned int sigLen,
+ const unsigned char *hash,
+ unsigned int hashLen);
extern SECStatus
-RSA_CheckSignRecoverRaw(RSAPublicKey * key,
- unsigned char * data,
- unsigned int * dataLen,
- unsigned int maxDataLen,
- const unsigned char * sig,
- unsigned int sigLen);
+RSA_CheckSignRecoverRaw(RSAPublicKey *key,
+ unsigned char *data,
+ unsigned int *dataLen,
+ unsigned int maxDataLen,
+ const unsigned char *sig,
+ unsigned int sigLen);
extern SECStatus
-RSA_EncryptRaw(RSAPublicKey * key,
- unsigned char * output,
- unsigned int * outputLen,
- unsigned int maxOutputLen,
- const unsigned char * input,
- unsigned int inputLen);
+RSA_EncryptRaw(RSAPublicKey *key,
+ unsigned char *output,
+ unsigned int *outputLen,
+ unsigned int maxOutputLen,
+ const unsigned char *input,
+ unsigned int inputLen);
extern SECStatus
-RSA_DecryptRaw(RSAPrivateKey * key,
- unsigned char * output,
- unsigned int * outputLen,
- unsigned int maxOutputLen,
- const unsigned char * input,
- unsigned int inputLen);
+RSA_DecryptRaw(RSAPrivateKey *key,
+ unsigned char *output,
+ unsigned int *outputLen,
+ unsigned int maxOutputLen,
+ const unsigned char *input,
+ unsigned int inputLen);
/********************************************************************
** RSAES-OAEP encryption/decryption, as defined in RFC 3447, Section 7.1.
@@ -168,49 +168,49 @@ RSA_DecryptRaw(RSAPrivateKey * key,
** hashAlg.
*/
extern SECStatus
-RSA_EncryptOAEP(RSAPublicKey * key,
- HASH_HashType hashAlg,
- HASH_HashType maskHashAlg,
- const unsigned char * label,
- unsigned int labelLen,
- const unsigned char * seed,
- unsigned int seedLen,
- unsigned char * output,
- unsigned int * outputLen,
- unsigned int maxOutputLen,
- const unsigned char * input,
- unsigned int inputLen);
+RSA_EncryptOAEP(RSAPublicKey *key,
+ HASH_HashType hashAlg,
+ HASH_HashType maskHashAlg,
+ const unsigned char *label,
+ unsigned int labelLen,
+ const unsigned char *seed,
+ unsigned int seedLen,
+ unsigned char *output,
+ unsigned int *outputLen,
+ unsigned int maxOutputLen,
+ const unsigned char *input,
+ unsigned int inputLen);
extern SECStatus
-RSA_DecryptOAEP(RSAPrivateKey * key,
- HASH_HashType hashAlg,
- HASH_HashType maskHashAlg,
- const unsigned char * label,
- unsigned int labelLen,
- unsigned char * output,
- unsigned int * outputLen,
- unsigned int maxOutputLen,
- const unsigned char * input,
- unsigned int inputLen);
+RSA_DecryptOAEP(RSAPrivateKey *key,
+ HASH_HashType hashAlg,
+ HASH_HashType maskHashAlg,
+ const unsigned char *label,
+ unsigned int labelLen,
+ unsigned char *output,
+ unsigned int *outputLen,
+ unsigned int maxOutputLen,
+ const unsigned char *input,
+ unsigned int inputLen);
/********************************************************************
** RSAES-PKCS1-v1_5 encryption/decryption, as defined in RFC 3447, Section 7.2.
*/
extern SECStatus
-RSA_EncryptBlock(RSAPublicKey * key,
- unsigned char * output,
- unsigned int * outputLen,
- unsigned int maxOutputLen,
- const unsigned char * input,
- unsigned int inputLen);
+RSA_EncryptBlock(RSAPublicKey *key,
+ unsigned char *output,
+ unsigned int *outputLen,
+ unsigned int maxOutputLen,
+ const unsigned char *input,
+ unsigned int inputLen);
extern SECStatus
-RSA_DecryptBlock(RSAPrivateKey * key,
- unsigned char * output,
- unsigned int * outputLen,
- unsigned int maxOutputLen,
- const unsigned char * input,
- unsigned int inputLen);
+RSA_DecryptBlock(RSAPrivateKey *key,
+ unsigned char *output,
+ unsigned int *outputLen,
+ unsigned int maxOutputLen,
+ const unsigned char *input,
+ unsigned int inputLen);
/********************************************************************
** RSASSA-PSS signing/verifying, as defined in RFC 3447, Section 8.1.
@@ -222,26 +222,26 @@ RSA_DecryptBlock(RSAPrivateKey * key,
** freebl should generate a random value.
*/
extern SECStatus
-RSA_SignPSS(RSAPrivateKey * key,
- HASH_HashType hashAlg,
- HASH_HashType maskHashAlg,
- const unsigned char * salt,
- unsigned int saltLen,
- unsigned char * output,
- unsigned int * outputLen,
- unsigned int maxOutputLen,
- const unsigned char * input,
- unsigned int inputLen);
+RSA_SignPSS(RSAPrivateKey *key,
+ HASH_HashType hashAlg,
+ HASH_HashType maskHashAlg,
+ const unsigned char *salt,
+ unsigned int saltLen,
+ unsigned char *output,
+ unsigned int *outputLen,
+ unsigned int maxOutputLen,
+ const unsigned char *input,
+ unsigned int inputLen);
extern SECStatus
-RSA_CheckSignPSS(RSAPublicKey * key,
- HASH_HashType hashAlg,
- HASH_HashType maskHashAlg,
- unsigned int saltLen,
- const unsigned char * sig,
- unsigned int sigLen,
- const unsigned char * hash,
- unsigned int hashLen);
+RSA_CheckSignPSS(RSAPublicKey *key,
+ HASH_HashType hashAlg,
+ HASH_HashType maskHashAlg,
+ unsigned int saltLen,
+ const unsigned char *sig,
+ unsigned int sigLen,
+ const unsigned char *hash,
+ unsigned int hashLen);
/********************************************************************
** RSASSA-PKCS1-v1_5 signing/verifying, as defined in RFC 3447, Section 8.2.
@@ -253,27 +253,27 @@ RSA_CheckSignPSS(RSAPublicKey * key,
** as the signatures used in SSL/TLS, which sign a raw hash.
*/
extern SECStatus
-RSA_Sign(RSAPrivateKey * key,
- unsigned char * output,
- unsigned int * outputLen,
- unsigned int maxOutputLen,
- const unsigned char * data,
- unsigned int dataLen);
+RSA_Sign(RSAPrivateKey *key,
+ unsigned char *output,
+ unsigned int *outputLen,
+ unsigned int maxOutputLen,
+ const unsigned char *data,
+ unsigned int dataLen);
extern SECStatus
-RSA_CheckSign(RSAPublicKey * key,
- const unsigned char * sig,
- unsigned int sigLen,
- const unsigned char * data,
- unsigned int dataLen);
+RSA_CheckSign(RSAPublicKey *key,
+ const unsigned char *sig,
+ unsigned int sigLen,
+ const unsigned char *data,
+ unsigned int dataLen);
extern SECStatus
-RSA_CheckSignRecover(RSAPublicKey * key,
- unsigned char * output,
- unsigned int * outputLen,
- unsigned int maxOutputLen,
- const unsigned char * sig,
- unsigned int sigLen);
+RSA_CheckSignRecover(RSAPublicKey *key,
+ unsigned char *output,
+ unsigned int *outputLen,
+ unsigned int maxOutputLen,
+ const unsigned char *sig,
+ unsigned int sigLen);
/********************************************************************
** DSA signing algorithm
@@ -281,17 +281,17 @@ RSA_CheckSignRecover(RSAPublicKey * key,
/* Generate a new random value within the interval [2, q-1].
*/
-extern SECStatus DSA_NewRandom(PLArenaPool * arena, const SECItem * q,
- SECItem * random);
+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.
+** 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);
+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.
@@ -299,52 +299,52 @@ extern SECStatus DSA_NewKey(const PQGParams * params,
** On output, signature->len == size of signature in buffer.
** Uses a random seed.
*/
-extern SECStatus DSA_SignDigest(DSAPrivateKey * key,
- SECItem * signature,
- const SECItem * digest);
+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);
+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,
+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);
+extern SECStatus DSA_SignDigestWithSeed(DSAPrivateKey *key,
+ SECItem *signature,
+ const SECItem *digest,
+ const unsigned char *seed);
/******************************************************
-** Diffie Helman key exchange algorithm
+** Diffie Helman key exchange algorithm
*/
/* Generates parameters for Diffie-Helman key generation.
-** primeLen is the length in bytes of prime P to be generated.
+** primeLen is the length in bytes of prime P to be generated.
*/
-extern SECStatus DH_GenParam(int primeLen, DHParams ** params);
+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.
+** DHPrivateKey struct. Params is input, privKey are output.
+** This is Phase 1 of Diffie Hellman.
*/
-extern SECStatus DH_NewKey(DHParams * params,
- DHPrivateKey ** privKey);
+extern SECStatus DH_NewKey(DHParams *params,
+ DHPrivateKey **privKey);
-/*
-** DH_Derive does the Diffie-Hellman phase 2 calculation, using the
+/*
+** 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
+** 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
@@ -353,25 +353,25 @@ extern SECStatus DH_NewKey(DHParams * params,
** 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
+** 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);
+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);
+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
@@ -401,24 +401,24 @@ extern PRBool KEA_Verify(SECItem *Y, SECItem *prime, SECItem *subPrime);
* 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);
+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.
+ * 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);
+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
+ * 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.
*
@@ -431,9 +431,9 @@ JPAKE_Verify(PLArenaPool * arena, const PQGParams * pqg,
* 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);
+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)
*
@@ -441,34 +441,34 @@ JPAKE_Round2(PLArenaPool * arena, const SECItem * p, const SECItem *q,
* 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);
+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
+/* 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_NewKey(ECParams *params,
+ ECPrivateKey **privKey);
-extern SECStatus EC_NewKeyFromSeed(ECParams * params,
- ECPrivateKey ** privKey,
- const unsigned char* seed,
- int seedlen);
+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);
+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
@@ -481,34 +481,34 @@ extern SECStatus EC_ValidatePublicKey(ECParams * params,
** 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);
+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,
+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,
+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);
+extern SECStatus ECDSA_SignDigestWithSeed(ECPrivateKey *key,
+ SECItem *signature,
+ const SECItem *digest,
+ const unsigned char *seed,
+ const int seedlen);
/******************************************/
/*
@@ -517,56 +517,56 @@ extern SECStatus ECDSA_SignDigestWithSeed(ECPrivateKey *key,
/*
** Create a new RC4 context suitable for RC4 encryption/decryption.
-** "key" raw key data
-** "len" the number of bytes of key data
+** "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 );
+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
+** "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
+** "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);
+ 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
+** "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);
+ unsigned int *outputLen, unsigned int maxOutputLen,
+ const unsigned char *input, unsigned int inputLen);
/******************************************/
/*
@@ -575,64 +575,64 @@ extern SECStatus RC4_Decrypt(RC4Context *cx, unsigned char *output,
/*
** 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).
+** "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);
+ 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 );
+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
+** "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
+** "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);
+ 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
+** "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);
+ unsigned int *outputLen, unsigned int maxOutputLen,
+ const unsigned char *input, unsigned int inputLen);
/******************************************/
/*
@@ -650,15 +650,15 @@ extern SECStatus RC2_Decrypt(RC2Context *cx, unsigned char *output,
** chaining" mode.
*/
extern RC5Context *RC5_CreateContext(const SECItem *key, unsigned int rounds,
- unsigned int wordSize, const unsigned char *iv, int mode);
+ 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);
+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.
@@ -679,8 +679,8 @@ extern void RC5_DestroyContext(RC5Context *cx, PRBool freeit);
** "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);
+ unsigned int *outputLen, unsigned int maxOutputLen,
+ const unsigned char *input, unsigned int inputLen);
/*
** Perform RC5 decryption.
@@ -695,10 +695,8 @@ extern SECStatus RC5_Encrypt(RC5Context *cx, unsigned char *output,
*/
extern SECStatus RC5_Decrypt(RC5Context *cx, unsigned char *output,
- unsigned int *outputLen, unsigned int maxOutputLen,
- const unsigned char *input, unsigned int inputLen);
-
-
+ unsigned int *outputLen, unsigned int maxOutputLen,
+ const unsigned char *input, unsigned int inputLen);
/******************************************/
/*
@@ -707,91 +705,91 @@ extern SECStatus RC5_Decrypt(RC5Context *cx, unsigned char *output,
/*
** 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
+** "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,
+extern DESContext *DES_CreateContext(const unsigned char *key,
const unsigned char *iv,
- int mode, PRBool encrypt);
+ 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 );
+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
+** "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
+** "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);
+ 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
+** "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);
+ unsigned int *outputLen, unsigned int maxOutputLen,
+ const unsigned char *input, unsigned int inputLen);
/******************************************/
-/*
-** SEED symmetric block cypher
+/*
+** SEED symmetric block cypher
*/
extern SEEDContext *
-SEED_CreateContext(const unsigned char *key, const unsigned char *iv,
- int mode, PRBool encrypt);
+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 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,
+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);
/******************************************/
@@ -801,60 +799,60 @@ SEED_Decrypt(SEEDContext *cx, unsigned char *output,
/*
** 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)
+** "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,
+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);
+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
+** "cx" the context
+** "freeit" if PR_TRUE then free the object as well as its sub-objects
*/
-extern void
+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
+** "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
+** "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);
@@ -866,126 +864,155 @@ AES_Decrypt(AESContext *cx, unsigned char *output,
/*
** Create a new AES context suitable for AES encryption/decryption.
-** "key" raw key data
+** "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)
+** "keylen" the number of bytes of key data (16, 24, or 32)
*/
extern AESKeyWrapContext *
-AESKeyWrap_CreateContext(const unsigned char *key, const unsigned char *iv,
+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 );
+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
+** "cx" the context
+** "freeit" if PR_TRUE then free the object as well as its sub-objects
*/
-extern void
+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
+** "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);
+ 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
+** "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);
+ 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)
+** "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);
+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);
+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
+** "cx" the context
+** "freeit" if PR_TRUE then free the object as well as its sub-objects
*/
-extern void
+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
+** "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);
+ 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
+** "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);
+ unsigned int *outputLen, unsigned int maxOutputLen,
+ const unsigned char *input, unsigned int inputLen);
+
+/******************************************/
+/*
+** ChaCha20+Poly1305 AEAD
+*/
+extern SECStatus ChaCha20Poly1305_InitContext(ChaCha20Poly1305Context *ctx,
+ const unsigned char *key,
+ unsigned int keyLen,
+ unsigned int tagLen);
+
+extern ChaCha20Poly1305Context *ChaCha20Poly1305_CreateContext(
+ const unsigned char *key, unsigned int keyLen, unsigned int tagLen);
+
+extern void ChaCha20Poly1305_DestroyContext(ChaCha20Poly1305Context *ctx,
+ PRBool freeit);
+
+extern SECStatus ChaCha20Poly1305_Seal(
+ const ChaCha20Poly1305Context *ctx, unsigned char *output,
+ unsigned int *outputLen, unsigned int maxOutputLen,
+ const unsigned char *input, unsigned int inputLen,
+ const unsigned char *nonce, unsigned int nonceLen,
+ const unsigned char *ad, unsigned int adLen);
+
+extern SECStatus ChaCha20Poly1305_Open(
+ const ChaCha20Poly1305Context *ctx, unsigned char *output,
+ unsigned int *outputLen, unsigned int maxOutputLen,
+ const unsigned char *input, unsigned int inputLen,
+ const unsigned char *nonce, unsigned int nonceLen,
+ const unsigned char *ad, unsigned int adLen);
/******************************************/
/*
@@ -1001,18 +1028,17 @@ 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,
- PRUint32 src_length);
+ PRUint32 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
+** "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);
@@ -1023,35 +1049,35 @@ 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
+** "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);
+ 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"
+** "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);
+ 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"
+** "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);
+ unsigned int *digestLen, unsigned int maxDigestLen);
/*
* Return the the size of a buffer needed to flatten the MD5 Context into
@@ -1066,7 +1092,7 @@ extern unsigned int MD5_FlattenSize(MD5Context *cx);
* "space" the buffer to flatten to
* returns status;
*/
-extern SECStatus MD5_Flatten(MD5Context *cx,unsigned char *space);
+extern SECStatus MD5_Flatten(MD5Context *cx, unsigned char *space);
/*
* Resurrect a flattened context into a MD5 Context
@@ -1074,7 +1100,7 @@ extern SECStatus MD5_Flatten(MD5Context *cx,unsigned char *space);
* "arg" ptr to void used by cryptographic resurrect
* returns resurected context;
*/
-extern MD5Context * MD5_Resurrect(unsigned char *space, void *arg);
+extern MD5Context *MD5_Resurrect(unsigned char *space, void *arg);
extern void MD5_Clone(MD5Context *dest, MD5Context *src);
/*
@@ -1082,7 +1108,6 @@ extern void MD5_Clone(MD5Context *dest, MD5Context *src);
*/
extern void MD5_TraceState(MD5Context *cx);
-
/******************************************/
/*
** MD2 secure hash function
@@ -1098,11 +1123,10 @@ extern SECStatus MD2_Hash(unsigned char *dest, const char *src);
*/
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
+** "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);
@@ -1113,23 +1137,23 @@ 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
+** "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);
+ 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"
+** "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);
+ unsigned int *digestLen, unsigned int maxDigestLen);
/*
* Return the the size of a buffer needed to flatten the MD2 Context into
@@ -1144,7 +1168,7 @@ extern unsigned int MD2_FlattenSize(MD2Context *cx);
* "space" the buffer to flatten to
* returns status;
*/
-extern SECStatus MD2_Flatten(MD2Context *cx,unsigned char *space);
+extern SECStatus MD2_Flatten(MD2Context *cx, unsigned char *space);
/*
* Resurrect a flattened context into a MD2 Context
@@ -1152,7 +1176,7 @@ extern SECStatus MD2_Flatten(MD2Context *cx,unsigned char *space);
* "arg" ptr to void used by cryptographic resurrect
* returns resurected context;
*/
-extern MD2Context * MD2_Resurrect(unsigned char *space, void *arg);
+extern MD2Context *MD2_Resurrect(unsigned char *space, void *arg);
extern void MD2_Clone(MD2Context *dest, MD2Context *src);
/******************************************/
@@ -1169,18 +1193,17 @@ 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,
- PRUint32 src_length);
+ PRUint32 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
+** "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);
@@ -1191,35 +1214,35 @@ 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
+** "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);
+ 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"
+** "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);
+ 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"
+** "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);
+ unsigned int *digestLen, unsigned int maxDigestLen);
/*
** trace the intermediate state info of the SHA1 hash.
@@ -1239,7 +1262,7 @@ extern unsigned int SHA1_FlattenSize(SHA1Context *cx);
* "space" the buffer to flatten to
* returns status;
*/
-extern SECStatus SHA1_Flatten(SHA1Context *cx,unsigned char *space);
+extern SECStatus SHA1_Flatten(SHA1Context *cx, unsigned char *space);
/*
* Resurrect a flattened context into a SHA-1 Context
@@ -1247,7 +1270,7 @@ extern SECStatus SHA1_Flatten(SHA1Context *cx,unsigned char *space);
* "arg" ptr to void used by cryptographic resurrect
* returns resurected context;
*/
-extern SHA1Context * SHA1_Resurrect(unsigned char *space, void *arg);
+extern SHA1Context *SHA1_Resurrect(unsigned char *space, void *arg);
extern void SHA1_Clone(SHA1Context *dest, SHA1Context *src);
/******************************************/
@@ -1256,27 +1279,27 @@ 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);
+ unsigned int inputLen);
extern void SHA224_End(SHA224Context *cx, unsigned char *digest,
- unsigned int *digestLen, unsigned int maxDigestLen);
+ 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"
+** "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);
+ unsigned int *digestLen, unsigned int maxDigestLen);
extern SECStatus SHA224_HashBuf(unsigned char *dest, const unsigned char *src,
- PRUint32 src_length);
+ PRUint32 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 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);
/******************************************/
@@ -1285,27 +1308,27 @@ 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);
+ unsigned int inputLen);
extern void SHA256_End(SHA256Context *cx, unsigned char *digest,
- unsigned int *digestLen, unsigned int maxDigestLen);
+ 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"
+** "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);
+ unsigned int *digestLen, unsigned int maxDigestLen);
extern SECStatus SHA256_HashBuf(unsigned char *dest, const unsigned char *src,
- PRUint32 src_length);
+ PRUint32 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 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);
/******************************************/
@@ -1314,27 +1337,27 @@ 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);
+ 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"
+** "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);
+ unsigned int *digestLen, unsigned int maxDigestLen);
extern void SHA512_End(SHA512Context *cx, unsigned char *digest,
- unsigned int *digestLen, unsigned int maxDigestLen);
+ unsigned int *digestLen, unsigned int maxDigestLen);
extern SECStatus SHA512_HashBuf(unsigned char *dest, const unsigned char *src,
- PRUint32 src_length);
+ PRUint32 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 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);
/******************************************/
@@ -1343,27 +1366,27 @@ 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);
+ unsigned int inputLen);
extern void SHA384_End(SHA384Context *cx, unsigned char *digest,
- unsigned int *digestLen, unsigned int maxDigestLen);
+ 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"
+** "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);
+ unsigned int *digestLen, unsigned int maxDigestLen);
extern SECStatus SHA384_HashBuf(unsigned char *dest, const unsigned char *src,
- PRUint32 src_length);
+ PRUint32 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 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);
/****************************************
@@ -1371,8 +1394,8 @@ extern void SHA384_Clone(SHA384Context *dest, SHA384Context *src);
*/
extern SECStatus
-TLS_PRF(const SECItem *secret, const char *label, SECItem *seed,
- SECItem *result, PRBool isFIPS);
+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,
@@ -1406,11 +1429,13 @@ extern SECStatus RNG_RandomUpdate(const void *data, size_t bytes);
*/
extern SECStatus RNG_GenerateGlobalRandomBytes(void *dest, size_t len);
+extern SECStatus RNG_ResetForFuzzing(void);
+
/* 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_RNGShutdown(void);
extern void RNG_SystemInfoForRNG(void);
@@ -1449,17 +1474,17 @@ FIPS186Change_ReduceModQForDSA(const unsigned char *w,
* 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);
+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);
+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);
+PRNGTEST_Generate(PRUint8 *bytes, unsigned int bytes_len,
+ const PRUint8 *additional, unsigned int additional_len);
extern SECStatus
PRNGTEST_Uninstantiate(void);
@@ -1468,15 +1493,15 @@ extern SECStatus
PRNGTEST_RunHealthTests(void);
/* Generate PQGParams and PQGVerify structs.
- * Length of seed and length of h both equal length of P.
+ * 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. */
+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.
@@ -1487,14 +1512,14 @@ PQG_ParamGen(unsigned int j, /* input : determines length of P. */
*/
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. */
+ 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 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.
*
@@ -1511,17 +1536,16 @@ PQG_ParamGenSeedLen(
* pick a default value (typically the smallest secure value for these
* variables).
*
- * The verify parameters will conform to FIPS186-3 using the smallest
+ * 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. */
-
+ 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
@@ -1538,14 +1562,13 @@ PQG_ParamGenV2(
* PQG_VerifyParams will automatically choose the appropriate test.
*/
-extern SECStatus PQG_VerifyParams(const PQGParams *params,
- const PQGVerify *vfy, SECStatus *result);
+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
@@ -1572,7 +1595,7 @@ PRBool BLAPI_SHVerifyFile(const char *shName);
PRBool BLAPI_VerifySelf(const char *name);
/*********************************************************************/
-extern const SECHashObject * HASH_GetRawHashObject(HASH_HashType hashType);
+extern const SECHashObject *HASH_GetRawHashObject(HASH_HashType hashType);
extern void BL_SetForkState(PRBool forked);
diff --git a/nss/lib/freebl/blapii.h b/nss/lib/freebl/blapii.h
index 4840fc7..6ad2e28 100644
--- a/nss/lib/freebl/blapii.h
+++ b/nss/lib/freebl/blapii.h
@@ -14,18 +14,23 @@
#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);
+ 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
+SECStatus BL_FIPSEntryOK(PRBool freeblOnly);
+PRBool BL_POSTRan(PRBool freeblOnly);
+
#if defined(XP_UNIX) && !defined(NO_FORK_CHECK)
extern PRBool bl_parentForkedAfterC_Initialize;
-#define SKIP_AFTER_FORK(x) if (!bl_parentForkedAfterC_Initialize) x
+#define SKIP_AFTER_FORK(x) \
+ if (!bl_parentForkedAfterC_Initialize) \
+ x
#else
@@ -35,5 +40,22 @@ extern PRBool bl_parentForkedAfterC_Initialize;
SEC_END_PROTOS
-#endif /* _BLAPII_H_ */
+#if defined(NSS_X86_OR_X64)
+#define HAVE_UNALIGNED_ACCESS 1
+#endif
+
+#if defined(__clang__)
+#define HAVE_NO_SANITIZE_ATTR __has_attribute(no_sanitize)
+#else
+#define HAVE_NO_SANITIZE_ATTR 0
+#endif
+#if defined(HAVE_UNALIGNED_ACCESS) && HAVE_NO_SANITIZE_ATTR
+#define NO_SANITIZE_ALIGNMENT __attribute__((no_sanitize("alignment")))
+#else
+#define NO_SANITIZE_ALIGNMENT
+#endif
+
+#undef HAVE_NO_SANITIZE_ATTR
+
+#endif /* _BLAPII_H_ */
diff --git a/nss/lib/freebl/blapit.h b/nss/lib/freebl/blapit.h
index 8e172d4..7cf8fc6 100644
--- a/nss/lib/freebl/blapit.h
+++ b/nss/lib/freebl/blapit.h
@@ -13,42 +13,41 @@
#include "plarena.h"
#include "ecl-exp.h"
-
/* RC2 operation modes */
-#define NSS_RC2 0
-#define NSS_RC2_CBC 1
+#define NSS_RC2 0
+#define NSS_RC2_CBC 1
/* RC5 operation modes */
-#define NSS_RC5 0
-#define NSS_RC5_CBC 1
+#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 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 */
+#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
+#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
+#define NSS_CAMELLIA 0
+#define NSS_CAMELLIA_CBC 1
/* SEED operation modes */
-#define NSS_SEED 0
-#define NSS_SEED_CBC 1
+#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 */
+#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
@@ -59,78 +58,72 @@
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))
+#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_SUBPRIME_LEN DSA1_SUBPRIME_LEN
#define DSA_SIGNATURE_LEN DSA1_SIGNATURE_LEN
-#define DSA_Q_BITS (DSA1_SUBPRIME_LEN*8)
+#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 */
+#define MAX_ECKEY_LEN 72 /* Bytes */
-#ifdef NSS_ECC_MORE_THAN_SUITE_B
-#define EC_MAX_KEY_BITS 571 /* in bits */
-#define EC_MIN_KEY_BITS 112 /* in bits */
-#else
-#define EC_MAX_KEY_BITS 521 /* in bits */
-#define EC_MIN_KEY_BITS 256 /* in bits */
-#endif
+#define EC_MAX_KEY_BITS 521 /* in bits */
+#define EC_MIN_KEY_BITS 256 /* in bits */
/* 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
+#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
+#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 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_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 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 CAMELLIA_BLOCK_SIZE 16 /* bytes */
-#define SEED_BLOCK_SIZE 16 /* bytes */
-#define SEED_KEY_LENGTH 16 /* bytes */
+#define SEED_BLOCK_SIZE 16 /* bytes */
+#define SEED_KEY_LENGTH 16 /* bytes */
#define NSS_FREEBL_DEFAULT_CHUNKSIZE 2048
@@ -138,11 +131,11 @@ typedef int __BLAPI_DEPRECATED __attribute__((deprecated));
* 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_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
+#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
@@ -152,17 +145,17 @@ typedef int __BLAPI_DEPRECATED __attribute__((deprecated));
* 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
+ * 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.
*
@@ -179,24 +172,22 @@ typedef int __BLAPI_DEPRECATED __attribute__((deprecated));
* 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
+#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
+#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)
+ (((bits) < 512 || (bits) > 1024 || (bits) % 64) ? -1 : (int)((bits)-512) / 64)
/*
* function takes index (0-8)
@@ -204,42 +195,43 @@ typedef int __BLAPI_DEPRECATED __attribute__((deprecated));
*/
#define PQG_INDEX_TO_PBITS(j) (((unsigned)(j) > 8) ? -1 : (512 + 64 * (j)))
-
/***************************************************************************
-** Opaque objects
+** 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;
+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;
+struct ChaCha20Poly1305ContextStr;
+
+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;
+typedef struct SHA256ContextStr SHA224Context;
+typedef struct SHA512ContextStr SHA512Context;
/* SHA384Context is really a SHA512ContextStr. This is not a mistake. */
-typedef struct SHA512ContextStr SHA384Context;
+typedef struct SHA512ContextStr SHA384Context;
typedef struct AESKeyWrapContextStr AESKeyWrapContext;
-typedef struct SEEDContextStr SEEDContext;
+typedef struct SEEDContextStr SEEDContext;
+typedef struct ChaCha20Poly1305ContextStr ChaCha20Poly1305Context;
/***************************************************************************
** RSA Public and Private Key structures
@@ -247,7 +239,7 @@ typedef struct SEEDContextStr SEEDContext;
/* member names from PKCS#1, section 7.1 */
struct RSAPublicKeyStr {
- PLArenaPool * arena;
+ PLArenaPool *arena;
SECItem modulus;
SECItem publicExponent;
};
@@ -255,7 +247,7 @@ typedef struct RSAPublicKeyStr RSAPublicKey;
/* member names from PKCS#1, section 7.2 */
struct RSAPrivateKeyStr {
- PLArenaPool * arena;
+ PLArenaPool *arena;
SECItem version;
SECItem modulus;
SECItem publicExponent;
@@ -268,7 +260,6 @@ struct RSAPrivateKeyStr {
};
typedef struct RSAPrivateKeyStr RSAPrivateKey;
-
/***************************************************************************
** DSA Public and Private Key and related structures
*/
@@ -283,10 +274,10 @@ struct PQGParamsStr {
typedef struct PQGParamsStr PQGParams;
struct PQGVerifyStr {
- PLArenaPool * arena; /* includes this struct, seed, & h. */
- unsigned int counter;
- SECItem seed;
- SECItem h;
+ PLArenaPool *arena; /* includes this struct, seed, & h. */
+ unsigned int counter;
+ SECItem seed;
+ SECItem h;
};
typedef struct PQGVerifyStr PQGVerify;
@@ -309,14 +300,14 @@ typedef struct DSAPrivateKeyStr DSAPrivateKey;
*/
struct DHParamsStr {
- PLArenaPool * arena;
+ PLArenaPool *arena;
SECItem prime; /* p */
- SECItem base; /* g */
+ SECItem base; /* g */
};
typedef struct DHParamsStr DHParams;
struct DHPublicKeyStr {
- PLArenaPool * arena;
+ PLArenaPool *arena;
SECItem prime;
SECItem base;
SECItem publicValue;
@@ -324,7 +315,7 @@ struct DHPublicKeyStr {
typedef struct DHPublicKeyStr DHPublicKey;
struct DHPrivateKeyStr {
- PLArenaPool * arena;
+ PLArenaPool *arena;
SECItem prime;
SECItem base;
SECItem publicValue;
@@ -338,85 +329,87 @@ typedef struct DHPrivateKeyStr DHPrivateKey;
*/
/*
-** The ECParams data structures can encode elliptic curve
+** The ECParams data structures can encode elliptic curve
** parameters for both GFp and GF2m curves.
*/
typedef enum { ec_params_explicit,
- ec_params_named
+ ec_params_named
} ECParamsType;
typedef enum { ec_field_GFp = 1,
- ec_field_GF2m
+ ec_field_GF2m,
+ ec_field_plain
} ECFieldType;
struct ECFieldIDStr {
- int size; /* field size in bits */
+ int size; /* field size in bits */
ECFieldType type;
union {
- SECItem prime; /* prime p for (GFp) */
- SECItem poly; /* irreducible binary polynomial for (GF2m) */
+ 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 k1; /* first coefficient of pentanomial or
+ * the only coefficient of trinomial
*/
- int k2; /* two remaining coefficients of pentanomial */
- int k3;
+ 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 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;
+ PLArenaPool *arena;
+ ECParamsType type;
+ ECFieldID fieldID;
+ ECCurve curve;
+ SECItem base;
+ SECItem order;
+ int cofactor;
+ SECItem DEREncoding;
+ ECCurveName name;
+ SECItem curveOID;
+ int pointSize;
};
typedef struct ECParamsStr ECParams;
struct ECPublicKeyStr {
- ECParams ecParams;
- SECItem publicValue; /* elliptic curve point encoded as
- * octet stream.
- */
+ 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 */
+ 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 *(*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 (*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);
+ unsigned int *outputLen,
+ unsigned int maxOutputLen,
+ const unsigned char *input,
+ unsigned int inputLen);
#endif /* _BLAPIT_H_ */
diff --git a/nss/lib/freebl/blname.c b/nss/lib/freebl/blname.c
new file mode 100644
index 0000000..4bad74a
--- /dev/null
+++ b/nss/lib/freebl/blname.c
@@ -0,0 +1,100 @@
+/*
+ * blname.c - determine the freebl library name.
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.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 defined(FREEBL_LOWHASH)
+static const char* default_name =
+ SHLIB_PREFIX "freeblpriv" SHLIB_VERSION "." SHLIB_SUFFIX;
+#else
+static const char* default_name =
+ SHLIB_PREFIX "freebl" SHLIB_VERSION "." SHLIB_SUFFIX;
+#endif
+
+/* 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)
+#include <unistd.h>
+
+/* 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
diff --git a/nss/lib/freebl/camellia.c b/nss/lib/freebl/camellia.c
index 07ae425..8a7bcb0 100644
--- a/nss/lib/freebl/camellia.c
+++ b/nss/lib/freebl/camellia.c
@@ -15,7 +15,6 @@
#include "camellia.h"
#include "sha_fast.h" /* for SHA_HTONL and related configuration macros */
-
/* key constants */
#define CAMELLIA_SIGMA1L (0xA09E667FL)
@@ -35,8 +34,7 @@
* macros
*/
-
-#if defined(SHA_ALLOW_UNALIGNED_ACCESS)
+#if defined(HAVE_UNALIGNED_ACCESS)
/* require a CPU that allows unaligned access */
@@ -44,22 +42,24 @@
#define CAMELLIA_NEED_TMP_VARIABLE 1
#endif
-# define GETU32(p) SHA_HTONL(*((PRUint32 *)(p)))
-# define PUTU32(ct, st) {*((PRUint32 *)(ct)) = SHA_HTONL(st);}
+#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 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); }
+#define PUTU32(ct, st) \
+ { \
+ (ct)[0] = (PRUint8)((st) >> 24); \
+ (ct)[1] = (PRUint8)((st) >> 16); \
+ (ct)[2] = (PRUint8)((st) >> 8); \
+ (ct)[3] = (PRUint8)(st); \
+ }
#endif
@@ -73,367 +73,365 @@
/* 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_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)
-
+#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)
-
+ 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,
+ 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,
+ 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,
+ 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,
+ 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)
+void
+camellia_setup128(const unsigned char *key, PRUint32 *subkey)
{
PRUint32 kll, klr, krl, krr;
PRUint32 il, ir, t0, t1, w0, w1;
@@ -447,106 +445,157 @@ void camellia_setup128(const unsigned char *key, PRUint32 *subkey)
/**
* k == kll || klr || krl || krr (|| is concatination)
*/
- kll = GETU32(key );
- klr = GETU32(key + 4);
- krl = GETU32(key + 8);
+ 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;
+ 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;
+ 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;
+ 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;
+ 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;
+ 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;
+ 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;
+ 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);
+ 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_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_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_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;
+ 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;
+ 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;
+ 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;
+ 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;
+ 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;
+ 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;
+ 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;
-
+ 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(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(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);
+ 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 = 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;
+ 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;
+ 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);
@@ -582,7 +631,7 @@ void camellia_setup128(const unsigned char *key, PRUint32 *subkey)
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);
+ dw = tl & subl(16), tr = subr(18) ^ CAMELLIA_RL1(dw);
CamelliaSubkeyL(15) = subl(14) ^ tl;
CamelliaSubkeyR(15) = subr(14) ^ tr;
CamelliaSubkeyL(16) = subl(16);
@@ -590,7 +639,7 @@ void camellia_setup128(const unsigned char *key, PRUint32 *subkey)
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);
+ 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);
@@ -647,11 +696,12 @@ void camellia_setup128(const unsigned char *key, PRUint32 *subkey)
return;
}
-void camellia_setup256(const unsigned char *key, PRUint32 *subkey)
+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 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];
@@ -664,146 +714,217 @@ void camellia_setup256(const unsigned char *key, PRUint32 *subkey)
* (|| is concatination)
*/
- kll = GETU32(key );
- klr = GETU32(key + 4);
- krl = GETU32(key + 8);
- krr = GETU32(key + 12);
+ 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;
+ 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;
+ 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;
+ 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;
+ 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;
+ 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;
+ 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;
+ 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;
+ 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;
+ 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;
+ 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_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_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_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;
+ CAMELLIA_SIGMA4L, CAMELLIA_SIGMA4R,
+ w0, w1, il, ir, t0, t1);
+ kll ^= w0;
+ klr ^= w1;
/* generate KB */
- krll ^= kll; krlr ^= klr;
- krrl ^= krl; krrr ^= krr;
+ 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_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;
+ 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;
+ 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;
+ 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;
+ 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;
+ 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;
+ 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;
+ 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;
+ 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(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(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(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);
+ 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 = 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;
+ 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;
+ 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;
+ 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);
@@ -866,7 +987,7 @@ void camellia_setup256(const unsigned char *key, PRUint32 *subkey)
CamelliaSubkeyR(24) = subr(24);
CamelliaSubkeyL(25) = subl(25);
CamelliaSubkeyR(25) = subr(25);
- tl = subl(23) ^ (subr(23) & ~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);
@@ -931,36 +1052,36 @@ void camellia_setup256(const unsigned char *key, PRUint32 *subkey)
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;
-
+ CamelliaSubkeyR(31) = CamelliaSubkeyL(31) ^ dw, CamelliaSubkeyL(31) = dw;
+
return;
}
-void camellia_setup192(const unsigned char *key, PRUint32 *subkey)
+void
+camellia_setup192(const unsigned char *key, PRUint32 *subkey)
{
unsigned char kk[32];
- PRUint32 krll, krlr, krrl,krrr;
+ PRUint32 krll, krlr, krrl, krrr;
memcpy(kk, key, 24);
- memcpy((unsigned char *)&krll, key+16,4);
- memcpy((unsigned char *)&krlr, key+20,4);
+ 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);
+ 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
+SECStatus NO_SANITIZE_ALIGNMENT
camellia_encrypt128(const PRUint32 *subkey,
- unsigned char *output,
- const unsigned char *input)
+ unsigned char *output,
+ const unsigned char *input)
{
PRUint32 il, ir, t0, t1;
PRUint32 io[4];
@@ -969,81 +1090,81 @@ camellia_encrypt128(const PRUint32 *subkey,
#endif
io[0] = GETU32(input);
- io[1] = GETU32(input+4);
- io[2] = GETU32(input+8);
- io[3] = GETU32(input+12);
+ 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_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);
@@ -1057,100 +1178,100 @@ camellia_encrypt128(const PRUint32 *subkey,
io[3] = t1;
PUTU32(output, io[0]);
- PUTU32(output+4, io[1]);
- PUTU32(output+8, io[2]);
- PUTU32(output+12, io[3]);
+ PUTU32(output + 4, io[1]);
+ PUTU32(output + 8, io[2]);
+ PUTU32(output + 12, io[3]);
return SECSuccess;
}
-SECStatus
+SECStatus NO_SANITIZE_ALIGNMENT
camellia_decrypt128(const PRUint32 *subkey,
- unsigned char *output,
- const unsigned char *input)
+ unsigned char *output,
+ const unsigned char *input)
{
- PRUint32 il,ir,t0,t1; /* temporary valiables */
+ 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);
+ 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);
+ 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);
@@ -1164,9 +1285,9 @@ camellia_decrypt128(const PRUint32 *subkey,
io[3] = t1;
PUTU32(output, io[0]);
- PUTU32(output+4, io[1]);
- PUTU32(output+8, io[2]);
- PUTU32(output+12, io[3]);
+ PUTU32(output + 4, io[1]);
+ PUTU32(output + 8, io[2]);
+ PUTU32(output + 12, io[3]);
return SECSuccess;
}
@@ -1174,117 +1295,117 @@ camellia_decrypt128(const PRUint32 *subkey,
/**
* stuff for 192 and 256bit encryption/decryption
*/
-SECStatus
+SECStatus NO_SANITIZE_ALIGNMENT
camellia_encrypt256(const PRUint32 *subkey,
- unsigned char *output,
- const unsigned char *input)
+ unsigned char *output,
+ const unsigned char *input)
{
- PRUint32 il,ir,t0,t1; /* temporary valiables */
+ 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);
+ 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);
+ 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);
@@ -1298,124 +1419,124 @@ camellia_encrypt256(const PRUint32 *subkey,
io[3] = t1;
PUTU32(output, io[0]);
- PUTU32(output+4, io[1]);
- PUTU32(output+8, io[2]);
- PUTU32(output+12, io[3]);
+ PUTU32(output + 4, io[1]);
+ PUTU32(output + 8, io[2]);
+ PUTU32(output + 12, io[3]);
return SECSuccess;
}
-SECStatus
+SECStatus NO_SANITIZE_ALIGNMENT
camellia_decrypt256(const PRUint32 *subkey,
- unsigned char *output,
- const unsigned char *input)
+ unsigned char *output,
+ const unsigned char *input)
{
- PRUint32 il,ir,t0,t1; /* temporary valiables */
+ 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);
+ 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);
+ 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);
@@ -1429,51 +1550,49 @@ camellia_decrypt256(const PRUint32 *subkey,
io[3] = t1;
PUTU32(output, io[0]);
- PUTU32(output+4, io[1]);
- PUTU32(output+8, io[2]);
- PUTU32(output+12, io[3]);
+ 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,
+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;
+ 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
+SECStatus
camellia_encryptECB(CamelliaContext *cx, unsigned char *output,
unsigned int *outputLen, unsigned int maxOutputLen,
const unsigned char *input, unsigned int inputLen)
@@ -1481,20 +1600,20 @@ camellia_encryptECB(CamelliaContext *cx, unsigned char *output,
CamelliaBlockFunc *encryptor;
encryptor = (cx->keysize == 16)
- ? &camellia_encrypt128
- : &camellia_encrypt256;
+ ? &camellia_encrypt128
+ : &camellia_encrypt256;
while (inputLen > 0) {
- (*encryptor)(cx->expandedKey, output, input);
-
- output += CAMELLIA_BLOCK_SIZE;
- input += CAMELLIA_BLOCK_SIZE;
- inputLen -= CAMELLIA_BLOCK_SIZE;
+ (*encryptor)(cx->expandedKey, output, input);
+
+ output += CAMELLIA_BLOCK_SIZE;
+ input += CAMELLIA_BLOCK_SIZE;
+ inputLen -= CAMELLIA_BLOCK_SIZE;
}
return SECSuccess;
}
-SECStatus
+SECStatus
camellia_encryptCBC(CamelliaContext *cx, unsigned char *output,
unsigned int *outputLen, unsigned int maxOutputLen,
const unsigned char *input, unsigned int inputLen)
@@ -1505,31 +1624,31 @@ camellia_encryptCBC(CamelliaContext *cx, unsigned char *output,
CamelliaBlockFunc *encryptor;
if (!inputLen)
- return SECSuccess;
+ return SECSuccess;
lastblock = cx->iv;
encryptor = (cx->keysize == 16)
- ? &camellia_encrypt128
- : &camellia_encrypt256;
+ ? &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;
+ /* 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
+SECStatus
camellia_decryptECB(CamelliaContext *cx, unsigned char *output,
unsigned int *outputLen, unsigned int maxOutputLen,
const unsigned char *input, unsigned int inputLen)
@@ -1537,22 +1656,21 @@ camellia_decryptECB(CamelliaContext *cx, unsigned char *output,
CamelliaBlockFunc *decryptor;
decryptor = (cx->keysize == 16)
- ? &camellia_decrypt128
- : &camellia_decrypt256;
-
+ ? &camellia_decrypt128
+ : &camellia_decrypt256;
while (inputLen > 0) {
- (*decryptor)(cx->expandedKey, output, input);
+ (*decryptor)(cx->expandedKey, output, input);
- output += CAMELLIA_BLOCK_SIZE;
- input += CAMELLIA_BLOCK_SIZE;
- inputLen -= CAMELLIA_BLOCK_SIZE;
+ output += CAMELLIA_BLOCK_SIZE;
+ input += CAMELLIA_BLOCK_SIZE;
+ inputLen -= CAMELLIA_BLOCK_SIZE;
}
return SECSuccess;
}
-SECStatus
+SECStatus
camellia_decryptCBC(CamelliaContext *cx, unsigned char *output,
unsigned int *outputLen, unsigned int maxOutputLen,
const unsigned char *input, unsigned int inputLen)
@@ -1563,36 +1681,34 @@ camellia_decryptCBC(CamelliaContext *cx, unsigned char *output,
unsigned char newIV[CAMELLIA_BLOCK_SIZE];
CamelliaBlockFunc *decryptor;
+ if (!inputLen)
+ return SECSuccess;
+ PORT_Assert(output - input >= 0 || input - output >= (int)inputLen);
- if (!inputLen)
- return SECSuccess;
-
- PORT_Assert(output - input >= 0 || input - output >= (int)inputLen );
-
- in = input + (inputLen - CAMELLIA_BLOCK_SIZE);
+ 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;
+ ? &camellia_decrypt128
+ : &camellia_decrypt256;
while (inputLen > CAMELLIA_BLOCK_SIZE) {
- (*decryptor)(cx->expandedKey, out, in);
+ (*decryptor)(cx->expandedKey, out, in);
- for (j=0; j<CAMELLIA_BLOCK_SIZE; ++j)
- out[j] ^= in[(int)(j - CAMELLIA_BLOCK_SIZE)];
+ 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;
+ out -= CAMELLIA_BLOCK_SIZE;
+ in -= CAMELLIA_BLOCK_SIZE;
+ inputLen -= CAMELLIA_BLOCK_SIZE;
}
if (in == input) {
- (*decryptor)(cx->expandedKey, out, in);
+ (*decryptor)(cx->expandedKey, out, in);
- for (j=0; j<CAMELLIA_BLOCK_SIZE; ++j)
- out[j] ^= cx->iv[j];
+ for (j = 0; j < CAMELLIA_BLOCK_SIZE; ++j)
+ out[j] ^= cx->iv[j];
}
memcpy(cx->iv, newIV, CAMELLIA_BLOCK_SIZE);
return SECSuccess;
@@ -1610,39 +1726,39 @@ Camellia_AllocateContext(void)
return PORT_ZNew(CamelliaContext);
}
-SECStatus
+SECStatus
Camellia_InitContext(CamelliaContext *cx, const unsigned char *key,
- unsigned int keysize,
- const unsigned char *iv, int mode, unsigned int encrypt,
- unsigned int unused)
+ 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;
+ (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;
+ PORT_SetError(SEC_ERROR_INVALID_ARGS);
+ return SECFailure;
}
if (mode == NSS_CAMELLIA_CBC && iv == NULL) {
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- return SECFailure;
+ PORT_SetError(SEC_ERROR_INVALID_ARGS);
+ return SECFailure;
}
if (!cx) {
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- return SECFailure;
+ 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;
+ memcpy(cx->iv, iv, CAMELLIA_BLOCK_SIZE);
+ cx->worker = (encrypt) ? &camellia_encryptCBC : &camellia_decryptCBC;
} else {
- cx->worker = (encrypt) ? &camellia_encryptECB : &camellia_decryptECB;
+ cx->worker = (encrypt) ? &camellia_encryptECB : &camellia_decryptECB;
}
/* Generate expanded key */
if (camellia_key_expansion(cx, key, keysize) != SECSuccess)
- goto cleanup;
+ goto cleanup;
return SECSuccess;
cleanup:
@@ -1654,66 +1770,65 @@ cleanup:
* create a new context for Camellia operations
*/
-
CamelliaContext *
-Camellia_CreateContext(const unsigned char *key, const unsigned char *iv,
+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;
+ (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;
+ PORT_SetError(SEC_ERROR_INVALID_ARGS);
+ return NULL;
}
if (mode == NSS_CAMELLIA_CBC && iv == NULL) {
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- return NULL;
+ PORT_SetError(SEC_ERROR_INVALID_ARGS);
+ return NULL;
}
cx = PORT_ZNew(CamelliaContext);
if (!cx) {
- PORT_SetError(SEC_ERROR_NO_MEMORY);
- return NULL;
+ 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;
+ memcpy(cx->iv, iv, CAMELLIA_BLOCK_SIZE);
+ cx->worker = (encrypt) ? &camellia_encryptCBC : &camellia_decryptCBC;
} else {
- cx->worker = (encrypt) ? &camellia_encryptECB : &camellia_decryptECB;
+ 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;
+ goto cleanup;
return cx;
- cleanup:
+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
+void
Camellia_DestroyContext(CamelliaContext *cx, PRBool freeit)
{
if (cx)
- memset(cx, 0, sizeof *cx);
+ memset(cx, 0, sizeof *cx);
if (freeit)
- PORT_Free(cx);
+ PORT_Free(cx);
}
/*
@@ -1722,7 +1837,7 @@ Camellia_DestroyContext(CamelliaContext *cx, PRBool freeit)
* Encrypt an arbitrary-length buffer. The output buffer must already be
* allocated to at least inputLen.
*/
-SECStatus
+SECStatus
Camellia_Encrypt(CamelliaContext *cx, unsigned char *output,
unsigned int *outputLen, unsigned int maxOutputLen,
const unsigned char *input, unsigned int inputLen)
@@ -1730,23 +1845,23 @@ Camellia_Encrypt(CamelliaContext *cx, unsigned char *output,
/* Check args */
if (cx == NULL || output == NULL || input == NULL ||
- outputLen == NULL) {
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- return SECFailure;
+ outputLen == NULL) {
+ PORT_SetError(SEC_ERROR_INVALID_ARGS);
+ return SECFailure;
}
if (inputLen % CAMELLIA_BLOCK_SIZE != 0) {
- PORT_SetError(SEC_ERROR_INPUT_LEN);
- return SECFailure;
+ PORT_SetError(SEC_ERROR_INPUT_LEN);
+ return SECFailure;
}
if (maxOutputLen < inputLen) {
- PORT_SetError(SEC_ERROR_OUTPUT_LEN);
- return SECFailure;
+ PORT_SetError(SEC_ERROR_OUTPUT_LEN);
+ return SECFailure;
}
*outputLen = inputLen;
- return (*cx->worker)(cx, output, outputLen, maxOutputLen,
- input, inputLen);
+ return (*cx->worker)(cx, output, outputLen, maxOutputLen,
+ input, inputLen);
}
/*
@@ -1755,28 +1870,27 @@ Camellia_Encrypt(CamelliaContext *cx, unsigned char *output,
* Decrypt and arbitrary-length buffer. The output buffer must already be
* allocated to at least inputLen.
*/
-SECStatus
+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 (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;
+ PORT_SetError(SEC_ERROR_INPUT_LEN);
+ return SECFailure;
}
if (maxOutputLen < inputLen) {
- PORT_SetError(SEC_ERROR_OUTPUT_LEN);
- return SECFailure;
+ PORT_SetError(SEC_ERROR_OUTPUT_LEN);
+ return SECFailure;
}
*outputLen = inputLen;
- return (*cx->worker)(cx, output, outputLen, maxOutputLen,
- input, inputLen);
+ return (*cx->worker)(cx, output, outputLen, maxOutputLen,
+ input, inputLen);
}
diff --git a/nss/lib/freebl/camellia.h b/nss/lib/freebl/camellia.h
index 0f76005..15114db 100644
--- a/nss/lib/freebl/camellia.h
+++ b/nss/lib/freebl/camellia.h
@@ -9,19 +9,19 @@
#define CAMELLIA_MIN_KEYSIZE 16 /* bytes */
#define CAMELLIA_MAX_KEYSIZE 32 /* bytes */
-#define CAMELLIA_MAX_EXPANDEDKEY (34*2) /* 32bit unit */
+#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);
+ 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);
+typedef SECStatus CamelliaBlockFunc(const PRUint32 *subkey,
+ unsigned char *output,
+ const unsigned char *input);
/* CamelliaContextStr
*
@@ -32,11 +32,10 @@ typedef SECStatus CamelliaBlockFunc(const PRUint32 *subkey,
* 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];
+struct CamelliaContextStr {
+ PRUint32 keysize; /* bytes */
+ CamelliaFunc *worker;
+ PRUint32 expandedKey[CAMELLIA_MAX_EXPANDEDKEY];
PRUint8 iv[CAMELLIA_BLOCK_SIZE];
};
diff --git a/nss/lib/freebl/chacha20.c b/nss/lib/freebl/chacha20.c
new file mode 100644
index 0000000..f55d1e6
--- /dev/null
+++ b/nss/lib/freebl/chacha20.c
@@ -0,0 +1,119 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+/* Adopted from the public domain code in NaCl by djb. */
+
+#include <string.h>
+#include <stdio.h>
+
+#include "prtypes.h"
+#include "secport.h"
+#include "chacha20.h"
+
+#if defined(_MSC_VER)
+#pragma intrinsic(_lrotl)
+#define ROTL32(x, n) _lrotl(x, n)
+#else
+#define ROTL32(x, n) ((x << n) | (x >> ((8 * sizeof x) - n)))
+#endif
+
+#define ROTATE(v, c) ROTL32((v), (c))
+
+#define U32TO8_LITTLE(p, v) \
+ { \
+ (p)[0] = ((v)) & 0xff; \
+ (p)[1] = ((v) >> 8) & 0xff; \
+ (p)[2] = ((v) >> 16) & 0xff; \
+ (p)[3] = ((v) >> 24) & 0xff; \
+ }
+#define U8TO32_LITTLE(p) \
+ (((PRUint32)((p)[0])) | ((PRUint32)((p)[1]) << 8) | \
+ ((PRUint32)((p)[2]) << 16) | ((PRUint32)((p)[3]) << 24))
+
+#define QUARTERROUND(x, a, b, c, d) \
+ x[a] = x[a] + x[b]; \
+ x[d] = ROTATE(x[d] ^ x[a], 16); \
+ x[c] = x[c] + x[d]; \
+ x[b] = ROTATE(x[b] ^ x[c], 12); \
+ x[a] = x[a] + x[b]; \
+ x[d] = ROTATE(x[d] ^ x[a], 8); \
+ x[c] = x[c] + x[d]; \
+ x[b] = ROTATE(x[b] ^ x[c], 7);
+
+static void
+ChaChaCore(unsigned char output[64], const PRUint32 input[16], int num_rounds)
+{
+ PRUint32 x[16];
+ int i;
+
+ PORT_Memcpy(x, input, sizeof(PRUint32) * 16);
+ for (i = num_rounds; i > 0; i -= 2) {
+ QUARTERROUND(x, 0, 4, 8, 12)
+ QUARTERROUND(x, 1, 5, 9, 13)
+ QUARTERROUND(x, 2, 6, 10, 14)
+ QUARTERROUND(x, 3, 7, 11, 15)
+ QUARTERROUND(x, 0, 5, 10, 15)
+ QUARTERROUND(x, 1, 6, 11, 12)
+ QUARTERROUND(x, 2, 7, 8, 13)
+ QUARTERROUND(x, 3, 4, 9, 14)
+ }
+
+ for (i = 0; i < 16; ++i) {
+ x[i] = x[i] + input[i];
+ }
+ for (i = 0; i < 16; ++i) {
+ U32TO8_LITTLE(output + 4 * i, x[i]);
+ }
+}
+
+static const unsigned char sigma[16] = "expand 32-byte k";
+
+void
+ChaCha20XOR(unsigned char *out, const unsigned char *in, unsigned int inLen,
+ const unsigned char key[32], const unsigned char nonce[12],
+ uint32_t counter)
+{
+ unsigned char block[64];
+ PRUint32 input[16];
+ unsigned int i;
+
+ input[4] = U8TO32_LITTLE(key + 0);
+ input[5] = U8TO32_LITTLE(key + 4);
+ input[6] = U8TO32_LITTLE(key + 8);
+ input[7] = U8TO32_LITTLE(key + 12);
+
+ input[8] = U8TO32_LITTLE(key + 16);
+ input[9] = U8TO32_LITTLE(key + 20);
+ input[10] = U8TO32_LITTLE(key + 24);
+ input[11] = U8TO32_LITTLE(key + 28);
+
+ input[0] = U8TO32_LITTLE(sigma + 0);
+ input[1] = U8TO32_LITTLE(sigma + 4);
+ input[2] = U8TO32_LITTLE(sigma + 8);
+ input[3] = U8TO32_LITTLE(sigma + 12);
+
+ input[12] = counter;
+ input[13] = U8TO32_LITTLE(nonce + 0);
+ input[14] = U8TO32_LITTLE(nonce + 4);
+ input[15] = U8TO32_LITTLE(nonce + 8);
+
+ while (inLen >= 64) {
+ ChaChaCore(block, input, 20);
+ for (i = 0; i < 64; i++) {
+ out[i] = in[i] ^ block[i];
+ }
+
+ input[12]++;
+ inLen -= 64;
+ in += 64;
+ out += 64;
+ }
+
+ if (inLen > 0) {
+ ChaChaCore(block, input, 20);
+ for (i = 0; i < inLen; i++) {
+ out[i] = in[i] ^ block[i];
+ }
+ }
+}
diff --git a/nss/lib/freebl/chacha20.h b/nss/lib/freebl/chacha20.h
new file mode 100644
index 0000000..7e396fa
--- /dev/null
+++ b/nss/lib/freebl/chacha20.h
@@ -0,0 +1,26 @@
+/*
+ * chacha20.h - header file for ChaCha20 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/. */
+
+#ifndef FREEBL_CHACHA20_H_
+#define FREEBL_CHACHA20_H_
+
+#if defined(_MSC_VER) && _MSC_VER < 1600
+#include "prtypes.h"
+typedef PRUint32 uint32_t;
+typedef PRUint64 uint64_t;
+#else
+#include <stdint.h>
+#endif
+
+/* ChaCha20XOR encrypts |inLen| bytes from |in| with the given key and
+ * nonce and writes the result to |out|, which may be equal to |in|. The
+ * initial block counter is specified by |counter|. */
+extern void ChaCha20XOR(unsigned char *out, const unsigned char *in,
+ unsigned int inLen, const unsigned char key[32],
+ const unsigned char nonce[12], uint32_t counter);
+
+#endif /* FREEBL_CHACHA20_H_ */
diff --git a/nss/lib/freebl/chacha20_vec.c b/nss/lib/freebl/chacha20_vec.c
new file mode 100644
index 0000000..12f94d8
--- /dev/null
+++ b/nss/lib/freebl/chacha20_vec.c
@@ -0,0 +1,327 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.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 implementation is by Ted Krovetz and was submitted to SUPERCOP and
+ * marked as public domain. It was been altered to allow for non-aligned inputs
+ * and to allow the block counter to be passed in specifically. */
+
+#include <string.h>
+
+#include "chacha20.h"
+#include "blapii.h"
+
+#ifndef CHACHA_RNDS
+#define CHACHA_RNDS 20 /* 8 (high speed), 20 (conservative), 12 (middle) */
+#endif
+
+/* Architecture-neutral way to specify 16-byte vector of ints */
+typedef unsigned vec __attribute__((vector_size(16)));
+
+/* This implementation is designed for Neon, SSE and AltiVec machines. The
+ * following specify how to do certain vector operations efficiently on
+ * each architecture, using intrinsics.
+ * This implementation supports parallel processing of multiple blocks,
+ * including potentially using general-purpose registers.
+ */
+#if __ARM_NEON__
+#include <arm_neon.h>
+#define GPR_TOO 1
+#define VBPI 2
+#define ONE (vec) vsetq_lane_u32(1, vdupq_n_u32(0), 0)
+#define LOAD(m) (vec)(*((vec *)(m)))
+#define STORE(m, r) (*((vec *)(m))) = (r)
+#define ROTV1(x) (vec) vextq_u32((uint32x4_t)x, (uint32x4_t)x, 1)
+#define ROTV2(x) (vec) vextq_u32((uint32x4_t)x, (uint32x4_t)x, 2)
+#define ROTV3(x) (vec) vextq_u32((uint32x4_t)x, (uint32x4_t)x, 3)
+#define ROTW16(x) (vec) vrev32q_u16((uint16x8_t)x)
+#if __clang__
+#define ROTW7(x) (x << ((vec){ 7, 7, 7, 7 })) ^ (x >> ((vec){ 25, 25, 25, 25 }))
+#define ROTW8(x) (x << ((vec){ 8, 8, 8, 8 })) ^ (x >> ((vec){ 24, 24, 24, 24 }))
+#define ROTW12(x) (x << ((vec){ 12, 12, 12, 12 })) ^ (x >> ((vec){ 20, 20, 20, 20 }))
+#else
+#define ROTW7(x) (vec) vsriq_n_u32(vshlq_n_u32((uint32x4_t)x, 7), (uint32x4_t)x, 25)
+#define ROTW8(x) (vec) vsriq_n_u32(vshlq_n_u32((uint32x4_t)x, 8), (uint32x4_t)x, 24)
+#define ROTW12(x) (vec) vsriq_n_u32(vshlq_n_u32((uint32x4_t)x, 12), (uint32x4_t)x, 20)
+#endif
+#elif __SSE2__
+#include <emmintrin.h>
+#define GPR_TOO 0
+#if __clang__
+#define VBPI 4
+#else
+#define VBPI 3
+#endif
+#define ONE (vec) _mm_set_epi32(0, 0, 0, 1)
+#define LOAD(m) (vec) _mm_loadu_si128((__m128i *)(m))
+#define STORE(m, r) _mm_storeu_si128((__m128i *)(m), (__m128i)(r))
+#define ROTV1(x) (vec) _mm_shuffle_epi32((__m128i)x, _MM_SHUFFLE(0, 3, 2, 1))
+#define ROTV2(x) (vec) _mm_shuffle_epi32((__m128i)x, _MM_SHUFFLE(1, 0, 3, 2))
+#define ROTV3(x) (vec) _mm_shuffle_epi32((__m128i)x, _MM_SHUFFLE(2, 1, 0, 3))
+#define ROTW7(x) (vec)(_mm_slli_epi32((__m128i)x, 7) ^ _mm_srli_epi32((__m128i)x, 25))
+#define ROTW12(x) (vec)(_mm_slli_epi32((__m128i)x, 12) ^ _mm_srli_epi32((__m128i)x, 20))
+#if __SSSE3__
+#include <tmmintrin.h>
+#define ROTW8(x) (vec) _mm_shuffle_epi8((__m128i)x, _mm_set_epi8(14, 13, 12, 15, 10, 9, 8, 11, 6, 5, 4, 7, 2, 1, 0, 3))
+#define ROTW16(x) (vec) _mm_shuffle_epi8((__m128i)x, _mm_set_epi8(13, 12, 15, 14, 9, 8, 11, 10, 5, 4, 7, 6, 1, 0, 3, 2))
+#else
+#define ROTW8(x) (vec)(_mm_slli_epi32((__m128i)x, 8) ^ _mm_srli_epi32((__m128i)x, 24))
+#define ROTW16(x) (vec)(_mm_slli_epi32((__m128i)x, 16) ^ _mm_srli_epi32((__m128i)x, 16))
+#endif
+#else
+#error-- Implementation supports only machines with neon or SSE2
+#endif
+
+#ifndef REVV_BE
+#define REVV_BE(x) (x)
+#endif
+
+#ifndef REVW_BE
+#define REVW_BE(x) (x)
+#endif
+
+#define BPI (VBPI + GPR_TOO) /* Blocks computed per loop iteration */
+
+#define DQROUND_VECTORS(a, b, c, d) \
+ a += b; \
+ d ^= a; \
+ d = ROTW16(d); \
+ c += d; \
+ b ^= c; \
+ b = ROTW12(b); \
+ a += b; \
+ d ^= a; \
+ d = ROTW8(d); \
+ c += d; \
+ b ^= c; \
+ b = ROTW7(b); \
+ b = ROTV1(b); \
+ c = ROTV2(c); \
+ d = ROTV3(d); \
+ a += b; \
+ d ^= a; \
+ d = ROTW16(d); \
+ c += d; \
+ b ^= c; \
+ b = ROTW12(b); \
+ a += b; \
+ d ^= a; \
+ d = ROTW8(d); \
+ c += d; \
+ b ^= c; \
+ b = ROTW7(b); \
+ b = ROTV3(b); \
+ c = ROTV2(c); \
+ d = ROTV1(d);
+
+#define QROUND_WORDS(a, b, c, d) \
+ a = a + b; \
+ d ^= a; \
+ d = d << 16 | d >> 16; \
+ c = c + d; \
+ b ^= c; \
+ b = b << 12 | b >> 20; \
+ a = a + b; \
+ d ^= a; \
+ d = d << 8 | d >> 24; \
+ c = c + d; \
+ b ^= c; \
+ b = b << 7 | b >> 25;
+
+#define WRITE_XOR(in, op, d, v0, v1, v2, v3) \
+ STORE(op + d + 0, LOAD(in + d + 0) ^ REVV_BE(v0)); \
+ STORE(op + d + 4, LOAD(in + d + 4) ^ REVV_BE(v1)); \
+ STORE(op + d + 8, LOAD(in + d + 8) ^ REVV_BE(v2)); \
+ STORE(op + d + 12, LOAD(in + d + 12) ^ REVV_BE(v3));
+
+void NO_SANITIZE_ALIGNMENT
+ChaCha20XOR(unsigned char *out, const unsigned char *in, unsigned int inlen,
+ const unsigned char key[32], const unsigned char nonce[12],
+ uint32_t counter)
+{
+ unsigned iters, i, *op = (unsigned *)out, *ip = (unsigned *)in, *kp;
+#if defined(__ARM_NEON__)
+ unsigned *np;
+#endif
+ vec s0, s1, s2, s3;
+#if !defined(__ARM_NEON__) && !defined(__SSE2__)
+ __attribute__((aligned(16))) unsigned key[8], nonce[4];
+#endif
+ __attribute__((aligned(16))) unsigned chacha_const[] =
+ { 0x61707865, 0x3320646E, 0x79622D32, 0x6B206574 };
+#if defined(__ARM_NEON__) || defined(__SSE2__)
+ kp = (unsigned *)key;
+#else
+ ((vec *)key)[0] = REVV_BE(((vec *)key)[0]);
+ ((vec *)key)[1] = REVV_BE(((vec *)key)[1]);
+ ((unsigned *)nonce)[0] = REVW_BE(((unsigned *)nonce)[0]);
+ ((unsigned *)nonce)[1] = REVW_BE(((unsigned *)nonce)[1]);
+ ((unsigned *)nonce)[2] = REVW_BE(((unsigned *)nonce)[2]);
+ ((unsigned *)nonce)[3] = REVW_BE(((unsigned *)nonce)[3]);
+ kp = (unsigned *)key;
+ np = (unsigned *)nonce;
+#endif
+#if defined(__ARM_NEON__)
+ np = (unsigned *)nonce;
+#endif
+ s0 = LOAD(chacha_const);
+ s1 = LOAD(&((vec *)kp)[0]);
+ s2 = LOAD(&((vec *)kp)[1]);
+ s3 = (vec){
+ counter,
+ ((uint32_t *)nonce)[0],
+ ((uint32_t *)nonce)[1],
+ ((uint32_t *)nonce)[2]
+ };
+
+ for (iters = 0; iters < inlen / (BPI * 64); iters++) {
+#if GPR_TOO
+ register unsigned x0, x1, x2, x3, x4, x5, x6, x7, x8,
+ x9, x10, x11, x12, x13, x14, x15;
+#endif
+#if VBPI > 2
+ vec v8, v9, v10, v11;
+#endif
+#if VBPI > 3
+ vec v12, v13, v14, v15;
+#endif
+
+ vec v0, v1, v2, v3, v4, v5, v6, v7;
+ v4 = v0 = s0;
+ v5 = v1 = s1;
+ v6 = v2 = s2;
+ v3 = s3;
+ v7 = v3 + ONE;
+#if VBPI > 2
+ v8 = v4;
+ v9 = v5;
+ v10 = v6;
+ v11 = v7 + ONE;
+#endif
+#if VBPI > 3
+ v12 = v8;
+ v13 = v9;
+ v14 = v10;
+ v15 = v11 + ONE;
+#endif
+#if GPR_TOO
+ x0 = chacha_const[0];
+ x1 = chacha_const[1];
+ x2 = chacha_const[2];
+ x3 = chacha_const[3];
+ x4 = kp[0];
+ x5 = kp[1];
+ x6 = kp[2];
+ x7 = kp[3];
+ x8 = kp[4];
+ x9 = kp[5];
+ x10 = kp[6];
+ x11 = kp[7];
+ x12 = counter + BPI * iters + (BPI - 1);
+ x13 = np[0];
+ x14 = np[1];
+ x15 = np[2];
+#endif
+ for (i = CHACHA_RNDS / 2; i; i--) {
+ DQROUND_VECTORS(v0, v1, v2, v3)
+ DQROUND_VECTORS(v4, v5, v6, v7)
+#if VBPI > 2
+ DQROUND_VECTORS(v8, v9, v10, v11)
+#endif
+#if VBPI > 3
+ DQROUND_VECTORS(v12, v13, v14, v15)
+#endif
+#if GPR_TOO
+ QROUND_WORDS(x0, x4, x8, x12)
+ QROUND_WORDS(x1, x5, x9, x13)
+ QROUND_WORDS(x2, x6, x10, x14)
+ QROUND_WORDS(x3, x7, x11, x15)
+ QROUND_WORDS(x0, x5, x10, x15)
+ QROUND_WORDS(x1, x6, x11, x12)
+ QROUND_WORDS(x2, x7, x8, x13)
+ QROUND_WORDS(x3, x4, x9, x14)
+#endif
+ }
+
+ WRITE_XOR(ip, op, 0, v0 + s0, v1 + s1, v2 + s2, v3 + s3)
+ s3 += ONE;
+ WRITE_XOR(ip, op, 16, v4 + s0, v5 + s1, v6 + s2, v7 + s3)
+ s3 += ONE;
+#if VBPI > 2
+ WRITE_XOR(ip, op, 32, v8 + s0, v9 + s1, v10 + s2, v11 + s3)
+ s3 += ONE;
+#endif
+#if VBPI > 3
+ WRITE_XOR(ip, op, 48, v12 + s0, v13 + s1, v14 + s2, v15 + s3)
+ s3 += ONE;
+#endif
+ ip += VBPI * 16;
+ op += VBPI * 16;
+#if GPR_TOO
+ op[0] = REVW_BE(REVW_BE(ip[0]) ^ (x0 + chacha_const[0]));
+ op[1] = REVW_BE(REVW_BE(ip[1]) ^ (x1 + chacha_const[1]));
+ op[2] = REVW_BE(REVW_BE(ip[2]) ^ (x2 + chacha_const[2]));
+ op[3] = REVW_BE(REVW_BE(ip[3]) ^ (x3 + chacha_const[3]));
+ op[4] = REVW_BE(REVW_BE(ip[4]) ^ (x4 + kp[0]));
+ op[5] = REVW_BE(REVW_BE(ip[5]) ^ (x5 + kp[1]));
+ op[6] = REVW_BE(REVW_BE(ip[6]) ^ (x6 + kp[2]));
+ op[7] = REVW_BE(REVW_BE(ip[7]) ^ (x7 + kp[3]));
+ op[8] = REVW_BE(REVW_BE(ip[8]) ^ (x8 + kp[4]));
+ op[9] = REVW_BE(REVW_BE(ip[9]) ^ (x9 + kp[5]));
+ op[10] = REVW_BE(REVW_BE(ip[10]) ^ (x10 + kp[6]));
+ op[11] = REVW_BE(REVW_BE(ip[11]) ^ (x11 + kp[7]));
+ op[12] = REVW_BE(REVW_BE(ip[12]) ^ (x12 + counter + BPI * iters + (BPI - 1)));
+ op[13] = REVW_BE(REVW_BE(ip[13]) ^ (x13 + np[0]));
+ op[14] = REVW_BE(REVW_BE(ip[14]) ^ (x14 + np[1]));
+ op[15] = REVW_BE(REVW_BE(ip[15]) ^ (x15 + np[2]));
+ s3 += ONE;
+ ip += 16;
+ op += 16;
+#endif
+ }
+
+ for (iters = inlen % (BPI * 64) / 64; iters != 0; iters--) {
+ vec v0 = s0, v1 = s1, v2 = s2, v3 = s3;
+ for (i = CHACHA_RNDS / 2; i; i--) {
+ DQROUND_VECTORS(v0, v1, v2, v3);
+ }
+ WRITE_XOR(ip, op, 0, v0 + s0, v1 + s1, v2 + s2, v3 + s3)
+ s3 += ONE;
+ ip += 16;
+ op += 16;
+ }
+
+ inlen = inlen % 64;
+ if (inlen) {
+ __attribute__((aligned(16))) vec buf[4];
+ vec v0, v1, v2, v3;
+ v0 = s0;
+ v1 = s1;
+ v2 = s2;
+ v3 = s3;
+ for (i = CHACHA_RNDS / 2; i; i--) {
+ DQROUND_VECTORS(v0, v1, v2, v3);
+ }
+
+ if (inlen >= 16) {
+ STORE(op + 0, LOAD(ip + 0) ^ REVV_BE(v0 + s0));
+ if (inlen >= 32) {
+ STORE(op + 4, LOAD(ip + 4) ^ REVV_BE(v1 + s1));
+ if (inlen >= 48) {
+ STORE(op + 8, LOAD(ip + 8) ^ REVV_BE(v2 + s2));
+ buf[3] = REVV_BE(v3 + s3);
+ } else {
+ buf[2] = REVV_BE(v2 + s2);
+ }
+ } else {
+ buf[1] = REVV_BE(v1 + s1);
+ }
+ } else {
+ buf[0] = REVV_BE(v0 + s0);
+ }
+
+ for (i = inlen & ~15; i < inlen; i++) {
+ ((char *)op)[i] = ((char *)ip)[i] ^ ((char *)buf)[i];
+ }
+ }
+}
diff --git a/nss/lib/freebl/chacha20poly1305.c b/nss/lib/freebl/chacha20poly1305.c
new file mode 100644
index 0000000..cd265e1
--- /dev/null
+++ b/nss/lib/freebl/chacha20poly1305.c
@@ -0,0 +1,198 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.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 <string.h>
+#include <stdio.h>
+
+#include "seccomon.h"
+#include "secerr.h"
+#include "blapit.h"
+
+#ifndef NSS_DISABLE_CHACHAPOLY
+#include "poly1305.h"
+#include "chacha20.h"
+#include "chacha20poly1305.h"
+#endif
+
+/* Poly1305Do writes the Poly1305 authenticator of the given additional data
+ * and ciphertext to |out|. */
+#ifndef NSS_DISABLE_CHACHAPOLY
+static void
+Poly1305Do(unsigned char *out, const unsigned char *ad, unsigned int adLen,
+ const unsigned char *ciphertext, unsigned int ciphertextLen,
+ const unsigned char key[32])
+{
+ poly1305_state state;
+ unsigned int j;
+ unsigned char lengthBytes[8];
+ static const unsigned char zeros[15];
+ unsigned int i;
+
+ Poly1305Init(&state, key);
+ Poly1305Update(&state, ad, adLen);
+ if (adLen % 16 > 0) {
+ Poly1305Update(&state, zeros, 16 - adLen % 16);
+ }
+ Poly1305Update(&state, ciphertext, ciphertextLen);
+ if (ciphertextLen % 16 > 0) {
+ Poly1305Update(&state, zeros, 16 - ciphertextLen % 16);
+ }
+ j = adLen;
+ for (i = 0; i < sizeof(lengthBytes); i++) {
+ lengthBytes[i] = j;
+ j >>= 8;
+ }
+ Poly1305Update(&state, lengthBytes, sizeof(lengthBytes));
+ j = ciphertextLen;
+ for (i = 0; i < sizeof(lengthBytes); i++) {
+ lengthBytes[i] = j;
+ j >>= 8;
+ }
+ Poly1305Update(&state, lengthBytes, sizeof(lengthBytes));
+ Poly1305Finish(&state, out);
+}
+#endif
+
+SECStatus
+ChaCha20Poly1305_InitContext(ChaCha20Poly1305Context *ctx,
+ const unsigned char *key, unsigned int keyLen,
+ unsigned int tagLen)
+{
+#ifdef NSS_DISABLE_CHACHAPOLY
+ return SECFailure;
+#else
+ if (keyLen != 32) {
+ PORT_SetError(SEC_ERROR_BAD_KEY);
+ return SECFailure;
+ }
+ if (tagLen == 0 || tagLen > 16) {
+ PORT_SetError(SEC_ERROR_INPUT_LEN);
+ return SECFailure;
+ }
+
+ PORT_Memcpy(ctx->key, key, sizeof(ctx->key));
+ ctx->tagLen = tagLen;
+
+ return SECSuccess;
+#endif
+}
+
+ChaCha20Poly1305Context *
+ChaCha20Poly1305_CreateContext(const unsigned char *key, unsigned int keyLen,
+ unsigned int tagLen)
+{
+#ifdef NSS_DISABLE_CHACHAPOLY
+ return NULL;
+#else
+ ChaCha20Poly1305Context *ctx;
+
+ ctx = PORT_New(ChaCha20Poly1305Context);
+ if (ctx == NULL) {
+ return NULL;
+ }
+
+ if (ChaCha20Poly1305_InitContext(ctx, key, keyLen, tagLen) != SECSuccess) {
+ PORT_Free(ctx);
+ ctx = NULL;
+ }
+
+ return ctx;
+#endif
+}
+
+void
+ChaCha20Poly1305_DestroyContext(ChaCha20Poly1305Context *ctx, PRBool freeit)
+{
+#ifndef NSS_DISABLE_CHACHAPOLY
+ PORT_Memset(ctx, 0, sizeof(*ctx));
+ if (freeit) {
+ PORT_Free(ctx);
+ }
+#endif
+}
+
+SECStatus
+ChaCha20Poly1305_Seal(const ChaCha20Poly1305Context *ctx, unsigned char *output,
+ unsigned int *outputLen, unsigned int maxOutputLen,
+ const unsigned char *input, unsigned int inputLen,
+ const unsigned char *nonce, unsigned int nonceLen,
+ const unsigned char *ad, unsigned int adLen)
+{
+#ifdef NSS_DISABLE_CHACHAPOLY
+ return SECFailure;
+#else
+ unsigned char block[64];
+ unsigned char tag[16];
+
+ if (nonceLen != 12) {
+ PORT_SetError(SEC_ERROR_INPUT_LEN);
+ return SECFailure;
+ }
+ *outputLen = inputLen + ctx->tagLen;
+ if (maxOutputLen < *outputLen) {
+ PORT_SetError(SEC_ERROR_OUTPUT_LEN);
+ return SECFailure;
+ }
+
+ PORT_Memset(block, 0, sizeof(block));
+ // Generate a block of keystream. The first 32 bytes will be the poly1305
+ // key. The remainder of the block is discarded.
+ ChaCha20XOR(block, block, sizeof(block), ctx->key, nonce, 0);
+ ChaCha20XOR(output, input, inputLen, ctx->key, nonce, 1);
+
+ Poly1305Do(tag, ad, adLen, output, inputLen, block);
+ PORT_Memcpy(output + inputLen, tag, ctx->tagLen);
+
+ return SECSuccess;
+#endif
+}
+
+SECStatus
+ChaCha20Poly1305_Open(const ChaCha20Poly1305Context *ctx, unsigned char *output,
+ unsigned int *outputLen, unsigned int maxOutputLen,
+ const unsigned char *input, unsigned int inputLen,
+ const unsigned char *nonce, unsigned int nonceLen,
+ const unsigned char *ad, unsigned int adLen)
+{
+#ifdef NSS_DISABLE_CHACHAPOLY
+ return SECFailure;
+#else
+ unsigned char block[64];
+ unsigned char tag[16];
+ unsigned int ciphertextLen;
+
+ if (nonceLen != 12) {
+ PORT_SetError(SEC_ERROR_INPUT_LEN);
+ return SECFailure;
+ }
+ if (inputLen < ctx->tagLen) {
+ PORT_SetError(SEC_ERROR_INPUT_LEN);
+ return SECFailure;
+ }
+ ciphertextLen = inputLen - ctx->tagLen;
+ *outputLen = ciphertextLen;
+ if (maxOutputLen < *outputLen) {
+ PORT_SetError(SEC_ERROR_OUTPUT_LEN);
+ return SECFailure;
+ }
+
+ PORT_Memset(block, 0, sizeof(block));
+ // Generate a block of keystream. The first 32 bytes will be the poly1305
+ // key. The remainder of the block is discarded.
+ ChaCha20XOR(block, block, sizeof(block), ctx->key, nonce, 0);
+ Poly1305Do(tag, ad, adLen, input, ciphertextLen, block);
+ if (NSS_SecureMemcmp(tag, &input[ciphertextLen], ctx->tagLen) != 0) {
+ PORT_SetError(SEC_ERROR_BAD_DATA);
+ return SECFailure;
+ }
+
+ ChaCha20XOR(output, input, ciphertextLen, ctx->key, nonce, 1);
+
+ return SECSuccess;
+#endif
+}
diff --git a/nss/lib/freebl/chacha20poly1305.h b/nss/lib/freebl/chacha20poly1305.h
new file mode 100644
index 0000000..c77632a
--- /dev/null
+++ b/nss/lib/freebl/chacha20poly1305.h
@@ -0,0 +1,15 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.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 _CHACHA20_POLY1305_H_
+#define _CHACHA20_POLY1305_H_ 1
+
+/* ChaCha20Poly1305ContextStr saves the key and tag length for a
+ * ChaCha20+Poly1305 AEAD operation. */
+struct ChaCha20Poly1305ContextStr {
+ unsigned char key[32];
+ unsigned char tagLen;
+};
+
+#endif /* _CHACHA20_POLY1305_H_ */
diff --git a/nss/lib/freebl/ctr.c b/nss/lib/freebl/ctr.c
index 1cbf30c..d5715a5 100644
--- a/nss/lib/freebl/ctr.c
+++ b/nss/lib/freebl/ctr.c
@@ -19,33 +19,38 @@
SECStatus
CTR_InitContext(CTRContext *ctr, void *context, freeblCipherFunc cipher,
- const unsigned char *param, unsigned int blocksize)
+ 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;
+ ctrParams->ulCounterBits > blocksize * PR_BITS_PER_BYTE) {
+ PORT_SetError(SEC_ERROR_INVALID_ARGS);
+ return SECFailure;
}
/* Invariant: 0 < ctr->bufPtr <= blocksize */
+ ctr->checkWrap = PR_FALSE;
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;
+ blocksize > sizeof(ctrParams->cb)) {
+ PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
+ return SECFailure;
}
PORT_Memcpy(ctr->counter, ctrParams->cb, blocksize);
+ if (ctr->counterBits < 64) {
+ PORT_Memcpy(ctr->counterFirst, ctr->counter, blocksize);
+ ctr->checkWrap = PR_TRUE;
+ }
return SECSuccess;
}
CTRContext *
CTR_CreateContext(void *context, freeblCipherFunc cipher,
- const unsigned char *param, unsigned int blocksize)
+ const unsigned char *param, unsigned int blocksize)
{
CTRContext *ctr;
SECStatus rv;
@@ -53,12 +58,12 @@ CTR_CreateContext(void *context, freeblCipherFunc cipher,
/* first fill in the Counter context */
ctr = PORT_ZNew(CTRContext);
if (ctr == NULL) {
- return NULL;
+ return NULL;
}
rv = CTR_InitContext(ctr, context, cipher, param, blocksize);
if (rv != SECSuccess) {
- CTR_DestroyContext(ctr, PR_TRUE);
- ctr = NULL;
+ CTR_DestroyContext(ctr, PR_TRUE);
+ ctr = NULL;
}
return ctr;
}
@@ -68,7 +73,7 @@ CTR_DestroyContext(CTRContext *ctr, PRBool freeit)
{
PORT_Memset(ctr, 0, sizeof(CTRContext));
if (freeit) {
- PORT_Free(ctr);
+ PORT_Free(ctr);
}
}
@@ -82,23 +87,23 @@ CTR_DestroyContext(CTRContext *ctr, PRBool freeit)
*/
static void
ctr_GetNextCtr(unsigned char *counter, unsigned int counterBits,
- unsigned int blocksize)
+ unsigned int blocksize)
{
unsigned char *counterPtr = counter + blocksize - 1;
unsigned char mask, count;
- PORT_Assert(counterBits <= blocksize*PR_BITS_PER_BYTE);
+ PORT_Assert(counterBits <= blocksize * PR_BITS_PER_BYTE);
while (counterBits >= PR_BITS_PER_BYTE) {
- if (++(*(counterPtr--))) {
- return;
- }
- counterBits -= PR_BITS_PER_BYTE;
+ if (++(*(counterPtr--))) {
+ return;
+ }
+ counterBits -= PR_BITS_PER_BYTE;
}
if (counterBits == 0) {
- return;
+ return;
}
/* increment the final partial byte */
- mask = (1 << counterBits)-1;
+ mask = (1 << counterBits) - 1;
count = ++(*counterPtr) & mask;
*counterPtr = ((*counterPtr) & ~mask) | count;
return;
@@ -106,64 +111,76 @@ ctr_GetNextCtr(unsigned char *counter, unsigned int counterBits,
static void
ctr_xor(unsigned char *target, const unsigned char *x,
- const unsigned char *y, unsigned int count)
+ const unsigned char *y, unsigned int count)
{
unsigned int i;
- for (i=0; i < count; i++) {
- *target++ = *x++ ^ *y++;
+ 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 *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 = 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);
+ 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;
+ rv = (*ctr->cipher)(ctr->context, ctr->buffer, &tmp, blocksize,
+ ctr->counter, blocksize, blocksize);
+ ctr_GetNextCtr(ctr->counter, ctr->counterBits, blocksize);
+ if (ctr->checkWrap) {
+ if (PORT_Memcmp(ctr->counter, ctr->counterFirst, blocksize) == 0) {
+ PORT_SetError(SEC_ERROR_INVALID_ARGS);
+ return SECFailure;
+ }
+ }
+ 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;
+ return SECSuccess;
}
rv = (*ctr->cipher)(ctr->context, ctr->buffer, &tmp, blocksize,
- ctr->counter, blocksize, blocksize);
+ ctr->counter, blocksize, blocksize);
ctr_GetNextCtr(ctr->counter, ctr->counterBits, blocksize);
+ if (ctr->checkWrap) {
+ if (PORT_Memcmp(ctr->counter, ctr->counterFirst, blocksize) == 0) {
+ PORT_SetError(SEC_ERROR_INVALID_ARGS);
+ return SECFailure;
+ }
+ }
if (rv != SECSuccess) {
- return SECFailure;
+ return SECFailure;
}
ctr_xor(outbuf, inbuf, ctr->buffer, inlen);
ctr->bufPtr = inlen;
@@ -174,52 +191,52 @@ CTR_Update(CTRContext *ctr, unsigned char *outbuf,
#if defined(USE_HW_AES) && defined(_MSC_VER)
SECStatus
CTR_Update_HW_AES(CTRContext *ctr, unsigned char *outbuf,
- unsigned int *outlen, unsigned int maxout,
- const unsigned char *inbuf, unsigned int inlen,
- unsigned int blocksize)
+ unsigned int *outlen, unsigned int maxout,
+ const unsigned char *inbuf, unsigned int inlen,
+ unsigned int blocksize)
{
unsigned int fullblocks;
unsigned int tmp;
SECStatus rv;
if (maxout < inlen) {
- *outlen = inlen;
- PORT_SetError(SEC_ERROR_OUTPUT_LEN);
- return SECFailure;
+ *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);
- }
-
- intel_aes_ctr_worker(((AESContext*)(ctr->context))->Nr)(
- ctr, outbuf, outlen, maxout, inbuf, inlen, 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);
+ }
+
+ intel_aes_ctr_worker(((AESContext *)(ctr->context))->Nr)(
+ ctr, outbuf, outlen, maxout, inbuf, inlen, blocksize);
/* XXX intel_aes_ctr_worker should set *outlen. */
PORT_Assert(*outlen == 0);
- fullblocks = (inlen/blocksize)*blocksize;
+ fullblocks = (inlen / blocksize) * blocksize;
*outlen += fullblocks;
outbuf += fullblocks;
inbuf += fullblocks;
inlen -= fullblocks;
if (inlen == 0) {
- return SECSuccess;
+ return SECSuccess;
}
rv = (*ctr->cipher)(ctr->context, ctr->buffer, &tmp, blocksize,
- ctr->counter, blocksize, blocksize);
+ ctr->counter, blocksize, blocksize);
ctr_GetNextCtr(ctr->counter, ctr->counterBits, blocksize);
if (rv != SECSuccess) {
- return SECFailure;
+ return SECFailure;
}
ctr_xor(outbuf, inbuf, ctr->buffer, inlen);
ctr->bufPtr = inlen;
diff --git a/nss/lib/freebl/ctr.h b/nss/lib/freebl/ctr.h
index e7645a2..a97da14 100644
--- a/nss/lib/freebl/ctr.h
+++ b/nss/lib/freebl/ctr.h
@@ -10,19 +10,21 @@
/* 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;
+ freeblCipherFunc cipher;
+ void *context;
+ unsigned char counter[MAX_BLOCK_SIZE];
+ unsigned char buffer[MAX_BLOCK_SIZE];
+ unsigned char counterFirst[MAX_BLOCK_SIZE]; /* counter overlfow value */
+ PRBool checkWrap; /*check for counter overflow*/
+ 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);
+ freeblCipherFunc cipher, const unsigned char *param,
+ unsigned int blocksize);
/*
* The context argument is the inner cipher context to use with cipher. The
@@ -31,21 +33,21 @@ SECStatus CTR_InitContext(CTRContext *ctr, void *context,
*
* 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);
+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);
+ unsigned int *outlen, unsigned int maxout,
+ const unsigned char *inbuf, unsigned int inlen,
+ unsigned int blocksize);
#ifdef USE_HW_AES
SECStatus CTR_Update_HW_AES(CTRContext *ctr, unsigned char *outbuf,
- unsigned int *outlen, unsigned int maxout,
- const unsigned char *inbuf, unsigned int inlen,
- unsigned int blocksize);
+ unsigned int *outlen, unsigned int maxout,
+ const unsigned char *inbuf, unsigned int inlen,
+ unsigned int blocksize);
#endif
#endif
diff --git a/nss/lib/freebl/cts.c b/nss/lib/freebl/cts.c
index 984e05b..99ccebb 100644
--- a/nss/lib/freebl/cts.c
+++ b/nss/lib/freebl/cts.c
@@ -20,17 +20,17 @@ struct CTSContextStr {
CTSContext *
CTS_CreateContext(void *context, freeblCipherFunc cipher,
- const unsigned char *iv, unsigned int blocksize)
+ const unsigned char *iv, unsigned int blocksize)
{
- CTSContext *cts;
+ CTSContext *cts;
if (blocksize > MAX_BLOCK_SIZE) {
- PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
- return NULL;
+ PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
+ return NULL;
}
cts = PORT_ZNew(CTSContext);
if (cts == NULL) {
- return NULL;
+ return NULL;
}
PORT_Memcpy(cts->iv, iv, blocksize);
cts->cipher = cipher;
@@ -42,10 +42,10 @@ void
CTS_DestroyContext(CTSContext *cts, PRBool freeit)
{
if (freeit) {
- PORT_Free(cts);
+ PORT_Free(cts);
}
}
-
+
/*
* See addemdum to NIST SP 800-38A
* Generically handle cipher text stealing. Basically this is doing CBC
@@ -75,7 +75,7 @@ CTS_DestroyContext(CTSContext *cts, PRBool freeit)
* if (pad) {
* memcpy(tmp, outbuf+*outlen-blocksize, blocksize);
* memcpy(outbuf+*outlen-pad,outbuf+*outlen-blocksize-pad, pad);
- * memcpy(outbuf+*outlen-blocksize-pad, tmp, blocksize);
+ * memcpy(outbuf+*outlen-blocksize-pad, tmp, blocksize);
* }
* CS-3 (Kerberos): do
* unsigned char tmp[MAX_BLOCK_SIZE];
@@ -85,41 +85,42 @@ CTS_DestroyContext(CTSContext *cts, PRBool freeit)
* }
* memcpy(tmp, outbuf+*outlen-blocksize, blocksize);
* memcpy(outbuf+*outlen-pad,outbuf+*outlen-blocksize-pad, pad);
- * memcpy(outbuf+*outlen-blocksize-pad, tmp, blocksize);
+ * 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 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;
+ unsigned char *saveout = outbuf;
SECStatus rv;
if (inlen < blocksize) {
- PORT_SetError(SEC_ERROR_INPUT_LEN);
- return SECFailure;
+ PORT_SetError(SEC_ERROR_INPUT_LEN);
+ return SECFailure;
}
if (maxout < inlen) {
- *outlen = inlen;
- PORT_SetError(SEC_ERROR_OUTPUT_LEN);
- return SECFailure;
+ *outlen = inlen;
+ PORT_SetError(SEC_ERROR_OUTPUT_LEN);
+ return SECFailure;
}
- fullblocks = (inlen/blocksize)*blocksize;
+ fullblocks = (inlen / blocksize) * blocksize;
rv = (*cts->cipher)(cts->context, outbuf, outlen, maxout, inbuf,
- fullblocks, blocksize);
+ fullblocks, blocksize);
if (rv != SECSuccess) {
- return SECFailure;
+ return SECFailure;
}
*outlen = fullblocks; /* AES low level doesn't set outlen */
inbuf += fullblocks;
inlen -= fullblocks;
if (inlen == 0) {
- return SECSuccess;
+ return SECSuccess;
}
written = *outlen - (blocksize - inlen);
outbuf += written;
@@ -137,16 +138,19 @@ CTS_EncryptUpdate(CTSContext *cts, unsigned char *outbuf,
PORT_Memcpy(lastBlock, inbuf, inlen);
PORT_Memset(lastBlock + inlen, 0, blocksize - inlen);
rv = (*cts->cipher)(cts->context, outbuf, &tmp, maxout, lastBlock,
- blocksize, blocksize);
+ blocksize, blocksize);
PORT_Memset(lastBlock, 0, blocksize);
if (rv == SECSuccess) {
- *outlen = written + blocksize;
+ *outlen = written + blocksize;
+ } else {
+ PORT_Memset(saveout, 0, written + blocksize);
}
return rv;
}
-
-#define XOR_BLOCK(x,y,count) for(i=0; i < count; i++) x[i] = x[i] ^ y[i]
+#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
@@ -160,7 +164,7 @@ CTS_EncryptUpdate(CTSContext *cts, unsigned char *outbuf,
* if (pad) {
* memcpy(tmp, inbuf+inlen-blocksize-pad, blocksize);
* memcpy(inbuf+inlen-blocksize-pad,inbuf+inlen-pad, pad);
- * memcpy(inbuf+inlen-blocksize, tmp, blocksize);
+ * memcpy(inbuf+inlen-blocksize, tmp, blocksize);
* }
* CS-3 (Kerberos): do
* unsigned char tmp[MAX_BLOCK_SIZE];
@@ -170,13 +174,13 @@ CTS_EncryptUpdate(CTSContext *cts, unsigned char *outbuf,
* }
* memcpy(tmp, inbuf+inlen-blocksize-pad, blocksize);
* memcpy(inbuf+inlen-blocksize-pad,inbuf+inlen-pad, pad);
- * memcpy(inbuf+inlen-blocksize, tmp, blocksize);
+ * 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 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 */
@@ -184,23 +188,24 @@ CTS_DecryptUpdate(CTSContext *cts, unsigned char *outbuf,
unsigned char Cn[MAX_BLOCK_SIZE]; /* block Cn */
unsigned char lastBlock[MAX_BLOCK_SIZE];
const unsigned char *tmp;
+ unsigned char *saveout = outbuf;
unsigned int tmpLen;
unsigned int fullblocks, pad;
unsigned int i;
SECStatus rv;
if (inlen < blocksize) {
- PORT_SetError(SEC_ERROR_INPUT_LEN);
- return SECFailure;
+ PORT_SetError(SEC_ERROR_INPUT_LEN);
+ return SECFailure;
}
if (maxout < inlen) {
- *outlen = inlen;
- PORT_SetError(SEC_ERROR_OUTPUT_LEN);
- return SECFailure;
+ *outlen = inlen;
+ PORT_SetError(SEC_ERROR_OUTPUT_LEN);
+ return SECFailure;
}
- fullblocks = (inlen/blocksize)*blocksize;
+ 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
@@ -209,34 +214,33 @@ CTS_DecryptUpdate(CTSContext *cts, unsigned char *outbuf,
*/
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);
+ 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;
+ tmp = (fullblocks < blocksize * 2) ? cts->iv : inbuf + fullblocks - blocksize * 2;
PORT_Memcpy(Cn_2, tmp, blocksize);
- PORT_Memcpy(Cn, inbuf+fullblocks-blocksize, blocksize);
+ PORT_Memcpy(Cn, inbuf + fullblocks - blocksize, blocksize);
rv = (*cts->cipher)(cts->context, outbuf, outlen, maxout, inbuf,
- fullblocks, blocksize);
+ fullblocks, blocksize);
if (rv != SECSuccess) {
- return SECFailure;
+ return SECFailure;
}
*outlen = fullblocks; /* AES low level doesn't set outlen */
inbuf += fullblocks;
inlen -= fullblocks;
if (inlen == 0) {
- return SECSuccess;
+ return SECSuccess;
}
outbuf += fullblocks;
@@ -244,7 +248,7 @@ CTS_DecryptUpdate(CTSContext *cts, unsigned char *outbuf,
PORT_Memset(lastBlock, 0, blocksize);
PORT_Memcpy(lastBlock, inbuf, inlen);
PORT_Memcpy(Cn_1, inbuf, inlen);
- Pn = outbuf-blocksize;
+ 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.
@@ -278,9 +282,11 @@ CTS_DecryptUpdate(CTSContext *cts, unsigned char *outbuf,
* 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);
+ blocksize, blocksize);
if (rv != SECSuccess) {
- return SECFailure;
+ PORT_Memset(lastBlock, 0, blocksize);
+ PORT_Memset(saveout, 0, *outlen);
+ return SECFailure;
}
/* make up for the out of order CBC decryption */
XOR_BLOCK(Pn, Cn_2, blocksize);
@@ -290,8 +296,8 @@ CTS_DecryptUpdate(CTSContext *cts, unsigned char *outbuf,
/* 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);
+ (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 */
diff --git a/nss/lib/freebl/cts.h b/nss/lib/freebl/cts.h
index 97b385f..a3ec180 100644
--- a/nss/lib/freebl/cts.h
+++ b/nss/lib/freebl/cts.h
@@ -17,17 +17,17 @@ typedef struct CTSContextStr CTSContext;
* 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);
+ 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);
+ 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);
+ unsigned int *outlen, unsigned int maxout,
+ const unsigned char *inbuf, unsigned int inlen,
+ unsigned int blocksize);
#endif
diff --git a/nss/lib/freebl/des.c b/nss/lib/freebl/des.c
index bcfcaba..fd433bb 100644
--- a/nss/lib/freebl/des.c
+++ b/nss/lib/freebl/des.c
@@ -10,524 +10,504 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "des.h"
-#include <stddef.h> /* for ptrdiff_t */
+#include "blapii.h"
+#include <stddef.h> /* for ptrdiff_t */
/* #define USE_INDEXING 1 */
-/* Some processors automatically fix up unaligned memory access, so they can
- * read or write a HALF (4 bytes) at a time whether the address is 4-byte
- * aligned or not. */
-#if defined(NSS_X86_OR_X64)
-#define HAVE_UNALIGNED_ACCESS 1
-#endif
-
/*
- * The tables below are the 8 sbox functions, with the 6-bit input permutation
+ * 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.
+ * 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
- }
+ /* 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
- }
+ /* 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,
+ * 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
+ * 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
+ * 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
- *
+ * 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
+ * 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
+ * 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);
+#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));
+ __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__))))
+#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));
+ __asm("rev %0, %0" \
+ : "+r"(word));
#else
-#define BYTESWAP(word, temp) \
+#define BYTESWAP(word, temp) \
word = (word >> 16) | (word << 16); \
- temp = 0x00ff00ff; \
- word = ((word & temp) << 8) | ((word >> 8) & temp);
+ temp = 0x00ff00ff; \
+ word = ((word & temp) << 8) | ((word >> 8) & temp);
#endif
-#define PC1(left, right, c0, d0, temp) \
+#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);
+ 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)
+#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)
+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;
+ int delta;
+ unsigned int ls;
#if defined(HAVE_UNALIGNED_ACCESS)
- left = HALFPTR(key)[0];
- right = HALFPTR(key)[1];
+ left = HALFPTR(key)[0];
+ right = HALFPTR(key)[1];
#if defined(IS_LITTLE_ENDIAN)
BYTESWAP(left, temp);
BYTESWAP(right, temp);
#endif
#else
if (((ptrdiff_t)key & 0x03) == 0) {
- left = HALFPTR(key)[0];
- right = HALFPTR(key)[1];
+ left = HALFPTR(key)[0];
+ right = HALFPTR(key)[1];
#if defined(IS_LITTLE_ENDIAN)
- BYTESWAP(left, temp);
- BYTESWAP(right, temp);
+ 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];
+ 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);
+ delta = 2 * (int)sizeof(HALF);
} else {
- ks += 30;
- delta = (-2) * (int)sizeof(HALF);
+ 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 );
- }
+ 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]
+#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));
+ 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));
+ 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))
+#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));
+ 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));
+ 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;
+ /* 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;
+ temp = (left & 0xffff0000) /* S1 S3 XX XX */
+ | (right & 0x0000ffff); /* XX XX S5 S7 */
+ ks[1] = temp;
- ks = (HALF*)((BYTE *)ks + delta);
+ 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
+ * 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.
@@ -535,97 +515,97 @@ DES_MakeSchedule( HALF * ks, const BYTE * key, DESDirection direction)
*
* #define swapHiLo(word, temp) \
* temp = (word ^ (word >> 24)) & 0x000000ff; \
- * word ^= temp | (temp << 24);
+ * word ^= temp | (temp << 24);
*
- * right ^= temp = ((left << 8) ^ right) & 0xff00ff00;
- * left ^= temp >> 8;
+ * 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.
+ * operations from 8 ot 5.
*
* Initial Permutation */
-#define IP(left, right, temp) \
- right ^= temp = ((left >> 4) ^ right) & 0x0f0f0f0f; \
- left ^= temp << 4; \
+#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
+ 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; \
+#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;
+ left ^= temp << 16; \
+ right ^= temp = ((left >> 4) ^ right) & 0x0f0f0f0f; \
+ left ^= temp << 4;
-void
-DES_Do1Block(HALF * ks, const BYTE * inbuf, BYTE * outbuf)
+void NO_SANITIZE_ALIGNMENT
+DES_Do1Block(HALF *ks, const BYTE *inbuf, BYTE *outbuf)
{
register HALF left, right;
register HALF temp;
#if defined(HAVE_UNALIGNED_ACCESS)
- left = HALFPTR(inbuf)[0];
- right = HALFPTR(inbuf)[1];
+ left = HALFPTR(inbuf)[0];
+ right = HALFPTR(inbuf)[1];
#if defined(IS_LITTLE_ENDIAN)
BYTESWAP(left, temp);
BYTESWAP(right, temp);
#endif
#else
if (((ptrdiff_t)inbuf & 0x03) == 0) {
- left = HALFPTR(inbuf)[0];
- right = HALFPTR(inbuf)[1];
+ left = HALFPTR(inbuf)[0];
+ right = HALFPTR(inbuf)[1];
#if defined(IS_LITTLE_ENDIAN)
- BYTESWAP(left, temp);
- BYTESWAP(right, temp);
+ 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];
+ 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);
+ left = (left << 3) | (left >> 29);
right = (right << 3) | (right >> 29);
#ifdef USE_INDEXING
-#define KSLOOKUP(s,b) SP[s][((temp >> (b+2)) & 0x3f)]
+#define KSLOOKUP(s, b) SP[s][((temp >> (b + 2)) & 0x3f)]
#else
-#define KSLOOKUP(s,b) *(HALF*)((BYTE*)&SP[s][0]+((temp >> b) & 0xFC))
+#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 );
+#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)
@@ -645,11 +625,11 @@ DES_Do1Block(HALF * ks, const BYTE * inbuf, BYTE * outbuf)
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.
+ /* 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);
+ temp = (left >> 3) | (left << 29);
+ left = (right >> 3) | (right << 29);
right = temp;
FP(left, right, temp);
@@ -659,35 +639,38 @@ DES_Do1Block(HALF * ks, const BYTE * inbuf, BYTE * outbuf)
BYTESWAP(left, temp);
BYTESWAP(right, temp);
#endif
- HALFPTR(outbuf)[0] = left;
- HALFPTR(outbuf)[1] = right;
+ 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);
+ BYTESWAP(left, temp);
+ BYTESWAP(right, temp);
#endif
- HALFPTR(outbuf)[0] = left;
- HALFPTR(outbuf)[1] = right;
+ 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 );
+ 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
+** 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.
+** 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/nss/lib/freebl/des.h b/nss/lib/freebl/des.h
index 10dba12..70a17e5 100644
--- a/nss/lib/freebl/des.h
+++ b/nss/lib/freebl/des.h
@@ -13,7 +13,7 @@
#include "blapi.h"
typedef unsigned char BYTE;
-typedef unsigned int HALF;
+typedef unsigned int HALF;
#define HALFPTR(x) ((HALF *)(x))
#define SHORTPTR(x) ((unsigned short *)(x))
@@ -24,20 +24,20 @@ typedef enum {
DES_DECRYPT = 0xAAAA
} DESDirection;
-typedef void DESFunc(struct DESContextStr *cx, BYTE *out, const BYTE *in,
+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];
+ HALF ks0[32];
+ HALF ks1[32];
+ HALF ks2[32];
+ HALF iv[2];
DESDirection direction;
- DESFunc *worker;
+ DESFunc *worker;
};
-void DES_MakeSchedule( HALF * ks, const BYTE * key, DESDirection direction);
-void DES_Do1Block( HALF * ks, const BYTE * inbuf, BYTE * outbuf);
+void DES_MakeSchedule(HALF *ks, const BYTE *key, DESDirection direction);
+void DES_Do1Block(HALF *ks, const BYTE *inbuf, BYTE *outbuf);
#endif
diff --git a/nss/lib/freebl/desblapi.c b/nss/lib/freebl/desblapi.c
index 04a07ca..c03ab27 100644
--- a/nss/lib/freebl/desblapi.c
+++ b/nss/lib/freebl/desblapi.c
@@ -14,119 +14,122 @@
#endif
#include "des.h"
+#include "blapii.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];
+ HALFPTR(to) \
+ [0] = HALFPTR(from)[0]; \
+ HALFPTR(to) \
+ [1] = HALFPTR(from)[1];
#else
#define COPY8B(to, from, ptr) memcpy(to, from, 8)
#endif
#define COPY8BTOHALF(to, from) COPY8B(to, from, from)
#define COPY8BFROMHALF(to, from) COPY8B(to, from, to)
-static void
+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;
+ DES_Do1Block(cx->ks0, in, out);
+ len -= 8;
+ in += 8;
+ out += 8;
}
}
-static void
+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;
+ 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
+static void NO_SANITIZE_ALIGNMENT
DES_CBCEn(DESContext *cx, BYTE *out, const BYTE *in, unsigned int len)
{
- const BYTE * bufend = in + len;
- HALF vec[2];
+ 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;
+ 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
+static void NO_SANITIZE_ALIGNMENT
DES_CBCDe(DESContext *cx, BYTE *out, const BYTE *in, unsigned int len)
{
- const BYTE * bufend;
+ 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;
+ 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
+static void NO_SANITIZE_ALIGNMENT
DES_EDE3CBCEn(DESContext *cx, BYTE *out, const BYTE *in, unsigned int len)
{
- const BYTE * bufend = in + len;
- HALF vec[2];
+ 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;
+ 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
+static void NO_SANITIZE_ALIGNMENT
DES_EDE3CBCDe(DESContext *cx, BYTE *out, const BYTE *in, unsigned int len)
{
- const BYTE * bufend;
+ 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;
+ 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;
}
}
@@ -136,74 +139,74 @@ DES_AllocateContext(void)
return PORT_ZNew(DESContext);
}
-SECStatus
+SECStatus
DES_InitContext(DESContext *cx, const unsigned char *key, unsigned int keylen,
- const unsigned char *iv, int mode, unsigned int encrypt,
- unsigned int unused)
+ const unsigned char *iv, int mode, unsigned int encrypt,
+ unsigned int unused)
{
DESDirection opposite;
if (!cx) {
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- return SECFailure;
+ PORT_SetError(SEC_ERROR_INVALID_ARGS);
+ return SECFailure;
}
cx->direction = encrypt ? DES_ENCRYPT : DES_DECRYPT;
- opposite = encrypt ? DES_DECRYPT : DES_ENCRYPT;
+ 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;
+ 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)
+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);
+ SECStatus rv = DES_InitContext(cx, key, 0, iv, mode, encrypt, 0);
if (rv != SECSuccess) {
- PORT_ZFree(cx, sizeof *cx);
- cx = NULL;
+ PORT_ZFree(cx, sizeof *cx);
+ cx = NULL;
}
return cx;
}
@@ -212,9 +215,9 @@ void
DES_DestroyContext(DESContext *cx, PRBool freeit)
{
if (cx) {
- memset(cx, 0, sizeof *cx);
- if (freeit)
- PORT_Free(cx);
+ memset(cx, 0, sizeof *cx);
+ if (freeit)
+ PORT_Free(cx);
}
}
@@ -223,15 +226,15 @@ 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 ||
+ if ((inLen % 8) != 0 || maxOutLen < inLen || !cx ||
cx->direction != DES_ENCRYPT) {
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- return SECFailure;
+ PORT_SetError(SEC_ERROR_INVALID_ARGS);
+ return SECFailure;
}
cx->worker(cx, out, in, inLen);
if (outLen)
- *outLen = inLen;
+ *outLen = inLen;
return SECSuccess;
}
@@ -240,14 +243,14 @@ 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 ||
+ if ((inLen % 8) != 0 || maxOutLen < inLen || !cx ||
cx->direction != DES_DECRYPT) {
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- return SECFailure;
+ PORT_SetError(SEC_ERROR_INVALID_ARGS);
+ return SECFailure;
}
cx->worker(cx, out, in, inLen);
if (outLen)
- *outLen = inLen;
+ *outLen = inLen;
return SECSuccess;
}
diff --git a/nss/lib/freebl/det_rng.c b/nss/lib/freebl/det_rng.c
new file mode 100644
index 0000000..fcbf9b3
--- /dev/null
+++ b/nss/lib/freebl/det_rng.c
@@ -0,0 +1,67 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.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 "blapi.h"
+#include "blapit.h"
+#include "chacha20.h"
+#include "nssilock.h"
+#include "seccomon.h"
+#include "secerr.h"
+
+static unsigned long globalNumCalls = 0;
+
+SECStatus
+prng_ResetForFuzzing(PZLock *rng_lock)
+{
+ /* Check for a valid RNG lock. */
+ PORT_Assert(rng_lock != NULL);
+ if (rng_lock == NULL) {
+ PORT_SetError(SEC_ERROR_INVALID_ARGS);
+ return SECFailure;
+ }
+
+ /* --- LOCKED --- */
+ PZ_Lock(rng_lock);
+ globalNumCalls = 0;
+ PZ_Unlock(rng_lock);
+ /* --- UNLOCKED --- */
+
+ return SECSuccess;
+}
+
+SECStatus
+prng_GenerateDeterministicRandomBytes(PZLock *rng_lock, void *dest, size_t len)
+{
+ static const uint8_t key[32];
+ uint8_t nonce[12] = { 0 };
+
+ /* Check for a valid RNG lock. */
+ PORT_Assert(rng_lock != NULL);
+ if (rng_lock == NULL) {
+ PORT_SetError(SEC_ERROR_INVALID_ARGS);
+ return SECFailure;
+ }
+
+ /* --- LOCKED --- */
+ PZ_Lock(rng_lock);
+
+ memcpy(nonce, &globalNumCalls, sizeof(globalNumCalls));
+ globalNumCalls++;
+
+ ChaCha20Poly1305Context *cx =
+ ChaCha20Poly1305_CreateContext(key, sizeof(key), 16);
+ if (!cx) {
+ PORT_SetError(SEC_ERROR_NO_MEMORY);
+ PZ_Unlock(rng_lock);
+ return SECFailure;
+ }
+
+ memset(dest, 0, len);
+ ChaCha20XOR(dest, dest, len, key, nonce, 0);
+ ChaCha20Poly1305_DestroyContext(cx, PR_TRUE);
+
+ PZ_Unlock(rng_lock);
+ /* --- UNLOCKED --- */
+ return SECSuccess;
+}
diff --git a/nss/lib/freebl/det_rng.h b/nss/lib/freebl/det_rng.h
new file mode 100644
index 0000000..599d726
--- /dev/null
+++ b/nss/lib/freebl/det_rng.h
@@ -0,0 +1,12 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.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 __det_rng_h_
+#define __det_rng_h_
+
+SECStatus prng_ResetForFuzzing(PZLock *rng_lock);
+SECStatus prng_GenerateDeterministicRandomBytes(PZLock *rng_lock, void *dest,
+ size_t len);
+
+#endif /* __det_rng_h_ */
diff --git a/nss/lib/freebl/dh.c b/nss/lib/freebl/dh.c
index 66c1101..97025c7 100644
--- a/nss/lib/freebl/dh.c
+++ b/nss/lib/freebl/dh.c
@@ -27,21 +27,21 @@ dh_GetSecretKeyLen(unsigned int primeLen)
{
/* Based on Table 2 in NIST SP 800-57. */
if (primeLen >= 1920) { /* 15360 bits */
- return 64; /* 512 bits */
+ return 64; /* 512 bits */
}
if (primeLen >= 960) { /* 7680 bits */
- return 48; /* 384 bits */
+ return 48; /* 384 bits */
}
if (primeLen >= 384) { /* 3072 bits */
- return 32; /* 256 bits */
+ return 32; /* 256 bits */
}
if (primeLen >= 256) { /* 2048 bits */
- return 28; /* 224 bits */
+ return 28; /* 224 bits */
}
- return 20; /* 160 bits */
+ return 20; /* 160 bits */
}
-SECStatus
+SECStatus
DH_GenParam(int primeLen, DHParams **params)
{
PLArenaPool *arena;
@@ -53,19 +53,19 @@ DH_GenParam(int primeLen, DHParams **params)
mp_err err = MP_OKAY;
SECStatus rv = SECSuccess;
if (!params || primeLen < 0) {
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- return SECFailure;
+ 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;
+ 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;
+ PORT_SetError(SEC_ERROR_NO_MEMORY);
+ PORT_FreeArena(arena, PR_TRUE);
+ return SECFailure;
}
dhparams->arena = arena;
MP_DIGITS(&p) = 0;
@@ -74,42 +74,42 @@ DH_GenParam(int primeLen, DHParams **params)
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) );
+ 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) );
+ 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) );
+ 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) );
+ 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) );
+ 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. */
+ /* 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) );
+ }
+ /* 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);
@@ -121,65 +121,67 @@ cleanup:
mp_clear(&h);
mp_clear(&psub1);
mp_clear(&test);
- if (pb) PORT_ZFree(pb, primeLen);
- if (ab) PORT_ZFree(ab, primeLen);
+ if (pb)
+ PORT_ZFree(pb, primeLen);
+ if (ab)
+ PORT_ZFree(ab, primeLen);
if (err) {
- MP_TO_SEC_ERROR(err);
- rv = SECFailure;
+ MP_TO_SEC_ERROR(err);
+ rv = SECFailure;
}
if (rv)
- PORT_FreeArena(arena, PR_TRUE);
+ PORT_FreeArena(arena, PR_TRUE);
return rv;
}
-SECStatus
+SECStatus
DH_NewKey(DHParams *params, DHPrivateKey **privKey)
{
PLArenaPool *arena;
DHPrivateKey *key;
mp_int g, xa, p, Ya;
- mp_err err = MP_OKAY;
+ mp_err err = MP_OKAY;
SECStatus rv = SECSuccess;
if (!params || !privKey) {
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- return SECFailure;
+ 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;
+ 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;
+ PORT_SetError(SEC_ERROR_NO_MEMORY);
+ PORT_FreeArena(arena, PR_TRUE);
+ return SECFailure;
}
key->arena = arena;
- MP_DIGITS(&g) = 0;
+ MP_DIGITS(&g) = 0;
MP_DIGITS(&xa) = 0;
- MP_DIGITS(&p) = 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) );
+ 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) );
+ 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) );
+ 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 );
+ CHECK_SEC_OK(RNG_GenerateGlobalRandomBytes(key->privateValue.data,
+ key->privateValue.len));
+ SECITEM_TO_MPINT(key->privateValue, &xa);
/* xa < p */
- CHECK_MPI_OK( mp_mod(&xa, &p, &xa) );
+ 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) );
+ CHECK_MPI_OK(mp_exptmod(&g, &xa, &p, &Ya));
MPINT_TO_SECITEM(&Ya, &key->publicValue, key->arena);
*privKey = key;
cleanup:
@@ -188,19 +190,21 @@ cleanup:
mp_clear(&p);
mp_clear(&Ya);
if (err) {
- MP_TO_SEC_ERROR(err);
- rv = SECFailure;
+ MP_TO_SEC_ERROR(err);
+ rv = SECFailure;
+ }
+ if (rv) {
+ *privKey = NULL;
+ PORT_FreeArena(arena, PR_TRUE);
}
- if (rv)
- PORT_FreeArena(arena, PR_TRUE);
return rv;
}
-SECStatus
-DH_Derive(SECItem *publicValue,
- SECItem *prime,
- SECItem *privateValue,
- SECItem *derivedSecret,
+SECStatus
+DH_Derive(SECItem *publicValue,
+ SECItem *prime,
+ SECItem *privateValue,
+ SECItem *derivedSecret,
unsigned int outBytes)
{
mp_int p, Xa, Yb, ZZ, psub1;
@@ -209,24 +213,24 @@ DH_Derive(SECItem *publicValue,
unsigned int nb;
unsigned char *secret = NULL;
if (!publicValue || !prime || !privateValue || !derivedSecret) {
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- return SECFailure;
+ PORT_SetError(SEC_ERROR_INVALID_ARGS);
+ return SECFailure;
}
memset(derivedSecret, 0, sizeof *derivedSecret);
- MP_DIGITS(&p) = 0;
+ MP_DIGITS(&p) = 0;
MP_DIGITS(&Xa) = 0;
MP_DIGITS(&Yb) = 0;
MP_DIGITS(&ZZ) = 0;
MP_DIGITS(&psub1) = 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) );
- CHECK_MPI_OK( mp_init(&psub1) );
- SECITEM_TO_MPINT(*publicValue, &Yb);
+ CHECK_MPI_OK(mp_init(&p));
+ CHECK_MPI_OK(mp_init(&Xa));
+ CHECK_MPI_OK(mp_init(&Yb));
+ CHECK_MPI_OK(mp_init(&ZZ));
+ CHECK_MPI_OK(mp_init(&psub1));
+ SECITEM_TO_MPINT(*publicValue, &Yb);
SECITEM_TO_MPINT(*privateValue, &Xa);
- SECITEM_TO_MPINT(*prime, &p);
- CHECK_MPI_OK( mp_sub_d(&p, 1, &psub1) );
+ SECITEM_TO_MPINT(*prime, &p);
+ CHECK_MPI_OK(mp_sub_d(&p, 1, &psub1));
/* We assume that the modulus, p, is a safe prime. That is, p = 2q+1 where
* q is also a prime. Thus the orders of the subgroups are factors of 2q:
@@ -239,13 +243,13 @@ DH_Derive(SECItem *publicValue,
*
* Thus we must be operating in the subgroup of size q or 2q. */
if (mp_cmp_d(&Yb, 1) <= 0 ||
- mp_cmp(&Yb, &psub1) >= 0) {
- err = MP_BADARG;
- goto cleanup;
+ mp_cmp(&Yb, &psub1) >= 0) {
+ err = MP_BADARG;
+ goto cleanup;
}
/* ZZ = (Yb)**Xa mod p */
- CHECK_MPI_OK( mp_exptmod(&Yb, &Xa, &p, &ZZ) );
+ 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) {
@@ -272,26 +276,34 @@ DH_Derive(SECItem *publicValue,
/* allocate a buffer which can hold the entire derived secret. */
secret = PORT_Alloc(len);
+ if (secret == NULL) {
+ err = MP_MEM;
+ goto cleanup;
+ }
/* grab the derived secret */
err = mp_to_unsigned_octets(&ZZ, secret, len);
- if (err >= 0) err = MP_OKAY;
- /*
+ 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
+ ** pad at the beginning if necessary, and truncate beginning bytes
** if necessary.
*/
if (outBytes > 0)
- nb = outBytes;
+ nb = outBytes;
else
- nb = len;
- SECITEM_AllocItem(NULL, derivedSecret, nb);
+ nb = len;
+ if (SECITEM_AllocItem(NULL, derivedSecret, nb) == NULL) {
+ err = MP_MEM;
+ goto cleanup;
+ }
if (len < nb) {
- unsigned int offset = nb - len;
- memset(derivedSecret->data, 0, offset);
- memcpy(derivedSecret->data + offset, secret, len);
+ unsigned int offset = nb - len;
+ memset(derivedSecret->data, 0, offset);
+ memcpy(derivedSecret->data + offset, secret, len);
} else {
- memcpy(derivedSecret->data, secret + len - nb, nb);
+ memcpy(derivedSecret->data, secret + len - nb, nb);
}
cleanup:
mp_clear(&p);
@@ -300,23 +312,23 @@ cleanup:
mp_clear(&ZZ);
mp_clear(&psub1);
if (secret) {
- /* free the buffer allocated for the full secret. */
- PORT_ZFree(secret, len);
+ /* 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;
+ 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,
+SECStatus
+KEA_Derive(SECItem *prime,
+ SECItem *public1,
+ SECItem *public2,
+ SECItem *private1,
SECItem *private2,
SECItem *derivedSecret)
{
@@ -326,8 +338,8 @@ KEA_Derive(SECItem *prime,
unsigned int len = 0, offset;
if (!prime || !public1 || !public2 || !private1 || !private2 ||
!derivedSecret) {
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- return SECFailure;
+ PORT_SetError(SEC_ERROR_INVALID_ARGS);
+ return SECFailure;
}
memset(derivedSecret, 0, sizeof *derivedSecret);
MP_DIGITS(&p) = 0;
@@ -338,41 +350,49 @@ KEA_Derive(SECItem *prime,
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);
+ 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) );
+ 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) );
+ CHECK_MPI_OK(mp_exptmod(&R, &x, &p, &u));
/* w = (t + u) mod p */
- CHECK_MPI_OK( mp_addmod(&t, &u, &p, &w) );
+ 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);
+ if (secret == NULL) {
+ err = MP_MEM;
+ goto cleanup;
+ }
/* grab the secret */
err = mp_to_unsigned_octets(&w, secret, len);
- if (err > 0) err = MP_OKAY;
+ if (err > 0)
+ err = MP_OKAY;
/* allocate output buffer */
- SECITEM_AllocItem(NULL, derivedSecret, KEA_DERIVED_SECRET_LEN);
+ if (SECITEM_AllocItem(NULL, derivedSecret, KEA_DERIVED_SECRET_LEN) == NULL) {
+ err = MP_MEM;
+ goto cleanup;
+ }
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);
+ 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);
+ offset = KEA_DERIVED_SECRET_LEN - len;
+ memcpy(derivedSecret->data + offset, secret, len);
}
cleanup:
mp_clear(&p);
@@ -384,37 +404,39 @@ cleanup:
mp_clear(&u);
mp_clear(&w);
if (secret)
- PORT_ZFree(secret, len);
+ PORT_ZFree(secret, len);
if (err) {
- MP_TO_SEC_ERROR(err);
- return SECFailure;
+ MP_TO_SEC_ERROR(err);
+ if (derivedSecret->data)
+ PORT_ZFree(derivedSecret->data, derivedSecret->len);
+ return SECFailure;
}
return SECSuccess;
}
-PRBool
+PRBool
KEA_Verify(SECItem *Y, SECItem *prime, SECItem *subPrime)
{
mp_int p, q, y, r;
mp_err err;
- int cmp = 1; /* default is false */
+ int cmp = 1; /* default is false */
if (!Y || !prime || !subPrime) {
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- return SECFailure;
+ 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);
+ 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);
+ SECITEM_TO_MPINT(*Y, &y);
/* compute r = y**q mod p */
- CHECK_MPI_OK( mp_exptmod(&y, &q, &p, &r) );
+ CHECK_MPI_OK(mp_exptmod(&y, &q, &p, &r));
/* compare to 1 */
cmp = mp_cmp_d(&r, 1);
cleanup:
@@ -423,8 +445,8 @@ cleanup:
mp_clear(&y);
mp_clear(&r);
if (err) {
- MP_TO_SEC_ERROR(err);
- return PR_FALSE;
+ MP_TO_SEC_ERROR(err);
+ return PR_FALSE;
}
return (cmp == 0) ? PR_TRUE : PR_FALSE;
}
diff --git a/nss/lib/freebl/drbg.c b/nss/lib/freebl/drbg.c
index 391d456..658faa3 100644
--- a/nss/lib/freebl/drbg.c
+++ b/nss/lib/freebl/drbg.c
@@ -17,24 +17,28 @@
#include "secitem.h"
#include "sha_fast.h"
#include "sha256.h"
-#include "secrng.h" /* for RNG_SystemRNG() */
+#include "secrng.h" /* for RNG_SystemRNG() */
#include "secmpi.h"
-/* PRNG_SEEDLEN defined in NIST SP 800-90 section 10.1
+#ifdef UNSAFE_FUZZER_MODE
+#include "det_rng.h"
+#endif
+
+/* 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)
+#define PRNG_SEEDLEN (440 / PR_BITS_PER_BYTE)
#define PRNG_MAX_ADDITIONAL_BYTES PR_INT64(0x100000000)
- /* 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
- */
+/* 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
+/* 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
+ * 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
@@ -43,67 +47,65 @@
#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;
-
+#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
+ * 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 */
+ 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 */
+ 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
+ * 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 */
+ 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 lastOutput[SHA256_LENGTH]; /* 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] */
+ 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];
+ PRUint8 additionalDataCache[PRNG_ADDITONAL_DATA_CACHE_SIZE];
PRUint32 additionalAvail;
- PRBool isValid; /* false if RNG reaches an invalid state */
+ 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
@@ -113,41 +115,40 @@ static RNGContext theGlobalRng;
/*
* 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 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)
+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;
+ 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
*
@@ -158,18 +159,17 @@ 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;
+ /* 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_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
@@ -180,45 +180,45 @@ prng_instantiate(RNGContext *rng, const PRUint8 *bytes, unsigned int len)
*/
static SECStatus
prng_reseed(RNGContext *rng, const PRUint8 *entropy, unsigned int entropy_len,
- const PRUint8 *additional_input, unsigned int additional_input_len)
+ const PRUint8 *additional_input, unsigned int additional_input_len)
{
- PRUint8 noiseData[(sizeof rng->V_Data)+PRNG_SEEDLEN];
+ 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);
+ 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);
+ /* 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;
+ 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);
+ additional_input, additional_input_len);
/* clear potential CSP */
- PORT_Memset(noise, 0, (sizeof rng->V_Data) + entropy_len);
+ 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_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);
+ PORT_Free(noise);
}
return SECSuccess;
}
@@ -227,148 +227,165 @@ prng_reseed(RNGContext *rng, const PRUint8 *entropy, unsigned int entropy_len,
* 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)
+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;
+ /* error set by PRNGTEST_RunHealTests() */
+ rng->isValid = PR_FALSE;
+ return SECFailure;
}
- return prng_reseed(rng, entropy, entropy_len,
- additional_input, additional_input_len);
+ 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, carry) \
- { \
- int k1; \
+#define PRNG_ADD_CARRY_ONLY(dest, start, carry) \
+ { \
+ int k1; \
for (k1 = start; carry && k1 >= 0; k1--) { \
- carry = !(++dest[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) \
- carry = 0; \
- PORT_Assert((dest_len) >= (len)); \
- { \
- int k1, k2; \
+#define PRNG_ADD_BITS(dest, dest_len, add, len, carry) \
+ carry = 0; \
+ PORT_Assert((dest_len) >= (len)); \
+ { \
+ int k1, k2; \
for (k1 = dest_len - 1, k2 = len - 1; k2 >= 0; --k1, --k2) { \
- carry += dest[k1] + add[k2]; \
- dest[k1] = (PRUint8) carry; \
- carry >>= 8; \
- } \
+ carry += dest[k1] + add[k2]; \
+ dest[k1] = (PRUint8)carry; \
+ carry >>= 8; \
+ } \
}
#define PRNG_ADD_BITS_AND_CARRY(dest, dest_len, add, len, carry) \
- PRNG_ADD_BITS(dest, dest_len, add, len, carry) \
+ PRNG_ADD_BITS(dest, dest_len, add, len, carry) \
PRNG_ADD_CARRY_ONLY(dest, dest_len - len, 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.
+ * 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)
+prng_Hashgen(RNGContext *rng, PRUint8 *returned_bytes,
+ unsigned int no_of_returned_bytes)
{
PRUint8 data[VSize(rng)];
+ PRUint8 thisHash[SHA256_LENGTH];
+ PRUint8 *lastHash = rng->lastOutput;
PORT_Memcpy(data, V(rng), VSize(rng));
while (no_of_returned_bytes) {
- SHA256Context ctx;
- unsigned int len;
- unsigned int carry;
-
- 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 */
+ SHA256Context ctx;
+ unsigned int len;
+ unsigned int carry;
+
+ SHA256_Begin(&ctx);
+ SHA256_Update(&ctx, data, sizeof data);
+ SHA256_End(&ctx, thisHash, &len, SHA256_LENGTH);
+ if (PORT_Memcmp(lastHash, thisHash, len) == 0) {
+ rng->isValid = PR_FALSE;
+ break;
+ }
+ if (no_of_returned_bytes < SHA256_LENGTH) {
+ len = no_of_returned_bytes;
+ }
+ PORT_Memcpy(returned_bytes, thisHash, len);
+ lastHash = 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 */
carry = no_of_returned_bytes;
- PRNG_ADD_CARRY_ONLY(data, (sizeof data)- 1, carry);
+ PRNG_ADD_CARRY_ONLY(data, (sizeof data) - 1, carry);
}
- PORT_Memset(data, 0, sizeof data);
+ PORT_Memcpy(rng->lastOutput, thisHash, SHA256_LENGTH);
+ PORT_Memset(data, 0, sizeof data);
+ PORT_Memset(thisHash, 0, sizeof thisHash);
}
-/*
- * Generates new random bytes and advances the internal prng state.
+/*
+ * 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)
+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 */
+ PRUint8 H[SHA256_LENGTH]; /* both H and w since they
+ * aren't used concurrently */
unsigned int carry;
if (!rng->isValid) {
- PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
- return SECFailure;
+ 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 */
+ 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, carry)
- PORT_Memset(w, 0, sizeof w);
-#undef w
+ 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, carry)
+ 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) );
+ /* short_cut to hashbuf and a couple of copies and clears */
+ SHA256_HashBuf(returned_bytes, V(rng), VSize(rng));
+ /* continuous rng check */
+ if (memcmp(rng->lastOutput, returned_bytes, SHA256_LENGTH) == 0) {
+ rng->isValid = PR_FALSE;
+ }
+ PORT_Memcpy(rng->lastOutput, returned_bytes, sizeof rng->lastOutput);
} else {
- prng_Hashgen(rng, returned_bytes, no_of_returned_bytes);
+ 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, carry)
PRNG_ADD_BITS(V(rng), VSize(rng), rng->C, sizeof rng->C, carry);
- PRNG_ADD_BITS_AND_CARRY(V(rng), VSize(rng), rng->reseed_counter,
- sizeof rng->reseed_counter, carry)
+ PRNG_ADD_BITS_AND_CARRY(V(rng), VSize(rng), rng->reseed_counter,
+ sizeof rng->reseed_counter, carry)
carry = 1;
- PRNG_ADD_CARRY_ONLY(rng->reseed_counter,(sizeof rng->reseed_counter)-1, carry);
+ PRNG_ADD_CARRY_ONLY(rng->reseed_counter, (sizeof rng->reseed_counter) - 1, carry);
- /* 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;
+ /* if the prng failed, don't return any output, signal softoken */
+ if (!rng->isValid) {
+ PORT_Memset(returned_bytes, 0, no_of_returned_bytes);
+ PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
+ return SECFailure;
}
- PORT_Memcpy(rng->oldV, V(rng), sizeof rng->oldV);
return SECSuccess;
}
@@ -377,59 +394,60 @@ prng_generateNewBytes(RNGContext *rng,
*/
static const PRCallOnceType pristineCallOnce;
static PRCallOnceType coRNGInit;
-static PRStatus rng_init(void)
+static PRStatus
+rng_init(void)
{
- PRUint8 bytes[PRNG_SEEDLEN*2]; /* entropy + nonce */
+ 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;
+ /* 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();
+ /* 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;
}
@@ -446,12 +464,12 @@ prng_freeRNGContext(RNGContext *rng)
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);
+ 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));
+ memcpy(rng->C, inputhash, sizeof rng->C);
+ memcpy(V(rng), &inputhash[sizeof rng->C], VSize(rng));
memset(inputhash, 0, sizeof inputhash);
}
@@ -469,7 +487,7 @@ prng_freeRNGContext(RNGContext *rng)
* provide the generator with additional entropy is to call
* RNG_SystemInfoForRNG(). Note that C_Initialize() does exactly that.
*/
-SECStatus
+SECStatus
RNG_RNGInit(void)
{
/* Allow only one call to initialize the context */
@@ -482,7 +500,7 @@ RNG_RNGInit(void)
** Update the global random number generator with more seeding
** material.
*/
-SECStatus
+SECStatus
RNG_RandomUpdate(const void *data, size_t bytes)
{
SECStatus rv;
@@ -501,23 +519,23 @@ RNG_RandomUpdate(const void *data, size_t bytes)
* 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
+ * 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
+ * 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
+ * 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 > (size_t)PRNG_MAX_ADDITIONAL_BYTES) {
- bytes = PRNG_MAX_ADDITIONAL_BYTES;
+ bytes = PRNG_MAX_ADDITIONAL_BYTES;
}
#else
PR_STATIC_ASSERT(sizeof(size_t) <= 4);
@@ -526,41 +544,38 @@ RNG_RandomUpdate(const void *data, size_t bytes)
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;
+ 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;
- }
-
+ /* 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;
}
@@ -569,7 +584,7 @@ RNG_RandomUpdate(const void *data, size_t bytes)
** Generate some random bytes, using the global random number generator
** object.
*/
-static SECStatus
+static SECStatus
prng_GenerateGlobalRandomBytes(RNGContext *rng,
void *dest, size_t len)
{
@@ -578,13 +593,13 @@ prng_GenerateGlobalRandomBytes(RNGContext *rng,
/* check for a valid global RNG context */
PORT_Assert(rng != NULL);
if (rng == NULL) {
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- return SECFailure;
+ 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;
+ PORT_SetError(SEC_ERROR_INVALID_ARGS);
+ return SECFailure;
}
/* --- LOCKED --- */
PZ_Lock(rng->lock);
@@ -592,40 +607,40 @@ prng_GenerateGlobalRandomBytes(RNGContext *rng,
* 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);
+ 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
+ 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 */
+ 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;
+ rv = prng_generateNewBytes(rng, output, len,
+ rng->additionalAvail ? rng->additionalDataCache : NULL,
+ rng->additionalAvail);
+ rng->additionalAvail = 0;
}
PZ_Unlock(rng->lock);
/* --- UNLOCKED --- */
@@ -636,10 +651,24 @@ prng_GenerateGlobalRandomBytes(RNGContext *rng,
** Generate some random bytes, using the global random number generator
** object.
*/
-SECStatus
+SECStatus
RNG_GenerateGlobalRandomBytes(void *dest, size_t len)
{
+#ifdef UNSAFE_FUZZER_MODE
+ return prng_GenerateDeterministicRandomBytes(globalrng->lock, dest, len);
+#else
return prng_GenerateGlobalRandomBytes(globalrng, dest, len);
+#endif
+}
+
+SECStatus
+RNG_ResetForFuzzing(void)
+{
+#ifdef UNSAFE_FUZZER_MODE
+ return prng_ResetForFuzzing(globalrng->lock);
+#else
+ return SECFailure;
+#endif
}
void
@@ -648,9 +677,9 @@ 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;
+ /* Should set a "not initialized" error code. */
+ PORT_SetError(SEC_ERROR_NO_MEMORY);
+ return;
}
/* clear */
prng_freeRNGContext(globalrng);
@@ -662,7 +691,7 @@ RNG_RNGShutdown(void)
/*
* Test case interface. used by fips testing and power on self test
*/
- /* make sure the test context is separate from the global context, This
+/* 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;
@@ -672,249 +701,253 @@ RNGContext testContext;
* 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)
+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
+ 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;
+ 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)
+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;
+ 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;
+ /* 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);
-
+ additional_len);
}
SECStatus
-PRNGTEST_Generate(PRUint8 *bytes, unsigned int bytes_len,
- const PRUint8 *additional, unsigned int additional_len)
+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;
+ 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;
- }
+ rv = prng_reseed(&testContext, NULL, 0, NULL, 0);
+ if (rv != SECSuccess) {
+ return rv;
+ }
}
return prng_generateNewBytes(&testContext, bytes, bytes_len,
- additional, additional_len);
-
+ additional, additional_len);
}
SECStatus
PRNGTEST_Uninstantiate()
{
if (!testContext.isValid) {
- PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
- return SECFailure;
+ PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
+ return SECFailure;
}
- PORT_Memset(&testContext, 0, sizeof testContext);
- return SECSuccess;
+ 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.
+ 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;
+ * 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/nss/lib/freebl/dsa.c b/nss/lib/freebl/dsa.c
index 0da63ed..9324d30 100644
--- a/nss/lib/freebl/dsa.c
+++ b/nss/lib/freebl/dsa.c
@@ -21,12 +21,12 @@
#include "secmpi.h"
#include "pqg.h"
- /* XXX to be replaced by define in blapit.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.
+ * 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
@@ -34,7 +34,7 @@
*/
static SECStatus
fips186Change_ReduceModQForDSA(const PRUint8 *w, const PRUint8 *q,
- unsigned int qLen, PRUint8 * xj)
+ unsigned int qLen, PRUint8 *xj)
{
mp_int W, Q, Xj;
mp_err err;
@@ -44,41 +44,42 @@ fips186Change_ReduceModQForDSA(const PRUint8 *w, const PRUint8 *q,
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) );
+ 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) );
+ 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) );
+ 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;
+ 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.
+ * 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) {
+ unsigned char *xj)
+{
return fips186Change_ReduceModQForDSA(w, q, DSA1_SUBPRIME_LEN, xj);
}
@@ -112,13 +113,13 @@ FIPS186Change_GenerateX(PRUint8 *XKEY, const PRUint8 *XSEEDj,
** 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)
+static SECStatus
+dsa_GenerateGlobalRandomBytes(const SECItem *qItem, PRUint8 *dest,
+ unsigned int *destLen, unsigned int maxDestLen)
{
SECStatus rv;
SECItem w;
- const PRUint8 * q = qItem->data;
+ const PRUint8 *q = qItem->data;
unsigned int qLen = qItem->len;
if (*q == 0) {
@@ -132,7 +133,7 @@ dsa_GenerateGlobalRandomBytes(const SECItem * qItem, PRUint8 * dest,
return SECFailure;
}
w.data = NULL; /* otherwise SECITEM_AllocItem asserts */
- if (!SECITEM_AllocItem(NULL, &w, 2*qLen)) {
+ if (!SECITEM_AllocItem(NULL, &w, 2 * qLen)) {
return SECFailure;
}
*destLen = qLen;
@@ -146,13 +147,14 @@ dsa_GenerateGlobalRandomBytes(const SECItem * qItem, PRUint8 * dest,
return rv;
}
-static void translate_mpi_error(mp_err err)
+static void
+translate_mpi_error(mp_err err)
{
MP_TO_SEC_ERROR(err);
}
-static SECStatus
-dsa_NewKeyExtended(const PQGParams *params, const SECItem * seed,
+static SECStatus
+dsa_NewKeyExtended(const PQGParams *params, const SECItem *seed,
DSAPrivateKey **privKey)
{
mp_int p, g;
@@ -162,20 +164,20 @@ dsa_NewKeyExtended(const PQGParams *params, const SECItem * seed,
DSAPrivateKey *key;
/* Check args. */
if (!params || !privKey || !seed || !seed->data) {
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- return SECFailure;
+ 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;
+ 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;
+ PORT_SetError(SEC_ERROR_NO_MEMORY);
+ PORT_FreeArena(arena, PR_TRUE);
+ return SECFailure;
}
key->params.arena = arena;
/* Initialize MPI integers. */
@@ -183,25 +185,25 @@ dsa_NewKeyExtended(const PQGParams *params, const SECItem * seed,
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) );
+ 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) );
+ 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);
+ 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) );
+ CHECK_MPI_OK(mp_exptmod(&g, &x, &p, &y));
/* Store y in public key */
MPINT_TO_SECITEM(&y, &key->publicValue, arena);
*privKey = key;
@@ -212,16 +214,16 @@ cleanup:
mp_clear(&x);
mp_clear(&y);
if (key)
- PORT_FreeArena(key->params.arena, PR_TRUE);
+ PORT_FreeArena(key->params.arena, PR_TRUE);
if (err) {
- translate_mpi_error(err);
- return SECFailure;
+ translate_mpi_error(err);
+ return SECFailure;
}
return SECSuccess;
}
SECStatus
-DSA_NewRandom(PLArenaPool * arena, const SECItem * q, SECItem * seed)
+DSA_NewRandom(PLArenaPool *arena, const SECItem *q, SECItem *seed)
{
int retries = 10;
unsigned int i;
@@ -238,30 +240,31 @@ DSA_NewRandom(PLArenaPool * arena, const SECItem * q, SECItem * seed)
}
do {
- /* Generate seed bytes for x according to FIPS 186-1 appendix 3 */
+ /* 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;
- }
+ /* 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) {
+ PORT_SetError(SEC_ERROR_NEED_RANDOM);
+ loser:
+ if (arena != NULL) {
SECITEM_FreeItem(seed, PR_FALSE);
}
- return SECFailure;
+ return SECFailure;
}
return SECSuccess;
@@ -269,11 +272,11 @@ loser: if (arena != NULL) {
/*
** 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.
+** 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
+SECStatus
DSA_NewKey(const PQGParams *params, DSAPrivateKey **privKey)
{
SECItem seed;
@@ -281,7 +284,7 @@ DSA_NewKey(const PQGParams *params, DSAPrivateKey **privKey)
rv = PQG_Check(params);
if (rv != SECSuccess) {
- return rv;
+ return rv;
}
seed.data = NULL;
@@ -299,56 +302,56 @@ DSA_NewKey(const PQGParams *params, DSAPrivateKey **privKey)
}
/* For FIPS compliance testing. Seed must be exactly the size of subPrime */
-SECStatus
-DSA_NewKeyFromSeed(const PQGParams *params,
+SECStatus
+DSA_NewKeyFromSeed(const PQGParams *params,
const unsigned char *seed,
DSAPrivateKey **privKey)
{
SECItem seedItem;
- seedItem.data = (unsigned char*) seed;
+ seedItem.data = (unsigned char *)seed;
seedItem.len = PQG_GetLength(&params->subPrime);
return dsa_NewKeyExtended(params, &seedItem, privKey);
}
-static SECStatus
+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;
+ 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_int t; /* holding tmp values */
+ 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];
-
+ SECItem t2 = { siBuffer, NULL, 0 };
/* FIPS-compliance dictates that digest is a SHA hash. */
/* Check args. */
if (!key || !signature || !digest) {
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- return SECFailure;
+ PORT_SetError(SEC_ERROR_INVALID_ARGS);
+ return SECFailure;
}
dsa_subprime_len = PQG_GetLength(&key->params.subPrime);
- dsa_signature_len = dsa_subprime_len*2;
+ 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;
+ (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 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);
+ 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;
@@ -360,46 +363,56 @@ dsa_SignDigest(DSAPrivateKey *key, SECItem *signature, const SECItem *digest,
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) );
+ MP_DIGITS(&t) = 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));
+ CHECK_MPI_OK(mp_init(&t));
/*
** Convert stored PQG and private key into MPI integers.
*/
- SECITEM_TO_MPINT(key->params.prime, &p);
+ 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);
+ 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 */
- /*
+ 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 */
+ if (DSA_NewRandom(NULL, &key->params.subPrime, &t2) != SECSuccess) {
+ PORT_SetError(SEC_ERROR_NEED_RANDOM);
+ rv = SECFailure;
+ goto cleanup;
+ }
+ SECITEM_TO_MPINT(t2, &t); /* t <-$ Zq */
+ CHECK_MPI_OK(mp_mulmod(&k, &t, &q, &k)); /* k = k * t mod q */
+ CHECK_MPI_OK(mp_invmod(&k, &q, &k)); /* k = k**-1 mod q */
+ CHECK_MPI_OK(mp_mulmod(&k, &t, &q, &k)); /* k = k * t mod q */
+ SECITEM_TO_MPINT(localDigest, &s); /* s = HASH(M) */
+ 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;
+ PORT_SetError(SEC_ERROR_NEED_RANDOM);
+ rv = SECFailure;
+ goto cleanup;
}
/*
** Step 4
@@ -407,10 +420,12 @@ dsa_SignDigest(DSAPrivateKey *key, SECItem *signature, const SECItem *digest,
** 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;
+ 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:
@@ -422,9 +437,11 @@ cleanup:
mp_clear(&k);
mp_clear(&r);
mp_clear(&s);
+ mp_clear(&t);
+ SECITEM_FreeItem(&t2, PR_FALSE);
if (err) {
- translate_mpi_error(err);
- rv = SECFailure;
+ translate_mpi_error(err);
+ rv = SECFailure;
}
return rv;
}
@@ -435,53 +452,53 @@ cleanup:
** On output, signature->len == size of signature in buffer.
** Uses a random seed.
*/
-SECStatus
+SECStatus
DSA_SignDigest(DSAPrivateKey *key, SECItem *signature, const SECItem *digest)
{
SECStatus rv;
- int retries = 10;
+ 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;
+ PRBool good;
PORT_SetError(0);
do {
- rv = dsa_GenerateGlobalRandomBytes(&key->params.subPrime,
+ rv = dsa_GenerateGlobalRandomBytes(&key->params.subPrime,
kSeed, &kSeedLen, sizeof kSeed);
- if (rv != SECSuccess)
- break;
+ 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);
+ /* 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);
+ --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
+DSA_SignDigestWithSeed(DSAPrivateKey *key,
+ SECItem *signature,
+ const SECItem *digest,
+ const unsigned char *seed)
{
SECStatus rv;
rv = dsa_SignDigest(key, signature, digest, seed);
@@ -492,8 +509,8 @@ DSA_SignDigestWithSeed(DSAPrivateKey * key,
** On input, signature->len == size of buffer to hold signature.
** digest->len == size of digest.
*/
-SECStatus
-DSA_VerifyDigest(DSAPublicKey *key, const SECItem *signature,
+SECStatus
+DSA_VerifyDigest(DSAPublicKey *key, const SECItem *signature,
const SECItem *digest)
{
/* FIPS-compliance dictates that digest is a SHA hash. */
@@ -508,60 +525,59 @@ DSA_VerifyDigest(DSAPublicKey *key, const SECItem *signature,
SECStatus verified = SECFailure;
/* Check args. */
- if (!key || !signature || !digest ) {
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- return SECFailure;
+ 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;
+ 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;
+ (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 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);
+ 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(&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) );
+ 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.prime, &p);
SECITEM_TO_MPINT(key->params.subPrime, &q);
- SECITEM_TO_MPINT(key->params.base, &g);
- SECITEM_TO_MPINT(key->publicValue, &y);
+ SECITEM_TO_MPINT(key->params.base, &g);
+ SECITEM_TO_MPINT(key->publicValue, &y);
/*
** Convert received signature (r', s') into MPI integers.
*/
@@ -572,46 +588,46 @@ DSA_VerifyDigest(DSAPublicKey *key, const SECItem *signature,
*/
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 */
+ /* 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 */
+ 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 */
+ 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) );
+ 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 */
+ 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. */
+ PORT_SetError(SEC_ERROR_BAD_SIGNATURE);
+ verified = SECFailure; /* Signature failed to verify. */
} else {
- verified = SECSuccess; /* Signature verified. */
+ verified = SECSuccess; /* Signature verified. */
}
cleanup:
mp_clear(&p);
@@ -625,7 +641,7 @@ cleanup:
mp_clear(&v);
mp_clear(&w);
if (err) {
- translate_mpi_error(err);
+ translate_mpi_error(err);
}
return verified;
}
diff --git a/nss/lib/freebl/ec.c b/nss/lib/freebl/ec.c
index 4435f91..a9b7c05 100644
--- a/nss/lib/freebl/ec.c
+++ b/nss/lib/freebl/ec.c
@@ -6,7 +6,6 @@
#include "stubs.h"
#endif
-
#include "blapi.h"
#include "prerr.h"
#include "secerr.h"
@@ -18,7 +17,25 @@
#ifndef NSS_DISABLE_ECC
-/*
+static const ECMethod kMethods[] = {
+ { ECCurve25519,
+ ec_Curve25519_pt_mul,
+ ec_Curve25519_pt_validate }
+};
+
+static const ECMethod *
+ec_get_method_from_name(ECCurveName name)
+{
+ int i;
+ for (i = 0; i < sizeof(kMethods) / sizeof(kMethods[0]); ++i) {
+ if (kMethods[i].name == name) {
+ return &kMethods[i];
+ }
+ }
+ return NULL;
+}
+
+/*
* Returns true if pointP is the point at infinity, false otherwise
*/
PRBool
@@ -27,25 +44,23 @@ ec_point_at_infinity(SECItem *pointP)
unsigned int i;
for (i = 1; i < pointP->len; i++) {
- if (pointP->data[i] != 0x00) return PR_FALSE;
+ 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
+SECStatus
ec_points_mul(const ECParams *params, const mp_int *k1, const mp_int *k2,
- const SECItem *pointP, SECItem *pointQ)
+ 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;
@@ -56,120 +71,96 @@ ec_points_mul(const ECParams *params, const mp_int *k1, const mp_int *k2,
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]);
+ 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
+ if (k1 != NULL) {
+ mp_tohex((mp_int *)k1, mpstr);
+ printf("ec_points_mul: scalar k1: %s\n", mpstr);
+ mp_todecimal((mp_int *)k1, mpstr);
+ printf("ec_points_mul: scalar k1: %s (dec)\n", mpstr);
+ }
- /* 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);
- }
- }
+ if (k2 != NULL) {
+ mp_tohex((mp_int *)k2, mpstr);
+ printf("ec_points_mul: scalar k2: %s\n", mpstr);
+ mp_todecimal((mp_int *)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
- 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) );
+ /* 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 (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) );
+ 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]);
+ for (i = 0; i < pointQ->len; i++)
+ printf("%02x:", pointQ->data[i]);
printf("\n");
#endif
@@ -186,8 +177,8 @@ cleanup:
mp_clear(&a);
mp_clear(&b);
if (err) {
- MP_TO_SEC_ERROR(err);
- rv = SECFailure;
+ MP_TO_SEC_ERROR(err);
+ rv = SECFailure;
}
return rv;
@@ -195,12 +186,12 @@ cleanup:
#endif /* NSS_DISABLE_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
+ * 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
+ec_NewKey(ECParams *ecParams, ECPrivateKey **privKey,
+ const unsigned char *privKeyBytes, int privKeyLen)
{
SECStatus rv = SECFailure;
#ifndef NSS_DISABLE_ECC
@@ -215,19 +206,20 @@ ec_NewKey(ECParams *ecParams, ECPrivateKey **privKey,
#endif
MP_DIGITS(&k) = 0;
- if (!ecParams || !privKey || !privKeyBytes || (privKeyLen < 0)) {
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- return SECFailure;
+ if (!ecParams || !privKey || !privKeyBytes || (privKeyLen < 0) ||
+ !ecParams->name) {
+ 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;
+ return SECFailure;
key = (ECPrivateKey *)PORT_ArenaZAlloc(arena, sizeof(ECPrivateKey));
if (!key) {
- PORT_FreeArena(arena, PR_TRUE);
- return SECFailure;
+ PORT_FreeArena(arena, PR_TRUE);
+ return SECFailure;
}
/* Set the version number (SEC 1 section C.4 says it should be 1) */
@@ -241,80 +233,98 @@ ec_NewKey(ECParams *ecParams, ECPrivateKey **privKey,
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));
+ key->ecParams.pointSize = ecParams->pointSize;
+ if (ecParams->fieldID.type == ec_field_GFp ||
+ ecParams->fieldID.type == ec_field_plain) {
+ 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));
+ 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));
+ &ecParams->curve.a));
CHECK_SEC_OK(SECITEM_CopyItem(arena, &key->ecParams.curve.b,
- &ecParams->curve.b));
+ &ecParams->curve.b));
CHECK_SEC_OK(SECITEM_CopyItem(arena, &key->ecParams.curve.seed,
- &ecParams->curve.seed));
+ &ecParams->curve.seed));
CHECK_SEC_OK(SECITEM_CopyItem(arena, &key->ecParams.base,
- &ecParams->base));
+ &ecParams->base));
CHECK_SEC_OK(SECITEM_CopyItem(arena, &key->ecParams.order,
- &ecParams->order));
+ &ecParams->order));
key->ecParams.cofactor = ecParams->cofactor;
CHECK_SEC_OK(SECITEM_CopyItem(arena, &key->ecParams.DEREncoding,
- &ecParams->DEREncoding));
+ &ecParams->DEREncoding));
key->ecParams.name = ecParams->name;
CHECK_SEC_OK(SECITEM_CopyItem(arena, &key->ecParams.curveOID,
- &ecParams->curveOID));
+ &ecParams->curveOID));
- len = (ecParams->fieldID.size + 7) >> 3;
- SECITEM_AllocItem(arena, &key->publicValue, 2*len + 1);
+ SECITEM_AllocItem(arena, &key->publicValue, ecParams->pointSize);
len = ecParams->order.len;
SECITEM_AllocItem(arena, &key->privateValue, len);
/* Copy private key */
if (privKeyLen >= len) {
- memcpy(key->privateValue.data, privKeyBytes, len);
+ memcpy(key->privateValue.data, privKeyBytes, len);
} else {
- memset(key->privateValue.data, 0, (len - privKeyLen));
- memcpy(key->privateValue.data + (len - privKeyLen), privKeyBytes, privKeyLen);
+ 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) );
+
+ /* Use curve specific code for point multiplication */
+ if (ecParams->fieldID.type == ec_field_plain) {
+ const ECMethod *method = ec_get_method_from_name(ecParams->name);
+ if (method == NULL || method->mul == NULL) {
+ /* unknown curve */
+ rv = SECFailure;
+ goto cleanup;
+ }
+ rv = method->mul(&key->publicValue, &key->privateValue, NULL);
+ goto done;
+ }
+
+ 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;
+ if (rv != SECSuccess) {
+ goto cleanup;
+ }
+
+done:
*privKey = key;
cleanup:
mp_clear(&k);
- if (rv)
- PORT_FreeArena(arena, PR_TRUE);
+ if (rv) {
+ PORT_FreeArena(arena, PR_TRUE);
+ }
#if EC_DEBUG
- printf("ec_NewKey returning %s\n",
- (rv == SECSuccess) ? "success" : "failure");
+ printf("ec_NewKey returning %s\n",
+ (rv == SECSuccess) ? "success" : "failure");
#endif
#else
PORT_SetError(SEC_ERROR_UNSUPPORTED_KEYALG);
#endif /* NSS_DISABLE_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
+ * 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
+EC_NewKeyFromSeed(ECParams *ecParams, ECPrivateKey **privKey,
+ const unsigned char *seed, int seedlen)
{
SECStatus rv = SECFailure;
#ifndef NSS_DISABLE_ECC
@@ -349,35 +359,36 @@ ec_GenerateRandomPrivateKey(const unsigned char *order, int len)
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) );
+ 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);
+ 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;
+ MP_TO_SEC_ERROR(err);
+ rv = SECFailure;
}
if (rv != SECSuccess && privKeyBytes) {
- PORT_Free(privKeyBytes);
- privKeyBytes = NULL;
+ PORT_ZFree(privKeyBytes, 2 * len);
+ privKeyBytes = NULL;
}
return privKeyBytes;
}
@@ -387,7 +398,7 @@ cleanup:
* the public key is the result of performing a scalar point multiplication
* of that value with the curve's base point.
*/
-SECStatus
+SECStatus
EC_NewKey(ECParams *ecParams, ECPrivateKey **privKey)
{
SECStatus rv = SECFailure;
@@ -396,38 +407,39 @@ EC_NewKey(ECParams *ecParams, ECPrivateKey **privKey)
unsigned char *privKeyBytes = NULL;
if (!ecParams) {
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- return SECFailure;
+ PORT_SetError(SEC_ERROR_INVALID_ARGS);
+ return SECFailure;
}
len = ecParams->order.len;
privKeyBytes = ec_GenerateRandomPrivateKey(ecParams->order.data, len);
- if (privKeyBytes == NULL) goto cleanup;
+ if (privKeyBytes == NULL)
+ goto cleanup;
/* generate public key */
- CHECK_SEC_OK( ec_NewKey(ecParams, privKey, privKeyBytes, len) );
+ CHECK_SEC_OK(ec_NewKey(ecParams, privKey, privKeyBytes, len));
cleanup:
if (privKeyBytes) {
- PORT_ZFree(privKeyBytes, len);
+ PORT_ZFree(privKeyBytes, len);
}
#if EC_DEBUG
- printf("EC_NewKey returning %s\n",
- (rv == SECSuccess) ? "success" : "failure");
+ printf("EC_NewKey returning %s\n",
+ (rv == SECSuccess) ? "success" : "failure");
#endif
#else
PORT_SetError(SEC_ERROR_UNSUPPORTED_KEYALG);
#endif /* NSS_DISABLE_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
+ * public key is not valid. These attacks can be prevented by
* validating the public key before using ECDH.
*/
-SECStatus
+SECStatus
EC_ValidatePublicKey(ECParams *ecParams, SECItem *publicValue)
{
#ifndef NSS_DISABLE_ECC
@@ -437,59 +449,70 @@ EC_ValidatePublicKey(ECParams *ecParams, SECItem *publicValue)
mp_err err = MP_OKAY;
int len;
- if (!ecParams || !publicValue) {
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- return SECFailure;
+ if (!ecParams || !publicValue || !ecParams->name) {
+ PORT_SetError(SEC_ERROR_INVALID_ARGS);
+ return SECFailure;
+ }
+
+ /* Uses curve specific code for point validation. */
+ if (ecParams->fieldID.type == ec_field_plain) {
+ const ECMethod *method = ec_get_method_from_name(ecParams->name);
+ if (method == NULL || method->validate == NULL) {
+ /* unknown curve */
+ PORT_SetError(SEC_ERROR_INVALID_ARGS);
+ return SECFailure;
+ }
+ return method->validate(publicValue);
}
-
+
/* 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;
+ 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;
+ 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) );
+ 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) );
+ 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;
+ /*
+ * 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;
+ 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;
@@ -499,8 +522,8 @@ cleanup:
mp_clear(&Px);
mp_clear(&Py);
if (err) {
- MP_TO_SEC_ERROR(err);
- rv = SECFailure;
+ MP_TO_SEC_ERROR(err);
+ rv = SECFailure;
}
return rv;
#else
@@ -509,7 +532,7 @@ cleanup:
#endif /* NSS_DISABLE_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
@@ -519,17 +542,17 @@ cleanup:
** produced. It is the caller's responsibility to free the allocated
** buffer containing the derived secret.
*/
-SECStatus
-ECDH_Derive(SECItem *publicValue,
+SECStatus
+ECDH_Derive(SECItem *publicValue,
ECParams *ecParams,
- SECItem *privateValue,
- PRBool withCofactor,
- SECItem *derivedSecret)
+ SECItem *privateValue,
+ PRBool withCofactor,
+ SECItem *derivedSecret)
{
SECStatus rv = SECFailure;
#ifndef NSS_DISABLE_ECC
unsigned int len = 0;
- SECItem pointQ = {siBuffer, NULL, 0};
+ SECItem pointQ = { siBuffer, NULL, 0 };
mp_int k; /* to hold the private value */
mp_int cofactor;
mp_err err = MP_OKAY;
@@ -537,10 +560,32 @@ ECDH_Derive(SECItem *publicValue,
int i;
#endif
- if (!publicValue || !ecParams || !privateValue ||
- !derivedSecret) {
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- return SECFailure;
+ if (!publicValue || !ecParams || !privateValue || !derivedSecret ||
+ !ecParams->name) {
+ PORT_SetError(SEC_ERROR_INVALID_ARGS);
+ return SECFailure;
+ }
+
+ /* Perform curve specific multiplication using ECMethod */
+ if (ecParams->fieldID.type == ec_field_plain) {
+ const ECMethod *method;
+ memset(derivedSecret, 0, sizeof(*derivedSecret));
+ derivedSecret = SECITEM_AllocItem(NULL, derivedSecret, ecParams->pointSize);
+ if (derivedSecret == NULL) {
+ PORT_SetError(SEC_ERROR_NO_MEMORY);
+ return SECFailure;
+ }
+ method = ec_get_method_from_name(ecParams->name);
+ if (method == NULL || method->validate == NULL ||
+ method->mul == NULL) {
+ PORT_SetError(SEC_ERROR_UNSUPPORTED_ELLIPTIC_CURVE);
+ return SECFailure;
+ }
+ if (method->validate(publicValue) != SECSuccess) {
+ PORT_SetError(SEC_ERROR_BAD_KEY);
+ return SECFailure;
+ }
+ return method->mul(derivedSecret, privateValue, publicValue);
}
/*
@@ -548,34 +593,36 @@ ECDH_Derive(SECItem *publicValue,
* this produces predictable results.
*/
if (ec_point_at_infinity(publicValue)) {
- PORT_SetError(SEC_ERROR_BAD_KEY);
- return SECFailure;
+ PORT_SetError(SEC_ERROR_BAD_KEY);
+ 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;
+ len = (ecParams->fieldID.size + 7) >> 3;
+ pointQ.len = ecParams->pointSize;
+ if ((pointQ.data = PORT_Alloc(ecParams->pointSize)) == NULL)
+ goto cleanup;
- CHECK_MPI_OK( mp_init(&k) );
- CHECK_MPI_OK( mp_read_unsigned_octets(&k, privateValue->data,
- (mp_size) privateValue->len) );
+ 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 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_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;
+ PORT_SetError(SEC_ERROR_BAD_KEY); /* XXX better error code? */
+ goto cleanup;
}
/* Allocate memory for the derived secret and copy
@@ -588,8 +635,8 @@ ECDH_Derive(SECItem *publicValue,
#if EC_DEBUG
printf("derived_secret:\n");
- for (i = 0; i < derivedSecret->len; i++)
- printf("%02x:", derivedSecret->data[i]);
+ for (i = 0; i < derivedSecret->len; i++)
+ printf("%02x:", derivedSecret->data[i]);
printf("\n");
#endif
@@ -597,11 +644,11 @@ cleanup:
mp_clear(&k);
if (err) {
- MP_TO_SEC_ERROR(err);
+ MP_TO_SEC_ERROR(err);
}
if (pointQ.data) {
- PORT_ZFree(pointQ.data, 2*len + 1);
+ PORT_ZFree(pointQ.data, ecParams->pointSize);
}
#else
PORT_SetError(SEC_ERROR_UNSUPPORTED_KEYALG);
@@ -614,22 +661,24 @@ cleanup:
* 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
+ECDSA_SignDigestWithSeed(ECPrivateKey *key, SECItem *signature,
+ const SECItem *digest, const unsigned char *kb, const int kblen)
{
SECStatus rv = SECFailure;
#ifndef NSS_DISABLE_ECC
mp_int x1;
- mp_int d, k; /* private key, random integer */
- mp_int r, s; /* tuple (r, s) is the signature */
+ mp_int d, k; /* private key, random integer */
+ mp_int r, s; /* tuple (r, s) is the signature */
+ mp_int t; /* holding tmp values */
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 */
+ 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 */
+ unsigned char *t2 = NULL;
#if EC_DEBUG
char mpstr[256];
@@ -643,48 +692,49 @@ ECDSA_SignDigestWithSeed(ECPrivateKey *key, SECItem *signature,
MP_DIGITS(&r) = 0;
MP_DIGITS(&s) = 0;
MP_DIGITS(&n) = 0;
+ MP_DIGITS(&t) = 0;
/* Check args */
if (!key || !signature || !digest || !kb || (kblen < 0)) {
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- goto cleanup;
+ PORT_SetError(SEC_ERROR_INVALID_ARGS);
+ goto cleanup;
}
ecParams = &(key->ecParams);
flen = (ecParams->fieldID.size + 7) >> 3;
- olen = ecParams->order.len;
+ olen = ecParams->order.len;
if (signature->data == NULL) {
- /* a call to get the signature length only */
- goto finish;
+ /* a call to get the signature length only */
+ goto finish;
}
- if (signature->len < 2*olen) {
- PORT_SetError(SEC_ERROR_OUTPUT_LEN);
- goto cleanup;
+ 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));
+ CHECK_MPI_OK(mp_init(&t));
- 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 );
+ SECITEM_TO_MPINT(ecParams->order, &n);
+ SECITEM_TO_MPINT(key->privateValue, &d);
- CHECK_MPI_OK( mp_read_unsigned_octets(&k, kb, kblen) );
+ 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);
+ printf("k : %s \n", mpstr);
mp_tohex(&n, mpstr);
- printf("n : %s \n", mpstr);
+ printf("n : %s \n", mpstr);
#endif
- PORT_SetError(SEC_ERROR_NEED_RANDOM);
- goto cleanup;
+ PORT_SetError(SEC_ERROR_NEED_RANDOM);
+ goto cleanup;
}
/*
@@ -703,61 +753,60 @@ ECDSA_SignDigestWithSeed(ECPrivateKey *key, SECItem *signature,
** 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) );
+ 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) );
+ 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);
+ kGpoint.len = ecParams->pointSize;
+ kGpoint.data = PORT_Alloc(ecParams->pointSize);
if ((kGpoint.data == NULL) ||
- (ec_points_mul(ecParams, &k, NULL, NULL, &kGpoint)
- != SECSuccess))
- goto cleanup;
+ (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) );
+ 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) );
+ CHECK_MPI_OK(mp_mod(&x1, &n, &r));
/*
** ANSI X9.62, Section 5.3.3, Step 3
**
- ** verify r != 0
+ ** verify r != 0
*/
if (mp_cmp_z(&r) == 0) {
- PORT_SetError(SEC_ERROR_NEED_RANDOM);
- goto cleanup;
+ 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
+ ** s = (k**-1 * (HASH(M) + d*r)) mod n
*/
- SECITEM_TO_MPINT(*digest, &s); /* s = HASH(M) */
+ SECITEM_TO_MPINT(*digest, &s); /* s = HASH(M) */
/* In the definition of EC signing, digests are truncated
- * to the length of n in bits.
+ * 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);
+ CHECK_MPI_OK((obits = mpl_significant_bits(&n)));
+ if (digest->len * 8 > obits) {
+ mpl_rsh(&s, &s, digest->len * 8 - obits);
}
#if EC_DEBUG
@@ -775,10 +824,22 @@ ECDSA_SignDigestWithSeed(ECPrivateKey *key, SECItem *signature,
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 ((t2 = PORT_Alloc(2 * ecParams->order.len)) == NULL) {
+ rv = SECFailure;
+ goto cleanup;
+ }
+ if (RNG_GenerateGlobalRandomBytes(t2, 2 * ecParams->order.len) != SECSuccess) {
+ PORT_SetError(SEC_ERROR_NEED_RANDOM);
+ rv = SECFailure;
+ goto cleanup;
+ }
+ CHECK_MPI_OK(mp_read_unsigned_octets(&t, t2, 2 * ecParams->order.len)); /* t <-$ Zn */
+ CHECK_MPI_OK(mp_mulmod(&k, &t, &n, &k)); /* k = k * t mod n */
+ CHECK_MPI_OK(mp_invmod(&k, &n, &k)); /* k = k**-1 mod n */
+ CHECK_MPI_OK(mp_mulmod(&k, &t, &n, &k)); /* k = k * t 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);
@@ -793,18 +854,18 @@ ECDSA_SignDigestWithSeed(ECPrivateKey *key, SECItem *signature,
** verify s != 0
*/
if (mp_cmp_z(&s) == 0) {
- PORT_SetError(SEC_ERROR_NEED_RANDOM);
- goto cleanup;
+ 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) );
+ 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;
+ signature->len = 2 * olen;
rv = SECSuccess;
err = MP_OKAY;
@@ -815,60 +876,66 @@ cleanup:
mp_clear(&r);
mp_clear(&s);
mp_clear(&n);
+ mp_clear(&t);
+
+ if (t2) {
+ PORT_Free(t2);
+ }
if (kGpoint.data) {
- PORT_ZFree(kGpoint.data, 2*flen + 1);
+ PORT_ZFree(kGpoint.data, ecParams->pointSize);
}
if (err) {
- MP_TO_SEC_ERROR(err);
- rv = SECFailure;
+ MP_TO_SEC_ERROR(err);
+ rv = SECFailure;
}
#if EC_DEBUG
printf("ECDSA signing with seed %s\n",
- (rv == SECSuccess) ? "succeeded" : "failed");
+ (rv == SECSuccess) ? "succeeded" : "failed");
#endif
#else
PORT_SetError(SEC_ERROR_UNSUPPORTED_KEYALG);
#endif /* NSS_DISABLE_ECC */
- return rv;
+ return rv;
}
/*
-** Computes the ECDSA signature on the digest using the given key
+** Computes the ECDSA signature on the digest using the given key
** and a random seed.
*/
-SECStatus
+SECStatus
ECDSA_SignDigest(ECPrivateKey *key, SECItem *signature, const SECItem *digest)
{
SECStatus rv = SECFailure;
#ifndef NSS_DISABLE_ECC
int len;
- unsigned char *kBytes= NULL;
+ unsigned char *kBytes = NULL;
if (!key) {
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- return SECFailure;
+ 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;
+ if (kBytes == NULL)
+ goto cleanup;
/* Generate ECDSA signature with the specified k value */
rv = ECDSA_SignDigestWithSeed(key, signature, digest, kBytes, len);
-cleanup:
+cleanup:
if (kBytes) {
- PORT_ZFree(kBytes, len);
+ PORT_ZFree(kBytes, len);
}
#if EC_DEBUG
printf("ECDSA signing %s\n",
- (rv == SECSuccess) ? "succeeded" : "failed");
+ (rv == SECSuccess) ? "succeeded" : "failed");
#endif
#else
PORT_SetError(SEC_ERROR_UNSUPPORTED_KEYALG);
@@ -885,14 +952,14 @@ cleanup:
** of this function is undefined. In cases where a public key might
** not be valid, use EC_ValidatePublicKey to check.
*/
-SECStatus
-ECDSA_VerifyDigest(ECPublicKey *key, const SECItem *signature,
- const SECItem *digest)
+SECStatus
+ECDSA_VerifyDigest(ECPublicKey *key, const SECItem *signature,
+ const SECItem *digest)
{
SECStatus rv = SECFailure;
#ifndef NSS_DISABLE_ECC
- mp_int r_, s_; /* tuple (r', s') is received signature) */
- mp_int c, u1, u2, v; /* intermediate values used in verification */
+ 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;
@@ -916,45 +983,45 @@ ECDSA_VerifyDigest(ECPublicKey *key, const SECItem *signature,
MP_DIGITS(&u1) = 0;
MP_DIGITS(&u2) = 0;
MP_DIGITS(&x1) = 0;
- MP_DIGITS(&v) = 0;
- MP_DIGITS(&n) = 0;
+ MP_DIGITS(&v) = 0;
+ MP_DIGITS(&n) = 0;
/* Check args */
if (!key || !signature || !digest) {
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- goto cleanup;
+ 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;
+ 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;
+ slen = signature->len / 2;
- SECITEM_AllocItem(NULL, &pointC, 2*flen + 1);
+ SECITEM_AllocItem(NULL, &pointC, ecParams->pointSize);
if (pointC.data == NULL)
- goto cleanup;
+ 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) );
+ 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) );
-
- /*
+ 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
@@ -962,8 +1029,8 @@ ECDSA_VerifyDigest(ECPublicKey *key, const SECItem *signature,
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 */
+ PORT_SetError(SEC_ERROR_BAD_SIGNATURE);
+ goto cleanup; /* will return rv == SECFailure */
}
/*
@@ -971,21 +1038,21 @@ ECDSA_VerifyDigest(ECPublicKey *key, const SECItem *signature,
**
** c = (s')**-1 mod n
*/
- CHECK_MPI_OK( mp_invmod(&s_, &n, &c) ); /* 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) */
+ SECITEM_TO_MPINT(*digest, &u1); /* u1 = HASH(M) */
/* In the definition of EC signing, digests are truncated
- * to the length of n in bits.
+ * 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);
+ 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
@@ -999,14 +1066,14 @@ ECDSA_VerifyDigest(ECPublicKey *key, const SECItem *signature,
printf("digest: %s (dec)\n", mpstr);
#endif
- CHECK_MPI_OK( mp_mulmod(&u1, &c, &n, &u1) ); /* u1 = u1 * c mod n */
+ 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) );
+ CHECK_MPI_OK(mp_mulmod(&r_, &c, &n, &u2));
/*
** ANSI X9.62, Section 5.4.3, Step 1
@@ -1015,25 +1082,24 @@ ECDSA_VerifyDigest(ECPublicKey *key, const SECItem *signature,
** 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_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;
+ PORT_SetError(SEC_ERROR_BAD_SIGNATURE);
+ rv = SECFailure;
+ goto cleanup;
}
- CHECK_MPI_OK( mp_read_unsigned_octets(&x1, pointC.data + 1, flen) );
+ 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) );
+ CHECK_MPI_OK(mp_mod(&x1, &n, &v));
#if EC_DEBUG
mp_todecimal(&r_, mpstr);
@@ -1048,10 +1114,10 @@ ECDSA_VerifyDigest(ECPublicKey *key, const SECItem *signature,
** Verification: v == r'
*/
if (mp_cmp(&v, &r_)) {
- PORT_SetError(SEC_ERROR_BAD_SIGNATURE);
- rv = SECFailure; /* Signature failed to verify. */
+ PORT_SetError(SEC_ERROR_BAD_SIGNATURE);
+ rv = SECFailure; /* Signature failed to verify. */
} else {
- rv = SECSuccess; /* Signature verified. */
+ rv = SECSuccess; /* Signature verified. */
}
#if EC_DEBUG
@@ -1075,15 +1141,16 @@ cleanup:
mp_clear(&v);
mp_clear(&n);
- if (pointC.data) SECITEM_FreeItem(&pointC, PR_FALSE);
+ if (pointC.data)
+ SECITEM_ZfreeItem(&pointC, PR_FALSE);
if (err) {
- MP_TO_SEC_ERROR(err);
- rv = SECFailure;
+ MP_TO_SEC_ERROR(err);
+ rv = SECFailure;
}
#if EC_DEBUG
printf("ECDSA verification %s\n",
- (rv == SECSuccess) ? "succeeded" : "failed");
+ (rv == SECSuccess) ? "succeeded" : "failed");
#endif
#else
PORT_SetError(SEC_ERROR_UNSUPPORTED_KEYALG);
@@ -1091,4 +1158,3 @@ cleanup:
return rv;
}
-
diff --git a/nss/lib/freebl/ec.h b/nss/lib/freebl/ec.h
index 5a694d3..bb65e82 100644
--- a/nss/lib/freebl/ec.h
+++ b/nss/lib/freebl/ec.h
@@ -5,9 +5,17 @@
#ifndef __ec_h_
#define __ec_h_
-#define EC_DEBUG 0
+#define EC_DEBUG 0
-#define ANSI_X962_CURVE_OID_TOTAL_LEN 10
-#define SECG_CURVE_OID_TOTAL_LEN 7
+#define ANSI_X962_CURVE_OID_TOTAL_LEN 10
+#define SECG_CURVE_OID_TOTAL_LEN 7
+#define PKIX_NEWCURVES_OID_TOTAL_LEN 11
+
+struct ECMethodStr {
+ ECCurveName name;
+ SECStatus (*mul)(SECItem *result, SECItem *scalar, SECItem *point);
+ SECStatus (*validate)(const SECItem *point);
+};
+typedef struct ECMethodStr ECMethod;
#endif /* __ec_h_ */
diff --git a/nss/lib/freebl/ecdecode.c b/nss/lib/freebl/ecdecode.c
index 3c0294d..eda3f0c 100644
--- a/nss/lib/freebl/ecdecode.c
+++ b/nss/lib/freebl/ecdecode.c
@@ -15,8 +15,12 @@
#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
+#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
@@ -31,34 +35,39 @@ hexString2SECItem(PLArenaPool *arena, SECItem *item, const char *str)
int byteval = 0;
int tmp = PORT_Strlen(str);
- if ((tmp % 2) != 0) return NULL;
-
+ PORT_Assert(arena);
+ PORT_Assert(item);
+
+ 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;
+ 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++;
+ 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;
@@ -68,7 +77,7 @@ hexString2SECItem(PLArenaPool *arena, SECItem *item, const char *str)
*/
SECStatus
EC_CopyParams(PLArenaPool *arena, ECParams *dstParams,
- const ECParams *srcParams)
+ const ECParams *srcParams)
{
SECStatus rv = SECFailure;
@@ -76,31 +85,33 @@ EC_CopyParams(PLArenaPool *arena, ECParams *dstParams,
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));
+ dstParams->pointSize = srcParams->pointSize;
+ if (srcParams->fieldID.type == ec_field_GFp ||
+ srcParams->fieldID.type == ec_field_plain) {
+ 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));
+ 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));
+ &srcParams->curve.a));
CHECK_SEC_OK(SECITEM_CopyItem(arena, &dstParams->curve.b,
- &srcParams->curve.b));
+ &srcParams->curve.b));
CHECK_SEC_OK(SECITEM_CopyItem(arena, &dstParams->curve.seed,
- &srcParams->curve.seed));
+ &srcParams->curve.seed));
CHECK_SEC_OK(SECITEM_CopyItem(arena, &dstParams->base,
- &srcParams->base));
+ &srcParams->base));
CHECK_SEC_OK(SECITEM_CopyItem(arena, &dstParams->order,
- &srcParams->order));
+ &srcParams->order));
CHECK_SEC_OK(SECITEM_CopyItem(arena, &dstParams->DEREncoding,
- &srcParams->DEREncoding));
- dstParams->name = srcParams->name;
+ &srcParams->DEREncoding));
+ dstParams->name = srcParams->name;
CHECK_SEC_OK(SECITEM_CopyItem(arena, &dstParams->curveOID,
- &srcParams->curveOID));
+ &srcParams->curveOID));
dstParams->cofactor = srcParams->cofactor;
return SECSuccess;
@@ -117,31 +128,34 @@ gf_populate_params(ECCurveName name, ECFieldType field_type, ECParams *params)
/* 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;
+ 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));
+ params->pointSize = curveParams->pointSize;
+ if (field_type == ec_field_GFp ||
+ field_type == ec_field_plain) {
+ 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->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));
+ 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));
+ CHECK_OK(hexString2SECItem(params->arena, &params->order,
+ curveParams->order));
params->cofactor = curveParams->cofactor;
rv = SECSuccess;
@@ -152,34 +166,35 @@ cleanup:
SECStatus
EC_FillParams(PLArenaPool *arena, const SECItem *encodedParams,
- ECParams *params)
+ ECParams *params)
{
SECStatus rv = SECFailure;
SECOidTag tag;
- SECItem oid = { siBuffer, NULL, 0};
+ 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("%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;
+ (encodedParams->len != SECG_CURVE_OID_TOTAL_LEN) &&
+ (encodedParams->len != PKIX_NEWCURVES_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;
+ ((tag = SECOID_FindOIDTag(&oid)) == SEC_OID_UNKNOWN)) {
+ PORT_SetError(SEC_ERROR_UNSUPPORTED_ELLIPTIC_CURVE);
+ return SECFailure;
}
params->arena = arena;
@@ -187,10 +202,11 @@ EC_FillParams(PLArenaPool *arena, const SECItem *encodedParams,
params->type = ec_params_named;
params->name = ECCurve_noName;
- /* For named curves, fill out curveOID */
+ /* 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;
+ 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
@@ -198,374 +214,44 @@ EC_FillParams(PLArenaPool *arena, const SECItem *encodedParams,
#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;
+ 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_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;
+
+ case SEC_OID_CURVE25519:
+ /* Populate params for Curve25519 */
+ CHECK_SEC_OK(gf_populate_params(ECCurve25519, ec_field_plain, params));
+ break;
+
+ default:
+ break;
};
cleanup:
if (!params->cofactor) {
- PORT_SetError(SEC_ERROR_UNSUPPORTED_ELLIPTIC_CURVE);
+ PORT_SetError(SEC_ERROR_UNSUPPORTED_ELLIPTIC_CURVE);
#if EC_DEBUG
- printf("Unrecognized curve, returning NULL params\n");
+ printf("Unrecognized curve, returning NULL params\n");
#endif
}
@@ -581,29 +267,30 @@ EC_DecodeParams(const SECItem *encodedParams, ECParams **ecparams)
/* Initialize an arena for the ECParams structure */
if (!(arena = PORT_NewArena(NSS_FREEBL_DEFAULT_CHUNKSIZE)))
- return SECFailure;
+ return SECFailure;
params = (ECParams *)PORT_ArenaZAlloc(arena, sizeof(ECParams));
if (!params) {
- PORT_FreeArena(arena, PR_TRUE);
- return SECFailure;
+ PORT_FreeArena(arena, PR_TRUE);
+ return SECFailure;
}
/* Copy the encoded params */
SECITEM_AllocItem(arena, &(params->DEREncoding),
- encodedParams->len);
+ encodedParams->len);
memcpy(params->DEREncoding.data, encodedParams->data, encodedParams->len);
- /* Fill out the rest of the ECParams structure based on
- * the encoded params
+ /* 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;
+ PORT_FreeArena(arena, PR_TRUE);
+ return SECFailure;
} else {
- *ecparams = params;;
- return SECSuccess;
+ *ecparams = params;
+ ;
+ return SECSuccess;
}
}
diff --git a/nss/lib/freebl/ecl/Makefile b/nss/lib/freebl/ecl/Makefile
deleted file mode 100644
index 8237d06..0000000
--- a/nss/lib/freebl/ecl/Makefile
+++ /dev/null
@@ -1,195 +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 \
- ecp_256_32.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/nss/lib/freebl/ecl/README b/nss/lib/freebl/ecl/README
index f086cde..04a8b3b 100644
--- a/nss/lib/freebl/ecl/README
+++ b/nss/lib/freebl/ecl/README
@@ -24,9 +24,6 @@ and point multiplication operations. Used by higher level algorithms
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.
@@ -268,30 +265,3 @@ function in ec2_k163.c:
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/nss/lib/freebl/ecl/README.FP b/nss/lib/freebl/ecl/README.FP
deleted file mode 100644
index 833f42e..0000000
--- a/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/nss/lib/freebl/ecl/curve25519_32.c b/nss/lib/freebl/ecl/curve25519_32.c
new file mode 100644
index 0000000..0122961
--- /dev/null
+++ b/nss/lib/freebl/ecl/curve25519_32.c
@@ -0,0 +1,390 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+/*
+ * Derived from public domain code by Matthew Dempsky and D. J. Bernstein.
+ */
+
+#include "ecl-priv.h"
+#include "mpi.h"
+
+#include <stdint.h>
+#include <stdio.h>
+
+typedef uint32_t elem[32];
+
+/*
+ * Add two field elements.
+ * out = a + b
+ */
+static void
+add(elem out, const elem a, const elem b)
+{
+ uint32_t j;
+ uint32_t u = 0;
+ for (j = 0; j < 31; ++j) {
+ u += a[j] + b[j];
+ out[j] = u & 0xFF;
+ u >>= 8;
+ }
+ u += a[31] + b[31];
+ out[31] = u;
+}
+
+/*
+ * Subtract two field elements.
+ * out = a - b
+ */
+static void
+sub(elem out, const elem a, const elem b)
+{
+ uint32_t j;
+ uint32_t u;
+ u = 218;
+ for (j = 0; j < 31; ++j) {
+ u += a[j] + 0xFF00 - b[j];
+ out[j] = u & 0xFF;
+ u >>= 8;
+ }
+ u += a[31] - b[31];
+ out[31] = u;
+}
+
+/*
+ * "Squeeze" an element after multiplication (and square).
+ */
+static void
+squeeze(elem a)
+{
+ uint32_t j;
+ uint32_t u;
+ u = 0;
+ for (j = 0; j < 31; ++j) {
+ u += a[j];
+ a[j] = u & 0xFF;
+ u >>= 8;
+ }
+ u += a[31];
+ a[31] = u & 0x7F;
+ u = 19 * (u >> 7);
+ for (j = 0; j < 31; ++j) {
+ u += a[j];
+ a[j] = u & 0xFF;
+ u >>= 8;
+ }
+ a[31] += u;
+}
+
+static const elem minusp = { 19, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 128 };
+
+/*
+ * Reduce point a by 2^255-19
+ */
+static void
+reduce(elem a)
+{
+ elem aorig;
+ uint32_t j;
+ uint32_t negative;
+
+ for (j = 0; j < 32; ++j) {
+ aorig[j] = a[j];
+ }
+ add(a, a, minusp);
+ negative = 1 + ~((a[31] >> 7) & 1);
+ for (j = 0; j < 32; ++j) {
+ a[j] ^= negative & (aorig[j] ^ a[j]);
+ }
+}
+
+/*
+ * Multiplication and squeeze
+ * out = a * b
+ */
+static void
+mult(elem out, const elem a, const elem b)
+{
+ uint32_t i;
+ uint32_t j;
+ uint32_t u;
+
+ for (i = 0; i < 32; ++i) {
+ u = 0;
+ for (j = 0; j <= i; ++j) {
+ u += a[j] * b[i - j];
+ }
+ for (j = i + 1; j < 32; ++j) {
+ u += 38 * a[j] * b[i + 32 - j];
+ }
+ out[i] = u;
+ }
+ squeeze(out);
+}
+
+/*
+ * Multiplication
+ * out = 121665 * a
+ */
+static void
+mult121665(elem out, const elem a)
+{
+ uint32_t j;
+ uint32_t u;
+
+ u = 0;
+ for (j = 0; j < 31; ++j) {
+ u += 121665 * a[j];
+ out[j] = u & 0xFF;
+ u >>= 8;
+ }
+ u += 121665 * a[31];
+ out[31] = u & 0x7F;
+ u = 19 * (u >> 7);
+ for (j = 0; j < 31; ++j) {
+ u += out[j];
+ out[j] = u & 0xFF;
+ u >>= 8;
+ }
+ u += out[j];
+ out[j] = u;
+}
+
+/*
+ * Square a and squeeze the result.
+ * out = a * a
+ */
+static void
+square(elem out, const elem a)
+{
+ uint32_t i;
+ uint32_t j;
+ uint32_t u;
+
+ for (i = 0; i < 32; ++i) {
+ u = 0;
+ for (j = 0; j < i - j; ++j) {
+ u += a[j] * a[i - j];
+ }
+ for (j = i + 1; j < i + 32 - j; ++j) {
+ u += 38 * a[j] * a[i + 32 - j];
+ }
+ u *= 2;
+ if ((i & 1) == 0) {
+ u += a[i / 2] * a[i / 2];
+ u += 38 * a[i / 2 + 16] * a[i / 2 + 16];
+ }
+ out[i] = u;
+ }
+ squeeze(out);
+}
+
+/*
+ * Constant time swap between r and s depending on b
+ */
+static void
+cswap(uint32_t p[64], uint32_t q[64], uint32_t b)
+{
+ uint32_t j;
+ uint32_t swap = 1 + ~b;
+
+ for (j = 0; j < 64; ++j) {
+ const uint32_t t = swap & (p[j] ^ q[j]);
+ p[j] ^= t;
+ q[j] ^= t;
+ }
+}
+
+/*
+ * Montgomery ladder
+ */
+static void
+monty(elem x_2_out, elem z_2_out,
+ const elem point, const elem scalar)
+{
+ uint32_t x_3[64] = { 0 };
+ uint32_t x_2[64] = { 0 };
+ uint32_t a0[64];
+ uint32_t a1[64];
+ uint32_t b0[64];
+ uint32_t b1[64];
+ uint32_t c1[64];
+ uint32_t r[32];
+ uint32_t s[32];
+ uint32_t t[32];
+ uint32_t u[32];
+ uint32_t swap = 0;
+ uint32_t k_t = 0;
+ int j;
+
+ for (j = 0; j < 32; ++j) {
+ x_3[j] = point[j];
+ }
+ x_3[32] = 1;
+ x_2[0] = 1;
+
+ for (j = 254; j >= 0; --j) {
+ k_t = (scalar[j >> 3] >> (j & 7)) & 1;
+ swap ^= k_t;
+ cswap(x_2, x_3, swap);
+ swap = k_t;
+ add(a0, x_2, x_2 + 32);
+ sub(a0 + 32, x_2, x_2 + 32);
+ add(a1, x_3, x_3 + 32);
+ sub(a1 + 32, x_3, x_3 + 32);
+ square(b0, a0);
+ square(b0 + 32, a0 + 32);
+ mult(b1, a1, a0 + 32);
+ mult(b1 + 32, a1 + 32, a0);
+ add(c1, b1, b1 + 32);
+ sub(c1 + 32, b1, b1 + 32);
+ square(r, c1 + 32);
+ sub(s, b0, b0 + 32);
+ mult121665(t, s);
+ add(u, t, b0);
+ mult(x_2, b0, b0 + 32);
+ mult(x_2 + 32, s, u);
+ square(x_3, c1);
+ mult(x_3 + 32, r, point);
+ }
+
+ cswap(x_2, x_3, swap);
+ for (j = 0; j < 32; ++j) {
+ x_2_out[j] = x_2[j];
+ }
+ for (j = 0; j < 32; ++j) {
+ z_2_out[j] = x_2[j + 32];
+ }
+}
+
+static void
+recip(elem out, const elem z)
+{
+ elem z2;
+ elem z9;
+ elem z11;
+ elem z2_5_0;
+ elem z2_10_0;
+ elem z2_20_0;
+ elem z2_50_0;
+ elem z2_100_0;
+ elem t0;
+ elem t1;
+ int i;
+
+ /* 2 */ square(z2, z);
+ /* 4 */ square(t1, z2);
+ /* 8 */ square(t0, t1);
+ /* 9 */ mult(z9, t0, z);
+ /* 11 */ mult(z11, z9, z2);
+ /* 22 */ square(t0, z11);
+ /* 2^5 - 2^0 = 31 */ mult(z2_5_0, t0, z9);
+
+ /* 2^6 - 2^1 */ square(t0, z2_5_0);
+ /* 2^7 - 2^2 */ square(t1, t0);
+ /* 2^8 - 2^3 */ square(t0, t1);
+ /* 2^9 - 2^4 */ square(t1, t0);
+ /* 2^10 - 2^5 */ square(t0, t1);
+ /* 2^10 - 2^0 */ mult(z2_10_0, t0, z2_5_0);
+
+ /* 2^11 - 2^1 */ square(t0, z2_10_0);
+ /* 2^12 - 2^2 */ square(t1, t0);
+ /* 2^20 - 2^10 */
+ for (i = 2; i < 10; i += 2) {
+ square(t0, t1);
+ square(t1, t0);
+ }
+ /* 2^20 - 2^0 */ mult(z2_20_0, t1, z2_10_0);
+
+ /* 2^21 - 2^1 */ square(t0, z2_20_0);
+ /* 2^22 - 2^2 */ square(t1, t0);
+ /* 2^40 - 2^20 */
+ for (i = 2; i < 20; i += 2) {
+ square(t0, t1);
+ square(t1, t0);
+ }
+ /* 2^40 - 2^0 */ mult(t0, t1, z2_20_0);
+
+ /* 2^41 - 2^1 */ square(t1, t0);
+ /* 2^42 - 2^2 */ square(t0, t1);
+ /* 2^50 - 2^10 */
+ for (i = 2; i < 10; i += 2) {
+ square(t1, t0);
+ square(t0, t1);
+ }
+ /* 2^50 - 2^0 */ mult(z2_50_0, t0, z2_10_0);
+
+ /* 2^51 - 2^1 */ square(t0, z2_50_0);
+ /* 2^52 - 2^2 */ square(t1, t0);
+ /* 2^100 - 2^50 */
+ for (i = 2; i < 50; i += 2) {
+ square(t0, t1);
+ square(t1, t0);
+ }
+ /* 2^100 - 2^0 */ mult(z2_100_0, t1, z2_50_0);
+
+ /* 2^101 - 2^1 */ square(t1, z2_100_0);
+ /* 2^102 - 2^2 */ square(t0, t1);
+ /* 2^200 - 2^100 */
+ for (i = 2; i < 100; i += 2) {
+ square(t1, t0);
+ square(t0, t1);
+ }
+ /* 2^200 - 2^0 */ mult(t1, t0, z2_100_0);
+
+ /* 2^201 - 2^1 */ square(t0, t1);
+ /* 2^202 - 2^2 */ square(t1, t0);
+ /* 2^250 - 2^50 */
+ for (i = 2; i < 50; i += 2) {
+ square(t0, t1);
+ square(t1, t0);
+ }
+ /* 2^250 - 2^0 */ mult(t0, t1, z2_50_0);
+
+ /* 2^251 - 2^1 */ square(t1, t0);
+ /* 2^252 - 2^2 */ square(t0, t1);
+ /* 2^253 - 2^3 */ square(t1, t0);
+ /* 2^254 - 2^4 */ square(t0, t1);
+ /* 2^255 - 2^5 */ square(t1, t0);
+ /* 2^255 - 21 */ mult(out, t1, z11);
+}
+
+/*
+ * Computes q = Curve25519(p, s)
+ */
+SECStatus
+ec_Curve25519_mul(PRUint8 *q, const PRUint8 *s, const PRUint8 *p)
+{
+ elem point = { 0 };
+ elem x_2 = { 0 };
+ elem z_2 = { 0 };
+ elem X = { 0 };
+ elem scalar = { 0 };
+ uint32_t i;
+
+ /* read and mask scalar */
+ for (i = 0; i < 32; ++i) {
+ scalar[i] = s[i];
+ }
+ scalar[0] &= 0xF8;
+ scalar[31] &= 0x7F;
+ scalar[31] |= 64;
+
+ /* read and mask point */
+ for (i = 0; i < 32; ++i) {
+ point[i] = p[i];
+ }
+ point[31] &= 0x7F;
+
+ monty(x_2, z_2, point, scalar);
+ recip(z_2, z_2);
+ mult(X, x_2, z_2);
+ reduce(X);
+ for (i = 0; i < 32; ++i) {
+ q[i] = X[i];
+ }
+ return 0;
+}
diff --git a/nss/lib/freebl/ecl/curve25519_64.c b/nss/lib/freebl/ecl/curve25519_64.c
new file mode 100644
index 0000000..89327ad
--- /dev/null
+++ b/nss/lib/freebl/ecl/curve25519_64.c
@@ -0,0 +1,514 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+/*
+ * Derived from public domain C code by Adan Langley and Daniel J. Bernstein
+ */
+
+#include "uint128.h"
+
+#include "ecl-priv.h"
+#include "mpi.h"
+
+#include <stdint.h>
+#include <stdio.h>
+#include <string.h>
+
+typedef uint8_t u8;
+typedef uint64_t felem;
+
+/* Sum two numbers: output += in */
+static void
+fsum(felem *output, const felem *in)
+{
+ unsigned i;
+ for (i = 0; i < 5; ++i) {
+ output[i] += in[i];
+ }
+}
+
+/* Find the difference of two numbers: output = in - output
+ * (note the order of the arguments!)
+ */
+static void
+fdifference_backwards(felem *ioutput, const felem *iin)
+{
+ static const int64_t twotothe51 = ((int64_t)1l << 51);
+ const int64_t *in = (const int64_t *)iin;
+ int64_t *out = (int64_t *)ioutput;
+
+ out[0] = in[0] - out[0];
+ out[1] = in[1] - out[1];
+ out[2] = in[2] - out[2];
+ out[3] = in[3] - out[3];
+ out[4] = in[4] - out[4];
+
+ // An arithmetic shift right of 63 places turns a positive number to 0 and a
+ // negative number to all 1's. This gives us a bitmask that lets us avoid
+ // side-channel prone branches.
+ int64_t t;
+
+#define NEGCHAIN(a, b) \
+ t = out[a] >> 63; \
+ out[a] += twotothe51 & t; \
+ out[b] -= 1 & t;
+
+#define NEGCHAIN19(a, b) \
+ t = out[a] >> 63; \
+ out[a] += twotothe51 & t; \
+ out[b] -= 19 & t;
+
+ NEGCHAIN(0, 1);
+ NEGCHAIN(1, 2);
+ NEGCHAIN(2, 3);
+ NEGCHAIN(3, 4);
+ NEGCHAIN19(4, 0);
+ NEGCHAIN(0, 1);
+ NEGCHAIN(1, 2);
+ NEGCHAIN(2, 3);
+ NEGCHAIN(3, 4);
+}
+
+/* Multiply a number by a scalar: output = in * scalar */
+static void
+fscalar_product(felem *output, const felem *in,
+ const felem scalar)
+{
+ uint128_t tmp, tmp2;
+
+ tmp = mul6464(in[0], scalar);
+ output[0] = mask51(tmp);
+
+ tmp2 = mul6464(in[1], scalar);
+ tmp = add128(tmp2, rshift128(tmp, 51));
+ output[1] = mask51(tmp);
+
+ tmp2 = mul6464(in[2], scalar);
+ tmp = add128(tmp2, rshift128(tmp, 51));
+ output[2] = mask51(tmp);
+
+ tmp2 = mul6464(in[3], scalar);
+ tmp = add128(tmp2, rshift128(tmp, 51));
+ output[3] = mask51(tmp);
+
+ tmp2 = mul6464(in[4], scalar);
+ tmp = add128(tmp2, rshift128(tmp, 51));
+ output[4] = mask51(tmp);
+
+ output[0] += mask_lower(rshift128(tmp, 51)) * 19;
+}
+
+/* Multiply two numbers: output = in2 * in
+ *
+ * output must be distinct to both inputs. The inputs are reduced coefficient
+ * form, the output is not.
+ */
+static void
+fmul(felem *output, const felem *in2, const felem *in)
+{
+ uint128_t t0, t1, t2, t3, t4, t5, t6, t7, t8;
+
+ t0 = mul6464(in[0], in2[0]);
+ t1 = add128(mul6464(in[1], in2[0]), mul6464(in[0], in2[1]));
+ t2 = add128(add128(mul6464(in[0], in2[2]),
+ mul6464(in[2], in2[0])),
+ mul6464(in[1], in2[1]));
+ t3 = add128(add128(add128(mul6464(in[0], in2[3]),
+ mul6464(in[3], in2[0])),
+ mul6464(in[1], in2[2])),
+ mul6464(in[2], in2[1]));
+ t4 = add128(add128(add128(add128(mul6464(in[0], in2[4]),
+ mul6464(in[4], in2[0])),
+ mul6464(in[3], in2[1])),
+ mul6464(in[1], in2[3])),
+ mul6464(in[2], in2[2]));
+ t5 = add128(add128(add128(mul6464(in[4], in2[1]),
+ mul6464(in[1], in2[4])),
+ mul6464(in[2], in2[3])),
+ mul6464(in[3], in2[2]));
+ t6 = add128(add128(mul6464(in[4], in2[2]),
+ mul6464(in[2], in2[4])),
+ mul6464(in[3], in2[3]));
+ t7 = add128(mul6464(in[3], in2[4]), mul6464(in[4], in2[3]));
+ t8 = mul6464(in[4], in2[4]);
+
+ t0 = add128(t0, mul12819(t5));
+ t1 = add128(t1, mul12819(t6));
+ t2 = add128(t2, mul12819(t7));
+ t3 = add128(t3, mul12819(t8));
+
+ t1 = add128(t1, rshift128(t0, 51));
+ t0 = mask51full(t0);
+ t2 = add128(t2, rshift128(t1, 51));
+ t1 = mask51full(t1);
+ t3 = add128(t3, rshift128(t2, 51));
+ t4 = add128(t4, rshift128(t3, 51));
+ t0 = add128(t0, mul12819(rshift128(t4, 51)));
+ t1 = add128(t1, rshift128(t0, 51));
+ t2 = mask51full(t2);
+ t2 = add128(t2, rshift128(t1, 51));
+
+ output[0] = mask51(t0);
+ output[1] = mask51(t1);
+ output[2] = mask_lower(t2);
+ output[3] = mask51(t3);
+ output[4] = mask51(t4);
+}
+
+static void
+fsquare(felem *output, const felem *in)
+{
+ uint128_t t0, t1, t2, t3, t4, t5, t6, t7, t8;
+
+ t0 = mul6464(in[0], in[0]);
+ t1 = lshift128(mul6464(in[0], in[1]), 1);
+ t2 = add128(lshift128(mul6464(in[0], in[2]), 1),
+ mul6464(in[1], in[1]));
+ t3 = add128(lshift128(mul6464(in[0], in[3]), 1),
+ lshift128(mul6464(in[1], in[2]), 1));
+ t4 = add128(add128(lshift128(mul6464(in[0], in[4]), 1),
+ lshift128(mul6464(in[3], in[1]), 1)),
+ mul6464(in[2], in[2]));
+ t5 = add128(lshift128(mul6464(in[4], in[1]), 1),
+ lshift128(mul6464(in[2], in[3]), 1));
+ t6 = add128(lshift128(mul6464(in[4], in[2]), 1),
+ mul6464(in[3], in[3]));
+ t7 = lshift128(mul6464(in[3], in[4]), 1);
+ t8 = mul6464(in[4], in[4]);
+
+ t0 = add128(t0, mul12819(t5));
+ t1 = add128(t1, mul12819(t6));
+ t2 = add128(t2, mul12819(t7));
+ t3 = add128(t3, mul12819(t8));
+
+ t1 = add128(t1, rshift128(t0, 51));
+ t0 = mask51full(t0);
+ t2 = add128(t2, rshift128(t1, 51));
+ t1 = mask51full(t1);
+ t3 = add128(t3, rshift128(t2, 51));
+ t4 = add128(t4, rshift128(t3, 51));
+ t0 = add128(t0, mul12819(rshift128(t4, 51)));
+ t1 = add128(t1, rshift128(t0, 51));
+
+ output[0] = mask51(t0);
+ output[1] = mask_lower(t1);
+ output[2] = mask51(t2);
+ output[3] = mask51(t3);
+ output[4] = mask51(t4);
+}
+
+/* Take a 32-byte number and expand it into polynomial form */
+static void NO_SANITIZE_ALIGNMENT
+fexpand(felem *output, const u8 *in)
+{
+ output[0] = *((const uint64_t *)(in)) & MASK51;
+ output[1] = (*((const uint64_t *)(in + 6)) >> 3) & MASK51;
+ output[2] = (*((const uint64_t *)(in + 12)) >> 6) & MASK51;
+ output[3] = (*((const uint64_t *)(in + 19)) >> 1) & MASK51;
+ output[4] = (*((const uint64_t *)(in + 25)) >> 4) & MASK51;
+}
+
+/* Take a fully reduced polynomial form number and contract it into a
+ * 32-byte array
+ */
+static void
+fcontract(u8 *output, const felem *input)
+{
+ uint128_t t0 = init128x(input[0]);
+ uint128_t t1 = init128x(input[1]);
+ uint128_t t2 = init128x(input[2]);
+ uint128_t t3 = init128x(input[3]);
+ uint128_t t4 = init128x(input[4]);
+ uint128_t tmp = init128x(19);
+
+ t1 = add128(t1, rshift128(t0, 51));
+ t0 = mask51full(t0);
+ t2 = add128(t2, rshift128(t1, 51));
+ t1 = mask51full(t1);
+ t3 = add128(t3, rshift128(t2, 51));
+ t2 = mask51full(t2);
+ t4 = add128(t4, rshift128(t3, 51));
+ t3 = mask51full(t3);
+ t0 = add128(t0, mul12819(rshift128(t4, 51)));
+ t4 = mask51full(t4);
+
+ t1 = add128(t1, rshift128(t0, 51));
+ t0 = mask51full(t0);
+ t2 = add128(t2, rshift128(t1, 51));
+ t1 = mask51full(t1);
+ t3 = add128(t3, rshift128(t2, 51));
+ t2 = mask51full(t2);
+ t4 = add128(t4, rshift128(t3, 51));
+ t3 = mask51full(t3);
+ t0 = add128(t0, mul12819(rshift128(t4, 51)));
+ t4 = mask51full(t4);
+
+ /* now t is between 0 and 2^255-1, properly carried. */
+ /* case 1: between 0 and 2^255-20. case 2: between 2^255-19 and 2^255-1. */
+
+ t0 = add128(t0, tmp);
+
+ t1 = add128(t1, rshift128(t0, 51));
+ t0 = mask51full(t0);
+ t2 = add128(t2, rshift128(t1, 51));
+ t1 = mask51full(t1);
+ t3 = add128(t3, rshift128(t2, 51));
+ t2 = mask51full(t2);
+ t4 = add128(t4, rshift128(t3, 51));
+ t3 = mask51full(t3);
+ t0 = add128(t0, mul12819(rshift128(t4, 51)));
+ t4 = mask51full(t4);
+
+ /* now between 19 and 2^255-1 in both cases, and offset by 19. */
+
+ t0 = add128(t0, init128x(0x8000000000000 - 19));
+ tmp = init128x(0x8000000000000 - 1);
+ t1 = add128(t1, tmp);
+ t2 = add128(t2, tmp);
+ t3 = add128(t3, tmp);
+ t4 = add128(t4, tmp);
+
+ /* now between 2^255 and 2^256-20, and offset by 2^255. */
+
+ t1 = add128(t1, rshift128(t0, 51));
+ t0 = mask51full(t0);
+ t2 = add128(t2, rshift128(t1, 51));
+ t1 = mask51full(t1);
+ t3 = add128(t3, rshift128(t2, 51));
+ t2 = mask51full(t2);
+ t4 = add128(t4, rshift128(t3, 51));
+ t3 = mask51full(t3);
+ t4 = mask51full(t4);
+
+ *((uint64_t *)(output)) = mask_lower(t0) | mask_lower(t1) << 51;
+ *((uint64_t *)(output + 8)) = (mask_lower(t1) >> 13) | (mask_lower(t2) << 38);
+ *((uint64_t *)(output + 16)) = (mask_lower(t2) >> 26) | (mask_lower(t3) << 25);
+ *((uint64_t *)(output + 24)) = (mask_lower(t3) >> 39) | (mask_lower(t4) << 12);
+}
+
+/* Input: Q, Q', Q-Q'
+ * Output: 2Q, Q+Q'
+ *
+ * x2 z3: long form
+ * x3 z3: long form
+ * x z: short form, destroyed
+ * xprime zprime: short form, destroyed
+ * qmqp: short form, preserved
+ */
+static void
+fmonty(felem *x2, felem *z2, /* output 2Q */
+ felem *x3, felem *z3, /* output Q + Q' */
+ felem *x, felem *z, /* input Q */
+ felem *xprime, felem *zprime, /* input Q' */
+ const felem *qmqp /* input Q - Q' */)
+{
+ felem origx[5], origxprime[5], zzz[5], xx[5], zz[5], xxprime[5], zzprime[5],
+ zzzprime[5];
+
+ memcpy(origx, x, 5 * sizeof(felem));
+ fsum(x, z);
+ fdifference_backwards(z, origx); // does x - z
+
+ memcpy(origxprime, xprime, sizeof(felem) * 5);
+ fsum(xprime, zprime);
+ fdifference_backwards(zprime, origxprime);
+ fmul(xxprime, xprime, z);
+ fmul(zzprime, x, zprime);
+ memcpy(origxprime, xxprime, sizeof(felem) * 5);
+ fsum(xxprime, zzprime);
+ fdifference_backwards(zzprime, origxprime);
+ fsquare(x3, xxprime);
+ fsquare(zzzprime, zzprime);
+ fmul(z3, zzzprime, qmqp);
+
+ fsquare(xx, x);
+ fsquare(zz, z);
+ fmul(x2, xx, zz);
+ fdifference_backwards(zz, xx); // does zz = xx - zz
+ fscalar_product(zzz, zz, 121665);
+ fsum(zzz, xx);
+ fmul(z2, zz, zzz);
+}
+
+// -----------------------------------------------------------------------------
+// Maybe swap the contents of two felem arrays (@a and @b), each @len elements
+// long. Perform the swap iff @swap is non-zero.
+//
+// This function performs the swap without leaking any side-channel
+// information.
+// -----------------------------------------------------------------------------
+static void
+swap_conditional(felem *a, felem *b, unsigned len, felem iswap)
+{
+ unsigned i;
+ const felem swap = 1 + ~iswap;
+
+ for (i = 0; i < len; ++i) {
+ const felem x = swap & (a[i] ^ b[i]);
+ a[i] ^= x;
+ b[i] ^= x;
+ }
+}
+
+/* Calculates nQ where Q is the x-coordinate of a point on the curve
+ *
+ * resultx/resultz: the x coordinate of the resulting curve point (short form)
+ * n: a 32-byte number
+ * q: a point of the curve (short form)
+ */
+static void
+cmult(felem *resultx, felem *resultz, const u8 *n, const felem *q)
+{
+ felem a[5] = { 0 }, b[5] = { 1 }, c[5] = { 1 }, d[5] = { 0 };
+ felem *nqpqx = a, *nqpqz = b, *nqx = c, *nqz = d, *t;
+ felem e[5] = { 0 }, f[5] = { 1 }, g[5] = { 0 }, h[5] = { 1 };
+ felem *nqpqx2 = e, *nqpqz2 = f, *nqx2 = g, *nqz2 = h;
+
+ unsigned i, j;
+
+ memcpy(nqpqx, q, sizeof(felem) * 5);
+
+ for (i = 0; i < 32; ++i) {
+ u8 byte = n[31 - i];
+ for (j = 0; j < 8; ++j) {
+ const felem bit = byte >> 7;
+
+ swap_conditional(nqx, nqpqx, 5, bit);
+ swap_conditional(nqz, nqpqz, 5, bit);
+ fmonty(nqx2, nqz2, nqpqx2, nqpqz2, nqx, nqz, nqpqx, nqpqz, q);
+ swap_conditional(nqx2, nqpqx2, 5, bit);
+ swap_conditional(nqz2, nqpqz2, 5, bit);
+
+ t = nqx;
+ nqx = nqx2;
+ nqx2 = t;
+ t = nqz;
+ nqz = nqz2;
+ nqz2 = t;
+ t = nqpqx;
+ nqpqx = nqpqx2;
+ nqpqx2 = t;
+ t = nqpqz;
+ nqpqz = nqpqz2;
+ nqpqz2 = t;
+
+ byte <<= 1;
+ }
+ }
+
+ memcpy(resultx, nqx, sizeof(felem) * 5);
+ memcpy(resultz, nqz, sizeof(felem) * 5);
+}
+
+// -----------------------------------------------------------------------------
+// Shamelessly copied from djb's code
+// -----------------------------------------------------------------------------
+static void
+crecip(felem *out, const felem *z)
+{
+ felem z2[5];
+ felem z9[5];
+ felem z11[5];
+ felem z2_5_0[5];
+ felem z2_10_0[5];
+ felem z2_20_0[5];
+ felem z2_50_0[5];
+ felem z2_100_0[5];
+ felem t0[5];
+ felem t1[5];
+ int i;
+
+ /* 2 */ fsquare(z2, z);
+ /* 4 */ fsquare(t1, z2);
+ /* 8 */ fsquare(t0, t1);
+ /* 9 */ fmul(z9, t0, z);
+ /* 11 */ fmul(z11, z9, z2);
+ /* 22 */ fsquare(t0, z11);
+ /* 2^5 - 2^0 = 31 */ fmul(z2_5_0, t0, z9);
+
+ /* 2^6 - 2^1 */ fsquare(t0, z2_5_0);
+ /* 2^7 - 2^2 */ fsquare(t1, t0);
+ /* 2^8 - 2^3 */ fsquare(t0, t1);
+ /* 2^9 - 2^4 */ fsquare(t1, t0);
+ /* 2^10 - 2^5 */ fsquare(t0, t1);
+ /* 2^10 - 2^0 */ fmul(z2_10_0, t0, z2_5_0);
+
+ /* 2^11 - 2^1 */ fsquare(t0, z2_10_0);
+ /* 2^12 - 2^2 */ fsquare(t1, t0);
+ /* 2^20 - 2^10 */ for (i = 2; i < 10; i += 2) {
+ fsquare(t0, t1);
+ fsquare(t1, t0);
+ }
+ /* 2^20 - 2^0 */ fmul(z2_20_0, t1, z2_10_0);
+
+ /* 2^21 - 2^1 */ fsquare(t0, z2_20_0);
+ /* 2^22 - 2^2 */ fsquare(t1, t0);
+ /* 2^40 - 2^20 */ for (i = 2; i < 20; i += 2) {
+ fsquare(t0, t1);
+ fsquare(t1, t0);
+ }
+ /* 2^40 - 2^0 */ fmul(t0, t1, z2_20_0);
+
+ /* 2^41 - 2^1 */ fsquare(t1, t0);
+ /* 2^42 - 2^2 */ fsquare(t0, t1);
+ /* 2^50 - 2^10 */ for (i = 2; i < 10; i += 2) {
+ fsquare(t1, t0);
+ fsquare(t0, t1);
+ }
+ /* 2^50 - 2^0 */ fmul(z2_50_0, t0, z2_10_0);
+
+ /* 2^51 - 2^1 */ fsquare(t0, z2_50_0);
+ /* 2^52 - 2^2 */ fsquare(t1, t0);
+ /* 2^100 - 2^50 */ for (i = 2; i < 50; i += 2) {
+ fsquare(t0, t1);
+ fsquare(t1, t0);
+ }
+ /* 2^100 - 2^0 */ fmul(z2_100_0, t1, z2_50_0);
+
+ /* 2^101 - 2^1 */ fsquare(t1, z2_100_0);
+ /* 2^102 - 2^2 */ fsquare(t0, t1);
+ /* 2^200 - 2^100 */ for (i = 2; i < 100; i += 2) {
+ fsquare(t1, t0);
+ fsquare(t0, t1);
+ }
+ /* 2^200 - 2^0 */ fmul(t1, t0, z2_100_0);
+
+ /* 2^201 - 2^1 */ fsquare(t0, t1);
+ /* 2^202 - 2^2 */ fsquare(t1, t0);
+ /* 2^250 - 2^50 */ for (i = 2; i < 50; i += 2) {
+ fsquare(t0, t1);
+ fsquare(t1, t0);
+ }
+ /* 2^250 - 2^0 */ fmul(t0, t1, z2_50_0);
+
+ /* 2^251 - 2^1 */ fsquare(t1, t0);
+ /* 2^252 - 2^2 */ fsquare(t0, t1);
+ /* 2^253 - 2^3 */ fsquare(t1, t0);
+ /* 2^254 - 2^4 */ fsquare(t0, t1);
+ /* 2^255 - 2^5 */ fsquare(t1, t0);
+ /* 2^255 - 21 */ fmul(out, t1, z11);
+}
+
+SECStatus
+ec_Curve25519_mul(uint8_t *mypublic, const uint8_t *secret,
+ const uint8_t *basepoint)
+{
+ felem bp[5], x[5], z[5], zmone[5];
+ uint8_t e[32];
+ int i;
+
+ for (i = 0; i < 32; ++i) {
+ e[i] = secret[i];
+ }
+ e[0] &= 248;
+ e[31] &= 127;
+ e[31] |= 64;
+ fexpand(bp, basepoint);
+ cmult(x, z, e, bp);
+ crecip(zmone, z);
+ fmul(z, x, zmone);
+ fcontract(mypublic, z);
+
+ return 0;
+}
diff --git a/nss/lib/freebl/ecl/ec2.h b/nss/lib/freebl/ecl/ec2.h
deleted file mode 100644
index 5d75d48..0000000
--- a/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/nss/lib/freebl/ecl/ec2_163.c b/nss/lib/freebl/ecl/ec2_163.c
deleted file mode 100644
index 8ed40a4..0000000
--- a/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/nss/lib/freebl/ecl/ec2_193.c b/nss/lib/freebl/ecl/ec2_193.c
deleted file mode 100644
index edb38a6..0000000
--- a/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/nss/lib/freebl/ecl/ec2_233.c b/nss/lib/freebl/ecl/ec2_233.c
deleted file mode 100644
index f73673c..0000000
--- a/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/nss/lib/freebl/ecl/ec2_aff.c b/nss/lib/freebl/ecl/ec2_aff.c
deleted file mode 100644
index 50edc54..0000000
--- a/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/nss/lib/freebl/ecl/ec2_mont.c b/nss/lib/freebl/ecl/ec2_mont.c
deleted file mode 100644
index 8d35f25..0000000
--- a/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/nss/lib/freebl/ecl/ec2_proj.c b/nss/lib/freebl/ecl/ec2_proj.c
deleted file mode 100644
index 9378982..0000000
--- a/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/nss/lib/freebl/ecl/ec_naf.c b/nss/lib/freebl/ecl/ec_naf.c
index 3db6f30..cad08cb 100644
--- a/nss/lib/freebl/ecl/ec_naf.c
+++ b/nss/lib/freebl/ecl/ec_naf.c
@@ -4,22 +4,22 @@
#include "ecl-priv.h"
-/* Returns 2^e as an integer. This is meant to be used for small powers of
+/* 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;
+ int a = 1;
+ int i;
- for (i = 0; i < e; i++) {
- a *= 2;
- }
- return a;
+ 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
+ * 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
@@ -27,43 +27,42 @@ ec_twoTo(int e)
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;
+ mp_int k;
+ mp_err res = MP_OKAY;
+ int i, twowm1, mask;
- twowm1 = ec_twoTo(w - 1);
- mask = 2 * twowm1 - 1;
+ twowm1 = ec_twoTo(w - 1);
+ mask = 2 * twowm1 - 1;
- MP_DIGITS(&k) = 0;
- MP_CHECKOK(mp_init_copy(&k, in));
+ 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;
+ 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_CHECKOK(mp_sub_d(&k, out[i], &k));
+ } else {
+ MP_CHECKOK(mp_add_d(&k, -(out[i]), &k));
+ }
+ } else {
+ out[i] = 0;
+ }
+ MP_CHECKOK(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/nss/lib/freebl/ecl/ecl-curve.h b/nss/lib/freebl/ecl/ecl-curve.h
index d81d6df..df06139 100644
--- a/nss/lib/freebl/ecl/ecl-curve.h
+++ b/nss/lib/freebl/ecl/ecl-curve.h
@@ -8,103 +8,116 @@
#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
+/* copied from certt.h */
+#define KU_DIGITAL_SIGNATURE (0x80) /* bit 0 */
+#define KU_KEY_AGREEMENT (0x08) /* bit 4 */
static const ECCurveParams ecCurve_NIST_P256 = {
- "NIST-P256", ECField_GFp, 256,
- "FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFF",
- "FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFC",
- "5AC635D8AA3A93E7B3EBBD55769886BC651D06B0CC53B0F63BCE3C3E27D2604B",
- "6B17D1F2E12C4247F8BCE6E563A440F277037D812DEB33A0F4A13945D898C296",
- "4FE342E2FE1A7F9B8EE7EB4A7C0F9E162BCE33576B315ECECBB6406837BF51F5",
- "FFFFFFFF00000000FFFFFFFFFFFFFFFFBCE6FAADA7179E84F3B9CAC2FC632551", 1
+ "NIST-P256", ECField_GFp, 256,
+ "FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFF",
+ "FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFC",
+ "5AC635D8AA3A93E7B3EBBD55769886BC651D06B0CC53B0F63BCE3C3E27D2604B",
+ "6B17D1F2E12C4247F8BCE6E563A440F277037D812DEB33A0F4A13945D898C296",
+ "4FE342E2FE1A7F9B8EE7EB4A7C0F9E162BCE33576B315ECECBB6406837BF51F5",
+ "FFFFFFFF00000000FFFFFFFFFFFFFFFFBCE6FAADA7179E84F3B9CAC2FC632551",
+ 1, 128, 65, KU_DIGITAL_SIGNATURE | KU_KEY_AGREEMENT
};
static const ECCurveParams ecCurve_NIST_P384 = {
- "NIST-P384", ECField_GFp, 384,
- "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFF0000000000000000FFFFFFFF",
- "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFF0000000000000000FFFFFFFC",
- "B3312FA7E23EE7E4988E056BE3F82D19181D9C6EFE8141120314088F5013875AC656398D8A2ED19D2A85C8EDD3EC2AEF",
- "AA87CA22BE8B05378EB1C71EF320AD746E1D3B628BA79B9859F741E082542A385502F25DBF55296C3A545E3872760AB7",
- "3617DE4A96262C6F5D9E98BF9292DC29F8F41DBD289A147CE9DA3113B5F0B8C00A60B1CE1D7E819D7A431D7C90EA0E5F",
- "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC7634D81F4372DDF581A0DB248B0A77AECEC196ACCC52973",
- 1
+ "NIST-P384", ECField_GFp, 384,
+ "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFF0000000000000000FFFFFFFF",
+ "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFF0000000000000000FFFFFFFC",
+ "B3312FA7E23EE7E4988E056BE3F82D19181D9C6EFE8141120314088F5013875AC656398D8A2ED19D2A85C8EDD3EC2AEF",
+ "AA87CA22BE8B05378EB1C71EF320AD746E1D3B628BA79B9859F741E082542A385502F25DBF55296C3A545E3872760AB7",
+ "3617DE4A96262C6F5D9E98BF9292DC29F8F41DBD289A147CE9DA3113B5F0B8C00A60B1CE1D7E819D7A431D7C90EA0E5F",
+ "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC7634D81F4372DDF581A0DB248B0A77AECEC196ACCC52973",
+ 1, 192, 97, KU_DIGITAL_SIGNATURE | KU_KEY_AGREEMENT
};
static const ECCurveParams ecCurve_NIST_P521 = {
- "NIST-P521", ECField_GFp, 521,
- "01FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF",
- "01FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC",
- "0051953EB9618E1C9A1F929A21A0B68540EEA2DA725B99B315F3B8B489918EF109E156193951EC7E937B1652C0BD3BB1BF073573DF883D2C34F1EF451FD46B503F00",
- "00C6858E06B70404E9CD9E3ECB662395B4429C648139053FB521F828AF606B4D3DBAA14B5E77EFE75928FE1DC127A2FFA8DE3348B3C1856A429BF97E7E31C2E5BD66",
- "011839296A789A3BC0045C8A5FB42C7D1BD998F54449579B446817AFBD17273E662C97EE72995EF42640C550B9013FAD0761353C7086A272C24088BE94769FD16650",
- "01FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA51868783BF2F966B7FCC0148F709A5D03BB5C9B8899C47AEBB6FB71E91386409",
- 1
+ "NIST-P521", ECField_GFp, 521,
+ "01FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF",
+ "01FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC",
+ "0051953EB9618E1C9A1F929A21A0B68540EEA2DA725B99B315F3B8B489918EF109E156193951EC7E937B1652C0BD3BB1BF073573DF883D2C34F1EF451FD46B503F00",
+ "00C6858E06B70404E9CD9E3ECB662395B4429C648139053FB521F828AF606B4D3DBAA14B5E77EFE75928FE1DC127A2FFA8DE3348B3C1856A429BF97E7E31C2E5BD66",
+ "011839296A789A3BC0045C8A5FB42C7D1BD998F54449579B446817AFBD17273E662C97EE72995EF42640C550B9013FAD0761353C7086A272C24088BE94769FD16650",
+ "01FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA51868783BF2F966B7FCC0148F709A5D03BB5C9B8899C47AEBB6FB71E91386409",
+ 1, 256, 133, KU_DIGITAL_SIGNATURE | KU_KEY_AGREEMENT
+};
+
+static const ECCurveParams ecCurve25519 = {
+ "Curve25519", ECField_GFp, 255,
+ "7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffed",
+ "076D06",
+ "00",
+ "0900000000000000000000000000000000000000000000000000000000000000",
+ "20AE19A1B8A086B4E01EDD2C7748D14C923D4D7E6D7C61B229E9C5A27ECED3D9",
+ "1000000000000000000000000000000014def9dea2f79cd65812631a5cf5d3ed",
+ 8, 128, 32, KU_KEY_AGREEMENT
};
/* 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 */
+ 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 */
+ &ecCurve25519, /* ECCurve25519 */
+ NULL /* ECCurve_pastLastCurve */
};
#endif
diff --git a/nss/lib/freebl/ecl/ecl-exp.h b/nss/lib/freebl/ecl/ecl-exp.h
index b79eb30..44adb8a 100644
--- a/nss/lib/freebl/ecl/ecl-exp.h
+++ b/nss/lib/freebl/ecl/ecl-exp.h
@@ -7,156 +7,161 @@
/* Curve field type */
typedef enum {
- ECField_GFp,
- ECField_GF2m
+ 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;
+ char *text;
+ ECField field;
+ unsigned int size;
+ char *irr;
+ char *curvea;
+ char *curveb;
+ char *genx;
+ char *geny;
+ char *order;
+ int cofactor;
+ int security;
+ int pointSize;
+ unsigned int usage;
};
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
+ ECCurve_noName = 0,
+
+ /* NIST prime curves */
+ ECCurve_NIST_P192, /* not supported */
+ ECCurve_NIST_P224, /* not supported */
+ ECCurve_NIST_P256,
+ ECCurve_NIST_P384,
+ ECCurve_NIST_P521,
+
+ /* NIST binary curves */
+ ECCurve_NIST_K163, /* not supported */
+ ECCurve_NIST_B163, /* not supported */
+ ECCurve_NIST_K233, /* not supported */
+ ECCurve_NIST_B233, /* not supported */
+ ECCurve_NIST_K283, /* not supported */
+ ECCurve_NIST_B283, /* not supported */
+ ECCurve_NIST_K409, /* not supported */
+ ECCurve_NIST_B409, /* not supported */
+ ECCurve_NIST_K571, /* not supported */
+ ECCurve_NIST_B571, /* not supported */
+
+ /* ANSI X9.62 prime curves */
+ /* ECCurve_X9_62_PRIME_192V1 == ECCurve_NIST_P192 */
+ ECCurve_X9_62_PRIME_192V2, /* not supported */
+ ECCurve_X9_62_PRIME_192V3, /* not supported */
+ ECCurve_X9_62_PRIME_239V1, /* not supported */
+ ECCurve_X9_62_PRIME_239V2, /* not supported */
+ ECCurve_X9_62_PRIME_239V3, /* not supported */
+ /* ECCurve_X9_62_PRIME_256V1 == ECCurve_NIST_P256 */
+
+ /* ANSI X9.62 binary curves */
+ ECCurve_X9_62_CHAR2_PNB163V1, /* not supported */
+ ECCurve_X9_62_CHAR2_PNB163V2, /* not supported */
+ ECCurve_X9_62_CHAR2_PNB163V3, /* not supported */
+ ECCurve_X9_62_CHAR2_PNB176V1, /* not supported */
+ ECCurve_X9_62_CHAR2_TNB191V1, /* not supported */
+ ECCurve_X9_62_CHAR2_TNB191V2, /* not supported */
+ ECCurve_X9_62_CHAR2_TNB191V3, /* not supported */
+ ECCurve_X9_62_CHAR2_PNB208W1, /* not supported */
+ ECCurve_X9_62_CHAR2_TNB239V1, /* not supported */
+ ECCurve_X9_62_CHAR2_TNB239V2, /* not supported */
+ ECCurve_X9_62_CHAR2_TNB239V3, /* not supported */
+ ECCurve_X9_62_CHAR2_PNB272W1, /* not supported */
+ ECCurve_X9_62_CHAR2_PNB304W1, /* not supported */
+ ECCurve_X9_62_CHAR2_TNB359V1, /* not supported */
+ ECCurve_X9_62_CHAR2_PNB368W1, /* not supported */
+ ECCurve_X9_62_CHAR2_TNB431R1, /* not supported */
+
+ /* SEC2 prime curves */
+ ECCurve_SECG_PRIME_112R1, /* not supported */
+ ECCurve_SECG_PRIME_112R2, /* not supported */
+ ECCurve_SECG_PRIME_128R1, /* not supported */
+ ECCurve_SECG_PRIME_128R2, /* not supported */
+ ECCurve_SECG_PRIME_160K1, /* not supported */
+ ECCurve_SECG_PRIME_160R1, /* not supported */
+ ECCurve_SECG_PRIME_160R2, /* not supported */
+ ECCurve_SECG_PRIME_192K1, /* not supported */
+ /* ECCurve_SECG_PRIME_192R1 == ECCurve_NIST_P192 */
+ ECCurve_SECG_PRIME_224K1, /* not supported */
+ /* ECCurve_SECG_PRIME_224R1 == ECCurve_NIST_P224 */
+ ECCurve_SECG_PRIME_256K1, /* not supported */
+ /* 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, /* not supported */
+ ECCurve_SECG_CHAR2_113R2, /* not supported */
+ ECCurve_SECG_CHAR2_131R1, /* not supported */
+ ECCurve_SECG_CHAR2_131R2, /* not supported */
+ /* ECCurve_SECG_CHAR2_163K1 == ECCurve_NIST_K163 */
+ ECCurve_SECG_CHAR2_163R1, /* not supported */
+ /* ECCurve_SECG_CHAR2_163R2 == ECCurve_NIST_B163 */
+ ECCurve_SECG_CHAR2_193R1, /* not supported */
+ ECCurve_SECG_CHAR2_193R2, /* not supported */
+ /* ECCurve_SECG_CHAR2_233K1 == ECCurve_NIST_K233 */
+ /* ECCurve_SECG_CHAR2_233R1 == ECCurve_NIST_B233 */
+ ECCurve_SECG_CHAR2_239K1, /* not supported */
+ /* 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, /* not supported */
+ /* 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, /* not supported */
+ ECCurve_WTLS_9, /* not supported */
+ /* ECCurve_WTLS_10 == ECCurve_NIST_K233 */
+ /* ECCurve_WTLS_11 == ECCurve_NIST_B233 */
+ /* ECCurve_WTLS_12 == ECCurve_NIST_P224 */
+
+ ECCurve25519,
+
+ ECCurve_pastLastCurve
} ECCurveName;
/* Aliased named curves */
-#define ECCurve_X9_62_PRIME_192V1 ECCurve_NIST_P192
+#define ECCurve_X9_62_PRIME_192V1 ECCurve_NIST_P192 /* not supported */
#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_192R1 ECCurve_NIST_P192 /* not supported */
+#define ECCurve_SECG_PRIME_224R1 ECCurve_NIST_P224 /* not supported */
#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_ */
+#define ECCurve_SECG_CHAR2_163K1 ECCurve_NIST_K163 /* not supported */
+#define ECCurve_SECG_CHAR2_163R2 ECCurve_NIST_B163 /* not supported */
+#define ECCurve_SECG_CHAR2_233K1 ECCurve_NIST_K233 /* not supported */
+#define ECCurve_SECG_CHAR2_233R1 ECCurve_NIST_B233 /* not supported */
+#define ECCurve_SECG_CHAR2_283K1 ECCurve_NIST_K283 /* not supported */
+#define ECCurve_SECG_CHAR2_283R1 ECCurve_NIST_B283 /* not supported */
+#define ECCurve_SECG_CHAR2_409K1 ECCurve_NIST_K409 /* not supported */
+#define ECCurve_SECG_CHAR2_409R1 ECCurve_NIST_B409 /* not supported */
+#define ECCurve_SECG_CHAR2_571K1 ECCurve_NIST_K571 /* not supported */
+#define ECCurve_SECG_CHAR2_571R1 ECCurve_NIST_B571 /* not supported */
+#define ECCurve_WTLS_3 ECCurve_NIST_K163 /* not supported */
+#define ECCurve_WTLS_4 ECCurve_SECG_CHAR2_113R1 /* not supported */
+#define ECCurve_WTLS_5 ECCurve_X9_62_CHAR2_PNB163V1 /* not supported */
+#define ECCurve_WTLS_6 ECCurve_SECG_PRIME_112R1 /* not supported */
+#define ECCurve_WTLS_7 ECCurve_SECG_PRIME_160R1 /* not supported */
+#define ECCurve_WTLS_10 ECCurve_NIST_K233 /* not supported */
+#define ECCurve_WTLS_11 ECCurve_NIST_B233 /* not supported */
+#define ECCurve_WTLS_12 ECCurve_NIST_P224 /* not supported */
+
+#endif /* __ecl_exp_h_ */
diff --git a/nss/lib/freebl/ecl/ecl-priv.h b/nss/lib/freebl/ecl/ecl-priv.h
index 16f80a4..f43f193 100644
--- a/nss/lib/freebl/ecl/ecl-priv.h
+++ b/nss/lib/freebl/ecl/ecl-priv.h
@@ -8,6 +8,7 @@
#include "ecl.h"
#include "mpi.h"
#include "mplogic.h"
+#include "../blapii.h"
/* MAX_FIELD_SIZE_DIGITS is the maximum size of field element supported */
/* the following needs to go away... */
@@ -18,212 +19,219 @@
#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))
+ (((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),
+/* 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))
+ ((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, carry) \
- { mp_word w; \
- w = ((mp_word)carry) + (a1) + (a2); \
- s = ACCUM(w); \
- carry = CARRYOUT(w); }
+#define MP_ADD_CARRY(a1, a2, s, carry) \
+ { \
+ mp_word w; \
+ w = ((mp_word)carry) + (a1) + (a2); \
+ s = ACCUM(w); \
+ carry = CARRYOUT(w); \
+ }
#define MP_SUB_BORROW(a1, a2, s, borrow) \
- { mp_word w; \
- w = ((mp_word)(a1)) - (a2) - borrow; \
- s = ACCUM(w); \
- borrow = (w >> MP_DIGIT_BIT) & 1; }
+ { \
+ mp_word w; \
+ w = ((mp_word)(a1)) - (a2)-borrow; \
+ s = ACCUM(w); \
+ borrow = (w >> MP_DIGIT_BIT) & 1; \
+ }
#else
-/* NOTE,
+/* NOTE,
* carry and borrow are both read and written.
* 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, carry) \
- { mp_digit tmp,sum; \
- tmp = (a1); \
- sum = tmp + (a2); \
- tmp = (sum < tmp); /* detect overflow */ \
- s = sum += carry; \
- carry = tmp + (sum < carry); }
+#define MP_ADD_CARRY(a1, a2, s, carry) \
+ { \
+ mp_digit tmp, sum; \
+ tmp = (a1); \
+ sum = tmp + (a2); \
+ tmp = (sum < tmp); /* detect overflow */ \
+ s = sum += carry; \
+ carry = tmp + (sum < carry); \
+ }
-#define MP_SUB_BORROW(a1, a2, s, borrow) \
- { mp_digit tmp; \
- tmp = (a1); \
- s = tmp - (a2); \
- tmp = (s > tmp); /* detect borrow */ \
- if (borrow && !s--) tmp++; \
- borrow = tmp; }
+#define MP_SUB_BORROW(a1, a2, s, borrow) \
+ { \
+ mp_digit tmp; \
+ tmp = (a1); \
+ s = tmp - (a2); \
+ tmp = (s > tmp); /* detect borrow */ \
+ if (borrow && !s--) \
+ tmp++; \
+ borrow = 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);
+ /* 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);
+ /* 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);
+ 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);
+ 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);
+ const GFMethod *meth);
mp_err ec_GFp_add_4(const mp_int *a, const mp_int *b, mp_int *r,
- const GFMethod *meth);
+ const GFMethod *meth);
mp_err ec_GFp_add_5(const mp_int *a, const mp_int *b, mp_int *r,
- const GFMethod *meth);
+ const GFMethod *meth);
mp_err ec_GFp_add_6(const mp_int *a, const mp_int *b, mp_int *r,
- const GFMethod *meth);
+ const GFMethod *meth);
mp_err ec_GFp_sub_3(const mp_int *a, const mp_int *b, mp_int *r,
- const GFMethod *meth);
+ const GFMethod *meth);
mp_err ec_GFp_sub_4(const mp_int *a, const mp_int *b, mp_int *r,
- const GFMethod *meth);
+ const GFMethod *meth);
mp_err ec_GFp_sub_5(const mp_int *a, const mp_int *b, mp_int *r,
- const GFMethod *meth);
+ const GFMethod *meth);
mp_err ec_GFp_sub_6(const mp_int *a, const mp_int *b, mp_int *r,
- const GFMethod *meth);
+ 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);
+ 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);
+ 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);
+ 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);
+ 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);
+ 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);
+ 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);
+ 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);
+ 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);
+ 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
+ * 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);
+ int w);
/* Optimized field arithmetic */
mp_err ec_group_set_gfp192(ECGroup *group, ECCurveName);
@@ -245,4 +253,5 @@ mp_err ec_group_set_nistp192_fp(ECGroup *group);
mp_err ec_group_set_nistp224_fp(ECGroup *group);
#endif
-#endif /* __ecl_priv_h_ */
+SECStatus ec_Curve25519_mul(PRUint8 *q, const PRUint8 *s, const PRUint8 *p);
+#endif /* __ecl_priv_h_ */
diff --git a/nss/lib/freebl/ecl/ecl.c b/nss/lib/freebl/ecl/ecl.c
index d55e593..3540af7 100644
--- a/nss/lib/freebl/ecl/ecl.c
+++ b/nss/lib/freebl/ecl/ecl.c
@@ -6,7 +6,6 @@
#include "mplogic.h"
#include "ecl.h"
#include "ecl-priv.h"
-#include "ec2.h"
#include "ecp.h"
#include <stdlib.h>
#include <string.h>
@@ -15,382 +14,288 @@
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));
+ 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;
+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)
+ 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;
+ mp_err res = MP_OKAY;
+ ECGroup *group = NULL;
- group = ECGroup_new();
- if (group == NULL)
- return 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;
+ 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;
+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)
+ 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;
+ mp_err res = MP_OKAY;
+ ECGroup *group = NULL;
- group = ECGroup_new();
- if (group == NULL)
- return 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;
+ 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;
+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)
+ const ECCurveParams *params)
{
- mp_int irr, curvea, curveb, genx, geny, order;
- int bits;
- ECGroup *group = NULL;
- mp_err res = MP_OKAY;
+ 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));
+ /* 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 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) {
- switch (name) {
-#ifdef NSS_ECC_MORE_THAN_SUITE_B
-#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;
-#endif /* NSS_ECC_MORE_THAN_SUITE_B */
- 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));
- MP_CHECKOK(ec_group_set_gfp256_32(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 */
- 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;
- }
+ /* determine which optimizations (if any) to use */
+ if (params->field == ECField_GFp) {
+ switch (name) {
+ 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));
+ MP_CHECKOK(ec_group_set_gfp256_32(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 */
+ group =
+ ECGroup_consGFp_mont(&irr, &curvea, &curveb, &genx, &geny,
+ &order, params->cofactor);
+ if (group == NULL) {
+ res = MP_UNDEF;
+ goto CLEANUP;
+ }
+ }
+ } 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;
- }
- }
+ /* 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;
+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)
+ECGroup_fromHex(const ECCurveParams *params)
{
- return ecgroup_fromNameAndHex(ECCurve_noName, 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;
+ ECGroup *group = NULL;
+ ECCurveParams *params = NULL;
+ mp_err res = MP_OKAY;
- params = EC_GetNamedCurveParams(name);
- if (params == NULL) {
- res = MP_UNDEF;
- goto CLEANUP;
- }
+ 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;
- }
+ /* 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;
+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)
+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
+ /* 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);
+ 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);
+ 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/nss/lib/freebl/ecl/ecl.h b/nss/lib/freebl/ecl/ecl.h
index 3e44803..ddcbb1f 100644
--- a/nss/lib/freebl/ecl/ecl.h
+++ b/nss/lib/freebl/ecl/ecl.h
@@ -8,6 +8,7 @@
#ifndef __ecl_h_
#define __ecl_h_
+#include "blapi.h"
#include "ecl-exp.h"
#include "mpi.h"
@@ -15,7 +16,7 @@ struct ECGroupStr;
typedef struct ECGroupStr ECGroup;
/* Construct ECGroup from hexadecimal representations of parameters. */
-ECGroup *ECGroup_fromHex(const ECCurveParams * params);
+ECGroup *ECGroup_fromHex(const ECCurveParams *params);
/* Construct ECGroup from named parameters. */
ECGroup *ECGroup_fromName(const ECCurveName name);
@@ -27,31 +28,33 @@ void ECGroup_free(ECGroup *group);
ECCurveParams *EC_GetNamedCurveParams(const ECCurveName name);
/* Duplicates an ECCurveParams */
-ECCurveParams *ECCurveParams_dup(const ECCurveParams * params);
+ECCurveParams *ECCurveParams_dup(const ECCurveParams *params);
/* Free an allocated ECCurveParams */
-void EC_FreeCurveParams(ECCurveParams * params);
+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)
+/* 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);
+ const mp_int *py, mp_int *qx, mp_int *qy);
-/* Elliptic curve scalar-point multiplication. Computes Q(x, y) = k1 * G +
+/* 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);
+ 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);
+mp_err ECPoint_validate(const ECGroup *group, const mp_int *px, const mp_int *py);
-#endif /* __ecl_h_ */
+SECStatus ec_Curve25519_pt_mul(SECItem *X, SECItem *k, SECItem *P);
+SECStatus ec_Curve25519_pt_validate(const SECItem *px);
+
+#endif /* __ecl_h_ */
diff --git a/nss/lib/freebl/ecl/ecl_curve.c b/nss/lib/freebl/ecl/ecl_curve.c
index 192dab1..cf090cf 100644
--- a/nss/lib/freebl/ecl/ecl_curve.c
+++ b/nss/lib/freebl/ecl/ecl_curve.c
@@ -8,47 +8,51 @@
#include <stdlib.h>
#include <string.h>
-#define CHECK(func) if ((func) == NULL) { res = 0; goto CLEANUP; }
+#define CHECK(func) \
+ if ((func) == NULL) { \
+ res = 0; \
+ goto CLEANUP; \
+ }
/* Duplicates an ECCurveParams */
ECCurveParams *
-ECCurveParams_dup(const ECCurveParams * params)
+ECCurveParams_dup(const ECCurveParams *params)
{
- int res = 1;
- ECCurveParams *ret = NULL;
+ 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;
+ 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;
+CLEANUP:
+ if (res != 1) {
+ EC_FreeCurveParams(ret);
+ return NULL;
+ }
+ return ret;
}
#undef CHECK
@@ -57,33 +61,33 @@ ECCurveParams_dup(const ECCurveParams * params)
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]);
- }
+ 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)
+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);
+ 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/nss/lib/freebl/ecl/ecl_gf.c b/nss/lib/freebl/ecl/ecl_gf.c
index d250d78..81b0077 100644
--- a/nss/lib/freebl/ecl/ecl_gf.c
+++ b/nss/lib/freebl/ecl/ecl_gf.c
@@ -12,22 +12,22 @@
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;
+ 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
@@ -35,126 +35,70 @@ GFMethod_new()
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;
+ 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;
}
/* 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);
+ 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. */
@@ -162,404 +106,404 @@ GFMethod_free(GFMethod *meth)
/* 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)
+ 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;
+ /* 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) */
+ /* 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);
+ 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)
+ 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;
+ 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)
+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);
- }
+ 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
- carry = 0;
- MP_ADD_CARRY(a0, r0, r0, carry);
- MP_ADD_CARRY(a1, r1, r1, carry);
- MP_ADD_CARRY(a2, r2, r2, carry);
+ carry = 0;
+ MP_ADD_CARRY(a0, r0, r0, carry);
+ MP_ADD_CARRY(a1, r1, r1, carry);
+ MP_ADD_CARRY(a2, r2, r2, 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" );
+ __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);
+ 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
- carry = 0;
- MP_SUB_BORROW(r0, a0, r0, carry);
- MP_SUB_BORROW(r1, a1, r1, carry);
- MP_SUB_BORROW(r2, a2, r2, carry);
+ carry = 0;
+ MP_SUB_BORROW(r0, a0, r0, carry);
+ MP_SUB_BORROW(r1, a1, r1, carry);
+ MP_SUB_BORROW(r2, a2, r2, 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" );
+ __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;
+ 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)
+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);
- }
+ 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
- carry = 0;
- MP_ADD_CARRY(a0, r0, r0, carry);
- MP_ADD_CARRY(a1, r1, r1, carry);
- MP_ADD_CARRY(a2, r2, r2, carry);
- MP_ADD_CARRY(a3, r3, r3, carry);
+ carry = 0;
+ MP_ADD_CARRY(a0, r0, r0, carry);
+ MP_ADD_CARRY(a1, r1, r1, carry);
+ MP_ADD_CARRY(a2, r2, r2, carry);
+ MP_ADD_CARRY(a3, r3, r3, 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" );
+ __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);
+ 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
- carry = 0;
- MP_SUB_BORROW(r0, a0, r0, carry);
- MP_SUB_BORROW(r1, a1, r1, carry);
- MP_SUB_BORROW(r2, a2, r2, carry);
- MP_SUB_BORROW(r3, a3, r3, carry);
+ carry = 0;
+ MP_SUB_BORROW(r0, a0, r0, carry);
+ MP_SUB_BORROW(r1, a1, r1, carry);
+ MP_SUB_BORROW(r2, a2, r2, carry);
+ MP_SUB_BORROW(r3, a3, r3, 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" );
+ __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;
+ 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)
+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_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);
+ }
+
+ carry = 0;
+ MP_ADD_CARRY(a0, r0, r0, carry);
+ MP_ADD_CARRY(a1, r1, r1, carry);
+ MP_ADD_CARRY(a2, r2, r2, carry);
+ MP_ADD_CARRY(a3, r3, r3, carry);
+ MP_ADD_CARRY(a4, r4, r4, 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);
carry = 0;
- MP_ADD_CARRY(a0, r0, r0, carry);
- MP_ADD_CARRY(a1, r1, r1, carry);
- MP_ADD_CARRY(a2, r2, r2, carry);
- MP_ADD_CARRY(a3, r3, r3, carry);
- MP_ADD_CARRY(a4, r4, r4, 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);
- carry = 0;
- MP_SUB_BORROW(r0, a0, r0, carry);
- MP_SUB_BORROW(r1, a1, r1, carry);
- MP_SUB_BORROW(r2, a2, r2, carry);
- MP_SUB_BORROW(r3, a3, r3, carry);
- MP_SUB_BORROW(r4, a4, r4, 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;
+ MP_SUB_BORROW(r0, a0, r0, carry);
+ MP_SUB_BORROW(r1, a1, r1, carry);
+ MP_SUB_BORROW(r2, a2, r2, carry);
+ MP_SUB_BORROW(r3, a3, r3, carry);
+ MP_SUB_BORROW(r4, a4, r4, 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)
+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_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);
+ }
+
+ carry = 0;
+ MP_ADD_CARRY(a0, r0, r0, carry);
+ MP_ADD_CARRY(a1, r1, r1, carry);
+ MP_ADD_CARRY(a2, r2, r2, carry);
+ MP_ADD_CARRY(a3, r3, r3, carry);
+ MP_ADD_CARRY(a4, r4, r4, carry);
+ MP_ADD_CARRY(a5, r5, r5, 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);
carry = 0;
- MP_ADD_CARRY(a0, r0, r0, carry);
- MP_ADD_CARRY(a1, r1, r1, carry);
- MP_ADD_CARRY(a2, r2, r2, carry);
- MP_ADD_CARRY(a3, r3, r3, carry);
- MP_ADD_CARRY(a4, r4, r4, carry);
- MP_ADD_CARRY(a5, r5, r5, 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);
- carry = 0;
- MP_SUB_BORROW(r0, a0, r0, carry);
- MP_SUB_BORROW(r1, a1, r1, carry);
- MP_SUB_BORROW(r2, a2, r2, carry);
- MP_SUB_BORROW(r3, a3, r3, carry);
- MP_SUB_BORROW(r4, a4, r4, carry);
- MP_SUB_BORROW(r5, a5, r5, 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;
+ MP_SUB_BORROW(r0, a0, r0, carry);
+ MP_SUB_BORROW(r1, a1, r1, carry);
+ MP_SUB_BORROW(r2, a2, r2, carry);
+ MP_SUB_BORROW(r3, a3, r3, carry);
+ MP_SUB_BORROW(r4, a4, r4, carry);
+ MP_SUB_BORROW(r5, a5, r5, 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;
}
/*
@@ -569,379 +513,380 @@ ec_GFp_add_6(const mp_int *a, const mp_int *b, mp_int *r,
* ... 3 words
*/
mp_err
-ec_GFp_sub_3(const mp_int *a, const mp_int *b, mp_int *r,
- const GFMethod *meth)
+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);
- }
+ 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
- borrow = 0;
- MP_SUB_BORROW(r0, b0, r0, borrow);
- MP_SUB_BORROW(r1, b1, r1, borrow);
- MP_SUB_BORROW(r2, b2, r2, borrow);
+ borrow = 0;
+ MP_SUB_BORROW(r0, b0, r0, borrow);
+ MP_SUB_BORROW(r1, b1, r1, borrow);
+ MP_SUB_BORROW(r2, b2, r2, 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" );
+ __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);
+ /* 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
- borrow = 0;
- MP_ADD_CARRY(b0, r0, r0, borrow);
- MP_ADD_CARRY(b1, r1, r1, borrow);
- MP_ADD_CARRY(b2, r2, r2, borrow);
+ borrow = 0;
+ MP_ADD_CARRY(b0, r0, r0, borrow);
+ MP_ADD_CARRY(b1, r1, r1, borrow);
+ MP_ADD_CARRY(b2, r2, r2, 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" );
+ __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));
- }
+ /* 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;
+ 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)
+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);
- }
+ 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
- borrow = 0;
- MP_SUB_BORROW(r0, b0, r0, borrow);
- MP_SUB_BORROW(r1, b1, r1, borrow);
- MP_SUB_BORROW(r2, b2, r2, borrow);
- MP_SUB_BORROW(r3, b3, r3, borrow);
+ borrow = 0;
+ MP_SUB_BORROW(r0, b0, r0, borrow);
+ MP_SUB_BORROW(r1, b1, r1, borrow);
+ MP_SUB_BORROW(r2, b2, r2, borrow);
+ MP_SUB_BORROW(r3, b3, r3, 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" );
+ __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);
+ /* 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
- borrow = 0;
- MP_ADD_CARRY(b0, r0, r0, borrow);
- MP_ADD_CARRY(b1, r1, r1, borrow);
- MP_ADD_CARRY(b2, r2, r2, borrow);
- MP_ADD_CARRY(b3, r3, r3, borrow);
+ borrow = 0;
+ MP_ADD_CARRY(b0, r0, r0, borrow);
+ MP_ADD_CARRY(b1, r1, r1, borrow);
+ MP_ADD_CARRY(b2, r2, r2, borrow);
+ MP_ADD_CARRY(b3, r3, r3, 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" );
+ __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));
- }
+ /* 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;
+ 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)
+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_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);
+ }
+
+ borrow = 0;
+ MP_SUB_BORROW(r0, b0, r0, borrow);
+ MP_SUB_BORROW(r1, b1, r1, borrow);
+ MP_SUB_BORROW(r2, b2, r2, borrow);
+ MP_SUB_BORROW(r3, b3, r3, borrow);
+ MP_SUB_BORROW(r4, b4, r4, 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);
borrow = 0;
- MP_SUB_BORROW(r0, b0, r0, borrow);
- MP_SUB_BORROW(r1, b1, r1, borrow);
- MP_SUB_BORROW(r2, b2, r2, borrow);
- MP_SUB_BORROW(r3, b3, r3, borrow);
- MP_SUB_BORROW(r4, b4, r4, 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);
- borrow = 0;
- MP_ADD_CARRY(b0, r0, r0, borrow);
- MP_ADD_CARRY(b1, r1, r1, borrow);
- MP_ADD_CARRY(b2, r2, r2, borrow);
- MP_ADD_CARRY(b3, r3, r3, 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;
+ MP_ADD_CARRY(b0, r0, r0, borrow);
+ MP_ADD_CARRY(b1, r1, r1, borrow);
+ MP_ADD_CARRY(b2, r2, r2, borrow);
+ MP_ADD_CARRY(b3, r3, r3, borrow);
+ MP_ADD_CARRY(b4, r4, r4, 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)
+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_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);
+ }
+
+ borrow = 0;
+ MP_SUB_BORROW(r0, b0, r0, borrow);
+ MP_SUB_BORROW(r1, b1, r1, borrow);
+ MP_SUB_BORROW(r2, b2, r2, borrow);
+ MP_SUB_BORROW(r3, b3, r3, borrow);
+ MP_SUB_BORROW(r4, b4, r4, borrow);
+ MP_SUB_BORROW(r5, b5, r5, 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);
borrow = 0;
- MP_SUB_BORROW(r0, b0, r0, borrow);
- MP_SUB_BORROW(r1, b1, r1, borrow);
- MP_SUB_BORROW(r2, b2, r2, borrow);
- MP_SUB_BORROW(r3, b3, r3, borrow);
- MP_SUB_BORROW(r4, b4, r4, borrow);
- MP_SUB_BORROW(r5, b5, r5, 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);
- borrow = 0;
- MP_ADD_CARRY(b0, r0, r0, borrow);
- MP_ADD_CARRY(b1, r1, r1, borrow);
- MP_ADD_CARRY(b2, r2, r2, borrow);
- MP_ADD_CARRY(b3, r3, r3, borrow);
- MP_ADD_CARRY(b4, r4, r4, 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;
+ MP_ADD_CARRY(b0, r0, r0, borrow);
+ MP_ADD_CARRY(b1, r1, r1, borrow);
+ MP_ADD_CARRY(b2, r2, r2, borrow);
+ MP_ADD_CARRY(b3, r3, r3, borrow);
+ MP_ADD_CARRY(b4, r4, r4, borrow);
+ MP_ADD_CARRY(b5, r5, r5, 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);
+ 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)
+ const GFMethod *meth)
{
- return mp_mulmod(a, b, &meth->irr, r);
+ 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);
+ 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)
+ 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;
- }
+ 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. */
@@ -949,9 +894,9 @@ ec_GFp_div(const mp_int *a, const mp_int *b, mp_int *r,
/* Adds two field elements. */
mp_err
ec_GF2m_add(const mp_int *a, const mp_int *b, mp_int *r,
- const GFMethod *meth)
+ const GFMethod *meth)
{
- return mp_badd(a, b, r);
+ return mp_badd(a, b, r);
}
/* Negates a field element. Note that for binary polynomial fields, the
@@ -959,55 +904,55 @@ ec_GF2m_add(const mp_int *a, const mp_int *b, mp_int *r,
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);
- }
+ 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);
+ 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)
+ const GFMethod *meth)
{
- return mp_bmulmod(a, b, meth->irr_arr, r);
+ 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);
+ 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)
+ 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);
- }
+ 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/nss/lib/freebl/ecl/ecl_mult.c b/nss/lib/freebl/ecl/ecl_mult.c
index 5932828..ffbcbf1 100644
--- a/nss/lib/freebl/ecl/ecl_mult.c
+++ b/nss/lib/freebl/ecl/ecl_mult.c
@@ -8,113 +8,110 @@
#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)
+/* 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)
+ const mp_int *py, mp_int *rx, mp_int *ry)
{
- mp_err res = MP_OKAY;
- mp_int kt;
+ mp_err res = MP_OKAY;
+ mp_int kt;
- ARGCHK((k != NULL) && (group != NULL), MP_BADARG);
- MP_DIGITS(&kt) = 0;
+ 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);
- }
+ /* 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));
- }
+ 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;
+CLEANUP:
+ if (MP_DIGITS(&kt) != MP_DIGITS(k)) {
+ mp_clear(&kt);
+ }
+ return res;
}
-/* Elliptic curve scalar-point multiplication. Computes R(x, y) = k1 * G +
+/* 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)
+ const mp_int *py, mp_int *rx, mp_int *ry,
+ const ECGroup *group)
{
- mp_err res = MP_OKAY;
- mp_int sx, sy;
+ 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);
+ 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);
- }
+ /* 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_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));
+ 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));
- }
+ 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));
+ 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));
- }
+ 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;
+CLEANUP:
+ mp_clear(&sx);
+ mp_clear(&sy);
+ return res;
}
-/* Elliptic curve scalar-point multiplication. Computes R(x, y) = k1 * G +
+/* 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
@@ -123,200 +120,186 @@ ec_pts_mul_basic(const mp_int *k1, const mp_int *k2, const mp_int *px,
* 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)
+ 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;
- unsigned int i, j;
- int ai, bi, d;
+ mp_err res = MP_OKAY;
+ mp_int precomp[4][4][2];
+ const mp_int *a, *b;
+ unsigned int i, j;
+ int ai, bi, d;
- ARGCHK(group != NULL, MP_BADARG);
- ARGCHK(!((k1 == NULL)
- && ((k2 == NULL) || (px == NULL)
- || (py == NULL))), MP_BADARG);
+ 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);
- }
+ /* 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) );
- }
- }
+ /* 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));
- }
+ /* 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;
+ d = (mpl_significant_bits(a) + 1) / 2;
- /* R = inf */
- mp_zero(rx);
- mp_zero(ry);
+ /* R = inf */
+ mp_zero(rx);
+ mp_zero(ry);
- for (i = d; i-- > 0;) {
- 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));
- }
+ for (i = d; i-- > 0;) {
+ 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));
- }
+ 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;
+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 +
+/* 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)
+ 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_err res = MP_OKAY;
+ mp_int k1t, k2t;
+ const mp_int *k1p, *k2p;
- MP_DIGITS(&k1t) = 0;
- MP_DIGITS(&k2t) = 0;
+ MP_DIGITS(&k1t) = 0;
+ MP_DIGITS(&k2t) = 0;
- ARGCHK(group != NULL, MP_BADARG);
+ 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;
- }
+ /* 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);
- }
+ /* 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;
+CLEANUP:
+ mp_clear(&k1t);
+ mp_clear(&k2t);
+ return res;
}
diff --git a/nss/lib/freebl/ecl/ecp.h b/nss/lib/freebl/ecl/ecp.h
index 4784b02..7e54e4e 100644
--- a/nss/lib/freebl/ecl/ecp.h
+++ b/nss/lib/freebl/ecl/ecp.h
@@ -16,17 +16,17 @@ 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);
+ 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);
+ 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);
+ 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);
@@ -36,25 +36,25 @@ mp_err ec_GFp_validate_point(const mp_int *px, const mp_int *py, const ECGroup *
* 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);
+ 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);
+ 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);
+ 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);
+ const mp_int *pz);
/* Sets P(px, py, pz) to be the point at infinity. Uses Jacobian
* coordinates. */
@@ -63,22 +63,22 @@ 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);
+ 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);
+ 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);
+ 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
@@ -87,9 +87,9 @@ mp_err ec_GFp_pt_mul_jac(const mp_int *n, const mp_int *px,
* 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);
+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
@@ -97,10 +97,10 @@ mp_err
* 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
+ * 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);
+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_ */
+#endif /* __ecp_h_ */
diff --git a/nss/lib/freebl/ecl/ecp_192.c b/nss/lib/freebl/ecl/ecp_192.c
deleted file mode 100644
index 0bfd95e..0000000
--- a/nss/lib/freebl/ecl/ecp_192.c
+++ /dev/null
@@ -1,493 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.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"
-
-#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. */
-static 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) */
- carry = 0;
- MP_ADD_CARRY(r0a, a3a, r0a, carry);
- MP_ADD_CARRY(r0b, a3b, r0b, carry);
- MP_ADD_CARRY(r1a, a3a, r1a, carry);
- MP_ADD_CARRY(r1b, a3b, r1b, carry);
- MP_ADD_CARRY(r2a, a4a, r2a, carry);
- MP_ADD_CARRY(r2b, a4b, r2b, carry);
- r3 = carry; carry = 0;
- MP_ADD_CARRY(r0a, a5a, r0a, carry);
- MP_ADD_CARRY(r0b, a5b, r0b, carry);
- MP_ADD_CARRY(r1a, a5a, r1a, carry);
- MP_ADD_CARRY(r1b, a5b, r1b, carry);
- MP_ADD_CARRY(r2a, a5a, r2a, carry);
- MP_ADD_CARRY(r2b, a5b, r2b, carry);
- r3 += carry; carry = 0;
- MP_ADD_CARRY(r1a, a4a, r1a, carry);
- MP_ADD_CARRY(r1b, a4b, r1b, carry);
- MP_ADD_CARRY(r2a, 0, r2a, carry);
- MP_ADD_CARRY(r2b, 0, r2b, carry);
- r3 += carry;
-
- /* reduce out the carry */
- while (r3) {
- carry = 0;
- MP_ADD_CARRY(r0a, r3, r0a, carry);
- MP_ADD_CARRY(r0b, 0, r0b, carry);
- MP_ADD_CARRY(r1a, r3, r1a, carry);
- MP_ADD_CARRY(r1b, 0, r1b, carry);
- MP_ADD_CARRY(r2a, 0, r2a, carry);
- MP_ADD_CARRY(r2b, 0, r2b, 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 */
- carry = 0;
- MP_ADD_CARRY(r0a, 1, r0a, carry);
- MP_ADD_CARRY(r0b, carry, r0a, 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
- carry = 0;
- MP_ADD_CARRY(r0, a3, r0, carry);
- MP_ADD_CARRY(r1, a3, r1, carry);
- MP_ADD_CARRY(r2, a4, r2, carry);
- r3 = carry; carry = 0;
- MP_ADD_CARRY(r0, a5, r0, carry);
- MP_ADD_CARRY(r1, a5, r1, carry);
- MP_ADD_CARRY(r2, a5, r2, carry);
- r3 += carry; carry = 0;
- MP_ADD_CARRY(r1, a4, r1, carry);
- MP_ADD_CARRY(r2, 0, r2, 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
- carry = 0;
- MP_ADD_CARRY(r0, r3, r0, carry);
- MP_ADD_CARRY(r1, r3, r1, carry);
- MP_ADD_CARRY(r2, 0, r2, 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 */
- carry = 0;
- MP_ADD_CARRY(r0, 1, r0, 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.
- */
-static 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
- carry = 0;
- MP_ADD_CARRY(a0, r0, r0, carry);
- MP_ADD_CARRY(a1, r1, r1, carry);
- MP_ADD_CARRY(a2, r2, r2, 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
- carry = 0;
- MP_ADD_CARRY(r0, 1, r0, carry);
- MP_ADD_CARRY(r1, 1, r1, carry);
- MP_ADD_CARRY(r2, 0, r2, 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.
- */
-static 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
- borrow = 0;
- MP_SUB_BORROW(r0, b0, r0, borrow);
- MP_SUB_BORROW(r1, b1, r1, borrow);
- MP_SUB_BORROW(r2, b2, r2, 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
- borrow = 0;
- MP_SUB_BORROW(r0, 1, r0, borrow);
- MP_SUB_BORROW(r1, 1, r1, borrow);
- MP_SUB_BORROW(r2, 0, r2, 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.
- */
-static 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. */
-static 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. */
-static 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/nss/lib/freebl/ecl/ecp_224.c b/nss/lib/freebl/ecl/ecp_224.c
deleted file mode 100644
index 142f255..0000000
--- a/nss/lib/freebl/ecl/ecp_224.c
+++ /dev/null
@@ -1,352 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.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"
-
-#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. */
-static 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, 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 ) */
- carry = 0;
- MP_ADD_CARRY (r1b, a3b, r1b, carry);
- MP_ADD_CARRY (r2a, a4a, r2a, carry);
- MP_ADD_CARRY (r2b, a4b, r2b, carry);
- MP_ADD_CARRY (r3a, a5a, r3a, carry);
- r3b = carry; carry = 0;
- MP_ADD_CARRY (r1b, a5b, r1b, carry);
- MP_ADD_CARRY (r2a, a6a, r2a, carry);
- MP_ADD_CARRY (r2b, a6b, r2b, carry);
- MP_ADD_CARRY (r3a, 0, r3a, carry);
- r3b += carry; carry = 0;
- MP_SUB_BORROW(r0a, a3b, r0a, carry);
- MP_SUB_BORROW(r0b, a4a, r0b, carry);
- MP_SUB_BORROW(r1a, a4b, r1a, carry);
- MP_SUB_BORROW(r1b, a5a, r1b, carry);
- MP_SUB_BORROW(r2a, a5b, r2a, carry);
- MP_SUB_BORROW(r2b, a6a, r2b, carry);
- MP_SUB_BORROW(r3a, a6b, r3a, carry);
- r3b -= carry; carry = 0;
- MP_SUB_BORROW(r0a, a5b, r0a, carry);
- MP_SUB_BORROW(r0b, a6a, r0b, carry);
- MP_SUB_BORROW(r1a, a6b, r1a, carry);
- if (carry) {
- MP_SUB_BORROW(r1b, 0, r1b, carry);
- MP_SUB_BORROW(r2a, 0, r2a, carry);
- MP_SUB_BORROW(r2b, 0, r2b, carry);
- MP_SUB_BORROW(r3a, 0, r3a, carry);
- r3b -= carry;
- }
-
- while (r3b > 0) {
- int tmp;
- carry = 0;
- MP_ADD_CARRY(r1b, r3b, r1b, carry);
- if (carry) {
- MP_ADD_CARRY(r2a, 0, r2a, carry);
- MP_ADD_CARRY(r2b, 0, r2b, carry);
- MP_ADD_CARRY(r3a, 0, r3a, carry);
- }
- tmp = carry; carry = 0;
- MP_SUB_BORROW(r0a, r3b, r0a, carry);
- if (carry) {
- MP_SUB_BORROW(r0b, 0, r0b, carry);
- MP_SUB_BORROW(r1a, 0, r1a, carry);
- MP_SUB_BORROW(r1b, 0, r1b, carry);
- MP_SUB_BORROW(r2a, 0, r2a, carry);
- MP_SUB_BORROW(r2b, 0, r2b, carry);
- MP_SUB_BORROW(r3a, 0, r3a, carry);
- tmp -= carry;
- }
- r3b = tmp;
- }
-
- while (r3b < 0) {
- mp_digit maxInt = MP_DIGIT_MAX;
- carry = 0;
- MP_ADD_CARRY (r0a, 1, r0a, carry);
- MP_ADD_CARRY (r0b, 0, r0b, carry);
- MP_ADD_CARRY (r1a, 0, r1a, carry);
- MP_ADD_CARRY (r1b, maxInt, r1b, carry);
- MP_ADD_CARRY (r2a, maxInt, r2a, carry);
- MP_ADD_CARRY (r2b, maxInt, r2b, carry);
- MP_ADD_CARRY (r3a, maxInt, r3a, 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 */
- carry = 0;
- MP_SUB_BORROW(r0a, 1, r0a, carry);
- MP_SUB_BORROW(r0b, 0, r0b, carry);
- MP_SUB_BORROW(r1a, 0, r1a, 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 ) */
- carry = 0;
- MP_ADD_CARRY (r1, a3b, r1, carry);
- MP_ADD_CARRY (r2, a4 , r2, carry);
- MP_ADD_CARRY (r3, a5a, r3, carry);
- carry = 0;
- MP_ADD_CARRY (r1, a5b, r1, carry);
- MP_ADD_CARRY (r2, a6 , r2, carry);
- MP_ADD_CARRY (r3, 0, r3, carry);
-
- carry = 0;
- MP_SUB_BORROW(r0, a4a_a3b, r0, carry);
- MP_SUB_BORROW(r1, a5a_a4b, r1, carry);
- MP_SUB_BORROW(r2, a6a_a5b, r2, carry);
- MP_SUB_BORROW(r3, a6b , r3, carry);
- carry = 0;
- MP_SUB_BORROW(r0, a6a_a5b, r0, carry);
- MP_SUB_BORROW(r1, a6b , r1, carry);
- if (carry) {
- MP_SUB_BORROW(r2, 0, r2, carry);
- MP_SUB_BORROW(r3, 0, r3, carry);
- }
-
-
- /* if the value is negative, r3 has a 2's complement
- * high value */
- r3b = (int)(r3 >>32);
- while (r3b > 0) {
- r3 &= 0xffffffff;
- carry = 0;
- MP_ADD_CARRY(r1,((mp_digit)r3b) << 32, r1, carry);
- if (carry) {
- MP_ADD_CARRY(r2, 0, r2, carry);
- MP_ADD_CARRY(r3, 0, r3, carry);
- }
- carry = 0;
- MP_SUB_BORROW(r0, r3b, r0, carry);
- if (carry) {
- MP_SUB_BORROW(r1, 0, r1, carry);
- MP_SUB_BORROW(r2, 0, r2, carry);
- MP_SUB_BORROW(r3, 0, r3, carry);
- }
- r3b = (int)(r3 >>32);
- }
-
- while (r3b < 0) {
- carry = 0;
- MP_ADD_CARRY (r0, 1, r0, carry);
- MP_ADD_CARRY (r1, MP_DIGIT_MAX <<32, r1, carry);
- MP_ADD_CARRY (r2, MP_DIGIT_MAX, r2, carry);
- MP_ADD_CARRY (r3, MP_DIGIT_MAX >> 32, r3, 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 */
- carry = 0;
- MP_SUB_BORROW(r0, 1, r0, carry);
- MP_SUB_BORROW(r1, MP_DIGIT_MAX << 32, r1, 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.
- */
-static 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. */
-static 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. */
-static 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/nss/lib/freebl/ecl/ecp_25519.c b/nss/lib/freebl/ecl/ecp_25519.c
new file mode 100644
index 0000000..a8d4152
--- /dev/null
+++ b/nss/lib/freebl/ecl/ecp_25519.c
@@ -0,0 +1,120 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+/* curve 25519 https://www.rfc-editor.org/rfc/rfc7748.txt */
+
+#ifdef FREEBL_NO_DEPEND
+#include "../stubs.h"
+#endif
+
+#include "ecl-priv.h"
+#include "ecp.h"
+#include "mpi.h"
+#include "mplogic.h"
+#include "mpi-priv.h"
+#include "secmpi.h"
+#include "secitem.h"
+#include "secport.h"
+#include <stdlib.h>
+#include <stdio.h>
+
+/*
+ * point validation is not necessary in general. But this checks a point (px)
+ * against some known bad values.
+ */
+SECStatus
+ec_Curve25519_pt_validate(const SECItem *px)
+{
+ PRUint8 *p;
+ int i;
+ PRUint8 forbiddenValues[12][32] = {
+ { 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 },
+ { 0x01, 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 },
+ { 0xe0, 0xeb, 0x7a, 0x7c, 0x3b, 0x41, 0xb8, 0xae,
+ 0x16, 0x56, 0xe3, 0xfa, 0xf1, 0x9f, 0xc4, 0x6a,
+ 0xda, 0x09, 0x8d, 0xeb, 0x9c, 0x32, 0xb1, 0xfd,
+ 0x86, 0x62, 0x05, 0x16, 0x5f, 0x49, 0xb8, 0x00 },
+ { 0x5f, 0x9c, 0x95, 0xbc, 0xa3, 0x50, 0x8c, 0x24,
+ 0xb1, 0xd0, 0xb1, 0x55, 0x9c, 0x83, 0xef, 0x5b,
+ 0x04, 0x44, 0x5c, 0xc4, 0x58, 0x1c, 0x8e, 0x86,
+ 0xd8, 0x22, 0x4e, 0xdd, 0xd0, 0x9f, 0x11, 0x57 },
+ { 0xec, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f },
+ { 0xed, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f },
+ { 0xee, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f },
+ { 0xcd, 0xeb, 0x7a, 0x7c, 0x3b, 0x41, 0xb8, 0xae,
+ 0x16, 0x56, 0xe3, 0xfa, 0xf1, 0x9f, 0xc4, 0x6a,
+ 0xda, 0x09, 0x8d, 0xeb, 0x9c, 0x32, 0xb1, 0xfd,
+ 0x86, 0x62, 0x05, 0x16, 0x5f, 0x49, 0xb8, 0x80 },
+ { 0x4c, 0x9c, 0x95, 0xbc, 0xa3, 0x50, 0x8c, 0x24,
+ 0xb1, 0xd0, 0xb1, 0x55, 0x9c, 0x83, 0xef, 0x5b,
+ 0x04, 0x44, 0x5c, 0xc4, 0x58, 0x1c, 0x8e, 0x86,
+ 0xd8, 0x22, 0x4e, 0xdd, 0xd0, 0x9f, 0x11, 0xd7 },
+ { 0xd9, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff },
+ { 0xda, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff },
+ { 0xdb, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff },
+ };
+
+ /* The point must not be longer than 32 (it can be smaller). */
+ if (px->len <= 32) {
+ p = px->data;
+ } else {
+ return SECFailure;
+ }
+
+ for (i = 0; i < PR_ARRAY_SIZE(forbiddenValues); ++i) {
+ if (NSS_SecureMemcmp(p, forbiddenValues[i], px->len) == 0) {
+ return SECFailure;
+ }
+ }
+
+ return SECSuccess;
+}
+
+/*
+ * Scalar multiplication for Curve25519.
+ * If P == NULL, the base point is used.
+ * Returns X = k*P
+ */
+SECStatus
+ec_Curve25519_pt_mul(SECItem *X, SECItem *k, SECItem *P)
+{
+ PRUint8 *px;
+ PRUint8 basePoint[32] = { 9 };
+
+ if (!P) {
+ px = basePoint;
+ } else {
+ PORT_Assert(P->len == 32);
+ if (P->len != 32) {
+ return SECFailure;
+ }
+ px = P->data;
+ }
+
+ return ec_Curve25519_mul(X->data, k->data, px);
+}
diff --git a/nss/lib/freebl/ecl/ecp_256.c b/nss/lib/freebl/ecl/ecp_256.c
index 936ee6d..ad4e630 100644
--- a/nss/lib/freebl/ecl/ecp_256.c
+++ b/nss/lib/freebl/ecl/ecp_256.c
@@ -7,362 +7,369 @@
#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
+/* 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;
+ 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 ! */
+ 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 ! */
+ 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 {
+ /* 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);
- }
+ 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);
+ 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 */
- carry = 0;
- MP_ADD_CARRY(r3, a11, r3, carry);
- MP_ADD_CARRY(r4, a12, r4, carry);
- MP_ADD_CARRY(r5, a13, r5, carry);
- MP_ADD_CARRY(r6, a14, r6, carry);
- MP_ADD_CARRY(r7, a15, r7, carry);
- r8 = carry; carry = 0;
- MP_ADD_CARRY(r3, a11, r3, carry);
- MP_ADD_CARRY(r4, a12, r4, carry);
- MP_ADD_CARRY(r5, a13, r5, carry);
- MP_ADD_CARRY(r6, a14, r6, carry);
- MP_ADD_CARRY(r7, a15, r7, carry);
- r8 += carry; carry = 0;
- /* sum 2 */
- MP_ADD_CARRY(r3, a12, r3, carry);
- MP_ADD_CARRY(r4, a13, r4, carry);
- MP_ADD_CARRY(r5, a14, r5, carry);
- MP_ADD_CARRY(r6, a15, r6, carry);
- MP_ADD_CARRY(r7, 0, r7, carry);
- r8 += carry; carry = 0;
- /* combine last bottom of sum 3 with second sum 2 */
- MP_ADD_CARRY(r0, a8, r0, carry);
- MP_ADD_CARRY(r1, a9, r1, carry);
- MP_ADD_CARRY(r2, a10, r2, carry);
- MP_ADD_CARRY(r3, a12, r3, carry);
- MP_ADD_CARRY(r4, a13, r4, carry);
- MP_ADD_CARRY(r5, a14, r5, carry);
- MP_ADD_CARRY(r6, a15, r6, carry);
- MP_ADD_CARRY(r7, a15, r7, carry); /* from sum 3 */
- r8 += carry; carry = 0;
- /* sum 3 (rest of it)*/
- MP_ADD_CARRY(r6, a14, r6, carry);
- MP_ADD_CARRY(r7, 0, r7, carry);
- r8 += carry; carry = 0;
- /* sum 4 (rest of it)*/
- MP_ADD_CARRY(r0, a9, r0, carry);
- MP_ADD_CARRY(r1, a10, r1, carry);
- MP_ADD_CARRY(r2, a11, r2, carry);
- MP_ADD_CARRY(r3, a13, r3, carry);
- MP_ADD_CARRY(r4, a14, r4, carry);
- MP_ADD_CARRY(r5, a15, r5, carry);
- MP_ADD_CARRY(r6, a13, r6, carry);
- MP_ADD_CARRY(r7, a8, r7, carry);
- r8 += carry; carry = 0;
- /* diff 5 */
- MP_SUB_BORROW(r0, a11, r0, carry);
- MP_SUB_BORROW(r1, a12, r1, carry);
- MP_SUB_BORROW(r2, a13, r2, carry);
- MP_SUB_BORROW(r3, 0, r3, carry);
- MP_SUB_BORROW(r4, 0, r4, carry);
- MP_SUB_BORROW(r5, 0, r5, carry);
- MP_SUB_BORROW(r6, a8, r6, carry);
- MP_SUB_BORROW(r7, a10, r7, carry);
- r8 -= carry; carry = 0;
- /* diff 6 */
- MP_SUB_BORROW(r0, a12, r0, carry);
- MP_SUB_BORROW(r1, a13, r1, carry);
- MP_SUB_BORROW(r2, a14, r2, carry);
- MP_SUB_BORROW(r3, a15, r3, carry);
- MP_SUB_BORROW(r4, 0, r4, carry);
- MP_SUB_BORROW(r5, 0, r5, carry);
- MP_SUB_BORROW(r6, a9, r6, carry);
- MP_SUB_BORROW(r7, a11, r7, carry);
- r8 -= carry; carry = 0;
- /* diff 7 */
- MP_SUB_BORROW(r0, a13, r0, carry);
- MP_SUB_BORROW(r1, a14, r1, carry);
- MP_SUB_BORROW(r2, a15, r2, carry);
- MP_SUB_BORROW(r3, a8, r3, carry);
- MP_SUB_BORROW(r4, a9, r4, carry);
- MP_SUB_BORROW(r5, a10, r5, carry);
- MP_SUB_BORROW(r6, 0, r6, carry);
- MP_SUB_BORROW(r7, a12, r7, carry);
- r8 -= carry; carry = 0;
- /* diff 8 */
- MP_SUB_BORROW(r0, a14, r0, carry);
- MP_SUB_BORROW(r1, a15, r1, carry);
- MP_SUB_BORROW(r2, 0, r2, carry);
- MP_SUB_BORROW(r3, a9, r3, carry);
- MP_SUB_BORROW(r4, a10, r4, carry);
- MP_SUB_BORROW(r5, a11, r5, carry);
- MP_SUB_BORROW(r6, 0, r6, carry);
- MP_SUB_BORROW(r7, a13, r7, carry);
- r8 -= carry;
+ /* sum 1 */
+ carry = 0;
+ MP_ADD_CARRY(r3, a11, r3, carry);
+ MP_ADD_CARRY(r4, a12, r4, carry);
+ MP_ADD_CARRY(r5, a13, r5, carry);
+ MP_ADD_CARRY(r6, a14, r6, carry);
+ MP_ADD_CARRY(r7, a15, r7, carry);
+ r8 = carry;
+ carry = 0;
+ MP_ADD_CARRY(r3, a11, r3, carry);
+ MP_ADD_CARRY(r4, a12, r4, carry);
+ MP_ADD_CARRY(r5, a13, r5, carry);
+ MP_ADD_CARRY(r6, a14, r6, carry);
+ MP_ADD_CARRY(r7, a15, r7, carry);
+ r8 += carry;
+ carry = 0;
+ /* sum 2 */
+ MP_ADD_CARRY(r3, a12, r3, carry);
+ MP_ADD_CARRY(r4, a13, r4, carry);
+ MP_ADD_CARRY(r5, a14, r5, carry);
+ MP_ADD_CARRY(r6, a15, r6, carry);
+ MP_ADD_CARRY(r7, 0, r7, carry);
+ r8 += carry;
+ carry = 0;
+ /* combine last bottom of sum 3 with second sum 2 */
+ MP_ADD_CARRY(r0, a8, r0, carry);
+ MP_ADD_CARRY(r1, a9, r1, carry);
+ MP_ADD_CARRY(r2, a10, r2, carry);
+ MP_ADD_CARRY(r3, a12, r3, carry);
+ MP_ADD_CARRY(r4, a13, r4, carry);
+ MP_ADD_CARRY(r5, a14, r5, carry);
+ MP_ADD_CARRY(r6, a15, r6, carry);
+ MP_ADD_CARRY(r7, a15, r7, carry); /* from sum 3 */
+ r8 += carry;
+ carry = 0;
+ /* sum 3 (rest of it)*/
+ MP_ADD_CARRY(r6, a14, r6, carry);
+ MP_ADD_CARRY(r7, 0, r7, carry);
+ r8 += carry;
+ carry = 0;
+ /* sum 4 (rest of it)*/
+ MP_ADD_CARRY(r0, a9, r0, carry);
+ MP_ADD_CARRY(r1, a10, r1, carry);
+ MP_ADD_CARRY(r2, a11, r2, carry);
+ MP_ADD_CARRY(r3, a13, r3, carry);
+ MP_ADD_CARRY(r4, a14, r4, carry);
+ MP_ADD_CARRY(r5, a15, r5, carry);
+ MP_ADD_CARRY(r6, a13, r6, carry);
+ MP_ADD_CARRY(r7, a8, r7, carry);
+ r8 += carry;
+ carry = 0;
+ /* diff 5 */
+ MP_SUB_BORROW(r0, a11, r0, carry);
+ MP_SUB_BORROW(r1, a12, r1, carry);
+ MP_SUB_BORROW(r2, a13, r2, carry);
+ MP_SUB_BORROW(r3, 0, r3, carry);
+ MP_SUB_BORROW(r4, 0, r4, carry);
+ MP_SUB_BORROW(r5, 0, r5, carry);
+ MP_SUB_BORROW(r6, a8, r6, carry);
+ MP_SUB_BORROW(r7, a10, r7, carry);
+ r8 -= carry;
+ carry = 0;
+ /* diff 6 */
+ MP_SUB_BORROW(r0, a12, r0, carry);
+ MP_SUB_BORROW(r1, a13, r1, carry);
+ MP_SUB_BORROW(r2, a14, r2, carry);
+ MP_SUB_BORROW(r3, a15, r3, carry);
+ MP_SUB_BORROW(r4, 0, r4, carry);
+ MP_SUB_BORROW(r5, 0, r5, carry);
+ MP_SUB_BORROW(r6, a9, r6, carry);
+ MP_SUB_BORROW(r7, a11, r7, carry);
+ r8 -= carry;
+ carry = 0;
+ /* diff 7 */
+ MP_SUB_BORROW(r0, a13, r0, carry);
+ MP_SUB_BORROW(r1, a14, r1, carry);
+ MP_SUB_BORROW(r2, a15, r2, carry);
+ MP_SUB_BORROW(r3, a8, r3, carry);
+ MP_SUB_BORROW(r4, a9, r4, carry);
+ MP_SUB_BORROW(r5, a10, r5, carry);
+ MP_SUB_BORROW(r6, 0, r6, carry);
+ MP_SUB_BORROW(r7, a12, r7, carry);
+ r8 -= carry;
+ carry = 0;
+ /* diff 8 */
+ MP_SUB_BORROW(r0, a14, r0, carry);
+ MP_SUB_BORROW(r1, a15, r1, carry);
+ MP_SUB_BORROW(r2, 0, r2, carry);
+ MP_SUB_BORROW(r3, a9, r3, carry);
+ MP_SUB_BORROW(r4, a10, r4, carry);
+ MP_SUB_BORROW(r5, a11, r5, carry);
+ MP_SUB_BORROW(r6, 0, r6, carry);
+ MP_SUB_BORROW(r7, a13, r7, carry);
+ r8 -= carry;
- /* reduce the overflows */
- while (r8 > 0) {
- mp_digit r8_d = r8; carry = 0;
- carry = 0;
- MP_ADD_CARRY(r0, r8_d, r0, carry);
- MP_ADD_CARRY(r1, 0, r1, carry);
- MP_ADD_CARRY(r2, 0, r2, carry);
- MP_ADD_CARRY(r3, 0-r8_d, r3, carry);
- MP_ADD_CARRY(r4, MP_DIGIT_MAX, r4, carry);
- MP_ADD_CARRY(r5, MP_DIGIT_MAX, r5, carry);
- MP_ADD_CARRY(r6, 0-(r8_d+1), r6, carry);
- MP_ADD_CARRY(r7, (r8_d-1), r7, carry);
- r8 = carry;
- }
+ /* reduce the overflows */
+ while (r8 > 0) {
+ mp_digit r8_d = r8;
+ carry = 0;
+ MP_ADD_CARRY(r0, r8_d, r0, carry);
+ MP_ADD_CARRY(r1, 0, r1, carry);
+ MP_ADD_CARRY(r2, 0, r2, carry);
+ MP_ADD_CARRY(r3, 0 - r8_d, r3, carry);
+ MP_ADD_CARRY(r4, MP_DIGIT_MAX, r4, carry);
+ MP_ADD_CARRY(r5, MP_DIGIT_MAX, r5, carry);
+ MP_ADD_CARRY(r6, 0 - (r8_d + 1), r6, carry);
+ MP_ADD_CARRY(r7, (r8_d - 1), r7, carry);
+ r8 = carry;
+ }
- /* reduce the underflows */
- while (r8 < 0) {
- mp_digit r8_d = -r8;
- carry = 0;
- MP_SUB_BORROW(r0, r8_d, r0, carry);
- MP_SUB_BORROW(r1, 0, r1, carry);
- MP_SUB_BORROW(r2, 0, r2, carry);
- MP_SUB_BORROW(r3, 0-r8_d, r3, carry);
- MP_SUB_BORROW(r4, MP_DIGIT_MAX, r4, carry);
- MP_SUB_BORROW(r5, MP_DIGIT_MAX, r5, carry);
- MP_SUB_BORROW(r6, 0-(r8_d+1), r6, carry);
- MP_SUB_BORROW(r7, (r8_d-1), r7, carry);
- r8 = 0-carry;
- }
- if (a != r) {
- MP_CHECKOK(s_mp_pad(r,8));
- }
- MP_SIGN(r) = MP_ZPOS;
- MP_USED(r) = 8;
+ /* reduce the underflows */
+ while (r8 < 0) {
+ mp_digit r8_d = -r8;
+ carry = 0;
+ MP_SUB_BORROW(r0, r8_d, r0, carry);
+ MP_SUB_BORROW(r1, 0, r1, carry);
+ MP_SUB_BORROW(r2, 0, r2, carry);
+ MP_SUB_BORROW(r3, 0 - r8_d, r3, carry);
+ MP_SUB_BORROW(r4, MP_DIGIT_MAX, r4, carry);
+ MP_SUB_BORROW(r5, MP_DIGIT_MAX, r5, carry);
+ MP_SUB_BORROW(r6, 0 - (r8_d + 1), r6, carry);
+ MP_SUB_BORROW(r7, (r8_d - 1), r7, 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;
+ 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));
- }
+ /* 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);
+ 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);
+ 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 */
- carry = 0;
- carry = 0;
- MP_ADD_CARRY(r1, a5h << 32, r1, carry);
- MP_ADD_CARRY(r2, a6, r2, carry);
- MP_ADD_CARRY(r3, a7, r3, carry);
- r4 = carry; carry = 0;
- carry = 0;
- MP_ADD_CARRY(r1, a5h << 32, r1, carry);
- MP_ADD_CARRY(r2, a6, r2, carry);
- MP_ADD_CARRY(r3, a7, r3, carry);
- r4 += carry; carry = 0;
- /* sum 2 */
- carry = 0;
- MP_ADD_CARRY(r1, a6l, r1, carry);
- MP_ADD_CARRY(r2, a6h | a7l, r2, carry);
- MP_ADD_CARRY(r3, a7h, r3, carry);
- r4 += carry; carry = 0;
- carry = 0;
- MP_ADD_CARRY(r1, a6l, r1, carry);
- MP_ADD_CARRY(r2, a6h | a7l, r2, carry);
- MP_ADD_CARRY(r3, a7h, r3, carry);
- r4 += carry; carry = 0;
+ /* sum 1 */
+ carry = 0;
+ MP_ADD_CARRY(r1, a5h << 32, r1, carry);
+ MP_ADD_CARRY(r2, a6, r2, carry);
+ MP_ADD_CARRY(r3, a7, r3, carry);
+ r4 = carry;
+ carry = 0;
+ MP_ADD_CARRY(r1, a5h << 32, r1, carry);
+ MP_ADD_CARRY(r2, a6, r2, carry);
+ MP_ADD_CARRY(r3, a7, r3, carry);
+ r4 += carry;
+ /* sum 2 */
+ carry = 0;
+ MP_ADD_CARRY(r1, a6l, r1, carry);
+ MP_ADD_CARRY(r2, a6h | a7l, r2, carry);
+ MP_ADD_CARRY(r3, a7h, r3, carry);
+ r4 += carry;
+ carry = 0;
+ MP_ADD_CARRY(r1, a6l, r1, carry);
+ MP_ADD_CARRY(r2, a6h | a7l, r2, carry);
+ MP_ADD_CARRY(r3, a7h, r3, carry);
+ r4 += carry;
- /* sum 3 */
- carry = 0;
- MP_ADD_CARRY(r0, a4, r0, carry);
- MP_ADD_CARRY(r1, a5l >> 32, r1, carry);
- MP_ADD_CARRY(r2, 0, r2, carry);
- MP_ADD_CARRY(r3, a7, r3, carry);
- r4 += carry; carry = 0;
- /* sum 4 */
- carry = 0;
- MP_ADD_CARRY(r0, a4h | a5l, r0, carry);
- MP_ADD_CARRY(r1, a5h|(a6h<<32), r1, carry);
- MP_ADD_CARRY(r2, a7, r2, carry);
- MP_ADD_CARRY(r3, a6h | a4l, r3, carry);
- r4 += carry;
- /* diff 5 */
- carry = 0;
- MP_SUB_BORROW(r0, a5h | a6l, r0, carry);
- MP_SUB_BORROW(r1, a6h, r1, carry);
- MP_SUB_BORROW(r2, 0, r2, carry);
- MP_SUB_BORROW(r3, (a4l>>32)|a5l,r3, carry);
- r4 -= carry;
- /* diff 6 */
- carry = 0;
- MP_SUB_BORROW(r0, a6, r0, carry);
- MP_SUB_BORROW(r1, a7, r1, carry);
- MP_SUB_BORROW(r2, 0, r2, carry);
- MP_SUB_BORROW(r3, a4h|(a5h<<32),r3, carry);
- r4 -= carry;
- /* diff 7 */
- carry = 0;
- MP_SUB_BORROW(r0, a6h|a7l, r0, carry);
- MP_SUB_BORROW(r1, a7h|a4l, r1, carry);
- MP_SUB_BORROW(r2, a4h|a5l, r2, carry);
- MP_SUB_BORROW(r3, a6l, r3, carry);
- r4 -= carry;
- /* diff 8 */
- carry = 0;
- MP_SUB_BORROW(r0, a7, r0, carry);
- MP_SUB_BORROW(r1, a4h<<32, r1, carry);
- MP_SUB_BORROW(r2, a5, r2, carry);
- MP_SUB_BORROW(r3, a6h<<32, r3, carry);
- r4 -= carry;
+ /* sum 3 */
+ carry = 0;
+ MP_ADD_CARRY(r0, a4, r0, carry);
+ MP_ADD_CARRY(r1, a5l >> 32, r1, carry);
+ MP_ADD_CARRY(r2, 0, r2, carry);
+ MP_ADD_CARRY(r3, a7, r3, carry);
+ r4 += carry;
+ /* sum 4 */
+ carry = 0;
+ MP_ADD_CARRY(r0, a4h | a5l, r0, carry);
+ MP_ADD_CARRY(r1, a5h | (a6h << 32), r1, carry);
+ MP_ADD_CARRY(r2, a7, r2, carry);
+ MP_ADD_CARRY(r3, a6h | a4l, r3, carry);
+ r4 += carry;
+ /* diff 5 */
+ carry = 0;
+ MP_SUB_BORROW(r0, a5h | a6l, r0, carry);
+ MP_SUB_BORROW(r1, a6h, r1, carry);
+ MP_SUB_BORROW(r2, 0, r2, carry);
+ MP_SUB_BORROW(r3, (a4l >> 32) | a5l, r3, carry);
+ r4 -= carry;
+ /* diff 6 */
+ carry = 0;
+ MP_SUB_BORROW(r0, a6, r0, carry);
+ MP_SUB_BORROW(r1, a7, r1, carry);
+ MP_SUB_BORROW(r2, 0, r2, carry);
+ MP_SUB_BORROW(r3, a4h | (a5h << 32), r3, carry);
+ r4 -= carry;
+ /* diff 7 */
+ carry = 0;
+ MP_SUB_BORROW(r0, a6h | a7l, r0, carry);
+ MP_SUB_BORROW(r1, a7h | a4l, r1, carry);
+ MP_SUB_BORROW(r2, a4h | a5l, r2, carry);
+ MP_SUB_BORROW(r3, a6l, r3, carry);
+ r4 -= carry;
+ /* diff 8 */
+ carry = 0;
+ MP_SUB_BORROW(r0, a7, r0, carry);
+ MP_SUB_BORROW(r1, a4h << 32, r1, carry);
+ MP_SUB_BORROW(r2, a5, r2, carry);
+ MP_SUB_BORROW(r3, a6h << 32, r3, carry);
+ r4 -= carry;
- /* reduce the overflows */
- while (r4 > 0) {
- mp_digit r4_long = r4;
- mp_digit r4l = (r4_long << 32);
- carry = 0;
- carry = 0;
- MP_ADD_CARRY(r0, r4_long, r0, carry);
- MP_ADD_CARRY(r1, 0-r4l, r1, carry);
- MP_ADD_CARRY(r2, MP_DIGIT_MAX, r2, carry);
- MP_ADD_CARRY(r3, r4l-r4_long-1,r3, carry);
- r4 = carry;
- }
+ /* reduce the overflows */
+ while (r4 > 0) {
+ mp_digit r4_long = r4;
+ mp_digit r4l = (r4_long << 32);
+ carry = 0;
+ MP_ADD_CARRY(r0, r4_long, r0, carry);
+ MP_ADD_CARRY(r1, 0 - r4l, r1, carry);
+ MP_ADD_CARRY(r2, MP_DIGIT_MAX, r2, carry);
+ MP_ADD_CARRY(r3, r4l - r4_long - 1, r3, carry);
+ r4 = carry;
+ }
- /* reduce the underflows */
- while (r4 < 0) {
- mp_digit r4_long = -r4;
- mp_digit r4l = (r4_long << 32);
- carry = 0;
- MP_SUB_BORROW(r0, r4_long, r0, carry);
- MP_SUB_BORROW(r1, 0-r4l, r1, carry);
- MP_SUB_BORROW(r2, MP_DIGIT_MAX, r2, carry);
- MP_SUB_BORROW(r3, r4l-r4_long-1,r3, carry);
- r4 = 0-carry;
- }
+ /* reduce the underflows */
+ while (r4 < 0) {
+ mp_digit r4_long = -r4;
+ mp_digit r4l = (r4_long << 32);
+ carry = 0;
+ MP_SUB_BORROW(r0, r4_long, r0, carry);
+ MP_SUB_BORROW(r1, 0 - r4l, r1, carry);
+ MP_SUB_BORROW(r2, MP_DIGIT_MAX, r2, carry);
+ MP_SUB_BORROW(r3, r4l - r4_long - 1, r3, carry);
+ r4 = 0 - carry;
+ }
- if (a != r) {
- MP_CHECKOK(s_mp_pad(r,4));
- }
- MP_SIGN(r) = MP_ZPOS;
- MP_USED(r) = 4;
+ 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;
+ 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);
+ /* 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;
+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.
+ * 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_err res = MP_OKAY;
- MP_CHECKOK(mp_sqr(a, r));
- MP_CHECKOK(ec_GFp_nistp256_mod(r, r, meth));
- CLEANUP:
- return res;
+ 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.
@@ -370,14 +377,14 @@ ec_GFp_nistp256_sqr(const mp_int *a, mp_int *r, const GFMethod *meth)
* 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)
+ const GFMethod *meth)
{
- mp_err res = MP_OKAY;
+ mp_err res = MP_OKAY;
- MP_CHECKOK(mp_mul(a, b, r));
- MP_CHECKOK(ec_GFp_nistp256_mod(r, r, meth));
- CLEANUP:
- return res;
+ 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
@@ -385,10 +392,10 @@ ec_GFp_nistp256_mul(const mp_int *a, const mp_int *b, mp_int *r,
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;
+ 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/nss/lib/freebl/ecl/ecp_256_32.c b/nss/lib/freebl/ecl/ecp_256_32.c
index cd8cd23..515f6f7 100644
--- a/nss/lib/freebl/ecl/ecp_256_32.c
+++ b/nss/lib/freebl/ecl/ecp_256_32.c
@@ -48,7 +48,7 @@ static const felem kOne = {
0x1fffffff, 0xfffffff, 0x1fbfffff, 0x1ffffff,
0
};
-static const felem kZero = {0};
+static const felem kZero = { 0 };
static const felem kP = {
0x1fffffff, 0xfffffff, 0x1fffffff, 0x3ff,
0, 0, 0x200000, 0xf000000,
@@ -162,7 +162,7 @@ static const limb kPrecomputed[NLIMBS * 2 * 15 * 2] = {
*
* x must be a u32 or an equivalent type such as limb.
*/
-#define NON_ZERO_TO_ALL_ONES(x) ((((u32)(x) - 1) >> 31) - 1)
+#define NON_ZERO_TO_ALL_ONES(x) ((((u32)(x)-1) >> 31) - 1)
/* felem_reduce_carry adds a multiple of p in order to cancel |carry|,
* which is a term at 2**257.
@@ -170,7 +170,8 @@ static const limb kPrecomputed[NLIMBS * 2 * 15 * 2] = {
* On entry: carry < 2**3, inout[0,2,...] < 2**29, inout[1,3,...] < 2**28.
* On exit: inout[0,2,..] < 2**30, inout[1,3,...] < 2**29.
*/
-static void felem_reduce_carry(felem inout, limb carry)
+static void
+felem_reduce_carry(felem inout, limb carry)
{
const u32 carry_mask = NON_ZERO_TO_ALL_ONES(carry);
@@ -196,24 +197,25 @@ static void felem_reduce_carry(felem inout, limb carry)
* On entry, in[i]+in2[i] must not overflow a 32-bit word.
* On exit: out[0,2,...] < 2**30, out[1,3,...] < 2**29
*/
-static void felem_sum(felem out, const felem in, const felem in2)
+static void
+felem_sum(felem out, const felem in, const felem in2)
{
limb carry = 0;
unsigned int i;
for (i = 0;; i++) {
- out[i] = in[i] + in2[i];
- out[i] += carry;
- carry = out[i] >> 29;
- out[i] &= kBottom29Bits;
-
- i++;
- if (i == NLIMBS)
- break;
-
- out[i] = in[i] + in2[i];
- out[i] += carry;
- carry = out[i] >> 28;
- out[i] &= kBottom28Bits;
+ out[i] = in[i] + in2[i];
+ out[i] += carry;
+ carry = out[i] >> 29;
+ out[i] &= kBottom29Bits;
+
+ i++;
+ if (i == NLIMBS)
+ break;
+
+ out[i] = in[i] + in2[i];
+ out[i] += carry;
+ carry = out[i] >> 28;
+ out[i] &= kBottom28Bits;
}
felem_reduce_carry(out, carry);
@@ -240,27 +242,28 @@ static const felem zero31 = {
* in2[0,2,...] < 2**30, in2[1,3,...] < 2**29.
* On exit: out[0,2,...] < 2**30, out[1,3,...] < 2**29.
*/
-static void felem_diff(felem out, const felem in, const felem in2)
+static void
+felem_diff(felem out, const felem in, const felem in2)
{
limb carry = 0;
unsigned int i;
for (i = 0;; i++) {
- out[i] = in[i] - in2[i];
- out[i] += zero31[i];
- out[i] += carry;
- carry = out[i] >> 29;
- out[i] &= kBottom29Bits;
-
- i++;
- if (i == NLIMBS)
- break;
-
- out[i] = in[i] - in2[i];
- out[i] += zero31[i];
- out[i] += carry;
- carry = out[i] >> 28;
- out[i] &= kBottom28Bits;
+ out[i] = in[i] - in2[i];
+ out[i] += zero31[i];
+ out[i] += carry;
+ carry = out[i] >> 29;
+ out[i] &= kBottom29Bits;
+
+ i++;
+ if (i == NLIMBS)
+ break;
+
+ out[i] = in[i] - in2[i];
+ out[i] += zero31[i];
+ out[i] += carry;
+ carry = out[i] >> 28;
+ out[i] &= kBottom28Bits;
}
felem_reduce_carry(out, carry);
@@ -277,7 +280,8 @@ static void felem_diff(felem out, const felem in, const felem in2)
* On entry: tmp[i] < 2**64
* On exit: out[0,2,...] < 2**30, out[1,3,...] < 2**29
*/
-static void felem_reduce_degree(felem out, u64 tmp[17])
+static void
+felem_reduce_degree(felem out, u64 tmp[17])
{
/* The following table may be helpful when reading this code:
*
@@ -301,36 +305,36 @@ static void felem_reduce_degree(felem out, u64 tmp[17])
* the right register rather than doing a double-word shift and truncating
* afterwards.
*/
- tmp2[1] = ((limb) tmp[0]) >> 29;
- tmp2[1] |= (((limb) (tmp[0] >> 32)) << 3) & kBottom28Bits;
- tmp2[1] += ((limb) tmp[1]) & kBottom28Bits;
+ tmp2[1] = ((limb)tmp[0]) >> 29;
+ tmp2[1] |= (((limb)(tmp[0] >> 32)) << 3) & kBottom28Bits;
+ tmp2[1] += ((limb)tmp[1]) & kBottom28Bits;
carry = tmp2[1] >> 28;
tmp2[1] &= kBottom28Bits;
for (i = 2; i < 17; i++) {
- tmp2[i] = ((limb) (tmp[i - 2] >> 32)) >> 25;
- tmp2[i] += ((limb) (tmp[i - 1])) >> 28;
- tmp2[i] += (((limb) (tmp[i - 1] >> 32)) << 4) & kBottom29Bits;
- tmp2[i] += ((limb) tmp[i]) & kBottom29Bits;
- tmp2[i] += carry;
- carry = tmp2[i] >> 29;
- tmp2[i] &= kBottom29Bits;
-
- i++;
- if (i == 17)
- break;
- tmp2[i] = ((limb) (tmp[i - 2] >> 32)) >> 25;
- tmp2[i] += ((limb) (tmp[i - 1])) >> 29;
- tmp2[i] += (((limb) (tmp[i - 1] >> 32)) << 3) & kBottom28Bits;
- tmp2[i] += ((limb) tmp[i]) & kBottom28Bits;
- tmp2[i] += carry;
- carry = tmp2[i] >> 28;
- tmp2[i] &= kBottom28Bits;
+ tmp2[i] = ((limb)(tmp[i - 2] >> 32)) >> 25;
+ tmp2[i] += ((limb)(tmp[i - 1])) >> 28;
+ tmp2[i] += (((limb)(tmp[i - 1] >> 32)) << 4) & kBottom29Bits;
+ tmp2[i] += ((limb)tmp[i]) & kBottom29Bits;
+ tmp2[i] += carry;
+ carry = tmp2[i] >> 29;
+ tmp2[i] &= kBottom29Bits;
+
+ i++;
+ if (i == 17)
+ break;
+ tmp2[i] = ((limb)(tmp[i - 2] >> 32)) >> 25;
+ tmp2[i] += ((limb)(tmp[i - 1])) >> 29;
+ tmp2[i] += (((limb)(tmp[i - 1] >> 32)) << 3) & kBottom28Bits;
+ tmp2[i] += ((limb)tmp[i]) & kBottom28Bits;
+ tmp2[i] += carry;
+ carry = tmp2[i] >> 28;
+ tmp2[i] &= kBottom28Bits;
}
- tmp2[17] = ((limb) (tmp[15] >> 32)) >> 25;
- tmp2[17] += ((limb) (tmp[16])) >> 29;
- tmp2[17] += (((limb) (tmp[16] >> 32)) << 3);
+ tmp2[17] = ((limb)(tmp[15] >> 32)) >> 25;
+ tmp2[17] += ((limb)(tmp[16])) >> 29;
+ tmp2[17] += (((limb)(tmp[16] >> 32)) << 3);
tmp2[17] += carry;
/* Montgomery elimination of terms:
@@ -345,101 +349,101 @@ static void felem_reduce_degree(felem out, u64 tmp[17])
* extra factor of R.
*/
for (i = 0;; i += 2) {
- tmp2[i + 1] += tmp2[i] >> 29;
- x = tmp2[i] & kBottom29Bits;
- xMask = NON_ZERO_TO_ALL_ONES(x);
- tmp2[i] = 0;
-
- /* The bounds calculations for this loop are tricky. Each iteration of
- * the loop eliminates two words by adding values to words to their
- * right.
- *
- * The following table contains the amounts added to each word (as an
- * offset from the value of i at the top of the loop). The amounts are
- * accounted for from the first and second half of the loop separately
- * and are written as, for example, 28 to mean a value <2**28.
- *
- * Word: 3 4 5 6 7 8 9 10
- * Added in top half: 28 11 29 21 29 28
- * 28 29
- * 29
- * Added in bottom half: 29 10 28 21 28 28
- * 29
- *
- * The value that is currently offset 7 will be offset 5 for the next
- * iteration and then offset 3 for the iteration after that. Therefore
- * the total value added will be the values added at 7, 5 and 3.
- *
- * The following table accumulates these values. The sums at the bottom
- * are written as, for example, 29+28, to mean a value < 2**29+2**28.
- *
- * Word: 3 4 5 6 7 8 9 10 11 12 13
- * 28 11 10 29 21 29 28 28 28 28 28
- * 29 28 11 28 29 28 29 28 29 28
- * 29 28 21 21 29 21 29 21
- * 10 29 28 21 28 21 28
- * 28 29 28 29 28 29 28
- * 11 10 29 10 29 10
- * 29 28 11 28 11
- * 29 29
- * --------------------------------------------
- * 30+ 31+ 30+ 31+ 30+
- * 28+ 29+ 28+ 29+ 21+
- * 21+ 28+ 21+ 28+ 10
- * 10 21+ 10 21+
- * 11 11
- *
- * So the greatest amount is added to tmp2[10] and tmp2[12]. If
- * tmp2[10/12] has an initial value of <2**29, then the maximum value
- * will be < 2**31 + 2**30 + 2**28 + 2**21 + 2**11, which is < 2**32,
- * as required.
+ tmp2[i + 1] += tmp2[i] >> 29;
+ x = tmp2[i] & kBottom29Bits;
+ xMask = NON_ZERO_TO_ALL_ONES(x);
+ tmp2[i] = 0;
+
+ /* The bounds calculations for this loop are tricky. Each iteration of
+ * the loop eliminates two words by adding values to words to their
+ * right.
+ *
+ * The following table contains the amounts added to each word (as an
+ * offset from the value of i at the top of the loop). The amounts are
+ * accounted for from the first and second half of the loop separately
+ * and are written as, for example, 28 to mean a value <2**28.
+ *
+ * Word: 3 4 5 6 7 8 9 10
+ * Added in top half: 28 11 29 21 29 28
+ * 28 29
+ * 29
+ * Added in bottom half: 29 10 28 21 28 28
+ * 29
+ *
+ * The value that is currently offset 7 will be offset 5 for the next
+ * iteration and then offset 3 for the iteration after that. Therefore
+ * the total value added will be the values added at 7, 5 and 3.
+ *
+ * The following table accumulates these values. The sums at the bottom
+ * are written as, for example, 29+28, to mean a value < 2**29+2**28.
+ *
+ * Word: 3 4 5 6 7 8 9 10 11 12 13
+ * 28 11 10 29 21 29 28 28 28 28 28
+ * 29 28 11 28 29 28 29 28 29 28
+ * 29 28 21 21 29 21 29 21
+ * 10 29 28 21 28 21 28
+ * 28 29 28 29 28 29 28
+ * 11 10 29 10 29 10
+ * 29 28 11 28 11
+ * 29 29
+ * --------------------------------------------
+ * 30+ 31+ 30+ 31+ 30+
+ * 28+ 29+ 28+ 29+ 21+
+ * 21+ 28+ 21+ 28+ 10
+ * 10 21+ 10 21+
+ * 11 11
+ *
+ * So the greatest amount is added to tmp2[10] and tmp2[12]. If
+ * tmp2[10/12] has an initial value of <2**29, then the maximum value
+ * will be < 2**31 + 2**30 + 2**28 + 2**21 + 2**11, which is < 2**32,
+ * as required.
*/
- tmp2[i + 3] += (x << 10) & kBottom28Bits;
- tmp2[i + 4] += (x >> 18);
-
- tmp2[i + 6] += (x << 21) & kBottom29Bits;
- tmp2[i + 7] += x >> 8;
-
- /* At position 200, which is the starting bit position for word 7, we
- * have a factor of 0xf000000 = 2**28 - 2**24.
- */
- tmp2[i + 7] += 0x10000000 & xMask;
- /* Word 7 is 28 bits wide, so the 2**28 term exactly hits word 8. */
- tmp2[i + 8] += (x - 1) & xMask;
- tmp2[i + 7] -= (x << 24) & kBottom28Bits;
- tmp2[i + 8] -= x >> 4;
-
- tmp2[i + 8] += 0x20000000 & xMask;
- tmp2[i + 8] -= x;
- tmp2[i + 8] += (x << 28) & kBottom29Bits;
- tmp2[i + 9] += ((x >> 1) - 1) & xMask;
-
- if (i+1 == NLIMBS)
- break;
- tmp2[i + 2] += tmp2[i + 1] >> 28;
- x = tmp2[i + 1] & kBottom28Bits;
- xMask = NON_ZERO_TO_ALL_ONES(x);
- tmp2[i + 1] = 0;
-
- tmp2[i + 4] += (x << 11) & kBottom29Bits;
- tmp2[i + 5] += (x >> 18);
-
- tmp2[i + 7] += (x << 21) & kBottom28Bits;
- tmp2[i + 8] += x >> 7;
-
- /* At position 199, which is the starting bit of the 8th word when
- * dealing with a context starting on an odd word, we have a factor of
- * 0x1e000000 = 2**29 - 2**25. Since we have not updated i, the 8th
- * word from i+1 is i+8.
- */
- tmp2[i + 8] += 0x20000000 & xMask;
- tmp2[i + 9] += (x - 1) & xMask;
- tmp2[i + 8] -= (x << 25) & kBottom29Bits;
- tmp2[i + 9] -= x >> 4;
-
- tmp2[i + 9] += 0x10000000 & xMask;
- tmp2[i + 9] -= x;
- tmp2[i + 10] += (x - 1) & xMask;
+ tmp2[i + 3] += (x << 10) & kBottom28Bits;
+ tmp2[i + 4] += (x >> 18);
+
+ tmp2[i + 6] += (x << 21) & kBottom29Bits;
+ tmp2[i + 7] += x >> 8;
+
+ /* At position 200, which is the starting bit position for word 7, we
+ * have a factor of 0xf000000 = 2**28 - 2**24.
+ */
+ tmp2[i + 7] += 0x10000000 & xMask;
+ /* Word 7 is 28 bits wide, so the 2**28 term exactly hits word 8. */
+ tmp2[i + 8] += (x - 1) & xMask;
+ tmp2[i + 7] -= (x << 24) & kBottom28Bits;
+ tmp2[i + 8] -= x >> 4;
+
+ tmp2[i + 8] += 0x20000000 & xMask;
+ tmp2[i + 8] -= x;
+ tmp2[i + 8] += (x << 28) & kBottom29Bits;
+ tmp2[i + 9] += ((x >> 1) - 1) & xMask;
+
+ if (i + 1 == NLIMBS)
+ break;
+ tmp2[i + 2] += tmp2[i + 1] >> 28;
+ x = tmp2[i + 1] & kBottom28Bits;
+ xMask = NON_ZERO_TO_ALL_ONES(x);
+ tmp2[i + 1] = 0;
+
+ tmp2[i + 4] += (x << 11) & kBottom29Bits;
+ tmp2[i + 5] += (x >> 18);
+
+ tmp2[i + 7] += (x << 21) & kBottom28Bits;
+ tmp2[i + 8] += x >> 7;
+
+ /* At position 199, which is the starting bit of the 8th word when
+ * dealing with a context starting on an odd word, we have a factor of
+ * 0x1e000000 = 2**29 - 2**25. Since we have not updated i, the 8th
+ * word from i+1 is i+8.
+ */
+ tmp2[i + 8] += 0x20000000 & xMask;
+ tmp2[i + 9] += (x - 1) & xMask;
+ tmp2[i + 8] -= (x << 25) & kBottom29Bits;
+ tmp2[i + 9] -= x >> 4;
+
+ tmp2[i + 9] += 0x10000000 & xMask;
+ tmp2[i + 9] -= x;
+ tmp2[i + 10] += (x - 1) & xMask;
}
/* We merge the right shift with a carry chain. The words above 2**257 have
@@ -447,21 +451,21 @@ static void felem_reduce_degree(felem out, u64 tmp[17])
*/
carry = 0;
for (i = 0; i < 8; i++) {
- /* The maximum value of tmp2[i + 9] occurs on the first iteration and
- * is < 2**30+2**29+2**28. Adding 2**29 (from tmp2[i + 10]) is
- * therefore safe.
- */
- out[i] = tmp2[i + 9];
- out[i] += carry;
- out[i] += (tmp2[i + 10] << 28) & kBottom29Bits;
- carry = out[i] >> 29;
- out[i] &= kBottom29Bits;
-
- i++;
- out[i] = tmp2[i + 9] >> 1;
- out[i] += carry;
- carry = out[i] >> 28;
- out[i] &= kBottom28Bits;
+ /* The maximum value of tmp2[i + 9] occurs on the first iteration and
+ * is < 2**30+2**29+2**28. Adding 2**29 (from tmp2[i + 10]) is
+ * therefore safe.
+ */
+ out[i] = tmp2[i + 9];
+ out[i] += carry;
+ out[i] += (tmp2[i + 10] << 28) & kBottom29Bits;
+ carry = out[i] >> 29;
+ out[i] &= kBottom29Bits;
+
+ i++;
+ out[i] = tmp2[i + 9] >> 1;
+ out[i] += carry;
+ carry = out[i] >> 28;
+ out[i] &= kBottom28Bits;
}
out[8] = tmp2[17];
@@ -477,58 +481,59 @@ static void felem_reduce_degree(felem out, u64 tmp[17])
* On entry: in[0,2,...] < 2**30, in[1,3,...] < 2**29.
* On exit: out[0,2,...] < 2**30, out[1,3,...] < 2**29.
*/
-static void felem_square(felem out, const felem in)
+static void
+felem_square(felem out, const felem in)
{
u64 tmp[17];
- tmp[0] = ((u64) in[0]) * in[0];
- tmp[1] = ((u64) in[0]) * (in[1] << 1);
- tmp[2] = ((u64) in[0]) * (in[2] << 1) +
- ((u64) in[1]) * (in[1] << 1);
- tmp[3] = ((u64) in[0]) * (in[3] << 1) +
- ((u64) in[1]) * (in[2] << 1);
- tmp[4] = ((u64) in[0]) * (in[4] << 1) +
- ((u64) in[1]) * (in[3] << 2) +
- ((u64) in[2]) * in[2];
- tmp[5] = ((u64) in[0]) * (in[5] << 1) +
- ((u64) in[1]) * (in[4] << 1) +
- ((u64) in[2]) * (in[3] << 1);
- tmp[6] = ((u64) in[0]) * (in[6] << 1) +
- ((u64) in[1]) * (in[5] << 2) +
- ((u64) in[2]) * (in[4] << 1) +
- ((u64) in[3]) * (in[3] << 1);
- tmp[7] = ((u64) in[0]) * (in[7] << 1) +
- ((u64) in[1]) * (in[6] << 1) +
- ((u64) in[2]) * (in[5] << 1) +
- ((u64) in[3]) * (in[4] << 1);
+ tmp[0] = ((u64)in[0]) * in[0];
+ tmp[1] = ((u64)in[0]) * (in[1] << 1);
+ tmp[2] = ((u64)in[0]) * (in[2] << 1) +
+ ((u64)in[1]) * (in[1] << 1);
+ tmp[3] = ((u64)in[0]) * (in[3] << 1) +
+ ((u64)in[1]) * (in[2] << 1);
+ tmp[4] = ((u64)in[0]) * (in[4] << 1) +
+ ((u64)in[1]) * (in[3] << 2) +
+ ((u64)in[2]) * in[2];
+ tmp[5] = ((u64)in[0]) * (in[5] << 1) +
+ ((u64)in[1]) * (in[4] << 1) +
+ ((u64)in[2]) * (in[3] << 1);
+ tmp[6] = ((u64)in[0]) * (in[6] << 1) +
+ ((u64)in[1]) * (in[5] << 2) +
+ ((u64)in[2]) * (in[4] << 1) +
+ ((u64)in[3]) * (in[3] << 1);
+ tmp[7] = ((u64)in[0]) * (in[7] << 1) +
+ ((u64)in[1]) * (in[6] << 1) +
+ ((u64)in[2]) * (in[5] << 1) +
+ ((u64)in[3]) * (in[4] << 1);
/* tmp[8] has the greatest value of 2**61 + 2**60 + 2**61 + 2**60 + 2**60,
* which is < 2**64 as required.
*/
- tmp[8] = ((u64) in[0]) * (in[8] << 1) +
- ((u64) in[1]) * (in[7] << 2) +
- ((u64) in[2]) * (in[6] << 1) +
- ((u64) in[3]) * (in[5] << 2) +
- ((u64) in[4]) * in[4];
- tmp[9] = ((u64) in[1]) * (in[8] << 1) +
- ((u64) in[2]) * (in[7] << 1) +
- ((u64) in[3]) * (in[6] << 1) +
- ((u64) in[4]) * (in[5] << 1);
- tmp[10] = ((u64) in[2]) * (in[8] << 1) +
- ((u64) in[3]) * (in[7] << 2) +
- ((u64) in[4]) * (in[6] << 1) +
- ((u64) in[5]) * (in[5] << 1);
- tmp[11] = ((u64) in[3]) * (in[8] << 1) +
- ((u64) in[4]) * (in[7] << 1) +
- ((u64) in[5]) * (in[6] << 1);
- tmp[12] = ((u64) in[4]) * (in[8] << 1) +
- ((u64) in[5]) * (in[7] << 2) +
- ((u64) in[6]) * in[6];
- tmp[13] = ((u64) in[5]) * (in[8] << 1) +
- ((u64) in[6]) * (in[7] << 1);
- tmp[14] = ((u64) in[6]) * (in[8] << 1) +
- ((u64) in[7]) * (in[7] << 1);
- tmp[15] = ((u64) in[7]) * (in[8] << 1);
- tmp[16] = ((u64) in[8]) * in[8];
+ tmp[8] = ((u64)in[0]) * (in[8] << 1) +
+ ((u64)in[1]) * (in[7] << 2) +
+ ((u64)in[2]) * (in[6] << 1) +
+ ((u64)in[3]) * (in[5] << 2) +
+ ((u64)in[4]) * in[4];
+ tmp[9] = ((u64)in[1]) * (in[8] << 1) +
+ ((u64)in[2]) * (in[7] << 1) +
+ ((u64)in[3]) * (in[6] << 1) +
+ ((u64)in[4]) * (in[5] << 1);
+ tmp[10] = ((u64)in[2]) * (in[8] << 1) +
+ ((u64)in[3]) * (in[7] << 2) +
+ ((u64)in[4]) * (in[6] << 1) +
+ ((u64)in[5]) * (in[5] << 1);
+ tmp[11] = ((u64)in[3]) * (in[8] << 1) +
+ ((u64)in[4]) * (in[7] << 1) +
+ ((u64)in[5]) * (in[6] << 1);
+ tmp[12] = ((u64)in[4]) * (in[8] << 1) +
+ ((u64)in[5]) * (in[7] << 2) +
+ ((u64)in[6]) * in[6];
+ tmp[13] = ((u64)in[5]) * (in[8] << 1) +
+ ((u64)in[6]) * (in[7] << 1);
+ tmp[14] = ((u64)in[6]) * (in[8] << 1) +
+ ((u64)in[7]) * (in[7] << 1);
+ tmp[15] = ((u64)in[7]) * (in[8] << 1);
+ tmp[16] = ((u64)in[8]) * in[8];
felem_reduce_degree(out, tmp);
}
@@ -539,99 +544,101 @@ static void felem_square(felem out, const felem in)
* in2[0,2,...] < 2**30, in2[1,3,...] < 2**29.
* On exit: out[0,2,...] < 2**30, out[1,3,...] < 2**29.
*/
-static void felem_mul(felem out, const felem in, const felem in2)
+static void
+felem_mul(felem out, const felem in, const felem in2)
{
u64 tmp[17];
- tmp[0] = ((u64) in[0]) * in2[0];
- tmp[1] = ((u64) in[0]) * (in2[1] << 0) +
- ((u64) in[1]) * (in2[0] << 0);
- tmp[2] = ((u64) in[0]) * (in2[2] << 0) +
- ((u64) in[1]) * (in2[1] << 1) +
- ((u64) in[2]) * (in2[0] << 0);
- tmp[3] = ((u64) in[0]) * (in2[3] << 0) +
- ((u64) in[1]) * (in2[2] << 0) +
- ((u64) in[2]) * (in2[1] << 0) +
- ((u64) in[3]) * (in2[0] << 0);
- tmp[4] = ((u64) in[0]) * (in2[4] << 0) +
- ((u64) in[1]) * (in2[3] << 1) +
- ((u64) in[2]) * (in2[2] << 0) +
- ((u64) in[3]) * (in2[1] << 1) +
- ((u64) in[4]) * (in2[0] << 0);
- tmp[5] = ((u64) in[0]) * (in2[5] << 0) +
- ((u64) in[1]) * (in2[4] << 0) +
- ((u64) in[2]) * (in2[3] << 0) +
- ((u64) in[3]) * (in2[2] << 0) +
- ((u64) in[4]) * (in2[1] << 0) +
- ((u64) in[5]) * (in2[0] << 0);
- tmp[6] = ((u64) in[0]) * (in2[6] << 0) +
- ((u64) in[1]) * (in2[5] << 1) +
- ((u64) in[2]) * (in2[4] << 0) +
- ((u64) in[3]) * (in2[3] << 1) +
- ((u64) in[4]) * (in2[2] << 0) +
- ((u64) in[5]) * (in2[1] << 1) +
- ((u64) in[6]) * (in2[0] << 0);
- tmp[7] = ((u64) in[0]) * (in2[7] << 0) +
- ((u64) in[1]) * (in2[6] << 0) +
- ((u64) in[2]) * (in2[5] << 0) +
- ((u64) in[3]) * (in2[4] << 0) +
- ((u64) in[4]) * (in2[3] << 0) +
- ((u64) in[5]) * (in2[2] << 0) +
- ((u64) in[6]) * (in2[1] << 0) +
- ((u64) in[7]) * (in2[0] << 0);
+ tmp[0] = ((u64)in[0]) * in2[0];
+ tmp[1] = ((u64)in[0]) * (in2[1] << 0) +
+ ((u64)in[1]) * (in2[0] << 0);
+ tmp[2] = ((u64)in[0]) * (in2[2] << 0) +
+ ((u64)in[1]) * (in2[1] << 1) +
+ ((u64)in[2]) * (in2[0] << 0);
+ tmp[3] = ((u64)in[0]) * (in2[3] << 0) +
+ ((u64)in[1]) * (in2[2] << 0) +
+ ((u64)in[2]) * (in2[1] << 0) +
+ ((u64)in[3]) * (in2[0] << 0);
+ tmp[4] = ((u64)in[0]) * (in2[4] << 0) +
+ ((u64)in[1]) * (in2[3] << 1) +
+ ((u64)in[2]) * (in2[2] << 0) +
+ ((u64)in[3]) * (in2[1] << 1) +
+ ((u64)in[4]) * (in2[0] << 0);
+ tmp[5] = ((u64)in[0]) * (in2[5] << 0) +
+ ((u64)in[1]) * (in2[4] << 0) +
+ ((u64)in[2]) * (in2[3] << 0) +
+ ((u64)in[3]) * (in2[2] << 0) +
+ ((u64)in[4]) * (in2[1] << 0) +
+ ((u64)in[5]) * (in2[0] << 0);
+ tmp[6] = ((u64)in[0]) * (in2[6] << 0) +
+ ((u64)in[1]) * (in2[5] << 1) +
+ ((u64)in[2]) * (in2[4] << 0) +
+ ((u64)in[3]) * (in2[3] << 1) +
+ ((u64)in[4]) * (in2[2] << 0) +
+ ((u64)in[5]) * (in2[1] << 1) +
+ ((u64)in[6]) * (in2[0] << 0);
+ tmp[7] = ((u64)in[0]) * (in2[7] << 0) +
+ ((u64)in[1]) * (in2[6] << 0) +
+ ((u64)in[2]) * (in2[5] << 0) +
+ ((u64)in[3]) * (in2[4] << 0) +
+ ((u64)in[4]) * (in2[3] << 0) +
+ ((u64)in[5]) * (in2[2] << 0) +
+ ((u64)in[6]) * (in2[1] << 0) +
+ ((u64)in[7]) * (in2[0] << 0);
/* tmp[8] has the greatest value but doesn't overflow. See logic in
* felem_square.
*/
- tmp[8] = ((u64) in[0]) * (in2[8] << 0) +
- ((u64) in[1]) * (in2[7] << 1) +
- ((u64) in[2]) * (in2[6] << 0) +
- ((u64) in[3]) * (in2[5] << 1) +
- ((u64) in[4]) * (in2[4] << 0) +
- ((u64) in[5]) * (in2[3] << 1) +
- ((u64) in[6]) * (in2[2] << 0) +
- ((u64) in[7]) * (in2[1] << 1) +
- ((u64) in[8]) * (in2[0] << 0);
- tmp[9] = ((u64) in[1]) * (in2[8] << 0) +
- ((u64) in[2]) * (in2[7] << 0) +
- ((u64) in[3]) * (in2[6] << 0) +
- ((u64) in[4]) * (in2[5] << 0) +
- ((u64) in[5]) * (in2[4] << 0) +
- ((u64) in[6]) * (in2[3] << 0) +
- ((u64) in[7]) * (in2[2] << 0) +
- ((u64) in[8]) * (in2[1] << 0);
- tmp[10] = ((u64) in[2]) * (in2[8] << 0) +
- ((u64) in[3]) * (in2[7] << 1) +
- ((u64) in[4]) * (in2[6] << 0) +
- ((u64) in[5]) * (in2[5] << 1) +
- ((u64) in[6]) * (in2[4] << 0) +
- ((u64) in[7]) * (in2[3] << 1) +
- ((u64) in[8]) * (in2[2] << 0);
- tmp[11] = ((u64) in[3]) * (in2[8] << 0) +
- ((u64) in[4]) * (in2[7] << 0) +
- ((u64) in[5]) * (in2[6] << 0) +
- ((u64) in[6]) * (in2[5] << 0) +
- ((u64) in[7]) * (in2[4] << 0) +
- ((u64) in[8]) * (in2[3] << 0);
- tmp[12] = ((u64) in[4]) * (in2[8] << 0) +
- ((u64) in[5]) * (in2[7] << 1) +
- ((u64) in[6]) * (in2[6] << 0) +
- ((u64) in[7]) * (in2[5] << 1) +
- ((u64) in[8]) * (in2[4] << 0);
- tmp[13] = ((u64) in[5]) * (in2[8] << 0) +
- ((u64) in[6]) * (in2[7] << 0) +
- ((u64) in[7]) * (in2[6] << 0) +
- ((u64) in[8]) * (in2[5] << 0);
- tmp[14] = ((u64) in[6]) * (in2[8] << 0) +
- ((u64) in[7]) * (in2[7] << 1) +
- ((u64) in[8]) * (in2[6] << 0);
- tmp[15] = ((u64) in[7]) * (in2[8] << 0) +
- ((u64) in[8]) * (in2[7] << 0);
- tmp[16] = ((u64) in[8]) * (in2[8] << 0);
+ tmp[8] = ((u64)in[0]) * (in2[8] << 0) +
+ ((u64)in[1]) * (in2[7] << 1) +
+ ((u64)in[2]) * (in2[6] << 0) +
+ ((u64)in[3]) * (in2[5] << 1) +
+ ((u64)in[4]) * (in2[4] << 0) +
+ ((u64)in[5]) * (in2[3] << 1) +
+ ((u64)in[6]) * (in2[2] << 0) +
+ ((u64)in[7]) * (in2[1] << 1) +
+ ((u64)in[8]) * (in2[0] << 0);
+ tmp[9] = ((u64)in[1]) * (in2[8] << 0) +
+ ((u64)in[2]) * (in2[7] << 0) +
+ ((u64)in[3]) * (in2[6] << 0) +
+ ((u64)in[4]) * (in2[5] << 0) +
+ ((u64)in[5]) * (in2[4] << 0) +
+ ((u64)in[6]) * (in2[3] << 0) +
+ ((u64)in[7]) * (in2[2] << 0) +
+ ((u64)in[8]) * (in2[1] << 0);
+ tmp[10] = ((u64)in[2]) * (in2[8] << 0) +
+ ((u64)in[3]) * (in2[7] << 1) +
+ ((u64)in[4]) * (in2[6] << 0) +
+ ((u64)in[5]) * (in2[5] << 1) +
+ ((u64)in[6]) * (in2[4] << 0) +
+ ((u64)in[7]) * (in2[3] << 1) +
+ ((u64)in[8]) * (in2[2] << 0);
+ tmp[11] = ((u64)in[3]) * (in2[8] << 0) +
+ ((u64)in[4]) * (in2[7] << 0) +
+ ((u64)in[5]) * (in2[6] << 0) +
+ ((u64)in[6]) * (in2[5] << 0) +
+ ((u64)in[7]) * (in2[4] << 0) +
+ ((u64)in[8]) * (in2[3] << 0);
+ tmp[12] = ((u64)in[4]) * (in2[8] << 0) +
+ ((u64)in[5]) * (in2[7] << 1) +
+ ((u64)in[6]) * (in2[6] << 0) +
+ ((u64)in[7]) * (in2[5] << 1) +
+ ((u64)in[8]) * (in2[4] << 0);
+ tmp[13] = ((u64)in[5]) * (in2[8] << 0) +
+ ((u64)in[6]) * (in2[7] << 0) +
+ ((u64)in[7]) * (in2[6] << 0) +
+ ((u64)in[8]) * (in2[5] << 0);
+ tmp[14] = ((u64)in[6]) * (in2[8] << 0) +
+ ((u64)in[7]) * (in2[7] << 1) +
+ ((u64)in[8]) * (in2[6] << 0);
+ tmp[15] = ((u64)in[7]) * (in2[8] << 0) +
+ ((u64)in[8]) * (in2[7] << 0);
+ tmp[16] = ((u64)in[8]) * (in2[8] << 0);
felem_reduce_degree(out, tmp);
}
-static void felem_assign(felem out, const felem in)
+static void
+felem_assign(felem out, const felem in)
{
memcpy(out, in, sizeof(felem));
}
@@ -643,66 +650,67 @@ static void felem_assign(felem out, const felem in)
* a^{p-1} = 1 (mod p)
* a^{p-2} = a^{-1} (mod p)
*/
-static void felem_inv(felem out, const felem in)
+static void
+felem_inv(felem out, const felem in)
{
felem ftmp, ftmp2;
/* each e_I will hold |in|^{2^I - 1} */
felem e2, e4, e8, e16, e32, e64;
unsigned int i;
- felem_square(ftmp, in); /* 2^1 */
- felem_mul(ftmp, in, ftmp); /* 2^2 - 2^0 */
+ felem_square(ftmp, in); /* 2^1 */
+ felem_mul(ftmp, in, ftmp); /* 2^2 - 2^0 */
felem_assign(e2, ftmp);
- felem_square(ftmp, ftmp); /* 2^3 - 2^1 */
- felem_square(ftmp, ftmp); /* 2^4 - 2^2 */
- felem_mul(ftmp, ftmp, e2); /* 2^4 - 2^0 */
+ felem_square(ftmp, ftmp); /* 2^3 - 2^1 */
+ felem_square(ftmp, ftmp); /* 2^4 - 2^2 */
+ felem_mul(ftmp, ftmp, e2); /* 2^4 - 2^0 */
felem_assign(e4, ftmp);
- felem_square(ftmp, ftmp); /* 2^5 - 2^1 */
- felem_square(ftmp, ftmp); /* 2^6 - 2^2 */
- felem_square(ftmp, ftmp); /* 2^7 - 2^3 */
- felem_square(ftmp, ftmp); /* 2^8 - 2^4 */
- felem_mul(ftmp, ftmp, e4); /* 2^8 - 2^0 */
+ felem_square(ftmp, ftmp); /* 2^5 - 2^1 */
+ felem_square(ftmp, ftmp); /* 2^6 - 2^2 */
+ felem_square(ftmp, ftmp); /* 2^7 - 2^3 */
+ felem_square(ftmp, ftmp); /* 2^8 - 2^4 */
+ felem_mul(ftmp, ftmp, e4); /* 2^8 - 2^0 */
felem_assign(e8, ftmp);
for (i = 0; i < 8; i++) {
- felem_square(ftmp, ftmp);
- } /* 2^16 - 2^8 */
- felem_mul(ftmp, ftmp, e8); /* 2^16 - 2^0 */
+ felem_square(ftmp, ftmp);
+ } /* 2^16 - 2^8 */
+ felem_mul(ftmp, ftmp, e8); /* 2^16 - 2^0 */
felem_assign(e16, ftmp);
for (i = 0; i < 16; i++) {
- felem_square(ftmp, ftmp);
- } /* 2^32 - 2^16 */
- felem_mul(ftmp, ftmp, e16); /* 2^32 - 2^0 */
+ felem_square(ftmp, ftmp);
+ } /* 2^32 - 2^16 */
+ felem_mul(ftmp, ftmp, e16); /* 2^32 - 2^0 */
felem_assign(e32, ftmp);
for (i = 0; i < 32; i++) {
- felem_square(ftmp, ftmp);
- } /* 2^64 - 2^32 */
+ felem_square(ftmp, ftmp);
+ } /* 2^64 - 2^32 */
felem_assign(e64, ftmp);
- felem_mul(ftmp, ftmp, in); /* 2^64 - 2^32 + 2^0 */
+ felem_mul(ftmp, ftmp, in); /* 2^64 - 2^32 + 2^0 */
for (i = 0; i < 192; i++) {
- felem_square(ftmp, ftmp);
- } /* 2^256 - 2^224 + 2^192 */
+ felem_square(ftmp, ftmp);
+ } /* 2^256 - 2^224 + 2^192 */
- felem_mul(ftmp2, e64, e32); /* 2^64 - 2^0 */
+ felem_mul(ftmp2, e64, e32); /* 2^64 - 2^0 */
for (i = 0; i < 16; i++) {
- felem_square(ftmp2, ftmp2);
- } /* 2^80 - 2^16 */
- felem_mul(ftmp2, ftmp2, e16); /* 2^80 - 2^0 */
+ felem_square(ftmp2, ftmp2);
+ } /* 2^80 - 2^16 */
+ felem_mul(ftmp2, ftmp2, e16); /* 2^80 - 2^0 */
for (i = 0; i < 8; i++) {
- felem_square(ftmp2, ftmp2);
- } /* 2^88 - 2^8 */
- felem_mul(ftmp2, ftmp2, e8); /* 2^88 - 2^0 */
+ felem_square(ftmp2, ftmp2);
+ } /* 2^88 - 2^8 */
+ felem_mul(ftmp2, ftmp2, e8); /* 2^88 - 2^0 */
for (i = 0; i < 4; i++) {
- felem_square(ftmp2, ftmp2);
- } /* 2^92 - 2^4 */
- felem_mul(ftmp2, ftmp2, e4); /* 2^92 - 2^0 */
- felem_square(ftmp2, ftmp2); /* 2^93 - 2^1 */
- felem_square(ftmp2, ftmp2); /* 2^94 - 2^2 */
- felem_mul(ftmp2, ftmp2, e2); /* 2^94 - 2^0 */
- felem_square(ftmp2, ftmp2); /* 2^95 - 2^1 */
- felem_square(ftmp2, ftmp2); /* 2^96 - 2^2 */
- felem_mul(ftmp2, ftmp2, in); /* 2^96 - 3 */
-
- felem_mul(out, ftmp2, ftmp); /* 2^256 - 2^224 + 2^192 + 2^96 - 3 */
+ felem_square(ftmp2, ftmp2);
+ } /* 2^92 - 2^4 */
+ felem_mul(ftmp2, ftmp2, e4); /* 2^92 - 2^0 */
+ felem_square(ftmp2, ftmp2); /* 2^93 - 2^1 */
+ felem_square(ftmp2, ftmp2); /* 2^94 - 2^2 */
+ felem_mul(ftmp2, ftmp2, e2); /* 2^94 - 2^0 */
+ felem_square(ftmp2, ftmp2); /* 2^95 - 2^1 */
+ felem_square(ftmp2, ftmp2); /* 2^96 - 2^2 */
+ felem_mul(ftmp2, ftmp2, in); /* 2^96 - 3 */
+
+ felem_mul(out, ftmp2, ftmp); /* 2^256 - 2^224 + 2^192 + 2^96 - 3 */
}
/* felem_scalar_3 sets out=3*out.
@@ -710,25 +718,26 @@ static void felem_inv(felem out, const felem in)
* On entry: out[0,2,...] < 2**30, out[1,3,...] < 2**29.
* On exit: out[0,2,...] < 2**30, out[1,3,...] < 2**29.
*/
-static void felem_scalar_3(felem out)
+static void
+felem_scalar_3(felem out)
{
limb carry = 0;
unsigned int i;
for (i = 0;; i++) {
- out[i] *= 3;
- out[i] += carry;
- carry = out[i] >> 29;
- out[i] &= kBottom29Bits;
-
- i++;
- if (i == NLIMBS)
- break;
-
- out[i] *= 3;
- out[i] += carry;
- carry = out[i] >> 28;
- out[i] &= kBottom28Bits;
+ out[i] *= 3;
+ out[i] += carry;
+ carry = out[i] >> 29;
+ out[i] &= kBottom29Bits;
+
+ i++;
+ if (i == NLIMBS)
+ break;
+
+ out[i] *= 3;
+ out[i] += carry;
+ carry = out[i] >> 28;
+ out[i] &= kBottom28Bits;
}
felem_reduce_carry(out, carry);
@@ -739,28 +748,29 @@ static void felem_scalar_3(felem out)
* On entry: out[0,2,...] < 2**30, out[1,3,...] < 2**29.
* On exit: out[0,2,...] < 2**30, out[1,3,...] < 2**29.
*/
-static void felem_scalar_4(felem out)
+static void
+felem_scalar_4(felem out)
{
limb carry = 0, next_carry;
unsigned int i;
for (i = 0;; i++) {
- next_carry = out[i] >> 27;
- out[i] <<= 2;
- out[i] &= kBottom29Bits;
- out[i] += carry;
- carry = next_carry + (out[i] >> 29);
- out[i] &= kBottom29Bits;
-
- i++;
- if (i == NLIMBS)
- break;
- next_carry = out[i] >> 26;
- out[i] <<= 2;
- out[i] &= kBottom28Bits;
- out[i] += carry;
- carry = next_carry + (out[i] >> 28);
- out[i] &= kBottom28Bits;
+ next_carry = out[i] >> 27;
+ out[i] <<= 2;
+ out[i] &= kBottom29Bits;
+ out[i] += carry;
+ carry = next_carry + (out[i] >> 29);
+ out[i] &= kBottom29Bits;
+
+ i++;
+ if (i == NLIMBS)
+ break;
+ next_carry = out[i] >> 26;
+ out[i] <<= 2;
+ out[i] &= kBottom28Bits;
+ out[i] += carry;
+ carry = next_carry + (out[i] >> 28);
+ out[i] &= kBottom28Bits;
}
felem_reduce_carry(out, carry);
@@ -771,28 +781,29 @@ static void felem_scalar_4(felem out)
* On entry: out[0,2,...] < 2**30, out[1,3,...] < 2**29.
* On exit: out[0,2,...] < 2**30, out[1,3,...] < 2**29.
*/
-static void felem_scalar_8(felem out)
+static void
+felem_scalar_8(felem out)
{
limb carry = 0, next_carry;
unsigned int i;
for (i = 0;; i++) {
- next_carry = out[i] >> 26;
- out[i] <<= 3;
- out[i] &= kBottom29Bits;
- out[i] += carry;
- carry = next_carry + (out[i] >> 29);
- out[i] &= kBottom29Bits;
-
- i++;
- if (i == NLIMBS)
- break;
- next_carry = out[i] >> 25;
- out[i] <<= 3;
- out[i] &= kBottom28Bits;
- out[i] += carry;
- carry = next_carry + (out[i] >> 28);
- out[i] &= kBottom28Bits;
+ next_carry = out[i] >> 26;
+ out[i] <<= 3;
+ out[i] &= kBottom29Bits;
+ out[i] += carry;
+ carry = next_carry + (out[i] >> 29);
+ out[i] &= kBottom29Bits;
+
+ i++;
+ if (i == NLIMBS)
+ break;
+ next_carry = out[i] >> 25;
+ out[i] <<= 3;
+ out[i] &= kBottom28Bits;
+ out[i] += carry;
+ carry = next_carry + (out[i] >> 28);
+ out[i] &= kBottom28Bits;
}
felem_reduce_carry(out, carry);
@@ -801,7 +812,8 @@ static void felem_scalar_8(felem out)
/* felem_is_zero_vartime returns 1 iff |in| == 0. It takes a variable amount of
* time depending on the value of |in|.
*/
-static char felem_is_zero_vartime(const felem in)
+static char
+felem_is_zero_vartime(const felem in)
{
limb carry;
int i;
@@ -811,29 +823,29 @@ static char felem_is_zero_vartime(const felem in)
/* First, reduce tmp to a minimal form.
*/
do {
- carry = 0;
- for (i = 0;; i++) {
- tmp[i] += carry;
- carry = tmp[i] >> 29;
- tmp[i] &= kBottom29Bits;
-
- i++;
- if (i == NLIMBS)
- break;
-
- tmp[i] += carry;
- carry = tmp[i] >> 28;
- tmp[i] &= kBottom28Bits;
- }
-
- felem_reduce_carry(tmp, carry);
+ carry = 0;
+ for (i = 0;; i++) {
+ tmp[i] += carry;
+ carry = tmp[i] >> 29;
+ tmp[i] &= kBottom29Bits;
+
+ i++;
+ if (i == NLIMBS)
+ break;
+
+ tmp[i] += carry;
+ carry = tmp[i] >> 28;
+ tmp[i] &= kBottom28Bits;
+ }
+
+ felem_reduce_carry(tmp, carry);
} while (carry);
/* tmp < 2**257, so the only possible zero values are 0, p and 2p.
*/
return memcmp(tmp, kZero, sizeof(tmp)) == 0 ||
- memcmp(tmp, kP, sizeof(tmp)) == 0 ||
- memcmp(tmp, k2P, sizeof(tmp)) == 0;
+ memcmp(tmp, kP, sizeof(tmp)) == 0 ||
+ memcmp(tmp, k2P, sizeof(tmp)) == 0;
}
/* Group operations:
@@ -847,8 +859,9 @@ static char felem_is_zero_vartime(const felem in)
*
* See http://www.hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-0.html#doubling-dbl-2009-l
*/
-static void point_double(felem x_out, felem y_out, felem z_out,
- const felem x, const felem y, const felem z)
+static void
+point_double(felem x_out, felem y_out, felem z_out,
+ const felem x, const felem y, const felem z)
{
felem delta, gamma, alpha, beta, tmp, tmp2;
@@ -886,9 +899,10 @@ static void point_double(felem x_out, felem y_out, felem z_out,
* Note that this function does not handle P+P, infinity+P nor P+infinity
* correctly.
*/
-static void point_add_mixed(felem x_out, felem y_out, felem z_out,
- const felem x1, const felem y1, const felem z1,
- const felem x2, const felem y2)
+static void
+point_add_mixed(felem x_out, felem y_out, felem z_out,
+ const felem x1, const felem y1, const felem z1,
+ const felem x2, const felem y2)
{
felem z1z1, z1z1z1, s2, u2, h, i, j, r, rr, v, tmp;
@@ -926,9 +940,10 @@ static void point_add_mixed(felem x_out, felem y_out, felem z_out,
* Note that this function does not handle P+P, infinity+P nor P+infinity
* correctly.
*/
-static void point_add(felem x_out, felem y_out, felem z_out,
- const felem x1, const felem y1, const felem z1,
- const felem x2, const felem y2, const felem z2)
+static void
+point_add(felem x_out, felem y_out, felem z_out,
+ const felem x1, const felem y1, const felem z1,
+ const felem x2, const felem y2, const felem z2)
{
felem z1z1, z1z1z1, z2z2, z2z2z2, s1, s2, u1, u2, h, i, j, r, rr, v, tmp;
@@ -975,7 +990,8 @@ static void point_add(felem x_out, felem y_out, felem z_out,
*
* This function handles the case where {x1,y1,z1}={x2,y2,z2}.
*/
-static void point_add_or_double_vartime(
+static void
+point_add_or_double_vartime(
felem x_out, felem y_out, felem z_out,
const felem x1, const felem y1, const felem z1,
const felem x2, const felem y2, const felem z2)
@@ -1006,8 +1022,8 @@ static void point_add_or_double_vartime(
felem_diff(r, s2, s1);
y_equal = felem_is_zero_vartime(r);
if (x_equal && y_equal) {
- point_double(x_out, y_out, z_out, x1, y1, z1);
- return;
+ point_double(x_out, y_out, z_out, x1, y1, z1);
+ return;
}
felem_sum(r, r, r);
felem_mul(v, u1, i);
@@ -1029,21 +1045,23 @@ static void point_add_or_double_vartime(
*
* On entry: mask is either 0 or 0xffffffff.
*/
-static void copy_conditional(felem out, const felem in, limb mask)
+static void
+copy_conditional(felem out, const felem in, limb mask)
{
int i;
for (i = 0; i < NLIMBS; i++) {
- const limb tmp = mask & (in[i] ^ out[i]);
- out[i] ^= tmp;
+ const limb tmp = mask & (in[i] ^ out[i]);
+ out[i] ^= tmp;
}
}
/* select_affine_point sets {out_x,out_y} to the index'th entry of table.
* On entry: index < 16, table[0] must be zero.
*/
-static void select_affine_point(felem out_x, felem out_y,
- const limb *table, limb index)
+static void
+select_affine_point(felem out_x, felem out_y,
+ const limb *table, limb index)
{
limb i, j;
@@ -1051,25 +1069,26 @@ static void select_affine_point(felem out_x, felem out_y,
memset(out_y, 0, sizeof(felem));
for (i = 1; i < 16; i++) {
- limb mask = i ^ index;
- mask |= mask >> 2;
- mask |= mask >> 1;
- mask &= 1;
- mask--;
- for (j = 0; j < NLIMBS; j++, table++) {
- out_x[j] |= *table & mask;
- }
- for (j = 0; j < NLIMBS; j++, table++) {
- out_y[j] |= *table & mask;
- }
+ limb mask = i ^ index;
+ mask |= mask >> 2;
+ mask |= mask >> 1;
+ mask &= 1;
+ mask--;
+ for (j = 0; j < NLIMBS; j++, table++) {
+ out_x[j] |= *table & mask;
+ }
+ for (j = 0; j < NLIMBS; j++, table++) {
+ out_y[j] |= *table & mask;
+ }
}
}
/* select_jacobian_point sets {out_x,out_y,out_z} to the index'th entry of
* table. On entry: index < 16, table[0] must be zero.
*/
-static void select_jacobian_point(felem out_x, felem out_y, felem out_z,
- const limb *table, limb index)
+static void
+select_jacobian_point(felem out_x, felem out_y, felem out_z,
+ const limb *table, limb index)
{
limb i, j;
@@ -1080,28 +1099,29 @@ static void select_jacobian_point(felem out_x, felem out_y, felem out_z,
/* The implicit value at index 0 is all zero. We don't need to perform that
* iteration of the loop because we already set out_* to zero.
*/
- table += 3*NLIMBS;
+ table += 3 * NLIMBS;
for (i = 1; i < 16; i++) {
- limb mask = i ^ index;
- mask |= mask >> 2;
- mask |= mask >> 1;
- mask &= 1;
- mask--;
- for (j = 0; j < NLIMBS; j++, table++) {
- out_x[j] |= *table & mask;
- }
- for (j = 0; j < NLIMBS; j++, table++) {
- out_y[j] |= *table & mask;
- }
- for (j = 0; j < NLIMBS; j++, table++) {
- out_z[j] |= *table & mask;
- }
+ limb mask = i ^ index;
+ mask |= mask >> 2;
+ mask |= mask >> 1;
+ mask &= 1;
+ mask--;
+ for (j = 0; j < NLIMBS; j++, table++) {
+ out_x[j] |= *table & mask;
+ }
+ for (j = 0; j < NLIMBS; j++, table++) {
+ out_y[j] |= *table & mask;
+ }
+ for (j = 0; j < NLIMBS; j++, table++) {
+ out_z[j] |= *table & mask;
+ }
}
}
/* get_bit returns the bit'th bit of scalar. */
-static char get_bit(const u8 scalar[32], int bit)
+static char
+get_bit(const u8 scalar[32], int bit)
{
return ((scalar[bit >> 3]) >> (bit & 7)) & 1;
}
@@ -1110,7 +1130,8 @@ static char get_bit(const u8 scalar[32], int bit)
* number. Note that the value of scalar must be less than the order of the
* group.
*/
-static void scalar_base_mult(felem nx, felem ny, felem nz, const u8 scalar[32])
+static void
+scalar_base_mult(felem nx, felem ny, felem nz, const u8 scalar[32])
{
int i, j;
limb n_is_infinity_mask = -1, p_is_noninfinite_mask, mask;
@@ -1127,53 +1148,55 @@ static void scalar_base_mult(felem nx, felem ny, felem nz, const u8 scalar[32])
* positions 32,96,160 and 224 and does this 32 times.
*/
for (i = 0; i < 32; i++) {
- if (i) {
- point_double(nx, ny, nz, nx, ny, nz);
- }
- table_offset = 0;
- for (j = 0; j <= 32; j += 32) {
- char bit0 = get_bit(scalar, 31 - i + j);
- char bit1 = get_bit(scalar, 95 - i + j);
- char bit2 = get_bit(scalar, 159 - i + j);
- char bit3 = get_bit(scalar, 223 - i + j);
- limb index = bit0 | (bit1 << 1) | (bit2 << 2) | (bit3 << 3);
-
- select_affine_point(px, py, kPrecomputed + table_offset, index);
- table_offset += 30 * NLIMBS;
-
- /* Since scalar is less than the order of the group, we know that
- * {nx,ny,nz} != {px,py,1}, unless both are zero, which we handle
- * below.
- */
- point_add_mixed(tx, ty, tz, nx, ny, nz, px, py);
- /* The result of point_add_mixed is incorrect if {nx,ny,nz} is zero
- * (a.k.a. the point at infinity). We handle that situation by
- * copying the point from the table.
- */
- copy_conditional(nx, px, n_is_infinity_mask);
- copy_conditional(ny, py, n_is_infinity_mask);
- copy_conditional(nz, kOne, n_is_infinity_mask);
-
- /* Equally, the result is also wrong if the point from the table is
- * zero, which happens when the index is zero. We handle that by
- * only copying from {tx,ty,tz} to {nx,ny,nz} if index != 0.
- */
- p_is_noninfinite_mask = NON_ZERO_TO_ALL_ONES(index);
- mask = p_is_noninfinite_mask & ~n_is_infinity_mask;
- copy_conditional(nx, tx, mask);
- copy_conditional(ny, ty, mask);
- copy_conditional(nz, tz, mask);
- /* If p was not zero, then n is now non-zero. */
- n_is_infinity_mask &= ~p_is_noninfinite_mask;
- }
+ if (i) {
+ point_double(nx, ny, nz, nx, ny, nz);
+ }
+ table_offset = 0;
+ for (j = 0; j <= 32; j += 32) {
+ char bit0 = get_bit(scalar, 31 - i + j);
+ char bit1 = get_bit(scalar, 95 - i + j);
+ char bit2 = get_bit(scalar, 159 - i + j);
+ char bit3 = get_bit(scalar, 223 - i + j);
+ limb index = bit0 | (bit1 << 1) | (bit2 << 2) | (bit3 << 3);
+
+ select_affine_point(px, py, kPrecomputed + table_offset, index);
+ table_offset += 30 * NLIMBS;
+
+ /* Since scalar is less than the order of the group, we know that
+ * {nx,ny,nz} != {px,py,1}, unless both are zero, which we handle
+ * below.
+ */
+ point_add_mixed(tx, ty, tz, nx, ny, nz, px, py);
+ /* The result of point_add_mixed is incorrect if {nx,ny,nz} is zero
+ * (a.k.a. the point at infinity). We handle that situation by
+ * copying the point from the table.
+ */
+ copy_conditional(nx, px, n_is_infinity_mask);
+ copy_conditional(ny, py, n_is_infinity_mask);
+ copy_conditional(nz, kOne, n_is_infinity_mask);
+
+ /* Equally, the result is also wrong if the point from the table is
+ * zero, which happens when the index is zero. We handle that by
+ * only copying from {tx,ty,tz} to {nx,ny,nz} if index != 0.
+ */
+ p_is_noninfinite_mask = NON_ZERO_TO_ALL_ONES(index);
+ mask = p_is_noninfinite_mask & ~n_is_infinity_mask;
+ copy_conditional(nx, tx, mask);
+ copy_conditional(ny, ty, mask);
+ copy_conditional(nz, tz, mask);
+ /* If p was not zero, then n is now non-zero. */
+ n_is_infinity_mask &= ~p_is_noninfinite_mask;
+ }
}
}
/* point_to_affine converts a Jacobian point to an affine point. If the input
* is the point at infinity then it returns (0, 0) in constant time.
*/
-static void point_to_affine(felem x_out, felem y_out,
- const felem nx, const felem ny, const felem nz) {
+static void
+point_to_affine(felem x_out, felem y_out,
+ const felem nx, const felem ny, const felem nz)
+{
felem z_inv, z_inv_sq;
felem_inv(z_inv, nz);
felem_square(z_inv_sq, z_inv);
@@ -1183,8 +1206,9 @@ static void point_to_affine(felem x_out, felem y_out,
}
/* scalar_mult sets {nx,ny,nz} = scalar*{x,y}. */
-static void scalar_mult(felem nx, felem ny, felem nz,
- const felem x, const felem y, const u8 scalar[32])
+static void
+scalar_mult(felem nx, felem ny, felem nz,
+ const felem x, const felem y, const u8 scalar[32])
{
int i;
felem px, py, pz, tx, ty, tz;
@@ -1198,11 +1222,11 @@ static void scalar_mult(felem nx, felem ny, felem nz,
memcpy(&precomp[1][2], kOne, sizeof(felem));
for (i = 2; i < 16; i += 2) {
- point_double(precomp[i][0], precomp[i][1], precomp[i][2],
- precomp[i / 2][0], precomp[i / 2][1], precomp[i / 2][2]);
+ point_double(precomp[i][0], precomp[i][1], precomp[i][2],
+ precomp[i / 2][0], precomp[i / 2][1], precomp[i / 2][2]);
- point_add_mixed(precomp[i + 1][0], precomp[i + 1][1], precomp[i + 1][2],
- precomp[i][0], precomp[i][1], precomp[i][2], x, y);
+ point_add_mixed(precomp[i + 1][0], precomp[i + 1][1], precomp[i + 1][2],
+ precomp[i][0], precomp[i][1], precomp[i][2], x, y);
}
memset(nx, 0, sizeof(felem));
@@ -1212,33 +1236,33 @@ static void scalar_mult(felem nx, felem ny, felem nz,
/* We add in a window of four bits each iteration and do this 64 times. */
for (i = 0; i < 64; i++) {
- if (i) {
- point_double(nx, ny, nz, nx, ny, nz);
- point_double(nx, ny, nz, nx, ny, nz);
- point_double(nx, ny, nz, nx, ny, nz);
- point_double(nx, ny, nz, nx, ny, nz);
- }
-
- index = scalar[31 - i / 2];
- if ((i & 1) == 1) {
- index &= 15;
- } else {
- index >>= 4;
- }
-
- /* See the comments in scalar_base_mult about handling infinities. */
- select_jacobian_point(px, py, pz, precomp[0][0], index);
- point_add(tx, ty, tz, nx, ny, nz, px, py, pz);
- copy_conditional(nx, px, n_is_infinity_mask);
- copy_conditional(ny, py, n_is_infinity_mask);
- copy_conditional(nz, pz, n_is_infinity_mask);
-
- p_is_noninfinite_mask = NON_ZERO_TO_ALL_ONES(index);
- mask = p_is_noninfinite_mask & ~n_is_infinity_mask;
- copy_conditional(nx, tx, mask);
- copy_conditional(ny, ty, mask);
- copy_conditional(nz, tz, mask);
- n_is_infinity_mask &= ~p_is_noninfinite_mask;
+ if (i) {
+ point_double(nx, ny, nz, nx, ny, nz);
+ point_double(nx, ny, nz, nx, ny, nz);
+ point_double(nx, ny, nz, nx, ny, nz);
+ point_double(nx, ny, nz, nx, ny, nz);
+ }
+
+ index = scalar[31 - i / 2];
+ if ((i & 1) == 1) {
+ index &= 15;
+ } else {
+ index >>= 4;
+ }
+
+ /* See the comments in scalar_base_mult about handling infinities. */
+ select_jacobian_point(px, py, pz, precomp[0][0], index);
+ point_add(tx, ty, tz, nx, ny, nz, px, py, pz);
+ copy_conditional(nx, px, n_is_infinity_mask);
+ copy_conditional(ny, py, n_is_infinity_mask);
+ copy_conditional(nz, pz, n_is_infinity_mask);
+
+ p_is_noninfinite_mask = NON_ZERO_TO_ALL_ONES(index);
+ mask = p_is_noninfinite_mask & ~n_is_infinity_mask;
+ copy_conditional(nx, tx, mask);
+ copy_conditional(ny, ty, mask);
+ copy_conditional(nz, tz, mask);
+ n_is_infinity_mask &= ~p_is_noninfinite_mask;
}
}
@@ -1254,12 +1278,12 @@ static void scalar_mult(felem nx, felem ny, felem nz,
#define BYTESWAP64(x) OSSwapInt64(x)
#else
#define BYTESWAP32(x) \
- (((x) >> 24) | (((x) >> 8) & 0xff00) | (((x) & 0xff00) << 8) | ((x) << 24))
-#define BYTESWAP64(x) \
- (((x) >> 56) | (((x) >> 40) & 0xff00) | \
+ (((x) >> 24) | (((x) >> 8) & 0xff00) | (((x)&0xff00) << 8) | ((x) << 24))
+#define BYTESWAP64(x) \
+ (((x) >> 56) | (((x) >> 40) & 0xff00) | \
(((x) >> 24) & 0xff0000) | (((x) >> 8) & 0xff000000) | \
- (((x) & 0xff000000) << 8) | (((x) & 0xff0000) << 24) | \
- (((x) & 0xff00) << 40) | ((x) << 56))
+ (((x)&0xff000000) << 8) | (((x)&0xff0000) << 24) | \
+ (((x)&0xff00) << 40) | ((x) << 56))
#endif
#ifdef MP_USE_UINT_DIGIT
@@ -1276,23 +1300,24 @@ static const mp_digit kRInvDigits[8] = {
};
#else
static const mp_digit kRInvDigits[4] = {
- PR_UINT64(0x180000000), 0xffffffff,
+ PR_UINT64(0x180000000), 0xffffffff,
PR_UINT64(0xfffffffe80000001), PR_UINT64(0x7fffffff00000001)
};
#endif
-#define MP_DIGITS_IN_256_BITS (32/sizeof(mp_digit))
+#define MP_DIGITS_IN_256_BITS (32 / sizeof(mp_digit))
static const mp_int kRInv = {
MP_ZPOS,
MP_DIGITS_IN_256_BITS,
MP_DIGITS_IN_256_BITS,
- (mp_digit*) kRInvDigits
+ (mp_digit *)kRInvDigits
};
static const limb kTwo28 = 0x10000000;
static const limb kTwo29 = 0x20000000;
/* to_montgomery sets out = R*in. */
-static mp_err to_montgomery(felem out, const mp_int *in, const ECGroup *group)
+static mp_err
+to_montgomery(felem out, const mp_int *in, const ECGroup *group)
{
/* There are no MPI functions for bitshift operations and we wish to shift
* in 257 bits left so we move the digits 256-bits left and then multiply
@@ -1302,23 +1327,23 @@ static mp_err to_montgomery(felem out, const mp_int *in, const ECGroup *group)
int i;
mp_err res;
- mp_init(&in_shifted);
- s_mp_pad(&in_shifted, MP_USED(in) + MP_DIGITS_IN_256_BITS);
+ MP_CHECKOK(mp_init(&in_shifted));
+ MP_CHECKOK(s_mp_pad(&in_shifted, MP_USED(in) + MP_DIGITS_IN_256_BITS));
memcpy(&MP_DIGIT(&in_shifted, MP_DIGITS_IN_256_BITS),
- MP_DIGITS(in),
- MP_USED(in)*sizeof(mp_digit));
- mp_mul_2(&in_shifted, &in_shifted);
+ MP_DIGITS(in),
+ MP_USED(in) * sizeof(mp_digit));
+ MP_CHECKOK(mp_mul_2(&in_shifted, &in_shifted));
MP_CHECKOK(group->meth->field_mod(&in_shifted, &in_shifted, group->meth));
for (i = 0;; i++) {
- out[i] = MP_DIGIT(&in_shifted, 0) & kBottom29Bits;
- mp_div_d(&in_shifted, kTwo29, &in_shifted, NULL);
-
- i++;
- if (i == NLIMBS)
- break;
- out[i] = MP_DIGIT(&in_shifted, 0) & kBottom28Bits;
- mp_div_d(&in_shifted, kTwo28, &in_shifted, NULL);
+ out[i] = MP_DIGIT(&in_shifted, 0) & kBottom29Bits;
+ MP_CHECKOK(mp_div_d(&in_shifted, kTwo29, &in_shifted, NULL));
+
+ i++;
+ if (i == NLIMBS)
+ break;
+ out[i] = MP_DIGIT(&in_shifted, 0) & kBottom28Bits;
+ MP_CHECKOK(mp_div_d(&in_shifted, kTwo28, &in_shifted, NULL));
}
CLEANUP:
@@ -1327,24 +1352,25 @@ CLEANUP:
}
/* from_montgomery sets out=in/R. */
-static mp_err from_montgomery(mp_int *out, const felem in,
- const ECGroup *group)
+static mp_err
+from_montgomery(mp_int *out, const felem in,
+ const ECGroup *group)
{
mp_int result, tmp;
mp_err res;
int i;
- mp_init(&result);
- mp_init(&tmp);
-
- MP_CHECKOK(mp_add_d(&tmp, in[NLIMBS-1], &result));
- for (i = NLIMBS-2; i >= 0; i--) {
- if ((i & 1) == 0) {
- MP_CHECKOK(mp_mul_d(&result, kTwo29, &tmp));
- } else {
- MP_CHECKOK(mp_mul_d(&result, kTwo28, &tmp));
- }
- MP_CHECKOK(mp_add_d(&tmp, in[i], &result));
+ MP_CHECKOK(mp_init(&result));
+ MP_CHECKOK(mp_init(&tmp));
+
+ MP_CHECKOK(mp_add_d(&tmp, in[NLIMBS - 1], &result));
+ for (i = NLIMBS - 2; i >= 0; i--) {
+ if ((i & 1) == 0) {
+ MP_CHECKOK(mp_mul_d(&result, kTwo29, &tmp));
+ } else {
+ MP_CHECKOK(mp_mul_d(&result, kTwo28, &tmp));
+ }
+ MP_CHECKOK(mp_add_d(&tmp, in[i], &result));
}
MP_CHECKOK(mp_mul(&result, &kRInv, out));
@@ -1357,7 +1383,8 @@ CLEANUP:
}
/* scalar_from_mp_int sets out_scalar=n, where n < the group order. */
-static void scalar_from_mp_int(u8 out_scalar[32], const mp_int *n)
+static void
+scalar_from_mp_int(u8 out_scalar[32], const mp_int *n)
{
/* We require that |n| is less than the order of the group and therefore it
* will fit into |out_scalar|. However, these is a timing side-channel here
@@ -1369,12 +1396,12 @@ static void scalar_from_mp_int(u8 out_scalar[32], const mp_int *n)
memcpy(out_scalar, MP_DIGITS(n), MP_USED(n) * sizeof(mp_digit));
#else
{
- mp_size i;
- mp_digit swapped[MP_DIGITS_IN_256_BITS];
- for (i = 0; i < MP_USED(n); i++) {
- swapped[i] = BYTESWAP_MP_DIGIT_TO_LE(MP_DIGIT(n, i));
- }
- memcpy(out_scalar, swapped, MP_USED(n) * sizeof(mp_digit));
+ mp_size i;
+ mp_digit swapped[MP_DIGITS_IN_256_BITS];
+ for (i = 0; i < MP_USED(n); i++) {
+ swapped[i] = BYTESWAP_MP_DIGIT_TO_LE(MP_DIGIT(n, i));
+ }
+ memcpy(out_scalar, swapped, MP_USED(n) * sizeof(mp_digit));
}
#endif
}
@@ -1382,9 +1409,10 @@ static void scalar_from_mp_int(u8 out_scalar[32], const mp_int *n)
/* ec_GFp_nistp256_base_point_mul sets {out_x,out_y} = nG, where n is < the
* order of the group.
*/
-static mp_err ec_GFp_nistp256_base_point_mul(const mp_int *n,
- mp_int *out_x, mp_int *out_y,
- const ECGroup *group)
+static mp_err
+ec_GFp_nistp256_base_point_mul(const mp_int *n,
+ mp_int *out_x, mp_int *out_y,
+ const ECGroup *group)
{
u8 scalar[32];
felem x, y, z, x_affine, y_affine;
@@ -1405,10 +1433,11 @@ CLEANUP:
/* ec_GFp_nistp256_point_mul sets {out_x,out_y} = n*{in_x,in_y}, where n is <
* the order of the group.
*/
-static mp_err ec_GFp_nistp256_point_mul(const mp_int *n,
- const mp_int *in_x, const mp_int *in_y,
- mp_int *out_x, mp_int *out_y,
- const ECGroup *group)
+static mp_err
+ec_GFp_nistp256_point_mul(const mp_int *n,
+ const mp_int *in_x, const mp_int *in_y,
+ mp_int *out_x, mp_int *out_y,
+ const ECGroup *group)
{
u8 scalar[32];
felem x, y, z, x_affine, y_affine, px, py;
@@ -1435,11 +1464,12 @@ CLEANUP:
* is safe because it's used for signature validation which doesn't deal
* with secrets.
*/
-static mp_err ec_GFp_nistp256_points_mul_vartime(
- const mp_int *n1, const mp_int *n2,
- const mp_int *in_x, const mp_int *in_y,
- mp_int *out_x, mp_int *out_y,
- const ECGroup *group)
+static mp_err
+ec_GFp_nistp256_points_mul_vartime(
+ const mp_int *n1, const mp_int *n2,
+ const mp_int *in_x, const mp_int *in_y,
+ mp_int *out_x, mp_int *out_y,
+ const ECGroup *group)
{
u8 scalar1[32], scalar2[32];
felem x1, y1, z1, x2, y2, z2, x_affine, y_affine, px, py;
@@ -1447,19 +1477,19 @@ static mp_err ec_GFp_nistp256_points_mul_vartime(
/* If n2 == NULL, this is just a base-point multiplication. */
if (n2 == NULL) {
- return ec_GFp_nistp256_base_point_mul(n1, out_x, out_y, group);
+ return ec_GFp_nistp256_base_point_mul(n1, out_x, out_y, group);
}
/* If n1 == nULL, this is just an arbitary-point multiplication. */
if (n1 == NULL) {
- return ec_GFp_nistp256_point_mul(n2, in_x, in_y, out_x, out_y, group);
+ return ec_GFp_nistp256_point_mul(n2, in_x, in_y, out_x, out_y, group);
}
/* If both scalars are zero, then the result is the point at infinity. */
if (mp_cmp_z(n1) == 0 && mp_cmp_z(n2) == 0) {
- mp_zero(out_x);
- mp_zero(out_y);
- return res;
+ mp_zero(out_x);
+ mp_zero(out_y);
+ return res;
}
scalar_from_mp_int(scalar1, n1);
@@ -1471,17 +1501,17 @@ static mp_err ec_GFp_nistp256_points_mul_vartime(
scalar_mult(x2, y2, z2, px, py, scalar2);
if (mp_cmp_z(n2) == 0) {
- /* If n2 == 0, then {x2,y2,z2} is zero and the result is just
- * {x1,y1,z1}. */
+ /* If n2 == 0, then {x2,y2,z2} is zero and the result is just
+ * {x1,y1,z1}. */
} else if (mp_cmp_z(n1) == 0) {
- /* If n1 == 0, then {x1,y1,z1} is zero and the result is just
- * {x2,y2,z2}. */
- memcpy(x1, x2, sizeof(x2));
- memcpy(y1, y2, sizeof(y2));
- memcpy(z1, z2, sizeof(z2));
+ /* If n1 == 0, then {x1,y1,z1} is zero and the result is just
+ * {x2,y2,z2}. */
+ memcpy(x1, x2, sizeof(x2));
+ memcpy(y1, y2, sizeof(y2));
+ memcpy(z1, z2, sizeof(z2));
} else {
- /* This function handles the case where {x1,y1,z1} == {x2,y2,z2}. */
- point_add_or_double_vartime(x1, y1, z1, x1, y1, z1, x2, y2, z2);
+ /* This function handles the case where {x1,y1,z1} == {x2,y2,z2}. */
+ point_add_or_double_vartime(x1, y1, z1, x1, y1, z1, x2, y2, z2);
}
point_to_affine(x_affine, y_affine, x1, y1, z1);
@@ -1493,7 +1523,8 @@ CLEANUP:
}
/* Wire in fast point multiplication for named curves. */
-mp_err ec_group_set_gfp256_32(ECGroup *group, ECCurveName name)
+mp_err
+ec_group_set_gfp256_32(ECGroup *group, ECCurveName name)
{
if (name == ECCurve_NIST_P256) {
group->base_point_mul = &ec_GFp_nistp256_base_point_mul;
diff --git a/nss/lib/freebl/ecl/ecp_384.c b/nss/lib/freebl/ecl/ecp_384.c
index 4c1e85e..702fd97 100644
--- a/nss/lib/freebl/ecl/ecp_384.c
+++ b/nss/lib/freebl/ecl/ecp_384.c
@@ -7,226 +7,226 @@
#include "mplogic.h"
#include "mpi-priv.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
+/* 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. */
static 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;
+ 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];
+ /* 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];
- }
+ 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];
- }
+ 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;
+ /* 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);
- }
+ 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;
+ /* 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);
- }
+ 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;
+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.
+ * result in r. r could be a. Uses optimized modular reduction for p384.
*/
static mp_err
ec_GFp_nistp384_sqr(const mp_int *a, mp_int *r, const GFMethod *meth)
{
- mp_err res = MP_OKAY;
+ mp_err res = MP_OKAY;
- MP_CHECKOK(mp_sqr(a, r));
- MP_CHECKOK(ec_GFp_nistp384_mod(r, r, meth));
- CLEANUP:
- return res;
+ 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.
@@ -234,14 +234,14 @@ ec_GFp_nistp384_sqr(const mp_int *a, mp_int *r, const GFMethod *meth)
* optimized modular reduction for p384. */
static mp_err
ec_GFp_nistp384_mul(const mp_int *a, const mp_int *b, mp_int *r,
- const GFMethod *meth)
+ const GFMethod *meth)
{
- mp_err res = MP_OKAY;
+ mp_err res = MP_OKAY;
- MP_CHECKOK(mp_mul(a, b, r));
- MP_CHECKOK(ec_GFp_nistp384_mod(r, r, meth));
- CLEANUP:
- return res;
+ 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
@@ -249,10 +249,10 @@ ec_GFp_nistp384_mul(const mp_int *a, const mp_int *b, mp_int *r,
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;
+ 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/nss/lib/freebl/ecl/ecp_521.c b/nss/lib/freebl/ecl/ecp_521.c
index f70c2f4..6ca0dbb 100644
--- a/nss/lib/freebl/ecl/ecp_521.c
+++ b/nss/lib/freebl/ecl/ecp_521.c
@@ -10,76 +10,76 @@
#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
+ * algorithm 2.31 from Hankerson, Menezes, Vanstone. Guide to
* Elliptic Curve Cryptography. */
static 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);
- unsigned 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;
+ mp_err res = MP_OKAY;
+ int a_bits = mpl_significant_bits(a);
+ unsigned 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.
+ * result in r. r could be a. Uses optimized modular reduction for p521.
*/
static mp_err
ec_GFp_nistp521_sqr(const mp_int *a, mp_int *r, const GFMethod *meth)
{
- mp_err res = MP_OKAY;
+ mp_err res = MP_OKAY;
- MP_CHECKOK(mp_sqr(a, r));
- MP_CHECKOK(ec_GFp_nistp521_mod(r, r, meth));
- CLEANUP:
- return res;
+ 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.
@@ -87,39 +87,39 @@ ec_GFp_nistp521_sqr(const mp_int *a, mp_int *r, const GFMethod *meth)
* optimized modular reduction for p521. */
static mp_err
ec_GFp_nistp521_mul(const mp_int *a, const mp_int *b, mp_int *r,
- const GFMethod *meth)
+ const GFMethod *meth)
{
- mp_err res = MP_OKAY;
+ mp_err res = MP_OKAY;
- MP_CHECKOK(mp_mul(a, b, r));
- MP_CHECKOK(ec_GFp_nistp521_mod(r, r, meth));
- CLEANUP:
- return res;
+ 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. */
static mp_err
ec_GFp_nistp521_div(const mp_int *a, const mp_int *b, mp_int *r,
- const GFMethod *meth)
+ 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;
- }
+ 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
@@ -127,11 +127,11 @@ ec_GFp_nistp521_div(const mp_int *a, const mp_int *b, mp_int *r,
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;
+ 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/nss/lib/freebl/ecl/ecp_aff.c b/nss/lib/freebl/ecl/ecp_aff.c
index 92e8604..47fb273 100644
--- a/nss/lib/freebl/ecl/ecp_aff.c
+++ b/nss/lib/freebl/ecl/ecp_aff.c
@@ -11,107 +11,101 @@ 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;
- }
-
+ 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;
+ mp_zero(px);
+ mp_zero(py);
+ return MP_OKAY;
}
-/* Computes R = P + Q based on IEEE P1363 A.10.1. Elliptic curve points P,
+/* 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)
+ 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_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));
+ 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;
+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
@@ -120,20 +114,20 @@ ec_GFp_pt_add_aff(const mp_int *px, const mp_int *py, const mp_int *qx,
* 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)
+ const mp_int *qy, mp_int *rx, mp_int *ry,
+ const ECGroup *group)
{
- mp_err res = MP_OKAY;
- mp_int nqy;
+ 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;
+ 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
@@ -141,177 +135,174 @@ ec_GFp_pt_sub_aff(const mp_int *px, const mp_int *py, const mp_int *qx,
* 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)
+ mp_int *ry, const ECGroup *group)
{
- return ec_GFp_pt_add_aff(px, py, px, py, rx, ry, 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
+/* 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_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_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));
+ 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));
- }
- }
+ /* 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));
+ /* 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;
+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
+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_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));
+ 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
+ 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;
- }
+ 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;
- }
+ if (group->meth->field_enc) {
+ group->meth->field_enc(px, &pxt, group->meth);
+ group->meth->field_enc(py, &pyt, group->meth);
+ } else {
+ MP_CHECKOK(mp_copy(px, &pxt));
+ MP_CHECKOK(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;
- }
+ 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;
+ res = MP_YES;
CLEANUP:
- mp_clear(&accl);
- mp_clear(&accr);
- mp_clear(&tmp);
- mp_clear(&pxt);
- mp_clear(&pyt);
- return res;
+ mp_clear(&accl);
+ mp_clear(&accr);
+ mp_clear(&tmp);
+ mp_clear(&pxt);
+ mp_clear(&pyt);
+ return res;
}
diff --git a/nss/lib/freebl/ecl/ecp_fp.c b/nss/lib/freebl/ecl/ecp_fp.c
deleted file mode 100644
index 46dc123..0000000
--- a/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/nss/lib/freebl/ecl/ecp_fp.h b/nss/lib/freebl/ecl/ecp_fp.h
deleted file mode 100644
index a5a6769..0000000
--- a/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/nss/lib/freebl/ecl/ecp_fp160.c b/nss/lib/freebl/ecl/ecp_fp160.c
deleted file mode 100644
index f462f3b..0000000
--- a/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/nss/lib/freebl/ecl/ecp_fp192.c b/nss/lib/freebl/ecl/ecp_fp192.c
deleted file mode 100644
index a415bcd..0000000
--- a/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/nss/lib/freebl/ecl/ecp_fp224.c b/nss/lib/freebl/ecl/ecp_fp224.c
deleted file mode 100644
index 71b6a6d..0000000
--- a/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/nss/lib/freebl/ecl/ecp_fpinc.c b/nss/lib/freebl/ecl/ecp_fpinc.c
deleted file mode 100644
index be0f966..0000000
--- a/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/nss/lib/freebl/ecl/ecp_jac.c b/nss/lib/freebl/ecl/ecp_jac.c
index f174b16..535e759 100644
--- a/nss/lib/freebl/ecl/ecp_jac.c
+++ b/nss/lib/freebl/ecl/ecp_jac.c
@@ -15,22 +15,22 @@
* 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_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;
+ 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
@@ -39,41 +39,41 @@ ec_GFp_pt_aff2jac(const mp_int *px, const mp_int *py, mp_int *rx,
* 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_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;
+ 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
@@ -81,7 +81,7 @@ ec_GFp_pt_jac2aff(const mp_int *px, const mp_int *py, const mp_int *pz,
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);
+ return mp_cmp_z(pz);
}
/* Sets P(px, py, pz) to be the point at infinity. Uses Jacobian
@@ -89,8 +89,8 @@ ec_GFp_pt_is_inf_jac(const mp_int *px, const mp_int *py, const mp_int *pz)
mp_err
ec_GFp_pt_set_inf_jac(mp_int *px, mp_int *py, mp_int *pz)
{
- mp_zero(pz);
- return MP_OKAY;
+ mp_zero(pz);
+ return MP_OKAY;
}
/* Computes R = P + Q where R is (rx, ry, rz), P is (px, py, pz) and Q is
@@ -102,191 +102,191 @@ ec_GFp_pt_set_inf_jac(mp_int *px, mp_int *py, mp_int *pz)
* 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)
+ 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));
-
- if (mp_cmp_z(&C) == 0) {
- /* P == Q or P == -Q */
- if (mp_cmp_z(&D) == 0) {
- /* P == Q */
- /* It is cheaper to double (qx, qy, 1) than (px, py, pz). */
- MP_DIGIT(&D, 0) = 1; /* Set D to 1. */
- MP_CHECKOK(ec_GFp_pt_dbl_jac(qx, qy, &D, rx, ry, rz, group));
- } else {
- /* P == -Q */
- MP_CHECKOK(ec_GFp_pt_set_inf_jac(rx, ry, rz));
- }
- goto CLEANUP;
- }
-
- /* 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;
+ 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));
+
+ if (mp_cmp_z(&C) == 0) {
+ /* P == Q or P == -Q */
+ if (mp_cmp_z(&D) == 0) {
+ /* P == Q */
+ /* It is cheaper to double (qx, qy, 1) than (px, py, pz). */
+ MP_DIGIT(&D, 0) = 1; /* Set D to 1. */
+ MP_CHECKOK(ec_GFp_pt_dbl_jac(qx, qy, &D, rx, ry, rz, group));
+ } else {
+ /* P == -Q */
+ MP_CHECKOK(ec_GFp_pt_set_inf_jac(rx, ry, rz));
+ }
+ goto CLEANUP;
+ }
+
+ /* 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
+/* 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
+ * 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
+ * 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_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));
-
- /* P == inf or P == -P */
- if (ec_GFp_pt_is_inf_jac(px, py, pz) == MP_YES || mp_cmp_z(py) == 0) {
- 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;
+ 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));
+
+ /* P == inf or P == -P */
+ if (ec_GFp_pt_is_inf_jac(px, py, pz) == MP_YES || mp_cmp_z(py) == 0) {
+ 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_SIGN(&group->curvea) == MP_NEG &&
+ MP_USED(&group->curvea) == 1 &&
+ MP_DIGIT(&group->curvea, 0) == 3) {
+ /* 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 */
@@ -295,83 +295,81 @@ ec_GFp_pt_dbl_jac(const mp_int *px, const mp_int *py, const mp_int *pz,
* 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
+ * 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_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;
+ 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 +
+/* 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
@@ -380,150 +378,136 @@ ec_GFp_pt_mul_jac(const mp_int *n, const mp_int *px, const mp_int *py,
* 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)
+ 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;
- unsigned 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; i-- > 0;) {
- 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;
+ mp_err res = MP_OKAY;
+ mp_int precomp[4][4][2];
+ mp_int rz;
+ const mp_int *a, *b;
+ unsigned 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; i-- > 0;) {
+ 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/nss/lib/freebl/ecl/ecp_jm.c b/nss/lib/freebl/ecl/ecp_jm.c
index 2d56412..a1106ce 100644
--- a/nss/lib/freebl/ecl/ecp_jm.c
+++ b/nss/lib/freebl/ecl/ecp_jm.c
@@ -9,76 +9,74 @@
#define MAX_SCRATCH 6
-/* Computes R = 2P. Elliptic curve points P and R can be identical. Uses
+/* 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
+ * Assumes input is already field-encoded using field_enc, and returns
* output that is still field-encoded.
*
*/
static 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)
+ 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;
+ mp_err res = MP_OKAY;
+ mp_int *t0, *t1, *M, *S;
- t0 = &scratch[0];
- t1 = &scratch[1];
- M = &scratch[2];
- S = &scratch[3];
+ 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 */
+ /* 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;
- }
+ 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));
+ /* 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));
+ /* 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));
+ /* 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));
+ /* 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));
- /* 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));
- /* 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));
- /* 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;
+CLEANUP:
+ return res;
}
/* Computes R = P + Q where R is (rx, ry, rz), P is (px, py, pz) and Q is
@@ -88,84 +86,82 @@ ec_GFp_pt_dbl_jm(const mp_int *px, const mp_int *py, const mp_int *pz,
* field-encoded. */
static 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)
+ 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;
+ 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];
+ 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));
+ /* 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;
+ return res;
}
/* Computes R = nP where R is (rx, ry) and P is the base point. Elliptic
@@ -174,116 +170,114 @@ CLEANUP:
* 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
+ * 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_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;
+ 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/nss/lib/freebl/ecl/ecp_mont.c b/nss/lib/freebl/ecl/ecp_mont.c
index 6b8462e..779685b 100644
--- a/nss/lib/freebl/ecl/ecp_mont.c
+++ b/nss/lib/freebl/ecl/ecp_mont.c
@@ -18,38 +18,38 @@
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;
+ 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. */
@@ -57,60 +57,59 @@ GFMethod_consGFp_mont(const mp_int *irr)
/* 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)
+ const GFMethod *meth)
{
- mp_err res = MP_OKAY;
+ 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));
+ /* 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);
- }
+ 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;
+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);
+ 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)
+ 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;
+ 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
@@ -118,29 +117,29 @@ ec_GFp_div_mont(const mp_int *a, const mp_int *b, mp_int *r,
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;
+ 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;
+ 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
@@ -148,8 +147,8 @@ ec_GFp_dec_mont(const mp_int *a, mp_int *r, const GFMethod *meth)
void
ec_GFp_extra_free_mont(GFMethod *meth)
{
- if (meth->extra1 != NULL) {
- free(meth->extra1);
- meth->extra1 = NULL;
- }
+ if (meth->extra1 != NULL) {
+ free(meth->extra1);
+ meth->extra1 = NULL;
+ }
}
diff --git a/nss/lib/freebl/ecl/tests/ec2_test.c b/nss/lib/freebl/ecl/tests/ec2_test.c
deleted file mode 100644
index 1b4d8c3..0000000
--- a/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/nss/lib/freebl/ecl/tests/ec_naft.c b/nss/lib/freebl/ecl/tests/ec_naft.c
index 833daea..61ef15c 100644
--- a/nss/lib/freebl/ecl/tests/ec_naft.c
+++ b/nss/lib/freebl/ecl/tests/ec_naft.c
@@ -14,7 +14,7 @@
#include <sys/time.h>
#include <sys/resource.h>
-/* Returns 2^e as an integer. This is meant to be used for small powers of
+/* Returns 2^e as an integer. This is meant to be used for small powers of
* two. */
int ec_twoTo(int e);
@@ -22,96 +22,100 @@ int ec_twoTo(int e);
#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.
+#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;
+ 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/nss/lib/freebl/ecl/tests/ecp_fpt.c b/nss/lib/freebl/ecl/tests/ecp_fpt.c
deleted file mode 100644
index 3c91796..0000000
--- a/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/nss/lib/freebl/ecl/tests/ecp_test.c b/nss/lib/freebl/ecl/tests/ecp_test.c
index e9a448e..dcec4d7 100644
--- a/nss/lib/freebl/ecl/tests/ecp_test.c
+++ b/nss/lib/freebl/ecl/tests/ecp_test.c
@@ -17,336 +17,322 @@
#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); \
-}
+#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");
+#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"); \
- }
+#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)
+ int generic)
{
- mp_int one, order_1, gx, gy, rx, ry, n;
- int size;
- mp_err res;
- char s[1000];
+ 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));
+ /* 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));
+ 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);
- }
- }
+ /* 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;
- }
+ /* 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;
- }
+ /* 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, 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;
- }
+ /* 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;
- }
+ /* 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;
- }
+ /* 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, 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;
- }
+ /* 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;
- }
+ /* 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;
- }
+ /* 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) {
+ 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);
+ 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);
- }
- }
+ 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;
+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");
+ 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
@@ -356,71 +342,68 @@ int
main(int argv, char **argc)
{
- int ectestTime = 0;
- int ectestPrint = 0;
- int i;
- ECGroup *group = NULL;
- ECCurveParams *params = NULL;
- mp_err res;
+ 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;
- }
- }
+ /* 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);
+ /* 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);
+ /* 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);
+ ECTEST_NAMED_GFP("Curve25519", ECCurve25519);
- CLEANUP:
- EC_FreeCurveParams(params);
- ECGroup_free(group);
- if (res != MP_OKAY) {
- printf("Error: exiting with error value %i\n", res);
- }
- return res;
+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/nss/lib/freebl/ecl/uint128.c b/nss/lib/freebl/ecl/uint128.c
new file mode 100644
index 0000000..22cbd02
--- /dev/null
+++ b/nss/lib/freebl/ecl/uint128.c
@@ -0,0 +1,87 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.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 "uint128.h"
+
+/* helper functions */
+uint64_t
+mask51(uint128_t x)
+{
+ return x.lo & MASK51;
+}
+
+uint64_t
+mask_lower(uint128_t x)
+{
+ return x.lo;
+}
+
+uint128_t
+mask51full(uint128_t x)
+{
+ uint128_t ret = { x.lo & MASK51, 0 };
+ return ret;
+}
+
+uint128_t
+init128x(uint64_t x)
+{
+ uint128_t ret = { x, 0 };
+ return ret;
+}
+
+/* arithmetic */
+
+uint128_t
+add128(uint128_t a, uint128_t b)
+{
+ uint128_t ret;
+ ret.lo = a.lo + b.lo;
+ ret.hi = a.hi + b.hi + (ret.lo < b.lo);
+ return ret;
+}
+
+/* out = 19 * a */
+uint128_t
+mul12819(uint128_t a)
+{
+ uint128_t ret = lshift128(a, 4);
+ ret = add128(ret, a);
+ ret = add128(ret, a);
+ ret = add128(ret, a);
+ return ret;
+}
+
+uint128_t
+mul6464(uint64_t a, uint64_t b)
+{
+ uint128_t ret;
+ uint64_t t0 = ((uint64_t)(uint32_t)a) * ((uint64_t)(uint32_t)b);
+ uint64_t t1 = (a >> 32) * ((uint64_t)(uint32_t)b) + (t0 >> 32);
+ uint64_t t2 = (b >> 32) * ((uint64_t)(uint32_t)a) + ((uint32_t)t1);
+ ret.lo = (((uint64_t)((uint32_t)t2)) << 32) + ((uint32_t)t0);
+ ret.hi = (a >> 32) * (b >> 32);
+ ret.hi += (t2 >> 32) + (t1 >> 32);
+ return ret;
+}
+
+/* only defined for n < 64 */
+uint128_t
+rshift128(uint128_t x, uint8_t n)
+{
+ uint128_t ret;
+ ret.lo = (x.lo >> n) + (x.hi << (64 - n));
+ ret.hi = x.hi >> n;
+ return ret;
+}
+
+/* only defined for n < 64 */
+uint128_t
+lshift128(uint128_t x, uint8_t n)
+{
+ uint128_t ret;
+ ret.hi = (x.hi << n) + (x.lo >> (64 - n));
+ ret.lo = x.lo << n;
+ return ret;
+}
diff --git a/nss/lib/freebl/ecl/uint128.h b/nss/lib/freebl/ecl/uint128.h
new file mode 100644
index 0000000..a3a71e6
--- /dev/null
+++ b/nss/lib/freebl/ecl/uint128.h
@@ -0,0 +1,35 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.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 <stdint.h>
+
+#define MASK51 0x7ffffffffffffULL
+
+#ifdef HAVE_INT128_SUPPORT
+typedef unsigned __int128 uint128_t;
+#define add128(a, b) (a) + (b)
+#define mul6464(a, b) (uint128_t)(a) * (uint128_t)(b)
+#define mul12819(a) (uint128_t)(a) * 19
+#define rshift128(x, n) (x) >> (n)
+#define lshift128(x, n) (x) << (n)
+#define mask51(x) (x) & 0x7ffffffffffff
+#define mask_lower(x) (uint64_t)(x)
+#define mask51full(x) (x) & 0x7ffffffffffff
+#define init128x(x) (x)
+#else /* uint128_t for Windows and 32 bit intel systems */
+struct uint128_t_str {
+ uint64_t lo;
+ uint64_t hi;
+};
+typedef struct uint128_t_str uint128_t;
+uint128_t add128(uint128_t a, uint128_t b);
+uint128_t mul6464(uint64_t a, uint64_t b);
+uint128_t mul12819(uint128_t a);
+uint128_t rshift128(uint128_t x, uint8_t n);
+uint128_t lshift128(uint128_t x, uint8_t n);
+uint64_t mask51(uint128_t x);
+uint64_t mask_lower(uint128_t x);
+uint128_t mask51full(uint128_t x);
+uint128_t init128x(uint64_t x);
+#endif
diff --git a/nss/lib/freebl/exports.gyp b/nss/lib/freebl/exports.gyp
new file mode 100644
index 0000000..ef81685
--- /dev/null
+++ b/nss/lib/freebl/exports.gyp
@@ -0,0 +1,48 @@
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+{
+ 'includes': [
+ '../../coreconf/config.gypi'
+ ],
+ 'targets': [
+ {
+ 'target_name': 'lib_freebl_exports',
+ 'type': 'none',
+ 'copies': [
+ {
+ 'files': [
+ 'blapit.h',
+ 'ecl/ecl-exp.h',
+ 'shsign.h'
+ ],
+ 'conditions': [
+ [ 'OS=="linux"', {
+ 'files': [
+ 'nsslowhash.h',
+ ],
+ }],
+ ],
+ 'destination': '<(nss_public_dist_dir)/<(module)'
+ },
+ {
+ 'files': [
+ 'alghmac.h',
+ 'blapi.h',
+ 'chacha20poly1305.h',
+ 'ec.h',
+ 'ecl/ecl-curve.h',
+ 'ecl/ecl.h',
+ 'hmacct.h',
+ 'secmpi.h',
+ 'secrng.h'
+ ],
+ 'destination': '<(nss_private_dist_dir)/<(module)'
+ }
+ ]
+ }
+ ],
+ 'variables': {
+ 'module': 'nss'
+ }
+}
diff --git a/nss/lib/freebl/fipsfreebl.c b/nss/lib/freebl/fipsfreebl.c
new file mode 100644
index 0000000..b3ae686
--- /dev/null
+++ b/nss/lib/freebl/fipsfreebl.c
@@ -0,0 +1,1715 @@
+/*
+ * 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: fipstest.c,v 1.31 2012/06/28 17:55:06 rrelyea%redhat.com Exp $ */
+
+#ifdef FREEBL_NO_DEPEND
+#include "stubs.h"
+#endif
+
+#include "blapi.h"
+#include "seccomon.h" /* Required for RSA and DSA. */
+#include "secerr.h"
+#include "prtypes.h"
+
+#ifdef NSS_ENABLE_ECC
+#include "ec.h" /* Required for ECDSA */
+#endif
+
+/*
+ * different platforms have different ways of calling and initial entry point
+ * when the dll/.so is loaded. Most platforms support either a posix pragma
+ * or the GCC attribute. Some platforms suppor a pre-defined name, and some
+ * platforms have a link line way of invoking this function.
+ */
+
+/* The pragma */
+#if defined(USE_INIT_PRAGMA)
+#pragma init(bl_startup_tests)
+#endif
+
+/* GCC Attribute */
+#if defined(__GNUC__) && !defined(NSS_NO_INIT_SUPPORT)
+#define INIT_FUNCTION __attribute__((constructor))
+#else
+#define INIT_FUNCTION
+#endif
+
+static void INIT_FUNCTION bl_startup_tests(void);
+
+/* Windows pre-defined entry */
+#if defined(XP_WIN) && !defined(NSS_NO_INIT_SUPPORT)
+#include <windows.h>
+
+BOOL WINAPI DllMain(
+ HINSTANCE hinstDLL, // handle to DLL module
+ DWORD fdwReason, // reason for calling function
+ LPVOID lpReserved) // reserved
+{
+ // Perform actions based on the reason for calling.
+ switch (fdwReason) {
+ case DLL_PROCESS_ATTACH:
+ // Initialize once for each new process.
+ // Return FALSE to fail DLL load.
+ bl_startup_tests();
+ break;
+
+ case DLL_THREAD_ATTACH:
+ // Do thread-specific initialization.
+ break;
+
+ case DLL_THREAD_DETACH:
+ // Do thread-specific cleanup.
+ break;
+
+ case DLL_PROCESS_DETACH:
+ // Perform any necessary cleanup.
+ break;
+ }
+ return TRUE; // Successful DLL_PROCESS_ATTACH.
+}
+#endif
+
+/* insert other platform dependent init entry points here, or modify
+ * the linker line */
+
+/* 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 SECStatus
+freebl_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) {
+ PORT_SetError(SEC_ERROR_NO_MEMORY);
+ return (SECFailure);
+ }
+
+ 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)) {
+ PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
+ return (SECFailure);
+ }
+
+ /*******************************************************/
+ /* 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) {
+ PORT_SetError(SEC_ERROR_NO_MEMORY);
+ return (SECFailure);
+ }
+
+ 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)) {
+ PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
+ return (SECFailure);
+ }
+
+ /*******************************************************/
+ /* 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) {
+ PORT_SetError(SEC_ERROR_NO_MEMORY);
+ return (SECFailure);
+ }
+
+ 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)) {
+ PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
+ return (SECFailure);
+ }
+
+ /*******************************************************/
+ /* 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) {
+ PORT_SetError(SEC_ERROR_NO_MEMORY);
+ return (SECFailure);
+ }
+
+ 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)) {
+ PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
+ return (SECFailure);
+ }
+
+ return (SECSuccess);
+}
+
+/* AES self-test for 128-bit, 192-bit, or 256-bit key sizes*/
+static SECStatus
+freebl_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)) {
+ PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
+ return (SECFailure);
+ }
+
+ /******************************************************/
+ /* 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) {
+ PORT_SetError(SEC_ERROR_NO_MEMORY);
+ return (SECFailure);
+ }
+
+ 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)) {
+ PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
+ return (SECFailure);
+ }
+
+ /******************************************************/
+ /* 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) {
+ PORT_SetError(SEC_ERROR_NO_MEMORY);
+ return (SECFailure);
+ }
+
+ 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)) {
+ PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
+ return (SECFailure);
+ }
+
+ /******************************************************/
+ /* 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) {
+ PORT_SetError(SEC_ERROR_NO_MEMORY);
+ return (SECFailure);
+ }
+
+ 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)) {
+ PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
+ return (SECFailure);
+ }
+
+ /******************************************************/
+ /* 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) {
+ PORT_SetError(SEC_ERROR_NO_MEMORY);
+ return (SECFailure);
+ }
+
+ 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)) {
+ PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
+ return (SECFailure);
+ }
+
+ return (SECSuccess);
+}
+
+/* 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."
+};
+
+/****************************************************/
+/* Single Round HMAC SHA-X test */
+/****************************************************/
+static SECStatus
+freebl_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 SECStatus
+freebl_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 = freebl_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)) {
+ PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
+ return (SECFailure);
+ }
+
+ /***************************************************/
+ /* HMAC SHA-224 Single-Round Known Answer Test. */
+ /***************************************************/
+
+ hmac_status = freebl_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)) {
+ PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
+ return (SECFailure);
+ }
+
+ /***************************************************/
+ /* HMAC SHA-256 Single-Round Known Answer Test. */
+ /***************************************************/
+
+ hmac_status = freebl_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)) {
+ PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
+ return (SECFailure);
+ }
+
+ /***************************************************/
+ /* HMAC SHA-384 Single-Round Known Answer Test. */
+ /***************************************************/
+
+ hmac_status = freebl_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)) {
+ PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
+ return (SECFailure);
+ }
+
+ /***************************************************/
+ /* HMAC SHA-512 Single-Round Known Answer Test. */
+ /***************************************************/
+
+ hmac_status = freebl_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)) {
+ PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
+ return (SECFailure);
+ }
+
+ return (SECSuccess);
+}
+
+static SECStatus
+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)) {
+ PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
+ return (SECFailure);
+ }
+
+ /***************************************************/
+ /* 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)) {
+ PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
+ return (SECFailure);
+ }
+
+ /***************************************************/
+ /* 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)) {
+ PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
+ return (SECFailure);
+ }
+
+ /***************************************************/
+ /* 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)) {
+ PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
+ return (SECFailure);
+ }
+
+ /***************************************************/
+ /* 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)) {
+ PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
+ return (SECFailure);
+ }
+
+ return (SECSuccess);
+}
+
+static SECStatus
+freebl_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
+ };
+
+ 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. */
+ SECStatus rsa_status;
+ RSAPublicKey rsa_public_key;
+ RSAPrivateKey rsa_private_key;
+
+ PRUint8 rsa_computed_ciphertext[FIPS_RSA_ENCRYPT_LENGTH];
+ PRUint8 rsa_computed_plaintext[FIPS_RSA_DECRYPT_LENGTH];
+
+ rsa_public_key = bl_public_key;
+ rsa_private_key = bl_private_key;
+
+ /**************************************************/
+ /* RSA Single-Round Known Answer Encryption Test. */
+ /**************************************************/
+
+ /* Perform RSA Public Key Encryption. */
+ rsa_status = RSA_PublicKeyOp(&rsa_public_key,
+ 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,
+ 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;
+
+ return (SECSuccess);
+
+rsa_loser:
+
+ PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
+ return (SECFailure);
+}
+
+#ifdef NSS_ENABLE_ECC
+
+static SECStatus
+freebl_fips_ECDSA_Test(ECParams *ecparams,
+ 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;
+ ECPrivateKey *ecdsa_private_key = NULL;
+ ECPublicKey ecdsa_public_key;
+ SECStatus ecdsaStatus = SECSuccess;
+
+ /* 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));
+ if (ecdsaStatus != SECSuccess) {
+ PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
+ return (SECFailure);
+ }
+
+ /* construct public key from private key. */
+ ecdsa_public_key.ecParams = ecdsa_private_key->ecParams;
+ 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*/
+ PORT_FreeArena(ecdsa_private_key->ecParams.arena, PR_FALSE);
+
+ if (ecdsaStatus != SECSuccess) {
+ PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
+ return (SECFailure);
+ }
+ return (SECSuccess);
+}
+
+static SECStatus
+freebl_fips_ECDSA_PowerUpSelfTest()
+{
+
+ /* ECDSA Known curve nistp256 == ECCCurve_X9_62_PRIME_256V1 params */
+ static const unsigned char p256_prime[] = {
+ 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF
+ };
+ static const unsigned char p256_a[] = {
+ 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC
+ };
+ static const unsigned char p256_b[] = {
+ 0x5A, 0xC6, 0x35, 0xD8, 0xAA, 0x3A, 0x93, 0xE7, 0xB3, 0xEB, 0xBD, 0x55, 0x76,
+ 0x98, 0x86, 0xBC, 0x65, 0x1D, 0x06, 0xB0, 0xCC, 0x53, 0xB0, 0xF6, 0x3B, 0xCE,
+ 0x3C, 0x3E, 0x27, 0xD2, 0x60, 0x4B
+ };
+ static const unsigned char p256_base[] = {
+ 0x04,
+ 0x6B, 0x17, 0xD1, 0xF2, 0xE1, 0x2C, 0x42, 0x47, 0xF8, 0xBC, 0xE6, 0xE5, 0x63,
+ 0xA4, 0x40, 0xF2, 0x77, 0x03, 0x7D, 0x81, 0x2D, 0xEB, 0x33, 0xA0, 0xF4, 0xA1,
+ 0x39, 0x45, 0xD8, 0x98, 0xC2, 0x96,
+ 0x4F, 0xE3, 0x42, 0xE2, 0xFE, 0x1A, 0x7F, 0x9B, 0x8E, 0xE7, 0xEB, 0x4A, 0x7C,
+ 0x0F, 0x9E, 0x16, 0x2B, 0xCE, 0x33, 0x57, 0x6B, 0x31, 0x5E, 0xCE, 0xCB, 0xB6,
+ 0x40, 0x68, 0x37, 0xBF, 0x51, 0xF5
+ };
+ static const unsigned char p256_order[] = {
+ 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xBC, 0xE6, 0xFA, 0xAD, 0xA7, 0x17, 0x9E, 0x84, 0xF3, 0xB9,
+ 0xCA, 0xC2, 0xFC, 0x63, 0x25, 0x51
+ };
+ static const unsigned char p256_encoding[] = {
+ 0x06, 0x08, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x03, 0x01, 0x07
+ };
+ static const ECParams ecdsa_known_P256_Params = {
+ NULL, ec_params_named, /* arena, type */
+ /* fieldID */
+ { 256, ec_field_GFp, /* size and type */
+ { { siBuffer, (unsigned char *)p256_prime, sizeof(p256_prime) } }, /* u.prime */
+ 0,
+ 0,
+ 0 },
+ /* curve */
+ { /* a = curvea b = curveb */
+ /* curve.a */
+ { siBuffer, (unsigned char *)p256_a, sizeof(p256_a) },
+ /* curve.b */
+ { siBuffer, (unsigned char *)p256_b, sizeof(p256_b) },
+ /* curve.seed */
+ { siBuffer, NULL, 0 } },
+ /* base = 04xy*/
+ { siBuffer, (unsigned char *)p256_base, sizeof(p256_base) },
+ /* order */
+ { siBuffer, (unsigned char *)p256_order, sizeof(p256_order) },
+ 1, /* cofactor */
+ /* DEREncoding */
+ { siBuffer, (unsigned char *)p256_encoding, sizeof(p256_encoding) },
+ ECCurve_X9_62_PRIME_256V1,
+ /* curveOID */
+ { siBuffer, (unsigned char *)(p256_encoding) + 2, sizeof(p256_encoding) - 2 },
+ };
+
+ 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
+ };
+
+ ECParams ecparams;
+
+ SECStatus rv;
+
+ /* ECDSA GF(p) prime field curve test */
+ ecparams = ecdsa_known_P256_Params;
+ rv = freebl_fips_ECDSA_Test(&ecparams,
+ ecdsa_known_P256_signature,
+ sizeof ecdsa_known_P256_signature);
+ if (rv != SECSuccess) {
+ return (SECFailure);
+ }
+
+ return (SECSuccess);
+}
+
+#endif /* NSS_ENABLE_ECC */
+
+static SECStatus
+freebl_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) {
+ PORT_SetError(SEC_ERROR_NO_MEMORY);
+ return (SECFailure);
+ }
+
+ /* 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) {
+ PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
+ return SECFailure;
+ }
+
+ return (SECSuccess);
+}
+
+static SECStatus
+freebl_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) {
+ PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
+ return SECFailure;
+ }
+
+ /*******************************************/
+ /* 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)) {
+ PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
+ return SECFailure;
+ }
+
+ return (SECSuccess);
+}
+
+static SECStatus
+freebl_fipsSoftwareIntegrityTest(const char *libname)
+{
+ SECStatus rv = SECSuccess;
+
+ /* make sure that our check file signatures are OK */
+ if (!BLAPI_VerifySelf(libname)) {
+ rv = SECFailure;
+ }
+ return rv;
+}
+
+#define DO_FREEBL 1
+#define DO_REST 2
+
+static SECStatus
+freebl_fipsPowerUpSelfTest(unsigned int tests)
+{
+ SECStatus rv;
+
+ /*
+ * stand alone freebl. Test hash, and rng
+ */
+ if (tests & DO_FREEBL) {
+
+ /* SHA-X Power-Up SelfTest(s). */
+ rv = freebl_fips_SHA_PowerUpSelfTest();
+
+ if (rv != SECSuccess)
+ return rv;
+
+ /* RNG Power-Up SelfTest(s). */
+ rv = freebl_fips_RNG_PowerUpSelfTest();
+
+ if (rv != SECSuccess)
+ return rv;
+ }
+
+ /*
+ * test the rest of the algorithms not accessed through freebl
+ * standalone */
+ if (tests & DO_REST) {
+
+ /* DES3 Power-Up SelfTest(s). */
+ rv = freebl_fips_DES3_PowerUpSelfTest();
+
+ if (rv != SECSuccess)
+ return rv;
+
+ /* AES Power-Up SelfTest(s) for 128-bit key. */
+ rv = freebl_fips_AES_PowerUpSelfTest(FIPS_AES_128_KEY_SIZE);
+
+ if (rv != SECSuccess)
+ return rv;
+
+ /* AES Power-Up SelfTest(s) for 192-bit key. */
+ rv = freebl_fips_AES_PowerUpSelfTest(FIPS_AES_192_KEY_SIZE);
+
+ if (rv != SECSuccess)
+ return rv;
+
+ /* AES Power-Up SelfTest(s) for 256-bit key. */
+ rv = freebl_fips_AES_PowerUpSelfTest(FIPS_AES_256_KEY_SIZE);
+
+ if (rv != SECSuccess)
+ return rv;
+
+ /* HMAC SHA-X Power-Up SelfTest(s). */
+ rv = freebl_fips_HMAC_PowerUpSelfTest();
+
+ if (rv != SECSuccess)
+ return rv;
+
+ /* NOTE: RSA can only be tested in full freebl. It requires access to
+ * the locking primitives */
+ /* RSA Power-Up SelfTest(s). */
+ rv = freebl_fips_RSA_PowerUpSelfTest();
+
+ if (rv != SECSuccess)
+ return rv;
+
+ /* DSA Power-Up SelfTest(s). */
+ rv = freebl_fips_DSA_PowerUpSelfTest();
+
+ if (rv != SECSuccess)
+ return rv;
+
+#ifdef NSS_ENABLE_ECC
+ /* ECDSA Power-Up SelfTest(s). */
+ rv = freebl_fips_ECDSA_PowerUpSelfTest();
+
+ if (rv != SECSuccess)
+ return rv;
+#endif
+ }
+ /* Passed Power-Up SelfTest(s). */
+ return (SECSuccess);
+}
+
+/*
+ * state variables. NOTE: freebl has two uses: a standalone use which
+ * provided limitted access to the hash functions throught the NSSLOWHASH_
+ * interface and an joint use from softoken, using the function pointer
+ * table. The standalone use can operation without nspr or nss-util, while
+ * the joint use requires both to be loaded. Certain functions (like RSA)
+ * needs locking from NSPR, for instance.
+ *
+ * At load time, we need to handle the two uses separately. If nspr and
+ * nss-util are loaded, then we can run all the selftests, but if nspr and
+ * nss-util are not loaded, then we can't run all the selftests, and we need
+ * to prevent the softoken function pointer table from operating until the
+ * libraries are loaded and we try to use them.
+ */
+static PRBool self_tests_freebl_ran = PR_FALSE;
+static PRBool self_tests_ran = PR_FALSE;
+static PRBool self_tests_freebl_success = PR_FALSE;
+static PRBool self_tests_success = PR_FALSE;
+#if defined(DEBUG)
+static PRBool fips_mode_available = PR_FALSE;
+#endif
+
+/*
+ * accessors for freebl
+ */
+PRBool
+BL_POSTRan(PRBool freebl_only)
+{
+ SECStatus rv;
+ /* if the freebl self tests didn't run, there is something wrong with
+ * our on load tests */
+ if (!self_tests_freebl_ran) {
+ return PR_FALSE;
+ }
+ /* if all the self tests have run, we are good */
+ if (self_tests_ran) {
+ return PR_TRUE;
+ }
+ /* if we only care about the freebl tests, we are good */
+ if (freebl_only) {
+ return PR_TRUE;
+ }
+ /* run the rest of the self tests */
+ /* We could get there if freebl was loaded without the rest of the support
+ * libraries, but now we want to use more than just a standalone freebl.
+ * This requires the other libraries to be loaded.
+ * If they are now loaded, Try to run the rest of the selftests,
+ * otherwise fail (disabling access to these algorithms) */
+ self_tests_ran = PR_TRUE;
+ BL_Init(); /* required by RSA */
+ RNG_RNGInit(); /* required by RSA */
+ rv = freebl_fipsPowerUpSelfTest(DO_REST);
+ if (rv == SECSuccess) {
+ self_tests_success = PR_TRUE;
+ }
+ return PR_TRUE;
+}
+
+#include "blname.c"
+
+/*
+ * This function is called at dll load time, the code tha makes this
+ * happen is platform specific on defined above.
+ */
+static void
+bl_startup_tests(void)
+{
+ const char *libraryName;
+ PRBool freebl_only = PR_FALSE;
+ SECStatus rv;
+
+ PORT_Assert(self_tests_freebl_ran == PR_FALSE);
+ PORT_Assert(self_tests_success == PR_FALSE);
+ PORT_Assert(fips_mode_available == PR_FALSE);
+ self_tests_freebl_ran = PR_TRUE; /* we are running the tests */
+ self_tests_success = PR_FALSE; /* force it just in case */
+ self_tests_freebl_success = PR_FALSE; /* force it just in case */
+
+#ifdef FREEBL_NO_DEPEND
+ rv = FREEBL_InitStubs();
+ if (rv != SECSuccess) {
+ freebl_only = PR_TRUE;
+ }
+#endif
+
+ self_tests_freebl_ran = PR_TRUE; /* we are running the tests */
+
+ if (!freebl_only) {
+ self_tests_ran = PR_TRUE; /* we're running all the tests */
+ BL_Init(); /* needs to be called before RSA can be used */
+ RNG_RNGInit();
+ }
+
+ /* always run the post tests */
+ rv = freebl_fipsPowerUpSelfTest(freebl_only ? DO_FREEBL : DO_FREEBL | DO_REST);
+ if (rv != SECSuccess) {
+ return;
+ }
+
+ libraryName = getLibName();
+ rv = freebl_fipsSoftwareIntegrityTest(libraryName);
+ if (rv != SECSuccess) {
+ return;
+ }
+
+ /* posts are happy, allow the fips module to function now */
+ self_tests_freebl_success = PR_TRUE; /* we always test the freebl stuff */
+ if (!freebl_only) {
+ self_tests_success = PR_TRUE;
+ }
+}
+
+/*
+ * this is called from the freebl init entry points that controll access to
+ * all other freebl functions. This prevents freebl from operating if our
+ * power on selftest failed.
+ */
+SECStatus
+BL_FIPSEntryOK(PRBool freebl_only)
+{
+#ifdef NSS_NO_INIT_SUPPORT
+ /* this should only be set on platforms that can't handle one of the INIT
+ * schemes. This code allows those platforms to continue to function,
+ * though they don't meet the strict NIST requirements. If NSS_NO_INIT_SUPPORT
+ * is not set, and init support has not been properly enabled, freebl
+ * will always fail because of the test below
+ */
+ if (!self_tests_freebl_ran) {
+ bl_startup_tests();
+ }
+#endif
+ /* if the general self tests succeeded, we're done */
+ if (self_tests_success) {
+ return SECSuccess;
+ }
+ /* standalone freebl can initialize */
+ if (freebl_only & self_tests_freebl_success) {
+ return SECSuccess;
+ }
+ PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
+ return SECFailure;
+}
diff --git a/nss/lib/freebl/freebl.gyp b/nss/lib/freebl/freebl.gyp
new file mode 100644
index 0000000..f5ae232
--- /dev/null
+++ b/nss/lib/freebl/freebl.gyp
@@ -0,0 +1,408 @@
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+{
+ 'includes': [
+ '../../coreconf/config.gypi'
+ ],
+ 'targets': [
+ {
+ 'target_name': 'intel-gcm-wrap_c_lib',
+ 'type': 'static_library',
+ 'sources': [
+ 'intel-gcm-wrap.c'
+ ],
+ 'dependencies': [
+ '<(DEPTH)/exports.gyp:nss_exports'
+ ],
+ 'cflags': [
+ '-mssse3'
+ ],
+ 'cflags_mozilla': [
+ '-mssse3'
+ ]
+ },
+ {
+ 'target_name': 'freebl',
+ 'type': 'static_library',
+ 'sources': [
+ 'loader.c'
+ ],
+ 'dependencies': [
+ '<(DEPTH)/exports.gyp:nss_exports'
+ ]
+ },
+ {
+ 'target_name': '<(freebl_name)',
+ 'type': 'shared_library',
+ 'sources': [
+ 'aeskeywrap.c',
+ 'alg2268.c',
+ 'alghmac.c',
+ 'arcfive.c',
+ 'arcfour.c',
+ 'camellia.c',
+ 'chacha20poly1305.c',
+ 'ctr.c',
+ 'cts.c',
+ 'des.c',
+ 'desblapi.c',
+ 'dh.c',
+ 'drbg.c',
+ 'dsa.c',
+ 'ec.c',
+ 'ecdecode.c',
+ 'ecl/ec_naf.c',
+ 'ecl/ecl.c',
+ 'ecl/ecl_curve.c',
+ 'ecl/ecl_gf.c',
+ 'ecl/ecl_mult.c',
+ 'ecl/ecp_25519.c',
+ 'ecl/ecp_256.c',
+ 'ecl/ecp_256_32.c',
+ 'ecl/ecp_384.c',
+ 'ecl/ecp_521.c',
+ 'ecl/ecp_aff.c',
+ 'ecl/ecp_jac.c',
+ 'ecl/ecp_jm.c',
+ 'ecl/ecp_mont.c',
+ 'fipsfreebl.c',
+ 'freeblver.c',
+ 'gcm.c',
+ 'hmacct.c',
+ 'jpake.c',
+ 'ldvector.c',
+ 'md2.c',
+ 'md5.c',
+ 'mpi/mp_gf2m.c',
+ 'mpi/mpcpucache.c',
+ 'mpi/mpi.c',
+ 'mpi/mplogic.c',
+ 'mpi/mpmontg.c',
+ 'mpi/mpprime.c',
+ 'pqg.c',
+ 'rawhash.c',
+ 'rijndael.c',
+ 'rsa.c',
+ 'rsapkcs.c',
+ 'seed.c',
+ 'sha512.c',
+ 'sha_fast.c',
+ 'shvfy.c',
+ 'sysrand.c',
+ 'tlsprfalg.c'
+ ],
+ 'conditions': [
+ [ 'OS=="linux"', {
+ 'sources': [
+ 'nsslowhash.c',
+ 'stubs.c',
+ ],
+ 'conditions': [
+ [ 'test_build==1', {
+ 'dependencies': [
+ '<(DEPTH)/lib/util/util.gyp:nssutil3',
+ ],
+ }],
+ [ 'target_arch=="x64"', {
+ 'sources': [
+ 'arcfour-amd64-gas.s',
+ 'intel-aes.s',
+ 'intel-gcm.s',
+ 'mpi/mpi_amd64.c',
+ 'mpi/mpi_amd64_gas.s',
+ 'mpi/mp_comba.c',
+ ],
+ 'dependencies': [
+ 'intel-gcm-wrap_c_lib',
+ ],
+ 'conditions': [
+ [ 'cc_is_clang==1', {
+ 'cflags': [
+ '-no-integrated-as',
+ ],
+ 'cflags_mozilla': [
+ '-no-integrated-as',
+ ],
+ 'asflags_mozilla': [
+ '-no-integrated-as',
+ ],
+ }],
+ ],
+ }],
+ [ 'target_arch=="ia32"', {
+ 'sources': [
+ 'mpi/mpi_x86.s',
+ ],
+ }],
+ [ 'target_arch=="arm"', {
+ 'sources': [
+ 'mpi/mpi_arm.c',
+ ],
+ }],
+ ],
+ }, {
+ # not Linux
+ 'conditions': [
+ [ 'moz_fold_libs==0', {
+ 'dependencies': [
+ '../util/util.gyp:nssutil3',
+ ],
+ }, {
+ 'libraries': [
+ '<(moz_folded_library_name)',
+ ],
+ }],
+ ],
+ }],
+ [ 'OS=="win"', {
+ 'sources': [
+ #TODO: building with mingw should not need this.
+ 'ecl/uint128.c',
+ #TODO: clang-cl needs -msse3 here
+ 'intel-gcm-wrap.c',
+ ],
+ 'libraries': [
+ 'advapi32.lib',
+ ],
+ 'conditions': [
+ [ 'target_arch=="x64"', {
+ 'sources': [
+ 'arcfour-amd64-masm.asm',
+ 'mpi/mpi_amd64.c',
+ 'mpi/mpi_amd64_masm.asm',
+ 'mpi/mp_comba_amd64_masm.asm',
+ 'intel-aes-x64-masm.asm',
+ 'intel-gcm-x64-masm.asm',
+ ],
+ }, {
+ # not x64
+ 'sources': [
+ 'mpi/mpi_x86_asm.c',
+ 'intel-aes-x86-masm.asm',
+ 'intel-gcm-x86-masm.asm',
+ ],
+ }],
+ ],
+ }],
+ ['target_arch=="ia32" or target_arch=="x64"', {
+ 'sources': [
+ # All intel architectures get the 64 bit version
+ 'ecl/curve25519_64.c',
+ ],
+ }, {
+ 'sources': [
+ # All non intel architectures get the generic 32 bit implementation (slow!)
+ 'ecl/curve25519_32.c',
+ ],
+ }],
+ #TODO uint128.c
+ [ 'disable_chachapoly==0', {
+ 'conditions': [
+ [ 'OS!="win" and target_arch=="x64"', {
+ 'sources': [
+ 'chacha20_vec.c',
+ 'poly1305-donna-x64-sse2-incremental-source.c',
+ ],
+ }, {
+ # not x64
+ 'sources': [
+ 'chacha20.c',
+ 'poly1305.c',
+ ],
+ }],
+ ],
+ }],
+ [ 'fuzz==1', {
+ 'sources': [
+ 'det_rng.c',
+ ],
+ 'defines': [
+ 'UNSAFE_FUZZER_MODE',
+ ],
+ }],
+ [ 'test_build==1', {
+ 'defines': [
+ 'CT_VERIF',
+ ],
+ }],
+ [ 'OS=="mac"', {
+ 'conditions': [
+ [ 'target_arch=="ia32"', {
+ 'sources': [
+ 'mpi/mpi_sse2.s',
+ ],
+ 'defines': [
+ 'MP_USE_UINT_DIGIT',
+ 'MP_ASSEMBLY_MULTIPLY',
+ 'MP_ASSEMBLY_SQUARE',
+ 'MP_ASSEMBLY_DIV_2DX1D',
+ ],
+ }],
+ ],
+ }],
+ ],
+ 'dependencies': [
+ '<(DEPTH)/exports.gyp:nss_exports',
+ ],
+ 'variables': {
+ 'conditions': [
+ [ 'OS=="linux"', {
+ 'mapfile': 'freebl_hash_vector.def',
+ }, {
+ 'mapfile': 'freebl.def',
+ }],
+ ]
+ },
+ 'ldflags': [
+ '-Wl,-Bsymbolic'
+ ]
+ },
+ ],
+ 'conditions': [
+ [ 'OS=="linux"', {
+ # stub build
+ 'targets': [
+ {
+ 'target_name': 'freebl3',
+ 'type': 'shared_library',
+ 'defines': [
+ 'FREEBL_NO_DEPEND',
+ ],
+ 'sources': [
+ 'lowhash_vector.c'
+ ],
+ 'dependencies': [
+ '<(DEPTH)/exports.gyp:nss_exports'
+ ],
+ 'variables': {
+ 'mapfile': 'freebl_hash.def'
+ }
+ },
+ ],
+ }],
+ ],
+ 'target_defaults': {
+ 'include_dirs': [
+ 'mpi',
+ 'ecl'
+ ],
+ 'defines': [
+ 'SHLIB_SUFFIX=\"<(dll_suffix)\"',
+ 'SHLIB_PREFIX=\"<(dll_prefix)\"',
+ 'SHLIB_VERSION=\"3\"',
+ 'SOFTOKEN_SHLIB_VERSION=\"3\"',
+ 'RIJNDAEL_INCLUDE_TABLES',
+ 'MP_API_COMPATIBLE'
+ ],
+ 'conditions': [
+ [ 'OS=="win" and target_arch=="ia32"', {
+ 'msvs_settings': {
+ 'VCCLCompilerTool': {
+ #TODO: -Ox optimize flags
+ 'PreprocessorDefinitions': [
+ 'NSS_X86_OR_X64',
+ 'NSS_X86',
+ 'MP_ASSEMBLY_MULTIPLY',
+ 'MP_ASSEMBLY_SQUARE',
+ 'MP_ASSEMBLY_DIV_2DX1D',
+ 'MP_USE_UINT_DIGIT',
+ 'MP_NO_MP_WORD',
+ 'USE_HW_AES',
+ 'INTEL_GCM',
+ ],
+ },
+ },
+ }],
+ [ 'OS=="win" and target_arch=="x64"', {
+ 'msvs_settings': {
+ 'VCCLCompilerTool': {
+ #TODO: -Ox optimize flags
+ 'PreprocessorDefinitions': [
+ 'NSS_USE_64',
+ 'NSS_X86_OR_X64',
+ 'NSS_X64',
+ 'MP_IS_LITTLE_ENDIAN',
+ 'NSS_BEVAND_ARCFOUR',
+ 'MPI_AMD64',
+ 'MP_ASSEMBLY_MULTIPLY',
+ 'NSS_USE_COMBA',
+ 'USE_HW_AES',
+ 'INTEL_GCM',
+ ],
+ },
+ },
+ }],
+ [ 'OS!="win"', {
+ 'conditions': [
+ [ 'target_arch=="x64"', {
+ 'defines': [
+ 'NSS_USE_64',
+ 'NSS_X86_OR_X64',
+ 'NSS_X64',
+ # The Makefile does version-tests on GCC, but we're not doing that here.
+ 'HAVE_INT128_SUPPORT',
+ ],
+ }, {
+ 'sources': [
+ 'ecl/uint128.c',
+ ],
+ }],
+ [ 'target_arch=="ia32"', {
+ 'defines': [
+ 'NSS_X86_OR_X64',
+ 'NSS_X86',
+ ],
+ }],
+ ],
+ }],
+ [ 'OS=="linux"', {
+ 'defines': [
+ 'FREEBL_LOWHASH',
+ ],
+ 'conditions': [
+ [ 'test_build==0', {
+ 'defines': [
+ 'FREEBL_NO_DEPEND',
+ ],
+ }],
+ [ 'target_arch=="x64"', {
+ 'defines': [
+ 'MP_IS_LITTLE_ENDIAN',
+ 'NSS_BEVAND_ARCFOUR',
+ 'MPI_AMD64',
+ 'MP_ASSEMBLY_MULTIPLY',
+ 'NSS_USE_COMBA',
+ ],
+ }],
+ [ 'target_arch=="x64" and use_msan==0', {
+ 'defines': [
+ 'USE_HW_AES',
+ 'INTEL_GCM',
+ ],
+ }],
+ [ 'target_arch=="ia32"', {
+ 'defines': [
+ 'MP_IS_LITTLE_ENDIAN',
+ 'MP_ASSEMBLY_MULTIPLY',
+ 'MP_ASSEMBLY_SQUARE',
+ 'MP_ASSEMBLY_DIV_2DX1D',
+ 'MP_USE_UINT_DIGIT',
+ ],
+ }],
+ [ 'target_arch=="arm"', {
+ 'defines': [
+ 'MP_ASSEMBLY_MULTIPLY',
+ 'MP_ASSEMBLY_SQUARE',
+ 'MP_USE_UINT_DIGIT',
+ 'SHA_NO_LONG_LONG',
+ ],
+ }],
+ ],
+ }],
+ ],
+ },
+ 'variables': {
+ 'module': 'nss',
+ }
+}
diff --git a/nss/lib/freebl/freebl_hash_vector.def b/nss/lib/freebl/freebl_hash_vector.def
new file mode 100644
index 0000000..9d7d07d
--- /dev/null
+++ b/nss/lib/freebl/freebl_hash_vector.def
@@ -0,0 +1,34 @@
+;+#
+;+# This Source Code Form is subject to the terms of the Mozilla Public
+;+# License, v. 2.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:
+;+ *;
+;+};
+;+NSSprivate_3.16 { # NSS 3.11 release
+;+ global:
+LIBRARY freebl3 ;-
+EXPORTS ;-
+NSSLOW_GetVector;
+;+ local:
+;+ *;
+;+};
diff --git a/nss/lib/freebl/gcm.c b/nss/lib/freebl/gcm.c
index c8ba738..2212100 100644
--- a/nss/lib/freebl/gcm.c
+++ b/nss/lib/freebl/gcm.c
@@ -23,19 +23,19 @@
typedef struct gcmHashContextStr gcmHashContext;
static SECStatus gcmHash_InitContext(gcmHashContext *hash,
- const unsigned char *H,
- unsigned int blocksize);
+ 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);
+ 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);
+ 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);
+ 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.
@@ -45,9 +45,9 @@ static SECStatus gcmHash_Reset(gcmHashContext *ghash,
* "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 */
+#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
@@ -88,23 +88,29 @@ static const unsigned char gcm_byte_rev[256] = {
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"); }
+#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)
+#define GCM_TRACE_X(ghash, label)
+#define GCM_TRACE_BLOCK(label, buf, blocksize)
#endif
#ifdef GCM_USE_MPI
@@ -120,15 +126,15 @@ static const unsigned char gcm_byte_rev[256] = {
/* 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;
+ 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 */
@@ -137,18 +143,18 @@ 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 blocksize)
{
unsigned int i;
- for (i=0; i < blocksize; i++) {
- target[blocksize-i-1] = gcm_byte_rev[src[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)
+ unsigned int blocksize)
{
mp_err err = MP_OKAY;
unsigned char H_rev[MAX_BLOCK_SIZE];
@@ -156,23 +162,23 @@ gcmHash_InitContext(gcmHashContext *ghash, const unsigned char *H,
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) );
+ 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) );
+ 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;
+ case 16: /* 128 bits */
+ ghash->poly = poly_128;
+ break;
+ default:
+ PORT_SetError(SEC_ERROR_INVALID_ARGS);
+ goto cleanup;
}
ghash->cLen = 0;
ghash->bufLen = 0;
@@ -192,11 +198,9 @@ 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;
+ PORT_Memset(ghash, 0, sizeof(gcmHashContext));
if (freeit) {
- PORT_Free(ghash);
+ PORT_Free(ghash);
}
}
@@ -210,25 +214,25 @@ gcm_getX(gcmHashContext *ghash, unsigned char *T, unsigned int blocksize)
len = mp_unsigned_octet_size(&ghash->X);
if (len <= 0) {
- PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
- return SECFailure;
+ 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;
+ PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
+ return SECFailure;
}
/* zero pad the result */
if (len != blocksize) {
- PORT_Memset(X,0,blocksize-len);
- X += blocksize-len;
+ 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;
+ PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
+ return SECFailure;
}
gcm_reverse(T, tmp_buf, blocksize);
return SECSuccess;
@@ -236,39 +240,40 @@ gcm_getX(gcmHashContext *ghash, unsigned char *T, unsigned int blocksize)
static SECStatus
gcm_HashMult(gcmHashContext *ghash, const unsigned char *buf,
- unsigned int count, unsigned int blocksize)
+ 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
- */
+ 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 = ")
+ ghash->poly, &ghash->X));
+ GCM_TRACE_X(ghash, "X%d = ")
}
rv = SECSuccess;
cleanup:
+ PORT_Memset(tmp_buf, 0, sizeof(tmp_buf));
if (rv != SECSuccess) {
- MP_TO_SEC_ERROR(err);
+ MP_TO_SEC_ERROR(err);
}
return rv;
}
@@ -285,58 +290,57 @@ gcm_zeroX(gcmHashContext *ghash)
#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))
+#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;
+ 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);
+ 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;
+ 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);
+ 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);
- }
+ 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)
+ unsigned int blocksize)
{
PORT_Memset(ghash->X, 0, sizeof(ghash->X));
PORT_Memset(ghash->H, 0, sizeof(ghash->H));
@@ -345,12 +349,12 @@ gcmHash_InitContext(gcmHashContext *ghash, const unsigned char *H,
/* 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;
+ 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;
@@ -366,8 +370,9 @@ cleanup:
static void
gcmHash_DestroyContext(gcmHashContext *ghash, PRBool freeit)
{
+ PORT_Memset(ghash, 0, sizeof(gcmHashContext));
if (freeit) {
- PORT_Free(ghash);
+ PORT_Free(ghash);
}
}
@@ -377,10 +382,10 @@ 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;
+ 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;
}
@@ -392,41 +397,42 @@ gcm_getX(gcmHashContext *ghash, unsigned char *T, unsigned int blocksize)
return SECSuccess;
}
-#define GCM_XOR(t, s, len) \
- for (l=0; l < len; l++) t[l] ^= s[l]
+#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 int count, unsigned int blocksize)
{
unsigned long C_i[GCM_ARRAY_SIZE];
- unsigned int arraysize = blocksize/sizeof(unsigned long);
+ 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 = ")
- }
+ 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 = ")
+ }
+ PORT_Memset(C_i, 0, sizeof(C_i));
return SECSuccess;
}
-
static void
gcm_zeroX(gcmHashContext *ghash)
{
@@ -442,51 +448,51 @@ gcm_zeroX(gcmHashContext *ghash)
*/
static SECStatus
gcmHash_Update(gcmHashContext *ghash, const unsigned char *buf,
- unsigned int len, unsigned int blocksize)
+ unsigned int len, unsigned int blocksize)
{
unsigned int blocks;
SECStatus rv;
- ghash->cLen += (len*PR_BITS_PER_BYTE);
+ 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);
- if (needed != 0) {
- 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;
- }
+ unsigned int needed = PR_MIN(len, blocksize - ghash->bufLen);
+ if (needed != 0) {
+ 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;
+ blocks = len / blocksize;
if (blocks) {
- rv = gcm_HashMult(ghash, buf, blocks, blocksize);
- if (rv != SECSuccess) {
- return SECFailure;
- }
- buf += blocks*blocksize;
- len -= blocks*blocksize;
+ 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;
+ PORT_Memcpy(ghash->buffer, buf, len);
+ ghash->bufLen = len;
}
return SECSuccess;
}
@@ -503,23 +509,23 @@ gcmHash_Sync(gcmHashContext *ghash, unsigned int blocksize)
/* copy the previous counter to the upper block */
PORT_Memcpy(ghash->counterBuf, &ghash->counterBuf[GCM_HASH_LEN_LEN],
- 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;
+ 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;
- }
+ 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;
}
@@ -530,57 +536,62 @@ gcmHash_Sync(gcmHashContext *ghash, unsigned int blocksize)
*/
static SECStatus
gcmHash_Final(gcmHashContext *ghash, unsigned char *outbuf,
- unsigned int *outlen, unsigned int maxout,
- unsigned int blocksize)
+ 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;
+ goto cleanup;
}
- rv = gcm_HashMult(ghash, ghash->counterBuf, (GCM_HASH_LEN_LEN*2)/blocksize,
- blocksize);
+ rv = gcm_HashMult(ghash, ghash->counterBuf, (GCM_HASH_LEN_LEN * 2) / blocksize,
+ blocksize);
if (rv != SECSuccess) {
- return SECFailure;
+ goto cleanup;
}
GCM_TRACE_X(ghash, "GHASH(H,A,C) = ")
rv = gcm_getX(ghash, T, blocksize);
if (rv != SECSuccess) {
- return SECFailure;
+ goto cleanup;
}
- if (maxout > blocksize) maxout = blocksize;
+ if (maxout > blocksize)
+ maxout = blocksize;
PORT_Memcpy(outbuf, T, maxout);
*outlen = maxout;
- return SECSuccess;
+ rv = SECSuccess;
+
+cleanup:
+ PORT_Memset(T, 0, sizeof(T));
+ return rv;
}
SECStatus
gcmHash_Reset(gcmHashContext *ghash, const unsigned char *AAD,
- unsigned int AADLen, unsigned int blocksize)
+ unsigned int AADLen, unsigned int blocksize)
{
SECStatus rv;
ghash->cLen = 0;
- PORT_Memset(ghash->counterBuf, 0, GCM_HASH_LEN_LEN*2);
+ 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;
- }
+ rv = gcmHash_Update(ghash, AAD, AADLen, blocksize);
+ if (rv != SECSuccess) {
+ return SECFailure;
+ }
+ rv = gcmHash_Sync(ghash, blocksize);
+ if (rv != SECSuccess) {
+ return SECFailure;
+ }
}
return SECSuccess;
}
@@ -599,7 +610,7 @@ struct GCMContextStr {
GCMContext *
GCM_CreateContext(void *context, freeblCipherFunc cipher,
- const unsigned char *params, unsigned int blocksize)
+ const unsigned char *params, unsigned int blocksize)
{
GCMContext *gcm = NULL;
gcmHashContext *ghash;
@@ -612,23 +623,23 @@ GCM_CreateContext(void *context, freeblCipherFunc cipher,
SECStatus rv;
if (blocksize > MAX_BLOCK_SIZE || blocksize > sizeof(ctrParams.cb)) {
- PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
- return NULL;
+ PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
+ return NULL;
}
gcm = PORT_ZNew(GCMContext);
if (gcm == NULL) {
- return 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;
+ goto loser;
}
rv = gcmHash_InitContext(ghash, H, blocksize);
if (rv != SECSuccess) {
- goto loser;
+ goto loser;
}
freeHash = PR_TRUE;
@@ -636,23 +647,23 @@ GCM_CreateContext(void *context, freeblCipherFunc cipher,
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;
+ 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 = 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);
+ (unsigned char *)&ctrParams, blocksize);
if (rv != SECSuccess) {
- goto loser;
+ goto loser;
}
freeCtr = PR_TRUE;
@@ -661,28 +672,28 @@ GCM_CreateContext(void *context, freeblCipherFunc cipher,
/* 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);
+ gcm->tagKey, blocksize, blocksize);
if (rv != SECSuccess) {
- goto loser;
+ goto loser;
}
/* finally mix in the AAD data */
rv = gcmHash_Reset(ghash, gcmParams->pAAD, gcmParams->ulAADLen, blocksize);
if (rv != SECSuccess) {
- goto loser;
+ goto loser;
}
return gcm;
loser:
if (freeCtr) {
- CTR_DestroyContext(&gcm->ctr_context, PR_FALSE);
+ CTR_DestroyContext(&gcm->ctr_context, PR_FALSE);
}
if (freeHash) {
- gcmHash_DestroyContext(&gcm->ghash_context, PR_FALSE);
+ gcmHash_DestroyContext(&gcm->ghash_context, PR_FALSE);
}
if (gcm) {
- PORT_Free(gcm);
+ PORT_Free(gcm);
}
return NULL;
}
@@ -695,56 +706,57 @@ GCM_DestroyContext(GCMContext *gcm, PRBool freeit)
* allocated data (like mp_int's) */
CTR_DestroyContext(&gcm->ctr_context, PR_FALSE);
gcmHash_DestroyContext(&gcm->ghash_context, PR_FALSE);
+ PORT_Memset(&gcm->tagBits, 0, sizeof(gcm->tagBits));
+ PORT_Memset(gcm->tagKey, 0, sizeof(gcm->tagKey));
if (freeit) {
- PORT_Free(gcm);
+ PORT_Free(gcm);
}
}
static SECStatus
gcm_GetTag(GCMContext *gcm, unsigned char *outbuf,
- unsigned int *outlen, unsigned int maxout,
- unsigned int blocksize)
+ 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;
+ 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;
+ *outlen = tagBytes;
+ PORT_SetError(SEC_ERROR_OUTPUT_LEN);
+ return SECFailure;
}
if (maxout < tagBytes) {
- *outlen = tagBytes;
- PORT_SetError(SEC_ERROR_OUTPUT_LEN);
- return SECFailure;
+ *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;
+ 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];
+ 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);
+ 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
@@ -752,41 +764,41 @@ gcm_GetTag(GCMContext *gcm, unsigned char *outbuf,
*/
SECStatus
GCM_EncryptUpdate(GCMContext *gcm, unsigned char *outbuf,
- unsigned int *outlen, unsigned int maxout,
- const unsigned char *inbuf, unsigned int inlen,
- unsigned int blocksize)
+ 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;
+ 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;
+ PORT_SetError(SEC_ERROR_INPUT_LEN);
+ return SECFailure;
}
if (maxout < inlen + tagBytes) {
- *outlen = inlen + tagBytes;
- PORT_SetError(SEC_ERROR_OUTPUT_LEN);
- return SECFailure;
+ *outlen = inlen + tagBytes;
+ PORT_SetError(SEC_ERROR_OUTPUT_LEN);
+ return SECFailure;
}
rv = CTR_Update(&gcm->ctr_context, outbuf, outlen, maxout,
- inbuf, inlen, blocksize);
+ inbuf, inlen, blocksize);
if (rv != SECSuccess) {
- return SECFailure;
+ 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;
+ 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;
+ PORT_Memset(outbuf, 0, *outlen); /* clear the output buffer */
+ *outlen = 0;
+ return SECFailure;
};
*outlen += len;
return SECSuccess;
@@ -802,9 +814,9 @@ GCM_EncryptUpdate(GCMContext *gcm, unsigned char *outbuf,
*/
SECStatus
GCM_DecryptUpdate(GCMContext *gcm, unsigned char *outbuf,
- unsigned int *outlen, unsigned int maxout,
- const unsigned char *inbuf, unsigned int inlen,
- unsigned int blocksize)
+ unsigned int *outlen, unsigned int maxout,
+ const unsigned char *inbuf, unsigned int inlen,
+ unsigned int blocksize)
{
SECStatus rv;
unsigned int tagBytes;
@@ -812,12 +824,12 @@ GCM_DecryptUpdate(GCMContext *gcm, unsigned char *outbuf,
const unsigned char *intag;
unsigned int len;
- tagBytes = (gcm->tagBits + (PR_BITS_PER_BYTE-1)) / PR_BITS_PER_BYTE;
+ tagBytes = (gcm->tagBits + (PR_BITS_PER_BYTE - 1)) / PR_BITS_PER_BYTE;
/* get the authentication block */
if (inlen < tagBytes) {
- PORT_SetError(SEC_ERROR_INPUT_LEN);
- return SECFailure;
+ PORT_SetError(SEC_ERROR_INPUT_LEN);
+ return SECFailure;
}
inlen -= tagBytes;
@@ -826,21 +838,23 @@ GCM_DecryptUpdate(GCMContext *gcm, unsigned char *outbuf,
/* verify the block */
rv = gcmHash_Update(&gcm->ghash_context, inbuf, inlen, blocksize);
if (rv != SECSuccess) {
- return SECFailure;
+ return SECFailure;
}
rv = gcm_GetTag(gcm, tag, &len, blocksize, blocksize);
if (rv != SECSuccess) {
- return SECFailure;
+ 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;
+ /* force a CKR_ENCRYPTED_DATA_INVALID error at in softoken */
+ PORT_SetError(SEC_ERROR_BAD_DATA);
+ PORT_Memset(tag, 0, sizeof(tag));
+ return SECFailure;
}
+ PORT_Memset(tag, 0, sizeof(tag));
/* finish the decryption */
return CTR_Update(&gcm->ctr_context, outbuf, outlen, maxout,
- inbuf, inlen, blocksize);
+ inbuf, inlen, blocksize);
}
diff --git a/nss/lib/freebl/gcm.h b/nss/lib/freebl/gcm.h
index 4dd71b4..1cdba53 100644
--- a/nss/lib/freebl/gcm.h
+++ b/nss/lib/freebl/gcm.h
@@ -16,16 +16,16 @@ typedef struct GCMContextStr GCMContext;
*
* 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);
+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_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);
+ unsigned int *outlen, unsigned int maxout,
+ const unsigned char *inbuf, unsigned int inlen,
+ unsigned int blocksize);
#endif
diff --git a/nss/lib/freebl/genload.c b/nss/lib/freebl/genload.c
index 63b97db..832deb5 100644
--- a/nss/lib/freebl/genload.c
+++ b/nss/lib/freebl/genload.c
@@ -9,7 +9,7 @@
* const char *NameOfThisSharedLib;
*
* NameOfThisSharedLib:
- * The file name of the shared library that shall be used as the
+ * 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.
*/
@@ -25,13 +25,14 @@
* The caller should call PR_Free to free the string returned by this
* function.
*/
-static char* loader_GetOriginalPathname(const char* link)
+static char*
+loader_GetOriginalPathname(const char* link)
{
#ifdef __GLIBC__
char* tmp = realpath(link, NULL);
char* resolved;
- if (! tmp)
- return NULL;
+ 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);
@@ -58,8 +59,8 @@ static char* loader_GetOriginalPathname(const char* link)
return NULL;
}
strcpy(input, link);
- while ( (iterations++ < BL_MAXSYMLINKS) &&
- ( (retlen = readlink(input, resolved, len - 1)) > 0) ) {
+ while ((iterations++ < BL_MAXSYMLINKS) &&
+ ((retlen = readlink(input, resolved, len - 1)) > 0)) {
char* tmp = input;
resolved[retlen] = '\0'; /* NULL termination */
input = resolved;
@@ -79,11 +80,11 @@ static char* loader_GetOriginalPathname(const char* link)
* 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)
+static PRLibrary*
+loader_LoadLibInReferenceDir(const char* referencePath, const char* name)
{
- PRLibrary *dlh = NULL;
- char *fullName = NULL;
+ PRLibrary* dlh = NULL;
+ char* fullName = NULL;
char* c;
PRLibSpec libSpec;
@@ -91,12 +92,12 @@ loader_LoadLibInReferenceDir(const char *referencePath, const char *name)
c = strrchr(referencePath, PR_GetDirectorySeparator());
if (c) {
size_t referencePathSize = 1 + c - referencePath;
- fullName = (char*) PORT_Alloc(strlen(name) + referencePathSize + 1);
+ fullName = (char*)PORT_Alloc(strlen(name) + referencePathSize + 1);
if (fullName) {
memcpy(fullName, referencePath, referencePathSize);
- strcpy(fullName + referencePathSize, name);
+ strcpy(fullName + referencePathSize, name);
#ifdef DEBUG_LOADER
- PR_fprintf(PR_STDOUT, "\nAttempting to load fully-qualified %s\n",
+ PR_fprintf(PR_STDOUT, "\nAttempting to load fully-qualified %s\n",
fullName);
#endif
libSpec.type = PR_LibSpec_Pathname;
@@ -109,15 +110,15 @@ loader_LoadLibInReferenceDir(const char *referencePath, const char *name)
}
/*
- * We use PR_GetLibraryFilePathname to get the pathname of the loaded
+ * 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)
+static PRLibrary*
+loader_LoadLibrary(const char* nameToLoad)
{
- PRLibrary *lib = NULL;
+ PRLibrary* lib = NULL;
char* fullPath = NULL;
PRLibSpec libSpec;
@@ -164,4 +165,3 @@ loader_LoadLibrary(const char *nameToLoad)
}
return lib;
}
-
diff --git a/nss/lib/freebl/hmacct.c b/nss/lib/freebl/hmacct.c
index 0c3ba41..c7815ac 100644
--- a/nss/lib/freebl/hmacct.c
+++ b/nss/lib/freebl/hmacct.c
@@ -25,8 +25,8 @@
*
* 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)) )
+#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. */
@@ -115,7 +115,7 @@ MAC(unsigned char *mdOut,
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;
+ (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;
@@ -152,67 +152,67 @@ MAC(unsigned char *mdOut,
/* 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;
+ numStartingBlocks = numBlocks - varianceBlocks;
+ k = mdBlockSize * numStartingBlocks;
}
- bits = 8*macEndOffset;
+ 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);
+ /* 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;
+ 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);
- }
+ /* 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));
- }
+ /* 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);
- }
- }
+ 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));
@@ -221,69 +221,69 @@ MAC(unsigned char *mdOut,
* 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++;
+ 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;
+ /* 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;
- }
+ /* 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->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;
+ /* 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);
+ 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;
+ /* 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->update(mdState, hmacPad, mdBlockSize);
+ hashObj->update(mdState, macOut, mdSize);
}
hashObj->end(mdState, mdOut, mdOutLen, mdOutMax);
@@ -307,10 +307,10 @@ HMAC_ConstantTime(
unsigned int bodyTotalLen)
{
if (hashObj->end_raw == NULL)
- return SECFailure;
+ return SECFailure;
return MAC(result, resultLen, maxResultLen, hashObj, secret, secretLen,
- header, headerLen, body, bodyLen, bodyTotalLen,
- 0 /* not SSLv3 */);
+ header, headerLen, body, bodyLen, bodyTotalLen,
+ 0 /* not SSLv3 */);
}
SECStatus
@@ -328,9 +328,8 @@ SSLv3_MAC_ConstantTime(
unsigned int bodyTotalLen)
{
if (hashObj->end_raw == NULL)
- return SECFailure;
+ return SECFailure;
return MAC(result, resultLen, maxResultLen, hashObj, secret, secretLen,
- header, headerLen, body, bodyLen, bodyTotalLen,
- 1 /* SSLv3 */);
+ header, headerLen, body, bodyLen, bodyTotalLen,
+ 1 /* SSLv3 */);
}
-
diff --git a/nss/lib/freebl/intel-aes.h b/nss/lib/freebl/intel-aes.h
index 3b71e5f..d5bd2d8 100644
--- a/nss/lib/freebl/intel-aes.h
+++ b/nss/lib/freebl/intel-aes.h
@@ -10,137 +10,134 @@ 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);
+ 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);
+ 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);
+ 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);
+ unsigned int *outputLen,
+ unsigned int maxOutputLen,
+ const unsigned char *input,
+ unsigned int inputLen,
+ unsigned int blocksize);
SECStatus intel_aes_encrypt_ctr_128(CTRContext *cx, unsigned char *output,
- unsigned int *outputLen,
- unsigned int maxOutputLen,
- const unsigned char *input,
- unsigned int inputLen,
- unsigned int blocksize);
+ 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);
+ 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);
+ 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);
+ 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);
+ unsigned int *outputLen,
+ unsigned int maxOutputLen,
+ const unsigned char *input,
+ unsigned int inputLen,
+ unsigned int blocksize);
SECStatus intel_aes_encrypt_ctr_192(CTRContext *cx, unsigned char *output,
- unsigned int *outputLen,
- unsigned int maxOutputLen,
- const unsigned char *input,
- unsigned int inputLen,
- unsigned int blocksize);
+ 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);
+ 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);
+ 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);
+ 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);
+ unsigned int *outputLen,
+ unsigned int maxOutputLen,
+ const unsigned char *input,
+ unsigned int inputLen,
+ unsigned int blocksize);
SECStatus intel_aes_encrypt_ctr_256(CTRContext *cx, unsigned char *output,
- unsigned int *outputLen,
- unsigned int maxOutputLen,
- const unsigned char *input,
- unsigned int inputLen,
- unsigned int blocksize);
+ 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_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_ctr_worker(nr) \
+ ((nr) == 10 ? intel_aes_encrypt_ctr_128 \
+ : (nr) == 12 ? intel_aes_encrypt_ctr_192 \
+ : intel_aes_encrypt_ctr_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_ctr_worker(nr) \
- ((nr) == 10 ? intel_aes_encrypt_ctr_128 : \
- (nr) == 12 ? intel_aes_encrypt_ctr_192 : \
- intel_aes_encrypt_ctr_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)
+#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/nss/lib/freebl/intel-aes.s b/nss/lib/freebl/intel-aes.s
index a83529a..2dfcfa1 100644
--- a/nss/lib/freebl/intel-aes.s
+++ b/nss/lib/freebl/intel-aes.s
@@ -7,6 +7,20 @@
#define IV_OFFSET 16
#define EXPANDED_KEY_OFFSET 48
+/*
+ * Warning: the length values used in this module are "unsigned int"
+ * in C, which is 32-bit. When they're passed in registers, use only
+ * the low 32 bits, because the top half is unspecified.
+ *
+ * This is called from C code, so the contents of those bits can
+ * depend on the C compiler's optimization decisions. This means that
+ * mistakes might not be obvious in testing if those bits happen to be
+ * zero in your build.
+ *
+ * Exception: 32-bit lea instructions use a 64-bit address because the
+ * address size doesn't affect the result, and that form is more
+ * compactly encoded and preferred by compilers over a 32-bit address.
+ */
/* in %rdi : the key
in %rsi : buffer for expanded key
@@ -119,10 +133,11 @@ 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
+ (already filled in by caller)
+ in %ecx : maxOutputLen - length of output buffer
+ (already checked by caller)
in %r8 : input - pointer to input buffer
- in %r9 : inputLen - length of input buffer
+ in %r9d : inputLen - length of input buffer
on stack: blocksize - AES blocksize (always 16, unused)
*/
.type intel_aes_encrypt_ecb_128,@function
@@ -135,11 +150,11 @@ intel_aes_encrypt_ecb_128:
movdqu (%rdi), %xmm2
movdqu 160(%rdi), %xmm12
xor %eax, %eax
-// cmpq $8*16, %r9
- cmpq $128, %r9
+// cmpl $8*16, %r9d
+ cmpl $128, %r9d
jb 1f
-// leaq -8*16(%r9), %r11
- leaq -128(%r9), %r11
+// leal -8*16(%r9), %r11d
+ leal -128(%r9), %r11d
2: movdqu (%r8, %rax), %xmm3
movdqu 16(%r8, %rax), %xmm4
movdqu 32(%r8, %rax), %xmm5
@@ -260,11 +275,11 @@ intel_aes_encrypt_ecb_128:
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
+// addl $8*16, %eax
+ addl $128, %eax
+ cmpl %r11d, %eax
jbe 2b
-1: cmpq %rax, %r9
+1: cmpl %eax, %r9d
je 5f
movdqu 16(%rdi), %xmm3
@@ -290,8 +305,8 @@ intel_aes_encrypt_ecb_128:
.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
+ addl $16, %eax
+ cmpl %eax, %r9d
jne 4b
5: xor %eax, %eax
@@ -302,10 +317,11 @@ 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
+ (already filled in by caller)
+ in %ecx : maxOutputLen - length of output buffer
+ (already checked by caller)
in %r8 : input - pointer to input buffer
- in %r9 : inputLen - length of input buffer
+ in %r9d : inputLen - length of input buffer
on stack: blocksize - AES blocksize (always 16, unused)
*/
.type intel_aes_decrypt_ecb_128,@function
@@ -318,11 +334,11 @@ intel_aes_decrypt_ecb_128:
movdqu (%rdi), %xmm2
movdqu 160(%rdi), %xmm12
xorl %eax, %eax
-// cmpq $8*16, %r9
- cmpq $128, %r9
+// cmpl $8*16, %r9d
+ cmpl $128, %r9d
jb 1f
-// leaq -8*16(%r9), %r11
- leaq -128(%r9), %r11
+// leal -8*16(%r9), %r11d
+ leal -128(%r9), %r11d
2: movdqu (%r8, %rax), %xmm3
movdqu 16(%r8, %rax), %xmm4
movdqu 32(%r8, %rax), %xmm5
@@ -443,11 +459,11 @@ intel_aes_decrypt_ecb_128:
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
+// addl $8*16, %eax
+ addl $128, %eax
+ cmpl %r11d, %eax
jbe 2b
-1: cmpq %rax, %r9
+1: cmpl %eax, %r9d
je 5f
movdqu 16(%rdi), %xmm3
@@ -473,8 +489,8 @@ intel_aes_decrypt_ecb_128:
.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
+ addl $16, %eax
+ cmpl %eax, %r9d
jne 4b
5: xor %eax, %eax
@@ -485,17 +501,18 @@ 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
+ (already filled in by caller)
+ in %ecx : maxOutputLen - length of output buffer
+ (already checked by caller)
in %r8 : input - pointer to input buffer
- in %r9 : inputLen - length of input buffer
+ in %r9d : 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
+ testl %r9d, %r9d
je 2f
// leaq IV_OFFSET(%rdi), %rdx
@@ -532,8 +549,8 @@ intel_aes_encrypt_cbc_128:
.byte 0x66,0x41,0x0f,0x38,0xdd,0xcc /* aesenclast %xmm12, %xmm1 */
movdqu %xmm1, (%rsi, %rax)
movdqa %xmm1, %xmm0
- addq $16, %rax
- cmpq %rax, %r9
+ addl $16, %eax
+ cmpl %eax, %r9d
jne 1b
movdqu %xmm0, (%rdx)
@@ -546,10 +563,11 @@ 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
+ (already filled in by caller)
+ in %ecx : maxOutputLen - length of output buffer
+ (already checked by caller)
in %r8 : input - pointer to input buffer
- in %r9 : inputLen - length of input buffer
+ in %r9d : inputLen - length of input buffer
on stack: blocksize - AES blocksize (always 16, unused)
*/
.type intel_aes_decrypt_cbc_128,@function
@@ -565,9 +583,9 @@ intel_aes_decrypt_cbc_128:
movdqu (%rdi), %xmm2 /* first key block */
movdqu 160(%rdi), %xmm12 /* last key block */
xorl %eax, %eax
- cmpq $128, %r9
+ cmpl $128, %r9d
jb 1f
- leaq -128(%r9), %r11
+ leal -128(%r9), %r11d
2: movdqu (%r8, %rax), %xmm3 /* 1st data block */
movdqu 16(%r8, %rax), %xmm4 /* 2d data block */
movdqu 32(%r8, %rax), %xmm5
@@ -704,10 +722,10 @@ intel_aes_decrypt_cbc_128:
movdqu %xmm8, 80(%rsi, %rax)
movdqu %xmm9, 96(%rsi, %rax)
movdqu %xmm10, 112(%rsi, %rax)
- addq $128, %rax
- cmpq %r11, %rax
+ addl $128, %eax
+ cmpl %r11d, %eax
jbe 2b
-1: cmpq %rax, %r9
+1: cmpl %eax, %r9d
je 5f
movdqu 16(%rdi), %xmm3
@@ -736,8 +754,8 @@ intel_aes_decrypt_cbc_128:
pxor %xmm0, %xmm1
movdqu %xmm1, (%rsi, %rax)
movdqa %xmm13, %xmm0
- addq $16, %rax
- cmpq %rax, %r9
+ addl $16, %eax
+ cmpl %eax, %r9d
jne 4b
5: movdqu %xmm0, (%rdx)
@@ -873,10 +891,11 @@ 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
+ (already filled in by caller)
+ in %ecx : maxOutputLen - length of output buffer
+ (already checked by caller)
in %r8 : input - pointer to input buffer
- in %r9 : inputLen - length of input buffer
+ in %r9d : inputLen - length of input buffer
on stack: blocksize - AES blocksize (always 16, unused)
*/
.type intel_aes_encrypt_ecb_192,@function
@@ -889,11 +908,11 @@ intel_aes_encrypt_ecb_192:
movdqu (%rdi), %xmm2
movdqu 192(%rdi), %xmm14
xorl %eax, %eax
-// cmpq $8*16, %r9
- cmpq $128, %r9
+// cmpl $8*16, %r9d
+ cmpl $128, %r9d
jb 1f
-// leaq -8*16(%r9), %r11
- leaq -128(%r9), %r11
+// leal -8*16(%r9), %r11d
+ leal -128(%r9), %r11d
2: movdqu (%r8, %rax), %xmm3
movdqu 16(%r8, %rax), %xmm4
movdqu 32(%r8, %rax), %xmm5
@@ -1033,11 +1052,11 @@ intel_aes_encrypt_ecb_192:
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
+// addl $8*16, %eax
+ addl $128, %eax
+ cmpl %r11d, %eax
jbe 2b
-1: cmpq %rax, %r9
+1: cmpl %eax, %r9d
je 5f
movdqu 16(%rdi), %xmm3
@@ -1067,8 +1086,8 @@ intel_aes_encrypt_ecb_192:
.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
+ addl $16, %eax
+ cmpl %eax, %r9d
jne 4b
5: xor %eax, %eax
@@ -1079,10 +1098,11 @@ 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
+ (already filled in by caller)
+ in %ecx : maxOutputLen - length of output buffer
+ (already checked by caller)
in %r8 : input - pointer to input buffer
- in %r9 : inputLen - length of input buffer
+ in %r9d : inputLen - length of input buffer
on stack: blocksize - AES blocksize (always 16, unused)
*/
.type intel_aes_decrypt_ecb_192,@function
@@ -1095,11 +1115,11 @@ intel_aes_decrypt_ecb_192:
movdqu (%rdi), %xmm2
movdqu 192(%rdi), %xmm14
xorl %eax, %eax
-// cmpq $8*16, %r9
- cmpq $128, %r9
+// cmpl $8*16, %r9d
+ cmpl $128, %r9d
jb 1f
-// leaq -8*16(%r9), %r11
- leaq -128(%r9), %r11
+// leal -8*16(%r9), %r11d
+ leal -128(%r9), %r11d
2: movdqu (%r8, %rax), %xmm3
movdqu 16(%r8, %rax), %xmm4
movdqu 32(%r8, %rax), %xmm5
@@ -1239,11 +1259,11 @@ intel_aes_decrypt_ecb_192:
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
+// addl $8*16, %eax
+ addl $128, %eax
+ cmpl %r11d, %eax
jbe 2b
-1: cmpq %rax, %r9
+1: cmpl %eax, %r9d
je 5f
movdqu 16(%rdi), %xmm3
@@ -1273,8 +1293,8 @@ intel_aes_decrypt_ecb_192:
.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
+ addl $16, %eax
+ cmpl %eax, %r9d
jne 4b
5: xor %eax, %eax
@@ -1285,17 +1305,18 @@ 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
+ (already filled in by caller)
+ in %ecx : maxOutputLen - length of output buffer
+ (already checked by caller)
in %r8 : input - pointer to input buffer
- in %r9 : inputLen - length of input buffer
+ in %r9d : 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
+ testl %r9d, %r9d
je 2f
// leaq IV_OFFSET(%rdi), %rdx
@@ -1336,8 +1357,8 @@ intel_aes_encrypt_cbc_192:
.byte 0x66,0x41,0x0f,0x38,0xdd,0xce /* aesenclast %xmm14, %xmm1 */
movdqu %xmm1, (%rsi, %rax)
movdqa %xmm1, %xmm0
- addq $16, %rax
- cmpq %rax, %r9
+ addl $16, %eax
+ cmpl %eax, %r9d
jne 1b
movdqu %xmm0, (%rdx)
@@ -1350,10 +1371,11 @@ 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
+ (already filled in by caller)
+ in %exx : maxOutputLen - length of output buffer
+ (already checked by caller)
in %r8 : input - pointer to input buffer
- in %r9 : inputLen - length of input buffer
+ in %r9d : inputLen - length of input buffer
on stack: blocksize - AES blocksize (always 16, unused)
*/
.type intel_aes_decrypt_cbc_192,@function
@@ -1367,9 +1389,9 @@ intel_aes_decrypt_cbc_192:
movdqu (%rdi), %xmm2
movdqu 192(%rdi), %xmm14
xorl %eax, %eax
- cmpq $128, %r9
+ cmpl $128, %r9d
jb 1f
- leaq -128(%r9), %r11
+ leal -128(%r9), %r11d
2: movdqu (%r8, %rax), %xmm3
movdqu 16(%r8, %rax), %xmm4
movdqu 32(%r8, %rax), %xmm5
@@ -1525,10 +1547,10 @@ intel_aes_decrypt_cbc_192:
movdqu %xmm8, 80(%rsi, %rax)
movdqu %xmm9, 96(%rsi, %rax)
movdqu %xmm10, 112(%rsi, %rax)
- addq $128, %rax
- cmpq %r11, %rax
+ addl $128, %eax
+ cmpl %r11d, %eax
jbe 2b
-1: cmpq %rax, %r9
+1: cmpl %eax, %r9d
je 5f
movdqu 16(%rdi), %xmm3
@@ -1561,8 +1583,8 @@ intel_aes_decrypt_cbc_192:
pxor %xmm0, %xmm1
movdqu %xmm1, (%rsi, %rax)
movdqa %xmm15, %xmm0
- addq $16, %rax
- cmpq %rax, %r9
+ addl $16, %eax
+ cmpl %eax, %r9d
jne 4b
5: movdqu %xmm0, (%rdx)
@@ -1705,10 +1727,11 @@ 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
+ (already filled in by caller)
+ in %ecx : maxOutputLen - length of output buffer
+ (already checked by caller)
in %r8 : input - pointer to input buffer
- in %r9 : inputLen - length of input buffer
+ in %r9d : inputLen - length of input buffer
on stack: blocksize - AES blocksize (always 16, unused)
*/
.type intel_aes_encrypt_ecb_256,@function
@@ -1721,11 +1744,11 @@ intel_aes_encrypt_ecb_256:
movdqu (%rdi), %xmm2
movdqu 224(%rdi), %xmm15
xorl %eax, %eax
-// cmpq $8*16, %r9
- cmpq $128, %r9
+// cmpl $8*16, %r9d
+ cmpl $128, %r9d
jb 1f
-// leaq -8*16(%r9), %r11
- leaq -128(%r9), %r11
+// leal -8*16(%r9), %r11d
+ leal -128(%r9), %r11d
2: movdqu (%r8, %rax), %xmm3
movdqu 16(%r8, %rax), %xmm4
movdqu 32(%r8, %rax), %xmm5
@@ -1884,11 +1907,11 @@ intel_aes_encrypt_ecb_256:
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
+// addl $8*16, %eax
+ addl $128, %eax
+ cmpl %r11d, %eax
jbe 2b
-1: cmpq %rax, %r9
+1: cmpl %eax, %r9d
je 5f
movdqu (%rdi), %xmm8
@@ -1924,8 +1947,8 @@ intel_aes_encrypt_ecb_256:
.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
+ addl $16, %eax
+ cmpl %eax, %r9d
jne 4b
5: xor %eax, %eax
@@ -1936,10 +1959,11 @@ 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
+ (already filled in by caller)
+ in %ecx : maxOutputLen - length of output buffer
+ (already checked by caller)
in %r8 : input - pointer to input buffer
- in %r9 : inputLen - length of input buffer
+ in %r9d : inputLen - length of input buffer
on stack: blocksize - AES blocksize (always 16, unused)
*/
.type intel_aes_decrypt_ecb_256,@function
@@ -1952,11 +1976,11 @@ intel_aes_decrypt_ecb_256:
movdqu (%rdi), %xmm2
movdqu 224(%rdi), %xmm15
xorl %eax, %eax
-// cmpq $8*16, %r9
- cmpq $128, %r9
+// cmpl $8*16, %r9d
+ cmpl $128, %r9d
jb 1f
-// leaq -8*16(%r9), %r11
- leaq -128(%r9), %r11
+// leal -8*16(%r9), %r11d
+ leal -128(%r9), %r11d
2: movdqu (%r8, %rax), %xmm3
movdqu 16(%r8, %rax), %xmm4
movdqu 32(%r8, %rax), %xmm5
@@ -2115,11 +2139,11 @@ intel_aes_decrypt_ecb_256:
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
+// addl $8*16, %eax
+ addl $128, %eax
+ cmpl %r11d, %eax
jbe 2b
-1: cmpq %rax, %r9
+1: cmpl %eax, %r9d
je 5f
movdqu 16(%rdi), %xmm2
@@ -2155,8 +2179,8 @@ intel_aes_decrypt_ecb_256:
.byte 0x66,0x41,0x0f,0x38,0xdf,0xc8 /* aesdeclast %xmm8, %xmm1 */
movdqu 112(%rdi), %xmm8
movdqu %xmm1, (%rsi, %rax)
- addq $16, %rax
- cmpq %rax, %r9
+ addl $16, %eax
+ cmpl %eax, %r9d
jne 4b
5: xor %eax, %eax
@@ -2167,17 +2191,18 @@ 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
+ (already filled in by caller)
+ in %ecx : maxOutputLen - length of output buffer
+ (already checked by caller)
in %r8 : input - pointer to input buffer
- in %r9 : inputLen - length of input buffer
+ in %r9d : 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
+ testl %r9d, %r9d
je 2f
// leaq IV_OFFSET(%rdi), %rdx
@@ -2223,8 +2248,8 @@ intel_aes_encrypt_cbc_256:
.byte 0x66,0x41,0x0f,0x38,0xdd,0xcf /* aesenclast %xmm15, %xmm1 */
movdqu %xmm1, (%rsi, %rax)
movdqa %xmm1, %xmm0
- addq $16, %rax
- cmpq %rax, %r9
+ addl $16, %eax
+ cmpl %eax, %r9d
jne 1b
movdqu %xmm0, (%rdx)
@@ -2237,10 +2262,11 @@ 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
+ (already filled in by caller)
+ in %ecx : maxOutputLen - length of output buffer
+ (already checked by caller)
in %r8 : input - pointer to input buffer
- in %r9 : inputLen - length of input buffer
+ in %r9d : inputLen - length of input buffer
on stack: blocksize - AES blocksize (always 16, unused)
*/
.type intel_aes_decrypt_cbc_256,@function
@@ -2256,11 +2282,11 @@ intel_aes_decrypt_cbc_256:
movdqu (%rdi), %xmm2
movdqu 224(%rdi), %xmm15
xorl %eax, %eax
-// cmpq $8*16, %r9
- cmpq $128, %r9
+// cmpl $8*16, %r9d
+ cmpl $128, %r9d
jb 1f
-// leaq -8*16(%r9), %r11
- leaq -128(%r9), %r11
+// leal -8*16(%r9), %r11d
+ leal -128(%r9), %r11d
2: movdqu (%r8, %rax), %xmm3
movdqu 16(%r8, %rax), %xmm4
movdqu 32(%r8, %rax), %xmm5
@@ -2435,11 +2461,11 @@ intel_aes_decrypt_cbc_256:
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
+// addl $8*16, %eax
+ addl $128, %eax
+ cmpl %r11d, %eax
jbe 2b
-1: cmpq %rax, %r9
+1: cmpl %eax, %r9d
je 5f
movdqu 16(%rdi), %xmm2
@@ -2477,8 +2503,8 @@ intel_aes_decrypt_cbc_256:
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
+ addl $16, %eax
+ cmpl %eax, %r9d
jne 4b
5: movdqu %xmm0, (%rdx)
diff --git a/nss/lib/freebl/intel-gcm-wrap.c b/nss/lib/freebl/intel-gcm-wrap.c
index 9b0a542..8c5eaf0 100644
--- a/nss/lib/freebl/intel-gcm-wrap.c
+++ b/nss/lib/freebl/intel-gcm-wrap.c
@@ -27,9 +27,8 @@
#include <emmintrin.h>
#include <tmmintrin.h>
-
-struct intel_AES_GCMContextStr{
- unsigned char Htbl[16*AES_BLOCK_SIZE];
+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];
@@ -39,13 +38,14 @@ struct intel_AES_GCMContextStr{
unsigned long Mlen;
};
-intel_AES_GCMContext *intel_AES_GCM_CreateContext(void *context,
- freeblCipherFunc cipher,
- const unsigned char *params,
- unsigned int blocksize)
+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;
+ AESContext *aes = (AESContext *)context;
const CK_GCM_PARAMS *gcmParams = (const CK_GCM_PARAMS *)params;
unsigned char buff[AES_BLOCK_SIZE]; /* aux buffer */
@@ -54,14 +54,14 @@ intel_AES_GCMContext *intel_AES_GCM_CreateContext(void *context,
unsigned long AAD_whole_len = gcmParams->ulAADLen & (~0xful);
unsigned int AAD_remainder_len = gcmParams->ulAADLen & 0xful;
- __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);
+ __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;
+ PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
+ return NULL;
}
gcm = PORT_ZNew(intel_AES_GCMContext);
@@ -76,18 +76,18 @@ intel_AES_GCMContext *intel_AES_GCM_CreateContext(void *context,
gcm->Mlen = 0;
/* first prepare H and its derivatives for ghash */
- intel_aes_gcmINIT(gcm->Htbl, (unsigned char*)aes->expandedKey, aes->Nr);
+ 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());
+ _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],
+ _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
@@ -110,7 +110,7 @@ intel_AES_GCMContext *intel_AES_GCM_CreateContext(void *context,
gcm->CTR);
/* TAG should be zero again */
- _mm_storeu_si128((__m128i*)gcm->T, _mm_setzero_si128());
+ _mm_storeu_si128((__m128i *)gcm->T, _mm_setzero_si128());
}
/* Encrypt the initial counter, will be used to encrypt the GHASH value,
@@ -122,7 +122,7 @@ intel_AES_GCMContext *intel_AES_GCM_CreateContext(void *context,
}
/* 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));
+ _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
@@ -138,24 +138,24 @@ intel_AES_GCMContext *intel_AES_GCM_CreateContext(void *context,
return gcm;
loser:
- if (gcm) {
- PORT_Free(gcm);
- }
+ PORT_Free(gcm);
return NULL;
}
-void intel_AES_GCM_DestroyContext(intel_AES_GCMContext *gcm, PRBool freeit)
+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)
+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];
@@ -196,11 +196,12 @@ SECStatus intel_AES_GCM_EncryptUpdate(intel_AES_GCMContext *gcm,
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)
+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];
@@ -224,19 +225,19 @@ SECStatus intel_AES_GCM_DecryptUpdate(intel_AES_GCMContext *gcm,
}
intel_aes_gcmDEC(
- inbuf,
- outbuf,
- gcm,
- inlen);
+ inbuf,
+ outbuf,
+ gcm,
+ inlen);
gcm->Mlen += inlen;
intel_aes_gcmTAG(
- gcm->Htbl,
- gcm->T,
- gcm->Mlen,
- gcm->Alen,
- gcm->X0,
- T);
+ gcm->Htbl,
+ gcm->T,
+ gcm->Mlen,
+ gcm->Alen,
+ gcm->X0,
+ T);
if (NSS_SecureMemcmp(T, intag, tagBytes) != 0) {
memset(outbuf, 0, inlen);
diff --git a/nss/lib/freebl/intel-gcm.h b/nss/lib/freebl/intel-gcm.h
index 6dfbc3c..566e544 100644
--- a/nss/lib/freebl/intel-gcm.h
+++ b/nss/lib/freebl/intel-gcm.h
@@ -27,57 +27,57 @@
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);
+ 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);
+ 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);
+ unsigned int *outlen, unsigned int maxout,
+ const unsigned char *inbuf, unsigned int inlen,
+ unsigned int blocksize);
-/* Prototypes of functions in the assembler file for fast AES-GCM, using
+/* Prototypes 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(R) 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],
+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);
+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,
+void intel_aes_gcmAAD(unsigned char Htbl[16 * 16],
+ unsigned char *AAD,
+ unsigned long Alen,
unsigned char *Tp);
-/* Encrypts and hashes the Plaintext.
+/* 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,
+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,
+void intel_aes_gcmDEC(const unsigned char *CT,
+ unsigned char *PT,
+ void *Gctx,
unsigned long len);
#endif
diff --git a/nss/lib/freebl/jpake.c b/nss/lib/freebl/jpake.c
index 88cdc6e..741c7a8 100644
--- a/nss/lib/freebl/jpake.c
+++ b/nss/lib/freebl/jpake.c
@@ -16,15 +16,15 @@
* to match the OpenSSL J-PAKE implementation.
*/
static mp_err
-hashSECItem(HASHContext * hash, const SECItem * it)
+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);
+ 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;
@@ -33,15 +33,15 @@ hashSECItem(HASHContext * hash, const SECItem * it)
/* 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)
+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;
@@ -55,10 +55,10 @@ hashPublicParams(HASH_HashType hashType, const SECItem * g,
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) );
+ 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);
@@ -73,10 +73,10 @@ cleanup:
/* 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)
+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;
@@ -92,22 +92,21 @@ JPAKE_Sign(PLArenaPool * arena, const PQGParams * pqg, HASH_HashType hashType,
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 ||
+ 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) {
+ !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;
@@ -119,25 +118,25 @@ JPAKE_Sign(PLArenaPool * arena, const PQGParams * pqg, HASH_HashType hashType,
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) );
+ 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);
+ SECITEM_TO_MPINT(*x, &X);
/* gx = g^x */
if (gxIn == NULL) {
- CHECK_MPI_OK( mp_exptmod(&g, &X, &p, &GX) );
+ CHECK_MPI_OK(mp_exptmod(&g, &X, &p, &GX));
MPINT_TO_SECITEM(&GX, gxOut, arena);
gxIn = gxOut;
} else {
@@ -158,16 +157,16 @@ JPAKE_Sign(PLArenaPool * arena, const PQGParams * pqg, HASH_HashType hashType,
SECITEM_TO_MPINT(v, &V);
/* gv = g^v (mod q), random v, 1 <= v < q */
- CHECK_MPI_OK( mp_exptmod(&g, &V, &p, &GV) );
+ 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) );
+ 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) );
+ 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:
@@ -191,9 +190,9 @@ cleanup:
/* 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)
+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;
@@ -210,15 +209,15 @@ JPAKE_Verify(PLArenaPool * arena, const PQGParams * pqg, HASH_HashType hashType,
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 ||
+ 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;
@@ -237,17 +236,17 @@ JPAKE_Verify(PLArenaPool * arena, const PQGParams * pqg, HASH_HashType hashType,
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) );
+ 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);
@@ -255,23 +254,23 @@ JPAKE_Verify(PLArenaPool * arena, const PQGParams * pqg, HASH_HashType hashType,
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_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 &&
+ 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) );
+
+ 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) );
+ 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);
@@ -279,7 +278,8 @@ JPAKE_Verify(PLArenaPool * arena, const PQGParams * pqg, HASH_HashType hashType,
NSS_SecureMemcmp(calculated.data, gv->data, calculated.len) == 0) {
rv = SECSuccess;
} else {
-badSig: PORT_SetError(SEC_ERROR_BAD_SIGNATURE);
+ badSig:
+ PORT_SetError(SEC_ERROR_BAD_SIGNATURE);
rv = SECFailure;
}
@@ -295,7 +295,7 @@ cleanup:
mp_clear(&gr);
mp_clear(&gxh);
mp_clear(&gr_gxh);
-
+
if (rv == SECSuccess && err != MP_OKAY) {
MP_TO_SEC_ERROR(err);
rv = SECFailure;
@@ -305,8 +305,8 @@ cleanup:
/* 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)
+jpake_Round2Base(const SECItem *gx1, const SECItem *gx3,
+ const SECItem *gx4, const mp_int *p, mp_int *base)
{
mp_err err;
mp_int GX1;
@@ -319,10 +319,10 @@ jpake_Round2Base(const SECItem * gx1, const SECItem * gx3,
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) );
+ 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);
@@ -333,10 +333,10 @@ jpake_Round2Base(const SECItem * gx1, const SECItem * gx3,
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) );
+
+ 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);
@@ -347,10 +347,10 @@ cleanup:
}
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)
+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;
@@ -360,15 +360,15 @@ JPAKE_Round2(PLArenaPool * arena,
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 ||
+ !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))) {
+ !x2 || !x2->data || x2->len == 0 ||
+ !s || !s->data || s->len == 0))) {
PORT_SetError(SEC_ERROR_INVALID_ARGS);
return SECFailure;
}
@@ -379,17 +379,17 @@ JPAKE_Round2(PLArenaPool * arena,
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) );
+ 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) );
+ 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) {
@@ -397,12 +397,12 @@ JPAKE_Round2(PLArenaPool * arena,
goto cleanup;
}
- CHECK_MPI_OK( mp_mulmod(&X2, &S, &Q, &result) );
+ 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) );
+ CHECK_MPI_OK(jpake_Round2Base(gx1, gx3, gx4, &P, &result));
MPINT_TO_SECITEM(&result, base, arena);
cleanup:
@@ -420,9 +420,9 @@ cleanup:
}
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)
+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;
@@ -433,13 +433,13 @@ JPAKE_Final(PLArenaPool * arena, const SECItem * p, const SECItem * q,
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) {
+ !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;
}
@@ -451,31 +451,31 @@ JPAKE_Final(PLArenaPool * arena, const SECItem * p, const SECItem * q,
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) );
+ 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) );
+ 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) );
-
+ 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) );
+ 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) );
+ CHECK_MPI_OK(mp_exptmod(&base, &exponent, &P, &tmp));
MPINT_TO_SECITEM(&tmp, K, arena);
diff --git a/nss/lib/freebl/ldvector.c b/nss/lib/freebl/ldvector.c
index 1d9affe..fb986a6 100644
--- a/nss/lib/freebl/ldvector.c
+++ b/nss/lib/freebl/ldvector.c
@@ -12,294 +12,338 @@ extern int FREEBL_InitStubs(void);
#include "loader.h"
#include "alghmac.h"
#include "hmacct.h"
+#include "blapii.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 */
+
+ RSA_SignRaw,
+ RSA_CheckSignRaw,
+ RSA_CheckSignRecoverRaw,
+ RSA_EncryptRaw,
+ RSA_DecryptRaw,
+ RSA_EncryptOAEP,
+ RSA_DecryptOAEP,
+ RSA_EncryptBlock,
+ RSA_DecryptBlock,
+ RSA_SignPSS,
+ RSA_CheckSignPSS,
+ RSA_Sign,
+ RSA_CheckSign,
+ RSA_CheckSignRecover,
+ /* End of Version 3.016 */
+
+ EC_FillParams,
+ EC_DecodeParams,
+ EC_CopyParams,
-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 */
-
- RSA_SignRaw,
- RSA_CheckSignRaw,
- RSA_CheckSignRecoverRaw,
- RSA_EncryptRaw,
- RSA_DecryptRaw,
- RSA_EncryptOAEP,
- RSA_DecryptOAEP,
- RSA_EncryptBlock,
- RSA_DecryptBlock,
- RSA_SignPSS,
- RSA_CheckSignPSS,
- RSA_Sign,
- RSA_CheckSign,
- RSA_CheckSignRecover,
-
- /* End of Version 3.016 */
-
- EC_FillParams,
- EC_DecodeParams,
- EC_CopyParams
+ /* End of Version 3.017 */
- /* End of Version 3.017 */
-};
-
-const FREEBLVector *
+ ChaCha20Poly1305_InitContext,
+ ChaCha20Poly1305_CreateContext,
+ ChaCha20Poly1305_DestroyContext,
+ ChaCha20Poly1305_Seal,
+ ChaCha20Poly1305_Open
+
+ /* End of Version 3.018 */
+ };
+
+const FREEBLVector*
FREEBL_GetVector(void)
{
+#ifdef FREEBL_NO_DEPEND
+ SECStatus rv;
+#endif
+
#define NSS_VERSION_VARIABLE __nss_freebl_version
#include "verref.h"
#ifdef FREEBL_NO_DEPEND
- FREEBL_InitStubs();
+ /* this entry point is only valid if nspr and nss-util has been loaded */
+ rv = FREEBL_InitStubs();
+ if (rv != SECSuccess) {
+ return NULL;
+ }
#endif
+ /* make sure the Full self tests have been run before continuing */
+ BL_POSTRan(PR_FALSE);
+
return &vector;
}
+#ifdef FREEBL_LOWHASH
+static const struct NSSLOWVectorStr nssvector =
+ {
+ sizeof nssvector,
+ NSSLOW_VERSION,
+ FREEBL_GetVector,
+ NSSLOW_Init,
+ NSSLOW_Shutdown,
+ NSSLOW_Reset,
+ NSSLOWHASH_NewContext,
+ NSSLOWHASH_Begin,
+ NSSLOWHASH_Update,
+ NSSLOWHASH_End,
+ NSSLOWHASH_Destroy,
+ NSSLOWHASH_Length
+ };
+
+const NSSLOWVector*
+NSSLOW_GetVector(void)
+{
+ /* POST check and stub init happens in FREEBL_GetVector() and
+ * NSSLOW_Init() respectively */
+ return &nssvector;
+}
+#endif
diff --git a/nss/lib/freebl/loader.c b/nss/lib/freebl/loader.c
index 9105a69..84876c1 100644
--- a/nss/lib/freebl/loader.c
+++ b/nss/lib/freebl/loader.c
@@ -10,106 +10,20 @@
#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)
-#include <unistd.h>
-
-/* 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 "blname.c"
#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 const char *NameOfThisSharedLib =
+ SHLIB_PREFIX "softokn" SOFTOKEN_SHLIB_VERSION "." SHLIB_SUFFIX;
-static PRLibrary* blLib;
+static PRLibrary *blLib = NULL;
#define LSB(x) ((x)&0xff)
-#define MSB(x) ((x)>>8)
+#define MSB(x) ((x) >> 8)
static const FREEBLVector *vector;
static const char *libraryName = NULL;
@@ -119,93 +33,94 @@ static const char *libraryName = NULL;
/* This function must be run only once. */
/* determine if hybrid platform, then actually load the DSO. */
static PRStatus
-freebl_LoadDSO( void )
+freebl_LoadDSO(void)
{
- PRLibrary * handle;
- const char * name = getLibName();
+ 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");
- 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;
- }
- }
+ 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");
+ 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;
+ }
+ }
+ }
#ifdef DEBUG
- {
- PRStatus status = PR_UnloadLibrary(blLib);
- PORT_Assert(PR_SUCCESS == status);
- }
+ if (blLib) {
+ PRStatus status = PR_UnloadLibrary(blLib);
+ PORT_Assert(PR_SUCCESS == status);
+ }
#else
- PR_UnloadLibrary(blLib);
+ if (blLib)
+ PR_UnloadLibrary(blLib);
#endif
- }
- return PR_FAILURE;
+ }
+ return PR_FAILURE;
}
static const PRCallOnceType pristineCallOnce;
static PRCallOnceType loadFreeBLOnce;
static PRStatus
-freebl_RunLoaderOnce( void )
+freebl_RunLoaderOnce(void)
{
- PRStatus status;
+ PRStatus status;
- status = PR_CallOnce(&loadFreeBLOnce, &freebl_LoadDSO);
- return status;
+ status = PR_CallOnce(&loadFreeBLOnce, &freebl_LoadDSO);
+ return status;
}
-SECStatus
+SECStatus
BL_Init(void)
{
- if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
- return SECFailure;
- return (vector->p_BL_Init)();
+ if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
+ return SECFailure;
+ return (vector->p_BL_Init)();
}
-RSAPrivateKey *
-RSA_NewKey(int keySizeInBits, SECItem * publicExponent)
+RSAPrivateKey *
+RSA_NewKey(int keySizeInBits, SECItem *publicExponent)
{
- if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
- return NULL;
- return (vector->p_RSA_NewKey)(keySizeInBits, 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)
+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);
+ 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)
+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);
+ if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
+ return SECFailure;
+ return (vector->p_RSA_PrivateKeyOp)(key, output, input);
}
SECStatus
@@ -213,1029 +128,1020 @@ 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);
+ if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
+ return SECFailure;
+ return (vector->p_RSA_PrivateKeyOpDoubleChecked)(key, output, input);
}
SECStatus
RSA_PrivateKeyCheck(const RSAPrivateKey *key)
{
- if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
- return SECFailure;
- return (vector->p_RSA_PrivateKeyCheck)(key);
+ if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
+ return SECFailure;
+ return (vector->p_RSA_PrivateKeyCheck)(key);
}
-SECStatus
-DSA_NewKey(const PQGParams * params, DSAPrivateKey ** privKey)
+SECStatus
+DSA_NewKey(const PQGParams *params, DSAPrivateKey **privKey)
{
- if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
- return SECFailure;
- return (vector->p_DSA_NewKey)(params, 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)
+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);
+ 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)
+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);
+ 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,
+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);
+ 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)
+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);
+ 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)
+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)
+SECStatus
+DH_GenParam(int primeLen, DHParams **params)
{
- if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
- return SECFailure;
- return (vector->p_DH_GenParam)(primeLen, params);
+ if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
+ return SECFailure;
+ return (vector->p_DH_GenParam)(primeLen, params);
}
-SECStatus
-DH_NewKey(DHParams * params, DHPrivateKey ** privKey)
+SECStatus
+DH_NewKey(DHParams *params, DHPrivateKey **privKey)
{
- if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
- return SECFailure;
- return (vector->p_DH_NewKey)( params, 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)
+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);
+ 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)
+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);
+ if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
+ return SECFailure;
+ return (vector->p_KEA_Derive)(prime, public1, public2,
+ private1, private2, derivedSecret);
}
-PRBool
+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);
+ 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);
+ if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
+ return NULL;
+ return (vector->p_RC4_CreateContext)(key, len);
}
-void
+void
RC4_DestroyContext(RC4Context *cx, PRBool freeit)
{
- if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
- return;
- (vector->p_RC4_DestroyContext)(cx, 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)
+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);
+ 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)
+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);
+ 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)
+ 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);
+ if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
+ return NULL;
+ return (vector->p_RC2_CreateContext)(key, len, iv, mode, effectiveKeyLen);
}
-void
+void
RC2_DestroyContext(RC2Context *cx, PRBool freeit)
{
- if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
- return;
- (vector->p_RC2_DestroyContext)(cx, 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)
+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);
+ 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)
+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);
+ 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)
+ 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);
+ if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
+ return NULL;
+ return (vector->p_RC5_CreateContext)(key, rounds, wordSize, iv, mode);
}
-void
+void
RC5_DestroyContext(RC5Context *cx, PRBool freeit)
{
- if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
- return;
- (vector->p_RC5_DestroyContext)(cx, 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)
+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);
+ 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)
+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);
+ 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)
+ int mode, PRBool encrypt)
{
- if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
- return NULL;
- return (vector->p_DES_CreateContext)(key, iv, mode, encrypt);
+ if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
+ return NULL;
+ return (vector->p_DES_CreateContext)(key, iv, mode, encrypt);
}
-void
+void
DES_DestroyContext(DESContext *cx, PRBool freeit)
{
- if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
- return;
- (vector->p_DES_DestroyContext)(cx, 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)
+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);
+ 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)
+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);
+ 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)
+ int mode, PRBool encrypt)
{
- if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
- return NULL;
- return (vector->p_SEED_CreateContext)(key, iv, mode, encrypt);
+ if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
+ return NULL;
+ return (vector->p_SEED_CreateContext)(key, iv, mode, encrypt);
}
-void
+void
SEED_DestroyContext(SEEDContext *cx, PRBool freeit)
{
- if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
- return;
- (vector->p_SEED_DestroyContext)(cx, 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)
+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);
+ 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)
+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);
+ 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,
+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);
+ if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
+ return NULL;
+ return (vector->p_AES_CreateContext)(key, iv, mode, encrypt, keylen,
+ blocklen);
}
-void
+void
AES_DestroyContext(AESContext *cx, PRBool freeit)
{
- if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
- return ;
- (vector->p_AES_DestroyContext)(cx, freeit);
+ if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
+ return;
+ (vector->p_AES_DestroyContext)(cx, freeit);
}
-SECStatus
+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);
+ if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
+ return SECFailure;
+ return (vector->p_AES_Encrypt)(cx, output, outputLen, maxOutputLen,
+ input, inputLen);
}
-SECStatus
+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);
+ if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
+ return SECFailure;
+ return (vector->p_AES_Decrypt)(cx, output, outputLen, maxOutputLen,
+ input, inputLen);
}
-SECStatus
+SECStatus
MD5_Hash(unsigned char *dest, const char *src)
{
- if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
- return SECFailure;
- return (vector->p_MD5_Hash)(dest, src);
+ if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
+ return SECFailure;
+ return (vector->p_MD5_Hash)(dest, src);
}
-SECStatus
+SECStatus
MD5_HashBuf(unsigned char *dest, const unsigned char *src, PRUint32 src_length)
{
- if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
- return SECFailure;
- return (vector->p_MD5_HashBuf)(dest, src, 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)();
+ if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
+ return NULL;
+ return (vector->p_MD5_NewContext)();
}
-void
+void
MD5_DestroyContext(MD5Context *cx, PRBool freeit)
{
- if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
- return;
- (vector->p_MD5_DestroyContext)(cx, freeit);
+ if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
+ return;
+ (vector->p_MD5_DestroyContext)(cx, freeit);
}
-void
+void
MD5_Begin(MD5Context *cx)
{
- if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
- return;
- (vector->p_MD5_Begin)(cx);
+ if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
+ return;
+ (vector->p_MD5_Begin)(cx);
}
-void
+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);
+ if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
+ return;
+ (vector->p_MD5_Update)(cx, input, inputLen);
}
-void
+void
MD5_End(MD5Context *cx, unsigned char *digest,
- unsigned int *digestLen, unsigned int maxDigestLen)
+ unsigned int *digestLen, unsigned int maxDigestLen)
{
- if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
- return;
- (vector->p_MD5_End)(cx, digest, digestLen, maxDigestLen);
+ if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
+ return;
+ (vector->p_MD5_End)(cx, digest, digestLen, maxDigestLen);
}
-unsigned int
+unsigned int
MD5_FlattenSize(MD5Context *cx)
{
- if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
- return 0;
- return (vector->p_MD5_FlattenSize)(cx);
+ if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
+ return 0;
+ return (vector->p_MD5_FlattenSize)(cx);
}
-SECStatus
-MD5_Flatten(MD5Context *cx,unsigned char *space)
+SECStatus
+MD5_Flatten(MD5Context *cx, unsigned char *space)
{
- if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
- return SECFailure;
- return (vector->p_MD5_Flatten)(cx, space);
+ if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
+ return SECFailure;
+ return (vector->p_MD5_Flatten)(cx, space);
}
-MD5Context *
+MD5Context *
MD5_Resurrect(unsigned char *space, void *arg)
{
- if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
- return NULL;
- return (vector->p_MD5_Resurrect)(space, arg);
+ if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
+ return NULL;
+ return (vector->p_MD5_Resurrect)(space, arg);
}
-void
+void
MD5_TraceState(MD5Context *cx)
{
- if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
- return ;
- (vector->p_MD5_TraceState)(cx);
+ if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
+ return;
+ (vector->p_MD5_TraceState)(cx);
}
-SECStatus
+SECStatus
MD2_Hash(unsigned char *dest, const char *src)
{
- if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
- return SECFailure;
- return (vector->p_MD2_Hash)(dest, 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)();
+ if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
+ return NULL;
+ return (vector->p_MD2_NewContext)();
}
-void
+void
MD2_DestroyContext(MD2Context *cx, PRBool freeit)
{
- if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
- return ;
- (vector->p_MD2_DestroyContext)(cx, freeit);
+ if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
+ return;
+ (vector->p_MD2_DestroyContext)(cx, freeit);
}
-void
+void
MD2_Begin(MD2Context *cx)
{
- if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
- return ;
- (vector->p_MD2_Begin)(cx);
+ if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
+ return;
+ (vector->p_MD2_Begin)(cx);
}
-void
+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);
+ if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
+ return;
+ (vector->p_MD2_Update)(cx, input, inputLen);
}
-void
+void
MD2_End(MD2Context *cx, unsigned char *digest,
- unsigned int *digestLen, unsigned int maxDigestLen)
+ unsigned int *digestLen, unsigned int maxDigestLen)
{
- if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
- return ;
- (vector->p_MD2_End)(cx, digest, digestLen, maxDigestLen);
+ if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
+ return;
+ (vector->p_MD2_End)(cx, digest, digestLen, maxDigestLen);
}
-unsigned int
+unsigned int
MD2_FlattenSize(MD2Context *cx)
{
- if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
- return 0;
- return (vector->p_MD2_FlattenSize)(cx);
+ if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
+ return 0;
+ return (vector->p_MD2_FlattenSize)(cx);
}
-SECStatus
-MD2_Flatten(MD2Context *cx,unsigned char *space)
+SECStatus
+MD2_Flatten(MD2Context *cx, unsigned char *space)
{
- if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
- return SECFailure;
- return (vector->p_MD2_Flatten)(cx, space);
+ if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
+ return SECFailure;
+ return (vector->p_MD2_Flatten)(cx, space);
}
-MD2Context *
+MD2Context *
MD2_Resurrect(unsigned char *space, void *arg)
{
- if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
- return NULL;
- return (vector->p_MD2_Resurrect)(space, arg);
+ if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
+ return NULL;
+ return (vector->p_MD2_Resurrect)(space, arg);
}
-
-SECStatus
+SECStatus
SHA1_Hash(unsigned char *dest, const char *src)
{
- if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
- return SECFailure;
- return (vector->p_SHA1_Hash)(dest, src);
+ if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
+ return SECFailure;
+ return (vector->p_SHA1_Hash)(dest, src);
}
-SECStatus
+SECStatus
SHA1_HashBuf(unsigned char *dest, const unsigned char *src, PRUint32 src_length)
{
- if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
- return SECFailure;
- return (vector->p_SHA1_HashBuf)(dest, src, 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)();
+ if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
+ return NULL;
+ return (vector->p_SHA1_NewContext)();
}
-void
+void
SHA1_DestroyContext(SHA1Context *cx, PRBool freeit)
{
- if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
- return ;
- (vector->p_SHA1_DestroyContext)(cx, freeit);
+ if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
+ return;
+ (vector->p_SHA1_DestroyContext)(cx, freeit);
}
-void
+void
SHA1_Begin(SHA1Context *cx)
{
- if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
- return ;
- (vector->p_SHA1_Begin)(cx);
+ if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
+ return;
+ (vector->p_SHA1_Begin)(cx);
}
-void
+void
SHA1_Update(SHA1Context *cx, const unsigned char *input,
- unsigned int inputLen)
+ unsigned int inputLen)
{
- if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
- return ;
- (vector->p_SHA1_Update)(cx, input, inputLen);
+ if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
+ return;
+ (vector->p_SHA1_Update)(cx, input, inputLen);
}
-void
+void
SHA1_End(SHA1Context *cx, unsigned char *digest,
- unsigned int *digestLen, unsigned int maxDigestLen)
+ unsigned int *digestLen, unsigned int maxDigestLen)
{
- if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
- return ;
- (vector->p_SHA1_End)(cx, digest, digestLen, maxDigestLen);
+ if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
+ return;
+ (vector->p_SHA1_End)(cx, digest, digestLen, maxDigestLen);
}
-void
+void
SHA1_TraceState(SHA1Context *cx)
{
- if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
- return ;
- (vector->p_SHA1_TraceState)(cx);
+ if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
+ return;
+ (vector->p_SHA1_TraceState)(cx);
}
-unsigned int
+unsigned int
SHA1_FlattenSize(SHA1Context *cx)
{
- if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
- return 0;
- return (vector->p_SHA1_FlattenSize)(cx);
+ if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
+ return 0;
+ return (vector->p_SHA1_FlattenSize)(cx);
}
-SECStatus
-SHA1_Flatten(SHA1Context *cx,unsigned char *space)
+SECStatus
+SHA1_Flatten(SHA1Context *cx, unsigned char *space)
{
- if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
- return SECFailure;
- return (vector->p_SHA1_Flatten)(cx, space);
+ if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
+ return SECFailure;
+ return (vector->p_SHA1_Flatten)(cx, space);
}
-SHA1Context *
+SHA1Context *
SHA1_Resurrect(unsigned char *space, void *arg)
{
- if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
- return NULL;
- return (vector->p_SHA1_Resurrect)(space, arg);
+ if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
+ return NULL;
+ return (vector->p_SHA1_Resurrect)(space, arg);
}
-SECStatus
+SECStatus
RNG_RNGInit(void)
{
- if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
- return SECFailure;
- return (vector->p_RNG_RNGInit)();
+ if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
+ return SECFailure;
+ return (vector->p_RNG_RNGInit)();
}
-SECStatus
+SECStatus
RNG_RandomUpdate(const void *data, size_t bytes)
{
- if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
- return SECFailure;
- return (vector->p_RNG_RandomUpdate)(data, bytes);
+ if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
+ return SECFailure;
+ return (vector->p_RNG_RandomUpdate)(data, bytes);
}
-SECStatus
+SECStatus
RNG_GenerateGlobalRandomBytes(void *dest, size_t len)
{
- if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
- return SECFailure;
- return (vector->p_RNG_GenerateGlobalRandomBytes)(dest, len);
+ if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
+ return SECFailure;
+ return (vector->p_RNG_GenerateGlobalRandomBytes)(dest, len);
}
-void
+void
RNG_RNGShutdown(void)
{
- if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
- return ;
- (vector->p_RNG_RNGShutdown)();
+ 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);
+ 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)
+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);
+ 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)
+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);
+ if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
+ return SECFailure;
+ return (vector->p_PQG_VerifyParams)(params, vfy, result);
}
-void
+void
PQG_DestroyParams(PQGParams *params)
{
- if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
- return;
- (vector->p_PQG_DestroyParams)(params);
+ if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
+ return;
+ (vector->p_PQG_DestroyParams)(params);
}
-void
+void
PQG_DestroyVerify(PQGVerify *vfy)
{
- if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
- return;
- (vector->p_PQG_DestroyVerify)(vfy);
+ if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
+ return;
+ (vector->p_PQG_DestroyVerify)(vfy);
}
-void
+void
BL_Cleanup(void)
{
- if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
- return;
- (vector->p_BL_Cleanup)();
+ 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) {
+ /* 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;
+ disableUnload = PR_GetEnvSecure("NSS_DISABLE_UNLOAD");
+ if (blLib && !disableUnload) {
#ifdef DEBUG
- PRStatus status = PR_UnloadLibrary(blLib);
- PORT_Assert(PR_SUCCESS == status);
+ PRStatus status = PR_UnloadLibrary(blLib);
+ PORT_Assert(PR_SUCCESS == status);
#else
- PR_UnloadLibrary(blLib);
+ PR_UnloadLibrary(blLib);
#endif
- }
- blLib = NULL;
- }
- loadFreeBLOnce = pristineCallOnce;
+ }
+ blLib = NULL;
+ loadFreeBLOnce = pristineCallOnce;
}
/* ============== New for 3.003 =============================== */
-SECStatus
+SECStatus
SHA256_Hash(unsigned char *dest, const char *src)
{
- if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
- return SECFailure;
- return (vector->p_SHA256_Hash)(dest, src);
+ if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
+ return SECFailure;
+ return (vector->p_SHA256_Hash)(dest, src);
}
-SECStatus
+SECStatus
SHA256_HashBuf(unsigned char *dest, const unsigned char *src, PRUint32 src_length)
{
- if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
- return SECFailure;
- return (vector->p_SHA256_HashBuf)(dest, src, 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)();
+ if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
+ return NULL;
+ return (vector->p_SHA256_NewContext)();
}
-void
+void
SHA256_DestroyContext(SHA256Context *cx, PRBool freeit)
{
- if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
- return ;
- (vector->p_SHA256_DestroyContext)(cx, freeit);
+ if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
+ return;
+ (vector->p_SHA256_DestroyContext)(cx, freeit);
}
-void
+void
SHA256_Begin(SHA256Context *cx)
{
- if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
- return ;
- (vector->p_SHA256_Begin)(cx);
+ if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
+ return;
+ (vector->p_SHA256_Begin)(cx);
}
-void
+void
SHA256_Update(SHA256Context *cx, const unsigned char *input,
- unsigned int inputLen)
+ unsigned int inputLen)
{
- if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
- return ;
- (vector->p_SHA256_Update)(cx, input, inputLen);
+ if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
+ return;
+ (vector->p_SHA256_Update)(cx, input, inputLen);
}
-void
+void
SHA256_End(SHA256Context *cx, unsigned char *digest,
- unsigned int *digestLen, unsigned int maxDigestLen)
+ unsigned int *digestLen, unsigned int maxDigestLen)
{
- if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
- return ;
- (vector->p_SHA256_End)(cx, digest, digestLen, maxDigestLen);
+ if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
+ return;
+ (vector->p_SHA256_End)(cx, digest, digestLen, maxDigestLen);
}
-void
+void
SHA256_TraceState(SHA256Context *cx)
{
- if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
- return ;
- (vector->p_SHA256_TraceState)(cx);
+ if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
+ return;
+ (vector->p_SHA256_TraceState)(cx);
}
-unsigned int
+unsigned int
SHA256_FlattenSize(SHA256Context *cx)
{
- if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
- return 0;
- return (vector->p_SHA256_FlattenSize)(cx);
+ if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
+ return 0;
+ return (vector->p_SHA256_FlattenSize)(cx);
}
-SECStatus
-SHA256_Flatten(SHA256Context *cx,unsigned char *space)
+SECStatus
+SHA256_Flatten(SHA256Context *cx, unsigned char *space)
{
- if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
- return SECFailure;
- return (vector->p_SHA256_Flatten)(cx, space);
+ if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
+ return SECFailure;
+ return (vector->p_SHA256_Flatten)(cx, space);
}
-SHA256Context *
+SHA256Context *
SHA256_Resurrect(unsigned char *space, void *arg)
{
- if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
- return NULL;
- return (vector->p_SHA256_Resurrect)(space, arg);
+ if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
+ return NULL;
+ return (vector->p_SHA256_Resurrect)(space, arg);
}
-SECStatus
+SECStatus
SHA512_Hash(unsigned char *dest, const char *src)
{
- if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
- return SECFailure;
- return (vector->p_SHA512_Hash)(dest, src);
+ if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
+ return SECFailure;
+ return (vector->p_SHA512_Hash)(dest, src);
}
-SECStatus
+SECStatus
SHA512_HashBuf(unsigned char *dest, const unsigned char *src, PRUint32 src_length)
{
- if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
- return SECFailure;
- return (vector->p_SHA512_HashBuf)(dest, src, 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)();
+ if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
+ return NULL;
+ return (vector->p_SHA512_NewContext)();
}
-void
+void
SHA512_DestroyContext(SHA512Context *cx, PRBool freeit)
{
- if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
- return ;
- (vector->p_SHA512_DestroyContext)(cx, freeit);
+ if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
+ return;
+ (vector->p_SHA512_DestroyContext)(cx, freeit);
}
-void
+void
SHA512_Begin(SHA512Context *cx)
{
- if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
- return ;
- (vector->p_SHA512_Begin)(cx);
+ if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
+ return;
+ (vector->p_SHA512_Begin)(cx);
}
-void
+void
SHA512_Update(SHA512Context *cx, const unsigned char *input,
- unsigned int inputLen)
+ unsigned int inputLen)
{
- if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
- return ;
- (vector->p_SHA512_Update)(cx, input, inputLen);
+ if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
+ return;
+ (vector->p_SHA512_Update)(cx, input, inputLen);
}
-void
+void
SHA512_End(SHA512Context *cx, unsigned char *digest,
- unsigned int *digestLen, unsigned int maxDigestLen)
+ unsigned int *digestLen, unsigned int maxDigestLen)
{
- if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
- return ;
- (vector->p_SHA512_End)(cx, digest, digestLen, maxDigestLen);
+ if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
+ return;
+ (vector->p_SHA512_End)(cx, digest, digestLen, maxDigestLen);
}
-void
+void
SHA512_TraceState(SHA512Context *cx)
{
- if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
- return ;
- (vector->p_SHA512_TraceState)(cx);
+ if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
+ return;
+ (vector->p_SHA512_TraceState)(cx);
}
-unsigned int
+unsigned int
SHA512_FlattenSize(SHA512Context *cx)
{
- if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
- return 0;
- return (vector->p_SHA512_FlattenSize)(cx);
+ if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
+ return 0;
+ return (vector->p_SHA512_FlattenSize)(cx);
}
-SECStatus
-SHA512_Flatten(SHA512Context *cx,unsigned char *space)
+SECStatus
+SHA512_Flatten(SHA512Context *cx, unsigned char *space)
{
- if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
- return SECFailure;
- return (vector->p_SHA512_Flatten)(cx, space);
+ if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
+ return SECFailure;
+ return (vector->p_SHA512_Flatten)(cx, space);
}
-SHA512Context *
+SHA512Context *
SHA512_Resurrect(unsigned char *space, void *arg)
{
- if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
- return NULL;
- return (vector->p_SHA512_Resurrect)(space, arg);
+ if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
+ return NULL;
+ return (vector->p_SHA512_Resurrect)(space, arg);
}
-
-SECStatus
+SECStatus
SHA384_Hash(unsigned char *dest, const char *src)
{
- if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
- return SECFailure;
- return (vector->p_SHA384_Hash)(dest, src);
+ if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
+ return SECFailure;
+ return (vector->p_SHA384_Hash)(dest, src);
}
-SECStatus
+SECStatus
SHA384_HashBuf(unsigned char *dest, const unsigned char *src, PRUint32 src_length)
{
- if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
- return SECFailure;
- return (vector->p_SHA384_HashBuf)(dest, src, 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)();
+ if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
+ return NULL;
+ return (vector->p_SHA384_NewContext)();
}
-void
+void
SHA384_DestroyContext(SHA384Context *cx, PRBool freeit)
{
- if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
- return ;
- (vector->p_SHA384_DestroyContext)(cx, freeit);
+ if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
+ return;
+ (vector->p_SHA384_DestroyContext)(cx, freeit);
}
-void
+void
SHA384_Begin(SHA384Context *cx)
{
- if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
- return ;
- (vector->p_SHA384_Begin)(cx);
+ if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
+ return;
+ (vector->p_SHA384_Begin)(cx);
}
-void
+void
SHA384_Update(SHA384Context *cx, const unsigned char *input,
- unsigned int inputLen)
+ unsigned int inputLen)
{
- if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
- return ;
- (vector->p_SHA384_Update)(cx, input, inputLen);
+ if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
+ return;
+ (vector->p_SHA384_Update)(cx, input, inputLen);
}
-void
+void
SHA384_End(SHA384Context *cx, unsigned char *digest,
- unsigned int *digestLen, unsigned int maxDigestLen)
+ unsigned int *digestLen, unsigned int maxDigestLen)
{
- if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
- return ;
- (vector->p_SHA384_End)(cx, digest, digestLen, maxDigestLen);
+ if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
+ return;
+ (vector->p_SHA384_End)(cx, digest, digestLen, maxDigestLen);
}
-void
+void
SHA384_TraceState(SHA384Context *cx)
{
- if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
- return ;
- (vector->p_SHA384_TraceState)(cx);
+ if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
+ return;
+ (vector->p_SHA384_TraceState)(cx);
}
-unsigned int
+unsigned int
SHA384_FlattenSize(SHA384Context *cx)
{
- if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
- return 0;
- return (vector->p_SHA384_FlattenSize)(cx);
+ if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
+ return 0;
+ return (vector->p_SHA384_FlattenSize)(cx);
}
-SECStatus
-SHA384_Flatten(SHA384Context *cx,unsigned char *space)
+SECStatus
+SHA384_Flatten(SHA384Context *cx, unsigned char *space)
{
- if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
- return SECFailure;
- return (vector->p_SHA384_Flatten)(cx, space);
+ if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
+ return SECFailure;
+ return (vector->p_SHA384_Flatten)(cx, space);
}
-SHA384Context *
+SHA384Context *
SHA384_Resurrect(unsigned char *space, void *arg)
{
- if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
- return NULL;
- return (vector->p_SHA384_Resurrect)(space, 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,
+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);
+ if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
+ return NULL;
+ return vector->p_AESKeyWrap_CreateContext(key, iv, encrypt, keylen);
}
-void
+void
AESKeyWrap_DestroyContext(AESKeyWrapContext *cx, PRBool freeit)
{
- if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
- return;
- vector->p_AESKeyWrap_DestroyContext(cx, freeit);
+ if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
+ return;
+ vector->p_AESKeyWrap_DestroyContext(cx, freeit);
}
-SECStatus
+SECStatus
AESKeyWrap_Encrypt(AESKeyWrapContext *cx, unsigned char *output,
- unsigned int *outputLen, unsigned int maxOutputLen,
- const unsigned char *input, unsigned int inputLen)
+ 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);
+ if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
+ return SECFailure;
+ return vector->p_AESKeyWrap_Encrypt(cx, output, outputLen, maxOutputLen,
+ input, inputLen);
}
-SECStatus
+SECStatus
AESKeyWrap_Decrypt(AESKeyWrapContext *cx, unsigned char *output,
- unsigned int *outputLen, unsigned int maxOutputLen,
- const unsigned char *input, unsigned int inputLen)
+ 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);
+ 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);
+ if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
+ return PR_FALSE;
+ return vector->p_BLAPI_SHVerify(name, addr);
}
/*
@@ -1247,75 +1153,75 @@ BLAPI_SHVerify(const char *name, PRFuncPtr addr)
PRBool
BLAPI_VerifySelf(const char *name)
{
- PORT_Assert(!name);
- if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
- return PR_FALSE;
- return vector->p_BLAPI_VerifySelf(libraryName);
+ 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)
+SECStatus
+EC_NewKey(ECParams *params, ECPrivateKey **privKey)
{
- if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
- return SECFailure;
- return (vector->p_EC_NewKey)( params, 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)
+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 );
+ if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
+ return SECFailure;
+ return (vector->p_EC_NewKeyFromSeed)(params, privKey, seed, seedlen);
}
-SECStatus
-EC_ValidatePublicKey(ECParams * params, SECItem * publicValue)
+SECStatus
+EC_ValidatePublicKey(ECParams *params, SECItem *publicValue)
{
- if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
- return SECFailure;
- return (vector->p_EC_ValidatePublicKey)( params, 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)
+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 );
+ 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)
+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 );
+ 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)
+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 );
+ 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)
+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 );
+ if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
+ return SECFailure;
+ return (vector->p_ECDSA_SignDigestWithSeed)(key, signature, digest,
+ seed, seedlen);
}
/* ============== New for 3.008 =============================== */
@@ -1323,247 +1229,245 @@ ECDSA_SignDigestWithSeed(ECPrivateKey * key, SECItem * signature,
AESContext *
AES_AllocateContext(void)
{
- if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
- return NULL;
- return (vector->p_AES_AllocateContext)();
+ 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)();
+ 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)();
+ 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)();
+ 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)();
+ 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)
+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);
+ 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)
+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);
+ 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)
+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);
+ 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)
+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);
+ 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)
+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);
+ 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)
+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);
+ if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
+ return SECFailure;
+ return (vector->p_RC4_InitContext)(cx, key, keylen, x1, x2, x3, x4);
}
-void
+void
MD2_Clone(MD2Context *dest, MD2Context *src)
{
- if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
- return;
- (vector->p_MD2_Clone)(dest, src);
+ if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
+ return;
+ (vector->p_MD2_Clone)(dest, src);
}
-void
+void
MD5_Clone(MD5Context *dest, MD5Context *src)
{
- if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
- return;
- (vector->p_MD5_Clone)(dest, src);
+ if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
+ return;
+ (vector->p_MD5_Clone)(dest, src);
}
-void
+void
SHA1_Clone(SHA1Context *dest, SHA1Context *src)
{
- if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
- return;
- (vector->p_SHA1_Clone)(dest, src);
+ if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
+ return;
+ (vector->p_SHA1_Clone)(dest, src);
}
-void
+void
SHA256_Clone(SHA256Context *dest, SHA256Context *src)
{
- if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
- return;
- (vector->p_SHA256_Clone)(dest, src);
+ if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
+ return;
+ (vector->p_SHA256_Clone)(dest, src);
}
-void
+void
SHA384_Clone(SHA384Context *dest, SHA384Context *src)
{
- if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
- return;
- (vector->p_SHA384_Clone)(dest, src);
+ if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
+ return;
+ (vector->p_SHA384_Clone)(dest, src);
}
-void
+void
SHA512_Clone(SHA512Context *dest, SHA512Context *src)
{
- if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
- return;
- (vector->p_SHA512_Clone)(dest, 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)
+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);
+ 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);
+ 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);
+ 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)
+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);
+ 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)
+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);
+ 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);
+ if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
+ return;
+ (vector->p_HMAC_Begin)(cx);
}
-void
+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);
+ 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)
+ 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);
+ 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);
+ 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)();
-
+ 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);
+ if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
+ return SECFailure;
+ return (vector->p_FIPS186Change_GenerateX)(XKEY, XSEEDj, x_j);
}
SECStatus
@@ -1571,116 +1475,116 @@ 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);
+ 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)
+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);
+ 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)();
+ 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)
+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 NULL;
return (vector->p_Camellia_CreateContext)(key, iv, mode, encrypt, keylen);
}
-void
+void
Camellia_DestroyContext(CamelliaContext *cx, PRBool freeit)
{
if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
- return ;
+ return;
(vector->p_Camellia_DestroyContext)(cx, freeit);
}
-SECStatus
+SECStatus
Camellia_Encrypt(CamelliaContext *cx, unsigned char *output,
- unsigned int *outputLen, unsigned int maxOutputLen,
- const unsigned char *input, unsigned int inputLen)
+ 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);
+ return SECFailure;
+ return (vector->p_Camellia_Encrypt)(cx, output, outputLen, maxOutputLen,
+ input, inputLen);
}
-SECStatus
+SECStatus
Camellia_Decrypt(CamelliaContext *cx, unsigned char *output,
- unsigned int *outputLen, unsigned int maxOutputLen,
- const unsigned char *input, unsigned int inputLen)
+ 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);
+ return SECFailure;
+ return (vector->p_Camellia_Decrypt)(cx, output, outputLen, maxOutputLen,
+ input, inputLen);
}
-void BL_SetForkState(PRBool forked)
+void
+BL_SetForkState(PRBool forked)
{
if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
- return;
+ 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)
+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);
+ 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)
+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);
+ 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)
+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);
+ 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 SECFailure;
return (vector->p_PRNGTEST_Uninstantiate)();
}
@@ -1688,16 +1592,15 @@ SECStatus
RSA_PopulatePrivateKey(RSAPrivateKey *key)
{
if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
- return SECFailure;
+ 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)
+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;
@@ -1706,21 +1609,21 @@ JPAKE_Sign(PLArenaPool * arena, const PQGParams * pqg, HASH_HashType hashType,
}
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)
+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,
+ 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)
+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;
@@ -1728,146 +1631,146 @@ JPAKE_Round2(PLArenaPool * arena, const SECItem * p, const SECItem *q,
}
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)
+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
+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);
+ if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
+ return SECFailure;
+ return (vector->p_TLS_P_hash)(hashAlg, secret, label, seed, result, isFIPS);
}
-SECStatus
+SECStatus
SHA224_Hash(unsigned char *dest, const char *src)
{
- if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
- return SECFailure;
- return (vector->p_SHA224_Hash)(dest, 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, PRUint32 src_length)
{
- if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
- return SECFailure;
- return (vector->p_SHA224_HashBuf)(dest, src, 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)();
+ 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);
+ 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);
+ if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
+ return;
+ (vector->p_SHA224_Begin)(cx);
}
void
SHA224_Update(SHA224Context *cx, const unsigned char *input,
- unsigned int inputLen)
+ unsigned int inputLen)
{
- if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
- return;
- (vector->p_SHA224_Update)(cx, input, 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)
+ unsigned int *digestLen, unsigned int maxDigestLen)
{
- if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
- return;
- (vector->p_SHA224_End)(cx, digest, digestLen, 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);
+ 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);
+ if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
+ return 0;
+ return (vector->p_SHA224_FlattenSize)(cx);
}
SECStatus
-SHA224_Flatten(SHA224Context *cx,unsigned char *space)
+SHA224_Flatten(SHA224Context *cx, unsigned char *space)
{
- if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
- return SECFailure;
- return (vector->p_SHA224_Flatten)(cx, 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);
+ if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
+ return NULL;
+ return (vector->p_SHA224_Resurrect)(space, arg);
}
-void
+void
SHA224_Clone(SHA224Context *dest, SHA224Context *src)
{
- if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
- return;
- (vector->p_SHA224_Clone)(dest, 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);
+ 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,
+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);
+ 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();
+ if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
+ return SECFailure;
+ return vector->p_PRNGTEST_RunHealthTests();
}
SECStatus
@@ -1884,14 +1787,14 @@ SSLv3_MAC_ConstantTime(
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);
+ 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
@@ -1908,223 +1811,308 @@ HMAC_ConstantTime(
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);
+ if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
+ return SECFailure;
+ return (vector->p_HMAC_ConstantTime)(
+ result, resultLen, maxResultLen,
+ hashObj,
+ secret, secretLen,
+ header, headerLen,
+ body, bodyLen, bodyTotalLen);
}
-SECStatus RSA_SignRaw(RSAPrivateKey *key,
- 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_RSA_SignRaw)(key, output, outputLen, maxOutputLen, input,
- inputLen);
-}
-
-SECStatus RSA_CheckSignRaw(RSAPublicKey *key,
- const unsigned char *sig,
- unsigned int sigLen,
- const unsigned char *hash,
- unsigned int hashLen) {
- if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
- return SECFailure;
- return (vector->p_RSA_CheckSignRaw)(key, sig, sigLen, hash, hashLen);
-}
-
-SECStatus RSA_CheckSignRecoverRaw(RSAPublicKey *key,
- unsigned char *data,
- unsigned int *dataLen,
- unsigned int maxDataLen,
- const unsigned char *sig,
- unsigned int sigLen) {
- if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
- return SECFailure;
- return (vector->p_RSA_CheckSignRecoverRaw)(key, data, dataLen, maxDataLen,
- sig, sigLen);
-}
-
-SECStatus RSA_EncryptRaw(RSAPublicKey *key,
- 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_RSA_EncryptRaw)(key, output, outputLen, maxOutputLen,
- input, inputLen);
-}
-
-SECStatus RSA_DecryptRaw(RSAPrivateKey *key,
- 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_RSA_DecryptRaw)(key, output, outputLen, maxOutputLen,
- input, inputLen);
-
-}
-
-SECStatus RSA_EncryptOAEP(RSAPublicKey *key,
- HASH_HashType hashAlg,
- HASH_HashType maskHashAlg,
- const unsigned char *label,
- unsigned int labelLen,
- const unsigned char *seed,
- unsigned int seedLen,
- 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_RSA_EncryptOAEP)(key, hashAlg, maskHashAlg, label,
- labelLen, seed, seedLen, output,
- outputLen, maxOutputLen, input, inputLen);
-}
-
-SECStatus RSA_DecryptOAEP(RSAPrivateKey *key,
- HASH_HashType hashAlg,
- HASH_HashType maskHashAlg,
- const unsigned char *label,
- unsigned int labelLen,
- 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_RSA_DecryptOAEP)(key, hashAlg, maskHashAlg, label,
- labelLen, output, outputLen,
- maxOutputLen, input, inputLen);
-}
-
-SECStatus RSA_EncryptBlock(RSAPublicKey *key,
- 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_RSA_EncryptBlock)(key, output, outputLen, maxOutputLen,
+SECStatus
+RSA_SignRaw(RSAPrivateKey *key,
+ 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_RSA_SignRaw)(key, output, outputLen, maxOutputLen, input,
+ inputLen);
+}
+
+SECStatus
+RSA_CheckSignRaw(RSAPublicKey *key,
+ const unsigned char *sig,
+ unsigned int sigLen,
+ const unsigned char *hash,
+ unsigned int hashLen)
+{
+ if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
+ return SECFailure;
+ return (vector->p_RSA_CheckSignRaw)(key, sig, sigLen, hash, hashLen);
+}
+
+SECStatus
+RSA_CheckSignRecoverRaw(RSAPublicKey *key,
+ unsigned char *data,
+ unsigned int *dataLen,
+ unsigned int maxDataLen,
+ const unsigned char *sig,
+ unsigned int sigLen)
+{
+ if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
+ return SECFailure;
+ return (vector->p_RSA_CheckSignRecoverRaw)(key, data, dataLen, maxDataLen,
+ sig, sigLen);
+}
+
+SECStatus
+RSA_EncryptRaw(RSAPublicKey *key,
+ 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_RSA_EncryptRaw)(key, output, outputLen, maxOutputLen,
input, inputLen);
}
-SECStatus RSA_DecryptBlock(RSAPrivateKey *key,
- 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_RSA_DecryptBlock)(key, output, outputLen, maxOutputLen,
+SECStatus
+RSA_DecryptRaw(RSAPrivateKey *key,
+ 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_RSA_DecryptRaw)(key, output, outputLen, maxOutputLen,
input, inputLen);
}
-SECStatus RSA_SignPSS(RSAPrivateKey *key,
- HASH_HashType hashAlg,
- HASH_HashType maskHashAlg,
- const unsigned char *salt,
- unsigned int saltLen,
- 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_RSA_SignPSS)(key, hashAlg, maskHashAlg, salt, saltLen,
- output, outputLen, maxOutputLen, input,
- inputLen);
-}
-
-SECStatus RSA_CheckSignPSS(RSAPublicKey *key,
- HASH_HashType hashAlg,
- HASH_HashType maskHashAlg,
- unsigned int saltLen,
- const unsigned char *sig,
- unsigned int sigLen,
- const unsigned char *hash,
- unsigned int hashLen) {
- if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
- return SECFailure;
- return (vector->p_RSA_CheckSignPSS)(key, hashAlg, maskHashAlg, saltLen,
- sig, sigLen, hash, hashLen);
-}
-
-SECStatus RSA_Sign(RSAPrivateKey *key,
- 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_RSA_Sign)(key, output, outputLen, maxOutputLen, input,
- inputLen);
-}
-
-SECStatus RSA_CheckSign(RSAPublicKey *key,
- const unsigned char *sig,
- unsigned int sigLen,
- const unsigned char *data,
- unsigned int dataLen) {
- if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
- return SECFailure;
- return (vector->p_RSA_CheckSign)(key, sig, sigLen, data, dataLen);
+SECStatus
+RSA_EncryptOAEP(RSAPublicKey *key,
+ HASH_HashType hashAlg,
+ HASH_HashType maskHashAlg,
+ const unsigned char *label,
+ unsigned int labelLen,
+ const unsigned char *seed,
+ unsigned int seedLen,
+ 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_RSA_EncryptOAEP)(key, hashAlg, maskHashAlg, label,
+ labelLen, seed, seedLen, output,
+ outputLen, maxOutputLen, input, inputLen);
+}
+SECStatus
+RSA_DecryptOAEP(RSAPrivateKey *key,
+ HASH_HashType hashAlg,
+ HASH_HashType maskHashAlg,
+ const unsigned char *label,
+ unsigned int labelLen,
+ 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_RSA_DecryptOAEP)(key, hashAlg, maskHashAlg, label,
+ labelLen, output, outputLen,
+ maxOutputLen, input, inputLen);
}
-SECStatus RSA_CheckSignRecover(RSAPublicKey *key,
- unsigned char *output,
- unsigned int *outputLen,
- unsigned int maxOutputLen,
- const unsigned char *sig,
- unsigned int sigLen) {
- if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
- return SECFailure;
- return (vector->p_RSA_CheckSignRecover)(key, output, outputLen, maxOutputLen,
- sig, sigLen);
+SECStatus
+RSA_EncryptBlock(RSAPublicKey *key,
+ 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_RSA_EncryptBlock)(key, output, outputLen, maxOutputLen,
+ input, inputLen);
}
-SECStatus EC_FillParams(PLArenaPool *arena,
- const SECItem *encodedParams,
- ECParams *params)
+SECStatus
+RSA_DecryptBlock(RSAPrivateKey *key,
+ 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_EC_FillParams)(arena, encodedParams, params);
+ if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
+ return SECFailure;
+ return (vector->p_RSA_DecryptBlock)(key, output, outputLen, maxOutputLen,
+ input, inputLen);
}
-SECStatus EC_DecodeParams(const SECItem *encodedParams,
- ECParams **ecparams)
+SECStatus
+RSA_SignPSS(RSAPrivateKey *key,
+ HASH_HashType hashAlg,
+ HASH_HashType maskHashAlg,
+ const unsigned char *salt,
+ unsigned int saltLen,
+ 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_EC_DecodeParams)(encodedParams, ecparams);
+ if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
+ return SECFailure;
+ return (vector->p_RSA_SignPSS)(key, hashAlg, maskHashAlg, salt, saltLen,
+ output, outputLen, maxOutputLen, input,
+ inputLen);
}
-SECStatus EC_CopyParams(PLArenaPool *arena, ECParams *dstParams,
- const ECParams *srcParams)
+SECStatus
+RSA_CheckSignPSS(RSAPublicKey *key,
+ HASH_HashType hashAlg,
+ HASH_HashType maskHashAlg,
+ unsigned int saltLen,
+ const unsigned char *sig,
+ unsigned int sigLen,
+ const unsigned char *hash,
+ unsigned int hashLen)
+{
+ if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
+ return SECFailure;
+ return (vector->p_RSA_CheckSignPSS)(key, hashAlg, maskHashAlg, saltLen,
+ sig, sigLen, hash, hashLen);
+}
+
+SECStatus
+RSA_Sign(RSAPrivateKey *key,
+ 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_RSA_Sign)(key, output, outputLen, maxOutputLen, input,
+ inputLen);
+}
+
+SECStatus
+RSA_CheckSign(RSAPublicKey *key,
+ const unsigned char *sig,
+ unsigned int sigLen,
+ const unsigned char *data,
+ unsigned int dataLen)
+{
+ if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
+ return SECFailure;
+ return (vector->p_RSA_CheckSign)(key, sig, sigLen, data, dataLen);
+}
+
+SECStatus
+RSA_CheckSignRecover(RSAPublicKey *key,
+ unsigned char *output,
+ unsigned int *outputLen,
+ unsigned int maxOutputLen,
+ const unsigned char *sig,
+ unsigned int sigLen)
{
- if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
- return SECFailure;
- return (vector->p_EC_CopyParams)(arena, dstParams, srcParams);
+ if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
+ return SECFailure;
+ return (vector->p_RSA_CheckSignRecover)(key, output, outputLen, maxOutputLen,
+ sig, sigLen);
}
+SECStatus
+EC_FillParams(PLArenaPool *arena,
+ const SECItem *encodedParams,
+ ECParams *params)
+{
+ if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
+ return SECFailure;
+ return (vector->p_EC_FillParams)(arena, encodedParams, params);
+}
+
+SECStatus
+EC_DecodeParams(const SECItem *encodedParams,
+ ECParams **ecparams)
+{
+ if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
+ return SECFailure;
+ return (vector->p_EC_DecodeParams)(encodedParams, ecparams);
+}
+
+SECStatus
+EC_CopyParams(PLArenaPool *arena, ECParams *dstParams,
+ const ECParams *srcParams)
+{
+ if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
+ return SECFailure;
+ return (vector->p_EC_CopyParams)(arena, dstParams, srcParams);
+}
+
+SECStatus
+ChaCha20Poly1305_InitContext(ChaCha20Poly1305Context *ctx,
+ const unsigned char *key, unsigned int keyLen,
+ unsigned int tagLen)
+{
+ if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
+ return SECFailure;
+ return (vector->p_ChaCha20Poly1305_InitContext)(ctx, key, keyLen, tagLen);
+}
+
+ChaCha20Poly1305Context *
+ChaCha20Poly1305_CreateContext(const unsigned char *key, unsigned int keyLen,
+ unsigned int tagLen)
+{
+ if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
+ return NULL;
+ return (vector->p_ChaCha20Poly1305_CreateContext)(key, keyLen, tagLen);
+}
+
+void
+ChaCha20Poly1305_DestroyContext(ChaCha20Poly1305Context *ctx, PRBool freeit)
+{
+ if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
+ return;
+ (vector->p_ChaCha20Poly1305_DestroyContext)(ctx, freeit);
+}
+
+SECStatus
+ChaCha20Poly1305_Seal(const ChaCha20Poly1305Context *ctx,
+ unsigned char *output, unsigned int *outputLen,
+ unsigned int maxOutputLen,
+ const unsigned char *input, unsigned int inputLen,
+ const unsigned char *nonce, unsigned int nonceLen,
+ const unsigned char *ad, unsigned int adLen)
+{
+ if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
+ return SECFailure;
+ return (vector->p_ChaCha20Poly1305_Seal)(
+ ctx, output, outputLen, maxOutputLen, input, inputLen,
+ nonce, nonceLen, ad, adLen);
+}
+
+SECStatus
+ChaCha20Poly1305_Open(const ChaCha20Poly1305Context *ctx,
+ unsigned char *output, unsigned int *outputLen,
+ unsigned int maxOutputLen,
+ const unsigned char *input, unsigned int inputLen,
+ const unsigned char *nonce, unsigned int nonceLen,
+ const unsigned char *ad, unsigned int adLen)
+{
+ if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
+ return SECFailure;
+ return (vector->p_ChaCha20Poly1305_Open)(
+ ctx, output, outputLen, maxOutputLen, input, inputLen,
+ nonce, nonceLen, ad, adLen);
+}
diff --git a/nss/lib/freebl/loader.h b/nss/lib/freebl/loader.h
index 65cfd76..ced03b5 100644
--- a/nss/lib/freebl/loader.h
+++ b/nss/lib/freebl/loader.h
@@ -10,712 +10,772 @@
#include "blapi.h"
-#define FREEBL_VERSION 0x0311
+#define FREEBL_VERSION 0x0312
struct FREEBLVectorStr {
- unsigned short length; /* of this struct in bytes */
- unsigned short version; /* of this struct. */
+ unsigned short length; /* of this struct in bytes */
+ unsigned short version; /* of this struct. */
- RSAPrivateKey * (* p_RSA_NewKey)(int keySizeInBits,
- SECItem * publicExponent);
+ RSAPrivateKey *(*p_RSA_NewKey)(int keySizeInBits,
+ SECItem *publicExponent);
- SECStatus (* p_RSA_PublicKeyOp) (RSAPublicKey * key,
- unsigned char * output,
- const unsigned char * input);
+ 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_RSA_PrivateKeyOp)(RSAPrivateKey *key,
+ unsigned char *output,
+ const unsigned char *input);
- SECStatus (* p_DSA_NewKey)(const PQGParams * params,
- DSAPrivateKey ** privKey);
+ SECStatus (*p_DSA_NewKey)(const PQGParams *params,
+ DSAPrivateKey **privKey);
- SECStatus (* p_DSA_SignDigest)(DSAPrivateKey * key,
- SECItem * signature,
- const SECItem * digest);
+ 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_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_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_DSA_SignDigestWithSeed)(DSAPrivateKey *key,
+ SECItem *signature,
+ const SECItem *digest,
+ const unsigned char *seed);
- SECStatus (* p_DH_GenParam)(int primeLen, DHParams ** params);
+ SECStatus (*p_DH_GenParam)(int primeLen, DHParams **params);
- SECStatus (* p_DH_NewKey)(DHParams * params,
- DHPrivateKey ** privKey);
+ 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_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);
+ 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);
+ PRBool (*p_KEA_Verify)(SECItem *Y, SECItem *prime, SECItem *subPrime);
- RC4Context * (* p_RC4_CreateContext)(const unsigned char *key, int len);
+ RC4Context *(*p_RC4_CreateContext)(const unsigned char *key, int len);
- void (* p_RC4_DestroyContext)(RC4Context *cx, PRBool freeit);
+ 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_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);
+ 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);
+ 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);
+ 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_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);
+ 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);
+ 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);
+ 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_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);
+ 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);
+ DESContext *(*p_DES_CreateContext)(const unsigned char *key,
+ const unsigned char *iv,
+ int mode, PRBool encrypt);
- void (* p_DES_DestroyContext)(DESContext *cx, PRBool freeit);
+ 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_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);
+ 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);
+ 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);
+ 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_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_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_Hash)(unsigned char *dest, const char *src);
- SECStatus (* p_MD5_HashBuf)(unsigned char *dest, const unsigned char *src,
- PRUint32 src_length);
+ SECStatus (*p_MD5_HashBuf)(unsigned char *dest, const unsigned char *src,
+ PRUint32 src_length);
- MD5Context *(* p_MD5_NewContext)(void);
+ MD5Context *(*p_MD5_NewContext)(void);
- void (* p_MD5_DestroyContext)(MD5Context *cx, PRBool freeit);
+ void (*p_MD5_DestroyContext)(MD5Context *cx, PRBool freeit);
- void (* p_MD5_Begin)(MD5Context *cx);
+ void (*p_MD5_Begin)(MD5Context *cx);
- void (* p_MD5_Update)(MD5Context *cx,
- const unsigned char *input, unsigned int inputLen);
+ 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);
+ void (*p_MD5_End)(MD5Context *cx, unsigned char *digest,
+ unsigned int *digestLen, unsigned int maxDigestLen);
- unsigned int (* p_MD5_FlattenSize)(MD5Context *cx);
+ unsigned int (*p_MD5_FlattenSize)(MD5Context *cx);
- SECStatus (* p_MD5_Flatten)(MD5Context *cx,unsigned char *space);
+ SECStatus (*p_MD5_Flatten)(MD5Context *cx, unsigned char *space);
- MD5Context * (* p_MD5_Resurrect)(unsigned char *space, void *arg);
+ MD5Context *(*p_MD5_Resurrect)(unsigned char *space, void *arg);
- void (* p_MD5_TraceState)(MD5Context *cx);
+ void (*p_MD5_TraceState)(MD5Context *cx);
- SECStatus (* p_MD2_Hash)(unsigned char *dest, const char *src);
+ SECStatus (*p_MD2_Hash)(unsigned char *dest, const char *src);
- MD2Context *(* p_MD2_NewContext)(void);
+ MD2Context *(*p_MD2_NewContext)(void);
- void (* p_MD2_DestroyContext)(MD2Context *cx, PRBool freeit);
+ void (*p_MD2_DestroyContext)(MD2Context *cx, PRBool freeit);
- void (* p_MD2_Begin)(MD2Context *cx);
+ void (*p_MD2_Begin)(MD2Context *cx);
- void (* p_MD2_Update)(MD2Context *cx,
- const unsigned char *input, unsigned int inputLen);
+ 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);
+ void (*p_MD2_End)(MD2Context *cx, unsigned char *digest,
+ unsigned int *digestLen, unsigned int maxDigestLen);
- unsigned int (* p_MD2_FlattenSize)(MD2Context *cx);
+ unsigned int (*p_MD2_FlattenSize)(MD2Context *cx);
- SECStatus (* p_MD2_Flatten)(MD2Context *cx,unsigned char *space);
+ SECStatus (*p_MD2_Flatten)(MD2Context *cx, unsigned char *space);
- MD2Context * (* p_MD2_Resurrect)(unsigned char *space, void *arg);
+ MD2Context *(*p_MD2_Resurrect)(unsigned char *space, void *arg);
- SECStatus (* p_SHA1_Hash)(unsigned char *dest, const char *src);
+ SECStatus (*p_SHA1_Hash)(unsigned char *dest, const char *src);
- SECStatus (* p_SHA1_HashBuf)(unsigned char *dest, const unsigned char *src,
- PRUint32 src_length);
+ SECStatus (*p_SHA1_HashBuf)(unsigned char *dest, const unsigned char *src,
+ PRUint32 src_length);
- SHA1Context *(* p_SHA1_NewContext)(void);
+ SHA1Context *(*p_SHA1_NewContext)(void);
- void (* p_SHA1_DestroyContext)(SHA1Context *cx, PRBool freeit);
+ void (*p_SHA1_DestroyContext)(SHA1Context *cx, PRBool freeit);
- void (* p_SHA1_Begin)(SHA1Context *cx);
+ void (*p_SHA1_Begin)(SHA1Context *cx);
- void (* p_SHA1_Update)(SHA1Context *cx, const unsigned char *input,
- unsigned int inputLen);
+ 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);
- void (* p_SHA1_End)(SHA1Context *cx, unsigned char *digest,
- unsigned int *digestLen, unsigned int maxDigestLen);
+ SECStatus (*p_RNG_RNGInit)(void);
- void (* p_SHA1_TraceState)(SHA1Context *cx);
+ SECStatus (*p_RNG_RandomUpdate)(const void *data, size_t bytes);
- unsigned int (* p_SHA1_FlattenSize)(SHA1Context *cx);
+ SECStatus (*p_RNG_GenerateGlobalRandomBytes)(void *dest, size_t len);
- SECStatus (* p_SHA1_Flatten)(SHA1Context *cx,unsigned char *space);
+ void (*p_RNG_RNGShutdown)(void);
- SHA1Context * (* p_SHA1_Resurrect)(unsigned char *space, void *arg);
+ SECStatus (*p_PQG_ParamGen)(unsigned int j, PQGParams **pParams,
+ PQGVerify **pVfy);
- SECStatus (* p_RNG_RNGInit)(void);
+ SECStatus (*p_PQG_ParamGenSeedLen)(unsigned int j, unsigned int seedBytes,
+ PQGParams **pParams, PQGVerify **pVfy);
- SECStatus (* p_RNG_RandomUpdate)(const void *data, size_t bytes);
+ SECStatus (*p_PQG_VerifyParams)(const PQGParams *params,
+ const PQGVerify *vfy, SECStatus *result);
- SECStatus (* p_RNG_GenerateGlobalRandomBytes)(void *dest, size_t len);
+ /* Version 3.001 came to here */
- void (* p_RNG_RNGShutdown)(void);
+ SECStatus (*p_RSA_PrivateKeyOpDoubleChecked)(RSAPrivateKey *key,
+ unsigned char *output,
+ const unsigned char *input);
- SECStatus (* p_PQG_ParamGen)(unsigned int j, PQGParams **pParams,
- PQGVerify **pVfy);
+ SECStatus (*p_RSA_PrivateKeyCheck)(const RSAPrivateKey *key);
- SECStatus (* p_PQG_ParamGenSeedLen)( unsigned int j, unsigned int seedBytes,
- PQGParams **pParams, PQGVerify **pVfy);
+ void (*p_BL_Cleanup)(void);
- SECStatus (* p_PQG_VerifyParams)(const PQGParams *params,
- const PQGVerify *vfy, SECStatus *result);
+ /* Version 3.002 came to here */
- /* Version 3.001 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,
+ PRUint32 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);
- SECStatus (* p_RSA_PrivateKeyOpDoubleChecked)(RSAPrivateKey *key,
- unsigned char *output,
- const unsigned char *input);
+ 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,
+ PRUint32 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);
- SECStatus (* p_RSA_PrivateKeyCheck)(const RSAPrivateKey *key);
+ 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,
+ PRUint32 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);
- void (* p_BL_Cleanup)(void);
+ /* Version 3.003 came to here */
- /* Version 3.002 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);
- 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,
- PRUint32 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);
+ /* Version 3.004 came to here */
- 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,
- PRUint32 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);
+ PRBool (*p_BLAPI_SHVerify)(const char *name, PRFuncPtr addr);
+ PRBool (*p_BLAPI_VerifySelf)(const char *name);
- 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,
- PRUint32 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.005 came to here */
- /* Version 3.003 came to here */
+ SECStatus (*p_EC_NewKey)(ECParams *params,
+ ECPrivateKey **privKey);
- AESKeyWrapContext * (* p_AESKeyWrap_CreateContext)(const unsigned char *key,
- const unsigned char *iv, int encrypt, unsigned int keylen);
+ SECStatus (*p_EC_NewKeyFromSeed)(ECParams *params,
+ ECPrivateKey **privKey,
+ const unsigned char *seed,
+ int seedlen);
- void (* p_AESKeyWrap_DestroyContext)(AESKeyWrapContext *cx, PRBool freeit);
+ SECStatus (*p_EC_ValidatePublicKey)(ECParams *params,
+ SECItem *publicValue);
- SECStatus (* p_AESKeyWrap_Encrypt)(AESKeyWrapContext *cx,
- unsigned char *output,
- unsigned int *outputLen, unsigned int maxOutputLen,
- const unsigned char *input, unsigned int inputLen);
+ SECStatus (*p_ECDH_Derive)(SECItem *publicValue,
+ ECParams *params,
+ SECItem *privateValue,
+ PRBool withCofactor,
+ SECItem *derivedSecret);
- SECStatus (* p_AESKeyWrap_Decrypt)(AESKeyWrapContext *cx,
- unsigned char *output,
- unsigned int *outputLen, unsigned int maxOutputLen,
- const unsigned char *input, unsigned int inputLen);
+ SECStatus (*p_ECDSA_SignDigest)(ECPrivateKey *key,
+ SECItem *signature,
+ const SECItem *digest);
- /* Version 3.004 came to here */
+ SECStatus (*p_ECDSA_VerifyDigest)(ECPublicKey *key,
+ const SECItem *signature,
+ const SECItem *digest);
- PRBool (*p_BLAPI_SHVerify)(const char *name, PRFuncPtr addr);
- PRBool (*p_BLAPI_VerifySelf)(const char *name);
+ SECStatus (*p_ECDSA_SignDigestWithSeed)(ECPrivateKey *key,
+ SECItem *signature,
+ const SECItem *digest,
+ const unsigned char *seed,
+ const int seedlen);
- /* 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.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,
- PRUint32 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 */
-
- SECStatus (* p_RSA_SignRaw)(RSAPrivateKey *key,
- unsigned char *output,
- unsigned int *outputLen,
- unsigned int maxOutputLen,
- const unsigned char *input,
- unsigned int inputLen);
- SECStatus (* p_RSA_CheckSignRaw)(RSAPublicKey *key,
- const unsigned char *sig,
- unsigned int sigLen,
- const unsigned char *hash,
- unsigned int hashLen);
- SECStatus (* p_RSA_CheckSignRecoverRaw)(RSAPublicKey *key,
- unsigned char *data,
- unsigned int *dataLen,
- unsigned int maxDataLen,
- const unsigned char *sig,
- unsigned int sigLen);
- SECStatus (* p_RSA_EncryptRaw)(RSAPublicKey *key,
- unsigned char *output,
- unsigned int *outputLen,
- unsigned int maxOutputLen,
- const unsigned char *input,
- unsigned int inputLen);
- SECStatus (* p_RSA_DecryptRaw)(RSAPrivateKey *key,
- unsigned char *output,
- unsigned int *outputLen,
- unsigned int maxOutputLen,
- const unsigned char *input,
- unsigned int inputLen);
- SECStatus (* p_RSA_EncryptOAEP)(RSAPublicKey *key,
- HASH_HashType hashAlg,
- HASH_HashType maskHashAlg,
- const unsigned char *label,
- unsigned int labelLen,
- const unsigned char *seed,
- unsigned int seedLen,
- unsigned char *output,
- unsigned int *outputLen,
- unsigned int maxOutputLen,
- const unsigned char *input,
- unsigned int inputLen);
- SECStatus (* p_RSA_DecryptOAEP)(RSAPrivateKey *key,
- HASH_HashType hashAlg,
- HASH_HashType maskHashAlg,
- const unsigned char *label,
- unsigned int labelLen,
- unsigned char *output,
- unsigned int *outputLen,
- unsigned int maxOutputLen,
- const unsigned char *input,
- unsigned int inputLen);
- SECStatus (* p_RSA_EncryptBlock)(RSAPublicKey *key,
+ /* 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,
+ PRUint32 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 */
+
+ SECStatus (*p_RSA_SignRaw)(RSAPrivateKey *key,
+ unsigned char *output,
+ unsigned int *outputLen,
+ unsigned int maxOutputLen,
+ const unsigned char *input,
+ unsigned int inputLen);
+ SECStatus (*p_RSA_CheckSignRaw)(RSAPublicKey *key,
+ const unsigned char *sig,
+ unsigned int sigLen,
+ const unsigned char *hash,
+ unsigned int hashLen);
+ SECStatus (*p_RSA_CheckSignRecoverRaw)(RSAPublicKey *key,
+ unsigned char *data,
+ unsigned int *dataLen,
+ unsigned int maxDataLen,
+ const unsigned char *sig,
+ unsigned int sigLen);
+ SECStatus (*p_RSA_EncryptRaw)(RSAPublicKey *key,
unsigned char *output,
unsigned int *outputLen,
unsigned int maxOutputLen,
const unsigned char *input,
unsigned int inputLen);
- SECStatus (* p_RSA_DecryptBlock)(RSAPrivateKey *key,
+ SECStatus (*p_RSA_DecryptRaw)(RSAPrivateKey *key,
unsigned char *output,
unsigned int *outputLen,
unsigned int maxOutputLen,
const unsigned char *input,
unsigned int inputLen);
- SECStatus (* p_RSA_SignPSS)(RSAPrivateKey *key,
- HASH_HashType hashAlg,
- HASH_HashType maskHashAlg,
- const unsigned char *salt,
- unsigned int saltLen,
- unsigned char *output,
- unsigned int *outputLen,
- unsigned int maxOutputLen,
- const unsigned char *input,
- unsigned int inputLen);
- SECStatus (* p_RSA_CheckSignPSS)(RSAPublicKey *key,
- HASH_HashType hashAlg,
- HASH_HashType maskHashAlg,
- unsigned int saltLen,
- const unsigned char *sig,
- unsigned int sigLen,
- const unsigned char *hash,
- unsigned int hashLen);
- SECStatus (* p_RSA_Sign)(RSAPrivateKey *key,
- unsigned char *output,
- unsigned int *outputLen,
- unsigned int maxOutputLen,
- const unsigned char *input,
- unsigned int inputLen);
- SECStatus (* p_RSA_CheckSign)(RSAPublicKey *key,
- const unsigned char *sig,
- unsigned int sigLen,
- const unsigned char *data,
- unsigned int dataLen);
- SECStatus (* p_RSA_CheckSignRecover)(RSAPublicKey *key,
- unsigned char *output,
- unsigned int *outputLen,
- unsigned int maxOutputLen,
- const unsigned char *sig,
- unsigned int sigLen);
+ SECStatus (*p_RSA_EncryptOAEP)(RSAPublicKey *key,
+ HASH_HashType hashAlg,
+ HASH_HashType maskHashAlg,
+ const unsigned char *label,
+ unsigned int labelLen,
+ const unsigned char *seed,
+ unsigned int seedLen,
+ unsigned char *output,
+ unsigned int *outputLen,
+ unsigned int maxOutputLen,
+ const unsigned char *input,
+ unsigned int inputLen);
+ SECStatus (*p_RSA_DecryptOAEP)(RSAPrivateKey *key,
+ HASH_HashType hashAlg,
+ HASH_HashType maskHashAlg,
+ const unsigned char *label,
+ unsigned int labelLen,
+ unsigned char *output,
+ unsigned int *outputLen,
+ unsigned int maxOutputLen,
+ const unsigned char *input,
+ unsigned int inputLen);
+ SECStatus (*p_RSA_EncryptBlock)(RSAPublicKey *key,
+ unsigned char *output,
+ unsigned int *outputLen,
+ unsigned int maxOutputLen,
+ const unsigned char *input,
+ unsigned int inputLen);
+ SECStatus (*p_RSA_DecryptBlock)(RSAPrivateKey *key,
+ unsigned char *output,
+ unsigned int *outputLen,
+ unsigned int maxOutputLen,
+ const unsigned char *input,
+ unsigned int inputLen);
+ SECStatus (*p_RSA_SignPSS)(RSAPrivateKey *key,
+ HASH_HashType hashAlg,
+ HASH_HashType maskHashAlg,
+ const unsigned char *salt,
+ unsigned int saltLen,
+ unsigned char *output,
+ unsigned int *outputLen,
+ unsigned int maxOutputLen,
+ const unsigned char *input,
+ unsigned int inputLen);
+ SECStatus (*p_RSA_CheckSignPSS)(RSAPublicKey *key,
+ HASH_HashType hashAlg,
+ HASH_HashType maskHashAlg,
+ unsigned int saltLen,
+ const unsigned char *sig,
+ unsigned int sigLen,
+ const unsigned char *hash,
+ unsigned int hashLen);
+ SECStatus (*p_RSA_Sign)(RSAPrivateKey *key,
+ unsigned char *output,
+ unsigned int *outputLen,
+ unsigned int maxOutputLen,
+ const unsigned char *input,
+ unsigned int inputLen);
+ SECStatus (*p_RSA_CheckSign)(RSAPublicKey *key,
+ const unsigned char *sig,
+ unsigned int sigLen,
+ const unsigned char *data,
+ unsigned int dataLen);
+ SECStatus (*p_RSA_CheckSignRecover)(RSAPublicKey *key,
+ unsigned char *output,
+ unsigned int *outputLen,
+ unsigned int maxOutputLen,
+ const unsigned char *sig,
+ unsigned int sigLen);
+
+ /* Version 3.016 came to here */
+
+ SECStatus (*p_EC_FillParams)(PLArenaPool *arena,
+ const SECItem *encodedParams, ECParams *params);
+ SECStatus (*p_EC_DecodeParams)(const SECItem *encodedParams,
+ ECParams **ecparams);
+ SECStatus (*p_EC_CopyParams)(PLArenaPool *arena, ECParams *dstParams,
+ const ECParams *srcParams);
+
+ /* Version 3.017 came to here */
+
+ SECStatus (*p_ChaCha20Poly1305_InitContext)(ChaCha20Poly1305Context *ctx,
+ const unsigned char *key,
+ unsigned int keyLen,
+ unsigned int tagLen);
+
+ ChaCha20Poly1305Context *(*p_ChaCha20Poly1305_CreateContext)(
+ const unsigned char *key, unsigned int keyLen, unsigned int tagLen);
+
+ void (*p_ChaCha20Poly1305_DestroyContext)(ChaCha20Poly1305Context *ctx,
+ PRBool freeit);
+
+ SECStatus (*p_ChaCha20Poly1305_Seal)(
+ const ChaCha20Poly1305Context *ctx, unsigned char *output,
+ unsigned int *outputLen, unsigned int maxOutputLen,
+ const unsigned char *input, unsigned int inputLen,
+ const unsigned char *nonce, unsigned int nonceLen,
+ const unsigned char *ad, unsigned int adLen);
+
+ SECStatus (*p_ChaCha20Poly1305_Open)(
+ const ChaCha20Poly1305Context *ctx, unsigned char *output,
+ unsigned int *outputLen, unsigned int maxOutputLen,
+ const unsigned char *input, unsigned int inputLen,
+ const unsigned char *nonce, unsigned int nonceLen,
+ const unsigned char *ad, unsigned int adLen);
+
+ /* Version 3.018 came to here */
+
+ /* Add new function pointers at the end of this struct and bump
+ * FREEBL_VERSION at the beginning of this file. */
+};
- /* Version 3.016 came to here */
-
- SECStatus (* p_EC_FillParams)(PLArenaPool *arena,
- const SECItem *encodedParams, ECParams *params);
- SECStatus (* p_EC_DecodeParams)(const SECItem *encodedParams,
- ECParams **ecparams);
- SECStatus (* p_EC_CopyParams)(PLArenaPool *arena, ECParams *dstParams,
- const ECParams *srcParams);
+typedef struct FREEBLVectorStr FREEBLVector;
- /* Version 3.017 came to here */
+#ifdef FREEBL_LOWHASH
+#include "nsslowhash.h"
+
+#define NSSLOW_VERSION 0x0300
+
+struct NSSLOWVectorStr {
+ unsigned short length; /* of this struct in bytes */
+ unsigned short version; /* of this struct. */
+ const FREEBLVector *(*p_FREEBL_GetVector)(void);
+ NSSLOWInitContext *(*p_NSSLOW_Init)(void);
+ void (*p_NSSLOW_Shutdown)(NSSLOWInitContext *context);
+ void (*p_NSSLOW_Reset)(NSSLOWInitContext *context);
+ NSSLOWHASHContext *(*p_NSSLOWHASH_NewContext)(
+ NSSLOWInitContext *initContext,
+ HASH_HashType hashType);
+ void (*p_NSSLOWHASH_Begin)(NSSLOWHASHContext *context);
+ void (*p_NSSLOWHASH_Update)(NSSLOWHASHContext *context,
+ const unsigned char *buf,
+ unsigned int len);
+ void (*p_NSSLOWHASH_End)(NSSLOWHASHContext *context,
+ unsigned char *buf,
+ unsigned int *ret, unsigned int len);
+ void (*p_NSSLOWHASH_Destroy)(NSSLOWHASHContext *context);
+ unsigned int (*p_NSSLOWHASH_Length)(NSSLOWHASHContext *context);
+};
+
+typedef struct NSSLOWVectorStr NSSLOWVector;
+#endif
- /* Add new function pointers at the end of this struct and bump
- * FREEBL_VERSION at the beginning of this file. */
- };
+SEC_BEGIN_PROTOS
-typedef struct FREEBLVectorStr FREEBLVector;
+#ifdef FREEBL_LOWHASH
+typedef const NSSLOWVector *NSSLOWGetVectorFn(void);
-SEC_BEGIN_PROTOS
+extern NSSLOWGetVectorFn NSSLOW_GetVector;
+#endif
-typedef const FREEBLVector * FREEBLGetVectorFn(void);
+typedef const FREEBLVector *FREEBLGetVectorFn(void);
extern FREEBLGetVectorFn FREEBL_GetVector;
diff --git a/nss/lib/freebl/lowhash_vector.c b/nss/lib/freebl/lowhash_vector.c
new file mode 100644
index 0000000..7690c98
--- /dev/null
+++ b/nss/lib/freebl/lowhash_vector.c
@@ -0,0 +1,217 @@
+/*
+ * 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/. */
+
+#define _GNU_SOURCE 1
+#include "loader.h"
+#include "prmem.h"
+#include "prerror.h"
+#include "prinit.h"
+#include "prenv.h"
+#include "blname.c"
+
+#include "prio.h"
+#include "prprf.h"
+#include <stdio.h>
+#include "prsystem.h"
+#include "nsslowhash.h"
+#include <dlfcn.h>
+#include "pratom.h"
+
+static PRLibrary *blLib;
+
+#define LSB(x) ((x)&0xff)
+#define MSB(x) ((x) >> 8)
+
+static const NSSLOWVector *vector;
+static const char *libraryName = NULL;
+
+/* pretty much only glibc uses this, make sure we don't have any depenencies
+ * on nspr.. */
+#undef PORT_Alloc
+#undef PORT_Free
+#define PORT_Alloc malloc
+#define PR_Malloc malloc
+#define PORT_Free free
+#define PR_Free free
+#define PR_GetDirectorySeparator() '/'
+#define PR_LoadLibraryWithFlags(libspec, flags) \
+ (PRLibrary *)dlopen(libSpec.value.pathname, RTLD_NOW | RTLD_LOCAL)
+#define PR_GetLibraryFilePathname(name, addr) \
+ freebl_lowhash_getLibraryFilePath(addr)
+
+static char *
+freebl_lowhash_getLibraryFilePath(void *addr)
+{
+ Dl_info dli;
+ if (dladdr(addr, &dli) == 0) {
+ return NULL;
+ }
+ return strdup(dli.dli_fname);
+}
+
+/*
+ * The PR_LoadLibraryWithFlags call above defines this variable away, so we
+ * don't need it..
+ */
+#ifdef nodef
+static const char *NameOfThisSharedLib =
+ SHLIB_PREFIX "freebl" SHLIB_VERSION "." SHLIB_SUFFIX;
+#endif
+
+#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) {
+ void *address = dlsym(handle, "NSSLOW_GetVector");
+ if (address) {
+ NSSLOWGetVectorFn *getVector = (NSSLOWGetVectorFn *)address;
+ const NSSLOWVector *dsoVector = getVector();
+ if (dsoVector) {
+ unsigned short dsoVersion = dsoVector->version;
+ unsigned short myVersion = NSSLOW_VERSION;
+ if (MSB(dsoVersion) == MSB(myVersion) &&
+ LSB(dsoVersion) >= LSB(myVersion) &&
+ dsoVector->length >= sizeof(NSSLOWVector)) {
+ vector = dsoVector;
+ libraryName = name;
+ blLib = handle;
+ return PR_SUCCESS;
+ }
+ }
+ }
+ (void)dlclose(handle);
+ }
+ return PR_FAILURE;
+}
+
+static PRCallOnceType loadFreeBLOnce;
+
+static PRStatus
+freebl_RunLoaderOnce(void)
+{
+ /* Don't have NSPR, so can use the real PR_CallOnce, implement a stripped
+ * down version. */
+ if (loadFreeBLOnce.initialized) {
+ return loadFreeBLOnce.status;
+ }
+ if (__sync_lock_test_and_set(&loadFreeBLOnce.inProgress, 1) == 0) {
+ loadFreeBLOnce.status = freebl_LoadDSO();
+ loadFreeBLOnce.initialized = 1;
+ } else {
+ /* shouldn't have a lot of takers on the else clause, which is good
+ * since we don't have condition variables yet.
+ * 'initialized' only ever gets set (not cleared) so we don't
+ * need the traditional locks. */
+ while (!loadFreeBLOnce.initialized) {
+ sleep(1); /* don't have condition variables, just give up the CPU */
+ }
+ }
+
+ return loadFreeBLOnce.status;
+}
+
+const FREEBLVector *
+FREEBL_GetVector(void)
+{
+ if (!vector && PR_SUCCESS != freebl_RunLoaderOnce()) {
+ return NULL;
+ }
+ if (vector) {
+ return (vector->p_FREEBL_GetVector)();
+ }
+ return NULL;
+}
+
+NSSLOWInitContext *
+NSSLOW_Init(void)
+{
+ if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
+ return NULL;
+ return (vector->p_NSSLOW_Init)();
+}
+
+void
+NSSLOW_Shutdown(NSSLOWInitContext *context)
+{
+ if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
+ return;
+ (vector->p_NSSLOW_Shutdown)(context);
+}
+
+void
+NSSLOW_Reset(NSSLOWInitContext *context)
+{
+ if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
+ return;
+ (vector->p_NSSLOW_Reset)(context);
+}
+
+NSSLOWHASHContext *
+NSSLOWHASH_NewContext(
+ NSSLOWInitContext *initContext,
+ HASH_HashType hashType)
+{
+ if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
+ return NULL;
+ return (vector->p_NSSLOWHASH_NewContext)(initContext, hashType);
+}
+
+void
+NSSLOWHASH_Begin(NSSLOWHASHContext *context)
+{
+ if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
+ return;
+ (vector->p_NSSLOWHASH_Begin)(context);
+}
+
+void
+NSSLOWHASH_Update(NSSLOWHASHContext *context,
+ const unsigned char *buf,
+ unsigned int len)
+{
+ if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
+ return;
+ (vector->p_NSSLOWHASH_Update)(context, buf, len);
+}
+
+void
+NSSLOWHASH_End(NSSLOWHASHContext *context,
+ unsigned char *buf,
+ unsigned int *ret, unsigned int len)
+{
+ if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
+ return;
+ (vector->p_NSSLOWHASH_End)(context, buf, ret, len);
+}
+
+void
+NSSLOWHASH_Destroy(NSSLOWHASHContext *context)
+{
+ if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
+ return;
+ (vector->p_NSSLOWHASH_Destroy)(context);
+}
+
+unsigned int
+NSSLOWHASH_Length(NSSLOWHASHContext *context)
+{
+ if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
+ return -1;
+ return (vector->p_NSSLOWHASH_Length)(context);
+}
diff --git a/nss/lib/freebl/manifest.mn b/nss/lib/freebl/manifest.mn
index 1137e85..1ef9839 100644
--- a/nss/lib/freebl/manifest.mn
+++ b/nss/lib/freebl/manifest.mn
@@ -10,6 +10,30 @@ CORE_DEPTH = ../..
MODULE = nss
+# copied from Linux.mk. We have a chicken and egg issue here. We need to set
+# Library name before we call the platform code in coreconf, but we need to
+# Pick up the automatic setting of FREEBL_LOWHASH before we can set the
+# Library name... so for now we mimic the code in Linux.mk to get the
+# automatic setting early...
+#
+# On Linux 2.6 or later, build libfreebl3.so with no NSPR and libnssutil3.so
+# dependencies by default. Set FREEBL_NO_DEPEND to 0 in the environment to
+# override this.
+#
+#
+include $(CORE_DEPTH)/coreconf/arch.mk
+ifeq ($(OS_ARCH),Linux)
+ifneq ($(OS_TARGET),Android)
+ifeq (2.6,$(firstword $(sort 2.6 $(OS_RELEASE))))
+ifndef FREEBL_NO_DEPEND
+FREEBL_NO_DEPEND = 1
+FREEBL_LOWHASH = 1
+endif
+endif
+endif
+endif
+
+
LIBRARY_NAME = freebl
LIBRARY_VERSION = 3
@@ -29,6 +53,13 @@ ifdef FREEBL_CHILD_BUILD
ifdef USE_ABI64_FPU
LIBRARY_NAME = freebl_64fpu
endif
+ ifdef FREEBL_LOWHASH
+ LIBRARY_NAME = freeblpriv
+ endif
+ ifdef USE_STUB_BUILD
+ # for the stub build, reset name to the default (from freeblpriv)
+ LIBRARY_NAME = freebl
+ endif
endif
# if the library name contains _, we prefix the version with _
@@ -56,6 +87,7 @@ EXPORTS = \
PRIVATE_EXPORTS = \
alghmac.h \
blapi.h \
+ chacha20poly1305.h \
hmacct.h \
secmpi.h \
secrng.h \
@@ -68,17 +100,12 @@ 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
+ECL_HDRS = ecl-exp.h ecl.h ecp.h ecl-priv.h
ifndef NSS_DISABLE_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 ecp_256.c ecp_384.c ecp_521.c \
- ecp_256_32.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
-endif
+ ecp_256_32.c ecp_25519.c
else
ECL_SRCS = $(NULL)
endif
@@ -101,8 +128,10 @@ CSRCS = \
desblapi.c \
des.c \
drbg.c \
+ chacha20poly1305.c \
cts.c \
ctr.c \
+ fipsfreebl.c \
gcm.c \
hmacct.c \
rijndael.c \
diff --git a/nss/lib/freebl/md2.c b/nss/lib/freebl/md2.c
index d069eca..cb3d3d8 100644
--- a/nss/lib/freebl/md2.c
+++ b/nss/lib/freebl/md2.c
@@ -13,256 +13,257 @@
#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_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;
+ 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
+ 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
+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;
+ 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;
+ MD2Context *cx = (MD2Context *)PORT_ZAlloc(sizeof(MD2Context));
+ if (cx == NULL) {
+ PORT_SetError(PR_OUT_OF_MEMORY_ERROR);
+ return NULL;
+ }
+ return cx;
}
-void
+void
MD2_DestroyContext(MD2Context *cx, PRBool freeit)
{
- if (freeit)
- PORT_ZFree(cx, sizeof(*cx));
+ if (freeit)
+ PORT_ZFree(cx, sizeof(*cx));
}
-void
+void
MD2_Begin(MD2Context *cx)
{
- memset(cx, 0, sizeof(*cx));
- cx->unusedBuffer = MD2_BUFSIZE;
+ 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;
+ 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
+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;
- }
+ PRUint32 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;
- }
+ /* 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;
+ }
- /* Copy any input that remains into the buffer. */
- if (inputLen)
- memcpy(&cx->X[MD2_INPUT], input, inputLen);
- cx->unusedBuffer = MD2_BUFSIZE - inputLen;
+ /* 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
+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);
+ 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
+unsigned int
MD2_FlattenSize(MD2Context *cx)
{
- return sizeof(*cx);
+ return sizeof(*cx);
}
-SECStatus
+SECStatus
MD2_Flatten(MD2Context *cx, unsigned char *space)
{
- memcpy(space, cx, sizeof(*cx));
- return SECSuccess;
+ memcpy(space, cx, sizeof(*cx));
+ return SECSuccess;
}
-MD2Context *
+MD2Context *
MD2_Resurrect(unsigned char *space, void *arg)
{
- MD2Context *cx = MD2_NewContext();
- if (cx)
- memcpy(cx, space, sizeof(*cx));
- return cx;
+ MD2Context *cx = MD2_NewContext();
+ if (cx)
+ memcpy(cx, space, sizeof(*cx));
+ return cx;
}
-void MD2_Clone(MD2Context *dest, MD2Context *src)
+void
+MD2_Clone(MD2Context *dest, MD2Context *src)
{
- memcpy(dest, src, sizeof *dest);
+ memcpy(dest, src, sizeof *dest);
}
diff --git a/nss/lib/freebl/md5.c b/nss/lib/freebl/md5.c
index 6ac15b6..bdd36a6 100644
--- a/nss/lib/freebl/md5.c
+++ b/nss/lib/freebl/md5.c
@@ -13,6 +13,7 @@
#include "prlong.h"
#include "blapi.h"
+#include "blapii.h"
#define MD5_HASH_LEN 16
#define MD5_BUFFER_SIZE 64
@@ -23,16 +24,16 @@
#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_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
@@ -40,16 +41,16 @@
#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_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
@@ -57,16 +58,16 @@
#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_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
@@ -74,16 +75,16 @@
#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_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
@@ -91,16 +92,16 @@
#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 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
@@ -108,56 +109,56 @@
#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 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 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 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 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 R4B12 4
#define R4B13 11
-#define R4B14 2
-#define R4B15 9
+#define R4B14 2
+#define R4B15 9
#define S1_0 7
#define S1_1 12
@@ -180,358 +181,360 @@
#define S4_3 21
struct MD5ContextStr {
- PRUint32 lsbInput;
- PRUint32 msbInput;
- PRUint32 cv[4];
- union {
- PRUint8 b[64];
- PRUint32 w[16];
- } u;
+ PRUint32 lsbInput;
+ PRUint32 msbInput;
+ PRUint32 cv[4];
+ union {
+ PRUint8 b[64];
+ PRUint32 w[16];
+ } u;
};
#define inBuf u.b
-SECStatus
+SECStatus
MD5_Hash(unsigned char *dest, const char *src)
{
- return MD5_HashBuf(dest, (const unsigned char *)src, PORT_Strlen(src));
+ return MD5_HashBuf(dest, (const unsigned char *)src, PORT_Strlen(src));
}
-SECStatus
+SECStatus
MD5_HashBuf(unsigned char *dest, const unsigned char *src, PRUint32 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;
+ 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;
+ /* 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
+void
MD5_DestroyContext(MD5Context *cx, PRBool freeit)
{
- memset(cx, 0, sizeof *cx);
- if (freeit) {
- PORT_Free(cx);
- }
+ memset(cx, 0, sizeof *cx);
+ if (freeit) {
+ PORT_Free(cx);
+ }
}
-void
+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;
+ 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);
+ sumlow += addend; \
+ sumhigh += (sumlow < addend);
#else
#define addto64(sumhigh, sumlow, addend) \
- sumlow += addend; if (sumlow < addend) ++sumhigh;
+ sumlow += addend; \
+ if (sumlow < addend) \
+ ++sumhigh;
#endif
#define MASK 0x00ff00ff
#ifdef IS_LITTLE_ENDIAN
#define lendian(i32) \
- (i32)
+ (i32)
#else
#define lendian(i32) \
- (tmp = (i32 >> 16) | (i32 << 16), ((tmp & MASK) << 8) | ((tmp >> 8) & MASK))
+ (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])
+ ((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]);
+ 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]);
+ 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))
+ ((X & Y) | ((~X) & Z))
#define G(X, Y, Z) \
- ((X & Z) | (Y & (~Z)))
+ ((X & Z) | (Y & (~Z)))
#define H(X, Y, Z) \
- (X ^ Y ^ Z)
+ (X ^ Y ^ Z)
#define I(X, Y, Z) \
- (Y ^ (X | (~Z)))
+ (Y ^ (X | (~Z)))
#define FF(a, b, c, d, bufint, s, ti) \
- a = b + cls(a + F(b, c, d) + bufint + ti, s)
+ 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)
+ 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)
+ 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)
+ a = b + cls(a + I(b, c, d) + bufint + ti, s)
-static void
+static void NO_SANITIZE_ALIGNMENT
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;
+ 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
+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. */
+ 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);
+ 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) {
+ 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;
+#ifdef HAVE_UNALIGNED_ACCESS
+ /* 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;
- }
+ 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;
+ 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);
+ 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
+ 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
+void
MD5_End(MD5Context *cx, unsigned char *digest,
unsigned int *digestLen, unsigned int maxDigestLen)
{
#ifndef IS_LITTLE_ENDIAN
- PRUint32 tmp;
+ 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. */
+ 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);
+ md5_prep_state_le(cx);
#endif
- md5_compress(cx, cx->u.w);
+ md5_compress(cx, cx->u.w);
- /* Copy the resulting values out of the chain variables into return buf. */
- if (digestLen)
- *digestLen = MD5_HASH_LEN;
+ /* 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]);
+ 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);
+ memcpy(digest, cx->cv, MD5_HASH_LEN);
}
void
@@ -539,56 +542,57 @@ MD5_EndRaw(MD5Context *cx, unsigned char *digest,
unsigned int *digestLen, unsigned int maxDigestLen)
{
#ifndef IS_LITTLE_ENDIAN
- PRUint32 tmp;
+ PRUint32 tmp;
#endif
- PRUint32 cv[4];
+ PRUint32 cv[4];
- if (maxDigestLen < MD5_HASH_LEN) {
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- return;
- }
+ if (maxDigestLen < MD5_HASH_LEN) {
+ PORT_SetError(SEC_ERROR_INVALID_ARGS);
+ return;
+ }
- memcpy(cv, cx->cv, sizeof(cv));
+ 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]);
+ 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;
+ memcpy(digest, cv, MD5_HASH_LEN);
+ if (digestLen)
+ *digestLen = MD5_HASH_LEN;
}
-unsigned int
+unsigned int
MD5_FlattenSize(MD5Context *cx)
{
- return sizeof(*cx);
+ return sizeof(*cx);
}
-SECStatus
+SECStatus
MD5_Flatten(MD5Context *cx, unsigned char *space)
{
- memcpy(space, cx, sizeof(*cx));
- return SECSuccess;
+ memcpy(space, cx, sizeof(*cx));
+ return SECSuccess;
}
-MD5Context *
+MD5Context *
MD5_Resurrect(unsigned char *space, void *arg)
{
- MD5Context *cx = MD5_NewContext();
- if (cx)
- memcpy(cx, space, sizeof(*cx));
- return cx;
+ MD5Context *cx = MD5_NewContext();
+ if (cx)
+ memcpy(cx, space, sizeof(*cx));
+ return cx;
}
-void MD5_Clone(MD5Context *dest, MD5Context *src)
+void
+MD5_Clone(MD5Context *dest, MD5Context *src)
{
- memcpy(dest, src, sizeof *dest);
+ memcpy(dest, src, sizeof *dest);
}
-void
+void
MD5_TraceState(MD5Context *cx)
{
- PORT_SetError(PR_NOT_IMPLEMENTED_ERROR);
+ PORT_SetError(PR_NOT_IMPLEMENTED_ERROR);
}
diff --git a/nss/lib/freebl/mknewpc2.c b/nss/lib/freebl/mknewpc2.c
index b0957fa..6b29688 100644
--- a/nss/lib/freebl/mknewpc2.c
+++ b/nss/lib/freebl/mknewpc2.c
@@ -8,7 +8,7 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
typedef unsigned char BYTE;
-typedef unsigned int HALF;
+typedef unsigned int HALF;
#define DES_ENCRYPT 0
#define DES_DECRYPT 1
@@ -19,65 +19,64 @@ static HALF C0, D0;
static HALF L0, R0;
/* key schedule, 16 internal keys, each with 8 6-bit parts */
-static BYTE KS [8] [16];
-
+static BYTE KS[8][16];
/*
- * This table takes the 56 bits in C0 and D0 and shows show they are
+ * 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,
+ * 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 */
+ 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
+/* 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,
+ * 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 */
+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
+/* 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 */
+ /* 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.
@@ -85,54 +84,54 @@ static const signed char PC2b[64] = {
* 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.
+ * 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 */
+ /* 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));
+/* 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));
+ 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 )
+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) {
+ 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] );
+ 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]);
}
}
@@ -141,70 +140,69 @@ HALF PC2cd0[64];
HALF PC_2H[8][64];
void
-mktable( )
+mktable()
{
int i;
int table;
- const BYTE * ndx = NDX;
- HALF mask;
+ const BYTE* ndx = NDX;
+ HALF mask;
- mask = 0x80000000;
+ mask = 0x80000000;
for (i = 0; i < 32; ++i, mask >>= 1) {
- int bit = PC2b[i];
- if (bit < 0)
- continue;
- PC2cd0[bit + 32] = mask;
+ int bit = PC2b[i];
+ if (bit < 0)
+ continue;
+ PC2cd0[bit + 32] = mask;
}
- mask = 0x80000000;
+ mask = 0x80000000;
for (i = 32; i < 64; ++i, mask >>= 1) {
- int bit = PC2b[i];
- if (bit < 0)
- continue;
- PC2cd0[bit] = mask;
+ 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]);
+ printf("0x%08x,\n", PC2cd0[i]);
}
#endif
for (i = 0; i < 24; ++i) {
- NDX[i] += 32; /* because c0 is the upper half */
+ 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");
+ 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;
+ /* make_pc2a(); */
+ mktable();
+ return 0;
}
diff --git a/nss/lib/freebl/mksp.c b/nss/lib/freebl/mksp.c
index 99b9917..ca83ac8 100644
--- a/nss/lib/freebl/mksp.c
+++ b/nss/lib/freebl/mksp.c
@@ -14,66 +14,58 @@
* 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
- }
+ /* 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 =
+ * 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
+ 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];
@@ -85,9 +77,9 @@ makePinv(void)
int i;
unsigned int Pi = 0x80000000;
for (i = 0; i < 32; ++i) {
- int j = 32 - P[i];
- Pinv[j] = Pi;
- Pi >>= 1;
+ int j = 32 - P[i];
+ Pinv[j] = Pi;
+ Pi >>= 1;
}
}
@@ -96,25 +88,25 @@ 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 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");
}
}
diff --git a/nss/lib/freebl/mpi/README b/nss/lib/freebl/mpi/README
index fc6c5e1..475549b 100644
--- a/nss/lib/freebl/mpi/README
+++ b/nss/lib/freebl/mpi/README
@@ -234,7 +234,6 @@ 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
@@ -282,7 +281,6 @@ 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
@@ -523,13 +521,6 @@ 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
diff --git a/nss/lib/freebl/mpi/logtab.h b/nss/lib/freebl/mpi/logtab.h
index 1f2660e..24cb13c 100644
--- a/nss/lib/freebl/mpi/logtab.h
+++ b/nss/lib/freebl/mpi/logtab.h
@@ -8,22 +8,21 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
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
+ 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/nss/lib/freebl/mpi/mdxptest.c b/nss/lib/freebl/mpi/mdxptest.c
index 28b05f0..adbcfc3 100644
--- a/nss/lib/freebl/mpi/mdxptest.c
+++ b/nss/lib/freebl/mpi/mdxptest.c
@@ -5,42 +5,40 @@
#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
+/* 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
+ 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
+ 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;
@@ -54,39 +52,43 @@ struct TimingContextStr {
timetype end;
timetype interval;
- int minutes;
- int seconds;
- int millisecs;
+ int minutes;
+ int seconds;
+ int millisecs;
};
typedef struct TimingContextStr TimingContext;
-TimingContext *CreateTimingContext(void)
+TimingContext *
+CreateTimingContext(void)
{
return (TimingContext *)malloc(sizeof(TimingContext));
}
-void DestroyTimingContext(TimingContext *ctx)
+void
+DestroyTimingContext(TimingContext *ctx)
{
free(ctx);
}
-void TimingBegin(TimingContext *ctx)
+void
+TimingBegin(TimingContext *ctx)
{
gettime(&ctx->start);
}
-static void timingUpdate(TimingContext *ctx)
+static void
+timingUpdate(TimingContext *ctx)
{
ctx->millisecs = msec(ctx->interval) % 1000;
- ctx->seconds = sec(ctx->interval);
- ctx->minutes = ctx->seconds / 60;
- ctx->seconds %= 60;
-
+ ctx->seconds = sec(ctx->interval);
+ ctx->minutes = ctx->seconds / 60;
+ ctx->seconds %= 60;
}
-void TimingEnd(TimingContext *ctx)
+void
+TimingEnd(TimingContext *ctx)
{
gettime(&ctx->end);
ctx->interval = ctx->end;
@@ -94,17 +96,18 @@ void TimingEnd(TimingContext *ctx)
timingUpdate(ctx);
}
-char *TimingGenerateString(TimingContext *ctx)
+char *
+TimingGenerateString(TimingContext *ctx)
{
static char sBuf[4096];
sprintf(sBuf, "%d minutes, %d.%03d seconds", ctx->minutes,
- ctx->seconds, ctx->millisecs);
+ ctx->seconds, ctx->millisecs);
return sBuf;
}
static void
-dumpBytes( unsigned char * b, int l)
+dumpBytes(unsigned char *b, int l)
{
int i;
if (l <= 0)
@@ -122,17 +125,17 @@ dumpBytes( unsigned char * b, int l)
}
static mp_err
-testNewFuncs(const unsigned char * modulusBytes, int modulus_len)
+testNewFuncs(const unsigned char *modulusBytes, int modulus_len)
{
- mp_err mperr = MP_OKAY;
+ 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_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_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);
@@ -140,41 +143,41 @@ testNewFuncs(const unsigned char * modulusBytes, int modulus_len)
}
int
-testModExp( const unsigned char * modulusBytes,
- const unsigned int expo,
- const unsigned char * input,
- unsigned char * output,
- int modulus_len)
+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_err mperr = MP_OKAY;
mp_int modulus;
mp_int base;
mp_int exponent;
mp_int result;
- mperr = mp_init(&modulus);
+ 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.
+ ** 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) {
+ 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);
+ mperr = s_mp_exptmod(&base, &exponent, &modulus, &result);
#else
- mperr = mp_exptmod(&base, &exponent, &modulus, &result);
+ mperr = mp_exptmod(&base, &exponent, &modulus, &result);
#endif
- if (mperr == MP_OKAY) {
- mperr = mp_to_fixlen_octets(&result, output, modulus_len);
- }
- }
+ if (mperr == MP_OKAY) {
+ mperr = mp_to_fixlen_octets(&result, output, modulus_len);
+ }
+ }
}
mp_clear(&base);
mp_clear(&result);
@@ -186,41 +189,41 @@ testModExp( const unsigned char * modulusBytes,
}
int
-doModExp( const unsigned char * modulusBytes,
- const unsigned char * exponentBytes,
- const unsigned char * input,
- unsigned char * output,
- int modulus_len)
+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_err mperr = MP_OKAY;
mp_int modulus;
mp_int base;
mp_int exponent;
mp_int result;
- mperr = mp_init(&modulus);
+ 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.
+ ** 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) {
+ 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);
+ mperr = s_mp_exptmod(&base, &exponent, &modulus, &result);
#else
- mperr = mp_exptmod(&base, &exponent, &modulus, &result);
+ mperr = mp_exptmod(&base, &exponent, &modulus, &result);
#endif
- if (mperr == MP_OKAY) {
- mperr = mp_to_fixlen_octets(&result, output, modulus_len);
- }
- }
+ if (mperr == MP_OKAY) {
+ mperr = mp_to_fixlen_octets(&result, output, modulus_len);
+ }
+ }
}
mp_clear(&base);
mp_clear(&result);
@@ -234,77 +237,70 @@ doModExp( const unsigned char * modulusBytes,
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];
+ 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];
+ progName = strrchr(argv[0], '\\');
+ progName = progName ? progName + 1 : argv[0];
if (argc >= 2) {
- iters = atol(argv[1]);
+ iters = atol(argv[1]);
}
if (argc >= 3) {
- modulus_len = atol(argv[2]);
- } else
- modulus_len = sizeof default_n;
+ 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);
+ 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);
+ 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);
+ 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);
+ 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 = testModExp(default_n, 3, buf, buf2, modulus_len);
+ dumpBytes((unsigned char *)buf2, modulus_len);
+ }
rv = doModExp(default_n, default_d, buf, buf2, modulus_len);
if (rv != 0) {
- fprintf(stderr, "Error in modexp operation:\n");
- exit(1);
+ 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);
- }
+ 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/nss/lib/freebl/mpi/montmulf.c b/nss/lib/freebl/mpi/montmulf.c
index 3f93d3e..ce8fbc3 100644
--- a/nss/lib/freebl/mpi/montmulf.c
+++ b/nss/lib/freebl/mpi/montmulf.c
@@ -6,11 +6,11 @@
#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);
+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
@@ -18,13 +18,12 @@ 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* */);
+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
@@ -33,263 +32,255 @@ void i16_to_d16_and_d32x4(const double * /*1/(2^16)*/,
#define floor(d) ((double)((unsigned long long)(d)))
#endif
-static double upper32(double x)
+static double
+upper32(double x)
{
- return floor(x*TwoToMinus32);
+ return floor(x * TwoToMinus32);
}
-static double lower32(double x, double y)
+static double
+lower32(double x, double y)
{
- return x-TwoTo32*floor(x*TwoToMinus32);
+ return x - TwoTo32 * floor(x * TwoToMinus32);
}
-static double mod(double x, double oneoverm, double m)
+static double
+mod(double x, double oneoverm, double m)
{
- return x-m*floor(x*oneoverm);
+ return x - m * floor(x * oneoverm);
}
#endif
-
-static void cleanup(double *dt, int from, int tlen)
+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 **/
-}
+ 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)
+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;
+ 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)
+void
+conv_i32_to_d32(double *d32, unsigned int *i32, int len)
{
-int i;
+ int i;
#pragma pipeloop(0)
- for(i=0;i<len;i++) d32[i]=(double)(i32[i]);
+ for (i = 0; i < len; i++)
+ d32[i] = (double)(i32[i]);
}
-
-void conv_i32_to_d16(double *d16, unsigned int *i32, int len)
+void
+conv_i32_to_d16(double *d16, unsigned int *i32, int len)
{
-int i;
-unsigned int a;
+ 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);
- }
+ 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)
+void
+conv_i32_to_d32_and_d16(double *d32, double *d16,
+ unsigned int *i32, int len)
{
-int i = 0;
-unsigned int a;
+ 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])));
- }
+ 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);
- }
+ 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)
+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;
- }
- }
+ 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)
+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;
+ 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);
-
+ 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/nss/lib/freebl/mpi/montmulf.h b/nss/lib/freebl/mpi/montmulf.h
index 7039c0b..69bed4a 100644
--- a/nss/lib/freebl/mpi/montmulf.h
+++ b/nss/lib/freebl/mpi/montmulf.h
@@ -6,7 +6,6 @@
* 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
@@ -16,7 +15,6 @@ void conv_i32_to_d32(double *d32, unsigned int *i32, int 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
@@ -29,24 +27,22 @@ void conv_i32_to_d16(double *d16, unsigned int *i32, int len);
* 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);
+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);
+ 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,
+ * 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.
@@ -54,10 +50,10 @@ void mont_mulf_noconv(unsigned int *result,
* 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
+ * 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
+ * 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
@@ -66,4 +62,4 @@ void mont_mulf_noconv(unsigned int *result,
* dn - nlen
* nint - nlen
* No two arrays should point to overlapping areas of memory.
- */
+ */
diff --git a/nss/lib/freebl/mpi/mp_comba.c b/nss/lib/freebl/mpi/mp_comba.c
index f12f454..3b4937b 100644
--- a/nss/lib/freebl/mpi/mp_comba.c
+++ b/nss/lib/freebl/mpi/mp_comba.c
@@ -10,1289 +10,3226 @@
*/
/* 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; }
+#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;
+ c0 = c1 = c2 = 0;
/* forward the carry to the next digit */
#define COMBA_FORWARD \
- do { c0 = c1; c1 = c2; c2 = 0; } while (0);
+ 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");
-
-
-
+#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;
+ c0 = c1 = c2 = 0;
#define COMBA_STORE(x) \
- x = c0;
+ x = c0;
#define COMBA_STORE2(x) \
- x = c1;
+ x = c1;
#define CARRY_FORWARD \
- do { c0 = c1; c1 = c2; c2 = 0; } while (0);
+ 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)
+#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;
+ 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)
+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;
+ 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)
+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;
+ 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)
+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;
+ 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)
+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);
+ 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)
+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);
+ 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)
+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);
+ 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)
+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);
+ 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/nss/lib/freebl/mpi/mp_gf2m-priv.h b/nss/lib/freebl/mpi/mp_gf2m-priv.h
index b9c2f3b..5be4da4 100644
--- a/nss/lib/freebl/mpi/mp_gf2m-priv.h
+++ b/nss/lib/freebl/mpi/mp_gf2m-priv.h
@@ -23,23 +23,23 @@ extern const mp_digit mp_gf2m_sqr_tb[16];
/* Platform-specific macros for fast binary polynomial squaring. */
#if MP_DIGIT_BITS == 32
-#define gf2m_SQR1(w) \
+#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]
+ 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]
+#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.
@@ -48,26 +48,26 @@ extern const mp_digit mp_gf2m_sqr_tb[16];
*/
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)
+/* 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);
+ const mp_digit b0);
-/* Compute xor-multiply of two binary polynomials (a2, a1, a0) x (b2, b1, 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);
+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)
+/* 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);
+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/nss/lib/freebl/mpi/mp_gf2m.c b/nss/lib/freebl/mpi/mp_gf2m.c
index e84f3a0..5a096ad 100644
--- a/nss/lib/freebl/mpi/mp_gf2m.c
+++ b/nss/lib/freebl/mpi/mp_gf2m.c
@@ -8,159 +8,251 @@
#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
-};
+ {
+ 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
+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;
+ 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;
+ 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; }
+ if (top2b & 01) {
+ l ^= b << 30;
+ h ^= b >> 2;
+ }
+ if (top2b & 02) {
+ l ^= b << 31;
+ h ^= b >> 1;
+ }
- *rh = h; *rl = l;
-}
+ *rh = h;
+ *rl = l;
+}
#else
-void
+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;
+ 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; }
+ 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;
-}
+ *rh = h;
+ *rl = l;
+}
#endif
-/* Compute xor-multiply of two binary polynomials (a1, a0) x (b1, b0)
+/* 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
+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(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; */
+ 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)
+/* 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)
+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];
+ 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 */
+ 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];
+ 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];
+ 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)
+/* 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)
+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];
+ 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 */
+ 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];
+ 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];
+ 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;
+ * 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
@@ -187,7 +279,7 @@ mp_badd(const mp_int *a, const mp_int *b, mp_int *c)
}
/* Make sure c has enough precision for the output value */
- MP_CHECKOK( s_mp_pad(c, used_pa) );
+ MP_CHECKOK(s_mp_pad(c, used_pa));
/* Do word-by-word xor */
pc = MP_DIGITS(c);
@@ -206,12 +298,12 @@ mp_badd(const mp_int *a, const mp_int *b, mp_int *c)
CLEANUP:
return res;
-}
+}
-#define s_mp_div2(a) MP_CHECKOK( mpl_rsh((a), (a), 1) );
+#define s_mp_div2(a) MP_CHECKOK(mpl_rsh((a), (a), 1));
/* Compute binary polynomial multiply d = a * b */
-static void
+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;
@@ -225,7 +317,7 @@ s_bmul_d(const mp_digit *a, mp_size a_len, mp_digit b, mp_digit *d)
}
/* Compute binary polynomial xor multiply accumulate d ^= a * b */
-static void
+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;
@@ -238,10 +330,10 @@ s_bmul_d_add(const mp_digit *a, mp_size a_len, mp_digit b, mp_digit *d)
*d ^= carry;
}
-/* Compute binary polynomial xor multiply c = a * b.
+/* Compute binary polynomial xor multiply c = a * b.
* All parameters may be identical.
*/
-mp_err
+mp_err
mp_bmul(const mp_int *a, const mp_int *b, mp_int *c)
{
mp_digit *pb, b_i;
@@ -254,23 +346,24 @@ mp_bmul(const mp_int *a, const mp_int *b, mp_int *c)
ARGCHK(a != NULL && b != NULL && c != NULL, MP_BADARG);
if (a == c) {
- MP_CHECKOK( mp_init_copy(&tmp, a) );
+ 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) );
+ 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 */
+ 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)) );
+ 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));
@@ -278,7 +371,7 @@ mp_bmul(const mp_int *a, const mp_int *b, mp_int *c)
/* Outer loop: Digits of b */
a_used = MP_USED(a);
b_used = MP_USED(b);
- MP_USED(c) = a_used + b_used;
+ MP_USED(c) = a_used + b_used;
for (ib = 1; ib < b_used; ib++) {
b_i = *pb++;
@@ -298,11 +391,10 @@ CLEANUP:
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:
+/* 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.
*/
@@ -315,11 +407,11 @@ mp_bmod(const mp_int *a, const unsigned int p[], mp_int *r)
mp_size used;
mp_err res = MP_OKAY;
- /* The algorithm does the reduction in place in r,
+ /* 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) );
+ MP_CHECKOK(mp_copy(a, r));
}
z = MP_DIGITS(r);
@@ -332,7 +424,8 @@ mp_bmod(const mp_int *a, const unsigned int p[], mp_int *r)
zz = z[j];
if (zz == 0) {
- j--; continue;
+ j--;
+ continue;
}
z[j] = 0;
@@ -344,20 +437,19 @@ mp_bmod(const mp_int *a, const unsigned int p[], mp_int *r)
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);
+ z[j - n] ^= (zz >> d0);
+ if (d0)
+ z[j - n - 1] ^= (zz << d1);
}
/* reducing component t^0 */
- n = dN;
+ 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);
-
+ z[j - n] ^= (zz >> d0);
+ if (d0)
+ z[j - n - 1] ^= (zz << d1);
}
/* final round of reduction */
@@ -365,16 +457,17 @@ mp_bmod(const mp_int *a, const unsigned int p[], mp_int *r)
/* d0 = p[0] % MP_DIGIT_BITS; */
d0 = p[0] & MP_DIGIT_BITS_MASK;
- zz = z[dN] >> d0;
- if (zz == 0) break;
+ 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[dN] = (z[dN] << d1) >> d1;
+ } else {
+ z[dN] = 0;
+ }
*z ^= zz; /* reduction t^0 component */
for (k = 1; p[k] > 0; k++) {
@@ -387,7 +480,7 @@ mp_bmod(const mp_int *a, const unsigned int p[], mp_int *r)
z[n] ^= (zz << d0);
tmp = zz >> d1;
if (d0 && tmp)
- z[n+1] ^= tmp;
+ z[n + 1] ^= tmp;
}
}
@@ -396,25 +489,26 @@ CLEANUP:
return res;
}
-/* Compute the product of two polynomials a and b, reduce modulo p,
+/* 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_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;
+
+ 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 .
+/* Compute binary polynomial squaring c = a*a mod p .
* Parameter r and a can be identical.
*/
-mp_err
+mp_err
mp_bsqrmod(const mp_int *a, const unsigned int p[], mp_int *r)
{
mp_digit *pa, *pr, a_i;
@@ -426,17 +520,18 @@ mp_bsqrmod(const mp_int *a, const unsigned int p[], mp_int *r)
MP_DIGITS(&tmp) = 0;
if (a == r) {
- MP_CHECKOK( mp_init_copy(&tmp, a) );
+ 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)) );
+ 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;
+ MP_USED(r) = 2 * a_used;
for (ia = 0; ia < a_used; ia++) {
a_i = *pa++;
@@ -444,7 +539,7 @@ mp_bsqrmod(const mp_int *a, const unsigned int p[], mp_int *r)
*pr++ = gf2m_SQR1(a_i);
}
- MP_CHECKOK( mp_bmod(r, p, r) );
+ MP_CHECKOK(mp_bmod(r, p, r));
s_mp_clamp(r);
SIGN(r) = ZPOS;
@@ -455,13 +550,13 @@ CLEANUP:
/* 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
+ * 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)
+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;
@@ -471,60 +566,62 @@ mp_bdivmod(const mp_int *y, const mp_int *x, const mp_int *pp,
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;
+ 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) );
+ 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) );
+ 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) );
+ 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) );
+ 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))
+ } 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) );
+ 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) );
+ MP_CHECKOK(mp_badd(u, pp, u));
}
s_mp_div2(u);
} while (!mp_isodd(a));
}
} while (1);
- MP_CHECKOK( mp_copy(u, r) );
+ 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
@@ -541,14 +638,16 @@ mp_bpoly2arr(const mp_int *a, unsigned int p[], int max)
top_bit = 1;
top_bit <<= MP_DIGIT_BIT - 1;
- for (k = 0; k < max; k++) p[k] = 0;
+ 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;
+ if (k < max)
+ p[k] = MP_DIGIT_BIT * i + j;
k++;
}
mask >>= 1;
@@ -558,7 +657,7 @@ mp_bpoly2arr(const mp_int *a, unsigned int p[], int max)
return k;
}
-/* Convert the coefficient array representation of a polynomial to a
+/* Convert the coefficient array representation of a polynomial to a
* bit-string. The array must be terminated by 0.
*/
mp_err
@@ -570,10 +669,10 @@ mp_barr2poly(const unsigned int p[], mp_int *a)
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, p[i], 1));
}
- MP_CHECKOK( mpl_set_bit(a, 0, 1) );
-
+ MP_CHECKOK(mpl_set_bit(a, 0, 1));
+
CLEANUP:
return res;
}
diff --git a/nss/lib/freebl/mpi/mp_gf2m.h b/nss/lib/freebl/mpi/mp_gf2m.h
index 9faa026..ed2c854 100644
--- a/nss/lib/freebl/mpi/mp_gf2m.h
+++ b/nss/lib/freebl/mpi/mp_gf2m.h
@@ -10,17 +10,17 @@
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:
+/* 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_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);
+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);
diff --git a/nss/lib/freebl/mpi/mpcpucache.c b/nss/lib/freebl/mpi/mpcpucache.c
index 9250061..6fed352 100644
--- a/nss/lib/freebl/mpi/mpcpucache.c
+++ b/nss/lib/freebl/mpi/mpcpucache.c
@@ -9,7 +9,7 @@
* 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
+ * 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
@@ -18,10 +18,10 @@
* 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)
+#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"
@@ -34,25 +34,27 @@
#if defined(__GNUC__)
-void freebl_cpuid(unsigned long op, unsigned long *eax,
- unsigned long *ebx, unsigned long *ecx,
- unsigned long *edx)
+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));
+ __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)
+void
+freebl_cpuid(unsigned long op, unsigned long *eax,
+ unsigned long *ebx, unsigned long *ecx,
+ unsigned long *edx)
{
int intrinsic_out[4];
@@ -70,44 +72,50 @@ void freebl_cpuid(unsigned long op, unsigned long *eax,
/* x86 */
#if defined(__GNUC__)
-void freebl_cpuid(unsigned long op, unsigned long *eax,
- unsigned long *ebx, unsigned long *ecx,
- unsigned long *edx)
+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));
+ /* Some older processors don't fill the ecx register with cpuid, so clobber it
+ * before calling cpuid, so that there's no risk of picking random bits that
+ * erroneously indicate that absent CPU features are present.
+ * Also, GCC isn't smart enough to save the ebx PIC register on its 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__("xor %%ecx, %%ecx\n\t"
+ "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)
+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;
+ 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)
@@ -116,12 +124,14 @@ static unsigned long changeFlag(unsigned long flag)
* 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)
+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 {
+ unsigned long Leax, Lebx, Lecx, Ledx;
+ __asm {
pushad
+ xor ecx,ecx
mov eax,op
wcpuid
mov Leax,eax
@@ -129,35 +139,36 @@ void freebl_cpuid(unsigned long op, unsigned long *Reax,
mov Lecx,ecx
mov Ledx,edx
popad
- }
- *Reax = Leax;
- *Rebx = Lebx;
- *Recx = Lecx;
- *Redx = Ledx;
+ }
+ *Reax = Leax;
+ *Rebx = Lebx;
+ *Recx = Lecx;
+ *Redx = Ledx;
}
-static unsigned long changeFlag(unsigned long flag)
+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;
+ 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
@@ -168,42 +179,43 @@ static unsigned long changeFlag(unsigned long flag)
#define ID_FLAG 0x200000
/* 386 processors can't flip the AC_FLAG, intel AP Note AP-485 */
-static int is386()
+static int
+is386()
{
return changeFlag(AC_FLAG) == 0;
}
/* 486 processors can't flip the ID_FLAG, intel AP Note AP-485 */
-static int is486()
+static int
+is486()
{
return changeFlag(ID_FLAG) == 0;
}
#endif
-
/*
* table for Intel Cache.
- * See Intel Application Note AP-485 for more information
+ * See Intel Application Note AP-485 for more information
*/
typedef unsigned char CacheTypeEntry;
typedef enum {
- Cache_NONE = 0,
+ 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
+ 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 {
@@ -211,271 +223,272 @@ struct _cache {
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 }
+ /* 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)
+getIntelCacheEntryLineSize(unsigned long val, int *level,
+ unsigned long *lineSize)
{
CacheType type;
@@ -485,28 +498,27 @@ getIntelCacheEntryLineSize(unsigned long val, int *level,
* 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;
+ 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;
+ 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;
+ *level = 2;
+ *lineSize = CacheMap[val].lineSize;
} else if ((*level >= 3) && ((type == Cache_L3) || (type == Cache_L3d))) {
- *level = 3;
- *lineSize = CacheMap[val].lineSize;
+ *level = 3;
+ *lineSize = CacheMap[val].lineSize;
}
return;
}
-
static void
-getIntelRegisterCacheLineSize(unsigned long val,
- int *level, unsigned long *lineSize)
+getIntelRegisterCacheLineSize(unsigned long val,
+ int *level, unsigned long *lineSize)
{
getIntelCacheEntryLineSize(val >> 24 & 0xff, level, lineSize);
getIntelCacheEntryLineSize(val >> 16 & 0xff, level, lineSize);
@@ -516,7 +528,7 @@ getIntelRegisterCacheLineSize(unsigned long val,
/*
* returns '0' if no recognized cache is found, or if the cache
- * information is supported by this processor
+ * information is supported by this processor
*/
static unsigned long
getIntelCacheLineSize(int cpuidLevel)
@@ -527,13 +539,13 @@ getIntelCacheLineSize(int cpuidLevel)
int repeat, count;
if (cpuidLevel < 2) {
- return 0;
+ 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
+ * 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
+ * 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
@@ -543,28 +555,28 @@ getIntelCacheLineSize(int cpuidLevel)
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);
- }
+ 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.
+ * 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").
@@ -580,58 +592,57 @@ getOtherCacheLineSize(unsigned long cpuidLevel)
cpuidLevel = eax;
if (cpuidLevel >= 0x80000005) {
- freebl_cpuid(0x80000005, &eax, &ebx, &ecx, &edx);
- lineSize = ecx & 0xff; /* line Size, L1 Data Cache */
+ 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
+static const char *const manMap[] = {
+#define INTEL 0
"GenuineIntel",
-#define AMD 1
+#define AMD 1
"AuthenticAMD",
-#define CYRIX 2
+#define CYRIX 2
"CyrixInstead",
-#define CENTAUR 2
+#define CENTAUR 2
"CentaurHauls",
-#define NEXGEN 3
+#define NEXGEN 3
"NexGenDriven",
#define TRANSMETA 4
"GenuineTMx86",
-#define RISE 5
+#define RISE 5
"RiseRiseRise",
-#define UMC 6
+#define UMC 6
"UMC UMC UMC ",
-#define SIS 7
+#define SIS 7
"Sis Sis Sis ",
-#define NATIONAL 8
+#define NATIONAL 8
"Geode by NSC",
};
-static const int n_manufacturers = sizeof(manMap)/sizeof(manMap[0]);
-
+static const int n_manufacturers = sizeof(manMap) / sizeof(manMap[0]);
#define MAN_UNKNOWN 9
#if !defined(AMD_64)
-#define SSE2_FLAG (1<<26)
+#define SSE2_FLAG (1 << 26)
unsigned long
s_mpi_is_sse2()
{
unsigned long eax, ebx, ecx, edx;
if (is386() || is486()) {
- return 0;
+ return 0;
}
freebl_cpuid(0, &eax, &ebx, &ecx, &edx);
/* has no SSE2 extensions */
if (eax == 0) {
- return 0;
+ return 0;
}
- freebl_cpuid(1,&eax,&ebx,&ecx,&edx);
+ freebl_cpuid(1, &eax, &ebx, &ecx, &edx);
return (edx & SSE2_FLAG) == SSE2_FLAG;
}
#endif
@@ -649,9 +660,10 @@ s_mpi_getProcessorLineSize()
#if !defined(AMD_64)
if (is386()) {
- return 0; /* 386 had no cache */
- } if (is486()) {
- return 32; /* really? need more info */
+ return 0; /* 386 had no cache */
+ }
+ if (is486()) {
+ return 32; /* really? need more info */
}
#endif
@@ -669,30 +681,30 @@ s_mpi_getProcessorLineSize()
string[12] = 0;
manufacturer = MAN_UNKNOWN;
- for (i=0; i < n_manufacturers; i++) {
- if ( strcmp(manMap[i],string) == 0) {
- manufacturer = i;
- }
+ for (i = 0; i < n_manufacturers; i++) {
+ if (strcmp(manMap[i], string) == 0) {
+ manufacturer = i;
+ }
}
if (manufacturer == INTEL) {
- cacheLineSize = getIntelCacheLineSize(cpuidLevel);
+ cacheLineSize = getIntelCacheLineSize(cpuidLevel);
} else {
- cacheLineSize = getOtherCacheLineSize(cpuidLevel);
+ 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;
+ cacheLineSize = 32;
}
return cacheLineSize;
}
#define MPI_GET_PROCESSOR_LINE_SIZE_DEFINED 1
#endif
-#if defined(__ppc64__)
+#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
@@ -700,48 +712,49 @@ s_mpi_getProcessorLineSize()
* 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),
+ * 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
+ * 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)
+static inline void
+dcbzl(char *array)
{
- register char *a asm("r2") = array;
- __asm__ __volatile__( "dcbzl %0,r0" : "=r" (a): "0"(a) );
+ 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_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 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);
+ 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;
- }
+ for (i = PPC_MAX_LINE_SIZE; i != 0; i = i / 2) {
+ if (test[i - 1] == 0) {
+ return i;
+ }
}
return 0;
}
@@ -749,42 +762,39 @@ s_mpi_getProcessorLineSize()
#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
+ * 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
+/* 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;
+ 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;
+ return 32;
}
#endif
@@ -794,5 +804,5 @@ s_mpi_getProcessorLineSize()
main()
{
printf("line size = %d\n", s_mpi_getProcessorLineSize());
-}
+}
#endif
diff --git a/nss/lib/freebl/mpi/mpcpucache_x86.s b/nss/lib/freebl/mpi/mpcpucache_x86.s
index cc65ea3..af17ebc 100644
--- a/nss/lib/freebl/mpi/mpcpucache_x86.s
+++ b/nss/lib/freebl/mpi/mpcpucache_x86.s
@@ -569,6 +569,7 @@ freebl_cpuid:
movl %edx, %ebp
/APP
pushl %ebx
+ xorl %ecx, %ecx
cpuid
mov %ebx,%esi
popl %ebx
diff --git a/nss/lib/freebl/mpi/mpi-config.h b/nss/lib/freebl/mpi/mpi-config.h
index 1d35028..f365592 100644
--- a/nss/lib/freebl/mpi/mpi-config.h
+++ b/nss/lib/freebl/mpi/mpi-config.h
@@ -1,4 +1,4 @@
-/* Default configuration for MPI library
+/* 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
@@ -8,7 +8,7 @@
#define MPI_CONFIG_H_
/*
- For boolean options,
+ For boolean options,
0 = no
1 = yes
@@ -17,31 +17,27 @@
*/
#ifndef MP_IOFUNC
-#define MP_IOFUNC 0 /* include mp_print() ? */
+#define MP_IOFUNC 0 /* include mp_print() ? */
#endif
#ifndef MP_MODARITH
-#define MP_MODARITH 1 /* include modular arithmetic ? */
+#define MP_MODARITH 1 /* include modular arithmetic ? */
#endif
#ifndef MP_NUMTH
-#define MP_NUMTH 1 /* include number theoretic functions? */
+#define MP_NUMTH 1 /* include number theoretic functions? */
#endif
#ifndef MP_LOGTAB
-#define MP_LOGTAB 1 /* use table of logs instead of log()? */
+#define MP_LOGTAB 1 /* use table of logs instead of log()? */
#endif
#ifndef MP_MEMSET
-#define MP_MEMSET 1 /* use memset() to zero buffers? */
+#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? */
+#define MP_MEMCPY 1 /* use memcpy() to copy buffers? */
#endif
#ifndef MP_ARGCHK
@@ -51,28 +47,22 @@
2 = assertions; dump core on parameter errors
*/
#ifdef DEBUG
-#define MP_ARGCHK 2 /* how to check input arguments */
+#define MP_ARGCHK 2 /* how to check input arguments */
#else
-#define MP_ARGCHK 1 /* how to check input arguments */
+#define MP_ARGCHK 1 /* how to check input arguments */
#endif
#endif
#ifndef MP_DEBUG
-#define MP_DEBUG 0 /* print diagnostic output? */
+#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? */
+#define MP_DEFPREC 64 /* default precision, in digits */
#endif
#ifndef MP_SQUARE
-#define MP_SQUARE 1 /* use separate squaring code? */
+#define MP_SQUARE 1 /* use separate squaring code? */
#endif
#endif /* ifndef MPI_CONFIG_H_ */
-
-
diff --git a/nss/lib/freebl/mpi/mpi-priv.h b/nss/lib/freebl/mpi/mpi-priv.h
index 7a0725f..b34452c 100644
--- a/nss/lib/freebl/mpi/mpi-priv.h
+++ b/nss/lib/freebl/mpi/mpi-priv.h
@@ -1,9 +1,9 @@
/*
- * mpi-priv.h - Private header file for MPI
+ * 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.
+ * 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
@@ -20,9 +20,14 @@
#if MP_DEBUG
#include <stdio.h>
-#define DIAG(T,V) {fprintf(stderr,T);mp_print(V,stderr);fputc('\n',stderr);}
+#define DIAG(T, V) \
+ { \
+ fprintf(stderr, T); \
+ mp_print(V, stderr); \
+ fputc('\n', stderr); \
+ }
#else
-#define DIAG(T,V)
+#define DIAG(T, V)
#endif
/* If we aren't using a wired-in logarithm table, we need to include
@@ -34,7 +39,7 @@
#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 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)
@@ -44,22 +49,22 @@
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.
+ which are the output bases supported.
*/
extern const float s_logv_2[];
-#define LOG_V_2(R) s_logv_2[(R)]
+#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))
+#define LOG_V_2(R) (log(2.0) / log(R))
#endif /* if MP_LOGTAB */
@@ -75,127 +80,81 @@ extern const float s_logv_2[];
ourselves with the low-order 2 mp_digits)
*/
-#define CARRYOUT(W) (mp_digit)((W)>>DIGIT_BIT)
-#define ACCUM(W) (mp_digit)(W)
+#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))
+#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
+#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 */
+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 */
+
+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 */
+
+void s_mp_clamp(mp_int *mp); /* clip leading zeroes */
+
+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 */
+mp_err s_mp_sqr(mp_int *a); /* magnitude square */
#else
-#define s_mp_sqr(a) s_mp_mul(a, a)
+#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);
+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
@@ -214,7 +173,7 @@ 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__)
+#if defined(__OS2__) && defined(__IBMC__)
#define MPI_ASM_DECL __cdecl
#else
#define MPI_ASM_DECL
@@ -222,50 +181,49 @@ void s_mp_sqr_comba_32(const mp_int *A, mp_int *B);
#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);
+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)
+ ((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)
-
+ ((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);
+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);
+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);
+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); */
/* Callers of this macro should be aware that the return type might vary;
* it should be treated as a void function. */
#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)
+ s_mpv_mul_d_add_prop(MP_DIGITS(a), MP_USED(a), b, MP_DIGITS(c) + off)
typedef struct {
- mp_int N; /* modulus N */
- mp_digit n0prime; /* n0' = - (n0 ** -1) mod MP_RADIX */
+ 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_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);
/*
@@ -283,4 +241,3 @@ unsigned long s_mpi_getProcessorLineSize();
/* }}} */
#endif
-
diff --git a/nss/lib/freebl/mpi/mpi-test.c b/nss/lib/freebl/mpi/mpi-test.c
deleted file mode 100644
index 1276d35..0000000
--- a/nss/lib/freebl/mpi/mpi-test.c
+++ /dev/null
@@ -1,1952 +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/. */
-
-#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/nss/lib/freebl/mpi/mpi.c b/nss/lib/freebl/mpi/mpi.c
index 84f9b97..f6f7543 100644
--- a/nss/lib/freebl/mpi/mpi.c
+++ b/nss/lib/freebl/mpi/mpi.c
@@ -22,7 +22,7 @@
#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 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)
@@ -32,58 +32,80 @@
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.
+ which are the output bases supported.
*/
#include "logtab.h"
#endif
+#ifdef CT_VERIF
+#include <valgrind/memcheck.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 */
+ "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+/";
+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)
+mp_size
+mp_get_prec(void)
{
- return s_mp_defprec;
+ return s_mp_defprec;
} /* end mp_get_prec() */
-void mp_set_prec(mp_size prec)
+void
+mp_set_prec(mp_size prec)
{
- if(prec == 0)
- s_mp_defprec = MP_DEFPREC;
- else
- s_mp_defprec = prec;
+ if (prec == 0)
+ s_mp_defprec = MP_DEFPREC;
+ else
+ s_mp_defprec = prec;
} /* end mp_set_prec() */
/* }}} */
+#ifdef CT_VERIF
+void
+mp_taint(mp_int *mp)
+{
+ size_t i;
+ for (i = 0; i < mp->used; ++i) {
+ VALGRIND_MAKE_MEM_UNDEFINED(&(mp->dp[i]), sizeof(mp_digit));
+ }
+}
+
+void
+mp_untaint(mp_int *mp)
+{
+ size_t i;
+ for (i = 0; i < mp->used; ++i) {
+ VALGRIND_MAKE_MEM_DEFINED(&(mp->dp[i]), sizeof(mp_digit));
+ }
+}
+#endif
+
/*------------------------------------------------------------------------*/
/* {{{ mp_init(mp) */
@@ -94,9 +116,10 @@ void mp_set_prec(mp_size prec)
MP_MEM if memory could not be allocated for the structure.
*/
-mp_err mp_init(mp_int *mp)
+mp_err
+mp_init(mp_int *mp)
{
- return mp_init_size(mp, s_mp_defprec);
+ return mp_init_size(mp, s_mp_defprec);
} /* end mp_init() */
@@ -112,19 +135,20 @@ mp_err mp_init(mp_int *mp)
not be allocated for the structure.
*/
-mp_err mp_init_size(mp_int *mp, mp_size prec)
+mp_err
+mp_init_size(mp_int *mp, mp_size prec)
{
- ARGCHK(mp != NULL && prec > 0, MP_BADARG);
+ 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;
+ 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;
+ SIGN(mp) = ZPOS;
+ USED(mp) = 1;
+ ALLOC(mp) = prec;
- return MP_OKAY;
+ return MP_OKAY;
} /* end mp_init_size() */
@@ -140,22 +164,23 @@ mp_err mp_init_size(mp_int *mp, mp_size prec)
structure.
*/
-mp_err mp_init_copy(mp_int *mp, const mp_int *from)
+mp_err
+mp_init_copy(mp_int *mp, const mp_int *from)
{
- ARGCHK(mp != NULL && from != NULL, MP_BADARG);
+ ARGCHK(mp != NULL && from != NULL, MP_BADARG);
- if(mp == from)
- return MP_OKAY;
+ if (mp == from)
+ return MP_OKAY;
- if((DIGITS(mp) = s_mp_alloc(ALLOC(from), sizeof(mp_digit))) == NULL)
- return MP_MEM;
+ 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);
+ s_mp_copy(DIGITS(from), DIGITS(mp), USED(from));
+ USED(mp) = USED(from);
+ ALLOC(mp) = ALLOC(from);
+ SIGN(mp) = SIGN(from);
- return MP_OKAY;
+ return MP_OKAY;
} /* end mp_init_copy() */
@@ -171,50 +196,49 @@ mp_err mp_init_copy(mp_int *mp, const mp_int *from)
instead). If 'from' and 'to' are identical, nothing happens.
*/
-mp_err mp_copy(const mp_int *from, mp_int *to)
+mp_err
+mp_copy(const mp_int *from, mp_int *to)
{
- ARGCHK(from != NULL && to != NULL, MP_BADARG);
+ ARGCHK(from != NULL && to != NULL, MP_BADARG);
- if(from == to)
- return MP_OKAY;
+ if (from == to)
+ return MP_OKAY;
- { /* copy */
- mp_digit *tmp;
+ { /* 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;
+ /*
+ 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));
- s_mp_copy(DIGITS(from), tmp, USED(from));
+ } else {
+ if ((tmp = s_mp_alloc(ALLOC(from), sizeof(mp_digit))) == NULL)
+ return MP_MEM;
- if(DIGITS(to) != NULL) {
-#if MP_CRYPTO
- s_mp_setz(DIGITS(to), ALLOC(to));
-#endif
- s_mp_free(DIGITS(to));
- }
+ s_mp_copy(DIGITS(from), tmp, USED(from));
- DIGITS(to) = tmp;
- ALLOC(to) = ALLOC(from);
- }
+ if (DIGITS(to) != NULL) {
+ s_mp_setz(DIGITS(to), ALLOC(to));
+ s_mp_free(DIGITS(to));
+ }
- /* Copy the precision and sign from the original */
- USED(to) = USED(from);
- SIGN(to) = SIGN(from);
- } /* end copy */
+ DIGITS(to) = tmp;
+ ALLOC(to) = ALLOC(from);
+ }
- return MP_OKAY;
+ /* Copy the precision and sign from the original */
+ USED(to) = USED(from);
+ SIGN(to) = SIGN(from);
+ } /* end copy */
+
+ return MP_OKAY;
} /* end mp_copy() */
@@ -230,16 +254,17 @@ mp_err mp_copy(const mp_int *from, mp_int *to)
locals it creates...). This cannot fail.
*/
-void mp_exch(mp_int *mp1, mp_int *mp2)
+void
+mp_exch(mp_int *mp1, mp_int *mp2)
{
#if MP_ARGCHK == 2
- assert(mp1 != NULL && mp2 != NULL);
+ assert(mp1 != NULL && mp2 != NULL);
#else
- if(mp1 == NULL || mp2 == NULL)
- return;
+ if (mp1 == NULL || mp2 == NULL)
+ return;
#endif
- s_mp_exch(mp1, mp2);
+ s_mp_exch(mp1, mp2);
} /* end mp_exch() */
@@ -255,21 +280,20 @@ void mp_exch(mp_int *mp1, mp_int *mp2)
get tollchocked.
*/
-void mp_clear(mp_int *mp)
+void
+mp_clear(mp_int *mp)
{
- if(mp == NULL)
- return;
+ 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;
- }
+ if (DIGITS(mp) != NULL) {
+ s_mp_setz(DIGITS(mp), ALLOC(mp));
+ s_mp_free(DIGITS(mp));
+ DIGITS(mp) = NULL;
+ }
- USED(mp) = 0;
- ALLOC(mp) = 0;
+ USED(mp) = 0;
+ ALLOC(mp) = 0;
} /* end mp_clear() */
@@ -278,19 +302,20 @@ void mp_clear(mp_int *mp)
/* {{{ mp_zero(mp) */
/*
- 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)
+void
+mp_zero(mp_int *mp)
{
- if(mp == NULL)
- return;
+ if (mp == NULL)
+ return;
- s_mp_setz(DIGITS(mp), ALLOC(mp));
- USED(mp) = 1;
- SIGN(mp) = ZPOS;
+ s_mp_setz(DIGITS(mp), ALLOC(mp));
+ USED(mp) = 1;
+ SIGN(mp) = ZPOS;
} /* end mp_zero() */
@@ -298,13 +323,14 @@ void mp_zero(mp_int *mp)
/* {{{ mp_set(mp, d) */
-void mp_set(mp_int *mp, mp_digit d)
+void
+mp_set(mp_int *mp, mp_digit d)
{
- if(mp == NULL)
- return;
+ if (mp == NULL)
+ return;
- mp_zero(mp);
- DIGIT(mp, 0) = d;
+ mp_zero(mp);
+ DIGIT(mp, 0) = d;
} /* end mp_set() */
@@ -312,34 +338,35 @@ void mp_set(mp_int *mp, mp_digit d)
/* {{{ mp_set_int(mp, z) */
-mp_err mp_set_int(mp_int *mp, long 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);
+ int ix;
+ unsigned long v = labs(z);
+ mp_err res;
- mp_zero(mp);
- if(z == 0)
- return MP_OKAY; /* shortcut for zero */
+ ARGCHK(mp != NULL, MP_BADARG);
- 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;
+ mp_zero(mp);
+ if (z == 0)
+ return MP_OKAY; /* shortcut for zero */
- res = s_mp_add_d(mp, (mp_digit)((v >> (ix * CHAR_BIT)) & UCHAR_MAX));
- if (res != MP_OKAY)
- return res;
+ 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;
+ if (z < 0)
+ SIGN(mp) = NEG;
- return MP_OKAY;
+ return MP_OKAY;
} /* end mp_set_int() */
@@ -347,30 +374,31 @@ mp_err mp_set_int(mp_int *mp, long z)
/* {{{ mp_set_ulong(mp, z) */
-mp_err mp_set_ulong(mp_int *mp, unsigned long z)
+mp_err
+mp_set_ulong(mp_int *mp, unsigned long z)
{
- int ix;
- mp_err res;
+ int ix;
+ mp_err res;
- ARGCHK(mp != NULL, MP_BADARG);
+ ARGCHK(mp != NULL, MP_BADARG);
- mp_zero(mp);
- if(z == 0)
- return MP_OKAY; /* shortcut for zero */
+ 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;
+ 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;
+ return MP_OKAY;
} /* end mp_set_ulong() */
/* }}} */
@@ -387,36 +415,37 @@ mp_err mp_set_ulong(mp_int *mp, unsigned long z)
its primary addend (single digits are unsigned anyway).
*/
-mp_err mp_add_d(const mp_int *a, mp_digit d, mp_int *b)
+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);
+ mp_int tmp;
+ mp_err res;
- if((res = mp_init_copy(&tmp, a)) != MP_OKAY)
- return res;
+ ARGCHK(a != NULL && b != NULL, MP_BADARG);
- 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);
+ 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);
- }
+ DIGIT(&tmp, 0) = d - DIGIT(&tmp, 0);
+ }
- if(s_mp_cmp_d(&tmp, 0) == 0)
- SIGN(&tmp) = ZPOS;
+ if (s_mp_cmp_d(&tmp, 0) == 0)
+ SIGN(&tmp) = ZPOS;
- s_mp_exch(&tmp, b);
+ s_mp_exch(&tmp, b);
CLEANUP:
- mp_clear(&tmp);
- return res;
+ mp_clear(&tmp);
+ return res;
} /* end mp_add_d() */
@@ -431,37 +460,38 @@ CLEANUP:
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_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);
+ mp_int tmp;
+ mp_err res;
- if((res = mp_init_copy(&tmp, a)) != MP_OKAY)
- return res;
+ ARGCHK(a != NULL && b != NULL, MP_BADARG);
- 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);
+ 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;
- }
+ DIGIT(&tmp, 0) = d - DIGIT(&tmp, 0);
+ SIGN(&tmp) = NEG;
+ }
- if(s_mp_cmp_d(&tmp, 0) == 0)
- SIGN(&tmp) = ZPOS;
+ if (s_mp_cmp_d(&tmp, 0) == 0)
+ SIGN(&tmp) = ZPOS;
- s_mp_exch(&tmp, b);
+ s_mp_exch(&tmp, b);
CLEANUP:
- mp_clear(&tmp);
- return res;
+ mp_clear(&tmp);
+ return res;
} /* end mp_sub_d() */
@@ -476,23 +506,24 @@ CLEANUP:
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
+mp_mul_d(const mp_int *a, mp_digit d, mp_int *b)
{
- mp_err res;
+ mp_err res;
- ARGCHK(a != NULL && b != NULL, MP_BADARG);
+ ARGCHK(a != NULL && b != NULL, MP_BADARG);
- if(d == 0) {
- mp_zero(b);
- return MP_OKAY;
- }
+ if (d == 0) {
+ mp_zero(b);
+ return MP_OKAY;
+ }
- if((res = mp_copy(a, b)) != MP_OKAY)
- return res;
+ if ((res = mp_copy(a, b)) != MP_OKAY)
+ return res;
- res = s_mp_mul_d(b, d);
+ res = s_mp_mul_d(b, d);
- return res;
+ return res;
} /* end mp_mul_d() */
@@ -500,16 +531,17 @@ mp_err mp_mul_d(const mp_int *a, mp_digit d, mp_int *b)
/* {{{ mp_mul_2(a, c) */
-mp_err mp_mul_2(const mp_int *a, mp_int *c)
+mp_err
+mp_mul_2(const mp_int *a, mp_int *c)
{
- mp_err res;
+ mp_err res;
- ARGCHK(a != NULL && c != NULL, MP_BADARG);
+ ARGCHK(a != NULL && c != NULL, MP_BADARG);
- if((res = mp_copy(a, c)) != MP_OKAY)
- return res;
+ if ((res = mp_copy(a, c)) != MP_OKAY)
+ return res;
- return s_mp_mul_2(c);
+ return s_mp_mul_2(c);
} /* end mp_mul_2() */
@@ -525,52 +557,56 @@ mp_err mp_mul_2(const mp_int *a, mp_int *c)
unsigned anyway).
*/
-mp_err mp_div_d(const mp_int *a, mp_digit d, mp_int *q, mp_digit *r)
+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;
+ mp_err res;
+ mp_int qp;
+ mp_digit rem = 0;
+ int pow;
- ARGCHK(a != NULL, MP_BADARG);
+ ARGCHK(a != NULL, MP_BADARG);
- if(d == 0)
- return MP_RANGE;
+ if (d == 0)
+ return MP_RANGE;
- /* Shortcut for powers of two ... */
- if((pow = s_mp_ispow2d(d)) >= 0) {
- mp_digit mask;
+ /* 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;
+ mask = ((mp_digit)1 << pow) - 1;
+ rem = DIGIT(a, 0) & mask;
- if(q) {
- mp_copy(a, q);
- s_mp_div_2d(q, pow);
- }
+ if (q) {
+ if ((res = mp_copy(a, q)) != MP_OKAY) {
+ return res;
+ }
+ s_mp_div_2d(q, pow);
+ }
- if(r)
- *r = rem;
+ if (r)
+ *r = rem;
- return MP_OKAY;
- }
+ return MP_OKAY;
+ }
- if((res = mp_init_copy(&qp, a)) != MP_OKAY)
- return res;
+ if ((res = mp_init_copy(&qp, a)) != MP_OKAY)
+ return res;
- res = s_mp_div_d(&qp, d, &rem);
+ res = s_mp_div_d(&qp, d, &rem);
- if(s_mp_cmp_d(&qp, 0) == 0)
- SIGN(q) = ZPOS;
+ if (s_mp_cmp_d(&qp, 0) == 0)
+ SIGN(q) = ZPOS;
- if(r)
- *r = rem;
+ if (r) {
+ *r = rem;
+ }
- if(q)
- s_mp_exch(&qp, q);
+ if (q)
+ s_mp_exch(&qp, q);
- mp_clear(&qp);
- return res;
+ mp_clear(&qp);
+ return res;
} /* end mp_div_d() */
@@ -584,18 +620,19 @@ mp_err mp_div_d(const mp_int *a, mp_digit d, mp_int *q, mp_digit *r)
Compute c = a / 2, disregarding the remainder.
*/
-mp_err mp_div_2(const mp_int *a, mp_int *c)
+mp_err
+mp_div_2(const mp_int *a, mp_int *c)
{
- mp_err res;
+ mp_err res;
- ARGCHK(a != NULL && c != NULL, MP_BADARG);
+ ARGCHK(a != NULL && c != NULL, MP_BADARG);
- if((res = mp_copy(a, c)) != MP_OKAY)
- return res;
+ if ((res = mp_copy(a, c)) != MP_OKAY)
+ return res;
- s_mp_div_2(c);
+ s_mp_div_2(c);
- return MP_OKAY;
+ return MP_OKAY;
} /* end mp_div_2() */
@@ -603,40 +640,41 @@ mp_err mp_div_2(const mp_int *a, mp_int *c)
/* {{{ mp_expt_d(a, d, b) */
-mp_err mp_expt_d(const mp_int *a, mp_digit d, mp_int *c)
+mp_err
+mp_expt_d(const mp_int *a, mp_digit d, mp_int *c)
{
- mp_int s, x;
- mp_err res;
+ mp_int s, x;
+ mp_err res;
- ARGCHK(a != NULL && c != NULL, MP_BADARG);
+ 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;
+ if ((res = mp_init(&s)) != MP_OKAY)
+ return res;
+ if ((res = mp_init_copy(&x, a)) != MP_OKAY)
+ goto X;
- DIGIT(&s, 0) = 1;
+ DIGIT(&s, 0) = 1;
- while(d != 0) {
- if(d & 1) {
- if((res = s_mp_mul(&s, &x)) != MP_OKAY)
- goto CLEANUP;
- }
+ while (d != 0) {
+ if (d & 1) {
+ if ((res = s_mp_mul(&s, &x)) != MP_OKAY)
+ goto CLEANUP;
+ }
- d /= 2;
+ d /= 2;
- if((res = s_mp_sqr(&x)) != MP_OKAY)
- goto CLEANUP;
- }
+ if ((res = s_mp_sqr(&x)) != MP_OKAY)
+ goto CLEANUP;
+ }
- s_mp_exch(&s, c);
+ s_mp_exch(&s, c);
CLEANUP:
- mp_clear(&x);
+ mp_clear(&x);
X:
- mp_clear(&s);
+ mp_clear(&s);
- return res;
+ return res;
} /* end mp_expt_d() */
@@ -655,18 +693,19 @@ X:
Compute b = |a|. 'a' and 'b' may be identical.
*/
-mp_err mp_abs(const mp_int *a, mp_int *b)
+mp_err
+mp_abs(const mp_int *a, mp_int *b)
{
- mp_err res;
+ mp_err res;
- ARGCHK(a != NULL && b != NULL, MP_BADARG);
+ ARGCHK(a != NULL && b != NULL, MP_BADARG);
- if((res = mp_copy(a, b)) != MP_OKAY)
- return res;
+ if ((res = mp_copy(a, b)) != MP_OKAY)
+ return res;
- SIGN(b) = ZPOS;
+ SIGN(b) = ZPOS;
- return MP_OKAY;
+ return MP_OKAY;
} /* end mp_abs() */
@@ -680,21 +719,22 @@ mp_err mp_abs(const mp_int *a, mp_int *b)
Compute b = -a. 'a' and 'b' may be identical.
*/
-mp_err mp_neg(const mp_int *a, mp_int *b)
+mp_err
+mp_neg(const mp_int *a, mp_int *b)
{
- mp_err res;
+ mp_err res;
- ARGCHK(a != NULL && b != NULL, MP_BADARG);
+ ARGCHK(a != NULL && b != NULL, MP_BADARG);
- if((res = mp_copy(a, b)) != MP_OKAY)
- return res;
+ 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;
+ if (s_mp_cmp_d(b, 0) == MP_EQ)
+ SIGN(b) = ZPOS;
+ else
+ SIGN(b) = (SIGN(b) == NEG) ? ZPOS : NEG;
- return MP_OKAY;
+ return MP_OKAY;
} /* end mp_neg() */
@@ -708,25 +748,26 @@ mp_err mp_neg(const mp_int *a, mp_int *b)
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
+mp_add(const mp_int *a, const mp_int *b, mp_int *c)
{
- mp_err res;
+ mp_err res;
- ARGCHK(a != NULL && b != NULL && c != NULL, MP_BADARG);
+ 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 (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;
+ if (s_mp_cmp_d(c, 0) == MP_EQ)
+ SIGN(c) = ZPOS;
CLEANUP:
- return res;
+ return res;
} /* end mp_add() */
@@ -740,35 +781,36 @@ CLEANUP:
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
+mp_sub(const mp_int *a, const mp_int *b, mp_int *c)
{
- mp_err res;
- int magDiff;
+ mp_err res;
+ int magDiff;
- ARGCHK(a != NULL && b != NULL && c != NULL, MP_BADARG);
+ ARGCHK(a != NULL && b != NULL && c != NULL, MP_BADARG);
- if (a == b) {
- mp_zero(c);
- return MP_OKAY;
- }
+ 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 (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;
+ if (s_mp_cmp_d(c, 0) == MP_EQ)
+ MP_SIGN(c) = MP_ZPOS;
CLEANUP:
- return res;
+ return res;
} /* end mp_sub() */
@@ -781,87 +823,89 @@ CLEANUP:
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_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;
- }
+ 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;
- }
+ 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;
+ 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;
- }
- }
+ 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));
+ 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++;
+ /* 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;
- }
+ /* 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);
+ s_mp_clamp(c);
- if(SIGN(a) == SIGN(b) || s_mp_cmp_d(c, 0) == MP_EQ)
- SIGN(c) = ZPOS;
- else
- SIGN(c) = NEG;
+ 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;
+ mp_clear(&tmp);
+ return res;
} /* end mp_mul() */
/* }}} */
@@ -878,81 +922,82 @@ CLEANUP:
*/
/* sqr = a^2; Caller provides both a and tmp; */
-mp_err mp_sqr(const mp_int *a, mp_int *sqr)
+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;
- }
+ 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;
+ 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;
- }
- }
+ 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);
+ 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;
+ mp_clear(&tmp);
+ return res;
} /* end mp_sqr() */
#endif
@@ -968,85 +1013,86 @@ CLEANUP:
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
+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);
+ 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_set(pQ, 1);
- mp_zero(pR);
+ MP_CHECKOK(s_mp_pad(q, MP_USED(a)));
+ pQ = q;
+ mp_zero(pQ);
}
- } 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 |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;
+ 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);
+ /* Copy output, if it is needed */
+ if (q && q != pQ)
+ s_mp_exch(pQ, q);
- if(r && r != pR)
- s_mp_exch(pR, r);
+ if (r && r != pR)
+ s_mp_exch(pR, r);
CLEANUP:
- mp_clear(&btmp);
- mp_clear(&rtmp);
- mp_clear(&qtmp);
+ mp_clear(&btmp);
+ mp_clear(&rtmp);
+ mp_clear(&qtmp);
- return res;
+ return res;
} /* end mp_div() */
@@ -1054,28 +1100,29 @@ CLEANUP:
/* {{{ 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
+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;
+ 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() */
@@ -1090,70 +1137,71 @@ mp_err mp_div_2d(const mp_int *a, mp_digit d, mp_int *q, mp_int *r)
standard iterative square-and-multiply technique.
*/
-mp_err mp_expt(mp_int *a, mp_int *b, mp_int *c)
+mp_err
+mp_expt(mp_int *a, mp_int *b, mp_int *c)
{
- mp_int s, x;
- mp_err res;
- mp_digit d;
- unsigned int dig, bit;
+ mp_int s, x;
+ mp_err res;
+ mp_digit d;
+ unsigned int dig, bit;
- ARGCHK(a != NULL && b != NULL && c != NULL, MP_BADARG);
+ ARGCHK(a != NULL && b != NULL && c != NULL, MP_BADARG);
- if(mp_cmp_z(b) < 0)
- return MP_RANGE;
+ if (mp_cmp_z(b) < 0)
+ return MP_RANGE;
- if((res = mp_init(&s)) != MP_OKAY)
- return res;
+ if ((res = mp_init(&s)) != MP_OKAY)
+ return res;
+
+ mp_set(&s, 1);
- mp_set(&s, 1);
+ if ((res = mp_init_copy(&x, a)) != MP_OKAY)
+ goto X;
- 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 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;
+ }
- /* 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;
- d >>= 1;
-
- if((res = s_mp_sqr(&x)) != MP_OKAY)
- goto CLEANUP;
+ if ((res = s_mp_sqr(&x)) != MP_OKAY)
+ goto CLEANUP;
+ }
}
- }
- /* Consider now the last digit... */
- d = DIGIT(b, dig);
+ /* 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;
- }
+ while (d) {
+ if (d & 1) {
+ if ((res = s_mp_mul(&s, &x)) != MP_OKAY)
+ goto CLEANUP;
+ }
- d >>= 1;
+ d >>= 1;
- if((res = s_mp_sqr(&x)) != MP_OKAY)
- goto CLEANUP;
- }
-
- if(mp_iseven(b))
- SIGN(&s) = SIGN(a);
+ if ((res = s_mp_sqr(&x)) != MP_OKAY)
+ goto CLEANUP;
+ }
- res = mp_copy(&s, c);
+ if (mp_iseven(b))
+ SIGN(&s) = SIGN(a);
+
+ res = mp_copy(&s, c);
CLEANUP:
- mp_clear(&x);
+ mp_clear(&x);
X:
- mp_clear(&s);
+ mp_clear(&s);
- return res;
+ return res;
} /* end mp_expt() */
@@ -1163,11 +1211,12 @@ X:
/* Compute a = 2^k */
-mp_err mp_2expt(mp_int *a, mp_digit k)
+mp_err
+mp_2expt(mp_int *a, mp_digit k)
{
- ARGCHK(a != NULL, MP_BADARG);
+ ARGCHK(a != NULL, MP_BADARG);
- return s_mp_2expt(a, k);
+ return s_mp_2expt(a, k);
} /* end mp_2expt() */
@@ -1181,19 +1230,20 @@ mp_err mp_2expt(mp_int *a, mp_digit k)
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
+mp_mod(const mp_int *a, const mp_int *m, mp_int *c)
{
- mp_err res;
- int mag;
+ mp_err res;
+ int mag;
- ARGCHK(a != NULL && m != NULL && c != NULL, MP_BADARG);
+ ARGCHK(a != NULL && m != NULL && c != NULL, MP_BADARG);
- if(SIGN(m) == NEG)
- return MP_RANGE;
+ if (SIGN(m) == NEG)
+ return MP_RANGE;
- /*
+ /*
If |a| > m, we need to divide to get the remainder and take the
- absolute value.
+ absolute value.
If |a| < m, we don't need to do any division, just copy and adjust
the sign (if a is negative).
@@ -1203,32 +1253,30 @@ mp_err mp_mod(const mp_int *a, const mp_int *m, mp_int *c)
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;
- }
+ */
+ if ((mag = s_mp_cmp(a, m)) > 0) {
+ if ((res = mp_div(a, m, NULL, c)) != MP_OKAY)
+ return res;
- } else if(mag < 0) {
- if((res = mp_copy(a, c)) != MP_OKAY)
- return res;
+ if (SIGN(c) == NEG) {
+ if ((res = mp_add(c, m, c)) != MP_OKAY)
+ return res;
+ }
- if(mp_cmp_z(a) < 0) {
- 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;
- }
-
- } else {
- mp_zero(c);
+ if (mp_cmp_z(a) < 0) {
+ if ((res = mp_add(c, m, c)) != MP_OKAY)
+ return res;
+ }
- }
+ } else {
+ mp_zero(c);
+ }
- return MP_OKAY;
+ return MP_OKAY;
} /* end mp_mod() */
@@ -1241,115 +1289,34 @@ mp_err mp_mod(const mp_int *a, const mp_int *m, mp_int *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
+mp_mod_d(const mp_int *a, mp_digit d, mp_digit *c)
{
- mp_err res;
- mp_digit rem;
+ mp_err res;
+ mp_digit rem;
- ARGCHK(a != NULL && c != NULL, MP_BADARG);
+ 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;
+ 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);
- }
+ } else {
+ if (SIGN(a) == NEG)
+ rem = d - DIGIT(a, 0);
+ else
+ rem = DIGIT(a, 0);
+ }
- if(c)
- *c = rem;
+ if (c)
+ *c = rem;
- return MP_OKAY;
+ 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() */
-
-/* }}} */
-
/* }}} */
/*------------------------------------------------------------------------*/
@@ -1364,19 +1331,19 @@ mp_err mp_sqrt(const mp_int *a, mp_int *b)
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
+mp_addmod(const mp_int *a, const mp_int *b, const mp_int *m, mp_int *c)
{
- mp_err res;
+ mp_err res;
- ARGCHK(a != NULL && b != NULL && m != NULL && c != NULL, MP_BADARG);
+ 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;
+ 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;
}
/* }}} */
@@ -1389,19 +1356,19 @@ mp_err mp_addmod(const mp_int *a, const mp_int *b, const mp_int *m, mp_int *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
+mp_submod(const mp_int *a, const mp_int *b, const mp_int *m, mp_int *c)
{
- mp_err res;
+ mp_err res;
- ARGCHK(a != NULL && b != NULL && m != NULL && c != NULL, MP_BADARG);
+ 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;
+ 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;
}
/* }}} */
@@ -1414,19 +1381,19 @@ mp_err mp_submod(const mp_int *a, const mp_int *b, const mp_int *m, mp_int *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
+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);
+ mp_err res;
- if((res = mp_mul(a, b, c)) != MP_OKAY)
- return res;
- if((res = mp_mod(c, m, c)) != MP_OKAY)
- return res;
+ ARGCHK(a != NULL && b != NULL && m != NULL && c != NULL, MP_BADARG);
- return MP_OKAY;
+ 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;
}
/* }}} */
@@ -1434,18 +1401,19 @@ mp_err mp_mulmod(const mp_int *a, const mp_int *b, const mp_int *m, mp_int *c)
/* {{{ 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
+mp_sqrmod(const mp_int *a, const mp_int *m, mp_int *c)
{
- mp_err res;
+ mp_err res;
- ARGCHK(a != NULL && m != NULL && c != NULL, MP_BADARG);
+ 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;
+ if ((res = mp_sqr(a, c)) != MP_OKAY)
+ return res;
+ if ((res = mp_mod(c, m, c)) != MP_OKAY)
+ return res;
- return MP_OKAY;
+ return MP_OKAY;
} /* end mp_sqrmod() */
#endif
@@ -1460,90 +1428,93 @@ mp_err mp_sqrmod(const mp_int *a, const mp_int *m, mp_int *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_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;
- unsigned 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;
+ mp_int s, x, mu;
+ mp_err res;
+ mp_digit d;
+ unsigned 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 */
+ if ((res = s_mp_add_d(&mu, 1)) != MP_OKAY)
+ goto CLEANUP;
+ if ((res = s_mp_lshd(&mu, 2 * USED(m))) != MP_OKAY)
+ goto CLEANUP;
+ 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;
+ }
+ }
- 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++) {
+ /* Now do the last digit... */
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;
- }
+ 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;
+ d >>= 1;
- if((res = s_mp_sqr(&x)) != MP_OKAY)
- goto CLEANUP;
- if((res = s_mp_reduce(&x, m, &mu)) != MP_OKAY)
- goto CLEANUP;
+ 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);
- s_mp_exch(&s, c);
-
- CLEANUP:
- mp_clear(&mu);
- MU:
- mp_clear(&x);
- X:
- mp_clear(&s);
+CLEANUP:
+ mp_clear(&mu);
+MU:
+ mp_clear(&x);
+X:
+ mp_clear(&s);
- return res;
+ return res;
} /* end s_mp_exptmod() */
@@ -1551,42 +1522,43 @@ mp_err s_mp_exptmod(const mp_int *a, const mp_int *b, const mp_int *m, mp_int *c
/* {{{ 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_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;
+ mp_int s, x;
+ mp_err res;
- ARGCHK(a != NULL && c != NULL, MP_BADARG);
+ 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;
+ if ((res = mp_init(&s)) != MP_OKAY)
+ return res;
+ if ((res = mp_init_copy(&x, a)) != MP_OKAY)
+ goto X;
- mp_set(&s, 1);
+ 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;
- }
+ 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;
+ d /= 2;
- if((res = s_mp_sqr(&x)) != MP_OKAY ||
- (res = mp_mod(&x, m, &x)) != MP_OKAY)
- goto CLEANUP;
- }
+ if ((res = s_mp_sqr(&x)) != MP_OKAY ||
+ (res = mp_mod(&x, m, &x)) != MP_OKAY)
+ goto CLEANUP;
+ }
- s_mp_exch(&s, c);
+ s_mp_exch(&s, c);
CLEANUP:
- mp_clear(&x);
+ mp_clear(&x);
X:
- mp_clear(&s);
+ mp_clear(&s);
- return res;
+ return res;
} /* end mp_exptmod_d() */
@@ -1606,14 +1578,15 @@ X:
Compare a <=> 0. Returns <0 if a<0, 0 if a=0, >0 if a>0.
*/
-int mp_cmp_z(const mp_int *a)
+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;
+ 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() */
@@ -1627,14 +1600,15 @@ int mp_cmp_z(const mp_int *a)
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)
+int
+mp_cmp_d(const mp_int *a, mp_digit d)
{
- ARGCHK(a != NULL, MP_EQ);
+ ARGCHK(a != NULL, MP_EQ);
- if(SIGN(a) == NEG)
- return MP_LT;
+ if (SIGN(a) == NEG)
+ return MP_LT;
- return s_mp_cmp_d(a, d);
+ return s_mp_cmp_d(a, d);
} /* end mp_cmp_d() */
@@ -1642,26 +1616,27 @@ int mp_cmp_d(const mp_int *a, mp_digit d)
/* {{{ mp_cmp(a, b) */
-int mp_cmp(const mp_int *a, const mp_int *b)
+int
+mp_cmp(const mp_int *a, const mp_int *b)
{
- ARGCHK(a != NULL && b != NULL, MP_EQ);
+ ARGCHK(a != NULL && b != NULL, MP_EQ);
- if(SIGN(a) == SIGN(b)) {
- int mag;
+ if (SIGN(a) == SIGN(b)) {
+ int mag;
- if((mag = s_mp_cmp(a, b)) == MP_EQ)
- return MP_EQ;
+ if ((mag = s_mp_cmp(a, b)) == MP_EQ)
+ return MP_EQ;
- if(SIGN(a) == ZPOS)
- return mag;
- else
- return -mag;
+ if (SIGN(a) == ZPOS)
+ return mag;
+ else
+ return -mag;
- } else if(SIGN(a) == ZPOS) {
- return MP_GT;
- } else {
- return MP_LT;
- }
+ } else if (SIGN(a) == ZPOS) {
+ return MP_GT;
+ } else {
+ return MP_LT;
+ }
} /* end mp_cmp() */
@@ -1675,41 +1650,17 @@ int mp_cmp(const mp_int *a, const mp_int *b)
Compares |a| <=> |b|, and returns an appropriate comparison result
*/
-int mp_cmp_mag(mp_int *a, mp_int *b)
+int
+mp_cmp_mag(const mp_int *a, const mp_int *b)
{
- ARGCHK(a != NULL && b != NULL, MP_EQ);
+ ARGCHK(a != NULL && b != NULL, MP_EQ);
- return s_mp_cmp(a, b);
+ 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) */
/*
@@ -1717,11 +1668,12 @@ int mp_cmp_int(const mp_int *a, long z)
Returns a true (non-zero) value if a is odd, false (zero) otherwise.
*/
-int mp_isodd(const mp_int *a)
+int
+mp_isodd(const mp_int *a)
{
- ARGCHK(a != NULL, 0);
+ ARGCHK(a != NULL, 0);
- return (int)(DIGIT(a, 0) & 1);
+ return (int)(DIGIT(a, 0) & 1);
} /* end mp_isodd() */
@@ -1729,9 +1681,10 @@ int mp_isodd(const mp_int *a)
/* {{{ mp_iseven(a) */
-int mp_iseven(const mp_int *a)
+int
+mp_iseven(const mp_int *a)
{
- return !mp_isodd(a);
+ return !mp_isodd(a);
} /* end mp_iseven() */
@@ -1749,94 +1702,94 @@ int mp_iseven(const mp_int *a)
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
+mp_gcd(mp_int *a, mp_int *b, mp_int *c)
{
- mp_err res;
- mp_int u, v, t;
- mp_size k = 0;
+ 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);
+ }
- ARGCHK(a != NULL && b != NULL && c != NULL, MP_BADARG);
+ 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;
+ }
- 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);
- }
+ /* Initialize t */
+ if (mp_isodd(&u)) {
+ if ((res = mp_copy(&v, &t)) != MP_OKAY)
+ goto CLEANUP;
- 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;
+ /* t = -v */
+ if (SIGN(&v) == ZPOS)
+ SIGN(&t) = NEG;
+ else
+ SIGN(&t) = ZPOS;
- }
-
- for(;;) {
- while(mp_iseven(&t)) {
- s_mp_div_2(&t);
+ } else {
+ if ((res = mp_copy(&u, &t)) != MP_OKAY)
+ goto CLEANUP;
}
- if(mp_cmp_z(&t) == MP_GT) {
- if((res = mp_copy(&t, &u)) != MP_OKAY)
- goto CLEANUP;
+ for (;;) {
+ while (mp_iseven(&t)) {
+ s_mp_div_2(&t);
+ }
- } else {
- if((res = mp_copy(&t, &v)) != MP_OKAY)
- goto CLEANUP;
+ if (mp_cmp_z(&t) == MP_GT) {
+ if ((res = mp_copy(&t, &u)) != MP_OKAY)
+ goto CLEANUP;
- /* v = -t */
- if(SIGN(&t) == ZPOS)
- SIGN(&v) = NEG;
- else
- SIGN(&v) = ZPOS;
- }
+ } else {
+ if ((res = mp_copy(&t, &v)) != MP_OKAY)
+ goto CLEANUP;
- if((res = mp_sub(&u, &v, &t)) != MP_OKAY)
- goto CLEANUP;
+ /* v = -t */
+ if (SIGN(&t) == ZPOS)
+ SIGN(&v) = NEG;
+ else
+ SIGN(&v) = ZPOS;
+ }
- if(s_mp_cmp_d(&t, 0) == MP_EQ)
- break;
- }
+ if ((res = mp_sub(&u, &v, &t)) != MP_OKAY)
+ goto CLEANUP;
- s_mp_2expt(&v, k); /* v = 2^k */
- res = mp_mul(&u, &v, c); /* c = u * v */
+ if (s_mp_cmp_d(&t, 0) == MP_EQ)
+ break;
+ }
- CLEANUP:
- mp_clear(&v);
- V:
- mp_clear(&u);
- U:
- mp_clear(&t);
+ s_mp_2expt(&v, k); /* v = 2^k */
+ res = mp_mul(&u, &v, c); /* c = u * v */
- return res;
+CLEANUP:
+ mp_clear(&v);
+V:
+ mp_clear(&u);
+U:
+ mp_clear(&t);
+
+ return res;
} /* end mp_gcd() */
@@ -1851,32 +1804,33 @@ mp_err mp_gcd(mp_int *a, mp_int *b, mp_int *c)
... by computing the product, and dividing out the gcd.
*/
-mp_err mp_lcm(mp_int *a, mp_int *b, mp_int *c)
+mp_err
+mp_lcm(mp_int *a, mp_int *b, mp_int *c)
{
- mp_int gcd, prod;
- mp_err res;
+ mp_int gcd, prod;
+ mp_err res;
- ARGCHK(a != NULL && b != NULL && c != NULL, MP_BADARG);
+ 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;
+ /* 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;
+ 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);
+ res = mp_div(&prod, &gcd, c, NULL);
- CLEANUP:
- mp_clear(&prod);
- GCD:
- mp_clear(&gcd);
+CLEANUP:
+ mp_clear(&prod);
+GCD:
+ mp_clear(&gcd);
- return res;
+ return res;
} /* end mp_lcm() */
@@ -1893,156 +1847,161 @@ mp_err mp_lcm(mp_int *a, mp_int *b, mp_int *c)
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_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) );
+ 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));
}
- } 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) );
+ MP_CHECKOK(mp_copy(&xc, &u));
+ MP_CHECKOK(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--]);
+CLEANUP:
+ while (last >= 0)
+ mp_clear(clean[last--]);
- return res;
+ return res;
} /* end mp_xgcd() */
/* }}} */
-mp_size mp_trailing_zeros(const mp_int *mp)
+mp_size
+mp_trailing_zeros(const mp_int *mp)
{
- mp_digit d;
- mp_size n = 0;
- unsigned int ix;
+ mp_digit d;
+ mp_size n = 0;
+ unsigned int ix;
- if (!mp || !MP_DIGITS(mp) || !mp_cmp_z(mp))
- return n;
+ 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 ... */
+ 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;
- }
+ 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 (!(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));
+ assert(0 != (d & 1));
#endif
- return n;
+ return n;
}
/* Given a and prime p, computes c and k such that a*c == 2**k (mod p).
@@ -2050,337 +2009,343 @@ mp_size mp_trailing_zeros(const mp_int *mp)
** 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
+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) );
+ 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;
}
- res = k;
- }
CLEANUP:
- mp_clear(&d);
- mp_clear(&f);
- mp_clear(&g);
- return res;
+ 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
+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);
+ 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);
+ T *= 2 - (P * T);
+ T *= 2 - (P * T);
#endif
- return T;
+ return T;
}
-/* Given c, k, and prime p, where a*c == 2**k (mod p),
+/* 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)
+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;
+ 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;
+ 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)
+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);
+ int k;
+ mp_err res;
+ mp_int x;
- if(mp_cmp_z(a) == 0 || mp_cmp_z(m) == 0)
- return MP_RANGE;
- if (mp_iseven(m))
- return MP_UNDEF;
+ ARGCHK(a && m && c, MP_BADARG);
- MP_DIGITS(&x) = 0;
+ if (mp_cmp_z(a) == 0 || mp_cmp_z(m) == 0)
+ return MP_RANGE;
+ if (mp_iseven(m))
+ return MP_UNDEF;
- 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) );
+ 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;
+ 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_err
+mp_invmod_xgcd(const mp_int *a, const mp_int *m, mp_int *c)
{
- mp_int g, x;
- mp_err res;
+ mp_int g, x;
+ mp_err res;
- ARGCHK(a && m && c, MP_BADARG);
+ ARGCHK(a && m && c, MP_BADARG);
- if(mp_cmp_z(a) == 0 || mp_cmp_z(m) == 0)
- return MP_RANGE;
+ 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_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) );
+ MP_CHECKOK(mp_xgcd(a, m, &g, &x, NULL));
- if (mp_cmp_d(&g, 1) != MP_EQ) {
- res = MP_UNDEF;
- goto CLEANUP;
- }
+ if (mp_cmp_d(&g, 1) != MP_EQ) {
+ res = MP_UNDEF;
+ goto CLEANUP;
+ }
- res = mp_mod(&x, m, c);
- SIGN(c) = SIGN(a);
+ res = mp_mod(&x, m, c);
+ SIGN(c) = SIGN(a);
CLEANUP:
- mp_clear(&x);
- mp_clear(&g);
+ mp_clear(&x);
+ mp_clear(&g);
- return res;
+ 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
+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);
- }
+ 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_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
+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.
- */
+ 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 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 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) );
+ /* 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_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) */
/*
@@ -2391,21 +2356,22 @@ CLEANUP:
MP_UNDEF is returned, and there is no inverse.
*/
-mp_err mp_invmod(const mp_int *a, const mp_int *m, mp_int *c)
+mp_err
+mp_invmod(const mp_int *a, const mp_int *m, mp_int *c)
{
- ARGCHK(a && m && c, MP_BADARG);
+ ARGCHK(a && m && c, MP_BADARG);
- if(mp_cmp_z(a) == 0 || mp_cmp_z(m) == 0)
- return MP_RANGE;
+ 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 */
+ 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);
+ return s_mp_invmod_even_m(a, m, c);
} /* end mp_invmod() */
@@ -2425,18 +2391,19 @@ mp_err mp_invmod(const mp_int *a, const mp_int *m, mp_int *c)
stream 'ofp'. Output is generated using the internal radix.
*/
-void mp_print(mp_int *mp, FILE *ofp)
+void
+mp_print(mp_int *mp, FILE *ofp)
{
- int ix;
+ int ix;
- if(mp == NULL || ofp == NULL)
- return;
+ if (mp == NULL || ofp == NULL)
+ return;
- fputc((SIGN(mp) == NEG) ? '-' : '+', ofp);
+ fputc((SIGN(mp) == NEG) ? '-' : '+', ofp);
- for(ix = USED(mp) - 1; ix >= 0; ix--) {
- fprintf(ofp, DIGIT_FMT, DIGIT(mp, ix));
- }
+ for (ix = USED(mp) - 1; ix >= 0; ix--) {
+ fprintf(ofp, DIGIT_FMT, DIGIT(mp, ix));
+ }
} /* end mp_print() */
@@ -2449,37 +2416,38 @@ void mp_print(mp_int *mp, FILE *ofp)
/* {{{ 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)
+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);
+ int ix;
+ mp_err res;
+ unsigned char *ustr = (unsigned char *)str;
- mp_zero(mp);
+ ARGCHK(mp != NULL && str != NULL && len > 0, MP_BADARG);
- /* Get sign from first byte */
- if(ustr[0])
- SIGN(mp) = NEG;
- else
- SIGN(mp) = ZPOS;
+ mp_zero(mp);
- /* 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;
- }
+ /* 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;
+ return MP_OKAY;
} /* end mp_read_raw() */
@@ -2487,11 +2455,12 @@ mp_err mp_read_raw(mp_int *mp, char *str, int len)
/* {{{ mp_raw_size(mp) */
-int mp_raw_size(mp_int *mp)
+int
+mp_raw_size(mp_int *mp)
{
- ARGCHK(mp != NULL, 0);
+ ARGCHK(mp != NULL, 0);
- return (USED(mp) * sizeof(mp_digit)) + 1;
+ return (USED(mp) * sizeof(mp_digit)) + 1;
} /* end mp_raw_size() */
@@ -2499,25 +2468,26 @@ int mp_raw_size(mp_int *mp)
/* {{{ mp_toraw(mp, str) */
-mp_err mp_toraw(mp_int *mp, char *str)
+mp_err
+mp_toraw(mp_int *mp, char *str)
{
- int ix, jx, pos = 1;
+ int ix, jx, pos = 1;
- ARGCHK(mp != NULL && str != NULL, MP_BADARG);
+ ARGCHK(mp != NULL && str != NULL, MP_BADARG);
- str[0] = (char)SIGN(mp);
+ str[0] = (char)SIGN(mp);
- /* Iterate over each digit... */
- for(ix = USED(mp) - 1; ix >= 0; ix--) {
- mp_digit d = DIGIT(mp, ix);
+ /* 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));
+ /* 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;
+ return MP_OKAY;
} /* end mp_toraw() */
@@ -2534,103 +2504,106 @@ mp_err mp_toraw(mp_int *mp, char *str)
character or the end of the string.
*/
-mp_err mp_read_radix(mp_int *mp, const char *str, int radix)
+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;
+ int ix = 0, val = 0;
+ mp_err res;
+ mp_sign sig = ZPOS;
+
+ ARGCHK(mp != NULL && str != NULL && radix >= 2 && radix <= MAX_RADIX,
+ MP_BADARG);
- return MP_OKAY;
+ 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)
+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;
+ 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
+mp_radix_size(mp_int *mp, int radix)
{
- int bits;
+ int bits;
+
+ if (!mp || radix < 2 || radix > MAX_RADIX)
+ return 0;
- if(!mp || radix < 2 || radix > MAX_RADIX)
- return 0;
+ bits = USED(mp) * DIGIT_BIT - 1;
- bits = USED(mp) * DIGIT_BIT - 1;
-
- return s_mp_outlen(bits, radix);
+ return s_mp_outlen(bits, radix);
} /* end mp_radix_size() */
@@ -2638,64 +2611,66 @@ int mp_radix_size(mp_int *mp, int radix)
/* {{{ mp_toradix(mp, str, radix) */
-mp_err mp_toradix(mp_int *mp, char *str, int 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;
+ int ix, pos = 0;
- if((res = mp_init_copy(&tmp, mp)) != MP_OKAY)
- return res;
+ ARGCHK(mp != NULL && str != NULL, MP_BADARG);
+ ARGCHK(radix > 1 && radix <= MAX_RADIX, MP_RANGE);
- /* 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;
+ 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);
}
-
- mp_clear(&tmp);
- }
- return MP_OKAY;
+ return MP_OKAY;
} /* end mp_toradix() */
@@ -2703,9 +2678,10 @@ mp_err mp_toradix(mp_int *mp, char *str, int radix)
/* {{{ mp_tovalue(ch, r) */
-int mp_tovalue(char ch, int r)
+int
+mp_tovalue(char ch, int r)
{
- return s_mp_tovalue(ch, r);
+ return s_mp_tovalue(ch, r);
} /* end mp_tovalue() */
@@ -2723,17 +2699,18 @@ int mp_tovalue(char ch, int r)
not attempt to modify or free the memory associated with this
string.
*/
-const char *mp_strerror(mp_err ec)
+const char *
+mp_strerror(mp_err ec)
{
- int aec = (ec < 0) ? -ec : ec;
+ int aec = (ec < 0) ? -ec : ec;
- /* Code values are negative, so the senses of these comparisons
+ /* 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];
- }
+ 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() */
@@ -2748,28 +2725,27 @@ const char *mp_strerror(mp_err ec)
/* {{{ 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)
+mp_err
+s_mp_grow(mp_int *mp, mp_size min)
{
- if(min > ALLOC(mp)) {
- mp_digit *tmp;
+ if (min > ALLOC(mp)) {
+ mp_digit *tmp;
- /* Set min to next nearest default precision block size */
- min = MP_ROUNDUP(min, s_mp_defprec);
+ /* 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;
+ if ((tmp = s_mp_alloc(min, sizeof(mp_digit))) == NULL)
+ return MP_MEM;
- s_mp_copy(DIGITS(mp), tmp, USED(mp));
+ 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;
- }
+ s_mp_setz(DIGITS(mp), ALLOC(mp));
+ s_mp_free(DIGITS(mp));
+ DIGITS(mp) = tmp;
+ ALLOC(mp) = min;
+ }
- return MP_OKAY;
+ return MP_OKAY;
} /* end s_mp_grow() */
@@ -2778,24 +2754,25 @@ mp_err s_mp_grow(mp_int *mp, mp_size min)
/* {{{ 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)
+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));
+ 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;
}
- /* Increase precision; should already be 0-filled */
- USED(mp) = min;
- }
-
- return MP_OKAY;
+ return MP_OKAY;
} /* end s_mp_pad() */
@@ -2803,99 +2780,91 @@ mp_err s_mp_pad(mp_int *mp, mp_size min)
/* {{{ 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)
+void
+s_mp_setz(mp_digit *dp, mp_size count)
{
#if MP_MEMSET == 0
- int ix;
+ int ix;
- for(ix = 0; ix < count; ix++)
- dp[ix] = 0;
+ for (ix = 0; ix < count; ix++)
+ dp[ix] = 0;
#else
- memset(dp, 0, count * sizeof(mp_digit));
+ 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)
+void
+s_mp_copy(const mp_digit *sp, mp_digit *dp, mp_size count)
{
#if MP_MEMCPY == 0
- int ix;
+ int ix;
- for(ix = 0; ix < count; ix++)
- dp[ix] = sp[ix];
+ for (ix = 0; ix < count; ix++)
+ dp[ix] = sp[ix];
#else
- memcpy(dp, sp, count * sizeof(mp_digit));
+ 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)
+void *
+s_mp_alloc(size_t nb, size_t ni)
{
- ++mp_allocs;
- return calloc(nb, ni);
+ 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)
+void
+s_mp_free(void *ptr)
{
- if(ptr) {
- ++mp_frees;
- free(ptr);
- }
+ if (ptr) {
+ 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)
+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;
+ 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)
+void
+s_mp_exch(mp_int *a, mp_int *b)
{
- mp_int tmp;
+ mp_int tmp;
- tmp = *a;
- *a = *b;
- *b = tmp;
+ tmp = *a;
+ *a = *b;
+ *b = tmp;
} /* end s_mp_exch() */
@@ -2907,36 +2876,37 @@ void s_mp_exch(mp_int *a, mp_int *b)
/* {{{ 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
+s_mp_lshd(mp_int *mp, mp_size p)
{
- mp_err res;
- unsigned int ix;
+ mp_err res;
+ unsigned int ix;
- if(p == 0)
- return MP_OKAY;
+ if (p == 0)
+ return MP_OKAY;
- if (MP_USED(mp) == 1 && MP_DIGIT(mp, 0) == 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;
+ if ((res = s_mp_pad(mp, USED(mp) + p)) != MP_OKAY)
+ return res;
- /* Shift all the significant figures over as needed */
- for (ix = USED(mp) - p; ix-- > 0;) {
- DIGIT(mp, ix + p) = DIGIT(mp, ix);
- }
+ /* Shift all the significant figures over as needed */
+ for (ix = USED(mp) - p; ix-- > 0;) {
+ DIGIT(mp, ix + p) = DIGIT(mp, ix);
+ }
- /* Fill the bottom digits with zeroes */
- for(ix = 0; (mp_size)ix < p; ix++)
- DIGIT(mp, ix) = 0;
+ /* Fill the bottom digits with zeroes */
+ for (ix = 0; (mp_size)ix < p; ix++)
+ DIGIT(mp, ix) = 0;
- return MP_OKAY;
+ return MP_OKAY;
} /* end s_mp_lshd() */
@@ -2948,81 +2918,82 @@ mp_err s_mp_lshd(mp_int *mp, mp_size p)
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
+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);
+ 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 */
+ if (bshift) {
+ mask = (mp_digit)~0 << (MP_DIGIT_BIT - bshift);
+ mask &= MP_DIGIT(mp, MP_USED(mp) - 1);
+ } else {
+ mask = 0;
+ }
- if (MP_OKAY != (res = s_mp_pad(mp, MP_USED(mp) + dshift + (mask != 0) )))
- return res;
+ 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 (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;
+ 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);
+ 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;
+ 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)
+void
+s_mp_rshd(mp_int *mp, mp_size p)
{
- mp_size ix;
- mp_digit *src, *dst;
+ 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;
+ }
- if(p == 0)
- 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++;
- /* 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
+ MP_USED(mp) -= p;
+ /* Fill the top digits with zeroes */
+ while (p-- > 0)
+ *dst++ = 0;
} /* end s_mp_rshd() */
@@ -3031,9 +3002,10 @@ void s_mp_rshd(mp_int *mp, mp_size p)
/* {{{ 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)
+void
+s_mp_div_2(mp_int *mp)
{
- s_mp_div_2d(mp, 1);
+ s_mp_div_2d(mp, 1);
} /* end s_mp_div_2() */
@@ -3041,34 +3013,35 @@ void s_mp_div_2(mp_int *mp)
/* {{{ s_mp_mul_2(mp) */
-mp_err s_mp_mul_2(mp_int *mp)
+mp_err
+s_mp_mul_2(mp_int *mp)
{
- mp_digit *pd;
- unsigned int ix, used;
- mp_digit kin = 0;
+ mp_digit *pd;
+ unsigned 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;
+ /* 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));
}
- DIGIT(mp, ix) = kin;
- USED(mp) += 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;
+ }
- return MP_OKAY;
+ DIGIT(mp, ix) = kin;
+ USED(mp) += 1;
+ }
+
+ return MP_OKAY;
} /* end s_mp_mul_2() */
@@ -3081,24 +3054,25 @@ mp_err s_mp_mul_2(mp_int *mp)
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)
+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;
+ mp_size ndig = (d / DIGIT_BIT), nbit = (d % DIGIT_BIT);
+ mp_size ix;
+ mp_digit dmask;
- if(ndig >= USED(mp))
- return;
+ 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 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;
+ /* 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);
+ s_mp_clamp(mp);
} /* end s_mp_mod_2d() */
@@ -3111,23 +3085,24 @@ void s_mp_mod_2d(mp_int *mp, mp_digit d)
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)
+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);
+ 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() */
@@ -3141,34 +3116,35 @@ void s_mp_div_2d(mp_int *mp, mp_digit 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
+ 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_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;
+ 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;
+ return res;
} /* end s_mp_norm() */
@@ -3181,55 +3157,55 @@ CLEANUP:
/* {{{ 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 */
+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);
+ mp_word w, k = 0;
+ mp_size ix = 1;
- while(ix < USED(mp) && k) {
- w = (mp_word)DIGIT(mp, ix) + k;
- DIGIT(mp, ix) = ACCUM(w);
+ w = (mp_word)DIGIT(mp, 0) + d;
+ DIGIT(mp, 0) = ACCUM(w);
k = CARRYOUT(w);
- ++ix;
- }
- if(k != 0) {
- mp_err res;
+ while (ix < USED(mp) && k) {
+ w = (mp_word)DIGIT(mp, ix) + k;
+ DIGIT(mp, ix) = ACCUM(w);
+ k = CARRYOUT(w);
+ ++ix;
+ }
- if((res = s_mp_pad(mp, USED(mp) + 1)) != MP_OKAY)
- return res;
+ if (k != 0) {
+ mp_err res;
- DIGIT(mp, ix) = (mp_digit)k;
- }
+ if ((res = s_mp_pad(mp, USED(mp) + 1)) != MP_OKAY)
+ return res;
- return MP_OKAY;
+ 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_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 = 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;
- }
+ *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;
+ return res;
#endif
} /* end s_mp_add_d() */
@@ -3238,48 +3214,48 @@ CLEANUP:
/* {{{ 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 */
+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);
+ mp_word w, b = 0;
+ mp_size ix = 1;
- /* Propagate borrows leftward */
- while(b && ix < USED(mp)) {
- w = (RADIX + (mp_word)DIGIT(mp, ix)) - b;
+ /* Compute initial subtraction */
+ w = (RADIX + (mp_word)DIGIT(mp, 0)) - d;
b = CARRYOUT(w) ? 0 : 1;
- DIGIT(mp, ix) = ACCUM(w);
- ++ix;
- }
+ 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);
+ /* 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;
+ /* 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_digit *pmp = MP_DIGITS(mp);
+ mp_digit mp_i, diff, borrow;
+ mp_size used = MP_USED(mp);
+
mp_i = *pmp;
- *pmp++ = diff = mp_i - borrow;
+ *pmp++ = diff = mp_i - d;
borrow = (diff > mp_i);
- }
- s_mp_clamp(mp);
- return (borrow && !used) ? MP_RANGE : MP_OKAY;
+ 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() */
@@ -3288,32 +3264,33 @@ mp_err s_mp_sub_d(mp_int *mp, mp_digit d) /* unsigned digit subtract */
/* {{{ 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
+s_mp_mul_d(mp_int *a, mp_digit d)
{
- mp_err res;
- mp_size used;
- int pow;
+ 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);
- }
+ 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) );
+ 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_mpv_mul_d(MP_DIGITS(a), used, d, MP_DIGITS(a));
- s_mp_clamp(a);
+ s_mp_clamp(a);
CLEANUP:
- return res;
-
+ return res;
+
} /* end s_mp_mul_d() */
/* }}} */
@@ -3327,114 +3304,115 @@ CLEANUP:
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)
+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;
+ mp_word w = 0, q;
#else
- mp_digit w, q;
+ mp_digit w = 0, 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;
- }
+ 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)) );
+ 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;
+ 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;
}
-
- s_mp_lshd(&quot, 1);
- DIGIT(&quot, 0) = (mp_digit)q;
- }
#else
- {
- mp_digit p;
+ {
+ mp_digit p;
#if !defined(MP_ASSEMBLY_DIV_2DX1D)
- mp_digit norm;
+ mp_digit norm;
#endif
- MP_CHECKOK( mp_init_copy(&rem, mp) );
+ 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;
+ 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;
- }
+ 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;
+ if (norm)
+ w >>= norm;
#endif
- }
+ }
#endif
- /* Deliver the remainder, if desired */
- if(r)
- *r = (mp_digit)w;
+ /* Deliver the remainder, if desired */
+ if (r) {
+ *r = (mp_digit)w;
+ }
- s_mp_clamp(&quot);
- mp_exch(&quot, mp);
+ s_mp_clamp(&quot);
+ mp_exch(&quot, mp);
CLEANUP:
- mp_clear(&quot);
- mp_clear(&rem);
+ mp_clear(&quot);
+ mp_clear(&rem);
- return res;
+ return res;
} /* end s_mp_div_d() */
/* }}} */
-
/* }}} */
/* {{{ Primitive full arithmetic */
@@ -3442,259 +3420,261 @@ CLEANUP:
/* {{{ s_mp_add(a, b) */
/* Compute a = |a| + |b| */
-mp_err s_mp_add(mp_int *a, const mp_int *b) /* magnitude addition */
+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;
+ mp_word w = 0;
#else
- mp_digit d, sum, carry = 0;
+ mp_digit d, sum, carry = 0;
#endif
- mp_digit *pa, *pb;
- mp_size ix;
- mp_size used;
- mp_err res;
+ 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;
+ /* 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++) {
+ /*
+ 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);
+ 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 */
+ 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 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;
- }
+ 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;
- }
+ while (carry && ix < used) {
+ sum = carry + *pa;
+ *pa++ = sum;
+ carry = !sum;
+ ++ix;
+ }
#endif
- /* If there's an overall carry out, increase precision and include
+/* 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;
+ if (w) {
+ if ((res = s_mp_pad(a, used + 1)) != MP_OKAY)
+ return res;
- DIGIT(a, ix) = (mp_digit)w;
- }
+ DIGIT(a, ix) = (mp_digit)w;
+ }
#else
- if (carry) {
- if((res = s_mp_pad(a, used + 1)) != MP_OKAY)
- return res;
+ if (carry) {
+ if ((res = s_mp_pad(a, used + 1)) != MP_OKAY)
+ return res;
- DIGIT(a, used) = carry;
- }
+ DIGIT(a, used) = carry;
+ }
#endif
- return MP_OKAY;
+ 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_err
+s_mp_add_3arg(const mp_int *a, const mp_int *b, mp_int *c)
{
- mp_digit *pa, *pb, *pc;
+ mp_digit *pa, *pb, *pc;
#if !defined(MP_NO_MP_WORD) && !defined(MP_NO_ADD_WORD)
- mp_word w = 0;
+ mp_word w = 0;
#else
- mp_digit sum, carry = 0, d;
+ 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;
+ 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;
+ }
- /*
- 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++) {
+ /* 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);
+ 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 */
+ 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...
+ /* 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) {
+ 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);
+ w = w + *pa++;
+ *pc++ = ACCUM(w);
+ w = CARRYOUT(w);
#else
- *pc++ = sum = carry + *pa++;
- carry = (sum < carry);
+ *pc++ = sum = carry + *pa++;
+ carry = (sum < carry);
#endif
- }
+ }
- /* If there's an overall carry out, increase precision and include
+/* 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;
+ if (w) {
+ if ((res = s_mp_pad(c, used + 1)) != MP_OKAY)
+ return res;
- DIGIT(c, used) = (mp_digit)w;
- ++used;
- }
+ DIGIT(c, used) = (mp_digit)w;
+ ++used;
+ }
#else
- if (carry) {
- if((res = s_mp_pad(c, used + 1)) != MP_OKAY)
- return res;
+ if (carry) {
+ if ((res = s_mp_pad(c, used + 1)) != MP_OKAY)
+ return res;
- DIGIT(c, used) = carry;
- ++used;
- }
+ DIGIT(c, used) = carry;
+ ++used;
+ }
#endif
- MP_USED(c) = used;
- return MP_OKAY;
+ 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)
+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;
+ mp_word w, k = 0;
#else
- mp_digit d, sum, carry = 0;
+ 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;
+ 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++) {
+ 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);
+ 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);
+ 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 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);
- }
+ 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);
- }
+ 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
+/* 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;
+ if (k) {
+ if ((res = s_mp_pad(a, USED(a) + 1)) != MP_OKAY)
+ return res;
- DIGIT(a, ia) = (mp_digit)k;
- }
+ DIGIT(a, ia) = (mp_digit)k;
+ }
#else
- if (carry) {
- if((res = s_mp_pad(a, lim + 1)) != MP_OKAY)
- return res;
+ if (carry) {
+ if ((res = s_mp_pad(a, lim + 1)) != MP_OKAY)
+ return res;
- DIGIT(a, lim) = carry;
- }
+ DIGIT(a, lim) = carry;
+ }
#endif
- s_mp_clamp(a);
+ s_mp_clamp(a);
- return MP_OKAY;
+ return MP_OKAY;
} /* end s_mp_add_offset() */
@@ -3703,399 +3683,419 @@ mp_err s_mp_add_offset(mp_int *a, mp_int *b, mp_size 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_err s_mp_sub(mp_int *a, const mp_int *b) /* magnitude subtract */
{
- mp_digit *pa, *pb, *limit;
+ mp_digit *pa, *pb, *limit;
#if !defined(MP_NO_MP_WORD) && !defined(MP_NO_SUB_WORD)
- mp_sword w = 0;
+ mp_sword w = 0;
#else
- mp_digit d, diff, borrow = 0;
+ 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) {
+ 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;
+ 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;
+ 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);
+ }
+ 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;
- }
+ 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);
- }
+ while (borrow && pa < limit) {
+ d = *pa;
+ *pa++ = diff = d - borrow;
+ borrow = (diff > d);
+ }
#endif
- /* Clobber any leading zeroes we created */
- s_mp_clamp(a);
+ /* 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;
+ return w ? MP_RANGE : MP_OKAY;
#else
- return borrow ? MP_RANGE : MP_OKAY;
+ 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_err
+s_mp_sub_3arg(const mp_int *a, const mp_int *b, mp_int *c)
{
- mp_digit *pa, *pb, *pc;
+ mp_digit *pa, *pb, *pc;
#if !defined(MP_NO_MP_WORD) && !defined(MP_NO_SUB_WORD)
- mp_sword w = 0;
+ mp_sword w = 0;
#else
- mp_digit d, diff, borrow = 0;
+ mp_digit d, diff, borrow = 0;
#endif
- int ix, limit;
- mp_err res;
+ int ix, limit;
+ mp_err res;
- MP_SIGN(c) = MP_SIGN(a);
+ 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;
+ /* 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) {
+ 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;
+ 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;
+ 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) {
+ }
+ 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;
+ w = w + *pa++;
+ *pc++ = ACCUM(w);
+ w >>= MP_DIGIT_BIT;
#else
- d = *pa++;
- *pc++ = diff = d - borrow;
- borrow = (diff > d);
+ d = *pa++;
+ *pc++ = diff = d - borrow;
+ borrow = (diff > d);
#endif
- }
+ }
- /* Clobber any leading zeroes we created */
- MP_USED(c) = ix;
- s_mp_clamp(c);
+ /* 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;
+ return w ? MP_RANGE : MP_OKAY;
#else
- return borrow ? MP_RANGE : MP_OKAY;
+ 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)
+mp_err
+s_mp_mul(mp_int *a, const mp_int *b)
{
- return mp_mul(a, b, a);
+ 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); }
+#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); }
+#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; \
- }
+#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)
+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;
+ 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;
+ 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)
+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;
+ 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;
+ 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)
+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);
- }
+ 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;
- }
+ 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); }
+#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); }
+#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; \
- }
+#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)
+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); \
+ 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);
- }
+ 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;
- }
+ 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)
+#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
+** 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_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;
@@ -4109,8 +4109,8 @@ mp_err s_mpv_div_2dx1d(mp_digit Nhi, mp_digit Nlo, mp_digit divisor,
if (r1 < m) {
q1--, r1 += divisor;
if (r1 >= divisor && r1 < m) {
- q1--, r1 += divisor;
- }
+ q1--, r1 += divisor;
+ }
}
r1 -= m;
r0 = r1 % d1;
@@ -4120,13 +4120,13 @@ mp_err s_mpv_div_2dx1d(mp_digit Nhi, mp_digit Nlo, mp_digit divisor,
if (r0 < m) {
q0--, r0 += divisor;
if (r0 >= divisor && r0 < m) {
- q0--, r0 += divisor;
- }
+ q0--, r0 += divisor;
+ }
}
if (qp)
- *qp = (q1 << MP_HALF_DIGIT_BIT) | q0;
+ *qp = (q1 << MP_HALF_DIGIT_BIT) | q0;
if (rp)
- *rp = r0 - m;
+ *rp = r0 - m;
return MP_OKAY;
}
#endif
@@ -4134,19 +4134,20 @@ mp_err s_mpv_div_2dx1d(mp_digit Nhi, mp_digit Nlo, mp_digit divisor,
#if MP_SQUARE
/* {{{ s_mp_sqr(a) */
-mp_err s_mp_sqr(mp_int *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)
+ 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;
- res = mp_sqr(a, &tmp);
- if (res == MP_OKAY) {
- s_mp_exch(&tmp, a);
- }
- mp_clear(&tmp);
- return res;
}
/* }}} */
@@ -4160,170 +4161,170 @@ mp_err s_mp_sqr(mp_int *a)
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_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;
+ mp_int part, t;
#if !defined(MP_NO_MP_WORD) && !defined(MP_NO_DIV_WORD)
- mp_word q_msd;
+ mp_word q_msd;
#else
- mp_digit q_msd;
+ 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_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;
- MP_SIGN(&part) = ZPOS;
+ MP_SIGN(rem) = ZPOS;
+ MP_SIGN(div) = ZPOS;
+ MP_SIGN(&part) = ZPOS;
- /* A working temporary for division */
- MP_CHECKOK( mp_init_size(&t, MP_ALLOC(rem)));
+ /* 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) );
+ /* Normalize to optimize guessing */
+ MP_CHECKOK(s_mp_norm(rem, div, &d));
- /* Perform the division itself...woo! */
- MP_USED(quot) = MP_ALLOC(quot);
+ /* 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;
- int partExtended = 0; /* set to true if we need to extend part */
+ /* 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;
+ int partExtended = 0; /* set to true if we need to extend part */
- 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);
+ 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);
- /* We have now truncated the part of the remainder to the same length as
+ /* We have now truncated the part of the remainder to the same length as
* the divisor. If part is smaller than div, extend part by one digit. */
- if (s_mp_cmp(&part, div) < 0) {
- -- unusedRem;
+ if (s_mp_cmp(&part, div) < 0) {
+ --unusedRem;
#if MP_ARGCHK == 2
- assert(unusedRem >= 0);
+ assert(unusedRem >= 0);
#endif
- -- MP_DIGITS(&part);
- ++ MP_USED(&part);
- ++ MP_ALLOC(&part);
- partExtended = 1;
- }
-
- /* 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 (!partExtended) {
- /* In this case, q_msd /= div_msd is always 1. First, since div_msd is
+ --MP_DIGITS(&part);
+ ++MP_USED(&part);
+ ++MP_ALLOC(&part);
+ partExtended = 1;
+ }
+
+ /* 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 (!partExtended) {
+ /* In this case, q_msd /= div_msd is always 1. First, since div_msd is
* normalized to have the high bit set, 2*div_msd > MP_DIGIT_MAX. Since
* we didn't extend part, q_msd >= div_msd. Therefore we know that
* div_msd <= q_msd <= MP_DIGIT_MAX < 2*div_msd. Dividing by div_msd we
* get 1 <= q_msd/div_msd < 2. So q_msd /= div_msd must be 1. */
- q_msd = 1;
- } else {
+ q_msd = 1;
+ } else {
#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;
+ 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
- if (q_msd == div_msd) {
- q_msd = MP_DIGIT_MAX;
- } else {
- mp_digit r;
- MP_CHECKOK( s_mpv_div_2dx1d(q_msd, MP_DIGIT(&part, MP_USED(&part) - 2),
- div_msd, &q_msd, &r) );
- }
+ if (q_msd == div_msd) {
+ q_msd = MP_DIGIT_MAX;
+ } 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
- }
+ }
#if MP_ARGCHK == 2
- assert(q_msd > 0); /* This case should never occur any more. */
+ assert(q_msd > 0); /* This case should never occur any more. */
#endif
- if (q_msd <= 0)
- break;
+ 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) );
+ /* 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);
-
- /*
+ for (i = 4; s_mp_cmp(&t, &part) > 0 && i > 0; --i) {
+ --q_msd;
+ MP_CHECKOK(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;
- }
+ MP_DIGIT(quot, unusedRem) = (mp_digit)q_msd;
+ }
- /* Denormalize remainder */
- if (d) {
- s_mp_div_2d(rem, d);
- }
+ /* Denormalize remainder */
+ if (d) {
+ s_mp_div_2d(rem, d);
+ }
- s_mp_clamp(quot);
+ s_mp_clamp(quot);
CLEANUP:
- mp_clear(&t);
+ mp_clear(&t);
- return res;
+ return res;
} /* end s_mp_div() */
-
/* }}} */
/* {{{ s_mp_2expt(a, k) */
-mp_err s_mp_2expt(mp_int *a, mp_digit k)
+mp_err
+s_mp_2expt(mp_int *a, mp_digit k)
{
- mp_err res;
- mp_size dig, bit;
+ mp_err res;
+ mp_size dig, bit;
- dig = k / DIGIT_BIT;
- bit = k % DIGIT_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);
+ mp_zero(a);
+ if ((res = s_mp_pad(a, dig + 1)) != MP_OKAY)
+ return res;
- return MP_OKAY;
+ DIGIT(a, dig) |= ((mp_digit)1 << bit);
+
+ return MP_OKAY;
} /* end s_mp_2expt() */
@@ -4341,51 +4342,52 @@ mp_err s_mp_2expt(mp_int *a, mp_digit k)
This algorithm was derived from the _Handbook of Applied
Cryptography_ by Menezes, Oorschot and VanStone, Ch. 14,
- pp. 603-604.
+ pp. 603-604.
*/
-mp_err s_mp_reduce(mp_int *x, const mp_int *m, const mp_int *mu)
+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;
- }
+ 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;
- }
+ /* 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);
+CLEANUP:
+ mp_clear(&q);
- return res;
+ return res;
} /* end s_mp_reduce() */
@@ -4398,47 +4400,50 @@ mp_err s_mp_reduce(mp_int *x, const mp_int *m, const mp_int *mu)
/* {{{ 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)
+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;
+ 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;
+ return MP_LT;
IS_GT:
- return MP_GT;
+ return MP_GT;
} /* end s_mp_cmp() */
/* }}} */
@@ -4446,17 +4451,18 @@ IS_GT:
/* {{{ 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)
+int
+s_mp_cmp_d(const mp_int *a, mp_digit d)
{
- if(USED(a) > 1)
- return MP_GT;
+ 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;
+ 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() */
@@ -4468,25 +4474,26 @@ int s_mp_cmp_d(const mp_int *a, mp_digit d)
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)
+int
+s_mp_ispow2(const mp_int *v)
{
- mp_digit d;
- int extra = 0, ix;
+ mp_digit d;
+ int extra = 0, ix;
- ix = MP_USED(v) - 1;
- d = MP_DIGIT(v, ix); /* most significant digit of v */
+ 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;
+ 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;
- }
+ while (--ix >= 0) {
+ if (DIGIT(v, ix) != 0)
+ return -1; /* not a power of two */
+ extra += MP_DIGIT_BIT;
+ }
- return extra;
+ return extra;
} /* end s_mp_ispow2() */
@@ -4494,53 +4501,54 @@ int s_mp_ispow2(const mp_int *v)
/* {{{ s_mp_ispow2d(d) */
-int s_mp_ispow2d(mp_digit 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;
+ 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;
+ 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;
+ 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;
+ return pow;
+ }
+ return -1;
} /* end s_mp_ispow2d() */
@@ -4560,32 +4568,33 @@ int s_mp_ispow2d(mp_digit d)
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
+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;
+ int val, xch;
- if(val < 0 || val >= r)
- return -1;
+ 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;
- return val;
+ if (val < 0 || val >= r)
+ return -1;
+
+ return val;
} /* end s_mp_tovalue() */
@@ -4601,20 +4610,21 @@ int s_mp_tovalue(char ch, int r)
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
+s_mp_todigit(mp_digit val, int r, int low)
{
- char ch;
+ char ch;
- if(val >= r)
- return 0;
+ if (val >= r)
+ return 0;
- ch = s_dmap_1[val];
+ ch = s_dmap_1[val];
- if(r <= 36 && low)
- ch = tolower(ch);
+ if (r <= 36 && low)
+ ch = tolower(ch);
- return ch;
+ return ch;
} /* end s_mp_todigit() */
@@ -4622,14 +4632,15 @@ char s_mp_todigit(mp_digit val, int r, int low)
/* {{{ 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)
+int
+s_mp_outlen(int bits, int r)
{
- return (int)((double)bits * LOG_V_2(r) + 1.5) + 1;
+ return (int)((double)bits * LOG_V_2(r) + 1.5) + 1;
} /* end s_mp_outlen() */
@@ -4643,40 +4654,40 @@ int s_mp_outlen(int bits, int r)
No sign bit, number is positive. Leading zeros ignored.
*/
-mp_err
+mp_err
mp_read_unsigned_octets(mp_int *mp, const unsigned char *str, mp_size len)
{
- int count;
- mp_err res;
- mp_digit d;
+ int count;
+ mp_err res;
+ mp_digit d;
- ARGCHK(mp != NULL && str != NULL && len > 0, MP_BADARG);
+ ARGCHK(mp != NULL && str != NULL && len > 0, MP_BADARG);
- mp_zero(mp);
+ mp_zero(mp);
- count = len % sizeof(mp_digit);
- if (count) {
- for (d = 0; count-- > 0; --len) {
- d = (d << 8) | *str++;
+ count = len % sizeof(mp_digit);
+ if (count) {
+ for (d = 0; count-- > 0; --len) {
+ d = (d << 8) | *str++;
+ }
+ MP_DIGIT(mp, 0) = d;
}
- 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;
+ /* 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;
}
- MP_DIGIT(mp, 0) = d;
- }
- return MP_OKAY;
+ return MP_OKAY;
} /* end mp_read_unsigned_octets() */
/* }}} */
@@ -4684,146 +4695,145 @@ mp_read_unsigned_octets(mp_int *mp, const unsigned char *str, mp_size len)
unsigned int
mp_unsigned_octet_size(const mp_int *mp)
{
- unsigned 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;
+ unsigned 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_err
mp_to_unsigned_octets(const mp_int *mp, unsigned char *str, mp_size maxlen)
{
- int ix, pos = 0;
- unsigned int bytes;
-
- ARGCHK(mp != NULL && str != NULL && !SIGN(mp), MP_BADARG);
-
- bytes = mp_unsigned_octet_size(mp);
- ARGCHK(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;
+ int ix, pos = 0;
+ unsigned int bytes;
+
+ ARGCHK(mp != NULL && str != NULL && !SIGN(mp), MP_BADARG);
+
+ bytes = mp_unsigned_octet_size(mp);
+ ARGCHK(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_err
mp_to_signed_octets(const mp_int *mp, unsigned char *str, mp_size maxlen)
{
- int ix, pos = 0;
- unsigned int bytes;
-
- ARGCHK(mp != NULL && str != NULL && !SIGN(mp), MP_BADARG);
-
- bytes = mp_unsigned_octet_size(mp);
- ARGCHK(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;
+ int ix, pos = 0;
+ unsigned int bytes;
+
+ ARGCHK(mp != NULL && str != NULL && !SIGN(mp), MP_BADARG);
+
+ bytes = mp_unsigned_octet_size(mp);
+ ARGCHK(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_err
mp_to_fixlen_octets(const mp_int *mp, unsigned char *str, mp_size length)
{
- int ix, pos = 0;
- unsigned int bytes;
-
- ARGCHK(mp != NULL && str != NULL && !SIGN(mp), MP_BADARG);
-
- bytes = mp_unsigned_octet_size(mp);
- ARGCHK(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;
+ int ix, pos = 0;
+ unsigned int bytes;
+
+ ARGCHK(mp != NULL && str != NULL && !SIGN(mp), MP_BADARG);
+
+ bytes = mp_unsigned_octet_size(mp);
+ ARGCHK(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/nss/lib/freebl/mpi/mpi.h b/nss/lib/freebl/mpi/mpi.h
index b1b45d2..64ffe75 100644
--- a/nss/lib/freebl/mpi/mpi.h
+++ b/nss/lib/freebl/mpi/mpi.h
@@ -12,6 +12,9 @@
#include "mpi-config.h"
+#include "seccomon.h"
+SEC_BEGIN_PROTOS
+
#if MP_DEBUG
#undef MP_IOFUNC
#define MP_IOFUNC 1
@@ -30,25 +33,25 @@
#include <sys/types.h>
-#define MP_NEG 1
-#define MP_ZPOS 0
+#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
+#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;
+typedef unsigned int mp_sign;
+typedef unsigned int mp_size;
+typedef int mp_err;
#define MP_32BIT_MAX 4294967295U
-#if !defined(ULONG_MAX)
+#if !defined(ULONG_MAX)
#error "ULONG_MAX not defined"
#elif !defined(UINT_MAX)
#error "UINT_MAX not defined"
@@ -56,119 +59,118 @@ typedef int mp_err;
#error "USHRT_MAX not defined"
#endif
-#if defined(ULLONG_MAX) /* C99, Solaris */
+#if defined(ULLONG_MAX) /* C99, Solaris */
#define MP_ULONG_LONG_MAX ULLONG_MAX
/* MP_ULONG_LONG_MAX was defined to be ULLONG_MAX */
-#elif defined(ULONG_LONG_MAX) /* HPUX */
+#elif defined(ULONG_LONG_MAX) /* HPUX */
#define MP_ULONG_LONG_MAX ULONG_LONG_MAX
-#elif defined(ULONGLONG_MAX) /* IRIX, AIX */
+#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 */
+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
+#undef MP_NO_MP_WORD
#define MP_NO_MP_WORD 1
-#undef MP_USE_LONG_DIGIT
+#undef MP_USE_LONG_DIGIT
#define MP_USE_LONG_DIGIT 1
-#undef MP_USE_LONG_LONG_DIGIT
+#undef MP_USE_LONG_LONG_DIGIT
-#elif !defined(MP_USE_UINT_DIGIT) && defined(MP_ULONG_LONG_MAX)
+#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_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
+#undef MP_USE_LONG_LONG_DIGIT
#define MP_USE_LONG_LONG_DIGIT 1
-#undef MP_USE_LONG_DIGIT
+#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 */
+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
+#undef MP_USE_UINT_DIGIT
#define MP_USE_UINT_DIGIT 1
-#undef MP_USE_LONG_LONG_DIGIT
-#undef MP_USE_LONG_DIGIT
+#undef MP_USE_LONG_LONG_DIGIT
+#undef MP_USE_LONG_DIGIT
#endif
-#if !defined(MP_NO_MP_WORD)
-#if defined(MP_USE_UINT_DIGIT) && \
+#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
+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
+typedef long long mp_sword;
+#define MP_WORD_MAX MP_ULONG_LONG_MAX
#endif
-#else
+#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
+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_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
+#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)]
+#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
+#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_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);
+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);
+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)
+#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 */
@@ -197,7 +199,6 @@ 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
@@ -216,13 +217,12 @@ 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);
+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(const mp_int *a, const mp_int *b);
+int mp_isodd(const mp_int *a);
+int mp_iseven(const mp_int *a);
/* Number theoretic */
#if MP_NUMTH
@@ -235,26 +235,26 @@ mp_err mp_invmod_xgcd(const mp_int *a, const mp_int *m, mp_int *c);
/* Input and output */
#if MP_IOFUNC
-void mp_print(mp_int *mp, FILE *ofp);
+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);
+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_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);
+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_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)
+#define mp_tohex(M, S) mp_toradix((M), (S), 16)
/* Error strings */
-const char *mp_strerror(mp_err ec);
+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);
@@ -266,35 +266,48 @@ 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)
+ 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
+
+#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);}}
+#define ARGCHK(X, Y) \
+ { \
+ if (!(X)) { \
+ return (Y); \
+ } \
+ }
#elif MP_ARGCHK == 2
#include <assert.h>
-#define ARGCHK(X,Y) assert(X)
+#define ARGCHK(X, Y) assert(X)
#else
-#define ARGCHK(X,Y) /* */
+#define ARGCHK(X, Y) /* */
#endif
-#endif /* defined MP_API_COMPATIBLE */
+
+#ifdef CT_VERIF
+void mp_taint(mp_int *mp);
+void mp_untaint(mp_int *mp);
+#endif
+
+SEC_END_PROTOS
#endif /* end _H_MPI_ */
diff --git a/nss/lib/freebl/mpi/mpi_amd64.c b/nss/lib/freebl/mpi/mpi_amd64.c
index 9c9b1f9..9e538bb 100644
--- a/nss/lib/freebl/mpi/mpi_amd64.c
+++ b/nss/lib/freebl/mpi/mpi_amd64.c
@@ -15,18 +15,18 @@
/* 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)
+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;
+ 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;
- }
+ 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/nss/lib/freebl/mpi/mpi_arm.c b/nss/lib/freebl/mpi/mpi_arm.c
index 9199aab..b5139f2 100644
--- a/nss/lib/freebl/mpi/mpi_arm.c
+++ b/nss/lib/freebl/mpi/mpi_arm.c
@@ -14,158 +14,162 @@
#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)
+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"
+ __asm__ __volatile__(
+ "mov r5, #0\n"
#ifdef __thumb2__
- "cbz %1, 2f\n"
+ "cbz %1, 2f\n"
#else
- "cmp %1, r5\n" /* r5 is 0 now */
- "beq 2f\n"
+ "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");
+ "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)
+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"
+ __asm__ __volatile__(
+ "mov r5, #0\n"
#ifdef __thumb2__
- "cbz %1, 2f\n"
+ "cbz %1, 2f\n"
#else
- "cmp %1, r5\n" /* r5 is 0 now */
- "beq 2f\n"
+ "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");
+ "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)
+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;
+ if (!a_len)
+ return;
- __asm__ __volatile__(
- "mov r5, #0\n"
+ __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"
+ "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"
+ "subs %1, #1\n"
+ "bne 1b\n"
#ifdef __thumb2__
- "cbz r4, 3f\n"
+ "cbz r4, 3f\n"
#else
- "cmp r4, #0\n"
- "beq 3f\n"
+ "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");
+ "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)
+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"
+ 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"
+ "cbz r3, 3f\n"
#else
- "cmp r3, #0\n"
- "beq 3f\n"
+ "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");
+ "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/nss/lib/freebl/mpi/mpi_hp.c b/nss/lib/freebl/mpi/mpi_hp.c
index e86d3d6..0cea768 100644
--- a/nss/lib/freebl/mpi/mpi_hp.c
+++ b/nss/lib/freebl/mpi/mpi_hp.c
@@ -11,72 +11,71 @@
/* #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 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. */
+ 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. */
+ int length, /* doublewords in input vector. */
+ const mp_digit *root, /* The vector to square. */
+ mp_digit *result); /* Where to accumulate the result. */
-void
+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)
+#define MULTACC512_LEN (512 / MP_DIGIT_BIT)
+#define HP_MPY_ADD_FN (a_len == MULTACC512_LEN ? multacc512 : maxpy_little)
/* c = a * b */
-void
+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;
+ 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;
+ 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);
+ memset(px, 0, xSize);
+ free(px);
}
}
/* c += a * b, where a is a_len words long. */
-void
+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. */
+ 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)
+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/nss/lib/freebl/mpi/mpi_sparc.c b/nss/lib/freebl/mpi/mpi_sparc.c
index 628843e..1e88357 100644
--- a/nss/lib/freebl/mpi/mpi_sparc.c
+++ b/nss/lib/freebl/mpi/mpi_sparc.c
@@ -18,207 +18,209 @@
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);
+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); }
+#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
+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;
+ 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;
+ 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
+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;
+ 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;
+ 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
+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);
- }
+ 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;
- }
+ 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
+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;
+ 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);
+ v8_mpv_mul_d(a, a_len, b, c);
}
}
/* c += a * b, where a is a_len words long. */
-void
+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;
+ 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);
+ v8_mpv_mul_d_add(a, a_len, b, c);
}
}
/* c += a * b, where a is y words long. */
-void
+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);
- }
+ 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);
+ v8_mpv_mul_d_add_prop(a, a_len, b, c);
}
}
diff --git a/nss/lib/freebl/mpi/mpi_x86_asm.c b/nss/lib/freebl/mpi/mpi_x86_asm.c
index e25166e..4faeef3 100644
--- a/nss/lib/freebl/mpi/mpi_x86_asm.c
+++ b/nss/lib/freebl/mpi/mpi_x86_asm.c
@@ -1,6 +1,6 @@
/*
* 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/. */
@@ -11,33 +11,32 @@ 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
+ * 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
+ * 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)
+__declspec(naked) void s_mpv_mul_d(const mp_digit *a, mp_size a_len, mp_digit b, mp_digit *c)
{
- __asm {
+ __asm {
mov eax, is_sse
cmp eax, 0
je s_mpv_mul_d_x86
@@ -53,95 +52,94 @@ s_mpv_mul_d_x86:
push edi
push esi
push ebx
- mov ebx,0 ; carry = 0
- mov ecx,[ebp+12] ; ecx = a_len
+ 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
+ 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
+ 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
+ add eax,ebx ; add carry (ebx) to edx:eax
adc edx,0
- mov ebx,edx ; high half of product becomes next carry
+ 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
+ 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
+ mov [edi],ebx ; *c = carry
pop ebx
pop esi
pop edi
- leave
- ret
+ 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
+ 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
+ je L_6 ; jmp if a_len == 0
+ mov esi, [ebp+8] ; esi = a
cld
L_5:
- movd mm0, [esi] ; mm0 = *a++
+ 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
+ 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
+ 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
+ movd [edi], mm2 ; *c = carry
emms
pop esi
pop edi
- leave
- ret
+ 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
+ * 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
+ * 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)
+__declspec(naked) void s_mpv_mul_d_add(const mp_digit *a, mp_size a_len, mp_digit b, mp_digit *c)
{
- __asm {
+ __asm {
mov eax, is_sse
cmp eax, 0
je s_mpv_mul_d_add_x86
@@ -157,100 +155,99 @@ s_mpv_mul_d_add_x86:
push edi
push esi
push ebx
- mov ebx,0 ; carry = 0
- mov ecx,[ebp+12] ; ecx = a_len
+ 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
+ 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
+ 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
+ add eax,ebx ; add carry (ebx) to edx:eax
adc edx,0
- mov ebx,[edi] ; add in current word from *c
- add eax,ebx
+ 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
+ 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
+ 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
+ mov [edi],ebx ; *c = carry
pop ebx
pop esi
pop edi
- leave
- ret
+ 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
+ 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
+ je L_16 ; jmp if a_len == 0
+ mov esi, [ebp+8] ; esi = a
cld
L_15:
- movd mm0, [esi] ; mm0 = *a++
+ movd mm0, [esi] ; mm0 = *a++
add esi, 4
- pmuludq mm0, mm1 ; mm0 = b * *a++
- paddq mm2, mm0 ; add the carry
+ 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
+ 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
+ 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
+ movd [edi], mm2 ; *c = carry
emms
pop esi
pop edi
- leave
- ret
+ 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
+ * 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
+ * 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)
+__declspec(naked) void s_mpv_mul_d_add_prop(const mp_digit *a, mp_size a_len, mp_digit b, mp_digit *c)
{
- __asm {
+ __asm {
mov eax, is_sse
cmp eax, 0
je s_mpv_mul_d_add_prop_x86
@@ -266,46 +263,46 @@ s_mpv_mul_d_add_prop_x86:
push edi
push esi
push ebx
- mov ebx,0 ; carry = 0
- mov ecx,[ebp+12] ; ecx = a_len
+ 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
+ je L_21 ; jmp if a_len == 0
cld
- mov esi,[ebp+8] ; esi = a
+ 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
+ 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
+ add eax,ebx ; add carry (ebx) to edx:eax
adc edx,0
- mov ebx,[edi] ; add in current word from *c
- add eax,ebx
+ 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
+ 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
+ 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?
+ cmp ebx,0 ; is carry zero?
jz L_23
- mov eax,[edi] ; add in current word from *c
+ mov eax,[edi] ; add in current word from *c
add eax,ebx
- stosd ; [es:edi] = ax; edi += 4;
+ stosd ; [es:edi] = ax; edi += 4;
jnc L_23
L_22:
- mov eax,[edi] ; add in current word from *c
+ mov eax,[edi] ; add in current word from *c
adc eax,0
- stosd ; [es:edi] = ax; edi += 4;
+ stosd ; [es:edi] = ax; edi += 4;
jc L_22
L_23:
pop ebx
pop esi
pop edi
- leave
- ret
+ leave
+ ret
nop
s_mpv_mul_d_add_prop_sse2:
push ebp
@@ -313,74 +310,73 @@ s_mpv_mul_d_add_prop_sse2:
push edi
push esi
push ebx
- psubq mm2, mm2 ; carry = 0
- mov ecx, [ebp+12] ; ecx = a_len
- movd mm1, [ebp+16] ; mm1 = b
+ 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
+ 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
+ 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
+ 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
+ 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?
+ 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;
+ 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
+ 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:
+ * 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
+ * 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)
+__declspec(naked) void s_mpv_sqr_add_prop(const mp_digit *a, mp_size a_len, mp_digit *sqrs)
{
- __asm {
+ __asm {
mov eax, is_sse
cmp eax, 0
je s_mpv_sqr_add_prop_x86
@@ -396,48 +392,48 @@ s_mpv_sqr_add_prop_x86:
push edi
push esi
push ebx
- mov ebx,0 ; carry = 0
- mov ecx,[ebp+12] ; a_len
- mov edi,[ebp+16] ; edi = ps
+ 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
+ je L_31 ; jump if a_len == 0
cld
- mov esi,[ebp+8] ; esi = pa
+ mov esi,[ebp+8] ; esi = pa
L_30:
- lodsd ; eax = [ds:si]; si += 4;
+ lodsd ; eax = [ds:si]; si += 4;
mul eax
- add eax,ebx ; add "carry"
+ add eax,ebx ; add "carry"
adc edx,0
mov ebx,[edi]
- add eax,ebx ; add low word from result
+ 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
+ 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
+ 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?
+ cmp ebx,0 ; is carry zero?
jz L_34
- mov eax,[edi] ; add in current word from *c
+ mov eax,[edi] ; add in current word from *c
add eax,ebx
- stosd ; [es:edi] = ax; edi += 4;
+ stosd ; [es:edi] = ax; edi += 4;
jnc L_34
L_32:
- mov eax,[edi] ; add in current word from *c
+ mov eax,[edi] ; add in current word from *c
adc eax,0
- stosd ; [es:edi] = ax; edi += 4;
+ stosd ; [es:edi] = ax; edi += 4;
jc L_32
L_34:
pop ebx
pop esi
pop edi
- leave
- ret
+ leave
+ ret
nop
s_mpv_sqr_add_prop_sse2:
push ebp
@@ -445,79 +441,79 @@ s_mpv_sqr_add_prop_sse2:
push edi
push esi
push ebx
- psubq mm2, mm2 ; carry = 0
- mov ecx, [ebp+12] ; ecx = a_len
+ 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
+ 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 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.
+ 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
+ dec ecx ; --a_len
+ jnz L_35 ; jmp if a_len != 0
L_36:
movd ebx, mm2
- cmp ebx, 0 ; is carry zero?
+ 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;
+ 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
+ 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
+ * 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
- */
+ * 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)
+ s_mpv_div_2dx1d(mp_digit Nhi, mp_digit Nlo, mp_digit divisor,
+ mp_digit *qp, mp_digit *rp)
{
- __asm {
+ __asm {
push ebx
mov edx,[esp+8]
mov eax,[esp+12]
@@ -527,9 +523,9 @@ s_mpv_div_2dx1d(mp_digit Nhi, mp_digit Nlo, mp_digit divisor,
mov [ebx],eax
mov ebx,[esp+24]
mov [ebx],edx
- xor eax,eax ; return zero
+ xor eax,eax ; return zero
pop ebx
- ret
+ ret
nop
- }
+ }
}
diff --git a/nss/lib/freebl/mpi/mplogic.c b/nss/lib/freebl/mpi/mplogic.c
index df0aad0..89fd03a 100644
--- a/nss/lib/freebl/mpi/mplogic.c
+++ b/nss/lib/freebl/mpi/mplogic.c
@@ -13,22 +13,22 @@
/* {{{ 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
+ 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
};
/* }}} */
@@ -43,23 +43,24 @@ static unsigned char bitc[] = {
/* {{{ mpl_not(a, b) */
-mp_err mpl_not(mp_int *a, mp_int *b)
+mp_err
+mpl_not(mp_int *a, mp_int *b)
{
- mp_err res;
- unsigned int ix;
+ mp_err res;
+ unsigned int ix;
- ARGCHK(a != NULL && b != NULL, MP_BADARG);
+ ARGCHK(a != NULL && b != NULL, MP_BADARG);
- if((res = mp_copy(a, b)) != MP_OKAY)
- return res;
+ 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);
+ /* 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);
+ s_mp_clamp(b);
- return MP_OKAY;
+ return MP_OKAY;
} /* end mpl_not() */
@@ -67,31 +68,32 @@ mp_err mpl_not(mp_int *a, mp_int *b)
/* {{{ mpl_and(a, b, c) */
-mp_err mpl_and(mp_int *a, mp_int *b, mp_int *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;
- }
+ 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;
+ if ((res = mp_copy(which, c)) != MP_OKAY)
+ return res;
- for(ix = 0; ix < USED(which); ix++)
- DIGIT(c, ix) &= DIGIT(other, ix);
+ for (ix = 0; ix < USED(which); ix++)
+ DIGIT(c, ix) &= DIGIT(other, ix);
- s_mp_clamp(c);
+ s_mp_clamp(c);
- return MP_OKAY;
+ return MP_OKAY;
} /* end mpl_and() */
@@ -99,29 +101,30 @@ mp_err mpl_and(mp_int *a, mp_int *b, mp_int *c)
/* {{{ mpl_or(a, b, c) */
-mp_err mpl_or(mp_int *a, mp_int *b, mp_int *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;
- }
+ 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;
+ if ((res = mp_copy(which, c)) != MP_OKAY)
+ return res;
- for(ix = 0; ix < USED(which); ix++)
- DIGIT(c, ix) |= DIGIT(other, ix);
+ for (ix = 0; ix < USED(which); ix++)
+ DIGIT(c, ix) |= DIGIT(other, ix);
- return MP_OKAY;
+ return MP_OKAY;
} /* end mpl_or() */
@@ -129,31 +132,32 @@ mp_err mpl_or(mp_int *a, mp_int *b, mp_int *c)
/* {{{ mpl_xor(a, b, c) */
-mp_err mpl_xor(mp_int *a, mp_int *b, mp_int *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;
- }
+ 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;
+ if ((res = mp_copy(which, c)) != MP_OKAY)
+ return res;
- for(ix = 0; ix < USED(which); ix++)
- DIGIT(c, ix) ^= DIGIT(other, ix);
+ for (ix = 0; ix < USED(which); ix++)
+ DIGIT(c, ix) ^= DIGIT(other, ix);
- s_mp_clamp(c);
+ s_mp_clamp(c);
- return MP_OKAY;
+ return MP_OKAY;
} /* end mpl_xor() */
@@ -167,18 +171,19 @@ mp_err mpl_xor(mp_int *a, mp_int *b, mp_int *c)
/* {{{ mpl_rsh(a, b, d) */
-mp_err mpl_rsh(const mp_int *a, mp_int *b, mp_digit d)
+mp_err
+mpl_rsh(const mp_int *a, mp_int *b, mp_digit d)
{
- mp_err res;
+ mp_err res;
- ARGCHK(a != NULL && b != NULL, MP_BADARG);
+ ARGCHK(a != NULL && b != NULL, MP_BADARG);
- if((res = mp_copy(a, b)) != MP_OKAY)
- return res;
+ if ((res = mp_copy(a, b)) != MP_OKAY)
+ return res;
- s_mp_div_2d(b, d);
+ s_mp_div_2d(b, d);
- return MP_OKAY;
+ return MP_OKAY;
} /* end mpl_rsh() */
@@ -186,16 +191,17 @@ mp_err mpl_rsh(const mp_int *a, mp_int *b, mp_digit d)
/* {{{ mpl_lsh(a, b, d) */
-mp_err mpl_lsh(const mp_int *a, mp_int *b, mp_digit d)
+mp_err
+mpl_lsh(const mp_int *a, mp_int *b, mp_digit d)
{
- mp_err res;
+ mp_err res;
- ARGCHK(a != NULL && b != NULL, MP_BADARG);
+ ARGCHK(a != NULL && b != NULL, MP_BADARG);
- if((res = mp_copy(a, b)) != MP_OKAY)
- return res;
+ if ((res = mp_copy(a, b)) != MP_OKAY)
+ return res;
- return s_mp_mul_2d(b, d);
+ return s_mp_mul_2d(b, d);
} /* end mpl_lsh() */
@@ -215,29 +221,30 @@ mp_err mpl_lsh(const mp_int *a, mp_int *b, mp_digit d)
/* {{{ mpl_num_set(a, num) */
-mp_err mpl_num_set(mp_int *a, int *num)
+mp_err
+mpl_num_set(mp_int *a, int *num)
{
- unsigned int ix;
- int db, nset = 0;
- mp_digit cur;
- unsigned char reg;
+ unsigned int ix;
+ int db, nset = 0;
+ mp_digit cur;
+ unsigned char reg;
+
+ ARGCHK(a != NULL, MP_BADARG);
- ARGCHK(a != NULL, MP_BADARG);
+ for (ix = 0; ix < USED(a); ix++) {
+ cur = DIGIT(a, ix);
- 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));
+ for (db = 0; db < sizeof(mp_digit); db++) {
+ reg = (unsigned char)(cur >> (CHAR_BIT * db));
- nset += bitc[reg];
+ nset += bitc[reg];
+ }
}
- }
- if(num)
- *num = nset;
+ if (num)
+ *num = nset;
- return MP_OKAY;
+ return MP_OKAY;
} /* end mpl_num_set() */
@@ -245,30 +252,30 @@ mp_err mpl_num_set(mp_int *a, int *num)
/* {{{ mpl_num_clear(a, num) */
-mp_err mpl_num_clear(mp_int *a, int *num)
+mp_err
+mpl_num_clear(mp_int *a, int *num)
{
- unsigned int ix;
- int db, nset = 0;
- mp_digit cur;
- unsigned char reg;
+ unsigned int ix;
+ int db, nset = 0;
+ mp_digit cur;
+ unsigned char reg;
- ARGCHK(a != NULL, MP_BADARG);
+ 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));
+ for (ix = 0; ix < USED(a); ix++) {
+ cur = DIGIT(a, ix);
- nset += bitc[UCHAR_MAX - reg];
- }
- }
+ for (db = 0; db < sizeof(mp_digit); db++) {
+ reg = (unsigned char)(cur >> (CHAR_BIT * db));
- if(num)
- *num = nset;
+ nset += bitc[UCHAR_MAX - reg];
+ }
+ }
- return MP_OKAY;
+ if (num)
+ *num = nset;
+ return MP_OKAY;
} /* end mpl_num_clear() */
@@ -285,34 +292,35 @@ mp_err mpl_num_clear(mp_int *a, int *num)
/* {{{ mpl_parity(a) */
-mp_err mpl_parity(mp_int *a)
+mp_err
+mpl_parity(mp_int *a)
{
- unsigned int ix;
- int par = 0;
- mp_digit cur;
+ unsigned int ix;
+ int par = 0;
+ mp_digit cur;
- ARGCHK(a != NULL, MP_BADARG);
+ ARGCHK(a != NULL, MP_BADARG);
- for(ix = 0; ix < USED(a); ix++) {
- int shft = (sizeof(mp_digit) * CHAR_BIT) / 2;
+ for (ix = 0; ix < USED(a); ix++) {
+ int shft = (sizeof(mp_digit) * CHAR_BIT) / 2;
- cur = DIGIT(a, ix);
+ cur = DIGIT(a, ix);
- /* Compute parity for current digit */
- while(shft != 0) {
- cur ^= (cur >> shft);
- shft >>= 1;
- }
- cur &= 1;
+ /* Compute parity for current digit */
+ while (shft != 0) {
+ cur ^= (cur >> shft);
+ shft >>= 1;
+ }
+ cur &= 1;
- /* XOR with running parity so far */
- par ^= cur;
- }
+ /* XOR with running parity so far */
+ par ^= cur;
+ }
- if(par)
- return MP_ODD;
- else
- return MP_EVEN;
+ if (par)
+ return MP_ODD;
+ else
+ return MP_EVEN;
} /* end mpl_parity() */
@@ -324,29 +332,30 @@ mp_err mpl_parity(mp_int *a)
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_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;
+ 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;
}
/*
@@ -354,48 +363,50 @@ mp_err mpl_set_bit(mp_int *a, mp_size bitNum, mp_size value)
returns 0 or 1 or some (negative) error code.
*/
-mp_err mpl_get_bit(const mp_int *a, mp_size bitNum)
+mp_err
+mpl_get_bit(const mp_int *a, mp_size bitNum)
{
- mp_size bit, ix;
- mp_err rv;
+ mp_size bit, ix;
+ mp_err rv;
- ARGCHK(a != NULL, MP_BADARG);
+ ARGCHK(a != NULL, MP_BADARG);
- ix = bitNum / MP_DIGIT_BIT;
- ARGCHK(ix <= MP_USED(a) - 1, MP_RANGE);
+ 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;
+ 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
+ - 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_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;
+ 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;
}
/*
@@ -403,29 +414,29 @@ mp_err mpl_get_bits(const mp_int *a, mp_size lsbNum, mp_size numBits)
returns number of significnant bits in abs(a).
returns 1 if value is zero.
*/
-mp_size mpl_significant_bits(const mp_int *a)
+mp_size
+mpl_significant_bits(const mp_int *a)
{
- mp_size 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;
+ mp_size bits = 0;
+ int ix;
+
+ ARGCHK(a != NULL, MP_BADARG);
+
+ 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;
+ bits += ix * MP_DIGIT_BIT;
+ if (!bits)
+ bits = 1;
+ return bits;
}
/*------------------------------------------------------------------------*/
diff --git a/nss/lib/freebl/mpi/mplogic.h b/nss/lib/freebl/mpi/mplogic.h
index e05374a..a4a6b77 100644
--- a/nss/lib/freebl/mpi/mplogic.h
+++ b/nss/lib/freebl/mpi/mplogic.h
@@ -21,8 +21,8 @@
/* Parity results */
-#define MP_EVEN MP_YES
-#define MP_ODD MP_NO
+#define MP_EVEN MP_YES
+#define MP_ODD MP_NO
/* Bitwise functions */
@@ -33,14 +33,14 @@ 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 */
+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 */
+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 */
diff --git a/nss/lib/freebl/mpi/mpmontg.c b/nss/lib/freebl/mpi/mpmontg.c
index 9667755..06fd41b 100644
--- a/nss/lib/freebl/mpi/mpmontg.c
+++ b/nss/lib/freebl/mpi/mpmontg.c
@@ -11,7 +11,7 @@
* published by Springer Verlag.
*/
-#define MP_USING_CACHE_SAFE_MOD_EXP 1
+#define MP_USING_CACHE_SAFE_MOD_EXP 1
#include <string.h>
#include "mpi-priv.h"
#include "mplogic.h"
@@ -20,53 +20,46 @@
#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
+#include <assert.h>
#define STATIC
-#define MAX_ODD_INTS 32 /* 2 ** (WINDOW_BITS - 1) */
+#define MAX_ODD_INTS 32 /* 2 ** (WINDOW_BITS - 1) */
-/*! computes T = REDC(T), 2^b == R
+/*! computes T = REDC(T), 2^b == R
\param T < RN
*/
-mp_err s_mp_redc(mp_int *T, mp_mont_modulus *mmm)
+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); */
- 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;
+ 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); */
+ 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;
+ }
+ res = MP_OKAY;
CLEANUP:
- return res;
+ return res;
}
#if !defined(MP_MONT_USE_MP_MUL)
@@ -76,75 +69,78 @@ CLEANUP:
\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_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);
+ 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;
}
- }
- 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;
+
+ 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;
+ return res;
}
#endif
STATIC
-mp_err s_mp_to_mont(const mp_int *x, mp_mont_modulus *mmm, mp_int *xMont)
+mp_err
+s_mp_to_mont(const mp_int *x, mp_mont_modulus *mmm, mp_int *xMont)
{
- mp_err res;
+ 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 */
+ /* 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;
+ return res;
}
#ifdef MP_USING_MONT_MULF
@@ -159,329 +155,508 @@ CLEANUP:
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)
+#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)
+#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_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();
+ 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(mResult, MP_DIGITS(&accum1), nLen); /* from, to, len */
+ 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();
+ }
+ }
- res = s_mp_redc(&accum1, mmm);
- mp_exch(&accum1, result);
+ 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;
+ 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) )
+#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) )
+#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) )
+#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
+#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_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();
+ 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;
}
- }
- res = s_mp_redc(pa1, mmm);
- mp_exch(pa1, result);
+ 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_CHECKOK(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_CHECKOK(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;
+ 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
@@ -490,33 +665,33 @@ CLEANUP:
unsigned int mp_using_cache_safe_exp = 1;
#endif
-mp_err mp_set_safe_modexp(int value)
+mp_err
+mp_set_safe_modexp(int value)
{
#ifdef MP_USING_CACHE_SAFE_MOD_EXP
- mp_using_cache_safe_exp = value;
- return MP_OKAY;
+ mp_using_cache_safe_exp = value;
+ return MP_OKAY;
#else
- if (value == 0) {
- return MP_OKAY;
- }
- return MP_BADARG;
+ 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
+ * 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,
+ * 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
@@ -526,653 +701,441 @@ mp_err mp_set_safe_modexp(int value)
* 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.
+ * This implementation treats each mp_int bignum as an array of mp_digits,
+ * It stores those bytes as a column of mp_digits in the output matrix. It
+ * doesn't care if the machine uses big-endian or little-endian byte ordering
+ * within mp_digits.
*
* "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.
+ * "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
+ * "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_err mpi_to_weave(const mp_int *bignums,
+ mp_digit *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));
+ mp_size i;
+ mp_digit *endDest = weaved + (nDigits * nBignums);
- 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;
+ for (i = 0; i < WEAVE_WORD_SIZE; i++) {
+ mp_size used = MP_USED(&bignums[i]);
+ mp_digit *pSrc = MP_DIGITS(&bignums[i]);
+ mp_digit *endSrc = pSrc + used;
+ mp_digit *pDest = weaved + i;
- ARGCHK(MP_SIGN(&bignums[i]) == MP_ZPOS, MP_BADARG);
- ARGCHK(used <= nDigits, MP_BADARG);
+ 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;
+ for (; pSrc < endSrc; pSrc++) {
+ *pDest = *pSrc;
+ pDest += nBignums;
+ }
+ while (pDest < endDest) {
+ *pDest = 0;
+ pDest += nBignums;
+ }
}
- }
- return MP_OKAY;
+ 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 PRUint32 before we write. We
- * also need to make sure the PRUint32 is arranged so that the first value of
- * the first array winds up in b[0]. This means construction of that PRUint32
- * 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
- *
+ * These functions return 0xffffffff if the output is true, and 0 otherwise.
*/
-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
+#define CONST_TIME_MSB(x) (0L - ((x) >> (8 * sizeof(x) - 1)))
+#define CONST_TIME_EQ_Z(x) CONST_TIME_MSB(~(x) & ((x)-1))
+#define CONST_TIME_EQ(a, b) CONST_TIME_EQ_Z((a) ^ (b))
- 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.
+/* Reverse the operation above for one mp_int.
+ * Reconstruct one mp_int from its column in the weaved array.
+ * Every read accesses every element of the weaved array, in order to
+ * avoid timing attacks based on patterns of memory accesses.
*/
-#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_err weave_to_mpi(mp_int *a, /* out, result */
+ const mp_digit *weaved, /* in, byte matrix */
+ mp_size index, /* which column to read */
+ mp_size nDigits, /* number of mp_digits in each bignum */
+ mp_size nBignums) /* width of the matrix */
{
- 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;
+ /* these are indices, but need to be the same size as mp_digit
+ * because of the CONST_TIME operations */
+ mp_digit i, j;
+ mp_digit d;
+ mp_digit *pDest = MP_DIGITS(a);
+
+ MP_SIGN(a) = MP_ZPOS;
+ MP_USED(a) = nDigits;
+
+ assert(weaved != NULL);
+
+ /* Fetch the proper column in constant time, indexing over the whole array */
+ for (i = 0; i < nDigits; ++i) {
+ d = 0;
+ for (j = 0; j < nBignums; ++j) {
+ d |= weaved[i * nBignums + j] & CONST_TIME_EQ(j, index);
+ }
+ pDest[i] = d;
}
- digit |= *b; b += count;
- *pb = digit;
- }
- s_mp_clamp(a);
- return MP_OKAY;
+ 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) )
+#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) )
+#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) )
+#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 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)))
+#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_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 = NULL;
- unsigned char *powers = NULL;
-
- 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;
-
- /* grab the first window value. This allows us to preload accumulator1
+ 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;
+ mp_digit *powersArray = NULL;
+ mp_digit *powers = NULL;
+
+ 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;
+
+ /* 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) );
-
- /* 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]);
- powersArray = (unsigned char *)malloc(num_powers*(nLen*sizeof(mp_digit)+1));
- if (!powersArray) {
- res = MP_MEM;
- goto CLEANUP;
- }
- /* powers[i] = base ** (i); */ \
- powers = (unsigned char *)MP_ALIGN(powersArray,num_powers); \
- 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.
- * Given the value of 4 for WEAVE_WORD_SIZE, this loop will only execute if
- * num_powers > 2, in which case powers will have been allocated.
- */
- 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;
+ 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));
+
+ /* 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]);
+ powersArray = (mp_digit *)malloc(num_powers * (nLen * sizeof(mp_digit) + 1));
+ if (!powersArray) {
+ res = MP_MEM;
+ goto CLEANUP;
+ }
+ /* powers[i] = base ** (i); */
+ powers = (mp_digit *)MP_ALIGN(powersArray, num_powers);
+ 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 {
- /* 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 (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));
+ }
}
- }
- /* if the accum1 isn't set, Then there is something wrong with our logic
- * above and is an internal programming error.
+
+ /*
+ * 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.
+ * Given the value of 4 for WEAVE_WORD_SIZE, this loop will only execute if
+ * num_powers > 2, in which case powers will have been allocated.
+ */
+ 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);
+ assert(MP_USED(&accum1) != 0);
#endif
- /* set accumulator to montgomery residue of 1 */
- pa1 = &accum1;
- pa2 = &accum2;
-
- /* tmp is not used if window_bits == 1. */
- if (window_bits != 1) {
- MP_CHECKOK( mp_init_size(&tmp, 3 * nLen + 2) );
- }
-
- 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? */
+ /* set accumulator to montgomery residue of 1 */
+ pa1 = &accum1;
+ pa2 = &accum2;
+
+ /* tmp is not used if window_bits == 1. */
+ if (window_bits != 1) {
+ MP_CHECKOK(mp_init_size(&tmp, 3 * nLen + 2));
+ }
+
+ 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);
+ 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;
+ 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)
+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;
+ 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;
+ 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);
+ /* 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;
+ 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) );
- }
+ 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) );
+ nLen = MP_USED(modulus);
+ MP_CHECKOK(mp_init_size(&montBase, 2 * nLen + 2));
- mmm.N = *modulus; /* a copy of the mp_int struct */
+ 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) );
+ /* 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) );
+ MP_CHECKOK(s_mp_to_mont(base, &mmm, &montBase));
- bits_in_exponent = mpl_significant_bits(exponent);
+ 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
+ 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;
+ 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;
+ /*
+ * 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;
- }
+ 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
+ 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
+ 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);
+ 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;
+ 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/nss/lib/freebl/mpi/mpprime.c b/nss/lib/freebl/mpi/mpprime.c
index 9b97fb2..5828719 100644
--- a/nss/lib/freebl/mpi/mpprime.c
+++ b/nss/lib/freebl/mpi/mpprime.c
@@ -18,14 +18,14 @@
#define RANDOM() rand()
-#include "primes.c" /* pull in the prime digit table */
+#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);
+mp_err s_mpp_divp(mp_int *a, const mp_digit *vec, int size, int *which);
/* {{{ mpp_divis(a, b) */
@@ -35,25 +35,26 @@ mp_err s_mpp_divp(mp_int *a, const mp_digit *vec, int size, int *which);
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
+mpp_divis(mp_int *a, mp_int *b)
{
- mp_err res;
- mp_int rem;
+ mp_err res;
+ mp_int rem;
- if((res = mp_init(&rem)) != MP_OKAY)
- return res;
+ if ((res = mp_init(&rem)) != MP_OKAY)
+ return res;
- if((res = mp_mod(a, b, &rem)) != MP_OKAY)
- goto CLEANUP;
+ if ((res = mp_mod(a, b, &rem)) != MP_OKAY)
+ goto CLEANUP;
- if(mp_cmp_z(&rem) == 0)
- res = MP_YES;
- else
- res = MP_NO;
+ if (mp_cmp_z(&rem) == 0)
+ res = MP_YES;
+ else
+ res = MP_NO;
CLEANUP:
- mp_clear(&rem);
- return res;
+ mp_clear(&rem);
+ return res;
} /* end mpp_divis() */
@@ -67,23 +68,24 @@ CLEANUP:
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
+mpp_divis_d(mp_int *a, mp_digit d)
{
- mp_err res;
- mp_digit rem;
+ mp_err res;
+ mp_digit rem;
- ARGCHK(a != NULL, MP_BADARG);
+ ARGCHK(a != NULL, MP_BADARG);
- if(d == 0)
- return MP_NO;
+ if (d == 0)
+ return MP_NO;
- if((res = mp_mod_d(a, d, &rem)) != MP_OKAY)
- return res;
+ if ((res = mp_mod_d(a, d, &rem)) != MP_OKAY)
+ return res;
- if(rem == 0)
- return MP_YES;
- else
- return MP_NO;
+ if (rem == 0)
+ return MP_YES;
+ else
+ return MP_NO;
} /* end mpp_divis_d() */
@@ -102,22 +104,23 @@ mp_err mpp_divis_d(mp_int *a, mp_digit d)
As many digits as a currently has are filled with random digits.
*/
-mp_err mpp_random(mp_int *a)
+mp_err
+mpp_random(mp_int *a)
{
- mp_digit next = 0;
- unsigned int ix, jx;
+ mp_digit next = 0;
+ unsigned int ix, jx;
- ARGCHK(a != NULL, MP_BADARG);
+ 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);
+ 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;
}
- DIGIT(a, ix) = next;
- }
- return MP_OKAY;
+ return MP_OKAY;
} /* end mpp_random() */
@@ -125,16 +128,17 @@ mp_err mpp_random(mp_int *a)
/* {{{ mpp_random_size(a, prec) */
-mp_err mpp_random_size(mp_int *a, mp_size prec)
+mp_err
+mpp_random_size(mp_int *a, mp_size prec)
{
- mp_err res;
+ mp_err res;
- ARGCHK(a != NULL && prec > 0, MP_BADARG);
-
- if((res = s_mp_pad(a, prec)) != MP_OKAY)
- return res;
+ ARGCHK(a != NULL && prec > 0, MP_BADARG);
- return mpp_random(a);
+ if ((res = s_mp_pad(a, prec)) != MP_OKAY)
+ return res;
+
+ return mpp_random(a);
} /* end mpp_random_size() */
@@ -150,11 +154,12 @@ mp_err mpp_random_size(mp_int *a, mp_size prec)
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)
+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);
+ ARGCHK(a != NULL && vec != NULL && size > 0, MP_BADARG);
+
+ return s_mpp_divp(a, vec, size, which);
} /* end mpp_divis_vector() */
@@ -169,22 +174,23 @@ mp_err mpp_divis_vector(mp_int *a, const mp_digit *vec, int size, int *which)
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)
+mp_err
+mpp_divis_primes(mp_int *a, mp_digit *np)
{
- int size, which;
- mp_err res;
+ int size, which;
+ mp_err res;
- ARGCHK(a != NULL && np != NULL, MP_BADARG);
+ ARGCHK(a != NULL && np != NULL, MP_BADARG);
- size = (int)*np;
- if(size > prime_tab_size)
- size = prime_tab_size;
+ 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];
+ res = mpp_divis_vector(a, prime_tab, size, &which);
+ if (res == MP_YES)
+ *np = prime_tab[which];
- return res;
+ return res;
} /* end mpp_divis_primes() */
@@ -199,35 +205,35 @@ mp_err mpp_divis_primes(mp_int *a, mp_digit *np)
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_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_int base, test;
+ mp_err res;
- mp_set(&base, w);
+ if ((res = mp_init(&base)) != MP_OKAY)
+ return res;
- if((res = mp_init(&test)) != MP_OKAY)
- goto TEST;
+ mp_set(&base, w);
- /* Compute test = base^a (mod a) */
- if((res = mp_exptmod(&base, a, a, &test)) != MP_OKAY)
- goto CLEANUP;
+ if ((res = mp_init(&test)) != MP_OKAY)
+ goto TEST;
-
- if(mp_cmp(&base, &test) == 0)
- res = MP_YES;
- else
- res = MP_NO;
+ /* Compute test = base^a (mod a) */
+ if ((res = mp_exptmod(&base, a, a, &test)) != MP_OKAY)
+ goto CLEANUP;
- CLEANUP:
- mp_clear(&test);
- TEST:
- mp_clear(&base);
+ if (mp_cmp(&base, &test) == 0)
+ res = MP_YES;
+ else
+ res = MP_NO;
+
+CLEANUP:
+ mp_clear(&test);
+TEST:
+ mp_clear(&base);
- return res;
+ return res;
} /* end mpp_fermat() */
@@ -235,20 +241,21 @@ mp_err mpp_fermat(mp_int *a, mp_digit w)
/*
Perform the fermat test on each of the primes in a list until
- a) one of them shows a is not prime, or
+ 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_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
+mpp_fermat_list(mp_int *a, const mp_digit *primes, mp_size nPrimes)
{
- mp_err rv = MP_YES;
+ mp_err rv = MP_YES;
- while (nPrimes-- > 0 && rv == MP_YES) {
- rv = mpp_fermat(a, *primes++);
- }
- return rv;
+ while (nPrimes-- > 0 && rv == MP_YES) {
+ rv = mpp_fermat(a, *primes++);
+ }
+ return rv;
}
/* {{{ mpp_pprime(a, nt) */
@@ -262,285 +269,292 @@ mp_err mpp_fermat_list(mp_int *a, const mp_digit *primes, mp_size nPrimes)
is returned, it is probably prime (but that is not guaranteed).
*/
-mp_err mpp_pprime(mp_int *a, int nt)
+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 */
+ 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;
}
- /* 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 */
-
+ 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 */
+ MP_CHECKOK(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;
+ 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.
+/* 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
+** 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
+** 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
+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;
+ 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;
+ }
+
+ for (i = offset; i < nSieve * 2; i += prime) {
+ if (i % 2 == 0) {
+ sieve[i / 2] = 1;
+ }
+ }
}
- }
- return MP_OKAY;
+ return MP_OKAY;
}
-#define SIEVE_SIZE 32*1024
+#define SIEVE_SIZE 32 * 1024
-mp_err mpp_make_prime(mp_int *start, mp_size nBits, mp_size strong,
- unsigned long * nTries)
+mp_err
+mpp_make_prime(mp_int *start, mp_size nBits, mp_size strong,
+ unsigned long *nTries)
{
- mp_digit np;
- mp_err res;
- unsigned 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) );
+ mp_digit np;
+ mp_err res;
+ unsigned 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 originally taken from table 4.4,
+ * HandBook of Applied Cryptography, augmented by FIPS-186
+ * requirements, Table C.2 and C.3 */
+ if (nBits >= 2000) {
+ num_tests = 3;
+ } else if (nBits >= 1536) {
+ num_tests = 4;
+ } else if (nBits >= 1024) {
+ num_tests = 5;
+ } else if (nBits >= 550) {
+ num_tests = 6;
+ } else if (nBits >= 450) {
+ num_tests = 7;
+ } else if (nBits >= 400) {
+ num_tests = 8;
+ } else if (nBits >= 350) {
+ num_tests = 9;
+ } else if (nBits >= 300) {
+ num_tests = 10;
+ } else if (nBits >= 250) {
+ num_tests = 20;
+ } else if (nBits >= 200) {
+ num_tests = 41;
+ } else if (nBits >= 100) {
+ num_tests = 38; /* funny anomaly in the FIPS tables, for aux primes, the
+ * required more iterations for larger aux primes */
+ } 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)
+ 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)
+#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);
+ 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;
+ mp_clear(&trial);
+ mp_clear(&q);
+ if (nTries)
+ *nTries += i;
+ if (sieve != NULL) {
+ memset(sieve, 0, SIEVE_SIZE);
+ free(sieve);
+ }
+ return res;
}
/*========================================================================*/
@@ -549,32 +563,33 @@ CLEANUP:
/* {{{ 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
+s_mpp_divp(mp_int *a, const mp_digit *vec, int size, int *which)
{
- mp_err res;
- mp_digit rem;
+ mp_err res;
+ mp_digit rem;
- int ix;
+ int ix;
- for(ix = 0; ix < size; ix++) {
- if((res = mp_mod_d(a, vec[ix], &rem)) != MP_OKAY)
- return res;
+ 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;
+ if (rem == 0) {
+ if (which)
+ *which = ix;
+ return MP_YES;
+ }
}
- }
- return MP_NO;
+ return MP_NO;
} /* end s_mpp_divp() */
diff --git a/nss/lib/freebl/mpi/mpprime.h b/nss/lib/freebl/mpi/mpprime.h
index 805e0db..c47c618 100644
--- a/nss/lib/freebl/mpi/mpprime.h
+++ b/nss/lib/freebl/mpi/mpprime.h
@@ -13,26 +13,26 @@
#include "mpi.h"
-extern const int prime_tab_size; /* number of primes available */
+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);
+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);
+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_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_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);
+ unsigned long *nTries);
#endif /* end _H_MP_PRIME_ */
diff --git a/nss/lib/freebl/mpi/mpv_sparc.c b/nss/lib/freebl/mpi/mpv_sparc.c
index 07319b6..423311b 100644
--- a/nss/lib/freebl/mpi/mpv_sparc.c
+++ b/nss/lib/freebl/mpi/mpv_sparc.c
@@ -6,215 +6,216 @@
/***************************************************************/
-typedef int t_s32;
-typedef unsigned int t_u32;
+typedef int t_s32;
+typedef unsigned int t_u32;
#if defined(__sparcv9)
-typedef long t_s64;
-typedef unsigned long t_u64;
+typedef long t_s64;
+typedef unsigned long t_u64;
#else
-typedef long long t_s64;
-typedef unsigned long long t_u64;
+typedef long long t_s64;
+typedef unsigned long long t_u64;
#endif
-typedef double t_d64;
+typedef double t_d64;
/***************************************************************/
typedef union {
- t_d64 d64;
- struct {
- t_s32 i0;
- t_s32 i1;
- } i32s;
+ t_d64 d64;
+ struct {
+ t_s32 i0;
+ t_s32 i1;
+ } i32s;
} d64_2_i32;
/***************************************************************/
-#define BUFF_SIZE 256
+#define BUFF_SIZE 256
-#define A_BITS 19
-#define A_MASK ((1 << A_BITS) - 1)
+#define A_BITS 19
+#define A_MASK ((1 << A_BITS) - 1)
/***************************************************************/
static t_u64 mask_cnst[] = {
- 0x8000000080000000ull
+ 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
+ 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(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 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(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 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_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 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)
+#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)
+t_u32
+mul_add(t_u32 *z, t_u32 *x, t_u32 *y, int n, t_u32 a)
{
- if (a < (1 << A_BITS)) {
+ if (a < (1 << A_BITS)) {
- if (n == 8) {
- DEF_VARS(8);
- t_s32 c = 0;
+ if (n == 8) {
+ DEF_VARS(8);
+ t_s32 c = 0;
- MUL_U32_S64_8(0);
- ADD_S64_U32_8(0);
+ MUL_U32_S64_8(0);
+ ADD_S64_U32_8(0);
- return c;
+ return c;
- } else if (n == 16) {
- DEF_VARS(16);
- t_s32 c = 0;
+ } 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);
+ MUL_U32_S64_8(0);
+ MUL_U32_S64_8(4);
+ ADD_S64_U32_8(0);
+ ADD_S64_U32_8(8);
- return c;
+ return c;
- } else {
- DEF_VARS(BUFF_SIZE);
- t_s32 i, c = 0;
+ } 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);
- }
+ 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;
+ for (i = 0; i < n; i++) {
+ ADD_S64_U32(i);
+ }
- }
- } else {
+ return c;
+ }
+ } else {
- if (n == 8) {
- DEF_VARS(2*8);
- t_d64 d0, d1, db;
- t_u32 uc = 0;
+ 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);
+ da = (t_d64)(a & A_MASK);
+ db = (t_d64)(a >> A_BITS);
- MUL_U32_S64_D_8(0);
- ADD_S64_U32_D_8(0);
+ MUL_U32_S64_D_8(0);
+ ADD_S64_U32_D_8(0);
- return uc;
+ return uc;
- } else if (n == 16) {
- DEF_VARS(2*16);
- t_d64 d0, d1, db;
- t_u32 uc = 0;
+ } 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);
+ 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);
+ 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;
+ return uc;
- } else {
- DEF_VARS(2*BUFF_SIZE);
- t_d64 d0, d1, db;
- t_u32 i, uc = 0;
+ } 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);
+ 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);
- }
+ 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);
- }
+ for (i = 0; i < n; i++) {
+ ADD_S64_U32_D(i);
+ }
- return uc;
+ return uc;
+ }
}
- }
}
/***************************************************************/
-t_u32 mul_add_inp(t_u32 *x, t_u32 *y, int n, t_u32 a)
+t_u32
+mul_add_inp(t_u32 *x, t_u32 *y, int n, t_u32 a)
{
- return mul_add(x, x, y, n, a);
+ return mul_add(x, x, y, n, a);
}
/***************************************************************/
diff --git a/nss/lib/freebl/mpi/mpvalpha.c b/nss/lib/freebl/mpi/mpvalpha.c
index 943064d..94e86ee 100644
--- a/nss/lib/freebl/mpi/mpvalpha.c
+++ b/nss/lib/freebl/mpi/mpvalpha.c
@@ -5,104 +5,104 @@
#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); \
+ }
-#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 */
+/* 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; \
-} \
+#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
@@ -110,33 +110,34 @@ FUNC_NAME(FNAME) \
#define DO_NOT_EXPAND 1
/* Need forward declaration so it can be instantiated after
- the routine that uses it; this helps locality somewhat */
+ 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)
+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;
- }
+ 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)
+ EXPAND_256(s_mpv_mul_d_MUL256)
#endif
- *c = carry;
+ *c = carry;
}
#if !defined(DO_NOT_EXPAND)
@@ -145,21 +146,22 @@ DECLARE_MUL_256(s_mpv_mul_d_MUL256)
#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; \
+#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 */
+ 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)
+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;
+ EXPAND_256(s_mpv_mul_d_add_MUL256)
+ *c = carry;
}
/* Instantiate multiply 256 routine here */
@@ -167,15 +169,15 @@ 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)
+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;
- }
+ 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/nss/lib/freebl/mpi/mulsqr.c b/nss/lib/freebl/mpi/mulsqr.c
index 702ad24..461d40a 100644
--- a/nss/lib/freebl/mpi/mulsqr.c
+++ b/nss/lib/freebl/mpi/mulsqr.c
@@ -10,74 +10,75 @@
#include <limits.h>
#include <time.h>
-#define MP_SQUARE 1 /* make sure squaring code is included */
+#define MP_SQUARE 1 /* make sure squaring code is included */
#include "mpi.h"
#include "mpprime.h"
-int main(int argc, char *argv[])
+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;
-
+ 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/nss/lib/freebl/mpi/primes.c b/nss/lib/freebl/mpi/primes.c
index 58536ad..c8bd93f 100644
--- a/nss/lib/freebl/mpi/primes.c
+++ b/nss/lib/freebl/mpi/primes.c
@@ -1,6 +1,6 @@
/*
* These tables of primes wwere generated using the 'sieve' program
- * (sieve.c) and converted to this format with 'ptab.pl'.
+ * (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
@@ -17,826 +17,825 @@
#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,
+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/nss/lib/freebl/mpi/target.mk b/nss/lib/freebl/mpi/target.mk
index dbd2fb9..dd74564 100644
--- a/nss/lib/freebl/mpi/target.mk
+++ b/nss/lib/freebl/mpi/target.mk
@@ -171,7 +171,7 @@ 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
+MPICMN += -DMP_MONT_USE_MP_MUL -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)
@@ -193,7 +193,7 @@ 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
+MP_CONFIG += -DMP_IS_LITTLE_ENDIAN
CFLAGS = -xarch=generic64 -xO4 -I. -DMP_API_COMPATIBLE -DMP_IOFUNC $(MP_CONFIG)
MPICMN += $(MP_CONFIG)
diff --git a/nss/lib/freebl/mpi/test-arrays.txt b/nss/lib/freebl/mpi/test-arrays.txt
index 76c4e3e..6c8908c 100644
--- a/nss/lib/freebl/mpi/test-arrays.txt
+++ b/nss/lib/freebl/mpi/test-arrays.txt
@@ -33,7 +33,6 @@ 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
diff --git a/nss/lib/freebl/mpi/test-info.c b/nss/lib/freebl/mpi/test-info.c
deleted file mode 100644
index bf6fecf..0000000
--- a/nss/lib/freebl/mpi/test-info.c
+++ /dev/null
@@ -1,161 +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/. */
-
-/* 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/nss/lib/freebl/mpi/tests/mptest-1.c b/nss/lib/freebl/mpi/tests/mptest-1.c
index 1c24fdf..4491346 100644
--- a/nss/lib/freebl/mpi/tests/mptest-1.c
+++ b/nss/lib/freebl/mpi/tests/mptest-1.c
@@ -20,23 +20,24 @@
#include "mpi.h"
-int main(int argc, char *argv[])
+int
+main(int argc, char *argv[])
{
- int ix;
- mp_int mp;
+ int ix;
+ mp_int mp;
#ifdef MAC_CW_SIOUX
- argc = ccommand(&argv);
+ 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_init(&mp);
- mp_clear(&mp);
- return 0;
+ 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/nss/lib/freebl/mpi/tests/mptest-2.c b/nss/lib/freebl/mpi/tests/mptest-2.c
index ea1161e..1505e6a 100644
--- a/nss/lib/freebl/mpi/tests/mptest-2.c
+++ b/nss/lib/freebl/mpi/tests/mptest-2.c
@@ -15,39 +15,48 @@
#include "mpi.h"
-int main(int argc, char *argv[])
+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;
+ 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/nss/lib/freebl/mpi/tests/mptest-3.c b/nss/lib/freebl/mpi/tests/mptest-3.c
index 4636a25..86fb246 100644
--- a/nss/lib/freebl/mpi/tests/mptest-3.c
+++ b/nss/lib/freebl/mpi/tests/mptest-3.c
@@ -17,82 +17,89 @@
#include "mpi.h"
-#define SQRT 1 /* define nonzero to get square-root test */
-#define EXPT 0 /* define nonzero to get exponentiate test */
+#define EXPT 0 /* define nonzero to get exponentiate test */
-int main(int argc, char *argv[])
+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);
+ 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);
+ 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
+ ix = rand() % 256;
+ printf("\nc = 2^%d\n", ix);
+ mp_2expt(&c, ix);
+ printf("c = ");
+ mp_print(&c, stdout);
+ fputc('\n', stdout);
- mp_clear(&d);
- mp_clear(&c);
- mp_clear(&b);
- mp_clear(&a);
+ mp_clear(&d);
+ mp_clear(&c);
+ mp_clear(&b);
+ mp_clear(&a);
- return 0;
+ return 0;
}
diff --git a/nss/lib/freebl/mpi/tests/mptest-3a.c b/nss/lib/freebl/mpi/tests/mptest-3a.c
index c496aa6..c6cea70 100644
--- a/nss/lib/freebl/mpi/tests/mptest-3a.c
+++ b/nss/lib/freebl/mpi/tests/mptest-3a.c
@@ -18,94 +18,106 @@
#include "mpi.h"
#include "mpprime.h"
-int main(int argc, char *argv[])
+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;
+ 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;
+ 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/nss/lib/freebl/mpi/tests/mptest-4.c b/nss/lib/freebl/mpi/tests/mptest-4.c
index 3001739..0f326ac 100644
--- a/nss/lib/freebl/mpi/tests/mptest-4.c
+++ b/nss/lib/freebl/mpi/tests/mptest-4.c
@@ -15,79 +15,97 @@
#include "mpi.h"
-int main(int argc, char *argv[])
+int
+main(int argc, char *argv[])
{
- int ix;
- mp_int a, b, c, m;
- mp_digit r;
+ 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;
- }
+ if (argc < 4) {
+ fprintf(stderr, "Usage: %s <a> <b> <m>\n", argv[0]);
+ return 1;
+ }
- printf("Test 4: Modular arithmetic\n\n");
+ printf("Test 4: Modular arithmetic\n\n");
- mp_init(&a);
- mp_init(&b);
- mp_init(&m);
+ 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_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_mod(&a, &m, &c);
- printf("c = "); mp_print(&c, stdout); fputc('\n', stdout);
+ mp_init(&c);
+ printf("\nc = a (mod m)\n");
- printf("\nc = b (mod m)\n");
+ mp_mod(&a, &m, &c);
+ printf("c = ");
+ mp_print(&c, stdout);
+ fputc('\n', stdout);
- mp_mod(&b, &m, &c);
- printf("c = "); mp_print(&c, stdout); fputc('\n', stdout);
+ printf("\nc = b (mod m)\n");
- printf("\nc = b (mod 1853)\n");
+ mp_mod(&b, &m, &c);
+ printf("c = ");
+ mp_print(&c, stdout);
+ fputc('\n', stdout);
- mp_mod_d(&b, 1853, &r);
- printf("c = %04X\n", r);
+ printf("\nc = b (mod 1853)\n");
- printf("\nc = (a + b) mod m\n");
+ mp_mod_d(&b, 1853, &r);
+ printf("c = %04X\n", r);
- mp_addmod(&a, &b, &m, &c);
- printf("c = "); mp_print(&c, stdout); fputc('\n', stdout);
+ printf("\nc = (a + b) mod m\n");
- printf("\nc = (a - b) mod m\n");
+ mp_addmod(&a, &b, &m, &c);
+ printf("c = ");
+ mp_print(&c, stdout);
+ fputc('\n', stdout);
- mp_submod(&a, &b, &m, &c);
- printf("c = "); mp_print(&c, stdout); fputc('\n', stdout);
+ printf("\nc = (a - b) mod m\n");
- printf("\nc = (a * b) mod m\n");
+ mp_submod(&a, &b, &m, &c);
+ printf("c = ");
+ mp_print(&c, stdout);
+ fputc('\n', stdout);
- mp_mulmod(&a, &b, &m, &c);
- printf("c = "); mp_print(&c, stdout); fputc('\n', stdout);
+ printf("\nc = (a * b) mod m\n");
- printf("\nc = (a ** b) mod m\n");
+ mp_mulmod(&a, &b, &m, &c);
+ printf("c = ");
+ mp_print(&c, stdout);
+ fputc('\n', stdout);
- mp_exptmod(&a, &b, &m, &c);
- printf("c = "); mp_print(&c, stdout); fputc('\n', stdout);
+ printf("\nc = (a ** b) mod m\n");
- 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);
+ mp_exptmod(&a, &b, &m, &c);
+ printf("c = ");
+ mp_print(&c, stdout);
fputc('\n', stdout);
- }
-
- mp_clear(&c);
- mp_clear(&m);
- mp_clear(&b);
- mp_clear(&a);
+ 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;
+ return 0;
}
diff --git a/nss/lib/freebl/mpi/tests/mptest-4a.c b/nss/lib/freebl/mpi/tests/mptest-4a.c
index 46d4a4d..0c8e188 100644
--- a/nss/lib/freebl/mpi/tests/mptest-4a.c
+++ b/nss/lib/freebl/mpi/tests/mptest-4a.c
@@ -1,5 +1,5 @@
-/*
- * mptest4a - modular exponentiation speed test
+/*
+ * 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
@@ -17,89 +17,93 @@
#include "mpprime.h"
typedef struct {
- unsigned int sec;
- unsigned int usec;
+ unsigned int sec;
+ unsigned int usec;
} instant_t;
-instant_t now(void)
+instant_t
+now(void)
{
- struct timeval clk;
- instant_t res;
+ struct timeval clk;
+ instant_t res;
- res.sec = res.usec = 0;
+ res.sec = res.usec = 0;
- if(gettimeofday(&clk, NULL) != 0)
- return res;
+ if (gettimeofday(&clk, NULL) != 0)
+ return res;
- res.sec = clk.tv_sec;
- res.usec = clk.tv_usec;
+ res.sec = clk.tv_sec;
+ res.usec = clk.tv_usec;
- return res;
+ return res;
}
extern mp_err s_mp_pad();
-int main(int argc, char *argv[])
+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;
+ 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/nss/lib/freebl/mpi/tests/mptest-4b.c b/nss/lib/freebl/mpi/tests/mptest-4b.c
index b8e15ba..1bb2f91 100644
--- a/nss/lib/freebl/mpi/tests/mptest-4b.c
+++ b/nss/lib/freebl/mpi/tests/mptest-4b.c
@@ -19,84 +19,89 @@
#include "mpi.h"
#include "mpprime.h"
-char *g_prime =
- "34BD53C07350E817CCD49721020F1754527959C421C1533244769D4CF060A8B1C3DA"
- "25094BE723FB1E2369B55FEEBBE0FAC16425161BF82684062B5EC5D7D47D1B23C117"
- "0FA19745E44A55E148314E582EB813AC9EE5126295E2E380CACC2F6D206B293E5ED9"
- "23B54EE961A8C69CD625CE4EC38B70C649D7F014432AEF3A1C93";
+char *g_prime =
+ "34BD53C07350E817CCD49721020F1754527959C421C1533244769D4CF060A8B1C3DA"
+ "25094BE723FB1E2369B55FEEBBE0FAC16425161BF82684062B5EC5D7D47D1B23C117"
+ "0FA19745E44A55E148314E582EB813AC9EE5126295E2E380CACC2F6D206B293E5ED9"
+ "23B54EE961A8C69CD625CE4EC38B70C649D7F014432AEF3A1C93";
char *g_gen = "5";
typedef struct {
- unsigned int sec;
- unsigned int usec;
+ unsigned int sec;
+ unsigned int usec;
} instant_t;
-instant_t now(void)
+instant_t
+now(void)
{
- struct timeval clk;
- instant_t res;
+ struct timeval clk;
+ instant_t res;
- res.sec = res.usec = 0;
+ res.sec = res.usec = 0;
- if(gettimeofday(&clk, NULL) != 0)
- return res;
+ if (gettimeofday(&clk, NULL) != 0)
+ return res;
- res.sec = clk.tv_sec;
- res.usec = clk.tv_usec;
+ res.sec = clk.tv_sec;
+ res.usec = clk.tv_usec;
- return res;
+ return res;
}
extern mp_err s_mp_pad();
-int main(int argc, char *argv[])
+int
+main(int argc, char *argv[])
{
- instant_t start, finish;
- mp_int prime, gen, expt, res;
- unsigned int ix, diff;
- int num;
+ instant_t start, finish;
+ mp_int prime, gen, expt, res;
+ unsigned int ix, diff;
+ int num;
- srand(time(NULL));
+ srand(time(NULL));
- if(argc < 2) {
- fprintf(stderr, "Usage: %s <num-tests>\n", argv[0]);
- return 1;
- }
+ if (argc < 2) {
+ fprintf(stderr, "Usage: %s <num-tests>\n", argv[0]);
+ return 1;
+ }
- if((num = atoi(argv[1])) < 0)
- num = -num;
+ if ((num = atoi(argv[1])) < 0)
+ num = -num;
- if(num == 0)
- ++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(&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);
+ mp_init_size(&expt, USED(&prime) - 1);
+ s_mp_pad(&expt, USED(&prime) - 1);
- printf("Testing %d modular exponentations ... \n", num);
+ 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();
+ 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;
+ 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);
+ 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);
+ mp_clear(&expt);
+ mp_clear(&res);
+ mp_clear(&gen);
+ mp_clear(&prime);
- return 0;
+ return 0;
}
diff --git a/nss/lib/freebl/mpi/tests/mptest-5.c b/nss/lib/freebl/mpi/tests/mptest-5.c
index 73e8901..dff3ed4 100644
--- a/nss/lib/freebl/mpi/tests/mptest-5.c
+++ b/nss/lib/freebl/mpi/tests/mptest-5.c
@@ -15,56 +15,71 @@
#include "mpi.h"
-int main(int argc, char *argv[])
+int
+main(int argc, char *argv[])
{
- mp_int a, b, c, x, y;
+ mp_int a, b, c, x, y;
- if(argc < 3) {
- fprintf(stderr, "Usage: %s <a> <b>\n", argv[0]);
- return 1;
- }
+ if (argc < 3) {
+ fprintf(stderr, "Usage: %s <a> <b>\n", argv[0]);
+ return 1;
+ }
- printf("Test 5: Number theoretic functions\n\n");
+ printf("Test 5: Number theoretic functions\n\n");
- mp_init(&a);
- mp_init(&b);
+ mp_init(&a);
+ mp_init(&b);
- mp_read_radix(&a, argv[1], 10);
- mp_read_radix(&b, argv[2], 10);
+ 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");
+ printf("a = ");
+ mp_print(&a, stdout);
+ fputc('\n', stdout);
+ printf("b = ");
+ mp_print(&b, stdout);
+ fputc('\n', stdout);
- 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_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);
+ 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);
- }
+ 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);
+ mp_clear(&y);
+ mp_clear(&x);
+ mp_clear(&c);
+ mp_clear(&b);
+ mp_clear(&a);
- return 0;
+ return 0;
}
diff --git a/nss/lib/freebl/mpi/tests/mptest-5a.c b/nss/lib/freebl/mpi/tests/mptest-5a.c
index c7b29f7..c410a6a 100644
--- a/nss/lib/freebl/mpi/tests/mptest-5a.c
+++ b/nss/lib/freebl/mpi/tests/mptest-5a.c
@@ -20,113 +20,128 @@
#include "mpprime.h"
typedef struct {
- unsigned int sec;
- unsigned int usec;
+ unsigned int sec;
+ unsigned int usec;
} instant_t;
-instant_t now(void)
+instant_t
+now(void)
{
- struct timeval clk;
- instant_t res;
+ struct timeval clk;
+ instant_t res;
- res.sec = res.usec = 0;
+ res.sec = res.usec = 0;
- if(gettimeofday(&clk, NULL) != 0)
- return res;
+ if (gettimeofday(&clk, NULL) != 0)
+ return res;
- res.sec = clk.tv_sec;
- res.usec = clk.tv_usec;
+ res.sec = clk.tv_sec;
+ res.usec = clk.tv_usec;
- return res;
+ return res;
}
#define PRECISION 16
-int main(int argc, char *argv[])
+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;
+ 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;
+ 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/nss/lib/freebl/mpi/tests/mptest-6.c b/nss/lib/freebl/mpi/tests/mptest-6.c
index d39b3d4..4febf39 100644
--- a/nss/lib/freebl/mpi/tests/mptest-6.c
+++ b/nss/lib/freebl/mpi/tests/mptest-6.c
@@ -15,64 +15,64 @@
#include "mpi.h"
-void print_buf(FILE *ofp, char *buf, int len)
+void
+print_buf(FILE *ofp, char *buf, int len)
{
- int ix, brk = 0;
+ int ix, brk = 0;
- for(ix = 0; ix < len; ix++) {
- fprintf(ofp, "%02X ", buf[ix]);
+ 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);
+ brk = (brk + 1) & 0xF;
+ if (!brk)
+ fputc('\n', ofp);
+ }
+ if (brk)
+ fputc('\n', ofp);
}
-int main(int argc, char *argv[])
+int
+main(int argc, char *argv[])
{
- int ix, size;
- mp_int a;
- char *buf;
+ int ix, size;
+ mp_int a;
+ char *buf;
- if(argc < 2) {
- fprintf(stderr, "Usage: %s <a>\n", argv[0]);
- return 1;
- }
+ if (argc < 2) {
+ fprintf(stderr, "Usage: %s <a>\n", argv[0]);
+ return 1;
+ }
- printf("Test 6: Output functions\n\n");
+ printf("Test 6: Output functions\n\n");
- mp_init(&a);
+ mp_init(&a);
- mp_read_radix(&a, argv[1], 10);
+ mp_read_radix(&a, argv[1], 10);
- printf("\nConverting to a string:\n");
+ printf("\nConverting to a string:\n");
- printf("Rx Size Representation\n");
- for(ix = 2; ix <= MAX_RADIX; ix++) {
- size = mp_radix_size(&a, ix);
+ 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);
+ 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("\nRaw output:\n");
- size = mp_raw_size(&a);
- buf = calloc(size, sizeof(char));
+ printf("Size: %d bytes\n", size);
- printf("Size: %d bytes\n", size);
+ mp_toraw(&a, buf);
+ print_buf(stdout, buf, size);
+ free(buf);
- mp_toraw(&a, buf);
- print_buf(stdout, buf, size);
- free(buf);
-
- mp_clear(&a);
+ mp_clear(&a);
- return 0;
+ return 0;
}
diff --git a/nss/lib/freebl/mpi/tests/mptest-7.c b/nss/lib/freebl/mpi/tests/mptest-7.c
index bc86029..1e83fbf 100644
--- a/nss/lib/freebl/mpi/tests/mptest-7.c
+++ b/nss/lib/freebl/mpi/tests/mptest-7.c
@@ -19,56 +19,67 @@
#include "mpprime.h"
-int main(int argc, char *argv[])
+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;
+ 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/nss/lib/freebl/mpi/tests/mptest-8.c b/nss/lib/freebl/mpi/tests/mptest-8.c
index 8be438c..a9d3aff 100644
--- a/nss/lib/freebl/mpi/tests/mptest-8.c
+++ b/nss/lib/freebl/mpi/tests/mptest-8.c
@@ -19,47 +19,50 @@
#include "mpprime.h"
-int main(int argc, char *argv[])
+int
+main(int argc, char *argv[])
{
- int ix;
- mp_digit num;
- mp_int a;
+ int ix;
+ mp_digit num;
+ mp_int a;
- srand(time(NULL));
+ srand(time(NULL));
- if(argc < 2) {
- fprintf(stderr, "Usage: %s <a>\n", argv[0]);
- return 1;
- }
+ if (argc < 2) {
+ fprintf(stderr, "Usage: %s <a>\n", argv[0]);
+ return 1;
+ }
- printf("Test 8: Probabilistic primality testing\n\n");
+ printf("Test 8: Probabilistic primality testing\n\n");
- mp_init(&a);
+ mp_init(&a);
- mp_read_radix(&a, argv[1], 10);
+ mp_read_radix(&a, argv[1], 10);
- printf("a = "); mp_print(&a, stdout); fputc('\n', stdout);
+ 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");
+ 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);
+ 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;
+ if (mpp_pprime(&a, 5) == MP_NO) {
+ printf("it is not prime\n");
+ goto CLEANUP;
+ }
}
- }
- printf("All tests passed; a is probably prime\n");
+ printf("All tests passed; a is probably prime\n");
CLEANUP:
- mp_clear(&a);
+ mp_clear(&a);
- return 0;
+ return 0;
}
diff --git a/nss/lib/freebl/mpi/tests/mptest-9.c b/nss/lib/freebl/mpi/tests/mptest-9.c
index 210adca..133264e 100644
--- a/nss/lib/freebl/mpi/tests/mptest-9.c
+++ b/nss/lib/freebl/mpi/tests/mptest-9.c
@@ -17,67 +17,93 @@
#include "mpi.h"
#include "mplogic.h"
-int main(int argc, char *argv[])
+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;
+ 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/nss/lib/freebl/mpi/tests/mptest-b.c b/nss/lib/freebl/mpi/tests/mptest-b.c
index 51ffc20..07f30ea 100644
--- a/nss/lib/freebl/mpi/tests/mptest-b.c
+++ b/nss/lib/freebl/mpi/tests/mptest-b.c
@@ -15,14 +15,15 @@
#include "mp_gf2m.h"
-int main(int argc, char *argv[])
+int
+main(int argc, char *argv[])
{
- int ix;
- mp_int pp, a, b, x, y, order;
- mp_int c, d, e;
+ 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};
+ mp_err res;
+ unsigned int p[] = { 163, 7, 6, 3, 0 };
unsigned int ptemp[10];
printf("Test b: Binary Polynomial Arithmetic\n\n");
@@ -40,12 +41,24 @@ int main(int argc, char *argv[])
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);
+ 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);
@@ -54,121 +67,152 @@ int main(int argc, char *argv[])
/* 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;
+ (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) );
+ MP_CHECKOK(mp_barr2poly(p, &c));
if (mp_cmp(&pp, &c) != 0) {
- printf("Array to polynomial conversion not correct\n");
+ 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) );
+ MP_CHECKOK(mp_badd(&a, &a, &c));
if (mp_cmp_z(&c) != 0) {
- printf("a+a should equal zero\n");
+ 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) );
+ 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);
+ 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_CHECKOK(mp_bmul(&b, &c, &c));
+ MP_CHECKOK(mp_badd(&b, &c, &c));
mp_set(&d, 3);
- MP_CHECKOK( mp_bmul(&b, &d, &d) );
+ 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);
+ 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) );
+ 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);
+ 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) );
+ 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);
+ 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) );
+ 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);
+ 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) );
+ 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);
+ 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) );
+ 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);
+ 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) );
+ 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);
+ 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) );
+ 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);
+ 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");
diff --git a/nss/lib/freebl/mpi/utils/basecvt.c b/nss/lib/freebl/mpi/utils/basecvt.c
index 6cfda55..0e99154 100644
--- a/nss/lib/freebl/mpi/utils/basecvt.c
+++ b/nss/lib/freebl/mpi/utils/basecvt.c
@@ -15,53 +15,54 @@
#include "mpi.h"
-#define IBASE 10
-#define OBASE 16
-#define USAGE "Usage: %s ibase obase [value]\n"
-#define MAXBASE 64
-#define MINBASE 2
+#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
+main(int argc, char *argv[])
{
- int ix, ibase = IBASE, obase = OBASE;
- mp_int val;
+ 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;
+ 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 (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;
+ 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_init(&val);
+ while (ix < argc) {
+ char *out;
+ int outlen;
- mp_read_radix(&val, argv[ix++], ibase);
+ mp_read_radix(&val, argv[ix++], ibase);
- outlen = mp_radix_size(&val, obase);
- out = calloc(outlen, sizeof(char));
- mp_toradix(&val, out, obase);
+ outlen = mp_radix_size(&val, obase);
+ out = calloc(outlen, sizeof(char));
+ mp_toradix(&val, out, obase);
- printf("%s\n", out);
- free(out);
- }
+ printf("%s\n", out);
+ free(out);
+ }
- mp_clear(&val);
+ mp_clear(&val);
- return 0;
+ return 0;
}
diff --git a/nss/lib/freebl/mpi/utils/bbs_rand.c b/nss/lib/freebl/mpi/utils/bbs_rand.c
index c905b0f..fed2fe2 100644
--- a/nss/lib/freebl/mpi/utils/bbs_rand.c
+++ b/nss/lib/freebl/mpi/utils/bbs_rand.c
@@ -7,55 +7,57 @@
#include "bbs_rand.h"
-#define SEED 1
-#define MODULUS 2
+#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 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 */
+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);
+int bbs_seed_size = (sizeof(bbs_modulus) / 2);
-void bbs_srand(unsigned char *data, int len)
+void
+bbs_srand(unsigned char *data, int len)
{
- if((bbs_init & SEED) == 0) {
- mp_init(&bbs_state);
- bbs_init |= SEED;
- }
+ if ((bbs_init & SEED) == 0) {
+ mp_init(&bbs_state);
+ bbs_init |= SEED;
+ }
- mp_read_raw(&bbs_state, (char *)data, len);
+ mp_read_raw(&bbs_state, (char *)data, len);
} /* end bbs_srand() */
-unsigned int bbs_rand(void)
+unsigned int
+bbs_rand(void)
{
- static mp_int modulus;
- unsigned int result = 0, ix;
+ 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;
- }
+ 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;
+ for (ix = 0; ix < sizeof(unsigned int); ix++) {
+ mp_digit d;
- mp_sqrmod(&bbs_state, &modulus, &bbs_state);
- d = DIGIT(&bbs_state, 0);
+ mp_sqrmod(&bbs_state, &modulus, &bbs_state);
+ d = DIGIT(&bbs_state, 0);
- result = (result << CHAR_BIT) | (d & UCHAR_MAX);
- }
+ result = (result << CHAR_BIT) | (d & UCHAR_MAX);
+ }
- return result;
+ return result;
} /* end bbs_rand() */
diff --git a/nss/lib/freebl/mpi/utils/bbs_rand.h b/nss/lib/freebl/mpi/utils/bbs_rand.h
index faf0f3d..d12269b 100644
--- a/nss/lib/freebl/mpi/utils/bbs_rand.h
+++ b/nss/lib/freebl/mpi/utils/bbs_rand.h
@@ -13,12 +13,12 @@
#include <limits.h>
#include "mpi.h"
-#define BBS_RAND_MAX UINT_MAX
+#define BBS_RAND_MAX UINT_MAX
/* Suggested length of seed data */
extern int bbs_seed_size;
-void bbs_srand(unsigned char *data, int len);
+void bbs_srand(unsigned char *data, int len);
unsigned int bbs_rand(void);
#endif /* end _H_BBSRAND_ */
diff --git a/nss/lib/freebl/mpi/utils/bbsrand.c b/nss/lib/freebl/mpi/utils/bbsrand.c
index 6ef20bb..d9151e0 100644
--- a/nss/lib/freebl/mpi/utils/bbsrand.c
+++ b/nss/lib/freebl/mpi/utils/bbsrand.c
@@ -15,20 +15,21 @@
#include "bbs_rand.h"
-#define NUM_TESTS 100
+#define NUM_TESTS 100
-int main(void)
+int
+main(void)
{
- unsigned int seed, result, ix;
+ unsigned int seed, result, ix;
- seed = time(NULL);
- bbs_srand((unsigned char *)&seed, sizeof(seed));
+ 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);
- }
+ for (ix = 0; ix < NUM_TESTS; ix++) {
+ result = bbs_rand();
- return 0;
+ printf("Test %3u: %08X\n", ix + 1, result);
+ }
+
+ return 0;
}
diff --git a/nss/lib/freebl/mpi/utils/dec2hex.c b/nss/lib/freebl/mpi/utils/dec2hex.c
index 13550e4..ef3a520 100644
--- a/nss/lib/freebl/mpi/utils/dec2hex.c
+++ b/nss/lib/freebl/mpi/utils/dec2hex.c
@@ -13,26 +13,28 @@
#include "mpi.h"
-int main(int argc, char *argv[])
+int
+main(int argc, char *argv[])
{
- mp_int a;
- char *buf;
- int len;
+ mp_int a;
+ char *buf;
+ int len;
- if(argc < 2) {
- fprintf(stderr, "Usage: %s <a>\n", argv[0]);
- return 1;
- }
+ 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);
+ 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);
+ printf("%s\n", buf);
- free(buf);
- mp_clear(&a);
+ free(buf);
+ mp_clear(&a);
- return 0;
+ return 0;
}
diff --git a/nss/lib/freebl/mpi/utils/exptmod.c b/nss/lib/freebl/mpi/utils/exptmod.c
index 4aa5b23..3ac9078 100644
--- a/nss/lib/freebl/mpi/utils/exptmod.c
+++ b/nss/lib/freebl/mpi/utils/exptmod.c
@@ -14,37 +14,42 @@
#include "mpi.h"
-int main(int argc, char *argv[])
+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;
+ 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/nss/lib/freebl/mpi/utils/fact.c b/nss/lib/freebl/mpi/utils/fact.c
index a8735ad..da8e61a 100644
--- a/nss/lib/freebl/mpi/utils/fact.c
+++ b/nss/lib/freebl/mpi/utils/fact.c
@@ -15,68 +15,70 @@
mp_err mp_fact(mp_int *a, mp_int *b);
-int main(int argc, char *argv[])
+int
+main(int argc, char *argv[])
{
- mp_int a;
- mp_err res;
+ mp_int a;
+ mp_err res;
- if(argc < 2) {
- fprintf(stderr, "Usage: %s <number>\n", argv[0]);
- return 1;
- }
+ if (argc < 2) {
+ fprintf(stderr, "Usage: %s <number>\n", argv[0]);
+ return 1;
+ }
- mp_init(&a);
- mp_read_radix(&a, argv[1], 10);
+ 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;
- }
+ 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;
+ {
+ char *buf;
+ int len;
- len = mp_radix_size(&a, 10);
- buf = malloc(len);
- mp_todecimal(&a, buf);
+ len = mp_radix_size(&a, 10);
+ buf = malloc(len);
+ mp_todecimal(&a, buf);
- puts(buf);
+ puts(buf);
- free(buf);
- }
+ free(buf);
+ }
- mp_clear(&a);
- return 0;
+ mp_clear(&a);
+ return 0;
}
-mp_err mp_fact(mp_int *a, mp_int *b)
+mp_err
+mp_fact(mp_int *a, mp_int *b)
{
- mp_int ix, s;
- mp_err res = MP_OKAY;
+ mp_int ix, s;
+ mp_err res = MP_OKAY;
- if(mp_cmp_z(a) < 0)
- return MP_UNDEF;
+ 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 */
+ 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;
- }
+ 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);
+ mp_clear(&ix);
- /* Copy out results if we got them */
- if(res == MP_OKAY)
- mp_copy(&s, b);
+ /* Copy out results if we got them */
+ if (res == MP_OKAY)
+ mp_copy(&s, b);
- mp_clear(&s);
+ mp_clear(&s);
- return res;
+ return res;
}
diff --git a/nss/lib/freebl/mpi/utils/gcd.c b/nss/lib/freebl/mpi/utils/gcd.c
index d5f3a4e..9f11a25 100644
--- a/nss/lib/freebl/mpi/utils/gcd.c
+++ b/nss/lib/freebl/mpi/utils/gcd.c
@@ -13,74 +13,83 @@
#include "mpi.h"
-char *g_prog = NULL;
+char *g_prog = NULL;
void print_mp_int(mp_int *mp, FILE *ofp);
-int main(int argc, char *argv[])
+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;
+ 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;
}
- } 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;
+
+ 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);
}
- }
- print_mp_int(&a, stdout);
- if(ext) {
- fputs("x = ", stdout); print_mp_int(&x, stdout);
- fputs("y = ", stdout); print_mp_int(&y, stdout);
- }
+ 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;
+ }
+ }
- mp_clear(&a); mp_clear(&b);
+ print_mp_int(&a, stdout);
+ if (ext) {
+ fputs("x = ", stdout);
+ print_mp_int(&x, stdout);
+ fputs("y = ", stdout);
+ print_mp_int(&y, stdout);
+ }
- if(ext) {
- mp_clear(&x);
- mp_clear(&y);
- }
+ mp_clear(&a);
+ mp_clear(&b);
- return 0;
+ if (ext) {
+ mp_clear(&x);
+ mp_clear(&y);
+ }
+ return 0;
}
-void print_mp_int(mp_int *mp, FILE *ofp)
+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);
-
+ 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/nss/lib/freebl/mpi/utils/hex2dec.c b/nss/lib/freebl/mpi/utils/hex2dec.c
index 5bcb0f3..9b21d22 100644
--- a/nss/lib/freebl/mpi/utils/hex2dec.c
+++ b/nss/lib/freebl/mpi/utils/hex2dec.c
@@ -13,26 +13,28 @@
#include "mpi.h"
-int main(int argc, char *argv[])
+int
+main(int argc, char *argv[])
{
- mp_int a;
- char *buf;
- int len;
+ mp_int a;
+ char *buf;
+ int len;
- if(argc < 2) {
- fprintf(stderr, "Usage: %s <a>\n", argv[0]);
- return 1;
- }
+ 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);
+ 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);
+ printf("%s\n", buf);
- free(buf);
- mp_clear(&a);
+ free(buf);
+ mp_clear(&a);
- return 0;
+ return 0;
}
diff --git a/nss/lib/freebl/mpi/utils/identest.c b/nss/lib/freebl/mpi/utils/identest.c
index 8172d77..321d2c2 100644
--- a/nss/lib/freebl/mpi/utils/identest.c
+++ b/nss/lib/freebl/mpi/utils/identest.c
@@ -11,73 +11,74 @@
#define MAX_PREC (4096 / MP_DIGIT_BIT)
-mp_err identity_test(void)
+mp_err
+identity_test(void)
{
- mp_size preca, precb;
- mp_err res;
- mp_int a, b;
- mp_int t1, t2, t3, t4, t5;
+ 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;
+ 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_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(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) );
+ MP_CHECKOK(mpp_random_size(&a, preca));
+ MP_CHECKOK(mpp_random_size(&b, precb));
- if (mp_cmp(&a, &b) < 0)
- mp_exch(&a, &b);
+ 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;
- }
+ 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;
+ 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;
+ unsigned int seed = (unsigned int)time(NULL);
+ unsigned long count = 0;
+ mp_err res;
- srand(seed);
+ srand(seed);
- while (MP_OKAY == (res = identity_test())) {
- if ((++count % 100) == 0)
- fputc('.', stderr);
- }
+ while (MP_OKAY == (res = identity_test())) {
+ if ((++count % 100) == 0)
+ fputc('.', stderr);
+ }
- fprintf(stderr, "\ntest failed, err %d\n", res);
- return res;
+ fprintf(stderr, "\ntest failed, err %d\n", res);
+ return res;
}
diff --git a/nss/lib/freebl/mpi/utils/invmod.c b/nss/lib/freebl/mpi/utils/invmod.c
index c71cc02..9b4b04d 100644
--- a/nss/lib/freebl/mpi/utils/invmod.c
+++ b/nss/lib/freebl/mpi/utils/invmod.c
@@ -12,48 +12,50 @@
#include "mpi.h"
-int main(int argc, char *argv[])
+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;
+ 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/nss/lib/freebl/mpi/utils/isprime.c b/nss/lib/freebl/mpi/utils/isprime.c
index 6548899..d2d8695 100644
--- a/nss/lib/freebl/mpi/utils/isprime.c
+++ b/nss/lib/freebl/mpi/utils/isprime.c
@@ -14,75 +14,76 @@
#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 */
+#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 g_tests = RM_TESTS;
+char *g_prog = NULL;
-int main(int argc, char *argv[])
+int
+main(int argc, char *argv[])
{
- mp_int a;
- mp_digit np = prime_tab_size; /* from mpprime.h */
- int res = 0;
+ mp_int a;
+ mp_digit np = prime_tab_size; /* from mpprime.h */
+ int res = 0;
- g_prog = argv[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;
- }
+ 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;
+ /* 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;
+ if ((tmp = PR_GetEnvSecure("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);
+ 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;
+ }
- 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);
+ /* 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;
+ mp_clear(&a);
+ return res;
}
diff --git a/nss/lib/freebl/mpi/utils/lap.c b/nss/lib/freebl/mpi/utils/lap.c
index b6ab884..501e453 100644
--- a/nss/lib/freebl/mpi/utils/lap.c
+++ b/nss/lib/freebl/mpi/utils/lap.c
@@ -17,72 +17,74 @@ void sig_catch(int ign);
int g_quit = 0;
-int main(int argc, char *argv[])
+int
+main(int argc, char *argv[])
{
- mp_int a, m, p, k;
+ mp_int a, m, p, k;
- if(argc < 3) {
- fprintf(stderr, "Usage: %s <a> <m>\n", argv[0]);
- return 1;
- }
+ 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_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_read_radix(&a, argv[1], 10);
+ mp_read_radix(&m, argv[2], 10);
- mp_init_copy(&k, &a);
+ mp_init_copy(&k, &a);
- signal(SIGINT, sig_catch);
+ signal(SIGINT, sig_catch);
#ifndef __OS2__
- signal(SIGHUP, sig_catch);
+ 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;
+ signal(SIGTERM, sig_catch);
- len = mp_radix_size(&p, 10);
- buf = malloc(len);
- mp_toradix(&p, buf, 10);
+ while (mp_cmp(&p, &m) < 0) {
+ if (g_quit) {
+ int len;
+ char *buf;
- printf("%s\n", buf);
+ len = mp_radix_size(&p, 10);
+ buf = malloc(len);
+ mp_toradix(&p, buf, 10);
- free(buf);
- break;
- }
+ fprintf(stderr, "Terminated at: %s\n", buf);
+ free(buf);
+ return 1;
+ }
+ if (mp_cmp_d(&k, 1) == 0) {
+ int len;
+ char *buf;
- mp_mulmod(&k, &a, &m, &k);
- mp_add_d(&p, 1, &p);
- }
+ 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");
+ if (mp_cmp(&p, &m) >= 0)
+ printf("No annihilating power.\n");
- mp_clear(&p);
- mp_clear(&m);
- mp_clear(&a);
- return 0;
+ mp_clear(&p);
+ mp_clear(&m);
+ mp_clear(&a);
+ return 0;
}
-void sig_catch(int ign)
+void
+sig_catch(int ign)
{
- g_quit = 1;
+ g_quit = 1;
}
diff --git a/nss/lib/freebl/mpi/utils/makeprime.c b/nss/lib/freebl/mpi/utils/makeprime.c
index 22808c6..401b753 100644
--- a/nss/lib/freebl/mpi/utils/makeprime.c
+++ b/nss/lib/freebl/mpi/utils/makeprime.c
@@ -29,84 +29,86 @@
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.
+ caller should keep a copy if the value is needed.
*/
-mp_err make_prime(mp_int *p, int nr);
+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[])
+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;
- }
-
+ 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
+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;
+ 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() */
diff --git a/nss/lib/freebl/mpi/utils/metime.c b/nss/lib/freebl/mpi/utils/metime.c
index de51043..122875e 100644
--- a/nss/lib/freebl/mpi/utils/metime.c
+++ b/nss/lib/freebl/mpi/utils/metime.c
@@ -1,4 +1,4 @@
-/*
+/*
* metime.c
*
* Modular exponentiation timing test
@@ -18,82 +18,84 @@
double clk_to_sec(clock_t start, clock_t stop);
-int main(int argc, char *argv[])
+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;
+ int ix, num, prec = 8;
+ unsigned int seed;
+ clock_t start, stop;
+ double sec;
+
+ mp_int a, m, c;
+
+ if (PR_GetEnvSecure("SEED") != NULL)
+ seed = abs(atoi(PR_GetEnvSecure("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)
+double
+clk_to_sec(clock_t start, clock_t stop)
{
- return (double)(stop - start) / CLOCKS_PER_SEC;
+ return (double)(stop - start) / CLOCKS_PER_SEC;
}
/*------------------------------------------------------------------------*/
diff --git a/nss/lib/freebl/mpi/utils/pi.c b/nss/lib/freebl/mpi/utils/pi.c
index 78f5736..7e31097 100644
--- a/nss/lib/freebl/mpi/utils/pi.c
+++ b/nss/lib/freebl/mpi/utils/pi.c
@@ -3,7 +3,7 @@
*
* 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
@@ -23,89 +23,96 @@
mp_err arctan(mp_digit mul, mp_digit x, mp_digit prec, mp_int *sum);
-int main(int argc, char *argv[])
+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_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;
}
- mp_todecimal(&sum1, buf);
- printf("%s\n", buf);
- free(buf);
- }
- fprintf(stderr, "Computation took %.2f sec.\n",
- (double)(stop - start) / CLOCKS_PER_SEC);
+ if ((ndigits = abs(atoi(argv[1]))) == 0) {
+ fprintf(stderr, "%s: you must request at least 1 digit\n", argv[0]);
+ return 1;
+ }
- CLEANUP:
- mp_clear(&sum1);
- mp_clear(&sum2);
+ start = clock();
+ mp_init(&sum1);
+ mp_init(&sum2);
- return out;
+ /* 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;
+ }
-/* 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;
+ /* 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);
- prec += 3; /* push inaccuracies off the end */
+CLEANUP:
+ mp_clear(&sum1);
+ mp_clear(&sum2);
- 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;
+ 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.
@@ -113,51 +120,51 @@ mp_err arctan(mp_digit mul, mp_digit x, mp_digit prec, mp_int *sum)
We compute arctan(1/x) by the formula:
1 1 1 1
- - - ----- + ----- - ----- + ...
- x 3 x^3 5 x^5 7 x^7
+ - - ----- + ----- - ----- + ...
+ 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 */
+ x *= x; /* works as long as x < sqrt(RADIX), which it is here */
- mp_zero(sum);
+ mp_zero(sum);
- do {
- if((res = mp_div_d(&t, x, &t, &rd)) != MP_OKAY)
- goto CLEANUP;
+ 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 (sign < 0 && rd != 0)
+ mp_add_d(&t, 1, &t);
- if((res = mp_div_d(&t, q, &v, &rd)) != MP_OKAY)
- goto CLEANUP;
+ 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 && 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 (sign > 0)
+ res = mp_add(sum, &v, sum);
+ else
+ res = mp_sub(sum, &v, sum);
- if(res != MP_OKAY)
- goto CLEANUP;
+ if (res != MP_OKAY)
+ goto CLEANUP;
- sign *= -1;
- q += 2;
+ sign *= -1;
+ q += 2;
- } while(mp_cmp_z(&t) != 0);
+ } while (mp_cmp_z(&t) != 0);
- /* Chop off inaccurate low-order digits */
- mp_div_d(sum, 1000, sum, NULL);
+ /* Chop off inaccurate low-order digits */
+ mp_div_d(sum, 1000, sum, NULL);
- CLEANUP:
- mp_clear(&v);
- mp_clear(&t);
+CLEANUP:
+ mp_clear(&v);
+ mp_clear(&t);
- return res;
+ return res;
}
/*------------------------------------------------------------------------*/
diff --git a/nss/lib/freebl/mpi/utils/primegen.c b/nss/lib/freebl/mpi/utils/primegen.c
index aac7aba..f62a56a 100644
--- a/nss/lib/freebl/mpi/utils/primegen.c
+++ b/nss/lib/freebl/mpi/utils/primegen.c
@@ -25,134 +25,135 @@
#include "mplogic.h"
#include "mpprime.h"
-#define NUM_TESTS 5 /* Number of Rabin-Miller iterations to test with */
+#define NUM_TESTS 5 /* Number of Rabin-Miller iterations to test with */
#ifdef DEBUG
-#define FPUTC(x,y) fputc(x,y)
+#define FPUTC(x, y) fputc(x, y)
#else
-#define FPUTC(x,y)
+#define FPUTC(x, y)
#endif
-int main(int argc, char *argv[])
+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
+ 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
+ if ((out = PR_GetEnvSecure("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 (argc < 3) {
+ ngen = 1;
+ } else {
+ ngen = abs(atoi(argv[2]));
+ }
- /* If fourth argument is given, and is the word "strong", we'll
+ /* 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;
+ 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);
}
- 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;
+
+ 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/nss/lib/freebl/mpi/utils/prng.c b/nss/lib/freebl/mpi/utils/prng.c
index 59ccae0..38748d1 100644
--- a/nss/lib/freebl/mpi/utils/prng.c
+++ b/nss/lib/freebl/mpi/utils/prng.c
@@ -21,37 +21,37 @@
#include "bbs_rand.h"
-int main(int argc, char *argv[])
+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;
- }
+ unsigned char *seed;
+ unsigned int ix, num = 1;
+ pid_t pid;
- pid = getpid();
- srand(time(NULL) * (unsigned int)pid);
+ if (argc > 1) {
+ num = atoi(argv[1]);
+ if (num <= 0)
+ num = 1;
+ }
- /* 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;
- }
+ pid = getpid();
+ srand(time(NULL) * (unsigned int)pid);
- bbs_srand(seed, bbs_seed_size);
- memset(seed, 0, bbs_seed_size);
- free(seed);
+ /* 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;
+ }
- while(num-- > 0) {
- ix = bbs_rand();
+ bbs_srand(seed, bbs_seed_size);
+ memset(seed, 0, bbs_seed_size);
+ free(seed);
- printf("%u\n", ix);
- }
+ while (num-- > 0) {
+ ix = bbs_rand();
- return 0;
+ printf("%u\n", ix);
+ }
+ return 0;
}
diff --git a/nss/lib/freebl/mpi/utils/sieve.c b/nss/lib/freebl/mpi/utils/sieve.c
index 71a17c8..57768af 100644
--- a/nss/lib/freebl/mpi/utils/sieve.c
+++ b/nss/lib/freebl/mpi/utils/sieve.c
@@ -28,14 +28,14 @@
#include <stdlib.h>
#include <limits.h>
-typedef unsigned char byte;
+typedef unsigned char byte;
typedef struct {
- int size;
- byte *bits;
- long base;
- int next;
- int nbits;
+ int size;
+ byte *bits;
+ long base;
+ int next;
+ int nbits;
} sieve;
void sieve_init(sieve *sp, long base, int nbits);
@@ -45,191 +45,199 @@ 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)
+#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[])
+int
+main(int argc, char *argv[])
{
- sieve s;
- long pr, *p;
- int c, ix, cur = 0;
+ sieve s;
+ long pr, *p;
+ int c, ix, cur = 0;
- if(argc < 2) {
- fprintf(stderr, "Usage: %s <width>\n", argv[0]);
- return 1;
- }
+ if (argc < 2) {
+ fprintf(stderr, "Usage: %s <width>\n", argv[0]);
+ return 1;
+ }
- c = atoi(argv[1]);
- if(c < 0) c = -c;
+ c = atoi(argv[1]);
+ if (c < 0)
+ c = -c;
- fprintf(stderr, "%s: sieving to %d positions\n", argv[0], c);
+ fprintf(stderr, "%s: sieving to %d positions\n", argv[0], c);
- sieve_init(&s, 3, c);
+ sieve_init(&s, 3, c);
- c = 0;
- while((pr = sieve_next(&s)) > 0) {
- ++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);
- }
+ 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]);
- 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;
+ }
+ }
- 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);
}
- }
-
- 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));
+ 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);
+ sieve_clear(&s);
- return 0;
+ return 0;
}
-void sieve_init(sieve *sp, long base, int nbits)
+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;
+ 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)
+void
+sieve_grow(sieve *sp, int nbits)
{
- int ns = (nbits / CHAR_BIT);
+ int ns = (nbits / CHAR_BIT);
- if(nbits % CHAR_BIT)
- ++ns;
+ if (nbits % CHAR_BIT)
+ ++ns;
- if(ns > sp->size) {
- byte *tmp;
- int ix;
+ 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;
- }
+ 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;
- }
+ 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;
+ free(sp->bits);
+ sp->bits = tmp;
+ sp->size = ns;
- sp->nbits = sp->size * CHAR_BIT;
- }
+ sp->nbits = sp->size * CHAR_BIT;
+ }
}
-long sieve_next(sieve *sp)
+long
+sieve_next(sieve *sp)
{
- long out;
- int ix = 0;
- long val;
+ long out;
+ int ix = 0;
+ long val;
- if(sp->next > sp->nbits)
- return -1;
+ if (sp->next > sp->nbits)
+ return -1;
- out = S_VAL(sp, sp->next);
+ out = S_VAL(sp, sp->next);
#ifdef DEBUG
- fprintf(stderr, "Sieving %ld\n", out);
+ 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);
+ /* 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);
+ 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))
+ /* Scan ahead to the next prime */
++sp->next;
+ while (sp->next < sp->nbits && !S_ISSET(sp, sp->next))
+ ++sp->next;
- return out;
+ return out;
}
-void sieve_cross(sieve *sp, long val)
+void
+sieve_cross(sieve *sp, long val)
{
- int ix = 0;
- long cur = val;
+ int ix = 0;
+ long cur = val;
- while(cur < sp->base)
- 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);
- }
+ 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)
+void
+sieve_reset(sieve *sp, long base)
{
- memset(sp->bits, UCHAR_MAX, sp->size);
- sp->base = base;
- sp->next = 0;
+ memset(sp->bits, UCHAR_MAX, sp->size);
+ sp->base = base;
+ sp->next = 0;
}
-void sieve_clear(sieve *sp)
+void
+sieve_clear(sieve *sp)
{
- if(sp->bits)
- free(sp->bits);
+ if (sp->bits)
+ free(sp->bits);
- sp->bits = NULL;
+ sp->bits = NULL;
}
diff --git a/nss/lib/freebl/mpi/vis_proto.h b/nss/lib/freebl/mpi/vis_proto.h
index 7e8ed29..275de59 100644
--- a/nss/lib/freebl/mpi/vis_proto.h
+++ b/nss/lib/freebl/mpi/vis_proto.h
@@ -9,7 +9,7 @@
#ifndef VIS_PROTO_H
#define VIS_PROTO_H
-#pragma ident "@(#)vis_proto.h 1.3 97/03/30 SMI"
+#pragma ident "@(#)vis_proto.h 1.3 97/03/30 SMI"
#ifdef __cplusplus
extern "C" {
@@ -186,46 +186,46 @@ 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))
+#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_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_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
+#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))
+#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"
diff --git a/nss/lib/freebl/nsslowhash.c b/nss/lib/freebl/nsslowhash.c
index a9ab5b7..5ed0396 100644
--- a/nss/lib/freebl/nsslowhash.c
+++ b/nss/lib/freebl/nsslowhash.c
@@ -7,256 +7,24 @@
#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 );
-}
+#include "blapii.h"
struct NSSLOWInitContextStr {
- int count;
+ int count;
};
struct NSSLOWHASHContextStr {
const SECHashObject *hashObj;
void *hashCtxt;
-
};
-static int nsslow_GetFIPSEnabled(void) {
+static int
+nsslow_GetFIPSEnabled(void)
+{
#ifdef LINUX
FILE *f;
char d;
@@ -276,117 +44,107 @@ static int nsslow_GetFIPSEnabled(void) {
return 1;
}
-
-static int post = 0;
-static int post_failed = 0;
-
static NSSLOWInitContext dummyContext = { 0 };
+static PRBool post_failed = PR_TRUE;
NSSLOWInitContext *
NSSLOW_Init(void)
{
- CK_RV crv;
#ifdef FREEBL_NO_DEPEND
(void)FREEBL_InitStubs();
#endif
- if (post_failed) {
- return NULL;
- }
-
-
- if (!post && nsslow_GetFIPSEnabled()) {
- crv = freebl_fipsPowerUpSelfTest();
- if (crv != CKR_OK) {
- post_failed = 1;
- return NULL;
- }
+ /* make sure the FIPS product is installed if we are trying to
+ * go into FIPS mode */
+ if (nsslow_GetFIPSEnabled()) {
+ if (BL_FIPSEntryOK(PR_TRUE) != SECSuccess) {
+ PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
+ post_failed = PR_TRUE;
+ return NULL;
+ }
}
- post = 1;
+ post_failed = PR_FALSE;
-
return &dummyContext;
}
void
NSSLOW_Shutdown(NSSLOWInitContext *context)
{
- PORT_Assert(context == &dummyContext);
- return;
+ PORT_Assert(context == &dummyContext);
+ return;
}
void
NSSLOW_Reset(NSSLOWInitContext *context)
{
- PORT_Assert(context == &dummyContext);
- post_failed = 0;
- post = 0;
- return;
+ PORT_Assert(context == &dummyContext);
+ return;
}
NSSLOWHASHContext *
-NSSLOWHASH_NewContext(NSSLOWInitContext *initContext,
- HASH_HashType hashType)
+NSSLOWHASH_NewContext(NSSLOWInitContext *initContext,
+ HASH_HashType hashType)
{
- NSSLOWHASHContext *context;
+ NSSLOWHASHContext *context;
- if (post_failed) {
- PORT_SetError(SEC_ERROR_PKCS11_DEVICE_ERROR);
- return NULL;
- }
+ if (post_failed) {
+ PORT_SetError(SEC_ERROR_PKCS11_DEVICE_ERROR);
+ return NULL;
+ }
- if (initContext != &dummyContext) {
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- 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;
- }
+ 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;
+ return context;
}
void
NSSLOWHASH_Begin(NSSLOWHASHContext *context)
{
- return context->hashObj->begin(context->hashCtxt);
+ return context->hashObj->begin(context->hashCtxt);
}
void
-NSSLOWHASH_Update(NSSLOWHASHContext *context, const unsigned char *buf,
- unsigned int len)
+NSSLOWHASH_Update(NSSLOWHASHContext *context, const unsigned char *buf,
+ unsigned int len)
{
- return context->hashObj->update(context->hashCtxt, buf, len);
+ return context->hashObj->update(context->hashCtxt, buf, len);
}
void
-NSSLOWHASH_End(NSSLOWHASHContext *context, unsigned char *buf,
- unsigned int *ret, unsigned int len)
+NSSLOWHASH_End(NSSLOWHASHContext *context, unsigned char *buf,
+ unsigned int *ret, unsigned int len)
{
- return context->hashObj->end(context->hashCtxt, buf, ret, 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);
+ context->hashObj->destroy(context->hashCtxt, PR_TRUE);
+ PORT_Free(context);
}
unsigned int
NSSLOWHASH_Length(NSSLOWHASHContext *context)
{
- return context->hashObj->length;
+ return context->hashObj->length;
}
diff --git a/nss/lib/freebl/nsslowhash.h b/nss/lib/freebl/nsslowhash.h
index bfce42b..d8f0587 100644
--- a/nss/lib/freebl/nsslowhash.h
+++ b/nss/lib/freebl/nsslowhash.h
@@ -18,16 +18,16 @@ NSSLOWInitContext *NSSLOW_Init(void);
void NSSLOW_Shutdown(NSSLOWInitContext *context);
void NSSLOW_Reset(NSSLOWInitContext *context);
NSSLOWHASHContext *NSSLOWHASH_NewContext(
- NSSLOWInitContext *initContext,
- HASH_HashType hashType);
+ 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_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);
+unsigned int NSSLOWHASH_Length(NSSLOWHASHContext *context);
#endif
diff --git a/nss/lib/freebl/os2_rand.c b/nss/lib/freebl/os2_rand.c
index bfe28cf..407b080 100644
--- a/nss/lib/freebl/os2_rand.c
+++ b/nss/lib/freebl/os2_rand.c
@@ -12,32 +12,34 @@
#include <stdio.h>
#include <sys/stat.h>
-static BOOL clockTickTime(unsigned long *phigh, unsigned long *plow)
+static BOOL
+clockTickTime(unsigned long *phigh, unsigned long *plow)
{
APIRET rc = NO_ERROR;
- QWORD qword = {0,0};
+ QWORD qword = { 0, 0 };
rc = DosTmrQueryTime(&qword);
if (rc != NO_ERROR)
- return FALSE;
+ return FALSE;
*phigh = qword.ulHi;
- *plow = qword.ulLo;
+ *plow = qword.ulLo;
return TRUE;
}
-size_t RNG_GetNoise(void *buf, size_t maxbuf)
+size_t
+RNG_GetNoise(void *buf, size_t maxbuf)
{
unsigned long high = 0;
- unsigned long low = 0;
+ unsigned long low = 0;
clock_t val = 0;
int n = 0;
int nBytes = 0;
time_t sTime;
if (maxbuf <= 0)
- return 0;
+ return 0;
clockTickTime(&high, &low);
@@ -48,7 +50,7 @@ size_t RNG_GetNoise(void *buf, size_t maxbuf)
maxbuf -= nBytes;
if (maxbuf <= 0)
- return n;
+ return n;
nBytes = sizeof(high) > maxbuf ? maxbuf : sizeof(high);
memcpy(((char *)buf) + n, &high, nBytes);
@@ -56,7 +58,7 @@ size_t RNG_GetNoise(void *buf, size_t maxbuf)
maxbuf -= nBytes;
if (maxbuf <= 0)
- return n;
+ return n;
/* get the number of milliseconds that have elapsed since application started */
val = clock();
@@ -67,7 +69,7 @@ size_t RNG_GetNoise(void *buf, size_t maxbuf)
maxbuf -= nBytes;
if (maxbuf <= 0)
- return n;
+ return n;
/* get the time in seconds since midnight Jan 1, 1970 */
time(&sTime);
@@ -81,54 +83,51 @@ size_t RNG_GetNoise(void *buf, size_t maxbuf)
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);
+ 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, "*.*" );
+ 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 );
+ 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 int dwNumFiles, dwReadEvery, dwFileToRead = 0;
static void
CountFiles(const char *file)
@@ -145,17 +144,17 @@ ReadFiles(const char *file)
dwNumFiles++;
}
-static void
+static void
ReadSingleFile(const char *filename)
{
unsigned char buffer[1024];
- FILE *file;
-
+ FILE *file;
+
file = fopen((char *)filename, "rb");
if (file != NULL) {
- while (fread(buffer, 1, sizeof(buffer), file) > 0)
- ;
- fclose(file);
+ while (fread(buffer, 1, sizeof(buffer), file) > 0)
+ ;
+ fclose(file);
}
}
@@ -185,157 +184,151 @@ ReadSystemFiles(void)
dwReadEvery = dwNumFiles / 10;
if (dwReadEvery == 0)
- dwReadEvery = 1; // less than 10 files
+ dwReadEvery = 1; // less than 10 files
dwNumFiles = 0;
EnumSystemFiles(ReadFiles);
}
-void RNG_SystemInfoForRNG(void)
+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);
+ 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)
+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;
+ return;
+
+ RNG_RandomUpdate((unsigned char *)&stat_buf, sizeof(stat_buf));
- 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);
+ 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);
+ nBytes = RNG_GetNoise(buffer, 20);
RNG_RandomUpdate(buffer, nBytes);
}
-static void rng_systemJitter(void)
+static void
+rng_systemJitter(void)
{
dwNumFiles = 0;
EnumSystemFiles(ReadOneFile);
dwFileToRead++;
if (dwFileToRead >= dwNumFiles) {
- dwFileToRead = 0;
+ dwFileToRead = 0;
}
}
-size_t RNG_SystemRNG(void *dest, size_t maxLen)
+size_t
+RNG_SystemRNG(void *dest, size_t maxLen)
{
- return rng_systemFromNoise(dest,maxLen);
+ return rng_systemFromNoise(dest, maxLen);
}
diff --git a/nss/lib/freebl/poly1305-donna-x64-sse2-incremental-source.c b/nss/lib/freebl/poly1305-donna-x64-sse2-incremental-source.c
new file mode 100644
index 0000000..3c803c1
--- /dev/null
+++ b/nss/lib/freebl/poly1305-donna-x64-sse2-incremental-source.c
@@ -0,0 +1,881 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.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 implementation of poly1305 is by Andrew Moon
+ * (https://github.com/floodyberry/poly1305-donna) and released as public
+ * domain. It implements SIMD vectorization based on the algorithm described in
+ * http://cr.yp.to/papers.html#neoncrypto. Unrolled to 2 powers, i.e. 64 byte
+ * block size. */
+
+#include <emmintrin.h>
+#include <stdint.h>
+
+#include "poly1305.h"
+#include "blapii.h"
+
+#define ALIGN(x) __attribute__((aligned(x)))
+#define INLINE inline
+#define U8TO64_LE(m) (*(uint64_t *)(m))
+#define U8TO32_LE(m) (*(uint32_t *)(m))
+#define U64TO8_LE(m, v) (*(uint64_t *)(m)) = v
+
+typedef __m128i xmmi;
+typedef unsigned __int128 uint128_t;
+
+static const uint32_t ALIGN(16) poly1305_x64_sse2_message_mask[4] = { (1 << 26) - 1, 0, (1 << 26) - 1, 0 };
+static const uint32_t ALIGN(16) poly1305_x64_sse2_5[4] = { 5, 0, 5, 0 };
+static const uint32_t ALIGN(16) poly1305_x64_sse2_1shl128[4] = { (1 << 24), 0, (1 << 24), 0 };
+
+static uint128_t INLINE
+add128(uint128_t a, uint128_t b)
+{
+ return a + b;
+}
+
+static uint128_t INLINE
+add128_64(uint128_t a, uint64_t b)
+{
+ return a + b;
+}
+
+static uint128_t INLINE
+mul64x64_128(uint64_t a, uint64_t b)
+{
+ return (uint128_t)a * b;
+}
+
+static uint64_t INLINE
+lo128(uint128_t a)
+{
+ return (uint64_t)a;
+}
+
+static uint64_t INLINE
+shr128(uint128_t v, const int shift)
+{
+ return (uint64_t)(v >> shift);
+}
+
+static uint64_t INLINE
+shr128_pair(uint64_t hi, uint64_t lo, const int shift)
+{
+ return (uint64_t)((((uint128_t)hi << 64) | lo) >> shift);
+}
+
+typedef struct poly1305_power_t {
+ union {
+ xmmi v;
+ uint64_t u[2];
+ uint32_t d[4];
+ } R20, R21, R22, R23, R24, S21, S22, S23, S24;
+} poly1305_power;
+
+typedef struct poly1305_state_internal_t {
+ poly1305_power P[2]; /* 288 bytes, top 32 bit halves unused = 144 bytes of free storage */
+ union {
+ xmmi H[5]; /* 80 bytes */
+ uint64_t HH[10];
+ };
+ /* uint64_t r0,r1,r2; [24 bytes] */
+ /* uint64_t pad0,pad1; [16 bytes] */
+ uint64_t started; /* 8 bytes */
+ uint64_t leftover; /* 8 bytes */
+ uint8_t buffer[64]; /* 64 bytes */
+} poly1305_state_internal; /* 448 bytes total + 63 bytes for alignment = 511 bytes raw */
+
+static poly1305_state_internal INLINE
+ *
+ poly1305_aligned_state(poly1305_state *state)
+{
+ return (poly1305_state_internal *)(((uint64_t)state + 63) & ~63);
+}
+
+/* copy 0-63 bytes */
+static void INLINE NO_SANITIZE_ALIGNMENT
+poly1305_block_copy(uint8_t *dst, const uint8_t *src, size_t bytes)
+{
+ size_t offset = src - dst;
+ if (bytes & 32) {
+ _mm_storeu_si128((xmmi *)(dst + 0), _mm_loadu_si128((xmmi *)(dst + offset + 0)));
+ _mm_storeu_si128((xmmi *)(dst + 16), _mm_loadu_si128((xmmi *)(dst + offset + 16)));
+ dst += 32;
+ }
+ if (bytes & 16) {
+ _mm_storeu_si128((xmmi *)dst, _mm_loadu_si128((xmmi *)(dst + offset)));
+ dst += 16;
+ }
+ if (bytes & 8) {
+ *(uint64_t *)dst = *(uint64_t *)(dst + offset);
+ dst += 8;
+ }
+ if (bytes & 4) {
+ *(uint32_t *)dst = *(uint32_t *)(dst + offset);
+ dst += 4;
+ }
+ if (bytes & 2) {
+ *(uint16_t *)dst = *(uint16_t *)(dst + offset);
+ dst += 2;
+ }
+ if (bytes & 1) {
+ *(uint8_t *)dst = *(uint8_t *)(dst + offset);
+ }
+}
+
+/* zero 0-15 bytes */
+static void INLINE
+poly1305_block_zero(uint8_t *dst, size_t bytes)
+{
+ if (bytes & 8) {
+ *(uint64_t *)dst = 0;
+ dst += 8;
+ }
+ if (bytes & 4) {
+ *(uint32_t *)dst = 0;
+ dst += 4;
+ }
+ if (bytes & 2) {
+ *(uint16_t *)dst = 0;
+ dst += 2;
+ }
+ if (bytes & 1) {
+ *(uint8_t *)dst = 0;
+ }
+}
+
+static size_t INLINE
+poly1305_min(size_t a, size_t b)
+{
+ return (a < b) ? a : b;
+}
+
+void
+Poly1305Init(poly1305_state *state, const unsigned char key[32])
+{
+ poly1305_state_internal *st = poly1305_aligned_state(state);
+ poly1305_power *p;
+ uint64_t r0, r1, r2;
+ uint64_t t0, t1;
+
+ /* clamp key */
+ t0 = U8TO64_LE(key + 0);
+ t1 = U8TO64_LE(key + 8);
+ r0 = t0 & 0xffc0fffffff;
+ t0 >>= 44;
+ t0 |= t1 << 20;
+ r1 = t0 & 0xfffffc0ffff;
+ t1 >>= 24;
+ r2 = t1 & 0x00ffffffc0f;
+
+ /* store r in un-used space of st->P[1] */
+ p = &st->P[1];
+ p->R20.d[1] = (uint32_t)(r0);
+ p->R20.d[3] = (uint32_t)(r0 >> 32);
+ p->R21.d[1] = (uint32_t)(r1);
+ p->R21.d[3] = (uint32_t)(r1 >> 32);
+ p->R22.d[1] = (uint32_t)(r2);
+ p->R22.d[3] = (uint32_t)(r2 >> 32);
+
+ /* store pad */
+ p->R23.d[1] = U8TO32_LE(key + 16);
+ p->R23.d[3] = U8TO32_LE(key + 20);
+ p->R24.d[1] = U8TO32_LE(key + 24);
+ p->R24.d[3] = U8TO32_LE(key + 28);
+
+ /* H = 0 */
+ st->H[0] = _mm_setzero_si128();
+ st->H[1] = _mm_setzero_si128();
+ st->H[2] = _mm_setzero_si128();
+ st->H[3] = _mm_setzero_si128();
+ st->H[4] = _mm_setzero_si128();
+
+ st->started = 0;
+ st->leftover = 0;
+}
+
+static void
+poly1305_first_block(poly1305_state_internal *st, const uint8_t *m)
+{
+ const xmmi MMASK = _mm_load_si128((xmmi *)poly1305_x64_sse2_message_mask);
+ const xmmi FIVE = _mm_load_si128((xmmi *)poly1305_x64_sse2_5);
+ const xmmi HIBIT = _mm_load_si128((xmmi *)poly1305_x64_sse2_1shl128);
+ xmmi T5, T6;
+ poly1305_power *p;
+ uint128_t d[3];
+ uint64_t r0, r1, r2;
+ uint64_t r20, r21, r22, s22;
+ uint64_t pad0, pad1;
+ uint64_t c;
+ uint64_t i;
+
+ /* pull out stored info */
+ p = &st->P[1];
+
+ r0 = ((uint64_t)p->R20.d[3] << 32) | (uint64_t)p->R20.d[1];
+ r1 = ((uint64_t)p->R21.d[3] << 32) | (uint64_t)p->R21.d[1];
+ r2 = ((uint64_t)p->R22.d[3] << 32) | (uint64_t)p->R22.d[1];
+ pad0 = ((uint64_t)p->R23.d[3] << 32) | (uint64_t)p->R23.d[1];
+ pad1 = ((uint64_t)p->R24.d[3] << 32) | (uint64_t)p->R24.d[1];
+
+ /* compute powers r^2,r^4 */
+ r20 = r0;
+ r21 = r1;
+ r22 = r2;
+ for (i = 0; i < 2; i++) {
+ s22 = r22 * (5 << 2);
+
+ d[0] = add128(mul64x64_128(r20, r20), mul64x64_128(r21 * 2, s22));
+ d[1] = add128(mul64x64_128(r22, s22), mul64x64_128(r20 * 2, r21));
+ d[2] = add128(mul64x64_128(r21, r21), mul64x64_128(r22 * 2, r20));
+
+ r20 = lo128(d[0]) & 0xfffffffffff;
+ c = shr128(d[0], 44);
+ d[1] = add128_64(d[1], c);
+ r21 = lo128(d[1]) & 0xfffffffffff;
+ c = shr128(d[1], 44);
+ d[2] = add128_64(d[2], c);
+ r22 = lo128(d[2]) & 0x3ffffffffff;
+ c = shr128(d[2], 42);
+ r20 += c * 5;
+ c = (r20 >> 44);
+ r20 = r20 & 0xfffffffffff;
+ r21 += c;
+
+ p->R20.v = _mm_shuffle_epi32(_mm_cvtsi32_si128((uint32_t)(r20)&0x3ffffff), _MM_SHUFFLE(1, 0, 1, 0));
+ p->R21.v = _mm_shuffle_epi32(_mm_cvtsi32_si128((uint32_t)((r20 >> 26) | (r21 << 18)) & 0x3ffffff), _MM_SHUFFLE(1, 0, 1, 0));
+ p->R22.v = _mm_shuffle_epi32(_mm_cvtsi32_si128((uint32_t)((r21 >> 8)) & 0x3ffffff), _MM_SHUFFLE(1, 0, 1, 0));
+ p->R23.v = _mm_shuffle_epi32(_mm_cvtsi32_si128((uint32_t)((r21 >> 34) | (r22 << 10)) & 0x3ffffff), _MM_SHUFFLE(1, 0, 1, 0));
+ p->R24.v = _mm_shuffle_epi32(_mm_cvtsi32_si128((uint32_t)((r22 >> 16))), _MM_SHUFFLE(1, 0, 1, 0));
+ p->S21.v = _mm_mul_epu32(p->R21.v, FIVE);
+ p->S22.v = _mm_mul_epu32(p->R22.v, FIVE);
+ p->S23.v = _mm_mul_epu32(p->R23.v, FIVE);
+ p->S24.v = _mm_mul_epu32(p->R24.v, FIVE);
+ p--;
+ }
+
+ /* put saved info back */
+ p = &st->P[1];
+ p->R20.d[1] = (uint32_t)(r0);
+ p->R20.d[3] = (uint32_t)(r0 >> 32);
+ p->R21.d[1] = (uint32_t)(r1);
+ p->R21.d[3] = (uint32_t)(r1 >> 32);
+ p->R22.d[1] = (uint32_t)(r2);
+ p->R22.d[3] = (uint32_t)(r2 >> 32);
+ p->R23.d[1] = (uint32_t)(pad0);
+ p->R23.d[3] = (uint32_t)(pad0 >> 32);
+ p->R24.d[1] = (uint32_t)(pad1);
+ p->R24.d[3] = (uint32_t)(pad1 >> 32);
+
+ /* H = [Mx,My] */
+ T5 = _mm_unpacklo_epi64(_mm_loadl_epi64((xmmi *)(m + 0)), _mm_loadl_epi64((xmmi *)(m + 16)));
+ T6 = _mm_unpacklo_epi64(_mm_loadl_epi64((xmmi *)(m + 8)), _mm_loadl_epi64((xmmi *)(m + 24)));
+ st->H[0] = _mm_and_si128(MMASK, T5);
+ st->H[1] = _mm_and_si128(MMASK, _mm_srli_epi64(T5, 26));
+ T5 = _mm_or_si128(_mm_srli_epi64(T5, 52), _mm_slli_epi64(T6, 12));
+ st->H[2] = _mm_and_si128(MMASK, T5);
+ st->H[3] = _mm_and_si128(MMASK, _mm_srli_epi64(T5, 26));
+ st->H[4] = _mm_or_si128(_mm_srli_epi64(T6, 40), HIBIT);
+}
+
+static void
+poly1305_blocks(poly1305_state_internal *st, const uint8_t *m, size_t bytes)
+{
+ const xmmi MMASK = _mm_load_si128((xmmi *)poly1305_x64_sse2_message_mask);
+ const xmmi FIVE = _mm_load_si128((xmmi *)poly1305_x64_sse2_5);
+ const xmmi HIBIT = _mm_load_si128((xmmi *)poly1305_x64_sse2_1shl128);
+
+ poly1305_power *p;
+ xmmi H0, H1, H2, H3, H4;
+ xmmi T0, T1, T2, T3, T4, T5, T6;
+ xmmi M0, M1, M2, M3, M4;
+ xmmi C1, C2;
+
+ H0 = st->H[0];
+ H1 = st->H[1];
+ H2 = st->H[2];
+ H3 = st->H[3];
+ H4 = st->H[4];
+
+ while (bytes >= 64) {
+ /* H *= [r^4,r^4] */
+ p = &st->P[0];
+ T0 = _mm_mul_epu32(H0, p->R20.v);
+ T1 = _mm_mul_epu32(H0, p->R21.v);
+ T2 = _mm_mul_epu32(H0, p->R22.v);
+ T3 = _mm_mul_epu32(H0, p->R23.v);
+ T4 = _mm_mul_epu32(H0, p->R24.v);
+ T5 = _mm_mul_epu32(H1, p->S24.v);
+ T6 = _mm_mul_epu32(H1, p->R20.v);
+ T0 = _mm_add_epi64(T0, T5);
+ T1 = _mm_add_epi64(T1, T6);
+ T5 = _mm_mul_epu32(H2, p->S23.v);
+ T6 = _mm_mul_epu32(H2, p->S24.v);
+ T0 = _mm_add_epi64(T0, T5);
+ T1 = _mm_add_epi64(T1, T6);
+ T5 = _mm_mul_epu32(H3, p->S22.v);
+ T6 = _mm_mul_epu32(H3, p->S23.v);
+ T0 = _mm_add_epi64(T0, T5);
+ T1 = _mm_add_epi64(T1, T6);
+ T5 = _mm_mul_epu32(H4, p->S21.v);
+ T6 = _mm_mul_epu32(H4, p->S22.v);
+ T0 = _mm_add_epi64(T0, T5);
+ T1 = _mm_add_epi64(T1, T6);
+ T5 = _mm_mul_epu32(H1, p->R21.v);
+ T6 = _mm_mul_epu32(H1, p->R22.v);
+ T2 = _mm_add_epi64(T2, T5);
+ T3 = _mm_add_epi64(T3, T6);
+ T5 = _mm_mul_epu32(H2, p->R20.v);
+ T6 = _mm_mul_epu32(H2, p->R21.v);
+ T2 = _mm_add_epi64(T2, T5);
+ T3 = _mm_add_epi64(T3, T6);
+ T5 = _mm_mul_epu32(H3, p->S24.v);
+ T6 = _mm_mul_epu32(H3, p->R20.v);
+ T2 = _mm_add_epi64(T2, T5);
+ T3 = _mm_add_epi64(T3, T6);
+ T5 = _mm_mul_epu32(H4, p->S23.v);
+ T6 = _mm_mul_epu32(H4, p->S24.v);
+ T2 = _mm_add_epi64(T2, T5);
+ T3 = _mm_add_epi64(T3, T6);
+ T5 = _mm_mul_epu32(H1, p->R23.v);
+ T4 = _mm_add_epi64(T4, T5);
+ T5 = _mm_mul_epu32(H2, p->R22.v);
+ T4 = _mm_add_epi64(T4, T5);
+ T5 = _mm_mul_epu32(H3, p->R21.v);
+ T4 = _mm_add_epi64(T4, T5);
+ T5 = _mm_mul_epu32(H4, p->R20.v);
+ T4 = _mm_add_epi64(T4, T5);
+
+ /* H += [Mx,My]*[r^2,r^2] */
+ T5 = _mm_unpacklo_epi64(_mm_loadl_epi64((xmmi *)(m + 0)), _mm_loadl_epi64((xmmi *)(m + 16)));
+ T6 = _mm_unpacklo_epi64(_mm_loadl_epi64((xmmi *)(m + 8)), _mm_loadl_epi64((xmmi *)(m + 24)));
+ M0 = _mm_and_si128(MMASK, T5);
+ M1 = _mm_and_si128(MMASK, _mm_srli_epi64(T5, 26));
+ T5 = _mm_or_si128(_mm_srli_epi64(T5, 52), _mm_slli_epi64(T6, 12));
+ M2 = _mm_and_si128(MMASK, T5);
+ M3 = _mm_and_si128(MMASK, _mm_srli_epi64(T5, 26));
+ M4 = _mm_or_si128(_mm_srli_epi64(T6, 40), HIBIT);
+
+ p = &st->P[1];
+ T5 = _mm_mul_epu32(M0, p->R20.v);
+ T6 = _mm_mul_epu32(M0, p->R21.v);
+ T0 = _mm_add_epi64(T0, T5);
+ T1 = _mm_add_epi64(T1, T6);
+ T5 = _mm_mul_epu32(M1, p->S24.v);
+ T6 = _mm_mul_epu32(M1, p->R20.v);
+ T0 = _mm_add_epi64(T0, T5);
+ T1 = _mm_add_epi64(T1, T6);
+ T5 = _mm_mul_epu32(M2, p->S23.v);
+ T6 = _mm_mul_epu32(M2, p->S24.v);
+ T0 = _mm_add_epi64(T0, T5);
+ T1 = _mm_add_epi64(T1, T6);
+ T5 = _mm_mul_epu32(M3, p->S22.v);
+ T6 = _mm_mul_epu32(M3, p->S23.v);
+ T0 = _mm_add_epi64(T0, T5);
+ T1 = _mm_add_epi64(T1, T6);
+ T5 = _mm_mul_epu32(M4, p->S21.v);
+ T6 = _mm_mul_epu32(M4, p->S22.v);
+ T0 = _mm_add_epi64(T0, T5);
+ T1 = _mm_add_epi64(T1, T6);
+ T5 = _mm_mul_epu32(M0, p->R22.v);
+ T6 = _mm_mul_epu32(M0, p->R23.v);
+ T2 = _mm_add_epi64(T2, T5);
+ T3 = _mm_add_epi64(T3, T6);
+ T5 = _mm_mul_epu32(M1, p->R21.v);
+ T6 = _mm_mul_epu32(M1, p->R22.v);
+ T2 = _mm_add_epi64(T2, T5);
+ T3 = _mm_add_epi64(T3, T6);
+ T5 = _mm_mul_epu32(M2, p->R20.v);
+ T6 = _mm_mul_epu32(M2, p->R21.v);
+ T2 = _mm_add_epi64(T2, T5);
+ T3 = _mm_add_epi64(T3, T6);
+ T5 = _mm_mul_epu32(M3, p->S24.v);
+ T6 = _mm_mul_epu32(M3, p->R20.v);
+ T2 = _mm_add_epi64(T2, T5);
+ T3 = _mm_add_epi64(T3, T6);
+ T5 = _mm_mul_epu32(M4, p->S23.v);
+ T6 = _mm_mul_epu32(M4, p->S24.v);
+ T2 = _mm_add_epi64(T2, T5);
+ T3 = _mm_add_epi64(T3, T6);
+ T5 = _mm_mul_epu32(M0, p->R24.v);
+ T4 = _mm_add_epi64(T4, T5);
+ T5 = _mm_mul_epu32(M1, p->R23.v);
+ T4 = _mm_add_epi64(T4, T5);
+ T5 = _mm_mul_epu32(M2, p->R22.v);
+ T4 = _mm_add_epi64(T4, T5);
+ T5 = _mm_mul_epu32(M3, p->R21.v);
+ T4 = _mm_add_epi64(T4, T5);
+ T5 = _mm_mul_epu32(M4, p->R20.v);
+ T4 = _mm_add_epi64(T4, T5);
+
+ /* H += [Mx,My] */
+ T5 = _mm_unpacklo_epi64(_mm_loadl_epi64((xmmi *)(m + 32)), _mm_loadl_epi64((xmmi *)(m + 48)));
+ T6 = _mm_unpacklo_epi64(_mm_loadl_epi64((xmmi *)(m + 40)), _mm_loadl_epi64((xmmi *)(m + 56)));
+ M0 = _mm_and_si128(MMASK, T5);
+ M1 = _mm_and_si128(MMASK, _mm_srli_epi64(T5, 26));
+ T5 = _mm_or_si128(_mm_srli_epi64(T5, 52), _mm_slli_epi64(T6, 12));
+ M2 = _mm_and_si128(MMASK, T5);
+ M3 = _mm_and_si128(MMASK, _mm_srli_epi64(T5, 26));
+ M4 = _mm_or_si128(_mm_srli_epi64(T6, 40), HIBIT);
+
+ T0 = _mm_add_epi64(T0, M0);
+ T1 = _mm_add_epi64(T1, M1);
+ T2 = _mm_add_epi64(T2, M2);
+ T3 = _mm_add_epi64(T3, M3);
+ T4 = _mm_add_epi64(T4, M4);
+
+ /* reduce */
+ C1 = _mm_srli_epi64(T0, 26);
+ C2 = _mm_srli_epi64(T3, 26);
+ T0 = _mm_and_si128(T0, MMASK);
+ T3 = _mm_and_si128(T3, MMASK);
+ T1 = _mm_add_epi64(T1, C1);
+ T4 = _mm_add_epi64(T4, C2);
+ C1 = _mm_srli_epi64(T1, 26);
+ C2 = _mm_srli_epi64(T4, 26);
+ T1 = _mm_and_si128(T1, MMASK);
+ T4 = _mm_and_si128(T4, MMASK);
+ T2 = _mm_add_epi64(T2, C1);
+ T0 = _mm_add_epi64(T0, _mm_mul_epu32(C2, FIVE));
+ C1 = _mm_srli_epi64(T2, 26);
+ C2 = _mm_srli_epi64(T0, 26);
+ T2 = _mm_and_si128(T2, MMASK);
+ T0 = _mm_and_si128(T0, MMASK);
+ T3 = _mm_add_epi64(T3, C1);
+ T1 = _mm_add_epi64(T1, C2);
+ C1 = _mm_srli_epi64(T3, 26);
+ T3 = _mm_and_si128(T3, MMASK);
+ T4 = _mm_add_epi64(T4, C1);
+
+ /* H = (H*[r^4,r^4] + [Mx,My]*[r^2,r^2] + [Mx,My]) */
+ H0 = T0;
+ H1 = T1;
+ H2 = T2;
+ H3 = T3;
+ H4 = T4;
+
+ m += 64;
+ bytes -= 64;
+ }
+
+ st->H[0] = H0;
+ st->H[1] = H1;
+ st->H[2] = H2;
+ st->H[3] = H3;
+ st->H[4] = H4;
+}
+
+static size_t
+poly1305_combine(poly1305_state_internal *st, const uint8_t *m, size_t bytes)
+{
+ const xmmi MMASK = _mm_load_si128((xmmi *)poly1305_x64_sse2_message_mask);
+ const xmmi HIBIT = _mm_load_si128((xmmi *)poly1305_x64_sse2_1shl128);
+ const xmmi FIVE = _mm_load_si128((xmmi *)poly1305_x64_sse2_5);
+
+ poly1305_power *p;
+ xmmi H0, H1, H2, H3, H4;
+ xmmi M0, M1, M2, M3, M4;
+ xmmi T0, T1, T2, T3, T4, T5, T6;
+ xmmi C1, C2;
+
+ uint64_t r0, r1, r2;
+ uint64_t t0, t1, t2, t3, t4;
+ uint64_t c;
+ size_t consumed = 0;
+
+ H0 = st->H[0];
+ H1 = st->H[1];
+ H2 = st->H[2];
+ H3 = st->H[3];
+ H4 = st->H[4];
+
+ /* p = [r^2,r^2] */
+ p = &st->P[1];
+
+ if (bytes >= 32) {
+ /* H *= [r^2,r^2] */
+ T0 = _mm_mul_epu32(H0, p->R20.v);
+ T1 = _mm_mul_epu32(H0, p->R21.v);
+ T2 = _mm_mul_epu32(H0, p->R22.v);
+ T3 = _mm_mul_epu32(H0, p->R23.v);
+ T4 = _mm_mul_epu32(H0, p->R24.v);
+ T5 = _mm_mul_epu32(H1, p->S24.v);
+ T6 = _mm_mul_epu32(H1, p->R20.v);
+ T0 = _mm_add_epi64(T0, T5);
+ T1 = _mm_add_epi64(T1, T6);
+ T5 = _mm_mul_epu32(H2, p->S23.v);
+ T6 = _mm_mul_epu32(H2, p->S24.v);
+ T0 = _mm_add_epi64(T0, T5);
+ T1 = _mm_add_epi64(T1, T6);
+ T5 = _mm_mul_epu32(H3, p->S22.v);
+ T6 = _mm_mul_epu32(H3, p->S23.v);
+ T0 = _mm_add_epi64(T0, T5);
+ T1 = _mm_add_epi64(T1, T6);
+ T5 = _mm_mul_epu32(H4, p->S21.v);
+ T6 = _mm_mul_epu32(H4, p->S22.v);
+ T0 = _mm_add_epi64(T0, T5);
+ T1 = _mm_add_epi64(T1, T6);
+ T5 = _mm_mul_epu32(H1, p->R21.v);
+ T6 = _mm_mul_epu32(H1, p->R22.v);
+ T2 = _mm_add_epi64(T2, T5);
+ T3 = _mm_add_epi64(T3, T6);
+ T5 = _mm_mul_epu32(H2, p->R20.v);
+ T6 = _mm_mul_epu32(H2, p->R21.v);
+ T2 = _mm_add_epi64(T2, T5);
+ T3 = _mm_add_epi64(T3, T6);
+ T5 = _mm_mul_epu32(H3, p->S24.v);
+ T6 = _mm_mul_epu32(H3, p->R20.v);
+ T2 = _mm_add_epi64(T2, T5);
+ T3 = _mm_add_epi64(T3, T6);
+ T5 = _mm_mul_epu32(H4, p->S23.v);
+ T6 = _mm_mul_epu32(H4, p->S24.v);
+ T2 = _mm_add_epi64(T2, T5);
+ T3 = _mm_add_epi64(T3, T6);
+ T5 = _mm_mul_epu32(H1, p->R23.v);
+ T4 = _mm_add_epi64(T4, T5);
+ T5 = _mm_mul_epu32(H2, p->R22.v);
+ T4 = _mm_add_epi64(T4, T5);
+ T5 = _mm_mul_epu32(H3, p->R21.v);
+ T4 = _mm_add_epi64(T4, T5);
+ T5 = _mm_mul_epu32(H4, p->R20.v);
+ T4 = _mm_add_epi64(T4, T5);
+
+ /* H += [Mx,My] */
+ T5 = _mm_unpacklo_epi64(_mm_loadl_epi64((xmmi *)(m + 0)), _mm_loadl_epi64((xmmi *)(m + 16)));
+ T6 = _mm_unpacklo_epi64(_mm_loadl_epi64((xmmi *)(m + 8)), _mm_loadl_epi64((xmmi *)(m + 24)));
+ M0 = _mm_and_si128(MMASK, T5);
+ M1 = _mm_and_si128(MMASK, _mm_srli_epi64(T5, 26));
+ T5 = _mm_or_si128(_mm_srli_epi64(T5, 52), _mm_slli_epi64(T6, 12));
+ M2 = _mm_and_si128(MMASK, T5);
+ M3 = _mm_and_si128(MMASK, _mm_srli_epi64(T5, 26));
+ M4 = _mm_or_si128(_mm_srli_epi64(T6, 40), HIBIT);
+
+ T0 = _mm_add_epi64(T0, M0);
+ T1 = _mm_add_epi64(T1, M1);
+ T2 = _mm_add_epi64(T2, M2);
+ T3 = _mm_add_epi64(T3, M3);
+ T4 = _mm_add_epi64(T4, M4);
+
+ /* reduce */
+ C1 = _mm_srli_epi64(T0, 26);
+ C2 = _mm_srli_epi64(T3, 26);
+ T0 = _mm_and_si128(T0, MMASK);
+ T3 = _mm_and_si128(T3, MMASK);
+ T1 = _mm_add_epi64(T1, C1);
+ T4 = _mm_add_epi64(T4, C2);
+ C1 = _mm_srli_epi64(T1, 26);
+ C2 = _mm_srli_epi64(T4, 26);
+ T1 = _mm_and_si128(T1, MMASK);
+ T4 = _mm_and_si128(T4, MMASK);
+ T2 = _mm_add_epi64(T2, C1);
+ T0 = _mm_add_epi64(T0, _mm_mul_epu32(C2, FIVE));
+ C1 = _mm_srli_epi64(T2, 26);
+ C2 = _mm_srli_epi64(T0, 26);
+ T2 = _mm_and_si128(T2, MMASK);
+ T0 = _mm_and_si128(T0, MMASK);
+ T3 = _mm_add_epi64(T3, C1);
+ T1 = _mm_add_epi64(T1, C2);
+ C1 = _mm_srli_epi64(T3, 26);
+ T3 = _mm_and_si128(T3, MMASK);
+ T4 = _mm_add_epi64(T4, C1);
+
+ /* H = (H*[r^2,r^2] + [Mx,My]) */
+ H0 = T0;
+ H1 = T1;
+ H2 = T2;
+ H3 = T3;
+ H4 = T4;
+
+ consumed = 32;
+ }
+
+ /* finalize, H *= [r^2,r] */
+ r0 = ((uint64_t)p->R20.d[3] << 32) | (uint64_t)p->R20.d[1];
+ r1 = ((uint64_t)p->R21.d[3] << 32) | (uint64_t)p->R21.d[1];
+ r2 = ((uint64_t)p->R22.d[3] << 32) | (uint64_t)p->R22.d[1];
+
+ p->R20.d[2] = (uint32_t)(r0)&0x3ffffff;
+ p->R21.d[2] = (uint32_t)((r0 >> 26) | (r1 << 18)) & 0x3ffffff;
+ p->R22.d[2] = (uint32_t)((r1 >> 8)) & 0x3ffffff;
+ p->R23.d[2] = (uint32_t)((r1 >> 34) | (r2 << 10)) & 0x3ffffff;
+ p->R24.d[2] = (uint32_t)((r2 >> 16));
+ p->S21.d[2] = p->R21.d[2] * 5;
+ p->S22.d[2] = p->R22.d[2] * 5;
+ p->S23.d[2] = p->R23.d[2] * 5;
+ p->S24.d[2] = p->R24.d[2] * 5;
+
+ /* H *= [r^2,r] */
+ T0 = _mm_mul_epu32(H0, p->R20.v);
+ T1 = _mm_mul_epu32(H0, p->R21.v);
+ T2 = _mm_mul_epu32(H0, p->R22.v);
+ T3 = _mm_mul_epu32(H0, p->R23.v);
+ T4 = _mm_mul_epu32(H0, p->R24.v);
+ T5 = _mm_mul_epu32(H1, p->S24.v);
+ T6 = _mm_mul_epu32(H1, p->R20.v);
+ T0 = _mm_add_epi64(T0, T5);
+ T1 = _mm_add_epi64(T1, T6);
+ T5 = _mm_mul_epu32(H2, p->S23.v);
+ T6 = _mm_mul_epu32(H2, p->S24.v);
+ T0 = _mm_add_epi64(T0, T5);
+ T1 = _mm_add_epi64(T1, T6);
+ T5 = _mm_mul_epu32(H3, p->S22.v);
+ T6 = _mm_mul_epu32(H3, p->S23.v);
+ T0 = _mm_add_epi64(T0, T5);
+ T1 = _mm_add_epi64(T1, T6);
+ T5 = _mm_mul_epu32(H4, p->S21.v);
+ T6 = _mm_mul_epu32(H4, p->S22.v);
+ T0 = _mm_add_epi64(T0, T5);
+ T1 = _mm_add_epi64(T1, T6);
+ T5 = _mm_mul_epu32(H1, p->R21.v);
+ T6 = _mm_mul_epu32(H1, p->R22.v);
+ T2 = _mm_add_epi64(T2, T5);
+ T3 = _mm_add_epi64(T3, T6);
+ T5 = _mm_mul_epu32(H2, p->R20.v);
+ T6 = _mm_mul_epu32(H2, p->R21.v);
+ T2 = _mm_add_epi64(T2, T5);
+ T3 = _mm_add_epi64(T3, T6);
+ T5 = _mm_mul_epu32(H3, p->S24.v);
+ T6 = _mm_mul_epu32(H3, p->R20.v);
+ T2 = _mm_add_epi64(T2, T5);
+ T3 = _mm_add_epi64(T3, T6);
+ T5 = _mm_mul_epu32(H4, p->S23.v);
+ T6 = _mm_mul_epu32(H4, p->S24.v);
+ T2 = _mm_add_epi64(T2, T5);
+ T3 = _mm_add_epi64(T3, T6);
+ T5 = _mm_mul_epu32(H1, p->R23.v);
+ T4 = _mm_add_epi64(T4, T5);
+ T5 = _mm_mul_epu32(H2, p->R22.v);
+ T4 = _mm_add_epi64(T4, T5);
+ T5 = _mm_mul_epu32(H3, p->R21.v);
+ T4 = _mm_add_epi64(T4, T5);
+ T5 = _mm_mul_epu32(H4, p->R20.v);
+ T4 = _mm_add_epi64(T4, T5);
+
+ C1 = _mm_srli_epi64(T0, 26);
+ C2 = _mm_srli_epi64(T3, 26);
+ T0 = _mm_and_si128(T0, MMASK);
+ T3 = _mm_and_si128(T3, MMASK);
+ T1 = _mm_add_epi64(T1, C1);
+ T4 = _mm_add_epi64(T4, C2);
+ C1 = _mm_srli_epi64(T1, 26);
+ C2 = _mm_srli_epi64(T4, 26);
+ T1 = _mm_and_si128(T1, MMASK);
+ T4 = _mm_and_si128(T4, MMASK);
+ T2 = _mm_add_epi64(T2, C1);
+ T0 = _mm_add_epi64(T0, _mm_mul_epu32(C2, FIVE));
+ C1 = _mm_srli_epi64(T2, 26);
+ C2 = _mm_srli_epi64(T0, 26);
+ T2 = _mm_and_si128(T2, MMASK);
+ T0 = _mm_and_si128(T0, MMASK);
+ T3 = _mm_add_epi64(T3, C1);
+ T1 = _mm_add_epi64(T1, C2);
+ C1 = _mm_srli_epi64(T3, 26);
+ T3 = _mm_and_si128(T3, MMASK);
+ T4 = _mm_add_epi64(T4, C1);
+
+ /* H = H[0]+H[1] */
+ H0 = _mm_add_epi64(T0, _mm_srli_si128(T0, 8));
+ H1 = _mm_add_epi64(T1, _mm_srli_si128(T1, 8));
+ H2 = _mm_add_epi64(T2, _mm_srli_si128(T2, 8));
+ H3 = _mm_add_epi64(T3, _mm_srli_si128(T3, 8));
+ H4 = _mm_add_epi64(T4, _mm_srli_si128(T4, 8));
+
+ t0 = _mm_cvtsi128_si32(H0);
+ c = (t0 >> 26);
+ t0 &= 0x3ffffff;
+ t1 = _mm_cvtsi128_si32(H1) + c;
+ c = (t1 >> 26);
+ t1 &= 0x3ffffff;
+ t2 = _mm_cvtsi128_si32(H2) + c;
+ c = (t2 >> 26);
+ t2 &= 0x3ffffff;
+ t3 = _mm_cvtsi128_si32(H3) + c;
+ c = (t3 >> 26);
+ t3 &= 0x3ffffff;
+ t4 = _mm_cvtsi128_si32(H4) + c;
+ c = (t4 >> 26);
+ t4 &= 0x3ffffff;
+ t0 = t0 + (c * 5);
+ c = (t0 >> 26);
+ t0 &= 0x3ffffff;
+ t1 = t1 + c;
+
+ st->HH[0] = ((t0) | (t1 << 26)) & 0xfffffffffffull;
+ st->HH[1] = ((t1 >> 18) | (t2 << 8) | (t3 << 34)) & 0xfffffffffffull;
+ st->HH[2] = ((t3 >> 10) | (t4 << 16)) & 0x3ffffffffffull;
+
+ return consumed;
+}
+
+void
+Poly1305Update(poly1305_state *state, const unsigned char *m, size_t bytes)
+{
+ poly1305_state_internal *st = poly1305_aligned_state(state);
+ size_t want;
+
+ /* need at least 32 initial bytes to start the accelerated branch */
+ if (!st->started) {
+ if ((st->leftover == 0) && (bytes > 32)) {
+ poly1305_first_block(st, m);
+ m += 32;
+ bytes -= 32;
+ } else {
+ want = poly1305_min(32 - st->leftover, bytes);
+ poly1305_block_copy(st->buffer + st->leftover, m, want);
+ bytes -= want;
+ m += want;
+ st->leftover += want;
+ if ((st->leftover < 32) || (bytes == 0))
+ return;
+ poly1305_first_block(st, st->buffer);
+ st->leftover = 0;
+ }
+ st->started = 1;
+ }
+
+ /* handle leftover */
+ if (st->leftover) {
+ want = poly1305_min(64 - st->leftover, bytes);
+ poly1305_block_copy(st->buffer + st->leftover, m, want);
+ bytes -= want;
+ m += want;
+ st->leftover += want;
+ if (st->leftover < 64)
+ return;
+ poly1305_blocks(st, st->buffer, 64);
+ st->leftover = 0;
+ }
+
+ /* process 64 byte blocks */
+ if (bytes >= 64) {
+ want = (bytes & ~63);
+ poly1305_blocks(st, m, want);
+ m += want;
+ bytes -= want;
+ }
+
+ if (bytes) {
+ poly1305_block_copy(st->buffer + st->leftover, m, bytes);
+ st->leftover += bytes;
+ }
+}
+
+void
+Poly1305Finish(poly1305_state *state, unsigned char mac[16])
+{
+ poly1305_state_internal *st = poly1305_aligned_state(state);
+ size_t leftover = st->leftover;
+ uint8_t *m = st->buffer;
+ uint128_t d[3];
+ uint64_t h0, h1, h2;
+ uint64_t t0, t1;
+ uint64_t g0, g1, g2, c, nc;
+ uint64_t r0, r1, r2, s1, s2;
+ poly1305_power *p;
+
+ if (st->started) {
+ size_t consumed = poly1305_combine(st, m, leftover);
+ leftover -= consumed;
+ m += consumed;
+ }
+
+ /* st->HH will either be 0 or have the combined result */
+ h0 = st->HH[0];
+ h1 = st->HH[1];
+ h2 = st->HH[2];
+
+ p = &st->P[1];
+ r0 = ((uint64_t)p->R20.d[3] << 32) | (uint64_t)p->R20.d[1];
+ r1 = ((uint64_t)p->R21.d[3] << 32) | (uint64_t)p->R21.d[1];
+ r2 = ((uint64_t)p->R22.d[3] << 32) | (uint64_t)p->R22.d[1];
+ s1 = r1 * (5 << 2);
+ s2 = r2 * (5 << 2);
+
+ if (leftover < 16)
+ goto poly1305_donna_atmost15bytes;
+
+poly1305_donna_atleast16bytes:
+ t0 = U8TO64_LE(m + 0);
+ t1 = U8TO64_LE(m + 8);
+ h0 += t0 & 0xfffffffffff;
+ t0 = shr128_pair(t1, t0, 44);
+ h1 += t0 & 0xfffffffffff;
+ h2 += (t1 >> 24) | ((uint64_t)1 << 40);
+
+poly1305_donna_mul:
+ d[0] = add128(add128(mul64x64_128(h0, r0), mul64x64_128(h1, s2)), mul64x64_128(h2, s1));
+ d[1] = add128(add128(mul64x64_128(h0, r1), mul64x64_128(h1, r0)), mul64x64_128(h2, s2));
+ d[2] = add128(add128(mul64x64_128(h0, r2), mul64x64_128(h1, r1)), mul64x64_128(h2, r0));
+ h0 = lo128(d[0]) & 0xfffffffffff;
+ c = shr128(d[0], 44);
+ d[1] = add128_64(d[1], c);
+ h1 = lo128(d[1]) & 0xfffffffffff;
+ c = shr128(d[1], 44);
+ d[2] = add128_64(d[2], c);
+ h2 = lo128(d[2]) & 0x3ffffffffff;
+ c = shr128(d[2], 42);
+ h0 += c * 5;
+
+ m += 16;
+ leftover -= 16;
+ if (leftover >= 16)
+ goto poly1305_donna_atleast16bytes;
+
+/* final bytes */
+poly1305_donna_atmost15bytes:
+ if (!leftover)
+ goto poly1305_donna_finish;
+
+ m[leftover++] = 1;
+ poly1305_block_zero(m + leftover, 16 - leftover);
+ leftover = 16;
+
+ t0 = U8TO64_LE(m + 0);
+ t1 = U8TO64_LE(m + 8);
+ h0 += t0 & 0xfffffffffff;
+ t0 = shr128_pair(t1, t0, 44);
+ h1 += t0 & 0xfffffffffff;
+ h2 += (t1 >> 24);
+
+ goto poly1305_donna_mul;
+
+poly1305_donna_finish:
+ c = (h0 >> 44);
+ h0 &= 0xfffffffffff;
+ h1 += c;
+ c = (h1 >> 44);
+ h1 &= 0xfffffffffff;
+ h2 += c;
+ c = (h2 >> 42);
+ h2 &= 0x3ffffffffff;
+ h0 += c * 5;
+
+ g0 = h0 + 5;
+ c = (g0 >> 44);
+ g0 &= 0xfffffffffff;
+ g1 = h1 + c;
+ c = (g1 >> 44);
+ g1 &= 0xfffffffffff;
+ g2 = h2 + c - ((uint64_t)1 << 42);
+
+ c = (g2 >> 63) - 1;
+ nc = ~c;
+ h0 = (h0 & nc) | (g0 & c);
+ h1 = (h1 & nc) | (g1 & c);
+ h2 = (h2 & nc) | (g2 & c);
+
+ /* pad */
+ t0 = ((uint64_t)p->R23.d[3] << 32) | (uint64_t)p->R23.d[1];
+ t1 = ((uint64_t)p->R24.d[3] << 32) | (uint64_t)p->R24.d[1];
+ h0 += (t0 & 0xfffffffffff);
+ c = (h0 >> 44);
+ h0 &= 0xfffffffffff;
+ t0 = shr128_pair(t1, t0, 44);
+ h1 += (t0 & 0xfffffffffff) + c;
+ c = (h1 >> 44);
+ h1 &= 0xfffffffffff;
+ t1 = (t1 >> 24);
+ h2 += (t1) + c;
+
+ U64TO8_LE(mac + 0, ((h0) | (h1 << 44)));
+ U64TO8_LE(mac + 8, ((h1 >> 20) | (h2 << 24)));
+}
diff --git a/nss/lib/freebl/poly1305.c b/nss/lib/freebl/poly1305.c
new file mode 100644
index 0000000..eb3e3cd
--- /dev/null
+++ b/nss/lib/freebl/poly1305.c
@@ -0,0 +1,314 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.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 implementation of poly1305 is by Andrew Moon
+ * (https://github.com/floodyberry/poly1305-donna) and released as public
+ * domain. */
+
+#include <string.h>
+
+#include "poly1305.h"
+
+#if defined(_MSC_VER) && _MSC_VER < 1600
+#include "prtypes.h"
+typedef PRUint32 uint32_t;
+typedef PRUint64 uint64_t;
+#else
+#include <stdint.h>
+#endif
+
+#if defined(NSS_X86) || defined(NSS_X64)
+/* We can assume little-endian. */
+static uint32_t
+U8TO32_LE(const unsigned char *m)
+{
+ uint32_t r;
+ memcpy(&r, m, sizeof(r));
+ return r;
+}
+
+static void
+U32TO8_LE(unsigned char *m, uint32_t v)
+{
+ memcpy(m, &v, sizeof(v));
+}
+#else
+static uint32_t
+U8TO32_LE(const unsigned char *m)
+{
+ return (uint32_t)m[0] |
+ (uint32_t)m[1] << 8 |
+ (uint32_t)m[2] << 16 |
+ (uint32_t)m[3] << 24;
+}
+
+static void
+U32TO8_LE(unsigned char *m, uint32_t v)
+{
+ m[0] = v;
+ m[1] = v >> 8;
+ m[2] = v >> 16;
+ m[3] = v >> 24;
+}
+#endif
+
+static uint64_t
+mul32x32_64(uint32_t a, uint32_t b)
+{
+ return (uint64_t)a * b;
+}
+
+struct poly1305_state_st {
+ uint32_t r0, r1, r2, r3, r4;
+ uint32_t s1, s2, s3, s4;
+ uint32_t h0, h1, h2, h3, h4;
+ unsigned char buf[16];
+ unsigned int buf_used;
+ unsigned char key[16];
+};
+
+/* update updates |state| given some amount of input data. This function may
+ * only be called with a |len| that is not a multiple of 16 at the end of the
+ * data. Otherwise the input must be buffered into 16 byte blocks. */
+static void
+update(struct poly1305_state_st *state, const unsigned char *in,
+ size_t len)
+{
+ uint32_t t0, t1, t2, t3;
+ uint64_t t[5];
+ uint32_t b;
+ uint64_t c;
+ size_t j;
+ unsigned char mp[16];
+
+ if (len < 16)
+ goto poly1305_donna_atmost15bytes;
+
+poly1305_donna_16bytes:
+ t0 = U8TO32_LE(in);
+ t1 = U8TO32_LE(in + 4);
+ t2 = U8TO32_LE(in + 8);
+ t3 = U8TO32_LE(in + 12);
+
+ in += 16;
+ len -= 16;
+
+ state->h0 += t0 & 0x3ffffff;
+ state->h1 += ((((uint64_t)t1 << 32) | t0) >> 26) & 0x3ffffff;
+ state->h2 += ((((uint64_t)t2 << 32) | t1) >> 20) & 0x3ffffff;
+ state->h3 += ((((uint64_t)t3 << 32) | t2) >> 14) & 0x3ffffff;
+ state->h4 += (t3 >> 8) | (1 << 24);
+
+poly1305_donna_mul:
+ t[0] = mul32x32_64(state->h0, state->r0) +
+ mul32x32_64(state->h1, state->s4) +
+ mul32x32_64(state->h2, state->s3) +
+ mul32x32_64(state->h3, state->s2) +
+ mul32x32_64(state->h4, state->s1);
+ t[1] = mul32x32_64(state->h0, state->r1) +
+ mul32x32_64(state->h1, state->r0) +
+ mul32x32_64(state->h2, state->s4) +
+ mul32x32_64(state->h3, state->s3) +
+ mul32x32_64(state->h4, state->s2);
+ t[2] = mul32x32_64(state->h0, state->r2) +
+ mul32x32_64(state->h1, state->r1) +
+ mul32x32_64(state->h2, state->r0) +
+ mul32x32_64(state->h3, state->s4) +
+ mul32x32_64(state->h4, state->s3);
+ t[3] = mul32x32_64(state->h0, state->r3) +
+ mul32x32_64(state->h1, state->r2) +
+ mul32x32_64(state->h2, state->r1) +
+ mul32x32_64(state->h3, state->r0) +
+ mul32x32_64(state->h4, state->s4);
+ t[4] = mul32x32_64(state->h0, state->r4) +
+ mul32x32_64(state->h1, state->r3) +
+ mul32x32_64(state->h2, state->r2) +
+ mul32x32_64(state->h3, state->r1) +
+ mul32x32_64(state->h4, state->r0);
+
+ state->h0 = (uint32_t)t[0] & 0x3ffffff;
+ c = (t[0] >> 26);
+ t[1] += c;
+ state->h1 = (uint32_t)t[1] & 0x3ffffff;
+ b = (uint32_t)(t[1] >> 26);
+ t[2] += b;
+ state->h2 = (uint32_t)t[2] & 0x3ffffff;
+ b = (uint32_t)(t[2] >> 26);
+ t[3] += b;
+ state->h3 = (uint32_t)t[3] & 0x3ffffff;
+ b = (uint32_t)(t[3] >> 26);
+ t[4] += b;
+ state->h4 = (uint32_t)t[4] & 0x3ffffff;
+ b = (uint32_t)(t[4] >> 26);
+ state->h0 += b * 5;
+
+ if (len >= 16)
+ goto poly1305_donna_16bytes;
+
+/* final bytes */
+poly1305_donna_atmost15bytes:
+ if (!len)
+ return;
+
+ for (j = 0; j < len; j++)
+ mp[j] = in[j];
+ mp[j++] = 1;
+ for (; j < 16; j++)
+ mp[j] = 0;
+ len = 0;
+
+ t0 = U8TO32_LE(mp + 0);
+ t1 = U8TO32_LE(mp + 4);
+ t2 = U8TO32_LE(mp + 8);
+ t3 = U8TO32_LE(mp + 12);
+
+ state->h0 += t0 & 0x3ffffff;
+ state->h1 += ((((uint64_t)t1 << 32) | t0) >> 26) & 0x3ffffff;
+ state->h2 += ((((uint64_t)t2 << 32) | t1) >> 20) & 0x3ffffff;
+ state->h3 += ((((uint64_t)t3 << 32) | t2) >> 14) & 0x3ffffff;
+ state->h4 += (t3 >> 8);
+
+ goto poly1305_donna_mul;
+}
+
+void
+Poly1305Init(poly1305_state *statep, const unsigned char key[32])
+{
+ struct poly1305_state_st *state = (struct poly1305_state_st *)statep;
+ uint32_t t0, t1, t2, t3;
+
+ t0 = U8TO32_LE(key + 0);
+ t1 = U8TO32_LE(key + 4);
+ t2 = U8TO32_LE(key + 8);
+ t3 = U8TO32_LE(key + 12);
+
+ /* precompute multipliers */
+ state->r0 = t0 & 0x3ffffff;
+ t0 >>= 26;
+ t0 |= t1 << 6;
+ state->r1 = t0 & 0x3ffff03;
+ t1 >>= 20;
+ t1 |= t2 << 12;
+ state->r2 = t1 & 0x3ffc0ff;
+ t2 >>= 14;
+ t2 |= t3 << 18;
+ state->r3 = t2 & 0x3f03fff;
+ t3 >>= 8;
+ state->r4 = t3 & 0x00fffff;
+
+ state->s1 = state->r1 * 5;
+ state->s2 = state->r2 * 5;
+ state->s3 = state->r3 * 5;
+ state->s4 = state->r4 * 5;
+
+ /* init state */
+ state->h0 = 0;
+ state->h1 = 0;
+ state->h2 = 0;
+ state->h3 = 0;
+ state->h4 = 0;
+
+ state->buf_used = 0;
+ memcpy(state->key, key + 16, sizeof(state->key));
+}
+
+void
+Poly1305Update(poly1305_state *statep, const unsigned char *in,
+ size_t in_len)
+{
+ unsigned int i;
+ struct poly1305_state_st *state = (struct poly1305_state_st *)statep;
+
+ if (state->buf_used) {
+ unsigned int todo = 16 - state->buf_used;
+ if (todo > in_len)
+ todo = in_len;
+ for (i = 0; i < todo; i++)
+ state->buf[state->buf_used + i] = in[i];
+ state->buf_used += todo;
+ in_len -= todo;
+ in += todo;
+
+ if (state->buf_used == 16) {
+ update(state, state->buf, 16);
+ state->buf_used = 0;
+ }
+ }
+
+ if (in_len >= 16) {
+ size_t todo = in_len & ~0xf;
+ update(state, in, todo);
+ in += todo;
+ in_len &= 0xf;
+ }
+
+ if (in_len) {
+ for (i = 0; i < in_len; i++)
+ state->buf[i] = in[i];
+ state->buf_used = in_len;
+ }
+}
+
+void
+Poly1305Finish(poly1305_state *statep, unsigned char mac[16])
+{
+ struct poly1305_state_st *state = (struct poly1305_state_st *)statep;
+ uint64_t f0, f1, f2, f3;
+ uint32_t g0, g1, g2, g3, g4;
+ uint32_t b, nb;
+
+ if (state->buf_used)
+ update(state, state->buf, state->buf_used);
+
+ b = state->h0 >> 26;
+ state->h0 = state->h0 & 0x3ffffff;
+ state->h1 += b;
+ b = state->h1 >> 26;
+ state->h1 = state->h1 & 0x3ffffff;
+ state->h2 += b;
+ b = state->h2 >> 26;
+ state->h2 = state->h2 & 0x3ffffff;
+ state->h3 += b;
+ b = state->h3 >> 26;
+ state->h3 = state->h3 & 0x3ffffff;
+ state->h4 += b;
+ b = state->h4 >> 26;
+ state->h4 = state->h4 & 0x3ffffff;
+ state->h0 += b * 5;
+
+ g0 = state->h0 + 5;
+ b = g0 >> 26;
+ g0 &= 0x3ffffff;
+ g1 = state->h1 + b;
+ b = g1 >> 26;
+ g1 &= 0x3ffffff;
+ g2 = state->h2 + b;
+ b = g2 >> 26;
+ g2 &= 0x3ffffff;
+ g3 = state->h3 + b;
+ b = g3 >> 26;
+ g3 &= 0x3ffffff;
+ g4 = state->h4 + b - (1 << 26);
+
+ b = (g4 >> 31) - 1;
+ nb = ~b;
+ state->h0 = (state->h0 & nb) | (g0 & b);
+ state->h1 = (state->h1 & nb) | (g1 & b);
+ state->h2 = (state->h2 & nb) | (g2 & b);
+ state->h3 = (state->h3 & nb) | (g3 & b);
+ state->h4 = (state->h4 & nb) | (g4 & b);
+
+ f0 = ((state->h0) | (state->h1 << 26)) + (uint64_t)U8TO32_LE(&state->key[0]);
+ f1 = ((state->h1 >> 6) | (state->h2 << 20)) + (uint64_t)U8TO32_LE(&state->key[4]);
+ f2 = ((state->h2 >> 12) | (state->h3 << 14)) + (uint64_t)U8TO32_LE(&state->key[8]);
+ f3 = ((state->h3 >> 18) | (state->h4 << 8)) + (uint64_t)U8TO32_LE(&state->key[12]);
+
+ U32TO8_LE(&mac[0], (uint32_t)f0);
+ f1 += (f0 >> 32);
+ U32TO8_LE(&mac[4], (uint32_t)f1);
+ f2 += (f1 >> 32);
+ U32TO8_LE(&mac[8], (uint32_t)f2);
+ f3 += (f2 >> 32);
+ U32TO8_LE(&mac[12], (uint32_t)f3);
+}
diff --git a/nss/lib/freebl/poly1305.h b/nss/lib/freebl/poly1305.h
new file mode 100644
index 0000000..0a46348
--- /dev/null
+++ b/nss/lib/freebl/poly1305.h
@@ -0,0 +1,28 @@
+/*
+ * poly1305.h - header file for Poly1305 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/. */
+
+#ifndef FREEBL_POLY1305_H_
+#define FREEBL_POLY1305_H_
+
+typedef unsigned char poly1305_state[512];
+
+/* Poly1305Init sets up |state| so that it can be used to calculate an
+ * authentication tag with the one-time key |key|. Note that |key| is a
+ * one-time key and therefore there is no `reset' method because that would
+ * enable several messages to be authenticated with the same key. */
+extern void Poly1305Init(poly1305_state* state, const unsigned char key[32]);
+
+/* Poly1305Update processes |in_len| bytes from |in|. It can be called zero or
+ * more times after poly1305_init. */
+extern void Poly1305Update(poly1305_state* state, const unsigned char* in,
+ size_t inLen);
+
+/* Poly1305Finish completes the poly1305 calculation and writes a 16 byte
+ * authentication tag to |mac|. */
+extern void Poly1305Finish(poly1305_state* state, unsigned char mac[16]);
+
+#endif /* FREEBL_POLY1305_H_ */
diff --git a/nss/lib/freebl/pqg.c b/nss/lib/freebl/pqg.c
index fd1351e..2f24afd 100644
--- a/nss/lib/freebl/pqg.c
+++ b/nss/lib/freebl/pqg.c
@@ -20,20 +20,20 @@
#include "mplogic.h"
#include "secmpi.h"
-#define MAX_ITERATIONS 1000 /* Maximum number of iterations of primegen */
+#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 */
+ 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
+ * 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
@@ -43,17 +43,18 @@ typedef enum {
* 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)
+static int
+prime_testcount_p(int L, int N)
{
switch (L) {
- case 1024:
- return 40;
- case 2048:
- return 56;
- case 3072:
- return 64;
- default:
- break;
+ case 1024:
+ return 40;
+ case 2048:
+ return 56;
+ case 3072:
+ return 64;
+ default:
+ break;
}
return 50; /* L = 512-960 */
}
@@ -61,13 +62,14 @@ int prime_testcount_p(int L, int N)
/* 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)
+static int
+prime_testcount_q(int L, int N)
{
- return prime_testcount_p(L,N);
+ return prime_testcount_p(L, N);
}
/*
- * generic function to make sure our input matches DSA2 requirements
+ * 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.
*/
@@ -76,27 +78,27 @@ 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;
+ 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;
}
@@ -106,18 +108,18 @@ 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 */
+ 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;
}
@@ -129,16 +131,16 @@ static HASH_HashType
getFirstHash(unsigned int L, unsigned int N)
{
if (N < 224) {
- return HASH_AlgSHA1;
+ return HASH_AlgSHA1;
}
if (N < 256) {
- return HASH_AlgSHA224;
+ return HASH_AlgSHA224;
}
if (N < 384) {
- return HASH_AlgSHA256;
+ return HASH_AlgSHA256;
}
if (N < 512) {
- return HASH_AlgSHA384;
+ return HASH_AlgSHA384;
}
return HASH_AlgSHA512;
}
@@ -150,22 +152,22 @@ 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;
+ 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;
}
@@ -174,31 +176,35 @@ static unsigned int
HASH_ResultLen(HASH_HashType type)
{
const SECHashObject *hash_obj = HASH_GetRawHashObject(type);
+ PORT_Assert(hash_obj != NULL);
if (hash_obj == NULL) {
- return 0;
+ /* type is always a valid HashType. Thus a null hash_obj must be a bug */
+ PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
+ return 0;
}
+ PORT_Assert(hash_obj->length != 0);
return hash_obj->length;
}
static SECStatus
HASH_HashBuf(HASH_HashType type, unsigned char *dest,
- const unsigned char *src, PRUint32 src_len)
+ 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;
+ return SECFailure;
}
hashcx = hash_obj->create();
if (hashcx == NULL) {
- return SECFailure;
+ return SECFailure;
}
hash_obj->begin(hashcx);
- hash_obj->update(hashcx,src,src_len);
- hash_obj->end(hashcx,dest, &dummy, hash_obj->length);
+ hash_obj->update(hashcx, src, src_len);
+ hash_obj->end(hashcx, dest, &dummy, hash_obj->length);
hash_obj->destroy(hashcx, PR_TRUE);
return SECSuccess;
}
@@ -209,10 +215,10 @@ PQG_GetLength(const SECItem *obj)
unsigned int len = obj->len;
if (obj->data == NULL) {
- return 0;
+ return 0;
}
if (len > 1 && obj->data[0] == 0) {
- len--;
+ len--;
}
return len;
}
@@ -220,33 +226,33 @@ PQG_GetLength(const SECItem *obj)
SECStatus
PQG_Check(const PQGParams *params)
{
- unsigned int L,N;
+ unsigned int L, N;
SECStatus rv = SECSuccess;
if (params == NULL) {
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- return SECFailure;
+ PORT_SetError(SEC_ERROR_INVALID_ARGS);
+ return SECFailure;
}
- L = PQG_GetLength(&params->prime)*PR_BITS_PER_BYTE;
- N = PQG_GetLength(&params->subPrime)*PR_BITS_PER_BYTE;
+ L = PQG_GetLength(&params->prime) * PR_BITS_PER_BYTE;
+ N = PQG_GetLength(&params->subPrime) * PR_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;
- }
+ 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);
+ /* handle DSA2 parameters (includes DSA1, 1024 bits) */
+ rv = pqg_validate_dsa2(L, N);
}
return rv;
}
@@ -254,15 +260,15 @@ PQG_Check(const PQGParams *params)
HASH_HashType
PQG_GetHashType(const PQGParams *params)
{
- unsigned int L,N;
+ unsigned int L, N;
if (params == NULL) {
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- return HASH_AlgNULL;
+ PORT_SetError(SEC_ERROR_INVALID_ARGS);
+ return HASH_AlgNULL;
}
- L = PQG_GetLength(&params->prime)*PR_BITS_PER_BYTE;
- N = PQG_GetLength(&params->subPrime)*PR_BITS_PER_BYTE;
+ L = PQG_GetLength(&params->prime) * PR_BITS_PER_BYTE;
+ N = PQG_GetLength(&params->subPrime) * PR_BITS_PER_BYTE;
return getFirstHash(L, N);
}
@@ -271,16 +277,16 @@ PQG_GetHashType(const PQGParams *params)
** global random number generator.
*/
static SECStatus
-getPQseed(SECItem *seed, PLArenaPool* arena)
+getPQseed(SECItem *seed, PLArenaPool *arena)
{
SECStatus rv;
if (!seed->data) {
- seed->data = (unsigned char*)PORT_ArenaZAlloc(arena, seed->len);
+ seed->data = (unsigned char *)PORT_ArenaZAlloc(arena, seed->len);
}
if (!seed->data) {
- PORT_SetError(SEC_ERROR_NO_MEMORY);
- return SECFailure;
+ PORT_SetError(SEC_ERROR_NO_MEMORY);
+ return SECFailure;
}
rv = RNG_GenerateGlobalRandomBytes(seed->data, seed->len);
/*
@@ -301,52 +307,52 @@ static SECStatus
generate_h_candidate(SECItem *hit, mp_int *H)
{
SECStatus rv = SECSuccess;
- mp_err err = MP_OKAY;
+ mp_err err = MP_OKAY;
#ifdef FIPS_186_1_A5_TEST
memset(hit->data, 0, hit->len);
- hit->data[hit->len-1] = 0x02;
+ hit->data[hit->len - 1] = 0x02;
#else
rv = RNG_GenerateGlobalRandomBytes(hit->data, hit->len);
#endif
if (rv)
- return SECFailure;
+ return SECFailure;
err = mp_read_unsigned_octets(H, hit->data, hit->len);
if (err) {
- MP_TO_SEC_ERROR(err);
- return SECFailure;
+ 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)
+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_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) );
+ 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) );
+ 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) );
+ 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) );
+ CHECK_MPI_OK(mp_div_2d(&s, (mp_digit)seedlen, NULL, &sum));
if (seedout->data != NULL) {
- SECITEM_ZfreeItem(seedout, PR_FALSE);
+ SECITEM_ZfreeItem(seedout, PR_FALSE);
}
MPINT_TO_SECITEM(&sum, seedout, NULL);
cleanup:
@@ -355,8 +361,8 @@ cleanup:
mp_clear(&modulus);
mp_clear(&tmp);
if (err) {
- MP_TO_SEC_ERROR(err);
- return SECFailure;
+ MP_TO_SEC_ERROR(err);
+ return SECFailure;
}
return rv;
}
@@ -367,21 +373,21 @@ cleanup:
** 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)
+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;
+ return rv;
}
- rv = HASH_HashBuf(hashtype, hashOutBuf, str.data, str.len);/* hash result */
+ rv = HASH_HashBuf(hashtype, hashOutBuf, str.data, str.len); /* hash result */
if (str.data)
- SECITEM_ZfreeItem(&str, PR_FALSE);
+ SECITEM_ZfreeItem(&str, PR_FALSE);
return rv;
}
@@ -391,42 +397,42 @@ addToSeedThenHash(HASH_HashType hashtype,
*/
static SECStatus
makeQfromSeed(
- unsigned int g, /* input. Length of seed in bits. */
-const SECItem * seed, /* input. */
- mp_int * Q) /* output. */
+ 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;
+ 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];
+ 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;
+ 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;
+ 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;
}
/*
@@ -435,15 +441,15 @@ cleanup:
*/
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. */
+ 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/PR_BITS_PER_BYTE; /* length of N in bytes rather than bits */
+ SECStatus rv = SECSuccess;
+ mp_err err = MP_OKAY;
+ int N_bytes = N / PR_BITS_PER_BYTE; /* length of N in bytes rather than bits */
int hashLen = HASH_ResultLen(hashtype);
int offset = 0;
@@ -451,29 +457,29 @@ const SECItem * seed, /* input. */
** Step 6.
** "Compute U = hash[SEED] mod 2**N-1]."
**/
- CHECK_SEC_OK( HASH_HashBuf(hashtype, U, seed->data, seed->len) );
+ 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;
+ 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;
+ 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;
+ memset(U, 0, HASH_LENGTH_MAX);
+ if (err) {
+ MP_TO_SEC_ERROR(err);
+ return SECFailure;
+ }
+ return rv;
}
/*
@@ -485,16 +491,16 @@ cleanup:
** 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*PR_BITS_PER_BYTE)
-SECStatus
+#define MAX_ST_SEED_BITS (HASH_LENGTH_MAX * PR_BITS_PER_BYTE)
+static 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. */
- unsigned int *prime_gen_counter) /* input/output. */
+ 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. */
+ unsigned int *prime_gen_counter) /* input/output. */
{
mp_int c;
mp_int c0_2;
@@ -504,13 +510,13 @@ makePrimefromPrimesShaweTaylor(
mp_int two_length_minus_1;
SECStatus rv = SECFailure;
int hashlen = HASH_ResultLen(hashtype);
- int outlen = hashlen*PR_BITS_PER_BYTE;
+ int outlen = hashlen * PR_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];
+ unsigned char x[DSA_MAX_P_BITS / 8 + HASH_LENGTH_MAX];
mp_err err = MP_OKAY;
int i;
int iterations;
@@ -522,13 +528,12 @@ makePrimefromPrimesShaweTaylor(
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) );
-
+ 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
@@ -547,10 +552,10 @@ makePrimefromPrimesShaweTaylor(
*/
/* Step 4/16 iterations = ceiling(length/outlen)-1 */
- iterations = (length+outlen-1)/outlen; /* NOTE: iterations +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].
**
@@ -561,31 +566,31 @@ makePrimefromPrimesShaweTaylor(
** 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]));
+ 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));
+ 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)
+ ** 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
+ ** 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)/PR_BITS_PER_BYTE;
- /* now we want to set the 'high bit', since length may not be a
+ offset = (outlen * iterations - length) / PR_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 */
+ 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);
+ mask = (bit - 1);
/* now we set it */
x[offset] = (mask & x[offset]) | bit;
/*
@@ -595,34 +600,34 @@ makePrimefromPrimesShaweTaylor(
** 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 */
+ 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) );
- /*
+ 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) );
+ 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*/
+ 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)++;
@@ -632,51 +637,51 @@ step_23:
**
** Step 14/26 a=0
*/
- PORT_Memset(x, 0, sizeof(x)); /* use x for a */
+ 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]));
+ 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));
+ 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 */
+ 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 */
+ 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 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 ));
+ 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;
- }
+ 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
@@ -684,16 +689,16 @@ step_23:
** 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_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);
@@ -701,16 +706,17 @@ cleanup:
mp_clear(&a);
mp_clear(&z);
mp_clear(&two_length_minus_1);
+ PORT_Memset(x, 0, sizeof(x));
if (err) {
- MP_TO_SEC_ERROR(err);
- rv = SECFailure;
+ 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;
+ mp_zero(prime);
+ if (prime_seed->data) {
+ SECITEM_FreeItem(prime_seed, PR_FALSE);
+ }
+ *prime_gen_counter = 0;
}
return rv;
}
@@ -720,24 +726,24 @@ cleanup:
**
** This generates a provable prime from a seed
*/
-SECStatus
+static 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. */
- unsigned int *prime_gen_counter) /* output. */
+ 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. */
+ unsigned 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*PR_BITS_PER_BYTE;
+ int outlen = hashlen * PR_BITS_PER_BYTE;
int offset;
unsigned char bit, mask;
- unsigned char x[HASH_LENGTH_MAX*2];
+ unsigned char x[HASH_LENGTH_MAX * 2];
mp_digit dummy;
mp_err err = MP_OKAY;
int i;
@@ -745,33 +751,33 @@ const SECItem * input_seed, /* input. */
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) );
+ 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;
+ 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 */
+ 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));
@@ -780,11 +786,11 @@ const SECItem * input_seed, /* input. */
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];
+ 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
@@ -795,19 +801,19 @@ step_5:
** 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)/PR_BITS_PER_BYTE;
- /* now we want to set the 'high bit'. We have to calculate this since
+ offset = (outlen - length) / PR_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 */
+ 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);
+ 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;
+ 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) );
+ 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 */
@@ -819,155 +825,153 @@ step_5:
** 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;
+ 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;
+ /* 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 */
+ goto cleanup; /* function failed, bail out */
} else {
- /* reset mp_err */
- err = MP_OKAY;
+ /* reset mp_err */
+ err = MP_OKAY;
}
/*
- ** Step 12 if (prime_gen_counter > (4*len))
- ** then return (FAILURE, 0, 0, 0))
+ ** 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_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);
+ PORT_Memset(x, 0, sizeof(x));
if (err) {
- MP_TO_SEC_ERROR(err);
- rv = SECFailure;
+ 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;
+ 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. */
- unsigned int *qseed_len, /* output */
- HASH_HashType *hashtypePtr, /* output. Hash uses */
- pqgGenType *typePtr) /* output. Generation Type used */
+ 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. */
+ unsigned 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 };
+ 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
+ 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 */
+ 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;
- }
+ 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
+ * 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)) {
- unsigned 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);
+ firstseed.len = seed->len / 3;
+ for (hashtype = getFirstHash(L, N); hashtype != HASH_AlgTOTAL;
+ hashtype = getNextHash(hashtype)) {
+ unsigned 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.
@@ -976,40 +980,40 @@ const SECItem * seed, /* input. */
*/
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. */
+ 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 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;
+ 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) );
+ 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*PR_BITS_PER_BYTE;
+ outlen = hashlen * PR_BITS_PER_BYTE;
/* L - 1 = n*outlen + b */
n = (L - 1) / outlen;
@@ -1021,48 +1025,48 @@ const mp_int * Q, /* input. */
** 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))
+ ** "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 */
+ 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))]
+ ** [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)
+ 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 */
+ 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 */
+ 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 */
+ 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);
@@ -1071,8 +1075,8 @@ cleanup:
mp_clear(&V_n);
mp_clear(&tmp);
if (err) {
- MP_TO_SEC_ERROR(err);
- return SECFailure;
+ MP_TO_SEC_ERROR(err);
+ return SECFailure;
}
return rv;
}
@@ -1081,11 +1085,11 @@ cleanup:
** 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)
+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;
@@ -1093,35 +1097,35 @@ makeGfromH(const mp_int *P, /* input. */
*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) */
+ 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;
+ 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_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;
+ rv = SECFailure;
+ goto cleanup;
}
*passed = PR_TRUE;
cleanup:
mp_clear(&exp);
mp_clear(&pm1);
if (err) {
- MP_TO_SEC_ERROR(err);
- rv = SECFailure;
+ MP_TO_SEC_ERROR(err);
+ rv = SECFailure;
}
return rv;
}
@@ -1131,11 +1135,11 @@ cleanup:
*/
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 */
+ 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;
@@ -1149,72 +1153,72 @@ makeGfromIndex(HASH_HashType hashtype,
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) );
+ 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;
+ /* shouldn't happen */
+ PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
+ rv = SECFailure;
+ goto cleanup;
}
hashcx = hashobj->create();
if (hashcx == NULL) {
- rv = SECFailure;
- goto cleanup;
+ rv = SECFailure;
+ goto cleanup;
}
- CHECK_MPI_OK( mp_sub_d(P, 1, &pm1) ); /* P - 1 */
+ 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
+ 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.
+ /* 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);
+ hashobj->destroy(hashcx, PR_TRUE);
}
mp_clear(&e);
mp_clear(&pm1);
mp_clear(&W);
if (err) {
- MP_TO_SEC_ERROR(err);
- rv = SECFailure;
+ MP_TO_SEC_ERROR(err);
+ rv = SECFailure;
}
return rv;
}
@@ -1226,102 +1230,124 @@ cleanup:
**/
static SECStatus
pqg_ParamGen(unsigned int L, unsigned int N, pqgGenType type,
- unsigned int seedBytes, PQGParams **pParams, PQGVerify **pVfy)
+ 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 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;
+ unsigned int n; /* 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 */
- PLArenaPool *arena = NULL;
- PQGParams *params = NULL;
- PQGVerify *verify = NULL;
+ SECItem *seed; /* Per FIPS 186, app 2.2. 186-3 app A.1.1.2 */
+ PLArenaPool *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;
+ 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/PR_BITS_PER_BYTE || !pParams || !pVfy) {
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- return SECFailure;
+ if (seedBytes < N / PR_BITS_PER_BYTE || !pParams || !pVfy) {
+ PORT_SetError(SEC_ERROR_INVALID_ARGS);
+ return SECFailure;
+ }
+
+ /* 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));
+
+ /* parameters have been passed in, only generate G */
+ if (*pParams != NULL) {
+ /* we only support G index generation if generating separate from PQ */
+ if ((*pVfy == NULL) || (type == FIPS186_1_TYPE) ||
+ ((*pVfy)->h.len != 1) || ((*pVfy)->h.data == NULL) ||
+ ((*pVfy)->seed.data == NULL) || ((*pVfy)->seed.len == 0)) {
+ PORT_SetError(SEC_ERROR_INVALID_ARGS);
+ return SECFailure;
+ }
+ params = *pParams;
+ verify = *pVfy;
+
+ /* fill in P Q, */
+ SECITEM_TO_MPINT((*pParams)->prime, &P);
+ SECITEM_TO_MPINT((*pParams)->subPrime, &Q);
+ hashtype = getFirstHash(L, N);
+ CHECK_SEC_OK(makeGfromIndex(hashtype, &P, &Q, &(*pVfy)->seed,
+ (*pVfy)->h.data[0], &G));
+ MPINT_TO_SECITEM(&G, &(*pParams)->base, (*pParams)->arena);
+ goto cleanup;
}
/* Initialize an arena for the params. */
arena = PORT_NewArena(NSS_FREEBL_DEFAULT_CHUNKSIZE);
if (!arena) {
- PORT_SetError(SEC_ERROR_NO_MEMORY);
- return SECFailure;
+ 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;
+ 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;
+ 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;
+ 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)*PR_BITS_PER_BYTE;
+ hashtype = getFirstHash(L, N);
+ outlen = HASH_ResultLen(hashtype) * PR_BITS_PER_BYTE;
/* Step 3: n = Ceil(L/outlen)-1; (same as n = Floor((L-1)/outlen)) */
- n = (L - 1) / outlen;
+ n = (L - 1) / outlen;
/* Step 4: (skipped since we don't use b): b = L -1 - (n*outlen); */
- seedlen = seedBytes * PR_BITS_PER_BYTE; /* bits in seed */
+ seedlen = seedBytes * PR_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 */
+ 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) );
+ CHECK_SEC_OK(getPQseed(seed, verify->arena));
/* ******************************************************************
** Step 6. (Step 2 in 186-1)
**
@@ -1329,7 +1355,7 @@ step_5:
** "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)
+ ** "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)"
**
@@ -1338,46 +1364,46 @@ step_5:
** 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.
+ ** FIPS186_3_ST_TYPE.
*/
if (type == FIPS186_1_TYPE) {
- CHECK_SEC_OK( makeQfromSeed(seedlen, seed, &Q) );
+ CHECK_SEC_OK(makeQfromSeed(seedlen, seed, &Q));
} else if (type == FIPS186_3_TYPE) {
- CHECK_SEC_OK( makeQ2fromSeed(hashtype, N, seed, &Q) );
+ CHECK_SEC_OK(makeQ2fromSeed(hashtype, N, seed, &Q));
} else {
- /* FIPS186_3_ST_TYPE */
- unsigned int qgen_counter, pgen_counter;
+ /* FIPS186_3_ST_TYPE */
+ unsigned 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;
+ 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)
@@ -1387,7 +1413,7 @@ step_5:
** "will give an acceptable probability of error."
*/
/*CHECK_SEC_OK( prm_RabinTest(&Q, &passed) );*/
- err = mpp_pprime(&Q, prime_testcount_q(L,N));
+ 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)."
@@ -1395,7 +1421,7 @@ step_5:
if (passed != SECSuccess)
goto step_5;
/* ******************************************************************
- ** Step 10.
+ ** Step 10.
** offset = 1;
**( Step 6b 186-1)"Let counter = 0 and offset = 2."
*/
@@ -1405,54 +1431,54 @@ step_5:
** For counter - 0 to (4L-1) do
**
*/
- maxCount = L >= 1024 ? (4*L - 1) : 4095;
+ 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)
+ /* ******************************************************************
+ ** 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
+ /************************************************************
+ ** 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;
+ */
+ if (passed == SECSuccess)
+ break;
+ step_11_9:
+ /* ******************************************************************
+ ** Step 11.9. "offset = offset + n + 1."
+ */
+ offset += n + 1;
}
/* ******************************************************************
** Step 12. "goto step 5."
@@ -1460,47 +1486,50 @@ step_11_9:
** 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;
+ 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);
+ /* 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) );
+ 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(&P, &params->prime, params->arena);
MPINT_TO_SECITEM(&Q, &params->subPrime, params->arena);
- MPINT_TO_SECITEM(&G, &params->base, 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);
+ PORT_Free(pseed.data);
}
if (qseed.data) {
- PORT_Free(qseed.data);
+ PORT_Free(qseed.data);
}
mp_clear(&P);
mp_clear(&Q);
@@ -1509,12 +1538,16 @@ cleanup:
mp_clear(&l);
mp_clear(&p0);
if (err) {
- MP_TO_SEC_ERROR(err);
- rv = SECFailure;
+ MP_TO_SEC_ERROR(err);
+ rv = SECFailure;
}
if (rv) {
- PORT_FreeArena(params->arena, PR_TRUE);
- PORT_FreeArena(verify->arena, PR_TRUE);
+ if (params) {
+ PORT_FreeArena(params->arena, PR_TRUE);
+ }
+ if (verify) {
+ PORT_FreeArena(verify->arena, PR_TRUE);
+ }
}
if (hit.data) {
SECITEM_FreeItem(&hit, PR_FALSE);
@@ -1525,16 +1558,16 @@ cleanup:
SECStatus
PQG_ParamGen(unsigned int j, PQGParams **pParams, PQGVerify **pVfy)
{
- unsigned int L; /* Length of P in bits. Per FIPS 186. */
+ 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);
+ 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,
+ L = 512 + (j * 64); /* bits in P */
+ seedBytes = L / 8;
+ return pqg_ParamGen(L, DSA1_Q_BITS, FIPS186_1_TYPE, seedBytes,
pParams, pVfy);
}
@@ -1542,43 +1575,42 @@ SECStatus
PQG_ParamGenSeedLen(unsigned int j, unsigned int seedBytes,
PQGParams **pParams, PQGVerify **pVfy)
{
- unsigned int L; /* Length of P in bits. Per FIPS 186. */
+ unsigned int L; /* Length of P in bits. Per FIPS 186. */
if (j > 8 || !pParams || !pVfy) {
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
+ PORT_SetError(SEC_ERROR_INVALID_ARGS);
return SECFailure;
}
- L = 512 + (j * 64); /* bits in P */
+ 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)
+ PQGParams **pParams, PQGVerify **pVfy)
{
if (N == 0) {
- N = pqg_get_default_N(L);
+ N = pqg_get_default_N(L);
}
if (seedBytes == 0) {
- /* seedBytes == L/8 for probable primes, N/8 for Shawe-Taylor Primes */
- seedBytes = N/8;
+ /* 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;
+ 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,
+SECStatus
+PQG_VerifyParams(const PQGParams *params,
const PQGVerify *vfy, SECStatus *result)
{
SECStatus rv = SECSuccess;
@@ -1588,30 +1620,30 @@ PQG_VerifyParams(const PQGParams *params,
int j;
unsigned int counter_max = 0; /* handle legacy L < 1024 */
unsigned int qseed_len;
- SECItem pseed_ = {0, 0, 0};
+ SECItem pseed_ = { 0, 0, 0 };
HASH_HashType hashtype;
pqgGenType type;
#define CHECKPARAM(cond) \
if (!(cond)) { \
- *result = SECFailure; \
- goto cleanup; \
+ *result = SECFailure; \
+ goto cleanup; \
}
if (!params || !vfy || !result) {
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- return SECFailure;
+ 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;
+ 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;
+ PORT_SetError(SEC_ERROR_INVALID_ARGS);
+ return SECFailure;
}
MP_DIGITS(&p0) = 0;
@@ -1623,145 +1655,146 @@ PQG_VerifyParams(const PQGParams *params,
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) );
+ 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->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);
+ 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;
+ /* 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;
+ /* 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 );
+ 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 );
+ 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 );
+ 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 );
+ 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) );
+ 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 );
+ 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 );
+ 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 };
- unsigned int first_seed_len;
- unsigned 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 );
+ SECItem qseed = { 0, 0, 0 };
+ SECItem pseed = { 0, 0, 0 };
+ unsigned int first_seed_len;
+ unsigned 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 */
+ /* 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)*PR_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 );
+ /* 10. P generated from (L, counter, g, SEED, Q) matches P
+ * in PQGParams. */
+ outlen = HASH_ResultLen(hashtype) * PR_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;
+ 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 */
+ 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 */
+ 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 (type != FIPS186_1_TYPE) {
+ *result = SECWouldBlock;
+ }
+ goto cleanup;
}
/*
@@ -1771,22 +1804,22 @@ PQG_VerifyParams(const PQGParams *params,
* 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 );
+ /* 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 );
+ 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);
@@ -1799,11 +1832,11 @@ cleanup:
mp_clear(&r);
mp_clear(&h);
if (pseed_.data) {
- SECITEM_FreeItem(&pseed_,PR_FALSE);
+ SECITEM_FreeItem(&pseed_, PR_FALSE);
}
if (err) {
- MP_TO_SEC_ERROR(err);
- rv = SECFailure;
+ MP_TO_SEC_ERROR(err);
+ rv = SECFailure;
}
return rv;
}
@@ -1814,15 +1847,15 @@ cleanup:
void
PQG_DestroyParams(PQGParams *params)
{
- if (params == NULL)
- return;
+ if (params == NULL)
+ return;
if (params->arena != NULL) {
- PORT_FreeArena(params->arena, PR_FALSE); /* don't zero it */
+ 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);
+ 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);
}
}
@@ -1833,13 +1866,13 @@ PQG_DestroyParams(PQGParams *params)
void
PQG_DestroyVerify(PQGVerify *vfy)
{
- if (vfy == NULL)
- return;
+ if (vfy == NULL)
+ return;
if (vfy->arena != NULL) {
- PORT_FreeArena(vfy->arena, PR_FALSE); /* don't zero it */
+ 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);
+ 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/nss/lib/freebl/pqg.h b/nss/lib/freebl/pqg.h
index 097f360..c4eecd5 100644
--- a/nss/lib/freebl/pqg.h
+++ b/nss/lib/freebl/pqg.h
@@ -11,7 +11,7 @@
#ifndef _PQG_H_
#define _PQG_H_ 1
-/* PQG_GetLength returns the significant bytes in the SECItem object (that is
+/* 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);
diff --git a/nss/lib/freebl/rawhash.c b/nss/lib/freebl/rawhash.c
index 7962b1f..551727b 100644
--- a/nss/lib/freebl/rawhash.c
+++ b/nss/lib/freebl/rawhash.c
@@ -8,7 +8,7 @@
#include "nspr.h"
#include "hasht.h"
-#include "blapi.h" /* below the line */
+#include "blapi.h" /* below the line */
#include "secerr.h"
static void *
@@ -36,7 +36,7 @@ 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)
+ unsigned int maxOut)
{
*outLen = 0;
}
@@ -47,115 +47,108 @@ 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
- },
+ { 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;
+ if (hashType <= HASH_AlgNULL || hashType >= HASH_AlgTOTAL) {
+ PORT_SetError(SEC_ERROR_INVALID_ARGS);
+ return NULL;
}
return &SECRawHashObjects[hashType];
}
diff --git a/nss/lib/freebl/rijndael.c b/nss/lib/freebl/rijndael.c
index 4e4be79..4bb1826 100644
--- a/nss/lib/freebl/rijndael.c
+++ b/nss/lib/freebl/rijndael.c
@@ -7,6 +7,7 @@
#endif
#include "prinit.h"
+#include "prenv.h"
#include "prerr.h"
#include "secerr.h"
@@ -20,8 +21,11 @@
#ifdef USE_HW_AES
#include "intel-aes.h"
+#endif
+
#include "mpi.h"
+#ifdef USE_HW_AES
static int has_intel_aes = 0;
static PRBool use_hw_aes = PR_FALSE;
@@ -30,15 +34,18 @@ static PRBool use_hw_aes = PR_FALSE;
static int has_intel_avx = 0;
static int has_intel_clmul = 0;
static PRBool use_hw_gcm = PR_FALSE;
+#if defined(_MSC_VER) && !defined(_M_IX86)
+#include <intrin.h> /* for _xgetbv() */
+#endif
#endif
-#endif /* USE_HW_AES */
+#endif /* USE_HW_AES */
/*
* 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
+ * 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
@@ -51,7 +58,7 @@ static PRBool use_hw_gcm = PR_FALSE;
*/
/*
- * When building RIJNDAEL_INCLUDE_TABLES, includes S**-1, Rcon, T[0..4],
+ * 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
*/
@@ -61,10 +68,10 @@ static PRBool use_hw_gcm = PR_FALSE;
/*
* RIJNDAEL_INCLUDE_TABLES
*/
-#define T0(i) _T0[i]
-#define T1(i) _T1[i]
-#define T2(i) _T2[i]
-#define T3(i) _T3[i]
+#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]
@@ -75,9 +82,9 @@ static PRBool use_hw_gcm = PR_FALSE;
#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])
+#define SBOX(b) ((PRUint8)_T3[b])
#else
-#define SBOX(b) ((PRUint8)_T1[b])
+#define SBOX(b) ((PRUint8)_T1[b])
#endif
#define SINV(b) (_SInv[b])
@@ -89,16 +96,22 @@ static PRBool use_hw_gcm = PR_FALSE;
#ifdef IS_LITTLE_ENDIAN
#define WORD4(b0, b1, b2, b3) \
- (((b3) << 24) | ((b2) << 16) | ((b1) << 8) | (b0))
+ ((((PRUint32)b3) << 24) | \
+ (((PRUint32)b2) << 16) | \
+ (((PRUint32)b1) << 8) | \
+ ((PRUint32)b0))
#else
#define WORD4(b0, b1, b2, b3) \
- (((b0) << 24) | ((b1) << 16) | ((b2) << 8) | (b3))
+ ((((PRUint32)b0) << 24) | \
+ (((PRUint32)b1) << 16) | \
+ (((PRUint32)b2) << 8) | \
+ ((PRUint32)b3))
#endif
/*
* Define the S and S**-1 tables (both have been stored)
*/
-#define SBOX(b) (_S[b])
+#define SBOX(b) (_S[b])
#define SINV(b) (_SInv[b])
/*
@@ -108,62 +121,63 @@ static PRBool use_hw_gcm = PR_FALSE;
((a & 0x80) ? ((a << 1) ^ 0x1b) : (a << 1))
/* Choose GFM method (macros or function) */
-#if defined(RIJNDAEL_GENERATE_TABLES_MACRO) || \
+#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 */
+ (a) /* a * 01 = a, the identity */
#define GFM02(a) \
- (XTIME(a) & 0xff) /* a * 02 = xtime(a) */
+ (XTIME(a) & 0xff) /* a * 02 = xtime(a) */
#define GFM04(a) \
- (GFM02(GFM02(a))) /* a * 04 = xtime**2(a) */
+ (GFM02(GFM02(a))) /* a * 04 = xtime**2(a) */
#define GFM08(a) \
- (GFM02(GFM04(a))) /* a * 08 = xtime**3(a) */
+ (GFM02(GFM04(a))) /* a * 08 = xtime**3(a) */
#define GFM03(a) \
- (GFM01(a) ^ GFM02(a)) /* a * 03 = a * (01 + 02) */
+ (GFM01(a) ^ GFM02(a)) /* a * 03 = a * (01 + 02) */
#define GFM09(a) \
- (GFM01(a) ^ GFM08(a)) /* a * 09 = a * (01 + 08) */
+ (GFM01(a) ^ GFM08(a)) /* a * 09 = a * (01 + 08) */
#define GFM0B(a) \
- (GFM01(a) ^ GFM02(a) ^ GFM08(a)) /* a * 0B = a * (01 + 02 + 08) */
+ (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) */
+ (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) */
+ (GFM02(a) ^ GFM04(a) ^ GFM08(a)) /* a * 0E = a * (02 + 04 + 08) */
-#else /* RIJNDAEL_GENERATE_TABLES or RIJNDAEL_GENERATE_VALUES */
+#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
+gfm(PRUint8 a, PRUint8 b)
{
PRUint8 res = 0;
while (b > 0) {
- res = (b & 0x01) ? res ^ a : res;
- a = XTIME(a);
- b >>= 1;
+ res = (b & 0x01) ? res ^ a : res;
+ a = XTIME(a);
+ b >>= 1;
}
return res;
}
#define GFM01(a) \
- (a) /* a * 01 = a, the identity */
+ (a) /* a * 01 = a, the identity */
#define GFM02(a) \
- (XTIME(a) & 0xff) /* a * 02 = xtime(a) */
+ (XTIME(a) & 0xff) /* a * 02 = xtime(a) */
#define GFM03(a) \
- (gfm(a, 0x03)) /* a * 03 */
+ (gfm(a, 0x03)) /* a * 03 */
#define GFM09(a) \
- (gfm(a, 0x09)) /* a * 09 */
+ (gfm(a, 0x09)) /* a * 09 */
#define GFM0B(a) \
- (gfm(a, 0x0B)) /* a * 0B */
+ (gfm(a, 0x0B)) /* a * 0B */
#define GFM0D(a) \
- (gfm(a, 0x0D)) /* a * 0D */
+ (gfm(a, 0x0D)) /* a * 0D */
#define GFM0E(a) \
- (gfm(a, 0x0E)) /* a * 0E */
+ (gfm(a, 0x0E)) /* a * 0E */
#endif /* choosing GFM function */
@@ -171,42 +185,43 @@ PRUint8 gfm(PRUint8 a, PRUint8 b)
* The T-tables
*/
#define G_T0(i) \
- ( WORD4( GFM02(SBOX(i)), GFM01(SBOX(i)), GFM01(SBOX(i)), GFM03(SBOX(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)) ) )
+ (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)) ) )
+ (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)) ) )
+ (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)) ) )
+ (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)) ) )
+ (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)) ) )
+ (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)) ) )
+ (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) ) )
+ (WORD4(GFM0E(i), GFM09(i), GFM0D(i), GFM0B(i)))
#define G_IMXC1(i) \
- ( WORD4( GFM0B(i), GFM0E(i), GFM09(i), GFM0D(i) ) )
+ (WORD4(GFM0B(i), GFM0E(i), GFM09(i), GFM0D(i)))
#define G_IMXC2(i) \
- ( WORD4( GFM0D(i), GFM0B(i), GFM0E(i), GFM09(i) ) )
+ (WORD4(GFM0D(i), GFM0B(i), GFM0E(i), GFM09(i)))
#define G_IMXC3(i) \
- ( WORD4( GFM09(i), GFM0D(i), GFM0B(i), GFM0E(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)
+static PRUint32
+gen_TInvXi(PRUint8 tx, PRUint8 i)
{
PRUint8 si01, si02, si03, si04, si08, si09, si0B, si0D, si0E;
si01 = SINV(i);
@@ -219,21 +234,21 @@ static PRUint32 gen_TInvXi(PRUint8 tx, PRUint8 i)
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);
+ 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 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)
@@ -244,10 +259,10 @@ static PRUint32 gen_TInvXi(PRUint8 tx, PRUint8 i)
#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 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)
@@ -256,13 +271,13 @@ static PRUint32 gen_TInvXi(PRUint8 tx, PRUint8 i)
#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 */
+#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 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]
@@ -275,7 +290,7 @@ static PRUint32 gen_TInvXi(PRUint8 tx, PRUint8 i)
#endif /* not RIJNDAEL_INCLUDE_TABLES */
-#if defined(RIJNDAEL_GENERATE_TABLES) || \
+#if defined(RIJNDAEL_GENERATE_TABLES) || \
defined(RIJNDAEL_GENERATE_TABLES_MACRO)
/* Code to generate and store the tables */
@@ -293,38 +308,39 @@ struct rijndael_tables_str {
static struct rijndael_tables_str *rijndaelTables = NULL;
static PRCallOnceType coRTInit = { 0, 0, 0 };
-static PRStatus
+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);
+ 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;
@@ -339,11 +355,11 @@ init_rijndael_tables(void)
*
*************************************************************************/
-#define SUBBYTE(w) \
- ((SBOX((w >> 24) & 0xff) << 24) | \
- (SBOX((w >> 16) & 0xff) << 16) | \
- (SBOX((w >> 8) & 0xff) << 8) | \
- (SBOX((w ) & 0xff) ))
+#define SUBBYTE(w) \
+ ((((PRUint32)SBOX((w >> 24) & 0xff)) << 24) | \
+ (((PRUint32)SBOX((w >> 16) & 0xff)) << 16) | \
+ (((PRUint32)SBOX((w >> 8) & 0xff)) << 8) | \
+ (((PRUint32)SBOX((w)&0xff))))
#ifdef IS_LITTLE_ENDIAN
#define ROTBYTE(b) \
@@ -377,12 +393,12 @@ rijndael_key_expansion7(AESContext *cx, const unsigned char *key, unsigned int N
/* 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;
+ 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;
}
@@ -400,7 +416,7 @@ rijndael_key_expansion(AESContext *cx, const unsigned char *key, unsigned int Nk
PRUint32 tmp;
unsigned int round_key_words = cx->Nb * (cx->Nr + 1);
if (Nk == 7)
- return rijndael_key_expansion7(cx, key, Nk);
+ return rijndael_key_expansion7(cx, key, Nk);
W = cx->expandedKey;
/* The first Nk words contain the input cipher key */
memcpy(W, key, Nk * 4);
@@ -408,20 +424,32 @@ rijndael_key_expansion(AESContext *cx, const unsigned char *key, unsigned int 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;
- }
+ 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++;
@@ -432,27 +460,27 @@ rijndael_key_expansion(AESContext *cx, const unsigned char *key, unsigned int Nk
* is no more need for the SubByte transformation.
*/
if (Nk < 8) {
- for (; i < round_key_words; ++i) {
- tmp = *pW++;
- *pW = W[i - Nk] ^ tmp;
- }
+ 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;
- }
+ /* 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
+ * Generate the expanded key for the inverse cipher from the key input by
* the user.
*/
static SECStatus
@@ -464,43 +492,47 @@ rijndael_invkey_expansion(AESContext *cx, const unsigned char *key, unsigned int
int Nb = cx->Nb;
/* begins like usual key expansion ... */
if (rijndael_key_expansion(cx, key, Nk) != SECSuccess)
- return SECFailure;
+ 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]);
- }
+ 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;
}
@@ -512,20 +544,20 @@ rijndael_invkey_expansion(AESContext *cx, const unsigned char *key, unsigned int
*************************************************************************/
#ifdef IS_LITTLE_ENDIAN
-#define BYTE0WORD(w) ((w) & 0x000000ff)
-#define BYTE1WORD(w) ((w) & 0x0000ff00)
-#define BYTE2WORD(w) ((w) & 0x00ff0000)
-#define BYTE3WORD(w) ((w) & 0xff000000)
+#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)
+#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];
+ PRUint8 b[16];
} rijndael_state;
#define COLUMN_0(state) state.w[0]
@@ -535,8 +567,8 @@ typedef union {
#define STATE_BYTE(i) state.b[i]
-static SECStatus
-rijndael_encryptBlock128(AESContext *cx,
+static SECStatus NO_SANITIZE_ALIGNMENT
+rijndael_encryptBlock128(AESContext *cx,
unsigned char *output,
const unsigned char *input)
{
@@ -552,87 +584,87 @@ rijndael_encryptBlock128(AESContext *cx,
PRUint32 inBuf[4], outBuf[4];
if ((ptrdiff_t)input & 0x3) {
- memcpy(inBuf, input, sizeof inBuf);
- pIn = (unsigned char *)inBuf;
+ memcpy(inBuf, input, sizeof inBuf);
+ pIn = (unsigned char *)inBuf;
} else {
- pIn = (unsigned char *)input;
+ pIn = (unsigned char *)input;
}
if ((ptrdiff_t)output & 0x3) {
- pOut = (unsigned char *)outBuf;
+ pOut = (unsigned char *)outBuf;
} else {
- pOut = (unsigned char *)output;
+ 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_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) {
+ 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++;
+ 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;
+ 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);
+ memcpy(output, outBuf, sizeof outBuf);
}
#endif
return SECSuccess;
}
-static SECStatus
-rijndael_decryptBlock128(AESContext *cx,
+static SECStatus NO_SANITIZE_ALIGNMENT
+rijndael_decryptBlock128(AESContext *cx,
unsigned char *output,
const unsigned char *input)
{
@@ -648,76 +680,76 @@ rijndael_decryptBlock128(AESContext *cx,
PRUint32 inBuf[4], outBuf[4];
if ((ptrdiff_t)input & 0x3) {
- memcpy(inBuf, input, sizeof inBuf);
- pIn = (unsigned char *)inBuf;
+ memcpy(inBuf, input, sizeof inBuf);
+ pIn = (unsigned char *)inBuf;
} else {
- pIn = (unsigned char *)input;
+ pIn = (unsigned char *)input;
}
if ((ptrdiff_t)output & 0x3) {
- pOut = (unsigned char *)outBuf;
+ pOut = (unsigned char *)outBuf;
} else {
- pOut = (unsigned char *)output;
+ 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--;
+ 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--;
+ 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[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));
+ 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--;
+ *((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);
+ memcpy(output, outBuf, sizeof outBuf);
}
#endif
return SECSuccess;
@@ -736,86 +768,86 @@ rijndael_decryptBlock128(AESContext *cx,
#define COLUMN(array, j) *((PRUint32 *)(array + j))
-SECStatus
-rijndael_encryptBlock(AESContext *cx,
+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;
+ 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++;
+ 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++;
- }
+ 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++;
+ 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,
+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;
+ 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--;
+ 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--;
- }
+ 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]);
+ 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--;
+ for (j = 4 * Nb; j >= 0; j -= 4) {
+ COLUMN(output, j) ^= *roundkeyw--;
}
return SECSuccess;
#endif
@@ -827,33 +859,33 @@ rijndael_decryptBlock(AESContext *cx,
*
*************************************************************************/
-static SECStatus
+static SECStatus
rijndael_encryptECB(AESContext *cx, unsigned char *output,
unsigned int *outputLen, unsigned int maxOutputLen,
- const unsigned char *input, unsigned int inputLen,
+ const unsigned char *input, unsigned int inputLen,
unsigned int blocksize)
{
SECStatus rv;
AESBlockFunc *encryptor;
- encryptor = (blocksize == RIJNDAEL_MIN_BLOCKSIZE)
- ? &rijndael_encryptBlock128
- : &rijndael_encryptBlock;
+ 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;
+ if (rv != SECSuccess)
+ return rv;
+ output += blocksize;
+ input += blocksize;
+ inputLen -= blocksize;
}
return SECSuccess;
}
-static SECStatus
+static SECStatus
rijndael_encryptCBC(AESContext *cx, unsigned char *output,
unsigned int *outputLen, unsigned int maxOutputLen,
- const unsigned char *input, unsigned int inputLen,
+ const unsigned char *input, unsigned int inputLen,
unsigned int blocksize)
{
unsigned int j;
@@ -863,56 +895,56 @@ rijndael_encryptCBC(AESContext *cx, unsigned char *output,
unsigned char inblock[RIJNDAEL_MAX_STATE_SIZE * 8];
if (!inputLen)
- return SECSuccess;
+ return SECSuccess;
lastblock = cx->iv;
- encryptor = (blocksize == RIJNDAEL_MIN_BLOCKSIZE)
- ? &rijndael_encryptBlock128
- : &rijndael_encryptBlock;
+ 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 */
+ /* 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;
+ 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
+static SECStatus
rijndael_decryptECB(AESContext *cx, unsigned char *output,
unsigned int *outputLen, unsigned int maxOutputLen,
- const unsigned char *input, unsigned int inputLen,
+ const unsigned char *input, unsigned int inputLen,
unsigned int blocksize)
{
SECStatus rv;
AESBlockFunc *decryptor;
- decryptor = (blocksize == RIJNDAEL_MIN_BLOCKSIZE)
- ? &rijndael_decryptBlock128
- : &rijndael_decryptBlock;
+ 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;
+ if (rv != SECSuccess)
+ return rv;
+ output += blocksize;
+ input += blocksize;
+ inputLen -= blocksize;
}
return SECSuccess;
}
-static SECStatus
+static SECStatus
rijndael_decryptCBC(AESContext *cx, unsigned char *output,
unsigned int *outputLen, unsigned int maxOutputLen,
- const unsigned char *input, unsigned int inputLen,
+ const unsigned char *input, unsigned int inputLen,
unsigned int blocksize)
{
SECStatus rv;
@@ -922,32 +954,31 @@ rijndael_decryptCBC(AESContext *cx, unsigned char *output,
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);
+ 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 (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];
+ if (rv != SECSuccess)
+ return rv;
+ for (j = 0; j < blocksize; ++j)
+ out[j] ^= cx->iv[j];
}
memcpy(cx->iv, newIV, blocksize);
return SECSuccess;
@@ -962,12 +993,12 @@ rijndael_decryptCBC(AESContext *cx, unsigned char *output,
*
***********************************************************************/
-AESContext * AES_AllocateContext(void)
+AESContext *
+AES_AllocateContext(void)
{
return PORT_ZNew(AESContext);
}
-
#ifdef INTEL_GCM
/*
* Adapted from the example code in "How to detect New Instruction support in
@@ -988,10 +1019,13 @@ check_xcr0_ymm()
mov xcr0, eax
}
#else
- xcr0 = (PRUint32)_xgetbv(0); /* Requires VS2010 SP1 or later. */
+ xcr0 = (PRUint32)_xgetbv(0); /* Requires VS2010 SP1 or later. */
#endif
#else
- __asm__ ("xgetbv" : "=a" (xcr0) : "c" (0) : "%edx");
+ __asm__("xgetbv"
+ : "=a"(xcr0)
+ : "c"(0)
+ : "%edx");
#endif
/* Check if xmm and ymm state are enabled in XCR0. */
return (xcr0 & 6) == 6;
@@ -1001,72 +1035,70 @@ check_xcr0_ymm()
/*
** 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
+** "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)
+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 (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;
+ PORT_SetError(SEC_ERROR_INVALID_ARGS);
+ return SECFailure;
}
if (mode == NSS_AES_CBC && iv == NULL) {
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- return SECFailure;
+ PORT_SetError(SEC_ERROR_INVALID_ARGS);
+ return SECFailure;
}
if (!cx) {
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- return SECFailure;
+ PORT_SetError(SEC_ERROR_INVALID_ARGS);
+ return SECFailure;
}
#ifdef USE_HW_AES
if (has_intel_aes == 0) {
- unsigned long eax, ebx, ecx, edx;
- char *disable_hw_aes = getenv("NSS_DISABLE_HW_AES");
+ unsigned long eax, ebx, ecx, edx;
+ char *disable_hw_aes = PR_GetEnvSecure("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;
+ if (disable_hw_aes == NULL) {
+ freebl_cpuid(1, &eax, &ebx, &ecx, &edx);
+ has_intel_aes = (ecx & (1 << 25)) != 0 ? 1 : -1;
#ifdef INTEL_GCM
- has_intel_clmul = (ecx & (1 << 1)) != 0 ? 1 : -1;
- if ((ecx & (1 << 27)) != 0 && (ecx & (1 << 28)) != 0 &&
- check_xcr0_ymm()) {
- has_intel_avx = 1;
- } else {
- has_intel_avx = -1;
- }
+ has_intel_clmul = (ecx & (1 << 1)) != 0 ? 1 : -1;
+ if ((ecx & (1 << 27)) != 0 && (ecx & (1 << 28)) != 0 &&
+ check_xcr0_ymm()) {
+ has_intel_avx = 1;
+ } else {
+ has_intel_avx = -1;
+ }
#endif
- } else {
- has_intel_aes = -1;
+ } else {
+ has_intel_aes = -1;
#ifdef INTEL_GCM
- has_intel_avx = -1;
- has_intel_clmul = -1;
+ has_intel_avx = -1;
+ has_intel_clmul = -1;
#endif
- }
+ }
}
- use_hw_aes = (PRBool)
- (has_intel_aes > 0 && (keysize % 8) == 0 && blocksize == 16);
+ use_hw_aes = (PRBool)(has_intel_aes > 0 && (keysize % 8) == 0 && blocksize == 16);
#ifdef INTEL_GCM
- use_hw_gcm = (PRBool)
- (use_hw_aes && has_intel_avx>0 && has_intel_clmul>0);
+ use_hw_gcm = (PRBool)(use_hw_aes && has_intel_avx > 0 && has_intel_clmul > 0);
#endif
-#endif /* USE_HW_AES */
+#endif /* USE_HW_AES */
/* Nb = (block size in bits) / 32 */
cx->Nb = blocksize / 4;
/* Nk = (key size in bits) / 32 */
@@ -1075,58 +1107,59 @@ aes_InitContext(AESContext *cx, const unsigned char *key, unsigned int keysize,
cx->Nr = RIJNDAEL_NUM_ROUNDS(Nk, cx->Nb);
/* copy in the iv, if neccessary */
if (mode == NSS_AES_CBC) {
- memcpy(cx->iv, iv, blocksize);
+ memcpy(cx->iv, iv, blocksize);
#ifdef USE_HW_AES
- if (use_hw_aes) {
- cx->worker = (freeblCipherFunc)
- intel_aes_cbc_worker(encrypt, keysize);
- } else
+ if (use_hw_aes) {
+ cx->worker = (freeblCipherFunc)
+ intel_aes_cbc_worker(encrypt, keysize);
+ } else
#endif
- {
- cx->worker = (freeblCipherFunc) (encrypt
- ? &rijndael_encryptCBC : &rijndael_decryptCBC);
- }
+ {
+ cx->worker = (freeblCipherFunc)(encrypt
+ ? &rijndael_encryptCBC
+ : &rijndael_decryptCBC);
+ }
} else {
-#ifdef USE_HW_AES
- if (use_hw_aes) {
- cx->worker = (freeblCipherFunc)
- intel_aes_ecb_worker(encrypt, keysize);
- } else
+#ifdef 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);
- }
+ {
+ 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;
+ PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
+ goto cleanup;
}
#ifdef USE_HW_AES
if (use_hw_aes) {
- intel_aes_init(encrypt, keysize);
+ 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;
- }
- }
+#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;
- }
+ /* 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;
@@ -1136,87 +1169,85 @@ 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)
+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;
+ 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);
+ rv = aes_InitContext(cx, key, keysize, iv, basemode,
+ baseencrypt, blocksize);
if (rv != SECSuccess) {
- AES_DestroyContext(cx, PR_FALSE);
- return rv;
+ AES_DestroyContext(cx, PR_FALSE);
+ return rv;
}
+ cx->mode = mode;
/* 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:
+ 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:
#ifdef INTEL_GCM
- 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
+ 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_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);
#if defined(USE_HW_AES) && defined(_MSC_VER)
- if (use_hw_aes) {
- cx->worker = (freeblCipherFunc) CTR_Update_HW_AES;
- } else
+ if (use_hw_aes) {
+ cx->worker = (freeblCipherFunc)CTR_Update_HW_AES;
+ } else
#endif
- {
- 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;
+ {
+ 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;
+ /* 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;
}
@@ -1226,38 +1257,38 @@ AES_InitContext(AESContext *cx, const unsigned char *key, unsigned int keysize,
* create a new context for Rijndael operations
*/
AESContext *
-AES_CreateContext(const unsigned char *key, const unsigned char *iv,
+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;
- }
+ 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
+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;
+ (*cx->destroy)(cx->worker_cx, PR_TRUE);
+ cx->worker_cx = NULL;
+ cx->destroy = NULL;
}
if (freeit)
- PORT_Free(cx);
+ PORT_Free(cx);
}
/*
@@ -1266,7 +1297,7 @@ AES_DestroyContext(AESContext *cx, PRBool freeit)
* Encrypt an arbitrary-length buffer. The output buffer must already be
* allocated to at least inputLen.
*/
-SECStatus
+SECStatus
AES_Encrypt(AESContext *cx, unsigned char *output,
unsigned int *outputLen, unsigned int maxOutputLen,
const unsigned char *input, unsigned int inputLen)
@@ -1274,21 +1305,42 @@ AES_Encrypt(AESContext *cx, unsigned char *output,
int blocksize;
/* Check args */
if (cx == NULL || output == NULL || (input == NULL && inputLen != 0)) {
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- return SECFailure;
+ 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;
+ PORT_SetError(SEC_ERROR_INPUT_LEN);
+ return SECFailure;
}
if (maxOutputLen < inputLen) {
- PORT_SetError(SEC_ERROR_OUTPUT_LEN);
- return SECFailure;
+ PORT_SetError(SEC_ERROR_OUTPUT_LEN);
+ return SECFailure;
}
*outputLen = inputLen;
- return (*cx->worker)(cx->worker_cx, output, outputLen, maxOutputLen,
- input, inputLen, blocksize);
+#if UINT_MAX > MP_32BIT_MAX
+ /*
+ * we can guarentee that GSM won't overlfow if we limit the input to
+ * 2^36 bytes. For simplicity, we are limiting it to 2^32 for now.
+ *
+ * We do it here to cover both hardware and software GCM operations.
+ */
+ {
+ PR_STATIC_ASSERT(sizeof(unsigned int) > 4);
+ }
+ if ((cx->mode == NSS_AES_GCM) && (inputLen > MP_32BIT_MAX)) {
+ PORT_SetError(SEC_ERROR_OUTPUT_LEN);
+ return SECFailure;
+ }
+#else
+ /* if we can't pass in a 32_bit number, then no such check needed */
+ {
+ PR_STATIC_ASSERT(sizeof(unsigned int) <= 4);
+ }
+#endif
+
+ return (*cx->worker)(cx->worker_cx, output, outputLen, maxOutputLen,
+ input, inputLen, blocksize);
}
/*
@@ -1297,7 +1349,7 @@ AES_Encrypt(AESContext *cx, unsigned char *output,
* Decrypt and arbitrary-length buffer. The output buffer must already be
* allocated to at least inputLen.
*/
-SECStatus
+SECStatus
AES_Decrypt(AESContext *cx, unsigned char *output,
unsigned int *outputLen, unsigned int maxOutputLen,
const unsigned char *input, unsigned int inputLen)
@@ -1305,19 +1357,19 @@ AES_Decrypt(AESContext *cx, unsigned char *output,
int blocksize;
/* Check args */
if (cx == NULL || output == NULL || (input == NULL && inputLen != 0)) {
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- return SECFailure;
+ 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;
+ PORT_SetError(SEC_ERROR_INPUT_LEN);
+ return SECFailure;
}
if (maxOutputLen < inputLen) {
- PORT_SetError(SEC_ERROR_OUTPUT_LEN);
- return SECFailure;
+ PORT_SetError(SEC_ERROR_OUTPUT_LEN);
+ return SECFailure;
}
*outputLen = inputLen;
- return (*cx->worker)(cx->worker_cx, output, outputLen, maxOutputLen,
- input, inputLen, blocksize);
+ return (*cx->worker)(cx->worker_cx, output, outputLen, maxOutputLen,
+ input, inputLen, blocksize);
}
diff --git a/nss/lib/freebl/rijndael.h b/nss/lib/freebl/rijndael.h
index 5f79058..0e14ec2 100644
--- a/nss/lib/freebl/rijndael.h
+++ b/nss/lib/freebl/rijndael.h
@@ -10,7 +10,7 @@
#define RIJNDAEL_MIN_BLOCKSIZE 16 /* bytes */
#define RIJNDAEL_MAX_BLOCKSIZE 32 /* bytes */
-typedef SECStatus AESBlockFunc(AESContext *cx,
+typedef SECStatus AESBlockFunc(AESContext *cx,
unsigned char *output,
const unsigned char *input);
@@ -23,7 +23,7 @@ typedef SECStatus AESBlockFunc(AESContext *cx,
#define RIJNDAEL_NUM_ROUNDS(Nk, Nb) \
(PR_MAX(Nk, Nb) + 6)
-/* RIJNDAEL_MAX_STATE_SIZE
+/* RIJNDAEL_MAX_STATE_SIZE
*
* Maximum number of bytes in the state (spec includes up to 256-bit block
* size)
@@ -50,18 +50,18 @@ typedef SECStatus AESBlockFunc(AESContext *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;
+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];
+ PRUint32 expandedKey[RIJNDAEL_MAX_EXP_KEY_SIZE];
freeblDestroyFunc destroy;
- void *worker_cx;
- PRBool isBlock;
+ void *worker_cx;
+ PRBool isBlock;
+ int mode;
};
#endif /* _RIJNDAEL_H_ */
diff --git a/nss/lib/freebl/rijndael_tables.c b/nss/lib/freebl/rijndael_tables.c
index 97f645f..78dd85a 100644
--- a/nss/lib/freebl/rijndael_tables.c
+++ b/nss/lib/freebl/rijndael_tables.c
@@ -11,136 +11,138 @@
* 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 __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
-};
+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
+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;
+ 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 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':' ');
+ 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':' ');
+ 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)
+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':' ');
+ 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':' ');
+ 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
+main()
{
int i, j;
PRUint8 cur, last;
@@ -150,16 +152,16 @@ int main()
/* 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':' ');
+ 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':' ');
+ 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");
@@ -190,21 +192,21 @@ int main()
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);
+ 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);
+ 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");
diff --git a/nss/lib/freebl/rsa.c b/nss/lib/freebl/rsa.c
index f885acc..ff8c40e 100644
--- a/nss/lib/freebl/rsa.c
+++ b/nss/lib/freebl/rsa.c
@@ -37,33 +37,32 @@
#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)
+#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) */
+ 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
+** 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
-{
+struct RSABlindingParamsStr {
/* Blinding-specific parameters */
- PRCList link; /* link to list of structs */
- SECItem modulus; /* list element "key" */
- blindingParams *free, *bp; /* Blinding parameters queue */
+ 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;
@@ -76,12 +75,11 @@ typedef struct RSABlindingParamsStr RSABlindingParams;
** 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 */
+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 */
+ int waitCount; /* Number of threads waiting on cVar */
+ PRCList head; /* Pointer to the list */
};
/*
@@ -98,75 +96,75 @@ static PRBool nssRSAUseBlinding = PR_TRUE;
static SECStatus
rsa_build_from_primes(const mp_int *p, const mp_int *q,
- mp_int *e, PRBool needPublicExponent,
- mp_int *d, PRBool needPrivateExponent,
- RSAPrivateKey *key, unsigned int keySizeInBits)
+ 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;
+ mp_err err = MP_OKAY;
SECStatus rv = SECSuccess;
- MP_DIGITS(&n) = 0;
- MP_DIGITS(&phi) = 0;
+ 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) );
+ 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));
/* p and q must be distinct. */
if (mp_cmp(p, q) == 0) {
- PORT_SetError(SEC_ERROR_NEED_RANDOM);
- rv = SECFailure;
- goto cleanup;
+ PORT_SetError(SEC_ERROR_NEED_RANDOM);
+ rv = SECFailure;
+ goto cleanup;
}
/* 1. Compute n = p*q */
- CHECK_MPI_OK( mp_mul(p, q, &n) );
+ 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;
+ 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) );
+ 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);
- }
+ CHECK_MPI_OK(mp_lcm(&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;
+ 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;
+ 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) );
+ 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) );
+ 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) );
+ CHECK_MPI_OK(mp_invmod(q, p, &tmp));
MPINT_TO_SECITEM(&tmp, &key->coefficient, key->arena);
/* copy our calculated results, overwrite what is there */
@@ -187,53 +185,92 @@ cleanup:
mp_clear(&qsub1);
mp_clear(&tmp);
if (err) {
- MP_TO_SEC_ERROR(err);
- rv = SECFailure;
+ MP_TO_SEC_ERROR(err);
+ rv = SECFailure;
}
return rv;
}
static SECStatus
generate_prime(mp_int *prime, int primeLen)
{
- mp_err err = MP_OKAY;
+ 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;
+ 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 */
+ 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);
+ PORT_ZFree(pb, primeLen);
if (err) {
- MP_TO_SEC_ERROR(err);
- rv = SECFailure;
+ MP_TO_SEC_ERROR(err);
+ rv = SECFailure;
}
return rv;
}
/*
+ * make sure the key components meet fips186 requirements.
+ */
+static PRBool
+rsa_fips186_verify(mp_int *p, mp_int *q, mp_int *d, int keySizeInBits)
+{
+ mp_int pq_diff;
+ mp_err err = MP_OKAY;
+ PRBool ret = PR_FALSE;
+
+ if (keySizeInBits < 250) {
+ /* not a valid FIPS length, no point in our other tests */
+ /* if you are here, and in FIPS mode, you are outside the security
+ * policy */
+ return PR_TRUE;
+ }
+
+ /* p & q are already known to be greater then sqrt(2)*2^(keySize/2-1) */
+ /* we also know that gcd(p-1,e) = 1 and gcd(q-1,e) = 1 because the
+ * mp_invmod() function will fail. */
+ /* now check p-q > 2^(keysize/2-100) */
+ MP_DIGITS(&pq_diff) = 0;
+ CHECK_MPI_OK(mp_init(&pq_diff));
+ /* NSS always has p > q, so we know pq_diff is positive */
+ CHECK_MPI_OK(mp_sub(p, q, &pq_diff));
+ if ((unsigned)mpl_significant_bits(&pq_diff) < (keySizeInBits / 2 - 100)) {
+ goto cleanup;
+ }
+ /* now verify d is large enough*/
+ if ((unsigned)mpl_significant_bits(d) < (keySizeInBits / 2)) {
+ goto cleanup;
+ }
+ ret = PR_TRUE;
+
+cleanup:
+ mp_clear(&pq_diff);
+ return ret;
+}
+
+/*
** 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.
+** 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)
@@ -241,28 +278,29 @@ RSA_NewKey(int keySizeInBits, SECItem *publicExponent)
unsigned int primeLen;
mp_int p, q, e, d;
int kiter;
- mp_err err = MP_OKAY;
+ int max_attempts;
+ mp_err err = MP_OKAY;
SECStatus rv = SECSuccess;
int prerr = 0;
RSAPrivateKey *key = NULL;
PLArenaPool *arena = NULL;
/* Require key size to be a multiple of 16 bits. */
if (!publicExponent || keySizeInBits % 16 != 0 ||
- BAD_RSA_KEY_SIZE((unsigned int)keySizeInBits/8, publicExponent->len)) {
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- return NULL;
+ BAD_RSA_KEY_SIZE((unsigned int)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;
+ 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;
+ PORT_SetError(SEC_ERROR_NO_MEMORY);
+ PORT_FreeArena(arena, PR_TRUE);
+ return NULL;
}
key->arena = arena;
/* length of primes p and q (in bytes) */
@@ -271,65 +309,72 @@ RSA_NewKey(int keySizeInBits, SECItem *publicExponent)
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) );
+ 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;
+ max_attempts = 5 * (keySizeInBits / 2); /* FIPS 186-4 B.3.3 steps 4.7 and 5.8 */
do {
- prerr = 0;
- PORT_SetError(0);
- CHECK_SEC_OK( generate_prime(&p, primeLen) );
- CHECK_SEC_OK( generate_prime(&q, primeLen) );
- /* Assure p > q */
- /* NOTE: PKCS #1 does not require p > q, and NSS doesn't use any
- * implementation optimization that requires p > q. We can remove
- * this code in the future.
- */
- 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);
+ prerr = 0;
+ PORT_SetError(0);
+ CHECK_SEC_OK(generate_prime(&p, primeLen));
+ CHECK_SEC_OK(generate_prime(&q, primeLen));
+ /* Assure p > q */
+ /* NOTE: PKCS #1 does not require p > q, and NSS doesn't use any
+ * implementation optimization that requires p > q. We can remove
+ * this code in the future.
+ */
+ 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) {
+ if (rsa_fips186_verify(&p, &q, &d, keySizeInBits)) {
+ break;
+ }
+ prerr = SEC_ERROR_NEED_RANDOM; /* retry with different values */
+ } else {
+ prerr = PORT_GetError();
+ }
+ kiter++;
+ /* loop until have primes */
+ } while (prerr == SEC_ERROR_NEED_RANDOM && kiter < max_attempts);
if (prerr)
- goto cleanup;
+ goto cleanup;
cleanup:
mp_clear(&p);
mp_clear(&q);
mp_clear(&e);
mp_clear(&d);
if (err) {
- MP_TO_SEC_ERROR(err);
- rv = SECFailure;
+ MP_TO_SEC_ERROR(err);
+ rv = SECFailure;
}
if (rv && arena) {
- PORT_FreeArena(arena, PR_TRUE);
- key = NULL;
+ PORT_FreeArena(arena, PR_TRUE);
+ key = NULL;
}
return key;
}
mp_err
-rsa_is_prime(mp_int *p) {
+rsa_is_prime(mp_int *p)
+{
int res;
/* run a Fermat test */
res = mpp_fermat(p, 2);
if (res != MP_OKAY) {
- return res;
+ return res;
}
/* If that passed, run some Miller-Rabin tests */
@@ -338,90 +383,181 @@ rsa_is_prime(mp_int *p) {
}
/*
- * Try to find the two primes based on 2 exponents plus either a prime
- * or a modulus.
+ * Factorize a RSA modulus n into p and q by using the exponents e and d.
+ *
+ * In: e, d, n
+ * Out: p, q
+ *
+ * See Handbook of Applied Cryptography, 8.2.2(i).
+ *
+ * The algorithm is probabilistic, it is run 64 times and each run has a 50%
+ * chance of succeeding with a runtime of O(log(e*d)).
+ *
+ * The returned p might be smaller than q.
+ */
+static mp_err
+rsa_factorize_n_from_exponents(mp_int *e, mp_int *d, mp_int *p, mp_int *q,
+ mp_int *n)
+{
+ /* lambda is the private modulus: e*d = 1 mod lambda */
+ /* so: e*d - 1 = k*lambda = t*2^s where t is odd */
+ mp_int klambda;
+ mp_int t, onetwentyeight;
+ unsigned long s = 0;
+ unsigned long i;
+
+ /* cand = a^(t * 2^i) mod n, next_cand = a^(t * 2^(i+1)) mod n */
+ mp_int a;
+ mp_int cand;
+ mp_int next_cand;
+
+ mp_int n_minus_one;
+ mp_err err = MP_OKAY;
+
+ MP_DIGITS(&klambda) = 0;
+ MP_DIGITS(&t) = 0;
+ MP_DIGITS(&a) = 0;
+ MP_DIGITS(&cand) = 0;
+ MP_DIGITS(&n_minus_one) = 0;
+ MP_DIGITS(&next_cand) = 0;
+ MP_DIGITS(&onetwentyeight) = 0;
+ CHECK_MPI_OK(mp_init(&klambda));
+ CHECK_MPI_OK(mp_init(&t));
+ CHECK_MPI_OK(mp_init(&a));
+ CHECK_MPI_OK(mp_init(&cand));
+ CHECK_MPI_OK(mp_init(&n_minus_one));
+ CHECK_MPI_OK(mp_init(&next_cand));
+ CHECK_MPI_OK(mp_init(&onetwentyeight));
+
+ mp_set_int(&onetwentyeight, 128);
+
+ /* calculate k*lambda = e*d - 1 */
+ CHECK_MPI_OK(mp_mul(e, d, &klambda));
+ CHECK_MPI_OK(mp_sub_d(&klambda, 1, &klambda));
+
+ /* factorize klambda into t*2^s */
+ CHECK_MPI_OK(mp_copy(&klambda, &t));
+ while (mpp_divis_d(&t, 2) == MP_YES) {
+ CHECK_MPI_OK(mp_div_2(&t, &t));
+ s += 1;
+ }
+
+ /* precompute n_minus_one = n - 1 */
+ CHECK_MPI_OK(mp_copy(n, &n_minus_one));
+ CHECK_MPI_OK(mp_sub_d(&n_minus_one, 1, &n_minus_one));
+
+ /* pick random bases a, each one has a 50% leading to a factorization */
+ CHECK_MPI_OK(mp_set_int(&a, 2));
+ /* The following is equivalent to for (a=2, a <= 128, a+=2) */
+ while (mp_cmp(&a, &onetwentyeight) <= 0) {
+ /* compute the base cand = a^(t * 2^0) [i = 0] */
+ CHECK_MPI_OK(mp_exptmod(&a, &t, n, &cand));
+
+ for (i = 0; i < s; i++) {
+ /* condition 1: skip the base if we hit a trivial factor of n */
+ if (mp_cmp(&cand, &n_minus_one) == 0 || mp_cmp_d(&cand, 1) == 0) {
+ break;
+ }
+
+ /* increase i in a^(t * 2^i) by squaring the number */
+ CHECK_MPI_OK(mp_exptmod_d(&cand, 2, n, &next_cand));
+
+ /* condition 2: a^(t * 2^(i+1)) = 1 mod n */
+ if (mp_cmp_d(&next_cand, 1) == 0) {
+ /* conditions verified, gcd(a^(t * 2^i) - 1, n) is a factor */
+ CHECK_MPI_OK(mp_sub_d(&cand, 1, &cand));
+ CHECK_MPI_OK(mp_gcd(&cand, n, p));
+ if (mp_cmp_d(p, 1) == 0) {
+ CHECK_MPI_OK(mp_add_d(&cand, 1, &cand));
+ break;
+ }
+ CHECK_MPI_OK(mp_div(n, p, q, NULL));
+ goto cleanup;
+ }
+ CHECK_MPI_OK(mp_copy(&next_cand, &cand));
+ }
+
+ CHECK_MPI_OK(mp_add_d(&a, 2, &a));
+ }
+
+ /* if we reach here it's likely (2^64 - 1 / 2^64) that d is wrong */
+ err = MP_RANGE;
+
+cleanup:
+ mp_clear(&klambda);
+ mp_clear(&t);
+ mp_clear(&a);
+ mp_clear(&cand);
+ mp_clear(&n_minus_one);
+ mp_clear(&next_cand);
+ mp_clear(&onetwentyeight);
+ return err;
+}
+
+/*
+ * Try to find the two primes based on 2 exponents plus a prime.
*
- * In: e, d and either p or n (depending on the setting of hasModulus).
+ * In: e, d and p.
* 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.
+ * 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, We can divide k*phi by 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.
+ * 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 our tentative phi=kphi/k. Note: real phi is (p-1)*(q-1).
+ * Step 4a, kphi is k*(q-1), so phi is our 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,
+ * 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)
+rsa_get_prime_from_exponents(mp_int *e, mp_int *d, mp_int *p, mp_int *q,
+ mp_int *n, 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_int tmp; /* p-1 if p is given */
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) );
+ CHECK_MPI_OK(mp_init(&kphi));
+ CHECK_MPI_OK(mp_init(&phi));
+ CHECK_MPI_OK(mp_init(&k));
+ CHECK_MPI_OK(mp_init(&r));
+ CHECK_MPI_OK(mp_init(&tmp));
/* 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.
+ * 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
@@ -429,188 +565,128 @@ rsa_get_primes_from_exponents(mp_int *e, mp_int *d, mp_int *p, mp_int *q,
* 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
+ * 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;
+ 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) );
-
+ 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
+ * 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) );
+ 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) */
+ /* tmp = p-1 (used to calculate q-1= phi/tmp) */
+ 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;
+ for (; (err == MP_OKAY) && (mpl_significant_bits(&k) >= order_k);
+ err = mp_sub_d(&k, 1, &k)) {
+ CHECK_MPI_OK(err);
+ /* 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 ((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 */
+ 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;
}
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;
- }
+ if (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.
*
@@ -637,27 +713,23 @@ cleanup:
* 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) *
+ * 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
+ * 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 an exponent and 2 primes.
+ * If we are given 2 exponents and 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.
+ * 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).
+ * (rsa_get_prime_from_exponents)
+ * If we are given 2 exponents and the modulus we factor the modulus to
+ * get the 2 missing primes (rsa_factorize_n_from_exponents)
*
*/
SECStatus
@@ -682,35 +754,35 @@ RSA_PopulatePrivateKey(RSAPrivateKey *key)
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) );
-
+ 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;
+ 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;
- }
+ needPublicExponent = PR_FALSE;
+ }
if (key->privateExponent.data) {
SECITEM_TO_MPINT(key->privateExponent, &d);
- needPrivateExponent = PR_FALSE;
+ needPrivateExponent = PR_FALSE;
}
if (needPrivateExponent && needPublicExponent) {
- /* Not enough information, we need at least one exponent */
- err = MP_BADARG;
- goto cleanup;
+ /* 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
@@ -718,74 +790,75 @@ RSA_PopulatePrivateKey(RSAPrivateKey *key)
* 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 * PR_BITS_PER_BYTE;
+ int primeLen = key->prime1.len;
+ if (key->prime1.data[0] == 0) {
+ primeLen--;
+ }
+ keySizeInBits = primeLen * 2 * PR_BITS_PER_BYTE;
SECITEM_TO_MPINT(key->prime1, &p);
- prime_count++;
+ prime_count++;
}
if (key->prime2.data) {
- int primeLen = key->prime2.len;
- if (key->prime2.data[0] == 0) {
- primeLen--;
- }
- keySizeInBits = primeLen * 2 * PR_BITS_PER_BYTE;
+ int primeLen = key->prime2.len;
+ if (key->prime2.data[0] == 0) {
+ primeLen--;
+ }
+ keySizeInBits = primeLen * 2 * PR_BITS_PER_BYTE;
SECITEM_TO_MPINT(key->prime2, prime_count ? &q : &p);
- prime_count++;
+ prime_count++;
}
/* load up the modulus */
if (key->modulus.data) {
- int modLen = key->modulus.len;
- if (key->modulus.data[0] == 0) {
- modLen--;
- }
- keySizeInBits = modLen * PR_BITS_PER_BYTE;
- SECITEM_TO_MPINT(key->modulus, &n);
- hasModulus = PR_TRUE;
+ int modLen = key->modulus.len;
+ if (key->modulus.data[0] == 0) {
+ modLen--;
+ }
+ keySizeInBits = modLen * PR_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 (mp_div(&n, &p, &q, &r) != MP_OKAY || 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;
- }
- }
-
- /* Assure p > q */
- /* NOTE: PKCS #1 does not require p > q, and NSS doesn't use any
+ /* 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)) {
+ CHECK_MPI_OK(rsa_get_prime_from_exponents(&e, &d, &p, &q, &n,
+ keySizeInBits));
+ } else if (!needPublicExponent && !needPrivateExponent && hasModulus) {
+ CHECK_MPI_OK(rsa_factorize_n_from_exponents(&e, &d, &p, &q, &n));
+ } else {
+ /* not enough given parameters to get both primes */
+ err = MP_BADARG;
+ goto cleanup;
+ }
+ }
+
+ /* Assure p > q */
+ /* NOTE: PKCS #1 does not require p > q, and NSS doesn't use any
* implementation optimization that requires p > q. We can remove
* this code in the future.
*/
- if (mp_cmp(&p, &q) < 0)
- mp_exch(&p, &q);
+ if (mp_cmp(&p, &q) < 0)
+ mp_exch(&p, &q);
- /* we now have our 2 primes and at least one exponent, we can fill
+ /* 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);
+ rv = rsa_build_from_primes(&p, &q,
+ &e, needPublicExponent,
+ &d, needPrivateExponent,
+ key, keySizeInBits);
cleanup:
mp_clear(&p);
mp_clear(&q);
@@ -794,12 +867,12 @@ cleanup:
mp_clear(&n);
mp_clear(&r);
if (err) {
- MP_TO_SEC_ERROR(err);
- rv = SECFailure;
+ MP_TO_SEC_ERROR(err);
+ rv = SECFailure;
}
if (rv && arena) {
- PORT_FreeArena(arena, PR_TRUE);
- key->arena = NULL;
+ PORT_FreeArena(arena, PR_TRUE);
+ key->arena = NULL;
}
return rv;
}
@@ -813,45 +886,45 @@ rsa_modulusLen(SECItem *modulus)
}
/*
-** Perform a raw public-key operation
-** Length of input and output buffers are equal to key's modulus len.
+** 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,
+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;
+ mp_err err = MP_OKAY;
SECStatus rv = SECSuccess;
if (!key || !output || !input) {
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- return SECFailure;
+ 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) );
+ 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;
+ 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;
+ /* 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 */
@@ -861,26 +934,27 @@ RSA_PublicKeyOp(RSAPublicKey *key,
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 */
+ 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) );
+ CHECK_MPI_OK(mp_exptmod_d(&m, MP_DIGIT(&e, 0), &n, &c));
} else
#endif
- CHECK_MPI_OK( mp_exptmod(&m, &e, &n, &c) );
+ 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;
+ 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;
+ MP_TO_SEC_ERROR(err);
+ rv = SECFailure;
}
return rv;
}
@@ -888,23 +962,23 @@ cleanup:
/*
** RSA Private key operation (no CRT).
*/
-static SECStatus
+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;
+ mp_err err = MP_OKAY;
SECStatus rv = SECSuccess;
MP_DIGITS(&d) = 0;
- CHECK_MPI_OK( mp_init(&d) );
+ 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) );
+ CHECK_MPI_OK(mp_exptmod(c, &d, n, m));
cleanup:
mp_clear(&d);
if (err) {
- MP_TO_SEC_ERROR(err);
- rv = SECFailure;
+ MP_TO_SEC_ERROR(err);
+ rv = SECFailure;
}
return rv;
}
@@ -912,49 +986,49 @@ cleanup:
/*
** RSA Private key operation using CRT.
*/
-static SECStatus
+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;
+ 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(&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(&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) );
+ 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->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) );
+ 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) );
+ 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) );
+ 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) );
+ CHECK_MPI_OK(mp_mul(&h, &q, m));
+ CHECK_MPI_OK(mp_add(m, &m2, m));
cleanup:
mp_clear(&p);
mp_clear(&q);
@@ -966,8 +1040,8 @@ cleanup:
mp_clear(&h);
mp_clear(&ctmp);
if (err) {
- MP_TO_SEC_ERROR(err);
- rv = SECFailure;
+ MP_TO_SEC_ERROR(err);
+ rv = SECFailure;
}
return rv;
}
@@ -977,54 +1051,54 @@ cleanup:
** "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.
+** 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
+static SECStatus
rsa_PrivateKeyOpCRTCheckedPubKey(RSAPrivateKey *key, mp_int *m, mp_int *c)
{
mp_int n, e, v;
- mp_err err = MP_OKAY;
+ 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);
+ 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) );
+ CHECK_MPI_OK(mp_exptmod(m, &e, &n, &v));
if (mp_cmp(&v, c) != 0) {
- rv = SECFailure;
+ rv = SECFailure;
}
cleanup:
mp_clear(&n);
mp_clear(&e);
mp_clear(&v);
if (err) {
- MP_TO_SEC_ERROR(err);
- rv = SECFailure;
+ MP_TO_SEC_ERROR(err);
+ rv = SECFailure;
}
return rv;
}
static PRCallOnceType coBPInit = { 0, 0, 0 };
-static PRStatus
+static PRStatus
init_blinding_params_list(void)
{
blindingParamsList.lock = PZ_NewLock(nssILockOther);
if (!blindingParamsList.lock) {
- PORT_SetError(SEC_ERROR_NO_MEMORY);
- return PR_FAILURE;
+ PORT_SetError(SEC_ERROR_NO_MEMORY);
+ return PR_FAILURE;
}
- blindingParamsList.cVar = PR_NewCondVar( blindingParamsList.lock );
+ blindingParamsList.cVar = PR_NewCondVar(blindingParamsList.lock);
if (!blindingParamsList.cVar) {
- PORT_SetError(SEC_ERROR_NO_MEMORY);
- return PR_FAILURE;
+ PORT_SetError(SEC_ERROR_NO_MEMORY);
+ return PR_FAILURE;
}
blindingParamsList.waitCount = 0;
PR_INIT_CLIST(&blindingParamsList.head);
@@ -1032,7 +1106,7 @@ init_blinding_params_list(void)
}
static SECStatus
-generate_blinding_params(RSAPrivateKey *key, mp_int* f, mp_int* g, mp_int *n,
+generate_blinding_params(RSAPrivateKey *key, mp_int *f, mp_int *g, mp_int *n,
unsigned int modLen)
{
SECStatus rv = SECSuccess;
@@ -1042,31 +1116,31 @@ generate_blinding_params(RSAPrivateKey *key, mp_int* f, mp_int* g, mp_int *n,
MP_DIGITS(&e) = 0;
MP_DIGITS(&k) = 0;
- CHECK_MPI_OK( mp_init(&e) );
- CHECK_MPI_OK( mp_init(&k) );
+ 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;
+ 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) );
+ 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) );
+ CHECK_MPI_OK(mp_mod(&k, n, &k));
/* f = k**e mod n */
- CHECK_MPI_OK( mp_exptmod(&k, &e, n, f) );
+ CHECK_MPI_OK(mp_exptmod(&k, &e, n, f));
/* g = k**-1 mod n */
- CHECK_MPI_OK( mp_invmod(&k, n, g) );
+ CHECK_MPI_OK(mp_invmod(&k, n, g));
cleanup:
if (kb)
- PORT_ZFree(kb, modLen);
+ PORT_ZFree(kb, modLen);
mp_clear(&k);
mp_clear(&e);
if (err) {
- MP_TO_SEC_ERROR(err);
- rv = SECFailure;
+ MP_TO_SEC_ERROR(err);
+ rv = SECFailure;
}
return rv;
}
@@ -1075,207 +1149,206 @@ static SECStatus
init_blinding_params(RSABlindingParams *rsabp, RSAPrivateKey *key,
mp_int *n, unsigned int modLen)
{
- blindingParams * bp = rsabp->array;
+ 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;
+ 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
- */
+ * 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;
+
+ 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;
+ return SECITEM_CopyItem(NULL, &rsabp->modulus, &key->modulus);
}
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;
- PRCList *el;
- SECStatus rv = SECSuccess;
- mp_err err = MP_OKAY;
- int cmp = -1;
- PRBool holdingLock = PR_FALSE;
+ RSABlindingParams *rsabp = NULL;
+ blindingParams *bpUnlinked = NULL;
+ blindingParams *bp;
+ 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. */
- 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;
+ 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. */
+ 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;
+ (void)holdingLock;
+ /* 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;
+ (void)holdingLock;
} 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_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;
+ PZ_Unlock(blindingParamsList.lock);
}
if (err) {
- MP_TO_SEC_ERROR(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.
+** 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,
+static SECStatus
+rsa_PrivateKeyOp(RSAPrivateKey *key,
+ unsigned char *output,
const unsigned char *input,
PRBool check)
{
@@ -1286,57 +1359,58 @@ rsa_PrivateKeyOp(RSAPrivateKey *key,
mp_int n, c, m;
mp_int f, g;
if (!key || !output || !input) {
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- return SECFailure;
+ 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;
+ 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) );
+ 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) );
+ 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) );
+ 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) );
+ CHECK_SEC_OK(rsa_PrivateKeyOpCRTCheckedPubKey(key, &m, &c));
} else {
- CHECK_SEC_OK( rsa_PrivateKeyOpCRTNoCheck(key, &m, &c) );
+ 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) );
+ /* 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;
+ if (err >= 0)
+ err = MP_OKAY;
cleanup:
mp_clear(&n);
mp_clear(&c);
@@ -1344,23 +1418,23 @@ cleanup:
mp_clear(&f);
mp_clear(&g);
if (err) {
- MP_TO_SEC_ERROR(err);
- rv = SECFailure;
+ MP_TO_SEC_ERROR(err);
+ rv = SECFailure;
}
return rv;
}
-SECStatus
-RSA_PrivateKeyOp(RSAPrivateKey *key,
- unsigned char *output,
+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,
+SECStatus
+RSA_PrivateKeyOpDoubleChecked(RSAPrivateKey *key,
+ unsigned char *output,
const unsigned char *input)
{
return rsa_PrivateKeyOp(key, output, input, PR_TRUE);
@@ -1370,30 +1444,30 @@ SECStatus
RSA_PrivateKeyCheck(const RSAPrivateKey *key)
{
mp_int p, q, n, psub1, qsub1, e, d, d_p, d_q, qInv, res;
- mp_err err = MP_OKAY;
+ 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(&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) );
+ 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));
if (!key->modulus.data || !key->prime1.data || !key->prime2.data ||
!key->publicExponent.data || !key->privateExponent.data ||
@@ -1405,54 +1479,54 @@ RSA_PrivateKeyCheck(const RSAPrivateKey *key)
goto cleanup;
}
- 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->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);
+ SECITEM_TO_MPINT(key->exponent1, &d_p);
+ SECITEM_TO_MPINT(key->exponent2, &d_q);
+ SECITEM_TO_MPINT(key->coefficient, &qInv);
/* p and q must be distinct. */
if (mp_cmp(&p, &q) == 0) {
- rv = SECFailure;
- goto cleanup;
+ rv = SECFailure;
+ goto cleanup;
}
#define VERIFY_MPI_EQUAL(m1, m2) \
if (mp_cmp(m1, m2) != 0) { \
- rv = SECFailure; \
- goto cleanup; \
+ rv = SECFailure; \
+ goto cleanup; \
}
-#define VERIFY_MPI_EQUAL_1(m) \
- if (mp_cmp_d(m, 1) != 0) { \
- rv = SECFailure; \
- goto cleanup; \
+#define VERIFY_MPI_EQUAL_1(m) \
+ if (mp_cmp_d(m, 1) != 0) { \
+ rv = SECFailure; \
+ goto cleanup; \
}
/* n == p * q */
- CHECK_MPI_OK( mp_mul(&p, &q, &res) );
+ 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) );
+ 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) );
+ 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) );
+ 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) );
+ CHECK_MPI_OK(mp_mulmod(&d, &e, &qsub1, &res));
VERIFY_MPI_EQUAL_1(&res);
/* d_p == d mod p-1 */
- CHECK_MPI_OK( mp_mod(&d, &psub1, &res) );
+ CHECK_MPI_OK(mp_mod(&d, &psub1, &res));
VERIFY_MPI_EQUAL(&res, &d_p);
/* d_q == d mod q-1 */
- CHECK_MPI_OK( mp_mod(&d, &qsub1, &res) );
+ CHECK_MPI_OK(mp_mod(&d, &qsub1, &res));
VERIFY_MPI_EQUAL(&res, &d_q);
/* q * q**-1 == 1 mod p */
- CHECK_MPI_OK( mp_mulmod(&q, &qInv, &p, &res) );
+ CHECK_MPI_OK(mp_mulmod(&q, &qInv, &p, &res));
VERIFY_MPI_EQUAL_1(&res);
cleanup:
@@ -1468,13 +1542,14 @@ cleanup:
mp_clear(&qInv);
mp_clear(&res);
if (err) {
- MP_TO_SEC_ERROR(err);
- rv = SECFailure;
+ MP_TO_SEC_ERROR(err);
+ rv = SECFailure;
}
return rv;
}
-static SECStatus RSA_Init(void)
+static SECStatus
+RSA_Init(void)
{
if (PR_CallOnce(&coBPInit, init_blinding_params_list) != PR_SUCCESS) {
PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
@@ -1483,41 +1558,43 @@ static SECStatus RSA_Init(void)
return SECSuccess;
}
-SECStatus BL_Init(void)
+SECStatus
+BL_Init(void)
{
return RSA_Init();
}
/* cleanup at shutdown */
-void RSA_Cleanup(void)
+void
+RSA_Cleanup(void)
{
- blindingParams * bp = NULL;
+ blindingParams *bp = NULL;
if (!coBPInit.initialized)
- return;
+ 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);
+ 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;
+ PR_DestroyCondVar(blindingParamsList.cVar);
+ blindingParamsList.cVar = NULL;
}
if (blindingParamsList.lock) {
- SKIP_AFTER_FORK(PZ_DestroyLock(blindingParamsList.lock));
- blindingParamsList.lock = NULL;
+ SKIP_AFTER_FORK(PZ_DestroyLock(blindingParamsList.lock));
+ blindingParamsList.lock = NULL;
}
coBPInit.initialized = 0;
@@ -1530,7 +1607,8 @@ void RSA_Cleanup(void)
* 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)
+void
+BL_Cleanup(void)
{
RSA_Cleanup();
}
@@ -1540,8 +1618,8 @@ PRBool bl_parentForkedAfterC_Initialize;
/*
* Set fork flag so it can be tested in SKIP_AFTER_FORK on relevant platforms.
*/
-void BL_SetForkState(PRBool forked)
+void
+BL_SetForkState(PRBool forked)
{
bl_parentForkedAfterC_Initialize = forked;
}
-
diff --git a/nss/lib/freebl/rsapkcs.c b/nss/lib/freebl/rsapkcs.c
index c1e3d54..577fe1f 100644
--- a/nss/lib/freebl/rsapkcs.c
+++ b/nss/lib/freebl/rsapkcs.c
@@ -16,10 +16,10 @@
#include "secitem.h"
#include "blapii.h"
-#define RSA_BLOCK_MIN_PAD_LEN 8
-#define RSA_BLOCK_FIRST_OCTET 0x00
-#define RSA_BLOCK_PRIVATE_PAD_OCTET 0xff
-#define RSA_BLOCK_AFTER_PAD_OCTET 0x00
+#define RSA_BLOCK_MIN_PAD_LEN 8
+#define RSA_BLOCK_FIRST_OCTET 0x00
+#define RSA_BLOCK_PRIVATE_PAD_OCTET 0xff
+#define RSA_BLOCK_AFTER_PAD_OCTET 0x00
/*
* RSA block types
@@ -29,9 +29,9 @@
* the value that NSS has been using in the past.
*/
typedef enum {
- 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_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_BlockType;
/* Needed for RSA-PSS functions */
@@ -41,7 +41,9 @@ static const unsigned char eightZeros[] = { 0, 0, 0, 0, 0, 0, 0, 0 };
* 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) {
+static unsigned char
+constantTimeEQ8(unsigned char a, unsigned char b)
+{
unsigned char c = ~((a - b) | (b - a));
c >>= 7;
return c;
@@ -51,9 +53,11 @@ static unsigned char constantTimeEQ8(unsigned char a, unsigned char b) {
* 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) {
+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)
@@ -65,15 +69,16 @@ static unsigned char constantTimeCompare(const unsigned char *a,
* 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)
+static unsigned int
+constantTimeCondition(unsigned int c,
+ unsigned int a,
+ unsigned int b)
{
return (~(c - 1) & a) | ((c - 1) & b);
}
static unsigned int
-rsa_modulusLen(SECItem * modulus)
+rsa_modulusLen(SECItem *modulus)
{
unsigned char byteZero = modulus->data[0];
unsigned int modLen = modulus->len - !byteZero;
@@ -87,7 +92,7 @@ rsa_modulusLen(SECItem * modulus)
static unsigned char *
rsa_FormatOneBlock(unsigned modulusLen,
RSA_BlockType blockType,
- SECItem * data)
+ SECItem *data)
{
unsigned char *block;
unsigned char *bp;
@@ -95,7 +100,7 @@ rsa_FormatOneBlock(unsigned modulusLen,
int i, j;
SECStatus rv;
- block = (unsigned char *) PORT_Alloc(modulusLen);
+ block = (unsigned char *)PORT_Alloc(modulusLen);
if (block == NULL)
return NULL;
@@ -103,146 +108,146 @@ rsa_FormatOneBlock(unsigned modulusLen,
/*
* All RSA blocks start with two octets:
- * 0x00 || BlockType
+ * 0x00 || BlockType
*/
*bp++ = RSA_BLOCK_FIRST_OCTET;
- *bp++ = (unsigned char) blockType;
+ *bp++ = (unsigned char)blockType;
switch (blockType) {
- /*
+ /*
* Blocks intended for private-key operation.
*/
- case RSA_BlockPrivate: /* preferred method */
- /*
+ 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, 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:
+ 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, RSA_BLOCK_PRIVATE_PAD_OCTET, padLen);
+ bp += padLen;
+ *bp++ = RSA_BLOCK_AFTER_PAD_OCTET;
+ PORT_Memcpy(bp, data->data, data->len);
+ break;
+
/*
- * 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.
+ * Blocks intended for public-key operation.
*/
- 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;
+ 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) {
+ if (rv != SECSuccess) {
+ PORT_Free(block);
+ PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
+ 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);
- PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
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,
+rsa_FormatBlock(SECItem *result,
unsigned modulusLen,
RSA_BlockType blockType,
- SECItem * data)
+ SECItem *data)
{
switch (blockType) {
- 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)));
+ 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;
- result->data = rsa_FormatOneBlock(modulusLen, blockType, data);
- if (result->data == NULL) {
- result->len = 0;
- return SECFailure;
- }
- result->len = modulusLen;
+ break;
- 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;
- case RSA_BlockRaw:
- /*
- * Pad || ActualData
- * Pad is zeros. The application is responsible for recovering
- * the actual data.
- */
- if (data->len > modulusLen ) {
+ default:
+ PORT_Assert(0);
+ result->data = NULL;
+ result->len = 0;
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;
@@ -253,18 +258,18 @@ rsa_FormatBlock(SECItem * result,
*/
static SECStatus
MGF1(HASH_HashType hashAlg,
- unsigned char * mask,
+ unsigned char *mask,
unsigned int maskLen,
- const unsigned char * mgfSeed,
+ const unsigned char *mgfSeed,
unsigned int mgfSeedLen)
{
unsigned int digestLen;
PRUint32 counter;
PRUint32 rounds;
- unsigned char * tempHash;
- unsigned char * temp;
- const SECHashObject * hash;
- void * hashContext;
+ unsigned char *tempHash;
+ unsigned char *temp;
+ const SECHashObject *hash;
+ void *hashContext;
unsigned char C[4];
hash = HASH_GetRawHashObject(hashAlg);
@@ -302,11 +307,11 @@ MGF1(HASH_HashType hashAlg,
/* XXX Doesn't set error code */
SECStatus
-RSA_SignRaw(RSAPrivateKey * key,
- unsigned char * output,
- unsigned int * outputLen,
+RSA_SignRaw(RSAPrivateKey *key,
+ unsigned char *output,
+ unsigned int *outputLen,
unsigned int maxOutputLen,
- const unsigned char * data,
+ const unsigned char *data,
unsigned int dataLen)
{
SECStatus rv = SECSuccess;
@@ -317,9 +322,9 @@ RSA_SignRaw(RSAPrivateKey * key,
if (maxOutputLen < modulusLen)
return SECFailure;
- unformatted.len = dataLen;
- unformatted.data = (unsigned char*)data;
- formatted.data = NULL;
+ unformatted.len = dataLen;
+ unformatted.data = (unsigned char *)data;
+ formatted.data = NULL;
rv = rsa_FormatBlock(&formatted, modulusLen, RSA_BlockRaw, &unformatted);
if (rv != SECSuccess)
goto done;
@@ -335,15 +340,15 @@ done:
/* XXX Doesn't set error code */
SECStatus
-RSA_CheckSignRaw(RSAPublicKey * key,
- const unsigned char * sig,
+RSA_CheckSignRaw(RSAPublicKey *key,
+ const unsigned char *sig,
unsigned int sigLen,
- const unsigned char * hash,
+ const unsigned char *hash,
unsigned int hashLen)
{
SECStatus rv;
unsigned int modulusLen = rsa_modulusLen(&key->modulus);
- unsigned char * buffer;
+ unsigned char *buffer;
if (sigLen != modulusLen)
goto failure;
@@ -377,11 +382,11 @@ failure:
/* XXX Doesn't set error code */
SECStatus
-RSA_CheckSignRecoverRaw(RSAPublicKey * key,
- unsigned char * data,
- unsigned int * dataLen,
+RSA_CheckSignRecoverRaw(RSAPublicKey *key,
+ unsigned char *data,
+ unsigned int *dataLen,
unsigned int maxDataLen,
- const unsigned char * sig,
+ const unsigned char *sig,
unsigned int sigLen)
{
SECStatus rv;
@@ -405,11 +410,11 @@ failure:
/* XXX Doesn't set error code */
SECStatus
-RSA_EncryptRaw(RSAPublicKey * key,
- unsigned char * output,
- unsigned int * outputLen,
+RSA_EncryptRaw(RSAPublicKey *key,
+ unsigned char *output,
+ unsigned int *outputLen,
unsigned int maxOutputLen,
- const unsigned char * input,
+ const unsigned char *input,
unsigned int inputLen)
{
SECStatus rv;
@@ -421,9 +426,9 @@ RSA_EncryptRaw(RSAPublicKey * key,
if (maxOutputLen < modulusLen)
goto failure;
- unformatted.len = inputLen;
- unformatted.data = (unsigned char*)input;
- formatted.data = NULL;
+ unformatted.len = inputLen;
+ unformatted.data = (unsigned char *)input;
+ formatted.data = NULL;
rv = rsa_FormatBlock(&formatted, modulusLen, RSA_BlockRaw, &unformatted);
if (rv != SECSuccess)
goto failure;
@@ -444,11 +449,11 @@ failure:
/* XXX Doesn't set error code */
SECStatus
-RSA_DecryptRaw(RSAPrivateKey * key,
- unsigned char * output,
- unsigned int * outputLen,
+RSA_DecryptRaw(RSAPrivateKey *key,
+ unsigned char *output,
+ unsigned int *outputLen,
unsigned int maxOutputLen,
- const unsigned char * input,
+ const unsigned char *input,
unsigned int inputLen)
{
SECStatus rv;
@@ -480,25 +485,25 @@ failure:
* output and outputLen.
*/
static SECStatus
-eme_oaep_decode(unsigned char * output,
- unsigned int * outputLen,
+eme_oaep_decode(unsigned char *output,
+ unsigned int *outputLen,
unsigned int maxOutputLen,
- const unsigned char * input,
+ const unsigned char *input,
unsigned int inputLen,
HASH_HashType hashAlg,
HASH_HashType maskHashAlg,
- const unsigned char * label,
+ const unsigned char *label,
unsigned int labelLen)
{
- const SECHashObject * hash;
- void * hashContext;
+ const SECHashObject *hash;
+ void *hashContext;
SECStatus rv = SECFailure;
unsigned char labelHash[HASH_LENGTH_MAX];
unsigned int i;
unsigned int maskLen;
unsigned int paddingOffset;
- unsigned char * mask = NULL;
- unsigned char * tmpOutput = NULL;
+ unsigned char *mask = NULL;
+ unsigned char *tmpOutput = NULL;
unsigned char isGood;
unsigned char foundPaddingEnd;
@@ -522,14 +527,14 @@ eme_oaep_decode(unsigned char * output,
(*hash->end)(hashContext, labelHash, &i, sizeof(labelHash));
(*hash->destroy)(hashContext, PR_TRUE);
- tmpOutput = (unsigned char*)PORT_Alloc(inputLen);
+ 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);
+ mask = (unsigned char *)PORT_Alloc(maskLen);
if (mask == NULL) {
PORT_SetError(SEC_ERROR_NO_MEMORY);
goto done;
@@ -639,21 +644,21 @@ done:
* label is the optional value L to be associated with the message.
*/
static SECStatus
-eme_oaep_encode(unsigned char * em,
+eme_oaep_encode(unsigned char *em,
unsigned int emLen,
- const unsigned char * input,
+ const unsigned char *input,
unsigned int inputLen,
HASH_HashType hashAlg,
HASH_HashType maskHashAlg,
- const unsigned char * label,
+ const unsigned char *label,
unsigned int labelLen,
- const unsigned char * seed,
+ const unsigned char *seed,
unsigned int seedLen)
{
- const SECHashObject * hash;
- void * hashContext;
+ const SECHashObject *hash;
+ void *hashContext;
SECStatus rv;
- unsigned char * mask;
+ unsigned char *mask;
unsigned int reservedLen;
unsigned int dbMaskLen;
unsigned int i;
@@ -732,7 +737,7 @@ eme_oaep_encode(unsigned char * em,
/* Step 2.e - Generate dbMask*/
dbMaskLen = emLen - hash->length - 1;
- mask = (unsigned char*)PORT_Alloc(dbMaskLen);
+ mask = (unsigned char *)PORT_Alloc(dbMaskLen);
if (mask == NULL) {
PORT_SetError(SEC_ERROR_NO_MEMORY);
return SECFailure;
@@ -753,22 +758,22 @@ eme_oaep_encode(unsigned char * em,
}
SECStatus
-RSA_EncryptOAEP(RSAPublicKey * key,
+RSA_EncryptOAEP(RSAPublicKey *key,
HASH_HashType hashAlg,
HASH_HashType maskHashAlg,
- const unsigned char * label,
+ const unsigned char *label,
unsigned int labelLen,
- const unsigned char * seed,
+ const unsigned char *seed,
unsigned int seedLen,
- unsigned char * output,
- unsigned int * outputLen,
+ unsigned char *output,
+ unsigned int *outputLen,
unsigned int maxOutputLen,
- const unsigned char * input,
+ const unsigned char *input,
unsigned int inputLen)
{
SECStatus rv = SECFailure;
unsigned int modulusLen = rsa_modulusLen(&key->modulus);
- unsigned char * oaepEncoded = NULL;
+ unsigned char *oaepEncoded = NULL;
if (maxOutputLen < modulusLen) {
PORT_SetError(SEC_ERROR_OUTPUT_LEN);
@@ -807,20 +812,20 @@ done:
}
SECStatus
-RSA_DecryptOAEP(RSAPrivateKey * key,
+RSA_DecryptOAEP(RSAPrivateKey *key,
HASH_HashType hashAlg,
HASH_HashType maskHashAlg,
- const unsigned char * label,
+ const unsigned char *label,
unsigned int labelLen,
- unsigned char * output,
- unsigned int * outputLen,
+ unsigned char *output,
+ unsigned int *outputLen,
unsigned int maxOutputLen,
- const unsigned char * input,
+ const unsigned char *input,
unsigned int inputLen)
{
SECStatus rv = SECFailure;
unsigned int modulusLen = rsa_modulusLen(&key->modulus);
- unsigned char * oaepEncoded = NULL;
+ unsigned char *oaepEncoded = NULL;
if ((hashAlg == HASH_AlgNULL) || (maskHashAlg == HASH_AlgNULL)) {
PORT_SetError(SEC_ERROR_INVALID_ALGORITHM);
@@ -860,11 +865,11 @@ done:
/* XXX Doesn't set error code */
SECStatus
-RSA_EncryptBlock(RSAPublicKey * key,
- unsigned char * output,
- unsigned int * outputLen,
+RSA_EncryptBlock(RSAPublicKey *key,
+ unsigned char *output,
+ unsigned int *outputLen,
unsigned int maxOutputLen,
- const unsigned char * input,
+ const unsigned char *input,
unsigned int inputLen)
{
SECStatus rv;
@@ -876,9 +881,9 @@ RSA_EncryptBlock(RSAPublicKey * key,
if (maxOutputLen < modulusLen)
goto failure;
- unformatted.len = inputLen;
- unformatted.data = (unsigned char*)input;
- formatted.data = NULL;
+ unformatted.len = inputLen;
+ unformatted.data = (unsigned char *)input;
+ formatted.data = NULL;
rv = rsa_FormatBlock(&formatted, modulusLen, RSA_BlockPublic,
&unformatted);
if (rv != SECSuccess)
@@ -900,17 +905,17 @@ failure:
/* XXX Doesn't set error code */
SECStatus
-RSA_DecryptBlock(RSAPrivateKey * key,
- unsigned char * output,
- unsigned int * outputLen,
+RSA_DecryptBlock(RSAPrivateKey *key,
+ unsigned char *output,
+ unsigned int *outputLen,
unsigned int maxOutputLen,
- const unsigned char * input,
+ const unsigned char *input,
unsigned int inputLen)
{
SECStatus rv;
unsigned int modulusLen = rsa_modulusLen(&key->modulus);
unsigned int i;
- unsigned char * buffer;
+ unsigned char *buffer;
if (inputLen != modulusLen)
goto failure;
@@ -961,17 +966,17 @@ failure:
* NOTE: this code assumes modBits is a multiple of 8.
*/
static SECStatus
-emsa_pss_encode(unsigned char * em,
+emsa_pss_encode(unsigned char *em,
unsigned int emLen,
- const unsigned char * mHash,
+ const unsigned char *mHash,
HASH_HashType hashAlg,
HASH_HashType maskHashAlg,
- const unsigned char * salt,
+ const unsigned char *salt,
unsigned int saltLen)
{
- const SECHashObject * hash;
- void * hash_context;
- unsigned char * dbMask;
+ const SECHashObject *hash;
+ void *hash_context;
+ unsigned char *dbMask;
unsigned int dbMaskLen;
unsigned int i;
SECStatus rv;
@@ -1045,17 +1050,17 @@ emsa_pss_encode(unsigned char * em,
* NOTE: this code assumes modBits is a multiple of 8.
*/
static SECStatus
-emsa_pss_verify(const unsigned char * mHash,
- const unsigned char * em,
+emsa_pss_verify(const unsigned char *mHash,
+ const unsigned char *em,
unsigned int emLen,
HASH_HashType hashAlg,
HASH_HashType maskHashAlg,
unsigned int saltLen)
{
- const SECHashObject * hash;
- void * hash_context;
- unsigned char * db;
- unsigned char * H_; /* H' from the RFC */
+ const SECHashObject *hash;
+ void *hash_context;
+ unsigned char *db;
+ unsigned char *H_; /* H' from the RFC */
unsigned int i;
unsigned int dbMaskLen;
SECStatus rv;
@@ -1138,15 +1143,15 @@ emsa_pss_verify(const unsigned char * mHash,
}
SECStatus
-RSA_SignPSS(RSAPrivateKey * key,
+RSA_SignPSS(RSAPrivateKey *key,
HASH_HashType hashAlg,
HASH_HashType maskHashAlg,
- const unsigned char * salt,
+ const unsigned char *salt,
unsigned int saltLength,
- unsigned char * output,
- unsigned int * outputLen,
+ unsigned char *output,
+ unsigned int *outputLen,
unsigned int maxOutputLen,
- const unsigned char * input,
+ const unsigned char *input,
unsigned int inputLen)
{
SECStatus rv = SECSuccess;
@@ -1182,18 +1187,18 @@ done:
}
SECStatus
-RSA_CheckSignPSS(RSAPublicKey * key,
+RSA_CheckSignPSS(RSAPublicKey *key,
HASH_HashType hashAlg,
HASH_HashType maskHashAlg,
unsigned int saltLength,
- const unsigned char * sig,
+ const unsigned char *sig,
unsigned int sigLen,
- const unsigned char * hash,
+ const unsigned char *hash,
unsigned int hashLen)
{
SECStatus rv;
unsigned int modulusLen = rsa_modulusLen(&key->modulus);
- unsigned char * buffer;
+ unsigned char *buffer;
if (sigLen != modulusLen) {
PORT_SetError(SEC_ERROR_BAD_SIGNATURE);
@@ -1227,11 +1232,11 @@ RSA_CheckSignPSS(RSAPublicKey * key,
/* XXX Doesn't set error code */
SECStatus
-RSA_Sign(RSAPrivateKey * key,
- unsigned char * output,
- unsigned int * outputLen,
+RSA_Sign(RSAPrivateKey *key,
+ unsigned char *output,
+ unsigned int *outputLen,
unsigned int maxOutputLen,
- const unsigned char * input,
+ const unsigned char *input,
unsigned int inputLen)
{
SECStatus rv = SECSuccess;
@@ -1242,9 +1247,9 @@ RSA_Sign(RSAPrivateKey * key,
if (maxOutputLen < modulusLen)
return SECFailure;
- unformatted.len = inputLen;
- unformatted.data = (unsigned char*)input;
- formatted.data = NULL;
+ unformatted.len = inputLen;
+ unformatted.data = (unsigned char *)input;
+ formatted.data = NULL;
rv = rsa_FormatBlock(&formatted, modulusLen, RSA_BlockPrivate,
&unformatted);
if (rv != SECSuccess)
@@ -1263,16 +1268,16 @@ done:
/* XXX Doesn't set error code */
SECStatus
-RSA_CheckSign(RSAPublicKey * key,
- const unsigned char * sig,
+RSA_CheckSign(RSAPublicKey *key,
+ const unsigned char *sig,
unsigned int sigLen,
- const unsigned char * data,
+ const unsigned char *data,
unsigned int dataLen)
{
SECStatus rv;
unsigned int modulusLen = rsa_modulusLen(&key->modulus);
unsigned int i;
- unsigned char * buffer;
+ unsigned char *buffer;
if (sigLen != modulusLen)
goto failure;
@@ -1324,17 +1329,17 @@ failure:
/* XXX Doesn't set error code */
SECStatus
-RSA_CheckSignRecover(RSAPublicKey * key,
- unsigned char * output,
- unsigned int * outputLen,
+RSA_CheckSignRecover(RSAPublicKey *key,
+ unsigned char *output,
+ unsigned int *outputLen,
unsigned int maxOutputLen,
- const unsigned char * sig,
+ const unsigned char *sig,
unsigned int sigLen)
{
SECStatus rv;
unsigned int modulusLen = rsa_modulusLen(&key->modulus);
unsigned int i;
- unsigned char * buffer;
+ unsigned char *buffer;
if (sigLen != modulusLen)
goto failure;
diff --git a/nss/lib/freebl/secmpi.h b/nss/lib/freebl/secmpi.h
index 92ab612..5e8fd11 100644
--- a/nss/lib/freebl/secmpi.h
+++ b/nss/lib/freebl/secmpi.h
@@ -4,9 +4,13 @@
#include "mpi.h"
-#define CHECK_SEC_OK(func) if (SECSuccess != (rv = func)) goto cleanup
+#define CHECK_SEC_OK(func) \
+ if (SECSuccess != (rv = func)) \
+ goto cleanup
-#define CHECK_MPI_OK(func) if (MP_OKAY > (err = 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))
@@ -15,18 +19,36 @@
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)
+ 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; \
+#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/nss/lib/freebl/secrng.h b/nss/lib/freebl/secrng.h
index e9e6dd2..19eae48 100644
--- a/nss/lib/freebl/secrng.h
+++ b/nss/lib/freebl/secrng.h
@@ -43,7 +43,7 @@ extern size_t RNG_GetNoise(void *buf, size_t maxbytes);
*/
extern void RNG_SystemInfoForRNG(void);
-/*
+/*
** Use the contents (and stat) of a file to help seed the
** global random number generator.
*/
diff --git a/nss/lib/freebl/seed.c b/nss/lib/freebl/seed.c
index 1e1639e..f198cce 100644
--- a/nss/lib/freebl/seed.c
+++ b/nss/lib/freebl/seed.c
@@ -17,350 +17,343 @@
#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
- }
+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)
+#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);
+ char2word(rawkey, K0);
+ char2word(rawkey + 4, K1);
+ char2word(rawkey + 8, K2);
+ char2word(rawkey + 12, K3);
t0 = (K0 + K2 - KC0);
- t1 = (K1 - K3 + KC0);
+ t1 = (K1 - K3 + KC0);
KEYUPDATE_TEMP(t0, t1, &ks->data[0]);
- KEYSCHEDULE_UPDATE1(t0, t1, K0, K1, K2, K3, KC1);
+ 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);
+ 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);
+ 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);
+ 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);
+ 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);
+ 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);
+ 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);
+ 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);
+ 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);
+ 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);
+ 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);
+ 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);
+ 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);
+ 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);
+ 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)
+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);
-
+ 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);
@@ -379,23 +372,24 @@ void SEED_encrypt(const unsigned char s[SEED_BLOCK_SIZE],
E_SEED(t0, t1, R0, R1, L0, L1, 30);
word2char(R0, d);
- word2char(R1, d+4);
- word2char(L0, d+8);
- word2char(L1, d+12);
+ 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)
+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);
-
+ 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);
@@ -414,14 +408,15 @@ void SEED_decrypt(const unsigned char s[SEED_BLOCK_SIZE],
E_SEED(t0, t1, R0, R1, L0, L1, 0);
word2char(R0, d);
- word2char(R1, d+4);
- word2char(L0, d+8);
- word2char(L1, d+12);
+ 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)
+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);
@@ -430,10 +425,10 @@ void SEED_ecb_encrypt(const unsigned char *in,
}
}
-
-void SEED_cbc_encrypt(const unsigned char *in, unsigned char *out,
- size_t len, const SEED_KEY_SCHEDULE *ks,
- unsigned char ivec[SEED_BLOCK_SIZE], int enc)
+void
+SEED_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];
@@ -447,7 +442,7 @@ void SEED_cbc_encrypt(const unsigned char *in, unsigned char *out,
SEED_encrypt(out, out, ks);
iv = out;
len -= SEED_BLOCK_SIZE;
- in += SEED_BLOCK_SIZE;
+ in += SEED_BLOCK_SIZE;
out += SEED_BLOCK_SIZE;
}
@@ -461,7 +456,7 @@ void SEED_cbc_encrypt(const unsigned char *in, unsigned char *out,
SEED_encrypt(out, out, ks);
iv = out;
}
-
+
memcpy(ivec, iv, SEED_BLOCK_SIZE);
} else if (in != out) {
while (len >= SEED_BLOCK_SIZE) {
@@ -472,10 +467,10 @@ void SEED_cbc_encrypt(const unsigned char *in, unsigned char *out,
iv = in;
len -= SEED_BLOCK_SIZE;
- in += SEED_BLOCK_SIZE;
+ in += SEED_BLOCK_SIZE;
out += SEED_BLOCK_SIZE;
}
-
+
if (len) {
SEED_decrypt(in, tmp, ks);
@@ -484,7 +479,7 @@ void SEED_cbc_encrypt(const unsigned char *in, unsigned char *out,
iv = in;
}
-
+
memcpy(ivec, iv, SEED_BLOCK_SIZE);
} else {
while (len >= SEED_BLOCK_SIZE) {
@@ -496,7 +491,7 @@ void SEED_cbc_encrypt(const unsigned char *in, unsigned char *out,
memcpy(ivec, tmp, SEED_BLOCK_SIZE);
len -= SEED_BLOCK_SIZE;
- in += SEED_BLOCK_SIZE;
+ in += SEED_BLOCK_SIZE;
out += SEED_BLOCK_SIZE;
}
@@ -518,45 +513,45 @@ 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)
+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);
+ 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;
+ 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,
+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);
+ SECStatus rv = SEED_InitContext(cx, key, SEED_KEY_LENGTH, iv, mode,
+ encrypt, 0);
if (rv != SECSuccess) {
PORT_ZFree(cx, sizeof *cx);
@@ -579,7 +574,7 @@ SEED_DestroyContext(SEEDContext *cx, PRBool freeit)
SECStatus
SEED_Encrypt(SEEDContext *cx, unsigned char *out, unsigned int *outLen,
- unsigned int maxOutLen, const unsigned char *in,
+ unsigned int maxOutLen, const unsigned char *in,
unsigned int inLen)
{
if (!cx) {
@@ -593,19 +588,19 @@ SEED_Encrypt(SEEDContext *cx, unsigned char *out, unsigned int *outLen,
}
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;
+ 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;
@@ -613,7 +608,7 @@ SEED_Encrypt(SEEDContext *cx, unsigned char *out, unsigned int *outLen,
SECStatus
SEED_Decrypt(SEEDContext *cx, unsigned char *out, unsigned int *outLen,
- unsigned int maxOutLen, const unsigned char *in,
+ unsigned int maxOutLen, const unsigned char *in,
unsigned int inLen)
{
if (!cx) {
@@ -627,20 +622,20 @@ SEED_Decrypt(SEEDContext *cx, unsigned char *out, unsigned int *outLen,
}
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;
+ 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/nss/lib/freebl/seed.h b/nss/lib/freebl/seed.h
index 8e09dbf..f527165 100644
--- a/nss/lib/freebl/seed.h
+++ b/nss/lib/freebl/seed.h
@@ -9,86 +9,85 @@
#include "blapi.h"
#if !defined(NO_SYS_TYPES_H)
-# include <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 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) \
+#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)); \
+ (((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)); \
+ (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)); \
+#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]; \
+#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]; \
+#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); \
+#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
+#ifdef __cplusplus
extern "C" {
#endif
@@ -96,8 +95,6 @@ typedef struct seed_key_st {
PRUint32 data[32];
} SEED_KEY_SCHEDULE;
-
-
struct SEEDContextStr {
unsigned char iv[SEED_BLOCK_SIZE];
SEED_KEY_SCHEDULE ks;
@@ -105,23 +102,23 @@ struct SEEDContextStr {
unsigned int encrypt;
};
-void SEED_set_key(const unsigned char rawkey[SEED_KEY_LENGTH],
+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],
+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],
+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,
+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,
+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
+#ifdef __cplusplus
}
#endif
diff --git a/nss/lib/freebl/sha256.h b/nss/lib/freebl/sha256.h
index 86bec7c..c65ca15 100644
--- a/nss/lib/freebl/sha256.h
+++ b/nss/lib/freebl/sha256.h
@@ -9,11 +9,11 @@
struct SHA256ContextStr {
union {
- PRUint32 w[64]; /* message schedule, input buffer, plus 48 words */
- PRUint8 b[256];
+ 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. */
+ PRUint32 h[8]; /* 8 state variables */
+ PRUint32 sizeHi, sizeLo; /* 64-bit count of hashed bytes. */
};
#endif /* _SHA_256_H_ */
diff --git a/nss/lib/freebl/sha512.c b/nss/lib/freebl/sha512.c
index 28e7c04..528f884 100644
--- a/nss/lib/freebl/sha512.c
+++ b/nss/lib/freebl/sha512.c
@@ -14,11 +14,11 @@
#define NOUNROLL512 1
#undef HAVE_LONG_LONG
#endif
-#include "prtypes.h" /* for PRUintXX */
+#include "prtypes.h" /* for PRUintXX */
#include "prlong.h"
-#include "secport.h" /* for PORT_XXX */
+#include "secport.h" /* for PORT_XXX */
#include "blapi.h"
-#include "sha256.h" /* for struct SHA256ContextStr */
+#include "sha256.h" /* for struct SHA256ContextStr */
/* ============= Common constants and defines ======================= */
@@ -26,44 +26,44 @@
#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)
+#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 */
+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,
+ 0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5,
0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5,
- 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3,
+ 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3,
0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174,
- 0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc,
+ 0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc,
0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,
- 0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7,
+ 0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7,
0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967,
- 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13,
+ 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13,
0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85,
- 0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3,
+ 0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3,
0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,
- 0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5,
+ 0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5,
0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3,
- 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208,
+ 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208,
0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2
};
/* SHA-256 initial hash values */
static const PRUint32 H256[8] = {
- 0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a,
+ 0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a,
0x510e527f, 0x9b05688c, 0x1f83d9ab, 0x5be0cd19
};
@@ -82,47 +82,53 @@ static const PRUint32 H256[8] = {
#endif
#define FASTCALL __fastcall
-static FORCEINLINE PRUint32 FASTCALL
-swap4b(PRUint32 dwd)
+static FORCEINLINE PRUint32 FASTCALL
+swap4b(PRUint32 dwd)
{
__asm {
- mov eax,dwd
- bswap eax
+ mov eax,dwd
+ bswap eax
}
}
#define SHA_HTONL(x) swap4b(x)
#elif defined(__GNUC__) && defined(NSS_X86_OR_X64)
-static __inline__ PRUint32 swap4b(PRUint32 value)
+static __inline__ PRUint32
+swap4b(PRUint32 value)
{
- __asm__("bswap %0" : "+r" (value));
+ __asm__("bswap %0"
+ : "+r"(value));
return (value);
}
#define SHA_HTONL(x) swap4b(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)
+#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));
+ __asm__("rev %0, %1"
+ : "=r"(ret)
+ : "r"(value));
return ret;
}
#define SHA_HTONL(x) swap4b(x)
#else
-#define SWAP4MASK 0x00FF00FF
-static PRUint32 swap4b(PRUint32 value)
+#define SWAP4MASK 0x00FF00FF
+static PRUint32
+swap4b(PRUint32 value)
{
PRUint32 t1 = (value << 16) | (value >> 16);
return ((t1 & SWAP4MASK) << 8) | ((t1 >> 8) & SWAP4MASK);
@@ -133,19 +139,19 @@ static PRUint32 swap4b(PRUint32 value)
#endif /* defined(IS_LITTLE_ENDIAN) */
#if defined(_MSC_VER)
-#pragma intrinsic (_lrotr, _lrotl)
-#define ROTR32(x,n) _lrotr(x,n)
-#define ROTL32(x,n) _lrotl(x,n)
+#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)))
+#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) (ROTR32(x, 7) ^ ROTR32(x,18) ^ SHR(x, 3))
-#define s1(x) (ROTR32(x,17) ^ ROTR32(x,19) ^ SHR(x,10))
+#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) (ROTR32(x, 7) ^ ROTR32(x, 18) ^ SHR(x, 3))
+#define s1(x) (ROTR32(x, 17) ^ ROTR32(x, 19) ^ SHR(x, 10))
SHA256Context *
SHA256_NewContext(void)
@@ -154,7 +160,7 @@ SHA256_NewContext(void)
return ctx;
}
-void
+void
SHA256_DestroyContext(SHA256Context *ctx, PRBool freeit)
{
memset(ctx, 0, sizeof *ctx);
@@ -163,7 +169,7 @@ SHA256_DestroyContext(SHA256Context *ctx, PRBool freeit)
}
}
-void
+void
SHA256_Begin(SHA256Context *ctx)
{
memset(ctx, 0, sizeof *ctx);
@@ -173,208 +179,208 @@ SHA256_Begin(SHA256Context *ctx)
static void
SHA256_Compress(SHA256Context *ctx)
{
- {
+ {
#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]);
+ 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])
+#define INITW(t) W[t] = (s1(W[t - 2]) + W[t - 7] + s0(W[t - 15]) + W[t - 16])
- /* prepare the "message schedule" */
+/* prepare the "message schedule" */
#ifdef NOUNROLL256
- {
- int t;
- for (t = 16; t < 64; ++t) {
- INITW(t);
- }
- }
+ {
+ 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);
+ 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);
+ }
+ {
+ 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)
- }
- }
+ {
+ 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)
+ 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;
- }
+ 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
}
@@ -383,43 +389,43 @@ SHA256_Compress(SHA256Context *ctx)
#undef S0
#undef S1
-void
+void
SHA256_Update(SHA256Context *ctx, const unsigned char *input,
- unsigned int inputLen)
+ unsigned int inputLen)
{
unsigned int inBuf = ctx->sizeLo & 0x3f;
if (!inputLen)
- return;
+ return;
/* Add inputLen into the count of bytes processed, before processing */
if ((ctx->sizeLo += inputLen) < inputLen)
- ctx->sizeHi++;
+ 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);
+ 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);
+ 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);
+ if (inputLen)
+ memcpy(B, input, inputLen);
}
-void
+void
SHA256_End(SHA256Context *ctx, unsigned char *digest,
unsigned int *digestLen, unsigned int maxDigestLen)
{
@@ -441,7 +447,7 @@ SHA256_End(SHA256Context *ctx, unsigned char *digest,
#endif
SHA256_Compress(ctx);
- /* now output the answer */
+/* now output the answer */
#if defined(IS_LITTLE_ENDIAN)
BYTESWAP4(H[0]);
BYTESWAP4(H[1]);
@@ -455,12 +461,12 @@ SHA256_End(SHA256Context *ctx, unsigned char *digest,
padLen = PR_MIN(SHA256_LENGTH, maxDigestLen);
memcpy(digest, H, padLen);
if (digestLen)
- *digestLen = padLen;
+ *digestLen = padLen;
}
void
SHA256_EndRaw(SHA256Context *ctx, unsigned char *digest,
- unsigned int *digestLen, unsigned int maxDigestLen)
+ unsigned int *digestLen, unsigned int maxDigestLen)
{
PRUint32 h[8];
unsigned int len;
@@ -481,11 +487,11 @@ SHA256_EndRaw(SHA256Context *ctx, unsigned char *digest,
len = PR_MIN(SHA256_LENGTH, maxDigestLen);
memcpy(digest, h, len);
if (digestLen)
- *digestLen = len;
+ *digestLen = len;
}
-SECStatus
-SHA256_HashBuf(unsigned char *dest, const unsigned char *src,
+SECStatus
+SHA256_HashBuf(unsigned char *dest, const unsigned char *src,
PRUint32 src_length)
{
SHA256Context ctx;
@@ -499,39 +505,41 @@ SHA256_HashBuf(unsigned char *dest, const unsigned char *src,
return SECSuccess;
}
-
-SECStatus
+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)
+{
+}
-void SHA256_TraceState(SHA256Context *ctx) { }
-
-unsigned int
+unsigned int
SHA256_FlattenSize(SHA256Context *ctx)
{
return sizeof *ctx;
}
-SECStatus
-SHA256_Flatten(SHA256Context *ctx,unsigned char *space)
+SECStatus
+SHA256_Flatten(SHA256Context *ctx, unsigned char *space)
{
PORT_Memcpy(space, ctx, sizeof *ctx);
return SECSuccess;
}
-SHA256Context *
+SHA256Context *
SHA256_Resurrect(unsigned char *space, void *arg)
{
SHA256Context *ctx = SHA256_NewContext();
- if (ctx)
- PORT_Memcpy(ctx, space, sizeof *ctx);
+ if (ctx)
+ PORT_Memcpy(ctx, space, sizeof *ctx);
return ctx;
}
-void SHA256_Clone(SHA256Context *dest, SHA256Context *src)
+void
+SHA256_Clone(SHA256Context *dest, SHA256Context *src)
{
memcpy(dest, src, sizeof *dest);
}
@@ -540,7 +548,7 @@ void SHA256_Clone(SHA256Context *dest, SHA256Context *src)
/* SHA-224 initial hash values */
static const PRUint32 H224[8] = {
- 0xc1059ed8, 0x367cd507, 0x3070dd17, 0xf70e5939,
+ 0xc1059ed8, 0x367cd507, 0x3070dd17, 0xf70e5939,
0xffc00b31, 0x68581511, 0x64f98fa7, 0xbefa4fa4
};
@@ -565,7 +573,7 @@ SHA224_Begin(SHA224Context *ctx)
void
SHA224_Update(SHA224Context *ctx, const unsigned char *input,
- unsigned int inputLen)
+ unsigned int inputLen)
{
SHA256_Update(ctx, input, inputLen);
}
@@ -580,13 +588,13 @@ SHA224_End(SHA256Context *ctx, unsigned char *digest,
void
SHA224_EndRaw(SHA256Context *ctx, unsigned char *digest,
- unsigned int *digestLen, unsigned int maxDigestLen)
+ unsigned int *digestLen, unsigned int maxDigestLen)
{
unsigned int maxLen = SHA_MIN(maxDigestLen, SHA224_LENGTH);
SHA256_EndRaw(ctx, digest, digestLen, maxLen);
}
-SECStatus
+SECStatus
SHA224_HashBuf(unsigned char *dest, const unsigned char *src,
PRUint32 src_length)
{
@@ -607,7 +615,10 @@ SHA224_Hash(unsigned char *dest, const char *src)
return SHA224_HashBuf(dest, (const unsigned char *)src, PORT_Strlen(src));
}
-void SHA224_TraceState(SHA224Context *ctx) { }
+void
+SHA224_TraceState(SHA224Context *ctx)
+{
+}
unsigned int
SHA224_FlattenSize(SHA224Context *ctx)
@@ -627,36 +638,36 @@ SHA224_Resurrect(unsigned char *space, void *arg)
return SHA256_Resurrect(space, arg);
}
-void SHA224_Clone(SHA224Context *dest, SHA224Context *src)
+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)
+#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)))
+#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) (ROTR64(x, 1) ^ ROTR64(x, 8) ^ SHR(x,7))
-#define s1(x) (ROTR64(x,19) ^ ROTR64(x,61) ^ SHR(x,6))
+#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) (ROTR64(x, 1) ^ ROTR64(x, 8) ^ SHR(x, 7))
+#define s1(x) (ROTR64(x, 19) ^ ROTR64(x, 61) ^ SHR(x, 6))
#if PR_BYTES_PER_LONG == 8
-#define ULLC(hi,lo) 0x ## hi ## lo ## UL
+#define ULLC(hi, lo) 0x##hi##lo##UL
#elif defined(_MSC_VER)
-#define ULLC(hi,lo) 0x ## hi ## lo ## ui64
+#define ULLC(hi, lo) 0x##hi##lo##ui64
#else
-#define ULLC(hi,lo) 0x ## hi ## lo ## ULL
+#define ULLC(hi, lo) 0x##hi##lo##ULL
#endif
#if defined(IS_LITTLE_ENDIAN)
@@ -665,38 +676,54 @@ void SHA224_Clone(SHA224Context *dest, SHA224Context *src)
#define SHA_HTONLL(x) _byteswap_uint64(x)
#elif defined(__GNUC__) && (defined(__x86_64__) || defined(__x86_64))
-static __inline__ PRUint64 swap8b(PRUint64 value)
+static __inline__ PRUint64
+swap8b(PRUint64 value)
{
- __asm__("bswapq %0" : "+r" (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)
-static PRUint64 swap8b(PRUint64 x)
+#define SHA_MASK16 ULLC(0000FFFF, 0000FFFF)
+#define SHA_MASK8 ULLC(00FF00FF, 00FF00FF)
+static PRUint64
+swap8b(PRUint64 x)
{
PRUint64 t1 = x;
- t1 = ((t1 & SHA_MASK8 ) << 8) | ((t1 >> 8) & SHA_MASK8 );
+ t1 = ((t1 & SHA_MASK8) << 8) | ((t1 >> 8) & SHA_MASK8);
t1 = ((t1 & SHA_MASK16) << 16) | ((t1 >> 16) & SHA_MASK16);
return (t1 >> 32) | (t1 << 32);
}
#define SHA_HTONLL(x) swap8b(x)
#endif
-#define BYTESWAP8(x) x = SHA_HTONLL(x)
+#define BYTESWAP8(x) x = SHA_HTONLL(x)
#endif /* defined(IS_LITTLE_ENDIAN) */
#else /* no long long */
#if defined(IS_LITTLE_ENDIAN)
-#define ULLC(hi,lo) { 0x ## lo ## U, 0x ## hi ## U }
-#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)
+#define ULLC(hi, lo) \
+ { \
+ 0x##lo##U, 0x##hi##U \
+ }
+#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)
#else
-#define ULLC(hi,lo) { 0x ## hi ## U, 0x ## lo ## U }
+#define ULLC(hi, lo) \
+ { \
+ 0x##hi##U, 0x##lo##U \
+ }
#endif
#endif
@@ -704,98 +731,98 @@ static PRUint64 swap8b(PRUint64 x)
/* 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
+ 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)
+ 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];
+ 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. */
+ PRUint64 h[8]; /* 8 state variables */
+ PRUint64 sizeLo; /* 64-bit count of hashed bytes. */
};
/* =========== SHA512 implementation ===================================== */
@@ -803,19 +830,18 @@ struct SHA512ContextStr {
/* SHA-512 initial hash values */
static const PRUint64 H512[8] = {
#if PR_BYTES_PER_LONG == 8
- 0x6a09e667f3bcc908UL , 0xbb67ae8584caa73bUL ,
- 0x3c6ef372fe94f82bUL , 0xa54ff53a5f1d36f1UL ,
- 0x510e527fade682d1UL , 0x9b05688c2b3e6c1fUL ,
- 0x1f83d9abfb41bd6bUL , 0x5be0cd19137e2179UL
+ 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)
+ 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)
{
@@ -823,7 +849,7 @@ SHA512_NewContext(void)
return ctx;
}
-void
+void
SHA512_DestroyContext(SHA512Context *ctx, PRBool freeit)
{
memset(ctx, 0, sizeof *ctx);
@@ -832,7 +858,7 @@ SHA512_DestroyContext(SHA512Context *ctx, PRBool freeit)
}
}
-void
+void
SHA512_Begin(SHA512Context *ctx)
{
memset(ctx, 0, sizeof *ctx);
@@ -841,84 +867,102 @@ SHA512_Begin(SHA512Context *ctx)
#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);
+#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);
+#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)
+#define DUMP(n, a, d, e, h)
#endif
#if defined(HAVE_LONG_LONG)
-#define ADDTO(x,y) y += x
+#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 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)
+#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
+#undef NOUNROLL512
#define NOUNROLL512 1
-#define ADDTO(x,y) y.lo += x.lo; y.hi += x.hi + (x.lo > y.lo)
+#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))
+#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 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 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 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))
+#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; \
+#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) \
+#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
@@ -926,256 +970,256 @@ static void
SHA512_Compress(SHA512Context *ctx)
{
#if defined(IS_LITTLE_ENDIAN)
- {
- 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]);
- }
+ {
+ 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
- {
-#ifdef NOUNROLL512
{
- /* prepare the "message schedule" */
- int t;
- for (t = 16; t < 80; ++t) {
- INITW(t);
- }
- }
+#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);
+ 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) {
+ {
+ int i;
+ for (i = 0; i < 80; ++i) {
#ifdef HAVE_LONG_LONG
- printf("W[%2d] = %016lx\n", i, W[i]);
+ printf("W[%2d] = %016lx\n", i, W[i]);
#else
- printf("W[%2d] = %08x%08x\n", i, W[i].hi, W[i].lo);
+ 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];
+ {
+ 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)
- }
- }
+ {
+ 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)
+ 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]);
- }
+ 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
+void
SHA512_Update(SHA512Context *ctx, const unsigned char *input,
unsigned int inputLen)
{
unsigned int inBuf;
if (!inputLen)
- return;
+ return;
#if defined(HAVE_LONG_LONG)
inBuf = (unsigned int)ctx->sizeLo & 0x7f;
@@ -1184,41 +1228,42 @@ SHA512_Update(SHA512Context *ctx, const unsigned char *input,
#else
inBuf = (unsigned int)ctx->sizeLo.lo & 0x7f;
ctx->sizeLo.lo += inputLen;
- if (ctx->sizeLo.lo < inputLen) ctx->sizeLo.hi++;
+ 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);
+ 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);
+ 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);
+ if (inputLen)
+ memcpy(B, input, inputLen);
}
-void
+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;
+ unsigned int inBuf = (unsigned int)ctx->sizeLo & 0x7f;
#else
- unsigned int inBuf = (unsigned int)ctx->sizeLo.lo & 0x7f;
+ unsigned int inBuf = (unsigned int)ctx->sizeLo.lo & 0x7f;
#endif
unsigned int padLen = (inBuf < 112) ? (112 - inBuf) : (112 + 128 - inBuf);
PRUint64 lo;
@@ -1239,7 +1284,7 @@ SHA512_End(SHA512Context *ctx, unsigned char *digest,
#endif
SHA512_Compress(ctx);
- /* now output the answer */
+/* now output the answer */
#if defined(IS_LITTLE_ENDIAN)
BYTESWAP8(H[0]);
BYTESWAP8(H[1]);
@@ -1253,7 +1298,7 @@ SHA512_End(SHA512Context *ctx, unsigned char *digest,
padLen = PR_MIN(SHA512_LENGTH, maxDigestLen);
memcpy(digest, H, padLen);
if (digestLen)
- *digestLen = padLen;
+ *digestLen = padLen;
}
void
@@ -1278,11 +1323,11 @@ SHA512_EndRaw(SHA512Context *ctx, unsigned char *digest,
len = PR_MIN(SHA512_LENGTH, maxDigestLen);
memcpy(digest, h, len);
if (digestLen)
- *digestLen = len;
+ *digestLen = len;
}
-SECStatus
-SHA512_HashBuf(unsigned char *dest, const unsigned char *src,
+SECStatus
+SHA512_HashBuf(unsigned char *dest, const unsigned char *src,
PRUint32 src_length)
{
SHA512Context ctx;
@@ -1296,45 +1341,47 @@ SHA512_HashBuf(unsigned char *dest, const unsigned char *src,
return SECSuccess;
}
-
-SECStatus
+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)
+{
+}
-void SHA512_TraceState(SHA512Context *ctx) { }
-
-unsigned int
+unsigned int
SHA512_FlattenSize(SHA512Context *ctx)
{
return sizeof *ctx;
}
-SECStatus
-SHA512_Flatten(SHA512Context *ctx,unsigned char *space)
+SECStatus
+SHA512_Flatten(SHA512Context *ctx, unsigned char *space)
{
PORT_Memcpy(space, ctx, sizeof *ctx);
return SECSuccess;
}
-SHA512Context *
+SHA512Context *
SHA512_Resurrect(unsigned char *space, void *arg)
{
SHA512Context *ctx = SHA512_NewContext();
- if (ctx)
- PORT_Memcpy(ctx, space, sizeof *ctx);
+ if (ctx)
+ PORT_Memcpy(ctx, space, sizeof *ctx);
return ctx;
}
-void SHA512_Clone(SHA512Context *dest, SHA512Context *src)
+void
+SHA512_Clone(SHA512Context *dest, SHA512Context *src)
{
memcpy(dest, src, sizeof *dest);
}
/* ======================================================================= */
-/* SHA384 uses a SHA512Context as the real context.
+/* 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.
@@ -1343,15 +1390,15 @@ void SHA512_Clone(SHA512Context *dest, SHA512Context *src)
/* SHA-384 initial hash values */
static const PRUint64 H384[8] = {
#if PR_BYTES_PER_LONG == 8
- 0xcbbb9d5dc1059ed8UL , 0x629a292a367cd507UL ,
- 0x9159015a3070dd17UL , 0x152fecd8f70e5939UL ,
- 0x67332667ffc00b31UL , 0x8eb44a8768581511UL ,
- 0xdb0c2e0d64f98fa7UL , 0x47b5481dbefa4fa4UL
+ 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)
+ 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
};
@@ -1361,29 +1408,29 @@ SHA384_NewContext(void)
return SHA512_NewContext();
}
-void
+void
SHA384_DestroyContext(SHA384Context *ctx, PRBool freeit)
{
SHA512_DestroyContext(ctx, freeit);
}
-void
+void
SHA384_Begin(SHA384Context *ctx)
{
memset(ctx, 0, sizeof *ctx);
memcpy(H, H384, sizeof H384);
}
-void
+void
SHA384_Update(SHA384Context *ctx, const unsigned char *input,
- unsigned int inputLen)
+ unsigned int inputLen)
{
SHA512_Update(ctx, input, inputLen);
}
-void
+void
SHA384_End(SHA384Context *ctx, unsigned char *digest,
- unsigned int *digestLen, unsigned int maxDigestLen)
+ unsigned int *digestLen, unsigned int maxDigestLen)
{
unsigned int maxLen = SHA_MIN(maxDigestLen, SHA384_LENGTH);
SHA512_End(ctx, digest, digestLen, maxLen);
@@ -1391,15 +1438,15 @@ SHA384_End(SHA384Context *ctx, unsigned char *digest,
void
SHA384_EndRaw(SHA384Context *ctx, unsigned char *digest,
- unsigned int *digestLen, unsigned int maxDigestLen)
+ unsigned int *digestLen, unsigned int maxDigestLen)
{
unsigned int maxLen = SHA_MIN(maxDigestLen, SHA384_LENGTH);
SHA512_EndRaw(ctx, digest, digestLen, maxLen);
}
-SECStatus
+SECStatus
SHA384_HashBuf(unsigned char *dest, const unsigned char *src,
- PRUint32 src_length)
+ PRUint32 src_length)
{
SHA512Context ctx;
unsigned int outLen;
@@ -1412,33 +1459,37 @@ SHA384_HashBuf(unsigned char *dest, const unsigned char *src,
return SECSuccess;
}
-SECStatus
+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) { }
+void
+SHA384_TraceState(SHA384Context *ctx)
+{
+}
-unsigned int
+unsigned int
SHA384_FlattenSize(SHA384Context *ctx)
{
return sizeof(SHA384Context);
}
-SECStatus
-SHA384_Flatten(SHA384Context *ctx,unsigned char *space)
+SECStatus
+SHA384_Flatten(SHA384Context *ctx, unsigned char *space)
{
return SHA512_Flatten(ctx, space);
}
-SHA384Context *
+SHA384Context *
SHA384_Resurrect(unsigned char *space, void *arg)
{
return SHA512_Resurrect(space, arg);
}
-void SHA384_Clone(SHA384Context *dest, SHA384Context *src)
+void
+SHA384_Clone(SHA384Context *dest, SHA384Context *src)
{
memcpy(dest, src, sizeof *dest);
}
@@ -1448,12 +1499,12 @@ void SHA384_Clone(SHA384Context *dest, SHA384Context *src)
#include <stdio.h>
static const char abc[] = { "abc" };
-static const char abcdbc[] = {
+static const char abcdbc[] = {
"abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq"
};
-static const char abcdef[] = {
+static const char abcdef[] = {
"abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmn"
- "hijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu"
+ "hijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu"
};
void
@@ -1461,12 +1512,13 @@ 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(" %02x%02x%02x%02x", buf[i], buf[i + 1], buf[i + 2], buf[i + 3]);
}
printf("\n");
}
-void test256(void)
+void
+test256(void)
{
unsigned char outBuf[SHA256_LENGTH];
@@ -1479,7 +1531,8 @@ void test256(void)
dumpHash32(outBuf, sizeof outBuf);
}
-void test224(void)
+void
+test224(void)
{
SHA224Context ctx;
unsigned char a1000times[1000];
@@ -1500,7 +1553,7 @@ void test224(void)
/* Test Vector 3 */
/* to hash one million 'a's perform 1000
- * sha224 updates on a buffer with 1000 'a's
+ * sha224 updates on a buffer with 1000 'a's
*/
memset(a1000times, 'a', 1000);
printf("SHA224, input = %s\n", "a one million times");
@@ -1516,16 +1569,17 @@ 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]);
+ 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)
+void
+test512(void)
{
unsigned char outBuf[SHA512_LENGTH];
@@ -1538,7 +1592,8 @@ void test512(void)
dumpHash64(outBuf, sizeof outBuf);
}
-void time512(void)
+void
+time512(void)
{
unsigned char outBuf[SHA512_LENGTH];
@@ -1546,7 +1601,8 @@ void time512(void)
SHA512_Hash(outBuf, abcdef);
}
-void test384(void)
+void
+test384(void)
{
unsigned char outBuf[SHA384_LENGTH];
@@ -1559,27 +1615,41 @@ void test384(void)
dumpHash64(outBuf, sizeof outBuf);
}
-int main (int argc, char *argv[], char *envp[])
+int
+main(int argc, char *argv[], char *envp[])
{
int i = 1;
if (argc > 1) {
- i = atoi(argv[1]);
+ i = atoi(argv[1]);
}
if (i < 2) {
- test224();
- test256();
- test384();
- test512();
+ test224();
+ test256();
+ test384();
+ test512();
} else {
- while (i-- > 0) {
- time512();
- }
- printf("done\n");
+ 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); }
+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/nss/lib/freebl/sha_fast.c b/nss/lib/freebl/sha_fast.c
index 2901949..52071f0 100644
--- a/nss/lib/freebl/sha_fast.c
+++ b/nss/lib/freebl/sha_fast.c
@@ -16,38 +16,37 @@
#include "ssltrace.h"
#endif
-static void shaCompress(volatile SHA_HW_t *X, const PRUint32 * datain);
+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_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)
+#define SHA_MIX(n, a, b, c) XW(n) = SHA_ROTL(XW(a) ^ XW(b) ^ XW(c) ^ XW(n), 1)
/*
* SHA: initialize context
*/
-void
+void
SHA1_Begin(SHA1Context *ctx)
{
- ctx->size = 0;
- /*
+ 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;
+ 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
+ * 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].
@@ -60,26 +59,26 @@ SHA1_Begin(SHA1Context *ctx)
* 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.
+ * 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
+ *
+ * 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.
+ * 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] */
+#define W2X 6 /* X[0] is W[6], and W[0] is X[-6] */
#else
#define H2X 0
#endif
@@ -87,96 +86,95 @@ SHA1_Begin(SHA1Context *ctx)
/*
* SHA: Add data to context.
*/
-void
-SHA1_Update(SHA1Context *ctx, const unsigned char *dataIn, unsigned int len)
+void
+SHA1_Update(SHA1Context *ctx, const unsigned char *dataIn, unsigned int len)
{
- register unsigned int lenB;
- register unsigned int togo;
+ register unsigned int lenB;
+ register unsigned int togo;
- if (!len)
- return;
+ if (!len)
+ return;
- /* accumulate the byte count. */
- lenB = (unsigned int)(ctx->size) & 63U;
+ /* accumulate the byte count. */
+ lenB = (unsigned int)(ctx->size) & 63U;
- ctx->size += len;
+ 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;
+ 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);
+ }
}
- } else
+#if !defined(HAVE_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;
+ {
+ while (len >= 64U) {
+ len -= 64U;
+ shaCompress(&ctx->H[H2X], (PRUint32 *)dataIn);
+ dataIn += 64U;
+ }
+ }
+ if (len) {
+ memcpy(ctx->B, dataIn, len);
}
- }
- if (len) {
- memcpy(ctx->B, dataIn, len);
- }
}
-
/*
* SHA: Generate hash value from context
*/
-void
+void NO_SANITIZE_ALIGNMENT
SHA1_End(SHA1Context *ctx, unsigned char *hashout,
unsigned int *pDigestLen, unsigned int maxDigestLen)
{
- register PRUint64 size;
- register PRUint32 lenB;
+ register PRUint64 size;
+ register PRUint32 lenB;
- 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 };
+ 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);
+ 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;
- }
+ 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
}
@@ -185,13 +183,13 @@ SHA1_EndRaw(SHA1Context *ctx, unsigned char *hashout,
unsigned int *pDigestLen, unsigned int maxDigestLen)
{
#if defined(SHA_NEED_TMP_VARIABLE)
- register PRUint32 tmp;
+ register PRUint32 tmp;
#endif
- PORT_Assert (maxDigestLen >= SHA1_LENGTH);
+ PORT_Assert(maxDigestLen >= SHA1_LENGTH);
- SHA_STORE_RESULT;
- if (pDigestLen)
- *pDigestLen = SHA1_LENGTH;
+ SHA_STORE_RESULT;
+ if (pDigestLen)
+ *pDigestLen = SHA1_LENGTH;
}
#undef B
@@ -207,26 +205,26 @@ SHA1_EndRaw(SHA1Context *ctx, unsigned char *hashout,
* 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
+ * 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
+ * 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
+ * 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.
+ * 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
+ * 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
+ * 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
@@ -242,22 +240,22 @@ SHA1_EndRaw(SHA1Context *ctx, unsigned char *hashout,
* 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)
+static void NO_SANITIZE_ALIGNMENT
+shaCompress(volatile SHA_HW_t *X, const PRUint32 *inbuf)
{
- register SHA_HW_t A, B, C, D, E;
+ register SHA_HW_t A, B, C, D, E;
#if defined(SHA_NEED_TMP_VARIABLE)
- register PRUint32 tmp;
+ register PRUint32 tmp;
#endif
#if !defined(SHA_PUT_W_IN_STACK)
-#define XH(n) X[n-H2X]
-#define XW(n) X[n-W2X]
+#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
+ 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
@@ -266,116 +264,200 @@ shaCompress(volatile SHA_HW_t *X, const PRUint32 *inbuf)
#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 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;
+ 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;
}
/*************************************************************************
@@ -419,7 +501,7 @@ SHA1_HashBuf(unsigned char *dest, const unsigned char *src, PRUint32 src_length)
SECStatus
SHA1_Hash(unsigned char *dest, const char *src)
{
- return SHA1_HashBuf(dest, (const unsigned char *)src, PORT_Strlen (src));
+ return SHA1_HashBuf(dest, (const unsigned char *)src, PORT_Strlen(src));
}
/*
@@ -433,23 +515,25 @@ SHA1_FlattenSize(SHA1Context *cx)
}
SECStatus
-SHA1_Flatten(SHA1Context *cx,unsigned char *space)
+SHA1_Flatten(SHA1Context *cx, unsigned char *space)
{
- PORT_Memcpy(space,cx, sizeof(SHA1Context));
+ PORT_Memcpy(space, cx, sizeof(SHA1Context));
return SECSuccess;
}
SHA1Context *
-SHA1_Resurrect(unsigned char *space,void *arg)
+SHA1_Resurrect(unsigned char *space, void *arg)
{
SHA1Context *cx = SHA1_NewContext();
- if (cx == NULL) return NULL;
+ if (cx == NULL)
+ return NULL;
- PORT_Memcpy(cx,space, sizeof(SHA1Context));
+ PORT_Memcpy(cx, space, sizeof(SHA1Context));
return cx;
}
-void SHA1_Clone(SHA1Context *dest, SHA1Context *src)
+void
+SHA1_Clone(SHA1Context *dest, SHA1Context *src)
{
memcpy(dest, src, sizeof *dest);
}
diff --git a/nss/lib/freebl/sha_fast.h b/nss/lib/freebl/sha_fast.h
index 256e190..4f37d13 100644
--- a/nss/lib/freebl/sha_fast.h
+++ b/nss/lib/freebl/sha_fast.h
@@ -6,10 +6,11 @@
#define _SHA_FAST_H_
#include "prlong.h"
+#include "blapii.h"
#define SHA1_INPUT_LEN 64
-#if defined(IS_64) && !defined(__sparc)
+#if defined(IS_64) && !defined(__sparc)
typedef PRUint64 SHA_HW_t;
#define SHA1_USING_64_BIT 1
#else
@@ -17,17 +18,17 @@ 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 */
+ 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 defined(IS_LITTLE_ENDIAN)
#if (_MSC_VER >= 1300)
#pragma intrinsic(_byteswap_ulong)
#define SHA_HTONL(x) _byteswap_ulong(x)
@@ -41,8 +42,8 @@ struct SHA1ContextStr {
#endif /* !defined FORCEINLINE */
#define FASTCALL __fastcall
-static FORCEINLINE PRUint32 FASTCALL
-swap4b(PRUint32 dwd)
+static FORCEINLINE PRUint32 FASTCALL
+swap4b(PRUint32 dwd)
{
__asm {
mov eax,dwd
@@ -54,21 +55,23 @@ swap4b(PRUint32 dwd)
#endif /* NSS_X86_OR_X64 */
#endif /* IS_LITTLE_ENDIAN */
-#pragma intrinsic (_lrotr, _lrotl)
-#define SHA_ROTL(x,n) _lrotl(x,n)
+#pragma intrinsic(_lrotr, _lrotl)
+#define SHA_ROTL(x, n) _lrotl(x, n)
#define SHA_ROTL_IS_DEFINED 1
#endif /* _MSC_VER */
-#if defined(__GNUC__)
+#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)
+#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)
+#else
+static __inline__ PRUint32
+SHA_ROTL(PRUint32 t, PRUint32 n)
{
return ((t << n) | (t >> (32 - n)));
}
@@ -76,28 +79,33 @@ static __inline__ PRUint32 SHA_ROTL(PRUint32 t, PRUint32 n)
#define SHA_ROTL_IS_DEFINED 1
#if defined(NSS_X86_OR_X64)
-static __inline__ PRUint32 swap4b(PRUint32 value)
+static __inline__ PRUint32
+swap4b(PRUint32 value)
{
- __asm__("bswap %0" : "+r" (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)
+#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));
+ __asm__("rev %0, %1"
+ : "=r"(ret)
+ : "r"(value));
return ret;
}
#define SHA_HTONL(x) swap4b(x)
@@ -108,65 +116,61 @@ static __inline__ PRUint32 swap4b(PRUint32 value)
#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
+#define SHA_ROTL(X, n) (tmp = (X), ((tmp) << (n)) | ((tmp) >> (32 - (n))))
#endif
#if !defined(SHA_HTONL)
-#define SHA_MASK 0x00FF00FF
+#define SHA_MASK 0x00FF00FF
#if defined(IS_LITTLE_ENDIAN)
-#undef SHA_NEED_TMP_VARIABLE
+#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))
+#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)
+#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)
+#if defined(HAVE_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 { \
- PRUint32 tmpbuf[5]; \
- 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); \
- }
+ 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 { \
+ PRUint32 tmpbuf[5]; \
+ 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
+#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/nss/lib/freebl/shsign.h b/nss/lib/freebl/shsign.h
index 3a3d2f1..590c0e6 100644
--- a/nss/lib/freebl/shsign.h
+++ b/nss/lib/freebl/shsign.h
@@ -6,9 +6,9 @@
#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
+#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/nss/lib/freebl/shvfy.c b/nss/lib/freebl/shvfy.c
index ad64a26..af4a34f 100644
--- a/nss/lib/freebl/shvfy.c
+++ b/nss/lib/freebl/shvfy.c
@@ -16,6 +16,7 @@
#include "prmem.h"
#include "hasht.h"
#include "pqg.h"
+#include "blapii.h"
/*
* Most modern version of Linux support a speed optimization scheme where an
@@ -28,7 +29,7 @@
* 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
@@ -49,10 +50,10 @@
/*
* 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).
+ * changes to it (usually address fixups).
*
* If prelink is installed, this
- * file descriptor is a pipe connecting the output of
+ * 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.
*
@@ -62,115 +63,121 @@
PRFileDesc *
bl_OpenUnPrelink(const char *shName, int *pid)
{
- char *command= strdup(FREEBL_PRELINK_COMMAND);
+ char *command = strdup(FREEBL_PRELINK_COMMAND);
char *argString = NULL;
- char **argv = 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 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;
+ for (cp = command; *cp; cp++) {
+ if (*cp == ' ') {
+ *cp++ = 0;
+ argString = cp;
+ break;
}
}
- memset (&statBuf, 0, sizeof(statBuf));
+ 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);
+ 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);
+ 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;
- }
+ /* 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++;
- }
- }
+ 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;
+ 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;
- }
- }
+ 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;
+ goto loser;
}
argv[argNext++] = shNameArg;
argv[argNext++] = 0;
-
+
ret = pipe(pipefd);
if (ret < 0) {
- goto loser;
+ goto loser;
}
/* use vfork() so we don't trigger the pthread_at_fork() handlers */
child = vfork();
- if (child < 0) goto loser;
+ 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 */
+ /* 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;
@@ -188,10 +195,10 @@ bl_OpenUnPrelink(const char *shName, int *pid)
loser:
if (pipefd[0] != -1) {
- close(pipefd[0]);
+ close(pipefd[0]);
}
if (pipefd[1] != -1) {
- close(pipefd[1]);
+ close(pipefd[1]);
}
free(command);
free(shNameArg);
@@ -209,13 +216,13 @@ loser:
* from hanging around.
*/
void
-bl_CloseUnPrelink( PRFileDesc *file, int pid)
+bl_CloseUnPrelink(PRFileDesc *file, int pid)
{
/* close the file descriptor */
PR_Close(file);
/* reap the child */
if (pid) {
- waitpid(pid, NULL, 0);
+ waitpid(pid, NULL, 0);
}
}
#endif
@@ -226,16 +233,16 @@ 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);
+ 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)) {
+ "." 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));
+ PORT_Memcpy(output, libName, ln_len);
+ PORT_Memcpy(&output[ln_len], SGN_SUFFIX, sizeof(SGN_SUFFIX));
return output;
}
@@ -251,55 +258,68 @@ readItem(PRFileDesc *fd, SECItem *item)
unsigned char buf[4];
int bytesRead;
-
bytesRead = PR_Read(fd, buf, 4);
if (bytesRead != 4) {
- return SECFailure;
+ return SECFailure;
}
item->len = decodeInt(buf);
item->data = PORT_Alloc(item->len);
if (item->data == NULL) {
- item->len = 0;
- return SECFailure;
+ 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;
+ PORT_Free(item->data);
+ item->data = NULL;
+ item->len = 0;
+ return SECFailure;
}
return SECSuccess;
}
-PRBool
-BLAPI_SHVerify(const char *name, PRFuncPtr addr)
+static PRBool blapi_SHVerifyFile(const char *shName, PRBool self);
+
+static PRBool
+blapi_SHVerify(const char *name, PRFuncPtr addr, PRBool self)
{
PRBool result = PR_FALSE; /* if anything goes wrong,
- * the signature does not verify */
+ * the signature does not verify */
/* find our shared library name */
char *shName = PR_GetLibraryFilePathname(name, addr);
if (!shName) {
- goto loser;
+ goto loser;
}
- result = BLAPI_SHVerifyFile(shName);
+ result = blapi_SHVerifyFile(shName, self);
loser:
if (shName != NULL) {
- PR_Free(shName);
+ PR_Free(shName);
}
return result;
}
PRBool
+BLAPI_SHVerify(const char *name, PRFuncPtr addr)
+{
+ return blapi_SHVerify(name, addr, PR_FALSE);
+}
+
+PRBool
BLAPI_SHVerifyFile(const char *shName)
{
+ return blapi_SHVerifyFile(shName, PR_FALSE);
+}
+
+static PRBool
+blapi_SHVerifyFile(const char *shName, PRBool self)
+{
char *checkName = NULL;
PRFileDesc *checkFD = NULL;
PRFileDesc *shFD = NULL;
- void *hashcx = NULL;
+ void *hashcx = NULL;
const SECHashObject *hashObj = NULL;
SECItem signature = { 0, NULL, 0 };
SECItem hash;
@@ -312,22 +332,28 @@ BLAPI_SHVerifyFile(const char *shName)
#endif
PRBool result = PR_FALSE; /* if anything goes wrong,
- * the signature does not verify */
+ * the signature does not verify */
unsigned char buf[4096];
unsigned char hashBuf[HASH_LENGTH_MAX];
- PORT_Memset(&key,0,sizeof(key));
+ PORT_Memset(&key, 0, sizeof(key));
hash.data = hashBuf;
hash.len = sizeof(hashBuf);
+ /* If our integrity check was never ran or failed, fail any other
+ * integrity checks to prevent any token going into FIPS mode. */
+ if (!self && (BL_FIPSEntryOK(PR_FALSE) != SECSuccess)) {
+ return PR_FALSE;
+ }
+
if (!shName) {
- goto loser;
+ goto loser;
}
/* figure out the name of our check file */
checkName = mkCheckFileName(shName);
if (!checkName) {
- goto loser;
+ goto loser;
}
/* open the check File */
@@ -337,52 +363,54 @@ BLAPI_SHVerifyFile(const char *shName)
fprintf(stderr, "Failed to open the check file %s: (%d, %d)\n",
checkName, (int)PR_GetError(), (int)PR_GetOSError());
#endif /* DEBUG_SHVERIFY */
- goto loser;
+ goto loser;
}
/* read and Verify the headerthe header */
bytesRead = PR_Read(checkFD, buf, 12);
if (bytesRead != 12) {
- goto loser;
+ goto loser;
}
if ((buf[0] != NSS_SIGN_CHK_MAGIC1) || (buf[1] != NSS_SIGN_CHK_MAGIC2)) {
- goto loser;
+ goto loser;
}
- if ((buf[2] != NSS_SIGN_CHK_MAJOR_VERSION) ||
- (buf[3] < NSS_SIGN_CHK_MINOR_VERSION)) {
- 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;
+ goto loser;
}
#endif
/* seek past any future header extensions */
offset = decodeInt(&buf[4]);
- PR_Seek(checkFD, offset, PR_SEEK_SET);
+ if (PR_Seek(checkFD, offset, PR_SEEK_SET) < 0) {
+ goto loser;
+ }
/* read the key */
- rv = readItem(checkFD,&key.params.prime);
+ rv = readItem(checkFD, &key.params.prime);
if (rv != SECSuccess) {
- goto loser;
+ goto loser;
}
- rv = readItem(checkFD,&key.params.subPrime);
+ rv = readItem(checkFD, &key.params.subPrime);
if (rv != SECSuccess) {
- goto loser;
+ goto loser;
}
- rv = readItem(checkFD,&key.params.base);
+ rv = readItem(checkFD, &key.params.base);
if (rv != SECSuccess) {
- goto loser;
+ goto loser;
}
- rv = readItem(checkFD,&key.publicValue);
+ rv = readItem(checkFD, &key.publicValue);
if (rv != SECSuccess) {
- goto loser;
+ goto loser;
}
/* read the siganture */
- rv = readItem(checkFD,&signature);
+ rv = readItem(checkFD, &signature);
if (rv != SECSuccess) {
- goto loser;
+ goto loser;
}
/* done with the check file */
@@ -391,12 +419,12 @@ BLAPI_SHVerifyFile(const char *shName)
hashObj = HASH_GetRawHashObject(PQG_GetHashType(&key.params));
if (hashObj == NULL) {
- goto loser;
+ goto loser;
}
- /* open our library file */
+/* open our library file */
#ifdef FREEBL_USE_PRELINK
- shFD = bl_OpenUnPrelink(shName,&pid);
+ shFD = bl_OpenUnPrelink(shName, &pid);
#else
shFD = PR_Open(shName, PR_RDONLY, 0);
#endif
@@ -405,20 +433,20 @@ BLAPI_SHVerifyFile(const char *shName)
fprintf(stderr, "Failed to open the library file %s: (%d, %d)\n",
shName, (int)PR_GetError(), (int)PR_GetOSError());
#endif /* DEBUG_SHVERIFY */
- goto loser;
+ goto loser;
}
/* hash our library file with SHA1 */
hashcx = hashObj->create();
if (hashcx == NULL) {
- goto loser;
+ goto loser;
}
hashObj->begin(hashcx);
count = 0;
while ((bytesRead = PR_Read(shFD, buf, sizeof(buf))) > 0) {
- hashObj->update(hashcx, buf, bytesRead);
- count += bytesRead;
+ hashObj->update(hashcx, buf, bytesRead);
+ count += bytesRead;
}
#ifdef FREEBL_USE_PRELINK
bl_CloseUnPrelink(shFD, pid);
@@ -429,66 +457,64 @@ BLAPI_SHVerifyFile(const char *shName)
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;
+ 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);
+ {
+ 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");
+ 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, " 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");
+ fprintf(stderr, "Verified : %s\n", result ? "TRUE" : "FALSE");
}
#endif /* DEBUG_SHVERIFY */
-
loser:
if (checkName != NULL) {
- PORT_Free(checkName);
+ PORT_Free(checkName);
}
if (checkFD != NULL) {
- PR_Close(checkFD);
+ PR_Close(checkFD);
}
if (shFD != NULL) {
- PR_Close(shFD);
+ PR_Close(shFD);
}
if (hashcx != NULL) {
- if (hashObj) {
- hashObj->destroy(hashcx,PR_TRUE);
- }
+ if (hashObj) {
+ hashObj->destroy(hashcx, PR_TRUE);
+ }
}
if (signature.data != NULL) {
- PORT_Free(signature.data);
+ PORT_Free(signature.data);
}
if (key.params.prime.data != NULL) {
- PORT_Free(key.params.prime.data);
+ PORT_Free(key.params.prime.data);
}
if (key.params.subPrime.data != NULL) {
- PORT_Free(key.params.subPrime.data);
+ PORT_Free(key.params.subPrime.data);
}
if (key.params.base.data != NULL) {
- PORT_Free(key.params.base.data);
+ PORT_Free(key.params.base.data);
}
if (key.publicValue.data != NULL) {
- PORT_Free(key.publicValue.data);
+ PORT_Free(key.publicValue.data);
}
return result;
@@ -498,11 +524,11 @@ 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;
+ /*
+ * 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);
+ return blapi_SHVerify(name, (PRFuncPtr)decodeInt, PR_TRUE);
}
diff --git a/nss/lib/freebl/stubs.c b/nss/lib/freebl/stubs.c
index 993d01e..8e07849 100644
--- a/nss/lib/freebl/stubs.c
+++ b/nss/lib/freebl/stubs.c
@@ -46,7 +46,7 @@
/*
* This uses function pointers.
- *
+ *
* CONS: A separate function is needed to
* fill in the function pointers.
*
@@ -56,107 +56,129 @@
* 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_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; \
+ 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.
+ * 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_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); }
+ 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_ArenaAlloc_Util,(PLArenaPool *arena, size_t size));
-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,(PLArenaPool *arena,
- SECItem *item,unsigned int len));
-STUB_DECLARE(SECComparison,SECITEM_CompareItem_Util,(const SECItem *a,
- const SECItem *b));
-STUB_DECLARE(SECStatus,SECITEM_CopyItem_Util,(PLArenaPool *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(SECOidTag,SECOID_FindOIDTag_Util,(const SECItem *oid));
-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))
-
+STUB_DECLARE(void *, PORT_Alloc_Util, (size_t len));
+STUB_DECLARE(void *, PORT_ArenaAlloc_Util, (PLArenaPool * arena, size_t size));
+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_Access, (const char *name, PRAccessHow how));
+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(char *, PR_GetEnvSecure, (const char *));
+
+STUB_DECLARE(SECItem *, SECITEM_AllocItem_Util, (PLArenaPool * arena,
+ SECItem *item, unsigned int len));
+STUB_DECLARE(SECComparison, SECITEM_CompareItem_Util, (const SECItem *a,
+ const SECItem *b));
+STUB_DECLARE(SECStatus, SECITEM_CopyItem_Util, (PLArenaPool * 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(SECOidTag, SECOID_FindOIDTag_Util, (const SECItem *oid));
+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,
@@ -166,7 +188,6 @@ STUB_DECLARE(int, NSS_SecureMemcmp,(const void *a, const void *b, size_t n));
* will most likely fail.
*/
-
/* memory */
extern void *
PORT_Alloc_stub(size_t len)
@@ -188,12 +209,11 @@ PORT_ZAlloc_stub(size_t len)
STUB_SAFE_CALL1(PORT_ZAlloc_Util, len);
void *ptr = malloc(len);
if (ptr) {
- memset(ptr, 0, len);
+ memset(ptr, 0, len);
}
return ptr;
}
-
extern void
PORT_ZFree_stub(void *ptr, size_t len)
{
@@ -239,7 +259,7 @@ PORT_ArenaZAlloc_stub(PLArenaPool *arena, size_t size)
return NULL;
}
-extern void
+extern void
PORT_FreeArena_stub(PLArenaPool *arena, PRBool zero)
{
@@ -247,7 +267,6 @@ PORT_FreeArena_stub(PLArenaPool *arena, PRBool zero)
abort();
}
-
/* io */
extern PRFileDesc *
PR_Open_stub(const char *name, PRIntn flags, PRIntn mode)
@@ -275,10 +294,12 @@ PR_Open_stub(const char *name, PRIntn flags, PRIntn mode)
fd = open(name, lflags, mode);
if (fd >= 0) {
- lfd = PORT_New_stub(int);
- if (lfd != NULL) {
- *lfd = fd;
- }
+ lfd = PORT_New_stub(int);
+ if (lfd != NULL) {
+ *lfd = fd;
+ } else {
+ close(fd);
+ }
}
return (PRFileDesc *)lfd;
}
@@ -292,7 +313,7 @@ PR_ImportPipe_stub(PROsfd fd)
lfd = PORT_New_stub(int);
if (lfd != NULL) {
- *lfd = fd;
+ *lfd = fd;
}
return (PRFileDesc *)lfd;
}
@@ -306,7 +327,7 @@ PR_Close_stub(PRFileDesc *fd)
lfd = (int *)fd;
close(*lfd);
PORT_Free_stub(lfd);
-
+
return PR_SUCCESS;
}
@@ -315,7 +336,7 @@ 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);
}
@@ -341,9 +362,32 @@ PR_Seek_stub(PRFileDesc *fd, PROffset32 offset, PRSeekWhence whence)
return lseek(*lfd, offset, lwhence);
}
+PRStatus
+PR_Access_stub(const char *name, PRAccessHow how)
+{
+ int mode = F_OK;
+ int rv;
+ STUB_SAFE_CALL2(PR_Access, name, how);
+ switch (how) {
+ case PR_ACCESS_WRITE_OK:
+ mode = W_OK;
+ break;
+ case PR_ACCESS_READ_OK:
+ mode = R_OK;
+ break;
+ /* assume F_OK for all others */
+ default:
+ break;
+ }
+ rv = access(name, mode);
+ if (rv == 0) {
+ return PR_SUCCESS;
+ }
+ return PR_FAILURE;
+}
/*
- * library
+ * library
*/
extern char *
PR_GetLibraryFilePathname_stub(const char *name, PRFuncPtr addr)
@@ -356,27 +400,26 @@ PR_GetLibraryFilePathname_stub(const char *name, PRFuncPtr addr)
if (dladdr((void *)addr, &dli) == 0) {
return NULL;
}
- result = PORT_Alloc_stub(strlen(dli.dli_fname)+1);
+ 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
+extern void
PORT_SetError_stub(int value)
-{
+{
STUB_SAFE_CALL1(PORT_SetError_Util, value);
errno = value;
}
@@ -395,11 +438,10 @@ extern PRStatus
PR_Sleep_stub(PRIntervalTime ticks)
{
STUB_SAFE_CALL1(PR_Sleep, ticks);
- usleep(ticks*1000);
+ usleep(ticks * 1000);
return PR_SUCCESS;
}
-
/* locking */
extern PRLock *
PR_NewLock_stub(void)
@@ -465,7 +507,13 @@ PR_WaitCondVar_stub(PRCondVar *cvar, PRIntervalTime timeout)
return PR_FAILURE;
}
-
+extern char *
+PR_GetEnvSecure_stub(const char *var)
+{
+ STUB_SAFE_CALL1(PR_GetEnvSecure, var);
+ abort();
+ return NULL;
+}
extern void
PR_DestroyCondVar_stub(PRCondVar *cvar)
@@ -486,7 +534,6 @@ PR_CallOnce_stub(PRCallOnceType *once, PRCallOnceFN func)
return PR_FAILURE;
}
-
/*
* SECITEMS implement Item Utilities
*/
@@ -500,13 +547,13 @@ SECITEM_FreeItem_stub(SECItem *zap, PRBool freeit)
extern SECItem *
SECITEM_AllocItem_stub(PLArenaPool *arena, SECItem *item, unsigned int len)
{
- STUB_SAFE_CALL3(SECITEM_AllocItem_Util, arena, item, len);
+ STUB_SAFE_CALL3(SECITEM_AllocItem_Util, arena, item, len);
abort();
return NULL;
}
extern SECComparison
-SECITEM_CompareItem_stub(const SECItem *a, const SECItem *b)
+SECITEM_CompareItem_stub(const SECItem *a, const SECItem *b)
{
STUB_SAFE_CALL2(SECITEM_CompareItem_Util, a, b);
abort();
@@ -545,8 +592,8 @@ NSS_SecureMemcmp_stub(const void *a, const void *b, size_t n)
#ifdef FREEBL_NO_WEAK
-static const char *nsprLibName = SHLIB_PREFIX"nspr4."SHLIB_SUFFIX;
-static const char *nssutilLibName = SHLIB_PREFIX"nssutil3."SHLIB_SUFFIX;
+static const char *nsprLibName = SHLIB_PREFIX "nspr4." SHLIB_SUFFIX;
+static const char *nssutilLibName = SHLIB_PREFIX "nssutil3." SHLIB_SUFFIX;
static SECStatus
freebl_InitNSPR(void *lib)
@@ -559,6 +606,7 @@ freebl_InitNSPR(void *lib)
STUB_FETCH_FUNCTION(PR_Seek);
STUB_FETCH_FUNCTION(PR_GetLibraryFilePathname);
STUB_FETCH_FUNCTION(PR_Assert);
+ STUB_FETCH_FUNCTION(PR_Access);
STUB_FETCH_FUNCTION(PR_Sleep);
STUB_FETCH_FUNCTION(PR_CallOnce);
STUB_FETCH_FUNCTION(PR_NewCondVar);
@@ -570,6 +618,7 @@ freebl_InitNSPR(void *lib)
STUB_FETCH_FUNCTION(PR_Unlock);
STUB_FETCH_FUNCTION(PR_Lock);
STUB_FETCH_FUNCTION(PR_DestroyLock);
+ STUB_FETCH_FUNCTION(PR_GetEnvSecure);
return SECSuccess;
}
@@ -599,16 +648,17 @@ freebl_InitNSSUtil(void *lib)
/*
* 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_getLibrary(libName) \
+ dlopen(libName, RTLD_LAZY | RTLD_NOLOAD)
#define freebl_releaseLibrary(lib) \
- if (lib) dlclose(lib)
+ if (lib) \
+ dlclose(lib)
-static void * FREEBLnsprGlobalLib = NULL;
-static void * FREEBLnssutilGlobalLib = NULL;
+static void *FREEBLnsprGlobalLib = NULL;
+static void *FREEBLnssutilGlobalLib = NULL;
-void __attribute ((destructor)) FREEBL_unload()
+void __attribute((destructor)) FREEBL_unload()
{
freebl_releaseLibrary(FREEBLnsprGlobalLib);
freebl_releaseLibrary(FREEBLnssutilGlobalLib);
@@ -617,7 +667,7 @@ void __attribute ((destructor)) FREEBL_unload()
/*
* 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.
*/
@@ -626,34 +676,34 @@ FREEBL_InitStubs()
{
SECStatus rv = SECSuccess;
#ifdef FREEBL_NO_WEAK
- void *nspr = NULL;
- void *nssutil = NULL;
+ 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 */
+ 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 */
+ nssutil = freebl_getLibrary(nssutilLibName);
+ if (!nssutil) {
+ return SECFailure;
+ }
+ rv = freebl_InitNSSUtil(nssutil);
+ if (rv != SECSuccess) {
+ freebl_releaseLibrary(nssutil);
+ return rv;
+ }
+ FREEBLnssutilGlobalLib = nssutil; /* adopt */
}
#endif
diff --git a/nss/lib/freebl/stubs.h b/nss/lib/freebl/stubs.h
index 72f3000..25ec394 100644
--- a/nss/lib/freebl/stubs.h
+++ b/nss/lib/freebl/stubs.h
@@ -21,44 +21,46 @@
#define _LIBUTIL_H_ 1
#define PORT_Alloc PORT_Alloc_stub
-#define PORT_ArenaAlloc PORT_ArenaAlloc_stub
-#define PORT_ArenaZAlloc PORT_ArenaZAlloc_stub
+#define PORT_ArenaAlloc PORT_ArenaAlloc_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_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 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 SECOID_FindOIDTag SECOID_FindOIDTag_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 SECOID_FindOIDTag SECOID_FindOIDTag_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_Assert PR_Assert_stub
+#define PR_Access PR_Access_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_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_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_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
+#define PR_GetEnvSecure PR_GetEnvSecure_stub
-extern int FREEBL_InitStubs(void);
+extern int FREEBL_InitStubs(void);
#endif
diff --git a/nss/lib/freebl/sysrand.c b/nss/lib/freebl/sysrand.c
index e6dd56a..0128fa0 100644
--- a/nss/lib/freebl/sysrand.c
+++ b/nss/lib/freebl/sysrand.c
@@ -27,23 +27,23 @@ static size_t rng_systemFromNoise(unsigned char *dest, size_t maxLen);
* 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)
+static size_t
+rng_systemFromNoise(unsigned char *dest, size_t maxLen)
{
- size_t retBytes = maxLen;
+ size_t retBytes = maxLen;
- while (maxLen) {
- size_t nbytes = RNG_GetNoise(dest, maxLen);
+ while (maxLen) {
+ size_t nbytes = RNG_GetNoise(dest, maxLen);
- PORT_Assert(nbytes != 0);
+ PORT_Assert(nbytes != 0);
- dest += nbytes;
- maxLen -= nbytes;
+ dest += nbytes;
+ maxLen -= nbytes;
- /* some hw op to try to introduce more entropy into the next
- * RNG_GetNoise call */
- rng_systemJitter();
- }
- return retBytes;
+ /* some hw op to try to introduce more entropy into the next
+ * RNG_GetNoise call */
+ rng_systemJitter();
+ }
+ return retBytes;
}
#endif
diff --git a/nss/lib/freebl/tlsprfalg.c b/nss/lib/freebl/tlsprfalg.c
index f2db803..1e5e678 100644
--- a/nss/lib/freebl/tlsprfalg.c
+++ b/nss/lib/freebl/tlsprfalg.c
@@ -12,13 +12,12 @@
#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)
+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];
@@ -38,11 +37,11 @@ TLS_P_hash(HASH_HashType hashType, const SECItem *secret, const char *label,
res = result->data;
if (label != NULL)
- label_len = PORT_Strlen(label);
+ label_len = PORT_Strlen(label);
cx = HMAC_Create(hashObj, secret->data, secret->len, isFIPS);
if (cx == NULL)
- goto loser;
+ goto loser;
/* initialize the state = A(1) = HMAC_hash(secret, seed) */
HMAC_Begin(cx);
@@ -50,51 +49,51 @@ TLS_P_hash(HASH_HashType hashType, const SECItem *secret, const char *label,
HMAC_Update(cx, seed->data, seed->len);
status = HMAC_Finish(cx, state, &state_len, sizeof(state));
if (status != SECSuccess)
- goto loser;
+ 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;
+ 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;
+ 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);
+ 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)
+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 tmp = { siBuffer, NULL, 0 };
SECItem S1;
SECItem S2;
@@ -103,34 +102,33 @@ TLS_PRF(const SECItem *secret, const char *label, SECItem *seed,
PORT_Assert((result != NULL) && (result->data != NULL));
S1.type = siBuffer;
- S1.len = (secret->len / 2) + (secret->len & 1);
+ S1.len = (secret->len / 2) + (secret->len & 1);
S1.data = secret->data;
S2.type = siBuffer;
- S2.len = S1.len;
+ S2.len = S1.len;
S2.data = secret->data + (secret->len - S2.len);
- tmp.data = (unsigned char*)PORT_Alloc(result->len);
+ tmp.data = (unsigned char *)PORT_Alloc(result->len);
if (tmp.data == NULL)
- goto loser;
+ goto loser;
tmp.len = result->len;
status = TLS_P_hash(HASH_AlgMD5, &S1, label, seed, result, isFIPS);
if (status != SECSuccess)
- goto loser;
+ goto loser;
status = TLS_P_hash(HASH_AlgSHA1, &S2, label, seed, &tmp, isFIPS);
if (status != SECSuccess)
- goto loser;
+ goto loser;
for (i = 0; i < result->len; i++)
- result->data[i] ^= tmp.data[i];
+ result->data[i] ^= tmp.data[i];
rv = SECSuccess;
loser:
if (tmp.data != NULL)
- PORT_ZFree(tmp.data, tmp.len);
+ PORT_ZFree(tmp.data, tmp.len);
return rv;
}
-
diff --git a/nss/lib/freebl/unix_rand.c b/nss/lib/freebl/unix_rand.c
index 579040e..ea3b6af 100644
--- a/nss/lib/freebl/unix_rand.c
+++ b/nss/lib/freebl/unix_rand.c
@@ -12,11 +12,14 @@
#include <sys/time.h>
#include <sys/wait.h>
#include <sys/stat.h>
+#include <sys/types.h>
+#include <dirent.h>
#include "secrng.h"
#include "secerr.h"
#include "prerror.h"
#include "prthread.h"
#include "prprf.h"
+#include "prenv.h"
size_t RNG_FileUpdate(const char *fileName, size_t limit);
@@ -29,25 +32,26 @@ size_t RNG_FileUpdate(const char *fileName, size_t limit);
* 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)
+
+static size_t
+CopyLowBits(void *dst, size_t dstlen, void *src, size_t srclen)
{
union endianness {
- PRInt32 i;
- char c[4];
+ PRInt32 i;
+ char c[4];
} u;
if (srclen <= dstlen) {
- memcpy(dst, src, srclen);
- return srclen;
+ memcpy(dst, src, srclen);
+ return srclen;
}
u.i = 0x01020304;
if (u.c[0] == 0x01) {
- /* big-endian case */
- memcpy(dst, (char*)src + (srclen - dstlen), dstlen);
+ /* big-endian case */
+ memcpy(dst, (char *)src + (srclen - dstlen), dstlen);
} else {
- /* little-endian case */
- memcpy(dst, src, dstlen);
+ /* little-endian case */
+ memcpy(dst, src, dstlen);
}
return dstlen;
}
@@ -62,9 +66,10 @@ static const PRUint32 entropy_buf_len = 4096; /* buffer up to 4 KB */
* 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)
+static SECStatus
+BufferEntropy(char *inbuf, PRUint32 inlen,
+ char *entropy_buf, PRUint32 *entropy_buffered,
+ PRUint32 *total_fed)
{
PRUint32 tocopy = 0;
PRUint32 avail = 0;
@@ -94,13 +99,14 @@ static SECStatus BufferEntropy(char* inbuf, PRUint32 inlen,
/* 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)
+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;
+ 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) {
@@ -113,7 +119,7 @@ static SECStatus RNG_kstat(PRUint32* fed)
if (!kc) {
return SECFailure;
}
- entropy_buf = (char*) PORT_Alloc(entropy_buf_len);
+ 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) {
@@ -121,17 +127,17 @@ static SECStatus RNG_kstat(PRUint32* fed)
/* missing data from a single kstat shouldn't be fatal */
continue;
}
- rv = BufferEntropy((char*)ksp, sizeof(kstat_t),
- entropy_buf, &entropy_buffered,
- fed);
+ 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 (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;
}
@@ -154,9 +160,7 @@ static SECStatus RNG_kstat(PRUint32* fed)
#endif
-#if defined(SCO) || defined(UNIXWARE) || defined(BSDI) || defined(FREEBSD) \
- || defined(NETBSD) || defined(DARWIN) || defined(OPENBSD) \
- || defined(NTO) || defined(__riscos__)
+#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)
@@ -167,7 +171,7 @@ GetHighResClock(void *buf, size_t maxbytes)
int ticks;
struct tms buffer;
- ticks=times(&buffer);
+ ticks = times(&buffer);
return CopyLowBits(buf, maxbytes, &ticks, sizeof(ticks));
}
@@ -176,7 +180,7 @@ GiveSystemInfo(void)
{
long si;
- /*
+ /*
* Is this really necessary? Why not use rand48 or something?
*/
si = sysconf(_SC_CHILD_MAX);
@@ -204,15 +208,15 @@ GiveSystemInfo(void)
rv = sysinfo(SI_MACHINE, buf, sizeof(buf));
if (rv > 0) {
- RNG_RandomUpdate(buf, rv);
+ RNG_RandomUpdate(buf, rv);
}
rv = sysinfo(SI_RELEASE, buf, sizeof(buf));
if (rv > 0) {
- RNG_RandomUpdate(buf, rv);
+ RNG_RandomUpdate(buf, rv);
}
rv = sysinfo(SI_HW_SERIAL, buf, sizeof(buf));
if (rv > 0) {
- RNG_RandomUpdate(buf, rv);
+ RNG_RandomUpdate(buf, rv);
}
}
@@ -222,7 +226,7 @@ GetHighResClock(void *buf, size_t maxbytes)
hrtime_t t;
t = gethrtime();
if (t) {
- return CopyLowBits(buf, maxbytes, &t, sizeof(t));
+ return CopyLowBits(buf, maxbytes, &t, sizeof(t));
}
return 0;
}
@@ -304,15 +308,15 @@ GiveSystemInfo(void)
rv = sysinfo(SI_MACHINE, buf, sizeof(buf));
if (rv > 0) {
- RNG_RandomUpdate(buf, rv);
+ RNG_RandomUpdate(buf, rv);
}
rv = sysinfo(SI_RELEASE, buf, sizeof(buf));
if (rv > 0) {
- RNG_RandomUpdate(buf, rv);
+ RNG_RandomUpdate(buf, rv);
}
rv = sysinfo(SI_HW_SERIAL, buf, sizeof(buf));
if (rv > 0) {
- RNG_RandomUpdate(buf, rv);
+ RNG_RandomUpdate(buf, rv);
}
}
@@ -361,7 +365,7 @@ GiveSystemInfo(void)
#ifndef NO_SYSINFO
struct sysinfo si;
if (sysinfo(&si) == 0) {
- RNG_RandomUpdate(&si, sizeof(si));
+ RNG_RandomUpdate(&si, sizeof(si));
}
#endif
}
@@ -388,15 +392,15 @@ GiveSystemInfo(void)
rv = sysinfo(SI_MACHINE, buf, sizeof(buf));
if (rv > 0) {
- RNG_RandomUpdate(buf, rv);
+ RNG_RandomUpdate(buf, rv);
}
rv = sysinfo(SI_RELEASE, buf, sizeof(buf));
if (rv > 0) {
- RNG_RandomUpdate(buf, rv);
+ RNG_RandomUpdate(buf, rv);
}
rv = sysinfo(SI_HW_SERIAL, buf, sizeof(buf));
if (rv > 0) {
- RNG_RandomUpdate(buf, rv);
+ RNG_RandomUpdate(buf, rv);
}
}
@@ -420,33 +424,34 @@ GiveSystemInfo(void)
rv = syssgi(SGI_SYSID, &buf[0]);
if (rv > 0) {
- RNG_RandomUpdate(buf, MAXSYSIDSIZE);
+ RNG_RandomUpdate(buf, MAXSYSIDSIZE);
}
#ifdef SGI_RDUBLK
rv = syssgi(SGI_RDUBLK, getpid(), &buf[0], sizeof(buf));
if (rv > 0) {
- RNG_RandomUpdate(buf, sizeof(buf));
+ 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));
+ RNG_RandomUpdate(buf, sizeof(buf));
}
rv = sysinfo(SI_MACHINE, buf, sizeof(buf));
if (rv > 0) {
- RNG_RandomUpdate(buf, rv);
+ RNG_RandomUpdate(buf, rv);
}
rv = sysinfo(SI_RELEASE, buf, sizeof(buf));
if (rv > 0) {
- RNG_RandomUpdate(buf, rv);
+ RNG_RandomUpdate(buf, rv);
}
rv = sysinfo(SI_HW_SERIAL, buf, sizeof(buf));
if (rv > 0) {
- RNG_RandomUpdate(buf, rv);
+ RNG_RandomUpdate(buf, rv);
}
}
-static size_t GetHighResClock(void *buf, size_t maxbuf)
+static size_t
+GetHighResClock(void *buf, size_t maxbuf)
{
unsigned phys_addr, raddr, cycleval;
static volatile unsigned *iotimer_addr = NULL;
@@ -457,66 +462,65 @@ static size_t GetHighResClock(void *buf, size_t maxbuf)
struct timeval tv;
#ifndef SGI_CYCLECNTR_SIZE
-#define SGI_CYCLECNTR_SIZE 165 /* Size user needs to use to read CC */
+#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 */
- }
+ 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);
+ s0[1] = *(iotimer_addr + 1);
memcpy(buf, (char *)&s0[0], cntr_size);
return CopyLowBits(buf, maxbuf, &s0, cntr_size);
}
@@ -541,15 +545,15 @@ GiveSystemInfo(void)
rv = sysinfo(SI_MACHINE, buf, sizeof(buf));
if (rv > 0) {
- RNG_RandomUpdate(buf, rv);
+ RNG_RandomUpdate(buf, rv);
}
rv = sysinfo(SI_RELEASE, buf, sizeof(buf));
if (rv > 0) {
- RNG_RandomUpdate(buf, rv);
+ RNG_RandomUpdate(buf, rv);
}
rv = sysinfo(SI_HW_SERIAL, buf, sizeof(buf));
if (rv > 0) {
- RNG_RandomUpdate(buf, rv);
+ RNG_RandomUpdate(buf, rv);
}
}
#endif /* sony */
@@ -569,7 +573,7 @@ GetHighResClock(void *buf, size_t maxbytes)
int ticks;
struct tms buffer;
- ticks=times(&buffer);
+ ticks = times(&buffer);
return CopyLowBits(buf, maxbytes, &ticks, sizeof(ticks));
}
@@ -581,20 +585,19 @@ GiveSystemInfo(void)
rv = sysinfo(SI_MACHINE, buf, sizeof(buf));
if (rv > 0) {
- RNG_RandomUpdate(buf, rv);
+ RNG_RandomUpdate(buf, rv);
}
rv = sysinfo(SI_RELEASE, buf, sizeof(buf));
if (rv > 0) {
- RNG_RandomUpdate(buf, rv);
+ RNG_RandomUpdate(buf, rv);
}
rv = sysinfo(SI_HW_SERIAL, buf, sizeof(buf));
if (rv > 0) {
- RNG_RandomUpdate(buf, rv);
+ RNG_RandomUpdate(buf, rv);
}
}
#endif /* sinix */
-
#ifdef BEOS
#include <be/kernel/OS.h>
@@ -647,20 +650,21 @@ GiveSystemInfo(void)
rv = sysinfo(SI_MACHINE, buf, sizeof(buf));
if (rv > 0) {
- RNG_RandomUpdate(buf, rv);
+ RNG_RandomUpdate(buf, rv);
}
rv = sysinfo(SI_RELEASE, buf, sizeof(buf));
if (rv > 0) {
- RNG_RandomUpdate(buf, rv);
+ RNG_RandomUpdate(buf, rv);
}
rv = sysinfo(SI_HW_SERIAL, buf, sizeof(buf));
if (rv > 0) {
- RNG_RandomUpdate(buf, rv);
+ RNG_RandomUpdate(buf, rv);
}
}
#endif /* nec_ews */
-size_t RNG_GetNoise(void *buf, size_t maxbytes)
+size_t
+RNG_GetNoise(void *buf, size_t maxbytes)
{
struct timeval tv;
int n = 0;
@@ -670,15 +674,15 @@ size_t RNG_GetNoise(void *buf, size_t maxbytes)
maxbytes -= n;
(void)gettimeofday(&tv, 0);
- c = CopyLowBits((char*)buf+n, maxbytes, &tv.tv_usec, sizeof(tv.tv_usec));
+ 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));
+ 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 */
+#define SAFE_POPEN_MAXARGS 10 /* must be at least 2 */
/*
* safe_popen is static to this module and we know what arguments it is
@@ -699,73 +703,76 @@ safe_popen(char *cmd)
static struct sigaction newact;
if (pipe(p) < 0)
- return 0;
+ return 0;
fp = fdopen(p[0], "r");
if (fp == 0) {
- close(p[0]);
- close(p[1]);
- return 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);
+ 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;
+ 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 */
@@ -780,7 +787,7 @@ safe_pclose(FILE *fp)
int status = -1, rv;
if ((pid = safe_popen_pid) == 0)
- return -1;
+ return -1;
safe_popen_pid = 0;
fclose(fp);
@@ -790,11 +797,11 @@ safe_pclose(FILE *fp)
/* 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)
- ;
+ kill(pid, SIGKILL);
+ while ((rv = waitpid(pid, &status, 0)) == -1 && errno == EINTR)
+ ;
}
/* Reset SIGCHLD signal hander before returning */
@@ -815,12 +822,13 @@ safe_pclose(FILE *fp)
*/
#define DO_NETSTAT 1
-void RNG_SystemInfoForRNG(void)
+void
+RNG_SystemInfoForRNG(void)
{
FILE *fp;
char buf[BUFSIZ];
size_t bytes;
- const char * const *cp;
+ const char *const *cp;
char *randfile;
#ifdef DARWIN
#if TARGET_OS_IPHONE
@@ -833,22 +841,22 @@ void RNG_SystemInfoForRNG(void)
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
+ 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
+ static const char *const files[] = {
+ "/etc/passwd",
+ "/etc/utmp",
+ "/tmp",
+ "/var/tmp",
+ "/usr/tmp",
+ 0
};
#endif
@@ -870,17 +878,17 @@ void RNG_SystemInfoForRNG(void)
* is running on.
*/
if (environ != NULL) {
- cp = (const char * const *) environ;
+ cp = (const char *const *)environ;
while (*cp) {
- RNG_RandomUpdate(*cp, strlen(*cp));
- cp++;
+ RNG_RandomUpdate(*cp, strlen(*cp));
+ cp++;
}
- RNG_RandomUpdate(environ, (char*)cp - (char*)environ);
+ RNG_RandomUpdate(environ, (char *)cp - (char *)environ);
}
/* Give in system information */
if (gethostname(buf, sizeof(buf)) == 0) {
- RNG_RandomUpdate(buf, strlen(buf));
+ RNG_RandomUpdate(buf, strlen(buf));
}
GiveSystemInfo();
@@ -888,20 +896,20 @@ void RNG_SystemInfoForRNG(void)
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);
- }
+ randfile = PR_GetEnvSecure("NSRANDFILE");
+ if ((randfile != NULL) && (randfile[0] != '\0')) {
+ char *randCountString = PR_GetEnvSecure("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);
+ RNG_FileForRNG(*cp);
/*
* Bug 100447: On BSD/OS 4.2 and 4.3, we have problem calling safe_popen
@@ -913,9 +921,7 @@ void RNG_SystemInfoForRNG(void)
* either, if data has been gathered successfully.
*/
-#if defined(BSDI) || defined(FREEBSD) || defined(NETBSD) \
- || defined(OPENBSD) || defined(DARWIN) || defined(LINUX) \
- || defined(HPUX)
+#if defined(BSDI) || defined(FREEBSD) || defined(NETBSD) || defined(OPENBSD) || defined(DARWIN) || defined(LINUX) || defined(HPUX)
if (bytes)
return;
#endif
@@ -946,60 +952,60 @@ void RNG_SystemInfoForRNG(void)
#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);
+ while ((bytes = fread(buf, 1, sizeof(buf), fp)) > 0)
+ RNG_RandomUpdate(buf, bytes);
+ safe_pclose(fp);
}
#endif
-
}
-#define TOTAL_FILE_LIMIT 1000000 /* one million */
+#define TOTAL_FILE_LIMIT 1000000 /* one million */
-size_t RNG_FileUpdate(const char *fileName, size_t limit)
+size_t
+RNG_FileUpdate(const char *fileName, size_t limit)
{
- FILE * file;
- int fd;
- int bytes;
- size_t fileBytes = 0;
- struct stat stat_buf;
+ FILE *file;
+ int fd;
+ int 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;
+ return fileBytes;
RNG_RandomUpdate(&stat_buf, sizeof(stat_buf));
-
+
file = fopen(fileName, "r");
if (file != NULL) {
- /* Read from the underlying file descriptor directly to bypass stdio
- * buffering and avoid reading more bytes than we need from
- * /dev/urandom. NOTE: we can't use fread with unbuffered I/O because
- * fread may return EOF in unbuffered I/O mode on Android.
- *
- * Moreover, we read into a buffer of size BUFSIZ, so buffered I/O
- * has no performance advantage. */
- fd = fileno(file);
- /* 'file' was just opened, so this should not fail. */
- PORT_Assert(fd != -1);
- while (limit > fileBytes) {
- bytes = PR_MIN(sizeof buffer, limit - fileBytes);
- bytes = read(fd, buffer, bytes);
- 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);
+ /* Read from the underlying file descriptor directly to bypass stdio
+ * buffering and avoid reading more bytes than we need from
+ * /dev/urandom. NOTE: we can't use fread with unbuffered I/O because
+ * fread may return EOF in unbuffered I/O mode on Android.
+ *
+ * Moreover, we read into a buffer of size BUFSIZ, so buffered I/O
+ * has no performance advantage. */
+ fd = fileno(file);
+ /* 'file' was just opened, so this should not fail. */
+ PORT_Assert(fd != -1);
+ while (limit > fileBytes && fd != -1) {
+ bytes = PR_MIN(sizeof buffer, limit - fileBytes);
+ bytes = read(fd, buffer, bytes);
+ 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
@@ -1010,22 +1016,24 @@ size_t RNG_FileUpdate(const char *fileName, size_t limit)
return fileBytes;
}
-void RNG_FileForRNG(const char *fileName)
+void
+RNG_FileForRNG(const char *fileName)
{
RNG_FileUpdate(fileName, TOTAL_FILE_LIMIT);
}
-void ReadSingleFile(const char *fileName)
+void
+ReadSingleFile(const char *fileName)
{
- FILE * file;
+ FILE *file;
unsigned char buffer[BUFSIZ];
-
+
file = fopen(fileName, "rb");
if (file != NULL) {
- while (fread(buffer, 1, sizeof(buffer), file) > 0)
- ;
- fclose(file);
- }
+ while (fread(buffer, 1, sizeof(buffer), file) > 0)
+ ;
+ fclose(file);
+ }
}
#define _POSIX_PTHREAD_SEMANTICS
@@ -1034,16 +1042,16 @@ void ReadSingleFile(const char *fileName)
PRBool
ReadFileOK(char *dir, char *file)
{
- struct stat stat_buf;
+ struct stat stat_buf;
char filename[PATH_MAX];
- int count = snprintf(filename, sizeof filename, "%s/%s",dir, file);
+ int count = snprintf(filename, sizeof filename, "%s/%s", dir, file);
if (count <= 0) {
- return PR_FALSE; /* name too long, can't read it anyway */
+ 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 PR_FALSE; /* can't stat, probably can't read it then as well */
return S_ISREG(stat_buf.st_mode) ? PR_TRUE : PR_FALSE;
}
@@ -1053,68 +1061,63 @@ ReadFileOK(char *dir, char *file)
*
* return 1 if it's time to reset the fileToRead (no more files to read).
*/
-int ReadOneFile(int fileToRead)
+static 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
+ struct dirent *entry;
+#if defined(__sun)
+ char firstName[256];
#else
- struct dirent entry, firstEntry;
-#define entry_dir entry
+ char firstName[NAME_MAX + 1];
#endif
-
- int i, error = -1;
+ const char *name = NULL;
+ int i;
if (fd == NULL) {
- dir = getenv("HOME");
- if (dir) {
- fd = opendir(dir);
- }
+ dir = PR_GetEnvSecure("HOME");
+ if (dir) {
+ fd = opendir(dir);
+ }
}
if (fd == NULL) {
- return 1;
+ 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;
- }
+ firstName[0] = '\0';
+ for (i = 0; i <= fileToRead; i++) {
+ do {
+ /* readdir() isn't guaranteed to be thread safe on every platform;
+ * this code assumes the same directory isn't read concurrently.
+ * This usage is confirmed safe on Linux, see bug 1254334. */
+ entry = readdir(fd);
+ } while (entry != NULL && !ReadFileOK(dir, &entry->d_name[0]));
+ if (entry == NULL) {
+ resetCount = 1; /* read to the end, start again at the beginning */
+ if (firstName[0]) {
+ /* ran out of entries in the directory, use the first one */
+ name = firstName;
+ }
+ break;
+ }
+ name = entry->d_name;
+ if (i == 0) {
+ /* copy the name of the first in case we run out of entries */
+ PORT_Assert(PORT_Strlen(name) < sizeof(firstName));
+ PORT_Strncpy(firstName, name, sizeof(firstName) - 1);
+ firstName[sizeof(firstName) - 1] = '\0';
+ }
}
- 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);
- }
- }
+ if (name) {
+ char filename[PATH_MAX];
+ int count = snprintf(filename, sizeof(filename), "%s/%s", dir, name);
+ if (count >= 1) {
+ ReadSingleFile(filename);
+ }
+ }
closedir(fd);
return resetCount;
@@ -1123,18 +1126,20 @@ int ReadOneFile(int fileToRead)
/*
* do something to try to introduce more noise into the 'GetNoise' call
*/
-static void rng_systemJitter(void)
+static void
+rng_systemJitter(void)
{
- static int fileToRead = 1;
+ static int fileToRead = 1;
- if (ReadOneFile(fileToRead)) {
- fileToRead = 1;
- } else {
- fileToRead++;
- }
+ if (ReadOneFile(fileToRead)) {
+ fileToRead = 1;
+ } else {
+ fileToRead++;
+ }
}
-size_t RNG_SystemRNG(void *dest, size_t maxLen)
+size_t
+RNG_SystemRNG(void *dest, size_t maxLen)
{
FILE *file;
int fd;
@@ -1144,7 +1149,7 @@ size_t RNG_SystemRNG(void *dest, size_t maxLen)
file = fopen("/dev/urandom", "r");
if (file == NULL) {
- return rng_systemFromNoise(dest, maxLen);
+ return rng_systemFromNoise(dest, maxLen);
}
/* Read from the underlying file descriptor directly to bypass stdio
* buffering and avoid reading more bytes than we need from /dev/urandom.
@@ -1154,18 +1159,18 @@ size_t RNG_SystemRNG(void *dest, size_t maxLen)
fd = fileno(file);
/* 'file' was just opened, so this should not fail. */
PORT_Assert(fd != -1);
- while (maxLen > fileBytes) {
- bytes = maxLen - fileBytes;
- bytes = read(fd, buffer, bytes);
- if (bytes <= 0)
- break;
- fileBytes += bytes;
- buffer += bytes;
+ while (maxLen > fileBytes && fd != -1) {
+ bytes = maxLen - fileBytes;
+ bytes = read(fd, buffer, bytes);
+ if (bytes <= 0)
+ break;
+ fileBytes += bytes;
+ buffer += bytes;
}
fclose(file);
if (fileBytes != maxLen) {
- PORT_SetError(SEC_ERROR_NEED_RANDOM); /* system RNG failed */
- fileBytes = 0;
+ PORT_SetError(SEC_ERROR_NEED_RANDOM); /* system RNG failed */
+ fileBytes = 0;
}
return fileBytes;
}
diff --git a/nss/lib/freebl/win_rand.c b/nss/lib/freebl/win_rand.c
index 2918d58..b863776 100644
--- a/nss/lib/freebl/win_rand.c
+++ b/nss/lib/freebl/win_rand.c
@@ -11,7 +11,7 @@
static BOOL
CurrentClockTickTime(LPDWORD lpdwHigh, LPDWORD lpdwLow)
{
- LARGE_INTEGER liCount;
+ LARGE_INTEGER liCount;
if (!QueryPerformanceCounter(&liCount))
return FALSE;
@@ -21,12 +21,13 @@ CurrentClockTickTime(LPDWORD lpdwHigh, LPDWORD lpdwLow)
return TRUE;
}
-size_t RNG_GetNoise(void *buf, size_t maxbuf)
+size_t
+RNG_GetNoise(void *buf, size_t maxbuf)
{
- DWORD dwHigh, dwLow, dwVal;
- int n = 0;
- int nBytes;
- time_t sTime;
+ DWORD dwHigh, dwLow, dwVal;
+ int n = 0;
+ int nBytes;
+ time_t sTime;
if (maxbuf <= 0)
return 0;
@@ -70,41 +71,42 @@ size_t RNG_GetNoise(void *buf, size_t maxbuf)
return n;
}
-void RNG_SystemInfoForRNG(void)
+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
+ 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
+ GlobalMemoryStatus(&sMem); // assorted memory stats
RNG_RandomUpdate(&sMem, sizeof(sMem));
dwVal = GetLogicalDrives();
- RNG_RandomUpdate(&dwVal, sizeof(dwVal)); // bitfields in bits 0-25
+ 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
+ hVal = GetCurrentProcess(); // 4 or 8 byte pseudo handle (a
+ // constant!) of current process
RNG_RandomUpdate(&hVal, sizeof(hVal));
- dwVal = GetCurrentProcessId(); // process ID (4 bytes)
+ dwVal = GetCurrentProcessId(); // process ID (4 bytes)
RNG_RandomUpdate(&dwVal, sizeof(dwVal));
- dwVal = GetCurrentThreadId(); // thread ID (4 bytes)
+ dwVal = GetCurrentThreadId(); // thread ID (4 bytes)
RNG_RandomUpdate(&dwVal, sizeof(dwVal));
volName[0] = '\0';
@@ -118,25 +120,24 @@ void RNG_SystemInfoForRNG(void)
buffer,
sizeof(buffer));
- RNG_RandomUpdate(volName, strlen(volName));
- RNG_RandomUpdate(&dwSerialNum, sizeof(dwSerialNum));
+ 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));
+ RNG_RandomUpdate(&dwSysFlags, sizeof(dwSysFlags));
+ RNG_RandomUpdate(buffer, strlen(buffer));
- if (GetDiskFreeSpace(NULL, &dwSectors, &dwBytes, &dwFreeClusters,
+ if (GetDiskFreeSpace(NULL, &dwSectors, &dwBytes, &dwFreeClusters,
&dwNumClusters)) {
- RNG_RandomUpdate(&dwSectors, sizeof(dwSectors));
- RNG_RandomUpdate(&dwBytes, sizeof(dwBytes));
+ RNG_RandomUpdate(&dwSectors, sizeof(dwSectors));
+ RNG_RandomUpdate(&dwBytes, sizeof(dwBytes));
RNG_RandomUpdate(&dwFreeClusters, sizeof(dwFreeClusters));
- RNG_RandomUpdate(&dwNumClusters, sizeof(dwNumClusters));
+ RNG_RandomUpdate(&dwNumClusters, sizeof(dwNumClusters));
}
- nBytes = RNG_GetNoise(buffer, 20); // get up to 20 bytes
+ nBytes = RNG_GetNoise(buffer, 20); // get up to 20 bytes
RNG_RandomUpdate(buffer, nBytes);
}
-
/*
* The RtlGenRandom function is declared in <ntsecapi.h>, but the
* declaration is missing a calling convention specifier. So we
@@ -147,13 +148,14 @@ DECLSPEC_IMPORT BOOLEAN WINAPI RtlGenRandom(
PVOID RandomBuffer,
ULONG RandomBufferLength);
-size_t RNG_SystemRNG(void *dest, size_t maxLen)
+size_t
+RNG_SystemRNG(void *dest, size_t maxLen)
{
size_t bytes = 0;
if (RtlGenRandom(dest, maxLen)) {
- bytes = maxLen;
+ bytes = maxLen;
}
return bytes;
}
-#endif /* is XP_WIN */
+#endif /* is XP_WIN */
diff --git a/nss/lib/jar/exports.gyp b/nss/lib/jar/exports.gyp
new file mode 100644
index 0000000..94ee144
--- /dev/null
+++ b/nss/lib/jar/exports.gyp
@@ -0,0 +1,27 @@
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+{
+ 'includes': [
+ '../../coreconf/config.gypi'
+ ],
+ 'targets': [
+ {
+ 'target_name': 'lib_jar_exports',
+ 'type': 'none',
+ 'copies': [
+ {
+ 'files': [
+ 'jar-ds.h',
+ 'jar.h',
+ 'jarfile.h'
+ ],
+ 'destination': '<(nss_public_dist_dir)/<(module)'
+ }
+ ]
+ }
+ ],
+ 'variables': {
+ 'module': 'nss'
+ }
+}
diff --git a/nss/lib/jar/jar-ds.c b/nss/lib/jar/jar-ds.c
index 0d787ba..8962305 100644
--- a/nss/lib/jar/jar-ds.c
+++ b/nss/lib/jar/jar-ds.c
@@ -8,29 +8,29 @@
ZZList *
ZZ_NewList(void)
{
- ZZList *list = (ZZList *) PORT_ZAlloc (sizeof (ZZList));
+ ZZList *list = (ZZList *)PORT_ZAlloc(sizeof(ZZList));
if (list)
- ZZ_InitList (list);
+ ZZ_InitList(list);
return list;
}
ZZLink *
ZZ_NewLink(JAR_Item *thing)
{
- ZZLink *link = (ZZLink *) PORT_ZAlloc (sizeof (ZZLink));
+ ZZLink *link = (ZZLink *)PORT_ZAlloc(sizeof(ZZLink));
if (link)
- link->thing = thing;
+ link->thing = thing;
return link;
}
-void
+void
ZZ_DestroyLink(ZZLink *link)
{
PORT_Free(link);
}
-void
-ZZ_DestroyList (ZZList *list)
+void
+ZZ_DestroyList(ZZList *list)
{
PORT_Free(list);
}
diff --git a/nss/lib/jar/jar-ds.h b/nss/lib/jar/jar-ds.h
index dd212e4..9818c66 100644
--- a/nss/lib/jar/jar-ds.h
+++ b/nss/lib/jar/jar-ds.h
@@ -23,12 +23,12 @@ struct ZZListStr {
ZZLink link;
};
-#define ZZ_InitList(lst) \
-{ \
- (lst)->link.next = &(lst)->link; \
- (lst)->link.prev = &(lst)->link; \
- (lst)->link.thing = 0; \
-}
+#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)
@@ -36,43 +36,42 @@ struct ZZListStr {
#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; \
-}
+#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
+extern void
ZZ_DestroyLink(ZZLink *link);
extern ZZList *
ZZ_NewList(void);
-extern void
+extern void
ZZ_DestroyList(ZZList *list);
-
#endif /* __JAR_DS_h_ */
diff --git a/nss/lib/jar/jar.c b/nss/lib/jar/jar.c
index d7aadbb..00a5546 100644
--- a/nss/lib/jar/jar.c
+++ b/nss/lib/jar/jar.c
@@ -14,10 +14,10 @@
#include "jarint.h"
#include "portreg.h"
-static void
-jar_destroy_list (ZZList *list);
+static void
+jar_destroy_list(ZZList *list);
-static int
+static int
jar_find_first_cert(JAR_Signer *signer, int type, JAR_Item **it);
/*
@@ -32,33 +32,33 @@ JAR_new(void)
{
JAR *jar;
- if ((jar = (JAR*)PORT_ZAlloc (sizeof (JAR))) == NULL)
- goto loser;
+ if ((jar = (JAR *)PORT_ZAlloc(sizeof(JAR))) == NULL)
+ goto loser;
if ((jar->manifest = ZZ_NewList()) == NULL)
- goto loser;
+ goto loser;
if ((jar->hashes = ZZ_NewList()) == NULL)
- goto loser;
+ goto loser;
if ((jar->phy = ZZ_NewList()) == NULL)
- goto loser;
+ goto loser;
if ((jar->metainfo = ZZ_NewList()) == NULL)
- goto loser;
+ goto loser;
if ((jar->signers = ZZ_NewList()) == NULL)
- goto loser;
+ 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);
+ 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;
}
@@ -66,36 +66,38 @@ loser:
/*
* J A R _ d e s t r o y
*/
-void PR_CALLBACK
+void PR_CALLBACK
JAR_destroy(JAR *jar)
{
- PORT_Assert( jar != NULL );
+ PORT_Assert(jar != NULL);
if (jar == NULL)
- return;
+ return;
- if (jar->fp)
- JAR_FCLOSE ((PRFileDesc*)jar->fp);
- if (jar->url)
- PORT_Free (jar->url);
- if (jar->filename)
- PORT_Free (jar->filename);
+ if (jar->fp)
+ JAR_FCLOSE((PRFileDesc *)jar->fp);
+ if (jar->url)
+ PORT_Free(jar->url);
+ if (jar->filename)
+ PORT_Free(jar->filename);
+ if (jar->globalmeta)
+ PORT_Free(jar->globalmeta);
/* 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);
+ 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
+static void
jar_destroy_list(ZZList *list)
{
ZZLink *link, *oldlink;
@@ -106,70 +108,70 @@ jar_destroy_list(ZZList *list)
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);
- }
+ 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);
+ }
}
}
@@ -181,42 +183,42 @@ next:
*
*/
-int
-JAR_get_metainfo(JAR *jar, char *name, char *header, void **info,
+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 );
+ PORT_Assert(jar != NULL && header != NULL);
if (jar == NULL || header == NULL)
- return JAR_ERR_PNF;
+ return JAR_ERR_PNF;
list = jar->metainfo;
- if (ZZ_ListEmpty (list))
- return JAR_ERR_PNF;
+ if (ZZ_ListEmpty(list))
+ return JAR_ERR_PNF;
- for (link = ZZ_ListHead (list);
- !ZZ_ListIterDone (list, link);
+ 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;
- }
- }
+ 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;
}
@@ -232,61 +234,61 @@ JAR_get_metainfo(JAR *jar, char *name, char *header, void **info,
*
*/
JAR_Context *
-JAR_find (JAR *jar, char *pattern, jarType type)
+JAR_find(JAR *jar, char *pattern, jarType type)
{
JAR_Context *ctx;
- PORT_Assert( jar != NULL );
+ PORT_Assert(jar != NULL);
if (!jar)
- return NULL;
+ return NULL;
- ctx = (JAR_Context *) PORT_ZAlloc (sizeof (JAR_Context));
+ ctx = (JAR_Context *)PORT_ZAlloc(sizeof(JAR_Context));
if (ctx == NULL)
- return NULL;
+ return NULL;
ctx->jar = jar;
if (pattern) {
- if ((ctx->pattern = PORT_Strdup (pattern)) == NULL) {
- PORT_Free (ctx);
- return NULL;
- }
+ 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;
+ 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;
}
@@ -297,14 +299,14 @@ JAR_find (JAR *jar, char *pattern, jarType type)
* Destroy the find iterator context.
*
*/
-void
-JAR_find_end (JAR_Context *ctx)
+void
+JAR_find_end(JAR_Context *ctx)
{
- PORT_Assert( ctx != NULL );
+ PORT_Assert(ctx != NULL);
if (ctx) {
- if (ctx->pattern)
- PORT_Free (ctx->pattern);
- PORT_Free (ctx);
+ if (ctx->pattern)
+ PORT_Free(ctx->pattern);
+ PORT_Free(ctx);
}
}
@@ -316,15 +318,16 @@ JAR_find_end (JAR_Context *ctx)
*
*/
-int JAR_find_next (JAR_Context *ctx, JAR_Item **it)
+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 );
+ PORT_Assert(ctx != NULL);
+ PORT_Assert(ctx->jar != NULL);
jar = ctx->jar;
@@ -332,184 +335,184 @@ int JAR_find_next (JAR_Context *ctx, JAR_Item **it)
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;
+ 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.
+ 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
+ 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;
- }
+ 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)
+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;
+ 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;
- }
+ 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_new_signer(void)
{
- JAR_Signer *signer = (JAR_Signer *) PORT_ZAlloc (sizeof (JAR_Signer));
+ JAR_Signer *signer = (JAR_Signer *)PORT_ZAlloc(sizeof(JAR_Signer));
if (signer == NULL)
- goto loser;
+ goto loser;
/* certs */
signer->certs = ZZ_NewList();
if (signer->certs == NULL)
- goto loser;
+ goto loser;
/* sf */
signer->sf = ZZ_NewList();
if (signer->sf == NULL)
- goto loser;
+ goto loser;
return signer;
loser:
if (signer) {
- if (signer->certs)
- ZZ_DestroyList (signer->certs);
- if (signer->sf)
- ZZ_DestroyList (signer->sf);
- PORT_Free (signer);
+ if (signer->certs)
+ ZZ_DestroyList(signer->certs);
+ if (signer->sf)
+ ZZ_DestroyList(signer->sf);
+ PORT_Free(signer);
}
return NULL;
}
-void
+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);
+ 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);
}
}
@@ -517,21 +520,21 @@ JAR_Signer *
jar_get_signer(JAR *jar, char *basename)
{
JAR_Item *it;
- JAR_Context *ctx = JAR_find (jar, NULL, jarTypeOwner);
+ 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;
- }
+ 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);
+ JAR_find_end(ctx);
return signer;
}
@@ -567,12 +570,12 @@ JAR_get_url(JAR *jar)
* Register some manner of callback function for this jar.
*
*/
-int
+int
JAR_set_callback(int type, JAR *jar, jar_settable_callback_fn *fn)
{
if (type == JAR_CB_SIGNAL) {
- jar->signal = fn;
- return 0;
+ jar->signal = fn;
+ return 0;
}
return -1;
}
@@ -583,16 +586,16 @@ JAR_set_callback(int type, JAR *jar, jar_settable_callback_fn *fn)
*/
/* To return an error string */
-char *(*jar_fn_GetString) (int) = NULL;
+char *(*jar_fn_GetString)(int) = NULL;
/* To return an MWContext for Java */
-void *(*jar_fn_FindSomeContext) (void) = NULL;
+void *(*jar_fn_FindSomeContext)(void) = NULL;
/* To fabricate an MWContext for FE_GetPassword */
-void *(*jar_fn_GetInitContext) (void) = NULL;
+void *(*jar_fn_GetInitContext)(void) = NULL;
void
-JAR_init_callbacks(char *(*string_cb)(int),
+JAR_init_callbacks(char *(*string_cb)(int),
void *(*find_cx)(void),
void *(*init_cx)(void))
{
@@ -617,68 +620,68 @@ 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
+ 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;
+ 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/nss/lib/jar/jar.gyp b/nss/lib/jar/jar.gyp
new file mode 100644
index 0000000..e38b4ab
--- /dev/null
+++ b/nss/lib/jar/jar.gyp
@@ -0,0 +1,76 @@
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+{
+ 'includes': [
+ '../../coreconf/config.gypi'
+ ],
+ 'targets': [
+ {
+ 'target_name': 'jar',
+ 'type': 'static_library',
+ 'sources': [
+ 'jar-ds.c',
+ 'jar.c',
+ 'jarfile.c',
+ 'jarint.c',
+ 'jarsign.c',
+ 'jarver.c'
+ ],
+ 'dependencies': [
+ '<(DEPTH)/exports.gyp:nss_exports'
+ ]
+ }
+ ],
+ 'target_defaults': {
+ 'defines': [
+ 'MOZILLA_CLIENT=1',
+ ],
+ 'conditions': [
+ [ 'OS=="win"', {
+ 'configurations': {
+ 'x86_Base': {
+ 'msvs_settings': {
+ 'VCCLCompilerTool': {
+ 'PreprocessorDefinitions': [
+ 'NSS_X86_OR_X64',
+ 'NSS_X86',
+ ],
+ },
+ },
+ },
+ 'x64_Base': {
+ 'msvs_settings': {
+ 'VCCLCompilerTool': {
+ 'PreprocessorDefinitions': [
+ 'NSS_USE_64',
+ 'NSS_X86_OR_X64',
+ 'NSS_X64',
+ ],
+ },
+ },
+ },
+ },
+ }, {
+ 'conditions': [
+ [ 'target_arch=="x64"', {
+ 'defines': [
+ 'NSS_USE_64',
+ 'NSS_X86_OR_X64',
+ 'NSS_X64',
+ ],
+ }],
+ [ 'target_arch=="ia32"', {
+ 'defines': [
+ 'NSS_X86_OR_X64',
+ 'NSS_X86',
+ ],
+ }],
+ ],
+ }],
+ ],
+ },
+ 'variables': {
+ 'module': 'nss'
+ }
+}
diff --git a/nss/lib/jar/jar.h b/nss/lib/jar/jar.h
index 8815560..d337cef 100644
--- a/nss/lib/jar/jar.h
+++ b/nss/lib/jar/jar.h
@@ -36,10 +36,10 @@ typedef enum {
/* 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 */
+ char *pathname; /* relative. inside zip file */
+ jarType type; /* various types */
+ size_t size; /* size of data below */
+ void *data; /* totally opaque */
} JAR_Item;
/* hashes */
@@ -51,9 +51,9 @@ typedef enum {
typedef struct JAR_Digest_ {
jarHash md5_status;
- unsigned char md5 [MD5_LENGTH];
+ unsigned char md5[MD5_LENGTH];
jarHash sha1_status;
- unsigned char sha1 [SHA1_LENGTH];
+ unsigned char sha1[SHA1_LENGTH];
} JAR_Digest;
/* physical archive formats */
@@ -68,35 +68,35 @@ typedef enum {
struct JAR_;
-typedef int jar_settable_callback_fn(int status, struct JAR_ *jar,
- const char *metafile, char *pathname,
- char *errortext);
+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 */
+ jarArch format; /* physical archive format */
- char *url; /* Where it came from */
- char *filename; /* Disk location */
- FILE *fp; /* For multiple extractions */
+ 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 */
+ 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 */
+ 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 */
+ int pkcs7; /* Enforced opaqueness */
+ int valid; /* PKCS7 signature validated */
- ZZList *signers; /* the above, per signer */
+ ZZList *signers; /* the above, per signer */
/* Window context, very necessary for PKCS11 now */
- void *mw; /* MWContext window context */
+ void *mw; /* MWContext window context */
/* Signal callback function */
jar_settable_callback_fn *signal;
@@ -111,20 +111,20 @@ typedef struct JAR_ {
*
*/
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 *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 */
+ 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.
@@ -151,7 +151,6 @@ typedef struct JAR_Cert_ {
CERTCertificate *cert;
} JAR_Cert;
-
/* certificate stuff */
typedef enum {
jarCertCompany = 1,
@@ -164,7 +163,7 @@ typedef enum {
} jarCert;
/* callback types */
-#define JAR_CB_SIGNAL 1
+#define JAR_CB_SIGNAL 1
/*
* This is the base for the JAR error codes. It will
@@ -173,40 +172,40 @@ typedef enum {
*
*/
#ifndef SEC_ERR_BASE
-#define SEC_ERR_BASE (-0x2000)
+#define SEC_ERR_BASE (-0x2000)
#endif
-#define JAR_BASE SEC_ERR_BASE + 300
+#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)
+#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 JAR *JAR_new(void);
-extern void PR_CALLBACK JAR_destroy (JAR *jar);
+extern void PR_CALLBACK JAR_destroy(JAR *jar);
-extern char *JAR_get_error (int status);
+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) );
+extern void
+JAR_init_callbacks(char *(*string_cb)(int),
+ void *(*find_cx)(void),
+ void *(*init_cx)(void));
/*
* JAR_set_context
@@ -220,7 +219,7 @@ JAR_init_callbacks(char *(*string_cb)(int),
* and one will be chosen for you.
*
*/
-int JAR_set_context (JAR *jar, void /*MWContext*/ *mw);
+int JAR_set_context(JAR *jar, void /*MWContext*/ *mw);
/*
* Iterative operations
@@ -236,17 +235,17 @@ int JAR_set_context (JAR *jar, void /*MWContext*/ *mw);
* JAR_Item *item;
* JAR_find (jar, "*.class", jarTypeMF);
* while (JAR_find_next (jar, &item) >= 0)
- * { do stuff }
+ * { do stuff }
*
*/
/* Replacement functions with an external context */
-extern JAR_Context *JAR_find (JAR *jar, char *pattern, jarType type);
+extern JAR_Context *JAR_find(JAR *jar, char *pattern, jarType type);
-extern int JAR_find_next (JAR_Context *ctx, JAR_Item **it);
+extern int JAR_find_next(JAR_Context *ctx, JAR_Item **it);
-extern void JAR_find_end (JAR_Context *ctx);
+extern void JAR_find_end(JAR_Context *ctx);
/*
* Function to parse manifest file:
@@ -273,7 +272,7 @@ extern void JAR_find_end (JAR_Context *ctx);
*
*/
-extern int
+extern int
JAR_parse_manifest(JAR *jar, char *raw_manifest, long length, const char *path,
const char *url);
@@ -283,13 +282,13 @@ JAR_parse_manifest(JAR *jar, char *raw_manifest, long length, const char *path,
*
*/
-extern JAR_Digest * PR_CALLBACK
+extern JAR_Digest *PR_CALLBACK
JAR_calculate_digest(void *data, long length);
-extern int PR_CALLBACK
+extern int PR_CALLBACK
JAR_verify_digest(JAR *jar, const char *name, JAR_Digest *dig);
-extern int
+extern int
JAR_digest_file(char *filename, JAR_Digest *dig);
/*
@@ -309,18 +308,18 @@ JAR_digest_file(char *filename, JAR_Digest *dig);
*
*/
-extern int
-JAR_get_metainfo(JAR *jar, char *name, char *header, void **info,
+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_filename(JAR *jar);
-extern char *JAR_get_url (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
+extern int PR_CALLBACK
JAR_stash_cert(JAR *jar, long keylen, void *key);
/* retrieve a certificate presumably stashed with the above
@@ -341,14 +340,14 @@ JAR_fetch_cert(long length, void *key);
* a list of filenames and certificates from traversing the linked list.
*
*/
-extern int
+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,
+extern int
+JAR_pass_archive_unverified(JAR *jar, jarArch format, char *filename,
const char *url);
/*
@@ -359,7 +358,7 @@ JAR_pass_archive_unverified(JAR *jar, jarArch format, char *filename,
* open between multiple calls to JAR_verify_extract.
*
*/
-extern int
+extern int
JAR_verified_extract(JAR *jar, char *path, char *outpath);
/*
@@ -367,7 +366,7 @@ JAR_verified_extract(JAR *jar, char *path, char *outpath);
* need to extract a manifest file or signature, etc.
*
*/
-extern int
+extern int
JAR_extract(JAR *jar, char *path, char *outpath);
#endif /* __JAR_h_ */
diff --git a/nss/lib/jar/jarfile.c b/nss/lib/jar/jarfile.c
index 96da4d7..e2470a1 100644
--- a/nss/lib/jar/jarfile.c
+++ b/nss/lib/jar/jarfile.c
@@ -20,7 +20,7 @@
#include "sys/stat.h"
#endif
-#include "sechash.h" /* for HASH_GetHashObject() */
+#include "sechash.h" /* for HASH_GetHashObject() */
PR_STATIC_ASSERT(46 == sizeof(struct ZipCentral));
PR_STATIC_ASSERT(30 == sizeof(struct ZipLocal));
@@ -28,50 +28,48 @@ PR_STATIC_ASSERT(22 == sizeof(struct ZipEnd));
PR_STATIC_ASSERT(512 == sizeof(union TarEntry));
/* extracting */
-static int
+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,
+static int
+jar_inflate_memory(unsigned int method, long *length, long expected_out_len,
char **data);
-static int
+static int
jar_physical_extraction(JAR_FILE fp, char *outpath, unsigned long offset,
unsigned long length);
-static int
+static int
jar_physical_inflate(JAR_FILE fp, char *outpath, unsigned long offset,
unsigned long length, unsigned int method);
-static int
+static int
jar_verify_extract(JAR *jar, char *path, char *physical_path);
static JAR_Physical *
jar_get_physical(JAR *jar, char *pathname);
-static int
+static int
jar_extract_manifests(JAR *jar, jarArch format, JAR_FILE fp);
-static int
+static int
jar_extract_mf(JAR *jar, jarArch format, JAR_FILE fp, char *ext);
-
/* indexing */
-static int
+static int
jar_gen_index(JAR *jar, jarArch format, JAR_FILE fp);
-static int
+static int
jar_listtar(JAR *jar, JAR_FILE fp);
-static int
+static int
jar_listzip(JAR *jar, JAR_FILE fp);
-
/* conversions */
-static int
+static int
dosdate(char *date, const char *s);
-static int
+static int
dostime(char *time, const char *s);
#ifdef NSS_X86_OR_X64
@@ -79,8 +77,8 @@ dostime(char *time, const char *s);
#if defined(__GNUC__) && !defined(NSS_NO_GCC48)
#pragma GCC diagnostic ignored "-Wstrict-aliasing"
#endif
-#define x86ShortToUint32(ii) ((const PRUint32)*((const PRUint16 *)(ii)))
-#define x86LongToUint32(ii) (*(const PRUint32 *)(ii))
+#define x86ShortToUint32(ii) ((const PRUint32) * ((const PRUint16 *)(ii)))
+#define x86LongToUint32(ii) (*(const PRUint32 *)(ii))
#else
static PRUint32
x86ShortToUint32(const void *ii);
@@ -89,7 +87,7 @@ static PRUint32
x86LongToUint32(const void *ll);
#endif
-static long
+static long
octalToLong(const char *s);
/*
@@ -100,33 +98,33 @@ octalToLong(const char *s);
* the archive file, and do whatever nastiness.
*
*/
-int
+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;
+ return JAR_ERR_GENERAL;
- if ((fp = JAR_FOPEN (filename, "rb")) != NULL) {
- if (format == jarArchGuess)
- format = (jarArch)jar_guess_jar (filename, fp);
+ 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);
+ 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);
+ 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;
+ JAR_FCLOSE(fp);
+ if (status < 0)
+ return status;
- /* people were expecting it this way */
- return jar->valid;
+ /* people were expecting it this way */
+ return jar->valid;
}
/* file not found */
return JAR_ERR_FNF;
@@ -138,38 +136,38 @@ JAR_pass_archive(JAR *jar, jarArch format, char *filename, const char *url)
* Same as JAR_pass_archive, but doesn't parse signatures.
*
*/
-int
-JAR_pass_archive_unverified(JAR *jar, jarArch format, char *filename,
+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;
+ return JAR_ERR_GENERAL;
}
- if ((fp = JAR_FOPEN (filename, "rb")) != NULL) {
- if (format == jarArchGuess) {
- format = (jarArch)jar_guess_jar (filename, fp);
- }
+ 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);
+ 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");
- }
+ 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;
- }
+ JAR_FCLOSE(fp);
+ if (status < 0) {
+ return status;
+ }
- /* people were expecting it this way */
- return jar->valid;
+ /* people were expecting it this way */
+ return jar->valid;
}
/* file not found */
return JAR_ERR_FNF;
@@ -184,52 +182,51 @@ JAR_pass_archive_unverified(JAR *jar, jarArch format, char *filename,
*
*/
-int
+int
JAR_verified_extract(JAR *jar, char *path, char *outpath)
{
- int status = JAR_extract (jar, path, outpath);
+ int status = JAR_extract(jar, path, outpath);
if (status >= 0)
- return jar_verify_extract(jar, path, outpath);
+ return jar_verify_extract(jar, path, outpath);
return status;
}
-int
+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");
+ jar->fp = (FILE *)JAR_FOPEN(jar->filename, "rb");
}
if (jar->fp == NULL) {
- /* file not found */
- return JAR_ERR_FNF;
+ /* file not found */
+ return JAR_ERR_FNF;
}
- phy = jar_get_physical (jar, path);
+ 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 (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);
+ if (phy->mode)
+ chmod(outpath, 0400 | (mode_t)phy->mode);
#endif
} else {
- /* pathname not found in archive */
- result = JAR_ERR_PNF;
+ /* pathname not found in archive */
+ result = JAR_ERR_PNF;
}
return result;
}
@@ -245,7 +242,7 @@ JAR_extract(JAR *jar, char *path, char *outpath)
#define CHUNK 32768
-static int
+static int
jar_physical_extraction(JAR_FILE fp, char *outpath, unsigned long offset,
unsigned long length)
{
@@ -254,31 +251,31 @@ jar_physical_extraction(JAR_FILE fp, char *outpath, unsigned long offset,
int status = 0;
if (buffer == NULL)
- return JAR_ERR_MEMORY;
-
- if ((out = JAR_FOPEN (outpath, "wb")) != NULL) {
- unsigned 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);
+ return JAR_ERR_MEMORY;
+
+ if ((out = JAR_FOPEN(outpath, "wb")) != NULL) {
+ unsigned 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;
+ /* error opening output file */
+ status = JAR_ERR_DISK;
}
- PORT_Free (buffer);
+ PORT_Free(buffer);
return status;
}
@@ -294,7 +291,7 @@ jar_physical_extraction(JAR_FILE fp, char *outpath, unsigned long offset,
#define ICHUNK 8192
#define OCHUNK 32768
-static int
+static int
jar_physical_inflate(JAR_FILE fp, char *outpath, unsigned long offset, unsigned long length,
unsigned int method)
{
@@ -305,77 +302,77 @@ jar_physical_inflate(JAR_FILE fp, char *outpath, unsigned long offset, unsigned
/* 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;
+ return JAR_ERR_MEMORY;
if ((outbuf = (char *)PORT_ZAlloc(OCHUNK)) == NULL) {
- PORT_Free (inbuf);
- return JAR_ERR_MEMORY;
+ PORT_Free(inbuf);
+ return JAR_ERR_MEMORY;
}
- PORT_Memset (&zs, 0, sizeof (zs));
- status = inflateInit2 (&zs, -MAX_WBITS);
+ 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;
+ PORT_Free(inbuf);
+ PORT_Free(outbuf);
+ return JAR_ERR_GENERAL;
}
- if ((out = JAR_FOPEN (outpath, "wb")) != NULL) {
- unsigned long at = 0;
-
- JAR_FSEEK (fp, offset, (PRSeekWhence)0);
- while (at < length) {
- unsigned 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) < (long)ochunk) {
- /* most likely a disk full error */
- status = JAR_ERR_DISK;
- break;
- }
- if (status == Z_STREAM_END)
- break;
- }
- }
- JAR_FCLOSE (out);
- status = inflateEnd (&zs);
+ if ((out = JAR_FOPEN(outpath, "wb")) != NULL) {
+ unsigned long at = 0;
+
+ JAR_FSEEK(fp, offset, (PRSeekWhence)0);
+ while (at < length) {
+ unsigned 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) < (long)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;
+ /* error opening output file */
+ status = JAR_ERR_DISK;
}
- PORT_Free (inbuf);
- PORT_Free (outbuf);
+ PORT_Free(inbuf);
+ PORT_Free(outbuf);
return status;
}
@@ -386,44 +383,44 @@ jar_physical_inflate(JAR_FILE fp, char *outpath, unsigned long offset, unsigned
* and thus appears to operate inplace to the caller.
*
*/
-static int
-jar_inflate_memory(unsigned int method, long *length, long expected_out_len,
+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;
+ 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;
+ return JAR_ERR_MEMORY;
PORT_Memset(&zs, 0, sizeof zs);
- status = inflateInit2 (&zs, -MAX_WBITS);
+ status = inflateInit2(&zs, -MAX_WBITS);
if (status < 0) {
- /* error initializing zlib stream */
- PORT_Free (outbuf);
- return JAR_ERR_GENERAL;
+ /* error initializing zlib stream */
+ PORT_Free(outbuf);
+ return JAR_ERR_GENERAL;
}
- zs.next_in = (Bytef *) inbuf;
- zs.next_out = (Bytef *) outbuf;
+ 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);
+ status = inflate(&zs, Z_FINISH);
if (status != Z_OK && status != Z_STREAM_END) {
- /* error during deflation */
- PORT_Free (outbuf);
- return JAR_ERR_GENERAL;
+ /* error during deflation */
+ PORT_Free(outbuf);
+ return JAR_ERR_GENERAL;
}
- status = inflateEnd (&zs);
+ status = inflateEnd(&zs);
if (status != Z_OK) {
- /* error during deflation */
- PORT_Free (outbuf);
- return JAR_ERR_GENERAL;
+ /* error during deflation */
+ PORT_Free(outbuf);
+ return JAR_ERR_GENERAL;
}
PORT_Free(*data);
*data = outbuf;
@@ -437,16 +434,16 @@ jar_inflate_memory(unsigned int method, long *length, long expected_out_len,
* Validate signature on the freshly extracted file.
*
*/
-static int
+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);
+ PORT_Memset(&dig, 0, sizeof dig);
+ status = JAR_digest_file(physical_path, &dig);
if (!status)
- status = JAR_verify_digest (jar, path, &dig);
+ status = JAR_verify_digest(jar, path, &dig);
return status;
}
@@ -463,19 +460,19 @@ jar_get_physical(JAR *jar, char *pathname)
ZZLink *link;
ZZList *list = jar->phy;
- if (ZZ_ListEmpty (list))
- return NULL;
+ if (ZZ_ListEmpty(list))
+ return NULL;
- for (link = ZZ_ListHead (list);
- !ZZ_ListIterDone (list, link);
+ for (link = ZZ_ListHead(list);
+ !ZZ_ListIterDone(list, link);
link = link->next) {
- JAR_Item *it = link->thing;
+ 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;
- }
+ if (it->type == jarTypePhy &&
+ it->pathname && !PORT_Strcmp(it->pathname, pathname)) {
+ JAR_Physical *phy = (JAR_Physical *)it->data;
+ return phy;
+ }
}
return NULL;
}
@@ -487,29 +484,29 @@ jar_get_physical(JAR *jar, char *pathname)
* from an open archive file whose contents are known.
*
*/
-static int
+static int
jar_extract_manifests(JAR *jar, jarArch format, JAR_FILE fp)
{
int status, signatures;
if (format != jarArchZip && format != jarArchTar)
- return JAR_ERR_CORRUPT;
+ return JAR_ERR_CORRUPT;
- if ((status = jar_extract_mf (jar, format, fp, "mf")) < 0)
- return status;
+ 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;
+ 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;
+ 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 ((status = jar_extract_mf(jar, format, fp, "dsa")) < 0)
+ return status;
if (!(signatures += status))
- return JAR_ERR_SIG;
+ return JAR_ERR_SIG;
return 0;
}
@@ -521,101 +518,100 @@ jar_extract_manifests(JAR *jar, jarArch format, JAR_FILE fp)
* longer important when zipping jar files.
*
*/
-static int
+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;
+ if (ZZ_ListEmpty(list))
+ return JAR_ERR_PNF;
- for (link = ZZ_ListHead (list);
- ret >= 0 && !ZZ_ListIterDone (list, link);
+ 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 */
- }
+ 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;
}
@@ -627,26 +623,26 @@ jar_extract_mf(JAR *jar, jarArch format, JAR_FILE fp, char *ext)
* known archive files. Right now .ZIP and .TAR
*
*/
-static int
+static int
jar_gen_index(JAR *jar, jarArch format, JAR_FILE fp)
{
int result = JAR_ERR_CORRUPT;
- JAR_FSEEK (fp, 0, (PRSeekWhence)0);
+ JAR_FSEEK(fp, 0, (PRSeekWhence)0);
switch (format) {
- case jarArchZip:
- result = jar_listzip (jar, fp);
- break;
+ case jarArchZip:
+ result = jar_listzip(jar, fp);
+ break;
- case jarArchTar:
- result = jar_listtar (jar, fp);
- break;
+ case jarArchTar:
+ result = jar_listtar(jar, fp);
+ break;
- case jarArchGuess:
- case jarArchNone:
- return JAR_ERR_GENERAL;
+ case jarArchGuess:
+ case jarArchNone:
+ return JAR_ERR_GENERAL;
}
- JAR_FSEEK (fp, 0, (PRSeekWhence)0);
+ JAR_FSEEK(fp, 0, (PRSeekWhence)0);
return result;
}
@@ -657,15 +653,15 @@ jar_gen_index(JAR *jar, jarArch format, JAR_FILE fp)
* style .ZIP file into the JAR linked list.
*
*/
-static int
+static int
jar_listzip(JAR *jar, JAR_FILE fp)
{
- ZZLink *ent;
- JAR_Item *it;
- JAR_Physical *phy;
- struct ZipLocal *Local = PORT_ZNew(struct ZipLocal);
+ ZZLink *ent;
+ JAR_Item *it = NULL;
+ JAR_Physical *phy = NULL;
+ struct ZipLocal *Local = PORT_ZNew(struct ZipLocal);
struct ZipCentral *Central = PORT_ZNew(struct ZipCentral);
- struct ZipEnd *End = PORT_ZNew(struct ZipEnd);
+ struct ZipEnd *End = PORT_ZNew(struct ZipEnd);
int err = 0;
long pos = 0L;
@@ -677,139 +673,141 @@ jar_listzip(JAR *jar, JAR_FILE fp)
char sig[4];
if (!Local || !Central || !End) {
- /* out of memory */
- err = JAR_ERR_MEMORY;
- goto loser;
+ /* 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;
- }
+ 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;
- }
- }
+ /* 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;
- }
+ 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);
+ if (Local)
+ PORT_Free(Local);
+ if (phy && it == NULL)
+ PORT_Free(phy);
+ if (Central)
+ PORT_Free(Central);
+ if (End)
+ PORT_Free(End);
return err;
}
@@ -820,7 +818,7 @@ loser:
* .tar file into the JAR linked list.
*
*/
-static int
+static int
jar_listtar(JAR *jar, JAR_FILE fp)
{
char *s;
@@ -830,37 +828,37 @@ jar_listtar(JAR *jar, JAR_FILE fp)
union TarEntry tarball;
while (1) {
- JAR_FSEEK (fp, pos, (PRSeekWhence)0);
+ JAR_FSEEK(fp, pos, (PRSeekWhence)0);
- if (JAR_FREAD (fp, &tarball, sizeof tarball) < sizeof tarball)
- break;
+ if (JAR_FREAD(fp, &tarball, sizeof tarball) < sizeof tarball)
+ break;
- if (!*tarball.val.filename)
- break;
+ if (!*tarball.val.filename)
+ break;
- sz = octalToLong (tarball.val.size);
+ sz = octalToLong(tarball.val.size);
- /* Tag the end of filename */
- s = tarball.val.filename;
- while (*s && *s != ' ')
- s++;
- *s = 0;
+ /* 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;
+ /* 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;
+ phy->compression = 0;
+ phy->offset = pos + sizeof tarball;
+ phy->length = sz;
- ADDITEM(jar->phy, jarTypePhy, tarball.val.filename, phy,
- sizeof *phy);
+ 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;
+ /* Advance to next file entry */
+ sz = PR_ROUNDUP(sz, sizeof tarball);
+ pos += sz + sizeof tarball;
}
return 0;
@@ -873,13 +871,13 @@ jar_listtar(JAR *jar, JAR_FILE fp)
* it will be needed.
*
*/
-static int
+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));
+ PR_snprintf(date, 9, "%02d-%02d-%02d", ((num >> 5) & 0x0F), (num & 0x1F),
+ ((num >> 9) + 80));
return 0;
}
@@ -890,13 +888,13 @@ dosdate(char *date, const char *s)
* it will be needed.
*
*/
-static int
-dostime (char *time, const char *s)
+static int
+dostime(char *time, const char *s)
{
PRUint32 num = x86ShortToUint32(s);
- PR_snprintf (time, 6, "%02d:%02d", ((num >> 11) & 0x1F),
- ((num >> 5) & 0x3F));
+ PR_snprintf(time, 6, "%02d:%02d", ((num >> 11) & 0x1F),
+ ((num >> 5) & 0x3F));
return 0;
}
@@ -905,7 +903,7 @@ dostime (char *time, const char *s)
* Simulates an x86 (little endian, unaligned) ushort fetch from any address.
*/
static PRUint32
-x86ShortToUint32(const void * v)
+x86ShortToUint32(const void *v)
{
const unsigned char *ii = (const unsigned char *)v;
PRUint32 ret = (PRUint32)(ii[0]) | ((PRUint32)(ii[1]) << 8);
@@ -921,10 +919,10 @@ 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));
+ ret = ((((PRUint32)(ll[0])) << 0) |
+ (((PRUint32)(ll[1])) << 8) |
+ (((PRUint32)(ll[2])) << 16) |
+ (((PRUint32)(ll[3])) << 24));
return ret;
}
#endif
@@ -934,16 +932,16 @@ x86LongToUint32(const void *v)
* Used for integer encoding inside tar files.
*
*/
-static long
+static long
octalToLong(const char *s)
{
long num = 0L;
- while (*s == ' ')
- s++;
+ while (*s == ' ')
+ s++;
while (*s >= '0' && *s <= '7') {
- num <<= 3;
- num += *s++ - '0';
+ num <<= 3;
+ num += *s++ - '0';
}
return num;
}
@@ -956,13 +954,13 @@ octalToLong(const char *s)
* or at its filename.
*
*/
-static int
+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 jarArchTar;
return jarArchZip;
}
diff --git a/nss/lib/jar/jarfile.h b/nss/lib/jar/jarfile.h
index 667415d..52d4f1f 100644
--- a/nss/lib/jar/jarfile.h
+++ b/nss/lib/jar/jarfile.h
@@ -10,49 +10,49 @@
*/
/* 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 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 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];
+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
@@ -60,17 +60,17 @@ struct ZipEnd { /* 22 bytes */
#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];
+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];
+ char buffer[512];
};
diff --git a/nss/lib/jar/jarint.c b/nss/lib/jar/jarint.c
index 2fa220b..b0ef7fb 100644
--- a/nss/lib/jar/jarint.c
+++ b/nss/lib/jar/jarint.c
@@ -14,34 +14,34 @@
* Translate JAR_FOPEN arguments to PR_Open arguments
*/
PRFileDesc*
-JAR_FOPEN_to_PR_Open(const char* name, const char *mode)
+JAR_FOPEN_to_PR_Open(const char* name, const char* mode)
{
- PRIntn prflags=0, prmode=0;
+ 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;
+ prflags |= PR_RDONLY;
+ } else if ((strchr(mode, 'w') || strchr(mode, 'a')) &&
+ !strchr(mode, '+')) {
+ prflags |= PR_WRONLY;
} else {
- prflags |= PR_RDWR;
+ prflags |= PR_RDWR;
}
/* Create a new file? */
if (strchr(mode, 'w') || strchr(mode, 'a')) {
- prflags |= PR_CREATE_FILE;
+ prflags |= PR_CREATE_FILE;
}
/* Append? */
if (strchr(mode, 'a')) {
- prflags |= PR_APPEND;
+ prflags |= PR_APPEND;
}
/* Truncate? */
if (strchr(mode, 'w')) {
- prflags |= PR_TRUNCATE;
+ prflags |= PR_TRUNCATE;
}
/* We can't do umask because it isn't XP. Choose some default
diff --git a/nss/lib/jar/jarint.h b/nss/lib/jar/jarint.h
index 214b8a1..21aecef 100644
--- a/nss/lib/jar/jarint.h
+++ b/nss/lib/jar/jarint.h
@@ -8,33 +8,33 @@
#include "key.h"
#include "base64.h"
-extern CERTCertDBHandle *JAR_open_database (void);
+extern CERTCertDBHandle *JAR_open_database(void);
-extern int JAR_close_database (CERTCertDBHandle *certdb);
+extern int JAR_close_database(CERTCertDBHandle *certdb);
-extern int jar_close_key_database (void *keydb);
+extern int jar_close_key_database(void *keydb);
-extern void *jar_open_key_database (void);
+extern void *jar_open_key_database(void);
-extern JAR_Signer *JAR_new_signer (void);
+extern JAR_Signer *JAR_new_signer(void);
-extern void JAR_destroy_signer (JAR_Signer *signer);
+extern void JAR_destroy_signer(JAR_Signer *signer);
-extern JAR_Signer *jar_get_signer (JAR *jar, char *basename);
+extern JAR_Signer *jar_get_signer(JAR *jar, char *basename);
-extern int
+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*
+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; \
-}
+#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
@@ -42,14 +42,13 @@ JAR_FOPEN_to_PR_Open(const char *name, const char *mode);
/* nspr 2.0 suite */
#define JAR_FILE PRFileDesc *
-#define JAR_FOPEN(fn,mode) JAR_FOPEN_to_PR_Open(fn,mode)
+#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
+int
jar_create_pk7(CERTCertDBHandle *certdb, void *keydb,
CERTCertificate *cert, char *password, JAR_FILE infp,
JAR_FILE outfp);
-
diff --git a/nss/lib/jar/jarnav.c b/nss/lib/jar/jarnav.c
index 6ae763c..8b72a52 100644
--- a/nss/lib/jar/jarnav.c
+++ b/nss/lib/jar/jarnav.c
@@ -16,10 +16,10 @@
extern MWContext *FE_GetInitContext(void);
/* To return an MWContext for Java */
-static MWContext *(*jar_fn_FindSomeContext) (void) = NULL;
+static MWContext *(*jar_fn_FindSomeContext)(void) = NULL;
/* To fabricate an MWContext for FE_GetPassword */
-static MWContext *(*jar_fn_GetInitContext) (void) = NULL;
+static MWContext *(*jar_fn_GetInitContext)(void) = NULL;
/*
* J A R _ i n i t
@@ -28,9 +28,10 @@ static MWContext *(*jar_fn_GetInitContext) (void) = NULL;
*
*/
-void JAR_init (void)
+void
+JAR_init(void)
{
- JAR_init_callbacks (XP_GetString, NULL, NULL);
+ JAR_init_callbacks(XP_GetString, NULL, NULL);
}
/*
@@ -40,23 +41,23 @@ void JAR_init (void)
* it may be needed to prompt the user for a password.
*
*/
-int
+int
JAR_set_context(JAR *jar, MWContext *mw)
{
if (mw) {
- jar->mw = 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();
- }
+ /* 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/nss/lib/jar/jarsign.c b/nss/lib/jar/jarsign.c
index 9beaa3b..601a7fd 100644
--- a/nss/lib/jar/jarsign.c
+++ b/nss/lib/jar/jarsign.c
@@ -8,7 +8,6 @@
* Routines used in signing archives.
*/
-
#include "jar.h"
#include "jarint.h"
#include "secpkcs7.h"
@@ -16,7 +15,7 @@
#include "sechash.h"
/* from libevent.h */
-typedef void (*ETVoidPtrFunc) (void * data);
+typedef void (*ETVoidPtrFunc)(void *data);
/* key database wrapper */
/* static SECKEYKeyDBHandle *jar_open_key_database (void); */
@@ -35,49 +34,51 @@ typedef void (*ETVoidPtrFunc) (void * data);
* This version supports huge pointers for WIN16.
*
*/
-JAR_Digest * PR_CALLBACK
+JAR_Digest *PR_CALLBACK
JAR_calculate_digest(void *data, long length)
{
- PK11Context *md5 = 0;
+ PK11Context *md5 = 0;
PK11Context *sha1 = 0;
- JAR_Digest *dig = PORT_ZNew(JAR_Digest);
+ 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;
+ /* out of memory allocating digest */
+ return NULL;
}
md5 = PK11_CreateDigestContext(SEC_OID_MD5);
if (md5 == NULL) {
- return NULL;
+ PORT_ZFree(dig, sizeof(JAR_Digest));
+ return NULL;
}
sha1 = PK11_CreateDigestContext(SEC_OID_SHA1);
if (sha1 == NULL) {
- PK11_DestroyContext(md5, PR_TRUE);
- return NULL;
+ PK11_DestroyContext(md5, PR_TRUE);
+ /* added due to bug Bug 1250214 - prevent the 2nd memory leak */
+ PORT_ZFree(dig, sizeof(JAR_Digest));
+ return NULL;
}
if (length >= 0) {
- PK11_DigestBegin (md5);
- PK11_DigestBegin (sha1);
+ PK11_DigestBegin(md5);
+ PK11_DigestBegin(sha1);
- do {
- chunq = length;
+ 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_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_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);
+ PK11_DestroyContext(md5, PR_TRUE);
+ PK11_DestroyContext(sha1, PR_TRUE);
}
return dig;
}
@@ -89,62 +90,62 @@ JAR_calculate_digest(void *data, long length)
* present on disk, and returns these in JAR_Digest struct.
*
*/
-int
-JAR_digest_file (char *filename, JAR_Digest *dig)
+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);
+ 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;
+ /* 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;
+ 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);
+ md5 = PK11_CreateDigestContext(SEC_OID_MD5);
+ sha1 = PK11_CreateDigestContext(SEC_OID_SHA1);
if (md5 == NULL || sha1 == NULL) {
- if (md5) {
- PK11_DestroyContext(md5, PR_TRUE);
- }
- if (sha1) {
- PK11_DestroyContext(sha1, PR_TRUE);
- }
- /* can't generate digest contexts */
- PORT_Free (buf);
- JAR_FCLOSE (fp);
- return JAR_ERR_GENERAL;
+ if (md5) {
+ PK11_DestroyContext(md5, PR_TRUE);
+ }
+ if (sha1) {
+ PK11_DestroyContext(sha1, PR_TRUE);
+ }
+ /* can't generate digest contexts */
+ PORT_Free(buf);
+ JAR_FCLOSE(fp);
+ return JAR_ERR_GENERAL;
}
- PK11_DigestBegin (md5);
- PK11_DigestBegin (sha1);
+ PK11_DigestBegin(md5);
+ PK11_DigestBegin(sha1);
while (1) {
- if ((num = JAR_FREAD (fp, buf, FILECHUNQ)) == 0)
- break;
+ if ((num = JAR_FREAD(fp, buf, FILECHUNQ)) == 0)
+ break;
- PK11_DigestOp (md5, buf, num);
- PK11_DigestOp (sha1, buf, num);
+ 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_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);
+ PK11_DestroyContext(md5, PR_TRUE);
+ PK11_DestroyContext(sha1, PR_TRUE);
- PORT_Free (buf);
- JAR_FCLOSE (fp);
+ PORT_Free(buf);
+ JAR_FCLOSE(fp);
return 0;
}
@@ -154,32 +155,32 @@ JAR_digest_file (char *filename, JAR_Digest *dig)
*
*/
-void*
+void *
jar_open_key_database(void)
{
return NULL;
}
-int
+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)
+static void
+jar_pk7_out(void *arg, const char *buf, unsigned long len)
{
- JAR_FWRITE ((JAR_FILE) arg, buf, len);
+ JAR_FWRITE((JAR_FILE)arg, buf, len);
}
-int
-jar_create_pk7(CERTCertDBHandle *certdb, void *keydb, CERTCertificate *cert,
+int
+jar_create_pk7(CERTCertDBHandle *certdb, void *keydb, CERTCertificate *cert,
char *password, JAR_FILE infp, JAR_FILE outfp)
{
SEC_PKCS7ContentInfo *cinfo;
@@ -194,42 +195,42 @@ jar_create_pk7(CERTCertDBHandle *certdb, void *keydb, CERTCertificate *cert,
unsigned char buffer[4096];
if (outfp == NULL || infp == NULL || cert == NULL)
- return JAR_ERR_GENERAL;
+ return JAR_ERR_GENERAL;
/* we sign with SHA */
hashObj = HASH_GetHashObject(HASH_AlgSHA1);
- hashcx = (* hashObj->create)();
+ hashcx = (*hashObj->create)();
if (hashcx == NULL)
- return JAR_ERR_GENERAL;
+ return JAR_ERR_GENERAL;
- (* hashObj->begin)(hashcx);
+ (*hashObj->begin)(hashcx);
while (1) {
- int nb = JAR_FREAD(infp, buffer, sizeof buffer);
- if (nb == 0) { /* eof */
- break;
- }
- (* hashObj->update) (hashcx, buffer, nb);
+ 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);
+ (*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);
+ 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;
+ return JAR_ERR_PK7;
rv = SEC_PKCS7IncludeCertChain(cinfo, NULL);
if (rv != SECSuccess) {
- status = PORT_GetError();
- SEC_PKCS7DestroyContentInfo(cinfo);
- return status;
+ status = PORT_GetError();
+ SEC_PKCS7DestroyContentInfo(cinfo);
+ return status;
}
/* Having this here forces signtool to always include signing time. */
@@ -240,10 +241,10 @@ jar_create_pk7(CERTCertDBHandle *certdb, void *keydb, CERTCertificate *cert,
/* 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);
+ status = PORT_GetError();
+ SEC_PKCS7DestroyContentInfo(cinfo);
if (rv != SECSuccess) {
- return ((status < 0) ? status : JAR_ERR_GENERAL);
+ return ((status < 0) ? status : JAR_ERR_GENERAL);
}
return 0;
}
diff --git a/nss/lib/jar/jarver.c b/nss/lib/jar/jarver.c
index fa3c8a0..38d73c2 100644
--- a/nss/lib/jar/jarver.c
+++ b/nss/lib/jar/jarver.c
@@ -37,7 +37,7 @@ 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);
+ long length, JAR *jar);
static int
jar_add_cert(JAR *jar, JAR_Signer *signer, int type, CERTCertificate *cert);
@@ -53,20 +53,20 @@ static int jar_insanity_check(char *data, long length);
int
jar_parse_mf(JAR *jar, char *raw_manifest, long length,
- const char *path, const char *url);
+ const char *path, const char *url);
int
jar_parse_sf(JAR *jar, char *raw_manifest, long length,
- const char *path, const char *url);
+ const char *path, const char *url);
int
jar_parse_sig(JAR *jar, const char *path, char *raw_manifest,
- long length);
+ long length);
int
jar_parse_any(JAR *jar, int type, JAR_Signer *signer,
- char *raw_manifest, long length, const char *path,
- const char *url);
+ 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);
@@ -83,45 +83,43 @@ jar_internal_digest(JAR *jar, const char *path, char *x_name, JAR_Digest *dig);
*/
int
JAR_parse_manifest(JAR *jar, char *raw_manifest, long length,
- const char *path, const char *url)
+ 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 */
+ 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;
+ 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. */
+ 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;
- }
+ 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 */
+ 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);
+ 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);
+ /* This is probably a binary signature */
+ return jar_parse_sig(jar, path, raw_manifest, length);
}
}
@@ -134,47 +132,46 @@ JAR_parse_manifest(JAR *jar, char *raw_manifest, long length,
*/
int
jar_parse_sig(JAR *jar, const char *path, char *raw_manifest,
- long length)
+ long length)
{
JAR_Signer *signer;
int status = JAR_ERR_ORDER;
if (length <= 128) {
- /* signature is way too small */
- return JAR_ERR_SIG;
+ /* 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;
+ return JAR_ERR_ORDER;
/* Determine whether or not this RSA file has
- has an associated SF file */
+ has an associated SF file */
if (path) {
- char *owner;
- owner = jar_basename(path);
+ char *owner;
+ owner = jar_basename(path);
- if (owner == NULL)
- return JAR_ERR_MEMORY;
+ if (owner == NULL)
+ return JAR_ERR_MEMORY;
- signer = jar_get_signer(jar, owner);
- PORT_Free(owner);
+ signer = jar_get_signer(jar, owner);
+ PORT_Free(owner);
} else
- signer = jar_get_signer(jar, "*");
+ signer = jar_get_signer(jar, "*");
if (signer == NULL)
- return JAR_ERR_ORDER;
-
+ 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. */
+ 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;
+ /* this digital signature is way too big */
+ return JAR_ERR_SIG;
}
/* don't expense unneeded calloc overhead on non-win16 */
@@ -192,19 +189,19 @@ jar_parse_sig(JAR *jar, const char *path, char *raw_manifest,
*/
int
jar_parse_mf(JAR *jar, char *raw_manifest, long length,
- const char *path, const char *url)
+ const char *path, const char *url)
{
if (jar->globalmeta) {
- /* refuse a second manifest file, if passed for some reason */
- return JAR_ERR_ORDER;
+ /* 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_ERR_MEMORY;
return jar_parse_any(jar, jarTypeMF, NULL, raw_manifest, length,
- path, url);
+ path, url);
}
/*
@@ -216,50 +213,50 @@ jar_parse_mf(JAR *jar, char *raw_manifest, long length,
*/
int
jar_parse_sf(JAR *jar, char *raw_manifest, long length,
- const char *path, const char *url)
+ 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;
+ /* 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;
+ goto loser;
if (path) {
- signer->owner = jar_basename(path);
- if (signer->owner == NULL)
- goto loser;
+ 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 */
+ 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;
+ /* someone is trying to spoof us */
+ status = JAR_ERR_ORDER;
+ goto loser;
}
/* remember its digest */
- signer->digest = JAR_calculate_digest (raw_manifest, length);
+ signer->digest = JAR_calculate_digest(raw_manifest, length);
if (signer->digest == NULL)
- goto loser;
+ goto loser;
/* Add this signer to the jar */
ADDITEM(jar->signers, jarTypeOwner, signer->owner, signer,
- sizeof (JAR_Signer));
+ sizeof(JAR_Signer));
return jar_parse_any(jar, jarTypeSF, signer, raw_manifest, length,
- path, url);
+ path, url);
loser:
if (signer)
- JAR_destroy_signer (signer);
+ JAR_destroy_signer(signer);
return status;
}
@@ -269,16 +266,16 @@ loser:
* 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
+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 line[SZ];
+ char x_name[SZ], x_md5[SZ], x_sha[SZ];
char *x_info;
char *sf_md5 = NULL, *sf_sha1 = NULL;
@@ -286,12 +283,12 @@ jar_parse_any(JAR *jar, int type, JAR_Signer *signer,
*x_md5 = 0;
*x_sha = 0;
- PORT_Assert( length > 0 );
+ PORT_Assert(length > 0);
raw_len = length;
#ifdef DEBUG
if ((status = jar_insanity_check(raw_manifest, raw_len)) < 0)
- return status;
+ return status;
#endif
/* null terminate the first line */
@@ -300,262 +297,270 @@ jar_parse_any(JAR *jar, int type, JAR_Signer *signer,
/* 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);
- }
+ 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;
+ } else if (!PORT_Strcasecmp(line, "SHA1-Digest") ||
+ !PORT_Strcasecmp(line, "SHA-Digest")) {
+ sf_sha1 = (char *)met->info;
+ } else {
+ PORT_Free(met->info);
+ met->info = NULL;
+ }
+ }
+
+ if (type != jarTypeMF) {
+ PORT_Free(met->header);
+ if ((type != jarTypeSF || !jar->globalmeta) && met->info) {
+ 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. */
+ /* 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;
+ int match = 0;
+ JAR_Digest *glob = jar->globalmeta;
- if (sf_md5) {
- unsigned int md5_length;
- unsigned char *md5_digest;
+ 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 );
+ md5_digest = ATOB_AsciiToData(sf_md5, &md5_length);
+ PORT_Assert(md5_length == MD5_LENGTH);
+ PORT_Free(sf_md5);
- if (md5_length != MD5_LENGTH)
- return JAR_ERR_CORRUPT;
+ if (md5_length != MD5_LENGTH)
+ return JAR_ERR_CORRUPT;
- match = PORT_Memcmp(md5_digest, glob->md5, MD5_LENGTH);
- }
+ match = PORT_Memcmp(md5_digest, glob->md5, MD5_LENGTH);
+ PORT_Free(md5_digest);
+ }
- if (sf_sha1 && match == 0) {
- unsigned int sha1_length;
- unsigned char *sha1_digest;
+ 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 );
+ sha1_digest = ATOB_AsciiToData(sf_sha1, &sha1_length);
+ PORT_Assert(sha1_length == SHA1_LENGTH);
+ PORT_Free(sf_sha1);
- if (sha1_length != SHA1_LENGTH)
- return JAR_ERR_CORRUPT;
+ if (sha1_length != SHA1_LENGTH)
+ return JAR_ERR_CORRUPT;
- match = PORT_Memcmp(sha1_digest, glob->sha1, SHA1_LENGTH);
- }
+ match = PORT_Memcmp(sha1_digest, glob->sha1, SHA1_LENGTH);
+ PORT_Free(sha1_digest);
+ }
- if (match != 0) {
- /* global digest doesn't match, SF file therefore invalid */
- jar->valid = JAR_ERR_METADATA;
- return JAR_ERR_METADATA;
- }
+ 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;
- }
+ *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;
+ PORT_Free(binary_digest);
+ }
+
+ 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_Free(binary_digest);
+ }
+
+ 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;
@@ -571,45 +576,45 @@ jar_internal_digest(JAR *jar, const char *path, char *x_name, JAR_Digest *dig)
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;
+ /* 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;
- }
+ 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;
- }
+ 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;
}
@@ -631,10 +636,10 @@ jar_insanity_check(char *data, long length)
long off;
for (off = 0; off < length; off++) {
- c = data [off];
- if (c == '\n' || c == '\r' || (c >= ' ' && c <= 128))
- continue;
- return JAR_ERR_CORRUPT;
+ c = data[off];
+ if (c == '\n' || c == '\r' || (c >= ' ' && c <= 128))
+ continue;
+ return JAR_ERR_CORRUPT;
}
return 0;
}
@@ -649,9 +654,9 @@ jar_insanity_check(char *data, long length)
*/
static int
jar_parse_digital_signature(char *raw_manifest, JAR_Signer *signer,
- long length, JAR *jar)
+ long length, JAR *jar)
{
- return jar_validate_pkcs7 (jar, signer, raw_manifest, length);
+ return jar_validate_pkcs7(jar, signer, raw_manifest, length);
}
/*
@@ -670,33 +675,33 @@ jar_add_cert(JAR *jar, JAR_Signer *signer, int type, CERTCertificate *cert)
unsigned char *keyData;
if (cert == NULL)
- return JAR_ERR_ORDER;
+ return JAR_ERR_ORDER;
fing = PORT_ZNew(JAR_Cert);
if (fing == NULL)
- goto loser;
+ goto loser;
- fing->cert = CERT_DupCertificate (cert);
+ 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);
+ fing->key = keyData = (unsigned char *)PORT_ZAlloc(fing->length);
if (fing->key == NULL)
- goto loser;
+ 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);
+ PORT_Memcpy(&keyData[2 + cert->derIssuer.len], cert->serialNumber.data,
+ cert->serialNumber.len);
- ADDITEM (signer->certs, type, NULL, fing, sizeof (JAR_Cert));
+ ADDITEM(signer->certs, type, NULL, fing, sizeof(JAR_Cert));
return 0;
loser:
if (fing) {
- if (fing->cert)
- CERT_DestroyCertificate (fing->cert);
- PORT_Free(fing);
+ if (fing->cert)
+ CERT_DestroyCertificate(fing->cert);
+ PORT_Free(fing);
}
return JAR_ERR_MEMORY;
}
@@ -710,10 +715,10 @@ loser:
* 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
+ * 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 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.
@@ -729,43 +734,43 @@ jar_eat_line(int lines, int eating, char *data, long *len)
long maxLen = *len;
if (maxLen <= 0)
- return start;
+ 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++;
+ for (/* yip */; lines > 0; lines--) {
+ while (GO_ON && *data && *data != '\r' && *data != '\n')
+ data++;
- /* Eat any leading CR */
- if (GO_ON && *data == '\r')
- 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++;
+ /* 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++;
+ /* 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. */
+ 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++;
+ /* 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;
+ /* 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;
+ /* After the CR (if any), if not past the end, ok to eat one LF */
+ if (GO_ON && *data == '\n')
+ *data++ = 0;
}
return start;
}
@@ -788,11 +793,11 @@ jar_digest_section(char *manifest, long length)
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;
+ 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);
+ return JAR_calculate_digest(manifest, global_end - manifest);
}
/*
@@ -812,45 +817,38 @@ JAR_verify_digest(JAR *jar, const char *name, JAR_Digest *dig)
int result1 = 0;
int result2 = 0;
-
if (jar->valid < 0) {
- /* signature not valid */
- return JAR_ERR_SIG;
+ /* signature not valid */
+ return JAR_ERR_SIG;
}
- if (ZZ_ListEmpty (list)) {
- /* empty list */
- return JAR_ERR_PNF;
+ 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;
- }
+ 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
*
@@ -869,13 +867,13 @@ JAR_fetch_cert(long length, void *key)
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);
+ 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;
}
@@ -895,18 +893,18 @@ jar_get_mf_digest(JAR *jar, char *pathname)
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;
- }
+ 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;
}
@@ -924,21 +922,21 @@ jar_basename(const char *path)
char *pith, *e, *basename, *ext;
if (path == NULL)
- return PORT_Strdup("");
+ 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;
+ for (e = basename; *e && *e != '/' && *e != '\\'; e++)
+ /* yip */;
+ if (*e)
+ basename = ++e;
+ else
+ break;
}
if ((ext = PORT_Strrchr(basename, '.')) != NULL)
- *ext = 0;
+ *ext = 0;
/* We already have the space allocated */
PORT_Strcpy(pith, basename);
@@ -968,7 +966,7 @@ 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. */
+ presumably no data in the signature itself. */
}
/*
@@ -978,7 +976,7 @@ jar_catch_bytes(void *arg, const char *buf, unsigned long len)
* signature in DER format.
*
*/
-static int
+static int
jar_validate_pkcs7(JAR *jar, JAR_Signer *signer, char *data, long length)
{
@@ -988,35 +986,35 @@ jar_validate_pkcs7(JAR *jar, JAR_Signer *signer, char *data, long length)
int status = 0;
SECItem detdig;
- PORT_Assert( jar != NULL && signer != NULL );
+ PORT_Assert(jar != NULL && signer != NULL);
if (jar == NULL || signer == NULL)
- return JAR_ERR_ORDER;
+ 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);
+ NULL /*getpassword*/, jar->mw,
+ NULL, NULL, NULL);
if (dcx == NULL) {
- /* strange pkcs7 failure */
- return JAR_ERR_PK7;
+ /* strange pkcs7 failure */
+ return JAR_ERR_PK7;
}
- SEC_PKCS7DecoderUpdate (dcx, data, length);
- cinfo = SEC_PKCS7DecoderFinish (dcx);
+ SEC_PKCS7DecoderUpdate(dcx, data, length);
+ cinfo = SEC_PKCS7DecoderFinish(dcx);
if (cinfo == NULL) {
- /* strange pkcs7 failure */
- return JAR_ERR_PK7;
+ /* strange pkcs7 failure */
+ return JAR_ERR_PK7;
}
- if (SEC_PKCS7ContentIsEncrypted (cinfo)) {
- /* content was encrypted, fail */
- 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;
+ if (SEC_PKCS7ContentIsSigned(cinfo) == PR_FALSE) {
+ /* content was not signed, fail */
+ return JAR_ERR_PK7;
}
PORT_SetError(0);
@@ -1025,20 +1023,20 @@ jar_validate_pkcs7(JAR *jar, JAR_Signer *signer, char *data, long length)
detdig.len = SHA1_LENGTH;
detdig.data = signer->digest->sha1;
goodSig = SEC_PKCS7VerifyDetachedSignature(cinfo,
- certUsageObjectSigner,
- &detdig, HASH_AlgSHA1,
- PR_FALSE);
+ certUsageObjectSigner,
+ &detdig, HASH_AlgSHA1,
+ PR_FALSE);
jar_gather_signers(jar, signer, cinfo);
if (goodSig == PR_TRUE) {
- /* signature is valid */
- signer->valid = 0;
+ /* 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;
+ 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;
@@ -1063,25 +1061,25 @@ jar_gather_signers(JAR *jar, JAR_Signer *signer, SEC_PKCS7ContentInfo *cinfo)
SEC_PKCS7SignerInfo **pksigners, *pksigner;
if (sdp == NULL)
- return JAR_ERR_PK7;
+ return JAR_ERR_PK7;
pksigners = sdp->signerInfos;
/* permit exactly one signer */
- if (pksigners == NULL || pksigners [0] == NULL || pksigners [1] != NULL)
- return JAR_ERR_PK7;
+ 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;
+ return JAR_ERR_PK7;
certdb = JAR_open_database();
if (certdb == NULL)
- return JAR_ERR_GENERAL;
+ return JAR_ERR_GENERAL;
result = jar_add_cert(jar, signer, jarTypeSign, cert);
- JAR_close_database (certdb);
+ JAR_close_database(certdb);
return result;
}
@@ -1105,13 +1103,12 @@ JAR_open_database(void)
* For use by JAR functions.
*
*/
-int
+int
JAR_close_database(CERTCertDBHandle *certdb)
{
return 0;
}
-
/*
* j a r _ s i g n a l
*
@@ -1121,10 +1118,10 @@ JAR_close_database(CERTCertDBHandle *certdb)
static int
jar_signal(int status, JAR *jar, const char *metafile, char *pathname)
{
- char *errstring = JAR_get_error (status);
+ char *errstring = JAR_get_error(status);
if (jar->signal) {
- (*jar->signal) (status, jar, metafile, pathname, errstring);
- return 0;
+ (*jar->signal)(status, jar, metafile, pathname, errstring);
+ return 0;
}
return status;
}
@@ -1143,28 +1140,28 @@ jar_append(ZZList *list, int type, char *pathname, void *data, size_t size)
ZZLink *entity;
if (it == NULL)
- goto loser;
+ goto loser;
if (pathname) {
- it->pathname = PORT_Strdup(pathname);
- if (it->pathname == NULL)
- goto loser;
+ it->pathname = PORT_Strdup(pathname);
+ if (it->pathname == NULL)
+ goto loser;
}
it->type = (jarType)type;
- it->data = (unsigned char *) data;
+ it->data = (unsigned char *)data;
it->size = size;
- entity = ZZ_NewLink (it);
+ entity = ZZ_NewLink(it);
if (entity) {
- ZZ_AppendLink (list, entity);
- return 0;
+ ZZ_AppendLink(list, entity);
+ return 0;
}
loser:
if (it) {
- if (it->pathname)
- PORT_Free(it->pathname);
- PORT_Free(it);
+ if (it->pathname)
+ PORT_Free(it->pathname);
+ PORT_Free(it);
}
return JAR_ERR_MEMORY;
}
diff --git a/nss/lib/jar/jzconf.h b/nss/lib/jar/jzconf.h
index 59012e2..7687eb3 100644
--- a/nss/lib/jar/jzconf.h
+++ b/nss/lib/jar/jzconf.h
@@ -1,6 +1,6 @@
/* 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
+ * For conditions of distribution and use, see copyright notice in zlib.h
*/
/* This file was modified since it was taken from the zlib distribution */
@@ -12,49 +12,49 @@
* 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
+#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
+#define WIN32
#endif
#if defined(__GNUC__) || defined(WIN32) || defined(__386__) || defined(i386)
-# ifndef __32BIT__
-# define __32BIT__
-# endif
+#ifndef __32BIT__
+#define __32BIT__
+#endif
#endif
#if defined(__MSDOS__) && !defined(MSDOS)
-# define MSDOS
+#define MSDOS
#endif
/*
@@ -62,42 +62,42 @@
* than 64k bytes at a time (needed on systems with 16-bit int).
*/
#if defined(MSDOS) && !defined(__32BIT__)
-# define MAXSEG_64K
+#define MAXSEG_64K
#endif
#ifdef MSDOS
-# define UNALIGNED_OK
+#define UNALIGNED_OK
#endif
-#if (defined(MSDOS) || defined(_WINDOWS) || defined(WIN32) || defined(XP_OS2)) && !defined(STDC)
-# define STDC
+#if (defined(MSDOS) || defined(_WINDOWS) || defined(WIN32) || defined(XP_OS2)) && !defined(STDC)
+#define STDC
#endif
#if (defined(__STDC__) || defined(__cplusplus)) && !defined(STDC)
-# define STDC
+#define STDC
#endif
#ifndef STDC
-# ifndef const /* cannot use !defined(STDC) && !defined(const) on Mac */
-# define const
-# endif
+#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
+#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
+#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 */
+#define MAX_WBITS 15 /* 32K LZ77 window */
#endif
/* The memory requirements for deflate are (in bytes):
@@ -113,14 +113,14 @@
for small objects.
*/
- /* Type declarations */
+/* Type declarations */
#ifndef OF /* function prototypes */
-# ifdef STDC
-# define OF(args) args
-# else
-# define OF(args) ()
-# endif
+#ifdef STDC
+#define OF(args) args
+#else
+#define OF(args) ()
+#endif
#endif
/* The following definitions for FAR are needed only for MSDOS mixed
@@ -130,45 +130,45 @@
* 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
+/* 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
+#ifndef __32BIT__
+#define SMALL_MEDIUM
+#define FAR __far
+#endif
#endif
#ifndef FAR
-# define 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 */
+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
+/* Borland C/C++ ignores FAR inside typedef */
+#define Bytef Byte FAR
#else
- typedef Byte FAR Bytef;
+typedef Byte FAR Bytef;
#endif
-typedef char FAR charf;
-typedef int FAR intf;
-typedef uInt FAR uIntf;
+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;
+typedef void FAR *voidpf;
+typedef void *voidp;
#else
- typedef Byte FAR *voidpf;
- typedef Byte *voidp;
+typedef Byte FAR *voidpf;
+typedef Byte *voidp;
#endif
#ifdef MOZILLA_CLIENT
@@ -176,10 +176,10 @@ typedef uLong FAR uLongf;
#else
/* Compile with -DZLIB_DLL for Windows DLL support */
#if (defined(_WINDOWS) || defined(WINDOWS)) && defined(ZLIB_DLL)
-# include <windows.h>
-# define EXPORT WINAPI
+#include <windows.h>
+#define EXPORT WINAPI
#else
-# define EXPORT
+#define EXPORT
#endif
#define PR_PUBLIC_API(type) type
diff --git a/nss/lib/jar/jzlib.h b/nss/lib/jar/jzlib.h
index aa25c28..92d3d5b 100644
--- a/nss/lib/jar/jzlib.h
+++ b/nss/lib/jar/jzlib.h
@@ -44,7 +44,7 @@ extern "C" {
#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
@@ -68,30 +68,30 @@ extern "C" {
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));
+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_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 */
+ 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 */
+ 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 */
+ 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 */
+ 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;
@@ -125,58 +125,59 @@ typedef z_stream FAR *z_streamp;
a single step).
*/
- /* constants */
+/* constants */
-#define Z_NO_FLUSH 0
+#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_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_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_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)
+#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
+#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
+#define Z_BINARY 0
+#define Z_ASCII 1
+#define Z_UNKNOWN 2
/* Possible values of the data_type field */
-#define Z_DEFLATED 8
+#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 Z_NULL 0 /* for initializing zalloc, zfree, opaque */
#define zlib_version zlibVersion()
/* for compatibility with versions < 1.0.2 */
- /* basic functions */
+/* basic functions */
#ifdef MOZILLA_CLIENT
-PR_EXTERN(const char *) zlibVersion (void);
+PR_EXTERN(const char *)
+zlibVersion(void);
#else
-extern const char * EXPORT zlibVersion OF((void));
+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
@@ -184,7 +185,7 @@ extern const char * EXPORT zlibVersion OF((void));
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
@@ -206,9 +207,9 @@ extern int EXPORT deflateInit OF((z_streamp strm, int level));
perform any compression: this will be done by deflate().
*/
-
#ifdef MOZILLA_CLIENT
-PR_EXTERN(int) deflate (z_streamp strm, int flush);
+PR_EXTERN(int)
+deflate(z_streamp strm, int flush);
#else
extern int EXPORT deflate OF((z_streamp strm, int flush));
#endif
@@ -261,7 +262,7 @@ extern int EXPORT deflate OF((z_streamp strm, int flush));
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
@@ -279,9 +280,9 @@ extern int EXPORT deflate OF((z_streamp strm, int flush));
if next_in or next_out was NULL), Z_BUF_ERROR if no progress is possible.
*/
-
#ifdef MOZILLA_CLIENT
-PR_EXTERN(int) deflateEnd (z_streamp strm);
+PR_EXTERN(int)
+deflateEnd(z_streamp strm);
#else
extern int EXPORT deflateEnd OF((z_streamp strm));
#endif
@@ -297,8 +298,7 @@ extern int EXPORT deflateEnd OF((z_streamp strm));
deallocated).
*/
-
-/*
+/*
extern int EXPORT inflateInit OF((z_streamp strm));
Initializes the internal stream state for decompression. The fields
@@ -313,9 +313,9 @@ extern int EXPORT inflateInit OF((z_streamp strm));
done by inflate().
*/
-
#ifdef MOZILLA_CLIENT
-PR_EXTERN(int) inflate (z_streamp strm, int flush);
+PR_EXTERN(int)
+inflate(z_streamp strm, int flush);
#else
extern int EXPORT inflate OF((z_streamp strm, int flush));
#endif
@@ -372,9 +372,9 @@ extern int EXPORT inflate OF((z_streamp strm, int flush));
dictionary chosen by the compressor.
*/
-
#ifdef MOZILLA_CLIENT
-PR_EXTERN(int) inflateEnd (z_streamp strm);
+PR_EXTERN(int)
+inflateEnd(z_streamp strm);
#else
extern int EXPORT inflateEnd OF((z_streamp strm));
#endif
@@ -388,13 +388,13 @@ extern int EXPORT inflateEnd OF((z_streamp strm));
static string (which must not be deallocated).
*/
- /* Advanced functions */
+/* Advanced functions */
/*
The following functions are needed only in some special applications.
*/
-/*
+/*
extern int EXPORT deflateInit2 OF((z_streamp strm,
int level,
int method,
@@ -450,17 +450,18 @@ extern int EXPORT deflateInit2 OF((z_streamp strm,
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().
+ deflate().
*/
-
+
#ifdef MOZILLA_CLIENT
-PR_EXTERN(int) deflateSetDictionary (z_streamp strm,
- const Bytef *dictionary,
- uInt dictLength);
+PR_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));
+ uInt dictLength));
#endif
/*
Initializes the compression dictionary (history buffer) from the given
@@ -485,11 +486,12 @@ extern int EXPORT deflateSetDictionary OF((z_streamp strm,
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().
+ be done by deflate().
*/
#ifdef MOZILLA_CLIENT
-PR_EXTERN(int) deflateCopy (z_streamp dest, z_streamp source);
+PR_EXTERN(int)
+deflateCopy(z_streamp dest, z_streamp source);
#else
extern int EXPORT deflateCopy OF((z_streamp dest, z_streamp source));
#endif
@@ -515,7 +517,8 @@ extern int EXPORT deflateCopy OF((z_streamp dest, z_streamp source));
*/
#ifdef MOZILLA_CLIENT
-PR_EXTERN(int) deflateReset (z_streamp strm);
+PR_EXTERN(int)
+deflateReset(z_streamp strm);
#else
extern int EXPORT deflateReset OF((z_streamp strm));
#endif
@@ -530,7 +533,8 @@ extern int EXPORT deflateReset OF((z_streamp strm));
*/
#ifdef MOZILLA_CLIENT
-PR_EXTERN(int) deflateParams (z_streamp strm, int level, int strategy);
+PR_EXTERN(int)
+deflateParams(z_streamp strm, int level, int strategy);
#else
extern int EXPORT deflateParams OF((z_streamp strm, int level, int strategy));
#endif
@@ -551,7 +555,7 @@ extern int EXPORT deflateParams OF((z_streamp strm, int level, int strategy));
if strm->avail_out was zero.
*/
-/*
+/*
extern int EXPORT inflateInit2 OF((z_streamp strm,
int windowBits));
@@ -587,13 +591,14 @@ extern int EXPORT inflateInit2 OF((z_streamp strm,
*/
#ifdef MOZILLA_CLIENT
-PR_EXTERN(int) inflateSetDictionary (z_streamp strm,
- const Bytef *dictionary,
- uInt dictLength);
+PR_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));
+ const Bytef *dictionary,
+ uInt dictLength));
#endif
/*
Initializes the decompression dictionary (history buffer) from the given
@@ -612,11 +617,12 @@ extern int EXPORT inflateSetDictionary OF((z_streamp strm,
*/
#ifdef MOZILLA_CLIENT
-PR_EXTERN(int) inflateSync (z_streamp strm);
+PR_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.
@@ -631,7 +637,8 @@ extern int EXPORT inflateSync OF((z_streamp strm));
*/
#ifdef MOZILLA_CLIENT
-PR_EXTERN(int) inflateReset (z_streamp strm);
+PR_EXTERN(int)
+inflateReset(z_streamp strm);
#else
extern int EXPORT inflateReset OF((z_streamp strm));
#endif
@@ -644,8 +651,7 @@ extern int EXPORT inflateReset OF((z_streamp strm));
stream state was inconsistent (such as zalloc or state being NULL).
*/
-
- /* utility functions */
+/* utility functions */
/*
The following utility functions are implemented on top of the
@@ -656,11 +662,12 @@ extern int EXPORT inflateReset OF((z_streamp strm));
*/
#ifdef MOZILLA_CLIENT
-PR_EXTERN(int) compress (Bytef *dest, uLongf *destLen,
- const Bytef *source, uLong sourceLen);
+PR_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));
+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
@@ -676,11 +683,12 @@ extern int EXPORT compress OF((Bytef *dest, uLongf *destLen,
*/
#ifdef MOZILLA_CLIENT
-PR_EXTERN(int) uncompress (Bytef *dest, uLongf *destLen,
- const Bytef *source, uLong sourceLen);
+PR_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));
+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
@@ -698,13 +706,13 @@ extern int EXPORT uncompress OF((Bytef *dest, uLongf *destLen,
buffer, or Z_DATA_ERROR if the input data was corrupted.
*/
-
typedef voidp gzFile;
#ifdef MOZILLA_CLIENT
-PR_EXTERN(gzFile) gzopen (const char *path, const char *mode);
+PR_EXTERN(gzFile)
+gzopen(const char *path, const char *mode);
#else
-extern gzFile EXPORT gzopen OF((const char *path, const char *mode));
+extern gzFile EXPORT gzopen OF((const char *path, const char *mode));
#endif
/*
Opens a gzip (.gz) file for reading or writing. The mode parameter
@@ -718,9 +726,10 @@ extern gzFile EXPORT gzopen OF((const char *path, const char *mode));
*/
#ifdef MOZILLA_CLIENT
-PR_EXTERN(gzFile) gzdopen (int fd, const char *mode);
+PR_EXTERN(gzFile)
+gzdopen(int fd, const char *mode);
#else
-extern gzFile EXPORT gzdopen OF((int fd, const char *mode));
+extern gzFile EXPORT gzdopen OF((int fd, const char *mode));
#endif
/*
gzdopen() associates a gzFile with the file descriptor fd. File
@@ -735,9 +744,10 @@ extern gzFile EXPORT gzdopen OF((int fd, const char *mode));
*/
#ifdef MOZILLA_CLIENT
-PR_EXTERN(int) gzread (gzFile file, voidp buf, unsigned len);
+PR_EXTERN(int)
+gzread(gzFile file, voidp buf, unsigned len);
#else
-extern int EXPORT gzread OF((gzFile file, voidp buf, unsigned len));
+extern int EXPORT gzread OF((gzFile file, voidp buf, unsigned len));
#endif
/*
Reads the given number of uncompressed bytes from the compressed file.
@@ -747,9 +757,10 @@ extern int EXPORT gzread OF((gzFile file, voidp buf, unsigned len));
end of file, -1 for error). */
#ifdef MOZILLA_CLIENT
-PR_EXTERN(int) gzwrite (gzFile file, const voidp buf, unsigned len);
+PR_EXTERN(int)
+gzwrite(gzFile file, const voidp buf, unsigned len);
#else
-extern int EXPORT gzwrite OF((gzFile file, const voidp buf, unsigned len));
+extern int EXPORT gzwrite OF((gzFile file, const voidp buf, unsigned len));
#endif
/*
Writes the given number of uncompressed bytes into the compressed file.
@@ -758,9 +769,10 @@ extern int EXPORT gzwrite OF((gzFile file, const voidp buf, unsigned len));
*/
#ifdef MOZILLA_CLIENT
-PR_EXTERN(int) gzflush (gzFile file, int flush);
+PR_EXTERN(int)
+gzflush(gzFile file, int flush);
#else
-extern int EXPORT gzflush OF((gzFile file, int flush));
+extern int EXPORT gzflush OF((gzFile file, int flush));
#endif
/*
Flushes all pending output into the compressed file. The parameter
@@ -772,9 +784,10 @@ extern int EXPORT gzflush OF((gzFile file, int flush));
*/
#ifdef MOZILLA_CLIENT
-PR_EXTERN(int) gzclose (gzFile file);
+PR_EXTERN(int)
+gzclose(gzFile file);
#else
-extern int EXPORT gzclose OF((gzFile file));
+extern int EXPORT gzclose OF((gzFile file));
#endif
/*
Flushes all pending output if necessary, closes the compressed file
@@ -783,9 +796,10 @@ extern int EXPORT gzclose OF((gzFile file));
*/
#ifdef MOZILLA_CLIENT
-PR_EXTERN(const char *) gzerror (gzFile file, int *errnum);
+PR_EXTERN(const char *)
+gzerror(gzFile file, int *errnum);
#else
-extern const char * EXPORT gzerror OF((gzFile file, int *errnum));
+extern const char *EXPORT gzerror OF((gzFile file, int *errnum));
#endif
/*
Returns the error message for the last error which occurred on the
@@ -795,7 +809,7 @@ extern const char * EXPORT gzerror OF((gzFile file, int *errnum));
to get the exact error code.
*/
- /* checksum functions */
+/* checksum functions */
/*
These functions are not related to compression but are exported
@@ -804,7 +818,8 @@ extern const char * EXPORT gzerror OF((gzFile file, int *errnum));
*/
#ifdef MOZILLA_CLIENT
-PR_EXTERN(uLong) adler32 (uLong adler, const Bytef *buf, uInt len);
+PR_EXTERN(uLong)
+adler32(uLong adler, const Bytef *buf, uInt len);
#else
extern uLong EXPORT adler32 OF((uLong adler, const Bytef *buf, uInt len));
#endif
@@ -825,9 +840,10 @@ extern uLong EXPORT adler32 OF((uLong adler, const Bytef *buf, uInt len));
*/
#ifdef MOZILLA_CLIENT
-PR_EXTERN(uLong) crc32 (uLong crc, const Bytef *buf, uInt len);
+PR_EXTERN(uLong)
+crc32(uLong crc, const Bytef *buf, uInt len);
#else
-extern uLong EXPORT crc32 OF((uLong crc, const Bytef *buf, uInt len));
+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
@@ -844,47 +860,51 @@ extern uLong EXPORT crc32 OF((uLong crc, const Bytef *buf, uInt len));
if (crc != original_crc) error();
*/
-
- /* various hacks, don't look :) */
+/* 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_EXTERN(int) deflateInit (z_streamp strm, int level, const char *version,
- int stream_size);
-PR_EXTERN(int) inflateInit_(z_streamp strm, const char *version,
- int stream_size);
-PR_EXTERN(int) deflateInit2_(z_streamp strm, int level, int method,
- int windowBits, int memLevel, int strategy,
- const char *version, int stream_size);
-PR_EXTERN(int) inflateInit2_(z_streamp strm, int windowBits,
- const char *version, int stream_size);
+PR_EXTERN(int)
+deflateInit(z_streamp strm, int level, const char *version,
+ int stream_size);
+PR_EXTERN(int)
+inflateInit_(z_streamp strm, const char *version,
+ int stream_size);
+PR_EXTERN(int)
+deflateInit2_(z_streamp strm, int level, int method,
+ int windowBits, int memLevel, int strategy,
+ const char *version, int stream_size);
+PR_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));
+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))
+ deflateInit_((strm), (level), ZLIB_VERSION, sizeof(z_stream))
#define inflateInit(strm) \
- inflateInit_((strm), ZLIB_VERSION, sizeof(z_stream))
+ 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))
+ deflateInit2_((strm), (level), (method), (windowBits), (memLevel), \
+ (strategy), ZLIB_VERSION, sizeof(z_stream))
#define inflateInit2(strm, windowBits) \
- inflateInit2_((strm), (windowBits), ZLIB_VERSION, sizeof(z_stream))
+ 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 */
+struct internal_state {
+ int dummy;
+}; /* hack for buggy compilers */
#endif
uLongf *get_crc_table OF((void)); /* can be used by asm versions of crc32() */
diff --git a/nss/lib/libpkix/include/exports.gyp b/nss/lib/libpkix/include/exports.gyp
new file mode 100644
index 0000000..92baaaa
--- /dev/null
+++ b/nss/lib/libpkix/include/exports.gyp
@@ -0,0 +1,38 @@
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+{
+ 'includes': [
+ '../../../coreconf/config.gypi'
+ ],
+ 'targets': [
+ {
+ 'target_name': 'lib_libpkix_include_exports',
+ 'type': 'none',
+ 'copies': [
+ {
+ 'files': [
+ 'pkix.h',
+ 'pkix_certsel.h',
+ 'pkix_certstore.h',
+ 'pkix_checker.h',
+ 'pkix_crlsel.h',
+ 'pkix_errorstrings.h',
+ 'pkix_params.h',
+ 'pkix_pl_pki.h',
+ 'pkix_pl_system.h',
+ 'pkix_results.h',
+ 'pkix_revchecker.h',
+ 'pkix_sample_modules.h',
+ 'pkix_util.h',
+ 'pkixt.h'
+ ],
+ 'destination': '<(nss_private_dist_dir)/<(module)'
+ }
+ ]
+ }
+ ],
+ 'variables': {
+ 'module': 'nss'
+ }
+}
diff --git a/nss/lib/libpkix/include/include.gyp b/nss/lib/libpkix/include/include.gyp
new file mode 100644
index 0000000..c435015
--- /dev/null
+++ b/nss/lib/libpkix/include/include.gyp
@@ -0,0 +1,12 @@
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+{
+ 'includes': [
+ '../../../coreconf/config.gypi'
+ ],
+ 'targets': [],
+ 'variables': {
+ 'module': 'nss'
+ }
+} \ No newline at end of file
diff --git a/nss/lib/libpkix/include/pkix_errorstrings.h b/nss/lib/libpkix/include/pkix_errorstrings.h
index d3fea94..e7e898f 100755
--- a/nss/lib/libpkix/include/pkix_errorstrings.h
+++ b/nss/lib/libpkix/include/pkix_errorstrings.h
@@ -1095,4 +1095,5 @@ PKIX_ERRORENTRY(X500NAMEMATCHFAILED,PKIX_PL_X500Name_Match failed,0),
PKIX_ERRORENTRY(X500NAMETOSTRINGFAILED,PKIX_PL_X500Name_ToString failed,0),
PKIX_ERRORENTRY(ZEROLENGTHBYTEARRAYFORCRLENCODING,Zero-length ByteArray for CRL encoding,0),
PKIX_ERRORENTRY(INVALIDOCSPHTTPMETHOD,Unsupported HTTP Method for OCSP retrieval,0),
-PKIX_ERRORENTRY(OCSPGETREQUESTTOOBIG,OCSP request too big for HTTP GET method,0)
+PKIX_ERRORENTRY(OCSPGETREQUESTTOOBIG,OCSP request too big for HTTP GET method,0),
+PKIX_ERRORENTRY(CERTISBLACKLISTEDATISSUANCETIME,Issuer Certificate is distrusted at the time the subordinate certifiate was issued,SEC_ERROR_UNTRUSTED_ISSUER)
diff --git a/nss/lib/libpkix/pkix/certsel/certsel.gyp b/nss/lib/libpkix/pkix/certsel/certsel.gyp
new file mode 100644
index 0000000..a7ff65c
--- /dev/null
+++ b/nss/lib/libpkix/pkix/certsel/certsel.gyp
@@ -0,0 +1,24 @@
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+{
+ 'includes': [
+ '../../../../coreconf/config.gypi'
+ ],
+ 'targets': [
+ {
+ 'target_name': 'pkixcertsel',
+ 'type': 'static_library',
+ 'sources': [
+ 'pkix_certselector.c',
+ 'pkix_comcertselparams.c'
+ ],
+ 'dependencies': [
+ '<(DEPTH)/exports.gyp:nss_exports'
+ ]
+ }
+ ],
+ 'variables': {
+ 'module': 'nss'
+ }
+} \ No newline at end of file
diff --git a/nss/lib/libpkix/pkix/certsel/exports.gyp b/nss/lib/libpkix/pkix/certsel/exports.gyp
new file mode 100644
index 0000000..9cbd847
--- /dev/null
+++ b/nss/lib/libpkix/pkix/certsel/exports.gyp
@@ -0,0 +1,26 @@
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+{
+ 'includes': [
+ '../../../../coreconf/config.gypi'
+ ],
+ 'targets': [
+ {
+ 'target_name': 'lib_libpkix_pkix_certsel_exports',
+ 'type': 'none',
+ 'copies': [
+ {
+ 'files': [
+ 'pkix_certselector.h',
+ 'pkix_comcertselparams.h'
+ ],
+ 'destination': '<(nss_private_dist_dir)/<(module)'
+ }
+ ]
+ }
+ ],
+ 'variables': {
+ 'module': 'nss'
+ }
+}
diff --git a/nss/lib/libpkix/pkix/checker/checker.gyp b/nss/lib/libpkix/pkix/checker/checker.gyp
new file mode 100644
index 0000000..ac260fc
--- /dev/null
+++ b/nss/lib/libpkix/pkix/checker/checker.gyp
@@ -0,0 +1,35 @@
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+{
+ 'includes': [
+ '../../../../coreconf/config.gypi'
+ ],
+ 'targets': [
+ {
+ 'target_name': 'pkixchecker',
+ 'type': 'static_library',
+ 'sources': [
+ '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_policychecker.c',
+ 'pkix_revocationchecker.c',
+ 'pkix_revocationmethod.c',
+ 'pkix_signaturechecker.c',
+ 'pkix_targetcertchecker.c'
+ ],
+ 'dependencies': [
+ '<(DEPTH)/exports.gyp:nss_exports'
+ ]
+ }
+ ],
+ 'variables': {
+ 'module': 'nss'
+ }
+} \ No newline at end of file
diff --git a/nss/lib/libpkix/pkix/checker/exports.gyp b/nss/lib/libpkix/pkix/checker/exports.gyp
new file mode 100644
index 0000000..4bd68b3
--- /dev/null
+++ b/nss/lib/libpkix/pkix/checker/exports.gyp
@@ -0,0 +1,37 @@
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+{
+ 'includes': [
+ '../../../../coreconf/config.gypi'
+ ],
+ 'targets': [
+ {
+ 'target_name': 'lib_libpkix_pkix_checker_exports',
+ 'type': 'none',
+ 'copies': [
+ {
+ 'files': [
+ '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_revocationchecker.h',
+ 'pkix_revocationmethod.h',
+ 'pkix_signaturechecker.h',
+ 'pkix_targetcertchecker.h'
+ ],
+ 'destination': '<(nss_private_dist_dir)/<(module)'
+ }
+ ]
+ }
+ ],
+ 'variables': {
+ 'module': 'nss'
+ }
+}
diff --git a/nss/lib/libpkix/pkix/crlsel/crlsel.gyp b/nss/lib/libpkix/pkix/crlsel/crlsel.gyp
new file mode 100644
index 0000000..894569e
--- /dev/null
+++ b/nss/lib/libpkix/pkix/crlsel/crlsel.gyp
@@ -0,0 +1,24 @@
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+{
+ 'includes': [
+ '../../../../coreconf/config.gypi'
+ ],
+ 'targets': [
+ {
+ 'target_name': 'pkixcrlsel',
+ 'type': 'static_library',
+ 'sources': [
+ 'pkix_comcrlselparams.c',
+ 'pkix_crlselector.c'
+ ],
+ 'dependencies': [
+ '<(DEPTH)/exports.gyp:nss_exports'
+ ]
+ }
+ ],
+ 'variables': {
+ 'module': 'nss'
+ }
+} \ No newline at end of file
diff --git a/nss/lib/libpkix/pkix/crlsel/exports.gyp b/nss/lib/libpkix/pkix/crlsel/exports.gyp
new file mode 100644
index 0000000..a7001ff
--- /dev/null
+++ b/nss/lib/libpkix/pkix/crlsel/exports.gyp
@@ -0,0 +1,26 @@
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+{
+ 'includes': [
+ '../../../../coreconf/config.gypi'
+ ],
+ 'targets': [
+ {
+ 'target_name': 'lib_libpkix_pkix_crlsel_exports',
+ 'type': 'none',
+ 'copies': [
+ {
+ 'files': [
+ 'pkix_comcrlselparams.h',
+ 'pkix_crlselector.h'
+ ],
+ 'destination': '<(nss_private_dist_dir)/<(module)'
+ }
+ ]
+ }
+ ],
+ 'variables': {
+ 'module': 'nss'
+ }
+}
diff --git a/nss/lib/libpkix/pkix/params/exports.gyp b/nss/lib/libpkix/pkix/params/exports.gyp
new file mode 100644
index 0000000..921f2ce
--- /dev/null
+++ b/nss/lib/libpkix/pkix/params/exports.gyp
@@ -0,0 +1,28 @@
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+{
+ 'includes': [
+ '../../../../coreconf/config.gypi'
+ ],
+ 'targets': [
+ {
+ 'target_name': 'lib_libpkix_pkix_params_exports',
+ 'type': 'none',
+ 'copies': [
+ {
+ 'files': [
+ 'pkix_procparams.h',
+ 'pkix_resourcelimits.h',
+ 'pkix_trustanchor.h',
+ 'pkix_valparams.h'
+ ],
+ 'destination': '<(nss_private_dist_dir)/<(module)'
+ }
+ ]
+ }
+ ],
+ 'variables': {
+ 'module': 'nss'
+ }
+}
diff --git a/nss/lib/libpkix/pkix/params/params.gyp b/nss/lib/libpkix/pkix/params/params.gyp
new file mode 100644
index 0000000..a1463c4
--- /dev/null
+++ b/nss/lib/libpkix/pkix/params/params.gyp
@@ -0,0 +1,26 @@
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+{
+ 'includes': [
+ '../../../../coreconf/config.gypi'
+ ],
+ 'targets': [
+ {
+ 'target_name': 'pkixparams',
+ 'type': 'static_library',
+ 'sources': [
+ 'pkix_procparams.c',
+ 'pkix_resourcelimits.c',
+ 'pkix_trustanchor.c',
+ 'pkix_valparams.c'
+ ],
+ 'dependencies': [
+ '<(DEPTH)/exports.gyp:nss_exports'
+ ]
+ }
+ ],
+ 'variables': {
+ 'module': 'nss'
+ }
+} \ No newline at end of file
diff --git a/nss/lib/libpkix/pkix/results/exports.gyp b/nss/lib/libpkix/pkix/results/exports.gyp
new file mode 100644
index 0000000..dfff689
--- /dev/null
+++ b/nss/lib/libpkix/pkix/results/exports.gyp
@@ -0,0 +1,28 @@
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+{
+ 'includes': [
+ '../../../../coreconf/config.gypi'
+ ],
+ 'targets': [
+ {
+ 'target_name': 'lib_libpkix_pkix_results_exports',
+ 'type': 'none',
+ 'copies': [
+ {
+ 'files': [
+ 'pkix_buildresult.h',
+ 'pkix_policynode.h',
+ 'pkix_valresult.h',
+ 'pkix_verifynode.h'
+ ],
+ 'destination': '<(nss_private_dist_dir)/<(module)'
+ }
+ ]
+ }
+ ],
+ 'variables': {
+ 'module': 'nss'
+ }
+}
diff --git a/nss/lib/libpkix/pkix/results/results.gyp b/nss/lib/libpkix/pkix/results/results.gyp
new file mode 100644
index 0000000..962fdb9
--- /dev/null
+++ b/nss/lib/libpkix/pkix/results/results.gyp
@@ -0,0 +1,26 @@
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+{
+ 'includes': [
+ '../../../../coreconf/config.gypi'
+ ],
+ 'targets': [
+ {
+ 'target_name': 'pkixresults',
+ 'type': 'static_library',
+ 'sources': [
+ 'pkix_buildresult.c',
+ 'pkix_policynode.c',
+ 'pkix_valresult.c',
+ 'pkix_verifynode.c'
+ ],
+ 'dependencies': [
+ '<(DEPTH)/exports.gyp:nss_exports'
+ ]
+ }
+ ],
+ 'variables': {
+ 'module': 'nss'
+ }
+} \ No newline at end of file
diff --git a/nss/lib/libpkix/pkix/store/exports.gyp b/nss/lib/libpkix/pkix/store/exports.gyp
new file mode 100644
index 0000000..52f13f5
--- /dev/null
+++ b/nss/lib/libpkix/pkix/store/exports.gyp
@@ -0,0 +1,25 @@
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+{
+ 'includes': [
+ '../../../../coreconf/config.gypi'
+ ],
+ 'targets': [
+ {
+ 'target_name': 'lib_libpkix_pkix_store_exports',
+ 'type': 'none',
+ 'copies': [
+ {
+ 'files': [
+ 'pkix_store.h'
+ ],
+ 'destination': '<(nss_private_dist_dir)/<(module)'
+ }
+ ]
+ }
+ ],
+ 'variables': {
+ 'module': 'nss'
+ }
+}
diff --git a/nss/lib/libpkix/pkix/store/store.gyp b/nss/lib/libpkix/pkix/store/store.gyp
new file mode 100644
index 0000000..43aa177
--- /dev/null
+++ b/nss/lib/libpkix/pkix/store/store.gyp
@@ -0,0 +1,23 @@
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+{
+ 'includes': [
+ '../../../../coreconf/config.gypi'
+ ],
+ 'targets': [
+ {
+ 'target_name': 'pkixstore',
+ 'type': 'static_library',
+ 'sources': [
+ 'pkix_store.c'
+ ],
+ 'dependencies': [
+ '<(DEPTH)/exports.gyp:nss_exports'
+ ]
+ }
+ ],
+ 'variables': {
+ 'module': 'nss'
+ }
+} \ No newline at end of file
diff --git a/nss/lib/libpkix/pkix/top/exports.gyp b/nss/lib/libpkix/pkix/top/exports.gyp
new file mode 100644
index 0000000..d41f2b5
--- /dev/null
+++ b/nss/lib/libpkix/pkix/top/exports.gyp
@@ -0,0 +1,27 @@
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+{
+ 'includes': [
+ '../../../../coreconf/config.gypi'
+ ],
+ 'targets': [
+ {
+ 'target_name': 'lib_libpkix_pkix_top_exports',
+ 'type': 'none',
+ 'copies': [
+ {
+ 'files': [
+ 'pkix_build.h',
+ 'pkix_lifecycle.h',
+ 'pkix_validate.h'
+ ],
+ 'destination': '<(nss_private_dist_dir)/<(module)'
+ }
+ ]
+ }
+ ],
+ 'variables': {
+ 'module': 'nss'
+ }
+}
diff --git a/nss/lib/libpkix/pkix/top/pkix_build.c b/nss/lib/libpkix/pkix/top/pkix_build.c
index 9451578..0c87ba3 100755
--- a/nss/lib/libpkix/pkix/top/pkix_build.c
+++ b/nss/lib/libpkix/pkix/top/pkix_build.c
@@ -1943,6 +1943,10 @@ pkix_PrepareForwardBuilderStateForAIA(
state->status = BUILD_TRYAIA;
}
+extern SECStatus
+isIssuerCertAllowedAtCertIssuanceTime(CERTCertificate *issuerCert,
+ CERTCertificate *referenceCert);
+
/*
* FUNCTION: pkix_BuildForwardDepthFirstSearch
* DESCRIPTION:
@@ -2057,6 +2061,7 @@ pkix_BuildForwardDepthFirstSearch(
PKIX_ComCertSelParams *certSelParams = NULL;
PKIX_TrustAnchor *trustAnchor = NULL;
PKIX_PL_Cert *trustedCert = NULL;
+ PKIX_PL_Cert *targetCert = NULL;
PKIX_VerifyNode *verifyNode = NULL;
PKIX_Error *verifyError = NULL;
PKIX_Error *finalError = NULL;
@@ -2072,6 +2077,7 @@ pkix_BuildForwardDepthFirstSearch(
validityDate = state->validityDate;
canBeCached = state->canBeCached;
PKIX_DECREF(*pValResult);
+ targetCert = state->buildConstants.targetCert;
/*
* We return if successful; if we fall off the end
@@ -2354,6 +2360,12 @@ pkix_BuildForwardDepthFirstSearch(
plContext),
PKIX_LISTGETITEMFAILED);
+ if (isIssuerCertAllowedAtCertIssuanceTime(
+ state->candidateCert->nssCert, targetCert->nssCert)
+ != SECSuccess) {
+ PKIX_ERROR(PKIX_CERTISBLACKLISTEDATISSUANCETIME);
+ }
+
if ((state->verifyNode) != NULL) {
PKIX_CHECK_FATAL(pkix_VerifyNode_Create
(state->candidateCert,
diff --git a/nss/lib/libpkix/pkix/top/top.gyp b/nss/lib/libpkix/pkix/top/top.gyp
new file mode 100644
index 0000000..fb1b08e
--- /dev/null
+++ b/nss/lib/libpkix/pkix/top/top.gyp
@@ -0,0 +1,25 @@
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+{
+ 'includes': [
+ '../../../../coreconf/config.gypi'
+ ],
+ 'targets': [
+ {
+ 'target_name': 'pkixtop',
+ 'type': 'static_library',
+ 'sources': [
+ 'pkix_build.c',
+ 'pkix_lifecycle.c',
+ 'pkix_validate.c'
+ ],
+ 'dependencies': [
+ '<(DEPTH)/exports.gyp:nss_exports'
+ ]
+ }
+ ],
+ 'variables': {
+ 'module': 'nss'
+ }
+} \ No newline at end of file
diff --git a/nss/lib/libpkix/pkix/util/exports.gyp b/nss/lib/libpkix/pkix/util/exports.gyp
new file mode 100644
index 0000000..8318c6c
--- /dev/null
+++ b/nss/lib/libpkix/pkix/util/exports.gyp
@@ -0,0 +1,28 @@
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+{
+ 'includes': [
+ '../../../../coreconf/config.gypi'
+ ],
+ 'targets': [
+ {
+ 'target_name': 'lib_libpkix_pkix_util_exports',
+ 'type': 'none',
+ 'copies': [
+ {
+ 'files': [
+ 'pkix_error.h',
+ 'pkix_list.h',
+ 'pkix_logger.h',
+ 'pkix_tools.h'
+ ],
+ 'destination': '<(nss_private_dist_dir)/<(module)'
+ }
+ ]
+ }
+ ],
+ 'variables': {
+ 'module': 'nss'
+ }
+}
diff --git a/nss/lib/libpkix/pkix/util/pkix_tools.h b/nss/lib/libpkix/pkix/util/pkix_tools.h
index 1a4689d..5a8ef27 100755
--- a/nss/lib/libpkix/pkix/util/pkix_tools.h
+++ b/nss/lib/libpkix/pkix/util/pkix_tools.h
@@ -1458,8 +1458,8 @@ extern const char *PKIX_ERRORCLASSNAMES[PKIX_NUMERRORCLASSES];
extern PRLogModuleInfo *pkixLog;
-#define PKIX_MAGIC_HEADER LL_INIT(0xFEEDC0FF, 0xEEFACADE)
-#define PKIX_MAGIC_HEADER_DESTROYED LL_INIT(0xBAADF00D, 0xDEADBEEF)
+#define PKIX_MAGIC_HEADER PR_UINT64(0xFEEDC0FFEEFACADE)
+#define PKIX_MAGIC_HEADER_DESTROYED PR_UINT64(0xBAADF00DDEADBEEF)
/* see source file for function documentation */
diff --git a/nss/lib/libpkix/pkix/util/util.gyp b/nss/lib/libpkix/pkix/util/util.gyp
new file mode 100644
index 0000000..078852f
--- /dev/null
+++ b/nss/lib/libpkix/pkix/util/util.gyp
@@ -0,0 +1,27 @@
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+{
+ 'includes': [
+ '../../../../coreconf/config.gypi'
+ ],
+ 'targets': [
+ {
+ 'target_name': 'pkixutil',
+ 'type': 'static_library',
+ 'sources': [
+ 'pkix_error.c',
+ 'pkix_errpaths.c',
+ 'pkix_list.c',
+ 'pkix_logger.c',
+ 'pkix_tools.c'
+ ],
+ 'dependencies': [
+ '<(DEPTH)/exports.gyp:nss_exports'
+ ]
+ }
+ ],
+ 'variables': {
+ 'module': 'nss'
+ }
+} \ No newline at end of file
diff --git a/nss/lib/libpkix/pkix_pl_nss/module/exports.gyp b/nss/lib/libpkix/pkix_pl_nss/module/exports.gyp
new file mode 100644
index 0000000..064a17c
--- /dev/null
+++ b/nss/lib/libpkix/pkix_pl_nss/module/exports.gyp
@@ -0,0 +1,36 @@
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+{
+ 'includes': [
+ '../../../../coreconf/config.gypi'
+ ],
+ 'targets': [
+ {
+ 'target_name': 'lib_libpkix_pkix_pl_nss_module_exports',
+ 'type': 'none',
+ 'copies': [
+ {
+ 'files': [
+ 'pkix_pl_aiamgr.h',
+ 'pkix_pl_colcertstore.h',
+ 'pkix_pl_httpcertstore.h',
+ 'pkix_pl_httpdefaultclient.h',
+ 'pkix_pl_ldapcertstore.h',
+ 'pkix_pl_ldapdefaultclient.h',
+ 'pkix_pl_ldaprequest.h',
+ 'pkix_pl_ldapresponse.h',
+ 'pkix_pl_ldapt.h',
+ 'pkix_pl_nsscontext.h',
+ 'pkix_pl_pk11certstore.h',
+ 'pkix_pl_socket.h'
+ ],
+ 'destination': '<(nss_private_dist_dir)/<(module)'
+ }
+ ]
+ }
+ ],
+ 'variables': {
+ 'module': 'nss'
+ }
+}
diff --git a/nss/lib/libpkix/pkix_pl_nss/module/module.gyp b/nss/lib/libpkix/pkix_pl_nss/module/module.gyp
new file mode 100644
index 0000000..8d7459d
--- /dev/null
+++ b/nss/lib/libpkix/pkix_pl_nss/module/module.gyp
@@ -0,0 +1,41 @@
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+{
+ 'includes': [
+ '../../../../coreconf/config.gypi'
+ ],
+ 'targets': [
+ {
+ 'target_name': 'pkixmodule',
+ 'type': 'static_library',
+ 'sources': [
+ 'pkix_pl_aiamgr.c',
+ 'pkix_pl_colcertstore.c',
+ 'pkix_pl_httpcertstore.c',
+ 'pkix_pl_httpdefaultclient.c',
+ 'pkix_pl_ldapcertstore.c',
+ 'pkix_pl_ldapdefaultclient.c',
+ 'pkix_pl_ldaprequest.c',
+ 'pkix_pl_ldapresponse.c',
+ 'pkix_pl_ldaptemplates.c',
+ 'pkix_pl_nsscontext.c',
+ 'pkix_pl_pk11certstore.c',
+ 'pkix_pl_socket.c'
+ ],
+ 'dependencies': [
+ '<(DEPTH)/exports.gyp:nss_exports'
+ ]
+ }
+ ],
+ 'target_defaults': {
+ 'defines': [
+ 'SHLIB_SUFFIX=\"<(dll_suffix)\"',
+ 'SHLIB_PREFIX=\"<(dll_prefix)\"',
+ 'SHLIB_VERSION=\"\"'
+ ]
+ },
+ 'variables': {
+ 'module': 'nss'
+ }
+} \ No newline at end of file
diff --git a/nss/lib/libpkix/pkix_pl_nss/module/pkix_pl_aiamgr.c b/nss/lib/libpkix/pkix_pl_nss/module/pkix_pl_aiamgr.c
index 148c2c1..d9f5662 100644
--- a/nss/lib/libpkix/pkix_pl_nss/module/pkix_pl_aiamgr.c
+++ b/nss/lib/libpkix/pkix_pl_nss/module/pkix_pl_aiamgr.c
@@ -366,7 +366,7 @@ pkix_pl_AIAMgr_GetHTTPCerts(
cleanup:
/* Session and request cleanup in case of error. Passing through without cleanup
* if interrupted by blocked IO. */
- if (PKIX_ERROR_RECEIVED && aiaMgr) {
+ if (PKIX_ERROR_RECEIVED) {
if (aiaMgr->client.hdata.requestSession != NULL) {
(*hcv1->freeFcn)(aiaMgr->client.hdata.requestSession);
aiaMgr->client.hdata.requestSession = NULL;
diff --git a/nss/lib/libpkix/pkix_pl_nss/module/pkix_pl_httpcertstore.c b/nss/lib/libpkix/pkix_pl_nss/module/pkix_pl_httpcertstore.c
index 30aefb8..471f920 100755
--- a/nss/lib/libpkix/pkix_pl_nss/module/pkix_pl_httpcertstore.c
+++ b/nss/lib/libpkix/pkix_pl_nss/module/pkix_pl_httpcertstore.c
@@ -39,10 +39,10 @@ const SEC_ASN1Template SECOID_AlgorithmIDTemplate[] = {
{ SEC_ASN1_SEQUENCE,
0, NULL, sizeof(SECAlgorithmID) },
{ SEC_ASN1_OBJECT_ID,
- offsetof(SECAlgorithmID,algorithm), },
+ offsetof(SECAlgorithmID,algorithm) },
{ SEC_ASN1_OPTIONAL | SEC_ASN1_ANY,
- offsetof(SECAlgorithmID,parameters), },
- { 0, }
+ offsetof(SECAlgorithmID,parameters) },
+ { 0 }
}; */
/* --Private-HttpCertStoreContext-Object Functions----------------------- */
diff --git a/nss/lib/libpkix/pkix_pl_nss/module/pkix_pl_socket.c b/nss/lib/libpkix/pkix_pl_nss/module/pkix_pl_socket.c
index 6bd0a3a..e869837 100644
--- a/nss/lib/libpkix/pkix_pl_nss/module/pkix_pl_socket.c
+++ b/nss/lib/libpkix/pkix_pl_nss/module/pkix_pl_socket.c
@@ -765,7 +765,7 @@ pkix_pl_Socket_RegisterSelf(void *plContext)
#ifdef PKIX_SOCKETTRACE
{
char *val = NULL;
- val = PR_GetEnv("SOCKETTRACE");
+ val = PR_GetEnvSecure("SOCKETTRACE");
/* Is SOCKETTRACE set in the environment? */
if ((val != NULL) && (*val != '\0')) {
socketTraceFlag =
diff --git a/nss/lib/libpkix/pkix_pl_nss/pki/exports.gyp b/nss/lib/libpkix/pkix_pl_nss/pki/exports.gyp
new file mode 100644
index 0000000..616f94f
--- /dev/null
+++ b/nss/lib/libpkix/pkix_pl_nss/pki/exports.gyp
@@ -0,0 +1,41 @@
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+{
+ 'includes': [
+ '../../../../coreconf/config.gypi'
+ ],
+ 'targets': [
+ {
+ 'target_name': 'lib_libpkix_pkix_pl_nss_pki_exports',
+ 'type': 'none',
+ 'copies': [
+ {
+ 'files': [
+ '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_ocspcertid.h',
+ 'pkix_pl_ocsprequest.h',
+ 'pkix_pl_ocspresponse.h',
+ 'pkix_pl_publickey.h',
+ 'pkix_pl_x500name.h'
+ ],
+ 'destination': '<(nss_private_dist_dir)/<(module)'
+ }
+ ]
+ }
+ ],
+ 'variables': {
+ 'module': 'nss'
+ }
+}
diff --git a/nss/lib/libpkix/pkix_pl_nss/pki/pki.gyp b/nss/lib/libpkix/pkix_pl_nss/pki/pki.gyp
new file mode 100644
index 0000000..af7730c
--- /dev/null
+++ b/nss/lib/libpkix/pkix_pl_nss/pki/pki.gyp
@@ -0,0 +1,39 @@
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+{
+ 'includes': [
+ '../../../../coreconf/config.gypi'
+ ],
+ 'targets': [
+ {
+ 'target_name': 'pkixpki',
+ 'type': 'static_library',
+ 'sources': [
+ '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_ocspcertid.c',
+ 'pkix_pl_ocsprequest.c',
+ 'pkix_pl_ocspresponse.c',
+ 'pkix_pl_publickey.c',
+ 'pkix_pl_x500name.c'
+ ],
+ 'dependencies': [
+ '<(DEPTH)/exports.gyp:nss_exports'
+ ]
+ }
+ ],
+ 'variables': {
+ 'module': 'nss'
+ }
+} \ No newline at end of file
diff --git a/nss/lib/libpkix/pkix_pl_nss/system/exports.gyp b/nss/lib/libpkix/pkix_pl_nss/system/exports.gyp
new file mode 100644
index 0000000..a2f7594
--- /dev/null
+++ b/nss/lib/libpkix/pkix_pl_nss/system/exports.gyp
@@ -0,0 +1,37 @@
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+{
+ 'includes': [
+ '../../../../coreconf/config.gypi'
+ ],
+ 'targets': [
+ {
+ 'target_name': 'lib_libpkix_pkix_pl_nss_system_exports',
+ 'type': 'none',
+ 'copies': [
+ {
+ 'files': [
+ 'pkix_pl_bigint.h',
+ 'pkix_pl_bytearray.h',
+ 'pkix_pl_common.h',
+ 'pkix_pl_hashtable.h',
+ 'pkix_pl_lifecycle.h',
+ 'pkix_pl_mem.h',
+ 'pkix_pl_monitorlock.h',
+ 'pkix_pl_mutex.h',
+ 'pkix_pl_object.h',
+ 'pkix_pl_oid.h',
+ 'pkix_pl_primhash.h',
+ 'pkix_pl_rwlock.h',
+ 'pkix_pl_string.h'
+ ],
+ 'destination': '<(nss_private_dist_dir)/<(module)'
+ }
+ ]
+ }
+ ],
+ 'variables': {
+ 'module': 'nss'
+ }
+}
diff --git a/nss/lib/libpkix/pkix_pl_nss/system/pkix_pl_lifecycle.c b/nss/lib/libpkix/pkix_pl_nss/system/pkix_pl_lifecycle.c
index 338eb1c..70ed25d 100755
--- a/nss/lib/libpkix/pkix_pl_nss/system/pkix_pl_lifecycle.c
+++ b/nss/lib/libpkix/pkix_pl_nss/system/pkix_pl_lifecycle.c
@@ -135,7 +135,7 @@ PKIX_PL_Initialize(
return PKIX_ALLOC_ERROR();
}
- if (PR_GetEnv("NSS_STRICT_SHUTDOWN")) {
+ if (PR_GetEnvSecure("NSS_STRICT_SHUTDOWN")) {
pkixLog = PR_NewLogModule("pkix");
}
/*
@@ -262,7 +262,7 @@ PKIX_PL_Shutdown(void *plContext)
#ifdef DEBUG
numLeakedObjects = pkix_pl_lifecycle_ObjectLeakCheck(NULL);
- if (PR_GetEnv("NSS_STRICT_SHUTDOWN")) {
+ if (PR_GetEnvSecure("NSS_STRICT_SHUTDOWN")) {
PORT_Assert(numLeakedObjects == 0);
}
#else
diff --git a/nss/lib/libpkix/pkix_pl_nss/system/system.gyp b/nss/lib/libpkix/pkix_pl_nss/system/system.gyp
new file mode 100644
index 0000000..32daec9
--- /dev/null
+++ b/nss/lib/libpkix/pkix_pl_nss/system/system.gyp
@@ -0,0 +1,36 @@
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+{
+ 'includes': [
+ '../../../../coreconf/config.gypi'
+ ],
+ 'targets': [
+ {
+ 'target_name': 'pkixsystem',
+ 'type': 'static_library',
+ 'sources': [
+ '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'
+ ],
+ 'dependencies': [
+ '<(DEPTH)/exports.gyp:nss_exports'
+ ]
+ }
+ ],
+ 'variables': {
+ 'module': 'nss'
+ }
+} \ No newline at end of file
diff --git a/nss/lib/manifest.mn b/nss/lib/manifest.mn
index dd4b542..80d7d9c 100644
--- a/nss/lib/manifest.mn
+++ b/nss/lib/manifest.mn
@@ -5,6 +5,38 @@
CORE_DEPTH = ..
DEPTH = ..
+# Building softoken (and freebl) only requires that the paths
+# to the locations where the util headers and libraries were
+# previously installed by a prior util-only build - likely in
+# in a system location that varies with the distribution. This
+# cannot be addressed here and requires that downstream package
+# mantainers add suitable modifications. Building full nss will
+# not have that problem as everything is available.
+
+SOFTOKEN_SRCDIRS=
+NSS_SRCDIRS=
+
+ifndef NSS_BUILD_UTIL_ONLY
+SOFTOKEN_SRCDIRS = \
+ $(FREEBL_SRCDIR) \
+ $(SQLITE_SRCDIR) \
+ $(DBM_SRCDIR) \
+ $(SOFTOKEN_SRCDIR) \
+ $(NULL)
+ifndef NSS_BUILD_SOFTOKEN_ONLY
+# the rest of nss
+NSS_SRCDIRS = \
+ base dev pki \
+ $(LIBPKIX_SRCDIR) \
+ certdb certhigh pk11wrap cryptohi nss \
+ $(ZLIB_SRCDIR) ssl \
+ pkcs7 pkcs12 smime \
+ crmf jar \
+ ckfw $(SYSINIT_SRCDIR) \
+ $(NULL)
+endif
+endif
+
#
# organized by DLL
#
@@ -18,17 +50,8 @@ DEPTH = ..
# crmf jar (not dll's)
DIRS = \
$(UTIL_SRCDIR) \
- $(FREEBL_SRCDIR) \
- $(SQLITE_SRCDIR) \
- $(DBM_SRCDIR) \
- $(SOFTOKEN_SRCDIR) \
- base dev pki \
- libpkix \
- certdb certhigh pk11wrap cryptohi nss \
- $(ZLIB_SRCDIR) ssl \
- pkcs7 pkcs12 smime \
- crmf jar \
- ckfw $(SYSINIT_SRCDIR) \
+ $(SOFTOKEN_SRCDIRS) \
+ $(NSS_SRCDIRS) \
$(NULL)
# fortcrypt is no longer built
diff --git a/nss/lib/nss/config.mk b/nss/lib/nss/config.mk
index 170e999..a17f3ef 100644
--- a/nss/lib/nss/config.mk
+++ b/nss/lib/nss/config.mk
@@ -79,6 +79,10 @@ SHARED_LIBRARY_DIRS = \
../pki \
../dev \
../base \
+ $(NULL)
+
+ifndef NSS_DISABLE_LIBPKIX
+SHARED_LIBRARY_DIRS += \
../libpkix/pkix/certsel \
../libpkix/pkix/checker \
../libpkix/pkix/params \
@@ -91,6 +95,7 @@ SHARED_LIBRARY_DIRS = \
../libpkix/pkix_pl_nss/system \
../libpkix/pkix_pl_nss/module \
$(NULL)
+endif
ifeq (,$(filter-out WINNT WIN95,$(OS_TARGET)))
ifndef NS_USE_GCC
@@ -100,3 +105,10 @@ DEFINES += -DWIN32_NSS3_DLL_COMPAT
DLLFLAGS += -EXPORT:mktemp=nss_mktemp,PRIVATE
endif
endif
+
+ifdef POLICY_FILE
+ifndef POLICY_PATH
+$(error You must define POLICY_PATH if you set POLICY_FILE)
+endif
+DEFINES += -DPOLICY_FILE=\"$(POLICY_FILE)\" -DPOLICY_PATH=\"$(POLICY_PATH)\"
+endif
diff --git a/nss/lib/nss/exports.gyp b/nss/lib/nss/exports.gyp
new file mode 100644
index 0000000..6f874f6
--- /dev/null
+++ b/nss/lib/nss/exports.gyp
@@ -0,0 +1,32 @@
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+{
+ 'includes': [
+ '../../coreconf/config.gypi'
+ ],
+ 'targets': [
+ {
+ 'target_name': 'lib_nss_exports',
+ 'type': 'none',
+ 'copies': [
+ {
+ 'files': [
+ 'nss.h'
+ ],
+ 'destination': '<(nss_public_dist_dir)/<(module)'
+ },
+ {
+ 'files': [
+ 'nssoptions.h',
+ 'nssrenam.h'
+ ],
+ 'destination': '<(nss_private_dist_dir)/<(module)'
+ }
+ ]
+ }
+ ],
+ 'variables': {
+ 'module': 'nss'
+ }
+}
diff --git a/nss/lib/nss/nss.def b/nss/lib/nss/nss.def
index cd2920c..1760b96 100644
--- a/nss/lib/nss/nss.def
+++ b/nss/lib/nss/nss.def
@@ -1090,3 +1090,10 @@ SECMOD_CreateModuleEx;
;+ local:
;+ *;
;+};
+;+NSS_3.22 { # NSS 3.22 release
+;+ global:
+PK11_SignWithMechanism;
+PK11_VerifyWithMechanism;
+;+ local:
+;+ *;
+;+};
diff --git a/nss/lib/nss/nss.gyp b/nss/lib/nss/nss.gyp
new file mode 100644
index 0000000..56984d9
--- /dev/null
+++ b/nss/lib/nss/nss.gyp
@@ -0,0 +1,83 @@
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+{
+ 'includes': [
+ '../../coreconf/config.gypi'
+ ],
+ 'targets': [
+ {
+ 'target_name': 'nss_static',
+ 'type': 'static_library',
+ 'sources': [
+ 'nssinit.c',
+ 'nssoptions.c',
+ 'nssver.c',
+ 'utilwrap.c'
+ ],
+ 'dependencies': [
+ '<(DEPTH)/exports.gyp:nss_exports',
+ ]
+ },
+ {
+ # This is here so Firefox can link this without having to
+ # repeat the list of dependencies.
+ 'target_name': 'nss3_deps',
+ 'type': 'none',
+ 'dependencies': [
+ 'nss_static',
+ '<(DEPTH)/lib/certhigh/certhigh.gyp:certhi',
+ '<(DEPTH)/lib/cryptohi/cryptohi.gyp:cryptohi',
+ '<(DEPTH)/lib/pk11wrap/pk11wrap.gyp:pk11wrap',
+ '<(DEPTH)/lib/certdb/certdb.gyp:certdb',
+ '<(DEPTH)/lib/pki/pki.gyp:nsspki',
+ '<(DEPTH)/lib/dev/dev.gyp:nssdev',
+ '<(DEPTH)/lib/base/base.gyp:nssb',
+ ],
+ 'conditions': [
+ [ 'disable_libpkix==0', {
+ 'dependencies': [
+ '<(DEPTH)/lib/libpkix/pkix/certsel/certsel.gyp:pkixcertsel',
+ '<(DEPTH)/lib/libpkix/pkix/checker/checker.gyp:pkixchecker',
+ '<(DEPTH)/lib/libpkix/pkix/params/params.gyp:pkixparams',
+ '<(DEPTH)/lib/libpkix/pkix/results/results.gyp:pkixresults',
+ '<(DEPTH)/lib/libpkix/pkix/top/top.gyp:pkixtop',
+ '<(DEPTH)/lib/libpkix/pkix/util/util.gyp:pkixutil',
+ '<(DEPTH)/lib/libpkix/pkix/crlsel/crlsel.gyp:pkixcrlsel',
+ '<(DEPTH)/lib/libpkix/pkix/store/store.gyp:pkixstore',
+ '<(DEPTH)/lib/libpkix/pkix_pl_nss/pki/pki.gyp:pkixpki',
+ '<(DEPTH)/lib/libpkix/pkix_pl_nss/system/system.gyp:pkixsystem',
+ '<(DEPTH)/lib/libpkix/pkix_pl_nss/module/module.gyp:pkixmodule'
+ ],
+ }],
+ ],
+ },
+ {
+ 'target_name': 'nss3',
+ 'type': 'shared_library',
+ 'dependencies': [
+ 'nss3_deps',
+ '<(DEPTH)/lib/util/util.gyp:nssutil3',
+ ],
+ 'variables': {
+ 'mapfile': 'nss.def'
+ }
+ }
+ ],
+ 'conditions': [
+ [ 'moz_fold_libs==1', {
+ 'targets': [
+ {
+ 'target_name': 'nss3_static',
+ 'type': 'static_library',
+ 'dependencies': [
+ 'nss3_deps',
+ ],
+ }
+ ],
+ }],
+ ],
+ 'variables': {
+ 'module': 'nss'
+ }
+}
diff --git a/nss/lib/nss/nss.h b/nss/lib/nss/nss.h
index 2433cfc..e1c67ec 100644
--- a/nss/lib/nss/nss.h
+++ b/nss/lib/nss/nss.h
@@ -8,22 +8,11 @@
#ifndef __nss_h_
#define __nss_h_
-/* The private macro _NSS_ECC_STRING is for NSS internal use only. */
-#ifndef NSS_DISABLE_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
+#define _NSS_CUSTOMIZED
#endif
/*
@@ -33,12 +22,12 @@
* The format of the version string should be
* "<major version>.<minor version>[.<patch level>[.<build number>]][ <ECC>][ <Beta>]"
*/
-#define NSS_VERSION "3.21" _NSS_ECC_STRING _NSS_CUSTOMIZED
-#define NSS_VMAJOR 3
-#define NSS_VMINOR 21
-#define NSS_VPATCH 0
-#define NSS_VBUILD 0
-#define NSS_BETA PR_FALSE
+#define NSS_VERSION "3.28.1" _NSS_CUSTOMIZED
+#define NSS_VMAJOR 3
+#define NSS_VMINOR 28
+#define NSS_VPATCH 1
+#define NSS_VBUILD 0
+#define NSS_BETA PR_FALSE
#ifndef RC_INVOKED
@@ -47,76 +36,75 @@
typedef struct NSSInitParametersStr NSSInitParameters;
/*
- * parameters used to initialize softoken. Mostly strings used to
+ * 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
+ * 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
+ * default is used. These are equivalent to the parameters for
* PK11_ConfigurePKCS11().
*
- * field names match their equivalent parameter names for softoken strings
+ * 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
+ *
+ * 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
+ * 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
+ * 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
+ * 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
+ * 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
+ * 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
+ * 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
+ * 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).
+ * 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;
+ 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
@@ -169,20 +157,20 @@ extern SECStatus NSS_InitReadWrite(const char *configdir);
*
* 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-"
+ * "https-server1-"
* keyPrefix - prefix added to the beginning of the key database example: "
- * "https-server1-"
+ * "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_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.
+ * 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
@@ -215,37 +203,36 @@ extern SECStatus NSS_InitReadWrite(const char *configdir);
* 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.
+ * 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 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 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 NSSInitContext *NSS_InitContext(const char *configdir,
+ const char *certPrefix, const char *keyPrefix,
+ const char *secmodName, NSSInitParameters *initParams, PRUint32 flags);
extern SECStatus NSS_ShutdownContext(NSSInitContext *);
@@ -259,11 +246,11 @@ extern SECStatus NSS_ShutdownContext(NSSInitContext *);
* 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);
+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.
*/
@@ -273,10 +260,10 @@ 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
+ * 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.
+ * 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.
@@ -296,9 +283,13 @@ SECStatus NSS_UnregisterShutdown(NSS_ShutdownFunc sFunc, void *appData);
/* Available options for NSS_OptionSet() and NSS_OptionGet().
*/
-#define NSS_RSA_MIN_KEY_SIZE (1<<0)
-#define NSS_DH_MIN_KEY_SIZE (1<<1)
-#define NSS_DSA_MIN_KEY_SIZE (1<<2)
+#define NSS_RSA_MIN_KEY_SIZE 0x001
+#define NSS_DH_MIN_KEY_SIZE 0x002
+#define NSS_DSA_MIN_KEY_SIZE 0x004
+#define NSS_TLS_VERSION_MIN_POLICY 0x008
+#define NSS_TLS_VERSION_MAX_POLICY 0x009
+#define NSS_DTLS_VERSION_MIN_POLICY 0x00a
+#define NSS_DTLS_VERSION_MAX_POLICY 0x00b
/*
* Set and get global options for the NSS library.
@@ -306,8 +297,7 @@ SECStatus NSS_UnregisterShutdown(NSS_ShutdownFunc sFunc, void *appData);
SECStatus NSS_OptionSet(PRInt32 which, PRInt32 value);
SECStatus NSS_OptionGet(PRInt32 which, PRInt32 *value);
-
-/*
+/*
* Close the Cert, Key databases.
*/
extern SECStatus NSS_Shutdown(void);
@@ -315,10 +305,10 @@ 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);
+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.
diff --git a/nss/lib/nss/nssinit.c b/nss/lib/nss/nssinit.c
index b22f915..5d62d47 100644
--- a/nss/lib/nss/nssinit.c
+++ b/nss/lib/nss/nssinit.c
@@ -20,9 +20,12 @@
#include "secerr.h"
#include "nssbase.h"
#include "nssutil.h"
+
+#ifndef NSS_DISABLE_LIBPKIX
#include "pkixt.h"
#include "pkix.h"
#include "pkix_tools.h"
+#endif /* NSS_DISABLE_LIBPKIX */
#include "pki3hack.h"
#include "certi.h"
@@ -49,141 +52,153 @@ nss_mktemp(char *path)
}
#endif
-#define NSS_MAX_FLAG_SIZE sizeof("readOnly")+sizeof("noCertDB")+ \
- sizeof("noModDB")+sizeof("forceOpen")+sizeof("passwordRequired")+ \
- sizeof ("optimizeSpace")
+#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)
+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);
+ PORT_Memset(flags, 0, NSS_MAX_FLAG_SIZE);
if (readOnly) {
- PORT_Strcat(flags,"readOnly");
+ PORT_Strcat(flags, "readOnly");
first = PR_FALSE;
}
if (noCertDB) {
- if (!first) PORT_Strcat(flags,",");
- PORT_Strcat(flags,"noCertDB");
+ if (!first)
+ PORT_Strcat(flags, ",");
+ PORT_Strcat(flags, "noCertDB");
first = PR_FALSE;
}
if (noModDB) {
- if (!first) PORT_Strcat(flags,",");
- PORT_Strcat(flags,"noModDB");
+ if (!first)
+ PORT_Strcat(flags, ",");
+ PORT_Strcat(flags, "noModDB");
first = PR_FALSE;
}
if (forceOpen) {
- if (!first) PORT_Strcat(flags,",");
- PORT_Strcat(flags,"forceOpen");
+ if (!first)
+ PORT_Strcat(flags, ",");
+ PORT_Strcat(flags, "forceOpen");
first = PR_FALSE;
}
if (passwordRequired) {
- if (!first) PORT_Strcat(flags,",");
- PORT_Strcat(flags,"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;
+ if (!first)
+ PORT_Strcat(flags, ",");
+ PORT_Strcat(flags, "optimizeSpace");
}
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)
+ 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 (strings == NULL)
+ return NULL;
if (man) {
- newStrings = PR_smprintf("%s manufacturerID='%s'",strings,man);
- PR_smprintf_free(strings);
- strings = newStrings;
+ newStrings = PR_smprintf("%s manufacturerID='%s'", strings, man);
+ PR_smprintf_free(strings);
+ strings = newStrings;
}
- if (strings == NULL) return NULL;
+ if (strings == NULL)
+ return NULL;
if (libdesc) {
- newStrings = PR_smprintf("%s libraryDescription='%s'",strings,libdesc);
- PR_smprintf_free(strings);
- strings = newStrings;
+ newStrings = PR_smprintf("%s libraryDescription='%s'", strings, libdesc);
+ PR_smprintf_free(strings);
+ strings = newStrings;
}
- if (strings == NULL) return NULL;
+ if (strings == NULL)
+ return NULL;
if (tokdesc) {
- newStrings = PR_smprintf("%s cryptoTokenDescription='%s'",strings,
- tokdesc);
- PR_smprintf_free(strings);
- strings = newStrings;
+ newStrings = PR_smprintf("%s cryptoTokenDescription='%s'", strings,
+ tokdesc);
+ PR_smprintf_free(strings);
+ strings = newStrings;
}
- if (strings == NULL) return NULL;
+ if (strings == NULL)
+ return NULL;
if (ptokdesc) {
- newStrings = PR_smprintf("%s dbTokenDescription='%s'",strings,ptokdesc);
- PR_smprintf_free(strings);
- strings = newStrings;
+ newStrings = PR_smprintf("%s dbTokenDescription='%s'", strings, ptokdesc);
+ PR_smprintf_free(strings);
+ strings = newStrings;
}
- if (strings == NULL) return NULL;
+ if (strings == NULL)
+ return NULL;
if (slotdesc) {
- newStrings = PR_smprintf("%s cryptoSlotDescription='%s'",strings,
- slotdesc);
- PR_smprintf_free(strings);
- strings = newStrings;
+ newStrings = PR_smprintf("%s cryptoSlotDescription='%s'", strings,
+ slotdesc);
+ PR_smprintf_free(strings);
+ strings = newStrings;
}
- if (strings == NULL) return NULL;
+ if (strings == NULL)
+ return NULL;
if (pslotdesc) {
- newStrings = PR_smprintf("%s dbSlotDescription='%s'",strings,pslotdesc);
- PR_smprintf_free(strings);
- strings = newStrings;
+ newStrings = PR_smprintf("%s dbSlotDescription='%s'", strings, pslotdesc);
+ PR_smprintf_free(strings);
+ strings = newStrings;
}
- if (strings == NULL) return NULL;
+ if (strings == NULL)
+ return NULL;
if (fslotdesc) {
newStrings = PR_smprintf("%s FIPSSlotDescription='%s'",
- strings,fslotdesc);
- PR_smprintf_free(strings);
- strings = newStrings;
+ strings, fslotdesc);
+ PR_smprintf_free(strings);
+ strings = newStrings;
}
- if (strings == NULL) return NULL;
+ if (strings == NULL)
+ return NULL;
if (fpslotdesc) {
newStrings = PR_smprintf("%s FIPSTokenDescription='%s'",
- strings,fpslotdesc);
- PR_smprintf_free(strings);
- strings = newStrings;
+ strings, fpslotdesc);
+ PR_smprintf_free(strings);
+ strings = newStrings;
}
- if (strings == NULL) return NULL;
+ if (strings == NULL)
+ return NULL;
newStrings = PR_smprintf("%s minPS=%d", strings, minPwd);
PR_smprintf_free(strings);
strings = newStrings;
- return(strings);
+ return (strings);
}
/*
* statics to remember the PK11_ConfigurePKCS11()
* info.
*/
-static char * pk11_config_strings = NULL;
-static char * pk11_config_name = NULL;
+static char *pk11_config_strings = NULL;
+static char *pk11_config_name = NULL;
static PRBool pk11_password_required = PR_FALSE;
/*
@@ -192,27 +207,27 @@ static PRBool pk11_password_required = PR_FALSE;
*/
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)
+ const char *ptokdesc, const char *slotdesc, const char *pslotdesc,
+ const char *fslotdesc, const char *fpslotdesc, int minPwd,
+ int pwRequired)
{
- char * strings;
+ char *strings;
- strings = nss_MkConfigString(man,libdesc,tokdesc,ptokdesc,slotdesc,
- pslotdesc,fslotdesc,fpslotdesc,minPwd);
+ strings = nss_MkConfigString(man, libdesc, tokdesc, ptokdesc, slotdesc,
+ pslotdesc, fslotdesc, fpslotdesc, minPwd);
if (strings == NULL) {
- return;
+ return;
}
if (libdesc) {
- if (pk11_config_name != NULL) {
- PORT_Free(pk11_config_name);
- }
- pk11_config_name = PORT_Strdup(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);
+ PR_smprintf_free(pk11_config_strings);
}
pk11_config_strings = strings;
pk11_password_required = pwRequired;
@@ -220,10 +235,11 @@ PK11_ConfigurePKCS11(const char *man, const char *libdesc, const char *tokdesc,
return;
}
-void PK11_UnconfigurePKCS11(void)
+void
+PK11_UnconfigurePKCS11(void)
{
if (pk11_config_strings != NULL) {
- PR_smprintf_free(pk11_config_strings);
+ PR_smprintf_free(pk11_config_strings);
pk11_config_strings = NULL;
}
if (pk11_config_name) {
@@ -240,23 +256,24 @@ void PK11_UnconfigurePKCS11(void)
static const char *dllname =
#if defined(XP_WIN32) || defined(XP_OS2)
- "nssckbi.dll";
-#elif defined(HPUX) && !defined(__ia64) /* HP-UX PA-RISC */
- "libnssckbi.sl";
+ "nssckbi.dll";
+#elif defined(HPUX) && !defined(__ia64) /* HP-UX PA-RISC */
+ "libnssckbi.sl";
#elif defined(DARWIN)
- "libnssckbi.dylib";
+ "libnssckbi.dylib";
#elif defined(XP_UNIX) || defined(XP_BEOS)
- "libnssckbi.so";
+ "libnssckbi.so";
#else
- #error "Uh! Oh! I don't know about this platform."
+#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)
+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;
@@ -267,26 +284,27 @@ static void nss_FindExternalRootPaths(const char *dbpath,
len = path_len + secmod_len + dll_len + 2; /* FILE_SEP + NULL */
path = PORT_Alloc(len);
- if (path == NULL) return;
+ 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) {
+ PORT_Memcpy(path, dbpath, path_len);
+ if (path[path_len - 1] != FILE_SEP) {
path[path_len++] = FILE_SEP;
}
- PORT_Strcpy(&path[path_len],dllname);
+ 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 */
+ 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);
+ PORT_Memcpy(oldpath, path, path_len);
+ PORT_Memcpy(&oldpath[path_len], secmodprefix, secmoddir_len);
+ PORT_Strcpy(&oldpath[path_len + secmoddir_len], dllname);
}
}
*retoldpath = oldpath;
@@ -294,7 +312,8 @@ static void nss_FindExternalRootPaths(const char *dbpath,
return;
}
-static void nss_FreeExternalRootPaths(char* oldpath, char* path)
+static void
+nss_FreeExternalRootPaths(char *oldpath, char *path)
{
if (path) {
PORT_Free(path);
@@ -305,27 +324,27 @@ static void nss_FreeExternalRootPaths(char* oldpath, char* path)
}
static void
-nss_FindExternalRoot(const char *dbpath, const char* secmodprefix)
+nss_FindExternalRoot(const char *dbpath, const char *secmodprefix)
{
- char *path = NULL;
- char *oldpath = NULL;
- PRBool hasrootcerts = PR_FALSE;
+ 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;
+ /*
+ * '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;
}
/*
@@ -335,17 +354,17 @@ nss_FindExternalRoot(const char *dbpath, const char* secmodprefix)
* 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)
+static SECMODModule *
+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;
+ SECMODModule *module = NULL;
char *moduleSpec = NULL;
char *flags = NULL;
char *lconfigdir = NULL;
@@ -359,13 +378,14 @@ nss_InitModules(const char *configdir, const char *certPrefix,
char *lupdateName = NULL;
if (NSS_InitializePRErrorTable() != SECSuccess) {
- PORT_SetError(SEC_ERROR_NO_MEMORY);
- return rv;
+ PORT_SetError(SEC_ERROR_NO_MEMORY);
+ return NULL;
}
- flags = nss_makeFlags(readOnly,noCertDB,noModDB,forceOpen,
- pwRequired, optimizeSpace);
- if (flags == NULL) return rv;
+ flags = nss_makeFlags(readOnly, noCertDB, noModDB, forceOpen,
+ pwRequired, optimizeSpace);
+ if (flags == NULL)
+ return NULL;
/*
* configdir is double nested, and Windows uses the same character
@@ -373,73 +393,82 @@ nss_InitModules(const char *configdir, const char *certPrefix,
*/
lconfigdir = NSSUTIL_DoubleEscape(configdir, '\'', '\"');
if (lconfigdir == NULL) {
- goto loser;
+ goto loser;
}
lcertPrefix = NSSUTIL_DoubleEscape(certPrefix, '\'', '\"');
if (lcertPrefix == NULL) {
- goto loser;
+ goto loser;
}
lkeyPrefix = NSSUTIL_DoubleEscape(keyPrefix, '\'', '\"');
if (lkeyPrefix == NULL) {
- goto loser;
+ goto loser;
}
lsecmodName = NSSUTIL_DoubleEscape(secmodName, '\'', '\"');
if (lsecmodName == NULL) {
- goto loser;
+ goto loser;
}
lupdateDir = NSSUTIL_DoubleEscape(updateDir, '\'', '\"');
if (lupdateDir == NULL) {
- goto loser;
+ goto loser;
}
lupdCertPrefix = NSSUTIL_DoubleEscape(updCertPrefix, '\'', '\"');
if (lupdCertPrefix == NULL) {
- goto loser;
+ goto loser;
}
lupdKeyPrefix = NSSUTIL_DoubleEscape(updKeyPrefix, '\'', '\"');
if (lupdKeyPrefix == NULL) {
- goto loser;
+ goto loser;
}
lupdateID = NSSUTIL_DoubleEscape(updateID, '\'', '\"');
if (lupdateID == NULL) {
- goto loser;
+ goto loser;
}
lupdateName = NSSUTIL_DoubleEscape(updateName, '\'', '\"');
if (lupdateName == NULL) {
- goto loser;
+ 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");
+ "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 (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);
- }
+ module = SECMOD_LoadModule(moduleSpec, NULL, PR_TRUE);
+ PR_smprintf_free(moduleSpec);
+ if (module && !module->loaded) {
+ SECMOD_DestroyModule(module);
+ return NULL;
+ }
}
- return rv;
+ return module;
}
/*
@@ -447,9 +476,9 @@ loser:
*
* 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-"
+ * "https-server1-"
* keyPrefix - prefix added to the beginning of the key database example: "
- * "https-server1-"
+ * "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.
@@ -457,12 +486,12 @@ loser:
* 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.
+ * 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.
+ * 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.
@@ -479,9 +508,12 @@ loser:
* don'tFinalizeModules - dont shutdown modules we may have loaded.
*/
-static PRBool nssIsInitted = PR_FALSE;
+static PRBool nssIsInitted = PR_FALSE;
static NSSInitContext *nssInitContextList = NULL;
-static void* plContext = NULL;
+
+#ifndef NSS_DISABLE_LIBPKIX
+static void *plContext = NULL;
+#endif /* NSS_DISABLE_LIBPKIX */
struct NSSInitContextStr {
NSSInitContext *next;
@@ -502,62 +534,66 @@ nss_doLockInit(void)
{
nssInitLock = PZ_NewLock(nssILockOther);
if (nssInitLock == NULL) {
- return PR_FAILURE;
+ return PR_FAILURE;
}
nssInitCondition = PZ_NewCondVar(nssInitLock);
if (nssInitCondition == NULL) {
- return PR_FAILURE;
+ 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)
+ 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;
+ SECMODModule *parent = NULL;
+#ifndef NSS_DISABLE_LIBPKIX
PKIX_UInt32 actualMinorVersion = 0;
PKIX_Error *pkixError = NULL;
+#endif /* NSS_DISABLE_LIBPKIX */
PRBool isReallyInitted;
char *configStrings = NULL;
char *configName = NULL;
PRBool passwordRequired = PR_FALSE;
+#ifdef POLICY_FILE
+ char *ignoreVar;
+#endif
/* if we are trying to init with a traditional NSS_Init call, maintain
* the traditional idempotent behavior. */
if (!initContextPtr && nssIsInitted) {
- return SECSuccess;
+ return SECSuccess;
}
-
+
/* make sure our lock and condition variable are initialized one and only
- * one time */
+ * one time */
if (PR_CallOnce(&nssInitOnce, nss_doLockInit) != PR_SUCCESS) {
- return SECFailure;
+ return SECFailure;
}
/*
- * if we haven't done basic initialization, single thread the
+ * 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. */
+ 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);
@@ -569,21 +605,21 @@ nss_Init(const char *configdir, const char *certPrefix, const char *keyPrefix,
if (!isReallyInitted) {
#ifdef DEBUG
CERTCertificate dummyCert;
- /* New option bits must not change the size of CERTCertificate. */
- PORT_Assert(sizeof(dummyCert.options) == sizeof(void *));
+ /* New option bits must not change the size of CERTCertificate. */
+ PORT_Assert(sizeof(dummyCert.options) == sizeof(void *));
#endif
- if (SECSuccess != cert_InitLocks()) {
- goto loser;
- }
+ if (SECSuccess != cert_InitLocks()) {
+ goto loser;
+ }
+
+ if (SECSuccess != InitCRLCache()) {
+ goto loser;
+ }
- if (SECSuccess != InitCRLCache()) {
- goto loser;
- }
-
- if (SECSuccess != OCSP_InitGlobal()) {
- goto loser;
- }
+ if (SECSuccess != OCSP_InitGlobal()) {
+ goto loser;
+ }
}
if (noSingleThreadedModules || allowAlreadyInitializedModules ||
@@ -594,110 +630,146 @@ nss_Init(const char *configdir, const char *certPrefix, const char *keyPrefix,
}
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.
- */
+ *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;
- }
+ 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;
+ }
+
+ /* If we're NSS_ContextInit, we're probably a library. It could be
+ * possible that the application initialized NSS then forked(). The
+ * library would have no knowledge of that. If we call
+ * SECMOD_RestartModules() here, we will be able to continue on with
+ * NSS as normal. SECMOD_RestartModules() does have the side affect
+ * of losing all our PKCS #11 objects in the new process, but only if
+ * the module needs to be reinited. If it needs to be reinit those
+ * objects are inaccessible anyway, it's always save to call
+ * SECMOD_RestartModules(PR_FALSE).
+ */
+ /* NOTE: We could call SECMOD_Init() here, but if we aren't already
+ * inited, then there's no modules to restart, so SECMOD_RestartModules
+ * will return immediately */
+ SECMOD_RestartModules(PR_FALSE);
} else {
- configStrings = pk11_config_strings;
- configName = pk11_config_name;
- passwordRequired = pk11_password_required;
+ 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;
- }
+ parent = nss_InitModules(configdir, certPrefix, keyPrefix, secmodName,
+ updateDir, updCertPrefix, updKeyPrefix, updateID,
+ updateName, configName, configStrings, passwordRequired,
+ readOnly, noCertDB, noModDB, forceOpen, optimizeSpace,
+ (initContextPtr != NULL));
+
+ if (parent == NULL) {
+ 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);
+ 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);
+ }
+ }
+ }
+#ifdef POLICY_FILE
+ /* Load the system crypto policy file if it exists,
+ * unless the NSS_IGNORE_SYSTEM_POLICY environment
+ * variable has been set to 1. */
+ ignoreVar = PR_GetEnvSecure("NSS_IGNORE_SYSTEM_POLICY");
+ if (ignoreVar == NULL || strncmp(ignoreVar, "1", sizeof("1")) != 0) {
+ if (PR_Access(POLICY_PATH "/" POLICY_FILE, PR_ACCESS_READ_OK) == PR_SUCCESS) {
+ SECMODModule *module = SECMOD_LoadModule(
+ "name=\"Policy File\" "
+ "parameters=\"configdir='sql:" POLICY_PATH "' "
+ "secmod='" POLICY_FILE "' "
+ "flags=readOnly,noCertDB,forceSecmodChoice,forceOpen\" "
+ "NSS=\"flags=internal,moduleDB,skipFirst,moduleDBOnly,critical\"",
+ parent, PR_TRUE);
+ if (module) {
+ PRBool isLoaded = module->loaded;
+ SECMOD_DestroyModule(module);
+ if (!isLoaded) {
+ goto loser;
+ }
+ }
}
}
+#endif
+ pk11sdr_Init();
+ cert_CreateSubjectKeyIDHashTable();
+#ifndef NSS_DISABLE_LIBPKIX
+ pkixError = PKIX_Initialize(PKIX_FALSE, PKIX_MAJOR_VERSION, PKIX_MINOR_VERSION,
+ PKIX_MINOR_VERSION, &actualMinorVersion, &plContext);
+ if (pkixError != NULL) {
+ goto loser;
+ } else {
+ char *ev = PR_GetEnvSecure("NSS_ENABLE_PKIX_VERIFY");
+ if (ev && ev[0]) {
+ CERT_SetUsePKIXForValidation(PR_TRUE);
+ }
+ }
+#endif /* NSS_DISABLE_LIBPKIX */
}
/*
@@ -707,11 +779,11 @@ nss_Init(const char *configdir, const char *certPrefix, const char *keyPrefix,
*/
PZ_Lock(nssInitLock);
if (!initContextPtr) {
- nssIsInitted = PR_TRUE;
+ nssIsInitted = PR_TRUE;
} else {
- (*initContextPtr)->magic = NSS_INIT_MAGIC;
- (*initContextPtr)->next = nssInitContextList;
- nssInitContextList = (*initContextPtr);
+ (*initContextPtr)->magic = NSS_INIT_MAGIC;
+ (*initContextPtr)->next = nssInitContextList;
+ nssInitContextList = (*initContextPtr);
}
nssIsInInit--;
/* now that we are inited, all waiters can move forward */
@@ -719,42 +791,47 @@ nss_Init(const char *configdir, const char *certPrefix, const char *keyPrefix,
PZ_Unlock(nssInitLock);
if (initContextPtr && configStrings) {
- PR_smprintf_free(configStrings);
+ PR_smprintf_free(configStrings);
+ }
+ if (parent) {
+ SECMOD_DestroyModule(parent);
}
return SECSuccess;
loser:
if (initContextPtr && *initContextPtr) {
- PORT_Free(*initContextPtr);
- *initContextPtr = NULL;
- if (configStrings) {
- PR_smprintf_free(configStrings);
- }
+ 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);
+ if (parent) {
+ SECMOD_DestroyModule(parent);
+ }
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);
+ 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);
+ NULL, PR_FALSE, PR_FALSE, PR_FALSE, PR_FALSE, PR_FALSE,
+ PR_TRUE, PR_FALSE, PR_FALSE, PR_FALSE);
}
/*
@@ -762,18 +839,18 @@ NSS_InitReadWrite(const char *configdir)
*
* 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-"
+ * "https-server1-"
* keyPrefix - prefix added to the beginning of the key database example: "
- * "https-server1-"
+ * "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_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
@@ -803,111 +880,110 @@ NSS_InitReadWrite(const char *configdir)
* 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.
+ * 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)
+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));
+ "", "", "", "", "", 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)
+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));
+ "", "", "", "", "", &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)
+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));
+ 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)
+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);
+ 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;
+ NSS_ShutdownFunc func;
+ void *appData;
};
static struct NSSShutdownListStr {
- PZLock *lock;
- int allocatedFuncs;
- int peakFuncs;
- struct NSSShutdownFuncPair *funcs;
+ PZLock *lock;
+ int allocatedFuncs;
+ int peakFuncs;
+ struct NSSShutdownFuncPair *funcs;
} nssShutdownList = { 0 };
/*
* find and existing shutdown function
*/
-static int
+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;
- }
+ 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
*/
@@ -917,21 +993,21 @@ NSS_RegisterShutdown(NSS_ShutdownFunc sFunc, void *appData)
int i;
/* make sure our lock and condition variable are initialized one and only
- * one time */
+ * one time */
if (PR_CallOnce(&nssInitOnce, nss_doLockInit) != PR_SUCCESS) {
- return SECFailure;
+ return SECFailure;
}
PZ_Lock(nssInitLock);
if (!NSS_IsInitialized()) {
- PZ_Unlock(nssInitLock);
- PORT_SetError(SEC_ERROR_NOT_INITIALIZED);
- return SECFailure;
+ 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_SetError(SEC_ERROR_INVALID_ARGS);
+ return SECFailure;
}
PORT_Assert(nssShutdownList.lock);
@@ -940,30 +1016,28 @@ NSS_RegisterShutdown(NSS_ShutdownFunc sFunc, void *appData)
/* 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;
+ 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;
+ 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;
+ 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;
@@ -981,15 +1055,15 @@ NSS_UnregisterShutdown(NSS_ShutdownFunc sFunc, void *appData)
int i;
/* make sure our lock and condition variable are initialized one and only
- * one time */
+ * one time */
if (PR_CallOnce(&nssInitOnce, nss_doLockInit) != PR_SUCCESS) {
- return SECFailure;
+ return SECFailure;
}
PZ_Lock(nssInitLock);
if (!NSS_IsInitialized()) {
- PZ_Unlock(nssInitLock);
- PORT_SetError(SEC_ERROR_NOT_INITIALIZED);
- return SECFailure;
+ PZ_Unlock(nssInitLock);
+ PORT_SetError(SEC_ERROR_NOT_INITIALIZED);
+ return SECFailure;
}
PZ_Unlock(nssInitLock);
@@ -997,14 +1071,14 @@ NSS_UnregisterShutdown(NSS_ShutdownFunc sFunc, void *appData)
PZ_Lock(nssShutdownList.lock);
i = nss_GetShutdownEntry(sFunc, appData);
if (i >= 0) {
- nssShutdownList.funcs[i].func = NULL;
- nssShutdownList.funcs[i].appData = NULL;
+ 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;
+ PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
+ return SECFailure;
}
return SECSuccess;
}
@@ -1016,18 +1090,18 @@ static SECStatus
nss_InitShutdownList(void)
{
if (nssShutdownList.lock != NULL) {
- return SECSuccess;
+ return SECSuccess;
}
nssShutdownList.lock = PZ_NewLock(nssILockOther);
if (nssShutdownList.lock == NULL) {
- return SECFailure;
+ return SECFailure;
}
- nssShutdownList.funcs = PORT_ZNewArray(struct NSSShutdownFuncPair,
- NSS_SHUTDOWN_STEP);
+ nssShutdownList.funcs = PORT_ZNewArray(struct NSSShutdownFuncPair,
+ NSS_SHUTDOWN_STEP);
if (nssShutdownList.funcs == NULL) {
- PZ_DestroyLock(nssShutdownList.lock);
- nssShutdownList.lock = NULL;
- return SECFailure;
+ PZ_DestroyLock(nssShutdownList.lock);
+ nssShutdownList.lock = NULL;
+ return SECFailure;
}
nssShutdownList.allocatedFuncs = NSS_SHUTDOWN_STEP;
nssShutdownList.peakFuncs = 0;
@@ -1042,13 +1116,13 @@ nss_ShutdownShutdownList(void)
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;
- }
- }
+ 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;
@@ -1056,13 +1130,12 @@ nss_ShutdownShutdownList(void)
PORT_Free(nssShutdownList.funcs);
nssShutdownList.funcs = NULL;
if (nssShutdownList.lock) {
- PZ_DestroyLock(nssShutdownList.lock);
+ PZ_DestroyLock(nssShutdownList.lock);
}
nssShutdownList.lock = NULL;
return rv;
}
-
extern const NSSError NSS_ERROR_BUSY;
SECStatus
@@ -1075,27 +1148,29 @@ nss_Shutdown(void)
rv = nss_ShutdownShutdownList();
if (rv != SECSuccess) {
- shutdownRV = SECFailure;
+ shutdownRV = SECFailure;
}
cert_DestroyLocks();
ShutdownCRLCache();
OCSP_ShutdownGlobal();
+#ifndef NSS_DISABLE_LIBPKIX
PKIX_Shutdown(plContext);
+#endif /* NSS_DISABLE_LIBPKIX */
SECOID_Shutdown();
status = STAN_Shutdown();
cert_DestroySubjectKeyIDHashTable();
pk11_SetInternalKeySlot(NULL);
rv = SECMOD_Shutdown();
if (rv != SECSuccess) {
- shutdownRV = SECFailure;
+ shutdownRV = SECFailure;
}
pk11sdr_Shutdown();
nssArena_Shutdown();
if (status == PR_FAILURE) {
- if (NSS_GetError() == NSS_ERROR_BUSY) {
- PORT_SetError(SEC_ERROR_BUSY);
- }
- shutdownRV = SECFailure;
+ if (NSS_GetError() == NSS_ERROR_BUSY) {
+ PORT_SetError(SEC_ERROR_BUSY);
+ }
+ shutdownRV = SECFailure;
}
/*
* A thread's error stack is automatically destroyed when the thread
@@ -1113,10 +1188,10 @@ nss_Shutdown(void)
/* 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;
+ NSSInitContext *next = temp->next;
+ temp->magic = 0;
+ PORT_Free(temp);
+ temp = next;
}
return shutdownRV;
}
@@ -1126,22 +1201,22 @@ NSS_Shutdown(void)
{
SECStatus rv;
/* make sure our lock and condition variable are initialized one and only
- * one time */
+ * one time */
if (PR_CallOnce(&nssInitOnce, nss_doLockInit) != PR_SUCCESS) {
- return SECFailure;
+ return SECFailure;
}
PZ_Lock(nssInitLock);
if (!nssIsInitted) {
- PZ_Unlock(nssInitLock);
- PORT_SetError(SEC_ERROR_NOT_INITIALIZED);
- return SECFailure;
+ 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);
+ PZ_WaitCondVar(nssInitCondition, PR_INTERVAL_NO_TIMEOUT);
}
rv = nss_Shutdown();
PZ_Unlock(nssInitLock);
@@ -1152,25 +1227,26 @@ NSS_Shutdown(void)
* remove the context from a list. return true if found, false if not
*/
PRBool
-nss_RemoveList(NSSInitContext *context) {
+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;
+ 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
+ * 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.
@@ -1183,34 +1259,34 @@ NSS_ShutdownContext(NSSInitContext *context)
SECStatus rv = SECSuccess;
/* make sure our lock and condition variable are initialized one and only
- * one time */
+ * one time */
if (PR_CallOnce(&nssInitOnce, nss_doLockInit) != PR_SUCCESS) {
- return SECFailure;
+ 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);
+ 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) {
+ 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();
+ rv = nss_Shutdown();
}
/* NOTE: we don't try to free the nssInitLocks to prevent races against
@@ -1227,7 +1303,6 @@ NSS_IsInitialized(void)
{
return (nssIsInitted) || (nssInitContextList != NULL);
}
-
extern const char __nss_base_version[];
diff --git a/nss/lib/nss/nssoptions.c b/nss/lib/nss/nssoptions.c
index 10b0138..fc97d62 100644
--- a/nss/lib/nss/nssoptions.c
+++ b/nss/lib/nss/nssoptions.c
@@ -19,31 +19,51 @@ struct nssOps {
PRInt32 rsaMinKeySize;
PRInt32 dhMinKeySize;
PRInt32 dsaMinKeySize;
+ PRInt32 tlsVersionMinPolicy;
+ PRInt32 tlsVersionMaxPolicy;
+ PRInt32 dtlsVersionMinPolicy;
+ PRInt32 dtlsVersionMaxPolicy;
};
static struct nssOps nss_ops = {
SSL_RSA_MIN_MODULUS_BITS,
SSL_DH_MIN_P_BITS,
- SSL_DSA_MIN_P_BITS
+ SSL_DSA_MIN_P_BITS,
+ 1, /* Set TLS min to less the the smallest legal SSL value */
+ 0xffff, /* set TLS max to more than the largest legal SSL value */
+ 1,
+ 0xffff,
};
SECStatus
NSS_OptionSet(PRInt32 which, PRInt32 value)
{
-SECStatus rv = SECSuccess;
+ SECStatus rv = SECSuccess;
switch (which) {
- case NSS_RSA_MIN_KEY_SIZE:
- nss_ops.rsaMinKeySize = value;
- break;
- case NSS_DH_MIN_KEY_SIZE:
- nss_ops.dhMinKeySize = value;
- break;
- case NSS_DSA_MIN_KEY_SIZE:
- nss_ops.dsaMinKeySize = value;
- break;
- default:
- rv = SECFailure;
+ case NSS_RSA_MIN_KEY_SIZE:
+ nss_ops.rsaMinKeySize = value;
+ break;
+ case NSS_DH_MIN_KEY_SIZE:
+ nss_ops.dhMinKeySize = value;
+ break;
+ case NSS_DSA_MIN_KEY_SIZE:
+ nss_ops.dsaMinKeySize = value;
+ break;
+ case NSS_TLS_VERSION_MIN_POLICY:
+ nss_ops.tlsVersionMinPolicy = value;
+ break;
+ case NSS_TLS_VERSION_MAX_POLICY:
+ nss_ops.tlsVersionMaxPolicy = value;
+ break;
+ case NSS_DTLS_VERSION_MIN_POLICY:
+ nss_ops.dtlsVersionMinPolicy = value;
+ break;
+ case NSS_DTLS_VERSION_MAX_POLICY:
+ nss_ops.dtlsVersionMaxPolicy = value;
+ break;
+ default:
+ rv = SECFailure;
}
return rv;
@@ -52,22 +72,33 @@ SECStatus rv = SECSuccess;
SECStatus
NSS_OptionGet(PRInt32 which, PRInt32 *value)
{
-SECStatus rv = SECSuccess;
+ SECStatus rv = SECSuccess;
switch (which) {
- case NSS_RSA_MIN_KEY_SIZE:
- *value = nss_ops.rsaMinKeySize;
- break;
- case NSS_DH_MIN_KEY_SIZE:
- *value = nss_ops.dhMinKeySize;
- break;
- case NSS_DSA_MIN_KEY_SIZE:
- *value = nss_ops.dsaMinKeySize;
- break;
- default:
- rv = SECFailure;
+ case NSS_RSA_MIN_KEY_SIZE:
+ *value = nss_ops.rsaMinKeySize;
+ break;
+ case NSS_DH_MIN_KEY_SIZE:
+ *value = nss_ops.dhMinKeySize;
+ break;
+ case NSS_DSA_MIN_KEY_SIZE:
+ *value = nss_ops.dsaMinKeySize;
+ break;
+ case NSS_TLS_VERSION_MIN_POLICY:
+ *value = nss_ops.tlsVersionMinPolicy;
+ break;
+ case NSS_TLS_VERSION_MAX_POLICY:
+ *value = nss_ops.tlsVersionMaxPolicy;
+ break;
+ case NSS_DTLS_VERSION_MIN_POLICY:
+ *value = nss_ops.dtlsVersionMinPolicy;
+ break;
+ case NSS_DTLS_VERSION_MAX_POLICY:
+ *value = nss_ops.dtlsVersionMaxPolicy;
+ break;
+ default:
+ rv = SECFailure;
}
return rv;
}
-
diff --git a/nss/lib/nss/nssoptions.h b/nss/lib/nss/nssoptions.h
index daa0944..024c1e9 100644
--- a/nss/lib/nss/nssoptions.h
+++ b/nss/lib/nss/nssoptions.h
@@ -7,7 +7,7 @@
/*
* Include the default limits here
*/
-/* SSL default limits are here so we don't have to import a private SSL header
+/* SSL default limits are here so we don't have to import a private SSL header
* file into NSS proper */
/* The minimum server key sizes accepted by the clients.
@@ -18,4 +18,3 @@
* happens because NSS used to count bit lengths incorrectly. */
#define SSL_DH_MIN_P_BITS 1023
#define SSL_DSA_MIN_P_BITS 1023
-
diff --git a/nss/lib/nss/utilwrap.c b/nss/lib/nss/utilwrap.c
index d3b6037..938d95c 100644
--- a/nss/lib/nss/utilwrap.c
+++ b/nss/lib/nss/utilwrap.c
@@ -236,518 +236,595 @@ PORT_SetUCS4_UTF8ConversionFunction(PORTCharConversionFunc convFunc)
void
PORT_SetUCS2_ASCIIConversionFunction(PORTCharConversionWSwapFunc convFunc)
-{
+{
PORT_SetUCS2_ASCIIConversionFunction_Util(convFunc);
}
void
PORT_SetUCS2_UTF8ConversionFunction(PORTCharConversionFunc convFunc)
-{
+{
PORT_SetUCS2_UTF8ConversionFunction_Util(convFunc);
}
-PRBool
+PRBool
PORT_UCS2_UTF8Conversion(PRBool toUnicode, unsigned char *inBuf,
- unsigned int inBufLen, unsigned char *outBuf,
- unsigned int maxOutBufLen, unsigned int *outBufLen)
+ unsigned int inBufLen, unsigned char *outBuf,
+ unsigned int maxOutBufLen, unsigned int *outBufLen)
{
return PORT_UCS2_UTF8Conversion_Util(toUnicode, inBuf, inBufLen, outBuf,
- maxOutBufLen, outBufLen);
-}
+ maxOutBufLen, outBufLen);
+}
-PRBool
+PRBool
PORT_UCS2_ASCIIConversion(PRBool toUnicode, unsigned char *inBuf,
- unsigned int inBufLen, unsigned char *outBuf,
- unsigned int maxOutBufLen, unsigned int *outBufLen,
- PRBool swapBytes)
+ 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);
+ maxOutBufLen, outBufLen, swapBytes);
}
int
-NSS_PutEnv(const char * envVarName, const char * envValue)
+NSS_PutEnv(const char *envVarName, const char *envValue)
{
return NSS_PutEnv_Util(envVarName, envValue);
}
-SECOidData *SECOID_FindOID( const SECItem *oid)
+SECOidData *
+SECOID_FindOID(const SECItem *oid)
{
return SECOID_FindOID_Util(oid);
}
-SECOidTag SECOID_FindOIDTag(const SECItem *oid)
+SECOidTag
+SECOID_FindOIDTag(const SECItem *oid)
{
return SECOID_FindOIDTag_Util(oid);
}
-SECOidData *SECOID_FindOIDByTag(SECOidTag tagnum)
+SECOidData *
+SECOID_FindOIDByTag(SECOidTag tagnum)
{
return SECOID_FindOIDByTag_Util(tagnum);
}
-SECStatus SECOID_SetAlgorithmID(PLArenaPool *arena, SECAlgorithmID *aid,
- SECOidTag tag, SECItem *params)
+SECStatus
+SECOID_SetAlgorithmID(PLArenaPool *arena, SECAlgorithmID *aid,
+ SECOidTag tag, SECItem *params)
{
return SECOID_SetAlgorithmID_Util(arena, aid, tag, params);
}
-SECStatus SECOID_CopyAlgorithmID(PLArenaPool *arena, SECAlgorithmID *dest,
- const SECAlgorithmID *src)
+SECStatus
+SECOID_CopyAlgorithmID(PLArenaPool *arena, SECAlgorithmID *dest,
+ const SECAlgorithmID *src)
{
return SECOID_CopyAlgorithmID_Util(arena, dest, src);
}
-SECOidTag SECOID_GetAlgorithmTag(const SECAlgorithmID *aid)
+SECOidTag
+SECOID_GetAlgorithmTag(const SECAlgorithmID *aid)
{
return SECOID_GetAlgorithmTag_Util(aid);
}
-void SECOID_DestroyAlgorithmID(SECAlgorithmID *aid, PRBool freeit)
+void
+SECOID_DestroyAlgorithmID(SECAlgorithmID *aid, PRBool freeit)
{
SECOID_DestroyAlgorithmID_Util(aid, freeit);
}
-SECComparison SECOID_CompareAlgorithmID(SECAlgorithmID *a,
- SECAlgorithmID *b)
+SECComparison
+SECOID_CompareAlgorithmID(SECAlgorithmID *a,
+ SECAlgorithmID *b)
{
return SECOID_CompareAlgorithmID_Util(a, b);
}
-const char *SECOID_FindOIDTagDescription(SECOidTag tagnum)
+const char *
+SECOID_FindOIDTagDescription(SECOidTag tagnum)
{
return SECOID_FindOIDTagDescription_Util(tagnum);
}
-SECOidTag SECOID_AddEntry(const SECOidData * src)
+SECOidTag
+SECOID_AddEntry(const SECOidData *src)
{
return SECOID_AddEntry_Util(src);
}
-SECItem *SECITEM_AllocItem(PLArenaPool *arena, SECItem *item,
- unsigned int len)
+SECItem *
+SECITEM_AllocItem(PLArenaPool *arena, SECItem *item,
+ unsigned int len)
{
return SECITEM_AllocItem_Util(arena, item, len);
}
-SECComparison SECITEM_CompareItem(const SECItem *a, const SECItem *b)
+SECComparison
+SECITEM_CompareItem(const SECItem *a, const SECItem *b)
{
return SECITEM_CompareItem_Util(a, b);
}
-PRBool SECITEM_ItemsAreEqual(const SECItem *a, const SECItem *b)
+PRBool
+SECITEM_ItemsAreEqual(const SECItem *a, const SECItem *b)
{
return SECITEM_ItemsAreEqual_Util(a, b);
}
-SECStatus SECITEM_CopyItem(PLArenaPool *arena, SECItem *to,
- const SECItem *from)
+SECStatus
+SECITEM_CopyItem(PLArenaPool *arena, SECItem *to,
+ const SECItem *from)
{
return SECITEM_CopyItem_Util(arena, to, from);
}
-SECItem *SECITEM_DupItem(const SECItem *from)
+SECItem *
+SECITEM_DupItem(const SECItem *from)
{
return SECITEM_DupItem_Util(from);
}
-SECItem *SECITEM_ArenaDupItem(PLArenaPool *arena, const SECItem *from)
+SECItem *
+SECITEM_ArenaDupItem(PLArenaPool *arena, const SECItem *from)
{
return SECITEM_ArenaDupItem_Util(arena, from);
}
-void SECITEM_FreeItem(SECItem *zap, PRBool freeit)
+void
+SECITEM_FreeItem(SECItem *zap, PRBool freeit)
{
SECITEM_FreeItem_Util(zap, freeit);
}
-void SECITEM_ZfreeItem(SECItem *zap, PRBool freeit)
+void
+SECITEM_ZfreeItem(SECItem *zap, PRBool freeit)
{
SECITEM_ZfreeItem_Util(zap, freeit);
}
-SGNDigestInfo *SGN_CreateDigestInfo(SECOidTag algorithm,
- unsigned char *sig,
- unsigned int sigLen)
+SGNDigestInfo *
+SGN_CreateDigestInfo(SECOidTag algorithm,
+ unsigned char *sig,
+ unsigned int sigLen)
{
return SGN_CreateDigestInfo_Util(algorithm, sig, sigLen);
}
-void SGN_DestroyDigestInfo(SGNDigestInfo *info)
+void
+SGN_DestroyDigestInfo(SGNDigestInfo *info)
{
SGN_DestroyDigestInfo_Util(info);
}
-SECStatus SGN_CopyDigestInfo(PLArenaPool *poolp,
- SGNDigestInfo *a,
- SGNDigestInfo *b)
+SECStatus
+SGN_CopyDigestInfo(PLArenaPool *poolp,
+ SGNDigestInfo *a,
+ SGNDigestInfo *b)
{
return SGN_CopyDigestInfo_Util(poolp, a, b);
}
-SECComparison SGN_CompareDigestInfo(SGNDigestInfo *a, SGNDigestInfo *b)
+SECComparison
+SGN_CompareDigestInfo(SGNDigestInfo *a, SGNDigestInfo *b)
{
return SGN_CompareDigestInfo_Util(a, b);
}
-SECStatus DER_Encode(PLArenaPool *arena, SECItem *dest, DERTemplate *t,
- void *src)
+SECStatus
+DER_Encode(PLArenaPool *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)
+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(const SECItem *src)
+long
+DER_GetInteger(const SECItem *src)
{
return DER_GetInteger_Util(src);
}
-SECStatus DER_TimeToUTCTime(SECItem *result, PRTime time)
+SECStatus
+DER_TimeToUTCTime(SECItem *result, PRTime time)
{
return DER_TimeToUTCTime_Util(result, time);
}
-SECStatus DER_AsciiToTime(PRTime *result, const char *string)
+SECStatus
+DER_AsciiToTime(PRTime *result, const char *string)
{
return DER_AsciiToTime_Util(result, string);
}
-SECStatus DER_UTCTimeToTime(PRTime *result, const SECItem *time)
+SECStatus
+DER_UTCTimeToTime(PRTime *result, const SECItem *time)
{
return DER_UTCTimeToTime_Util(result, time);
}
-char *DER_UTCTimeToAscii(SECItem *utcTime)
+char *
+DER_UTCTimeToAscii(SECItem *utcTime)
{
return DER_UTCTimeToAscii_Util(utcTime);
}
-char *DER_UTCDayToAscii(SECItem *utctime)
+char *
+DER_UTCDayToAscii(SECItem *utctime)
{
return DER_UTCDayToAscii_Util(utctime);
}
-char *DER_GeneralizedDayToAscii(SECItem *gentime)
+char *
+DER_GeneralizedDayToAscii(SECItem *gentime)
{
return DER_GeneralizedDayToAscii_Util(gentime);
}
-char *DER_TimeChoiceDayToAscii(SECItem *timechoice)
+char *
+DER_TimeChoiceDayToAscii(SECItem *timechoice)
{
return DER_TimeChoiceDayToAscii_Util(timechoice);
}
-SECStatus DER_TimeToGeneralizedTime(SECItem *dst, PRTime gmttime)
+SECStatus
+DER_TimeToGeneralizedTime(SECItem *dst, PRTime gmttime)
{
return DER_TimeToGeneralizedTime_Util(dst, gmttime);
}
-SECStatus DER_TimeToGeneralizedTimeArena(PLArenaPool* arenaOpt,
- SECItem *dst, PRTime gmttime)
+SECStatus
+DER_TimeToGeneralizedTimeArena(PLArenaPool *arenaOpt,
+ SECItem *dst, PRTime gmttime)
{
return DER_TimeToGeneralizedTimeArena_Util(arenaOpt, dst, gmttime);
}
-SECStatus DER_GeneralizedTimeToTime(PRTime *dst, const SECItem *time)
+SECStatus
+DER_GeneralizedTimeToTime(PRTime *dst, const SECItem *time)
{
return DER_GeneralizedTimeToTime_Util(dst, time);
}
-char *CERT_GenTime2FormattedAscii(PRTime genTime, char *format)
+char *
+CERT_GenTime2FormattedAscii(PRTime genTime, char *format)
{
return CERT_GenTime2FormattedAscii_Util(genTime, format);
}
-SECStatus DER_DecodeTimeChoice(PRTime* output, const SECItem* input)
+SECStatus
+DER_DecodeTimeChoice(PRTime *output, const SECItem *input)
{
return DER_DecodeTimeChoice_Util(output, input);
}
-SECStatus DER_EncodeTimeChoice(PLArenaPool* arena, SECItem* output,
- PRTime input)
+SECStatus
+DER_EncodeTimeChoice(PLArenaPool *arena, SECItem *output,
+ PRTime input)
{
return DER_EncodeTimeChoice_Util(arena, output, input);
}
-SEC_ASN1DecoderContext *SEC_ASN1DecoderStart(PLArenaPool *pool,
- void *dest,
- const SEC_ASN1Template *t)
+SEC_ASN1DecoderContext *
+SEC_ASN1DecoderStart(PLArenaPool *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)
+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)
+SECStatus
+SEC_ASN1DecoderFinish(SEC_ASN1DecoderContext *cx)
{
return SEC_ASN1DecoderFinish_Util(cx);
}
-void SEC_ASN1DecoderAbort(SEC_ASN1DecoderContext *cx, int error)
+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)
+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)
+void
+SEC_ASN1DecoderClearFilterProc(SEC_ASN1DecoderContext *cx)
{
SEC_ASN1DecoderClearFilterProc_Util(cx);
}
-void SEC_ASN1DecoderSetNotifyProc(SEC_ASN1DecoderContext *cx,
- SEC_ASN1NotifyProc fn,
- void *arg)
+void
+SEC_ASN1DecoderSetNotifyProc(SEC_ASN1DecoderContext *cx,
+ SEC_ASN1NotifyProc fn,
+ void *arg)
{
SEC_ASN1DecoderSetNotifyProc_Util(cx, fn, arg);
}
-void SEC_ASN1DecoderClearNotifyProc(SEC_ASN1DecoderContext *cx)
+void
+SEC_ASN1DecoderClearNotifyProc(SEC_ASN1DecoderContext *cx)
{
SEC_ASN1DecoderClearNotifyProc_Util(cx);
}
-SECStatus SEC_ASN1Decode(PLArenaPool *pool, void *dest,
- const SEC_ASN1Template *t,
- const char *buf, long len)
+SECStatus
+SEC_ASN1Decode(PLArenaPool *pool, void *dest,
+ const SEC_ASN1Template *t,
+ const char *buf, long len)
{
return SEC_ASN1Decode_Util(pool, dest, t, buf, len);
}
-SECStatus SEC_ASN1DecodeItem(PLArenaPool *pool, void *dest,
- const SEC_ASN1Template *t,
- const SECItem *src)
+SECStatus
+SEC_ASN1DecodeItem(PLArenaPool *pool, void *dest,
+ const SEC_ASN1Template *t,
+ const SECItem *src)
{
return SEC_ASN1DecodeItem_Util(pool, dest, t, src);
}
-SECStatus SEC_QuickDERDecodeItem(PLArenaPool* arena, void* dest,
- const SEC_ASN1Template* templateEntry,
- const SECItem* src)
+SECStatus
+SEC_QuickDERDecodeItem(PLArenaPool *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)
+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)
+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)
+void
+SEC_ASN1EncoderFinish(SEC_ASN1EncoderContext *cx)
{
SEC_ASN1EncoderFinish_Util(cx);
}
-void SEC_ASN1EncoderAbort(SEC_ASN1EncoderContext *cx, int error)
+void
+SEC_ASN1EncoderAbort(SEC_ASN1EncoderContext *cx, int error)
{
SEC_ASN1EncoderAbort_Util(cx, error);
}
-void SEC_ASN1EncoderSetNotifyProc(SEC_ASN1EncoderContext *cx,
- SEC_ASN1NotifyProc fn,
- void *arg)
+void
+SEC_ASN1EncoderSetNotifyProc(SEC_ASN1EncoderContext *cx,
+ SEC_ASN1NotifyProc fn,
+ void *arg)
{
SEC_ASN1EncoderSetNotifyProc_Util(cx, fn, arg);
}
-void SEC_ASN1EncoderClearNotifyProc(SEC_ASN1EncoderContext *cx)
+void
+SEC_ASN1EncoderClearNotifyProc(SEC_ASN1EncoderContext *cx)
{
SEC_ASN1EncoderClearNotifyProc_Util(cx);
}
-void SEC_ASN1EncoderSetStreaming(SEC_ASN1EncoderContext *cx)
+void
+SEC_ASN1EncoderSetStreaming(SEC_ASN1EncoderContext *cx)
{
SEC_ASN1EncoderSetStreaming_Util(cx);
}
-void SEC_ASN1EncoderClearStreaming(SEC_ASN1EncoderContext *cx)
+void
+SEC_ASN1EncoderClearStreaming(SEC_ASN1EncoderContext *cx)
{
SEC_ASN1EncoderClearStreaming_Util(cx);
}
-void SEC_ASN1EncoderSetTakeFromBuf(SEC_ASN1EncoderContext *cx)
+void
+SEC_ASN1EncoderSetTakeFromBuf(SEC_ASN1EncoderContext *cx)
{
SEC_ASN1EncoderSetTakeFromBuf_Util(cx);
}
-void SEC_ASN1EncoderClearTakeFromBuf(SEC_ASN1EncoderContext *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)
+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(PLArenaPool *pool, SECItem *dest,
- const void *src, const SEC_ASN1Template *t)
+SECItem *
+SEC_ASN1EncodeItem(PLArenaPool *pool, SECItem *dest,
+ const void *src, const SEC_ASN1Template *t)
{
return SEC_ASN1EncodeItem_Util(pool, dest, src, t);
}
-SECItem * SEC_ASN1EncodeInteger(PLArenaPool *pool,
- SECItem *dest, long value)
+SECItem *
+SEC_ASN1EncodeInteger(PLArenaPool *pool,
+ SECItem *dest, long value)
{
return SEC_ASN1EncodeInteger_Util(pool, dest, value);
}
-SECItem * SEC_ASN1EncodeUnsignedInteger(PLArenaPool *pool,
- SECItem *dest,
- unsigned long value)
+SECItem *
+SEC_ASN1EncodeUnsignedInteger(PLArenaPool *pool,
+ SECItem *dest,
+ unsigned long value)
{
return SEC_ASN1EncodeUnsignedInteger_Util(pool, dest, value);
}
-SECStatus SEC_ASN1DecodeInteger(SECItem *src,
- unsigned long *value)
+SECStatus
+SEC_ASN1DecodeInteger(SECItem *src,
+ unsigned long *value)
{
return SEC_ASN1DecodeInteger_Util(src, value);
}
-int SEC_ASN1LengthLength (unsigned long len)
+int
+SEC_ASN1LengthLength(unsigned long len)
{
return SEC_ASN1LengthLength_Util(len);
}
-char *BTOA_DataToAscii(const unsigned char *data, unsigned int 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)
+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)
+
+SECStatus
+ATOB_ConvertAsciiToItem(SECItem *binary_item, const char *ascii)
{
return ATOB_ConvertAsciiToItem_Util(binary_item, ascii);
}
-char *BTOA_ConvertItemToAscii(SECItem *binary_item)
+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)
+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)
+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)
+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)
+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)
+NSSBase64Decoder_Destroy(NSSBase64Decoder *data, PRBool abort_p)
{
return NSSBase64Decoder_Destroy_Util(data, abort_p);
}
SECStatus
-NSSBase64Encoder_Destroy (NSSBase64Encoder *data, PRBool abort_p)
+NSSBase64Encoder_Destroy(NSSBase64Encoder *data, PRBool abort_p)
{
return NSSBase64Encoder_Destroy_Util(data, abort_p);
}
SECItem *
-NSSBase64_DecodeBuffer (PLArenaPool *arenaOpt, SECItem *outItemOpt,
- const char *inStr, unsigned int inLen)
+NSSBase64_DecodeBuffer(PLArenaPool *arenaOpt, SECItem *outItemOpt,
+ const char *inStr, unsigned int inLen)
{
return NSSBase64_DecodeBuffer_Util(arenaOpt, outItemOpt, inStr, inLen);
}
char *
-NSSBase64_EncodeItem (PLArenaPool *arenaOpt, char *outStrOpt,
- unsigned int maxOutLen, SECItem *inItem)
+NSSBase64_EncodeItem(PLArenaPool *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)
+NSSRWLock *
+NSSRWLock_New(PRUint32 lock_rank, const char *lock_name)
{
return NSSRWLock_New_Util(lock_rank, lock_name);
}
-void NSSRWLock_Destroy(NSSRWLock *lock)
+void
+NSSRWLock_Destroy(NSSRWLock *lock)
{
NSSRWLock_Destroy_Util(lock);
}
-void NSSRWLock_LockRead(NSSRWLock *lock)
+void
+NSSRWLock_LockRead(NSSRWLock *lock)
{
NSSRWLock_LockRead_Util(lock);
}
-void NSSRWLock_LockWrite(NSSRWLock *lock)
+void
+NSSRWLock_LockWrite(NSSRWLock *lock)
{
NSSRWLock_LockWrite_Util(lock);
}
-void NSSRWLock_UnlockRead(NSSRWLock *lock)
+void
+NSSRWLock_UnlockRead(NSSRWLock *lock)
{
NSSRWLock_UnlockRead_Util(lock);
}
-void NSSRWLock_UnlockWrite(NSSRWLock *lock)
+void
+NSSRWLock_UnlockWrite(NSSRWLock *lock)
{
NSSRWLock_UnlockWrite_Util(lock);
}
-PRBool NSSRWLock_HaveWriteLock(NSSRWLock *rwlock)
+PRBool
+NSSRWLock_HaveWriteLock(NSSRWLock *rwlock)
{
return NSSRWLock_HaveWriteLock_Util(rwlock);
}
-SECStatus __nss_InitLock( PZLock **ppLock, nssILockType ltype )
+SECStatus
+__nss_InitLock(PZLock **ppLock, nssILockType ltype)
{
PORT_SetError(PR_NOT_IMPLEMENTED_ERROR);
return SECFailure;
@@ -791,4 +868,3 @@ SECStatus __nss_InitLock( PZLock **ppLock, nssILockType ltype )
#undef sgn_DigestInfoTemplate
#include "templates.c"
-
diff --git a/nss/lib/pk11wrap/debug_module.c b/nss/lib/pk11wrap/debug_module.c
index 89ebacc..9230c01 100644
--- a/nss/lib/pk11wrap/debug_module.c
+++ b/nss/lib/pk11wrap/debug_module.c
@@ -3,7 +3,7 @@
* 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 */
+#include "cert.h" /* for CERT_DerNameToAscii & CERT_Hexify */
static PRLogModuleInfo *modlog = NULL;
@@ -13,575 +13,593 @@ 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";
+#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;
+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;
+ 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);
+ PR_snprintf(str, len, "%s", a);
else
- PR_snprintf(str, len, "0x%p", atype);
+ PR_snprintf(str, len, "0x%p", atype);
}
-static void get_obj_class(CK_OBJECT_CLASS objClass, char *str, int len)
+static void
+get_obj_class(CK_OBJECT_CLASS objClass, char *str, int len)
{
- const char * a = NULL;
+ 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;
+ 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);
+ PR_snprintf(str, len, "%s", a);
else
- PR_snprintf(str, len, "0x%p", objClass);
+ PR_snprintf(str, len, "0x%p", objClass);
}
-static void get_trust_val(CK_TRUST trust, char *str, int len)
+static void
+get_trust_val(CK_TRUST trust, char *str, int len)
{
- const char * a = NULL;
+ 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;
+ 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);
+ PR_snprintf(str, len, "%s", a);
else
- PR_snprintf(str, len, "0x%p", trust);
+ PR_snprintf(str, len, "0x%p", trust);
}
-static void log_rv(CK_RV rv)
+static void
+log_rv(CK_RV rv)
{
- const char * a = NULL;
+ 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;
+ 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));
+ PR_LOG(modlog, 1, (" rv = %s\n", a));
else
- PR_LOG(modlog, 1, (" rv = 0x%x\n", rv));
+ PR_LOG(modlog, 1, (" rv = 0x%x\n", rv));
}
-static void log_state(CK_STATE state)
+static void
+log_state(CK_STATE state)
{
- const char * a = NULL;
+ 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;
+ 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));
+ PR_LOG(modlog, 1, (" state = %s\n", a));
else
- PR_LOG(modlog, 1, (" state = 0x%x\n", state));
+ PR_LOG(modlog, 1, (" state = 0x%x\n", state));
}
-static void log_handle(int level, const char * format, CK_ULONG handle)
+static void
+log_handle(int level, const char *format, CK_ULONG handle)
{
char fmtBuf[80];
if (handle)
- PR_LOG(modlog, level, (format, 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));
+ 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)
+static void
+print_mechanism(CK_MECHANISM_PTR m)
{
- const char * a = NULL;
+ 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_CCM);
- CASE(CKM_AES_CTR);
- CASE(CKM_AES_CTS);
- CASE(CKM_AES_GCM);
- 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;
+ CASE(CKM_AES_CBC);
+ CASE(CKM_AES_CBC_ENCRYPT_DATA);
+ CASE(CKM_AES_CBC_PAD);
+ CASE(CKM_AES_CCM);
+ CASE(CKM_AES_CTR);
+ CASE(CKM_AES_CTS);
+ CASE(CKM_AES_GCM);
+ 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));
+ PR_LOG(modlog, 4, (" mechanism = %s", a));
else
- PR_LOG(modlog, 4, (" mechanism = 0x%p", m->mechanism));
+ PR_LOG(modlog, 4, (" mechanism = 0x%p", m->mechanism));
}
-static void get_key_type(CK_KEY_TYPE keyType, char *str, int len)
+static void
+get_key_type(CK_KEY_TYPE keyType, char *str, int len)
{
- const char * a = NULL;
+ 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;
+ 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);
+ PR_snprintf(str, len, "%s", a);
else
- PR_snprintf(str, len, "0x%p", keyType);
+ PR_snprintf(str, len, "0x%p", keyType);
}
-static void print_attr_value(CK_ATTRIBUTE_PTR attr)
+static void
+print_attr_value(CK_ATTRIBUTE_PTR attr)
{
char atype[48];
char valstr[49];
@@ -589,153 +607,154 @@ static void print_attr_value(CK_ATTRIBUTE_PTR attr)
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;
+ 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)
+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]);
+ for (i = 0; i < tlen; i++) {
+ print_attr_value(&templ[i]);
}
}
@@ -745,7 +764,10 @@ struct nssdbg_prof_str {
char *function;
};
-#define NSSDBG_DEFINE(func) { 0, 0, #func }
+#define NSSDBG_DEFINE(func) \
+ { \
+ 0, 0, #func \
+ }
struct nssdbg_prof_str nssdbg_prof_data[] = {
#define FUNC_C_INITIALIZE 0
@@ -794,7 +816,7 @@ struct nssdbg_prof_str nssdbg_prof_data[] = {
NSSDBG_DEFINE(C_CopyObject),
#define FUNC_C_DESTROYOBJECT 22
NSSDBG_DEFINE(C_DestroyObject),
-#define FUNC_C_GETOBJECTSIZE 23
+#define FUNC_C_GETOBJECTSIZE 23
NSSDBG_DEFINE(C_GetObjectSize),
#define FUNC_C_GETATTRIBUTEVALUE 24
NSSDBG_DEFINE(C_GetAttributeValue),
@@ -872,7 +894,7 @@ struct nssdbg_prof_str nssdbg_prof_data[] = {
NSSDBG_DEFINE(C_WrapKey),
#define FUNC_C_UNWRAPKEY 61
NSSDBG_DEFINE(C_UnWrapKey),
-#define FUNC_C_DERIVEKEY 62
+#define FUNC_C_DERIVEKEY 62
NSSDBG_DEFINE(C_DeriveKey),
#define FUNC_C_SEEDRANDOM 63
NSSDBG_DEFINE(C_SeedRandom),
@@ -886,105 +908,106 @@ struct nssdbg_prof_str nssdbg_prof_data[] = {
NSSDBG_DEFINE(C_WaitForSlotEvent)
};
-int nssdbg_prof_size = sizeof(nssdbg_prof_data)/sizeof(nssdbg_prof_data[0]);
-
+int nssdbg_prof_size = sizeof(nssdbg_prof_data) / sizeof(nssdbg_prof_data[0]);
-static void nssdbg_finish_time(PRInt32 fun_number, PRIntervalTime start)
+static void
+nssdbg_finish_time(PRInt32 fun_number, PRIntervalTime start)
{
PRIntervalTime ival;
PRIntervalTime end = PR_IntervalNow();
- ival = end-start;
+ 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)
+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; \
+ CK_RV rv; \
PRIntervalTime start
-CK_RV NSSDBGC_Initialize(
- CK_VOID_PTR pInitArgs
-)
+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);
+ nssdbg_start_time(FUNC_C_INITIALIZE, &start);
rv = module_functions->C_Initialize(pInitArgs);
- nssdbg_finish_time(FUNC_C_INITIALIZE,start);
+ nssdbg_finish_time(FUNC_C_INITIALIZE, start);
log_rv(rv);
return rv;
}
-CK_RV NSSDBGC_Finalize(
- CK_VOID_PTR pReserved
-)
+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);
+ nssdbg_start_time(FUNC_C_FINALIZE, &start);
rv = module_functions->C_Finalize(pReserved);
- nssdbg_finish_time(FUNC_C_FINALIZE,start);
+ nssdbg_finish_time(FUNC_C_FINALIZE, start);
log_rv(rv);
return rv;
}
-CK_RV NSSDBGC_GetInfo(
- CK_INFO_PTR pInfo
-)
+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);
+ nssdbg_start_time(FUNC_C_GETINFO, &start);
rv = module_functions->C_GetInfo(pInfo);
- nssdbg_finish_time(FUNC_C_GETINFO,start);
+ 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));
+ 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
-)
+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);
+ nssdbg_start_time(FUNC_C_GETFUNCITONLIST, &start);
rv = module_functions->C_GetFunctionList(ppFunctionList);
- nssdbg_finish_time(FUNC_C_GETFUNCITONLIST,start);
+ 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
-)
+CK_RV
+NSSDBGC_GetSlotList(
+ CK_BBOOL tokenPresent,
+ CK_SLOT_ID_PTR pSlotList,
+ CK_ULONG_PTR pulCount)
{
COMMON_DEFINITIONS;
@@ -993,96 +1016,96 @@ CK_RV NSSDBGC_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);
+ nssdbg_start_time(FUNC_C_GETSLOTLIST, &start);
rv = module_functions->C_GetSlotList(tokenPresent, pSlotList, pulCount);
- nssdbg_finish_time(FUNC_C_GETSLOTLIST,start);
+ 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]));
- }
+ 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
-)
+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);
+ nssdbg_start_time(FUNC_C_GETSLOTINFO, &start);
rv = module_functions->C_GetSlotInfo(slotID, pInfo);
- nssdbg_finish_time(FUNC_C_GETSLOTINFO,start);
+ 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));
+ 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
-)
+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);
+ nssdbg_start_time(FUNC_C_GETTOKENINFO, &start);
rv = module_functions->C_GetTokenInfo(slotID, pInfo);
- nssdbg_finish_time(FUNC_C_GETTOKENINFO,start);
+ 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));
+ 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
-)
+CK_RV
+NSSDBGC_GetMechanismList(
+ CK_SLOT_ID slotID,
+ CK_MECHANISM_TYPE_PTR pMechanismList,
+ CK_ULONG_PTR pulCount)
{
COMMON_DEFINITIONS;
@@ -1090,21 +1113,21 @@ CK_RV NSSDBGC_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);
+ nssdbg_start_time(FUNC_C_GETMECHANISMLIST, &start);
rv = module_functions->C_GetMechanismList(slotID,
- pMechanismList,
- pulCount);
- nssdbg_finish_time(FUNC_C_GETMECHANISMLIST,start);
+ 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
-)
+CK_RV
+NSSDBGC_GetMechanismInfo(
+ CK_SLOT_ID slotID,
+ CK_MECHANISM_TYPE type,
+ CK_MECHANISM_INFO_PTR pInfo)
{
COMMON_DEFINITIONS;
@@ -1112,21 +1135,21 @@ CK_RV NSSDBGC_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);
+ nssdbg_start_time(FUNC_C_GETMECHANISMINFO, &start);
rv = module_functions->C_GetMechanismInfo(slotID,
- type,
- pInfo);
- nssdbg_finish_time(FUNC_C_GETMECHANISMINFO,start);
+ 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
-)
+CK_RV
+NSSDBGC_InitToken(
+ CK_SLOT_ID slotID,
+ CK_CHAR_PTR pPin,
+ CK_ULONG ulPinLen,
+ CK_CHAR_PTR pLabel)
{
COMMON_DEFINITIONS;
@@ -1135,21 +1158,21 @@ CK_RV NSSDBGC_InitToken(
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);
+ nssdbg_start_time(FUNC_C_INITTOKEN, &start);
rv = module_functions->C_InitToken(slotID,
- pPin,
- ulPinLen,
- pLabel);
- nssdbg_finish_time(FUNC_C_INITTOKEN,start);
+ 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
-)
+CK_RV
+NSSDBGC_InitPIN(
+ CK_SESSION_HANDLE hSession,
+ CK_CHAR_PTR pPin,
+ CK_ULONG ulPinLen)
{
COMMON_DEFINITIONS;
@@ -1157,22 +1180,22 @@ CK_RV NSSDBGC_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);
+ nssdbg_start_time(FUNC_C_INITPIN, &start);
rv = module_functions->C_InitPIN(hSession,
- pPin,
- ulPinLen);
- nssdbg_finish_time(FUNC_C_INITPIN,start);
+ 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
-)
+CK_RV
+NSSDBGC_SetPIN(
+ CK_SESSION_HANDLE hSession,
+ CK_CHAR_PTR pOldPin,
+ CK_ULONG ulOldLen,
+ CK_CHAR_PTR pNewPin,
+ CK_ULONG ulNewLen)
{
COMMON_DEFINITIONS;
@@ -1182,13 +1205,13 @@ CK_RV NSSDBGC_SetPIN(
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);
+ nssdbg_start_time(FUNC_C_SETPIN, &start);
rv = module_functions->C_SetPIN(hSession,
- pOldPin,
- ulOldLen,
- pNewPin,
- ulNewLen);
- nssdbg_finish_time(FUNC_C_SETPIN,start);
+ pOldPin,
+ ulOldLen,
+ pNewPin,
+ ulNewLen);
+ nssdbg_finish_time(FUNC_C_SETPIN, start);
log_rv(rv);
return rv;
}
@@ -1196,13 +1219,13 @@ CK_RV NSSDBGC_SetPIN(
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
-)
+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;
@@ -1214,80 +1237,80 @@ CK_RV NSSDBGC_OpenSession(
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);
+ nssdbg_start_time(FUNC_C_OPENSESSION, &start);
rv = module_functions->C_OpenSession(slotID,
- flags,
- pApplication,
- Notify,
- phSession);
- nssdbg_finish_time(FUNC_C_OPENSESSION,start);
+ 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
-)
+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);
+ nssdbg_start_time(FUNC_C_CLOSESESSION, &start);
rv = module_functions->C_CloseSession(hSession);
- nssdbg_finish_time(FUNC_C_CLOSESESSION,start);
+ nssdbg_finish_time(FUNC_C_CLOSESESSION, start);
log_rv(rv);
return rv;
}
-CK_RV NSSDBGC_CloseAllSessions(
- CK_SLOT_ID slotID
-)
+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);
+ nssdbg_start_time(FUNC_C_CLOSEALLSESSIONS, &start);
rv = module_functions->C_CloseAllSessions(slotID);
- nssdbg_finish_time(FUNC_C_CLOSEALLSESSIONS,start);
+ 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
-)
+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);
+ nssdbg_start_time(FUNC_C_GETSESSIONINFO, &start);
rv = module_functions->C_GetSessionInfo(hSession,
- pInfo);
- nssdbg_finish_time(FUNC_C_GETSESSIONINFO,start);
+ 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));
+ 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
-)
+CK_RV
+NSSDBGC_GetOperationState(
+ CK_SESSION_HANDLE hSession,
+ CK_BYTE_PTR pOperationState,
+ CK_ULONG_PTR pulOperationStateLen)
{
COMMON_DEFINITIONS;
@@ -1295,23 +1318,23 @@ CK_RV NSSDBGC_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);
+ nssdbg_start_time(FUNC_C_GETOPERATIONSTATE, &start);
rv = module_functions->C_GetOperationState(hSession,
- pOperationState,
- pulOperationStateLen);
- nssdbg_finish_time(FUNC_C_GETOPERATIONSTATE,start);
+ 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
-)
+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;
@@ -1321,23 +1344,23 @@ CK_RV NSSDBGC_SetOperationState(
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);
+ nssdbg_start_time(FUNC_C_SETOPERATIONSTATE, &start);
rv = module_functions->C_SetOperationState(hSession,
- pOperationState,
- ulOperationStateLen,
- hEncryptionKey,
- hAuthenticationKey);
- nssdbg_finish_time(FUNC_C_SETOPERATIONSTATE,start);
+ 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
-)
+CK_RV
+NSSDBGC_Login(
+ CK_SESSION_HANDLE hSession,
+ CK_USER_TYPE userType,
+ CK_CHAR_PTR pPin,
+ CK_ULONG ulPinLen)
{
COMMON_DEFINITIONS;
@@ -1346,37 +1369,37 @@ CK_RV NSSDBGC_Login(
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);
+ nssdbg_start_time(FUNC_C_LOGIN, &start);
rv = module_functions->C_Login(hSession,
- userType,
- pPin,
- ulPinLen);
- nssdbg_finish_time(FUNC_C_LOGIN,start);
+ userType,
+ pPin,
+ ulPinLen);
+ nssdbg_finish_time(FUNC_C_LOGIN, start);
log_rv(rv);
return rv;
}
-CK_RV NSSDBGC_Logout(
- CK_SESSION_HANDLE hSession
-)
+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);
+ nssdbg_start_time(FUNC_C_LOGOUT, &start);
rv = module_functions->C_Logout(hSession);
- nssdbg_finish_time(FUNC_C_LOGOUT,start);
+ 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
-)
+CK_RV
+NSSDBGC_CreateObject(
+ CK_SESSION_HANDLE hSession,
+ CK_ATTRIBUTE_PTR pTemplate,
+ CK_ULONG ulCount,
+ CK_OBJECT_HANDLE_PTR phObject)
{
COMMON_DEFINITIONS;
@@ -1386,24 +1409,24 @@ CK_RV NSSDBGC_CreateObject(
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);
+ nssdbg_start_time(FUNC_C_CREATEOBJECT, &start);
rv = module_functions->C_CreateObject(hSession,
- pTemplate,
- ulCount,
- phObject);
- nssdbg_finish_time(FUNC_C_CREATEOBJECT,start);
+ 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
-)
+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;
@@ -1414,41 +1437,41 @@ CK_RV NSSDBGC_CopyObject(
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);
+ nssdbg_start_time(FUNC_C_COPYOBJECT, &start);
rv = module_functions->C_CopyObject(hSession,
- hObject,
- pTemplate,
- ulCount,
- phNewObject);
- nssdbg_finish_time(FUNC_C_COPYOBJECT,start);
+ 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
-)
+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);
+ nssdbg_start_time(FUNC_C_DESTROYOBJECT, &start);
rv = module_functions->C_DestroyObject(hSession,
- hObject);
- nssdbg_finish_time(FUNC_C_DESTROYOBJECT,start);
+ 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
-)
+CK_RV
+NSSDBGC_GetObjectSize(
+ CK_SESSION_HANDLE hSession,
+ CK_OBJECT_HANDLE hObject,
+ CK_ULONG_PTR pulSize)
{
COMMON_DEFINITIONS;
@@ -1456,22 +1479,22 @@ CK_RV NSSDBGC_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);
+ nssdbg_start_time(FUNC_C_GETOBJECTSIZE, &start);
rv = module_functions->C_GetObjectSize(hSession,
- hObject,
- pulSize);
- nssdbg_finish_time(FUNC_C_GETOBJECTSIZE,start);
+ 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
-)
+CK_RV
+NSSDBGC_GetAttributeValue(
+ CK_SESSION_HANDLE hSession,
+ CK_OBJECT_HANDLE hObject,
+ CK_ATTRIBUTE_PTR pTemplate,
+ CK_ULONG ulCount)
{
COMMON_DEFINITIONS;
@@ -1480,23 +1503,23 @@ CK_RV NSSDBGC_GetAttributeValue(
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);
+ nssdbg_start_time(FUNC_C_GETATTRIBUTEVALUE, &start);
rv = module_functions->C_GetAttributeValue(hSession,
- hObject,
- pTemplate,
- ulCount);
- nssdbg_finish_time(FUNC_C_GETATTRIBUTEVALUE,start);
+ 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
-)
+CK_RV
+NSSDBGC_SetAttributeValue(
+ CK_SESSION_HANDLE hSession,
+ CK_OBJECT_HANDLE hObject,
+ CK_ATTRIBUTE_PTR pTemplate,
+ CK_ULONG ulCount)
{
COMMON_DEFINITIONS;
@@ -1506,21 +1529,21 @@ CK_RV NSSDBGC_SetAttributeValue(
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);
+ nssdbg_start_time(FUNC_C_SETATTRIBUTEVALUE, &start);
rv = module_functions->C_SetAttributeValue(hSession,
- hObject,
- pTemplate,
- ulCount);
- nssdbg_finish_time(FUNC_C_SETATTRIBUTEVALUE,start);
+ 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
-)
+CK_RV
+NSSDBGC_FindObjectsInit(
+ CK_SESSION_HANDLE hSession,
+ CK_ATTRIBUTE_PTR pTemplate,
+ CK_ULONG ulCount)
{
COMMON_DEFINITIONS;
@@ -1529,21 +1552,21 @@ CK_RV NSSDBGC_FindObjectsInit(
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);
+ nssdbg_start_time(FUNC_C_FINDOBJECTSINIT, &start);
rv = module_functions->C_FindObjectsInit(hSession,
- pTemplate,
- ulCount);
- nssdbg_finish_time(FUNC_C_FINDOBJECTSINIT,start);
+ 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
-)
+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;
@@ -1553,41 +1576,41 @@ CK_RV NSSDBGC_FindObjects(
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);
+ nssdbg_start_time(FUNC_C_FINDOBJECTS, &start);
rv = module_functions->C_FindObjects(hSession,
- phObject,
- ulMaxObjectCount,
- pulObjectCount);
- nssdbg_finish_time(FUNC_C_FINDOBJECTS,start);
+ 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));
+ 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
-)
+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);
+ nssdbg_start_time(FUNC_C_FINDOBJECTSFINAL, &start);
rv = module_functions->C_FindObjectsFinal(hSession);
- nssdbg_finish_time(FUNC_C_FINDOBJECTSFINAL,start);
+ 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
-)
+CK_RV
+NSSDBGC_EncryptInit(
+ CK_SESSION_HANDLE hSession,
+ CK_MECHANISM_PTR pMechanism,
+ CK_OBJECT_HANDLE hKey)
{
COMMON_DEFINITIONS;
@@ -1596,22 +1619,22 @@ CK_RV NSSDBGC_EncryptInit(
PR_LOG(modlog, 3, (fmt_pMechanism, pMechanism));
log_handle(3, fmt_hKey, hKey);
print_mechanism(pMechanism);
- nssdbg_start_time(FUNC_C_ENCRYPTINIT,&start);
+ nssdbg_start_time(FUNC_C_ENCRYPTINIT, &start);
rv = module_functions->C_EncryptInit(hSession,
- pMechanism,
- hKey);
- nssdbg_finish_time(FUNC_C_ENCRYPTINIT,start);
+ 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
-)
+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;
@@ -1621,25 +1644,25 @@ CK_RV NSSDBGC_Encrypt(
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);
+ nssdbg_start_time(FUNC_C_ENCRYPT, &start);
rv = module_functions->C_Encrypt(hSession,
- pData,
- ulDataLen,
- pEncryptedData,
- pulEncryptedDataLen);
- nssdbg_finish_time(FUNC_C_ENCRYPT,start);
+ 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
-)
+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;
@@ -1649,23 +1672,23 @@ CK_RV NSSDBGC_EncryptUpdate(
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);
+ nssdbg_start_time(FUNC_C_ENCRYPTUPDATE, &start);
rv = module_functions->C_EncryptUpdate(hSession,
- pPart,
- ulPartLen,
- pEncryptedPart,
- pulEncryptedPartLen);
- nssdbg_finish_time(FUNC_C_ENCRYPTUPDATE,start);
+ 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
-)
+CK_RV
+NSSDBGC_EncryptFinal(
+ CK_SESSION_HANDLE hSession,
+ CK_BYTE_PTR pLastEncryptedPart,
+ CK_ULONG_PTR pulLastEncryptedPartLen)
{
COMMON_DEFINITIONS;
@@ -1673,21 +1696,21 @@ CK_RV NSSDBGC_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);
+ nssdbg_start_time(FUNC_C_ENCRYPTFINAL, &start);
rv = module_functions->C_EncryptFinal(hSession,
- pLastEncryptedPart,
- pulLastEncryptedPartLen);
- nssdbg_finish_time(FUNC_C_ENCRYPTFINAL,start);
+ 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
-)
+CK_RV
+NSSDBGC_DecryptInit(
+ CK_SESSION_HANDLE hSession,
+ CK_MECHANISM_PTR pMechanism,
+ CK_OBJECT_HANDLE hKey)
{
COMMON_DEFINITIONS;
@@ -1696,22 +1719,22 @@ CK_RV NSSDBGC_DecryptInit(
PR_LOG(modlog, 3, (fmt_pMechanism, pMechanism));
log_handle(3, fmt_hKey, hKey);
print_mechanism(pMechanism);
- nssdbg_start_time(FUNC_C_DECRYPTINIT,&start);
+ nssdbg_start_time(FUNC_C_DECRYPTINIT, &start);
rv = module_functions->C_DecryptInit(hSession,
- pMechanism,
- hKey);
- nssdbg_finish_time(FUNC_C_DECRYPTINIT,start);
+ 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
-)
+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;
@@ -1721,25 +1744,25 @@ CK_RV NSSDBGC_Decrypt(
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);
+ nssdbg_start_time(FUNC_C_DECRYPT, &start);
rv = module_functions->C_Decrypt(hSession,
- pEncryptedData,
- ulEncryptedDataLen,
- pData,
- pulDataLen);
- nssdbg_finish_time(FUNC_C_DECRYPT,start);
+ 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
-)
+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;
@@ -1749,23 +1772,23 @@ CK_RV NSSDBGC_DecryptUpdate(
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);
+ nssdbg_start_time(FUNC_C_DECRYPTUPDATE, &start);
rv = module_functions->C_DecryptUpdate(hSession,
- pEncryptedPart,
- ulEncryptedPartLen,
- pPart,
- pulPartLen);
- nssdbg_finish_time(FUNC_C_DECRYPTUPDATE,start);
+ 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
-)
+CK_RV
+NSSDBGC_DecryptFinal(
+ CK_SESSION_HANDLE hSession,
+ CK_BYTE_PTR pLastPart,
+ CK_ULONG_PTR pulLastPartLen)
{
COMMON_DEFINITIONS;
@@ -1773,20 +1796,20 @@ CK_RV NSSDBGC_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);
+ nssdbg_start_time(FUNC_C_DECRYPTFINAL, &start);
rv = module_functions->C_DecryptFinal(hSession,
- pLastPart,
- pulLastPartLen);
- nssdbg_finish_time(FUNC_C_DECRYPTFINAL,start);
+ 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
-)
+CK_RV
+NSSDBGC_DigestInit(
+ CK_SESSION_HANDLE hSession,
+ CK_MECHANISM_PTR pMechanism)
{
COMMON_DEFINITIONS;
@@ -1794,21 +1817,21 @@ CK_RV NSSDBGC_DigestInit(
log_handle(3, fmt_hSession, hSession);
PR_LOG(modlog, 3, (fmt_pMechanism, pMechanism));
print_mechanism(pMechanism);
- nssdbg_start_time(FUNC_C_DIGESTINIT,&start);
+ nssdbg_start_time(FUNC_C_DIGESTINIT, &start);
rv = module_functions->C_DigestInit(hSession,
- pMechanism);
- nssdbg_finish_time(FUNC_C_DIGESTINIT,start);
+ 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
-)
+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;
@@ -1818,23 +1841,23 @@ CK_RV NSSDBGC_Digest(
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);
+ nssdbg_start_time(FUNC_C_DIGEST, &start);
rv = module_functions->C_Digest(hSession,
- pData,
- ulDataLen,
- pDigest,
- pulDigestLen);
- nssdbg_finish_time(FUNC_C_DIGEST,start);
+ 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
-)
+CK_RV
+NSSDBGC_DigestUpdate(
+ CK_SESSION_HANDLE hSession,
+ CK_BYTE_PTR pPart,
+ CK_ULONG ulPartLen)
{
COMMON_DEFINITIONS;
@@ -1842,37 +1865,37 @@ CK_RV NSSDBGC_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);
+ nssdbg_start_time(FUNC_C_DIGESTUPDATE, &start);
rv = module_functions->C_DigestUpdate(hSession,
- pPart,
- ulPartLen);
- nssdbg_finish_time(FUNC_C_DIGESTUPDATE,start);
+ 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
-)
+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);
+ nssdbg_start_time(FUNC_C_DIGESTKEY, &start);
rv = module_functions->C_DigestKey(hSession,
- hKey);
- nssdbg_finish_time(FUNC_C_DIGESTKEY,start);
+ 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
-)
+CK_RV
+NSSDBGC_DigestFinal(
+ CK_SESSION_HANDLE hSession,
+ CK_BYTE_PTR pDigest,
+ CK_ULONG_PTR pulDigestLen)
{
COMMON_DEFINITIONS;
@@ -1880,21 +1903,21 @@ CK_RV NSSDBGC_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);
+ nssdbg_start_time(FUNC_C_DIGESTFINAL, &start);
rv = module_functions->C_DigestFinal(hSession,
- pDigest,
- pulDigestLen);
- nssdbg_finish_time(FUNC_C_DIGESTFINAL,start);
+ 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
-)
+CK_RV
+NSSDBGC_SignInit(
+ CK_SESSION_HANDLE hSession,
+ CK_MECHANISM_PTR pMechanism,
+ CK_OBJECT_HANDLE hKey)
{
COMMON_DEFINITIONS;
@@ -1903,22 +1926,22 @@ CK_RV NSSDBGC_SignInit(
PR_LOG(modlog, 3, (fmt_pMechanism, pMechanism));
log_handle(3, fmt_hKey, hKey);
print_mechanism(pMechanism);
- nssdbg_start_time(FUNC_C_SIGNINIT,&start);
+ nssdbg_start_time(FUNC_C_SIGNINIT, &start);
rv = module_functions->C_SignInit(hSession,
- pMechanism,
- hKey);
- nssdbg_finish_time(FUNC_C_SIGNINIT,start);
+ 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
-)
+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;
@@ -1928,23 +1951,23 @@ CK_RV NSSDBGC_Sign(
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);
+ nssdbg_start_time(FUNC_C_SIGN, &start);
rv = module_functions->C_Sign(hSession,
- pData,
- ulDataLen,
- pSignature,
- pulSignatureLen);
- nssdbg_finish_time(FUNC_C_SIGN,start);
+ 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
-)
+CK_RV
+NSSDBGC_SignUpdate(
+ CK_SESSION_HANDLE hSession,
+ CK_BYTE_PTR pPart,
+ CK_ULONG ulPartLen)
{
COMMON_DEFINITIONS;
@@ -1952,20 +1975,20 @@ CK_RV NSSDBGC_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);
+ nssdbg_start_time(FUNC_C_SIGNUPDATE, &start);
rv = module_functions->C_SignUpdate(hSession,
- pPart,
- ulPartLen);
- nssdbg_finish_time(FUNC_C_SIGNUPDATE,start);
+ 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
-)
+CK_RV
+NSSDBGC_SignFinal(
+ CK_SESSION_HANDLE hSession,
+ CK_BYTE_PTR pSignature,
+ CK_ULONG_PTR pulSignatureLen)
{
COMMON_DEFINITIONS;
@@ -1973,21 +1996,21 @@ CK_RV NSSDBGC_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);
+ nssdbg_start_time(FUNC_C_SIGNFINAL, &start);
rv = module_functions->C_SignFinal(hSession,
- pSignature,
- pulSignatureLen);
- nssdbg_finish_time(FUNC_C_SIGNFINAL,start);
+ 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
-)
+CK_RV
+NSSDBGC_SignRecoverInit(
+ CK_SESSION_HANDLE hSession,
+ CK_MECHANISM_PTR pMechanism,
+ CK_OBJECT_HANDLE hKey)
{
COMMON_DEFINITIONS;
@@ -1996,22 +2019,22 @@ CK_RV NSSDBGC_SignRecoverInit(
PR_LOG(modlog, 3, (fmt_pMechanism, pMechanism));
log_handle(3, fmt_hKey, hKey);
print_mechanism(pMechanism);
- nssdbg_start_time(FUNC_C_SIGNRECOVERINIT,&start);
+ nssdbg_start_time(FUNC_C_SIGNRECOVERINIT, &start);
rv = module_functions->C_SignRecoverInit(hSession,
- pMechanism,
- hKey);
- nssdbg_finish_time(FUNC_C_SIGNRECOVERINIT,start);
+ 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
-)
+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;
@@ -2021,23 +2044,23 @@ CK_RV NSSDBGC_SignRecover(
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);
+ nssdbg_start_time(FUNC_C_SIGNRECOVER, &start);
rv = module_functions->C_SignRecover(hSession,
- pData,
- ulDataLen,
- pSignature,
- pulSignatureLen);
- nssdbg_finish_time(FUNC_C_SIGNRECOVER,start);
+ 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
-)
+CK_RV
+NSSDBGC_VerifyInit(
+ CK_SESSION_HANDLE hSession,
+ CK_MECHANISM_PTR pMechanism,
+ CK_OBJECT_HANDLE hKey)
{
COMMON_DEFINITIONS;
@@ -2046,22 +2069,22 @@ CK_RV NSSDBGC_VerifyInit(
PR_LOG(modlog, 3, (fmt_pMechanism, pMechanism));
log_handle(3, fmt_hKey, hKey);
print_mechanism(pMechanism);
- nssdbg_start_time(FUNC_C_VERIFYINIT,&start);
+ nssdbg_start_time(FUNC_C_VERIFYINIT, &start);
rv = module_functions->C_VerifyInit(hSession,
- pMechanism,
- hKey);
- nssdbg_finish_time(FUNC_C_VERIFYINIT,start);
+ 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
-)
+CK_RV
+NSSDBGC_Verify(
+ CK_SESSION_HANDLE hSession,
+ CK_BYTE_PTR pData,
+ CK_ULONG ulDataLen,
+ CK_BYTE_PTR pSignature,
+ CK_ULONG ulSignatureLen)
{
COMMON_DEFINITIONS;
@@ -2071,22 +2094,22 @@ CK_RV NSSDBGC_Verify(
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);
+ nssdbg_start_time(FUNC_C_VERIFY, &start);
rv = module_functions->C_Verify(hSession,
- pData,
- ulDataLen,
- pSignature,
- ulSignatureLen);
- nssdbg_finish_time(FUNC_C_VERIFY,start);
+ 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
-)
+CK_RV
+NSSDBGC_VerifyUpdate(
+ CK_SESSION_HANDLE hSession,
+ CK_BYTE_PTR pPart,
+ CK_ULONG ulPartLen)
{
COMMON_DEFINITIONS;
@@ -2094,20 +2117,20 @@ CK_RV NSSDBGC_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);
+ nssdbg_start_time(FUNC_C_VERIFYUPDATE, &start);
rv = module_functions->C_VerifyUpdate(hSession,
- pPart,
- ulPartLen);
- nssdbg_finish_time(FUNC_C_VERIFYUPDATE,start);
+ 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
-)
+CK_RV
+NSSDBGC_VerifyFinal(
+ CK_SESSION_HANDLE hSession,
+ CK_BYTE_PTR pSignature,
+ CK_ULONG ulSignatureLen)
{
COMMON_DEFINITIONS;
@@ -2115,20 +2138,20 @@ CK_RV NSSDBGC_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);
+ nssdbg_start_time(FUNC_C_VERIFYFINAL, &start);
rv = module_functions->C_VerifyFinal(hSession,
- pSignature,
- ulSignatureLen);
- nssdbg_finish_time(FUNC_C_VERIFYFINAL,start);
+ 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
-)
+CK_RV
+NSSDBGC_VerifyRecoverInit(
+ CK_SESSION_HANDLE hSession,
+ CK_MECHANISM_PTR pMechanism,
+ CK_OBJECT_HANDLE hKey)
{
COMMON_DEFINITIONS;
@@ -2137,22 +2160,22 @@ CK_RV NSSDBGC_VerifyRecoverInit(
PR_LOG(modlog, 3, (fmt_pMechanism, pMechanism));
log_handle(3, fmt_hKey, hKey);
print_mechanism(pMechanism);
- nssdbg_start_time(FUNC_C_VERIFYRECOVERINIT,&start);
+ nssdbg_start_time(FUNC_C_VERIFYRECOVERINIT, &start);
rv = module_functions->C_VerifyRecoverInit(hSession,
- pMechanism,
- hKey);
- nssdbg_finish_time(FUNC_C_VERIFYRECOVERINIT,start);
+ 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
-)
+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;
@@ -2162,25 +2185,25 @@ CK_RV NSSDBGC_VerifyRecover(
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);
+ nssdbg_start_time(FUNC_C_VERIFYRECOVER, &start);
rv = module_functions->C_VerifyRecover(hSession,
- pSignature,
- ulSignatureLen,
- pData,
- pulDataLen);
- nssdbg_finish_time(FUNC_C_VERIFYRECOVER,start);
+ 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
-)
+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;
@@ -2190,25 +2213,25 @@ CK_RV NSSDBGC_DigestEncryptUpdate(
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);
+ nssdbg_start_time(FUNC_C_DIGESTENCRYPTUPDATE, &start);
rv = module_functions->C_DigestEncryptUpdate(hSession,
- pPart,
- ulPartLen,
- pEncryptedPart,
- pulEncryptedPartLen);
- nssdbg_finish_time(FUNC_C_DIGESTENCRYPTUPDATE,start);
+ 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
-)
+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;
@@ -2218,25 +2241,25 @@ CK_RV NSSDBGC_DecryptDigestUpdate(
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);
+ nssdbg_start_time(FUNC_C_DECRYPTDIGESTUPDATE, &start);
rv = module_functions->C_DecryptDigestUpdate(hSession,
- pEncryptedPart,
- ulEncryptedPartLen,
- pPart,
- pulPartLen);
- nssdbg_finish_time(FUNC_C_DECRYPTDIGESTUPDATE,start);
+ 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
-)
+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;
@@ -2246,25 +2269,25 @@ CK_RV NSSDBGC_SignEncryptUpdate(
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);
+ nssdbg_start_time(FUNC_C_SIGNENCRYPTUPDATE, &start);
rv = module_functions->C_SignEncryptUpdate(hSession,
- pPart,
- ulPartLen,
- pEncryptedPart,
- pulEncryptedPartLen);
- nssdbg_finish_time(FUNC_C_SIGNENCRYPTUPDATE,start);
+ 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
-)
+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;
@@ -2274,25 +2297,25 @@ CK_RV NSSDBGC_DecryptVerifyUpdate(
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);
+ nssdbg_start_time(FUNC_C_DECRYPTVERIFYUPDATE, &start);
rv = module_functions->C_DecryptVerifyUpdate(hSession,
- pEncryptedPart,
- ulEncryptedPartLen,
- pPart,
- pulPartLen);
- nssdbg_finish_time(FUNC_C_DECRYPTVERIFYUPDATE,start);
+ 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
-)
+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;
@@ -2304,28 +2327,28 @@ CK_RV NSSDBGC_GenerateKey(
PR_LOG(modlog, 3, (fmt_phKey, phKey));
print_template(pTemplate, ulCount);
print_mechanism(pMechanism);
- nssdbg_start_time(FUNC_C_GENERATEKEY,&start);
+ nssdbg_start_time(FUNC_C_GENERATEKEY, &start);
rv = module_functions->C_GenerateKey(hSession,
- pMechanism,
- pTemplate,
- ulCount,
- phKey);
- nssdbg_finish_time(FUNC_C_GENERATEKEY,start);
+ 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
-)
+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;
@@ -2341,30 +2364,30 @@ CK_RV NSSDBGC_GenerateKeyPair(
PR_LOG(modlog, 3, (" phPrivateKey = 0x%p", phPrivateKey));
print_template(pPrivateKeyTemplate, ulPrivateKeyAttributeCount);
print_mechanism(pMechanism);
- nssdbg_start_time(FUNC_C_GENERATEKEYPAIR,&start);
+ 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);
+ 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
-)
+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;
@@ -2376,29 +2399,29 @@ CK_RV NSSDBGC_WrapKey(
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);
+ 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);
+ 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
-)
+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;
@@ -2413,29 +2436,29 @@ CK_RV NSSDBGC_UnwrapKey(
PR_LOG(modlog, 3, (fmt_phKey, phKey));
print_template(pTemplate, ulAttributeCount);
print_mechanism(pMechanism);
- nssdbg_start_time(FUNC_C_UNWRAPKEY,&start);
+ 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);
+ 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
-)
+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;
@@ -2448,24 +2471,24 @@ CK_RV NSSDBGC_DeriveKey(
PR_LOG(modlog, 3, (fmt_phKey, phKey));
print_template(pTemplate, ulAttributeCount);
print_mechanism(pMechanism);
- nssdbg_start_time(FUNC_C_DERIVEKEY,&start);
+ 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);
+ 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
-)
+CK_RV
+NSSDBGC_SeedRandom(
+ CK_SESSION_HANDLE hSession,
+ CK_BYTE_PTR pSeed,
+ CK_ULONG ulSeedLen)
{
COMMON_DEFINITIONS;
@@ -2473,20 +2496,20 @@ CK_RV NSSDBGC_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);
+ nssdbg_start_time(FUNC_C_SEEDRANDOM, &start);
rv = module_functions->C_SeedRandom(hSession,
- pSeed,
- ulSeedLen);
- nssdbg_finish_time(FUNC_C_SEEDRANDOM,start);
+ 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
-)
+CK_RV
+NSSDBGC_GenerateRandom(
+ CK_SESSION_HANDLE hSession,
+ CK_BYTE_PTR RandomData,
+ CK_ULONG ulRandomLen)
{
COMMON_DEFINITIONS;
@@ -2494,50 +2517,50 @@ CK_RV NSSDBGC_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);
+ nssdbg_start_time(FUNC_C_GENERATERANDOM, &start);
rv = module_functions->C_GenerateRandom(hSession,
- RandomData,
- ulRandomLen);
- nssdbg_finish_time(FUNC_C_GENERATERANDOM,start);
+ RandomData,
+ ulRandomLen);
+ nssdbg_finish_time(FUNC_C_GENERATERANDOM, start);
log_rv(rv);
return rv;
}
-CK_RV NSSDBGC_GetFunctionStatus(
- CK_SESSION_HANDLE hSession
-)
+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);
+ nssdbg_start_time(FUNC_C_GETFUNCTIONSTATUS, &start);
rv = module_functions->C_GetFunctionStatus(hSession);
- nssdbg_finish_time(FUNC_C_GETFUNCTIONSTATUS,start);
+ nssdbg_finish_time(FUNC_C_GETFUNCTIONSTATUS, start);
log_rv(rv);
return rv;
}
-CK_RV NSSDBGC_CancelFunction(
- CK_SESSION_HANDLE hSession
-)
+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);
+ nssdbg_start_time(FUNC_C_CANCELFUNCTION, &start);
rv = module_functions->C_CancelFunction(hSession);
- nssdbg_finish_time(FUNC_C_CANCELFUNCTION,start);
+ 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
-)
+CK_RV
+NSSDBGC_WaitForSlotEvent(
+ CK_FLAGS flags,
+ CK_SLOT_ID_PTR pSlot,
+ CK_VOID_PTR pRserved)
{
COMMON_DEFINITIONS;
@@ -2545,18 +2568,18 @@ CK_RV NSSDBGC_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);
+ nssdbg_start_time(FUNC_C_WAITFORSLOTEVENT, &start);
rv = module_functions->C_WaitForSlotEvent(flags,
- pSlot,
- pRserved);
- nssdbg_finish_time(FUNC_C_WAITFORSLOTEVENT,start);
+ 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
-)
+CK_FUNCTION_LIST_PTR
+nss_InsertDeviceLog(
+ CK_FUNCTION_LIST_PTR devEPV)
{
module_functions = devEPV;
modlog = PR_NewLogModule("nss_mod_log");
@@ -2644,38 +2667,40 @@ CK_FUNCTION_LIST_PTR nss_InsertDeviceLog(
* 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)
+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;
@@ -2685,53 +2710,51 @@ static void print_final_statistics(void)
FILE *outfile = NULL;
int i;
- fname = PR_GetEnv("NSS_OUTPUT_FILE");
+ fname = PR_GetEnvSecure("NSS_OUTPUT_FILE");
if (fname) {
- /* need to add an optional process id to the filename */
- outfile = fopen(fname,"w+");
+ /* need to add an optional process id to the filename */
+ outfile = fopen(fname, "w+");
}
if (!outfile) {
- outfile = stdout;
+ 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;
+
+ 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");
+ 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");
+ fprintf(outfile, "\n");
- pr_total_time = getPrintTime(total_time,&type);
+ 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);
+ 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);
+ fclose(outfile);
}
}
-
diff --git a/nss/lib/pk11wrap/dev3hack.c b/nss/lib/pk11wrap/dev3hack.c
index c1fe55c..27325a5 100644
--- a/nss/lib/pk11wrap/dev3hack.c
+++ b/nss/lib/pk11wrap/dev3hack.c
@@ -24,45 +24,43 @@
NSS_IMPLEMENT nssSession *
nssSession_ImportNSS3Session(NSSArena *arenaOpt,
- CK_SESSION_HANDLE session,
+ 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;
- }
+ 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
-)
+nssSlot_CreateSession(
+ NSSSlot *slot,
+ NSSArena *arenaOpt,
+ PRBool readWrite)
{
nssSession *rvSession;
if (!readWrite) {
- /* nss3hack version only returns rw swssions */
- return NULL;
+ /* nss3hack version only returns rw swssions */
+ return NULL;
}
rvSession = nss_ZNEW(arenaOpt, nssSession);
if (!rvSession) {
- return (nssSession *)NULL;
+ return (nssSession *)NULL;
}
rvSession->handle = PK11_GetRWSession(slot->pk11slot);
if (rvSession->handle == CK_INVALID_HANDLE) {
- nss_ZFreeIf(rvSession);
- return NULL;
+ nss_ZFreeIf(rvSession);
+ return NULL;
}
rvSession->isRW = PR_TRUE;
rvSession->slot = slot;
@@ -87,17 +85,14 @@ nssSlot_CreateSession
}
NSS_IMPLEMENT PRStatus
-nssSession_Destroy
-(
- nssSession *s
-)
+nssSession_Destroy(nssSession *s)
{
PRStatus rv = PR_SUCCESS;
if (s) {
- if (s->isRW) {
- PK11_RestoreROSession(s->slot->pk11slot, s->handle);
- }
- rv = nss_ZFreeIf(s);
+ if (s->isRW) {
+ PK11_RestoreROSession(s->slot->pk11slot, s->handle);
+ }
+ rv = nss_ZFreeIf(s);
}
return rv;
}
@@ -109,12 +104,12 @@ nssSlot_CreateFromPK11SlotInfo(NSSTrustDomain *td, PK11SlotInfo *nss3slot)
NSSArena *arena;
arena = nssArena_Create();
if (!arena) {
- return NULL;
+ return NULL;
}
rvSlot = nss_ZNEW(arena, NSSSlot);
if (!rvSlot) {
- nssArena_Destroy(arena);
- return NULL;
+ nssArena_Destroy(arena);
+ return NULL;
}
rvSlot->base.refCount = 1;
rvSlot->base.lock = PZ_NewLock(nssILockOther);
@@ -123,7 +118,7 @@ nssSlot_CreateFromPK11SlotInfo(NSSTrustDomain *td, PK11SlotInfo *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->base.name = nssUTF8_Duplicate(nss3slot->slot_name, td->arena);
rvSlot->lock = (nss3slot->isThreadSafe) ? NULL : nss3slot->sessionLock;
return rvSlot;
}
@@ -136,53 +131,53 @@ nssToken_CreateFromPK11SlotInfo(NSSTrustDomain *td, PK11SlotInfo *nss3slot)
/* Don't create a token object for a disabled slot */
if (nss3slot->disabled) {
- PORT_SetError(SEC_ERROR_NO_TOKEN);
- return NULL;
+ PORT_SetError(SEC_ERROR_NO_TOKEN);
+ return NULL;
}
arena = nssArena_Create();
if (!arena) {
- return NULL;
+ return NULL;
}
rvToken = nss_ZNEW(arena, NSSToken);
if (!rvToken) {
- nssArena_Destroy(arena);
- return NULL;
+ nssArena_Destroy(arena);
+ return NULL;
}
rvToken->base.refCount = 1;
rvToken->base.lock = PZ_NewLock(nssILockOther);
if (!rvToken->base.lock) {
- nssArena_Destroy(arena);
- return NULL;
+ 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);
+ 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;
+ 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->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->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;
+ rvToken->defaultSession->slot = rvToken->slot;
return rvToken;
loser:
PZ_DestroyLock(rvToken->base.lock);
@@ -194,25 +189,19 @@ NSS_IMPLEMENT void
nssToken_UpdateName(NSSToken *token)
{
if (!token) {
- return;
+ return;
}
- token->base.name = nssUTF8_Duplicate(token->pk11slot->token_name,token->base.arena);
+ token->base.name = nssUTF8_Duplicate(token->pk11slot->token_name, token->base.arena);
}
NSS_IMPLEMENT PRBool
-nssSlot_IsPermanent
-(
- NSSSlot *slot
-)
+nssSlot_IsPermanent(NSSSlot *slot)
{
return slot->pk11slot->isPerm;
}
NSS_IMPLEMENT PRBool
-nssSlot_IsFriendly
-(
- NSSSlot *slot
-)
+nssSlot_IsFriendly(NSSSlot *slot)
{
return PK11_IsFriendly(slot->pk11slot);
}
@@ -223,43 +212,37 @@ nssToken_Refresh(NSSToken *token)
PK11SlotInfo *nss3slot;
if (!token) {
- return PR_SUCCESS;
+ return PR_SUCCESS;
}
nss3slot = token->pk11slot;
- token->defaultSession =
- nssSession_ImportNSS3Session(token->slot->base.arena,
- nss3slot->session,
- nss3slot->sessionLock,
- nss3slot->defRWSession);
+ 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
-)
+nssSlot_Refresh(NSSSlot *slot)
{
PK11SlotInfo *nss3slot = slot->pk11slot;
PRBool doit = PR_FALSE;
if (slot->token && slot->token->base.name[0] == 0) {
- doit = PR_TRUE;
+ doit = PR_TRUE;
}
if (PK11_InitToken(nss3slot, PR_FALSE) != SECSuccess) {
- return PR_FAILURE;
+ return PR_FAILURE;
}
if (doit) {
- nssTrustDomain_UpdateCachedTokenCerts(slot->token->trustDomain,
- slot->token);
+ nssTrustDomain_UpdateCachedTokenCerts(slot->token->trustDomain,
+ slot->token);
}
return nssToken_Refresh(slot->token);
}
NSS_IMPLEMENT PRStatus
-nssToken_GetTrustOrder
-(
- NSSToken *tok
-)
+nssToken_GetTrustOrder(NSSToken *tok)
{
PK11SlotInfo *slot;
SECMODModule *module;
@@ -269,18 +252,14 @@ nssToken_GetTrustOrder
}
NSS_IMPLEMENT PRBool
-nssSlot_IsLoggedIn
-(
- NSSSlot *slot
-)
+nssSlot_IsLoggedIn(NSSSlot *slot)
{
if (!slot->pk11slot->needLogin) {
- return PR_TRUE;
+ return PR_TRUE;
}
return PK11_IsLoggedIn(slot->pk11slot, NULL);
}
-
NSSTrustDomain *
nssToken_GetTrustDomain(NSSToken *token)
{
@@ -288,18 +267,13 @@ nssToken_GetTrustDomain(NSSToken *token)
}
NSS_EXTERN PRStatus
-nssTrustDomain_RemoveTokenCertsFromCache
-(
- NSSTrustDomain *td,
- NSSToken *token
-);
+nssTrustDomain_RemoveTokenCertsFromCache(
+ NSSTrustDomain *td,
+ NSSToken *token);
NSS_IMPLEMENT PRStatus
-nssToken_NotifyCertsNotVisible
-(
- NSSToken *tok
-)
+nssToken_NotifyCertsNotVisible(
+ NSSToken *tok)
{
return nssTrustDomain_RemoveTokenCertsFromCache(tok->trustDomain, tok);
}
-
diff --git a/nss/lib/pk11wrap/dev3hack.h b/nss/lib/pk11wrap/dev3hack.h
index 6b4f8de..6105259 100644
--- a/nss/lib/pk11wrap/dev3hack.h
+++ b/nss/lib/pk11wrap/dev3hack.h
@@ -23,7 +23,7 @@ nssToken_GetTrustDomain(NSSToken *token);
void PK11Slot_SetNSSToken(PK11SlotInfo *sl, NSSToken *nsst);
-NSSToken * PK11Slot_GetNSSToken(PK11SlotInfo *sl);
+NSSToken *PK11Slot_GetNSSToken(PK11SlotInfo *sl);
PR_END_EXTERN_C
diff --git a/nss/lib/pk11wrap/exports.gyp b/nss/lib/pk11wrap/exports.gyp
new file mode 100644
index 0000000..b3d4bf4
--- /dev/null
+++ b/nss/lib/pk11wrap/exports.gyp
@@ -0,0 +1,39 @@
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+{
+ 'includes': [
+ '../../coreconf/config.gypi'
+ ],
+ 'targets': [
+ {
+ 'target_name': 'lib_pk11wrap_exports',
+ 'type': 'none',
+ 'copies': [
+ {
+ 'files': [
+ 'pk11func.h',
+ 'pk11pqg.h',
+ 'pk11priv.h',
+ 'pk11pub.h',
+ 'pk11sdr.h',
+ 'secmod.h',
+ 'secmodt.h',
+ 'secpkcs5.h'
+ ],
+ 'destination': '<(nss_public_dist_dir)/<(module)'
+ },
+ {
+ 'files': [
+ 'dev3hack.h',
+ 'secmodi.h'
+ ],
+ 'destination': '<(nss_private_dist_dir)/<(module)'
+ }
+ ]
+ }
+ ],
+ 'variables': {
+ 'module': 'nss'
+ }
+}
diff --git a/nss/lib/pk11wrap/pk11akey.c b/nss/lib/pk11wrap/pk11akey.c
index b0604de..d086ed4 100644
--- a/nss/lib/pk11wrap/pk11akey.c
+++ b/nss/lib/pk11wrap/pk11akey.c
@@ -14,53 +14,54 @@
#include "pk11func.h"
#include "cert.h"
#include "key.h"
+#include "keyi.h"
#include "secitem.h"
-#include "secasn1.h"
-#include "secoid.h"
+#include "secasn1.h"
+#include "secoid.h"
#include "secerr.h"
#include "sechash.h"
-#include "secpkcs5.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;
+ 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;
+ 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
+ * 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)
+PK11_ImportPublicKey(PK11SlotInfo *slot, SECKEYPublicKey *pubKey,
+ PRBool isToken)
{
CK_BBOOL cktrue = CK_TRUE;
CK_BBOOL ckfalse = CK_FALSE;
@@ -78,139 +79,167 @@ PK11_ImportPublicKey(PK11SlotInfo *slot, SECKEYPublicKey *pubKey,
/* if we already have an object in the desired slot, use it */
if (!isToken && pubKey->pkcs11Slot == slot) {
- return pubKey->pkcs11ID;
+ 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++;
+ 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++;
+ 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++;
+ 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);
- }
+ 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_GetEnvSecure("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;
- }
+ 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;
@@ -229,22 +258,21 @@ pk11_Attr2SecItem(PLArenaPool *arena, const CK_ATTRIBUTE *attr, SECItem *item)
(void)SECITEM_AllocItem(arena, item, attr->ulValueLen);
if (item->data == NULL) {
- return CKR_HOST_MEMORY;
- }
+ 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
+ * 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.
+ * 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
@@ -253,127 +281,133 @@ pk11_Attr2SecItem(PLArenaPool *arena, const CK_ATTRIBUTE *attr, SECItem *item)
* Point length = (Roundup(curveLenInBits/8)*2+1)
*/
static int
-pk11_get_EC_PointLenInBytes(PLArenaPool *arena, const SECItem *ecParams)
+pk11_get_EC_PointLenInBytes(PLArenaPool *arena, const SECItem *ecParams,
+ PRBool *plain)
{
- 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;
+ 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;
+ }
+
+ *plain = PR_FALSE;
+ 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 */
+ case SEC_OID_CURVE25519:
+ *plain = PR_TRUE;
+ return 32; /* curve len in bytes = 32 bytes (only X) */
+ /* 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
+ * 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
+ * is first decoded and returned. Space for the point is allocated out of
* the passed in arena.
*/
static CK_RV
pk11_get_Decoded_ECPoint(PLArenaPool *arena, const SECItem *ecParams,
- const CK_ATTRIBUTE *ecPoint, SECItem *publicKeyValue)
+ const CK_ATTRIBUTE *ecPoint, SECItem *publicKeyValue)
{
SECItem encodedPublicValue;
SECStatus rv;
int keyLen;
+ PRBool plain = PR_FALSE;
if (ecPoint->ulValueLen == 0) {
- return CKR_ATTRIBUTE_VALUE_INVALID;
+ return CKR_ATTRIBUTE_VALUE_INVALID;
}
/*
@@ -381,7 +415,7 @@ pk11_get_Decoded_ECPoint(PLArenaPool *arena, const SECItem *ecParams,
* 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
+ * 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.
*/
@@ -393,134 +427,140 @@ pk11_get_Decoded_ECPoint(PLArenaPool *arena, const SECItem *ecParams,
* encoded or not heuristically. If the ecParams are invalid, it
* will return -1 for the keyLen.
*/
- keyLen = pk11_get_EC_PointLenInBytes(arena, ecParams);
+ keyLen = pk11_get_EC_PointLenInBytes(arena, ecParams, &plain);
if (keyLen < 0) {
- return CKR_ATTRIBUTE_VALUE_INVALID;
+ return CKR_ATTRIBUTE_VALUE_INVALID;
}
+ /*
+ * Some curves are not encoded but we don't have the name here.
+ * Instead, pk11_get_EC_PointLenInBytes returns true plain if this is the
+ * case.
+ */
+ if (plain && ecPoint->ulValueLen == (unsigned int)keyLen) {
+ return pk11_Attr2SecItem(arena, ecPoint, publicKeyValue);
+ }
/* 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 == (unsigned int)keyLen)) {
- return pk11_Attr2SecItem(arena, ecPoint, publicKeyValue);
+ if ((*((char *)ecPoint->pValue) == EC_POINT_FORM_UNCOMPRESSED) &&
+ (ecPoint->ulValueLen == (unsigned int)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. */
+ /* 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 == (unsigned int)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;
+ 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
@@ -528,13 +568,13 @@ pk11_get_Decoded_ECPoint(PLArenaPool *arena, const SECItem *ecParams,
* 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
+ * 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;
}
@@ -542,7 +582,7 @@ pk11_get_Decoded_ECPoint(PLArenaPool *arena, const SECItem *ecParams,
* extract a public key from a slot and id
*/
SECKEYPublicKey *
-PK11_ExtractPublicKey(PK11SlotInfo *slot,KeyType keyType,CK_OBJECT_HANDLE id)
+PK11_ExtractPublicKey(PK11SlotInfo *slot, KeyType keyType, CK_OBJECT_HANDLE id)
{
CK_OBJECT_CLASS keyClass = CKO_PUBLIC_KEY;
PLArenaPool *arena;
@@ -552,171 +592,200 @@ PK11_ExtractPublicKey(PK11SlotInfo *slot,KeyType keyType,CK_OBJECT_HANDLE id)
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 *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;
- }
- }
+ 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);
+ 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;
+ PORT_FreeArena(arena, PR_FALSE);
+ return NULL;
}
-
- pubKey = (SECKEYPublicKey *)
- PORT_ArenaZAlloc(arena, sizeof(SECKEYPublicKey));
+ pubKey = (SECKEYPublicKey *)
+ PORT_ArenaZAlloc(arena, sizeof(SECKEYPublicKey));
if (pubKey == NULL) {
- PORT_FreeArena (arena, PR_FALSE);
- PORT_FreeArena (tmp_arena, PR_FALSE);
- return 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++;
+ 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);
+ 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);
+ if (seckey_SetPointEncoding(arena, pubKey) != SECSuccess) {
+ crv |= CKR_GENERAL_ERROR;
+ }
+ 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;
+ PORT_FreeArena(arena, PR_FALSE);
+ PK11_FreeSlot(slot);
+ PORT_SetError(PK11_MapError(crv));
+ return NULL;
}
return pubKey;
@@ -726,8 +795,8 @@ PK11_ExtractPublicKey(PK11SlotInfo *slot,KeyType keyType,CK_OBJECT_HANDLE id)
* 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)
+PK11_MakePrivKey(PK11SlotInfo *slot, KeyType keyType,
+ PRBool isTemp, CK_OBJECT_HANDLE privID, void *wincx)
{
PLArenaPool *arena;
SECKEYPrivateKey *privKey;
@@ -736,40 +805,51 @@ PK11_MakePrivKey(PK11SlotInfo *slot, KeyType keyType,
/* 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;
- }
+ 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);
+ isPrivate = (PRBool)PK11_HasAttributeSet(slot, privID, CKA_PRIVATE, PR_FALSE);
if (isPrivate) {
- rv = PK11_Authenticate(slot, PR_TRUE, wincx);
- if (rv != SECSuccess) {
- return NULL;
- }
+ 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;
+ arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
+ if (arena == NULL)
+ return NULL;
- privKey = (SECKEYPrivateKey *)
- PORT_ArenaZAlloc(arena, sizeof(SECKEYPrivateKey));
+ privKey = (SECKEYPrivateKey *)
+ PORT_ArenaZAlloc(arena, sizeof(SECKEYPrivateKey));
if (privKey == NULL) {
- PORT_FreeArena(arena, PR_FALSE);
- return NULL;
+ PORT_FreeArena(arena, PR_FALSE);
+ return NULL;
}
privKey->arena = arena;
@@ -782,7 +862,6 @@ PK11_MakePrivKey(PK11SlotInfo *slot, KeyType keyType,
return privKey;
}
-
PK11SlotInfo *
PK11_GetSlotFromPrivateKey(SECKEYPrivateKey *key)
{
@@ -803,34 +882,31 @@ PK11_GetPrivateModulusLen(SECKEYPrivateKey *key)
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;
+ 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--;
+ }
+ 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 );
+ 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.
@@ -838,43 +914,43 @@ PK11_GetPrivateModulusLen(SECKEYPrivateKey *key)
* result into another.
*/
static SECKEYPrivateKey *
-pk11_loadPrivKeyWithFlags(PK11SlotInfo *slot,SECKEYPrivateKey *privKey,
- SECKEYPublicKey *pubKey, PK11AttrFlags attrFlags)
+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 */
+ { 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]);
+ const int templateSize = sizeof(privTemplate) / sizeof(privTemplate[0]);
PLArenaPool *arena;
CK_OBJECT_HANDLE objectID;
int i, count = 0;
@@ -884,120 +960,160 @@ pk11_loadPrivKeyWithFlags(PK11SlotInfo *slot,SECKEYPrivateKey *privKey,
PRBool token = ((attrFlags & PK11_ATTR_TOKEN) != 0);
if (pk11_BadAttrFlags(attrFlags)) {
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- return NULL;
+ 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;
- }
+ 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;
+ 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;
- /*
+ 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
+ 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);
+ 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)
+pk11_loadPrivKey(PK11SlotInfo *slot, SECKEYPrivateKey *privKey,
+ SECKEYPublicKey *pubKey, PRBool token, PRBool sensitive)
{
PK11AttrFlags attrFlags = 0;
if (token) {
- attrFlags |= (PK11_ATTR_TOKEN | PK11_ATTR_PRIVATE);
+ attrFlags |= (PK11_ATTR_TOKEN | PK11_ATTR_PRIVATE);
} else {
- attrFlags |= (PK11_ATTR_SESSION | PK11_ATTR_PUBLIC);
+ attrFlags |= (PK11_ATTR_SESSION | PK11_ATTR_PUBLIC);
}
if (sensitive) {
- attrFlags |= PK11_ATTR_SENSITIVE;
+ attrFlags |= PK11_ATTR_SENSITIVE;
} else {
- attrFlags |= PK11_ATTR_INSENSITIVE;
+ attrFlags |= PK11_ATTR_INSENSITIVE;
}
return pk11_loadPrivKeyWithFlags(slot, privKey, pubKey, attrFlags);
}
@@ -1006,20 +1122,19 @@ pk11_loadPrivKey(PK11SlotInfo *slot,SECKEYPrivateKey *privKey,
* export this for PSM
*/
SECKEYPrivateKey *
-PK11_LoadPrivKey(PK11SlotInfo *slot,SECKEYPrivateKey *privKey,
- SECKEYPublicKey *pubKey, PRBool token, PRBool sensitive)
+PK11_LoadPrivKey(PK11SlotInfo *slot, SECKEYPrivateKey *privKey,
+ SECKEYPublicKey *pubKey, PRBool token, PRBool sensitive)
{
- return pk11_loadPrivKey(slot,privKey,pubKey,token,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)
+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
@@ -1029,61 +1144,61 @@ PK11_GenerateKeyPairWithOpFlags(PK11SlotInfo *slot,CK_MECHANISM_TYPE type,
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},
+ { 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},
+ { 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},
+ { 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},
+ { 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},
+ { 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;
+ SECKEYECParams *ecParams;
/*CK_ULONG key_size = 0;*/
CK_ATTRIBUTE *pubTemplate;
@@ -1091,17 +1206,17 @@ PK11_GenerateKeyPairWithOpFlags(PK11SlotInfo *slot,CK_MECHANISM_TYPE type,
int pubCount = 0;
PK11RSAGenParams *rsaParams;
SECKEYPQGParams *dsaParams;
- SECKEYDHParams * dhParams;
+ 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;
+ CK_OBJECT_HANDLE privID, pubID;
SECKEYPrivateKey *privKey;
KeyType keyType;
PRBool restore;
- int peCount,i;
+ int peCount, i;
CK_ATTRIBUTE *attrs;
CK_ATTRIBUTE *privattrs;
CK_ATTRIBUTE setTemplate;
@@ -1113,76 +1228,74 @@ PK11_GenerateKeyPairWithOpFlags(PK11SlotInfo *slot,CK_MECHANISM_TYPE type,
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);
+ (PK11_ATTR_TOKEN | PK11_ATTR_SESSION | PK11_ATTR_MODIFIABLE | PK11_ATTR_UNMODIFIABLE);
if (pk11_BadAttrFlags(attrFlags)) {
- PORT_SetError( SEC_ERROR_INVALID_ARGS );
- return NULL;
+ PORT_SetError(SEC_ERROR_INVALID_ARGS);
+ return NULL;
}
if (!param) {
- PORT_SetError( SEC_ERROR_INVALID_ARGS );
+ 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
+ * 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.
+ * 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);
+ PORT_Assert((opFlags & ~opFlagsMask) == 0);
opFlags &= opFlagsMask;
PORT_Assert(slot != NULL);
if (slot == NULL) {
- PORT_SetError( SEC_ERROR_NO_MODULE);
- return 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;
- }
-
+ 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;
@@ -1196,317 +1309,340 @@ PK11_GenerateKeyPairWithOpFlags(PK11SlotInfo *slot,CK_MECHANISM_TYPE type,
/* set up the private key template */
privattrs = privTemplate;
privattrs += pk11_AttrFlagsToAttributes(attrFlags, privattrs,
- &cktrue, &ckfalse);
+ &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;
+ 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);
+ if (!slot->isThreadSafe)
+ PK11_EnterSlotMonitor(slot);
crv = PK11_GETTAB(slot)->C_GetMechanismInfo(slot->slotID,
- test_mech.mechanism,&mechanism_info);
+ 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);
+ 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;
- }
+ /* 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++;
+ &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++;
+ 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;
+ 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;
+ 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;
+ 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);
+ 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;
+ 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); }
+ if (haslock) {
+ PK11_ExitSlotMonitor(slot);
+ }
/* swap around the ID's for older PKCS #11 modules */
- keyClass = PK11_ReadULongAttribute(slot,pubID,CKA_CLASS);
+ keyClass = PK11_ReadULongAttribute(slot, pubID, CKA_CLASS);
if (keyClass != CKO_PUBLIC_KEY) {
- CK_OBJECT_HANDLE tmp = pubID;
- pubID = privID;
- privID = tmp;
+ 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;
+ 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);
+ 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); }
+ if (haslock) {
+ PK11_EnterSlotMonitor(slot);
+ }
crv = PK11_GETTAB(slot)->C_SetAttributeValue(session_handle, privID,
- &setTemplate, 1);
-
+ &setTemplate, 1);
+
if (crv == CKR_OK && pubIsToken) {
- crv = PK11_GETTAB(slot)->C_SetAttributeValue(session_handle, pubID,
- &setTemplate, 1);
+ crv = PK11_GETTAB(slot)->C_SetAttributeValue(session_handle, pubID,
+ &setTemplate, 1);
}
-
if (restore) {
- PK11_RestoreROSession(slot,session_handle);
+ PK11_RestoreROSession(slot, session_handle);
} else {
- PK11_ExitSlotMonitor(slot);
+ PK11_ExitSlotMonitor(slot);
}
- SECITEM_FreeItem(cka_id,PR_TRUE);
-
+ 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;
+ 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);
+ privKey = PK11_MakePrivKey(slot, keyType, !token, privID, wincx);
if (privKey == NULL) {
- SECKEY_DestroyPublicKey(*pubKey);
- PK11_DestroyObject(slot,privID);
- *pubKey = NULL;
- return 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)
+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);
+ 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)
+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;
+ attrFlags |= PK11_ATTR_TOKEN;
} else {
- attrFlags |= PK11_ATTR_SESSION;
+ attrFlags |= PK11_ATTR_SESSION;
}
if (sensitive) {
- attrFlags |= (PK11_ATTR_SENSITIVE | PK11_ATTR_PRIVATE);
+ attrFlags |= (PK11_ATTR_SENSITIVE | PK11_ATTR_PRIVATE);
} else {
- attrFlags |= (PK11_ATTR_INSENSITIVE | PK11_ATTR_PUBLIC);
+ attrFlags |= (PK11_ATTR_INSENSITIVE | PK11_ATTR_PUBLIC);
}
return PK11_GenerateKeyPairWithFlags(slot, type, param, pubKey,
- attrFlags, wincx);
+ attrFlags, wincx);
}
/* build a public KEA key from the public value */
SECKEYPublicKey *
-PK11_MakeKEAPubKey(unsigned char *keyData,int length)
+PK11_MakeKEAPubKey(unsigned char *keyData, int length)
{
SECKEYPublicKey *pubk;
SECItem pkData;
@@ -1517,14 +1653,14 @@ PK11_MakeKEAPubKey(unsigned char *keyData,int length)
pkData.len = length;
pkData.type = siBuffer;
- arena = PORT_NewArena (DER_DEFAULT_CHUNKSIZE);
+ arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
if (arena == NULL)
- return NULL;
+ return NULL;
- pubk = (SECKEYPublicKey *) PORT_ArenaZAlloc(arena, sizeof(SECKEYPublicKey));
+ pubk = (SECKEYPublicKey *)PORT_ArenaZAlloc(arena, sizeof(SECKEYPublicKey));
if (pubk == NULL) {
- PORT_FreeArena (arena, PR_FALSE);
- return NULL;
+ PORT_FreeArena(arena, PR_FALSE);
+ return NULL;
}
pubk->arena = arena;
@@ -1533,8 +1669,8 @@ PK11_MakeKEAPubKey(unsigned char *keyData,int length)
pubk->keyType = fortezzaKey;
rv = SECITEM_CopyItem(arena, &pubk->u.fortezza.KEAKey, &pkData);
if (rv != SECSuccess) {
- PORT_FreeArena (arena, PR_FALSE);
- return NULL;
+ PORT_FreeArena(arena, PR_FALSE);
+ return NULL;
}
return pubk;
}
@@ -1545,29 +1681,29 @@ PK11_MakeKEAPubKey(unsigned char *keyData,int length)
* could later be looked up by its nickname, it would leak a SECKEYPrivateKey.
* So isPerm must be true.
*/
-SECStatus
+SECStatus
PK11_ImportEncryptedPrivateKeyInfo(PK11SlotInfo *slot,
- SECKEYEncryptedPrivateKeyInfo *epki, SECItem *pwitem,
- SECItem *nickname, SECItem *publicValue, PRBool isPerm,
- PRBool isPrivate, KeyType keyType,
- unsigned int keyUsage, void *wincx)
+ 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;
+ PORT_SetError(SEC_ERROR_INVALID_ARGS);
+ return SECFailure;
}
return PK11_ImportEncryptedPrivateKeyInfoAndReturnKey(slot, epki,
- pwitem, nickname, publicValue, isPerm, isPrivate, keyType,
- keyUsage, NULL, wincx);
+ 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)
+ 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;
@@ -1580,131 +1716,131 @@ PK11_ImportEncryptedPrivateKeyInfoAndReturnKey(PK11SlotInfo *slot,
CK_KEY_TYPE key_type;
CK_ATTRIBUTE_TYPE *usage = NULL;
CK_ATTRIBUTE_TYPE rsaUsage[] = {
- CKA_UNWRAP, CKA_DECRYPT, CKA_SIGN, CKA_SIGN_RECOVER };
+ 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;
+ if ((epki == NULL) || (pwitem == NULL))
+ return SECFailure;
pbeMechType = PK11_AlgtagToMechanism(SECOID_FindOIDTag(
- &epki->algorithm.algorithm));
+ &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;
+ 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;
+ rv = SECFailure;
+ goto done;
}
cryptoMechType = pk11_GetPBECryptoMechanism(&epki->algorithm,
- &crypto_param, pwitem, faulty3DES);
+ &crypto_param, pwitem, faulty3DES);
if (cryptoMechType == CKM_INVALID_MECHANISM) {
- rv = SECFailure;
- goto done;
+ 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
+ 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. */
+ */
+ if ((pbeMechType == CKM_NETSCAPE_PBE_SHA1_TRIPLE_DES_CBC) && (!faulty3DES)) {
+ /* clean up after ourselves before redoing the key generation. */
- PK11_FreeSymKey(key);
- key = NULL;
+ PK11_FreeSymKey(key);
+ key = NULL;
- if(crypto_param) {
- SECITEM_ZfreeItem(crypto_param, PR_TRUE);
- crypto_param = NULL;
- }
+ if (crypto_param) {
+ SECITEM_ZfreeItem(crypto_param, PR_TRUE);
+ crypto_param = NULL;
+ }
- faulty3DES = PR_TRUE;
- goto try_faulty_3des;
+ 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 (crypto_param != NULL) {
+ SECITEM_ZfreeItem(crypto_param, PR_TRUE);
}
- if(key != NULL) {
- PK11_FreeSymKey(key);
+ if (key != NULL) {
+ PK11_FreeSymKey(key);
}
return rv;
@@ -1714,82 +1850,81 @@ SECKEYPrivateKeyInfo *
PK11_ExportPrivateKeyInfo(CERTCertificate *cert, void *wincx)
{
SECKEYPrivateKeyInfo *pki = NULL;
- SECKEYPrivateKey *pk = PK11_FindKeyByAnyCert(cert, wincx);
+ SECKEYPrivateKey *pk = PK11_FindKeyByAnyCert(cert, wincx);
if (pk != NULL) {
- pki = PK11_ExportPrivKeyInfo(pk, wincx);
- SECKEY_DestroyPrivateKey(pk);
+ pki = PK11_ExportPrivKeyInfo(pk, wincx);
+ SECKEY_DestroyPrivateKey(pk);
}
return pki;
}
-SECKEYEncryptedPrivateKeyInfo *
+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 ? */
+ 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;
- PLArenaPool *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;
+ SECKEYEncryptedPrivateKeyInfo *epki = NULL;
+ PLArenaPool *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;
+ PORT_SetError(SEC_ERROR_INVALID_ARGS);
+ return NULL;
}
algid = sec_pkcs5CreateAlgorithmID(algTag, SEC_OID_UNKNOWN, SEC_OID_UNKNOWN,
- &pbeAlgTag, 0, NULL, iteration);
+ &pbeAlgTag, 0, NULL, iteration);
if (algid == NULL) {
- return NULL;
+ return NULL;
}
arena = PORT_NewArena(2048);
if (arena)
- epki = PORT_ArenaZNew(arena, SECKEYEncryptedPrivateKeyInfo);
- if(epki == NULL) {
- rv = SECFailure;
- goto loser;
+ 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;
+ 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
+ * 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;
- }
+ 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;
+ rv = SECFailure;
+ goto loser;
}
cryptoMechType = PK11_GetPBECryptoMechanism(algid, &crypto_param, pwitem);
if (cryptoMechType == CKM_INVALID_MECHANISM) {
- rv = SECFailure;
- goto loser;
+ rv = SECFailure;
+ goto loser;
}
cryptoMech.mechanism = PK11_GetPadMechanism(cryptoMechType);
@@ -1798,24 +1933,24 @@ PK11_ExportEncryptedPrivKeyInfo(
/* 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) {
+ 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;
- }
- }
-
+ 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
@@ -1823,81 +1958,77 @@ PK11_ExportEncryptedPrivKeyInfo(
*/
encBufLen = 0;
PK11_EnterSlotMonitor(pk->pkcs11Slot);
- crv = PK11_GETTAB(pk->pkcs11Slot)->C_WrapKey(pk->pkcs11Slot->session,
- &cryptoMech, key->objectID, pk->pkcs11ID, NULL,
- &encBufLen);
+ 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;
+ rv = SECFailure;
+ goto loser;
}
epki->encryptedData.data = PORT_ArenaAlloc(arena, encBufLen);
if (!epki->encryptedData.data) {
- rv = SECFailure;
- goto loser;
+ 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);
+ 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;
+ epki->encryptedData.len = (unsigned int)encBufLen;
+ if (crv != CKR_OK) {
+ rv = SECFailure;
+ goto loser;
}
- if(!epki->encryptedData.len) {
- 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 (crypto_param != NULL) {
+ SECITEM_ZfreeItem(crypto_param, PR_TRUE);
+ crypto_param = NULL;
}
- if(key != NULL) {
- PK11_FreeSymKey(key);
+ if (key != NULL) {
+ PK11_FreeSymKey(key);
}
if (tmpPK != NULL) {
- SECKEY_DestroyPrivateKey(tmpPK);
+ SECKEY_DestroyPrivateKey(tmpPK);
}
SECOID_DestroyAlgorithmID(algid, PR_TRUE);
- if(rv == SECFailure) {
- if(arena != NULL) {
- PORT_FreeArena(arena, PR_TRUE);
- }
- epki = NULL;
+ if (rv == SECFailure) {
+ if (arena != NULL) {
+ PORT_FreeArena(arena, PR_TRUE);
+ }
+ epki = NULL;
}
return epki;
}
-SECKEYEncryptedPrivateKeyInfo *
+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 ? */
+ 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);
+ SECKEYPrivateKey *pk = PK11_FindKeyByAnyCert(cert, wincx);
if (pk != NULL) {
- epki = PK11_ExportEncryptedPrivKeyInfo(slot, algTag, pwitem, pk,
- iteration, wincx);
- SECKEY_DestroyPrivateKey(pk);
+ epki = PK11_ExportEncryptedPrivKeyInfo(slot, algTag, pwitem, pk,
+ iteration, wincx);
+ SECKEY_DestroyPrivateKey(pk);
}
return epki;
}
-SECItem*
+SECItem *
PK11_DEREncodePublicKey(const SECKEYPublicKey *pubk)
{
return SECKEY_EncodeDERSubjectPublicKeyInfo(pubk);
@@ -1906,57 +2037,56 @@ PK11_DEREncodePublicKey(const SECKEYPublicKey *pubk)
char *
PK11_GetPrivateKeyNickname(SECKEYPrivateKey *privKey)
{
- return PK11_GetObjectNickname(privKey->pkcs11Slot,privKey->pkcs11ID);
+ return PK11_GetObjectNickname(privKey->pkcs11Slot, privKey->pkcs11ID);
}
char *
PK11_GetPublicKeyNickname(SECKEYPublicKey *pubKey)
{
- return PK11_GetObjectNickname(pubKey->pkcs11Slot,pubKey->pkcs11ID);
+ return PK11_GetObjectNickname(pubKey->pkcs11Slot, pubKey->pkcs11ID);
}
SECStatus
PK11_SetPrivateKeyNickname(SECKEYPrivateKey *privKey, const char *nickname)
{
return PK11_SetObjectNickname(privKey->pkcs11Slot,
- privKey->pkcs11ID,nickname);
+ privKey->pkcs11ID, nickname);
}
SECStatus
PK11_SetPublicKeyNickname(SECKEYPublicKey *pubKey, const char *nickname)
{
return PK11_SetObjectNickname(pubKey->pkcs11Slot,
- pubKey->pkcs11ID,nickname);
+ pubKey->pkcs11ID, nickname);
}
SECKEYPQGParams *
PK11_GetPQGParamsFromPrivateKey(SECKEYPrivateKey *privKey)
{
CK_ATTRIBUTE pTemplate[] = {
- { CKA_PRIME, NULL, 0 },
- { CKA_SUBPRIME, NULL, 0 },
- { CKA_BASE, NULL, 0 },
+ { CKA_PRIME, NULL, 0 },
+ { CKA_SUBPRIME, NULL, 0 },
+ { CKA_BASE, NULL, 0 },
};
- int pTemplateLen = sizeof(pTemplate)/sizeof(pTemplate[0]);
+ int pTemplateLen = sizeof(pTemplate) / sizeof(pTemplate[0]);
PLArenaPool *arena = NULL;
SECKEYPQGParams *params;
CK_RV crv;
-
arena = PORT_NewArena(2048);
if (arena == NULL) {
- goto loser;
+ goto loser;
}
- params=(SECKEYPQGParams *)PORT_ArenaZAlloc(arena,sizeof(SECKEYPQGParams));
+ params = (SECKEYPQGParams *)PORT_ArenaZAlloc(arena, sizeof(SECKEYPQGParams));
if (params == NULL) {
- goto loser;
+ goto loser;
}
- crv = PK11_GetAttributes(arena, privKey->pkcs11Slot, privKey->pkcs11ID,
- pTemplate, pTemplateLen);
+ crv = PK11_GetAttributes(arena, privKey->pkcs11Slot, privKey->pkcs11ID,
+ pTemplate, pTemplateLen);
if (crv != CKR_OK) {
- PORT_SetError( PK11_MapError(crv) );
- goto loser;
+ PORT_SetError(PK11_MapError(crv));
+ goto loser;
}
params->arena = arena;
@@ -1971,55 +2101,55 @@ PK11_GetPQGParamsFromPrivateKey(SECKEYPrivateKey *privKey)
loser:
if (arena != NULL) {
- PORT_FreeArena(arena,PR_FALSE);
+ PORT_FreeArena(arena, PR_FALSE);
}
return NULL;
}
-SECKEYPrivateKey*
+SECKEYPrivateKey *
PK11_CopyTokenPrivKeyToSessionPrivKey(PK11SlotInfo *destSlot,
- SECKEYPrivateKey *privKey)
+ SECKEYPrivateKey *privKey)
{
- CK_RV crv;
- CK_OBJECT_HANDLE newKeyID;
+ 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 }
+ 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;
+ 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);
+ 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;
+ PORT_SetError(PK11_MapError(crv));
+ return NULL;
}
- return PK11_MakePrivKey(destSlot, privKey->keyType, PR_TRUE /*isTemp*/,
- newKeyID, privKey->wincx);
+ return PK11_MakePrivKey(destSlot, privKey->keyType, PR_TRUE /*isTemp*/,
+ newKeyID, privKey->wincx);
}
-SECKEYPrivateKey*
-PK11_ConvertSessionPrivKeyToTokenPrivKey(SECKEYPrivateKey *privk, void* wincx)
+SECKEYPrivateKey *
+PK11_ConvertSessionPrivKeyToTokenPrivKey(SECKEYPrivateKey *privk, void *wincx)
{
- PK11SlotInfo* slot = privk->pkcs11Slot;
+ PK11SlotInfo *slot = privk->pkcs11Slot;
CK_ATTRIBUTE template[1];
CK_ATTRIBUTE *attrs = template;
CK_BBOOL cktrue = CK_TRUE;
@@ -2027,25 +2157,26 @@ PK11_ConvertSessionPrivKeyToTokenPrivKey(SECKEYPrivateKey *privk, void* wincx)
CK_OBJECT_HANDLE newKeyID;
CK_SESSION_HANDLE rwsession;
- PK11_SETATTRS(attrs, CKA_TOKEN, &cktrue, sizeof(cktrue)); attrs++;
+ 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;
+ PORT_SetError(SEC_ERROR_BAD_DATA);
+ return NULL;
}
crv = PK11_GETTAB(slot)->C_CopyObject(rwsession, privk->pkcs11ID,
- template, 1, &newKeyID);
+ template, 1, &newKeyID);
PK11_RestoreROSession(slot, rwsession);
if (crv != CKR_OK) {
- PORT_SetError( PK11_MapError(crv) );
+ PORT_SetError(PK11_MapError(crv));
return NULL;
}
return PK11_MakePrivKey(slot, nullKey /*KeyType*/, PR_FALSE /*isTemp*/,
- newKeyID, NULL /*wincx*/);
+ newKeyID, NULL /*wincx*/);
}
/*
@@ -2055,15 +2186,15 @@ PK11_ConvertSessionPrivKeyToTokenPrivKey(SECKEYPrivateKey *privk, void* wincx)
SECStatus
PK11_DeleteTokenPrivateKey(SECKEYPrivateKey *privKey, PRBool force)
{
- CERTCertificate *cert=PK11_GetCertFromPrivateKey(privKey);
+ 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);
+ /* now, then it's safe for the key to go away */
+ rv = PK11_DestroyTokenObject(privKey->pkcs11Slot, privKey->pkcs11ID);
}
if (cert) {
- CERT_DestroyCertificate(cert);
+ CERT_DestroyCertificate(cert);
}
SECKEY_DestroyPrivateKey(privKey);
return rv;
@@ -2078,9 +2209,9 @@ PK11_DeleteTokenPublicKey(SECKEYPublicKey *pubKey)
{
/* now, then it's safe for the key to go away */
if (pubKey->pkcs11Slot == NULL) {
- return SECFailure;
+ return SECFailure;
}
- PK11_DestroyTokenObject(pubKey->pkcs11Slot,pubKey->pkcs11ID);
+ PK11_DestroyTokenObject(pubKey->pkcs11Slot, pubKey->pkcs11ID);
SECKEY_DestroyPublicKey(pubKey);
return SECSuccess;
}
@@ -2089,9 +2220,9 @@ PK11_DeleteTokenPublicKey(SECKEYPublicKey *pubKey)
* key call back structure.
*/
typedef struct pk11KeyCallbackStr {
- SECStatus (* callback)(SECKEYPrivateKey *,void *);
- void *callbackArg;
- void *wincx;
+ SECStatus (*callback)(SECKEYPrivateKey *, void *);
+ void *callbackArg;
+ void *wincx;
} pk11KeyCallback;
/*
@@ -2102,22 +2233,22 @@ pk11_DoKeys(PK11SlotInfo *slot, CK_OBJECT_HANDLE keyHandle, void *arg)
{
SECStatus rv = SECSuccess;
SECKEYPrivateKey *privKey;
- pk11KeyCallback *keycb = (pk11KeyCallback *) arg;
+ pk11KeyCallback *keycb = (pk11KeyCallback *)arg;
if (!arg) {
return SECFailure;
}
- privKey = PK11_MakePrivKey(slot,nullKey,PR_TRUE,keyHandle,keycb->wincx);
+ privKey = PK11_MakePrivKey(slot, nullKey, PR_TRUE, keyHandle, keycb->wincx);
if (privKey == NULL) {
- return SECFailure;
+ return SECFailure;
}
if (keycb->callback) {
- rv = (*keycb->callback)(privKey,keycb->callbackArg);
+ rv = (*keycb->callback)(privKey, keycb->callbackArg);
}
- SECKEY_DestroyPrivateKey(privKey);
+ SECKEY_DestroyPrivateKey(privKey);
return rv;
}
@@ -2135,8 +2266,8 @@ pk11_DoKeys(PK11SlotInfo *slot, CK_OBJECT_HANDLE keyHandle, void *arg)
* An argument that will be passed to the callback function.
*/
SECStatus
-PK11_TraversePrivateKeysInSlot( PK11SlotInfo *slot,
- SECStatus(* callback)(SECKEYPrivateKey*, void*), void *arg)
+PK11_TraversePrivateKeysInSlot(PK11SlotInfo *slot,
+ SECStatus (*callback)(SECKEYPrivateKey *, void *), void *arg)
{
pk11KeyCallback perKeyCB;
pk11TraverseSlot perObjectCB;
@@ -2152,7 +2283,7 @@ PK11_TraversePrivateKeysInSlot( PK11SlotInfo *slot,
theTemplate[1].pValue = &ckTrue;
theTemplate[1].ulValueLen = sizeof(ckTrue);
- if(slot==NULL) {
+ if (slot == NULL) {
return SECSuccess;
}
@@ -2175,19 +2306,19 @@ pk11_FindPrivateKeyFromCertID(PK11SlotInfo *slot, SECItem *keyID)
{
CK_OBJECT_CLASS privKey = CKO_PRIVATE_KEY;
CK_ATTRIBUTE theTemplate[] = {
- { CKA_ID, NULL, 0 },
- { CKA_CLASS, NULL, 0 },
+ { 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]);
+ 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_ID, keyID->data, keyID->len);
+ attrs++;
PK11_SETATTRS(attrs, CKA_CLASS, &privKey, sizeof(privKey));
- return pk11_FindObjectByTemplate(slot,theTemplate,tsize);
-}
-
+ return pk11_FindObjectByTemplate(slot, theTemplate, tsize);
+}
SECKEYPrivateKey *
PK11_FindKeyByKeyID(PK11SlotInfo *slot, SECItem *keyID, void *wincx)
@@ -2196,10 +2327,10 @@ PK11_FindKeyByKeyID(PK11SlotInfo *slot, SECItem *keyID, void *wincx)
SECKEYPrivateKey *privKey;
keyHandle = pk11_FindPrivateKeyFromCertID(slot, keyID);
- if (keyHandle == CK_INVALID_HANDLE) {
- return NULL;
+ if (keyHandle == CK_INVALID_HANDLE) {
+ return NULL;
}
- privKey = PK11_MakePrivKey(slot, nullKey, PR_TRUE, keyHandle, wincx);
+ privKey = PK11_MakePrivKey(slot, nullKey, PR_TRUE, keyHandle, wincx);
return privKey;
}
@@ -2209,55 +2340,55 @@ PK11_FindKeyByKeyID(PK11SlotInfo *slot, SECItem *keyID, void *wincx)
* smart cards happy.
*/
SECItem *
-PK11_MakeIDFromPubKey(SECItem *pubKeyData)
+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);
+ /* 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;
+ return NULL;
}
rv = PK11_DigestBegin(context);
if (rv == SECSuccess) {
- rv = PK11_DigestOp(context,pubKeyData->data,pubKeyData->len);
+ rv = PK11_DigestOp(context, pubKeyData->data, pubKeyData->len);
}
if (rv != SECSuccess) {
- PK11_DestroyContext(context,PR_TRUE);
- return NULL;
+ 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;
+ PK11_DestroyContext(context, PR_TRUE);
+ return NULL;
}
certCKA_ID->len = SHA1_LENGTH;
- certCKA_ID->data = (unsigned char*)PORT_Alloc(certCKA_ID->len);
+ certCKA_ID->data = (unsigned char *)PORT_Alloc(certCKA_ID->len);
if (certCKA_ID->data == NULL) {
- PORT_Free(certCKA_ID);
- PK11_DestroyContext(context,PR_TRUE);
+ 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);
+ 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;
+ SECITEM_FreeItem(certCKA_ID, PR_TRUE);
+ return NULL;
}
return certCKA_ID;
@@ -2267,41 +2398,41 @@ PK11_MakeIDFromPubKey(SECItem *pubKeyData)
* Call PK11_GetLowLevelKeyIDForPrivateKey instead.
*/
-
SECItem *
PK11_GetLowLevelKeyIDForPrivateKey(SECKEYPrivateKey *privKey)
{
- return pk11_GetLowLevelKeyFromHandle(privKey->pkcs11Slot,privKey->pkcs11ID);
+ return pk11_GetLowLevelKeyFromHandle(privKey->pkcs11Slot, privKey->pkcs11ID);
}
static SECStatus
privateKeyListCallback(SECKEYPrivateKey *key, void *arg)
{
- SECKEYPrivateKeyList *list = (SECKEYPrivateKeyList*)arg;
+ SECKEYPrivateKeyList *list = (SECKEYPrivateKeyList *)arg;
return SECKEY_AddPrivateKeyToListTail(list, SECKEY_CopyPrivateKey(key));
}
-SECKEYPrivateKeyList*
+SECKEYPrivateKeyList *
PK11_ListPrivateKeysInSlot(PK11SlotInfo *slot)
{
SECStatus status;
SECKEYPrivateKeyList *keys;
keys = SECKEY_NewPrivateKeyList();
- if(keys == NULL) return NULL;
+ if (keys == NULL)
+ return NULL;
status = PK11_TraversePrivateKeysInSlot(slot, privateKeyListCallback,
- (void*)keys);
+ (void *)keys);
- if( status != SECSuccess ) {
- SECKEY_DestroyPrivateKeyList(keys);
- keys = NULL;
+ if (status != SECSuccess) {
+ SECKEY_DestroyPrivateKeyList(keys);
+ keys = NULL;
}
return keys;
}
-SECKEYPublicKeyList*
+SECKEYPublicKeyList *
PK11_ListPublicKeysInSlot(PK11SlotInfo *slot, char *nickname)
{
CK_ATTRIBUTE findTemp[4];
@@ -2312,42 +2443,44 @@ PK11_ListPublicKeysInSlot(PK11SlotInfo *slot, char *nickname)
int objCount = 0;
CK_OBJECT_HANDLE *key_ids;
SECKEYPublicKeyList *keys;
- int i,len;
-
+ int i, len;
attrs = findTemp;
- PK11_SETATTRS(attrs, CKA_CLASS, &keyclass, sizeof(keyclass)); attrs++;
- PK11_SETATTRS(attrs, CKA_TOKEN, &ckTrue, sizeof(ckTrue)); attrs++;
+ 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++;
+ len = PORT_Strlen(nickname);
+ PK11_SETATTRS(attrs, CKA_LABEL, nickname, len);
+ attrs++;
}
tsize = attrs - findTemp;
- PORT_Assert(tsize <= sizeof(findTemp)/sizeof(CK_ATTRIBUTE));
+ PORT_Assert(tsize <= sizeof(findTemp) / sizeof(CK_ATTRIBUTE));
- key_ids = pk11_FindObjectsByTemplate(slot,findTemp,tsize,&objCount);
+ key_ids = pk11_FindObjectsByTemplate(slot, findTemp, tsize, &objCount);
if (key_ids == NULL) {
- return NULL;
+ return NULL;
}
keys = SECKEY_NewPublicKeyList();
if (keys == NULL) {
- PORT_Free(key_ids);
- return 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);
- }
- }
+ 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;
+ PORT_Free(key_ids);
+ return keys;
}
-SECKEYPrivateKeyList*
+SECKEYPrivateKeyList *
PK11_ListPrivKeysInSlot(PK11SlotInfo *slot, char *nickname, void *wincx)
{
CK_ATTRIBUTE findTemp[4];
@@ -2358,36 +2491,37 @@ PK11_ListPrivKeysInSlot(PK11SlotInfo *slot, char *nickname, void *wincx)
int objCount = 0;
CK_OBJECT_HANDLE *key_ids;
SECKEYPrivateKeyList *keys;
- int i,len;
-
+ int i, len;
attrs = findTemp;
- PK11_SETATTRS(attrs, CKA_CLASS, &keyclass, sizeof(keyclass)); attrs++;
- PK11_SETATTRS(attrs, CKA_TOKEN, &ckTrue, sizeof(ckTrue)); attrs++;
+ 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++;
+ len = PORT_Strlen(nickname);
+ PK11_SETATTRS(attrs, CKA_LABEL, nickname, len);
+ attrs++;
}
tsize = attrs - findTemp;
- PORT_Assert(tsize <= sizeof(findTemp)/sizeof(CK_ATTRIBUTE));
+ PORT_Assert(tsize <= sizeof(findTemp) / sizeof(CK_ATTRIBUTE));
- key_ids = pk11_FindObjectsByTemplate(slot,findTemp,tsize,&objCount);
+ key_ids = pk11_FindObjectsByTemplate(slot, findTemp, tsize, &objCount);
if (key_ids == NULL) {
- return NULL;
+ return NULL;
}
keys = SECKEY_NewPrivateKeyList();
if (keys == NULL) {
- PORT_Free(key_ids);
- return 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);
- }
+ 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;
+ PORT_Free(key_ids);
+ return keys;
}
-
diff --git a/nss/lib/pk11wrap/pk11auth.c b/nss/lib/pk11wrap/pk11auth.c
index 14aeffa..4ccfad6 100644
--- a/nss/lib/pk11wrap/pk11auth.c
+++ b/nss/lib/pk11wrap/pk11auth.c
@@ -13,8 +13,7 @@
#include "secitem.h"
#include "secerr.h"
-#include "pkim.h"
-
+#include "pkim.h"
/*************************************************************
* local static and global data
@@ -22,22 +21,22 @@
/*
* 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
+ * 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
+ * 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 *);
+ 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
***********************************************************/
@@ -47,7 +46,7 @@ static struct PK11GlobalStruct {
*/
static SECStatus
pk11_CheckPassword(PK11SlotInfo *slot, CK_SESSION_HANDLE session,
- char *pw, PRBool alreadyLocked, PRBool contextSpecific)
+ char *pw, PRBool alreadyLocked, PRBool contextSpecific)
{
int len = 0;
CK_RV crv;
@@ -57,67 +56,69 @@ pk11_CheckPassword(PK11SlotInfo *slot, CK_SESSION_HANDLE session,
int retry = 0;
if (slot->protectedAuthPath) {
- len = 0;
- pw = NULL;
+ len = 0;
+ pw = NULL;
} else if (pw == NULL) {
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- return SECFailure;
+ PORT_SetError(SEC_ERROR_INVALID_ARGS);
+ return SECFailure;
} else {
- len = PORT_Strlen(pw);
+ 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 */
- }
+ 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;
}
@@ -135,13 +136,13 @@ PK11_CheckUserPassword(PK11SlotInfo *slot, const char *pw)
PRTime currtime = PR_Now();
if (slot->protectedAuthPath) {
- len = 0;
- pw = NULL;
+ len = 0;
+ pw = NULL;
} else if (pw == NULL) {
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- return SECFailure;
+ PORT_SetError(SEC_ERROR_INVALID_ARGS);
+ return SECFailure;
} else {
- len = PORT_Strlen(pw);
+ len = PORT_Strlen(pw);
}
/*
@@ -163,24 +164,24 @@ PK11_CheckUserPassword(PK11SlotInfo *slot, const char *pw)
PK11_EnterSlotMonitor(slot);
PK11_GETTAB(slot)->C_Logout(slot->session);
- crv = PK11_GETTAB(slot)->C_Login(slot->session,CKU_USER,
- (unsigned char *)pw,len);
+ 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 */
+ /* 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;
}
@@ -196,26 +197,28 @@ PK11_Logout(PK11SlotInfo *slot)
slot->lastLoginCheck = 0;
PK11_ExitSlotMonitor(slot);
if (crv != CKR_OK) {
- PORT_SetError(PK11_MapError(crv));
- return SECFailure;
+ PORT_SetError(PK11_MapError(crv));
+ return SECFailure;
}
- return SECSuccess;
+ 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)
+void
+PK11_StartAuthTransaction(void)
{
-PK11_Global.transaction++;
-PK11_Global.inTransaction = PR_TRUE;
+ PK11_Global.transaction++;
+ PK11_Global.inTransaction = PR_TRUE;
}
-void PK11_EndAuthTransaction(void)
+void
+PK11_EndAuthTransaction(void)
{
-PK11_Global.transaction++;
-PK11_Global.inTransaction = PR_FALSE;
+ PK11_Global.transaction++;
+ PK11_Global.inTransaction = PR_FALSE;
}
/*
@@ -223,37 +226,39 @@ PK11_Global.inTransaction = PR_FALSE;
* need to reauthenticate.
*/
void
-PK11_HandlePasswordCheck(PK11SlotInfo *slot,void *wincx)
+PK11_HandlePasswordCheck(PK11SlotInfo *slot, void *wincx)
{
int askpw = slot->askpw;
PRBool NeedAuth = PR_FALSE;
- if (!slot->needLogin) return;
+ if (!slot->needLogin)
+ return;
if ((slot->defaultFlags & PK11_OWN_PW_DEFAULTS) == 0) {
- PK11SlotInfo *def_slot = PK11_GetInternalKeySlot();
+ PK11SlotInfo *def_slot = PK11_GetInternalKeySlot();
- if (def_slot) {
- askpw = def_slot->askpw;
- PK11_FreeSlot(def_slot);
- }
+ if (def_slot) {
+ askpw = def_slot->askpw;
+ PK11_FreeSlot(def_slot);
+ }
}
/* timeouts are handled by isLoggedIn */
- if (!PK11_IsLoggedIn(slot,wincx)) {
- NeedAuth = PR_TRUE;
+ 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);
+ 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
@@ -266,31 +271,31 @@ PK11_SlotDBUpdate(PK11SlotInfo *slot)
* set new askpw and timeout values
*/
void
-PK11_SetSlotPWValues(PK11SlotInfo *slot,int askpw, int timeout)
+PK11_SetSlotPWValues(PK11SlotInfo *slot, int askpw, int timeout)
{
- slot->askpw = askpw;
- slot->timeout = timeout;
- slot->defaultFlags |= PK11_OWN_PW_DEFAULTS;
- PK11_SlotDBUpdate(slot);
+ 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)
+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();
+ PK11SlotInfo *def_slot = PK11_GetInternalKeySlot();
- if (def_slot) {
- *askpw = def_slot->askpw;
- *timeout = def_slot->timeout;
- PK11_FreeSlot(def_slot);
- }
+ if (def_slot) {
+ *askpw = def_slot->askpw;
+ *timeout = def_slot->timeout;
+ PK11_FreeSlot(def_slot);
+ }
}
}
@@ -302,7 +307,7 @@ PK11_GetSlotPWValues(PK11SlotInfo *slot,int *askpw, int *timeout)
PRBool
pk11_LoginStillRequired(PK11SlotInfo *slot, void *wincx)
{
- return slot->needLogin && !PK11_IsLoggedIn(slot,wincx);
+ return slot->needLogin && !PK11_IsLoggedIn(slot, wincx);
}
/*
@@ -310,10 +315,14 @@ pk11_LoginStillRequired(PK11SlotInfo *slot, void *wincx)
* 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);
+PK11_Authenticate(PK11SlotInfo *slot, PRBool loadCerts, void *wincx)
+{
+ if (!slot) {
+ return SECFailure;
+ }
+ if (pk11_LoginStillRequired(slot, wincx)) {
+ return PK11_DoPassword(slot, slot->session, loadCerts, wincx,
+ PR_FALSE, PR_FALSE);
}
return SECSuccess;
}
@@ -327,12 +336,11 @@ pk11_AuthenticateUnfriendly(PK11SlotInfo *slot, PRBool loadCerts, void *wincx)
{
SECStatus rv = SECSuccess;
if (!PK11_IsFriendly(slot)) {
- rv = PK11_Authenticate(slot, loadCerts, wincx);
+ rv = PK11_Authenticate(slot, loadCerts, wincx);
}
return rv;
}
-
/*
* NOTE: this assumes that we are logged out of the card before hand
*/
@@ -347,42 +355,42 @@ PK11_CheckSSOPassword(PK11SlotInfo *slot, char *ssopw)
/* get a rwsession */
rwsession = PK11_GetRWSession(slot);
if (rwsession == CK_INVALID_SESSION) {
- PORT_SetError(SEC_ERROR_BAD_DATA);
- return rv;
+ PORT_SetError(SEC_ERROR_BAD_DATA);
+ return rv;
}
if (slot->protectedAuthPath) {
- len = 0;
- ssopw = NULL;
+ len = 0;
+ ssopw = NULL;
} else if (ssopw == NULL) {
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- return SECFailure;
+ PORT_SetError(SEC_ERROR_INVALID_ARGS);
+ return SECFailure;
} else {
- len = PORT_Strlen(ssopw);
+ len = PORT_Strlen(ssopw);
}
/* check the password */
- crv = PK11_GETTAB(slot)->C_Login(rwsession,CKU_SO,
- (unsigned char *)ssopw,len);
+ 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 */
+ /* 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);
+ PK11_RestoreROSession(slot, rwsession);
return rv;
}
@@ -390,13 +398,13 @@ PK11_CheckSSOPassword(PK11SlotInfo *slot, char *ssopw)
* make sure the password conforms to your token's requirements.
*/
SECStatus
-PK11_VerifyPW(PK11SlotInfo *slot,char *pw)
+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;
+ PORT_SetError(SEC_ERROR_BAD_DATA);
+ return SECFailure;
}
return SECSuccess;
}
@@ -413,8 +421,10 @@ PK11_InitPin(PK11SlotInfo *slot, const char *ssopw, const char *userpw)
int len;
int ssolen;
- if (userpw == NULL) userpw = "";
- if (ssopw == NULL) ssopw = "";
+ if (userpw == NULL)
+ userpw = "";
+ if (ssopw == NULL)
+ ssopw = "";
len = PORT_Strlen(userpw);
ssolen = PORT_Strlen(ssopw);
@@ -422,48 +432,48 @@ PK11_InitPin(PK11SlotInfo *slot, const char *ssopw, const char *userpw)
/* get a rwsession */
rwsession = PK11_GetRWSession(slot);
if (rwsession == CK_INVALID_SESSION) {
- PORT_SetError(SEC_ERROR_BAD_DATA);
- slot->lastLoginCheck = 0;
- return rv;
+ PORT_SetError(SEC_ERROR_BAD_DATA);
+ slot->lastLoginCheck = 0;
+ return rv;
}
if (slot->protectedAuthPath) {
- len = 0;
- ssolen = 0;
- ssopw = NULL;
- userpw = NULL;
+ len = 0;
+ ssolen = 0;
+ ssopw = NULL;
+ userpw = NULL;
}
/* check the password */
- crv = PK11_GETTAB(slot)->C_Login(rwsession,CKU_SO,
- (unsigned char *)ssopw,ssolen);
+ 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;
+ PORT_SetError(PK11_MapError(crv));
+ goto done;
}
- crv = PK11_GETTAB(slot)->C_InitPIN(rwsession,(unsigned char *)userpw,len);
+ crv = PK11_GETTAB(slot)->C_InitPIN(rwsession, (unsigned char *)userpw, len);
if (crv != CKR_OK) {
- PORT_SetError(PK11_MapError(crv));
+ PORT_SetError(PK11_MapError(crv));
} else {
- rv = SECSuccess;
+ rv = SECSuccess;
}
done:
PK11_GETTAB(slot)->C_Logout(rwsession);
slot->lastLoginCheck = 0;
- PK11_RestoreROSession(slot,rwsession);
+ 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);
- }
+ 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;
}
@@ -482,38 +492,43 @@ PK11_ChangePW(PK11SlotInfo *slot, const char *oldpw, const char *newpw)
/* use NULL values to trigger the protected authentication path */
if (!slot->protectedAuthPath) {
- if (newpw == NULL) newpw = "";
- if (oldpw == NULL) oldpw = "";
+ if (newpw == NULL)
+ newpw = "";
+ if (oldpw == NULL)
+ oldpw = "";
}
- if (newpw) newLen = PORT_Strlen(newpw);
- if (oldpw) oldLen = PORT_Strlen(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;
+ PORT_SetError(SEC_ERROR_BAD_DATA);
+ return rv;
}
crv = PK11_GETTAB(slot)->C_SetPIN(rwsession,
- (unsigned char *)oldpw,oldLen,(unsigned char *)newpw,newLen);
+ (unsigned char *)oldpw, oldLen, (unsigned char *)newpw, newLen);
if (crv == CKR_OK) {
- rv = SECSuccess;
+ rv = SECSuccess;
} else {
- PORT_SetError(PK11_MapError(crv));
+ PORT_SetError(PK11_MapError(crv));
}
- PK11_RestoreROSession(slot,rwsession);
+ PK11_RestoreROSession(slot, rwsession);
/* update our view of the world */
- PK11_InitToken(slot,PR_TRUE);
+ PK11_InitToken(slot, PR_TRUE);
return rv;
}
static char *
-pk11_GetPassword(PK11SlotInfo *slot, PRBool retry, void * wincx)
+pk11_GetPassword(PK11SlotInfo *slot, PRBool retry, void *wincx)
{
- if (PK11_Global.getPass == NULL) return NULL;
+ if (PK11_Global.getPass == NULL)
+ return NULL;
return (*PK11_Global.getPass)(slot, retry, wincx);
}
@@ -535,7 +550,6 @@ 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
@@ -545,19 +559,18 @@ PK11_SetIsLoggedInFunc(PK11IsLoggedInFunc func)
*/
SECStatus
PK11_DoPassword(PK11SlotInfo *slot, CK_SESSION_HANDLE session,
- PRBool loadCerts, void *wincx, PRBool alreadyLocked,
- PRBool contextSpecific)
+ PRBool loadCerts, void *wincx, PRBool alreadyLocked,
+ PRBool contextSpecific)
{
SECStatus rv = SECFailure;
- char * password;
+ char *password;
PRBool attempt = PR_FALSE;
if (PK11_NeedUserInit(slot)) {
- PORT_SetError(SEC_ERROR_IO);
- return SECFailure;
+ 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
@@ -568,69 +581,72 @@ PK11_DoPassword(PK11SlotInfo *slot, CK_SESSION_HANDLE session,
* 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;
+ 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.
+ * (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
+ /* 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
+ * 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;
+ * 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);
+ 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)
+void
+PK11_LogoutAll(void)
{
SECMODListLock *lock = SECMOD_GetDefaultModuleListLock();
SECMODModuleList *modList;
@@ -639,16 +655,16 @@ void PK11_LogoutAll(void)
/* NSS is not initialized, there are not tokens to log out */
if (lock == NULL) {
- return;
+ 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]);
- }
+ for (i = 0; i < mlp->module->slotCount; i++) {
+ PK11_Logout(mlp->module->slots[i]);
+ }
}
SECMOD_ReleaseReadLock(lock);
@@ -664,26 +680,28 @@ PK11_GetMinimumPwdLength(PK11SlotInfo *slot)
PRBool
PK11_ProtectedAuthenticationPath(PK11SlotInfo *slot)
{
- return slot->protectedAuthPath;
+ return slot->protectedAuthPath;
}
/*
- * we can initialize the password if 1) The toke is not inited
+ * 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)
+PRBool
+PK11_NeedPWInitForSlot(PK11SlotInfo *slot)
{
if (slot->needLogin && PK11_NeedUserInit(slot)) {
- return PR_TRUE;
+ return PR_TRUE;
}
if (!slot->needLogin && !PK11_NeedUserInit(slot)) {
- return PR_TRUE;
+ return PR_TRUE;
}
return PR_FALSE;
}
-PRBool PK11_NeedPWInit()
+PRBool
+PK11_NeedPWInit()
{
PK11SlotInfo *slot = PK11_GetInternalKeySlot();
PRBool ret = PK11_NeedPWInitForSlot(slot);
@@ -692,14 +710,14 @@ PRBool PK11_NeedPWInit()
return ret;
}
-PRBool
-pk11_InDelayPeriod(PRIntervalTime lastTime, PRIntervalTime delayTime,
- PRIntervalTime *retTime)
+PRBool
+pk11_InDelayPeriod(PRIntervalTime lastTime, PRIntervalTime delayTime,
+ PRIntervalTime *retTime)
{
PRIntervalTime time;
*retTime = time = PR_IntervalNow();
- return (PRBool) (lastTime) && ((time-lastTime) < delayTime);
+ return (PRBool)(lastTime) && ((time - lastTime) < delayTime);
}
/*
@@ -707,7 +725,7 @@ pk11_InDelayPeriod(PRIntervalTime lastTime, PRIntervalTime delayTime,
* because it's state can change without intervention from us.
*/
PRBool
-PK11_IsLoggedIn(PK11SlotInfo *slot,void *wincx)
+PK11_IsLoggedIn(PK11SlotInfo *slot, void *wincx)
{
CK_SESSION_INFO sessionInfo;
int askpw = slot->askpw;
@@ -717,72 +735,73 @@ PK11_IsLoggedIn(PK11SlotInfo *slot,void *wincx)
static PRIntervalTime login_delay_time = 0;
if (login_delay_time == 0) {
- login_delay_time = PR_SecondsToInterval(1);
+ 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();
+ PK11SlotInfo *def_slot = PK11_GetInternalKeySlot();
- if (def_slot) {
- askpw = def_slot->askpw;
- timeout = def_slot->timeout;
- PK11_FreeSlot(def_slot);
- }
+ 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; }
-
+ (*PK11_Global.isLoggedIn)(slot, wincx) == PR_FALSE) {
+ return PR_FALSE;
+ }
/* forget the password if we've been inactive too long */
if (askpw == 1) {
- PRTime currtime = PR_Now();
- PRTime result;
- PRTime 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;
- }
+ PRTime currtime = PR_Now();
+ PRTime result;
+ PRTime 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;
+ 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;
- }
+ 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;
+ 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;
+ 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/nss/lib/pk11wrap/pk11cert.c b/nss/lib/pk11wrap/pk11cert.c
index e29b4e2..6968ae7 100644
--- a/nss/lib/pk11wrap/pk11cert.c
+++ b/nss/lib/pk11wrap/pk11cert.c
@@ -15,7 +15,7 @@
#include "cert.h"
#include "certi.h"
#include "secitem.h"
-#include "key.h"
+#include "key.h"
#include "secoid.h"
#include "pkcs7t.h"
#include "cmsreclist.h"
@@ -27,7 +27,7 @@
#include "pki3hack.h"
#include "dev3hack.h"
-#include "devm.h"
+#include "devm.h"
#include "nsspki.h"
#include "pki.h"
#include "pkim.h"
@@ -39,7 +39,7 @@ extern const NSSError NSS_ERROR_NOT_FOUND;
extern const NSSError NSS_ERROR_INVALID_CERTIFICATE;
struct nss3_cert_cbstr {
- SECStatus(* callback)(CERTCertificate*, void *);
+ SECStatus (*callback)(CERTCertificate *, void *);
nssList *cached;
void *arg;
};
@@ -47,69 +47,77 @@ struct nss3_cert_cbstr {
/* Translate from NSSCertificate to CERTCertificate, then pass the latter
* to a callback.
*/
-static PRStatus convert_cert(NSSCertificate *c, void *arg)
+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;
+ 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
+ * 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); }
+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)
+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;
+ 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;
+ 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;
+ 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);
+ 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;
+ 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;
+ next = nickname = (char *)PORT_Alloc(prefixLen + 1 + suffixLen + 1);
+ if (nickname == NULL)
+ return NULL;
- PORT_Memcpy(next,slot->token_name,prefixLen);
+ PORT_Memcpy(next, slot->token_name, prefixLen);
next += prefixLen;
*next++ = ':';
- PORT_Memcpy(next,suffix,suffixLen);
+ PORT_Memcpy(next, suffix, suffixLen);
next += suffixLen;
*next++ = 0;
return nickname;
@@ -117,67 +125,69 @@ pk11_buildNickname(PK11SlotInfo *slot,CK_ATTRIBUTE *cert_label,
PRBool
PK11_IsUserCert(PK11SlotInfo *slot, CERTCertificate *cert,
- CK_OBJECT_HANDLE certID)
+ CK_OBJECT_HANDLE certID)
{
CK_OBJECT_CLASS theClass;
- if (slot == NULL) return PR_FALSE;
- if (cert == NULL) return PR_FALSE;
+ 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:
- case rsaPssKey:
- case rsaOaepKey:
- 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);
+ 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:
+ case rsaPssKey:
+ case rsaOaepKey:
+ 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;
}
@@ -186,35 +196,33 @@ PK11_IsUserCert(PK11SlotInfo *slot, CERTCertificate *cert,
* 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};
+ CK_ATTRIBUTE keyID = { CKA_ID, NULL, 0 };
PRBool isZero = PR_FALSE;
int i;
CK_RV crv;
-
- crv = PK11_GetAttributes(NULL,slot,certID,&keyID,1);
+ crv = PK11_GetAttributes(NULL, slot, certID, &keyID, 1);
if (crv != CKR_OK) {
- return isZero;
+ 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;
- }
- }
+ 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;
-
}
/*
@@ -222,8 +230,8 @@ pk11_isID0(PK11SlotInfo *slot, CK_OBJECT_HANDLE certID)
* CERTCertificate. Optionally, output the nickname string.
*/
static CERTCertificate *
-pk11_fastCert(PK11SlotInfo *slot, CK_OBJECT_HANDLE certID,
- CK_ATTRIBUTE *privateLabel, char **nickptr)
+pk11_fastCert(PK11SlotInfo *slot, CK_OBJECT_HANDLE certID,
+ CK_ATTRIBUTE *privateLabel, char **nickptr)
{
NSSCertificate *c;
nssCryptokiObject *co = NULL;
@@ -234,48 +242,48 @@ pk11_fastCert(PK11SlotInfo *slot, CK_OBJECT_HANDLE certID,
/* Get the cryptoki object from the handle */
token = PK11Slot_GetNSSToken(slot);
if (token->defaultSession) {
- co = nssCryptokiObject_Create(token, token->defaultSession, certID);
+ co = nssCryptokiObject_Create(token, token->defaultSession, certID);
} else {
- PORT_SetError(SEC_ERROR_NO_TOKEN);
+ PORT_SetError(SEC_ERROR_NO_TOKEN);
}
if (!co) {
- return NULL;
+ 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;
+ nssCryptokiObject_Destroy(co);
+ return NULL;
}
/* Create a certificate */
c = nssCertificate_Create(pkio);
if (!c) {
- nssPKIObject_Destroy(pkio);
- return NULL;
+ nssPKIObject_Destroy(pkio);
+ return NULL;
}
- /* Build and output a nickname, if desired.
+ /* 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;
+ CK_ATTRIBUTE label, id;
- label.type = CKA_LABEL;
- label.pValue = co->label;
- label.ulValueLen = PORT_Strlen(co->label);
+ 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;
+ id.type = CKA_ID;
+ id.pValue = c->id.data;
+ id.ulValueLen = c->id.size;
- *nickptr = pk11_buildNickname(slot, &label, privateLabel, &id);
+ *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
+ * 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. :)
*/
@@ -288,78 +296,77 @@ pk11_fastCert(PK11SlotInfo *slot, CK_OBJECT_HANDLE certID,
* Must be a CertObject. This code does not explicitly checks that.
*/
CERTCertificate *
-PK11_MakeCertFromHandle(PK11SlotInfo *slot,CK_OBJECT_HANDLE certID,
- CK_ATTRIBUTE *privateLabel)
+PK11_MakeCertFromHandle(PK11SlotInfo *slot, CK_OBJECT_HANDLE certID,
+ CK_ATTRIBUTE *privateLabel)
{
- char * nickname = NULL;
+ char *nickname = NULL;
CERTCertificate *cert = NULL;
CERTCertTrust *trust;
- cert = pk11_fastCert(slot,certID,privateLabel, &nickname);
- if (cert == NULL)
- goto loser;
+ 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;
+ if (cert->nickname != NULL) {
+ cert->dbnickname = cert->nickname;
+ }
+ cert->nickname = PORT_ArenaStrdup(cert->arena, nickname);
+ PORT_Free(nickname);
+ nickname = NULL;
}
/* 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;
- }
- }
- 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->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;
+ }
+ }
+ 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;
@@ -368,14 +375,13 @@ PK11_MakeCertFromHandle(PK11SlotInfo *slot,CK_OBJECT_HANDLE certID,
return cert;
loser:
- if (nickname)
- PORT_Free(nickname);
- if (cert)
- CERT_DestroyCertificate(cert);
+ if (nickname)
+ PORT_Free(nickname);
+ if (cert)
+ CERT_DestroyCertificate(cert);
return NULL;
}
-
/*
* Build get a certificate from a private key
*/
@@ -384,17 +390,16 @@ PK11_GetCertFromPrivateKey(SECKEYPrivateKey *privKey)
{
PK11SlotInfo *slot = privKey->pkcs11Slot;
CK_OBJECT_HANDLE handle = privKey->pkcs11ID;
- CK_OBJECT_HANDLE certID =
- PK11_MatchItem(slot,handle,CKO_CERTIFICATE);
+ 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;
+ PORT_SetError(SSL_ERROR_NO_CERTIFICATE);
+ return NULL;
}
- cert = PK11_MakeCertFromHandle(slot,certID,NULL);
+ cert = PK11_MakeCertFromHandle(slot, certID, NULL);
return (cert);
-
}
/*
@@ -402,20 +407,20 @@ PK11_GetCertFromPrivateKey(SECKEYPrivateKey *privKey)
* private key.
*/
SECStatus
-PK11_DeleteTokenCertAndKey(CERTCertificate *cert,void *wincx)
+PK11_DeleteTokenCertAndKey(CERTCertificate *cert, void *wincx)
{
- SECKEYPrivateKey *privKey = PK11_FindKeyByAnyCert(cert,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);
+ /* 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);
+ if ((pubKey != CK_INVALID_HANDLE) && (slot != NULL)) {
+ PK11_DestroyTokenObject(slot, pubKey);
PK11_FreeSlot(slot);
}
return SECSuccess;
@@ -425,25 +430,24 @@ PK11_DeleteTokenCertAndKey(CERTCertificate *cert,void *wincx)
* cert callback structure
*/
typedef struct pk11DoCertCallbackStr {
- SECStatus(* callback)(PK11SlotInfo *slot, CERTCertificate*, void *);
- SECStatus(* noslotcallback)(CERTCertificate*, void *);
- SECStatus(* itemcallback)(CERTCertificate*, SECItem *, void *);
- void *callbackArg;
+ 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;
+ SECStatus (*callback)(CERTCertificate *, SECItem *, void *);
+ void *callbackArg;
} pk11CertCallback;
-struct fake_der_cb_argstr
-{
- SECStatus(* callback)(CERTCertificate*, SECItem *, void *);
+struct fake_der_cb_argstr {
+ SECStatus (*callback)(CERTCertificate *, SECItem *, void *);
void *arg;
};
-static SECStatus fake_der_cb(CERTCertificate *c, void *a)
+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);
@@ -453,15 +457,15 @@ static SECStatus fake_der_cb(CERTCertificate *c, void *a)
* Extract all the certs on a card from a slot.
*/
SECStatus
-PK11_TraverseSlotCerts(SECStatus(* callback)(CERTCertificate*,SECItem *,void *),
- void *arg, void *wincx)
+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);
+ (void)pk11_TraverseAllSlots(NULL, NULL, PR_TRUE, wincx);
fda.callback = callback;
fda.arg = arg;
@@ -472,7 +476,7 @@ PK11_TraverseSlotCerts(SECStatus(* callback)(CERTCertificate*,SECItem *,void *),
}
static void
-transfer_token_certs_to_collection(nssList *certList, NSSToken *token,
+transfer_token_certs_to_collection(nssList *certList, NSSToken *token,
nssPKIObjectCollection *collection)
{
NSSCertificate **certs;
@@ -480,37 +484,37 @@ transfer_token_certs_to_collection(nssList *certList, NSSToken *token,
NSSToken **tokens, **tp;
count = nssList_Count(certList);
if (count == 0) {
- return;
+ return;
}
certs = nss_ZNEWARRAY(NULL, NSSCertificate *, count);
if (!certs) {
- return;
+ 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]));
+ 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)
+PK11_FindCertFromNickname(const char *nickname, void *wincx)
{
PRStatus status;
CERTCertificate *rvCert = NULL;
NSSCertificate *cert = NULL;
NSSCertificate **certs = NULL;
- static const NSSUsage usage = {PR_TRUE /* ... */ };
+ static const NSSUsage usage = { PR_TRUE /* ... */ };
NSSToken *token;
NSSTrustDomain *defaultTD = STAN_GetDefaultTrustDomain();
PK11SlotInfo *slot = NULL;
@@ -524,180 +528,180 @@ PK11_FindCertFromNickname(const char *nickname, void *wincx)
/* 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 = ':';
+ 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);
+ 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);
+ 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);
+ PK11_FreeSlot(slot);
}
- if (nickCopy) PORT_Free(nickCopy);
+ if (nickCopy)
+ PORT_Free(nickCopy);
return rvCert;
loser:
if (slot) {
- PK11_FreeSlot(slot);
+ PK11_FreeSlot(slot);
}
- if (nickCopy) PORT_Free(nickCopy);
+ if (nickCopy)
+ PORT_Free(nickCopy);
return NULL;
}
/* Traverse slots callback */
typedef struct FindCertsEmailArgStr {
- char *email;
+ char *email;
CERTCertList *certList;
} FindCertsEmailArg;
-SECStatus
+SECStatus
FindCertsEmailCallback(CERTCertificate *cert, SECItem *item, void *arg)
{
- FindCertsEmailArg *cbparam = (FindCertsEmailArg *) 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;
+ if (cert_email == NULL) {
+ return SECSuccess;
}
-
+
/* Parameter correctly set? */
if (cbparam->email == NULL) {
- return SECFailure;
+ 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);
+ 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)
+PK11_FindCertsFromEmailAddress(const char *email, void *wincx)
{
FindCertsEmailArg cbparam;
SECStatus rv;
cbparam.certList = CERT_NewCertList();
if (cbparam.certList == NULL) {
- return NULL;
+ return NULL;
}
cbparam.email = CERT_FixupEmailAddr(email);
if (cbparam.email == NULL) {
- CERT_DestroyCertList(cbparam.certList);
- return NULL;
+ CERT_DestroyCertList(cbparam.certList);
+ return NULL;
}
- rv = PK11_TraverseSlotCerts(FindCertsEmailCallback, &cbparam, NULL);
+ rv = PK11_TraverseSlotCerts(FindCertsEmailCallback, &cbparam, NULL);
if (rv != SECSuccess) {
- CERT_DestroyCertList(cbparam.certList);
- PORT_Free(cbparam.email);
- return NULL;
+ CERT_DestroyCertList(cbparam.certList);
+ PORT_Free(cbparam.email);
+ return NULL;
}
/* empty list? */
- if (CERT_LIST_HEAD(cbparam.certList) == NULL ||
+ if (CERT_LIST_HEAD(cbparam.certList) == NULL ||
CERT_LIST_END(CERT_LIST_HEAD(cbparam.certList), cbparam.certList)) {
- CERT_DestroyCertList(cbparam.certList);
- cbparam.certList = NULL;
+ CERT_DestroyCertList(cbparam.certList);
+ cbparam.certList = NULL;
}
PORT_Free(cbparam.email);
return cbparam.certList;
}
-
CERTCertList *
-PK11_FindCertsFromNickname(const char *nickname, void *wincx)
+PK11_FindCertsFromNickname(const char *nickname, void *wincx)
{
char *nickCopy;
char *delimit = NULL;
@@ -717,67 +721,69 @@ PK11_FindCertsFromNickname(const char *nickname, void *wincx)
/* 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 = ':';
+ 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);
+ 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);
+ 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);
+ PORT_Strchr(nickname, '@') != NULL) {
+ char *lowercaseName = CERT_FixupEmailAddr(nickname);
if (lowercaseName) {
- (void)nssTrustDomain_GetCertsForEmailAddressFromCache(defaultTD,
- lowercaseName,
+ (void)nssTrustDomain_GetCertsForEmailAddressFromCache(defaultTD,
+ lowercaseName,
nameList);
transfer_token_certs_to_collection(nameList, token, collection);
instances = nssToken_FindCertificatesByEmail(token,
@@ -793,36 +799,37 @@ PK11_FindCertsFromNickname(const char *nickname, void *wincx)
}
nssList_Destroy(nameList);
- foundCerts = nssPKIObjectCollection_GetCertificates(collection,
- NULL, 0, NULL);
- nssPKIObjectCollection_Destroy(collection);
+ foundCerts = nssPKIObjectCollection_GetCertificates(collection,
+ NULL, 0, NULL);
+ nssPKIObjectCollection_Destroy(collection);
}
if (slot) {
- PK11_FreeSlot(slot);
+ PK11_FreeSlot(slot);
}
- if (nickCopy) PORT_Free(nickCopy);
+ 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);
+ 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;
}
@@ -833,30 +840,31 @@ PK11_FindCertsFromNickname(const char *nickname, void *wincx)
* pkcs11 to extract the public key (we currently do not), this will break.
*/
SECItem *
-PK11_GetPubIndexKeyID(CERTCertificate *cert)
+PK11_GetPubIndexKeyID(CERTCertificate *cert)
{
SECKEYPublicKey *pubk;
SECItem *newItem = NULL;
pubk = CERT_ExtractPublicKey(cert);
- if (pubk == NULL) return NULL;
+ 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... */
+ 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 */
@@ -867,15 +875,16 @@ PK11_GetPubIndexKeyID(CERTCertificate *cert)
* generate a CKA_ID from a certificate.
*/
SECItem *
-pk11_mkcertKeyID(CERTCertificate *cert)
+pk11_mkcertKeyID(CERTCertificate *cert)
{
- SECItem *pubKeyData = PK11_GetPubIndexKeyID(cert) ;
+ SECItem *pubKeyData = PK11_GetPubIndexKeyID(cert);
SECItem *certCKA_ID;
- if (pubKeyData == NULL) return NULL;
-
+ if (pubKeyData == NULL)
+ return NULL;
+
certCKA_ID = PK11_MakeIDFromPubKey(pubKeyData);
- SECITEM_FreeItem(pubKeyData,PR_TRUE);
+ SECITEM_FreeItem(pubKeyData, PR_TRUE);
return certCKA_ID;
}
@@ -883,9 +892,9 @@ pk11_mkcertKeyID(CERTCertificate *cert)
* Write the cert into the token.
*/
SECStatus
-PK11_ImportCert(PK11SlotInfo *slot, CERTCertificate *cert,
- CK_OBJECT_HANDLE key, const char *nickname,
- PRBool includeTrust)
+PK11_ImportCert(PK11SlotInfo *slot, CERTCertificate *cert,
+ CK_OBJECT_HANDLE key, const char *nickname,
+ PRBool includeTrust)
{
PRStatus status;
NSSCertificate *c;
@@ -893,54 +902,54 @@ PK11_ImportCert(PK11SlotInfo *slot, CERTCertificate *cert,
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};
+ 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 */
+ goto loser; /* error code should be set already */
}
if (!token) {
- PORT_SetError(SEC_ERROR_NO_TOKEN);
- goto loser;
+ PORT_SetError(SEC_ERROR_NO_TOKEN);
+ goto loser;
}
if (PK11_IsInternal(slot) && cert->emailAddr && cert->emailAddr[0]) {
- emailAddr = cert->emailAddr;
+ emailAddr = cert->emailAddr;
}
/* need to get the cert as a stan cert */
if (cert->nssCertificate) {
- c = cert->nssCertificate;
+ c = cert->nssCertificate;
} else {
- c = STAN_GetNSSCertificate(cert);
- if (c == NULL) {
- goto loser;
- }
+ 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;
+ 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;
- }
+ /* 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 */
@@ -952,26 +961,26 @@ PK11_ImportCert(PK11SlotInfo *slot, CERTCertificate *cert,
&c->issuer,
&c->subject,
&c->serial,
- emailAddr,
+ 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 (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;
+ /* 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
@@ -985,30 +994,31 @@ PK11_ImportCert(PK11SlotInfo *slot, CERTCertificate *cert,
nssTrustDomain_AddCertsToCache(STAN_GetDefaultTrustDomain(), &c, 1);
(void)STAN_ForceCERTCertificateUpdate(c);
nssCertificate_Destroy(c);
- SECITEM_FreeItem(keyID,PR_TRUE);
+ SECITEM_FreeItem(keyID, PR_TRUE);
return SECSuccess;
loser:
CERT_MapStanError();
- SECITEM_FreeItem(keyID,PR_TRUE);
+ SECITEM_FreeItem(keyID, PR_TRUE);
if (PORT_GetError() != SEC_ERROR_TOKEN_NOT_LOGGED_IN) {
- PORT_SetError(SEC_ERROR_ADDING_CERT);
+ PORT_SetError(SEC_ERROR_ADDING_CERT);
}
return SECFailure;
}
SECStatus
PK11_ImportDERCert(PK11SlotInfo *slot, SECItem *derCert,
- CK_OBJECT_HANDLE key, char *nickname, PRBool includeTrust)
+ 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;
+ if (cert == NULL)
+ return SECFailure;
rv = PK11_ImportCert(slot, cert, key, nickname, includeTrust);
- CERT_DestroyCertificate (cert);
+ CERT_DestroyCertificate(cert);
return rv;
}
@@ -1016,21 +1026,21 @@ PK11_ImportDERCert(PK11SlotInfo *slot, SECItem *derCert,
* get a certificate handle, look at the cached handle first..
*/
CK_OBJECT_HANDLE
-pk11_getcerthandle(PK11SlotInfo *slot, CERTCertificate *cert,
- CK_ATTRIBUTE *theTemplate,int tsize)
+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;
- }
+ 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);
+ certh = pk11_FindObjectByTemplate(slot, theTemplate, tsize);
}
return certh;
}
@@ -1040,24 +1050,25 @@ pk11_getcerthandle(PK11SlotInfo *slot, CERTCertificate *cert,
*/
SECKEYPrivateKey *
PK11_FindPrivateKeyFromCert(PK11SlotInfo *slot, CERTCertificate *cert,
- void *wincx)
+ void *wincx)
{
int err;
CK_OBJECT_CLASS certClass = CKO_CERTIFICATE;
CK_ATTRIBUTE theTemplate[] = {
- { CKA_VALUE, NULL, 0 },
- { CKA_CLASS, NULL, 0 }
+ { 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]);
+ 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_VALUE, cert->derCert.data,
+ cert->derCert.len);
+ attrs++;
PK11_SETATTRS(attrs, CKA_CLASS, &certClass, sizeof(certClass));
/*
@@ -1065,45 +1076,45 @@ PK11_FindPrivateKeyFromCert(PK11SlotInfo *slot, CERTCertificate *cert,
*/
rv = pk11_AuthenticateUnfriendly(slot, PR_TRUE, wincx);
if (rv != SECSuccess) {
- return NULL;
+ return NULL;
}
- certh = pk11_getcerthandle(slot,cert,theTemplate,tsize);
+ certh = pk11_getcerthandle(slot, cert, theTemplate, tsize);
if (certh == CK_INVALID_HANDLE) {
- return NULL;
+ return NULL;
}
/*
* prevent a login race condition. If slot is logged in between
- * our call to pk11_LoginStillRequired and the
+ * 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
+ * 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);
+ 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;
+ (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)
+PK11_KeyForCertExists(CERTCertificate *cert, CK_OBJECT_HANDLE *keyPtr,
+ void *wincx)
{
PK11SlotList *list;
PK11SlotListElement *le;
@@ -1115,51 +1126,54 @@ PK11_KeyForCertExists(CERTCertificate *cert, CK_OBJECT_HANDLE *keyPtr,
keyID = pk11_mkcertKeyID(cert);
/* get them all! */
- list = PK11_GetAllTokens(CKM_INVALID_MECHANISM,PR_FALSE,PR_TRUE,wincx);
+ 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;
+ 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);
+ 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)
+PK11_KeyForDERCertExists(SECItem *derCert, CK_OBJECT_HANDLE *keyPtr,
+ void *wincx)
{
CERTCertificate *cert;
PK11SlotInfo *slot = NULL;
@@ -1168,52 +1182,54 @@ PK11_KeyForDERCertExists(SECItem *derCert, CK_OBJECT_HANDLE *keyPtr,
* to get the ID attribute.
*/
cert = CERT_DecodeDERCertificate(derCert, PR_FALSE, NULL);
- if (cert == NULL) return NULL;
+ if (cert == NULL)
+ return NULL;
slot = PK11_KeyForCertExists(cert, keyPtr, wincx);
- CERT_DestroyCertificate (cert);
+ CERT_DestroyCertificate(cert);
return slot;
}
PK11SlotInfo *
PK11_ImportCertForKey(CERTCertificate *cert, const char *nickname,
- void *wincx)
+ void *wincx)
{
PK11SlotInfo *slot = NULL;
CK_OBJECT_HANDLE key;
- slot = PK11_KeyForCertExists(cert,&key,wincx);
+ slot = PK11_KeyForCertExists(cert, &key, wincx);
if (slot) {
- if (PK11_ImportCert(slot,cert,key,nickname,PR_FALSE) != SECSuccess) {
- PK11_FreeSlot(slot);
- slot = NULL;
- }
+ if (PK11_ImportCert(slot, cert, key, nickname, PR_FALSE) != SECSuccess) {
+ PK11_FreeSlot(slot);
+ slot = NULL;
+ }
} else {
- PORT_SetError(SEC_ERROR_ADDING_CERT);
+ PORT_SetError(SEC_ERROR_ADDING_CERT);
}
return slot;
}
PK11SlotInfo *
-PK11_ImportDERCertForKey(SECItem *derCert, char *nickname,void *wincx)
+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;
+ if (cert == NULL)
+ return NULL;
slot = PK11_ImportCertForKey(cert, nickname, wincx);
- CERT_DestroyCertificate (cert);
+ CERT_DestroyCertificate(cert);
return slot;
}
static CK_OBJECT_HANDLE
-pk11_FindCertObjectByTemplate(PK11SlotInfo **slotPtr,
- CK_ATTRIBUTE *searchTemplate, int count, void *wincx)
+pk11_FindCertObjectByTemplate(PK11SlotInfo **slotPtr,
+ CK_ATTRIBUTE *searchTemplate, int count, void *wincx)
{
PK11SlotList *list;
PK11SlotListElement *le;
@@ -1224,36 +1240,36 @@ pk11_FindCertObjectByTemplate(PK11SlotInfo **slotPtr,
*slotPtr = NULL;
/* get them all! */
- list = PK11_GetAllTokens(CKM_INVALID_MECHANISM,PR_FALSE,PR_TRUE,wincx);
+ list = PK11_GetAllTokens(CKM_INVALID_MECHANISM, PR_FALSE, PR_TRUE, wincx);
if (list == NULL) {
- return CK_INVALID_HANDLE;
+ 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;
- }
+ 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;
+ return CK_INVALID_HANDLE;
}
*slotPtr = slot;
return certHandle;
}
CERTCertificate *
-PK11_FindCertByIssuerAndSNOnToken(PK11SlotInfo *slot,
- CERTIssuerAndSN *issuerSN, void *wincx)
+PK11_FindCertByIssuerAndSNOnToken(PK11SlotInfo *slot,
+ CERTIssuerAndSN *issuerSN, void *wincx)
{
CERTCertificate *rvCert = NULL;
NSSCertificate *cert = NULL;
@@ -1267,20 +1283,19 @@ PK11_FindCertByIssuerAndSNOnToken(PK11SlotInfo *slot,
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;
+ !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;
+ 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).
@@ -1289,7 +1304,7 @@ PK11_FindCertByIssuerAndSNOnToken(PK11SlotInfo *slot,
&issuerSN->serialNumber,
SEC_ASN1_GET(SEC_IntegerTemplate));
if (!derSerial) {
- return NULL;
+ return NULL;
}
NSSITEM_FROM_SECITEM(&issuer, &issuerSN->derIssuer);
@@ -1297,44 +1312,44 @@ PK11_FindCertByIssuerAndSNOnToken(PK11SlotInfo *slot,
session = nssToken_GetDefaultSession(token);
if (!session) {
- goto loser;
+ goto loser;
}
- instance = nssToken_FindCertificateByIssuerAndSerialNumber(token,session,
- &issuer, &serial, nssTokenSearchType_TokenForced, &status);
+ instance = nssToken_FindCertificateByIssuerAndSerialNumber(token, session,
+ &issuer, &serial, nssTokenSearchType_TokenForced, &status);
SECITEM_FreeItem(derSerial, PR_TRUE);
if (!instance) {
- goto loser;
+ goto loser;
}
object = nssPKIObject_Create(NULL, instance, td, NULL, nssPKIMonitor);
if (!object) {
- goto loser;
+ goto loser;
}
instance = NULL; /* adopted by the previous call */
cert = nssCertificate_Create(object);
if (!cert) {
- goto loser;
+ goto loser;
}
object = NULL; /* adopted by the previous call */
- nssTrustDomain_AddCertsToCache(td, &cert,1);
+ nssTrustDomain_AddCertsToCache(td, &cert, 1);
/* on failure, cert is freed below */
rvCert = STAN_GetCERTCertificate(cert);
if (!rvCert) {
- goto loser;
+ goto loser;
}
return rvCert;
loser:
if (instance) {
- nssCryptokiObject_Destroy(instance);
+ nssCryptokiObject_Destroy(instance);
}
if (object) {
- nssPKIObject_Destroy(object);
+ nssPKIObject_Destroy(object);
}
if (cert) {
- nssCertificate_Destroy(cert);
+ nssCertificate_Destroy(cert);
}
return NULL;
}
@@ -1344,28 +1359,28 @@ static PRCallOnceType keyIDHashCallOnce;
static PRStatus PR_CALLBACK
pk11_keyIDHash_populate(void *wincx)
{
- CERTCertList *certList;
+ CERTCertList *certList;
CERTCertListNode *node = NULL;
- SECItem subjKeyID = {siBuffer, NULL, 0};
- SECItem *slotid = NULL;
+ SECItem subjKeyID = { siBuffer, NULL, 0 };
+ SECItem *slotid = NULL;
SECMODModuleList *modules, *mlp;
- SECMODListLock *moduleLock;
- int i;
+ SECMODListLock *moduleLock;
+ int i;
certList = PK11_ListCerts(PK11CertListUser, wincx);
if (!certList) {
- return PR_FAILURE;
+ 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);
- }
+ if (CERT_FindSubjectKeyIDExtension(node->cert,
+ &subjKeyID) == SECSuccess &&
+ subjKeyID.data != NULL) {
+ cert_AddSubjectKeyIDMapping(&subjKeyID, node->cert);
+ SECITEM_FreeItem(&subjKeyID, PR_FALSE);
+ }
}
CERT_DestroyCertList(certList);
@@ -1376,26 +1391,26 @@ pk11_keyIDHash_populate(void *wincx)
slotid = SECITEM_AllocItem(NULL, NULL,
sizeof(CK_SLOT_ID) + sizeof(SECMODModuleID));
if (!slotid) {
- PORT_SetError(SEC_ERROR_NO_MEMORY);
- return PR_FAILURE;
+ PORT_SetError(SEC_ERROR_NO_MEMORY);
+ return PR_FAILURE;
}
moduleLock = SECMOD_GetDefaultModuleListLock();
if (!moduleLock) {
- SECITEM_FreeItem(slotid, PR_TRUE);
- PORT_SetError(SEC_ERROR_NOT_INITIALIZED);
- return PR_FAILURE;
+ SECITEM_FreeItem(slotid, PR_TRUE);
+ 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);
- }
+ 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);
@@ -1411,102 +1426,102 @@ pk11_keyIDHash_populate(void *wincx)
* (they should be!)
*/
static CERTCertificate *
-pk11_FindCertObjectByRecipientNew(PK11SlotInfo *slot, NSSCMSRecipient **recipientlist, int *rlIndex, void *pwarg)
+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);
- PK11_FreeSlotList(sl);
- 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;
- }
+ 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);
+ PK11_FreeSlotList(sl);
+ 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;
@@ -1527,20 +1542,21 @@ pk11_AllFindCertObjectByRecipientNew(NSSCMSRecipient **recipientlist, void *winc
SECStatus rv;
/* get them all! */
- list = PK11_GetAllTokens(CKM_INVALID_MECHANISM,PR_FALSE,PR_TRUE,wincx);
+ list = PK11_GetAllTokens(CKM_INVALID_MECHANISM, PR_FALSE, PR_TRUE, wincx);
if (list == NULL) {
- return CK_INVALID_HANDLE;
+ 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;
+ 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;
+ cert = pk11_FindCertObjectByRecipientNew(le->slot,
+ recipientlist, rlIndex, wincx);
+ if (cert)
+ break;
}
PK11_FreeSlotList(list);
@@ -1553,30 +1569,29 @@ pk11_AllFindCertObjectByRecipientNew(NSSCMSRecipient **recipientlist, void *winc
* list of recipients. This searches one slot.
*/
static CERTCertificate *
-pk11_FindCertObjectByRecipient(PK11SlotInfo *slot,
- SEC_PKCS7RecipientInfo **recipientArray,
- SEC_PKCS7RecipientInfo **rip, void *pwarg)
+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;
+ for (i = 0; (ri = recipientArray[i]) != NULL; i++) {
+ CERTCertificate *cert;
- cert = PK11_FindCertByIssuerAndSNOnToken(slot, ri->issuerAndSN,
- pwarg);
+ 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;
- }
-
+ /* 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;
@@ -1586,43 +1601,45 @@ pk11_FindCertObjectByRecipient(PK11SlotInfo *slot,
* 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)
+pk11_AllFindCertObjectByRecipient(PK11SlotInfo **slotPtr,
+ SEC_PKCS7RecipientInfo **recipientArray,
+ SEC_PKCS7RecipientInfo **rip,
+ void *wincx)
{
PK11SlotList *list;
PK11SlotListElement *le;
- CERTCertificate * cert = NULL;
+ CERTCertificate *cert = NULL;
PK11SlotInfo *slot = NULL;
SECStatus rv;
*slotPtr = NULL;
/* get them all! */
- list = PK11_GetAllTokens(CKM_INVALID_MECHANISM,PR_FALSE,PR_TRUE,wincx);
+ list = PK11_GetAllTokens(CKM_INVALID_MECHANISM, PR_FALSE, PR_TRUE, wincx);
if (list == NULL) {
- return CK_INVALID_HANDLE;
+ 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;
+ 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;
- }
+ cert = pk11_FindCertObjectByRecipient(le->slot, recipientArray,
+ rip, wincx);
+ if (cert) {
+ slot = PK11_ReferenceSlot(le->slot);
+ break;
+ }
}
PK11_FreeSlotList(list);
if (slot == NULL) {
- return NULL;
+ return NULL;
}
*slotPtr = slot;
PORT_Assert(cert != NULL);
@@ -1637,28 +1654,31 @@ pk11_AllFindCertObjectByRecipient(PK11SlotInfo **slotPtr,
* the key...
*/
CERTCertificate *
-PK11_FindCertAndKeyByRecipientList(PK11SlotInfo **slotPtr,
- SEC_PKCS7RecipientInfo **array, SEC_PKCS7RecipientInfo **rip,
- SECKEYPrivateKey**privKey, void *wincx)
+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);
+ cert = pk11_AllFindCertObjectByRecipient(slotPtr, array, rip, wincx);
if (!cert) {
- return NULL;
+ return NULL;
}
*privKey = PK11_FindKeyByAnyCert(cert, wincx);
if (*privKey == NULL) {
- goto loser;
+ goto loser;
}
return cert;
loser:
- if (cert) CERT_DestroyCertificate(cert);
- if (*slotPtr) PK11_FreeSlot(*slotPtr);
+ if (cert)
+ CERT_DestroyCertificate(cert);
+ if (*slotPtr)
+ PK11_FreeSlot(*slotPtr);
*slotPtr = NULL;
return NULL;
}
@@ -1678,11 +1698,11 @@ PK11_FindCertAndKeyByRecipientListNew(NSSCMSRecipient **recipientlist, void *win
rv = PR_CallOnceWithArg(&keyIDHashCallOnce, pk11_keyIDHash_populate, wincx);
if (rv != PR_SUCCESS)
- return -1;
+ return -1;
cert = pk11_AllFindCertObjectByRecipientNew(recipientlist, wincx, &rlIndex);
if (!cert) {
- return -1;
+ return -1;
}
rl = recipientlist[rlIndex];
@@ -1691,7 +1711,7 @@ PK11_FindCertAndKeyByRecipientListNew(NSSCMSRecipient **recipientlist, void *win
rl->privkey = PK11_FindKeyByAnyCert(cert, wincx);
if (rl->privkey == NULL) {
- goto loser;
+ goto loser;
}
/* make a cert from the cert handle */
@@ -1699,15 +1719,17 @@ PK11_FindCertAndKeyByRecipientListNew(NSSCMSRecipient **recipientlist, void *win
return rlIndex;
loser:
- if (cert) CERT_DestroyCertificate(cert);
- if (rl->slot) PK11_FreeSlot(rl->slot);
+ 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)
+ void *wincx)
{
CERTCertificate *rvCert = NULL;
NSSCertificate *cert;
@@ -1716,14 +1738,15 @@ PK11_FindCertByIssuerAndSN(PK11SlotInfo **slotPtr, CERTIssuerAndSN *issuerSN,
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;
+ !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;
+ 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
@@ -1733,45 +1756,46 @@ PK11_FindCertByIssuerAndSN(PK11SlotInfo **slotPtr, CERTIssuerAndSN *issuerSN,
&issuerSN->serialNumber,
SEC_ASN1_GET(SEC_IntegerTemplate));
if (!derSerial) {
- return NULL;
+ return NULL;
}
NSSITEM_FROM_SECITEM(&issuer, &issuerSN->derIssuer);
NSSITEM_FROM_SECITEM(&serial, derSerial);
cc = STAN_GetDefaultCryptoContext();
- cert = NSSCryptoContext_FindCertificateByIssuerAndSerialNumber(cc,
- &issuer,
- &serial);
+ cert = NSSCryptoContext_FindCertificateByIssuerAndSerialNumber(cc,
+ &issuer,
+ &serial);
if (cert) {
- SECITEM_FreeItem(derSerial, PR_TRUE);
- return STAN_GetCERTCertificateOrRelease(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 */
+ /* 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);
+ if (rvCert && slotPtr)
+ *slotPtr = PK11_ReferenceSlot(rvCert->slot);
SECITEM_FreeItem(derSerial, PR_TRUE);
return rvCert;
@@ -1783,37 +1807,38 @@ 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 },
+ CK_ATTRIBUTE searchTemplate[] = {
+ { CKA_CLASS, NULL, 0 },
+ { CKA_VALUE, NULL, 0 },
};
- int templateSize = sizeof(searchTemplate)/sizeof(searchTemplate[0]);
+ int templateSize = sizeof(searchTemplate) / sizeof(searchTemplate[0]);
attr = searchTemplate;
- PK11_SETATTRS(attr, CKA_CLASS, &certClass, sizeof(certClass)); attr++;
+ 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_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;
- }
+ if (cert->slot == NULL) {
+ cert->slot = PK11_ReferenceSlot(*pSlot);
+ cert->pkcs11ID = certHandle;
+ cert->ownSlot = PR_TRUE;
+ cert->series = cert->slot->series;
+ }
}
- return(certHandle);
+ return (certHandle);
}
SECKEYPrivateKey *
@@ -1829,31 +1854,31 @@ PK11_FindKeyByAnyCert(CERTCertificate *cert, void *wincx)
certHandle = PK11_FindObjectForCert(cert, wincx, &slot);
if (certHandle == CK_INVALID_HANDLE) {
- return NULL;
+ return NULL;
}
/*
* prevent a login race condition. If slot is logged in between
- * our call to pk11_LoginStillRequired and the
+ * 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
+ * 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);
+ 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);
+ PK11_FreeSlot(slot);
}
return privKey;
}
@@ -1866,12 +1891,12 @@ pk11_FindPubKeyByAnyCert(CERTCertificate *cert, PK11SlotInfo **slot, void *wincx
certHandle = PK11_FindObjectForCert(cert, wincx, slot);
if (certHandle == CK_INVALID_HANDLE) {
- return 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;
+ keyHandle = PK11_MatchItem(*slot, certHandle, CKO_PUBLIC_KEY);
+ if (keyHandle == CK_INVALID_HANDLE) {
+ PK11_FreeSlot(*slot);
+ return CK_INVALID_HANDLE;
}
return keyHandle;
}
@@ -1884,35 +1909,36 @@ PK11_NumberCertsForCertSubject(CERTCertificate *cert)
{
CK_OBJECT_CLASS certClass = CKO_CERTIFICATE;
CK_ATTRIBUTE theTemplate[] = {
- { CKA_CLASS, NULL, 0 },
- { CKA_SUBJECT, NULL, 0 },
+ { CKA_CLASS, NULL, 0 },
+ { CKA_SUBJECT, NULL, 0 },
};
CK_ATTRIBUTE *attr = theTemplate;
- int templateSize = sizeof(theTemplate)/sizeof(theTemplate[0]);
+ 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);
+ 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;
+ PK11SlotList *list = PK11_GetAllTokens(CKM_INVALID_MECHANISM,
+ PR_FALSE, PR_TRUE, NULL);
+ PK11SlotListElement *le;
+ int count = 0;
- if (!list) {
+ 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;
+ /* 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);
+ return PK11_NumberObjectsFor(cert->slot, theTemplate, templateSize);
}
/*
@@ -1920,27 +1946,26 @@ PK11_NumberCertsForCertSubject(CERTCertificate *cert)
*/
SECStatus
PK11_TraverseCertsForSubject(CERTCertificate *cert,
- SECStatus(* callback)(CERTCertificate*, void *), void *arg)
+ SECStatus (*callback)(CERTCertificate *, void *), void *arg)
{
- if(!cert) {
- return SECFailure;
+ if (!cert) {
+ return SECFailure;
}
if (cert->slot == NULL) {
- PK11SlotList *list = PK11_GetAllTokens(CKM_INVALID_MECHANISM,
- PR_FALSE,PR_TRUE,NULL);
- PK11SlotListElement *le;
+ PK11SlotList *list = PK11_GetAllTokens(CKM_INVALID_MECHANISM,
+ PR_FALSE, PR_TRUE, NULL);
+ PK11SlotListElement *le;
- if (!list) {
+ 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;
-
+ }
+ /* 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);
@@ -1948,7 +1973,7 @@ PK11_TraverseCertsForSubject(CERTCertificate *cert,
SECStatus
PK11_TraverseCertsForSubjectInSlot(CERTCertificate *cert, PK11SlotInfo *slot,
- SECStatus(* callback)(CERTCertificate*, void *), void *arg)
+ SECStatus (*callback)(CERTCertificate *, void *), void *arg)
{
PRStatus nssrv = PR_SUCCESS;
NSSToken *token;
@@ -1963,23 +1988,23 @@ PK11_TraverseCertsForSubjectInSlot(CERTCertificate *cert, PK11SlotInfo *slot,
NSSITEM_FROM_SECITEM(&subject, &cert->derSubject);
token = PK11Slot_GetNSSToken(slot);
if (!nssToken_IsPresent(token)) {
- return SECSuccess;
+ return SECSuccess;
}
collection = nssCertificateCollection_Create(td, NULL);
if (!collection) {
- return SECFailure;
+ return SECFailure;
}
subjectList = nssList_Create(NULL, PR_FALSE);
if (!subjectList) {
- nssPKIObjectCollection_Destroy(collection);
- return SECFailure;
+ nssPKIObjectCollection_Destroy(collection);
+ return SECFailure;
}
- (void)nssTrustDomain_GetCertsForSubjectFromCache(td, &subject,
+ (void)nssTrustDomain_GetCertsForSubjectFromCache(td, &subject,
subjectList);
transfer_token_certs_to_collection(subjectList, token, collection);
instances = nssToken_FindCertificatesBySubject(token, NULL,
- &subject,
- tokenOnly, 0, &nssrv);
+ &subject,
+ tokenOnly, 0, &nssrv);
nssPKIObjectCollection_AddInstances(collection, instances, 0);
nss_ZFreeIf(instances);
nssList_Destroy(subjectList);
@@ -1987,26 +2012,26 @@ PK11_TraverseCertsForSubjectInSlot(CERTCertificate *cert, PK11SlotInfo *slot,
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);
+ 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)
+ SECStatus (*callback)(CERTCertificate *, void *), void *arg)
{
PRStatus nssrv = PR_SUCCESS;
NSSToken *token;
@@ -2020,29 +2045,29 @@ PK11_TraverseCertsForNicknameInSlot(SECItem *nickname, PK11SlotInfo *slot,
nssTokenSearchType tokenOnly = nssTokenSearchType_TokenOnly;
token = PK11Slot_GetNSSToken(slot);
if (!nssToken_IsPresent(token)) {
- return SECSuccess;
+ return SECSuccess;
}
- if (nickname->data[nickname->len-1] != '\0') {
- nick = nssUTF8_Create(NULL, nssStringType_UTF8String,
- nickname->data, nickname->len);
- created = PR_TRUE;
+ 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;
+ nick = (NSSUTF8 *)nickname->data;
}
td = STAN_GetDefaultTrustDomain();
collection = nssCertificateCollection_Create(td, NULL);
if (!collection) {
- goto loser;
+ goto loser;
}
nameList = nssList_Create(NULL, PR_FALSE);
if (!nameList) {
- goto loser;
+ 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);
+ nick,
+ tokenOnly, 0, &nssrv);
nssPKIObjectCollection_AddInstances(collection, instances, 0);
nss_ZFreeIf(instances);
nssList_Destroy(nameList);
@@ -2050,38 +2075,39 @@ PK11_TraverseCertsForNicknameInSlot(SECItem *nickname, PK11SlotInfo *slot,
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);
+ 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);
+ nss_ZFreeIf(nick);
}
if (collection) {
- nssPKIObjectCollection_Destroy(collection);
+ nssPKIObjectCollection_Destroy(collection);
}
if (nameList) {
- nssList_Destroy(nameList);
+ nssList_Destroy(nameList);
}
return SECFailure;
}
SECStatus
PK11_TraverseCertsInSlot(PK11SlotInfo *slot,
- SECStatus(* callback)(CERTCertificate*, void *), void *arg)
+ SECStatus (*callback)(CERTCertificate *, void *), void *arg)
{
PRStatus nssrv;
NSSTrustDomain *td = STAN_GetDefaultTrustDomain();
@@ -2093,16 +2119,16 @@ PK11_TraverseCertsInSlot(PK11SlotInfo *slot,
nssTokenSearchType tokenOnly = nssTokenSearchType_TokenOnly;
tok = PK11Slot_GetNSSToken(slot);
if (!nssToken_IsPresent(tok)) {
- return SECSuccess;
+ return SECSuccess;
}
collection = nssCertificateCollection_Create(td, NULL);
if (!collection) {
- return SECFailure;
+ return SECFailure;
}
certList = nssList_Create(NULL, PR_FALSE);
if (!certList) {
- nssPKIObjectCollection_Destroy(collection);
- return SECFailure;
+ nssPKIObjectCollection_Destroy(collection);
+ return SECFailure;
}
(void)nssTrustDomain_GetCertsFromCache(td, certList);
transfer_token_certs_to_collection(certList, tok, collection);
@@ -2115,65 +2141,70 @@ PK11_TraverseCertsInSlot(PK11SlotInfo *slot,
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);
+ 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
+ * return the certificate associated with a derCert
*/
CERTCertificate *
PK11_FindCertFromDERCert(PK11SlotInfo *slot, CERTCertificate *cert,
- void *wincx)
+ void *wincx)
{
return PK11_FindCertFromDERCertItem(slot, &cert->derCert, wincx);
}
CERTCertificate *
PK11_FindCertFromDERCertItem(PK11SlotInfo *slot, const SECItem *inDerCert,
- void *wincx)
+ void *wincx)
{
NSSDER derCert;
NSSToken *tok;
nssCryptokiObject *co = NULL;
SECStatus rv;
+ CERTCertificate *cert = NULL;
tok = PK11Slot_GetNSSToken(slot);
NSSITEM_FROM_SECITEM(&derCert, inDerCert);
rv = pk11_AuthenticateUnfriendly(slot, PR_TRUE, wincx);
if (rv != SECSuccess) {
- PK11_FreeSlot(slot);
- return NULL;
+ PK11_FreeSlot(slot);
+ return NULL;
}
co = nssToken_FindCertificateByEncodedCertificate(tok, NULL, &derCert,
- nssTokenSearchType_TokenOnly, NULL);
+ nssTokenSearchType_TokenOnly, NULL);
- return co ? PK11_MakeCertFromHandle(slot, co->handle, NULL) : NULL;
+ if (co) {
+ cert = PK11_MakeCertFromHandle(slot, co->handle, NULL);
+ nssCryptokiObject_Destroy(co);
+ }
-}
+ return cert;
+}
/*
* 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)
+static CK_OBJECT_HANDLE
+pk11_findKeyObjectByDERCert(PK11SlotInfo *slot, CERTCertificate *cert,
+ void *wincx)
{
SECItem *keyID;
CK_OBJECT_HANDLE key;
@@ -2181,32 +2212,33 @@ pk11_findKeyObjectByDERCert(PK11SlotInfo *slot, CERTCertificate *cert,
PRBool needLogin;
int err;
- if((slot == NULL) || (cert == NULL)) {
- return CK_INVALID_HANDLE;
+ if ((slot == NULL) || (cert == NULL)) {
+ return CK_INVALID_HANDLE;
}
keyID = pk11_mkcertKeyID(cert);
- if(keyID == NULL) {
- return CK_INVALID_HANDLE;
+ 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
+ * 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
+ * we will call it one more time after calling PK11_Authenticate
* (which is a noop on an authenticated token).
*/
- needLogin = pk11_LoginStillRequired(slot,wincx);
+ 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);
- }
+ (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);
@@ -2214,90 +2246,91 @@ loser:
}
SECKEYPrivateKey *
-PK11_FindKeyByDERCert(PK11SlotInfo *slot, CERTCertificate *cert,
- void *wincx)
+PK11_FindKeyByDERCert(PK11SlotInfo *slot, CERTCertificate *cert,
+ void *wincx)
{
CK_OBJECT_HANDLE keyHandle;
- if((slot == NULL) || (cert == NULL)) {
- return NULL;
+ if ((slot == NULL) || (cert == NULL)) {
+ return NULL;
}
keyHandle = pk11_findKeyObjectByDERCert(slot, cert, wincx);
if (keyHandle == CK_INVALID_HANDLE) {
- return NULL;
+ return NULL;
}
- return PK11_MakePrivKey(slot,nullKey,PR_TRUE,keyHandle,wincx);
+ return PK11_MakePrivKey(slot, nullKey, PR_TRUE, keyHandle, wincx);
}
SECStatus
-PK11_ImportCertForKeyToSlot(PK11SlotInfo *slot, CERTCertificate *cert,
- char *nickname,
- PRBool addCertUsage,void *wincx)
+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;
+ if ((slot == NULL) || (cert == NULL) || (nickname == NULL)) {
+ return SECFailure;
}
keyHandle = pk11_findKeyObjectByDERCert(slot, cert, wincx);
if (keyHandle == CK_INVALID_HANDLE) {
- return SECFailure;
+ 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 */
+#define SEC_OID_MISSI_KEA 300 /* until we have v3 stuff merged */
PRBool
-KEAPQGCompare(CERTCertificate *server,CERTCertificate *cert) {
+KEAPQGCompare(CERTCertificate *server, CERTCertificate *cert)
+{
/* not implemented */
return PR_FALSE;
}
PRBool
-PK11_FortezzaHasKEA(CERTCertificate *cert)
+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)) ;
+ /* 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)
+ *
+ 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];
+ 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;
- }
+ if (PK11_FortezzaHasKEA(cert) && KEAPQGCompare(peer, cert)) {
+ returnedCert = CERT_DupCertificate(cert);
+ break;
+ }
}
return returnedCert;
}
@@ -2312,7 +2345,7 @@ CERTCertificate *
PK11_FindBestKEAMatch(CERTCertificate *server, void *wincx)
{
PK11SlotList *keaList = PK11_GetAllTokens(CKM_KEA_KEY_DERIVE,
- PR_FALSE,PR_TRUE,wincx);
+ PR_FALSE, PR_TRUE, wincx);
PK11SlotListElement *le;
CERTCertificate *returnedCert = NULL;
SECStatus rv;
@@ -2325,12 +2358,14 @@ PK11_FindBestKEAMatch(CERTCertificate *server, void *wincx)
/* 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;
+ if (rv != SECSuccess)
+ continue;
+ if (le->slot->session == CK_INVALID_SESSION) {
+ continue;
+ }
+ returnedCert = pk11_GetKEAMate(le->slot, server);
+ if (returnedCert)
+ break;
}
PK11_FreeSlotList(keaList);
@@ -2338,27 +2373,27 @@ PK11_FindBestKEAMatch(CERTCertificate *server, void *wincx)
}
/*
- * find a matched pair of kea certs to key exchange parameters from one
+ * 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 **cert1, CERTCertificate **cert2)
{
CERTCertificate *returnedCert = NULL;
int i;
- for (i=0; i < slot1->cert_count; i++) {
- CERTCertificate *cert = slot1->cert_array[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;
- }
- }
+ if (PK11_FortezzaHasKEA(cert)) {
+ returnedCert = pk11_GetKEAMate(slot2, cert);
+ if (returnedCert != NULL) {
+ *cert2 = returnedCert;
+ *cert1 = CERT_DupCertificate(cert);
+ return SECSuccess;
+ }
+ }
}
return SECFailure;
}
@@ -2371,16 +2406,17 @@ 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 }
+ { 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]);
+ 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++;
+ cert->derCert.len);
+ attrs++;
PK11_SETATTRS(attrs, CKA_CLASS, &certClass, sizeof(certClass));
/*
@@ -2388,17 +2424,16 @@ PK11_FindCertInSlot(PK11SlotInfo *slot, CERTCertificate *cert, void *wincx)
*/
rv = pk11_AuthenticateUnfriendly(slot, PR_TRUE, wincx);
if (rv != SECSuccess) {
- return CK_INVALID_HANDLE;
+ return CK_INVALID_HANDLE;
}
- return pk11_getcerthandle(slot,cert,theTemplate,tsize);
+ return pk11_getcerthandle(slot, cert, theTemplate, tsize);
}
-/* Looking for PK11_GetKeyIDFromCert?
+/* Looking for PK11_GetKeyIDFromCert?
* Use PK11_GetLowLevelKeyIDForCert instead.
*/
-
struct listCertsStr {
PK11CertListType type;
CERTCertList *certList;
@@ -2418,88 +2453,87 @@ pk11ListCertCallback(NSSCertificate *c, void *arg)
SECStatus rv;
if ((type == PK11CertListUnique) || (type == PK11CertListRootUnique) ||
- (type == PK11CertListCAUnique) || (type == PK11CertListUserUnique) ) {
+ (type == PK11CertListCAUnique) || (type == PK11CertListUserUnique)) {
/* only list one instance of each certificate, even if several exist */
- isUnique = PR_TRUE;
+ isUnique = PR_TRUE;
}
if ((type == PK11CertListCA) || (type == PK11CertListRootUnique) ||
(type == PK11CertListCAUnique)) {
- isCA = PR_TRUE;
+ 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;
+ 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;
+ 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;
+ 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 (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);
- }
+ 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);
+ /* 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)
{
@@ -2511,23 +2545,23 @@ PK11_ListCerts(PK11CertListType type, void *pwarg)
listCerts.certList = certList;
/* authenticate to the slots */
- (void) pk11_TraverseAllSlots( NULL, NULL, PR_TRUE, pwarg);
+ (void)pk11_TraverseAllSlots(NULL, NULL, PR_TRUE, pwarg);
NSSTrustDomain_TraverseCertificates(defaultTD, pk11ListCertCallback,
- &listCerts);
+ &listCerts);
return certList;
}
-
+
SECItem *
PK11_GetLowLevelKeyIDForCert(PK11SlotInfo *slot,
- CERTCertificate *cert, void *wincx)
+ CERTCertificate *cert, void *wincx)
{
CK_OBJECT_CLASS certClass = CKO_CERTIFICATE;
CK_ATTRIBUTE theTemplate[] = {
- { CKA_VALUE, NULL, 0 },
- { CKA_CLASS, NULL, 0 }
+ { 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]);
+ int tsize = sizeof(theTemplate) / sizeof(theTemplate[0]);
CK_OBJECT_HANDLE certHandle;
CK_ATTRIBUTE *attrs = theTemplate;
PK11SlotInfo *slotRef = NULL;
@@ -2535,29 +2569,31 @@ PK11_GetLowLevelKeyIDForCert(PK11SlotInfo *slot,
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);
+ 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;
+ certHandle = PK11_FindObjectForCert(cert, wincx, &slotRef);
+ if (certHandle == CK_INVALID_HANDLE) {
+ return pk11_mkcertKeyID(cert);
+ }
+ slot = slotRef;
}
if (certHandle == CK_INVALID_HANDLE) {
- return NULL;
+ return NULL;
}
- item = pk11_GetLowLevelKeyFromHandle(slot,certHandle);
- if (slotRef) PK11_FreeSlot(slotRef);
+ item = pk11_GetLowLevelKeyFromHandle(slot, certHandle);
+ if (slotRef)
+ PK11_FreeSlot(slotRef);
return item;
}
@@ -2568,9 +2604,9 @@ typedef struct {
} ListCertsArg;
static SECStatus
-listCertsCallback(CERTCertificate* cert, void*arg)
+listCertsCallback(CERTCertificate *cert, void *arg)
{
- ListCertsArg *cdata = (ListCertsArg*)arg;
+ ListCertsArg *cdata = (ListCertsArg *)arg;
char *nickname = NULL;
nssCryptokiObject *instance, **ci;
nssCryptokiObject **instances;
@@ -2586,25 +2622,25 @@ listCertsCallback(CERTCertificate* cert, void*arg)
}
instance = NULL;
for (ci = instances; *ci; ci++) {
- if ((*ci)->token->pk11slot == cdata->slot) {
- instance = *ci;
- break;
- }
+ 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;
+ nssCryptokiObjectArray_Destroy(instances);
+ PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
+ return SECFailure;
}
nickname = STAN_GetCERTCertificateNameForInstance(cdata->list->arena,
- c, instance);
+ c, instance);
nssCryptokiObjectArray_Destroy(instances);
CERT_DupCertificate(cert);
rv = CERT_AddCertToListTailWithData(cdata->list, cert, nickname);
if (rv != SECSuccess) {
- CERT_DestroyCertificate(cert);
+ CERT_DestroyCertificate(cert);
}
return rv;
}
@@ -2617,16 +2653,17 @@ PK11_ListCertsInSlot(PK11SlotInfo *slot)
ListCertsArg cdata;
certs = CERT_NewCertList();
- if(certs == NULL) return NULL;
+ if (certs == NULL)
+ return NULL;
cdata.list = certs;
cdata.slot = slot;
status = PK11_TraverseCertsInSlot(slot, listCertsCallback,
- &cdata);
+ &cdata);
- if( status != SECSuccess ) {
- CERT_DestroyCertList(certs);
- certs = NULL;
+ if (status != SECSuccess) {
+ CERT_DestroyCertList(certs);
+ certs = NULL;
}
return certs;
@@ -2642,41 +2679,41 @@ PK11_GetAllSlotsForCert(CERTCertificate *cert, void *arg)
PRBool found = PR_FALSE;
if (!cert) {
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- return NULL;
+ PORT_SetError(SEC_ERROR_INVALID_ARGS);
+ return NULL;
}
c = STAN_GetNSSCertificate(cert);
if (!c) {
- CERT_MapStanError();
- return NULL;
+ 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;
+ PORT_SetError(SEC_ERROR_NO_TOKEN);
+ return NULL;
}
slotList = PK11_NewSlotList();
if (!slotList) {
- nssCryptokiObjectArray_Destroy(instances);
- return NULL;
+ 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;
- }
+ 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;
+ PK11_FreeSlotList(slotList);
+ PORT_SetError(SEC_ERROR_NO_TOKEN);
+ slotList = NULL;
}
nssCryptokiObjectArray_Destroy(instances);
diff --git a/nss/lib/pk11wrap/pk11cxt.c b/nss/lib/pk11wrap/pk11cxt.c
index d626ba7..e9726d0 100644
--- a/nss/lib/pk11wrap/pk11cxt.c
+++ b/nss/lib/pk11wrap/pk11cxt.c
@@ -2,7 +2,7 @@
* License, v. 2.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,
+ * This file PK11Contexts which are used in multipart hashing,
* encryption/decryption, and signing/verication operations.
*/
@@ -14,7 +14,7 @@
#include "pkcs11.h"
#include "pk11func.h"
#include "secitem.h"
-#include "secoid.h"
+#include "secoid.h"
#include "sechash.h"
#include "secerr.h"
@@ -30,26 +30,28 @@ static const SECItem pk11_null_params = { 0 };
* the monitors...
*/
void
-PK11_EnterContextMonitor(PK11Context *cx) {
+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);
+ /* Should this use monitors instead? */
+ PZ_Lock(cx->sessionLock);
} else {
- PK11_EnterSlotMonitor(cx->slot);
+ PK11_EnterSlotMonitor(cx->slot);
}
}
void
-PK11_ExitContextMonitor(PK11Context *cx) {
+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);
+ /* Should this use monitors instead? */
+ PZ_Unlock(cx->sessionLock);
} else {
- PK11_ExitSlotMonitor(cx->slot);
+ PK11_ExitSlotMonitor(cx->slot);
}
}
@@ -59,51 +61,50 @@ PK11_ExitContextMonitor(PK11Context *cx) {
void
PK11_DestroyContext(PK11Context *context, PRBool freeit)
{
- pk11_CloseSession(context->slot,context->session,context->ownSession);
+ 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->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);
+ SECITEM_FreeItem(context->param, PR_TRUE);
+ if (context->sessionLock)
+ PZ_DestroyLock(context->sessionLock);
PK11_FreeSlot(context->slot);
- if (freeit) PORT_Free(context);
+ if (freeit)
+ PORT_Free(context);
}
/*
* save the current context. Allocate Space if necessary.
*/
static unsigned char *
-pk11_saveContextHelper(PK11Context *context, unsigned char *buffer,
+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);
+ 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);
- }
+ /* 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;
+ PORT_SetError(PK11_MapError(crv));
+ return (unsigned char *)NULL;
}
return buffer;
}
@@ -111,7 +112,7 @@ pk11_saveContextHelper(PK11Context *context, unsigned char *buffer,
void *
pk11_saveContext(PK11Context *context, void *space, unsigned long *savedLength)
{
- return pk11_saveContextHelper(context,
+ return pk11_saveContextHelper(context,
(unsigned char *)space, savedLength);
}
@@ -119,24 +120,22 @@ pk11_saveContext(PK11Context *context, void *space, unsigned long *savedLength)
* restore the current context
*/
SECStatus
-pk11_restoreContext(PK11Context *context,void *space, unsigned long savedLength)
+pk11_restoreContext(PK11Context *context, void *space, unsigned long savedLength)
{
CK_RV crv;
- CK_OBJECT_HANDLE objectID = (context->key) ? context->key->objectID:
- CK_INVALID_HANDLE;
+ 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;
+ PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
+ return SECFailure;
}
- crv = PK11_GETTAB(context->slot)->C_SetOperationState(context->session,
- (CK_BYTE_PTR)space, savedLength, objectID, 0);
+ 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;
+ PORT_SetError(PK11_MapError(crv));
+ return SECFailure;
+ }
+ return SECSuccess;
}
SECStatus pk11_Finalize(PK11Context *context);
@@ -144,7 +143,7 @@ SECStatus pk11_Finalize(PK11Context *context);
/*
* Context initialization. Used by all flavors of CreateContext
*/
-static SECStatus
+static SECStatus
pk11_context_init(PK11Context *context, CK_MECHANISM *mech_info)
{
CK_RV crv;
@@ -152,42 +151,38 @@ pk11_context_init(PK11Context *context, CK_MECHANISM *mech_info)
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;
+ 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) );
+ PORT_SetError(PK11_MapError(crv));
return SECFailure;
}
@@ -195,36 +190,37 @@ pk11_context_init(PK11Context *context, CK_MECHANISM *mech_info)
* 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);
+ 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)
+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;
+ if (!slot || (!symKey && ((operation != CKA_DIGEST) ||
+ (type == CKM_SKIPJACK_CBC64)))) {
+ PORT_SetError(SEC_ERROR_INVALID_ARGS);
+ return NULL;
}
- context = (PK11Context *) PORT_Alloc(sizeof(PK11Context));
+ context = (PK11Context *)PORT_Alloc(sizeof(PK11Context));
if (context == NULL) {
- return NULL;
+ return NULL;
}
/* now deal with the fortezza hack... the fortezza hack is an attempt
@@ -236,16 +232,16 @@ static PK11Context *pk11_CreateNewContextInSlot(CK_MECHANISM_TYPE type,
* of the connection.*/
context->fortezzaHack = PR_FALSE;
if (type == CKM_SKIPJACK_CBC64) {
- if (symKey->origin == PK11_OriginFortezzaHack) {
- context->fortezzaHack = PR_TRUE;
- }
+ 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->session = pk11_GetNewSession(slot, &context->ownSession);
context->cx = symKey ? symKey->cx : NULL;
/* get our session */
context->savedData = NULL;
@@ -254,64 +250,64 @@ static PK11Context *pk11_CreateNewContextInSlot(CK_MECHANISM_TYPE type,
* 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;
- }
+ 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;
+ 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;
+ 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);
+ rv = pk11_context_init(context, &mech_info);
PK11_ExitContextMonitor(context);
if (rv != SECSuccess) {
- PK11_DestroyContext(context,PR_TRUE);
- return NULL;
+ 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)
+ 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;
- }
+ slot = PK11_GetBestSlot(type, wincx);
+ if (slot == NULL) {
+ PORT_SetError(SEC_ERROR_NO_MODULE);
+ goto loser;
+ }
} else {
- PK11_ReferenceSlot(slot);
+ PK11_ReferenceSlot(slot);
}
/* now import the key */
- symKey = PK11_ImportSymKey(slot, type, origin, operation, key, wincx);
- if (symKey == NULL) goto loser;
+ symKey = PK11_ImportSymKey(slot, type, origin, operation, key, wincx);
+ if (symKey == NULL)
+ goto loser;
context = PK11_CreateContextBySymKey(type, operation, symKey, param);
@@ -328,37 +324,35 @@ loser:
PK11Context *
PK11_CreateContextByRawKey(PK11SlotInfo *slot, CK_MECHANISM_TYPE type,
- PK11Origin origin, CK_ATTRIBUTE_TYPE operation, SECItem *key,
- SECItem *param, void *wincx)
+ 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)
+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);
+ newKey = pk11_ForceSlot(symKey, type, operation);
if (newKey == NULL) {
- PK11_ReferenceSymKey(symKey);
+ PK11_ReferenceSymKey(symKey);
} else {
- symKey = newKey;
+ symKey = newKey;
}
-
/* Context Adopts the symKey.... */
context = pk11_CreateNewContextInSlot(type, symKey->slot, operation, symKey,
- param);
+ param);
PK11_FreeSymKey(symKey);
return context;
}
@@ -379,8 +373,8 @@ PK11_CreateDigestContext(SECOidTag hashAlg)
type = PK11_AlgtagToMechanism(hashAlg);
slot = PK11_GetBestSlot(type, NULL);
if (slot == NULL) {
- PORT_SetError( SEC_ERROR_NO_MODULE );
- return NULL;
+ PORT_SetError(SEC_ERROR_NO_MODULE);
+ return NULL;
}
/* maybe should really be PK11_GenerateNewParam?? */
@@ -396,60 +390,63 @@ PK11_CreateDigestContext(SECOidTag hashAlg)
/*
* create a new context which is the clone of the state of old context.
*/
-PK11Context * PK11_CloneContext(PK11Context *old)
+PK11Context *
+PK11_CloneContext(PK11Context *old)
{
- PK11Context *newcx;
- PRBool needFree = PR_FALSE;
- SECStatus rv = SECSuccess;
- void *data;
- unsigned long len;
+ 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;
+ 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
+ /* 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) {
+ if (old->ownSession) {
PK11_EnterContextMonitor(old);
- data=pk11_saveContext(old,NULL,&len);
+ 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
+ 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) {
+ if (newcx->ownSession) {
PK11_EnterContextMonitor(newcx);
- rv = pk11_restoreContext(newcx,data,len);
+ 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;
- }
+ } 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 (needFree)
+ PORT_Free(data);
if (rv != SECSuccess) {
- PK11_DestroyContext(newcx,PR_TRUE);
- return NULL;
+ PK11_DestroyContext(newcx, PR_TRUE);
+ return NULL;
}
return newcx;
}
@@ -459,30 +456,31 @@ PK11Context * PK11_CloneContext(PK11Context *old)
* work.
*/
SECStatus
-PK11_SaveContext(PK11Context *cx,unsigned char *save,int *len, int saveLength)
+PK11_SaveContext(PK11Context *cx, unsigned char *save, int *len, int saveLength)
{
- unsigned char * data = NULL;
+ unsigned char *data = NULL;
CK_ULONG length = saveLength;
if (cx->ownSession) {
PK11_EnterContextMonitor(cx);
- data = pk11_saveContextHelper(cx, save, &length);
+ 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)
+ *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;
+ if (cx->ownSession) {
+ PORT_ZFree(data, length);
+ }
+ return SECSuccess;
} else {
- return SECFailure;
+ return SECFailure;
}
}
@@ -497,22 +495,22 @@ PK11_SaveContextAlloc(PK11Context *cx,
if (cx->ownSession) {
PK11_EnterContextMonitor(cx);
- stateBuf = pk11_saveContextHelper(cx, preAllocBuf, &length);
+ stateBuf = pk11_saveContextHelper(cx, preAllocBuf, &length);
PK11_ExitContextMonitor(cx);
- *stateLen = (stateBuf != NULL) ? length : 0;
+ *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;
+ 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;
}
@@ -522,23 +520,23 @@ PK11_SaveContextAlloc(PK11Context *cx,
* FORTEZZA .
*/
SECStatus
-PK11_RestoreContext(PK11Context *cx,unsigned char *save,int len)
+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_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;
- }
+ 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;
}
@@ -549,27 +547,28 @@ PK11_RestoreContext(PK11Context *cx,unsigned char *save,int len)
* if we can't get a PK11 Context.
*/
PRBool
-PK11_HashOK(SECOidTag algID) {
+PK11_HashOK(SECOidTag algID)
+{
PK11Context *cx;
cx = PK11_CreateDigestContext(algID);
- if (cx == NULL) return PR_FALSE;
+ 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)
+SECStatus
+PK11_DigestBegin(PK11Context *cx)
{
CK_MECHANISM mech_info;
SECStatus rv;
if (cx->init == PR_TRUE) {
- return SECSuccess;
+ return SECSuccess;
}
/*
@@ -581,11 +580,11 @@ SECStatus PK11_DigestBegin(PK11Context *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);
+ rv = pk11_context_init(cx, &mech_info);
PK11_ExitContextMonitor(cx);
if (rv != SECSuccess) {
- return SECFailure;
+ return SECFailure;
}
cx->init = PR_TRUE;
return SECSuccess;
@@ -593,7 +592,8 @@ SECStatus PK11_DigestBegin(PK11Context *cx)
SECStatus
PK11_HashBuf(SECOidTag hashAlg, unsigned char *out, const unsigned char *in,
- PRInt32 len) {
+ PRInt32 len)
+{
PK11Context *context;
unsigned int max_length;
unsigned int out_length;
@@ -606,42 +606,42 @@ PK11_HashBuf(SECOidTag hashAlg, unsigned char *out, const unsigned char *in,
}
context = PK11_CreateDigestContext(hashAlg);
- if (context == NULL) return SECFailure;
+ if (context == NULL)
+ return SECFailure;
rv = PK11_DigestBegin(context);
if (rv != SECSuccess) {
- PK11_DestroyContext(context, PR_TRUE);
- return rv;
+ PK11_DestroyContext(context, PR_TRUE);
+ return rv;
}
rv = PK11_DigestOp(context, in, len);
if (rv != SECSuccess) {
- PK11_DestroyContext(context, PR_TRUE);
- return rv;
+ 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;
+ max_length = HASH_LENGTH_MAX;
- rv = PK11_DigestFinal(context,out,&out_length,max_length);
+ 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)
+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;
+ CK_ULONG offset = 0;
SECStatus rv = SECSuccess;
unsigned char *saveOut = out;
unsigned char *allocOut = NULL;
@@ -651,12 +651,12 @@ PK11_CipherOp(PK11Context *context, unsigned char * out, int *outlen,
*/
PK11_EnterContextMonitor(context);
if (!context->ownSession) {
- rv = pk11_restoreContext(context,context->savedData,
- context->savedLength);
- if (rv != SECSuccess) {
- PK11_ExitContextMonitor(context);
- return rv;
- }
+ rv = pk11_restoreContext(context, context->savedData,
+ context->savedLength);
+ if (rv != SECSuccess) {
+ PK11_ExitContextMonitor(context);
+ return rv;
+ }
}
/*
@@ -664,82 +664,77 @@ PK11_CipherOp(PK11Context *context, unsigned char * out, int *outlen,
* 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;
- }
+ 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;
+ 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;
+ PORT_SetError(PK11_MapError(crv));
+ *outlen = 0;
rv = SECFailure;
} else {
- *outlen = length;
+ *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;
+ 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);
+ 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;
@@ -749,7 +744,7 @@ PK11_CipherOp(PK11Context *context, unsigned char * out, int *outlen,
* execute a digest/signature operation
*/
SECStatus
-PK11_DigestOp(PK11Context *context, const unsigned char * in, unsigned inLen)
+PK11_DigestOp(PK11Context *context, const unsigned char *in, unsigned inLen)
{
CK_RV crv = CKR_OK;
SECStatus rv = SECSuccess;
@@ -768,38 +763,32 @@ PK11_DigestOp(PK11Context *context, const unsigned char * in, unsigned inLen)
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;
- }
+ 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;
+ /* 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) );
+ PORT_SetError(PK11_MapError(crv));
rv = SECFailure;
}
@@ -807,12 +796,13 @@ PK11_DigestOp(PK11Context *context, const unsigned char * in, unsigned inLen)
* 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);
+ 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;
@@ -837,37 +827,34 @@ PK11_DigestKey(PK11Context *context, PK11SymKey *key)
* state.
*/
if (context->slot != key->slot) {
- newKey = pk11_CopyToSlot(context->slot,CKM_SSL3_SHA1_MAC,CKA_SIGN,key);
+ newKey = pk11_CopyToSlot(context->slot, CKM_SSL3_SHA1_MAC, CKA_SIGN, key);
} else {
- newKey = PK11_ReferenceSymKey(key);
+ 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);
+ rv = pk11_restoreContext(context, context->savedData,
+ context->savedLength);
+ if (rv != SECSuccess) {
+ PK11_ExitContextMonitor(context);
PK11_FreeSymKey(newKey);
- return rv;
- }
+ 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);
- }
+ 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);
+ crv = PK11_GETTAB(context->slot)->C_DigestKey(context->session, newKey->objectID);
}
if (crv != CKR_OK) {
- PORT_SetError( PK11_MapError(crv) );
+ PORT_SetError(PK11_MapError(crv));
rv = SECFailure;
}
@@ -875,15 +862,17 @@ PK11_DigestKey(PK11Context *context, PK11SymKey *key)
* 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);
+ 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);
+ if (newKey)
+ PK11_FreeSymKey(newKey);
return rv;
}
@@ -891,7 +880,8 @@ PK11_DigestKey(PK11Context *context, PK11SymKey *key)
* externally callable version of the lowercase pk11_finalize().
*/
SECStatus
-PK11_Finalize(PK11Context *context) {
+PK11_Finalize(PK11Context *context)
+{
SECStatus rv;
PK11_EnterContextMonitor(context);
@@ -913,63 +903,58 @@ pk11_Finalize(PK11Context *context)
unsigned char *buffer = NULL;
if (!context->ownSession) {
- return SECSuccess;
+ 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;
+ 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) );
+ 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 == 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);
+ PORT_Free(buffer);
}
return SECSuccess;
}
@@ -980,63 +965,55 @@ finalize:
* 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)
+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;
- }
+ 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;
+ 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;
+ *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;
+ PORT_SetError(PK11_MapError(crv));
+ return SECFailure;
}
return SECSuccess;
}
-
diff --git a/nss/lib/pk11wrap/pk11err.c b/nss/lib/pk11wrap/pk11err.c
index 7d9ab92..db6d244 100644
--- a/nss/lib/pk11wrap/pk11err.c
+++ b/nss/lib/pk11wrap/pk11err.c
@@ -1,7 +1,7 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.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
@@ -18,118 +18,124 @@
#include "secerr.h"
#include "prerror.h"
-#ifdef PK11_ERROR_USE_ARRAY
+#ifdef PK11_ERROR_USE_ARRAY
/*
* build a static array of entries...
*/
static struct {
- CK_RV pk11_error;
- int sec_error;
+ CK_RV pk11_error;
+ int sec_error;
} pk11_error_map = {
-#define MAPERROR(x,y) {x, y},
+#define MAPERROR(x, y) { x, y },
#else
/* the default is to use a big switch statement */
int
-PK11_MapError(CK_RV rv) {
+PK11_MapError(CK_RV rv)
+{
- switch (rv) {
-#define MAPERROR(x,y) case x: return y;
+ 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)
+ /* the guts mapping */
+ /* clang-format off */
+ 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)
+/* clang-format on */
-#ifdef PK11_ERROR_USE_ARRAY
+#ifdef PK11_ERROR_USE_ARRAY
};
int
-PK11_MapError(CK_RV rv) {
- int size = sizeof(pk11_error_map)/sizeof(pk11_error_map[0]);
+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;
- }
+ 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;
+ /* clang-format off */
+ default :
+ break;
+/* clang-format on */
+}
+return SEC_ERROR_UNKNOWN_PKCS11_ERROR;
}
-
#endif
diff --git a/nss/lib/pk11wrap/pk11kea.c b/nss/lib/pk11wrap/pk11kea.c
index a7dd4fb..331a19c 100644
--- a/nss/lib/pk11wrap/pk11kea.c
+++ b/nss/lib/pk11wrap/pk11kea.c
@@ -29,103 +29,112 @@ 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]);
+ 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++;
+ 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));
+ PR_ASSERT(template_count <= sizeof(theTemplate) / sizeof(CK_ATTRIBUTE));
- return pk11_FindObjectByTemplate(slot,theTemplate,template_count);
+ 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)
+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
+ * 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);
+ 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;
+ 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);
- }
+ /* 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 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;
+ 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.len = SECKEY_PublicKeyStrength(pubKey);
+ if (!wrapData.len)
+ goto rsa_failed;
wrapData.data = PORT_Alloc(wrapData.len);
- if (wrapData.data == NULL) goto rsa_failed;
+ 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);
+ /* 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;
+ return newSymKey;
}
- PORT_SetError( SEC_ERROR_NO_MODULE );
+ PORT_SetError(SEC_ERROR_NO_MODULE);
return NULL;
}
-
diff --git a/nss/lib/pk11wrap/pk11list.c b/nss/lib/pk11wrap/pk11list.c
index 9e32482..aaf29f6 100644
--- a/nss/lib/pk11wrap/pk11list.c
+++ b/nss/lib/pk11wrap/pk11list.c
@@ -16,25 +16,27 @@
/*
* create a new lock for a Module List
*/
-SECMODListLock *SECMOD_NewListLock()
+SECMODListLock *
+SECMOD_NewListLock()
{
- return NSSRWLock_New( 10, "moduleListLock");
+ return NSSRWLock_New(10, "moduleListLock");
}
/*
* destroy the lock
*/
-void SECMOD_DestroyListLock(SECMODListLock *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)
+void
+SECMOD_GetReadLock(SECMODListLock *modLock)
{
NSSRWLock_LockRead(modLock);
}
@@ -42,36 +44,36 @@ void SECMOD_GetReadLock(SECMODListLock *modLock)
/*
* Release the Read lock
*/
-void SECMOD_ReleaseReadLock(SECMODListLock *modLock)
+void
+SECMOD_ReleaseReadLock(SECMODListLock *modLock)
{
NSSRWLock_UnlockRead(modLock);
}
-
/*
* lock the list for Write
*/
-void SECMOD_GetWriteLock(SECMODListLock *modLock)
+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)
+void
+SECMOD_ReleaseWriteLock(SECMODListLock *modLock)
{
NSSRWLock_UnlockWrite(modLock);
}
-
/*
* must Hold the Write lock
*/
void
-SECMOD_RemoveList(SECMODModuleList **parent, SECMODModuleList *child)
+SECMOD_RemoveList(SECMODModuleList **parent, SECMODModuleList *child)
{
*parent = child->next;
child->next = NULL;
@@ -81,15 +83,17 @@ SECMOD_RemoveList(SECMODModuleList **parent, SECMODModuleList *child)
* if lock is not specified, it must already be held
*/
void
-SECMOD_AddList(SECMODModuleList *parent, SECMODModuleList *child,
- SECMODListLock *lock)
+SECMOD_AddList(SECMODModuleList *parent, SECMODModuleList *child,
+ SECMODListLock *lock)
{
- if (lock) { SECMOD_GetWriteLock(lock); }
+ if (lock) {
+ SECMOD_GetWriteLock(lock);
+ }
child->next = parent->next;
parent->next = child;
- if (lock) { SECMOD_ReleaseWriteLock(lock); }
+ if (lock) {
+ SECMOD_ReleaseWriteLock(lock);
+ }
}
-
-
diff --git a/nss/lib/pk11wrap/pk11load.c b/nss/lib/pk11wrap/pk11load.c
index e3ba122..f12d0fd 100644
--- a/nss/lib/pk11wrap/pk11load.c
+++ b/nss/lib/pk11wrap/pk11load.c
@@ -27,38 +27,46 @@ static char *modToDBG = NULL;
#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;
+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) {
+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) {
+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) {
+CK_RV PR_CALLBACK
+secmodUnlockMutext(CK_VOID_PTR mutext)
+{
PZ_Unlock((PZLock *)mutext);
return CKR_OK;
}
-static SECMODModuleID nextModuleID = 1;
+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
+ secmodCreateMutext, secmodDestroyMutext, secmodLockMutext,
+ secmodUnlockMutext, CKF_LIBRARY_CANT_CREATE_OS_THREADS |
+ CKF_OS_LOCKING_OK,
+ NULL
};
static const CK_C_INITIALIZE_ARGS secmodNoLockArgs = {
NULL, NULL, NULL, NULL,
- CKF_LIBRARY_CANT_CREATE_OS_THREADS
- ,NULL
+ CKF_LIBRARY_CANT_CREATE_OS_THREADS, NULL
};
static PRBool loadSingleThreadedModules = PR_TRUE;
@@ -66,9 +74,10 @@ 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)
+SECStatus
+pk11_setGlobalOptions(PRBool noSingleThreadedModules,
+ PRBool allowAlreadyInitializedModules,
+ PRBool dontFinalizeModules)
{
if (noSingleThreadedModules) {
loadSingleThreadedModules = PR_FALSE;
@@ -88,7 +97,8 @@ SECStatus pk11_setGlobalOptions(PRBool noSingleThreadedModules,
return SECSuccess;
}
-PRBool pk11_getFinalizeModulesOption(void)
+PRBool
+pk11_getFinalizeModulesOption(void)
{
return finalizeModules;
}
@@ -114,82 +124,81 @@ secmod_handleReload(SECMODModule *oldModule, SECMODModule *newModule)
char **children;
CK_SLOT_ID *ids;
SECMODConfigList *conflist = NULL;
- SECStatus rv = SECFailure;
- int count = 0;
+ 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);
+ newModule->isFIPS, modulespec, &children, &ids);
if (!newModuleSpec) {
- return SECFailure;
+ 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.
+ * internal module.
*/
if (oldModule->internal) {
- conflist = secmod_GetConfigList(oldModule->isFIPS,
- oldModule->libraryParams, &count);
+ 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;
+ 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;
+ 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);
+ secmod_FreeConfigList(conflist, count);
}
return rv;
}
@@ -198,15 +207,15 @@ loser:
* collect the steps we need to initialize a module in a single function
*/
SECStatus
-secmod_ModuleInit(SECMODModule *mod, SECMODModule **reload,
- PRBool* alreadyLoaded)
+secmod_ModuleInit(SECMODModule *mod, SECMODModule **reload,
+ PRBool *alreadyLoaded)
{
CK_C_INITIALIZE_ARGS moduleArgs;
CK_VOID_PTR pInitArgs;
CK_RV crv;
if (reload) {
- *reload = NULL;
+ *reload = NULL;
}
if (!mod || !alreadyLoaded) {
@@ -215,86 +224,86 @@ secmod_ModuleInit(SECMODModule *mod, SECMODModule **reload,
}
if (mod->libraryParams == NULL) {
- if (mod->isThreadSafe) {
- pInitArgs = (void *) &secmodLockFunctions;
- } else {
- pInitArgs = NULL;
- }
+ if (mod->isThreadSafe) {
+ pInitArgs = (void *)&secmodLockFunctions;
+ } else {
+ pInitArgs = NULL;
+ }
} else {
- if (mod->isThreadSafe) {
- moduleArgs = secmodLockFunctions;
- } else {
- moduleArgs = secmodNoLockArgs;
- }
- moduleArgs.LibraryParameters = (void *) mod->libraryParams;
- pInitArgs = &moduleArgs;
+ if (mod->isThreadSafe) {
+ moduleArgs = secmodLockFunctions;
+ } else {
+ moduleArgs = secmodNoLockArgs;
+ }
+ 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;
+ 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 (!mod->isThreadSafe ||
- crv == CKR_NETSCAPE_CERTDB_FAILED ||
- crv == CKR_NETSCAPE_KEYDB_FAILED) {
- PORT_SetError(PK11_MapError(crv));
- return SECFailure;
- }
- /* If we had attempted to init a single threaded module "with"
- * parameters and it failed, should we retry "without" parameters?
- * (currently we don't retry in this scenario) */
-
- if (!loadSingleThreadedModules) {
- PORT_SetError(SEC_ERROR_INCOMPATIBLE_PKCS11);
- return SECFailure;
- }
- /* If we arrive here, the module failed a ThreadSafe init. */
- mod->isThreadSafe = PR_FALSE;
- if (!mod->libraryParams) {
- pInitArgs = NULL;
- } else {
- moduleArgs = secmodNoLockArgs;
- moduleArgs.LibraryParameters = (void *) mod->libraryParams;
- pInitArgs = &moduleArgs;
- }
- crv = PK11_GETTAB(mod)->C_Initialize(pInitArgs);
- if ((CKR_CRYPTOKI_ALREADY_INITIALIZED == crv) &&
- (!enforceAlreadyInitializedError)) {
- *alreadyLoaded = PR_TRUE;
- return SECSuccess;
- }
- if (crv != CKR_OK) {
- PORT_SetError(PK11_MapError(crv));
- return SECFailure;
- }
+ if (!mod->isThreadSafe ||
+ crv == CKR_NETSCAPE_CERTDB_FAILED ||
+ crv == CKR_NETSCAPE_KEYDB_FAILED) {
+ PORT_SetError(PK11_MapError(crv));
+ return SECFailure;
+ }
+ /* If we had attempted to init a single threaded module "with"
+ * parameters and it failed, should we retry "without" parameters?
+ * (currently we don't retry in this scenario) */
+
+ if (!loadSingleThreadedModules) {
+ PORT_SetError(SEC_ERROR_INCOMPATIBLE_PKCS11);
+ return SECFailure;
+ }
+ /* If we arrive here, the module failed a ThreadSafe init. */
+ mod->isThreadSafe = PR_FALSE;
+ if (!mod->libraryParams) {
+ pInitArgs = NULL;
+ } else {
+ moduleArgs = secmodNoLockArgs;
+ moduleArgs.LibraryParameters = (void *)mod->libraryParams;
+ pInitArgs = &moduleArgs;
+ }
+ crv = PK11_GETTAB(mod)->C_Initialize(pInitArgs);
+ 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;
}
@@ -304,50 +313,50 @@ secmod_ModuleInit(SECMODModule *mod, SECMODModule **reload,
* into the database.
*/
void
-SECMOD_SetRootCerts(PK11SlotInfo *slot, SECMODModule *mod) {
+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;
+ 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 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 PRLibrary *softokenLib;
static PRInt32 softokenLoadCount;
#include "prio.h"
@@ -358,25 +367,26 @@ static PRInt32 softokenLoadCount;
/* This function must be run only once. */
/* determine if hybrid platform, then actually load the DSO. */
static PRStatus
-softoken_LoadDSO( void )
+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;
+ 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) {
+secmod_LoadPKCS11Module(SECMODModule *mod, SECMODModule **oldModule)
+{
PRLibrary *library = NULL;
CK_C_GetFunctionList entry = NULL;
CK_INFO info;
@@ -385,92 +395,94 @@ secmod_LoadPKCS11Module(SECMODModule *mod, SECMODModule **oldModule) {
PRBool alreadyLoaded = PR_FALSE;
char *disableUnload = NULL;
- if (mod->loaded) return SECSuccess;
+ 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;
+ /*
+ * 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");
+ }
- PR_ATOMIC_INCREMENT(&softokenLoadCount);
+ if (!entry)
+ return SECFailure;
- if (mod->isFIPS) {
- entry = (CK_C_GetFunctionList)
- PR_FindSymbol(softokenLib, "FC_GetFunctionList");
+ if (mod->isModuleDB) {
+ mod->moduleDBFunc = (CK_C_GetFunctionList)
+ PR_FindSymbol(softokenLib, "NSC_ModuleDBFunc");
+ }
+
+ if (mod->moduleDBOnly) {
+ mod->loaded = PR_TRUE;
+ return SECSuccess;
+ }
} else {
- entry = (CK_C_GetFunctionList)
- PR_FindSymbol(softokenLib, "NSC_GetFunctionList");
- }
+ /* Not internal, load the DLL and look up C_GetFunctionList */
+ if (mod->dllName == NULL) {
+ return SECFailure;
+ }
- if (!entry)
- 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 (mod->isModuleDB) {
- mod->moduleDBFunc = (CK_C_GetFunctionList)
- PR_FindSymbol(softokenLib, "NSC_ModuleDBFunc");
- }
+ if (library == NULL) {
+ return SECFailure;
+ }
- 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;
- }
+ /*
+ * 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;
+ 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);
- }
+ modToDBG = PR_GetEnvSecure("NSS_DEBUG_PKCS11_MODULE");
+ if (modToDBG && strcmp(mod->commonName, modToDBG) == 0) {
+ mod->functionList = (void *)nss_InsertDeviceLog(
+ (CK_FUNCTION_LIST_PTR)mod->functionList);
+ }
}
#endif
@@ -479,19 +491,21 @@ secmod_LoadPKCS11Module(SECMODModule *mod, SECMODModule **oldModule) {
/* Now we initialize the module */
rv = secmod_ModuleInit(mod, oldModule, &alreadyLoaded);
if (rv != SECSuccess) {
- goto fail;
+ goto fail;
}
- /* module has been reloaded, this module itself is done,
+ /* 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;
+ 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;
+ 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) {
@@ -505,50 +519,51 @@ secmod_LoadPKCS11Module(SECMODModule *mod, SECMODModule **oldModule) {
/* 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;
+ 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);
+ 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;
@@ -558,7 +573,7 @@ fail2:
}
fail:
mod->functionList = NULL;
- disableUnload = PR_GetEnv("NSS_DISABLE_UNLOAD");
+ disableUnload = PR_GetEnvSecure("NSS_DISABLE_UNLOAD");
if (library && !disableUnload) {
PR_UnloadLibrary(library);
}
@@ -566,50 +581,51 @@ fail:
}
SECStatus
-SECMOD_UnloadModule(SECMODModule *mod) {
+SECMOD_UnloadModule(SECMODModule *mod)
+{
PRLibrary *library;
char *disableUnload = NULL;
if (!mod->loaded) {
- return SECFailure;
+ return SECFailure;
}
if (finalizeModules) {
- if (mod->functionList &&!mod->moduleDBOnly) {
- PK11_GETTAB(mod)->C_Finalize(NULL);
- }
+ 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) {
+ if (softokenLib) {
+ disableUnload = PR_GetEnvSecure("NSS_DISABLE_UNLOAD");
+ if (!disableUnload) {
#ifdef DEBUG
- PRStatus status = PR_UnloadLibrary(softokenLib);
- PORT_Assert(PR_SUCCESS == status);
+ PRStatus status = PR_UnloadLibrary(softokenLib);
+ PORT_Assert(PR_SUCCESS == status);
#else
- PR_UnloadLibrary(softokenLib);
+ PR_UnloadLibrary(softokenLib);
#endif
- }
- softokenLib = NULL;
- }
- loadSoftokenOnce = pristineCallOnce;
+ }
+ softokenLib = NULL;
+ }
+ loadSoftokenOnce = pristineCallOnce;
}
- return SECSuccess;
+ return SECSuccess;
}
library = (PRLibrary *)mod->library;
/* paranoia */
if (library == NULL) {
- return SECFailure;
+ return SECFailure;
}
- disableUnload = PR_GetEnv("NSS_DISABLE_UNLOAD");
+ disableUnload = PR_GetEnvSecure("NSS_DISABLE_UNLOAD");
if (!disableUnload) {
PR_UnloadLibrary(library);
}
@@ -621,7 +637,7 @@ nss_DumpModuleLog(void)
{
#ifdef DEBUG_MODULE
if (modToDBG) {
- print_final_statistics();
+ print_final_statistics();
}
#endif
}
diff --git a/nss/lib/pk11wrap/pk11mech.c b/nss/lib/pk11wrap/pk11mech.c
index 29e86e6..4db05ff 100644
--- a/nss/lib/pk11wrap/pk11mech.c
+++ b/nss/lib/pk11wrap/pk11mech.c
@@ -12,7 +12,7 @@
#include "pk11func.h"
#include "secitem.h"
#include "secder.h"
-#include "secasn1.h"
+#include "secasn1.h"
#include "secoid.h"
#include "secerr.h"
@@ -24,17 +24,17 @@
* 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;
+ 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_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;
@@ -61,7 +61,7 @@ CK_MECHANISM_TYPE wrapMechanismList[] = {
CKM_SKIPJACK_WRAP,
};
-int wrapMechanismCount = sizeof(wrapMechanismList)/sizeof(wrapMechanismList[0]);
+int wrapMechanismCount = sizeof(wrapMechanismList) / sizeof(wrapMechanismList[0]);
/*********************************************************************
* Mechanism Mapping functions
@@ -75,10 +75,10 @@ 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]);
- }
+ for (i = 0; i < pk11_MechEntrySize; i++) {
+ if (pk11_MechanismTable[i].type == type) {
+ return (&pk11_MechanismTable[i]);
+ }
}
return &pk11_default;
}
@@ -90,10 +90,10 @@ CK_MECHANISM_TYPE
PK11_GetBestWrapMechanism(PK11SlotInfo *slot)
{
int i;
- for (i=0; i < wrapMechanismCount; i++) {
- if (PK11_DoesMechanism(slot,wrapMechanismList[i])) {
- return wrapMechanismList[i];
- }
+ for (i = 0; i < wrapMechanismCount; i++) {
+ if (PK11_DoesMechanism(slot, wrapMechanismList[i])) {
+ return wrapMechanismList[i];
+ }
}
return CKM_INVALID_MECHANISM;
}
@@ -108,9 +108,9 @@ PK11_GetBestWrapMechanism(PK11SlotInfo *slot)
*/
void
PK11_AddMechanismEntry(CK_MECHANISM_TYPE type, CK_KEY_TYPE key,
- CK_MECHANISM_TYPE keyGen,
- CK_MECHANISM_TYPE padType,
- int ivLen, int blockSize)
+ CK_MECHANISM_TYPE keyGen,
+ CK_MECHANISM_TYPE padType,
+ int ivLen, int blockSize)
{
int tableSize = pk11_MechTableSize;
int size = pk11_MechEntrySize;
@@ -118,15 +118,17 @@ PK11_AddMechanismEntry(CK_MECHANISM_TYPE type, CK_KEY_TYPE key,
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;
+ 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;
+ if (old)
+ PORT_Memcpy(newt, old, oldTableSize * sizeof(*newt));
+ } else
+ old = NULL;
newt[entry].type = type;
newt[entry].keyType = key;
@@ -138,7 +140,8 @@ PK11_AddMechanismEntry(CK_MECHANISM_TYPE type, CK_KEY_TYPE key,
pk11_MechanismTable = newt;
pk11_MechTableSize = tableSize;
pk11_MechEntrySize = size;
- if (old) PORT_Free(old);
+ if (old)
+ PORT_Free(old);
}
/*
@@ -148,53 +151,55 @@ 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;
+ case CKK_SEED:
+ return CKM_SEED_CBC;
+ case CKK_CAMELLIA:
+ return CKM_CAMELLIA_CBC;
+ case CKK_NSS_CHACHA20:
+ return CKM_NSS_CHACHA20_POLY1305;
+ 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;
}
}
@@ -202,209 +207,212 @@ PK11_GetKeyMechanism(CK_KEY_TYPE type)
* Get the key type needed for the given mechanism
*/
CK_KEY_TYPE
-PK11_GetKeyType(CK_MECHANISM_TYPE type,unsigned long len)
+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_CCM:
- case CKM_AES_CTR:
- case CKM_AES_CTS:
- case CKM_AES_GCM:
- 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_NSS_TLS_MASTER_KEY_DERIVE_SHA256:
- case CKM_TLS_MASTER_KEY_DERIVE_DH:
- case CKM_NSS_TLS_MASTER_KEY_DERIVE_DH_SHA256:
- case CKM_TLS_KEY_AND_MAC_DERIVE:
- case CKM_NSS_TLS_KEY_AND_MAC_DERIVE_SHA256:
- case CKM_NSS_TLS_EXTENDED_MASTER_KEY_DERIVE:
- case CKM_NSS_TLS_EXTENDED_MASTER_KEY_DERIVE_DH:
- 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_NSS_TLS_PRF_GENERAL_SHA256:
- return CKK_GENERIC_SECRET;
- default:
- return pk11_lookup(type)->keyType;
+ 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_NSS_CHACHA20_POLY1305:
+ case CKM_NSS_CHACHA20_KEY_GEN:
+ return CKK_NSS_CHACHA20;
+ case CKM_AES_ECB:
+ case CKM_AES_CBC:
+ case CKM_AES_CCM:
+ case CKM_AES_CTR:
+ case CKM_AES_CTS:
+ case CKM_AES_GCM:
+ 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_NSS_TLS_MASTER_KEY_DERIVE_SHA256:
+ case CKM_TLS_MASTER_KEY_DERIVE_DH:
+ case CKM_NSS_TLS_MASTER_KEY_DERIVE_DH_SHA256:
+ case CKM_TLS_KEY_AND_MAC_DERIVE:
+ case CKM_NSS_TLS_KEY_AND_MAC_DERIVE_SHA256:
+ case CKM_NSS_TLS_EXTENDED_MASTER_KEY_DERIVE:
+ case CKM_NSS_TLS_EXTENDED_MASTER_KEY_DERIVE_DH:
+ 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_NSS_TLS_PRF_GENERAL_SHA256:
+ return CKK_GENERIC_SECRET;
+ default:
+ return pk11_lookup(type)->keyType;
}
}
/*
- * Get the Key Gen Mechanism needed for the given
+ * Get the Key Gen Mechanism needed for the given
* crypto mechanism
*/
CK_MECHANISM_TYPE
@@ -417,208 +425,210 @@ 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_CCM:
- case CKM_AES_CTR:
- case CKM_AES_CTS:
- case CKM_AES_GCM:
- 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:
- case CKM_NSS_TLS_KEY_AND_MAC_DERIVE_SHA256:
- case CKM_NSS_TLS_EXTENDED_MASTER_KEY_DERIVE:
- case CKM_NSS_TLS_EXTENDED_MASTER_KEY_DERIVE_DH:
- 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_NSS_TLS_PRF_GENERAL_SHA256:
- 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;
+ 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_NSS_CHACHA20_POLY1305:
+ return CKM_NSS_CHACHA20_KEY_GEN;
+ case CKM_AES_ECB:
+ case CKM_AES_CBC:
+ case CKM_AES_CCM:
+ case CKM_AES_CTR:
+ case CKM_AES_CTS:
+ case CKM_AES_GCM:
+ 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:
+ case CKM_NSS_TLS_KEY_AND_MAC_DERIVE_SHA256:
+ case CKM_NSS_TLS_EXTENDED_MASTER_KEY_DERIVE:
+ case CKM_NSS_TLS_EXTENDED_MASTER_KEY_DERIVE_DH:
+ 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_NSS_TLS_PRF_GENERAL_SHA256:
+ 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;
}
}
@@ -626,98 +636,98 @@ PK11_GetKeyGenWithSize(CK_MECHANISM_TYPE type, int size)
* get the mechanism block size
*/
int
-PK11_GetBlockSize(CK_MECHANISM_TYPE type,SECItem *params)
+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;
+ 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;
}
}
@@ -728,87 +738,86 @@ 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;
+ 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.
@@ -823,136 +832,141 @@ pk11_ParamFromIVWithLen(CK_MECHANISM_TYPE type, SECItem *iv, int keyLen)
SECItem *param;
param = (SECItem *)PORT_Alloc(sizeof(SECItem));
- if (param == NULL) return NULL;
+ 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;
+ 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
@@ -960,90 +974,90 @@ pk11_ParamFromIVWithLen(CK_MECHANISM_TYPE type, SECItem *iv, int keyLen)
* like SSL and S-MIME to automatically add them.
*/
SECItem *
-PK11_ParamFromIV(CK_MECHANISM_TYPE type,SECItem *iv)
+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)
+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;
+ 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 {
@@ -1055,27 +1069,27 @@ typedef struct sec_rc5cbcParameterStr {
static const SEC_ASN1Template sec_rc5ecb_parameter_template[] = {
{ SEC_ASN1_SEQUENCE,
- 0, NULL, sizeof(sec_rc5cbcParameter) },
+ 0, NULL, sizeof(sec_rc5cbcParameter) },
{ SEC_ASN1_INTEGER,
- offsetof(sec_rc5cbcParameter,version) },
+ offsetof(sec_rc5cbcParameter, version) },
{ SEC_ASN1_INTEGER,
- offsetof(sec_rc5cbcParameter,rounds) },
+ offsetof(sec_rc5cbcParameter, rounds) },
{ SEC_ASN1_INTEGER,
- offsetof(sec_rc5cbcParameter,blockSizeInBits) },
+ offsetof(sec_rc5cbcParameter, blockSizeInBits) },
{ 0 }
};
static const SEC_ASN1Template sec_rc5cbc_parameter_template[] = {
{ SEC_ASN1_SEQUENCE,
- 0, NULL, sizeof(sec_rc5cbcParameter) },
+ 0, NULL, sizeof(sec_rc5cbcParameter) },
{ SEC_ASN1_INTEGER,
- offsetof(sec_rc5cbcParameter,version) },
+ offsetof(sec_rc5cbcParameter, version) },
{ SEC_ASN1_INTEGER,
- offsetof(sec_rc5cbcParameter,rounds) },
+ offsetof(sec_rc5cbcParameter, rounds) },
{ SEC_ASN1_INTEGER,
- offsetof(sec_rc5cbcParameter,blockSizeInBits) },
+ offsetof(sec_rc5cbcParameter, blockSizeInBits) },
{ SEC_ASN1_OCTET_STRING,
- offsetof(sec_rc5cbcParameter,iv) },
+ offsetof(sec_rc5cbcParameter, iv) },
{ 0 }
};
@@ -1086,430 +1100,435 @@ typedef struct sec_rc2cbcParameterStr {
static const SEC_ASN1Template sec_rc2cbc_parameter_template[] = {
{ SEC_ASN1_SEQUENCE,
- 0, NULL, sizeof(sec_rc2cbcParameter) },
+ 0, NULL, sizeof(sec_rc2cbcParameter) },
{ SEC_ASN1_INTEGER,
- offsetof(sec_rc2cbcParameter,rc2ParameterVersion) },
+ offsetof(sec_rc2cbcParameter, rc2ParameterVersion) },
{ SEC_ASN1_OCTET_STRING,
- offsetof(sec_rc2cbcParameter,iv) },
+ offsetof(sec_rc2cbcParameter, iv) },
{ 0 }
};
static const SEC_ASN1Template sec_rc2ecb_parameter_template[] = {
{ SEC_ASN1_SEQUENCE,
- 0, NULL, sizeof(sec_rc2cbcParameter) },
+ 0, NULL, sizeof(sec_rc2cbcParameter) },
{ SEC_ASN1_INTEGER,
- offsetof(sec_rc2cbcParameter,rc2ParameterVersion) },
+ 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)
+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;
+ case 58:
+ return 128;
+ case 120:
+ return 64;
+ case 160:
+ return 40;
}
- return 128;
+ return 128;
}
-static unsigned long rc2_unmap(unsigned long x)
+static unsigned long
+rc2_unmap(unsigned long x)
{
switch (x) {
- case 128: return 58;
- case 64: return 120;
- case 40: return 160;
+ case 128:
+ return 58;
+ case 64:
+ return 120;
+ case 40:
+ return 160;
}
- return 58;
+ 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;
- PLArenaPool * arena = NULL;
- SECItem * mech = NULL;
- SECOidTag algtag;
- SECStatus rv;
- CK_MECHANISM_TYPE type;
+ 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;
+ PLArenaPool *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} };
+ 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;
+ return NULL;
}
mech->type = siBuffer;
mech->data = NULL;
- mech->len = 0;
+ mech->len = 0;
arena = PORT_NewArena(1024);
if (!arena) {
- goto loser;
+ 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;
+ 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);
+ PORT_FreeArena(arena, PR_FALSE);
+ SECITEM_FreeItem(mech, PR_TRUE);
return NULL;
}
/*
- * Generate an IV for the given mechanism
+ * Generate an IV for the given mechanism
*/
static SECStatus
-pk11_GenIV(CK_MECHANISM_TYPE type, SECItem *iv) {
+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;
+ if (iv_size == 0) {
+ iv->data = NULL;
+ return SECSuccess;
}
- iv->data = (unsigned char *) PORT_Alloc(iv_size);
+ iv->data = (unsigned char *)PORT_Alloc(iv_size);
if (iv->data == NULL) {
- iv->len = 0;
- return SECFailure;
+ iv->len = 0;
+ return SECFailure;
}
- rv = PK11_GenerateRandom(iv->data,iv->len);
+ rv = PK11_GenerateRandom(iv->data, iv->len);
if (rv != SECSuccess) {
- PORT_Free(iv->data);
- iv->data = NULL; iv->len = 0;
- return SECFailure;
+ 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)
-{
+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;
+ mech = (SECItem *)PORT_Alloc(sizeof(SECItem));
+ if (mech == NULL)
+ return NULL;
rv = SECSuccess;
mech->type = siBuffer;
mech->data = NULL;
mech->len = 0;
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:
- 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) {
- 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;
+ 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;
+ 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) {
+ 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;
+ 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;
+PK11_GenerateNewParam(CK_MECHANISM_TYPE type, PK11SymKey *key)
+{
+ int keyLen = key ? PK11_GetKeyLength(key) : 0;
return pk11_GenerateNewParamWithKeyLen(type, keyLen);
}
@@ -1518,8 +1537,9 @@ PK11_GenerateNewParam(CK_MECHANISM_TYPE type, PK11SymKey *key)
/* turn a PKCS #11 parameter into a DER Encoded Algorithm ID */
SECStatus
-PK11_ParamToAlgid(SECOidTag algTag, SECItem *param,
- PLArenaPool *arena, SECAlgorithmID *algid) {
+PK11_ParamToAlgid(SECOidTag algTag, SECItem *param,
+ PLArenaPool *arena, SECAlgorithmID *algid)
+{
CK_RC2_CBC_PARAMS *rc2_params;
sec_rc2cbcParameter rc2;
CK_RC5_CBC_PARAMS *rc5_params;
@@ -1530,138 +1550,139 @@ PK11_ParamToAlgid(SECOidTag algTag, SECItem *param,
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) {
+ 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);
- 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;
+ 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;
+ if (rv != SECSuccess) {
+ if (newParams)
+ SECITEM_FreeItem(newParams, PR_TRUE);
+ return rv;
}
rv = SECOID_SetAlgorithmID(arena, algid, algTag, newParams);
- SECITEM_FreeItem(newParams,PR_TRUE);
+ SECITEM_FreeItem(newParams, PR_TRUE);
return rv;
}
@@ -1669,19 +1690,23 @@ PK11_ParamToAlgid(SECOidTag algTag, SECItem *param,
* 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) {
+PK11_AlgtagToMechanism(SECOidTag algTag)
+{
SECOidData *oid = SECOID_FindOIDByTag(algTag);
- if (oid) return (CK_MECHANISM_TYPE) oid->mechanism;
+ 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) {
+PK11_MechanismToAlgtag(CK_MECHANISM_TYPE type)
+{
SECOidData *oid = SECOID_FindOIDByMechanism((unsigned long)type);
- if (oid) return oid->offset;
+ if (oid)
+ return oid->offset;
return SEC_OID_UNKNOWN;
}
@@ -1690,149 +1715,150 @@ PK11_MechanismToAlgtag(CK_MECHANISM_TYPE type) {
* 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;
+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) {
+pk11_isAllZero(unsigned char *data, int len)
+{
while (len--) {
- if (*data++) {
- return PR_FALSE;
- }
+ 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)
+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;
+ 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;
+ 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);
- }
+ 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;
+ 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;
@@ -1843,16 +1869,16 @@ 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;
+ 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;
}
@@ -1861,27 +1887,27 @@ CK_MECHANISM_TYPE
pk11_mapWrapKeyType(KeyType keyType)
{
switch (keyType) {
- case rsaKey:
- return CKM_RSA_PKCS;
- /* Add fortezza?? */
- default:
- break;
+ case rsaKey:
+ return CKM_RSA_PKCS;
+ /* Add fortezza?? */
+ default:
+ break;
}
return CKM_INVALID_MECHANISM;
}
-SECOidTag
+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;
+ 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/nss/lib/pk11wrap/pk11merge.c b/nss/lib/pk11wrap/pk11merge.c
index 8fadc7c..8c4c512 100644
--- a/nss/lib/pk11wrap/pk11merge.c
+++ b/nss/lib/pk11wrap/pk11merge.c
@@ -30,50 +30,74 @@
*/
static SECStatus
pk11_setAttributes(PK11SlotInfo *slot, CK_OBJECT_HANDLE id,
- CK_ATTRIBUTE *setTemplate, CK_ULONG setTemplCount)
+ 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;
+ PORT_SetError(SEC_ERROR_BAD_DATA);
+ return SECFailure;
}
crv = PK11_GETTAB(slot)->C_SetAttributeValue(rwsession, id,
- setTemplate, setTemplCount);
+ setTemplate, setTemplCount);
PK11_RestoreROSession(slot, rwsession);
if (crv != CKR_OK) {
- PORT_SetError(PK11_MapError(crv));
- return SECFailure;
+ 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(PLArenaPool *arena,
- PK11SlotInfo *targetSlot, CK_OBJECT_HANDLE targetID,
- PK11SlotInfo *sourceSlot, CK_OBJECT_HANDLE sourceID,
- CK_ATTRIBUTE *copyTemplate, CK_ULONG copyTemplateCount)
+ 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;
+ SECStatus rv;
+ CK_ATTRIBUTE *newTemplate = NULL;
+ CK_RV crv;
+
+ crv = PK11_GetAttributes(arena, sourceSlot, sourceID,
+ copyTemplate, copyTemplateCount);
+ /* if we have missing attributes, just skip them and create the object */
+ if (crv == CKR_ATTRIBUTE_TYPE_INVALID) {
+ int i, j;
+ newTemplate = PORT_NewArray(CK_ATTRIBUTE, copyTemplateCount);
+ /* remove the unknown attributes. If we don't have enough attributes
+ * PK11_CreateNewObject() will fail */
+ for (i = 0, j = 0; i < copyTemplateCount; i++) {
+ if (copyTemplate[i].ulValueLen != -1) {
+ newTemplate[j] = copyTemplate[i];
+ j++;
+ }
+ }
+ copyTemplate = newTemplate;
+ copyTemplateCount = j;
+ crv = PK11_GetAttributes(arena, sourceSlot, sourceID,
+ copyTemplate, copyTemplateCount);
+ }
+ if (crv != CKR_OK) {
+ PORT_SetError(PK11_MapError(crv));
+ return SECFailure;
}
if (targetID == CK_INVALID_HANDLE) {
- /* we need to create the object */
- rv = PK11_CreateNewObject(targetSlot, CK_INVALID_SESSION,
- copyTemplate, copyTemplateCount, PR_TRUE, &targetID);
+ /* 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);
+ /* update the existing object with the new attributes */
+ rv = pk11_setAttributes(targetSlot, targetID,
+ copyTemplate, copyTemplateCount);
+ }
+ if (newTemplate) {
+ free(newTemplate);
}
return rv;
}
@@ -83,9 +107,9 @@ pk11_copyAttributes(PLArenaPool *arena,
*/
static SECStatus
pk11_matchAcrossTokens(PLArenaPool *arena, PK11SlotInfo *targetSlot,
- PK11SlotInfo *sourceSlot,
- CK_ATTRIBUTE *template, CK_ULONG tsize,
- CK_OBJECT_HANDLE id, CK_OBJECT_HANDLE *peer)
+ PK11SlotInfo *sourceSlot,
+ CK_ATTRIBUTE *template, CK_ULONG tsize,
+ CK_OBJECT_HANDLE id, CK_OBJECT_HANDLE *peer)
{
CK_RV crv;
@@ -93,14 +117,14 @@ pk11_matchAcrossTokens(PLArenaPool *arena, PK11SlotInfo *targetSlot,
crv = PK11_GetAttributes(arena, sourceSlot, id, template, tsize);
if (crv != CKR_OK) {
- PORT_SetError( PK11_MapError(crv) );
- goto loser;
+ PORT_SetError(PK11_MapError(crv));
+ goto loser;
}
if (template[0].ulValueLen == -1) {
- crv = CKR_ATTRIBUTE_TYPE_INVALID;
- PORT_SetError( PK11_MapError(crv) );
- goto loser;
+ crv = CKR_ATTRIBUTE_TYPE_INVALID;
+ PORT_SetError(PK11_MapError(crv));
+ goto loser;
}
*peer = pk11_FindObjectByTemplate(targetSlot, template, tsize);
@@ -115,46 +139,44 @@ loser:
*/
SECStatus
pk11_encrypt(PK11SymKey *symKey, CK_MECHANISM_TYPE mechType, SECItem *param,
- SECItem *input, SECItem **output)
+ SECItem *input, SECItem **output)
{
PK11Context *ctxt = NULL;
SECStatus rv = SECSuccess;
if (*output) {
- SECITEM_FreeItem(*output,PR_TRUE);
+ SECITEM_FreeItem(*output, PR_TRUE);
}
- *output = SECITEM_AllocItem(NULL, NULL, input->len+20 /*slop*/);
+ *output = SECITEM_AllocItem(NULL, NULL, input->len + 20 /*slop*/);
if (!*output) {
- rv = SECFailure;
- goto done;
+ rv = SECFailure;
+ goto done;
}
ctxt = PK11_CreateContextBySymKey(mechType, CKA_ENCRYPT, symKey, param);
if (ctxt == NULL) {
- rv = SECFailure;
- goto done;
+ rv = SECFailure;
+ goto done;
}
- rv = PK11_CipherOp(ctxt, (*output)->data,
- (int *)&((*output)->len),
- (*output)->len, input->data, input->len);
+ 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);
+ PK11_Finalize(ctxt);
+ PK11_DestroyContext(ctxt, PR_TRUE);
}
if (rv != SECSuccess) {
- if (*output) {
- SECITEM_FreeItem(*output, PR_TRUE);
- *output = NULL;
- }
+ if (*output) {
+ SECITEM_FreeItem(*output, PR_TRUE);
+ *output = NULL;
+ }
}
return rv;
}
-
-
/*************************************************************************
*
* Private Keys
@@ -169,23 +191,22 @@ 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_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;
+ 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;
+ 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,
+ * 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
@@ -193,7 +214,7 @@ pk11_getPrivateKeyUsage(PK11SlotInfo *slot, CK_OBJECT_HANDLE id)
*/
static SECStatus
pk11_mergePrivateKey(PK11SlotInfo *targetSlot, PK11SlotInfo *sourceSlot,
- CK_OBJECT_HANDLE id, void *targetPwArg, void *sourcePwArg)
+ CK_OBJECT_HANDLE id, void *targetPwArg, void *sourcePwArg)
{
SECKEYPrivateKey *sourceKey = NULL;
CK_OBJECT_HANDLE targetKeyID;
@@ -208,110 +229,109 @@ pk11_mergePrivateKey(PK11SlotInfo *targetSlot, PK11SlotInfo *sourceSlot,
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 }
+ { CKA_ID, NULL, 0 },
+ { CKA_CLASS, NULL, 0 }
};
- CK_ULONG privTemplateCount = sizeof(privTemplate)/sizeof(privTemplate[0]);
+ CK_ULONG privTemplateCount = sizeof(privTemplate) / sizeof(privTemplate[0]);
CK_ATTRIBUTE privCopyTemplate[] = {
- { CKA_SUBJECT, NULL, 0 }
+ { CKA_SUBJECT, NULL, 0 }
};
- CK_ULONG privCopyTemplateCount =
- sizeof(privCopyTemplate)/sizeof(privCopyTemplate[0]);
+ CK_ULONG privCopyTemplateCount =
+ sizeof(privCopyTemplate) / sizeof(privCopyTemplate[0]);
- arena = PORT_NewArena( DER_DEFAULT_CHUNKSIZE);
+ arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
if (arena == NULL) {
- rv = SECFailure;
- goto done;
+ 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);
+ rv = pk11_matchAcrossTokens(arena, targetSlot, sourceSlot, privTemplate,
+ privTemplateCount, id, &targetKeyID);
if (rv != SECSuccess) {
- goto done;
+ goto done;
}
if (targetKeyID != CK_INVALID_HANDLE) {
- /* match found, not an error ... */
- goto done;
+ /* match found, not an error ... */
+ goto done;
}
/* get an NSS representation of our source key */
- sourceKey = PK11_MakePrivKey(sourceSlot, nullKey, PR_FALSE,
- id, sourcePwArg);
+ sourceKey = PK11_MakePrivKey(sourceSlot, nullKey, PR_FALSE,
+ id, sourcePwArg);
if (sourceKey == NULL) {
- rv = SECFailure;
- goto done;
+ rv = SECFailure;
+ goto done;
}
/* Load the private key */
/* generate a random pwitem */
rv = PK11_GenerateRandom(randomData, sizeof(randomData));
if (rv != SECSuccess) {
- goto done;
+ goto done;
}
pwitem.data = randomData;
pwitem.len = sizeof(randomData);
/* fetch the private key encrypted */
- epki = PK11_ExportEncryptedPrivKeyInfo(sourceSlot, algTag, &pwitem,
- sourceKey, 1, sourcePwArg);
+ epki = PK11_ExportEncryptedPrivKeyInfo(sourceSlot, algTag, &pwitem,
+ sourceKey, 1, sourcePwArg);
if (epki == NULL) {
- rv = SECFailure;
- goto done;
+ 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);
+ 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);
+ nickname ? &nickItem : NULL, &publicValue,
+ PR_TRUE, PR_TRUE, sourceKey->keyType, keyUsage,
+ targetPwArg);
if (rv != SECSuccess) {
- goto done;
+ goto done;
}
/* make sure it made it */
- rv = pk11_matchAcrossTokens(arena, targetSlot, sourceSlot, privTemplate,
- privTemplateCount, id, &targetKeyID);
+ rv = pk11_matchAcrossTokens(arena, targetSlot, sourceSlot, privTemplate,
+ privTemplateCount, id, &targetKeyID);
if (rv != SECSuccess) {
- goto done;
+ goto done;
}
if (targetKeyID == CK_INVALID_HANDLE) {
- /* this time the key should exist */
- rv = SECFailure;
- goto done;
+ /* this time the key should exist */
+ rv = SECFailure;
+ goto done;
}
/* fill in remaining attributes */
rv = pk11_copyAttributes(arena, targetSlot, targetKeyID, sourceSlot, id,
- privCopyTemplate, privCopyTemplateCount);
+ privCopyTemplate, privCopyTemplateCount);
done:
/* make sure the 'key' is cleared */
PORT_Memset(randomData, 0, sizeof(randomData));
if (nickname) {
- PORT_Free(nickname);
+ PORT_Free(nickname);
}
if (sourceKey) {
- SECKEY_DestroyPrivateKey(sourceKey);
+ SECKEY_DestroyPrivateKey(sourceKey);
}
if (epki) {
- SECKEY_DestroyEncryptedPrivateKeyInfo(epki, PR_TRUE);
+ SECKEY_DestroyEncryptedPrivateKeyInfo(epki, PR_TRUE);
}
if (arena) {
- PORT_FreeArena(arena,PR_FALSE);
+ PORT_FreeArena(arena, PR_FALSE);
}
return rv;
}
-
/*************************************************************************
*
* Secret Keys
@@ -322,12 +342,12 @@ done:
* 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
+ * 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
+ * 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
@@ -337,76 +357,75 @@ pk11_incrementID(PLArenaPool *arena, CK_ATTRIBUTE *ptemplate)
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;
+ /* 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 */
- }
+ 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);
+ buf = PORT_ArenaZAlloc(arena, len + 1);
if (buf == NULL) {
- return SECFailure;
+ return SECFailure;
}
ptemplate->pValue = buf;
- ptemplate->ulValueLen = len+1;
+ 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;
+ flags |= CKF_UNWRAP;
}
if (PK11_HasAttributeSet(slot, id, CKA_WRAP, PR_FALSE)) {
- flags |= CKF_WRAP;
+ flags |= CKF_WRAP;
}
if (PK11_HasAttributeSet(slot, id, CKA_ENCRYPT, PR_FALSE)) {
- flags |= CKF_ENCRYPT;
+ flags |= CKF_ENCRYPT;
}
if (PK11_HasAttributeSet(slot, id, CKA_DECRYPT, PR_FALSE)) {
- flags |= CKF_DECRYPT;
+ flags |= CKF_DECRYPT;
}
if (PK11_HasAttributeSet(slot, id, CKA_DERIVE, PR_FALSE)) {
- flags |= CKF_DERIVE;
+ flags |= CKF_DERIVE;
}
if (PK11_HasAttributeSet(slot, id, CKA_SIGN, PR_FALSE)) {
- flags |= CKF_SIGN;
+ flags |= CKF_SIGN;
}
if (PK11_HasAttributeSet(slot, id, CKA_SIGN_RECOVER, PR_FALSE)) {
- flags |= CKF_SIGN_RECOVER;
+ flags |= CKF_SIGN_RECOVER;
}
if (PK11_HasAttributeSet(slot, id, CKA_VERIFY, PR_FALSE)) {
- flags |= CKF_VERIFY;
+ flags |= CKF_VERIFY;
}
if (PK11_HasAttributeSet(slot, id, CKA_VERIFY_RECOVER, PR_FALSE)) {
- flags |= CKF_VERIFY_RECOVER;
+ flags |= CKF_VERIFY_RECOVER;
}
return flags;
}
-static const char testString[] =
- "My Encrytion Test Data (should be at least 32 bytes long)";
+static const char testString[] =
+ "My Encrytion Test Data (should be at least 32 bytes long)";
/*
- * merge a secret key,
+ * 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.
@@ -414,7 +433,7 @@ static const char testString[] =
* 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
@@ -422,7 +441,7 @@ static const char testString[] =
*/
static SECStatus
pk11_mergeSecretKey(PK11SlotInfo *targetSlot, PK11SlotInfo *sourceSlot,
- CK_OBJECT_HANDLE id, void *targetPwArg, void *sourcePwArg)
+ CK_OBJECT_HANDLE id, void *targetPwArg, void *sourcePwArg)
{
PK11SymKey *sourceKey = NULL;
PK11SymKey *targetKey = NULL;
@@ -438,26 +457,26 @@ pk11_mergeSecretKey(PK11SlotInfo *targetSlot, PK11SlotInfo *sourceSlot,
CK_MECHANISM_TYPE keyMechType, cryptoMechType;
CK_KEY_TYPE sourceKeyType, targetKeyType;
CK_ATTRIBUTE symTemplate[] = {
- { CKA_ID, NULL, 0 },
- { CKA_CLASS, NULL, 0 }
+ { CKA_ID, NULL, 0 },
+ { CKA_CLASS, NULL, 0 }
};
- CK_ULONG symTemplateCount = sizeof(symTemplate)/sizeof(symTemplate[0]);
+ CK_ULONG symTemplateCount = sizeof(symTemplate) / sizeof(symTemplate[0]);
CK_ATTRIBUTE symCopyTemplate[] = {
- { CKA_LABEL, NULL, 0 }
+ { CKA_LABEL, NULL, 0 }
};
- CK_ULONG symCopyTemplateCount =
- sizeof(symCopyTemplate)/sizeof(symCopyTemplate[0]);
+ CK_ULONG symCopyTemplateCount =
+ sizeof(symCopyTemplate) / sizeof(symCopyTemplate[0]);
- arena = PORT_NewArena( DER_DEFAULT_CHUNKSIZE);
+ arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
if (arena == NULL) {
- rv = SECFailure;
- goto done;
+ rv = SECFailure;
+ goto done;
}
sourceKeyType = PK11_ReadULongAttribute(sourceSlot, id, CKA_KEY_TYPE);
- if (sourceKeyType == (CK_ULONG) -1) {
- rv = SECFailure;
- goto done;
+ if (sourceKeyType == (CK_ULONG)-1) {
+ rv = SECFailure;
+ goto done;
}
/* get the key mechanism */
@@ -467,124 +486,124 @@ pk11_mergeSecretKey(PK11SlotInfo *targetSlot, PK11SlotInfo *sourceSlot,
* 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;
+ 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);
+ keyMechType, id, PR_FALSE, sourcePwArg);
if (sourceKey == NULL) {
- rv = SECFailure;
- goto done;
+ rv = SECFailure;
+ goto done;
}
- /* check to see a key with the same CKA_ID already exists in
+ /* 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);
+ symTemplate, symTemplateCount, id, &targetKeyID);
if (rv != SECSuccess) {
- goto done;
+ goto done;
}
/* set up the input test */
input.data = (unsigned char *)testString;
blockSize = PK11_GetBlockSize(cryptoMechType, NULL);
if (blockSize < 0) {
- rv = SECFailure;
- goto done;
+ rv = SECFailure;
+ goto done;
}
input.len = blockSize;
if (input.len == 0) {
- input.len = sizeof (testString);
+ 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);
+ /* 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);
+ sourceKey);
if (targetKey == NULL) {
- rv = SECFailure;
- goto done;
+ rv = SECFailure;
+ goto done;
}
/* set the key new CKAID */
rv = pk11_setAttributes(targetSlot, targetKey->objectID, symTemplate, 1);
if (rv != SECSuccess) {
- goto done;
+ goto done;
}
/* fill in remaining attributes */
- rv = pk11_copyAttributes(arena, targetSlot, targetKey->objectID,
- sourceSlot, id, symCopyTemplate, symCopyTemplateCount);
+ rv = pk11_copyAttributes(arena, targetSlot, targetKey->objectID,
+ sourceSlot, id, symCopyTemplate, symCopyTemplateCount);
done:
if (sourceKey) {
- PK11_FreeSymKey(sourceKey);
+ PK11_FreeSymKey(sourceKey);
}
if (targetKey) {
- PK11_FreeSymKey(targetKey);
+ PK11_FreeSymKey(targetKey);
}
if (sourceOutput) {
- SECITEM_FreeItem(sourceOutput, PR_TRUE);
+ SECITEM_FreeItem(sourceOutput, PR_TRUE);
}
if (targetOutput) {
- SECITEM_FreeItem(targetOutput, PR_TRUE);
+ SECITEM_FreeItem(targetOutput, PR_TRUE);
}
if (param) {
- SECITEM_FreeItem(param, PR_TRUE);
+ SECITEM_FreeItem(param, PR_TRUE);
}
if (arena) {
- PORT_FreeArena(arena,PR_FALSE);
+ PORT_FreeArena(arena, PR_FALSE);
}
return rv;
}
@@ -603,70 +622,68 @@ done:
*/
static SECStatus
pk11_mergePublicKey(PK11SlotInfo *targetSlot, PK11SlotInfo *sourceSlot,
- CK_OBJECT_HANDLE id, void *targetPwArg, void *sourcePwArg)
+ CK_OBJECT_HANDLE id, void *targetPwArg, void *sourcePwArg)
{
SECKEYPublicKey *sourceKey = NULL;
CK_OBJECT_HANDLE targetKeyID;
PLArenaPool *arena = NULL;
SECStatus rv = SECSuccess;
CK_ATTRIBUTE pubTemplate[] = {
- { CKA_ID, NULL, 0 },
- { CKA_CLASS, NULL, 0 }
+ { CKA_ID, NULL, 0 },
+ { CKA_CLASS, NULL, 0 }
};
- CK_ULONG pubTemplateCount = sizeof(pubTemplate)/sizeof(pubTemplate[0]);
+ CK_ULONG pubTemplateCount = sizeof(pubTemplate) / sizeof(pubTemplate[0]);
CK_ATTRIBUTE pubCopyTemplate[] = {
- { CKA_ID, NULL, 0 },
- { CKA_LABEL, NULL, 0 },
- { CKA_SUBJECT, NULL, 0 }
+ { CKA_ID, NULL, 0 },
+ { CKA_LABEL, NULL, 0 },
+ { CKA_SUBJECT, NULL, 0 }
};
- CK_ULONG pubCopyTemplateCount =
- sizeof(pubCopyTemplate)/sizeof(pubCopyTemplate[0]);
+ CK_ULONG pubCopyTemplateCount =
+ sizeof(pubCopyTemplate) / sizeof(pubCopyTemplate[0]);
- arena = PORT_NewArena( DER_DEFAULT_CHUNKSIZE);
+ arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
if (arena == NULL) {
- rv = SECFailure;
- goto done;
+ 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);
+ rv = pk11_matchAcrossTokens(arena, targetSlot, sourceSlot, pubTemplate,
+ pubTemplateCount, id, &targetKeyID);
if (rv != SECSuccess) {
- goto done;
+ goto done;
}
/* Key is already in the target slot */
if (targetKeyID != CK_INVALID_HANDLE) {
- /* not an error ... */
- goto done;
+ /* 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;
+ 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;
+ rv = SECFailure;
+ goto done;
}
/* fill in remaining attributes */
rv = pk11_copyAttributes(arena, targetSlot, targetKeyID, sourceSlot, id,
- pubCopyTemplate, pubCopyTemplateCount);
-
+ pubCopyTemplate, pubCopyTemplateCount);
done:
if (sourceKey) {
- SECKEY_DestroyPublicKey(sourceKey);
+ SECKEY_DestroyPublicKey(sourceKey);
}
if (arena) {
- PORT_FreeArena(arena,PR_FALSE);
+ PORT_FreeArena(arena, PR_FALSE);
}
return rv;
}
@@ -678,7 +695,7 @@ done:
*************************************************************************/
/*
- * Two copies of the source code for this algorithm exist in NSS.
+ * 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.
*/
@@ -691,44 +708,45 @@ pk11_IncrementNickname(char *nickname)
int len = strlen(nickname);
/* does nickname end with " #n*" ? */
- for (end = len - 1;
- end >= 2 && (digit = nickname[end]) <= '9' && digit >= '0';
- end--) /* just scan */ ;
+ 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 */
+ 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';
+ /* ... 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;
+ newNickname[++end] = '1';
+ PORT_Memset(&newNickname[end + 1], '0', len - end);
+ newNickname[len + 1] = 0;
} else {
- PORT_Free(nickname);
+ PORT_Free(nickname);
}
return newNickname;
}
@@ -740,22 +758,22 @@ pk11_IncrementNickname(char *nickname)
*/
static SECStatus
pk11_mergeCert(PK11SlotInfo *targetSlot, PK11SlotInfo *sourceSlot,
- CK_OBJECT_HANDLE id, void *targetPwArg, void *sourcePwArg)
+ CK_OBJECT_HANDLE id, void *targetPwArg, void *sourcePwArg)
{
CERTCertificate *sourceCert = NULL;
CK_OBJECT_HANDLE targetCertID = CK_INVALID_HANDLE;
char *nickname = NULL;
SECStatus rv = SECSuccess;
PLArenaPool *arena = NULL;
- CK_ATTRIBUTE sourceCKAID = {CKA_ID, NULL, 0};
- CK_ATTRIBUTE targetCKAID = {CKA_ID, NULL, 0};
+ CK_ATTRIBUTE sourceCKAID = { CKA_ID, NULL, 0 };
+ CK_ATTRIBUTE targetCKAID = { CKA_ID, NULL, 0 };
SECStatus lrv = SECSuccess;
int error = SEC_ERROR_LIBRARY_FAILURE;
sourceCert = PK11_MakeCertFromHandle(sourceSlot, id, NULL);
if (sourceCert == NULL) {
- rv = SECFailure;
- goto done;
+ rv = SECFailure;
+ goto done;
}
nickname = PK11_GetObjectNickname(sourceSlot, id);
@@ -764,107 +782,104 @@ pk11_mergeCert(PK11SlotInfo *targetSlot, PK11SlotInfo *sourceSlot,
* 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);
- }
- }
-
-
+ 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;
+ /* 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);
+ arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
if (arena == NULL) {
- rv = SECFailure;
- goto done;
+ rv = SECFailure;
+ goto done;
}
/* does our source have a CKA_ID ? */
- rv = PK11_GetAttributes(arena, sourceSlot, id, &sourceCKAID, 1);
+ rv = PK11_GetAttributes(arena, sourceSlot, id, &sourceCKAID, 1);
if (rv != SECSuccess) {
- sourceCKAID.ulValueLen = 0;
+ 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 = 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);
- }
+ 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);
+ rv = lrv;
+ PORT_SetError(error);
}
done:
if (nickname) {
- PORT_Free(nickname);
+ PORT_Free(nickname);
}
if (sourceCert) {
- CERT_DestroyCertificate(sourceCert);
+ CERT_DestroyCertificate(sourceCert);
}
if (arena) {
- PORT_FreeArena(arena,PR_FALSE);
+ PORT_FreeArena(arena, PR_FALSE);
}
return rv;
}
-
/*************************************************************************
*
* Crls
@@ -878,53 +893,53 @@ done:
*/
static SECStatus
pk11_mergeCrl(PK11SlotInfo *targetSlot, PK11SlotInfo *sourceSlot,
- CK_OBJECT_HANDLE id, void *targetPwArg, void *sourcePwArg)
+ CK_OBJECT_HANDLE id, void *targetPwArg, void *sourcePwArg)
{
CK_OBJECT_HANDLE targetCrlID;
PLArenaPool *arena = NULL;
SECStatus rv = SECSuccess;
CK_ATTRIBUTE crlTemplate[] = {
- { CKA_SUBJECT, NULL, 0 },
- { CKA_CLASS, NULL, 0 },
- { CKA_NSS_KRL, NULL, 0 }
+ { CKA_SUBJECT, NULL, 0 },
+ { CKA_CLASS, NULL, 0 },
+ { CKA_NSS_KRL, NULL, 0 }
};
- CK_ULONG crlTemplateCount = sizeof(crlTemplate)/sizeof(crlTemplate[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 }
+ { 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]);
+ CK_ULONG crlCopyTemplateCount =
+ sizeof(crlCopyTemplate) / sizeof(crlCopyTemplate[0]);
- arena = PORT_NewArena( DER_DEFAULT_CHUNKSIZE);
+ arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
if (arena == NULL) {
- rv = SECFailure;
- goto done;
+ 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);
+ rv = pk11_matchAcrossTokens(arena, targetSlot, sourceSlot, crlTemplate,
+ crlTemplateCount, id, &targetCrlID);
if (rv != SECSuccess) {
- goto done;
+ goto done;
}
if (targetCrlID != CK_INVALID_HANDLE) {
- /* we already have a CRL, check to see which is more up-to-date. */
- goto done;
+ /* 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);
+ crlCopyTemplate, crlCopyTemplateCount);
done:
if (arena) {
- PORT_FreeArena(arena,PR_FALSE);
+ PORT_FreeArena(arena, PR_FALSE);
}
return rv;
}
@@ -940,54 +955,54 @@ done:
*/
static SECStatus
pk11_mergeSmime(PK11SlotInfo *targetSlot, PK11SlotInfo *sourceSlot,
- CK_OBJECT_HANDLE id, void *targetPwArg, void *sourcePwArg)
+ CK_OBJECT_HANDLE id, void *targetPwArg, void *sourcePwArg)
{
CK_OBJECT_HANDLE targetSmimeID;
PLArenaPool *arena = NULL;
SECStatus rv = SECSuccess;
CK_ATTRIBUTE smimeTemplate[] = {
- { CKA_SUBJECT, NULL, 0 },
- { CKA_NSS_EMAIL, NULL, 0 },
- { CKA_CLASS, NULL, 0 },
+ { CKA_SUBJECT, NULL, 0 },
+ { CKA_NSS_EMAIL, NULL, 0 },
+ { CKA_CLASS, NULL, 0 },
};
- CK_ULONG smimeTemplateCount =
- sizeof(smimeTemplate)/sizeof(smimeTemplate[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 }
+ { 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]);
+ CK_ULONG smimeCopyTemplateCount =
+ sizeof(smimeCopyTemplate) / sizeof(smimeCopyTemplate[0]);
- arena = PORT_NewArena( DER_DEFAULT_CHUNKSIZE);
+ arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
if (arena == NULL) {
- rv = SECFailure;
- goto done;
+ 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);
+ rv = pk11_matchAcrossTokens(arena, targetSlot, sourceSlot, smimeTemplate,
+ smimeTemplateCount, id, &targetSmimeID);
if (rv != SECSuccess) {
- goto done;
+ goto done;
}
if (targetSmimeID != CK_INVALID_HANDLE) {
- /* we already have a SMIME record */
- goto done;
+ /* 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);
+ smimeCopyTemplate, smimeCopyTemplateCount);
done:
if (arena) {
- PORT_FreeArena(arena,PR_FALSE);
+ PORT_FreeArena(arena, PR_FALSE);
}
return rv;
}
@@ -998,7 +1013,6 @@ done:
*
*************************************************************************/
-
/*
* decide which trust record entry wins. PR_TRUE (source) or PR_FALSE (target)
*/
@@ -1007,10 +1021,10 @@ done:
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;
+ 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
@@ -1018,38 +1032,38 @@ pk11_mergeTrustEntry(CK_ATTRIBUTE *target, CK_ATTRIBUTE *source)
* 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
+ * case where the source wins). If the source wins, it already
*/
if (sourceTrust == targetTrust) {
- return USE_TARGET; /* which equates to 'do nothing' */
+ return USE_TARGET; /* which equates to 'do nothing' */
}
if (sourceTrust == CKT_NSS_TRUST_UNKNOWN) {
- return USE_TARGET;
+ 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;
+ /* 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.
+ /* 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 ((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;
+ 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. */
@@ -1060,117 +1074,116 @@ pk11_mergeTrustEntry(CK_ATTRIBUTE *target, CK_ATTRIBUTE *source)
*/
static SECStatus
pk11_mergeTrust(PK11SlotInfo *targetSlot, PK11SlotInfo *sourceSlot,
- CK_OBJECT_HANDLE id, void *targetPwArg, void *sourcePwArg)
+ CK_OBJECT_HANDLE id, void *targetPwArg, void *sourcePwArg)
{
CK_OBJECT_HANDLE targetTrustID;
PLArenaPool *arena = NULL;
SECStatus rv = SECSuccess;
int error = 0;
CK_ATTRIBUTE trustTemplate[] = {
- { CKA_ISSUER, NULL, 0 },
- { CKA_SERIAL_NUMBER, NULL, 0 },
- { CKA_CLASS, NULL, 0 },
+ { CKA_ISSUER, NULL, 0 },
+ { CKA_SERIAL_NUMBER, NULL, 0 },
+ { CKA_CLASS, NULL, 0 },
};
- CK_ULONG trustTemplateCount =
- sizeof(trustTemplate)/sizeof(trustTemplate[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 }
+ { 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]);
+ CK_ULONG trustCopyTemplateCount =
+ sizeof(trustCopyTemplate) / sizeof(trustCopyTemplate[0]);
- arena = PORT_NewArena( DER_DEFAULT_CHUNKSIZE);
+ arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
if (arena == NULL) {
- rv = SECFailure;
- goto done;
+ 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);
+ rv = pk11_matchAcrossTokens(arena, targetSlot, sourceSlot, trustTemplate,
+ trustTemplateCount, id, &targetTrustID);
if (rv != SECSuccess) {
- goto done;
+ 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;
-
+ /* 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);
+ trustCopyTemplate, trustCopyTemplateCount);
done:
if (arena) {
- PORT_FreeArena(arena,PR_FALSE);
+ PORT_FreeArena(arena, PR_FALSE);
}
/* restore the error code */
if (rv == SECFailure && error) {
- PORT_SetError(error);
+ PORT_SetError(error);
}
-
+
return rv;
}
@@ -1184,70 +1197,69 @@ done:
*/
static SECStatus
pk11_mergeObject(PK11SlotInfo *targetSlot, PK11SlotInfo *sourceSlot,
- CK_OBJECT_HANDLE id, void *targetPwArg, void *sourcePwArg)
+ 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;
+ 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 );
+ 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(PLArenaPool *arena,
- PK11SlotInfo *slot, CK_OBJECT_HANDLE id, int error)
+ PK11SlotInfo *slot, CK_OBJECT_HANDLE id, int error)
{
PK11MergeLogNode *newLog;
PK11GenericObject *obj;
newLog = PORT_ArenaZNew(arena, PK11MergeLogNode);
if (newLog == NULL) {
- return NULL;
+ return NULL;
}
obj = PORT_ArenaZNew(arena, PK11GenericObject);
- if ( !obj ) {
- return NULL;
+ if (!obj) {
+ return NULL;
}
/* initialize it */
obj->slot = slot;
obj->objectID = id;
- newLog->object= obj;
+ newLog->object = obj;
newLog->error = error;
return newLog;
}
@@ -1257,63 +1269,63 @@ pk11_newMergeLogNode(PLArenaPool *arena,
*/
static SECStatus
pk11_mergeByObjectIDs(PK11SlotInfo *targetSlot, PK11SlotInfo *sourceSlot,
- CK_OBJECT_HANDLE *objectIDs, int count,
- PK11MergeLog *log, void *targetPwArg, void *sourcePwArg)
+ CK_OBJECT_HANDLE *objectIDs, int count,
+ PK11MergeLog *log, void *targetPwArg, void *sourcePwArg)
{
SECStatus rv = SECSuccess;
int error = SEC_ERROR_LIBRARY_FAILURE;
int 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;
+
+ 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);
+ 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.
*
@@ -1323,7 +1335,7 @@ pk11_mergeByObjectIDs(PK11SlotInfo *targetSlot, PK11SlotInfo *sourceSlot,
*/
SECStatus
PK11_MergeTokens(PK11SlotInfo *targetSlot, PK11SlotInfo *sourceSlot,
- PK11MergeLog *log, void *targetPwArg, void *sourcePwArg)
+ PK11MergeLog *log, void *targetPwArg, void *sourcePwArg)
{
SECStatus rv = SECSuccess, lrv = SECSuccess;
int error = SEC_ERROR_LIBRARY_FAILURE;
@@ -1340,25 +1352,25 @@ PK11_MergeTokens(PK11SlotInfo *targetSlot, PK11SlotInfo *sourceSlot,
*/
rv = PK11_Authenticate(targetSlot, PR_TRUE, targetPwArg);
if (rv != SECSuccess) {
- goto loser;
+ goto loser;
}
rv = PK11_Authenticate(sourceSlot, PR_TRUE, sourcePwArg);
if (rv != SECSuccess) {
- goto loser;
+ 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;
+ 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
@@ -1366,26 +1378,26 @@ PK11_MergeTokens(PK11SlotInfo *targetSlot, PK11SlotInfo *sourceSlot,
* merged in */
objectIDs = pk11_FindObjectsByTemplate(sourceSlot, search, 1, &count);
if (!objectIDs) {
- rv = SECFailure;
- goto loser;
+ rv = SECFailure;
+ goto loser;
}
- rv = pk11_mergeByObjectIDs(targetSlot, sourceSlot, objectIDs, count, log,
- targetPwArg, sourcePwArg);
+ 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);
- }
+ /* 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);
+ PORT_Free(objectIDs);
}
return rv;
}
@@ -1396,15 +1408,15 @@ PK11_CreateMergeLog(void)
PLArenaPool *arena;
PK11MergeLog *log;
- arena = PORT_NewArena( DER_DEFAULT_CHUNKSIZE);
+ arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
if (arena == NULL) {
- return NULL;
+ return NULL;
}
log = PORT_ArenaZNew(arena, PK11MergeLog);
if (log == NULL) {
- PORT_FreeArena(arena,PR_FALSE);
- return NULL;
+ PORT_FreeArena(arena, PR_FALSE);
+ return NULL;
}
log->arena = arena;
log->version = 1;
@@ -1414,7 +1426,7 @@ PK11_CreateMergeLog(void)
void
PK11_DestroyMergeLog(PK11MergeLog *log)
{
- if (log && log->arena) {
- PORT_FreeArena(log->arena, PR_FALSE);
+ if (log && log->arena) {
+ PORT_FreeArena(log->arena, PR_FALSE);
}
}
diff --git a/nss/lib/pk11wrap/pk11nobj.c b/nss/lib/pk11wrap/pk11nobj.c
index dcca434..41d1d96 100644
--- a/nss/lib/pk11wrap/pk11nobj.c
+++ b/nss/lib/pk11wrap/pk11nobj.c
@@ -14,20 +14,20 @@
#include "pkcs11.h"
#include "pk11func.h"
#include "cert.h"
-#include "certi.h"
+#include "certi.h"
#include "secitem.h"
-#include "sechash.h"
+#include "sechash.h"
#include "secoid.h"
-#include "certdb.h"
+#include "certdb.h"
#include "secerr.h"
#include "pki3hack.h"
-#include "dev3hack.h"
+#include "dev3hack.h"
-#include "devm.h"
+#include "devm.h"
#include "pki.h"
-#include "pkim.h"
+#include "pkim.h"
extern const NSSError NSS_ERROR_NOT_FOUND;
@@ -35,135 +35,135 @@ CK_TRUST
pk11_GetTrustField(PK11SlotInfo *slot, PLArenaPool *arena,
CK_OBJECT_HANDLE id, CK_ATTRIBUTE_TYPE type)
{
- CK_TRUST rv = 0;
- SECItem item;
+ CK_TRUST rv = 0;
+ SECItem item;
- item.data = NULL;
- item.len = 0;
+ 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;
- }
+ 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;
+ return 0;
}
PRBool
pk11_HandleTrustObject(PK11SlotInfo *slot, CERTCertificate *cert, CERTCertTrust *trust)
{
- PLArenaPool *arena;
-
- CK_ATTRIBUTE tobjTemplate[] = {
- { CKA_CLASS, NULL, 0 },
- { CKA_CERT_SHA1_HASH, NULL, 0 },
- };
+ PLArenaPool *arena;
- CK_OBJECT_CLASS tobjc = CKO_NETSCAPE_TRUST;
- CK_OBJECT_HANDLE tobjID;
- unsigned char sha1_hash[SHA1_LENGTH];
+ CK_ATTRIBUTE tobjTemplate[] = {
+ { CKA_CLASS, NULL, 0 },
+ { CKA_CERT_SHA1_HASH, NULL, 0 },
+ };
- CK_TRUST serverAuth, codeSigning, emailProtection, clientAuth;
+ CK_OBJECT_CLASS tobjc = CKO_NETSCAPE_TRUST;
+ CK_OBJECT_HANDLE tobjID;
+ unsigned char sha1_hash[SHA1_LENGTH];
- PK11_HashBuf(SEC_OID_SHA1, sha1_hash, cert->derCert.data, cert->derCert.len);
+ CK_TRUST serverAuth, codeSigning, emailProtection, clientAuth;
- PK11_SETATTRS(&tobjTemplate[0], CKA_CLASS, &tobjc, sizeof(tobjc));
- PK11_SETATTRS(&tobjTemplate[1], CKA_CERT_SHA1_HASH, sha1_hash,
- SHA1_LENGTH);
+ PK11_HashBuf(SEC_OID_SHA1, sha1_hash, cert->derCert.data, cert->derCert.len);
- tobjID = pk11_FindObjectByTemplate(slot, tobjTemplate,
- sizeof(tobjTemplate)/sizeof(tobjTemplate[0]));
- if( CK_INVALID_HANDLE == tobjID ) {
- return PR_FALSE;
- }
+ PK11_SETATTRS(&tobjTemplate[0], CKA_CLASS, &tobjc, sizeof(tobjc));
+ PK11_SETATTRS(&tobjTemplate[1], CKA_CERT_SHA1_HASH, sha1_hash,
+ SHA1_LENGTH);
- arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
- if( NULL == arena ) return PR_FALSE;
+ tobjID = pk11_FindObjectByTemplate(slot, tobjTemplate,
+ sizeof(tobjTemplate) / sizeof(tobjTemplate[0]));
+ if (CK_INVALID_HANDLE == tobjID) {
+ 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.
- */
+ arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
+ if (NULL == arena)
+ return PR_FALSE;
- /* We could verify CKA_CERT_HASH here */
+ /* 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_EXPIRES here */
+ /* 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. */
+ /* "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 */
+ /* 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) {
+ 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 (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) {
+ 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 (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) {
+ 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;
- }
+ 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.. */
+ /* There's certainly a lot more logic that can go here.. */
- PORT_FreeArena(arena, PR_FALSE);
+ PORT_FreeArena(arena, PR_FALSE);
- return PR_TRUE;
+ return PR_TRUE;
}
static SECStatus
pk11_CollectCrls(PK11SlotInfo *slot, CK_OBJECT_HANDLE crlID, void *arg)
{
SECItem derCrl;
- CERTCrlHeadNode *head = (CERTCrlHeadNode *) arg;
+ 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},
+ { CKA_VALUE, NULL, 0 },
+ { CKA_NETSCAPE_KRL, NULL, 0 },
+ { CKA_NETSCAPE_URL, NULL, 0 },
};
- const int fetchCrlSize = sizeof(fetchCrl)/sizeof(fetchCrl[2]);
+ const int fetchCrlSize = sizeof(fetchCrl) / sizeof(fetchCrl[2]);
CK_RV crv;
SECStatus rv = SECFailure;
- crv = PK11_GetAttributes(head->arena,slot,crlID,fetchCrl,fetchCrlSize);
+ crv = PK11_GetAttributes(head->arena, slot, crlID, fetchCrl, fetchCrlSize);
if (CKR_OK != crv) {
- PORT_SetError(PK11_MapError(crv));
- goto loser;
+ PORT_SetError(PK11_MapError(crv));
+ goto loser;
}
if (!fetchCrl[1].pValue) {
- PORT_SetError(SEC_ERROR_CRL_INVALID);
- goto loser;
+ PORT_SetError(SEC_ERROR_CRL_INVALID);
+ goto loser;
}
new_node = (CERTCrlNode *)PORT_ArenaAlloc(head->arena, sizeof(CERTCrlNode));
@@ -179,15 +179,15 @@ pk11_CollectCrls(PK11SlotInfo *slot, CK_OBJECT_HANDLE crlID, void *arg)
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);
+ new_node->crl = CERT_DecodeDERCrl(head->arena, &derCrl, new_node->type);
if (new_node->crl == NULL) {
- goto loser;
+ 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 ) {
+ 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);
@@ -196,7 +196,6 @@ pk11_CollectCrls(PK11SlotInfo *slot, CK_OBJECT_HANDLE crlID, void *arg)
new_node->crl->url = NULL;
}
-
new_node->next = NULL;
if (head->last) {
head->last->next = new_node;
@@ -207,7 +206,7 @@ pk11_CollectCrls(PK11SlotInfo *slot, CK_OBJECT_HANDLE crlID, void *arg)
rv = SECSuccess;
loser:
- return(rv);
+ return (rv);
}
/*
@@ -215,7 +214,8 @@ loser:
* CRLs are allocated in the list's arena.
*/
SECStatus
-PK11_LookupCrls(CERTCrlHeadNode *nodes, int type, void *wincx) {
+PK11_LookupCrls(CERTCrlHeadNode *nodes, int type, void *wincx)
+{
pk11TraverseSlot creater;
CK_ATTRIBUTE theTemplate[2];
CK_ATTRIBUTE *attrs;
@@ -223,14 +223,16 @@ PK11_LookupCrls(CERTCrlHeadNode *nodes, int type, void *wincx) {
CK_BBOOL isKrl = CK_FALSE;
attrs = theTemplate;
- PK11_SETATTRS(attrs, CKA_CLASS, &certClass, sizeof(certClass)); attrs++;
+ 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++;
+ 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.callbackArg = (void *)nodes;
creater.findTemplate = theTemplate;
creater.templateCount = (attrs - theTemplate);
@@ -238,7 +240,7 @@ PK11_LookupCrls(CERTCrlHeadNode *nodes, int type, void *wincx) {
}
struct crlOptionsStr {
- CERTCrlHeadNode* head;
+ CERTCrlHeadNode *head;
PRInt32 decodeOptions;
};
@@ -248,32 +250,32 @@ static SECStatus
pk11_RetrieveCrlsCallback(PK11SlotInfo *slot, CK_OBJECT_HANDLE crlID,
void *arg)
{
- SECItem* derCrl = NULL;
- crlOptions* options = (crlOptions*) 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},
+ { CKA_VALUE, NULL, 0 },
+ { CKA_NETSCAPE_KRL, NULL, 0 },
+ { CKA_NETSCAPE_URL, NULL, 0 },
};
- const int fetchCrlSize = sizeof(fetchCrl)/sizeof(fetchCrl[2]);
+ 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);
+ crv = PK11_GetAttributes(NULL, slot, crlID, fetchCrl, fetchCrlSize);
if (CKR_OK != crv) {
- PORT_SetError(PK11_MapError(crv));
- goto loser;
+ PORT_SetError(PK11_MapError(crv));
+ goto loser;
}
if (!fetchCrl[1].pValue) {
/* reject KRLs */
- PORT_SetError(SEC_ERROR_CRL_INVALID);
- goto loser;
+ PORT_SetError(SEC_ERROR_CRL_INVALID);
+ goto loser;
}
new_node = (CERTCrlNode *)PORT_ArenaAlloc(head->arena,
@@ -291,20 +293,20 @@ pk11_RetrieveCrlsCallback(PK11SlotInfo *slot, CK_OBJECT_HANDLE crlID,
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,
+ new_node->crl = CERT_DecodeDERCrlWithFlags(NULL, derCrl, new_node->type,
options->decodeOptions);
if (new_node->crl == NULL) {
- goto loser;
- }
+ 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 ) {
+ 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);
@@ -326,7 +328,7 @@ pk11_RetrieveCrlsCallback(PK11SlotInfo *slot, CK_OBJECT_HANDLE crlID,
loser:
/* free attributes that weren't adopted by the CRL */
- for (i=1;i<fetchCrlSize;i++) {
+ for (i = 1; i < fetchCrlSize; i++) {
if (fetchCrl[i].pValue) {
PORT_Free(fetchCrl[i].pValue);
}
@@ -342,7 +344,7 @@ loser:
/* free the memory for the SECItem structure itself */
SECITEM_FreeItem(derCrl, PR_TRUE);
}
- return(rv);
+ return (rv);
}
/*
@@ -351,8 +353,9 @@ loser:
* 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)
+SECStatus
+pk11_RetrieveCrls(CERTCrlHeadNode *nodes, SECItem *issuer,
+ void *wincx)
{
pk11TraverseSlot creater;
CK_ATTRIBUTE theTemplate[2];
@@ -361,27 +364,27 @@ SECStatus pk11_RetrieveCrls(CERTCrlHeadNode *nodes, SECItem* issuer,
crlOptions options;
attrs = theTemplate;
- PK11_SETATTRS(attrs, CKA_CLASS, &crlClass, sizeof(crlClass)); attrs++;
+ 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
+ /* - 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++;
+ if (issuer) {
+ PK11_SETATTRS(attrs, CKA_SUBJECT, issuer->data, issuer->len);
+ attrs++;
}
creater.callback = pk11_RetrieveCrlsCallback;
- creater.callbackArg = (void *) &options;
+ creater.callbackArg = (void *)&options;
creater.findTemplate = theTemplate;
creater.templateCount = (attrs - theTemplate);
@@ -389,71 +392,70 @@ SECStatus pk11_RetrieveCrls(CERTCrlHeadNode *nodes, SECItem* issuer,
}
/*
- * return the crl associated with a derSubjectName
+ * return the crl associated with a derSubjectName
*/
SECItem *
PK11_FindCrlByName(PK11SlotInfo **slot, CK_OBJECT_HANDLE *crlHandle,
- SECItem *name, int type, char **pUrl)
+ SECItem *name, int type, char **pUrl)
{
NSSCRL **crls, **crlp, *crl = NULL;
NSSDER subject;
SECItem *rvItem;
NSSTrustDomain *td = STAN_GetDefaultTrustDomain();
- char * url = NULL;
+ 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);
+ 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);
+ 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;
+ 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;
- }
+ 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) {
+ /* 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;
- }
+ url = PORT_Strdup(crl->url);
+ if (!url) {
+ goto loser;
+ }
}
rvItem = SECITEM_AllocItem(NULL, NULL, crl->encoding.size);
if (!rvItem) {
- goto loser;
+ goto loser;
}
memcpy(rvItem->data, crl->encoding.data, crl->encoding.size);
*slot = PK11_ReferenceSlot(crl->object.instances[0]->token->pk11slot);
@@ -464,18 +466,18 @@ PK11_FindCrlByName(PK11SlotInfo **slot, CK_OBJECT_HANDLE *crlHandle,
loser:
if (url)
- PORT_Free(url);
+ PORT_Free(url);
if (crl)
- nssCRL_Destroy(crl);
+ nssCRL_Destroy(crl);
if (PORT_GetError() == 0) {
- PORT_SetError(SEC_ERROR_CRL_NOT_FOUND);
+ PORT_SetError(SEC_ERROR_CRL_NOT_FOUND);
}
return NULL;
}
CK_OBJECT_HANDLE
-PK11_PutCrl(PK11SlotInfo *slot, SECItem *crl, SECItem *name,
- char *url, int type)
+PK11_PutCrl(PK11SlotInfo *slot, SECItem *crl, SECItem *name,
+ char *url, int type)
{
NSSItem derCRL, derSubject;
NSSToken *token = PK11Slot_GetNSSToken(slot);
@@ -486,20 +488,19 @@ PK11_PutCrl(PK11SlotInfo *slot, SECItem *crl, SECItem *name,
NSSITEM_FROM_SECITEM(&derSubject, name);
NSSITEM_FROM_SECITEM(&derCRL, crl);
- object = nssToken_ImportCRL(token, NULL,
+ object = nssToken_ImportCRL(token, NULL,
&derSubject, &derCRL, isKRL, url, PR_TRUE);
if (object) {
- rvH = object->handle;
- nssCryptokiObject_Destroy(object);
+ rvH = object->handle;
+ nssCryptokiObject_Destroy(object);
} else {
- rvH = CK_INVALID_HANDLE;
+ rvH = CK_INVALID_HANDLE;
PORT_SetError(SEC_ERROR_CRL_IMPORT_FAILED);
}
return rvH;
}
-
/*
* delete a crl.
*/
@@ -513,9 +514,9 @@ SEC_DeletePermCRL(CERTSignedCrl *crl)
if (slot == NULL) {
PORT_Assert(slot);
- /* shouldn't happen */
- PORT_SetError( SEC_ERROR_CRL_INVALID);
- return SECFailure;
+ /* shouldn't happen */
+ PORT_SetError(SEC_ERROR_CRL_INVALID);
+ return SECFailure;
}
token = PK11Slot_GetNSSToken(slot);
@@ -534,129 +535,130 @@ SEC_DeletePermCRL(CERTSignedCrl *crl)
}
/*
- * return the certificate associated with a derCert
+ * return the certificate associated with a derCert
*/
SECItem *
PK11_FindSMimeProfile(PK11SlotInfo **slot, char *emailAddr,
- SECItem *name, SECItem **profileTime)
+ 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 },
+ { CKA_SUBJECT, NULL, 0 },
+ { CKA_CLASS, NULL, 0 },
+ { CKA_NETSCAPE_EMAIL, NULL, 0 },
};
- CK_ATTRIBUTE smimeData[] = {
- { CKA_SUBJECT, NULL, 0 },
- { CKA_VALUE, 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]);
+ 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;
+ 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++;
+ 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);
+ 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);
- }
-
+ 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;
+ 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);
+ 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;
+ PORT_SetError(PK11_MapError(crv));
+ goto loser;
}
if (!profileTime) {
- SECItem profileSubject;
+ SECItem profileSubject;
- profileSubject.data = (unsigned char*) smimeData[0].pValue;
- profileSubject.len = smimeData[0].ulValueLen;
- if (!SECITEM_ItemsAreEqual(&profileSubject,name)) {
- goto loser;
- }
+ 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));
+ emailProfile = (SECItem *)PORT_ZAlloc(sizeof(SECItem));
if (emailProfile == NULL) {
- goto loser;
+ goto loser;
}
- emailProfile->data = (unsigned char*) smimeData[1].pValue;
+ 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;
- }
+ *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 (smimeData[1].pValue) {
+ PORT_Free(smimeData[1].pValue);
+ }
}
if (profileTime == NULL || *profileTime == NULL) {
- if (smimeData[0].pValue) {
- PORT_Free(smimeData[0].pValue);
- }
+ if (smimeData[0].pValue) {
+ PORT_Free(smimeData[0].pValue);
+ }
}
return emailProfile;
}
-
SECStatus
PK11_SaveSMimeProfile(PK11SlotInfo *slot, char *emailAddr, SECItem *derSubj,
- SECItem *emailProfile, SECItem *profileTime)
+ 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 }
+ { 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;
@@ -666,60 +668,65 @@ PK11_SaveSMimeProfile(PK11SlotInfo *slot, char *emailAddr, SECItem *derSubj,
PK11SlotInfo *free_slot = NULL;
CK_RV crv;
#ifdef DEBUG
- int tsize = sizeof(theTemplate)/sizeof(theTemplate[0]);
+ 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++;
+ 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++;
+ 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);
+ PORT_Assert(realSize <= tsize);
if (slot == NULL) {
- free_slot = slot = PK11_GetInternalKeySlot();
- /* we need to free the key slot in the end!!! */
+ 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;
+ 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);
+ crv = PK11_GETTAB(slot)->C_CreateObject(rwsession, theTemplate, realSize, &smimeh);
if (crv != CKR_OK) {
- PORT_SetError( PK11_MapError(crv) );
+ PORT_SetError(PK11_MapError(crv));
}
- PK11_RestoreROSession(slot,rwsession);
+ PK11_RestoreROSession(slot, rwsession);
if (free_slot) {
- PK11_FreeSlot(free_slot);
+ PK11_FreeSlot(free_slot);
}
return SECSuccess;
}
-
-CERTSignedCrl * crl_storeCRL (PK11SlotInfo *slot,char *url,
- CERTSignedCrl *newCrl, SECItem *derCrl, int type);
+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, PLArenaPool* arena,
- PRInt32 decodeoptions)
+CERTSignedCrl *
+PK11_ImportCRL(PK11SlotInfo *slot, SECItem *derCRL, char *url,
+ int type, void *wincx, PRInt32 importOptions, PLArenaPool *arena,
+ PRInt32 decodeoptions)
{
CERTSignedCrl *newCrl, *crl;
SECStatus rv;
@@ -733,27 +740,27 @@ CERTSignedCrl* PK11_ImportCRL(PK11SlotInfo * slot, SECItem *derCRL, char *url,
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)
+ if (PORT_GetError() == SEC_ERROR_BAD_DER)
PORT_SetError(SEC_ERROR_CRL_INVALID);
- } else {
+ } else {
PORT_SetError(SEC_ERROR_KRL_INVALID);
}
- break;
+ break;
}
- if (0 == (importOptions & CRL_IMPORT_BYPASS_CHECKS)){
- CERTCertDBHandle* handle = CERT_GetDefaultCertDB();
+ if (0 == (importOptions & CRL_IMPORT_BYPASS_CHECKS)) {
+ CERTCertDBHandle *handle = CERT_GetDefaultCertDB();
PR_ASSERT(handle != NULL);
- caCert = CERT_FindCertByName (handle,
- &newCrl->crl.derName);
+ caCert = CERT_FindCertByName(handle,
+ &newCrl->crl.derName);
if (caCert == NULL) {
- PORT_SetError(SEC_ERROR_UNKNOWN_ISSUER);
+ 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);
+ rv = CERT_CheckCertUsage(caCert, KU_CRL_SIGN);
if (rv != SECSuccess) {
break;
}
@@ -770,12 +777,12 @@ CERTSignedCrl* PK11_ImportCRL(PK11SlotInfo * slot, SECItem *derCRL, char *url,
}
}
- crl = crl_storeCRL(slot, url, newCrl, derCRL, type);
+ crl = crl_storeCRL(slot, url, newCrl, derCRL, type);
} while (0);
if (crl == NULL) {
- SEC_DestroyCrl (newCrl);
+ SEC_DestroyCrl(newCrl);
}
if (caCert) {
CERT_DestroyCertificate(caCert);
diff --git a/nss/lib/pk11wrap/pk11obj.c b/nss/lib/pk11wrap/pk11obj.c
index 848b45a..18850b2 100644
--- a/nss/lib/pk11wrap/pk11obj.c
+++ b/nss/lib/pk11wrap/pk11obj.c
@@ -11,7 +11,7 @@
#include "pkcs11.h"
#include "pkcs11t.h"
#include "pk11func.h"
-#include "key.h"
+#include "key.h"
#include "secitem.h"
#include "secerr.h"
#include "sslerr.h"
@@ -22,63 +22,68 @@
* Build a block big enough to hold the data
*/
SECItem *
-PK11_BlockData(SECItem *data,unsigned long size) {
+PK11_BlockData(SECItem *data, unsigned long size)
+{
SECItem *newData;
+ if (size == 0u)
+ return NULL;
+
newData = (SECItem *)PORT_Alloc(sizeof(SECItem));
- if (newData == NULL) return NULL;
+ if (newData == NULL)
+ return NULL;
- newData->len = (data->len + (size-1))/size;
+ newData->len = (data->len + (size - 1)) / size;
newData->len *= size;
- newData->data = (unsigned char *) PORT_ZAlloc(newData->len);
+ newData->data = (unsigned char *)PORT_ZAlloc(newData->len);
if (newData->data == NULL) {
- PORT_Free(newData);
- return NULL;
+ PORT_Free(newData);
+ return NULL;
}
- PORT_Memset(newData->data,newData->len-data->len,newData->len);
- PORT_Memcpy(newData->data,data->data,data->len);
+ 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) {
+PK11_DestroyObject(PK11SlotInfo *slot, CK_OBJECT_HANDLE object)
+{
CK_RV crv;
PK11_EnterSlotMonitor(slot);
- crv = PK11_GETTAB(slot)->C_DestroyObject(slot->session,object);
+ crv = PK11_GETTAB(slot)->C_DestroyObject(slot->session, object);
PK11_ExitSlotMonitor(slot);
if (crv != CKR_OK) {
- return SECFailure;
+ return SECFailure;
}
return SECSuccess;
}
SECStatus
-PK11_DestroyTokenObject(PK11SlotInfo *slot,CK_OBJECT_HANDLE object) {
+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;
+ PORT_SetError(SEC_ERROR_BAD_DATA);
+ return SECFailure;
}
- crv = PK11_GETTAB(slot)->C_DestroyObject(rwsession,object);
+ crv = PK11_GETTAB(slot)->C_DestroyObject(rwsession, object);
if (crv != CKR_OK) {
- rv = SECFailure;
- PORT_SetError(PK11_MapError(crv));
+ rv = SECFailure;
+ PORT_SetError(PK11_MapError(crv));
}
- PK11_RestoreROSession(slot,rwsession);
+ PK11_RestoreROSession(slot, rwsession);
return rv;
}
/*
- * Read in a single attribute into a SECItem. Allocate space for it with
+ * 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.
*
@@ -87,59 +92,62 @@ PK11_DestroyTokenObject(PK11SlotInfo *slot,CK_OBJECT_HANDLE object) {
*/
SECStatus
PK11_ReadAttribute(PK11SlotInfo *slot, CK_OBJECT_HANDLE id,
- CK_ATTRIBUTE_TYPE type, PLArenaPool *arena, SECItem *result) {
+ CK_ATTRIBUTE_TYPE type, PLArenaPool *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);
+ 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;
+ PK11_ExitSlotMonitor(slot);
+ PORT_SetError(PK11_MapError(crv));
+ return SECFailure;
}
if (arena) {
- attr.pValue = PORT_ArenaAlloc(arena,attr.ulValueLen);
+ attr.pValue = PORT_ArenaAlloc(arena, attr.ulValueLen);
} else {
- attr.pValue = PORT_Alloc(attr.ulValueLen);
+ attr.pValue = PORT_Alloc(attr.ulValueLen);
}
if (attr.pValue == NULL) {
- PK11_ExitSlotMonitor(slot);
- return SECFailure;
+ PK11_ExitSlotMonitor(slot);
+ return SECFailure;
}
- crv = PK11_GETTAB(slot)->C_GetAttributeValue(slot->session,id,&attr,1);
+ 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;
+ PORT_SetError(PK11_MapError(crv));
+ if (!arena)
+ PORT_Free(attr.pValue);
+ return SECFailure;
}
- result->data = (unsigned char*)attr.pValue;
+ result->data = (unsigned char *)attr.pValue;
result->len = attr.ulValueLen;
return SECSuccess;
}
/*
- * Read in a single attribute into As a Ulong.
+ * 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_TYPE type)
+{
CK_ATTRIBUTE attr;
CK_ULONG value = CK_UNAVAILABLE_INFORMATION;
CK_RV crv;
- PK11_SETATTRS(&attr,type,&value,sizeof(value));
+ PK11_SETATTRS(&attr, type, &value, sizeof(value));
PK11_EnterSlotMonitor(slot);
- crv = PK11_GETTAB(slot)->C_GetAttributeValue(slot->session,id,&attr,1);
+ crv = PK11_GETTAB(slot)->C_GetAttributeValue(slot->session, id, &attr, 1);
PK11_ExitSlotMonitor(slot);
if (crv != CKR_OK) {
- PORT_SetError(PK11_MapError(crv));
+ PORT_SetError(PK11_MapError(crv));
}
return value;
}
@@ -148,23 +156,25 @@ PK11_ReadULongAttribute(PK11SlotInfo *slot, CK_OBJECT_HANDLE id,
* 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 )
+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 ) );
+ 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 ) );
+ 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;
}
@@ -176,80 +186,81 @@ PK11_HasAttributeSet( PK11SlotInfo *slot, CK_OBJECT_HANDLE id,
* provided, allocate space out of the arena.
*/
CK_RV
-PK11_GetAttributes(PLArenaPool *arena,PK11SlotInfo *slot,
- CK_OBJECT_HANDLE obj,CK_ATTRIBUTE *attr, int count)
+PK11_GetAttributes(PLArenaPool *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;
+ /* 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;
+ 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);
+ crv = PK11_GETTAB(slot)->C_GetAttributeValue(slot->session, obj, attr, count);
if (crv != CKR_OK) {
- PK11_ExitSlotMonitor(slot);
- return crv;
+ PK11_ExitSlotMonitor(slot);
+ return crv;
}
if (arena) {
- mark = PORT_ArenaMark(arena);
- if (mark == NULL) return CKR_HOST_MEMORY;
+ 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;
- }
- }
+ 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);
+ 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;
- }
- }
+ 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);
+ PORT_ArenaUnmark(arena, mark);
}
return crv;
}
@@ -257,25 +268,25 @@ PK11_GetAttributes(PLArenaPool *arena,PK11SlotInfo *slot,
PRBool
PK11_IsPermObject(PK11SlotInfo *slot, CK_OBJECT_HANDLE handle)
{
- return (PRBool) PK11_HasAttributeSet(slot, handle, CKA_TOKEN, PR_FALSE);
+ return (PRBool)PK11_HasAttributeSet(slot, handle, CKA_TOKEN, PR_FALSE);
}
char *
-PK11_GetObjectNickname(PK11SlotInfo *slot, CK_OBJECT_HANDLE id)
+PK11_GetObjectNickname(PK11SlotInfo *slot, CK_OBJECT_HANDLE id)
{
char *nickname = NULL;
SECItem result;
SECStatus rv;
- rv = PK11_ReadAttribute(slot,id,CKA_LABEL,NULL,&result);
+ rv = PK11_ReadAttribute(slot, id, CKA_LABEL, NULL, &result);
if (rv != SECSuccess) {
- return NULL;
+ return NULL;
}
- nickname = PORT_ZAlloc(result.len+1);
+ nickname = PORT_ZAlloc(result.len + 1);
if (nickname == NULL) {
- PORT_Free(result.data);
- return NULL;
+ PORT_Free(result.data);
+ return NULL;
}
PORT_Memcpy(nickname, result.data, result.len);
PORT_Free(result.data);
@@ -283,8 +294,8 @@ PK11_GetObjectNickname(PK11SlotInfo *slot, CK_OBJECT_HANDLE id)
}
SECStatus
-PK11_SetObjectNickname(PK11SlotInfo *slot, CK_OBJECT_HANDLE id,
- const char *nickname)
+PK11_SetObjectNickname(PK11SlotInfo *slot, CK_OBJECT_HANDLE id,
+ const char *nickname)
{
int len = PORT_Strlen(nickname);
CK_ATTRIBUTE setTemplate;
@@ -292,21 +303,21 @@ PK11_SetObjectNickname(PK11SlotInfo *slot, CK_OBJECT_HANDLE id,
CK_SESSION_HANDLE rwsession;
if (len < 0) {
- return SECFailure;
+ return SECFailure;
}
- PK11_SETATTRS(&setTemplate, CKA_LABEL, (CK_CHAR *) nickname, len);
+ 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;
+ PORT_SetError(SEC_ERROR_BAD_DATA);
+ return SECFailure;
}
crv = PK11_GETTAB(slot)->C_SetAttributeValue(rwsession, id,
- &setTemplate, 1);
+ &setTemplate, 1);
PK11_RestoreROSession(slot, rwsession);
if (crv != CKR_OK) {
- PORT_SetError(PK11_MapError(crv));
- return SECFailure;
+ PORT_SetError(PK11_MapError(crv));
+ return SECFailure;
}
return SECSuccess;
}
@@ -315,13 +326,14 @@ PK11_SetObjectNickname(PK11SlotInfo *slot, CK_OBJECT_HANDLE id,
* strip leading zero's from key material
*/
void
-pk11_SignedToUnsigned(CK_ATTRIBUTE *attrib) {
+pk11_SignedToUnsigned(CK_ATTRIBUTE *attrib)
+{
char *ptr = (char *)attrib->pValue;
unsigned long len = attrib->ulValueLen;
while ((len > 1) && (*ptr == 0)) {
- len--;
- ptr++;
+ len--;
+ ptr++;
}
attrib->pValue = ptr;
attrib->ulValueLen = len;
@@ -332,68 +344,71 @@ pk11_SignedToUnsigned(CK_ATTRIBUTE *attrib) {
* 'exclusive' session. In this case owner becomes false.
*/
CK_SESSION_HANDLE
-pk11_GetNewSession(PK11SlotInfo *slot,PRBool *owner)
+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);
+ *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)
+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);
+ 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)
+ 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);
- }
+ CK_SESSION_HANDLE rwsession;
+ CK_RV crv;
+ SECStatus rv = SECSuccess;
- return rv;
-}
+ 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
@@ -401,26 +416,25 @@ 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
+ 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;
-
+ 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;
- }
+ if (test & flags) {
+ flags ^= test;
+ PR_ASSERT(*pType);
+ PK11_SETATTRS(attr, *pType, ckTrue, sizeof *ckTrue);
+ ++attr;
+ }
}
return (attr - attrs);
}
@@ -443,30 +457,30 @@ pk11_BadAttrFlags(PK11AttrFlags attrFlags)
*/
unsigned int
pk11_AttrFlagsToAttributes(PK11AttrFlags attrFlags, CK_ATTRIBUTE *attrs,
- CK_BBOOL *ckTrue, CK_BBOOL *ckFalse)
+ CK_BBOOL *ckTrue, CK_BBOOL *ckFalse)
{
const static CK_ATTRIBUTE_TYPE attrTypes[5] = {
- CKA_TOKEN, CKA_PRIVATE, CKA_MODIFIABLE, CKA_SENSITIVE,
- CKA_EXTRACTABLE
+ 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;
+ 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;
- }
+ 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);
}
@@ -479,38 +493,40 @@ static int
pk11_backupGetSignLength(SECKEYPrivateKey *key)
{
PK11SlotInfo *slot = key->pkcs11Slot;
- CK_MECHANISM mech = {0, NULL, 0 };
+ 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 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);
+ 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;
+ 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);
+ 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);
+ (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;
+ PORT_SetError(PK11_MapError(crv));
+ return -1;
}
return len;
}
@@ -522,50 +538,50 @@ int
PK11_SignatureLen(SECKEYPrivateKey *key)
{
int val;
- SECItem attributeItem = {siBuffer, NULL, 0};
+ SECItem attributeItem = { siBuffer, NULL, 0 };
SECStatus rv;
- int length;
+ 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 );
+ 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;
}
@@ -579,36 +595,37 @@ PK11_CopyKey(PK11SlotInfo *slot, CK_OBJECT_HANDLE srcObject)
CK_RV crv;
PK11_EnterSlotMonitor(slot);
- crv = PK11_GETTAB(slot)->C_CopyObject(slot->session,srcObject,NULL,0,
- &destObject);
+ 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) );
+ 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)
+ CK_ATTRIBUTE_TYPE target)
{
for (; numAttrs > 0; ++attr, --numAttrs) {
- if (attr->type == target)
- return PR_TRUE;
+ 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)
+ SECItem *dsig, void *wincx)
{
PK11SlotInfo *slot = key->pkcs11Slot;
CK_OBJECT_HANDLE id = key->pkcs11ID;
- CK_MECHANISM mech = {0, NULL, 0 };
+ CK_MECHANISM mech = { 0, NULL, 0 };
PRBool owner = PR_TRUE;
CK_SESSION_HANDLE session;
CK_ULONG len;
@@ -617,43 +634,46 @@ PK11_VerifyRecover(SECKEYPublicKey *key, const SECItem *sig,
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);
+ 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);
+ PK11_ReferenceSlot(slot);
}
if (id == CK_INVALID_HANDLE) {
- PK11_FreeSlot(slot);
- PORT_SetError( SEC_ERROR_BAD_KEY );
- return SECFailure;
+ 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);
+ 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;
+ 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);
+ 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;
+ PORT_SetError(PK11_MapError(crv));
+ PK11_FreeSlot(slot);
+ return SECFailure;
}
PK11_FreeSlot(slot);
return SECSuccess;
@@ -664,69 +684,88 @@ PK11_VerifyRecover(SECKEYPublicKey *key, const SECItem *sig,
*/
SECStatus
PK11_Verify(SECKEYPublicKey *key, const SECItem *sig, const SECItem *hash,
- void *wincx)
+ void *wincx)
+{
+ CK_MECHANISM_TYPE mech = PK11_MapSignKeyType(key->keyType);
+ return PK11_VerifyWithMechanism(key, mech, NULL, sig, hash, wincx);
+}
+
+/*
+ * Verify a signature from its hash using the given algorithm.
+ */
+SECStatus
+PK11_VerifyWithMechanism(SECKEYPublicKey *key, CK_MECHANISM_TYPE mechanism,
+ const SECItem *param, const SECItem *sig,
+ const SECItem *hash, void *wincx)
{
PK11SlotInfo *slot = key->pkcs11Slot;
CK_OBJECT_HANDLE id = key->pkcs11ID;
- CK_MECHANISM mech = {0, NULL, 0 };
+ CK_MECHANISM mech = { 0, NULL, 0 };
PRBool owner = PR_TRUE;
CK_SESSION_HANDLE session;
CK_RV crv;
- mech.mechanism = PK11_MapSignKeyType(key->keyType);
+ mech.mechanism = mechanism;
+ if (param) {
+ mech.pParameter = param->data;
+ mech.ulParameterLen = param->len;
+ }
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 --;
- }
- /* convert keysize to bits for slot lookup */
- length *= 8;
- }
- 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);
-
+ 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--;
+ }
+ /* convert keysize to bits for slot lookup */
+ length *= 8;
+ }
+ 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);
+ PK11_ReferenceSlot(slot);
}
if (id == CK_INVALID_HANDLE) {
- PK11_FreeSlot(slot);
- PORT_SetError( SEC_ERROR_BAD_KEY );
- return SECFailure;
+ 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);
+ 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);
+ 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;
+ PORT_SetError(PK11_MapError(crv));
+ return SECFailure;
}
return SECSuccess;
}
@@ -737,47 +776,65 @@ PK11_Verify(SECKEYPublicKey *key, const SECItem *sig, const SECItem *hash,
SECStatus
PK11_Sign(SECKEYPrivateKey *key, SECItem *sig, const SECItem *hash)
{
+ CK_MECHANISM_TYPE mech = PK11_MapSignKeyType(key->keyType);
+ return PK11_SignWithMechanism(key, mech, NULL, sig, hash);
+}
+
+/*
+ * Sign a hash using the given algorithm.
+ */
+SECStatus
+PK11_SignWithMechanism(SECKEYPrivateKey *key, CK_MECHANISM_TYPE mechanism,
+ const SECItem *param, SECItem *sig, const SECItem *hash)
+{
PK11SlotInfo *slot = key->pkcs11Slot;
- CK_MECHANISM mech = {0, NULL, 0 };
+ 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);
+ mech.mechanism = mechanism;
+ if (param) {
+ mech.pParameter = param->data;
+ mech.ulParameterLen = param->len;
+ }
- if (SECKEY_HAS_ATTRIBUTE_SET(key,CKA_PRIVATE)) {
- PK11_HandlePasswordCheck(slot, key->wincx);
+ if (SECKEY_HAS_ATTRIBUTE_SET(key, CKA_PRIVATE)) {
+ PK11_HandlePasswordCheck(slot, key->wincx);
}
- session = pk11_GetNewSession(slot,&owner);
+ 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 (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;
+ 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
+ /* 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);
+ 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);
+ 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;
+ PORT_SetError(PK11_MapError(crv));
+ return SECFailure;
}
return SECSuccess;
}
@@ -787,10 +844,10 @@ 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)
+ SECItem *param, SECItem *sig, const SECItem *data)
{
PK11SlotInfo *slot = symKey->slot;
- CK_MECHANISM mech = {0, NULL, 0 };
+ CK_MECHANISM mech = { 0, NULL, 0 };
PRBool owner = PR_TRUE;
CK_SESSION_HANDLE session;
PRBool haslock = PR_FALSE;
@@ -799,30 +856,33 @@ PK11_SignWithSymKey(PK11SymKey *symKey, CK_MECHANISM_TYPE mechanism,
mech.mechanism = mechanism;
if (param) {
- mech.pParameter = param->data;
- mech.ulParameterLen = param->len;
+ mech.pParameter = param->data;
+ mech.ulParameterLen = param->len;
}
- session = pk11_GetNewSession(slot,&owner);
+ 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 (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;
+ 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);
+ 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;
+ PORT_SetError(PK11_MapError(crv));
+ return SECFailure;
}
return SECSuccess;
}
@@ -835,7 +895,7 @@ PK11_Decrypt(PK11SymKey *symKey,
const unsigned char *enc, unsigned encLen)
{
PK11SlotInfo *slot = symKey->slot;
- CK_MECHANISM mech = {0, NULL, 0 };
+ CK_MECHANISM mech = { 0, NULL, 0 };
CK_ULONG len = maxLen;
PRBool owner = PR_TRUE;
CK_SESSION_HANDLE session;
@@ -844,29 +904,32 @@ PK11_Decrypt(PK11SymKey *symKey,
mech.mechanism = mechanism;
if (param) {
- mech.pParameter = param->data;
- mech.ulParameterLen = param->len;
+ mech.pParameter = param->data;
+ mech.ulParameterLen = param->len;
}
session = pk11_GetNewSession(slot, &owner);
haslock = (!owner || !slot->isThreadSafe);
- if (haslock) PK11_EnterSlotMonitor(slot);
+ if (haslock)
+ PK11_EnterSlotMonitor(slot);
crv = PK11_GETTAB(slot)->C_DecryptInit(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;
+ if (haslock)
+ PK11_ExitSlotMonitor(slot);
+ pk11_CloseSession(slot, session, owner);
+ PORT_SetError(PK11_MapError(crv));
+ return SECFailure;
}
crv = PK11_GETTAB(slot)->C_Decrypt(session, (unsigned char *)enc, encLen,
out, &len);
- if (haslock) PK11_ExitSlotMonitor(slot);
+ if (haslock)
+ PK11_ExitSlotMonitor(slot);
pk11_CloseSession(slot, session, owner);
*outLen = len;
if (crv != CKR_OK) {
- PORT_SetError( PK11_MapError(crv) );
- return SECFailure;
+ PORT_SetError(PK11_MapError(crv));
+ return SECFailure;
}
return SECSuccess;
}
@@ -879,7 +942,7 @@ PK11_Encrypt(PK11SymKey *symKey,
const unsigned char *data, unsigned int dataLen)
{
PK11SlotInfo *slot = symKey->slot;
- CK_MECHANISM mech = {0, NULL, 0 };
+ CK_MECHANISM mech = { 0, NULL, 0 };
CK_ULONG len = maxLen;
PRBool owner = PR_TRUE;
CK_SESSION_HANDLE session;
@@ -888,35 +951,38 @@ PK11_Encrypt(PK11SymKey *symKey,
mech.mechanism = mechanism;
if (param) {
- mech.pParameter = param->data;
- mech.ulParameterLen = param->len;
+ mech.pParameter = param->data;
+ mech.ulParameterLen = param->len;
}
session = pk11_GetNewSession(slot, &owner);
haslock = (!owner || !slot->isThreadSafe);
- if (haslock) PK11_EnterSlotMonitor(slot);
+ if (haslock)
+ PK11_EnterSlotMonitor(slot);
crv = PK11_GETTAB(slot)->C_EncryptInit(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;
+ if (haslock)
+ PK11_ExitSlotMonitor(slot);
+ pk11_CloseSession(slot, session, owner);
+ PORT_SetError(PK11_MapError(crv));
+ return SECFailure;
}
crv = PK11_GETTAB(slot)->C_Encrypt(session, (unsigned char *)data,
dataLen, out, &len);
- if (haslock) PK11_ExitSlotMonitor(slot);
- pk11_CloseSession(slot,session,owner);
+ if (haslock)
+ PK11_ExitSlotMonitor(slot);
+ pk11_CloseSession(slot, session, owner);
*outLen = len;
if (crv != CKR_OK) {
- PORT_SetError( PK11_MapError(crv) );
- return SECFailure;
+ PORT_SetError(PK11_MapError(crv));
+ return SECFailure;
}
return SECSuccess;
}
static SECStatus
pk11_PrivDecryptRaw(SECKEYPrivateKey *key,
- unsigned char *data, unsigned *outLen, unsigned int maxLen,
+ unsigned char *data, unsigned *outLen, unsigned int maxLen,
const unsigned char *enc, unsigned encLen,
CK_MECHANISM_PTR mech)
{
@@ -928,44 +994,47 @@ pk11_PrivDecryptRaw(SECKEYPrivateKey *key,
CK_RV crv;
if (key->keyType != rsaKey) {
- PORT_SetError( SEC_ERROR_INVALID_KEY );
- return SECFailure;
+ 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);
+ if (SECKEY_HAS_ATTRIBUTE_SET(key, CKA_PRIVATE)) {
+ PK11_HandlePasswordCheck(slot, key->wincx);
}
- session = pk11_GetNewSession(slot,&owner);
+ session = pk11_GetNewSession(slot, &owner);
haslock = (!owner || !(slot->isThreadSafe));
- if (haslock) PK11_EnterSlotMonitor(slot);
+ 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;
+ 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
+ /* 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);
+ PK11_DoPassword(slot, session, PR_FALSE, key->wincx, haslock, PR_TRUE);
}
crv = PK11_GETTAB(slot)->C_Decrypt(session, (unsigned char *)enc, encLen,
- data, &out);
- if (haslock) PK11_ExitSlotMonitor(slot);
- pk11_CloseSession(slot,session,owner);
+ 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;
+ PORT_SetError(PK11_MapError(crv));
+ return SECFailure;
}
return SECSuccess;
}
@@ -975,7 +1044,7 @@ PK11_PubDecryptRaw(SECKEYPrivateKey *key,
unsigned char *data, unsigned *outLen, unsigned int maxLen,
const unsigned char *enc, unsigned encLen)
{
- CK_MECHANISM mech = {CKM_RSA_X_509, NULL, 0 };
+ CK_MECHANISM mech = { CKM_RSA_X_509, NULL, 0 };
return pk11_PrivDecryptRaw(key, data, outLen, maxLen, enc, encLen, &mech);
}
@@ -984,7 +1053,7 @@ PK11_PrivDecryptPKCS1(SECKEYPrivateKey *key,
unsigned char *data, unsigned *outLen, unsigned int maxLen,
const unsigned char *enc, unsigned encLen)
{
- CK_MECHANISM mech = {CKM_RSA_PKCS, NULL, 0 };
+ CK_MECHANISM mech = { CKM_RSA_PKCS, NULL, 0 };
return pk11_PrivDecryptRaw(key, data, outLen, maxLen, enc, encLen, &mech);
}
@@ -1002,39 +1071,42 @@ pk11_PubEncryptRaw(SECKEYPublicKey *key,
CK_SESSION_HANDLE session;
CK_RV crv;
- slot = PK11_GetBestSlotWithAttributes(mech->mechanism,CKF_ENCRYPT,0,wincx);
+ slot = PK11_GetBestSlotWithAttributes(mech->mechanism, CKF_ENCRYPT, 0, wincx);
if (slot == NULL) {
- PORT_SetError( SEC_ERROR_NO_MODULE );
- return SECFailure;
+ PORT_SetError(SEC_ERROR_NO_MODULE);
+ return SECFailure;
}
- id = PK11_ImportPublicKey(slot,key,PR_FALSE);
+ id = PK11_ImportPublicKey(slot, key, PR_FALSE);
if (id == CK_INVALID_HANDLE) {
- PK11_FreeSlot(slot);
- PORT_SetError( SEC_ERROR_BAD_KEY );
- return SECFailure;
+ PK11_FreeSlot(slot);
+ PORT_SetError(SEC_ERROR_BAD_KEY);
+ return SECFailure;
}
- session = pk11_GetNewSession(slot,&owner);
- if (!owner || !(slot->isThreadSafe)) PK11_EnterSlotMonitor(slot);
+ 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,(unsigned char *)data,dataLen,
- out,&len);
- if (!owner || !(slot->isThreadSafe)) PK11_ExitSlotMonitor(slot);
- pk11_CloseSession(slot,session,owner);
+ 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, (unsigned char *)data, dataLen,
+ out, &len);
+ if (!owner || !(slot->isThreadSafe))
+ PK11_ExitSlotMonitor(slot);
+ pk11_CloseSession(slot, session, owner);
PK11_FreeSlot(slot);
*outLen = len;
if (crv != CKR_OK) {
- PORT_SetError( PK11_MapError(crv) );
- return SECFailure;
+ PORT_SetError(PK11_MapError(crv));
+ return SECFailure;
}
return SECSuccess;
}
@@ -1045,11 +1117,11 @@ PK11_PubEncryptRaw(SECKEYPublicKey *key,
const unsigned char *data, unsigned dataLen,
void *wincx)
{
- CK_MECHANISM mech = {CKM_RSA_X_509, NULL, 0 };
+ CK_MECHANISM mech = { CKM_RSA_X_509, NULL, 0 };
unsigned int outLen;
if (!key || key->keyType != rsaKey) {
- PORT_SetError(SEC_ERROR_BAD_KEY);
- return SECFailure;
+ PORT_SetError(SEC_ERROR_BAD_KEY);
+ return SECFailure;
}
outLen = SECKEY_PublicKeyStrength(key);
return pk11_PubEncryptRaw(key, enc, &outLen, outLen, data, dataLen, &mech,
@@ -1062,11 +1134,11 @@ PK11_PubEncryptPKCS1(SECKEYPublicKey *key,
const unsigned char *data, unsigned dataLen,
void *wincx)
{
- CK_MECHANISM mech = {CKM_RSA_PKCS, NULL, 0 };
+ CK_MECHANISM mech = { CKM_RSA_PKCS, NULL, 0 };
unsigned int outLen;
if (!key || key->keyType != rsaKey) {
- PORT_SetError(SEC_ERROR_BAD_KEY);
- return SECFailure;
+ PORT_SetError(SEC_ERROR_BAD_KEY);
+ return SECFailure;
}
outLen = SECKEY_PublicKeyStrength(key);
return pk11_PubEncryptRaw(key, enc, &outLen, outLen, data, dataLen, &mech,
@@ -1107,16 +1179,16 @@ PK11_PubEncrypt(SECKEYPublicKey *key,
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_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] ;
+ CK_ATTRIBUTE keyTemplate[15];
int templateCount = 0;
CK_OBJECT_HANDLE privKeyID;
CK_MECHANISM mechanism;
@@ -1127,125 +1199,134 @@ PK11_UnwrapPrivKey(PK11SlotInfo *slot, PK11SymKey *wrappingKey,
PK11SymKey *newKey = NULL;
int i;
- if(!slot || !wrappedKey || !idValue) {
- /* SET AN ERROR!!! */
- return NULL;
+ if (!slot || !wrappedKey || !idValue) {
+ /* SET AN ERROR!!! */
+ return NULL;
}
ck_id = PK11_MakeIDFromPubKey(idValue);
- if(!ck_id) {
- return NULL;
+ 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++;
+ 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++;
+ sizeof(cktrue));
+ attrs++;
PK11_SETATTRS(attrs, CKA_SENSITIVE, sensitive ? &cktrue : &ckfalse,
- sizeof(cktrue)); attrs++;
+ sizeof(cktrue));
+ attrs++;
if (label && label->data) {
- PK11_SETATTRS(attrs, CKA_LABEL, label->data, label->len); attrs++;
+ 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++;
+ 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++;
+ PK11_SETATTRS(attrs, CKA_NETSCAPE_DB, idValue->data,
+ idValue->len);
+ attrs++;
}
templateCount = attrs - keyTemplate;
- PR_ASSERT(templateCount <= (sizeof(keyTemplate) / sizeof(CK_ATTRIBUTE)) );
+ 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;
+ 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;
+ mechanism.pParameter = NULL;
+ mechanism.ulParameterLen = 0;
}
if (wrappingKey->slot != slot) {
- newKey = pk11_CopyToSlot(slot,wrapType,CKA_UNWRAP,wrappingKey);
+ newKey = pk11_CopyToSlot(slot, wrapType, CKA_UNWRAP, wrappingKey);
} else {
- newKey = PK11_ReferenceSymKey(wrappingKey);
+ 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);
- }
+ 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;
+ 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;
+ crv = CKR_FUNCTION_NOT_SUPPORTED;
}
- if (ck_id) {
- SECITEM_FreeItem(ck_id, PR_TRUE);
- ck_id = NULL;
- }
+ 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;
+ /* 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);
+ PK11_FreeSymKey(newKey);
}
if (ck_id) {
- SECITEM_FreeItem(ck_id, PR_TRUE);
+ SECITEM_FreeItem(ck_id, PR_TRUE);
}
return NULL;
}
@@ -1257,69 +1338,69 @@ loser:
* 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)
+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;
+ 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;
+ 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.
- */
+ * 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;
+ 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;
+ newSymKey = pk11_CopyToSlot(privSlot, wrapType, CKA_WRAP,
+ wrappingKey);
+ wrappingKey = newSymKey;
}
if (wrappingKey == NULL) {
if (newPrivKey) {
- SECKEY_DestroyPrivateKey(newPrivKey);
- }
- return SECFailure;
+ 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;
+ mech.pParameter = param->data;
+ mech.ulParameterLen = param->len;
} else {
- mech.pParameter = NULL;
- mech.ulParameterLen = 0;
+ 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);
+ crv = PK11_GETTAB(privSlot)->C_WrapKey(privSlot->session, &mech,
+ wrappingKey->objectID,
+ privKey->pkcs11ID,
+ wrappedKey->data, &len);
PK11_ExitSlotMonitor(privSlot);
if (newSymKey) {
@@ -1329,12 +1410,12 @@ PK11_WrapPrivKey(PK11SlotInfo *slot, PK11SymKey *wrappingKey,
SECKEY_DestroyPrivateKey(newPrivKey);
}
if (param_free) {
- SECITEM_FreeItem(param_free,PR_TRUE);
+ SECITEM_FreeItem(param_free, PR_TRUE);
}
if (crv != CKR_OK) {
- PORT_SetError( PK11_MapError(crv) );
- return SECFailure;
+ PORT_SetError(PK11_MapError(crv));
+ return SECFailure;
}
wrappedKey->len = len;
@@ -1351,7 +1432,7 @@ PK11_WrapPrivKey(PK11SlotInfo *slot, PK11SymKey *wrappingKey,
*/
firstObj = PK11_FindGenericObjects(slot, objClass);
for (thisObj=firstObj;
- thisObj;
+ thisObj;
thisObj=PK11_GetNextGenericObject(thisObj)) {
/* operate on thisObj */
}
@@ -1360,14 +1441,14 @@ PK11_WrapPrivKey(PK11SlotInfo *slot, PK11SymKey *wrappingKey,
*/
firstObj = PK11_FindGenericObjects(slot, objClass);
for (thisObj=firstObj;
- thisObj;
+ thisObj;
thisObj=PK11_GetNextGenericObject(thisObj)) {
- if (isMyObj(thisObj)) {
- if ( thisObj == firstObj) {
+ if (isMyObj(thisObj)) {
+ if ( thisObj == firstObj) {
/* NOTE: firstObj could be NULL at this point */
- firstObj = PK11_GetNextGenericObject(thsObj);
- }
- PK11_UnlinkGenericObject(thisObj);
+ firstObj = PK11_GetNextGenericObject(thsObj);
+ }
+ PK11_UnlinkGenericObject(thisObj);
myObj = thisObj;
break;
}
@@ -1396,37 +1477,37 @@ PK11_FindGenericObjects(PK11SlotInfo *slot, CK_OBJECT_CLASS objClass)
PK11GenericObject *firstObj = NULL;
int i, count = 0;
+ PK11_SETATTRS(attrs, CKA_CLASS, &objClass, sizeof(objClass));
+ attrs++;
- PK11_SETATTRS(attrs, CKA_CLASS, &objClass, sizeof(objClass)); attrs++;
-
- objectIDs = pk11_FindObjectsByTemplate(slot,template,1,&count);
+ objectIDs = pk11_FindObjectsByTemplate(slot, template, 1, &count);
if (objectIDs == NULL) {
- return 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;
+ 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;
@@ -1459,9 +1540,9 @@ PK11_LinkGenericObject(PK11GenericObject *list, PK11GenericObject *object)
object->next = list->next;
list->next = object;
if (object->next != NULL) {
- object->next->prev = object;
+ object->next->prev = object;
}
- return SECSuccess;
+ return SECSuccess;
}
/*
@@ -1472,10 +1553,10 @@ SECStatus
PK11_UnlinkGenericObject(PK11GenericObject *object)
{
if (object->prev != NULL) {
- object->prev->next = object->next;
+ object->prev->next = object->next;
}
if (object->next != NULL) {
- object->next->prev = object->prev;
+ object->next->prev = object->prev;
}
object->next = NULL;
@@ -1488,16 +1569,16 @@ PK11_UnlinkGenericObject(PK11GenericObject *object)
* For an already unlinked object there is no difference between
* PK11_DestroyGenericObject and PK11_DestroyGenericObjects
*/
-SECStatus
+SECStatus
PK11_DestroyGenericObject(PK11GenericObject *object)
{
if (object == NULL) {
- return SECSuccess;
+ return SECSuccess;
}
PK11_UnlinkGenericObject(object);
if (object->slot) {
- PK11_FreeSlot(object->slot);
+ PK11_FreeSlot(object->slot);
}
PORT_Free(object);
return SECSuccess;
@@ -1508,60 +1589,59 @@ PK11_DestroyGenericObject(PK11GenericObject *object)
* This will destroy all objects in a list that the object is linked into.
* (the list is traversed in both directions).
*/
-SECStatus
+SECStatus
PK11_DestroyGenericObjects(PK11GenericObject *objects)
{
PK11GenericObject *nextObject;
PK11GenericObject *prevObject;
-
+
if (objects == NULL) {
- return SECSuccess;
+ 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);
+ 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);
+ 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)
+ 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);
+ crv = PK11_CreateNewObject(slot, slot->session, pTemplate, count,
+ token, &objectID);
PK11_ExitSlotMonitor(slot);
if (crv != CKR_OK) {
- PORT_SetError(PK11_MapError(crv));
- return NULL;
+ PORT_SetError(PK11_MapError(crv));
+ return NULL;
}
obj = PORT_New(PK11GenericObject);
- if ( !obj ) {
- /* error set by PORT_New */
- return NULL;
+ if (!obj) {
+ /* error set by PORT_New */
+ return NULL;
}
- /* initialize it */
+ /* initialize it */
obj->slot = PK11_ReferenceSlot(slot);
obj->objectID = objectID;
obj->next = NULL;
@@ -1573,8 +1653,8 @@ PK11_CreateGenericObject(PK11SlotInfo *slot, const CK_ATTRIBUTE *pTemplate,
* Change an attribute on a raw object
*/
SECStatus
-PK11_WriteRawAttribute(PK11ObjectType objType, void *objSpec,
- CK_ATTRIBUTE_TYPE attrType, SECItem *item)
+PK11_WriteRawAttribute(PK11ObjectType objType, void *objSpec,
+ CK_ATTRIBUTE_TYPE attrType, SECItem *item)
{
PK11SlotInfo *slot = NULL;
CK_OBJECT_HANDLE handle = 0;
@@ -1583,90 +1663,88 @@ PK11_WriteRawAttribute(PK11ObjectType objType, void *objSpec,
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;
+ 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;
+ PORT_SetError(SEC_ERROR_UNKNOWN_OBJECT_TYPE);
+ return SECFailure;
}
- PK11_SETATTRS(&setTemplate, attrType, (CK_CHAR *) item->data, item->len);
+ 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;
+ PORT_SetError(SEC_ERROR_BAD_DATA);
+ return SECFailure;
}
crv = PK11_GETTAB(slot)->C_SetAttributeValue(rwsession, handle,
- &setTemplate, 1);
+ &setTemplate, 1);
PK11_RestoreROSession(slot, rwsession);
if (crv != CKR_OK) {
- PORT_SetError(PK11_MapError(crv));
- return SECFailure;
+ PORT_SetError(PK11_MapError(crv));
+ return SECFailure;
}
return SECSuccess;
}
-
SECStatus
-PK11_ReadRawAttribute(PK11ObjectType objType, void *objSpec,
- CK_ATTRIBUTE_TYPE attrType, SECItem *item)
+PK11_ReadRawAttribute(PK11ObjectType objType, void *objSpec,
+ CK_ATTRIBUTE_TYPE attrType, SECItem *item)
{
PK11SlotInfo *slot = NULL;
CK_OBJECT_HANDLE handle = 0;
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;
+ 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;
+ 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)
+pk11_FindObjectByTemplate(PK11SlotInfo *slot, CK_ATTRIBUTE *theTemplate, int tsize)
{
CK_OBJECT_HANDLE object;
CK_RV crv = CKR_SESSION_HANDLE_INVALID;
@@ -1677,36 +1755,35 @@ pk11_FindObjectByTemplate(PK11SlotInfo *slot,CK_ATTRIBUTE *theTemplate,int tsize
*/
PK11_EnterSlotMonitor(slot);
if (slot->session != CK_INVALID_SESSION) {
- crv = PK11_GETTAB(slot)->C_FindObjectsInit(slot->session,
- theTemplate, tsize);
+ 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;
+ PORT_SetError(PK11_MapError(crv));
+ return CK_INVALID_HANDLE;
}
- crv=PK11_GETTAB(slot)->C_FindObjects(slot->session,&object,1,&objectCount);
+ 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;
+ /* 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)
+ int templCount, int *object_count)
{
CK_OBJECT_HANDLE *objID = NULL;
CK_ULONG returned_count = 0;
@@ -1714,54 +1791,55 @@ pk11_FindObjectsByTemplate(PK11SlotInfo *slot, CK_ATTRIBUTE *findTemplate,
PK11_EnterSlotMonitor(slot);
if (slot->session != CK_INVALID_SESSION) {
- crv = PK11_GETTAB(slot)->C_FindObjectsInit(slot->session,
- findTemplate, templCount);
+ 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;
+ 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;
+ 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;
+ PORT_Free(objID);
+ return NULL;
}
- if (objID == NULL) *object_count = -1;
+ if (objID == NULL)
+ *object_count = -1;
return objID;
}
/*
@@ -1770,49 +1848,46 @@ pk11_FindObjectsByTemplate(PK11SlotInfo *slot, CK_ATTRIBUTE *findTemplate,
*/
CK_OBJECT_HANDLE
PK11_MatchItem(PK11SlotInfo *slot, CK_OBJECT_HANDLE searchID,
- CK_OBJECT_CLASS matchclass)
+ CK_OBJECT_CLASS matchclass)
{
CK_ATTRIBUTE theTemplate[] = {
- { CKA_ID, NULL, 0 },
- { CKA_CLASS, NULL, 0 }
+ { 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]);
+ int tsize = sizeof(theTemplate) / sizeof(theTemplate[0]);
/* if you change the array, change the variable below as well */
CK_OBJECT_HANDLE peerID;
- PLArenaPool *arena;
+ PORTCheapArenaPool tmpArena;
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;
+ PORT_InitCheapArena(&tmpArena, DER_DEFAULT_CHUNKSIZE);
- crv = PK11_GetAttributes(arena,slot,searchID,theTemplate,tsize);
+ crv = PK11_GetAttributes(&tmpArena.arena, slot, searchID, theTemplate, tsize);
if (crv != CKR_OK) {
- PORT_FreeArena(arena,PR_FALSE);
- PORT_SetError( PK11_MapError(crv) );
- return CK_INVALID_HANDLE;
+ PORT_DestroyCheapArena(&tmpArena);
+ 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;
- }
-
-
+ PORT_DestroyCheapArena(&tmpArena);
+ if (matchclass == CKO_CERTIFICATE)
+ PORT_SetError(SEC_ERROR_BAD_KEY);
+ else
+ PORT_SetError(SEC_ERROR_NO_KEY);
+ return CK_INVALID_HANDLE;
+ }
/*
* issue the find
*/
*(CK_OBJECT_CLASS *)(keyclass->pValue) = matchclass;
- peerID = pk11_FindObjectByTemplate(slot,theTemplate,tsize);
- PORT_FreeArena(arena,PR_FALSE);
+ peerID = pk11_FindObjectByTemplate(slot, theTemplate, tsize);
+ PORT_DestroyCheapArena(&tmpArena);
return peerID;
}
@@ -1821,8 +1896,8 @@ PK11_MatchItem(PK11SlotInfo *slot, CK_OBJECT_HANDLE searchID,
* count the number of objects that match the template.
*/
int
-PK11_NumberObjectsFor(PK11SlotInfo *slot, CK_ATTRIBUTE *findTemplate,
- int templCount)
+PK11_NumberObjectsFor(PK11SlotInfo *slot, CK_ATTRIBUTE *findTemplate,
+ int templCount)
{
CK_OBJECT_HANDLE objID[PK11_SEARCH_CHUNKSIZE];
int object_count = 0;
@@ -1831,27 +1906,27 @@ PK11_NumberObjectsFor(PK11SlotInfo *slot, CK_ATTRIBUTE *findTemplate,
PK11_EnterSlotMonitor(slot);
if (slot->session != CK_INVALID_SESSION) {
- crv = PK11_GETTAB(slot)->C_FindObjectsInit(slot->session,
- findTemplate, templCount);
+ 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;
+ 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;
+ 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);
@@ -1868,22 +1943,22 @@ PK11_TraverseSlot(PK11SlotInfo *slot, void *arg)
int i;
CK_OBJECT_HANDLE *objID = NULL;
int object_count = 0;
- pk11TraverseSlot *slotcb = (pk11TraverseSlot*) arg;
+ pk11TraverseSlot *slotcb = (pk11TraverseSlot *)arg;
- objID = pk11_FindObjectsByTemplate(slot,slotcb->findTemplate,
- slotcb->templateCount,&object_count);
+ 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;
+ return SECSuccess;
}
if (objID == NULL) {
- return SECFailure;
+ return SECFailure;
}
- for (i=0; i < object_count; i++) {
- (*slotcb->callback)(slot,objID[i],slotcb->callbackArg);
+ for (i = 0; i < object_count; i++) {
+ (*slotcb->callback)(slot, objID[i], slotcb->callbackArg);
}
PORT_Free(objID);
return SECSuccess;
@@ -1893,27 +1968,29 @@ PK11_TraverseSlot(PK11SlotInfo *slot, void *arg)
* Traverse all the objects in all slots.
*/
SECStatus
-pk11_TraverseAllSlots( SECStatus (*callback)(PK11SlotInfo *,void *),
- void *arg, PRBool forceLogin, void *wincx) {
+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;
+ 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);
- }
+ 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);
@@ -1922,41 +1999,41 @@ pk11_TraverseAllSlots( SECStatus (*callback)(PK11SlotInfo *,void *),
}
CK_OBJECT_HANDLE *
-PK11_FindObjectsFromNickname(char *nickname,PK11SlotInfo **slotptr,
- CK_OBJECT_CLASS objclass, int *returnCount, void *wincx)
+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},
+ { CKA_LABEL, NULL, 0 },
+ { CKA_CLASS, NULL, 0 },
};
- int findCount = sizeof(findTemplate)/sizeof(findTemplate[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;
+ 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;
- }
+ /* 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();
+ *slotptr = slot = PK11_GetInternalKeySlot();
}
if (slot == NULL) {
return CK_INVALID_HANDLE;
@@ -1964,59 +2041,58 @@ PK11_FindObjectsFromNickname(char *nickname,PK11SlotInfo **slotptr,
rv = pk11_AuthenticateUnfriendly(slot, PR_TRUE, wincx);
if (rv != SECSuccess) {
- PK11_FreeSlot(slot);
- *slotptr = NULL;
- return CK_INVALID_HANDLE;
+ 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);
+ 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;
- }
+ /* 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)
+pk11_GetLowLevelKeyFromHandle(PK11SlotInfo *slot, CK_OBJECT_HANDLE handle)
{
CK_ATTRIBUTE theTemplate[] = {
- { CKA_ID, NULL, 0 },
+ { CKA_ID, NULL, 0 },
};
- int tsize = sizeof(theTemplate)/sizeof(theTemplate[0]);
+ int tsize = sizeof(theTemplate) / sizeof(theTemplate[0]);
CK_RV crv;
SECItem *item;
item = SECITEM_AllocItem(NULL, NULL, 0);
if (item == NULL) {
- return NULL;
+ return NULL;
}
- crv = PK11_GetAttributes(NULL,slot,handle,theTemplate,tsize);
+ crv = PK11_GetAttributes(NULL, slot, handle, theTemplate, tsize);
if (crv != CKR_OK) {
- SECITEM_FreeItem(item,PR_TRUE);
- PORT_SetError( PK11_MapError(crv) );
- return NULL;
+ SECITEM_FreeItem(item, PR_TRUE);
+ PORT_SetError(PK11_MapError(crv));
+ return NULL;
}
- item->data = (unsigned char*) theTemplate[0].pValue;
- item->len =theTemplate[0].ulValueLen;
+ item->data = (unsigned char *)theTemplate[0].pValue;
+ item->len = theTemplate[0].ulValueLen;
return item;
}
-
diff --git a/nss/lib/pk11wrap/pk11pars.c b/nss/lib/pk11wrap/pk11pars.c
index 40ac790..ee20789 100644
--- a/nss/lib/pk11wrap/pk11pars.c
+++ b/nss/lib/pk11wrap/pk11pars.c
@@ -7,6 +7,7 @@
*/
#include <ctype.h>
+#include <assert.h>
#include "pkcs11.h"
#include "seccomon.h"
#include "secmod.h"
@@ -14,29 +15,29 @@
#include "secmodti.h"
#include "pki3hack.h"
#include "secerr.h"
-
-#include "utilpars.h"
+#include "nss.h"
+#include "utilpars.h"
+#include "pk11pub.h"
/* create a new module */
-static SECMODModule *
+static SECMODModule *
secmod_NewModule(void)
{
SECMODModule *newMod;
PLArenaPool *arena;
-
/* create an arena in which dllName and commonName can be
* allocated.
*/
arena = PORT_NewArena(512);
if (arena == NULL) {
- return NULL;
+ return NULL;
}
- newMod = (SECMODModule *)PORT_ArenaAlloc(arena,sizeof (SECMODModule));
+ newMod = (SECMODModule *)PORT_ArenaAlloc(arena, sizeof(SECMODModule));
if (newMod == NULL) {
- PORT_FreeArena(arena,PR_FALSE);
- return NULL;
+ PORT_FreeArena(arena, PR_FALSE);
+ return NULL;
}
/*
@@ -68,148 +69,658 @@ secmod_NewModule(void)
newMod->evControlMask = 0;
newMod->refLock = PZ_NewLock(nssILockRefLock);
if (newMod->refLock == NULL) {
- PORT_FreeArena(arena,PR_FALSE);
- return 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
+ * 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
+ * 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
+ * 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
+ * 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
+ * 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_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
+ * 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
+ * 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
+#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)
+SECMOD_CreateModule(const char *library, const char *moduleName,
+ const char *parameters, const char *nss)
{
return SECMOD_CreateModuleEx(library, moduleName, parameters, nss, NULL);
}
/*
+ * NSS config options format:
+ *
+ * The specified ciphers will be allowed by policy, but an application
+ * may allow more by policy explicitly:
+ * config="allow=curve1:curve2:hash1:hash2:rsa-1024..."
+ *
+ * Only the specified hashes and curves will be allowed:
+ * config="disallow=all allow=sha1:sha256:secp256r1:secp384r1"
+ *
+ * Only the specified hashes and curves will be allowed, and
+ * RSA keys of 2048 or more will be accepted, and DH key exchange
+ * with 1024-bit primes or more:
+ * config="disallow=all allow=sha1:sha256:secp256r1:secp384r1:min-rsa=2048:min-dh=1024"
+ *
+ * A policy that enables the AES ciphersuites and the SECP256/384 curves:
+ * config="allow=aes128-cbc:aes128-gcm:TLS1.0:TLS1.2:TLS1.1:HMAC-SHA1:SHA1:SHA256:SHA384:RSA:ECDHE-RSA:SECP256R1:SECP384R1"
+ *
+ * Disallow values are parsed first, then allow values, independent of the
+ * order they appear.
+ *
+ * Future key words (not yet implemented):
+ * enable: turn on ciphersuites by default.
+ * disable: turn off ciphersuites by default without disallowing them by policy.
+ * flags: turn on the following flags:
+ * ssl-lock: turn off the ability for applications to change policy with
+ * the SSL_SetCipherPolicy (or SSL_SetPolicy).
+ * policy-lock: turn off the ability for applications to change policy with
+ * the call NSS_SetAlgorithmPolicy.
+ * ssl-default-lock: turn off the ability for applications to change cipher
+ * suite states with SSL_EnableCipher, SSL_DisableCipher.
+ *
+ */
+
+typedef struct {
+ const char *name;
+ unsigned name_size;
+ SECOidTag oid;
+ PRUint32 val;
+} oidValDef;
+
+typedef struct {
+ const char *name;
+ unsigned name_size;
+ PRInt32 option;
+} optionFreeDef;
+
+typedef struct {
+ const char *name;
+ unsigned name_size;
+ PRUint32 flag;
+} policyFlagDef;
+
+/*
+ * This table should be merged with the SECOID table.
+ */
+#define CIPHER_NAME(x) x, (sizeof(x) - 1)
+static const oidValDef algOptList[] = {
+ /* Curves */
+ { CIPHER_NAME("PRIME192V1"), SEC_OID_ANSIX962_EC_PRIME192V1,
+ NSS_USE_ALG_IN_SSL_KX | NSS_USE_ALG_IN_CERT_SIGNATURE },
+ { CIPHER_NAME("PRIME192V2"), SEC_OID_ANSIX962_EC_PRIME192V2,
+ NSS_USE_ALG_IN_SSL_KX | NSS_USE_ALG_IN_CERT_SIGNATURE },
+ { CIPHER_NAME("PRIME192V3"), SEC_OID_ANSIX962_EC_PRIME192V3,
+ NSS_USE_ALG_IN_SSL_KX | NSS_USE_ALG_IN_CERT_SIGNATURE },
+ { CIPHER_NAME("PRIME239V1"), SEC_OID_ANSIX962_EC_PRIME239V1,
+ NSS_USE_ALG_IN_SSL_KX | NSS_USE_ALG_IN_CERT_SIGNATURE },
+ { CIPHER_NAME("PRIME239V2"), SEC_OID_ANSIX962_EC_PRIME239V2,
+ NSS_USE_ALG_IN_SSL_KX | NSS_USE_ALG_IN_CERT_SIGNATURE },
+ { CIPHER_NAME("PRIME239V3"), SEC_OID_ANSIX962_EC_PRIME239V3,
+ NSS_USE_ALG_IN_SSL_KX | NSS_USE_ALG_IN_CERT_SIGNATURE },
+ { CIPHER_NAME("PRIME256V1"), SEC_OID_ANSIX962_EC_PRIME256V1,
+ NSS_USE_ALG_IN_SSL_KX | NSS_USE_ALG_IN_CERT_SIGNATURE },
+ { CIPHER_NAME("SECP112R1"), SEC_OID_SECG_EC_SECP112R1,
+ NSS_USE_ALG_IN_SSL_KX | NSS_USE_ALG_IN_CERT_SIGNATURE },
+ { CIPHER_NAME("SECP112R2"), SEC_OID_SECG_EC_SECP112R2,
+ NSS_USE_ALG_IN_SSL_KX | NSS_USE_ALG_IN_CERT_SIGNATURE },
+ { CIPHER_NAME("SECP128R1"), SEC_OID_SECG_EC_SECP128R1,
+ NSS_USE_ALG_IN_SSL_KX | NSS_USE_ALG_IN_CERT_SIGNATURE },
+ { CIPHER_NAME("SECP128R2"), SEC_OID_SECG_EC_SECP128R2,
+ NSS_USE_ALG_IN_SSL_KX | NSS_USE_ALG_IN_CERT_SIGNATURE },
+ { CIPHER_NAME("SECP160K1"), SEC_OID_SECG_EC_SECP160K1,
+ NSS_USE_ALG_IN_SSL_KX | NSS_USE_ALG_IN_CERT_SIGNATURE },
+ { CIPHER_NAME("SECP160R1"), SEC_OID_SECG_EC_SECP160R1,
+ NSS_USE_ALG_IN_SSL_KX | NSS_USE_ALG_IN_CERT_SIGNATURE },
+ { CIPHER_NAME("SECP160R2"), SEC_OID_SECG_EC_SECP160R2,
+ NSS_USE_ALG_IN_SSL_KX | NSS_USE_ALG_IN_CERT_SIGNATURE },
+ { CIPHER_NAME("SECP192K1"), SEC_OID_SECG_EC_SECP192K1,
+ NSS_USE_ALG_IN_SSL_KX | NSS_USE_ALG_IN_CERT_SIGNATURE },
+ { CIPHER_NAME("SECP192R1"), SEC_OID_ANSIX962_EC_PRIME192V1,
+ NSS_USE_ALG_IN_SSL_KX | NSS_USE_ALG_IN_CERT_SIGNATURE },
+ { CIPHER_NAME("SECP224K1"), SEC_OID_SECG_EC_SECP224K1,
+ NSS_USE_ALG_IN_SSL_KX | NSS_USE_ALG_IN_CERT_SIGNATURE },
+ { CIPHER_NAME("SECP256K1"), SEC_OID_SECG_EC_SECP256K1,
+ NSS_USE_ALG_IN_SSL_KX | NSS_USE_ALG_IN_CERT_SIGNATURE },
+ { CIPHER_NAME("SECP256R1"), SEC_OID_ANSIX962_EC_PRIME256V1,
+ NSS_USE_ALG_IN_SSL_KX | NSS_USE_ALG_IN_CERT_SIGNATURE },
+ { CIPHER_NAME("SECP384R1"), SEC_OID_SECG_EC_SECP384R1,
+ NSS_USE_ALG_IN_SSL_KX | NSS_USE_ALG_IN_CERT_SIGNATURE },
+ { CIPHER_NAME("SECP521R1"), SEC_OID_SECG_EC_SECP521R1,
+ NSS_USE_ALG_IN_SSL_KX | NSS_USE_ALG_IN_CERT_SIGNATURE },
+ /* ANSI X9.62 named elliptic curves (characteristic two field) */
+ { CIPHER_NAME("C2PNB163V1"), SEC_OID_ANSIX962_EC_C2PNB163V1,
+ NSS_USE_ALG_IN_SSL_KX | NSS_USE_ALG_IN_CERT_SIGNATURE },
+ { CIPHER_NAME("C2PNB163V2"), SEC_OID_ANSIX962_EC_C2PNB163V2,
+ NSS_USE_ALG_IN_SSL_KX | NSS_USE_ALG_IN_CERT_SIGNATURE },
+ { CIPHER_NAME("C2PNB163V3"), SEC_OID_ANSIX962_EC_C2PNB163V3,
+ NSS_USE_ALG_IN_SSL_KX | NSS_USE_ALG_IN_CERT_SIGNATURE },
+ { CIPHER_NAME("C2PNB176V1"), SEC_OID_ANSIX962_EC_C2PNB176V1,
+ NSS_USE_ALG_IN_SSL_KX | NSS_USE_ALG_IN_CERT_SIGNATURE },
+ { CIPHER_NAME("C2TNB191V1"), SEC_OID_ANSIX962_EC_C2TNB191V1,
+ NSS_USE_ALG_IN_SSL_KX | NSS_USE_ALG_IN_CERT_SIGNATURE },
+ { CIPHER_NAME("C2TNB191V2"), SEC_OID_ANSIX962_EC_C2TNB191V2,
+ NSS_USE_ALG_IN_SSL_KX | NSS_USE_ALG_IN_CERT_SIGNATURE },
+ { CIPHER_NAME("C2TNB191V3"), SEC_OID_ANSIX962_EC_C2TNB191V3,
+ NSS_USE_ALG_IN_SSL_KX | NSS_USE_ALG_IN_CERT_SIGNATURE },
+ { CIPHER_NAME("C2ONB191V4"), SEC_OID_ANSIX962_EC_C2ONB191V4,
+ NSS_USE_ALG_IN_SSL_KX | NSS_USE_ALG_IN_CERT_SIGNATURE },
+ { CIPHER_NAME("C2ONB191V5"), SEC_OID_ANSIX962_EC_C2ONB191V5,
+ NSS_USE_ALG_IN_SSL_KX | NSS_USE_ALG_IN_CERT_SIGNATURE },
+ { CIPHER_NAME("C2PNB208W1"), SEC_OID_ANSIX962_EC_C2PNB208W1,
+ NSS_USE_ALG_IN_SSL_KX | NSS_USE_ALG_IN_CERT_SIGNATURE },
+ { CIPHER_NAME("C2TNB239V1"), SEC_OID_ANSIX962_EC_C2TNB239V1,
+ NSS_USE_ALG_IN_SSL_KX | NSS_USE_ALG_IN_CERT_SIGNATURE },
+ { CIPHER_NAME("C2TNB239V2"), SEC_OID_ANSIX962_EC_C2TNB239V2,
+ NSS_USE_ALG_IN_SSL_KX | NSS_USE_ALG_IN_CERT_SIGNATURE },
+ { CIPHER_NAME("C2TNB239V3"), SEC_OID_ANSIX962_EC_C2TNB239V3,
+ NSS_USE_ALG_IN_SSL_KX | NSS_USE_ALG_IN_CERT_SIGNATURE },
+ { CIPHER_NAME("C2ONB239V4"), SEC_OID_ANSIX962_EC_C2ONB239V4,
+ NSS_USE_ALG_IN_SSL_KX | NSS_USE_ALG_IN_CERT_SIGNATURE },
+ { CIPHER_NAME("C2ONB239V5"), SEC_OID_ANSIX962_EC_C2ONB239V5,
+ NSS_USE_ALG_IN_SSL_KX | NSS_USE_ALG_IN_CERT_SIGNATURE },
+ { CIPHER_NAME("C2PNB272W1"), SEC_OID_ANSIX962_EC_C2PNB272W1,
+ NSS_USE_ALG_IN_SSL_KX | NSS_USE_ALG_IN_CERT_SIGNATURE },
+ { CIPHER_NAME("C2PNB304W1"), SEC_OID_ANSIX962_EC_C2PNB304W1,
+ NSS_USE_ALG_IN_SSL_KX | NSS_USE_ALG_IN_CERT_SIGNATURE },
+ { CIPHER_NAME("C2TNB359V1"), SEC_OID_ANSIX962_EC_C2TNB359V1,
+ NSS_USE_ALG_IN_SSL_KX | NSS_USE_ALG_IN_CERT_SIGNATURE },
+ { CIPHER_NAME("C2PNB368W1"), SEC_OID_ANSIX962_EC_C2PNB368W1,
+ NSS_USE_ALG_IN_SSL_KX | NSS_USE_ALG_IN_CERT_SIGNATURE },
+ { CIPHER_NAME("C2TNB431R1"), SEC_OID_ANSIX962_EC_C2TNB431R1,
+ NSS_USE_ALG_IN_SSL_KX | NSS_USE_ALG_IN_CERT_SIGNATURE },
+ /* SECG named elliptic curves (characteristic two field) */
+ { CIPHER_NAME("SECT113R1"), SEC_OID_SECG_EC_SECT113R1,
+ NSS_USE_ALG_IN_SSL_KX | NSS_USE_ALG_IN_CERT_SIGNATURE },
+ { CIPHER_NAME("SECT131R1"), SEC_OID_SECG_EC_SECT113R2,
+ NSS_USE_ALG_IN_SSL_KX | NSS_USE_ALG_IN_CERT_SIGNATURE },
+ { CIPHER_NAME("SECT131R1"), SEC_OID_SECG_EC_SECT131R1,
+ NSS_USE_ALG_IN_SSL_KX | NSS_USE_ALG_IN_CERT_SIGNATURE },
+ { CIPHER_NAME("SECT131R2"), SEC_OID_SECG_EC_SECT131R2,
+ NSS_USE_ALG_IN_SSL_KX | NSS_USE_ALG_IN_CERT_SIGNATURE },
+ { CIPHER_NAME("SECT163K1"), SEC_OID_SECG_EC_SECT163K1,
+ NSS_USE_ALG_IN_SSL_KX | NSS_USE_ALG_IN_CERT_SIGNATURE },
+ { CIPHER_NAME("SECT163R1"), SEC_OID_SECG_EC_SECT163R1,
+ NSS_USE_ALG_IN_SSL_KX | NSS_USE_ALG_IN_CERT_SIGNATURE },
+ { CIPHER_NAME("SECT163R2"), SEC_OID_SECG_EC_SECT163R2,
+ NSS_USE_ALG_IN_SSL_KX | NSS_USE_ALG_IN_CERT_SIGNATURE },
+ { CIPHER_NAME("SECT193R1"), SEC_OID_SECG_EC_SECT193R1,
+ NSS_USE_ALG_IN_SSL_KX | NSS_USE_ALG_IN_CERT_SIGNATURE },
+ { CIPHER_NAME("SECT193R2"), SEC_OID_SECG_EC_SECT193R2,
+ NSS_USE_ALG_IN_SSL_KX | NSS_USE_ALG_IN_CERT_SIGNATURE },
+ { CIPHER_NAME("SECT233K1"), SEC_OID_SECG_EC_SECT233K1,
+ NSS_USE_ALG_IN_SSL_KX | NSS_USE_ALG_IN_CERT_SIGNATURE },
+ { CIPHER_NAME("SECT233R1"), SEC_OID_SECG_EC_SECT233R1,
+ NSS_USE_ALG_IN_SSL_KX | NSS_USE_ALG_IN_CERT_SIGNATURE },
+ { CIPHER_NAME("SECT239K1"), SEC_OID_SECG_EC_SECT239K1,
+ NSS_USE_ALG_IN_SSL_KX | NSS_USE_ALG_IN_CERT_SIGNATURE },
+ { CIPHER_NAME("SECT283K1"), SEC_OID_SECG_EC_SECT283K1,
+ NSS_USE_ALG_IN_SSL_KX | NSS_USE_ALG_IN_CERT_SIGNATURE },
+ { CIPHER_NAME("SECT283R1"), SEC_OID_SECG_EC_SECT283R1,
+ NSS_USE_ALG_IN_SSL_KX | NSS_USE_ALG_IN_CERT_SIGNATURE },
+ { CIPHER_NAME("SECT409K1"), SEC_OID_SECG_EC_SECT409K1,
+ NSS_USE_ALG_IN_SSL_KX | NSS_USE_ALG_IN_CERT_SIGNATURE },
+ { CIPHER_NAME("SECT409R1"), SEC_OID_SECG_EC_SECT409R1,
+ NSS_USE_ALG_IN_SSL_KX | NSS_USE_ALG_IN_CERT_SIGNATURE },
+ { CIPHER_NAME("SECT571K1"), SEC_OID_SECG_EC_SECT571K1,
+ NSS_USE_ALG_IN_SSL_KX | NSS_USE_ALG_IN_CERT_SIGNATURE },
+ { CIPHER_NAME("SECT571R1"), SEC_OID_SECG_EC_SECT571R1,
+ NSS_USE_ALG_IN_SSL_KX | NSS_USE_ALG_IN_CERT_SIGNATURE },
+
+ /* Hashes */
+ { CIPHER_NAME("MD2"), SEC_OID_MD2,
+ NSS_USE_ALG_IN_SSL_KX | NSS_USE_ALG_IN_CERT_SIGNATURE },
+ { CIPHER_NAME("MD4"), SEC_OID_MD4,
+ NSS_USE_ALG_IN_SSL_KX | NSS_USE_ALG_IN_CERT_SIGNATURE },
+ { CIPHER_NAME("MD5"), SEC_OID_MD5,
+ NSS_USE_ALG_IN_SSL_KX | NSS_USE_ALG_IN_CERT_SIGNATURE },
+ { CIPHER_NAME("SHA1"), SEC_OID_SHA1,
+ NSS_USE_ALG_IN_SSL_KX | NSS_USE_ALG_IN_CERT_SIGNATURE },
+ { CIPHER_NAME("SHA224"), SEC_OID_SHA224,
+ NSS_USE_ALG_IN_SSL_KX | NSS_USE_ALG_IN_CERT_SIGNATURE },
+ { CIPHER_NAME("SHA256"), SEC_OID_SHA256,
+ NSS_USE_ALG_IN_SSL_KX | NSS_USE_ALG_IN_CERT_SIGNATURE },
+ { CIPHER_NAME("SHA384"), SEC_OID_SHA384,
+ NSS_USE_ALG_IN_SSL_KX | NSS_USE_ALG_IN_CERT_SIGNATURE },
+ { CIPHER_NAME("SHA512"), SEC_OID_SHA512,
+ NSS_USE_ALG_IN_SSL_KX | NSS_USE_ALG_IN_CERT_SIGNATURE },
+
+ /* MACs */
+ { CIPHER_NAME("HMAC-SHA1"), SEC_OID_HMAC_SHA1, NSS_USE_ALG_IN_SSL },
+ { CIPHER_NAME("HMAC-SHA224"), SEC_OID_HMAC_SHA224, NSS_USE_ALG_IN_SSL },
+ { CIPHER_NAME("HMAC-SHA256"), SEC_OID_HMAC_SHA256, NSS_USE_ALG_IN_SSL },
+ { CIPHER_NAME("HMAC-SHA384"), SEC_OID_HMAC_SHA384, NSS_USE_ALG_IN_SSL },
+ { CIPHER_NAME("HMAC-SHA512"), SEC_OID_HMAC_SHA512, NSS_USE_ALG_IN_SSL },
+ { CIPHER_NAME("HMAC-MD5"), SEC_OID_HMAC_MD5, NSS_USE_ALG_IN_SSL },
+
+ /* Ciphers */
+ { CIPHER_NAME("AES128-CBC"), SEC_OID_AES_128_CBC, NSS_USE_ALG_IN_SSL },
+ { CIPHER_NAME("AES192-CBC"), SEC_OID_AES_192_CBC, NSS_USE_ALG_IN_SSL },
+ { CIPHER_NAME("AES256-CBC"), SEC_OID_AES_256_CBC, NSS_USE_ALG_IN_SSL },
+ { CIPHER_NAME("AES128-GCM"), SEC_OID_AES_128_GCM, NSS_USE_ALG_IN_SSL },
+ { CIPHER_NAME("AES192-GCM"), SEC_OID_AES_192_GCM, NSS_USE_ALG_IN_SSL },
+ { CIPHER_NAME("AES256-GCM"), SEC_OID_AES_256_GCM, NSS_USE_ALG_IN_SSL },
+ { CIPHER_NAME("CAMELLIA128-CBC"), SEC_OID_CAMELLIA_128_CBC, NSS_USE_ALG_IN_SSL },
+ { CIPHER_NAME("CAMELLIA192-CBC"), SEC_OID_CAMELLIA_192_CBC, NSS_USE_ALG_IN_SSL },
+ { CIPHER_NAME("CAMELLIA256-CBC"), SEC_OID_CAMELLIA_256_CBC, NSS_USE_ALG_IN_SSL },
+ { CIPHER_NAME("CHACHA20-POLY1305"), SEC_OID_CHACHA20_POLY1305, NSS_USE_ALG_IN_SSL },
+ { CIPHER_NAME("SEED-CBC"), SEC_OID_SEED_CBC, NSS_USE_ALG_IN_SSL },
+ { CIPHER_NAME("DES-EDE3-CBC"), SEC_OID_DES_EDE3_CBC, NSS_USE_ALG_IN_SSL },
+ { CIPHER_NAME("DES-40-CBC"), SEC_OID_DES_40_CBC, NSS_USE_ALG_IN_SSL },
+ { CIPHER_NAME("DES-CBC"), SEC_OID_DES_CBC, NSS_USE_ALG_IN_SSL },
+ { CIPHER_NAME("NULL-CIPHER"), SEC_OID_NULL_CIPHER, NSS_USE_ALG_IN_SSL },
+ { CIPHER_NAME("RC2"), SEC_OID_RC2_CBC, NSS_USE_ALG_IN_SSL },
+ { CIPHER_NAME("RC4"), SEC_OID_RC4, NSS_USE_ALG_IN_SSL },
+ { CIPHER_NAME("IDEA"), SEC_OID_IDEA_CBC, NSS_USE_ALG_IN_SSL },
+
+ /* Key exchange */
+ { CIPHER_NAME("RSA"), SEC_OID_TLS_RSA, NSS_USE_ALG_IN_SSL_KX },
+ { CIPHER_NAME("RSA-EXPORT"), SEC_OID_TLS_RSA_EXPORT, NSS_USE_ALG_IN_SSL_KX },
+ { CIPHER_NAME("DHE-RSA"), SEC_OID_TLS_DHE_RSA, NSS_USE_ALG_IN_SSL_KX },
+ { CIPHER_NAME("DHE-DSS"), SEC_OID_TLS_DHE_DSS, NSS_USE_ALG_IN_SSL_KX },
+ { CIPHER_NAME("DH-RSA"), SEC_OID_TLS_DH_RSA, NSS_USE_ALG_IN_SSL_KX },
+ { CIPHER_NAME("DH-DSS"), SEC_OID_TLS_DH_DSS, NSS_USE_ALG_IN_SSL_KX },
+ { CIPHER_NAME("ECDHE-ECDSA"), SEC_OID_TLS_ECDHE_ECDSA, NSS_USE_ALG_IN_SSL_KX },
+ { CIPHER_NAME("ECDHE-RSA"), SEC_OID_TLS_ECDHE_RSA, NSS_USE_ALG_IN_SSL_KX },
+ { CIPHER_NAME("ECDH-ECDSA"), SEC_OID_TLS_ECDH_ECDSA, NSS_USE_ALG_IN_SSL_KX },
+ { CIPHER_NAME("ECDH-RSA"), SEC_OID_TLS_ECDH_RSA, NSS_USE_ALG_IN_SSL_KX },
+};
+
+static const optionFreeDef sslOptList[] = {
+ /* Versions */
+ { CIPHER_NAME("SSL2.0"), 0x002 },
+ { CIPHER_NAME("SSL3.0"), 0x300 },
+ { CIPHER_NAME("SSL3.1"), 0x301 },
+ { CIPHER_NAME("TLS1.0"), 0x301 },
+ { CIPHER_NAME("TLS1.1"), 0x302 },
+ { CIPHER_NAME("TLS1.2"), 0x303 },
+ { CIPHER_NAME("TLS1.3"), 0x304 },
+ { CIPHER_NAME("DTLS1.0"), 0x302 },
+ { CIPHER_NAME("DTLS1.1"), 0x302 },
+ { CIPHER_NAME("DTLS1.2"), 0x303 },
+ { CIPHER_NAME("DTLS1.3"), 0x304 },
+};
+
+static const optionFreeDef freeOptList[] = {
+
+ /* Restrictions for asymetric keys */
+ { CIPHER_NAME("RSA-MIN"), NSS_RSA_MIN_KEY_SIZE },
+ { CIPHER_NAME("DH-MIN"), NSS_DH_MIN_KEY_SIZE },
+ { CIPHER_NAME("DSA-MIN"), NSS_DSA_MIN_KEY_SIZE },
+ /* constraints on SSL Protocols */
+ { CIPHER_NAME("TLS-VERSION-MIN"), NSS_TLS_VERSION_MIN_POLICY },
+ { CIPHER_NAME("TLS-VERSION-MAX"), NSS_TLS_VERSION_MAX_POLICY },
+ /* constraints on DTLS Protocols */
+ { CIPHER_NAME("DTLS-VERSION-MIN"), NSS_DTLS_VERSION_MIN_POLICY },
+ { CIPHER_NAME("DTLS-VERSION-MAX"), NSS_DTLS_VERSION_MIN_POLICY }
+};
+
+static const policyFlagDef policyFlagList[] = {
+ { CIPHER_NAME("SSL"), NSS_USE_ALG_IN_SSL },
+ { CIPHER_NAME("SSL-KEY-EXCHANGE"), NSS_USE_ALG_IN_SSL_KX },
+ /* add other key exhanges in the future */
+ { CIPHER_NAME("KEY-EXCHANGE"), NSS_USE_ALG_IN_SSL_KX },
+ { CIPHER_NAME("CERT-SIGNATURE"), NSS_USE_ALG_IN_CERT_SIGNATURE },
+ /* add other signatures in the future */
+ { CIPHER_NAME("SIGNATURE"), NSS_USE_ALG_IN_CERT_SIGNATURE },
+ /* enable everything */
+ { CIPHER_NAME("ALL"), NSS_USE_ALG_IN_SSL | NSS_USE_ALG_IN_SSL_KX |
+ NSS_USE_ALG_IN_CERT_SIGNATURE },
+ { CIPHER_NAME("NONE"), 0 }
+};
+
+/*
+ * Get the next cipher on the list. point to the next one in 'next'.
+ * return the length;
+ */
+static const char *
+secmod_ArgGetSubValue(const char *cipher, char sep1, char sep2,
+ int *len, const char **next)
+{
+ const char *start = cipher;
+
+ if (start == NULL) {
+ *len = 0;
+ *next = NULL;
+ return start;
+ }
+
+ for (; *cipher && *cipher != sep2; cipher++) {
+ if (*cipher == sep1) {
+ *next = cipher + 1;
+ *len = cipher - start;
+ return start;
+ }
+ }
+ *next = NULL;
+ *len = cipher - start;
+ return start;
+}
+
+static PRUint32
+secmod_parsePolicyValue(const char *policyFlags, int policyLength)
+{
+ const char *flag, *currentString;
+ PRUint32 flags = 0;
+ int i;
+
+ for (currentString = policyFlags; currentString &&
+ currentString < policyFlags + policyLength;) {
+ int length;
+ flag = secmod_ArgGetSubValue(currentString, ',', ':', &length,
+ &currentString);
+ if (length == 0) {
+ continue;
+ }
+ for (i = 0; i < PR_ARRAY_SIZE(policyFlagList); i++) {
+ const policyFlagDef *policy = &policyFlagList[i];
+ unsigned name_size = policy->name_size;
+ if ((policy->name_size == length) &&
+ PORT_Strncasecmp(policy->name, flag, name_size) == 0) {
+ flags |= policy->flag;
+ break;
+ }
+ }
+ }
+ return flags;
+}
+
+/* allow symbolic names for values. The only ones currently defines or
+ * SSL protocol versions. */
+static PRInt32
+secmod_getPolicyOptValue(const char *policyValue, int policyValueLength)
+{
+ PRInt32 val = atoi(policyValue);
+ int i;
+
+ if ((val != 0) || (*policyValue == '0')) {
+ return val;
+ }
+ for (i = 0; i < PR_ARRAY_SIZE(sslOptList); i++) {
+ if (policyValueLength == sslOptList[i].name_size &&
+ PORT_Strncasecmp(sslOptList[i].name, policyValue,
+ sslOptList[i].name_size) == 0) {
+ val = sslOptList[i].option;
+ break;
+ }
+ }
+ return val;
+}
+
+static SECStatus
+secmod_applyCryptoPolicy(const char *policyString,
+ PRBool allow)
+{
+ const char *cipher, *currentString;
+ unsigned i;
+ SECStatus rv = SECSuccess;
+ PRBool unknown;
+
+ if (policyString == NULL || policyString[0] == 0) {
+ return SECSuccess; /* do nothing */
+ }
+
+ /* if we change any of these, make sure it gets applied in ssl as well */
+ NSS_SetAlgorithmPolicy(SEC_OID_APPLY_SSL_POLICY, NSS_USE_POLICY_IN_SSL, 0);
+
+ for (currentString = policyString; currentString;) {
+ int length;
+ PRBool newValue = PR_FALSE;
+
+ cipher = secmod_ArgGetSubValue(currentString, ':', 0, &length,
+ &currentString);
+ unknown = PR_TRUE;
+ if (length >= 3 && cipher[3] == '/') {
+ newValue = PR_TRUE;
+ }
+ if ((newValue || (length == 3)) && PORT_Strncasecmp(cipher, "all", 3) == 0) {
+ /* disable or enable all options by default */
+ PRUint32 value = 0;
+ if (newValue) {
+ value = secmod_parsePolicyValue(&cipher[3] + 1, length - 3 - 1);
+ }
+ for (i = 0; i < PR_ARRAY_SIZE(algOptList); i++) {
+ PRUint32 enable, disable;
+ if (!newValue) {
+ value = algOptList[i].val;
+ }
+ if (allow) {
+ enable = value;
+ disable = 0;
+ } else {
+ enable = 0;
+ disable = value;
+ }
+ NSS_SetAlgorithmPolicy(algOptList[i].oid, enable, disable);
+ }
+ continue;
+ }
+
+ for (i = 0; i < PR_ARRAY_SIZE(algOptList); i++) {
+ const oidValDef *algOpt = &algOptList[i];
+ unsigned name_size = algOpt->name_size;
+ PRBool newValue = PR_FALSE;
+
+ if ((length >= name_size) && (cipher[name_size] == '/')) {
+ newValue = PR_TRUE;
+ }
+ if ((newValue || algOpt->name_size == length) &&
+ PORT_Strncasecmp(algOpt->name, cipher, name_size) == 0) {
+ PRUint32 value = algOpt->val;
+ PRUint32 enable, disable;
+ if (newValue) {
+ value = secmod_parsePolicyValue(&cipher[name_size] + 1,
+ length - name_size - 1);
+ }
+ if (allow) {
+ enable = value;
+ disable = 0;
+ } else {
+ enable = 0;
+ disable = value;
+ }
+ rv = NSS_SetAlgorithmPolicy(algOpt->oid, enable, disable);
+ if (rv != SECSuccess) {
+ /* could not enable option */
+ /* NSS_SetAlgorithPolicy should have set the error code */
+ return SECFailure;
+ }
+ unknown = PR_FALSE;
+ break;
+ }
+ }
+ if (!unknown) {
+ continue;
+ }
+
+ for (i = 0; i < PR_ARRAY_SIZE(freeOptList); i++) {
+ const optionFreeDef *freeOpt = &freeOptList[i];
+ unsigned name_size = freeOpt->name_size;
+
+ if ((length > name_size) && cipher[name_size] == '=' &&
+ PORT_Strncasecmp(freeOpt->name, cipher, name_size) == 0) {
+ PRInt32 val = secmod_getPolicyOptValue(&cipher[name_size + 1],
+ length - name_size - 1);
+
+ rv = NSS_OptionSet(freeOpt->option, val);
+ if (rv != SECSuccess) {
+ /* could not enable option */
+ /* NSS_OptionSet should have set the error code */
+ return SECFailure;
+ }
+ /* to allow the policy to expand in the future. ignore ciphers
+ * we don't understand */
+ unknown = PR_FALSE;
+ break;
+ }
+ }
+ }
+ return rv;
+}
+
+static SECStatus
+secmod_parseCryptoPolicy(const char *policyConfig)
+{
+ char *disallow, *allow;
+ SECStatus rv;
+
+ if (policyConfig == NULL) {
+ return SECSuccess; /* no policy given */
+ }
+ /* make sure we initialize the oid table and set all the default policy
+ * values first so we can override them here */
+ rv = SECOID_Init();
+ if (rv != SECSuccess) {
+ return rv;
+ }
+ disallow = NSSUTIL_ArgGetParamValue("disallow", policyConfig);
+ rv = secmod_applyCryptoPolicy(disallow, PR_FALSE);
+ if (disallow)
+ PORT_Free(disallow);
+ if (rv != SECSuccess) {
+ return rv;
+ }
+ allow = NSSUTIL_ArgGetParamValue("allow", policyConfig);
+ rv = secmod_applyCryptoPolicy(allow, PR_TRUE);
+ if (allow)
+ PORT_Free(allow);
+ return rv;
+}
+
+/*
* for 3.4 we continue to use the old SECMODModule structure
*/
SECMODModule *
-SECMOD_CreateModuleEx(const char *library, const char *moduleName,
- const char *parameters, const char *nss,
- const char *config)
+SECMOD_CreateModuleEx(const char *library, const char *moduleName,
+ const char *parameters, const char *nss,
+ const char *config)
{
- SECMODModule *mod = secmod_NewModule();
- char *slotParams,*ciphers;
+ SECMODModule *mod;
+ SECStatus rv;
+ 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 : "");
+ rv = secmod_parseCryptoPolicy(config);
+
+ /* do not load the module if policy parsing fails */
+ if (rv != SECSuccess) {
+ return NULL;
+ }
+
+ mod = secmod_NewModule();
+ if (mod == NULL)
+ return NULL;
+
+ mod->commonName = PORT_ArenaStrdup(mod->arena, moduleName ? moduleName : "");
if (library) {
- mod->dllName = PORT_ArenaStrdup(mod->arena,library);
+ mod->dllName = PORT_ArenaStrdup(mod->arena, library);
}
/* new field */
if (parameters) {
- mod->libraryParams = PORT_ArenaStrdup(mod->arena,parameters);
- }
- if (config) {
- /* XXX: Apply configuration */
- }
- 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);
+ 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);
+ mod->trustOrder = NSSUTIL_ArgReadLong("trustOrder", nssc,
+ NSSUTIL_DEFAULT_TRUST_ORDER, NULL);
/* new field */
- mod->cipherOrder = NSSUTIL_ArgReadLong("cipherOrder",nssc,
- NSSUTIL_DEFAULT_CIPHER_ORDER,NULL);
+ 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;
+ 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.
+ /* 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
+ * 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;
+ 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;
+ char flags = SECMOD_FLAG_INTERNAL_IS_INTERNAL;
- if (NSSUTIL_ArgHasFlag("flags", "internalKeySlot", nssc)) {
- flags |= SECMOD_FLAG_INTERNAL_KEY_SLOT;
- }
- mod->internal = (PRBool) flags;
+ 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);
+ ciphers = NSSUTIL_ArgGetParamValue("ciphers", nssc);
+ NSSUTIL_ArgParseCipherFlags(&mod->ssl[0], ciphers);
+ if (ciphers)
+ PORT_Free(ciphers);
secmod_PrivateModuleCount++;
@@ -219,38 +730,38 @@ SECMOD_CreateModuleEx(const char *library, const char *moduleName,
PRBool
SECMOD_GetSkipFirstFlag(SECMODModule *mod)
{
- char flags = (char) mod->isModuleDB;
+ char flags = (char)mod->isModuleDB;
- return (flags & SECMOD_FLAG_MODULE_DB_SKIP_FIRST) ? PR_TRUE : PR_FALSE;
+ return (flags & SECMOD_FLAG_MODULE_DB_SKIP_FIRST) ? PR_TRUE : PR_FALSE;
}
PRBool
SECMOD_GetDefaultModDBFlag(SECMODModule *mod)
{
- char flags = (char) mod->isModuleDB;
+ char flags = (char)mod->isModuleDB;
- return (flags & SECMOD_FLAG_MODULE_DB_DEFAULT_MODDB) ? PR_TRUE : PR_FALSE;
+ return (flags & SECMOD_FLAG_MODULE_DB_DEFAULT_MODDB) ? PR_TRUE : PR_FALSE;
}
PRBool
secmod_IsInternalKeySlot(SECMODModule *mod)
{
- char flags = (char) mod->internal;
+ char flags = (char)mod->internal;
- return (flags & SECMOD_FLAG_INTERNAL_KEY_SLOT) ? PR_TRUE : PR_FALSE;
+ 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;
+ char flags = (char)mod->internal;
+
+ if (val) {
+ flags |= SECMOD_FLAG_INTERNAL_KEY_SLOT;
+ } else {
+ flags &= ~SECMOD_FLAG_INTERNAL_KEY_SLOT;
+ }
+ mod->internal = flags;
}
/*
@@ -264,50 +775,49 @@ secmod_SetInternalKeySlotFlag(SECMODModule *mod, PRBool val)
*/
static char *
secmod_doDescCopy(char *target, int *targetLen, const char *desc,
- int descLen, char *value)
+ 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 */
- }
+ /* 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++='\"';
+ *target++ = '\"';
PORT_Memcpy(target, value, esc_len);
target += esc_len;
- *target++='\"';
+ *target++ = '\"';
if (diff > 0) {
- PORT_Free(value);
+ 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_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="
-
+#define SECMOD_SLOT_DESCRIPTION "slotDescription="
/*
- * Find any tokens= values in the module spec.
+ * 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.
@@ -316,37 +826,37 @@ secmod_doDescCopy(char *target, int *targetLen, const char *desc,
* spec.
*/
char *
-secmod_ParseModuleSpecForTokens(PRBool convert, PRBool isFIPS,
- char *moduleSpec, char ***children,
- CK_SLOT_ID **ids)
+secmod_ParseModuleSpecForTokens(PRBool convert, PRBool isFIPS,
+ const 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;
+ int newSpecLen = PORT_Strlen(moduleSpec) + 2;
+ char *newSpec = PORT_Alloc(newSpecLen);
+ char *newSpecPtr = newSpec;
+ const char *modulePrev = moduleSpec;
+ char *target = NULL;
char *tmp = NULL;
- char **childArray = NULL;
- char *tokenIndex;
- CK_SLOT_ID *idArray = NULL;
- int tokenCount = 0;
- int i;
+ char **childArray = NULL;
+ const char *tokenIndex;
+ CK_SLOT_ID *idArray = NULL;
+ int tokenCount = 0;
+ int i;
if (newSpec == NULL) {
- return NULL;
+ return NULL;
}
*children = NULL;
if (ids) {
- *ids = NULL;
+ *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
+ /* 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.
@@ -360,9 +870,9 @@ secmod_ParseModuleSpecForTokens(PRBool convert, PRBool isFIPS,
* 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
+ * 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).
*/
/*
@@ -370,139 +880,152 @@ secmod_ParseModuleSpecForTokens(PRBool convert, PRBool isFIPS,
* 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);
+ 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;
+ PORT_Free(tmp);
+ tmp = NULL;
}
*newSpecPtr = 0;
/* no target found, return the newSpec */
if (target == NULL) {
- return newSpec;
+ 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++;
+ tokenIndex = NSSUTIL_ArgStrip(NSSUTIL_ArgSkipParameter(tokenIndex))) {
+ tokenCount++;
}
- childArray = PORT_NewArray(char *, tokenCount+1);
+ childArray = PORT_NewArray(char *, tokenCount + 1);
if (childArray == NULL) {
- /* just return the spec as is then */
- PORT_Free(target);
- return newSpec;
+ /* 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;
- }
+ 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);
- }
+ 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 */
+ 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;
- }
+ /* 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;
+ idArray[i] = 0;
}
/* return it */
*children = childArray;
if (ids) {
- *ids = idArray;
+ *ids = idArray;
}
return newSpec;
}
/* get the database and flags from the spec */
static char *
-secmod_getConfigDir(char *spec, char **certPrefix, char **keyPrefix,
- PRBool *readOnly)
+secmod_getConfigDir(const char *spec, char **certPrefix, char **keyPrefix,
+ PRBool *readOnly)
{
- char * config = NULL;
+ char *config = NULL;
*certPrefix = NULL;
*keyPrefix = NULL;
- *readOnly = NSSUTIL_ArgHasFlag("flags","readOnly",spec);
+ *readOnly = NSSUTIL_ArgHasFlag("flags", "readOnly", spec);
+ if (NSSUTIL_ArgHasFlag("flags", "nocertdb", spec) ||
+ NSSUTIL_ArgHasFlag("flags", "nokeydb", spec)) {
+ return NULL;
+ }
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)
+ 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;
}
@@ -527,29 +1050,30 @@ secmod_GetConfigList(PRBool isFIPS, char *spec, int *count)
SECMODConfigList *conflist = NULL;
int i;
- strippedSpec = secmod_ParseModuleSpecForTokens(PR_TRUE, isFIPS,
- spec,&children,&ids);
+ strippedSpec = secmod_ParseModuleSpecForTokens(PR_TRUE, isFIPS,
+ spec, &children, &ids);
if (strippedSpec == NULL) {
- return NULL;
+ return NULL;
}
- for (childCount=0; children && children[childCount]; childCount++) ;
- *count = childCount+1; /* include strippedSpec */
- conflist = PORT_NewArray(SECMODConfigList,*count);
+ for (childCount = 0; children && children[childCount]; childCount++)
+ ;
+ *count = childCount + 1; /* include strippedSpec */
+ conflist = PORT_NewArray(SECMODConfigList, *count);
if (conflist == NULL) {
- *count = 0;
- goto loser;
+ *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);
+ 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:
@@ -569,18 +1093,18 @@ secmod_configIsDBM(char *configDir)
/* explicit dbm open */
if (strncmp(configDir, "dbm:", 4) == 0) {
- return PR_TRUE;
+ 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;
+ 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");
+ env = PR_GetEnvSecure("NSS_DEFAULT_DB_TYPE");
/* implicit dbm open */
- if ((env == NULL) || (strcmp(env,"dbm") == 0)) {
- return PR_TRUE;
+ if ((env == NULL) || (strcmp(env, "dbm") == 0)) {
+ return PR_TRUE;
}
/* implicit non-dbm open */
return PR_FALSE;
@@ -593,55 +1117,88 @@ 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 ((prefix2 == NULL) || (*prefix2 == 0)) {
+ return PR_TRUE;
+ }
+ return PR_FALSE;
}
if (strcmp(prefix1, prefix2) == 0) {
- return PR_TRUE;
+ return PR_TRUE;
}
return PR_FALSE;
}
+/* do two config paramters match? Not all callers are compariing
+ * SECMODConfigLists directly, so this function breaks them out to their
+ * components. */
+static PRBool
+secmod_matchConfig(char *configDir1, char *configDir2,
+ char *certPrefix1, char *certPrefix2,
+ char *keyPrefix1, char *keyPrefix2,
+ PRBool isReadOnly1, PRBool isReadOnly2)
+{
+ /* TODO: Document the answer to the question:
+ * "Why not allow them to match if they are both NULL?"
+ * See: https://bugzilla.mozilla.org/show_bug.cgi?id=1318633#c1
+ */
+ if ((configDir1 == NULL) || (configDir2 == NULL)) {
+ return PR_FALSE;
+ }
+ if (strcmp(configDir1, configDir2) != 0) {
+ return PR_FALSE;
+ }
+ if (!secmod_matchPrefix(certPrefix1, certPrefix2)) {
+ return PR_FALSE;
+ }
+ if (!secmod_matchPrefix(keyPrefix1, keyPrefix2)) {
+ return PR_FALSE;
+ }
+ /* these 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 */
+ if (isReadOnly1) {
+ return PR_TRUE;
+ }
+ if (isReadOnly2) { /* isReadonly1 == PR_FALSE */
+ return PR_FALSE;
+ }
+ return PR_TRUE;
+}
+
/*
* return true if we are requesting a database that is already openned.
*/
PRBool
-secmod_MatchConfigList(char *spec, SECMODConfigList *conflist, int count)
+secmod_MatchConfigList(const char *spec, SECMODConfigList *conflist, int count)
{
char *config;
char *certPrefix;
char *keyPrefix;
PRBool isReadOnly;
- PRBool ret=PR_FALSE;
+ PRBool ret = PR_FALSE;
int i;
config = secmod_getConfigDir(spec, &certPrefix, &keyPrefix, &isReadOnly);
if (!config) {
- ret=PR_TRUE;
- goto done;
+ goto done;
}
- /* NOTE: we dbm isn't multiple open safe. If we open the same database
+ /* 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;
- }
+ isReadOnly = 1;
+ }
+ for (i = 0; i < count; i++) {
+ if (secmod_matchConfig(config, conflist[i].config, certPrefix,
+ conflist[i].certPrefix, keyPrefix,
+ conflist[i].keyPrefix, isReadOnly,
+ conflist[i].isReadOnly)) {
+ ret = PR_TRUE;
+ goto done;
+ }
}
ret = PR_FALSE;
@@ -652,14 +1209,93 @@ done:
return ret;
}
+/*
+ * Find the slot id from the module spec. If the slot is the database slot, we
+ * can get the slot id from the default database slot.
+ */
+CK_SLOT_ID
+secmod_GetSlotIDFromModuleSpec(const char *moduleSpec, SECMODModule *module)
+{
+ char *tmp_spec = NULL;
+ char **children, **thisChild;
+ CK_SLOT_ID *ids, *thisID, slotID = -1;
+ char *inConfig = NULL, *thisConfig = NULL;
+ char *inCertPrefix = NULL, *thisCertPrefix = NULL;
+ char *inKeyPrefix = NULL, *thisKeyPrefix = NULL;
+ PRBool inReadOnly, thisReadOnly;
+
+ inConfig = secmod_getConfigDir(moduleSpec, &inCertPrefix, &inKeyPrefix,
+ &inReadOnly);
+ if (!inConfig) {
+ goto done;
+ }
+
+ if (secmod_configIsDBM(inConfig)) {
+ inReadOnly = 1;
+ }
+
+ tmp_spec = secmod_ParseModuleSpecForTokens(PR_TRUE, module->isFIPS,
+ module->libraryParams, &children, &ids);
+ if (tmp_spec == NULL) {
+ goto done;
+ }
+
+ /* first check to see if the parent is the database */
+ thisConfig = secmod_getConfigDir(tmp_spec, &thisCertPrefix, &thisKeyPrefix,
+ &thisReadOnly);
+ if (!thisConfig) {
+ goto done;
+ }
+ if (secmod_matchConfig(inConfig, thisConfig, inCertPrefix, thisCertPrefix,
+ inKeyPrefix, thisKeyPrefix, inReadOnly, thisReadOnly)) {
+ /* yup it's the default key slot, get the id for it */
+ PK11SlotInfo *slot = PK11_GetInternalKeySlot();
+ if (slot) {
+ slotID = slot->slotID;
+ PK11_FreeSlot(slot);
+ }
+ goto done;
+ }
+
+ /* find id of the token */
+ for (thisChild = children, thisID = ids; thisChild && *thisChild; thisChild++, thisID++) {
+ PORT_Free(thisConfig);
+ PORT_Free(thisCertPrefix);
+ PORT_Free(thisKeyPrefix);
+ thisConfig = secmod_getConfigDir(*thisChild, &thisCertPrefix,
+ &thisKeyPrefix, &thisReadOnly);
+ if (thisConfig == NULL) {
+ continue;
+ }
+ if (secmod_matchConfig(inConfig, thisConfig, inCertPrefix, thisCertPrefix,
+ inKeyPrefix, thisKeyPrefix, inReadOnly, thisReadOnly)) {
+ slotID = *thisID;
+ break;
+ }
+ }
+
+done:
+ PORT_Free(inConfig);
+ PORT_Free(inCertPrefix);
+ PORT_Free(inKeyPrefix);
+ PORT_Free(thisConfig);
+ PORT_Free(thisCertPrefix);
+ PORT_Free(thisKeyPrefix);
+ if (tmp_spec) {
+ secmod_FreeChildren(children, ids);
+ PORT_Free(tmp_spec);
+ }
+ return slotID;
+}
+
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);
+ for (i = 0; i < count; i++) {
+ PORT_Free(conflist[i].config);
+ PORT_Free(conflist[i].certPrefix);
+ PORT_Free(conflist[i].keyPrefix);
}
PORT_Free(conflist);
}
@@ -670,15 +1306,15 @@ secmod_FreeChildren(char **children, CK_SLOT_ID *ids)
char **thisChild;
if (!children) {
- return;
+ return;
}
- for (thisChild = children; thisChild && *thisChild; thisChild++ ) {
- PORT_Free(*thisChild);
+ for (thisChild = children; thisChild && *thisChild; thisChild++) {
+ PORT_Free(*thisChild);
}
PORT_Free(children);
if (ids) {
- PORT_Free(ids);
+ PORT_Free(ids);
}
return;
}
@@ -692,11 +1328,11 @@ secmod_getChildLength(char *child, CK_SLOT_ID id)
{
int length = NSSUTIL_DoubleEscapeSize(child, '>', ']');
if (id == 0) {
- length++;
+ length++;
}
while (id) {
- length++;
- id = id >> 4;
+ length++;
+ id = id >> 4;
}
length += 6; /* {sp}0x[id]=<{child}> */
return length;
@@ -712,26 +1348,26 @@ secmod_mkTokenChild(char **next, int *length, char *child, CK_SLOT_ID id)
int len;
char *escSpec;
- len = PR_snprintf(*next, *length, " 0x%x=<",id);
+ len = PR_snprintf(*next, *length, " 0x%x=<", id);
if (len < 0) {
- return SECFailure;
+ return SECFailure;
}
*next += len;
*length -= len;
escSpec = NSSUTIL_DoubleEscape(child, '>', ']');
if (escSpec == NULL) {
- return SECFailure;
+ return SECFailure;
}
if (*child && (*escSpec == 0)) {
- PORT_Free(escSpec);
- return SECFailure;
+ PORT_Free(escSpec);
+ return SECFailure;
}
len = strlen(escSpec);
- if (len+1 > *length) {
- PORT_Free(escSpec);
- return SECFailure;
+ if (len + 1 > *length) {
+ PORT_Free(escSpec);
+ return SECFailure;
}
- PORT_Memcpy(*next,escSpec, len);
+ PORT_Memcpy(*next, escSpec, len);
*next += len;
*length -= len;
PORT_Free(escSpec);
@@ -745,23 +1381,23 @@ secmod_mkTokenChild(char **next, int *length, char *child, CK_SLOT_ID id)
char *
secmod_MkAppendTokensList(PLArenaPool *arena, char *oldParam, char *newToken,
- CK_SLOT_ID newID, char **children, CK_SLOT_ID *ids)
+ 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 *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 */
+ 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);
+ rawParam = secmod_ParseModuleSpecForTokens(PR_FALSE, PR_FALSE,
+ oldParam, &oldChildren, &oldIds);
if (!rawParam) {
- goto loser;
+ goto loser;
}
/* now calculate the total length of the new buffer */
@@ -769,63 +1405,63 @@ secmod_MkAppendTokensList(PLArenaPool *arena, char *oldParam, char *newToken,
* 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]);
+ 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]);
+ 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;
+ goto loser;
}
- newParam = PORT_ArenaAlloc(arena,length);
+ newParam = PORT_ArenaAlloc(arena, length);
if (!newParam) {
- goto loser;
+ 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;
- }
+ 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;
+ 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;
- }
+ 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;
+ goto loser;
}
*nextParam++ = ']';
@@ -837,21 +1473,21 @@ secmod_MkAppendTokensList(PLArenaPool *arena, char *oldParam, char *newToken,
loser:
if (mark) {
- PORT_ArenaRelease(arena, mark);
- newParam = NULL; /* if the mark is still active,
- * don't return the param */
+ PORT_ArenaRelease(arena, mark);
+ newParam = NULL; /* if the mark is still active,
+ * don't return the param */
}
if (rawParam) {
- PORT_Free(rawParam);
+ PORT_Free(rawParam);
}
if (oldChildren) {
- secmod_FreeChildren(oldChildren, oldIds);
+ secmod_FreeChildren(oldChildren, oldIds);
}
return newParam;
}
-
+
static char *
-secmod_mkModuleSpec(SECMODModule * module)
+secmod_mkModuleSpec(SECMODModule *module)
{
char *nss = NULL, *modSpec = NULL, **slotStrings = NULL;
int slotCount, i, si;
@@ -862,71 +1498,70 @@ secmod_mkModuleSpec(SECMODModule * module)
SECMOD_GetReadLock(moduleLock);
if (module->slotCount) {
- for (i=0; i < module->slotCount; i++) {
- if (module->slots[i]->defaultFlags !=0) {
- slotCount++;
- }
- }
+ for (i = 0; i < module->slotCount; i++) {
+ if (module->slots[i]->defaultFlags != 0) {
+ slotCount++;
+ }
+ }
} else {
- slotCount = module->slotInfoCount;
+ slotCount = module->slotInfoCount;
}
- slotStrings = (char **)PORT_ZAlloc(slotCount*sizeof(char *));
+ slotStrings = (char **)PORT_ZAlloc(slotCount * sizeof(char *));
if (slotStrings == NULL) {
SECMOD_ReleaseReadLock(moduleLock);
- goto loser;
+ 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);
- }
+ 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);
+ 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;
+ SECMODModuleDBFunc func = (SECMODModuleDBFunc)module->moduleDBFunc;
if (func) {
- return (*func)(SECMOD_MODULE_DB_FUNCTION_FIND,
- module->libraryParams,NULL);
+ return (*func)(SECMOD_MODULE_DB_FUNCTION_FIND,
+ module->libraryParams, NULL);
}
return NULL;
}
@@ -938,15 +1573,17 @@ SECMOD_AddPermDB(SECMODModule *module)
char *moduleSpec;
char **retString;
- if (module->parent == NULL) return SECFailure;
+ if (module->parent == NULL)
+ return SECFailure;
- func = (SECMODModuleDBFunc) module->parent->moduleDBFunc;
+ 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;
+ 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;
}
@@ -958,15 +1595,17 @@ SECMOD_DeletePermDB(SECMODModule *module)
char *moduleSpec;
char **retString;
- if (module->parent == NULL) return SECFailure;
+ if (module->parent == NULL)
+ return SECFailure;
- func = (SECMODModuleDBFunc) module->parent->moduleDBFunc;
+ 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;
+ 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;
}
@@ -974,12 +1613,13 @@ SECMOD_DeletePermDB(SECMODModule *module)
SECStatus
SECMOD_FreeModuleSpecList(SECMODModule *module, char **moduleSpecList)
{
- SECMODModuleDBFunc func = (SECMODModuleDBFunc) module->moduleDBFunc;
+ SECMODModuleDBFunc func = (SECMODModuleDBFunc)module->moduleDBFunc;
char **retString;
if (func) {
- retString = (*func)(SECMOD_MODULE_DB_FUNCTION_RELEASE,
- module->libraryParams,moduleSpecList);
- if (retString != NULL) return SECSuccess;
+ retString = (*func)(SECMOD_MODULE_DB_FUNCTION_RELEASE,
+ module->libraryParams, moduleSpecList);
+ if (retString != NULL)
+ return SECSuccess;
}
return SECFailure;
}
@@ -988,9 +1628,9 @@ SECMOD_FreeModuleSpecList(SECMODModule *module, char **moduleSpecList)
* 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)
+SECMOD_LoadModule(char *modulespec, SECMODModule *parent, PRBool recurse)
{
- char *library = NULL, *moduleName = NULL, *parameters = NULL, *nss= NULL;
+ char *library = NULL, *moduleName = NULL, *parameters = NULL, *nss = NULL;
char *config = NULL;
SECStatus status;
SECMODModule *module = NULL;
@@ -1000,107 +1640,112 @@ SECMOD_LoadModule(char *modulespec,SECMODModule *parent, PRBool recurse)
/* initialize the underlying module structures */
SECMOD_Init();
- status = NSSUTIL_ArgParseModuleSpecEx(modulespec, &library, &moduleName,
- &parameters, &nss,
- &config);
+ status = NSSUTIL_ArgParseModuleSpecEx(modulespec, &library, &moduleName,
+ &parameters, &nss,
+ &config);
if (status != SECSuccess) {
- goto loser;
+ goto loser;
}
module = SECMOD_CreateModuleEx(library, moduleName, parameters, nss, config);
- if (library) PORT_Free(library);
- if (moduleName) PORT_Free(moduleName);
- if (parameters) PORT_Free(parameters);
- if (nss) PORT_Free(nss);
- if (config) PORT_Free(config);
+ if (library)
+ PORT_Free(library);
+ if (moduleName)
+ PORT_Free(moduleName);
+ if (parameters)
+ PORT_Free(parameters);
+ if (nss)
+ PORT_Free(nss);
+ if (config)
+ PORT_Free(config);
if (!module) {
- goto loser;
+ goto loser;
}
if (parent) {
- module->parent = SECMOD_ReferenceModule(parent);
- if (module->internal && secmod_IsInternalKeySlot(parent)) {
- module->internal = parent->internal;
- }
+ 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;
+ 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;
+ /* 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;
- }
+ 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;
+ goto loser;
}
-
/* inherit the reference */
if (!module->moduleDBOnly) {
- SECMOD_AddModuleToList(module);
+ SECMOD_AddModuleToList(module);
} else {
- SECMOD_AddModuleToDBOnlyList(module);
+ SECMOD_AddModuleToDBOnlyList(module);
}
-
+
/* handle any additional work here */
return module;
loser:
if (module) {
- if (module->loaded) {
- SECMOD_UnloadModule(module);
- }
- SECMOD_AddModuleToUnloadList(module);
+ if (module->loaded) {
+ SECMOD_UnloadModule(module);
+ }
+ SECMOD_AddModuleToUnloadList(module);
}
return module;
}
@@ -1109,16 +1754,16 @@ loser:
* load a PKCS#11 module and add it to the default NSS trust domain
*/
SECMODModule *
-SECMOD_LoadUserModule(char *modulespec,SECMODModule *parent, PRBool recurse)
+SECMOD_LoadUserModule(char *modulespec, SECMODModule *parent, PRBool recurse)
{
SECStatus rv = SECSuccess;
- SECMODModule * newmod = SECMOD_LoadModule(modulespec, parent, recurse);
+ SECMODModule *newmod = SECMOD_LoadModule(modulespec, parent, recurse);
SECMODListLock *moduleLock = SECMOD_GetDefaultModuleListLock();
if (newmod) {
- SECMOD_GetReadLock(moduleLock);
+ SECMOD_GetReadLock(moduleLock);
rv = STAN_AddModuleToDefaultTrustDomain(newmod);
- SECMOD_ReleaseReadLock(moduleLock);
+ SECMOD_ReleaseReadLock(moduleLock);
if (SECSuccess != rv) {
SECMOD_DestroyModule(newmod);
return NULL;
@@ -1131,7 +1776,8 @@ SECMOD_LoadUserModule(char *modulespec,SECMODModule *parent, PRBool recurse)
* 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
+SECMOD_UnloadUserModule(SECMODModule *mod)
{
SECStatus rv = SECSuccess;
int atype = 0;
@@ -1148,4 +1794,3 @@ SECStatus SECMOD_UnloadUserModule(SECMODModule *mod)
}
return SECMOD_DeleteModuleEx(NULL, mod, &atype, PR_FALSE);
}
-
diff --git a/nss/lib/pk11wrap/pk11pbe.c b/nss/lib/pk11wrap/pk11pbe.c
index cc72faf..7837bfe 100644
--- a/nss/lib/pk11wrap/pk11pbe.c
+++ b/nss/lib/pk11wrap/pk11pbe.c
@@ -26,80 +26,78 @@
typedef struct SEC_PKCS5PBEParameterStr SEC_PKCS5PBEParameter;
struct SEC_PKCS5PBEParameterStr {
- PLArenaPool *poolp;
- SECItem salt; /* octet string */
- SECItem iteration; /* integer */
- SECItem keyLength; /* PKCS5v2 only */
- SECAlgorithmID *pPrfAlgId; /* PKCS5v2 only */
- SECAlgorithmID prfAlgId; /* PKCS5v2 only */
+ PLArenaPool *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
+/* 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 {
- PLArenaPool *poolp;
- SECAlgorithmID pbeAlgId; /* real pbe algorithms */
+ PLArenaPool *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 }
-};
+ {
+ { 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_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
+ {
+ { 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_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 }
-};
-
+ {
+ { 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
@@ -108,32 +106,31 @@ const SEC_ASN1Template SEC_PKCS5V2ParameterTemplate[] =
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;
+ 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;
@@ -151,27 +148,27 @@ sec_pkcs5_v2_get_v2_param(PLArenaPool *arena, SECAlgorithmID *algid)
SECStatus rv;
if (arena == NULL) {
- localArena = arena = PORT_NewArena(SEC_ASN1_DEFAULT_ARENA_SIZE);
- if (arena == NULL) {
- return 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;
+ goto loser;
}
-
+
rv = SEC_ASN1DecodeItem(arena, pbeV2_param,
- SEC_PKCS5V2ParameterTemplate, &algid->parameters);
+ SEC_PKCS5V2ParameterTemplate, &algid->parameters);
if (rv == SECFailure) {
- goto loser;
+ goto loser;
}
pbeV2_param->poolp = arena;
return pbeV2_param;
loser:
if (localArena) {
- PORT_FreeArena(arena, PR_FALSE);
+ PORT_FreeArena(arena, PR_FALSE);
}
return NULL;
}
@@ -179,50 +176,49 @@ loser:
void
sec_pkcs5_v2_destroy_v2_param(sec_pkcs5V2Parameter *param)
{
- if (param && param->poolp) {
- PORT_FreeArena(param->poolp, PR_TRUE);
- }
+ if (param && param->poolp) {
+ PORT_FreeArena(param->poolp, PR_TRUE);
+ }
}
-
/* maps crypto algorithm from PBE algorithm.
*/
-SECOidTag
+SECOidTag
SEC_PKCS5GetCryptoAlgorithm(SECAlgorithmID *algid)
{
SECOidTag pbeAlg;
SECOidTag cipherAlg;
- if(algid == NULL)
- return SEC_OID_UNKNOWN;
+ 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;
+ 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);
- }
+ 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
+ */
+PRBool
SEC_PKCS5IsAlgorithmPBEAlg(SECAlgorithmID *algid)
{
return (PRBool)(SEC_PKCS5GetCryptoAlgorithm(algid) != SEC_OID_UNKNOWN);
}
-PRBool
+PRBool
SEC_PKCS5IsAlgorithmPBEAlgTag(SECOidTag algtag)
{
return (PRBool)(sec_pkcs5GetCryptoFromAlgTag(algtag) != SEC_OID_UNKNOWN);
@@ -237,70 +233,69 @@ 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;
+ /* use the MAC tag */
+ return SEC_OID_PKCS5_PBMAC1;
}
if (HASH_GetHashTypeByOidTag(algTag) != HASH_AlgNULL) {
- /* eliminate Hash algorithms */
- return SEC_OID_UNKNOWN;
+ /* 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;
+ /* 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
+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);
+ 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;
@@ -321,18 +316,18 @@ sec_pkcs5v2_key_length(SECAlgorithmID *algid)
algorithm = SECOID_GetAlgorithmTag(algid);
/* sanity check, they should all be PBKDF2 here */
if (algorithm != SEC_OID_PKCS5_PBKDF2) {
- return -1;
+ return -1;
}
arena = PORT_NewArena(SEC_ASN1_DEFAULT_ARENA_SIZE);
if (arena == NULL) {
- goto loser;
+ goto loser;
}
PORT_Memset(&p5_param, 0, sizeof(p5_param));
- rv = SEC_ASN1DecodeItem(arena,&p5_param,
- SEC_PKCS5V2PBEParameterTemplate, &algid->parameters);
+ rv = SEC_ASN1DecodeItem(arena, &p5_param,
+ SEC_PKCS5V2PBEParameterTemplate, &algid->parameters);
if (rv != SECSuccess) {
- goto loser;
+ goto loser;
}
if (p5_param.keyLength.data != NULL) {
@@ -341,7 +336,7 @@ sec_pkcs5v2_key_length(SECAlgorithmID *algid)
loser:
if (arena) {
- PORT_FreeArena(arena, PR_FALSE);
+ PORT_FreeArena(arena, PR_FALSE);
}
return length;
}
@@ -349,76 +344,72 @@ loser:
/*
* get the key length in bytes needed for the PBE algorithm
*/
-int
+int
SEC_PKCS5GetKeyLength(SECAlgorithmID *algid)
{
SECOidTag algorithm;
- if(algid == NULL)
- return SEC_OID_UNKNOWN;
+ 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;
+ 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;
+ 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;
@@ -427,28 +418,27 @@ sec_pkcs5_is_algorithm_v2_pkcs12_algorithm(SECOidTag algorithm)
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;
+ 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
+/* destroy a pbe parameter. it assumes that the parameter was
* generated using the appropriate create function and therefor
* contains an arena pool.
*/
-static void
+static void
sec_pkcs5_destroy_pbe_param(SEC_PKCS5PBEParameter *pbe_param)
{
- if(pbe_param != NULL)
- PORT_FreeArena(pbe_param->poolp, PR_TRUE);
+ if (pbe_param != NULL)
+ PORT_FreeArena(pbe_param->poolp, PR_TRUE);
}
/* creates a PBE parameter based on the PBE algorithm. the only required
@@ -460,84 +450,84 @@ sec_pkcs5_destroy_pbe_param(SEC_PKCS5PBEParameter *pbe_param)
* 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
+ * 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)
+sec_pkcs5_create_pbe_parameter(SECOidTag algorithm,
+ SECItem *salt,
+ int iteration,
+ int keyLength,
+ SECOidTag prfAlg)
{
PLArenaPool *poolp = NULL;
SEC_PKCS5PBEParameter *pbe_param = NULL;
- SECStatus rv= SECSuccess;
+ SECStatus rv = SECSuccess;
void *dummy = NULL;
- if(iteration < 0) {
- return NULL;
+ if (iteration < 0) {
+ return NULL;
}
poolp = PORT_NewArena(SEC_ASN1_DEFAULT_ARENA_SIZE);
- if(poolp == NULL)
- return NULL;
+ 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;
+ 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);
+ 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);
- }
+ /* 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;
+ if (rv != SECSuccess) {
+ PORT_FreeArena(poolp, PR_TRUE);
+ return NULL;
}
/* encode the integer */
- dummy = SEC_ASN1EncodeInteger(poolp, &pbe_param->iteration,
- iteration);
+ dummy = SEC_ASN1EncodeInteger(poolp, &pbe_param->iteration,
+ iteration);
rv = (dummy) ? SECSuccess : SECFailure;
- if(rv != SECSuccess) {
- PORT_FreeArena(poolp, PR_FALSE);
- return NULL;
+ 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;
+ 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;
@@ -545,19 +535,19 @@ sec_pkcs5_create_pbe_parameter(SECOidTag algorithm,
/* 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.
+ * not specified, it is generated randomly.
*
- * the returned SECAlgorithmID should be destroyed using
+ * 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)
+sec_pkcs5CreateAlgorithmID(SECOidTag algorithm,
+ SECOidTag cipherAlgorithm,
+ SECOidTag prfAlg,
+ SECOidTag *pPbeAlgorithm,
+ int keyLength,
+ SECItem *salt,
+ int iteration)
{
PLArenaPool *poolp = NULL;
SECAlgorithmID *algid, *ret_algid = NULL;
@@ -568,174 +558,173 @@ sec_pkcs5CreateAlgorithmID(SECOidTag algorithm,
SEC_PKCS5PBEParameter *pbe_param = NULL;
sec_pkcs5V2Parameter pbeV2_param;
- if(iteration <= 0) {
- return NULL;
+ if (iteration <= 0) {
+ return NULL;
}
poolp = PORT_NewArena(SEC_ASN1_DEFAULT_ARENA_SIZE);
- if(!poolp) {
- goto loser;
+ 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;
- }
- }
-
+ 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 SEC_OID_HMAC_SHA1 is the default */
+ 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;
+ keyLength, prfAlg);
+ if (!pbe_param) {
+ goto loser;
}
/* generate the algorithm id */
algid = (SECAlgorithmID *)PORT_ArenaZAlloc(poolp, sizeof(SECAlgorithmID));
- if(algid == NULL) {
- goto loser;
+ 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);
+ /* 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);
+ dummy = SEC_ASN1EncodeItem(poolp, &der_param, pbe_param,
+ SEC_V2PKCS12PBEParameterTemplate);
}
if (dummy == NULL) {
- goto loser;
+ goto loser;
}
rv = SECOID_SetAlgorithmID(poolp, algid, algorithm, &der_param);
if (rv != SECSuccess) {
- goto loser;
+ goto loser;
}
ret_algid = (SECAlgorithmID *)PORT_ZAlloc(sizeof(SECAlgorithmID));
if (ret_algid == NULL) {
- goto loser;
+ goto loser;
}
rv = SECOID_CopyAlgorithmID(NULL, ret_algid, algid);
if (rv != SECSuccess) {
- SECOID_DestroyAlgorithmID(ret_algid, PR_TRUE);
- ret_algid = NULL;
+ SECOID_DestroyAlgorithmID(ret_algid, PR_TRUE);
+ ret_algid = NULL;
} else if (pPbeAlgorithm) {
- *pPbeAlgorithm = pbeAlgorithm;
+ *pPbeAlgorithm = pbeAlgorithm;
}
loser:
if (poolp != NULL) {
- PORT_FreeArena(poolp, PR_TRUE);
- algid = NULL;
+ PORT_FreeArena(poolp, PR_TRUE);
+ algid = NULL;
}
if (pbe_param) {
- sec_pkcs5_destroy_pbe_param(pbe_param);
+ sec_pkcs5_destroy_pbe_param(pbe_param);
}
return ret_algid;
}
SECStatus
-pbe_PK11AlgidToParam(SECAlgorithmID *algid,SECItem *mech)
+pbe_PK11AlgidToParam(SECAlgorithmID *algid, SECItem *mech)
{
SEC_PKCS5PBEParameter p5_param;
SECItem *salt = NULL;
@@ -747,14 +736,12 @@ pbe_PK11AlgidToParam(SECAlgorithmID *algid,SECItem *mech)
CK_ULONG iterations;
int paramLen = 0;
int iv_len;
-
arena = PORT_NewArena(SEC_ASN1_DEFAULT_ARENA_SIZE);
if (arena == NULL) {
- goto loser;
+ goto loser;
}
-
/*
* decode the algid based on the pbe type
*/
@@ -762,131 +749,145 @@ pbe_PK11AlgidToParam(SECAlgorithmID *algid,SECItem *mech)
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);
+ SEC_V2PKCS12PBEParameterTemplate, &algid->parameters);
} else if (algorithm == SEC_OID_PKCS5_PBKDF2) {
- iv_len = 0;
- rv = SEC_ASN1DecodeItem(arena,&p5_param,
- SEC_PKCS5V2PBEParameterTemplate, &algid->parameters);
+ 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);
+ rv = SEC_ASN1DecodeItem(arena, &p5_param, SEC_PKCS5PBEParameterTemplate,
+ &algid->parameters);
}
if (iv_len < 0) {
- goto loser;
+ goto loser;
}
if (rv != SECSuccess) {
- goto loser;
+ goto loser;
}
-
+
/* get salt */
salt = &p5_param.salt;
- iterations = (CK_ULONG) DER_GetInteger(&p5_param.iteration);
+ 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);
+ 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);
+ }
+ switch (prfAlgTag) {
+ case SEC_OID_HMAC_SHA1:
+ pbeV2_params->prf = CKP_PKCS5_PBKD2_HMAC_SHA1;
+ break;
+ case SEC_OID_HMAC_SHA224:
+ pbeV2_params->prf = CKP_PKCS5_PBKD2_HMAC_SHA224;
+ break;
+ case SEC_OID_HMAC_SHA256:
+ pbeV2_params->prf = CKP_PKCS5_PBKD2_HMAC_SHA256;
+ break;
+ case SEC_OID_HMAC_SHA384:
+ pbeV2_params->prf = CKP_PKCS5_PBKD2_HMAC_SHA384;
+ break;
+ case SEC_OID_HMAC_SHA512:
+ pbeV2_params->prf = CKP_PKCS5_PBKD2_HMAC_SHA512;
+ break;
+ default:
+ 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;
+ 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;
+ 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;
+ 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);
+ PORT_FreeArena(arena, PR_TRUE);
}
return SECSuccess;
loser:
if (paramData) {
- PORT_Free(paramData);
+ PORT_Free(paramData);
}
if (arena) {
- PORT_FreeArena(arena,PR_TRUE);
+ PORT_FreeArena(arena, PR_TRUE);
}
return SECFailure;
}
/*
- * public, deprecated, not valid for pkcs5 v2
- *
+ * 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, PLArenaPool *arena,
- SECAlgorithmID *algId)
+ SECAlgorithmID *algId)
{
CK_PBE_PARAMS *pbe_param;
SECItem pbeSalt;
SECAlgorithmID *pbeAlgID = NULL;
SECStatus rv;
- if(!param || !algId) {
- return SECFailure;
+ 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;
+ 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);
@@ -895,7 +896,7 @@ PBE_PK11ParamToAlgid(SECOidTag algTag, SECItem *param, PLArenaPool *arena,
}
/*
- * public, Deprecated, This function is only for binary compatibility with
+ * 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
@@ -903,8 +904,8 @@ PBE_PK11ParamToAlgid(SECOidTag algTag, SECItem *param, PLArenaPool *arena,
*/
PBEBitGenContext *
PBE_CreateContext(SECOidTag hashAlgorithm, PBEBitGenID bitGenPurpose,
- SECItem *pwitem, SECItem *salt, unsigned int bitsNeeded,
- unsigned int iterations)
+ SECItem *pwitem, SECItem *salt, unsigned int bitsNeeded,
+ unsigned int iterations)
{
SECItem *context = NULL;
SECItem mechItem;
@@ -913,57 +914,56 @@ PBE_CreateContext(SECOidTag hashAlgorithm, PBEBitGenID bitGenPurpose,
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;
+ 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;
- }
+ /* 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;
@@ -971,42 +971,41 @@ PBE_CreateContext(SECOidTag hashAlgorithm, PBEBitGenID bitGenPurpose,
pbe_params.pSalt = salt->data;
pbe_params.ulSaltLen = salt->len;
pbe_params.ulIteration = iterations;
- mechItem.data = (unsigned char *) &pbe_params;
+ mechItem.data = (unsigned char *)&pbe_params;
mechItem.len = sizeof(pbe_params);
-
slot = PK11_GetInternalSlot();
- symKey = PK11_RawPBEKeyGen(slot,mechanism,
- &mechItem, pwitem, PR_FALSE, NULL);
+ 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);
+ 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
+ * 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.
*/
@@ -1017,16 +1016,16 @@ PBE_GenerateBits(PBEBitGenContext *context)
}
/*
- * public, Deprecated, This function is only for binary compatibility with
+ * 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);
+ SECITEM_FreeItem((SECItem *)context, PR_TRUE);
}
/*
@@ -1044,48 +1043,48 @@ SEC_PKCS5GetIV(SECAlgorithmID *algid, SECItem *pwitem, PRBool faulty3DES)
PK11SymKey *symKey;
PK11SlotInfo *slot;
CK_PBE_PARAMS_PTR pPBEparams;
- SECOidTag pbeAlg;
+ 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;
+ 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;
+ goto done;
}
slot = PK11_GetInternalSlot();
symKey = PK11_RawPBEKeyGen(slot, type, param, pwitem, faulty3DES, NULL);
PK11_FreeSlot(slot);
if (symKey == NULL) {
- goto loser;
+ goto loser;
}
PK11_FreeSymKey(symKey);
pPBEparams = (CK_PBE_PARAMS_PTR)param->data;
@@ -1099,7 +1098,7 @@ done:
loser:
if (param) {
- SECITEM_ZfreeItem(param, PR_TRUE);
+ SECITEM_ZfreeItem(param, PR_TRUE);
}
return iv;
}
@@ -1109,8 +1108,8 @@ loser:
*/
PBEBitGenContext *
__PBE_CreateContext(SECOidTag hashAlgorithm, PBEBitGenID bitGenPurpose,
- SECItem *pwitem, SECItem *salt, unsigned int bitsNeeded,
- unsigned int iterations)
+ SECItem *pwitem, SECItem *salt, unsigned int bitsNeeded,
+ unsigned int iterations)
{
PORT_Assert("__PBE_CreateContext is Deprecated" == NULL);
return NULL;
@@ -1147,29 +1146,29 @@ 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));
+ 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
+ * 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 *
+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;
+ if (!paramRV) {
+ goto loser;
}
/* init paramRV->data with zeros. SECITEM_AllocItem does not do it */
PORT_Memset(paramRV->data, 0, sizeof(CK_PBE_PARAMS));
@@ -1184,7 +1183,7 @@ PK11_CreatePBEParams(SECItem *salt, SECItem *pwd, unsigned int iterations)
pbe_params->pSalt = (CK_CHAR_PTR)PORT_ZAlloc(salt->len);
if (!pbe_params->pSalt) {
- goto loser;
+ goto loser;
}
PORT_Memcpy(pbe_params->pSalt, salt->data, salt->len);
pbe_params->ulSaltLen = salt->len;
@@ -1195,8 +1194,8 @@ PK11_CreatePBEParams(SECItem *salt, SECItem *pwd, unsigned int iterations)
loser:
if (pbe_params)
pk11_destroy_ck_pbe_params(pbe_params);
- if (paramRV)
- PORT_ZFree(paramRV, sizeof(SECItem));
+ if (paramRV)
+ PORT_ZFree(paramRV, sizeof(SECItem));
return NULL;
}
@@ -1207,10 +1206,10 @@ 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));
+ CK_PBE_PARAMS *params = (CK_PBE_PARAMS *)(pItem->data);
+ if (params)
+ pk11_destroy_ck_pbe_params(params);
+ PORT_ZFree(pItem, sizeof(SECItem));
}
}
@@ -1224,7 +1223,8 @@ 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);
+ SEC_OID_UNKNOWN, SEC_OID_UNKNOWN, NULL,
+ 0, salt, iteration);
return algid;
}
@@ -1233,12 +1233,12 @@ PK11_CreatePBEAlgorithmID(SECOidTag algorithm, int iteration, SECItem *salt)
*/
SECAlgorithmID *
PK11_CreatePBEV2AlgorithmID(SECOidTag pbeAlgTag, SECOidTag cipherAlgTag,
- SECOidTag prfAlgTag, int keyLength, int iteration,
- SECItem *salt)
+ SECOidTag prfAlgTag, int keyLength, int iteration,
+ SECItem *salt)
{
SECAlgorithmID *algid = NULL;
algid = sec_pkcs5CreateAlgorithmID(pbeAlgTag, cipherAlgTag, prfAlgTag,
- NULL, keyLength, salt, iteration);
+ NULL, keyLength, salt, iteration);
return algid;
}
@@ -1246,48 +1246,49 @@ PK11_CreatePBEV2AlgorithmID(SECOidTag pbeAlgTag, SECOidTag cipherAlgTag,
* private.
*/
PK11SymKey *
-pk11_RawPBEKeyGenWithKeyType(PK11SlotInfo *slot, CK_MECHANISM_TYPE type,
- SECItem *params, CK_KEY_TYPE keyType, int keyLen,
- SECItem *pwitem, void *wincx)
+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;
+ PORT_SetError(SEC_ERROR_INVALID_ARGS);
+ return NULL;
}
if (type == CKM_INVALID_MECHANISM) {
- PORT_SetError(SEC_ERROR_INVALID_ALGORITHM);
- return NULL;
+ 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;
+ 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;
+ 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);
+ return pk11_TokenKeyGenWithFlagsAndKeyType(slot, type, params, keyType,
+ keyLen, NULL,
+ CKF_SIGN | CKF_ENCRYPT | CKF_DECRYPT | CKF_UNWRAP | CKF_WRAP,
+ 0, wincx);
}
/*
@@ -1295,10 +1296,10 @@ pk11_RawPBEKeyGenWithKeyType(PK11SlotInfo *slot, CK_MECHANISM_TYPE type,
*/
PK11SymKey *
PK11_RawPBEKeyGen(PK11SlotInfo *slot, CK_MECHANISM_TYPE type, SECItem *mech,
- SECItem *pwitem, PRBool faulty3DES, void *wincx)
+ SECItem *pwitem, PRBool faulty3DES, void *wincx)
{
- if(faulty3DES && (type == CKM_NETSCAPE_PBE_SHA1_TRIPLE_DES_CBC)) {
- type = CKM_NETSCAPE_PBE_SHA1_FAULTY_3DES_CBC;
+ 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);
}
@@ -1312,12 +1313,12 @@ PK11_RawPBEKeyGen(PK11SlotInfo *slot, CK_MECHANISM_TYPE type, SECItem *mech,
*/
PK11SymKey *
PK11_PBEKeyGen(PK11SlotInfo *slot, SECAlgorithmID *algid, SECItem *pwitem,
- PRBool faulty3DES, void *wincx)
+ PRBool faulty3DES, void *wincx)
{
CK_MECHANISM_TYPE type;
SECItem *param = NULL;
PK11SymKey *symKey = NULL;
- SECOidTag pbeAlg;
+ SECOidTag pbeAlg;
CK_KEY_TYPE keyType = -1;
int keyLen = 0;
@@ -1325,45 +1326,45 @@ PK11_PBEKeyGen(PK11SlotInfo *slot, SECAlgorithmID *algid, SECItem *pwitem,
/* 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);
+ 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);
+ param = PK11_ParamFromAlgid(algid);
}
- if(param == NULL) {
- goto loser;
+ if (param == NULL) {
+ goto loser;
}
- type = PK11_AlgtagToMechanism(pbeAlg);
+ type = PK11_AlgtagToMechanism(pbeAlg);
if (type == CKM_INVALID_MECHANISM) {
- PORT_SetError(SEC_ERROR_INVALID_ALGORITHM);
- goto loser;
+ 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;
+ 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);
+ symKey = pk11_RawPBEKeyGenWithKeyType(slot, type, param, keyType, keyLen,
+ pwitem, wincx);
loser:
if (param) {
- SECITEM_ZfreeItem(param, PR_TRUE);
+ SECITEM_ZfreeItem(param, PR_TRUE);
}
return symKey;
}
@@ -1378,8 +1379,8 @@ PK11_GetPBEIV(SECAlgorithmID *algid, SECItem *pwitem)
}
CK_MECHANISM_TYPE
-pk11_GetPBECryptoMechanism(SECAlgorithmID *algid, SECItem **param,
- SECItem *pbe_pwd, PRBool faulty3DES)
+pk11_GetPBECryptoMechanism(SECAlgorithmID *algid, SECItem **param,
+ SECItem *pbe_pwd, PRBool faulty3DES)
{
int keyLen = 0;
SECOidTag algTag = SEC_PKCS5GetCryptoAlgorithm(algid);
@@ -1388,27 +1389,27 @@ pk11_GetPBECryptoMechanism(SECAlgorithmID *algid, SECItem **param,
SECItem *iv = NULL;
if (mech == CKM_INVALID_MECHANISM) {
- PORT_SetError(SEC_ERROR_INVALID_ALGORITHM);
- goto loser;
+ PORT_SetError(SEC_ERROR_INVALID_ALGORITHM);
+ goto loser;
}
if (PK11_GetIVLength(mech)) {
- iv = SEC_PKCS5GetIV(algid, pbe_pwd, faulty3DES);
- if (iv == NULL) {
- goto loser;
- }
+ 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;
+ goto loser;
}
returnedMechanism = mech;
loser:
if (iv) {
- SECITEM_FreeItem(iv,PR_TRUE);
+ SECITEM_FreeItem(iv, PR_TRUE);
}
return returnedMechanism;
}
@@ -1425,8 +1426,8 @@ loser:
* The caller is responsible for freeing the parameter.
*/
CK_MECHANISM_TYPE
-PK11_GetPBECryptoMechanism(SECAlgorithmID *algid, SECItem **param,
- SECItem *pbe_pwd)
+PK11_GetPBECryptoMechanism(SECAlgorithmID *algid, SECItem **param,
+ SECItem *pbe_pwd)
{
return pk11_GetPBECryptoMechanism(algid, param, pbe_pwd, PR_FALSE);
}
diff --git a/nss/lib/pk11wrap/pk11pk12.c b/nss/lib/pk11wrap/pk11pk12.c
index e5a0a21..1683cc5 100644
--- a/nss/lib/pk11wrap/pk11pk12.c
+++ b/nss/lib/pk11wrap/pk11pk12.c
@@ -20,8 +20,6 @@
#include "secerr.h"
#include "prerror.h"
-
-
/* These data structures should move to a common .h file shared between the
* wrappers and the pkcs 12 code. */
@@ -31,7 +29,7 @@
/* member names from PKCS#1, section 7.2 */
struct SECKEYRSAPrivateKeyStr {
- PLArenaPool * arena;
+ PLArenaPool *arena;
SECItem version;
SECItem modulus;
SECItem publicExponent;
@@ -44,7 +42,6 @@ struct SECKEYRSAPrivateKeyStr {
};
typedef struct SECKEYRSAPrivateKeyStr SECKEYRSAPrivateKey;
-
/*
** DSA Raw Private Key structures
*/
@@ -60,7 +57,7 @@ typedef struct SECKEYDSAPrivateKeyStr SECKEYDSAPrivateKey;
** Structure member names suggested by PKCS#3.
*/
struct SECKEYDHPrivateKeyStr {
- PLArenaPool * arena;
+ PLArenaPool *arena;
SECItem prime;
SECItem base;
SECItem privateValue;
@@ -76,7 +73,7 @@ struct SECKEYRawPrivateKeyStr {
union {
SECKEYRSAPrivateKey rsa;
SECKEYDSAPrivateKey dsa;
- SECKEYDHPrivateKey dh;
+ SECKEYDHPrivateKey dh;
} u;
};
typedef struct SECKEYRawPrivateKeyStr SECKEYRawPrivateKey;
@@ -90,10 +87,10 @@ SEC_ASN1_MKSUB(SECOID_AlgorithmIDTemplate)
*/
const SEC_ASN1Template SECKEY_AttributeTemplate[] = {
{ SEC_ASN1_SEQUENCE,
- 0, NULL, sizeof(SECKEYAttribute) },
+ 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) },
+ SEC_ASN1_SUB(SEC_AnyTemplate) },
{ 0 }
};
@@ -103,14 +100,14 @@ const SEC_ASN1Template SECKEY_SetOfAttributeTemplate[] = {
const SEC_ASN1Template SECKEY_PrivateKeyInfoTemplate[] = {
{ SEC_ASN1_SEQUENCE, 0, NULL, sizeof(SECKEYPrivateKeyInfo) },
- { SEC_ASN1_INTEGER, offsetof(SECKEYPrivateKeyInfo,version) },
+ { 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) },
+ 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 },
+ offsetof(SECKEYPrivateKeyInfo, attributes),
+ SECKEY_SetOfAttributeTemplate },
{ 0 }
};
@@ -120,41 +117,41 @@ const SEC_ASN1Template SECKEY_PointerToPrivateKeyInfoTemplate[] = {
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) },
+ { 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) },
+ { 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) },
+ { 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) },
+ 0, NULL, sizeof(SECKEYEncryptedPrivateKeyInfo) },
{ SEC_ASN1_INLINE | SEC_ASN1_XTRN,
- offsetof(SECKEYEncryptedPrivateKeyInfo,algorithm),
- SEC_ASN1_SUB(SECOID_AlgorithmIDTemplate) },
+ offsetof(SECKEYEncryptedPrivateKeyInfo, algorithm),
+ SEC_ASN1_SUB(SECOID_AlgorithmIDTemplate) },
{ SEC_ASN1_OCTET_STRING,
- offsetof(SECKEYEncryptedPrivateKeyInfo,encryptedData) },
+ offsetof(SECKEYEncryptedPrivateKeyInfo, encryptedData) },
{ 0 }
};
const SEC_ASN1Template SECKEY_PointerToEncryptedPrivateKeyInfoTemplate[] = {
- { SEC_ASN1_POINTER, 0, SECKEY_EncryptedPrivateKeyInfoTemplate }
+ { SEC_ASN1_POINTER, 0, SECKEY_EncryptedPrivateKeyInfoTemplate }
};
SEC_ASN1_CHOOSER_IMPLEMENT(SECKEY_EncryptedPrivateKeyInfoTemplate)
@@ -201,21 +198,22 @@ prepare_dh_priv_key_export_for_asn1(SECKEYRawPrivateKey *key)
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)
+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);
+ 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)
+PK11_ImportDERPrivateKeyInfoAndReturnKey(PK11SlotInfo *slot, SECItem *derPKI,
+ SECItem *nickname, SECItem *publicValue,
+ PRBool isPerm, PRBool isPrivate, unsigned int keyUsage,
+ SECKEYPrivateKey **privk, void *wincx)
{
SECKEYPrivateKeyInfo *pki = NULL;
PLArenaPool *temparena = NULL;
@@ -232,29 +230,38 @@ PK11_ImportDERPrivateKeyInfoAndReturnKey(PK11SlotInfo *slot, SECItem *derPKI,
pki->arena = temparena;
rv = SEC_ASN1DecodeItem(pki->arena, pki, SECKEY_PrivateKeyInfoTemplate,
- derPKI);
- if( rv != SECSuccess ) {
+ derPKI);
+ if (rv != SECSuccess) {
/* If SEC_ASN1DecodeItem fails, we cannot assume anything about the
* validity of the data in pki. The best we can do is free the arena
- * and return.
- */
+ * and return. */
PORT_FreeArena(temparena, PR_TRUE);
return rv;
}
+ if (pki->privateKey.data == NULL) {
+ /* If SEC_ASN1DecodeItems succeeds but SECKEYPrivateKeyInfo.privateKey
+ * is a zero-length octet string, free the arena and return a failure
+ * to avoid trying to zero the corresponding SECItem in
+ * SECKEY_DestroyPrivateKeyInfo(). */
+ PORT_FreeArena(temparena, PR_TRUE);
+ PORT_SetError(SEC_ERROR_BAD_KEY);
+ return SECFailure;
+ }
rv = PK11_ImportPrivateKeyInfoAndReturnKey(slot, pki, nickname,
- publicValue, isPerm, isPrivate, keyUsage, privk, wincx);
+ publicValue, isPerm, isPrivate,
+ keyUsage, privk, wincx);
/* 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)
+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;
@@ -272,159 +279,195 @@ PK11_ImportAndReturnPrivateKey(PK11SlotInfo *slot, SECKEYRawPrivateKey *lpk,
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_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++;
+ 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;
+ 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(templateCount <= sizeof(theTemplate) / sizeof(CK_ATTRIBUTE));
PORT_Assert(signedattr != NULL);
signedcount = attrs - signedattr;
- for (ap=signedattr; signedcount; ap++, signedcount--) {
- pk11_SignedToUnsigned(ap);
+ for (ap = signedattr; signedcount; ap++, signedcount--) {
+ pk11_SignedToUnsigned(ap);
}
rv = PK11_CreateNewObject(slot, CK_INVALID_SESSION,
- theTemplate, templateCount, isPerm, &objectID);
+ 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;
- }
+ 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);
+ 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)
+ SECKEYPrivateKeyInfo *pki, SECItem *nickname, SECItem *publicValue,
+ PRBool isPerm, PRBool isPrivate, unsigned int keyUsage,
+ SECKEYPrivateKey **privk, void *wincx)
{
SECStatus rv = SECFailure;
SECKEYRawPrivateKey *lpk = NULL;
@@ -433,88 +476,86 @@ PK11_ImportPrivateKeyInfoAndReturnKey(PK11SlotInfo *slot,
PLArenaPool *arena = NULL;
arena = PORT_NewArena(2048);
- if(!arena) {
- return SECFailure;
+ 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;
+ 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;
- 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;
- 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;
- break;
-
- default:
- keyTemplate = NULL;
- paramTemplate = NULL;
- paramDest = NULL;
- break;
+ 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;
+ 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;
+ 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;
+ break;
+
+ default:
+ keyTemplate = NULL;
+ paramTemplate = NULL;
+ paramDest = NULL;
+ break;
}
- if(!keyTemplate) {
- goto loser;
+ 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 (rv != SECSuccess) {
+ goto loser;
}
- if(paramDest && paramTemplate) {
- rv = SEC_ASN1DecodeItem(arena, paramDest, paramTemplate,
- &(pki->algorithm.parameters));
- 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);
-
+ rv = PK11_ImportAndReturnPrivateKey(slot, lpk, nickname, publicValue, isPerm,
+ isPrivate, keyUsage, privk, wincx);
loser:
if (arena != NULL) {
- PORT_FreeArena(arena, PR_TRUE);
+ 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)
+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);
-
+ publicValue, isPerm, isPrivate, keyUsage, NULL, wincx);
}
SECItem *
diff --git a/nss/lib/pk11wrap/pk11pqg.c b/nss/lib/pk11wrap/pk11pqg.c
index be8adec..d7c5f36 100644
--- a/nss/lib/pk11wrap/pk11pqg.c
+++ b/nss/lib/pk11wrap/pk11pqg.c
@@ -13,20 +13,19 @@
#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
+ * 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,
+ * 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:
@@ -41,86 +40,92 @@
*/
extern SECStatus
PK11_PQG_ParamGenV2(unsigned int L, unsigned int N,
- unsigned int seedBytes, PQGParams **pParams, PQGVerify **pVfy)
+ 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]);
+ 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 },
+ { 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 },
+ { 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]);
+ int pTemplateCount = sizeof(pTemplate) / sizeof(pTemplate[0]);
+ int vTemplateCount = sizeof(vTemplate) / sizeof(vTemplate[0]);
PLArenaPool *parena = NULL;
PLArenaPool *varena = NULL;
PQGParams *params = NULL;
PQGVerify *verify = NULL;
- CK_ULONG seedBits = seedBytes*8;
+ CK_ULONG seedBits = seedBytes * 8;
*pParams = NULL;
- *pVfy = NULL;
+ *pVfy = NULL;
if (primeBits == (CK_ULONG)-1) {
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- goto loser;
+ PORT_SetError(SEC_ERROR_INVALID_ARGS);
+ goto loser;
}
- PK11_SETATTRS(attrs, CKA_PRIME_BITS,&primeBits,sizeof(primeBits)); attrs++;
+ PK11_SETATTRS(attrs, CKA_PRIME_BITS, &primeBits, sizeof(primeBits));
+ attrs++;
if (subPrimeBits != 0) {
- PK11_SETATTRS(attrs, CKA_SUB_PRIME_BITS,
- &subPrimeBits, sizeof(subPrimeBits)); attrs++;
+ 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++;
+ PK11_SETATTRS(attrs, CKA_NETSCAPE_PQG_SEED_BITS,
+ &seedBits, sizeof(seedBits));
+ attrs++;
}
count = attrs - genTemplate;
- PR_ASSERT(count <= sizeof(genTemplate)/sizeof(CK_ATTRIBUTE));
+ 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;
+ /* 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--;
- }
- }
+ 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 */
@@ -130,29 +135,28 @@ PK11_PQG_ParamGenV2(unsigned int L, unsigned int N,
PK11_EnterSlotMonitor(slot);
crv = PK11_GETTAB(slot)->C_GenerateKey(slot->session,
- &mechanism, genTemplate, count, &objectID);
+ &mechanism, genTemplate, count, &objectID);
PK11_ExitSlotMonitor(slot);
if (crv != CKR_OK) {
- PORT_SetError( PK11_MapError(crv) );
- goto loser;
+ PORT_SetError(PK11_MapError(crv));
+ goto loser;
}
parena = PORT_NewArena(60);
if (!parena) {
- goto loser;
- }
+ goto loser;
+ }
crv = PK11_GetAttributes(parena, slot, objectID, pTemplate, pTemplateCount);
if (crv != CKR_OK) {
- PORT_SetError( PK11_MapError(crv) );
- goto loser;
+ PORT_SetError(PK11_MapError(crv));
+ goto loser;
}
-
- params = (PQGParams *)PORT_ArenaAlloc(parena,sizeof(PQGParams));
+ params = (PQGParams *)PORT_ArenaAlloc(parena, sizeof(PQGParams));
if (params == NULL) {
- goto loser;
+ goto loser;
}
/* fill in Params */
@@ -167,26 +171,24 @@ PK11_PQG_ParamGenV2(unsigned int L, unsigned int N,
params->base.data = pTemplate[2].pValue;
params->base.len = pTemplate[2].ulValueLen;
-
varena = PORT_NewArena(60);
if (!varena) {
- goto loser;
- }
+ goto loser;
+ }
crv = PK11_GetAttributes(varena, slot, objectID, vTemplate, vTemplateCount);
if (crv != CKR_OK) {
- PORT_SetError( PK11_MapError(crv) );
- goto loser;
+ PORT_SetError(PK11_MapError(crv));
+ goto loser;
}
-
- verify = (PQGVerify *)PORT_ArenaAlloc(varena,sizeof(PQGVerify));
+ verify = (PQGVerify *)PORT_ArenaAlloc(varena, sizeof(PQGVerify));
if (verify == NULL) {
- goto loser;
+ goto loser;
}
/* fill in Params */
verify->arena = varena;
- verify->counter = (unsigned int)(*(CK_ULONG*)vTemplate[0].pValue);
+ 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;
@@ -194,26 +196,26 @@ PK11_PQG_ParamGenV2(unsigned int L, unsigned int N,
verify->h.data = vTemplate[2].pValue;
verify->h.len = vTemplate[2].ulValueLen;
- PK11_DestroyObject(slot,objectID);
+ PK11_DestroyObject(slot, objectID);
PK11_FreeSlot(slot);
*pParams = params;
- *pVfy = verify;
+ *pVfy = verify;
return SECSuccess;
loser:
if (objectID != CK_INVALID_HANDLE) {
- PK11_DestroyObject(slot,objectID);
+ PK11_DestroyObject(slot, objectID);
}
if (parena != NULL) {
- PORT_FreeArena(parena,PR_FALSE);
+ PORT_FreeArena(parena, PR_FALSE);
}
if (varena != NULL) {
- PORT_FreeArena(varena,PR_FALSE);
+ PORT_FreeArena(varena, PR_FALSE);
}
if (slot) {
- PK11_FreeSlot(slot);
+ PK11_FreeSlot(slot);
}
return SECFailure;
}
@@ -224,15 +226,15 @@ loser:
* 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)
+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.
+ * 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
@@ -254,19 +256,19 @@ PK11_PQG_ParamGen(unsigned int j, PQGParams **pParams, PQGVerify **pVfy)
*/
extern SECStatus
-PK11_PQG_VerifyParams(const PQGParams *params, const PQGVerify *vfy,
- SECStatus *result)
+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 },
+ { 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;
@@ -280,76 +282,81 @@ PK11_PQG_VerifyParams(const PQGParams *params, const PQGVerify *vfy,
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++;
+ 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_BASE, params->base.data, params->base.len);
+ attrs++;
}
- PK11_SETATTRS(attrs, CKA_TOKEN, &ckfalse, sizeof(ckfalse)); 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++;
- }
+ 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]));
-
+ PORT_Assert(keyCount <= sizeof(keyTempl) / sizeof(keyTempl[0]));
slot = PK11_GetInternalSlot();
if (slot == NULL) {
- return SECFailure;
+ return SECFailure;
}
PK11_EnterSlotMonitor(slot);
- crv = PK11_GETTAB(slot)->C_CreateObject(slot->session, keyTempl, keyCount,
- &objectID);
+ 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_DestroyObject(slot, objectID);
PK11_FreeSlot(slot);
*result = SECSuccess;
if (crv == CKR_ATTRIBUTE_VALUE_INVALID) {
- *result = SECFailure;
+ *result = SECFailure;
} else if (crv != CKR_OK) {
- PORT_SetError( PK11_MapError(crv) );
- rv = SECFailure;
+ 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;
+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 */
+ 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);
+ 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);
}
}
@@ -357,19 +364,20 @@ PK11_PQG_DestroyParams(PQGParams *params) {
* Free the PQGVerify struct and the things it points to. *
**************************************************************************/
extern void
-PK11_PQG_DestroyVerify(PQGVerify *vfy) {
- if (vfy == NULL)
- return;
+PK11_PQG_DestroyVerify(PQGVerify *vfy)
+{
+ if (vfy == NULL)
+ return;
if (vfy->arena != NULL) {
- PORT_FreeArena(vfy->arena, PR_FALSE); /* don't zero it */
+ 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);
+ 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 */
+#define PQG_DEFAULT_CHUNKSIZE 2048 /* bytes */
/**************************************************************************
* Return a pointer to a new PQGParams struct that is constructed from *
@@ -377,136 +385,138 @@ PK11_PQG_DestroyVerify(PQGVerify *vfy) {
* Return NULL on failure. *
**************************************************************************/
extern PQGParams *
-PK11_PQG_NewParams(const SECItem * prime, const SECItem * subPrime,
- const SECItem * base) {
+PK11_PQG_NewParams(const SECItem *prime, const SECItem *subPrime,
+ const SECItem *base)
+{
PLArenaPool *arena;
PQGParams *dest;
SECStatus status;
arena = PORT_NewArena(PQG_DEFAULT_CHUNKSIZE);
if (arena == NULL)
- goto loser;
+ goto loser;
- dest = (PQGParams*)PORT_ArenaZAlloc(arena, sizeof(PQGParams));
+ dest = (PQGParams *)PORT_ArenaZAlloc(arena, sizeof(PQGParams));
if (dest == NULL)
- goto loser;
+ goto loser;
dest->arena = arena;
status = SECITEM_CopyItem(arena, &dest->prime, prime);
if (status != SECSuccess)
- goto loser;
+ goto loser;
status = SECITEM_CopyItem(arena, &dest->subPrime, subPrime);
if (status != SECSuccess)
- goto loser;
+ goto loser;
status = SECITEM_CopyItem(arena, &dest->base, base);
if (status != SECSuccess)
- goto loser;
+ goto loser;
return dest;
loser:
if (arena != NULL)
- PORT_FreeArena(arena, PR_FALSE);
+ 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);
+ * Contents can be freed by calling SECITEM_FreeItem(prime, PR_FALSE);
**************************************************************************/
-extern SECStatus
-PK11_PQG_GetPrimeFromParams(const PQGParams *params, SECItem * prime) {
+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);
+ * Contents can be freed by calling SECITEM_FreeItem(subPrime, PR_FALSE);
**************************************************************************/
extern SECStatus
-PK11_PQG_GetSubPrimeFromParams(const PQGParams *params, SECItem * subPrime) {
+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);
+ * Contents can be freed by calling SECITEM_FreeItem(base, PR_FALSE);
**************************************************************************/
-extern SECStatus
-PK11_PQG_GetBaseFromParams(const PQGParams *params, SECItem *base) {
+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) {
+PK11_PQG_NewVerify(unsigned int counter, const SECItem *seed,
+ const SECItem *h)
+{
PLArenaPool *arena;
- PQGVerify * dest;
- SECStatus status;
+ PQGVerify *dest;
+ SECStatus status;
arena = PORT_NewArena(PQG_DEFAULT_CHUNKSIZE);
if (arena == NULL)
- goto loser;
+ goto loser;
- dest = (PQGVerify*)PORT_ArenaZAlloc(arena, sizeof(PQGVerify));
+ dest = (PQGVerify *)PORT_ArenaZAlloc(arena, sizeof(PQGVerify));
if (dest == NULL)
- goto loser;
+ goto loser;
- dest->arena = arena;
+ dest->arena = arena;
dest->counter = counter;
status = SECITEM_CopyItem(arena, &dest->seed, seed);
if (status != SECSuccess)
- goto loser;
+ goto loser;
status = SECITEM_CopyItem(arena, &dest->h, h);
if (status != SECSuccess)
- goto loser;
+ goto loser;
return dest;
loser:
if (arena != NULL)
- PORT_FreeArena(arena, PR_FALSE);
+ PORT_FreeArena(arena, PR_FALSE);
return NULL;
}
-
/**************************************************************************
* Returns "counter" value from the PQGVerify.
**************************************************************************/
-extern unsigned int
-PK11_PQG_GetCounterFromVerify(const PQGVerify *verify) {
+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);
+ * Contents can be freed by calling SECITEM_FreeItem(seed, PR_FALSE);
**************************************************************************/
-extern SECStatus
-PK11_PQG_GetSeedFromVerify(const PQGVerify *verify, SECItem *seed) {
+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);
+ * Contents can be freed by calling SECITEM_FreeItem(h, PR_FALSE);
**************************************************************************/
-extern SECStatus
-PK11_PQG_GetHFromVerify(const PQGVerify *verify, SECItem * h) {
+extern SECStatus
+PK11_PQG_GetHFromVerify(const PQGVerify *verify, SECItem *h)
+{
return SECITEM_CopyItem(NULL, h, &verify->h);
}
diff --git a/nss/lib/pk11wrap/pk11pqg.h b/nss/lib/pk11wrap/pk11pqg.h
index 02f9394..36596dd 100644
--- a/nss/lib/pk11wrap/pk11pqg.h
+++ b/nss/lib/pk11wrap/pk11pqg.h
@@ -6,27 +6,26 @@
*/
#ifndef _PK11PQG_H_
-#define _PK11PQG_H_ 1
+#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.
+ * 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);
+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);
-
+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.
@@ -34,13 +33,13 @@ extern SECStatus PK11_PQG_ParamGenSeedLen( unsigned int j,
* 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
+ * 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,
+ * 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:
@@ -55,7 +54,7 @@ extern SECStatus PK11_PQG_ParamGenSeedLen( unsigned int j,
*/
extern SECStatus
PK11_PQG_ParamGenV2(unsigned int L, unsigned int N, unsigned int seedBytes,
- PQGParams **pParams, PQGVerify **pVfy);
+ 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
@@ -69,11 +68,11 @@ PK11_PQG_ParamGenV2(unsigned int L, unsigned int N, unsigned int seedBytes,
*
* 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
+ * 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 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);
@@ -82,42 +81,36 @@ extern void PK11_PQG_DestroyVerify(PQGVerify *vfy);
* copies of the arguments passed in. *
* Return NULL on failure. *
**************************************************************************/
-extern PQGParams * PK11_PQG_NewParams(const SECItem * prime, const
- SECItem * subPrime, const SECItem * base);
-
+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);
+ * Contents can be freed by calling SECITEM_FreeItem(prime, PR_FALSE);
**************************************************************************/
-extern SECStatus PK11_PQG_GetPrimeFromParams(const PQGParams *params,
- SECItem * prime);
-
+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);
+ * Contents can be freed by calling SECITEM_FreeItem(subPrime, PR_FALSE);
**************************************************************************/
-extern SECStatus PK11_PQG_GetSubPrimeFromParams(const PQGParams *params,
- SECItem * subPrime);
-
+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);
+ * Contents can be freed by calling SECITEM_FreeItem(base, PR_FALSE);
**************************************************************************/
-extern SECStatus PK11_PQG_GetBaseFromParams(const PQGParams *params,
- SECItem *base);
-
+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);
-
+extern PQGVerify *PK11_PQG_NewVerify(unsigned int counter,
+ const SECItem *seed, const SECItem *h);
/**************************************************************************
* Returns "counter" value from the PQGVerify.
@@ -126,16 +119,16 @@ 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);
+ * Contents can be freed by calling SECITEM_FreeItem(seed, PR_FALSE);
**************************************************************************/
-extern SECStatus PK11_PQG_GetSeedFromVerify(const PQGVerify *verify,
- SECItem *seed);
+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);
+ * Contents can be freed by calling SECITEM_FreeItem(h, PR_FALSE);
**************************************************************************/
-extern SECStatus PK11_PQG_GetHFromVerify(const PQGVerify *verify, SECItem * h);
+extern SECStatus PK11_PQG_GetHFromVerify(const PQGVerify *verify, SECItem *h);
SEC_END_PROTOS
diff --git a/nss/lib/pk11wrap/pk11priv.h b/nss/lib/pk11wrap/pk11priv.h
index c68293b..45a60b4 100644
--- a/nss/lib/pk11wrap/pk11priv.h
+++ b/nss/lib/pk11wrap/pk11priv.h
@@ -17,7 +17,7 @@
/*
* These are the private NSS functions. They are not exported by nss.def, and
- * are not callable outside nss3.dll.
+ * are not callable outside nss3.dll.
*/
SEC_BEGIN_PROTOS
@@ -25,13 +25,13 @@ 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);
+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 *slot);
PK11SlotInfo *PK11_FindSlotBySerial(char *serial);
int PK11_GetMaxKeyLength(CK_MECHANISM_TYPE type);
@@ -40,30 +40,29 @@ int PK11_GetMaxKeyLength(CK_MECHANISM_TYPE type);
************************************************************/
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_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);
+ 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);
+void PK11_RestoreROSession(PK11SlotInfo *slot, CK_SESSION_HANDLE rwsession);
PRBool PK11_RWSessionHasLock(PK11SlotInfo *slot,
- CK_SESSION_HANDLE session_handle);
+ 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);
+ 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);
@@ -76,12 +75,11 @@ 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);
+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);
@@ -92,92 +90,89 @@ 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 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
+ * 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 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);
+ 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);
+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_TraverseCertsForSubject(CERTCertificate *cert,
+ SECStatus (*callback)(CERTCertificate *, void *), void *arg);
SECStatus PK11_GetKEAMatchedCerts(PK11SlotInfo *slot1,
- PK11SlotInfo *slot2, CERTCertificate **cert1, CERTCertificate **cert2);
+ PK11SlotInfo *slot2, CERTCertificate **cert1, CERTCertificate **cert2);
SECStatus PK11_TraverseCertsInSlot(PK11SlotInfo *slot,
- SECStatus(* callback)(CERTCertificate*, void *), void *arg);
+ 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);
+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);
+ SECItem *derName, int type, char **url);
CK_OBJECT_HANDLE
-PK11_PutCrl(PK11SlotInfo *slot, SECItem *crl,
- SECItem *name, char *url, int type);
+PK11_PutCrl(PK11SlotInfo *slot, SECItem *crl,
+ SECItem *name, char *url, int type);
SECItem *
PK11_FindSMimeProfile(PK11SlotInfo **slotp, char *emailAddr, SECItem *derSubj,
- SECItem **profileTime);
+ SECItem **profileTime);
SECStatus
PK11_SaveSMimeProfile(PK11SlotInfo *slot, char *emailAddr, SECItem *derSubj,
- SECItem *emailProfile, SECItem *profileTime);
+ 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) ;
-
+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);
+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);
+SECStatus pk11_RetrieveCrls(CERTCrlHeadNode *nodes, SECItem *issuer,
+ void *wincx);
/* set global options for NSS PKCS#11 module loader */
SECStatus pk11_setGlobalOptions(PRBool noSingleThreadedModules,
diff --git a/nss/lib/pk11wrap/pk11pub.h b/nss/lib/pk11wrap/pk11pub.h
index d4565eb..e11af86 100644
--- a/nss/lib/pk11wrap/pk11pub.h
+++ b/nss/lib/pk11wrap/pk11pub.h
@@ -26,32 +26,31 @@ SEC_BEGIN_PROTOS
************************************************************/
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);
+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);
+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);
+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,
+SECStatus PK11_InitPin(PK11SlotInfo *slot, const char *ssopw,
const char *pk11_userpwd);
SECStatus PK11_ChangePW(PK11SlotInfo *slot, const char *oldpw,
const char *newpw);
@@ -61,7 +60,6 @@ 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
******************************************************************/
@@ -73,12 +71,12 @@ PK11SlotInfo *PK11_FindSlotByName(const char *name);
* returned.
******************************************************************/
PK11SlotList *PK11_FindSlotsByNames(const char *dllName,
- const char* slotName, const char* tokenName, PRBool presentOnly);
+ 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);
+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);
@@ -105,34 +103,34 @@ PRBool PK11_UserDisableSlot(PK11SlotInfo *slot);
PRBool PK11_UserEnableSlot(PK11SlotInfo *slot);
/*
* wait for a specific slot event.
- * event is a specific event to wait for. Currently only
+ * 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
+ * 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
+ * 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
+ * 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
+ * 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
+ * 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
+ * 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);
+ PRIntervalTime timeout, PRIntervalTime pollInterval, int series);
PRBool PK11_NeedPWInit(void);
PRBool PK11_TokenExists(CK_MECHANISM_TYPE);
@@ -145,16 +143,16 @@ SECMODModule *PK11_GetModule(PK11SlotInfo *slot);
*********************************************************************/
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);
+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);
+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);
@@ -218,31 +216,28 @@ SECStatus SECMOD_CloseUserDB(PK11SlotInfo *slot);
*/
PK11SlotInfo *SECMOD_OpenNewSlot(SECMODModule *mod, const char *moduleSpec);
-
/*
- * merge the permanent objects from on token to another
+ * merge the permanent objects from on token to another
*/
SECStatus PK11_MergeTokens(PK11SlotInfo *targetSlot, PK11SlotInfo *sourceSlot,
- PK11MergeLog *log, void *targetPwArg, void *sourcePwArg);
+ PK11MergeLog *log, void *targetPwArg, void *sourcePwArg);
/*
* create and destroy merge logs needed by PK11_MergeTokens
*/
-PK11MergeLog * PK11_CreateMergeLog(void);
+PK11MergeLog *PK11_CreateMergeLog(void);
void PK11_DestroyMergeLog(PK11MergeLog *log);
-
-
/*********************************************************************
* Mechanism Mapping functions
*********************************************************************/
-CK_KEY_TYPE PK11_GetKeyType(CK_MECHANISM_TYPE type,unsigned long len);
+CK_KEY_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_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);
+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);
@@ -251,35 +246,35 @@ 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);
+ 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);
+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_PTR pCryptoMechanism,
+ SECItem *pbe_pwd, PRBool bad3DES);
CK_MECHANISM_TYPE PK11_GetPadMechanism(CK_MECHANISM_TYPE);
CK_MECHANISM_TYPE PK11_MapSignKeyType(KeyType keyType);
/**********************************************************************
- * Symmetric, Public, and Private Keys
+ * Symmetric, 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);
+ 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);
+ 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);
+ 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.
@@ -288,44 +283,43 @@ 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
+ *
+ * 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);
+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);
+ 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);
+ 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,
+ SECItem *param, CK_ATTRIBUTE *attrs,
unsigned int attrsCount, void *wincx);
-PK11SymKey * PK11_ListFixedKeysInSlot(PK11SlotInfo *slot, char *nickname,
- 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)
@@ -333,22 +327,22 @@ CK_OBJECT_HANDLE PK11_GetSymKeyHandle(PK11SymKey *symKey);
* 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
+ * 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
+ * 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
+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
*
@@ -360,15 +354,15 @@ void PK11_SetSymKeyUserData(PK11SymKey *symKey, void *data,
void *PK11_GetSymKeyUserData(PK11SymKey *symKey);
SECStatus PK11_PubWrapSymKey(CK_MECHANISM_TYPE type, SECKEYPublicKey *pubKey,
- PK11SymKey *symKey, SECItem *wrappedKey);
+ PK11SymKey *symKey, SECItem *wrappedKey);
SECStatus PK11_WrapSymKey(CK_MECHANISM_TYPE type, SECItem *params,
- PK11SymKey *wrappingKey, PK11SymKey *symKey, SECItem *wrappedKey);
+ 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
+ * 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);
+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
@@ -379,31 +373,30 @@ PK11SymKey *PK11_MoveSymKey(PK11SlotInfo *slot, CK_ATTRIBUTE_TYPE operation,
* (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);
+ 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);
+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.
@@ -414,50 +407,50 @@ PK11SymKey *PK11_PubDeriveWithKDF( SECKEYPrivateKey *privKey,
* 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);
+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
+ * 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);
+ 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_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);
+SECStatus PK11_SetPrivateKeyNickname(SECKEYPrivateKey *privKey,
+ const char *nickname);
+SECStatus PK11_SetPublicKeyNickname(SECKEYPublicKey *pubKey,
+ const char *nickname);
/*
* Using __PK11_SetCertificateNickname is *DANGEROUS*.
@@ -472,17 +465,17 @@ SECStatus PK11_SetPublicKeyNickname(SECKEYPublicKey *pubKey,
* If you ignore this warning, your process is TAINTED and will most likely misbehave.
*/
SECStatus __PK11_SetCertificateNickname(CERTCertificate *cert,
- const char *nickname);
+ 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);
+unsigned int PK11_GetKeyStrength(PK11SymKey *key, SECAlgorithmID *algid);
SECStatus PK11_ExtractKeyValue(PK11SymKey *symKey);
-SECItem * PK11_GetKeyData(PK11SymKey *symKey);
-PK11SlotInfo * PK11_GetSlotFromKey(PK11SymKey *symKey);
+SECItem *PK11_GetKeyData(PK11SymKey *symKey);
+PK11SlotInfo *PK11_GetSlotFromKey(PK11SymKey *symKey);
void *PK11_GetWindow(PK11SymKey *symKey);
/*
@@ -493,17 +486,17 @@ void *PK11_GetWindow(PK11SymKey *symKey);
*
* 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
+ * 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
+ * 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);
+ 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,
@@ -511,28 +504,28 @@ SECKEYPrivateKey *PK11_GenerateKeyPairWithOpFlags(PK11SlotInfo *slot,
* flags also apply to the public key.
*/
SECKEYPrivateKey *PK11_GenerateKeyPairWithFlags(PK11SlotInfo *slot,
- CK_MECHANISM_TYPE type, void *param, SECKEYPublicKey **pubk,
- PK11AttrFlags attrFlags, void *wincx);
+ 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);
+ 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);
SECStatus PK11_Decrypt(PK11SymKey *symkey,
- CK_MECHANISM_TYPE mechanism, SECItem *param,
- unsigned char *out, unsigned int *outLen,
- unsigned int maxLen,
- const unsigned char *enc, unsigned int encLen);
+ CK_MECHANISM_TYPE mechanism, SECItem *param,
+ unsigned char *out, unsigned int *outLen,
+ unsigned int maxLen,
+ const unsigned char *enc, unsigned int encLen);
SECStatus PK11_Encrypt(PK11SymKey *symKey,
- CK_MECHANISM_TYPE mechanism, SECItem *param,
- unsigned char *out, unsigned int *outLen,
- unsigned int maxLen,
- const unsigned char *data, unsigned int dataLen);
+ CK_MECHANISM_TYPE mechanism, SECItem *param,
+ unsigned char *out, unsigned int *outLen,
+ unsigned int maxLen,
+ const unsigned char *data, unsigned int dataLen);
/* note: despite the name, this function takes a private key. */
SECStatus PK11_PubDecryptRaw(SECKEYPrivateKey *key,
@@ -568,134 +561,134 @@ SECStatus PK11_PubEncrypt(SECKEYPublicKey *key,
const unsigned char *data, unsigned int 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);
+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);
SECItem *PK11_ExportDERPrivateKeyInfo(SECKEYPrivateKey *pk, void *wincx);
SECKEYPrivateKeyInfo *PK11_ExportPrivKeyInfo(
- SECKEYPrivateKey *pk, void *wincx);
+ SECKEYPrivateKey *pk, void *wincx);
SECKEYPrivateKeyInfo *PK11_ExportPrivateKeyInfo(
- CERTCertificate *cert, void *wincx);
+ CERTCertificate *cert, void *wincx);
SECKEYEncryptedPrivateKeyInfo *PK11_ExportEncryptedPrivKeyInfo(
- PK11SlotInfo *slot, SECOidTag algTag, SECItem *pwitem,
- SECKEYPrivateKey *pk, int iteration, void *wincx);
+ 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);
+ 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);
+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);
+ 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(const 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);
+SECItem *PK11_DEREncodePublicKey(const 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);
+SECKEYPrivateKeyList *PK11_ListPrivateKeysInSlot(PK11SlotInfo *slot);
PK11SymKey *PK11_ConvertSessionSymKeyToTokenSymKey(PK11SymKey *symk,
- void *wincx);
+ void *wincx);
SECKEYPrivateKey *PK11_ConvertSessionPrivKeyToTokenPrivKey(
- SECKEYPrivateKey *privk, void* wincx);
-SECKEYPrivateKey * PK11_CopyTokenPrivKeyToSessionPrivKey(PK11SlotInfo *destSlot,
- SECKEYPrivateKey *privKey);
+ 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);
+ 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);
+ 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,
+ 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);
+ void *wincx);
PK11SlotInfo *PK11_KeyForCertExists(CERTCertificate *cert,
- CK_OBJECT_HANDLE *keyPtr, void *wincx);
+ 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);
+ 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);
+ void *wincx);
SECStatus PK11_TraverseCertsForSubjectInSlot(CERTCertificate *cert,
- PK11SlotInfo *slot, SECStatus(*callback)(CERTCertificate *, void *),
- void *arg);
-CERTCertificate *PK11_FindCertFromDERCert(PK11SlotInfo *slot,
- CERTCertificate *cert, void *wincx);
+ 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);
+ 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);
+ 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);
+ 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);
+ 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
+ * Sign/Verify
**********************************************************************/
/*
@@ -706,24 +699,30 @@ CERTSignedCrl* PK11_ImportCRL(PK11SlotInfo * slot, SECItem *derCRL, char *url,
* -1 on failure?)
*/
int PK11_SignatureLen(SECKEYPrivateKey *key);
-PK11SlotInfo * PK11_GetSlotFromPrivateKey(SECKEYPrivateKey *key);
+PK11SlotInfo *PK11_GetSlotFromPrivateKey(SECKEYPrivateKey *key);
SECStatus PK11_Sign(SECKEYPrivateKey *key, SECItem *sig,
- const SECItem *hash);
+ const SECItem *hash);
+SECStatus PK11_SignWithMechanism(SECKEYPrivateKey *key,
+ CK_MECHANISM_TYPE mechanism,
+ const SECItem *param, SECItem *sig,
+ const SECItem *hash);
SECStatus PK11_SignWithSymKey(PK11SymKey *symKey, CK_MECHANISM_TYPE mechanism,
- SECItem *param, SECItem *sig, const SECItem *data);
+ SECItem *param, SECItem *sig, const SECItem *data);
SECStatus PK11_VerifyRecover(SECKEYPublicKey *key, const SECItem *sig,
- SECItem *dsig, void * wincx);
+ SECItem *dsig, void *wincx);
SECStatus PK11_Verify(SECKEYPublicKey *key, const SECItem *sig,
- const SECItem *hash, void *wincx);
-
-
+ const SECItem *hash, void *wincx);
+SECStatus PK11_VerifyWithMechanism(SECKEYPublicKey *key,
+ CK_MECHANISM_TYPE mechanism,
+ const SECItem *param, 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);
+ CK_ATTRIBUTE_TYPE operation, PK11SymKey *symKey, SECItem *param);
PK11Context *PK11_CreateDigestContext(SECOidTag hashAlg);
PK11Context *PK11_CloneContext(PK11Context *old);
SECStatus PK11_DigestBegin(PK11Context *cx);
@@ -732,17 +731,17 @@ SECStatus PK11_DigestBegin(PK11Context *cx);
* 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,
+ 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_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_DigestFinal(PK11Context *context, unsigned char *data,
+ unsigned int *outLen, unsigned int length);
#define PK11_CipherFinal PK11_DigestFinal
-SECStatus PK11_SaveContext(PK11Context *cx,unsigned char *save,
- int *len, int saveLength);
+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,
@@ -758,20 +757,19 @@ 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) ;
-
+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
+ * 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 *
+SECItem *
PK11_CreatePBEParams(SECItem *salt, SECItem *pwd, unsigned int iterations);
/* free params created above (can be called after keygen is done */
@@ -787,13 +785,13 @@ 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);
+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 *pwitem, PRBool faulty3DES, void *wincx);
SECItem *
PK11_GetPBEIV(SECAlgorithmID *algid, SECItem *pwitem);
/*
@@ -802,38 +800,38 @@ PK11_GetPBEIV(SECAlgorithmID *algid, SECItem *pwitem);
* Caller is responsible for freeing the return parameter (param).
*/
CK_MECHANISM_TYPE
-PK11_GetPBECryptoMechanism(SECAlgorithmID *algid,
- SECItem **param, SECItem *pwd);
+PK11_GetPBECryptoMechanism(SECAlgorithmID *algid,
+ SECItem **param, SECItem *pwd);
/**********************************************************************
* Functions to manage secmod flags
**********************************************************************/
const PK11DefaultArrayEntry *PK11_GetDefaultArray(int *size);
SECStatus PK11_UpdateSlotAttribute(PK11SlotInfo *slot,
- const PK11DefaultArrayEntry *entry,
- PRBool add);
+ const PK11DefaultArrayEntry *entry,
+ PRBool add);
/**********************************************************************
* Functions to look at PKCS #11 dependent data
**********************************************************************/
-PK11GenericObject *PK11_FindGenericObjects(PK11SlotInfo *slot,
- CK_OBJECT_CLASS objClass);
+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);
+ 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);
+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:
@@ -852,10 +850,10 @@ PK11GenericObject *PK11_CreateGenericObject(PK11SlotInfo *slot,
* 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);
+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
@@ -870,7 +868,7 @@ PK11_GetAllSlotsForCert(CERTCertificate *cert, void *arg);
**********************************************************************/
SECItem *
PK11_GetLowLevelKeyIDForCert(PK11SlotInfo *slot,
- CERTCertificate *cert, void *pwarg);
+ CERTCertificate *cert, void *pwarg);
SECItem *
PK11_GetLowLevelKeyIDForPrivateKey(SECKEYPrivateKey *key);
diff --git a/nss/lib/pk11wrap/pk11sdr.c b/nss/lib/pk11wrap/pk11sdr.c
index 43030b6..eb67bfb 100644
--- a/nss/lib/pk11wrap/pk11sdr.c
+++ b/nss/lib/pk11wrap/pk11sdr.c
@@ -13,34 +13,33 @@
* 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;
+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 }
+ { 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
+ 0xF8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01
};
static SECItem keyIDItem = {
- 0,
- keyID,
- sizeof keyID
+ 0,
+ keyID,
+ sizeof keyID
};
/* local utility function for padding an incoming data block
@@ -49,82 +48,91 @@ static SECItem keyIDItem = {
static SECStatus
padBlock(SECItem *data, int blockSize, SECItem *result)
{
- SECStatus rv = SECSuccess;
- int padLength;
- unsigned int i;
+ SECStatus rv = SECSuccess;
+ int padLength;
+ unsigned int i;
- result->data = 0;
- result->len = 0;
+ result->data = 0;
+ result->len = 0;
- /* This algorithm always adds to the block (to indicate the number
+ /* 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);
+ 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);
+ /* 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;
+ /* Add the pad values */
+ for (i = data->len; i < result->len; i++)
+ result->data[i] = (unsigned char)padLength;
- return rv;
+ return rv;
}
static SECStatus
unpadBlock(SECItem *data, int blockSize, SECItem *result)
{
- SECStatus rv = SECSuccess;
- int padLength;
- unsigned int i;
+ SECStatus rv = SECSuccess;
+ int padLength;
+ unsigned int i;
- result->data = 0;
- result->len = 0;
+ 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; }
+ /* 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; }
+ 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;
+ /* 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; }
+ 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);
+ PORT_Memcpy(result->data, data->data, result->len);
- if (padLength < 2) {
- return SECWouldBlock;
- }
+ if (padLength < 2) {
+ return SECWouldBlock;
+ }
loser:
- return rv;
+ return rv;
}
static PRLock *pk11sdrLock = NULL;
void
-pk11sdr_Init (void)
+pk11sdr_Init(void)
{
- pk11sdrLock = PR_NewLock();
+ pk11sdrLock = PR_NewLock();
}
void
pk11sdr_Shutdown(void)
{
if (pk11sdrLock) {
- PR_DestroyLock(pk11sdrLock);
- pk11sdrLock = NULL;
+ PR_DestroyLock(pk11sdrLock);
+ pk11sdrLock = NULL;
}
}
@@ -136,135 +144,171 @@ pk11sdr_Shutdown(void)
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 */
+ 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;
+ }
- /* put in a course lock to prevent a race between not finding the
- * key and creating one.
- */
+ /* 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)
+ */
- if (pk11sdrLock) PR_Lock(pk11sdrLock);
+ slot = PK11_GetInternalKeySlot();
+ if (!slot) {
+ rv = SECFailure;
+ goto loser;
+ }
- /* 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);
- }
+ /* 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; }
+ if (!key) {
+ rv = SECFailure;
+ goto loser;
+ }
- params = PK11_GenerateNewParam(type, key);
- if (!params) { 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; }
+ 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;
+ 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);
+ 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;
+ 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);
+ PK11_Finalize(ctx);
- sdrResult.keyid = *pKeyID;
+ sdrResult.keyid = *pKeyID;
- rv = PK11_ParamToAlgid(SEC_OID_DES_EDE3_CBC, params, arena, &sdrResult.alg);
- if (rv != SECSuccess) goto loser;
+ 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; }
+ 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;
+ 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)
+pk11Decrypt(PK11SlotInfo *slot, PLArenaPool *arena,
+ CK_MECHANISM_TYPE type, PK11SymKey *key,
+ SECItem *params, SECItem *in, SECItem *result)
{
- PK11Context *ctx = 0;
- SECItem paddedResult;
- SECStatus rv;
+ PK11Context *ctx = 0;
+ SECItem paddedResult;
+ SECStatus rv;
- paddedResult.len = 0;
- paddedResult.data = 0;
+ paddedResult.len = 0;
+ paddedResult.data = 0;
- ctx = PK11_CreateContextBySymKey(type, CKA_DECRYPT, key, params);
- if (!ctx) { rv = SECFailure; goto loser; }
+ 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);
+ 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;
+ rv = PK11_CipherOp(ctx, paddedResult.data,
+ (int *)&paddedResult.len, paddedResult.len,
+ in->data, in->len);
+ if (rv != SECSuccess)
+ goto loser;
- PK11_Finalize(ctx);
+ PK11_Finalize(ctx);
- /* Remove the padding */
- rv = unpadBlock(&paddedResult, PK11_GetBlockSize(type, 0), result);
- if (rv) goto loser;
+ /* 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;
+ if (ctx)
+ PK11_DestroyContext(ctx, PR_TRUE);
+ return rv;
}
/*
@@ -275,103 +319,119 @@ loser:
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;
- }
+ 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;
+ }
- /*
- * 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;
- }
+ /* 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;
+ }
-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);
+ 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;
+ }
- return rv;
+ /* 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/nss/lib/pk11wrap/pk11skey.c b/nss/lib/pk11wrap/pk11skey.c
index 20d9eaa..850ec02 100644
--- a/nss/lib/pk11wrap/pk11skey.c
+++ b/nss/lib/pk11wrap/pk11skey.c
@@ -19,15 +19,17 @@
#include "hasht.h"
static void
-pk11_EnterKeyMonitor(PK11SymKey *symKey) {
- if (!symKey->sessionOwner || !(symKey->slot->isThreadSafe))
- PK11_EnterSlotMonitor(symKey->slot);
+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_ExitKeyMonitor(PK11SymKey *symKey)
+{
+ if (!symKey->sessionOwner || !(symKey->slot->isThreadSafe))
+ PK11_ExitSlotMonitor(symKey->slot);
}
/*
@@ -36,66 +38,67 @@ pk11_ExitKeyMonitor(PK11SymKey *symKey) {
* was not specified).
*/
static PK11SymKey *
-pk11_getKeyFromList(PK11SlotInfo *slot, PRBool needSession) {
+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 (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--;
- }
+ 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.
+ 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;
+ 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;
+ return NULL;
}
symKey->next = NULL;
if (needSession) {
- symKey->session = pk11_GetNewSession(slot,&symKey->sessionOwner);
- PORT_Assert(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) {
- PK11_FreeSymKey(symKey);
- symKey = NULL;
- }
+ PK11_FreeSymKey(symKey);
+ symKey = NULL;
+ }
} else {
- symKey->session = CK_INVALID_SESSION;
+ symKey->session = CK_INVALID_SESSION;
}
return symKey;
}
@@ -107,16 +110,16 @@ 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);
+ 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);
+ symKey = slot->freeSymKeysHead;
+ slot->freeSymKeysHead = symKey->next;
+ pk11_CloseSession(slot, symKey->session, symKey->sessionOwner);
+ PORT_Free(symKey);
}
return;
}
@@ -124,29 +127,29 @@ PK11_CleanKeyList(PK11SlotInfo *slot)
/*
* create a symetric key:
* Slot is the slot to create the key in.
- * type is the mechanism type
+ * 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)
+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;
+ 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;
+ PK11_FreeSymKey(symKey);
+ PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
+ return NULL;
}
symKey->type = type;
@@ -178,61 +181,60 @@ PK11_FreeSymKey(PK11SymKey *symKey)
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);
- }
+ 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) {
- /*
+ if (slot->keyCount < slot->maxKeyCount) {
+ /*
* freeSymkeysWithSessionHead contain a list of reusable
- * SymKey structures with valid sessions.
- * sessionOwner must be true.
+ * 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;
+ * 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);
+ PZ_Unlock(slot->freeListLock);
if (freeit) {
- pk11_CloseSession(symKey->slot, symKey->session,
- symKey->sessionOwner);
- PORT_Free(symKey);
- }
- PK11_FreeSlot(slot);
+ pk11_CloseSession(symKey->slot, symKey->session,
+ symKey->sessionOwner);
+ PORT_Free(symKey);
+ }
+ PK11_FreeSlot(slot);
- if (parent) {
- PK11_FreeSymKey(parent);
- }
+ if (parent) {
+ PK11_FreeSymKey(parent);
+ }
}
}
@@ -261,9 +263,10 @@ PK11_GetSlotFromKey(PK11SymKey *symKey)
return PK11_ReferenceSlot(symKey->slot);
}
-CK_KEY_TYPE PK11_GetSymKeyType(PK11SymKey *symKey)
+CK_KEY_TYPE
+PK11_GetSymKeyType(PK11SymKey *symKey)
{
- return PK11_GetKeyType(symKey->type,symKey->size);
+ return PK11_GetKeyType(symKey->type, symKey->size);
}
PK11SymKey *
@@ -275,13 +278,13 @@ PK11_GetNextSymKey(PK11SymKey *symKey)
char *
PK11_GetSymKeyNickname(PK11SymKey *symKey)
{
- return PK11_GetObjectNickname(symKey->slot,symKey->objectID);
+ return PK11_GetObjectNickname(symKey->slot, symKey->objectID);
}
SECStatus
PK11_SetSymKeyNickname(PK11SymKey *symKey, const char *nickname)
{
- return PK11_SetObjectNickname(symKey->slot,symKey->objectID,nickname);
+ return PK11_SetObjectNickname(symKey->slot, symKey->objectID, nickname);
}
void *
@@ -291,12 +294,12 @@ PK11_GetSymKeyUserData(PK11SymKey *symKey)
}
void
-PK11_SetSymKeyUserData(PK11SymKey *symKey, void *userData,
- PK11FreeDataFunc freeFunc)
+PK11_SetSymKeyUserData(PK11SymKey *symKey, void *userData,
+ PK11FreeDataFunc freeFunc)
{
/* free any existing data */
if (symKey->userData && symKey->freeFunc) {
- (*symKey->freeFunc)(symKey->userData);
+ (*symKey->freeFunc)(symKey->userData);
}
symKey->userData = userData;
symKey->freeFunc = freeFunc;
@@ -308,18 +311,18 @@ PK11_SetSymKeyUserData(PK11SymKey *symKey, void *userData,
*/
PK11SymKey *
PK11_SymKeyFromHandle(PK11SlotInfo *slot, PK11SymKey *parent, PK11Origin origin,
- CK_MECHANISM_TYPE type, CK_OBJECT_HANDLE keyID, PRBool owner, void *wincx)
+ 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;
+ return NULL;
}
symKey = pk11_CreateSymKey(slot, type, owner, needSession, wincx);
if (symKey == NULL) {
- return NULL;
+ return NULL;
}
symKey->objectID = keyID;
@@ -330,18 +333,18 @@ PK11_SymKeyFromHandle(PK11SlotInfo *slot, PK11SymKey *parent, PK11Origin origin,
* 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);
+ 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;
- }
+ * 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;
@@ -352,16 +355,19 @@ PK11_SymKeyFromHandle(PK11SlotInfo *slot, PK11SymKey *parent, PK11Origin origin,
*/
PK11SymKey *
PK11_GetWrapKey(PK11SlotInfo *slot, int wrap, CK_MECHANISM_TYPE type,
- int series, void *wincx)
+ 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;
+ 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);
+ slot->wrapMechanism, slot->refKeys[wrap], PR_FALSE, wincx);
return symKey;
}
@@ -382,29 +388,29 @@ PK11_SetWrapKey(PK11SlotInfo *slot, int wrap, PK11SymKey *wrapKey)
slot->wrapMechanism = wrapKey->type;
}
-
/*
* figure out if a key is still valid or if it is stale.
*/
PRBool
-PK11_VerifyKeyOK(PK11SymKey *key) {
+PK11_VerifyKeyOK(PK11SymKey *key)
+{
if (!PK11_IsPresent(key->slot)) {
- return PR_FALSE;
+ 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)
+ PK11Origin origin, PRBool isToken, CK_ATTRIBUTE *keyTemplate,
+ unsigned int templateCount, SECItem *key, void *wincx)
{
- PK11SymKey * symKey;
- SECStatus rv;
+ PK11SymKey *symKey;
+ SECStatus rv;
symKey = pk11_CreateSymKey(slot, type, !isToken, PR_TRUE, wincx);
if (symKey == NULL) {
- return NULL;
+ return NULL;
}
symKey->size = key->len;
@@ -412,19 +418,19 @@ pk11_ImportSymKeyWithTempl(PK11SlotInfo *slot, CK_MECHANISM_TYPE type,
PK11_SETATTRS(&keyTemplate[templateCount], CKA_VALUE, key->data, key->len);
templateCount++;
- if (SECITEM_CopyItem(NULL,&symKey->data,key) != SECSuccess) {
- PK11_FreeSymKey(symKey);
- return NULL;
+ 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;
+ templateCount, isToken, &symKey->objectID);
+ if (rv != SECSuccess) {
+ PK11_FreeSymKey(symKey);
+ return NULL;
}
return symKey;
@@ -435,74 +441,80 @@ pk11_ImportSymKeyWithTempl(PK11SlotInfo *slot, CK_MECHANISM_TYPE type,
*/
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++;
+ 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));
+ 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);
+ 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++;
+ 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++;
+ 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++;
+ !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));
+ PR_ASSERT(templateCount + 1 <= sizeof(keyTemplate) / sizeof(CK_ATTRIBUTE));
- keyType = PK11_GetKeyType(type,key->len);
+ keyType = PK11_GetKeyType(type, key->len);
symKey = pk11_ImportSymKeyWithTempl(slot, type, origin, isPerm,
- keyTemplate, templateCount, key, wincx);
+ keyTemplate, templateCount, key, wincx);
if (symKey && isPerm) {
- symKey->owner = PR_FALSE;
+ symKey->owner = PR_FALSE;
}
return symKey;
}
-
PK11SymKey *
PK11_FindFixedKey(PK11SlotInfo *slot, CK_MECHANISM_TYPE type, SECItem *keyID,
- void *wincx)
+ void *wincx)
{
CK_ATTRIBUTE findTemp[4];
CK_ATTRIBUTE *attrs;
@@ -512,20 +524,23 @@ PK11_FindFixedKey(PK11SlotInfo *slot, CK_MECHANISM_TYPE type, SECItem *keyID,
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++;
+ 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++;
+ PK11_SETATTRS(attrs, CKA_ID, keyID->data, keyID->len);
+ attrs++;
}
tsize = attrs - findTemp;
- PORT_Assert(tsize <= sizeof(findTemp)/sizeof(CK_ATTRIBUTE));
+ PORT_Assert(tsize <= sizeof(findTemp) / sizeof(CK_ATTRIBUTE));
- key_id = pk11_FindObjectByTemplate(slot,findTemp,tsize);
+ key_id = pk11_FindObjectByTemplate(slot, findTemp, tsize);
if (key_id == CK_INVALID_HANDLE) {
- return NULL;
+ return NULL;
}
return PK11_SymKeyFromHandle(slot, NULL, PK11_OriginDerive, type, key_id,
- PR_FALSE, wincx);
+ PR_FALSE, wincx);
}
PK11SymKey *
@@ -540,51 +555,53 @@ PK11_ListFixedKeysInSlot(PK11SlotInfo *slot, char *nickname, void *wincx)
CK_OBJECT_HANDLE *key_ids;
PK11SymKey *nextKey = NULL;
PK11SymKey *topKey = NULL;
- int i,len;
+ int i, len;
attrs = findTemp;
- PK11_SETATTRS(attrs, CKA_CLASS, &keyclass, sizeof(keyclass)); attrs++;
- PK11_SETATTRS(attrs, CKA_TOKEN, &ckTrue, sizeof(ckTrue)); attrs++;
+ 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++;
+ len = PORT_Strlen(nickname);
+ PK11_SETATTRS(attrs, CKA_LABEL, nickname, len);
+ attrs++;
}
tsize = attrs - findTemp;
- PORT_Assert(tsize <= sizeof(findTemp)/sizeof(CK_ATTRIBUTE));
+ PORT_Assert(tsize <= sizeof(findTemp) / sizeof(CK_ATTRIBUTE));
- key_ids = pk11_FindObjectsByTemplate(slot,findTemp,tsize,&objCount);
+ 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;
+ 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;
+ return key->cx;
}
-
/*
* extract a symetric key value. NOTE: if the key is sensitive, we will
@@ -596,21 +613,21 @@ PK11_ExtractKeyValue(PK11SymKey *symKey)
SECStatus rv;
if (symKey->data.data != NULL) {
- if (symKey->size == 0) {
- symKey->size = symKey->data.len;
- }
- return SECSuccess;
+ if (symKey->size == 0) {
+ symKey->size = symKey->data.len;
+ }
+ return SECSuccess;
}
if (symKey->slot == NULL) {
- PORT_SetError( SEC_ERROR_INVALID_KEY );
- return SECFailure;
+ PORT_SetError(SEC_ERROR_INVALID_KEY);
+ return SECFailure;
}
- rv = PK11_ReadAttribute(symKey->slot,symKey->objectID,CKA_VALUE,NULL,
- &symKey->data);
+ rv = PK11_ReadAttribute(symKey->slot, symKey->objectID, CKA_VALUE, NULL,
+ &symKey->data);
if (rv == SECSuccess) {
- symKey->size = symKey->data.len;
+ symKey->size = symKey->data.len;
}
return rv;
}
@@ -619,9 +636,9 @@ SECStatus
PK11_DeleteTokenSymKey(PK11SymKey *symKey)
{
if (!PK11_IsPermObject(symKey->slot, symKey->objectID)) {
- return SECFailure;
+ return SECFailure;
}
- PK11_DestroyTokenObject(symKey->slot,symKey->objectID);
+ PK11_DestroyTokenObject(symKey->slot, symKey->objectID);
symKey->objectID = CK_INVALID_HANDLE;
return SECSuccess;
}
@@ -639,7 +656,6 @@ __PK11_GetKeyData(PK11SymKey *symKey)
return PK11_GetKeyData(symKey);
}
-
/*
* PKCS #11 key Types with predefined length
*/
@@ -648,13 +664,26 @@ 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;
+ 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;
}
@@ -665,33 +694,35 @@ PK11_GetKeyLength(PK11SymKey *key)
{
CK_KEY_TYPE keyType;
- if (key->size != 0) return key->size;
+ 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);
+ 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;
+ (key->type == CKM_SSL3_PRE_MASTER_KEY_GEN)) {
+ key->size = 48;
}
- if( key->size != 0 ) return key->size;
+ 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;
+ 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;
- }
+ keyLength = PK11_ReadULongAttribute(key->slot, key->objectID, CKA_VALUE_LEN);
+ if (keyLength != CK_UNAVAILABLE_INFORMATION) {
+ key->size = (unsigned int)keyLength;
+ }
}
- return key->size;
+ return key->size;
}
/* return the strength of a key. This is different from length in that
@@ -699,77 +730,78 @@ PK11_GetKeyLength(PK11SymKey *key)
* 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;
+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;
}
@@ -780,36 +812,36 @@ PK11_GetKeyStrength(PK11SymKey *key, SECAlgorithmID *algid)
* into the new slot.
*/
PK11SymKey *
-pk11_CopyToSlotPerm(PK11SlotInfo *slot,CK_MECHANISM_TYPE type,
- CK_ATTRIBUTE_TYPE operation, CK_FLAGS flags,
- PRBool isPerm, PK11SymKey *symKey)
+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);
- }
+ 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);
+ 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);
+ 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)
+pk11_CopyToSlot(PK11SlotInfo *slot, CK_MECHANISM_TYPE type,
+ CK_ATTRIBUTE_TYPE operation, PK11SymKey *symKey)
{
- return pk11_CopyToSlotPerm(slot, type, operation, 0, PR_FALSE, symKey);
+ return pk11_CopyToSlotPerm(slot, type, operation, 0, PR_FALSE, symKey);
}
/*
@@ -818,7 +850,7 @@ pk11_CopyToSlot(PK11SlotInfo *slot,CK_MECHANISM_TYPE type,
*/
PK11SymKey *
pk11_ForceSlotMultiple(PK11SymKey *symKey, CK_MECHANISM_TYPE *type,
- int mechCount, CK_ATTRIBUTE_TYPE operation)
+ int mechCount, CK_ATTRIBUTE_TYPE operation)
{
PK11SlotInfo *slot = symKey->slot;
PK11SymKey *newKey = NULL;
@@ -826,25 +858,25 @@ pk11_ForceSlotMultiple(PK11SymKey *symKey, CK_MECHANISM_TYPE *type,
int i;
if (slot == NULL) {
- needToCopy = PR_TRUE;
+ needToCopy = PR_TRUE;
} else {
- i = 0;
- while ((i < mechCount) && (needToCopy == PR_FALSE)) {
- if (!PK11_DoesMechanism(slot,type[i])) {
- needToCopy = PR_TRUE;
- }
- i++;
- }
+ 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);
+ 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;
}
@@ -853,40 +885,40 @@ pk11_ForceSlotMultiple(PK11SymKey *symKey, CK_MECHANISM_TYPE *type,
* 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)
+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)
+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);
- }
+ if (perm) {
+ return PK11_ConvertSessionSymKeyToTokenSymKey(symKey, symKey->cx);
+ } else {
+ return PK11_ReferenceSymKey(symKey);
+ }
}
-
- return pk11_CopyToSlotPerm(slot, symKey->type,
- operation, flags, perm, 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
+ * 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
+ * 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.
@@ -898,50 +930,51 @@ PK11_MoveSymKey(PK11SlotInfo *slot, CK_ATTRIBUTE_TYPE operation,
*/
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)
+ 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]);
+ 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 */
+ CK_ULONG ck_key_size; /* only used for variable-length keys */
if (pk11_BadAttrFlags(attrFlags)) {
- PORT_SetError( SEC_ERROR_INVALID_ARGS );
- return NULL;
+ PORT_SetError(SEC_ERROR_INVALID_ARGS);
+ return NULL;
}
- if ((keySize != 0) && (type != CKM_DES3_CBC) &&
- (type !=CKM_DES3_CBC_PAD) && (type != CKM_DES3_ECB)) {
+ 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++;
+ 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++;
+ 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++;
+ 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));
+ PR_ASSERT(count <= sizeof(genTemplate) / sizeof(CK_ATTRIBUTE));
keyGenType = PK11_GetKeyGenWithSize(type, keySize);
if (keyGenType == CKM_FAKE_RANDOM) {
- PORT_SetError( SEC_ERROR_NO_MODULE );
+ PORT_SetError(SEC_ERROR_NO_MODULE);
return NULL;
}
symKey = PK11_KeyGenWithTemplate(slot, type, keyGenType,
@@ -954,10 +987,10 @@ pk11_TokenKeyGenWithFlagsAndKeyType(PK11SlotInfo *slot, CK_MECHANISM_TYPE type,
/*
* 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
+ *
+ * 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
@@ -968,11 +1001,11 @@ pk11_TokenKeyGenWithFlagsAndKeyType(PK11SlotInfo *slot, CK_MECHANISM_TYPE type,
*/
PK11SymKey *
PK11_TokenKeyGenWithFlags(PK11SlotInfo *slot, CK_MECHANISM_TYPE type,
- SECItem *param, int keySize, SECItem *keyid, CK_FLAGS opFlags,
- PK11AttrFlags attrFlags, void *wincx)
+ 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);
+ return pk11_TokenKeyGenWithFlagsAndKeyType(slot, type, param, -1, keySize,
+ keyid, opFlags, attrFlags, wincx);
}
/*
@@ -986,28 +1019,28 @@ PK11_TokenKeyGenWithFlags(PK11SlotInfo *slot, CK_MECHANISM_TYPE type,
*/
PK11SymKey *
PK11_TokenKeyGen(PK11SlotInfo *slot, CK_MECHANISM_TYPE type, SECItem *param,
- int keySize, SECItem *keyid, PRBool isToken, void *wincx)
+ int keySize, SECItem *keyid, PRBool isToken, void *wincx)
{
PK11SymKey *symKey;
- PRBool weird = PR_FALSE; /* hack for fortezza */
+ 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;
+ weird = PR_TRUE;
+ keySize = 0;
}
opFlags |= weird ? CKF_DECRYPT : CKF_ENCRYPT;
if (isToken) {
- attrFlags |= (PK11_ATTR_TOKEN | PK11_ATTR_PRIVATE);
+ attrFlags |= (PK11_ATTR_TOKEN | PK11_ATTR_PRIVATE);
}
- symKey = pk11_TokenKeyGenWithFlagsAndKeyType(slot, type, param,
- -1, keySize, keyid, opFlags, attrFlags, wincx);
+ symKey = pk11_TokenKeyGenWithFlagsAndKeyType(slot, type, param,
+ -1, keySize, keyid, opFlags, attrFlags, wincx);
if (symKey && weird) {
- PK11_SetFortezzaHack(symKey);
+ PK11_SetFortezzaHack(symKey);
}
return symKey;
@@ -1015,7 +1048,7 @@ PK11_TokenKeyGen(PK11SlotInfo *slot, CK_MECHANISM_TYPE type, SECItem *param,
PK11SymKey *
PK11_KeyGen(PK11SlotInfo *slot, CK_MECHANISM_TYPE type, SECItem *param,
- int keySize, void *wincx)
+ int keySize, void *wincx)
{
return PK11_TokenKeyGen(slot, type, param, keySize, 0, PR_FALSE, wincx);
}
@@ -1023,7 +1056,7 @@ PK11_KeyGen(PK11SlotInfo *slot, CK_MECHANISM_TYPE type, SECItem *param,
PK11SymKey *
PK11_KeyGenWithTemplate(PK11SlotInfo *slot, CK_MECHANISM_TYPE type,
CK_MECHANISM_TYPE keyGenType,
- SECItem *param, CK_ATTRIBUTE * attrs,
+ SECItem *param, CK_ATTRIBUTE *attrs,
unsigned int attrsCount, void *wincx)
{
PK11SymKey *symKey;
@@ -1044,25 +1077,25 @@ PK11_KeyGenWithTemplate(PK11SlotInfo *slot, CK_MECHANISM_TYPE type,
PORT_SetError(PK11_MapError(CKR_TEMPLATE_INCONSISTENT));
return NULL;
}
- keySize = * (CK_ULONG *) attrs[i].pValue;
+ keySize = *(CK_ULONG *)attrs[i].pValue;
break;
case CKA_TOKEN:
- if (attrs[i].pValue == NULL ||
+ 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;
+ 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 (!isToken && (slot == NULL || !PK11_DoesMechanism(slot, type))) {
+ PK11SlotInfo *bestSlot = PK11_GetBestSlot(type, wincx);
if (bestSlot == NULL) {
- PORT_SetError( SEC_ERROR_NO_MODULE );
+ PORT_SetError(SEC_ERROR_NO_MODULE);
return NULL;
}
symKey = pk11_CreateSymKey(bestSlot, type, !isToken, PR_TRUE, wincx);
@@ -1070,7 +1103,8 @@ PK11_KeyGenWithTemplate(PK11SlotInfo *slot, CK_MECHANISM_TYPE type,
} else {
symKey = pk11_CreateSymKey(slot, type, !isToken, PR_TRUE, wincx);
}
- if (symKey == NULL) return NULL;
+ if (symKey == NULL)
+ return NULL;
symKey->size = keySize;
symKey->origin = PK11_OriginGenerated;
@@ -1086,13 +1120,13 @@ PK11_KeyGenWithTemplate(PK11SlotInfo *slot, CK_MECHANISM_TYPE type,
/* Get session and perform locking */
if (isToken) {
- PK11_Authenticate(symKey->slot,PR_TRUE,wincx);
+ PK11_Authenticate(symKey->slot, PR_TRUE, wincx);
/* Should always be original slot */
- session = PK11_GetRWSession(symKey->slot);
+ session = PK11_GetRWSession(symKey->slot);
symKey->owner = PR_FALSE;
} else {
session = symKey->session;
- if (session != CK_INVALID_SESSION)
+ if (session != CK_INVALID_SESSION)
pk11_EnterKeyMonitor(symKey);
}
if (session == CK_INVALID_SESSION) {
@@ -1101,8 +1135,7 @@ PK11_KeyGenWithTemplate(PK11SlotInfo *slot, CK_MECHANISM_TYPE type,
return NULL;
}
- crv = PK11_GETTAB(symKey->slot)->C_GenerateKey(session,
- &mechanism, attrs, attrsCount, &symKey->objectID);
+ crv = PK11_GETTAB(symKey->slot)->C_GenerateKey(session, &mechanism, attrs, attrsCount, &symKey->objectID);
/* Release lock and session */
if (isToken) {
@@ -1113,25 +1146,24 @@ PK11_KeyGenWithTemplate(PK11SlotInfo *slot, CK_MECHANISM_TYPE type,
if (crv != CKR_OK) {
PK11_FreeSymKey(symKey);
- PORT_SetError( PK11_MapError(crv) );
+ 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);
+ return PK11_TokenKeyGen(slot, CKM_DES3_CBC, 0, 0, keyid, PR_TRUE, cx);
}
-PK11SymKey*
+PK11SymKey *
PK11_ConvertSessionSymKeyToTokenSymKey(PK11SymKey *symk, void *wincx)
{
- PK11SlotInfo* slot = symk->slot;
+ PK11SlotInfo *slot = symk->slot;
CK_ATTRIBUTE template[1];
CK_ATTRIBUTE *attrs = template;
CK_BBOOL cktrue = CK_TRUE;
@@ -1139,25 +1171,26 @@ PK11_ConvertSessionSymKeyToTokenSymKey(PK11SymKey *symk, void *wincx)
CK_OBJECT_HANDLE newKeyID;
CK_SESSION_HANDLE rwsession;
- PK11_SETATTRS(attrs, CKA_TOKEN, &cktrue, sizeof(cktrue)); attrs++;
+ 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;
+ PORT_SetError(SEC_ERROR_BAD_DATA);
+ return NULL;
}
crv = PK11_GETTAB(slot)->C_CopyObject(rwsession, symk->objectID,
- template, 1, &newKeyID);
+ template, 1, &newKeyID);
PK11_RestoreROSession(slot, rwsession);
if (crv != CKR_OK) {
- PORT_SetError( PK11_MapError(crv) );
+ PORT_SetError(PK11_MapError(crv));
return NULL;
}
return PK11_SymKeyFromHandle(slot, NULL /*parent*/, symk->origin,
- symk->type, newKeyID, PR_FALSE /*owner*/, NULL /*wincx*/);
+ symk->type, newKeyID, PR_FALSE /*owner*/, NULL /*wincx*/);
}
/*
@@ -1166,10 +1199,10 @@ PK11_ConvertSessionSymKeyToTokenSymKey(PK11SymKey *symk, void *wincx)
* Diffie-Hellman Ciphers. */
SECStatus
PK11_PubWrapSymKey(CK_MECHANISM_TYPE type, SECKEYPublicKey *pubKey,
- PK11SymKey *symKey, SECItem *wrappedKey)
+ PK11SymKey *symKey, SECItem *wrappedKey)
{
PK11SlotInfo *slot;
- CK_ULONG len = wrappedKey->len;
+ CK_ULONG len = wrappedKey->len;
PK11SymKey *newKey = NULL;
CK_OBJECT_HANDLE id;
CK_MECHANISM mechanism;
@@ -1178,19 +1211,19 @@ PK11_PubWrapSymKey(CK_MECHANISM_TYPE type, SECKEYPublicKey *pubKey,
CK_RV crv;
if (symKey == NULL) {
- PORT_SetError( SEC_ERROR_INVALID_ARGS );
- return SECFailure;
+ 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);
+ newKey = pk11_ForceSlot(symKey, type, CKA_ENCRYPT);
if (newKey != NULL) {
- symKey = newKey;
+ symKey = newKey;
}
if (symKey->slot == NULL) {
- PORT_SetError( SEC_ERROR_NO_MODULE );
- return SECFailure;
+ PORT_SetError(SEC_ERROR_NO_MODULE);
+ return SECFailure;
}
slot = symKey->slot;
@@ -1198,31 +1231,33 @@ PK11_PubWrapSymKey(CK_MECHANISM_TYPE type, SECKEYPublicKey *pubKey,
mechanism.pParameter = NULL;
mechanism.ulParameterLen = 0;
- id = PK11_ImportPublicKey(slot,pubKey,PR_FALSE);
+ 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);
+ }
+ 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);
+ PK11_FreeSymKey(newKey);
}
if (crv != CKR_OK) {
- PORT_SetError( PK11_MapError(crv) );
- return SECFailure;
+ 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
@@ -1230,7 +1265,7 @@ PK11_PubWrapSymKey(CK_MECHANISM_TYPE type, SECKEYPublicKey *pubKey,
*/
static SECStatus
pk11_HandWrap(PK11SymKey *wrappingKey, SECItem *param, CK_MECHANISM_TYPE type,
- SECItem *inKey, SECItem *outKey)
+ SECItem *inKey, SECItem *outKey)
{
PK11SlotInfo *slot;
CK_ULONG len;
@@ -1244,42 +1279,46 @@ pk11_HandWrap(PK11SymKey *wrappingKey, SECItem *param, CK_MECHANISM_TYPE type,
/* use NULL IV's for wrapping */
mech.mechanism = type;
if (param) {
- mech.pParameter = param->data;
- mech.ulParameterLen = param->len;
+ 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);
+ 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;
+ 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));
+ 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;
+ 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);
+ 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;
+ PORT_SetError(PK11_MapError(crv));
+ return SECFailure;
}
return SECSuccess;
}
@@ -1288,8 +1327,8 @@ pk11_HandWrap(PK11SymKey *wrappingKey, SECItem *param, CK_MECHANISM_TYPE type,
* This function does a symetric based wrap.
*/
SECStatus
-PK11_WrapSymKey(CK_MECHANISM_TYPE type, SECItem *param,
- PK11SymKey *wrappingKey, PK11SymKey *symKey, SECItem *wrappedKey)
+PK11_WrapSymKey(CK_MECHANISM_TYPE type, SECItem *param,
+ PK11SymKey *wrappingKey, PK11SymKey *symKey, SECItem *wrappedKey)
{
PK11SlotInfo *slot;
CK_ULONG len = wrappedKey->len;
@@ -1304,40 +1343,41 @@ PK11_WrapSymKey(CK_MECHANISM_TYPE type, SECItem *param,
/* 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;
- }
+ /* 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 */
@@ -1345,224 +1385,231 @@ PK11_WrapSymKey(CK_MECHANISM_TYPE type, SECItem *param,
mechanism.mechanism = type;
/* use NULL IV's for wrapping */
if (param == NULL) {
- param_save = param = PK11_ParamFromIV(type,NULL);
+ param_save = param = PK11_ParamFromIV(type, NULL);
}
if (param) {
- mechanism.pParameter = param->data;
- mechanism.ulParameterLen = param->len;
+ mechanism.pParameter = param->data;
+ mechanism.ulParameterLen = param->len;
} else {
- mechanism.pParameter = NULL;
- mechanism.ulParameterLen = 0;
+ mechanism.pParameter = NULL;
+ mechanism.ulParameterLen = 0;
}
len = wrappedKey->len;
- session = pk11_GetNewSession(slot,&owner);
- if (!owner || !(slot->isThreadSafe)) PK11_EnterSlotMonitor(slot);
+ 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);
+ 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);
+ /* 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);
+ 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)
+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);
+ 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)
+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;
+ 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);
+ 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)
+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;
+ 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++;
+ 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);
+ 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;
+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];
+ CK_ATTRIBUTE keyTemplate[MAX_TEMPL_ATTRS + MAX_ADD_ATTRS];
#undef MAX_ADD_ATTRS
- CK_ATTRIBUTE * attrs = keyTemplate;
+ CK_ATTRIBUTE *attrs = keyTemplate;
CK_SESSION_HANDLE session;
- unsigned int templateCount;
+ unsigned int templateCount;
if (numAttrs > MAX_TEMPL_ATTRS) {
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- return NULL;
+ PORT_SetError(SEC_ERROR_INVALID_ARGS);
+ return NULL;
}
/* first copy caller attributes in. */
for (templateCount = 0; templateCount < numAttrs; ++templateCount) {
- *attrs++ = *userAttr++;
+ *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++;
+ 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++;
+ 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++;
+ !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++;
+ !pk11_FindAttrInTemplate(keyTemplate, numAttrs, operation)) {
+ PK11_SETATTRS(attrs, operation, &cktrue, sizeof cktrue);
+ attrs++;
}
templateCount = attrs - keyTemplate;
- PR_ASSERT(templateCount <= sizeof(keyTemplate)/sizeof(CK_ATTRIBUTE));
+ 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 (!PK11_DoesMechanism(slot, derive)) {
+ /* get a new base key & slot */
+ PK11SlotInfo *newSlot = PK11_GetBestSlot(derive, baseKey->cx);
- if (newSlot == NULL) return NULL;
+ 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;
+ 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;
+ return NULL;
}
symKey->size = keySize;
mechanism.mechanism = derive;
if (param) {
- mechanism.pParameter = param->data;
- mechanism.ulParameterLen = param->len;
+ mechanism.pParameter = param->data;
+ mechanism.ulParameterLen = param->len;
} else {
- mechanism.pParameter = NULL;
- mechanism.ulParameterLen = 0;
+ mechanism.pParameter = NULL;
+ mechanism.ulParameterLen = 0;
}
- symKey->origin=PK11_OriginDerive;
+ symKey->origin = PK11_OriginDerive;
if (isPerm) {
- session = PK11_GetRWSession(slot);
+ session = PK11_GetRWSession(slot);
} else {
pk11_EnterKeyMonitor(symKey);
- session = symKey->session;
+ session = symKey->session;
}
if (session == CK_INVALID_SESSION) {
- if (!isPerm)
- pk11_ExitKeyMonitor(symKey);
- crv = CKR_SESSION_HANDLE_INVALID;
+ 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);
+ 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;
+ 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)
+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;
+ PORT_SetError(SEC_ERROR_INVALID_ARGS);
+ return NULL;
}
mechParams.pData = data;
@@ -1571,45 +1618,48 @@ static PK11SymKey *pk11_ConcatenateBaseAndData(PK11SymKey *base,
param.len = sizeof(CK_KEY_DERIVATION_STRING_DATA);
return PK11_Derive(base, CKM_CONCATENATE_BASE_AND_DATA,
- &param, target, operation, 0);
+ &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)
+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;
+ 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);
+ &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)
+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)
+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];
@@ -1621,70 +1671,70 @@ static PK11SymKey *pk11_ANSIX963Derive(PK11SymKey *sharedSecret,
PK11SymKey *oldIntermediateResult, *intermediateResult = NULL;
if (sharedSecret == NULL) {
- PORT_SetError( SEC_ERROR_INVALID_ARGS );
- return 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;
+ 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;
- }
+ 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;
+ PORT_SetError(SEC_ERROR_INVALID_ARGS);
+ return NULL;
}
maxCounter = derivedKeySize / HashLen;
if (derivedKeySize > maxCounter * HashLen)
- maxCounter++;
+ maxCounter++;
if ((sharedData == NULL) || (sharedData->data == NULL))
- SharedInfoLen = 0;
+ SharedInfoLen = 0;
else
- SharedInfoLen = sharedData->len;
+ 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;
+ PORT_SetError(SEC_ERROR_NO_MEMORY);
+ return NULL;
}
buffer[0] = 0;
@@ -1692,7 +1742,7 @@ static PK11SymKey *pk11_ANSIX963Derive(PK11SymKey *sharedSecret,
buffer[2] = 0;
buffer[3] = 1;
if (SharedInfoLen > 0) {
- PORT_Memcpy(&buffer[4], sharedData->data, SharedInfoLen);
+ PORT_Memcpy(&buffer[4], sharedData->data, SharedInfoLen);
}
/* Look for a slot that supports the mechanisms needed
@@ -1705,82 +1755,81 @@ static PK11SymKey *pk11_ANSIX963Derive(PK11SymKey *sharedSecret,
mechanismArray[3] = target;
newSharedSecret = pk11_ForceSlotMultiple(sharedSecret,
- mechanismArray, 4, operation);
+ 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]++;
+ 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);
+ PK11_FreeSymKey(newSharedSecret);
return intermediateResult;
loser:
- if (buffer != NULL)
- PORT_ZFree(buffer, bufferLen);
+ PORT_ZFree(buffer, bufferLen);
if (newSharedSecret != NULL)
- PK11_FreeSymKey(newSharedSecret);
+ PK11_FreeSymKey(newSharedSecret);
if (intermediateResult != NULL)
- PK11_FreeSymKey(intermediateResult);
+ PK11_FreeSymKey(intermediateResult);
return NULL;
}
@@ -1789,451 +1838,452 @@ loser:
* 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)
+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;
+ return NULL;
}
symKey->origin = PK11_OriginDerive;
switch (privKey->keyType) {
- case rsaKey:
- case rsaPssKey:
- case rsaOaepKey:
- 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;
+ case rsaKey:
+ case rsaPssKey:
+ case rsaOaepKey:
+ case nullKey:
+ PORT_SetError(SEC_ERROR_BAD_KEY);
+ break;
+ case dsaKey:
+ case keaKey:
+ case fortezzaKey: {
+ static unsigned char rb_email[128] = { 0 };
+ CK_KEA_DERIVE_PARAMS param;
+ param.isSender = (CK_BBOOL)isSender;
+ param.ulRandomLen = randomA->len;
+ param.pRandomA = randomA->data;
+ param.pRandomB = rb_email;
+ param.pRandomB[127] = 1;
+ 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)
+pk11_ECPubKeySize(SECKEYPublicKey *pubKey)
{
+ SECItem *publicValue = &pubKey->u.ec.publicValue;
+
+ if (pubKey->u.ec.encoding == ECPoint_XOnly) {
+ return publicValue->len;
+ }
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 encoded in uncompressed form */
+ return ((publicValue->len - 1) / 2);
}
/* key encoding not recognized */
- return(0);
+ 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;
+ 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;
+ 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;
+ (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;
+ 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));
+ 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);
+ 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;
- }
- }
+ 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);
+ 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;
+ PK11_FreeSymKey(symKey);
+ return NULL;
}
mechParams->kdf = kdf;
if (sharedData == NULL) {
- mechParams->ulSharedDataLen = 0;
- mechParams->pSharedData = NULL;
+ mechParams->ulSharedDataLen = 0;
+ mechParams->pSharedData = NULL;
} else {
- mechParams->ulSharedDataLen = sharedData->len;
- mechParams->pSharedData = sharedData->data;
+ mechParams->ulSharedDataLen = sharedData->len;
+ mechParams->pSharedData = sharedData->data;
}
- mechParams->ulPublicDataLen = pubKey->u.ec.publicValue.len;
- mechParams->pPublicData = pubKey->u.ec.publicValue.data;
+ mechParams->ulPublicDataLen = pubKey->u.ec.publicValue.len;
+ mechParams->pPublicData = pubKey->u.ec.publicValue.data;
- mechanism.mechanism = derive;
- mechanism.pParameter = mechParams;
+ 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);
+ 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);
+ 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);
+ 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) );
+ 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)
+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:
- PORT_SetError(SEC_ERROR_BAD_KEY);
- break;
+ 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:
+ PORT_SetError(SEC_ERROR_BAD_KEY);
+ break;
}
return NULL;
@@ -2246,9 +2296,9 @@ PK11_PubDeriveWithKDF(SECKEYPrivateKey *privKey, SECKEYPublicKey *pubKey,
*/
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_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;
@@ -2258,66 +2308,74 @@ pk11_HandUnwrap(PK11SlotInfo *slot, CK_OBJECT_HANDLE wrappingKey,
CK_SESSION_HANDLE session;
/* remove any VALUE_LEN parameters */
- if (keyTemplate[templateCount-1].type == CKA_VALUE_LEN) {
+ 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);
+ 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;
+ 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);
+ 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 (!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;
+ 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);
+ 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);
+ 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;
+ if (crvp)
+ *crvp = symKey ? CKR_OK : CKR_DEVICE_ERROR;
return symKey;
}
@@ -2328,311 +2386,319 @@ pk11_HandUnwrap(PK11SlotInfo *slot, CK_OBJECT_HANDLE wrappingKey,
*/
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_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_RV crv;
CK_MECHANISM_INFO mechanism_info;
#define MAX_ADD_ATTRS 4
- CK_ATTRIBUTE keyTemplate[MAX_TEMPL_ATTRS + MAX_ADD_ATTRS];
+ CK_ATTRIBUTE keyTemplate[MAX_TEMPL_ATTRS + MAX_ADD_ATTRS];
#undef MAX_ADD_ATTRS
- CK_ATTRIBUTE * attrs = keyTemplate;
- unsigned int templateCount;
+ CK_ATTRIBUTE *attrs = keyTemplate;
+ unsigned int templateCount;
if (numAttrs > MAX_TEMPL_ATTRS) {
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- return NULL;
+ PORT_SetError(SEC_ERROR_INVALID_ARGS);
+ return NULL;
}
/* first copy caller attributes in. */
for (templateCount = 0; templateCount < numAttrs; ++templateCount) {
- *attrs++ = *userAttr++;
+ *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++;
+ 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++;
+ 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++;
+ !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++;
+ !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));
-
+ 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;
+ 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 (!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;
- }
+ 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 == NULL)
+ param = param_free = PK11_ParamFromIV(wrapType, NULL);
if (param) {
- mechanism.pParameter = param->data;
- mechanism.ulParameterLen = param->len;
+ 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 */
+ 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;
+ if (param_free)
+ SECITEM_FreeItem(param_free, PR_TRUE);
+ return NULL;
}
symKey->size = keySize;
symKey->origin = PK11_OriginUnwrap;
if (isPerm) {
- rwsession = PK11_GetRWSession(slot);
+ rwsession = PK11_GetRWSession(slot);
} else {
pk11_EnterKeyMonitor(symKey);
- rwsession = symKey->session;
+ rwsession = symKey->session;
}
PORT_Assert(rwsession != CK_INVALID_SESSION);
- if (rwsession == CK_INVALID_SESSION)
- crv = CKR_SESSION_HANDLE_INVALID;
+ 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);
+ 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);
+ if (rwsession != CK_INVALID_SESSION)
+ PK11_RestoreROSession(slot, rwsession);
} else {
pk11_ExitKeyMonitor(symKey);
}
- if (param_free) SECITEM_FreeItem(param_free,PR_TRUE);
+ 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);
- }
- }
+ 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;
+ 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)
+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);
+ 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)
+ 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;
+ 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);
+ 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)
+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;
+ 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++;
+ PK11_SETATTRS(attrs, CKA_TOKEN, &cktrue, sizeof(CK_BBOOL));
+ attrs++;
}
- templateCount = attrs-keyTemplate;
+ 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);
+ 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 target, CK_ATTRIBUTE_TYPE operation, int keySize)
{
CK_MECHANISM_TYPE wrapType = pk11_mapWrapKeyType(wrappingKey->keyType);
- PK11SlotInfo *slot = wrappingKey->pkcs11Slot;
+ PK11SlotInfo *slot = wrappingKey->pkcs11Slot;
- if (SECKEY_HAS_ATTRIBUTE_SET(wrappingKey,CKA_PRIVATE)) {
- PK11_HandlePasswordCheck(slot,wrappingKey->wincx);
+ 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);
+ 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)
+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;
+ 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);
+ 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);
+ 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)
+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;
+ 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++;
+ PK11_SETATTRS(attrs, CKA_TOKEN, &cktrue, sizeof(CK_BBOOL));
+ attrs++;
}
- templateCount = attrs-keyTemplate;
+ templateCount = attrs - keyTemplate;
templateCount += pk11_OpFlagsToAttributes(flags, attrs, &cktrue);
- if (SECKEY_HAS_ATTRIBUTE_SET(wrappingKey,CKA_PRIVATE)) {
- PK11_HandlePasswordCheck(slot,wrappingKey->wincx);
+ 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);
+ wrapType, NULL, wrappedKey, target, operation, keySize,
+ wrappingKey->wincx, keyTemplate, templateCount, isPerm);
}
-PK11SymKey*
+PK11SymKey *
PK11_CopySymKeyForSigning(PK11SymKey *originalKey, CK_MECHANISM_TYPE mech)
{
CK_RV crv;
CK_ATTRIBUTE setTemplate;
- CK_BBOOL ckTrue = CK_TRUE;
+ 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);
+ crv = PK11_GETTAB(slot)->C_SetAttributeValue(originalKey->session,
+ originalKey->objectID, &setTemplate, 1);
pk11_ExitKeyMonitor(originalKey);
if (crv == CKR_OK) {
- return PK11_ReferenceSymKey(originalKey);
+ 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;
+
+void
+PK11_SetFortezzaHack(PK11SymKey *symKey)
+{
+ symKey->origin = PK11_OriginFortezzaHack;
}
/*
@@ -2640,7 +2706,7 @@ PK11_SetFortezzaHack(PK11SymKey *symKey) {
* working. This function simply gets a valid IV for the keys.
*/
SECStatus
-PK11_GenerateFortezzaIV(PK11SymKey *symKey,unsigned char *iv,int len)
+PK11_GenerateFortezzaIV(PK11SymKey *symKey, unsigned char *iv, int len)
{
CK_MECHANISM mech_info;
CK_ULONG count = 0;
@@ -2653,12 +2719,10 @@ PK11_GenerateFortezzaIV(PK11SymKey *symKey,unsigned char *iv,int len)
/* generate the IV for fortezza */
PK11_EnterSlotMonitor(symKey->slot);
- crv=PK11_GETTAB(symKey->slot)->C_EncryptInit(symKey->slot->session,
- &mech_info, symKey->objectID);
+ 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_GETTAB(symKey->slot)->C_EncryptFinal(symKey->slot->session, NULL, &count);
+ rv = SECSuccess;
}
PK11_ExitSlotMonitor(symKey->slot);
return rv;
@@ -2669,4 +2733,3 @@ PK11_GetSymKeyHandle(PK11SymKey *symKey)
{
return symKey->objectID;
}
-
diff --git a/nss/lib/pk11wrap/pk11slot.c b/nss/lib/pk11wrap/pk11slot.c
index d52c020..c66ae27 100644
--- a/nss/lib/pk11wrap/pk11slot.c
+++ b/nss/lib/pk11wrap/pk11slot.c
@@ -14,12 +14,11 @@
#include "secitem.h"
#include "secerr.h"
-#include "dev.h"
-#include "dev3hack.h"
+#include "dev.h"
+#include "dev3hack.h"
#include "pkim.h"
#include "utilpars.h"
-
/*************************************************************
* local static and global data
*************************************************************/
@@ -30,38 +29,38 @@
* to this table.
*/
const PK11DefaultArrayEntry PK11_DefaultArray[] = {
- { "RSA", SECMOD_RSA_FLAG, CKM_RSA_PKCS },
- { "DSA", SECMOD_DSA_FLAG, CKM_DSA },
- { "ECC", SECMOD_ECC_FLAG, CKM_ECDSA },
- { "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 },
+ { "RSA", SECMOD_RSA_FLAG, CKM_RSA_PKCS },
+ { "DSA", SECMOD_DSA_FLAG, CKM_DSA },
+ { "ECC", SECMOD_ECC_FLAG, CKM_ECDSA },
+ { "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]);
+const int num_pk11_default_mechanisms =
+ sizeof(PK11_DefaultArray) / sizeof(PK11_DefaultArray[0]);
const PK11DefaultArrayEntry *
PK11_GetDefaultArray(int *size)
{
if (size) {
- *size = num_pk11_default_mechanisms;
+ *size = num_pk11_default_mechanisms;
}
return PK11_DefaultArray;
}
@@ -70,7 +69,7 @@ PK11_GetDefaultArray(int *size)
* These slotlists are lists of modules which provide default support for
* a given algorithm or mechanism.
*/
-static PK11SlotList
+static PK11SlotList
pk11_seedSlotList,
pk11_camelliaSlotList,
pk11_aesSlotList,
@@ -90,28 +89,29 @@ static PK11SlotList
pk11_tlsSlotList,
pk11_randomSlotList,
pk11_sha256SlotList,
- pk11_sha512SlotList; /* slots do SHA512 and SHA384 */
+ pk11_sha512SlotList; /* slots do SHA512 and SHA384 */
/************************************************************
* Generic Slot List and Slot List element manipulations
************************************************************/
/*
- * allocate a new list
+ * allocate a new list
*/
PK11SlotList *
PK11_NewSlotList(void)
{
PK11SlotList *list;
-
+
list = (PK11SlotList *)PORT_Alloc(sizeof(PK11SlotList));
- if (list == NULL) return NULL;
+ 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;
+ PORT_Free(list);
+ return NULL;
}
return list;
@@ -126,18 +126,18 @@ PK11_FreeSlotListElement(PK11SlotList *list, PK11SlotListElement *le)
PRBool freeit = PR_FALSE;
if (list == NULL || le == NULL) {
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- return SECFailure;
+ PORT_SetError(SEC_ERROR_INVALID_ARGS);
+ return SECFailure;
}
PZ_Lock(list->lock);
if (le->refCount-- == 1) {
- freeit = PR_TRUE;
+ freeit = PR_TRUE;
}
PZ_Unlock(list->lock);
if (freeit) {
- PK11_FreeSlot(le->slot);
- PORT_Free(le);
+ PK11_FreeSlot(le->slot);
+ PORT_Free(le);
}
return SECSuccess;
}
@@ -145,15 +145,16 @@ PK11_FreeSlotListElement(PK11SlotList *list, PK11SlotListElement *le)
static void
pk11_FreeSlotListStatic(PK11SlotList *list)
{
- PK11SlotListElement *le, *next ;
- if (list == NULL) return;
+ PK11SlotListElement *le, *next;
+ if (list == NULL)
+ return;
- for (le = list->head ; le; le = next) {
- next = le->next;
- PK11_FreeSlotListElement(list,le);
+ for (le = list->head; le; le = next) {
+ next = le->next;
+ PK11_FreeSlotListElement(list, le);
}
if (list->lock) {
- PZ_DestroyLock(list->lock);
+ PZ_DestroyLock(list->lock);
}
list->lock = NULL;
list->head = NULL;
@@ -178,13 +179,14 @@ PK11_FreeSlotList(PK11SlotList *list)
* should be inserted to the head of the list.
*/
SECStatus
-PK11_AddSlotToList(PK11SlotList *list,PK11SlotInfo *slot, PRBool sorted)
+PK11_AddSlotToList(PK11SlotList *list, PK11SlotInfo *slot, PRBool sorted)
{
PK11SlotListElement *le;
PK11SlotListElement *element;
- le = (PK11SlotListElement *) PORT_Alloc(sizeof(PK11SlotListElement));
- if (le == NULL) return SECFailure;
+ le = (PK11SlotListElement *)PORT_Alloc(sizeof(PK11SlotListElement));
+ if (le == NULL)
+ return SECFailure;
le->slot = PK11_ReferenceSlot(slot);
le->prev = NULL;
@@ -205,8 +207,10 @@ PK11_AddSlotToList(PK11SlotList *list,PK11SlotInfo *slot, PRBool sorted)
le->next = NULL;
list->tail = le;
}
- if (le->prev) le->prev->next = le;
- if (list->head == element) list->head = le;
+ if (le->prev)
+ le->prev->next = le;
+ if (list->head == element)
+ list->head = le;
PZ_Unlock(list->lock);
return SECSuccess;
@@ -216,14 +220,20 @@ PK11_AddSlotToList(PK11SlotList *list,PK11SlotInfo *slot, PRBool sorted)
* remove a slot entry from the list
*/
SECStatus
-PK11_DeleteSlotFromList(PK11SlotList *list,PK11SlotListElement *le)
+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;
+ 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);
+ PK11_FreeSlotListElement(list, le);
return SECSuccess;
}
@@ -233,14 +243,15 @@ PK11_DeleteSlotFromList(PK11SlotList *list,PK11SlotListElement *le)
* lists. It also does not re-sort the target list.
*/
SECStatus
-pk11_MoveListToList(PK11SlotList *target,PK11SlotList *src)
+pk11_MoveListToList(PK11SlotList *target, PK11SlotList *src)
{
- if (src->head == NULL) return SECSuccess;
+ if (src->head == NULL)
+ return SECSuccess;
if (target->tail == NULL) {
- target->head = src->head;
+ target->head = src->head;
} else {
- target->tail->next = src->head;
+ target->tail->next = src->head;
}
src->head->prev = target->tail;
target->tail = src->tail;
@@ -257,7 +268,8 @@ PK11_GetFirstRef(PK11SlotList *list)
PK11SlotListElement *le;
le = list->head;
- if (le != NULL) (le)->refCount++;
+ if (le != NULL)
+ (le)->refCount++;
return le;
}
@@ -269,8 +281,9 @@ 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);
+ if (new_le)
+ new_le->refCount++;
+ PK11_FreeSlotListElement(list, le);
return new_le;
}
@@ -285,7 +298,8 @@ PK11_GetFirstSafe(PK11SlotList *list)
PZ_Lock(list->lock);
le = list->head;
- if (le != NULL) (le)->refCount++;
+ if (le != NULL)
+ (le)->refCount++;
PZ_Unlock(list->lock);
return le;
}
@@ -302,31 +316,32 @@ PK11_GetNextSafe(PK11SlotList *list, PK11SlotListElement *le, PRBool restart)
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++;
+ /* 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);
+ PK11_FreeSlotListElement(list, le);
return new_le;
}
-
/*
* Find the element that holds this slot
*/
PK11SlotListElement *
-PK11_FindSlotElement(PK11SlotList *list,PK11SlotInfo *slot)
+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;
+ le = PK11_GetNextSafe(list, le, PR_TRUE)) {
+ if (le->slot == slot)
+ return le;
}
return NULL;
}
@@ -343,21 +358,21 @@ PK11_NewSlotInfo(SECMODModule *mod)
PK11SlotInfo *slot;
slot = (PK11SlotInfo *)PORT_Alloc(sizeof(PK11SlotInfo));
- if (slot == NULL) return slot;
+ if (slot == NULL)
+ return slot;
- slot->sessionLock = mod->isThreadSafe ?
- PZ_NewLock(nssILockSession) : mod->refLock;
+ slot->sessionLock = mod->isThreadSafe ? PZ_NewLock(nssILockSession) : mod->refLock;
if (slot->sessionLock == NULL) {
- PORT_Free(slot);
- return 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;
+ if (mod->isThreadSafe) {
+ PZ_DestroyLock(slot->sessionLock);
+ }
+ PORT_Free(slot);
+ return NULL;
}
slot->freeSymKeysWithSessionHead = NULL;
slot->freeSymKeysHead = NULL;
@@ -393,7 +408,7 @@ PK11_NewSlotInfo(SECMODModule *mod)
slot->cert_count = 0;
slot->slot_name[0] = 0;
slot->token_name[0] = 0;
- PORT_Memset(slot->serial,' ',sizeof(slot->serial));
+ PORT_Memset(slot->serial, ' ', sizeof(slot->serial));
slot->module = NULL;
slot->authTransact = 0;
slot->authTime = LL_ZERO;
@@ -404,7 +419,7 @@ PK11_NewSlotInfo(SECMODModule *mod)
slot->nssToken = NULL;
return slot;
}
-
+
/* create a new reference to a slot so it doesn't go away */
PK11SlotInfo *
PK11_ReferenceSlot(PK11SlotInfo *slot)
@@ -417,52 +432,54 @@ PK11_ReferenceSlot(PK11SlotInfo *slot)
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);
- }
+ /* 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;
- }
+ 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);
- }
+ /* 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);
+ /* 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);
+ PK11_DestroySlot(slot);
}
}
void
-PK11_EnterSlotMonitor(PK11SlotInfo *slot) {
+PK11_EnterSlotMonitor(PK11SlotInfo *slot)
+{
PZ_Lock(slot->sessionLock);
}
void
-PK11_ExitSlotMonitor(PK11SlotInfo *slot) {
+PK11_ExitSlotMonitor(PK11SlotInfo *slot)
+{
PZ_Unlock(slot->sessionLock);
}
@@ -472,31 +489,32 @@ PK11_ExitSlotMonitor(PK11SlotInfo *slot) {
PRBool
SECMOD_HasRootCerts(void)
{
- SECMODModuleList *mlp;
- SECMODModuleList *modules;
- SECMODListLock *moduleLock = SECMOD_GetDefaultModuleListLock();
- int i;
- PRBool found = PR_FALSE;
+ 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;
+ 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);
@@ -507,20 +525,20 @@ SECMOD_HasRootCerts(void)
* Functions to find specific slots.
***********************************************************/
PK11SlotList *
-PK11_FindSlotsByNames(const char *dllName, const char* slotName,
- const char* tokenName, PRBool presentOnly)
+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;
+ PK11SlotList *slotList = NULL;
PRUint32 slotcount = 0;
SECStatus rv = SECSuccess;
if (!moduleLock) {
- PORT_SetError(SEC_ERROR_NOT_INITIALIZED);
- return slotList;
+ PORT_SetError(SEC_ERROR_NOT_INITIALIZED);
+ return slotList;
}
slotList = PK11_NewSlotList();
@@ -529,11 +547,17 @@ PK11_FindSlotsByNames(const char *dllName, const char* slotName,
return slotList;
}
- if ( ((NULL == dllName) || (0 == *dllName)) &&
+ if (((NULL == dllName) || (0 == *dllName)) &&
((NULL == slotName) || (0 == *slotName)) &&
- ((NULL == tokenName) || (0 == *tokenName)) ) {
+ ((NULL == tokenName) || (0 == *tokenName))) {
/* default to softoken */
- PK11_AddSlotToList(slotList, PK11_GetInternalKeySlot(), PR_TRUE);
+ /* PK11_GetInternalKeySlot increments the refcount on the internal slot,
+ * but so does PK11_AddSlotToList. To avoid erroneously increasing the
+ * refcount twice, we get our own reference to the internal slot and
+ * decrement its refcount when we're done with it. */
+ PK11SlotInfo *internalKeySlot = PK11_GetInternalKeySlot();
+ PK11_AddSlotToList(slotList, internalKeySlot, PR_TRUE);
+ PK11_FreeSlot(internalKeySlot);
return slotList;
}
@@ -547,30 +571,28 @@ PK11_FindSlotsByNames(const char *dllName, const char* slotName,
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);
+ (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) ||
- (0==PORT_Strcmp(tmpSlot->token_name, tokenName)) ) &&
- ( (!slotName) ||
- (0==PORT_Strcmp(tmpSlot->slot_name, slotName)) ) ) {
- if (tmpSlot) {
- PK11_AddSlotToList(slotList, tmpSlot, PR_TRUE);
- slotcount++;
- }
+ ((!tokenName) ||
+ (0 == PORT_Strcmp(tmpSlot->token_name, tokenName))) &&
+ ((!slotName) ||
+ (0 == PORT_Strcmp(tmpSlot->slot_name, slotName)))) {
+ PK11_AddSlotToList(slotList, tmpSlot, PR_TRUE);
+ slotcount++;
}
}
}
}
SECMOD_ReleaseReadLock(moduleLock);
- if ( (0 == slotcount) || (SECFailure == rv) ) {
+ if ((0 == slotcount) || (SECFailure == rv)) {
PORT_SetError(SEC_ERROR_NO_TOKEN);
PK11_FreeSlotList(slotList);
slotList = NULL;
@@ -586,78 +608,79 @@ PK11_FindSlotsByNames(const char *dllName, const char* slotName,
PK11SlotInfo *
PK11_FindSlotByName(const char *name)
{
- SECMODModuleList *mlp;
- SECMODModuleList *modules;
- SECMODListLock *moduleLock = SECMOD_GetDefaultModuleListLock();
- int i;
- PK11SlotInfo *slot = NULL;
+ 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;
+ 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);
+ 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;
+ 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;
+ 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);
+ PORT_SetError(SEC_ERROR_NO_TOKEN);
}
return slot;
@@ -668,8 +691,9 @@ PK11_FindSlotBySerial(char *serial)
* 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)
+CK_RV
+pk11_notify(CK_SESSION_HANDLE session, CK_NOTIFICATION event,
+ CK_VOID_PTR pdata)
{
return CKR_OK;
}
@@ -680,56 +704,57 @@ CK_RV pk11_notify(CK_SESSION_HANDLE session, CK_NOTIFICATION event,
* 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
+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;
+ 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;
+ 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);
+ 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 (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;
+ slot->session = rwsession;
}
return rwsession;
}
PRBool
-PK11_RWSessionHasLock(PK11SlotInfo *slot,CK_SESSION_HANDLE session_handle)
+PK11_RWSessionHasLock(PK11SlotInfo *slot, CK_SESSION_HANDLE session_handle)
{
PRBool hasLock;
- hasLock = (PRBool)(!slot->isThreadSafe ||
- (slot->defRWSession && slot->session != CK_INVALID_SESSION));
+ hasLock = (PRBool)(!slot->isThreadSafe ||
+ (slot->defRWSession && slot->session != CK_INVALID_SESSION));
return hasLock;
}
static PRBool
-pk11_RWSessionIsDefault(PK11SlotInfo *slot,CK_SESSION_HANDLE rwsession)
+pk11_RWSessionIsDefault(PK11SlotInfo *slot, CK_SESSION_HANDLE rwsession)
{
PRBool isDefault;
isDefault = (PRBool)(slot->session == rwsession &&
- slot->defRWSession &&
- slot->session != CK_INVALID_SESSION);
+ slot->defRWSession &&
+ slot->session != CK_INVALID_SESSION);
return isDefault;
}
@@ -739,15 +764,16 @@ pk11_RWSessionIsDefault(PK11SlotInfo *slot,CK_SESSION_HANDLE rwsession)
* session is RW or the slot is not thread safe.
*/
void
-PK11_RestoreROSession(PK11SlotInfo *slot,CK_SESSION_HANDLE rwsession)
+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);
+ PRBool doExit = PK11_RWSessionHasLock(slot, rwsession);
+ if (!pk11_RWSessionIsDefault(slot, rwsession))
+ PK11_GETTAB(slot)
+ ->C_CloseSession(rwsession);
+ if (doExit)
+ PK11_ExitSlotMonitor(slot);
}
}
@@ -764,7 +790,6 @@ pk11_InitSlotListStatic(PK11SlotList *list)
list->head = NULL;
}
-
/* initialize the system slotlists */
SECStatus
PK11_InitSlotLists(void)
@@ -828,71 +853,71 @@ PK11_GetSlotList(CK_MECHANISM_TYPE 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_CCM:
- case CKM_AES_CTR:
- case CKM_AES_CTS:
- case CKM_AES_GCM:
- 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:
- case CKM_NSS_TLS_KEY_AND_MAC_DERIVE_SHA256:
- return &pk11_tlsSlotList;
- case CKM_IDEA_CBC:
- case CKM_IDEA_ECB:
- return &pk11_ideaSlotList;
- case CKM_FAKE_RANDOM:
- return &pk11_randomSlotList;
+ 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_CCM:
+ case CKM_AES_CTR:
+ case CKM_AES_CTS:
+ case CKM_AES_GCM:
+ 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:
+ case CKM_NSS_TLS_KEY_AND_MAC_DERIVE_SHA256:
+ return &pk11_tlsSlotList;
+ case CKM_IDEA_CBC:
+ case CKM_IDEA_ECB:
+ return &pk11_ideaSlotList;
+ case CKM_FAKE_RANDOM:
+ return &pk11_randomSlotList;
}
return NULL;
}
@@ -907,12 +932,13 @@ PK11_LoadSlotList(PK11SlotInfo *slot, PK11PreSlotInfo *psi, int count)
{
int i;
- for (i=0; i < count; i++) {
- if (psi[i].slotID == slot->slotID)
- break;
+ for (i = 0; i < count; i++) {
+ if (psi[i].slotID == slot->slotID)
+ break;
}
- if (i == count) return;
+ if (i == count)
+ return;
slot->defaultFlags = psi[i].defaultFlags;
slot->askpw = psi[i].askpw;
@@ -922,29 +948,30 @@ PK11_LoadSlotList(PK11SlotInfo *slot, PK11PreSlotInfo *psi, int count)
/* 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 (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;
+ 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);
+ 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);
- }
+ 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
@@ -953,25 +980,25 @@ SECStatus
PK11_UpdateSlotAttribute(PK11SlotInfo *slot,
const PK11DefaultArrayEntry *entry,
PRBool add)
- /* add: PR_TRUE if want to turn on */
+/* 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)
+ if (slotList != NULL)
result = PK11_AddSlotToList(slotList, slot, PR_FALSE);
-
+
} else { /* trying to turn off */
-
- /* turn OFF the flag in the slot */
+
+ /* 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);
@@ -992,26 +1019,28 @@ PK11_ClearSlotList(PK11SlotInfo *slot)
{
int i;
- if (slot->disabled) return;
- if (slot->defaultFlags == 0) return;
+ 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;
+ 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 (slotList)
+ le = PK11_FindSlotElement(slotList, slot);
- if (le) {
- PK11_DeleteSlotFromList(slotList,le);
- PK11_FreeSlotListElement(slotList,le);
- }
- }
+ if (le) {
+ PK11_DeleteSlotFromList(slotList, le);
+ PK11_FreeSlotListElement(slotList, le);
+ }
+ }
}
}
-
/******************************************************************
* Slot initialization
******************************************************************/
@@ -1019,29 +1048,32 @@ PK11_ClearSlotList(PK11SlotInfo *slot)
* turn a PKCS11 Static Label into a string
*/
char *
-PK11_MakeString(PLArenaPool *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;
+PK11_MakeString(PLArenaPool *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;
}
/*
@@ -1055,42 +1087,46 @@ PK11_ReadMechanismList(PK11SlotInfo *slot)
PRUint32 i;
if (slot->mechanismList) {
- PORT_Free(slot->mechanismList);
- slot->mechanismList = NULL;
+ 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 (!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;
+ 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));
+ PORT_Alloc(count * sizeof(CK_MECHANISM_TYPE));
if (slot->mechanismList == NULL) {
- if (!slot->isThreadSafe) PK11_ExitSlotMonitor(slot);
- return SECFailure;
+ 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);
+ 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;
+ 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);
- }
+ 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;
}
@@ -1110,171 +1146,179 @@ PK11_InitToken(PK11SlotInfo *slot, PRBool loadCerts)
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 (!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;
+ 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->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->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);
+ ((tokenInfo.flags & CKF_PROTECTED_AUTHENTICATION_PATH)
+ ? PR_TRUE
+ : PR_FALSE);
slot->lastLoginCheck = 0;
slot->lastState = 0;
- /* on some platforms Active Card incorrectly sets the
+ /* 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;
+ slot->protectedAuthPath = PR_FALSE;
}
- (void)PK11_MakeString(NULL,slot->token_name,
- (char *)tokenInfo.label, sizeof(tokenInfo.label));
+ (void)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));
+ PORT_Memcpy(slot->serial, tokenInfo.serialNumber, sizeof(slot->serial));
nssToken_UpdateName(slot->nssToken);
- slot->defRWSession = (PRBool)((!slot->readOnly) &&
- (tokenInfo.ulMaxSessionCount == 1));
+ slot->defRWSession = (PRBool)((!slot->readOnly) &&
+ (tokenInfo.ulMaxSessionCount == 1));
rv = PK11_ReadMechanismList(slot);
- if (rv != SECSuccess) return rv;
+ 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 */
+ 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;
+ /* don't have enough sessions to keep that many keys around */
+ slot->maxKeyCount = 0;
} else {
- slot->maxKeyCount = tokenInfo.ulMaxSessionCount/2;
+ 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;
+ /* 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;
+ /* 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 (!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);
+ 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;
+ 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);
- }
+ /* 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);
- }
- }
-
+ 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;
}
@@ -1291,33 +1335,34 @@ PK11_TokenRefresh(PK11SlotInfo *slot)
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 (!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;
+ 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->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
+ ((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;
+ slot->protectedAuthPath = PR_FALSE;
}
return SECSuccess;
}
static PRBool
-pk11_isRootSlot(PK11SlotInfo *slot)
+pk11_isRootSlot(PK11SlotInfo *slot)
{
CK_ATTRIBUTE findTemp[1];
CK_ATTRIBUTE *attrs;
@@ -1326,13 +1371,14 @@ pk11_isRootSlot(PK11SlotInfo *slot)
CK_OBJECT_HANDLE handle;
attrs = findTemp;
- PK11_SETATTRS(attrs, CKA_CLASS, &oclass, sizeof(oclass)); attrs++;
+ PK11_SETATTRS(attrs, CKA_CLASS, &oclass, sizeof(oclass));
+ attrs++;
tsize = attrs - findTemp;
- PORT_Assert(tsize <= sizeof(findTemp)/sizeof(CK_ATTRIBUTE));
+ PORT_Assert(tsize <= sizeof(findTemp) / sizeof(CK_ATTRIBUTE));
- handle = pk11_FindObjectByTemplate(slot,findTemp,tsize);
+ handle = pk11_FindObjectByTemplate(slot, findTemp, tsize);
if (handle == CK_INVALID_HANDLE) {
- return PR_FALSE;
+ return PR_FALSE;
}
return PR_TRUE;
}
@@ -1356,63 +1402,61 @@ PK11_InitSlot(SECMODModule *mod, CK_SLOT_ID slotID, PK11SlotInfo *slot)
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;
+
+ 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 */
- (void)PK11_MakeString(NULL,slot->slot_name,
- (char *)slotInfo.slotDescription, sizeof(slotInfo.slotDescription));
+ * 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 */
+ (void)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);
+ 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 */
- }
+ 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;
- }
+ 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
+ * we have a valid session handle. Also set the value of needLogin
* appropriately.
*/
static PRBool
@@ -1424,53 +1468,62 @@ pk11_IsPresentCertLoad(PK11SlotInfo *slot, PRBool loadCerts)
/* disabled slots are never present */
if (slot->disabled) {
- return PR_FALSE;
+ return PR_FALSE;
}
/* permanent slots are always present */
if (slot->isPerm && (slot->session != CK_INVALID_SESSION)) {
- return PR_TRUE;
+ return PR_TRUE;
}
if (slot->nssToken) {
- return nssToken_IsPresent(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 (!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;
+ /* 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_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);
+ 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;
+ if (slot->session != CK_INVALID_SESSION)
+ return PR_TRUE;
/* initialize the token info state */
- if (PK11_InitToken(slot,loadCerts) != SECSuccess) {
- return PR_FALSE;
+ if (PK11_InitToken(slot, loadCerts) != SECSuccess) {
+ return PR_FALSE;
}
return PR_TRUE;
@@ -1480,8 +1533,9 @@ pk11_IsPresentCertLoad(PK11SlotInfo *slot, PRBool loadCerts)
* old version of the routine
*/
PRBool
-PK11_IsPresent(PK11SlotInfo *slot) {
- return pk11_IsPresentCertLoad(slot,PR_TRUE);
+PK11_IsPresent(PK11SlotInfo *slot)
+{
+ return pk11_IsPresentCertLoad(slot, PR_TRUE);
}
/* is the slot disabled? */
@@ -1500,22 +1554,26 @@ PK11_GetDisabledReason(PK11SlotInfo *slot)
/* returns PR_TRUE if successfully disable the slot */
/* returns PR_FALSE otherwise */
-PRBool PK11_UserDisableSlot(PK11SlotInfo *slot) {
+PRBool
+PK11_UserDisableSlot(PK11SlotInfo *slot)
+{
/* Prevent users from disabling the internal module. */
if (slot->isInternal) {
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- return PR_FALSE;
+ PORT_SetError(SEC_ERROR_INVALID_ARGS);
+ return PR_FALSE;
}
slot->defaultFlags |= PK11_DISABLE_FLAG;
slot->disabled = PR_TRUE;
slot->reason = PK11_DIS_USER_SELECTED;
-
+
return PR_TRUE;
}
-PRBool PK11_UserEnableSlot(PK11SlotInfo *slot) {
+PRBool
+PK11_UserEnableSlot(PK11SlotInfo *slot)
+{
slot->defaultFlags &= ~PK11_DISABLE_FLAG;
slot->disabled = PR_FALSE;
@@ -1523,7 +1581,9 @@ PRBool PK11_UserEnableSlot(PK11SlotInfo *slot) {
return PR_TRUE;
}
-PRBool PK11_HasRootCerts(PK11SlotInfo *slot) {
+PRBool
+PK11_HasRootCerts(PK11SlotInfo *slot)
+{
return slot->hasRootCerts;
}
@@ -1531,14 +1591,14 @@ PRBool PK11_HasRootCerts(PK11SlotInfo *slot) {
SECMODModule *
PK11_GetModule(PK11SlotInfo *slot)
{
- return slot->module;
+ return slot->module;
}
/* return the default flags of a slot */
unsigned long
PK11_GetDefaultFlags(PK11SlotInfo *slot)
{
- return slot->defaultFlags;
+ return slot->defaultFlags;
}
/*
@@ -1575,7 +1635,7 @@ PK11_IsInternalKeySlot(PK11SlotInfo *slot)
PRBool result;
if (!slot->isInternal) {
- return PR_FALSE;
+ return PR_FALSE;
}
int_slot = PK11_GetInternalKeySlot();
@@ -1594,21 +1654,21 @@ PRBool
PK11_IsFriendly(PK11SlotInfo *slot)
{
/* internal slot always has public readable certs */
- return (PRBool)(slot->isInternal ||
- ((slot->defaultFlags & SECMOD_FRIENDLY_FLAG) ==
- SECMOD_FRIENDLY_FLAG));
+ return (PRBool)(slot->isInternal ||
+ ((slot->defaultFlags & SECMOD_FRIENDLY_FLAG) ==
+ SECMOD_FRIENDLY_FLAG));
}
char *
PK11_GetTokenName(PK11SlotInfo *slot)
{
- return slot->token_name;
+ return slot->token_name;
}
char *
PK11_GetSlotName(PK11SlotInfo *slot)
{
- return slot->slot_name;
+ return slot->slot_name;
}
int
@@ -1643,12 +1703,12 @@ pk11_zeroTerminatedToBlankPadded(CK_CHAR *buffer, size_t buffer_size)
/* find the NULL */
while (walk < end && *walk != '\0') {
- walk++;
+ walk++;
}
/* clear out the buffer */
while (walk < end) {
- *walk++ = ' ';
+ *walk++ = ' ';
}
}
@@ -1658,22 +1718,24 @@ PK11_GetSlotInfo(PK11SlotInfo *slot, CK_SLOT_INFO *info)
{
CK_RV crv;
- if (!slot->isThreadSafe) PK11_EnterSlotMonitor(slot);
+ if (!slot->isThreadSafe)
+ PK11_EnterSlotMonitor(slot);
/*
- * some buggy drivers do not fill the buffer completely,
+ * 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);
+ 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));
+ sizeof(info->slotDescription));
pk11_zeroTerminatedToBlankPadded(info->manufacturerID,
- sizeof(info->manufacturerID));
- if (!slot->isThreadSafe) PK11_ExitSlotMonitor(slot);
+ sizeof(info->manufacturerID));
+ if (!slot->isThreadSafe)
+ PK11_ExitSlotMonitor(slot);
if (crv != CKR_OK) {
- PORT_SetError(PK11_MapError(crv));
- return SECFailure;
+ PORT_SetError(PK11_MapError(crv));
+ return SECFailure;
}
return SECSuccess;
}
@@ -1683,26 +1745,28 @@ SECStatus
PK11_GetTokenInfo(PK11SlotInfo *slot, CK_TOKEN_INFO *info)
{
CK_RV crv;
- if (!slot->isThreadSafe) PK11_EnterSlotMonitor(slot);
+ if (!slot->isThreadSafe)
+ PK11_EnterSlotMonitor(slot);
/*
- * some buggy drivers do not fill the buffer completely,
+ * 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));
+ 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));
+ sizeof(info->manufacturerID));
+ pk11_zeroTerminatedToBlankPadded(info->model, sizeof(info->model));
pk11_zeroTerminatedToBlankPadded(info->serialNumber,
- sizeof(info->serialNumber));
- if (!slot->isThreadSafe) PK11_ExitSlotMonitor(slot);
+ sizeof(info->serialNumber));
+ if (!slot->isThreadSafe)
+ PK11_ExitSlotMonitor(slot);
if (crv != CKR_OK) {
- PORT_SetError(PK11_MapError(crv));
- return SECFailure;
+ PORT_SetError(PK11_MapError(crv));
+ return SECFailure;
}
return SECSuccess;
}
@@ -1711,18 +1775,17 @@ PK11_GetTokenInfo(PK11SlotInfo *slot, CK_TOKEN_INFO *info)
PRBool
PK11_NeedUserInit(PK11SlotInfo *slot)
{
- PRBool needUserInit = (PRBool) ((slot->flags & CKF_USER_PIN_INITIALIZED)
- == 0);
+ PRBool needUserInit = (PRBool)((slot->flags & CKF_USER_PIN_INITIALIZED) == 0);
if (needUserInit) {
- CK_TOKEN_INFO info;
- SECStatus rv;
+ 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;
- }
+ /* 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);
}
@@ -1737,10 +1800,10 @@ static PK11SlotInfo *pk11InternalKeySlot = NULL;
void
pk11_SetInternalKeySlot(PK11SlotInfo *slot)
{
- if (pk11InternalKeySlot) {
- PK11_FreeSlot(pk11InternalKeySlot);
- }
- pk11InternalKeySlot = slot ? PK11_ReferenceSlot(slot) : NULL;
+ if (pk11InternalKeySlot) {
+ PK11_FreeSlot(pk11InternalKeySlot);
+ }
+ pk11InternalKeySlot = slot ? PK11_ReferenceSlot(slot) : NULL;
}
/*
@@ -1751,10 +1814,10 @@ pk11_SetInternalKeySlot(PK11SlotInfo *slot)
void
pk11_SetInternalKeySlotIfFirst(PK11SlotInfo *slot)
{
- if (pk11InternalKeySlot) {
- return;
- }
- pk11InternalKeySlot = slot ? PK11_ReferenceSlot(slot) : NULL;
+ if (pk11InternalKeySlot) {
+ return;
+ }
+ pk11InternalKeySlot = slot ? PK11_ReferenceSlot(slot) : NULL;
}
/*
@@ -1763,13 +1826,12 @@ pk11_SetInternalKeySlotIfFirst(PK11SlotInfo *slot)
PK11SlotInfo *
pk11_SwapInternalKeySlot(PK11SlotInfo *slot)
{
- PK11SlotInfo *swap = pk11InternalKeySlot;
+ PK11SlotInfo *swap = pk11InternalKeySlot;
- pk11InternalKeySlot = slot ? PK11_ReferenceSlot(slot) : NULL;
- return swap;
+ 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 *
@@ -1778,30 +1840,30 @@ PK11_GetInternalKeySlot(void)
SECMODModule *mod;
if (pk11InternalKeySlot) {
- return PK11_ReferenceSlot(pk11InternalKeySlot);
+ return PK11_ReferenceSlot(pk11InternalKeySlot);
}
mod = SECMOD_GetInternalModule();
PORT_Assert(mod != NULL);
if (!mod) {
- PORT_SetError( SEC_ERROR_NO_MODULE );
- return NULL;
+ 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)
+PK11_GetInternalSlot(void)
{
- SECMODModule * mod = SECMOD_GetInternalModule();
+ SECMODModule *mod = SECMOD_GetInternalModule();
PORT_Assert(mod != NULL);
if (!mod) {
- PORT_SetError( SEC_ERROR_NO_MODULE );
- return NULL;
+ PORT_SetError(SEC_ERROR_NO_MODULE);
+ return NULL;
}
if (mod->isFIPS) {
- return PK11_GetInternalKeySlot();
+ return PK11_GetInternalKeySlot();
}
return PK11_ReferenceSlot(mod->slots[0]);
}
@@ -1818,17 +1880,17 @@ PK11_DoesMechanism(PK11SlotInfo *slot, CK_MECHANISM_TYPE type)
* tell us we're looking form someone that has implemented get
* random bits */
if (type == CKM_FAKE_RANDOM) {
- return slot->hasRandom;
+ 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;
+ 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;
+
+ for (i = 0; i < (int)slot->mechanismCount; i++) {
+ if (slot->mechanismList[i] == type)
+ return PR_TRUE;
}
return PR_FALSE;
}
@@ -1849,31 +1911,32 @@ PK11_TokenExists(CK_MECHANISM_TYPE type)
int i;
if (!moduleLock) {
- PORT_SetError(SEC_ERROR_NOT_INITIALIZED);
- return found;
+ 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
+ * 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);
+ found = PK11_DoesMechanism(slot, type);
+ PK11_FreeSlot(slot);
}
- if (found) return PR_TRUE; /* bypass getting module locks */
+ 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;
- }
- }
- }
+ 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;
@@ -1886,104 +1949,108 @@ PK11_TokenExists(CK_MECHANISM_TYPE type)
* the end of this list.
*/
PK11SlotList *
-PK11_GetAllTokens(CK_MECHANISM_TYPE type, PRBool needRW, PRBool loadCerts,
+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];
+ 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();
+ moduleLock = SECMOD_GetDefaultModuleListLock();
if (!moduleLock) {
- PORT_SetError(SEC_ERROR_NOT_INITIALIZED);
- return NULL;
+ PORT_SetError(SEC_ERROR_NOT_INITIALIZED);
+ return NULL;
}
- list = PK11_NewSlotList();
- loginList = PK11_NewSlotList();
+ 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;
+ 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++;
+ 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);
- }
- }
- }
- }
+ 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_MoveListToList(list, friendlyList);
PK11_FreeSlotList(friendlyList);
- pk11_MoveListToList(list,loginList);
+ pk11_MoveListToList(list, loginList);
PK11_FreeSlotList(loginList);
return list;
}
/*
- * NOTE: This routine is working from a private List generated by
+ * 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)
+PK11_GetPrivateKeyTokens(CK_MECHANISM_TYPE type, PRBool needRW, void *wincx)
{
- PK11SlotList *list = PK11_GetAllTokens(type,needRW,PR_TRUE,wincx);
- PK11SlotListElement *le, *next ;
+ PK11SlotList *list = PK11_GetAllTokens(type, needRW, PR_TRUE, wincx);
+ PK11SlotListElement *le, *next;
SECStatus rv;
- if (list == NULL) return list;
+ 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;
- }
+ 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;
}
@@ -1992,8 +2059,8 @@ PK11_GetPrivateKeyTokens(CK_MECHANISM_TYPE type,PRBool needRW,void *wincx)
* 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)
+pk11_filterSlot(PK11SlotInfo *slot, CK_MECHANISM_TYPE mechanism,
+ CK_FLAGS mechanismInfoFlags, unsigned int keySize)
{
CK_MECHANISM_INFO mechanism_info;
CK_RV crv = CKR_OK;
@@ -2001,53 +2068,52 @@ pk11_filterSlot(PK11SlotInfo *slot, CK_MECHANISM_TYPE mechanism,
/* 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;
+ 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;
- }
+ 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 (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 (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;
+ 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
+ * 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
+ * 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)
+PK11_GetBestSlotMultipleWithAttributes(CK_MECHANISM_TYPE *type,
+ CK_FLAGS *mechanismInfoFlags, unsigned int *keySize,
+ unsigned int mech_count, void *wincx)
{
PK11SlotList *list = NULL;
- PK11SlotListElement *le ;
+ PK11SlotListElement *le;
PK11SlotInfo *slot = NULL;
PRBool freeit = PR_FALSE;
PRBool listNeedLogin = PR_FALSE;
@@ -2057,81 +2123,86 @@ PK11_GetBestSlotMultipleWithAttributes(CK_MECHANISM_TYPE *type,
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;
+ /* 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(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 (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); }
+ 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);
+ PORT_SetError(SEC_ERROR_NO_TOKEN);
}
return NULL;
}
PK11SlotInfo *
-PK11_GetBestSlotMultiple(CK_MECHANISM_TYPE *type,
- unsigned int mech_count, void *wincx)
+PK11_GetBestSlotMultiple(CK_MECHANISM_TYPE *type,
+ unsigned int mech_count, void *wincx)
{
- return PK11_GetBestSlotMultipleWithAttributes(type, NULL, NULL,
- mech_count, wincx);
+ return PK11_GetBestSlotMultipleWithAttributes(type, NULL, NULL,
+ mech_count, wincx);
}
/* original get best slot now calls the multiple version with only one type */
@@ -2143,30 +2214,32 @@ PK11_GetBestSlot(CK_MECHANISM_TYPE type, void *wincx)
PK11SlotInfo *
PK11_GetBestSlotWithAttributes(CK_MECHANISM_TYPE type, CK_FLAGS mechanismFlags,
- unsigned int keySize, void *wincx)
+ unsigned int keySize, void *wincx)
{
return PK11_GetBestSlotMultipleWithAttributes(&type, &mechanismFlags,
- &keySize, 1, wincx);
+ &keySize, 1, wincx);
}
int
-PK11_GetBestKeyLength(PK11SlotInfo *slot,CK_MECHANISM_TYPE mechanism)
+PK11_GetBestKeyLength(PK11SlotInfo *slot, CK_MECHANISM_TYPE mechanism)
{
CK_MECHANISM_INFO mechanism_info;
CK_RV crv;
- if (!slot->isThreadSafe) PK11_EnterSlotMonitor(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) return 0;
-
- if (mechanism_info.ulMinKeySize == mechanism_info.ulMaxKeySize)
- return 0;
+ 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.
@@ -2183,73 +2256,77 @@ PK11_GetMaxKeyLength(CK_MECHANISM_TYPE mechanism)
{
CK_MECHANISM_INFO mechanism_info;
PK11SlotList *list = NULL;
- PK11SlotListElement *le ;
+ 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;
+ /* 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;
+ 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);
+ 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) {
+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;
+ PORT_SetError(PK11_MapError(crv));
+ return SECFailure;
}
return SECSuccess;
}
-
SECStatus
-PK11_GenerateRandomOnSlot(PK11SlotInfo *slot, unsigned char *data, int len) {
+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 (!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;
+ PORT_SetError(PK11_MapError(crv));
+ return SECFailure;
}
return SECSuccess;
}
@@ -2263,14 +2340,14 @@ SECStatus
PK11_RandomUpdate(void *data, size_t bytes)
{
PK11SlotInfo *slot;
- PRBool bestIsInternal;
- SECStatus status;
+ PRBool bestIsInternal;
+ SECStatus status;
slot = PK11_GetBestSlot(CKM_FAKE_RANDOM, NULL);
if (slot == NULL) {
- slot = PK11_GetInternalSlot();
- if (!slot)
- return SECFailure;
+ slot = PK11_GetInternalSlot();
+ if (!slot)
+ return SECFailure;
}
bestIsInternal = PK11_IsInternal(slot);
@@ -2278,22 +2355,23 @@ PK11_RandomUpdate(void *data, size_t 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);
+ /* 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) {
+PK11_GenerateRandom(unsigned char *data, int len)
+{
PK11SlotInfo *slot;
SECStatus rv;
- slot = PK11_GetBestSlot(CKM_FAKE_RANDOM,NULL);
- if (slot == NULL) return SECFailure;
+ slot = PK11_GetBestSlot(CKM_FAKE_RANDOM, NULL);
+ if (slot == NULL)
+ return SECFailure;
rv = PK11_GenerateRandomOnSlot(slot, data, len);
PK11_FreeSlot(slot);
@@ -2304,7 +2382,7 @@ PK11_GenerateRandom(unsigned char *data,int len) {
* 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
+SECStatus
PK11_ResetToken(PK11SlotInfo *slot, char *sso_pwd)
{
unsigned char tokenName[32];
@@ -2314,92 +2392,93 @@ PK11_ResetToken(PK11SlotInfo *slot, char *sso_pwd)
/* reconstruct the token name */
tokenNameLen = PORT_Strlen(slot->token_name);
if (tokenNameLen > sizeof(tokenName)) {
- tokenNameLen = sizeof(tokenName);
+ tokenNameLen = sizeof(tokenName);
}
- PORT_Memcpy(tokenName,slot->token_name,tokenNameLen);
+ PORT_Memcpy(tokenName, slot->token_name, tokenNameLen);
if (tokenNameLen < sizeof(tokenName)) {
- PORT_Memset(&tokenName[tokenNameLen],' ',
- sizeof(tokenName)-tokenNameLen);
+ PORT_Memset(&tokenName[tokenNameLen], ' ',
+ sizeof(tokenName) - tokenNameLen);
}
- /* initialize the token */
+ /* initialize the token */
PK11_EnterSlotMonitor(slot);
/* first shutdown the token. Existing sessions will get closed here */
- PK11_GETTAB(slot)->C_CloseAllSessions(slot->slotID);
+ PK11_GETTAB(slot)
+ ->C_CloseAllSessions(slot->slotID);
slot->session = CK_INVALID_SESSION;
- /* now re-init the token */
+ /* 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);
+ (unsigned char *)sso_pwd, sso_pwd ? PORT_Strlen(sso_pwd) : 0, tokenName);
/* finally bring the token back up */
- PK11_InitToken(slot,PR_TRUE);
+ PK11_InitToken(slot, PR_TRUE);
PK11_ExitSlotMonitor(slot);
if (crv != CKR_OK) {
- PORT_SetError(PK11_MapError(crv));
- return SECFailure;
+ PORT_SetError(PK11_MapError(crv));
+ return SECFailure;
}
nssTrustDomain_UpdateCachedTokenCerts(slot->nssToken->trustDomain,
- slot->nssToken);
+ slot->nssToken);
return SECSuccess;
}
void
-PK11Slot_SetNSSToken(PK11SlotInfo *sl, NSSToken *nsst)
+PK11Slot_SetNSSToken(PK11SlotInfo *sl, NSSToken *nsst)
{
sl->nssToken = nsst;
}
NSSToken *
-PK11Slot_GetNSSToken(PK11SlotInfo *sl)
+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.
+ * 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;
+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/nss/lib/pk11wrap/pk11util.c b/nss/lib/pk11wrap/pk11util.c
index 4a384ad..9636b07 100644
--- a/nss/lib/pk11wrap/pk11util.c
+++ b/nss/lib/pk11wrap/pk11util.c
@@ -17,12 +17,12 @@
/* 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 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;
@@ -30,52 +30,51 @@ int secmod_PrivateModuleCount = 0;
extern const PK11DefaultArrayEntry PK11_DefaultArray[];
extern const int num_pk11_default_mechanisms;
-
void
-SECMOD_Init()
+SECMOD_Init()
{
/* don't initialize twice */
- if (moduleLock) return;
+ if (moduleLock)
+ return;
moduleLock = SECMOD_NewListLock();
PK11_InitSlotLists();
}
-
SECStatus
-SECMOD_Shutdown()
+SECMOD_Shutdown()
{
/* destroy the lock */
if (moduleLock) {
- SECMOD_DestroyListLock(moduleLock);
- moduleLock = NULL;
+ SECMOD_DestroyListLock(moduleLock);
+ moduleLock = NULL;
}
/* free the internal module */
if (internalModule) {
- SECMOD_DestroyModule(internalModule);
- internalModule = NULL;
+ SECMOD_DestroyModule(internalModule);
+ internalModule = NULL;
}
/* free the default database module */
if (defaultDBModule) {
- SECMOD_DestroyModule(defaultDBModule);
- defaultDBModule = NULL;
+ SECMOD_DestroyModule(defaultDBModule);
+ defaultDBModule = NULL;
}
-
+
/* destroy the list */
if (modules) {
- SECMOD_DestroyModuleList(modules);
- modules = NULL;
+ SECMOD_DestroyModuleList(modules);
+ modules = NULL;
}
-
+
if (modulesDB) {
- SECMOD_DestroyModuleList(modulesDB);
- modulesDB = NULL;
+ SECMOD_DestroyModuleList(modulesDB);
+ modulesDB = NULL;
}
if (modulesUnload) {
- SECMOD_DestroyModuleList(modulesUnload);
- modulesUnload = NULL;
+ SECMOD_DestroyModuleList(modulesUnload);
+ modulesUnload = NULL;
}
/* make all the slots and the lists go away */
@@ -84,36 +83,34 @@ SECMOD_Shutdown()
nss_DumpModuleLog();
#ifdef DEBUG
- if (PR_GetEnv("NSS_STRICT_SHUTDOWN")) {
- PORT_Assert(secmod_PrivateModuleCount == 0);
+ if (PR_GetEnvSecure("NSS_STRICT_SHUTDOWN")) {
+ PORT_Assert(secmod_PrivateModuleCount == 0);
}
#endif
if (secmod_PrivateModuleCount) {
- PORT_SetError(SEC_ERROR_BUSY);
- return SECFailure;
+ PORT_SetError(SEC_ERROR_BUSY);
+ return SECFailure;
}
return SECSuccess;
}
-
/*
* retrieve the internal module
*/
SECMODModule *
SECMOD_GetInternalModule(void)
{
- return internalModule;
+ return internalModule;
}
-
SECStatus
-secmod_AddModuleToList(SECMODModuleList **moduleList,SECMODModule *newModule)
+secmod_AddModuleToList(SECMODModuleList **moduleList, SECMODModule *newModule)
{
SECMODModuleList *mlp, *newListElement, *last = NULL;
newListElement = SECMOD_NewModuleListElement();
if (newListElement == NULL) {
- return SECFailure;
+ return SECFailure;
}
newListElement->module = SECMOD_ReferenceModule(newModule);
@@ -122,14 +119,14 @@ secmod_AddModuleToList(SECMODModuleList **moduleList,SECMODModule *newModule)
/* 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;
+ for (mlp = *moduleList; mlp != NULL; mlp = mlp->next) {
+ last = mlp;
}
if (last == NULL) {
- *moduleList = newListElement;
+ *moduleList = newListElement;
} else {
- SECMOD_AddList(last,newListElement,NULL);
+ SECMOD_AddList(last, newListElement, NULL);
}
SECMOD_ReleaseWriteLock(moduleLock);
return SECSuccess;
@@ -139,50 +136,64 @@ SECStatus
SECMOD_AddModuleToList(SECMODModule *newModule)
{
if (newModule->internal && !internalModule) {
- internalModule = SECMOD_ReferenceModule(newModule);
+ internalModule = SECMOD_ReferenceModule(newModule);
}
- return secmod_AddModuleToList(&modules,newModule);
+ return secmod_AddModuleToList(&modules, newModule);
}
SECStatus
SECMOD_AddModuleToDBOnlyList(SECMODModule *newModule)
{
if (defaultDBModule && SECMOD_GetDefaultModDBFlag(newModule)) {
- SECMOD_DestroyModule(defaultDBModule);
- defaultDBModule = SECMOD_ReferenceModule(newModule);
+ SECMOD_DestroyModule(defaultDBModule);
+ defaultDBModule = SECMOD_ReferenceModule(newModule);
} else if (defaultDBModule == NULL) {
- defaultDBModule = SECMOD_ReferenceModule(newModule);
+ defaultDBModule = SECMOD_ReferenceModule(newModule);
}
- return secmod_AddModuleToList(&modulesDB,newModule);
+ return secmod_AddModuleToList(&modulesDB, newModule);
}
SECStatus
SECMOD_AddModuleToUnloadList(SECMODModule *newModule)
{
- return secmod_AddModuleToList(&modulesUnload,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; }
+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
+ * 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; }
-
-
+SECMODListLock *
+SECMOD_GetDefaultModuleListLock()
+{
+ return moduleLock;
+}
/*
* find a module by name, and add a reference to it.
@@ -195,26 +206,26 @@ SECMOD_FindModule(const char *name)
SECMODModule *module = NULL;
if (!moduleLock) {
- PORT_SetError(SEC_ERROR_NOT_INITIALIZED);
- return module;
+ 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;
- }
+ 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;
+ 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;
- }
+ for (mlp = modulesUnload; mlp != NULL; mlp = mlp->next) {
+ if (PORT_Strcmp(name, mlp->module->commonName) == 0) {
+ module = mlp->module;
+ SECMOD_ReferenceModule(module);
+ break;
+ }
}
found:
@@ -228,26 +239,26 @@ found:
* return that module.
*/
SECMODModule *
-SECMOD_FindModuleByID(SECMODModuleID id)
+SECMOD_FindModuleByID(SECMODModuleID id)
{
SECMODModuleList *mlp;
SECMODModule *module = NULL;
if (!moduleLock) {
- PORT_SetError(SEC_ERROR_NOT_INITIALIZED);
- return module;
+ 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;
- }
+ 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);
+ PORT_SetError(SEC_ERROR_NO_MODULE);
}
return module;
}
@@ -256,26 +267,26 @@ SECMOD_FindModuleByID(SECMODModuleID id)
* find the function pointer.
*/
SECMODModule *
-secmod_FindModuleByFuncPtr(void *funcPtr)
+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;
- }
+ 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);
+ PORT_SetError(SEC_ERROR_NO_MODULE);
}
return module;
}
@@ -290,22 +301,22 @@ SECMOD_FindSlotByID(SECMODModule *module, CK_SLOT_ID slotID)
PK11SlotInfo *slot = NULL;
if (!moduleLock) {
- PORT_SetError(SEC_ERROR_NOT_INITIALIZED);
- return slot;
+ PORT_SetError(SEC_ERROR_NOT_INITIALIZED);
+ return slot;
}
SECMOD_GetReadLock(moduleLock);
- for (i=0; i < module->slotCount; i++) {
- PK11SlotInfo *cSlot = module->slots[i];
+ for (i = 0; i < module->slotCount; i++) {
+ PK11SlotInfo *cSlot = module->slots[i];
- if (cSlot->slotID == slotID) {
- slot = PK11_ReferenceSlot(cSlot);
- break;
- }
+ if (cSlot->slotID == slotID) {
+ slot = PK11_ReferenceSlot(cSlot);
+ break;
+ }
}
SECMOD_ReleaseReadLock(moduleLock);
if (slot == NULL) {
- PORT_SetError(SEC_ERROR_NO_SLOT_SELECTED);
+ PORT_SetError(SEC_ERROR_NO_SLOT_SELECTED);
}
return slot;
}
@@ -314,86 +325,85 @@ SECMOD_FindSlotByID(SECMODModule *module, CK_SLOT_ID slotID)
* lookup the Slot module based on it's module ID and slot ID.
*/
PK11SlotInfo *
-SECMOD_LookupSlot(SECMODModuleID moduleID,CK_SLOT_ID slotID)
+SECMOD_LookupSlot(SECMODModuleID moduleID, CK_SLOT_ID slotID)
{
SECMODModule *module;
PK11SlotInfo *slot;
module = SECMOD_FindModuleByID(moduleID);
- if (module == NULL) return NULL;
+ 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)
+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;
+ 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;
- }
+ 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;
+ 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;
- }
+ 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);
+ if (permdb) {
+ SECMOD_DeletePermDB(mlp->module);
+ }
+ SECMOD_DestroyModuleListElement(mlp);
}
return rv;
}
@@ -402,7 +412,7 @@ found:
* find a module by name and delete it off the module list
*/
SECStatus
-SECMOD_DeleteModule(const char *name, int *type)
+SECMOD_DeleteModule(const char *name, int *type)
{
return SECMOD_DeleteModuleEx(name, NULL, type, PR_TRUE);
}
@@ -411,96 +421,96 @@ SECMOD_DeleteModule(const char *name, int *type)
* find a module by name and delete it off the module list
*/
SECStatus
-SECMOD_DeleteInternalModule(const char *name)
+SECMOD_DeleteInternalModule(const char *name)
{
SECMODModuleList *mlp;
SECMODModuleList **mlpp;
SECStatus rv = SECFailure;
if (pendingModule) {
- PORT_SetError(SEC_ERROR_MODULE_STUCK);
- return rv;
+ PORT_SetError(SEC_ERROR_MODULE_STUCK);
+ return rv;
}
if (!moduleLock) {
- PORT_SetError(SEC_ERROR_NOT_INITIALIZED);
- return rv;
+ 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;
- }
+ 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 */
+ 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)
+SECMOD_AddModule(SECMODModule *newModule)
{
SECStatus rv;
SECMODModule *oldModule;
@@ -511,18 +521,18 @@ SECMOD_AddModule(SECMODModule *newModule)
/* SECDublicateModule, but to minimize ripples, I'll */
/* give SECWouldBlock a new meaning */
if ((oldModule = SECMOD_FindModule(newModule->commonName)) != NULL) {
- SECMOD_DestroyModule(oldModule);
+ SECMOD_DestroyModule(oldModule);
return SECWouldBlock;
/* module already exists. */
}
rv = secmod_LoadPKCS11Module(newModule, NULL);
if (rv != SECSuccess) {
- return rv;
+ return rv;
}
if (newModule->parent == NULL) {
- newModule->parent = SECMOD_ReferenceModule(defaultDBModule);
+ newModule->parent = SECMOD_ReferenceModule(defaultDBModule);
}
SECMOD_AddPermDB(newModule);
@@ -534,48 +544,49 @@ SECMOD_AddModule(SECMODModule *newModule)
}
PK11SlotInfo *
-SECMOD_FindSlot(SECMODModule *module,const char *name)
+SECMOD_FindSlot(SECMODModule *module, const char *name)
{
int i;
char *string;
PK11SlotInfo *retSlot = NULL;
if (!moduleLock) {
- PORT_SetError(SEC_ERROR_NOT_INITIALIZED);
- return retSlot;
+ 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;
- }
+ 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);
+ PORT_SetError(SEC_ERROR_NO_SLOT_SELECTED);
}
return retSlot;
}
SECStatus
-PK11_GetModInfo(SECMODModule *mod,CK_INFO *info)
+PK11_GetModInfo(SECMODModule *mod, CK_INFO *info)
{
CK_RV crv;
- if (mod->functionList == NULL) return SECFailure;
+ if (mod->functionList == NULL)
+ return SECFailure;
crv = PK11_GETTAB(mod)->C_GetInfo(info);
if (crv != CKR_OK) {
- PORT_SetError(PK11_MapError(crv));
- }
+ PORT_SetError(PK11_MapError(crv));
+ }
return (crv == CKR_OK) ? SECSuccess : SECFailure;
}
@@ -589,7 +600,7 @@ PK11_IsFIPS(void)
SECMODModule *mod = SECMOD_GetInternalModule();
if (mod && mod->internal) {
- return mod->isFIPS;
+ return mod->isFIPS;
}
return PR_FALSE;
@@ -598,27 +609,27 @@ PK11_IsFIPS(void)
/* 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)
+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;
+ int s, i;
+ PK11SlotInfo *slot;
PR_SetErrorText(0, NULL);
if (!moduleLock) {
- PORT_SetError(SEC_ERROR_NOT_INITIALIZED);
- return result;
+ PORT_SetError(SEC_ERROR_NOT_INITIALIZED);
+ return result;
}
module = SECMOD_CreateModule(dllPath, moduleName, modparms, nssparms);
if (module == NULL) {
- return result;
+ return result;
}
if (module->dllName != NULL) {
@@ -628,29 +639,33 @@ SECMOD_AddNewModuleEx(const char* moduleName, const char* dllPath,
/* turn on SSL cipher enable flags */
module->ssl[0] = cipherEnableFlags;
- SECMOD_GetReadLock(moduleLock);
+ 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++) {
+ 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);
+ PRBool add =
+ (PK11_DefaultArray[i].flag & defaultMechanismFlags) ? PR_TRUE : PR_FALSE;
+ result = PK11_UpdateSlotAttribute(slot,
+ &(PK11_DefaultArray[i]), add);
+ if (result != SECSuccess) {
+ SECMOD_ReleaseReadLock(moduleLock);
+ SECMOD_DestroyModule(module);
+ return result;
+ }
} /* 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);
+ SECMOD_ReleaseReadLock(moduleLock);
- /* delete and re-add module in order to save changes
- * to the module */
- result = SECMOD_UpdateModule(module);
+ /* delete and re-add module in order to save changes
+ * to the module */
+ result = SECMOD_UpdateModule(module);
}
}
}
@@ -658,25 +673,25 @@ SECMOD_AddNewModuleEx(const char* moduleName, const char* dllPath,
return result;
}
-SECStatus
-SECMOD_AddNewModule(const char* moduleName, const char* dllPath,
- unsigned long defaultMechanismFlags,
- unsigned long cipherEnableFlags)
+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 */
+ cipherEnableFlags,
+ NULL, NULL); /* don't pass module or nss params */
}
-SECStatus
+SECStatus
SECMOD_UpdateModule(SECMODModule *module)
{
SECStatus result;
result = SECMOD_DeletePermDB(module);
-
- if (result == SECSuccess) {
- result = SECMOD_AddPermDB(module);
+
+ if (result == SECSuccess) {
+ result = SECMOD_AddPermDB(module);
}
return result;
}
@@ -684,11 +699,11 @@ SECMOD_UpdateModule(SECMODModule *module)
/* Public & Internal(Security Library) representation of
* encryption mechanism flags conversion */
-/* Currently, the only difference is that internal representation
+/* 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
+unsigned long
SECMOD_PubMechFlagstoInternal(unsigned long publicFlags)
{
unsigned long internalFlags = publicFlags;
@@ -700,8 +715,8 @@ SECMOD_PubMechFlagstoInternal(unsigned long publicFlags)
return internalFlags;
}
-unsigned long
-SECMOD_InternaltoPubMechFlags(unsigned long internalFlags)
+unsigned long
+SECMOD_InternaltoPubMechFlags(unsigned long internalFlags)
{
unsigned long publicFlags = internalFlags;
@@ -712,38 +727,37 @@ SECMOD_InternaltoPubMechFlags(unsigned long internalFlags)
return publicFlags;
}
-
/* Public & Internal(Security Library) representation of */
/* cipher flags conversion */
/* Note: currently they are just stubs */
-unsigned long
-SECMOD_PubCipherFlagstoInternal(unsigned long publicFlags)
+unsigned long
+SECMOD_PubCipherFlagstoInternal(unsigned long publicFlags)
{
return publicFlags;
}
-unsigned long
-SECMOD_InternaltoPubCipherFlags(unsigned long internalFlags)
+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
+SECMOD_IsModulePresent(unsigned long int pubCipherEnableFlags)
{
PRBool result = PR_FALSE;
SECMODModuleList *mods;
if (!moduleLock) {
- PORT_SetError(SEC_ERROR_NOT_INITIALIZED);
- return result;
+ 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)) {
+ for (; mods != NULL; mods = mods->next) {
+ if (mods->module->ssl[0] &
+ SECMOD_PubCipherFlagstoInternal(pubCipherEnableFlags)) {
result = PR_TRUE;
}
}
@@ -753,14 +767,15 @@ SECMOD_IsModulePresent( unsigned long int pubCipherEnableFlags )
}
/* create a new ModuleListElement */
-SECMODModuleList *SECMOD_NewModuleListElement(void)
+SECMODModuleList *
+SECMOD_NewModuleListElement(void)
{
SECMODModuleList *newModList;
- newModList= (SECMODModuleList *) PORT_Alloc(sizeof(SECMODModuleList));
+ newModList = (SECMODModuleList *)PORT_Alloc(sizeof(SECMODModuleList));
if (newModList) {
- newModList->next = NULL;
- newModList->module = NULL;
+ newModList->next = NULL;
+ newModList->module = NULL;
}
return newModList;
}
@@ -769,7 +784,7 @@ SECMODModuleList *SECMOD_NewModuleListElement(void)
* make a new reference to a module so It doesn't go away on us
*/
SECMODModule *
-SECMOD_ReferenceModule(SECMODModule *module)
+SECMOD_ReferenceModule(SECMODModule *module)
{
PZ_Lock(module->refLock);
PORT_Assert(module->refCount > 0);
@@ -779,10 +794,9 @@ SECMOD_ReferenceModule(SECMODModule *module)
return module;
}
-
/* destroy an existing module */
void
-SECMOD_DestroyModule(SECMODModule *module)
+SECMOD_DestroyModule(SECMODModule *module)
{
PRBool willfree = PR_FALSE;
int slotCount;
@@ -790,69 +804,69 @@ SECMOD_DestroyModule(SECMODModule *module)
PZ_Lock(module->refLock);
if (module->refCount-- == 1) {
- willfree = PR_TRUE;
+ willfree = PR_TRUE;
}
PORT_Assert(willfree || (module->refCount > 0));
PZ_Unlock(module->refLock);
if (!willfree) {
- return;
+ 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);
+ 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;
+ 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]);
+ 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)
+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;
+ 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;
+ pendingModule = NULL;
}
if (module->loaded) {
- SECMOD_UnloadModule(module);
+ SECMOD_UnloadModule(module);
}
PZ_DestroyLock(module->refLock);
- PORT_FreeArena(module->arena,PR_FALSE);
+ PORT_FreeArena(module->arena, PR_FALSE);
secmod_PrivateModuleCount--;
}
@@ -861,39 +875,39 @@ SECMOD_SlotDestroyModule(SECMODModule *module, PRBool fromSlot)
* 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)
+SECMOD_DestroyModuleListElement(SECMODModuleList *element)
{
SECMODModuleList *next = element->next;
if (element->module) {
- SECMOD_DestroyModule(element->module);
- element->module = NULL;
+ SECMOD_DestroyModule(element->module);
+ element->module = NULL;
}
PORT_Free(element);
return next;
}
-
/*
* Destroy an entire module list
*/
void
-SECMOD_DestroyModuleList(SECMODModuleList *list)
+SECMOD_DestroyModuleList(SECMODModuleList *list)
{
SECMODModuleList *lp;
- for ( lp = list; lp != NULL; lp = SECMOD_DestroyModuleListElement(lp)) ;
+ for (lp = list; lp != NULL; lp = SECMOD_DestroyModuleListElement(lp))
+ ;
}
PRBool
SECMOD_CanDeleteInternalModule(void)
{
- return (PRBool) (pendingModule == NULL);
+ 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
+ * 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
@@ -912,67 +926,67 @@ SECMOD_UpdateSlotList(SECMODModule *mod)
PK11SlotInfo **oldSlots = NULL;
if (!moduleLock) {
- PORT_SetError(SEC_ERROR_NOT_INITIALIZED);
- return SECFailure;
+ PORT_SetError(SEC_ERROR_NOT_INITIALIZED);
+ return SECFailure;
}
- /* C_GetSlotList is not a session function, make sure
+ /* 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;
+ 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;
+ 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;
+ /* 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;
+ goto loser;
}
crv = PK11_GETTAB(mod)->C_GetSlotList(PR_FALSE, slotIDs, &count);
if (crv != CKR_OK) {
- PORT_SetError(PK11_MapError(crv));
- goto loser;
+ PORT_SetError(PK11_MapError(crv));
+ goto loser;
}
freeRef = PR_FALSE;
PZ_Unlock(mod->refLock);
mark = PORT_ArenaMark(mod->arena);
if (mark == NULL) {
- goto loser;
+ goto loser;
}
- newSlots = PORT_ArenaZNewArray(mod->arena,PK11SlotInfo *,count);
+ 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
+ * 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;
+ 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);
@@ -980,46 +994,46 @@ SECMOD_UpdateSlotList(SECMODModule *mod)
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
+ * 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;
+ 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 */
+ * 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]);
+ for (i = 0; i < oldCount; i++) {
+ PK11_FreeSlot(oldSlots[i]);
}
return SECSuccess;
loser:
if (freeRef) {
- PZ_Unlock(mod->refLock);
+ PZ_Unlock(mod->refLock);
}
if (slotIDs) {
- PORT_Free(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]);
- }
+ 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);
+ PORT_ArenaRelease(mod->arena, mark);
}
return SECFailure;
}
@@ -1030,69 +1044,69 @@ loser:
* have a timeout, so we don't have one for handleWaitForSlotEvent() either.
*/
PK11SlotInfo *
-secmod_HandleWaitForSlotEvent(SECMODModule *mod, unsigned long flags,
- PRIntervalTime latency)
+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;
+ 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_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];
- PRUint16 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);
+ 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];
+ PRUint16 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);
@@ -1108,7 +1122,7 @@ secmod_HandleWaitForSlotEvent(SECMODModule *mod, unsigned long flags,
*/
PK11SlotInfo *
SECMOD_WaitForAnyTokenEvent(SECMODModule *mod, unsigned long flags,
- PRIntervalTime latency)
+ PRIntervalTime latency)
{
CK_SLOT_ID id;
CK_RV crv;
@@ -1116,17 +1130,17 @@ SECMOD_WaitForAnyTokenEvent(SECMODModule *mod, unsigned long flags,
if (!pk11_getFinalizeModulesOption() ||
((mod->cryptokiVersion.major == 2) &&
- (mod->cryptokiVersion.minor < 1))) {
+ (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);
+ 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;
+ goto end_wait;
}
mod->evControlMask |= SECMOD_WAIT_PKCS11_EVENT;
PZ_Unlock(mod->refLock);
@@ -1136,39 +1150,39 @@ SECMOD_WaitForAnyTokenEvent(SECMODModule *mod, unsigned long flags,
/* 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;
+ 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);
+ /* 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;
+ /* 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);
+ /* 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);
+ nssSlot_ResetDelay(slot->nssToken->slot);
}
return slot;
- /* must be called with the lock on. */
+/* must be called with the lock on. */
end_wait:
mod->evControlMask &= ~SECMOD_END_WAIT;
PZ_Unlock(mod->refLock);
@@ -1200,27 +1214,27 @@ SECMOD_CancelWait(SECMODModule *mod)
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) {
+ /* 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;
- }
+ 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 */
+ mod->evControlMask &= ~SECMOD_WAIT_SIMULATED_EVENT;
+ /* Simulated events will eventually timeout
+ * and wake up in the loop */
}
loser:
PZ_Unlock(mod->refLock);
@@ -1238,21 +1252,21 @@ SECMOD_HasRemovableSlots(SECMODModule *mod)
PRBool ret = PR_FALSE;
if (!moduleLock) {
- PORT_SetError(SEC_ERROR_NOT_INITIALIZED);
- return ret;
+ 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;
+ 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;
@@ -1262,29 +1276,30 @@ SECMOD_HasRemovableSlots(SECMODModule *mod)
* helper function to actually create and destroy user defined slots
*/
static SECStatus
-secmod_UserDBOp(PK11SlotInfo *slot, CK_OBJECT_CLASS objClass,
- const char *sendSpec)
+secmod_UserDBOp(PK11SlotInfo *slot, CK_OBJECT_CLASS objClass,
+ const char *sendSpec)
{
CK_OBJECT_HANDLE dummy;
- CK_ATTRIBUTE template[2] ;
+ 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_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);
+ template, attrs - template, PR_FALSE, &dummy);
PK11_ExitSlotMonitor(slot);
if (crv != CKR_OK) {
- PORT_SetError(PK11_MapError(crv));
- return SECFailure;
+ PORT_SetError(PK11_MapError(crv));
+ return SECFailure;
}
return SECMOD_UpdateSlotList(slot->module);
}
@@ -1293,15 +1308,15 @@ secmod_UserDBOp(PK11SlotInfo *slot, CK_OBJECT_CLASS objClass,
* return true if the selected slot ID is not present or doesn't exist
*/
static PRBool
-secmod_SlotIsEmpty(SECMODModule *mod, CK_SLOT_ID slotID)
+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;
- }
+ 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;
@@ -1317,19 +1332,19 @@ secmod_FindFreeSlot(SECMODModule *mod)
/* 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;
+ 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;
+ 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;
- }
+ 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;
+ return (CK_SLOT_ID)-1;
}
/*
@@ -1338,10 +1353,10 @@ secmod_FindFreeSlot(SECMODModule *mod)
* 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
+ * 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.
@@ -1356,66 +1371,80 @@ SECMOD_OpenNewSlot(SECMODModule *mod, const char *moduleSpec)
SECStatus rv;
slotID = secmod_FindFreeSlot(mod);
- if (slotID == (CK_SLOT_ID) -1) {
- return NULL;
+ if (slotID == (CK_SLOT_ID)-1) {
+ return NULL;
}
if (mod->slotCount == 0) {
- return NULL;
+ 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;
+ return NULL;
}
/* we've found the slot, now build the moduleSpec */
escSpec = NSSUTIL_DoubleEscape(moduleSpec, '>', ']');
if (escSpec == NULL) {
- PK11_FreeSlot(slot);
- return 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;
+ /* 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;
+ 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);
+ /* 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;
}
/*
+ * given a module spec, find the slot in the module for it.
+ */
+PK11SlotInfo *
+secmod_FindSlotFromModuleSpec(const char *moduleSpec, SECMODModule *module)
+{
+ CK_SLOT_ID slot_id = secmod_GetSlotIDFromModuleSpec(moduleSpec, module);
+ if (slot_id == -1) {
+ return NULL;
+ }
+
+ return SECMOD_FindSlotByID(module, slot_id);
+}
+
+/*
* 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
+ * 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
+ * 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
+ * module spec here. The slot ID will be calculated for you by
* SECMOD_OpenUserDB().
*
* Typical parameters here are configdir, tokenDescription and flags.
@@ -1423,22 +1452,22 @@ SECMOD_OpenNewSlot(SECMODModule *mod, const char *moduleSpec)
* a Full list is below:
*
*
- * configDir - The location of the databases for this token. If configDir is
+ * 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
+ * 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
+ * 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
+ * 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.
@@ -1446,35 +1475,51 @@ SECMOD_OpenNewSlot(SECMODModule *mod, const char *moduleSpec)
* 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
+ * forceOpen - Don't fail to initialize the token if the
* databases could not be opened.
- * passwordRequired - zero length passwords are not acceptable
+ * 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.
+ * When this flag is not specified, Softoken will allocate
+ * large tables to prevent lock contention.
*/
PK11SlotInfo *
SECMOD_OpenUserDB(const char *moduleSpec)
{
SECMODModule *mod;
+ SECMODConfigList *conflist = NULL;
+ int count = 0;
if (moduleSpec == NULL) {
- return 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;
+ /* shouldn't happen */
+ PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
+ return NULL;
+ }
+
+ /* make sure we don't open the same database twice. We only understand
+ * the moduleSpec for internal databases well enough to do this, so only
+ * do this in OpenUserDB */
+ conflist = secmod_GetConfigList(mod->isFIPS, mod->libraryParams, &count);
+ if (conflist) {
+ PK11SlotInfo *slot = NULL;
+ if (secmod_MatchConfigList(moduleSpec, conflist, count)) {
+ slot = secmod_FindSlotFromModuleSpec(moduleSpec, mod);
+ }
+ secmod_FreeConfigList(conflist, count);
+ if (slot) {
+ return slot;
+ }
}
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().
@@ -1486,21 +1531,21 @@ 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;
+ /* 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);
/* 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);
+ nssSlot_ResetDelay(slot->nssToken->slot);
+ /* force the slot info structures to properly reset */
+ (void)PK11_IsPresent(slot);
}
return rv;
}
@@ -1516,59 +1561,58 @@ SECMOD_RestartModules(PRBool force)
int lastError = 0;
if (!moduleLock) {
- PORT_SetError(SEC_ERROR_NOT_INITIALIZED);
- return SECFailure;
+ 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)) {
+ 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
+ /* 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;
- }
- }
- }
+ (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);
@@ -1577,8 +1621,8 @@ SECMOD_RestartModules(PRBool force)
* can determine which slots are bad by calling PK11_IsDisabled().
*/
if (rrv != SECSuccess) {
- /* restore the last error code */
- PORT_SetError(lastError);
+ /* restore the last error code */
+ PORT_SetError(lastError);
}
return rrv;
diff --git a/nss/lib/pk11wrap/pk11wrap.gyp b/nss/lib/pk11wrap/pk11wrap.gyp
new file mode 100644
index 0000000..2af27a0
--- /dev/null
+++ b/nss/lib/pk11wrap/pk11wrap.gyp
@@ -0,0 +1,51 @@
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+{
+ 'includes': [
+ '../../coreconf/config.gypi'
+ ],
+ 'targets': [
+ {
+ 'target_name': 'pk11wrap',
+ 'type': 'static_library',
+ 'sources': [
+ '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'
+ ],
+ 'dependencies': [
+ '<(DEPTH)/exports.gyp:nss_exports'
+ ]
+ }
+ ],
+ 'target_defaults': {
+ 'defines': [
+ 'SHLIB_SUFFIX=\"<(dll_suffix)\"',
+ 'SHLIB_PREFIX=\"<(dll_prefix)\"',
+ 'SHLIB_VERSION=\"3\"',
+ 'SOFTOKEN_SHLIB_VERSION=\"3\"'
+ ]
+ },
+ 'variables': {
+ 'module': 'nss'
+ }
+} \ No newline at end of file
diff --git a/nss/lib/pk11wrap/secmod.h b/nss/lib/pk11wrap/secmod.h
index c194d9a..fcc7707 100644
--- a/nss/lib/pk11wrap/secmod.h
+++ b/nss/lib/pk11wrap/secmod.h
@@ -10,38 +10,38 @@
/* 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_ECC_FLAG 0x00040000ul
-
-#define PUBLIC_MECH_RANDOM_FLAG 0x08000000ul
-#define PUBLIC_MECH_FRIENDLY_FLAG 0x10000000ul
-#define PUBLIC_OWN_PW_DEFAULTS 0X20000000ul
-#define PUBLIC_DISABLE_FLAG 0x40000000ul
+#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_ECC_FLAG 0x00040000ul
+
+#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
+#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
+#define PUBLIC_CIPHER_FORTEZZA_FLAG 0x00000001ul
/* warning: reserved means reserved */
#define PUBLIC_CIPHER_RESERVED_FLAGS 0xFFFFFFFEul
@@ -54,41 +54,39 @@ SEC_BEGIN_PROTOS
*/
/* Initialization */
-extern SECMODModule *SECMOD_LoadModule(char *moduleSpec,SECMODModule *parent,
- PRBool recurse);
+extern SECMODModule *SECMOD_LoadModule(char *moduleSpec, SECMODModule *parent,
+ PRBool recurse);
-extern SECMODModule *SECMOD_LoadUserModule(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);
-SECMODModule * SECMOD_CreateModuleEx(const char *lib, const char *name,
- const char *param, const char *nss,
- const char *config);
+SECMODModule *SECMOD_CreateModule(const char *lib, const char *name,
+ const char *param, const char *nss);
+SECMODModule *SECMOD_CreateModuleEx(const char *lib, const char *name,
+ const char *param, const char *nss,
+ const char *config);
/*
* 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
+ * 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
+ * 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);
+SECStatus SECMOD_FreeModuleSpecList(SECMODModule *module, char **moduleSpecList);
-
/* protoypes */
/* Get a list of active PKCS #11 modules */
-extern SECMODModuleList *SECMOD_GetDefaultModuleList(void);
+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 */
@@ -106,34 +104,34 @@ 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,
+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);
+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);
+ 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 );
+PRBool SECMOD_IsModulePresent(unsigned long int pubCipherEnableFlags);
/* accessors */
PRBool SECMOD_GetSkipFirstFlag(SECMODModule *mod);
@@ -146,18 +144,18 @@ extern unsigned long SECMOD_InternaltoPubMechFlags(unsigned long internalFlags);
extern unsigned long SECMOD_PubCipherFlagstoInternal(unsigned long publicFlags);
PRBool SECMOD_HasRemovableSlots(SECMODModule *mod);
-PK11SlotInfo *SECMOD_WaitForAnyTokenEvent(SECMODModule *mod,
- unsigned long flags, PRIntervalTime latency);
+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.
+ * 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
+ * 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
diff --git a/nss/lib/pk11wrap/secmodi.h b/nss/lib/pk11wrap/secmodi.h
index 830fb67..1225661 100644
--- a/nss/lib/pk11wrap/secmodi.h
+++ b/nss/lib/pk11wrap/secmodi.h
@@ -27,14 +27,14 @@ extern int secmod_PrivateModuleCount;
extern void SECMOD_Init(void);
SECStatus secmod_ModuleInit(SECMODModule *mod, SECMODModule **oldModule,
- PRBool* alreadyLoaded);
+ 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 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 *);
@@ -59,14 +59,15 @@ 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);
+PRBool secmod_MatchConfigList(const char *spec,
+ SECMODConfigList *conflist, int count);
+/* returns the slot id from a module and modulespec */
+CK_SLOT_ID secmod_GetSlotIDFromModuleSpec(const char *moduleSpec, SECMODModule *module);
/* free our list of databases */
void secmod_FreeConfigList(SECMODConfigList *conflist, int count);
@@ -75,45 +76,44 @@ void secmod_FreeConfigList(SECMODConfigList *conflist, int count);
/* 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);
+ PRBool isFIPS,
+ const char *moduleSpec,
+ char ***children,
+ CK_SLOT_ID **ids);
void secmod_FreeChildren(char **children, CK_SLOT_ID *ids);
char *secmod_MkAppendTokensList(PLArenaPool *arena, char *origModuleSpec,
- char *newModuleSpec, CK_SLOT_ID newID,
- char **children, CK_SLOT_ID *ids);
-
+ 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);
+ CK_VOID_PTR pdata);
void pk11_SignedToUnsigned(CK_ATTRIBUTE *attrib);
CK_OBJECT_HANDLE pk11_FindObjectByTemplate(PK11SlotInfo *slot,
- CK_ATTRIBUTE *inTemplate,int tsize);
+ CK_ATTRIBUTE *inTemplate, int tsize);
CK_OBJECT_HANDLE *pk11_FindObjectsByTemplate(PK11SlotInfo *slot,
- CK_ATTRIBUTE *inTemplate,int tsize, int *objCount);
+ CK_ATTRIBUTE *inTemplate, int tsize, int *objCount);
#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);
+#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);
+ PRBool token, CK_OBJECT_HANDLE *objectID);
-SECStatus pbe_PK11AlgidToParam(SECAlgorithmID *algid,SECItem *mech);
-SECStatus PBE_PK11ParamToAlgid(SECOidTag algTag, SECItem *param,
- PLArenaPool *arena, SECAlgorithmID *algId);
+SECStatus pbe_PK11AlgidToParam(SECAlgorithmID *algid, SECItem *mech);
+SECStatus PBE_PK11ParamToAlgid(SECOidTag algTag, SECItem *param,
+ PLArenaPool *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 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);
-
-
+ SECItem **param, SECItem *pwd, PRBool faulty3DES);
extern void pk11sdr_Init(void);
extern void pk11sdr_Shutdown(void);
@@ -126,46 +126,45 @@ 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);
+ 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);
+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);
+ CK_ATTRIBUTE *attrs, CK_BBOOL *ckTrue, CK_BBOOL *ckFalse);
PRBool pk11_FindAttrInTemplate(CK_ATTRIBUTE *attr, unsigned int numAttrs,
- CK_ATTRIBUTE_TYPE target);
+ 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);
+ CK_ATTRIBUTE_TYPE operation, CK_FLAGS flags, PRBool isPerm,
+ PK11SymKey *symKey);
PRBool pk11_HandleTrustObject(PK11SlotInfo *slot, CERTCertificate *cert,
- CERTCertTrust *trust);
+ CERTCertTrust *trust);
CK_OBJECT_HANDLE pk11_FindPubKeyByAnyCert(CERTCertificate *cert,
- PK11SlotInfo **slot, void *wincx);
+ PK11SlotInfo **slot, void *wincx);
SECStatus pk11_AuthenticateUnfriendly(PK11SlotInfo *slot, PRBool loadCerts,
- void *wincx);
+ void *wincx);
int PK11_NumberObjectsFor(PK11SlotInfo *slot, CK_ATTRIBUTE *findTemplate,
- int templateCount);
-SECItem *pk11_GetLowLevelKeyFromHandle(PK11SlotInfo *slot,
- CK_OBJECT_HANDLE handle);
+ 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);
+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);
+ 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);
+SECItem *pk11_ParamFromIVWithLen(CK_MECHANISM_TYPE type,
+ SECItem *iv, int keyLen);
SEC_END_PROTOS
#endif
-
diff --git a/nss/lib/pk11wrap/secmodt.h b/nss/lib/pk11wrap/secmodt.h
index 33e7f1b..23abe30 100644
--- a/nss/lib/pk11wrap/secmodt.h
+++ b/nss/lib/pk11wrap/secmodt.h
@@ -29,10 +29,10 @@ SEC_END_PROTOS
typedef struct SECMODModuleStr SECMODModule;
typedef struct SECMODModuleListStr SECMODModuleList;
typedef NSSRWLock SECMODListLock;
-typedef struct PK11SlotInfoStr PK11SlotInfo; /* defined in secmodti.h */
+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 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;
@@ -42,37 +42,37 @@ 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 */
+ 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 */
+ * events (SECMOD_WaitForAnyTokenEvent) */
+ CK_VERSION cryptokiVersion; /* version of this library */
};
/* evControlMask flags */
@@ -86,14 +86,14 @@ struct SECMODModuleStr {
* 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
+ */
+#define SECMOD_END_WAIT 0x01
+#define SECMOD_WAIT_SIMULATED_EVENT 0x02
+#define SECMOD_WAIT_PKCS11_EVENT 0x04
struct SECMODModuleListStr {
- SECMODModuleList *next;
- SECMODModule *module;
+ SECMODModuleList *next;
+ SECMODModule *module;
};
struct PK11SlotListStr {
@@ -115,27 +115,27 @@ struct PK11RSAGenParamsStr {
};
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 */
+ 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 they represent.
- * Always statically allocated.
+ * Always statically allocated.
*/
struct PK11DefaultArrayEntryStr {
const 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 */
+ unsigned long mechanism; /* this is a long so we don't include the
+ * whole pkcs 11 world to use this header */
};
/*
@@ -187,8 +187,8 @@ typedef PRUint32 PK11AttrFlags;
* These two flags specify the value of the PKCS #11 CKA_TOKEN
* attribute.
*/
-#define PK11_ATTR_TOKEN 0x00000001L
-#define PK11_ATTR_SESSION 0x00000002L
+#define PK11_ATTR_TOKEN 0x00000001L
+#define PK11_ATTR_SESSION 0x00000002L
/*
* PK11_ATTR_PRIVATE
@@ -209,8 +209,8 @@ typedef PRUint32 PK11AttrFlags;
* 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
+#define PK11_ATTR_PRIVATE 0x00000004L
+#define PK11_ATTR_PUBLIC 0x00000008L
/*
* PK11_ATTR_MODIFIABLE
@@ -228,8 +228,8 @@ typedef PRUint32 PK11AttrFlags;
* These two flags specify the value of the PKCS #11 CKA_MODIFIABLE
* attribute.
*/
-#define PK11_ATTR_MODIFIABLE 0x00000010L
-#define PK11_ATTR_UNMODIFIABLE 0x00000020L
+#define PK11_ATTR_MODIFIABLE 0x00000010L
+#define PK11_ATTR_UNMODIFIABLE 0x00000020L
/* Attributes for PKCS #11 key objects. */
@@ -253,8 +253,8 @@ typedef PRUint32 PK11AttrFlags;
* 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
+#define PK11_ATTR_SENSITIVE 0x00000040L
+#define PK11_ATTR_INSENSITIVE 0x00000080L
/*
* PK11_ATTR_EXTRACTABLE
@@ -271,24 +271,24 @@ typedef PRUint32 PK11AttrFlags;
* These two flags specify the value of the PKCS #11 CKA_EXTRACTABLE
* attribute.
*/
-#define PK11_ATTR_EXTRACTABLE 0x00000100L
+#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 */
+#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_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_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)
+#define SECMOD_FIPS_FLAGS SECMOD_MAKE_NSS_FLAGS(",fips", 3)
/*
* What is the origin of a given Key. Normally this doesn't matter, but
@@ -296,11 +296,11 @@ typedef PRUint32 PK11AttrFlags;
* 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 */
+ 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 */
@@ -312,8 +312,8 @@ typedef enum {
PK11_DIS_TOKEN_NOT_PRESENT = 4
} PK11DisableReasons;
-/* types of PKCS #11 objects
- * used to identify which NSS data structure is
+/* 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 *
@@ -322,38 +322,36 @@ typedef enum {
* PK11_TypeCert CERTCertificate * (currently not used).
*/
typedef enum {
- PK11_TypeGeneric = 0,
- PK11_TypePrivKey = 1,
- PK11_TypePubKey = 2,
- PK11_TypeCert = 3,
- PK11_TypeSymKey = 4
+ 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()
+ * 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);
+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 */
+ */
+#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
+ * 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 */
+#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
@@ -394,23 +392,22 @@ typedef struct SECKEYEncryptedPrivateKeyInfoStr SECKEYEncryptedPrivateKeyInfo;
* token removal detection
*/
typedef enum {
- PK11TokenNotRemovable = 0,
- PK11TokenPresent = 1,
- PK11TokenChanged = 2,
- PK11TokenRemoved = 3
+ PK11TokenNotRemovable = 0,
+ PK11TokenPresent = 1,
+ PK11TokenChanged = 2,
+ PK11TokenRemoved = 3
} PK11TokenStatus;
typedef enum {
- PK11TokenRemovedOrChangedEvent = 0,
- PK11TokenPresentEvent = 1
+ PK11TokenRemovedOrChangedEvent = 0,
+ PK11TokenPresentEvent = 1
} PK11TokenEvent;
/*
* CRL Import Flags
*/
#define CRL_IMPORT_DEFAULT_OPTIONS 0x00000000
-#define CRL_IMPORT_BYPASS_CHECKS 0x00000001
-
+#define CRL_IMPORT_BYPASS_CHECKS 0x00000001
/*
* Merge Error Log
@@ -421,15 +418,15 @@ 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 */
+ 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 */
+ 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 */
+ void *reserved4; /* future pointer */
+ void *reserved5; /* future expansion pointer */
};
struct PK11MergeLogStr {
@@ -443,6 +440,5 @@ struct PK11MergeLogStr {
void *reserverd4;
void *reserverd5;
};
-
#endif /*_SECMODT_H_ */
diff --git a/nss/lib/pk11wrap/secmodti.h b/nss/lib/pk11wrap/secmodti.h
index 2b63130..5201655 100644
--- a/nss/lib/pk11wrap/secmodti.h
+++ b/nss/lib/pk11wrap/secmodti.h
@@ -6,8 +6,8 @@
* pkcs11 specific client and server files.
*/
-#ifndef _SECMODTI_H_
-#define _SECMODTI_H_ 1
+#ifndef _SECMODTI_H_
+#define _SECMODTI_H_ 1
#include "prmon.h"
#include "prtypes.h"
#include "nssilckt.h"
@@ -20,38 +20,37 @@
/* Traverse slots callback */
typedef struct pk11TraverseSlotStr {
- SECStatus (*callback)(PK11SlotInfo *,CK_OBJECT_HANDLE, void *);
+ 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 */
+ 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 */
+ CK_FLAGS flags; /* flags from PKCS #11 token Info */
/* a default session handle to do quick and dirty functions */
- CK_SESSION_HANDLE session;
+ CK_SESSION_HANDLE session;
PZLock *sessionLock; /* lock for this session */
/* our ID */
CK_SLOT_ID slotID;
@@ -59,7 +58,7 @@ struct PK11SlotInfoStr {
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! */
+ PRInt32 refCount; /* to be in/decremented by atomic calls ONLY! */
PZLock *freeListLock;
PK11SymKey *freeSymKeysWithSessionHead;
PK11SymKey *freeSymKeysHead;
@@ -67,34 +66,34 @@ struct PK11SlotInfoStr {
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 */
- PRTime authTime; /* when were we last authenticated */
- int minPassword; /* smallest legal password */
- int maxPassword; /* largest legal password */
- PRUint16 series; /* break up the slot info into various groups of
- * inserted tokens so that keys and certs can be
- * invalidated */
- PRUint16 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. */
- PRUint16 wrapKey; /* current wrapping key for SSL master secrets */
+ 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 */
+ PRTime authTime; /* when were we last authenticated */
+ int minPassword; /* smallest legal password */
+ int maxPassword; /* largest legal password */
+ PRUint16 series; /* break up the slot info into various groups of
+ * inserted tokens so that keys and certs can be
+ * invalidated */
+ PRUint16 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. */
+ PRUint16 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 */
+ /* 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 */
+ * 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
+ /* 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];
@@ -114,60 +113,59 @@ struct PK11SlotInfoStr {
/* 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_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 */
- PRUint16 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 */
+ 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 */
+ PRUint16 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*/
+ 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
+ * structure to hold a pointer to a unique PKCS #11 object
* (pointer to the slot and the object id).
*/
struct PK11GenericObjectStr {
@@ -177,11 +175,9 @@ struct PK11GenericObjectStr {
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/nss/lib/pk11wrap/secpkcs5.h b/nss/lib/pk11wrap/secpkcs5.h
index ac863b1..5785676 100644
--- a/nss/lib/pk11wrap/secpkcs5.h
+++ b/nss/lib/pk11wrap/secpkcs5.h
@@ -21,8 +21,8 @@ SEC_BEGIN_PROTOS
/* private */
SECAlgorithmID *
sec_pkcs5CreateAlgorithmID(SECOidTag algorithm, SECOidTag cipherAlgorithm,
- SECOidTag prfAlg, SECOidTag *pPbeAlgorithm,
- int keyLengh, SECItem *salt, int iteration);
+ 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.
@@ -47,13 +47,12 @@ int SEC_PKCS5GetKeyLength(SECAlgorithmID *algid);
PBEBitGenContext *
PBE_CreateContext(SECOidTag hashAlgorithm, PBEBitGenID bitGenPurpose,
- SECItem *pwitem, SECItem *salt, unsigned int bitsNeeded,
- unsigned int iterations);
+ SECItem *pwitem, SECItem *salt, unsigned int bitsNeeded,
+ unsigned int iterations);
void
PBE_DestroyContext(PBEBitGenContext *context);
-
SECItem *
PBE_GenerateBits(PBEBitGenContext *context);
diff --git a/nss/lib/pkcs12/exports.gyp b/nss/lib/pkcs12/exports.gyp
new file mode 100644
index 0000000..274ef68
--- /dev/null
+++ b/nss/lib/pkcs12/exports.gyp
@@ -0,0 +1,29 @@
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+{
+ 'includes': [
+ '../../coreconf/config.gypi'
+ ],
+ 'targets': [
+ {
+ 'target_name': 'lib_pkcs12_exports',
+ 'type': 'none',
+ 'copies': [
+ {
+ 'files': [
+ 'p12.h',
+ 'p12plcy.h',
+ 'p12t.h',
+ 'pkcs12.h',
+ 'pkcs12t.h'
+ ],
+ 'destination': '<(nss_public_dist_dir)/<(module)'
+ }
+ ]
+ }
+ ],
+ 'variables': {
+ 'module': 'nss'
+ }
+}
diff --git a/nss/lib/pkcs12/p12.h b/nss/lib/pkcs12/p12.h
index 508f0a0..118db6e 100644
--- a/nss/lib/pkcs12/p12.h
+++ b/nss/lib/pkcs12/p12.h
@@ -2,7 +2,6 @@
* License, v. 2.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_
@@ -11,30 +10,30 @@
#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);
+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.
+ * the 'leafCert' variable in sec_pkcs12_validate_cert in p12d.c.
* See r1.35 of p12d.c ("Patch 2" in bug 321584).
*
* This callback might be called by SEC_PKCS12DecoderValidateBags each time
@@ -44,10 +43,10 @@ typedef void (PR_CALLBACK * SEC_PKCS12DecoderOutputCallback)(
* SECITEM_AllocItem(NULL, NULL, LENGTH_OF_NEW_NICKNAME + 1)
* and data must contain the new nickname as a zero terminated string.
*/
-typedef SECItem * (PR_CALLBACK * SEC_PKCS12NicknameCollisionCallback)(
- SECItem *old_nickname,
- PRBool *cancel,
- void *arg);
+typedef SECItem *(PR_CALLBACK *SEC_PKCS12NicknameCollisionCallback)(
+ SECItem *old_nickname,
+ PRBool *cancel,
+ void *arg);
/*
* This callback is called by SEC_PKCS12DecoderRenameCertNicknames for each
* certificate found in the p12 source data.
@@ -74,16 +73,16 @@ typedef SECItem * (PR_CALLBACK * SEC_PKCS12NicknameCollisionCallback)(
* Otherwise, the callback function must return SECSuccess, including use
* default nickname as mentioned above.
*/
-typedef SECStatus (PR_CALLBACK * SEC_PKCS12NicknameRenameCallback)(
- const CERTCertificate *cert,
- const SECItem *default_nickname,
- SECItem **new_nickname,
- void *arg);
+typedef SECStatus(PR_CALLBACK *SEC_PKCS12NicknameRenameCallback)(
+ const CERTCertificate *cert,
+ const SECItem *default_nickname,
+ SECItem **new_nickname,
+ 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 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;
@@ -91,14 +90,14 @@ typedef struct SEC_PKCS12DecoderContextStr SEC_PKCS12DecoderContext;
typedef struct SEC_PKCS12DecoderItemStr SEC_PKCS12DecoderItem;
struct sec_PKCS12PasswordModeInfo {
- SECItem *password;
- SECOidTag algorithm;
+ SECItem *password;
+ SECOidTag algorithm;
};
struct sec_PKCS12PublicKeyModeInfo {
- CERTCertificate *cert;
+ CERTCertificate *cert;
CERTCertDBHandle *certDb;
- SECOidTag algorithm;
+ SECOidTag algorithm;
int keySize;
};
@@ -106,91 +105,89 @@ struct SEC_PKCS12DecoderItemStr {
SECItem *der;
SECOidTag type;
PRBool hasKey;
- SECItem *friendlyName; /* UTF-8 string */
+ 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);
+ CERTCertDBHandle *certDb,
+ CERTCertificate *signer,
+ CERTCertificate **recipients,
+ SECOidTag algorithm, int keysize);
extern SEC_PKCS12SafeInfo *
-SEC_PKCS12CreatePasswordPrivSafe(SEC_PKCS12ExportContext *p12ctxt,
- SECItem *pwitem, SECOidTag privAlg);
+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);
+ SECItem *pwitem, SECOidTag integAlg);
extern SECStatus
SEC_PKCS12AddPublicKeyIntegrity(SEC_PKCS12ExportContext *p12ctxt,
- CERTCertificate *cert, CERTCertDBHandle *certDb,
- SECOidTag algorithm, int keySize);
+ CERTCertificate *cert, CERTCertDBHandle *certDb,
+ SECOidTag algorithm, int keySize);
extern SEC_PKCS12ExportContext *
-SEC_PKCS12CreateExportContext(SECKEYGetPasswordKey pwfn, void *pwfnarg,
- PK11SlotInfo *slot, void *wincx);
+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);
+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);
+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);
-
+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);
+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);
+ void *baseSafe, void *nestedDest);
extern SECStatus
-SEC_PKCS12Encode(SEC_PKCS12ExportContext *p12exp,
- SEC_PKCS12EncoderOutputCallback output, void *outputarg);
+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);
+ digestOpenFn dOpen, digestCloseFn dClose,
+ digestIOFn dRead, digestIOFn dWrite, void *dArg);
extern SECStatus
SEC_PKCS12DecoderSetTargetTokenCAs(SEC_PKCS12DecoderContext *p12dcx,
- SECPKCS12TargetTokenCAs tokenCAs);
+ SECPKCS12TargetTokenCAs tokenCAs);
extern SECStatus
SEC_PKCS12DecoderUpdate(SEC_PKCS12DecoderContext *p12dcx, unsigned char *data,
- unsigned long len);
+ unsigned long len);
extern void
SEC_PKCS12DecoderFinish(SEC_PKCS12DecoderContext *p12dcx);
@@ -200,7 +197,7 @@ SEC_PKCS12DecoderVerify(SEC_PKCS12DecoderContext *p12dcx);
extern SECStatus
SEC_PKCS12DecoderValidateBags(SEC_PKCS12DecoderContext *p12dcx,
- SEC_PKCS12NicknameCollisionCallback nicknameCb);
+ SEC_PKCS12NicknameCollisionCallback nicknameCb);
/*
* SEC_PKCS12DecoderRenameCertNicknames() can be used to change
@@ -221,7 +218,6 @@ SEC_PKCS12DecoderRenameCertNicknames(SEC_PKCS12DecoderContext *p12dcx,
SEC_PKCS12NicknameRenameCallback nicknameCb,
void *arg);
-
extern SECStatus
SEC_PKCS12DecoderImportBags(SEC_PKCS12DecoderContext *p12dcx);
diff --git a/nss/lib/pkcs12/p12creat.c b/nss/lib/pkcs12/p12creat.c
index 65bf086..7cc72cf 100644
--- a/nss/lib/pkcs12/p12creat.c
+++ b/nss/lib/pkcs12/p12creat.c
@@ -10,7 +10,6 @@
#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.
@@ -18,17 +17,17 @@
SEC_PKCS12PFXItem *
sec_pkcs12_new_pfx(void)
{
- SEC_PKCS12PFXItem *pfx = NULL;
- PLArenaPool *poolp = NULL;
+ SEC_PKCS12PFXItem *pfx = NULL;
+ PLArenaPool *poolp = NULL;
- poolp = PORT_NewArena(SEC_ASN1_DEFAULT_ARENA_SIZE); /* XXX Different size? */
- if(poolp == NULL)
- goto loser;
+ 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 = (SEC_PKCS12PFXItem *)PORT_ArenaZAlloc(poolp,
+ sizeof(SEC_PKCS12PFXItem));
+ if (pfx == NULL)
+ goto loser;
pfx->poolp = poolp;
return pfx;
@@ -45,14 +44,14 @@ loser:
SEC_PKCS12AuthenticatedSafe *
sec_pkcs12_new_asafe(PLArenaPool *poolp)
{
- SEC_PKCS12AuthenticatedSafe *asafe = NULL;
+ 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 = (SEC_PKCS12AuthenticatedSafe *)PORT_ArenaZAlloc(poolp,
+ sizeof(SEC_PKCS12AuthenticatedSafe));
+ if (asafe == NULL)
+ goto loser;
asafe->poolp = poolp;
PORT_Memset(&asafe->old_baggage, 0, sizeof(SEC_PKCS12Baggage_OLD));
@@ -65,7 +64,7 @@ loser:
}
/* create a safe contents structure with a list of
- * length 0 with the first element being NULL
+ * length 0 with the first element being NULL
*/
SEC_PKCS12SafeContents *
sec_pkcs12_create_safe_contents(PLArenaPool *poolp)
@@ -73,31 +72,30 @@ sec_pkcs12_create_safe_contents(PLArenaPool *poolp)
SEC_PKCS12SafeContents *safe;
void *mark;
- if(poolp == NULL)
- return NULL;
+ 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;
+ 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 = (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;
+ safe->poolp = poolp;
+ safe->safe_size = 0;
PORT_ArenaUnmark(poolp, mark);
return safe;
}
@@ -112,48 +110,48 @@ sec_pkcs12_create_external_bag(SEC_PKCS12Baggage *luggage)
void *dummy, *mark;
SEC_PKCS12BaggageItem *bag;
- if(luggage == NULL) {
- return NULL;
+ 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;
+ 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 */
+ /* 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;
+ 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 = (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;
+ 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 *));
+ 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;
+ luggage->poolp,
+ sizeof(SEC_PKCS12SafeBag *));
+ if ((bag->espvks == NULL) || (bag->unencSecrets == NULL)) {
+ goto loser;
}
bag->poolp = luggage->poolp;
@@ -179,28 +177,27 @@ sec_pkcs12_create_baggage(PLArenaPool *poolp)
SEC_PKCS12Baggage *luggage;
void *mark;
- if(poolp == NULL)
- return NULL;
+ 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;
+ 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;
+ sizeof(SEC_PKCS12BaggageItem *));
+ if (luggage->bags == NULL) {
+ PORT_SetError(SEC_ERROR_NO_MEMORY);
+ PORT_ArenaRelease(poolp, mark);
+ return NULL;
}
luggage->bags[0] = NULL;
@@ -212,11 +209,10 @@ sec_pkcs12_create_baggage(PLArenaPool *poolp)
}
/* free pfx structure and associated items in the arena */
-void
+void
SEC_PKCS12DestroyPFX(SEC_PKCS12PFXItem *pfx)
{
- if (pfx != NULL && pfx->poolp != NULL)
- {
- PORT_FreeArena(pfx->poolp, PR_TRUE);
+ if (pfx != NULL && pfx->poolp != NULL) {
+ PORT_FreeArena(pfx->poolp, PR_TRUE);
}
}
diff --git a/nss/lib/pkcs12/p12d.c b/nss/lib/pkcs12/p12d.c
index ac67827..d0b6476 100644
--- a/nss/lib/pkcs12/p12d.c
+++ b/nss/lib/pkcs12/p12d.c
@@ -2,7 +2,6 @@
* License, v. 2.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"
@@ -27,9 +26,8 @@
/* This belongs in secport.h */
#define PORT_ArenaGrowArray(poolp, oldptr, type, oldnum, newnum) \
- (type *)PORT_ArenaGrow((poolp), (oldptr), \
- (oldnum) * sizeof(type), (newnum) * sizeof(type))
-
+ (type *)PORT_ArenaGrow((poolp), (oldptr), \
+ (oldnum) * sizeof(type), (newnum) * sizeof(type))
typedef struct sec_PKCS12SafeContentsContextStr sec_PKCS12SafeContentsContext;
@@ -59,10 +57,10 @@ struct sec_PKCS12SafeContentsContextStr {
};
/* opaque decoder context structure. information for decoding a pkcs 12
- * PDU are stored here as well as decoding pointers for intermediary
+ * 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 {
PLArenaPool *arena;
PK11SlotInfo *slot;
@@ -74,27 +72,27 @@ struct SEC_PKCS12DecoderContextStr {
SECItem *pwitem;
/* used for decoding the PFX structure */
- SEC_ASN1DecoderContext *pfxA1Dcx;
- sec_PKCS12PFXItem pfx;
+ SEC_ASN1DecoderContext *pfxA1Dcx;
+ sec_PKCS12PFXItem pfx;
- /* safe bags found during decoding */
- sec_PKCS12SafeBag **safeBags;
- unsigned int safeBagCount;
+ /* 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_PKCS7DecoderContext *currentASafeP7Dcx;
+ SEC_ASN1DecoderContext *aSafeA1Dcx;
+ SEC_PKCS7DecoderContext *aSafeP7Dcx;
+ SEC_PKCS7ContentInfo *aSafeCinfo;
sec_PKCS12AuthenticatedSafe authSafe;
- sec_PKCS12SafeContents safeContents;
+ sec_PKCS12SafeContents safeContents;
/* safe contents info */
- unsigned int safeContentsCnt;
+ unsigned int safeContentsCnt;
sec_PKCS12SafeContentsContext **safeContentsList;
/* HMAC info */
- sec_PKCS12MacData macData;
+ sec_PKCS12MacData macData;
/* routines for reading back the data to be hmac'd */
/* They are called as follows.
@@ -118,42 +116,41 @@ struct SEC_PKCS12DecoderContextStr {
* 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? */
+ digestOpenFn dOpen;
+ digestCloseFn dClose;
+ digestIOFn dRead, dWrite;
+ void *dArg;
+ PRBool dIsOpen; /* is the temp file created? */
/* helper functions */
- SECKEYGetPasswordKey pwfn;
- void *pwfnarg;
- PRBool swapUnicodeBytes;
+ SECKEYGetPasswordKey pwfn;
+ void *pwfnarg;
+ PRBool swapUnicodeBytes;
/* import information */
- PRBool bagsVerified;
+ 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 */
+ 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() */
+ 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
+ * safeContents bags which are nested and when decoding the
* authenticatedSafes.
*/
static SECStatus
-sec_pkcs12_decoder_begin_nested_safe_contents(sec_PKCS12SafeContentsContext
- *safeContentsCtx);
+sec_pkcs12_decoder_begin_nested_safe_contents(sec_PKCS12SafeContentsContext
+ *safeContentsCtx);
static SECStatus
sec_pkcs12_decoder_finish_nested_safe_contents(sec_PKCS12SafeContentsContext
- *safeContentsCtx);
-
+ *safeContentsCtx);
/* make sure that the PFX version being decoded is a version
* which we support.
@@ -162,56 +159,55 @@ 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 (pfx->version.len == 0) {
+ return PR_FALSE;
}
- if(DER_GetInteger(&pfx->version) > SEC_PKCS12_VERSION) {
- 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 */
+/* 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;
+ SEC_PKCS12DecoderContext *p12dcx = (SEC_PKCS12DecoderContext *)arg;
PK11SlotInfo *slot;
PK11SymKey *bulkKey;
- if(!p12dcx) {
- return NULL;
+ if (!p12dcx) {
+ return NULL;
}
/* if no slot specified, use the internal key slot */
- if(p12dcx->slot) {
- slot = PK11_ReferenceSlot(p12dcx->slot);
+ if (p12dcx->slot) {
+ slot = PK11_ReferenceSlot(p12dcx->slot);
} else {
- slot = PK11_GetInternalKeySlot();
+ slot = PK11_GetInternalKeySlot();
}
- bulkKey = PK11_PBEKeyGen(slot, algid, p12dcx->pwitem,
- PR_FALSE, p12dcx->wincx);
+ 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);
+ 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);
+ PK11_SetSymKeyUserData(bulkKey, p12dcx->pwitem, NULL);
}
-
return bulkKey;
}
@@ -219,77 +215,76 @@ sec_pkcs12_decoder_get_decrypt_key(void *arg, SECAlgorithmID *algid)
* likely, it should mirror the routines for SMIME in that regard.
*/
static PRBool
-sec_pkcs12_decoder_decryption_allowed(SECAlgorithmID *algid,
- PK11SymKey *bulkkey)
+sec_pkcs12_decoder_decryption_allowed(SECAlgorithmID *algid,
+ PK11SymKey *bulkkey)
{
PRBool decryptionAllowed = SEC_PKCS12DecryptionAllowed(algid);
- if(!decryptionAllowed) {
- return PR_FALSE;
+ 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
+ * 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)
+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
+ * not been an error in the decoding
*/
- if(!safeContentsCtx || !safeContentsCtx->p12dcx
- || safeContentsCtx->p12dcx->error) {
- return SECFailure;
+ 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
+ /* 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);
+ ? 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;
+ 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] =
+ 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->swapUnicodeBytes =
+ safeContentsCtx->p12dcx->swapUnicodeBytes;
safeContentsCtx->currentSafeBag->arena = safeContentsCtx->p12dcx->arena;
- safeContentsCtx->currentSafeBag->tokenCAs =
- safeContentsCtx->p12dcx->tokenCAs;
+ safeContentsCtx->currentSafeBag->tokenCAs =
+ safeContentsCtx->p12dcx->tokenCAs;
PORT_ArenaUnmark(p12dcx->arena, mark);
return SECSuccess;
@@ -297,11 +292,11 @@ sec_pkcs12_decoder_init_new_safe_bag(sec_PKCS12SafeContentsContext
loser:
/* if an error occurred, release the memory and set the error flag
- * the only possible errors triggered by this function are memory
+ * the only possible errors triggered by this function are memory
* related.
*/
- if(mark) {
- PORT_ArenaRelease(p12dcx->arena, mark);
+ if (mark) {
+ PORT_ArenaRelease(p12dcx->arena, mark);
}
p12dcx->error = PR_TRUE;
@@ -313,11 +308,11 @@ loser:
* 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_pkcs12_decoder_safe_bag_update(void *arg, const char *data,
+ unsigned long len, int depth,
+ SEC_ASN1EncodingPart data_kind)
{
- sec_PKCS12SafeContentsContext *safeContentsCtx =
+ sec_PKCS12SafeContentsContext *safeContentsCtx =
(sec_PKCS12SafeContentsContext *)arg;
SEC_PKCS12DecoderContext *p12dcx;
SECStatus rv;
@@ -326,23 +321,22 @@ sec_pkcs12_decoder_safe_bag_update(void *arg, const char *data,
* 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;
+ 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;
+ if (rv != SECSuccess) {
+ p12dcx->errorValue = PORT_GetError();
+ goto loser;
}
return;
loser:
- /* set the error, and finish the decoder context. because there
+ /* 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.
@@ -361,66 +355,66 @@ loser:
*/
static void
sec_pkcs12_decoder_safe_bag_notify(void *arg, PRBool before,
- void *dest, int real_depth)
+ void *dest, int real_depth)
{
- sec_PKCS12SafeContentsContext *safeContentsCtx =
+ 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;
+ 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;
+ 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;
+ 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;
+ 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;
@@ -436,58 +430,58 @@ sec_pkcs12_decoder_safe_bag_notify(void *arg, PRBool before,
*/
static void
sec_pkcs12_decoder_safe_contents_notify(void *arg, PRBool before,
- void *dest, int real_depth)
+ void *dest, int real_depth)
{
- sec_PKCS12SafeContentsContext *safeContentsCtx =
- (sec_PKCS12SafeContentsContext*)arg;
+ 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;
+ 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;
+ 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);
+ /* 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;
@@ -498,9 +492,9 @@ loser:
*/
p12dcx->error = PR_TRUE;
- if(safeContentsCtx->currentSafeBagA1Dcx) {
- SEC_ASN1DecoderFinish(safeContentsCtx->currentSafeBagA1Dcx);
- safeContentsCtx->currentSafeBagA1Dcx = NULL;
+ if (safeContentsCtx->currentSafeBagA1Dcx) {
+ SEC_ASN1DecoderFinish(safeContentsCtx->currentSafeBagA1Dcx);
+ safeContentsCtx->currentSafeBagA1Dcx = NULL;
}
SEC_ASN1DecoderClearNotifyProc(safeContentsCtx->safeContentsA1Dcx);
@@ -514,35 +508,35 @@ loser:
*/
static sec_PKCS12SafeContentsContext *
sec_pkcs12_decoder_safe_contents_init_decode(SEC_PKCS12DecoderContext *p12dcx,
- PRBool nestedSafe)
+ PRBool nestedSafe)
{
sec_PKCS12SafeContentsContext *safeContentsCtx = NULL;
const SEC_ASN1Template *theTemplate;
- if(!p12dcx || p12dcx->error) {
- return NULL;
+ 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);
+ 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;
+ if (!p12dcx->safeContentsList) {
+ p12dcx->errorValue = PORT_GetError();
+ goto loser;
}
- p12dcx->safeContentsList[p12dcx->safeContentsCnt] = safeContentsCtx =
+ p12dcx->safeContentsList[p12dcx->safeContentsCnt] = safeContentsCtx =
PORT_ArenaZNew(p12dcx->arena, sec_PKCS12SafeContentsContext);
- if(!p12dcx->safeContentsList[p12dcx->safeContentsCnt]) {
- p12dcx->errorValue = PORT_GetError();
- goto loser;
+ if (!p12dcx->safeContentsList[p12dcx->safeContentsCnt]) {
+ p12dcx->errorValue = PORT_GetError();
+ goto loser;
}
p12dcx->safeContentsList[++p12dcx->safeContentsCnt] = NULL;
@@ -553,28 +547,28 @@ sec_pkcs12_decoder_safe_contents_init_decode(SEC_PKCS12DecoderContext *p12dcx,
/* begin the decoding -- the template is based on whether we are
* decoding a nested safeContents or not.
*/
- if(nestedSafe == PR_TRUE) {
- theTemplate = sec_PKCS12NestedSafeContentsDecodeTemplate;
+ if (nestedSafe == PR_TRUE) {
+ theTemplate = sec_PKCS12NestedSafeContentsDecodeTemplate;
} else {
- theTemplate = sec_PKCS12SafeContentsDecodeTemplate;
+ 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;
+ 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);
+ SEC_ASN1DecoderSetNotifyProc(safeContentsCtx->safeContentsA1Dcx,
+ sec_pkcs12_decoder_safe_contents_notify,
+ safeContentsCtx);
return safeContentsCtx;
@@ -582,9 +576,9 @@ 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;
+ if (safeContentsCtx && safeContentsCtx->safeContentsA1Dcx) {
+ SEC_ASN1DecoderFinish(safeContentsCtx->safeContentsA1Dcx);
+ safeContentsCtx->safeContentsA1Dcx = NULL;
}
p12dcx->error = PR_TRUE;
@@ -597,32 +591,31 @@ loser:
*/
static void
sec_pkcs12_decoder_nested_safe_contents_update(void *arg, const char *buf,
- unsigned long len, int depth,
- SEC_ASN1EncodingPart data_kind)
+ unsigned long len, int depth,
+ SEC_ASN1EncodingPart data_kind)
{
- sec_PKCS12SafeContentsContext *safeContentsCtx =
+ 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;
+ if (!safeContentsCtx || !safeContentsCtx->p12dcx ||
+ safeContentsCtx->p12dcx->error || !safeContentsCtx->safeContentsA1Dcx) {
+ return;
}
/* no need to update if no data sent in */
- if(!len || !buf) {
- return;
+ 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;
+ if (rv != SECSuccess) {
+ p12dcx->errorValue = PORT_GetError();
+ goto loser;
}
return;
@@ -630,65 +623,65 @@ sec_pkcs12_decoder_nested_safe_contents_update(void *arg, const char *buf,
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;
+ if (safeContentsCtx->safeContentsA1Dcx) {
+ SEC_ASN1DecoderFinish(safeContentsCtx->safeContentsA1Dcx);
+ safeContentsCtx->safeContentsA1Dcx = NULL;
}
}
/* whenever a new safeContentsSafeBag is encountered, we need
- * to init a safeContentsContext.
+ * to init a safeContentsContext.
*/
-static SECStatus
-sec_pkcs12_decoder_begin_nested_safe_contents(sec_PKCS12SafeContentsContext
- *safeContentsCtx)
+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;
+ 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;
+ 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);
+ 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);
+ 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
+ * proper filter and notify procs and close the decoding context
*/
static SECStatus
sec_pkcs12_decoder_finish_nested_safe_contents(sec_PKCS12SafeContentsContext
- *safeContentsCtx)
+ *safeContentsCtx)
{
/* check for error */
- if(!safeContentsCtx || !safeContentsCtx->p12dcx ||
- safeContentsCtx->p12dcx->error) {
- return SECFailure;
+ if (!safeContentsCtx || !safeContentsCtx->p12dcx ||
+ safeContentsCtx->p12dcx->error) {
+ return SECFailure;
}
- /* clean up */
+ /* clean up */
SEC_ASN1DecoderClearFilterProc(safeContentsCtx->currentSafeBagA1Dcx);
SEC_ASN1DecoderClearNotifyProc(
- safeContentsCtx->nestedSafeContentsCtx->safeContentsA1Dcx);
+ safeContentsCtx->nestedSafeContentsCtx->safeContentsA1Dcx);
SEC_ASN1DecoderFinish(
- safeContentsCtx->nestedSafeContentsCtx->safeContentsA1Dcx);
+ safeContentsCtx->nestedSafeContentsCtx->safeContentsA1Dcx);
safeContentsCtx->nestedSafeContentsCtx->safeContentsA1Dcx = NULL;
safeContentsCtx->nestedSafeContentsCtx = NULL;
@@ -700,30 +693,29 @@ sec_pkcs12_decoder_finish_nested_safe_contents(sec_PKCS12SafeContentsContext
*/
static void
sec_pkcs12_decoder_safe_contents_callback(void *arg, const char *buf,
- unsigned long len)
+ unsigned long len)
{
SECStatus rv;
- sec_PKCS12SafeContentsContext *safeContentsCtx =
+ sec_PKCS12SafeContentsContext *safeContentsCtx =
(sec_PKCS12SafeContentsContext *)arg;
SEC_PKCS12DecoderContext *p12dcx;
- /* check for error */
- if(!safeContentsCtx || !safeContentsCtx->p12dcx
- || safeContentsCtx->p12dcx->error
- || !safeContentsCtx->safeContentsA1Dcx) {
- return;
+ /* 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;
+ 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;
@@ -731,9 +723,9 @@ sec_pkcs12_decoder_safe_contents_callback(void *arg, const char *buf,
loser:
/* set the error and finish the context */
p12dcx->error = PR_TRUE;
- if(safeContentsCtx->safeContentsA1Dcx) {
- SEC_ASN1DecoderFinish(safeContentsCtx->safeContentsA1Dcx);
- safeContentsCtx->safeContentsA1Dcx = NULL;
+ if (safeContentsCtx->safeContentsA1Dcx) {
+ SEC_ASN1DecoderFinish(safeContentsCtx->safeContentsA1Dcx);
+ safeContentsCtx->safeContentsA1Dcx = NULL;
}
return;
@@ -743,8 +735,8 @@ loser:
*/
static void
sec_pkcs12_decoder_wrap_p7_update(void *arg, const char *data,
- unsigned long len, int depth,
- SEC_ASN1EncodingPart data_kind)
+ unsigned long len, int depth,
+ SEC_ASN1EncodingPart data_kind)
{
SEC_PKCS7DecoderContext *p7dcx = (SEC_PKCS7DecoderContext *)arg;
@@ -754,66 +746,65 @@ sec_pkcs12_decoder_wrap_p7_update(void *arg, const char *data,
/* 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
+ * reset state variables
*/
static void
-sec_pkcs12_decoder_asafes_notify(void *arg, PRBool before, void *dest,
- int real_depth)
+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 */
- }
+ 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;
@@ -825,35 +816,35 @@ loser:
/* wrapper for updating asafes decoding context. this function
* writes data being decoded to disk, so that a mac can be computed
- * later.
+ * later.
*/
static void
-sec_pkcs12_decoder_asafes_callback(void *arg, const char *buf,
- unsigned long len)
+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;
+ 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 (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;
- }
+ if (p12dcx->dWrite) {
+ unsigned long writeLen = (*p12dcx->dWrite)(p12dcx->dArg,
+ (unsigned char *)buf, len);
+ if (writeLen != len) {
+ p12dcx->errorValue = PORT_GetError();
+ goto loser;
+ }
}
return;
@@ -866,43 +857,42 @@ loser:
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;
+ 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;
+ 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);
+ 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;
+ 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;
@@ -912,47 +902,47 @@ sec_pkcs12_decode_start_asafes_cinfo(SEC_PKCS12DecoderContext *p12dcx)
loser:
p12dcx->error = PR_TRUE;
- if(p12dcx->aSafeA1Dcx) {
- SEC_ASN1DecoderFinish(p12dcx->aSafeA1Dcx);
- p12dcx->aSafeA1Dcx = NULL;
- }
+ if (p12dcx->aSafeA1Dcx) {
+ SEC_ASN1DecoderFinish(p12dcx->aSafeA1Dcx);
+ p12dcx->aSafeA1Dcx = NULL;
+ }
- if(p12dcx->aSafeP7Dcx) {
- SEC_PKCS7DecoderFinish(p12dcx->aSafeP7Dcx);
- p12dcx->aSafeP7Dcx = 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
+ * a filter for the pfx when decoding the authenticated safes
*/
-static void
+static void
sec_pkcs12_decode_asafes_cinfo_update(void *arg, const char *buf,
- unsigned long len, int depth,
- SEC_ASN1EncodingPart data_kind)
+ unsigned long len, int depth,
+ SEC_ASN1EncodingPart data_kind)
{
SEC_PKCS12DecoderContext *p12dcx;
SECStatus rv;
- p12dcx = (SEC_PKCS12DecoderContext*)arg;
- if(!p12dcx || p12dcx->error) {
- return;
+ 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;
+ 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
+ /* did we find an error? if so, close the context and set the
* error flag.
*/
SEC_PKCS7DecoderFinish(p12dcx->aSafeP7Dcx);
@@ -966,61 +956,59 @@ loser:
* 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
+static void
sec_pkcs12_decoder_pfx_notify_proc(void *arg, PRBool before, void *dest,
- int real_depth)
+ int real_depth)
{
SECStatus rv;
- SEC_PKCS12DecoderContext *p12dcx = (SEC_PKCS12DecoderContext*)arg;
+ SEC_PKCS12DecoderContext *p12dcx = (SEC_PKCS12DecoderContext *)arg;
- /* if an error occurs, clear the notifyProc and the filterProc
- * and continue.
+ /* 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 (p12dcx->error) {
+ SEC_ASN1DecoderClearNotifyProc(p12dcx->pfxA1Dcx);
+ SEC_ASN1DecoderClearFilterProc(p12dcx->pfxA1Dcx);
+ return;
}
- if(before && (dest == &p12dcx->pfx.encodedAuthSafe)) {
+ 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;
- }
+ /* 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;
- }
+ /* 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);
+ /* 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;
- }
+ 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;
@@ -1030,7 +1018,7 @@ loser:
}
/* default implementations of the open/close/read/write functions for
- SEC_PKCS12DecoderStart
+ SEC_PKCS12DecoderStart
*/
#define DEFAULT_TEMP_SIZE 4096
@@ -1038,7 +1026,7 @@ loser:
static SECStatus
p12u_DigestOpen(void *arg, PRBool readData)
{
- SEC_PKCS12DecoderContext* p12cxt = arg;
+ SEC_PKCS12DecoderContext *p12cxt = arg;
p12cxt->currentpos = 0;
@@ -1048,9 +1036,7 @@ p12u_DigestOpen(void *arg, PRBool readData)
p12cxt->allocated = DEFAULT_TEMP_SIZE;
p12cxt->buffer = PORT_Alloc(DEFAULT_TEMP_SIZE);
PR_ASSERT(p12cxt->buffer);
- }
- else
- {
+ } else {
PR_ASSERT(p12cxt->buffer);
if (!p12cxt->buffer) {
return SECFailure; /* no data to read */
@@ -1063,7 +1049,7 @@ p12u_DigestOpen(void *arg, PRBool readData)
static SECStatus
p12u_DigestClose(void *arg, PRBool removeFile)
{
- SEC_PKCS12DecoderContext* p12cxt = arg;
+ SEC_PKCS12DecoderContext *p12cxt = arg;
PR_ASSERT(p12cxt);
if (!p12cxt) {
@@ -1091,18 +1077,18 @@ static int
p12u_DigestRead(void *arg, unsigned char *buf, unsigned long len)
{
int toread = len;
- SEC_PKCS12DecoderContext* p12cxt = arg;
+ SEC_PKCS12DecoderContext *p12cxt = arg;
- if(!buf || len == 0 || !p12cxt->buffer) {
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- return -1;
+ 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);
+ memcpy(buf, (char *)p12cxt->buffer + p12cxt->currentpos, toread);
p12cxt->currentpos += toread;
return toread;
}
@@ -1110,22 +1096,21 @@ p12u_DigestRead(void *arg, unsigned char *buf, unsigned long len)
static int
p12u_DigestWrite(void *arg, unsigned char *buf, unsigned long len)
{
- SEC_PKCS12DecoderContext* p12cxt = arg;
+ SEC_PKCS12DecoderContext *p12cxt = arg;
- if(!buf || len == 0) {
+ if (!buf || len == 0) {
return -1;
}
- if (p12cxt->currentpos+(long)len > p12cxt->filesize) {
+ if (p12cxt->currentpos + (long)len > p12cxt->filesize) {
p12cxt->filesize = p12cxt->currentpos + len;
- }
- else {
+ } else {
p12cxt->filesize += len;
}
if (p12cxt->filesize > p12cxt->allocated) {
- void* newbuffer;
+ void *newbuffer;
size_t newsize = p12cxt->filesize + DEFAULT_TEMP_SIZE;
- newbuffer = PORT_Realloc(p12cxt->buffer, newsize);
+ newbuffer = PORT_Realloc(p12cxt->buffer, newsize);
if (NULL == newbuffer) {
return -1; /* can't extend the buffer */
}
@@ -1133,54 +1118,54 @@ p12u_DigestWrite(void *arg, unsigned char *buf, unsigned long len)
p12cxt->allocated = newsize;
}
PR_ASSERT(p12cxt->buffer);
- memcpy((char*)p12cxt->buffer + p12cxt->currentpos, buf, len);
+ 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.
+ * 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.
+ * 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.
+ * 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)
+ digestOpenFn dOpen, digestCloseFn dClose,
+ digestIOFn dRead, digestIOFn dWrite, void *dArg)
{
SEC_PKCS12DecoderContext *p12dcx;
PLArenaPool *arena;
arena = PORT_NewArena(2048); /* different size? */
- if(!arena) {
- return NULL; /* error is already set */
+ 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 (!p12dcx) {
+ goto loser; /* error is already set */
}
if (!dOpen && !dClose && !dRead && !dWrite && !dArg) {
@@ -1189,13 +1174,13 @@ SEC_PKCS12DecoderStart(SECItem *pwitem, PK11SlotInfo *slot, void *wincx,
dClose = p12u_DigestClose;
dRead = p12u_DigestRead;
dWrite = p12u_DigestWrite;
- dArg = (void*)p12dcx;
+ dArg = (void *)p12dcx;
}
p12dcx->arena = arena;
p12dcx->pwitem = pwitem;
- p12dcx->slot = (slot ? PK11_ReferenceSlot(slot)
- : PK11_GetInternalKeySlot());
+ p12dcx->slot = (slot ? PK11_ReferenceSlot(slot)
+ : PK11_GetInternalKeySlot());
p12dcx->wincx = wincx;
p12dcx->tokenCAs = SECPKCS12TargetTokenNoCAs;
#ifdef IS_LITTLE_ENDIAN
@@ -1210,16 +1195,16 @@ SEC_PKCS12DecoderStart(SECItem *pwitem, PK11SlotInfo *slot, void *wincx,
* for the PFX item.
*/
p12dcx->pfxA1Dcx = SEC_ASN1DecoderStart(p12dcx->arena, &p12dcx->pfx,
- sec_PKCS12PFXItemTemplate);
- if(!p12dcx->pfxA1Dcx) {
- PK11_FreeSlot(p12dcx->slot);
- goto loser;
+ sec_PKCS12PFXItemTemplate);
+ if (!p12dcx->pfxA1Dcx) {
+ PK11_FreeSlot(p12dcx->slot);
+ goto loser;
}
- SEC_ASN1DecoderSetNotifyProc(p12dcx->pfxA1Dcx,
- sec_pkcs12_decoder_pfx_notify_proc,
- p12dcx);
-
+ SEC_ASN1DecoderSetNotifyProc(p12dcx->pfxA1Dcx,
+ sec_pkcs12_decoder_pfx_notify_proc,
+ p12dcx);
+
/* set up digest functions */
p12dcx->dOpen = dOpen;
p12dcx->dWrite = dWrite;
@@ -1227,7 +1212,7 @@ SEC_PKCS12DecoderStart(SECItem *pwitem, PK11SlotInfo *slot, void *wincx,
p12dcx->dRead = dRead;
p12dcx->dArg = dArg;
p12dcx->dIsOpen = PR_FALSE;
-
+
p12dcx->keyList = NULL;
p12dcx->decitem.type = 0;
p12dcx->decitem.der = NULL;
@@ -1244,40 +1229,39 @@ loser:
SECStatus
SEC_PKCS12DecoderSetTargetTokenCAs(SEC_PKCS12DecoderContext *p12dcx,
- SECPKCS12TargetTokenCAs tokenCAs)
+ SECPKCS12TargetTokenCAs tokenCAs)
{
if (!p12dcx || p12dcx->error) {
- return SECFailure;
+ return SECFailure;
}
p12dcx->tokenCAs = tokenCAs;
return SECSuccess;
}
-
-/* SEC_PKCS12DecoderUpdate
- * Streaming update sending more data to the decoder. If
- * an error occurs, SECFailure is returned.
+/* 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.
+ * 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)
+ unsigned char *data, unsigned long len)
{
SECStatus rv;
- if(!p12dcx || p12dcx->error) {
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- return SECFailure;
+ 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;
+ if (rv != SECSuccess) {
+ p12dcx->errorValue = SEC_ERROR_PKCS12_CORRUPT_PFX_STRUCTURE;
+ goto loser;
}
return SECSuccess;
@@ -1288,53 +1272,53 @@ loser:
return SECFailure;
}
-/* This should be a nice sized buffer for reading in data (potentially large
+/* 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
+#define IN_BUF_LEN 1024
#ifdef DEBUG
-static const char bufferEnd[] = { "BufferEnd" } ;
+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
+ * 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};
+ 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;
+
+ 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. */
+ 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);
+ if (p12dcx->macData.iter.data) {
+ iteration = (int)DER_GetInteger(&p12dcx->macData.iter);
} else {
- iteration = 1;
+ iteration = 1;
}
params = PK11_CreatePBEParams(&p12dcx->macData.macSalt, p12dcx->pwitem,
@@ -1342,70 +1326,73 @@ sec_pkcs12_decoder_verify_mac(SEC_PKCS12DecoderContext *p12dcx)
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;
+ 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;
+ if (!symKey)
+ goto loser;
/* init hmac */
pk11cx = PK11_CreateContextBySymKey(sec_pkcs12_algtag_to_mech(algtag),
CKA_SIGN, symKey, &ignore);
- if(!pk11cx) {
- goto loser;
+ if (!pk11cx) {
+ goto loser;
}
lrv = PK11_DigestBegin(pk11cx);
- if (lrv == SECFailure ) {
- goto loser;
+ if (lrv == SECFailure) {
+ goto loser;
}
/* try to open the data for readback */
- if(p12dcx->dOpen && ((*p12dcx->dOpen)(p12dcx->dArg, PR_TRUE)
- != SECSuccess)) {
- goto loser;
+ 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
+ * 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;
- }
- }
+ 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;
+ if (lrv == SECFailure) {
+ goto loser;
}
hmacRes.data = buf;
@@ -1413,27 +1400,26 @@ sec_pkcs12_decoder_verify_mac(SEC_PKCS12DecoderContext *p12dcx)
/* 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;
+ 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 (p12dcx->dClose) {
+ (*p12dcx->dClose)(p12dcx->dArg, PR_TRUE);
+ p12dcx->dIsOpen = PR_FALSE;
}
- if(pk11cx) {
- PK11_DestroyContext(pk11cx, PR_TRUE);
+ if (pk11cx) {
+ PK11_DestroyContext(pk11cx, PR_TRUE);
}
if (params) {
- PK11_DestroyPBEParams(params);
+ PK11_DestroyPBEParams(params);
}
if (symKey) {
- PK11_FreeSymKey(symKey);
+ PK11_FreeSymKey(symKey);
}
PORT_ZFree(buf, IN_BUF_LEN + FUDGE);
@@ -1441,11 +1427,11 @@ loser:
}
/* 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.
+ * 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
+ * p12dcx - the decoder context
*/
SECStatus
SEC_PKCS12DecoderVerify(SEC_PKCS12DecoderContext *p12dcx)
@@ -1453,112 +1439,112 @@ 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) {
+ PORT_SetError(SEC_ERROR_INVALID_ARGS);
+ return SECFailure;
}
- if(p12dcx->error) {
- /* error code is already set! PORT_SetError(p12dcx->errorValue); */
- 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;
+ 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,
+ 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;
- }
+ 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.
+ * 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
+ * p12dcx - the decoder context
*/
void
SEC_PKCS12DecoderFinish(SEC_PKCS12DecoderContext *p12dcx)
{
unsigned int i;
- if(!p12dcx) {
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- return;
+ if (!p12dcx) {
+ PORT_SetError(SEC_ERROR_INVALID_ARGS);
+ return;
}
- if(p12dcx->pfxA1Dcx) {
- SEC_ASN1DecoderFinish(p12dcx->pfxA1Dcx);
- p12dcx->pfxA1Dcx = NULL;
+ if (p12dcx->pfxA1Dcx) {
+ SEC_ASN1DecoderFinish(p12dcx->pfxA1Dcx);
+ p12dcx->pfxA1Dcx = NULL;
}
- if(p12dcx->aSafeA1Dcx) {
- SEC_ASN1DecoderFinish(p12dcx->aSafeA1Dcx);
- p12dcx->aSafeA1Dcx = 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;
- }
- }
+ 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 != 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->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->aSafeCinfo) {
+ SEC_PKCS7DestroyContentInfo(p12dcx->aSafeCinfo);
+ p12dcx->aSafeCinfo = NULL;
}
if (p12dcx->decitem.type != 0 && p12dcx->decitem.der != NULL) {
@@ -1568,64 +1554,64 @@ SEC_PKCS12DecoderFinish(SEC_PKCS12DecoderContext *p12dcx)
SECITEM_FreeItem(p12dcx->decitem.friendlyName, PR_TRUE);
}
- if(p12dcx->slot) {
- PK11_FreeSlot(p12dcx->slot);
- p12dcx->slot = NULL;
+ 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->dIsOpen && p12dcx->dClose) {
+ (*p12dcx->dClose)(p12dcx->dArg, PR_TRUE);
+ p12dcx->dIsOpen = PR_FALSE;
}
- if(p12dcx->arena) {
- PORT_FreeArena(p12dcx->arena, PR_TRUE);
+ if (p12dcx->arena) {
+ PORT_FreeArena(p12dcx->arena, PR_TRUE);
}
}
static SECStatus
sec_pkcs12_decoder_set_attribute_value(sec_PKCS12SafeBag *bag,
- SECOidTag attributeType,
- SECItem *attrValue)
+ SECOidTag attributeType,
+ SECItem *attrValue)
{
int i = 0;
SECOidData *oid;
- if(!bag || !attrValue) {
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- return SECFailure;
+ if (!bag || !attrValue) {
+ PORT_SetError(SEC_ERROR_INVALID_ARGS);
+ return SECFailure;
}
oid = SECOID_FindOIDByTag(attributeType);
- if(!oid) {
- return SECFailure;
+ if (!oid) {
+ return SECFailure;
}
- if(!bag->attribs) {
- bag->attribs =
- PORT_ArenaZNewArray(bag->arena, sec_PKCS12Attribute *, 2);
+ 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);
+ while (bag->attribs[i])
+ i++;
+ bag->attribs = PORT_ArenaGrowArray(bag->arena, bag->attribs,
+ sec_PKCS12Attribute *, i + 1, i + 2);
}
- if(!bag->attribs) {
- return SECFailure;
+ if (!bag->attribs) {
+ return SECFailure;
}
bag->attribs[i] = PORT_ArenaZNew(bag->arena, sec_PKCS12Attribute);
- if(!bag->attribs) {
- return SECFailure;
+ if (!bag->attribs[i]) {
+ return SECFailure;
}
bag->attribs[i]->attrValue = PORT_ArenaZNewArray(bag->arena, SECItem *, 2);
- if(!bag->attribs[i]->attrValue) {
- return SECFailure;
+ if (!bag->attribs[i]->attrValue) {
+ return SECFailure;
}
- bag->attribs[i+1] = NULL;
+ bag->attribs[i + 1] = NULL;
bag->attribs[i]->attrValue[0] = attrValue;
bag->attribs[i]->attrValue[1] = NULL;
@@ -1634,19 +1620,19 @@ sec_pkcs12_decoder_set_attribute_value(sec_PKCS12SafeBag *bag,
static SECItem *
sec_pkcs12_get_attribute_value(sec_PKCS12SafeBag *bag,
- SECOidTag attributeType)
+ SECOidTag attributeType)
{
int i;
- if(!bag->attribs) {
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- return NULL;
+ 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];
- }
+ if (SECOID_FindOIDTag(&bag->attribs[i]->attrType) == attributeType) {
+ return bag->attribs[i]->attrValue[0];
+ }
}
return NULL;
}
@@ -1664,29 +1650,28 @@ sec_pkcs12_sanitize_nickname(PK11SlotInfo *slot, SECItem *nick)
char *nickname;
char *delimit;
int delimitlen;
-
- nickname = (char*)nick->data;
+
+ 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);
- }
-
+ 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 *
@@ -1694,9 +1679,9 @@ sec_pkcs12_get_nickname(sec_PKCS12SafeBag *bag)
{
SECItem *src, *dest;
- if(!bag) {
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- return NULL;
+ if (!bag) {
+ PORT_SetError(SEC_ERROR_INVALID_ARGS);
+ return NULL;
}
src = sec_pkcs12_get_attribute_value(bag, SEC_OID_PKCS9_FRIENDLY_NAME);
@@ -1704,17 +1689,17 @@ sec_pkcs12_get_nickname(sec_PKCS12SafeBag *bag)
/* 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;
+ 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;
+ 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;
+ 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);
@@ -1722,8 +1707,8 @@ sec_pkcs12_get_nickname(sec_PKCS12SafeBag *bag)
return dest;
loser:
- if(dest) {
- SECITEM_ZfreeItem(dest, PR_TRUE);
+ if (dest) {
+ SECITEM_ZfreeItem(dest, PR_TRUE);
}
bag->problem = PR_TRUE;
@@ -1737,80 +1722,77 @@ 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;
- }
+ 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;
- }
- }
+ 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;
+ 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;
+ if (!sec_pkcs12_convert_item_to_unicode(bag->arena, attr->attrValue[0],
+ name, PR_FALSE, PR_FALSE, PR_TRUE)) {
+ goto loser;
}
return SECSuccess;
@@ -1820,50 +1802,49 @@ loser:
bag->error = PORT_GetError();
return SECFailure;
}
-
+
static SECStatus
-sec_pkcs12_get_key_info(sec_PKCS12SafeBag *key)
+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 (!key) {
+ PORT_SetError(SEC_ERROR_INVALID_ARGS);
+ return SECFailure;
}
- /* if the bag does *not* contain an unencrypted PrivateKeyInfo
+ /* 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;
+ if (SECOID_FindOIDTag(&(key->safeBagType)) !=
+ SEC_OID_PKCS12_V1_KEY_BAG_ID) {
+ return SECSuccess;
}
pki = key->safeBagContent.pkcs8KeyBag;
- if(!pki || !pki->attributes) {
- return SECSuccess;
+ if (!pki || !pki->attributes) {
+ return SECSuccess;
}
- while(pki->attributes[i]) {
- SECOidTag tag = SECOID_FindOIDTag(&pki->attributes[i]->attrType);
+ 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++;
+ 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;
@@ -1874,28 +1855,27 @@ sec_pkcs12_get_key_info(sec_PKCS12SafeBag *key)
*/
static SECItem *
sec_pkcs12_get_nickname_for_cert(sec_PKCS12SafeBag *cert,
- sec_PKCS12SafeBag *key)
+ sec_PKCS12SafeBag *key)
{
SECItem *nickname;
- if(!cert) {
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- return NULL;
+ if (!cert) {
+ PORT_SetError(SEC_ERROR_INVALID_ARGS);
+ return NULL;
}
nickname = sec_pkcs12_get_nickname(cert);
- if(nickname) {
- return nickname;
+ 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;
- }
+ 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;
@@ -1903,25 +1883,25 @@ sec_pkcs12_get_nickname_for_cert(sec_PKCS12SafeBag *cert,
/* set the nickname for the certificate */
static SECStatus
-sec_pkcs12_set_nickname_for_cert(sec_PKCS12SafeBag *cert,
- sec_PKCS12SafeBag *key,
- SECItem *nickname)
+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 (!nickname || !cert) {
+ PORT_SetError(SEC_ERROR_INVALID_ARGS);
+ return SECFailure;
}
- if(sec_pkcs12_set_nickname(cert, nickname) != SECSuccess) {
- 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;
- }
+ if (key) {
+ if (sec_pkcs12_set_nickname(key, nickname) != SECSuccess) {
+ cert->problem = PR_TRUE;
+ cert->error = key->error;
+ return SECFailure;
+ }
}
return SECSuccess;
@@ -1929,23 +1909,22 @@ sec_pkcs12_set_nickname_for_cert(sec_PKCS12SafeBag *cert,
/* retrieve the DER cert from the cert bag */
static SECItem *
-sec_pkcs12_get_der_cert(sec_PKCS12SafeBag *cert)
+sec_pkcs12_get_der_cert(sec_PKCS12SafeBag *cert)
{
- if(!cert) {
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- return NULL;
+ if (!cert) {
+ PORT_SetError(SEC_ERROR_INVALID_ARGS);
+ return NULL;
}
- if(SECOID_FindOIDTag(&cert->safeBagType) != SEC_OID_PKCS12_V1_CERT_BAG_ID) {
- 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;
+ if (SECOID_FindOIDTag(&cert->safeBagContent.certBag->bagID) != SEC_OID_PKCS9_X509_CERT) {
+ return NULL;
}
-
+
return SECITEM_DupItem(&(cert->safeBagContent.certBag->value.x509Cert));
}
@@ -1956,15 +1935,15 @@ struct certNickInfo {
unsigned int error;
};
-/* callback for traversing certificates to gather the nicknames
+/* 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)
{
@@ -1972,13 +1951,13 @@ gatherNicknames(CERTCertificate *cert, void *arg)
SECItem tempNick;
unsigned int i;
- if(!cert || !nickArg || nickArg->error) {
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- return SECFailure;
+ if (!cert || !nickArg || nickArg->error) {
+ PORT_SetError(SEC_ERROR_INVALID_ARGS);
+ return SECFailure;
}
- if(!cert->nickname) {
- return SECSuccess;
+ if (!cert->nickname) {
+ return SECSuccess;
}
tempNick.data = (unsigned char *)cert->nickname;
@@ -1986,46 +1965,44 @@ gatherNicknames(CERTCertificate *cert, void *arg)
tempNick.type = siAsciiString;
/* do we already have the nickname in the list? */
- if(nickArg->nNicks > 0) {
+ 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;
- }
+ /* 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;
- }
- }
+ 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);
+ 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;
+ 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;
+ 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;
+ if (SECITEM_CopyItem(nickArg->arena, nickArg->nickList[nickArg->nNicks],
+ &tempNick) != SECSuccess) {
+ nickArg->error = PORT_GetError();
+ return SECFailure;
}
nickArg->nNicks++;
@@ -2035,7 +2012,7 @@ gatherNicknames(CERTCertificate *cert, void *arg)
/* 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.
+ * If so, return it.
*/
static SECItem *
sec_pkcs12_get_existing_nick_for_dn(sec_PKCS12SafeBag *cert)
@@ -2045,71 +2022,71 @@ sec_pkcs12_get_existing_nick_for_dn(sec_PKCS12SafeBag *cert)
PLArenaPool *arena = NULL;
CERTCertificate *tempCert;
- if(!cert) {
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- return NULL;
+ if (!cert) {
+ PORT_SetError(SEC_ERROR_INVALID_ARGS);
+ return NULL;
}
derCert = sec_pkcs12_get_der_cert(cert);
- if(!derCert) {
- return NULL;
+ if (!derCert) {
+ return NULL;
}
tempCert = CERT_DecodeDERCertificate(derCert, PR_FALSE, NULL);
- if(!tempCert) {
- returnDn = NULL;
- goto loser;
+ if (!tempCert) {
+ returnDn = NULL;
+ goto loser;
}
arena = PORT_NewArena(1024);
- if(!arena) {
- returnDn = NULL;
- goto loser;
+ if (!arena) {
+ returnDn = NULL;
+ goto loser;
}
nickArg = PORT_ArenaZNew(arena, struct certNickInfo);
- if(!nickArg) {
- returnDn = NULL;
- goto loser;
+ 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
+ /* 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 (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->error) {
+ /* XXX do we want to set the error? */
+ returnDn = NULL;
+ goto loser;
}
-
- if(nickArg->nNicks == 0) {
- 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 (arena) {
+ PORT_FreeArena(arena, PR_TRUE);
}
- if(tempCert) {
- CERT_DestroyCertificate(tempCert);
+ if (tempCert) {
+ CERT_DestroyCertificate(tempCert);
}
- if(derCert) {
- SECITEM_FreeItem(derCert, PR_TRUE);
+ if (derCert) {
+ SECITEM_FreeItem(derCert, PR_TRUE);
}
return (returnDn);
@@ -2121,9 +2098,9 @@ countCertificate(CERTCertificate *cert, void *arg)
{
unsigned int *nCerts = (unsigned int *)arg;
- if(!cert || !arg) {
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- return SECFailure;
+ if (!cert || !arg) {
+ PORT_SetError(SEC_ERROR_INVALID_ARGS);
+ return SECFailure;
}
(*nCerts)++;
@@ -2135,164 +2112,164 @@ 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;
+ 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);
+ 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,
+ *
+ * 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)
+ 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 (!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 (!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;
+ 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;
+ 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;
+ 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.
+ * 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.
+ * 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 */
+ 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 (certNickname) {
+ SECITEM_ZfreeItem(certNickname, PR_TRUE);
}
- if(existingDNNick) {
- SECITEM_ZfreeItem(existingDNNick, PR_TRUE);
+ if (existingDNNick) {
+ SECITEM_ZfreeItem(existingDNNick, PR_TRUE);
}
}
-static void
+static void
sec_pkcs12_validate_cert(sec_PKCS12SafeBag *cert,
- sec_PKCS12SafeBag *key,
- SEC_PKCS12NicknameCollisionCallback nicknameCb)
+ sec_PKCS12SafeBag *key,
+ SEC_PKCS12NicknameCollisionCallback nicknameCb)
{
CERTCertificate *leafCert;
- if(!cert) {
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- return;
+ 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 (!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;
+ 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;
@@ -2301,12 +2278,12 @@ sec_pkcs12_validate_cert(sec_PKCS12SafeBag *cert,
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;
+ &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);
@@ -2316,43 +2293,43 @@ sec_pkcs12_validate_cert(sec_PKCS12SafeBag *cert,
static void
sec_pkcs12_validate_key_by_cert(sec_PKCS12SafeBag *cert, sec_PKCS12SafeBag *key,
- void *wincx)
+ void *wincx)
{
CERTCertificate *leafCert;
SECKEYPrivateKey *privk;
- if(!key) {
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- return;
+ 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;
+ 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;
+ &(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) {
+ privk = PK11_FindKeyByDERCert(key->slot, leafCert, wincx);
+ }
+
+ if (privk) {
+ SECKEY_DestroyPrivateKey(privk);
+ key->noInstall = PR_TRUE;
}
-
- if(privk) {
- SECKEY_DestroyPrivateKey(privk);
- key->noInstall = PR_TRUE;
- }
CERT_DestroyCertificate(leafCert);
}
@@ -2365,13 +2342,13 @@ sec_pkcs12_add_cert(sec_PKCS12SafeBag *cert, PRBool keyExists, void *wincx)
PRBool isIntermediateCA;
SECStatus rv;
- if(!cert) {
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- return SECFailure;
+ if (!cert) {
+ PORT_SetError(SEC_ERROR_INVALID_ARGS);
+ return SECFailure;
}
- if(cert->problem || cert->noInstall || cert->installed) {
- return SECSuccess;
+ if (cert->problem || cert->noInstall || cert->installed) {
+ return SECSuccess;
}
derCert = &cert->safeBagContent.certBag->value.x509Cert;
@@ -2379,47 +2356,49 @@ sec_pkcs12_add_cert(sec_PKCS12SafeBag *cert, PRBool keyExists, void *wincx)
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);
+ 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);
+ rv = PK11_ImportDERCert(cert->slot, derCert, CK_INVALID_HANDLE,
+ nickData, PR_FALSE);
}
if (rv) {
- cert->problem = 1;
- cert->error = PORT_GetError();
+ cert->problem = 1;
+ cert->error = PORT_GetError();
}
cert->installed = PR_TRUE;
- if(nickName) SECITEM_ZfreeItem(nickName, PR_TRUE);
+ if (nickName)
+ SECITEM_ZfreeItem(nickName, PR_TRUE);
return rv;
}
@@ -2427,9 +2406,9 @@ 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)
+sec_pkcs12_add_key(sec_PKCS12SafeBag *key, SECKEYPublicKey *pubKey,
+ unsigned int keyUsage,
+ SECItem *nickName, void *wincx)
{
SECStatus rv;
SECItem *publicValue = NULL;
@@ -2437,146 +2416,142 @@ sec_pkcs12_add_key(sec_PKCS12SafeBag *key, SECKEYPublicKey *pubKey,
/* 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 || !pubKey) {
+ PORT_SetError(SEC_ERROR_INVALID_ARGS);
+ return SECFailure;
}
- if(key->problem || key->noInstall) {
- return SECSuccess;
+ 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;
+ 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;
+ /* 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.
+/*
+ * 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
+ * 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.
+ * 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
+ * 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_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 || !bag) {
+ PORT_SetError(SEC_ERROR_INVALID_ARGS);
+ return SECFailure;
}
- if(!(*bagList)) {
- newBagList = PORT_ArenaZNewArray(bag->arena, sec_PKCS12SafeBag *, 2);
+ 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);
+ 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;
+ if (!newBagList) {
+ PORT_SetError(SEC_ERROR_NO_MEMORY);
+ return SECFailure;
}
- newBagList[i] = bag;
- newBagList[i+1] = NULL;
+ 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_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;
+ 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;
+ 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;
- }
- }
- }
+ 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;
@@ -2590,37 +2565,36 @@ SEC_PKCS12DecoderGetCerts(SEC_PKCS12DecoderContext *p12dcx)
int i;
if (!p12dcx || !p12dcx->safeBags || !p12dcx->safeBags[0]) {
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- return NULL;
+ PORT_SetError(SEC_ERROR_INVALID_ARGS);
+ return NULL;
}
safeBags = p12dcx->safeBags;
certList = CERT_NewCertList();
if (certList == NULL) {
- return 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.
- */
+ 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;
@@ -2632,119 +2606,118 @@ sec_pkcs12_get_key_bags(sec_PKCS12SafeBag **safeBags)
sec_PKCS12SafeBag **keyList = NULL;
SECOidTag bagType;
- if(!safeBags || !safeBags[0]) {
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- return NULL;
+ 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;
- }
+ 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
+/* 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)
+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 || !nicknameCb) {
+ PORT_SetError(SEC_ERROR_INVALID_ARGS);
+ return SECFailure;
}
- if(!safeBags[0]) {
- return SECSuccess;
+ if (!safeBags[0]) {
+ return SECSuccess;
}
- /* First pass. Find all the key bags.
- * Find the matching cert(s) for each key.
+ /* 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
+ 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;
- }
- }
+ 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;
@@ -2752,45 +2725,45 @@ sec_pkcs12_validate_bags(sec_PKCS12SafeBag **safeBags,
SECStatus
SEC_PKCS12DecoderValidateBags(SEC_PKCS12DecoderContext *p12dcx,
- SEC_PKCS12NicknameCollisionCallback nicknameCb)
+ 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;
+ 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;
+ 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++;
+ 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;
+ * 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
+ * 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;
+ if (probCnt) {
+ PORT_SetError(errorVal);
+ return SECFailure;
}
return rv;
@@ -2806,7 +2779,7 @@ SEC_PKCS12DecoderRenameCertNicknames(SEC_PKCS12DecoderContext *p12dcx,
CERTCertificate *cert;
SECStatus srv;
- if(!p12dcx || p12dcx->error || !p12dcx->safeBags || !nicknameCb) {
+ if (!p12dcx || p12dcx->error || !p12dcx->safeBags || !nicknameCb) {
PORT_SetError(SEC_ERROR_INVALID_ARGS);
return SECFailure;
}
@@ -2822,8 +2795,8 @@ SEC_PKCS12DecoderRenameCertNicknames(SEC_PKCS12DecoderContext *p12dcx,
}
cert = CERT_DecodeDERCertificate(
- &safeBag->safeBagContent.certBag->value.x509Cert,
- PR_FALSE, NULL);
+ &safeBag->safeBagContent.certBag->value.x509Cert,
+ PR_FALSE, NULL);
if (!cert) {
return SECFailure;
}
@@ -2857,22 +2830,22 @@ SEC_PKCS12DecoderRenameCertNicknames(SEC_PKCS12DecoderContext *p12dcx,
static SECKEYPublicKey *
sec_pkcs12_get_public_key_and_usage(sec_PKCS12SafeBag *certBag,
- unsigned int *usage)
+ unsigned int *usage)
{
SECKEYPublicKey *pubKey = NULL;
CERTCertificate *cert = NULL;
- if(!certBag || !usage) {
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- return 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;
+ &certBag->safeBagContent.certBag->value.x509Cert, PR_FALSE, NULL);
+ if (!cert) {
+ return NULL;
}
*usage = cert->keyUsage;
@@ -2883,163 +2856,163 @@ sec_pkcs12_get_public_key_and_usage(sec_PKCS12SafeBag *certBag,
static SECItem *
sec_pkcs12_get_public_value_and_type(SECKEYPublicKey *pubKey,
- KeyType *type)
+ KeyType *type)
{
SECItem *pubValue = NULL;
- if(!type || !pubKey) {
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- return 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;
+ 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;
+ 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
+ * desired slot. The two passes are intended to mirror exactly the
* two passes in sec_pkcs12_validate_bags.
*/
-static SECStatus
+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) {
+ PORT_SetError(SEC_ERROR_INVALID_ARGS);
+ return SECFailure;
}
- if(!safeBags[0]) {
- return SECSuccess;
+ if (!safeBags[0]) {
+ return SECSuccess;
}
- /* First pass. Find all the key bags.
- * Try to install them, and any certs associated with them.
+ /* 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) {
+ 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;
+ key->problem = PR_TRUE;
rv = SECFailure;
- } else {
- rv = sec_pkcs12_add_key(key, pubKey, keyUsage, nickName, wincx);
+ } 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 (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;
+ return SECFailure;
- /* Now take a second pass over the safebags and install any certs
+ /* 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;
- }
- }
+ 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;
@@ -3048,13 +3021,13 @@ sec_pkcs12_install_bags(sec_PKCS12SafeBag **safeBags, void *wincx)
SECStatus
SEC_PKCS12DecoderImportBags(SEC_PKCS12DecoderContext *p12dcx)
{
- if(!p12dcx || p12dcx->error) {
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- return SECFailure;
+ if (!p12dcx || p12dcx->error) {
+ PORT_SetError(SEC_ERROR_INVALID_ARGS);
+ return SECFailure;
}
- if(!p12dcx->bagsVerified) {
- return SECFailure;
+ if (!p12dcx->bagsVerified) {
+ return SECFailure;
}
return sec_pkcs12_install_bags(p12dcx->safeBags, p12dcx->wincx);
@@ -3071,14 +3044,14 @@ sec_pkcs12_bagHasKey(SEC_PKCS12DecoderContext *p12dcx, sec_PKCS12SafeBag *bag)
if (certKeyId == NULL) {
return PR_FALSE;
}
-
- for (i=0; p12dcx->keyList && p12dcx->keyList[i]; i++) {
+
+ 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) {
+ SEC_OID_PKCS9_LOCAL_KEY_ID);
+ if (!keyId) {
continue;
}
- if(SECITEM_CompareItem(certKeyId, keyId) == SECEqual) {
+ if (SECITEM_CompareItem(certKeyId, keyId) == SECEqual) {
return PR_TRUE;
}
}
@@ -3090,12 +3063,12 @@ 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)) {
+ tempnm, PR_TRUE, PR_FALSE, PR_FALSE)) {
SECITEM_FreeItem(friendlyName, PR_TRUE);
friendlyName = NULL;
}
@@ -3117,9 +3090,9 @@ sec_pkcs12_get_friendlyName(sec_PKCS12SafeBag *bag)
SECStatus
SEC_PKCS12DecoderIterateInit(SEC_PKCS12DecoderContext *p12dcx)
{
- if(!p12dcx || p12dcx->error) {
+ if (!p12dcx || p12dcx->error) {
PORT_SetError(SEC_ERROR_INVALID_ARGS);
- return SECFailure;
+ return SECFailure;
}
p12dcx->iteration = 0;
@@ -3131,10 +3104,10 @@ SEC_PKCS12DecoderIterateNext(SEC_PKCS12DecoderContext *p12dcx,
const SEC_PKCS12DecoderItem **ipp)
{
sec_PKCS12SafeBag *bag;
-
- if(!p12dcx || p12dcx->error) {
+
+ if (!p12dcx || p12dcx->error) {
PORT_SetError(SEC_ERROR_INVALID_ARGS);
- return SECFailure;
+ return SECFailure;
}
if (p12dcx->decitem.type != 0 && p12dcx->decitem.der != NULL) {
@@ -3156,14 +3129,13 @@ SEC_PKCS12DecoderIterateNext(SEC_PKCS12DecoderContext *p12dcx,
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) {
+ if (bag == NULL || bag->problem) {
continue;
}
p12dcx->decitem.type = SECOID_FindOIDTag(&(bag->safeBagType));
- switch(p12dcx->decitem.type) {
+ 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);
@@ -3171,11 +3143,11 @@ SEC_PKCS12DecoderIterateNext(SEC_PKCS12DecoderContext *p12dcx,
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);
- }
- /* fall through */
+ if (p12dcx->decitem.shroudAlg) {
+ SECOID_CopyAlgorithmID(NULL, p12dcx->decitem.shroudAlg,
+ &bag->safeBagContent.pkcs8ShroudedKeyBag->algorithm);
+ }
+ /* fall through */
case SEC_OID_PKCS12_V1_KEY_BAG_ID:
p12dcx->decitem.friendlyName = sec_pkcs12_get_friendlyName(bag);
break;
@@ -3188,35 +3160,35 @@ SEC_PKCS12DecoderIterateNext(SEC_PKCS12DecoderContext *p12dcx,
}
*ipp = &p12dcx->decitem;
p12dcx->iteration++;
- break; /* end for() */
+ break; /* end for() */
}
-
- PORT_SetError(0); /* end-of-list is SECFailure with no PORT error */
+
+ 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)
+ sec_PKCS12SafeBag *bag)
{
- if(!p12dcx || p12dcx->error) {
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- return SECFailure;
+ 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);
+ 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;
+ if (!p12dcx->safeBags) {
+ PORT_SetError(SEC_ERROR_NO_MEMORY);
+ return SECFailure;
}
p12dcx->safeBags[p12dcx->safeBagCount] = bag;
- p12dcx->safeBags[p12dcx->safeBagCount+1] = NULL;
+ p12dcx->safeBags[p12dcx->safeBagCount + 1] = NULL;
p12dcx->safeBagCount++;
return SECSuccess;
@@ -3224,22 +3196,22 @@ sec_pkcs12_decoder_append_bag_to_context(SEC_PKCS12DecoderContext *p12dcx,
static sec_PKCS12SafeBag *
sec_pkcs12_decoder_convert_old_key(SEC_PKCS12DecoderContext *p12dcx,
- void *key, PRBool isEspvk)
+ 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;
+ 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 = PORT_ArenaZNew(p12dcx->arena, sec_PKCS12SafeBag);
+ if (!keyBag || !newNickName) {
+ return NULL;
}
keyBag->swapUnicodeBytes = p12dcx->swapUnicodeBytes;
@@ -3249,74 +3221,72 @@ sec_pkcs12_decoder_convert_old_key(SEC_PKCS12DecoderContext *p12dcx,
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;
+ 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 (!oid) {
+ return NULL;
}
- if(SECITEM_CopyItem(p12dcx->arena, &keyBag->safeBagType, &oid->oid)
- != SECSuccess) {
- 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;
+ 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;
+ 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;
@@ -3324,7 +3294,7 @@ sec_pkcs12_decoder_convert_old_key(SEC_PKCS12DecoderContext *p12dcx,
static sec_PKCS12SafeBag *
sec_pkcs12_decoder_create_cert(SEC_PKCS12DecoderContext *p12dcx,
- SECItem *derCert)
+ SECItem *derCert)
{
sec_PKCS12SafeBag *certBag;
SECOidData *oid;
@@ -3332,33 +3302,33 @@ sec_pkcs12_decoder_create_cert(SEC_PKCS12DecoderContext *p12dcx,
SECItem *keyId;
SECStatus rv;
- if(!p12dcx || p12dcx->error || !derCert) {
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- return NULL;
+ if (!p12dcx || p12dcx->error || !derCert) {
+ PORT_SetError(SEC_ERROR_INVALID_ARGS);
+ return NULL;
}
keyId = PORT_ArenaZNew(p12dcx->arena, SECItem);
- if(!keyId) {
- return NULL;
+ if (!keyId) {
+ return NULL;
}
digest = sec_pkcs12_compute_thumbprint(derCert);
- if(!digest) {
- return NULL;
+ 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;
+ 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;
+ if (!certBag || !oid || (SECITEM_CopyItem(p12dcx->arena,
+ &certBag->safeBagType, &oid->oid) != SECSuccess)) {
+ return NULL;
}
certBag->slot = p12dcx->slot;
@@ -3368,24 +3338,24 @@ sec_pkcs12_decoder_create_cert(SEC_PKCS12DecoderContext *p12dcx,
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;
+ 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 (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;
+ if (sec_pkcs12_decoder_set_attribute_value(certBag, SEC_OID_PKCS9_LOCAL_KEY_ID,
+ keyId) != SECSuccess) {
+ return NULL;
}
return certBag;
@@ -3393,45 +3363,46 @@ sec_pkcs12_decoder_create_cert(SEC_PKCS12DecoderContext *p12dcx,
static sec_PKCS12SafeBag **
sec_pkcs12_decoder_convert_old_cert(SEC_PKCS12DecoderContext *p12dcx,
- SEC_PKCS12CertAndCRL *oldCert)
+ SEC_PKCS12CertAndCRL *oldCert)
{
sec_PKCS12SafeBag **certList;
SECItem **derCertList;
int i, j;
- if(!p12dcx || p12dcx->error || !oldCert) {
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- return NULL;
+ if (!p12dcx || p12dcx->error || !oldCert) {
+ PORT_SetError(SEC_ERROR_INVALID_ARGS);
+ return NULL;
}
derCertList = SEC_PKCS7GetCertificateList(&oldCert->value.x509->certOrCRL);
- if(!derCertList) {
- return NULL;
+ if (!derCertList) {
+ return NULL;
}
i = 0;
- while(derCertList[i]) i++;
+ while (derCertList[i])
+ i++;
certList = PORT_ArenaZNewArray(p12dcx->arena, sec_PKCS12SafeBag *, (i + 1));
- if(!certList) {
- return NULL;
+ 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;
- }
+ 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)
+ void *oldKey, PRBool isEspvk,
+ SEC_PKCS12SafeContents *safe,
+ SEC_PKCS12Baggage *baggage)
{
sec_PKCS12SafeBag *key, **certList;
SEC_PKCS12CertAndCRL *oldCert;
@@ -3439,126 +3410,124 @@ sec_pkcs12_decoder_convert_old_key_and_certs(SEC_PKCS12DecoderContext *p12dcx,
int i;
SECItem *keyName;
- if(!p12dcx || !oldKey) {
- return SECFailure;
+ if (!p12dcx || !oldKey) {
+ return SECFailure;
}
- if(isEspvk) {
- pvkData = &((SEC_PKCS12ESPVKItem *)(oldKey))->espvkData;
+ if (isEspvk) {
+ pvkData = &((SEC_PKCS12ESPVKItem *)(oldKey))->espvkData;
} else {
- pvkData = &((SEC_PKCS12PrivateKey *)(oldKey))->pvkData;
+ pvkData = &((SEC_PKCS12PrivateKey *)(oldKey))->pvkData;
}
- if(!pvkData->assocCerts || !pvkData->assocCerts[0]) {
- PORT_SetError(SEC_ERROR_PKCS12_CORRUPT_PFX_STRUCTURE);
- return SECFailure;
+ 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;
+ 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);
+
+ 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 (!key || !certList) {
+ return SECFailure;
}
- if(sec_pkcs12_decoder_append_bag_to_context(p12dcx, key) != SECSuccess) {
- 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;
+ if (!keyName) {
+ return SECFailure;
}
i = 0;
- while(certList[i]) {
- if(sec_pkcs12_decoder_append_bag_to_context(p12dcx, certList[i])
- != SECSuccess) {
- return SECFailure;
- }
- i++;
+ 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;
+ if (!certList) {
+ return SECFailure;
}
i = 0;
- while(certList[i] != 0) {
- if(sec_pkcs12_set_nickname(certList[i], keyName) != SECSuccess) {
- return SECFailure;
- }
- i++;
+ 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)
+ 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++;
- }
+ 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;
@@ -3569,39 +3538,38 @@ loser:
SEC_PKCS12DecoderContext *
sec_PKCS12ConvertOldSafeToNew(PLArenaPool *arena, PK11SlotInfo *slot,
- PRBool swapUnicode, SECItem *pwitem,
- void *wincx, SEC_PKCS12SafeContents *safe,
- SEC_PKCS12Baggage *baggage)
+ 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 (!arena || !slot || !pwitem) {
+ PORT_SetError(SEC_ERROR_INVALID_ARGS);
+ return NULL;
}
- if(!safe && !baggage) {
- 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;
+ if (!p12dcx) {
+ return NULL;
}
p12dcx->arena = arena;
p12dcx->slot = PK11_ReferenceSlot(slot);
p12dcx->wincx = wincx;
p12dcx->error = PR_FALSE;
- p12dcx->swapUnicodeBytes = swapUnicode;
+ 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;
+
+ if (sec_pkcs12_decoder_convert_old_safe_to_bags(p12dcx, safe, baggage) != SECSuccess) {
+ p12dcx->error = PR_TRUE;
+ return NULL;
}
return p12dcx;
diff --git a/nss/lib/pkcs12/p12dec.c b/nss/lib/pkcs12/p12dec.c
index 61651b0..5a94392 100644
--- a/nss/lib/pkcs12/p12dec.c
+++ b/nss/lib/pkcs12/p12dec.c
@@ -15,8 +15,8 @@
#include "cert.h"
#include "certdb.h"
#include "p12plcy.h"
-#include "p12.h"
-#include "secpkcs5.h"
+#include "p12.h"
+#include "secpkcs5.h"
/* PFX extraction and validation routines */
@@ -31,41 +31,51 @@ sec_pkcs12_decode_pfx(SECItem *der_pfx)
SEC_PKCS12PFXItem *pfx;
SECStatus rv;
- if(der_pfx == NULL) {
- return NULL;
+ if (der_pfx == NULL) {
+ return NULL;
}
/* allocate the space for a new PFX item */
pfx = sec_pkcs12_new_pfx();
- if(pfx == NULL) {
- return NULL;
+ if (pfx == NULL) {
+ return NULL;
}
- rv = SEC_ASN1DecodeItem(pfx->poolp, pfx, SEC_PKCS12PFXItemTemplate,
- der_pfx);
+ 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);
+ 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;
+ rv = SGN_CopyDigestInfo(pfx->poolp, &pfx->macData.safeMac, &pfx->old_safeMac);
+ if (rv != SECSuccess) {
+ PORT_SetError(SEC_ERROR_NO_MEMORY);
+ PORT_FreeArena(pfx->poolp, PR_TRUE);
+ return NULL;
+ }
+ rv = SECITEM_CopyItem(pfx->poolp, &pfx->macData.macSalt, &pfx->old_macSalt);
+ if (rv != SECSuccess) {
+ PORT_SetError(SEC_ERROR_NO_MEMORY);
+ PORT_FreeArena(pfx->poolp, PR_TRUE);
+ return NULL;
+ }
} else {
- pfx->old = PR_FALSE;
+ pfx->old = PR_FALSE;
}
/* convert bit string from bits to bytes */
@@ -80,84 +90,84 @@ sec_pkcs12_decode_pfx(SECItem *der_pfx)
* pwitem is the integrity password
* pfx is the decoded pfx item
*/
-static PRBool
+static PRBool
sec_pkcs12_check_pfx_mac(SEC_PKCS12PFXItem *pfx,
- SECItem *pwitem)
+ SECItem *pwitem)
{
SECItem *key = NULL, *mac = NULL, *data = NULL;
SECItem *vpwd = NULL;
SECOidTag algorithm;
PRBool ret = PR_FALSE;
- if(pfx == NULL) {
- return 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;
+ 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);
+ if (key != NULL)
+ SECITEM_ZfreeItem(key, PR_TRUE);
return ret;
}
@@ -165,22 +175,21 @@ recheckUnicodePassword:
/* 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)
+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;
+ 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;
@@ -190,25 +199,25 @@ sec_pkcs12_validate_pfx(SEC_PKCS12PFXItem *pfx,
* NULL is returned.
*/
static SEC_PKCS12PFXItem *
-sec_pkcs12_get_pfx(SECItem *pfx_data,
- SECItem *pwitem)
+sec_pkcs12_get_pfx(SECItem *pfx_data,
+ SECItem *pwitem)
{
SEC_PKCS12PFXItem *pfx;
PRBool valid_pfx;
- if((pfx_data == NULL) || (pwitem == NULL)) {
- return NULL;
+ if ((pfx_data == NULL) || (pwitem == NULL)) {
+ return NULL;
}
pfx = sec_pkcs12_decode_pfx(pfx_data);
- if(pfx == NULL) {
- return NULL;
+ if (pfx == NULL) {
+ return NULL;
}
valid_pfx = sec_pkcs12_validate_pfx(pfx, pwitem);
- if(valid_pfx != PR_TRUE) {
- SEC_PKCS12DestroyPFX(pfx);
- pfx = NULL;
+ if (valid_pfx != PR_TRUE) {
+ SEC_PKCS12DestroyPFX(pfx);
+ pfx = NULL;
}
return pfx;
@@ -227,41 +236,41 @@ sec_pkcs12_convert_old_auth_safe(SEC_PKCS12AuthenticatedSafe *asafe)
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;
+ 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;
+ if (!baggage) {
+ return SECFailure;
}
bag = sec_pkcs12_create_external_bag(baggage);
- if(!bag) {
- return SECFailure;
+ 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++;
- }
+ 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
@@ -271,110 +280,110 @@ sec_pkcs12_convert_old_auth_safe(SEC_PKCS12AuthenticatedSafe *asafe)
* old authenticated safe to the new one.
*/
static SEC_PKCS12AuthenticatedSafe *
-sec_pkcs12_decode_authenticated_safe(SEC_PKCS12PFXItem *pfx)
+sec_pkcs12_decode_authenticated_safe(SEC_PKCS12PFXItem *pfx)
{
SECItem *der_asafe = NULL;
SEC_PKCS12AuthenticatedSafe *asafe = NULL;
SECStatus rv;
- if(pfx == NULL) {
- return NULL;
+ if (pfx == NULL) {
+ return NULL;
}
der_asafe = SEC_PKCS7GetContent(&pfx->authSafe);
- if(der_asafe == NULL) {
- /* XXX set error ? */
- goto loser;
+ if (der_asafe == NULL) {
+ /* XXX set error ? */
+ goto loser;
}
asafe = sec_pkcs12_new_asafe(pfx->poolp);
- if(asafe == NULL) {
- goto loser;
+ 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;
+ 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;
+ /* 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;
+ if (rv != SECSuccess) {
+ goto loser;
}
asafe->poolp = pfx->poolp;
-
+
return asafe;
loser:
return NULL;
}
-/* validates the safe within the authenticated safe item.
+/* 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)
+ * export policy)
* PR_FALSE indicates an error, PR_TRUE indicates a valid safe
*/
-static PRBool
+static PRBool
sec_pkcs12_validate_encrypted_safe(SEC_PKCS12AuthenticatedSafe *asafe)
{
PRBool valid = PR_FALSE;
SECAlgorithmID *algid;
- if(asafe == NULL) {
- return PR_FALSE;
+ 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;
+ if (asafe->privacySalt.len != 0) {
+ valid = PR_TRUE;
+ asafe->privacySalt.len /= 8;
} else {
- PORT_SetError(SEC_ERROR_PKCS12_CORRUPT_PFX_STRUCTURE);
- return PR_FALSE;
+ 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;
+ * 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;
- }
+ 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);
+ valid = PR_FALSE;
+ PORT_SetError(SEC_ERROR_PKCS12_UNSUPPORTED_PBE_ALGORITHM);
}
return valid;
@@ -386,40 +395,39 @@ sec_pkcs12_validate_encrypted_safe(SEC_PKCS12AuthenticatedSafe *asafe)
* 3. further, makes sure safe has appropriate policies per above function
* PR_FALSE indicates failure.
*/
-static PRBool
+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;
+ 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;
- }
+ 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;
+ 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;
@@ -436,20 +444,20 @@ sec_pkcs12_get_auth_safe(SEC_PKCS12PFXItem *pfx)
SEC_PKCS12AuthenticatedSafe *asafe;
PRBool valid_safe;
- if(pfx == NULL) {
- return NULL;
+ if (pfx == NULL) {
+ return NULL;
}
asafe = sec_pkcs12_decode_authenticated_safe(pfx);
- if(asafe == NULL) {
- return NULL;
+ 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;
+ if (valid_safe != PR_TRUE) {
+ asafe = NULL;
+ } else if (asafe) {
+ asafe->baggage.poolp = asafe->poolp;
}
return asafe;
@@ -457,44 +465,44 @@ sec_pkcs12_get_auth_safe(SEC_PKCS12PFXItem *pfx)
/* 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
+ * 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
+ * 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)
+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 == 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;
- }
+ 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);
+ rv = SEC_PKCS7DecryptContents(asafe->poolp, asafe->safe,
+ (asafe->old ? pwitem : vpwd), wincx);
- if(asafe->old == PR_FALSE) {
- SECITEM_ZfreeItem(vpwd, PR_TRUE);
+ 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
+ * 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.
@@ -507,157 +515,155 @@ sec_pkcs12_get_safe_contents(SEC_PKCS12AuthenticatedSafe *asafe)
SEC_PKCS12SafeContents *safe = NULL;
SECStatus rv = SECFailure;
- if(asafe == NULL) {
- return NULL;
+ if (asafe == NULL) {
+ return NULL;
}
- safe = (SEC_PKCS12SafeContents *)PORT_ArenaZAlloc(asafe->poolp,
- sizeof(SEC_PKCS12SafeContents));
- if(safe == 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);
- }
+ 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;
+ PORT_SetError(SEC_ERROR_PKCS12_CORRUPT_PFX_STRUCTURE);
+ rv = SECFailure;
}
return safe;
}
-/* import PFX item
+/* 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
+ * on error, error code set and SECFailure returned
*/
SECStatus
SEC_PKCS12PutPFX(SECItem *der_pfx, SECItem *pwitem,
- SEC_PKCS12NicknameCollisionCallback ncCall,
- PK11SlotInfo *slot,
- void *wincx)
+ 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;
+ 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 {
+ 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;
+ rv = SECSuccess;
+ }
+ }
- p12dcx = sec_PKCS12ConvertOldSafeToNew(pfx->poolp, slot,
- pfx->swapUnicode,
- pwitem, wincx, safe_contents,
- &asafe->baggage);
- if(!p12dcx) {
- rv = SECFailure;
- goto loser;
- }
+ /* get safe contents and begin import */
+ if (rv == SECSuccess) {
+ SEC_PKCS12DecoderContext *p12dcx;
- if(SEC_PKCS12DecoderValidateBags(p12dcx, ncCall)
- != SECSuccess) {
- rv = SECFailure;
- goto loser;
- }
+ p12dcx = sec_PKCS12ConvertOldSafeToNew(pfx->poolp, slot,
+ pfx->swapUnicode,
+ pwitem, wincx, safe_contents,
+ &asafe->baggage);
+ if (!p12dcx) {
+ rv = SECFailure;
+ goto loser;
+ }
- rv = SEC_PKCS12DecoderImportBags(p12dcx);
- }
+ if (SEC_PKCS12DecoderValidateBags(p12dcx, ncCall) != SECSuccess) {
+ rv = SECFailure;
+ goto loser;
+ }
- }
+ rv = SEC_PKCS12DecoderImportBags(p12dcx);
+ }
+ }
}
loser:
- if(pfx) {
- SEC_PKCS12DestroyPFX(pfx);
+ if (pfx) {
+ SEC_PKCS12DestroyPFX(pfx);
}
return rv;
}
-PRBool
+PRBool
SEC_PKCS12ValidData(char *buf, int bufLen, long int totalLength)
{
int lengthLength;
PRBool valid = PR_FALSE;
- if(buf == NULL) {
- return 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;
- }
- }
+ 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/nss/lib/pkcs12/p12e.c b/nss/lib/pkcs12/p12e.c
index ff83156..cce1ff7 100644
--- a/nss/lib/pkcs12/p12e.c
+++ b/nss/lib/pkcs12/p12e.c
@@ -26,11 +26,11 @@ extern const int NSS_PBE_DEFAULT_ITERATION_COUNT; /* defined in p7create.c */
**
** "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.
+** "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.
+** "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
@@ -42,14 +42,14 @@ extern const int NSS_PBE_DEFAULT_ITERATION_COUNT; /* defined in p7create.c */
* before passing data on down to the next PKCS7 encoder.
*********************************/
-#define PK12_OUTPUT_BUFFER_SIZE 8192
+#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];
+ SEC_PKCS7EncoderContext *p7eCx;
+ PK11Context *hmacCx;
+ unsigned int numBytes;
+ unsigned int bufBytes;
+ char buf[PK12_OUTPUT_BUFFER_SIZE];
};
typedef struct sec_pkcs12OutputBufferStr sec_pkcs12OutputBuffer;
@@ -72,7 +72,7 @@ struct SEC_PKCS12SafeInfoStr {
/* 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 */
@@ -91,11 +91,11 @@ struct SEC_PKCS12ExportContextStr {
/* integrity information */
PRBool integrityEnabled;
- PRBool pwdIntegrity;
+ PRBool pwdIntegrity;
union {
- struct sec_PKCS12PasswordModeInfo pwdInfo;
- struct sec_PKCS12PublicKeyModeInfo pubkeyInfo;
- } integrityInfo;
+ struct sec_PKCS12PasswordModeInfo pwdInfo;
+ struct sec_PKCS12PublicKeyModeInfo pubkeyInfo;
+ } integrityInfo;
/* helper functions */
/* retrieve the password call back */
@@ -127,72 +127,71 @@ struct sec_pkcs12_hmac_and_output_info {
};
/* An encoder context which is used for the actual encoding
- * portion of PKCS 12.
+ * portion of PKCS 12.
*/
typedef struct sec_PKCS12EncoderContextStr {
PLArenaPool *arena;
SEC_PKCS12ExportContext *p12exp;
- /* encoder information - this is set up based on whether
+ /* 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;
+ 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;
+ sec_PKCS12PFXItem pfx;
+ sec_PKCS12MacData mac;
/* authenticated safe encoding tracking information */
- SEC_PKCS7ContentInfo *aSafeCinfo;
+ SEC_PKCS7ContentInfo *aSafeCinfo;
SEC_PKCS7EncoderContext *middleP7ecx;
- SEC_ASN1EncoderContext *middleA1ecx;
- unsigned int currentSafe;
+ SEC_ASN1EncoderContext *middleA1ecx;
+ unsigned int currentSafe;
/* hmac context */
- PK11Context *hmacCx;
+ PK11Context *hmacCx;
/* output buffers */
- sec_pkcs12OutputBuffer middleBuf;
- sec_pkcs12OutputBuffer innerBuf;
+ sec_pkcs12OutputBuffer middleBuf;
+ sec_pkcs12OutputBuffer innerBuf;
} sec_PKCS12EncoderContext;
-
/*********************************
* Export setup routines
*********************************/
-/* SEC_PKCS12CreateExportContext
+/* 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.
+ * required for password-authentication mode.
*/
SEC_PKCS12ExportContext *
-SEC_PKCS12CreateExportContext(SECKEYGetPasswordKey pwfn, void *pwfnarg,
- PK11SlotInfo *slot, void *wincx)
+SEC_PKCS12CreateExportContext(SECKEYGetPasswordKey pwfn, void *pwfnarg,
+ PK11SlotInfo *slot, void *wincx)
{
PLArenaPool *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;
+ 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;
+ p12ctxt = (SEC_PKCS12ExportContext *)PORT_ArenaZAlloc(arena,
+ sizeof(SEC_PKCS12ExportContext));
+ if (!p12ctxt) {
+ PORT_SetError(SEC_ERROR_NO_MEMORY);
+ goto loser;
}
/* password callback for key retrieval */
@@ -207,46 +206,45 @@ SEC_PKCS12CreateExportContext(SECKEYGetPasswordKey pwfn, void *pwfnarg,
return p12ctxt;
loser:
- if(arena) {
- PORT_FreeArena(arena, PR_TRUE);
+ 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.
+/* 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;
+ 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.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;
@@ -255,25 +253,25 @@ SEC_PKCS12AddPasswordIntegrity(SEC_PKCS12ExportContext *p12ctxt,
}
/* 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 (?)
+ * 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)
+ CERTCertificate *cert, CERTCertDBHandle *certDb,
+ SECOidTag algorithm, int keySize)
{
- if(!p12ctxt) {
- return SECFailure;
+ if (!p12ctxt) {
+ return SECFailure;
}
-
+
p12ctxt->integrityInfo.pubkeyInfo.cert = cert;
p12ctxt->integrityInfo.pubkeyInfo.certDb = certDb;
p12ctxt->integrityInfo.pubkeyInfo.algorithm = algorithm;
@@ -283,59 +281,58 @@ SEC_PKCS12AddPublicKeyIntegrity(SEC_PKCS12ExportContext *p12ctxt,
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.
+ * 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.
+ * 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;
+ 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;
+ 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;
+ 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;
+ 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] =
+ (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;
@@ -348,111 +345,111 @@ loser:
}
/* SEC_PKCS12CreatePasswordPrivSafe
- * Create a password privacy safe to store exported information in.
+ * 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.
+ * 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_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};
+ SECItem uniPwitem = { siBuffer, NULL, 0 };
- if(!p12ctxt) {
- return NULL;
+ 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 = (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->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;
+ /* 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;
+ 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;
- }
+ 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->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 (sec_pkcs12_append_safe_info(p12ctxt, safeInfo) != SECSuccess) {
+ goto loser;
}
- if(uniPwitem.data) {
- SECITEM_ZfreeItem(&uniPwitem, PR_FALSE);
+ if (uniPwitem.data) {
+ SECITEM_ZfreeItem(&uniPwitem, PR_FALSE);
}
PORT_ArenaUnmark(p12ctxt->arena, mark);
if (slot) {
- PK11_FreeSlot(slot);
+ PK11_FreeSlot(slot);
}
return safeInfo;
loser:
if (slot) {
- PK11_FreeSlot(slot);
+ PK11_FreeSlot(slot);
}
- if(safeInfo->cinfo) {
- SEC_PKCS7DestroyContentInfo(safeInfo->cinfo);
+ if (safeInfo->cinfo) {
+ SEC_PKCS7DestroyContentInfo(safeInfo->cinfo);
}
- if(uniPwitem.data) {
- SECITEM_ZfreeItem(&uniPwitem, PR_FALSE);
+ 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.
+/* SEC_PKCS12CreateUnencryptedSafe
+ * Creates an unencrypted safe within the export context.
*
- * p12ctxt - the export context
+ * p12ctxt - the export context
*/
SEC_PKCS12SafeInfo *
SEC_PKCS12CreateUnencryptedSafe(SEC_PKCS12ExportContext *p12ctxt)
@@ -460,39 +457,39 @@ SEC_PKCS12CreateUnencryptedSafe(SEC_PKCS12ExportContext *p12ctxt)
SEC_PKCS12SafeInfo *safeInfo = NULL;
void *mark = NULL;
- if(!p12ctxt) {
- return 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 = (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 (!safeInfo->cinfo) {
+ PORT_SetError(SEC_ERROR_NO_MEMORY);
+ goto loser;
}
- if(sec_pkcs12_append_safe_info(p12ctxt, safeInfo) != SECSuccess) {
- 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);
+ if (safeInfo->cinfo) {
+ SEC_PKCS7DestroyContentInfo(safeInfo->cinfo);
}
PORT_ArenaRelease(p12ctxt->arena, mark);
@@ -500,37 +497,37 @@ loser:
}
/* SEC_PKCS12CreatePubKeyEncryptedSafe
- * Creates a safe which is protected by public key encryption.
+ * 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 (?)
+ * 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)
+ CERTCertDBHandle *certDb,
+ CERTCertificate *signer,
+ CERTCertificate **recipients,
+ SECOidTag algorithm, int keysize)
{
SEC_PKCS12SafeInfo *safeInfo = NULL;
void *mark = NULL;
- if(!p12ctxt || !signer || !recipients || !(*recipients)) {
- return 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 = (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;
@@ -540,42 +537,42 @@ SEC_PKCS12CreatePubKeyEncryptedSafe(SEC_PKCS12ExportContext *p12ctxt,
* 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;
+ 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 (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;
+ 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;
+ 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
@@ -587,16 +584,16 @@ sec_PKCS12CreateSafeContents(PLArenaPool *arena)
{
sec_PKCS12SafeContents *safeContents;
- if(arena == NULL) {
- return NULL;
+ 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;
+ sizeof(sec_PKCS12SafeContents));
+ if (!safeContents) {
+ PORT_SetError(SEC_ERROR_NO_MEMORY);
+ goto loser;
}
/* set up the internal contents info */
@@ -608,44 +605,44 @@ sec_PKCS12CreateSafeContents(PLArenaPool *arena)
loser:
return NULL;
-}
+}
-/* appends a safe bag to a safeContents using the specified arena.
+/* appends a safe bag to a safeContents using the specified arena.
*/
SECStatus
sec_pkcs12_append_bag_to_safe_contents(PLArenaPool *arena,
- sec_PKCS12SafeContents *safeContents,
- sec_PKCS12SafeBag *safeBag)
+ sec_PKCS12SafeContents *safeContents,
+ sec_PKCS12SafeBag *safeBag)
{
void *mark = NULL, *dummy = NULL;
- if(!arena || !safeBag || !safeContents) {
- return SECFailure;
+ if (!arena || !safeBag || !safeContents) {
+ return SECFailure;
}
mark = PORT_ArenaMark(arena);
- if(!mark) {
- PORT_SetError(SEC_ERROR_NO_MEMORY);
- return SECFailure;
+ 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;
+ 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;
+ 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;
+ 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 */
@@ -660,109 +657,109 @@ sec_pkcs12_append_bag_to_safe_contents(PLArenaPool *arena,
/* appends a safeBag to a specific safeInfo.
*/
SECStatus
-sec_pkcs12_append_bag(SEC_PKCS12ExportContext *p12ctxt,
- SEC_PKCS12SafeInfo *safeInfo, sec_PKCS12SafeBag *safeBag)
+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 (!p12ctxt || !safeBag || !safeInfo) {
+ return SECFailure;
}
- if(!safeInfo->safe) {
- safeInfo->safe = sec_PKCS12CreateSafeContents(p12ctxt->arena);
- if(!safeInfo->safe) {
- 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++;
+ 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_PKCS12CreateSafeBag(SEC_PKCS12ExportContext *p12ctxt, SECOidTag bagType,
+ void *bagData)
{
sec_PKCS12SafeBag *safeBag;
void *mark = NULL;
SECStatus rv = SECSuccess;
SECOidData *oidData = NULL;
- if(!p12ctxt) {
- return NULL;
+ if (!p12ctxt) {
+ return NULL;
}
mark = PORT_ArenaMark(p12ctxt->arena);
- if(!mark) {
- PORT_SetError(SEC_ERROR_NO_MEMORY);
- return NULL;
+ 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;
+ 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;
- break;
- default:
- goto loser;
+ 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;
+ 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;
- }
+ 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;
+ goto loser;
}
-
+
safeBag->arena = p12ctxt->arena;
PORT_ArenaUnmark(p12ctxt->arena, mark);
return safeBag;
loser:
- if(mark) {
- PORT_ArenaRelease(p12ctxt->arena, mark);
+ if (mark) {
+ PORT_ArenaRelease(p12ctxt->arena, mark);
}
return NULL;
@@ -779,31 +776,31 @@ sec_PKCS12NewCertBag(PLArenaPool *arena, SECOidTag certType)
SECStatus rv;
void *mark = NULL;
- if(!arena) {
- return 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;
+ 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;
+ 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;
+ if (rv != SECSuccess) {
+ PORT_SetError(SEC_ERROR_NO_MEMORY);
+ goto loser;
}
-
+
PORT_ArenaUnmark(arena, mark);
return certBag;
@@ -823,31 +820,31 @@ sec_PKCS12NewCRLBag(PLArenaPool *arena, SECOidTag crlType)
SECStatus rv;
void *mark = NULL;
- if(!arena) {
- return 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;
+ 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;
+ 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;
+ if (rv != SECSuccess) {
+ PORT_SetError(SEC_ERROR_NO_MEMORY);
+ goto loser;
}
-
+
PORT_ArenaUnmark(arena, mark);
return crlBag;
@@ -858,112 +855,110 @@ loser:
/* sec_PKCS12AddAttributeToBag
* adds an attribute to a safeBag. currently, the only attributes supported
- * are those which are specified within PKCS 12.
+ * 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
+ * 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_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};
+ SECItem unicodeName = { siBuffer, NULL, 0 };
void *src = NULL;
unsigned int nItems = 0;
SECStatus rv;
- if(!safeBag || !p12ctxt) {
- return SECFailure;
+ 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;
+ 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 (!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;
+ 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;
+ 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;
+ 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[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;
+ 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;
+ 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;
+ safeBag->attribs = (sec_PKCS12Attribute **)PORT_ArenaZAlloc(p12ctxt->arena,
+ 2 * sizeof(sec_PKCS12Attribute *));
+ dummy = safeBag->attribs;
}
- if(!dummy) {
- goto loser;
+ if (!dummy) {
+ goto loser;
}
safeBag->attribs[safeBag->nAttribs] = attribute;
@@ -973,388 +968,385 @@ sec_PKCS12AddAttributeToBag(SEC_PKCS12ExportContext *p12ctxt,
return SECSuccess;
loser:
- if(mark) {
- PORT_ArenaRelease(p12ctxt->arena, mark);
+ if (mark) {
+ PORT_ArenaRelease(p12ctxt->arena, mark);
}
return SECFailure;
}
/* SEC_PKCS12AddCert
- * Adds a certificate to the data being exported.
+ * 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.
+ * 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_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};
+ SECItem nick = { siBuffer, NULL, 0 };
- if(!p12ctxt || !cert) {
- return SECFailure;
+ 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;
+ 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 (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 (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->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;
+ /*
+ * 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 (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;
- }
+
+ 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);
+ 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);
+ rv = sec_pkcs12_append_bag(p12ctxt, safe, safeBag);
}
- if(rv != SECSuccess) {
- goto loser;
+ if (rv != SECSuccess) {
+ goto loser;
}
PORT_ArenaUnmark(p12ctxt->arena, mark);
return SECSuccess;
loser:
- if(mark) {
- PORT_ArenaRelease(p12ctxt->arena, mark);
+ if (mark) {
+ PORT_ArenaRelease(p12ctxt->arena, mark);
}
return SECFailure;
}
/* SEC_PKCS12AddKeyForCert
- * Extracts the key associated with a particular certificate and exports
- * it.
+ * 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
+ * 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)
+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};
+ SECItem nickname = { siBuffer, NULL, 0 }, uniPwitem = { siBuffer, NULL, 0 };
sec_PKCS12SafeBag *returnBag;
- if(!p12ctxt || !cert || !safe) {
- return SECFailure;
+ if (!p12ctxt || !cert || !safe) {
+ return SECFailure;
}
mark = PORT_ArenaMark(p12ctxt->arena);
- /* retrieve the key based upon the type that it is and
+ /* 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);
+ */
+ 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
+ /* 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;
- }
+ */
+ 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);
+ 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);
+ rv = sec_pkcs12_append_bag(p12ctxt, safe, returnBag);
}
loser:
if (rv != SECSuccess) {
- PORT_ArenaRelease(p12ctxt->arena, mark);
+ PORT_ArenaRelease(p12ctxt->arena, mark);
} else {
- PORT_ArenaUnmark(p12ctxt->arena, mark);
+ PORT_ArenaUnmark(p12ctxt->arena, mark);
}
return rv;
}
/* SEC_PKCS12AddCertOrChainAndKey
- * Add a certificate and key pair to be exported.
+ * 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.
+ * 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)
+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;
+ 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;
+ 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;
+ 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;
+ rv = SEC_PKCS12AddKeyForCert(p12ctxt, (SEC_PKCS12SafeInfo *)keySafe,
+ keyNestedDest, cert,
+ shroudKey, algorithm, pwitem,
+ &digest->digest, NULL);
+ if (rv != SECSuccess) {
+ goto loser;
}
SGN_DestroyDigestInfo(digest);
@@ -1365,73 +1357,72 @@ SEC_PKCS12AddCertOrChainAndKey(SEC_PKCS12ExportContext *p12ctxt,
loser:
SGN_DestroyDigestInfo(digest);
PORT_ArenaRelease(p12ctxt->arena, mark);
-
- return SECFailure;
+
+ 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)
+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);
+ cert, certDb, keySafe, keyNestedDest, shroudKey, pwItem,
+ algorithm, PR_TRUE);
}
-
/* SEC_PKCS12CreateNestedSafeContents
- * Allows nesting of safe contents to be implemented. No limit imposed on
- * depth.
+ * 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 (?)
+ * p12ctxt - the export context
+ * baseSafe - the base safeInfo
+ * nestedDest - a parent safeContents (?)
*/
void *
SEC_PKCS12CreateNestedSafeContents(SEC_PKCS12ExportContext *p12ctxt,
- void *baseSafe, void *nestedDest)
+ void *baseSafe, void *nestedDest)
{
sec_PKCS12SafeContents *newSafe;
sec_PKCS12SafeBag *safeContentsBag;
void *mark;
SECStatus rv;
- if(!p12ctxt || !baseSafe) {
- return NULL;
+ 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;
+ 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;
+ 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);
+ 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);
+ rv = sec_pkcs12_append_bag(p12ctxt, (SEC_PKCS12SafeInfo *)baseSafe,
+ safeContentsBag);
}
- if(rv != SECSuccess) {
- goto loser;
+ if (rv != SECSuccess) {
+ goto loser;
}
PORT_ArenaUnmark(p12ctxt->arena, mark);
@@ -1450,34 +1441,34 @@ loser:
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;
- }
+ 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.
+ * 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)
@@ -1485,34 +1476,34 @@ sec_pkcs12_encoder_start_context(SEC_PKCS12ExportContext *p12exp)
sec_PKCS12EncoderContext *p12enc = NULL;
unsigned int i, nonEmptyCnt;
SECStatus rv;
- SECItem ignore = {0};
+ SECItem ignore = { 0 };
void *mark;
SECItem *salt = NULL;
SECItem *params = NULL;
- if(!p12exp || !p12exp->safeInfos) {
- return NULL;
+ 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++;
+ while (p12exp->safeInfos[i]) {
+ if (p12exp->safeInfos[i]->itemCount) {
+ nonEmptyCnt++;
+ }
+ i++;
}
- if(nonEmptyCnt == 0) {
- return NULL;
+ 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;
+ if (!p12enc) {
+ PORT_SetError(SEC_ERROR_NO_MEMORY);
+ return NULL;
}
p12enc->arena = p12exp->arena;
@@ -1520,118 +1511,120 @@ sec_pkcs12_encoder_start_context(SEC_PKCS12ExportContext *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;
+ 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
+ /* 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) {
- /* 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;
- }
- PORT_CheckSuccess(SEC_PKCS7AddSigningTime(p12enc->aSafeCinfo));
+ if (p12exp->integrityEnabled && !p12exp->pwdIntegrity) {
+ /* 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;
+ }
+ PORT_CheckSuccess(SEC_PKCS7AddSigningTime(p12enc->aSafeCinfo));
} else {
- p12enc->aSafeCinfo = SEC_PKCS7CreateData();
-
- /* init password pased integrity mode */
- if(p12exp->integrityEnabled) {
- SECItem pwd = {siBuffer,NULL, 0};
- PK11SymKey *symKey;
- CK_MECHANISM_TYPE integrityMechType;
- CK_MECHANISM_TYPE hmacMechType;
- salt = sec_pkcs12_generate_salt();
-
- /* 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) {
- PORT_SetError(SEC_ERROR_NO_MEMORY);
- goto loser;
- }
- if (!SEC_ASN1EncodeInteger(p12exp->arena, &(p12enc->mac.iter),
- NSS_PBE_DEFAULT_ITERATION_COUNT)) {
- goto loser;
- }
-
- /* generate HMAC key */
- if(!sec_pkcs12_convert_item_to_unicode(NULL, &pwd,
- p12exp->integrityInfo.pwdInfo.password, PR_TRUE,
- PR_TRUE, PR_TRUE)) {
- 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,
+ p12enc->aSafeCinfo = SEC_PKCS7CreateData();
+
+ /* init password pased integrity mode */
+ if (p12exp->integrityEnabled) {
+ SECItem pwd = { siBuffer, NULL, 0 };
+ PK11SymKey *symKey;
+ CK_MECHANISM_TYPE integrityMechType;
+ CK_MECHANISM_TYPE hmacMechType;
+ salt = sec_pkcs12_generate_salt();
+
+ /* 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) {
+ PORT_SetError(SEC_ERROR_NO_MEMORY);
+ goto loser;
+ }
+ if (!SEC_ASN1EncodeInteger(p12exp->arena, &(p12enc->mac.iter),
+ NSS_PBE_DEFAULT_ITERATION_COUNT)) {
+ goto loser;
+ }
+
+ /* generate HMAC key */
+ if (!sec_pkcs12_convert_item_to_unicode(NULL, &pwd,
+ p12exp->integrityInfo.pwdInfo.password, PR_TRUE,
+ PR_TRUE, PR_TRUE)) {
+ 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:
- 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;
+ 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:
+ 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);
@@ -1641,13 +1634,13 @@ sec_pkcs12_encoder_start_context(SEC_PKCS12ExportContext *p12exp)
loser:
sec_pkcs12_encoder_destroy_context(p12enc);
if (p12exp->arena != NULL)
- PORT_ArenaRelease(p12exp->arena, mark);
- if (salt) {
- SECITEM_ZfreeItem(salt, PR_TRUE);
- }
- if (params) {
- PK11_DestroyPBEParams(params);
- }
+ PORT_ArenaRelease(p12exp->arena, mark);
+ if (salt) {
+ SECITEM_ZfreeItem(salt, PR_TRUE);
+ }
+ if (params) {
+ PK11_DestroyPBEParams(params);
+ }
return NULL;
}
@@ -1658,69 +1651,69 @@ loser:
*/
static void
sec_P12A1OutputCB_Outer(void *arg, const char *buf, unsigned long len,
- int depth, SEC_ASN1EncodingPart data_kind)
+ 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);
+ 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.
+/* 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)
+ unsigned long len,
+ int depth,
+ SEC_ASN1EncodingPart data_kind)
{
- sec_pkcs12OutputBuffer * bufcx = (sec_pkcs12OutputBuffer *)arg;
+ sec_pkcs12OutputBuffer *bufcx = (sec_pkcs12OutputBuffer *)arg;
- if(!buf || !len)
- return;
+ if (!buf || !len)
+ return;
if (bufcx->hmacCx) {
- PK11_DigestOp(bufcx->hmacCx, (unsigned char *)buf, len);
+ 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;
- }
+ 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);
+ /* 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;
+ /* copy it all into the buffer, and return */
+ memcpy(bufcx->buf, buf, len);
+ bufcx->numBytes = len;
}
}
void
-sec_FlushPkcs12OutputBuffer( sec_pkcs12OutputBuffer * bufcx)
+sec_FlushPkcs12OutputBuffer(sec_pkcs12OutputBuffer *bufcx)
{
if (bufcx->numBytes > 0) {
- SEC_PKCS7EncoderUpdate(bufcx->p7eCx, bufcx->buf, bufcx->numBytes);
- bufcx->numBytes = 0;
+ SEC_PKCS7EncoderUpdate(bufcx->p7eCx, bufcx->buf, bufcx->numBytes);
+ bufcx->numBytes = 0;
}
}
@@ -1730,100 +1723,97 @@ sec_FlushPkcs12OutputBuffer( sec_pkcs12OutputBuffer * bufcx)
static void
sec_P12P7OutputCB_CallA1Update(void *arg, const char *buf, unsigned long len)
{
- SEC_ASN1EncoderContext *cx = (SEC_ASN1EncoderContext*)arg;
+ SEC_ASN1EncoderContext *cx = (SEC_ASN1EncoderContext *)arg;
- if (!buf || !len)
- return;
+ 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
+ * sequence of content infos labeled AuthenticatedSafes
*/
-static SECStatus
+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);
+ 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 (innerP7ecx) {
+ SEC_PKCS7EncoderFinish(innerP7ecx, p12ecx->p12exp->pwfn,
+ p12ecx->p12exp->pwfnarg);
}
- if(innerA1ecx) {
- SEC_ASN1EncoderFinish(innerA1ecx);
+ if (innerA1ecx) {
+ SEC_ASN1EncoderFinish(innerA1ecx);
}
memset(&p12ecx->innerBuf, 0, sizeof p12ecx->innerBuf);
return SECFailure;
@@ -1840,62 +1830,62 @@ sec_Pkcs12FinishMac(sec_PKCS12EncoderContext *p12ecx)
SGNDigestInfo *di = NULL;
void *dummy;
- if(!p12ecx) {
- return SECFailure;
+ if (!p12ecx) {
+ return SECFailure;
}
/* make sure we are using password integrity mode */
- if(!p12ecx->p12exp->integrityEnabled) {
- return SECSuccess;
+ if (!p12ecx->p12exp->integrityEnabled) {
+ return SECSuccess;
}
- if(!p12ecx->p12exp->pwdIntegrity) {
- 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;
+ 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;
+ 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;
+ 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;
+ 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;
+ 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 (di) {
+ SGN_DestroyDigestInfo(di);
}
- if(hmac.data) {
- SECITEM_ZfreeItem(&hmac, PR_FALSE);
+ if (hmac.data) {
+ SECITEM_ZfreeItem(&hmac, PR_FALSE);
}
PK11_DestroyContext(p12ecx->hmacCx, PR_TRUE);
p12ecx->hmacCx = NULL;
@@ -1903,24 +1893,24 @@ loser:
return rv;
}
-/* pfx notify function for ASN1 encoder.
- * We want to stop encoding once we reach the authenticated safe.
+/* 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.
+ * 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;
+ if (!before) {
+ return;
}
/* look for authenticated safe */
- p12ecx = (sec_PKCS12EncoderContext*)arg;
- if(dest != &p12ecx->pfx.encodedAuthSafe) {
- return;
+ p12ecx = (sec_PKCS12EncoderContext *)arg;
+ if (dest != &p12ecx->pfx.encodedAuthSafe) {
+ return;
}
SEC_ASN1EncoderSetTakeFromBuf(p12ecx->outerA1ecx);
@@ -1929,89 +1919,89 @@ sec_pkcs12_encoder_pfx_notify(void *arg, PRBool before, void *dest, int real_dep
}
/* 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.
+ * 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_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;
+ if (!p12exp || !output) {
+ return SECFailure;
}
/* get the encoder context */
p12enc = sec_pkcs12_encoder_start_context(p12exp);
- if(!p12enc) {
- return SECFailure;
+ 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;
+ 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_ASN1EncoderSetNotifyProc(p12enc->outerA1ecx,
sec_pkcs12_encoder_pfx_notify, p12enc);
rv = SEC_ASN1EncoderUpdate(p12enc->outerA1ecx, NULL, 0);
- if(rv != SECSuccess) {
- rv = SECFailure;
- goto loser;
+ 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;
+ 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.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;
+ 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_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_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);
@@ -2019,14 +2009,14 @@ SEC_PKCS12Encode(SEC_PKCS12ExportContext *p12exp,
SEC_ASN1EncoderFinish(p12enc->middleA1ecx);
p12enc->middleA1ecx = NULL;
- sec_FlushPkcs12OutputBuffer( &p12enc->middleBuf);
+ sec_FlushPkcs12OutputBuffer(&p12enc->middleBuf);
/* finish the encoding of the authenticated safes */
- rv = SEC_PKCS7EncoderFinish(p12enc->middleP7ecx, p12exp->pwfn,
- p12exp->pwfnarg);
+ rv = SEC_PKCS7EncoderFinish(p12enc->middleP7ecx, p12exp->pwfn,
+ p12exp->pwfnarg);
p12enc->middleP7ecx = NULL;
- if(rv != SECSuccess) {
- goto loser;
+ if (rv != SECSuccess) {
+ goto loser;
}
SEC_ASN1EncoderClearTakeFromBuf(p12enc->outerA1ecx);
@@ -2034,11 +2024,11 @@ SEC_PKCS12Encode(SEC_PKCS12ExportContext *p12exp,
/* update the mac, if necessary */
rv = sec_Pkcs12FinishMac(p12enc);
- if(rv != SECSuccess) {
- goto loser;
+ if (rv != SECSuccess) {
+ goto loser;
}
-
- /* finish encoding the pfx */
+
+ /* finish encoding the pfx */
rv = SEC_ASN1EncoderUpdate(p12enc->outerA1ecx, NULL, 0);
SEC_ASN1EncoderFinish(p12enc->outerA1ecx);
@@ -2054,21 +2044,21 @@ 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++;
- }
+ 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);
diff --git a/nss/lib/pkcs12/p12exp.c b/nss/lib/pkcs12/p12exp.c
index 852ea37..b9cb076 100644
--- a/nss/lib/pkcs12/p12exp.c
+++ b/nss/lib/pkcs12/p12exp.c
@@ -21,31 +21,31 @@ sec_pkcs12_destroy_nickname_list(SECItem **nicknames)
{
int i = 0;
- if(nicknames == NULL) {
- return;
+ if (nicknames == NULL) {
+ return;
}
- while(nicknames[i] != NULL) {
- SECITEM_FreeItem(nicknames[i], PR_FALSE);
- i++;
+ while (nicknames[i] != NULL) {
+ SECITEM_FreeItem(nicknames[i], PR_FALSE);
+ i++;
}
PORT_Free(nicknames);
}
-
-/* release the memory taken up by the list of certificates */
+
+/* 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;
+ if (ref_certs == NULL) {
+ return;
}
- while(ref_certs[i] != NULL) {
- CERT_DestroyCertificate(ref_certs[i]);
- i++;
+ while (ref_certs[i] != NULL) {
+ CERT_DestroyCertificate(ref_certs[i]);
+ i++;
}
}
@@ -54,14 +54,14 @@ 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++;
+ 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++;
}
}
@@ -70,41 +70,41 @@ sec_pkcs12_destroy_cinfos_for_cert_bags(SEC_PKCS12CertAndCRLBag *certBag)
*/
static void
sec_pkcs12_destroy_cert_content_infos(SEC_PKCS12SafeContents *safe,
- SEC_PKCS12Baggage *baggage)
+ 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++;
- }
+ 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++;
+ }
}
}
@@ -118,42 +118,42 @@ sec_pkcs12_convert_nickname_list(char **nicknames)
int i, j;
PRBool error = PR_FALSE;
- if(nicknames == NULL) {
- return NULL;
+ if (nicknames == NULL) {
+ return NULL;
}
i = j = 0;
- while(nicknames[i] != NULL) {
- i++;
+ while (nicknames[i] != NULL) {
+ i++;
}
- /* allocate the space and copy the data */
+ /* 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;
+ 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;
@@ -164,13 +164,13 @@ sec_pkcs12_convert_nickname_list(char **nicknames)
* the packaged contents.
* poolp -- common memory pool;
* add_cert -- certificate to package up
- * nickname for the certificate
+ * nickname for the certificate
* a return of NULL indicates an error
*/
static SEC_PKCS12CertAndCRL *
sec_pkcs12_get_cert(PLArenaPool *poolp,
- CERTCertificate *add_cert,
- SECItem *nickname)
+ CERTCertificate *add_cert,
+ SECItem *nickname)
{
SEC_PKCS12CertAndCRL *cert;
SEC_PKCS7ContentInfo *cinfo;
@@ -178,140 +178,137 @@ sec_pkcs12_get_cert(PLArenaPool *poolp,
void *mark;
SECStatus rv;
- if((poolp == NULL) || (add_cert == NULL) || (nickname == NULL)) {
- return NULL;
+ 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) {
+
+ /* 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);
+ PORT_ArenaRelease(poolp, mark);
} else {
- PORT_ArenaUnmark(poolp, mark);
+ PORT_ArenaUnmark(poolp, mark);
}
return cert;
}
-/* package the private key associated with the certificate and
- * return the appropriate PKCS 12 structure
+/* 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
+ * wincx -- window handle
* an error is indicated by a return of NULL
*/
static SEC_PKCS12PrivateKey *
sec_pkcs12_get_private_key(PLArenaPool *poolp,
- SECItem *nickname,
- CERTCertificate *cert,
- void *wincx)
+ SECItem *nickname,
+ CERTCertificate *cert,
+ void *wincx)
{
SECKEYPrivateKeyInfo *pki;
SEC_PKCS12PrivateKey *pk;
SECStatus rv;
void *mark;
- if((poolp == NULL) || (nickname == NULL)) {
- return NULL;
+ 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;
+ 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;
- }
+ 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);
+ PORT_SetError(SEC_ERROR_NO_MEMORY);
}
/* destroy private key, zeroing out data */
SECKEY_DestroyPrivateKeyInfo(pki, PR_TRUE);
if (pk == NULL) {
- PORT_ArenaRelease(poolp, mark);
+ PORT_ArenaRelease(poolp, mark);
} else {
- PORT_ArenaUnmark(poolp, mark);
+ PORT_ArenaUnmark(poolp, mark);
}
return pk;
}
/* get a shrouded key item associated with a certificate
- * return the appropriate PKCS 12 structure
+ * return the appropriate PKCS 12 structure
* poolp common memory pool
* nickname key nickname
* cert -- cert to look up
- * wincx -- window handle
+ * wincx -- window handle
* an error is indicated by a return of NULL
*/
static SEC_PKCS12ESPVKItem *
sec_pkcs12_get_shrouded_key(PLArenaPool *poolp,
- SECItem *nickname,
- CERTCertificate *cert,
- SECOidTag algorithm,
- SECItem *pwitem,
- PKCS12UnicodeConvertFunction unicodeFn,
- void *wincx)
+ SECItem *nickname,
+ CERTCertificate *cert,
+ SECOidTag algorithm,
+ SECItem *pwitem,
+ PKCS12UnicodeConvertFunction unicodeFn,
+ void *wincx)
{
SECKEYEncryptedPrivateKeyInfo *epki;
SEC_PKCS12ESPVKItem *pk;
@@ -324,8 +321,8 @@ sec_pkcs12_get_shrouded_key(PLArenaPool *poolp,
swapUnicodeBytes = PR_TRUE;
#endif
- if((poolp == NULL) || (nickname == NULL))
- return NULL;
+ if ((poolp == NULL) || (nickname == NULL))
+ return NULL;
mark = PORT_ArenaMark(poolp);
@@ -333,64 +330,64 @@ sec_pkcs12_get_shrouded_key(PLArenaPool *poolp,
slot = PK11_GetInternalKeySlot();
/* retrieve encrypted prviate key */
- epki = PK11_ExportEncryptedPrivateKeyInfo(slot, algorithm, pwitem,
- nickname, cert, 1, 0, NULL);
+ 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;
+ 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;
- }
+ 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);
+ if (pk == NULL) {
+ PORT_ArenaRelease(poolp, mark);
} else {
- PORT_ArenaUnmark(poolp, mark);
+ PORT_ArenaUnmark(poolp, mark);
}
-
+
return pk;
}
-/* add a thumbprint to a private key associated certs list
+/* 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
+ * a return of SECFailure indicates an error
*/
-static SECStatus
+static SECStatus
sec_pkcs12_add_thumbprint(SEC_PKCS12PVKSupportingData *pvk,
- SGNDigestInfo *thumb)
+ SGNDigestInfo *thumb)
{
SGNDigestInfo **thumb_list = NULL;
int nthumbs, size;
void *mark, *dummy;
SECStatus rv = SECFailure;
- if((pvk == NULL) || (thumb == NULL)) {
- return SECFailure;
+ if ((pvk == NULL) || (thumb == NULL)) {
+ return SECFailure;
}
mark = PORT_ArenaMark(pvk->poolp);
@@ -398,29 +395,29 @@ sec_pkcs12_add_thumbprint(SEC_PKCS12PVKSupportingData *pvk,
thumb_list = pvk->assocCerts;
nthumbs = pvk->nThumbs;
- /* allocate list space needed -- either growing or allocating
- * list must be NULL terminated
+ /* 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)));
+ (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;
- }
+ 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;
@@ -434,8 +431,8 @@ sec_pkcs12_add_thumbprint(SEC_PKCS12PVKSupportingData *pvk,
* that no match was present or that an error occurred.
*/
static SEC_PKCS12ESPVKItem *
-sec_pkcs12_get_espvk_by_name(SEC_PKCS12Baggage *luggage,
- SECItem *name)
+sec_pkcs12_get_espvk_by_name(SEC_PKCS12Baggage *luggage,
+ SECItem *name)
{
PRBool found = PR_FALSE;
SEC_PKCS12ESPVKItem *espvk = NULL;
@@ -444,38 +441,38 @@ sec_pkcs12_get_espvk_by_name(SEC_PKCS12Baggage *luggage,
SECItem *t_name;
SEC_PKCS12BaggageItem *bag;
- if((luggage == NULL) || (name == NULL)) {
- return NULL;
+ 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;
+ 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;
@@ -484,11 +481,11 @@ sec_pkcs12_get_espvk_by_name(SEC_PKCS12Baggage *luggage,
/* locates a certificate and copies the thumbprint to the
* appropriate private key
*/
-static SECStatus
+static SECStatus
sec_pkcs12_propagate_thumbprints(SECItem **nicknames,
- CERTCertificate **ref_certs,
- SEC_PKCS12SafeContents *safe,
- SEC_PKCS12Baggage *baggage)
+ CERTCertificate **ref_certs,
+ SEC_PKCS12SafeContents *safe,
+ SEC_PKCS12Baggage *baggage)
{
SEC_PKCS12CertAndCRL *cert;
SEC_PKCS12PrivateKey *key;
@@ -497,81 +494,81 @@ sec_pkcs12_propagate_thumbprints(SECItem **nicknames,
PRBool error = PR_FALSE;
SECStatus rv = SECFailure;
- if((nicknames == NULL) || (safe == NULL)) {
- return 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;
+ 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
+SECStatus
sec_pkcs12_append_safe_bag(SEC_PKCS12SafeContents *safe,
- SEC_PKCS12SafeBag *bag)
+ SEC_PKCS12SafeBag *bag)
{
int size;
void *mark = NULL, *dummy = NULL;
- if((bag == NULL) || (safe == NULL))
- return SECFailure;
+ 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;
+
+ 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;
+ 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;
+ if (dummy == NULL) {
+ PORT_SetError(SEC_ERROR_NO_MEMORY);
+ goto loser;
}
safe->contents[safe->safe_size] = bag;
@@ -587,49 +584,51 @@ loser:
}
/* append a certificate onto the end of a cert bag */
-static SECStatus
+static SECStatus
sec_pkcs12_append_cert_to_bag(PLArenaPool *arena,
- SEC_PKCS12SafeBag *safebag,
- CERTCertificate *cert,
- SECItem *nickname)
+ 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;
+ if ((arena == NULL) || (safebag == NULL) ||
+ (cert == NULL) || (nickname == NULL)) {
+ return SECFailure;
}
bag = safebag->safeContent.certAndCRLBag;
- if(bag == NULL) {
- return SECFailure;
+ 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;
+ 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;
+ 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;
+ 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;
+ if (dummy == NULL) {
+ PORT_SetError(SEC_ERROR_NO_MEMORY);
+ goto loser;
}
bag->certAndCRLs[bag->bag_size] = p12cert;
@@ -645,41 +644,41 @@ loser:
}
/* append a key onto the end of a list of keys in a key bag */
-SECStatus
+SECStatus
sec_pkcs12_append_key_to_bag(SEC_PKCS12SafeBag *safebag,
- SEC_PKCS12PrivateKey *pk)
+ SEC_PKCS12PrivateKey *pk)
{
void *mark, *dummy;
SEC_PKCS12PrivateKeyBag *bag;
int size;
- if((safebag == NULL) || (pk == NULL))
- return SECFailure;
+ if ((safebag == NULL) || (pk == NULL))
+ return SECFailure;
bag = safebag->safeContent.keyBag;
- if(bag == NULL) {
- return SECFailure;
+ 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;
+ 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;
+ 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;
+ if (dummy == NULL) {
+ PORT_SetError(SEC_ERROR_NO_MEMORY);
+ goto loser;
}
bag->privateKeys[bag->bag_size] = pk;
@@ -696,27 +695,27 @@ loser:
}
/* append a safe bag to the baggage area */
-static SECStatus
+static SECStatus
sec_pkcs12_append_unshrouded_bag(SEC_PKCS12BaggageItem *bag,
- SEC_PKCS12SafeBag *u_bag)
+ SEC_PKCS12SafeBag *u_bag)
{
int size;
void *mark = NULL, *dummy = NULL;
- if((bag == NULL) || (u_bag == NULL))
- return SECFailure;
+ 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, size,
+ size + sizeof(SEC_PKCS12SafeBag *));
bag->unencSecrets = dummy;
- if(dummy == NULL) {
- PORT_SetError(SEC_ERROR_NO_MEMORY);
- goto loser;
+ if (dummy == NULL) {
+ PORT_SetError(SEC_ERROR_NO_MEMORY);
+ goto loser;
}
bag->unencSecrets[bag->nSecrets] = u_bag;
@@ -744,15 +743,15 @@ loser:
*/
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)
+ CERTCertificate **ref_certs,
+ PRBool unencryptedCerts,
+ SEC_PKCS12SafeContents **rSafe,
+ SEC_PKCS12Baggage **rBaggage,
+ PRBool shroud_keys,
+ SECOidTag shroud_alg,
+ SECItem *pwitem,
+ PKCS12UnicodeConvertFunction unicodeFn,
+ void *wincx)
{
PLArenaPool *permArena;
SEC_PKCS12SafeContents *safe = NULL;
@@ -769,145 +768,145 @@ sec_pkcs12_package_certs_and_keys(SECItem **nicknames,
int ncerts = 0, nkeys = 0;
int i;
- if((nicknames == NULL) || (rSafe == NULL) || (rBaggage == NULL)) {
- return SECFailure;
+ 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;
- }
+ 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;
+ 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;
+ 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) {
+ 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);
+ 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 */
+ 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);
- }
+ 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;
+ 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;
+ 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;
+ baggage = NULL;
}
- if((problem == PR_TRUE) || (rv == SECFailure)) {
- PORT_FreeArena(permArena, PR_TRUE);
- rv = SECFailure;
- baggage = NULL;
- safe = NULL;
+ if ((problem == PR_TRUE) || (rv == SECFailure)) {
+ PORT_FreeArena(permArena, PR_TRUE);
+ rv = SECFailure;
+ baggage = NULL;
+ safe = NULL;
}
*rBaggage = baggage;
@@ -926,33 +925,33 @@ sec_pkcs12_encode_safe_contents(SEC_PKCS12SafeContents *safe)
void *dummy = NULL;
PLArenaPool *arena;
- if(safe == NULL) {
- return NULL;
+ if (safe == NULL) {
+ return NULL;
}
-/* rv = sec_pkcs12_prepare_for_der_code_safe(safe, PR_TRUE);
+ /* rv = sec_pkcs12_prepare_for_der_code_safe(safe, PR_TRUE);
if(rv != SECSuccess) {
- PORT_SetError(SEC_ERROR_NO_MEMORY);
- return NULL;
+ 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;
+ 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);
- }
+ 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_SetError(SEC_ERROR_NO_MEMORY);
}
PORT_FreeArena(arena, PR_TRUE);
@@ -960,13 +959,13 @@ sec_pkcs12_encode_safe_contents(SEC_PKCS12SafeContents *safe)
return dsafe;
}
-/* prepare the authenicated safe for encoding and encode it.
+/* 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
+ * data content info
* safe -- container of certs and keys, is encrypted.
- * baggage -- container of certs and keys, keys assumed to be encrypted by
+ * 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
@@ -975,12 +974,12 @@ sec_pkcs12_encode_safe_contents(SEC_PKCS12SafeContents *safe)
* 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)
+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;
PLArenaPool *poolp;
@@ -994,156 +993,154 @@ sec_pkcs12_get_auth_safe(SEC_PKCS12SafeContents *safe,
#ifdef IS_LITTLE_ENDIAN
swapUnicodeBytes = PR_TRUE;
#endif
-
- if(((safe != NULL) && (pwitem == NULL)) && (baggage == NULL))
- return NULL;
+
+ 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;
+ 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;
- }
- }
+ 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 (safe_cinfo != NULL) {
+ SEC_PKCS7DestroyContentInfo(safe_cinfo);
}
- if(psalt != NULL) {
- SECITEM_ZfreeItem(psalt, PR_TRUE);
+ if (psalt != NULL) {
+ SECITEM_ZfreeItem(psalt, PR_TRUE);
}
- if(rv == SECFailure) {
- return NULL;
+ if (rv == SECFailure) {
+ return NULL;
}
-
+
return asafe_cinfo;
}
-/* generates the PFX and computes the mac on the authenticated safe
+/* 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)
+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;
@@ -1156,73 +1153,73 @@ sec_pkcs12_get_pfx(SEC_PKCS7ContentInfo *cinfo,
swapUnicodeBytes = PR_TRUE;
#endif
- if((cinfo == NULL) || ((do_mac == PR_TRUE) && (pwitem == NULL))) {
- return NULL;
+ 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;
+ 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;
+ 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;
@@ -1235,21 +1232,21 @@ sec_pkcs12_encode_pfx(SEC_PKCS12PFXItem *pfx)
SECItem *dest;
void *dummy;
- if(pfx == NULL) {
- return NULL;
+ if (pfx == NULL) {
+ return NULL;
}
dest = (SECItem *)PORT_ZAlloc(sizeof(SECItem));
- if(dest == NULL) {
- PORT_SetError(SEC_ERROR_NO_MEMORY);
- return NULL;
+ 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;
+ if (dummy == NULL) {
+ PORT_SetError(SEC_ERROR_NO_MEMORY);
+ SECITEM_ZfreeItem(dest, PR_TRUE);
+ dest = NULL;
}
return dest;
@@ -1257,12 +1254,12 @@ sec_pkcs12_encode_pfx(SEC_PKCS12PFXItem *pfx)
SECItem *
SEC_PKCS12GetPFX(char **nicknames,
- CERTCertificate **ref_certs,
- PRBool shroud_keys,
- SEC_PKCS5GetPBEPassword pbef,
- void *pbearg,
- PKCS12UnicodeConvertFunction unicodeFn,
- void *wincx)
+ CERTCertificate **ref_certs,
+ PRBool shroud_keys,
+ SEC_PKCS5GetPBEPassword pbef,
+ void *pbearg,
+ PKCS12UnicodeConvertFunction unicodeFn,
+ void *wincx)
{
SECItem **nicks = NULL;
SEC_PKCS12PFXItem *pfx = NULL;
@@ -1277,101 +1274,100 @@ SEC_PKCS12GetPFX(char **nicknames,
/* 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;
- }
+ 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;
+ /* 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 (PK11_IsFIPS() && !unencryptedCerts) {
+ unencryptedCerts = PR_TRUE;
}
- if((nicknames == NULL) || (pbef == NULL) || (ref_certs == NULL)) {
- problem = PR_TRUE;
- goto loser;
+ 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;
+ 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);
- }
+ &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);
- }
+ if (safe != NULL) {
+ PORT_FreeArena(safe->poolp, PR_TRUE);
+ }
}
loser:
- if(nicks != NULL) {
- sec_pkcs12_destroy_nickname_list(nicks);
+ if (nicks != NULL) {
+ sec_pkcs12_destroy_nickname_list(nicks);
}
- if(ref_certs != NULL) {
- sec_pkcs12_destroy_certificate_list(ref_certs);
+ if (ref_certs != NULL) {
+ sec_pkcs12_destroy_certificate_list(ref_certs);
}
- if(pwitem != NULL) {
- SECITEM_ZfreeItem(pwitem, PR_TRUE);
+ if (pwitem != NULL) {
+ SECITEM_ZfreeItem(pwitem, PR_TRUE);
}
- if(problem == PR_TRUE) {
- dest = NULL;
+ if (problem == PR_TRUE) {
+ dest = NULL;
}
return dest;
diff --git a/nss/lib/pkcs12/p12local.c b/nss/lib/pkcs12/p12local.c
index b8aba64..d7f0d9e 100644
--- a/nss/lib/pkcs12/p12local.c
+++ b/nss/lib/pkcs12/p12local.c
@@ -15,7 +15,7 @@
#include "p12local.h"
#include "p12.h"
-#define SALT_LENGTH 16
+#define SALT_LENGTH 16
SEC_ASN1_MKSUB(SECKEY_PrivateKeyInfoTemplate)
SEC_ASN1_MKSUB(sgn_DigestInfoTemplate)
@@ -24,22 +24,22 @@ 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;
+ 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;
}
@@ -54,30 +54,30 @@ sec_pkcs12_choose_bag_type_old(void *src_or_dest, PRBool encoding)
SECOidData *oiddata;
if (src_or_dest == NULL) {
- return NULL;
+ return NULL;
}
- safebag = (SEC_PKCS12SafeBag*)src_or_dest;
+ safebag = (SEC_PKCS12SafeBag *)src_or_dest;
oiddata = safebag->safeBagTypeTag;
if (oiddata == NULL) {
- oiddata = SECOID_FindOID(&safebag->safeBagType);
- safebag->safeBagTypeTag = oiddata;
+ 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;
+ 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;
+ theTemplate = SEC_PointerToPKCS12SecretBagTemplate;
+ break;
}
return theTemplate;
}
@@ -90,30 +90,30 @@ sec_pkcs12_choose_bag_type(void *src_or_dest, PRBool encoding)
SECOidData *oiddata;
if (src_or_dest == NULL) {
- return NULL;
+ return NULL;
}
- safebag = (SEC_PKCS12SafeBag*)src_or_dest;
+ safebag = (SEC_PKCS12SafeBag *)src_or_dest;
oiddata = safebag->safeBagTypeTag;
if (oiddata == NULL) {
- oiddata = SECOID_FindOID(&safebag->safeBagType);
- safebag->safeBagTypeTag = oiddata;
+ 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;
+ 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;
+ theTemplate = SEC_PKCS12SecretBagTemplate;
+ break;
}
return theTemplate;
}
@@ -127,26 +127,26 @@ sec_pkcs12_choose_cert_crl_type_old(void *src_or_dest, PRBool encoding)
SECOidData *oiddata;
if (src_or_dest == NULL) {
- return NULL;
+ return NULL;
}
- certbag = (SEC_PKCS12CertAndCRL*)src_or_dest;
+ certbag = (SEC_PKCS12CertAndCRL *)src_or_dest;
oiddata = certbag->BagTypeTag;
if (oiddata == NULL) {
- oiddata = SECOID_FindOID(&certbag->BagID);
- certbag->BagTypeTag = oiddata;
+ 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;
+ 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;
}
@@ -159,26 +159,26 @@ sec_pkcs12_choose_cert_crl_type(void *src_or_dest, PRBool encoding)
SECOidData *oiddata;
if (src_or_dest == NULL) {
- return NULL;
+ return NULL;
}
- certbag = (SEC_PKCS12CertAndCRL*)src_or_dest;
+ certbag = (SEC_PKCS12CertAndCRL *)src_or_dest;
oiddata = certbag->BagTypeTag;
if (oiddata == NULL) {
- oiddata = SECOID_FindOID(&certbag->BagID);
- certbag->BagTypeTag = oiddata;
+ 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;
+ 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;
}
@@ -192,24 +192,24 @@ sec_pkcs12_choose_shroud_type(void *src_or_dest, PRBool encoding)
SECOidData *oiddata;
if (src_or_dest == NULL) {
- return NULL;
+ return NULL;
}
- espvk = (SEC_PKCS12ESPVKItem*)src_or_dest;
+ espvk = (SEC_PKCS12ESPVKItem *)src_or_dest;
oiddata = espvk->espvkTag;
if (oiddata == NULL) {
- oiddata = SECOID_FindOID(&espvk->espvkOID);
- espvk->espvkTag = oiddata;
+ 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;
+ default:
+ theTemplate = SEC_ASN1_GET(SEC_PointerToAnyTemplate);
+ break;
+ case SEC_OID_PKCS12_PKCS8_KEY_SHROUDING:
+ theTemplate =
+ SEC_ASN1_GET(SECKEY_PointerToEncryptedPrivateKeyInfoTemplate);
+ break;
}
return theTemplate;
}
@@ -224,17 +224,17 @@ sec_pkcs12_generate_salt(void)
SECItem *salt;
salt = (SECItem *)PORT_ZAlloc(sizeof(SECItem));
- if(salt == NULL) {
- PORT_SetError(SEC_ERROR_NO_MEMORY);
- return NULL;
+ if (salt == NULL) {
+ PORT_SetError(SEC_ERROR_NO_MEMORY);
+ return NULL;
}
- salt->data = (unsigned char *)PORT_ZAlloc(sizeof(unsigned char) *
- SALT_LENGTH);
+ 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;
+ if (salt->data == NULL) {
+ PORT_SetError(SEC_ERROR_NO_MEMORY);
+ SECITEM_ZfreeItem(salt, PR_TRUE);
+ return NULL;
}
PK11_GenerateRandom(salt->data, salt->len);
@@ -242,79 +242,78 @@ sec_pkcs12_generate_salt(void)
return salt;
}
-/* generate KEYS -- as per PKCS12 section 7.
+/* generate KEYS -- as per PKCS12 section 7.
* only used for MAC
*/
SECItem *
-sec_pkcs12_generate_key_from_password(SECOidTag algorithm,
- SECItem *salt,
- SECItem *password)
+sec_pkcs12_generate_key_from_password(SECOidTag algorithm,
+ SECItem *salt,
+ SECItem *password)
{
- unsigned char *pre_hash=NULL;
- unsigned char *hash_dest=NULL;
+ unsigned char *pre_hash = NULL;
+ unsigned char *hash_dest = NULL;
SECStatus res;
PLArenaPool *poolp;
SECItem *key = NULL;
int key_len = 0;
- if((salt == NULL) || (password == NULL)) {
- return NULL;
+ if ((salt == NULL) || (password == NULL)) {
+ return NULL;
}
poolp = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
- if(poolp == NULL) {
- PORT_SetError(SEC_ERROR_NO_MEMORY);
- return NULL;
+ 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;
+ 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;
+ 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);
+ 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;
+ 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;
+ 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);
@@ -322,8 +321,8 @@ sec_pkcs12_generate_key_from_password(SECOidTag algorithm,
loser:
PORT_FreeArena(poolp, PR_TRUE);
- if(key != NULL) {
- SECITEM_ZfreeItem(key, PR_TRUE);
+ if (key != NULL) {
+ SECITEM_ZfreeItem(key, PR_TRUE);
}
return NULL;
}
@@ -335,74 +334,73 @@ loser:
* imbedded NULLs
*/
static SECItem *
-sec_pkcs12_generate_old_mac(SECItem *key,
- SECItem *msg)
+sec_pkcs12_generate_old_mac(SECItem *key,
+ SECItem *msg)
{
SECStatus res;
PLArenaPool *temparena = NULL;
- unsigned char *hash_dest=NULL, *hash_src1=NULL, *hash_src2 = NULL;
+ unsigned char *hash_dest = NULL, *hash_src1 = NULL, *hash_src2 = NULL;
int i;
SECItem *mac = NULL;
- if((key == NULL) || (msg == 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);
+ 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;
+ if (mac->data == NULL)
+ goto loser;
/* allocate temporary items */
temparena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
- if(temparena == NULL)
- goto loser;
+ if (temparena == NULL)
+ goto loser;
hash_src1 = (unsigned char *)PORT_ArenaZAlloc(temparena,
- sizeof(unsigned char) * (16+msg->len));
- if(hash_src1 == NULL)
+ 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)
+ 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)
+ 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;
+ 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;
+ 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;
+ 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;
+ 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);
+ if (temparena != NULL)
+ PORT_FreeArena(temparena, PR_TRUE);
+ if (mac != NULL)
+ SECITEM_ZfreeItem(mac, PR_TRUE);
return NULL;
}
@@ -413,48 +411,48 @@ loser:
* imbedded NULLs
*/
SECItem *
-sec_pkcs12_generate_mac(SECItem *key,
- SECItem *msg,
- PRBool old_method)
+sec_pkcs12_generate_mac(SECItem *key,
+ SECItem *msg,
+ PRBool old_method)
{
SECStatus res = SECFailure;
SECItem *mac = NULL;
- PK11Context *pk11cx = NULL;
- SECItem ignore = {0};
+ PK11Context *pk11cx = NULL;
+ SECItem ignore = { 0 };
- if((key == NULL) || (msg == NULL)) {
- return NULL;
+ if ((key == NULL) || (msg == NULL)) {
+ return NULL;
}
- if(old_method == PR_TRUE) {
- return sec_pkcs12_generate_old_mac(key, msg);
+ 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;
+ return NULL;
}
pk11cx = PK11_CreateContextByRawKey(NULL, CKM_SHA_1_HMAC, PK11_OriginDerive,
CKA_SIGN, key, &ignore, NULL);
if (pk11cx == NULL) {
- goto loser;
+ goto loser;
}
res = PK11_DigestBegin(pk11cx);
if (res == SECFailure) {
- goto loser;
+ goto loser;
}
res = PK11_DigestOp(pk11cx, msg->data, msg->len);
if (res == SECFailure) {
- goto loser;
+ goto loser;
}
res = PK11_DigestFinal(pk11cx, mac->data, &mac->len, SHA1_LENGTH);
if (res == SECFailure) {
- goto loser;
+ goto loser;
}
PK11_DestroyContext(pk11cx, PR_TRUE);
@@ -462,12 +460,12 @@ sec_pkcs12_generate_mac(SECItem *key,
loser:
- if(res != SECSuccess) {
- SECITEM_ZfreeItem(mac, PR_TRUE);
- mac = NULL;
- if (pk11cx) {
- PK11_DestroyContext(pk11cx, PR_TRUE);
- }
+ if (res != SECSuccess) {
+ SECITEM_ZfreeItem(mac, PR_TRUE);
+ mac = NULL;
+ if (pk11cx) {
+ PK11_DestroyContext(pk11cx, PR_TRUE);
+ }
}
return mac;
@@ -485,31 +483,31 @@ sec_pkcs12_compute_thumbprint(SECItem *der_cert)
PLArenaPool *temparena = NULL;
SECStatus rv = SECFailure;
- if(der_cert == NULL)
- return NULL;
+ if (der_cert == NULL)
+ return NULL;
temparena = PORT_NewArena(SEC_ASN1_DEFAULT_ARENA_SIZE);
- if(temparena == NULL) {
- return NULL;
+ if (temparena == NULL) {
+ return NULL;
}
digest.data = (unsigned char *)PORT_ArenaZAlloc(temparena,
- sizeof(unsigned char) *
- SHA1_LENGTH);
+ 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);
- }
+ 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_SetError(SEC_ERROR_NO_MEMORY);
}
PORT_FreeArena(temparena, PR_TRUE);
@@ -522,41 +520,41 @@ sec_pkcs12_compute_thumbprint(SECItem *der_cert)
* is returned */
SECItem *
sec_pkcs12_create_virtual_password(SECItem *password, SECItem *salt,
- PRBool swap)
+ PRBool swap)
{
- SECItem uniPwd = {siBuffer, NULL,0}, *retPwd = NULL;
+ SECItem uniPwd = { siBuffer, NULL, 0 }, *retPwd = NULL;
- if((password == NULL) || (salt == NULL)) {
- return 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;
- }
+ 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;
- }
+ 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;
+ 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;
+ if (retPwd->data == NULL) {
+ PORT_Free(retPwd);
+ goto loser;
}
PORT_Memcpy(retPwd->data, salt->data, salt->len);
@@ -576,27 +574,27 @@ loser:
* to store externally wrapped keys. it is used when importing to convert
* old items to new
*/
-SECStatus
+SECStatus
sec_pkcs12_append_shrouded_key(SEC_PKCS12BaggageItem *bag,
- SEC_PKCS12ESPVKItem *espvk)
+ SEC_PKCS12ESPVKItem *espvk)
{
int size;
void *mark = NULL, *dummy = NULL;
- if((bag == NULL) || (espvk == NULL))
- return SECFailure;
+ 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, 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;
@@ -617,75 +615,75 @@ loser:
*/
static SEC_PKCS12CertAndCRL *
sec_pkcs12_find_cert_in_certbag(SEC_PKCS12CertAndCRLBag *certbag,
- SECItem *nickname, SGNDigestInfo *thumbprint)
+ 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 ((certbag == NULL) || ((nickname == NULL) && (thumbprint == NULL))) {
+ return NULL;
}
- if(thumbprint && nickname) {
- search_both = PR_TRUE;
+ if (thumbprint && nickname) {
+ search_both = PR_TRUE;
}
- if(nickname) {
- search_nickname = PR_TRUE;
+ if (nickname) {
+ search_nickname = PR_TRUE;
}
-search_again:
+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++;
+ 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;
+ if (search_both) {
+ search_both = PR_FALSE;
+ search_nickname = PR_FALSE;
+ goto search_again;
}
return NULL;
@@ -697,255 +695,255 @@ search_again:
*/
static SEC_PKCS12PrivateKey *
sec_pkcs12_find_key_in_keybag(SEC_PKCS12PrivateKeyBag *keybag,
- SECItem *nickname, SGNDigestInfo *thumbprint)
+ 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 == NULL) || ((nickname == NULL) && (thumbprint == NULL))) {
+ return NULL;
}
- if(keybag->privateKeys == NULL) {
- return NULL;
+ if (keybag->privateKeys == NULL) {
+ return NULL;
}
- if(thumbprint && nickname) {
- search_both = PR_TRUE;
+ if (thumbprint && nickname) {
+ search_both = PR_TRUE;
}
- if(nickname) {
- search_nickname = PR_TRUE;
+ if (nickname) {
+ search_nickname = PR_TRUE;
}
-search_again:
+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++;
+ 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;
+ 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
+/* 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)
+ 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;
+ 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;
+ 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
+ * 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_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)
+ 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;
- }
+
+ 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 ((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++;
- }
+ 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
+/* 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(PLArenaPool *arena, SECItem *dest,
- SECItem *src, PRBool zeroTerm,
- PRBool asciiConvert, PRBool toUnicode)
+ SECItem *src, PRBool zeroTerm,
+ PRBool asciiConvert, PRBool toUnicode)
{
PRBool success = PR_FALSE;
- if(!src || !dest) {
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- return 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);
+ if (arena) {
+ dest->data = (unsigned char *)PORT_ArenaZAlloc(arena, dest->len);
} else {
- dest->data = (unsigned char*)PORT_ZAlloc(dest->len);
+ dest->data = (unsigned char *)PORT_ZAlloc(dest->len);
}
- if(!dest->data) {
- dest->len = 0;
- return PR_FALSE;
+ 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);
+ 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;
+ PRBool swapUnicode = PR_FALSE;
#else
- PRBool swapUnicode = PR_TRUE;
+ PRBool swapUnicode = PR_TRUE;
#endif
- success = PORT_UCS2_ASCIIConversion(toUnicode, src->data, src->len, dest->data,
- dest->len, &dest->len, swapUnicode);
+ 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 (!success) {
+ if (!arena) {
+ PORT_Free(dest->data);
+ dest->data = NULL;
+ dest->len = 0;
+ }
+ return PR_FALSE;
}
if ((dest->len >= 2) &&
- (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;
+ (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;
@@ -956,388 +954,388 @@ 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 }
-};
+ {
+ { 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 }
-};
+ {
+ { 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 }
-};
+ {
+ { 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 }
-};
+ {
+ { 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 ,
+ {
+ { 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 }
-};
+ 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 ,
+ {
+ { 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 }
-};
+ 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 }
-};
+ {
+ { 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 },
-};
+ {
+ { 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 },
-};
+ {
+ { 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;
+ sec_pkcs12_choose_bag_type;
static const SEC_ASN1TemplateChooserPtr sec_pkcs12_bag_chooser_old =
- sec_pkcs12_choose_bag_type_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,
+ {
+ { 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 }
-};
+ &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,
+ {
+ { 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 }
-};
+ &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 }
-};
+ {
+ { 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 */
-};
+ {
+ { 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,
+ {
+ { 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 }
-};
+ 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 }
-};
+ {
+ { 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 ,
+ {
+ { 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 }
-};
+ 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 }
-};
+ {
+ { 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 }
-};
+ {
+ { 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;
+ sec_pkcs12_choose_cert_crl_type_old;
static const SEC_ASN1TemplateChooserPtr sec_pkcs12_cert_crl_chooser =
- sec_pkcs12_choose_cert_crl_type;
+ 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 }
-};
+ {
+ { 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 }
-};
+ {
+ { 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 },
-};
+ {
+ { 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 }
-};
+ {
+ { 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 }
-};
+ {
+ { 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 }
-};
+ {
+ { 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 },
-};
+ {
+ { 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 }
-};
+ {
+ { 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 }
-};
+ {
+ { 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 }
-};
+ {
+ { 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 }
-};
+ {
+ { 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 }
-};
+ {
+ { 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 }
-};
+ {
+ { SEC_ASN1_POINTER, 0, SEC_PKCS12PrivateKeyBagTemplate }
+ };
const SEC_ASN1Template SEC_PointerToPKCS12CertAndCRLBagTemplate_OLD[] =
-{
- { SEC_ASN1_POINTER, 0, SEC_PKCS12CertAndCRLBagTemplate_OLD }
-};
+ {
+ { SEC_ASN1_POINTER, 0, SEC_PKCS12CertAndCRLBagTemplate_OLD }
+ };
const SEC_ASN1Template SEC_PointerToPKCS12CertAndCRLBagTemplate[] =
-{
- { SEC_ASN1_POINTER, 0, SEC_PKCS12CertAndCRLBagTemplate }
-};
+ {
+ { SEC_ASN1_POINTER, 0, SEC_PKCS12CertAndCRLBagTemplate }
+ };
const SEC_ASN1Template SEC_PointerToPKCS12SecretBagTemplate[] =
-{
- { SEC_ASN1_POINTER, 0, SEC_PKCS12SecretBagTemplate }
-};
+ {
+ { SEC_ASN1_POINTER, 0, SEC_PKCS12SecretBagTemplate }
+ };
const SEC_ASN1Template SEC_PointerToPKCS12X509CertCRLTemplate_OLD[] =
-{
- { SEC_ASN1_POINTER, 0, SEC_PKCS12X509CertCRLTemplate_OLD }
-};
+ {
+ { SEC_ASN1_POINTER, 0, SEC_PKCS12X509CertCRLTemplate_OLD }
+ };
const SEC_ASN1Template SEC_PointerToPKCS12X509CertCRLTemplate[] =
-{
- { SEC_ASN1_POINTER, 0, SEC_PKCS12X509CertCRLTemplate }
-};
+ {
+ { SEC_ASN1_POINTER, 0, SEC_PKCS12X509CertCRLTemplate }
+ };
const SEC_ASN1Template SEC_PointerToPKCS12SDSICertTemplate[] =
-{
- { SEC_ASN1_POINTER, 0, SEC_PKCS12SDSICertTemplate }
-};
-
-
+ {
+ { SEC_ASN1_POINTER, 0, SEC_PKCS12SDSICertTemplate }
+ };
diff --git a/nss/lib/pkcs12/p12local.h b/nss/lib/pkcs12/p12local.h
index 024987c..f07122a 100644
--- a/nss/lib/pkcs12/p12local.h
+++ b/nss/lib/pkcs12/p12local.h
@@ -2,7 +2,6 @@
* License, v. 2.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_
@@ -23,27 +22,27 @@ 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 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 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);
+ SEC_PKCS12ESPVKItem *espvk);
extern void *sec_pkcs12_find_object(SEC_PKCS12SafeContents *safe,
- SEC_PKCS12Baggage *baggage, SECOidTag objType,
- SECItem *nickname, SGNDigestInfo *thumbprint);
+ SEC_PKCS12Baggage *baggage, SECOidTag objType,
+ SECItem *nickname, SGNDigestInfo *thumbprint);
extern PRBool sec_pkcs12_convert_item_to_unicode(PLArenaPool *arena, SECItem *dest,
- SECItem *src, PRBool zeroTerm,
- PRBool asciiConvert, PRBool toUnicode);
+ 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(
- PLArenaPool *poolp);
+ PLArenaPool *poolp);
extern SEC_PKCS12Baggage *sec_pkcs12_create_baggage(PLArenaPool *poolp);
extern SEC_PKCS12BaggageItem *sec_pkcs12_create_external_bag(SEC_PKCS12Baggage *luggage);
extern void SEC_PKCS12DestroyPFX(SEC_PKCS12PFXItem *pfx);
@@ -52,8 +51,8 @@ extern SEC_PKCS12AuthenticatedSafe *sec_pkcs12_new_asafe(PLArenaPool *poolp);
/* conversion from old to new */
extern SEC_PKCS12DecoderContext *
sec_PKCS12ConvertOldSafeToNew(PLArenaPool *arena, PK11SlotInfo *slot,
- PRBool swapUnicode, SECItem *pwitem,
- void *wincx, SEC_PKCS12SafeContents *safe,
- SEC_PKCS12Baggage *baggage);
-
+ PRBool swapUnicode, SECItem *pwitem,
+ void *wincx, SEC_PKCS12SafeContents *safe,
+ SEC_PKCS12Baggage *baggage);
+
#endif
diff --git a/nss/lib/pkcs12/p12plcy.c b/nss/lib/pkcs12/p12plcy.c
index 0a7608a..fef288c 100644
--- a/nss/lib/pkcs12/p12plcy.c
+++ b/nss/lib/pkcs12/p12plcy.c
@@ -2,56 +2,55 @@
* License, v. 2.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"
+#include "secpkcs5.h"
-#define PKCS12_NULL 0x0000
+#define PKCS12_NULL 0x0000
typedef struct pkcs12SuiteMapStr {
- SECOidTag algTag;
- unsigned int keyLengthBits; /* in bits */
- unsigned long suite;
- PRBool allowed;
- PRBool preferred;
+ 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}
+ { 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
+PRBool
SEC_PKCS12DecryptionAllowed(SECAlgorithmID *algid)
{
unsigned int keyLengthBits;
SECOidTag algId;
int i;
-
+
algId = SEC_PKCS5GetCryptoAlgorithm(algid);
- if(algId == SEC_OID_UNKNOWN) {
- return PR_FALSE;
+ 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)) {
+ while (pkcs12SuiteMaps[i].algTag != SEC_OID_UNKNOWN) {
+ if ((pkcs12SuiteMaps[i].algTag == algId) &&
+ (pkcs12SuiteMaps[i].keyLengthBits == keyLengthBits)) {
- return pkcs12SuiteMaps[i].allowed;
- }
- i++;
+ return pkcs12SuiteMaps[i].allowed;
+ }
+ i++;
}
return PR_FALSE;
@@ -64,33 +63,32 @@ SEC_PKCS12IsEncryptionAllowed(void)
int i;
i = 0;
- while(pkcs12SuiteMaps[i].algTag != SEC_OID_UNKNOWN) {
- if(pkcs12SuiteMaps[i].allowed == PR_TRUE) {
- return PR_TRUE;
- }
- i++;
+ 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)
+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++;
+ 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;
@@ -104,22 +102,21 @@ SEC_PKCS12SetPreferredCipher(long which, int on)
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++;
+ 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;
+ if ((turnedOn) && (turnedOff)) {
+ return SECSuccess;
}
return SECFailure;
}
-
diff --git a/nss/lib/pkcs12/p12t.h b/nss/lib/pkcs12/p12t.h
index d583f7d..62c2b50 100644
--- a/nss/lib/pkcs12/p12t.h
+++ b/nss/lib/pkcs12/p12t.h
@@ -9,10 +9,10 @@
#include "key.h"
#include "pkcs11.h"
#include "secpkcs7.h"
-#include "secdig.h" /* for SGNDigestInfo */
+#include "secdig.h" /* for SGNDigestInfo */
#include "pkcs12t.h"
-#define SEC_PKCS12_VERSION 3
+#define SEC_PKCS12_VERSION 3
/* structure declarations */
typedef struct sec_PKCS12PFXItemStr sec_PKCS12PFXItem;
@@ -32,8 +32,8 @@ struct sec_PKCS12CertBagStr {
/* certificate information */
union {
- SECItem x509Cert;
- SECItem SDSICert;
+ SECItem x509Cert;
+ SECItem SDSICert;
} value;
};
@@ -43,7 +43,7 @@ struct sec_PKCS12CRLBagStr {
/* certificate information */
union {
- SECItem x509CRL;
+ SECItem x509CRL;
} value;
};
@@ -67,12 +67,12 @@ struct sec_PKCS12SafeBagStr {
/* 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;
+ SECKEYPrivateKeyInfo *pkcs8KeyBag;
+ SECKEYEncryptedPrivateKeyInfo *pkcs8ShroudedKeyBag;
+ sec_PKCS12CertBag *certBag;
+ sec_PKCS12CRLBag *crlBag;
+ sec_PKCS12SecretBag *secretBag;
+ sec_PKCS12SafeContents *safeContents;
} safeBagContent;
sec_PKCS12Attribute **attribs;
@@ -92,11 +92,11 @@ struct sec_PKCS12SafeBagStr {
PRBool oldBagType;
SECPKCS12TargetTokenCAs tokenCAs;
};
-
+
struct sec_PKCS12SafeContentsStr {
sec_PKCS12SafeBag **safeBags;
SECItem **encodedSafeBags;
-
+
/* used locally */
PLArenaPool *arena;
unsigned int bagCount;
diff --git a/nss/lib/pkcs12/p12tmpl.c b/nss/lib/pkcs12/p12tmpl.c
index 184e0d4..7437cbc 100644
--- a/nss/lib/pkcs12/p12tmpl.c
+++ b/nss/lib/pkcs12/p12tmpl.c
@@ -23,43 +23,43 @@ sec_pkcs12_choose_safe_bag_type(void *src_or_dest, PRBool encoding)
SECOidData *oiddata;
if (src_or_dest == NULL) {
- return NULL;
+ return NULL;
}
- safeBag = (sec_PKCS12SafeBag*)src_or_dest;
+ safeBag = (sec_PKCS12SafeBag *)src_or_dest;
oiddata = SECOID_FindOID(&safeBag->safeBagType);
- if(oiddata == NULL) {
- return SEC_ASN1_GET(SEC_AnyTemplate);
+ 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;
+ 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;
+ 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;
}
@@ -72,23 +72,23 @@ sec_pkcs12_choose_crl_bag_type(void *src_or_dest, PRBool encoding)
SECOidData *oiddata;
if (src_or_dest == NULL) {
- return NULL;
+ return NULL;
}
- crlbag = (sec_PKCS12CRLBag*)src_or_dest;
+ crlbag = (sec_PKCS12CRLBag *)src_or_dest;
oiddata = SECOID_FindOID(&crlbag->bagID);
- if(oiddata == NULL) {
- return SEC_ASN1_GET(SEC_AnyTemplate);
+ 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;
+ default:
+ theTemplate = SEC_ASN1_GET(SEC_AnyTemplate);
+ break;
+ case SEC_OID_PKCS9_X509_CRL:
+ theTemplate = SEC_ASN1_GET(SEC_OctetStringTemplate);
+ break;
}
return theTemplate;
}
@@ -101,26 +101,26 @@ sec_pkcs12_choose_cert_bag_type(void *src_or_dest, PRBool encoding)
SECOidData *oiddata;
if (src_or_dest == NULL) {
- return NULL;
+ return NULL;
}
- certbag = (sec_PKCS12CertBag*)src_or_dest;
+ certbag = (sec_PKCS12CertBag *)src_or_dest;
oiddata = SECOID_FindOID(&certbag->bagID);
- if(oiddata == NULL) {
- return SEC_ASN1_GET(SEC_AnyTemplate);
+ 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;
+ 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;
}
@@ -133,35 +133,34 @@ sec_pkcs12_choose_attr_type(void *src_or_dest, PRBool encoding)
SECOidData *oiddata;
if (src_or_dest == NULL) {
- return NULL;
+ return NULL;
}
- attr = (sec_PKCS12Attribute*)src_or_dest;
+ attr = (sec_PKCS12Attribute *)src_or_dest;
oiddata = SECOID_FindOID(&attr->attrType);
- if(oiddata == NULL) {
- return SEC_ASN1_GET(SEC_AnyTemplate);
+ 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;
+ 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 }
};
@@ -195,73 +194,73 @@ const SEC_ASN1Template sec_PKCS12PointerToSafeContentsTemplate[] = {
};
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_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) },
+ 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_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) }
+ { 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_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_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 },
+ sec_PKCS12AttributeTemplate },
{ 0 }
};
const SEC_ASN1Template sec_PKCS12SafeContentsTemplate[] = {
- { SEC_ASN1_SEQUENCE_OF | SEC_ASN1_MAY_STREAM,
- offsetof(sec_PKCS12SafeContents, safeBags),
- sec_PKCS12SafeBagTemplate }
+ { 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) }
+ { 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 }
+ 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) }
+ { 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 },
+ { SEC_ASN1_DYNAMIC | SEC_ASN1_POINTER,
+ offsetof(sec_PKCS12CRLBag, value), &sec_pkcs12_crl_bag_chooser },
{ 0 }
};
@@ -269,8 +268,8 @@ 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 },
+ SEC_ASN1_CONTEXT_SPECIFIC | 0,
+ offsetof(sec_PKCS12CertBag, value), &sec_pkcs12_cert_bag_chooser },
{ 0 }
};
@@ -284,8 +283,8 @@ const SEC_ASN1Template sec_PKCS12SecretBagTemplate[] = {
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 },
+ { SEC_ASN1_SET_OF | SEC_ASN1_DYNAMIC,
+ offsetof(sec_PKCS12Attribute, attrValue),
+ &sec_pkcs12_attr_chooser },
{ 0 }
};
diff --git a/nss/lib/pkcs12/pkcs12.gyp b/nss/lib/pkcs12/pkcs12.gyp
new file mode 100644
index 0000000..5b296cc
--- /dev/null
+++ b/nss/lib/pkcs12/pkcs12.gyp
@@ -0,0 +1,29 @@
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+{
+ 'includes': [
+ '../../coreconf/config.gypi'
+ ],
+ 'targets': [
+ {
+ 'target_name': 'pkcs12',
+ 'type': 'static_library',
+ 'sources': [
+ 'p12creat.c',
+ 'p12d.c',
+ 'p12dec.c',
+ 'p12e.c',
+ 'p12local.c',
+ 'p12plcy.c',
+ 'p12tmpl.c'
+ ],
+ 'dependencies': [
+ '<(DEPTH)/exports.gyp:nss_exports'
+ ]
+ }
+ ],
+ 'variables': {
+ 'module': 'nss'
+ }
+} \ No newline at end of file
diff --git a/nss/lib/pkcs12/pkcs12.h b/nss/lib/pkcs12/pkcs12.h
index 5c67de5..57b3263 100644
--- a/nss/lib/pkcs12/pkcs12.h
+++ b/nss/lib/pkcs12/pkcs12.h
@@ -2,7 +2,6 @@
* License, v. 2.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_
@@ -11,26 +10,26 @@
SEC_BEGIN_PROTOS
-typedef SECItem * (* SEC_PKCS12GetPassword)(void *arg);
+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.
+/* 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);
+ 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
diff --git a/nss/lib/pkcs12/pkcs12t.h b/nss/lib/pkcs12/pkcs12t.h
index 60cbee7..ad00d7b 100644
--- a/nss/lib/pkcs12/pkcs12t.h
+++ b/nss/lib/pkcs12/pkcs12t.h
@@ -11,15 +11,15 @@
#include "key.h"
#include "plarena.h"
#include "secpkcs7.h"
-#include "secdig.h" /* for SGNDigestInfo */
+#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 */
+ 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 */
@@ -45,96 +45,88 @@ typedef struct SEC_PKCS12SecretAdditionalStr SEC_PKCS12SecretAdditional;
typedef struct SEC_PKCS12SecretItemStr SEC_PKCS12SecretItem;
typedef struct SEC_PKCS12SecretBagStr SEC_PKCS12SecretBag;
-typedef SECItem *(* SEC_PKCS12PasswordFunc)(SECItem *args);
+typedef SECItem *(*SEC_PKCS12PasswordFunc)(SECItem *args);
/* PKCS12 types */
/* stores shrouded keys */
-struct SEC_PKCS12BaggageStr
-{
- PLArenaPool *poolp;
+struct SEC_PKCS12BaggageStr {
+ PLArenaPool *poolp;
SEC_PKCS12BaggageItem **bags;
- int luggage_size; /* used locally */
+ int luggage_size; /* used locally */
};
-/* additional data to be associated with keys. currently there
+/* 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;
+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;
+struct SEC_PKCS12PVKSupportingDataStr {
+ PLArenaPool *poolp;
+ SGNDigestInfo **assocCerts;
+ SECItem regenerable;
+ SECItem nickname;
+ SEC_PKCS12PVKAdditionalData pvkAdditional;
+ SECItem pvkAdditionalDER;
+
+ SECItem uniNickName;
/* used locally */
- int nThumbs;
+ int nThumbs;
};
/* shrouded key structure. supports only pkcs8 shrouding
* currently.
*/
-struct SEC_PKCS12ESPVKItemStr
-{
- PLArenaPool *poolp; /* used locally */
- SECOidData *espvkTag; /* used locally */
- SECItem espvkOID;
+struct SEC_PKCS12ESPVKItemStr {
+ PLArenaPool *poolp; /* used locally */
+ SECOidData *espvkTag; /* used locally */
+ SECItem espvkOID;
SEC_PKCS12PVKSupportingData espvkData;
- union
- {
- SECKEYEncryptedPrivateKeyInfo *pkcs8KeyShroud;
+ 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 */
+ 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
-{
+struct SEC_PKCS12SafeBagStr {
PLArenaPool *poolp;
- SECOidData *safeBagTypeTag; /* used locally */
- SECItem safeBagType;
- union
- {
- SEC_PKCS12PrivateKeyBag *keyBag;
- SEC_PKCS12CertAndCRLBag *certAndCRLBag;
- SEC_PKCS12SecretBag *secretBag;
+ SECOidData *safeBagTypeTag; /* used locally */
+ SECItem safeBagType;
+ union {
+ SEC_PKCS12PrivateKeyBag *keyBag;
+ SEC_PKCS12CertAndCRLBag *certAndCRLBag;
+ SEC_PKCS12SecretBag *secretBag;
} safeContent;
- SECItem derSafeContent;
- SECItem safeBagName;
+ SECItem derSafeContent;
+ SECItem safeBagName;
- SECItem uniSafeBagName;
+ 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;
+struct SEC_PKCS12SafeContentsStr {
+ PLArenaPool *poolp;
+ SEC_PKCS12SafeBag **contents;
/* used for tracking purposes */
int safe_size;
@@ -146,173 +138,158 @@ struct SEC_PKCS12SafeContentsStr
/* private key structure which holds encrypted private key and
* supporting data including nickname and certificate thumbprint.
*/
-struct SEC_PKCS12PrivateKeyStr
-{
+struct SEC_PKCS12PrivateKeyStr {
PLArenaPool *poolp;
SEC_PKCS12PVKSupportingData pvkData;
- SECKEYPrivateKeyInfo pkcs8data; /* borrowed from PKCS 8 */
+ 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 */
+ 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;
+struct SEC_PKCS12PrivateKeyBagStr {
+ PLArenaPool *poolp;
+ SEC_PKCS12PrivateKey **privateKeys;
- int bag_size; /* used locally */
+ 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;
+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 */
+ SECItem nickname; /* used locally */
+ PRBool duplicate; /* used locally */
};
-/* x509 certificate structure. typically holds the der encoding
+/* 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;
+struct SEC_PKCS12X509CertCRLStr {
+ PLArenaPool *poolp;
+ SEC_PKCS7ContentInfo certOrCRL;
+ SGNDigestInfo thumbprint;
- SECItem *derLeafCert; /* used locally */
+ SECItem *derLeafCert; /* used locally */
};
-/* sdsi certificate structure. typically holds the der encoding
+/* 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;
+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;
+struct SEC_PKCS12CertAndCRLBagStr {
+ PLArenaPool *poolp;
+ SEC_PKCS12CertAndCRL **certAndCRLs;
- int bag_size; /* used locally */
+ 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;
+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_PKCS12SecretStr {
+ PLArenaPool *poolp;
+ SECItem secretName;
+ SECItem value;
+ SEC_PKCS12SecretAdditional secretAdditional;
+
+ SECItem uniSecretName;
};
-struct SEC_PKCS12SecretItemStr
-{
- PLArenaPool *poolp;
- SEC_PKCS12Secret secret;
- SEC_PKCS12SafeBag subFolder;
-};
+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;
+struct SEC_PKCS12SecretBagStr {
+ PLArenaPool *poolp;
+ SEC_PKCS12SecretItem **secrets;
- int bag_size; /* used locally */
+ int bag_size; /* used locally */
};
-struct SEC_PKCS12MacDataStr
-{
- SGNDigestInfo safeMac;
- SECItem macSalt;
+struct SEC_PKCS12MacDataStr {
+ SGNDigestInfo safeMac;
+ SECItem macSalt;
};
/* outer transfer unit */
-struct SEC_PKCS12PFXItemStr
-{
- PLArenaPool *poolp;
- SEC_PKCS12MacData macData;
- SEC_PKCS7ContentInfo authSafe;
+struct SEC_PKCS12PFXItemStr {
+ PLArenaPool *poolp;
+ SEC_PKCS12MacData macData;
+ SEC_PKCS7ContentInfo authSafe;
/* for compatibility with beta */
- PRBool old;
- SGNDigestInfo old_safeMac;
- SECItem old_macSalt;
+ PRBool old;
+ SGNDigestInfo old_safeMac;
+ SECItem old_macSalt;
/* compatibility between platforms for unicode swapping */
- PRBool swapUnicode;
+ PRBool swapUnicode;
};
struct SEC_PKCS12BaggageItemStr {
- PLArenaPool *poolp;
- SEC_PKCS12ESPVKItem **espvks;
- SEC_PKCS12SafeBag **unencSecrets;
+ PLArenaPool *poolp;
+ SEC_PKCS12ESPVKItem **espvks;
+ SEC_PKCS12SafeBag **unencSecrets;
int nEspvks;
- int nSecrets;
+ int nSecrets;
};
-
+
/* stores shrouded keys */
-struct SEC_PKCS12Baggage_OLDStr
-{
- PLArenaPool *poolp;
+struct SEC_PKCS12Baggage_OLDStr {
+ PLArenaPool *poolp;
SEC_PKCS12ESPVKItem **espvks;
- int luggage_size; /* used locally */
+ 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;
+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;
@@ -321,9 +298,7 @@ struct SEC_PKCS12AuthenticatedSafeStr
SEC_PKCS7ContentInfo old_safe;
PRBool swapUnicode;
};
-#define SEC_PKCS12_PFX_VERSION 1 /* what we create */
-
-
+#define SEC_PKCS12_PFX_VERSION 1 /* what we create */
/* PKCS 12 Templates */
extern const SEC_ASN1Template SEC_PKCS12PFXItemTemplate_OLD[];
diff --git a/nss/lib/pkcs7/certread.c b/nss/lib/pkcs7/certread.c
index 88812c7..2d692f1 100644
--- a/nss/lib/pkcs7/certread.c
+++ b/nss/lib/pkcs7/certread.c
@@ -17,7 +17,7 @@ typedef struct ContentInfoStr ContentInfo;
typedef struct DegenerateSignedDataStr DegenerateSignedData;
struct ContentInfoStr {
- SECOidTag contentTypeTag; /* local; not part of encoding */
+ SECOidTag contentTypeTag; /* local; not part of encoding */
SECItem contentType;
union {
SECItem *data;
@@ -37,43 +37,42 @@ struct DegenerateSignedDataStr {
static const SEC_ASN1Template *
choose_content_template(void *src_or_dest, PRBool encoding);
-static const SEC_ASN1TemplateChooserPtr template_chooser
- = choose_content_template;
+static const SEC_ASN1TemplateChooserPtr template_chooser = choose_content_template;
static const SEC_ASN1Template ContentInfoTemplate[] = {
{ SEC_ASN1_SEQUENCE,
- 0, NULL, sizeof(ContentInfo) },
+ 0, NULL, sizeof(ContentInfo) },
{ SEC_ASN1_OBJECT_ID,
- offsetof(ContentInfo,contentType) },
+ offsetof(ContentInfo, contentType) },
{ SEC_ASN1_OPTIONAL | SEC_ASN1_DYNAMIC |
- SEC_ASN1_EXPLICIT | SEC_ASN1_CONSTRUCTED | SEC_ASN1_CONTEXT_SPECIFIC | 0,
- offsetof(ContentInfo,content),
- &template_chooser },
+ SEC_ASN1_EXPLICIT | SEC_ASN1_CONSTRUCTED | SEC_ASN1_CONTEXT_SPECIFIC | 0,
+ offsetof(ContentInfo, content),
+ &template_chooser },
{ 0 }
};
static const SEC_ASN1Template DegenerateSignedDataTemplate[] = {
{ SEC_ASN1_SEQUENCE,
- 0, NULL, sizeof(DegenerateSignedData) },
+ 0, NULL, sizeof(DegenerateSignedData) },
{ SEC_ASN1_INTEGER,
- offsetof(DegenerateSignedData,version) },
+ offsetof(DegenerateSignedData, version) },
{ SEC_ASN1_SET_OF | SEC_ASN1_XTRN,
- offsetof(DegenerateSignedData,digestAlgorithms),
- SEC_ASN1_SUB(SEC_AnyTemplate) },
+ offsetof(DegenerateSignedData, digestAlgorithms),
+ SEC_ASN1_SUB(SEC_AnyTemplate) },
{ SEC_ASN1_INLINE,
- offsetof(DegenerateSignedData,contentInfo),
- ContentInfoTemplate },
+ offsetof(DegenerateSignedData, contentInfo),
+ ContentInfoTemplate },
{ SEC_ASN1_OPTIONAL | SEC_ASN1_CONSTRUCTED | SEC_ASN1_CONTEXT_SPECIFIC |
- SEC_ASN1_XTRN | 0,
- offsetof(DegenerateSignedData,certificates),
- SEC_ASN1_SUB(SEC_SetOfAnyTemplate) },
+ SEC_ASN1_XTRN | 0,
+ offsetof(DegenerateSignedData, certificates),
+ SEC_ASN1_SUB(SEC_SetOfAnyTemplate) },
{ SEC_ASN1_OPTIONAL | SEC_ASN1_CONSTRUCTED | SEC_ASN1_CONTEXT_SPECIFIC |
- SEC_ASN1_XTRN | 1,
- offsetof(DegenerateSignedData,crls),
- SEC_ASN1_SUB(SEC_SetOfAnyTemplate) },
+ SEC_ASN1_XTRN | 1,
+ offsetof(DegenerateSignedData, crls),
+ SEC_ASN1_SUB(SEC_SetOfAnyTemplate) },
{ SEC_ASN1_SET_OF | SEC_ASN1_XTRN,
- offsetof(DegenerateSignedData,signerInfos),
- SEC_ASN1_SUB(SEC_AnyTemplate) },
+ offsetof(DegenerateSignedData, signerInfos),
+ SEC_ASN1_SUB(SEC_AnyTemplate) },
{ 0 }
};
@@ -100,18 +99,18 @@ choose_content_template(void *src_or_dest, PRBool encoding)
if (src_or_dest == NULL)
return NULL;
- cinfo = (ContentInfo*)src_or_dest;
+ cinfo = (ContentInfo *)src_or_dest;
kind = GetContentTypeTag(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 = PointerToDegenerateSignedDataTemplate;
- break;
+ 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 = PointerToDegenerateSignedDataTemplate;
+ break;
}
return theTemplate;
}
@@ -120,50 +119,45 @@ static SECStatus
SEC_ReadPKCS7Certs(SECItem *pkcs7Item, CERTImportCertificateFunc f, void *arg)
{
ContentInfo contentInfo;
- SECStatus rv;
+ SECStatus rv = SECFailure;
SECItem **certs;
int count;
PLArenaPool *arena;
arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
- if ( arena == NULL ) {
- return SECFailure;
+ if (arena == NULL) {
+ return rv;
}
PORT_Memset(&contentInfo, 0, sizeof(contentInfo));
- rv = SEC_ASN1DecodeItem(arena, &contentInfo, ContentInfoTemplate,
- pkcs7Item);
- if ( rv != SECSuccess ) {
- goto loser;
+ if (SEC_ASN1DecodeItem(arena, &contentInfo, ContentInfoTemplate,
+ pkcs7Item) != SECSuccess) {
+ goto done;
}
- if ( GetContentTypeTag(&contentInfo) != SEC_OID_PKCS7_SIGNED_DATA ) {
- goto loser;
+ if (GetContentTypeTag(&contentInfo) != SEC_OID_PKCS7_SIGNED_DATA) {
+ goto done;
}
+ rv = SECSuccess;
+
certs = contentInfo.content.signedData->certificates;
- if ( certs ) {
- count = 0;
-
- while ( *certs ) {
- count++;
- certs++;
- }
- rv = (* f)(arg, contentInfo.content.signedData->certificates, count);
+ if (certs) {
+ count = 0;
+
+ while (*certs) {
+ count++;
+ certs++;
+ }
+ rv = (*f)(arg, contentInfo.content.signedData->certificates, count);
}
-
- rv = SECSuccess;
-
- goto done;
-loser:
- rv = SECFailure;
-
+
done:
- if ( arena ) {
- PORT_FreeArena(arena, PR_FALSE);
+ if (arena) {
+ PORT_FreeArena(arena, PR_FALSE);
}
- return(rv);
+ return rv;
}
const SEC_ASN1Template SEC_CertSequenceTemplate[] = {
@@ -173,7 +167,7 @@ const SEC_ASN1Template SEC_CertSequenceTemplate[] = {
static SECStatus
SEC_ReadCertSequence(SECItem *certsItem, CERTImportCertificateFunc f, void *arg)
{
- SECStatus rv;
+ SECStatus rv = SECFailure;
SECItem **certs;
int count;
SECItem **rawCerts = NULL;
@@ -181,51 +175,44 @@ SEC_ReadCertSequence(SECItem *certsItem, CERTImportCertificateFunc f, void *arg)
ContentInfo contentInfo;
arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
- if ( arena == NULL ) {
- return SECFailure;
+ if (arena == NULL) {
+ return rv;
}
PORT_Memset(&contentInfo, 0, sizeof(contentInfo));
- rv = SEC_ASN1DecodeItem(arena, &contentInfo, ContentInfoTemplate,
- certsItem);
- if ( rv != SECSuccess ) {
- goto loser;
+ if (SEC_ASN1DecodeItem(arena, &contentInfo, ContentInfoTemplate,
+ certsItem) != SECSuccess) {
+ goto done;
}
- if ( GetContentTypeTag(&contentInfo) != SEC_OID_NS_TYPE_CERT_SEQUENCE ) {
- goto loser;
+ if (GetContentTypeTag(&contentInfo) != SEC_OID_NS_TYPE_CERT_SEQUENCE) {
+ goto done;
}
- rv = SEC_QuickDERDecodeItem(arena, &rawCerts, SEC_CertSequenceTemplate,
- contentInfo.content.data);
-
- if (rv != SECSuccess) {
- goto loser;
+ if (SEC_QuickDERDecodeItem(arena, &rawCerts, SEC_CertSequenceTemplate,
+ contentInfo.content.data) != SECSuccess) {
+ goto done;
}
+ rv = SECSuccess;
+
certs = rawCerts;
- if ( certs ) {
- count = 0;
-
- while ( *certs ) {
- count++;
- certs++;
- }
- rv = (* f)(arg, rawCerts, count);
+ if (certs) {
+ count = 0;
+
+ while (*certs) {
+ count++;
+ certs++;
+ }
+ rv = (*f)(arg, rawCerts, count);
}
-
- rv = SECSuccess;
-
- goto done;
-loser:
- rv = SECFailure;
-
+
done:
- if ( arena ) {
- PORT_FreeArena(arena, PR_FALSE);
+ if (arena) {
+ PORT_FreeArena(arena, PR_FALSE);
}
-
- return(rv);
+
+ return rv;
}
CERTCertificate *
@@ -237,18 +224,18 @@ CERT_ConvertAndDecodeCertificate(char *certstr)
rv = ATOB_ConvertAsciiToItem(&der, certstr);
if (rv != SECSuccess)
- return NULL;
+ return NULL;
- cert = CERT_NewTempCertificate(CERT_GetDefaultCertDB(),
+ 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_HEADER[] = "-----BEGIN CERTIFICATE-----";
static const char NS_CERT_TRAILER[] = "-----END CERTIFICATE-----";
-#define NS_CERT_HEADER_LEN ((sizeof NS_CERT_HEADER) - 1)
+#define NS_CERT_HEADER_LEN ((sizeof NS_CERT_HEADER) - 1)
#define NS_CERT_TRAILER_LEN ((sizeof NS_CERT_TRAILER) - 1)
/*
@@ -256,18 +243,18 @@ static const char NS_CERT_TRAILER[] = "-----END CERTIFICATE-----";
*/
SECStatus
CERT_DecodeCertPackage(char *certbuf,
- int certlen,
- CERTImportCertificateFunc f,
- void *arg)
+ 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);
+ 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
@@ -282,220 +269,219 @@ CERT_DecodeCertPackage(char *certbuf,
* bytes.
*/
if (certlen < 17) {
- PORT_SetError(SEC_ERROR_INPUT_LEN);
- return(SECFailure);
+ 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:
- /* oid: 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x07, 0x02 */
- return(SEC_ReadPKCS7Certs(&certitem, f, arg));
- break;
- case SEC_OID_NS_TYPE_CERT_SEQUENCE:
- /* oid: 0x60, 0x86, 0x48, 0x01, 0x86, 0xf8, 0x42, 0x02, 0x05 */
- 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);
- }
+ if ((*cp & 0x1f) == SEC_ASN1_SEQUENCE) {
+ SECItem certitem;
+ SECItem *pcertitem = &certitem;
+ PRUint64 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 + 2L)) {
+ if (certlen > (seqLen + seqLenLen + 2L))
+ 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:
+ /* oid: 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x07, 0x02 */
+ return (SEC_ReadPKCS7Certs(&certitem, f, arg));
+ break;
+ case SEC_OID_NS_TYPE_CERT_SEQUENCE:
+ /* oid: 0x60, 0x86, 0x48, 0x01, 0x86, 0xf8, 0x42, 0x02, 0x05 */
+ 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;
+/* 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;
+ 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';
- }
+ 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;
- }
+ 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) {
+ /* 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;
+ if (certbegin && certend) {
+ unsigned int binLen;
- *certend = 0;
- /* convert to binary */
- bincert = ATOB_AsciiToData((char *)certbegin, &binLen);
- if (!bincert) {
- rv = SECFailure;
- goto loser;
- }
+ *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);
- /* now recurse to decode the binary */
- rv = CERT_DecodeCertPackage((char *)bincert, binLen, f, arg);
-
} else {
- PORT_SetError(SEC_ERROR_BAD_DER);
- rv = SECFailure;
+ PORT_SetError(SEC_ERROR_BAD_DER);
+ rv = SECFailure;
}
- }
+}
loser:
- if ( bincert ) {
- PORT_Free(bincert);
+ if (bincert) {
+ PORT_Free(bincert);
}
- if ( ascCert ) {
- PORT_Free(ascCert);
+ if (ascCert) {
+ PORT_Free(ascCert);
}
- return(rv);
+ return (rv);
}
typedef struct {
@@ -508,15 +494,14 @@ 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);
+ return (rv);
}
-
/*
* read an old style ascii or binary certificate
*/
@@ -526,18 +511,18 @@ 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);
+ (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);
+
+ return (cert);
}
diff --git a/nss/lib/pkcs7/exports.gyp b/nss/lib/pkcs7/exports.gyp
new file mode 100644
index 0000000..e5c9f09
--- /dev/null
+++ b/nss/lib/pkcs7/exports.gyp
@@ -0,0 +1,33 @@
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+{
+ 'includes': [
+ '../../coreconf/config.gypi'
+ ],
+ 'targets': [
+ {
+ 'target_name': 'lib_pkcs7_exports',
+ 'type': 'none',
+ 'copies': [
+ {
+ 'files': [
+ 'pkcs7t.h',
+ 'secmime.h',
+ 'secpkcs7.h'
+ ],
+ 'destination': '<(nss_public_dist_dir)/<(module)'
+ },
+ {
+ 'files': [
+ 'p7local.h'
+ ],
+ 'destination': '<(nss_private_dist_dir)/<(module)'
+ }
+ ]
+ }
+ ],
+ 'variables': {
+ 'module': 'nss'
+ }
+}
diff --git a/nss/lib/pkcs7/p7common.c b/nss/lib/pkcs7/p7common.c
index 10015ce..8a6ac03 100644
--- a/nss/lib/pkcs7/p7common.c
+++ b/nss/lib/pkcs7/p7common.c
@@ -19,18 +19,17 @@
* and return the inner content type.
*/
SECOidTag
-SEC_PKCS7ContentType (SEC_PKCS7ContentInfo *cinfo)
+SEC_PKCS7ContentType(SEC_PKCS7ContentInfo *cinfo)
{
if (cinfo->contentTypeTag == NULL)
- cinfo->contentTypeTag = SECOID_FindOID(&(cinfo->contentType));
+ cinfo->contentTypeTag = SECOID_FindOID(&(cinfo->contentType));
if (cinfo->contentTypeTag == NULL)
- return SEC_OID_UNKNOWN;
+ return SEC_OID_UNKNOWN;
return cinfo->contentTypeTag->offset;
}
-
/*
* Destroy a PKCS7 contentInfo and all of its sub-pieces.
*/
@@ -43,105 +42,98 @@ SEC_PKCS7DestroyContentInfo(SEC_PKCS7ContentInfo *cinfo)
SEC_PKCS7SignerInfo **signerinfos;
SEC_PKCS7RecipientInfo **recipientinfos;
- PORT_Assert (cinfo->refCount > 0);
+ PORT_Assert(cinfo->refCount > 0);
if (cinfo->refCount <= 0)
- return;
+ return;
cinfo->refCount--;
if (cinfo->refCount > 0)
- return;
+ return;
certs = NULL;
certlists = NULL;
recipientinfos = NULL;
signerinfos = NULL;
- kind = SEC_PKCS7ContentType (cinfo);
+ 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;
+ 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;
+ CERTCertificate *cert;
- while ((cert = *certs++) != NULL) {
- CERT_DestroyCertificate (cert);
- }
+ while ((cert = *certs++) != NULL) {
+ CERT_DestroyCertificate(cert);
+ }
}
if (certlists != NULL) {
- CERTCertificateList *certlist;
+ CERTCertificateList *certlist;
- while ((certlist = *certlists++) != NULL) {
- CERT_DestroyCertificateList (certlist);
- }
+ while ((certlist = *certlists++) != NULL) {
+ CERT_DestroyCertificateList(certlist);
+ }
}
if (recipientinfos != NULL) {
- SEC_PKCS7RecipientInfo *ri;
+ SEC_PKCS7RecipientInfo *ri;
- while ((ri = *recipientinfos++) != NULL) {
- if (ri->cert != NULL)
- CERT_DestroyCertificate (ri->cert);
- }
+ 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);
- }
+ 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? */
+ 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
@@ -151,30 +143,29 @@ SEC_PKCS7ContentInfo *
SEC_PKCS7CopyContentInfo(SEC_PKCS7ContentInfo *cinfo)
{
if (cinfo == NULL)
- return NULL;
+ return NULL;
- PORT_Assert (cinfo->refCount > 0);
+ 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.
- */
+ /*
+ * 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.
@@ -185,64 +176,58 @@ SEC_PKCS7GetContent(SEC_PKCS7ContentInfo *cinfo)
{
SECOidTag kind;
- kind = SEC_PKCS7ContentType (cinfo);
+ 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;
+ 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
@@ -250,35 +235,34 @@ SEC_PKCS7GetContent(SEC_PKCS7ContentInfo *cinfo)
* they all need a formatting/style rehaul)
*/
-/* retrieve the algorithm identifier for encrypted data.
+/* 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
+ * 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;
+ 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;
@@ -287,20 +271,20 @@ SEC_PKCS7GetEncryptionAlgorithm(SEC_PKCS7ContentInfo *cinfo)
/* 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
+ * in the event of an error, SECFailure is returned. SECSuccess
* indicates the content was successfully set.
*/
-SECStatus
+SECStatus
SEC_PKCS7SetContent(SEC_PKCS7ContentInfo *cinfo,
- const char *buf,
- unsigned long len)
+ const char *buf,
+ unsigned long len)
{
SECOidTag cinfo_type;
SECStatus rv;
@@ -314,76 +298,75 @@ SEC_PKCS7SetContent(SEC_PKCS7ContentInfo *cinfo,
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;
+ 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;
}
@@ -397,146 +380,145 @@ loser:
* 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
+SECStatus
SEC_PKCS7EncryptContents(PLArenaPool *poolp,
- SEC_PKCS7ContentInfo *cinfo,
- SECItem *key,
- void *wincx)
+ SEC_PKCS7ContentInfo *cinfo,
+ SECItem *key,
+ void *wincx)
{
- SECAlgorithmID *algid = NULL;
- SECItem * src;
- SECItem * dest;
- SECItem * blocked_data = NULL;
- void * mark;
- void * cx;
- PK11SymKey * eKey = NULL;
- PK11SlotInfo * slot = NULL;
+ SECAlgorithmID *algid = 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;
+ int bs;
+ SECStatus rv = SECFailure;
+ SECItem *c_param = NULL;
- if((cinfo == NULL) || (key == NULL))
- return SECFailure;
+ if ((cinfo == NULL) || (key == NULL))
+ return SECFailure;
- if(SEC_PKCS7ContentType(cinfo) != SEC_OID_PKCS7_ENCRYPTED_DATA)
- return SECFailure;
+ if (SEC_PKCS7ContentType(cinfo) != SEC_OID_PKCS7_ENCRYPTED_DATA)
+ return SECFailure;
- algid = SEC_PKCS7GetEncryptionAlgorithm(cinfo);
- if(algid == NULL)
- return SECFailure;
+ algid = SEC_PKCS7GetEncryptionAlgorithm(cinfo);
+ if (algid == NULL)
+ return SECFailure;
- if(poolp == NULL)
- poolp = cinfo->poolp;
+ 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->data = (unsigned char *)PORT_ArenaZAlloc(poolp, (src->len + 64));
dest->len = (src->len + 64);
- if(dest->data == NULL) {
- rv = SECFailure;
- goto loser;
+ if (dest->data == NULL) {
+ rv = SECFailure;
+ goto loser;
}
slot = PK11_GetInternalKeySlot();
- if(slot == NULL) {
- rv = SECFailure;
- goto loser;
+ if (slot == NULL) {
+ rv = SECFailure;
+ goto loser;
}
eKey = PK11_PBEKeyGen(slot, algid, key, PR_FALSE, wincx);
- if(eKey == NULL) {
- rv = SECFailure;
- goto loser;
+ if (eKey == NULL) {
+ rv = SECFailure;
+ goto loser;
}
-
+
cryptoMechType = PK11_GetPBECryptoMechanism(algid, &c_param, key);
if (cryptoMechType == CKM_INVALID_MECHANISM) {
- rv = SECFailure;
- goto loser;
+ 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;
- }
- }
+ 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;
- }
+ 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;
+ 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);
+ 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 (blocked_data != NULL)
+ SECITEM_ZfreeItem(blocked_data, PR_TRUE);
- if(rv == SECFailure)
- PORT_ArenaRelease(poolp, mark);
- else
- PORT_ArenaUnmark(poolp, mark);
+ if (rv == SECFailure)
+ PORT_ArenaRelease(poolp, mark);
+ else
+ PORT_ArenaUnmark(poolp, mark);
+
+ if (eKey != NULL)
+ PK11_FreeSymKey(eKey);
- if(eKey != NULL)
- PK11_FreeSymKey(eKey);
+ if (slot != NULL)
+ PK11_FreeSlot(slot);
- if(slot != NULL)
- PK11_FreeSlot(slot);
+ if (c_param != NULL)
+ SECITEM_ZfreeItem(c_param, PR_TRUE);
- if(c_param != NULL)
- SECITEM_ZfreeItem(c_param, PR_TRUE);
-
return rv;
}
@@ -550,15 +532,15 @@ loser:
* 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
+SECStatus
SEC_PKCS7DecryptContents(PLArenaPool *poolp,
- SEC_PKCS7ContentInfo *cinfo,
- SECItem *key,
- void *wincx)
+ SEC_PKCS7ContentInfo *cinfo,
+ SECItem *key,
+ void *wincx)
{
SECAlgorithmID *algid = NULL;
SECStatus rv = SECFailure;
@@ -572,113 +554,110 @@ SEC_PKCS7DecryptContents(PLArenaPool *poolp,
SECItem *c_param = NULL;
int bs;
- if((cinfo == NULL) || (key == NULL))
- return SECFailure;
+ if ((cinfo == NULL) || (key == NULL))
+ return SECFailure;
- if(SEC_PKCS7ContentType(cinfo) != SEC_OID_PKCS7_ENCRYPTED_DATA)
- return SECFailure;
+ if (SEC_PKCS7ContentType(cinfo) != SEC_OID_PKCS7_ENCRYPTED_DATA)
+ return SECFailure;
- algid = SEC_PKCS7GetEncryptionAlgorithm(cinfo);
- if(algid == NULL)
- return SECFailure;
+ algid = SEC_PKCS7GetEncryptionAlgorithm(cinfo);
+ if (algid == NULL)
+ return SECFailure;
- if(poolp == NULL)
- poolp = cinfo->poolp;
+ 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->data = (unsigned char *)PORT_ArenaZAlloc(poolp, (src->len + 64));
dest->len = (src->len + 64);
- if(dest->data == NULL) {
- rv = SECFailure;
- goto loser;
+ if (dest->data == NULL) {
+ rv = SECFailure;
+ goto loser;
}
slot = PK11_GetInternalKeySlot();
- if(slot == NULL) {
- rv = SECFailure;
- goto loser;
+ if (slot == NULL) {
+ rv = SECFailure;
+ goto loser;
}
eKey = PK11_PBEKeyGen(slot, algid, key, PR_FALSE, wincx);
- if(eKey == NULL) {
- rv = SECFailure;
- goto loser;
+ if (eKey == NULL) {
+ rv = SECFailure;
+ goto loser;
}
-
+
cryptoMechType = PK11_GetPBECryptoMechanism(algid, &c_param, key);
if (cryptoMechType == CKM_INVALID_MECHANISM) {
- rv = SECFailure;
- goto loser;
+ rv = SECFailure;
+ goto loser;
}
cx = PK11_CreateContextBySymKey(cryptoMechType, CKA_DECRYPT,
- eKey, c_param);
- if(cx == NULL) {
- rv = SECFailure;
- goto loser;
+ 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);
+ 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 ? */
- }
- }
+ 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(rv == SECFailure)
- PORT_ArenaRelease(poolp, mark);
+ if (rv == SECFailure)
+ PORT_ArenaRelease(poolp, mark);
else
- PORT_ArenaUnmark(poolp, mark);
+ PORT_ArenaUnmark(poolp, mark);
+
+ if (eKey != NULL)
+ PK11_FreeSymKey(eKey);
- if(eKey != NULL)
- PK11_FreeSymKey(eKey);
+ if (slot != NULL)
+ PK11_FreeSlot(slot);
- if(slot != NULL)
- PK11_FreeSlot(slot);
+ if (c_param != NULL)
+ SECITEM_ZfreeItem(c_param, PR_TRUE);
- 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;
+ 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;
+ if (cinfo->contentTypeTag->offset == SEC_OID_PKCS7_ENVELOPED_DATA)
+ return cinfo->content.envelopedData->encContentInfo.keysize;
+ else
+ return 0;
}
-
diff --git a/nss/lib/pkcs7/p7create.c b/nss/lib/pkcs7/p7create.c
index 983b7b5..fcf0cad 100644
--- a/nss/lib/pkcs7/p7create.c
+++ b/nss/lib/pkcs7/p7create.c
@@ -21,106 +21,104 @@
const int NSS_PBE_DEFAULT_ITERATION_COUNT = 2000; /* used in p12e.c too */
static SECStatus
-sec_pkcs7_init_content_info (SEC_PKCS7ContentInfo *cinfo, PLArenaPool *poolp,
- SECOidTag kind, PRBool detached)
+sec_pkcs7_init_content_info(SEC_PKCS7ContentInfo *cinfo, PLArenaPool *poolp,
+ SECOidTag kind, PRBool detached)
{
void *thing;
int version;
SECItem *versionp;
SECStatus rv;
- PORT_Assert (cinfo != NULL && poolp != NULL);
+ PORT_Assert(cinfo != NULL && poolp != NULL);
if (cinfo == NULL || poolp == NULL)
- return SECFailure;
+ return SECFailure;
- cinfo->contentTypeTag = SECOID_FindOIDByTag (kind);
- PORT_Assert (cinfo->contentTypeTag
- && cinfo->contentTypeTag->offset == kind);
+ cinfo->contentTypeTag = SECOID_FindOIDByTag(kind);
+ PORT_Assert(cinfo->contentTypeTag && cinfo->contentTypeTag->offset == kind);
- rv = SECITEM_CopyItem (poolp, &(cinfo->contentType),
- &(cinfo->contentTypeTag->oid));
+ rv = SECITEM_CopyItem(poolp, &(cinfo->contentType),
+ &(cinfo->contentTypeTag->oid));
if (rv != SECSuccess)
- return rv;
+ return rv;
if (detached)
- return SECSuccess;
+ 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;
+ 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;
+ return SECFailure;
if (versionp != NULL) {
- SECItem *dummy;
+ SECItem *dummy;
- PORT_Assert (version >= 0);
- dummy = SEC_ASN1EncodeInteger (poolp, versionp, version);
- if (dummy == NULL)
- return SECFailure;
- PORT_Assert (dummy == versionp);
+ 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_pkcs7_create_content_info(SECOidTag kind, PRBool detached,
+ SECKEYGetPasswordKey pwfn, void *pwfn_arg)
{
SEC_PKCS7ContentInfo *cinfo;
PLArenaPool *poolp;
SECStatus rv;
- poolp = PORT_NewArena (1024); /* XXX what is right value? */
+ poolp = PORT_NewArena(1024); /* XXX what is right value? */
if (poolp == NULL)
- return NULL;
+ return NULL;
- cinfo = (SEC_PKCS7ContentInfo*)PORT_ArenaZAlloc (poolp, sizeof(*cinfo));
+ cinfo = (SEC_PKCS7ContentInfo *)PORT_ArenaZAlloc(poolp, sizeof(*cinfo));
if (cinfo == NULL) {
- PORT_FreeArena (poolp, PR_FALSE);
- return NULL;
+ PORT_FreeArena(poolp, PR_FALSE);
+ return NULL;
}
cinfo->poolp = poolp;
@@ -129,16 +127,15 @@ sec_pkcs7_create_content_info (SECOidTag kind, PRBool detached,
cinfo->created = PR_TRUE;
cinfo->refCount = 1;
- rv = sec_pkcs7_init_content_info (cinfo, poolp, kind, detached);
+ rv = sec_pkcs7_init_content_info(cinfo, poolp, kind, detached);
if (rv != SECSuccess) {
- PORT_FreeArena (poolp, PR_FALSE);
- return NULL;
+ 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.
@@ -147,45 +144,41 @@ sec_pkcs7_create_content_info (SECOidTag kind, PRBool detached,
* 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_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);
+ 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? */
+ 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? */
}
/*
@@ -193,16 +186,15 @@ sec_pkcs7_add_signer (SEC_PKCS7ContentInfo *cinfo,
* a NULL database.
*/
if (certdb == NULL) {
- certdb = CERT_GetDefaultCertDB();
- if (certdb == NULL)
- return SECFailure; /* XXX set an error? */
+ 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;
+ if (CERT_VerifyCert(certdb, cert, PR_TRUE, certusage, PR_Now(),
+ cinfo->pwfn_arg, NULL) != SECSuccess) {
+ /* XXX Did CERT_VerifyCert set an error? */
+ return SECFailure;
}
/*
@@ -210,45 +202,44 @@ sec_pkcs7_add_signer (SEC_PKCS7ContentInfo *cinfo,
* 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);
+ PORT_Assert(*signerinfosp == NULL && *digestalgsp == NULL && *digestsp == NULL);
if (*signerinfosp != NULL || *digestalgsp != NULL || *digestsp != NULL)
- return SECFailure;
+ return SECFailure;
- mark = PORT_ArenaMark (cinfo->poolp);
+ mark = PORT_ArenaMark(cinfo->poolp);
- signerinfo = (SEC_PKCS7SignerInfo*)PORT_ArenaZAlloc (cinfo->poolp,
- sizeof(SEC_PKCS7SignerInfo));
+ signerinfo = (SEC_PKCS7SignerInfo *)PORT_ArenaZAlloc(cinfo->poolp,
+ sizeof(SEC_PKCS7SignerInfo));
if (signerinfo == NULL) {
- PORT_ArenaRelease (cinfo->poolp, mark);
- return SECFailure;
+ PORT_ArenaRelease(cinfo->poolp, mark);
+ return SECFailure;
}
- dummy = SEC_ASN1EncodeInteger (cinfo->poolp, &signerinfo->version,
- SEC_PKCS7_SIGNER_INFO_VERSION);
+ dummy = SEC_ASN1EncodeInteger(cinfo->poolp, &signerinfo->version,
+ SEC_PKCS7_SIGNER_INFO_VERSION);
if (dummy == NULL) {
- PORT_ArenaRelease (cinfo->poolp, mark);
- return SECFailure;
+ PORT_ArenaRelease(cinfo->poolp, mark);
+ return SECFailure;
}
- PORT_Assert (dummy == &signerinfo->version);
+ PORT_Assert(dummy == &signerinfo->version);
- signerinfo->cert = CERT_DupCertificate (cert);
+ signerinfo->cert = CERT_DupCertificate(cert);
if (signerinfo->cert == NULL) {
- PORT_ArenaRelease (cinfo->poolp, mark);
- return SECFailure;
+ PORT_ArenaRelease(cinfo->poolp, mark);
+ return SECFailure;
}
- signerinfo->issuerAndSN = CERT_GetCertIssuerAndSN (cinfo->poolp, cert);
+ signerinfo->issuerAndSN = CERT_GetCertIssuerAndSN(cinfo->poolp, cert);
if (signerinfo->issuerAndSN == NULL) {
- PORT_ArenaRelease (cinfo->poolp, mark);
- return SECFailure;
+ PORT_ArenaRelease(cinfo->poolp, mark);
+ return SECFailure;
}
- rv = SECOID_SetAlgorithmID (cinfo->poolp, &signerinfo->digestAlg,
- digestalgtag, NULL);
+ rv = SECOID_SetAlgorithmID(cinfo->poolp, &signerinfo->digestAlg,
+ digestalgtag, NULL);
if (rv != SECSuccess) {
- PORT_ArenaRelease (cinfo->poolp, mark);
- return SECFailure;
+ PORT_ArenaRelease(cinfo->poolp, mark);
+ return SECFailure;
}
/*
@@ -265,46 +256,46 @@ sec_pkcs7_add_signer (SEC_PKCS7ContentInfo *cinfo,
* should be *added* to the set already found.
*/
- signerinfos = (SEC_PKCS7SignerInfo**)PORT_ArenaAlloc (cinfo->poolp,
- 2 * sizeof(SEC_PKCS7SignerInfo *));
+ signerinfos = (SEC_PKCS7SignerInfo **)PORT_ArenaAlloc(cinfo->poolp,
+ 2 * sizeof(SEC_PKCS7SignerInfo *));
if (signerinfos == NULL) {
- PORT_ArenaRelease (cinfo->poolp, mark);
- return SECFailure;
+ 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 *));
+ 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;
+ PORT_ArenaRelease(cinfo->poolp, mark);
+ return SECFailure;
}
- rv = SECOID_SetAlgorithmID (cinfo->poolp, digestalg, digestalgtag, NULL);
+ rv = SECOID_SetAlgorithmID(cinfo->poolp, digestalg, digestalgtag, NULL);
if (rv != SECSuccess) {
- PORT_ArenaRelease (cinfo->poolp, mark);
- return SECFailure;
+ 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;
+ 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;
+ digests = NULL;
}
*signerinfosp = signerinfos;
@@ -315,40 +306,38 @@ sec_pkcs7_add_signer (SEC_PKCS7ContentInfo *cinfo,
return SECSuccess;
}
-
/*
* Helper function for creating an empty signedData.
*/
static SEC_PKCS7ContentInfo *
-sec_pkcs7_create_signed_data (SECKEYGetPasswordKey pwfn, void *pwfn_arg)
+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);
+ cinfo = sec_pkcs7_create_content_info(SEC_OID_PKCS7_SIGNED_DATA, PR_FALSE,
+ pwfn, pwfn_arg);
if (cinfo == NULL)
- return NULL;
+ return NULL;
sigd = cinfo->content.signedData;
- PORT_Assert (sigd != NULL);
+ 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);
+ rv = sec_pkcs7_init_content_info(&(sigd->contentInfo), cinfo->poolp,
+ SEC_OID_PKCS7_DATA, PR_TRUE);
if (rv != SECSuccess) {
- SEC_PKCS7DestroyContentInfo (cinfo);
- return NULL;
+ SEC_PKCS7DestroyContentInfo(cinfo);
+ return NULL;
}
return cinfo;
}
-
/*
* Start a PKCS7 signing context.
*
@@ -378,70 +367,69 @@ sec_pkcs7_create_signed_data (SECKEYGetPasswordKey pwfn, void *pwfn_arg)
* (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_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);
+ cinfo = sec_pkcs7_create_signed_data(pwfn, pwfn_arg);
if (cinfo == NULL)
- return NULL;
+ return NULL;
- rv = sec_pkcs7_add_signer (cinfo, cert, certusage, certdb,
- digestalg, digest);
+ rv = sec_pkcs7_add_signer(cinfo, cert, certusage, certdb,
+ digestalg, digest);
if (rv != SECSuccess) {
- SEC_PKCS7DestroyContentInfo (cinfo);
- return NULL;
+ SEC_PKCS7DestroyContentInfo(cinfo);
+ return NULL;
}
return cinfo;
}
-
static SEC_PKCS7Attribute *
-sec_pkcs7_create_attribute (PLArenaPool *poolp, SECOidTag oidtag,
- SECItem *value, PRBool encoded)
+sec_pkcs7_create_attribute(PLArenaPool *poolp, SECOidTag oidtag,
+ SECItem *value, PRBool encoded)
{
SEC_PKCS7Attribute *attr;
SECItem **values;
void *mark;
- PORT_Assert (poolp != NULL);
- mark = PORT_ArenaMark (poolp);
+ PORT_Assert(poolp != NULL);
+ mark = PORT_ArenaMark(poolp);
- attr = (SEC_PKCS7Attribute*)PORT_ArenaAlloc (poolp,
- sizeof(SEC_PKCS7Attribute));
+ attr = (SEC_PKCS7Attribute *)PORT_ArenaAlloc(poolp,
+ sizeof(SEC_PKCS7Attribute));
if (attr == NULL)
- goto loser;
+ goto loser;
- attr->typeTag = SECOID_FindOIDByTag (oidtag);
+ attr->typeTag = SECOID_FindOIDByTag(oidtag);
if (attr->typeTag == NULL)
- goto loser;
+ goto loser;
- if (SECITEM_CopyItem (poolp, &(attr->type),
- &(attr->typeTag->oid)) != SECSuccess)
- goto loser;
+ if (SECITEM_CopyItem(poolp, &(attr->type),
+ &(attr->typeTag->oid)) != SECSuccess)
+ goto loser;
- values = (SECItem**)PORT_ArenaAlloc (poolp, 2 * sizeof(SECItem *));
+ values = (SECItem **)PORT_ArenaAlloc(poolp, 2 * sizeof(SECItem *));
if (values == NULL)
- goto loser;
+ goto loser;
if (value != NULL) {
- SECItem *copy;
+ SECItem *copy;
- copy = (SECItem*)PORT_ArenaAlloc (poolp, sizeof(SECItem));
- if (copy == NULL)
- goto loser;
+ copy = (SECItem *)PORT_ArenaAlloc(poolp, sizeof(SECItem));
+ if (copy == NULL)
+ goto loser;
- if (SECITEM_CopyItem (poolp, copy, value) != SECSuccess)
- goto loser;
+ if (SECITEM_CopyItem(poolp, copy, value) != SECSuccess)
+ goto loser;
- value = copy;
+ value = copy;
}
values[0] = value;
@@ -449,62 +437,61 @@ sec_pkcs7_create_attribute (PLArenaPool *poolp, SECOidTag oidtag,
attr->values = values;
attr->encoded = encoded;
- PORT_ArenaUnmark (poolp, mark);
+ PORT_ArenaUnmark(poolp, mark);
return attr;
loser:
- PORT_Assert (mark != NULL);
- PORT_ArenaRelease (poolp, mark);
+ 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_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;
+ 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;
+ 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;
+ 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;
}
/*
@@ -517,43 +504,42 @@ sec_pkcs7_add_attribute (SEC_PKCS7ContentInfo *cinfo,
* 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 *));
+ attrs = (SEC_PKCS7Attribute **)PORT_ArenaAlloc(cinfo->poolp,
+ 4 * sizeof(SEC_PKCS7Attribute *));
if (attrs == NULL)
- return SECFailure;
+ return SECFailure;
- mark = PORT_ArenaMark (cinfo->poolp);
+ 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);
+ 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);
+ 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;
+ PORT_ArenaRelease(cinfo->poolp, mark);
+ return SECFailure;
}
attrs[2] = attr;
attrs[3] = NULL;
*attrsp = attrs;
- PORT_ArenaUnmark (cinfo->poolp, mark);
+ 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
@@ -571,7 +557,7 @@ sec_pkcs7_add_attribute (SEC_PKCS7ContentInfo *cinfo,
* if it is not.
*/
SECStatus
-SEC_PKCS7AddSigningTime (SEC_PKCS7ContentInfo *cinfo)
+SEC_PKCS7AddSigningTime(SEC_PKCS7ContentInfo *cinfo)
{
SEC_PKCS7SignerInfo **signerinfos;
SEC_PKCS7Attribute *attr;
@@ -579,48 +565,47 @@ SEC_PKCS7AddSigningTime (SEC_PKCS7ContentInfo *cinfo)
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;
+ 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;
+ return SECFailure;
rv = DER_EncodeTimeChoice(NULL, &stime, PR_Now());
if (rv != SECSuccess)
- return rv;
+ return rv;
- attr = sec_pkcs7_create_attribute (cinfo->poolp,
- SEC_OID_PKCS9_SIGNING_TIME,
- &stime, PR_FALSE);
- SECITEM_FreeItem (&stime, PR_FALSE);
+ 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;
+ 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 */
+ 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
@@ -640,16 +625,16 @@ SEC_PKCS7AddSigningTime (SEC_PKCS7ContentInfo *cinfo)
* if it is not.
*/
SECStatus
-SEC_PKCS7AddSignedAttribute (SEC_PKCS7ContentInfo *cinfo,
- SECOidTag oidtag,
- SECItem *value)
+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;
+ 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;
@@ -657,15 +642,14 @@ SEC_PKCS7AddSignedAttribute (SEC_PKCS7ContentInfo *cinfo,
* No signature or more than one means no deal.
*/
if (signerinfos == NULL || signerinfos[0] == NULL || signerinfos[1] != NULL)
- return SECFailure;
+ return SECFailure;
- attr = sec_pkcs7_create_attribute (cinfo->poolp, oidtag, value, PR_TRUE);
+ attr = sec_pkcs7_create_attribute(cinfo->poolp, oidtag, value, PR_TRUE);
if (attr == NULL)
- return SECFailure;
+ return SECFailure;
- return sec_pkcs7_add_attribute (cinfo, &(signerinfos[0]->authAttr), attr);
+ return sec_pkcs7_add_attribute(cinfo, &(signerinfos[0]->authAttr), attr);
}
-
/*
* Mark that the signer certificates and their issuing chain should
@@ -679,115 +663,110 @@ SEC_PKCS7AddSignedAttribute (SEC_PKCS7ContentInfo *cinfo,
* SECFailure will be returned if it is not.
*/
SECStatus
-SEC_PKCS7IncludeCertChain (SEC_PKCS7ContentInfo *cinfo,
- CERTCertDBHandle *certdb)
+SEC_PKCS7IncludeCertChain(SEC_PKCS7ContentInfo *cinfo,
+ CERTCertDBHandle *certdb)
{
SECOidTag kind;
SEC_PKCS7SignerInfo *signerinfo, **signerinfos;
- kind = SEC_PKCS7ContentType (cinfo);
+ 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? */
+ 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 (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;
- }
+ 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
+ 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);
+ 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)
+sec_pkcs7_add_cert_chain(SEC_PKCS7ContentInfo *cinfo,
+ CERTCertificate *cert,
+ CERTCertDBHandle *certdb)
{
SECOidTag kind;
CERTCertificateList *certlist, **certlists, ***certlistsp;
int count;
- kind = SEC_PKCS7ContentType (cinfo);
+ 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? */
+ 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;
- }
+ certdb = CERT_GetDefaultCertDB();
+ if (certdb == NULL) {
+ PORT_SetError(SEC_ERROR_BAD_DATABASE);
+ return SECFailure;
+ }
}
- certlist = CERT_CertChainFromCert (cert, certUsageEmailSigner, PR_FALSE);
+ certlist = CERT_CertChainFromCert(cert, certUsageEmailSigner, PR_FALSE);
if (certlist == NULL)
- return SECFailure;
+ return SECFailure;
certlists = *certlistsp;
if (certlists == NULL) {
- count = 0;
- certlists = (CERTCertificateList**)PORT_ArenaAlloc (cinfo->poolp,
- 2 * sizeof(CERTCertificateList *));
+ 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 *));
+ 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;
+ CERT_DestroyCertificateList(certlist);
+ return SECFailure;
}
certlists[count] = certlist;
@@ -798,62 +777,57 @@ sec_pkcs7_add_cert_chain (SEC_PKCS7ContentInfo *cinfo,
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)
+sec_pkcs7_add_certificate(SEC_PKCS7ContentInfo *cinfo,
+ CERTCertificate *cert)
{
SECOidTag kind;
CERTCertificate **certs, ***certsp;
int count;
- kind = SEC_PKCS7ContentType (cinfo);
+ 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? */
+ 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);
+ cert = CERT_DupCertificate(cert);
if (cert == NULL)
- return SECFailure;
+ return SECFailure;
certs = *certsp;
if (certs == NULL) {
- count = 0;
- certs = (CERTCertificate**)PORT_ArenaAlloc (cinfo->poolp,
- 2 * sizeof(CERTCertificate *));
+ 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 *));
+ 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;
+ CERT_DestroyCertificate(cert);
+ return SECFailure;
}
certs[count] = cert;
@@ -864,7 +838,6 @@ sec_pkcs7_add_certificate (SEC_PKCS7ContentInfo *cinfo,
return SECSuccess;
}
-
/*
* Create a PKCS7 certs-only container.
*
@@ -883,31 +856,30 @@ sec_pkcs7_add_certificate (SEC_PKCS7ContentInfo *cinfo,
* (Retrieve specific errors via PORT_GetError()/XP_GetError().)
*/
SEC_PKCS7ContentInfo *
-SEC_PKCS7CreateCertsOnly (CERTCertificate *cert,
- PRBool include_chain,
- CERTCertDBHandle *certdb)
+SEC_PKCS7CreateCertsOnly(CERTCertificate *cert,
+ PRBool include_chain,
+ CERTCertDBHandle *certdb)
{
SEC_PKCS7ContentInfo *cinfo;
SECStatus rv;
- cinfo = sec_pkcs7_create_signed_data (NULL, NULL);
+ cinfo = sec_pkcs7_create_signed_data(NULL, NULL);
if (cinfo == NULL)
- return NULL;
+ return NULL;
if (include_chain)
- rv = sec_pkcs7_add_cert_chain (cinfo, cert, certdb);
+ rv = sec_pkcs7_add_cert_chain(cinfo, cert, certdb);
else
- rv = sec_pkcs7_add_certificate (cinfo, cert);
+ rv = sec_pkcs7_add_certificate(cinfo, cert);
if (rv != SECSuccess) {
- SEC_PKCS7DestroyContentInfo (cinfo);
- return NULL;
+ SEC_PKCS7DestroyContentInfo(cinfo);
+ return NULL;
}
return cinfo;
}
-
/*
* Add "cert" and its entire chain to the set of certs included in "cinfo".
*
@@ -918,21 +890,19 @@ SEC_PKCS7CreateCertsOnly (CERTCertificate *cert,
* SECFailure will be returned if it is not.
*/
SECStatus
-SEC_PKCS7AddCertChain (SEC_PKCS7ContentInfo *cinfo,
- CERTCertificate *cert,
- CERTCertDBHandle *certdb)
+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? */
+ 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);
+ return sec_pkcs7_add_cert_chain(cinfo, cert, certdb);
}
-
/*
* Add "cert" to the set of certs included in "cinfo".
*
@@ -940,30 +910,28 @@ SEC_PKCS7AddCertChain (SEC_PKCS7ContentInfo *cinfo,
* SECFailure will be returned if it is not.
*/
SECStatus
-SEC_PKCS7AddCertificate (SEC_PKCS7ContentInfo *cinfo, CERTCertificate *cert)
+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? */
+ 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);
+ return sec_pkcs7_add_certificate(cinfo, cert);
}
-
static SECStatus
-sec_pkcs7_init_encrypted_content_info (SEC_PKCS7EncryptedContentInfo *enccinfo,
- PLArenaPool *poolp,
- SECOidTag kind, PRBool detached,
- SECOidTag encalg, int keysize)
+sec_pkcs7_init_encrypted_content_info(SEC_PKCS7EncryptedContentInfo *enccinfo,
+ PLArenaPool *poolp,
+ SECOidTag kind, PRBool detached,
+ SECOidTag encalg, int keysize)
{
SECStatus rv;
- PORT_Assert (enccinfo != NULL && poolp != NULL);
+ PORT_Assert(enccinfo != NULL && poolp != NULL);
if (enccinfo == NULL || poolp == NULL)
- return SECFailure;
+ return SECFailure;
/*
* XXX Some day we may want to allow for other kinds. That needs
@@ -972,16 +940,15 @@ sec_pkcs7_init_encrypted_content_info (SEC_PKCS7EncryptedContentInfo *enccinfo,
* They are responsible for creating the inner type and encoding,
* if it is other than DATA.
*/
- PORT_Assert (kind == SEC_OID_PKCS7_DATA);
+ PORT_Assert(kind == SEC_OID_PKCS7_DATA);
- enccinfo->contentTypeTag = SECOID_FindOIDByTag (kind);
- PORT_Assert (enccinfo->contentTypeTag
- && enccinfo->contentTypeTag->offset == kind);
+ enccinfo->contentTypeTag = SECOID_FindOIDByTag(kind);
+ PORT_Assert(enccinfo->contentTypeTag && enccinfo->contentTypeTag->offset == kind);
- rv = SECITEM_CopyItem (poolp, &(enccinfo->contentType),
- &(enccinfo->contentTypeTag->oid));
+ rv = SECITEM_CopyItem(poolp, &(enccinfo->contentType),
+ &(enccinfo->contentTypeTag->oid));
if (rv != SECSuccess)
- return rv;
+ return rv;
/* Save keysize and algorithm for later. */
enccinfo->keysize = keysize;
@@ -990,16 +957,15 @@ sec_pkcs7_init_encrypted_content_info (SEC_PKCS7EncryptedContentInfo *enccinfo,
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)
+sec_pkcs7_add_recipient(SEC_PKCS7ContentInfo *cinfo,
+ CERTCertificate *cert,
+ SECCertUsage certusage,
+ CERTCertDBHandle *certdb)
{
SECOidTag kind;
SEC_PKCS7RecipientInfo *recipientinfo, **recipientinfos, ***recipientinfosp;
@@ -1007,26 +973,22 @@ sec_pkcs7_add_recipient (SEC_PKCS7ContentInfo *cinfo,
void *mark;
int count;
- kind = SEC_PKCS7ContentType (cinfo);
+ 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? */
+ 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? */
}
/*
@@ -1034,45 +996,44 @@ sec_pkcs7_add_recipient (SEC_PKCS7ContentInfo *cinfo,
* a NULL database.
*/
if (certdb == NULL) {
- certdb = CERT_GetDefaultCertDB();
- if (certdb == NULL)
- return SECFailure; /* XXX set an error? */
+ 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;
+ 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);
+ mark = PORT_ArenaMark(cinfo->poolp);
- recipientinfo = (SEC_PKCS7RecipientInfo*)PORT_ArenaZAlloc (cinfo->poolp,
- sizeof(SEC_PKCS7RecipientInfo));
+ recipientinfo = (SEC_PKCS7RecipientInfo *)PORT_ArenaZAlloc(cinfo->poolp,
+ sizeof(SEC_PKCS7RecipientInfo));
if (recipientinfo == NULL) {
- PORT_ArenaRelease (cinfo->poolp, mark);
- return SECFailure;
+ PORT_ArenaRelease(cinfo->poolp, mark);
+ return SECFailure;
}
- dummy = SEC_ASN1EncodeInteger (cinfo->poolp, &recipientinfo->version,
- SEC_PKCS7_RECIPIENT_INFO_VERSION);
+ dummy = SEC_ASN1EncodeInteger(cinfo->poolp, &recipientinfo->version,
+ SEC_PKCS7_RECIPIENT_INFO_VERSION);
if (dummy == NULL) {
- PORT_ArenaRelease (cinfo->poolp, mark);
- return SECFailure;
+ PORT_ArenaRelease(cinfo->poolp, mark);
+ return SECFailure;
}
- PORT_Assert (dummy == &recipientinfo->version);
+ PORT_Assert(dummy == &recipientinfo->version);
- recipientinfo->cert = CERT_DupCertificate (cert);
+ recipientinfo->cert = CERT_DupCertificate(cert);
if (recipientinfo->cert == NULL) {
- PORT_ArenaRelease (cinfo->poolp, mark);
- return SECFailure;
+ PORT_ArenaRelease(cinfo->poolp, mark);
+ return SECFailure;
}
- recipientinfo->issuerAndSN = CERT_GetCertIssuerAndSN (cinfo->poolp, cert);
+ recipientinfo->issuerAndSN = CERT_GetCertIssuerAndSN(cinfo->poolp, cert);
if (recipientinfo->issuerAndSN == NULL) {
- PORT_ArenaRelease (cinfo->poolp, mark);
- return SECFailure;
+ PORT_ArenaRelease(cinfo->poolp, mark);
+ return SECFailure;
}
/*
@@ -1084,23 +1045,23 @@ sec_pkcs7_add_recipient (SEC_PKCS7ContentInfo *cinfo,
*/
recipientinfos = *recipientinfosp;
if (recipientinfos == NULL) {
- count = 0;
- recipientinfos = (SEC_PKCS7RecipientInfo **)PORT_ArenaAlloc (
- cinfo->poolp,
- 2 * sizeof(SEC_PKCS7RecipientInfo *));
+ 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 *));
+ 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;
+ PORT_ArenaRelease(cinfo->poolp, mark);
+ return SECFailure;
}
recipientinfos[count] = recipientinfo;
@@ -1108,11 +1069,10 @@ sec_pkcs7_add_recipient (SEC_PKCS7ContentInfo *cinfo,
*recipientinfosp = recipientinfos;
- PORT_ArenaUnmark (cinfo->poolp, mark);
+ PORT_ArenaUnmark(cinfo->poolp, mark);
return SECSuccess;
}
-
/*
* Start a PKCS7 enveloping context.
*
@@ -1140,42 +1100,42 @@ sec_pkcs7_add_recipient (SEC_PKCS7ContentInfo *cinfo,
* (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_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);
+ cinfo = sec_pkcs7_create_content_info(SEC_OID_PKCS7_ENVELOPED_DATA,
+ PR_FALSE, pwfn, pwfn_arg);
if (cinfo == NULL)
- return NULL;
+ return NULL;
- rv = sec_pkcs7_add_recipient (cinfo, cert, certusage, certdb);
+ rv = sec_pkcs7_add_recipient(cinfo, cert, certusage, certdb);
if (rv != SECSuccess) {
- SEC_PKCS7DestroyContentInfo (cinfo);
- return NULL;
+ SEC_PKCS7DestroyContentInfo(cinfo);
+ return NULL;
}
envd = cinfo->content.envelopedData;
- PORT_Assert (envd != NULL);
+ 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);
+ 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;
+ SEC_PKCS7DestroyContentInfo(cinfo);
+ return NULL;
}
/* XXX Anything more to do here? */
@@ -1183,7 +1143,6 @@ SEC_PKCS7CreateEnvelopedData (CERTCertificate *cert,
return cinfo;
}
-
/*
* Add another recipient to an encrypted message.
*
@@ -1202,15 +1161,14 @@ SEC_PKCS7CreateEnvelopedData (CERTCertificate *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)
+SEC_PKCS7AddRecipient(SEC_PKCS7ContentInfo *cinfo,
+ CERTCertificate *cert,
+ SECCertUsage certusage,
+ CERTCertDBHandle *certdb)
{
- return sec_pkcs7_add_recipient (cinfo, cert, certusage, certdb);
+ return sec_pkcs7_add_recipient(cinfo, cert, certusage, certdb);
}
-
/*
* Create an empty PKCS7 data content info.
*
@@ -1218,13 +1176,12 @@ SEC_PKCS7AddRecipient (SEC_PKCS7ContentInfo *cinfo,
* (Retrieve specific errors via PORT_GetError()/XP_GetError().)
*/
SEC_PKCS7ContentInfo *
-SEC_PKCS7CreateData (void)
+SEC_PKCS7CreateData(void)
{
- return sec_pkcs7_create_content_info (SEC_OID_PKCS7_DATA, PR_FALSE,
- NULL, NULL);
+ return sec_pkcs7_create_content_info(SEC_OID_PKCS7_DATA, PR_FALSE,
+ NULL, NULL);
}
-
/*
* Create an empty PKCS7 encrypted content info.
*
@@ -1234,24 +1191,24 @@ SEC_PKCS7CreateData (void)
* (Retrieve specific errors via PORT_GetError()/XP_GetError().)
*/
SEC_PKCS7ContentInfo *
-SEC_PKCS7CreateEncryptedData (SECOidTag algorithm, int keysize,
- SECKEYGetPasswordKey pwfn, void *pwfn_arg)
+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);
+ cinfo = sec_pkcs7_create_content_info(SEC_OID_PKCS7_ENCRYPTED_DATA,
+ PR_FALSE, pwfn, pwfn_arg);
if (cinfo == NULL)
- return 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);
+ rv = SECOID_SetAlgorithmID(cinfo->poolp, algid, algorithm, NULL);
} else {
/* Assume password-based-encryption.
* Note: we can't generate pkcs5v2 from this interface.
@@ -1260,32 +1217,31 @@ SEC_PKCS7CreateEncryptedData (SECOidTag algorithm, int keysize,
* 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,
+ 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 (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;
+ 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);
+ 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;
+ SEC_PKCS7DestroyContentInfo(cinfo);
+ return NULL;
}
return cinfo;
}
-
diff --git a/nss/lib/pkcs7/p7decode.c b/nss/lib/pkcs7/p7decode.c
index 7a52d82..658c61e 100644
--- a/nss/lib/pkcs7/p7decode.c
+++ b/nss/lib/pkcs7/p7decode.c
@@ -9,11 +9,11 @@
#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! */
+/* 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"
@@ -23,7 +23,7 @@
#include "pk11func.h"
#include "prtime.h"
#include "secerr.h"
-#include "sechash.h" /* for HASH_GetHashObject() */
+#include "sechash.h" /* for HASH_GetHashObject() */
#include "secder.h"
#include "secpkcs5.h"
@@ -60,10 +60,10 @@ struct SEC_PKCS7DecoderContextStr {
* 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)
+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;
@@ -76,7 +76,7 @@ sec_pkcs7_decoder_work_data (SEC_PKCS7DecoderContext *p7dcx,
* 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);
+ PORT_Assert((data != NULL && len) || final);
/*
* Decrypt this chunk.
@@ -87,100 +87,99 @@ sec_pkcs7_decoder_work_data (SEC_PKCS7DecoderContext *p7dcx,
* 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;
+ /* 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);
- }
+ 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);
- }
+ 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_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;
@@ -193,17 +192,17 @@ sec_pkcs7_decoder_filter (void *arg, const char *data, unsigned long len,
* smarter based on depth and data_kind.
*/
if (data_kind != SEC_ASN1_Contents)
- return;
+ return;
/*
* The ASN.1 decoder should not even call us with a length of 0.
* Just being paranoid.
*/
- PORT_Assert (len);
+ PORT_Assert(len);
if (len == 0)
- return;
+ return;
- p7dcx = (SEC_PKCS7DecoderContext*)arg;
+ p7dcx = (SEC_PKCS7DecoderContext *)arg;
/*
* Handling nested contents would mean that there is a chain
@@ -214,11 +213,10 @@ sec_pkcs7_decoder_filter (void *arg, const char *data, unsigned long len,
worker->saw_contents = PR_TRUE;
- sec_pkcs7_decoder_work_data (p7dcx, worker,
- (const unsigned char *) data, len, PR_FALSE);
+ 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.
@@ -227,35 +225,35 @@ sec_pkcs7_decoder_filter (void *arg, const char *data, unsigned long len,
* should just give up altogether.
*/
static SECStatus
-sec_pkcs7_decoder_start_digests (SEC_PKCS7DecoderContext *p7dcx, int depth,
- SECAlgorithmID **digestalgs)
+sec_pkcs7_decoder_start_digests(SEC_PKCS7DecoderContext *p7dcx, int depth,
+ SECAlgorithmID **digestalgs)
{
int i, digcnt;
if (digestalgs == NULL)
- return SECSuccess;
+ return SECSuccess;
/*
* Count the algorithms.
*/
digcnt = 0;
while (digestalgs[digcnt] != NULL)
- digcnt++;
+ digcnt++;
/*
* No algorithms means no work to do.
* Just act as if there were no algorithms specified.
*/
if (digcnt == 0)
- return SECSuccess;
+ 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 *));
+ 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->error = SEC_ERROR_NO_MEMORY;
+ return SECFailure;
}
p7dcx->worker.depth = depth;
@@ -265,49 +263,48 @@ sec_pkcs7_decoder_start_digests (SEC_PKCS7DecoderContext *p7dcx, int depth,
* 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++;
- }
+ 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));
+ 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,
- PLArenaPool *poolp,
- SECItem ***digestsp)
+sec_pkcs7_decoder_finish_digests(SEC_PKCS7DecoderContext *p7dcx,
+ PLArenaPool *poolp,
+ SECItem ***digestsp)
{
struct sec_pkcs7_decoder_worker *worker;
const SECHashObject *digobj;
@@ -327,14 +324,14 @@ sec_pkcs7_decoder_finish_digests (SEC_PKCS7DecoderContext *p7dcx,
* If no digests, then we have nothing to do.
*/
if (worker->digcnt == 0)
- return SECSuccess;
+ 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);
+ SEC_ASN1DecoderClearFilterProc(p7dcx->dcx);
/*
* If we ended up with no contents, just destroy each
@@ -342,50 +339,50 @@ sec_pkcs7_decoder_finish_digests (SEC_PKCS7DecoderContext *p7dcx,
* 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;
+ 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);
+ 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));
+ 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;
+ 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];
+ 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->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);
+ digest->len = digobj->length;
+ (*digobj->end)(digcx, digest->data, &(digest->len), digest->len);
+ (*digobj->destroy)(digcx, PR_TRUE);
- digests[i] = digest;
+ digests[i] = digest;
}
digests[i] = NULL;
*digestsp = digests;
- PORT_ArenaUnmark (poolp, mark);
+ PORT_ArenaUnmark(poolp, mark);
return SECSuccess;
}
@@ -395,9 +392,9 @@ sec_pkcs7_decoder_finish_digests (SEC_PKCS7DecoderContext *p7dcx,
*/
static PK11SymKey *
-sec_pkcs7_decoder_get_recipient_key (SEC_PKCS7DecoderContext *p7dcx,
- SEC_PKCS7RecipientInfo **recipientinfos,
- SEC_PKCS7EncryptedContentInfo *enccinfo)
+sec_pkcs7_decoder_get_recipient_key(SEC_PKCS7DecoderContext *p7dcx,
+ SEC_PKCS7RecipientInfo **recipientinfos,
+ SEC_PKCS7EncryptedContentInfo *enccinfo)
{
SEC_PKCS7RecipientInfo *ri;
CERTCertificate *cert = NULL;
@@ -407,53 +404,53 @@ sec_pkcs7_decoder_get_recipient_key (SEC_PKCS7DecoderContext *p7dcx,
PK11SlotInfo *slot = NULL;
if (recipientinfos == NULL || recipientinfos[0] == NULL) {
- p7dcx->error = SEC_ERROR_NOT_A_RECIPIENT;
- goto no_key_found;
+ p7dcx->error = SEC_ERROR_NOT_A_RECIPIENT;
+ goto no_key_found;
}
- cert = PK11_FindCertAndKeyByRecipientList(&slot,recipientinfos,&ri,
- &privkey, p7dcx->pwfn_arg);
+ cert = PK11_FindCertAndKeyByRecipientList(&slot, recipientinfos, &ri,
+ &privkey, p7dcx->pwfn_arg);
if (cert == NULL) {
- p7dcx->error = SEC_ERROR_NOT_A_RECIPIENT;
- goto no_key_found;
+ p7dcx->error = SEC_ERROR_NOT_A_RECIPIENT;
+ goto no_key_found;
}
- ri->cert = cert; /* so we can find it later */
+ ri->cert = cert; /* so we can find it later */
PORT_Assert(privkey != NULL);
keyalgtag = SECOID_GetAlgorithmTag(&(cert->subjectPublicKeyInfo.algorithm));
- encalgtag = SECOID_GetAlgorithmTag (&(ri->keyEncAlg));
+ encalgtag = SECOID_GetAlgorithmTag(&(ri->keyEncAlg));
if (keyalgtag != encalgtag) {
- p7dcx->error = SEC_ERROR_PKCS7_KEYALG_MISMATCH;
- goto no_key_found;
+ p7dcx->error = SEC_ERROR_PKCS7_KEYALG_MISMATCH;
+ goto no_key_found;
}
- bulkalgtag = SECOID_GetAlgorithmTag (&(enccinfo->contentEncAlg));
+ 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;
+ 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);
+ SECKEY_DestroyPrivateKey(privkey);
if (slot != NULL)
- PK11_FreeSlot(slot);
+ PK11_FreeSlot(slot);
return bulkkey;
}
-
+
/*
* XXX The following comment is old -- the function used to only handle
* EnvelopedData or SignedAndEnvelopedData but now handles EncryptedData
@@ -469,16 +466,16 @@ no_key_found:
* 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)
+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,
+ * 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
@@ -487,41 +484,41 @@ sec_pkcs7_decoder_start_decrypt (SEC_PKCS7DecoderContext *p7dcx, int depth,
* 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;
+ 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));
-
+ 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;
+ 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;
- }
+ 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;
+ p7dcx->error = SEC_ERROR_DECRYPTION_DISALLOWED;
+ goto no_decryption;
}
/*
@@ -531,31 +528,31 @@ sec_pkcs7_decoder_start_decrypt (SEC_PKCS7DecoderContext *p7dcx, int depth,
* RSA operation), copy it for later signature verification to use.
*/
if (copy_key_for_signature != NULL)
- *copy_key_for_signature = PK11_ReferenceSymKey (bulkkey);
+ *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));
+ decryptobj = sec_PKCS7CreateDecryptObject(bulkkey,
+ &(enccinfo->contentEncAlg));
/*
* We are done with (this) bulkkey now.
*/
- PK11_FreeSymKey (bulkkey);
+ PK11_FreeSymKey(bulkkey);
if (decryptobj == NULL) {
- p7dcx->error = PORT_GetError();
- PORT_SetError(0);
- goto no_decryption;
+ p7dcx->error = PORT_GetError();
+ PORT_SetError(0);
+ goto no_decryption;
}
- SEC_ASN1DecoderSetFilterProc (p7dcx->dcx,
- sec_pkcs7_decoder_filter,
- p7dcx,
- (PRBool)(p7dcx->cb != NULL));
+ SEC_ASN1DecoderSetFilterProc(p7dcx->dcx,
+ sec_pkcs7_decoder_filter,
+ p7dcx,
+ (PRBool)(p7dcx->cb != NULL));
p7dcx->worker.depth = depth;
p7dcx->worker.decryptobj = decryptobj;
@@ -575,16 +572,15 @@ no_decryption:
* maybe it is not important that the decryption failed.
*/
if (p7dcx->cb != NULL)
- return SECFailure;
+ return SECFailure;
else
- return SECSuccess; /* Let the decoding continue. */
+ return SECSuccess; /* Let the decoding continue. */
}
-
static SECStatus
-sec_pkcs7_decoder_finish_decrypt (SEC_PKCS7DecoderContext *p7dcx,
- PLArenaPool *poolp,
- SEC_PKCS7EncryptedContentInfo *enccinfo)
+sec_pkcs7_decoder_finish_decrypt(SEC_PKCS7DecoderContext *p7dcx,
+ PLArenaPool *poolp,
+ SEC_PKCS7EncryptedContentInfo *enccinfo)
{
struct sec_pkcs7_decoder_worker *worker;
@@ -599,32 +595,31 @@ sec_pkcs7_decoder_finish_decrypt (SEC_PKCS7DecoderContext *p7dcx,
* If no decryption context, then we have nothing to do.
*/
if (worker->decryptobj == NULL)
- return SECSuccess;
+ 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);
+ SEC_ASN1DecoderClearFilterProc(p7dcx->dcx);
/*
* Handle the last block.
*/
- sec_pkcs7_decoder_work_data (p7dcx, worker, NULL, 0, PR_TRUE);
+ sec_pkcs7_decoder_work_data(p7dcx, worker, NULL, 0, PR_TRUE);
/*
* All done, destroy it.
*/
- sec_PKCS7DestroyDecryptObject (worker->decryptobj);
+ sec_PKCS7DestroyDecryptObject(worker->decryptobj);
worker->decryptobj = NULL;
return SECSuccess;
}
-
static void
-sec_pkcs7_decoder_notify (void *arg, PRBool before, void *dest, int depth)
+sec_pkcs7_decoder_notify(void *arg, PRBool before, void *dest, int depth)
{
SEC_PKCS7DecoderContext *p7dcx;
SEC_PKCS7ContentInfo *cinfo;
@@ -643,331 +638,342 @@ sec_pkcs7_decoder_notify (void *arg, PRBool before, void *dest, int depth)
* causes a warning on the mac; to avoid that, we do it the long way.)
*/
if (before)
- after = PR_FALSE;
+ after = PR_FALSE;
else
- after = PR_TRUE;
+ after = PR_TRUE;
+
+ p7dcx = (SEC_PKCS7DecoderContext *)arg;
+ if (!p7dcx) {
+ return;
+ }
- p7dcx = (SEC_PKCS7DecoderContext*)arg;
cinfo = p7dcx->cinfo;
+ if (!cinfo) {
+ return;
+ }
+
if (cinfo->contentTypeTag == NULL) {
- if (after && dest == &(cinfo->contentType))
- cinfo->contentTypeTag = SECOID_FindOID(&(cinfo->contentType));
- return;
+ 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;
+ 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;
+
+ if (!encd) {
+ break;
+ }
+
+ /*
+ * 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)
+ 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;
PLArenaPool *poolp;
- poolp = PORT_NewArena (1024); /* XXX what is right value? */
+ poolp = PORT_NewArena(1024); /* XXX what is right value? */
if (poolp == NULL)
- return NULL;
+ return NULL;
- cinfo = (SEC_PKCS7ContentInfo*)PORT_ArenaZAlloc (poolp, sizeof(*cinfo));
+ cinfo = (SEC_PKCS7ContentInfo *)PORT_ArenaZAlloc(poolp, sizeof(*cinfo));
if (cinfo == NULL) {
- PORT_FreeArena (poolp, PR_FALSE);
- return NULL;
+ PORT_FreeArena(poolp, PR_FALSE);
+ return NULL;
}
cinfo->poolp = poolp;
@@ -976,29 +982,29 @@ SEC_PKCS7DecoderStart(SEC_PKCS7DecoderContentCallback cb, void *cb_arg,
cinfo->created = PR_FALSE;
cinfo->refCount = 1;
- p7dcx =
- (SEC_PKCS7DecoderContext*)PORT_ZAlloc (sizeof(SEC_PKCS7DecoderContext));
+ p7dcx =
+ (SEC_PKCS7DecoderContext *)PORT_ZAlloc(sizeof(SEC_PKCS7DecoderContext));
if (p7dcx == NULL) {
- PORT_FreeArena (poolp, PR_FALSE);
- return NULL;
+ PORT_FreeArena(poolp, PR_FALSE);
+ return NULL;
}
- p7dcx->tmp_poolp = PORT_NewArena (1024); /* XXX what is right value? */
+ 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;
+ PORT_Free(p7dcx);
+ PORT_FreeArena(poolp, PR_FALSE);
+ return NULL;
}
- dcx = SEC_ASN1DecoderStart (poolp, cinfo, sec_PKCS7ContentInfoTemplate);
+ 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;
+ 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);
+ SEC_ASN1DecoderSetNotifyProc(dcx, sec_pkcs7_decoder_notify, p7dcx);
p7dcx->dcx = dcx;
p7dcx->cinfo = cinfo;
@@ -1013,7 +1019,6 @@ SEC_PKCS7DecoderStart(SEC_PKCS7DecoderContentCallback cb, void *cb_arg,
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
@@ -1024,37 +1029,36 @@ SEC_PKCS7DecoderStart(SEC_PKCS7DecoderContentCallback cb, void *cb_arg,
*/
SECStatus
SEC_PKCS7DecoderUpdate(SEC_PKCS7DecoderContext *p7dcx,
- const char *buf, unsigned long len)
+ 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->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;
+ 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)
{
@@ -1062,38 +1066,37 @@ SEC_PKCS7DecoderFinish(SEC_PKCS7DecoderContext *p7dcx)
cinfo = p7dcx->cinfo;
if (p7dcx->dcx != NULL) {
- if (SEC_ASN1DecoderFinish (p7dcx->dcx) != SECSuccess) {
- SEC_PKCS7DestroyContentInfo (cinfo);
- cinfo = 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);
+ sec_PKCS7DestroyDecryptObject(p7dcx->worker.decryptobj);
}
- PORT_FreeArena (p7dcx->tmp_poolp, PR_FALSE);
- PORT_Free (p7dcx);
+ 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_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);
+ decrypt_key_cb_arg, decrypt_allowed_cb);
if (!p7dcx) {
/* error code is set */
return NULL;
}
- (void) SEC_PKCS7DecoderUpdate(p7dcx, (char *) p7item->data, p7item->len);
+ (void)SEC_PKCS7DecoderUpdate(p7dcx, (char *)p7item->data, p7item->len);
return SEC_PKCS7DecoderFinish(p7dcx);
}
@@ -1107,7 +1110,6 @@ SEC_PKCS7DecoderAbort(SEC_PKCS7DecoderContext *p7dcx, int error)
SEC_ASN1DecoderAbort(p7dcx->dcx, error);
}
-
/*
* If the thing contains any certs or crls return true; false otherwise.
*/
@@ -1118,90 +1120,87 @@ SEC_PKCS7ContainsCertsOrCrls(SEC_PKCS7ContentInfo *cinfo)
SECItem **certs;
CERTSignedCrl **crls;
- kind = SEC_PKCS7ContentType (cinfo);
+ 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;
+ 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;
+ return PR_TRUE;
else if (crls != NULL && crls[0] != NULL)
- return PR_TRUE;
+ return PR_TRUE;
else
- return PR_FALSE;
+ return PR_FALSE;
}
/* return the content length...could use GetContent, however we
- * need the encrypted content length
+ * need the encrypted content length
*/
PRBool
SEC_PKCS7IsContentEmpty(SEC_PKCS7ContentInfo *cinfo, unsigned int minLen)
{
SECItem *item = NULL;
- if(cinfo == NULL) {
- return PR_TRUE;
+ 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;
+ 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;
+ 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);
+ 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;
+ 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
@@ -1216,20 +1215,20 @@ SEC_PKCS7ContentIsSigned(SEC_PKCS7ContentInfo *cinfo)
SECOidTag kind;
SEC_PKCS7SignerInfo **signerinfos;
- kind = SEC_PKCS7ContentType (cinfo);
+ 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;
+ 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;
}
/*
@@ -1237,27 +1236,26 @@ SEC_PKCS7ContentIsSigned(SEC_PKCS7ContentInfo *cinfo)
* more complicated before I am finished, so...
*/
if (signerinfos != NULL && signerinfos[0] != NULL)
- return PR_TRUE;
+ return PR_TRUE;
else
- return PR_FALSE;
+ return PR_FALSE;
}
-
/*
* sec_pkcs7_verify_signature
*
- * 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".
+ * 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" at
- * - "*atTime" if "atTime" is not null, or
- * - the signing time if the signing time is available in "cinfo", or
- * - the current time (as returned by PR_Now).
+ * The verification checks that the signing cert is valid and trusted
+ * for the purpose specified by "certusage" at
+ * - "*atTime" if "atTime" is not null, or
+ * - the signing time if the signing time is available in "cinfo", or
+ * - the current time (as returned by PR_Now).
*
- * In addition, if "keepcerts" is true, add any new certificates found
- * into our local database.
+ * 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
@@ -1280,11 +1278,11 @@ SEC_PKCS7ContentIsSigned(SEC_PKCS7ContentInfo *cinfo)
*/
static PRBool
sec_pkcs7_verify_signature(SEC_PKCS7ContentInfo *cinfo,
- SECCertUsage certusage,
- const SECItem *detached_digest,
- HASH_HashType digest_type,
- PRBool keepcerts,
- const PRTime *atTime)
+ SECCertUsage certusage,
+ const SECItem *detached_digest,
+ HASH_HashType digest_type,
+ PRBool keepcerts,
+ const PRTime *atTime)
{
SECAlgorithmID **digestalgs, *bulkid;
const SECItem *digest;
@@ -1293,8 +1291,8 @@ sec_pkcs7_verify_signature(SEC_PKCS7ContentInfo *cinfo,
SEC_PKCS7SignerInfo **signerinfos, *signerinfo;
CERTCertificate *cert, **certs;
PRBool goodsig;
- CERTCertDBHandle *certdb, *defaultdb;
- SECOidTag encTag,digestTag;
+ CERTCertDBHandle *certdb, *defaultdb;
+ SECOidTag encTag, digestTag;
HASH_HashType found_type;
int i, certcount;
SECKEYPublicKey *publickey;
@@ -1316,54 +1314,50 @@ sec_pkcs7_verify_signature(SEC_PKCS7ContentInfo *cinfo,
defaultdb = CERT_GetDefaultCertDB();
publickey = NULL;
- if (! SEC_PKCS7ContentIsSigned(cinfo)) {
- PORT_SetError (SEC_ERROR_PKCS7_BAD_SIGNATURE);
- goto done;
+ if (!SEC_PKCS7ContentIsSigned(cinfo)) {
+ PORT_SetError(SEC_ERROR_PKCS7_BAD_SIGNATURE);
+ goto done;
}
- PORT_Assert (cinfo->contentTypeTag != NULL);
+ 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;
- 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;
- signerinfos = saedp->signerInfos;
- content_type = &(saedp->encContentInfo.contentType);
- sigkey = saedp->sigKey;
- bulkid = &(saedp->encContentInfo.contentEncAlg);
- }
- break;
+ 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;
+ 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;
+ 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;
+ PORT_SetError(SEC_ERROR_PKCS7_BAD_SIGNATURE);
+ goto done;
}
/*
@@ -1371,8 +1365,8 @@ sec_pkcs7_verify_signature(SEC_PKCS7ContentInfo *cinfo,
* but what should be the semantics here (like, return value)?
*/
if (signerinfos[1] != NULL) {
- PORT_SetError (SEC_ERROR_PKCS7_BAD_SIGNATURE);
- goto done;
+ PORT_SetError(SEC_ERROR_PKCS7_BAD_SIGNATURE);
+ goto done;
}
signerinfo = signerinfos[0];
@@ -1385,14 +1379,14 @@ sec_pkcs7_verify_signature(SEC_PKCS7ContentInfo *cinfo,
*/
certdb = defaultdb;
if (certdb == NULL) {
- goto done;
+ goto done;
}
certcount = 0;
if (rawcerts != NULL) {
- for (; rawcerts[certcount] != NULL; certcount++) {
- /* just counting */
- }
+ for (; rawcerts[certcount] != NULL; certcount++) {
+ /* just counting */
+ }
}
/*
@@ -1400,9 +1394,9 @@ sec_pkcs7_verify_signature(SEC_PKCS7ContentInfo *cinfo,
* needs to be destroyed.
*/
rv = CERT_ImportCerts(certdb, certusage, certcount, rawcerts, &certs,
- keepcerts, PR_FALSE, NULL);
- if ( rv != SECSuccess ) {
- goto done;
+ keepcerts, PR_FALSE, NULL);
+ if (rv != SECSuccess) {
+ goto done;
}
/*
@@ -1413,7 +1407,7 @@ sec_pkcs7_verify_signature(SEC_PKCS7ContentInfo *cinfo,
*/
cert = CERT_FindCertByIssuerAndSN(certdb, signerinfo->issuerAndSN);
if (cert == NULL) {
- goto done;
+ goto done;
}
signerinfo->cert = cert;
@@ -1423,10 +1417,10 @@ sec_pkcs7_verify_signature(SEC_PKCS7ContentInfo *cinfo,
* both on the cert verification and for importing the sender
* email profile.
*/
- encoded_stime = SEC_PKCS7GetSigningTime (cinfo);
+ encoded_stime = SEC_PKCS7GetSigningTime(cinfo);
if (encoded_stime != NULL) {
- if (DER_DecodeTimeChoice (&stime, encoded_stime) != SECSuccess)
- encoded_stime = NULL; /* conversion failed, so pretend none */
+ if (DER_DecodeTimeChoice(&stime, encoded_stime) != SECSuccess)
+ encoded_stime = NULL; /* conversion failed, so pretend none */
}
/*
@@ -1438,29 +1432,28 @@ sec_pkcs7_verify_signature(SEC_PKCS7ContentInfo *cinfo,
* maybe make them pass in the current time, always?).
*/
if (atTime) {
- verificationTime = *atTime;
+ verificationTime = *atTime;
} else if (encoded_stime != NULL) {
- verificationTime = stime;
+ verificationTime = stime;
} else {
- verificationTime = PR_Now();
+ verificationTime = PR_Now();
}
- if (CERT_VerifyCert (certdb, cert, PR_TRUE, certusage, verificationTime,
- 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;
+ if (CERT_VerifyCert(certdb, cert, PR_TRUE, certusage, verificationTime,
+ 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);
+ publickey = CERT_ExtractPublicKey(cert);
if (publickey == NULL)
- goto done;
+ goto done;
/*
* XXX No! If digests is empty, see if we can create it now by
@@ -1472,9 +1465,8 @@ sec_pkcs7_verify_signature(SEC_PKCS7ContentInfo *cinfo,
* 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;
+ if ((digests == NULL || digests[0] == NULL) && (detached_digest == NULL || detached_digest->data == NULL))
+ goto done;
/*
* Find and confirm digest algorithm.
@@ -1484,198 +1476,197 @@ sec_pkcs7_verify_signature(SEC_PKCS7ContentInfo *cinfo,
/* 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;
+ 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;
+ 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];
+ 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;
+ PORT_SetError(SEC_ERROR_PKCS7_BAD_SIGNATURE);
+ goto done;
}
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);
+ 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);
- }
+ 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);
+ 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:
@@ -1683,46 +1674,45 @@ 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.
- */
+ 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:
@@ -1732,52 +1722,52 @@ done:
*/
if (certs != NULL)
- CERT_DestroyCertArray (certs, certcount);
+ CERT_DestroyCertArray(certs, certcount);
if (publickey != NULL)
- SECKEY_DestroyPublicKey (publickey);
+ 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".
+ * 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.
+ * 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)
+ SECCertUsage certusage,
+ PRBool keepcerts)
{
- return sec_pkcs7_verify_signature (cinfo, certusage,
- NULL, HASH_AlgNULL, keepcerts, NULL);
+ return sec_pkcs7_verify_signature(cinfo, certusage,
+ NULL, HASH_AlgNULL, keepcerts, NULL);
}
/*
* 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".
+ * 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.
+ * 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)
+ SECCertUsage certusage,
+ const SECItem *detached_digest,
+ HASH_HashType digest_type,
+ PRBool keepcerts)
{
- return sec_pkcs7_verify_signature (cinfo, certusage,
- detached_digest, digest_type,
- keepcerts, NULL);
+ return sec_pkcs7_verify_signature(cinfo, certusage,
+ detached_digest, digest_type,
+ keepcerts, NULL);
}
/*
@@ -1787,20 +1777,20 @@ SEC_PKCS7VerifyDetachedSignature(SEC_PKCS7ContentInfo *cinfo,
* The verification checks that the signing cert is valid and trusted
* for the purpose specified by "certusage" at time "atTime".
*
- * In addition, if "keepcerts" is true, add any new certificates found
- * into our local database.
+ * In addition, if "keepcerts" is true, add any new certificates found
+ * into our local database.
*/
PRBool
SEC_PKCS7VerifyDetachedSignatureAtTime(SEC_PKCS7ContentInfo *cinfo,
- SECCertUsage certusage,
- const SECItem *detached_digest,
- HASH_HashType digest_type,
- PRBool keepcerts,
- PRTime atTime)
+ SECCertUsage certusage,
+ const SECItem *detached_digest,
+ HASH_HashType digest_type,
+ PRBool keepcerts,
+ PRTime atTime)
{
- return sec_pkcs7_verify_signature (cinfo, certusage,
- detached_digest, digest_type,
- keepcerts, &atTime);
+ return sec_pkcs7_verify_signature(cinfo, certusage,
+ detached_digest, digest_type,
+ keepcerts, &atTime);
}
/*
@@ -1822,35 +1812,31 @@ sec_pkcs7_get_signer_cert_info(SEC_PKCS7ContentInfo *cinfo, int selector)
CERTCertificate *signercert;
char *container;
- kind = SEC_PKCS7ContentType (cinfo);
+ 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;
+ 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;
+ return NULL;
signercert = signerinfos[0]->cert;
@@ -1858,33 +1844,33 @@ sec_pkcs7_get_signer_cert_info(SEC_PKCS7ContentInfo *cinfo, int selector)
* 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, NULL);
- signercert = signerinfos[0]->cert;
- if (signercert == NULL)
- return 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, NULL);
+ 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;
+ 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;
@@ -1902,7 +1888,6 @@ 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.
*/
@@ -1912,8 +1897,8 @@ SEC_PKCS7GetSigningTime(SEC_PKCS7ContentInfo *cinfo)
SEC_PKCS7SignerInfo **signerinfos;
SEC_PKCS7Attribute *attr;
- if (SEC_PKCS7ContentType (cinfo) != SEC_OID_PKCS7_SIGNED_DATA)
- return NULL;
+ if (SEC_PKCS7ContentType(cinfo) != SEC_OID_PKCS7_SIGNED_DATA)
+ return NULL;
signerinfos = cinfo->content.signedData->signerInfos;
@@ -1921,9 +1906,9 @@ SEC_PKCS7GetSigningTime(SEC_PKCS7ContentInfo *cinfo)
* No signature, or more than one, means no deal.
*/
if (signerinfos == NULL || signerinfos[0] == NULL || signerinfos[1] != NULL)
- return NULL;
+ return NULL;
- attr = sec_PKCS7FindAttribute (signerinfos[0]->authAttr,
- SEC_OID_PKCS9_SIGNING_TIME, PR_TRUE);
- return sec_PKCS7AttributeValue (attr);
+ attr = sec_PKCS7FindAttribute(signerinfos[0]->authAttr,
+ SEC_OID_PKCS9_SIGNING_TIME, PR_TRUE);
+ return sec_PKCS7AttributeValue(attr);
}
diff --git a/nss/lib/pkcs7/p7encode.c b/nss/lib/pkcs7/p7encode.c
index 349bc84..bdbc343 100644
--- a/nss/lib/pkcs7/p7encode.c
+++ b/nss/lib/pkcs7/p7encode.c
@@ -16,7 +16,7 @@
#include "secitem.h"
#include "pk11func.h"
#include "secerr.h"
-#include "sechash.h" /* for HASH_GetHashObject() */
+#include "sechash.h" /* for HASH_GetHashObject() */
struct sec_pkcs7_encoder_output {
SEC_PKCS7EncoderOutputCallback outputfn;
@@ -32,7 +32,6 @@ struct SEC_PKCS7EncoderContextStr {
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
@@ -40,17 +39,17 @@ struct SEC_PKCS7EncoderContextStr {
*/
static void
sec_pkcs7_encoder_out(void *arg, const char *buf, unsigned long len,
- int depth, SEC_ASN1EncodingPart data_kind)
+ 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);
+ 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)
+sec_pkcs7_encoder_start_encrypt(SEC_PKCS7ContentInfo *cinfo,
+ PK11SymKey *orig_bulkkey)
{
SECOidTag kind;
sec_PKCS7CipherObject *encryptobj;
@@ -58,153 +57,150 @@ sec_pkcs7_encoder_start_encrypt (SEC_PKCS7ContentInfo *cinfo,
SEC_PKCS7EncryptedContentInfo *enccinfo;
SECKEYPublicKey *publickey = NULL;
SECKEYPrivateKey *ourPrivKey = NULL;
- PK11SymKey *bulkkey;
+ PK11SymKey *bulkkey;
void *mark;
int i;
PLArenaPool *arena = NULL;
- kind = SEC_PKCS7ContentType (cinfo);
+ 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;
+ 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;
+ 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;
- }
+ 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);
+ 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;
+ 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));
+ 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 */
+ PORT_ArenaUnmark(cinfo->poolp, mark);
+ mark = NULL; /* good one; do not want to release */
}
- /* fallthru */
+/* fallthru */
loser:
if (arena) {
- PORT_FreeArena(arena, PR_FALSE);
+ PORT_FreeArena(arena, PR_FALSE);
}
if (publickey) {
SECKEY_DestroyPublicKey(publickey);
@@ -213,18 +209,18 @@ loser:
SECKEY_DestroyPrivateKey(ourPrivKey);
}
if (mark != NULL) {
- PORT_ArenaRelease (cinfo->poolp, mark);
+ PORT_ArenaRelease(cinfo->poolp, mark);
}
if (orig_bulkkey == NULL) {
- if (bulkkey) PK11_FreeSymKey(bulkkey);
+ if (bulkkey)
+ PK11_FreeSymKey(bulkkey);
}
return encryptobj;
}
-
static void
-sec_pkcs7_encoder_notify (void *arg, PRBool before, void *dest, int depth)
+sec_pkcs7_encoder_notify(void *arg, PRBool before, void *dest, int depth)
{
SEC_PKCS7EncoderContext *p7ecx;
SEC_PKCS7ContentInfo *cinfo;
@@ -236,9 +232,9 @@ sec_pkcs7_encoder_notify (void *arg, PRBool before, void *dest, int depth)
* not interesting to us.
*/
if (!before)
- return;
+ return;
- p7ecx = (SEC_PKCS7EncoderContext*)arg;
+ p7ecx = (SEC_PKCS7EncoderContext *)arg;
cinfo = p7ecx->cinfo;
before_content = PR_FALSE;
@@ -251,97 +247,86 @@ sec_pkcs7_encoder_notify (void *arg, PRBool before, void *dest, int depth)
* if/when we want to handle fully nested types, this will have
* to recurse until reaching the innermost data content.
*/
- kind = SEC_PKCS7ContentType (cinfo);
+ 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;
+ 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);
+ /*
+ * 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_pkcs7_encoder_start_contexts(SEC_PKCS7ContentInfo *cinfo,
+ PK11SymKey *bulkkey)
{
SEC_PKCS7EncoderContext *p7ecx;
SECOidTag kind;
@@ -349,97 +334,96 @@ sec_pkcs7_encoder_start_contexts (SEC_PKCS7ContentInfo *cinfo,
SECItem **digests;
SECAlgorithmID *digestalg, **digestalgs;
- p7ecx =
- (SEC_PKCS7EncoderContext*)PORT_ZAlloc (sizeof(SEC_PKCS7EncoderContext));
+ p7ecx =
+ (SEC_PKCS7EncoderContext *)PORT_ZAlloc(sizeof(SEC_PKCS7EncoderContext));
if (p7ecx == NULL)
- return NULL;
+ return NULL;
digests = NULL;
digestalg = NULL;
digestalgs = NULL;
encrypt = PR_FALSE;
- kind = SEC_PKCS7ContentType (cinfo);
+ 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;
+ 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;
- }
+ 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 (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;
- }
+ 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_PKCS7EncoderStart(SEC_PKCS7ContentInfo *cinfo,
+ SEC_PKCS7EncoderOutputCallback outputfn,
+ void *outputarg,
+ PK11SymKey *bulkkey)
{
SEC_PKCS7EncoderContext *p7ecx;
SECStatus rv;
- p7ecx = sec_pkcs7_encoder_start_contexts (cinfo, bulkkey);
+ p7ecx = sec_pkcs7_encoder_start_contexts(cinfo, bulkkey);
if (p7ecx == NULL)
- return NULL;
+ return NULL;
p7ecx->output.outputfn = outputfn;
p7ecx->output.outputarg = outputarg;
@@ -447,23 +431,23 @@ SEC_PKCS7EncoderStart (SEC_PKCS7ContentInfo *cinfo,
/*
* Initialize the BER encoder.
*/
- p7ecx->ecx = SEC_ASN1EncoderStart (cinfo, sec_PKCS7ContentInfoTemplate,
- sec_pkcs7_encoder_out, &(p7ecx->output));
+ p7ecx->ecx = SEC_ASN1EncoderStart(cinfo, sec_PKCS7ContentInfoTemplate,
+ sec_pkcs7_encoder_out, &(p7ecx->output));
if (p7ecx->ecx == NULL) {
- PORT_Free (p7ecx);
- return 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);
+ SEC_ASN1EncoderSetStreaming(p7ecx->ecx);
/*
* The notify function will watch for the contents field.
*/
- SEC_ASN1EncoderSetNotifyProc (p7ecx->ecx, sec_pkcs7_encoder_notify, p7ecx);
+ SEC_ASN1EncoderSetNotifyProc(p7ecx->ecx, sec_pkcs7_encoder_notify, p7ecx);
/*
* This will encode everything up to the content bytes. (The notify
@@ -471,29 +455,27 @@ SEC_PKCS7EncoderStart (SEC_PKCS7ContentInfo *cinfo,
* caller can start passing contents bytes to our Update, which we
* will pass along.
*/
- rv = SEC_ASN1EncoderUpdate (p7ecx->ecx, NULL, 0);
+ rv = SEC_ASN1EncoderUpdate(p7ecx->ecx, NULL, 0);
if (rv != SECSuccess) {
- PORT_Free (p7ecx);
- return NULL;
+ 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)
+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 */
+ rv = SECSuccess; /* may as well be optimistic */
/*
* We should really have data to process, or we should be trying
@@ -502,154 +484,153 @@ sec_pkcs7_encoder_work_data (SEC_PKCS7EncoderContext *p7ecx, SECItem *dest,
* 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);
+ 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);
+ (*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;
- }
+ /* 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);
- }
+ /*
+ * 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)
+ 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);
+ 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)
+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);
+ 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)
+sec_pkcs7_encoder_sig_and_certs(SEC_PKCS7ContentInfo *cinfo,
+ SECKEYGetPasswordKey pwfn, void *pwfnarg)
{
SECOidTag kind;
CERTCertificate **certs;
@@ -662,206 +643,202 @@ sec_pkcs7_encoder_sig_and_certs (SEC_PKCS7ContentInfo *cinfo,
int certcount;
int ci, cli, rci, si;
- kind = SEC_PKCS7ContentType (cinfo);
+ 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;
+ 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! */
+ 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;
- }
+ 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++;
+ for (ci = 0; certs[ci] != NULL; ci++)
+ certcount++;
}
if (certlists != NULL) {
- for (cli = 0; certlists[cli] != NULL; cli++)
- certcount += certlists[cli]->len;
+ for (cli = 0; certlists[cli] != NULL; cli++)
+ certcount += certlists[cli]->len;
}
if (certcount == 0)
- return SECSuccess; /* signing done; no certs */
+ return SECSuccess; /* signing done; no certs */
/*
* Combine all of the certs and cert chains into rawcerts.
@@ -869,10 +846,10 @@ sec_pkcs7_encoder_sig_and_certs (SEC_PKCS7ContentInfo *cinfo,
* 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 *));
+ rawcerts = (SECItem **)PORT_ArenaAlloc(poolp,
+ (certcount + 1) * sizeof(SECItem *));
if (rawcerts == NULL)
- return SECFailure;
+ return SECFailure;
/*
* XXX Want to check for duplicates and not add *any* cert that is
@@ -882,24 +859,23 @@ sec_pkcs7_encoder_sig_and_certs (SEC_PKCS7ContentInfo *cinfo,
*/
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]);
- }
-
+ 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);
+ 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]);
- }
+ for (cli = 0; certlists[cli] != NULL; cli++) {
+ for (ci = 0; ci < certlists[cli]->len; ci++)
+ rawcerts[rci++] = &(certlists[cli]->certs[ci]);
+ }
}
rawcerts[rci] = NULL;
@@ -908,36 +884,35 @@ sec_pkcs7_encoder_sig_and_certs (SEC_PKCS7ContentInfo *cinfo,
return SECSuccess;
}
-
SECStatus
-SEC_PKCS7EncoderFinish (SEC_PKCS7EncoderContext *p7ecx,
- SECKEYGetPasswordKey pwfn, void *pwfnarg)
+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);
+ rv = sec_pkcs7_encoder_work_data(p7ecx, NULL, NULL, 0, PR_TRUE);
/*
* Turn off streaming stuff.
*/
- SEC_ASN1EncoderClearTakeFromBuf (p7ecx->ecx);
- SEC_ASN1EncoderClearStreaming (p7ecx->ecx);
+ SEC_ASN1EncoderClearTakeFromBuf(p7ecx->ecx);
+ SEC_ASN1EncoderClearStreaming(p7ecx->ecx);
if (rv != SECSuccess)
- goto loser;
+ goto loser;
- rv = sec_pkcs7_encoder_sig_and_certs (p7ecx->cinfo, pwfn, pwfnarg);
+ rv = sec_pkcs7_encoder_sig_and_certs(p7ecx->cinfo, pwfn, pwfnarg);
if (rv != SECSuccess)
- goto loser;
+ goto loser;
- rv = SEC_ASN1EncoderUpdate (p7ecx->ecx, NULL, 0);
+ rv = SEC_ASN1EncoderUpdate(p7ecx->ecx, NULL, 0);
loser:
- SEC_ASN1EncoderFinish (p7ecx->ecx);
- PORT_Free (p7ecx);
+ SEC_ASN1EncoderFinish(p7ecx->ecx);
+ PORT_Free(p7ecx);
return rv;
}
@@ -958,61 +933,60 @@ SEC_PKCS7EncoderAbort(SEC_PKCS7EncoderContext *p7ecx, int error)
* the ASN1 template for pkcs7 contentInfo built into their own encodings.
*/
SECStatus
-SEC_PKCS7PrepareForEncode (SEC_PKCS7ContentInfo *cinfo,
- PK11SymKey *bulkkey,
- SECKEYGetPasswordKey pwfn,
- void *pwfnarg)
+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);
+ p7ecx = sec_pkcs7_encoder_start_contexts(cinfo, bulkkey);
if (p7ecx == NULL)
- return SECFailure;
+ return SECFailure;
- content = SEC_PKCS7GetContent (cinfo);
+ 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);
+ 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;
+ 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_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);
+ rv = sec_pkcs7_encoder_sig_and_certs(cinfo, pwfn, pwfnarg);
loser:
- PORT_Free (p7ecx);
+ 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
@@ -1037,30 +1011,29 @@ loser:
* "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)
+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);
+ rv = SEC_PKCS7PrepareForEncode(cinfo, bulkkey, pwfn, pwfnarg);
if (rv == SECSuccess) {
- struct sec_pkcs7_encoder_output outputcx;
+ struct sec_pkcs7_encoder_output outputcx;
- outputcx.outputfn = outputfn;
- outputcx.outputarg = outputarg;
+ outputcx.outputfn = outputfn;
+ outputcx.outputarg = outputarg;
- rv = SEC_ASN1Encode (cinfo, sec_PKCS7ContentInfoTemplate,
- sec_pkcs7_encoder_out, &outputcx);
+ 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
@@ -1089,19 +1062,18 @@ SEC_PKCS7Encode (SEC_PKCS7ContentInfo *cinfo,
* "pwfnarg" is an opaque argument to the above callback.
*/
SECItem *
-SEC_PKCS7EncodeItem (PLArenaPool *pool,
- SECItem *dest,
- SEC_PKCS7ContentInfo *cinfo,
- PK11SymKey *bulkkey,
- SECKEYGetPasswordKey pwfn,
- void *pwfnarg)
+SEC_PKCS7EncodeItem(PLArenaPool *pool,
+ SECItem *dest,
+ SEC_PKCS7ContentInfo *cinfo,
+ PK11SymKey *bulkkey,
+ SECKEYGetPasswordKey pwfn,
+ void *pwfnarg)
{
SECStatus rv;
- rv = SEC_PKCS7PrepareForEncode (cinfo, bulkkey, pwfn, pwfnarg);
+ rv = SEC_PKCS7PrepareForEncode(cinfo, bulkkey, pwfn, pwfnarg);
if (rv != SECSuccess)
- return NULL;
+ return NULL;
- return SEC_ASN1EncodeItem (pool, dest, cinfo, sec_PKCS7ContentInfoTemplate);
+ return SEC_ASN1EncodeItem(pool, dest, cinfo, sec_PKCS7ContentInfoTemplate);
}
-
diff --git a/nss/lib/pkcs7/p7local.c b/nss/lib/pkcs7/p7local.c
index 5e67a0e..182e385 100644
--- a/nss/lib/pkcs7/p7local.c
+++ b/nss/lib/pkcs7/p7local.c
@@ -11,7 +11,7 @@
#include "p7local.h"
-#include "cryptohi.h"
+#include "cryptohi.h"
#include "secasn1.h"
#include "secoid.h"
#include "secitem.h"
@@ -24,13 +24,13 @@
* 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);
+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
@@ -61,10 +61,10 @@ SEC_ASN1_MKSUB(SEC_SetOfAnyTemplate)
*
* 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.
+ * have two simple cover functions which call it.
*/
sec_PKCS7CipherObject *
-sec_PKCS7CreateDecryptObject (PK11SymKey *key, SECAlgorithmID *algid)
+sec_PKCS7CreateDecryptObject(PK11SymKey *key, SECAlgorithmID *algid)
{
sec_PKCS7CipherObject *result;
SECOidTag algtag;
@@ -73,53 +73,53 @@ sec_PKCS7CreateDecryptObject (PK11SymKey *key, SECAlgorithmID *algid)
PK11SlotInfo *slot;
SECItem *param = NULL;
- result = (struct sec_pkcs7_cipher_object*)
- PORT_ZAlloc (sizeof(struct sec_pkcs7_cipher_object));
+ result = (struct sec_pkcs7_cipher_object *)
+ PORT_ZAlloc(sizeof(struct sec_pkcs7_cipher_object));
if (result == NULL)
- return NULL;
+ return NULL;
ciphercx = NULL;
- algtag = SECOID_GetAlgorithmTag (algid);
+ 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;
- }
+ 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;
- }
+ 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);
+ ciphercx = PK11_CreateContextBySymKey(cryptoMechType, CKA_DECRYPT,
+ key, param);
+ SECITEM_FreeItem(param, PR_TRUE);
if (ciphercx == NULL) {
- PORT_Free (result);
- return 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->doit = (sec_pkcs7_cipher_function)PK11_CipherOp;
+ result->destroy = (sec_pkcs7_cipher_destroy)PK11_DestroyContext;
result->encrypt = PR_FALSE;
result->pending_count = 0;
@@ -137,11 +137,11 @@ sec_PKCS7CreateDecryptObject (PK11SymKey *key, SECAlgorithmID *algid)
*
* 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.
+ * have two simple cover functions which call it.
*/
sec_PKCS7CipherObject *
-sec_PKCS7CreateEncryptObject (PLArenaPool *poolp, PK11SymKey *key,
- SECOidTag algtag, SECAlgorithmID *algid)
+sec_PKCS7CreateEncryptObject(PLArenaPool *poolp, PK11SymKey *key,
+ SECOidTag algtag, SECAlgorithmID *algid)
{
sec_PKCS7CipherObject *result;
void *ciphercx;
@@ -151,47 +151,47 @@ sec_PKCS7CreateEncryptObject (PLArenaPool *poolp, PK11SymKey *key,
SECItem *param = NULL;
PRBool needToEncodeAlgid = PR_FALSE;
- result = (struct sec_pkcs7_cipher_object*)
- PORT_ZAlloc (sizeof(struct sec_pkcs7_cipher_object));
+ result = (struct sec_pkcs7_cipher_object *)
+ PORT_ZAlloc(sizeof(struct sec_pkcs7_cipher_object));
if (result == NULL)
- return 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;
- }
+ 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;
+ 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);
+ 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);
+ ciphercx = PK11_CreateContextBySymKey(cryptoMechType, CKA_ENCRYPT,
+ key, param);
if (ciphercx == NULL) {
- PORT_Free (result);
- SECITEM_FreeItem(param,PR_TRUE);
- return NULL;
+ PORT_Free(result);
+ SECITEM_FreeItem(param, PR_TRUE);
+ return NULL;
}
/*
@@ -200,63 +200,60 @@ sec_PKCS7CreateEncryptObject (PLArenaPool *poolp, PK11SymKey *key,
* 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);
- PK11_DestroyContext(ciphercx, PR_TRUE);
- return NULL;
- }
+ rv = PK11_ParamToAlgid(algtag, param, poolp, algid);
+ if (rv != SECSuccess) {
+ PORT_Free(result);
+ SECITEM_FreeItem(param, PR_TRUE);
+ PK11_DestroyContext(ciphercx, PR_TRUE);
+ return NULL;
+ }
}
- SECITEM_FreeItem(param,PR_TRUE);
+ 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->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)
+sec_pkcs7_destroy_cipher(sec_PKCS7CipherObject *obj)
{
- (* obj->destroy) (obj->cx, PR_TRUE);
- PORT_Free (obj);
+ (*obj->destroy)(obj->cx, PR_TRUE);
+ PORT_Free(obj);
}
void
-sec_PKCS7DestroyDecryptObject (sec_PKCS7CipherObject *obj)
+sec_PKCS7DestroyDecryptObject(sec_PKCS7CipherObject *obj)
{
- PORT_Assert (obj != NULL);
+ PORT_Assert(obj != NULL);
if (obj == NULL)
- return;
- PORT_Assert (! obj->encrypt);
- sec_pkcs7_destroy_cipher (obj);
+ return;
+ PORT_Assert(!obj->encrypt);
+ sec_pkcs7_destroy_cipher(obj);
}
void
-sec_PKCS7DestroyEncryptObject (sec_PKCS7CipherObject *obj)
+sec_PKCS7DestroyEncryptObject(sec_PKCS7CipherObject *obj)
{
- PORT_Assert (obj != NULL);
+ PORT_Assert(obj != NULL);
if (obj == NULL)
- return;
- PORT_Assert (obj->encrypt);
- sec_pkcs7_destroy_cipher (obj);
+ 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
@@ -274,12 +271,12 @@ sec_PKCS7DestroyEncryptObject (sec_PKCS7CipherObject *obj)
* will be stored.
*/
unsigned int
-sec_PKCS7DecryptLength (sec_PKCS7CipherObject *obj, unsigned int input_len,
- PRBool final)
+sec_PKCS7DecryptLength(sec_PKCS7CipherObject *obj, unsigned int input_len,
+ PRBool final)
{
int blocks, block_size;
- PORT_Assert (! obj->encrypt);
+ PORT_Assert(!obj->encrypt);
block_size = obj->block_size;
@@ -288,7 +285,7 @@ sec_PKCS7DecryptLength (sec_PKCS7CipherObject *obj, unsigned int input_len,
* number of output bytes as we had input bytes.
*/
if (block_size == 0)
- return input_len;
+ return input_len;
/*
* On the final call, we will always use up all of the pending
@@ -299,7 +296,7 @@ sec_PKCS7DecryptLength (sec_PKCS7CipherObject *obj, unsigned int input_len,
* at least 1 byte of padding), but seemed clearer/better to me.
*/
if (final)
- return obj->pending_count + input_len;
+ return obj->pending_count + input_len;
/*
* Okay, this amount is exactly what we will output on the
@@ -328,13 +325,13 @@ sec_PKCS7DecryptLength (sec_PKCS7CipherObject *obj, unsigned int input_len,
* will be stored.
*/
unsigned int
-sec_PKCS7EncryptLength (sec_PKCS7CipherObject *obj, unsigned int input_len,
- PRBool final)
+sec_PKCS7EncryptLength(sec_PKCS7CipherObject *obj, unsigned int input_len,
+ PRBool final)
{
int blocks, block_size;
int pad_size;
- PORT_Assert (obj->encrypt);
+ PORT_Assert(obj->encrypt);
block_size = obj->block_size;
pad_size = obj->pad_size;
@@ -344,7 +341,7 @@ sec_PKCS7EncryptLength (sec_PKCS7CipherObject *obj, unsigned int input_len,
* number of output bytes as we had input bytes.
*/
if (block_size == 0)
- return input_len;
+ return input_len;
/*
* On the final call, we only send out what we need for
@@ -353,13 +350,13 @@ sec_PKCS7EncryptLength (sec_PKCS7CipherObject *obj, unsigned int input_len,
* 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;
- }
+ if (pad_size == 0) {
+ return obj->pending_count + input_len;
+ } else {
+ blocks = (obj->pending_count + input_len) / pad_size;
+ blocks++;
+ return blocks * pad_size;
+ }
}
/*
@@ -367,11 +364,9 @@ sec_PKCS7EncryptLength (sec_PKCS7CipherObject *obj, unsigned int input_len,
*/
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
@@ -391,29 +386,29 @@ sec_PKCS7EncryptLength (sec_PKCS7CipherObject *obj, unsigned int input_len,
* 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)
+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)
{
unsigned int blocks, bsize, pcount, padsize;
unsigned int max_needed, ifraglen, ofraglen, output_len;
unsigned char *pbuf;
SECStatus rv;
- PORT_Assert (! obj->encrypt);
+ 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);
+ 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;
+ /* PORT_SetError (XXX); */
+ return SECFailure;
}
/*
@@ -428,8 +423,8 @@ sec_PKCS7Decrypt (sec_PKCS7CipherObject *obj, unsigned char *output,
* cipher function and we are done.
*/
if (bsize == 0) {
- return (* obj->doit) (obj->cx, output, output_len_p, max_output_len,
- input, input_len);
+ return (*obj->doit)(obj->cx, output, output_len_p, max_output_len,
+ input, input_len);
}
pcount = obj->pending_count;
@@ -438,64 +433,64 @@ sec_PKCS7Decrypt (sec_PKCS7CipherObject *obj, unsigned char *output,
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;
+ /*
+ * 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
@@ -506,46 +501,47 @@ sec_PKCS7Decrypt (sec_PKCS7CipherObject *obj, unsigned char *output,
* 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;
- }
+ 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);
+ 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;
+ 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;
+ 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;
+ ofraglen = 0;
}
/*
@@ -553,17 +549,17 @@ sec_PKCS7Decrypt (sec_PKCS7CipherObject *obj, unsigned char *output,
* 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;
+ 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);
+ PORT_Assert(output_len_p != NULL || output_len == 0);
if (output_len_p != NULL)
- *output_len_p = output_len;
+ *output_len_p = output_len;
return SECSuccess;
}
@@ -592,29 +588,29 @@ sec_PKCS7Decrypt (sec_PKCS7CipherObject *obj, unsigned char *output,
* 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)
+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);
+ 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);
+ 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;
+ /* PORT_SetError (XXX); */
+ return SECFailure;
}
bsize = obj->block_size;
@@ -625,8 +621,8 @@ sec_PKCS7Encrypt (sec_PKCS7CipherObject *obj, unsigned char *output,
* cipher function and we are done.
*/
if (bsize == 0) {
- return (* obj->doit) (obj->cx, output, output_len_p, max_output_len,
- input, input_len);
+ return (*obj->doit)(obj->cx, output, output_len_p, max_output_len,
+ input, input_len);
}
pcount = obj->pending_count;
@@ -635,103 +631,107 @@ sec_PKCS7Encrypt (sec_PKCS7CipherObject *obj, unsigned char *output,
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;
- }
+ /*
+ * 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);
+ 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;
+ if (padsize) {
+ padlen = padsize - (pcount % padsize);
+ PORT_Memset(pbuf + pcount, padlen, padlen);
+ } else {
+ padlen = 0;
+ }
+ 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;
+ obj->pending_count = pcount;
}
- PORT_Assert (output_len_p != NULL || output_len == 0);
+ PORT_Assert(output_len_p != NULL || output_len == 0);
if (output_len_p != NULL)
- *output_len_p = output_len;
+ *output_len_p = output_len;
return SECSuccess;
}
@@ -741,7 +741,6 @@ sec_PKCS7Encrypt (sec_PKCS7CipherObject *obj, unsigned char *output,
* -------------------------------------------------------------------
*/
-
/*
* -------------------------------------------------------------------
* XXX The following Attribute stuff really belongs elsewhere.
@@ -760,46 +759,41 @@ sec_PKCS7Encrypt (sec_PKCS7CipherObject *obj, unsigned char *output,
* that first-found behavior? It was like that when I found it...)
*/
SEC_PKCS7Attribute *
-sec_PKCS7FindAttribute (SEC_PKCS7Attribute **attrs, SECOidTag oidtag,
- PRBool only)
+sec_PKCS7FindAttribute(SEC_PKCS7Attribute **attrs, SECOidTag oidtag,
+ PRBool only)
{
SECOidData *oid;
SEC_PKCS7Attribute *attr1, *attr2;
if (attrs == NULL)
- return NULL;
+ return NULL;
oid = SECOID_FindOIDByTag(oidtag);
if (oid == NULL)
- return 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->type.len == oid->oid.len && PORT_Memcmp(attr1->type.data, oid->oid.data, oid->oid.len) == 0)
+ break;
}
if (attr1 == NULL)
- return NULL;
+ return NULL;
if (!only)
- return attr1;
+ 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->type.len == oid->oid.len && PORT_Memcmp(attr2->type.data, oid->oid.data, oid->oid.len) == 0)
+ break;
}
if (attr2 != NULL)
- return NULL;
+ return NULL;
return attr1;
}
-
/*
* Return the single attribute value, doing some sanity checking first:
* - Multiple values are *not* expected.
@@ -811,15 +805,15 @@ sec_PKCS7AttributeValue(SEC_PKCS7Attribute *attr)
SECItem *value;
if (attr == NULL)
- return NULL;
+ return NULL;
value = attr->values[0];
if (value == NULL || value->data == NULL || value->len == 0)
- return NULL;
+ return NULL;
if (attr->values[1] != NULL)
- return NULL;
+ return NULL;
return value;
}
@@ -833,82 +827,81 @@ sec_attr_choose_attr_value_template(void *src_or_dest, PRBool encoding)
SECOidData *oiddata;
PRBool encoded;
- PORT_Assert (src_or_dest != NULL);
+ PORT_Assert(src_or_dest != NULL);
if (src_or_dest == NULL)
- return NULL;
+ return NULL;
- attribute = (SEC_PKCS7Attribute*)src_or_dest;
+ attribute = (SEC_PKCS7Attribute *)src_or_dest;
if (encoding && attribute->encoded)
- return SEC_ASN1_GET(SEC_AnyTemplate);
+ return SEC_ASN1_GET(SEC_AnyTemplate);
oiddata = attribute->typeTag;
if (oiddata == NULL) {
- oiddata = SECOID_FindOID(&attribute->type);
- attribute->typeTag = oiddata;
+ oiddata = SECOID_FindOID(&attribute->type);
+ attribute->typeTag = oiddata;
}
if (oiddata == NULL) {
- encoded = PR_TRUE;
- theTemplate = SEC_ASN1_GET(SEC_AnyTemplate);
+ 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 */
- }
+ 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);
+ /*
+ * 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;
+ /*
+ * 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_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) },
+ 0, NULL, sizeof(SEC_PKCS7Attribute) },
{ SEC_ASN1_OBJECT_ID,
- offsetof(SEC_PKCS7Attribute,type) },
+ offsetof(SEC_PKCS7Attribute, type) },
{ SEC_ASN1_DYNAMIC | SEC_ASN1_SET_OF,
- offsetof(SEC_PKCS7Attribute,values),
- &sec_attr_chooser },
+ offsetof(SEC_PKCS7Attribute, values),
+ &sec_attr_chooser },
{ 0 }
};
@@ -924,10 +917,10 @@ static const SEC_ASN1Template sec_pkcs7_set_of_attribute_template[] = {
* do the reordering.)
*/
SECItem *
-sec_PKCS7EncodeAttributes (PLArenaPool *poolp, SECItem *dest, void *src)
+sec_PKCS7EncodeAttributes(PLArenaPool *poolp, SECItem *dest, void *src)
{
- return SEC_ASN1EncodeItem (poolp, dest, src,
- sec_pkcs7_set_of_attribute_template);
+ return SEC_ASN1EncodeItem(poolp, dest, src,
+ sec_pkcs7_set_of_attribute_template);
}
/*
@@ -936,7 +929,7 @@ sec_PKCS7EncodeAttributes (PLArenaPool *poolp, SECItem *dest, void *src)
* if reordering is necessary it will be done in place (in attrs).
*/
SECStatus
-sec_PKCS7ReorderAttributes (SEC_PKCS7Attribute **attrs)
+sec_PKCS7ReorderAttributes(SEC_PKCS7Attribute **attrs)
{
PLArenaPool *poolp;
int num_attrs, i, pass, besti;
@@ -948,56 +941,56 @@ sec_PKCS7ReorderAttributes (SEC_PKCS7Attribute **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);
+ PORT_Assert(attrs != NULL);
if (attrs == NULL)
- return SECSuccess;
+ return SECSuccess;
/*
* Count how many attributes we are dealing with here.
*/
num_attrs = 0;
while (attrs[num_attrs] != NULL)
- num_attrs++;
+ 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);
+ PORT_Assert(num_attrs);
if (num_attrs == 0 || num_attrs == 1)
- return SECSuccess;
+ 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? */
+ poolp = PORT_NewArena(1024); /* XXX what is right value? */
if (poolp == NULL)
- return SECFailure; /* no memory; nothing we can do... */
+ 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 *));
+ 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;
+ 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;
- }
+ 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;
+ }
}
/*
@@ -1006,60 +999,60 @@ sec_PKCS7ReorderAttributes (SEC_PKCS7Attribute **attrs)
* 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;
+ /*
+ * 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;
}
/*
@@ -1067,9 +1060,9 @@ sec_PKCS7ReorderAttributes (SEC_PKCS7Attribute **attrs)
* copy them back into the attrs array we started with.
*/
for (i = 0; i < num_attrs; i++)
- attrs[i] = new_attrs[i];
+ attrs[i] = new_attrs[i];
- PORT_FreeArena (poolp, PR_FALSE);
+ PORT_FreeArena(poolp, PR_FALSE);
return SECSuccess;
}
@@ -1078,7 +1071,6 @@ sec_PKCS7ReorderAttributes (SEC_PKCS7Attribute **attrs)
* -------------------------------------------------------------------
*/
-
/*
* Templates and stuff. Keep these at the end of the file.
*/
@@ -1087,18 +1079,16 @@ sec_PKCS7ReorderAttributes (SEC_PKCS7Attribute **attrs)
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;
+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) },
+ 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 },
+ 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 }
};
@@ -1106,51 +1096,51 @@ const SEC_ASN1Template sec_PKCS7ContentInfoTemplate[] = {
static const SEC_ASN1Template SEC_PKCS7SignerInfoTemplate[] = {
{ SEC_ASN1_SEQUENCE,
- 0, NULL, sizeof(SEC_PKCS7SignerInfo) },
+ 0, NULL, sizeof(SEC_PKCS7SignerInfo) },
{ SEC_ASN1_INTEGER,
- offsetof(SEC_PKCS7SignerInfo,version) },
+ offsetof(SEC_PKCS7SignerInfo, version) },
{ SEC_ASN1_POINTER | SEC_ASN1_XTRN,
- offsetof(SEC_PKCS7SignerInfo,issuerAndSN),
- SEC_ASN1_SUB(CERT_IssuerAndSNTemplate) },
+ offsetof(SEC_PKCS7SignerInfo, issuerAndSN),
+ SEC_ASN1_SUB(CERT_IssuerAndSNTemplate) },
{ SEC_ASN1_INLINE | SEC_ASN1_XTRN,
- offsetof(SEC_PKCS7SignerInfo,digestAlg),
- SEC_ASN1_SUB(SECOID_AlgorithmIDTemplate) },
+ 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 },
+ 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) },
+ offsetof(SEC_PKCS7SignerInfo, digestEncAlg),
+ SEC_ASN1_SUB(SECOID_AlgorithmIDTemplate) },
{ SEC_ASN1_OCTET_STRING,
- offsetof(SEC_PKCS7SignerInfo,encDigest) },
+ 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 },
+ 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) },
+ 0, NULL, sizeof(SEC_PKCS7SignedData) },
{ SEC_ASN1_INTEGER,
- offsetof(SEC_PKCS7SignedData,version) },
+ offsetof(SEC_PKCS7SignedData, version) },
{ SEC_ASN1_SET_OF | SEC_ASN1_XTRN,
- offsetof(SEC_PKCS7SignedData,digestAlgorithms),
- SEC_ASN1_SUB(SECOID_AlgorithmIDTemplate) },
+ 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) },
+ 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 },
+ offsetof(SEC_PKCS7SignedData, signerInfos),
+ SEC_PKCS7SignerInfoTemplate },
{ 0 }
};
@@ -1160,46 +1150,46 @@ static const SEC_ASN1Template SEC_PointerToPKCS7SignedDataTemplate[] = {
static const SEC_ASN1Template SEC_PKCS7RecipientInfoTemplate[] = {
{ SEC_ASN1_SEQUENCE,
- 0, NULL, sizeof(SEC_PKCS7RecipientInfo) },
+ 0, NULL, sizeof(SEC_PKCS7RecipientInfo) },
{ SEC_ASN1_INTEGER,
- offsetof(SEC_PKCS7RecipientInfo,version) },
+ offsetof(SEC_PKCS7RecipientInfo, version) },
{ SEC_ASN1_POINTER | SEC_ASN1_XTRN,
- offsetof(SEC_PKCS7RecipientInfo,issuerAndSN),
- SEC_ASN1_SUB(CERT_IssuerAndSNTemplate) },
+ offsetof(SEC_PKCS7RecipientInfo, issuerAndSN),
+ SEC_ASN1_SUB(CERT_IssuerAndSNTemplate) },
{ SEC_ASN1_INLINE | SEC_ASN1_XTRN,
- offsetof(SEC_PKCS7RecipientInfo,keyEncAlg),
- SEC_ASN1_SUB(SECOID_AlgorithmIDTemplate) },
+ offsetof(SEC_PKCS7RecipientInfo, keyEncAlg),
+ SEC_ASN1_SUB(SECOID_AlgorithmIDTemplate) },
{ SEC_ASN1_OCTET_STRING,
- offsetof(SEC_PKCS7RecipientInfo,encKey) },
+ offsetof(SEC_PKCS7RecipientInfo, encKey) },
{ 0 }
};
static const SEC_ASN1Template SEC_PKCS7EncryptedContentInfoTemplate[] = {
{ SEC_ASN1_SEQUENCE | SEC_ASN1_MAY_STREAM,
- 0, NULL, sizeof(SEC_PKCS7EncryptedContentInfo) },
+ 0, NULL, sizeof(SEC_PKCS7EncryptedContentInfo) },
{ SEC_ASN1_OBJECT_ID,
- offsetof(SEC_PKCS7EncryptedContentInfo,contentType) },
+ offsetof(SEC_PKCS7EncryptedContentInfo, contentType) },
{ SEC_ASN1_INLINE | SEC_ASN1_XTRN,
- offsetof(SEC_PKCS7EncryptedContentInfo,contentEncAlg),
- SEC_ASN1_SUB(SECOID_AlgorithmIDTemplate) },
+ 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) },
+ 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) },
+ 0, NULL, sizeof(SEC_PKCS7EnvelopedData) },
{ SEC_ASN1_INTEGER,
- offsetof(SEC_PKCS7EnvelopedData,version) },
+ offsetof(SEC_PKCS7EnvelopedData, version) },
{ SEC_ASN1_SET_OF,
- offsetof(SEC_PKCS7EnvelopedData,recipientInfos),
- SEC_PKCS7RecipientInfoTemplate },
+ offsetof(SEC_PKCS7EnvelopedData, recipientInfos),
+ SEC_PKCS7RecipientInfoTemplate },
{ SEC_ASN1_INLINE,
- offsetof(SEC_PKCS7EnvelopedData,encContentInfo),
- SEC_PKCS7EncryptedContentInfoTemplate },
+ offsetof(SEC_PKCS7EnvelopedData, encContentInfo),
+ SEC_PKCS7EncryptedContentInfoTemplate },
{ 0 }
};
@@ -1209,50 +1199,50 @@ static const SEC_ASN1Template SEC_PointerToPKCS7EnvelopedDataTemplate[] = {
static const SEC_ASN1Template SEC_PKCS7SignedAndEnvelopedDataTemplate[] = {
{ SEC_ASN1_SEQUENCE | SEC_ASN1_MAY_STREAM,
- 0, NULL, sizeof(SEC_PKCS7SignedAndEnvelopedData) },
+ 0, NULL, sizeof(SEC_PKCS7SignedAndEnvelopedData) },
{ SEC_ASN1_INTEGER,
- offsetof(SEC_PKCS7SignedAndEnvelopedData,version) },
+ offsetof(SEC_PKCS7SignedAndEnvelopedData, version) },
{ SEC_ASN1_SET_OF,
- offsetof(SEC_PKCS7SignedAndEnvelopedData,recipientInfos),
- SEC_PKCS7RecipientInfoTemplate },
+ offsetof(SEC_PKCS7SignedAndEnvelopedData, recipientInfos),
+ SEC_PKCS7RecipientInfoTemplate },
{ SEC_ASN1_SET_OF | SEC_ASN1_XTRN,
- offsetof(SEC_PKCS7SignedAndEnvelopedData,digestAlgorithms),
- SEC_ASN1_SUB(SECOID_AlgorithmIDTemplate) },
+ offsetof(SEC_PKCS7SignedAndEnvelopedData, digestAlgorithms),
+ SEC_ASN1_SUB(SECOID_AlgorithmIDTemplate) },
{ SEC_ASN1_INLINE,
- offsetof(SEC_PKCS7SignedAndEnvelopedData,encContentInfo),
- SEC_PKCS7EncryptedContentInfoTemplate },
+ 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_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_XTRN | 1,
+ offsetof(SEC_PKCS7SignedAndEnvelopedData, crls),
+ SEC_ASN1_SUB(CERT_SetOfSignedCrlTemplate) },
{ SEC_ASN1_SET_OF,
- offsetof(SEC_PKCS7SignedAndEnvelopedData,signerInfos),
- SEC_PKCS7SignerInfoTemplate },
+ offsetof(SEC_PKCS7SignedAndEnvelopedData, signerInfos),
+ SEC_PKCS7SignerInfoTemplate },
{ 0 }
};
static const SEC_ASN1Template
-SEC_PointerToPKCS7SignedAndEnvelopedDataTemplate[] = {
- { SEC_ASN1_POINTER, 0, SEC_PKCS7SignedAndEnvelopedDataTemplate }
-};
+ 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) },
+ 0, NULL, sizeof(SEC_PKCS7DigestedData) },
{ SEC_ASN1_INTEGER,
- offsetof(SEC_PKCS7DigestedData,version) },
+ offsetof(SEC_PKCS7DigestedData, version) },
{ SEC_ASN1_INLINE | SEC_ASN1_XTRN,
- offsetof(SEC_PKCS7DigestedData,digestAlg),
- SEC_ASN1_SUB(SECOID_AlgorithmIDTemplate) },
+ offsetof(SEC_PKCS7DigestedData, digestAlg),
+ SEC_ASN1_SUB(SECOID_AlgorithmIDTemplate) },
{ SEC_ASN1_INLINE,
- offsetof(SEC_PKCS7DigestedData,contentInfo),
- sec_PKCS7ContentInfoTemplate },
+ offsetof(SEC_PKCS7DigestedData, contentInfo),
+ sec_PKCS7ContentInfoTemplate },
{ SEC_ASN1_OCTET_STRING,
- offsetof(SEC_PKCS7DigestedData,digest) },
+ offsetof(SEC_PKCS7DigestedData, digest) },
{ 0 }
};
@@ -1262,12 +1252,12 @@ static const SEC_ASN1Template SEC_PointerToPKCS7DigestedDataTemplate[] = {
static const SEC_ASN1Template SEC_PKCS7EncryptedDataTemplate[] = {
{ SEC_ASN1_SEQUENCE | SEC_ASN1_MAY_STREAM,
- 0, NULL, sizeof(SEC_PKCS7EncryptedData) },
+ 0, NULL, sizeof(SEC_PKCS7EncryptedData) },
{ SEC_ASN1_INTEGER,
- offsetof(SEC_PKCS7EncryptedData,version) },
+ offsetof(SEC_PKCS7EncryptedData, version) },
{ SEC_ASN1_INLINE,
- offsetof(SEC_PKCS7EncryptedData,encContentInfo),
- SEC_PKCS7EncryptedContentInfoTemplate },
+ offsetof(SEC_PKCS7EncryptedData, encContentInfo),
+ SEC_PKCS7EncryptedContentInfoTemplate },
{ 0 }
};
@@ -1282,34 +1272,34 @@ sec_pkcs7_choose_content_template(void *src_or_dest, PRBool encoding)
SEC_PKCS7ContentInfo *cinfo;
SECOidTag kind;
- PORT_Assert (src_or_dest != NULL);
+ PORT_Assert(src_or_dest != NULL);
if (src_or_dest == NULL)
- return NULL;
+ return NULL;
- cinfo = (SEC_PKCS7ContentInfo*)src_or_dest;
- kind = SEC_PKCS7ContentType (cinfo);
+ 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;
+ 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;
}
diff --git a/nss/lib/pkcs7/p7local.h b/nss/lib/pkcs7/p7local.h
index a9b7887..ad37c3a 100644
--- a/nss/lib/pkcs7/p7local.h
+++ b/nss/lib/pkcs7/p7local.h
@@ -25,7 +25,6 @@ extern const SEC_ASN1Template sec_PKCS7ContentInfoTemplate[];
/* opaque objects */
typedef struct sec_pkcs7_cipher_object sec_PKCS7CipherObject;
-
/************************************************************************/
SEC_BEGIN_PROTOS
@@ -36,49 +35,48 @@ SEC_BEGIN_PROTOS
* 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);
+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);
+extern SECItem *sec_PKCS7AttributeValue(SEC_PKCS7Attribute *attr);
/*
* Encode a set of attributes (found in "src").
*/
-extern SECItem *sec_PKCS7EncodeAttributes (PLArenaPool *poolp,
- SECItem *dest, void *src);
+extern SECItem *sec_PKCS7EncodeAttributes(PLArenaPool *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);
-
+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);
+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 (PLArenaPool *poolp, PK11SymKey *key,
- SECOidTag algtag, SECAlgorithmID *algid);
+sec_PKCS7CreateEncryptObject(PLArenaPool *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);
+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?
@@ -96,12 +94,12 @@ extern void sec_PKCS7DestroyEncryptObject (sec_PKCS7CipherObject *obj);
* 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);
+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
@@ -109,14 +107,14 @@ extern unsigned int sec_PKCS7EncryptLength (sec_PKCS7CipherObject *obj,
* "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);
+ */
+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
@@ -124,14 +122,14 @@ extern SECStatus sec_PKCS7Decrypt (sec_PKCS7CipherObject *obj,
* "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);
+ */
+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
diff --git a/nss/lib/pkcs7/pkcs7.gyp b/nss/lib/pkcs7/pkcs7.gyp
new file mode 100644
index 0000000..8a73a29
--- /dev/null
+++ b/nss/lib/pkcs7/pkcs7.gyp
@@ -0,0 +1,29 @@
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+{
+ 'includes': [
+ '../../coreconf/config.gypi'
+ ],
+ 'targets': [
+ {
+ 'target_name': 'pkcs7',
+ 'type': 'static_library',
+ 'sources': [
+ 'certread.c',
+ 'p7common.c',
+ 'p7create.c',
+ 'p7decode.c',
+ 'p7encode.c',
+ 'p7local.c',
+ 'secmime.c'
+ ],
+ 'dependencies': [
+ '<(DEPTH)/exports.gyp:nss_exports'
+ ]
+ }
+ ],
+ 'variables': {
+ 'module': 'nss'
+ }
+} \ No newline at end of file
diff --git a/nss/lib/pkcs7/pkcs7t.h b/nss/lib/pkcs7/pkcs7t.h
index d01b1ea..4ef8902 100644
--- a/nss/lib/pkcs7/pkcs7t.h
+++ b/nss/lib/pkcs7/pkcs7t.h
@@ -23,7 +23,6 @@ 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
@@ -59,7 +58,7 @@ typedef struct SEC_PKCS7SignedDataStr SEC_PKCS7SignedData;
typedef struct SEC_PKCS7EncryptedContentInfoStr SEC_PKCS7EncryptedContentInfo;
typedef struct SEC_PKCS7EnvelopedDataStr SEC_PKCS7EnvelopedData;
typedef struct SEC_PKCS7SignedAndEnvelopedDataStr
- SEC_PKCS7SignedAndEnvelopedData;
+ SEC_PKCS7SignedAndEnvelopedData;
typedef struct SEC_PKCS7SignerInfoStr SEC_PKCS7SignerInfo;
typedef struct SEC_PKCS7RecipientInfoStr SEC_PKCS7RecipientInfo;
typedef struct SEC_PKCS7DigestedDataStr SEC_PKCS7DigestedData;
@@ -73,20 +72,20 @@ typedef struct SEC_PKCS7EncryptedDataStr SEC_PKCS7EncryptedData;
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 */
+ 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;
+ SECItem *data;
+ SEC_PKCS7DigestedData *digestedData;
+ SEC_PKCS7EncryptedData *encryptedData;
+ SEC_PKCS7EnvelopedData *envelopedData;
+ SEC_PKCS7SignedData *signedData;
+ SEC_PKCS7SignedAndEnvelopedData *signedAndEnvelopedData;
} content;
};
@@ -97,25 +96,25 @@ struct SEC_PKCS7SignedDataStr {
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 */
+ 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* */
+#define SEC_PKCS7_SIGNED_DATA_VERSION 1 /* what we *create* */
struct SEC_PKCS7EncryptedContentInfoStr {
- SECOidData *contentTypeTag; /* local; not part of encoding */
+ 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) */
+ 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 {
@@ -123,7 +122,7 @@ struct SEC_PKCS7EnvelopedDataStr {
SEC_PKCS7RecipientInfo **recipientInfos;
SEC_PKCS7EncryptedContentInfo encContentInfo;
};
-#define SEC_PKCS7_ENVELOPED_DATA_VERSION 0 /* what we *create* */
+#define SEC_PKCS7_ENVELOPED_DATA_VERSION 0 /* what we *create* */
struct SEC_PKCS7SignedAndEnvelopedDataStr {
SECItem version;
@@ -133,12 +132,12 @@ struct SEC_PKCS7SignedAndEnvelopedDataStr {
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 */
+ 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* */
+#define SEC_PKCS7_SIGNED_AND_ENVELOPED_DATA_VERSION 1 /* what we *create* */
struct SEC_PKCS7SignerInfoStr {
SECItem version;
@@ -148,19 +147,19 @@ struct SEC_PKCS7SignerInfoStr {
SECAlgorithmID digestEncAlg;
SECItem encDigest;
SEC_PKCS7Attribute **unAuthAttr;
- CERTCertificate *cert; /* local; not part of encoding */
- CERTCertificateList *certList; /* local; not part of encoding */
+ CERTCertificate *cert; /* local; not part of encoding */
+ CERTCertificateList *certList; /* local; not part of encoding */
};
-#define SEC_PKCS7_SIGNER_INFO_VERSION 1 /* what we *create* */
+#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 */
+ CERTCertificate *cert; /* local; not part of encoding */
};
-#define SEC_PKCS7_RECIPIENT_INFO_VERSION 0 /* what we *create* */
+#define SEC_PKCS7_RECIPIENT_INFO_VERSION 0 /* what we *create* */
struct SEC_PKCS7DigestedDataStr {
SECItem version;
@@ -168,13 +167,13 @@ struct SEC_PKCS7DigestedDataStr {
SEC_PKCS7ContentInfo contentInfo;
SECItem digest;
};
-#define SEC_PKCS7_DIGESTED_DATA_VERSION 0 /* what we *create* */
+#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* */
+#define SEC_PKCS7_ENCRYPTED_DATA_VERSION 0 /* what we *create* */
/*
* See comment above about this type not really belonging to PKCS7.
@@ -182,10 +181,10 @@ struct SEC_PKCS7EncryptedDataStr {
struct SEC_PKCS7AttributeStr {
/* The following fields make up an encoded Attribute: */
SECItem type;
- SECItem **values; /* data may or may not be encoded */
+ 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 */
+ PRBool encoded; /* when true, values are encoded */
};
/*
@@ -196,9 +195,9 @@ struct SEC_PKCS7AttributeStr {
* 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);
+typedef void (*SEC_PKCS7DecoderContentCallback)(void *arg,
+ const char *buf,
+ unsigned long len);
/*
* Type of function passed to SEC_PKCS7Encode or SEC_PKCS7EncoderStart.
@@ -207,10 +206,9 @@ typedef void (* SEC_PKCS7DecoderContentCallback)(void *arg,
* 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);
-
+typedef void (*SEC_PKCS7EncoderOutputCallback)(void *arg,
+ const char *buf,
+ unsigned long len);
/*
* Type of function passed to SEC_PKCS7Decode or SEC_PKCS7DecoderStart
@@ -218,10 +216,10 @@ typedef void (* SEC_PKCS7EncoderOutputCallback)(void *arg,
* 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);
+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
@@ -229,7 +227,7 @@ typedef PK11SymKey * (* SEC_PKCS7GetDecryptKeyCallback)(void *arg,
* is not specified for content types which require decryption, the
* decryption will be disallowed.
*/
-typedef PRBool (* SEC_PKCS7DecryptionAllowedCallback)(SECAlgorithmID *algid,
- PK11SymKey *bulkkey);
+typedef PRBool (*SEC_PKCS7DecryptionAllowedCallback)(SECAlgorithmID *algid,
+ PK11SymKey *bulkkey);
#endif /* _PKCS7T_H_ */
diff --git a/nss/lib/pkcs7/secmime.c b/nss/lib/pkcs7/secmime.c
index 12a1e20..ca1046a 100644
--- a/nss/lib/pkcs7/secmime.c
+++ b/nss/lib/pkcs7/secmime.c
@@ -10,7 +10,7 @@
#include "secmime.h"
#include "secoid.h"
#include "pk11func.h"
-#include "ciferfam.h" /* for CIPHER_FAMILY symbols */
+#include "ciferfam.h" /* for CIPHER_FAMILY symbols */
#include "secasn1.h"
#include "secitem.h"
#include "cert.h"
@@ -27,12 +27,12 @@ typedef struct smime_cipher_map_struct {
* 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
+#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 */
+#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 };
@@ -44,24 +44,23 @@ 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 },
+ { 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 },
+ { 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 }
+ { 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 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;
@@ -70,119 +69,114 @@ static PRBool smime_prefs_changed = PR_TRUE;
static unsigned long smime_policy_bits = 0;
-
static int
-smime_mapi_by_cipher (unsigned long cipher)
+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 (smime_cipher_maps[i].cipher == cipher)
+ break;
}
if (i == smime_symmetric_count)
- return -1;
+ return -1;
return i;
}
-
/*
* this function locally records the user's preference
*/
-SECStatus
+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;
+ /*
+ * 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;
+ /*
+ * 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);
+ PORT_Assert(mask == CIPHER_FAMILYID_SMIME);
if (mask != CIPHER_FAMILYID_SMIME) {
- /* XXX set an error! */
- return SECFailure;
+ /* 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;
- }
+ 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;
+ smime_newprefs[smime_current_pref_index++] = which;
}
return SECSuccess;
}
-
/*
* this function locally records the export policy
*/
-SECStatus
+SECStatus
SECMIME_SetPolicy(long which, int on)
{
unsigned long mask;
- PORT_Assert ((which & CIPHER_FAMILYID_MASK) == CIPHER_FAMILYID_SMIME);
+ PORT_Assert((which & CIPHER_FAMILYID_MASK) == CIPHER_FAMILYID_SMIME);
if ((which & CIPHER_FAMILYID_MASK) != CIPHER_FAMILYID_SMIME) {
- /* XXX set an error! */
- return SECFailure;
+ /* XXX set an error! */
+ return SECFailure;
}
which &= ~CIPHER_FAMILYID_MASK;
- PORT_Assert (which < 32); /* bits in the long */
+ PORT_Assert(which < 32); /* bits in the long */
if (which >= 32) {
- /* XXX set an error! */
- return SECFailure;
+ /* XXX set an error! */
+ return SECFailure;
}
mask = 1UL << which;
if (on) {
- smime_policy_bits |= mask;
+ smime_policy_bits |= mask;
} else {
- smime_policy_bits &= ~mask;
+ 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
@@ -190,77 +184,72 @@ SECMIME_SetPolicy(long which, int on)
* and return it. If no match can be made, -1 is returned.
*/
static long
-smime_policy_algorithm (SECAlgorithmID *algid, PK11SymKey *key)
+smime_policy_algorithm(SECAlgorithmID *algid, PK11SymKey *key)
{
SECOidTag algtag;
- algtag = SECOID_GetAlgorithmTag (algid);
+ 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;
+ 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;
+ case SEC_OID_RC5_CBC_PAD:
+ PORT_Assert(0); /* XXX need to pull out parameters and match */
+ break;
#endif
- default:
- break;
+ default:
+ break;
}
return -1;
}
-
static PRBool
-smime_cipher_allowed (unsigned long which)
+smime_cipher_allowed(unsigned long which)
{
unsigned long mask;
which &= ~CIPHER_FAMILYID_MASK;
- PORT_Assert (which < 32); /* bits per long (min) */
+ PORT_Assert(which < 32); /* bits per long (min) */
if (which >= 32)
- return PR_FALSE;
+ return PR_FALSE;
mask = 1UL << which;
if ((mask & smime_policy_bits) == 0)
- return PR_FALSE;
+ return PR_FALSE;
return PR_TRUE;
}
-
PRBool
SECMIME_DecryptionAllowed(SECAlgorithmID *algid, PK11SymKey *key)
{
long which;
- which = smime_policy_algorithm (algid, key);
+ which = smime_policy_algorithm(algid, key);
if (which < 0)
- return PR_FALSE;
+ return PR_FALSE;
- return smime_cipher_allowed ((unsigned long)which);
+ return smime_cipher_allowed((unsigned long)which);
}
-
/*
* Does the current policy allow *any* S/MIME encryption (or decryption)?
*
@@ -273,93 +262,89 @@ SECMIME_DecryptionAllowed(SECAlgorithmID *algid, PK11SymKey *key)
*
* 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)
+ * (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)
+SECMIME_EncryptionPossible(void)
{
if (smime_policy_bits != 0)
- return PR_TRUE;
+ 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 */
+ 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) },
+ 0, NULL, sizeof(smime_capability) },
{ SEC_ASN1_OBJECT_ID,
- offsetof(smime_capability,capabilityID), },
+ offsetof(smime_capability, capabilityID) },
{ SEC_ASN1_OPTIONAL | SEC_ASN1_ANY,
- offsetof(smime_capability,parameters), },
- { 0, }
+ 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)
+smime_fill_capability(smime_capability *cap)
{
unsigned long cipher;
SECOidTag algtag;
int i;
- algtag = SECOID_FindOIDTag (&(cap->capabilityID));
+ 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 (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;
+ cipher = 0;
else
- cipher = smime_cipher_maps[i].cipher;
+ cipher = smime_cipher_maps[i].cipher;
cap->cipher = cipher;
cap->capIDTag = algtag;
}
-
static long
-smime_choose_cipher (CERTCertificate *scert, CERTCertificate **rcerts)
+smime_choose_cipher(CERTCertificate *scert, CERTCertificate **rcerts)
{
PLArenaPool *poolp;
long chosen_cipher;
@@ -369,25 +354,25 @@ smime_choose_cipher (CERTCertificate *scert, CERTCertificate **rcerts)
int rcount, mapi, max;
if (smime_policy_bits == 0) {
- PORT_SetError (SEC_ERROR_BAD_EXPORT_ALGORITHM);
- return -1;
+ PORT_SetError(SEC_ERROR_BAD_EXPORT_ALGORITHM);
+ return -1;
}
- chosen_cipher = SMIME_RC2_CBC_40; /* the default, LCD */
+ chosen_cipher = SMIME_RC2_CBC_40; /* the default, LCD */
- poolp = PORT_NewArena (1024); /* XXX what is right value? */
+ poolp = PORT_NewArena(1024); /* XXX what is right value? */
if (poolp == NULL)
- goto done;
+ goto done;
- cipher_abilities = (int*)PORT_ArenaZAlloc (poolp,
- smime_symmetric_count * sizeof(int));
+ cipher_abilities = (int *)PORT_ArenaZAlloc(poolp,
+ smime_symmetric_count * sizeof(int));
if (cipher_abilities == NULL)
- goto done;
+ goto done;
- cipher_votes = (int*)PORT_ArenaZAlloc (poolp,
- smime_symmetric_count * sizeof(int));
+ cipher_votes = (int *)PORT_ArenaZAlloc(poolp,
+ smime_symmetric_count * sizeof(int));
if (cipher_votes == NULL)
- goto done;
+ goto done;
/*
* XXX Should have a #define somewhere which specifies default
@@ -395,127 +380,125 @@ smime_choose_cipher (CERTCertificate *scert, CERTCertificate **rcerts)
*/
/* Make triple-DES the strong cipher. */
- strong_mapi = smime_mapi_by_cipher (SMIME_DES_EDE3_168);
+ strong_mapi = smime_mapi_by_cipher(SMIME_DES_EDE3_168);
- PORT_Assert (strong_mapi >= 0);
+ 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);
+ 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? */
+ 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);
+ 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)
+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;
+ 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;
+ 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;
+ 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.
*
@@ -535,10 +518,10 @@ smime_keysize_by_cipher (unsigned long which)
*/
SEC_PKCS7ContentInfo *
SECMIME_CreateEncrypted(CERTCertificate *scert,
- CERTCertificate **rcerts,
- CERTCertDBHandle *certdb,
- SECKEYGetPasswordKey pwfn,
- void *pwfn_arg)
+ CERTCertificate **rcerts,
+ CERTCertDBHandle *certdb,
+ SECKEYGetPasswordKey pwfn,
+ void *pwfn_arg)
{
SEC_PKCS7ContentInfo *cinfo;
long cipher;
@@ -546,13 +529,13 @@ SECMIME_CreateEncrypted(CERTCertificate *scert,
int keysize;
int mapi, rci;
- cipher = smime_choose_cipher (scert, rcerts);
+ cipher = smime_choose_cipher(scert, rcerts);
if (cipher < 0)
- return NULL;
+ return NULL;
- mapi = smime_mapi_by_cipher (cipher);
+ mapi = smime_mapi_by_cipher(cipher);
if (mapi < 0)
- return NULL;
+ return NULL;
/*
* XXX This is stretching it -- CreateEnvelopedData should probably
@@ -563,36 +546,34 @@ SECMIME_CreateEncrypted(CERTCertificate *scert,
* block size). Work this out into a better API!
*/
encalg = smime_cipher_maps[mapi].algtag;
- keysize = smime_keysize_by_cipher (cipher);
+ keysize = smime_keysize_by_cipher(cipher);
if (keysize < 0)
- return NULL;
+ return NULL;
- cinfo = SEC_PKCS7CreateEnvelopedData (scert, certUsageEmailRecipient,
- certdb, encalg, keysize,
- pwfn, pwfn_arg);
+ cinfo = SEC_PKCS7CreateEnvelopedData(scert, certUsageEmailRecipient,
+ certdb, encalg, keysize,
+ pwfn, pwfn_arg);
if (cinfo == NULL)
- return 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;
- }
+ 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_init_caps(void)
{
smime_capability *cap;
smime_cipher_map *map;
@@ -600,141 +581,138 @@ smime_init_caps (void)
SECStatus rv;
int i;
- if (smime_encoded_caps != NULL && (! smime_prefs_changed))
- return SECSuccess;
+ 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;
+ 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;
+ 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:
+ 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.
+ (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.
+ (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
+ 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];
+ 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;
+ 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++;
+ 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);
+ smime_encoded_caps = SEC_ASN1EncodeItem(NULL, NULL, &smime_capabilities,
+ smime_capabilities_template);
if (smime_encoded_caps == NULL)
- return SECFailure;
+ return SECFailure;
return SECSuccess;
}
-
static SECStatus
-smime_add_profile (CERTCertificate *cert, SEC_PKCS7ContentInfo *cinfo)
+smime_add_profile(CERTCertificate *cert, SEC_PKCS7ContentInfo *cinfo)
{
- PORT_Assert (smime_prefs_complete);
- if (! smime_prefs_complete)
- return SECFailure;
+ 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;
+ SECStatus rv;
- rv = smime_init_caps();
- if (rv != SECSuccess)
- return rv;
+ rv = smime_init_caps();
+ if (rv != SECSuccess)
+ return rv;
- PORT_Assert (smime_encoded_caps != NULL);
+ PORT_Assert(smime_encoded_caps != NULL);
}
- return SEC_PKCS7AddSignedAttribute (cinfo, SEC_OID_PKCS9_SMIME_CAPABILITIES,
- smime_encoded_caps);
+ return SEC_PKCS7AddSignedAttribute(cinfo, SEC_OID_PKCS9_SMIME_CAPABILITIES,
+ smime_encoded_caps);
}
-
/*
* Start an S/MIME signing context.
*
@@ -747,7 +725,7 @@ smime_add_profile (CERTCertificate *cert, SEC_PKCS7ContentInfo *cinfo)
*
* "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
@@ -766,13 +744,13 @@ smime_add_profile (CERTCertificate *cert, SEC_PKCS7ContentInfo *cinfo)
*/
SEC_PKCS7ContentInfo *
-SECMIME_CreateSigned (CERTCertificate *scert,
- CERTCertificate *ecert,
- CERTCertDBHandle *certdb,
- SECOidTag digestalg,
- SECItem *digest,
- SECKEYGetPasswordKey pwfn,
- void *pwfn_arg)
+SECMIME_CreateSigned(CERTCertificate *scert,
+ CERTCertificate *ecert,
+ CERTCertDBHandle *certdb,
+ SECOidTag digestalg,
+ SECItem *digest,
+ SECKEYGetPasswordKey pwfn,
+ void *pwfn_arg)
{
SEC_PKCS7ContentInfo *cinfo;
SECStatus rv;
@@ -780,15 +758,15 @@ SECMIME_CreateSigned (CERTCertificate *scert,
/* 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);
+ cinfo = SEC_PKCS7CreateSignedData(scert, certUsageEmailSigner,
+ certdb, digestalg, digest,
+ pwfn, pwfn_arg);
if (cinfo == NULL)
- return NULL;
+ return NULL;
- if (SEC_PKCS7IncludeCertChain (cinfo, NULL) != SECSuccess) {
- SEC_PKCS7DestroyContentInfo (cinfo);
- return NULL;
+ if (SEC_PKCS7IncludeCertChain(cinfo, NULL) != SECSuccess) {
+ SEC_PKCS7DestroyContentInfo(cinfo);
+ return NULL;
}
/* if the encryption cert and the signing cert differ, then include
@@ -797,26 +775,26 @@ SECMIME_CreateSigned (CERTCertificate *scert,
/* 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;
- }
+ 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);
+ 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);
+ rv = smime_add_profile(ecert, cinfo);
+ PORT_Assert(rv == SECSuccess);
return cinfo;
}
diff --git a/nss/lib/pkcs7/secmime.h b/nss/lib/pkcs7/secmime.h
index a813d85..683cd8d 100644
--- a/nss/lib/pkcs7/secmime.h
+++ b/nss/lib/pkcs7/secmime.h
@@ -12,7 +12,6 @@
#include "secpkcs7.h"
-
/************************************************************************/
SEC_BEGIN_PROTOS
@@ -117,10 +116,10 @@ extern PRBool SECMIME_EncryptionPossible(void);
* (Retrieve specific errors via PORT_GetError()/XP_GetError().)
*/
extern SEC_PKCS7ContentInfo *SECMIME_CreateEncrypted(CERTCertificate *scert,
- CERTCertificate **rcerts,
- CERTCertDBHandle *certdb,
- SECKEYGetPasswordKey pwfn,
- void *pwfn_arg);
+ CERTCertificate **rcerts,
+ CERTCertDBHandle *certdb,
+ SECKEYGetPasswordKey pwfn,
+ void *pwfn_arg);
/*
* Start an S/MIME signing context.
@@ -130,7 +129,7 @@ extern SEC_PKCS7ContentInfo *SECMIME_CreateEncrypted(CERTCertificate *scert,
*
* "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
@@ -148,12 +147,12 @@ extern SEC_PKCS7ContentInfo *SECMIME_CreateEncrypted(CERTCertificate *scert,
* (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);
+ CERTCertificate *ecert,
+ CERTCertDBHandle *certdb,
+ SECOidTag digestalg,
+ SECItem *digest,
+ SECKEYGetPasswordKey pwfn,
+ void *pwfn_arg);
/************************************************************************/
SEC_END_PROTOS
diff --git a/nss/lib/pkcs7/secpkcs7.h b/nss/lib/pkcs7/secpkcs7.h
index 22f147a..d95c7d8 100644
--- a/nss/lib/pkcs7/secpkcs7.h
+++ b/nss/lib/pkcs7/secpkcs7.h
@@ -23,13 +23,13 @@ extern const SEC_ASN1Template sec_PKCS7ContentInfoTemplate[];
SEC_BEGIN_PROTOS
/************************************************************************
- * Miscellaneous
+ * Miscellaneous
************************************************************************/
/*
* Returns the content type of the given contentInfo.
*/
-extern SECOidTag SEC_PKCS7ContentType (SEC_PKCS7ContentInfo *cinfo);
+extern SECOidTag SEC_PKCS7ContentType(SEC_PKCS7ContentInfo *cinfo);
/*
* Destroy a PKCS7 contentInfo and all of its sub-pieces.
@@ -49,35 +49,34 @@ SEC_PKCS7CopyContentInfo(SEC_PKCS7ContentInfo *contentInfo);
extern SECItem *SEC_PKCS7GetContent(SEC_PKCS7ContentInfo *cinfo);
/************************************************************************
- * PKCS7 Decoding, Verification, etc..
+ * 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);
+ 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);
+ 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);
+ 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);
@@ -87,8 +86,8 @@ extern PRBool SEC_PKCS7ContainsCertsOrCrls(SEC_PKCS7ContentInfo *cinfo);
* 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_PKCS7IsContentEmpty(SEC_PKCS7ContentInfo *cinfo, unsigned int minLen);
extern PRBool SEC_PKCS7ContentIsEncrypted(SEC_PKCS7ContentInfo *cinfo);
@@ -104,32 +103,32 @@ 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".
+ * 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.
+ * 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);
+ 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".
+ * 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.
+ * 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);
+ SECCertUsage certusage,
+ const SECItem *detached_digest,
+ HASH_HashType digest_type,
+ PRBool keepcerts);
/*
* SEC_PKCS7VerifyDetachedSignatureAtTime
@@ -138,16 +137,16 @@ extern PRBool SEC_PKCS7VerifyDetachedSignature(SEC_PKCS7ContentInfo *cinfo,
* The verification checks that the signing cert is valid and trusted
* for the purpose specified by "certusage" at time "atTime".
*
- * In addition, if "keepcerts" is true, add any new certificates found
- * into our local database.
+ * In addition, if "keepcerts" is true, add any new certificates found
+ * into our local database.
*/
extern PRBool
SEC_PKCS7VerifyDetachedSignatureAtTime(SEC_PKCS7ContentInfo *cinfo,
- SECCertUsage certusage,
- const SECItem *detached_digest,
- HASH_HashType digest_type,
- PRBool keepcerts,
- PRTime atTime);
+ SECCertUsage certusage,
+ const SECItem *detached_digest,
+ HASH_HashType digest_type,
+ PRBool keepcerts,
+ PRTime atTime);
/*
* SEC_PKCS7GetSignerCommonName, SEC_PKCS7GetSignerEmailAddress
@@ -165,9 +164,8 @@ extern char *SEC_PKCS7GetSignerEmailAddress(SEC_PKCS7ContentInfo *cinfo);
*/
extern SECItem *SEC_PKCS7GetSigningTime(SEC_PKCS7ContentInfo *cinfo);
-
/************************************************************************
- * PKCS7 Creation and Encoding.
+ * PKCS7 Creation and Encoding.
************************************************************************/
/*
@@ -184,7 +182,7 @@ extern SECItem *SEC_PKCS7GetSigningTime(SEC_PKCS7ContentInfo *cinfo);
*
* "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
@@ -199,12 +197,12 @@ extern SECItem *SEC_PKCS7GetSigningTime(SEC_PKCS7ContentInfo *cinfo);
* (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);
+SEC_PKCS7CreateSignedData(CERTCertificate *cert,
+ SECCertUsage certusage,
+ CERTCertDBHandle *certdb,
+ SECOidTag digestalg,
+ SECItem *digest,
+ SECKEYGetPasswordKey pwfn, void *pwfn_arg);
/*
* Create a PKCS7 certs-only container.
@@ -224,9 +222,9 @@ SEC_PKCS7CreateSignedData (CERTCertificate *cert,
* (Retrieve specific errors via PORT_GetError()/XP_GetError().)
*/
extern SEC_PKCS7ContentInfo *
-SEC_PKCS7CreateCertsOnly (CERTCertificate *cert,
- PRBool include_chain,
- CERTCertDBHandle *certdb);
+SEC_PKCS7CreateCertsOnly(CERTCertificate *cert,
+ PRBool include_chain,
+ CERTCertDBHandle *certdb);
/*
* Start a PKCS7 enveloping context.
@@ -255,12 +253,12 @@ SEC_PKCS7CreateCertsOnly (CERTCertificate *cert,
* (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_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.
@@ -274,19 +272,19 @@ SEC_PKCS7CreateEnvelopedData (CERTCertificate *cert,
* 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);
+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);
+SEC_PKCS7CreateEncryptedData(SECOidTag algorithm, int keysize,
+ SECKEYGetPasswordKey pwfn, void *pwfn_arg);
/*
* All of the following things return SECStatus to signal success or failure.
@@ -312,9 +310,9 @@ SEC_PKCS7CreateEncryptedData (SECOidTag algorithm, int keysize,
* that is allowed authenticated attributes); SECFailure will be returned
* if it is not.
*/
-extern SECStatus SEC_PKCS7AddSignedAttribute (SEC_PKCS7ContentInfo *cinfo,
- SECOidTag oidtag,
- SECItem *value);
+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".
@@ -325,9 +323,9 @@ extern SECStatus SEC_PKCS7AddSignedAttribute (SEC_PKCS7ContentInfo *cinfo,
* "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);
+extern SECStatus SEC_PKCS7AddCertChain(SEC_PKCS7ContentInfo *cinfo,
+ CERTCertificate *cert,
+ CERTCertDBHandle *certdb);
/*
* Add "cert" to the set of certs included in "cinfo".
@@ -335,8 +333,8 @@ extern SECStatus SEC_PKCS7AddCertChain (SEC_PKCS7ContentInfo *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);
+extern SECStatus SEC_PKCS7AddCertificate(SEC_PKCS7ContentInfo *cinfo,
+ CERTCertificate *cert);
/*
* Add another recipient to an encrypted message.
@@ -355,10 +353,10 @@ extern SECStatus SEC_PKCS7AddCertificate (SEC_PKCS7ContentInfo *cinfo,
* "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);
+extern SECStatus SEC_PKCS7AddRecipient(SEC_PKCS7ContentInfo *cinfo,
+ CERTCertificate *cert,
+ SECCertUsage certusage,
+ CERTCertDBHandle *certdb);
/*
* Add the signing time to the authenticated (i.e. signed) attributes
@@ -376,7 +374,7 @@ extern SECStatus SEC_PKCS7AddRecipient (SEC_PKCS7ContentInfo *cinfo,
* that is allowed authenticated attributes); SECFailure will be returned
* if it is not.
*/
-extern SECStatus SEC_PKCS7AddSigningTime (SEC_PKCS7ContentInfo *cinfo);
+extern SECStatus SEC_PKCS7AddSigningTime(SEC_PKCS7ContentInfo *cinfo);
/*
* Add the signer's symmetric capabilities to the authenticated
@@ -401,9 +399,8 @@ extern SECStatus SEC_PKCS7AddSymmetricCapabilities(SEC_PKCS7ContentInfo *cinfo);
* "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);
-
+extern SECStatus SEC_PKCS7IncludeCertChain(SEC_PKCS7ContentInfo *cinfo,
+ CERTCertDBHandle *certdb);
/*
* Set the content; it will be included and also hashed and/or encrypted
@@ -413,8 +410,8 @@ extern SECStatus SEC_PKCS7IncludeCertChain (SEC_PKCS7ContentInfo *cinfo,
*
* "buf" points to data of length "len"; it will be copied.
*/
-extern SECStatus SEC_PKCS7SetContent (SEC_PKCS7ContentInfo *cinfo,
- const char *buf, unsigned long len);
+extern SECStatus SEC_PKCS7SetContent(SEC_PKCS7ContentInfo *cinfo,
+ const char *buf, unsigned long len);
/*
* Encode a PKCS7 object, in one shot. All necessary components
@@ -439,12 +436,12 @@ extern SECStatus SEC_PKCS7SetContent (SEC_PKCS7ContentInfo *cinfo,
*
* "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);
+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
@@ -473,12 +470,12 @@ extern SECStatus SEC_PKCS7Encode (SEC_PKCS7ContentInfo *cinfo,
*
* "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);
+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
@@ -486,10 +483,10 @@ extern SECItem *SEC_PKCS7EncodeItem (PLArenaPool *pool,
* 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);
+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
@@ -512,17 +509,17 @@ extern SECStatus SEC_PKCS7PrepareForEncode (SEC_PKCS7ContentInfo *cinfo,
* 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);
+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);
+extern SECStatus SEC_PKCS7EncoderUpdate(SEC_PKCS7EncoderContext *p7ecx,
+ const char *buf,
+ unsigned long len);
/*
* No more contents; finish the signature creation, if appropriate,
@@ -534,9 +531,9 @@ extern SECStatus SEC_PKCS7EncoderUpdate (SEC_PKCS7EncoderContext *p7ecx,
*
* "pwfnarg" is an opaque argument to the above callback.
*/
-extern SECStatus SEC_PKCS7EncoderFinish (SEC_PKCS7EncoderContext *p7ecx,
- SECKEYGetPasswordKey pwfn,
- void *pwfnarg);
+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);
@@ -545,9 +542,9 @@ void SEC_PKCS7EncoderAbort(SEC_PKCS7EncoderContext *p7dcx, int error);
* 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);
+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
@@ -559,16 +556,16 @@ SEC_PKCS7GetEncryptionAlgorithm(SEC_PKCS7ContentInfo *cinfo);
* 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
+extern SECStatus
SEC_PKCS7EncryptContents(PLArenaPool *poolp,
- SEC_PKCS7ContentInfo *cinfo,
- SECItem *key,
- void *wincx);
-
+ 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.
@@ -579,19 +576,19 @@ SEC_PKCS7EncryptContents(PLArenaPool *poolp,
* 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
+extern SECStatus
SEC_PKCS7DecryptContents(PLArenaPool *poolp,
- SEC_PKCS7ContentInfo *cinfo,
- SECItem *key,
- void *wincx);
+ 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
+ * be deleted or freed in any way short of calling
* SEC_PKCS7DestroyContentInfo
*/
extern SECItem **
@@ -600,9 +597,8 @@ 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
+extern int
SEC_PKCS7GetKeyLength(SEC_PKCS7ContentInfo *cinfo);
-
/************************************************************************/
SEC_END_PROTOS
diff --git a/nss/lib/pki/asymmkey.c b/nss/lib/pki/asymmkey.c
index 4c8ac9d..ce1f503 100644
--- a/nss/lib/pki/asymmkey.c
+++ b/nss/lib/pki/asymmkey.c
@@ -13,386 +13,349 @@
extern const NSSError NSS_ERROR_NOT_FOUND;
NSS_IMPLEMENT PRStatus
-NSSPrivateKey_Destroy (
- NSSPrivateKey *vk
-)
+NSSPrivateKey_Destroy(
+ NSSPrivateKey *vk)
{
nss_SetError(NSS_ERROR_NOT_FOUND);
return PR_FAILURE;
}
NSS_IMPLEMENT PRStatus
-NSSPrivateKey_DeleteStoredObject (
- NSSPrivateKey *vk,
- NSSCallback *uhh
-)
+NSSPrivateKey_DeleteStoredObject(
+ NSSPrivateKey *vk,
+ NSSCallback *uhh)
{
nss_SetError(NSS_ERROR_NOT_FOUND);
return PR_FAILURE;
}
NSS_IMPLEMENT PRUint32
-NSSPrivateKey_GetSignatureLength (
- NSSPrivateKey *vk
-)
+NSSPrivateKey_GetSignatureLength(
+ NSSPrivateKey *vk)
{
nss_SetError(NSS_ERROR_NOT_FOUND);
return -1;
}
NSS_IMPLEMENT PRUint32
-NSSPrivateKey_GetPrivateModulusLength (
- NSSPrivateKey *vk
-)
+NSSPrivateKey_GetPrivateModulusLength(
+ NSSPrivateKey *vk)
{
nss_SetError(NSS_ERROR_NOT_FOUND);
return -1;
}
NSS_IMPLEMENT PRBool
-NSSPrivateKey_IsStillPresent (
- NSSPrivateKey *vk,
- PRStatus *statusOpt
-)
+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
-)
+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
-)
+NSSPrivateKey_GetTrustDomain(
+ NSSPrivateKey *vk,
+ PRStatus *statusOpt)
{
nss_SetError(NSS_ERROR_NOT_FOUND);
return NULL;
}
NSS_IMPLEMENT NSSToken *
-NSSPrivateKey_GetToken (
- NSSPrivateKey *vk
-)
+NSSPrivateKey_GetToken(NSSPrivateKey *vk)
{
nss_SetError(NSS_ERROR_NOT_FOUND);
return NULL;
}
NSS_IMPLEMENT NSSSlot *
-NSSPrivateKey_GetSlot (
- NSSPrivateKey *vk
-)
+NSSPrivateKey_GetSlot(NSSPrivateKey *vk)
{
nss_SetError(NSS_ERROR_NOT_FOUND);
return NULL;
}
NSS_IMPLEMENT NSSModule *
-NSSPrivateKey_GetModule (
- NSSPrivateKey *vk
-)
+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
-)
+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
-)
+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
-)
+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
-)
+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
-)
+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? } */
-)
+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
-)
+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
-)
+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
-)
+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
-)
+NSSPublicKey_Destroy(NSSPublicKey *bk)
{
nss_SetError(NSS_ERROR_NOT_FOUND);
return PR_FAILURE;
}
NSS_IMPLEMENT PRStatus
-NSSPublicKey_DeleteStoredObject (
- NSSPublicKey *bk,
- NSSCallback *uhh
-)
+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
-)
+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
-)
+NSSPublicKey_GetTrustDomain(
+ NSSPublicKey *bk,
+ PRStatus *statusOpt)
{
nss_SetError(NSS_ERROR_NOT_FOUND);
return NULL;
}
NSS_IMPLEMENT NSSToken *
-NSSPublicKey_GetToken (
- NSSPublicKey *bk,
- PRStatus *statusOpt
-)
+NSSPublicKey_GetToken(
+ NSSPublicKey *bk,
+ PRStatus *statusOpt)
{
nss_SetError(NSS_ERROR_NOT_FOUND);
return NULL;
}
NSS_IMPLEMENT NSSSlot *
-NSSPublicKey_GetSlot (
- NSSPublicKey *bk,
- PRStatus *statusOpt
-)
+NSSPublicKey_GetSlot(
+ NSSPublicKey *bk,
+ PRStatus *statusOpt)
{
nss_SetError(NSS_ERROR_NOT_FOUND);
return NULL;
}
NSS_IMPLEMENT NSSModule *
-NSSPublicKey_GetModule (
- NSSPublicKey *bk,
- PRStatus *statusOpt
-)
+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
-)
+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
-)
+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
-)
+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
-)
+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
-)
+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
-)
+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
-)
+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
-)
+NSSPublicKey_FindPrivateKey(
+ NSSPublicKey *bk,
+ NSSCallback *uhh)
{
nss_SetError(NSS_ERROR_NOT_FOUND);
return NULL;
}
-
diff --git a/nss/lib/pki/certdecode.c b/nss/lib/pki/certdecode.c
index fa259cc..61c8033 100644
--- a/nss/lib/pki/certdecode.c
+++ b/nss/lib/pki/certdecode.c
@@ -12,54 +12,49 @@
/* This is defined in pki3hack.c */
NSS_EXTERN nssDecodedCert *
-nssDecodedPKIXCertificate_Create (
- NSSArena *arenaOpt,
- NSSDER *encoding
-);
+nssDecodedPKIXCertificate_Create(
+ NSSArena *arenaOpt,
+ NSSDER *encoding);
NSS_IMPLEMENT PRStatus
-nssDecodedPKIXCertificate_Destroy (
- nssDecodedCert *dc
-);
+nssDecodedPKIXCertificate_Destroy(
+ nssDecodedCert *dc);
NSS_IMPLEMENT nssDecodedCert *
-nssDecodedCert_Create (
- NSSArena *arenaOpt,
- NSSDER *encoding,
- NSSCertificateType type
-)
+nssDecodedCert_Create(
+ NSSArena *arenaOpt,
+ NSSDER *encoding,
+ NSSCertificateType type)
{
nssDecodedCert *rvDC = NULL;
- switch(type) {
- case NSSCertificateType_PKIX:
- rvDC = nssDecodedPKIXCertificate_Create(arenaOpt, encoding);
- break;
- default:
+ switch (type) {
+ case NSSCertificateType_PKIX:
+ rvDC = nssDecodedPKIXCertificate_Create(arenaOpt, encoding);
+ break;
+ default:
#if 0
- nss_SetError(NSS_ERROR_INVALID_ARGUMENT);
+ nss_SetError(NSS_ERROR_INVALID_ARGUMENT);
#endif
- return (nssDecodedCert *)NULL;
+ return (nssDecodedCert *)NULL;
}
return rvDC;
}
NSS_IMPLEMENT PRStatus
-nssDecodedCert_Destroy (
- nssDecodedCert *dc
-)
+nssDecodedCert_Destroy(
+ nssDecodedCert *dc)
{
if (!dc) {
- return PR_FAILURE;
+ return PR_FAILURE;
}
- switch(dc->type) {
- case NSSCertificateType_PKIX:
- return nssDecodedPKIXCertificate_Destroy(dc);
- default:
+ switch (dc->type) {
+ case NSSCertificateType_PKIX:
+ return nssDecodedPKIXCertificate_Destroy(dc);
+ default:
#if 0
- nss_SetError(NSS_ERROR_INVALID_ARGUMENT);
+ nss_SetError(NSS_ERROR_INVALID_ARGUMENT);
#endif
- break;
+ break;
}
return PR_FAILURE;
}
-
diff --git a/nss/lib/pki/certificate.c b/nss/lib/pki/certificate.c
index fdf147c..4d94bc8 100644
--- a/nss/lib/pki/certificate.c
+++ b/nss/lib/pki/certificate.c
@@ -32,25 +32,24 @@ extern const NSSError NSS_ERROR_NOT_FOUND;
/* Creates a certificate from a base object */
NSS_IMPLEMENT NSSCertificate *
-nssCertificate_Create (
- nssPKIObject *object
-)
+nssCertificate_Create(
+ nssPKIObject *object)
{
PRStatus status;
NSSCertificate *rvCert;
- nssArenaMark * mark;
+ 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;
+ return (NSSCertificate *)NULL;
}
rvCert->object = *object;
/* XXX should choose instance based on some criteria */
status = nssCryptokiCertificate_GetAttributes(object->instances[0],
- NULL, /* XXX sessionOpt */
+ NULL, /* XXX sessionOpt */
arena,
&rvCert->type,
&rvCert->id,
@@ -59,236 +58,217 @@ nssCertificate_Create (
&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;
+ !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);
+ nssArena_Unmark(arena, mark);
return rvCert;
}
NSS_IMPLEMENT NSSCertificate *
-nssCertificate_AddRef (
- NSSCertificate *c
-)
+nssCertificate_AddRef(
+ NSSCertificate *c)
{
if (c) {
- nssPKIObject_AddRef(&c->object);
+ nssPKIObject_AddRef(&c->object);
}
return c;
}
NSS_IMPLEMENT PRStatus
-nssCertificate_Destroy (
- NSSCertificate *c
-)
+nssCertificate_Destroy(
+ NSSCertificate *c)
{
- nssCertificateStoreTrace lockTrace = {NULL, NULL, PR_FALSE, PR_FALSE};
- nssCertificateStoreTrace unlockTrace = {NULL, NULL, PR_FALSE, PR_FALSE};
+ 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,
+ 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);
- }
- }
+ } 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
-)
+NSSCertificate_Destroy(NSSCertificate *c)
{
return nssCertificate_Destroy(c);
}
NSS_IMPLEMENT NSSDER *
-nssCertificate_GetEncoding (
- NSSCertificate *c
-)
+nssCertificate_GetEncoding(NSSCertificate *c)
{
if (c->encoding.size > 0 && c->encoding.data) {
- return &c->encoding;
+ return &c->encoding;
} else {
- return (NSSDER *)NULL;
+ return (NSSDER *)NULL;
}
}
NSS_IMPLEMENT NSSDER *
-nssCertificate_GetIssuer (
- NSSCertificate *c
-)
+nssCertificate_GetIssuer(NSSCertificate *c)
{
if (c->issuer.size > 0 && c->issuer.data) {
- return &c->issuer;
+ return &c->issuer;
} else {
- return (NSSDER *)NULL;
+ return (NSSDER *)NULL;
}
}
NSS_IMPLEMENT NSSDER *
-nssCertificate_GetSerialNumber (
- NSSCertificate *c
-)
+nssCertificate_GetSerialNumber(NSSCertificate *c)
{
if (c->serial.size > 0 && c->serial.data) {
- return &c->serial;
+ return &c->serial;
} else {
- return (NSSDER *)NULL;
+ return (NSSDER *)NULL;
}
}
NSS_IMPLEMENT NSSDER *
-nssCertificate_GetSubject (
- NSSCertificate *c
-)
+nssCertificate_GetSubject(NSSCertificate *c)
{
if (c->subject.size > 0 && c->subject.data) {
- return &c->subject;
+ return &c->subject;
} else {
- return (NSSDER *)NULL;
+ return (NSSDER *)NULL;
}
}
/* Returns a copy, Caller must free using nss_ZFreeIf */
NSS_IMPLEMENT NSSUTF8 *
-nssCertificate_GetNickname (
- NSSCertificate *c,
- NSSToken *tokenOpt
-)
+nssCertificate_GetNickname(
+ NSSCertificate *c,
+ NSSToken *tokenOpt)
{
return nssPKIObject_GetNicknameForToken(&c->object, tokenOpt);
}
NSS_IMPLEMENT NSSASCII7 *
-nssCertificate_GetEmailAddress (
- NSSCertificate *c
-)
+nssCertificate_GetEmailAddress(NSSCertificate *c)
{
return c->email;
}
NSS_IMPLEMENT PRStatus
-NSSCertificate_DeleteStoredObject (
- NSSCertificate *c,
- NSSCallback *uhh
-)
+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 */
-)
+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 */
-)
+ 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
-)
+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
-)
+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
-)
+nssCertificate_GetDecoding(
+ NSSCertificate *c)
{
- nssDecodedCert* deco = NULL;
+ 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);
+ deco = nssDecodedCert_Create(NULL, &c->encoding, c->type);
+ PORT_Assert(!c->decoding);
c->decoding = deco;
} else {
deco = c->decoding;
@@ -298,10 +278,9 @@ nssCertificate_GetDecoding (
}
static NSSCertificate **
-filter_subject_certs_for_id (
- NSSCertificate **subjectCerts,
- void *id
-)
+filter_subject_certs_for_id(
+ NSSCertificate **subjectCerts,
+ void *id)
{
NSSCertificate **si;
nssDecodedCert *dcp;
@@ -312,74 +291,71 @@ filter_subject_certs_for_id (
/* 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;
- }
+ 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
-)
+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);
- }
+ 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
-)
+find_cert_issuer(
+ NSSCertificate *c,
+ NSSTime *timeOpt,
+ NSSUsage *usage,
+ NSSPolicies *policiesOpt,
+ NSSTrustDomain *td,
+ NSSCryptoContext *cc)
{
NSSArena *arena;
NSSCertificate **certs = NULL;
@@ -388,47 +364,47 @@ find_cert_issuer (
NSSCertificate *issuer = NULL;
if (!cc)
- cc = c->object.cryptoContext;
+ cc = c->object.cryptoContext;
if (!td)
- td = NSSCertificate_GetTrustDomain(c);
+ td = NSSCertificate_GetTrustDomain(c);
arena = nssArena_Create();
if (!arena) {
- return (NSSCertificate *)NULL;
+ return (NSSCertificate *)NULL;
}
if (cc) {
- ccIssuers = nssCryptoContext_FindCertificatesBySubject(cc,
- &c->issuer,
- NULL,
- 0,
- arena);
+ ccIssuers = nssCryptoContext_FindCertificatesBySubject(cc,
+ &c->issuer,
+ NULL,
+ 0,
+ arena);
}
if (td)
- tdIssuers = nssTrustDomain_FindCertificatesBySubject(td,
- &c->issuer,
- NULL,
- 0,
- arena);
+ 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);
+ 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;
@@ -438,260 +414,243 @@ find_cert_issuer (
** 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_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;
+ PRUint32 rvCount = 0;
+ PRStatus st;
+ PRStatus ret = PR_SUCCESS;
if (!c || !cc ||
(!td && (td = NSSCertificate_GetTrustDomain(c)) == NULL)) {
- goto loser;
+ goto loser;
}
/* bump the usage up to CA level */
issuerUsage.nss3lookingForCA = PR_TRUE;
collection = nssCertificateCollection_Create(td, NULL);
if (!collection)
- goto loser;
+ goto loser;
st = nssPKIObjectCollection_AddObject(collection, (nssPKIObject *)c);
if (st != PR_SUCCESS)
- goto loser;
+ 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;
+ 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,
+ 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;
+ 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;
+ 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
-)
+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);
+ td, cc);
}
NSS_IMPLEMENT NSSCryptoContext *
-nssCertificate_GetCryptoContext (
- NSSCertificate *c
-)
+nssCertificate_GetCryptoContext(NSSCertificate *c)
{
return c->object.cryptoContext;
}
NSS_IMPLEMENT NSSTrustDomain *
-nssCertificate_GetTrustDomain (
- NSSCertificate *c
-)
+nssCertificate_GetTrustDomain(NSSCertificate *c)
{
return c->object.trustDomain;
}
NSS_IMPLEMENT NSSTrustDomain *
-NSSCertificate_GetTrustDomain (
- NSSCertificate *c
-)
+NSSCertificate_GetTrustDomain(NSSCertificate *c)
{
return nssCertificate_GetTrustDomain(c);
}
NSS_IMPLEMENT NSSToken *
-NSSCertificate_GetToken (
- NSSCertificate *c,
- PRStatus *statusOpt
-)
+NSSCertificate_GetToken(
+ NSSCertificate *c,
+ PRStatus *statusOpt)
{
return (NSSToken *)NULL;
}
NSS_IMPLEMENT NSSSlot *
-NSSCertificate_GetSlot (
- NSSCertificate *c,
- PRStatus *statusOpt
-)
+NSSCertificate_GetSlot(
+ NSSCertificate *c,
+ PRStatus *statusOpt)
{
return (NSSSlot *)NULL;
}
NSS_IMPLEMENT NSSModule *
-NSSCertificate_GetModule (
- NSSCertificate *c,
- PRStatus *statusOpt
-)
+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
-)
+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
-)
+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
-)
+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
-)
+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
-)
+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
-)
+NSSCertificate_GetPublicKey(
+ NSSCertificate *c)
{
#if 0
CK_ATTRIBUTE pubktemplate[] = {
- { CKA_CLASS, NULL, 0 },
- { CKA_ID, NULL, 0 },
- { CKA_SUBJECT, NULL, 0 }
+ { 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]);
+ /* CKA_ID */
+ NSS_CK_ITEM_TO_ATTRIBUTE(&c->id, &pubktemplate[1]);
} else {
- /* failure, yes? */
- return (NSSPublicKey *)NULL;
+ /* failure, yes? */
+ return (NSSPublicKey *)NULL;
}
if (c->subject.size > 0) {
- /* CKA_SUBJECT */
- NSS_CK_ITEM_TO_ATTRIBUTE(&c->subject, &pubktemplate[2]);
+ /* CKA_SUBJECT */
+ NSS_CK_ITEM_TO_ATTRIBUTE(&c->subject, &pubktemplate[2]);
} else {
- /* failure, yes? */
- return (NSSPublicKey *)NULL;
+ /* failure, yes? */
+ return (NSSPublicKey *)NULL;
}
/* Try the cert's token first */
if (c->token) {
- nssrv = nssToken_FindObjectByTemplate(c->token, pubktemplate, count);
+ nssrv = nssToken_FindObjectByTemplate(c->token, pubktemplate, count);
}
#endif
/* Try all other key tokens */
@@ -699,33 +658,31 @@ NSSCertificate_GetPublicKey (
}
NSS_IMPLEMENT NSSPrivateKey *
-NSSCertificate_FindPrivateKey (
- NSSCertificate *c,
- NSSCallback *uhh
-)
+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
-)
+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;
+ return PR_FALSE;
}
for (ip = instances; *ip; ip++) {
- nssCryptokiObject *instance = *ip;
- if (nssToken_IsPrivateKeyAvailable(instance->token, c, instance)) {
- isUser = PR_TRUE;
- }
+ nssCryptokiObject *instance = *ip;
+ if (nssToken_IsPrivateKeyAvailable(instance->token, c, instance)) {
+ isUser = PR_TRUE;
+ }
}
nssCryptokiObjectArray_Destroy(instances);
return isUser;
@@ -733,123 +690,115 @@ NSSCertificate_IsPrivateKeyAvailable (
/* sort the subject cert list from newest to oldest */
PRIntn
-nssCertificate_SubjectListSort (
- void *v1,
- void *v2
-)
+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;
+ return dc2 ? 1 : 0;
} else if (!dc2) {
- return -1;
+ return -1;
} else {
- return dc1->isNewerThan(dc1, dc2) ? -1 : 1;
+ return dc1->isNewerThan(dc1, dc2) ? -1 : 1;
}
}
NSS_IMPLEMENT PRBool
-NSSUserCertificate_IsStillPresent (
- NSSUserCertificate *uc,
- PRStatus *statusOpt
-)
+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
-)
+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
-)
+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
-)
+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
-)
+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
-)
+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
-)
+nssSMIMEProfile_Create(
+ NSSCertificate *cert,
+ NSSItem *profileTime,
+ NSSItem *profileData)
{
NSSArena *arena;
nssSMIMEProfile *rvProfile;
@@ -858,40 +807,41 @@ nssSMIMEProfile_Create (
NSSCryptoContext *cc = nssCertificate_GetCryptoContext(cert);
arena = nssArena_Create();
if (!arena) {
- return NULL;
+ return NULL;
}
object = nssPKIObject_Create(arena, NULL, td, cc, nssPKILock);
if (!object) {
- goto loser;
+ goto loser;
}
rvProfile = nss_ZNEW(arena, nssSMIMEProfile);
if (!rvProfile) {
- goto loser;
+ 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);
+ rvProfile->profileTime = nssItem_Duplicate(profileTime, arena, NULL);
}
if (profileData) {
- rvProfile->profileData = nssItem_Duplicate(profileData, arena, NULL);
+ rvProfile->profileData = nssItem_Duplicate(profileData, arena, NULL);
}
return rvProfile;
loser:
- if (object) nssPKIObject_Destroy(object);
- else if (arena) nssArena_Destroy(arena);
+ 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
-)
+nssCertificateList_DoCallback(
+ nssList *certList,
+ PRStatus (*callback)(NSSCertificate *c, void *arg),
+ void *arg)
{
nssListIterator *certs;
NSSCertificate *cert;
@@ -899,74 +849,71 @@ nssCertificateList_DoCallback (
if (!certs) {
return PR_FAILURE;
}
- for (cert = (NSSCertificate *)nssListIterator_Start(certs);
+ for (cert = (NSSCertificate *)nssListIterator_Start(certs);
cert != (NSSCertificate *)NULL;
- cert = (NSSCertificate *)nssListIterator_Next(certs))
- {
- (void)(*callback)(cert, arg);
+ cert = (NSSCertificate *)nssListIterator_Next(certs)) {
+ (void)(*callback)(cert, arg);
}
nssListIterator_Finish(certs);
nssListIterator_Destroy(certs);
return PR_SUCCESS;
}
-static PRStatus add_ref_callback(NSSCertificate *c, void *a)
+static PRStatus
+add_ref_callback(NSSCertificate *c, void *a)
{
nssCertificate_AddRef(c);
return PR_SUCCESS;
}
NSS_IMPLEMENT void
-nssCertificateList_AddReferences (
- nssList *certList
-)
+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
+ * 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)
+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;
+ return PR_FALSE;
}
- if ((serverAuth != nssTrustLevel_Unknown) &&
- (serverAuth != nssTrustLevel_NotTrusted)) {
- return PR_FALSE;
+ if ((serverAuth != nssTrustLevel_Unknown) &&
+ (serverAuth != nssTrustLevel_NotTrusted)) {
+ return PR_FALSE;
}
- if ((clientAuth != nssTrustLevel_Unknown) &&
- (clientAuth != 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 ((codeSigning != nssTrustLevel_Unknown) &&
+ (codeSigning != nssTrustLevel_NotTrusted)) {
+ return PR_FALSE;
}
- if ((email != nssTrustLevel_Unknown) &&
- (email != 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
+ /* 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
-)
+nssTrust_Create(
+ nssPKIObject *object,
+ NSSItem *certData)
{
PRStatus status;
PRUint32 i;
@@ -980,128 +927,115 @@ nssTrust_Create (
SECStatus rv; /* Should be stan flavor */
PRBool stepUp;
- lastTrustOrder = 1<<16; /* just make it big */
+ 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;
+ return (NSSTrust *)NULL;
}
rvt->object = *object;
/* should be stan flavor of Hashbuf */
- rv = PK11_HashBuf(SEC_OID_SHA1,sha1_hashcmp,certData->data,certData->size);
+ rv = PK11_HashBuf(SEC_OID_SHA1, sha1_hashcmp, certData->data, certData->size);
if (rv != SECSuccess) {
- return (NSSTrust *)NULL;
+ return (NSSTrust *)NULL;
}
sha1_hash.data = sha1_hashin;
- sha1_hash.size = sizeof (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;
+ 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
-)
+nssTrust_AddRef(NSSTrust *trust)
{
if (trust) {
- nssPKIObject_AddRef(&trust->object);
+ nssPKIObject_AddRef(&trust->object);
}
return trust;
}
NSS_IMPLEMENT PRStatus
-nssTrust_Destroy (
- NSSTrust *trust
-)
+nssTrust_Destroy(NSSTrust *trust)
{
if (trust) {
- (void)nssPKIObject_Destroy(&trust->object);
+ (void)nssPKIObject_Destroy(&trust->object);
}
return PR_SUCCESS;
}
NSS_IMPLEMENT nssSMIMEProfile *
-nssSMIMEProfile_AddRef (
- nssSMIMEProfile *profile
-)
+nssSMIMEProfile_AddRef(nssSMIMEProfile *profile)
{
if (profile) {
- nssPKIObject_AddRef(&profile->object);
+ nssPKIObject_AddRef(&profile->object);
}
return profile;
}
NSS_IMPLEMENT PRStatus
-nssSMIMEProfile_Destroy (
- nssSMIMEProfile *profile
-)
+nssSMIMEProfile_Destroy(nssSMIMEProfile *profile)
{
if (profile) {
- (void)nssPKIObject_Destroy(&profile->object);
+ (void)nssPKIObject_Destroy(&profile->object);
}
return PR_SUCCESS;
}
NSS_IMPLEMENT NSSCRL *
-nssCRL_Create (
- nssPKIObject *object
-)
+nssCRL_Create(nssPKIObject *object)
{
PRStatus status;
NSSCRL *rvCRL;
@@ -1109,12 +1043,12 @@ nssCRL_Create (
PR_ASSERT(object->instances != NULL && object->numInstances > 0);
rvCRL = nss_ZNEW(arena, NSSCRL);
if (!rvCRL) {
- return (NSSCRL *)NULL;
+ return (NSSCRL *)NULL;
}
rvCRL->object = *object;
/* XXX should choose instance based on some criteria */
status = nssCryptokiCRL_GetAttributes(object->instances[0],
- NULL, /* XXX sessionOpt */
+ NULL, /* XXX sessionOpt */
arena,
&rvCRL->encoding,
NULL, /* subject */
@@ -1122,50 +1056,46 @@ nssCRL_Create (
&rvCRL->url,
&rvCRL->isKRL);
if (status != PR_SUCCESS) {
- return (NSSCRL *)NULL;
+ if (!arena) {
+ nssPKIObject_Destroy((nssPKIObject *)rvCRL);
+ }
+ return (NSSCRL *)NULL;
}
return rvCRL;
}
NSS_IMPLEMENT NSSCRL *
-nssCRL_AddRef (
- NSSCRL *crl
-)
+nssCRL_AddRef(NSSCRL *crl)
{
if (crl) {
- nssPKIObject_AddRef(&crl->object);
+ nssPKIObject_AddRef(&crl->object);
}
return crl;
}
NSS_IMPLEMENT PRStatus
-nssCRL_Destroy (
- NSSCRL *crl
-)
+nssCRL_Destroy(NSSCRL *crl)
{
if (crl) {
- (void)nssPKIObject_Destroy(&crl->object);
+ (void)nssPKIObject_Destroy(&crl->object);
}
return PR_SUCCESS;
}
NSS_IMPLEMENT PRStatus
-nssCRL_DeleteStoredObject (
- NSSCRL *crl,
- NSSCallback *uhh
-)
+nssCRL_DeleteStoredObject(
+ NSSCRL *crl,
+ NSSCallback *uhh)
{
return nssPKIObject_DeleteStoredObject(&crl->object, uhh, PR_TRUE);
}
NSS_IMPLEMENT NSSDER *
-nssCRL_GetEncoding (
- NSSCRL *crl
-)
+nssCRL_GetEncoding(NSSCRL *crl)
{
if (crl && crl->encoding.data != NULL && crl->encoding.size > 0) {
- return &crl->encoding;
+ return &crl->encoding;
} else {
- return (NSSDER *)NULL;
+ return (NSSDER *)NULL;
}
}
diff --git a/nss/lib/pki/cryptocontext.c b/nss/lib/pki/cryptocontext.c
index 28d4e7b..074eb74 100644
--- a/nss/lib/pki/cryptocontext.c
+++ b/nss/lib/pki/cryptocontext.c
@@ -18,221 +18,206 @@ extern const NSSError NSS_ERROR_NOT_FOUND;
extern const NSSError NSS_ERROR_INVALID_ARGUMENT;
NSS_IMPLEMENT NSSCryptoContext *
-nssCryptoContext_Create (
- NSSTrustDomain *td,
- NSSCallback *uhhOpt
-)
+nssCryptoContext_Create(
+ NSSTrustDomain *td,
+ NSSCallback *uhhOpt)
{
NSSArena *arena;
NSSCryptoContext *rvCC;
arena = NSSArena_Create();
if (!arena) {
- return NULL;
+ return NULL;
}
rvCC = nss_ZNEW(arena, NSSCryptoContext);
if (!rvCC) {
- return NULL;
+ return NULL;
}
rvCC->td = td;
rvCC->arena = arena;
rvCC->certStore = nssCertificateStore_Create(rvCC->arena);
if (!rvCC->certStore) {
- nssArena_Destroy(arena);
- return NULL;
+ nssArena_Destroy(arena);
+ return NULL;
}
return rvCC;
}
NSS_IMPLEMENT PRStatus
-NSSCryptoContext_Destroy (
- NSSCryptoContext *cc
-)
+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;
- }
+ status = nssCertificateStore_Destroy(cc->certStore);
+ if (status == PR_FAILURE) {
+ return status;
+ }
} else {
- status = PR_FAILURE;
+ status = PR_FAILURE;
}
nssArena_Destroy(cc->arena);
return status;
}
NSS_IMPLEMENT PRStatus
-NSSCryptoContext_SetDefaultCallback (
- NSSCryptoContext *td,
- NSSCallback *newCallback,
- NSSCallback **oldCallbackOpt
-)
+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
-)
+NSSCryptoContext_GetDefaultCallback(
+ NSSCryptoContext *td,
+ PRStatus *statusOpt)
{
nss_SetError(NSS_ERROR_NOT_FOUND);
return NULL;
}
NSS_IMPLEMENT NSSTrustDomain *
-NSSCryptoContext_GetTrustDomain (
- NSSCryptoContext *td
-)
+NSSCryptoContext_GetTrustDomain(NSSCryptoContext *td)
{
nss_SetError(NSS_ERROR_NOT_FOUND);
return NULL;
}
-
NSS_IMPLEMENT NSSCertificate *
-NSSCryptoContext_FindOrImportCertificate (
- NSSCryptoContext *cc,
- NSSCertificate *c
-)
+NSSCryptoContext_FindOrImportCertificate(
+ NSSCryptoContext *cc,
+ NSSCertificate *c)
{
NSSCertificate *rvCert = NULL;
PORT_Assert(cc->certStore);
if (!cc->certStore) {
- nss_SetError(NSS_ERROR_INVALID_ARGUMENT);
- return rvCert;
+ 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;
- }
+ 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);
+ /* 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
-)
+NSSCryptoContext_ImportPKIXCertificate(
+ NSSCryptoContext *cc,
+ struct NSSPKIXCertificateStr *pc)
{
nss_SetError(NSS_ERROR_NOT_FOUND);
return NULL;
}
NSS_IMPLEMENT NSSCertificate *
-NSSCryptoContext_ImportEncodedCertificate (
- NSSCryptoContext *cc,
- NSSBER *ber
-)
+NSSCryptoContext_ImportEncodedCertificate(
+ NSSCryptoContext *cc,
+ NSSBER *ber)
{
nss_SetError(NSS_ERROR_NOT_FOUND);
return NULL;
}
NSS_IMPLEMENT PRStatus
-NSSCryptoContext_ImportEncodedPKIXCertificateChain (
- NSSCryptoContext *cc,
- NSSBER *ber
-)
+NSSCryptoContext_ImportEncodedPKIXCertificateChain(
+ NSSCryptoContext *cc,
+ NSSBER *ber)
{
nss_SetError(NSS_ERROR_NOT_FOUND);
return PR_FAILURE;
}
NSS_IMPLEMENT PRStatus
-nssCryptoContext_ImportTrust (
- NSSCryptoContext *cc,
- NSSTrust *trust
-)
+nssCryptoContext_ImportTrust(
+ NSSCryptoContext *cc,
+ NSSTrust *trust)
{
PRStatus nssrv;
PORT_Assert(cc->certStore);
if (!cc->certStore) {
- return PR_FAILURE;
+ return PR_FAILURE;
}
nssrv = nssCertificateStore_AddTrust(cc->certStore, trust);
#if 0
if (nssrv == PR_SUCCESS) {
- trust->object.cryptoContext = cc;
+ trust->object.cryptoContext = cc;
}
#endif
return nssrv;
}
NSS_IMPLEMENT PRStatus
-nssCryptoContext_ImportSMIMEProfile (
- NSSCryptoContext *cc,
- nssSMIMEProfile *profile
-)
+nssCryptoContext_ImportSMIMEProfile(
+ NSSCryptoContext *cc,
+ nssSMIMEProfile *profile)
{
PRStatus nssrv;
PORT_Assert(cc->certStore);
if (!cc->certStore) {
- return PR_FAILURE;
+ return PR_FAILURE;
}
nssrv = nssCertificateStore_AddSMIMEProfile(cc->certStore, profile);
#if 0
if (nssrv == PR_SUCCESS) {
- profile->object.cryptoContext = cc;
+ 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 */
-)
+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;
+ return NULL;
}
certs = nssCertificateStore_FindCertificatesByNickname(cc->certStore,
name,
NULL, 0, NULL);
if (certs) {
- rvCert = nssCertificateArray_FindBestCertificate(certs,
- timeOpt,
- usage,
- policiesOpt);
- nssCertificateArray_Destroy(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
-)
+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;
+ return NULL;
}
rvCerts = nssCertificateStore_FindCertificatesByNickname(cc->certStore,
name,
@@ -243,63 +228,60 @@ NSSCryptoContext_FindCertificatesByNickname (
}
NSS_IMPLEMENT NSSCertificate *
-NSSCryptoContext_FindCertificateByIssuerAndSerialNumber (
- NSSCryptoContext *cc,
- NSSDER *issuer,
- NSSDER *serialNumber
-)
+NSSCryptoContext_FindCertificateByIssuerAndSerialNumber(
+ NSSCryptoContext *cc,
+ NSSDER *issuer,
+ NSSDER *serialNumber)
{
PORT_Assert(cc->certStore);
if (!cc->certStore) {
- return NULL;
+ return NULL;
}
return nssCertificateStore_FindCertificateByIssuerAndSerialNumber(
- cc->certStore,
- issuer,
- serialNumber);
+ cc->certStore,
+ issuer,
+ serialNumber);
}
NSS_IMPLEMENT NSSCertificate *
-NSSCryptoContext_FindBestCertificateBySubject (
- NSSCryptoContext *cc,
- NSSDER *subject,
- NSSTime *timeOpt,
- NSSUsage *usage,
- NSSPolicies *policiesOpt
-)
+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;
+ return NULL;
}
certs = nssCertificateStore_FindCertificatesBySubject(cc->certStore,
subject,
NULL, 0, NULL);
if (certs) {
- rvCert = nssCertificateArray_FindBestCertificate(certs,
- timeOpt,
- usage,
- policiesOpt);
- nssCertificateArray_Destroy(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
-)
+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;
+ return NULL;
}
rvCerts = nssCertificateStore_FindCertificatesBySubject(cc->certStore,
subject,
@@ -310,13 +292,12 @@ nssCryptoContext_FindCertificatesBySubject (
}
NSS_IMPLEMENT NSSCertificate **
-NSSCryptoContext_FindCertificatesBySubject (
- NSSCryptoContext *cc,
- NSSDER *subject,
- NSSCertificate *rvOpt[],
- PRUint32 maximumOpt, /* 0 for no max */
- NSSArena *arenaOpt
-)
+NSSCryptoContext_FindCertificatesBySubject(
+ NSSCryptoContext *cc,
+ NSSDER *subject,
+ NSSCertificate *rvOpt[],
+ PRUint32 maximumOpt, /* 0 for no max */
+ NSSArena *arenaOpt)
{
return nssCryptoContext_FindCertificatesBySubject(cc, subject,
rvOpt, maximumOpt,
@@ -324,88 +305,83 @@ NSSCryptoContext_FindCertificatesBySubject (
}
NSS_IMPLEMENT NSSCertificate *
-NSSCryptoContext_FindBestCertificateByNameComponents (
- NSSCryptoContext *cc,
- NSSUTF8 *nameComponents,
- NSSTime *timeOpt,
- NSSUsage *usage,
- NSSPolicies *policiesOpt
-)
+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
-)
+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
-)
+NSSCryptoContext_FindCertificateByEncodedCertificate(
+ NSSCryptoContext *cc,
+ NSSBER *encodedCertificate)
{
PORT_Assert(cc->certStore);
if (!cc->certStore) {
- return NULL;
+ return NULL;
}
return nssCertificateStore_FindCertificateByEncodedCertificate(
- cc->certStore,
- encodedCertificate);
+ cc->certStore,
+ encodedCertificate);
}
NSS_IMPLEMENT NSSCertificate *
-NSSCryptoContext_FindBestCertificateByEmail (
- NSSCryptoContext *cc,
- NSSASCII7 *email,
- NSSTime *timeOpt,
- NSSUsage *usage,
- NSSPolicies *policiesOpt
-)
+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;
+ return NULL;
}
certs = nssCertificateStore_FindCertificatesByEmail(cc->certStore,
email,
NULL, 0, NULL);
if (certs) {
- rvCert = nssCertificateArray_FindBestCertificate(certs,
- timeOpt,
- usage,
- policiesOpt);
- nssCertificateArray_Destroy(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
-)
+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;
+ return NULL;
}
rvCerts = nssCertificateStore_FindCertificatesByEmail(cc->certStore,
email,
@@ -416,179 +392,166 @@ NSSCryptoContext_FindCertificatesByEmail (
}
NSS_IMPLEMENT NSSCertificate *
-NSSCryptoContext_FindCertificateByOCSPHash (
- NSSCryptoContext *cc,
- NSSItem *hash
-)
+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
-)
+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
-)
+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
-)
+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
-)
+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
-)
+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
-)
+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
-)
+nssCryptoContext_FindTrustForCertificate(
+ NSSCryptoContext *cc,
+ NSSCertificate *cert)
{
PORT_Assert(cc->certStore);
if (!cc->certStore) {
- return NULL;
+ return NULL;
}
return nssCertificateStore_FindTrustForCertificate(cc->certStore, cert);
}
NSS_IMPLEMENT nssSMIMEProfile *
-nssCryptoContext_FindSMIMEProfileForCertificate (
- NSSCryptoContext *cc,
- NSSCertificate *cert
-)
+nssCryptoContext_FindSMIMEProfileForCertificate(
+ NSSCryptoContext *cc,
+ NSSCertificate *cert)
{
PORT_Assert(cc->certStore);
if (!cc->certStore) {
- return NULL;
+ return NULL;
}
- return nssCertificateStore_FindSMIMEProfileForCertificate(cc->certStore,
+ 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
-)
+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
-)
+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
-)
+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
-)
+NSSCryptoContext_FindSymmetricKeyByAlgorithmAndKeyID(
+ NSSCryptoContext *cc,
+ NSSOID *algorithm,
+ NSSItem *keyID,
+ NSSCallback *uhhOpt)
{
nss_SetError(NSS_ERROR_NOT_FOUND);
return NULL;
@@ -600,383 +563,349 @@ struct token_session_str {
};
NSS_IMPLEMENT NSSItem *
-NSSCryptoContext_Decrypt (
- NSSCryptoContext *cc,
- NSSAlgorithmAndParameters *apOpt,
- NSSItem *encryptedData,
- NSSCallback *uhhOpt,
- NSSItem *rvOpt,
- NSSArena *arenaOpt
-)
+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
-)
+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
-)
+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
-)
+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
-)
+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
-)
+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
-)
+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
-)
+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
-)
+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
-)
+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
-)
+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
-)
+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
-)
+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
-)
+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
-)
+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
-)
+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
-)
+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
-)
+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
-)
+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
-)
+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
-)
+NSSCryptoContext_ContinueVerify(
+ NSSCryptoContext *cc,
+ NSSItem *data)
{
nss_SetError(NSS_ERROR_NOT_FOUND);
return PR_FAILURE;
}
NSS_IMPLEMENT PRStatus
-NSSCryptoContext_FinishVerify (
- NSSCryptoContext *cc
-)
+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
-)
+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
-)
+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
-)
+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
-)
+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
-)
+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,
+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
-)
+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
-)
+NSSCryptoContext_ContinueDigest(
+ NSSCryptoContext *cc,
+ NSSAlgorithmAndParameters *apOpt,
+ NSSItem *item)
{
- /*
+ /*
NSSAlgorithmAndParameters *ap;
ap = (apOpt) ? apOpt : cc->ap;
*/
- /* why apOpt? can't change it at this point... */
+ /* 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
-)
+NSSCryptoContext_FinishDigest(
+ NSSCryptoContext *cc,
+ NSSItem *rvOpt,
+ NSSArena *arenaOpt)
{
return nssToken_FinishDigest(cc->token, cc->session, rvOpt, arenaOpt);
}
NSS_IMPLEMENT NSSCryptoContext *
-NSSCryptoContext_Clone (
- NSSCryptoContext *cc
-)
+NSSCryptoContext_Clone(NSSCryptoContext *cc)
{
nss_SetError(NSS_ERROR_NOT_FOUND);
return NULL;
}
-
diff --git a/nss/lib/pki/exports.gyp b/nss/lib/pki/exports.gyp
new file mode 100644
index 0000000..a9707ae
--- /dev/null
+++ b/nss/lib/pki/exports.gyp
@@ -0,0 +1,32 @@
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+{
+ 'includes': [
+ '../../coreconf/config.gypi'
+ ],
+ 'targets': [
+ {
+ 'target_name': 'lib_pki_exports',
+ 'type': 'none',
+ 'copies': [
+ {
+ 'files': [
+ 'nsspki.h',
+ 'nsspkit.h',
+ 'pki.h',
+ 'pki3hack.h',
+ 'pkim.h',
+ 'pkistore.h',
+ 'pkit.h',
+ 'pkitm.h'
+ ],
+ 'destination': '<(nss_private_dist_dir)/<(module)'
+ }
+ ]
+ }
+ ],
+ 'variables': {
+ 'module': 'nss'
+ }
+}
diff --git a/nss/lib/pki/nsspki.h b/nss/lib/pki/nsspki.h
index a2da997..28780c3 100644
--- a/nss/lib/pki/nsspki.h
+++ b/nss/lib/pki/nsspki.h
@@ -70,7 +70,7 @@ PR_BEGIN_EXTERN_C
/*
* NSSCertificate
*
- * These things can do crypto ops like public keys, except that the trust,
+ * 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
@@ -84,42 +84,36 @@ PR_BEGIN_EXTERN_C
*/
NSS_EXTERN PRStatus
-NSSCertificate_Destroy
-(
- NSSCertificate *c
-);
+NSSCertificate_Destroy(NSSCertificate *c);
/*
* NSSCertificate_DeleteStoredObject
*
* Permanently remove this certificate from storage. If this is the
- * only (remaining) certificate corresponding to a private key,
+ * 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_DeleteStoredObject(
+ NSSCertificate *c,
+ NSSCallback *uhh);
/*
* NSSCertificate_Validate
*
- * Verify that this certificate is trusted, for the specified usage(s),
+ * 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_Validate(
+ NSSCertificate *c,
+ NSSTime *timeOpt, /* NULL for "now" */
+ NSSUsage *usage,
+ NSSPolicies *policiesOpt /* NULL for none */
+ );
/*
* NSSCertificate_ValidateCompletely
@@ -132,23 +126,22 @@ NSSCertificate_Validate
* 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_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
@@ -157,18 +150,16 @@ NSSCertificate_ValidateCompletely
*/
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_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
@@ -176,12 +167,10 @@ NSSCertificate_ValidateAndDiscoverUsagesAndPolicies
*/
NSS_EXTERN NSSDER *
-NSSCertificate_Encode
-(
- NSSCertificate *c,
- NSSDER *rvOpt,
- NSSArena *arenaOpt
-);
+NSSCertificate_Encode(
+ NSSCertificate *c,
+ NSSDER *rvOpt,
+ NSSArena *arenaOpt);
/*
* NSSCertificate_BuildChain
@@ -201,19 +190,17 @@ NSSCertificate_Encode
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_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
@@ -221,10 +208,7 @@ NSSCertificate_BuildChain
*/
NSS_EXTERN NSSTrustDomain *
-NSSCertificate_GetTrustDomain
-(
- NSSCertificate *c
-);
+NSSCertificate_GetTrustDomain(NSSCertificate *c);
/*
* NSSCertificate_GetToken
@@ -233,11 +217,9 @@ NSSCertificate_GetTrustDomain
*/
NSS_EXTERN NSSToken *
-NSSCertificate_GetToken
-(
- NSSCertificate *c,
- PRStatus *statusOpt
-);
+NSSCertificate_GetToken(
+ NSSCertificate *c,
+ PRStatus *statusOpt);
/*
* NSSCertificate_GetSlot
@@ -246,11 +228,9 @@ NSSCertificate_GetToken
*/
NSS_EXTERN NSSSlot *
-NSSCertificate_GetSlot
-(
- NSSCertificate *c,
- PRStatus *statusOpt
-);
+NSSCertificate_GetSlot(
+ NSSCertificate *c,
+ PRStatus *statusOpt);
/*
* NSSCertificate_GetModule
@@ -259,11 +239,9 @@ NSSCertificate_GetSlot
*/
NSS_EXTERN NSSModule *
-NSSCertificate_GetModule
-(
- NSSCertificate *c,
- PRStatus *statusOpt
-);
+NSSCertificate_GetModule(
+ NSSCertificate *c,
+ PRStatus *statusOpt);
/*
* NSSCertificate_Encrypt
@@ -273,18 +251,16 @@ NSSCertificate_GetModule
*/
NSS_EXTERN NSSItem *
-NSSCertificate_Encrypt
-(
- NSSCertificate *c,
- NSSAlgorithmAndParameters *apOpt,
- NSSItem *data,
- NSSTime *timeOpt,
- NSSUsage *usage,
- NSSPolicies *policiesOpt,
- NSSCallback *uhh,
- NSSItem *rvOpt,
- NSSArena *arenaOpt
-);
+NSSCertificate_Encrypt(
+ NSSCertificate *c,
+ NSSAlgorithmAndParameters *apOpt,
+ NSSItem *data,
+ NSSTime *timeOpt,
+ NSSUsage *usage,
+ NSSPolicies *policiesOpt,
+ NSSCallback *uhh,
+ NSSItem *rvOpt,
+ NSSArena *arenaOpt);
/*
* NSSCertificate_Verify
@@ -292,17 +268,15 @@ NSSCertificate_Encrypt
*/
NSS_EXTERN PRStatus
-NSSCertificate_Verify
-(
- NSSCertificate *c,
- NSSAlgorithmAndParameters *apOpt,
- NSSItem *data,
- NSSItem *signature,
- NSSTime *timeOpt,
- NSSUsage *usage,
- NSSPolicies *policiesOpt,
- NSSCallback *uhh
-);
+NSSCertificate_Verify(
+ NSSCertificate *c,
+ NSSAlgorithmAndParameters *apOpt,
+ NSSItem *data,
+ NSSItem *signature,
+ NSSTime *timeOpt,
+ NSSUsage *usage,
+ NSSPolicies *policiesOpt,
+ NSSCallback *uhh);
/*
* NSSCertificate_VerifyRecover
@@ -310,40 +284,36 @@ NSSCertificate_Verify
*/
NSS_EXTERN NSSItem *
-NSSCertificate_VerifyRecover
-(
- NSSCertificate *c,
- NSSAlgorithmAndParameters *apOpt,
- NSSItem *signature,
- NSSTime *timeOpt,
- NSSUsage *usage,
- NSSPolicies *policiesOpt,
- NSSCallback *uhh,
- NSSItem *rvOpt,
- NSSArena *arenaOpt
-);
+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
+ * 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_WrapSymmetricKey(
+ NSSCertificate *c,
+ NSSAlgorithmAndParameters *apOpt,
+ NSSSymmetricKey *keyToWrap,
+ NSSTime *timeOpt,
+ NSSUsage *usage,
+ NSSPolicies *policiesOpt,
+ NSSCallback *uhh,
+ NSSItem *rvOpt,
+ NSSArena *arenaOpt);
/*
* NSSCertificate_CreateCryptoContext
@@ -353,15 +323,13 @@ NSSCertificate_WrapSymmetricKey
*/
NSS_EXTERN NSSCryptoContext *
-NSSCertificate_CreateCryptoContext
-(
- NSSCertificate *c,
- NSSAlgorithmAndParameters *apOpt,
- NSSTime *timeOpt,
- NSSUsage *usage,
- NSSPolicies *policiesOpt,
- NSSCallback *uhh
-);
+NSSCertificate_CreateCryptoContext(
+ NSSCertificate *c,
+ NSSAlgorithmAndParameters *apOpt,
+ NSSTime *timeOpt,
+ NSSUsage *usage,
+ NSSPolicies *policiesOpt,
+ NSSCallback *uhh);
/*
* NSSCertificate_GetPublicKey
@@ -370,10 +338,7 @@ NSSCertificate_CreateCryptoContext
*/
NSS_EXTERN NSSPublicKey *
-NSSCertificate_GetPublicKey
-(
- NSSCertificate *c
-);
+NSSCertificate_GetPublicKey(NSSCertificate *c);
/*
* NSSCertificate_FindPrivateKey
@@ -385,11 +350,9 @@ NSSCertificate_GetPublicKey
*/
NSS_EXTERN NSSPrivateKey *
-NSSCertificate_FindPrivateKey
-(
- NSSCertificate *c,
- NSSCallback *uhh
-);
+NSSCertificate_FindPrivateKey(
+ NSSCertificate *c,
+ NSSCallback *uhh);
/*
* NSSCertificate_IsPrivateKeyAvailable
@@ -401,15 +364,13 @@ NSSCertificate_FindPrivateKey
*/
NSS_EXTERN PRBool
-NSSCertificate_IsPrivateKeyAvailable
-(
- NSSCertificate *c,
- NSSCallback *uhh,
- PRStatus *statusOpt
-);
+NSSCertificate_IsPrivateKeyAvailable(
+ NSSCertificate *c,
+ NSSCallback *uhh,
+ PRStatus *statusOpt);
/*
- * If we make NSSUserCertificate not a typedef of NSSCertificate,
+ * If we make NSSUserCertificate not a typedef of NSSCertificate,
* then we'll need implementations of the following:
*
* NSSUserCertificate_Destroy
@@ -438,11 +399,9 @@ NSSCertificate_IsPrivateKeyAvailable
*/
NSS_EXTERN PRBool
-NSSUserCertificate_IsStillPresent
-(
- NSSUserCertificate *uc,
- PRStatus *statusOpt
-);
+NSSUserCertificate_IsStillPresent(
+ NSSUserCertificate *uc,
+ PRStatus *statusOpt);
/*
* NSSUserCertificate_Decrypt
@@ -452,18 +411,16 @@ NSSUserCertificate_IsStillPresent
*/
NSS_EXTERN NSSItem *
-NSSUserCertificate_Decrypt
-(
- NSSUserCertificate *uc,
- NSSAlgorithmAndParameters *apOpt,
- NSSItem *data,
- NSSTime *timeOpt,
- NSSUsage *usage,
- NSSPolicies *policiesOpt,
- NSSCallback *uhh,
- NSSItem *rvOpt,
- NSSArena *arenaOpt
-);
+NSSUserCertificate_Decrypt(
+ NSSUserCertificate *uc,
+ NSSAlgorithmAndParameters *apOpt,
+ NSSItem *data,
+ NSSTime *timeOpt,
+ NSSUsage *usage,
+ NSSPolicies *policiesOpt,
+ NSSCallback *uhh,
+ NSSItem *rvOpt,
+ NSSArena *arenaOpt);
/*
* NSSUserCertificate_Sign
@@ -471,18 +428,16 @@ NSSUserCertificate_Decrypt
*/
NSS_EXTERN NSSItem *
-NSSUserCertificate_Sign
-(
- NSSUserCertificate *uc,
- NSSAlgorithmAndParameters *apOpt,
- NSSItem *data,
- NSSTime *timeOpt,
- NSSUsage *usage,
- NSSPolicies *policiesOpt,
- NSSCallback *uhh,
- NSSItem *rvOpt,
- NSSArena *arenaOpt
-);
+NSSUserCertificate_Sign(
+ NSSUserCertificate *uc,
+ NSSAlgorithmAndParameters *apOpt,
+ NSSItem *data,
+ NSSTime *timeOpt,
+ NSSUsage *usage,
+ NSSPolicies *policiesOpt,
+ NSSCallback *uhh,
+ NSSItem *rvOpt,
+ NSSArena *arenaOpt);
/*
* NSSUserCertificate_SignRecover
@@ -490,18 +445,16 @@ NSSUserCertificate_Sign
*/
NSS_EXTERN NSSItem *
-NSSUserCertificate_SignRecover
-(
- NSSUserCertificate *uc,
- NSSAlgorithmAndParameters *apOpt,
- NSSItem *data,
- NSSTime *timeOpt,
- NSSUsage *usage,
- NSSPolicies *policiesOpt,
- NSSCallback *uhh,
- NSSItem *rvOpt,
- NSSArena *arenaOpt
-);
+NSSUserCertificate_SignRecover(
+ NSSUserCertificate *uc,
+ NSSAlgorithmAndParameters *apOpt,
+ NSSItem *data,
+ NSSTime *timeOpt,
+ NSSUsage *usage,
+ NSSPolicies *policiesOpt,
+ NSSCallback *uhh,
+ NSSItem *rvOpt,
+ NSSArena *arenaOpt);
/*
* NSSUserCertificate_UnwrapSymmetricKey
@@ -509,18 +462,16 @@ NSSUserCertificate_SignRecover
*/
NSS_EXTERN NSSSymmetricKey *
-NSSUserCertificate_UnwrapSymmetricKey
-(
- NSSUserCertificate *uc,
- NSSAlgorithmAndParameters *apOpt,
- NSSItem *wrappedKey,
- NSSTime *timeOpt,
- NSSUsage *usage,
- NSSPolicies *policiesOpt,
- NSSCallback *uhh,
- NSSItem *rvOpt,
- NSSArena *arenaOpt
-);
+NSSUserCertificate_UnwrapSymmetricKey(
+ NSSUserCertificate *uc,
+ NSSAlgorithmAndParameters *apOpt,
+ NSSItem *wrappedKey,
+ NSSTime *timeOpt,
+ NSSUsage *usage,
+ NSSPolicies *policiesOpt,
+ NSSCallback *uhh,
+ NSSItem *rvOpt,
+ NSSArena *arenaOpt);
/*
* NSSUserCertificate_DeriveSymmetricKey
@@ -528,16 +479,14 @@ NSSUserCertificate_UnwrapSymmetricKey
*/
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
-);
+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) */
@@ -557,10 +506,7 @@ NSSUserCertificate_DeriveSymmetricKey
*/
NSS_EXTERN PRStatus
-NSSPrivateKey_Destroy
-(
- NSSPrivateKey *vk
-);
+NSSPrivateKey_Destroy(NSSPrivateKey *vk);
/*
* NSSPrivateKey_DeleteStoredObject
@@ -570,11 +516,9 @@ NSSPrivateKey_Destroy
*/
NSS_EXTERN PRStatus
-NSSPrivateKey_DeleteStoredObject
-(
- NSSPrivateKey *vk,
- NSSCallback *uhh
-);
+NSSPrivateKey_DeleteStoredObject(
+ NSSPrivateKey *vk,
+ NSSCallback *uhh);
/*
* NSSPrivateKey_GetSignatureLength
@@ -582,10 +526,7 @@ NSSPrivateKey_DeleteStoredObject
*/
NSS_EXTERN PRUint32
-NSSPrivateKey_GetSignatureLength
-(
- NSSPrivateKey *vk
-);
+NSSPrivateKey_GetSignatureLength(NSSPrivateKey *vk);
/*
* NSSPrivateKey_GetPrivateModulusLength
@@ -593,10 +534,7 @@ NSSPrivateKey_GetSignatureLength
*/
NSS_EXTERN PRUint32
-NSSPrivateKey_GetPrivateModulusLength
-(
- NSSPrivateKey *vk
-);
+NSSPrivateKey_GetPrivateModulusLength(NSSPrivateKey *vk);
/*
* NSSPrivateKey_IsStillPresent
@@ -604,11 +542,9 @@ NSSPrivateKey_GetPrivateModulusLength
*/
NSS_EXTERN PRBool
-NSSPrivateKey_IsStillPresent
-(
- NSSPrivateKey *vk,
- PRStatus *statusOpt
-);
+NSSPrivateKey_IsStillPresent(
+ NSSPrivateKey *vk,
+ PRStatus *statusOpt);
/*
* NSSPrivateKey_Encode
@@ -616,15 +552,13 @@ NSSPrivateKey_IsStillPresent
*/
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_Encode(
+ NSSPrivateKey *vk,
+ NSSAlgorithmAndParameters *ap,
+ NSSItem *passwordOpt, /* NULL will cause a callback; "" for no password */
+ NSSCallback *uhhOpt,
+ NSSItem *rvOpt,
+ NSSArena *arenaOpt);
/*
* NSSPrivateKey_GetTrustDomain
@@ -633,11 +567,9 @@ NSSPrivateKey_Encode
*/
NSS_EXTERN NSSTrustDomain *
-NSSPrivateKey_GetTrustDomain
-(
- NSSPrivateKey *vk,
- PRStatus *statusOpt
-);
+NSSPrivateKey_GetTrustDomain(
+ NSSPrivateKey *vk,
+ PRStatus *statusOpt);
/*
* NSSPrivateKey_GetToken
@@ -645,10 +577,7 @@ NSSPrivateKey_GetTrustDomain
*/
NSS_EXTERN NSSToken *
-NSSPrivateKey_GetToken
-(
- NSSPrivateKey *vk
-);
+NSSPrivateKey_GetToken(NSSPrivateKey *vk);
/*
* NSSPrivateKey_GetSlot
@@ -656,10 +585,7 @@ NSSPrivateKey_GetToken
*/
NSS_EXTERN NSSSlot *
-NSSPrivateKey_GetSlot
-(
- NSSPrivateKey *vk
-);
+NSSPrivateKey_GetSlot(NSSPrivateKey *vk);
/*
* NSSPrivateKey_GetModule
@@ -667,10 +593,7 @@ NSSPrivateKey_GetSlot
*/
NSS_EXTERN NSSModule *
-NSSPrivateKey_GetModule
-(
- NSSPrivateKey *vk
-);
+NSSPrivateKey_GetModule(NSSPrivateKey *vk);
/*
* NSSPrivateKey_Decrypt
@@ -678,15 +601,13 @@ NSSPrivateKey_GetModule
*/
NSS_EXTERN NSSItem *
-NSSPrivateKey_Decrypt
-(
- NSSPrivateKey *vk,
- NSSAlgorithmAndParameters *apOpt,
- NSSItem *encryptedData,
- NSSCallback *uhh,
- NSSItem *rvOpt,
- NSSArena *arenaOpt
-);
+NSSPrivateKey_Decrypt(
+ NSSPrivateKey *vk,
+ NSSAlgorithmAndParameters *apOpt,
+ NSSItem *encryptedData,
+ NSSCallback *uhh,
+ NSSItem *rvOpt,
+ NSSArena *arenaOpt);
/*
* NSSPrivateKey_Sign
@@ -694,15 +615,13 @@ NSSPrivateKey_Decrypt
*/
NSS_EXTERN NSSItem *
-NSSPrivateKey_Sign
-(
- NSSPrivateKey *vk,
- NSSAlgorithmAndParameters *apOpt,
- NSSItem *data,
- NSSCallback *uhh,
- NSSItem *rvOpt,
- NSSArena *arenaOpt
-);
+NSSPrivateKey_Sign(
+ NSSPrivateKey *vk,
+ NSSAlgorithmAndParameters *apOpt,
+ NSSItem *data,
+ NSSCallback *uhh,
+ NSSItem *rvOpt,
+ NSSArena *arenaOpt);
/*
* NSSPrivateKey_SignRecover
@@ -710,15 +629,13 @@ NSSPrivateKey_Sign
*/
NSS_EXTERN NSSItem *
-NSSPrivateKey_SignRecover
-(
- NSSPrivateKey *vk,
- NSSAlgorithmAndParameters *apOpt,
- NSSItem *data,
- NSSCallback *uhh,
- NSSItem *rvOpt,
- NSSArena *arenaOpt
-);
+NSSPrivateKey_SignRecover(
+ NSSPrivateKey *vk,
+ NSSAlgorithmAndParameters *apOpt,
+ NSSItem *data,
+ NSSCallback *uhh,
+ NSSItem *rvOpt,
+ NSSArena *arenaOpt);
/*
* NSSPrivateKey_UnwrapSymmetricKey
@@ -726,13 +643,11 @@ NSSPrivateKey_SignRecover
*/
NSS_EXTERN NSSSymmetricKey *
-NSSPrivateKey_UnwrapSymmetricKey
-(
- NSSPrivateKey *vk,
- NSSAlgorithmAndParameters *apOpt,
- NSSItem *wrappedKey,
- NSSCallback *uhh
-);
+NSSPrivateKey_UnwrapSymmetricKey(
+ NSSPrivateKey *vk,
+ NSSAlgorithmAndParameters *apOpt,
+ NSSItem *wrappedKey,
+ NSSCallback *uhh);
/*
* NSSPrivateKey_DeriveSymmetricKey
@@ -740,16 +655,14 @@ NSSPrivateKey_UnwrapSymmetricKey
*/
NSS_EXTERN NSSSymmetricKey *
-NSSPrivateKey_DeriveSymmetricKey
-(
- NSSPrivateKey *vk,
- NSSPublicKey *bk,
- NSSAlgorithmAndParameters *apOpt,
- NSSOID *target,
- PRUint32 keySizeOpt, /* zero for best allowed */
- NSSOperations operations,
- NSSCallback *uhh
-);
+NSSPrivateKey_DeriveSymmetricKey(
+ NSSPrivateKey *vk,
+ NSSPublicKey *bk,
+ NSSAlgorithmAndParameters *apOpt,
+ NSSOID *target,
+ PRUint32 keySizeOpt, /* zero for best allowed */
+ NSSOperations operations,
+ NSSCallback *uhh);
/*
* NSSPrivateKey_FindPublicKey
@@ -757,11 +670,10 @@ NSSPrivateKey_DeriveSymmetricKey
*/
NSS_EXTERN NSSPublicKey *
-NSSPrivateKey_FindPublicKey
-(
- NSSPrivateKey *vk
- /* { don't need the callback here, right? } */
-);
+NSSPrivateKey_FindPublicKey(
+ NSSPrivateKey *vk
+ /* { don't need the callback here, right? } */
+ );
/*
* NSSPrivateKey_CreateCryptoContext
@@ -771,12 +683,10 @@ NSSPrivateKey_FindPublicKey
*/
NSS_EXTERN NSSCryptoContext *
-NSSPrivateKey_CreateCryptoContext
-(
- NSSPrivateKey *vk,
- NSSAlgorithmAndParameters *apOpt,
- NSSCallback *uhh
-);
+NSSPrivateKey_CreateCryptoContext(
+ NSSPrivateKey *vk,
+ NSSAlgorithmAndParameters *apOpt,
+ NSSCallback *uhh);
/*
* NSSPrivateKey_FindCertificates
@@ -787,13 +697,11 @@ NSSPrivateKey_CreateCryptoContext
*/
NSS_EXTERN NSSCertificate **
-NSSPrivateKey_FindCertificates
-(
- NSSPrivateKey *vk,
- NSSCertificate *rvOpt[],
- PRUint32 maximumOpt, /* 0 for no max */
- NSSArena *arenaOpt
-);
+NSSPrivateKey_FindCertificates(
+ NSSPrivateKey *vk,
+ NSSCertificate *rvOpt[],
+ PRUint32 maximumOpt, /* 0 for no max */
+ NSSArena *arenaOpt);
/*
* NSSPrivateKey_FindBestCertificate
@@ -803,13 +711,11 @@ NSSPrivateKey_FindCertificates
*/
NSS_EXTERN NSSCertificate *
-NSSPrivateKey_FindBestCertificate
-(
- NSSPrivateKey *vk,
- NSSTime *timeOpt,
- NSSUsage *usageOpt,
- NSSPolicies *policiesOpt
-);
+NSSPrivateKey_FindBestCertificate(
+ NSSPrivateKey *vk,
+ NSSTime *timeOpt,
+ NSSUsage *usageOpt,
+ NSSPolicies *policiesOpt);
/*
* NSSPublicKey
@@ -827,10 +733,7 @@ NSSPrivateKey_FindBestCertificate
*/
NSS_EXTERN PRStatus
-NSSPublicKey_Destroy
-(
- NSSPublicKey *bk
-);
+NSSPublicKey_Destroy(NSSPublicKey *bk);
/*
* NSSPublicKey_DeleteStoredObject
@@ -840,11 +743,9 @@ NSSPublicKey_Destroy
*/
NSS_EXTERN PRStatus
-NSSPublicKey_DeleteStoredObject
-(
- NSSPublicKey *bk,
- NSSCallback *uhh
-);
+NSSPublicKey_DeleteStoredObject(
+ NSSPublicKey *bk,
+ NSSCallback *uhh);
/*
* NSSPublicKey_Encode
@@ -852,14 +753,12 @@ NSSPublicKey_DeleteStoredObject
*/
NSS_EXTERN NSSItem *
-NSSPublicKey_Encode
-(
- NSSPublicKey *bk,
- NSSAlgorithmAndParameters *ap,
- NSSCallback *uhhOpt,
- NSSItem *rvOpt,
- NSSArena *arenaOpt
-);
+NSSPublicKey_Encode(
+ NSSPublicKey *bk,
+ NSSAlgorithmAndParameters *ap,
+ NSSCallback *uhhOpt,
+ NSSItem *rvOpt,
+ NSSArena *arenaOpt);
/*
* NSSPublicKey_GetTrustDomain
@@ -868,11 +767,9 @@ NSSPublicKey_Encode
*/
NSS_EXTERN NSSTrustDomain *
-NSSPublicKey_GetTrustDomain
-(
- NSSPublicKey *bk,
- PRStatus *statusOpt
-);
+NSSPublicKey_GetTrustDomain(
+ NSSPublicKey *bk,
+ PRStatus *statusOpt);
/*
* NSSPublicKey_GetToken
@@ -881,11 +778,9 @@ NSSPublicKey_GetTrustDomain
*/
NSS_EXTERN NSSToken *
-NSSPublicKey_GetToken
-(
- NSSPublicKey *bk,
- PRStatus *statusOpt
-);
+NSSPublicKey_GetToken(
+ NSSPublicKey *bk,
+ PRStatus *statusOpt);
/*
* NSSPublicKey_GetSlot
@@ -894,11 +789,9 @@ NSSPublicKey_GetToken
*/
NSS_EXTERN NSSSlot *
-NSSPublicKey_GetSlot
-(
- NSSPublicKey *bk,
- PRStatus *statusOpt
-);
+NSSPublicKey_GetSlot(
+ NSSPublicKey *bk,
+ PRStatus *statusOpt);
/*
* NSSPublicKey_GetModule
@@ -907,11 +800,9 @@ NSSPublicKey_GetSlot
*/
NSS_EXTERN NSSModule *
-NSSPublicKey_GetModule
-(
- NSSPublicKey *bk,
- PRStatus *statusOpt
-);
+NSSPublicKey_GetModule(
+ NSSPublicKey *bk,
+ PRStatus *statusOpt);
/*
* NSSPublicKey_Encrypt
@@ -921,15 +812,13 @@ NSSPublicKey_GetModule
*/
NSS_EXTERN NSSItem *
-NSSPublicKey_Encrypt
-(
- NSSPublicKey *bk,
- NSSAlgorithmAndParameters *apOpt,
- NSSItem *data,
- NSSCallback *uhh,
- NSSItem *rvOpt,
- NSSArena *arenaOpt
-);
+NSSPublicKey_Encrypt(
+ NSSPublicKey *bk,
+ NSSAlgorithmAndParameters *apOpt,
+ NSSItem *data,
+ NSSCallback *uhh,
+ NSSItem *rvOpt,
+ NSSArena *arenaOpt);
/*
* NSSPublicKey_Verify
@@ -937,14 +826,12 @@ NSSPublicKey_Encrypt
*/
NSS_EXTERN PRStatus
-NSSPublicKey_Verify
-(
- NSSPublicKey *bk,
- NSSAlgorithmAndParameters *apOpt,
- NSSItem *data,
- NSSItem *signature,
- NSSCallback *uhh
-);
+NSSPublicKey_Verify(
+ NSSPublicKey *bk,
+ NSSAlgorithmAndParameters *apOpt,
+ NSSItem *data,
+ NSSItem *signature,
+ NSSCallback *uhh);
/*
* NSSPublicKey_VerifyRecover
@@ -952,15 +839,13 @@ NSSPublicKey_Verify
*/
NSS_EXTERN NSSItem *
-NSSPublicKey_VerifyRecover
-(
- NSSPublicKey *bk,
- NSSAlgorithmAndParameters *apOpt,
- NSSItem *signature,
- NSSCallback *uhh,
- NSSItem *rvOpt,
- NSSArena *arenaOpt
-);
+NSSPublicKey_VerifyRecover(
+ NSSPublicKey *bk,
+ NSSAlgorithmAndParameters *apOpt,
+ NSSItem *signature,
+ NSSCallback *uhh,
+ NSSItem *rvOpt,
+ NSSArena *arenaOpt);
/*
* NSSPublicKey_WrapSymmetricKey
@@ -968,15 +853,13 @@ NSSPublicKey_VerifyRecover
*/
NSS_EXTERN NSSItem *
-NSSPublicKey_WrapSymmetricKey
-(
- NSSPublicKey *bk,
- NSSAlgorithmAndParameters *apOpt,
- NSSSymmetricKey *keyToWrap,
- NSSCallback *uhh,
- NSSItem *rvOpt,
- NSSArena *arenaOpt
-);
+NSSPublicKey_WrapSymmetricKey(
+ NSSPublicKey *bk,
+ NSSAlgorithmAndParameters *apOpt,
+ NSSSymmetricKey *keyToWrap,
+ NSSCallback *uhh,
+ NSSItem *rvOpt,
+ NSSArena *arenaOpt);
/*
* NSSPublicKey_CreateCryptoContext
@@ -986,12 +869,10 @@ NSSPublicKey_WrapSymmetricKey
*/
NSS_EXTERN NSSCryptoContext *
-NSSPublicKey_CreateCryptoContext
-(
- NSSPublicKey *bk,
- NSSAlgorithmAndParameters *apOpt,
- NSSCallback *uhh
-);
+NSSPublicKey_CreateCryptoContext(
+ NSSPublicKey *bk,
+ NSSAlgorithmAndParameters *apOpt,
+ NSSCallback *uhh);
/*
* NSSPublicKey_FindCertificates
@@ -1005,13 +886,11 @@ NSSPublicKey_CreateCryptoContext
*/
NSS_EXTERN NSSCertificate **
-NSSPublicKey_FindCertificates
-(
- NSSPublicKey *bk,
- NSSCertificate *rvOpt[],
- PRUint32 maximumOpt, /* 0 for no max */
- NSSArena *arenaOpt
-);
+NSSPublicKey_FindCertificates(
+ NSSPublicKey *bk,
+ NSSCertificate *rvOpt[],
+ PRUint32 maximumOpt, /* 0 for no max */
+ NSSArena *arenaOpt);
/*
* NSSPrivateKey_FindBestCertificate
@@ -1021,13 +900,11 @@ NSSPublicKey_FindCertificates
*/
NSS_EXTERN NSSCertificate *
-NSSPublicKey_FindBestCertificate
-(
- NSSPublicKey *bk,
- NSSTime *timeOpt,
- NSSUsage *usageOpt,
- NSSPolicies *policiesOpt
-);
+NSSPublicKey_FindBestCertificate(
+ NSSPublicKey *bk,
+ NSSTime *timeOpt,
+ NSSUsage *usageOpt,
+ NSSPolicies *policiesOpt);
/*
* NSSPublicKey_FindPrivateKey
@@ -1035,11 +912,9 @@ NSSPublicKey_FindBestCertificate
*/
NSS_EXTERN NSSPrivateKey *
-NSSPublicKey_FindPrivateKey
-(
- NSSPublicKey *bk,
- NSSCallback *uhh
-);
+NSSPublicKey_FindPrivateKey(
+ NSSPublicKey *bk,
+ NSSCallback *uhh);
/*
* NSSSymmetricKey
@@ -1053,10 +928,7 @@ NSSPublicKey_FindPrivateKey
*/
NSS_EXTERN PRStatus
-NSSSymmetricKey_Destroy
-(
- NSSSymmetricKey *mk
-);
+NSSSymmetricKey_Destroy(NSSSymmetricKey *mk);
/*
* NSSSymmetricKey_DeleteStoredObject
@@ -1065,11 +937,9 @@ NSSSymmetricKey_Destroy
*/
NSS_EXTERN PRStatus
-NSSSymmetricKey_DeleteStoredObject
-(
- NSSSymmetricKey *mk,
- NSSCallback *uhh
-);
+NSSSymmetricKey_DeleteStoredObject(
+ NSSSymmetricKey *mk,
+ NSSCallback *uhh);
/*
* NSSSymmetricKey_GetKeyLength
@@ -1077,10 +947,7 @@ NSSSymmetricKey_DeleteStoredObject
*/
NSS_EXTERN PRUint32
-NSSSymmetricKey_GetKeyLength
-(
- NSSSymmetricKey *mk
-);
+NSSSymmetricKey_GetKeyLength(NSSSymmetricKey *mk);
/*
* NSSSymmetricKey_GetKeyStrength
@@ -1088,10 +955,7 @@ NSSSymmetricKey_GetKeyLength
*/
NSS_EXTERN PRUint32
-NSSSymmetricKey_GetKeyStrength
-(
- NSSSymmetricKey *mk
-);
+NSSSymmetricKey_GetKeyStrength(NSSSymmetricKey *mk);
/*
* NSSSymmetricKey_IsStillPresent
@@ -1099,10 +963,7 @@ NSSSymmetricKey_GetKeyStrength
*/
NSS_EXTERN PRStatus
-NSSSymmetricKey_IsStillPresent
-(
- NSSSymmetricKey *mk
-);
+NSSSymmetricKey_IsStillPresent(NSSSymmetricKey *mk);
/*
* NSSSymmetricKey_GetTrustDomain
@@ -1111,11 +972,9 @@ NSSSymmetricKey_IsStillPresent
*/
NSS_EXTERN NSSTrustDomain *
-NSSSymmetricKey_GetTrustDomain
-(
- NSSSymmetricKey *mk,
- PRStatus *statusOpt
-);
+NSSSymmetricKey_GetTrustDomain(
+ NSSSymmetricKey *mk,
+ PRStatus *statusOpt);
/*
* NSSSymmetricKey_GetToken
@@ -1124,11 +983,9 @@ NSSSymmetricKey_GetTrustDomain
*/
NSS_EXTERN NSSToken *
-NSSSymmetricKey_GetToken
-(
- NSSSymmetricKey *mk,
- PRStatus *statusOpt
-);
+NSSSymmetricKey_GetToken(
+ NSSSymmetricKey *mk,
+ PRStatus *statusOpt);
/*
* NSSSymmetricKey_GetSlot
@@ -1137,11 +994,9 @@ NSSSymmetricKey_GetToken
*/
NSS_EXTERN NSSSlot *
-NSSSymmetricKey_GetSlot
-(
- NSSSymmetricKey *mk,
- PRStatus *statusOpt
-);
+NSSSymmetricKey_GetSlot(
+ NSSSymmetricKey *mk,
+ PRStatus *statusOpt);
/*
* NSSSymmetricKey_GetModule
@@ -1150,11 +1005,9 @@ NSSSymmetricKey_GetSlot
*/
NSS_EXTERN NSSModule *
-NSSSymmetricKey_GetModule
-(
- NSSSymmetricKey *mk,
- PRStatus *statusOpt
-);
+NSSSymmetricKey_GetModule(
+ NSSSymmetricKey *mk,
+ PRStatus *statusOpt);
/*
* NSSSymmetricKey_Encrypt
@@ -1162,15 +1015,13 @@ NSSSymmetricKey_GetModule
*/
NSS_EXTERN NSSItem *
-NSSSymmetricKey_Encrypt
-(
- NSSSymmetricKey *mk,
- NSSAlgorithmAndParameters *apOpt,
- NSSItem *data,
- NSSCallback *uhh,
- NSSItem *rvOpt,
- NSSArena *arenaOpt
-);
+NSSSymmetricKey_Encrypt(
+ NSSSymmetricKey *mk,
+ NSSAlgorithmAndParameters *apOpt,
+ NSSItem *data,
+ NSSCallback *uhh,
+ NSSItem *rvOpt,
+ NSSArena *arenaOpt);
/*
* NSSSymmetricKey_Decrypt
@@ -1178,15 +1029,13 @@ NSSSymmetricKey_Encrypt
*/
NSS_EXTERN NSSItem *
-NSSSymmetricKey_Decrypt
-(
- NSSSymmetricKey *mk,
- NSSAlgorithmAndParameters *apOpt,
- NSSItem *encryptedData,
- NSSCallback *uhh,
- NSSItem *rvOpt,
- NSSArena *arenaOpt
-);
+NSSSymmetricKey_Decrypt(
+ NSSSymmetricKey *mk,
+ NSSAlgorithmAndParameters *apOpt,
+ NSSItem *encryptedData,
+ NSSCallback *uhh,
+ NSSItem *rvOpt,
+ NSSArena *arenaOpt);
/*
* NSSSymmetricKey_Sign
@@ -1194,15 +1043,13 @@ NSSSymmetricKey_Decrypt
*/
NSS_EXTERN NSSItem *
-NSSSymmetricKey_Sign
-(
- NSSSymmetricKey *mk,
- NSSAlgorithmAndParameters *apOpt,
- NSSItem *data,
- NSSCallback *uhh,
- NSSItem *rvOpt,
- NSSArena *arenaOpt
-);
+NSSSymmetricKey_Sign(
+ NSSSymmetricKey *mk,
+ NSSAlgorithmAndParameters *apOpt,
+ NSSItem *data,
+ NSSCallback *uhh,
+ NSSItem *rvOpt,
+ NSSArena *arenaOpt);
/*
* NSSSymmetricKey_SignRecover
@@ -1210,15 +1057,13 @@ NSSSymmetricKey_Sign
*/
NSS_EXTERN NSSItem *
-NSSSymmetricKey_SignRecover
-(
- NSSSymmetricKey *mk,
- NSSAlgorithmAndParameters *apOpt,
- NSSItem *data,
- NSSCallback *uhh,
- NSSItem *rvOpt,
- NSSArena *arenaOpt
-);
+NSSSymmetricKey_SignRecover(
+ NSSSymmetricKey *mk,
+ NSSAlgorithmAndParameters *apOpt,
+ NSSItem *data,
+ NSSCallback *uhh,
+ NSSItem *rvOpt,
+ NSSArena *arenaOpt);
/*
* NSSSymmetricKey_Verify
@@ -1226,14 +1071,12 @@ NSSSymmetricKey_SignRecover
*/
NSS_EXTERN PRStatus
-NSSSymmetricKey_Verify
-(
- NSSSymmetricKey *mk,
- NSSAlgorithmAndParameters *apOpt,
- NSSItem *data,
- NSSItem *signature,
- NSSCallback *uhh
-);
+NSSSymmetricKey_Verify(
+ NSSSymmetricKey *mk,
+ NSSAlgorithmAndParameters *apOpt,
+ NSSItem *data,
+ NSSItem *signature,
+ NSSCallback *uhh);
/*
* NSSSymmetricKey_VerifyRecover
@@ -1241,15 +1084,13 @@ NSSSymmetricKey_Verify
*/
NSS_EXTERN NSSItem *
-NSSSymmetricKey_VerifyRecover
-(
- NSSSymmetricKey *mk,
- NSSAlgorithmAndParameters *apOpt,
- NSSItem *signature,
- NSSCallback *uhh,
- NSSItem *rvOpt,
- NSSArena *arenaOpt
-);
+NSSSymmetricKey_VerifyRecover(
+ NSSSymmetricKey *mk,
+ NSSAlgorithmAndParameters *apOpt,
+ NSSItem *signature,
+ NSSCallback *uhh,
+ NSSItem *rvOpt,
+ NSSArena *arenaOpt);
/*
* NSSSymmetricKey_WrapSymmetricKey
@@ -1257,15 +1098,13 @@ NSSSymmetricKey_VerifyRecover
*/
NSS_EXTERN NSSItem *
-NSSSymmetricKey_WrapSymmetricKey
-(
- NSSSymmetricKey *wrappingKey,
- NSSAlgorithmAndParameters *apOpt,
- NSSSymmetricKey *keyToWrap,
- NSSCallback *uhh,
- NSSItem *rvOpt,
- NSSArena *arenaOpt
-);
+NSSSymmetricKey_WrapSymmetricKey(
+ NSSSymmetricKey *wrappingKey,
+ NSSAlgorithmAndParameters *apOpt,
+ NSSSymmetricKey *keyToWrap,
+ NSSCallback *uhh,
+ NSSItem *rvOpt,
+ NSSArena *arenaOpt);
/*
* NSSSymmetricKey_WrapPrivateKey
@@ -1273,15 +1112,13 @@ NSSSymmetricKey_WrapSymmetricKey
*/
NSS_EXTERN NSSItem *
-NSSSymmetricKey_WrapPrivateKey
-(
- NSSSymmetricKey *wrappingKey,
- NSSAlgorithmAndParameters *apOpt,
- NSSPrivateKey *keyToWrap,
- NSSCallback *uhh,
- NSSItem *rvOpt,
- NSSArena *arenaOpt
-);
+NSSSymmetricKey_WrapPrivateKey(
+ NSSSymmetricKey *wrappingKey,
+ NSSAlgorithmAndParameters *apOpt,
+ NSSPrivateKey *keyToWrap,
+ NSSCallback *uhh,
+ NSSItem *rvOpt,
+ NSSArena *arenaOpt);
/*
* NSSSymmetricKey_UnwrapSymmetricKey
@@ -1289,16 +1126,14 @@ NSSSymmetricKey_WrapPrivateKey
*/
NSS_EXTERN NSSSymmetricKey *
-NSSSymmetricKey_UnwrapSymmetricKey
-(
- NSSSymmetricKey *wrappingKey,
- NSSAlgorithmAndParameters *apOpt,
- NSSItem *wrappedKey,
- NSSOID *target,
- PRUint32 keySizeOpt,
- NSSOperations operations,
- NSSCallback *uhh
-);
+NSSSymmetricKey_UnwrapSymmetricKey(
+ NSSSymmetricKey *wrappingKey,
+ NSSAlgorithmAndParameters *apOpt,
+ NSSItem *wrappedKey,
+ NSSOID *target,
+ PRUint32 keySizeOpt,
+ NSSOperations operations,
+ NSSCallback *uhh);
/*
* NSSSymmetricKey_UnwrapPrivateKey
@@ -1306,18 +1141,16 @@ NSSSymmetricKey_UnwrapSymmetricKey
*/
NSS_EXTERN NSSPrivateKey *
-NSSSymmetricKey_UnwrapPrivateKey
-(
- NSSSymmetricKey *wrappingKey,
- NSSAlgorithmAndParameters *apOpt,
- NSSItem *wrappedKey,
- NSSUTF8 *labelOpt,
- NSSItem *keyIDOpt,
- PRBool persistant,
- PRBool sensitive,
- NSSToken *destinationOpt,
- NSSCallback *uhh
-);
+NSSSymmetricKey_UnwrapPrivateKey(
+ NSSSymmetricKey *wrappingKey,
+ NSSAlgorithmAndParameters *apOpt,
+ NSSItem *wrappedKey,
+ NSSUTF8 *labelOpt,
+ NSSItem *keyIDOpt,
+ PRBool persistant,
+ PRBool sensitive,
+ NSSToken *destinationOpt,
+ NSSCallback *uhh);
/*
* NSSSymmetricKey_DeriveSymmetricKey
@@ -1325,15 +1158,13 @@ NSSSymmetricKey_UnwrapPrivateKey
*/
NSS_EXTERN NSSSymmetricKey *
-NSSSymmetricKey_DeriveSymmetricKey
-(
- NSSSymmetricKey *originalKey,
- NSSAlgorithmAndParameters *apOpt,
- NSSOID *target,
- PRUint32 keySizeOpt,
- NSSOperations operations,
- NSSCallback *uhh
-);
+NSSSymmetricKey_DeriveSymmetricKey(
+ NSSSymmetricKey *originalKey,
+ NSSAlgorithmAndParameters *apOpt,
+ NSSOID *target,
+ PRUint32 keySizeOpt,
+ NSSOperations operations,
+ NSSCallback *uhh);
/*
* NSSSymmetricKey_CreateCryptoContext
@@ -1343,12 +1174,10 @@ NSSSymmetricKey_DeriveSymmetricKey
*/
NSS_EXTERN NSSCryptoContext *
-NSSSymmetricKey_CreateCryptoContext
-(
- NSSSymmetricKey *mk,
- NSSAlgorithmAndParameters *apOpt,
- NSSCallback *uhh
-);
+NSSSymmetricKey_CreateCryptoContext(
+ NSSSymmetricKey *mk,
+ NSSAlgorithmAndParameters *apOpt,
+ NSSCallback *uhh);
/*
* NSSTrustDomain
@@ -1367,7 +1196,7 @@ NSSSymmetricKey_CreateCryptoContext
*
* 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
+ * 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
@@ -1375,13 +1204,11 @@ NSSSymmetricKey_CreateCryptoContext
*/
NSS_EXTERN NSSTrustDomain *
-NSSTrustDomain_Create
-(
- NSSUTF8 *moduleOpt,
- NSSUTF8 *uriOpt,
- NSSUTF8 *opaqueOpt,
- void *reserved
-);
+NSSTrustDomain_Create(
+ NSSUTF8 *moduleOpt,
+ NSSUTF8 *uriOpt,
+ NSSUTF8 *opaqueOpt,
+ void *reserved);
/*
* NSSTrustDomain_Destroy
@@ -1389,10 +1216,7 @@ NSSTrustDomain_Create
*/
NSS_EXTERN PRStatus
-NSSTrustDomain_Destroy
-(
- NSSTrustDomain *td
-);
+NSSTrustDomain_Destroy(NSSTrustDomain *td);
/*
* NSSTrustDomain_SetDefaultCallback
@@ -1400,12 +1224,10 @@ NSSTrustDomain_Destroy
*/
NSS_EXTERN PRStatus
-NSSTrustDomain_SetDefaultCallback
-(
- NSSTrustDomain *td,
- NSSCallback *newCallback,
- NSSCallback **oldCallbackOpt
-);
+NSSTrustDomain_SetDefaultCallback(
+ NSSTrustDomain *td,
+ NSSCallback *newCallback,
+ NSSCallback **oldCallbackOpt);
/*
* NSSTrustDomain_GetDefaultCallback
@@ -1413,11 +1235,9 @@ NSSTrustDomain_SetDefaultCallback
*/
NSS_EXTERN NSSCallback *
-NSSTrustDomain_GetDefaultCallback
-(
- NSSTrustDomain *td,
- PRStatus *statusOpt
-);
+NSSTrustDomain_GetDefaultCallback(
+ NSSTrustDomain *td,
+ PRStatus *statusOpt);
/*
* Default policies?
@@ -1431,14 +1251,12 @@ NSSTrustDomain_GetDefaultCallback
*/
NSS_EXTERN PRStatus
-NSSTrustDomain_LoadModule
-(
- NSSTrustDomain *td,
- NSSUTF8 *moduleOpt,
- NSSUTF8 *uriOpt,
- NSSUTF8 *opaqueOpt,
- void *reserved
-);
+NSSTrustDomain_LoadModule(
+ NSSTrustDomain *td,
+ NSSUTF8 *moduleOpt,
+ NSSUTF8 *uriOpt,
+ NSSUTF8 *opaqueOpt,
+ void *reserved);
/*
* NSSTrustDomain_AddModule
@@ -1455,12 +1273,10 @@ NSSTrustDomain_LoadModule
*/
NSS_EXTERN PRStatus
-NSSTrustDomain_DisableToken
-(
- NSSTrustDomain *td,
- NSSToken *token,
- NSSError why
-);
+NSSTrustDomain_DisableToken(
+ NSSTrustDomain *td,
+ NSSToken *token,
+ NSSError why);
/*
* NSSTrustDomain_EnableToken
@@ -1468,11 +1284,9 @@ NSSTrustDomain_DisableToken
*/
NSS_EXTERN PRStatus
-NSSTrustDomain_EnableToken
-(
- NSSTrustDomain *td,
- NSSToken *token
-);
+NSSTrustDomain_EnableToken(
+ NSSTrustDomain *td,
+ NSSToken *token);
/*
* NSSTrustDomain_IsTokenEnabled
@@ -1482,12 +1296,10 @@ NSSTrustDomain_EnableToken
*/
NSS_EXTERN PRStatus
-NSSTrustDomain_IsTokenEnabled
-(
- NSSTrustDomain *td,
- NSSToken *token,
- NSSError *whyOpt
-);
+NSSTrustDomain_IsTokenEnabled(
+ NSSTrustDomain *td,
+ NSSToken *token,
+ NSSError *whyOpt);
/*
* NSSTrustDomain_FindSlotByName
@@ -1495,11 +1307,9 @@ NSSTrustDomain_IsTokenEnabled
*/
NSS_EXTERN NSSSlot *
-NSSTrustDomain_FindSlotByName
-(
- NSSTrustDomain *td,
- NSSUTF8 *slotName
-);
+NSSTrustDomain_FindSlotByName(
+ NSSTrustDomain *td,
+ NSSUTF8 *slotName);
/*
* NSSTrustDomain_FindTokenByName
@@ -1507,11 +1317,9 @@ NSSTrustDomain_FindSlotByName
*/
NSS_EXTERN NSSToken *
-NSSTrustDomain_FindTokenByName
-(
- NSSTrustDomain *td,
- NSSUTF8 *tokenName
-);
+NSSTrustDomain_FindTokenByName(
+ NSSTrustDomain *td,
+ NSSUTF8 *tokenName);
/*
* NSSTrustDomain_FindTokenBySlotName
@@ -1519,11 +1327,9 @@ NSSTrustDomain_FindTokenByName
*/
NSS_EXTERN NSSToken *
-NSSTrustDomain_FindTokenBySlotName
-(
- NSSTrustDomain *td,
- NSSUTF8 *slotName
-);
+NSSTrustDomain_FindTokenBySlotName(
+ NSSTrustDomain *td,
+ NSSUTF8 *slotName);
/*
* NSSTrustDomain_FindBestTokenForAlgorithm
@@ -1531,11 +1337,9 @@ NSSTrustDomain_FindTokenBySlotName
*/
NSS_EXTERN NSSToken *
-NSSTrustDomain_FindTokenForAlgorithm
-(
- NSSTrustDomain *td,
- NSSOID *algorithm
-);
+NSSTrustDomain_FindTokenForAlgorithm(
+ NSSTrustDomain *td,
+ NSSOID *algorithm);
/*
* NSSTrustDomain_FindBestTokenForAlgorithms
@@ -1543,12 +1347,11 @@ NSSTrustDomain_FindTokenForAlgorithm
*/
NSS_EXTERN NSSToken *
-NSSTrustDomain_FindBestTokenForAlgorithms
-(
- NSSTrustDomain *td,
- NSSOID *algorithms[], /* may be null-terminated */
- PRUint32 nAlgorithmsOpt /* limits the array if nonzero */
-);
+NSSTrustDomain_FindBestTokenForAlgorithms(
+ NSSTrustDomain *td,
+ NSSOID *algorithms[], /* may be null-terminated */
+ PRUint32 nAlgorithmsOpt /* limits the array if nonzero */
+ );
/*
* NSSTrustDomain_Login
@@ -1556,11 +1359,9 @@ NSSTrustDomain_FindBestTokenForAlgorithms
*/
NSS_EXTERN PRStatus
-NSSTrustDomain_Login
-(
- NSSTrustDomain *td,
- NSSCallback *uhhOpt
-);
+NSSTrustDomain_Login(
+ NSSTrustDomain *td,
+ NSSCallback *uhhOpt);
/*
* NSSTrustDomain_Logout
@@ -1568,10 +1369,7 @@ NSSTrustDomain_Login
*/
NSS_EXTERN PRStatus
-NSSTrustDomain_Logout
-(
- NSSTrustDomain *td
-);
+NSSTrustDomain_Logout(NSSTrustDomain *td);
/* Importing things */
@@ -1583,11 +1381,9 @@ NSSTrustDomain_Logout
*/
NSS_EXTERN NSSCertificate *
-NSSTrustDomain_ImportCertificate
-(
- NSSTrustDomain *td,
- NSSCertificate *c
-);
+NSSTrustDomain_ImportCertificate(
+ NSSTrustDomain *td,
+ NSSCertificate *c);
/*
* NSSTrustDomain_ImportPKIXCertificate
@@ -1595,12 +1391,10 @@ NSSTrustDomain_ImportCertificate
*/
NSS_EXTERN NSSCertificate *
-NSSTrustDomain_ImportPKIXCertificate
-(
- NSSTrustDomain *td,
- /* declared as a struct until these "data types" are defined */
- struct NSSPKIXCertificateStr *pc
-);
+NSSTrustDomain_ImportPKIXCertificate(
+ NSSTrustDomain *td,
+ /* declared as a struct until these "data types" are defined */
+ struct NSSPKIXCertificateStr *pc);
/*
* NSSTrustDomain_ImportEncodedCertificate
@@ -1609,11 +1403,9 @@ NSSTrustDomain_ImportPKIXCertificate
*/
NSS_EXTERN NSSCertificate *
-NSSTrustDomain_ImportEncodedCertificate
-(
- NSSTrustDomain *td,
- NSSBER *ber
-);
+NSSTrustDomain_ImportEncodedCertificate(
+ NSSTrustDomain *td,
+ NSSBER *ber);
/*
* NSSTrustDomain_ImportEncodedCertificateChain
@@ -1622,14 +1414,12 @@ NSSTrustDomain_ImportEncodedCertificate
*/
NSS_EXTERN NSSCertificate **
-NSSTrustDomain_ImportEncodedCertificateChain
-(
- NSSTrustDomain *td,
- NSSBER *ber,
- NSSCertificate *rvOpt[],
- PRUint32 maximumOpt, /* 0 for no max */
- NSSArena *arenaOpt
-);
+NSSTrustDomain_ImportEncodedCertificateChain(
+ NSSTrustDomain *td,
+ NSSBER *ber,
+ NSSCertificate *rvOpt[],
+ PRUint32 maximumOpt, /* 0 for no max */
+ NSSArena *arenaOpt);
/*
* NSSTrustDomain_ImportEncodedPrivateKey
@@ -1637,14 +1427,12 @@ NSSTrustDomain_ImportEncodedCertificateChain
*/
NSS_EXTERN NSSPrivateKey *
-NSSTrustDomain_ImportEncodedPrivateKey
-(
- NSSTrustDomain *td,
- NSSBER *ber,
- NSSItem *passwordOpt, /* NULL will cause a callback */
- NSSCallback *uhhOpt,
- NSSToken *destination
-);
+NSSTrustDomain_ImportEncodedPrivateKey(
+ NSSTrustDomain *td,
+ NSSBER *ber,
+ NSSItem *passwordOpt, /* NULL will cause a callback */
+ NSSCallback *uhhOpt,
+ NSSToken *destination);
/*
* NSSTrustDomain_ImportEncodedPublicKey
@@ -1652,11 +1440,9 @@ NSSTrustDomain_ImportEncodedPrivateKey
*/
NSS_EXTERN NSSPublicKey *
-NSSTrustDomain_ImportEncodedPublicKey
-(
- NSSTrustDomain *td,
- NSSBER *ber
-);
+NSSTrustDomain_ImportEncodedPublicKey(
+ NSSTrustDomain *td,
+ NSSBER *ber);
/* Other importations: S/MIME capabilities */
@@ -1666,14 +1452,13 @@ NSSTrustDomain_ImportEncodedPublicKey
*/
NSS_EXTERN NSSCertificate *
-NSSTrustDomain_FindBestCertificateByNickname
-(
- NSSTrustDomain *td,
- const NSSUTF8 *name,
- NSSTime *timeOpt, /* NULL for "now" */
- NSSUsage *usage,
- NSSPolicies *policiesOpt /* NULL for none */
-);
+NSSTrustDomain_FindBestCertificateByNickname(
+ NSSTrustDomain *td,
+ const NSSUTF8 *name,
+ NSSTime *timeOpt, /* NULL for "now" */
+ NSSUsage *usage,
+ NSSPolicies *policiesOpt /* NULL for none */
+ );
/*
* NSSTrustDomain_FindCertificatesByNickname
@@ -1681,14 +1466,12 @@ NSSTrustDomain_FindBestCertificateByNickname
*/
NSS_EXTERN NSSCertificate **
-NSSTrustDomain_FindCertificatesByNickname
-(
- NSSTrustDomain *td,
- NSSUTF8 *name,
- NSSCertificate *rvOpt[],
- PRUint32 maximumOpt, /* 0 for no max */
- NSSArena *arenaOpt
-);
+NSSTrustDomain_FindCertificatesByNickname(
+ NSSTrustDomain *td,
+ NSSUTF8 *name,
+ NSSCertificate *rvOpt[],
+ PRUint32 maximumOpt, /* 0 for no max */
+ NSSArena *arenaOpt);
/*
* NSSTrustDomain_FindCertificateByIssuerAndSerialNumber
@@ -1696,12 +1479,10 @@ NSSTrustDomain_FindCertificatesByNickname
*/
NSS_EXTERN NSSCertificate *
-NSSTrustDomain_FindCertificateByIssuerAndSerialNumber
-(
- NSSTrustDomain *td,
- NSSDER *issuer,
- NSSDER *serialNumber
-);
+NSSTrustDomain_FindCertificateByIssuerAndSerialNumber(
+ NSSTrustDomain *td,
+ NSSDER *issuer,
+ NSSDER *serialNumber);
/*
* NSSTrustDomain_FindCertificatesByIssuerAndSerialNumber
@@ -1718,14 +1499,12 @@ NSSTrustDomain_FindCertificateByIssuerAndSerialNumber
*/
NSS_EXTERN NSSCertificate *
-NSSTrustDomain_FindBestCertificateBySubject
-(
- NSSTrustDomain *td,
- NSSDER /*NSSUTF8*/ *subject,
- NSSTime *timeOpt,
- NSSUsage *usage,
- NSSPolicies *policiesOpt
-);
+NSSTrustDomain_FindBestCertificateBySubject(
+ NSSTrustDomain *td,
+ NSSDER /*NSSUTF8*/ *subject,
+ NSSTime *timeOpt,
+ NSSUsage *usage,
+ NSSPolicies *policiesOpt);
/*
* NSSTrustDomain_FindCertificatesBySubject
@@ -1734,33 +1513,29 @@ NSSTrustDomain_FindBestCertificateBySubject
*/
NSS_EXTERN NSSCertificate **
-NSSTrustDomain_FindCertificatesBySubject
-(
- NSSTrustDomain *td,
- NSSDER /*NSSUTF8*/ *subject,
- NSSCertificate *rvOpt[],
- PRUint32 maximumOpt, /* 0 for no max */
- NSSArena *arenaOpt
-);
+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
+ * 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_FindBestCertificateByNameComponents(
+ NSSTrustDomain *td,
+ NSSUTF8 *nameComponents,
+ NSSTime *timeOpt,
+ NSSUsage *usage,
+ NSSPolicies *policiesOpt);
/*
* NSSTrustDomain_FindCertificatesByNameComponents
@@ -1771,14 +1546,12 @@ NSSTrustDomain_FindBestCertificateByNameComponents
*/
NSS_EXTERN NSSCertificate **
-NSSTrustDomain_FindCertificatesByNameComponents
-(
- NSSTrustDomain *td,
- NSSUTF8 *nameComponents,
- NSSCertificate *rvOpt[],
- PRUint32 maximumOpt, /* 0 for no max */
- NSSArena *arenaOpt
-);
+NSSTrustDomain_FindCertificatesByNameComponents(
+ NSSTrustDomain *td,
+ NSSUTF8 *nameComponents,
+ NSSCertificate *rvOpt[],
+ PRUint32 maximumOpt, /* 0 for no max */
+ NSSArena *arenaOpt);
/*
* NSSTrustDomain_FindCertificateByEncodedCertificate
@@ -1786,11 +1559,9 @@ NSSTrustDomain_FindCertificatesByNameComponents
*/
NSS_EXTERN NSSCertificate *
-NSSTrustDomain_FindCertificateByEncodedCertificate
-(
- NSSTrustDomain *td,
- NSSBER *encodedCertificate
-);
+NSSTrustDomain_FindCertificateByEncodedCertificate(
+ NSSTrustDomain *td,
+ NSSBER *encodedCertificate);
/*
* NSSTrustDomain_FindBestCertificateByEmail
@@ -1798,14 +1569,12 @@ NSSTrustDomain_FindCertificateByEncodedCertificate
*/
NSS_EXTERN NSSCertificate *
-NSSTrustDomain_FindCertificateByEmail
-(
- NSSTrustDomain *td,
- NSSASCII7 *email,
- NSSTime *timeOpt,
- NSSUsage *usage,
- NSSPolicies *policiesOpt
-);
+NSSTrustDomain_FindCertificateByEmail(
+ NSSTrustDomain *td,
+ NSSASCII7 *email,
+ NSSTime *timeOpt,
+ NSSUsage *usage,
+ NSSPolicies *policiesOpt);
/*
* NSSTrustDomain_FindCertificatesByEmail
@@ -1813,14 +1582,12 @@ NSSTrustDomain_FindCertificateByEmail
*/
NSS_EXTERN NSSCertificate **
-NSSTrustDomain_FindCertificatesByEmail
-(
- NSSTrustDomain *td,
- NSSASCII7 *email,
- NSSCertificate *rvOpt[],
- PRUint32 maximumOpt, /* 0 for no max */
- NSSArena *arenaOpt
-);
+NSSTrustDomain_FindCertificatesByEmail(
+ NSSTrustDomain *td,
+ NSSASCII7 *email,
+ NSSCertificate *rvOpt[],
+ PRUint32 maximumOpt, /* 0 for no max */
+ NSSArena *arenaOpt);
/*
* NSSTrustDomain_FindCertificateByOCSPHash
@@ -1829,11 +1596,9 @@ NSSTrustDomain_FindCertificatesByEmail
*/
NSS_EXTERN NSSCertificate *
-NSSTrustDomain_FindCertificateByOCSPHash
-(
- NSSTrustDomain *td,
- NSSItem *hash
-);
+NSSTrustDomain_FindCertificateByOCSPHash(
+ NSSTrustDomain *td,
+ NSSItem *hash);
/*
* NSSTrustDomain_TraverseCertificates
@@ -1847,19 +1612,17 @@ NSSTrustDomain_FindCertificateByOCSPHash
* 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_TraverseCertificates(
+ NSSTrustDomain *td,
+ PRStatus (*callback)(NSSCertificate *c, void *arg),
+ void *arg);
/*
* NSSTrustDomain_FindBestUserCertificate
@@ -1867,13 +1630,11 @@ NSSTrustDomain_TraverseCertificates
*/
NSS_EXTERN NSSCertificate *
-NSSTrustDomain_FindBestUserCertificate
-(
- NSSTrustDomain *td,
- NSSTime *timeOpt,
- NSSUsage *usage,
- NSSPolicies *policiesOpt
-);
+NSSTrustDomain_FindBestUserCertificate(
+ NSSTrustDomain *td,
+ NSSTime *timeOpt,
+ NSSUsage *usage,
+ NSSPolicies *policiesOpt);
/*
* NSSTrustDomain_FindUserCertificates
@@ -1881,16 +1642,14 @@ NSSTrustDomain_FindBestUserCertificate
*/
NSS_EXTERN NSSCertificate **
-NSSTrustDomain_FindUserCertificates
-(
- NSSTrustDomain *td,
- NSSTime *timeOpt,
- NSSUsage *usageOpt,
- NSSPolicies *policiesOpt,
- NSSCertificate **rvOpt,
- PRUint32 rvLimit, /* zero for no limit */
- NSSArena *arenaOpt
-);
+NSSTrustDomain_FindUserCertificates(
+ NSSTrustDomain *td,
+ NSSTime *timeOpt,
+ NSSUsage *usageOpt,
+ NSSPolicies *policiesOpt,
+ NSSCertificate **rvOpt,
+ PRUint32 rvLimit, /* zero for no limit */
+ NSSArena *arenaOpt);
/*
* NSSTrustDomain_FindBestUserCertificateForSSLClientAuth
@@ -1898,15 +1657,13 @@ NSSTrustDomain_FindUserCertificates
*/
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_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
@@ -1914,18 +1671,16 @@ NSSTrustDomain_FindBestUserCertificateForSSLClientAuth
*/
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_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
@@ -1933,15 +1688,13 @@ NSSTrustDomain_FindUserCertificatesForSSLClientAuth
*/
NSS_EXTERN NSSCertificate *
-NSSTrustDomain_FindBestUserCertificateForEmailSigning
-(
- NSSTrustDomain *td,
- NSSASCII7 *signerOpt,
- NSSASCII7 *recipientOpt,
- /* anything more here? */
- NSSAlgorithmAndParameters *apOpt,
- NSSPolicies *policiesOpt
-);
+NSSTrustDomain_FindBestUserCertificateForEmailSigning(
+ NSSTrustDomain *td,
+ NSSASCII7 *signerOpt,
+ NSSASCII7 *recipientOpt,
+ /* anything more here? */
+ NSSAlgorithmAndParameters *apOpt,
+ NSSPolicies *policiesOpt);
/*
* NSSTrustDomain_FindUserCertificatesForEmailSigning
@@ -1949,18 +1702,16 @@ NSSTrustDomain_FindBestUserCertificateForEmailSigning
*/
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
-);
+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>
@@ -1980,21 +1731,19 @@ NSSTrustDomain_FindUserCertificatesForEmailSigning
*/
NSS_EXTERN PRStatus
-NSSTrustDomain_GenerateKeyPair
-(
- NSSTrustDomain *td,
- NSSAlgorithmAndParameters *ap,
- NSSPrivateKey **pvkOpt,
- NSSPublicKey **pbkOpt,
- PRBool privateKeyIsSensitive,
- NSSToken *destination,
- NSSCallback *uhhOpt
-);
+NSSTrustDomain_GenerateKeyPair(
+ NSSTrustDomain *td,
+ NSSAlgorithmAndParameters *ap,
+ NSSPrivateKey **pvkOpt,
+ NSSPublicKey **pbkOpt,
+ PRBool privateKeyIsSensitive,
+ NSSToken *destination,
+ NSSCallback *uhhOpt);
/*
* NSSTrustDomain_TraversePrivateKeys
*
- *
+ *
* NSS_EXTERN PRStatus *
* NSSTrustDomain_TraversePrivateKeys
* (
@@ -2012,14 +1761,12 @@ NSSTrustDomain_GenerateKeyPair
*/
NSS_EXTERN NSSSymmetricKey *
-NSSTrustDomain_GenerateSymmetricKey
-(
- NSSTrustDomain *td,
- NSSAlgorithmAndParameters *ap,
- PRUint32 keysize,
- NSSToken *destination,
- NSSCallback *uhhOpt
-);
+NSSTrustDomain_GenerateSymmetricKey(
+ NSSTrustDomain *td,
+ NSSAlgorithmAndParameters *ap,
+ PRUint32 keysize,
+ NSSToken *destination,
+ NSSCallback *uhhOpt);
/*
* NSSTrustDomain_GenerateSymmetricKeyFromPassword
@@ -2027,20 +1774,18 @@ NSSTrustDomain_GenerateSymmetricKey
*/
NSS_EXTERN NSSSymmetricKey *
-NSSTrustDomain_GenerateSymmetricKeyFromPassword
-(
- NSSTrustDomain *td,
- NSSAlgorithmAndParameters *ap,
- NSSUTF8 *passwordOpt, /* if null, prompt */
- NSSToken *destinationOpt,
- NSSCallback *uhhOpt
-);
+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
* (
@@ -2056,18 +1801,16 @@ NSSTrustDomain_GenerateSymmetricKeyFromPassword
*/
NSS_EXTERN NSSSymmetricKey *
-NSSTrustDomain_FindSymmetricKeyByAlgorithmAndKeyID
-(
- NSSTrustDomain *td,
- NSSOID *algorithm,
- NSSItem *keyID,
- NSSCallback *uhhOpt
-);
+NSSTrustDomain_FindSymmetricKeyByAlgorithmAndKeyID(
+ NSSTrustDomain *td,
+ NSSOID *algorithm,
+ NSSItem *keyID,
+ NSSCallback *uhhOpt);
/*
* NSSTrustDomain_TraverseSymmetricKeys
*
- *
+ *
* NSS_EXTERN PRStatus *
* NSSTrustDomain_TraverseSymmetricKeys
* (
@@ -2086,11 +1829,9 @@ NSSTrustDomain_FindSymmetricKeyByAlgorithmAndKeyID
*/
NSS_EXTERN NSSCryptoContext *
-NSSTrustDomain_CreateCryptoContext
-(
- NSSTrustDomain *td,
- NSSCallback *uhhOpt
-);
+NSSTrustDomain_CreateCryptoContext(
+ NSSTrustDomain *td,
+ NSSCallback *uhhOpt);
/*
* NSSTrustDomain_CreateCryptoContextForAlgorithm
@@ -2098,11 +1839,9 @@ NSSTrustDomain_CreateCryptoContext
*/
NSS_EXTERN NSSCryptoContext *
-NSSTrustDomain_CreateCryptoContextForAlgorithm
-(
- NSSTrustDomain *td,
- NSSOID *algorithm
-);
+NSSTrustDomain_CreateCryptoContextForAlgorithm(
+ NSSTrustDomain *td,
+ NSSOID *algorithm);
/*
* NSSTrustDomain_CreateCryptoContextForAlgorithmAndParameters
@@ -2110,11 +1849,9 @@ NSSTrustDomain_CreateCryptoContextForAlgorithm
*/
NSS_EXTERN NSSCryptoContext *
-NSSTrustDomain_CreateCryptoContextForAlgorithmAndParameters
-(
- NSSTrustDomain *td,
- NSSAlgorithmAndParameters *ap
-);
+NSSTrustDomain_CreateCryptoContextForAlgorithmAndParameters(
+ NSSTrustDomain *td,
+ NSSAlgorithmAndParameters *ap);
/* find/traverse other objects, e.g. s/mime profiles */
@@ -2124,15 +1861,15 @@ NSSTrustDomain_CreateCryptoContextForAlgorithmAndParameters
* 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.
*/
@@ -2143,10 +1880,7 @@ NSSTrustDomain_CreateCryptoContextForAlgorithmAndParameters
*/
NSS_EXTERN PRStatus
-NSSCryptoContext_Destroy
-(
- NSSCryptoContext *cc
-);
+NSSCryptoContext_Destroy(NSSCryptoContext *cc);
/* establishing a default callback */
@@ -2156,12 +1890,10 @@ NSSCryptoContext_Destroy
*/
NSS_EXTERN PRStatus
-NSSCryptoContext_SetDefaultCallback
-(
- NSSCryptoContext *cc,
- NSSCallback *newCallback,
- NSSCallback **oldCallbackOpt
-);
+NSSCryptoContext_SetDefaultCallback(
+ NSSCryptoContext *cc,
+ NSSCallback *newCallback,
+ NSSCallback **oldCallbackOpt);
/*
* NSSCryptoContext_GetDefaultCallback
@@ -2169,11 +1901,9 @@ NSSCryptoContext_SetDefaultCallback
*/
NSS_EXTERN NSSCallback *
-NSSCryptoContext_GetDefaultCallback
-(
- NSSCryptoContext *cc,
- PRStatus *statusOpt
-);
+NSSCryptoContext_GetDefaultCallback(
+ NSSCryptoContext *cc,
+ PRStatus *statusOpt);
/*
* NSSCryptoContext_GetTrustDomain
@@ -2181,10 +1911,8 @@ NSSCryptoContext_GetDefaultCallback
*/
NSS_EXTERN NSSTrustDomain *
-NSSCryptoContext_GetTrustDomain
-(
- NSSCryptoContext *cc
-);
+NSSCryptoContext_GetTrustDomain(
+ NSSCryptoContext *cc);
/* AddModule, etc: should we allow "temporary" changes here? */
/* DisableToken, etc: ditto */
@@ -2197,25 +1925,24 @@ NSSCryptoContext_GetTrustDomain
/*
* NSSCryptoContext_FindOrImportCertificate
*
- * If the certificate store already contains this DER cert, return the
+ * 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.
+ * 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,
+ * 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_FindOrImportCertificate(
+ NSSCryptoContext *cc,
+ NSSCertificate *c);
/*
* NSSCryptoContext_ImportPKIXCertificate
@@ -2223,11 +1950,9 @@ NSSCryptoContext_FindOrImportCertificate (
*/
NSS_EXTERN NSSCertificate *
-NSSCryptoContext_ImportPKIXCertificate
-(
- NSSCryptoContext *cc,
- struct NSSPKIXCertificateStr *pc
-);
+NSSCryptoContext_ImportPKIXCertificate(
+ NSSCryptoContext *cc,
+ struct NSSPKIXCertificateStr *pc);
/*
* NSSCryptoContext_ImportEncodedCertificate
@@ -2235,11 +1960,9 @@ NSSCryptoContext_ImportPKIXCertificate
*/
NSS_EXTERN NSSCertificate *
-NSSCryptoContext_ImportEncodedCertificate
-(
- NSSCryptoContext *cc,
- NSSBER *ber
-);
+NSSCryptoContext_ImportEncodedCertificate(
+ NSSCryptoContext *cc,
+ NSSBER *ber);
/*
* NSSCryptoContext_ImportEncodedPKIXCertificateChain
@@ -2247,11 +1970,9 @@ NSSCryptoContext_ImportEncodedCertificate
*/
NSS_EXTERN PRStatus
-NSSCryptoContext_ImportEncodedPKIXCertificateChain
-(
- NSSCryptoContext *cc,
- NSSBER *ber
-);
+NSSCryptoContext_ImportEncodedPKIXCertificateChain(
+ NSSCryptoContext *cc,
+ NSSBER *ber);
/* Other importations: S/MIME capabilities
*/
@@ -2262,14 +1983,13 @@ NSSCryptoContext_ImportEncodedPKIXCertificateChain
*/
NSS_EXTERN NSSCertificate *
-NSSCryptoContext_FindBestCertificateByNickname
-(
- NSSCryptoContext *cc,
- const NSSUTF8 *name,
- NSSTime *timeOpt, /* NULL for "now" */
- NSSUsage *usage,
- NSSPolicies *policiesOpt /* NULL for none */
-);
+NSSCryptoContext_FindBestCertificateByNickname(
+ NSSCryptoContext *cc,
+ const NSSUTF8 *name,
+ NSSTime *timeOpt, /* NULL for "now" */
+ NSSUsage *usage,
+ NSSPolicies *policiesOpt /* NULL for none */
+ );
/*
* NSSCryptoContext_FindCertificatesByNickname
@@ -2277,14 +1997,12 @@ NSSCryptoContext_FindBestCertificateByNickname
*/
NSS_EXTERN NSSCertificate **
-NSSCryptoContext_FindCertificatesByNickname
-(
- NSSCryptoContext *cc,
- NSSUTF8 *name,
- NSSCertificate *rvOpt[],
- PRUint32 maximumOpt, /* 0 for no max */
- NSSArena *arenaOpt
-);
+NSSCryptoContext_FindCertificatesByNickname(
+ NSSCryptoContext *cc,
+ NSSUTF8 *name,
+ NSSCertificate *rvOpt[],
+ PRUint32 maximumOpt, /* 0 for no max */
+ NSSArena *arenaOpt);
/*
* NSSCryptoContext_FindCertificateByIssuerAndSerialNumber
@@ -2292,12 +2010,10 @@ NSSCryptoContext_FindCertificatesByNickname
*/
NSS_EXTERN NSSCertificate *
-NSSCryptoContext_FindCertificateByIssuerAndSerialNumber
-(
- NSSCryptoContext *cc,
- NSSDER *issuer,
- NSSDER *serialNumber
-);
+NSSCryptoContext_FindCertificateByIssuerAndSerialNumber(
+ NSSCryptoContext *cc,
+ NSSDER *issuer,
+ NSSDER *serialNumber);
/*
* NSSCryptoContext_FindBestCertificateBySubject
@@ -2306,14 +2022,12 @@ NSSCryptoContext_FindCertificateByIssuerAndSerialNumber
*/
NSS_EXTERN NSSCertificate *
-NSSCryptoContext_FindBestCertificateBySubject
-(
- NSSCryptoContext *cc,
- NSSDER /*NSSUTF8*/ *subject,
- NSSTime *timeOpt,
- NSSUsage *usage,
- NSSPolicies *policiesOpt
-);
+NSSCryptoContext_FindBestCertificateBySubject(
+ NSSCryptoContext *cc,
+ NSSDER /*NSSUTF8*/ *subject,
+ NSSTime *timeOpt,
+ NSSUsage *usage,
+ NSSPolicies *policiesOpt);
/*
* NSSCryptoContext_FindCertificatesBySubject
@@ -2322,33 +2036,29 @@ NSSCryptoContext_FindBestCertificateBySubject
*/
NSS_EXTERN NSSCertificate **
-NSSCryptoContext_FindCertificatesBySubject
-(
- NSSCryptoContext *cc,
- NSSDER /*NSSUTF8*/ *subject,
- NSSCertificate *rvOpt[],
- PRUint32 maximumOpt, /* 0 for no max */
- NSSArena *arenaOpt
-);
+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
+ * 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_FindBestCertificateByNameComponents(
+ NSSCryptoContext *cc,
+ NSSUTF8 *nameComponents,
+ NSSTime *timeOpt,
+ NSSUsage *usage,
+ NSSPolicies *policiesOpt);
/*
* NSSCryptoContext_FindCertificatesByNameComponents
@@ -2359,14 +2069,12 @@ NSSCryptoContext_FindBestCertificateByNameComponents
*/
NSS_EXTERN NSSCertificate **
-NSSCryptoContext_FindCertificatesByNameComponents
-(
- NSSCryptoContext *cc,
- NSSUTF8 *nameComponents,
- NSSCertificate *rvOpt[],
- PRUint32 maximumOpt, /* 0 for no max */
- NSSArena *arenaOpt
-);
+NSSCryptoContext_FindCertificatesByNameComponents(
+ NSSCryptoContext *cc,
+ NSSUTF8 *nameComponents,
+ NSSCertificate *rvOpt[],
+ PRUint32 maximumOpt, /* 0 for no max */
+ NSSArena *arenaOpt);
/*
* NSSCryptoContext_FindCertificateByEncodedCertificate
@@ -2374,11 +2082,9 @@ NSSCryptoContext_FindCertificatesByNameComponents
*/
NSS_EXTERN NSSCertificate *
-NSSCryptoContext_FindCertificateByEncodedCertificate
-(
- NSSCryptoContext *cc,
- NSSBER *encodedCertificate
-);
+NSSCryptoContext_FindCertificateByEncodedCertificate(
+ NSSCryptoContext *cc,
+ NSSBER *encodedCertificate);
/*
* NSSCryptoContext_FindBestCertificateByEmail
@@ -2386,14 +2092,12 @@ NSSCryptoContext_FindCertificateByEncodedCertificate
*/
NSS_EXTERN NSSCertificate *
-NSSCryptoContext_FindBestCertificateByEmail
-(
- NSSCryptoContext *cc,
- NSSASCII7 *email,
- NSSTime *timeOpt,
- NSSUsage *usage,
- NSSPolicies *policiesOpt
-);
+NSSCryptoContext_FindBestCertificateByEmail(
+ NSSCryptoContext *cc,
+ NSSASCII7 *email,
+ NSSTime *timeOpt,
+ NSSUsage *usage,
+ NSSPolicies *policiesOpt);
/*
* NSSCryptoContext_FindCertificatesByEmail
@@ -2401,14 +2105,12 @@ NSSCryptoContext_FindBestCertificateByEmail
*/
NSS_EXTERN NSSCertificate **
-NSSCryptoContext_FindCertificatesByEmail
-(
- NSSCryptoContext *cc,
- NSSASCII7 *email,
- NSSCertificate *rvOpt[],
- PRUint32 maximumOpt, /* 0 for no max */
- NSSArena *arenaOpt
-);
+NSSCryptoContext_FindCertificatesByEmail(
+ NSSCryptoContext *cc,
+ NSSASCII7 *email,
+ NSSCertificate *rvOpt[],
+ PRUint32 maximumOpt, /* 0 for no max */
+ NSSArena *arenaOpt);
/*
* NSSCryptoContext_FindCertificateByOCSPHash
@@ -2416,16 +2118,14 @@ NSSCryptoContext_FindCertificatesByEmail
*/
NSS_EXTERN NSSCertificate *
-NSSCryptoContext_FindCertificateByOCSPHash
-(
- NSSCryptoContext *cc,
- NSSItem *hash
-);
+NSSCryptoContext_FindCertificateByOCSPHash(
+ NSSCryptoContext *cc,
+ NSSItem *hash);
/*
* NSSCryptoContext_TraverseCertificates
*
- *
+ *
* NSS_EXTERN PRStatus *
* NSSCryptoContext_TraverseCertificates
* (
@@ -2441,13 +2141,11 @@ NSSCryptoContext_FindCertificateByOCSPHash
*/
NSS_EXTERN NSSCertificate *
-NSSCryptoContext_FindBestUserCertificate
-(
- NSSCryptoContext *cc,
- NSSTime *timeOpt,
- NSSUsage *usage,
- NSSPolicies *policiesOpt
-);
+NSSCryptoContext_FindBestUserCertificate(
+ NSSCryptoContext *cc,
+ NSSTime *timeOpt,
+ NSSUsage *usage,
+ NSSPolicies *policiesOpt);
/*
* NSSCryptoContext_FindUserCertificates
@@ -2455,16 +2153,14 @@ NSSCryptoContext_FindBestUserCertificate
*/
NSS_EXTERN NSSCertificate **
-NSSCryptoContext_FindUserCertificates
-(
- NSSCryptoContext *cc,
- NSSTime *timeOpt,
- NSSUsage *usageOpt,
- NSSPolicies *policiesOpt,
- NSSCertificate **rvOpt,
- PRUint32 rvLimit, /* zero for no limit */
- NSSArena *arenaOpt
-);
+NSSCryptoContext_FindUserCertificates(
+ NSSCryptoContext *cc,
+ NSSTime *timeOpt,
+ NSSUsage *usageOpt,
+ NSSPolicies *policiesOpt,
+ NSSCertificate **rvOpt,
+ PRUint32 rvLimit, /* zero for no limit */
+ NSSArena *arenaOpt);
/*
* NSSCryptoContext_FindBestUserCertificateForSSLClientAuth
@@ -2472,15 +2168,13 @@ NSSCryptoContext_FindUserCertificates
*/
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_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
@@ -2488,18 +2182,16 @@ NSSCryptoContext_FindBestUserCertificateForSSLClientAuth
*/
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_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
@@ -2507,15 +2199,13 @@ NSSCryptoContext_FindUserCertificatesForSSLClientAuth
*/
NSS_EXTERN NSSCertificate *
-NSSCryptoContext_FindBestUserCertificateForEmailSigning
-(
- NSSCryptoContext *cc,
- NSSASCII7 *signerOpt,
- NSSASCII7 *recipientOpt,
- /* anything more here? */
- NSSAlgorithmAndParameters *apOpt,
- NSSPolicies *policiesOpt
-);
+NSSCryptoContext_FindBestUserCertificateForEmailSigning(
+ NSSCryptoContext *cc,
+ NSSASCII7 *signerOpt,
+ NSSASCII7 *recipientOpt,
+ /* anything more here? */
+ NSSAlgorithmAndParameters *apOpt,
+ NSSPolicies *policiesOpt);
/*
* NSSCryptoContext_FindUserCertificatesForEmailSigning
@@ -2523,18 +2213,16 @@ NSSCryptoContext_FindBestUserCertificateForEmailSigning
*/
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
-);
+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 */
@@ -2549,21 +2237,19 @@ NSSCryptoContext_FindUserCertificatesForEmailSigning
*/
NSS_EXTERN PRStatus
-NSSCryptoContext_GenerateKeyPair
-(
- NSSCryptoContext *cc,
- NSSAlgorithmAndParameters *ap,
- NSSPrivateKey **pvkOpt,
- NSSPublicKey **pbkOpt,
- PRBool privateKeyIsSensitive,
- NSSToken *destination,
- NSSCallback *uhhOpt
-);
+NSSCryptoContext_GenerateKeyPair(
+ NSSCryptoContext *cc,
+ NSSAlgorithmAndParameters *ap,
+ NSSPrivateKey **pvkOpt,
+ NSSPublicKey **pbkOpt,
+ PRBool privateKeyIsSensitive,
+ NSSToken *destination,
+ NSSCallback *uhhOpt);
/*
* NSSCryptoContext_TraversePrivateKeys
*
- *
+ *
* NSS_EXTERN PRStatus *
* NSSCryptoContext_TraversePrivateKeys
* (
@@ -2581,14 +2267,12 @@ NSSCryptoContext_GenerateKeyPair
*/
NSS_EXTERN NSSSymmetricKey *
-NSSCryptoContext_GenerateSymmetricKey
-(
- NSSCryptoContext *cc,
- NSSAlgorithmAndParameters *ap,
- PRUint32 keysize,
- NSSToken *destination,
- NSSCallback *uhhOpt
-);
+NSSCryptoContext_GenerateSymmetricKey(
+ NSSCryptoContext *cc,
+ NSSAlgorithmAndParameters *ap,
+ PRUint32 keysize,
+ NSSToken *destination,
+ NSSCallback *uhhOpt);
/*
* NSSCryptoContext_GenerateSymmetricKeyFromPassword
@@ -2596,19 +2280,17 @@ NSSCryptoContext_GenerateSymmetricKey
*/
NSS_EXTERN NSSSymmetricKey *
-NSSCryptoContext_GenerateSymmetricKeyFromPassword
-(
- NSSCryptoContext *cc,
- NSSAlgorithmAndParameters *ap,
- NSSUTF8 *passwordOpt, /* if null, prompt */
- NSSToken *destinationOpt,
- NSSCallback *uhhOpt
-);
+NSSCryptoContext_GenerateSymmetricKeyFromPassword(
+ NSSCryptoContext *cc,
+ NSSAlgorithmAndParameters *ap,
+ NSSUTF8 *passwordOpt, /* if null, prompt */
+ NSSToken *destinationOpt,
+ NSSCallback *uhhOpt);
/*
* NSSCryptoContext_FindSymmetricKeyByAlgorithm
*
- *
+ *
* NSS_EXTERN NSSSymmetricKey *
* NSSCryptoContext_FindSymmetricKeyByType
* (
@@ -2624,18 +2306,16 @@ NSSCryptoContext_GenerateSymmetricKeyFromPassword
*/
NSS_EXTERN NSSSymmetricKey *
-NSSCryptoContext_FindSymmetricKeyByAlgorithmAndKeyID
-(
- NSSCryptoContext *cc,
- NSSOID *algorithm,
- NSSItem *keyID,
- NSSCallback *uhhOpt
-);
+NSSCryptoContext_FindSymmetricKeyByAlgorithmAndKeyID(
+ NSSCryptoContext *cc,
+ NSSOID *algorithm,
+ NSSItem *keyID,
+ NSSCallback *uhhOpt);
/*
* NSSCryptoContext_TraverseSymmetricKeys
*
- *
+ *
* NSS_EXTERN PRStatus *
* NSSCryptoContext_TraverseSymmetricKeys
* (
@@ -2653,15 +2333,13 @@ NSSCryptoContext_FindSymmetricKeyByAlgorithmAndKeyID
*/
NSS_EXTERN NSSItem *
-NSSCryptoContext_Decrypt
-(
- NSSCryptoContext *cc,
- NSSAlgorithmAndParameters *apOpt,
- NSSItem *encryptedData,
- NSSCallback *uhhOpt,
- NSSItem *rvOpt,
- NSSArena *arenaOpt
-);
+NSSCryptoContext_Decrypt(
+ NSSCryptoContext *cc,
+ NSSAlgorithmAndParameters *apOpt,
+ NSSItem *encryptedData,
+ NSSCallback *uhhOpt,
+ NSSItem *rvOpt,
+ NSSArena *arenaOpt);
/*
* NSSCryptoContext_BeginDecrypt
@@ -2669,12 +2347,10 @@ NSSCryptoContext_Decrypt
*/
NSS_EXTERN PRStatus
-NSSCryptoContext_BeginDecrypt
-(
- NSSCryptoContext *cc,
- NSSAlgorithmAndParameters *apOpt,
- NSSCallback *uhhOpt
-);
+NSSCryptoContext_BeginDecrypt(
+ NSSCryptoContext *cc,
+ NSSAlgorithmAndParameters *apOpt,
+ NSSCallback *uhhOpt);
/*
* NSSCryptoContext_ContinueDecrypt
@@ -2703,13 +2379,11 @@ NSSCryptoContext_BeginDecrypt
*/
NSS_EXTERN NSSItem *
-NSSCryptoContext_ContinueDecrypt
-(
- NSSCryptoContext *cc,
- NSSItem *data,
- NSSItem *rvOpt,
- NSSArena *arenaOpt
-);
+NSSCryptoContext_ContinueDecrypt(
+ NSSCryptoContext *cc,
+ NSSItem *data,
+ NSSItem *rvOpt,
+ NSSArena *arenaOpt);
/*
* NSSCryptoContext_FinishDecrypt
@@ -2717,12 +2391,10 @@ NSSCryptoContext_ContinueDecrypt
*/
NSS_EXTERN NSSItem *
-NSSCryptoContext_FinishDecrypt
-(
- NSSCryptoContext *cc,
- NSSItem *rvOpt,
- NSSArena *arenaOpt
-);
+NSSCryptoContext_FinishDecrypt(
+ NSSCryptoContext *cc,
+ NSSItem *rvOpt,
+ NSSArena *arenaOpt);
/*
* NSSCryptoContext_Sign
@@ -2730,15 +2402,13 @@ NSSCryptoContext_FinishDecrypt
*/
NSS_EXTERN NSSItem *
-NSSCryptoContext_Sign
-(
- NSSCryptoContext *cc,
- NSSAlgorithmAndParameters *apOpt,
- NSSItem *data,
- NSSCallback *uhhOpt,
- NSSItem *rvOpt,
- NSSArena *arenaOpt
-);
+NSSCryptoContext_Sign(
+ NSSCryptoContext *cc,
+ NSSAlgorithmAndParameters *apOpt,
+ NSSItem *data,
+ NSSCallback *uhhOpt,
+ NSSItem *rvOpt,
+ NSSArena *arenaOpt);
/*
* NSSCryptoContext_BeginSign
@@ -2746,12 +2416,10 @@ NSSCryptoContext_Sign
*/
NSS_EXTERN PRStatus
-NSSCryptoContext_BeginSign
-(
- NSSCryptoContext *cc,
- NSSAlgorithmAndParameters *apOpt,
- NSSCallback *uhhOpt
-);
+NSSCryptoContext_BeginSign(
+ NSSCryptoContext *cc,
+ NSSAlgorithmAndParameters *apOpt,
+ NSSCallback *uhhOpt);
/*
* NSSCryptoContext_ContinueSign
@@ -2759,11 +2427,9 @@ NSSCryptoContext_BeginSign
*/
NSS_EXTERN PRStatus
-NSSCryptoContext_ContinueSign
-(
- NSSCryptoContext *cc,
- NSSItem *data
-);
+NSSCryptoContext_ContinueSign(
+ NSSCryptoContext *cc,
+ NSSItem *data);
/*
* NSSCryptoContext_FinishSign
@@ -2771,12 +2437,10 @@ NSSCryptoContext_ContinueSign
*/
NSS_EXTERN NSSItem *
-NSSCryptoContext_FinishSign
-(
- NSSCryptoContext *cc,
- NSSItem *rvOpt,
- NSSArena *arenaOpt
-);
+NSSCryptoContext_FinishSign(
+ NSSCryptoContext *cc,
+ NSSItem *rvOpt,
+ NSSArena *arenaOpt);
/*
* NSSCryptoContext_SignRecover
@@ -2784,15 +2448,13 @@ NSSCryptoContext_FinishSign
*/
NSS_EXTERN NSSItem *
-NSSCryptoContext_SignRecover
-(
- NSSCryptoContext *cc,
- NSSAlgorithmAndParameters *apOpt,
- NSSItem *data,
- NSSCallback *uhhOpt,
- NSSItem *rvOpt,
- NSSArena *arenaOpt
-);
+NSSCryptoContext_SignRecover(
+ NSSCryptoContext *cc,
+ NSSAlgorithmAndParameters *apOpt,
+ NSSItem *data,
+ NSSCallback *uhhOpt,
+ NSSItem *rvOpt,
+ NSSArena *arenaOpt);
/*
* NSSCryptoContext_BeginSignRecover
@@ -2800,12 +2462,10 @@ NSSCryptoContext_SignRecover
*/
NSS_EXTERN PRStatus
-NSSCryptoContext_BeginSignRecover
-(
- NSSCryptoContext *cc,
- NSSAlgorithmAndParameters *apOpt,
- NSSCallback *uhhOpt
-);
+NSSCryptoContext_BeginSignRecover(
+ NSSCryptoContext *cc,
+ NSSAlgorithmAndParameters *apOpt,
+ NSSCallback *uhhOpt);
/*
* NSSCryptoContext_ContinueSignRecover
@@ -2813,13 +2473,11 @@ NSSCryptoContext_BeginSignRecover
*/
NSS_EXTERN NSSItem *
-NSSCryptoContext_ContinueSignRecover
-(
- NSSCryptoContext *cc,
- NSSItem *data,
- NSSItem *rvOpt,
- NSSArena *arenaOpt
-);
+NSSCryptoContext_ContinueSignRecover(
+ NSSCryptoContext *cc,
+ NSSItem *data,
+ NSSItem *rvOpt,
+ NSSArena *arenaOpt);
/*
* NSSCryptoContext_FinishSignRecover
@@ -2827,12 +2485,10 @@ NSSCryptoContext_ContinueSignRecover
*/
NSS_EXTERN NSSItem *
-NSSCryptoContext_FinishSignRecover
-(
- NSSCryptoContext *cc,
- NSSItem *rvOpt,
- NSSArena *arenaOpt
-);
+NSSCryptoContext_FinishSignRecover(
+ NSSCryptoContext *cc,
+ NSSItem *rvOpt,
+ NSSArena *arenaOpt);
/*
* NSSCryptoContext_UnwrapSymmetricKey
@@ -2840,13 +2496,11 @@ NSSCryptoContext_FinishSignRecover
*/
NSS_EXTERN NSSSymmetricKey *
-NSSCryptoContext_UnwrapSymmetricKey
-(
- NSSCryptoContext *cc,
- NSSAlgorithmAndParameters *apOpt,
- NSSItem *wrappedKey,
- NSSCallback *uhhOpt
-);
+NSSCryptoContext_UnwrapSymmetricKey(
+ NSSCryptoContext *cc,
+ NSSAlgorithmAndParameters *apOpt,
+ NSSItem *wrappedKey,
+ NSSCallback *uhhOpt);
/*
* NSSCryptoContext_DeriveSymmetricKey
@@ -2854,16 +2508,14 @@ NSSCryptoContext_UnwrapSymmetricKey
*/
NSS_EXTERN NSSSymmetricKey *
-NSSCryptoContext_DeriveSymmetricKey
-(
- NSSCryptoContext *cc,
- NSSPublicKey *bk,
- NSSAlgorithmAndParameters *apOpt,
- NSSOID *target,
- PRUint32 keySizeOpt, /* zero for best allowed */
- NSSOperations operations,
- NSSCallback *uhhOpt
-);
+NSSCryptoContext_DeriveSymmetricKey(
+ NSSCryptoContext *cc,
+ NSSPublicKey *bk,
+ NSSAlgorithmAndParameters *apOpt,
+ NSSOID *target,
+ PRUint32 keySizeOpt, /* zero for best allowed */
+ NSSOperations operations,
+ NSSCallback *uhhOpt);
/*
* NSSCryptoContext_Encrypt
@@ -2873,15 +2525,13 @@ NSSCryptoContext_DeriveSymmetricKey
*/
NSS_EXTERN NSSItem *
-NSSCryptoContext_Encrypt
-(
- NSSCryptoContext *cc,
- NSSAlgorithmAndParameters *apOpt,
- NSSItem *data,
- NSSCallback *uhhOpt,
- NSSItem *rvOpt,
- NSSArena *arenaOpt
-);
+NSSCryptoContext_Encrypt(
+ NSSCryptoContext *cc,
+ NSSAlgorithmAndParameters *apOpt,
+ NSSItem *data,
+ NSSCallback *uhhOpt,
+ NSSItem *rvOpt,
+ NSSArena *arenaOpt);
/*
* NSSCryptoContext_BeginEncrypt
@@ -2889,12 +2539,10 @@ NSSCryptoContext_Encrypt
*/
NSS_EXTERN PRStatus
-NSSCryptoContext_BeginEncrypt
-(
- NSSCryptoContext *cc,
- NSSAlgorithmAndParameters *apOpt,
- NSSCallback *uhhOpt
-);
+NSSCryptoContext_BeginEncrypt(
+ NSSCryptoContext *cc,
+ NSSAlgorithmAndParameters *apOpt,
+ NSSCallback *uhhOpt);
/*
* NSSCryptoContext_ContinueEncrypt
@@ -2902,13 +2550,11 @@ NSSCryptoContext_BeginEncrypt
*/
NSS_EXTERN NSSItem *
-NSSCryptoContext_ContinueEncrypt
-(
- NSSCryptoContext *cc,
- NSSItem *data,
- NSSItem *rvOpt,
- NSSArena *arenaOpt
-);
+NSSCryptoContext_ContinueEncrypt(
+ NSSCryptoContext *cc,
+ NSSItem *data,
+ NSSItem *rvOpt,
+ NSSArena *arenaOpt);
/*
* NSSCryptoContext_FinishEncrypt
@@ -2916,12 +2562,10 @@ NSSCryptoContext_ContinueEncrypt
*/
NSS_EXTERN NSSItem *
-NSSCryptoContext_FinishEncrypt
-(
- NSSCryptoContext *cc,
- NSSItem *rvOpt,
- NSSArena *arenaOpt
-);
+NSSCryptoContext_FinishEncrypt(
+ NSSCryptoContext *cc,
+ NSSItem *rvOpt,
+ NSSArena *arenaOpt);
/*
* NSSCryptoContext_Verify
@@ -2929,14 +2573,12 @@ NSSCryptoContext_FinishEncrypt
*/
NSS_EXTERN PRStatus
-NSSCryptoContext_Verify
-(
- NSSCryptoContext *cc,
- NSSAlgorithmAndParameters *apOpt,
- NSSItem *data,
- NSSItem *signature,
- NSSCallback *uhhOpt
-);
+NSSCryptoContext_Verify(
+ NSSCryptoContext *cc,
+ NSSAlgorithmAndParameters *apOpt,
+ NSSItem *data,
+ NSSItem *signature,
+ NSSCallback *uhhOpt);
/*
* NSSCryptoContext_BeginVerify
@@ -2944,13 +2586,11 @@ NSSCryptoContext_Verify
*/
NSS_EXTERN PRStatus
-NSSCryptoContext_BeginVerify
-(
- NSSCryptoContext *cc,
- NSSAlgorithmAndParameters *apOpt,
- NSSItem *signature,
- NSSCallback *uhhOpt
-);
+NSSCryptoContext_BeginVerify(
+ NSSCryptoContext *cc,
+ NSSAlgorithmAndParameters *apOpt,
+ NSSItem *signature,
+ NSSCallback *uhhOpt);
/*
* NSSCryptoContext_ContinueVerify
@@ -2958,11 +2598,9 @@ NSSCryptoContext_BeginVerify
*/
NSS_EXTERN PRStatus
-NSSCryptoContext_ContinueVerify
-(
- NSSCryptoContext *cc,
- NSSItem *data
-);
+NSSCryptoContext_ContinueVerify(
+ NSSCryptoContext *cc,
+ NSSItem *data);
/*
* NSSCryptoContext_FinishVerify
@@ -2970,10 +2608,8 @@ NSSCryptoContext_ContinueVerify
*/
NSS_EXTERN PRStatus
-NSSCryptoContext_FinishVerify
-(
- NSSCryptoContext *cc
-);
+NSSCryptoContext_FinishVerify(
+ NSSCryptoContext *cc);
/*
* NSSCryptoContext_VerifyRecover
@@ -2981,15 +2617,13 @@ NSSCryptoContext_FinishVerify
*/
NSS_EXTERN NSSItem *
-NSSCryptoContext_VerifyRecover
-(
- NSSCryptoContext *cc,
- NSSAlgorithmAndParameters *apOpt,
- NSSItem *signature,
- NSSCallback *uhhOpt,
- NSSItem *rvOpt,
- NSSArena *arenaOpt
-);
+NSSCryptoContext_VerifyRecover(
+ NSSCryptoContext *cc,
+ NSSAlgorithmAndParameters *apOpt,
+ NSSItem *signature,
+ NSSCallback *uhhOpt,
+ NSSItem *rvOpt,
+ NSSArena *arenaOpt);
/*
* NSSCryptoContext_BeginVerifyRecover
@@ -2997,12 +2631,10 @@ NSSCryptoContext_VerifyRecover
*/
NSS_EXTERN PRStatus
-NSSCryptoContext_BeginVerifyRecover
-(
- NSSCryptoContext *cc,
- NSSAlgorithmAndParameters *apOpt,
- NSSCallback *uhhOpt
-);
+NSSCryptoContext_BeginVerifyRecover(
+ NSSCryptoContext *cc,
+ NSSAlgorithmAndParameters *apOpt,
+ NSSCallback *uhhOpt);
/*
* NSSCryptoContext_ContinueVerifyRecover
@@ -3010,13 +2642,11 @@ NSSCryptoContext_BeginVerifyRecover
*/
NSS_EXTERN NSSItem *
-NSSCryptoContext_ContinueVerifyRecover
-(
- NSSCryptoContext *cc,
- NSSItem *data,
- NSSItem *rvOpt,
- NSSArena *arenaOpt
-);
+NSSCryptoContext_ContinueVerifyRecover(
+ NSSCryptoContext *cc,
+ NSSItem *data,
+ NSSItem *rvOpt,
+ NSSArena *arenaOpt);
/*
* NSSCryptoContext_FinishVerifyRecover
@@ -3024,12 +2654,10 @@ NSSCryptoContext_ContinueVerifyRecover
*/
NSS_EXTERN NSSItem *
-NSSCryptoContext_FinishVerifyRecover
-(
- NSSCryptoContext *cc,
- NSSItem *rvOpt,
- NSSArena *arenaOpt
-);
+NSSCryptoContext_FinishVerifyRecover(
+ NSSCryptoContext *cc,
+ NSSItem *rvOpt,
+ NSSArena *arenaOpt);
/*
* NSSCryptoContext_WrapSymmetricKey
@@ -3037,15 +2665,13 @@ NSSCryptoContext_FinishVerifyRecover
*/
NSS_EXTERN NSSItem *
-NSSCryptoContext_WrapSymmetricKey
-(
- NSSCryptoContext *cc,
- NSSAlgorithmAndParameters *apOpt,
- NSSSymmetricKey *keyToWrap,
- NSSCallback *uhhOpt,
- NSSItem *rvOpt,
- NSSArena *arenaOpt
-);
+NSSCryptoContext_WrapSymmetricKey(
+ NSSCryptoContext *cc,
+ NSSAlgorithmAndParameters *apOpt,
+ NSSSymmetricKey *keyToWrap,
+ NSSCallback *uhhOpt,
+ NSSItem *rvOpt,
+ NSSArena *arenaOpt);
/*
* NSSCryptoContext_Digest
@@ -3055,15 +2681,13 @@ NSSCryptoContext_WrapSymmetricKey
*/
NSS_EXTERN NSSItem *
-NSSCryptoContext_Digest
-(
- NSSCryptoContext *cc,
- NSSAlgorithmAndParameters *apOpt,
- NSSItem *data,
- NSSCallback *uhhOpt,
- NSSItem *rvOpt,
- NSSArena *arenaOpt
-);
+NSSCryptoContext_Digest(
+ NSSCryptoContext *cc,
+ NSSAlgorithmAndParameters *apOpt,
+ NSSItem *data,
+ NSSCallback *uhhOpt,
+ NSSItem *rvOpt,
+ NSSArena *arenaOpt);
/*
* NSSCryptoContext_BeginDigest
@@ -3071,12 +2695,10 @@ NSSCryptoContext_Digest
*/
NSS_EXTERN PRStatus
-NSSCryptoContext_BeginDigest
-(
- NSSCryptoContext *cc,
- NSSAlgorithmAndParameters *apOpt,
- NSSCallback *uhhOpt
-);
+NSSCryptoContext_BeginDigest(
+ NSSCryptoContext *cc,
+ NSSAlgorithmAndParameters *apOpt,
+ NSSCallback *uhhOpt);
/*
* NSSCryptoContext_ContinueDigest
@@ -3084,12 +2706,10 @@ NSSCryptoContext_BeginDigest
*/
NSS_EXTERN PRStatus
-NSSCryptoContext_ContinueDigest
-(
- NSSCryptoContext *cc,
- NSSAlgorithmAndParameters *apOpt,
- NSSItem *item
-);
+NSSCryptoContext_ContinueDigest(
+ NSSCryptoContext *cc,
+ NSSAlgorithmAndParameters *apOpt,
+ NSSItem *item);
/*
* NSSCryptoContext_FinishDigest
@@ -3097,12 +2717,10 @@ NSSCryptoContext_ContinueDigest
*/
NSS_EXTERN NSSItem *
-NSSCryptoContext_FinishDigest
-(
- NSSCryptoContext *cc,
- NSSItem *rvOpt,
- NSSArena *arenaOpt
-);
+NSSCryptoContext_FinishDigest(
+ NSSCryptoContext *cc,
+ NSSItem *rvOpt,
+ NSSArena *arenaOpt);
/*
* tbd: Combination ops
@@ -3114,10 +2732,7 @@ NSSCryptoContext_FinishDigest
*/
NSS_EXTERN NSSCryptoContext *
-NSSCryptoContext_Clone
-(
- NSSCryptoContext *cc
-);
+NSSCryptoContext_Clone(NSSCryptoContext *cc);
/*
* NSSCryptoContext_Save
diff --git a/nss/lib/pki/nsspkit.h b/nss/lib/pki/nsspkit.h
index 726b0df..1d6bc71 100644
--- a/nss/lib/pki/nsspkit.h
+++ b/nss/lib/pki/nsspkit.h
@@ -27,7 +27,7 @@ PR_BEGIN_EXTERN_C
* 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,
+ * 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.
*/
@@ -45,7 +45,7 @@ typedef struct NSSCertificateStr NSSCertificate;
* 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
+ * 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.
@@ -87,7 +87,7 @@ typedef struct NSSSymmetricKeyStr NSSSymmetricKey;
*
* 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
+ * 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.
*
@@ -123,7 +123,7 @@ typedef struct NSSTrustDomainStr NSSTrustDomain;
* 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
+ * old code, but it has changed a lot as a result of what we've
* learned.
*/
@@ -139,10 +139,10 @@ typedef struct NSSCryptoContextStr NSSCryptoContext;
* This is the basic OID that crops up everywhere.
*/
-struct NSSOIDStr; /* unused opaque structure */
+struct NSSOIDStr; /* unused opaque structure */
typedef struct NSSOIDStr NSSOID;
-/*
+/*
* NSSTime
*
* Unfortunately, we need an "exceptional" value to indicate
@@ -212,16 +212,16 @@ 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 (*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);
+ 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);
+ PRStatus (*getPW)(NSSUTF8 *slotName, PRUint32 *retries, void *arg,
+ NSSUTF8 **password);
void *arg;
};
@@ -231,14 +231,14 @@ 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
+#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;
diff --git a/nss/lib/pki/pki.gyp b/nss/lib/pki/pki.gyp
new file mode 100644
index 0000000..c3475df
--- /dev/null
+++ b/nss/lib/pki/pki.gyp
@@ -0,0 +1,32 @@
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+{
+ 'includes': [
+ '../../coreconf/config.gypi'
+ ],
+ 'targets': [
+ {
+ 'target_name': 'nsspki',
+ 'type': 'static_library',
+ 'sources': [
+ 'asymmkey.c',
+ 'certdecode.c',
+ 'certificate.c',
+ 'cryptocontext.c',
+ 'pki3hack.c',
+ 'pkibase.c',
+ 'pkistore.c',
+ 'symmkey.c',
+ 'tdcache.c',
+ 'trustdomain.c'
+ ],
+ 'dependencies': [
+ '<(DEPTH)/exports.gyp:nss_exports'
+ ]
+ }
+ ],
+ 'variables': {
+ 'module': 'nss'
+ }
+} \ No newline at end of file
diff --git a/nss/lib/pki/pki.h b/nss/lib/pki/pki.h
index 959a2fd..00cebe7 100644
--- a/nss/lib/pki/pki.h
+++ b/nss/lib/pki/pki.h
@@ -20,193 +20,121 @@
PR_BEGIN_EXTERN_C
NSS_EXTERN NSSCallback *
-nssTrustDomain_GetDefaultCallback
-(
- NSSTrustDomain *td,
- PRStatus *statusOpt
-);
+nssTrustDomain_GetDefaultCallback(
+ NSSTrustDomain *td,
+ PRStatus *statusOpt);
NSS_EXTERN NSSCertificate **
-nssTrustDomain_FindCertificatesBySubject
-(
- NSSTrustDomain *td,
- NSSDER *subject,
- NSSCertificate *rvOpt[],
- PRUint32 maximumOpt,
- NSSArena *arenaOpt
-);
+nssTrustDomain_FindCertificatesBySubject(
+ NSSTrustDomain *td,
+ NSSDER *subject,
+ NSSCertificate *rvOpt[],
+ PRUint32 maximumOpt,
+ NSSArena *arenaOpt);
NSS_EXTERN NSSTrust *
-nssTrustDomain_FindTrustForCertificate
-(
- NSSTrustDomain *td,
- NSSCertificate *c
-);
+nssTrustDomain_FindTrustForCertificate(
+ NSSTrustDomain *td,
+ NSSCertificate *c);
NSS_EXTERN NSSCertificate *
-nssCertificate_AddRef
-(
- NSSCertificate *c
-);
+nssCertificate_AddRef(NSSCertificate *c);
NSS_EXTERN PRStatus
-nssCertificate_Destroy
-(
- NSSCertificate *c
-);
+nssCertificate_Destroy(NSSCertificate *c);
NSS_EXTERN NSSDER *
-nssCertificate_GetEncoding
-(
- NSSCertificate *c
-);
+nssCertificate_GetEncoding(NSSCertificate *c);
NSS_EXTERN NSSDER *
-nssCertificate_GetIssuer
-(
- NSSCertificate *c
-);
+nssCertificate_GetIssuer(NSSCertificate *c);
NSS_EXTERN NSSDER *
-nssCertificate_GetSerialNumber
-(
- NSSCertificate *c
-);
+nssCertificate_GetSerialNumber(NSSCertificate *c);
NSS_EXTERN NSSDER *
-nssCertificate_GetSubject
-(
- NSSCertificate *c
-);
+nssCertificate_GetSubject(NSSCertificate *c);
/* Returns a copy, Caller must free using nss_ZFreeIf */
NSS_EXTERN NSSUTF8 *
-nssCertificate_GetNickname
-(
- NSSCertificate *c,
- NSSToken *tokenOpt
-);
+nssCertificate_GetNickname(
+ NSSCertificate *c,
+ NSSToken *tokenOpt);
NSS_EXTERN NSSASCII7 *
-nssCertificate_GetEmailAddress
-(
- NSSCertificate *c
-);
+nssCertificate_GetEmailAddress(NSSCertificate *c);
NSS_EXTERN PRBool
-nssCertificate_IssuerAndSerialEqual
-(
- NSSCertificate *c1,
- NSSCertificate *c2
-);
+nssCertificate_IssuerAndSerialEqual(
+ NSSCertificate *c1,
+ NSSCertificate *c2);
NSS_EXTERN NSSPrivateKey *
-nssPrivateKey_AddRef
-(
- NSSPrivateKey *vk
-);
+nssPrivateKey_AddRef(NSSPrivateKey *vk);
NSS_EXTERN PRStatus
-nssPrivateKey_Destroy
-(
- NSSPrivateKey *vk
-);
+nssPrivateKey_Destroy(NSSPrivateKey *vk);
NSS_EXTERN NSSItem *
-nssPrivateKey_GetID
-(
- NSSPrivateKey *vk
-);
+nssPrivateKey_GetID(NSSPrivateKey *vk);
NSS_EXTERN NSSUTF8 *
-nssPrivateKey_GetNickname
-(
- NSSPrivateKey *vk,
- NSSToken *tokenOpt
-);
+nssPrivateKey_GetNickname(
+ NSSPrivateKey *vk,
+ NSSToken *tokenOpt);
NSS_EXTERN PRStatus
-nssPublicKey_Destroy
-(
- NSSPublicKey *bk
-);
+nssPublicKey_Destroy(NSSPublicKey *bk);
NSS_EXTERN NSSItem *
-nssPublicKey_GetID
-(
- NSSPublicKey *vk
-);
+nssPublicKey_GetID(NSSPublicKey *vk);
NSS_EXTERN NSSCertificate **
-nssCryptoContext_FindCertificatesBySubject
-(
- NSSCryptoContext *cc,
- NSSDER *subject,
- NSSCertificate *rvOpt[],
- PRUint32 maximumOpt, /* 0 for no max */
- NSSArena *arenaOpt
-);
+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
-);
+nssCryptoContext_ImportTrust(
+ NSSCryptoContext *cc,
+ NSSTrust *trust);
NSS_EXTERN NSSTrust *
-nssCryptoContext_FindTrustForCertificate
-(
- NSSCryptoContext *cc,
- NSSCertificate *cert
-);
+nssCryptoContext_FindTrustForCertificate(
+ NSSCryptoContext *cc,
+ NSSCertificate *cert);
NSS_EXTERN PRStatus
-nssCryptoContext_ImportSMIMEProfile
-(
- NSSCryptoContext *cc,
- nssSMIMEProfile *profile
-);
+nssCryptoContext_ImportSMIMEProfile(
+ NSSCryptoContext *cc,
+ nssSMIMEProfile *profile);
NSS_EXTERN nssSMIMEProfile *
-nssCryptoContext_FindSMIMEProfileForCertificate
-(
- NSSCryptoContext *cc,
- NSSCertificate *cert
-);
+nssCryptoContext_FindSMIMEProfileForCertificate(
+ NSSCryptoContext *cc,
+ NSSCertificate *cert);
NSS_EXTERN NSSTrust *
-nssTrust_AddRef
-(
- NSSTrust *trust
-);
+nssTrust_AddRef(NSSTrust *trust);
NSS_EXTERN PRStatus
-nssTrust_Destroy
-(
- NSSTrust *trust
-);
+nssTrust_Destroy(NSSTrust *trust);
NSS_EXTERN nssSMIMEProfile *
-nssSMIMEProfile_AddRef
-(
- nssSMIMEProfile *profile
-);
+nssSMIMEProfile_AddRef(nssSMIMEProfile *profile);
NSS_EXTERN PRStatus
-nssSMIMEProfile_Destroy
-(
- nssSMIMEProfile *profile
-);
+nssSMIMEProfile_Destroy(nssSMIMEProfile *profile);
NSS_EXTERN nssSMIMEProfile *
-nssSMIMEProfile_Create
-(
- NSSCertificate *cert,
- NSSItem *profileTime,
- NSSItem *profileData
-);
+nssSMIMEProfile_Create(
+ NSSCertificate *cert,
+ NSSItem *profileTime,
+ NSSItem *profileData);
PR_END_EXTERN_C
diff --git a/nss/lib/pki/pki3hack.c b/nss/lib/pki/pki3hack.c
index b145092..0826b7f 100644
--- a/nss/lib/pki/pki3hack.c
+++ b/nss/lib/pki/pki3hack.c
@@ -64,20 +64,20 @@ 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;
- }
+ 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);
+ NSSRWLock_LockWrite(td->tokensLock);
+ nssList_Add(td->tokenList, token);
+ NSSRWLock_UnlockWrite(td->tokensLock);
}
return PR_SUCCESS;
}
@@ -86,12 +86,12 @@ 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;
- }
+ 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);
@@ -101,9 +101,8 @@ STAN_ResetTokenInterator(NSSTrustDomain *td)
}
NSS_IMPLEMENT PRStatus
-STAN_LoadDefaultNSS3TrustDomain (
- void
-)
+STAN_LoadDefaultNSS3TrustDomain(
+ void)
{
NSSTrustDomain *td;
SECMODModuleList *mlp;
@@ -111,13 +110,13 @@ STAN_LoadDefaultNSS3TrustDomain (
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;
+ /* 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;
+ return PR_FAILURE;
}
/*
* Deadlock warning: we should never acquire the moduleLock while
@@ -126,29 +125,29 @@ STAN_LoadDefaultNSS3TrustDomain (
*/
td->tokenList = nssList_Create(td->arena, PR_TRUE);
if (!td->tokenList) {
- goto loser;
+ 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]);
- }
+ 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;
+ goto loser;
}
g_default_crypto_context = NSSTrustDomain_CreateCryptoContext(td, NULL);
if (!g_default_crypto_context) {
- goto loser;
+ goto loser;
}
g_default_trust_domain = td;
return PR_SUCCESS;
- loser:
+loser:
NSSTrustDomain_Destroy(td);
return PR_FAILURE;
}
@@ -157,15 +156,14 @@ STAN_LoadDefaultNSS3TrustDomain (
* must be called holding the ModuleListLock (either read or write).
*/
NSS_IMPLEMENT SECStatus
-STAN_AddModuleToDefaultTrustDomain (
- SECMODModule *module
-)
+STAN_AddModuleToDefaultTrustDomain(
+ SECMODModule *module)
{
NSSTrustDomain *td;
int i;
td = STAN_GetDefaultTrustDomain();
- for (i=0; i<module->slotCount; i++) {
- STAN_InitTokenForSlotInfo(td, module->slots[i]);
+ for (i = 0; i < module->slotCount; i++) {
+ STAN_InitTokenForSlotInfo(td, module->slots[i]);
}
STAN_ResetTokenInterator(td);
return SECSuccess;
@@ -175,23 +173,22 @@ STAN_AddModuleToDefaultTrustDomain (
* must be called holding the ModuleListLock (either read or write).
*/
NSS_IMPLEMENT SECStatus
-STAN_RemoveModuleFromDefaultTrustDomain (
- SECMODModule *module
-)
+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);
- }
+ 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);
@@ -204,18 +201,18 @@ 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 (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;
- }
+ if (NSSCryptoContext_Destroy(g_default_crypto_context) == PR_SUCCESS) {
+ g_default_crypto_context = NULL;
+ } else {
+ status = PR_FAILURE;
+ }
}
return status;
}
@@ -235,15 +232,15 @@ STAN_GetCertIdentifierFromDER(NSSArena *arenaOpt, NSSDER *der)
/* nss3 call uses nss3 arena's */
arena = PORT_NewArena(256);
if (!arena) {
- return NULL;
+ return NULL;
}
secrv = CERT_KeyFromDERCert(arena, &secDER, &secKey);
if (secrv != SECSuccess) {
- PORT_FreeArena(arena, PR_FALSE);
- return NULL;
+ PORT_FreeArena(arena, PR_FALSE);
+ return NULL;
}
rvKey = nssItem_Create(arenaOpt, NULL, secKey.len, (void *)secKey.data);
- PORT_FreeArena(arena,PR_FALSE);
+ PORT_FreeArena(arena, PR_FALSE);
return rvKey;
}
@@ -251,7 +248,7 @@ NSS_IMPLEMENT PRStatus
nssPKIX509_GetIssuerAndSerialFromDER(NSSDER *der,
NSSDER *issuer, NSSDER *serial)
{
- SECItem derCert = { 0 };
+ SECItem derCert = { 0 };
SECItem derIssuer = { 0 };
SECItem derSerial = { 0 };
SECStatus secrv;
@@ -259,12 +256,12 @@ nssPKIX509_GetIssuerAndSerialFromDER(NSSDER *der,
derCert.len = der->size;
secrv = CERT_IssuerNameFromDERCert(&derCert, &derIssuer);
if (secrv != SECSuccess) {
- return PR_FAILURE;
+ return PR_FAILURE;
}
secrv = CERT_SerialNumberFromDERCert(&derCert, &derSerial);
if (secrv != SECSuccess) {
- PORT_Free(derSerial.data);
- return PR_FAILURE;
+ PORT_Free(derSerial.data);
+ return PR_FAILURE;
}
issuer->data = derIssuer.data;
issuer->size = derIssuer.len;
@@ -299,35 +296,34 @@ nss3certificate_matchIdentifier(nssDecodedCert *dc, void *id)
/* 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;
- }
+ 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;
- }
+ 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;
}
@@ -347,26 +343,26 @@ nss3certificate_getUsage(nssDecodedCert *dc)
return NULL;
}
-static PRBool
+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_TRUE;
}
return PR_FALSE;
}
-static PRBool
+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);
+ CERTCertificate *certa = (CERTCertificate *)dc->data;
+ CERTCertificate *certb = (CERTCertificate *)cmpdc->data;
+ return CERT_IsNewer(certa, certb);
}
return PR_FALSE;
}
@@ -384,28 +380,28 @@ nss3certificate_matchUsage(nssDecodedCert *dc, const NSSUsage *usage)
/* This is for NSS 3.3 functions that do not specify a usage */
if (usage->anyUsage) {
- return PR_TRUE;
+ return PR_TRUE;
}
ca = usage->nss3lookingForCA;
secrv = CERT_KeyUsageAndTypeForCertUsage(usage->nss3usage, ca,
&requiredKeyUsage,
&requiredCertType);
if (secrv != SECSuccess) {
- return PR_FALSE;
+ 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;
- }
+ unsigned int certType = 0;
+ if (ca) {
+ (void)CERT_IsCACert(cc, &certType);
+ } else {
+ certType = cc->nsCertType;
+ }
+ if (!(certType & requiredCertType)) {
+ match = PR_FALSE;
+ }
}
return match;
}
@@ -423,33 +419,33 @@ nss3certificate_isTrustedForUsage(nssDecodedCert *dc, const NSSUsage *usage)
/* This is for NSS 3.3 functions that do not specify a usage */
if (usage->anyUsage) {
- return PR_FALSE; /* XXX is this right? */
+ 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;
+ PRBool trusted;
+ unsigned int failedFlags;
+ secrv = cert_CheckLeafTrust(cc, usage->nss3usage,
+ &failedFlags, &trusted);
+ return secrv == SECSuccess && trusted;
}
secrv = CERT_TrustFlagsForCACertUsage(usage->nss3usage, &requiredFlags,
- &trustType);
+ &trustType);
if (secrv != SECSuccess) {
- return PR_FALSE;
+ return PR_FALSE;
}
secrv = CERT_GetCertTrust(cc, &trust);
if (secrv != SECSuccess) {
- return PR_FALSE;
+ 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;
+ /* 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);
+ trustFlags = SEC_GET_TRUST_FLAGS(&trust, trustType);
}
return (trustFlags & requiredFlags) == requiredFlags;
}
@@ -459,11 +455,12 @@ nss3certificate_getEmailAddress(nssDecodedCert *dc)
{
CERTCertificate *cc = (CERTCertificate *)dc->data;
return (cc && cc->emailAddr && cc->emailAddr[0])
- ? (NSSASCII7 *)cc->emailAddr : NULL;
+ ? (NSSASCII7 *)cc->emailAddr
+ : NULL;
}
static PRStatus
-nss3certificate_getDERSerialNumber(nssDecodedCert *dc,
+nss3certificate_getDERSerialNumber(nssDecodedCert *dc,
NSSDER *serial, NSSArena *arena)
{
CERTCertificate *cc = (CERTCertificate *)dc->data;
@@ -471,96 +468,92 @@ nss3certificate_getDERSerialNumber(nssDecodedCert *dc,
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;
+ (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
-)
+nssDecodedPKIXCertificate_Create(
+ NSSArena *arenaOpt,
+ NSSDER *encoding)
{
- nssDecodedCert *rvDC = NULL;
+ nssDecodedCert *rvDC = NULL;
CERTCertificate *cert;
- SECItem secDER;
+ 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);
- }
+ 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
-)
+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;
+ 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
-)
+nssDecodedPKIXCertificate_Destroy(nssDecodedCert *dc)
{
CERTCertificate *cert = (CERTCertificate *)dc->data;
- /* The decoder may only be half initialized (the case where we find we
+ /* 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;
- PLArenaPool *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);
- }
+ PRBool freeSlot = cert->ownSlot;
+ PK11SlotInfo *slot = cert->slot;
+ PLArenaPool *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;
@@ -572,16 +565,16 @@ get_nss3trust_from_nss4trust(nssTrustLevel t)
{
unsigned int rt = 0;
if (t == nssTrustLevel_Trusted) {
- rt |= CERTDB_TERMINAL_RECORD | CERTDB_TRUSTED;
+ rt |= CERTDB_TERMINAL_RECORD | CERTDB_TRUSTED;
}
if (t == nssTrustLevel_TrustedDelegator) {
- rt |= CERTDB_VALID_CA | CERTDB_TRUSTED_CA;
+ rt |= CERTDB_VALID_CA | CERTDB_TRUSTED_CA;
}
if (t == nssTrustLevel_NotTrusted) {
- rt |= CERTDB_TERMINAL_RECORD;
+ rt |= CERTDB_TERMINAL_RECORD;
}
if (t == nssTrustLevel_ValidDelegator) {
- rt |= CERTDB_VALID_CA;
+ rt |= CERTDB_VALID_CA;
}
return rt;
}
@@ -592,15 +585,16 @@ cert_trust_from_stan_trust(NSSTrust *t, PLArenaPool *arena)
CERTCertTrust *rvTrust;
unsigned int client;
if (!t) {
- return NULL;
+ return NULL;
}
rvTrust = PORT_ArenaAlloc(arena, sizeof(CERTCertTrust));
- if (!rvTrust) return NULL;
+ 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;
+ 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);
@@ -608,7 +602,7 @@ cert_trust_from_stan_trust(NSSTrust *t, PLArenaPool *arena)
return rvTrust;
}
-CERTCertTrust *
+CERTCertTrust *
nssTrust_GetCERTCertTrustForCert(NSSCertificate *c, CERTCertificate *cc)
{
CERTCertTrust *rvTrust = NULL;
@@ -616,23 +610,23 @@ nssTrust_GetCERTCertTrustForCert(NSSCertificate *c, CERTCertificate *cc)
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);
+ 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));
+ 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;
+ rvTrust->sslFlags |= CERTDB_USER;
+ rvTrust->emailFlags |= CERTDB_USER;
+ rvTrust->objectSigningFlags |= CERTDB_USER;
}
return rvTrust;
}
@@ -643,34 +637,33 @@ get_cert_instance(NSSCertificate *c)
nssCryptokiObject *instance, **ci;
nssCryptokiObject **instances = nssPKIObject_GetInstances(&c->object);
if (!instances) {
- return NULL;
+ 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);
- }
- }
+ 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
-)
+char *
+STAN_GetCERTCertificateNameForInstance(
+ PLArenaPool *arenaOpt,
+ NSSCertificate *c,
+ nssCryptokiInstance *instance)
{
NSSCryptoContext *context = c->object.cryptoContext;
PRStatus nssrv;
@@ -681,55 +674,55 @@ STAN_GetCERTCertificateNameForInstance (
char *nick;
if (instance) {
- stanNick = instance->label;
+ stanNick = instance->label;
} else if (context) {
- stanNick = c->object.tempName;
+ 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';
+ /* 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 *
+char *
STAN_GetCERTCertificateName(PLArenaPool *arenaOpt, NSSCertificate *c)
{
- char * result;
+ 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);
+ nssCryptokiObject_Destroy(instance);
return result;
}
static void
fill_CERTCertificateFields(NSSCertificate *c, CERTCertificate *cc, PRBool forced)
{
- CERTCertTrust* trust = NULL;
+ CERTCertTrust *trust = NULL;
NSSTrust *nssTrust;
NSSCryptoContext *context = c->object.cryptoContext;
nssCryptokiInstance *instance;
@@ -742,62 +735,62 @@ fill_CERTCertificateFields(NSSCertificate *c, CERTCertificate *cc, PRBool forced
instance = get_cert_instance(c);
if (instance) {
- stanNick = instance->label;
+ stanNick = instance->label;
} else if (context) {
- stanNick = c->object.tempName;
+ 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';
+ 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;
- }
+ } 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 */
+ 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
@@ -807,21 +800,21 @@ fill_CERTCertificateFields(NSSCertificate *c, CERTCertificate *cc, PRBool forced
cc->trust = trust;
CERT_UnlockCertTrust(cc);
}
- nssTrust_Destroy(nssTrust);
- }
+ 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);
+ /* 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
@@ -830,8 +823,10 @@ fill_CERTCertificateFields(NSSCertificate *c, CERTCertificate *cc, PRBool forced
cc->trust = trust;
CERT_UnlockCertTrust(cc);
}
- nssCryptokiObject_Destroy(instance);
- }
+ }
+ if (instance) {
+ nssCryptokiObject_Destroy(instance);
+ }
/* database handle is now the trust domain */
cc->dbhandle = c->object.trustDomain;
/* subjectList ? */
@@ -841,12 +836,12 @@ fill_CERTCertificateFields(NSSCertificate *c, CERTCertificate *cc, PRBool forced
/* pointer back */
cc->nssCertificate = c;
if (trust) {
- /* force the cert type to be recomputed to include trust info */
- PRUint32 nsCertType = cert_ComputeCertType(cc);
+ /* 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);
+ /* 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);
}
}
@@ -863,26 +858,26 @@ stan_GetCERTCertificate(NSSCertificate *c, PRBool forceUpdate)
dc = c->decoding;
if (!dc) {
- dc = nssDecodedPKIXCertificate_Create(NULL, &c->encoding);
- 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 {
+ 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);
+ nssDecodedPKIXCertificate_Destroy(dc);
+ nss_SetError(NSS_ERROR_INTERNAL_ERROR);
goto loser;
- }
+ }
}
cc = (CERTCertificate *)dc->data;
PORT_Assert(cc);
@@ -898,7 +893,7 @@ stan_GetCERTCertificate(NSSCertificate *c, PRBool forceUpdate)
* trust, so look for the trust again. But a temp cert can be
* ignored.
*/
- CERTCertTrust* trust = NULL;
+ CERTCertTrust *trust = NULL;
trust = nssTrust_GetCERTCertTrustForCert(c, cc);
CERT_LockCertTrust(cc);
@@ -906,7 +901,7 @@ stan_GetCERTCertificate(NSSCertificate *c, PRBool forceUpdate)
CERT_UnlockCertTrust(cc);
}
- loser:
+loser:
nssPKIObject_Unlock(&c->object);
nssPKIObject_Destroy(&c->object);
return cc;
@@ -916,7 +911,7 @@ NSS_IMPLEMENT CERTCertificate *
STAN_ForceCERTCertificateUpdate(NSSCertificate *c)
{
if (c->decoding) {
- return stan_GetCERTCertificate(c, PR_TRUE);
+ return stan_GetCERTCertificate(c, PR_TRUE);
}
return NULL;
}
@@ -928,10 +923,10 @@ STAN_GetCERTCertificate(NSSCertificate *c)
}
/*
* 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
+ * 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 *
@@ -939,31 +934,31 @@ STAN_GetCERTCertificateOrRelease(NSSCertificate *c)
{
CERTCertificate *nss3cert = stan_GetCERTCertificate(c, PR_FALSE);
if (!nss3cert) {
- nssCertificate_Destroy(c);
+ nssCertificate_Destroy(c);
}
return nss3cert;
}
static nssTrustLevel
-get_stan_trust(unsigned int t, PRBool isClientAuth)
+get_stan_trust(unsigned int t, PRBool isClientAuth)
{
if (isClientAuth) {
- if (t & CERTDB_TRUSTED_CLIENT_CA) {
- return nssTrustLevel_TrustedDelegator;
- }
+ 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_CA || t & CERTDB_NS_TRUSTED_CA) {
+ return nssTrustLevel_TrustedDelegator;
+ }
}
if (t & CERTDB_TRUSTED) {
- return nssTrustLevel_Trusted;
+ return nssTrustLevel_Trusted;
}
if (t & CERTDB_TERMINAL_RECORD) {
- return nssTrustLevel_NotTrusted;
+ return nssTrustLevel_NotTrusted;
}
if (t & CERTDB_VALID_CA) {
- return nssTrustLevel_ValidDelegator;
+ return nssTrustLevel_ValidDelegator;
}
return nssTrustLevel_MustVerify;
}
@@ -977,26 +972,26 @@ STAN_GetNSSCertificate(CERTCertificate *cc)
NSSArena *arena;
c = cc->nssCertificate;
if (c) {
- return 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;
+ return NULL;
}
c = nss_ZNEW(arena, NSSCertificate);
if (!c) {
- nssArena_Destroy(arena);
- return NULL;
+ 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;
+ nssArena_Destroy(arena);
+ return NULL;
}
c->object = *pkiob;
nssItem_Create(arena,
@@ -1004,18 +999,18 @@ STAN_GetNSSCertificate(CERTCertificate *cc)
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);
+ /* 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,
@@ -1024,31 +1019,30 @@ STAN_GetNSSCertificate(CERTCertificate *cc)
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);
+ 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
-)
+static NSSToken *
+stan_GetTrustToken(
+ NSSCertificate *c)
{
NSSToken *ttok = NULL;
NSSToken *rtok = NULL;
@@ -1056,31 +1050,31 @@ stan_GetTrustToken (
nssCryptokiObject **ip;
nssCryptokiObject **instances = nssPKIObject_GetInstances(&c->object);
if (!instances) {
- return PR_FALSE;
+ 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;
- }
- }
+ 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);
@@ -1107,15 +1101,15 @@ STAN_ChangeCertTrust(CERTCertificate *cc, CERTCertTrust *trust)
}
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;
- }
+ 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));
+ newTrust = PORT_ArenaAlloc(cc->arena, sizeof(CERTCertTrust));
}
memcpy(newTrust, trust, sizeof(CERTCertTrust));
CERT_LockCertTrust(cc);
@@ -1123,16 +1117,17 @@ STAN_ChangeCertTrust(CERTCertificate *cc, CERTCertTrust *trust)
CERT_UnlockCertTrust(cc);
/* Set the NSSCerticate's trust */
arena = nssArena_Create();
- if (!arena) return PR_FAILURE;
+ if (!arena)
+ return PR_FAILURE;
nssTrust = nss_ZNEW(arena, NSSTrust);
if (!nssTrust) {
- nssArena_Destroy(arena);
- return PR_FAILURE;
+ nssArena_Destroy(arena);
+ return PR_FAILURE;
}
pkiob = nssPKIObject_Create(arena, NULL, cc->dbhandle, NULL, nssPKILock);
if (!pkiob) {
- nssArena_Destroy(arena);
- return PR_FAILURE;
+ nssArena_Destroy(arena);
+ return PR_FAILURE;
}
nssTrust->object = *pkiob;
nssTrust->certificate = c;
@@ -1140,120 +1135,120 @@ STAN_ChangeCertTrust(CERTCertificate *cc, CERTCertTrust *trust)
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);
+ 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;
- }
+ /* 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 && 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);
+ 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);
+ 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;
- }
+ 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;
+ nssrv = PR_FAILURE;
}
done:
(void)nssTrust_Destroy(nssTrust);
@@ -1271,41 +1266,40 @@ done:
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 numNotDestroyed = 0; /* the ones skipped plus the failures */
+ int failureCount = 0; /* actual deletion failures by devices */
unsigned int index;
nssPKIObject_AddRef(tObject);
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++;
- }
+ 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;
+ nss_ZFreeIf(tObject->instances);
+ tObject->numInstances = 0;
} else {
- tObject->numInstances = numNotDestroyed;
+ tObject->numInstances = numNotDestroyed;
}
nssPKIObject_Unlock(tObject);
@@ -1316,19 +1310,24 @@ DeleteCertTrustMatchingSlot(PK11SlotInfo *pk11slot, nssPKIObject *tObject)
/*
** Delete trust objects matching the slot of the given certificate.
-** Returns an error if any device fails to delete.
+** Returns an error if any device fails to delete.
*/
NSS_EXTERN PRStatus
STAN_DeleteCertTrustMatchingSlot(NSSCertificate *c)
{
PRStatus nssrv = PR_SUCCESS;
+ unsigned int i;
+ nssPKIObject *tobject = NULL;
+ nssPKIObject *cobject = &c->object;
+
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;
- unsigned int i;
+ if (!nssTrust) {
+ return PR_FAILURE;
+ }
+
+ tobject = &nssTrust->object;
/* Iterate through the cert and trust object instances looking for
* those with matching pk11 slots to delete. Even if some device
@@ -1339,17 +1338,19 @@ STAN_DeleteCertTrustMatchingSlot(NSSCertificate *c)
nssPKIObject_AddRef(cobject);
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;
- }
- }
+ 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;
+ }
+ }
}
+ nssTrust_Destroy(nssTrust);
nssPKIObject_Unlock(cobject);
nssPKIObject_Destroy(cobject);
NSSRWLock_UnlockRead(td->tokensLock);
@@ -1358,12 +1359,11 @@ STAN_DeleteCertTrustMatchingSlot(NSSCertificate *c)
/* CERT_TraversePermCertsForSubject */
NSS_IMPLEMENT PRStatus
-nssTrustDomain_TraverseCertificatesBySubject (
- NSSTrustDomain *td,
- NSSDER *subject,
- PRStatus (*callback)(NSSCertificate *c, void *arg),
- void *arg
-)
+nssTrustDomain_TraverseCertificatesBySubject(
+ NSSTrustDomain *td,
+ NSSDER *subject,
+ PRStatus (*callback)(NSSCertificate *c, void *arg),
+ void *arg)
{
PRStatus nssrv = PR_SUCCESS;
NSSArena *tmpArena;
@@ -1377,10 +1377,11 @@ nssTrustDomain_TraverseCertificatesBySubject (
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;
- }
+ for (i = 0, c = subjectCerts[i]; c; i++) {
+ nssrv = callback(c, arg);
+ if (nssrv != PR_SUCCESS)
+ break;
+ }
}
nssArena_Destroy(tmpArena);
return nssrv;
@@ -1388,12 +1389,11 @@ nssTrustDomain_TraverseCertificatesBySubject (
/* CERT_TraversePermCertsForNickname */
NSS_IMPLEMENT PRStatus
-nssTrustDomain_TraverseCertificatesByNickname (
- NSSTrustDomain *td,
- NSSUTF8 *nickname,
- PRStatus (*callback)(NSSCertificate *c, void *arg),
- void *arg
-)
+nssTrustDomain_TraverseCertificatesByNickname(
+ NSSTrustDomain *td,
+ NSSUTF8 *nickname,
+ PRStatus (*callback)(NSSCertificate *c, void *arg),
+ void *arg)
{
PRStatus nssrv = PR_SUCCESS;
NSSArena *tmpArena;
@@ -1407,16 +1407,18 @@ nssTrustDomain_TraverseCertificatesByNickname (
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;
- }
+ 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)
+static void
+cert_dump_iter(const void *k, void *v, void *a)
{
NSSCertificate *c = (NSSCertificate *)k;
CERTCertificate *cert = STAN_GetCERTCertificate(c);
@@ -1434,7 +1436,6 @@ nss_DumpCertificateCacheInfo()
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);
+ nssCertificateStore_DumpStoreInfo(cc->certStore, cert_dump_iter, NULL);
}
}
-
diff --git a/nss/lib/pki/pki3hack.h b/nss/lib/pki/pki3hack.h
index 39fab75..818872a 100644
--- a/nss/lib/pki/pki3hack.h
+++ b/nss/lib/pki/pki3hack.h
@@ -23,13 +23,13 @@
PR_BEGIN_EXTERN_C
-#define NSSITEM_FROM_SECITEM(nssit, secit) \
- (nssit)->data = (void *)(secit)->data; \
+#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;
+ (secit)->len = (unsigned int)(nssit)->size;
NSS_EXTERN NSSTrustDomain *
STAN_GetDefaultTrustDomain();
@@ -67,7 +67,7 @@ STAN_GetCERTCertificateOrRelease(NSSCertificate *c);
NSS_EXTERN NSSCertificate *
STAN_GetNSSCertificate(CERTCertificate *c);
-NSS_EXTERN CERTCertTrust *
+NSS_EXTERN CERTCertTrust *
nssTrust_GetCERTCertTrustForCert(NSSCertificate *c, CERTCertificate *cc);
NSS_EXTERN PRStatus
@@ -90,74 +90,59 @@ STAN_GetCERTCertificateNameForInstance(PLArenaPool *arenaOpt,
/* exposing this */
NSS_EXTERN NSSCertificate *
-NSSCertificate_Create
-(
- NSSArena *arenaOpt
-);
+NSSCertificate_Create(NSSArena *arenaOpt);
-/* This function is being put here because it is a hack for
+/* 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
+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
-);
+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
-);
+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
-);
+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
-);
+nssTrustDomain_TraverseCertificates(
+ NSSTrustDomain *td,
+ PRStatus (*callback)(NSSCertificate *c, void *arg),
+ void *arg);
/* CERT_AddTempCertToPerm */
NSS_EXTERN PRStatus
-nssTrustDomain_AddTempCertToPerm
-(
- NSSCertificate *c
-);
+nssTrustDomain_AddTempCertToPerm(NSSCertificate *c);
PR_END_EXTERN_C
diff --git a/nss/lib/pki/pkibase.c b/nss/lib/pki/pkibase.c
index 0e39e8b..4082a37 100644
--- a/nss/lib/pki/pkibase.c
+++ b/nss/lib/pki/pkibase.c
@@ -15,244 +15,237 @@
extern const NSSError NSS_ERROR_NOT_FOUND;
NSS_IMPLEMENT void
-nssPKIObject_Lock(nssPKIObject * object)
+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);
+ 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)
+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);
+ 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)
+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;
+ 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)
+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);
+ 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
-)
+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);
+ arena = arenaOpt;
+ mark = nssArena_Mark(arena);
} else {
- arena = nssArena_Create();
- if (!arena) {
- return (nssPKIObject *)NULL;
- }
+ arena = nssArena_Create();
+ if (!arena) {
+ return (nssPKIObject *)NULL;
+ }
}
object = nss_ZNEW(arena, nssPKIObject);
if (!object) {
- goto loser;
+ goto loser;
}
object->arena = arena;
object->trustDomain = td; /* XXX */
object->cryptoContext = cc;
if (PR_SUCCESS != nssPKIObject_NewLock(object, lockType)) {
- goto loser;
+ goto loser;
}
if (instanceOpt) {
- if (nssPKIObject_AddInstance(object, instanceOpt) != PR_SUCCESS) {
- goto loser;
- }
+ if (nssPKIObject_AddInstance(object, instanceOpt) != PR_SUCCESS) {
+ goto loser;
+ }
}
PR_ATOMIC_INCREMENT(&object->refCount);
if (mark) {
- nssArena_Unmark(arena, mark);
+ nssArena_Unmark(arena, mark);
}
return object;
loser:
if (mark) {
- nssArena_Release(arena, mark);
+ nssArena_Release(arena, mark);
} else {
- nssArena_Destroy(arena);
+ nssArena_Destroy(arena);
}
return (nssPKIObject *)NULL;
}
NSS_IMPLEMENT PRBool
-nssPKIObject_Destroy (
- nssPKIObject *object
-)
+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;
+ 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
-)
+nssPKIObject_AddRef(
+ nssPKIObject *object)
{
PR_ATOMIC_INCREMENT(&object->refCount);
return object;
}
NSS_IMPLEMENT PRStatus
-nssPKIObject_AddInstance (
- nssPKIObject *object,
- nssCryptokiObject *instance
-)
+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);
+ 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);
+ 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;
+ 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
-)
+nssPKIObject_HasInstance(
+ nssPKIObject *object,
+ nssCryptokiObject *instance)
{
PRUint32 i;
- PRBool hasIt = PR_FALSE;;
+ 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;
- }
+ 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
-)
+nssPKIObject_RemoveInstanceForToken(
+ nssPKIObject *object,
+ NSSToken *token)
{
PRUint32 i;
nssCryptokiObject *instanceToRemove = NULL;
nssPKIObject_Lock(object);
if (object->numInstances == 0) {
- nssPKIObject_Unlock(object);
- return PR_SUCCESS;
+ 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;
- }
+ 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;
- }
+ nssCryptokiObject **instances = nss_ZREALLOCARRAY(object->instances,
+ nssCryptokiObject *,
+ object->numInstances);
+ if (instances) {
+ object->instances = instances;
+ }
} else {
- nss_ZFreeIf(object->instances);
+ nss_ZFreeIf(object->instances);
}
nssCryptokiObject_Destroy(instanceToRemove);
nssPKIObject_Unlock(object);
@@ -263,171 +256,165 @@ nssPKIObject_RemoveInstanceForToken (
* instances
*/
NSS_IMPLEMENT PRStatus
-nssPKIObject_DeleteStoredObject (
- nssPKIObject *object,
- NSSCallback *uhh,
- PRBool isFriendly
-)
+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;
- }
+ 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;
+ nss_ZFreeIf(object->instances);
+ object->numInstances = 0;
} else {
- object->numInstances = numNotDestroyed;
+ object->numInstances = numNotDestroyed;
}
nssPKIObject_Unlock(object);
return status;
}
NSS_IMPLEMENT NSSToken **
-nssPKIObject_GetTokens (
- nssPKIObject *object,
- PRStatus *statusOpt
-)
+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);
- }
- }
+ 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 */
+ if (statusOpt)
+ *statusOpt = PR_SUCCESS; /* until more logic here */
return tokens;
}
NSS_IMPLEMENT NSSUTF8 *
-nssPKIObject_GetNicknameForToken (
- nssPKIObject *object,
- NSSToken *tokenOpt
-)
+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))
- {
+ 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;
- }
+ nickname = nssUTF8_Duplicate(object->instances[i]->label, NULL);
+ break;
+ }
}
nssPKIObject_Unlock(object);
return nickname;
}
NSS_IMPLEMENT nssCryptokiObject **
-nssPKIObject_GetInstances (
- nssPKIObject *object
-)
+nssPKIObject_GetInstances(
+ nssPKIObject *object)
{
nssCryptokiObject **instances = NULL;
PRUint32 i;
if (object->numInstances == 0) {
- return (nssCryptokiObject **)NULL;
+ return (nssCryptokiObject **)NULL;
}
nssPKIObject_Lock(object);
- instances = nss_ZNEWARRAY(NULL, nssCryptokiObject *,
+ instances = nss_ZNEWARRAY(NULL, nssCryptokiObject *,
object->numInstances + 1);
if (instances) {
- for (i=0; i<object->numInstances; i++) {
- instances[i] = nssCryptokiObject_Clone(object->instances[i]);
- }
+ 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
-)
+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);
+ 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(
+ NSSCertificate **certs)
{
nssCertificateArray_Destroy(certs);
}
NSS_IMPLEMENT NSSCertificate **
-nssCertificateArray_Join (
- NSSCertificate **certs1,
- NSSCertificate **certs2
-)
+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;
+ 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;
+ return certs1;
} else {
- return certs2;
+ return certs2;
}
}
-NSS_IMPLEMENT NSSCertificate *
-nssCertificateArray_FindBestCertificate (
- NSSCertificate **certs,
- NSSTime *timeOpt,
- const NSSUsage *usage,
- NSSPolicies *policiesOpt
-)
+NSS_IMPLEMENT NSSCertificate *
+nssCertificateArray_FindBestCertificate(
+ NSSCertificate **certs,
+ NSSTime *timeOpt,
+ const NSSUsage *usage,
+ NSSPolicies *policiesOpt)
{
NSSCertificate *bestCert = NULL;
nssDecodedCert *bestdc = NULL;
@@ -438,129 +425,127 @@ nssCertificateArray_FindBestCertificate (
PRBool bestCertIsTrusted = PR_FALSE;
if (timeOpt) {
- time = timeOpt;
+ time = timeOpt;
} else {
- NSSTime_Now(&sTime);
- time = &sTime;
+ NSSTime_Now(&sTime);
+ time = &sTime;
}
if (!certs) {
- return (NSSCertificate *)NULL;
+ 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 */
+ 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
-)
+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;
- }
- }
+ 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
-)
+nssCRLArray_Destroy(
+ NSSCRL **crls)
{
if (crls) {
- NSSCRL **crlp;
- for (crlp = crls; *crlp; crlp++) {
- nssCRL_Destroy(*crlp);
- }
- nss_ZFreeIf(crls);
+ NSSCRL **crlp;
+ for (crlp = crls; *crlp; crlp++) {
+ nssCRL_Destroy(*crlp);
+ }
+ nss_ZFreeIf(crls);
}
}
@@ -568,12 +553,11 @@ nssCRLArray_Destroy (
* Object collections
*/
-typedef enum
-{
- pkiObjectType_Certificate = 0,
- pkiObjectType_CRL = 1,
- pkiObjectType_PrivateKey = 2,
- pkiObjectType_PublicKey = 3
+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.
@@ -593,12 +577,11 @@ typedef enum
*/
typedef struct
{
- PRCList link;
- PRBool haveObject;
- nssPKIObject *object;
- NSSItem uid[MAX_ITEMS_FOR_UID];
-}
-pkiObjectCollectionNode;
+ PRCList link;
+ PRBool haveObject;
+ nssPKIObject *object;
+ NSSItem uid[MAX_ITEMS_FOR_UID];
+} pkiObjectCollectionNode;
/* nssPKIObjectCollection
*
@@ -606,38 +589,36 @@ pkiObjectCollectionNode;
* 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 */
+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
-)
+nssPKIObjectCollection_Create(
+ NSSTrustDomain *td,
+ NSSCryptoContext *ccOpt,
+ nssPKILockType lockType)
{
NSSArena *arena;
nssPKIObjectCollection *rvCollection = NULL;
arena = nssArena_Create();
if (!arena) {
- return (nssPKIObjectCollection *)NULL;
+ return (nssPKIObjectCollection *)NULL;
}
rvCollection = nss_ZNEW(arena, nssPKIObjectCollection);
if (!rvCollection) {
- goto loser;
+ goto loser;
}
PR_INIT_CLIST(&rvCollection->head);
rvCollection->arena = arena;
@@ -651,47 +632,44 @@ loser:
}
NSS_IMPLEMENT void
-nssPKIObjectCollection_Destroy (
- nssPKIObjectCollection *collection
-)
+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);
+ 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
-)
+nssPKIObjectCollection_Count(
+ nssPKIObjectCollection *collection)
{
return collection->size;
}
NSS_IMPLEMENT PRStatus
-nssPKIObjectCollection_AddObject (
- nssPKIObjectCollection *collection,
- nssPKIObject *object
-)
+nssPKIObjectCollection_AddObject(
+ nssPKIObjectCollection *collection,
+ nssPKIObject *object)
{
pkiObjectCollectionNode *node;
node = nss_ZNEW(collection->arena, pkiObjectCollectionNode);
if (!node) {
- return PR_FAILURE;
+ return PR_FAILURE;
}
node->haveObject = PR_TRUE;
node->object = nssPKIObject_AddRef(object);
@@ -703,29 +681,27 @@ nssPKIObjectCollection_AddObject (
}
static pkiObjectCollectionNode *
-find_instance_in_collection (
- nssPKIObjectCollection *collection,
- nssCryptokiObject *instance
-)
+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);
+ 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
-)
+find_object_in_collection(
+ nssPKIObjectCollection *collection,
+ NSSItem *uid)
{
PRUint32 i;
PRStatus status;
@@ -733,26 +709,25 @@ find_object_in_collection (
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);
+ 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
-)
+add_object_instance(
+ nssPKIObjectCollection *collection,
+ nssCryptokiObject *instance,
+ PRBool *foundIt)
{
PRUint32 i;
PRStatus status;
@@ -768,208 +743,203 @@ add_object_instance (
*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;
+ /* 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;
+ goto loser;
}
- status = (*collection->getUIDFromInstance)(instance, uid,
+ status = (*collection->getUIDFromInstance)(instance, uid,
collection->arena);
if (status != PR_SUCCESS) {
- goto loser;
+ 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
+ /* 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);
+ /* 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,
+ /* 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;
+ 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);
+ nssArena_Release(collection->arena, mark);
}
nssCryptokiObject_Destroy(instance);
return (pkiObjectCollectionNode *)NULL;
}
NSS_IMPLEMENT PRStatus
-nssPKIObjectCollection_AddInstances (
- nssPKIObjectCollection *collection,
- nssCryptokiObject **instances,
- PRUint32 numInstances
-)
+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++;
- }
+ 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
-)
+nssPKIObjectCollection_RemoveNode(
+ nssPKIObjectCollection *collection,
+ pkiObjectCollectionNode *node)
{
- PR_REMOVE_LINK(&node->link);
+ PR_REMOVE_LINK(&node->link);
collection->size--;
}
static PRStatus
-nssPKIObjectCollection_GetObjects (
- nssPKIObjectCollection *collection,
- nssPKIObject **rvObjects,
- PRUint32 rvSize
-)
+nssPKIObjectCollection_GetObjects(
+ nssPKIObjectCollection *collection,
+ nssPKIObject **rvObjects,
+ PRUint32 rvSize)
{
PRUint32 i = 0;
PRCList *link = PR_NEXT_LINK(&collection->head);
pkiObjectCollectionNode *node;
- int error=0;
+ 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);
+ 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);
+ nss_SetError(NSS_ERROR_NOT_FOUND);
}
return PR_SUCCESS;
}
NSS_IMPLEMENT PRStatus
-nssPKIObjectCollection_Traverse (
- nssPKIObjectCollection *collection,
- nssPKIObjectCallback *callback
-)
+nssPKIObjectCollection_Traverse(
+ nssPKIObjectCollection *collection,
+ nssPKIObjectCallback *callback)
{
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:
- (void)(*callback->func.cert)((NSSCertificate *)node->object,
- callback->arg);
- break;
- case pkiObjectType_CRL:
- (void)(*callback->func.crl)((NSSCRL *)node->object,
- callback->arg);
- break;
- case pkiObjectType_PrivateKey:
- (void)(*callback->func.pvkey)((NSSPrivateKey *)node->object,
- callback->arg);
- break;
- case pkiObjectType_PublicKey:
- (void)(*callback->func.pbkey)((NSSPublicKey *)node->object,
- callback->arg);
- break;
- }
- link = PR_NEXT_LINK(link);
+ 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:
+ (void)(*callback->func.cert)((NSSCertificate *)node->object,
+ callback->arg);
+ break;
+ case pkiObjectType_CRL:
+ (void)(*callback->func.crl)((NSSCRL *)node->object,
+ callback->arg);
+ break;
+ case pkiObjectType_PrivateKey:
+ (void)(*callback->func.pvkey)((NSSPrivateKey *)node->object,
+ callback->arg);
+ break;
+ case pkiObjectType_PublicKey:
+ (void)(*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
-)
+nssPKIObjectCollection_AddInstanceAsObject(
+ nssPKIObjectCollection *collection,
+ nssCryptokiObject *instance)
{
pkiObjectCollectionNode *node;
PRBool foundIt;
node = add_object_instance(collection, instance, &foundIt);
if (node == NULL) {
- return PR_FAILURE;
+ 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;
+ 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);
+ /* 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;
}
@@ -983,11 +953,11 @@ 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 */
+ CERTCertificate *cc = STAN_GetCERTCertificate(c);
+ if (cc) {
+ CERT_DestroyCertificate(cc);
+ return;
+ } /* else destroy it as NSSCertificate below */
}
nssCertificate_Destroy(c);
}
@@ -1002,32 +972,35 @@ cert_getUIDFromObject(nssPKIObject *o, NSSItem *uid)
*/
NSSDER *derCert;
derCert = nssCertificate_GetEncoding(c);
- uid[0].data = NULL; uid[0].size = 0;
- uid[1].data = NULL; uid[1].size = 0;
+ uid[0].data = NULL;
+ uid[0].size = 0;
+ uid[1].data = NULL;
+ uid[1].size = 0;
if (derCert != NULL) {
- uid[0] = *derCert;
+ uid[0] = *derCert;
}
return PR_SUCCESS;
}
static PRStatus
-cert_getUIDFromInstance(nssCryptokiObject *instance, NSSItem *uid,
+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;
+ uid[1].data = NULL;
+ uid[1].size = 0;
return nssCryptokiCertificate_GetAttributes(instance,
- NULL, /* XXX sessionOpt */
- arena, /* arena */
- NULL, /* type */
- NULL, /* id */
+ NULL, /* XXX sessionOpt */
+ arena, /* arena */
+ NULL, /* type */
+ NULL, /* id */
&uid[0], /* encoding */
- NULL, /* issuer */
- NULL, /* serial */
- NULL); /* subject */
+ NULL, /* issuer */
+ NULL, /* serial */
+ NULL); /* subject */
}
static nssPKIObject *
@@ -1035,26 +1008,25 @@ cert_createObject(nssPKIObject *o)
{
NSSCertificate *cert;
cert = nssCertificate_Create(o);
-/* if (STAN_GetCERTCertificate(cert) == NULL) {
- nssCertificate_Destroy(cert);
- return (nssPKIObject *)NULL;
+ /* 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);
+ NSSTrustDomain *td = o->trustDomain;
+ nssTrustDomain_AddCertsToCache(td, &cert, 1);
}
return (nssPKIObject *)cert;
}
NSS_IMPLEMENT nssPKIObjectCollection *
-nssCertificateCollection_Create (
- NSSTrustDomain *td,
- NSSCertificate **certsOpt
-)
+nssCertificateCollection_Create(
+ NSSTrustDomain *td,
+ NSSCertificate **certsOpt)
{
nssPKIObjectCollection *collection;
collection = nssPKIObjectCollection_Create(td, NULL, nssPKIMonitor);
@@ -1067,48 +1039,47 @@ nssCertificateCollection_Create (
collection->getUIDFromInstance = cert_getUIDFromInstance;
collection->createObject = cert_createObject;
if (certsOpt) {
- for (; *certsOpt; certsOpt++) {
- nssPKIObject *object = (nssPKIObject *)(*certsOpt);
- (void)nssPKIObjectCollection_AddObject(collection, object);
- }
+ for (; *certsOpt; certsOpt++) {
+ nssPKIObject *object = (nssPKIObject *)(*certsOpt);
+ (void)nssPKIObjectCollection_AddObject(collection, object);
+ }
}
return collection;
}
NSS_IMPLEMENT NSSCertificate **
-nssPKIObjectCollection_GetCertificates (
- nssPKIObjectCollection *collection,
- NSSCertificate **rvOpt,
- PRUint32 maximumOpt,
- NSSArena *arenaOpt
-)
+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;
+ return (NSSCertificate **)NULL;
}
if (maximumOpt == 0) {
- rvSize = collection->size;
+ rvSize = collection->size;
} else {
- rvSize = PR_MIN(collection->size, maximumOpt);
+ 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,
+ 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;
+ if (allocated) {
+ nss_ZFreeIf(rvOpt);
+ }
+ return (NSSCertificate **)NULL;
}
return rvOpt;
}
@@ -1135,12 +1106,13 @@ crl_getUIDFromObject(nssPKIObject *o, NSSItem *uid)
return PR_FALSE;
}
uid[0] = *encoding;
- uid[1].data = NULL; uid[1].size = 0;
+ uid[1].data = NULL;
+ uid[1].size = 0;
return PR_SUCCESS;
}
static PRStatus
-crl_getUIDFromInstance(nssCryptokiObject *instance, NSSItem *uid,
+crl_getUIDFromInstance(nssCryptokiObject *instance, NSSItem *uid,
NSSArena *arena)
{
return nssCryptokiCRL_GetAttributes(instance,
@@ -1160,10 +1132,9 @@ crl_createObject(nssPKIObject *o)
}
NSS_IMPLEMENT nssPKIObjectCollection *
-nssCRLCollection_Create (
- NSSTrustDomain *td,
- NSSCRL **crlsOpt
-)
+nssCRLCollection_Create(
+ NSSTrustDomain *td,
+ NSSCRL **crlsOpt)
{
nssPKIObjectCollection *collection;
collection = nssPKIObjectCollection_Create(td, NULL, nssPKILock);
@@ -1176,48 +1147,47 @@ nssCRLCollection_Create (
collection->getUIDFromInstance = crl_getUIDFromInstance;
collection->createObject = crl_createObject;
if (crlsOpt) {
- for (; *crlsOpt; crlsOpt++) {
- nssPKIObject *object = (nssPKIObject *)(*crlsOpt);
- (void)nssPKIObjectCollection_AddObject(collection, object);
- }
+ for (; *crlsOpt; crlsOpt++) {
+ nssPKIObject *object = (nssPKIObject *)(*crlsOpt);
+ (void)nssPKIObjectCollection_AddObject(collection, object);
+ }
}
return collection;
}
NSS_IMPLEMENT NSSCRL **
-nssPKIObjectCollection_GetCRLs (
- nssPKIObjectCollection *collection,
- NSSCRL **rvOpt,
- PRUint32 maximumOpt,
- NSSArena *arenaOpt
-)
+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;
+ return (NSSCRL **)NULL;
}
if (maximumOpt == 0) {
- rvSize = collection->size;
+ rvSize = collection->size;
} else {
- rvSize = PR_MIN(collection->size, maximumOpt);
+ 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,
+ 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;
+ if (allocated) {
+ nss_ZFreeIf(rvOpt);
+ }
+ return (NSSCRL **)NULL;
}
return rvOpt;
}
@@ -1226,18 +1196,15 @@ nssPKIObjectCollection_GetCRLs (
* this was called? would avoid repeated allocs...
*/
NSS_IMPLEMENT NSSTime *
-NSSTime_Now (
- NSSTime *timeOpt
-)
+NSSTime_Now(NSSTime *timeOpt)
{
return NSSTime_SetPRTime(timeOpt, PR_Now());
}
NSS_IMPLEMENT NSSTime *
-NSSTime_SetPRTime (
- NSSTime *timeOpt,
- PRTime prTime
-)
+NSSTime_SetPRTime(
+ NSSTime *timeOpt,
+ PRTime prTime)
{
NSSTime *rvTime;
rvTime = (timeOpt) ? timeOpt : nss_ZNEW(NULL, NSSTime);
@@ -1248,10 +1215,8 @@ NSSTime_SetPRTime (
}
NSS_IMPLEMENT PRTime
-NSSTime_GetPRTime (
- NSSTime *time
-)
+NSSTime_GetPRTime(
+ NSSTime *time)
{
- return time->prTime;
+ return time->prTime;
}
-
diff --git a/nss/lib/pki/pkim.h b/nss/lib/pki/pkim.h
index b1158eb..3be3337 100644
--- a/nss/lib/pki/pkim.h
+++ b/nss/lib/pki/pkim.h
@@ -36,11 +36,11 @@ PR_BEGIN_EXTERN_C
* 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);
+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
*
@@ -48,22 +48,17 @@ NSS_EXTERN void nssPKIObject_DestroyLock(nssPKIObject * object);
* 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_Create(
+ NSSArena *arenaOpt,
+ nssCryptokiObject *instanceOpt,
+ NSSTrustDomain *td,
+ NSSCryptoContext *ccOpt,
+ nssPKILockType lockType);
/* nssPKIObject_AddRef
*/
NSS_EXTERN nssPKIObject *
-nssPKIObject_AddRef
-(
- nssPKIObject *object
-);
+nssPKIObject_AddRef(nssPKIObject *object);
/* nssPKIObject_Destroy
*
@@ -71,43 +66,34 @@ nssPKIObject_AddRef
* all references are gone and it should delete any members it owns.
*/
NSS_EXTERN PRBool
-nssPKIObject_Destroy
-(
- nssPKIObject *object
-);
+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_AddInstance(
+ nssPKIObject *object,
+ nssCryptokiObject *instance);
/* nssPKIObject_HasInstance
*
* Query the object for a token instance.
*/
NSS_EXTERN PRBool
-nssPKIObject_HasInstance
-(
- nssPKIObject *object,
- nssCryptokiObject *instance
-);
+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_GetTokens(
+ nssPKIObject *object,
+ PRStatus *statusOpt);
/* nssPKIObject_GetNicknameForToken
*
@@ -115,22 +101,18 @@ nssPKIObject_GetTokens
* nickname for the specified token.
*/
NSS_EXTERN NSSUTF8 *
-nssPKIObject_GetNicknameForToken
-(
- nssPKIObject *object,
- NSSToken *tokenOpt
-);
+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_RemoveInstanceForToken(
+ nssPKIObject *object,
+ NSSToken *token);
/* nssPKIObject_DeleteStoredObject
*
@@ -143,135 +125,88 @@ nssPKIObject_RemoveInstanceForToken
* regardless of the value of 'isFriendly'.
*/
NSS_EXTERN PRStatus
-nssPKIObject_DeleteStoredObject
-(
- nssPKIObject *object,
- NSSCallback *uhh,
- PRBool isFriendly
-);
+nssPKIObject_DeleteStoredObject(
+ nssPKIObject *object,
+ NSSCallback *uhh,
+ PRBool isFriendly);
NSS_EXTERN nssCryptokiObject **
-nssPKIObject_GetInstances
-(
- nssPKIObject *object
-);
+nssPKIObject_GetInstances(
+ nssPKIObject *object);
NSS_EXTERN NSSCertificate **
-nssTrustDomain_FindCertificatesByID
-(
- NSSTrustDomain *td,
- NSSItem *id,
- NSSCertificate **rvOpt,
- PRUint32 maximumOpt,
- NSSArena *arenaOpt
-);
+nssTrustDomain_FindCertificatesByID(
+ NSSTrustDomain *td,
+ NSSItem *id,
+ NSSCertificate **rvOpt,
+ PRUint32 maximumOpt,
+ NSSArena *arenaOpt);
NSS_EXTERN NSSCRL **
-nssTrustDomain_FindCRLsBySubject
-(
- NSSTrustDomain *td,
- NSSDER *subject
-);
+nssTrustDomain_FindCRLsBySubject(
+ NSSTrustDomain *td,
+ NSSDER *subject);
/* module-private nsspki methods */
NSS_EXTERN NSSCryptoContext *
-nssCryptoContext_Create
-(
- NSSTrustDomain *td,
- NSSCallback *uhhOpt
-);
+nssCryptoContext_Create(
+ NSSTrustDomain *td,
+ NSSCallback *uhhOpt);
/* XXX for the collection */
NSS_EXTERN NSSCertificate *
-nssCertificate_Create
-(
- nssPKIObject *object
-);
+nssCertificate_Create(nssPKIObject *object);
NSS_EXTERN PRStatus
-nssCertificate_SetCertTrust
-(
- NSSCertificate *c,
- NSSTrust *trust
-);
+nssCertificate_SetCertTrust(
+ NSSCertificate *c,
+ NSSTrust *trust);
NSS_EXTERN nssDecodedCert *
-nssCertificate_GetDecoding
-(
- NSSCertificate *c
-);
+nssCertificate_GetDecoding(NSSCertificate *c);
extern PRIntn
-nssCertificate_SubjectListSort
-(
- void *v1,
- void *v2
-);
+nssCertificate_SubjectListSort(
+ void *v1,
+ void *v2);
NSS_EXTERN nssDecodedCert *
-nssDecodedCert_Create
-(
- NSSArena *arenaOpt,
- NSSDER *encoding,
- NSSCertificateType type
-);
+nssDecodedCert_Create(
+ NSSArena *arenaOpt,
+ NSSDER *encoding,
+ NSSCertificateType type);
NSS_EXTERN PRStatus
-nssDecodedCert_Destroy
-(
- nssDecodedCert *dc
-);
+nssDecodedCert_Destroy(nssDecodedCert *dc);
NSS_EXTERN NSSTrust *
-nssTrust_Create
-(
- nssPKIObject *object,
- NSSItem *certData
-);
+nssTrust_Create(
+ nssPKIObject *object,
+ NSSItem *certData);
NSS_EXTERN NSSCRL *
-nssCRL_Create
-(
- nssPKIObject *object
-);
+nssCRL_Create(nssPKIObject *object);
NSS_EXTERN NSSCRL *
-nssCRL_AddRef
-(
- NSSCRL *crl
-);
+nssCRL_AddRef(NSSCRL *crl);
NSS_EXTERN PRStatus
-nssCRL_Destroy
-(
- NSSCRL *crl
-);
+nssCRL_Destroy(NSSCRL *crl);
NSS_EXTERN PRStatus
-nssCRL_DeleteStoredObject
-(
- NSSCRL *crl,
- NSSCallback *uhh
-);
+nssCRL_DeleteStoredObject(
+ NSSCRL *crl,
+ NSSCallback *uhh);
NSS_EXTERN NSSPrivateKey *
-nssPrivateKey_Create
-(
- nssPKIObject *o
-);
+nssPrivateKey_Create(nssPKIObject *o);
NSS_EXTERN NSSDER *
-nssCRL_GetEncoding
-(
- NSSCRL *crl
-);
+nssCRL_GetEncoding(NSSCRL *crl);
NSS_EXTERN NSSPublicKey *
-nssPublicKey_Create
-(
- nssPKIObject *object
-);
+nssPublicKey_Create(nssPKIObject *object);
/* nssCertificateArray
*
@@ -291,10 +226,7 @@ nssPublicKey_Create
* to call this method on an arena-allocated array.
*/
NSS_EXTERN void
-nssCertificateArray_Destroy
-(
- NSSCertificate **certs
-);
+nssCertificateArray_Destroy(NSSCertificate **certs);
/* nssCertificateArray_Join
*
@@ -305,25 +237,21 @@ nssCertificateArray_Destroy
* arena.
*/
NSS_EXTERN NSSCertificate **
-nssCertificateArray_Join
-(
- NSSCertificate **certs1,
- NSSCertificate **certs2
-);
+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
-);
+NSS_EXTERN NSSCertificate *
+nssCertificateArray_FindBestCertificate(
+ NSSCertificate **certs,
+ NSSTime *timeOpt,
+ const NSSUsage *usage,
+ NSSPolicies *policiesOpt);
/* nssCertificateArray_Traverse
*
@@ -331,24 +259,19 @@ nssCertificateArray_FindBestCertificate
* fails.
*/
NSS_EXTERN PRStatus
-nssCertificateArray_Traverse
-(
- NSSCertificate **certs,
- PRStatus (* callback)(NSSCertificate *c, void *arg),
- void *arg
-);
+nssCertificateArray_Traverse(
+ NSSCertificate **certs,
+ PRStatus (*callback)(NSSCertificate *c, void *arg),
+ void *arg);
NSS_EXTERN void
-nssCRLArray_Destroy
-(
- NSSCRL **crls
-);
+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
+ * objects instances on tokens, where the actual object hasn't
* been formed yet.
*
* nssCertificateCollection_Create
@@ -360,7 +283,7 @@ nssCRLArray_Destroy
* 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
+ * 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
@@ -383,11 +306,9 @@ nssCRLArray_Destroy
* Optionally provide a starting set of certs.
*/
NSS_EXTERN nssPKIObjectCollection *
-nssCertificateCollection_Create
-(
- NSSTrustDomain *td,
- NSSCertificate **certsOpt
-);
+nssCertificateCollection_Create(
+ NSSTrustDomain *td,
+ NSSCertificate **certsOpt);
/* nssCRLCollection_Create
*
@@ -395,11 +316,9 @@ nssCertificateCollection_Create
* Optionally provide a starting set of CRLs.
*/
NSS_EXTERN nssPKIObjectCollection *
-nssCRLCollection_Create
-(
- NSSTrustDomain *td,
- NSSCRL **crlsOpt
-);
+nssCRLCollection_Create(
+ NSSTrustDomain *td,
+ NSSCRL **crlsOpt);
/* nssPrivateKeyCollection_Create
*
@@ -407,11 +326,9 @@ nssCRLCollection_Create
* Optionally provide a starting set of keys.
*/
NSS_EXTERN nssPKIObjectCollection *
-nssPrivateKeyCollection_Create
-(
- NSSTrustDomain *td,
- NSSPrivateKey **pvkOpt
-);
+nssPrivateKeyCollection_Create(
+ NSSTrustDomain *td,
+ NSSPrivateKey **pvkOpt);
/* nssPublicKeyCollection_Create
*
@@ -419,34 +336,24 @@ nssPrivateKeyCollection_Create
* Optionally provide a starting set of keys.
*/
NSS_EXTERN nssPKIObjectCollection *
-nssPublicKeyCollection_Create
-(
- NSSTrustDomain *td,
- NSSPublicKey **pvkOpt
-);
+nssPublicKeyCollection_Create(
+ NSSTrustDomain *td,
+ NSSPublicKey **pvkOpt);
/* nssPKIObjectCollection_Destroy
*/
NSS_EXTERN void
-nssPKIObjectCollection_Destroy
-(
- nssPKIObjectCollection *collection
-);
+nssPKIObjectCollection_Destroy(nssPKIObjectCollection *collection);
/* nssPKIObjectCollection_Count
*/
NSS_EXTERN PRUint32
-nssPKIObjectCollection_Count
-(
- nssPKIObjectCollection *collection
-);
+nssPKIObjectCollection_Count(nssPKIObjectCollection *collection);
NSS_EXTERN PRStatus
-nssPKIObjectCollection_AddObject
-(
- nssPKIObjectCollection *collection,
- nssPKIObject *object
-);
+nssPKIObjectCollection_AddObject(
+ nssPKIObjectCollection *collection,
+ nssPKIObject *object);
/* nssPKIObjectCollection_AddInstances
*
@@ -460,21 +367,17 @@ nssPKIObjectCollection_AddObject
* numInstances = 0 means the array is NULL-terminated
*/
NSS_EXTERN PRStatus
-nssPKIObjectCollection_AddInstances
-(
- nssPKIObjectCollection *collection,
- nssCryptokiObject **instances,
- PRUint32 numInstances
-);
+nssPKIObjectCollection_AddInstances(
+ nssPKIObjectCollection *collection,
+ nssCryptokiObject **instances,
+ PRUint32 numInstances);
/* nssPKIObjectCollection_Traverse
*/
NSS_EXTERN PRStatus
-nssPKIObjectCollection_Traverse
-(
- nssPKIObjectCollection *collection,
- nssPKIObjectCallback *callback
-);
+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
@@ -482,213 +385,162 @@ nssPKIObjectCollection_Traverse
* a cert does not already exist.
*/
NSS_EXTERN PRStatus
-nssPKIObjectCollection_AddInstanceAsObject
-(
- nssPKIObjectCollection *collection,
- nssCryptokiObject *instance
-);
+nssPKIObjectCollection_AddInstanceAsObject(
+ nssPKIObjectCollection *collection,
+ nssCryptokiObject *instance);
/* nssPKIObjectCollection_GetCertificates
*
- * Get all of the certificates in the collection.
+ * Get all of the certificates in the collection.
*/
NSS_EXTERN NSSCertificate **
-nssPKIObjectCollection_GetCertificates
-(
- nssPKIObjectCollection *collection,
- NSSCertificate **rvOpt,
- PRUint32 maximumOpt,
- NSSArena *arenaOpt
-);
+nssPKIObjectCollection_GetCertificates(
+ nssPKIObjectCollection *collection,
+ NSSCertificate **rvOpt,
+ PRUint32 maximumOpt,
+ NSSArena *arenaOpt);
NSS_EXTERN NSSCRL **
-nssPKIObjectCollection_GetCRLs
-(
- nssPKIObjectCollection *collection,
- NSSCRL **rvOpt,
- PRUint32 maximumOpt,
- NSSArena *arenaOpt
-);
+nssPKIObjectCollection_GetCRLs(
+ nssPKIObjectCollection *collection,
+ NSSCRL **rvOpt,
+ PRUint32 maximumOpt,
+ NSSArena *arenaOpt);
NSS_EXTERN NSSPrivateKey **
-nssPKIObjectCollection_GetPrivateKeys
-(
- nssPKIObjectCollection *collection,
- NSSPrivateKey **rvOpt,
- PRUint32 maximumOpt,
- NSSArena *arenaOpt
-);
+nssPKIObjectCollection_GetPrivateKeys(
+ nssPKIObjectCollection *collection,
+ NSSPrivateKey **rvOpt,
+ PRUint32 maximumOpt,
+ NSSArena *arenaOpt);
NSS_EXTERN NSSPublicKey **
-nssPKIObjectCollection_GetPublicKeys
-(
- nssPKIObjectCollection *collection,
- NSSPublicKey **rvOpt,
- PRUint32 maximumOpt,
- NSSArena *arenaOpt
-);
+nssPKIObjectCollection_GetPublicKeys(
+ nssPKIObjectCollection *collection,
+ NSSPublicKey **rvOpt,
+ PRUint32 maximumOpt,
+ NSSArena *arenaOpt);
NSS_EXTERN NSSTime *
-NSSTime_Now
-(
- NSSTime *timeOpt
-);
+NSSTime_Now(NSSTime *timeOpt);
NSS_EXTERN NSSTime *
-NSSTime_SetPRTime
-(
- NSSTime *timeOpt,
- PRTime prTime
-);
+NSSTime_SetPRTime(
+ NSSTime *timeOpt,
+ PRTime prTime);
NSS_EXTERN PRTime
-NSSTime_GetPRTime
-(
- NSSTime *time
-);
+NSSTime_GetPRTime(
+ NSSTime *time);
NSS_EXTERN nssHash *
-nssHash_CreateCertificate
-(
- NSSArena *arenaOpt,
- PRUint32 numBuckets
-);
+nssHash_CreateCertificate(
+ NSSArena *arenaOpt,
+ PRUint32 numBuckets);
/* 3.4 Certificate cache routines */
NSS_EXTERN PRStatus
-nssTrustDomain_InitializeCache
-(
- NSSTrustDomain *td,
- PRUint32 cacheSize
-);
+nssTrustDomain_InitializeCache(
+ NSSTrustDomain *td,
+ PRUint32 cacheSize);
NSS_EXTERN PRStatus
-nssTrustDomain_AddCertsToCache
-(
- NSSTrustDomain *td,
- NSSCertificate **certs,
- PRUint32 numCerts
-);
+nssTrustDomain_AddCertsToCache(
+ NSSTrustDomain *td,
+ NSSCertificate **certs,
+ PRUint32 numCerts);
NSS_EXTERN void
-nssTrustDomain_RemoveCertFromCacheLOCKED (
- NSSTrustDomain *td,
- NSSCertificate *cert
-);
+nssTrustDomain_RemoveCertFromCacheLOCKED(
+ NSSTrustDomain *td,
+ NSSCertificate *cert);
NSS_EXTERN void
-nssTrustDomain_LockCertCache (
- NSSTrustDomain *td
-);
+nssTrustDomain_LockCertCache(NSSTrustDomain *td);
NSS_EXTERN void
-nssTrustDomain_UnlockCertCache (
- NSSTrustDomain *td
-);
+nssTrustDomain_UnlockCertCache(NSSTrustDomain *td);
NSS_IMPLEMENT PRStatus
-nssTrustDomain_DestroyCache
-(
- NSSTrustDomain *td
-);
+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
-);
+nssTrustDomain_RemoveTokenCertsFromCache(
+ NSSTrustDomain *td,
+ NSSToken *token);
NSS_EXTERN PRStatus
-nssTrustDomain_UpdateCachedTokenCerts
-(
- NSSTrustDomain *td,
- NSSToken *token
-);
+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
-);
+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
-);
+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
-);
+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
-);
+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
-);
+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
-);
+nssTrustDomain_GetCertsFromCache(
+ NSSTrustDomain *td,
+ nssList *certListOpt);
NSS_EXTERN void
-nssTrustDomain_DumpCacheInfo
-(
- NSSTrustDomain *td,
- void (* cert_dump_iter)(const void *, void *, void *),
- void *arg
-);
+nssTrustDomain_DumpCacheInfo(
+ NSSTrustDomain *td,
+ void (*cert_dump_iter)(const void *, void *, void *),
+ void *arg);
NSS_EXTERN void
-nssCertificateList_AddReferences
-(
- nssList *certList
-);
+nssCertificateList_AddReferences(
+ nssList *certList);
PR_END_EXTERN_C
diff --git a/nss/lib/pki/pkistore.c b/nss/lib/pki/pkistore.c
index 15bb658..6113442 100644
--- a/nss/lib/pki/pkistore.c
+++ b/nss/lib/pki/pkistore.c
@@ -27,7 +27,7 @@
#include "prbit.h"
-/*
+/*
* Certificate Store
*
* This differs from the cache in that it is a true storage facility. Items
@@ -36,8 +36,7 @@
*
*/
-struct nssCertificateStoreStr
-{
+struct nssCertificateStoreStr {
PRBool i_alloced_arena;
NSSArena *arena;
PZLock *lock;
@@ -47,8 +46,7 @@ struct nssCertificateStoreStr
typedef struct certificate_hash_entry_str certificate_hash_entry;
-struct certificate_hash_entry_str
-{
+struct certificate_hash_entry_str {
NSSCertificate *cert;
NSSTrust *trust;
nssSMIMEProfile *profile;
@@ -56,65 +54,62 @@ struct certificate_hash_entry_str
/* forward static declarations */
static NSSCertificate *
-nssCertStore_FindCertByIssuerAndSerialNumberLocked (
- nssCertificateStore *store,
- NSSDER *issuer,
- NSSDER *serial
-);
+nssCertStore_FindCertByIssuerAndSerialNumberLocked(
+ nssCertificateStore *store,
+ NSSDER *issuer,
+ NSSDER *serial);
NSS_IMPLEMENT nssCertificateStore *
-nssCertificateStore_Create (
- NSSArena *arenaOpt
-)
+nssCertificateStore_Create(NSSArena *arenaOpt)
{
NSSArena *arena;
nssCertificateStore *store;
PRBool i_alloced_arena;
if (arenaOpt) {
- arena = arenaOpt;
- i_alloced_arena = PR_FALSE;
+ arena = arenaOpt;
+ i_alloced_arena = PR_FALSE;
} else {
- arena = nssArena_Create();
- if (!arena) {
- return NULL;
- }
- i_alloced_arena = PR_TRUE;
+ arena = nssArena_Create();
+ if (!arena) {
+ return NULL;
+ }
+ i_alloced_arena = PR_TRUE;
}
store = nss_ZNEW(arena, nssCertificateStore);
if (!store) {
- goto loser;
+ goto loser;
}
store->lock = PZ_NewLock(nssILockOther);
if (!store->lock) {
- goto loser;
+ 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;
+ goto loser;
}
/* Create the subject DER --> subject list hash */
store->subject = nssHash_CreateItem(arena, 0);
if (!store->subject) {
- goto loser;
+ 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 (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);
+ nssArena_Destroy(arena);
}
return NULL;
}
@@ -122,189 +117,176 @@ loser:
extern const NSSError NSS_ERROR_BUSY;
NSS_IMPLEMENT PRStatus
-nssCertificateStore_Destroy (
- nssCertificateStore *store
-)
+nssCertificateStore_Destroy(nssCertificateStore *store)
{
if (nssHash_Count(store->issuer_and_serial) > 0) {
- nss_SetError(NSS_ERROR_BUSY);
- return PR_FAILURE;
+ 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);
+ nssArena_Destroy(store->arena);
} else {
- nss_ZFreeIf(store);
+ nss_ZFreeIf(store);
}
return PR_SUCCESS;
}
static PRStatus
-add_certificate_entry (
- nssCertificateStore *store,
- NSSCertificate *cert
-)
+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;
+ return PR_FAILURE;
}
entry->cert = cert;
nssrv = nssHash_Add(store->issuer_and_serial, cert, entry);
if (nssrv != PR_SUCCESS) {
- nss_ZFreeIf(entry);
+ nss_ZFreeIf(entry);
}
return nssrv;
}
static PRStatus
-add_subject_entry (
- nssCertificateStore *store,
- NSSCertificate *cert
-)
+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);
+ /* 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);
+ /* 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
-);
+remove_certificate_entry(
+ nssCertificateStore *store,
+ NSSCertificate *cert);
/* Caller must hold store->lock */
static PRStatus
-nssCertificateStore_AddLocked (
- nssCertificateStore *store,
- NSSCertificate *cert
-)
+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);
- }
+ 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
-)
+nssCertificateStore_FindOrAdd(
+ nssCertificateStore *store,
+ NSSCertificate *c)
{
PRStatus nssrv;
NSSCertificate *rvCert = NULL;
PZ_Lock(store->lock);
rvCert = nssCertStore_FindCertByIssuerAndSerialNumberLocked(
- store, &c->issuer, &c->serial);
+ store, &c->issuer, &c->serial);
if (!rvCert) {
- nssrv = nssCertificateStore_AddLocked(store, c);
- if (PR_SUCCESS == nssrv) {
- rvCert = nssCertificate_AddRef(c);
- }
+ 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
-)
+remove_certificate_entry(
+ nssCertificateStore *store,
+ NSSCertificate *cert)
{
certificate_hash_entry *entry;
entry = (certificate_hash_entry *)
- nssHash_Lookup(store->issuer_and_serial, cert);
+ 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);
+ 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
-)
+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);
- }
+ /* 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
-)
+nssCertificateStore_RemoveCertLOCKED(
+ nssCertificateStore *store,
+ NSSCertificate *cert)
{
certificate_hash_entry *entry;
entry = (certificate_hash_entry *)
- nssHash_Lookup(store->issuer_and_serial, cert);
+ nssHash_Lookup(store->issuer_and_serial, cert);
if (entry && entry->cert == cert) {
- remove_certificate_entry(store, cert);
- remove_subject_entry(store, cert);
+ remove_certificate_entry(store, cert);
+ remove_subject_entry(store, cert);
}
}
NSS_IMPLEMENT void
-nssCertificateStore_Lock (
- nssCertificateStore *store, nssCertificateStoreTrace* out
-)
+nssCertificateStore_Lock(nssCertificateStore *store, nssCertificateStoreTrace *out)
{
#ifdef DEBUG
PORT_Assert(out);
@@ -318,10 +300,9 @@ nssCertificateStore_Lock (
}
NSS_IMPLEMENT void
-nssCertificateStore_Unlock (
- nssCertificateStore *store, const nssCertificateStoreTrace* in,
- nssCertificateStoreTrace* out
-)
+nssCertificateStore_Unlock(
+ nssCertificateStore *store, const nssCertificateStoreTrace *in,
+ nssCertificateStoreTrace *out)
{
#ifdef DEBUG
PORT_Assert(in);
@@ -343,50 +324,48 @@ nssCertificateStore_Unlock (
}
static NSSCertificate **
-get_array_from_list (
- nssList *certList,
- NSSCertificate *rvOpt[],
- PRUint32 maximumOpt,
- NSSArena *arenaOpt
-)
+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;
+ return NULL;
}
if (maximumOpt > 0) {
- count = PR_MIN(maximumOpt, count);
+ count = PR_MIN(maximumOpt, count);
}
if (rvOpt) {
- nssList_GetArray(certList, (void **)rvOpt, count);
+ nssList_GetArray(certList, (void **)rvOpt, count);
} else {
- rvArray = nss_ZNEWARRAY(arenaOpt, NSSCertificate *, count + 1);
- if (rvArray) {
- nssList_GetArray(certList, (void **)rvArray, count);
- }
+ 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
-)
+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);
+ nssCertificateList_AddReferences(subjectList);
+ rvArray = get_array_from_list(subjectList,
+ rvOpt, maximumOpt, arenaOpt);
}
PZ_Unlock(store->lock);
return rvArray;
@@ -394,7 +373,7 @@ nssCertificateStore_FindCertificatesBySubject (
/* 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
+ * 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.
*
@@ -403,13 +382,13 @@ nssCertificateStore_FindCertificatesBySubject (
* because the only crypto context is global and persistent.
*/
-struct nickname_template_str
-{
+struct nickname_template_str {
NSSUTF8 *nickname;
nssList *subjectList;
};
-static void match_nickname(const void *k, void *v, void *a)
+static void
+match_nickname(const void *k, void *v, void *a)
{
PRStatus nssrv;
NSSCertificate *c;
@@ -419,9 +398,8 @@ static void match_nickname(const void *k, void *v, void *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;
+ nssUTF8_Equal(nickname, nt->nickname, &nssrv)) {
+ nt->subjectList = subjectList;
}
nss_ZFreeIf(nickname);
}
@@ -430,56 +408,53 @@ static void match_nickname(const void *k, void *v, void *a)
* Find all cached certs with this label.
*/
NSS_IMPLEMENT NSSCertificate **
-nssCertificateStore_FindCertificatesByNickname (
- nssCertificateStore *store,
- const NSSUTF8 *nickname,
- NSSCertificate *rvOpt[],
- PRUint32 maximumOpt,
- NSSArena *arenaOpt
-)
+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.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);
+ nssCertificateList_AddReferences(nt.subjectList);
+ rvArray = get_array_from_list(nt.subjectList,
+ rvOpt, maximumOpt, arenaOpt);
}
PZ_Unlock(store->lock);
return rvArray;
}
-struct email_template_str
-{
+struct email_template_str {
NSSASCII7 *email;
nssList *emailList;
};
-static void match_email(const void *k, void *v, void *a)
+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);
- }
+ 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);
+ }
}
}
@@ -487,43 +462,41 @@ static void match_email(const void *k, void *v, void *a)
* Find all cached certs with this email address.
*/
NSS_IMPLEMENT NSSCertificate **
-nssCertificateStore_FindCertificatesByEmail (
- nssCertificateStore *store,
- NSSASCII7 *email,
- NSSCertificate *rvOpt[],
- PRUint32 maximumOpt,
- NSSArena *arenaOpt
-)
+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;
+ 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);
+ /* 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);
+ 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
-)
+nssCertStore_FindCertByIssuerAndSerialNumberLocked(
+ nssCertificateStore *store,
+ NSSDER *issuer,
+ NSSDER *serial)
{
certificate_hash_entry *entry;
NSSCertificate *rvCert = NULL;
@@ -532,127 +505,121 @@ nssCertStore_FindCertByIssuerAndSerialNumberLocked (
index.issuer = *issuer;
index.serial = *serial;
entry = (certificate_hash_entry *)
- nssHash_Lookup(store->issuer_and_serial, &index);
+ nssHash_Lookup(store->issuer_and_serial, &index);
if (entry) {
- rvCert = nssCertificate_AddRef(entry->cert);
+ rvCert = nssCertificate_AddRef(entry->cert);
}
return rvCert;
}
NSS_IMPLEMENT NSSCertificate *
-nssCertificateStore_FindCertificateByIssuerAndSerialNumber (
- nssCertificateStore *store,
- NSSDER *issuer,
- NSSDER *serial
-)
+nssCertificateStore_FindCertificateByIssuerAndSerialNumber(
+ nssCertificateStore *store,
+ NSSDER *issuer,
+ NSSDER *serial)
{
NSSCertificate *rvCert = NULL;
PZ_Lock(store->lock);
- rvCert = nssCertStore_FindCertByIssuerAndSerialNumberLocked (
- store, issuer, serial);
+ rvCert = nssCertStore_FindCertByIssuerAndSerialNumberLocked(
+ store, issuer, serial);
PZ_Unlock(store->lock);
return rvCert;
}
NSS_IMPLEMENT NSSCertificate *
-nssCertificateStore_FindCertificateByEncodedCertificate (
- nssCertificateStore *store,
- NSSDER *encoding
-)
+nssCertificateStore_FindCertificateByEncodedCertificate(
+ nssCertificateStore *store,
+ NSSDER *encoding)
{
PRStatus nssrv = PR_FAILURE;
NSSDER issuer, serial;
NSSCertificate *rvCert = NULL;
nssrv = nssPKIX509_GetIssuerAndSerialFromDER(encoding, &issuer, &serial);
if (nssrv != PR_SUCCESS) {
- return NULL;
+ return NULL;
}
- rvCert = nssCertificateStore_FindCertificateByIssuerAndSerialNumber(store,
- &issuer,
- &serial);
+ 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
-)
+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);
+ nssHash_Lookup(store->issuer_and_serial, cert);
if (entry) {
- NSSTrust* newTrust = nssTrust_AddRef(trust);
- if (entry->trust) {
- nssTrust_Destroy(entry->trust);
- }
- entry->trust = newTrust;
+ 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
-)
+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);
+ nssHash_Lookup(store->issuer_and_serial, cert);
if (entry && entry->trust) {
- rvTrust = nssTrust_AddRef(entry->trust);
+ rvTrust = nssTrust_AddRef(entry->trust);
}
PZ_Unlock(store->lock);
return rvTrust;
}
NSS_EXTERN PRStatus
-nssCertificateStore_AddSMIMEProfile (
- nssCertificateStore *store,
- nssSMIMEProfile *profile
-)
+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);
+ nssHash_Lookup(store->issuer_and_serial, cert);
if (entry) {
- nssSMIMEProfile* newProfile = nssSMIMEProfile_AddRef(profile);
- if (entry->profile) {
- nssSMIMEProfile_Destroy(entry->profile);
- }
- entry->profile = newProfile;
+ 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
-)
+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);
+ nssHash_Lookup(store->issuer_and_serial, cert);
if (entry && entry->profile) {
- rvProfile = nssSMIMEProfile_AddRef(entry->profile);
+ rvProfile = nssSMIMEProfile_AddRef(entry->profile);
}
PZ_Unlock(store->lock);
return rvProfile;
@@ -661,18 +628,16 @@ nssCertificateStore_FindSMIMEProfileForCertificate (
/* XXX this is also used by cache and should be somewhere else */
static PLHashNumber
-nss_certificate_hash (
- const void *key
-)
+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];
+ 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;
}
@@ -687,27 +652,24 @@ nss_compare_certs(const void *v1, const void *v2)
}
NSS_IMPLEMENT nssHash *
-nssHash_CreateCertificate (
- NSSArena *arenaOpt,
- PRUint32 numBuckets
-)
-{
- return nssHash_Create(arenaOpt,
- numBuckets,
- nss_certificate_hash,
- nss_compare_certs,
+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
-)
+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/nss/lib/pki/pkistore.h b/nss/lib/pki/pkistore.h
index d9d8944..729f209 100644
--- a/nss/lib/pki/pkistore.h
+++ b/nss/lib/pki/pkistore.h
@@ -15,7 +15,7 @@
PR_BEGIN_EXTERN_C
-/*
+/*
* PKI Stores
*
* This is a set of routines for managing local stores of PKI objects.
@@ -24,7 +24,7 @@ PR_BEGIN_EXTERN_C
* here for storing local references to keys.
*/
-/*
+/*
* nssCertificateStore
*
* Manages local store of certificate, trust, and S/MIME profile objects.
@@ -34,37 +34,29 @@ PR_BEGIN_EXTERN_C
*/
NSS_EXTERN nssCertificateStore *
-nssCertificateStore_Create
-(
- NSSArena *arenaOpt
-);
+nssCertificateStore_Create(
+ NSSArena *arenaOpt);
NSS_EXTERN PRStatus
-nssCertificateStore_Destroy
-(
- nssCertificateStore *store
-);
+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
-);
+nssCertificateStore_FindOrAdd(
+ nssCertificateStore *store,
+ NSSCertificate *c);
NSS_EXTERN void
-nssCertificateStore_RemoveCertLOCKED
-(
- nssCertificateStore *store,
- NSSCertificate *cert
-);
+nssCertificateStore_RemoveCertLOCKED(
+ nssCertificateStore *store,
+ NSSCertificate *cert);
struct nssCertificateStoreTraceStr {
- nssCertificateStore* store;
- PZLock* lock;
+ nssCertificateStore *store;
+ PZLock *lock;
PRBool locked;
PRBool unlocked;
};
@@ -72,96 +64,74 @@ struct nssCertificateStoreTraceStr {
typedef struct nssCertificateStoreTraceStr nssCertificateStoreTrace;
NSS_EXTERN void
-nssCertificateStore_Lock (
- nssCertificateStore *store, nssCertificateStoreTrace* out
-);
+nssCertificateStore_Lock(
+ nssCertificateStore *store, nssCertificateStoreTrace *out);
NSS_EXTERN void
-nssCertificateStore_Unlock (
- nssCertificateStore *store, const nssCertificateStoreTrace* in,
- nssCertificateStoreTrace* out
-);
+nssCertificateStore_Unlock(
+ nssCertificateStore *store, const nssCertificateStoreTrace *in,
+ nssCertificateStoreTrace *out);
NSS_EXTERN NSSCertificate **
-nssCertificateStore_FindCertificatesBySubject
-(
- nssCertificateStore *store,
- NSSDER *subject,
- NSSCertificate *rvOpt[],
- PRUint32 maximumOpt,
- NSSArena *arenaOpt
-);
+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
-);
+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
-);
+nssCertificateStore_FindCertificatesByEmail(
+ nssCertificateStore *store,
+ NSSASCII7 *email,
+ NSSCertificate *rvOpt[],
+ PRUint32 maximumOpt,
+ NSSArena *arenaOpt);
NSS_EXTERN NSSCertificate *
-nssCertificateStore_FindCertificateByIssuerAndSerialNumber
-(
- nssCertificateStore *store,
- NSSDER *issuer,
- NSSDER *serial
-);
+nssCertificateStore_FindCertificateByIssuerAndSerialNumber(
+ nssCertificateStore *store,
+ NSSDER *issuer,
+ NSSDER *serial);
NSS_EXTERN NSSCertificate *
-nssCertificateStore_FindCertificateByEncodedCertificate
-(
- nssCertificateStore *store,
- NSSDER *encoding
-);
+nssCertificateStore_FindCertificateByEncodedCertificate(
+ nssCertificateStore *store,
+ NSSDER *encoding);
NSS_EXTERN PRStatus
-nssCertificateStore_AddTrust
-(
- nssCertificateStore *store,
- NSSTrust *trust
-);
+nssCertificateStore_AddTrust(
+ nssCertificateStore *store,
+ NSSTrust *trust);
NSS_EXTERN NSSTrust *
-nssCertificateStore_FindTrustForCertificate
-(
- nssCertificateStore *store,
- NSSCertificate *cert
-);
+nssCertificateStore_FindTrustForCertificate(
+ nssCertificateStore *store,
+ NSSCertificate *cert);
NSS_EXTERN PRStatus
-nssCertificateStore_AddSMIMEProfile
-(
- nssCertificateStore *store,
- nssSMIMEProfile *profile
-);
+nssCertificateStore_AddSMIMEProfile(
+ nssCertificateStore *store,
+ nssSMIMEProfile *profile);
NSS_EXTERN nssSMIMEProfile *
-nssCertificateStore_FindSMIMEProfileForCertificate
-(
- nssCertificateStore *store,
- NSSCertificate *cert
-);
+nssCertificateStore_FindSMIMEProfileForCertificate(
+ nssCertificateStore *store,
+ NSSCertificate *cert);
NSS_EXTERN void
-nssCertificateStore_DumpStoreInfo
-(
- nssCertificateStore *store,
- void (* cert_dump_iter)(const void *, void *, void *),
- void *arg
-);
+nssCertificateStore_DumpStoreInfo(
+ nssCertificateStore *store,
+ void (*cert_dump_iter)(const void *, void *, void *),
+ void *arg);
PR_END_EXTERN_C
diff --git a/nss/lib/pki/pkit.h b/nss/lib/pki/pkit.h
index 5855dd2..5d17a45 100644
--- a/nss/lib/pki/pkit.h
+++ b/nss/lib/pki/pkit.h
@@ -45,7 +45,7 @@ PR_BEGIN_EXTERN_C
*
* 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
+ * 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
@@ -65,15 +65,14 @@ typedef enum {
* This is the base object class, common to all PKI objects defined in
* nsspkit.h
*/
-struct nssPKIObjectStr
-{
+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;
+ PZLock *lock;
PZMonitor *mlock;
} sync;
nssPKILockType lockType;
@@ -100,8 +99,7 @@ typedef struct nssSMIMEProfileStr nssSMIMEProfile;
typedef struct nssPKIObjectStr nssPKIObject;
-struct NSSTrustStr
-{
+struct NSSTrustStr {
nssPKIObject object;
NSSCertificate *certificate;
nssTrustLevel serverAuth;
@@ -111,8 +109,7 @@ struct NSSTrustStr
PRBool stepUpApproved;
};
-struct nssSMIMEProfileStr
-{
+struct nssSMIMEProfileStr {
nssPKIObject object;
NSSCertificate *certificate;
NSSASCII7 *email;
@@ -121,8 +118,7 @@ struct nssSMIMEProfileStr
NSSItem *profileData;
};
-struct NSSCertificateStr
-{
+struct NSSCertificateStr {
nssPKIObject object;
NSSCertificateType type;
NSSItem id;
@@ -154,8 +150,7 @@ struct NSSTrustDomainStr {
CERTStatusConfig *statusConfig;
};
-struct NSSCryptoContextStr
-{
+struct NSSCryptoContextStr {
PRInt32 refCount;
NSSArena *arena;
NSSTrustDomain *td;
@@ -169,10 +164,10 @@ struct NSSTimeStr {
};
struct NSSCRLStr {
- nssPKIObject object;
- NSSDER encoding;
- NSSUTF8 *url;
- PRBool isKRL;
+ nssPKIObject object;
+ NSSDER encoding;
+ NSSUTF8 *url;
+ PRBool isKRL;
};
typedef struct NSSCRLStr NSSCRL;
diff --git a/nss/lib/pki/pkitm.h b/nss/lib/pki/pkitm.h
index 76e2c66..38a5fac 100644
--- a/nss/lib/pki/pkitm.h
+++ b/nss/lib/pki/pkitm.h
@@ -22,9 +22,9 @@
PR_BEGIN_EXTERN_C
typedef enum nssCertIDMatchEnum {
- nssCertIDMatch_Yes = 0,
- nssCertIDMatch_No = 1,
- nssCertIDMatch_Unknown = 2
+ nssCertIDMatch_Yes = 0,
+ nssCertIDMatch_No = 1,
+ nssCertIDMatch_Unknown = 2
} nssCertIDMatch;
/*
@@ -39,29 +39,29 @@ struct nssDecodedCertStr {
NSSCertificateType type;
void *data;
/* returns the unique identifier for the cert */
- NSSItem * (*getIdentifier)(nssDecodedCert *dc);
+ NSSItem *(*getIdentifier)(nssDecodedCert *dc);
/* returns the unique identifier for this cert's issuer */
- void * (*getIssuerIdentifier)(nssDecodedCert *dc);
+ 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);
+ PRBool (*isValidIssuer)(nssDecodedCert *dc);
/* returns the cert usage */
- NSSUsage * (*getUsage)(nssDecodedCert *dc);
+ NSSUsage *(*getUsage)(nssDecodedCert *dc);
/* is time within the validity period of the cert? */
- PRBool (*isValidAtTime)(nssDecodedCert *dc, NSSTime *time);
+ PRBool (*isValidAtTime)(nssDecodedCert *dc, NSSTime *time);
/* is the validity period of this cert newer than cmpdc? */
- PRBool (*isNewerThan)(nssDecodedCert *dc, nssDecodedCert *cmpdc);
+ PRBool (*isNewerThan)(nssDecodedCert *dc, nssDecodedCert *cmpdc);
/* does the usage for this cert match the requested usage? */
- PRBool (*matchUsage)(nssDecodedCert *dc, const NSSUsage *usage);
+ PRBool (*matchUsage)(nssDecodedCert *dc, const NSSUsage *usage);
/* is this cert trusted for the requested usage? */
- PRBool (*isTrustedForUsage)(nssDecodedCert *dc,
- const NSSUsage *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);
+ PRStatus (*getDERSerialNumber)(nssDecodedCert *dc,
+ NSSDER *derSerial, NSSArena *arena);
};
struct NSSUsageStr {
@@ -74,13 +74,13 @@ 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;
+ 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
diff --git a/nss/lib/pki/symmkey.c b/nss/lib/pki/symmkey.c
index 60ed47a..3103f20 100644
--- a/nss/lib/pki/symmkey.c
+++ b/nss/lib/pki/symmkey.c
@@ -9,256 +9,230 @@
extern const NSSError NSS_ERROR_NOT_FOUND;
NSS_IMPLEMENT PRStatus
-NSSSymmetricKey_Destroy (
- NSSSymmetricKey *mk
-)
+NSSSymmetricKey_Destroy(NSSSymmetricKey *mk)
{
nss_SetError(NSS_ERROR_NOT_FOUND);
return PR_FAILURE;
}
NSS_IMPLEMENT PRStatus
-NSSSymmetricKey_DeleteStoredObject (
- NSSSymmetricKey *mk,
- NSSCallback *uhh
-)
+NSSSymmetricKey_DeleteStoredObject(
+ NSSSymmetricKey *mk,
+ NSSCallback *uhh)
{
nss_SetError(NSS_ERROR_NOT_FOUND);
return PR_FAILURE;
}
NSS_IMPLEMENT PRUint32
-NSSSymmetricKey_GetKeyLength (
- NSSSymmetricKey *mk
-)
+NSSSymmetricKey_GetKeyLength(NSSSymmetricKey *mk)
{
nss_SetError(NSS_ERROR_NOT_FOUND);
return -1;
}
NSS_IMPLEMENT PRUint32
-NSSSymmetricKey_GetKeyStrength (
- NSSSymmetricKey *mk
-)
+NSSSymmetricKey_GetKeyStrength(NSSSymmetricKey *mk)
{
nss_SetError(NSS_ERROR_NOT_FOUND);
return -1;
}
NSS_IMPLEMENT PRStatus
-NSSSymmetricKey_IsStillPresent (
- NSSSymmetricKey *mk
-)
+NSSSymmetricKey_IsStillPresent(NSSSymmetricKey *mk)
{
nss_SetError(NSS_ERROR_NOT_FOUND);
return PR_FAILURE;
}
NSS_IMPLEMENT NSSTrustDomain *
-NSSSymmetricKey_GetTrustDomain (
- NSSSymmetricKey *mk,
- PRStatus *statusOpt
-)
+NSSSymmetricKey_GetTrustDomain(
+ NSSSymmetricKey *mk,
+ PRStatus *statusOpt)
{
nss_SetError(NSS_ERROR_NOT_FOUND);
return NULL;
}
NSS_IMPLEMENT NSSToken *
-NSSSymmetricKey_GetToken (
- NSSSymmetricKey *mk,
- PRStatus *statusOpt
-)
+NSSSymmetricKey_GetToken(
+ NSSSymmetricKey *mk,
+ PRStatus *statusOpt)
{
nss_SetError(NSS_ERROR_NOT_FOUND);
return NULL;
}
NSS_IMPLEMENT NSSSlot *
-NSSSymmetricKey_GetSlot (
- NSSSymmetricKey *mk,
- PRStatus *statusOpt
-)
+NSSSymmetricKey_GetSlot(
+ NSSSymmetricKey *mk,
+ PRStatus *statusOpt)
{
nss_SetError(NSS_ERROR_NOT_FOUND);
return NULL;
}
NSS_IMPLEMENT NSSModule *
-NSSSymmetricKey_GetModule (
- NSSSymmetricKey *mk,
- PRStatus *statusOpt
-)
+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
-)
+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
-)
+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
-)
+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
-)
+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
-)
+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
-)
+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
-)
+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
-)
+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
-)
+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
-)
+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
-)
+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
-)
+NSSSymmetricKey_CreateCryptoContext(
+ NSSSymmetricKey *mk,
+ NSSAlgorithmAndParameters *apOpt,
+ NSSCallback *uhh)
{
nss_SetError(NSS_ERROR_NOT_FOUND);
return NULL;
}
-
diff --git a/nss/lib/pki/tdcache.c b/nss/lib/pki/tdcache.c
index 5f9dfdd..385b8e4 100644
--- a/nss/lib/pki/tdcache.c
+++ b/nss/lib/pki/tdcache.c
@@ -35,29 +35,31 @@ static PRLogModuleInfo *s_log = NULL;
#endif
#ifdef DEBUG_CACHE
-static void log_item_dump(const char *msg, NSSItem *it)
+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]);
+ 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]);
- }
+ 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)
+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));
+ (c->nickname) ? c->nickname : c->email));
log_item_dump("\tserial", &c->serial);
log_item_dump("\tsubject", &c->subject);
}
@@ -71,8 +73,7 @@ static void log_cert_ref(const char *msg, NSSCertificate *c)
*/
/* should it live in its own arena? */
-struct nssTDCertificateCacheStr
-{
+struct nssTDCertificateCacheStr {
PZLock *lock;
NSSArena *arena;
nssHash *issuerAndSN;
@@ -81,12 +82,11 @@ struct nssTDCertificateCacheStr
nssHash *email;
};
-struct cache_entry_str
-{
+struct cache_entry_str {
union {
- NSSCertificate *cert;
- nssList *list;
- void *value;
+ NSSCertificate *cert;
+ nssList *list;
+ void *value;
} entry;
PRUint32 hits;
PRTime lastHit;
@@ -101,13 +101,13 @@ 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;
+ ce->entry.value = value;
+ ce->hits = 1;
+ ce->lastHit = PR_Now();
+ if (ownArena) {
+ ce->arena = arena;
+ }
+ ce->nickname = NULL;
}
return ce;
}
@@ -116,10 +116,9 @@ new_cache_entry(NSSArena *arena, void *value, PRBool ownArena)
* types/functions static
*/
NSS_IMPLEMENT PRStatus
-nssTrustDomain_InitializeCache (
- NSSTrustDomain *td,
- PRUint32 cacheSize
-)
+nssTrustDomain_InitializeCache(
+ NSSTrustDomain *td,
+ PRUint32 cacheSize)
{
NSSArena *arena;
nssTDCertificateCache *cache = td->cache;
@@ -130,37 +129,37 @@ nssTrustDomain_InitializeCache (
PR_ASSERT(!cache);
arena = nssArena_Create();
if (!arena) {
- return PR_FAILURE;
+ return PR_FAILURE;
}
cache = nss_ZNEW(arena, nssTDCertificateCache);
if (!cache) {
- nssArena_Destroy(arena);
- return PR_FAILURE;
+ nssArena_Destroy(arena);
+ return PR_FAILURE;
}
cache->lock = PZ_NewLock(nssILockCache);
if (!cache->lock) {
- nssArena_Destroy(arena);
- return PR_FAILURE;
+ 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;
+ goto loser;
}
/* Create the subject DER --> subject list hash */
cache->subject = nssHash_CreateItem(arena, cacheSize);
if (!cache->subject) {
- goto loser;
+ goto loser;
}
/* Create the nickname --> subject list hash */
cache->nickname = nssHash_CreateString(arena, cacheSize);
if (!cache->nickname) {
- goto loser;
+ goto loser;
}
/* Create the email --> list of subject lists hash */
cache->email = nssHash_CreateString(arena, cacheSize);
if (!cache->email) {
- goto loser;
+ goto loser;
}
cache->arena = arena;
td->cache = cache;
@@ -189,17 +188,15 @@ extern const NSSError NSS_ERROR_INTERNAL_ERROR;
extern const NSSError NSS_ERROR_BUSY;
NSS_IMPLEMENT PRStatus
-nssTrustDomain_DestroyCache (
- NSSTrustDomain *td
-)
+nssTrustDomain_DestroyCache(NSSTrustDomain *td)
{
if (!td->cache) {
- nss_SetError(NSS_ERROR_INTERNAL_ERROR);
- return PR_FAILURE;
+ nss_SetError(NSS_ERROR_INTERNAL_ERROR);
+ return PR_FAILURE;
}
if (nssHash_Count(td->cache->issuerAndSN) > 0) {
- nss_SetError(NSS_ERROR_BUSY);
- return PR_FAILURE;
+ nss_SetError(NSS_ERROR_BUSY);
+ return PR_FAILURE;
}
PZ_DestroyLock(td->cache->lock);
nssHash_Destroy(td->cache->issuerAndSN);
@@ -215,10 +212,9 @@ nssTrustDomain_DestroyCache (
}
static PRStatus
-remove_issuer_and_serial_entry (
- nssTDCertificateCache *cache,
- NSSCertificate *cert
-)
+remove_issuer_and_serial_entry(
+ nssTDCertificateCache *cache,
+ NSSCertificate *cert)
{
/* Remove the cert from the issuer/serial hash */
nssHash_Remove(cache->issuerAndSN, cert);
@@ -229,13 +225,12 @@ remove_issuer_and_serial_entry (
}
static PRStatus
-remove_subject_entry (
- nssTDCertificateCache *cache,
- NSSCertificate *cert,
- nssList **subjectList,
- NSSUTF8 **nickname,
- NSSArena **arena
-)
+remove_subject_entry(
+ nssTDCertificateCache *cache,
+ NSSCertificate *cert,
+ nssList **subjectList,
+ NSSUTF8 **nickname,
+ NSSArena **arena)
{
PRStatus nssrv;
cache_entry *ce;
@@ -244,87 +239,86 @@ remove_subject_entry (
/* 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;
+ /* 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);
+ log_cert_ref("removed cert", cert);
+ log_item_dump("from subject list", &cert->subject);
#endif
} else {
- nssrv = PR_FAILURE;
+ nssrv = PR_FAILURE;
}
return nssrv;
}
static PRStatus
-remove_nickname_entry (
- nssTDCertificateCache *cache,
- NSSUTF8 *nickname,
- nssList *subjectList
-)
+remove_nickname_entry(
+ nssTDCertificateCache *cache,
+ NSSUTF8 *nickname,
+ nssList *subjectList)
{
PRStatus nssrv;
if (nickname) {
- nssHash_Remove(cache->nickname, nickname);
- nssrv = PR_SUCCESS;
+ nssHash_Remove(cache->nickname, nickname);
+ nssrv = PR_SUCCESS;
#ifdef DEBUG_CACHE
- PR_LOG(s_log, PR_LOG_DEBUG, ("removed nickname %s", nickname));
+ PR_LOG(s_log, PR_LOG_DEBUG, ("removed nickname %s", nickname));
#endif
} else {
- nssrv = PR_FAILURE;
+ nssrv = PR_FAILURE;
}
return nssrv;
}
static PRStatus
-remove_email_entry (
- nssTDCertificateCache *cache,
- NSSCertificate *cert,
- nssList *subjectList
-)
+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);
+ ce = (cache_entry *)nssHash_Lookup(cache->email, cert->email);
+ if (ce) {
+ nssList *subjects = ce->entry.list;
+ /* Remove the subject list from the email hash */
+ if (subjects) {
+ 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));
+ 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);
+ 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));
+ PR_LOG(s_log, PR_LOG_DEBUG, ("removed email %s", cert->email));
#endif
- }
- nssrv = PR_SUCCESS;
- }
+ }
+ }
+ nssrv = PR_SUCCESS;
+ }
}
return nssrv;
}
NSS_IMPLEMENT void
-nssTrustDomain_RemoveCertFromCacheLOCKED (
- NSSTrustDomain *td,
- NSSCertificate *cert
-)
+nssTrustDomain_RemoveCertFromCacheLOCKED(
+ NSSTrustDomain *td,
+ NSSCertificate *cert)
{
nssList *subjectList;
cache_entry *ce;
@@ -336,43 +330,39 @@ nssTrustDomain_RemoveCertFromCacheLOCKED (
#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
- */
+/* 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"));
+ PR_LOG(s_log, PR_LOG_DEBUG, ("but it wasn't in the cache"));
#endif
- return;
+ return;
}
(void)remove_issuer_and_serial_entry(td->cache, cert);
- (void)remove_subject_entry(td->cache, cert, &subjectList,
+ (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);
- }
+ (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
-)
+nssTrustDomain_LockCertCache(NSSTrustDomain *td)
{
PZ_Lock(td->cache->lock);
}
NSS_IMPLEMENT void
-nssTrustDomain_UnlockCertCache (
- NSSTrustDomain *td
-)
+nssTrustDomain_UnlockCertCache(NSSTrustDomain *td)
{
PZ_Unlock(td->cache->lock);
}
@@ -384,7 +374,7 @@ struct token_cert_dtor {
PRUint32 numCerts, arrSize;
};
-static void
+static void
remove_token_certs(const void *k, void *v, void *a)
{
NSSCertificate *c = (NSSCertificate *)k;
@@ -393,43 +383,42 @@ remove_token_certs(const void *k, void *v, void *a)
PRUint32 i;
nssPKIObject_AddRef(object);
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;
- }
+ 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);
nssPKIObject_Destroy(object);
return;
}
-/*
+/*
* Remove all certs for the given token from the cache. This is
- * needed if the token is removed.
+ * needed if the token is removed.
*/
NSS_IMPLEMENT PRStatus
-nssTrustDomain_RemoveTokenCertsFromCache (
- NSSTrustDomain *td,
- NSSToken *token
-)
+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;
+ return PR_FAILURE;
}
dtor.cache = td->cache;
dtor.token = token;
@@ -438,74 +427,73 @@ nssTrustDomain_RemoveTokenCertsFromCache (
dtor.arrSize = arrSize;
PZ_Lock(td->cache->lock);
nssHash_Iterate(td->cache->issuerAndSN, remove_token_certs, &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 */
- } else {
- /* make sure it doesn't disappear on us before we finish */
- nssCertificate_AddRef(dtor.certs[i]);
- }
+ 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 */
+ } else {
+ /* make sure it doesn't disappear on us before we finish */
+ nssCertificate_AddRef(dtor.certs[i]);
+ }
}
PZ_Unlock(td->cache->lock);
- for (i=0; i<dtor.numCerts; i++) {
- if (dtor.certs[i]) {
- STAN_ForceCERTCertificateUpdate(dtor.certs[i]);
- nssCertificate_Destroy(dtor.certs[i]);
- }
+ for (i = 0; i < dtor.numCerts; i++) {
+ if (dtor.certs[i]) {
+ STAN_ForceCERTCertificateUpdate(dtor.certs[i]);
+ nssCertificate_Destroy(dtor.certs[i]);
+ }
}
nss_ZFreeIf(dtor.certs);
return PR_SUCCESS;
}
NSS_IMPLEMENT PRStatus
-nssTrustDomain_UpdateCachedTokenCerts (
- NSSTrustDomain *td,
- NSSToken *token
-)
+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;
+ 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) {
- nssList_Destroy(certList);
- return PR_FAILURE;
- }
- nssList_GetArray(certList, (void **)cached, count);
- 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);
+ cached = nss_ZNEWARRAY(NULL, NSSCertificate *, count + 1);
+ if (!cached) {
+ nssList_Destroy(certList);
+ return PR_FAILURE;
+ }
+ nssList_GetArray(certList, (void **)cached, count);
+ 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);
}
nssList_Destroy(certList);
return PR_SUCCESS;
}
static PRStatus
-add_issuer_and_serial_entry (
- NSSArena *arena,
- nssTDCertificateCache *cache,
- NSSCertificate *cert
-)
+add_issuer_and_serial_entry(
+ NSSArena *arena,
+ nssTDCertificateCache *cache,
+ NSSCertificate *cert)
{
cache_entry *ce;
ce = new_cache_entry(arena, (void *)cert, PR_FALSE);
@@ -516,156 +504,153 @@ add_issuer_and_serial_entry (
}
static PRStatus
-add_subject_entry (
- NSSArena *arena,
- nssTDCertificateCache *cache,
- NSSCertificate *cert,
- NSSUTF8 *nickname,
- nssList **subjectList
-)
+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 */
+ *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);
+ 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);
+ 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;
+ 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);
+ log_cert_ref("created subject list", cert);
#endif
}
return nssrv;
}
static PRStatus
-add_nickname_entry (
- NSSArena *arena,
- nssTDCertificateCache *cache,
- NSSUTF8 *certNickname,
- nssList *subjectList
-)
+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;
+ /* 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);
+ 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);
+ log_cert_ref("created nickname for", cert);
#endif
}
return nssrv;
}
static PRStatus
-add_email_entry (
- nssTDCertificateCache *cache,
- NSSCertificate *cert,
- nssList *subjectList
-)
+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();
+ /* 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);
+ 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;
- }
+ 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);
+ log_cert_ref("created email for", cert);
#endif
}
return nssrv;
@@ -674,24 +659,22 @@ add_email_entry (
extern const NSSError NSS_ERROR_CERTIFICATE_IN_CACHE;
static void
-remove_object_instances (
- nssPKIObject *object,
- nssCryptokiObject **instances,
- int numInstances
-)
+remove_object_instances(
+ nssPKIObject *object,
+ nssCryptokiObject **instances,
+ int numInstances)
{
int i;
for (i = 0; i < numInstances; i++) {
- nssPKIObject_RemoveInstanceForToken(object, instances[i]->token);
+ nssPKIObject_RemoveInstanceForToken(object, instances[i]->token);
}
}
static SECStatus
-merge_object_instances (
- nssPKIObject *to,
- nssPKIObject *from
-)
+merge_object_instances(
+ nssPKIObject *to,
+ nssPKIObject *from)
{
nssCryptokiObject **instances, **ci;
int i;
@@ -699,29 +682,28 @@ merge_object_instances (
instances = nssPKIObject_GetInstances(from);
if (instances == NULL) {
- return SECFailure;
+ return SECFailure;
}
for (ci = instances, i = 0; *ci; ci++, i++) {
- nssCryptokiObject *instance = nssCryptokiObject_Clone(*ci);
- if (instance) {
- if (nssPKIObject_AddInstance(to, instance) == PR_SUCCESS) {
- continue;
- }
- nssCryptokiObject_Destroy(instance);
- }
- remove_object_instances(to, instances, i);
- rv = SECFailure;
- break;
+ nssCryptokiObject *instance = nssCryptokiObject_Clone(*ci);
+ if (instance) {
+ if (nssPKIObject_AddInstance(to, instance) == PR_SUCCESS) {
+ 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
-)
+add_cert_to_cache(
+ NSSTrustDomain *td,
+ NSSCertificate *cert)
{
NSSArena *arena = NULL;
nssList *subjectList = NULL;
@@ -735,85 +717,84 @@ add_cert_to_cache (
/* 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);
+ 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);
+ log_cert_ref("attempted to add cert already in cache", cert);
#endif
- PZ_Unlock(td->cache->lock);
+ 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;
+ /* 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;
+ goto loser;
}
added++;
/* create an arena for the nickname and subject entries */
arena = nssArena_Create();
if (!arena) {
- goto loser;
+ goto loser;
}
/* create a new subject list for this cert, or add to existing */
- nssrv = add_subject_entry(arena, td->cache, cert,
- certNickname, &subjectList);
+ nssrv = add_subject_entry(arena, td->cache, cert,
+ certNickname, &subjectList);
if (nssrv != PR_SUCCESS) {
- goto loser;
+ goto loser;
}
added++;
/* If a new subject entry was created, also need nickname and/or email */
if (subjectList != NULL) {
#ifdef nodef
- PRBool handle = PR_FALSE;
+ PRBool handle = PR_FALSE;
#endif
- if (certNickname) {
- nssrv = add_nickname_entry(arena, td->cache,
- certNickname, subjectList);
- if (nssrv != PR_SUCCESS) {
- goto loser;
- }
+ if (certNickname) {
+ nssrv = add_nickname_entry(arena, td->cache,
+ certNickname, subjectList);
+ if (nssrv != PR_SUCCESS) {
+ goto loser;
+ }
#ifdef nodef
- handle = PR_TRUE;
+ handle = PR_TRUE;
#endif
- added++;
- }
- if (cert->email) {
- nssrv = add_email_entry(td->cache, cert, subjectList);
- if (nssrv != PR_SUCCESS) {
- goto loser;
- }
+ added++;
+ }
+ if (cert->email) {
+ nssrv = add_email_entry(td->cache, cert, subjectList);
+ if (nssrv != PR_SUCCESS) {
+ goto loser;
+ }
#ifdef nodef
- handle = PR_TRUE;
+ handle = PR_TRUE;
#endif
- added += 2;
- }
+ 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;
- }
+ /* 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);
+ /* A new subject entry was not created. arena is unused. */
+ nssArena_Destroy(arena);
}
rvCert = cert;
PZ_Unlock(td->cache->lock);
@@ -825,78 +806,76 @@ loser:
/* Remove any handles that have been created */
subjectList = NULL;
if (added >= 1) {
- (void)remove_issuer_and_serial_entry(td->cache, cert);
+ (void)remove_issuer_and_serial_entry(td->cache, cert);
}
if (added >= 2) {
- (void)remove_subject_entry(td->cache, cert, &subjectList,
- &certNickname, &arena);
+ (void)remove_subject_entry(td->cache, cert, &subjectList,
+ &certNickname, &arena);
}
if (added == 3 || added == 5) {
- (void)remove_nickname_entry(td->cache, certNickname, subjectList);
+ (void)remove_nickname_entry(td->cache, certNickname, subjectList);
}
if (added >= 4) {
- (void)remove_email_entry(td->cache, cert, subjectList);
+ (void)remove_email_entry(td->cache, cert, subjectList);
}
if (subjectList) {
- nssHash_Remove(td->cache->subject, &cert->subject);
- nssList_Destroy(subjectList);
+ nssHash_Remove(td->cache->subject, &cert->subject);
+ nssList_Destroy(subjectList);
}
if (arena) {
- nssArena_Destroy(arena);
+ nssArena_Destroy(arena);
}
PZ_Unlock(td->cache->lock);
return NULL;
}
NSS_IMPLEMENT PRStatus
-nssTrustDomain_AddCertsToCache (
- NSSTrustDomain *td,
- NSSCertificate **certs,
- PRUint32 numCerts
-)
+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;
- }
+ 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
-)
+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);
+ 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);
+ count = nssList_Count(subjectList);
+ rvArray = nss_ZNEWARRAY(NULL, NSSCertificate *, count + 1);
+ if (!rvArray) {
+ return (NSSCertificate **)NULL;
+ }
+ nssList_GetArray(subjectList, (void **)rvArray, count);
}
return rvArray;
}
@@ -905,11 +884,10 @@ collect_subject_certs (
* Find all cached certs with this subject.
*/
NSS_IMPLEMENT NSSCertificate **
-nssTrustDomain_GetCertsForSubjectFromCache (
- NSSTrustDomain *td,
- NSSDER *subject,
- nssList *certListOpt
-)
+nssTrustDomain_GetCertsForSubjectFromCache(
+ NSSTrustDomain *td,
+ NSSDER *subject,
+ nssList *certListOpt)
{
NSSCertificate **rvArray = NULL;
cache_entry *ce;
@@ -919,12 +897,12 @@ nssTrustDomain_GetCertsForSubjectFromCache (
PZ_Lock(td->cache->lock);
ce = (cache_entry *)nssHash_Lookup(td->cache->subject, subject);
if (ce) {
- ce->hits++;
- ce->lastHit = PR_Now();
+ ce->hits++;
+ ce->lastHit = PR_Now();
#ifdef DEBUG_CACHE
- PR_LOG(s_log, PR_LOG_DEBUG, ("... found, %d hits", ce->hits));
+ PR_LOG(s_log, PR_LOG_DEBUG, ("... found, %d hits", ce->hits));
#endif
- rvArray = collect_subject_certs(ce->entry.list, certListOpt);
+ rvArray = collect_subject_certs(ce->entry.list, certListOpt);
}
PZ_Unlock(td->cache->lock);
return rvArray;
@@ -934,11 +912,10 @@ nssTrustDomain_GetCertsForSubjectFromCache (
* Find all cached certs with this label.
*/
NSS_IMPLEMENT NSSCertificate **
-nssTrustDomain_GetCertsForNicknameFromCache (
- NSSTrustDomain *td,
- const NSSUTF8 *nickname,
- nssList *certListOpt
-)
+nssTrustDomain_GetCertsForNicknameFromCache(
+ NSSTrustDomain *td,
+ const NSSUTF8 *nickname,
+ nssList *certListOpt)
{
NSSCertificate **rvArray = NULL;
cache_entry *ce;
@@ -948,12 +925,12 @@ nssTrustDomain_GetCertsForNicknameFromCache (
PZ_Lock(td->cache->lock);
ce = (cache_entry *)nssHash_Lookup(td->cache->nickname, nickname);
if (ce) {
- ce->hits++;
- ce->lastHit = PR_Now();
+ ce->hits++;
+ ce->lastHit = PR_Now();
#ifdef DEBUG_CACHE
- PR_LOG(s_log, PR_LOG_DEBUG, ("... found, %d hits", ce->hits));
+ PR_LOG(s_log, PR_LOG_DEBUG, ("... found, %d hits", ce->hits));
#endif
- rvArray = collect_subject_certs(ce->entry.list, certListOpt);
+ rvArray = collect_subject_certs(ce->entry.list, certListOpt);
}
PZ_Unlock(td->cache->lock);
return rvArray;
@@ -963,11 +940,10 @@ nssTrustDomain_GetCertsForNicknameFromCache (
* Find all cached certs with this email address.
*/
NSS_IMPLEMENT NSSCertificate **
-nssTrustDomain_GetCertsForEmailAddressFromCache (
- NSSTrustDomain *td,
- NSSASCII7 *email,
- nssList *certListOpt
-)
+nssTrustDomain_GetCertsForEmailAddressFromCache(
+ NSSTrustDomain *td,
+ NSSASCII7 *email,
+ nssList *certListOpt)
{
NSSCertificate **rvArray = NULL;
cache_entry *ce;
@@ -980,45 +956,45 @@ nssTrustDomain_GetCertsForEmailAddressFromCache (
PZ_Lock(td->cache->lock);
ce = (cache_entry *)nssHash_Lookup(td->cache->email, email);
if (ce) {
- ce->hits++;
- ce->lastHit = PR_Now();
+ ce->hits++;
+ ce->lastHit = PR_Now();
#ifdef DEBUG_CACHE
- PR_LOG(s_log, PR_LOG_DEBUG, ("... found, %d hits", ce->hits));
+ 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);
+ /* 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);
+ PRUint32 count = nssList_Count(collectList);
+ rvArray = nss_ZNEWARRAY(NULL, NSSCertificate *, count);
+ if (rvArray) {
+ nssList_GetArray(collectList, (void **)rvArray, count);
+ }
+ nssList_Destroy(collectList);
}
return rvArray;
}
@@ -1027,11 +1003,10 @@ nssTrustDomain_GetCertsForEmailAddressFromCache (
* Look for a specific cert in the cache
*/
NSS_IMPLEMENT NSSCertificate *
-nssTrustDomain_GetCertForIssuerAndSNFromCache (
- NSSTrustDomain *td,
- NSSDER *issuer,
- NSSDER *serial
-)
+nssTrustDomain_GetCertForIssuerAndSNFromCache(
+ NSSTrustDomain *td,
+ NSSDER *issuer,
+ NSSDER *serial)
{
NSSCertificate certkey;
NSSCertificate *rvCert = NULL;
@@ -1047,11 +1022,11 @@ nssTrustDomain_GetCertForIssuerAndSNFromCache (
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);
+ 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));
+ PR_LOG(s_log, PR_LOG_DEBUG, ("... found, %d hits", ce->hits));
#endif
}
PZ_Unlock(td->cache->lock);
@@ -1062,29 +1037,29 @@ nssTrustDomain_GetCertForIssuerAndSNFromCache (
* Look for a specific cert in the cache
*/
NSS_IMPLEMENT NSSCertificate *
-nssTrustDomain_GetCertByDERFromCache (
- NSSTrustDomain *td,
- NSSDER *der
-)
+nssTrustDomain_GetCertByDERFromCache(
+ NSSTrustDomain *td,
+ NSSDER *der)
{
PRStatus nssrv = PR_FAILURE;
NSSDER issuer, serial;
NSSCertificate *rvCert;
nssrv = nssPKIX509_GetIssuerAndSerialFromDER(der, &issuer, &serial);
if (nssrv != PR_SUCCESS) {
- return NULL;
+ return NULL;
}
#ifdef DEBUG_CACHE
log_item_dump("looking for cert by DER", der);
#endif
- rvCert = nssTrustDomain_GetCertForIssuerAndSNFromCache(td,
+ 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)
+static void
+cert_iter(const void *k, void *v, void *a)
{
nssList *certList = (nssList *)a;
NSSCertificate *c = (NSSCertificate *)k;
@@ -1092,40 +1067,38 @@ static void cert_iter(const void *k, void *v, void *a)
}
NSS_EXTERN NSSCertificate **
-nssTrustDomain_GetCertsFromCache (
- NSSTrustDomain *td,
- nssList *certListOpt
-)
+nssTrustDomain_GetCertsFromCache(
+ NSSTrustDomain *td,
+ nssList *certListOpt)
{
NSSCertificate **rvArray = NULL;
nssList *certList;
if (certListOpt) {
- certList = certListOpt;
+ certList = certListOpt;
} else {
- certList = nssList_Create(NULL, PR_FALSE);
- if (!certList) {
- return NULL;
- }
+ 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);
+ 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
-)
+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);
diff --git a/nss/lib/pki/trustdomain.c b/nss/lib/pki/trustdomain.c
index 90e8f26..49f7dc5 100644
--- a/nss/lib/pki/trustdomain.c
+++ b/nss/lib/pki/trustdomain.c
@@ -22,27 +22,26 @@ extern const NSSError NSS_ERROR_NOT_FOUND;
typedef PRUint32 nssUpdateLevel;
NSS_IMPLEMENT NSSTrustDomain *
-NSSTrustDomain_Create (
- NSSUTF8 *moduleOpt,
- NSSUTF8 *uriOpt,
- NSSUTF8 *opaqueOpt,
- void *reserved
-)
+NSSTrustDomain_Create(
+ NSSUTF8 *moduleOpt,
+ NSSUTF8 *uriOpt,
+ NSSUTF8 *opaqueOpt,
+ void *reserved)
{
NSSArena *arena;
NSSTrustDomain *rvTD;
arena = NSSArena_Create();
- if(!arena) {
- return (NSSTrustDomain *)NULL;
+ if (!arena) {
+ return (NSSTrustDomain *)NULL;
}
rvTD = nss_ZNEW(arena, NSSTrustDomain);
if (!rvTD) {
- goto loser;
+ goto loser;
}
/* protect the token list and the token iterator */
rvTD->tokensLock = NSSRWLock_New(100, "tokens");
if (!rvTD->tokensLock) {
- goto loser;
+ goto loser;
}
nssTrustDomain_InitializeCache(rvTD, NSSTRUSTDOMAIN_DEFAULT_CACHE_SIZE);
rvTD->arena = arena;
@@ -51,7 +50,7 @@ NSSTrustDomain_Create (
return rvTD;
loser:
if (rvTD && rvTD->tokensLock) {
- NSSRWLock_Destroy(rvTD->tokensLock);
+ NSSRWLock_Destroy(rvTD->tokensLock);
}
nssArena_Destroy(arena);
return (NSSTrustDomain *)NULL;
@@ -62,205 +61,196 @@ 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),
+ * 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
-)
+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);
+ /* 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
-)
+nssTrustDomain_GetActiveSlots(
+ NSSTrustDomain *td,
+ nssUpdateLevel *updateLevel)
{
PRUint32 count;
NSSSlot **slots = NULL;
NSSToken **tp, **tokens;
*updateLevel = 1;
+ if (!td->tokenList) {
+ return NULL;
+ }
NSSRWLock_LockRead(td->tokensLock);
count = nssList_Count(td->tokenList);
tokens = nss_ZNEWARRAY(NULL, NSSToken *, count + 1);
if (!tokens) {
- NSSRWLock_UnlockRead(td->tokensLock);
- return NULL;
+ NSSRWLock_UnlockRead(td->tokensLock);
+ return NULL;
}
slots = nss_ZNEWARRAY(NULL, NSSSlot *, count + 1);
if (!slots) {
- NSSRWLock_UnlockRead(td->tokensLock);
- nss_ZFreeIf(tokens);
- return NULL;
+ 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);
+ NSSSlot *slot = nssToken_GetSlot(*tp);
if (!PK11_IsDisabled(slot->pk11slot)) {
slots[count++] = slot;
} else {
- nssSlot_Destroy(slot);
- }
+ nssSlot_Destroy(slot);
+ }
}
nss_ZFreeIf(tokens);
if (!count) {
- nss_ZFreeIf(slots);
- slots = NULL;
+ nss_ZFreeIf(slots);
+ slots = NULL;
}
return slots;
}
/* XXX */
static nssSession *
-nssTrustDomain_GetSessionForToken (
- NSSTrustDomain *td,
- NSSToken *token
-)
+nssTrustDomain_GetSessionForToken(
+ NSSTrustDomain *td,
+ NSSToken *token)
{
return nssToken_GetDefaultSession(token);
}
NSS_IMPLEMENT PRStatus
-NSSTrustDomain_SetDefaultCallback (
- NSSTrustDomain *td,
- NSSCallback *newCallback,
- NSSCallback **oldCallbackOpt
-)
+NSSTrustDomain_SetDefaultCallback(
+ NSSTrustDomain *td,
+ NSSCallback *newCallback,
+ NSSCallback **oldCallbackOpt)
{
if (oldCallbackOpt) {
- *oldCallbackOpt = td->defaultCallback;
+ *oldCallbackOpt = td->defaultCallback;
}
td->defaultCallback = newCallback;
return PR_SUCCESS;
}
NSS_IMPLEMENT NSSCallback *
-nssTrustDomain_GetDefaultCallback (
- NSSTrustDomain *td,
- PRStatus *statusOpt
-)
+nssTrustDomain_GetDefaultCallback(
+ NSSTrustDomain *td,
+ PRStatus *statusOpt)
{
if (statusOpt) {
- *statusOpt = PR_SUCCESS;
+ *statusOpt = PR_SUCCESS;
}
return td->defaultCallback;
}
NSS_IMPLEMENT NSSCallback *
-NSSTrustDomain_GetDefaultCallback (
- NSSTrustDomain *td,
- PRStatus *statusOpt
-)
+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
-)
+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
-)
+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
-)
+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
-)
+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
-)
+NSSTrustDomain_FindSlotByName(
+ NSSTrustDomain *td,
+ NSSUTF8 *slotName)
{
nss_SetError(NSS_ERROR_NOT_FOUND);
return NULL;
}
NSS_IMPLEMENT NSSToken *
-NSSTrustDomain_FindTokenByName (
- NSSTrustDomain *td,
- NSSUTF8 *tokenName
-)
+NSSTrustDomain_FindTokenByName(
+ NSSTrustDomain *td,
+ NSSUTF8 *tokenName)
{
PRStatus nssrv;
NSSUTF8 *myName;
NSSToken *tok = NULL;
NSSRWLock_LockRead(td->tokensLock);
- for (tok = (NSSToken *)nssListIterator_Start(td->tokens);
+ 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;
- }
+ 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);
@@ -268,117 +258,106 @@ NSSTrustDomain_FindTokenByName (
}
NSS_IMPLEMENT NSSToken *
-NSSTrustDomain_FindTokenBySlotName (
- NSSTrustDomain *td,
- NSSUTF8 *slotName
-)
+NSSTrustDomain_FindTokenBySlotName(
+ NSSTrustDomain *td,
+ NSSUTF8 *slotName)
{
nss_SetError(NSS_ERROR_NOT_FOUND);
return NULL;
}
NSS_IMPLEMENT NSSToken *
-NSSTrustDomain_FindTokenForAlgorithm (
- NSSTrustDomain *td,
- NSSOID *algorithm
-)
+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 */
-)
+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
-)
+NSSTrustDomain_Login(
+ NSSTrustDomain *td,
+ NSSCallback *uhhOpt)
{
nss_SetError(NSS_ERROR_NOT_FOUND);
return PR_FAILURE;
}
NSS_IMPLEMENT PRStatus
-NSSTrustDomain_Logout (
- NSSTrustDomain *td
-)
+NSSTrustDomain_Logout(NSSTrustDomain *td)
{
nss_SetError(NSS_ERROR_NOT_FOUND);
return PR_FAILURE;
}
NSS_IMPLEMENT NSSCertificate *
-NSSTrustDomain_ImportCertificate (
- NSSTrustDomain *td,
- NSSCertificate *c
-)
+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
-)
+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
-)
+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
-)
+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
-)
+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
-)
+NSSTrustDomain_ImportEncodedPublicKey(
+ NSSTrustDomain *td,
+ NSSBER *ber)
{
nss_SetError(NSS_ERROR_NOT_FOUND);
return NULL;
@@ -390,22 +369,21 @@ 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);
- }
+ 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
-)
+nssTrustDomain_FindCertificatesByNickname(
+ NSSTrustDomain *td,
+ const NSSUTF8 *name,
+ NSSCertificate *rvOpt[],
+ PRUint32 maximumOpt, /* 0 for no max */
+ NSSArena *arenaOpt)
{
NSSToken *token = NULL;
NSSSlot **slots = NULL;
@@ -421,7 +399,7 @@ nssTrustDomain_FindCertificatesByNickname (
/* First, grab from the cache */
nameList = nssList_Create(NULL, PR_FALSE);
if (!nameList) {
- return NULL;
+ return NULL;
}
(void)nssTrustDomain_GetCertsForNicknameFromCache(td, name, nameList);
rvCerts = get_certs_from_list(nameList);
@@ -432,55 +410,55 @@ nssTrustDomain_FindCertificatesByNickname (
nssCertificateArray_Destroy(rvCerts);
nssList_Destroy(nameList);
if (!collection) {
- return (NSSCertificate **)NULL;
+ return (NSSCertificate **)NULL;
}
/* obtain the current set of active slots in the trust domain */
slots = nssTrustDomain_GetActiveSlots(td, &updateLevel);
if (!slots) {
- goto loser;
+ 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;
- }
- }
- }
+ 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;
+ goto loser;
/* Grab the certs collected in the search. */
rvCerts = nssPKIObjectCollection_GetCertificates(collection,
rvOpt, maximumOpt,
@@ -491,22 +469,21 @@ nssTrustDomain_FindCertificatesByNickname (
return rvCerts;
loser:
if (slots) {
- nssSlotArray_Destroy(slots);
+ nssSlotArray_Destroy(slots);
}
if (collection) {
- nssPKIObjectCollection_Destroy(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
-)
+NSSTrustDomain_FindCertificatesByNickname(
+ NSSTrustDomain *td,
+ NSSUTF8 *name,
+ NSSCertificate *rvOpt[],
+ PRUint32 maximumOpt, /* 0 for no max */
+ NSSArena *arenaOpt)
{
return nssTrustDomain_FindCertificatesByNickname(td,
name,
@@ -516,13 +493,12 @@ NSSTrustDomain_FindCertificatesByNickname (
}
NSS_IMPLEMENT NSSCertificate *
-nssTrustDomain_FindBestCertificateByNickname (
- NSSTrustDomain *td,
- const NSSUTF8 *name,
- NSSTime *timeOpt,
- NSSUsage *usage,
- NSSPolicies *policiesOpt
-)
+nssTrustDomain_FindBestCertificateByNickname(
+ NSSTrustDomain *td,
+ const NSSUTF8 *name,
+ NSSTime *timeOpt,
+ NSSUsage *usage,
+ NSSPolicies *policiesOpt)
{
NSSCertificate **nicknameCerts;
NSSCertificate *rvCert = NULL;
@@ -531,23 +507,22 @@ nssTrustDomain_FindBestCertificateByNickname (
0,
NULL);
if (nicknameCerts) {
- rvCert = nssCertificateArray_FindBestCertificate(nicknameCerts,
+ rvCert = nssCertificateArray_FindBestCertificate(nicknameCerts,
timeOpt,
usage,
policiesOpt);
- nssCertificateArray_Destroy(nicknameCerts);
+ nssCertificateArray_Destroy(nicknameCerts);
}
return rvCert;
}
NSS_IMPLEMENT NSSCertificate *
-NSSTrustDomain_FindBestCertificateByNickname (
- NSSTrustDomain *td,
- const NSSUTF8 *name,
- NSSTime *timeOpt,
- NSSUsage *usage,
- NSSPolicies *policiesOpt
-)
+NSSTrustDomain_FindBestCertificateByNickname(
+ NSSTrustDomain *td,
+ const NSSUTF8 *name,
+ NSSTime *timeOpt,
+ NSSUsage *usage,
+ NSSPolicies *policiesOpt)
{
return nssTrustDomain_FindBestCertificateByNickname(td,
name,
@@ -557,13 +532,12 @@ NSSTrustDomain_FindBestCertificateByNickname (
}
NSS_IMPLEMENT NSSCertificate **
-nssTrustDomain_FindCertificatesBySubject (
- NSSTrustDomain *td,
- NSSDER *subject,
- NSSCertificate *rvOpt[],
- PRUint32 maximumOpt, /* 0 for no max */
- NSSArena *arenaOpt
-)
+nssTrustDomain_FindCertificatesBySubject(
+ NSSTrustDomain *td,
+ NSSDER *subject,
+ NSSCertificate *rvOpt[],
+ PRUint32 maximumOpt, /* 0 for no max */
+ NSSArena *arenaOpt)
{
NSSToken *token = NULL;
NSSSlot **slots = NULL;
@@ -579,7 +553,7 @@ nssTrustDomain_FindCertificatesBySubject (
/* look in cache */
subjectList = nssList_Create(NULL, PR_FALSE);
if (!subjectList) {
- return NULL;
+ return NULL;
}
(void)nssTrustDomain_GetCertsForSubjectFromCache(td, subject, subjectList);
rvCerts = get_certs_from_list(subjectList);
@@ -587,53 +561,53 @@ nssTrustDomain_FindCertificatesBySubject (
nssCertificateArray_Destroy(rvCerts);
nssList_Destroy(subjectList);
if (!collection) {
- return (NSSCertificate **)NULL;
+ return (NSSCertificate **)NULL;
}
slots = nssTrustDomain_GetActiveSlots(td, &updateLevel);
if (!slots) {
- goto loser;
+ 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;
- }
- }
- }
+ 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;
+ goto loser;
rvCerts = nssPKIObjectCollection_GetCertificates(collection,
rvOpt, maximumOpt,
arenaOpt);
@@ -642,24 +616,23 @@ nssTrustDomain_FindCertificatesBySubject (
return rvCerts;
loser:
if (slots) {
- nssSlotArray_Destroy(slots);
+ nssSlotArray_Destroy(slots);
}
if (collection) {
- nssPKIObjectCollection_Destroy(collection);
+ nssPKIObjectCollection_Destroy(collection);
}
return (NSSCertificate **)NULL;
}
NSS_IMPLEMENT NSSCertificate **
-NSSTrustDomain_FindCertificatesBySubject (
- NSSTrustDomain *td,
- NSSDER *subject,
- NSSCertificate *rvOpt[],
- PRUint32 maximumOpt,
- NSSArena *arenaOpt
-)
+NSSTrustDomain_FindCertificatesBySubject(
+ NSSTrustDomain *td,
+ NSSDER *subject,
+ NSSCertificate *rvOpt[],
+ PRUint32 maximumOpt,
+ NSSArena *arenaOpt)
{
- return nssTrustDomain_FindCertificatesBySubject(td,
+ return nssTrustDomain_FindCertificatesBySubject(td,
subject,
rvOpt,
maximumOpt,
@@ -667,13 +640,12 @@ NSSTrustDomain_FindCertificatesBySubject (
}
NSS_IMPLEMENT NSSCertificate *
-nssTrustDomain_FindBestCertificateBySubject (
- NSSTrustDomain *td,
- NSSDER *subject,
- NSSTime *timeOpt,
- NSSUsage *usage,
- NSSPolicies *policiesOpt
-)
+nssTrustDomain_FindBestCertificateBySubject(
+ NSSTrustDomain *td,
+ NSSDER *subject,
+ NSSTime *timeOpt,
+ NSSUsage *usage,
+ NSSPolicies *policiesOpt)
{
NSSCertificate **subjectCerts;
NSSCertificate *rvCert = NULL;
@@ -682,23 +654,22 @@ nssTrustDomain_FindBestCertificateBySubject (
0,
NULL);
if (subjectCerts) {
- rvCert = nssCertificateArray_FindBestCertificate(subjectCerts,
+ rvCert = nssCertificateArray_FindBestCertificate(subjectCerts,
timeOpt,
usage,
policiesOpt);
- nssCertificateArray_Destroy(subjectCerts);
+ nssCertificateArray_Destroy(subjectCerts);
}
return rvCert;
}
NSS_IMPLEMENT NSSCertificate *
-NSSTrustDomain_FindBestCertificateBySubject (
- NSSTrustDomain *td,
- NSSDER *subject,
- NSSTime *timeOpt,
- NSSUsage *usage,
- NSSPolicies *policiesOpt
-)
+NSSTrustDomain_FindBestCertificateBySubject(
+ NSSTrustDomain *td,
+ NSSDER *subject,
+ NSSTime *timeOpt,
+ NSSUsage *usage,
+ NSSPolicies *policiesOpt)
{
return nssTrustDomain_FindBestCertificateBySubject(td,
subject,
@@ -708,26 +679,24 @@ NSSTrustDomain_FindBestCertificateBySubject (
}
NSS_IMPLEMENT NSSCertificate *
-NSSTrustDomain_FindBestCertificateByNameComponents (
- NSSTrustDomain *td,
- NSSUTF8 *nameComponents,
- NSSTime *timeOpt,
- NSSUsage *usage,
- NSSPolicies *policiesOpt
-)
+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
-)
+NSSTrustDomain_FindCertificatesByNameComponents(
+ NSSTrustDomain *td,
+ NSSUTF8 *nameComponents,
+ NSSCertificate *rvOpt[],
+ PRUint32 maximumOpt, /* 0 for no max */
+ NSSArena *arenaOpt)
{
nss_SetError(NSS_ERROR_NOT_FOUND);
return NULL;
@@ -737,11 +706,10 @@ NSSTrustDomain_FindCertificatesByNameComponents (
* when one is found.
*/
NSS_IMPLEMENT NSSCertificate *
-nssTrustDomain_FindCertificateByIssuerAndSerialNumber (
- NSSTrustDomain *td,
- NSSDER *issuer,
- NSSDER *serial
-)
+nssTrustDomain_FindCertificateByIssuerAndSerialNumber(
+ NSSTrustDomain *td,
+ NSSDER *issuer,
+ NSSDER *serial)
{
NSSSlot **slots = NULL;
NSSSlot **slotp;
@@ -751,70 +719,69 @@ nssTrustDomain_FindCertificateByIssuerAndSerialNumber (
/* see if this search is already cached */
rvCert = nssTrustDomain_GetCertForIssuerAndSNFromCache(td,
- issuer,
+ issuer,
serial);
if (rvCert) {
- return 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 */
- }
- }
- }
+ 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);
+ nssPKIObjectCollection_Destroy(collection);
}
if (slots) {
- nssSlotArray_Destroy(slots);
+ nssSlotArray_Destroy(slots);
}
return rvCert;
}
NSS_IMPLEMENT NSSCertificate *
-NSSTrustDomain_FindCertificateByIssuerAndSerialNumber (
- NSSTrustDomain *td,
- NSSDER *issuer,
- NSSDER *serial
-)
+NSSTrustDomain_FindCertificateByIssuerAndSerialNumber(
+ NSSTrustDomain *td,
+ NSSDER *issuer,
+ NSSDER *serial)
{
return nssTrustDomain_FindCertificateByIssuerAndSerialNumber(td,
issuer,
@@ -822,10 +789,9 @@ NSSTrustDomain_FindCertificateByIssuerAndSerialNumber (
}
NSS_IMPLEMENT NSSCertificate *
-nssTrustDomain_FindCertificateByEncodedCertificate (
- NSSTrustDomain *td,
- NSSBER *ber
-)
+nssTrustDomain_FindCertificateByEncodedCertificate(
+ NSSTrustDomain *td,
+ NSSBER *ber)
{
PRStatus status;
NSSCertificate *rvCert = NULL;
@@ -834,7 +800,7 @@ nssTrustDomain_FindCertificateByEncodedCertificate (
/* XXX this is not generic... will any cert crack into issuer/serial? */
status = nssPKIX509_GetIssuerAndSerialFromDER(ber, &issuer, &serial);
if (status != PR_SUCCESS) {
- return NULL;
+ return NULL;
}
rvCert = nssTrustDomain_FindCertificateByIssuerAndSerialNumber(td,
&issuer,
@@ -845,133 +811,123 @@ nssTrustDomain_FindCertificateByEncodedCertificate (
}
NSS_IMPLEMENT NSSCertificate *
-NSSTrustDomain_FindCertificateByEncodedCertificate (
- NSSTrustDomain *td,
- NSSBER *ber
-)
+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
-)
+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
-)
+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
-)
+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
-)
+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
-)
+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
-)
+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
-)
+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
-)
+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
-)
+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;
@@ -985,11 +941,10 @@ collector(nssCryptokiObject *instance, void *arg)
}
NSS_IMPLEMENT PRStatus *
-NSSTrustDomain_TraverseCertificates (
- NSSTrustDomain *td,
- PRStatus (*callback)(NSSCertificate *c, void *arg),
- void *arg
-)
+NSSTrustDomain_TraverseCertificates(
+ NSSTrustDomain *td,
+ PRStatus (*callback)(NSSCertificate *c, void *arg),
+ void *arg)
{
NSSToken *token = NULL;
NSSSlot **slots = NULL;
@@ -1001,40 +956,40 @@ NSSTrustDomain_TraverseCertificates (
nssList *certList;
certList = nssList_Create(NULL, PR_FALSE);
- if (!certList)
- return NULL;
+ 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;
+ return (PRStatus *)NULL;
}
/* obtain the current set of active slots in the trust domain */
slots = nssTrustDomain_GetActiveSlots(td, &updateLevel);
if (!slots) {
- goto loser;
+ 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 */
- (void)nssToken_TraverseCertificates(token,
- session,
- tokenOnly,
- collector,
- collection);
- }
- nssToken_Destroy(token);
- }
+ /* 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 */
+ (void)nssToken_TraverseCertificates(token,
+ session,
+ tokenOnly,
+ collector,
+ collection);
+ }
+ nssToken_Destroy(token);
+ }
}
/* Traverse the collection */
@@ -1043,20 +998,18 @@ NSSTrustDomain_TraverseCertificates (
(void)nssPKIObjectCollection_Traverse(collection, &pkiCallback);
loser:
if (slots) {
- nssSlotArray_Destroy(slots);
+ nssSlotArray_Destroy(slots);
}
if (collection) {
- nssPKIObjectCollection_Destroy(collection);
+ nssPKIObjectCollection_Destroy(collection);
}
return NULL;
}
-
NSS_IMPLEMENT NSSTrust *
-nssTrustDomain_FindTrustForCertificate (
- NSSTrustDomain *td,
- NSSCertificate *c
-)
+nssTrustDomain_FindTrustForCertificate(
+ NSSTrustDomain *td,
+ NSSCertificate *c)
{
NSSSlot **slots;
NSSSlot **slotp;
@@ -1066,50 +1019,49 @@ nssTrustDomain_FindTrustForCertificate (
nssUpdateLevel updateLevel;
slots = nssTrustDomain_GetActiveSlots(td, &updateLevel);
if (!slots) {
- return (NSSTrust *)NULL;
+ 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);
- }
+ 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 */
- }
+ 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);
+ nssPKIObject_Destroy(pkio);
}
return rvt;
}
NSS_IMPLEMENT NSSCRL **
-nssTrustDomain_FindCRLsBySubject (
- NSSTrustDomain *td,
- NSSDER *subject
-)
+nssTrustDomain_FindCRLsBySubject(
+ NSSTrustDomain *td,
+ NSSDER *subject)
{
NSSSlot **slots;
NSSSlot **slotp;
@@ -1119,35 +1071,35 @@ nssTrustDomain_FindCRLsBySubject (
NSSCRL **rvCRLs = NULL;
collection = nssCRLCollection_Create(td, NULL);
if (!collection) {
- return (NSSCRL **)NULL;
+ return (NSSCRL **)NULL;
}
slots = nssTrustDomain_GetActiveSlots(td, &updateLevel);
if (!slots) {
- goto loser;
+ 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);
- }
+ 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:
@@ -1157,93 +1109,84 @@ loser:
}
NSS_IMPLEMENT PRStatus
-NSSTrustDomain_GenerateKeyPair (
- NSSTrustDomain *td,
- NSSAlgorithmAndParameters *ap,
- NSSPrivateKey **pvkOpt,
- NSSPublicKey **pbkOpt,
- PRBool privateKeyIsSensitive,
- NSSToken *destination,
- NSSCallback *uhhOpt
-)
+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
-)
+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
-)
+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
-)
+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
-)
+nssTrustDomain_CreateCryptoContext(
+ NSSTrustDomain *td,
+ NSSCallback *uhhOpt)
{
return nssCryptoContext_Create(td, uhhOpt);
}
NSS_IMPLEMENT NSSCryptoContext *
-NSSTrustDomain_CreateCryptoContext (
- NSSTrustDomain *td,
- NSSCallback *uhhOpt
-)
+NSSTrustDomain_CreateCryptoContext(
+ NSSTrustDomain *td,
+ NSSCallback *uhhOpt)
{
return nssTrustDomain_CreateCryptoContext(td, uhhOpt);
}
NSS_IMPLEMENT NSSCryptoContext *
-NSSTrustDomain_CreateCryptoContextForAlgorithm (
- NSSTrustDomain *td,
- NSSOID *algorithm
-)
+NSSTrustDomain_CreateCryptoContextForAlgorithm(
+ NSSTrustDomain *td,
+ NSSOID *algorithm)
{
nss_SetError(NSS_ERROR_NOT_FOUND);
return NULL;
}
NSS_IMPLEMENT NSSCryptoContext *
-NSSTrustDomain_CreateCryptoContextForAlgorithmAndParameters (
- NSSTrustDomain *td,
- NSSAlgorithmAndParameters *ap
-)
+NSSTrustDomain_CreateCryptoContextForAlgorithmAndParameters(
+ NSSTrustDomain *td,
+ NSSAlgorithmAndParameters *ap)
{
nss_SetError(NSS_ERROR_NOT_FOUND);
return NULL;
}
-
diff --git a/nss/lib/smime/cms.h b/nss/lib/smime/cms.h
index 5b1d7a0..244df48 100644
--- a/nss/lib/smime/cms.h
+++ b/nss/lib/smime/cms.h
@@ -35,9 +35,9 @@ SEC_BEGIN_PROTOS
*/
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);
+ 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
@@ -62,9 +62,9 @@ NSS_CMSDecoder_Finish(NSSCMSDecoderContext *p7dcx);
*/
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);
+ NSSCMSContentCallback cb, void *cb_arg,
+ PK11PasswordFunc pwfn, void *pwfn_arg,
+ NSSCMSGetDecryptKeyCallback decrypt_key_cb, void *decrypt_key_cb_arg);
/************************************************************************
* cmsencode.c - CMS encoding
@@ -84,11 +84,11 @@ NSS_CMSMessage_CreateFromDER(SECItem *DERmessage,
*/
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);
+ 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
@@ -138,9 +138,9 @@ NSS_CMSMessage_Create(PLArenaPool *poolp);
*/
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);
+ 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.
@@ -149,7 +149,7 @@ extern void
NSS_CMSMessage_Destroy(NSSCMSMessage *cmsg);
/*
- * NSS_CMSMessage_Copy - return a copy of the given message.
+ * 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).
@@ -170,7 +170,7 @@ extern NSSCMSContentInfo *
NSS_CMSMessage_GetContentInfo(NSSCMSMessage *cmsg);
/*
- * Return a pointer to the actual content.
+ * 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.
*/
@@ -275,7 +275,6 @@ NSS_CMSContentInfo_SetContent_EncryptedData(NSSCMSMessage *cmsg, NSSCMSContentIn
extern SECStatus
NSS_CMSContentInfo_SetDontStream(NSSCMSContentInfo *cinfo, PRBool dontStream);
-
/*
* NSS_CMSContentInfo_GetContent - get pointer to inner content
*
@@ -284,7 +283,7 @@ NSS_CMSContentInfo_SetDontStream(NSSCMSContentInfo *cinfo, PRBool dontStream);
extern void *
NSS_CMSContentInfo_GetContent(NSSCMSContentInfo *cinfo);
-/*
+/*
* NSS_CMSContentInfo_GetInnerContent - get pointer to innermost content
*
* this is typically only called by NSS_CMSMessage_GetContent()
@@ -317,11 +316,11 @@ NSS_CMSContentInfo_GetContentEncAlg(NSSCMSContentInfo *cinfo);
extern SECStatus
NSS_CMSContentInfo_SetContentEncAlg(PLArenaPool *poolp, NSSCMSContentInfo *cinfo,
- SECOidTag bulkalgtag, SECItem *parameters, int keysize);
+ SECOidTag bulkalgtag, SECItem *parameters, int keysize);
extern SECStatus
NSS_CMSContentInfo_SetContentEncAlgID(PLArenaPool *poolp, NSSCMSContentInfo *cinfo,
- SECAlgorithmID *algid, int keysize);
+ SECAlgorithmID *algid, int keysize);
extern void
NSS_CMSContentInfo_SetBulkKey(NSSCMSContentInfo *cinfo, PK11SymKey *bulkkey);
@@ -354,28 +353,28 @@ extern int
NSS_CMSUtil_DERCompare(void *a, void *b);
/*
- * NSS_CMSAlgArray_GetIndexByAlgID - find a specific algorithm in an array of
+ * 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
+ * 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
+ * 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
+ * An integer containing the index of the algorithm in the array or -1 if
* algorithm was not found.
*/
extern int
@@ -453,7 +452,7 @@ NSS_CMSSignedData_Decode_AfterData(NSSCMSSignedData *sigd);
extern SECStatus
NSS_CMSSignedData_Decode_AfterEnd(NSSCMSSignedData *sigd);
-/*
+/*
* NSS_CMSSignedData_GetSignerInfos - retrieve the SignedData's signer list
*/
extern NSSCMSSignerInfo **
@@ -465,7 +464,7 @@ 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 **
@@ -477,7 +476,7 @@ NSS_CMSSignedData_GetDigestAlgs(NSSCMSSignedData *sigd);
extern NSSCMSContentInfo *
NSS_CMSSignedData_GetContentInfo(NSSCMSSignedData *sigd);
-/*
+/*
* NSS_CMSSignedData_GetCertificateList - retrieve the SignedData's certificate list
*/
extern SECItem **
@@ -485,7 +484,7 @@ NSS_CMSSignedData_GetCertificateList(NSSCMSSignedData *sigd);
extern SECStatus
NSS_CMSSignedData_ImportCerts(NSSCMSSignedData *sigd, CERTCertDBHandle *certdb,
- SECCertUsage certusage, PRBool keepcerts);
+ SECCertUsage certusage, PRBool keepcerts);
/*
* NSS_CMSSignedData_HasDigests - see if we have digests in place
@@ -504,21 +503,21 @@ NSS_CMSSignedData_HasDigests(NSSCMSSignedData *sigd);
*/
extern SECStatus
NSS_CMSSignedData_VerifySignerInfo(NSSCMSSignedData *sigd, int i, CERTCertDBHandle *certdb,
- SECCertUsage certusage);
+ SECCertUsage certusage);
/*
* NSS_CMSSignedData_VerifyCertsOnly - verify the certs in a certs-only message
*/
extern SECStatus
-NSS_CMSSignedData_VerifyCertsOnly(NSSCMSSignedData *sigd,
- CERTCertDBHandle *certdb,
+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
+ * NSS_CMSSignedData_AddCertChain - add cert and its entire chain to the set of certs
*/
extern SECStatus
NSS_CMSSignedData_AddCertChain(NSSCMSSignedData *sigd, CERTCertificate *cert);
@@ -531,23 +530,23 @@ NSS_CMSSignedData_ContainsCertsOrCrls(NSSCMSSignedData *sigd);
extern SECStatus
NSS_CMSSignedData_AddSignerInfo(NSSCMSSignedData *sigd,
- NSSCMSSignerInfo *signerinfo);
+ NSSCMSSignerInfo *signerinfo);
extern SECStatus
NSS_CMSSignedData_SetDigests(NSSCMSSignedData *sigd,
- SECAlgorithmID **digestalgs,
- SECItem **digests);
+ SECAlgorithmID **digestalgs,
+ SECItem **digests);
extern SECStatus
NSS_CMSSignedData_SetDigestValue(NSSCMSSignedData *sigd,
- SECOidTag digestalgtag,
- SECItem *digestdata);
+ SECOidTag digestalgtag,
+ SECItem *digestdata);
extern SECStatus
NSS_CMSSignedData_AddDigest(PLArenaPool *poolp,
- NSSCMSSignedData *sigd,
- SECOidTag digestalgtag,
- SECItem *digest);
+ NSSCMSSignedData *sigd,
+ SECOidTag digestalgtag,
+ SECItem *digest);
extern SECItem *
NSS_CMSSignedData_GetDigestValue(NSSCMSSignedData *sigd, SECOidTag digestalgtag);
@@ -589,7 +588,7 @@ NSS_CMSSignerInfo_Sign(NSSCMSSignerInfo *signerinfo, SECItem *digest, SECItem *c
extern SECStatus
NSS_CMSSignerInfo_VerifyCertificate(NSSCMSSignerInfo *signerinfo, CERTCertDBHandle *certdb,
- SECCertUsage certusage);
+ SECCertUsage certusage);
/*
* NSS_CMSSignerInfo_Verify - verify the signature of a single SignerInfo
@@ -617,7 +616,7 @@ NSS_CMSSignerInfo_GetCertList(NSSCMSSignerInfo *signerinfo);
/*
* NSS_CMSSignerInfo_GetSigningTime - return the signing time,
- * in UTCTime format, of a CMS signerInfo.
+ * in UTCTime format, of a CMS signerInfo.
*
* sinfo - signerInfo data for this signer
*
@@ -659,21 +658,21 @@ NSS_CMSSignerInfo_GetSignerEmailAddress(NSSCMSSignerInfo *sinfo);
/*
* NSS_CMSSignerInfo_AddAuthAttr - add an attribute to the
- * authenticated (i.e. signed) attributes of "signerinfo".
+ * 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".
+ * 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".
+ * 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.
@@ -716,12 +715,12 @@ NSS_CMSSignerInfo_AddSMIMEEncKeyPrefs(NSSCMSSignerInfo *signerinfo, CERTCertific
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);
+ SECOidTag digestalg, CERTCertificate signingcert);
/*
* XXXX the following needs to be done in the S/MIME layer code
@@ -794,7 +793,7 @@ extern SECStatus
NSS_CMSEnvelopedData_Encode_AfterData(NSSCMSEnvelopedData *envd);
/*
- * NSS_CMSEnvelopedData_Decode_BeforeData - find our recipientinfo,
+ * NSS_CMSEnvelopedData_Decode_BeforeData - find our recipientinfo,
* derive bulk key & set up our contentinfo
*/
extern SECStatus
@@ -812,7 +811,6 @@ NSS_CMSEnvelopedData_Decode_AfterData(NSSCMSEnvelopedData *envd);
extern SECStatus
NSS_CMSEnvelopedData_Decode_AfterEnd(NSSCMSEnvelopedData *envd);
-
/************************************************************************
* cmsrecinfo.c - CMS recipientInfo methods
************************************************************************/
@@ -827,42 +825,43 @@ extern NSSCMSRecipientInfo *
NSS_CMSRecipientInfo_Create(NSSCMSMessage *cmsg, CERTCertificate *cert);
extern NSSCMSRecipientInfo *
-NSS_CMSRecipientInfo_CreateWithSubjKeyID(NSSCMSMessage *cmsg,
- SECItem *subjKeyID,
+NSS_CMSRecipientInfo_CreateWithSubjKeyID(NSSCMSMessage *cmsg,
+ SECItem *subjKeyID,
SECKEYPublicKey *pubKey);
extern NSSCMSRecipientInfo *
-NSS_CMSRecipientInfo_CreateWithSubjKeyIDFromCert(NSSCMSMessage *cmsg,
+NSS_CMSRecipientInfo_CreateWithSubjKeyIDFromCert(NSSCMSMessage *cmsg,
CERTCertificate *cert);
/*
- * NSS_CMSRecipientInfo_CreateNew - create a blank recipientinfo for
+ * 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_CreateNew(void *pwfn_arg);
/*
* NSS_CMSRecipientInfo_CreateFromDER - create a recipientinfo from partially
- * decoded DER data for applications which want to encode their own CMS
+ * 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);
+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
+ * 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);
+ CERTCertificate **retcert,
+ SECKEYPrivateKey **retkey);
extern int
NSS_CMSRecipientInfo_GetVersion(NSSCMSRecipientInfo *ri);
@@ -873,19 +872,21 @@ NSS_CMSRecipientInfo_GetEncryptedKey(NSSCMSRecipientInfo *ri, int subIndex);
/*
* NSS_CMSRecipientInfo_Encode - encode an NSS_CMSRecipientInfo as ASN.1
*/
-SECStatus NSS_CMSRecipientInfo_Encode(PLArenaPool* poolp,
+SECStatus NSS_CMSRecipientInfo_Encode(PLArenaPool *poolp,
const NSSCMSRecipientInfo *src,
- SECItem* returned);
+ SECItem *returned);
extern SECOidTag
NSS_CMSRecipientInfo_GetKeyEncryptionAlgorithmTag(NSSCMSRecipientInfo *ri);
extern SECStatus
-NSS_CMSRecipientInfo_WrapBulkKey(NSSCMSRecipientInfo *ri, PK11SymKey *bulkkey, SECOidTag bulkalgtag);
+NSS_CMSRecipientInfo_WrapBulkKey(NSSCMSRecipientInfo *ri, PK11SymKey *bulkkey,
+ SECOidTag bulkalgtag);
extern PK11SymKey *
NSS_CMSRecipientInfo_UnwrapBulkKey(NSSCMSRecipientInfo *ri, int subIndex,
- CERTCertificate *cert, SECKEYPrivateKey *privkey, SECOidTag bulkalgtag);
+ CERTCertificate *cert, SECKEYPrivateKey *privkey,
+ SECOidTag bulkalgtag);
/************************************************************************
* cmsencdata.c - CMS encryptedData methods
@@ -895,7 +896,7 @@ NSS_CMSRecipientInfo_UnwrapBulkKey(NSSCMSRecipientInfo *ri, int subIndex,
*
* "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().)
*/
@@ -1076,7 +1077,7 @@ NSS_CMSDigestContext_Cancel(NSSCMSDigestContext *cmsdigcx);
*/
extern SECStatus
NSS_CMSDigestContext_FinishMultiple(NSSCMSDigestContext *cmsdigcx, PLArenaPool *poolp,
- SECItem ***digestsp);
+ SECItem ***digestsp);
/*
* NSS_CMSDigestContext_FinishSingle - same as NSS_CMSDigestContext_FinishMultiple,
@@ -1084,10 +1085,10 @@ NSS_CMSDigestContext_FinishMultiple(NSSCMSDigestContext *cmsdigcx, PLArenaPool *
*/
extern SECStatus
NSS_CMSDigestContext_FinishSingle(NSSCMSDigestContext *cmsdigcx, PLArenaPool *poolp,
- SECItem *digest);
+ SECItem *digest);
/************************************************************************
- *
+ *
************************************************************************/
/* shortcuts for basic use */
@@ -1098,12 +1099,11 @@ NSS_CMSDigestContext_FinishSingle(NSSCMSDigestContext *cmsdigcx, PLArenaPool *po
* stored in arena's pool.
*/
extern SECStatus
-NSS_CMSDEREncode(NSSCMSMessage *cmsg, SECItem *input, SECItem *derOut,
+NSS_CMSDEREncode(NSSCMSMessage *cmsg, SECItem *input, SECItem *derOut,
PLArenaPool *arena);
-
/************************************************************************
- *
+ *
************************************************************************/
/*
@@ -1116,36 +1116,36 @@ NSS_CMSDEREncode(NSSCMSMessage *cmsg, SECItem *input, SECItem *derOut,
* 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
+ * 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
+ * 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
+ *
+ * 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_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
diff --git a/nss/lib/smime/cmsarray.c b/nss/lib/smime/cmsarray.c
index 9ac5c57..6665d12 100644
--- a/nss/lib/smime/cmsarray.c
+++ b/nss/lib/smime/cmsarray.c
@@ -46,26 +46,27 @@ NSS_CMSArray_Add(PLArenaPool *poolp, void ***array, void *obj)
PORT_Assert(array != NULL);
if (array == NULL)
- return SECFailure;
+ return SECFailure;
if (*array == NULL) {
- dest = (void **)PORT_ArenaAlloc(poolp, 2 * sizeof(void *));
- n = 0;
+ 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 *));
+ 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;
+ return SECFailure;
dest[n] = obj;
- dest[n+1] = NULL;
+ dest[n + 1] = NULL;
*array = dest;
return SECSuccess;
}
@@ -88,10 +89,10 @@ NSS_CMSArray_Count(void **array)
int n = 0;
if (array == NULL)
- return 0;
+ return 0;
while (*array++ != NULL)
- n++;
+ n++;
return n;
}
@@ -102,14 +103,14 @@ NSS_CMSArray_Count(void **array)
* 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
+ * "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)
+NSS_CMSArray_Sort(void **primary, int (*compare)(void *, void *), void **secondary, void **tertiary)
{
int n, i, limit, lastxchg;
void *tmp;
@@ -118,36 +119,36 @@ NSS_CMSArray_Sort(void **primary, int (*compare)(void *,void *), void **secondar
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;
-
+
+ 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] */
+ 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] */
}
}
@@ -162,7 +163,7 @@ NSSCMSArrayIterator
NSS_CMSArray_First(void **array)
{
if (array == NULL || array[0] == NULL)
- return NULL;
+ return NULL;
return (NSSCMSArrayIterator)&(array[0]);
}
@@ -171,7 +172,7 @@ NSS_CMSArray_Obj(NSSCMSArrayIterator iter)
{
void **p = (void **)iter;
- return *iter; /* which is NULL if we are at the end of the array */
+ return *iter; /* which is NULL if we are at the end of the array */
}
NSSCMSArrayIterator
diff --git a/nss/lib/smime/cmsasn1.c b/nss/lib/smime/cmsasn1.c
index b09a2e1..15cf08f 100644
--- a/nss/lib/smime/cmsasn1.c
+++ b/nss/lib/smime/cmsasn1.c
@@ -16,7 +16,6 @@
#include "prtime.h"
#include "secerr.h"
-
extern const SEC_ASN1Template nss_cms_set_of_attribute_template[];
SEC_ASN1_MKSUB(CERT_IssuerAndSNTemplate)
@@ -36,18 +35,17 @@ SEC_ASN1_MKSUB(SEC_SetOfAnyTemplate)
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;
+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) },
+ 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 },
+ 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 }
};
@@ -57,28 +55,28 @@ const SEC_ASN1Template NSSCMSMessageTemplate[] = {
*/
static const SEC_ASN1Template NSSCMSEncapsulatedContentInfoTemplate[] = {
{ SEC_ASN1_SEQUENCE | SEC_ASN1_MAY_STREAM,
- 0, NULL, sizeof(NSSCMSContentInfo) },
+ 0, NULL, sizeof(NSSCMSContentInfo) },
{ SEC_ASN1_OBJECT_ID,
- offsetof(NSSCMSContentInfo,contentType) },
+ 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) },
+ 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) },
+ 0, NULL, sizeof(NSSCMSContentInfo) },
{ SEC_ASN1_OBJECT_ID,
- offsetof(NSSCMSContentInfo,contentType) },
+ 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) },
+ 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 }
};
@@ -90,26 +88,26 @@ const SEC_ASN1Template NSSCMSSignerInfoTemplate[];
const SEC_ASN1Template NSSCMSSignedDataTemplate[] = {
{ SEC_ASN1_SEQUENCE | SEC_ASN1_MAY_STREAM,
- 0, NULL, sizeof(NSSCMSSignedData) },
+ 0, NULL, sizeof(NSSCMSSignedData) },
{ SEC_ASN1_INTEGER,
- offsetof(NSSCMSSignedData,version) },
+ offsetof(NSSCMSSignedData, version) },
{ SEC_ASN1_SET_OF | SEC_ASN1_XTRN,
- offsetof(NSSCMSSignedData,digestAlgorithms),
- SEC_ASN1_SUB(SECOID_AlgorithmIDTemplate) },
+ offsetof(NSSCMSSignedData, digestAlgorithms),
+ SEC_ASN1_SUB(SECOID_AlgorithmIDTemplate) },
{ SEC_ASN1_INLINE,
- offsetof(NSSCMSSignedData,contentInfo),
- NSSCMSEncapsulatedContentInfoTemplate },
+ 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_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_XTRN | 1,
+ offsetof(NSSCMSSignedData, crls),
+ SEC_ASN1_SUB(CERT_SetOfSignedCrlTemplate) },
{ SEC_ASN1_SET_OF,
- offsetof(NSSCMSSignedData,signerInfos),
- NSSCMSSignerInfoTemplate },
+ offsetof(NSSCMSSignedData, signerInfos),
+ NSSCMSSignerInfoTemplate },
{ 0 }
};
@@ -123,16 +121,16 @@ const SEC_ASN1Template NSS_PointerToCMSSignedDataTemplate[] = {
static const SEC_ASN1Template NSSCMSSignerIdentifierTemplate[] = {
{ SEC_ASN1_CHOICE,
- offsetof(NSSCMSSignerIdentifier,identifierType), NULL,
- sizeof(NSSCMSSignerIdentifier) },
+ 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 },
+ 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 },
+ offsetof(NSSCMSSignerIdentifier, id.issuerAndSN),
+ SEC_ASN1_SUB(CERT_IssuerAndSNTemplate),
+ NSSCMSRecipientID_IssuerSN },
{ 0 }
};
@@ -142,26 +140,26 @@ static const SEC_ASN1Template NSSCMSSignerIdentifierTemplate[] = {
const SEC_ASN1Template NSSCMSSignerInfoTemplate[] = {
{ SEC_ASN1_SEQUENCE,
- 0, NULL, sizeof(NSSCMSSignerInfo) },
+ 0, NULL, sizeof(NSSCMSSignerInfo) },
{ SEC_ASN1_INTEGER,
- offsetof(NSSCMSSignerInfo,version) },
+ offsetof(NSSCMSSignerInfo, version) },
{ SEC_ASN1_INLINE,
- offsetof(NSSCMSSignerInfo,signerIdentifier),
- NSSCMSSignerIdentifierTemplate },
+ offsetof(NSSCMSSignerInfo, signerIdentifier),
+ NSSCMSSignerIdentifierTemplate },
{ SEC_ASN1_INLINE | SEC_ASN1_XTRN,
- offsetof(NSSCMSSignerInfo,digestAlg),
- SEC_ASN1_SUB(SECOID_AlgorithmIDTemplate) },
+ 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 },
+ offsetof(NSSCMSSignerInfo, authAttr),
+ nss_cms_set_of_attribute_template },
{ SEC_ASN1_INLINE | SEC_ASN1_XTRN,
- offsetof(NSSCMSSignerInfo,digestEncAlg),
- SEC_ASN1_SUB(SECOID_AlgorithmIDTemplate) },
+ offsetof(NSSCMSSignerInfo, digestEncAlg),
+ SEC_ASN1_SUB(SECOID_AlgorithmIDTemplate) },
{ SEC_ASN1_OCTET_STRING,
- offsetof(NSSCMSSignerInfo,encDigest) },
+ offsetof(NSSCMSSignerInfo, encDigest) },
{ SEC_ASN1_OPTIONAL | SEC_ASN1_CONSTRUCTED | SEC_ASN1_CONTEXT_SPECIFIC | 1,
- offsetof(NSSCMSSignerInfo,unAuthAttr),
- nss_cms_set_of_attribute_template },
+ offsetof(NSSCMSSignerInfo, unAuthAttr),
+ nss_cms_set_of_attribute_template },
{ 0 }
};
@@ -171,15 +169,15 @@ const SEC_ASN1Template NSSCMSSignerInfoTemplate[] = {
static const SEC_ASN1Template NSSCMSOriginatorInfoTemplate[] = {
{ SEC_ASN1_SEQUENCE,
- 0, NULL, sizeof(NSSCMSOriginatorInfo) },
+ 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_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) },
+ SEC_ASN1_XTRN | 1,
+ offsetof(NSSCMSOriginatorInfo, crls),
+ SEC_ASN1_SUB(CERT_SetOfSignedCrlTemplate) },
{ 0 }
};
@@ -187,21 +185,22 @@ const SEC_ASN1Template NSSCMSRecipientInfoTemplate[];
const SEC_ASN1Template NSSCMSEnvelopedDataTemplate[] = {
{ SEC_ASN1_SEQUENCE | SEC_ASN1_MAY_STREAM,
- 0, NULL, sizeof(NSSCMSEnvelopedData) },
+ 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 },
+ 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 },
+ offsetof(NSSCMSEnvelopedData, recipientInfos),
+ NSSCMSRecipientInfoTemplate },
{ SEC_ASN1_INLINE,
- offsetof(NSSCMSEnvelopedData,contentInfo),
- NSSCMSEncryptedContentInfoTemplate },
+ offsetof(NSSCMSEnvelopedData, contentInfo),
+ NSSCMSEncryptedContentInfoTemplate },
{ SEC_ASN1_OPTIONAL | SEC_ASN1_CONSTRUCTED | SEC_ASN1_CONTEXT_SPECIFIC | 1,
- offsetof(NSSCMSEnvelopedData,unprotectedAttr),
- nss_cms_set_of_attribute_template },
+ offsetof(NSSCMSEnvelopedData, unprotectedAttr),
+ nss_cms_set_of_attribute_template },
{ 0 }
};
@@ -217,33 +216,32 @@ const SEC_ASN1Template NSS_PointerToCMSEnvelopedDataTemplate[] = {
static const SEC_ASN1Template NSSCMSRecipientIdentifierTemplate[] = {
{ SEC_ASN1_CHOICE,
- offsetof(NSSCMSRecipientIdentifier,identifierType), NULL,
- sizeof(NSSCMSRecipientIdentifier) },
+ 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 },
+ 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 },
+ offsetof(NSSCMSRecipientIdentifier, id.issuerAndSN),
+ SEC_ASN1_SUB(CERT_IssuerAndSNTemplate),
+ NSSCMSRecipientID_IssuerSN },
{ 0 }
};
-
static const SEC_ASN1Template NSSCMSKeyTransRecipientInfoTemplate[] = {
{ SEC_ASN1_SEQUENCE,
- 0, NULL, sizeof(NSSCMSKeyTransRecipientInfo) },
+ 0, NULL, sizeof(NSSCMSKeyTransRecipientInfo) },
{ SEC_ASN1_INTEGER,
- offsetof(NSSCMSKeyTransRecipientInfo,version) },
+ offsetof(NSSCMSKeyTransRecipientInfo, version) },
{ SEC_ASN1_INLINE,
- offsetof(NSSCMSKeyTransRecipientInfo,recipientIdentifier),
- NSSCMSRecipientIdentifierTemplate },
+ offsetof(NSSCMSKeyTransRecipientInfo, recipientIdentifier),
+ NSSCMSRecipientIdentifierTemplate },
{ SEC_ASN1_INLINE | SEC_ASN1_XTRN,
- offsetof(NSSCMSKeyTransRecipientInfo,keyEncAlg),
- SEC_ASN1_SUB(SECOID_AlgorithmIDTemplate) },
+ offsetof(NSSCMSKeyTransRecipientInfo, keyEncAlg),
+ SEC_ASN1_SUB(SECOID_AlgorithmIDTemplate) },
{ SEC_ASN1_OCTET_STRING,
- offsetof(NSSCMSKeyTransRecipientInfo,encKey) },
+ offsetof(NSSCMSKeyTransRecipientInfo, encKey) },
{ 0 }
};
@@ -253,95 +251,93 @@ static const SEC_ASN1Template NSSCMSKeyTransRecipientInfoTemplate[] = {
static const SEC_ASN1Template NSSCMSOriginatorPublicKeyTemplate[] = {
{ SEC_ASN1_SEQUENCE,
- 0, NULL, sizeof(NSSCMSOriginatorPublicKey) },
+ 0, NULL, sizeof(NSSCMSOriginatorPublicKey) },
{ SEC_ASN1_INLINE | SEC_ASN1_XTRN,
- offsetof(NSSCMSOriginatorPublicKey,algorithmIdentifier),
- SEC_ASN1_SUB(SECOID_AlgorithmIDTemplate) },
+ offsetof(NSSCMSOriginatorPublicKey, algorithmIdentifier),
+ SEC_ASN1_SUB(SECOID_AlgorithmIDTemplate) },
{ SEC_ASN1_INLINE | SEC_ASN1_XTRN,
- offsetof(NSSCMSOriginatorPublicKey,publicKey),
- SEC_ASN1_SUB(SEC_BitStringTemplate) },
+ offsetof(NSSCMSOriginatorPublicKey, publicKey),
+ SEC_ASN1_SUB(SEC_BitStringTemplate) },
{ 0 }
};
-
static const SEC_ASN1Template NSSCMSOriginatorIdentifierOrKeyTemplate[] = {
{ SEC_ASN1_CHOICE,
- offsetof(NSSCMSOriginatorIdentifierOrKey,identifierType), NULL,
- sizeof(NSSCMSOriginatorIdentifierOrKey) },
+ offsetof(NSSCMSOriginatorIdentifierOrKey, identifierType), NULL,
+ sizeof(NSSCMSOriginatorIdentifierOrKey) },
{ SEC_ASN1_POINTER | SEC_ASN1_XTRN,
- offsetof(NSSCMSOriginatorIdentifierOrKey,id.issuerAndSN),
- SEC_ASN1_SUB(CERT_IssuerAndSNTemplate),
- NSSCMSOriginatorIDOrKey_IssuerSN },
+ 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_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 },
+ offsetof(NSSCMSOriginatorIdentifierOrKey, id.originatorPublicKey),
+ NSSCMSOriginatorPublicKeyTemplate,
+ NSSCMSOriginatorIDOrKey_OriginatorPublicKey },
{ 0 }
};
const SEC_ASN1Template NSSCMSRecipientKeyIdentifierTemplate[] = {
{ SEC_ASN1_SEQUENCE,
- 0, NULL, sizeof(NSSCMSRecipientKeyIdentifier) },
+ 0, NULL, sizeof(NSSCMSRecipientKeyIdentifier) },
{ SEC_ASN1_OCTET_STRING,
- offsetof(NSSCMSRecipientKeyIdentifier,subjectKeyIdentifier) },
+ offsetof(NSSCMSRecipientKeyIdentifier, subjectKeyIdentifier) },
{ SEC_ASN1_OPTIONAL | SEC_ASN1_OCTET_STRING,
- offsetof(NSSCMSRecipientKeyIdentifier,date) },
+ offsetof(NSSCMSRecipientKeyIdentifier, date) },
{ SEC_ASN1_OPTIONAL | SEC_ASN1_OCTET_STRING,
- offsetof(NSSCMSRecipientKeyIdentifier,other) },
+ offsetof(NSSCMSRecipientKeyIdentifier, other) },
{ 0 }
};
-
static const SEC_ASN1Template NSSCMSKeyAgreeRecipientIdentifierTemplate[] = {
{ SEC_ASN1_CHOICE,
- offsetof(NSSCMSKeyAgreeRecipientIdentifier,identifierType), NULL,
- sizeof(NSSCMSKeyAgreeRecipientIdentifier) },
+ offsetof(NSSCMSKeyAgreeRecipientIdentifier, identifierType), NULL,
+ sizeof(NSSCMSKeyAgreeRecipientIdentifier) },
{ SEC_ASN1_POINTER | SEC_ASN1_XTRN,
- offsetof(NSSCMSKeyAgreeRecipientIdentifier,id.issuerAndSN),
- SEC_ASN1_SUB(CERT_IssuerAndSNTemplate),
- NSSCMSKeyAgreeRecipientID_IssuerSN },
+ 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 },
+ offsetof(NSSCMSKeyAgreeRecipientIdentifier, id.recipientKeyIdentifier),
+ NSSCMSRecipientKeyIdentifierTemplate,
+ NSSCMSKeyAgreeRecipientID_RKeyID },
{ 0 }
};
static const SEC_ASN1Template NSSCMSRecipientEncryptedKeyTemplate[] = {
{ SEC_ASN1_SEQUENCE,
- 0, NULL, sizeof(NSSCMSRecipientEncryptedKey) },
+ 0, NULL, sizeof(NSSCMSRecipientEncryptedKey) },
{ SEC_ASN1_INLINE,
- offsetof(NSSCMSRecipientEncryptedKey,recipientIdentifier),
- NSSCMSKeyAgreeRecipientIdentifierTemplate },
+ offsetof(NSSCMSRecipientEncryptedKey, recipientIdentifier),
+ NSSCMSKeyAgreeRecipientIdentifierTemplate },
{ SEC_ASN1_INLINE | SEC_ASN1_XTRN,
- offsetof(NSSCMSRecipientEncryptedKey,encKey),
- SEC_ASN1_SUB(SEC_BitStringTemplate) },
+ offsetof(NSSCMSRecipientEncryptedKey, encKey),
+ SEC_ASN1_SUB(SEC_BitStringTemplate) },
{ 0 }
};
static const SEC_ASN1Template NSSCMSKeyAgreeRecipientInfoTemplate[] = {
{ SEC_ASN1_SEQUENCE,
- 0, NULL, sizeof(NSSCMSKeyAgreeRecipientInfo) },
+ 0, NULL, sizeof(NSSCMSKeyAgreeRecipientInfo) },
{ SEC_ASN1_INTEGER,
- offsetof(NSSCMSKeyAgreeRecipientInfo,version) },
+ offsetof(NSSCMSKeyAgreeRecipientInfo, version) },
{ SEC_ASN1_EXPLICIT | SEC_ASN1_CONSTRUCTED | SEC_ASN1_CONTEXT_SPECIFIC | 0,
- offsetof(NSSCMSKeyAgreeRecipientInfo,originatorIdentifierOrKey),
- NSSCMSOriginatorIdentifierOrKeyTemplate },
+ 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_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) },
+ offsetof(NSSCMSKeyAgreeRecipientInfo, keyEncAlg),
+ SEC_ASN1_SUB(SECOID_AlgorithmIDTemplate) },
{ SEC_ASN1_SEQUENCE_OF,
- offsetof(NSSCMSKeyAgreeRecipientInfo,recipientEncryptedKeys),
- NSSCMSRecipientEncryptedKeyTemplate },
+ offsetof(NSSCMSKeyAgreeRecipientInfo, recipientEncryptedKeys),
+ NSSCMSRecipientEncryptedKeyTemplate },
{ 0 }
};
@@ -351,29 +347,29 @@ static const SEC_ASN1Template NSSCMSKeyAgreeRecipientInfoTemplate[] = {
static const SEC_ASN1Template NSSCMSKEKIdentifierTemplate[] = {
{ SEC_ASN1_SEQUENCE,
- 0, NULL, sizeof(NSSCMSKEKIdentifier) },
+ 0, NULL, sizeof(NSSCMSKEKIdentifier) },
{ SEC_ASN1_OCTET_STRING,
- offsetof(NSSCMSKEKIdentifier,keyIdentifier) },
+ offsetof(NSSCMSKEKIdentifier, keyIdentifier) },
{ SEC_ASN1_OPTIONAL | SEC_ASN1_OCTET_STRING,
- offsetof(NSSCMSKEKIdentifier,date) },
+ offsetof(NSSCMSKEKIdentifier, date) },
{ SEC_ASN1_OPTIONAL | SEC_ASN1_OCTET_STRING,
- offsetof(NSSCMSKEKIdentifier,other) },
+ offsetof(NSSCMSKEKIdentifier, other) },
{ 0 }
};
static const SEC_ASN1Template NSSCMSKEKRecipientInfoTemplate[] = {
{ SEC_ASN1_SEQUENCE,
- 0, NULL, sizeof(NSSCMSKEKRecipientInfo) },
+ 0, NULL, sizeof(NSSCMSKEKRecipientInfo) },
{ SEC_ASN1_INTEGER,
- offsetof(NSSCMSKEKRecipientInfo,version) },
+ offsetof(NSSCMSKEKRecipientInfo, version) },
{ SEC_ASN1_INLINE,
- offsetof(NSSCMSKEKRecipientInfo,kekIdentifier),
- NSSCMSKEKIdentifierTemplate },
+ offsetof(NSSCMSKEKRecipientInfo, kekIdentifier),
+ NSSCMSKEKIdentifierTemplate },
{ SEC_ASN1_INLINE | SEC_ASN1_XTRN,
- offsetof(NSSCMSKEKRecipientInfo,keyEncAlg),
- SEC_ASN1_SUB(SECOID_AlgorithmIDTemplate) },
+ offsetof(NSSCMSKEKRecipientInfo, keyEncAlg),
+ SEC_ASN1_SUB(SECOID_AlgorithmIDTemplate) },
{ SEC_ASN1_OCTET_STRING,
- offsetof(NSSCMSKEKRecipientInfo,encKey) },
+ offsetof(NSSCMSKEKRecipientInfo, encKey) },
{ 0 }
};
@@ -382,20 +378,20 @@ static const SEC_ASN1Template NSSCMSKEKRecipientInfoTemplate[] = {
*/
const SEC_ASN1Template NSSCMSRecipientInfoTemplate[] = {
{ SEC_ASN1_CHOICE,
- offsetof(NSSCMSRecipientInfo,recipientInfoType), NULL,
- sizeof(NSSCMSRecipientInfo) },
+ offsetof(NSSCMSRecipientInfo, recipientInfoType), NULL,
+ sizeof(NSSCMSRecipientInfo) },
{ SEC_ASN1_EXPLICIT | SEC_ASN1_CONSTRUCTED | SEC_ASN1_CONTEXT_SPECIFIC | 1,
- offsetof(NSSCMSRecipientInfo,ri.keyAgreeRecipientInfo),
- NSSCMSKeyAgreeRecipientInfoTemplate,
- NSSCMSRecipientInfoID_KeyAgree },
+ 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 },
+ offsetof(NSSCMSRecipientInfo, ri.kekRecipientInfo),
+ NSSCMSKEKRecipientInfoTemplate,
+ NSSCMSRecipientInfoID_KEK },
{ SEC_ASN1_INLINE,
- offsetof(NSSCMSRecipientInfo,ri.keyTransRecipientInfo),
- NSSCMSKeyTransRecipientInfoTemplate,
- NSSCMSRecipientInfoID_KeyTrans },
+ offsetof(NSSCMSRecipientInfo, ri.keyTransRecipientInfo),
+ NSSCMSKeyTransRecipientInfoTemplate,
+ NSSCMSRecipientInfoID_KeyTrans },
{ 0 }
};
@@ -405,17 +401,17 @@ const SEC_ASN1Template NSSCMSRecipientInfoTemplate[] = {
const SEC_ASN1Template NSSCMSDigestedDataTemplate[] = {
{ SEC_ASN1_SEQUENCE | SEC_ASN1_MAY_STREAM,
- 0, NULL, sizeof(NSSCMSDigestedData) },
+ 0, NULL, sizeof(NSSCMSDigestedData) },
{ SEC_ASN1_INTEGER,
- offsetof(NSSCMSDigestedData,version) },
+ offsetof(NSSCMSDigestedData, version) },
{ SEC_ASN1_INLINE | SEC_ASN1_XTRN,
- offsetof(NSSCMSDigestedData,digestAlg),
- SEC_ASN1_SUB(SECOID_AlgorithmIDTemplate) },
+ offsetof(NSSCMSDigestedData, digestAlg),
+ SEC_ASN1_SUB(SECOID_AlgorithmIDTemplate) },
{ SEC_ASN1_INLINE,
- offsetof(NSSCMSDigestedData,contentInfo),
- NSSCMSEncapsulatedContentInfoTemplate },
+ offsetof(NSSCMSDigestedData, contentInfo),
+ NSSCMSEncapsulatedContentInfoTemplate },
{ SEC_ASN1_OCTET_STRING,
- offsetof(NSSCMSDigestedData,digest) },
+ offsetof(NSSCMSDigestedData, digest) },
{ 0 }
};
@@ -425,15 +421,15 @@ const SEC_ASN1Template NSS_PointerToCMSDigestedDataTemplate[] = {
const SEC_ASN1Template NSSCMSEncryptedDataTemplate[] = {
{ SEC_ASN1_SEQUENCE | SEC_ASN1_MAY_STREAM,
- 0, NULL, sizeof(NSSCMSEncryptedData) },
+ 0, NULL, sizeof(NSSCMSEncryptedData) },
{ SEC_ASN1_INTEGER,
- offsetof(NSSCMSEncryptedData,version) },
+ offsetof(NSSCMSEncryptedData, version) },
{ SEC_ASN1_INLINE,
- offsetof(NSSCMSEncryptedData,contentInfo),
- NSSCMSEncryptedContentInfoTemplate },
+ offsetof(NSSCMSEncryptedData, contentInfo),
+ NSSCMSEncryptedContentInfoTemplate },
{ SEC_ASN1_OPTIONAL | SEC_ASN1_CONSTRUCTED | SEC_ASN1_CONTEXT_SPECIFIC | 1,
- offsetof(NSSCMSEncryptedData,unprotectedAttr),
- nss_cms_set_of_attribute_template },
+ offsetof(NSSCMSEncryptedData, unprotectedAttr),
+ nss_cms_set_of_attribute_template },
{ 0 }
};
@@ -443,8 +439,8 @@ const SEC_ASN1Template NSS_PointerToCMSEncryptedDataTemplate[] = {
const SEC_ASN1Template NSSCMSGenericWrapperDataTemplate[] = {
{ SEC_ASN1_INLINE,
- offsetof(NSSCMSGenericWrapperData,contentInfo),
- NSSCMSEncapsulatedContentInfoTemplate },
+ offsetof(NSSCMSGenericWrapperData, contentInfo),
+ NSSCMSEncapsulatedContentInfoTemplate },
};
SEC_ASN1_CHOOSER_IMPLEMENT(NSSCMSGenericWrapperDataTemplate)
@@ -465,31 +461,31 @@ nss_cms_choose_content_template(void *src_or_dest, PRBool encoding)
NSSCMSContentInfo *cinfo;
SECOidTag type;
- PORT_Assert (src_or_dest != NULL);
+ PORT_Assert(src_or_dest != NULL);
if (src_or_dest == NULL)
- return 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;
+ 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/nss/lib/smime/cmsattr.c b/nss/lib/smime/cmsattr.c
index 253abe9..c1ec760 100644
--- a/nss/lib/smime/cmsattr.c
+++ b/nss/lib/smime/cmsattr.c
@@ -25,7 +25,6 @@
* to external naming convention, and move them elsewhere!
*/
-
/*
* NSS_CMSAttribute_Create - create an attribute
*
@@ -33,44 +32,45 @@
* with NSS_CMSAttribute_AddValue.
*/
NSSCMSAttribute *
-NSS_CMSAttribute_Create(PLArenaPool *poolp, SECOidTag oidtag, SECItem *value, PRBool encoded)
+NSS_CMSAttribute_Create(PLArenaPool *poolp, SECOidTag oidtag, SECItem *value,
+ PRBool encoded)
{
NSSCMSAttribute *attr;
SECItem *copiedvalue;
void *mark;
- PORT_Assert (poolp != NULL);
+ PORT_Assert(poolp != NULL);
- mark = PORT_ArenaMark (poolp);
+ mark = PORT_ArenaMark(poolp);
attr = (NSSCMSAttribute *)PORT_ArenaZAlloc(poolp, sizeof(NSSCMSAttribute));
if (attr == NULL)
- goto loser;
+ goto loser;
attr->typeTag = SECOID_FindOIDByTag(oidtag);
if (attr->typeTag == NULL)
- goto loser;
+ goto loser;
if (SECITEM_CopyItem(poolp, &(attr->type), &(attr->typeTag->oid)) != SECSuccess)
- goto loser;
+ goto loser;
if (value != NULL) {
- if ((copiedvalue = SECITEM_ArenaDupItem(poolp, value)) == NULL)
- goto loser;
+ if ((copiedvalue = SECITEM_ArenaDupItem(poolp, value)) == NULL)
+ goto loser;
- if (NSS_CMSArray_Add(poolp, (void ***)&(attr->values), (void *)copiedvalue) != SECSuccess)
- goto loser;
+ if (NSS_CMSArray_Add(poolp, (void ***)&(attr->values), (void *)copiedvalue) != SECSuccess)
+ goto loser;
}
attr->encoded = encoded;
- PORT_ArenaUnmark (poolp, mark);
+ PORT_ArenaUnmark(poolp, mark);
return attr;
loser:
- PORT_Assert (mark != NULL);
- PORT_ArenaRelease (poolp, mark);
+ PORT_Assert(mark != NULL);
+ PORT_ArenaRelease(poolp, mark);
return NULL;
}
@@ -83,27 +83,27 @@ NSS_CMSAttribute_AddValue(PLArenaPool *poolp, NSSCMSAttribute *attr, SECItem *va
SECItem *copiedvalue;
void *mark;
- PORT_Assert (poolp != NULL);
+ PORT_Assert(poolp != NULL);
mark = PORT_ArenaMark(poolp);
if (value == NULL) {
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- goto loser;
+ PORT_SetError(SEC_ERROR_INVALID_ARGS);
+ goto loser;
}
if ((copiedvalue = SECITEM_ArenaDupItem(poolp, value)) == NULL)
- goto loser;
+ goto loser;
if (NSS_CMSArray_Add(poolp, (void ***)&(attr->values), (void *)copiedvalue) != SECSuccess)
- goto loser;
+ goto loser;
PORT_ArenaUnmark(poolp, mark);
return SECSuccess;
loser:
- PORT_Assert (mark != NULL);
- PORT_ArenaRelease (poolp, mark);
+ PORT_Assert(mark != NULL);
+ PORT_ArenaRelease(poolp, mark);
return SECFailure;
}
@@ -117,7 +117,7 @@ NSS_CMSAttribute_GetType(NSSCMSAttribute *attr)
typetag = SECOID_FindOID(&(attr->type));
if (typetag == NULL)
- return SEC_OID_UNKNOWN;
+ return SEC_OID_UNKNOWN;
return typetag->offset;
}
@@ -135,15 +135,15 @@ NSS_CMSAttribute_GetValue(NSSCMSAttribute *attr)
SECItem *value;
if (attr == NULL)
- return NULL;
+ return NULL;
value = attr->values[0];
if (value == NULL || value->data == NULL || value->len == 0)
- return NULL;
+ return NULL;
if (attr->values[1] != NULL)
- return NULL;
+ return NULL;
return value;
}
@@ -155,14 +155,14 @@ PRBool
NSS_CMSAttribute_CompareValue(NSSCMSAttribute *attr, SECItem *av)
{
SECItem *value;
-
+
if (attr == NULL)
- return PR_FALSE;
+ return PR_FALSE;
value = NSS_CMSAttribute_GetValue(attr);
return (value != NULL && value->len == av->len &&
- PORT_Memcmp (value->data, av->data, value->len) == 0);
+ PORT_Memcmp(value->data, av->data, value->len) == 0);
}
/*
@@ -182,14 +182,14 @@ cms_attr_choose_attr_value_template(void *src_or_dest, PRBool encoding)
SECOidData *oiddata;
PRBool encoded;
- PORT_Assert (src_or_dest != NULL);
+ PORT_Assert(src_or_dest != NULL);
if (src_or_dest == NULL)
- return NULL;
+ return NULL;
attribute = (NSSCMSAttribute *)src_or_dest;
if (encoding && (!attribute->values || !attribute->values[0] ||
- attribute->encoded)) {
+ attribute->encoded)) {
/* we're encoding, and the attribute has no value or the attribute
* value is already encoded. */
return SEC_ASN1_GET(SEC_AnyTemplate);
@@ -198,77 +198,76 @@ cms_attr_choose_attr_value_template(void *src_or_dest, PRBool encoding)
/* get attribute's typeTag */
oiddata = attribute->typeTag;
if (oiddata == NULL) {
- oiddata = SECOID_FindOID(&attribute->type);
- attribute->typeTag = oiddata;
+ 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);
+ /* 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 */
- }
+ 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);
+ /*
+ * 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;
+ /*
+ * 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;
+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) },
+ 0, NULL, sizeof(NSSCMSAttribute) },
{ SEC_ASN1_OBJECT_ID,
- offsetof(NSSCMSAttribute,type) },
+ offsetof(NSSCMSAttribute, type) },
{ SEC_ASN1_DYNAMIC | SEC_ASN1_SET_OF,
- offsetof(NSSCMSAttribute,values),
- &cms_attr_chooser },
+ offsetof(NSSCMSAttribute, values),
+ &cms_attr_chooser },
{ 0 }
};
@@ -292,7 +291,7 @@ const SEC_ASN1Template nss_cms_set_of_attribute_template[] = {
SECItem *
NSS_CMSAttributeArray_Encode(PLArenaPool *poolp, NSSCMSAttribute ***attrs, SECItem *dest)
{
- return SEC_ASN1EncodeItem (poolp, dest, (void *)attrs, nss_cms_set_of_attribute_template);
+ return SEC_ASN1EncodeItem(poolp, dest, (void *)attrs, nss_cms_set_of_attribute_template);
}
/*
@@ -323,44 +322,43 @@ NSS_CMSAttributeArray_FindAttrByOidTag(NSSCMSAttribute **attrs, SECOidTag oidtag
NSSCMSAttribute *attr1, *attr2;
if (attrs == NULL)
- return NULL;
+ return NULL;
oid = SECOID_FindOIDByTag(oidtag);
if (oid == NULL)
- return 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->type.len == oid->oid.len &&
+ PORT_Memcmp(attr1->type.data, oid->oid.data, oid->oid.len) == 0)
+ break;
}
if (attr1 == NULL)
- return NULL;
+ return NULL;
if (!only)
- return attr1;
+ 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->type.len == oid->oid.len &&
+ PORT_Memcmp(attr2->type.data, oid->oid.data, oid->oid.len) == 0)
+ break;
}
if (attr2 != NULL)
- return NULL;
+ return NULL;
return attr1;
}
/*
* NSS_CMSAttributeArray_AddAttr - add an attribute to an
- * array of attributes.
+ * array of attributes.
*/
SECStatus
-NSS_CMSAttributeArray_AddAttr(PLArenaPool *poolp, NSSCMSAttribute ***attrs, NSSCMSAttribute *attr)
+NSS_CMSAttributeArray_AddAttr(PLArenaPool *poolp, NSSCMSAttribute ***attrs,
+ NSSCMSAttribute *attr)
{
NSSCMSAttribute *oattr;
void *mark;
@@ -373,13 +371,13 @@ NSS_CMSAttributeArray_AddAttr(PLArenaPool *poolp, NSSCMSAttribute ***attrs, NSSC
/* see if we have one already */
oattr = NSS_CMSAttributeArray_FindAttrByOidTag(*attrs, type, PR_FALSE);
- PORT_Assert (oattr == NULL);
+ PORT_Assert(oattr == NULL);
if (oattr != NULL)
- goto loser; /* XXX or would it be better to replace it? */
+ 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;
+ goto loser;
PORT_ArenaUnmark(poolp, mark);
return SECSuccess;
@@ -393,7 +391,8 @@ loser:
* 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)
+NSS_CMSAttributeArray_SetAttr(PLArenaPool *poolp, NSSCMSAttribute ***attrs,
+ SECOidTag type, SECItem *value, PRBool encoded)
{
NSSCMSAttribute *attr;
void *mark;
@@ -403,25 +402,24 @@ NSS_CMSAttributeArray_SetAttr(PLArenaPool *poolp, NSSCMSAttribute ***attrs, SECO
/* 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;
+ /* 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;
+ /* found, shove it in */
+ /* XXX we need a decent memory model @#$#$!#!!! */
+ attr->values[0] = value;
+ attr->encoded = encoded;
}
- PORT_ArenaUnmark (poolp, mark);
+ PORT_ArenaUnmark(poolp, mark);
return SECSuccess;
loser:
- PORT_ArenaRelease (poolp, mark);
+ PORT_ArenaRelease(poolp, mark);
return SECFailure;
}
-
diff --git a/nss/lib/smime/cmscinfo.c b/nss/lib/smime/cmscinfo.c
index b6f1d0a..08db662 100644
--- a/nss/lib/smime/cmscinfo.c
+++ b/nss/lib/smime/cmscinfo.c
@@ -13,7 +13,6 @@
#include "secoid.h"
#include "secerr.h"
-
/*
* NSS_CMSContentInfo_Create - create a content info
*
@@ -23,24 +22,23 @@ SECStatus
NSS_CMSContentInfo_Private_Init(NSSCMSContentInfo *cinfo)
{
if (cinfo->privateInfo) {
- return SECSuccess;
+ 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;
+ /* must destroy digest objects */
+ NSS_CMSDigestContext_Cancel(privateInfo->digcx);
+ privateInfo->digcx = NULL;
}
if (privateInfo->ciphcx) {
- NSS_CMSCipherContext_Destroy(privateInfo->ciphcx);
- privateInfo->ciphcx = NULL;
+ NSS_CMSCipherContext_Destroy(privateInfo->ciphcx);
+ privateInfo->ciphcx = NULL;
}
PORT_Free(privateInfo);
}
@@ -55,29 +53,29 @@ NSS_CMSContentInfo_Destroy(NSSCMSContentInfo *cinfo)
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;
+ 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;
+ nss_cmsContentInfo_private_destroy(cinfo->privateInfo);
+ cinfo->privateInfo = NULL;
}
if (cinfo->bulkkey) {
- PK11_FreeSymKey(cinfo->bulkkey);
+ PK11_FreeSymKey(cinfo->bulkkey);
}
}
@@ -87,40 +85,40 @@ NSS_CMSContentInfo_Destroy(NSSCMSContentInfo *cinfo)
NSSCMSContentInfo *
NSS_CMSContentInfo_GetChildContentInfo(NSSCMSContentInfo *cinfo)
{
- NSSCMSContentInfo * ccinfo = NULL;
+ 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;
+ 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);
+ NSS_CMSContentInfo_Private_Init(ccinfo);
}
return ccinfo;
}
@@ -128,47 +126,48 @@ NSS_CMSContentInfo_GetChildContentInfo(NSSCMSContentInfo *cinfo)
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;
+ 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)
+NSS_CMSContentInfo_SetContent(NSSCMSMessage *cmsg, NSSCMSContentInfo *cinfo,
+ SECOidTag type, void *ptr)
{
SECStatus rv;
cinfo->contentTypeTag = SECOID_FindOIDByTag(type);
if (cinfo->contentTypeTag == NULL)
- return SECFailure;
-
+ return SECFailure;
+
/* do not copy the oid, just create a reference */
- rv = SECITEM_CopyItem (cmsg->poolp, &(cinfo->contentType), &(cinfo->contentTypeTag->oid));
+ rv = SECITEM_CopyItem(cmsg->poolp, &(cinfo->contentType), &(cinfo->contentTypeTag->oid));
if (rv != SECSuccess)
- return SECFailure;
+ return SECFailure;
cinfo->content.pointer = ptr;
if (NSS_CMSType_IsData(type) && ptr) {
- cinfo->rawContent = 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;
- }
+ /* 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;
@@ -183,42 +182,46 @@ NSS_CMSContentInfo_SetContent(NSSCMSMessage *cmsg, NSSCMSContentInfo *cinfo, SEC
* data != NULL -> take this data
*/
SECStatus
-NSS_CMSContentInfo_SetContent_Data(NSSCMSMessage *cmsg, NSSCMSContentInfo *cinfo, SECItem *data, PRBool detached)
+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;
+ return SECFailure;
if (detached) {
cinfo->rawContent = NULL;
}
-
+
return SECSuccess;
}
SECStatus
-NSS_CMSContentInfo_SetContent_SignedData(NSSCMSMessage *cmsg, NSSCMSContentInfo *cinfo, NSSCMSSignedData *sigd)
+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)
+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)
+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)
+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
*
@@ -227,22 +230,24 @@ NSS_CMSContentInfo_SetContent_EncryptedData(NSSCMSMessage *cmsg, NSSCMSContentIn
void *
NSS_CMSContentInfo_GetContent(NSSCMSContentInfo *cinfo)
{
- SECOidTag tag = cinfo->contentTypeTag
- ? cinfo->contentTypeTag->offset
- : SEC_OID_UNKNOWN;
+ SECOidTag tag = 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);
+ 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()
@@ -252,25 +257,24 @@ SECItem *
NSS_CMSContentInfo_GetInnerContent(NSSCMSContentInfo *cinfo)
{
NSSCMSContentInfo *ccinfo;
- SECOidTag tag;
- SECItem *pItem = NULL;
+ SECOidTag tag;
+ SECItem *pItem = NULL;
tag = NSS_CMSContentInfo_GetContentTypeTag(cinfo);
if (NSS_CMSType_IsData(tag)) {
- pItem = cinfo->content.data;
+ pItem = cinfo->content.data;
} else if (NSS_CMSType_IsWrapper(tag)) {
- ccinfo = NSS_CMSContentInfo_GetChildContentInfo(cinfo);
- if (ccinfo != NULL) {
- pItem = NSS_CMSContentInfo_GetContent(ccinfo);
- }
+ ccinfo = NSS_CMSContentInfo_GetChildContentInfo(cinfo);
+ if (ccinfo != NULL) {
+ pItem = NSS_CMSContentInfo_GetContent(ccinfo);
+ }
} else {
- PORT_Assert(0);
+ 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.
@@ -279,10 +283,10 @@ SECOidTag
NSS_CMSContentInfo_GetContentTypeTag(NSSCMSContentInfo *cinfo)
{
if (cinfo->contentTypeTag == NULL)
- cinfo->contentTypeTag = SECOID_FindOID(&(cinfo->contentType));
+ cinfo->contentTypeTag = SECOID_FindOID(&(cinfo->contentType));
if (cinfo->contentTypeTag == NULL)
- return SEC_OID_UNKNOWN;
+ return SEC_OID_UNKNOWN;
return cinfo->contentTypeTag->offset;
}
@@ -291,10 +295,10 @@ SECItem *
NSS_CMSContentInfo_GetContentTypeOID(NSSCMSContentInfo *cinfo)
{
if (cinfo->contentTypeTag == NULL)
- cinfo->contentTypeTag = SECOID_FindOID(&(cinfo->contentType));
+ cinfo->contentTypeTag = SECOID_FindOID(&(cinfo->contentType));
if (cinfo->contentTypeTag == NULL)
- return NULL;
+ return NULL;
return &(cinfo->contentTypeTag->oid);
}
@@ -307,7 +311,7 @@ SECOidTag
NSS_CMSContentInfo_GetContentEncAlgTag(NSSCMSContentInfo *cinfo)
{
if (cinfo->contentEncAlgTag == SEC_OID_UNKNOWN)
- cinfo->contentEncAlgTag = SECOID_GetAlgorithmTag(&(cinfo->contentEncAlg));
+ cinfo->contentEncAlgTag = SECOID_GetAlgorithmTag(&(cinfo->contentEncAlg));
return cinfo->contentEncAlgTag;
}
@@ -323,28 +327,28 @@ NSS_CMSContentInfo_GetContentEncAlg(NSSCMSContentInfo *cinfo)
SECStatus
NSS_CMSContentInfo_SetContentEncAlg(PLArenaPool *poolp, NSSCMSContentInfo *cinfo,
- SECOidTag bulkalgtag, SECItem *parameters, int keysize)
+ SECOidTag bulkalgtag, SECItem *parameters, int keysize)
{
SECStatus rv;
rv = SECOID_SetAlgorithmID(poolp, &(cinfo->contentEncAlg), bulkalgtag, parameters);
if (rv != SECSuccess)
- return SECFailure;
+ return SECFailure;
cinfo->keysize = keysize;
return SECSuccess;
}
SECStatus
NSS_CMSContentInfo_SetContentEncAlgID(PLArenaPool *poolp, NSSCMSContentInfo *cinfo,
- SECAlgorithmID *algid, int keysize)
+ SECAlgorithmID *algid, int keysize)
{
SECStatus rv;
rv = SECOID_CopyAlgorithmID(poolp, &(cinfo->contentEncAlg), algid);
if (rv != SECSuccess)
- return SECFailure;
+ return SECFailure;
if (keysize >= 0)
- cinfo->keysize = keysize;
+ cinfo->keysize = keysize;
return SECSuccess;
}
@@ -359,7 +363,7 @@ PK11SymKey *
NSS_CMSContentInfo_GetBulkKey(NSSCMSContentInfo *cinfo)
{
if (cinfo->bulkkey == NULL)
- return NULL;
+ return NULL;
return PK11_ReferenceSymKey(cinfo->bulkkey);
}
diff --git a/nss/lib/smime/cmscipher.c b/nss/lib/smime/cmscipher.c
index 998ad16..9c8330b 100644
--- a/nss/lib/smime/cmscipher.c
+++ b/nss/lib/smime/cmscipher.c
@@ -19,31 +19,31 @@
* 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);
+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 */
+ 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 */
+ 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
+ * 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.
+ * have two simple cover functions which call it.
*/
NSSCMSCipherContext *
NSS_CMSCipherContext_StartDecrypt(PK11SymKey *key, SECAlgorithmID *algid)
@@ -59,28 +59,28 @@ NSS_CMSCipherContext_StartDecrypt(PK11SymKey *key, SECAlgorithmID *algid)
/* set param and mechanism */
if (SEC_PKCS5IsAlgorithmPBEAlg(algid)) {
- SECItem *pwitem;
+ SECItem *pwitem;
- pwitem = PK11_GetSymKeyUserData(key);
- if (!pwitem)
- return NULL;
+ 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;
- }
+ 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;
+ 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;
+ SECITEM_FreeItem(param, PR_TRUE);
+ return NULL;
}
/* figure out pad and block sizes */
@@ -90,17 +90,17 @@ NSS_CMSCipherContext_StartDecrypt(PK11SymKey *key, SECAlgorithmID *algid)
PK11_FreeSlot(slot);
/* create PK11 cipher context */
- ciphercx = PK11_CreateContextBySymKey(cryptoMechType, CKA_DECRYPT,
- key, param);
+ ciphercx = PK11_CreateContextBySymKey(cryptoMechType, CKA_DECRYPT,
+ key, param);
SECITEM_FreeItem(param, PR_TRUE);
if (ciphercx == NULL) {
- PORT_Free (cc);
- return 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->doit = (nss_cms_cipher_function)PK11_CipherOp;
+ cc->destroy = (nss_cms_cipher_destroy)PK11_DestroyContext;
cc->encrypt = PR_FALSE;
cc->pending_count = 0;
@@ -109,12 +109,12 @@ 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
+ * 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.
+ * have two simple cover functions which call it.
*/
NSSCMSCipherContext *
NSS_CMSCipherContext_StartEncrypt(PLArenaPool *poolp, PK11SymKey *key, SECAlgorithmID *algid)
@@ -130,27 +130,27 @@ NSS_CMSCipherContext_StartEncrypt(PLArenaPool *poolp, PK11SymKey *key, SECAlgori
/* set param and mechanism */
if (SEC_PKCS5IsAlgorithmPBEAlg(algid)) {
- SECItem *pwitem;
+ SECItem *pwitem;
- pwitem = PK11_GetSymKeyUserData(key);
- if (!pwitem)
- return NULL;
+ 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;
- }
+ 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;
+ 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;
+ goto loser;
}
/* now find pad and block sizes for our mechanism */
@@ -160,12 +160,12 @@ NSS_CMSCipherContext_StartEncrypt(PLArenaPool *poolp, PK11SymKey *key, SECAlgori
PK11_FreeSlot(slot);
/* and here we go, creating a PK11 cipher context */
- ciphercx = PK11_CreateContextBySymKey(cryptoMechType, CKA_ENCRYPT,
- key, param);
+ ciphercx = PK11_CreateContextBySymKey(cryptoMechType, CKA_ENCRYPT,
+ key, param);
if (ciphercx == NULL) {
- PORT_Free(cc);
- cc = NULL;
- goto loser;
+ PORT_Free(cc);
+ cc = NULL;
+ goto loser;
}
/*
@@ -177,12 +177,12 @@ NSS_CMSCipherContext_StartEncrypt(PLArenaPool *poolp, PK11SymKey *key, SECAlgori
* 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;
- }
+ rv = PK11_ParamToAlgid(algtag, param, poolp, algid);
+ if (rv != SECSuccess) {
+ PORT_Free(cc);
+ cc = NULL;
+ goto loser;
+ }
}
cc->cx = ciphercx;
@@ -206,7 +206,7 @@ NSS_CMSCipherContext_Destroy(NSSCMSCipherContext *cc)
{
PORT_Assert(cc != NULL);
if (cc == NULL)
- return;
+ return;
(*cc->destroy)(cc->cx, PR_TRUE);
PORT_Free(cc);
}
@@ -237,7 +237,7 @@ NSS_CMSCipherContext_DecryptLength(NSSCMSCipherContext *cc, unsigned int input_l
{
int blocks, block_size;
- PORT_Assert (! cc->encrypt);
+ PORT_Assert(!cc->encrypt);
block_size = cc->block_size;
@@ -246,7 +246,7 @@ NSS_CMSCipherContext_DecryptLength(NSSCMSCipherContext *cc, unsigned int input_l
* number of output bytes as we had input bytes.
*/
if (block_size == 0)
- return input_len;
+ return input_len;
/*
* On the final call, we will always use up all of the pending
@@ -257,7 +257,7 @@ NSS_CMSCipherContext_DecryptLength(NSSCMSCipherContext *cc, unsigned int input_l
* at least 1 byte of padding), but seemed clearer/better to me.
*/
if (final)
- return cc->pending_count + input_len;
+ return cc->pending_count + input_len;
/*
* Okay, this amount is exactly what we will output on the
@@ -296,7 +296,7 @@ NSS_CMSCipherContext_EncryptLength(NSSCMSCipherContext *cc, unsigned int input_l
int blocks, block_size;
int pad_size;
- PORT_Assert (cc->encrypt);
+ PORT_Assert(cc->encrypt);
block_size = cc->block_size;
pad_size = cc->pad_size;
@@ -306,7 +306,7 @@ NSS_CMSCipherContext_EncryptLength(NSSCMSCipherContext *cc, unsigned int input_l
* number of output bytes as we had input bytes.
*/
if (block_size == 0)
- return input_len;
+ return input_len;
/*
* On the final call, we only send out what we need for
@@ -315,13 +315,13 @@ NSS_CMSCipherContext_EncryptLength(NSSCMSCipherContext *cc, unsigned int input_l
* 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;
- }
+ if (pad_size == 0) {
+ return cc->pending_count + input_len;
+ } else {
+ blocks = (cc->pending_count + input_len) / pad_size;
+ blocks++;
+ return blocks * pad_size;
+ }
}
/*
@@ -329,11 +329,9 @@ NSS_CMSCipherContext_EncryptLength(NSSCMSCipherContext *cc, unsigned int input_l
*/
blocks = (cc->pending_count + input_len) / block_size;
-
return blocks * block_size;
}
-
/*
* NSS_CMSCipherContext_Decrypt - do the decryption
*
@@ -363,29 +361,29 @@ NSS_CMSCipherContext_EncryptLength(NSSCMSCipherContext *cc, unsigned int input_l
* 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)
+ unsigned int *output_len_p, unsigned int max_output_len,
+ const unsigned char *input, unsigned int input_len,
+ PRBool final)
{
unsigned int blocks, bsize, pcount, padsize;
unsigned int max_needed, ifraglen, ofraglen, output_len;
unsigned char *pbuf;
SECStatus rv;
- PORT_Assert (! cc->encrypt);
+ 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);
+ PORT_Assert(max_output_len >= max_needed);
if (max_output_len < max_needed) {
- /* PORT_SetError (XXX); */
- return SECFailure;
+ /* PORT_SetError (XXX); */
+ return SECFailure;
}
/*
@@ -400,8 +398,8 @@ NSS_CMSCipherContext_Decrypt(NSSCMSCipherContext *cc, unsigned char *output,
* cipher function and we are done.
*/
if (bsize == 0) {
- return (* cc->doit) (cc->cx, output, output_len_p, max_output_len,
- input, input_len);
+ return (*cc->doit)(cc->cx, output, output_len_p, max_output_len,
+ input, input_len);
}
pcount = cc->pending_count;
@@ -410,63 +408,63 @@ NSS_CMSCipherContext_Decrypt(NSSCMSCipherContext *cc, unsigned char *output,
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;
+ /*
+ * 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
@@ -477,46 +475,47 @@ NSS_CMSCipherContext_Decrypt(NSSCMSCipherContext *cc, unsigned char *output,
* 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;
- }
+ 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);
+ 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;
+ 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;
+ 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;
+ ofraglen = 0;
}
/*
@@ -524,18 +523,18 @@ NSS_CMSCipherContext_Decrypt(NSSCMSCipherContext *cc, unsigned char *output,
* adjusting the output length.
*/
if (final && (padsize != 0)) {
- unsigned int padlen = *(output + ofraglen - 1);
+ unsigned int padlen = *(output + ofraglen - 1);
- if (padlen == 0 || padlen > padsize) {
- PORT_SetError(SEC_ERROR_BAD_DATA);
- return SECFailure;
- }
- output_len -= padlen;
+ 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);
+ PORT_Assert(output_len_p != NULL || output_len == 0);
if (output_len_p != NULL)
- *output_len_p = output_len;
+ *output_len_p = output_len;
return SECSuccess;
}
@@ -574,29 +573,29 @@ NSS_CMSCipherContext_Decrypt(NSSCMSCipherContext *cc, unsigned char *output,
* 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)
+ 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);
+ 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);
+ 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;
+ /* PORT_SetError (XXX); */
+ return SECFailure;
}
bsize = cc->block_size;
@@ -607,8 +606,8 @@ NSS_CMSCipherContext_Encrypt(NSSCMSCipherContext *cc, unsigned char *output,
* cipher function and we are done.
*/
if (bsize == 0) {
- return (*cc->doit)(cc->cx, output, output_len_p, max_output_len,
- input, input_len);
+ return (*cc->doit)(cc->cx, output, output_len_p, max_output_len,
+ input, input_len);
}
pcount = cc->pending_count;
@@ -617,103 +616,107 @@ NSS_CMSCipherContext_Encrypt(NSSCMSCipherContext *cc, unsigned char *output,
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;
- }
+ /*
+ * 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);
+ 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;
+ if (padsize <= 0) {
+ padlen = 0;
+ } else {
+ 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;
+ cc->pending_count = pcount;
}
- PORT_Assert (output_len_p != NULL || output_len == 0);
+ PORT_Assert(output_len_p != NULL || output_len == 0);
if (output_len_p != NULL)
- *output_len_p = output_len;
+ *output_len_p = output_len;
return SECSuccess;
}
diff --git a/nss/lib/smime/cmsdecode.c b/nss/lib/smime/cmsdecode.c
index 0c2ca68..d965111 100644
--- a/nss/lib/smime/cmsdecode.c
+++ b/nss/lib/smime/cmsdecode.c
@@ -17,33 +17,36 @@
#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;
+ 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 */
+ 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 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 void nss_cms_decoder_work_data(NSSCMSDecoderContext *p7dcx,
+ const unsigned char *data,
+ unsigned long len,
+ PRBool final);
static NSSCMSDecoderData *nss_cms_create_decoder_data(PLArenaPool *poolp);
extern const SEC_ASN1Template NSSCMSMessageTemplate[];
@@ -54,9 +57,9 @@ nss_cms_create_decoder_data(PLArenaPool *poolp)
NSSCMSDecoderData *decoderData = NULL;
decoderData = (NSSCMSDecoderData *)
- PORT_ArenaAlloc(poolp,sizeof(NSSCMSDecoderData));
+ PORT_ArenaAlloc(poolp, sizeof(NSSCMSDecoderData));
if (!decoderData) {
- return NULL;
+ return NULL;
}
decoderData->data.data = NULL;
decoderData->data.len = 0;
@@ -64,7 +67,7 @@ nss_cms_create_decoder_data(PLArenaPool *poolp)
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.
@@ -81,106 +84,107 @@ nss_cms_decoder_notify(void *arg, PRBool before, void *dest, int depth)
p7dcx = (NSSCMSDecoderContext *)arg;
rootcinfo = &(p7dcx->cmsg->contentInfo);
- /* XXX error handling: need to set p7dcx->error */
+/* 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);
+#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 */
- }
+ /*
+ * 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);
- }
+ /* 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);
- }
- }
+ 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;
+ /* unsupported or unknown message type - fail gracefully */
+ p7dcx->error = SEC_ERROR_UNSUPPORTED_MESSAGE_TYPE;
}
}
@@ -198,58 +202,58 @@ nss_cms_before_data(NSSCMSDecoderContext *p7dcx)
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);
+ 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;
+ 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;
+ 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;
+ p7dcx->childp7dcx = NULL;
+ return SECSuccess;
}
/* set up inner decoder */
if ((template = NSS_CMSUtil_GetTemplateByTypeTag(childtype)) == NULL)
- return SECFailure;
+ return SECFailure;
childp7dcx = PORT_ZNew(NSSCMSDecoderContext);
if (childp7dcx == NULL)
- return SECFailure;
+ return SECFailure;
mark = PORT_ArenaMark(poolp);
@@ -257,37 +261,37 @@ nss_cms_before_data(NSSCMSDecoderContext *p7dcx)
size = NSS_CMSUtil_GetSizeByTypeTag(childtype);
childp7dcx->content.pointer = (void *)PORT_ArenaZAlloc(poolp, size);
if (childp7dcx->content.pointer == NULL)
- goto loser;
+ 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,
+ childp7dcx->dcx = SEC_ASN1DecoderStart(poolp, childp7dcx->content.pointer,
template);
if (childp7dcx->dcx == NULL)
- goto loser;
+ goto loser;
/* the new decoder needs to notify, too */
- SEC_ASN1DecoderSetNotifyProc(childp7dcx->dcx, nss_cms_decoder_notify,
+ 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->type = childtype; /* our type */
- childp7dcx->cmsg = p7dcx->cmsg; /* backpointer to root message */
+ childp7dcx->cmsg = p7dcx->cmsg; /* backpointer to root message */
- /* should the child decoder encounter real data,
- ** it must give it to the caller
+ /* 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;
+ childp7dcx->first_decoded = PR_TRUE;
}
/* now set up the parent to hand decoded data to the next level decoder */
@@ -300,9 +304,8 @@ nss_cms_before_data(NSSCMSDecoderContext *p7dcx)
loser:
if (mark)
- PORT_ArenaRelease(poolp, mark);
- if (childp7dcx)
- PORT_Free(childp7dcx);
+ PORT_ArenaRelease(poolp, mark);
+ PORT_Free(childp7dcx);
p7dcx->childp7dcx = NULL;
return SECFailure;
}
@@ -319,52 +322,52 @@ nss_cms_after_data(NSSCMSDecoderContext *p7dcx)
/* 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;
+ 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;
+ 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;
@@ -376,31 +379,31 @@ 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;
+ 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;
}
@@ -412,9 +415,9 @@ nss_cms_after_end(NSSCMSDecoderContext *p7dcx)
* 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)
+nss_cms_decoder_work_data(NSSCMSDecoderContext *p7dcx,
+ const unsigned char *data, unsigned long len,
+ PRBool final)
{
NSSCMSContentInfo *cinfo;
unsigned char *buf = NULL;
@@ -429,129 +432,129 @@ nss_cms_decoder_work_data(NSSCMSDecoderContext *p7dcx,
* 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);
+ 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;
+ /* 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;
+ /*
+ * 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 */
+ 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);
+ 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
+ /* 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);
+ (*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;
+ 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);
+ PORT_Free(buf);
}
/*
@@ -563,23 +566,23 @@ loser:
* 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)
+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 */
+ PORT_Assert(len); /* paranoia */
if (len == 0)
- return;
+ return;
- p7dcx = (NSSCMSDecoderContext*)arg;
+ 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_cms_decoder_work_data(p7dcx, (const unsigned char *)data, len,
+ PR_FALSE);
}
/*
@@ -592,35 +595,35 @@ nss_cms_decoder_update_filter (void *arg, const char *data, unsigned long len,
*/
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)
+ 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;
+ return NULL;
- NSS_CMSMessage_SetEncodingParams(cmsg, pwfn, pwfn_arg, decrypt_key_cb,
+ 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;
+ 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;
+ PORT_Free(p7dcx);
+ NSS_CMSMessage_Destroy(cmsg);
+ return NULL;
}
- SEC_ASN1DecoderSetNotifyProc (p7dcx->dcx, nss_cms_decoder_notify, p7dcx);
+ SEC_ASN1DecoderSetNotifyProc(p7dcx->dcx, nss_cms_decoder_notify, p7dcx);
p7dcx->cmsg = cmsg;
p7dcx->type = SEC_OID_UNKNOWN;
@@ -636,51 +639,49 @@ NSS_CMSDecoder_Start(PLArenaPool *poolp,
* NSS_CMSDecoder_Update - feed DER-encoded data to decoder
*/
SECStatus
-NSS_CMSDecoder_Update(NSSCMSDecoderContext *p7dcx, const char *buf,
+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);
+ 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;
+ p7dcx->error = PORT_GetError();
+ PORT_Assert(p7dcx->error);
+ if (p7dcx->error == 0)
+ p7dcx->error = -1;
}
if (p7dcx->error == 0)
- return SECSuccess;
+ return SECSuccess;
/* there has been a problem, let's finish the decoder */
if (p7dcx->dcx != NULL) {
- (void) SEC_ASN1DecoderFinish (p7dcx->dcx);
- p7dcx->dcx = NULL;
+ (void)SEC_ASN1DecoderFinish(p7dcx->dcx);
+ p7dcx->dcx = NULL;
}
- PORT_SetError (p7dcx->error);
+ PORT_SetError(p7dcx->error);
return SECFailure;
}
@@ -692,7 +693,7 @@ void
NSS_CMSDecoder_Cancel(NSSCMSDecoderContext *p7dcx)
{
if (p7dcx->dcx != NULL)
- (void)SEC_ASN1DecoderFinish(p7dcx->dcx);
+ (void)SEC_ASN1DecoderFinish(p7dcx->dcx);
NSS_CMSMessage_Destroy(p7dcx->cmsg);
PORT_Free(p7dcx);
}
@@ -707,12 +708,11 @@ NSS_CMSDecoder_Finish(NSSCMSDecoderContext *p7dcx)
cmsg = p7dcx->cmsg;
- if (p7dcx->dcx == NULL ||
+ 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;
+ nss_cms_after_end(p7dcx) != SECSuccess) {
+ NSS_CMSMessage_Destroy(cmsg); /* get rid of pool if it's ours */
+ cmsg = NULL;
}
PORT_Free(p7dcx);
@@ -721,19 +721,18 @@ NSS_CMSDecoder_Finish(NSSCMSDecoderContext *p7dcx)
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)
+ 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,
+ p7dcx = NSS_CMSDecoder_Start(NULL, cb, cb_arg, pwfn, pwfn_arg,
decrypt_key_cb, decrypt_key_cb_arg);
if (p7dcx == NULL)
- return NULL;
+ return NULL;
NSS_CMSDecoder_Update(p7dcx, (char *)DERmessage->data, DERmessage->len);
return NSS_CMSDecoder_Finish(p7dcx);
}
-
diff --git a/nss/lib/smime/cmsdigdata.c b/nss/lib/smime/cmsdigdata.c
index e37f7f5..9ea2270 100644
--- a/nss/lib/smime/cmsdigdata.c
+++ b/nss/lib/smime/cmsdigdata.c
@@ -34,12 +34,12 @@ NSS_CMSDigestedData_Create(NSSCMSMessage *cmsg, SECAlgorithmID *digestalg)
digd = (NSSCMSDigestedData *)PORT_ArenaZAlloc(poolp, sizeof(NSSCMSDigestedData));
if (digd == NULL)
- goto loser;
+ goto loser;
digd->cmsg = cmsg;
- if (SECOID_CopyAlgorithmID (poolp, &(digd->digestAlg), digestalg) != SECSuccess)
- goto loser;
+ if (SECOID_CopyAlgorithmID(poolp, &(digd->digestAlg), digestalg) != SECSuccess)
+ goto loser;
PORT_ArenaUnmark(poolp, mark);
return digd;
@@ -84,8 +84,8 @@ NSS_CMSDigestedData_Encode_BeforeStart(NSSCMSDigestedData *digd)
version = NSS_CMS_DIGESTED_DATA_VERSION_DATA;
if (!NSS_CMSType_IsData(NSS_CMSContentInfo_GetContentTypeTag(
- &(digd->contentInfo))))
- version = NSS_CMS_DIGESTED_DATA_VERSION_ENCAP;
+ &(digd->contentInfo))))
+ version = NSS_CMS_DIGESTED_DATA_VERSION_ENCAP;
dummy = SEC_ASN1EncodeInteger(digd->cmsg->poolp, &(digd->version), version);
return (dummy == NULL) ? SECFailure : SECSuccess;
@@ -101,17 +101,17 @@ NSS_CMSDigestedData_Encode_BeforeStart(NSSCMSDigestedData *digd)
SECStatus
NSS_CMSDigestedData_Encode_BeforeData(NSSCMSDigestedData *digd)
{
- SECStatus rv =NSS_CMSContentInfo_Private_Init(&digd->contentInfo);
- if (rv != SECSuccess) {
- return SECFailure;
+ 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;
+ /* 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;
}
@@ -129,11 +129,11 @@ 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;
+ 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;
@@ -153,16 +153,16 @@ NSS_CMSDigestedData_Decode_BeforeData(NSSCMSDigestedData *digd)
/* is there a digest algorithm yet? */
if (digd->digestAlg.algorithm.len == 0)
- return SECFailure;
+ return SECFailure;
rv = NSS_CMSContentInfo_Private_Init(&digd->contentInfo);
if (rv != SECSuccess) {
- return SECFailure;
+ return SECFailure;
}
digd->contentInfo.privateInfo->digcx = NSS_CMSDigestContext_StartSingle(&(digd->digestAlg));
if (digd->contentInfo.privateInfo->digcx == NULL)
- return SECFailure;
+ return SECFailure;
return SECSuccess;
}
@@ -180,11 +180,11 @@ 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;
+ 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;
@@ -201,9 +201,9 @@ 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!!!! */
+ /* XXX comparision btw digest & cdigest */
+ /* XXX set status */
+ /* TODO!!!! */
}
return SECSuccess;
diff --git a/nss/lib/smime/cmsdigest.c b/nss/lib/smime/cmsdigest.c
index 7ec282a..64b64a0 100644
--- a/nss/lib/smime/cmsdigest.c
+++ b/nss/lib/smime/cmsdigest.c
@@ -22,20 +22,19 @@ static int stop_on_err = 1;
static int global_num_digests = 0;
#endif
-struct digestPairStr {
- const SECHashObject * digobj;
- void * digcx;
+struct digestPairStr {
+ const SECHashObject *digobj;
+ void *digcx;
};
typedef struct digestPairStr digestPair;
struct NSSCMSDigestContextStr {
- PRBool saw_contents;
- PLArenaPool * pool;
- int digcnt;
- digestPair * digPairs;
+ PRBool saw_contents;
+ PLArenaPool *pool;
+ int digcnt;
+ digestPair *digPairs;
};
-
/*
* NSS_CMSDigestContext_StartMultiple - start digest calculation using all the
* digest algorithms in "digestalgs" in parallel.
@@ -43,7 +42,7 @@ struct NSSCMSDigestContextStr {
NSSCMSDigestContext *
NSS_CMSDigestContext_StartMultiple(SECAlgorithmID **digestalgs)
{
- PLArenaPool * pool;
+ PLArenaPool *pool;
NSSCMSDigestContext *cmsdigcx;
int digcnt;
int i;
@@ -58,68 +57,68 @@ NSS_CMSDigestContext_StartMultiple(SECAlgorithmID **digestalgs)
*/
pool = PORT_NewArena(2048);
if (!pool)
- return NULL;
+ return NULL;
cmsdigcx = PORT_ArenaNew(pool, NSSCMSDigestContext);
if (cmsdigcx == NULL)
- goto loser;
+ goto loser;
cmsdigcx->saw_contents = PR_FALSE;
- cmsdigcx->pool = pool;
+ cmsdigcx->pool = pool;
cmsdigcx->digcnt = digcnt;
cmsdigcx->digPairs = PORT_ArenaZNewArray(pool, digestPair, digcnt);
if (cmsdigcx->digPairs == NULL) {
- goto loser;
+ 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;
+ 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++;
+ 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);
+ PORT_FreeArena(pool, PR_FALSE);
}
return NULL;
}
/*
- * NSS_CMSDigestContext_StartSingle - same as
+ * NSS_CMSDigestContext_StartSingle - same as
* NSS_CMSDigestContext_StartMultiple, but only one algorithm.
*/
NSSCMSDigestContext *
NSS_CMSDigestContext_StartSingle(SECAlgorithmID *digestalg)
{
- SECAlgorithmID *digestalgs[] = { NULL, NULL }; /* fake array */
+ SECAlgorithmID *digestalgs[] = { NULL, NULL }; /* fake array */
digestalgs[0] = digestalg;
return NSS_CMSDigestContext_StartMultiple(digestalgs);
@@ -129,7 +128,7 @@ NSS_CMSDigestContext_StartSingle(SECAlgorithmID *digestalg)
* NSS_CMSDigestContext_Update - feed more data into the digest machine
*/
void
-NSS_CMSDigestContext_Update(NSSCMSDigestContext *cmsdigcx,
+NSS_CMSDigestContext_Update(NSSCMSDigestContext *cmsdigcx,
const unsigned char *data, int len)
{
int i;
@@ -138,9 +137,9 @@ NSS_CMSDigestContext_Update(NSSCMSDigestContext *cmsdigcx,
cmsdigcx->saw_contents = PR_TRUE;
for (i = 0; i < cmsdigcx->digcnt; i++, pair++) {
- if (pair->digcx) {
- (*pair->digobj->update)(pair->digcx, data, len);
- }
+ if (pair->digcx) {
+ (*pair->digobj->update)(pair->digcx, data, len);
+ }
}
}
@@ -154,12 +153,12 @@ NSS_CMSDigestContext_Cancel(NSSCMSDigestContext *cmsdigcx)
digestPair *pair = cmsdigcx->digPairs;
for (i = 0; i < cmsdigcx->digcnt; i++, pair++) {
- if (pair->digcx) {
- (*pair->digobj->destroy)(pair->digcx, PR_TRUE);
+ if (pair->digcx) {
+ (*pair->digobj->destroy)(pair->digcx, PR_TRUE);
#ifdef CMS_FIND_LEAK_MULTIPLE
- --global_num_digests;
+ --global_num_digests;
#endif
- }
+ }
}
#ifdef CMS_FIND_LEAK_MULTIPLE
PORT_Assert(global_num_digests == 0 || !stop_on_err);
@@ -172,52 +171,52 @@ NSS_CMSDigestContext_Cancel(NSSCMSDigestContext *cmsdigcx)
* into an array of SECItems (allocated on poolp)
*/
SECStatus
-NSS_CMSDigestContext_FinishMultiple(NSSCMSDigestContext *cmsdigcx,
+NSS_CMSDigestContext_FinishMultiple(NSSCMSDigestContext *cmsdigcx,
PLArenaPool *poolp,
- SECItem ***digestsp)
+ SECItem ***digestsp)
{
- SECItem ** digests = NULL;
+ SECItem **digests = NULL;
digestPair *pair;
- void * mark;
- int i;
- SECStatus rv;
+ void *mark;
+ int i;
+ SECStatus rv;
/* no contents? do not finish digests */
if (digestsp == NULL || !cmsdigcx->saw_contents) {
- rv = SECSuccess;
- goto cleanup;
+ rv = SECSuccess;
+ goto cleanup;
}
- mark = PORT_ArenaMark (poolp);
+ mark = PORT_ArenaMark(poolp);
/* allocate digest array & SECItems on arena */
- digests = PORT_ArenaNewArray( poolp, SECItem *, cmsdigcx->digcnt + 1);
+ 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;
- }
+ 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);
+ PORT_ArenaUnmark(poolp, mark);
} else
- PORT_ArenaRelease(poolp, mark);
+ PORT_ArenaRelease(poolp, mark);
cleanup:
NSS_CMSDigestContext_Cancel(cmsdigcx);
@@ -225,36 +224,36 @@ cleanup:
** NSS_CMSSignedData_Encode_AfterData depends on this behavior.
*/
if (rv == SECSuccess && digestsp && digests) {
- *digestsp = digests;
+ *digestsp = digests;
}
return rv;
}
/*
- * NSS_CMSDigestContext_FinishSingle - same as
+ * NSS_CMSDigestContext_FinishSingle - same as
* NSS_CMSDigestContext_FinishMultiple, but for one digest.
*/
SECStatus
-NSS_CMSDigestContext_FinishSingle(NSSCMSDigestContext *cmsdigcx,
+NSS_CMSDigestContext_FinishSingle(NSSCMSDigestContext *cmsdigcx,
PLArenaPool *poolp,
- SECItem *digest)
+ SECItem *digest)
{
SECStatus rv = SECFailure;
SECItem **dp;
PLArenaPool *arena = NULL;
if ((arena = PORT_NewArena(1024)) == NULL)
- goto loser;
+ 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]);
+ /* now copy it into poolp */
+ rv = SECITEM_CopyItem(poolp, digest, dp[0]);
}
loser:
if (arena)
- PORT_FreeArena(arena, PR_FALSE);
+ PORT_FreeArena(arena, PR_FALSE);
return rv;
}
diff --git a/nss/lib/smime/cmsencdata.c b/nss/lib/smime/cmsencdata.c
index 61ff6a1..c3a4549 100644
--- a/nss/lib/smime/cmsencdata.c
+++ b/nss/lib/smime/cmsencdata.c
@@ -22,13 +22,13 @@
*
* "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)
+NSS_CMSEncryptedData_Create(NSSCMSMessage *cmsg, SECOidTag algorithm,
+ int keysize)
{
void *mark;
NSSCMSEncryptedData *encd;
@@ -42,34 +42,35 @@ NSS_CMSEncryptedData_Create(NSSCMSMessage *cmsg, SECOidTag algorithm,
encd = PORT_ArenaZNew(poolp, NSSCMSEncryptedData);
if (encd == NULL)
- goto loser;
+ 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);
+ 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);
- }
+ /* 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;
+ goto loser;
PORT_ArenaUnmark(poolp, mark);
return encd;
@@ -116,24 +117,24 @@ NSS_CMSEncryptedData_Encode_BeforeStart(NSSCMSEncryptedData *encd)
NSSCMSContentInfo *cinfo = &(encd->contentInfo);
if (NSS_CMSArray_IsEmpty((void **)encd->unprotectedAttr))
- version = NSS_CMS_ENCRYPTED_DATA_VERSION;
+ version = NSS_CMS_ENCRYPTED_DATA_VERSION;
else
- version = NSS_CMS_ENCRYPTED_DATA_VERSION_UPATTR;
-
- dummy = SEC_ASN1EncodeInteger (encd->cmsg->poolp, &(encd->version), version);
+ version = NSS_CMS_ENCRYPTED_DATA_VERSION_UPATTR;
+
+ dummy = SEC_ASN1EncodeInteger(encd->cmsg->poolp, &(encd->version), version);
if (dummy == NULL)
- return SECFailure;
+ 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));
+ bulkkey = (*encd->cmsg->decrypt_key_cb)(encd->cmsg->decrypt_key_cb_arg,
+ NSS_CMSContentInfo_GetContentEncAlg(cinfo));
if (bulkkey == NULL)
- return SECFailure;
+ return SECFailure;
/* store the bulk key in the contentInfo so that the encoder can find it */
NSS_CMSContentInfo_SetBulkKey(cinfo, bulkkey);
- PK11_FreeSymKey (bulkkey);
+ PK11_FreeSymKey(bulkkey);
return SECSuccess;
}
@@ -154,22 +155,23 @@ NSS_CMSEncryptedData_Encode_BeforeData(NSSCMSEncryptedData *encd)
/* find bulkkey and algorithm - must have been set by NSS_CMSEncryptedData_Encode_BeforeStart */
bulkkey = NSS_CMSContentInfo_GetBulkKey(cinfo);
if (bulkkey == NULL)
- return SECFailure;
+ return SECFailure;
algid = NSS_CMSContentInfo_GetContentEncAlg(cinfo);
if (algid == NULL)
- return SECFailure;
+ return SECFailure;
rv = NSS_CMSContentInfo_Private_Init(cinfo);
if (rv != SECSuccess) {
- return SECFailure;
+ 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);
+ cinfo->privateInfo->ciphcx = NSS_CMSCipherContext_StartEncrypt(encd->cmsg->poolp,
+ bulkkey, algid);
PK11_FreeSymKey(bulkkey);
if (cinfo->privateInfo->ciphcx == NULL)
- return SECFailure;
+ return SECFailure;
return SECSuccess;
}
@@ -181,15 +183,14 @@ 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;
+ 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
*/
@@ -205,26 +206,25 @@ NSS_CMSEncryptedData_Decode_BeforeData(NSSCMSEncryptedData *encd)
bulkalg = NSS_CMSContentInfo_GetContentEncAlg(cinfo);
- if (encd->cmsg->decrypt_key_cb == NULL) /* no callback? no key../ */
- goto loser;
+ 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;
+ /* no success finding a bulk key */
+ goto loser;
NSS_CMSContentInfo_SetBulkKey(cinfo, bulkkey);
rv = NSS_CMSContentInfo_Private_Init(cinfo);
if (rv != SECSuccess) {
- goto loser;
+ 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 */
-
+ goto loser; /* error has been set by NSS_CMSCipherContext_StartDecrypt */
/* we are done with (this) bulkkey now. */
PK11_FreeSymKey(bulkkey);
@@ -242,8 +242,8 @@ 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;
+ NSS_CMSCipherContext_Destroy(encd->contentInfo.privateInfo->ciphcx);
+ encd->contentInfo.privateInfo->ciphcx = NULL;
}
return SECSuccess;
diff --git a/nss/lib/smime/cmsencode.c b/nss/lib/smime/cmsencode.c
index 3025740..a4414e0 100644
--- a/nss/lib/smime/cmsencode.c
+++ b/nss/lib/smime/cmsencode.c
@@ -24,22 +24,23 @@ struct nss_cms_encoder_output {
};
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 */
+ 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_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);
+ const unsigned char *data, unsigned long len,
+ PRBool final, PRBool innermost);
extern const SEC_ASN1Template NSSCMSMessageTemplate[];
@@ -50,7 +51,7 @@ extern const SEC_ASN1Template NSSCMSMessageTemplate[];
*/
static void
nss_cms_encoder_out(void *arg, const char *buf, unsigned long len,
- int depth, SEC_ASN1EncodingPart data_kind)
+ int depth, SEC_ASN1EncodingPart data_kind)
{
struct nss_cms_encoder_output *output = (struct nss_cms_encoder_output *)arg;
unsigned char *dest;
@@ -61,51 +62,53 @@ nss_cms_encoder_out(void *arg, const char *buf, unsigned long len,
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;
+ 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" : "");
+ 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");
+ fprintf(stderr, "\n");
#endif
if (output->outputfn != NULL)
- /* call output callback with DER data */
- output->outputfn(output->outputarg, buf, len);
+ /* 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);
+ /* 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 */
+ if (len) {
+ PORT_Memcpy(output->dest->data + offset, buf, len);
+ }
}
}
@@ -131,7 +134,9 @@ nss_cms_encoder_notify(void *arg, PRBool before, void *dest, int depth)
rootcinfo = &(p7ecx->cmsg->contentInfo);
#ifdef CMSDEBUG
- fprintf(stderr, "%6.6s, dest = 0x%08x, depth = %d\n", before ? "before" : "after", dest, depth);
+ fprintf(stderr, "%6.6s, dest = 0x%08x, depth = %d\n", before ? "before"
+ : "after",
+ dest, depth);
#endif
/*
@@ -139,54 +144,56 @@ nss_cms_encoder_notify(void *arg, PRBool before, void *dest, int depth)
* 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 */
- }
+ 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 */
- }
+ /* 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;
- }
+ /* 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;
+ }
}
}
@@ -204,124 +211,127 @@ nss_cms_before_data(NSSCMSEncoderContext *p7ecx)
/* 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;
- }
+ 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;
+ 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.
- */
+ /* 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);
+ 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);
+ /*
+ * 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) */
+ /* 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;
+ p7ecx->childp7ecx = NULL;
} else {
- /* we do not know this type */
- p7ecx->error = SEC_ERROR_BAD_DER;
+ /* 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;
+ if (childp7ecx->ecx)
+ SEC_ASN1EncoderFinish(childp7ecx->ecx);
+ PORT_Free(childp7ecx);
+ p7ecx->childp7ecx = NULL;
}
return SECFailure;
}
@@ -332,26 +342,27 @@ 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;
+ 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;
}
@@ -364,14 +375,14 @@ nss_cms_after_data(NSSCMSEncoderContext *p7ecx)
*/
static SECStatus
nss_cms_encoder_work_data(NSSCMSEncoderContext *p7ecx, SECItem *dest,
- const unsigned char *data, unsigned long len,
- PRBool final, PRBool innermost)
+ 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 */
+ rv = SECSuccess; /* may as well be optimistic */
/*
* We should really have data to process, or we should be trying
@@ -380,78 +391,80 @@ nss_cms_encoder_work_data(NSSCMSEncoderContext *p7ecx, SECItem *dest,
* 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);
+ 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;
+ /* 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);
+ 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;
+ 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);
+ 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);
- }
+ if (dest != NULL) {
+ dest->data = buf;
+ dest->len = len;
+ } else if (buf != NULL) {
+ PORT_Free(buf);
+ }
}
return rv;
}
@@ -465,7 +478,8 @@ 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);
+ return nss_cms_encoder_work_data(p7ecx, NULL, (const unsigned char *)data,
+ len, PR_FALSE, PR_FALSE);
}
/*
@@ -482,11 +496,11 @@ nss_cms_encoder_update(NSSCMSEncoderContext *p7ecx, const char *data, unsigned l
*/
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)
+ 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;
@@ -494,12 +508,12 @@ NSS_CMSEncoder_Start(NSSCMSMessage *cmsg,
SECOidTag tag;
NSS_CMSMessage_SetEncodingParams(cmsg, pwfn, pwfn_arg, decrypt_key_cb, decrypt_key_cb_arg,
- detached_digestalgs, detached_digests);
+ detached_digestalgs, detached_digests);
p7ecx = (NSSCMSEncoderContext *)PORT_ZAlloc(sizeof(NSSCMSEncoderContext));
if (p7ecx == NULL) {
- PORT_SetError(SEC_ERROR_NO_MEMORY);
- return NULL;
+ PORT_SetError(SEC_ERROR_NO_MEMORY);
+ return NULL;
}
p7ecx->cmsg = cmsg;
@@ -513,39 +527,39 @@ NSS_CMSEncoder_Start(NSSCMSMessage *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;
+ 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;
+ 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));
+ nss_cms_encoder_out, &(p7ecx->output));
if (p7ecx->ecx == NULL) {
- PORT_Free (p7ecx);
- return NULL;
+ PORT_Free(p7ecx);
+ return NULL;
}
p7ecx->ecxupdated = PR_FALSE;
@@ -554,7 +568,7 @@ NSS_CMSEncoder_Start(NSSCMSMessage *cmsg,
* get past the contents bytes.
*/
if (!cinfo->privateInfo || !cinfo->privateInfo->dontStream)
- SEC_ASN1EncoderSetStreaming(p7ecx->ecx);
+ SEC_ASN1EncoderSetStreaming(p7ecx->ecx);
/*
* The notify function will watch for the contents field.
@@ -566,8 +580,8 @@ NSS_CMSEncoder_Start(NSSCMSMessage *cmsg,
* a child encoder). */
p7ecx->ecxupdated = PR_TRUE;
if (SEC_ASN1EncoderUpdate(p7ecx->ecx, NULL, 0) != SECSuccess) {
- PORT_Free (p7ecx);
- return NULL;
+ PORT_Free(p7ecx);
+ return NULL;
}
return p7ecx;
@@ -591,38 +605,39 @@ NSS_CMSEncoder_Update(NSSCMSEncoderContext *p7ecx, const char *data, unsigned lo
SECOidTag childtype;
if (p7ecx->error)
- return SECFailure;
+ 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);
+ /* 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);
+ /* 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;
}
@@ -646,8 +661,13 @@ NSS_CMSEncoder_Cancel(NSSCMSEncoderContext *p7ecx)
* 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 */
+ rv = NSS_CMSEncoder_Cancel(p7ecx->childp7ecx); /* frees p7ecx->childp7ecx */
+ /* remember rv for now */
+#ifdef CMSDEBUG
+ if (rv != SECSuccess) {
+ fprintf(stderr, "Fail to cancel inner encoder\n");
+ }
+#endif
}
/*
@@ -657,7 +677,7 @@ NSS_CMSEncoder_Cancel(NSSCMSEncoderContext *p7ecx)
*/
rv = nss_cms_encoder_work_data(p7ecx, NULL, NULL, 0, PR_TRUE, (p7ecx->childp7ecx == NULL));
if (rv != SECSuccess)
- goto loser;
+ goto loser;
p7ecx->childp7ecx = NULL;
@@ -673,7 +693,7 @@ NSS_CMSEncoder_Cancel(NSSCMSEncoderContext *p7ecx)
loser:
SEC_ASN1EncoderFinish(p7ecx->ecx);
- PORT_Free (p7ecx);
+ PORT_Free(p7ecx);
return rv;
}
@@ -695,19 +715,19 @@ NSS_CMSEncoder_Finish(NSSCMSEncoderContext *p7ecx)
* 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;
+ /* 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;
}
/*
@@ -717,16 +737,16 @@ NSS_CMSEncoder_Finish(NSSCMSEncoderContext *p7ecx)
*/
rv = nss_cms_encoder_work_data(p7ecx, NULL, NULL, 0, PR_TRUE, (p7ecx->childp7ecx == NULL));
if (rv != SECSuccess)
- goto loser;
+ 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;
+ /* 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);
@@ -734,10 +754,10 @@ NSS_CMSEncoder_Finish(NSSCMSEncoderContext *p7ecx)
rv = SEC_ASN1EncoderUpdate(p7ecx->ecx, NULL, 0);
if (p7ecx->error)
- rv = SECFailure;
+ rv = SECFailure;
loser:
SEC_ASN1EncoderFinish(p7ecx->ecx);
- PORT_Free (p7ecx);
+ PORT_Free(p7ecx);
return rv;
}
diff --git a/nss/lib/smime/cmsenvdata.c b/nss/lib/smime/cmsenvdata.c
index 279faff..f2c8e17 100644
--- a/nss/lib/smime/cmsenvdata.c
+++ b/nss/lib/smime/cmsenvdata.c
@@ -34,15 +34,16 @@ NSS_CMSEnvelopedData_Create(NSSCMSMessage *cmsg, SECOidTag algorithm, int keysiz
envd = (NSSCMSEnvelopedData *)PORT_ArenaZAlloc(poolp, sizeof(NSSCMSEnvelopedData));
if (envd == NULL)
- goto loser;
+ goto loser;
envd->cmsg = cmsg;
/* version is set in NSS_CMSEnvelopedData_Encode_BeforeStart() */
- rv = NSS_CMSContentInfo_SetContentEncAlg(poolp, &(envd->contentInfo), algorithm, NULL, keysize);
+ rv = NSS_CMSContentInfo_SetContentEncAlg(poolp, &(envd->contentInfo),
+ algorithm, NULL, keysize);
if (rv != SECSuccess)
- goto loser;
+ goto loser;
PORT_ArenaUnmark(poolp, mark);
return envd;
@@ -62,17 +63,16 @@ NSS_CMSEnvelopedData_Destroy(NSSCMSEnvelopedData *edp)
NSSCMSRecipientInfo *ri;
if (edp == NULL)
- return;
+ return;
recipientinfos = edp->recipientInfos;
if (recipientinfos == NULL)
- return;
+ return;
while ((ri = *recipientinfos++) != NULL)
- NSS_CMSRecipientInfo_Destroy(ri);
-
- NSS_CMSContentInfo_Destroy(&(edp->contentInfo));
+ NSS_CMSRecipientInfo_Destroy(ri);
+ NSS_CMSContentInfo_Destroy(&(edp->contentInfo));
}
/*
@@ -104,11 +104,11 @@ NSS_CMSEnvelopedData_AddRecipient(NSSCMSEnvelopedData *edp, NSSCMSRecipientInfo
rv = NSS_CMSArray_Add(edp->cmsg->poolp, (void ***)&(edp->recipientInfos), (void *)rip);
if (rv != SECSuccess) {
- PORT_ArenaRelease(edp->cmsg->poolp, mark);
- return SECFailure;
+ PORT_ArenaRelease(edp->cmsg->poolp, mark);
+ return SECFailure;
}
- PORT_ArenaUnmark (edp->cmsg->poolp, mark);
+ PORT_ArenaUnmark(edp->cmsg->poolp, mark);
return SECSuccess;
}
@@ -146,65 +146,68 @@ NSS_CMSEnvelopedData_Encode_BeforeStart(NSSCMSEnvelopedData *envd)
recipientinfos = envd->recipientInfos;
if (recipientinfos == NULL) {
- PORT_SetError(SEC_ERROR_BAD_DATA);
+ PORT_SetError(SEC_ERROR_BAD_DATA);
#if 0
- PORT_SetErrorString("Cannot find recipientinfos to encode.");
+ PORT_SetErrorString("Cannot find recipientinfos to encode.");
#endif
- goto loser;
+ goto loser;
}
version = NSS_CMS_ENVELOPED_DATA_VERSION_REG;
if (envd->originatorInfo != NULL || envd->unprotectedAttr != NULL) {
- version = NSS_CMS_ENVELOPED_DATA_VERSION_ADV;
+ 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;
- }
- }
+ 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;
+ 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;
- }
+ 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 */
+ 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);
+ 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 */
+ 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. */
+ 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);
+ rv = NSS_CMSArray_SortByDER((void **)envd->recipientInfos,
+ NSSCMSRecipientInfoTemplate, NULL);
if (rv != SECSuccess)
- goto loser; /* error has been set by NSS_CMSArray_SortByDER */
+ 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);
@@ -217,9 +220,9 @@ NSS_CMSEnvelopedData_Encode_BeforeStart(NSSCMSEnvelopedData *envd)
loser:
if (mark != NULL)
- PORT_ArenaRelease (poolp, mark);
+ PORT_ArenaRelease(poolp, mark);
if (bulkkey)
- PK11_FreeSymKey(bulkkey);
+ PK11_FreeSymKey(bulkkey);
return SECFailure;
}
@@ -243,14 +246,14 @@ NSS_CMSEnvelopedData_Encode_BeforeData(NSSCMSEnvelopedData *envd)
/* find bulkkey and algorithm - must have been set by NSS_CMSEnvelopedData_Encode_BeforeStart */
bulkkey = NSS_CMSContentInfo_GetBulkKey(cinfo);
if (bulkkey == NULL)
- return SECFailure;
+ return SECFailure;
algid = NSS_CMSContentInfo_GetContentEncAlg(cinfo);
if (algid == NULL)
- return SECFailure;
+ return SECFailure;
rv = NSS_CMSContentInfo_Private_Init(cinfo);
if (rv != SECSuccess) {
- return SECFailure;
+ 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
@@ -258,7 +261,7 @@ NSS_CMSEnvelopedData_Encode_BeforeData(NSSCMSEnvelopedData *envd)
cinfo->privateInfo->ciphcx = NSS_CMSCipherContext_StartEncrypt(envd->cmsg->poolp, bulkkey, algid);
PK11_FreeSymKey(bulkkey);
if (cinfo->privateInfo->ciphcx == NULL)
- return SECFailure;
+ return SECFailure;
return SECSuccess;
}
@@ -270,8 +273,8 @@ 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;
+ NSS_CMSCipherContext_Destroy(envd->contentInfo.privateInfo->ciphcx);
+ envd->contentInfo.privateInfo->ciphcx = NULL;
}
/* nothing else to do after data */
@@ -279,7 +282,7 @@ NSS_CMSEnvelopedData_Encode_AfterData(NSSCMSEnvelopedData *envd)
}
/*
- * NSS_CMSEnvelopedData_Decode_BeforeData - find our recipientinfo,
+ * NSS_CMSEnvelopedData_Decode_BeforeData - find our recipientinfo,
* derive bulk key & set up our contentinfo
*/
SECStatus
@@ -296,18 +299,18 @@ NSS_CMSEnvelopedData_Decode_BeforeData(NSSCMSEnvelopedData *envd)
int rlIndex;
if (NSS_CMSArray_Count((void **)envd->recipientInfos) == 0) {
- PORT_SetError(SEC_ERROR_BAD_DATA);
+ PORT_SetError(SEC_ERROR_BAD_DATA);
#if 0
- PORT_SetErrorString("No recipient data in envelope.");
+ PORT_SetErrorString("No recipient data in envelope.");
#endif
- goto loser;
+ 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;
+ goto loser;
/* what about multiple recipientInfos that match?
* especially if, for some reason, we could not produce a bulk key with the first match?!
@@ -317,17 +320,17 @@ NSS_CMSEnvelopedData_Decode_BeforeData(NSSCMSEnvelopedData *envd)
/* if that fails, then we're not an intended recipient and cannot decrypt */
if (rlIndex < 0) {
- PORT_SetError(SEC_ERROR_NOT_A_RECIPIENT);
+ PORT_SetError(SEC_ERROR_NOT_A_RECIPIENT);
#if 0
- PORT_SetErrorString("Cannot decrypt data because proper key cannot be found.");
+ PORT_SetErrorString("Cannot decrypt data because proper key cannot be found.");
#endif
- goto loser;
+ goto loser;
}
recipient = recipient_list[rlIndex];
if (!recipient->cert || !recipient->privkey) {
- /* XXX should set an error code ?!? */
- goto loser;
+ /* XXX should set an error code ?!? */
+ goto loser;
}
/* get a pointer to "our" recipientinfo */
ri = envd->recipientInfos[recipient->riIndex];
@@ -335,16 +338,16 @@ NSS_CMSEnvelopedData_Decode_BeforeData(NSSCMSEnvelopedData *envd)
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);
+ 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;
+ /* no success finding a bulk key */
+ goto loser;
}
NSS_CMSContentInfo_SetBulkKey(cinfo, bulkkey);
@@ -353,21 +356,20 @@ NSS_CMSEnvelopedData_Decode_BeforeData(NSSCMSEnvelopedData *envd)
rv = NSS_CMSContentInfo_Private_Init(cinfo);
if (rv != SECSuccess) {
- goto loser;
+ 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 */
-
+ goto loser; /* error has been set by NSS_CMSCipherContext_StartDecrypt */
rv = SECSuccess;
loser:
if (bulkkey)
- PK11_FreeSymKey(bulkkey);
+ PK11_FreeSymKey(bulkkey);
if (recipient_list != NULL)
- nss_cms_recipient_list_destroy(recipient_list);
+ nss_cms_recipient_list_destroy(recipient_list);
return rv;
}
@@ -378,8 +380,8 @@ 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;
+ NSS_CMSCipherContext_Destroy(envd->contentInfo.privateInfo->ciphcx);
+ envd->contentInfo.privateInfo->ciphcx = NULL;
}
return SECSuccess;
@@ -394,4 +396,3 @@ NSS_CMSEnvelopedData_Decode_AfterEnd(NSSCMSEnvelopedData *envd)
/* apply final touches */
return SECSuccess;
}
-
diff --git a/nss/lib/smime/cmslocal.h b/nss/lib/smime/cmslocal.h
index ee00c05..ef7d500 100644
--- a/nss/lib/smime/cmslocal.h
+++ b/nss/lib/smime/cmslocal.h
@@ -23,7 +23,7 @@ extern const SEC_ASN1Template NSSCMSContentInfoTemplate[];
struct NSSCMSContentInfoPrivateStr {
NSSCMSCipherContext *ciphcx;
NSSCMSDigestContext *digcx;
- PRBool dontStream;
+ PRBool dontStream;
};
/************************************************************************/
@@ -38,7 +38,6 @@ SEC_BEGIN_PROTOS
*/
SECStatus NSS_CMSContentInfo_Private_Init(NSSCMSContentInfo *cinfo);
-
/***********************************************************************
* cmscipher.c - en/decryption routines
***********************************************************************/
@@ -105,12 +104,12 @@ NSS_CMSCipherContext_EncryptLength(NSSCMSCipherContext *cc, unsigned int input_l
* "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);
+ 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
@@ -128,12 +127,12 @@ NSS_CMSCipherContext_Decrypt(NSSCMSCipherContext *cc, unsigned char *output,
* "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);
+ 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
@@ -167,12 +166,12 @@ NSS_CMSUtil_DecryptSymKey_RSA(SECKEYPrivateKey *privkey, SECItem *encKey, SECOid
extern SECStatus
NSS_CMSUtil_EncryptSymKey_ESDH(PLArenaPool *poolp, CERTCertificate *cert, PK11SymKey *key,
- SECItem *encKey, SECItem **ukm, SECAlgorithmID *keyEncAlg,
- SECItem *originatorPubKey);
+ 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);
+ SECAlgorithmID *keyEncAlg, SECOidTag bulkalgtag, void *pwfn_arg);
/************************************************************************
* cmsreclist.c - recipient list stuff
@@ -213,13 +212,13 @@ NSS_CMSArray_Count(void **array);
*
* 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
+ * "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);
+NSS_CMSArray_Sort(void **primary, int (*compare)(void *, void *), void **secondary, void **tertiary);
/************************************************************************
* cmsattr.c - misc attribute functions
@@ -296,7 +295,7 @@ NSS_CMSAttributeArray_FindAttrByOidTag(NSSCMSAttribute **attrs, SECOidTag oidtag
/*
* NSS_CMSAttributeArray_AddAttr - add an attribute to an
- * array of attributes.
+ * array of attributes.
*/
extern SECStatus
NSS_CMSAttributeArray_AddAttr(PLArenaPool *poolp, NSSCMSAttribute ***attrs, NSSCMSAttribute *attr);
@@ -305,7 +304,8 @@ NSS_CMSAttributeArray_AddAttr(PLArenaPool *poolp, NSSCMSAttribute ***attrs, NSSC
* 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_CMSAttributeArray_SetAttr(PLArenaPool *poolp, NSSCMSAttribute ***attrs,
+ SECOidTag type, SECItem *value, PRBool encoded);
/*
* NSS_CMSSignedData_AddTempCertificate - add temporary certificate references.
@@ -320,33 +320,31 @@ NSS_CMSSignedData_AddTempCertificate(NSSCMSSignedData *sigd, CERTCertificate *ce
*/
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);
+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);
+ 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
diff --git a/nss/lib/smime/cmsmessage.c b/nss/lib/smime/cmsmessage.c
index a44fb0b..27d1256 100644
--- a/nss/lib/smime/cmsmessage.c
+++ b/nss/lib/smime/cmsmessage.c
@@ -28,7 +28,7 @@ NSS_CMSMessage_Create(PLArenaPool *poolp)
PRBool poolp_is_ours = PR_FALSE;
if (poolp == NULL) {
- poolp = PORT_NewArena (1024); /* XXX what is right value? */
+ poolp = PORT_NewArena(1024); /* XXX what is right value? */
if (poolp == NULL)
return NULL;
poolp_is_ours = PR_TRUE;
@@ -54,7 +54,7 @@ NSS_CMSMessage_Create(PLArenaPool *poolp)
cmsg->refCount = 1;
if (mark)
- PORT_ArenaUnmark(poolp, mark);
+ PORT_ArenaUnmark(poolp, mark);
return cmsg;
}
@@ -69,12 +69,12 @@ NSS_CMSMessage_Create(PLArenaPool *poolp)
*/
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)
+ 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);
+ PK11_SetPasswordFunc(pwfn);
cmsg->pwfn_arg = pwfn_arg;
cmsg->decrypt_key_cb = decrypt_key_cb;
cmsg->decrypt_key_cb_arg = decrypt_key_cb_arg;
@@ -88,23 +88,23 @@ NSS_CMSMessage_SetEncodingParams(NSSCMSMessage *cmsg,
void
NSS_CMSMessage_Destroy(NSSCMSMessage *cmsg)
{
- PORT_Assert (cmsg->refCount > 0);
- if (cmsg->refCount <= 0) /* oops */
- return;
+ PORT_Assert(cmsg->refCount > 0);
+ if (cmsg->refCount <= 0) /* oops */
+ return;
- cmsg->refCount--; /* thread safety? */
+ cmsg->refCount--; /* thread safety? */
if (cmsg->refCount > 0)
- return;
+ 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? */
+ PORT_FreeArena(cmsg->poolp, PR_FALSE); /* XXX clear it? */
}
/*
- * NSS_CMSMessage_Copy - return a copy of the given message.
+ * 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).
@@ -113,9 +113,9 @@ NSSCMSMessage *
NSS_CMSMessage_Copy(NSSCMSMessage *cmsg)
{
if (cmsg == NULL)
- return NULL;
+ return NULL;
- PORT_Assert (cmsg->refCount > 0);
+ PORT_Assert(cmsg->refCount > 0);
cmsg->refCount++; /* XXX chrisk thread safety? */
return cmsg;
@@ -140,7 +140,7 @@ NSS_CMSMessage_GetContentInfo(NSSCMSMessage *cmsg)
}
/*
- * Return a pointer to the actual content.
+ * 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.
*/
@@ -148,8 +148,8 @@ SECItem *
NSS_CMSMessage_GetContent(NSSCMSMessage *cmsg)
{
/* this is a shortcut */
- NSSCMSContentInfo * cinfo = NSS_CMSMessage_GetContentInfo(cmsg);
- SECItem * pItem = NSS_CMSContentInfo_GetInnerContent(cinfo);
+ NSSCMSContentInfo *cinfo = NSS_CMSMessage_GetContentInfo(cmsg);
+ SECItem *pItem = NSS_CMSContentInfo_GetInnerContent(cinfo);
return pItem;
}
@@ -165,9 +165,9 @@ NSS_CMSMessage_ContentLevelCount(NSSCMSMessage *cmsg)
NSSCMSContentInfo *cinfo;
/* walk down the chain of contentinfos */
- for (cinfo = &(cmsg->contentInfo); cinfo != NULL; ) {
- count++;
- cinfo = NSS_CMSContentInfo_GetChildContentInfo(cinfo);
+ for (cinfo = &(cmsg->contentInfo); cinfo != NULL;) {
+ count++;
+ cinfo = NSS_CMSContentInfo_GetChildContentInfo(cinfo);
}
return count;
}
@@ -184,8 +184,9 @@ NSS_CMSMessage_ContentLevel(NSSCMSMessage *cmsg, int n)
NSSCMSContentInfo *cinfo;
/* walk down the chain of contentinfos */
- for (cinfo = &(cmsg->contentInfo); cinfo != NULL && count < n; cinfo = NSS_CMSContentInfo_GetChildContentInfo(cinfo)) {
- count++;
+ for (cinfo = &(cmsg->contentInfo); cinfo != NULL && count < n;
+ cinfo = NSS_CMSContentInfo_GetChildContentInfo(cinfo)) {
+ count++;
}
return cinfo;
@@ -200,13 +201,14 @@ 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? */
+ 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;
}
@@ -220,16 +222,16 @@ 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;
- }
+ 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;
}
@@ -250,17 +252,17 @@ 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;
- }
+ 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;
}
@@ -277,14 +279,14 @@ NSS_CMSMessage_IsContentEmpty(NSSCMSMessage *cmsg, unsigned int minLen)
SECItem *item = NULL;
if (cmsg == NULL)
- return PR_TRUE;
+ 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_TRUE;
+ } else if (item->len <= minLen) {
+ return PR_TRUE;
}
return PR_FALSE;
diff --git a/nss/lib/smime/cmspubkey.c b/nss/lib/smime/cmspubkey.c
index cf80044..bc3cd99 100644
--- a/nss/lib/smime/cmspubkey.c
+++ b/nss/lib/smime/cmspubkey.c
@@ -25,7 +25,7 @@
* according to PKCS#1 and RFC2633 (S/MIME)
*/
SECStatus
-NSS_CMSUtil_EncryptSymKey_RSA(PLArenaPool *poolp, CERTCertificate *cert,
+NSS_CMSUtil_EncryptSymKey_RSA(PLArenaPool *poolp, CERTCertificate *cert,
PK11SymKey *bulkkey,
SECItem *encKey)
{
@@ -34,7 +34,7 @@ NSS_CMSUtil_EncryptSymKey_RSA(PLArenaPool *poolp, CERTCertificate *cert,
publickey = CERT_ExtractPublicKey(cert);
if (publickey == NULL)
- return SECFailure;
+ return SECFailure;
rv = NSS_CMSUtil_EncryptSymKey_RSAPubKey(poolp, publickey, bulkkey, encKey);
SECKEY_DestroyPublicKey(publickey);
@@ -42,8 +42,8 @@ NSS_CMSUtil_EncryptSymKey_RSA(PLArenaPool *poolp, CERTCertificate *cert,
}
SECStatus
-NSS_CMSUtil_EncryptSymKey_RSAPubKey(PLArenaPool *poolp,
- SECKEYPublicKey *publickey,
+NSS_CMSUtil_EncryptSymKey_RSAPubKey(PLArenaPool *poolp,
+ SECKEYPublicKey *publickey,
PK11SymKey *bulkkey, SECItem *encKey)
{
SECStatus rv;
@@ -51,37 +51,36 @@ NSS_CMSUtil_EncryptSymKey_RSAPubKey(PLArenaPool *poolp,
KeyType keyType;
void *mark = NULL;
-
mark = PORT_ArenaMark(poolp);
if (!mark)
- goto loser;
+ goto loser;
/* sanity check */
keyType = SECKEY_GetPublicKeyType(publickey);
PORT_Assert(keyType == rsaKey);
if (keyType != rsaKey) {
- goto loser;
+ 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);
+ 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;
+ goto loser;
/* encrypt the key now */
rv = PK11_PubWrapSymKey(PK11_AlgtagToMechanism(SEC_OID_PKCS1_RSA_ENCRYPTION),
- publickey, bulkkey, encKey);
+ publickey, bulkkey, encKey);
if (rv != SECSuccess)
- goto loser;
+ goto loser;
PORT_ArenaUnmark(poolp, mark);
return SECSuccess;
loser:
if (mark) {
- PORT_ArenaRelease(poolp, mark);
+ PORT_ArenaRelease(poolp, mark);
}
return SECFailure;
}
@@ -101,8 +100,8 @@ NSS_CMSUtil_DecryptSymKey_RSA(SECKEYPrivateKey *privkey, SECItem *encKey, SECOid
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;
+ PORT_SetError(SEC_ERROR_INVALID_ALGORITHM);
+ return NULL;
}
return PK11_PubUnwrapSymKey(privkey, encKey, target, CKA_DECRYPT, 0);
}
@@ -111,12 +110,12 @@ NSS_CMSUtil_DecryptSymKey_RSA(SECKEYPrivateKey *privkey, SECItem *encKey, SECOid
SECStatus
NSS_CMSUtil_EncryptSymKey_ESDH(PLArenaPool *poolp, CERTCertificate *cert, PK11SymKey *key,
- SECItem *encKey, SECItem **ukm, SECAlgorithmID *keyEncAlg,
- SECItem *pubKey)
+ 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 */
+ SECOidTag certalgtag; /* the certificate's encryption algorithm */
+ SECOidTag encalgtag; /* the algorithm used for key exchange/agreement */
SECStatus rv;
SECItem *params = NULL;
int data_len;
@@ -148,7 +147,7 @@ NSS_CMSUtil_EncryptSymKey_ESDH(PLArenaPool *poolp, CERTCertificate *cert, PK11Sy
/* XXXX */ourPubKey = CERT_ExtractPublicKey(ourCert);
if (ourPubKey == NULL)
{
- goto loser;
+ goto loser;
}
SECITEM_CopyItem(arena, pubKey, /* XXX */&(ourPubKey->u.fortezza.KEAKey));
SECKEY_DestroyPublicKey(ourPubKey); /* we only need the private key from now on */
@@ -161,24 +160,24 @@ NSS_CMSUtil_EncryptSymKey_ESDH(PLArenaPool *poolp, CERTCertificate *cert, PK11Sy
/* If ukm desired, prepare it - allocate enough space (filled with zeros). */
if (ukm) {
- ukm->data = (unsigned char*)PORT_ArenaZAlloc(arena,/* XXXX */);
- ukm->len = /* XXXX */;
+ 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);
+ 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;
+ goto loser;
/* allocate space for the encrypted CEK (bulk key) */
encKey->data = (unsigned char*)PORT_ArenaAlloc(poolp, SMIME_FORTEZZA_MAX_KEY_SIZE);
@@ -186,8 +185,8 @@ NSS_CMSUtil_EncryptSymKey_ESDH(PLArenaPool *poolp, CERTCertificate *cert, PK11Sy
if (encKey->data == NULL)
{
- PK11_FreeSymKey(kek);
- goto loser;
+ PK11_FreeSymKey(kek);
+ goto loser;
}
@@ -196,23 +195,23 @@ NSS_CMSUtil_EncryptSymKey_ESDH(PLArenaPool *poolp, CERTCertificate *cert, PK11Sy
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;
+ 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;
+ 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... */
+ /* XXXX what do we do here? Neither RC2 nor 3DES... */
err = SECFailure;
/* set error */
- break;
+ break;
}
- PK11_FreeSymKey(kek); /* we do not need the KEK anymore */
+ PK11_FreeSymKey(kek); /* we do not need the KEK anymore */
if (err != SECSuccess)
- goto loser;
+ goto loser;
PORT_Assert(whichKEA != NSSCMSKEAInvalid);
@@ -220,17 +219,17 @@ NSS_CMSUtil_EncryptSymKey_ESDH(PLArenaPool *poolp, CERTCertificate *cert, PK11Sy
/* 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;
+ goto loser;
/* now set keyEncAlg */
rv = SECOID_SetAlgorithmID(poolp, keyEncAlg, SEC_OID_CMS_EPHEMERAL_STATIC_DIFFIE_HELLMAN, params);
if (rv != SECSuccess)
- goto loser;
+ goto loser;
/* XXXXXXX this is not right yet */
loser:
if (arena) {
- PORT_FreeArena(arena, PR_FALSE);
+ PORT_FreeArena(arena, PR_FALSE);
}
if (publickey) {
SECKEY_DestroyPublicKey(publickey);
@@ -243,7 +242,9 @@ loser:
}
PK11SymKey *
-NSS_CMSUtil_DecryptSymKey_ESDH(SECKEYPrivateKey *privkey, SECItem *encKey, SECAlgorithmID *keyEncAlg, SECOidTag bulkalgtag, void *pwfn_arg)
+NSS_CMSUtil_DecryptSymKey_ESDH(SECKEYPrivateKey *privkey, SECItem *encKey,
+ SECAlgorithmID *keyEncAlg, SECOidTag bulkalgtag,
+ void *pwfn_arg)
{
#if 0 /* not yet done */
SECStatus err;
@@ -254,27 +255,27 @@ NSS_CMSUtil_DecryptSymKey_ESDH(SECKEYPrivateKey *privkey, SECItem *encKey, SECAl
/* XXXX get originator's public key */
originatorPubKey = PK11_MakeKEAPubKey(keaParams.originatorKEAKey.data,
- keaParams.originatorKEAKey.len);
+ 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 */
+ &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;
-
+ 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);
+ encKey, CKM_SKIPJACK_CBC64, CKA_DECRYPT, 0);
return bulkkey;
@@ -282,4 +283,3 @@ loser:
#endif
return NULL;
}
-
diff --git a/nss/lib/smime/cmsrecinfo.c b/nss/lib/smime/cmsrecinfo.c
index abc2254..2efb6b1 100644
--- a/nss/lib/smime/cmsrecinfo.c
+++ b/nss/lib/smime/cmsrecinfo.c
@@ -20,11 +20,11 @@ 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;
- }
+ NSSCMSRecipientIdentifier *rid;
+ rid = &ri->ri.keyTransRecipientInfo.recipientIdentifier;
+ if (rid->identifierType == NSSCMSRecipientID_SubjectKeyID) {
+ return PR_TRUE;
+ }
}
return PR_FALSE;
}
@@ -32,20 +32,20 @@ nss_cmsrecipientinfo_usessubjectkeyid(NSSCMSRecipientInfo *ri)
/*
* 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
+ * 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
+ * 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)
+nss_cmsrecipientinfo_create(NSSCMSMessage *cmsg,
+ NSSCMSRecipientIDSelector type,
+ CERTCertificate *cert,
+ SECKEYPublicKey *pubKey,
+ SECItem *subjKeyID,
+ void *pwfn_arg,
+ SECItem *DERinput)
{
NSSCMSRecipientInfo *ri;
void *mark;
@@ -61,12 +61,12 @@ nss_cmsrecipientinfo_create(NSSCMSMessage *cmsg,
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);
+ /* 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;
+ /* mark it as a special cms message */
+ cmsg->contentInfo.contentTypeTag = (SECOidData *)&fakeContent;
}
poolp = cmsg->poolp;
@@ -75,7 +75,7 @@ nss_cmsrecipientinfo_create(NSSCMSMessage *cmsg,
ri = (NSSCMSRecipientInfo *)PORT_ArenaZAlloc(poolp, sizeof(NSSCMSRecipientInfo));
if (ri == NULL)
- goto loser;
+ goto loser;
ri->cmsg = cmsg;
@@ -91,25 +91,23 @@ nss_cmsrecipientinfo_create(NSSCMSMessage *cmsg,
}
switch (type) {
- case NSSCMSRecipientID_IssuerSN:
- {
+ case NSSCMSRecipientID_IssuerSN: {
ri->cert = CERT_DupCertificate(cert);
if (NULL == ri->cert)
goto loser;
spki = &(cert->subjectPublicKeyInfo);
break;
}
-
- case NSSCMSRecipientID_SubjectKeyID:
- {
+
+ case NSSCMSRecipientID_SubjectKeyID: {
PORT_Assert(pubKey);
spki = freeSpki = SECKEY_CreateSubjectPublicKeyInfo(pubKey);
break;
}
- case NSSCMSRecipientID_BrandNew:
- goto done;
- break;
+ case NSSCMSRecipientID_BrandNew:
+ goto done;
+ break;
default:
/* unkown type */
@@ -121,129 +119,128 @@ nss_cmsrecipientinfo_create(NSSCMSMessage *cmsg,
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;
+ 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;
+ }
+ rv = SECITEM_CopyItem(poolp, rid->id.subjectKeyID, subjKeyID);
+ if (rv != SECSuccess || 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;
+ 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;
-
+ 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);
+ PORT_ArenaUnmark(poolp, mark);
if (freeSpki)
- SECKEY_DestroySubjectPublicKeyInfo(freeSpki);
+ SECKEY_DestroySubjectPublicKeyInfo(freeSpki);
return ri;
loser:
@@ -251,11 +248,11 @@ loser:
CERT_DestroyCertificate(ri->cert);
}
if (freeSpki) {
- SECKEY_DestroySubjectPublicKeyInfo(freeSpki);
+ SECKEY_DestroySubjectPublicKeyInfo(freeSpki);
}
- PORT_ArenaRelease (poolp, mark);
+ PORT_ArenaRelease(poolp, mark);
if (cmsg->contentInfo.contentTypeTag == &fakeContent) {
- NSS_CMSMessage_Destroy(cmsg);
+ NSS_CMSMessage_Destroy(cmsg);
}
return NULL;
}
@@ -263,67 +260,66 @@ loser:
/*
* NSS_CMSRecipientInfo_Create - create a recipientinfo
*
- * we currently do not create KeyAgreement recipientinfos with multiple
- * recipientEncryptedKeys the certificate is supposed to have been
+ * 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,
+ return nss_cmsrecipientinfo_create(cmsg, NSSCMSRecipientID_IssuerSN, cert,
NULL, NULL, NULL, NULL);
}
NSSCMSRecipientInfo *
-NSS_CMSRecipientInfo_CreateNew(void* pwfn_arg)
+NSS_CMSRecipientInfo_CreateNew(void *pwfn_arg)
{
- return nss_cmsrecipientinfo_create(NULL, NSSCMSRecipientID_BrandNew, NULL,
+ return nss_cmsrecipientinfo_create(NULL, NSSCMSRecipientID_BrandNew, NULL,
NULL, NULL, pwfn_arg, NULL);
}
NSSCMSRecipientInfo *
-NSS_CMSRecipientInfo_CreateFromDER(SECItem* input, void* pwfn_arg)
+NSS_CMSRecipientInfo_CreateFromDER(SECItem *input, void *pwfn_arg)
{
- return nss_cmsrecipientinfo_create(NULL, NSSCMSRecipientID_BrandNew, NULL,
+ return nss_cmsrecipientinfo_create(NULL, NSSCMSRecipientID_BrandNew, NULL,
NULL, NULL, pwfn_arg, input);
}
-
NSSCMSRecipientInfo *
-NSS_CMSRecipientInfo_CreateWithSubjKeyID(NSSCMSMessage *cmsg,
- SECItem *subjKeyID,
- SECKEYPublicKey *pubKey)
+NSS_CMSRecipientInfo_CreateWithSubjKeyID(NSSCMSMessage *cmsg,
+ SECItem *subjKeyID,
+ SECKEYPublicKey *pubKey)
{
- return nss_cmsrecipientinfo_create(cmsg, NSSCMSRecipientID_SubjectKeyID,
+ return nss_cmsrecipientinfo_create(cmsg, NSSCMSRecipientID_SubjectKeyID,
NULL, pubKey, subjKeyID, NULL, NULL);
}
NSSCMSRecipientInfo *
NSS_CMSRecipientInfo_CreateWithSubjKeyIDFromCert(NSSCMSMessage *cmsg,
- CERTCertificate *cert)
+ CERTCertificate *cert)
{
SECKEYPublicKey *pubKey = NULL;
- SECItem subjKeyID = {siBuffer, NULL, 0};
+ SECItem subjKeyID = { siBuffer, NULL, 0 };
NSSCMSRecipientInfo *retVal = NULL;
if (!cmsg || !cert) {
- return NULL;
+ return NULL;
}
pubKey = CERT_ExtractPublicKey(cert);
if (!pubKey) {
- goto done;
+ goto done;
}
if (CERT_FindSubjectKeyIDExtension(cert, &subjKeyID) != SECSuccess ||
subjKeyID.data == NULL) {
- goto done;
+ goto done;
}
retVal = NSS_CMSRecipientInfo_CreateWithSubjKeyID(cmsg, &subjKeyID, pubKey);
done:
if (pubKey)
- SECKEY_DestroyPublicKey(pubKey);
+ SECKEY_DestroyPublicKey(pubKey);
if (subjKeyID.data)
- SECITEM_FreeItem(&subjKeyID, PR_FALSE);
+ SECITEM_FreeItem(&subjKeyID, PR_FALSE);
return retVal;
}
@@ -337,16 +333,16 @@ NSS_CMSRecipientInfo_Destroy(NSSCMSRecipientInfo *ri)
/* 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);
+ CERT_DestroyCertificate(ri->cert);
if (nss_cmsrecipientinfo_usessubjectkeyid(ri)) {
- NSSCMSKeyTransRecipientInfoEx *extra;
- extra = &ri->ri.keyTransRecipientInfoEx;
- if (extra->pubKey)
- SECKEY_DestroyPublicKey(extra->pubKey);
+ 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);
+ NSS_CMSMessage_Destroy(ri->cmsg);
}
/* we're done. */
@@ -359,28 +355,28 @@ NSS_CMSRecipientInfo_GetVersion(NSSCMSRecipientInfo *ri)
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;
+ 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;
+ if (versionitem == NULL)
+ return 0;
/* always take apart the SECItem */
if (SEC_ASN1DecodeInteger(versionitem, &version) != SECSuccess)
- return 0;
+ return 0;
else
- return (int)version;
+ return (int)version;
}
SECItem *
@@ -389,43 +385,42 @@ 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;
+ 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;
+ 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,
+NSS_CMSRecipientInfo_WrapBulkKey(NSSCMSRecipientInfo *ri, PK11SymKey *bulkkey,
SECOidTag bulkalgtag)
{
CERTCertificate *cert;
@@ -442,21 +437,19 @@ NSS_CMSRecipientInfo_WrapBulkKey(NSSCMSRecipientInfo *ri, PK11SymKey *bulkkey,
cert = ri->cert;
usesSubjKeyID = nss_cmsrecipientinfo_usessubjectkeyid(ri);
if (cert) {
- spki = &cert->subjectPublicKeyInfo;
- certalgtag = SECOID_GetAlgorithmTag(&(spki->algorithm));
+ spki = &cert->subjectPublicKeyInfo;
} 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);
+ 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);
} else {
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- return SECFailure;
+ PORT_SetError(SEC_ERROR_INVALID_ARGS);
+ return SECFailure;
}
/* XXX set ri->recipientInfoType to the proper value here */
@@ -464,66 +457,65 @@ NSS_CMSRecipientInfo_WrapBulkKey(NSSCMSRecipientInfo *ri, PK11SymKey *bulkkey,
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;
+ 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;
}
if (freeSpki)
- SECKEY_DestroySubjectPublicKeyInfo(freeSpki);
+ SECKEY_DestroySubjectPublicKeyInfo(freeSpki);
return rv;
}
PK11SymKey *
-NSS_CMSRecipientInfo_UnwrapBulkKey(NSSCMSRecipientInfo *ri, int subIndex,
- CERTCertificate *cert, SECKEYPrivateKey *privkey, SECOidTag bulkalgtag)
+NSS_CMSRecipientInfo_UnwrapBulkKey(NSSCMSRecipientInfo *ri, int subIndex,
+ CERTCertificate *cert, SECKEYPrivateKey *privkey, SECOidTag bulkalgtag)
{
PK11SymKey *bulkkey = NULL;
SECOidTag encalgtag;
@@ -531,51 +523,51 @@ NSS_CMSRecipientInfo_UnwrapBulkKey(NSSCMSRecipientInfo *ri, int subIndex,
int error;
ri->cert = CERT_DupCertificate(cert);
- /* mark the recipientInfo so we can find it later */
+ /* mark the recipientInfo so we can find it later */
switch (ri->recipientInfoType) {
- case NSSCMSRecipientInfoID_KeyTrans:
- 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:
- 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:
- encalgtag = SECOID_GetAlgorithmTag(&(ri->ri.kekRecipientInfo.keyEncAlg));
- enckey = &(ri->ri.kekRecipientInfo.encKey);
- /* not supported yet */
- error = SEC_ERROR_UNSUPPORTED_KEYALG;
- goto loser;
- break;
+ case NSSCMSRecipientInfoID_KeyTrans:
+ 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:
+ 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:
+ 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;
@@ -585,19 +577,20 @@ loser:
return NULL;
}
-SECStatus NSS_CMSRecipientInfo_GetCertAndKey(NSSCMSRecipientInfo *ri,
- CERTCertificate** retcert,
- SECKEYPrivateKey** retkey)
+SECStatus
+NSS_CMSRecipientInfo_GetCertAndKey(NSSCMSRecipientInfo *ri,
+ CERTCertificate **retcert,
+ SECKEYPrivateKey **retkey)
{
- CERTCertificate* cert = NULL;
- NSSCMSRecipient** recipients = NULL;
- NSSCMSRecipientInfo* recipientInfos[2];
+ CERTCertificate *cert = NULL;
+ NSSCMSRecipient **recipients = NULL;
+ NSSCMSRecipientInfo *recipientInfos[2];
SECStatus rv = SECSuccess;
- SECKEYPrivateKey* key = NULL;
+ SECKEYPrivateKey *key = NULL;
if (!ri)
return SECFailure;
-
+
if (!retcert && !retkey) {
/* nothing requested, nothing found, success */
return SECSuccess;
@@ -626,7 +619,7 @@ SECStatus NSS_CMSRecipientInfo_GetCertAndKey(NSSCMSRecipientInfo *ri,
if (recipients) {
/* now look for the cert and key */
if (0 == PK11_FindCertAndKeyByRecipientListNew(recipients,
- ri->cmsg->pwfn_arg)) {
+ ri->cmsg->pwfn_arg)) {
cert = CERT_DupCertificate(recipients[0]->cert);
key = SECKEY_CopyPrivateKey(recipients[0]->privkey);
} else {
@@ -634,10 +627,9 @@ SECStatus NSS_CMSRecipientInfo_GetCertAndKey(NSSCMSRecipientInfo *ri,
}
nss_cms_recipient_list_destroy(recipients);
- }
- else {
+ } 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);
@@ -660,16 +652,17 @@ SECStatus NSS_CMSRecipientInfo_GetCertAndKey(NSSCMSRecipientInfo *ri,
return rv;
}
-SECStatus NSS_CMSRecipientInfo_Encode(PLArenaPool* poolp,
- const NSSCMSRecipientInfo *src,
- SECItem* returned)
+SECStatus
+NSS_CMSRecipientInfo_Encode(PLArenaPool *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)) {
+ NSSCMSRecipientInfoTemplate)) {
rv = SECSuccess;
}
return rv;
diff --git a/nss/lib/smime/cmsreclist.c b/nss/lib/smime/cmsreclist.c
index 913c651..99d7e90 100644
--- a/nss/lib/smime/cmsreclist.c
+++ b/nss/lib/smime/cmsreclist.c
@@ -18,7 +18,8 @@
#include "secerr.h"
static int
-nss_cms_recipients_traverse(NSSCMSRecipientInfo **recipientinfos, NSSCMSRecipient **recipient_list)
+nss_cms_recipients_traverse(NSSCMSRecipientInfo **recipientinfos,
+ NSSCMSRecipient **recipient_list)
{
int count = 0;
int rlindex = 0;
@@ -28,84 +29,85 @@ nss_cms_recipients_traverse(NSSCMSRecipientInfo **recipientinfos, NSSCMSRecipien
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;
+ 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 (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;
+ recipient_list[rlindex] = NULL;
+ return 0;
} else {
- return count;
+ return count;
}
}
@@ -118,25 +120,25 @@ nss_cms_recipient_list_create(NSSCMSRecipientInfo **recipientinfos)
/* count the number of recipient identifiers */
count = nss_cms_recipients_traverse(recipientinfos, NULL);
if (count <= 0) {
- /* no recipients? */
- PORT_SetError(SEC_ERROR_BAD_DATA);
+ /* no recipients? */
+ PORT_SetError(SEC_ERROR_BAD_DATA);
#if 0
- PORT_SetErrorString("Cannot find recipient data in envelope.");
+ PORT_SetErrorString("Cannot find recipient data in envelope.");
#endif
- return NULL;
+ return NULL;
}
/* allocate an array of pointers */
recipient_list = (NSSCMSRecipient **)
- PORT_ZAlloc((count + 1) * sizeof(NSSCMSRecipient *));
+ PORT_ZAlloc((count + 1) * sizeof(NSSCMSRecipient *));
if (recipient_list == NULL)
- return 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;
+ nss_cms_recipient_list_destroy(recipient_list);
+ return NULL;
}
return recipient_list;
}
@@ -147,15 +149,15 @@ 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);
+ 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);
}
@@ -163,5 +165,6 @@ nss_cms_recipient_list_destroy(NSSCMSRecipient **recipient_list)
NSSCMSRecipientEncryptedKey *
NSS_CMSRecipientEncryptedKey_Create(PLArenaPool *poolp)
{
- return (NSSCMSRecipientEncryptedKey *)PORT_ArenaZAlloc(poolp, sizeof(NSSCMSRecipientEncryptedKey));
+ return (NSSCMSRecipientEncryptedKey *)PORT_ArenaZAlloc(poolp,
+ sizeof(NSSCMSRecipientEncryptedKey));
}
diff --git a/nss/lib/smime/cmsreclist.h b/nss/lib/smime/cmsreclist.h
index 4c094d4..f424aca 100644
--- a/nss/lib/smime/cmsreclist.h
+++ b/nss/lib/smime/cmsreclist.h
@@ -6,19 +6,20 @@
#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 */
+ 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;
+ CERTIssuerAndSN* issuerAndSN;
+ SECItem* subjectKeyID;
} id;
/* result data (filled out for each recipient that's us) */
- CERTCertificate * cert;
- SECKEYPrivateKey * privkey;
- PK11SlotInfo * slot;
+ CERTCertificate* cert;
+ SECKEYPrivateKey* privkey;
+ PK11SlotInfo* slot;
};
typedef struct NSSCMSRecipientStr NSSCMSRecipient;
diff --git a/nss/lib/smime/cmssigdata.c b/nss/lib/smime/cmssigdata.c
index a4527d9..7dd6ea4 100644
--- a/nss/lib/smime/cmssigdata.c
+++ b/nss/lib/smime/cmssigdata.c
@@ -32,9 +32,9 @@ NSS_CMSSignedData_Create(NSSCMSMessage *cmsg)
mark = PORT_ArenaMark(poolp);
- sigd = (NSSCMSSignedData *)PORT_ArenaZAlloc (poolp, sizeof(NSSCMSSignedData));
+ sigd = (NSSCMSSignedData *)PORT_ArenaZAlloc(poolp, sizeof(NSSCMSSignedData));
if (sigd == NULL)
- goto loser;
+ goto loser;
sigd->cmsg = cmsg;
@@ -57,7 +57,7 @@ NSS_CMSSignedData_Destroy(NSSCMSSignedData *sigd)
NSSCMSSignerInfo **signerinfos, *si;
if (sigd == NULL)
- return;
+ return;
certs = sigd->certs;
tempCerts = sigd->tempCerts;
@@ -65,28 +65,27 @@ NSS_CMSSignedData_Destroy(NSSCMSSignedData *sigd)
signerinfos = sigd->signerInfos;
if (certs != NULL) {
- while ((cert = *certs++) != NULL)
- CERT_DestroyCertificate (cert);
+ while ((cert = *certs++) != NULL)
+ CERT_DestroyCertificate(cert);
}
if (tempCerts != NULL) {
- while ((cert = *tempCerts++) != NULL)
- CERT_DestroyCertificate (cert);
+ while ((cert = *tempCerts++) != NULL)
+ CERT_DestroyCertificate(cert);
}
if (certlists != NULL) {
- while ((certlist = *certlists++) != NULL)
- CERT_DestroyCertificateList (certlist);
+ while ((certlist = *certlists++) != NULL)
+ CERT_DestroyCertificateList(certlist);
}
if (signerinfos != NULL) {
- while ((si = *signerinfos++) != NULL)
- NSS_CMSSignerInfo_Destroy(si);
+ 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_CMSContentInfo_Destroy(&(sigd->contentInfo));
}
/*
@@ -122,58 +121,58 @@ NSS_CMSSignedData_Encode_BeforeStart(NSSCMSSignedData *sigd)
/* 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 */
- }
-
+ 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;
+ 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 */
- }
+ 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;
+ return SECFailure;
/* this is a SET OF, so we need to sort them guys */
- rv = NSS_CMSArray_SortByDER((void **)sigd->digestAlgorithms,
+ rv = NSS_CMSArray_SortByDER((void **)sigd->digestAlgorithms,
SEC_ASN1_GET(SECOID_AlgorithmIDTemplate),
- (void **)sigd->digests);
+ (void **)sigd->digests);
if (rv != SECSuccess)
- return SECFailure;
-
+ return SECFailure;
+
return SECSuccess;
loser:
@@ -190,16 +189,16 @@ NSS_CMSSignedData_Encode_BeforeData(NSSCMSSignedData *sigd)
}
rv = NSS_CMSContentInfo_Private_Init(&sigd->contentInfo);
if (rv != SECSuccess) {
- return SECFailure;
+ return SECFailure;
}
/* set up the digests */
if (sigd->digests && sigd->digests[0]) {
- sigd->contentInfo.privateInfo->digcx = NULL; /* don't attempt to make new ones. */
+ 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;
+ sigd->contentInfo.privateInfo->digcx =
+ NSS_CMSDigestContext_StartMultiple(sigd->digestAlgorithms);
+ if (sigd->contentInfo.privateInfo->digcx == NULL)
+ return SECFailure;
}
return SECSuccess;
}
@@ -239,53 +238,53 @@ NSS_CMSSignedData_Encode_AfterData(NSSCMSSignedData *sigd)
/* 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;
+ 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;
- }
+ 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...") */
+ /* 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;
+ /* 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;
+ /* 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;
+ /* 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;
+ goto loser;
/*
* now prepare certs & crls
@@ -293,65 +292,65 @@ NSS_CMSSignedData_Encode_AfterData(NSSCMSSignedData *sigd)
/* count the rest of the certs */
if (sigd->certs != NULL) {
- for (ci = 0; sigd->certs[ci] != NULL; ci++)
- certcount++;
+ 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;
+ for (cli = 0; sigd->certLists[cli] != NULL; cli++)
+ certcount += sigd->certLists[cli]->len;
}
if (certcount == 0) {
- sigd->rawCerts = NULL;
+ 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);
+ /*
+ * 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;
@@ -370,39 +369,38 @@ NSS_CMSSignedData_Decode_BeforeData(NSSCMSSignedData *sigd)
}
rv = NSS_CMSContentInfo_Private_Init(&sigd->contentInfo);
if (rv != SECSuccess) {
- return SECFailure;
+ 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;
- }
- }
- }
+ 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;
+ /* 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
+ * NSS_CMSSignedData_Decode_AfterData - do all the necessary things to a
* SignedData after all the encapsulated data was passed through the decoder.
*/
SECStatus
@@ -417,10 +415,10 @@ NSS_CMSSignedData_Decode_AfterData(NSSCMSSignedData *sigd)
/* 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;
+ 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;
}
@@ -445,14 +443,14 @@ NSS_CMSSignedData_Decode_AfterEnd(NSSCMSSignedData *sigd)
/* set cmsg for all the signerinfos */
if (signerinfos) {
- for (i = 0; signerinfos[i] != NULL; i++)
- signerinfos[i]->cmsg = sigd->cmsg;
+ for (i = 0; signerinfos[i] != NULL; i++)
+ signerinfos[i]->cmsg = sigd->cmsg;
}
return SECSuccess;
}
-/*
+/*
* NSS_CMSSignedData_GetSignerInfos - retrieve the SignedData's signer list
*/
NSSCMSSignerInfo **
@@ -485,7 +483,7 @@ NSS_CMSSignedData_GetSignerInfo(NSSCMSSignedData *sigd, int i)
return sigd->signerInfos[i];
}
-/*
+/*
* NSS_CMSSignedData_GetDigestAlgs - retrieve the SignedData's digest algorithm list
*/
SECAlgorithmID **
@@ -511,7 +509,7 @@ NSS_CMSSignedData_GetContentInfo(NSSCMSSignedData *sigd)
return &(sigd->contentInfo);
}
-/*
+/*
* NSS_CMSSignedData_GetCertificateList - retrieve the SignedData's certificate list
*/
SECItem **
@@ -526,7 +524,7 @@ NSS_CMSSignedData_GetCertificateList(NSSCMSSignedData *sigd)
SECStatus
NSS_CMSSignedData_ImportCerts(NSSCMSSignedData *sigd, CERTCertDBHandle *certdb,
- SECCertUsage certusage, PRBool keepcerts)
+ SECCertUsage certusage, PRBool keepcerts)
{
int certcount;
CERTCertificate **certArray = NULL;
@@ -545,99 +543,99 @@ NSS_CMSSignedData_ImportCerts(NSSCMSSignedData *sigd, CERTCertDBHandle *certdb,
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);
+ rv = CERT_ImportCerts(certdb, certusage, certcount, sigd->rawCerts,
+ &certArray, PR_FALSE, PR_FALSE, NULL);
if (rv != SECSuccess) {
- goto loser;
+ goto loser;
}
/* save the certs so they don't get destroyed */
- for (i=0; i < certcount; i++) {
- CERTCertificate *cert = certArray[i];
- if (cert)
+ for (i = 0; i < certcount; i++) {
+ CERTCertificate *cert = certArray[i];
+ if (cert)
NSS_CMSSignedData_AddTempCertificate(sigd, cert);
}
if (!keepcerts) {
- goto done;
+ goto done;
}
/* build a CertList for filtering */
certList = CERT_NewCertList();
if (certList == NULL) {
- rv = SECFailure;
- goto loser;
+ 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);
+ 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);
+ rv = CERT_FilterCertListByUsage(certList, certusage, PR_FALSE);
if (rv != SECSuccess) {
- goto loser;
+ 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);
+ 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 */
+/* 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);
+ /* 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);
+ CERT_DestroyCertArray(certArray, certcount);
}
if (certList) {
- CERT_DestroyCertList(certList);
+ CERT_DestroyCertList(certList);
}
return rv;
@@ -658,8 +656,8 @@ loser:
* for the purpose specified by "certusage".
*/
SECStatus
-NSS_CMSSignedData_VerifySignerInfo(NSSCMSSignedData *sigd, int i,
- CERTCertDBHandle *certdb, SECCertUsage certusage)
+NSS_CMSSignedData_VerifySignerInfo(NSSCMSSignedData *sigd, int i,
+ CERTCertDBHandle *certdb, SECCertUsage certusage)
{
NSSCMSSignerInfo *signerinfo;
NSSCMSContentInfo *cinfo;
@@ -680,7 +678,7 @@ NSS_CMSSignedData_VerifySignerInfo(NSSCMSSignedData *sigd, int i,
/* verify certificate */
rv = NSS_CMSSignerInfo_VerifyCertificate(signerinfo, certdb, certusage);
if (rv != SECSuccess)
- return rv; /* error is set */
+ return rv; /* error is set */
/* find digest and contentType for signerinfo */
algiddata = NSS_CMSSignerInfo_GetDigestAlg(signerinfo);
@@ -699,8 +697,8 @@ NSS_CMSSignedData_VerifySignerInfo(NSSCMSSignedData *sigd, int i,
* NSS_CMSSignedData_VerifyCertsOnly - verify the certs in a certs-only message
*/
SECStatus
-NSS_CMSSignedData_VerifyCertsOnly(NSSCMSSignedData *sigd,
- CERTCertDBHandle *certdb,
+NSS_CMSSignedData_VerifyCertsOnly(NSSCMSSignedData *sigd,
+ CERTCertDBHandle *certdb,
SECCertUsage usage)
{
CERTCertificate *cert;
@@ -708,27 +706,31 @@ NSS_CMSSignedData_VerifyCertsOnly(NSSCMSSignedData *sigd,
int i;
int count;
PRTime now;
+ void *pwarg = NULL;
if (!sigd || !certdb || !sigd->rawCerts) {
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- return SECFailure;
+ PORT_SetError(SEC_ERROR_INVALID_ARGS);
+ return SECFailure;
}
- count = NSS_CMSArray_Count((void**)sigd->rawCerts);
+ 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);
+ 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;
+ }
+ }
+ if (sigd->cmsg) {
+ pwarg = sigd->cmsg->pwfn_arg;
+ }
+ rv |= CERT_VerifyCert(certdb, cert, PR_TRUE, usage, now,
+ pwarg, NULL);
+ CERT_DestroyCertificate(cert);
}
return rv;
@@ -764,7 +766,7 @@ NSS_CMSSignedData_AddCertList(NSSCMSSignedData *sigd, CERTCertificateList *certl
}
/*
- * NSS_CMSSignedData_AddCertChain - add cert and its entire chain to the set of certs
+ * NSS_CMSSignedData_AddCertChain - add cert and its entire chain to the set of certs
*/
SECStatus
NSS_CMSSignedData_AddCertChain(NSSCMSSignedData *sigd, CERTCertificate *cert)
@@ -783,7 +785,7 @@ NSS_CMSSignedData_AddCertChain(NSSCMSSignedData *sigd, CERTCertificate *cert)
/* do not include root */
certlist = CERT_CertChainFromCert(cert, usage, PR_FALSE);
if (certlist == NULL)
- return SECFailure;
+ return SECFailure;
rv = NSS_CMSSignedData_AddCertList(sigd, certlist);
@@ -830,16 +832,16 @@ NSS_CMSSignedData_ContainsCertsOrCrls(NSSCMSSignedData *sigd)
return PR_FALSE;
}
if (sigd->rawCerts != NULL && sigd->rawCerts[0] != NULL)
- return PR_TRUE;
+ return PR_TRUE;
else if (sigd->crls != NULL && sigd->crls[0] != NULL)
- return PR_TRUE;
+ return PR_TRUE;
else
- return PR_FALSE;
+ return PR_FALSE;
}
SECStatus
NSS_CMSSignedData_AddSignerInfo(NSSCMSSignedData *sigd,
- NSSCMSSignerInfo *signerinfo)
+ NSSCMSSignerInfo *signerinfo)
{
void *mark;
SECStatus rv;
@@ -858,7 +860,7 @@ NSS_CMSSignedData_AddSignerInfo(NSSCMSSignedData *sigd,
/* add signerinfo */
rv = NSS_CMSArray_Add(poolp, (void ***)&(sigd->signerInfos), (void *)signerinfo);
if (rv != SECSuccess)
- goto loser;
+ goto loser;
/*
* add empty digest
@@ -869,7 +871,7 @@ NSS_CMSSignedData_AddSignerInfo(NSSCMSSignedData *sigd,
digestalgtag = NSS_CMSSignerInfo_GetDigestAlgTag(signerinfo);
rv = NSS_CMSSignedData_SetDigestValue(sigd, digestalgtag, NULL);
if (rv != SECSuccess)
- goto loser;
+ goto loser;
/*
* The last thing to get consistency would be adding the digest.
@@ -879,7 +881,7 @@ NSS_CMSSignedData_AddSignerInfo(NSSCMSSignedData *sigd,
return SECSuccess;
loser:
- PORT_ArenaRelease (poolp, mark);
+ PORT_ArenaRelease(poolp, mark);
return SECFailure;
}
@@ -891,8 +893,8 @@ loser:
*/
SECStatus
NSS_CMSSignedData_SetDigests(NSSCMSSignedData *sigd,
- SECAlgorithmID **digestalgs,
- SECItem **digests)
+ SECAlgorithmID **digestalgs,
+ SECItem **digests)
{
int cnt, i, idx;
@@ -902,55 +904,54 @@ NSS_CMSSignedData_SetDigests(NSSCMSSignedData *sigd,
}
if (sigd->digestAlgorithms == NULL) {
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- return SECFailure;
+ 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;
+ 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;
+ 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;
- }
+ /* 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)
+ SECOidTag digestalgtag,
+ SECItem *digestdata)
{
SECItem *digest = NULL;
PLArenaPool *poolp;
@@ -966,13 +967,12 @@ NSS_CMSSignedData_SetDigestValue(NSSCMSSignedData *sigd,
mark = PORT_ArenaMark(poolp);
-
if (digestdata) {
- digest = (SECItem *) PORT_ArenaZAlloc(poolp,sizeof(SECItem));
+ 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;
+ /* 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) */
@@ -980,22 +980,22 @@ NSS_CMSSignedData_SetDigestValue(NSSCMSSignedData *sigd,
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;
+ PORT_SetError(SEC_ERROR_NO_MEMORY);
+ return SECFailure;
}
}
n = -1;
if (sigd->digestAlgorithms != NULL)
- n = NSS_CMSAlgArray_GetIndexByAlgTag(sigd->digestAlgorithms, digestalgtag);
+ 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;
+ 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;
+ /* replace NULL pointer with digest item (and leak previous value) */
+ sigd->digests[n] = digest;
}
PORT_ArenaUnmark(poolp, mark);
@@ -1008,9 +1008,9 @@ loser:
SECStatus
NSS_CMSSignedData_AddDigest(PLArenaPool *poolp,
- NSSCMSSignedData *sigd,
- SECOidTag digestalgtag,
- SECItem *digest)
+ NSSCMSSignedData *sigd,
+ SECOidTag digestalgtag,
+ SECItem *digest)
{
SECAlgorithmID *digestalg;
void *mark;
@@ -1024,16 +1024,17 @@ NSS_CMSSignedData_AddDigest(PLArenaPool *poolp,
digestalg = PORT_ArenaZAlloc(poolp, sizeof(SECAlgorithmID));
if (digestalg == NULL)
- goto loser;
+ goto loser;
- if (SECOID_SetAlgorithmID (poolp, digestalg, digestalgtag, NULL) != SECSuccess) /* no params */
- 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;
+ 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);
@@ -1057,7 +1058,7 @@ NSS_CMSSignedData_GetDigestValue(NSSCMSSignedData *sigd, SECOidTag digestalgtag)
if (sigd->digestAlgorithms == NULL || sigd->digests == NULL) {
PORT_SetError(SEC_ERROR_DIGEST_NOT_FOUND);
- return NULL;
+ return NULL;
}
n = NSS_CMSAlgArray_GetIndexByAlgTag(sigd->digestAlgorithms, digestalgtag);
@@ -1099,18 +1100,18 @@ NSS_CMSSignedData_CreateCertsOnly(NSSCMSMessage *cmsg, CERTCertificate *cert, PR
sigd = NSS_CMSSignedData_Create(cmsg);
if (sigd == NULL)
- goto loser;
+ goto loser;
/* no signerinfos, thus no digestAlgorithms */
/* but certs */
if (include_chain) {
- rv = NSS_CMSSignedData_AddCertChain(sigd, cert);
+ rv = NSS_CMSSignedData_AddCertChain(sigd, cert);
} else {
- rv = NSS_CMSSignedData_AddCertificate(sigd, cert);
+ rv = NSS_CMSSignedData_AddCertificate(sigd, cert);
}
if (rv != SECSuccess)
- goto loser;
+ goto loser;
/* RFC2630 5.2 sez:
* In the degenerate case where there are no signers, the
@@ -1121,14 +1122,14 @@ NSS_CMSSignedData_CreateCertsOnly(NSSCMSMessage *cmsg, CERTCertificate *cert, PR
*/
rv = NSS_CMSContentInfo_SetContent_Data(cmsg, &(sigd->contentInfo), NULL, PR_TRUE);
if (rv != SECSuccess)
- goto loser;
+ goto loser;
PORT_ArenaUnmark(poolp, mark);
return sigd;
loser:
if (sigd)
- NSS_CMSSignedData_Destroy(sigd);
+ NSS_CMSSignedData_Destroy(sigd);
PORT_ArenaRelease(poolp, mark);
return NULL;
}
@@ -1138,4 +1139,3 @@ loser:
* NSS_CMSSignedData_HasReceiptRequest()
* easy way to iterate over signers
*/
-
diff --git a/nss/lib/smime/cmssiginfo.c b/nss/lib/smime/cmssiginfo.c
index f3635c2..ce4f87c 100644
--- a/nss/lib/smime/cmssiginfo.c
+++ b/nss/lib/smime/cmssiginfo.c
@@ -25,32 +25,36 @@
* SIGNERINFO
*/
NSSCMSSignerInfo *
-nss_cmssignerinfo_create(NSSCMSMessage *cmsg, NSSCMSSignerIDSelector type,
- CERTCertificate *cert, SECItem *subjKeyID, SECKEYPublicKey *pubKey,
- SECKEYPrivateKey *signingKey, SECOidTag digestalgtag);
+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)
+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);
+ 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);
+ 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)
+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;
+ SECStatus rv;
poolp = cmsg->poolp;
@@ -58,50 +62,52 @@ nss_cmssignerinfo_create(NSSCMSMessage *cmsg, NSSCMSSignerIDSelector type,
signerinfo = (NSSCMSSignerInfo *)PORT_ArenaZAlloc(poolp, sizeof(NSSCMSSignerInfo));
if (signerinfo == NULL) {
- PORT_ArenaRelease(poolp, mark);
- return 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)
+ 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);
+ rv = SECITEM_CopyItem(poolp, signerinfo->signerIdentifier.id.subjectKeyID,
+ subjKeyID);
+ if (rv != SECSuccess) {
+ goto loser;
+ }
+ signerinfo->signingKey = SECKEY_CopyPrivateKey(signingKey);
+ if (!signerinfo->signingKey)
+ goto loser;
+ signerinfo->pubKey = SECKEY_CopyPublicKey(pubKey);
+ if (!signerinfo->pubKey)
+ goto loser;
+ break;
+ default:
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;
+ 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;
+ goto loser;
PORT_ArenaUnmark(poolp, mark);
return signerinfo;
@@ -118,10 +124,10 @@ void
NSS_CMSSignerInfo_Destroy(NSSCMSSignerInfo *si)
{
if (si->cert != NULL)
- CERT_DestroyCertificate(si->cert);
+ CERT_DestroyCertificate(si->cert);
- if (si->certList != NULL)
- CERT_DestroyCertificateList(si->certList);
+ if (si->certList != NULL)
+ CERT_DestroyCertificateList(si->certList);
/* XXX storage ??? */
}
@@ -131,7 +137,7 @@ NSS_CMSSignerInfo_Destroy(NSSCMSSignerInfo *si)
*
*/
SECStatus
-NSS_CMSSignerInfo_Sign(NSSCMSSignerInfo *signerinfo, SECItem *digest,
+NSS_CMSSignerInfo_Sign(NSSCMSSignerInfo *signerinfo, SECItem *digest,
SECItem *contentType)
{
CERTCertificate *cert;
@@ -144,31 +150,31 @@ NSS_CMSSignerInfo_Sign(NSSCMSSignerInfo *signerinfo, SECItem *digest,
SECAlgorithmID *algID, freeAlgID;
CERTSubjectPublicKeyInfo *spki;
- PORT_Assert (digest != NULL);
+ 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;
+ 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);
/*
@@ -177,105 +183,104 @@ NSS_CMSSignerInfo_Sign(NSSCMSSignerInfo *signerinfo, SECItem *digest,
*/
pubkAlgTag = SECOID_GetAlgorithmTag(algID);
if (signerinfo->signerIdentifier.identifierType == NSSCMSSignerID_SubjectKeyID) {
- SECOID_DestroyAlgorithmID(&freeAlgID, PR_FALSE);
+ 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,
+ 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;
+ 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);
+ rv = SGN_Digest(privkey, digestalgtag, &signature, digest);
}
SECKEY_DestroyPrivateKey(privkey);
privkey = NULL;
if (rv != SECSuccess)
- goto loser;
+ goto loser;
- if (SECITEM_CopyItem(poolp, &(signerinfo->encDigest), &signature)
- != 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,
+ if (SECOID_SetAlgorithmID(poolp, &(signerinfo->digestEncAlg), pubkAlgTag,
NULL) != SECSuccess)
- goto loser;
+ goto loser;
return SECSuccess;
loser:
if (signature.len != 0)
- SECITEM_FreeItem (&signature, PR_FALSE);
+ SECITEM_FreeItem(&signature, PR_FALSE);
if (privkey)
- SECKEY_DestroyPrivateKey(privkey);
+ SECKEY_DestroyPrivateKey(privkey);
if (tmppoolp)
- PORT_FreeArena(tmppoolp, PR_FALSE);
+ PORT_FreeArena(tmppoolp, PR_FALSE);
return SECFailure;
}
SECStatus
NSS_CMSSignerInfo_VerifyCertificate(NSSCMSSignerInfo *signerinfo, CERTCertDBHandle *certdb,
- SECCertUsage certusage)
+ SECCertUsage certusage)
{
CERTCertificate *cert;
PRTime stime;
if ((cert = NSS_CMSSignerInfo_GetSigningCertificate(signerinfo, certdb)) == NULL) {
- signerinfo->verificationStatus = NSSCMSVS_SigningCertNotFound;
- return SECFailure;
+ signerinfo->verificationStatus = NSSCMSVS_SigningCertNotFound;
+ return SECFailure;
}
/*
@@ -283,9 +288,9 @@ NSS_CMSSignerInfo_VerifyCertificate(NSSCMSSignerInfo *signerinfo, CERTCertDBHand
* 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 */
-
+ 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
@@ -294,10 +299,10 @@ NSS_CMSSignerInfo_VerifyCertificate(NSSCMSSignerInfo *signerinfo, CERTCertDBHand
* 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,
+ if (CERT_VerifyCert(certdb, cert, PR_TRUE, certusage, stime,
signerinfo->cmsg->pwfn_arg, NULL) != SECSuccess) {
- signerinfo->verificationStatus = NSSCMSVS_SigningCertNotTrusted;
- return SECFailure;
+ signerinfo->verificationStatus = NSSCMSVS_SigningCertNotTrusted;
+ return SECFailure;
}
return SECSuccess;
}
@@ -305,13 +310,13 @@ NSS_CMSSignerInfo_VerifyCertificate(NSSCMSSignerInfo *signerinfo, CERTCertDBHand
/*
* NSS_CMSSignerInfo_Verify - verify the signature of a single SignerInfo
*
- * Just verifies the signature. The assumption is that verification of
+ * 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 */
+NSS_CMSSignerInfo_Verify(NSSCMSSignerInfo *signerinfo,
+ SECItem *digest, /* may be NULL */
+ SECItem *contentType) /* may be NULL */
{
SECKEYPublicKey *publickey = NULL;
NSSCMSAttribute *attr;
@@ -319,152 +324,154 @@ NSS_CMSSignerInfo_Verify(NSSCMSSignerInfo *signerinfo,
CERTCertificate *cert;
NSSCMSVerificationStatus vs = NSSCMSVS_Unverified;
PLArenaPool *poolp;
- SECOidTag digestalgtag;
- SECOidTag pubkAlgTag;
+ SECOidTag digestalgtag;
+ SECOidTag pubkAlgTag;
if (signerinfo == NULL)
- return SECFailure;
+ return SECFailure;
- /* NSS_CMSSignerInfo_GetSigningCertificate will fail if 2nd parm is NULL
- ** and cert has not been verified
+ /* 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;
+ vs = NSSCMSVS_SigningCertNotFound;
+ goto loser;
}
if ((publickey = CERT_ExtractPublicKey(cert)) == NULL) {
- vs = NSSCMSVS_ProcessingError;
- goto loser;
+ 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;
+ vs = NSSCMSVS_SignatureAlgorithmUnknown;
+ goto loser;
}
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) {
- PORT_FreeArena(poolp, PR_FALSE);
- 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 :-( */
+ 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) {
+ PORT_FreeArena(poolp, PR_FALSE);
+ 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;
+ 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;
- }
+ 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);
+ SECKEY_DestroyPublicKey(publickey);
signerinfo->verificationStatus = vs;
@@ -472,11 +479,11 @@ NSS_CMSSignerInfo_Verify(NSSCMSSignerInfo *signerinfo,
loser:
if (publickey != NULL)
- SECKEY_DestroyPublicKey (publickey);
+ SECKEY_DestroyPublicKey(publickey);
signerinfo->verificationStatus = vs;
- PORT_SetError (SEC_ERROR_PKCS7_BAD_SIGNATURE);
+ PORT_SetError(SEC_ERROR_PKCS7_BAD_SIGNATURE);
return SECFailure;
}
@@ -490,27 +497,26 @@ SECOidData *
NSS_CMSSignerInfo_GetDigestAlg(NSSCMSSignerInfo *signerinfo)
{
SECOidData *algdata;
- SECOidTag algtag;
+ SECOidTag algtag;
- algdata = SECOID_FindOID (&(signerinfo->digestAlg.algorithm));
+ algdata = SECOID_FindOID(&(signerinfo->digestAlg.algorithm));
if (algdata == NULL) {
- return algdata;
+ 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,
+ /* 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);
+ /* 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
@@ -525,9 +531,9 @@ NSS_CMSSignerInfo_GetDigestAlgTag(NSSCMSSignerInfo *signerinfo)
algdata = NSS_CMSSignerInfo_GetDigestAlg(signerinfo);
if (algdata != NULL)
- return algdata->offset;
+ return algdata->offset;
else
- return SEC_OID_UNKNOWN;
+ return SEC_OID_UNKNOWN;
}
CERTCertificateList *
@@ -543,14 +549,14 @@ NSS_CMSSignerInfo_GetVersion(NSSCMSSignerInfo *signerinfo)
/* always take apart the SECItem */
if (SEC_ASN1DecodeInteger(&(signerinfo->version), &version) != SECSuccess)
- return 0;
+ return 0;
else
- return (int)version;
+ return (int)version;
}
/*
* NSS_CMSSignerInfo_GetSigningTime - return the signing time,
- * in UTCTime or GeneralizedTime format,
+ * in UTCTime or GeneralizedTime format,
* of a CMS signerInfo.
*
* sinfo - signerInfo data for this signer
@@ -565,20 +571,21 @@ NSS_CMSSignerInfo_GetSigningTime(NSSCMSSignerInfo *sinfo, PRTime *stime)
SECItem *value;
if (sinfo == NULL)
- return SECFailure;
+ return SECFailure;
if (sinfo->signingTime != 0) {
- *stime = sinfo->signingTime; /* cached copy */
- return SECSuccess;
+ *stime = sinfo->signingTime; /* cached copy */
+ return SECSuccess;
}
- attr = NSS_CMSAttributeArray_FindAttrByOidTag(sinfo->authAttr, SEC_OID_PKCS9_SIGNING_TIME, PR_TRUE);
+ 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;
+ return SECFailure;
if (DER_DecodeTimeChoice(stime, value) != SECSuccess)
- return SECFailure;
- sinfo->signingTime = *stime; /* make cached copy */
+ return SECFailure;
+ sinfo->signingTime = *stime; /* make cached copy */
return SECSuccess;
}
@@ -594,11 +601,11 @@ NSS_CMSSignerInfo_GetSigningCertificate(NSSCMSSignerInfo *signerinfo, CERTCertDB
NSSCMSSignerIdentifier *sid;
if (signerinfo->cert != NULL)
- return signerinfo->cert;
+ return signerinfo->cert;
/* no certdb, and cert hasn't been set yet? */
if (certdb == NULL)
- return NULL;
+ return NULL;
/*
* This cert will also need to be freed, but since we save it
@@ -608,19 +615,19 @@ NSS_CMSSignerInfo_GetSigningCertificate(NSSCMSSignerInfo *signerinfo, CERTCertDB
*/
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;
+ 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 */
+ signerinfo->cert = cert; /* earmark it */
return cert;
}
@@ -640,7 +647,7 @@ NSS_CMSSignerInfo_GetSignerCommonName(NSSCMSSignerInfo *sinfo)
/* will fail if cert is not verified */
if ((signercert = NSS_CMSSignerInfo_GetSigningCertificate(sinfo, NULL)) == NULL)
- return NULL;
+ return NULL;
return (CERT_GetCommonName(&signercert->subject));
}
@@ -659,17 +666,17 @@ NSS_CMSSignerInfo_GetSignerEmailAddress(NSSCMSSignerInfo *sinfo)
CERTCertificate *signercert;
if ((signercert = NSS_CMSSignerInfo_GetSigningCertificate(sinfo, NULL)) == NULL)
- return NULL;
+ return NULL;
if (!signercert->emailAddr || !signercert->emailAddr[0])
- return NULL;
+ return NULL;
return (PORT_Strdup(signercert->emailAddr));
}
/*
* NSS_CMSSignerInfo_AddAuthAttr - add an attribute to the
- * authenticated (i.e. signed) attributes of "signerinfo".
+ * authenticated (i.e. signed) attributes of "signerinfo".
*/
SECStatus
NSS_CMSSignerInfo_AddAuthAttr(NSSCMSSignerInfo *signerinfo, NSSCMSAttribute *attr)
@@ -679,7 +686,7 @@ NSS_CMSSignerInfo_AddAuthAttr(NSSCMSSignerInfo *signerinfo, NSSCMSAttribute *att
/*
* NSS_CMSSignerInfo_AddUnauthAttr - add an attribute to the
- * unauthenticated attributes of "signerinfo".
+ * unauthenticated attributes of "signerinfo".
*/
SECStatus
NSS_CMSSignerInfo_AddUnauthAttr(NSSCMSSignerInfo *signerinfo, NSSCMSAttribute *attr)
@@ -687,9 +694,9 @@ NSS_CMSSignerInfo_AddUnauthAttr(NSSCMSSignerInfo *signerinfo, NSSCMSAttribute *a
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".
+ * 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.
@@ -714,30 +721,30 @@ NSS_CMSSignerInfo_AddSigningTime(NSSCMSSignerInfo *signerinfo, PRTime t)
/* create new signing time attribute */
if (DER_EncodeTimeChoice(NULL, &stime, t) != SECSuccess)
- goto loser;
+ 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);
+ goto loser;
}
- SECITEM_FreeItem (&stime, PR_FALSE);
+ SECITEM_FreeItem(&stime, PR_FALSE);
if (NSS_CMSSignerInfo_AddAuthAttr(signerinfo, attr) != SECSuccess)
- goto loser;
+ goto loser;
- PORT_ArenaUnmark (poolp, mark);
+ PORT_ArenaUnmark(poolp, mark);
return SECSuccess;
loser:
- PORT_ArenaRelease (poolp, mark);
+ PORT_ArenaRelease(poolp, mark);
return SECFailure;
}
-/*
+/*
* NSS_CMSSignerInfo_AddSMIMECaps - add a SMIMECapabilities attribute to the
- * authenticated (i.e. signed) attributes of "signerinfo".
+ * authenticated (i.e. signed) attributes of "signerinfo".
*
* This is expected to be included in outgoing signed
* messages for email (S/MIME).
@@ -756,29 +763,29 @@ NSS_CMSSignerInfo_AddSMIMECaps(NSSCMSSignerInfo *signerinfo)
smimecaps = SECITEM_AllocItem(poolp, NULL, 0);
if (smimecaps == NULL)
- goto loser;
+ goto loser;
/* create new signing time attribute */
if (NSS_SMIMEUtil_CreateSMIMECapabilities(poolp, smimecaps) != SECSuccess)
- goto loser;
+ goto loser;
if ((attr = NSS_CMSAttribute_Create(poolp, SEC_OID_PKCS9_SMIME_CAPABILITIES, smimecaps, PR_TRUE)) == NULL)
- goto loser;
+ goto loser;
if (NSS_CMSSignerInfo_AddAuthAttr(signerinfo, attr) != SECSuccess)
- goto loser;
+ goto loser;
- PORT_ArenaUnmark (poolp, mark);
+ PORT_ArenaUnmark(poolp, mark);
return SECSuccess;
loser:
- PORT_ArenaRelease (poolp, mark);
+ PORT_ArenaRelease(poolp, mark);
return SECFailure;
}
-/*
+/*
* NSS_CMSSignerInfo_AddSMIMEEncKeyPrefs - add a SMIMEEncryptionKeyPreferences attribute to the
- * authenticated (i.e. signed) attributes of "signerinfo".
+ * authenticated (i.e. signed) attributes of "signerinfo".
*
* This is expected to be included in outgoing signed messages for email (S/MIME).
*/
@@ -792,7 +799,7 @@ NSS_CMSSignerInfo_AddSMIMEEncKeyPrefs(NSSCMSSignerInfo *signerinfo, CERTCertific
/* verify this cert for encryption */
if (CERT_VerifyCert(certdb, cert, PR_TRUE, certUsageEmailRecipient, PR_Now(), signerinfo->cmsg->pwfn_arg, NULL) != SECSuccess) {
- return SECFailure;
+ return SECFailure;
}
poolp = signerinfo->cmsg->poolp;
@@ -800,27 +807,27 @@ NSS_CMSSignerInfo_AddSMIMEEncKeyPrefs(NSSCMSSignerInfo *signerinfo, CERTCertific
smimeekp = SECITEM_AllocItem(poolp, NULL, 0);
if (smimeekp == NULL)
- goto loser;
+ goto loser;
/* create new signing time attribute */
if (NSS_SMIMEUtil_CreateSMIMEEncKeyPrefs(poolp, smimeekp, cert) != SECSuccess)
- goto loser;
+ goto loser;
if ((attr = NSS_CMSAttribute_Create(poolp, SEC_OID_SMIME_ENCRYPTION_KEY_PREFERENCE, smimeekp, PR_TRUE)) == NULL)
- goto loser;
+ goto loser;
if (NSS_CMSSignerInfo_AddAuthAttr(signerinfo, attr) != SECSuccess)
- goto loser;
+ goto loser;
- PORT_ArenaUnmark (poolp, mark);
+ PORT_ArenaUnmark(poolp, mark);
return SECSuccess;
loser:
- PORT_ArenaRelease (poolp, mark);
+ 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.
*
@@ -837,7 +844,7 @@ NSS_CMSSignerInfo_AddMSSMIMEEncKeyPrefs(NSSCMSSignerInfo *signerinfo, CERTCertif
/* verify this cert for encryption */
if (CERT_VerifyCert(certdb, cert, PR_TRUE, certUsageEmailRecipient, PR_Now(), signerinfo->cmsg->pwfn_arg, NULL) != SECSuccess) {
- return SECFailure;
+ return SECFailure;
}
poolp = signerinfo->cmsg->poolp;
@@ -845,27 +852,27 @@ NSS_CMSSignerInfo_AddMSSMIMEEncKeyPrefs(NSSCMSSignerInfo *signerinfo, CERTCertif
smimeekp = SECITEM_AllocItem(poolp, NULL, 0);
if (smimeekp == NULL)
- goto loser;
+ goto loser;
/* create new signing time attribute */
if (NSS_SMIMEUtil_CreateMSSMIMEEncKeyPrefs(poolp, smimeekp, cert) != SECSuccess)
- goto loser;
+ goto loser;
if ((attr = NSS_CMSAttribute_Create(poolp, SEC_OID_MS_SMIME_ENCRYPTION_KEY_PREFERENCE, smimeekp, PR_TRUE)) == NULL)
- goto loser;
+ goto loser;
if (NSS_CMSSignerInfo_AddAuthAttr(signerinfo, attr) != SECSuccess)
- goto loser;
+ goto loser;
- PORT_ArenaUnmark (poolp, mark);
+ PORT_ArenaUnmark(poolp, mark);
return SECSuccess;
loser:
- PORT_ArenaRelease (poolp, mark);
+ PORT_ArenaRelease(poolp, mark);
return SECFailure;
}
-/*
+/*
* NSS_CMSSignerInfo_AddCounterSignature - countersign a signerinfo
*
* 1. digest the DER-encoded signature value of the original signerinfo
@@ -880,7 +887,7 @@ loser:
*/
SECStatus
NSS_CMSSignerInfo_AddCounterSignature(NSSCMSSignerInfo *signerinfo,
- SECOidTag digestalg, CERTCertificate signingcert)
+ SECOidTag digestalg, CERTCertificate signingcert)
{
/* XXXX TBD XXXX */
return SECFailure;
@@ -907,42 +914,41 @@ NSS_SMIMESignerInfo_SaveSMIMEProfile(NSSCMSSignerInfo *signerinfo)
/* sanity check - see if verification status is ok (unverified does not count...) */
if (signerinfo->verificationStatus != NSSCMSVS_GoodSignature)
- return SECFailure;
+ 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;
+ (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;
+ /* 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.
+/* 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;
+ if (must_free_cert)
+ CERT_DestroyCertificate(cert);
+ return SECFailure;
}
#endif
@@ -955,25 +961,25 @@ NSS_SMIMESignerInfo_SaveSMIMEProfile(NSSCMSSignerInfo *signerinfo)
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);
+ 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);
+ rv = CERT_SaveSMimeProfile(cert, profile, stime);
if (must_free_cert)
- CERT_DestroyCertificate(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);
+ PORT_SetError(save_error);
return rv;
}
@@ -982,34 +988,37 @@ NSS_SMIMESignerInfo_SaveSMIMEProfile(NSSCMSSignerInfo *signerinfo)
* NSS_CMSSignerInfo_IncludeCerts - set cert chain inclusion mode for this signer
*/
SECStatus
-NSS_CMSSignerInfo_IncludeCerts(NSSCMSSignerInfo *signerinfo, NSSCMSCertChainMode cm, SECCertUsage usage)
+NSS_CMSSignerInfo_IncludeCerts(NSSCMSSignerInfo *signerinfo,
+ NSSCMSCertChainMode cm, SECCertUsage usage)
{
if (signerinfo->cert == NULL)
- return SECFailure;
+ return SECFailure;
/* don't leak if we get called twice */
if (signerinfo->certList != NULL) {
- CERT_DestroyCertificateList(signerinfo->certList);
- 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;
+ 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 SECFailure;
+
return SECSuccess;
}
diff --git a/nss/lib/smime/cmst.h b/nss/lib/smime/cmst.h
index 7376322..3d888bc 100644
--- a/nss/lib/smime/cmst.h
+++ b/nss/lib/smime/cmst.h
@@ -76,10 +76,8 @@ typedef struct NSSCMSDigestContextStr NSSCMSDigestContext;
typedef struct NSSCMSContentInfoPrivateStr NSSCMSContentInfoPrivate;
-typedef SECStatus (*NSSCMSGenericWrapperDataCallback)
- (NSSCMSGenericWrapperData *);
-typedef void (*NSSCMSGenericWrapperDataDestroy)
- (NSSCMSGenericWrapperData *);
+typedef SECStatus (*NSSCMSGenericWrapperDataCallback)(NSSCMSGenericWrapperData *);
+typedef void (*NSSCMSGenericWrapperDataDestroy)(NSSCMSGenericWrapperData *);
extern const SEC_ASN1Template NSSCMSGenericWrapperDataTemplate[];
extern const SEC_ASN1Template NSS_PointerToCMSGenericWrapperDataTemplate[];
@@ -87,8 +85,6 @@ 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"
@@ -110,44 +106,43 @@ typedef void (*NSSCMSContentCallback)(void *arg, const char *buf, unsigned long
*/
typedef PK11SymKey *(*NSSCMSGetDecryptKeyCallback)(void *arg, SECAlgorithmID *algid);
-
/* =============================================================================
* ENCAPSULATED CONTENTINFO & CONTENTINFO
*/
union NSSCMSContentUnion {
/* either unstructured */
- SECItem * data;
+ SECItem *data;
/* or structured data */
- NSSCMSDigestedData * digestedData;
- NSSCMSEncryptedData * encryptedData;
- NSSCMSEnvelopedData * envelopedData;
- NSSCMSSignedData * signedData;
- NSSCMSGenericWrapperData * genericData;
+ NSSCMSDigestedData *digestedData;
+ NSSCMSEncryptedData *encryptedData;
+ NSSCMSEnvelopedData *envelopedData;
+ NSSCMSSignedData *signedData;
+ NSSCMSGenericWrapperData *genericData;
/* or anonymous pointer to something */
- void * pointer;
+ void *pointer;
};
struct NSSCMSContentInfoStr {
- SECItem contentType;
- NSSCMSContent content;
+ SECItem contentType;
+ NSSCMSContent content;
/* --------- local; not part of encoding --------- */
- SECOidData * contentTypeTag;
+ 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? */
+ 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 */
+ 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 */
};
/* =============================================================================
@@ -155,28 +150,28 @@ struct NSSCMSContentInfoStr {
*/
struct NSSCMSMessageStr {
- NSSCMSContentInfo contentInfo; /* "outer" cinfo */
+ NSSCMSContentInfo contentInfo; /* "outer" cinfo */
/* --------- local; not part of encoding --------- */
- PLArenaPool * poolp;
- PRBool poolp_is_ours;
- int refCount;
+ PLArenaPool *poolp;
+ PRBool poolp_is_ours;
+ int refCount;
/* properties of the "inner" data */
- SECAlgorithmID ** detached_digestalgs;
- SECItem ** detached_digests;
- void * pwfn_arg;
+ SECAlgorithmID **detached_digestalgs;
+ SECItem **detached_digests;
+ void *pwfn_arg;
NSSCMSGetDecryptKeyCallback decrypt_key_cb;
- void * decrypt_key_cb_arg;
+ void *decrypt_key_cb_arg;
};
/* ============================================================================
* GENERIC WRAPPER
- *
+ *
* used for user defined types.
*/
struct NSSCMSGenericWrapperDataStr {
- NSSCMSContentInfo contentInfo;
+ NSSCMSContentInfo contentInfo;
/* ---- local; not part of encoding ------ */
- NSSCMSMessage * cmsg;
+ NSSCMSMessage *cmsg;
/* wrapperspecific data starts here */
};
@@ -185,23 +180,23 @@ struct NSSCMSGenericWrapperDataStr {
*/
struct NSSCMSSignedDataStr {
- SECItem version;
- SECAlgorithmID ** digestAlgorithms;
- NSSCMSContentInfo contentInfo;
- SECItem ** rawCerts;
- CERTSignedCrl ** crls;
- NSSCMSSignerInfo ** signerInfos;
+ 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 */
+ 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* */
+#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,
@@ -224,30 +219,30 @@ typedef enum {
struct NSSCMSSignerIdentifierStr {
NSSCMSSignerIDSelector identifierType;
union {
- CERTIssuerAndSN *issuerAndSN;
- SECItem *subjectKeyID;
+ CERTIssuerAndSN *issuerAndSN;
+ SECItem *subjectKeyID;
} id;
};
struct NSSCMSSignerInfoStr {
- SECItem version;
- NSSCMSSignerIdentifier signerIdentifier;
- SECAlgorithmID digestAlg;
- NSSCMSAttribute ** authAttr;
- SECAlgorithmID digestEncAlg;
- SECItem encDigest;
- NSSCMSAttribute ** unAuthAttr;
+ 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;
+ 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* */
+#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,
@@ -260,22 +255,22 @@ typedef enum {
* ENVELOPED DATA
*/
struct NSSCMSEnvelopedDataStr {
- SECItem version;
- NSSCMSOriginatorInfo * originatorInfo; /* optional */
- NSSCMSRecipientInfo ** recipientInfos;
- NSSCMSContentInfo contentInfo;
- NSSCMSAttribute ** unprotectedAttr;
+ SECItem version;
+ NSSCMSOriginatorInfo *originatorInfo; /* optional */
+ NSSCMSRecipientInfo **recipientInfos;
+ NSSCMSContentInfo contentInfo;
+ NSSCMSAttribute **unprotectedAttr;
/* --------- local; not part of encoding --------- */
- NSSCMSMessage * cmsg; /* back pointer to message */
+ 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* */
+#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;
+ SECItem **rawCerts;
+ CERTSignedCrl **crls;
/* --------- local; not part of encoding --------- */
- CERTCertificate ** certs;
+ CERTCertificate **certs;
};
/* -----------------------------------------------------------------------------
@@ -288,19 +283,19 @@ typedef enum {
} NSSCMSRecipientIDSelector;
struct NSSCMSRecipientIdentifierStr {
- NSSCMSRecipientIDSelector identifierType;
+ NSSCMSRecipientIDSelector identifierType;
union {
- CERTIssuerAndSN *issuerAndSN;
- SECItem *subjectKeyID;
+ CERTIssuerAndSN *issuerAndSN;
+ SECItem *subjectKeyID;
} id;
};
typedef struct NSSCMSRecipientIdentifierStr NSSCMSRecipientIdentifier;
struct NSSCMSKeyTransRecipientInfoStr {
- SECItem version;
- NSSCMSRecipientIdentifier recipientIdentifier;
- SECAlgorithmID keyEncAlg;
- SECItem encKey;
+ SECItem version;
+ NSSCMSRecipientIdentifier recipientIdentifier;
+ SECAlgorithmID keyEncAlg;
+ SECItem encKey;
};
typedef struct NSSCMSKeyTransRecipientInfoStr NSSCMSKeyTransRecipientInfo;
@@ -310,21 +305,21 @@ typedef struct NSSCMSKeyTransRecipientInfoStr NSSCMSKeyTransRecipientInfo;
*/
struct NSSCMSKeyTransRecipientInfoExStr {
NSSCMSKeyTransRecipientInfo recipientInfo;
- int version; /* version of this structure (0) */
+ 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* */
+#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! */
+ SECAlgorithmID algorithmIdentifier;
+ SECItem publicKey; /* bit string! */
};
typedef struct NSSCMSOriginatorPublicKeyStr NSSCMSOriginatorPublicKey;
@@ -337,17 +332,17 @@ typedef enum {
struct NSSCMSOriginatorIdentifierOrKeyStr {
NSSCMSOriginatorIDOrKeySelector identifierType;
union {
- CERTIssuerAndSN *issuerAndSN; /* static-static */
- SECItem *subjectKeyID; /* static-static */
- NSSCMSOriginatorPublicKey originatorPublicKey; /* ephemeral-static */
+ 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 */
+ SECItem *subjectKeyIdentifier;
+ SECItem *date; /* optional */
+ SECItem *other; /* optional */
};
typedef struct NSSCMSRecipientKeyIdentifierStr NSSCMSRecipientKeyIdentifier;
@@ -357,50 +352,50 @@ typedef enum {
} NSSCMSKeyAgreeRecipientIDSelector;
struct NSSCMSKeyAgreeRecipientIdentifierStr {
- NSSCMSKeyAgreeRecipientIDSelector identifierType;
+ NSSCMSKeyAgreeRecipientIDSelector identifierType;
union {
- CERTIssuerAndSN *issuerAndSN;
- NSSCMSRecipientKeyIdentifier recipientKeyIdentifier;
+ CERTIssuerAndSN *issuerAndSN;
+ NSSCMSRecipientKeyIdentifier recipientKeyIdentifier;
} id;
};
typedef struct NSSCMSKeyAgreeRecipientIdentifierStr NSSCMSKeyAgreeRecipientIdentifier;
struct NSSCMSRecipientEncryptedKeyStr {
- NSSCMSKeyAgreeRecipientIdentifier recipientIdentifier;
- SECItem encKey;
+ NSSCMSKeyAgreeRecipientIdentifier recipientIdentifier;
+ SECItem encKey;
};
typedef struct NSSCMSRecipientEncryptedKeyStr NSSCMSRecipientEncryptedKey;
struct NSSCMSKeyAgreeRecipientInfoStr {
- SECItem version;
- NSSCMSOriginatorIdentifierOrKey originatorIdentifierOrKey;
- SECItem * ukm; /* optional */
- SECAlgorithmID keyEncAlg;
- NSSCMSRecipientEncryptedKey ** recipientEncryptedKeys;
+ 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* */
+#define NSS_CMS_KEYAGREE_RECIPIENT_INFO_VERSION 3 /* what we *create* */
/* -----------------------------------------------------------------------------
* KEK recipient info
*/
struct NSSCMSKEKIdentifierStr {
- SECItem keyIdentifier;
- SECItem * date; /* optional */
- SECItem * other; /* optional */
+ SECItem keyIdentifier;
+ SECItem *date; /* optional */
+ SECItem *other; /* optional */
};
typedef struct NSSCMSKEKIdentifierStr NSSCMSKEKIdentifier;
struct NSSCMSKEKRecipientInfoStr {
- SECItem version;
- NSSCMSKEKIdentifier kekIdentifier;
- SECAlgorithmID keyEncAlg;
- SECItem encKey;
+ SECItem version;
+ NSSCMSKEKIdentifier kekIdentifier;
+ SECAlgorithmID keyEncAlg;
+ SECItem encKey;
};
typedef struct NSSCMSKEKRecipientInfoStr NSSCMSKEKRecipientInfo;
-#define NSS_CMS_KEK_RECIPIENT_INFO_VERSION 4 /* what we *create* */
+#define NSS_CMS_KEK_RECIPIENT_INFO_VERSION 4 /* what we *create* */
/* -----------------------------------------------------------------------------
* recipient info
@@ -414,12 +409,12 @@ typedef enum {
/*
* In order to preserve backwards binary compatibility when implementing
- * creation of Recipient Info's that uses subjectKeyID in the
+ * 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
+ * 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.
@@ -437,43 +432,43 @@ typedef enum {
struct NSSCMSRecipientInfoStr {
NSSCMSRecipientInfoIDSelector recipientInfoType;
union {
- NSSCMSKeyTransRecipientInfo keyTransRecipientInfo;
- NSSCMSKeyAgreeRecipientInfo keyAgreeRecipientInfo;
- NSSCMSKEKRecipientInfo kekRecipientInfo;
- NSSCMSKeyTransRecipientInfoEx keyTransRecipientInfoEx;
+ 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 */
+ NSSCMSMessage *cmsg; /* back pointer to message */
+ CERTCertificate *cert; /* recipient's certificate */
};
/* =============================================================================
* DIGESTED DATA
*/
struct NSSCMSDigestedDataStr {
- SECItem version;
- SECAlgorithmID digestAlg;
- NSSCMSContentInfo contentInfo;
- SECItem digest;
+ SECItem version;
+ SECAlgorithmID digestAlg;
+ NSSCMSContentInfo contentInfo;
+ SECItem digest;
/* --------- local; not part of encoding --------- */
- NSSCMSMessage * cmsg; /* back pointer */
- SECItem cdigest; /* calculated digest */
+ 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* */
+#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 */
+ SECItem version;
+ NSSCMSContentInfo contentInfo;
+ NSSCMSAttribute **unprotectedAttr; /* optional */
/* --------- local; not part of encoding --------- */
- NSSCMSMessage * cmsg; /* back pointer */
+ 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* */
+#define NSS_CMS_ENCRYPTED_DATA_VERSION 0 /* what we *create* */
+#define NSS_CMS_ENCRYPTED_DATA_VERSION_UPATTR 2 /* what we *create* */
/*
* *****************************************************************************
@@ -486,11 +481,11 @@ struct NSSCMSEncryptedDataStr {
*/
struct NSSCMSAttributeStr {
/* The following fields make up an encoded Attribute: */
- SECItem type;
- SECItem ** values; /* data may or may not be encoded */
+ 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 */
+ SECOidData *typeTag;
+ PRBool encoded; /* when true, values are encoded */
};
#endif /* _CMST_H_ */
diff --git a/nss/lib/smime/cmsudf.c b/nss/lib/smime/cmsudf.c
index 472b6d6..3ef4268 100644
--- a/nss/lib/smime/cmsudf.c
+++ b/nss/lib/smime/cmsudf.c
@@ -21,7 +21,7 @@ struct nsscmstypeInfoStr {
SEC_ASN1Template *template;
size_t size;
PRBool isData;
- NSSCMSGenericWrapperDataDestroy destroy;
+ NSSCMSGenericWrapperDataDestroy destroy;
NSSCMSGenericWrapperDataCallback decode_before;
NSSCMSGenericWrapperDataCallback decode_after;
NSSCMSGenericWrapperDataCallback decode_end;
@@ -49,29 +49,29 @@ SECStatus
nss_cmstype_shutdown(void *appData, void *reserved)
{
if (nsscmstypeHashLock) {
- PR_Lock(nsscmstypeHashLock);
+ PR_Lock(nsscmstypeHashLock);
}
if (nsscmstypeHash) {
- PL_HashTableDestroy(nsscmstypeHash);
- nsscmstypeHash = NULL;
+ PL_HashTableDestroy(nsscmstypeHash);
+ nsscmstypeHash = NULL;
}
if (nsscmstypeArena) {
- PORT_FreeArena(nsscmstypeArena, PR_FALSE);
- nsscmstypeArena = NULL;
+ PORT_FreeArena(nsscmstypeArena, PR_FALSE);
+ nsscmstypeArena = NULL;
}
if (nsscmstypeAddLock) {
- PR_DestroyLock(nsscmstypeAddLock);
+ PR_DestroyLock(nsscmstypeAddLock);
}
if (nsscmstypeHashLock) {
- PRLock *oldLock = nsscmstypeHashLock;
- nsscmstypeHashLock = NULL;
- PR_Unlock(oldLock);
- PR_DestroyLock(oldLock);
+ 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;
+ nsscmstypeOnce = nsscmstypeClearOnce;
}
return SECSuccess;
}
@@ -79,16 +79,16 @@ nss_cmstype_shutdown(void *appData, void *reserved)
static PLHashNumber
nss_cmstype_hash_key(const void *key)
{
- return (PLHashNumber)((char *)key - (char *)NULL);
+ return (PLHashNumber)((char *)key - (char *)NULL);
}
static PRIntn
nss_cmstype_compare_keys(const void *v1, const void *v2)
{
- PLHashNumber value1 = nss_cmstype_hash_key(v1);
- PLHashNumber value2 = nss_cmstype_hash_key(v2);
+ PLHashNumber value1 = nss_cmstype_hash_key(v1);
+ PLHashNumber value2 = nss_cmstype_hash_key(v2);
- return (value1 == value2);
+ return (value1 == value2);
}
/*
@@ -99,27 +99,28 @@ static PRStatus
nss_cmstype_init(void)
{
SECStatus rv;
-
+
nsscmstypeHashLock = PR_NewLock();
if (nsscmstypeHashLock == NULL) {
- return PR_FAILURE;
+ return PR_FAILURE;
}
nsscmstypeAddLock = PR_NewLock();
if (nsscmstypeHashLock == NULL) {
- goto fail;
+ goto fail;
}
- nsscmstypeHash = PL_NewHashTable(64, nss_cmstype_hash_key,
- nss_cmstype_compare_keys, PL_CompareValues, NULL, NULL);
+ nsscmstypeHash = PL_NewHashTable(64, nss_cmstype_hash_key,
+ nss_cmstype_compare_keys,
+ PL_CompareValues, NULL, NULL);
if (nsscmstypeHash == NULL) {
- goto fail;
+ goto fail;
}
nsscmstypeArena = PORT_NewArena(2048);
if (nsscmstypeArena == NULL) {
- goto fail;
+ goto fail;
}
rv = NSS_RegisterShutdown(nss_cmstype_shutdown, NULL);
if (rv != SECSuccess) {
- goto fail;
+ goto fail;
}
return PR_SUCCESS;
@@ -128,20 +129,20 @@ fail:
return PR_FAILURE;
}
-
/*
* look up and registered SIME type
*/
static const nsscmstypeInfo *
nss_cmstype_lookup(SECOidTag type)
{
- nsscmstypeInfo *typeInfo = NULL;;
+ nsscmstypeInfo *typeInfo = NULL;
+ ;
if (!nsscmstypeHash) {
- return NULL;
+ return NULL;
}
PR_Lock(nsscmstypeHashLock);
if (nsscmstypeHash) {
- typeInfo = PL_HashTableLookupConst(nsscmstypeHash, (void *)type);
+ typeInfo = PL_HashTableLookupConst(nsscmstypeHash, (void *)type);
}
PR_Unlock(nsscmstypeHashLock);
return typeInfo;
@@ -156,22 +157,21 @@ nss_cmstype_add(SECOidTag type, nsscmstypeInfo *typeinfo)
PLHashEntry *entry;
if (!nsscmstypeHash) {
- /* assert? this shouldn't happen */
- return SECFailure;
+ /* 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;
+ 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
*/
@@ -181,16 +181,16 @@ 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;
- }
+ 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;
}
@@ -201,13 +201,13 @@ 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;
- }
+ case SEC_OID_PKCS7_DATA:
+ return PR_TRUE;
+ default:
+ typeInfo = nss_cmstype_lookup(type);
+ if (typeInfo && typeInfo->isData) {
+ return PR_TRUE;
+ }
}
return PR_FALSE;
}
@@ -218,7 +218,7 @@ NSS_CMSType_GetTemplate(SECOidTag type)
const nsscmstypeInfo *typeInfo = nss_cmstype_lookup(type);
if (typeInfo && typeInfo->template) {
- return typeInfo->template;
+ return typeInfo->template;
}
return SEC_ASN1_GET(SEC_PointerToOctetStringTemplate);
}
@@ -229,10 +229,9 @@ NSS_CMSType_GetContentSize(SECOidTag type)
const nsscmstypeInfo *typeInfo = nss_cmstype_lookup(type);
if (typeInfo) {
- return typeInfo->size;
+ return typeInfo->size;
}
return sizeof(SECItem *);
-
}
void
@@ -241,191 +240,187 @@ NSS_CMSGenericWrapperData_Destroy(SECOidTag type, NSSCMSGenericWrapperData *gd)
const nsscmstypeInfo *typeInfo = nss_cmstype_lookup(type);
if (typeInfo && typeInfo->destroy) {
- (*typeInfo->destroy)(gd);
+ (*typeInfo->destroy)(gd);
}
-
}
-
SECStatus
-NSS_CMSGenericWrapperData_Decode_BeforeData(SECOidTag type,
- NSSCMSGenericWrapperData *gd)
+NSS_CMSGenericWrapperData_Decode_BeforeData(SECOidTag type,
+ NSSCMSGenericWrapperData *gd)
{
const nsscmstypeInfo *typeInfo;
/* short cut common case */
if (type == SEC_OID_PKCS7_DATA) {
- return SECSuccess;
+ 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;
- }
+ 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)
+NSS_CMSGenericWrapperData_Decode_AfterData(SECOidTag type,
+ NSSCMSGenericWrapperData *gd)
{
const nsscmstypeInfo *typeInfo;
/* short cut common case */
if (type == SEC_OID_PKCS7_DATA) {
- return SECSuccess;
+ 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;
- }
+ 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)
+NSS_CMSGenericWrapperData_Decode_AfterEnd(SECOidTag type,
+ NSSCMSGenericWrapperData *gd)
{
const nsscmstypeInfo *typeInfo;
/* short cut common case */
if (type == SEC_OID_PKCS7_DATA) {
- return SECSuccess;
+ 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;
- }
+ 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)
+NSS_CMSGenericWrapperData_Encode_BeforeStart(SECOidTag type,
+ NSSCMSGenericWrapperData *gd)
{
const nsscmstypeInfo *typeInfo;
/* short cut common case */
if (type == SEC_OID_PKCS7_DATA) {
- return SECSuccess;
+ 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;
- }
+ 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)
+NSS_CMSGenericWrapperData_Encode_BeforeData(SECOidTag type,
+ NSSCMSGenericWrapperData *gd)
{
const nsscmstypeInfo *typeInfo;
/* short cut common case */
if (type == SEC_OID_PKCS7_DATA) {
- return SECSuccess;
+ 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;
- }
+ 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)
+NSS_CMSGenericWrapperData_Encode_AfterData(SECOidTag type,
+ NSSCMSGenericWrapperData *gd)
{
const nsscmstypeInfo *typeInfo;
/* short cut common case */
if (type == SEC_OID_PKCS7_DATA) {
- return SECSuccess;
+ 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;
- }
+ 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)
+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);
+ rc = PR_CallOnce(&nsscmstypeOnce, nss_cmstype_init);
if (rc == PR_FAILURE) {
- return SECFailure;
+ return SECFailure;
}
PR_Lock(nsscmstypeAddLock);
exists = nss_cmstype_lookup(type);
if (exists) {
- PR_Unlock(nsscmstypeAddLock);
- /* already added */
- return SECSuccess;
+ PR_Unlock(nsscmstypeAddLock);
+ /* already added */
+ return SECSuccess;
}
typeInfo = PORT_ArenaNew(nsscmstypeArena, nsscmstypeInfo);
typeInfo->type = type;
@@ -443,4 +438,3 @@ NSS_CMSType_RegisterContentType(SECOidTag type,
PR_Unlock(nsscmstypeAddLock);
return rv;
}
-
diff --git a/nss/lib/smime/cmsutil.c b/nss/lib/smime/cmsutil.c
index 2fe8564..cd12603 100644
--- a/nss/lib/smime/cmsutil.c
+++ b/nss/lib/smime/cmsutil.c
@@ -33,16 +33,16 @@ NSS_CMSArray_SortByDER(void **objs, const SEC_ASN1Template *objtemplate, void **
SECStatus rv = SECFailure;
int i;
- if (objs == NULL) /* already sorted */
- return SECSuccess;
+ 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;
+ if (num_objs == 0 || num_objs == 1) /* already sorted. */
+ return SECSuccess;
- poolp = PORT_NewArena (1024); /* arena for temporaries */
+ poolp = PORT_NewArena(1024); /* arena for temporaries */
if (poolp == NULL)
- return SECFailure; /* no memory; nothing we can do... */
+ return SECFailure; /* no memory; nothing we can do... */
/*
* Allocate arrays to hold the individual encodings which we will use
@@ -50,13 +50,13 @@ NSS_CMSArray_SortByDER(void **objs, const SEC_ASN1Template *objtemplate, void **
*/
enc_objs = (SECItem **)PORT_ArenaZAlloc(poolp, (num_objs + 1) * sizeof(SECItem *));
if (enc_objs == NULL)
- goto loser;
+ 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[i] = SEC_ASN1EncodeItem(poolp, NULL, objs[i], objtemplate);
+ if (enc_objs[i] == NULL)
+ goto loser;
}
enc_objs[num_objs] = NULL;
@@ -66,7 +66,7 @@ NSS_CMSArray_SortByDER(void **objs, const SEC_ASN1Template *objtemplate, void **
rv = SECSuccess;
loser:
- PORT_FreeArena (poolp, PR_FALSE);
+ PORT_FreeArena(poolp, PR_FALSE);
return rv;
}
@@ -93,25 +93,25 @@ NSS_CMSUtil_DERCompare(void *a, void *b)
* is found.
*/
if (der1->len != der2->len)
- return (der1->len < der2->len) ? -1 : 1;
+ 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;
+ 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
+ * 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
+ * An integer containing the index of the algorithm in the array or -1 if
* algorithm was not found.
*/
int
@@ -120,58 +120,58 @@ NSS_CMSAlgArray_GetIndexByAlgID(SECAlgorithmID **algorithmArray, SECAlgorithmID
int i;
if (algorithmArray == NULL || algorithmArray[0] == NULL)
- return -1;
+ return -1;
for (i = 0; algorithmArray[i] != NULL; i++) {
- if (SECOID_CompareAlgorithmID(algorithmArray[i], algid) == SECEqual)
- break; /* bingo */
+ if (SECOID_CompareAlgorithmID(algorithmArray[i], algid) == SECEqual)
+ break; /* bingo */
}
if (algorithmArray[i] == NULL)
- return -1; /* not found */
+ return -1; /* not found */
return i;
}
/*
- * NSS_CMSAlgArray_GetIndexByAlgTag - find a specific algorithm in an array of
+ * 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
+ * An integer containing the index of the algorithm in the array or -1 if
* algorithm was not found.
*/
int
-NSS_CMSAlgArray_GetIndexByAlgTag(SECAlgorithmID **algorithmArray,
+NSS_CMSAlgArray_GetIndexByAlgTag(SECAlgorithmID **algorithmArray,
SECOidTag algtag)
{
SECOidData *algid;
int i = -1;
if (algorithmArray == NULL || algorithmArray[0] == NULL)
- return i;
+ 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 */
+ algid = SECOID_FindOID(&(algorithmArray[i]->algorithm));
+ if (algid->offset == algtag)
+ break; /* bingo */
}
#else
algid = SECOID_FindOIDByTag(algtag);
- if (!algid)
- return i;
+ if (!algid)
+ return i;
for (i = 0; algorithmArray[i] != NULL; i++) {
- if (SECITEM_ItemsAreEqual(&algorithmArray[i]->algorithm, &algid->oid))
- break; /* bingo */
+ if (SECITEM_ItemsAreEqual(&algorithmArray[i]->algorithm, &algid->oid))
+ break; /* bingo */
}
#endif
if (algorithmArray[i] == NULL)
- return -1; /* not found */
+ return -1; /* not found */
return i;
}
@@ -185,31 +185,31 @@ 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;
+ 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;
@@ -234,21 +234,21 @@ NSS_CMSUtil_GetTemplateByTypeTag(SECOidTag type)
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;
+ 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;
}
@@ -259,21 +259,21 @@ 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;
+ 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;
}
@@ -285,26 +285,26 @@ NSS_CMSContent_GetContentInfo(void *msg, SECOidTag type)
NSSCMSContentInfo *cinfo = NULL;
if (!msg)
- return cinfo;
+ 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);
- }
+ 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;
}
@@ -313,45 +313,55 @@ 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";
+ 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,
+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;
+ 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;
+ 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_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);
+ PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
}
return rv;
}
-
diff --git a/nss/lib/smime/exports.gyp b/nss/lib/smime/exports.gyp
new file mode 100644
index 0000000..3865bb4
--- /dev/null
+++ b/nss/lib/smime/exports.gyp
@@ -0,0 +1,34 @@
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+{
+ 'includes': [
+ '../../coreconf/config.gypi'
+ ],
+ 'targets': [
+ {
+ 'target_name': 'lib_smime_exports',
+ 'type': 'none',
+ 'copies': [
+ {
+ 'files': [
+ 'cms.h',
+ 'cmsreclist.h',
+ 'cmst.h',
+ 'smime.h'
+ ],
+ 'destination': '<(nss_public_dist_dir)/<(module)'
+ },
+ {
+ 'files': [
+ 'cmslocal.h'
+ ],
+ 'destination': '<(nss_private_dist_dir)/<(module)'
+ }
+ ]
+ }
+ ],
+ 'variables': {
+ 'module': 'nss'
+ }
+}
diff --git a/nss/lib/smime/smime.gyp b/nss/lib/smime/smime.gyp
new file mode 100644
index 0000000..fa74cd9
--- /dev/null
+++ b/nss/lib/smime/smime.gyp
@@ -0,0 +1,80 @@
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+{
+ 'includes': [
+ '../../coreconf/config.gypi'
+ ],
+ 'targets': [
+ {
+ 'target_name': 'smime',
+ 'type': 'static_library',
+ 'sources': [
+ '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'
+ ],
+ 'dependencies': [
+ '<(DEPTH)/exports.gyp:nss_exports',
+ ]
+ },
+ {
+ # This is here so Firefox can link this without having to
+ # repeat the list of dependencies.
+ 'target_name': 'smime3_deps',
+ 'type': 'none',
+ 'dependencies': [
+ 'smime',
+ '<(DEPTH)/lib/pkcs12/pkcs12.gyp:pkcs12',
+ '<(DEPTH)/lib/pkcs7/pkcs7.gyp:pkcs7'
+ ],
+ },
+ {
+ 'target_name': 'smime3',
+ 'type': 'shared_library',
+ 'dependencies': [
+ 'smime3_deps',
+ '<(DEPTH)/lib/nss/nss.gyp:nss3',
+ '<(DEPTH)/lib/util/util.gyp:nssutil3'
+ ],
+ 'variables': {
+ 'mapfile': 'smime.def'
+ }
+ }
+ ],
+ 'conditions': [
+ [ 'moz_fold_libs==1', {
+ 'targets': [
+ {
+ 'target_name': 'smime3_static',
+ 'type': 'static_library',
+ 'dependencies': [
+ 'smime3_deps',
+ ],
+ }
+ ],
+ }],
+ ],
+ 'variables': {
+ 'module': 'nss'
+ }
+}
diff --git a/nss/lib/smime/smime.h b/nss/lib/smime/smime.h
index b1a7a0f..e534ef0 100644
--- a/nss/lib/smime/smime.h
+++ b/nss/lib/smime/smime.h
@@ -12,7 +12,6 @@
#include "cms.h"
-
/************************************************************************/
SEC_BEGIN_PROTOS
@@ -39,9 +38,9 @@ SEC_BEGIN_PROTOS
* 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)
+ * 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);
@@ -78,8 +77,8 @@ extern PRBool NSS_SMIMEUtil_DecryptionAllowed(SECAlgorithmID *algid, PK11SymKey
*
* 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)
+ * (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.
@@ -97,24 +96,28 @@ extern SECStatus NSS_SMIMEUtil_CreateSMIMECapabilities(PLArenaPool *poolp, SECIt
/*
* NSS_SMIMEUtil_CreateSMIMEEncKeyPrefs - create S/MIME encryption key preferences attr value
*/
-extern SECStatus NSS_SMIMEUtil_CreateSMIMEEncKeyPrefs(PLArenaPool *poolp, SECItem *dest, CERTCertificate *cert);
+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);
+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);
+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);
+NSS_SMIMEUtil_FindBulkAlgForRecipients(CERTCertificate **rcerts,
+ SECOidTag *bulkalgtag, int *keysize);
/*
* Return a boolean that indicates whether the underlying library
diff --git a/nss/lib/smime/smimemessage.c b/nss/lib/smime/smimemessage.c
index ec69b44..774b9f3 100644
--- a/nss/lib/smime/smimemessage.c
+++ b/nss/lib/smime/smimemessage.c
@@ -18,7 +18,6 @@
#include "prtime.h"
#include "secerr.h"
-
#if 0
/*
* NSS_SMIMEMessage_CreateEncrypted - start an S/MIME encrypting context.
@@ -39,10 +38,10 @@
*/
NSSCMSMessage *
NSS_SMIMEMessage_CreateEncrypted(CERTCertificate *scert,
- CERTCertificate **rcerts,
- CERTCertDBHandle *certdb,
- PK11PasswordFunc pwfn,
- void *pwfn_arg)
+ CERTCertificate **rcerts,
+ CERTCertDBHandle *certdb,
+ PK11PasswordFunc pwfn,
+ void *pwfn_arg)
{
NSSCMSMessage *cmsg;
long cipher;
@@ -52,11 +51,11 @@ NSS_SMIMEMessage_CreateEncrypted(CERTCertificate *scert,
cipher = smime_choose_cipher (scert, rcerts);
if (cipher < 0)
- return NULL;
+ return NULL;
mapi = smime_mapi_by_cipher (cipher);
if (mapi < 0)
- return NULL;
+ return NULL;
/*
* XXX This is stretching it -- CreateEnvelopedData should probably
@@ -69,22 +68,22 @@ NSS_SMIMEMessage_CreateEncrypted(CERTCertificate *scert,
encalg = smime_cipher_map[mapi].algtag;
keysize = smime_keysize_by_cipher (cipher);
if (keysize < 0)
- return NULL;
+ return NULL;
cinfo = SEC_PKCS7CreateEnvelopedData (scert, certUsageEmailRecipient,
- certdb, encalg, keysize,
- pwfn, pwfn_arg);
+ certdb, encalg, keysize,
+ pwfn, pwfn_arg);
if (cinfo == NULL)
- return 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;
- }
+ if (rcerts[rci] == scert)
+ continue;
+ if (SEC_PKCS7AddRecipient (cinfo, rcerts[rci], certUsageEmailRecipient,
+ NULL) != SECSuccess) {
+ SEC_PKCS7DestroyContentInfo (cinfo);
+ return NULL;
+ }
}
return cinfo;
@@ -103,7 +102,7 @@ NSS_SMIMEMessage_CreateEncrypted(CERTCertificate *scert,
*
* "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
@@ -123,12 +122,12 @@ NSS_SMIMEMessage_CreateEncrypted(CERTCertificate *scert,
NSSCMSMessage *
NSS_SMIMEMessage_CreateSigned(CERTCertificate *scert,
- CERTCertificate *ecert,
- CERTCertDBHandle *certdb,
- SECOidTag digestalgtag,
- SECItem *digest,
- PK11PasswordFunc pwfn,
- void *pwfn_arg)
+ CERTCertificate *ecert,
+ CERTCertDBHandle *certdb,
+ SECOidTag digestalgtag,
+ SECItem *digest,
+ PK11PasswordFunc pwfn,
+ void *pwfn_arg)
{
NSSCMSMessage *cmsg;
NSSCMSSignedData *sigd;
@@ -139,46 +138,46 @@ NSS_SMIMEMessage_CreateSigned(CERTCertificate *scert,
cmsg = NSS_CMSMessage_Create(NULL);
if (cmsg == NULL)
- return NULL;
+ return NULL;
sigd = NSS_CMSSignedData_Create(cmsg);
if (sigd == NULL)
- goto loser;
+ goto loser;
/* create just one signerinfo */
signerinfo = NSS_CMSSignerInfo_Create(cmsg, scert, digestalgtag);
if (signerinfo == NULL)
- goto loser;
+ goto loser;
/* Add the signing time to the signerinfo. */
if (NSS_CMSSignerInfo_AddSigningTime(signerinfo, PR_Now()) != SECSuccess)
- goto loser;
-
+ goto loser;
+
/* and add the SMIME profile */
if (NSS_SMIMESignerInfo_AddSMIMEProfile(signerinfo, scert) != SECSuccess)
- goto loser;
+ goto loser;
/* now add the signerinfo to the signeddata */
if (NSS_CMSSignedData_AddSignerInfo(sigd, signerinfo) != SECSuccess)
- goto loser;
+ 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;
+ 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;
+ if (NSS_CMSSignedData_AddCertificate(sigd, ecert) != SECSuccess)
+ goto loser;
}
return cmsg;
loser:
if (cmsg)
- NSS_CMSMessage_Destroy(cmsg);
+ NSS_CMSMessage_Destroy(cmsg);
return NULL;
}
#endif
diff --git a/nss/lib/smime/smimesym.c b/nss/lib/smime/smimesym.c
index 8ed6cbf..2ae39f4 100644
--- a/nss/lib/smime/smimesym.c
+++ b/nss/lib/smime/smimesym.c
@@ -5,8 +5,8 @@
extern void SEC_PKCS7DecodeItem();
extern void SEC_PKCS7DestroyContentInfo();
-smime_CMDExports() {
- SEC_PKCS7DecodeItem();
- SEC_PKCS7DestroyContentInfo();
+smime_CMDExports()
+{
+ SEC_PKCS7DecodeItem();
+ SEC_PKCS7DestroyContentInfo();
}
-
diff --git a/nss/lib/smime/smimeutil.c b/nss/lib/smime/smimeutil.c
index 84d1960..7674a65 100644
--- a/nss/lib/smime/smimeutil.c
+++ b/nss/lib/smime/smimeutil.c
@@ -9,7 +9,7 @@
#include "secmime.h"
#include "secoid.h"
#include "pk11func.h"
-#include "ciferfam.h" /* for CIPHER_FAMILY symbols */
+#include "ciferfam.h" /* for CIPHER_FAMILY symbols */
#include "secasn1.h"
#include "secitem.h"
#include "cert.h"
@@ -40,17 +40,17 @@ static SECItem param_int128 = { siBuffer, asn1_int128, sizeof(asn1_int128) };
typedef struct {
SECItem capabilityID;
SECItem parameters;
- long cipher; /* optimization */
+ long cipher; /* optimization */
} NSSSMIMECapability;
static const SEC_ASN1Template NSSSMIMECapabilityTemplate[] = {
{ SEC_ASN1_SEQUENCE,
- 0, NULL, sizeof(NSSSMIMECapability) },
+ 0, NULL, sizeof(NSSSMIMECapability) },
{ SEC_ASN1_OBJECT_ID,
- offsetof(NSSSMIMECapability,capabilityID), },
+ offsetof(NSSSMIMECapability, capabilityID) },
{ SEC_ASN1_OPTIONAL | SEC_ASN1_ANY,
- offsetof(NSSSMIMECapability,parameters), },
- { 0, }
+ offsetof(NSSSMIMECapability, parameters) },
+ { 0 }
};
static const SEC_ASN1Template NSSSMIMECapabilitiesTemplate[] = {
@@ -70,9 +70,9 @@ typedef enum {
typedef struct {
NSSSMIMEEncryptionKeyPrefSelector selector;
union {
- CERTIssuerAndSN *issuerAndSN;
- NSSCMSRecipientKeyIdentifier *recipientKeyID;
- SECItem *subjectKeyID;
+ CERTIssuerAndSN *issuerAndSN;
+ NSSCMSRecipientKeyIdentifier *recipientKeyID;
+ SECItem *subjectKeyID;
} id;
} NSSSMIMEEncryptionKeyPreference;
@@ -80,24 +80,21 @@ 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, }
+ 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 */
@@ -105,21 +102,21 @@ typedef struct {
unsigned long cipher;
SECOidTag algtag;
SECItem *parms;
- PRBool enabled; /* in the user's preferences */
- PRBool allowed; /* per export policy */
+ 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 }
+ /* 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);
@@ -132,16 +129,16 @@ 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 */
+ if (smime_cipher_map[i].cipher == cipher)
+ return i; /* bingo */
}
- return -1; /* should not happen if we're consistent, right? */
+ return -1; /* should not happen if we're consistent, right? */
}
/*
* NSS_SMIME_EnableCipher - this function locally records the user's preference
*/
-SECStatus
+SECStatus
NSS_SMIMEUtil_EnableCipher(unsigned long which, PRBool on)
{
unsigned long mask;
@@ -149,33 +146,32 @@ NSS_SMIMEUtil_EnableCipher(unsigned long which, PRBool on)
mask = which & CIPHER_FAMILYID_MASK;
- PORT_Assert (mask == CIPHER_FAMILYID_SMIME);
+ PORT_Assert(mask == CIPHER_FAMILYID_SMIME);
if (mask != CIPHER_FAMILYID_SMIME)
- /* XXX set an error! */
- return SECFailure;
+ /* XXX set an error! */
+ return SECFailure;
mapi = smime_mapi_by_cipher(which);
if (mapi < 0)
- /* XXX set an error */
- return SECFailure;
+ /* 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;
+ PORT_SetError(SEC_ERROR_BAD_EXPORT_ALGORITHM);
+ return SECFailure;
}
if (smime_cipher_map[mapi].enabled != on)
- smime_cipher_map[mapi].enabled = on;
+ smime_cipher_map[mapi].enabled = on;
return SECSuccess;
}
-
/*
* this function locally records the export policy
*/
-SECStatus
+SECStatus
NSS_SMIMEUtil_AllowCipher(unsigned long which, PRBool on)
{
unsigned long mask;
@@ -183,18 +179,18 @@ NSS_SMIMEUtil_AllowCipher(unsigned long which, PRBool on)
mask = which & CIPHER_FAMILYID_MASK;
- PORT_Assert (mask == CIPHER_FAMILYID_SMIME);
+ PORT_Assert(mask == CIPHER_FAMILYID_SMIME);
if (mask != CIPHER_FAMILYID_SMIME)
- /* XXX set an error! */
- return SECFailure;
+ /* XXX set an error! */
+ return SECFailure;
mapi = smime_mapi_by_cipher(which);
if (mapi < 0)
- /* XXX set an error */
- return SECFailure;
+ /* XXX set an error */
+ return SECFailure;
if (smime_cipher_map[mapi].allowed != on)
- smime_cipher_map[mapi].allowed = on;
+ smime_cipher_map[mapi].allowed = on;
return SECSuccess;
}
@@ -206,7 +202,8 @@ NSS_SMIMEUtil_AllowCipher(unsigned long which, PRBool on)
* 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)
+nss_smime_get_cipher_for_alg_and_key(SECAlgorithmID *algid, PK11SymKey *key,
+ unsigned long *cipher)
{
SECOidTag algtag;
unsigned int keylen_bits;
@@ -214,37 +211,37 @@ nss_smime_get_cipher_for_alg_and_key(SECAlgorithmID *algid, PK11SymKey *key, uns
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;
+ 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;
@@ -257,7 +254,7 @@ nss_smime_cipher_allowed(unsigned long which)
mapi = smime_mapi_by_cipher(which);
if (mapi < 0)
- return PR_FALSE;
+ return PR_FALSE;
return smime_cipher_map[mapi].allowed;
}
@@ -267,12 +264,11 @@ 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 PR_FALSE;
return nss_smime_cipher_allowed(which);
}
-
/*
* NSS_SMIME_EncryptionPossible - check if any encryption is allowed
*
@@ -285,8 +281,8 @@ NSS_SMIMEUtil_DecryptionAllowed(SECAlgorithmID *algid, PK11SymKey *key)
*
* 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)
+ * (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.
@@ -297,13 +293,12 @@ NSS_SMIMEUtil_EncryptionPossible(void)
int i;
for (i = 0; i < smime_cipher_map_count; i++) {
- if (smime_cipher_map[i].allowed)
- return PR_TRUE;
+ if (smime_cipher_map[i].allowed)
+ return PR_TRUE;
}
return PR_FALSE;
}
-
static int
nss_SMIME_FindCipherForSMIMECap(NSSSMIMECapability *cap)
{
@@ -315,32 +310,31 @@ nss_SMIME_FindCipherForSMIMECap(NSSSMIMECapability *cap)
/* 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 (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 */
+ return 0; /* no match found */
+ return smime_cipher_map[i].cipher; /* match found, point to cipher */
}
/*
@@ -363,145 +357,144 @@ smime_choose_cipher(CERTCertificate *scert, CERTCertificate **rcerts)
int aes256_mapi;
int rcount, mapi, max, i;
- chosen_cipher = SMIME_RC2_CBC_40; /* the default, LCD */
+ 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? */
+ poolp = PORT_NewArena(1024); /* XXX what is right value? */
if (poolp == NULL)
- goto done;
+ 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));
+ cipher_votes = (int *)PORT_ArenaZAlloc(poolp, smime_cipher_map_count * sizeof(int));
if (cipher_votes == NULL || cipher_abilities == NULL)
- goto done;
+ goto done;
/* Make triple-DES the strong cipher. */
- strong_mapi = smime_mapi_by_cipher (SMIME_DES_EDE3_168);
+ 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;
- key_type = nullKey;
- if (key != NULL) {
- pklen_bits = SECKEY_PublicKeyStrengthInBits (key);
- key_type = SECKEY_GetPublicKeyType(key);
- SECKEY_DestroyPublicKey (key);
- key = NULL;
- }
-
- 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);
+ 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;
+ key_type = nullKey;
+ if (key != NULL) {
+ pklen_bits = SECKEY_PublicKeyStrengthInBits(key);
+ key_type = SECKEY_GetPublicKeyType(key);
+ SECKEY_DestroyPublicKey(key);
+ key = NULL;
+ }
+
+ 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 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 */
+/* if no common cipher was found, chosen_cipher stays at the default */
done:
if (poolp != NULL)
- PORT_FreeArena (poolp, PR_FALSE);
+ PORT_FreeArena(poolp, PR_FALSE);
return chosen_cipher;
}
@@ -512,35 +505,35 @@ done:
* looking up the keysize is not going to be sufficient.
*/
static int
-smime_keysize_by_cipher (unsigned long which)
+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;
+ 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;
@@ -553,7 +546,8 @@ smime_keysize_by_cipher (unsigned long which)
* prevented a strong cipher from being used...
*/
SECStatus
-NSS_SMIMEUtil_FindBulkAlgForRecipients(CERTCertificate **rcerts, SECOidTag *bulkalgtag, int *keysize)
+NSS_SMIMEUtil_FindBulkAlgForRecipients(CERTCertificate **rcerts,
+ SECOidTag *bulkalgtag, int *keysize)
{
unsigned long cipher;
int mapi;
@@ -591,10 +585,9 @@ NSS_SMIMEUtil_CreateSMIMECapabilities(PLArenaPool *poolp, SECItem *dest)
/* 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 *));
+ smime_capabilities = (NSSSMIMECapability **)PORT_ZAlloc((smime_cipher_map_count + 1) * sizeof(NSSSMIMECapability *));
if (smime_capabilities == NULL)
- return SECFailure;
+ return SECFailure;
capIndex = 0;
@@ -603,38 +596,38 @@ NSS_SMIMEUtil_CreateSMIMECapabilities(PLArenaPool *poolp, SECItem *dest)
* 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;
+ /* 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 */
+ 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[i]);
PORT_Free(smime_capabilities);
return (dummy == NULL) ? SECFailure : SECSuccess;
@@ -656,22 +649,23 @@ NSS_SMIMEUtil_CreateSMIMEEncKeyPrefs(PLArenaPool *poolp, SECItem *dest, CERTCert
PLArenaPool *tmppoolp = NULL;
if (cert == NULL)
- goto loser;
+ goto loser;
tmppoolp = PORT_NewArena(1024);
if (tmppoolp == NULL)
- goto loser;
+ 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;
+ goto loser;
dummy = SEC_ASN1EncodeItem(poolp, dest, &ekp, smime_encryptionkeypref_template);
loser:
- if (tmppoolp) PORT_FreeArena(tmppoolp, PR_FALSE);
+ if (tmppoolp)
+ PORT_FreeArena(tmppoolp, PR_FALSE);
return (dummy == NULL) ? SECFailure : SECSuccess;
}
@@ -692,27 +686,28 @@ NSS_SMIMEUtil_CreateMSSMIMEEncKeyPrefs(PLArenaPool *poolp, SECItem *dest, CERTCe
CERTIssuerAndSN *isn;
if (cert == NULL)
- goto loser;
+ goto loser;
tmppoolp = PORT_NewArena(1024);
if (tmppoolp == NULL)
- goto loser;
+ goto loser;
isn = CERT_GetCertIssuerAndSN(tmppoolp, cert);
if (isn == NULL)
- goto loser;
+ goto loser;
dummy = SEC_ASN1EncodeItem(poolp, dest, isn, SEC_ASN1_GET(CERT_IssuerAndSNTemplate));
loser:
- if (tmppoolp) PORT_FreeArena(tmppoolp, PR_FALSE);
+ if (tmppoolp)
+ PORT_FreeArena(tmppoolp, PR_FALSE);
return (dummy == NULL) ? SECFailure : SECSuccess;
}
/*
* NSS_SMIMEUtil_GetCertFromEncryptionKeyPreference -
- * find cert marked by EncryptionKeyPreference attribute
+ * 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
@@ -729,27 +724,28 @@ NSS_SMIMEUtil_GetCertFromEncryptionKeyPreference(CERTCertDBHandle *certdb, SECIt
tmppoolp = PORT_NewArena(1024);
if (tmppoolp == NULL)
- return NULL;
+ return NULL;
/* decode DERekp */
if (SEC_QuickDERDecodeItem(tmppoolp, &ekp, smime_encryptionkeypref_template,
DERekp) != SECSuccess)
- goto loser;
+ 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);
+ 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);
+ if (tmppoolp)
+ PORT_FreeArena(tmppoolp, PR_FALSE);
return cert;
}
diff --git a/nss/lib/softoken/Makefile b/nss/lib/softoken/Makefile
index b2f33e2..90a9da2 100644
--- a/nss/lib/softoken/Makefile
+++ b/nss/lib/softoken/Makefile
@@ -20,6 +20,16 @@ include $(CORE_DEPTH)/coreconf/config.mk
# (3) Include "component" configuration information. (OPTIONAL) #
#######################################################################
+ifdef NSS_NO_INIT_SUPPORT
+ DEFINES += -DNSS_NO_INIT_SUPPORT
+endif
+ifeq ($(OS_TARGET),Linux)
+ifeq ($(CPU_ARCH),ppc)
+ifdef USE_64
+ DEFINES += -DNSS_NO_INIT_SUPPORT
+endif # USE_64
+endif # ppc
+endif # Linux
#######################################################################
diff --git a/nss/lib/softoken/exports.gyp b/nss/lib/softoken/exports.gyp
new file mode 100644
index 0000000..d11d8e4
--- /dev/null
+++ b/nss/lib/softoken/exports.gyp
@@ -0,0 +1,38 @@
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+{
+ 'includes': [
+ '../../coreconf/config.gypi'
+ ],
+ 'targets': [
+ {
+ 'target_name': 'lib_softoken_exports',
+ 'type': 'none',
+ 'copies': [
+ {
+ 'files': [
+ 'lowkeyi.h',
+ 'lowkeyti.h'
+ ],
+ 'destination': '<(nss_public_dist_dir)/<(module)'
+ },
+ {
+ 'files': [
+ 'lgglue.h',
+ 'pkcs11ni.h',
+ 'sdb.h',
+ 'sftkdbt.h',
+ 'softkver.h',
+ 'softoken.h',
+ 'softoknt.h'
+ ],
+ 'destination': '<(nss_private_dist_dir)/<(module)'
+ }
+ ]
+ }
+ ],
+ 'variables': {
+ 'module': 'nss'
+ }
+}
diff --git a/nss/lib/softoken/fipsaudt.c b/nss/lib/softoken/fipsaudt.c
index b026374..e0fd641 100644
--- a/nss/lib/softoken/fipsaudt.c
+++ b/nss/lib/softoken/fipsaudt.c
@@ -23,15 +23,16 @@
* 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)
+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);
+ PR_snprintf(out, outlen,
+ " *%s=0x%08lX", argName, (PRUint32)*phObject);
} else {
- PORT_Assert(outlen != 0);
- out[0] = '\0';
+ PORT_Assert(outlen != 0);
+ out[0] = '\0';
}
}
@@ -41,279 +42,280 @@ static void sftk_PrintReturnedObjectHandle(char *out, PRUint32 outlen,
*/
#define MECHANISM_BUFSIZE 64
-static void sftk_PrintMechanism(char *out, PRUint32 outlen,
- CK_MECHANISM_PTR pMechanism)
+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);
+ /*
+ * 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);
+ 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)
+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;
+ NSSAuditSeverity severity = (rv == CKR_OK) ? NSS_AUDIT_INFO : NSS_AUDIT_ERROR;
sftk_PrintReturnedObjectHandle(shObject, sizeof shObject,
- "phObject", phObject, rv);
+ "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);
+ "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)
+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;
+ NSSAuditSeverity severity = (rv == CKR_OK) ? NSS_AUDIT_INFO : NSS_AUDIT_ERROR;
sftk_PrintReturnedObjectHandle(shNewObject, sizeof shNewObject,
- "phNewObject", phNewObject, rv);
+ "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);
+ "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)
+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;
+ 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);
+ "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)
+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;
+ 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);
+ "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)
+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;
+ 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);
+ "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)
+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;
+ 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);
+ "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)
+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;
+ 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);
+ "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)
+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;
+ 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);
+ "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)
+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;
+ 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);
+ "phPublicKey", phPublicKey, rv);
sftk_PrintReturnedObjectHandle(shPrivateKey, sizeof shPrivateKey,
- "phPrivateKey", phPrivateKey, rv);
+ "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);
+ "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)
+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;
+ 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);
+ "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)
+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;
+ 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);
+ "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)
+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;
+ 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);
+ (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';
+ 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);
+ "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)
+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;
+ 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);
+ "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/nss/lib/softoken/fipstest.c b/nss/lib/softoken/fipstest.c
index aed33bb..3563bd2 100644
--- a/nss/lib/softoken/fipstest.c
+++ b/nss/lib/softoken/fipstest.c
@@ -5,1106 +5,122 @@
* License, v. 2.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 "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 "seccomon.h"
+#include "blapi.h"
+#include "softoken.h"
+#include "lowkeyi.h"
+#include "secoid.h"
#include "secerr.h"
-#ifndef NSS_DISABLE_ECC
-#include "ec.h" /* Required for ECDSA */
+/*
+ * different platforms have different ways of calling and initial entry point
+ * when the dll/.so is loaded. Most platforms support either a posix pragma
+ * or the GCC attribute. Some platforms suppor a pre-defined name, and some
+ * platforms have a link line way of invoking this function.
+ */
+
+/* The pragma */
+#if defined(USE_INIT_PRAGMA)
+#pragma init(sftk_startup_tests)
#endif
+/* GCC Attribute */
+#if defined(__GNUC__) && !defined(NSS_NO_INIT_SUPPORT)
+#define INIT_FUNCTION __attribute__((constructor))
+#else
+#define INIT_FUNCTION
+#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);
+static void INIT_FUNCTION sftk_startup_tests(void);
- return( hmac_status );
-}
+/* Windows pre-defined entry */
+#if defined(XP_WIN) && !defined(NSS_NO_INIT_SUPPORT)
+#include <windows.h>
-static CK_RV
-sftk_fips_HMAC_PowerUpSelfTest( void )
+BOOL WINAPI DllMain(
+ HINSTANCE hinstDLL, // handle to DLL module
+ DWORD fdwReason, // reason for calling function
+ LPVOID lpReserved) // reserved
{
- 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 );
+ // Perform actions based on the reason for calling.
+ switch (fdwReason) {
+ case DLL_PROCESS_ATTACH:
+ // Initialize once for each new process.
+ // Return FALSE to fail DLL load.
+ sftk_startup_tests();
+ break;
+
+ case DLL_THREAD_ATTACH:
+ // Do thread-specific initialization.
+ break;
+
+ case DLL_THREAD_DETACH:
+ // Do thread-specific cleanup.
+ break;
+
+ case DLL_PROCESS_DETACH:
+ // Perform any necessary cleanup.
+ break;
+ }
+ return TRUE; // Successful DLL_PROCESS_ATTACH.
}
+#endif
-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 );
-}
+/* 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 */
/*
-* Single round RSA Signature Known Answer Test
+* Test the softoken RSA_HashSign and RSH_HashCheckSign.
*/
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)
+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;
+ 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;
+ 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;
+ 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;
+ 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;
+ if (SHA512_HashBuf(sha, rsa_known_msg, rsa_kmsg_length) != SECSuccess) {
+ goto loser;
}
shaLength = SHA512_LENGTH;
shaOid = SEC_OID_SHA512;
@@ -1117,18 +133,18 @@ sftk_fips_RSA_PowerUpSigSelfTest (HASH_HashType shaAlg,
/*************************************************/
/* 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 ) ) {
+ 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;
}
@@ -1137,65 +153,64 @@ sftk_fips_RSA_PowerUpSigSelfTest (HASH_HashType shaAlg,
/****************************************************/
/* 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;
+ rv = RSA_HashCheckSign(shaOid,
+ rsa_public_key,
+ rsa_computed_signature,
+ rsa_bytes_signed,
+ sha,
+ shaLength);
+
+ if (rv != SECSuccess) {
+ goto loser;
}
- return( SECSuccess );
+ return (SECSuccess);
loser:
- return( SECFailure );
-
+ return (SECFailure);
}
-static CK_RV
-sftk_fips_RSA_PowerUpSelfTest( void )
+static SECStatus
+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};
+ 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 };
+ 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), */
@@ -1205,344 +220,319 @@ sftk_fips_RSA_PowerUpSelfTest( void )
/* 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_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_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};
+ 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};
+ 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};
+ 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};
+ "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 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};
+ 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_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};
+ /* 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 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 }
+ 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. */
+/* RSA variables. */
#ifdef CREATE_TEMP_ARENAS
- PLArenaPool * rsa_public_arena;
- PLArenaPool * rsa_private_arena;
+ PLArenaPool *rsa_public_arena;
+ PLArenaPool *rsa_private_arena;
#endif
- NSSLOWKEYPublicKey * rsa_public_key;
- NSSLOWKEYPrivateKey * rsa_private_key;
- SECStatus rsa_status;
+ 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];
+ NSSLOWKEYPublicKey low_public_key = { NULL, NSSLOWKEYRSAKey };
+ NSSLOWKEYPrivateKey low_private_key = { NULL, NSSLOWKEYRSAKey };
/****************************************/
/* Compose RSA Public/Private Key Pair. */
/****************************************/
- low_public_key.u.rsa = bl_public_key;
+ low_public_key.u.rsa = bl_public_key;
low_private_key.u.rsa = bl_private_key;
- rsa_public_key = &low_public_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 );
+ rsa_public_arena = PORT_NewArena(NSS_SOFTOKEN_DEFAULT_CHUNKSIZE);
- if( rsa_public_arena == NULL ) {
- PORT_SetError( SEC_ERROR_NO_MEMORY );
- return( CKR_HOST_MEMORY );
+ if (rsa_public_arena == NULL) {
+ PORT_SetError(SEC_ERROR_NO_MEMORY);
+ return (SECFailure);
}
/* Create some space for the RSA private key. */
- rsa_private_arena = PORT_NewArena( NSS_SOFTOKEN_DEFAULT_CHUNKSIZE );
+ 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 );
+ if (rsa_private_arena == NULL) {
+ PORT_FreeArena(rsa_public_arena, PR_TRUE);
+ PORT_SetError(SEC_ERROR_NO_MEMORY);
+ return (SECFailure);
}
rsa_public_key->arena = rsa_public_arena;
@@ -1550,551 +540,115 @@ sftk_fips_RSA_PowerUpSelfTest( void )
#endif
/**************************************************/
- /* RSA Single-Round Known Answer Encryption Test. */
+ /* RSA Hash tests */
/**************************************************/
- /* 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 ) )
+ 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 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 )
+ 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_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 )
+ 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 );
+ nsslowkey_DestroyPublicKey(rsa_public_key);
+ nsslowkey_DestroyPrivateKey(rsa_private_key);
- return( CKR_OK );
+ return (SECSuccess);
rsa_loser:
- nsslowkey_DestroyPublicKey( rsa_public_key );
- nsslowkey_DestroyPrivateKey( rsa_private_key );
+ nsslowkey_DestroyPublicKey(rsa_public_key);
+ nsslowkey_DestroyPrivateKey(rsa_private_key);
- return( CKR_DEVICE_ERROR );
+ PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
+ return (SECFailure);
}
-#ifndef NSS_DISABLE_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;
- }
+static PRBool sftk_self_tests_ran = PR_FALSE;
+static PRBool sftk_self_tests_success = PR_FALSE;
- /***************************************************/
- /* 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;
+/*
+ * This function is called at dll load time, the code tha makes this
+ * happen is platform specific on defined above.
+ */
+static void
+sftk_startup_tests(void)
+{
+ SECStatus rv;
+ const char *libraryName = SOFTOKEN_LIB_NAME;
+
+ PORT_Assert(!sftk_self_tests_ran);
+ PORT_Assert(!sftk_self_tests_success);
+ sftk_self_tests_ran = PR_TRUE;
+ sftk_self_tests_success = PR_FALSE; /* just in case */
+
+ /* need to initiallize the oid library before the RSA tests */
+ rv = SECOID_Init();
+ if (rv != SECSuccess) {
+ return;
}
-
- if( ( signature.len != knownSignatureLen ) ||
- ( PORT_Memcmp( signature.data, knownSignature,
- knownSignatureLen ) != 0 ) ) {
- ecdsaStatus = SECFailure;
- goto loser;
+ /* make sure freebl is initialized, or our RSA check
+ * may fail. This is normally done at freebl load time, but it's
+ * possible we may have shut freebl down without unloading it. */
+ rv = BL_Init();
+ if (rv != SECSuccess) {
+ return;
}
-
- /******************************************************/
- /* 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);
+ rv = RNG_RNGInit();
+ if (rv != SECSuccess) {
+ return;
}
-
- 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 );
+ /* check the RSA combined functions in softoken */
+ rv = sftk_fips_RSA_PowerUpSelfTest();
+ if (rv != SECSuccess) {
+ return;
}
-
-#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 );
+ if (!BLAPI_SHVerify(libraryName,
+ (PRFuncPtr)&sftk_fips_RSA_PowerUpSelfTest)) {
+ /* something is wrong with the library, fail without enabling
+ * the token */
+ return;
}
-#endif
-
- return( CKR_OK );
-}
-
-#endif /* NSS_DISABLE_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;
+ sftk_self_tests_success = PR_TRUE;
}
+/*
+ * this is called from nsc_Common_Initizialize entry points that gates access
+ * to * all other pkcs11 functions. This prevents softoken operation if our
+ * power on selftest failed.
+ */
CK_RV
-sftk_fipsPowerUpSelfTest( void )
+sftk_FIPSEntryOK()
{
- 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;
-
-#ifndef NSS_DISABLE_ECC
- /* ECDSA Power-Up SelfTest(s). */
- rv = sftk_fips_ECDSA_PowerUpSelfTest();
-
- if( rv != CKR_OK )
- return rv;
+#ifdef NSS_NO_INIT_SUPPORT
+ /* this should only be set on platforms that can't handle one of the INIT
+ * schemes. This code allows those platforms to continue to function,
+ * though they don't meet the strict NIST requirements. If NSS_NO_INIT_SUPPORT
+ * is not set, and init support has not been properly enabled, softken
+ * will always fail because of the test below
+ */
+ if (!sftk_self_tests_ran) {
+ sftk_startup_tests();
+ }
#endif
-
- /* Software/Firmware Integrity Test. */
- rv = sftk_fipsSoftwareIntegrityTest();
-
- if( rv != CKR_OK )
- return rv;
-
- /* Passed Power-Up SelfTest(s). */
- return( CKR_OK );
+ if (!sftk_self_tests_success) {
+ return CKR_DEVICE_ERROR;
+ }
+ return CKR_OK;
}
-
diff --git a/nss/lib/softoken/fipstokn.c b/nss/lib/softoken/fipstokn.c
index 3cb6b79..12ff77c 100644
--- a/nss/lib/softoken/fipstokn.c
+++ b/nss/lib/softoken/fipstokn.c
@@ -6,11 +6,11 @@
*
* 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
+ * 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
+ * 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.
*
@@ -38,21 +38,21 @@
#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 */
+#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);
+ 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);
+ const char *message);
static pthread_once_t libaudit_once_control = PTHREAD_ONCE_INIT;
@@ -61,7 +61,7 @@ libaudit_init(void)
{
libaudit_handle = dlopen(LIBAUDIT_NAME, RTLD_LAZY);
if (!libaudit_handle) {
- return;
+ return;
}
audit_open_func = dlsym(libaudit_handle, "audit_open");
audit_close_func = dlsym(libaudit_handle, "audit_close");
@@ -70,28 +70,28 @@ libaudit_init(void)
* audit_log_user_message, if available, is preferred.
*/
audit_log_user_message_func = dlsym(libaudit_handle,
- "audit_log_user_message");
+ "audit_log_user_message");
if (!audit_log_user_message_func) {
- audit_send_user_message_func = dlsym(libaudit_handle,
- "audit_send_user_message");
+ 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;
+ (!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;
+static PRBool isLevel2 = PR_TRUE;
PRBool sftk_fatalError = PR_FALSE;
/*
@@ -115,120 +115,122 @@ PRBool sftk_fatalError = PR_FALSE;
* 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) {
+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 */
+ 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;
- }
+ 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;
+ /* illegal UTF8 string */
+ return CKR_PIN_INVALID;
}
if (nchar < FIPS_MIN_PIN) {
- return CKR_PIN_LEN_RANGE;
+ return CKR_PIN_LEN_RANGE;
}
nclass = (ndigit != 0) + (nlower != 0) + (nupper != 0) +
- (nnonalnum != 0) + (nnonascii != 0);
+ (nnonalnum != 0) + (nnonascii != 0);
if (nclass < 3) {
- return CKR_PIN_LEN_RANGE;
+ 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;
+static CK_RV
+sftk_fipsCheck(void)
+{
+ if (sftk_fatalError)
+ return CKR_DEVICE_ERROR;
+ if (isLevel2 && !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_FIPSCHECK() \
+ CK_RV rv; \
+ if ((rv = sftk_fipsCheck()) != CKR_OK) \
+ return rv;
#define SFTK_FIPSFATALCHECK() \
- if (sftk_fatalError) return CKR_DEVICE_ERROR;
-
+ 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)
+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;
- }
+ for (i = 0; i < (int)ulCount; i++) {
+ if (pTemplate[i].type == type) {
+ return pTemplate[i].pValue;
+ }
}
return NULL;
}
-
-#define __PASTE(x,y) x##y
+#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_PKCS11_FUNCTION_INFO(name) CK_RV __PASTE(NS, name)
#define CK_NEED_ARG_LIST 1
#include "pkcs11f.h"
@@ -237,7 +239,7 @@ fc_getAttribute(CK_ATTRIBUTE_PTR pTemplate,
#undef CK_NEED_ARG_LIST
#undef CK_PKCS11_FUNCTION_INFO
-#define CK_PKCS11_FUNCTION_INFO(name) CK_RV __PASTE(F,name)
+#define CK_PKCS11_FUNCTION_INFO(name) CK_RV __PASTE(F, name)
#define CK_NEED_ARG_LIST 1
#include "pkcs11f.h"
@@ -249,8 +251,9 @@ static CK_FUNCTION_LIST sftk_fipsTable = {
#undef CK_NEED_ARG_LIST
#undef CK_PKCS11_FUNCTION_INFO
-#define CK_PKCS11_FUNCTION_INFO(name) __PASTE(F,name),
-
+#define CK_PKCS11_FUNCTION_INFO(name) \
+ __PASTE(F, name) \
+ ,
#include "pkcs11f.h"
@@ -259,32 +262,31 @@ static CK_FUNCTION_LIST sftk_fipsTable = {
#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_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_OBJECT_HANDLE hObject, CK_OBJECT_CLASS *pObjClass)
{
CK_RV rv;
- CK_ATTRIBUTE class;
+ 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();
+ rv = sftk_fipsCheck();
}
return rv;
}
@@ -295,41 +297,39 @@ 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 */
+ 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
@@ -354,67 +354,68 @@ PRBool sftk_audit_enabled = PR_FALSE;
*/
void
sftk_LogAuditMessage(NSSAuditSeverity severity, NSSAuditType auditType,
- const char *msg)
+ 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;
+ 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);
+ "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;
+ 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);
+ 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 */
#else
- /* do nothing */
+/* do nothing */
#endif
}
-
/**********************************************************************
*
- * Start of PKCS 11 functions
+ * Start of PKCS 11 functions
*
**********************************************************************/
/* return the function list */
-CK_RV FC_GetFunctionList(CK_FUNCTION_LIST_PTR *pFunctionList) {
+CK_RV
+FC_GetFunctionList(CK_FUNCTION_LIST_PTR *pFunctionList)
+{
CHECK_FORK();
@@ -425,307 +426,357 @@ CK_RV FC_GetFunctionList(CK_FUNCTION_LIST_PTR *pFunctionList) {
/* sigh global so pkcs11 can read it */
PRBool nsf_init = PR_FALSE;
+void
+fc_log_init_error(CK_RV crv)
+{
+ 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);
+ }
+}
+
/* FC_Initialize initializes the PKCS #11 library. */
-CK_RV FC_Initialize(CK_VOID_PTR pReserved) {
+CK_RV
+FC_Initialize(CK_VOID_PTR pReserved)
+{
const char *envp;
CK_RV crv;
- sftk_ForkReset(pReserved, &crv);
+ if ((envp = PR_GetEnv("NSS_ENABLE_AUDIT")) != NULL) {
+ sftk_audit_enabled = (atoi(envp) == 1);
+ }
- if (nsf_init) {
- return CKR_CRYPTOKI_ALREADY_INITIALIZED;
+ /* At this point we should have already done post and integrity checks.
+ * if we haven't, it probably means the FIPS product has not been installed
+ * or the tests failed. Don't let an application try to enter FIPS mode */
+ crv = sftk_FIPSEntryOK();
+ if (crv != CKR_OK) {
+ sftk_fatalError = PR_TRUE;
+ fc_log_init_error(crv);
+ return crv;
}
- if ((envp = PR_GetEnv("NSS_ENABLE_AUDIT")) != NULL) {
- sftk_audit_enabled = (atoi(envp) == 1);
+ sftk_ForkReset(pReserved, &crv);
+
+ if (nsf_init) {
+ return CKR_CRYPTOKI_ALREADY_INITIALIZED;
}
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_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;
+ isLevel2 = PR_TRUE; /* assume level 2 unless we learn otherwise */
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;
+CK_RV
+FC_Finalize(CK_VOID_PTR pReserved)
+{
+ CK_RV crv;
- if (sftk_ForkReset(pReserved, &crv)) {
- return crv;
- }
+ if (sftk_ForkReset(pReserved, &crv)) {
+ return crv;
+ }
- if (!nsf_init) {
- return CKR_OK;
- }
+ if (!nsf_init) {
+ return CKR_OK;
+ }
- crv = nsc_CommonFinalize (pReserved, PR_TRUE);
+ crv = nsc_CommonFinalize(pReserved, PR_TRUE);
- nsf_init = (PRBool) !(crv == CKR_OK);
- return crv;
+ nsf_init = (PRBool) !(crv == CKR_OK);
+ return crv;
}
-
/* FC_GetInfo returns general information about PKCS #11. */
-CK_RV FC_GetInfo(CK_INFO_PTR pInfo) {
+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) {
+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);
+ 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) {
+CK_RV
+FC_GetSlotInfo(CK_SLOT_ID slotID, CK_SLOT_INFO_PTR pInfo)
+{
CHECK_FORK();
- return NSC_GetSlotInfo(slotID,pInfo);
+ 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
+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;
+ crv = NSC_GetTokenInfo(slotID, pInfo);
+ if (crv == CKR_OK) {
+ if ((pInfo->flags & CKF_LOGIN_REQUIRED) == 0) {
+ isLevel2 = PR_FALSE;
+ }
+ }
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();
+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);
+ if ((slotID == FIPS_SLOT_ID) || (slotID >= SFTK_MIN_FIPS_USER_SLOT_ID)) {
+ slotID = NETSCAPE_SLOT_ID;
+ }
+ /* FIPS Slots support all functions */
+ return NSC_GetMechanismList(slotID, pMechanismList, pusCount);
}
-
-/* FC_GetMechanismInfo obtains information about a particular mechanism
+/* 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) {
+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);
+ if ((slotID == FIPS_SLOT_ID) || (slotID >= SFTK_MIN_FIPS_USER_SLOT_ID)) {
+ slotID = NETSCAPE_SLOT_ID;
+ }
+ /* FIPS Slots support 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
+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);
+ 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);
+ 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
+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_fatalError)
+ return CKR_DEVICE_ERROR;
+ /* NSC_InitPIN will only work once per database. We can either initialize
+ * it to level1 (pin len == 0) or level2. If we initialize to level 2, then
+ * we need to make sure the pin meets FIPS requirements */
+ if ((ulPinLen == 0) || ((rv = sftk_newPinCheck(pPin, ulPinLen)) == CKR_OK)) {
+ rv = NSC_InitPIN(hSession, pPin, ulPinLen);
+ if (rv == CKR_OK) {
+ isLevel2 = (ulPinLen > 0) ? PR_TRUE : 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_InitPIN(hSession=0x%08lX)=0x%08lX",
- (PRUint32)hSession,(PRUint32)rv);
- sftk_LogAuditMessage(severity, NSS_AUDIT_INIT_PIN, msg);
+ 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
+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);
+ (rv = sftk_newPinCheck(pNewPin, usNewLen)) == CKR_OK) {
+ rv = NSC_SetPIN(hSession, pOldPin, usOldLen, pNewPin, usNewLen);
+ if (rv == CKR_OK) {
+ /* if we set the password in level1 we now go
+ * to level2. NOTE: we don't allow the user to
+ * go from level2 to level1 */
+ isLevel2 = PR_TRUE;
+ }
}
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);
+ 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) {
+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);
+ 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) {
+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) {
+CK_RV
+FC_CloseAllSessions(CK_SLOT_ID slotID)
+{
CHECK_FORK();
- return NSC_CloseAllSessions (slotID);
+ 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
+FC_GetSessionInfo(CK_SESSION_HANDLE hSession,
+ CK_SESSION_INFO_PTR pInfo)
+{
CK_RV rv;
SFTK_FIPSFATALCHECK();
CHECK_FORK();
- rv = NSC_GetSessionInfo(hSession,pInfo);
+ 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;
- }
+ 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
+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);
+ 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;
+ 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);
+ 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
+FC_Logout(CK_SESSION_HANDLE hSession)
+{
CK_RV rv;
CHECK_FORK();
if ((rv = sftk_fipsCheck()) == CKR_OK) {
- rv = NSC_Logout(hSession);
- isLoggedIn = PR_FALSE;
+ 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);
+ 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;
+CK_RV
+FC_CreateObject(CK_SESSION_HANDLE hSession,
+ CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulCount,
+ CK_OBJECT_HANDLE_PTR phObject)
+{
+ CK_OBJECT_CLASS *classptr;
CK_RV rv = CKR_OK;
CHECK_FORK();
- classptr = (CK_OBJECT_CLASS *)fc_getAttribute(pTemplate,ulCount,CKA_CLASS);
- if (classptr == NULL) return CKR_TEMPLATE_INCOMPLETE;
+ classptr = (CK_OBJECT_CLASS *)fc_getAttribute(pTemplate, ulCount, CKA_CLASS);
+ if (classptr == NULL)
+ return CKR_TEMPLATE_INCOMPLETE;
if (*classptr == CKO_NETSCAPE_NEWSLOT || *classptr == CKO_NETSCAPE_DELSLOT) {
if (sftk_fatalError)
@@ -738,24 +789,22 @@ CK_RV FC_GetSlotInfo(CK_SLOT_ID slotID, CK_SLOT_INFO_PTR pInfo) {
/* FIPS can't create keys from raw key material */
if (SFTK_IS_NONPUBLIC_KEY_OBJECT(*classptr)) {
- rv = CKR_ATTRIBUTE_VALUE_INVALID;
+ rv = CKR_ATTRIBUTE_VALUE_INVALID;
} else {
- rv = NSC_CreateObject(hSession,pTemplate,ulCount,phObject);
+ rv = NSC_CreateObject(hSession, pTemplate, ulCount, phObject);
}
if (sftk_audit_enabled && SFTK_IS_KEY_OBJECT(*classptr)) {
- sftk_AuditCreateObject(hSession,pTemplate,ulCount,phObject,rv);
+ 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
+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;
@@ -764,19 +813,20 @@ CK_RV FC_GetSlotInfo(CK_SLOT_ID slotID, CK_SLOT_INFO_PTR pInfo) {
SFTK_FIPSFATALCHECK();
rv = sftk_get_object_class_and_fipsCheck(hSession, hObject, &objClass);
if (rv == CKR_OK) {
- rv = NSC_CopyObject(hSession,hObject,pTemplate,ulCount,phNewObject);
+ 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);
+ 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
+FC_DestroyObject(CK_SESSION_HANDLE hSession,
+ CK_OBJECT_HANDLE hObject)
+{
CK_RV rv;
CK_OBJECT_CLASS objClass = CKO_NOT_A_KEY;
@@ -785,18 +835,19 @@ CK_RV FC_GetSlotInfo(CK_SLOT_ID slotID, CK_SLOT_INFO_PTR pInfo) {
SFTK_FIPSFATALCHECK();
rv = sftk_get_object_class_and_fipsCheck(hSession, hObject, &objClass);
if (rv == CKR_OK) {
- rv = NSC_DestroyObject(hSession,hObject);
+ rv = NSC_DestroyObject(hSession, hObject);
}
if (sftk_audit_enabled && SFTK_IS_KEY_OBJECT(objClass)) {
- sftk_AuditDestroyObject(hSession,hObject,rv);
+ 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
+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;
@@ -805,18 +856,19 @@ CK_RV FC_GetSlotInfo(CK_SLOT_ID slotID, CK_SLOT_INFO_PTR pInfo) {
SFTK_FIPSFATALCHECK();
rv = sftk_get_object_class_and_fipsCheck(hSession, hObject, &objClass);
if (rv == CKR_OK) {
- rv = NSC_GetObjectSize(hSession, hObject, pulSize);
+ rv = NSC_GetObjectSize(hSession, hObject, pulSize);
}
if (sftk_audit_enabled && SFTK_IS_KEY_OBJECT(objClass)) {
- sftk_AuditGetObjectSize(hSession, hObject, pulSize, rv);
+ 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
+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;
@@ -825,18 +877,19 @@ CK_RV FC_GetSlotInfo(CK_SLOT_ID slotID, CK_SLOT_INFO_PTR pInfo) {
SFTK_FIPSFATALCHECK();
rv = sftk_get_object_class_and_fipsCheck(hSession, hObject, &objClass);
if (rv == CKR_OK) {
- rv = NSC_GetAttributeValue(hSession,hObject,pTemplate,ulCount);
+ rv = NSC_GetAttributeValue(hSession, hObject, pTemplate, ulCount);
}
if (sftk_audit_enabled && SFTK_IS_KEY_OBJECT(objClass)) {
- sftk_AuditGetAttributeValue(hSession,hObject,pTemplate,ulCount,rv);
+ 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
+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;
@@ -845,387 +898,417 @@ CK_RV FC_GetSlotInfo(CK_SLOT_ID slotID, CK_SLOT_INFO_PTR pInfo) {
SFTK_FIPSFATALCHECK();
rv = sftk_get_object_class_and_fipsCheck(hSession, hObject, &objClass);
if (rv == CKR_OK) {
- rv = NSC_SetAttributeValue(hSession,hObject,pTemplate,ulCount);
+ rv = NSC_SetAttributeValue(hSession, hObject, pTemplate, ulCount);
}
if (sftk_audit_enabled && SFTK_IS_KEY_OBJECT(objClass)) {
- sftk_AuditSetAttributeValue(hSession,hObject,pTemplate,ulCount,rv);
+ sftk_AuditSetAttributeValue(hSession, hObject, pTemplate, ulCount, rv);
}
return rv;
}
-
-
-/* FC_FindObjectsInit initializes a search for token and session objects
+/* 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) {
+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;
- }
+ 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;
+ if ((rv = sftk_fipsCheck()) != CKR_OK)
+ return rv;
}
- return NSC_FindObjectsInit(hSession,pTemplate,usCount);
+ return NSC_FindObjectsInit(hSession, pTemplate, usCount);
}
-
-/* FC_FindObjects continues a search for token and session objects
+/* 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) {
+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);
+ 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) {
+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);
+ rv = NSC_EncryptInit(hSession, pMechanism, hKey);
if (sftk_audit_enabled) {
- sftk_AuditCryptInit("Encrypt",hSession,pMechanism,hKey,rv);
+ 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) {
+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);
+ 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) {
+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);
+ 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) {
+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);
+ 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) {
+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);
+ rv = NSC_DecryptInit(hSession, pMechanism, hKey);
if (sftk_audit_enabled) {
- sftk_AuditCryptInit("Decrypt",hSession,pMechanism,hKey,rv);
+ 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) {
+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);
+ 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) {
+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);
+ 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) {
+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);
+ 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) {
+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) {
+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);
+ 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) {
+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);
+ 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) {
+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);
+ 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,
+ * 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) {
+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);
+ rv = NSC_SignInit(hSession, pMechanism, hKey);
if (sftk_audit_enabled) {
- sftk_AuditCryptInit("Sign",hSession,pMechanism,hKey,rv);
+ 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,
+ * 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) {
+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);
+ 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,
+ * 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) {
+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);
+ return NSC_SignUpdate(hSession, pPart, usPartLen);
}
-
-/* FC_SignFinal finishes a multiple-part signature operation,
+/* 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) {
+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);
+ 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.
+ * 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) {
+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);
+ rv = NSC_SignRecoverInit(hSession, pMechanism, hKey);
if (sftk_audit_enabled) {
- sftk_AuditCryptInit("SignRecover",hSession,pMechanism,hKey,rv);
+ 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.
+ * 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) {
+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);
+ 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,
+/* 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) {
+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);
+ rv = NSC_VerifyInit(hSession, pMechanism, hKey);
if (sftk_audit_enabled) {
- sftk_AuditCryptInit("Verify",hSession,pMechanism,hKey,rv);
+ 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,
+/* 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) {
+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);
+ 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,
+/* 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) {
+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);
+ return NSC_VerifyUpdate(hSession, pPart, usPartLen);
}
-
-/* FC_VerifyFinal finishes a multiple-part verification operation,
+/* 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) {
+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);
+ 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.
+/* 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) {
+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);
+ rv = NSC_VerifyRecoverInit(hSession, pMechanism, hKey);
if (sftk_audit_enabled) {
- sftk_AuditCryptInit("VerifyRecover",hSession,pMechanism,hKey,rv);
+ 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.
+/* 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) {
+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);
+ return NSC_VerifyRecover(hSession, pSignature, usSignatureLen, pData,
+ pusDataLen);
}
/*
@@ -1233,9 +1316,11 @@ CK_RV FC_GetSlotInfo(CK_SLOT_ID slotID, CK_SLOT_INFO_PTR pInfo) {
*/
/* 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_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();
@@ -1243,84 +1328,86 @@ CK_RV FC_GetSlotInfo(CK_SLOT_ID slotID, CK_SLOT_INFO_PTR pInfo) {
/* 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);
+ boolptr = (CK_BBOOL *)fc_getAttribute(pTemplate, ulCount, CKA_SENSITIVE);
if (boolptr != NULL) {
- if (!(*boolptr)) {
- return CKR_ATTRIBUTE_VALUE_INVALID;
- }
+ if (!(*boolptr)) {
+ return CKR_ATTRIBUTE_VALUE_INVALID;
+ }
}
- rv = NSC_GenerateKey(hSession,pMechanism,pTemplate,ulCount,phKey);
+ rv = NSC_GenerateKey(hSession, pMechanism, pTemplate, ulCount, phKey);
if (sftk_audit_enabled) {
- sftk_AuditGenerateKey(hSession,pMechanism,pTemplate,ulCount,phKey,rv);
+ sftk_AuditGenerateKey(hSession, pMechanism, pTemplate, ulCount, phKey, rv);
}
return rv;
}
-
-/* FC_GenerateKeyPair generates a public-key/private-key pair,
+/* 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_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);
+ boolptr = (CK_BBOOL *)fc_getAttribute(pPrivateKeyTemplate,
+ usPrivateKeyAttributeCount, CKA_SENSITIVE);
if (boolptr != NULL) {
- if (!(*boolptr)) {
- return CKR_ATTRIBUTE_VALUE_INVALID;
- }
+ if (!(*boolptr)) {
+ return CKR_ATTRIBUTE_VALUE_INVALID;
+ }
}
- crv = NSC_GenerateKeyPair (hSession,pMechanism,pPublicKeyTemplate,
- usPublicKeyAttributeCount,pPrivateKeyTemplate,
- usPrivateKeyAttributeCount,phPublicKey,phPrivateKey);
+ crv = NSC_GenerateKeyPair(hSession, pMechanism, pPublicKeyTemplate,
+ usPublicKeyAttributeCount, pPrivateKeyTemplate,
+ usPrivateKeyAttributeCount, phPublicKey, phPrivateKey);
if (crv == CKR_GENERAL_ERROR) {
- /* pairwise consistency check failed. */
- sftk_fatalError = PR_TRUE;
+ /* pairwise consistency check failed. */
+ sftk_fatalError = PR_TRUE;
}
if (sftk_audit_enabled) {
- sftk_AuditGenerateKeyPair(hSession,pMechanism,pPublicKeyTemplate,
- usPublicKeyAttributeCount,pPrivateKeyTemplate,
- usPrivateKeyAttributeCount,phPublicKey,phPrivateKey,crv);
+ 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) {
+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);
+ rv = NSC_WrapKey(hSession, pMechanism, hWrappingKey, hKey, pWrappedKey,
+ pulWrappedKeyLen);
if (sftk_audit_enabled) {
- sftk_AuditWrapKey(hSession,pMechanism,hWrappingKey,hKey,pWrappedKey,
- pulWrappedKeyLen,rv);
+ 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_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();
@@ -1328,28 +1415,29 @@ CK_RV FC_GetSlotInfo(CK_SLOT_ID slotID, CK_SLOT_INFO_PTR pInfo) {
/* 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);
+ boolptr = (CK_BBOOL *)fc_getAttribute(pTemplate,
+ ulAttributeCount, CKA_SENSITIVE);
if (boolptr != NULL) {
- if (!(*boolptr)) {
- return CKR_ATTRIBUTE_VALUE_INVALID;
- }
+ if (!(*boolptr)) {
+ return CKR_ATTRIBUTE_VALUE_INVALID;
+ }
}
- rv = NSC_UnwrapKey(hSession,pMechanism,hUnwrappingKey,pWrappedKey,
- ulWrappedKeyLen,pTemplate,ulAttributeCount,phKey);
+ 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);
+ 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_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();
@@ -1357,18 +1445,18 @@ CK_RV FC_GetSlotInfo(CK_SLOT_ID slotID, CK_SLOT_INFO_PTR pInfo) {
/* 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);
+ boolptr = (CK_BBOOL *)fc_getAttribute(pTemplate,
+ ulAttributeCount, CKA_SENSITIVE);
if (boolptr != NULL) {
- if (!(*boolptr)) {
- return CKR_ATTRIBUTE_VALUE_INVALID;
- }
+ if (!(*boolptr)) {
+ return CKR_ATTRIBUTE_VALUE_INVALID;
+ }
}
- rv = NSC_DeriveKey(hSession,pMechanism,hBaseKey,pTemplate,
- ulAttributeCount, phKey);
+ rv = NSC_DeriveKey(hSession, pMechanism, hBaseKey, pTemplate,
+ ulAttributeCount, phKey);
if (sftk_audit_enabled) {
- sftk_AuditDeriveKey(hSession,pMechanism,hBaseKey,pTemplate,
- ulAttributeCount,phKey,rv);
+ sftk_AuditDeriveKey(hSession, pMechanism, hBaseKey, pTemplate,
+ ulAttributeCount, phKey, rv);
}
return rv;
}
@@ -1377,61 +1465,66 @@ CK_RV FC_GetSlotInfo(CK_SLOT_ID slotID, CK_SLOT_INFO_PTR pInfo) {
**************************** Radom Functions: ************************
*/
-/* FC_SeedRandom mixes additional seed material into the token's random number
+/* 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
+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);
+ crv = NSC_SeedRandom(hSession, pSeed, usSeedLen);
if (crv != CKR_OK) {
- sftk_fatalError = PR_TRUE;
+ 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
+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);
+ 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);
- }
+ 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
+/* FC_GetFunctionStatus obtains an updated status of a function running
* in parallel with an application. */
- CK_RV FC_GetFunctionStatus(CK_SESSION_HANDLE hSession) {
+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) {
+CK_RV
+FC_CancelFunction(CK_SESSION_HANDLE hSession)
+{
SFTK_FIPSCHECK();
CHECK_FORK();
@@ -1442,31 +1535,36 @@ CK_RV FC_GetSlotInfo(CK_SLOT_ID slotID, CK_SLOT_INFO_PTR pInfo) {
**************************** Version 1.1 Functions: ************************
*/
-/* FC_GetOperationState saves the state of the cryptographic
+/* 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) {
+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);
+ return NSC_GetOperationState(hSession, pOperationState, pulOperationStateLen);
}
-
-/* FC_SetOperationState restores the state of the cryptographic operation
+/* 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) {
+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);
+ 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) {
+CK_RV
+FC_FindObjectsFinal(CK_SESSION_HANDLE hSession)
+{
/* let publically readable object be found */
SFTK_FIPSFATALCHECK();
CHECK_FORK();
@@ -1474,76 +1572,83 @@ CK_RV FC_FindObjectsFinal(CK_SESSION_HANDLE hSession) {
return NSC_FindObjectsFinal(hSession);
}
-
/* Dual-function cryptographic operations */
-/* FC_DigestEncryptUpdate continues a multiple-part digesting and encryption
+/* 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) {
+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);
+ return NSC_DigestEncryptUpdate(hSession, pPart, ulPartLen, pEncryptedPart,
+ pulEncryptedPartLen);
}
-
-/* FC_DecryptDigestUpdate continues a multiple-part decryption and digesting
+/* 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) {
+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);
+ return NSC_DecryptDigestUpdate(hSession, pEncryptedPart, ulEncryptedPartLen,
+ pPart, pulPartLen);
}
-/* FC_SignEncryptUpdate continues a multiple-part signing and encryption
+/* 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) {
+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);
+ return NSC_SignEncryptUpdate(hSession, pPart, ulPartLen, pEncryptedPart,
+ pulEncryptedPartLen);
}
-/* FC_DecryptVerifyUpdate continues a multiple-part decryption and verify
+/* 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) {
+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);
+ 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) {
+CK_RV
+FC_DigestKey(CK_SESSION_HANDLE hSession, CK_OBJECT_HANDLE hKey)
+{
SFTK_FIPSCHECK();
CHECK_FORK();
- rv = NSC_DigestKey(hSession,hKey);
+ rv = NSC_DigestKey(hSession, hKey);
if (sftk_audit_enabled) {
- sftk_AuditDigestKey(hSession,hKey,rv);
+ sftk_AuditDigestKey(hSession, hKey, rv);
}
return rv;
}
-
-CK_RV FC_WaitForSlotEvent(CK_FLAGS flags, CK_SLOT_ID_PTR pSlot,
- CK_VOID_PTR pReserved)
+CK_RV
+FC_WaitForSlotEvent(CK_FLAGS flags, CK_SLOT_ID_PTR pSlot,
+ CK_VOID_PTR pReserved)
{
CHECK_FORK();
diff --git a/nss/lib/softoken/jpakesftk.c b/nss/lib/softoken/jpakesftk.c
index 4f91c72..7ed1e34 100644
--- a/nss/lib/softoken/jpakesftk.c
+++ b/nss/lib/softoken/jpakesftk.c
@@ -9,7 +9,8 @@
#include "softoken.h"
static CK_RV
-jpake_mapStatus(SECStatus rv, CK_RV invalidArgsMapping) {
+jpake_mapStatus(SECStatus rv, CK_RV invalidArgsMapping)
+{
int err;
if (rv == SECSuccess)
return CKR_OK;
@@ -17,9 +18,12 @@ jpake_mapStatus(SECStatus rv, CK_RV invalidArgsMapping) {
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;
+ 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;
}
@@ -27,15 +31,15 @@ jpake_mapStatus(SECStatus rv, CK_RV invalidArgsMapping) {
/* 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)
+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;
@@ -45,9 +49,9 @@ jpake_Sign(PLArenaPool * arena, const PQGParams * pqg, HASH_HashType hashType,
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);
+ (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;
@@ -55,40 +59,45 @@ jpake_Sign(PLArenaPool * arena, const PQGParams * pqg, HASH_HashType hashType,
} 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)
+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;
+ 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])
+#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) {
+jpake_enforceKeyType(SFTKObject *key, CK_KEY_TYPE keyType)
+{
CK_RV crv;
- SFTKAttribute * keyTypeAttr = sftk_FindAttribute(key, CKA_KEY_TYPE);
+ SFTKAttribute *keyTypeAttr = sftk_FindAttribute(key, CKA_KEY_TYPE);
if (keyTypeAttr != NULL) {
crv = *(CK_KEY_TYPE *)keyTypeAttr->attrib.pValue == keyType
- ? CKR_OK
- : CKR_TEMPLATE_INCONSISTENT;
+ ? CKR_OK
+ : CKR_TEMPLATE_INCONSISTENT;
sftk_FreeAttribute(keyTypeAttr);
} else {
crv = sftk_forceAttribute(key, CKA_KEY_TYPE, &keyType, sizeof keyType);
@@ -97,11 +106,11 @@ jpake_enforceKeyType(SFTKObject * key, CK_KEY_TYPE keyType) {
}
static CK_RV
-jpake_MultipleSecItem2Attribute(SFTKObject * key, const SFTKItemTemplate * attrs,
+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);
@@ -112,12 +121,12 @@ jpake_MultipleSecItem2Attribute(SFTKObject * key, const SFTKItemTemplate * attrs
}
CK_RV
-jpake_Round1(HASH_HashType hashType, CK_NSS_JPAKERound1Params * params,
- SFTKObject * key)
+jpake_Round1(HASH_HashType hashType, CK_NSS_JPAKERound1Params *params,
+ SFTKObject *key)
{
CK_RV crv;
PQGParams pqg;
- PLArenaPool * arena;
+ PLArenaPool *arena;
SECItem signerID;
SFTKItemTemplate templateAttrs[] = {
{ CKA_PRIME, &pqg.prime },
@@ -127,7 +136,7 @@ jpake_Round1(HASH_HashType hashType, CK_NSS_JPAKERound1Params * params,
};
SECItem x2, gx1, gx2;
const SFTKItemTemplate generatedAttrs[] = {
- { CKA_NSS_JPAKE_X2, &x2 },
+ { CKA_NSS_JPAKE_X2, &x2 },
{ CKA_NSS_JPAKE_GX1, &gx1 },
{ CKA_NSS_JPAKE_GX2, &gx2 },
};
@@ -170,7 +179,7 @@ jpake_Round1(HASH_HashType hashType, CK_NSS_JPAKERound1Params * params,
gx1.len = params->gx1.ulGXLen;
gx2.data = params->gx2.pGX;
gx2.len = params->gx2.ulGXLen;
- crv = jpake_MultipleSecItem2Attribute(key, generatedAttrs,
+ crv = jpake_MultipleSecItem2Attribute(key, generatedAttrs,
NUM_ELEM(generatedAttrs));
}
@@ -179,19 +188,19 @@ jpake_Round1(HASH_HashType hashType, CK_NSS_JPAKERound1Params * params,
}
CK_RV
-jpake_Round2(HASH_HashType hashType, CK_NSS_JPAKERound2Params * params,
- SFTKObject * sourceKey, SFTKObject * key)
+jpake_Round2(HASH_HashType hashType, CK_NSS_JPAKERound2Params *params,
+ SFTKObject *sourceKey, SFTKObject *key)
{
CK_RV crv;
- PLArenaPool * arena;
+ PLArenaPool *arena;
PQGParams pqg;
SECItem signerID, x2, gx1, gx2;
- SFTKItemTemplate sourceAttrs[] = {
+ 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_X2, &x2 },
{ CKA_NSS_JPAKE_GX1, &gx1 },
{ CKA_NSS_JPAKE_GX2, &gx2 },
};
@@ -200,7 +209,7 @@ jpake_Round2(HASH_HashType hashType, CK_NSS_JPAKERound2Params * params,
{ CKA_NSS_JPAKE_SIGNERID, &signerID },
{ CKA_PRIME, &pqg.prime },
{ CKA_SUBPRIME, &pqg.subPrime },
- { CKA_NSS_JPAKE_X2, &x2 },
+ { CKA_NSS_JPAKE_X2, &x2 },
{ CKA_NSS_JPAKE_X2S, &x2s },
{ CKA_NSS_JPAKE_GX1, &gx1 },
{ CKA_NSS_JPAKE_GX2, &gx2 },
@@ -251,7 +260,7 @@ jpake_Round2(HASH_HashType hashType, CK_NSS_JPAKERound2Params * params,
pqg.base.data = NULL;
x2s.data = NULL;
crv = jpake_mapStatus(JPAKE_Round2(arena, &pqg.prime, &pqg.subPrime,
- &gx1, &gx3, &gx4, &pqg.base,
+ &gx1, &gx3, &gx4, &pqg.base,
&x2, &s, &x2s),
CKR_MECHANISM_PARAM_INVALID);
}
@@ -281,10 +290,10 @@ jpake_Round2(HASH_HashType hashType, CK_NSS_JPAKERound2Params * params,
}
CK_RV
-jpake_Final(HASH_HashType hashType, const CK_NSS_JPAKEFinalParams * param,
- SFTKObject * sourceKey, SFTKObject * key)
+jpake_Final(HASH_HashType hashType, const CK_NSS_JPAKEFinalParams *param,
+ SFTKObject *sourceKey, SFTKObject *key)
{
- PLArenaPool * arena;
+ PLArenaPool *arena;
SECItem K;
PQGParams pqg;
CK_RV crv;
@@ -294,7 +303,7 @@ jpake_Final(HASH_HashType hashType, const CK_NSS_JPAKEFinalParams * param,
{ CKA_NSS_JPAKE_SIGNERID, &signerID },
{ CKA_PRIME, &pqg.prime },
{ CKA_SUBPRIME, &pqg.subPrime },
- { CKA_NSS_JPAKE_X2, &x2 },
+ { CKA_NSS_JPAKE_X2, &x2 },
{ CKA_NSS_JPAKE_X2S, &x2s },
{ CKA_NSS_JPAKE_GX1, &gx1 },
{ CKA_NSS_JPAKE_GX2, &gx2 },
@@ -309,7 +318,7 @@ jpake_Final(HASH_HashType hashType, const CK_NSS_JPAKEFinalParams * param,
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,
diff --git a/nss/lib/softoken/legacydb/cdbhdl.h b/nss/lib/softoken/legacydb/cdbhdl.h
index 018048b..e7243db 100644
--- a/nss/lib/softoken/legacydb/cdbhdl.h
+++ b/nss/lib/softoken/legacydb/cdbhdl.h
@@ -20,32 +20,32 @@ struct NSSLOWCERTCertDBHandleStr {
DB *permCertDB;
PZMonitor *dbMon;
PRBool dbVerify;
- PRInt32 ref; /* reference count */
+ 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)
+#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)
+#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 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 *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);
+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/nss/lib/softoken/legacydb/dbmshim.c b/nss/lib/softoken/legacydb/dbmshim.c
index f299216..40728d5 100644
--- a/nss/lib/softoken/legacydb/dbmshim.c
+++ b/nss/lib/softoken/legacydb/dbmshim.c
@@ -28,16 +28,16 @@
* . . | |
* Byte 37 . -+ -+
*/
-#define DBS_BLOCK_SIZE (16*1024) /* 16 k */
+#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 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
+#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;
@@ -52,8 +52,6 @@ struct DBSStr {
PRUint32 dbs_len;
char staticBlobArea[BLOB_BUF_LEN];
};
-
-
/*
* return true if the Datablock contains a blobtype
@@ -63,9 +61,9 @@ dbs_IsBlob(DBT *blobData)
{
unsigned char *addr = (unsigned char *)blobData->data;
if (blobData->size < BLOB_BUF_LEN) {
- return PR_FALSE;
+ return PR_FALSE;
}
- return addr && ((certDBEntryType) addr[1] == certDBEntryTypeBlob);
+ return addr && ((certDBEntryType)addr[1] == certDBEntryTypeBlob);
}
/*
@@ -88,13 +86,12 @@ 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];
+ 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
@@ -104,10 +101,11 @@ dbs_getBlobSize(DBT *blobData)
static void
dbs_replaceSlash(char *cp, int len)
{
- while (len--) {
- if (*cp == '/') *cp = '-';
- cp++;
- }
+ while (len--) {
+ if (*cp == '/')
+ *cp = '-';
+ cp++;
+ }
}
/*
@@ -115,33 +113,32 @@ dbs_replaceSlash(char *cp, int len)
* 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)
+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;
+ 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
@@ -150,26 +147,26 @@ dbs_mkBlob(DBS *dbsp,const DBT *key, const DBT *data, DBT *blobData)
* 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)
+dbs_getBlobFilePath(char *blobdir, DBT *blobData)
{
const char *name;
if (blobdir == NULL) {
- PR_SetError(SEC_ERROR_BAD_DATABASE,0);
- return NULL;
+ PR_SetError(SEC_ERROR_BAD_DATABASE, 0);
+ return NULL;
}
if (!dbs_IsBlob(blobData)) {
- PR_SetError(SEC_ERROR_BAD_DATABASE,0);
- return NULL;
+ 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;
+ PR_SetError(SEC_ERROR_BAD_DATABASE, 0);
+ return NULL;
}
- return PR_smprintf("%s" PATH_SEPARATOR "%s", blobdir, name);
+ return PR_smprintf("%s" PATH_SEPARATOR "%s", blobdir, name);
}
/*
@@ -182,7 +179,7 @@ dbs_removeBlob(DBS *dbsp, DBT *blobData)
file = dbs_getBlobFilePath(dbsp->blobdir, blobData);
if (!file) {
- return;
+ return;
}
PR_Delete(file);
PR_smprintf_free(file);
@@ -195,8 +192,8 @@ dbs_removeBlob(DBS *dbsp, DBT *blobData)
static int
dbs_DirMode(int mode)
{
- int x_bits = (mode >> 2) & 0111;
- return mode | x_bits;
+ int x_bits = (mode >> 2) & 0111;
+ return mode | x_bits;
}
/*
@@ -214,43 +211,42 @@ dbs_writeBlob(DBS *dbsp, int mode, DBT *blobData, const DBT *data)
file = dbs_getBlobFilePath(dbsp->blobdir, blobData);
if (!file) {
- goto loser;
+ 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;
- }
+ 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);
+ filed = PR_OpenFile(file, PR_CREATE_FILE | PR_TRUNCATE | PR_WRONLY, mode);
if (filed == NULL) {
- error = PR_GetError();
- goto loser;
+ error = PR_GetError();
+ goto loser;
}
- len = PR_Write(filed,data->data,data->size);
+ len = PR_Write(filed, data->data, data->size);
error = PR_GetError();
PR_Close(filed);
if (len < (int)data->size) {
- goto loser;
+ goto loser;
}
PR_smprintf_free(file);
return 0;
loser:
if (file) {
- PR_Delete(file);
- PR_smprintf_free(file);
+ PR_Delete(file);
+ PR_smprintf_free(file);
}
/* don't let close or delete reset the error */
- PR_SetError(error,0);
+ 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.
+ * 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
@@ -263,15 +259,15 @@ 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;
+ 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;
+ PORT_Free(dbsp->dbs_addr);
+ dbsp->dbs_addr = NULL;
+ dbsp->dbs_len = 0;
}
return;
}
@@ -295,23 +291,22 @@ dbs_EmulateMap(PRFileDesc *filed, int len)
addr = PORT_Alloc(len);
if (addr == NULL) {
- return NULL;
+ return NULL;
}
- dataRead = PR_Read(filed,addr,len);
+ 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;
+ 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
@@ -329,32 +324,33 @@ dbs_readBlob(DBS *dbsp, DBT *data)
file = dbs_getBlobFilePath(dbsp->blobdir, data);
if (!file) {
- goto loser;
+ goto loser;
}
- filed = PR_OpenFile(file,PR_RDONLY,0);
- PR_smprintf_free(file); file = NULL;
+ filed = PR_OpenFile(file, PR_RDONLY, 0);
+ PR_smprintf_free(file);
+ file = NULL;
if (filed == NULL) {
- goto loser;
+ 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);
+ /* 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);
+ addr = PR_MemMap(mapfile, 0, len);
}
if (addr == NULL) {
- goto loser;
+ goto loser;
}
PR_Close(filed);
- dbs_setmap(dbsp,mapfile,addr,len);
+ dbs_setmap(dbsp, mapfile, addr, len);
data->data = addr;
data->size = len;
@@ -364,12 +360,12 @@ loser:
/* preserve the error code */
error = PR_GetError();
if (mapfile) {
- PR_CloseFileMap(mapfile);
+ PR_CloseFileMap(mapfile);
}
if (filed) {
- PR_Close(filed);
+ PR_Close(filed);
}
- PR_SetError(error,0);
+ PR_SetError(error, 0);
return -1;
}
@@ -382,16 +378,15 @@ 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);
+
+ ret = (*db->get)(db, key, data, flags);
if ((ret == 0) && dbs_IsBlob(data)) {
- ret = dbs_readBlob(dbsp,data);
+ ret = dbs_readBlob(dbsp, data);
}
- return(ret);
+ return (ret);
}
static int
@@ -406,30 +401,30 @@ dbs_put(const DB *dbs, DBT *key, const DBT *data, unsigned int flags)
/* If the db is readonly, just pass the data down to rdb and let it fail */
if (!dbsp->readOnly) {
- DBT oldData;
- int ret1;
+ DBT oldData;
+ int ret1;
- /* make sure the current record is deleted if it's a blob */
- ret1 = (*db->get)(db,key,&oldData,0);
+ /* 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;
- }
+ /* 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);
+ ret = (*db->put)(db, key, data, flags);
}
- return(ret);
+ return (ret);
}
static int
@@ -440,7 +435,7 @@ dbs_sync(const DB *dbs, unsigned int flags)
dbs_freemap(dbsp);
- return (* db->sync)(db, flags);
+ return (*db->sync)(db, flags);
}
static int
@@ -453,14 +448,14 @@ dbs_del(const DB *dbs, const DBT *key, unsigned int flags)
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);
- }
+ 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);
+ return (*db->del)(db, key, flags);
}
static int
@@ -469,16 +464,16 @@ 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);
+
+ 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);
+ /* don't return a blob read as an error so traversals keep going */
+ (void)dbs_readBlob(dbsp, data);
}
- return(ret);
+ return (ret);
}
static int
@@ -489,7 +484,7 @@ dbs_close(DB *dbs)
int ret;
dbs_freemap(dbsp);
- ret = (* db->close)(db);
+ ret = (*db->close)(db);
PORT_Free(dbsp->blobdir);
PORT_Free(dbsp);
return ret;
@@ -500,13 +495,13 @@ dbs_fd(const DB *dbs)
{
DB *db = (DB *)dbs->internal;
- return (* db->fd)(db);
+ 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
+ * if no .extension exists or is equal to .dir, add a .dir
* the returned data must be freed.
*/
#define DIRSUFFIX ".dir"
@@ -522,35 +517,35 @@ dbs_mkBlobDirName(const char *dbname)
* 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 */ ;
+ 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;
- }
+ dbname_end = cp - dbname;
+ if (PORT_Strcmp(cp, DIRSUFFIX) == 0) {
+ dbname_end = dbname_len;
+ }
}
- blobDir = PORT_ZAlloc(dbname_end+sizeof(DIRSUFFIX));
+ blobDir = PORT_ZAlloc(dbname_end + sizeof(DIRSUFFIX));
if (blobDir == NULL) {
- return NULL;
+ return NULL;
}
- PORT_Memcpy(blobDir,dbname,dbname_end);
- PORT_Memcpy(&blobDir[dbname_end],DIRSUFFIX,sizeof(DIRSUFFIX));
+ 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 */
+ 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 */
};
/*
@@ -559,9 +554,9 @@ static const HASHINFO dbs_hashInfo = {
*/
DB *
dbsopen(const char *dbname, int flags, int mode, DBTYPE type,
- const void *userData)
+ const void *userData)
{
- DB *db = NULL,*dbs = NULL;
+ DB *db = NULL, *dbs = NULL;
DBS *dbsp = NULL;
/* NOTE: we are overriding userData with dbs_hashInfo. since all known
@@ -569,13 +564,13 @@ dbsopen(const char *dbname, int flags, int mode, DBTYPE type,
dbsp = (DBS *)PORT_ZAlloc(sizeof(DBS));
if (!dbsp) {
- return NULL;
+ return NULL;
}
dbs = &dbsp->db;
- dbsp->blobdir=dbs_mkBlobDirName(dbname);
+ dbsp->blobdir = dbs_mkBlobDirName(dbname);
if (dbsp->blobdir == NULL) {
- goto loser;
+ goto loser;
}
dbsp->mode = mode;
dbsp->readOnly = (PRBool)(flags == NO_RDONLY);
@@ -586,9 +581,9 @@ dbsopen(const char *dbname, int flags, int mode, DBTYPE type,
/* the real dbm call */
db = dbopen(dbname, flags, mode, type, &dbs_hashInfo);
if (db == NULL) {
- goto loser;
+ goto loser;
}
- dbs->internal = (void *) db;
+ dbs->internal = (void *)db;
dbs->type = type;
dbs->close = dbs_close;
dbs->get = dbs_get;
@@ -601,13 +596,11 @@ dbsopen(const char *dbname, int flags, int mode, DBTYPE type,
return dbs;
loser:
if (db) {
- (*db->close)(db);
+ (*db->close)(db);
}
- if (dbsp) {
- if (dbsp->blobdir) {
- PORT_Free(dbsp->blobdir);
- }
- PORT_Free(dbsp);
+ if (dbsp->blobdir) {
+ PORT_Free(dbsp->blobdir);
}
+ PORT_Free(dbsp);
return NULL;
}
diff --git a/nss/lib/softoken/legacydb/keydb.c b/nss/lib/softoken/legacydb/keydb.c
index d54f10c..178e333 100644
--- a/nss/lib/softoken/legacydb/keydb.c
+++ b/nss/lib/softoken/legacydb/keydb.c
@@ -20,105 +20,104 @@
*/
#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
+#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
+#define SALT_LENGTH 16
SEC_ASN1_MKSUB(SECOID_AlgorithmIDTemplate)
const SEC_ASN1Template nsslowkey_EncryptedPrivateKeyInfoTemplate[] = {
{ SEC_ASN1_SEQUENCE,
- 0, NULL, sizeof(NSSLOWKEYEncryptedPrivateKeyInfo) },
+ 0, NULL, sizeof(NSSLOWKEYEncryptedPrivateKeyInfo) },
{ SEC_ASN1_INLINE | SEC_ASN1_XTRN,
- offsetof(NSSLOWKEYEncryptedPrivateKeyInfo,algorithm),
- SEC_ASN1_SUB(SECOID_AlgorithmIDTemplate) },
+ offsetof(NSSLOWKEYEncryptedPrivateKeyInfo, algorithm),
+ SEC_ASN1_SUB(SECOID_AlgorithmIDTemplate) },
{ SEC_ASN1_OCTET_STRING,
- offsetof(NSSLOWKEYEncryptedPrivateKeyInfo,encryptedData) },
+ offsetof(NSSLOWKEYEncryptedPrivateKeyInfo, encryptedData) },
{ 0 }
};
const SEC_ASN1Template nsslowkey_PointerToEncryptedPrivateKeyInfoTemplate[] = {
- { SEC_ASN1_POINTER, 0, nsslowkey_EncryptedPrivateKeyInfoTemplate }
+ { 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);
+ 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);
+ 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_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 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
+ * 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)
+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 (bufitem == NULL) {
+ goto loser;
}
-
- if ( dbkey->nickname ) {
- nn = dbkey->nickname;
- nnlen = PORT_Strlen(nn) + 1;
+
+ if (dbkey->nickname) {
+ nn = dbkey->nickname;
+ nnlen = PORT_Strlen(nn) + 1;
} else {
- nn = "";
- nnlen = 1;
+ 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;
+ if (bufitem->data == NULL) {
+ goto loser;
}
buf = (unsigned char *)bufitem->data;
-
+
/* set version number */
buf[0] = version;
@@ -131,23 +130,25 @@ encode_dbkey(NSSLOWKEYDBKey *dbkey,unsigned char version)
buf[2] = nnlen;
/* copy salt */
- PORT_Memcpy(&buf[3], dbkey->salt.data, dbkey->salt.len);
+ if (dbkey->salt.len > 0) {
+ 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);
-
+ dbkey->derPK.len);
+
+ return (bufitem);
+
loser:
- if ( bufitem ) {
- free_dbt(bufitem);
+ if (bufitem) {
+ free_dbt(bufitem);
}
-
- return(NULL);
+
+ return (NULL);
}
static NSSLOWKEYDBKey *
@@ -160,69 +161,69 @@ decode_dbkey(DBT *bufitem, int expectedVersion)
int keyoff;
int nnlen;
int saltoff;
-
+
buf = (unsigned char *)bufitem->data;
version = buf[0];
-
- if ( version != expectedVersion ) {
- goto loser;
+
+ if (version != expectedVersion) {
+ goto loser;
}
-
+
arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
- if ( arena == NULL ) {
- goto loser;
+ if (arena == NULL) {
+ goto loser;
}
-
+
dbkey = (NSSLOWKEYDBKey *)PORT_ArenaZAlloc(arena, sizeof(NSSLOWKEYDBKey));
- if ( dbkey == NULL ) {
- goto loser;
+ 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;
+ 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;
+
+ 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;
+ 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);
-
+
+ return (dbkey);
+
loser:
- if ( arena ) {
- PORT_FreeArena(arena, PR_FALSE);
+ if (arena) {
+ PORT_FreeArena(arena, PR_FALSE);
}
-
- return(NULL);
+
+ return (NULL);
}
static NSSLOWKEYDBKey *
@@ -231,19 +232,19 @@ 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;
+ if (ret) {
+ PORT_SetError(SEC_ERROR_BAD_DATABASE);
+ return NULL;
}
/* set up dbkey struct */
dbkey = decode_dbkey(&entry, handle->version);
- return(dbkey);
+ return (dbkey);
}
static SECStatus
@@ -251,44 +252,44 @@ put_dbkey(NSSLOWKEYDBHandle *handle, DBT *index, NSSLOWKEYDBKey *dbkey, PRBool u
{
DBT *keydata = NULL;
int status;
-
+
keydata = encode_dbkey(dbkey, handle->version);
- if ( keydata == NULL ) {
- goto loser;
+ if (keydata == NULL) {
+ goto loser;
}
-
+
/* put it in the database */
- if ( update ) {
- status = keydb_Put(handle, index, keydata, 0);
+ if (update) {
+ status = keydb_Put(handle, index, keydata, 0);
} else {
- status = keydb_Put(handle, index, keydata, R_NOOVERWRITE);
+ status = keydb_Put(handle, index, keydata, R_NOOVERWRITE);
}
-
- if ( status ) {
- goto loser;
+
+ if (status) {
+ goto loser;
}
/* sync the database */
status = keydb_Sync(handle, 0);
- if ( status ) {
- goto loser;
+ if (status) {
+ goto loser;
}
free_dbt(keydata);
- return(SECSuccess);
+ return (SECSuccess);
loser:
- if ( keydata ) {
- free_dbt(keydata);
+ if (keydata) {
+ free_dbt(keydata);
}
-
- return(SECFailure);
+
+ return (SECFailure);
}
SECStatus
-nsslowkey_TraverseKeys(NSSLOWKEYDBHandle *handle,
- SECStatus (* keyfunc)(DBT *k, DBT *d, void *pdata),
- void *udata )
+nsslowkey_TraverseKeys(NSSLOWKEYDBHandle *handle,
+ SECStatus (*keyfunc)(DBT *k, DBT *d, void *pdata),
+ void *udata)
{
DBT data;
DBT key;
@@ -296,39 +297,39 @@ nsslowkey_TraverseKeys(NSSLOWKEYDBHandle *handle,
int ret;
if (handle == NULL) {
- return(SECFailure);
+ return (SECFailure);
}
ret = keydb_Seq(handle, &key, &data, R_FIRST);
- if ( ret ) {
- return(SECFailure);
+ 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);
+ /* 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
@@ -348,19 +349,19 @@ 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);
+ 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);
+ if (keydata == NULL) {
+ return (SECFailure);
}
/* link node into list */
@@ -371,8 +372,8 @@ sec_add_key_to_list(DBT *key, DBT *data, void *arg)
PORT_Memcpy(keydata, key->data, key->size);
node->key.size = key->size;
node->key.data = keydata;
-
- return(SECSuccess);
+
+ return (SECSuccess);
}
#endif
@@ -380,22 +381,22 @@ static SECItem *
decodeKeyDBGlobalSalt(DBT *saltData)
{
SECItem *saltitem;
-
+
saltitem = (SECItem *)PORT_ZAlloc(sizeof(SECItem));
- if ( saltitem == NULL ) {
- return(NULL);
+ if (saltitem == NULL) {
+ return (NULL);
}
-
+
saltitem->data = (unsigned char *)PORT_ZAlloc(saltData->size);
- if ( saltitem->data == NULL ) {
- PORT_Free(saltitem);
- return(NULL);
+ if (saltitem->data == NULL) {
+ PORT_Free(saltitem);
+ return (NULL);
}
-
+
saltitem->len = saltData->size;
PORT_Memcpy(saltitem->data, saltData->data, saltitem->len);
-
- return(saltitem);
+
+ return (saltitem);
}
static SECItem *
@@ -404,16 +405,16 @@ 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);
+ if (ret) {
+ return (NULL);
}
- return(decodeKeyDBGlobalSalt(&saltData));
+ return (decodeKeyDBGlobalSalt(&saltData));
}
static SECStatus
@@ -422,7 +423,7 @@ StoreKeyDBGlobalSalt(NSSLOWKEYDBHandle *handle, SECItem *salt)
DBT saltKey;
DBT saltData;
int status;
-
+
saltKey.data = SALT_STRING;
saltKey.size = sizeof(SALT_STRING) - 1;
@@ -431,11 +432,11 @@ StoreKeyDBGlobalSalt(NSSLOWKEYDBHandle *handle, SECItem *salt)
/* put global salt into the database now */
status = keydb_Put(handle, &saltKey, &saltData, 0);
- if ( status ) {
- return(SECFailure);
+ if (status) {
+ return (SECFailure);
}
- return(SECSuccess);
+ return (SECSuccess);
}
static SECStatus
@@ -445,24 +446,23 @@ makeGlobalVersion(NSSLOWKEYDBHandle *handle)
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;
-
+ versionKey.size = sizeof(VERSION_STRING) - 1;
+
/* put version string into the database now */
status = keydb_Put(handle, &versionKey, &versionData, 0);
- if ( status ) {
- return(SECFailure);
+ if (status) {
+ return (SECFailure);
}
handle->version = version;
- return(SECSuccess);
+ return (SECSuccess);
}
-
static SECStatus
makeGlobalSalt(NSSLOWKEYDBHandle *handle)
{
@@ -470,7 +470,7 @@ makeGlobalSalt(NSSLOWKEYDBHandle *handle)
DBT saltData;
unsigned char saltbuf[16];
int status;
-
+
saltKey.data = SALT_STRING;
saltKey.size = sizeof(SALT_STRING) - 1;
@@ -480,16 +480,16 @@ makeGlobalSalt(NSSLOWKEYDBHandle *handle)
/* put global salt into the database now */
status = keydb_Put(handle, &saltKey, &saltData, 0);
- if ( status ) {
- return(SECFailure);
+ if (status) {
+ return (SECFailure);
}
- return(SECSuccess);
+ return (SECSuccess);
}
static SECStatus
encodePWCheckEntry(PLArenaPool *arena, SECItem *entry, SECOidTag alg,
- SECItem *encCheck);
+ SECItem *encCheck);
static unsigned char
nsslowkey_version(NSSLOWKEYDBHandle *handle)
@@ -498,24 +498,24 @@ nsslowkey_version(NSSLOWKEYDBHandle *handle)
DBT versionData;
int ret;
versionKey.data = VERSION_STRING;
- versionKey.size = sizeof(VERSION_STRING)-1;
+ versionKey.size = sizeof(VERSION_STRING) - 1;
if (handle->db == NULL) {
- return 255;
+ return 255;
}
/* lookup version string in database */
- ret = keydb_Get( handle, &versionKey, &versionData, 0 );
+ ret = keydb_Get(handle, &versionKey, &versionData, 0);
/* error accessing the database */
- if ( ret < 0 ) {
- return 255;
+ if (ret < 0) {
+ return 255;
}
- if ( ret >= 1 ) {
- return 0;
+ if (ret >= 1) {
+ return 0;
}
- return *( (unsigned char *)versionData.data);
+ return *((unsigned char *)versionData.data);
}
static PRBool
@@ -527,49 +527,48 @@ seckey_HasAServerKey(NSSLOWKEYDBHandle *handle)
PRBool found = PR_FALSE;
ret = keydb_Seq(handle, &key, &data, R_FIRST);
- if ( ret ) {
- return PR_FALSE;
+ 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 );
+ /* 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);
+static NSSLOWKEYDBHandle *nsslowkey_NewHandle(DB *dbHandle);
/*
* currently updates key database from v2 to v3
@@ -591,15 +590,15 @@ nsslowkey_UpdateKeyDBPass1(NSSLOWKEYDBHandle *handle)
int ret;
SECItem checkitem;
- if ( handle->updatedb == NULL ) {
- return SECSuccess;
+ if (handle->updatedb == NULL) {
+ return SECSuccess;
}
- /* create a full DB Handle for our update so we
+ /* 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;
+ if (update == NULL) {
+ return SECSuccess;
}
/* update has now inherited the database handle */
@@ -610,22 +609,22 @@ nsslowkey_UpdateKeyDBPass1(NSSLOWKEYDBHandle *handle)
*/
version = nsslowkey_version(update);
if (version != 2) {
- goto done;
+ 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;
+ 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;
+ if (oldSalt == NULL) {
+ /* bad salt in old db, so it is corrupted */
+ goto done;
}
/*
@@ -633,117 +632,116 @@ nsslowkey_UpdateKeyDBPass1(NSSLOWKEYDBHandle *handle)
*/
checkKey.data = KEYDB_PW_CHECK_STRING;
checkKey.size = KEYDB_PW_CHECK_LEN;
-
- ret = keydb_Get(update, &checkKey, &checkData, 0 );
+
+ 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;
- }
+ /*
+ * 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;
- }
-
-
+ /* 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;
+ 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 );
+ /* 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;
@@ -752,21 +750,21 @@ done:
ret = keydb_Sync(handle, 0);
nsslowkey_CloseKeyDB(update);
-
- if ( oldSalt ) {
- SECITEM_FreeItem(oldSalt, PR_TRUE);
+
+ if (oldSalt) {
+ SECITEM_FreeItem(oldSalt, PR_TRUE);
}
-
- if ( dbkey ) {
- sec_destroy_dbkey(dbkey);
+
+ if (dbkey) {
+ sec_destroy_dbkey(dbkey);
}
- return(SECSuccess);
+ return (SECSuccess);
}
static SECStatus
-openNewDB(const char *appName, const char *prefix, const char *dbname,
- NSSLOWKEYDBHandle *handle, NSSLOWKEYDBNameFunc namecb, void *cbarg)
+openNewDB(const char *appName, const char *prefix, const char *dbname,
+ NSSLOWKEYDBHandle *handle, NSSLOWKEYDBNameFunc namecb, void *cbarg)
{
SECStatus rv = SECFailure;
int status = RDB_FAIL;
@@ -776,21 +774,21 @@ openNewDB(const char *appName, const char *prefix, const char *dbname,
int ret;
if (appName) {
- handle->db = rdbopen( appName, prefix, "key", NO_CREATE, &status);
+ handle->db = rdbopen(appName, prefix, "key", NO_CREATE, &status);
} else {
- handle->db = dbopen( dbname, NO_CREATE, 0600, DB_HASH, 0 );
+ 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;
+ 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;
+ /* someone else has already updated the database for us */
+ db_InitComplete(handle->db);
+ return SECSuccess;
}
/*
@@ -799,76 +797,75 @@ openNewDB(const char *appName, const char *prefix, const char *dbname,
*/
if (appName) {
NSSLOWKEYDBHandle *updateHandle;
- updatedb = dbopen( dbname, NO_RDONLY, 0600, DB_HASH, 0 );
- if (!updatedb) {
- goto noupdate;
- }
+ updatedb = dbopen(dbname, NO_RDONLY, 0600, DB_HASH, 0);
+ if (!updatedb) {
+ goto noupdate;
+ }
- /* nsslowkey_version needs a full handle because it calls
+ /* 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;
+ 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;
+ 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;
- }
- }
-
+ 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;
- }
+ if (!updated) {
+ rv = makeGlobalSalt(handle);
+ if (rv != SECSuccess) {
+ goto loser;
+ }
}
-
+
/* sync the database */
ret = keydb_Sync(handle, 0);
- if ( ret ) {
- rv = SECFailure;
- goto loser;
+ if (ret) {
+ rv = SECFailure;
+ goto loser;
}
rv = SECSuccess;
@@ -877,16 +874,16 @@ loser:
return rv;
}
-
static DB *
-openOldDB(const char *appName, const char *prefix, const char *dbname,
- PRBool openflags) {
+openOldDB(const char *appName, const char *prefix, const char *dbname,
+ PRBool openflags)
+{
DB *db = NULL;
if (appName) {
- db = rdbopen( appName, prefix, "key", openflags, NULL);
+ db = rdbopen(appName, prefix, "key", openflags, NULL);
} else {
- db = dbopen( dbname, openflags, 0600, DB_HASH, 0 );
+ db = dbopen(dbname, openflags, 0600, DB_HASH, 0);
}
return db;
@@ -899,11 +896,11 @@ 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;
- }
+ if (version != NSSLOWKEY_DB_FILE_VERSION) {
+ if (handle->db) {
+ keydb_Close(handle);
+ handle->db = NULL;
+ }
}
return handle->db != NULL;
}
@@ -912,10 +909,10 @@ static NSSLOWKEYDBHandle *
nsslowkey_NewHandle(DB *dbHandle)
{
NSSLOWKEYDBHandle *handle;
- handle = (NSSLOWKEYDBHandle *)PORT_ZAlloc (sizeof(NSSLOWKEYDBHandle));
+ handle = (NSSLOWKEYDBHandle *)PORT_ZAlloc(sizeof(NSSLOWKEYDBHandle));
if (handle == NULL) {
- PORT_SetError (SEC_ERROR_NO_MEMORY);
- return NULL;
+ PORT_SetError(SEC_ERROR_NO_MEMORY);
+ return NULL;
}
handle->appname = NULL;
@@ -931,68 +928,63 @@ nsslowkey_NewHandle(DB *dbHandle)
NSSLOWKEYDBHandle *
nsslowkey_OpenKeyDB(PRBool readOnly, const char *appName, const char *prefix,
- NSSLOWKEYDBNameFunc namecb, void *cbarg)
+ 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;
+ 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->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;
- }
+ 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;
- }
+ 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 );
+ if (dbname)
+ PORT_Free(dbname);
return handle;
loser:
- if ( dbname )
- PORT_Free( dbname );
+ if (dbname)
+ PORT_Free(dbname);
PORT_SetError(SEC_ERROR_BAD_DATABASE);
nsslowkey_CloseKeyDB(handle);
return NULL;
@@ -1005,22 +997,24 @@ 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->db != NULL) {
+ keydb_Close(handle);
}
- 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);
+ 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);
}
}
@@ -1043,8 +1037,8 @@ nsslowkey_DeleteKey(NSSLOWKEYDBHandle *handle, const SECItem *pubkey)
int ret;
if (handle == NULL) {
- PORT_SetError(SEC_ERROR_BAD_DATABASE);
- return(SECFailure);
+ PORT_SetError(SEC_ERROR_BAD_DATABASE);
+ return (SECFailure);
}
/* set up db key and data */
@@ -1053,44 +1047,44 @@ nsslowkey_DeleteKey(NSSLOWKEYDBHandle *handle, const SECItem *pubkey)
/* delete it from the database */
ret = keydb_Del(handle, &namekey, 0);
- if ( ret ) {
- PORT_SetError(SEC_ERROR_BAD_DATABASE);
- return(SECFailure);
+ 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);
+ if (ret) {
+ PORT_SetError(SEC_ERROR_BAD_DATABASE);
+ return (SECFailure);
}
- return(SECSuccess);
+ 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)
+nsslowkey_StoreKeyByPublicKey(NSSLOWKEYDBHandle *handle,
+ NSSLOWKEYPrivateKey *privkey,
+ SECItem *pubKeyData,
+ char *nickname,
+ SDB *sdb)
{
- return nsslowkey_StoreKeyByPublicKeyAlg(handle, privkey, pubKeyData,
- nickname, sdb, PR_FALSE);
+ return nsslowkey_StoreKeyByPublicKeyAlg(handle, privkey, pubKeyData,
+ nickname, sdb, PR_FALSE);
}
SECStatus
-nsslowkey_UpdateNickname(NSSLOWKEYDBHandle *handle,
- NSSLOWKEYPrivateKey *privkey,
- SECItem *pubKeyData,
- char *nickname,
- SDB *sdb)
+nsslowkey_UpdateNickname(NSSLOWKEYDBHandle *handle,
+ NSSLOWKEYPrivateKey *privkey,
+ SECItem *pubKeyData,
+ char *nickname,
+ SDB *sdb)
{
- return nsslowkey_StoreKeyByPublicKeyAlg(handle, privkey, pubKeyData,
- nickname, sdb, PR_TRUE);
+ return nsslowkey_StoreKeyByPublicKeyAlg(handle, privkey, pubKeyData,
+ nickname, sdb, PR_TRUE);
}
/* see if the symetric CKA_ID already Exists.
@@ -1105,10 +1099,10 @@ nsslowkey_KeyForIDExists(NSSLOWKEYDBHandle *handle, SECItem *id)
namekey.data = (char *)id->data;
namekey.size = id->len;
status = keydb_Get(handle, &namekey, &dummy, 0);
- if ( status ) {
- return PR_FALSE;
+ if (status) {
+ return PR_FALSE;
}
-
+
return PR_TRUE;
}
@@ -1122,64 +1116,64 @@ nsslowkey_KeyForCertExists(NSSLOWKEYDBHandle *handle, NSSLOWCERTCertificate *cer
DBT namekey;
DBT dummy;
int status;
-
+
/* get cert's public key */
pubkey = nsslowcert_ExtractPublicKey(cert);
- if ( pubkey == NULL ) {
- return PR_FALSE;
+ 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;
+ 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;
#ifndef NSS_DISABLE_ECC
- case NSSLOWKEYECKey:
- namekey.data = pubkey->u.ec.publicValue.data;
- namekey.size = pubkey->u.ec.publicValue.len;
- break;
+ case NSSLOWKEYECKey:
+ namekey.data = pubkey->u.ec.publicValue.data;
+ namekey.size = pubkey->u.ec.publicValue.len;
+ break;
#endif /* NSS_DISABLE_ECC */
- default:
- /* XXX We don't do Fortezza or DH yet. */
- return PR_FALSE;
+ 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);
+ 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);
- }
+ 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;
+ if (status) {
+ return PR_FALSE;
}
-
+
return PR_TRUE;
}
@@ -1189,12 +1183,12 @@ typedef struct NSSLowPasswordDataParamStr {
} 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}
-};
+ {
+ { 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;
@@ -1203,12 +1197,12 @@ typedef struct LGEncryptedDataInfoStr LGEncryptedDataInfo;
const SEC_ASN1Template lg_EncryptedDataInfoTemplate[] = {
{ SEC_ASN1_SEQUENCE,
- 0, NULL, sizeof(LGEncryptedDataInfo) },
+ 0, NULL, sizeof(LGEncryptedDataInfo) },
{ SEC_ASN1_INLINE | SEC_ASN1_XTRN,
- offsetof(LGEncryptedDataInfo,algorithm),
- SEC_ASN1_SUB(SECOID_AlgorithmIDTemplate) },
+ offsetof(LGEncryptedDataInfo, algorithm),
+ SEC_ASN1_SUB(SECOID_AlgorithmIDTemplate) },
{ SEC_ASN1_OCTET_STRING,
- offsetof(LGEncryptedDataInfo,encryptedData) },
+ offsetof(LGEncryptedDataInfo, encryptedData) },
{ 0 }
};
@@ -1224,24 +1218,24 @@ nsslowkey_EncodePW(SECOidTag alg, const SECItem *salt, SECItem *data)
SECStatus rv;
param.salt = *salt;
- param.iter.type = siBuffer; /* encode as signed integer */
+ 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;
+ return NULL;
}
encParam = SEC_ASN1EncodeItem(arena, NULL, &param,
- NSSLOWPasswordParamTemplate);
+ NSSLOWPasswordParamTemplate);
if (encParam == NULL) {
- goto loser;
+ goto loser;
}
rv = SECOID_SetAlgorithmID(arena, &edi.algorithm, alg, encParam);
if (rv != SECSuccess) {
- goto loser;
+ goto loser;
}
epw = SEC_ASN1EncodeItem(NULL, NULL, &edi, lg_EncryptedDataInfoTemplate);
@@ -1260,69 +1254,68 @@ nsslowkey_DecodePW(const SECItem *derData, SECOidTag *alg, SECItem *salt)
SECStatus rv;
salt->data = NULL;
- param.iter.type = siBuffer; /* decode as signed integer */
+ param.iter.type = siBuffer; /* decode as signed integer */
arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
if (arena == NULL) {
- return NULL;
+ return NULL;
}
- rv = SEC_QuickDERDecodeItem(arena, &edi, lg_EncryptedDataInfoTemplate,
- derData);
+ rv = SEC_QuickDERDecodeItem(arena, &edi, lg_EncryptedDataInfoTemplate,
+ derData);
if (rv != SECSuccess) {
- goto loser;
+ goto loser;
}
*alg = SECOID_GetAlgorithmTag(&edi.algorithm);
rv = SEC_QuickDERDecodeItem(arena, &param, NSSLOWPasswordParamTemplate,
- &edi.algorithm.parameters);
+ &edi.algorithm.parameters);
if (rv != SECSuccess) {
- goto loser;
+ goto loser;
}
rv = SECITEM_CopyItem(NULL, salt, &param.salt);
if (rv != SECSuccess) {
- goto loser;
+ goto loser;
}
pwe = SECITEM_DupItem(&edi.encryptedData);
loser:
if (!pwe && salt->data) {
- PORT_Free(salt->data);
- salt->data = NULL;
+ 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)
+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 };
+ 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);
+ /* PORT_SetError */
+ return (SECFailure);
}
global_salt = GetKeyDBGlobalSalt(handle);
if (!global_salt) {
- global_salt = &none;
+ global_salt = &none;
}
if (global_salt->len > sizeof(entry->data)) {
- /* PORT_SetError */
- goto loser;
+ /* 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;
@@ -1332,24 +1325,24 @@ nsslowkey_GetPWCheckEntry(NSSLOWKEYDBHandle *handle,NSSLOWKEYPasswordEntry *entr
checkkey.size = KEYDB_PW_CHECK_LEN;
dbkey = get_dbkey(handle, &checkkey);
if (dbkey == NULL) {
- /* handle 'FAKE' check here */
- goto loser;
+ /* 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;
+ 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];
+ 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;
+ goto loser;
}
PORT_Memcpy(entry->value.data, item->data, item->len);
entry->value.len = item->len;
@@ -1357,13 +1350,13 @@ nsslowkey_GetPWCheckEntry(NSSLOWKEYDBHandle *handle,NSSLOWKEYPasswordEntry *entr
loser:
if (item) {
- SECITEM_FreeItem(item, PR_TRUE);
+ SECITEM_FreeItem(item, PR_TRUE);
}
if (dbkey) {
- sec_destroy_dbkey(dbkey);
+ sec_destroy_dbkey(dbkey);
}
if (global_salt != &none) {
- SECITEM_FreeItem(global_salt,PR_TRUE);
+ SECITEM_FreeItem(global_salt, PR_TRUE);
}
return rv;
}
@@ -1372,20 +1365,20 @@ loser:
* check to see if the user has a password
*/
static SECStatus
-nsslowkey_PutPWCheckEntry(NSSLOWKEYDBHandle *handle,NSSLOWKEYPasswordEntry *entry)
+nsslowkey_PutPWCheckEntry(NSSLOWKEYDBHandle *handle, NSSLOWKEYPasswordEntry *entry)
{
DBT checkkey;
NSSLOWKEYDBKey *dbkey = NULL;
- SECItem *item = NULL;
- SECItem salt;
+ SECItem *item = NULL;
+ SECItem salt;
SECOidTag algid = SEC_OID_UNKNOWN;
SECStatus rv = SECFailure;
PLArenaPool *arena;
int ret;
if (handle == NULL) {
- /* PORT_SetError */
- return(SECFailure);
+ /* PORT_SetError */
+ return (SECFailure);
}
checkkey.data = KEYDB_PW_CHECK_STRING;
@@ -1394,80 +1387,79 @@ nsslowkey_PutPWCheckEntry(NSSLOWKEYDBHandle *handle,NSSLOWKEYPasswordEntry *entr
salt.data = NULL;
arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
if (arena == NULL) {
- return SECFailure;
+ return SECFailure;
}
item = nsslowkey_DecodePW(&entry->value, &algid, &salt);
if (item == NULL) {
- goto loser;
+ goto loser;
}
dbkey = PORT_ArenaZNew(arena, NSSLOWKEYDBKey);
if (dbkey == NULL) {
- goto loser;
+ goto loser;
}
dbkey->arena = arena;
rv = SECITEM_CopyItem(arena, &dbkey->salt, &salt);
if (rv != SECSuccess) {
- goto loser;
+ goto loser;
}
rv = encodePWCheckEntry(arena, &dbkey->derPK, algid, item);
if (rv != SECSuccess) {
- goto loser;
+ goto loser;
}
rv = put_dbkey(handle, &checkkey, dbkey, PR_TRUE);
if (rv != SECSuccess) {
- goto loser;
+ goto loser;
}
if (handle->global_salt) {
- SECITEM_FreeItem(handle->global_salt, PR_TRUE);
- handle->global_salt = NULL;
+ SECITEM_FreeItem(handle->global_salt, PR_TRUE);
+ handle->global_salt = NULL;
}
rv = StoreKeyDBGlobalSalt(handle, &entry->salt);
if (rv != SECSuccess) {
- goto loser;
+ goto loser;
}
ret = keydb_Sync(handle, 0);
- if ( ret ) {
- rv = SECFailure;
- goto loser;
+ if (ret) {
+ rv = SECFailure;
+ goto loser;
}
handle->global_salt = GetKeyDBGlobalSalt(handle);
loser:
if (item) {
- SECITEM_FreeItem(item, PR_TRUE);
+ SECITEM_FreeItem(item, PR_TRUE);
}
if (arena) {
- PORT_FreeArena(arena, PR_TRUE);
+ PORT_FreeArena(arena, PR_TRUE);
}
if (salt.data) {
- PORT_Free(salt.data);
+ PORT_Free(salt.data);
}
return rv;
}
#ifdef EC_DEBUG
-#define SEC_PRINT(str1, str2, num, sitem) \
+#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")
+ 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)
+#define SEC_PRINT(a, b, c, d)
#endif /* EC_DEBUG */
-
-SECStatus
-seckey_encrypt_private_key( PLArenaPool *permarena, NSSLOWKEYPrivateKey *pk,
- SDB *sdbpw, SECItem *result)
+SECStatus
+seckey_encrypt_private_key(PLArenaPool *permarena, NSSLOWKEYPrivateKey *pk,
+ SDB *sdbpw, SECItem *result)
{
NSSLOWKEYPrivateKeyInfo *pki = NULL;
SECStatus rv = SECFailure;
@@ -1483,187 +1475,186 @@ seckey_encrypt_private_key( PLArenaPool *permarena, NSSLOWKEYPrivateKey *pk,
#endif
temparena = PORT_NewArena(SEC_ASN1_DEFAULT_ARENA_SIZE);
- if(temparena == NULL)
- goto loser;
+ if (temparena == NULL)
+ goto loser;
/* allocate structures */
- pki = (NSSLOWKEYPrivateKeyInfo *)PORT_ArenaZAlloc(temparena,
- sizeof(NSSLOWKEYPrivateKeyInfo));
+ pki = (NSSLOWKEYPrivateKeyInfo *)PORT_ArenaZAlloc(temparena,
+ sizeof(NSSLOWKEYPrivateKeyInfo));
der_item = (SECItem *)PORT_ArenaZAlloc(temparena, sizeof(SECItem));
- if((pki == NULL) || (der_item == NULL))
- goto loser;
-
+ 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;
+ 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;
+ 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;
#ifndef NSS_DISABLE_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;
- }
-
+ 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;
+ }
+
#ifdef EC_DEBUG
- fordebug = &(pki->privateKey);
- SEC_PRINT("seckey_encrypt_private_key()", "PrivateKey",
- pk->keyType, fordebug);
+ fordebug = &(pki->privateKey);
+ SEC_PRINT("seckey_encrypt_private_key()", "PrivateKey",
+ pk->keyType, fordebug);
#endif
- break;
+ break;
#endif /* NSS_DISABLE_ECC */
- default:
- /* We don't support DH or Fortezza private keys yet */
- PORT_Assert(PR_FALSE);
- break;
+ 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);
+ dummy = SEC_ASN1EncodeItem(temparena, der_item, pki,
+ lg_nsslowkey_PrivateKeyInfoTemplate);
- SEC_PRINT("seckey_encrypt_private_key()", "PrivateKeyInfo",
- pk->keyType, der_item);
+ SEC_PRINT("seckey_encrypt_private_key()", "PrivateKeyInfo",
+ pk->keyType, der_item);
- if(dummy == NULL) {
- rv = SECFailure;
- goto loser;
+ if (dummy == NULL) {
+ rv = SECFailure;
+ goto loser;
}
rv = lg_util_encrypt(temparena, sdbpw, dummy, &cipherText);
if (rv != SECSuccess) {
- goto loser;
+ goto loser;
}
- rv = SECITEM_CopyItem ( permarena, result, cipherText);
+ rv = SECITEM_CopyItem(permarena, result, cipherText);
loser:
- if(temparena != NULL)
- PORT_FreeArena(temparena, PR_TRUE);
+ if (temparena != NULL)
+ PORT_FreeArena(temparena, PR_TRUE);
return rv;
}
-static SECStatus
+static SECStatus
seckey_put_private_key(NSSLOWKEYDBHandle *keydb, DBT *index, SDB *sdbpw,
- NSSLOWKEYPrivateKey *pk, char *nickname, PRBool update)
+ 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;
-
+ if ((keydb == NULL) || (index == NULL) || (sdbpw == NULL) ||
+ (pk == NULL))
+ return SECFailure;
+
arena = PORT_NewArena(SEC_ASN1_DEFAULT_ARENA_SIZE);
- if(arena == NULL)
- return SECFailure;
+ if (arena == NULL)
+ return SECFailure;
dbkey = (NSSLOWKEYDBKey *)PORT_ArenaZAlloc(arena, sizeof(NSSLOWKEYDBKey));
- if(dbkey == NULL)
- goto loser;
+ 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;
+ if (rv != SECSuccess)
+ goto loser;
rv = put_dbkey(keydb, index, dbkey, update);
- /* let success fall through */
+/* let success fall through */
loser:
- if(arena != NULL)
- PORT_FreeArena(arena, PR_TRUE);
+ if (arena != NULL)
+ PORT_FreeArena(arena, PR_TRUE);
return rv;
}
@@ -1673,19 +1664,19 @@ loser:
* 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)
+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);
+ PORT_SetError(SEC_ERROR_BAD_DATABASE);
+ return (SECFailure);
}
/* set up db key and data */
@@ -1694,14 +1685,14 @@ nsslowkey_StoreKeyByPublicKeyAlg(NSSLOWKEYDBHandle *handle,
/* encrypt the private key */
rv = seckey_put_private_key(handle, &namekey, sdbpw, privkey, nickname,
- update);
-
- return(rv);
+ update);
+
+ return (rv);
}
static NSSLOWKEYPrivateKey *
-seckey_decrypt_private_key(SECItem*epki,
- SDB *sdbpw)
+seckey_decrypt_private_key(SECItem *epki,
+ SDB *sdbpw)
{
NSSLOWKEYPrivateKey *pk = NULL;
NSSLOWKEYPrivateKeyInfo *pki = NULL;
@@ -1712,174 +1703,174 @@ seckey_decrypt_private_key(SECItem*epki,
SECItem *fordebug = NULL;
#endif
- if((epki == NULL) || (sdbpw == NULL))
- goto loser;
+ 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;
+ if ((temparena == NULL) || (permarena == NULL))
+ goto loser;
/* allocate temporary items */
- pki = (NSSLOWKEYPrivateKeyInfo *)PORT_ArenaZAlloc(temparena,
- sizeof(NSSLOWKEYPrivateKeyInfo));
+ pki = (NSSLOWKEYPrivateKeyInfo *)PORT_ArenaZAlloc(temparena,
+ sizeof(NSSLOWKEYPrivateKeyInfo));
/* allocate permanent arena items */
pk = (NSSLOWKEYPrivateKey *)PORT_ArenaZAlloc(permarena,
- sizeof(NSSLOWKEYPrivateKey));
+ sizeof(NSSLOWKEYPrivateKey));
- if((pk == NULL) || (pki == NULL))
- goto loser;
+ if ((pk == NULL) || (pki == NULL))
+ goto loser;
pk->arena = permarena;
rv = lg_util_decrypt(sdbpw, epki, &dest);
if (rv != SECSuccess) {
- goto loser;
+ goto loser;
}
-
- if(dest != NULL)
- {
+
+ 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;
+ 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;
#ifndef NSS_DISABLE_ECC
- case SEC_OID_ANSIX962_EC_PUBLIC_KEY:
- pk->keyType = NSSLOWKEYECKey;
- lg_prepare_low_ec_priv_key_for_asn1(pk);
+ case SEC_OID_ANSIX962_EC_PUBLIC_KEY:
+ pk->keyType = NSSLOWKEYECKey;
+ lg_prepare_low_ec_priv_key_for_asn1(pk);
#ifdef EC_DEBUG
- fordebug = &pki->privateKey;
- SEC_PRINT("seckey_decrypt_private_key()", "PrivateKey",
- pk->keyType, fordebug);
+ fordebug = &pki->privateKey;
+ SEC_PRINT("seckey_decrypt_private_key()", "PrivateKey",
+ pk->keyType, fordebug);
#endif
- if (SECSuccess != SECITEM_CopyItem(permarena, &newPrivateKey,
- &pki->privateKey) ) break;
- rv = SEC_QuickDERDecodeItem(permarena, pk,
- lg_nsslowkey_ECPrivateKeyTemplate,
- &newPrivateKey);
- if (rv != SECSuccess)
- goto loser;
+ 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);
+ lg_prepare_low_ecparams_for_asn1(&pk->u.ec.ecParams);
- rv = SECITEM_CopyItem(permarena,
- &pk->u.ec.ecParams.DEREncoding,
- &pki->algorithm.parameters);
+ rv = SECITEM_CopyItem(permarena,
+ &pk->u.ec.ecParams.DEREncoding,
+ &pki->algorithm.parameters);
- if (rv != SECSuccess)
- goto loser;
+ 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);
+ /* 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 (rv != SECSuccess)
+ goto loser;
- if (pk->u.ec.publicValue.len != 0) {
- pk->u.ec.publicValue.len >>= 3;
- }
+ if (pk->u.ec.publicValue.len != 0) {
+ pk->u.ec.publicValue.len >>= 3;
+ }
- break;
+ break;
#endif /* NSS_DISABLE_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 */
+ 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 (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;
+ if (rv != SECSuccess) {
+ if (permarena != NULL)
+ PORT_FreeArena(permarena, PR_TRUE);
+ pk = NULL;
}
return pk;
@@ -1888,8 +1879,8 @@ loser:
static NSSLOWKEYPrivateKey *
seckey_decode_encrypted_private_key(NSSLOWKEYDBKey *dbkey, SDB *sdbpw)
{
- if( ( dbkey == NULL ) || ( sdbpw == NULL ) ) {
- return NULL;
+ if ((dbkey == NULL) || (sdbpw == NULL)) {
+ return NULL;
}
return seckey_decrypt_private_key(&(dbkey->derPK), sdbpw);
@@ -1897,35 +1888,35 @@ seckey_decode_encrypted_private_key(NSSLOWKEYDBKey *dbkey, SDB *sdbpw)
static NSSLOWKEYPrivateKey *
seckey_get_private_key(NSSLOWKEYDBHandle *keydb, DBT *index, char **nickname,
- SDB *sdbpw)
+ SDB *sdbpw)
{
NSSLOWKEYDBKey *dbkey = NULL;
NSSLOWKEYPrivateKey *pk = NULL;
- if( ( keydb == NULL ) || ( index == NULL ) || ( sdbpw == NULL ) ) {
- return 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;
- }
- }
-
+ 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 */
+
+/* let success fall through */
loser:
- if ( dbkey != NULL ) {
- sec_destroy_dbkey(dbkey);
+ if (dbkey != NULL) {
+ sec_destroy_dbkey(dbkey);
}
return pk;
@@ -1940,14 +1931,14 @@ loser:
*/
NSSLOWKEYPrivateKey *
nsslowkey_FindKeyByPublicKey(NSSLOWKEYDBHandle *handle, SECItem *modulus,
- SDB *sdbpw)
+ SDB *sdbpw)
{
DBT namekey;
NSSLOWKEYPrivateKey *pk = NULL;
if (handle == NULL) {
- PORT_SetError(SEC_ERROR_BAD_DATABASE);
- return NULL;
+ PORT_SetError(SEC_ERROR_BAD_DATABASE);
+ return NULL;
}
/* set up db key */
@@ -1955,24 +1946,24 @@ nsslowkey_FindKeyByPublicKey(NSSLOWKEYDBHandle *handle, SECItem *modulus,
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);
+ return (pk);
}
char *
-nsslowkey_FindKeyNicknameByPublicKey(NSSLOWKEYDBHandle *handle,
- SECItem *modulus, SDB *sdbpw)
+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;
+ PORT_SetError(SEC_ERROR_BAD_DATABASE);
+ return NULL;
}
/* set up db key */
@@ -1981,51 +1972,50 @@ nsslowkey_FindKeyNicknameByPublicKey(NSSLOWKEYDBHandle *handle,
pk = seckey_get_private_key(handle, &namekey, &nickname, sdbpw);
if (pk) {
- lg_nsslowkey_DestroyPrivateKey(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);
+ return (nickname);
}
/* ===== ENCODING ROUTINES ===== */
static SECStatus
encodePWCheckEntry(PLArenaPool *arena, SECItem *entry, SECOidTag alg,
- SECItem *encCheck)
+ SECItem *encCheck)
{
SECOidData *oidData;
-
+
oidData = SECOID_FindOIDByTag(alg);
- if ( oidData == NULL ) {
- return SECFailure;
+ if (oidData == NULL) {
+ return SECFailure;
}
entry->len = 1 + oidData->oid.len + encCheck->len;
- if ( arena ) {
- entry->data = (unsigned char *)PORT_ArenaAlloc(arena, entry->len);
+ if (arena) {
+ entry->data = (unsigned char *)PORT_ArenaAlloc(arena, entry->len);
} else {
- entry->data = (unsigned char *)PORT_Alloc(entry->len);
+ entry->data = (unsigned char *)PORT_Alloc(entry->len);
}
-
- if ( entry->data == NULL ) {
- return SECFailure;
+
+ if (entry->data == NULL) {
+ return SECFailure;
}
-
+
/* 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);
+ PORT_Memcpy(&entry->data[1 + oidData->oid.len], encCheck->data,
+ encCheck->len);
return SECSuccess;
}
-
-#define MAX_DB_SIZE 0xffff
+#define MAX_DB_SIZE 0xffff
/*
* Clear out all the keys in the existing database
*/
@@ -2035,47 +2025,47 @@ nsslowkey_ResetKeyDB(NSSLOWKEYDBHandle *handle)
SECStatus rv;
int errors = 0;
- if ( handle->db == NULL ) {
- return(SECSuccess);
+ if (handle->db == NULL) {
+ return (SECSuccess);
}
if (handle->readOnly) {
- /* set an error code */
- return SECFailure;
- }
+ /* set an error code */
+ return SECFailure;
+ }
if (handle->appname == NULL && handle->dbname == NULL) {
- return SECFailure;
+ return SECFailure;
}
keydb_Close(handle);
if (handle->appname) {
- handle->db=
- rdbopen(handle->appname, handle->dbname, "key", NO_CREATE, NULL);
+ handle->db =
+ rdbopen(handle->appname, handle->dbname, "key", NO_CREATE, NULL);
} else {
- handle->db = dbopen( handle->dbname, NO_CREATE, 0600, DB_HASH, 0 );
+ handle->db = dbopen(handle->dbname, NO_CREATE, 0600, DB_HASH, 0);
}
if (handle->db == NULL) {
- /* set an error code */
- return SECFailure;
+ /* set an error code */
+ return SECFailure;
}
-
+
rv = makeGlobalVersion(handle);
- if ( rv != SECSuccess ) {
- errors++;
- goto done;
+ if (rv != SECSuccess) {
+ errors++;
+ goto done;
}
if (handle->global_salt) {
- rv = StoreKeyDBGlobalSalt(handle, handle->global_salt);
+ rv = StoreKeyDBGlobalSalt(handle, handle->global_salt);
} else {
- rv = makeGlobalSalt(handle);
- if ( rv == SECSuccess ) {
- handle->global_salt = GetKeyDBGlobalSalt(handle);
- }
+ rv = makeGlobalSalt(handle);
+ if (rv == SECSuccess) {
+ handle->global_salt = GetKeyDBGlobalSalt(handle);
+ }
}
- if ( rv != SECSuccess ) {
- errors++;
+ if (rv != SECSuccess) {
+ errors++;
}
done:
@@ -2092,15 +2082,15 @@ keydb_Get(NSSLOWKEYDBHandle *kdb, DBT *key, DBT *data, unsigned int flags)
int ret;
PRLock *kdbLock = kdb->lock;
DB *db = kdb->db;
-
+
PORT_Assert(kdbLock != NULL);
PZ_Lock(kdbLock);
- ret = (* db->get)(db, key, data, flags);
+ ret = (*db->get)(db, key, data, flags);
(void)PZ_Unlock(kdbLock);
- return(ret);
+ return (ret);
}
static int
@@ -2113,11 +2103,11 @@ keydb_Put(NSSLOWKEYDBHandle *kdb, DBT *key, DBT *data, unsigned int flags)
PORT_Assert(kdbLock != NULL);
PZ_Lock(kdbLock);
- ret = (* db->put)(db, key, data, flags);
-
+ ret = (*db->put)(db, key, data, flags);
+
(void)PZ_Unlock(kdbLock);
- return(ret);
+ return (ret);
}
static int
@@ -2130,11 +2120,11 @@ keydb_Sync(NSSLOWKEYDBHandle *kdb, unsigned int flags)
PORT_Assert(kdbLock != NULL);
PZ_Lock(kdbLock);
- ret = (* db->sync)(db, flags);
-
+ ret = (*db->sync)(db, flags);
+
(void)PZ_Unlock(kdbLock);
- return(ret);
+ return (ret);
}
static int
@@ -2147,11 +2137,11 @@ keydb_Del(NSSLOWKEYDBHandle *kdb, DBT *key, unsigned int flags)
PORT_Assert(kdbLock != NULL);
PZ_Lock(kdbLock);
- ret = (* db->del)(db, key, flags);
-
+ ret = (*db->del)(db, key, flags);
+
(void)PZ_Unlock(kdbLock);
- return(ret);
+ return (ret);
}
static int
@@ -2160,15 +2150,15 @@ keydb_Seq(NSSLOWKEYDBHandle *kdb, DBT *key, DBT *data, unsigned int flags)
int ret;
PRLock *kdbLock = kdb->lock;
DB *db = kdb->db;
-
+
PORT_Assert(kdbLock != NULL);
PZ_Lock(kdbLock);
-
- ret = (* db->seq)(db, key, data, flags);
+
+ ret = (*db->seq)(db, key, data, flags);
(void)PZ_Unlock(kdbLock);
- return(ret);
+ return (ret);
}
static void
@@ -2180,15 +2170,15 @@ keydb_Close(NSSLOWKEYDBHandle *kdb)
PORT_Assert(kdbLock != NULL);
SKIP_AFTER_FORK(PZ_Lock(kdbLock));
- (* db->close)(db);
-
+ (*db->close)(db);
+
SKIP_AFTER_FORK(PZ_Unlock(kdbLock));
return;
}
/*
- * SDB Entry Points for the Key DB
+ * SDB Entry Points for the Key DB
*/
CK_RV
@@ -2202,9 +2192,9 @@ lg_GetMetaData(SDB *sdb, const char *id, SECItem *item1, SECItem *item2)
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 */
+ 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) {
@@ -2218,8 +2208,8 @@ 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)
+lg_PutMetaData(SDB *sdb, const char *id,
+ const SECItem *item1, const SECItem *item2)
{
NSSLOWKEYDBHandle *keydb;
NSSLOWKEYPasswordEntry entry;
@@ -2229,9 +2219,9 @@ lg_PutMetaData(SDB *sdb, const char *id,
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 */
+ if (PORT_Strcmp(id, "password") != 0) {
+ /* shouldn't happen */
+ return CKR_GENERAL_ERROR; /* no extra data stored */
}
entry.salt = *item1;
entry.value = *item2;
@@ -2258,4 +2248,3 @@ lg_Reset(SDB *sdb)
}
return CKR_OK;
}
-
diff --git a/nss/lib/softoken/legacydb/keydbi.h b/nss/lib/softoken/legacydb/keydbi.h
index 924bd71..783c98e 100644
--- a/nss/lib/softoken/legacydb/keydbi.h
+++ b/nss/lib/softoken/legacydb/keydbi.h
@@ -17,36 +17,35 @@
*/
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 */
+ 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 */
+ 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
+** "pdata" is the user's data
*/
-typedef SECStatus (* NSSLOWKEYTraverseKeysFunc)(DBT *key, DBT *data, void *pdata);
-
+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
+** 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);
+extern SECStatus nsslowkey_TraverseKeys(NSSLOWKEYDBHandle *handle,
+ NSSLOWKEYTraverseKeysFunc f,
+ void *udata);
SEC_END_PROTOS
diff --git a/nss/lib/softoken/legacydb/legacydb.gyp b/nss/lib/softoken/legacydb/legacydb.gyp
new file mode 100644
index 0000000..6431fb5
--- /dev/null
+++ b/nss/lib/softoken/legacydb/legacydb.gyp
@@ -0,0 +1,66 @@
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+{
+ 'includes': [
+ '../../../coreconf/config.gypi'
+ ],
+ 'targets': [
+ {
+ 'target_name': 'nssdbm',
+ 'type': 'static_library',
+ 'sources': [
+ 'dbmshim.c',
+ 'keydb.c',
+ 'lgattr.c',
+ 'lgcreate.c',
+ 'lgdestroy.c',
+ 'lgfind.c',
+ 'lgfips.c',
+ 'lginit.c',
+ 'lgutil.c',
+ 'lowcert.c',
+ 'lowkey.c',
+ 'pcertdb.c',
+ 'pk11db.c'
+ ],
+ 'dependencies': [
+ '<(DEPTH)/exports.gyp:dbm_exports',
+ '<(DEPTH)/exports.gyp:nss_exports',
+ '<(DEPTH)/lib/freebl/freebl.gyp:freebl',
+ '<(DEPTH)/lib/dbm/src/src.gyp:dbm'
+ ]
+ },
+ {
+ 'target_name': 'nssdbm3',
+ 'type': 'shared_library',
+ 'dependencies': [
+ 'nssdbm'
+ ],
+ 'conditions': [
+ [ 'moz_fold_libs==0', {
+ 'dependencies': [
+ '<(DEPTH)/lib/util/util.gyp:nssutil3',
+ ],
+ }, {
+ 'libraries': [
+ '<(moz_folded_library_name)',
+ ],
+ }],
+ ],
+ 'variables': {
+ 'mapfile': 'nssdbm.def'
+ }
+ }
+ ],
+ 'target_defaults': {
+ 'defines': [
+ 'SHLIB_SUFFIX=\"<(dll_suffix)\"',
+ 'SHLIB_PREFIX=\"<(dll_prefix)\"',
+ 'LG_LIB_NAME=\"libnssdbm3.so\"'
+ ]
+ },
+ 'variables': {
+ 'module': 'nss'
+ }
+}
diff --git a/nss/lib/softoken/legacydb/lgattr.c b/nss/lib/softoken/legacydb/lgattr.c
index 429ef87..5c2cbdb 100644
--- a/nss/lib/softoken/legacydb/lgattr.c
+++ b/nss/lib/softoken/legacydb/lgattr.c
@@ -18,22 +18,22 @@
* Cache the object we are working on during Set's and Get's
*/
typedef struct LGObjectCacheStr {
- CK_OBJECT_CLASS objclass;
+ CK_OBJECT_CLASS objclass;
CK_OBJECT_HANDLE handle;
- SDB *sdb;
- void *objectInfo;
- LGFreeFunc infoFree;
- SECItem dbKey;
+ 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 };
+ CKO_CERTIFICATE
+};
#define handleToClass(handle) \
- lg_classArray[((handle & LG_TOKEN_TYPE_MASK))>>LG_TOKEN_TYPE_SHIFT]
-
+ lg_classArray[((handle & LG_TOKEN_TYPE_MASK)) >> LG_TOKEN_TYPE_SHIFT]
static void lg_DestroyObjectCache(LGObjectCache *obj);
@@ -45,7 +45,7 @@ lg_NewObjectCache(SDB *sdb, const SECItem *dbKey, CK_OBJECT_HANDLE handle)
obj = PORT_New(LGObjectCache);
if (obj == NULL) {
- return NULL;
+ return NULL;
}
obj->objclass = handleToClass(handle);
@@ -57,25 +57,22 @@ lg_NewObjectCache(SDB *sdb, const SECItem *dbKey, CK_OBJECT_HANDLE handle)
obj->dbKey.len = 0;
lg_DBLock(sdb);
if (dbKey == NULL) {
- dbKey = lg_lookupTokenKeyByHandle(sdb,handle);
+ dbKey = lg_lookupTokenKeyByHandle(sdb, handle);
}
if (dbKey == NULL) {
- lg_DBUnlock(sdb);
- goto loser;
+ lg_DBUnlock(sdb);
+ goto loser;
}
- rv = SECITEM_CopyItem(NULL,&obj->dbKey,dbKey);
+ rv = SECITEM_CopyItem(NULL, &obj->dbKey, dbKey);
lg_DBUnlock(sdb);
if (rv != SECSuccess) {
- goto loser;
+ goto loser;
}
return obj;
loser:
- if (obj) {
- (void) lg_DestroyObjectCache(obj);
- }
+ (void)lg_DestroyObjectCache(obj);
return NULL;
-
}
/*
@@ -86,13 +83,13 @@ static void
lg_DestroyObjectCache(LGObjectCache *obj)
{
if (obj->dbKey.data) {
- PORT_Free(obj->dbKey.data);
- obj->dbKey.data = NULL;
- }
+ PORT_Free(obj->dbKey.data);
+ obj->dbKey.data = NULL;
+ }
if (obj->objectInfo) {
- (*obj->infoFree)(obj->objectInfo);
- obj->objectInfo = NULL;
- obj->infoFree = NULL;
+ (*obj->infoFree)(obj->objectInfo);
+ obj->objectInfo = NULL;
+ obj->infoFree = NULL;
}
PORT_Free(obj);
}
@@ -107,55 +104,57 @@ lg_ULongAttribute(CK_ATTRIBUTE *attr, CK_ATTRIBUTE_TYPE type, CK_ULONG value)
int i;
if (attr->pValue == NULL) {
- attr->ulValueLen = 4;
- return CKR_OK;
+ attr->ulValueLen = 4;
+ return CKR_OK;
}
if (attr->ulValueLen < 4) {
- attr->ulValueLen = (CK_ULONG) -1;
- return CKR_BUFFER_TOO_SMALL;
+ 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;
+ 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)
+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;
+ attr->ulValueLen = len;
+ return CKR_OK;
}
if (attr->ulValueLen < len) {
- attr->ulValueLen = (CK_ULONG) -1;
- return CKR_BUFFER_TOO_SMALL;
+ attr->ulValueLen = (CK_ULONG)-1;
+ return CKR_BUFFER_TOO_SMALL;
+ }
+ if (value != NULL) {
+ PORT_Memcpy(attr->pValue, value, len);
}
- 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)
+lg_CopyAttributeSigned(CK_ATTRIBUTE *attribute, CK_ATTRIBUTE_TYPE type,
+ void *value, CK_ULONG len)
{
- unsigned char * dval = (unsigned char *)value;
+ unsigned char *dval = (unsigned char *)value;
if (*dval == 0) {
- dval++;
- len--;
+ dval++;
+ len--;
}
- return lg_CopyAttribute(attribute,type,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)
+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;
@@ -165,86 +164,86 @@ lg_CopyPrivAttribute(CK_ATTRIBUTE *attribute, CK_ATTRIBUTE_TYPE type,
plainText.len = len;
rv = lg_util_encrypt(NULL, sdbpw, &plainText, &cipherText);
if (rv != SECSuccess) {
- goto loser;
+ goto loser;
}
- crv = lg_CopyAttribute(attribute,type,cipherText->data,cipherText->len);
+ crv = lg_CopyAttribute(attribute, type, cipherText->data, cipherText->len);
loser:
if (cipherText) {
- SECITEM_FreeItem(cipherText,PR_TRUE);
+ 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)
+lg_CopyPrivAttrSigned(CK_ATTRIBUTE *attribute, CK_ATTRIBUTE_TYPE type,
+ void *value, CK_ULONG len, SDB *sdbpw)
{
- unsigned char * dval = (unsigned char *)value;
+ unsigned char *dval = (unsigned char *)value;
if (*dval == 0) {
- dval++;
- len--;
+ dval++;
+ len--;
}
- return lg_CopyPrivAttribute(attribute,type,dval,len,sdbpw);
+ return lg_CopyPrivAttribute(attribute, type, dval, len, sdbpw);
}
static CK_RV
lg_invalidAttribute(CK_ATTRIBUTE *attr)
{
- attr->ulValueLen = (CK_ULONG) -1;
+ attr->ulValueLen = (CK_ULONG)-1;
return CKR_ATTRIBUTE_TYPE_INVALID;
}
-
-#define LG_DEF_ATTRIBUTE(value,len) \
- { 0, value, len }
+#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);
+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;
/*
- * helper functions which get the database and call the underlying
+ * 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;
+ char *label;
keyHandle = lg_getKeyDB(sdb);
if (!keyHandle) {
- return NULL;
+ return NULL;
}
- label = nsslowkey_FindKeyNicknameByPublicKey(keyHandle, dbKey,
- sdb);
+ label = nsslowkey_FindKeyNicknameByPublicKey(keyHandle, dbKey,
+ sdb);
return label;
}
-
NSSLOWKEYPrivateKey *
lg_FindKeyByPublicKey(SDB *sdb, SECItem *dbKey)
{
NSSLOWKEYPrivateKey *privKey;
- NSSLOWKEYDBHandle *keyHandle;
+ NSSLOWKEYDBHandle *keyHandle;
keyHandle = lg_getKeyDB(sdb);
if (keyHandle == NULL) {
- return NULL;
+ return NULL;
}
privKey = nsslowkey_FindKeyByPublicKey(keyHandle, dbKey, sdb);
if (privKey == NULL) {
- return NULL;
+ return NULL;
}
return privKey;
}
@@ -256,19 +255,19 @@ lg_getSMime(LGObjectCache *obj)
NSSLOWCERTCertDBHandle *certHandle;
if (obj->objclass != CKO_NSS_SMIME) {
- return NULL;
+ return NULL;
}
if (obj->objectInfo) {
- return (certDBEntrySMime *)obj->objectInfo;
+ return (certDBEntrySMime *)obj->objectInfo;
}
certHandle = lg_getCertDB(obj->sdb);
if (!certHandle) {
- return NULL;
+ return NULL;
}
entry = nsslowcert_ReadDBSMimeEntry(certHandle, (char *)obj->dbKey.data);
obj->objectInfo = (void *)entry;
- obj->infoFree = (LGFreeFunc) nsslowcert_DestroyDBEntry;
+ obj->infoFree = (LGFreeFunc)nsslowcert_DestroyDBEntry;
return entry;
}
@@ -280,21 +279,21 @@ lg_getCrl(LGObjectCache *obj)
NSSLOWCERTCertDBHandle *certHandle;
if (obj->objclass != CKO_NSS_CRL) {
- return NULL;
+ return NULL;
}
if (obj->objectInfo) {
- return (certDBEntryRevocation *)obj->objectInfo;
+ return (certDBEntryRevocation *)obj->objectInfo;
}
- isKrl = (PRBool) (obj->handle == LG_TOKEN_KRL_HANDLE);
+ isKrl = (PRBool)(obj->handle == LG_TOKEN_KRL_HANDLE);
certHandle = lg_getCertDB(obj->sdb);
if (!certHandle) {
- return NULL;
+ return NULL;
}
crl = nsslowcert_FindCrlByKey(certHandle, &obj->dbKey, isKrl);
obj->objectInfo = (void *)crl;
- obj->infoFree = (LGFreeFunc) nsslowcert_DestroyDBEntry;
+ obj->infoFree = (LGFreeFunc)nsslowcert_DestroyDBEntry;
return crl;
}
@@ -305,15 +304,15 @@ lg_getCert(LGObjectCache *obj, NSSLOWCERTCertDBHandle *certHandle)
CK_OBJECT_CLASS objClass = obj->objclass;
if ((objClass != CKO_CERTIFICATE) && (objClass != CKO_NSS_TRUST)) {
- return NULL;
+ return NULL;
}
if (objClass == CKO_CERTIFICATE && obj->objectInfo) {
- return (NSSLOWCERTCertificate *)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 ;
+ obj->objectInfo = (void *)cert;
+ obj->infoFree = (LGFreeFunc)nsslowcert_DestroyCertificate;
}
return cert;
}
@@ -324,14 +323,14 @@ lg_getTrust(LGObjectCache *obj, NSSLOWCERTCertDBHandle *certHandle)
NSSLOWCERTTrust *trust;
if (obj->objclass != CKO_NSS_TRUST) {
- return NULL;
+ return NULL;
}
if (obj->objectInfo) {
- return (NSSLOWCERTTrust *)obj->objectInfo;
+ return (NSSLOWCERTTrust *)obj->objectInfo;
}
trust = nsslowcert_FindTrustByKey(certHandle, &obj->dbKey);
obj->objectInfo = (void *)trust;
- obj->infoFree = (LGFreeFunc) nsslowcert_DestroyTrust ;
+ obj->infoFree = (LGFreeFunc)nsslowcert_DestroyTrust;
return trust;
}
@@ -342,26 +341,26 @@ lg_GetPublicKey(LGObjectCache *obj)
NSSLOWKEYPrivateKey *privKey;
if (obj->objclass != CKO_PUBLIC_KEY) {
- return NULL;
+ return NULL;
}
if (obj->objectInfo) {
- return (NSSLOWKEYPublicKey *)obj->objectInfo;
+ return (NSSLOWKEYPublicKey *)obj->objectInfo;
}
privKey = lg_FindKeyByPublicKey(obj->sdb, &obj->dbKey);
if (privKey == NULL) {
- return NULL;
+ return NULL;
}
pubKey = lg_nsslowkey_ConvertToPublicKey(privKey);
lg_nsslowkey_DestroyPrivateKey(privKey);
- obj->objectInfo = (void *) pubKey;
- obj->infoFree = (LGFreeFunc) lg_nsslowkey_DestroyPublicKey ;
+ obj->objectInfo = (void *)pubKey;
+ obj->infoFree = (LGFreeFunc)lg_nsslowkey_DestroyPublicKey;
return pubKey;
}
/*
- * we need two versions of lg_GetPrivateKey. One version that takes the
+ * 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,
+ * 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.
@@ -371,19 +370,19 @@ lg_GetPrivateKeyWithDB(LGObjectCache *obj, NSSLOWKEYDBHandle *keyHandle)
{
NSSLOWKEYPrivateKey *privKey;
- if ((obj->objclass != CKO_PRIVATE_KEY) &&
- (obj->objclass != CKO_SECRET_KEY)) {
- return NULL;
+ if ((obj->objclass != CKO_PRIVATE_KEY) &&
+ (obj->objclass != CKO_SECRET_KEY)) {
+ return NULL;
}
if (obj->objectInfo) {
- return (NSSLOWKEYPrivateKey *)obj->objectInfo;
+ return (NSSLOWKEYPrivateKey *)obj->objectInfo;
}
privKey = nsslowkey_FindKeyByPublicKey(keyHandle, &obj->dbKey, obj->sdb);
if (privKey == NULL) {
- return NULL;
+ return NULL;
}
- obj->objectInfo = (void *) privKey;
- obj->infoFree = (LGFreeFunc) lg_nsslowkey_DestroyPrivateKey ;
+ obj->objectInfo = (void *)privKey;
+ obj->infoFree = (LGFreeFunc)lg_nsslowkey_DestroyPrivateKey;
return privKey;
}
@@ -396,7 +395,7 @@ lg_GetPrivateKey(LGObjectCache *obj)
keyHandle = lg_getKeyDB(obj->sdb);
if (!keyHandle) {
- return NULL;
+ return NULL;
}
privKey = lg_GetPrivateKeyWithDB(obj, keyHandle);
return privKey;
@@ -408,138 +407,139 @@ lg_GetPrivateKey(LGObjectCache *obj)
* should include this comment.
*/
static SECItem *
-lg_GetPubItem(NSSLOWKEYPublicKey *pubKey) {
+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;
+ 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;
#ifndef NSS_DISABLE_ECC
- case NSSLOWKEYECKey:
- pubItem = &pubKey->u.ec.publicValue;
- break;
+ case NSSLOWKEYECKey:
+ pubItem = &pubKey->u.ec.publicValue;
+ break;
#endif /* NSS_DISABLE_ECC */
- default:
- break;
+ default:
+ break;
}
return pubItem;
}
static CK_RV
lg_FindRSAPublicKeyAttribute(NSSLOWKEYPublicKey *key, CK_ATTRIBUTE_TYPE type,
- CK_ATTRIBUTE *attribute)
+ 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;
+ 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)
+ 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;
+ 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)
+ 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;
+ 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);
}
@@ -547,111 +547,110 @@ lg_FindDHPublicKeyAttribute(NSSLOWKEYPublicKey *key, CK_ATTRIBUTE_TYPE type,
#ifndef NSS_DISABLE_ECC
static CK_RV
lg_FindECPublicKeyAttribute(NSSLOWKEYPublicKey *key, CK_ATTRIBUTE_TYPE type,
- CK_ATTRIBUTE *attribute)
+ 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;
+ 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 (PR_GetEnvSecure("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_DISABLE_ECC */
-
static CK_RV
lg_FindPublicKeyAttribute(LGObjectCache *obj, CK_ATTRIBUTE_TYPE type,
- CK_ATTRIBUTE *attribute)
+ CK_ATTRIBUTE *attribute)
{
- NSSLOWKEYPublicKey *key;
+ 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;
+ 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;
+ 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);
+ case NSSLOWKEYRSAKey:
+ return lg_FindRSAPublicKeyAttribute(key, type, attribute);
+ case NSSLOWKEYDSAKey:
+ return lg_FindDSAPublicKeyAttribute(key, type, attribute);
+ case NSSLOWKEYDHKey:
+ return lg_FindDHPublicKeyAttribute(key, type, attribute);
#ifndef NSS_DISABLE_ECC
- case NSSLOWKEYECKey:
- return lg_FindECPublicKeyAttribute(key,type,attribute);
+ case NSSLOWKEYECKey:
+ return lg_FindECPublicKeyAttribute(key, type, attribute);
#endif /* NSS_DISABLE_ECC */
- default:
- break;
+ default:
+ break;
}
return lg_invalidAttribute(attribute);
@@ -659,9 +658,9 @@ lg_FindPublicKeyAttribute(LGObjectCache *obj, CK_ATTRIBUTE_TYPE type,
static CK_RV
lg_FindSecretKeyAttribute(LGObjectCache *obj, CK_ATTRIBUTE_TYPE type,
- CK_ATTRIBUTE *attribute)
+ CK_ATTRIBUTE *attribute)
{
- NSSLOWKEYPrivateKey *key;
+ NSSLOWKEYPrivateKey *key;
char *label;
unsigned char *keyString;
CK_RV crv;
@@ -671,269 +670,267 @@ lg_FindSecretKeyAttribute(LGObjectCache *obj, CK_ATTRIBUTE_TYPE type,
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);
+ 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;
+ 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);
+ 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)
+ 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;
+ 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)
+ 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;
+ 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)
+ 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;
+ 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);
}
@@ -941,38 +938,38 @@ lg_FindDHPrivateKeyAttribute(NSSLOWKEYPrivateKey *key, CK_ATTRIBUTE_TYPE type,
#ifndef NSS_DISABLE_ECC
static CK_RV
lg_FindECPrivateKeyAttribute(NSSLOWKEYPrivateKey *key, CK_ATTRIBUTE_TYPE type,
- CK_ATTRIBUTE *attribute, SDB *sdbpw)
+ 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;
+ 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);
}
@@ -980,55 +977,55 @@ lg_FindECPrivateKeyAttribute(NSSLOWKEYPrivateKey *key, CK_ATTRIBUTE_TYPE type,
static CK_RV
lg_FindPrivateKeyAttribute(LGObjectCache *obj, CK_ATTRIBUTE_TYPE type,
- CK_ATTRIBUTE *attribute)
+ CK_ATTRIBUTE *attribute)
{
- NSSLOWKEYPrivateKey *key;
+ 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;
+ 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;
+ 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);
+ 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);
#ifndef NSS_DISABLE_ECC
- case NSSLOWKEYECKey:
- return lg_FindECPrivateKeyAttribute(key,type,attribute,obj->sdb);
+ case NSSLOWKEYECKey:
+ return lg_FindECPrivateKeyAttribute(key, type, attribute, obj->sdb);
#endif /* NSS_DISABLE_ECC */
- default:
- break;
+ default:
+ break;
}
return lg_invalidAttribute(attribute);
@@ -1036,46 +1033,46 @@ lg_FindPrivateKeyAttribute(LGObjectCache *obj, CK_ATTRIBUTE_TYPE type,
static CK_RV
lg_FindSMIMEAttribute(LGObjectCache *obj, CK_ATTRIBUTE_TYPE type,
- CK_ATTRIBUTE *attribute)
+ 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);
+ 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;
+ 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;
+ 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)
+ CK_ATTRIBUTE *attribute)
{
NSSLOWCERTTrust *trust;
NSSLOWCERTCertDBHandle *certHandle;
@@ -1085,231 +1082,235 @@ lg_FindTrustAttribute(LGObjectCache *obj, CK_ATTRIBUTE_TYPE type,
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);
+ 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;
+ return CKR_OBJECT_HANDLE_INVALID;
}
trust = lg_getTrust(obj, certHandle);
if (trust == NULL) {
- return CKR_OBJECT_HANDLE_INVALID;
+ 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;
+ 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;
+ 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;
+ nsslowcert_DestroyCertificate(cert);
+ return crv;
}
return lg_invalidAttribute(attribute);
}
static CK_RV
lg_FindCrlAttribute(LGObjectCache *obj, CK_ATTRIBUTE_TYPE type,
- CK_ATTRIBUTE *attribute)
+ 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);
+ 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;
+ 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;
+ 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)
+ CK_ATTRIBUTE *attribute)
{
- NSSLOWCERTCertificate *cert;
+ NSSLOWCERTCertificate *cert;
NSSLOWCERTCertDBHandle *certHandle;
- NSSLOWKEYPublicKey *pubKey;
+ 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);
+ 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;
+ return CKR_OBJECT_HANDLE_INVALID;
}
cert = lg_getCert(obj, certHandle);
if (cert == NULL) {
- return CKR_OBJECT_HANDLE_INVALID;
+ 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;
+ 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);
}
@@ -1320,60 +1321,61 @@ 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;
+ 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;
+ 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)
+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;
unsigned int i;
if (obj == NULL) {
- return CKR_OBJECT_HANDLE_INVALID;
+ return CKR_OBJECT_HANDLE_INVALID;
}
- for (i=0; i < count; i++) {
- crv = lg_GetSingleAttribute(obj, &templ[i]);
- if (crvCollect == CKR_OK) crvCollect = crv;
+ for (i = 0; i < count; i++) {
+ crv = lg_GetSingleAttribute(obj, &templ[i]);
+ if (crvCollect == CKR_OK)
+ crvCollect = crv;
}
lg_DestroyObjectCache(obj);
@@ -1399,45 +1401,47 @@ lg_cmpAttribute(LGObjectCache *obj, const CK_ATTRIBUTE *attribute)
/* 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;
+ 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;
+ if ((crv != CKR_OK) ||
+ (attribute->pValue == NULL) ||
+ (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);
+ PORT_Free(tempBuf);
}
return match;
}
PRBool
lg_tokenMatch(SDB *sdb, const SECItem *dbKey, CK_OBJECT_HANDLE class,
- const CK_ATTRIBUTE *templ, CK_ULONG count)
+ const CK_ATTRIBUTE *templ, CK_ULONG count)
{
PRBool match = PR_TRUE;
LGObjectCache *obj = lg_NewObjectCache(sdb, dbKey, class);
unsigned int i;
if (obj == NULL) {
- return PR_FALSE;
+ return PR_FALSE;
}
- for (i=0; i < count; i++) {
- match = lg_cmpAttribute(obj, &templ[i]);
- if (!match) {
- break;
- }
+ for (i = 0; i < count; i++) {
+ match = lg_cmpAttribute(obj, &templ[i]);
+ if (!match) {
+ break;
+ }
}
/* done looking, free up our cache */
@@ -1449,10 +1453,10 @@ lg_tokenMatch(SDB *sdb, const SECItem *dbKey, CK_OBJECT_HANDLE class,
}
static CK_RV
-lg_SetCertAttribute(LGObjectCache *obj, CK_ATTRIBUTE_TYPE type,
- const void *value, unsigned int len)
+lg_SetCertAttribute(LGObjectCache *obj, CK_ATTRIBUTE_TYPE type,
+ const void *value, unsigned int len)
{
- NSSLOWCERTCertificate *cert;
+ NSSLOWCERTCertificate *cert;
NSSLOWCERTCertDBHandle *certHandle;
char *nickname = NULL;
SECStatus rv;
@@ -1461,77 +1465,77 @@ lg_SetCertAttribute(LGObjectCache *obj, CK_ATTRIBUTE_TYPE type,
/* 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;
+ return CKR_OK;
}
certHandle = lg_getCertDB(obj->sdb);
if (certHandle == NULL) {
- crv = CKR_TOKEN_WRITE_PROTECTED;
- goto done;
+ crv = CKR_TOKEN_WRITE_PROTECTED;
+ goto done;
}
- if ((type != CKA_LABEL) && (type != CKA_ID)) {
- crv = CKR_ATTRIBUTE_READ_ONLY;
- 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;
+ 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;
+ 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;
+ 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);
+ PORT_Free(nickname);
}
return crv;
}
static CK_RV
-lg_SetPrivateKeyAttribute(LGObjectCache *obj, CK_ATTRIBUTE_TYPE type,
- const void *value, unsigned int len,
- PRBool *writePrivate)
+lg_SetPrivateKeyAttribute(LGObjectCache *obj, CK_ATTRIBUTE_TYPE type,
+ const void *value, unsigned int len,
+ PRBool *writePrivate)
{
NSSLOWKEYPrivateKey *privKey;
- NSSLOWKEYDBHandle *keyHandle;
+ NSSLOWKEYDBHandle *keyHandle;
char *nickname = NULL;
SECStatus rv;
CK_RV crv;
@@ -1539,162 +1543,165 @@ lg_SetPrivateKeyAttribute(LGObjectCache *obj, CK_ATTRIBUTE_TYPE type,
/* 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;
+ (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;
+ crv = CKR_TOKEN_WRITE_PROTECTED;
+ goto done;
}
privKey = lg_GetPrivateKeyWithDB(obj, keyHandle);
if (privKey == NULL) {
- crv = CKR_OBJECT_HANDLE_INVALID;
- goto done;
+ 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;
+ 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);
+ PORT_Free(nickname);
}
return crv;
}
static CK_RV
-lg_SetPublicKeyAttribute(LGObjectCache *obj, CK_ATTRIBUTE_TYPE type,
- const void *value, unsigned int len,
- PRBool *writePrivate)
+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_OK;
}
- return CKR_ATTRIBUTE_READ_ONLY;
+ return CKR_ATTRIBUTE_READ_ONLY;
}
static CK_RV
lg_SetTrustAttribute(LGObjectCache *obj, const CK_ATTRIBUTE *attr)
{
unsigned int flags;
- CK_TRUST trust;
- NSSLOWCERTCertificate *cert;
+ CK_TRUST trust;
+ NSSLOWCERTCertificate *cert = NULL;
NSSLOWCERTCertDBHandle *certHandle;
- NSSLOWCERTCertTrust dbTrust;
+ NSSLOWCERTCertTrust dbTrust;
SECStatus rv;
CK_RV crv;
if (attr->type == CKA_LABEL) {
- return CKR_OK;
+ return CKR_OK;
}
crv = lg_GetULongAttribute(attr->type, attr, 1, &trust);
if (crv != CKR_OK) {
- return crv;
+ return crv;
}
- flags = lg_MapTrust(trust, (PRBool) (attr->type == CKA_TRUST_CLIENT_AUTH));
+ 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;
+ crv = CKR_TOKEN_WRITE_PROTECTED;
+ goto done;
}
cert = lg_getCert(obj, certHandle);
if (cert == NULL) {
- crv = CKR_OBJECT_HANDLE_INVALID;
- goto done;
+ 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;
+ 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:
+ if (cert) {
+ nsslowcert_DestroyCertificate(cert);
+ }
return crv;
}
static CK_RV
-lg_SetSingleAttribute(LGObjectCache *obj, const CK_ATTRIBUTE *attr,
- PRBool *writePrivate)
+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;
+ *writePrivate = PR_TRUE;
+ return CKR_OK;
}
/* Make sure the attribute exists first */
@@ -1703,50 +1710,50 @@ lg_SetSingleAttribute(LGObjectCache *obj, const CK_ATTRIBUTE *attr,
attribLocal.ulValueLen = 0;
crv = lg_GetSingleAttribute(obj, &attribLocal);
if (crv != CKR_OK) {
- return crv;
+ 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;
- }
+ 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;
+ 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)
+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;
@@ -1754,29 +1761,30 @@ lg_SetAttributeValue(SDB *sdb, CK_OBJECT_HANDLE handle,
unsigned int i;
if (obj == NULL) {
- return CKR_OBJECT_HANDLE_INVALID;
+ return CKR_OBJECT_HANDLE_INVALID;
}
- for (i=0; i < count; i++) {
- crv = lg_SetSingleAttribute(obj, &templ[i], &writePrivate);
- if (crvCollect == CKR_OK) crvCollect = crv;
+ 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;
- }
- PORT_Free(label);
+ 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;
+ }
+ PORT_Free(label);
}
lg_DestroyObjectCache(obj);
diff --git a/nss/lib/softoken/legacydb/lgcreate.c b/nss/lib/softoken/legacydb/lgcreate.c
index c5ce99e..a0d2b2e 100644
--- a/nss/lib/softoken/legacydb/lgcreate.c
+++ b/nss/lib/softoken/legacydb/lgcreate.c
@@ -3,34 +3,34 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "secitem.h"
#include "pkcs11.h"
-#include "lgdb.h"
+#include "lgdb.h"
#include "pcert.h"
#include "lowkeyi.h"
#include "blapi.h"
#include "secder.h"
#include "secasn1.h"
-#include "keydbi.h"
+#include "keydbi.h"
/*
* ******************** Object Creation Utilities ***************************
*/
/*
- * check the consistancy and initialize a Certificate Object
+ * 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)
+ 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 };
+ 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;
@@ -43,68 +43,69 @@ lg_createCertObject(SDB *sdb, CK_OBJECT_HANDLE *handle,
/* we can't store any certs private */
if (lg_isTrue(CKA_PRIVATE, templ, count)) {
- return CKR_ATTRIBUTE_VALUE_INVALID;
+ 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;
+ return crv;
}
if (type != CKC_X_509) {
- return CKR_ATTRIBUTE_VALUE_INVALID;
+ return CKR_ATTRIBUTE_VALUE_INVALID;
}
/* X.509 Certificate */
-
if (certHandle == NULL) {
- return CKR_TOKEN_WRITE_PROTECTED;
+ return CKR_TOKEN_WRITE_PROTECTED;
}
- /* get the der cert */
+ /* get the der cert */
attribute = lg_FindAttribute(CKA_VALUE, templ, count);
if (!attribute) {
- return CKR_ATTRIBUTE_VALUE_INVALID;
+ return CKR_ATTRIBUTE_VALUE_INVALID;
}
derCert.type = 0;
derCert.data = (unsigned char *)attribute->pValue;
- derCert.len = attribute->ulValueLen ;
+ derCert.len = attribute->ulValueLen;
label = lg_getString(CKA_LABEL, templ, count);
- cert = nsslowcert_FindCertByDERCert(certHandle, &derCert);
+ cert = nsslowcert_FindCertByDERCert(certHandle, &derCert);
if (cert == NULL) {
- cert = nsslowcert_DecodeDERCertificate(&derCert, label);
- inDB = PR_FALSE;
+ cert = nsslowcert_DecodeDERCertificate(&derCert, label);
+ inDB = PR_FALSE;
}
if (cert == NULL) {
- if (label) PORT_Free(label);
- return CKR_ATTRIBUTE_VALUE_INVALID;
+ if (label)
+ PORT_Free(label);
+ return CKR_ATTRIBUTE_VALUE_INVALID;
}
keyHandle = lg_getKeyDB(sdb);
if (keyHandle) {
- if (nsslowkey_KeyForCertExists(keyHandle,cert)) {
- trust = &userTrust;
- }
+ if (nsslowkey_KeyForCertExists(keyHandle, cert)) {
+ trust = &userTrust;
+ }
}
if (!inDB) {
- if (!trust) trust = &defTrust;
- rv = nsslowcert_AddPermCert(certHandle, cert, label, trust);
+ if (!trust)
+ trust = &defTrust;
+ rv = nsslowcert_AddPermCert(certHandle, cert, label, trust);
} else {
- rv = trust ? nsslowcert_ChangeCertTrust(certHandle,cert,trust) :
- SECSuccess;
+ rv = trust ? nsslowcert_ChangeCertTrust(certHandle, cert, trust) : SECSuccess;
}
- if (label) PORT_Free(label);
+ if (label)
+ PORT_Free(label);
if (rv != SECSuccess) {
- nsslowcert_DestroyCertificate(cert);
- return CKR_DEVICE_ERROR;
+ nsslowcert_DestroyCertificate(cert);
+ return CKR_DEVICE_ERROR;
}
/*
@@ -112,18 +113,18 @@ lg_createCertObject(SDB *sdb, CK_OBJECT_HANDLE *handle,
*/
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);
+ 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;
@@ -132,32 +133,30 @@ lg_createCertObject(SDB *sdb, CK_OBJECT_HANDLE *handle,
unsigned int
lg_MapTrust(CK_TRUST trust, PRBool clientAuth)
{
- unsigned int trustCA = clientAuth ? CERTDB_TRUSTED_CLIENT_CA :
- CERTDB_TRUSTED_CA;
+ 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;
+ 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
+ * 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 *templ, CK_ULONG count)
{
const CK_ATTRIBUTE *issuer = NULL;
const CK_ATTRIBUTE *serial = NULL;
@@ -175,30 +174,30 @@ lg_createTrustObject(SDB *sdb, CK_OBJECT_HANDLE *handle,
/* we can't store any certs private */
if (lg_isTrue(CKA_PRIVATE, templ, count)) {
- return CKR_ATTRIBUTE_VALUE_INVALID;
+ return CKR_ATTRIBUTE_VALUE_INVALID;
}
if (certHandle == NULL) {
- return CKR_TOKEN_WRITE_PROTECTED;
+ 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.derIssuer.data = (unsigned char *)issuer->pValue;
+ issuerSN.derIssuer.len = issuer->ulValueLen;
- issuerSN.serialNumber.data = (unsigned char *)serial->pValue;
- issuerSN.serialNumber.len = serial->ulValueLen ;
+ issuerSN.serialNumber.data = (unsigned char *)serial->pValue;
+ issuerSN.serialNumber.len = serial->ulValueLen;
- cert = nsslowcert_FindCertByIssuerAndSN(certHandle,&issuerSN);
+ cert = nsslowcert_FindCertByIssuerAndSN(certHandle, &issuerSN);
}
if (cert == NULL) {
- return CKR_ATTRIBUTE_VALUE_INVALID;
+ 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);
@@ -206,284 +205,283 @@ lg_createTrustObject(SDB *sdb, CK_OBJECT_HANDLE *handle,
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;
- }
+ 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 = 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);
+ 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;
+ dbTrust.sslFlags |= CERTDB_GOVT_APPROVED_CA;
}
- rv = nsslowcert_ChangeCertTrust(certHandle,cert,&dbTrust);
- *handle=lg_mkHandle(sdb,&cert->certKey,LG_TOKEN_TYPE_TRUST);
+ 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_DEVICE_ERROR;
}
return CKR_OK;
}
/*
- * check the consistancy and initialize a Trust Object
+ * 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)
+ const CK_ATTRIBUTE *templ, CK_ULONG count)
{
- SECItem derSubj,rawProfile,rawTime,emailKey;
+ SECItem derSubj, rawProfile, rawTime, emailKey;
SECItem *pRawProfile = NULL;
SECItem *pRawTime = NULL;
char *email = NULL;
const CK_ATTRIBUTE *subject = NULL,
- *profile = NULL,
- *time = 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;
+ if (lg_isTrue(CKA_PRIVATE, templ, count)) {
+ return CKR_ATTRIBUTE_VALUE_INVALID;
}
certHandle = lg_getCertDB(sdb);
if (certHandle == NULL) {
- return CKR_TOKEN_WRITE_PROTECTED;
+ return CKR_TOKEN_WRITE_PROTECTED;
}
/* lookup SUBJECT */
- subject = lg_FindAttribute(CKA_SUBJECT,templ,count);
+ subject = lg_FindAttribute(CKA_SUBJECT, templ, count);
PORT_Assert(subject);
if (!subject) {
- ck_rv = CKR_ATTRIBUTE_VALUE_INVALID;
- goto loser;
+ ck_rv = CKR_ATTRIBUTE_VALUE_INVALID;
+ goto loser;
}
derSubj.data = (unsigned char *)subject->pValue;
- derSubj.len = subject->ulValueLen ;
+ derSubj.len = subject->ulValueLen;
derSubj.type = 0;
/* lookup VALUE */
- profile = lg_FindAttribute(CKA_VALUE,templ,count);
+ profile = lg_FindAttribute(CKA_VALUE, templ, count);
if (profile) {
- rawProfile.data = (unsigned char *)profile->pValue;
- rawProfile.len = profile->ulValueLen ;
- rawProfile.type = siBuffer;
- pRawProfile = &rawProfile;
+ 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);
+ 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;
+ rawTime.data = (unsigned char *)time->pValue;
+ rawTime.len = time->ulValueLen;
+ rawTime.type = siBuffer;
+ pRawTime = &rawTime;
}
-
- email = lg_getString(CKA_NSS_EMAIL,templ,count);
+ email = lg_getString(CKA_NSS_EMAIL, templ, count);
if (!email) {
- ck_rv = CKR_ATTRIBUTE_VALUE_INVALID;
- goto loser;
+ ck_rv = CKR_ATTRIBUTE_VALUE_INVALID;
+ goto loser;
}
/* Store S/MIME Profile by SUBJECT */
- rv = nsslowcert_SaveSMimeProfile(certHandle, email, &derSubj,
- pRawProfile,pRawTime);
+ rv = nsslowcert_SaveSMimeProfile(certHandle, email, &derSubj,
+ pRawProfile, pRawTime);
if (rv != SECSuccess) {
- ck_rv = CKR_DEVICE_ERROR;
- goto loser;
+ ck_rv = CKR_DEVICE_ERROR;
+ goto loser;
}
emailKey.data = (unsigned char *)email;
- emailKey.len = PORT_Strlen(email)+1;
+ emailKey.len = PORT_Strlen(email) + 1;
*handle = lg_mkHandle(sdb, &emailKey, LG_TOKEN_TYPE_SMIME);
loser:
- if (email) PORT_Free(email);
+ if (email)
+ PORT_Free(email);
return ck_rv;
}
/*
- * check the consistancy and initialize a Trust Object
+ * 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)
+ const CK_ATTRIBUTE *templ, CK_ULONG count)
{
PRBool isKRL = PR_FALSE;
- SECItem derSubj,derCrl;
+ SECItem derSubj, derCrl;
char *url = NULL;
- const CK_ATTRIBUTE *subject,*crl;
+ 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 (lg_isTrue(CKA_PRIVATE, templ, count)) {
+ return CKR_ATTRIBUTE_VALUE_INVALID;
}
if (certHandle == NULL) {
- return CKR_TOKEN_WRITE_PROTECTED;
+ return CKR_TOKEN_WRITE_PROTECTED;
}
/* lookup SUBJECT */
- subject = lg_FindAttribute(CKA_SUBJECT,templ,count);
+ subject = lg_FindAttribute(CKA_SUBJECT, templ, count);
if (!subject) {
- return CKR_ATTRIBUTE_VALUE_INVALID;
+ return CKR_ATTRIBUTE_VALUE_INVALID;
}
derSubj.data = (unsigned char *)subject->pValue;
- derSubj.len = subject->ulValueLen ;
+ derSubj.len = subject->ulValueLen;
/* lookup VALUE */
- crl = lg_FindAttribute(CKA_VALUE,templ,count);
+ crl = lg_FindAttribute(CKA_VALUE, templ, count);
PORT_Assert(crl);
if (!crl) {
- return CKR_ATTRIBUTE_VALUE_INVALID;
+ return CKR_ATTRIBUTE_VALUE_INVALID;
}
derCrl.data = (unsigned char *)crl->pValue;
- derCrl.len = crl->ulValueLen ;
+ derCrl.len = crl->ulValueLen;
- url = lg_getString(CKA_NSS_URL,templ,count);
- isKRL = lg_isTrue(CKA_NSS_KRL,templ,count);
+ 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);
+ PORT_Free(url);
}
if (rv != SECSuccess) {
- return CKR_DEVICE_ERROR;
+ 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);
+ (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);
+ isKRL ? LG_TOKEN_KRL_HANDLE : LG_TOKEN_TYPE_CRL);
return CKR_OK;
}
/*
- * check the consistancy and initialize a Public Key Object
+ * 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_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 pubKeySpace = { siBuffer, NULL, 0 };
SECItem *pubKey;
#ifndef NSS_DISABLE_ECC
- SECItem pubKey2Space = {siBuffer, NULL, 0};
+ SECItem pubKey2Space = { siBuffer, NULL, 0 };
PLArenaPool *arena = NULL;
#endif /* NSS_DISABLE_ECC */
NSSLOWKEYDBHandle *keyHandle = NULL;
-
switch (key_type) {
- case CKK_RSA:
- pubKeyAttr = CKA_MODULUS;
- break;
+ case CKK_RSA:
+ pubKeyAttr = CKA_MODULUS;
+ break;
#ifndef NSS_DISABLE_ECC
- case CKK_EC:
- pubKeyAttr = CKA_EC_POINT;
- break;
+ case CKK_EC:
+ pubKeyAttr = CKA_EC_POINT;
+ break;
#endif /* NSS_DISABLE_ECC */
- case CKK_DSA:
- case CKK_DH:
- break;
- default:
- return CKR_ATTRIBUTE_VALUE_INVALID;
+ 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;
+ crv = lg_Attribute2SSecItem(NULL, pubKeyAttr, templ, count, pubKey);
+ if (crv != CKR_OK)
+ return crv;
#ifndef NSS_DISABLE_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;
- }
+ 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_DISABLE_ECC */
PORT_Assert(pubKey->data);
if (pubKey->data == NULL) {
- crv = CKR_ATTRIBUTE_VALUE_INVALID;
- goto done;
+ crv = CKR_ATTRIBUTE_VALUE_INVALID;
+ goto done;
}
keyHandle = lg_getKeyDB(sdb);
if (keyHandle == NULL) {
- crv = CKR_TOKEN_WRITE_PROTECTED;
- goto done;
+ 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);
+ 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*/);
#ifndef NSS_DISABLE_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*/);
+ /* 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;
+ /* 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;
@@ -493,8 +491,8 @@ lg_createPublicKeyObject(SDB *sdb, CK_KEY_TYPE key_type,
done:
PORT_Free(pubKeySpace.data);
#ifndef NSS_DISABLE_ECC
- if (arena)
- PORT_FreeArena(arena, PR_FALSE);
+ if (arena)
+ PORT_FreeArena(arena, PR_FALSE);
#endif
return crv;
@@ -503,7 +501,7 @@ done:
/* 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)
+ CK_KEY_TYPE key_type, CK_RV *crvp)
{
NSSLOWKEYPrivateKey *privKey;
PLArenaPool *arena;
@@ -512,142 +510,162 @@ lg_mkPrivKey(SDB *sdb, const CK_ATTRIBUTE *templ, CK_ULONG count,
arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
if (arena == NULL) {
- *crvp = CKR_HOST_MEMORY;
- return 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;
+ 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;
+ 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;
#ifndef NSS_DISABLE_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;
+ 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_DISABLE_ECC */
- default:
- crv = CKR_KEY_TYPE_INCONSISTENT;
- break;
+ default:
+ crv = CKR_KEY_TYPE_INCONSISTENT;
+ break;
}
*crvp = crv;
if (crv != CKR_OK) {
- PORT_FreeArena(arena,PR_FALSE);
- return NULL;
+ PORT_FreeArena(arena, PR_FALSE);
+ return NULL;
}
return privKey;
}
/*
- * check the consistancy and initialize a Private Key Object
+ * 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)
+ CK_OBJECT_HANDLE *handle, const CK_ATTRIBUTE *templ, CK_ULONG count)
{
NSSLOWKEYPrivateKey *privKey;
char *label;
@@ -657,53 +675,56 @@ lg_createPrivateKeyObject(SDB *sdb, CK_KEY_TYPE key_type,
NSSLOWKEYDBHandle *keyHandle = lg_getKeyDB(sdb);
if (keyHandle == NULL) {
- return CKR_TOKEN_WRITE_PROTECTED;
+ 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);
+ 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);
+ crv = lg_Attribute2SSecItem(NULL, CKA_NETSCAPE_DB, templ, count, &pubKey);
if (crv != CKR_OK) {
- crv = CKR_TEMPLATE_INCOMPLETE;
- rv = SECFailure;
- goto fail;
+ 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);
+ 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 = RSA_PrivateKeyCheck(&privKey->u.rsa);
+ if (rv == SECFailure) {
+ goto fail;
+ }
}
- rv = nsslowkey_StoreKeyByPublicKey(keyHandle, privKey, &pubKey,
- label, sdb /*->password*/);
+ 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);
+ 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;
+ 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 */
+#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.
+ * will generate one if there wasn't one already.
*/
static CK_RV
lg_GenerateSecretCKA_ID(NSSLOWKEYDBHandle *handle, SECItem *id, char *label)
@@ -714,43 +735,43 @@ lg_GenerateSecretCKA_ID(NSSLOWKEYDBHandle *handle, SECItem *id, char *label)
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_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;
+ 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));
+ 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;
+ 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)
+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;
@@ -762,17 +783,23 @@ static NSSLOWKEYPrivateKey *lg_mkSecretKeyRep(const CK_ATTRIBUTE *templ,
static unsigned char derZero[1] = { 0 };
arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
- if (arena == NULL) { crv = CKR_HOST_MEMORY; goto loser; }
+ 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; }
+ 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.
+ /* 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)
@@ -784,10 +811,10 @@ static NSSLOWKEYPrivateKey *lg_mkSecretKeyRep(const CK_ATTRIBUTE *templ,
/* The modulus is set to the key id of the symmetric key */
privKey->u.rsa.modulus.data =
- (unsigned char *) PORT_ArenaAlloc(arena, pubkey->len);
+ (unsigned char *)PORT_ArenaAlloc(arena, pubkey->len);
if (privKey->u.rsa.modulus.data == NULL) {
- crv = CKR_HOST_MEMORY;
- goto loser;
+ crv = CKR_HOST_MEMORY;
+ goto loser;
}
privKey->u.rsa.modulus.len = pubkey->len;
PORT_Memcpy(privKey->u.rsa.modulus.data, pubkey->data, pubkey->len);
@@ -798,8 +825,9 @@ static NSSLOWKEYPrivateKey *lg_mkSecretKeyRep(const CK_ATTRIBUTE *templ,
/* 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;
+ &privKey->u.rsa.privateExponent, sdbpw);
+ if (crv != CKR_OK)
+ goto loser;
/* All other fields empty - needs testing */
privKey->u.rsa.prime1.len = sizeof derZero;
@@ -816,43 +844,47 @@ static NSSLOWKEYPrivateKey *lg_mkSecretKeyRep(const CK_ATTRIBUTE *templ,
/* Coeficient set to KEY_TYPE */
crv = lg_GetULongAttribute(CKA_KEY_TYPE, templ, count, &keyType);
- if (crv != CKR_OK) goto loser;
+ 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 = (PRUint32)keyType;
keyTypeStorage = PR_htonl(keyTypeStorage);
keyTypeItem.data = (unsigned char *)&keyTypeStorage;
- keyTypeItem.len = sizeof (keyTypeStorage);
+ keyTypeItem.len = sizeof(keyTypeStorage);
rv = SECITEM_CopyItem(arena, &privKey->u.rsa.coefficient, &keyTypeItem);
if (rv != SECSuccess) {
- crv = CKR_HOST_MEMORY;
- goto loser;
+ 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; }
+ 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;
+ PORT_FreeArena(arena, PR_FALSE);
+ privKey = 0;
}
return privKey;
}
/*
- * check the consistancy and initialize a Secret Key Object
+ * 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_OBJECT_HANDLE *handle, const CK_ATTRIBUTE *templ, CK_ULONG count)
{
CK_RV crv;
- NSSLOWKEYPrivateKey *privKey = NULL;
- NSSLOWKEYDBHandle *keyHandle = NULL;
+ NSSLOWKEYPrivateKey *privKey = NULL;
+ NSSLOWKEYDBHandle *keyHandle = NULL;
SECItem pubKey;
char *label = NULL;
SECStatus rv = SECSuccess;
@@ -863,54 +895,59 @@ lg_createSecretKeyObject(SDB *sdb, CK_KEY_TYPE key_type,
keyHandle = lg_getKeyDB(sdb);
if (keyHandle == NULL) {
- return CKR_TOKEN_WRITE_PROTECTED;
+ return CKR_TOKEN_WRITE_PROTECTED;
}
- label = lg_getString(CKA_LABEL,templ,count);
+ 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;
+ 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;
+ 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;
+ crv = CKR_HOST_MEMORY;
+ goto loser;
}
rv = nsslowkey_StoreKeyByPublicKey(keyHandle,
- privKey, &pubKey, label, sdb /*->password*/);
+ privKey, &pubKey, label, sdb /*->password*/);
if (rv != SECSuccess) {
- crv = CKR_DEVICE_ERROR;
- goto loser;
+ 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);
+ 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
+ * 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)
+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;
@@ -918,29 +955,29 @@ lg_createKeyObject(SDB *sdb, CK_OBJECT_CLASS objclass,
/* get the key type */
crv = lg_GetULongAttribute(CKA_KEY_TYPE, templ, count, &key_type);
if (crv != CKR_OK) {
- return crv;
+ 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;
+ 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)
+ const CK_ATTRIBUTE *templ, CK_ULONG count)
{
CK_RV crv;
CK_OBJECT_CLASS objclass;
@@ -948,34 +985,33 @@ lg_CreateObject(SDB *sdb, CK_OBJECT_HANDLE *handle,
/* get the object class */
crv = lg_GetULongAttribute(CKA_CLASS, templ, count, &objclass);
if (crv != CKR_OK) {
- return crv;
+ return crv;
}
- /* Now handle the specific object class.
+ /* 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;
+ 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/nss/lib/softoken/legacydb/lgdb.h b/nss/lib/softoken/legacydb/lgdb.h
index c67bffa..ee80f4b 100644
--- a/nss/lib/softoken/legacydb/lgdb.h
+++ b/nss/lib/softoken/legacydb/lgdb.h
@@ -13,12 +13,10 @@
#include "lowkeyti.h"
#include "pkcs11t.h"
#include "sdb.h"
-#include "cdbhdl.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"
@@ -27,39 +25,37 @@
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);
+ 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);
+ 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);
+ const CK_ATTRIBUTE *templ, CK_ULONG count);
extern PRBool lg_isTrue(CK_ATTRIBUTE_TYPE type,
- const CK_ATTRIBUTE *templ, CK_ULONG count);
+ 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);
+ 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);
@@ -67,28 +63,30 @@ NSSLOWKEYDBHandle *lg_getKeyDB(SDB *sdb);
const char *lg_EvaluateConfigDir(const char *configdir, char **domain);
+/* verify the FIPS selftests ran and were successful */
+PRBool lg_FIPSEntryOK(void);
/*
* object handle modifiers
*/
-#define LG_TOKEN_MASK 0xc0000000L
-#define LG_TOKEN_TYPE_MASK 0x38000000L
-#define LG_TOKEN_TYPE_SHIFT 27
+#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
+#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_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_TOKEN_KRL_HANDLE (LG_TOKEN_TYPE_CRL | 1)
-#define LG_SEARCH_BLOCK_SIZE 10
-#define LG_BUF_SPACE 50
-#define LG_STRICT PR_FALSE
+#define LG_SEARCH_BLOCK_SIZE 10
+#define LG_BUF_SPACE 50
+#define LG_STRICT PR_FALSE
/*
* token object utilities
@@ -96,48 +94,47 @@ const char *lg_EvaluateConfigDir(const char *configdir, char **domain);
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 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);
+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
+/* 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
+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);
+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);
+CK_RV lg_FindObjectsFinal(SDB *lgdb, SDBFind *search);
-/* lg_CreateObject parses the template and create an object stored in the
+/* 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);
+ 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_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);
@@ -151,8 +148,8 @@ 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);
+CK_RV lg_PutMetaData(SDB *sdb, const char *id,
+ const SECItem *item1, const SECItem *item2);
SEC_END_PROTOS
@@ -165,7 +162,9 @@ SEC_END_PROTOS
#ifndef NO_FORK_CHECK
extern PRBool lg_parentForkedAfterC_Initialize;
-#define SKIP_AFTER_FORK(x) if (!lg_parentForkedAfterC_Initialize) x
+#define SKIP_AFTER_FORK(x) \
+ if (!lg_parentForkedAfterC_Initialize) \
+ x
#else
@@ -174,4 +173,3 @@ extern PRBool lg_parentForkedAfterC_Initialize;
#endif /* NO_FORK_CHECK */
#endif /* _LGDB_H_ */
-
diff --git a/nss/lib/softoken/legacydb/lgdestroy.c b/nss/lib/softoken/legacydb/lgdestroy.c
index 914da51..1e3839d 100644
--- a/nss/lib/softoken/legacydb/lgdestroy.c
+++ b/nss/lib/softoken/legacydb/lgdestroy.c
@@ -25,87 +25,86 @@ lg_DestroyObject(SDB *sdb, CK_OBJECT_HANDLE object_id)
const SECItem *dbKey;
object_id &= ~LG_TOKEN_MASK;
- dbKey = lg_lookupTokenKeyByHandle(sdb,object_id);
+ dbKey = lg_lookupTokenKeyByHandle(sdb, object_id);
if (dbKey == NULL) {
- return CKR_OBJECT_HANDLE_INVALID;
+ 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;
+ 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_deleteTokenKeyByHandle(sdb, object_id);
lg_DBUnlock(sdb);
return crv;
}
-
-
-
diff --git a/nss/lib/softoken/legacydb/lgfind.c b/nss/lib/softoken/legacydb/lgfind.c
index a512cba..288e56c 100644
--- a/nss/lib/softoken/legacydb/lgfind.c
+++ b/nss/lib/softoken/legacydb/lgfind.c
@@ -8,7 +8,7 @@
#include "pcert.h"
#include "blapi.h"
-#include "keydbi.h"
+#include "keydbi.h"
/*
* This code maps PKCS #11 Finds to legacy database searches. This code
@@ -16,13 +16,12 @@
*/
struct SDBFindStr {
- CK_OBJECT_HANDLE *handles;
- int size;
- int index;
- int array_size;
+ CK_OBJECT_HANDLE *handles;
+ int size;
+ int index;
+ int array_size;
};
-
/*
* free a search structure
*/
@@ -30,7 +29,7 @@ void
lg_FreeSearch(SDBFind *search)
{
if (search->handles) {
- PORT_Free(search->handles);
+ PORT_Free(search->handles);
}
PORT_Free(search);
}
@@ -39,15 +38,15 @@ void
lg_addHandle(SDBFind *search, CK_OBJECT_HANDLE handle)
{
if (search->handles == NULL) {
- return;
+ 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->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++;
@@ -56,13 +55,13 @@ lg_addHandle(SDBFind *search, CK_OBJECT_HANDLE handle)
/*
* 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
+#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.
@@ -74,60 +73,58 @@ typedef struct lgEntryDataStr {
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;
+ 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));
+ crlData->template, crlData->templ_count)) {
+ lg_addHandle(crlData->searchHandles,
+ lg_mkHandle(sdb, key, class_handle));
}
- return(SECSuccess);
+ return (SECSuccess);
}
static void
-lg_searchCrls(SDB *sdb, SECItem *derSubject, PRBool isKrl,
- unsigned long classFlags, SDBFind *search,
- const CK_ATTRIBUTE *pTemplate, CK_ULONG ulCount)
+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;
+ return;
}
- if (derSubject->data != NULL) {
- certDBEntryRevocation *crl =
- nsslowcert_FindCrlByKey(certHandle, derSubject, isKrl);
+ 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);
- }
+ 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);
- }
+ 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);
+ }
}
/*
@@ -147,16 +144,14 @@ typedef struct lgKeyDataStr {
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;
+ if (privKey->keyType == NSSLOWKEYRSAKey &&
+ privKey->u.rsa.publicExponent.len == 1 &&
+ privKey->u.rsa.publicExponent.data[0] == 0)
+ return PR_TRUE;
- return PR_FALSE;
+ return PR_FALSE;
}
-
-
static SECStatus
lg_key_collect(DBT *key, DBT *data, void *arg)
{
@@ -165,7 +160,7 @@ lg_key_collect(DBT *key, DBT *data, void *arg)
SECItem tmpDBKey;
SDB *sdb;
unsigned long classFlags;
-
+
keyData = (lgKeyData *)arg;
sdb = keyData->sdb;
classFlags = keyData->classFlags;
@@ -176,97 +171,95 @@ lg_key_collect(DBT *key, DBT *data, void *arg)
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;
+ 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));
- }
+ 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));
- }
+ 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);
+ if (privKey) {
+ lg_nsslowkey_DestroyPrivateKey(privKey);
}
- return(SECSuccess);
+ 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)
+ unsigned long classFlags, SDBFind *search, PRBool mustStrict,
+ const CK_ATTRIBUTE *pTemplate, CK_ULONG ulCount)
{
NSSLOWKEYDBHandle *keyHandle = NULL;
NSSLOWKEYPrivateKey *privKey;
@@ -275,42 +268,42 @@ lg_searchKeys(SDB *sdb, SECItem *key_id,
keyHandle = lg_getKeyDB(sdb);
if (keyHandle == NULL) {
- return;
+ 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;
- }
+ 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;
@@ -336,49 +329,48 @@ typedef struct lgCertDataStr {
int max_cert_count;
NSSLOWCERTCertificate **certs;
const CK_ATTRIBUTE *template;
- CK_ULONG templ_count;
+ CK_ULONG templ_count;
unsigned long classFlags;
- PRBool strict;
+ PRBool strict;
} lgCertData;
/*
* collect all the certs from the traverse call.
- */
+ */
static SECStatus
-lg_cert_collect(NSSLOWCERTCertificate *cert,void *arg)
+lg_cert_collect(NSSLOWCERTCertificate *cert, void *arg)
{
lgCertData *cd = (lgCertData *)arg;
if (cert == NULL) {
- return SECSuccess;
+ return SECSuccess;
}
if (cd->certs == NULL) {
- return SECFailure;
+ 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;
- }
+ 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;
- }
+ 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);
@@ -393,53 +385,54 @@ lg_cert_collect2(NSSLOWCERTCertificate *cert, SECItem *dymmy, void *arg)
}
static void
-lg_searchSingleCert(lgCertData *certData,NSSLOWCERTCertificate *cert)
+lg_searchSingleCert(lgCertData *certData, NSSLOWCERTCertificate *cert)
{
if (cert == NULL) {
- return;
+ return;
}
- if (certData->strict &&
- !lg_tokenMatch(certData->sdb, &cert->certKey, LG_TOKEN_TYPE_CERT,
- certData->template,certData->templ_count)) {
- nsslowcert_DestroyCertificate(cert);
- 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 *));
+ certData->certs = (NSSLOWCERTCertificate **)
+ PORT_Alloc(sizeof(NSSLOWCERTCertificate *));
if (certData->certs == NULL) {
- nsslowcert_DestroyCertificate(cert);
- return;
+ nsslowcert_DestroyCertificate(cert);
+ return;
}
certData->certs[0] = cert;
certData->cert_count = 1;
}
static void
-lg_CertSetupData(lgCertData *certData,int count)
+lg_CertSetupData(lgCertData *certData, int count)
{
certData->max_cert_count = count;
if (certData->max_cert_count <= 0) {
- return;
+ return;
}
certData->certs = (NSSLOWCERTCertificate **)
- PORT_Alloc( count * sizeof(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)
+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;
+ if (certHandle == NULL)
+ return;
certData.sdb = sdb;
certData.max_cert_count = 0;
@@ -447,107 +440,107 @@ lg_searchCertsAndTrust(SDB *sdb, SECItem *derCert, SECItem *name,
certData.cert_count = 0;
certData.template = pTemplate;
certData.templ_count = ulCount;
- certData.classFlags = classFlags;
- certData.strict = LG_STRICT;
-
+ certData.classFlags = classFlags;
+ certData.strict = LG_STRICT;
/*
* Find the Cert.
*/
if (derCert->data != NULL) {
- NSSLOWCERTCertificate *cert =
- nsslowcert_FindCertByDERCert(certHandle,derCert);
- lg_searchSingleCert(&certData,cert);
+ 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);
+ 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)) {
+ 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);
- }
- }
+ 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);
+ 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);
+ /* 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);
+ */
+ 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;
}
@@ -556,67 +549,68 @@ 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));
+ smimeData->template, smimeData->templ_count)) {
+ lg_addHandle(smimeData->searchHandles,
+ lg_mkHandle(sdb, key, LG_TOKEN_TYPE_SMIME));
}
- return(SECSuccess);
+ return (SECSuccess);
}
static void
-lg_searchSMime(SDB *sdb, SECItem *email, SDBFind *handles,
- const CK_ATTRIBUTE *pTemplate, CK_LONG ulCount)
+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 (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);
+ 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 */
+ 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);
+ /* 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)
+ const CK_ATTRIBUTE *pTemplate, CK_LONG ulCount)
{
int i;
PRBool isKrl = PR_FALSE;
@@ -626,10 +620,10 @@ lg_searchTokenList(SDB *sdb, SDBFind *search,
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 };
+ SECItem cert_md5_hash = { siBuffer, NULL, 0 };
NSSLOWCERTIssuerAndSN issuerSN = {
- { siBuffer, NULL, 0 },
- { siBuffer, NULL, 0 }
+ { siBuffer, NULL, 0 },
+ { siBuffer, NULL, 0 }
};
SECItem *copy = NULL;
CK_CERTIFICATE_TYPE certType;
@@ -638,9 +632,9 @@ lg_searchTokenList(SDB *sdb, SDBFind *search,
unsigned long classFlags;
if (lg_getCertDB(sdb) == NULL) {
- classFlags = LG_PRIVATE|LG_KEY;
+ classFlags = LG_PRIVATE | LG_KEY;
} else {
- classFlags = LG_CERT|LG_TRUST|LG_PUBLIC|LG_SMIME|LG_CRL;
+ classFlags = LG_CERT | LG_TRUST | LG_PUBLIC | LG_SMIME | LG_CRL;
}
/*
@@ -650,214 +644,216 @@ lg_searchTokenList(SDB *sdb, SDBFind *search,
* 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;
+ 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);
+ 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);
+ 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);
+ 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);
+ lg_searchSMime(sdb, &email, search, pTemplate, ulCount);
}
return CKR_OK;
}
-
-/* lg_FindObjectsInit initializes a search for token and session objects
+/* 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)
+CK_RV
+lg_FindObjectsInit(SDB *sdb, const CK_ATTRIBUTE *pTemplate,
+ CK_ULONG ulCount, SDBFind **retSearch)
{
SDBFind *search;
CK_RV crv = CKR_OK;
-
- *retSearch = NULL;
+
+ *retSearch = NULL;
search = (SDBFind *)PORT_Alloc(sizeof(SDBFind));
if (search == NULL) {
- crv = CKR_HOST_MEMORY;
- goto loser;
+ crv = CKR_HOST_MEMORY;
+ goto loser;
}
search->handles = (CK_OBJECT_HANDLE *)
- PORT_Alloc(sizeof(CK_OBJECT_HANDLE) * LG_SEARCH_BLOCK_SIZE);
+ PORT_Alloc(sizeof(CK_OBJECT_HANDLE) * LG_SEARCH_BLOCK_SIZE);
if (search->handles == NULL) {
- crv = CKR_HOST_MEMORY;
- goto loser;
+ crv = CKR_HOST_MEMORY;
+ goto loser;
}
search->index = 0;
search->size = 0;
@@ -866,7 +862,7 @@ CK_RV lg_FindObjectsInit(SDB *sdb, const CK_ATTRIBUTE *pTemplate,
crv = lg_searchTokenList(sdb, search, pTemplate, ulCount);
if (crv != CKR_OK) {
- goto loser;
+ goto loser;
}
*retSearch = search;
@@ -874,29 +870,29 @@ CK_RV lg_FindObjectsInit(SDB *sdb, const CK_ATTRIBUTE *pTemplate,
loser:
if (search) {
- lg_FreeSearch(search);
+ lg_FreeSearch(search);
}
return crv;
}
-
-/* lg_FindObjects continues a search for token and session objects
+/* 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)
+CK_RV
+lg_FindObjects(SDB *sdb, SDBFind *search,
+ CK_OBJECT_HANDLE *phObject, CK_ULONG ulMaxObjectCount,
+ CK_ULONG *pulObjectCount)
{
- int transfer;
+ 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));
+ PORT_Memcpy(phObject, &search->handles[search->index],
+ transfer * sizeof(CK_OBJECT_HANDLE));
} else {
- *phObject = CK_INVALID_HANDLE;
+ *phObject = CK_INVALID_HANDLE;
}
search->index += transfer;
@@ -905,11 +901,12 @@ CK_RV lg_FindObjects(SDB *sdb, SDBFind *search,
}
/* lg_FindObjectsFinal finishes a search for token and session objects. */
-CK_RV lg_FindObjectsFinal(SDB* lgdb, SDBFind *search)
+CK_RV
+lg_FindObjectsFinal(SDB *lgdb, SDBFind *search)
{
if (search != NULL) {
- lg_FreeSearch(search);
+ lg_FreeSearch(search);
}
return CKR_OK;
}
diff --git a/nss/lib/softoken/legacydb/lgfips.c b/nss/lib/softoken/legacydb/lgfips.c
new file mode 100644
index 0000000..b017424
--- /dev/null
+++ b/nss/lib/softoken/legacydb/lgfips.c
@@ -0,0 +1,115 @@
+/*
+ * 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: fipstest.c,v 1.31 2012/06/28 17:55:06 rrelyea%redhat.com Exp $ */
+
+#include "seccomon.h"
+#include "lgdb.h"
+#include "blapi.h"
+
+/*
+ * different platforms have different ways of calling and initial entry point
+ * when the dll/.so is loaded. Most platforms support either a posix pragma
+ * or the GCC attribute. Some platforms suppor a pre-defined name, and some
+ * platforms have a link line way of invoking this function.
+ */
+
+/* The pragma */
+#if defined(USE_INIT_PRAGMA)
+#pragma init(lg_startup_tests)
+#endif
+
+/* GCC Attribute */
+#if defined(__GNUC__) && !defined(NSS_NO_INIT_SUPPORT)
+#define INIT_FUNCTION __attribute__((constructor))
+#else
+#define INIT_FUNCTION
+#endif
+
+static void INIT_FUNCTION lg_startup_tests(void);
+
+/* Windows pre-defined entry */
+#if defined(XP_WIN) && !defined(NSS_NO_INIT_SUPPORT)
+#include <windows.h>
+
+BOOL WINAPI DllMain(
+ HINSTANCE hinstDLL, // handle to DLL module
+ DWORD fdwReason, // reason for calling function
+ LPVOID lpReserved) // reserved
+{
+ // Perform actions based on the reason for calling.
+ switch (fdwReason) {
+ case DLL_PROCESS_ATTACH:
+ // Initialize once for each new process.
+ // Return FALSE to fail DLL load.
+ lg_startup_tests();
+ break;
+
+ case DLL_THREAD_ATTACH:
+ // Do thread-specific initialization.
+ break;
+
+ case DLL_THREAD_DETACH:
+ // Do thread-specific cleanup.
+ break;
+
+ case DLL_PROCESS_DETACH:
+ // Perform any necessary cleanup.
+ break;
+ }
+ return TRUE; // Successful DLL_PROCESS_ATTACH.
+}
+#endif
+
+static PRBool lg_self_tests_ran = PR_FALSE;
+static PRBool lg_self_tests_success = PR_FALSE;
+
+static void
+lg_local_function(void)
+{
+}
+
+/*
+ * This function is called at dll load time, the code tha makes this
+ * happen is platform specific on defined above.
+ */
+static void
+lg_startup_tests(void)
+{
+ const char *libraryName = LG_LIB_NAME;
+
+ PORT_Assert(!lg_self_tests_ran);
+ PORT_Assert(!lg_self_tests_success);
+ lg_self_tests_ran = PR_TRUE;
+ lg_self_tests_success = PR_FALSE; /* just in case */
+
+ /* no self tests required for the legacy db, only the integrity check */
+ /* check the integrity of our shared library */
+ if (!BLAPI_SHVerify(libraryName, (PRFuncPtr)&lg_local_function)) {
+ /* something is wrong with the library, fail without enabling
+ * the fips token */
+ return;
+ }
+ /* FIPS product has been installed and is functioning, allow
+ * the module to operate in fips mode */
+ lg_self_tests_success = PR_TRUE;
+}
+
+PRBool
+lg_FIPSEntryOK()
+{
+#ifdef NSS_NO_INIT_SUPPORT
+ /* this should only be set on platforms that can't handle one of the INIT
+ * schemes. This code allows those platforms to continue to function,
+ * though they don't meet the strict NIST requirements. If NO_INIT_SUPPORT
+ * is not set, and init support has not been properly enabled, softken
+ * will always fail because of the test below */
+ if (!lg_self_tests_ran) {
+ lg_startup_tests();
+ }
+#endif
+ return lg_self_tests_success;
+}
diff --git a/nss/lib/softoken/legacydb/lginit.c b/nss/lib/softoken/legacydb/lginit.c
index b49f3fe..6913eea 100644
--- a/nss/lib/softoken/legacydb/lginit.c
+++ b/nss/lib/softoken/legacydb/lginit.c
@@ -42,34 +42,34 @@ lg_certdb_name_cb(void *arg, int dbVersion)
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;
+ 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);
+ dbname = PORT_Strdup(smpname);
+ PR_smprintf_free(smpname);
}
return dbname;
}
-
+
static char *
lg_keydb_name_cb(void *arg, int dbVersion)
{
@@ -77,50 +77,50 @@ lg_keydb_name_cb(void *arg, int dbVersion)
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;
+ 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);
+ dbname = PORT_Strdup(smpname);
+ PR_smprintf_free(smpname);
}
return dbname;
}
const char *
-lg_EvaluateConfigDir(const char *configdir,char **appName)
+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;
+ 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;
}
@@ -130,21 +130,22 @@ 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
+#define RDBLIB SHLIB_PREFIX "rdb." SHLIB_SUFFIX
-DB * rdbopen(const char *appName, const char *prefix,
- const char *type, int flags, int *status)
+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;
+ db = (*lg_rdbfunc)(appName, prefix, type, rdbmapflags(flags));
+ if (!db && status && lg_rdbstatusfunc) {
+ *status = (*lg_rdbstatusfunc)();
+ }
+ return db;
}
/*
@@ -153,22 +154,22 @@ DB * rdbopen(const char *appName, const char *prefix,
lib = PR_LoadLibrary(RDBLIB);
if (!lib) {
- return NULL;
+ return NULL;
}
/* get the entry points */
- lg_rdbstatusfunc = (rdbstatusfunc) PR_FindSymbol(lib,"rdbstatus");
- lg_rdbfunc = (rdbfunc) PR_FindSymbol(lib,"rdbopen");
+ 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;
+ 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");
+ disableUnload = PR_GetEnvSecure("NSS_DISABLE_UNLOAD");
if (!disableUnload) {
PR_UnloadLibrary(lib);
}
@@ -179,37 +180,38 @@ DB * rdbopen(const char *appName, const char *prefix,
* the following data structures are from rdb.h.
*/
struct RDBStr {
- DB db;
+ 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
+#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;
+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;
+ return (PRBool)db->type == DB_RDB;
}
int
@@ -217,7 +219,7 @@ db_BeginTransaction(DB *db)
{
struct RDBStr *rdb = (struct RDBStr *)db;
if (db->type != DB_RDB) {
- return 0;
+ return 0;
}
return rdb->xactstart(db);
@@ -228,7 +230,7 @@ db_FinishTransaction(DB *db, PRBool abort)
{
struct RDBStr *rdb = (struct RDBStr *)db;
if (db->type != DB_RDB) {
- return 0;
+ return 0;
}
return rdb->xactdone(db, abort);
@@ -242,11 +244,11 @@ lg_getRawDB(SDB *sdb)
certDB = lg_getCertDB(sdb);
if (certDB) {
- return certDB->permCertDB;
+ return certDB->permCertDB;
}
keyDB = lg_getKeyDB(sdb);
if (keyDB) {
- return keyDB->db;
+ return keyDB->db;
}
return NULL;
}
@@ -258,11 +260,11 @@ lg_Begin(SDB *sdb)
int ret;
if (db == NULL) {
- return CKR_GENERAL_ERROR; /* shouldn't happen */
+ return CKR_GENERAL_ERROR; /* shouldn't happen */
}
ret = db_BeginTransaction(db);
if (ret != 0) {
- return CKR_GENERAL_ERROR; /* could happen */
+ return CKR_GENERAL_ERROR; /* could happen */
}
return CKR_OK;
}
@@ -274,11 +276,11 @@ lg_Commit(SDB *sdb)
int ret;
if (db == NULL) {
- return CKR_GENERAL_ERROR; /* shouldn't happen */
+ return CKR_GENERAL_ERROR; /* shouldn't happen */
}
ret = db_FinishTransaction(db, PR_FALSE);
if (ret != 0) {
- return CKR_GENERAL_ERROR; /* could happen */
+ return CKR_GENERAL_ERROR; /* could happen */
}
return CKR_OK;
}
@@ -290,11 +292,11 @@ lg_Abort(SDB *sdb)
int ret;
if (db == NULL) {
- return CKR_GENERAL_ERROR; /* shouldn't happen */
+ return CKR_GENERAL_ERROR; /* shouldn't happen */
}
ret = db_FinishTransaction(db, PR_TRUE);
if (ret != 0) {
- return CKR_GENERAL_ERROR; /* could happen */
+ return CKR_GENERAL_ERROR; /* could happen */
}
return CKR_OK;
}
@@ -304,100 +306,102 @@ db_InitComplete(DB *db)
{
struct RDBStr *rdb = (struct RDBStr *)db;
if (db->type != DB_RDB) {
- return 0;
+ 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 0;
}
return rdb->dbinitcomplete(db);
}
-
-
SECStatus
-db_Copy(DB *dest,DB *src)
+db_Copy(DB *dest, DB *src)
{
int ret;
- DBT key,data;
+ DBT key, data;
ret = (*src->seq)(src, &key, &data, R_FIRST);
- if (ret) {
- return SECSuccess;
+ 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);
+ (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)
+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;
+ CK_RV crv = CKR_NETSCAPE_CERTDB_FAILED;
+ SECStatus rv;
+ char *name = NULL;
+ char *appName = NULL;
if (prefix == NULL) {
- prefix = "";
+ prefix = "";
}
configdir = lg_EvaluateConfigDir(configdir, &appName);
- name = PR_smprintf("%s" PATH_SEPARATOR "%s",configdir,prefix);
- if (name == NULL) goto loser;
+ 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 = (NSSLOWCERTCertDBHandle *)PORT_ZAlloc(sizeof(NSSLOWCERTCertDBHandle));
+ if (certdb == NULL)
+ goto loser;
certdb->ref = 1;
-/* fix when we get the DB in */
+ /* fix when we get the DB in */
rv = nsslowcert_OpenCertDB(certdb, readOnly, appName, prefix,
- lg_certdb_name_cb, (void *)name, PR_FALSE);
+ 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);
+ 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)
+lg_OpenKeyDB(const char *configdir, const char *prefix, PRBool readOnly,
+ NSSLOWKEYDBHandle **keydbPtr)
{
NSSLOWKEYDBHandle *keydb;
- char * name = NULL;
- char * appName = NULL;
+ char *name = NULL;
+ char *appName = NULL;
if (prefix == NULL) {
- prefix = "";
+ 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);
+ 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 (appName)
+ PORT_Free(appName);
if (keydb == NULL)
- return CKR_NETSCAPE_KEYDB_FAILED;
+ return CKR_NETSCAPE_KEYDB_FAILED;
*keydbPtr = keydb;
return CKR_OK;
@@ -407,21 +411,21 @@ lg_OpenKeyDB(const char * configdir, const char *prefix, PRBool readOnly,
* Accessors for the private parts of the sdb structure.
*/
void
-lg_DBLock(SDB *sdb)
+lg_DBLock(SDB *sdb)
{
LGPrivate *lgdb_p = (LGPrivate *)sdb->private;
SKIP_AFTER_FORK(PR_Lock(lgdb_p->dbLock));
}
void
-lg_DBUnlock(SDB *sdb)
+lg_DBUnlock(SDB *sdb)
{
LGPrivate *lgdb_p = (LGPrivate *)sdb->private;
SKIP_AFTER_FORK(PR_Unlock(lgdb_p->dbLock));
}
PLHashTable *
-lg_GetHashTable(SDB *sdb)
+lg_GetHashTable(SDB *sdb)
{
LGPrivate *lgdb_p = (LGPrivate *)sdb->private;
return lgdb_p->hashTable;
@@ -445,7 +449,8 @@ lg_getKeyDB(SDB *sdb)
PRBool lg_parentForkedAfterC_Initialize;
-void lg_SetForkState(PRBool forked)
+void
+lg_SetForkState(PRBool forked)
{
lg_parentForkedAfterC_Initialize = forked;
}
@@ -456,18 +461,18 @@ 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);
+ 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;
@@ -483,39 +488,38 @@ lg_HashNumber(const void *key)
* helper function to wrap a NSSLOWCERTCertDBHandle or a NSSLOWKEYDBHandle
* with and sdb structure.
*/
-CK_RV
+CK_RV
lg_init(SDB **pSdb, int flags, NSSLOWCERTCertDBHandle *certdbPtr,
- NSSLOWKEYDBHandle *keydbPtr)
+ NSSLOWKEYDBHandle *keydbPtr)
{
SDB *sdb = NULL;
LGPrivate *lgdb_p = NULL;
CK_RV error = CKR_HOST_MEMORY;
*pSdb = NULL;
- sdb = (SDB *) PORT_Alloc(sizeof(SDB));
+ sdb = (SDB *)PORT_Alloc(sizeof(SDB));
if (sdb == NULL) {
- goto loser;
+ goto loser;
}
- lgdb_p = (LGPrivate *) PORT_Alloc(sizeof(LGPrivate));
+ lgdb_p = (LGPrivate *)PORT_Alloc(sizeof(LGPrivate));
if (lgdb_p == NULL) {
- goto loser;
+ goto loser;
}
/* invariant fields */
lgdb_p->certDB = certdbPtr;
lgdb_p->keyDB = keydbPtr;
lgdb_p->dbLock = PR_NewLock();
if (lgdb_p->dbLock == NULL) {
- goto loser;
+ goto loser;
}
lgdb_p->hashTable = PL_NewHashTable(64, lg_HashNumber, PL_CompareValues,
- SECITEM_HashCompare, NULL, 0);
+ SECITEM_HashCompare, NULL, 0);
if (lgdb_p->hashTable == NULL) {
- goto loser;
+ 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;
@@ -539,19 +543,18 @@ lg_init(SDB **pSdb, int flags, NSSLOWCERTCertDBHandle *certdbPtr,
loser:
if (sdb) {
- PORT_Free(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);
+ if (lgdb_p->dbLock) {
+ PR_DestroyLock(lgdb_p->dbLock);
+ }
+ if (lgdb_p->hashTable) {
+ PL_HashTableDestroy(lgdb_p->hashTable);
+ }
+ PORT_Free(lgdb_p);
}
return error;
-
}
/*
@@ -559,80 +562,88 @@ loser:
*
* 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-"
+ * "https-server1-"
* keyPrefix - prefix added to the beginning of the key database example: "
- * "https-server1-"
+ * "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.
+ * 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.
+ * 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)
+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;
+ PRBool readOnly = ((flags & 0x7) == SDB_RDONLY) ? PR_TRUE : PR_FALSE;
#define NSS_VERSION_VARIABLE __nss_dbm_version
#include "verref.h"
+ if (flags & SDB_FIPS) {
+ if (!lg_FIPSEntryOK()) {
+ return CKR_DEVICE_ERROR;
+ }
+ }
+
rv = SECOID_Init();
if (SECSuccess != rv) {
return CKR_DEVICE_ERROR;
}
nsslowcert_InitLocks();
- if (keyDB) *keyDB = NULL;
- if (certDB) *certDB = NULL;
+ if (keyDB)
+ *keyDB = NULL;
+ if (certDB)
+ *certDB = NULL;
if (certDB) {
- NSSLOWCERTCertDBHandle *certdbPtr = NULL;
-
- 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;
- }
+ NSSLOWCERTCertDBHandle *certdbPtr = NULL;
+
+ 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;
- }
+ 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;
- }
+ if (keyDB && *keyDB) {
+ lg_Close(*keyDB);
+ *keyDB = NULL;
+ }
+ if (certDB && *certDB) {
+ lg_Close(*certDB);
+ *certDB = NULL;
+ }
}
return crv;
}
@@ -647,4 +658,3 @@ legacy_Shutdown(PRBool forked)
lg_SetForkState(PR_FALSE);
return CKR_OK;
}
-
diff --git a/nss/lib/softoken/legacydb/lgutil.c b/nss/lib/softoken/legacydb/lgutil.c
index 1b45bb0..d872bf4 100644
--- a/nss/lib/softoken/legacydb/lgutil.c
+++ b/nss/lib/softoken/legacydb/lgutil.c
@@ -11,98 +11,100 @@
/*
* look up and attribute structure from a type and Object structure.
- * The returned attribute is referenced and needs to be freed when
+ * 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 )
+ CK_ULONG count)
{
unsigned int i;
- for (i=0; i < count; i++) {
- if (templ[i].type == type) {
- return &templ[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 )
+ CK_ULONG count)
{
- if (lg_FindAttribute(type, templ, count) == NULL) {
- return PR_FALSE;
- }
- return PR_TRUE;
+ 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)
+ 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;
+ if (attribute == NULL)
+ return CKR_TEMPLATE_INCOMPLETE;
len = attribute->ulValueLen;
if (arena) {
- item->data = (unsigned char *) PORT_ArenaAlloc(arena,len);
+ item->data = (unsigned char *)PORT_ArenaAlloc(arena, len);
} else {
- item->data = (unsigned char *) PORT_Alloc(len);
+ item->data = (unsigned char *)PORT_Alloc(len);
}
if (item->data == NULL) {
- return CKR_HOST_MEMORY;
+ return CKR_HOST_MEMORY;
}
item->len = len;
- PORT_Memcpy(item->data, attribute->pValue, len);
+ if (item->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 *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;
+ if (attribute == NULL)
+ return CKR_TEMPLATE_INCOMPLETE;
(void)SECITEM_AllocItem(arena, item, attribute->ulValueLen);
if (item->data == NULL) {
- return CKR_HOST_MEMORY;
+ 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 *templ, CK_ULONG count,
+ SECItem *item, SDB *sdbpw)
{
const CK_ATTRIBUTE *attribute;
SECItem epki, *dest = NULL;
@@ -111,21 +113,22 @@ lg_PrivAttr2SSecItem(PLArenaPool *arena, CK_ATTRIBUTE_TYPE type,
item->data = NULL;
attribute = lg_FindAttribute(type, templ, count);
- if (attribute == NULL) return CKR_TEMPLATE_INCOMPLETE;
+ 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;
+ 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;
+ 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;
@@ -133,8 +136,8 @@ lg_PrivAttr2SSecItem(PLArenaPool *arena, CK_ATTRIBUTE_TYPE type,
CK_RV
lg_PrivAttr2SecItem(PLArenaPool *arena, CK_ATTRIBUTE_TYPE type,
- const CK_ATTRIBUTE *templ, CK_ULONG count,
- SECItem *item, SDB *sdbpw)
+ const CK_ATTRIBUTE *templ, CK_ULONG count,
+ SECItem *item, SDB *sdbpw)
{
return lg_PrivAttr2SSecItem(arena, type, templ, count, item, sdbpw);
}
@@ -149,8 +152,10 @@ 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; }
+ attribute = lg_FindAttribute(type, templ, count);
+ if (attribute == NULL) {
+ return PR_FALSE;
+ }
tok = (PRBool)(*(CK_BBOOL *)attribute->pValue);
return tok;
@@ -167,23 +172,24 @@ lg_getString(CK_ATTRIBUTE_TYPE type, const CK_ATTRIBUTE *templ, CK_ULONG count)
char *label = NULL;
attribute = lg_FindAttribute(type, templ, count);
- if (attribute == NULL) return NULL;
+ if (attribute == NULL)
+ return NULL;
if (attribute->pValue != NULL) {
- label = (char *) PORT_Alloc(attribute->ulValueLen+1);
- if (label == NULL) {
- return NULL;
- }
+ label = (char *)PORT_Alloc(attribute->ulValueLen + 1);
+ if (label == NULL) {
+ return NULL;
+ }
- PORT_Memcpy(label,attribute->pValue, attribute->ulValueLen);
- label[attribute->ulValueLen] = 0;
+ 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)
+ CK_ULONG count, CK_ULONG *longData)
{
const CK_ATTRIBUTE *attribute;
CK_ULONG value = 0;
@@ -191,14 +197,15 @@ lg_GetULongAttribute(CK_ATTRIBUTE_TYPE type, const CK_ATTRIBUTE *templ,
int i;
attribute = lg_FindAttribute(type, templ, count);
- if (attribute == NULL) return CKR_TEMPLATE_INCOMPLETE;
+ if (attribute == NULL)
+ return CKR_TEMPLATE_INCOMPLETE;
if (attribute->ulValueLen != 4) {
- return CKR_ATTRIBUTE_VALUE_INVALID;
+ 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);
+ for (i = 0; i < 4; i++) {
+ value |= (CK_ULONG)(data[i]) << ((3 - i) * 8);
}
*longData = value;
@@ -214,12 +221,12 @@ lg_deleteTokenKeyByHandle(SDB *sdb, CK_OBJECT_HANDLE handle)
{
SECItem *item;
PRBool rem;
- PLHashTable *hashTable= lg_GetHashTable(sdb);
+ PLHashTable *hashTable = lg_GetHashTable(sdb);
item = (SECItem *)PL_HashTableLookup(hashTable, (void *)handle);
- rem = PL_HashTableRemove(hashTable,(void *)handle) ;
+ rem = PL_HashTableRemove(hashTable, (void *)handle);
if (rem && item) {
- SECITEM_FreeItem(item,PR_TRUE);
+ SECITEM_FreeItem(item, PR_TRUE);
}
return rem ? SECSuccess : SECFailure;
}
@@ -230,16 +237,16 @@ lg_addTokenKeyByHandle(SDB *sdb, CK_OBJECT_HANDLE handle, SECItem *key)
{
PLHashEntry *entry;
SECItem *item;
- PLHashTable *hashTable= lg_GetHashTable(sdb);
+ PLHashTable *hashTable = lg_GetHashTable(sdb);
item = SECITEM_DupItem(key);
if (item == NULL) {
- return SECFailure;
+ return SECFailure;
}
- entry = PL_HashTableAdd(hashTable,(void *)handle,item);
+ entry = PL_HashTableAdd(hashTable, (void *)handle, item);
if (entry == NULL) {
- SECITEM_FreeItem(item,PR_TRUE);
- return SECFailure;
+ SECITEM_FreeItem(item, PR_TRUE);
+ return SECFailure;
}
return SECSuccess;
}
@@ -248,13 +255,12 @@ lg_addTokenKeyByHandle(SDB *sdb, CK_OBJECT_HANDLE handle, SECItem *key)
const SECItem *
lg_lookupTokenKeyByHandle(SDB *sdb, CK_OBJECT_HANDLE handle)
{
- PLHashTable *hashTable= lg_GetHashTable(sdb);
+ PLHashTable *hashTable = lg_GetHashTable(sdb);
return (const SECItem *)PL_HashTableLookup(hashTable, (void *)handle);
}
-
static PRIntn
-lg_freeHashItem(PLHashEntry* entry, PRIntn index, void *arg)
+lg_freeHashItem(PLHashEntry *entry, PRIntn index, void *arg)
{
SECItem *item = (SECItem *)entry->value;
@@ -267,7 +273,7 @@ lg_ClearTokenKeyHashTable(SDB *sdb)
{
PLHashTable *hashTable;
lg_DBLock(sdb);
- hashTable= lg_GetHashTable(sdb);
+ hashTable = lg_GetHashTable(sdb);
PL_HashTableEnumerateEntries(hashTable, lg_freeHashItem, NULL);
lg_DBUnlock(sdb);
return CKR_OK;
@@ -279,16 +285,16 @@ lg_ClearTokenKeyHashTable(SDB *sdb)
static void
lg_XORHash(unsigned char *key, unsigned char *dbkey, int len)
{
- int i;
+ int i;
- PORT_Memset(key, 0, 4);
+ 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];
- }
+ 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 */
@@ -302,28 +308,28 @@ lg_mkHandle(SDB *sdb, SECItem *dbKey, CK_OBJECT_HANDLE class)
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);
+ lg_XORHash(hashBuf, dbKey->data, dbKey->len);
handle = ((CK_OBJECT_HANDLE)hashBuf[0] << 24) |
((CK_OBJECT_HANDLE)hashBuf[1] << 16) |
- ((CK_OBJECT_HANDLE)hashBuf[2] << 8) |
+ ((CK_OBJECT_HANDLE)hashBuf[2] << 8) |
(CK_OBJECT_HANDLE)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++;
- }
+ 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++;
+ while ((key = lg_lookupTokenKeyByHandle(sdb, handle)) != NULL) {
+ if (SECITEM_ItemsAreEqual(key, dbKey)) {
+ lg_DBUnlock(sdb);
+ return handle;
+ }
+ handle++;
}
- lg_addTokenKeyByHandle(sdb,handle,dbKey);
+ lg_addTokenKeyByHandle(sdb, handle, dbKey);
lg_DBUnlock(sdb);
return handle;
}
@@ -338,24 +344,24 @@ lg_poisonHandle(SDB *sdb, SECItem *dbKey, CK_OBJECT_HANDLE class)
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_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++;
+ 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;
@@ -367,27 +373,27 @@ static LGDecryptFunc lg_decrypt_stub = NULL;
void
legacy_SetCryptFunctions(LGEncryptFunc enc, LGDecryptFunc dec)
{
- lg_encrypt_stub = enc;
- lg_decrypt_stub = dec;
+ lg_encrypt_stub = enc;
+ lg_decrypt_stub = dec;
}
-SECStatus lg_util_encrypt(PLArenaPool *arena, SDB *sdb,
- SECItem *plainText, SECItem **cipherText)
+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;
+ 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)
+SECStatus
+lg_util_decrypt(SDB *sdb, SECItem *cipherText, SECItem **plainText)
{
if (lg_decrypt_stub == NULL) {
- PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
- return SECFailure;
+ PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
+ return SECFailure;
}
return (*lg_decrypt_stub)(sdb, cipherText, plainText);
}
-
-
diff --git a/nss/lib/softoken/legacydb/lowcert.c b/nss/lib/softoken/legacydb/lowcert.c
index a8191d8..2906120 100644
--- a/nss/lib/softoken/legacydb/lowcert.c
+++ b/nss/lib/softoken/legacydb/lowcert.c
@@ -20,26 +20,26 @@ 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) },
+ offsetof(NSSLOWCERTSubjectPublicKeyInfo, algorithm),
+ SEC_ASN1_SUB(SECOID_AlgorithmIDTemplate) },
{ SEC_ASN1_BIT_STRING,
- offsetof(NSSLOWCERTSubjectPublicKeyInfo,subjectPublicKey), },
- { 0, }
+ 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, }
+ { 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, }
+ { SEC_ASN1_INTEGER, offsetof(NSSLOWKEYPublicKey, u.dsa.publicValue) },
+ { 0 }
};
static const SEC_ASN1Template nsslowcert_DHPublicKeyTemplate[] = {
- { SEC_ASN1_INTEGER, offsetof(NSSLOWKEYPublicKey,u.dh.publicValue), },
- { 0, }
+ { SEC_ASN1_INTEGER, offsetof(NSSLOWKEYPublicKey, u.dh.publicValue) },
+ { 0 }
};
/*
@@ -77,17 +77,18 @@ prepare_low_dh_pub_key_for_asn1(NSSLOWKEYPublicKey *pubk)
/*
* 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) {
+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;
+ unsigned int used_length = 0;
/* need at least a tag and a 1 byte length */
if (length < 2) {
- return NULL;
+ return NULL;
}
tag = buf[used_length++];
@@ -98,35 +99,37 @@ nsslowcert_dataStart(unsigned char *buf, unsigned int length,
/* blow out when we come to the end */
if (tag == 0) {
- return NULL;
+ return NULL;
}
*data_length = buf[used_length++];
- if (*data_length&0x80) {
- int len_count = *data_length & 0x7f;
+ if (*data_length & 0x80) {
+ int len_count = *data_length & 0x7f;
- if (len_count+used_length > length) {
- return NULL;
- }
+ if (len_count + used_length > length) {
+ return NULL;
+ }
- *data_length = 0;
+ *data_length = 0;
- while (len_count-- > 0) {
- *data_length = (*data_length << 8) | buf[used_length++];
- }
+ 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 (*data_length > (length - used_length)) {
+ *data_length = length - used_length;
+ return NULL;
}
- if (includeTag) *data_length += used_length;
+ if (includeTag)
+ *data_length += used_length;
- return (buf + (includeTag ? 0 : used_length));
+ return (buf + (includeTag ? 0 : used_length));
}
-static void SetTimeType(SECItem* item, unsigned char tagtype)
+static void
+SetTimeType(SECItem *item, unsigned char tagtype)
{
switch (tagtype) {
case SEC_ASN1_UTC_TIME:
@@ -144,27 +147,29 @@ static void SetTimeType(SECItem* item, unsigned char tagtype)
}
static int
-nsslowcert_GetValidityFields(unsigned char *buf,int buf_length,
- SECItem *notBefore, SECItem *notAfter)
+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;
+ 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_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;
+ 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)
+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;
@@ -172,87 +177,97 @@ nsslowcert_GetCertFields(unsigned char *cert,int cert_length,
unsigned int dummylen;
/* get past the signature wrap */
- buf = nsslowcert_dataStart(cert,cert_length,&buf_length,PR_FALSE, NULL);
- if (buf == NULL) return SECFailure;
+ 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;
+ 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;
+ 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;
+ 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;
+ 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;
+ 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;
+ 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;
+ 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;
+ 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;
+ 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)
+ /* 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;
+ buf_length = extensions->len;
/* now parse the SEQUENCE holding the extensions. */
- dummy = nsslowcert_dataStart(buf,buf_length,&dummylen,PR_FALSE,NULL);
+ dummy = nsslowcert_dataStart(buf, buf_length, &dummylen, PR_FALSE, NULL);
if (dummy == NULL ||
- (dummy - buf) + dummylen != buf_length)
+ (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;
+ }
+ 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;
}
@@ -263,25 +278,25 @@ nsslowcert_GetCertTimes(NSSLOWCERTCertificate *c, PRTime *notBefore, PRTime *not
int rv;
NSSLOWCERTValidity validity;
- rv = nsslowcert_GetValidityFields(c->validity.data,c->validity.len,
- &validity.notBefore,&validity.notAfter);
+ rv = nsslowcert_GetValidityFields(c->validity.data, c->validity.len,
+ &validity.notBefore, &validity.notAfter);
if (rv != SECSuccess) {
- return rv;
+ return rv;
}
-
+
/* convert DER not-before time */
rv = DER_DecodeTimeChoice(notBefore, &validity.notBefore);
if (rv) {
- return(SECFailure);
+ return (SECFailure);
}
-
+
/* convert DER not-after time */
rv = DER_DecodeTimeChoice(notAfter, &validity.notAfter);
if (rv) {
- return(SECFailure);
+ return (SECFailure);
}
- return(SECSuccess);
+ return (SECSuccess);
}
/*
@@ -293,52 +308,52 @@ 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);
+ if (rv != SECSuccess) {
+ return (PR_FALSE);
}
-
+
rv = nsslowcert_GetCertTimes(certb, &notBeforeB, &notAfterB);
- if ( rv != SECSuccess ) {
- return(PR_TRUE);
+ if (rv != SECSuccess) {
+ return (PR_TRUE);
}
newerbefore = PR_FALSE;
- if ( LL_CMP(notBeforeA, >, notBeforeB) ) {
- newerbefore = PR_TRUE;
+ if (LL_CMP(notBeforeA, >, notBeforeB)) {
+ newerbefore = PR_TRUE;
}
newerafter = PR_FALSE;
- if ( LL_CMP(notAfterA, >, notAfterB) ) {
- newerafter = PR_TRUE;
+ if (LL_CMP(notAfterA, >, notAfterB)) {
+ newerafter = PR_TRUE;
}
-
- if ( newerbefore && newerafter ) {
- return(PR_TRUE);
+
+ if (newerbefore && newerafter) {
+ return (PR_TRUE);
}
-
- if ( ( !newerbefore ) && ( !newerafter ) ) {
- return(PR_FALSE);
+
+ 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);
+ 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);
+ /* 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);
}
}
@@ -346,21 +361,21 @@ nsslowcert_IsNewer(NSSLOWCERTCertificate *certa, NSSLOWCERTCertificate *certb)
static SECStatus
nsslowcert_KeyFromIssuerAndSN(PLArenaPool *arena,
- SECItem *issuer, SECItem *sn, SECItem *key)
+ SECItem *issuer, SECItem *sn, SECItem *key)
{
unsigned int len = sn->len + issuer->len;
if (!arena) {
PORT_SetError(SEC_ERROR_INVALID_ARGS);
- goto loser;
+ goto loser;
}
if (len > NSS_MAX_LEGACY_DB_KEY_SIZE) {
- PORT_SetError(SEC_ERROR_INPUT_LEN);
- goto loser;
+ PORT_SetError(SEC_ERROR_INPUT_LEN);
+ goto loser;
}
- key->data = (unsigned char*)PORT_ArenaAlloc(arena, len);
- if ( !key->data ) {
- goto loser;
+ key->data = (unsigned char *)PORT_ArenaAlloc(arena, len);
+ if (!key->data) {
+ goto loser;
}
key->len = len;
@@ -370,21 +385,21 @@ nsslowcert_KeyFromIssuerAndSN(PLArenaPool *arena,
/* copy the issuer */
PORT_Memcpy(&key->data[sn->len], issuer->data, issuer->len);
- return(SECSuccess);
+ return (SECSuccess);
loser:
- return(SECFailure);
+ return (SECFailure);
}
static SECStatus
nsslowcert_KeyFromIssuerAndSNStatic(unsigned char *space,
- int spaceLen, SECItem *issuer, SECItem *sn, SECItem *key)
+ 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;
+ if (!key->data) {
+ goto loser;
}
key->len = len;
@@ -394,13 +409,12 @@ nsslowcert_KeyFromIssuerAndSNStatic(unsigned char *space,
/* copy the issuer */
PORT_Memcpy(&key->data[sn->len], issuer->data, issuer->len);
- return(SECSuccess);
+ return (SECSuccess);
loser:
- return(SECFailure);
+ return (SECFailure);
}
-
static char *
nsslowcert_EmailName(SECItem *derDN, char *space, unsigned int len)
{
@@ -408,161 +422,178 @@ nsslowcert_EmailName(SECItem *derDN, char *space, unsigned int len)
unsigned int buf_length;
/* unwrap outer sequence */
- buf=nsslowcert_dataStart(derDN->data,derDN->len,&buf_length,PR_FALSE,NULL);
- if (buf == NULL) return NULL;
+ 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 (name == 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;
- }
- }
+ 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 (name == 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)
+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);
+ &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;
+ 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;
}
@@ -573,23 +604,21 @@ nsslowcert_GetCertificateEmailAddress(NSSLOWCERTCertificate *cert)
char *emailAddr = NULL;
char *str;
- emailAddr = nsslowcert_EmailName(&cert->derSubject,cert->emailAddrSpace,
- sizeof(cert->emailAddrSpace));
+ 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));
+ emailAddr = nsslowcert_EmailAltName(cert, cert->emailAddrSpace,
+ sizeof(cert->emailAddrSpace));
}
-
/* make it lower case */
str = emailAddr;
- while ( str && *str ) {
- *str = tolower( *str );
- str++;
+ while (str && *str) {
+ *str = tolower(*str);
+ str++;
}
return emailAddr;
-
}
/*
@@ -603,12 +632,12 @@ nsslowcert_DecodeDERCertificate(SECItem *derSignedCert, char *nickname)
/* allocate the certificate structure */
cert = nsslowcert_CreateCert();
-
- if ( !cert ) {
- goto loser;
+
+ if (!cert) {
+ goto loser;
}
-
- /* point to passed in DER data */
+
+ /* point to passed in DER data */
cert->derCert = *derSignedCert;
cert->nickname = NULL;
cert->certKey.data = NULL;
@@ -616,59 +645,58 @@ nsslowcert_DecodeDERCertificate(SECItem *derSignedCert, char *nickname)
/* 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);
+ &cert->derIssuer, &cert->serialNumber, &cert->derSN, &cert->derSubject,
+ &cert->validity, &cert->derSubjKeyInfo, &cert->extensions);
if (rv != SECSuccess) {
- goto loser;
+ goto loser;
}
- /* cert->subjectKeyID; x509v3 subject key identifier */
+ /* cert->subjectKeyID; x509v3 subject key identifier */
cert->subjectKeyID.data = NULL;
cert->subjectKeyID.len = 0;
cert->dbEntry = NULL;
- cert ->trust = NULL;
- cert ->dbhandle = 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;
+ sizeof(cert->certKeySpace), &cert->derIssuer,
+ &cert->serialNumber, &cert->certKey);
+ if (rv) {
+ goto loser;
}
/* set the nickname */
- if ( nickname == NULL ) {
- cert->nickname = NULL;
+ if (nickname == NULL) {
+ cert->nickname = NULL;
} else {
- /* copy and install the nickname */
- cert->nickname = pkcs11_copyNickname(nickname,cert->nicknameSpace,
- sizeof(cert->nicknameSpace));
+ /* 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;
+ if (rv != SECSuccess) {
+ goto loser;
}
#endif
/* set the email address */
cert->emailAddr = nsslowcert_GetCertificateEmailAddress(cert);
-
-
+
cert->referenceCount = 1;
-
- return(cert);
-
+
+ return (cert);
+
loser:
if (cert) {
- nsslowcert_DestroyCertificate(cert);
+ nsslowcert_DestroyCertificate(cert);
}
-
- return(0);
+
+ return (0);
}
char *
@@ -677,25 +705,24 @@ nsslowcert_FixupEmailAddr(char *emailAddr)
char *retaddr;
char *str;
- if ( emailAddr == NULL ) {
- return(NULL);
+ if (emailAddr == NULL) {
+ return (NULL);
}
-
+
/* copy the string */
str = retaddr = PORT_Strdup(emailAddr);
- if ( str == NULL ) {
- return(NULL);
+ if (str == NULL) {
+ return (NULL);
}
-
+
/* make it lower case */
- while ( *str ) {
- *str = tolower( *str );
- str++;
+ while (*str) {
+ *str = tolower(*str);
+ str++;
}
-
- return(retaddr);
-}
+ return (retaddr);
+}
/*
* Generate a database key, based on serial number and issuer, from a
@@ -707,20 +734,20 @@ nsslowcert_KeyFromDERCert(PLArenaPool *arena, SECItem *derCert, SECItem *key)
int rv;
NSSLOWCERTCertKey certkey;
- PORT_Memset(&certkey, 0, sizeof(NSSLOWCERTCertKey));
+ PORT_Memset(&certkey, 0, sizeof(NSSLOWCERTCertKey));
rv = nsslowcert_GetCertFields(derCert->data, derCert->len,
- &certkey.derIssuer, &certkey.serialNumber, NULL, NULL,
- NULL, NULL, NULL);
+ &certkey.derIssuer, &certkey.serialNumber, NULL, NULL,
+ NULL, NULL, NULL);
- if ( rv ) {
- goto loser;
+ if (rv) {
+ goto loser;
}
- return(nsslowcert_KeyFromIssuerAndSN(arena, &certkey.derIssuer,
- &certkey.serialNumber, key));
+ return (nsslowcert_KeyFromIssuerAndSN(arena, &certkey.derIssuer,
+ &certkey.serialNumber, key));
loser:
- return(SECFailure);
+ return (SECFailure);
}
NSSLOWKEYPublicKey *
@@ -734,93 +761,96 @@ nsslowcert_ExtractPublicKey(NSSLOWCERTCertificate *cert)
SECOidTag tag;
SECItem newDerSubjKeyInfo;
- arena = PORT_NewArena (DER_DEFAULT_CHUNKSIZE);
+ arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
if (arena == NULL)
return NULL;
- pubk = (NSSLOWKEYPublicKey *)
- PORT_ArenaZAlloc(arena, sizeof(NSSLOWKEYPublicKey));
+ pubk = (NSSLOWKEYPublicKey *)
+ PORT_ArenaZAlloc(arena, sizeof(NSSLOWKEYPublicKey));
if (pubk == NULL) {
- PORT_FreeArena (arena, PR_FALSE);
+ PORT_FreeArena(arena, PR_FALSE);
return NULL;
}
pubk->arena = arena;
- PORT_Memset(&spki,0,sizeof(spki));
+ 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);
+ 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);
+ rv = SEC_QuickDERDecodeItem(arena, &spki,
+ nsslowcert_SubjectPublicKeyInfoTemplate, &newDerSubjKeyInfo);
if (rv != SECSuccess) {
- PORT_FreeArena (arena, PR_FALSE);
- return NULL;
+ PORT_FreeArena(arena, PR_FALSE);
+ return NULL;
}
/* Convert bit string length from bits to bytes */
os = spki.subjectPublicKey;
- DER_ConvertBitString (&os);
+ 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;
+ switch (tag) {
+ case SEC_OID_X500_RSA_ENCRYPTION:
+ case SEC_OID_PKCS1_RSA_ENCRYPTION:
+ case SEC_OID_PKCS1_RSA_PSS_SIGNATURE:
+ 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;
#ifndef NSS_DISABLE_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;
+ 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_DISABLE_ECC */
- default:
- rv = SECFailure;
- break;
+ default:
+ rv = SECFailure;
+ break;
}
- lg_nsslowkey_DestroyPublicKey (pubk);
+ lg_nsslowkey_DestroyPublicKey(pubk);
return NULL;
}
-
diff --git a/nss/lib/softoken/legacydb/lowkey.c b/nss/lib/softoken/legacydb/lowkey.c
index 7521dac..7de4197 100644
--- a/nss/lib/softoken/legacydb/lowkey.c
+++ b/nss/lib/softoken/legacydb/lowkey.c
@@ -1,12 +1,12 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.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 "lowkeyi.h"
+#include "secoid.h"
#include "secitem.h"
-#include "secder.h"
+#include "secder.h"
#include "secasn1.h"
-#include "secerr.h"
+#include "secerr.h"
SEC_ASN1_MKSUB(SEC_AnyTemplate)
SEC_ASN1_MKSUB(SEC_BitStringTemplate)
@@ -14,11 +14,11 @@ 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_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) },
+ { SEC_ASN1_SET_OF | SEC_ASN1_XTRN, offsetof(NSSLOWKEYAttribute, attrValue),
+ SEC_ASN1_SUB(SEC_AnyTemplate) },
{ 0 }
};
@@ -28,41 +28,41 @@ static const SEC_ASN1Template nsslowkey_SetOfAttributeTemplate[] = {
/* ASN1 Templates for new decoder/encoder */
const SEC_ASN1Template lg_nsslowkey_PrivateKeyInfoTemplate[] = {
{ SEC_ASN1_SEQUENCE,
- 0, NULL, sizeof(NSSLOWKEYPrivateKeyInfo) },
+ 0, NULL, sizeof(NSSLOWKEYPrivateKeyInfo) },
{ SEC_ASN1_INTEGER,
- offsetof(NSSLOWKEYPrivateKeyInfo,version) },
+ offsetof(NSSLOWKEYPrivateKeyInfo, version) },
{ SEC_ASN1_INLINE | SEC_ASN1_XTRN,
- offsetof(NSSLOWKEYPrivateKeyInfo,algorithm),
- SEC_ASN1_SUB(SECOID_AlgorithmIDTemplate) },
+ offsetof(NSSLOWKEYPrivateKeyInfo, algorithm),
+ SEC_ASN1_SUB(SECOID_AlgorithmIDTemplate) },
{ SEC_ASN1_OCTET_STRING,
- offsetof(NSSLOWKEYPrivateKeyInfo,privateKey) },
+ offsetof(NSSLOWKEYPrivateKeyInfo, privateKey) },
{ SEC_ASN1_OPTIONAL | SEC_ASN1_CONSTRUCTED | SEC_ASN1_CONTEXT_SPECIFIC | 0,
- offsetof(NSSLOWKEYPrivateKeyInfo, attributes),
- nsslowkey_SetOfAttributeTemplate },
+ 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, }
+ { 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 }
-};
+ { 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
@@ -71,49 +71,36 @@ const SEC_ASN1Template lg_nsslowkey_RSAPrivateKeyTemplate[] = {
*/
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) },
+ { 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, }
+ { 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, }
+ { 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 }
};
#ifndef NSS_DISABLE_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
@@ -121,51 +108,41 @@ const SEC_ASN1Template lg_nsslowkey_ECParamsTemplate[] = {
*/
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
+ { SEC_ASN1_INTEGER, offsetof(NSSLOWKEYPrivateKey, u.ec.version) },
+ { SEC_ASN1_OCTET_STRING,
+ offsetof(NSSLOWKEYPrivateKey, u.ec.privateValue) },
+ /* We only support named curves for which the parameters are
+ * encoded as an object ID.
*/
-#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_EXPLICIT | SEC_ASN1_CONTEXT_SPECIFIC | SEC_ASN1_XTRN | 0,
+ offsetof(NSSLOWKEYPrivateKey, u.ec.ecParams.curveOID),
+ SEC_ASN1_SUB(SEC_ObjectIDTemplate) },
{ 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, }
+ 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(PLArenaPool *arena, const SECItem *encodedParams,
- ECParams *params)
+ ECParams *params)
{
SECOidTag tag;
- SECItem oid = { siBuffer, NULL, 0};
+ 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("%02x:", encodedParams->data[i]);
}
printf("\n");
#endif
@@ -173,18 +150,18 @@ LGEC_FillParams(PLArenaPool *arena, const SECItem *encodedParams,
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;
+ ((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;
+ 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);
@@ -195,20 +172,20 @@ LGEC_FillParams(PLArenaPool *arena, const SECItem *encodedParams,
*/
SECStatus
LGEC_CopyParams(PLArenaPool *arena, ECParams *dstParams,
- const ECParams *srcParams)
+ const ECParams *srcParams)
{
SECStatus rv = SECFailure;
dstParams->arena = arena;
rv = SECITEM_CopyItem(arena, &dstParams->DEREncoding,
- &srcParams->DEREncoding);
+ &srcParams->DEREncoding);
if (rv != SECSuccess) {
- goto loser;
+ goto loser;
}
- rv =SECITEM_CopyItem(arena, &dstParams->curveOID,
- &srcParams->curveOID);
+ rv = SECITEM_CopyItem(arena, &dstParams->curveOID,
+ &srcParams->curveOID);
if (rv != SECSuccess) {
- goto loser;
+ goto loser;
}
return SECSuccess;
@@ -289,7 +266,7 @@ void
lg_nsslowkey_DestroyPrivateKey(NSSLOWKEYPrivateKey *privk)
{
if (privk && privk->arena) {
- PORT_FreeArena(privk->arena, PR_TRUE);
+ PORT_FreeArena(privk->arena, PR_TRUE);
}
}
@@ -297,7 +274,7 @@ void
lg_nsslowkey_DestroyPublicKey(NSSLOWKEYPublicKey *pubk)
{
if (pubk && pubk->arena) {
- PORT_FreeArena(pubk->arena, PR_FALSE);
+ PORT_FreeArena(pubk->arena, PR_FALSE);
}
}
@@ -307,104 +284,112 @@ lg_nsslowkey_ConvertToPublicKey(NSSLOWKEYPrivateKey *privk)
NSSLOWKEYPublicKey *pubk;
PLArenaPool *arena;
-
- arena = PORT_NewArena (DER_DEFAULT_CHUNKSIZE);
+ arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
if (arena == NULL) {
- PORT_SetError (SEC_ERROR_NO_MEMORY);
+ 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;
+ 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;
#ifndef NSS_DISABLE_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;
+ 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_DISABLE_ECC */
- /* No Fortezza in Low Key implementations (Fortezza keys aren't
- * stored in our data base */
- default:
- break;
+ /* No Fortezza in Low Key implementations (Fortezza keys aren't
+ * stored in our data base */
+ default:
+ break;
}
- PORT_FreeArena (arena, PR_FALSE);
+ PORT_FreeArena(arena, PR_FALSE);
return NULL;
}
-
diff --git a/nss/lib/softoken/legacydb/lowkeyi.h b/nss/lib/softoken/legacydb/lowkeyi.h
index 6739888..5136b56 100644
--- a/nss/lib/softoken/legacydb/lowkeyi.h
+++ b/nss/lib/softoken/legacydb/lowkeyi.h
@@ -10,7 +10,7 @@
#include "secoidt.h"
#include "pcertt.h"
#include "lowkeyti.h"
-#include "sdb.h"
+#include "sdb.h"
SEC_BEGIN_PROTOS
@@ -31,16 +31,16 @@ extern void lg_prepare_low_ec_priv_key_for_asn1(NSSLOWKEYPrivateKey *key);
extern void lg_prepare_low_ecparams_for_asn1(ECParams *params);
#endif /* NSS_DISABLE_ECC */
-typedef char * (* NSSLOWKEYDBNameFunc)(void *arg, int dbVersion);
-
+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);
+ const char *domain,
+ const char *prefix,
+ NSSLOWKEYDBNameFunc namecb,
+ void *cbarg);
/*
** Close the specified key database.
@@ -55,55 +55,54 @@ extern int nsslowkey_GetKeyDBVersion(NSSLOWKEYDBHandle *handle);
/*
** Delete a key from the database
*/
-extern SECStatus nsslowkey_DeleteKey(NSSLOWKEYDBHandle *handle,
- const SECItem *pubkey);
+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
+** "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);
+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);
+ 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
+** "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
+** "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);
-
+extern NSSLOWKEYPublicKey
+ *
+ lg_nsslowkey_ConvertToPublicKey(NSSLOWKEYPrivateKey *privateKey);
SECStatus
nsslowkey_UpdateNickname(NSSLOWKEYDBHandle *handle,
- NSSLOWKEYPrivateKey *privkey,
- SECItem *pubKeyData,
- char *nickname,
- SDB *sdb);
+ 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,
@@ -113,27 +112,27 @@ nsslowkey_UpdateNickname(NSSLOWKEYDBHandle *handle,
* 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);
+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
+ * 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);
+nsslowkey_FindKeyByPublicKey(NSSLOWKEYDBHandle *handle, SECItem *modulus,
+ SDB *sdb);
extern char *
nsslowkey_FindKeyNicknameByPublicKey(NSSLOWKEYDBHandle *handle,
- SECItem *modulus, SDB *sdb);
+ SECItem *modulus, SDB *sdb);
#ifndef NSS_DISABLE_ECC
/*
@@ -141,11 +140,11 @@ nsslowkey_FindKeyNicknameByPublicKey(NSSLOWKEYDBHandle *handle,
* oid and DER data.
*/
SECStatus LGEC_FillParams(PLArenaPool *arena, const SECItem *encodedParams,
- ECParams *params);
+ ECParams *params);
/* Copy all of the fields from srcParams into dstParams */
SECStatus LGEC_CopyParams(PLArenaPool *arena, ECParams *dstParams,
- const ECParams *srcParams);
+ const ECParams *srcParams);
#endif
SEC_END_PROTOS
diff --git a/nss/lib/softoken/legacydb/lowkeyti.h b/nss/lib/softoken/legacydb/lowkeyti.h
index 47fff7d..ef92689 100644
--- a/nss/lib/softoken/legacydb/lowkeyti.h
+++ b/nss/lib/softoken/legacydb/lowkeyti.h
@@ -11,7 +11,6 @@
#include "secasn1t.h"
#include "secoidt.h"
-
/*
* a key in/for the data base
*/
@@ -32,7 +31,7 @@ typedef struct NSSLOWKEYDBHandleStr NSSLOWKEYDBHandle;
#define NSSLOWKEY_DB_FILE_VERSION 3
#endif
-#define NSSLOWKEY_VERSION 0 /* what we *create* */
+#define NSSLOWKEY_VERSION 0 /* what we *create* */
/*
** Typedef for callback to get a password "key".
@@ -44,8 +43,7 @@ extern const SEC_ASN1Template lg_nsslowkey_DSAPrivateKeyTemplate[];
extern const SEC_ASN1Template lg_nsslowkey_DHPrivateKeyTemplate[];
extern const SEC_ASN1Template lg_nsslowkey_DHPrivateKeyExportTemplate[];
#ifndef NSS_DISABLE_ECC
-#define NSSLOWKEY_EC_PRIVATE_KEY_VERSION 1 /* as per SECG 1 C.4 */
-extern const SEC_ASN1Template lg_nsslowkey_ECParamsTemplate[];
+#define NSSLOWKEY_EC_PRIVATE_KEY_VERSION 1 /* as per SECG 1 C.4 */
extern const SEC_ASN1Template lg_nsslowkey_ECPrivateKeyTemplate[];
#endif /* NSS_DISABLE_ECC */
@@ -72,7 +70,7 @@ struct NSSLOWKEYPrivateKeyInfoStr {
NSSLOWKEYAttribute **attributes;
};
typedef struct NSSLOWKEYPrivateKeyInfoStr NSSLOWKEYPrivateKeyInfo;
-#define NSSLOWKEY_PRIVATE_KEY_INFO_VERSION 0 /* what we *create* */
+#define NSSLOWKEY_PRIVATE_KEY_INFO_VERSION 0 /* what we *create* */
/*
** A PKCS#8 private key info object
@@ -84,11 +82,10 @@ struct NSSLOWKEYEncryptedPrivateKeyInfoStr {
};
typedef struct NSSLOWKEYEncryptedPrivateKeyInfoStr NSSLOWKEYEncryptedPrivateKeyInfo;
-
-typedef enum {
- NSSLOWKEYNullKey = 0,
- NSSLOWKEYRSAKey = 1,
- NSSLOWKEYDSAKey = 2,
+typedef enum {
+ NSSLOWKEYNullKey = 0,
+ NSSLOWKEYRSAKey = 1,
+ NSSLOWKEYDSAKey = 2,
NSSLOWKEYDHKey = 4,
NSSLOWKEYECKey = 5
} NSSLOWKEYType;
@@ -98,12 +95,12 @@ typedef enum {
*/
struct NSSLOWKEYPublicKeyStr {
PLArenaPool *arena;
- NSSLOWKEYType keyType ;
+ NSSLOWKEYType keyType;
union {
RSAPublicKey rsa;
- DSAPublicKey dsa;
- DHPublicKey dh;
- ECPublicKey ec;
+ DSAPublicKey dsa;
+ DHPublicKey dh;
+ ECPublicKey ec;
} u;
};
typedef struct NSSLOWKEYPublicKeyStr NSSLOWKEYPublicKey;
@@ -118,14 +115,13 @@ struct NSSLOWKEYPrivateKeyStr {
NSSLOWKEYType keyType;
union {
RSAPrivateKey rsa;
- DSAPrivateKey dsa;
- DHPrivateKey dh;
- ECPrivateKey ec;
+ DSAPrivateKey dsa;
+ DHPrivateKey dh;
+ ECPrivateKey ec;
} u;
};
typedef struct NSSLOWKEYPrivateKeyStr NSSLOWKEYPrivateKey;
-
typedef struct NSSLOWKEYPasswordEntryStr NSSLOWKEYPasswordEntry;
struct NSSLOWKEYPasswordEntryStr {
SECItem salt;
@@ -133,5 +129,4 @@ struct NSSLOWKEYPasswordEntryStr {
unsigned char data[128];
};
-
-#endif /* _LOWKEYTI_H_ */
+#endif /* _LOWKEYTI_H_ */
diff --git a/nss/lib/softoken/legacydb/manifest.mn b/nss/lib/softoken/legacydb/manifest.mn
index b0d3eef..9cce849 100644
--- a/nss/lib/softoken/legacydb/manifest.mn
+++ b/nss/lib/softoken/legacydb/manifest.mn
@@ -1,4 +1,4 @@
-#
+#
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
@@ -6,13 +6,13 @@ CORE_DEPTH = ../../..
MODULE = nss
-REQUIRES = dbm
+REQUIRES = dbm
LIBRARY_NAME = nssdbm
LIBRARY_VERSION = 3
MAPFILE = $(OBJDIR)/nssdbm.def
-DEFINES += -DSHLIB_SUFFIX=\"$(DLL_SUFFIX)\" -DSHLIB_PREFIX=\"$(DLL_PREFIX)\"
+DEFINES += -DSHLIB_SUFFIX=\"$(DLL_SUFFIX)\" -DSHLIB_PREFIX=\"$(DLL_PREFIX)\" -DLG_LIB_NAME=\"$(notdir $(SHARED_LIBRARY))\"
CSRCS = \
dbmshim.c \
@@ -21,6 +21,7 @@ CSRCS = \
lgcreate.c \
lgdestroy.c \
lgfind.c \
+ lgfips.c \
lginit.c \
lgutil.c \
lowcert.c \
diff --git a/nss/lib/softoken/legacydb/nssdbm.def b/nss/lib/softoken/legacydb/nssdbm.def
index e4dc6f2..dd6d5fa 100644
--- a/nss/lib/softoken/legacydb/nssdbm.def
+++ b/nss/lib/softoken/legacydb/nssdbm.def
@@ -5,13 +5,13 @@
;+#
;+# 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
+;+# 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.
+;+# 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.
+;+# 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 ";-"
diff --git a/nss/lib/softoken/legacydb/pcert.h b/nss/lib/softoken/legacydb/pcert.h
index 9d23cfc..d4be3f9 100644
--- a/nss/lib/softoken/legacydb/pcert.h
+++ b/nss/lib/softoken/legacydb/pcert.h
@@ -9,7 +9,7 @@
#include "prlong.h"
#include "pcertt.h"
-#include "lowkeyti.h" /* for struct NSSLOWKEYPublicKeyStr */
+#include "lowkeyti.h" /* for struct NSSLOWKEYPublicKeyStr */
SEC_BEGIN_PROTOS
@@ -20,51 +20,51 @@ 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
+** "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_AddPermCert(NSSLOWCERTCertDBHandle *handle,
+ NSSLOWCERTCertificate *cert,
+ char *nickname, NSSLOWCERTCertTrust *trust);
SECStatus nsslowcert_AddPermNickname(NSSLOWCERTCertDBHandle *dbhandle,
- NSSLOWCERTCertificate *cert, char *nickname);
+ NSSLOWCERTCertificate *cert, char *nickname);
SECStatus nsslowcert_DeletePermCertificate(NSSLOWCERTCertificate *cert);
-typedef SECStatus (PR_CALLBACK * PermCertCallback)(NSSLOWCERTCertificate *cert,
- SECItem *k, void *pdata);
+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"
+** "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 );
+ PermCertCallback certfunc,
+ void *udata);
PRBool
nsslowcert_CertDBKeyConflict(SECItem *derCert, NSSLOWCERTCertDBHandle *handle);
certDBEntryRevocation *
nsslowcert_FindCrlByKey(NSSLOWCERTCertDBHandle *handle,
- SECItem *crlKey, PRBool isKRL);
+ SECItem *crlKey, PRBool isKRL);
SECStatus
-nsslowcert_DeletePermCRL(NSSLOWCERTCertDBHandle *handle,const SECItem *derName,
- PRBool isKRL);
+nsslowcert_DeletePermCRL(NSSLOWCERTCertDBHandle *handle, const SECItem *derName,
+ PRBool isKRL);
SECStatus
-nsslowcert_AddCrl(NSSLOWCERTCertDBHandle *handle, SECItem *derCrl ,
- SECItem *derKey, char *url, PRBool isKRL);
+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);
+ char *nickname, PRBool isperm, PRBool copyDER);
NSSLOWCERTCertificate *
nsslowcert_DupCertificate(NSSLOWCERTCertificate *cert);
void nsslowcert_DestroyCertificate(NSSLOWCERTCertificate *cert);
@@ -72,7 +72,7 @@ void nsslowcert_DestroyTrust(NSSLOWCERTTrust *Trust);
/*
* Lookup a certificate in the databases without locking
- * "certKey" is the database key to look for
+ * "certKey" is the database key to look for
*
* XXX - this should be internal, but pkcs 11 needs to call it during a
* traversal.
@@ -82,7 +82,7 @@ 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
+ * "certKey" is the database key to look for
*
* XXX - this should be internal, but pkcs 11 needs to call it during a
* traversal.
@@ -93,22 +93,22 @@ 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
+** "issuerAndSN" is the issuer and serial number to look for
*/
extern NSSLOWCERTCertificate *
-nsslowcert_FindCertByIssuerAndSN (NSSLOWCERTCertDBHandle *handle, NSSLOWCERTIssuerAndSN *issuerAndSN);
+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
+** "issuerAndSN" is the issuer and serial number to look for
*/
extern NSSLOWCERTTrust *
-nsslowcert_FindTrustByIssuerAndSN (NSSLOWCERTCertDBHandle *handle, NSSLOWCERTIssuerAndSN *issuerAndSN);
+nsslowcert_FindTrustByIssuerAndSN(NSSLOWCERTCertDBHandle *handle, NSSLOWCERTIssuerAndSN *issuerAndSN);
/*
** Find a certificate in the database by a DER encoded certificate
-** "derCert" is the DER encoded certificate
+** "derCert" is the DER encoded certificate
*/
extern NSSLOWCERTCertificate *
nsslowcert_FindCertByDERCert(NSSLOWCERTCertDBHandle *handle, SECItem *derCert);
@@ -125,21 +125,21 @@ char *nsslowcert_FixupEmailAddr(char *emailAddr);
** then a temporary nickname is generated.
*/
extern NSSLOWCERTCertificate *
-nsslowcert_DecodeDERCertificate (SECItem *derSignedCert, char *nickname);
+nsslowcert_DecodeDERCertificate(SECItem *derSignedCert, char *nickname);
SECStatus
nsslowcert_KeyFromDERCert(PLArenaPool *arena, SECItem *derCert, SECItem *key);
certDBEntrySMime *
nsslowcert_ReadDBSMimeEntry(NSSLOWCERTCertDBHandle *certHandle,
- char *emailAddr);
+ 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);
+ const char *domain, const char *prefix,
+ NSSLOWCERTDBNameFunc namecb, void *cbarg, PRBool openVolatile);
void
nsslowcert_ClosePermCertDB(NSSLOWCERTCertDBHandle *handle);
@@ -150,42 +150,41 @@ nsslowcert_ClosePermCertDB(NSSLOWCERTCertDBHandle *handle);
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 );
+ 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);
+ SECItem *derSubject,
+ NSSLOWCERTCertCallback cb, void *cbarg);
int
nsslowcert_NumPermCertsForSubject(NSSLOWCERTCertDBHandle *handle,
- SECItem *derSubject);
+ SECItem *derSubject);
SECStatus
nsslowcert_TraversePermCertsForNickname(NSSLOWCERTCertDBHandle *handle,
- char *nickname, NSSLOWCERTCertCallback cb, void *cbarg);
+ char *nickname, NSSLOWCERTCertCallback cb, void *cbarg);
int
-nsslowcert_NumPermCertsForNickname(NSSLOWCERTCertDBHandle *handle,
- char *nickname);
+nsslowcert_NumPermCertsForNickname(NSSLOWCERTCertDBHandle *handle,
+ char *nickname);
SECStatus
nsslowcert_GetCertTrust(NSSLOWCERTCertificate *cert,
- NSSLOWCERTCertTrust *trust);
+ NSSLOWCERTCertTrust *trust);
SECStatus
-nsslowcert_SaveSMimeProfile(NSSLOWCERTCertDBHandle *dbhandle, char *emailAddr,
- SECItem *derSubject, SECItem *emailProfile, SECItem *profileTime);
+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);
+nsslowcert_ChangeCertTrust(NSSLOWCERTCertDBHandle *handle,
+ NSSLOWCERTCertificate *cert, NSSLOWCERTCertTrust *trust);
PRBool
nsslowcert_needDBVerify(NSSLOWCERTCertDBHandle *handle);
@@ -216,14 +215,14 @@ pkcs11_allocStaticData(int datalen, unsigned char *space, int spaceLen);
unsigned char *
pkcs11_copyStaticData(unsigned char *data, int datalen, unsigned char *space,
- int spaceLen);
+ int spaceLen);
NSSLOWCERTCertificate *
nsslowcert_CreateCert(void);
certDBEntry *
-nsslowcert_DecodeAnyDBEntry(SECItem *dbData, const SECItem *dbKey,
+nsslowcert_DecodeAnyDBEntry(SECItem *dbData, const SECItem *dbKey,
certDBEntryType entryType, void *pdata);
SEC_END_PROTOS
- #endif /* _PCERTDB_H_ */
+#endif /* _PCERTDB_H_ */
diff --git a/nss/lib/softoken/legacydb/pcertdb.c b/nss/lib/softoken/legacydb/pcertdb.c
index 418de0b..65da516 100644
--- a/nss/lib/softoken/legacydb/pcertdb.c
+++ b/nss/lib/softoken/legacydb/pcertdb.c
@@ -3,7 +3,7 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
/*
- * Permanent Certificate database handling code
+ * Permanent Certificate database handling code
*/
#include "lowkeyti.h"
#include "pcert.h"
@@ -19,15 +19,15 @@
NSSLOWCERTCertificate *
nsslowcert_FindCertByDERCertNoLocking(NSSLOWCERTCertDBHandle *handle, SECItem *derCert);
static SECStatus
-nsslowcert_UpdateSMimeProfile(NSSLOWCERTCertDBHandle *dbhandle,
- char *emailAddr, SECItem *derSubject, SECItem *emailProfile,
- SECItem *profileTime);
+nsslowcert_UpdateSMimeProfile(NSSLOWCERTCertDBHandle *dbhandle,
+ char *emailAddr, SECItem *derSubject, SECItem *emailProfile,
+ SECItem *profileTime);
static SECStatus
nsslowcert_UpdatePermCert(NSSLOWCERTCertDBHandle *dbhandle,
- NSSLOWCERTCertificate *cert, char *nickname, NSSLOWCERTCertTrust *trust);
+ NSSLOWCERTCertificate *cert, char *nickname, NSSLOWCERTCertTrust *trust);
static SECStatus
-nsslowcert_UpdateCrl(NSSLOWCERTCertDBHandle *handle, SECItem *derCrl,
- SECItem *crlKey, char *url, PRBool isKRL);
+nsslowcert_UpdateCrl(NSSLOWCERTCertDBHandle *handle, SECItem *derCrl,
+ SECItem *crlKey, char *url, PRBool isKRL);
static NSSLOWCERTCertificate *certListHead = NULL;
static NSSLOWCERTTrust *trustListHead = NULL;
@@ -52,8 +52,8 @@ void
certdb_InitDBLock(NSSLOWCERTCertDBHandle *handle)
{
if (dbLock == NULL) {
- dbLock = PZ_NewLock(nssILockCertDB);
- PORT_Assert(dbLock != NULL);
+ dbLock = PZ_NewLock(nssILockCertDB);
+ PORT_Assert(dbLock != NULL);
}
}
@@ -61,33 +61,33 @@ SECStatus
nsslowcert_InitLocks(void)
{
if (freeListLock == NULL) {
- freeListLock = PZ_NewLock(nssILockRefLock);
- if (freeListLock == NULL) {
- return SECFailure;
- }
+ 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;
- }
- }
-
+ 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
+ * 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
@@ -111,7 +111,6 @@ nsslowcert_UnlockDB(NSSLOWCERTCertDBHandle *handle)
#endif
}
-
/*
* Acquire the cert reference count lock
* There is currently one global lock for all certs, but I'm putting a cert
@@ -122,7 +121,7 @@ static void
nsslowcert_LockCertRefCount(NSSLOWCERTCertificate *cert)
{
PORT_Assert(certRefCountLock != NULL);
-
+
PZ_Lock(certRefCountLock);
return;
}
@@ -134,7 +133,7 @@ static void
nsslowcert_UnlockCertRefCount(NSSLOWCERTCertificate *cert)
{
PORT_Assert(certRefCountLock != NULL);
-
+
#ifdef DEBUG
{
PRStatus prstat = PZ_Unlock(certRefCountLock);
@@ -167,7 +166,7 @@ static void
nsslowcert_UnlockCertTrust(NSSLOWCERTCertificate *cert)
{
PORT_Assert(certTrustLock != NULL);
-
+
#ifdef DEBUG
{
PRStatus prstat = PZ_Unlock(certTrustLock);
@@ -178,7 +177,6 @@ nsslowcert_UnlockCertTrust(NSSLOWCERTCertificate *cert)
#endif
}
-
/*
* Acquire the cert reference count lock
* There is currently one global lock for all certs, but I'm putting a cert
@@ -189,7 +187,7 @@ static void
nsslowcert_LockFreeList(void)
{
PORT_Assert(freeListLock != NULL);
-
+
SKIP_AFTER_FORK(PZ_Lock(freeListLock));
return;
}
@@ -201,7 +199,7 @@ static void
nsslowcert_UnlockFreeList(void)
{
PORT_Assert(freeListLock != NULL);
-
+
#ifdef DEBUG
{
PRStatus prstat = PR_SUCCESS;
@@ -217,9 +215,9 @@ NSSLOWCERTCertificate *
nsslowcert_DupCertificate(NSSLOWCERTCertificate *c)
{
if (c) {
- nsslowcert_LockCertRefCount(c);
- ++c->referenceCount;
- nsslowcert_UnlockCertRefCount(c);
+ nsslowcert_LockCertRefCount(c);
+ ++c->referenceCount;
+ nsslowcert_UnlockCertRefCount(c);
}
return c;
}
@@ -228,15 +226,15 @@ static int
certdb_Get(DB *db, DBT *key, DBT *data, unsigned int flags)
{
int ret;
-
+
PORT_Assert(dbLock != NULL);
PZ_Lock(dbLock);
- ret = (* db->get)(db, key, data, flags);
+ ret = (*db->get)(db, key, data, flags);
(void)PZ_Unlock(dbLock);
- return(ret);
+ return (ret);
}
static int
@@ -247,11 +245,11 @@ certdb_Put(DB *db, DBT *key, DBT *data, unsigned int flags)
PORT_Assert(dbLock != NULL);
PZ_Lock(dbLock);
- ret = (* db->put)(db, key, data, flags);
-
+ ret = (*db->put)(db, key, data, flags);
+
(void)PZ_Unlock(dbLock);
- return(ret);
+ return (ret);
}
static int
@@ -262,14 +260,14 @@ certdb_Sync(DB *db, unsigned int flags)
PORT_Assert(dbLock != NULL);
PZ_Lock(dbLock);
- ret = (* db->sync)(db, flags);
-
+ ret = (*db->sync)(db, flags);
+
(void)PZ_Unlock(dbLock);
- return(ret);
+ return (ret);
}
-#define DB_NOT_FOUND -30991 /* from DBM 3.2 */
+#define DB_NOT_FOUND -30991 /* from DBM 3.2 */
static int
certdb_Del(DB *db, DBT *key, unsigned int flags)
{
@@ -278,31 +276,31 @@ certdb_Del(DB *db, DBT *key, unsigned int flags)
PORT_Assert(dbLock != NULL);
PZ_Lock(dbLock);
- ret = (* db->del)(db, key, flags);
-
+ ret = (*db->del)(db, key, flags);
+
(void)PZ_Unlock(dbLock);
/* don't fail if the record is already deleted */
if (ret == DB_NOT_FOUND) {
- ret = 0;
+ ret = 0;
}
- return(ret);
+ return (ret);
}
static int
certdb_Seq(DB *db, DBT *key, DBT *data, unsigned int flags)
{
int ret;
-
+
PORT_Assert(dbLock != NULL);
PZ_Lock(dbLock);
-
- ret = (* db->seq)(db, key, data, flags);
+
+ ret = (*db->seq)(db, key, data, flags);
(void)PZ_Unlock(dbLock);
- return(ret);
+ return (ret);
}
static void
@@ -311,8 +309,8 @@ certdb_Close(DB *db)
PORT_Assert(dbLock != NULL);
SKIP_AFTER_FORK(PZ_Lock(dbLock));
- (* db->close)(db);
-
+ (*db->close)(db);
+
SKIP_AFTER_FORK(PZ_Unlock(dbLock));
return;
@@ -322,32 +320,32 @@ void
pkcs11_freeNickname(char *nickname, char *space)
{
if (nickname && nickname != space) {
- PORT_Free(nickname);
+ PORT_Free(nickname);
}
}
char *
-pkcs11_copyNickname(char *nickname,char *space, int spaceLen)
+pkcs11_copyNickname(char *nickname, char *space, int spaceLen)
{
int len;
char *copy = NULL;
- len = PORT_Strlen(nickname)+1;
+ len = PORT_Strlen(nickname) + 1;
if (len <= spaceLen) {
- copy = space;
- PORT_Memcpy(copy,nickname,len);
+ copy = space;
+ PORT_Memcpy(copy, nickname, len);
} else {
- copy = PORT_Strdup(nickname);
+ copy = PORT_Strdup(nickname);
}
return copy;
}
void
-pkcs11_freeStaticData (unsigned char *data, unsigned char *space)
+pkcs11_freeStaticData(unsigned char *data, unsigned char *space)
{
if (data && data != space) {
- PORT_Free(data);
+ PORT_Free(data);
}
}
@@ -357,21 +355,21 @@ pkcs11_allocStaticData(int len, unsigned char *space, int spaceLen)
unsigned char *data = NULL;
if (len <= spaceLen) {
- data = space;
+ data = space;
} else {
- data = (unsigned char *) PORT_Alloc(len);
+ data = (unsigned char *)PORT_Alloc(len);
}
return data;
}
unsigned char *
-pkcs11_copyStaticData(unsigned char *data, int len,
- unsigned char *space, int spaceLen)
+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);
+ PORT_Memcpy(copy, data, len);
}
return copy;
@@ -387,29 +385,28 @@ DestroyDBEntry(certDBEntry *entry)
/* 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;
+ 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);
@@ -430,96 +427,96 @@ DeleteDBEntry(NSSLOWCERTCertDBHandle *handle, certDBEntryType type, SECItem *dbk
/* 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_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;
+ if (ret) {
+ PORT_SetError(SEC_ERROR_BAD_DATABASE);
+ goto loser;
}
- return(SECSuccess);
-
+ return (SECSuccess);
+
loser:
- return(SECFailure);
+ return (SECFailure);
}
static SECStatus
ReadDBEntry(NSSLOWCERTCertDBHandle *handle, certDBEntryCommon *entry,
- SECItem *dbkey, SECItem *dbentry, PLArenaPool *arena)
+ SECItem *dbkey, SECItem *dbentry, PLArenaPool *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;
+ 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;
+ 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[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;
+ 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];
- }
+ 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;
+ dbentry->data = NULL;
}
-
- return(SECSuccess);
+
+ return (SECSuccess);
loser:
- return(SECFailure);
+ return (SECFailure);
}
/**
@@ -527,43 +524,43 @@ loser:
**/
static SECStatus
WriteDBEntry(NSSLOWCERTCertDBHandle *handle, certDBEntryCommon *entry,
- SECItem *dbkey, SECItem *dbentry)
+ 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 = (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;
+ if (ret != 0) {
+ goto loser;
}
- ret = certdb_Sync( handle->permCertDB, 0 );
-
- if ( ret ) {
- goto loser;
+ ret = certdb_Sync(handle->permCertDB, 0);
+
+ if (ret) {
+ goto loser;
}
- return(SECSuccess);
+ return (SECSuccess);
loser:
- return(SECFailure);
+ return (SECFailure);
}
/*
@@ -576,50 +573,50 @@ EncodeDBCertEntry(certDBEntryCert *entry, PLArenaPool *arena, SECItem *dbitem)
unsigned char *buf;
char *nn;
char zbuf = 0;
-
- if ( entry->nickname ) {
- nn = entry->nickname;
+
+ if (entry->nickname) {
+ nn = entry->nickname;
} else {
- nn = &zbuf;
+ 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;
-
+ 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;
+ 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 );
-
+
+ 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);
+ entry->derCert.len);
PORT_Memcpy(&buf[DB_CERT_ENTRY_HEADER_LEN + entry->derCert.len],
- nn, nnlen);
+ nn, nnlen);
- return(SECSuccess);
+ return (SECSuccess);
loser:
- return(SECFailure);
+ return (SECFailure);
}
/*
@@ -630,59 +627,58 @@ EncodeDBCertKey(const SECItem *certKey, PLArenaPool *arena, SECItem *dbkey)
{
unsigned int len = certKey->len + SEC_DB_KEY_HEADER_LEN;
if (len > NSS_MAX_LEGACY_DB_KEY_SIZE)
- goto loser;
+ goto loser;
if (arena) {
- dbkey->data = (unsigned char *)PORT_ArenaAlloc(arena, len);
+ dbkey->data = (unsigned char *)PORT_ArenaAlloc(arena, len);
} else {
- if (dbkey->len < len) {
- dbkey->data = (unsigned char *)PORT_Alloc(len);
- }
+ if (dbkey->len < len) {
+ dbkey->data = (unsigned char *)PORT_Alloc(len);
+ }
}
dbkey->len = len;
- if ( dbkey->data == NULL ) {
- goto loser;
+ if (dbkey->data == NULL) {
+ goto loser;
}
PORT_Memcpy(&dbkey->data[SEC_DB_KEY_HEADER_LEN],
- certKey->data, certKey->len);
+ certKey->data, certKey->len);
dbkey->data[0] = certDBEntryTypeCert;
- return(SECSuccess);
+ return (SECSuccess);
loser:
- return(SECFailure);
+ return (SECFailure);
}
static SECStatus
EncodeDBGenericKey(const SECItem *certKey, PLArenaPool *arena, SECItem *dbkey,
- certDBEntryType entryType)
+ 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 = 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;
+ goto loser;
dbkey->data = (unsigned char *)PORT_ArenaAlloc(arena, dbkey->len);
- if ( dbkey->data == NULL ) {
- goto loser;
+ 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;
+ certKey->data, certKey->len);
+ dbkey->data[0] = (unsigned char)entryType;
- return(SECSuccess);
+ return (SECSuccess);
loser:
- return(SECFailure);
+ return (SECFailure);
}
static SECStatus
@@ -693,153 +689,152 @@ DecodeDBCertEntry(certDBEntryCert *entry, SECItem *dbentry)
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;
- }
-
+ 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;
+ 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;
- }
-
+ 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;
+ 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;
- }
+ 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];
+ 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];
+ 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);
+
+ return (SECSuccess);
loser:
- return(SECFailure);
+ return (SECFailure);
}
-
/*
* Create a new certDBEntryCert from existing data
*/
static certDBEntryCert *
NewDBCertEntry(SECItem *derCert, char *nickname,
- NSSLOWCERTCertTrust *trust, int flags)
+ NSSLOWCERTCertTrust *trust, int flags)
{
certDBEntryCert *entry;
PLArenaPool *arena = NULL;
int nnlen;
-
- arena = PORT_NewArena( DER_DEFAULT_CHUNKSIZE );
- if ( !arena ) {
- goto loser;
+ arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
+
+ if (!arena) {
+ goto loser;
}
-
+
entry = PORT_ArenaZNew(arena, certDBEntryCert);
- if ( entry == NULL ) {
- goto loser;
+ 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;
+
+ if (trust) {
+ entry->trust = *trust;
}
entry->derCert.data = (unsigned char *)PORT_ArenaAlloc(arena, derCert->len);
- if ( !entry->derCert.data ) {
- goto loser;
+ 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);
-
+
+ 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;
+ entry->nickname = 0;
}
- return(entry);
+ return (entry);
loser:
-
+
/* allocation error, free arena and return */
- if ( arena ) {
- PORT_FreeArena(arena, PR_FALSE);
+ if (arena) {
+ PORT_FreeArena(arena, PR_FALSE);
}
-
+
PORT_SetError(SEC_ERROR_NO_MEMORY);
- return(0);
+ return (0);
}
/*
@@ -853,36 +848,36 @@ DecodeV4DBCertEntry(unsigned char *buf, int len)
int certlen;
int nnlen;
PLArenaPool *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);
+ 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);
+ if ((certlen + nnlen + DBCERT_V4_HEADER_LEN) != len) {
+ PORT_SetError(SEC_ERROR_BAD_DATABASE);
+ return (0);
}
/* allocate arena */
- arena = PORT_NewArena( DER_DEFAULT_CHUNKSIZE );
+ arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
- if ( !arena ) {
- PORT_SetError(SEC_ERROR_NO_MEMORY);
- return(0);
+ if (!arena) {
+ PORT_SetError(SEC_ERROR_NO_MEMORY);
+ return (0);
}
-
+
/* allocate structure and members */
- entry = (certDBEntryCert *) PORT_ArenaAlloc(arena, sizeof(certDBEntryCert));
+ entry = (certDBEntryCert *)PORT_ArenaAlloc(arena, sizeof(certDBEntryCert));
- if ( !entry ) {
- goto loser;
+ if (!entry) {
+ goto loser;
}
entry->common.arena = arena;
@@ -894,19 +889,19 @@ DecodeV4DBCertEntry(unsigned char *buf, int len)
entry->trust.objectSigningFlags = buf[2];
entry->derCert.data = (unsigned char *)PORT_ArenaAlloc(arena, certlen);
- if ( !entry->derCert.data ) {
- goto loser;
+ 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 ) {
+ 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;
}
@@ -914,12 +909,12 @@ DecodeV4DBCertEntry(unsigned char *buf, int len)
entry->nickname = 0;
}
- return(entry);
-
+ return (entry);
+
loser:
PORT_FreeArena(arena, PR_FALSE);
PORT_SetError(SEC_ERROR_NO_MEMORY);
- return(0);
+ return (0);
}
/*
@@ -933,45 +928,44 @@ WriteDBCertEntry(NSSLOWCERTCertDBHandle *handle, certDBEntryCert *entry)
PLArenaPool *tmparena = NULL;
SECItem tmpitem;
SECStatus rv;
-
+
tmparena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
- if ( tmparena == NULL ) {
- goto loser;
+ if (tmparena == NULL) {
+ goto loser;
}
-
+
rv = EncodeDBCertEntry(entry, tmparena, &dbitem);
- if ( rv != SECSuccess ) {
- goto loser;
+ if (rv != SECSuccess) {
+ goto loser;
}
/* get the database key and format it */
rv = nsslowcert_KeyFromDERCert(tmparena, &entry->derCert, &tmpitem);
- if ( rv == SECFailure ) {
- goto loser;
+ if (rv == SECFailure) {
+ goto loser;
}
rv = EncodeDBCertKey(&tmpitem, tmparena, &dbkey);
- if ( rv == SECFailure ) {
- goto loser;
+ if (rv == SECFailure) {
+ goto loser;
}
-
+
/* now write it to the database */
rv = WriteDBEntry(handle, &entry->common, &dbkey, &dbitem);
- if ( rv != SECSuccess ) {
- goto loser;
+ if (rv != SECSuccess) {
+ goto loser;
}
-
+
PORT_FreeArena(tmparena, PR_FALSE);
- return(SECSuccess);
+ return (SECSuccess);
loser:
- if ( tmparena ) {
- PORT_FreeArena(tmparena, PR_FALSE);
+ if (tmparena) {
+ PORT_FreeArena(tmparena, PR_FALSE);
}
- return(SECFailure);
+ return (SECFailure);
}
-
/*
* delete a certificate entry
*/
@@ -981,28 +975,28 @@ DeleteDBCertEntry(NSSLOWCERTCertDBHandle *handle, SECItem *certKey)
SECItem dbkey;
SECStatus rv;
- dbkey.data= NULL;
+ dbkey.data = NULL;
dbkey.len = 0;
rv = EncodeDBCertKey(certKey, NULL, &dbkey);
- if ( rv != SECSuccess ) {
- goto loser;
+ if (rv != SECSuccess) {
+ goto loser;
}
-
+
rv = DeleteDBEntry(handle, certDBEntryTypeCert, &dbkey);
- if ( rv == SECFailure ) {
- goto loser;
+ if (rv == SECFailure) {
+ goto loser;
}
PORT_Free(dbkey.data);
- return(SECSuccess);
+ return (SECSuccess);
loser:
if (dbkey.data) {
- PORT_Free(dbkey.data);
+ PORT_Free(dbkey.data);
}
- return(SECFailure);
+ return (SECFailure);
}
static certDBEntryCert *
@@ -1013,13 +1007,13 @@ CreateCertEntry(void)
nsslowcert_LockFreeList();
entry = entryListHead;
if (entry) {
- entryListCount--;
- entryListHead = entry->next;
+ entryListCount--;
+ entryListHead = entry->next;
}
PORT_Assert(entryListCount >= 0);
nsslowcert_UnlockFreeList();
if (entry) {
- return entry;
+ return entry;
}
return PORT_ZNew(certDBEntryCert);
@@ -1032,9 +1026,9 @@ DestroyCertEntryFreeList(void)
nsslowcert_LockFreeList();
while (NULL != (entry = entryListHead)) {
- entryListCount--;
- entryListHead = entry->next;
- PORT_Free(entry);
+ entryListCount--;
+ entryListHead = entry->next;
+ PORT_Free(entry);
}
PORT_Assert(!entryListCount);
entryListCount = 0;
@@ -1057,40 +1051,40 @@ ReadDBCertEntry(NSSLOWCERTCertDBHandle *handle, const SECItem *certKey)
dbkey.len = sizeof(buf);
entry = CreateCertEntry();
- if ( entry == NULL ) {
- PORT_SetError(SEC_ERROR_NO_MEMORY);
- goto loser;
+ 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;
+ if (rv != SECSuccess) {
+ goto loser;
}
-
+
rv = ReadDBEntry(handle, &entry->common, &dbkey, &dbentry, NULL);
- if ( rv == SECFailure ) {
- goto loser;
+ if (rv == SECFailure) {
+ goto loser;
}
rv = DecodeDBCertEntry(entry, &dbentry);
- if ( rv != SECSuccess ) {
- goto loser;
+ if (rv != SECSuccess) {
+ goto loser;
}
- pkcs11_freeStaticData(dbkey.data,buf);
+ pkcs11_freeStaticData(dbkey.data, buf);
dbkey.data = NULL;
- return(entry);
-
+ return (entry);
+
loser:
- pkcs11_freeStaticData(dbkey.data,buf);
+ pkcs11_freeStaticData(dbkey.data, buf);
dbkey.data = NULL;
- if ( entry ) {
+ if (entry) {
DestroyDBEntry((certDBEntry *)entry);
}
-
- return(NULL);
+
+ return (NULL);
}
/*
@@ -1101,43 +1095,42 @@ EncodeDBCrlEntry(certDBEntryRevocation *entry, PLArenaPool *arena, SECItem *dbit
{
unsigned int nnlen = 0;
unsigned char *buf;
-
- if (entry->url) {
- nnlen = PORT_Strlen(entry->url) + 1;
+
+ 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->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;
+ 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 );
-
+
+ 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);
+ entry->derCrl.len);
if (nnlen != 0) {
- PORT_Memcpy(&buf[DB_CRL_ENTRY_HEADER_LEN + entry->derCrl.len],
- entry->url, nnlen);
+ PORT_Memcpy(&buf[DB_CRL_ENTRY_HEADER_LEN + entry->derCrl.len],
+ entry->url, nnlen);
}
- return(SECSuccess);
+ return (SECSuccess);
loser:
- return(SECFailure);
+ return (SECFailure);
}
static SECStatus
@@ -1147,189 +1140,186 @@ DecodeDBCrlEntry(certDBEntryRevocation *entry, SECItem *dbentry)
int lenDiff;
/* is record long enough for header? */
- if ( dbentry->len < DB_CRL_ENTRY_HEADER_LEN ) {
- PORT_SetError(SEC_ERROR_BAD_DATABASE);
- goto loser;
+ 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);
+ 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;
- }
-
+ 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;
+ 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);
+ 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);
+ 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);
+ return (SECFailure);
}
/*
* Create a new certDBEntryRevocation from existing data
*/
static certDBEntryRevocation *
-NewDBCrlEntry(SECItem *derCrl, char * url, certDBEntryType crlType, int flags)
+NewDBCrlEntry(SECItem *derCrl, char *url, certDBEntryType crlType, int flags)
{
certDBEntryRevocation *entry;
PLArenaPool *arena = NULL;
int nnlen;
-
- arena = PORT_NewArena( DER_DEFAULT_CHUNKSIZE );
- if ( !arena ) {
- goto loser;
+ arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
+
+ if (!arena) {
+ goto loser;
}
-
+
entry = PORT_ArenaZNew(arena, certDBEntryRevocation);
- if ( entry == NULL ) {
- goto loser;
+ 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 (!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);
+ 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->url = NULL;
}
-
entry->derCrl.len = derCrl->len;
PORT_Memcpy(entry->derCrl.data, derCrl->data, derCrl->len);
- return(entry);
+ return (entry);
loser:
-
+
/* allocation error, free arena and return */
- if ( arena ) {
- PORT_FreeArena(arena, PR_FALSE);
+ if (arena) {
+ PORT_FreeArena(arena, PR_FALSE);
}
-
+
PORT_SetError(SEC_ERROR_NO_MEMORY);
- return(0);
+ return (0);
}
-
static SECStatus
WriteDBCrlEntry(NSSLOWCERTCertDBHandle *handle, certDBEntryRevocation *entry,
- SECItem *crlKey )
+ SECItem *crlKey)
{
SECItem dbkey;
PLArenaPool *tmparena = NULL;
SECItem encodedEntry;
SECStatus rv;
-
+
tmparena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
- if ( tmparena == NULL ) {
- goto loser;
+ if (tmparena == NULL) {
+ goto loser;
}
rv = EncodeDBCrlEntry(entry, tmparena, &encodedEntry);
- if ( rv == SECFailure ) {
- goto loser;
+ if (rv == SECFailure) {
+ goto loser;
}
rv = EncodeDBGenericKey(crlKey, tmparena, &dbkey, entry->common.type);
- if ( rv == SECFailure ) {
- goto loser;
+ if (rv == SECFailure) {
+ goto loser;
}
-
+
/* now write it to the database */
rv = WriteDBEntry(handle, &entry->common, &dbkey, &encodedEntry);
- if ( rv != SECSuccess ) {
- goto loser;
+ if (rv != SECSuccess) {
+ goto loser;
}
-
+
PORT_FreeArena(tmparena, PR_FALSE);
- return(SECSuccess);
+ return (SECSuccess);
loser:
- if ( tmparena ) {
- PORT_FreeArena(tmparena, PR_FALSE);
+ if (tmparena) {
+ PORT_FreeArena(tmparena, PR_FALSE);
}
- return(SECFailure);
+ return (SECFailure);
}
/*
* delete a crl entry
*/
static SECStatus
-DeleteDBCrlEntry(NSSLOWCERTCertDBHandle *handle, const SECItem *crlKey,
- certDBEntryType crlType)
+DeleteDBCrlEntry(NSSLOWCERTCertDBHandle *handle, const SECItem *crlKey,
+ certDBEntryType crlType)
{
SECItem dbkey;
PLArenaPool *arena = NULL;
SECStatus rv;
-
+
arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
- if ( arena == NULL ) {
- goto loser;
+ if (arena == NULL) {
+ goto loser;
}
rv = EncodeDBGenericKey(crlKey, arena, &dbkey, crlType);
- if ( rv != SECSuccess ) {
- goto loser;
+ if (rv != SECSuccess) {
+ goto loser;
}
-
+
rv = DeleteDBEntry(handle, crlType, &dbkey);
- if ( rv == SECFailure ) {
- goto loser;
+ if (rv == SECFailure) {
+ goto loser;
}
PORT_FreeArena(arena, PR_FALSE);
- return(SECSuccess);
+ return (SECSuccess);
loser:
- if ( arena ) {
- PORT_FreeArena(arena, PR_FALSE);
+ if (arena) {
+ PORT_FreeArena(arena, PR_FALSE);
}
-
- return(SECFailure);
+
+ return (SECFailure);
}
/*
@@ -1337,7 +1327,7 @@ loser:
*/
static certDBEntryRevocation *
ReadDBCrlEntry(NSSLOWCERTCertDBHandle *handle, SECItem *certKey,
- certDBEntryType crlType)
+ certDBEntryType crlType)
{
PLArenaPool *arena = NULL;
PLArenaPool *tmparena = NULL;
@@ -1345,55 +1335,55 @@ ReadDBCrlEntry(NSSLOWCERTCertDBHandle *handle, SECItem *certKey,
SECItem dbkey;
SECItem dbentry;
SECStatus rv;
-
+
arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
- if ( arena == NULL ) {
- PORT_SetError(SEC_ERROR_NO_MEMORY);
- goto loser;
+ 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;
+ 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;
+ 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;
+ if (rv != SECSuccess) {
+ goto loser;
}
-
+
rv = ReadDBEntry(handle, &entry->common, &dbkey, &dbentry, NULL);
- if ( rv == SECFailure ) {
- goto loser;
+ if (rv == SECFailure) {
+ goto loser;
}
rv = DecodeDBCrlEntry(entry, &dbentry);
- if ( rv != SECSuccess ) {
- goto loser;
+ if (rv != SECSuccess) {
+ goto loser;
}
-
+
PORT_FreeArena(tmparena, PR_FALSE);
- return(entry);
-
+ return (entry);
+
loser:
- if ( tmparena ) {
- PORT_FreeArena(tmparena, PR_FALSE);
+ if (tmparena) {
+ PORT_FreeArena(tmparena, PR_FALSE);
}
- if ( arena ) {
- PORT_FreeArena(arena, PR_FALSE);
+ if (arena) {
+ PORT_FreeArena(arena, PR_FALSE);
}
-
- return(NULL);
+
+ return (NULL);
}
void
@@ -1408,31 +1398,31 @@ nsslowcert_DestroyDBEntry(certDBEntry *entry)
*/
static SECStatus
EncodeDBNicknameEntry(certDBEntryNickname *entry, PLArenaPool *arena,
- SECItem *dbitem)
+ 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;
+ SEC_DB_ENTRY_HEADER_LEN;
dbitem->data = (unsigned char *)PORT_ArenaAlloc(arena, dbitem->len);
- if ( dbitem->data == NULL) {
- goto loser;
+ 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 );
+ 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);
+ entry->subjectName.len);
- return(SECSuccess);
+ return (SECSuccess);
loser:
- return(SECFailure);
+ return (SECFailure);
}
/*
@@ -1440,27 +1430,27 @@ loser:
*/
static SECStatus
EncodeDBNicknameKey(char *nickname, PLArenaPool *arena,
- SECItem *dbkey)
+ 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;
+ goto loser;
dbkey->data = (unsigned char *)PORT_ArenaAlloc(arena, dbkey->len);
- if ( dbkey->data == NULL ) {
- goto loser;
+ if (dbkey->data == NULL) {
+ goto loser;
}
PORT_Memcpy(&dbkey->data[SEC_DB_KEY_HEADER_LEN], nickname, nnlen);
dbkey->data[0] = certDBEntryTypeNickname;
- return(SECSuccess);
+ return (SECSuccess);
loser:
- return(SECFailure);
+ return (SECFailure);
}
static SECStatus
@@ -1470,47 +1460,47 @@ DecodeDBNicknameEntry(certDBEntryNickname *entry, SECItem *dbentry,
int lenDiff;
/* is record long enough for header? */
- if ( dbentry->len < DB_NICKNAME_ENTRY_HEADER_LEN ) {
- PORT_SetError(SEC_ERROR_BAD_DATABASE);
- goto loser;
+ 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);
+ 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;
+ 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;
+ (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);
+ &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);
+
+ entry->nickname = (char *)PORT_ArenaAlloc(entry->common.arena,
+ PORT_Strlen(nickname) + 1);
+ if (entry->nickname) {
+ PORT_Strcpy(entry->nickname, nickname);
}
-
- return(SECSuccess);
+
+ return (SECSuccess);
loser:
- return(SECFailure);
+ return (SECFailure);
}
/*
@@ -1523,18 +1513,18 @@ NewDBNicknameEntry(char *nickname, SECItem *subjectName, unsigned int flags)
certDBEntryNickname *entry;
int nnlen;
SECStatus rv;
-
+
arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
- if ( arena == NULL ) {
- PORT_SetError(SEC_ERROR_NO_MEMORY);
- goto loser;
+ 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;
+ sizeof(certDBEntryNickname));
+ if (entry == NULL) {
+ PORT_SetError(SEC_ERROR_NO_MEMORY);
+ goto loser;
}
/* init common fields */
@@ -1545,26 +1535,26 @@ NewDBNicknameEntry(char *nickname, SECItem *subjectName, unsigned int flags)
/* copy the nickname */
nnlen = PORT_Strlen(nickname) + 1;
-
- entry->nickname = (char*)PORT_ArenaAlloc(arena, nnlen);
- if ( entry->nickname == NULL ) {
- goto loser;
+
+ 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;
+ if (rv != SECSuccess) {
+ goto loser;
}
-
- return(entry);
+
+ return (entry);
loser:
- if ( arena ) {
- PORT_FreeArena(arena, PR_FALSE);
+ if (arena) {
+ PORT_FreeArena(arena, PR_FALSE);
}
-
- return(NULL);
+
+ return (NULL);
}
/*
@@ -1576,35 +1566,35 @@ DeleteDBNicknameEntry(NSSLOWCERTCertDBHandle *handle, char *nickname)
PLArenaPool *arena = NULL;
SECStatus rv;
SECItem dbkey;
-
- if ( nickname == NULL ) {
- return(SECSuccess);
+
+ if (nickname == NULL) {
+ return (SECSuccess);
}
-
+
arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
- if ( arena == NULL ) {
- goto loser;
+ if (arena == NULL) {
+ goto loser;
}
rv = EncodeDBNicknameKey(nickname, arena, &dbkey);
- if ( rv != SECSuccess ) {
- goto loser;
+ if (rv != SECSuccess) {
+ goto loser;
}
rv = DeleteDBEntry(handle, certDBEntryTypeNickname, &dbkey);
- if ( rv == SECFailure ) {
- goto loser;
+ if (rv == SECFailure) {
+ goto loser;
}
PORT_FreeArena(arena, PR_FALSE);
- return(SECSuccess);
+ return (SECSuccess);
loser:
- if ( arena ) {
- PORT_FreeArena(arena, PR_FALSE);
+ if (arena) {
+ PORT_FreeArena(arena, PR_FALSE);
}
-
- return(SECFailure);
+
+ return (SECFailure);
}
/*
@@ -1619,61 +1609,61 @@ ReadDBNicknameEntry(NSSLOWCERTCertDBHandle *handle, char *nickname)
SECItem dbkey;
SECItem dbentry;
SECStatus rv;
-
+
arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
- if ( arena == NULL ) {
- PORT_SetError(SEC_ERROR_NO_MEMORY);
- goto loser;
+ 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;
+ 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;
+ 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;
+ if (rv != SECSuccess) {
+ goto loser;
}
-
+
rv = ReadDBEntry(handle, &entry->common, &dbkey, &dbentry, tmparena);
- if ( rv == SECFailure ) {
- goto loser;
+ 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;
+ 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;
+ if (rv != SECSuccess) {
+ goto loser;
}
-
+
PORT_FreeArena(tmparena, PR_FALSE);
- return(entry);
-
+ return (entry);
+
loser:
- if ( tmparena ) {
- PORT_FreeArena(tmparena, PR_FALSE);
+ if (tmparena) {
+ PORT_FreeArena(tmparena, PR_FALSE);
}
- if ( arena ) {
- PORT_FreeArena(arena, PR_FALSE);
+ if (arena) {
+ PORT_FreeArena(arena, PR_FALSE);
}
-
- return(NULL);
+
+ return (NULL);
}
/*
@@ -1686,88 +1676,87 @@ WriteDBNicknameEntry(NSSLOWCERTCertDBHandle *handle, certDBEntryNickname *entry)
SECItem dbitem, dbkey;
PLArenaPool *tmparena = NULL;
SECStatus rv;
-
+
tmparena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
- if ( tmparena == NULL ) {
- goto loser;
+ if (tmparena == NULL) {
+ goto loser;
}
-
+
rv = EncodeDBNicknameEntry(entry, tmparena, &dbitem);
- if ( rv != SECSuccess ) {
- goto loser;
+ if (rv != SECSuccess) {
+ goto loser;
}
rv = EncodeDBNicknameKey(entry->nickname, tmparena, &dbkey);
- if ( rv != SECSuccess ) {
- goto loser;
+ if (rv != SECSuccess) {
+ goto loser;
}
/* now write it to the database */
rv = WriteDBEntry(handle, &entry->common, &dbkey, &dbitem);
- if ( rv != SECSuccess ) {
- goto loser;
+ if (rv != SECSuccess) {
+ goto loser;
}
-
+
PORT_FreeArena(tmparena, PR_FALSE);
- return(SECSuccess);
+ return (SECSuccess);
loser:
- if ( tmparena ) {
- PORT_FreeArena(tmparena, PR_FALSE);
+ if (tmparena) {
+ PORT_FreeArena(tmparena, PR_FALSE);
}
- return(SECFailure);
-
+ return (SECFailure);
}
static SECStatus
EncodeDBSMimeEntry(certDBEntrySMime *entry, PLArenaPool *arena,
- SECItem *dbitem)
+ 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;
-
+ 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;
+ 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 );
+
+ 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_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);
+ 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);
+ return (SECSuccess);
loser:
- return(SECFailure);
+ return (SECFailure);
}
/*
@@ -1775,27 +1764,27 @@ loser:
*/
static SECStatus
EncodeDBSMimeKey(char *emailAddr, PLArenaPool *arena,
- SECItem *dbkey)
+ 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;
+ goto loser;
dbkey->data = (unsigned char *)PORT_ArenaAlloc(arena, dbkey->len);
- if ( dbkey->data == NULL ) {
- goto loser;
+ if (dbkey->data == NULL) {
+ goto loser;
}
PORT_Memcpy(&dbkey->data[SEC_DB_KEY_HEADER_LEN], emailAddr, addrlen);
dbkey->data[0] = certDBEntryTypeSMimeProfile;
- return(SECSuccess);
+ return (SECSuccess);
loser:
- return(SECFailure);
+ return (SECFailure);
}
/*
@@ -1807,87 +1796,87 @@ 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;
+ 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);
+ 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;
+ 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;
+ (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);
+ &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);
+ 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;
+ 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);
+ PORT_Strlen(emailAddr) + 1);
+ if (entry->emailAddr) {
+ PORT_Strcpy(entry->emailAddr, emailAddr);
}
-
- return(SECSuccess);
+
+ return (SECSuccess);
loser:
- return(SECFailure);
+ return (SECFailure);
}
/*
@@ -1895,24 +1884,24 @@ loser:
*/
static certDBEntrySMime *
NewDBSMimeEntry(char *emailAddr, SECItem *subjectName, SECItem *smimeOptions,
- SECItem *optionsDate, unsigned int flags)
+ SECItem *optionsDate, unsigned int flags)
{
PLArenaPool *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;
+ 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;
+ sizeof(certDBEntrySMime));
+ if (entry == NULL) {
+ PORT_SetError(SEC_ERROR_NO_MEMORY);
+ goto loser;
}
/* init common fields */
@@ -1923,51 +1912,51 @@ NewDBSMimeEntry(char *emailAddr, SECItem *subjectName, SECItem *smimeOptions,
/* copy the email addr */
addrlen = PORT_Strlen(emailAddr) + 1;
-
- entry->emailAddr = (char*)PORT_ArenaAlloc(arena, addrlen);
- if ( entry->emailAddr == NULL ) {
- goto loser;
+
+ 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;
+ if (rv != SECSuccess) {
+ goto loser;
}
/* copy the smime options */
- if ( smimeOptions ) {
- rv = SECITEM_CopyItem(arena, &entry->smimeOptions, smimeOptions);
- if ( rv != SECSuccess ) {
- goto loser;
- }
+ 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;
+ 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;
- }
+ 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;
+ PORT_Assert(smimeOptions == NULL);
+ entry->optionsDate.data = NULL;
+ entry->optionsDate.len = 0;
}
-
- return(entry);
+
+ return (entry);
loser:
- if ( arena ) {
- PORT_FreeArena(arena, PR_FALSE);
+ if (arena) {
+ PORT_FreeArena(arena, PR_FALSE);
}
-
- return(NULL);
+
+ return (NULL);
}
/*
@@ -1979,31 +1968,31 @@ DeleteDBSMimeEntry(NSSLOWCERTCertDBHandle *handle, char *emailAddr)
PLArenaPool *arena = NULL;
SECStatus rv;
SECItem dbkey;
-
+
arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
- if ( arena == NULL ) {
- goto loser;
+ if (arena == NULL) {
+ goto loser;
}
rv = EncodeDBSMimeKey(emailAddr, arena, &dbkey);
- if ( rv != SECSuccess ) {
- goto loser;
+ if (rv != SECSuccess) {
+ goto loser;
}
rv = DeleteDBEntry(handle, certDBEntryTypeSMimeProfile, &dbkey);
- if ( rv == SECFailure ) {
- goto loser;
+ if (rv == SECFailure) {
+ goto loser;
}
PORT_FreeArena(arena, PR_FALSE);
- return(SECSuccess);
+ return (SECSuccess);
loser:
- if ( arena ) {
- PORT_FreeArena(arena, PR_FALSE);
+ if (arena) {
+ PORT_FreeArena(arena, PR_FALSE);
}
-
- return(SECFailure);
+
+ return (SECFailure);
}
/*
@@ -2018,61 +2007,61 @@ nsslowcert_ReadDBSMimeEntry(NSSLOWCERTCertDBHandle *handle, char *emailAddr)
SECItem dbkey;
SECItem dbentry;
SECStatus rv;
-
+
arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
- if ( arena == NULL ) {
- PORT_SetError(SEC_ERROR_NO_MEMORY);
- goto loser;
+ 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;
+ 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;
+ 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;
+ if (rv != SECSuccess) {
+ goto loser;
}
-
+
rv = ReadDBEntry(handle, &entry->common, &dbkey, &dbentry, tmparena);
- if ( rv == SECFailure ) {
- goto loser;
+ 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;
+ 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;
+ if (rv != SECSuccess) {
+ goto loser;
}
-
+
PORT_FreeArena(tmparena, PR_FALSE);
- return(entry);
-
+ return (entry);
+
loser:
- if ( tmparena ) {
- PORT_FreeArena(tmparena, PR_FALSE);
+ if (tmparena) {
+ PORT_FreeArena(tmparena, PR_FALSE);
}
- if ( arena ) {
- PORT_FreeArena(arena, PR_FALSE);
+ if (arena) {
+ PORT_FreeArena(arena, PR_FALSE);
}
-
- return(NULL);
+
+ return (NULL);
}
/*
@@ -2085,37 +2074,36 @@ WriteDBSMimeEntry(NSSLOWCERTCertDBHandle *handle, certDBEntrySMime *entry)
SECItem dbitem, dbkey;
PLArenaPool *tmparena = NULL;
SECStatus rv;
-
+
tmparena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
- if ( tmparena == NULL ) {
- goto loser;
+ if (tmparena == NULL) {
+ goto loser;
}
-
+
rv = EncodeDBSMimeEntry(entry, tmparena, &dbitem);
- if ( rv != SECSuccess ) {
- goto loser;
+ if (rv != SECSuccess) {
+ goto loser;
}
rv = EncodeDBSMimeKey(entry->emailAddr, tmparena, &dbkey);
- if ( rv != SECSuccess ) {
- goto loser;
+ if (rv != SECSuccess) {
+ goto loser;
}
/* now write it to the database */
rv = WriteDBEntry(handle, &entry->common, &dbkey, &dbitem);
- if ( rv != SECSuccess ) {
- goto loser;
+ if (rv != SECSuccess) {
+ goto loser;
}
-
+
PORT_FreeArena(tmparena, PR_FALSE);
- return(SECSuccess);
+ return (SECSuccess);
loser:
- if ( tmparena ) {
- PORT_FreeArena(tmparena, PR_FALSE);
+ if (tmparena) {
+ PORT_FreeArena(tmparena, PR_FALSE);
}
- return(SECFailure);
-
+ return (SECFailure);
}
/*
@@ -2123,7 +2111,7 @@ loser:
*/
static SECStatus
EncodeDBSubjectEntry(certDBEntrySubject *entry, PLArenaPool *arena,
- SECItem *dbitem)
+ SECItem *dbitem)
{
unsigned char *buf;
int len;
@@ -2134,97 +2122,104 @@ EncodeDBSubjectEntry(certDBEntrySubject *entry, PLArenaPool *arena,
unsigned int eaddrslen = 0;
int keyidoff;
SECItem *certKeys = entry->certKeys;
- SECItem *keyIDs = entry->keyIDs;;
-
- if ( entry->nickname ) {
- nnlen = PORT_Strlen(entry->nickname) + 1;
+ 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;
- }
+ 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 ;
+ 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;
- }
-
+ 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;
+ 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 );
+
+ 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;
+ PORT_Assert(DB_SUBJECT_ENTRY_HEADER_LEN == 6);
+
+ if (entry->nickname) {
+ 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++) {
+ 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, 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;
+ for (i = 0; i < ncerts; i++) {
+ if (keyIDs[i].len) {
+ 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;
- }
+ 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);
+
+ return (SECSuccess);
loser:
- return(SECFailure);
+ return (SECFailure);
}
/*
@@ -2232,186 +2227,186 @@ loser:
*/
static SECStatus
EncodeDBSubjectKey(SECItem *derSubject, PLArenaPool *arena,
- SECItem *dbkey)
+ SECItem *dbkey)
{
dbkey->len = derSubject->len + SEC_DB_KEY_HEADER_LEN;
if (dbkey->len > NSS_MAX_LEGACY_DB_KEY_SIZE)
- goto loser;
+ goto loser;
dbkey->data = (unsigned char *)PORT_ArenaAlloc(arena, dbkey->len);
- if ( dbkey->data == NULL ) {
- goto loser;
+ if (dbkey->data == NULL) {
+ goto loser;
}
PORT_Memcpy(&dbkey->data[SEC_DB_KEY_HEADER_LEN], derSubject->data,
- derSubject->len);
+ derSubject->len);
dbkey->data[0] = certDBEntryTypeSubject;
- return(SECSuccess);
+ return (SECSuccess);
loser:
- return(SECFailure);
+ return (SECFailure);
}
static SECStatus
DecodeDBSubjectEntry(certDBEntrySubject *entry, SECItem *dbentry,
- const SECItem *derSubject)
+ const SECItem *derSubject)
{
- PLArenaPool *arena = entry->common.arena;
+ PLArenaPool *arena = entry->common.arena;
unsigned char *tmpbuf;
unsigned char *end;
- void *mark = PORT_ArenaMark(arena);
+ void *mark = PORT_ArenaMark(arena);
unsigned int eaddrlen;
unsigned int i;
unsigned int keyidoff;
unsigned int len;
- unsigned int ncerts = 0;
+ unsigned int ncerts = 0;
unsigned int nnlen;
SECStatus rv;
rv = SECITEM_CopyItem(arena, &entry->derSubject, derSubject);
- if ( rv != SECSuccess ) {
- goto loser;
+ 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] );
+ 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;
+ 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);
+ 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;
+ entry->nickname = NULL;
}
- /* if we have an old style email entry, there is only one */
+ /* 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;
+ 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;
+ 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];
+ 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] ;
+ 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;
+ 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;
+ /* 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);
+ return (SECSuccess);
loser:
PORT_ArenaRelease(arena, mark); /* discard above allocations */
- return(SECFailure);
+ return (SECFailure);
}
/*
@@ -2419,25 +2414,25 @@ loser:
*/
static certDBEntrySubject *
NewDBSubjectEntry(SECItem *derSubject, SECItem *certKey,
- SECItem *keyID, char *nickname, char *emailAddr,
- unsigned int flags)
+ SECItem *keyID, char *nickname, char *emailAddr,
+ unsigned int flags)
{
PLArenaPool *arena = NULL;
certDBEntrySubject *entry;
SECStatus rv;
unsigned int nnlen;
-
+
arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
- if ( arena == NULL ) {
- PORT_SetError(SEC_ERROR_NO_MEMORY);
- goto loser;
+ 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;
+ sizeof(certDBEntrySubject));
+ if (entry == NULL) {
+ PORT_SetError(SEC_ERROR_NO_MEMORY);
+ goto loser;
}
/* init common fields */
@@ -2448,72 +2443,72 @@ NewDBSubjectEntry(SECItem *derSubject, SECItem *certKey,
/* copy the subject */
rv = SECITEM_CopyItem(arena, &entry->derSubject, derSubject);
- if ( rv != SECSuccess ) {
- goto loser;
+ 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);
+ 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;
+ entry->nickname = NULL;
}
-
+
/* copy email addr */
- if ( emailAddr && ( *emailAddr != '\0' ) ) {
- emailAddr = nsslowcert_FixupEmailAddr(emailAddr);
- if ( emailAddr == NULL ) {
- entry->emailAddrs = NULL;
- goto loser;
- }
-
- 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);
+ if (emailAddr && (*emailAddr != '\0')) {
+ emailAddr = nsslowcert_FixupEmailAddr(emailAddr);
+ if (emailAddr == NULL) {
+ entry->emailAddrs = NULL;
+ goto loser;
+ }
+
+ 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;
+ 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;
+ 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;
+ if (rv != SECSuccess) {
+ goto loser;
}
rv = SECITEM_CopyItem(arena, &entry->keyIDs[0], keyID);
- if ( rv != SECSuccess ) {
- goto loser;
+ if (rv != SECSuccess) {
+ goto loser;
}
-
- return(entry);
+
+ return (entry);
loser:
- if ( arena ) {
- PORT_FreeArena(arena, PR_FALSE);
+ if (arena) {
+ PORT_FreeArena(arena, PR_FALSE);
}
-
- return(NULL);
+
+ return (NULL);
}
/*
@@ -2525,31 +2520,31 @@ DeleteDBSubjectEntry(NSSLOWCERTCertDBHandle *handle, SECItem *derSubject)
SECItem dbkey;
PLArenaPool *arena = NULL;
SECStatus rv;
-
+
arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
- if ( arena == NULL ) {
- goto loser;
+ if (arena == NULL) {
+ goto loser;
}
-
+
rv = EncodeDBSubjectKey(derSubject, arena, &dbkey);
- if ( rv != SECSuccess ) {
- goto loser;
+ if (rv != SECSuccess) {
+ goto loser;
}
-
+
rv = DeleteDBEntry(handle, certDBEntryTypeSubject, &dbkey);
- if ( rv == SECFailure ) {
- goto loser;
+ if (rv == SECFailure) {
+ goto loser;
}
PORT_FreeArena(arena, PR_FALSE);
- return(SECSuccess);
+ return (SECSuccess);
loser:
- if ( arena ) {
- PORT_FreeArena(arena, PR_FALSE);
+ if (arena) {
+ PORT_FreeArena(arena, PR_FALSE);
}
-
- return(SECFailure);
+
+ return (SECFailure);
}
/*
@@ -2558,61 +2553,57 @@ loser:
static certDBEntrySubject *
ReadDBSubjectEntry(NSSLOWCERTCertDBHandle *handle, SECItem *derSubject)
{
+ /* |arena| isn't function-bounded, so cannot be a PORTCheapArenaPool. */
PLArenaPool *arena = NULL;
- PLArenaPool *tmparena = NULL;
+ PORTCheapArenaPool tmpArena;
+
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;
+ 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;
- }
-
+ PORT_InitCheapArena(&tmpArena, DER_DEFAULT_CHUNKSIZE);
+
entry = (certDBEntrySubject *)PORT_ArenaAlloc(arena,
- sizeof(certDBEntrySubject));
- if ( entry == NULL ) {
- PORT_SetError(SEC_ERROR_NO_MEMORY);
- goto loser;
+ 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 = EncodeDBSubjectKey(derSubject, &tmpArena.arena, &dbkey);
+ if (rv != SECSuccess) {
+ goto loser;
}
-
- rv = ReadDBEntry(handle, &entry->common, &dbkey, &dbentry, tmparena);
- if ( rv == SECFailure ) {
- goto loser;
+
+ rv = ReadDBEntry(handle, &entry->common, &dbkey, &dbentry, &tmpArena.arena);
+ if (rv == SECFailure) {
+ goto loser;
}
rv = DecodeDBSubjectEntry(entry, &dbentry, derSubject);
- if ( rv == SECFailure ) {
- goto loser;
+ if (rv == SECFailure) {
+ goto loser;
}
-
- PORT_FreeArena(tmparena, PR_FALSE);
- return(entry);
-
+
+ PORT_DestroyCheapArena(&tmpArena);
+ return (entry);
+
loser:
- if ( tmparena ) {
- PORT_FreeArena(tmparena, PR_FALSE);
- }
- if ( arena ) {
- PORT_FreeArena(arena, PR_FALSE);
+ PORT_DestroyCheapArena(&tmpArena);
+ if (arena) {
+ PORT_FreeArena(arena, PR_FALSE);
}
-
- return(NULL);
+
+ return (NULL);
}
/*
@@ -2625,114 +2616,116 @@ WriteDBSubjectEntry(NSSLOWCERTCertDBHandle *handle, certDBEntrySubject *entry)
SECItem dbitem, dbkey;
PLArenaPool *tmparena = NULL;
SECStatus rv;
-
+
tmparena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
- if ( tmparena == NULL ) {
- goto loser;
+ if (tmparena == NULL) {
+ goto loser;
}
-
+
rv = EncodeDBSubjectEntry(entry, tmparena, &dbitem);
- if ( rv != SECSuccess ) {
- goto loser;
+ if (rv != SECSuccess) {
+ goto loser;
}
-
+
rv = EncodeDBSubjectKey(&entry->derSubject, tmparena, &dbkey);
- if ( rv != SECSuccess ) {
- goto loser;
+ if (rv != SECSuccess) {
+ goto loser;
}
/* now write it to the database */
rv = WriteDBEntry(handle, &entry->common, &dbkey, &dbitem);
- if ( rv != SECSuccess ) {
- goto loser;
+ if (rv != SECSuccess) {
+ goto loser;
}
-
+
PORT_FreeArena(tmparena, PR_FALSE);
- return(SECSuccess);
+ return (SECSuccess);
loser:
- if ( tmparena ) {
- PORT_FreeArena(tmparena, PR_FALSE);
+ if (tmparena) {
+ PORT_FreeArena(tmparena, PR_FALSE);
}
- return(SECFailure);
-
+ return (SECFailure);
}
-typedef enum { nsslowcert_remove, nsslowcert_add } nsslowcertUpdateType;
+typedef enum { nsslowcert_remove,
+ nsslowcert_add } nsslowcertUpdateType;
static SECStatus
-nsslowcert_UpdateSubjectEmailAddr(NSSLOWCERTCertDBHandle *dbhandle,
- SECItem *derSubject, char *emailAddr, nsslowcertUpdateType updateType)
+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;
- }
+
+ if (emailAddr) {
+ emailAddr = nsslowcert_FixupEmailAddr(emailAddr);
+ if (emailAddr == NULL) {
+ return SECFailure;
+ }
} else {
- return SECSuccess;
+ return SECSuccess;
}
- entry = ReadDBSubjectEntry(dbhandle,derSubject);
+ entry = ReadDBSubjectEntry(dbhandle, derSubject);
if (entry == NULL) {
- rv = SECFailure;
- goto done;
- }
+ rv = SECFailure;
+ goto done;
+ }
- for (i=0; i < (int)(entry->nemailAddrs); i++) {
- if (PORT_Strcmp(entry->emailAddrs[i],emailAddr) == 0) {
- index = i;
- }
+ 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];
- }
+ 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++;
- }
-
+ 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);
+done:
+ if (entry)
+ DestroyDBEntry((certDBEntry *)entry);
+ if (emailAddr)
+ PORT_Free(emailAddr);
return rv;
}
@@ -2742,45 +2735,47 @@ nsslowcert_UpdateSubjectEmailAddr(NSSLOWCERTCertDBHandle *dbhandle,
*/
static SECStatus
AddNicknameToSubject(NSSLOWCERTCertDBHandle *dbhandle,
- NSSLOWCERTCertificate *cert, char *nickname)
+ NSSLOWCERTCertificate *cert, char *nickname)
{
certDBEntrySubject *entry;
SECStatus rv;
-
- if ( nickname == NULL ) {
- return(SECFailure);
+
+ if (nickname == NULL) {
+ return (SECFailure);
}
-
- entry = ReadDBSubjectEntry(dbhandle,&cert->derSubject);
+
+ entry = ReadDBSubjectEntry(dbhandle, &cert->derSubject);
PORT_Assert(entry != NULL);
- if ( entry == NULL ) {
- goto loser;
+ if (entry == NULL) {
+ goto loser;
}
-
+
PORT_Assert(entry->nickname == NULL);
- if ( entry->nickname != NULL ) {
- goto loser;
+ if (entry->nickname != NULL) {
+ goto loser;
}
-
+
entry->nickname = PORT_ArenaStrdup(entry->common.arena, nickname);
-
- if ( entry->nickname == NULL ) {
- goto loser;
+
+ 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;
+ if (rv != SECSuccess) {
+ goto loser;
}
- return(SECSuccess);
+ DestroyDBEntry((certDBEntry *)entry);
+ return (SECSuccess);
loser:
- return(SECFailure);
+ DestroyDBEntry((certDBEntry *)entry);
+ return (SECFailure);
}
/*
@@ -2791,31 +2786,31 @@ NewDBVersionEntry(unsigned int flags)
{
PLArenaPool *arena = NULL;
certDBEntryVersion *entry;
-
+
arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
- if ( arena == NULL ) {
- PORT_SetError(SEC_ERROR_NO_MEMORY);
- goto loser;
+ 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;
+ 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);
+ return (entry);
loser:
- if ( arena ) {
- PORT_FreeArena(arena, PR_FALSE);
+ if (arena) {
+ PORT_FreeArena(arena, PR_FALSE);
}
-
- return(NULL);
+
+ return (NULL);
}
/*
@@ -2830,23 +2825,23 @@ ReadDBVersionEntry(NSSLOWCERTCertDBHandle *handle)
SECItem dbkey;
SECItem dbentry;
SECStatus rv;
-
+
arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
- if ( arena == NULL ) {
- PORT_SetError(SEC_ERROR_NO_MEMORY);
- goto loser;
+ 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;
+ 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;
+ if (entry == NULL) {
+ PORT_SetError(SEC_ERROR_NO_MEMORY);
+ goto loser;
}
entry->common.arena = arena;
entry->common.type = certDBEntryTypeVersion;
@@ -2854,31 +2849,30 @@ ReadDBVersionEntry(NSSLOWCERTCertDBHandle *handle)
/* 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;
+ if (dbkey.data == NULL) {
+ goto loser;
}
PORT_Memcpy(&dbkey.data[SEC_DB_KEY_HEADER_LEN], SEC_DB_VERSION_KEY,
- SEC_DB_VERSION_KEY_LEN);
+ SEC_DB_VERSION_KEY_LEN);
rv = ReadDBEntry(handle, &entry->common, &dbkey, &dbentry, tmparena);
if (rv != SECSuccess) {
- goto loser;
+ goto loser;
}
PORT_FreeArena(tmparena, PR_FALSE);
- return(entry);
-
+ return (entry);
+
loser:
- if ( tmparena ) {
- PORT_FreeArena(tmparena, PR_FALSE);
+ if (tmparena) {
+ PORT_FreeArena(tmparena, PR_FALSE);
}
- if ( arena ) {
- PORT_FreeArena(arena, PR_FALSE);
+ if (arena) {
+ PORT_FreeArena(arena, PR_FALSE);
}
-
- return(NULL);
-}
+ return (NULL);
+}
/*
* Encode a version entry into byte stream suitable for
@@ -2890,46 +2884,46 @@ WriteDBVersionEntry(NSSLOWCERTCertDBHandle *handle, certDBEntryVersion *entry)
SECItem dbitem, dbkey;
PLArenaPool *tmparena = NULL;
SECStatus rv;
-
+
tmparena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
- if ( tmparena == NULL ) {
- goto loser;
+ 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;
+ 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;
+ if (dbkey.data == NULL) {
+ goto loser;
}
PORT_Memcpy(&dbkey.data[SEC_DB_KEY_HEADER_LEN], SEC_DB_VERSION_KEY,
- SEC_DB_VERSION_KEY_LEN);
+ SEC_DB_VERSION_KEY_LEN);
/* now write it to the database */
rv = WriteDBEntry(handle, &entry->common, &dbkey, &dbitem);
- if ( rv != SECSuccess ) {
- goto loser;
+ if (rv != SECSuccess) {
+ goto loser;
}
-
+
PORT_FreeArena(tmparena, PR_FALSE);
- return(SECSuccess);
+ return (SECSuccess);
loser:
- if ( tmparena ) {
- PORT_FreeArena(tmparena, PR_FALSE);
+ if (tmparena) {
+ PORT_FreeArena(tmparena, PR_FALSE);
}
- return(SECFailure);
+ return (SECFailure);
}
/*
@@ -2941,243 +2935,242 @@ RemovePermSubjectNode(NSSLOWCERTCertificate *cert)
certDBEntrySubject *entry;
unsigned int i;
SECStatus rv;
-
- entry = ReadDBSubjectEntry(cert->dbhandle,&cert->derSubject);
- if ( entry == NULL ) {
- return(SECFailure);
+
+ 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;
- }
- }
+
+ 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);
+ /* 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);
+ return (rv);
}
/*
* add a cert to the perm subject list
*/
static SECStatus
-AddPermSubjectNode(certDBEntrySubject *entry, NSSLOWCERTCertificate *cert,
- char *nickname)
+AddPermSubjectNode(certDBEntrySubject *entry, NSSLOWCERTCertificate *cert,
+ char *nickname)
{
SECItem *newCertKeys, *newKeyIDs;
unsigned int i, new_i;
SECStatus rv;
unsigned int ncerts;
- PORT_Assert(entry);
+ PORT_Assert(entry);
ncerts = entry->ncerts;
-
- if ( nickname && entry->nickname ) {
- /* nicknames must be the same */
- PORT_Assert(PORT_Strcmp(nickname, entry->nickname) == 0);
+
+ 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);
- }
+ 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);
+ newKeyIDs = PORT_ArenaZNewArray(entry->common.arena, SECItem, ncerts + 1);
- if ( ( newCertKeys == NULL ) || ( newKeyIDs == NULL ) ) {
- return(SECFailure);
+ 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++;
+ 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);
+ &cert->certKey);
+ if (rv != SECSuccess) {
+ return (SECFailure);
}
rv = SECITEM_CopyItem(entry->common.arena, &newKeyIDs[new_i],
- &cert->subjectKeyID);
- if ( rv != SECSuccess ) {
- return(SECFailure);
+ &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];
+ 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;
+ entry->keyIDs = newKeyIDs;
/* set new count value */
entry->ncerts = new_i;
DeleteDBSubjectEntry(cert->dbhandle, &cert->derSubject);
rv = WriteDBSubjectEntry(cert->dbhandle, entry);
- return(rv);
+ return (rv);
}
-
SECStatus
nsslowcert_TraversePermCertsForSubject(NSSLOWCERTCertDBHandle *handle,
- SECItem *derSubject,
- NSSLOWCERTCertCallback cb, void *cbarg)
+ 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);
+ 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;
- }
+
+ 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);
+ return (rv);
}
int
nsslowcert_NumPermCertsForSubject(NSSLOWCERTCertDBHandle *handle,
- SECItem *derSubject)
+ SECItem *derSubject)
{
certDBEntrySubject *entry;
int ret;
-
+
entry = ReadDBSubjectEntry(handle, derSubject);
- if ( entry == NULL ) {
- return(SECFailure);
+ if (entry == NULL) {
+ return (SECFailure);
}
ret = entry->ncerts;
-
+
DestroyDBEntry((certDBEntry *)entry);
-
- return(ret);
+
+ return (ret);
}
SECStatus
nsslowcert_TraversePermCertsForNickname(NSSLOWCERTCertDBHandle *handle,
- char *nickname, NSSLOWCERTCertCallback cb, void *cbarg)
+ 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;
+ 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);
+ smentry = nsslowcert_ReadDBSMimeEntry(handle, nickname);
+ if (smentry) {
+ derSubject = &smentry->subjectName;
+ }
+ }
+
+ if (derSubject) {
+ rv = nsslowcert_TraversePermCertsForSubject(handle, derSubject,
+ cb, cbarg);
} else {
- rv = SECFailure;
+ rv = SECFailure;
}
- if ( nnentry ) {
- DestroyDBEntry((certDBEntry *)nnentry);
+ if (nnentry) {
+ DestroyDBEntry((certDBEntry *)nnentry);
}
- if ( smentry ) {
- DestroyDBEntry((certDBEntry *)smentry);
+ if (smentry) {
+ DestroyDBEntry((certDBEntry *)smentry);
}
-
- return(rv);
+
+ return (rv);
}
int
-nsslowcert_NumPermCertsForNickname(NSSLOWCERTCertDBHandle *handle,
- char *nickname)
+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);
+
+ if (entry) {
+ ret = nsslowcert_NumPermCertsForSubject(handle, &entry->subjectName);
+ DestroyDBEntry((certDBEntry *)entry);
} else {
- ret = 0;
+ ret = 0;
}
- return(ret);
+ return (ret);
}
/*
@@ -3185,36 +3178,36 @@ nsslowcert_NumPermCertsForNickname(NSSLOWCERTCertDBHandle *handle,
*/
static SECStatus
AddNicknameToPermCert(NSSLOWCERTCertDBHandle *dbhandle,
- NSSLOWCERTCertificate *cert, char *nickname)
+ NSSLOWCERTCertificate *cert, char *nickname)
{
certDBEntryCert *entry;
int rv;
entry = cert->dbEntry;
PORT_Assert(entry != NULL);
- if ( entry == NULL ) {
- goto loser;
+ if (entry == NULL) {
+ goto loser;
}
- pkcs11_freeNickname(entry->nickname,entry->nicknameSpace);
+ pkcs11_freeNickname(entry->nickname, entry->nicknameSpace);
entry->nickname = NULL;
- entry->nickname = pkcs11_copyNickname(nickname,entry->nicknameSpace,
- sizeof(entry->nicknameSpace));
+ entry->nickname = pkcs11_copyNickname(nickname, entry->nicknameSpace,
+ sizeof(entry->nicknameSpace));
rv = WriteDBCertEntry(dbhandle, entry);
- if ( rv ) {
- goto loser;
+ if (rv) {
+ goto loser;
}
- pkcs11_freeNickname(cert->nickname,cert->nicknameSpace);
+ pkcs11_freeNickname(cert->nickname, cert->nicknameSpace);
cert->nickname = NULL;
- cert->nickname = pkcs11_copyNickname(nickname,cert->nicknameSpace,
- sizeof(cert->nicknameSpace));
+ cert->nickname = pkcs11_copyNickname(nickname, cert->nicknameSpace,
+ sizeof(cert->nicknameSpace));
+
+ return (SECSuccess);
- return(SECSuccess);
-
loser:
- return(SECFailure);
+ return (SECFailure);
}
/*
@@ -3223,75 +3216,76 @@ loser:
*/
SECStatus
nsslowcert_AddPermNickname(NSSLOWCERTCertDBHandle *dbhandle,
- NSSLOWCERTCertificate *cert, char *nickname)
+ 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;
- }
+ 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;
- }
- }
+ /* 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);
+ DestroyDBEntry((certDBEntry *)entry);
}
if (nicknameEntry) {
- DestroyDBEntry((certDBEntry *)nicknameEntry);
+ DestroyDBEntry((certDBEntry *)nicknameEntry);
}
nsslowcert_UnlockDB(dbhandle);
- return(rv);
+ return (rv);
}
static certDBEntryCert *
AddCertToPermDB(NSSLOWCERTCertDBHandle *handle, NSSLOWCERTCertificate *cert,
- char *nickname, NSSLOWCERTCertTrust *trust)
+ char *nickname, NSSLOWCERTCertTrust *trust)
{
certDBEntryCert *certEntry = NULL;
certDBEntryNickname *nicknameEntry = NULL;
@@ -3300,103 +3294,103 @@ AddCertToPermDB(NSSLOWCERTCertDBHandle *handle, NSSLOWCERTCertificate *cert,
SECStatus rv;
PRBool donnentry = PR_FALSE;
- if ( nickname ) {
- donnentry = PR_TRUE;
+ if (nickname) {
+ donnentry = PR_TRUE;
}
subjectEntry = ReadDBSubjectEntry(handle, &cert->derSubject);
-
- if ( subjectEntry && subjectEntry->nickname ) {
- donnentry = PR_FALSE;
- nickname = subjectEntry->nickname;
+
+ if (subjectEntry && subjectEntry->nickname) {
+ donnentry = PR_FALSE;
+ nickname = subjectEntry->nickname;
}
-
+
certEntry = NewDBCertEntry(&cert->derCert, nickname, trust, 0);
- if ( certEntry == NULL ) {
- goto loser;
+ if (certEntry == NULL) {
+ goto loser;
}
-
- if ( donnentry ) {
- nicknameEntry = NewDBNicknameEntry(nickname, &cert->derSubject, 0);
- if ( nicknameEntry == 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;
+ if (rv != SECSuccess) {
+ goto loser;
}
state = 1;
-
- if ( nicknameEntry ) {
- rv = WriteDBNicknameEntry(handle, nicknameEntry);
- if ( rv != SECSuccess ) {
- goto loser;
- }
- }
-
+
+ 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;
- }
+ 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;
- }
- }
-
+ /* 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 (nicknameEntry) {
+ DestroyDBEntry((certDBEntry *)nicknameEntry);
}
-
- if ( subjectEntry ) {
- DestroyDBEntry((certDBEntry *)subjectEntry);
+
+ if (subjectEntry) {
+ DestroyDBEntry((certDBEntry *)subjectEntry);
}
- return(certEntry);
+ return (certEntry);
loser:
/* don't leave partial entry in the database */
- if ( state > 0 ) {
- DeleteDBCertEntry(handle, &cert->certKey);
+ if (state > 0) {
+ DeleteDBCertEntry(handle, &cert->certKey);
}
- if ( ( state > 1 ) && donnentry ) {
- DeleteDBNicknameEntry(handle, nickname);
+ if ((state > 1) && donnentry) {
+ DeleteDBNicknameEntry(handle, nickname);
}
- if ( certEntry ) {
- DestroyDBEntry((certDBEntry *)certEntry);
+ if (certEntry) {
+ DestroyDBEntry((certDBEntry *)certEntry);
}
- if ( nicknameEntry ) {
- DestroyDBEntry((certDBEntry *)nicknameEntry);
+ if (nicknameEntry) {
+ DestroyDBEntry((certDBEntry *)nicknameEntry);
}
- if ( subjectEntry ) {
- DestroyDBEntry((certDBEntry *)subjectEntry);
+ if (subjectEntry) {
+ DestroyDBEntry((certDBEntry *)subjectEntry);
}
- return(NULL);
+ return (NULL);
}
/* forward declaration */
@@ -3413,10 +3407,9 @@ UpdateV7DB(NSSLOWCERTCertDBHandle *handle, DB *updatedb);
static SECStatus
UpdateV8DB(NSSLOWCERTCertDBHandle *handle, DB *updatedb)
{
- return UpdateV7DB(handle,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
@@ -3437,128 +3430,128 @@ UpdateV7DB(NSSLOWCERTCertDBHandle *handle, DB *updatedb)
certDBEntrySMime smimeEntry;
SECStatus rv;
- ret = (* updatedb->seq)(updatedb, &key, &data, R_FIRST);
+ ret = (*updatedb->seq)(updatedb, &key, &data, R_FIRST);
- if ( ret ) {
- return(SECFailure);
+ 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 );
+ 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);
+ ret = (*updatedb->seq)(updatedb, &key, &data, R_FIRST);
- if ( ret ) {
- return(SECFailure);
+ 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;
- }
+ 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);
+ 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);
+ handle->dbVerify = PR_TRUE;
+ return (SECSuccess);
}
/*
@@ -3577,228 +3570,236 @@ UpdateV6DB(NSSLOWCERTCertDBHandle *handle, DB *updatedb)
certDBEntrySMime *emailEntry = NULL;
char *nickname;
char *emailAddr;
-
+
/*
* 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);
+ 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 );
+ 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;
+ }
+ if (ret) {
+ return SECFailure;
+ }
+ }
+ }
+ } while ((*updatedb->seq)(updatedb, &key, &data, R_NEXT) == 0);
ret = certdb_Sync(handle->permCertDB, 0);
+ if (ret) {
+ return SECFailure;
+ }
- ret = (* updatedb->seq)(updatedb, &key, &data, R_FIRST);
- if ( ret ) {
- return(SECFailure);
+ 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);
- (void)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;
- (void)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 );
+ 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);
+ (void)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;
+ (void)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);
+ if (ret) {
+ return SECFailure;
+ }
- (* updatedb->close)(updatedb);
- return(SECSuccess);
+ (*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;
+ 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;
+ 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);
+ &cert->dbEntry->trust);
+ if (entry) {
+ DestroyDBEntry((certDBEntry *)entry);
}
-
- return(SECSuccess);
+
+ return (SECSuccess);
}
static SECStatus
UpdateV5DB(NSSLOWCERTCertDBHandle *handle, DB *updatedb)
{
NSSLOWCERTCertDBHandle updatehandle;
-
+
updatehandle.permCertDB = updatedb;
updatehandle.dbMon = PZ_NewMonitor(nssILockCertDB);
updatehandle.dbVerify = 0;
- updatehandle.ref = 1; /* prevent premature close */
-
+ updatehandle.ref = 1; /* prevent premature close */
+
(void)nsslowcert_TraversePermCerts(&updatehandle, updateV5Callback,
- (void *)handle);
-
+ (void *)handle);
+
PZ_DestroyMonitor(updatehandle.dbMon);
- (* updatedb->close)(updatedb);
- return(SECSuccess);
+ (*updatedb->close)(updatedb);
+ return (SECSuccess);
}
static PRBool
-isV4DB(DB *db) {
- DBT key,data;
+isV4DB(DB *db)
+{
+ DBT key, data;
int ret;
key.data = "Version";
@@ -3806,11 +3807,11 @@ isV4DB(DB *db) {
ret = (*db->get)(db, &key, &data, 0);
if (ret) {
- return PR_FALSE;
+ return PR_FALSE;
}
- if ((data.size == 1) && (*(unsigned char *)data.data <= 4)) {
- return PR_TRUE;
+ if ((data.size == 1) && (*(unsigned char *)data.data <= 4)) {
+ return PR_TRUE;
}
return PR_FALSE;
@@ -3822,52 +3823,44 @@ UpdateV4DB(NSSLOWCERTCertDBHandle *handle, DB *updatedb)
DBT key, data;
certDBEntryCert *entry, *entry2;
int ret;
- PLArenaPool *arena = NULL;
NSSLOWCERTCertificate *cert;
- ret = (* updatedb->seq)(updatedb, &key, &data, R_FIRST);
+ ret = (*updatedb->seq)(updatedb, &key, &data, R_FIRST);
- if ( ret ) {
- return(SECFailure);
+ 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 );
+ 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);
+ (*updatedb->close)(updatedb);
+ return (SECSuccess);
}
-
/*
* return true if a database key conflict exists
*/
@@ -3881,40 +3874,40 @@ nsslowcert_CertDBKeyConflict(SECItem *derCert, NSSLOWCERTCertDBHandle *handle)
SECItem keyitem;
PLArenaPool *arena = NULL;
SECItem derKey;
-
+
arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
- if ( arena == NULL ) {
- goto loser;
+ if (arena == NULL) {
+ goto loser;
}
/* get the db key of the cert */
rv = nsslowcert_KeyFromDERCert(arena, derCert, &derKey);
- if ( rv != SECSuccess ) {
+ if (rv != SECSuccess) {
goto loser;
}
rv = EncodeDBCertKey(&derKey, arena, &keyitem);
- if ( rv != SECSuccess ) {
- goto loser;
+ 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;
+ if (ret == 0) {
+ goto loser;
}
PORT_FreeArena(arena, PR_FALSE);
-
- return(PR_FALSE);
+
+ return (PR_FALSE);
loser:
- if ( arena ) {
- PORT_FreeArena(arena, PR_FALSE);
+ if (arena) {
+ PORT_FreeArena(arena, PR_FALSE);
}
-
- return(PR_TRUE);
+
+ return (PR_TRUE);
}
/*
@@ -3924,40 +3917,40 @@ loser:
*/
static PRBool
nsslowcert_CertNicknameConflict(char *nickname, SECItem *derSubject,
- NSSLOWCERTCertDBHandle *handle)
+ NSSLOWCERTCertDBHandle *handle)
{
PRBool rv;
certDBEntryNickname *entry;
-
- if ( nickname == NULL ) {
- return(PR_FALSE);
+
+ if (nickname == NULL) {
+ return (PR_FALSE);
}
-
+
entry = ReadDBNicknameEntry(handle, nickname);
- if ( entry == NULL ) {
- /* no entry for this nickname, so no conflict */
- return(PR_FALSE);
+ 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;
+ if (SECITEM_CompareItem(derSubject, &entry->subjectName) == SECEqual) {
+ /* if subject names are the same, then no conflict */
+ rv = PR_FALSE;
}
DestroyDBEntry((certDBEntry *)entry);
- return(rv);
+ 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)
+#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)
+#define NO_RDONLY O_RDONLY
+#define NO_RDWR O_RDWR
+#define NO_CREATE (O_RDWR | O_CREAT | O_TRUNC)
#endif
/*
@@ -3966,20 +3959,20 @@ nsslowcert_CertNicknameConflict(char *nickname, SECItem *derSubject,
static DB *
nsslowcert_openolddb(NSSLOWCERTDBNameFunc namecb, void *cbarg, int version)
{
- char * tmpname;
+ 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);
+ 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)
+openNewCertDB(const char *appName, const char *prefix, const char *certdbname,
+ NSSLOWCERTCertDBHandle *handle, NSSLOWCERTDBNameFunc namecb, void *cbarg)
{
SECStatus rv;
certDBEntryVersion *versionEntry = NULL;
@@ -3987,66 +3980,65 @@ openNewCertDB(const char *appName, const char *prefix, const char *certdbname,
int status = RDB_FAIL;
if (appName) {
- handle->permCertDB=rdbopen( appName, prefix, "cert", NO_CREATE, &status);
+ handle->permCertDB = rdbopen(appName, prefix, "cert", NO_CREATE, &status);
} else {
- handle->permCertDB=dbsopen(certdbname, NO_CREATE, 0600, DB_HASH, 0);
+ 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;
+ if (handle->permCertDB == 0) {
+ return status == RDB_RETRY ? SECWouldBlock : SECFailure;
}
/* Verify version number; */
versionEntry = NewDBVersionEntry(0);
- if ( versionEntry == NULL ) {
- rv = SECFailure;
- goto loser;
+ if (versionEntry == NULL) {
+ rv = SECFailure;
+ goto loser;
}
-
+
rv = WriteDBVersionEntry(handle, versionEntry);
DestroyDBEntry((certDBEntry *)versionEntry);
- if ( rv != SECSuccess ) {
- goto loser;
+ 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);
- }
+ (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)
+nsslowcert_GetVersionNumber(NSSLOWCERTCertDBHandle *handle)
{
certDBEntryVersion *versionEntry = NULL;
int version = 0;
- versionEntry = ReadDBVersionEntry(handle);
- if ( versionEntry == NULL ) {
- return 0;
+ versionEntry = ReadDBVersionEntry(handle);
+ if (versionEntry == NULL) {
+ return 0;
}
version = versionEntry->common.version;
DestroyDBEntry((certDBEntry *)versionEntry);
@@ -4059,17 +4051,17 @@ nsslowcert_GetVersionNumber( NSSLOWCERTCertDBHandle *handle)
*/
static SECStatus
nsslowcert_OpenPermCertDB(NSSLOWCERTCertDBHandle *handle, PRBool readOnly,
- const char *appName, const char *prefix,
- NSSLOWCERTDBNameFunc namecb, void *cbarg)
+ 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);
+
+ certdbname = (*namecb)(cbarg, CERT_DB_FILE_VERSION);
+ if (certdbname == NULL) {
+ return (SECFailure);
}
openflags = readOnly ? NO_RDONLY : NO_RDWR;
@@ -4078,66 +4070,66 @@ nsslowcert_OpenPermCertDB(NSSLOWCERTCertDBHandle *handle, PRBool readOnly,
* first open the permanent file based database.
*/
if (appName) {
- handle->permCertDB = rdbopen( appName, prefix, "cert", openflags, NULL);
+ handle->permCertDB = rdbopen(appName, prefix, "cert", openflags, NULL);
} else {
- handle->permCertDB = dbsopen( certdbname, openflags, 0600, DB_HASH, 0 );
+ 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;
- }
+ 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;
- }
+ 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;
+
+ if (handle->permCertDB) {
+ certdb_Close(handle->permCertDB);
+ handle->permCertDB = 0;
}
PORT_Free(certdbname);
- return(SECFailure);
+ return (SECFailure);
}
/*
@@ -4150,16 +4142,15 @@ DeletePermCert(NSSLOWCERTCertificate *cert)
SECStatus ret;
ret = SECSuccess;
-
+
rv = DeleteDBCertEntry(cert->dbhandle, &cert->certKey);
- if ( rv != SECSuccess ) {
- ret = SECFailure;
+ if (rv != SECSuccess) {
+ ret = SECFailure;
}
-
- rv = RemovePermSubjectNode(cert);
+ rv = RemovePermSubjectNode(cert);
- return(ret);
+ return (ret);
}
/*
@@ -4169,7 +4160,7 @@ SECStatus
nsslowcert_DeletePermCertificate(NSSLOWCERTCertificate *cert)
{
SECStatus rv;
-
+
nsslowcert_LockDB(cert->dbhandle);
/* delete the records from the permanent database */
@@ -4179,9 +4170,9 @@ nsslowcert_DeletePermCertificate(NSSLOWCERTCertificate *cert)
DestroyDBEntry((certDBEntry *)cert->dbEntry);
cert->dbEntry = NULL;
cert->trust = NULL;
-
+
nsslowcert_UnlockDB(cert->dbhandle);
- return(rv);
+ return (rv);
}
/*
@@ -4190,10 +4181,10 @@ nsslowcert_DeletePermCertificate(NSSLOWCERTCertificate *cert)
*/
SECStatus
nsslowcert_TraverseDBEntries(NSSLOWCERTCertDBHandle *handle,
- certDBEntryType type,
- SECStatus (* callback)(SECItem *data, SECItem *key,
- certDBEntryType type, void *pdata),
- void *udata )
+ certDBEntryType type,
+ SECStatus (*callback)(SECItem *data, SECItem *key,
+ certDBEntryType type, void *pdata),
+ void *udata)
{
DBT data;
DBT key;
@@ -4203,34 +4194,34 @@ nsslowcert_TraverseDBEntries(NSSLOWCERTCertDBHandle *handle,
SECItem keyitem;
unsigned char *buf;
unsigned char *keybuf;
-
+
ret = certdb_Seq(handle->permCertDB, &key, &data, R_FIRST);
- if ( ret ) {
- return(SECFailure);
+ if (ret) {
+ return (SECFailure);
}
- /* here, ret is zero and rv is SECSuccess.
+ /* 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;
+ 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.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,
+ /* 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);
@@ -4245,21 +4236,21 @@ static NSSLOWCERTCertificate *
DecodeACert(NSSLOWCERTCertDBHandle *handle, certDBEntryCert *entry)
{
NSSLOWCERTCertificate *cert = NULL;
-
- cert = nsslowcert_DecodeDERCertificate(&entry->derCert, entry->nickname );
-
- if ( cert == NULL ) {
- goto loser;
+
+ cert = nsslowcert_DecodeDERCertificate(&entry->derCert, entry->nickname);
+
+ if (cert == NULL) {
+ goto loser;
}
cert->dbhandle = handle;
cert->dbEntry = entry;
cert->trust = &entry->trust;
- return(cert);
+ return (cert);
loser:
- return(0);
+ return (0);
}
static NSSLOWCERTTrust *
@@ -4270,13 +4261,13 @@ CreateTrust(void)
nsslowcert_LockFreeList();
trust = trustListHead;
if (trust) {
- trustListCount--;
- trustListHead = trust->next;
+ trustListCount--;
+ trustListHead = trust->next;
}
PORT_Assert(trustListCount >= 0);
nsslowcert_UnlockFreeList();
if (trust) {
- return trust;
+ return trust;
}
return PORT_ZNew(NSSLOWCERTTrust);
@@ -4289,37 +4280,37 @@ DestroyTrustFreeList(void)
nsslowcert_LockFreeList();
while (NULL != (trust = trustListHead)) {
- trustListCount--;
- trustListHead = trust->next;
- PORT_Free(trust);
+ trustListCount--;
+ trustListHead = trust->next;
+ PORT_Free(trust);
}
PORT_Assert(!trustListCount);
trustListCount = 0;
nsslowcert_UnlockFreeList();
}
-static NSSLOWCERTTrust *
-DecodeTrustEntry(NSSLOWCERTCertDBHandle *handle, certDBEntryCert *entry,
+static NSSLOWCERTTrust *
+DecodeTrustEntry(NSSLOWCERTCertDBHandle *handle, certDBEntryCert *entry,
const SECItem *dbKey)
{
NSSLOWCERTTrust *trust = CreateTrust();
if (trust == NULL) {
- return trust;
+ return trust;
}
trust->dbhandle = handle;
trust->dbEntry = entry;
- trust->dbKey.data = pkcs11_copyStaticData(dbKey->data,dbKey->len,
- trust->dbKeySpace, sizeof(trust->dbKeySpace));
+ trust->dbKey.data = pkcs11_copyStaticData(dbKey->data, dbKey->len,
+ trust->dbKeySpace, sizeof(trust->dbKeySpace));
if (!trust->dbKey.data) {
- PORT_Free(trust);
- return NULL;
+ PORT_Free(trust);
+ return NULL;
}
trust->dbKey.len = dbKey->len;
-
+
trust->trust = &entry->trust;
trust->derCert = &entry->derCert;
- return(trust);
+ return (trust);
}
typedef struct {
@@ -4340,43 +4331,47 @@ certcallback(SECItem *dbdata, SECItem *dbkey, certDBEntryType type, void *data)
SECItem entryitem;
NSSLOWCERTCertificate *cert;
PLArenaPool *arena = NULL;
-
+
arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
- if ( arena == NULL ) {
- goto loser;
+ if (arena == NULL) {
+ goto loser;
}
-
+
entry = (certDBEntryCert *)PORT_ArenaAlloc(arena, sizeof(certDBEntryCert));
+ if (!entry) {
+ PORT_SetError(SEC_ERROR_NO_MEMORY);
+ goto loser;
+ }
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;
+ 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);
+ rv = (*mystate->certfunc)(cert, dbkey, mystate->data);
/* arena stored in entry destroyed by nsslowcert_DestroyCertificate */
nsslowcert_DestroyCertificateNoLocking(cert);
- return(rv);
+ return (rv);
loser:
- if ( arena ) {
- PORT_FreeArena(arena, PR_FALSE);
+ if (arena) {
+ PORT_FreeArena(arena, PR_FALSE);
}
- return(SECFailure);
+ return (SECFailure);
}
/*
@@ -4385,10 +4380,10 @@ loser:
*/
static SECStatus
TraversePermCertsNoLocking(NSSLOWCERTCertDBHandle *handle,
- SECStatus (* certfunc)(NSSLOWCERTCertificate *cert,
- SECItem *k,
- void *pdata),
- void *udata )
+ SECStatus (*certfunc)(NSSLOWCERTCertificate *cert,
+ SECItem *k,
+ void *pdata),
+ void *udata)
{
SECStatus rv;
PermCertCallbackState mystate;
@@ -4397,9 +4392,9 @@ TraversePermCertsNoLocking(NSSLOWCERTCertDBHandle *handle,
mystate.handle = handle;
mystate.data = udata;
rv = nsslowcert_TraverseDBEntries(handle, certDBEntryTypeCert, certcallback,
- (void *)&mystate);
-
- return(rv);
+ (void *)&mystate);
+
+ return (rv);
}
/*
@@ -4408,20 +4403,18 @@ TraversePermCertsNoLocking(NSSLOWCERTCertDBHandle *handle,
*/
SECStatus
nsslowcert_TraversePermCerts(NSSLOWCERTCertDBHandle *handle,
- SECStatus (* certfunc)(NSSLOWCERTCertificate *cert, SECItem *k,
- void *pdata),
- void *udata )
+ 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);
-}
-
+ return (rv);
+}
/*
* Close the database
@@ -4429,16 +4422,16 @@ nsslowcert_TraversePermCerts(NSSLOWCERTCertDBHandle *handle,
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);
+ 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;
}
@@ -4450,18 +4443,18 @@ SECStatus
nsslowcert_GetCertTrust(NSSLOWCERTCertificate *cert, NSSLOWCERTCertTrust *trust)
{
SECStatus rv;
-
+
nsslowcert_LockCertTrust(cert);
-
- if ( cert->trust == NULL ) {
- rv = SECFailure;
+
+ if (cert->trust == NULL) {
+ rv = SECFailure;
} else {
- *trust = *cert->trust;
- rv = SECSuccess;
+ *trust = *cert->trust;
+ rv = SECSuccess;
}
-
+
nsslowcert_UnlockCertTrust(cert);
- return(rv);
+ return (rv);
}
/*
@@ -4469,48 +4462,47 @@ nsslowcert_GetCertTrust(NSSLOWCERTCertificate *cert, NSSLOWCERTCertTrust *trust)
* in the database.
*/
SECStatus
-nsslowcert_ChangeCertTrust(NSSLOWCERTCertDBHandle *handle,
- NSSLOWCERTCertificate *cert, NSSLOWCERTCertTrust *trust)
+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;
+ if (cert->trust == NULL) {
+ ret = SECFailure;
+ goto done;
}
*cert->trust = *trust;
- if ( cert->dbEntry == NULL ) {
- ret = SECSuccess; /* not in permanent database */
- goto done;
+ 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;
+ if (rv) {
+ ret = SECFailure;
+ goto done;
}
ret = SECSuccess;
-
+
done:
nsslowcert_UnlockCertTrust(cert);
nsslowcert_UnlockDB(handle);
- return(ret);
+ return (ret);
}
-
static SECStatus
nsslowcert_UpdatePermCert(NSSLOWCERTCertDBHandle *dbhandle,
- NSSLOWCERTCertificate *cert, char *nickname, NSSLOWCERTCertTrust *trust)
+ NSSLOWCERTCertificate *cert, char *nickname, NSSLOWCERTCertTrust *trust)
{
char *oldnn;
certDBEntryCert *entry;
@@ -4521,46 +4513,47 @@ nsslowcert_UpdatePermCert(NSSLOWCERTCertDBHandle *dbhandle,
/* don't add a conflicting nickname */
conflict = nsslowcert_CertNicknameConflict(nickname, &cert->derSubject,
- dbhandle);
- if ( conflict ) {
- ret = SECFailure;
- goto done;
+ 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;
+
+ if (entry == NULL) {
+ ret = SECFailure;
+ goto done;
}
- pkcs11_freeNickname(oldnn,cert->nicknameSpace);
-
+ pkcs11_freeNickname(oldnn, cert->nicknameSpace);
+
cert->nickname = (entry->nickname) ? pkcs11_copyNickname(entry->nickname,
- cert->nicknameSpace, sizeof(cert->nicknameSpace)) : NULL;
+ cert->nicknameSpace, sizeof(cert->nicknameSpace))
+ : NULL;
cert->trust = &entry->trust;
cert->dbEntry = entry;
-
+
ret = SECSuccess;
done:
- return(ret);
+ return (ret);
}
SECStatus
nsslowcert_AddPermCert(NSSLOWCERTCertDBHandle *dbhandle,
- NSSLOWCERTCertificate *cert, char *nickname, NSSLOWCERTCertTrust *trust)
+ NSSLOWCERTCertificate *cert, char *nickname, NSSLOWCERTCertTrust *trust)
{
SECStatus ret;
nsslowcert_LockDB(dbhandle);
ret = nsslowcert_UpdatePermCert(dbhandle, cert, nickname, trust);
-
+
nsslowcert_UnlockDB(dbhandle);
- return(ret);
+ return (ret);
}
/*
@@ -4569,21 +4562,21 @@ nsslowcert_AddPermCert(NSSLOWCERTCertDBHandle *dbhandle,
*/
SECStatus
nsslowcert_OpenCertDB(NSSLOWCERTCertDBHandle *handle, PRBool readOnly,
- const char *appName, const char *prefix,
- NSSLOWCERTDBNameFunc namecb, void *cbarg, PRBool openVolatile)
+ 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;
+ rv = nsslowcert_OpenPermCertDB(handle, readOnly, appName, prefix,
+ namecb, cbarg);
+ if (rv) {
+ goto loser;
}
return (SECSuccess);
@@ -4594,13 +4587,14 @@ loser:
handle->dbMon = NULL;
}
PORT_SetError(SEC_ERROR_BAD_DATABASE);
- return(SECFailure);
+ return (SECFailure);
}
PRBool
nsslowcert_needDBVerify(NSSLOWCERTCertDBHandle *handle)
{
- if (!handle) return PR_FALSE;
+ if (!handle)
+ return PR_FALSE;
return handle->dbVerify;
}
@@ -4610,7 +4604,6 @@ nsslowcert_setDBVerify(NSSLOWCERTCertDBHandle *handle, PRBool value)
handle->dbVerify = value;
}
-
/*
* Lookup a certificate in the databases.
*/
@@ -4620,34 +4613,34 @@ FindCertByKey(NSSLOWCERTCertDBHandle *handle, const SECItem *certKey, PRBool loc
NSSLOWCERTCertificate *cert = NULL;
certDBEntryCert *entry;
PRBool locked = PR_FALSE;
-
- if ( lockdb ) {
- locked = PR_TRUE;
- nsslowcert_LockDB(handle);
+
+ if (lockdb) {
+ locked = PR_TRUE;
+ nsslowcert_LockDB(handle);
}
-
+
/* find in perm database */
entry = ReadDBCertEntry(handle, certKey);
-
- if ( entry == NULL ) {
- goto loser;
+
+ if (entry == NULL) {
+ goto loser;
}
-
- /* inherit entry */
+
+ /* inherit entry */
cert = DecodeACert(handle, entry);
loser:
if (cert == NULL) {
- if (entry) {
- DestroyDBEntry((certDBEntry *)entry);
- }
+ if (entry) {
+ DestroyDBEntry((certDBEntry *)entry);
+ }
}
- if ( locked ) {
- nsslowcert_UnlockDB(handle);
+ if (locked) {
+ nsslowcert_UnlockDB(handle);
}
-
- return(cert);
+
+ return (cert);
}
/*
@@ -4659,38 +4652,38 @@ FindTrustByKey(NSSLOWCERTCertDBHandle *handle, const SECItem *certKey, PRBool lo
NSSLOWCERTTrust *trust = NULL;
certDBEntryCert *entry;
PRBool locked = PR_FALSE;
-
- if ( lockdb ) {
- locked = PR_TRUE;
- nsslowcert_LockDB(handle);
+
+ if (lockdb) {
+ locked = PR_TRUE;
+ nsslowcert_LockDB(handle);
}
-
+
/* find in perm database */
entry = ReadDBCertEntry(handle, certKey);
-
- if ( entry == NULL ) {
- goto loser;
+
+ if (entry == NULL) {
+ goto loser;
}
if (!nsslowcert_hasTrust(&entry->trust)) {
- goto loser;
+ goto loser;
}
-
- /* inherit entry */
+
+ /* inherit entry */
trust = DecodeTrustEntry(handle, entry, certKey);
loser:
if (trust == NULL) {
- if (entry) {
- DestroyDBEntry((certDBEntry *)entry);
- }
+ if (entry) {
+ DestroyDBEntry((certDBEntry *)entry);
+ }
}
- if ( locked ) {
- nsslowcert_UnlockDB(handle);
+ if (locked) {
+ nsslowcert_UnlockDB(handle);
}
-
- return(trust);
+
+ return (trust);
}
/*
@@ -4699,7 +4692,7 @@ loser:
NSSLOWCERTCertificate *
nsslowcert_FindCertByKey(NSSLOWCERTCertDBHandle *handle, const SECItem *certKey)
{
- return(FindCertByKey(handle, certKey, PR_FALSE));
+ return (FindCertByKey(handle, certKey, PR_FALSE));
}
/*
@@ -4708,7 +4701,7 @@ nsslowcert_FindCertByKey(NSSLOWCERTCertDBHandle *handle, const SECItem *certKey)
NSSLOWCERTTrust *
nsslowcert_FindTrustByKey(NSSLOWCERTCertDBHandle *handle, const SECItem *certKey)
{
- return(FindTrustByKey(handle, certKey, PR_FALSE));
+ return (FindTrustByKey(handle, certKey, PR_FALSE));
}
/*
@@ -4726,43 +4719,43 @@ nsslowcert_FindCertByIssuerAndSN(NSSLOWCERTCertDBHandle *handle, NSSLOWCERTIssue
int index = 0;
/* automatically detect DER encoded serial numbers and remove the der
- * encoding since the database expects unencoded data.
+ * 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.. */
- int 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;
- }
+ /* remove the der encoding of the serial number before generating the
+ * key.. */
+ int 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.data = (unsigned char *)PORT_Alloc(sn->len + issuer->len);
certKey.len = data_len + issuer->len;
-
- if ( certKey.data == NULL ) {
- return(0);
+
+ if (certKey.data == NULL) {
+ return (0);
}
/* first try the serial number as hand-decoded above*/
@@ -4770,12 +4763,12 @@ nsslowcert_FindCertByIssuerAndSN(NSSLOWCERTCertDBHandle *handle, NSSLOWCERTIssue
PORT_Memcpy(certKey.data, &sn->data[index], data_len);
/* copy the issuer */
- PORT_Memcpy( &certKey.data[data_len],issuer->data,issuer->len);
+ PORT_Memcpy(&certKey.data[data_len], issuer->data, issuer->len);
cert = nsslowcert_FindCertByKey(handle, &certKey);
if (cert) {
- PORT_Free(certKey.data);
- return (cert);
+ PORT_Free(certKey.data);
+ return (cert);
}
/* didn't find it, try by der encoded serial number */
@@ -4783,14 +4776,14 @@ nsslowcert_FindCertByIssuerAndSN(NSSLOWCERTCertDBHandle *handle, NSSLOWCERTIssue
PORT_Memcpy(certKey.data, sn->data, sn->len);
/* copy the issuer */
- PORT_Memcpy( &certKey.data[sn->len], issuer->data, issuer->len);
+ 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);
+
+ return (cert);
}
/*
@@ -4798,8 +4791,8 @@ nsslowcert_FindCertByIssuerAndSN(NSSLOWCERTCertDBHandle *handle, NSSLOWCERTIssue
* associated cert in the database.
*/
NSSLOWCERTTrust *
-nsslowcert_FindTrustByIssuerAndSN(NSSLOWCERTCertDBHandle *handle,
- NSSLOWCERTIssuerAndSN *issuerAndSN)
+nsslowcert_FindTrustByIssuerAndSN(NSSLOWCERTCertDBHandle *handle,
+ NSSLOWCERTIssuerAndSN *issuerAndSN)
{
SECItem certKey;
SECItem *sn = &issuerAndSN->serialNumber;
@@ -4811,48 +4804,48 @@ nsslowcert_FindTrustByIssuerAndSN(NSSLOWCERTCertDBHandle *handle,
int len;
/* automatically detect DER encoded serial numbers and remove the der
- * encoding since the database expects unencoded data.
+ * 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.. */
- int 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;
- }
+ /* remove the der encoding of the serial number before generating the
+ * key.. */
+ int 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);
+ if (len > sizeof(keyBuf)) {
+ certKey.data = (unsigned char *)PORT_Alloc(len);
} else {
- certKey.data = keyBuf;
+ certKey.data = keyBuf;
}
-
- if ( certKey.data == NULL ) {
- return(0);
+
+ if (certKey.data == NULL) {
+ return (0);
}
/* first try the serial number as hand-decoded above*/
@@ -4860,17 +4853,17 @@ nsslowcert_FindTrustByIssuerAndSN(NSSLOWCERTCertDBHandle *handle,
PORT_Memcpy(certKey.data, &sn->data[index], data_len);
/* copy the issuer */
- PORT_Memcpy( &certKey.data[data_len],issuer->data,issuer->len);
+ PORT_Memcpy(&certKey.data[data_len], issuer->data, issuer->len);
trust = nsslowcert_FindTrustByKey(handle, &certKey);
if (trust) {
- pkcs11_freeStaticData(certKey.data, keyBuf);
- return (trust);
+ pkcs11_freeStaticData(certKey.data, keyBuf);
+ return (trust);
}
if (index == 0) {
- pkcs11_freeStaticData(certKey.data, keyBuf);
- return NULL;
+ pkcs11_freeStaticData(certKey.data, keyBuf);
+ return NULL;
}
/* didn't find it, try by der encoded serial number */
@@ -4878,14 +4871,14 @@ nsslowcert_FindTrustByIssuerAndSN(NSSLOWCERTCertDBHandle *handle,
PORT_Memcpy(certKey.data, sn->data, sn->len);
/* copy the issuer */
- PORT_Memcpy( &certKey.data[sn->len], issuer->data, issuer->len);
+ 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);
+
+ return (trust);
}
/*
@@ -4898,25 +4891,25 @@ nsslowcert_FindCertByDERCert(NSSLOWCERTCertDBHandle *handle, SECItem *derCert)
SECItem certKey;
SECStatus rv;
NSSLOWCERTCertificate *cert = NULL;
-
+
/* create a scratch arena */
arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
- if ( arena == NULL ) {
- return(NULL);
+ if (arena == NULL) {
+ return (NULL);
}
-
+
/* extract the database key from the cert */
rv = nsslowcert_KeyFromDERCert(arena, derCert, &certKey);
- if ( rv != SECSuccess ) {
- goto loser;
+ if (rv != SECSuccess) {
+ goto loser;
}
/* find the certificate */
cert = nsslowcert_FindCertByKey(handle, &certKey);
-
+
loser:
PORT_FreeArena(arena, PR_FALSE);
- return(cert);
+ return (cert);
}
static void
@@ -4924,56 +4917,56 @@ DestroyCertificate(NSSLOWCERTCertificate *cert, PRBool lockdb)
{
int refCount;
NSSLOWCERTCertDBHandle *handle;
-
- if ( cert ) {
- handle = cert->dbhandle;
+ 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);
- }
+ /*
+ * 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;
+ PORT_Assert(cert->referenceCount > 0);
+ refCount = --cert->referenceCount;
nsslowcert_UnlockCertRefCount(cert);
- if ( refCount == 0 ) {
- certDBEntryCert *entry = cert->dbEntry;
+ if (refCount == 0) {
+ certDBEntryCert *entry = cert->dbEntry;
- if ( entry ) {
- DestroyDBEntry((certDBEntry *)entry);
+ 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;
+ 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);
}
- if ( lockdb && handle ) {
- nsslowcert_UnlockDB(handle);
- }
}
return;
@@ -4986,13 +4979,13 @@ nsslowcert_CreateCert(void)
nsslowcert_LockFreeList();
cert = certListHead;
if (cert) {
- certListHead = cert->next;
- certListCount--;
+ certListHead = cert->next;
+ certListCount--;
}
PORT_Assert(certListCount >= 0);
nsslowcert_UnlockFreeList();
if (cert) {
- return cert;
+ return cert;
}
return PORT_ZNew(NSSLOWCERTCertificate);
}
@@ -5004,9 +4997,9 @@ DestroyCertFreeList(void)
nsslowcert_LockFreeList();
while (NULL != (cert = certListHead)) {
- certListCount--;
- certListHead = cert->next;
- PORT_Free(cert);
+ certListCount--;
+ certListHead = cert->next;
+ PORT_Free(cert);
}
PORT_Assert(!certListCount);
certListCount = 0;
@@ -5016,21 +5009,21 @@ DestroyCertFreeList(void)
void
nsslowcert_DestroyTrust(NSSLOWCERTTrust *trust)
{
- certDBEntryCert *entry = trust->dbEntry;
+ certDBEntryCert *entry = trust->dbEntry;
- if ( entry ) {
- DestroyDBEntry((certDBEntry *)entry);
+ if (entry) {
+ DestroyDBEntry((certDBEntry *)entry);
}
- pkcs11_freeStaticData(trust->dbKey.data,trust->dbKeySpace);
+ pkcs11_freeStaticData(trust->dbKey.data, trust->dbKeySpace);
PORT_Memset(trust, 0, sizeof(*trust));
nsslowcert_LockFreeList();
if (trustListCount > MAX_TRUST_LIST_COUNT) {
- PORT_Free(trust);
+ PORT_Free(trust);
} else {
- trustListCount++;
- trust->next = trustListHead;
- trustListHead = trust;
+ trustListCount++;
+ trust->next = trustListHead;
+ trustListHead = trust;
}
nsslowcert_UnlockFreeList();
@@ -5056,38 +5049,38 @@ nsslowcert_DestroyCertificateNoLocking(NSSLOWCERTCertificate *cert)
* caching stuff used by certificates....?
*/
certDBEntryRevocation *
-nsslowcert_FindCrlByKey(NSSLOWCERTCertDBHandle *handle,
- SECItem *crlKey, PRBool isKRL)
+nsslowcert_FindCrlByKey(NSSLOWCERTCertDBHandle *handle,
+ SECItem *crlKey, PRBool isKRL)
{
SECItem keyitem;
SECStatus rv;
PLArenaPool *arena = NULL;
certDBEntryRevocation *entry = NULL;
- certDBEntryType crlType = isKRL ? certDBEntryTypeKeyRevocation
- : certDBEntryTypeRevocation;
-
+ certDBEntryType crlType = isKRL ? certDBEntryTypeKeyRevocation
+ : certDBEntryTypeRevocation;
+
arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
- if ( arena == NULL ) {
- goto loser;
+ if (arena == NULL) {
+ goto loser;
}
-
+
rv = EncodeDBGenericKey(crlKey, arena, &keyitem, crlType);
- if ( rv != SECSuccess ) {
- goto loser;
+ if (rv != SECSuccess) {
+ goto loser;
}
-
+
/* find in perm database */
entry = ReadDBCrlEntry(handle, crlKey, crlType);
-
- if ( entry == NULL ) {
- goto loser;
+
+ if (entry == NULL) {
+ goto loser;
}
loser:
- if ( arena ) {
- PORT_FreeArena(arena, PR_FALSE);
+ if (arena) {
+ PORT_FreeArena(arena, PR_FALSE);
}
-
+
return entry;
}
@@ -5095,32 +5088,34 @@ loser:
* 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)
+nsslowcert_UpdateCrl(NSSLOWCERTCertDBHandle *handle, SECItem *derCrl,
+ SECItem *crlKey, char *url, PRBool isKRL)
{
SECStatus rv = SECFailure;
certDBEntryRevocation *entry = NULL;
- certDBEntryType crlType = isKRL ? certDBEntryTypeKeyRevocation
- : certDBEntryTypeRevocation;
+ 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;
+ if (entry == NULL)
+ goto done;
rv = WriteDBCrlEntry(handle, entry, crlKey);
- if (rv != SECSuccess) goto done;
+ if (rv != SECSuccess)
+ goto done;
done:
if (entry) {
- DestroyDBEntry((certDBEntry *)entry);
+ DestroyDBEntry((certDBEntry *)entry);
}
return rv;
}
SECStatus
-nsslowcert_AddCrl(NSSLOWCERTCertDBHandle *handle, SECItem *derCrl,
- SECItem *crlKey, char *url, PRBool isKRL)
+nsslowcert_AddCrl(NSSLOWCERTCertDBHandle *handle, SECItem *derCrl,
+ SECItem *crlKey, char *url, PRBool isKRL)
{
SECStatus rv;
@@ -5131,29 +5126,29 @@ nsslowcert_AddCrl(NSSLOWCERTCertDBHandle *handle, SECItem *derCrl,
SECStatus
nsslowcert_DeletePermCRL(NSSLOWCERTCertDBHandle *handle, const SECItem *derName,
- PRBool isKRL)
+ PRBool isKRL)
{
SECStatus rv;
- certDBEntryType crlType = isKRL ? certDBEntryTypeKeyRevocation
- : certDBEntryTypeRevocation;
-
+ certDBEntryType crlType = isKRL ? certDBEntryTypeKeyRevocation
+ : certDBEntryTypeRevocation;
+
rv = DeleteDBCrlEntry(handle, derName, crlType);
- if (rv != SECSuccess) goto done;
-
+ if (rv != SECSuccess)
+ goto done;
+
done:
return rv;
}
-
PRBool
nsslowcert_hasTrust(NSSLOWCERTCertTrust *trust)
{
if (trust == NULL) {
- return PR_FALSE;
+ return PR_FALSE;
}
- return !((trust->sslFlags & CERTDB_TRUSTED_UNKNOWN) &&
- (trust->emailFlags & CERTDB_TRUSTED_UNKNOWN) &&
- (trust->objectSigningFlags & CERTDB_TRUSTED_UNKNOWN));
+ return !((trust->sslFlags & CERTDB_TRUSTED_UNKNOWN) &&
+ (trust->emailFlags & CERTDB_TRUSTED_UNKNOWN) &&
+ (trust->objectSigningFlags & CERTDB_TRUSTED_UNKNOWN));
}
/*
@@ -5162,33 +5157,33 @@ nsslowcert_hasTrust(NSSLOWCERTCertTrust *trust)
* the case when there is no profile.
*/
static SECStatus
-nsslowcert_UpdateSMimeProfile(NSSLOWCERTCertDBHandle *dbhandle,
- char *emailAddr, SECItem *derSubject, SECItem *emailProfile,
- SECItem *profileTime)
+nsslowcert_UpdateSMimeProfile(NSSLOWCERTCertDBHandle *dbhandle,
+ char *emailAddr, SECItem *derSubject, SECItem *emailProfile,
+ SECItem *profileTime)
{
certDBEntrySMime *entry = NULL;
- SECStatus rv = SECFailure;;
-
+ 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;
+ 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;
+ profileTime, 0);
+ if (entry == NULL) {
+ rv = SECFailure;
+ goto loser;
}
nsslowcert_LockDB(dbhandle);
@@ -5198,47 +5193,47 @@ nsslowcert_UpdateSMimeProfile(NSSLOWCERTCertDBHandle *dbhandle,
/* link subject entry back here */
rv = nsslowcert_UpdateSubjectEmailAddr(dbhandle, derSubject, emailAddr,
- nsslowcert_add);
- if ( rv != SECSuccess ) {
- nsslowcert_UnlockDB(dbhandle);
- goto loser;
+ nsslowcert_add);
+ if (rv != SECSuccess) {
+ nsslowcert_UnlockDB(dbhandle);
+ goto loser;
}
-
+
rv = WriteDBSMimeEntry(dbhandle, entry);
- if ( rv != SECSuccess ) {
- nsslowcert_UnlockDB(dbhandle);
- goto loser;
+ if (rv != SECSuccess) {
+ nsslowcert_UnlockDB(dbhandle);
+ goto loser;
}
nsslowcert_UnlockDB(dbhandle);
rv = SECSuccess;
-
+
loser:
- if ( entry ) {
- DestroyDBEntry((certDBEntry *)entry);
+ if (entry) {
+ DestroyDBEntry((certDBEntry *)entry);
}
- return(rv);
+ return (rv);
}
SECStatus
-nsslowcert_SaveSMimeProfile(NSSLOWCERTCertDBHandle *dbhandle, char *emailAddr,
- SECItem *derSubject, SECItem *emailProfile, SECItem *profileTime)
+nsslowcert_SaveSMimeProfile(NSSLOWCERTCertDBHandle *dbhandle, char *emailAddr,
+ SECItem *derSubject, SECItem *emailProfile, SECItem *profileTime)
{
- SECStatus rv = SECFailure;;
+ SECStatus rv = SECFailure;
+ ;
+ rv = nsslowcert_UpdateSMimeProfile(dbhandle, emailAddr,
+ derSubject, emailProfile, profileTime);
- rv = nsslowcert_UpdateSMimeProfile(dbhandle, emailAddr,
- derSubject, emailProfile, profileTime);
-
- return(rv);
+ return (rv);
}
void
nsslowcert_DestroyFreeLists(void)
{
if (freeListLock == NULL) {
- return;
+ return;
}
DestroyCertEntryFreeList();
DestroyTrustFreeList();
@@ -5251,90 +5246,88 @@ void
nsslowcert_DestroyGlobalLocks(void)
{
if (dbLock) {
- SKIP_AFTER_FORK(PZ_DestroyLock(dbLock));
- dbLock = NULL;
+ SKIP_AFTER_FORK(PZ_DestroyLock(dbLock));
+ dbLock = NULL;
}
if (certRefCountLock) {
- SKIP_AFTER_FORK(PZ_DestroyLock(certRefCountLock));
- certRefCountLock = NULL;
+ SKIP_AFTER_FORK(PZ_DestroyLock(certRefCountLock));
+ certRefCountLock = NULL;
}
if (certTrustLock) {
- SKIP_AFTER_FORK(PZ_DestroyLock(certTrustLock));
- certTrustLock = NULL;
+ SKIP_AFTER_FORK(PZ_DestroyLock(certTrustLock));
+ certTrustLock = NULL;
}
}
certDBEntry *
-nsslowcert_DecodeAnyDBEntry(SECItem *dbData, const SECItem *dbKey,
- certDBEntryType entryType, void *pdata)
+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;
+ 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;
+ dbEntry.len = dbData->len - SEC_DB_ENTRY_HEADER_LEN;
arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
if (arena == NULL) {
- goto loser;
+ goto loser;
}
entry = PORT_ArenaZNew(arena, certDBEntry);
if (!entry)
- goto loser;
+ 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;
+ 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 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 certDBEntryTypeSubject:
+ rv = DecodeDBSubjectEntry(&entry->subject, &dbEntry, dbKey);
+ break;
- case certDBEntryTypeNickname:
- rv = DecodeDBNicknameEntry(&entry->nickname, &dbEntry,
- (char *)dbKey->data);
- 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;
+ /* 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 certDBEntryTypeCert:
+ rv = DecodeDBCertEntry(&entry->cert, &dbEntry);
+ break;
- case certDBEntryTypeKeyRevocation:
- case certDBEntryTypeRevocation:
- rv = DecodeDBCrlEntry(&entry->revocation, &dbEntry);
- break;
+ case certDBEntryTypeKeyRevocation:
+ case certDBEntryTypeRevocation:
+ rv = DecodeDBCrlEntry(&entry->revocation, &dbEntry);
+ break;
- default:
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- rv = SECFailure;
+ default:
+ PORT_SetError(SEC_ERROR_INVALID_ARGS);
+ rv = SECFailure;
}
if (rv == SECSuccess)
- return entry;
+ return entry;
loser:
if (arena)
- PORT_FreeArena(arena, PR_FALSE);
+ PORT_FreeArena(arena, PR_FALSE);
return NULL;
}
-
diff --git a/nss/lib/softoken/legacydb/pcertt.h b/nss/lib/softoken/legacydb/pcertt.h
index fd5e17c..7eaa82d 100644
--- a/nss/lib/softoken/legacydb/pcertt.h
+++ b/nss/lib/softoken/legacydb/pcertt.h
@@ -18,17 +18,17 @@
#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;
+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
@@ -81,10 +81,10 @@ struct NSSLOWCERTCertTrustStr {
struct NSSLOWCERTTrustStr {
NSSLOWCERTTrust *next;
NSSLOWCERTCertDBHandle *dbhandle;
- SECItem dbKey; /* database key for this cert */
- certDBEntryCert *dbEntry; /* database entry struct */
+ SECItem dbKey; /* database key for this cert */
+ certDBEntryCert *dbEntry; /* database entry struct */
NSSLOWCERTCertTrust *trust;
- SECItem *derCert; /* original DER for the cert */
+ SECItem *derCert; /* original DER for the cert */
unsigned char dbKeySpace[512];
};
@@ -101,17 +101,17 @@ struct NSSLOWCERTCertificateStr {
NSSLOWCERTCertificate *next;
NSSLOWCERTCertDBHandle *dbhandle;
- SECItem derCert; /* original DER for the cert */
- SECItem derIssuer; /* DER for issuer name */
+ SECItem derCert; /* original DER for the cert */
+ SECItem derIssuer; /* DER for issuer name */
SECItem derSN;
SECItem serialNumber;
- SECItem derSubject; /* DER for subject name */
+ SECItem derSubject; /* DER for subject name */
SECItem derSubjKeyInfo;
NSSLOWCERTSubjectPublicKeyInfo *subjectPublicKeyInfo;
- SECItem certKey; /* database key for this cert */
+ SECItem certKey; /* database key for this cert */
SECItem validity;
- certDBEntryCert *dbEntry; /* database entry struct */
- SECItem subjectKeyID; /* x509v3 subject key identifier */
+ certDBEntryCert *dbEntry; /* database entry struct */
+ SECItem subjectKeyID; /* x509v3 subject key identifier */
SECItem extensions;
char *nickname;
char *emailAddr;
@@ -127,12 +127,12 @@ struct NSSLOWCERTCertificateStr {
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_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 SEC_CRL_VERSION_1 0 /* default */
+#define SEC_CRL_VERSION_2 1 /* v2 extensions */
#define NSS_MAX_LEGACY_DB_KEY_SIZE (60 * 1024)
@@ -141,36 +141,36 @@ struct NSSLOWCERTIssuerAndSNStr {
SECItem serialNumber;
};
-typedef SECStatus (* NSSLOWCERTCertCallback)(NSSLOWCERTCertificate *cert, void *arg);
+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);
+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 */
+#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 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
+#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
+ *
+ * byte offset field
+ * ----------- -----
+ * 0 version
+ * 1 type
+ * 2 flags
*/
/* database entry types */
@@ -196,26 +196,26 @@ typedef struct {
/*
* 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
+ * 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.
+ * 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.
+ * nickname-len-lsb will both be zero.
*/
struct _certDBEntryCert {
certDBEntryCommon common;
@@ -230,11 +230,11 @@ struct _certDBEntryCert {
/*
* Certificate Nickname entry:
*
- * byte offset field
- * ----------- -----
- * 0 subjectname-len-msb
- * 1 subjectname-len-lsb
- * 2... subjectname
+ * 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
@@ -251,22 +251,22 @@ typedef struct {
/*
* 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
+ * 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
@@ -290,17 +290,17 @@ typedef struct _certDBEntrySubject {
/*
* 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
+ * 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
@@ -324,34 +324,34 @@ typedef struct {
/*
* Crl/krl entry:
*
- * byte offset field
- * ----------- -----
- * 0 derCert-len-msb
- * 1 derCert-len-lsb
- * 2 url-len-msb
- * 3 url-len-lsb
- * ... derCert
- * ... url
+ * 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.
+ * 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.
+ * url-len-lsb will both be zero.
*/
-#define DB_CRL_ENTRY_HEADER_LEN 4
+#define DB_CRL_ENTRY_HEADER_LEN 4
struct _certDBEntryRevocation {
certDBEntryCommon common;
- SECItem derCrl;
- char *url; /* where to load the crl from */
+ SECItem derCrl;
+ char *url; /* where to load the crl from */
};
/*
* Database Version Entry:
*
- * byte offset field
- * ----------- -----
- * only the low level header...
+ * byte offset field
+ * ----------- -----
+ * only the low level header...
*
* The database key for this type of entry is the string "Version"
*/
@@ -365,9 +365,9 @@ typedef struct {
/*
* Database Content Version Entry:
*
- * byte offset field
- * ----------- -----
- * 0 contentVersion
+ * byte offset field
+ * ----------- -----
+ * 0 contentVersion
*
* The database key for this type of entry is the string "ContentVersion"
*/
@@ -380,39 +380,39 @@ typedef struct {
#define SEC_DB_CONTENT_VERSION_KEY_LEN sizeof(SEC_DB_CONTENT_VERSION_KEY)
typedef union {
- certDBEntryCommon common;
- certDBEntryCert cert;
+ certDBEntryCommon common;
+ certDBEntryCert cert;
certDBEntryContentVersion content;
- certDBEntryNickname nickname;
- certDBEntryRevocation revocation;
- certDBEntrySMime smime;
- certDBEntrySubject subject;
- certDBEntryVersion version;
+ 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
+#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 (1u<<0)
-#define CERTDB_TRUSTED (1u<<1)
-#define CERTDB_SEND_WARN (1u<<2)
-#define CERTDB_VALID_CA (1u<<3)
-#define CERTDB_TRUSTED_CA (1u<<4) /* trusted for issuing server certs */
-#define CERTDB_NS_TRUSTED_CA (1u<<5)
-#define CERTDB_USER (1u<<6)
-#define CERTDB_TRUSTED_CLIENT_CA (1u<<7) /* trusted for issuing client certs */
-#define CERTDB_INVISIBLE_CA (1u<<8) /* don't show in UI */
-#define CERTDB_GOVT_APPROVED_CA (1u<<9) /* can do strong crypto in export ver */
-#define CERTDB_MUST_VERIFY (1u<<10) /* explicitly don't trust this cert */
-#define CERTDB_TRUSTED_UNKNOWN (1u<<11) /* accept trust from another source */
+#define CERTDB_TERMINAL_RECORD (1u << 0)
+#define CERTDB_TRUSTED (1u << 1)
+#define CERTDB_SEND_WARN (1u << 2)
+#define CERTDB_VALID_CA (1u << 3)
+#define CERTDB_TRUSTED_CA (1u << 4) /* trusted for issuing server certs */
+#define CERTDB_NS_TRUSTED_CA (1u << 5)
+#define CERTDB_USER (1u << 6)
+#define CERTDB_TRUSTED_CLIENT_CA (1u << 7) /* trusted for issuing client certs */
+#define CERTDB_INVISIBLE_CA (1u << 8) /* don't show in UI */
+#define CERTDB_GOVT_APPROVED_CA (1u << 9) /* can do strong crypto in export ver */
+#define CERTDB_MUST_VERIFY (1u << 10) /* explicitly don't trust this cert */
+#define CERTDB_TRUSTED_UNKNOWN (1u << 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)
+#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/nss/lib/softoken/legacydb/pk11db.c b/nss/lib/softoken/legacydb/pk11db.c
index 7d0a03c..a7421c8 100644
--- a/nss/lib/softoken/legacydb/pk11db.c
+++ b/nss/lib/softoken/legacydb/pk11db.c
@@ -1,7 +1,7 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.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.
@@ -12,18 +12,25 @@
#include "secerr.h"
#include "utilpars.h"
-#define FREE_CLEAR(p) if (p) { PORT_Free(p); p = NULL; }
+#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) {
+static SECStatus
+lgdb_MakeKey(DBT *key, char *module)
+{
int len = 0;
char *commonName;
- commonName = NSSUTIL_ArgGetParamValue("name",module);
+ commonName = NSSUTIL_ArgGetParamValue("name", module);
if (commonName == NULL) {
- commonName = NSSUTIL_ArgGetParamValue("library",module);
+ commonName = NSSUTIL_ArgGetParamValue("library", module);
}
- if (commonName == NULL) return SECFailure;
+ if (commonName == NULL)
+ return SECFailure;
len = PORT_Strlen(commonName);
key->data = commonName;
key->size = len;
@@ -31,11 +38,11 @@ static SECStatus lgdb_MakeKey(DBT *key, char * module) {
}
/* free out constructed database key */
-static void
-lgdb_FreeKey(DBT *key)
+static void
+lgdb_FreeKey(DBT *key)
{
if (key->data) {
- PORT_Free(key->data);
+ PORT_Free(key->data);
}
key->data = NULL;
key->size = 0;
@@ -58,7 +65,7 @@ struct lgdbDataStr {
unsigned char isModuleDBOnly;
unsigned char isCritical;
unsigned char reserved[4];
- unsigned char names[6]; /* enough space for the length fields */
+ unsigned char names[6]; /* enough space for the length fields */
};
struct lgdbSlotDataStr {
@@ -77,162 +84,165 @@ struct lgdbSlotDataStr {
#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_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]))
+ ((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
+ * build a data base entry from a module
*/
-static SECStatus
-lgdb_EncodeData(DBT *data, char * module)
+static SECStatus
+lgdb_EncodeData(DBT *data, char *module)
{
lgdbData *encoded = NULL;
lgdbSlotData *slot;
- unsigned char *dataPtr;
+ unsigned char *dataPtr, *offsetPtr;
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;
+ 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 = NSSUTIL_ArgParseModuleSpec(module, &dllName, &commonName, &param, &nss);
+ if (rv != SECSuccess)
+ return rv;
rv = SECFailure;
if (commonName == NULL) {
- /* set error */
- goto loser;
+ /* set error */
+ goto loser;
}
len = PORT_Strlen(commonName);
if (dllName) {
- len2 = PORT_Strlen(dllName);
+ len2 = PORT_Strlen(dllName);
}
if (param) {
- len3 = PORT_Strlen(param);
+ len3 = PORT_Strlen(param);
}
- slotParams = NSSUTIL_ArgGetParamValue("slotParams",nss);
- slotInfo = NSSUTIL_ArgParseSlotInfo(NULL,slotParams,&count);
- if (slotParams) PORT_Free(slotParams);
+ slotParams = NSSUTIL_ArgGetParamValue("slotParams", nss);
+ slotInfo = NSSUTIL_ArgParseSlotInfo(NULL, slotParams, &count);
+ if (slotParams)
+ PORT_Free(slotParams);
if (count && slotInfo == NULL) {
- /* set error */
- goto loser;
+ /* set error */
+ goto loser;
}
dataLen = sizeof(lgdbData) + len + len2 + len3 + sizeof(unsigned short) +
- count*sizeof(lgdbSlotData);
+ count * sizeof(lgdbSlotData);
- data->data = (unsigned char *) PORT_ZAlloc(dataLen);
+ data->data = (unsigned char *)PORT_ZAlloc(dataLen);
encoded = (lgdbData *)data->data;
- dataPtr = (unsigned char *) data->data;
+ dataPtr = (unsigned char *)data->data;
data->size = dataLen;
if (encoded == NULL) {
- /* set error */
- goto loser;
+ /* 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);
+ 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);
-
+ 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);
- 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;
+ 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));
+
+ offsetPtr = encoded->names;
+ LGDB_PUTSHORT(encoded->names, len);
+ offsetPtr += sizeof(unsigned short);
+ PORT_Memcpy(offsetPtr, commonName, len);
+ offsetPtr += len;
+
+ LGDB_PUTSHORT(offsetPtr, len2);
+ offsetPtr += sizeof(unsigned short);
+ if (len2) {
+ PORT_Memcpy(offsetPtr, dllName, len2);
+ }
+ offsetPtr += len2;
- LGDB_PUTSHORT(&encoded->names[offset],len3);
- offset += sizeof(unsigned short);
- if (len3) PORT_Memcpy(&encoded->names[offset],param,len3);
- offset += len3;
+ LGDB_PUTSHORT(offsetPtr, len3);
+ offsetPtr += sizeof(unsigned short);
+ if (len3) {
+ PORT_Memcpy(offsetPtr, param, len3);
+ }
+ offsetPtr += 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));
- }
+ 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);
+ 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
+static void
lgdb_FreeData(DBT *data)
{
if (data->data) {
- PORT_Free(data->data);
+ PORT_Free(data->data);
}
}
@@ -241,11 +251,11 @@ 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;
- }
+ for (i = 0; i < count; i++) {
+ if (slotStrings[i]) {
+ PR_smprintf_free(slotStrings[i]);
+ slotStrings[i] = NULL;
+ }
}
}
@@ -258,88 +268,87 @@ lgdb_DecodeData(char *defParams, DBT *data, PRBool *retInternal)
lgdbData *encoded;
lgdbSlotData *slots;
PLArenaPool *arena;
- char *commonName = NULL;
- char *dllName = NULL;
- char *parameters = NULL;
+ char *commonName = NULL;
+ char *dllName = NULL;
+ char *parameters = NULL;
char *nss;
char *moduleSpec;
- char **slotStrings = NULL;
+ char **slotStrings = NULL;
unsigned char *names;
unsigned long slotCount;
- unsigned long ssl0 =0;
- unsigned long ssl1 =0;
+ 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 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 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 isOldVersion = PR_FALSE;
PRBool internal;
PRBool isFIPS;
- PRBool isModuleDB =PR_FALSE;
- PRBool isModuleDBOnly =PR_FALSE;
- PRBool extended =PR_FALSE;
+ 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;
+ if (arena == NULL)
+ return NULL;
-#define CHECK_SIZE(x) \
- if ((unsigned int) data->size < (unsigned int)(x)) goto db_loser
+#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.
+ ** 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]) );
+ 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;
+ internal = (encoded->internal != 0) ? PR_TRUE : PR_FALSE;
+ isFIPS = (encoded->fips != 0) ? PR_TRUE : PR_FALSE;
if (retInternal)
- *retInternal = internal;
+ *retInternal = internal;
if (internal) {
- parameters = PORT_ArenaStrdup(arena,defParams);
- if (parameters == NULL)
- goto loser;
+ 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;
+ (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;
- }
+ (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;
+ 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);
+ slotOffset = LGDB_GETSHORT(encoded->slotOffset);
namesOffset = LGDB_GETSHORT(encoded->nameStart);
-
/*--------------------------------------------------------------
- ** Now process the variable length set of names.
+ ** Now process the variable length set of names.
** The names have this structure:
** struct {
** BYTE commonNameLen[ 2 ];
@@ -354,60 +363,60 @@ lgdb_DecodeData(char *defParams, DBT *data, PRBool *retInternal)
namesRunningOffset = namesOffset;
/* copy the module's common name */
- CHECK_SIZE( namesRunningOffset + 2);
+ CHECK_SIZE(namesRunningOffset + 2);
names = (unsigned char *)data->data;
- len = LGDB_GETSHORT(names+namesRunningOffset);
+ len = LGDB_GETSHORT(names + namesRunningOffset);
- CHECK_SIZE( namesRunningOffset + 2 + len);
- commonName = (char*)PORT_ArenaAlloc(arena,len+1);
- if (commonName == NULL)
- goto loser;
+ 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);
+ 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;
+ 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;
+ 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
+ * 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
+ * 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;
- }
+ if (slotOffset < namesRunningOffset) {
+ goto db_loser;
+ }
}
/* ------------------------------------------------------------------
@@ -419,137 +428,135 @@ lgdb_DecodeData(char *defParams, DBT *data, PRBool *retInternal)
** {
*/
- CHECK_SIZE( slotOffset + 2 );
+ 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
+ /*
+ * 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;
- }
+ 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);
+ 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;
- }
+ 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);
+ 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);
+ moduleSpec = NSSUTIL_MkModuleSpec(dllName, commonName, parameters, nss);
PR_smprintf_free(nss);
- PORT_FreeArena(arena,PR_TRUE);
+ PORT_FreeArena(arena, PR_TRUE);
return moduleSpec;
db_loser:
PORT_SetError(SEC_ERROR_BAD_DATABASE);
loser:
- PORT_FreeArena(arena,PR_TRUE);
+ PORT_FreeArena(arena, PR_TRUE);
return NULL;
}
static DB *
-lgdb_OpenDB(const char *appName, const char *filename, const char *dbName,
- PRBool readOnly, PRBool update)
+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;
+ 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;
+ if (readOnly)
+ return NULL;
- pkcs11db = dbopen( dbName, NO_CREATE, 0600, DB_HASH, 0 );
- if (pkcs11db)
- (* pkcs11db->sync)(pkcs11db, 0);
+ pkcs11db = dbopen(dbName, NO_CREATE, 0600, DB_HASH, 0);
+ if (pkcs11db)
+ (*pkcs11db->sync)(pkcs11db, 0);
}
return pkcs11db;
}
-static void
-lgdb_CloseDB(DB *pkcs11db)
+static void
+lgdb_CloseDB(DB *pkcs11db)
{
- (*pkcs11db->close)(pkcs11db);
+ (*pkcs11db->close)(pkcs11db);
}
-
-SECStatus legacy_AddSecmodDB(const char *appName, const char *filename,
- const char *dbname, char *module, PRBool rw);
+SECStatus legacy_AddSecmodDB(const char *appName, const char *filename,
+ const char *dbname, char *module, PRBool rw);
#define LGDB_STEP 10
/*
@@ -557,83 +564,84 @@ SECStatus legacy_AddSecmodDB(const char *appName, const char *filename,
*/
char **
legacy_ReadSecmodDB(const char *appName, const char *filename,
- const char *dbname, char *params, PRBool rw)
+ const char *dbname, char *params, PRBool rw)
{
- DBT key,data;
+ 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;
+ 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;
+ 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;
-
+ 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);
+ 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);
- }
+ 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);
+ lgdb_CloseDB(pkcs11db);
} else if (moduleList[0] && rw) {
- legacy_AddSecmodDB(appName,filename,dbname,moduleList[0], rw) ;
+ legacy_AddSecmodDB(appName, filename, dbname, moduleList[0], rw);
}
if (!moduleList[0]) {
- PORT_Free(moduleList);
- moduleList = NULL;
+ PORT_Free(moduleList);
+ moduleList = NULL;
}
return moduleList;
}
SECStatus
-legacy_ReleaseSecmodDBData(const char *appName, const char *filename,
- const char *dbname, char **moduleSpecList, PRBool rw)
+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);
+ char **index;
+ for (index = moduleSpecList; *index; index++) {
+ PR_smprintf_free(*index);
+ }
+ PORT_Free(moduleSpecList);
}
return SECSuccess;
}
@@ -642,32 +650,35 @@ legacy_ReleaseSecmodDBData(const char *appName, const char *filename,
* Delete a module from the Data Base
*/
SECStatus
-legacy_DeleteSecmodDB(const char *appName, const char *filename,
- const char *dbname, char *args, PRBool rw)
+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;
+ if (!rw)
+ return SECFailure;
/* make sure we have a db handle */
- pkcs11db = lgdb_OpenDB(appName,filename,dbname,PR_FALSE,PR_FALSE);
+ pkcs11db = lgdb_OpenDB(appName, filename, dbname, PR_FALSE, PR_FALSE);
if (pkcs11db == NULL) {
- return SECFailure;
+ return SECFailure;
}
- rv = lgdb_MakeKey(&key,args);
- if (rv != SECSuccess) goto done;
+ 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;
-
+ if (ret != 0)
+ goto done;
ret = (*pkcs11db->sync)(pkcs11db, 0);
- if (ret == 0) rv = SECSuccess;
+ if (ret == 0)
+ rv = SECSuccess;
done:
lgdb_CloseDB(pkcs11db);
@@ -675,41 +686,44 @@ done:
}
/*
- * Add a module to the Data base
+ * Add a module to the Data base
*/
SECStatus
-legacy_AddSecmodDB(const char *appName, const char *filename,
- const char *dbname, char *module, PRBool rw)
+legacy_AddSecmodDB(const char *appName, const char *filename,
+ const char *dbname, char *module, PRBool rw)
{
- DBT key,data;
+ DBT key, data;
SECStatus rv = SECFailure;
DB *pkcs11db = NULL;
int ret;
-
- if (!rw) return SECFailure;
+ if (!rw)
+ return SECFailure;
/* make sure we have a db handle */
- pkcs11db = lgdb_OpenDB(appName,filename,dbname,PR_FALSE,PR_FALSE);
+ pkcs11db = lgdb_OpenDB(appName, filename, dbname, PR_FALSE, PR_FALSE);
if (pkcs11db == NULL) {
- return SECFailure;
+ return SECFailure;
}
- rv = lgdb_MakeKey(&key,module);
- if (rv != SECSuccess) goto done;
- rv = lgdb_EncodeData(&data,module);
+ rv = lgdb_MakeKey(&key, module);
+ if (rv != SECSuccess)
+ goto done;
+ rv = lgdb_EncodeData(&data, module);
if (rv != SECSuccess) {
- lgdb_FreeKey(&key);
- goto done;
+ 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;
+ if (ret != 0)
+ goto done;
ret = (*pkcs11db->sync)(pkcs11db, 0);
- if (ret == 0) rv = SECSuccess;
+ if (ret == 0)
+ rv = SECSuccess;
done:
lgdb_CloseDB(pkcs11db);
diff --git a/nss/lib/softoken/lgglue.c b/nss/lib/softoken/lgglue.c
index c7b82bd..94f0541 100644
--- a/nss/lib/softoken/lgglue.c
+++ b/nss/lib/softoken/lgglue.c
@@ -1,7 +1,7 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.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.
@@ -35,49 +35,51 @@ static char *
sftkdb_resolvePath(const char *orig)
{
int count = 0;
- int len =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;
+ if (strlen(orig) + 1 > len) {
+ /* PATH TOO LONG */
+ return NULL;
}
resolved = PORT_Alloc(len);
if (!resolved) {
- return NULL;
+ return NULL;
}
source = PORT_Alloc(len);
if (!source) {
- goto loser;
+ 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;
+ 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;
+ ret = 0;
}
loser:
if (resolved) {
- PORT_Free(resolved);
+ PORT_Free(resolved);
}
if (ret < 0) {
- if (source) {
- PORT_Free(source);
- source = NULL;
- }
+ if (source) {
+ PORT_Free(source);
+ source = NULL;
+ }
}
return source;
}
@@ -93,22 +95,21 @@ sftkdb_LoadFromPath(const char *path, const char *libname)
PRLibSpec libSpec;
PRLibrary *lib = NULL;
-
- /* strip of our parent's library name */
+ /* strip of our parent's library name */
c = strrchr(path, PR_GetDirectorySeparator());
if (!c) {
- return NULL; /* invalid path */
+ return NULL; /* invalid path */
}
- pathLen = (c-path)+1;
+ pathLen = (c - path) + 1;
nameLen = strlen(libname);
- fullPathLen = pathLen + nameLen +1;
+ fullPathLen = pathLen + nameLen + 1;
fullPathName = (char *)PORT_Alloc(fullPathLen);
if (fullPathName == NULL) {
- return NULL; /* memory allocation error */
+ return NULL; /* memory allocation error */
}
PORT_Memcpy(fullPathName, path, pathLen);
- PORT_Memcpy(fullPathName+pathLen, libname, nameLen);
- fullPathName[fullPathLen-1] = 0;
+ PORT_Memcpy(fullPathName + pathLen, libname, nameLen);
+ fullPathName[fullPathLen - 1] = 0;
libSpec.type = PR_LibSpec_Pathname;
libSpec.value.pathname = fullPathName;
@@ -117,7 +118,6 @@ sftkdb_LoadFromPath(const char *path, const char *libname)
return lib;
}
-
static PRLibrary *
sftkdb_LoadLibrary(const char *libname)
{
@@ -125,37 +125,37 @@ sftkdb_LoadLibrary(const char *libname)
PRFuncPtr fn_addr;
char *parentLibPath = NULL;
- fn_addr = (PRFuncPtr) &sftkdb_LoadLibrary;
+ fn_addr = (PRFuncPtr)&sftkdb_LoadLibrary;
parentLibPath = PR_GetLibraryFilePathname(SOFTOKEN_LIB_NAME, fn_addr);
if (!parentLibPath) {
- goto done;
+ 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);
+ char *trueParentLibPath = sftkdb_resolvePath(parentLibPath);
+ if (!trueParentLibPath) {
+ goto done;
+ }
+ lib = sftkdb_LoadFromPath(trueParentLibPath, libname);
+ PORT_Free(trueParentLibPath);
}
#endif
done:
if (parentLibPath) {
- PORT_Free(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);
+ PRLibSpec libSpec;
+ libSpec.type = PR_LibSpec_Pathname;
+ libSpec.value.pathname = libname;
+ lib = PR_LoadLibraryWithFlags(libSpec, PR_LD_NOW | PR_LD_LOCAL);
}
return lib;
@@ -167,35 +167,35 @@ done:
*/
static SECStatus
sftkdb_encrypt_stub(PLArenaPool *arena, SDB *sdb, SECItem *plainText,
- SECItem **cipherText)
+ SECItem **cipherText)
{
SFTKDBHandle *handle = sdb->app_private;
SECStatus rv;
if (handle == NULL) {
- return SECFailure;
+ return SECFailure;
}
/* if we aren't the key handle, try the other handle */
if (handle->type != SFTK_KEYDB_TYPE) {
- handle = handle->peerDB;
+ handle = handle->peerDB;
}
/* not a key handle */
if (handle == NULL || handle->passwordLock == NULL) {
- return SECFailure;
+ return SECFailure;
}
PZ_Lock(handle->passwordLock);
if (handle->passwordKey.data == NULL) {
- PZ_Unlock(handle->passwordLock);
- /* PORT_SetError */
- return SECFailure;
+ PZ_Unlock(handle->passwordLock);
+ /* PORT_SetError */
+ return SECFailure;
}
- rv = sftkdb_EncryptAttribute(arena,
- handle->newKey?handle->newKey:&handle->passwordKey,
- plainText, cipherText);
+ rv = sftkdb_EncryptAttribute(arena,
+ handle->newKey ? handle->newKey : &handle->passwordKey,
+ plainText, cipherText);
PZ_Unlock(handle->passwordLock);
return rv;
@@ -206,200 +206,176 @@ sftkdb_encrypt_stub(PLArenaPool *arena, SDB *sdb, SECItem *plainText,
* various keys and attributes.
*/
static SECStatus
-sftkdb_decrypt_stub(SDB *sdb, SECItem *cipherText, SECItem **plainText)
+sftkdb_decrypt_stub(SDB *sdb, SECItem *cipherText, SECItem **plainText)
{
SFTKDBHandle *handle = sdb->app_private;
SECStatus rv;
SECItem *oldKey = NULL;
if (handle == NULL) {
- return SECFailure;
+ return SECFailure;
}
/* if we aren't th handle, try the other handle */
oldKey = handle->oldKey;
if (handle->type != SFTK_KEYDB_TYPE) {
- handle = handle->peerDB;
+ handle = handle->peerDB;
}
/* not a key handle */
if (handle == NULL || handle->passwordLock == NULL) {
- return SECFailure;
+ return SECFailure;
}
PZ_Lock(handle->passwordLock);
if (handle->passwordKey.data == NULL) {
- PZ_Unlock(handle->passwordLock);
- /* PORT_SetError */
- return SECFailure;
+ PZ_Unlock(handle->passwordLock);
+ /* PORT_SetError */
+ return SECFailure;
}
- rv = sftkdb_DecryptAttribute( oldKey ? oldKey : &handle->passwordKey,
- cipherText, plainText);
+ 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;
+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)
+static SECStatus
+sftkdbLoad_Legacy()
{
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;
+ return SECSuccess;
}
lib = sftkdb_LoadLibrary(LEGACY_LIB_NAME);
if (lib == NULL) {
- return SECFailure;
+ 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_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;
+ }
+
+ 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)
+sftkdbCall_open(const char *dir, const char *certPrefix, const char *keyPrefix,
+ int certVersion, int keyVersion, int flags,
+ SDB **certDB, SDB **keyDB)
{
SECStatus rv;
- rv = sftkdbLoad_Legacy(isFIPS);
+ rv = sftkdbLoad_Legacy();
if (rv != SECSuccess) {
- return CKR_GENERAL_ERROR;
+ return CKR_GENERAL_ERROR;
}
if (!legacy_glue_open) {
- PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
- return SECFailure;
+ PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
+ return SECFailure;
}
- return (*legacy_glue_open)(dir, certPrefix, keyPrefix,
- certVersion, keyVersion,
- flags, certDB, keyDB);
+ 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)
+sftkdbCall_ReadSecmodDB(const char *appName, const char *filename,
+ const char *dbname, char *params, PRBool rw)
{
SECStatus rv;
- rv = sftkdbLoad_Legacy(PR_FALSE);
+ rv = sftkdbLoad_Legacy();
if (rv != SECSuccess) {
- return NULL;
+ return NULL;
}
if (!legacy_glue_readSecmod) {
- PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
- return NULL;
+ 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)
+sftkdbCall_ReleaseSecmodDBData(const char *appName,
+ const char *filename, const char *dbname,
+ char **moduleSpecList, PRBool rw)
{
SECStatus rv;
- rv = sftkdbLoad_Legacy(PR_FALSE);
+ rv = sftkdbLoad_Legacy();
if (rv != SECSuccess) {
- return rv;
+ return rv;
}
if (!legacy_glue_releaseSecmod) {
- PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
- return SECFailure;
+ PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
+ return SECFailure;
}
- return (*legacy_glue_releaseSecmod)(appName, filename, dbname,
- moduleSpecList, rw);
+ 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)
+sftkdbCall_DeleteSecmodDB(const char *appName,
+ const char *filename, const char *dbname,
+ char *args, PRBool rw)
{
SECStatus rv;
- rv = sftkdbLoad_Legacy(PR_FALSE);
+ rv = sftkdbLoad_Legacy();
if (rv != SECSuccess) {
- return rv;
+ return rv;
}
if (!legacy_glue_deleteSecmod) {
- PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
- return SECFailure;
+ 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)
+sftkdbCall_AddSecmodDB(const char *appName,
+ const char *filename, const char *dbname,
+ char *module, PRBool rw)
{
SECStatus rv;
- rv = sftkdbLoad_Legacy(PR_FALSE);
+ rv = sftkdbLoad_Legacy();
if (rv != SECSuccess) {
- return rv;
+ return rv;
}
if (!legacy_glue_addSecmod) {
- PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
- return SECFailure;
+ PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
+ return SECFailure;
}
return (*legacy_glue_addSecmod)(appName, filename, dbname, module, rw);
}
@@ -410,15 +386,15 @@ sftkdbCall_Shutdown(void)
CK_RV crv = CKR_OK;
char *disableUnload = NULL;
if (!legacy_glue_lib) {
- return CKR_OK;
+ return CKR_OK;
}
if (legacy_glue_shutdown) {
#ifdef NO_FORK_CHECK
- PRBool parentForkedAfterC_Initialize = PR_FALSE;
+ PRBool parentForkedAfterC_Initialize = PR_FALSE;
#endif
- crv = (*legacy_glue_shutdown)(parentForkedAfterC_Initialize);
+ crv = (*legacy_glue_shutdown)(parentForkedAfterC_Initialize);
}
- disableUnload = PR_GetEnv("NSS_DISABLE_UNLOAD");
+ disableUnload = PR_GetEnvSecure("NSS_DISABLE_UNLOAD");
if (!disableUnload) {
PR_UnloadLibrary(legacy_glue_lib);
}
@@ -428,9 +404,5 @@ sftkdbCall_Shutdown(void)
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/nss/lib/softoken/lgglue.h b/nss/lib/softoken/lgglue.h
index b87f756..61dbfec 100644
--- a/nss/lib/softoken/lgglue.h
+++ b/nss/lib/softoken/lgglue.h
@@ -1,7 +1,7 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.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"
@@ -11,29 +11,29 @@
*/
typedef SECStatus (*LGEncryptFunc)(PLArenaPool *arena, SDB *sdb,
- SECItem *plainText, SECItem **cipherText);
-typedef SECStatus (*LGDecryptFunc)(SDB *sdb, SECItem *cipherText,
- SECItem **plainText);
+ 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 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);
+ 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);
+ 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);
@@ -41,20 +41,19 @@ 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_open(const char *dir, const char *certPrefix,
+ const char *keyPrefix,
+ int certVersion, int keyVersion, int flags,
+ 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/nss/lib/softoken/lowkey.c b/nss/lib/softoken/lowkey.c
index d043342..73b1dc9 100644
--- a/nss/lib/softoken/lowkey.c
+++ b/nss/lib/softoken/lowkey.c
@@ -19,12 +19,12 @@ SEC_ASN1_MKSUB(SEC_ObjectIDTemplate)
SEC_ASN1_MKSUB(SECOID_AlgorithmIDTemplate)
const SEC_ASN1Template nsslowkey_AttributeTemplate[] = {
- { SEC_ASN1_SEQUENCE,
- 0, NULL, sizeof(NSSLOWKEYAttribute) },
+ { 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) },
+ { SEC_ASN1_SET_OF | SEC_ASN1_XTRN,
+ offsetof(NSSLOWKEYAttribute, attrValue),
+ SEC_ASN1_SUB(SEC_AnyTemplate) },
{ 0 }
};
@@ -34,78 +34,64 @@ const SEC_ASN1Template nsslowkey_SetOfAttributeTemplate[] = {
/* ASN1 Templates for new decoder/encoder */
const SEC_ASN1Template nsslowkey_PrivateKeyInfoTemplate[] = {
{ SEC_ASN1_SEQUENCE,
- 0, NULL, sizeof(NSSLOWKEYPrivateKeyInfo) },
+ 0, NULL, sizeof(NSSLOWKEYPrivateKeyInfo) },
{ SEC_ASN1_INTEGER,
- offsetof(NSSLOWKEYPrivateKeyInfo,version) },
+ offsetof(NSSLOWKEYPrivateKeyInfo, version) },
{ SEC_ASN1_INLINE | SEC_ASN1_XTRN,
- offsetof(NSSLOWKEYPrivateKeyInfo,algorithm),
- SEC_ASN1_SUB(SECOID_AlgorithmIDTemplate) },
+ offsetof(NSSLOWKEYPrivateKeyInfo, algorithm),
+ SEC_ASN1_SUB(SECOID_AlgorithmIDTemplate) },
{ SEC_ASN1_OCTET_STRING,
- offsetof(NSSLOWKEYPrivateKeyInfo,privateKey) },
+ offsetof(NSSLOWKEYPrivateKeyInfo, privateKey) },
{ SEC_ASN1_OPTIONAL | SEC_ASN1_CONSTRUCTED | SEC_ASN1_CONTEXT_SPECIFIC | 0,
- offsetof(NSSLOWKEYPrivateKeyInfo, attributes),
- nsslowkey_SetOfAttributeTemplate },
+ 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, }
+ { 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 }
-};
-
+ { 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, }
+ { 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) },
+ { 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, }
+ { 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 }
};
#ifndef NSS_DISABLE_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
@@ -113,32 +99,23 @@ const SEC_ASN1Template nsslowkey_ECParamsTemplate[] = {
*/
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
+ { SEC_ASN1_INTEGER, offsetof(NSSLOWKEYPrivateKey, u.ec.version) },
+ { SEC_ASN1_OCTET_STRING,
+ offsetof(NSSLOWKEYPrivateKey, u.ec.privateValue) },
+ /* We only support named curves for which the parameters are
+ * encoded as an object ID.
*/
-#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_EXPLICIT | SEC_ASN1_CONTEXT_SPECIFIC |
+ SEC_ASN1_XTRN | 0,
+ offsetof(NSSLOWKEYPrivateKey, u.ec.ecParams.curveOID),
+ SEC_ASN1_SUB(SEC_ObjectIDTemplate) },
{ 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, }
+ SEC_ASN1_EXPLICIT | SEC_ASN1_CONTEXT_SPECIFIC |
+ SEC_ASN1_XTRN | 1,
+ offsetof(NSSLOWKEYPrivateKey, u.ec.publicValue),
+ SEC_ASN1_SUB(SEC_BitStringTemplate) },
+ { 0 }
};
#endif /* NSS_DISABLE_ECC */
/*
@@ -219,7 +196,7 @@ void
nsslowkey_DestroyPrivateKey(NSSLOWKEYPrivateKey *privk)
{
if (privk && privk->arena) {
- PORT_FreeArena(privk->arena, PR_TRUE);
+ PORT_FreeArena(privk->arena, PR_TRUE);
}
}
@@ -227,7 +204,7 @@ void
nsslowkey_DestroyPublicKey(NSSLOWKEYPublicKey *pubk)
{
if (pubk && pubk->arena) {
- PORT_FreeArena(pubk->arena, PR_FALSE);
+ PORT_FreeArena(pubk->arena, PR_FALSE);
}
}
unsigned
@@ -239,11 +216,11 @@ nsslowkey_PublicModulusLen(NSSLOWKEYPublicKey *pubk)
* 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;
+ 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;
}
@@ -255,11 +232,11 @@ 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;
+ 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;
}
@@ -270,104 +247,113 @@ nsslowkey_ConvertToPublicKey(NSSLOWKEYPrivateKey *privk)
NSSLOWKEYPublicKey *pubk;
PLArenaPool *arena;
-
- arena = PORT_NewArena (DER_DEFAULT_CHUNKSIZE);
+ arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
if (arena == NULL) {
- PORT_SetError (SEC_ERROR_NO_MEMORY);
+ 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;
+ 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;
#ifndef NSS_DISABLE_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;
+ 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_DISABLE_ECC */
- /* No Fortezza in Low Key implementations (Fortezza keys aren't
- * stored in our data base */
- default:
- break;
+ /* No Fortezza in Low Key implementations (Fortezza keys aren't
+ * stored in our data base */
+ default:
+ break;
}
- PORT_FreeArena (arena, PR_FALSE);
+ PORT_FreeArena(arena, PR_FALSE);
return NULL;
}
@@ -378,114 +364,136 @@ nsslowkey_CopyPrivateKey(NSSLOWKEYPrivateKey *privKey)
SECStatus rv = SECFailure;
PLArenaPool *poolp;
- if(!privKey) {
- return NULL;
+ if (!privKey) {
+ return NULL;
}
poolp = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
- if(!poolp) {
- return NULL;
+ if (!poolp) {
+ return NULL;
}
- returnKey = (NSSLOWKEYPrivateKey*)PORT_ArenaZAlloc(poolp, sizeof(NSSLOWKEYPrivateKey));
- if(!returnKey) {
- rv = SECFailure;
- goto loser;
+ 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;
+ 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;
#ifndef NSS_DISABLE_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;
+ 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_DISABLE_ECC */
- default:
- rv = SECFailure;
+ default:
+ rv = SECFailure;
}
loser:
- if(rv != SECSuccess) {
- PORT_FreeArena(poolp, PR_TRUE);
- returnKey = NULL;
+ if (rv != SECSuccess) {
+ PORT_FreeArena(poolp, PR_TRUE);
+ returnKey = NULL;
}
return returnKey;
diff --git a/nss/lib/softoken/lowkeyi.h b/nss/lib/softoken/lowkeyi.h
index 7282ffe..a5878c2 100644
--- a/nss/lib/softoken/lowkeyi.h
+++ b/nss/lib/softoken/lowkeyi.h
@@ -32,15 +32,15 @@ extern void prepare_low_ecparams_for_asn1(ECParams *params);
/*
** Destroy a private key object.
-** "key" the object
-** "freeit" if PR_TRUE then free the object as well as its sub-objects
+** "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
+** "key" the object
+** "freeit" if PR_TRUE then free the object as well as its sub-objects
*/
extern void nsslowkey_DestroyPublicKey(NSSLOWKEYPublicKey *key);
@@ -49,18 +49,16 @@ extern void nsslowkey_DestroyPublicKey(NSSLOWKEYPublicKey *key);
*/
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);
+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.
@@ -68,7 +66,6 @@ extern NSSLOWKEYPublicKey
extern NSSLOWKEYPrivateKey *
nsslowkey_CopyPrivateKey(NSSLOWKEYPrivateKey *privKey);
-
SEC_END_PROTOS
#endif /* _LOWKEYI_H_ */
diff --git a/nss/lib/softoken/lowkeyti.h b/nss/lib/softoken/lowkeyti.h
index a4c94d8..2ef1640 100644
--- a/nss/lib/softoken/lowkeyti.h
+++ b/nss/lib/softoken/lowkeyti.h
@@ -21,8 +21,7 @@ extern const SEC_ASN1Template nsslowkey_DSAPrivateKeyExportTemplate[];
extern const SEC_ASN1Template nsslowkey_DHPrivateKeyTemplate[];
extern const SEC_ASN1Template nsslowkey_DHPrivateKeyExportTemplate[];
#ifndef NSS_DISABLE_ECC
-#define NSSLOWKEY_EC_PRIVATE_KEY_VERSION 1 /* as per SECG 1 C.4 */
-extern const SEC_ASN1Template nsslowkey_ECParamsTemplate[];
+#define NSSLOWKEY_EC_PRIVATE_KEY_VERSION 1 /* as per SECG 1 C.4 */
extern const SEC_ASN1Template nsslowkey_ECPrivateKeyTemplate[];
#endif /* NSS_DISABLE_ECC */
@@ -49,12 +48,12 @@ struct NSSLOWKEYPrivateKeyInfoStr {
NSSLOWKEYAttribute **attributes;
};
typedef struct NSSLOWKEYPrivateKeyInfoStr NSSLOWKEYPrivateKeyInfo;
-#define NSSLOWKEY_PRIVATE_KEY_INFO_VERSION 0 /* what we *create* */
+#define NSSLOWKEY_PRIVATE_KEY_INFO_VERSION 0 /* what we *create* */
-typedef enum {
- NSSLOWKEYNullKey = 0,
- NSSLOWKEYRSAKey = 1,
- NSSLOWKEYDSAKey = 2,
+typedef enum {
+ NSSLOWKEYNullKey = 0,
+ NSSLOWKEYRSAKey = 1,
+ NSSLOWKEYDSAKey = 2,
NSSLOWKEYDHKey = 4,
NSSLOWKEYECKey = 5
} NSSLOWKEYType;
@@ -64,12 +63,12 @@ typedef enum {
*/
struct NSSLOWKEYPublicKeyStr {
PLArenaPool *arena;
- NSSLOWKEYType keyType ;
+ NSSLOWKEYType keyType;
union {
RSAPublicKey rsa;
- DSAPublicKey dsa;
- DHPublicKey dh;
- ECPublicKey ec;
+ DSAPublicKey dsa;
+ DHPublicKey dh;
+ ECPublicKey ec;
} u;
};
typedef struct NSSLOWKEYPublicKeyStr NSSLOWKEYPublicKey;
@@ -84,11 +83,11 @@ struct NSSLOWKEYPrivateKeyStr {
NSSLOWKEYType keyType;
union {
RSAPrivateKey rsa;
- DSAPrivateKey dsa;
- DHPrivateKey dh;
- ECPrivateKey ec;
+ DSAPrivateKey dsa;
+ DHPrivateKey dh;
+ ECPrivateKey ec;
} u;
};
typedef struct NSSLOWKEYPrivateKeyStr NSSLOWKEYPrivateKey;
-#endif /* _LOWKEYTI_H_ */
+#endif /* _LOWKEYTI_H_ */
diff --git a/nss/lib/softoken/lowpbe.c b/nss/lib/softoken/lowpbe.c
index 16d4c91..b78302e 100644
--- a/nss/lib/softoken/lowpbe.c
+++ b/nss/lib/softoken/lowpbe.c
@@ -26,73 +26,69 @@ SEC_ASN1_MKSUB(SECOID_AlgorithmIDTemplate)
* 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 }
-};
+ {
+ { 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 }
-};
-
+ {
+ { 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 */
+ 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_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,
+ { SEC_ASN1_INLINE | SEC_ASN1_XTRN,
offsetof(nsspkcs5V2PBEParameter, algParams),
SEC_ASN1_SUB(SECOID_AlgorithmIDTemplate) },
- { 0 }
-};
+ { 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,
+ {
+ { 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
+ { 0 }
+ };
SECStatus
nsspkcs5_HashBuf(const SECHashObject *hashObj, unsigned char *dest,
- unsigned char *src, int len)
+ unsigned char *src, int len)
{
void *ctx;
unsigned int retLen;
ctx = hashObj->create();
- if(ctx == NULL) {
- return SECFailure;
+ if (ctx == NULL) {
+ return SECFailure;
}
hashObj->begin(ctx);
hashObj->update(ctx, src, len);
@@ -104,72 +100,72 @@ nsspkcs5_HashBuf(const SECHashObject *hashObj, unsigned char *dest,
/* generate bits using any hash
*/
static SECItem *
-nsspkcs5_PBKDF1(const SECHashObject *hashObj, SECItem *salt, SECItem *pwd,
- int iter, PRBool faulty3DES)
+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;
+ 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;
+ 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;
@@ -184,7 +180,7 @@ nsspkcs5_PBKDF1(const SECHashObject *hashObj, SECItem *salt, SECItem *pwd,
*/
static SECItem *
nsspkcs5_PFXPBE(const SECHashObject *hashObj, NSSPKCS5PBEParameter *pbe_param,
- SECItem *init_hash, unsigned int bytes_needed)
+ SECItem *init_hash, unsigned int bytes_needed)
{
SECItem *ret_bits = NULL;
int hash_size = 0;
@@ -200,69 +196,69 @@ nsspkcs5_PFXPBE(const SECHashObject *hashObj, NSSPKCS5PBEParameter *pbe_param,
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 = (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;
+ 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
+ * data which are added based on iteration number
*/
if ((unsigned int)hash_size > pbe_param->salt.len) {
- state_len = hash_size;
+ state_len = hash_size;
} else {
- state_len = pbe_param->salt.len;
+ state_len = pbe_param->salt.len;
}
state = (unsigned char *)PORT_ZAlloc(state_len);
- if(state == NULL) {
- rv = SECFailure;
- goto loser;
+ if (state == NULL) {
+ rv = SECFailure;
+ goto loser;
}
- if(pbe_param->salt.len > 0) {
- PORT_Memcpy(state, pbe_param->salt.data, pbe_param->salt.len);
+ 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;
+ rv = SECFailure;
+ goto loser;
}
- for(i = 0; i < hash_iter; i++) {
+ 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 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);
+ /* 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);
+ PORT_ZFree(state, state_len);
HMAC_Destroy(cx, PR_TRUE);
- if(rv != SECSuccess) {
- SECITEM_ZfreeItem(ret_bits, PR_TRUE);
- ret_bits = NULL;
+ if (rv != SECSuccess) {
+ SECITEM_ZfreeItem(ret_bits, PR_TRUE);
+ ret_bits = NULL;
}
return ret_bits;
@@ -274,47 +270,45 @@ loser:
*/
static SECItem *
nsspkcs5_PBKDF1Extended(const SECHashObject *hashObj,
- NSSPKCS5PBEParameter *pbe_param, SECItem *pwitem, PRBool faulty3DES)
+ NSSPKCS5PBEParameter *pbe_param, SECItem *pwitem, PRBool faulty3DES)
{
- SECItem * hash = NULL;
- SECItem * newHash = NULL;
- int bytes_needed;
- int bytes_available;
-
+ 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;
+ hash = nsspkcs5_PBKDF1(hashObj, &pbe_param->salt, pwitem,
+ pbe_param->iter, faulty3DES);
+
+ if (hash == NULL) {
+ return NULL;
}
- if(bytes_needed <= bytes_available) {
- return hash;
- }
+ if (bytes_needed <= bytes_available) {
+ return hash;
+ }
newHash = nsspkcs5_PFXPBE(hashObj, pbe_param, hash, bytes_needed);
if (hash != newHash)
- SECITEM_FreeItem(hash, PR_TRUE);
+ 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 */
+ /* use byt xor, not all platforms are happy about inaligned
+ * integer fetches */
while (len--) {
- *dest = *dest ^ *src;
- dest++;
- src++;
+ *dest = *dest ^ *src;
+ dest++;
+ src++;
}
}
@@ -330,51 +324,51 @@ nsspkcs5_PBKDF2_F(const SECHashObject *hashobj, SECItem *pwitem, SECItem *salt,
unsigned int lastLength = salt->len + 4;
unsigned int lastBufLength;
- cx=HMAC_Create(hashobj,pwitem->data,pwitem->len,PR_FALSE);
+ cx = HMAC_Create(hashobj, pwitem->data, pwitem->len, PR_FALSE);
if (cx == NULL) {
- goto loser;
+ goto loser;
}
- PORT_Memset(T,0,hLen);
+ PORT_Memset(T, 0, hLen);
lastBufLength = PR_MAX(lastLength, hLen);
last = PORT_Alloc(lastBufLength);
if (last == NULL) {
- goto loser;
+ 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;
+ 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);
+ 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);
+ HMAC_Destroy(cx, PR_TRUE);
}
if (last) {
- PORT_ZFree(last,lastBufLength);
+ PORT_ZFree(last, lastBufLength);
}
return rv;
}
static SECItem *
-nsspkcs5_PBKDF2(const SECHashObject *hashobj, NSSPKCS5PBEParameter *pbe_param,
- SECItem *pwitem)
+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 nblocks = (dkLen + hLen - 1) / hLen;
unsigned int i;
unsigned char *rp;
unsigned char *T = NULL;
@@ -382,89 +376,88 @@ nsspkcs5_PBKDF2(const SECHashObject *hashobj, NSSPKCS5PBEParameter *pbe_param,
SECItem *salt = &pbe_param->salt;
SECStatus rv = SECFailure;
- result = SECITEM_AllocItem(NULL,NULL,nblocks*hLen);
+ result = SECITEM_AllocItem(NULL, NULL, nblocks * hLen);
if (result == NULL) {
- return NULL;
+ return NULL;
}
T = PORT_Alloc(hLen);
if (T == NULL) {
- goto loser;
+ goto loser;
}
- for (i=1,rp=result->data; i <= nblocks ; i++, rp +=hLen) {
+ for (i = 1, rp = result->data; i <= nblocks; i++, rp += hLen) {
rv = nsspkcs5_PBKDF2_F(hashobj, pwitem, salt, iterations, i, T);
- if (rv != SECSuccess) {
- break;
- }
- PORT_Memcpy(rp,T,hLen);
+ if (rv != SECSuccess) {
+ break;
+ }
+ PORT_Memcpy(rp, T, hLen);
}
loser:
if (T) {
- PORT_ZFree(T,hLen);
+ PORT_ZFree(T, hLen);
}
if (rv != SECSuccess) {
- SECITEM_FreeItem(result,PR_TRUE);
- result = NULL;
+ SECITEM_FreeItem(result, PR_TRUE);
+ result = NULL;
} else {
- result->len = dkLen;
+ 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))
+#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)
+nsspkcs5_PKCS12PBE(const SECHashObject *hashObject,
+ NSSPKCS5PBEParameter *pbe_param, SECItem *pwitem,
+ PBEBitGenID bitGenPurpose, unsigned int bytesNeeded)
{
PLArenaPool *arena = NULL;
- unsigned int SLen,PLen;
+ 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 c, i = 0;
unsigned int hashLen;
int iter;
unsigned char *iterBuf;
void *hash = NULL;
arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
- if(!arena) {
- return NULL;
+ if (!arena) {
+ return NULL;
}
/* how many hash object lengths are needed */
- c = (bytesNeeded + (hashLength-1))/hashLength;
+ 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);
+ 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);
+ A = SECITEM_AllocItem(NULL, NULL, c * hashLength);
if (A == NULL) {
- goto loser;
+ 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);
+
+ 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;
+ goto loser;
}
/* S & P are only used to initialize I */
@@ -473,88 +466,87 @@ nsspkcs5_PKCS12PBE(const SECHashObject *hashObject,
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));
- }
- }
+ 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));
- }
- }
+ 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);
+ iterBuf = (unsigned char *)PORT_ArenaZAlloc(arena, hashLength);
if (iterBuf == NULL) {
- goto loser;
+ goto loser;
}
hash = hashObject->create();
- if(!hash) {
- goto loser;
+ 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 < (int)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);
- }
- }
+ 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 < (int)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);
+ hashObject->destroy(hash, PR_TRUE);
}
- if(arena) {
- PORT_FreeArena(arena, 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;
+ SECITEM_ZfreeItem(A, PR_TRUE);
+ A = NULL;
} else {
- A->len = bytesNeeded;
+ A->len = bytesNeeded;
}
}
-
+
return A;
}
@@ -563,78 +555,76 @@ loser:
*/
SECItem *
nsspkcs5_ComputeKeyAndIV(NSSPKCS5PBEParameter *pbe_param, SECItem *pwitem,
- SECItem *iv, PRBool faulty3DES)
+ SECItem *iv, PRBool faulty3DES)
{
SECItem *hash = NULL, *key = NULL;
const SECHashObject *hashObj;
PRBool getIV = PR_FALSE;
- if((pbe_param == NULL) || (pwitem == NULL)) {
- return NULL;
+ if ((pbe_param == NULL) || (pwitem == NULL)) {
+ return NULL;
}
- key = SECITEM_AllocItem(NULL,NULL,pbe_param->keyLen);
+ key = SECITEM_AllocItem(NULL, NULL, pbe_param->keyLen);
if (key == NULL) {
- return 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;
+ 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;
+ 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;
+ case NSSPKCS5_PBKDF2:
+ hash = nsspkcs5_PBKDF2(hashObj, pbe_param, pwitem);
+ if (getIV) {
+ PORT_Memcpy(iv->data, pbe_param->ivData, iv->len);
+ }
+ break;
+ 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;
+ 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);
+ 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);
+ PORT_Memcpy(key->data, hash->data, key->len);
}
SECITEM_ZfreeItem(hash, PR_TRUE);
@@ -642,8 +632,8 @@ nsspkcs5_ComputeKeyAndIV(NSSPKCS5PBEParameter *pbe_param, SECItem *pwitem,
loser:
if (getIV && iv->data) {
- PORT_ZFree(iv->data,iv->len);
- iv->data = NULL;
+ PORT_ZFree(iv->data, iv->len);
+ iv->data = NULL;
}
SECITEM_ZfreeItem(key, PR_TRUE);
@@ -651,86 +641,85 @@ loser:
}
static SECStatus
-nsspkcs5_FillInParam(SECOidTag algorithm, NSSPKCS5PBEParameter *pbe_param)
+nsspkcs5_FillInParam(SECOidTag algorithm, HASH_HashType hashType,
+ NSSPKCS5PBEParameter *pbe_param)
{
PRBool skipType = PR_FALSE;
pbe_param->keyLen = 5;
pbe_param->ivLen = 8;
- pbe_param->hashType = HASH_AlgSHA1;
+ pbe_param->hashType = hashType;
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;
+ 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;
+
+ 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;
+
+ default:
+ return SECFailure;
}
return SECSuccess;
@@ -739,7 +728,8 @@ finish_des:
/* decode the algid and generate a PKCS 5 parameter from it
*/
NSSPKCS5PBEParameter *
-nsspkcs5_NewParam(SECOidTag alg, SECItem *salt, int iterator)
+nsspkcs5_NewParam(SECOidTag alg, HASH_HashType hashType, SECItem *salt,
+ int iterationCount)
{
PLArenaPool *arena = NULL;
NSSPKCS5PBEParameter *pbe_param = NULL;
@@ -747,26 +737,26 @@ nsspkcs5_NewParam(SECOidTag alg, SECItem *salt, int iterator)
arena = PORT_NewArena(SEC_ASN1_DEFAULT_ARENA_SIZE);
if (arena == NULL)
- return NULL;
+ return NULL;
/* allocate memory for the parameter */
- pbe_param = (NSSPKCS5PBEParameter *)PORT_ArenaZAlloc(arena,
- sizeof(NSSPKCS5PBEParameter));
+ pbe_param = (NSSPKCS5PBEParameter *)PORT_ArenaZAlloc(arena,
+ sizeof(NSSPKCS5PBEParameter));
if (pbe_param == NULL) {
- goto loser;
+ goto loser;
}
pbe_param->poolp = arena;
- rv = nsspkcs5_FillInParam(alg, pbe_param);
+ rv = nsspkcs5_FillInParam(alg, hashType, pbe_param);
if (rv != SECSuccess) {
- goto loser;
+ goto loser;
}
- pbe_param->iter = iterator;
+ pbe_param->iter = iterationCount;
if (salt) {
- rv = SECITEM_CopyItem(arena,&pbe_param->salt,salt);
+ rv = SECITEM_CopyItem(arena, &pbe_param->salt, salt);
}
/* default key gen */
@@ -774,8 +764,8 @@ nsspkcs5_NewParam(SECOidTag alg, SECItem *salt, int iterator)
loser:
if (rv != SECSuccess) {
- PORT_FreeArena(arena, PR_TRUE);
- pbe_param = NULL;
+ PORT_FreeArena(arena, PR_TRUE);
+ pbe_param = NULL;
}
return pbe_param;
@@ -789,17 +779,17 @@ 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;
+ 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;
}
@@ -815,169 +805,166 @@ nsspkcs5_AlgidToParam(SECAlgorithmID *algid)
SECStatus rv = SECFailure;
if (algid == NULL) {
- return NULL;
+ return NULL;
}
algorithm = SECOID_GetAlgorithmTag(algid);
if (algorithm == SEC_OID_UNKNOWN) {
- goto loser;
+ goto loser;
}
- pbe_param = nsspkcs5_NewParam(algorithm, NULL, 1);
+ pbe_param = nsspkcs5_NewParam(algorithm, HASH_AlgSHA1, NULL, 1);
if (pbe_param == NULL) {
- goto loser;
+ 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
+ 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;
+ 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;
}
loser:
if (rv == SECSuccess) {
- pbe_param->iter = DER_GetInteger(&pbe_param->iteration);
+ pbe_param->iter = DER_GetInteger(&pbe_param->iteration);
} else {
- nsspkcs5_DestroyPBEParameter(pbe_param);
- pbe_param = NULL;
+ nsspkcs5_DestroyPBEParameter(pbe_param);
+ pbe_param = NULL;
}
return pbe_param;
}
-/* destroy a pbe parameter. it assumes that the parameter was
+/* destroy a pbe parameter. it assumes that the parameter was
* generated using the appropriate create function and therefor
* contains an arena pool.
*/
-void
+void
nsspkcs5_DestroyPBEParameter(NSSPKCS5PBEParameter *pbe_param)
{
if (pbe_param != NULL) {
- PORT_FreeArena(pbe_param->poolp, PR_FALSE);
+ 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)
+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;
+ if ((src == NULL) || (key == NULL) || (iv == NULL))
+ return NULL;
dup_src = SECITEM_DupItem(src);
- if(dup_src == NULL) {
- return NULL;
+ if (dup_src == NULL) {
+ return NULL;
}
- if(encrypt != PR_FALSE) {
- void *dummy;
+ 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;
+ 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);
+ 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;
@@ -986,77 +973,77 @@ sec_pkcs5_des(SECItem *key, SECItem *iv, SECItem *src, PRBool triple_des,
/* 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)
+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;
+ if ((src == NULL) || (key == NULL) || (iv == NULL))
+ return NULL;
dup_src = SECITEM_DupItem(src);
- if(dup_src == NULL) {
- return NULL;
+ if (dup_src == NULL) {
+ return NULL;
}
- if(encrypt != PR_FALSE) {
- void *dummy;
+ 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;
+ 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);
+ 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;
@@ -1065,76 +1052,75 @@ sec_pkcs5_aes(SECItem *key, SECItem *iv, SECItem *src, PRBool triple_des,
/* 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)
+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;
+ if ((src == NULL) || (key == NULL) || (iv == NULL)) {
+ return NULL;
}
dup_src = SECITEM_DupItem(src);
- if(dup_src == NULL) {
- return NULL;
+ if (dup_src == NULL) {
+ return NULL;
}
- if(encrypt != PR_FALSE) {
- void *dummy;
+ 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;
+ 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 (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 ((rv != SECSuccess) && (dest != NULL)) {
+ SECITEM_FreeItem(dest, PR_TRUE);
+ dest = NULL;
}
- if(dup_src != NULL) {
- SECITEM_FreeItem(dup_src, PR_TRUE);
+ if (dup_src != NULL) {
+ SECITEM_FreeItem(dup_src, PR_TRUE);
}
return dest;
@@ -1143,53 +1129,53 @@ sec_pkcs5_rc2(SECItem *key, SECItem *iv, SECItem *src, PRBool dummy,
/* perform rc4 encryption and decryption */
static SECItem *
sec_pkcs5_rc4(SECItem *key, SECItem *iv, SECItem *src, PRBool dummy_op,
- PRBool encrypt)
+ PRBool encrypt)
{
SECItem *dest;
SECStatus rv = SECFailure;
- if((src == NULL) || (key == NULL) || (iv == NULL)) {
- return NULL;
+ 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 (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;
+ 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);
+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.
+ * 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)
+nsspkcs5_CipherData(NSSPKCS5PBEParameter *pbe_param, SECItem *pwitem,
+ SECItem *src, PRBool encrypt, PRBool *update)
{
SECItem *key = NULL, iv;
SECItem *dest = NULL;
@@ -1198,71 +1184,72 @@ nsspkcs5_CipherData(NSSPKCS5PBEParameter *pbe_param, SECItem *pwitem,
iv.data = NULL;
- if (update) {
+ if (update) {
*update = PR_FALSE;
}
if ((pwitem == NULL) || (src == NULL)) {
- return 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 (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;
+ 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
+ * 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;
+ 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);
+ SECITEM_ZfreeItem(key, PR_TRUE);
}
if (iv.data != NULL) {
- SECITEM_ZfreeItem(&iv, PR_FALSE);
+ SECITEM_ZfreeItem(&iv, PR_FALSE);
}
return dest;
@@ -1271,14 +1258,14 @@ loser:
/* 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 PKCS 5 generation of the IV.
*
- * the returned SECAlgorithmID should be destroyed using
+ * the returned SECAlgorithmID should be destroyed using
* SECOID_DestroyAlgorithmID
*/
SECAlgorithmID *
nsspkcs5_CreateAlgorithmID(PLArenaPool *arena, SECOidTag algorithm,
- NSSPKCS5PBEParameter *pbe_param)
+ NSSPKCS5PBEParameter *pbe_param)
{
SECAlgorithmID *algid, *ret_algid = NULL;
SECItem der_param;
@@ -1288,7 +1275,7 @@ nsspkcs5_CreateAlgorithmID(PLArenaPool *arena, SECOidTag algorithm,
void *dummy = NULL;
if (arena == NULL) {
- return NULL;
+ return NULL;
}
der_param.data = NULL;
@@ -1297,82 +1284,80 @@ nsspkcs5_CreateAlgorithmID(PLArenaPool *arena, SECOidTag algorithm,
/* generate the algorithm id */
algid = (SECAlgorithmID *)PORT_ArenaZAlloc(arena, sizeof(SECAlgorithmID));
if (algid == NULL) {
- goto loser;
+ 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;
- }
+ 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;
+ 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;
+ 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;
+ default:
+ break;
}
if (dummy == NULL) {
- goto loser;
+ goto loser;
}
-
+
rv = SECOID_SetAlgorithmID(arena, algid, algorithm, &der_param);
if (rv != SECSuccess) {
- goto loser;
+ goto loser;
}
ret_algid = (SECAlgorithmID *)PORT_ZAlloc(sizeof(SECAlgorithmID));
if (ret_algid == NULL) {
- goto loser;
+ goto loser;
}
rv = SECOID_CopyAlgorithmID(NULL, ret_algid, algid);
if (rv != SECSuccess) {
- SECOID_DestroyAlgorithmID(ret_algid, PR_TRUE);
- ret_algid = NULL;
+ SECOID_DestroyAlgorithmID(ret_algid, PR_TRUE);
+ ret_algid = NULL;
}
-loser:
+loser:
return ret_algid;
}
diff --git a/nss/lib/softoken/lowpbe.h b/nss/lib/softoken/lowpbe.h
index 00c1007..2080138 100644
--- a/nss/lib/softoken/lowpbe.h
+++ b/nss/lib/softoken/lowpbe.h
@@ -11,9 +11,9 @@
#include "secoidt.h"
#include "hasht.h"
-typedef SECItem * (* SEC_PKCS5GetPBEPassword)(void *arg);
+typedef SECItem *(*SEC_PKCS5GetPBEPassword)(void *arg);
-/* used for V2 PKCS 12 Draft Spec */
+/* used for V2 PKCS 12 Draft Spec */
typedef enum {
pbeBitGenIDNull = 0,
pbeBitGenCipherKey = 0x01,
@@ -31,37 +31,36 @@ typedef struct NSSPKCS5PBEParameterStr NSSPKCS5PBEParameter;
struct NSSPKCS5PBEParameterStr {
PLArenaPool *poolp;
- SECItem salt; /* octet string */
- SECItem iteration; /* integer */
- SECItem keyLength; /* integer */
+ SECItem salt; /* octet string */
+ SECItem iteration; /* integer */
+ SECItem keyLength; /* integer */
/* used locally */
- int iter;
- int keyLen;
- int ivLen;
+ int iter;
+ int keyLen;
+ int ivLen;
unsigned char *ivData;
HASH_HashType hashType;
NSSPKCS5PBEType pbeType;
- SECAlgorithmID prfAlg;
- PBEBitGenID keyID;
- SECOidTag encAlg;
- PRBool is2KeyDES;
+ 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
+ * 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
+ * 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(PLArenaPool *arena, SECOidTag algorithm,
- NSSPKCS5PBEParameter *pbe);
+ NSSPKCS5PBEParameter *pbe);
/*
* Convert an Algorithm ID to a PBE Param.
@@ -77,10 +76,10 @@ nsspkcs5_AlgidToParam(SECAlgorithmID *algid);
* keyDB which only support PKCS 5 v1, PFX, and PKCS 12.
*/
NSSPKCS5PBEParameter *
-nsspkcs5_NewParam(SECOidTag alg, SECItem *salt, int iterator);
-
+nsspkcs5_NewParam(SECOidTag alg, HASH_HashType hashType, SECItem *salt,
+ int iterationCount);
-/* Encrypt/Decrypt data using password based encryption.
+/* Encrypt/Decrypt data using password based encryption.
* algid is the PBE algorithm identifier,
* pwitem is the password,
* src is the source for encryption/decryption,
@@ -91,11 +90,11 @@ nsspkcs5_NewParam(SECOidTag alg, SECItem *salt, int iterator);
*/
extern SECItem *
nsspkcs5_CipherData(NSSPKCS5PBEParameter *, SECItem *pwitem,
- SECItem *src, PRBool encrypt, PRBool *update);
+ SECItem *src, PRBool encrypt, PRBool *update);
extern SECItem *
nsspkcs5_ComputeKeyAndIV(NSSPKCS5PBEParameter *, SECItem *pwitem,
- SECItem *iv, PRBool faulty3DES);
+ SECItem *iv, PRBool faulty3DES);
/* Destroys PBE parameter */
extern void
diff --git a/nss/lib/softoken/manifest.mn b/nss/lib/softoken/manifest.mn
index 2f43bb3..256d443 100644
--- a/nss/lib/softoken/manifest.mn
+++ b/nss/lib/softoken/manifest.mn
@@ -1,4 +1,4 @@
-#
+#
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
@@ -18,12 +18,12 @@ INCLUDES += -I$(SQLITE_INCLUDE_DIR)
endif
EXPORTS = \
+ lowkeyi.h \
+ lowkeyti.h \
$(NULL)
PRIVATE_EXPORTS = \
lgglue.h \
- lowkeyi.h \
- lowkeyti.h \
pkcs11ni.h \
softoken.h \
softoknt.h \
diff --git a/nss/lib/softoken/padbuf.c b/nss/lib/softoken/padbuf.c
index 1f030b8..6e897f2 100644
--- a/nss/lib/softoken/padbuf.c
+++ b/nss/lib/softoken/padbuf.c
@@ -6,7 +6,7 @@
#include "secerr.h"
/*
- * Prepare a buffer for any padded CBC encryption algorithm, growing to the
+ * 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.
*
@@ -15,12 +15,12 @@
*/
unsigned char *
CBC_PadBuffer(PLArenaPool *arena, unsigned char *inbuf, unsigned int inlen,
- unsigned int *outlen, int blockSize)
+ unsigned int *outlen, int blockSize)
{
unsigned char *outbuf;
- unsigned int des_len;
- unsigned int i;
- unsigned char des_pad_len;
+ unsigned int des_len;
+ unsigned int i;
+ unsigned char des_pad_len;
/*
* We need from 1 to blockSize bytes -- we *always* grow.
@@ -30,19 +30,19 @@ CBC_PadBuffer(PLArenaPool *arena, unsigned char *inbuf, unsigned int inlen,
des_len = (inlen + blockSize) & ~(blockSize - 1);
if (arena != NULL) {
- outbuf = (unsigned char*)PORT_ArenaGrow (arena, inbuf, inlen, des_len);
+ outbuf = (unsigned char *)PORT_ArenaGrow(arena, inbuf, inlen, des_len);
} else {
- outbuf = (unsigned char*)PORT_Realloc (inbuf, des_len);
+ outbuf = (unsigned char *)PORT_Realloc(inbuf, des_len);
}
if (outbuf == NULL) {
- PORT_SetError (SEC_ERROR_NO_MEMORY);
- return 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;
+ outbuf[i] = des_pad_len;
*outlen = des_len;
return outbuf;
diff --git a/nss/lib/softoken/pkcs11.c b/nss/lib/softoken/pkcs11.c
index 97d6d3f..77212f7 100644
--- a/nss/lib/softoken/pkcs11.c
+++ b/nss/lib/softoken/pkcs11.c
@@ -6,11 +6,11 @@
*
* 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
+ * 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
+ * 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.
*
@@ -32,7 +32,7 @@
#include "softkver.h"
#include "secoid.h"
#include "sftkdb.h"
-#include "utilpars.h"
+#include "utilpars.h"
#include "ec.h"
#include "secasn1.h"
#include "secerr.h"
@@ -65,9 +65,9 @@ PRBool usePthread_atfork;
*/
/* The next three strings must be exactly 32 characters long */
-static char *manufacturerID = "Mozilla Foundation ";
+static char *manufacturerID = "Mozilla Foundation ";
static char manufacturerID_space[33];
-static char *libraryDescription = "NSS Internal Crypto Services ";
+static char *libraryDescription = "NSS Internal Crypto Services ";
static char libraryDescription_space[33];
/*
@@ -75,48 +75,46 @@ static char libraryDescription_space[33];
* failure so that there are at most 60 login attempts per minute.
*/
static PRIntervalTime loginWaitTime;
-static PRUint32 minSessionObjectHandle = 1U;
+static PRUint32 minSessionObjectHandle = 1U;
-#define __PASTE(x,y) x##y
+#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
-
+ 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),
+ __PASTE(NS, func) \
+ ,
#include "pkcs11f.h"
-
+
};
-
+
#undef CK_PKCS11_FUNCTION_INFO
#undef CK_NEED_ARG_LIST
-
-
+
#undef __PASTE
-/* List of DES Weak Keys */
+/* List of DES Weak Keys */
typedef unsigned char desKey[8];
-static const desKey sftk_desWeakTable[] = {
+static const desKey sftk_desWeakTable[] = {
#ifdef noParity
/* weak */
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
@@ -164,57 +162,56 @@ static const desKey sftk_desWeakTable[] = {
{ 0x01, 0x1f, 0x01, 0x1f, 0x01, 0x0e, 0x01, 0x0e },
{ 0x1f, 0x01, 0x1f, 0x01, 0x0e, 0x01, 0x0e, 0x01 },
- { 0xe0, 0xfe, 0xe0, 0xfe, 0xf1, 0xfe, 0xf1, 0xfe },
+ { 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]);
+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,
+ /* 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;
+ CK_MECHANISM_TYPE type;
+ CK_MECHANISM_INFO info;
+ PRBool privkey;
};
/*
@@ -222,24 +219,24 @@ struct mechanismList {
* 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 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_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_PNU CKF_EC_FP | CKF_EC_NAMEDCURVE | CKF_EC_UNCOMPRESS
-#define CKF_EC_BPNU CKF_EC_F_2M | CKF_EC_PNU
+#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.
@@ -253,269 +250,257 @@ static const struct mechanismList mechanisms[] = {
* 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
+ * 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},
- {CKM_RSA_PKCS_OAEP, {RSA_MIN_MODULUS_BITS,CK_MAX,
- CKF_EN_DE_WR_UN}, PR_TRUE},
+ /* ------------------------- 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 },
+ { CKM_RSA_PKCS_OAEP, { RSA_MIN_MODULUS_BITS, CK_MAX, CKF_EN_DE_WR_UN }, PR_TRUE },
#ifdef SFTK_RSA9796_SUPPORTED
- {CKM_RSA_9796, {RSA_MIN_MODULUS_BITS,CK_MAX,
- CKF_DUZ_IT_ALL}, PR_TRUE},
+ { 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},
+ { 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 },
#ifndef NSS_DISABLE_ECC
- /* -------------------- Elliptic Curve Operations --------------------- */
- {CKM_EC_KEY_PAIR_GEN, {EC_MIN_KEY_BITS, EC_MAX_KEY_BITS,
- CKF_GENERATE_KEY_PAIR|CKF_EC_BPNU}, PR_TRUE},
- {CKM_ECDH1_DERIVE, {EC_MIN_KEY_BITS, EC_MAX_KEY_BITS,
- CKF_DERIVE|CKF_EC_BPNU}, PR_TRUE},
- {CKM_ECDSA, {EC_MIN_KEY_BITS, EC_MAX_KEY_BITS,
- CKF_SN_VR|CKF_EC_BPNU}, PR_TRUE},
- {CKM_ECDSA_SHA1, {EC_MIN_KEY_BITS, EC_MAX_KEY_BITS,
- CKF_SN_VR|CKF_EC_BPNU}, PR_TRUE},
+ /* -------------------- Elliptic Curve Operations --------------------- */
+ { CKM_EC_KEY_PAIR_GEN, { EC_MIN_KEY_BITS, EC_MAX_KEY_BITS, CKF_GENERATE_KEY_PAIR | CKF_EC_BPNU }, PR_TRUE },
+ { CKM_ECDH1_DERIVE, { EC_MIN_KEY_BITS, EC_MAX_KEY_BITS, CKF_DERIVE | CKF_EC_BPNU }, PR_TRUE },
+ { CKM_ECDSA, { EC_MIN_KEY_BITS, EC_MAX_KEY_BITS, CKF_SN_VR | CKF_EC_BPNU }, PR_TRUE },
+ { CKM_ECDSA_SHA1, { EC_MIN_KEY_BITS, EC_MAX_KEY_BITS, CKF_SN_VR | CKF_EC_BPNU }, PR_TRUE },
#endif /* NSS_DISABLE_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},
- {CKM_TLS_MAC, {0, 512, CKF_SN_VR}, PR_FALSE},
- {CKM_NSS_TLS_PRF_GENERAL_SHA256,
- {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 --------------------------- */
+ /* ------------------------- 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 },
+#ifndef NSS_DISABLE_CHACHAPOLY
+ /* ------------------------- ChaCha20 Operations ---------------------- */
+ { CKM_NSS_CHACHA20_KEY_GEN, { 32, 32, CKF_GENERATE }, PR_TRUE },
+ { CKM_NSS_CHACHA20_POLY1305, { 32, 32, CKF_EN_DE }, PR_TRUE },
+#endif /* NSS_DISABLE_CHACHAPOLY */
+ /* ------------------------- 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 },
+ { CKM_TLS_MAC, { 0, 512, CKF_SN_VR }, PR_FALSE },
+ { CKM_NSS_TLS_PRF_GENERAL_SHA256,
+ { 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},
+ /* 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},
+ /* ------------------------- 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},
+ /* ------------------------- 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_TLS12_MASTER_KEY_DERIVE, {48, 48, CKF_DERIVE}, PR_FALSE},
- {CKM_NSS_TLS_MASTER_KEY_DERIVE_SHA256,
- {48, 48, CKF_DERIVE}, PR_FALSE},
- {CKM_TLS_MASTER_KEY_DERIVE_DH, {8, 128, CKF_DERIVE}, PR_FALSE},
- {CKM_TLS12_MASTER_KEY_DERIVE_DH, {8, 128, CKF_DERIVE}, PR_FALSE},
- {CKM_NSS_TLS_MASTER_KEY_DERIVE_DH_SHA256,
- {8, 128, CKF_DERIVE}, PR_FALSE},
- {CKM_TLS_KEY_AND_MAC_DERIVE, {48, 48, CKF_DERIVE}, PR_FALSE},
- {CKM_TLS12_KEY_AND_MAC_DERIVE, {48, 48, CKF_DERIVE}, PR_FALSE},
- {CKM_NSS_TLS_KEY_AND_MAC_DERIVE_SHA256,
- {48, 48, CKF_DERIVE}, PR_FALSE},
- {CKM_NSS_TLS_EXTENDED_MASTER_KEY_DERIVE,
- {48,128, CKF_DERIVE}, PR_FALSE},
- {CKM_NSS_TLS_EXTENDED_MASTER_KEY_DERIVE_DH,
- {48,128, 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}
+ /* --------------------- 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_TLS12_MASTER_KEY_DERIVE, { 48, 48, CKF_DERIVE }, PR_FALSE },
+ { CKM_NSS_TLS_MASTER_KEY_DERIVE_SHA256,
+ { 48, 48, CKF_DERIVE },
+ PR_FALSE },
+ { CKM_TLS_MASTER_KEY_DERIVE_DH, { 8, 128, CKF_DERIVE }, PR_FALSE },
+ { CKM_TLS12_MASTER_KEY_DERIVE_DH, { 8, 128, CKF_DERIVE }, PR_FALSE },
+ { CKM_NSS_TLS_MASTER_KEY_DERIVE_DH_SHA256,
+ { 8, 128, CKF_DERIVE },
+ PR_FALSE },
+ { CKM_TLS_KEY_AND_MAC_DERIVE, { 48, 48, CKF_DERIVE }, PR_FALSE },
+ { CKM_TLS12_KEY_AND_MAC_DERIVE, { 48, 48, CKF_DERIVE }, PR_FALSE },
+ { CKM_NSS_TLS_KEY_AND_MAC_DERIVE_SHA256,
+ { 48, 48, CKF_DERIVE },
+ PR_FALSE },
+ { CKM_NSS_TLS_EXTENDED_MASTER_KEY_DERIVE,
+ { 48, 128, CKF_DERIVE },
+ PR_FALSE },
+ { CKM_NSS_TLS_EXTENDED_MASTER_KEY_DERIVE_DH,
+ { 48, 128, 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]);
+static const CK_ULONG mechanismCount = sizeof(mechanisms) / sizeof(mechanisms[0]);
/* sigh global so fipstokn can read it */
PRBool nsc_init = PR_FALSE;
@@ -524,7 +509,8 @@ PRBool nsc_init = PR_FALSE;
#include <pthread.h>
-static void ForkedChild(void)
+static void
+ForkedChild(void)
{
if (nsc_init || nsf_init) {
forked = PR_TRUE;
@@ -534,18 +520,18 @@ static void ForkedChild(void)
#endif
static char *
-sftk_setStringName(const char *inString, char *buffer, int buffer_length, PRBool nullTerminate)
+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;
+ 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
+ * 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
+ * - 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'
@@ -556,32 +542,32 @@ sftk_setStringName(const char *inString, char *buffer, int buffer_length, PRBo
* 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
+ * 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
+ 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--;
- }
+ if (string_length) {
+ /* remove either '11' byte or an asci byte */
+ string_length--;
+ }
}
- PORT_Memset(buffer,' ',full_length);
+ PORT_Memset(buffer, ' ', full_length);
if (nullTerminate) {
- buffer[full_length] = 0;
+ buffer[full_length] = 0;
}
- PORT_Memcpy(buffer,inString,string_length);
+ PORT_Memcpy(buffer, inString, string_length);
return buffer;
}
/*
@@ -593,13 +579,13 @@ 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);
+ manufacturerID = sftk_setStringName(man, manufacturerID_space,
+ sizeof(manufacturerID_space), PR_TRUE);
}
if (libdes) {
- libraryDescription = sftk_setStringName(libdes,
- libraryDescription_space, sizeof(libraryDescription_space),
- PR_TRUE);
+ libraryDescription = sftk_setStringName(libdes,
+ libraryDescription_space, sizeof(libraryDescription_space),
+ PR_TRUE);
}
return CKR_OK;
@@ -616,15 +602,15 @@ 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);
+ PRBool tokenRemoved = PR_FALSE;
+ SECStatus rv = sftkdb_CheckPassword(keydb, "", &tokenRemoved);
+ if (tokenRemoved) {
+ sftk_CloseAllSessions(slot, PR_FALSE);
+ }
+ return (rv == SECSuccess);
}
return pwenabled;
@@ -634,246 +620,250 @@ sftk_hasNullPassword(SFTKSlot *slot, SFTKDBHandle *keydb)
* ******************** 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)
+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);
+ if (!sftk_hasAttribute(object, type)) {
+ return sftk_AddAttributeType(object, type, value, len);
}
return CKR_OK;
}
/*
- * check the consistancy and initialize a Data Object
+ * check the consistancy and initialize a Data Object
*/
static CK_RV
-sftk_handleDataObject(SFTKSession *session,SFTKObject *object)
+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;
+ 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;
+ 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
+ * check the consistancy and initialize a Certificate Object
*/
static CK_RV
-sftk_handleCertObject(SFTKSession *session,SFTKObject *object)
+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;
+ 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;
+ 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;
+ 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;
+ return CKR_ATTRIBUTE_VALUE_INVALID;
}
/* X.509 Certificate */
/* make sure we have a cert */
- if ( !sftk_hasAttribute(object,CKA_VALUE) ) {
- return CKR_TEMPLATE_INCOMPLETE;
+ 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;
+ 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;
+ 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;
+ if (!sftk_hasAttribute(object, CKA_SERIAL_NUMBER)) {
+ return CKR_TEMPLATE_INCOMPLETE;
}
/* add it to the object */
object->objectInfo = NULL;
- object->infoFree = (SFTKFree) 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 (crv != CKR_OK) {
+ return crv;
+ }
- if (sftk_isTrue(object,CKA_TOKEN)) {
- SFTKSlot *slot = session->slot;
- SFTKDBHandle *certHandle = sftk_getCertDB(slot);
+ if (sftk_isTrue(object, CKA_TOKEN)) {
+ SFTKSlot *slot = session->slot;
+ SFTKDBHandle *certHandle = sftk_getCertDB(slot);
- if (certHandle == NULL) {
- return CKR_TOKEN_WRITE_PROTECTED;
- }
+ if (certHandle == NULL) {
+ return CKR_TOKEN_WRITE_PROTECTED;
+ }
- crv = sftkdb_write(certHandle, object, &object->handle);
- sftk_freeDB(certHandle);
- return crv;
+ crv = sftkdb_write(certHandle, object, &object->handle);
+ sftk_freeDB(certHandle);
+ return crv;
}
return CKR_OK;
}
-
+
/*
- * check the consistancy and initialize a Trust Object
+ * check the consistancy and initialize a Trust Object
*/
static CK_RV
-sftk_handleTrustObject(SFTKSession *session,SFTKObject *object)
+sftk_handleTrustObject(SFTKSession *session, SFTKObject *object)
{
/* we can't store any certs private */
- if (sftk_isTrue(object,CKA_PRIVATE)) {
- return CKR_ATTRIBUTE_VALUE_INVALID;
+ 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_ISSUER)) {
+ return CKR_TEMPLATE_INCOMPLETE;
}
- if ( !sftk_hasAttribute(object,CKA_SERIAL_NUMBER) ) {
- 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_SHA1_HASH)) {
+ return CKR_TEMPLATE_INCOMPLETE;
}
- if ( !sftk_hasAttribute(object,CKA_CERT_MD5_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 (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;
- }
+ if (certHandle == NULL) {
+ return CKR_TOKEN_WRITE_PROTECTED;
+ }
- crv = sftkdb_write(certHandle, object, &object->handle);
- sftk_freeDB(certHandle);
- return crv;
+ crv = sftkdb_write(certHandle, object, &object->handle);
+ sftk_freeDB(certHandle);
+ return crv;
}
return CKR_OK;
}
/*
- * check the consistancy and initialize a Trust Object
+ * check the consistancy and initialize a Trust Object
*/
static CK_RV
-sftk_handleSMimeObject(SFTKSession *session,SFTKObject *object)
+sftk_handleSMimeObject(SFTKSession *session, SFTKObject *object)
{
/* we can't store any certs private */
- if (sftk_isTrue(object,CKA_PRIVATE)) {
- return CKR_ATTRIBUTE_VALUE_INVALID;
+ 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_SUBJECT)) {
+ return CKR_TEMPLATE_INCOMPLETE;
}
- if ( !sftk_hasAttribute(object,CKA_NETSCAPE_EMAIL) ) {
- 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;
+ 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;
- }
+ PORT_Assert(slot);
+ if (slot == NULL) {
+ return CKR_SESSION_HANDLE_INVALID;
+ }
- certHandle = sftk_getCertDB(slot);
- if (certHandle == NULL) {
- return CKR_TOKEN_WRITE_PROTECTED;
- }
+ certHandle = sftk_getCertDB(slot);
+ if (certHandle == NULL) {
+ return CKR_TOKEN_WRITE_PROTECTED;
+ }
- crv = sftkdb_write(certHandle, object, &object->handle);
- sftk_freeDB(certHandle);
- return crv;
+ crv = sftkdb_write(certHandle, object, &object->handle);
+ sftk_freeDB(certHandle);
+ return crv;
}
return CKR_OK;
}
/*
- * check the consistancy and initialize a Trust Object
+ * check the consistancy and initialize a Trust Object
*/
static CK_RV
-sftk_handleCrlObject(SFTKSession *session,SFTKObject *object)
+sftk_handleCrlObject(SFTKSession *session, SFTKObject *object)
{
/* we can't store any certs private */
- if (sftk_isTrue(object,CKA_PRIVATE)) {
- return CKR_ATTRIBUTE_VALUE_INVALID;
+ 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_SUBJECT)) {
+ return CKR_TEMPLATE_INCOMPLETE;
}
- if ( !sftk_hasAttribute(object,CKA_VALUE) ) {
- 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 (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;
- }
+ if (certHandle == NULL) {
+ return CKR_TOKEN_WRITE_PROTECTED;
+ }
- crv = sftkdb_write(certHandle, object, &object->handle);
- sftk_freeDB(certHandle);
- return crv;
+ crv = sftkdb_write(certHandle, object, &object->handle);
+ sftk_freeDB(certHandle);
+ return crv;
}
return CKR_OK;
}
/*
- * check the consistancy and initialize a Public Key Object
+ * check the consistancy and initialize a Public Key Object
*/
static CK_RV
sftk_handlePublicKeyObject(SFTKSession *session, SFTKObject *object,
- CK_KEY_TYPE key_type)
+ CK_KEY_TYPE key_type)
{
CK_BBOOL encrypt = CK_TRUE;
CK_BBOOL recover = CK_TRUE;
@@ -883,138 +873,144 @@ sftk_handlePublicKeyObject(SFTKSession *session, SFTKObject *object,
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;
+ 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;
#ifndef NSS_DISABLE_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;
+ 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_DISABLE_ECC */
- default:
- return CKR_ATTRIBUTE_VALUE_INVALID;
+ 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);
+ 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;
+ return crv;
}
- object->infoFree = (SFTKFree) nsslowkey_DestroyPublicKey;
+ object->infoFree = (SFTKFree)nsslowkey_DestroyPublicKey;
/* Check that an imported EC key is valid */
if (key_type == CKK_EC) {
- NSSLOWKEYPublicKey *pubKey = (NSSLOWKEYPublicKey*) object->objectInfo;
- SECStatus rv = EC_ValidatePublicKey(&pubKey->u.ec.ecParams,
- &pubKey->u.ec.publicValue);
+ NSSLOWKEYPublicKey *pubKey = (NSSLOWKEYPublicKey *)object->objectInfo;
+ SECStatus rv = EC_ValidatePublicKey(&pubKey->u.ec.ecParams,
+ &pubKey->u.ec.publicValue);
- if (rv != SECSuccess) {
- return CKR_TEMPLATE_INCONSISTENT;
- }
+ if (rv != SECSuccess) {
+ return CKR_TEMPLATE_INCONSISTENT;
+ }
}
- if (sftk_isTrue(object,CKA_TOKEN)) {
- SFTKSlot *slot = session->slot;
- SFTKDBHandle *certHandle = sftk_getCertDB(slot);
+ if (sftk_isTrue(object, CKA_TOKEN)) {
+ SFTKSlot *slot = session->slot;
+ SFTKDBHandle *certHandle = sftk_getCertDB(slot);
- if (certHandle == NULL) {
- return CKR_TOKEN_WRITE_PROTECTED;
- }
+ if (certHandle == NULL) {
+ return CKR_TOKEN_WRITE_PROTECTED;
+ }
- crv = sftkdb_write(certHandle, object, &object->handle);
- sftk_freeDB(certHandle);
- return crv;
+ 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 NSSLOWKEYPrivateKey *
+sftk_mkPrivKey(SFTKObject *object, CK_KEY_TYPE key, CK_RV *rvp);
static SECStatus
sftk_verifyRSAPrivateKey(SFTKObject *object, PRBool fillIfNeeded);
/*
- * check the consistancy and initialize a Private Key Object
+ * check the consistancy and initialize a Private Key Object
*/
static CK_RV
-sftk_handlePrivateKeyObject(SFTKSession *session,SFTKObject *object,CK_KEY_TYPE key_type)
+sftk_handlePrivateKeyObject(SFTKSession *session, SFTKObject *object, CK_KEY_TYPE key_type)
{
CK_BBOOL cktrue = CK_TRUE;
CK_BBOOL encrypt = CK_TRUE;
@@ -1034,156 +1030,170 @@ sftk_handlePrivateKeyObject(SFTKSession *session,SFTKObject *object,CK_KEY_TYPE
SECStatus rv;
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);
-
- if ((have_exp == 0) || (have_component < 3)) {
- /* nope, not enough to reconstruct the private key */
- return CKR_TEMPLATE_INCOMPLETE;
- }
- fillPrivateKey = PR_TRUE;
- }
- /*verify the parameters for consistency*/
- rv = sftk_verifyRSAPrivateKey(object, fillPrivateKey);
- 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;
+ 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);
+
+ if ((have_exp == 0) || (have_component < 3)) {
+ /* nope, not enough to reconstruct the private key */
+ return CKR_TEMPLATE_INCOMPLETE;
+ }
+ fillPrivateKey = PR_TRUE;
+ }
+ /*verify the parameters for consistency*/
+ rv = sftk_verifyRSAPrivateKey(object, fillPrivateKey);
+ 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;
#ifndef NSS_DISABLE_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;
+ 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_DISABLE_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;
- }
+ 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;
+ 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;
+ 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);
+ if (sftk_isTrue(object, CKA_TOKEN)) {
+ SFTKSlot *slot = session->slot;
+ SFTKDBHandle *keyHandle = sftk_getKeyDB(slot);
- if (keyHandle == NULL) {
- return CKR_TOKEN_WRITE_PROTECTED;
- }
+ if (keyHandle == NULL) {
+ return CKR_TOKEN_WRITE_PROTECTED;
+ }
- crv = sftkdb_write(keyHandle, object, &object->handle);
- sftk_freeDB(keyHandle);
- return crv;
+ 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;
+ object->objectInfo = sftk_mkPrivKey(object, key_type, &crv);
+ if (object->objectInfo == NULL)
+ return crv;
+ object->infoFree = (SFTKFree)nsslowkey_DestroyPrivateKey;
}
return CKR_OK;
}
@@ -1193,8 +1203,8 @@ 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)
+validateSecretKey(SFTKSession *session, SFTKObject *object,
+ CK_KEY_TYPE key_type, PRBool isFIPS)
{
CK_RV crv;
CK_BBOOL cktrue = CK_TRUE;
@@ -1202,127 +1212,139 @@ validateSecretKey(SFTKSession *session, SFTKObject *object,
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;
+ 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;
+ 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:
+ /* 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:
+ case CKK_RC5:
#endif
#ifdef NSS_SOFTOKEN_DOES_CAST
- case CKK_CAST:
- case CKK_CAST3:
- case CKK_CAST5:
+ case CKK_CAST:
+ case CKK_CAST3:
+ case CKK_CAST5:
#endif
#if NSS_SOFTOKEN_DOES_IDEA
- case CKK_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;
+ 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
+ * 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)
+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 (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 (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;
- }
+ if (keyHandle == NULL) {
+ return CKR_TOKEN_WRITE_PROTECTED;
+ }
- crv = sftkdb_write(keyHandle, object, &object->handle);
- sftk_freeDB(keyHandle);
- return crv;
+ crv = sftkdb_write(keyHandle, object, &object->handle);
+ sftk_freeDB(keyHandle);
+ return crv;
}
loser:
@@ -1331,7 +1353,7 @@ loser:
}
/*
- * check the consistancy and initialize a Key Object
+ * check the consistancy and initialize a Key Object
*/
static CK_RV
sftk_handleKeyObject(SFTKSession *session, SFTKObject *object)
@@ -1342,24 +1364,28 @@ sftk_handleKeyObject(SFTKSession *session, SFTKObject *object)
CK_RV crv;
/* verify the required fields */
- if ( !sftk_hasAttribute(object,CKA_KEY_TYPE) ) {
- return CKR_TEMPLATE_INCOMPLETE;
+ 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;
+ 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;
+ 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);
+ attribute = sftk_FindAttribute(object, CKA_KEY_TYPE);
if (!attribute) {
return CKR_ATTRIBUTE_VALUE_INVALID;
}
@@ -1367,22 +1393,22 @@ sftk_handleKeyObject(SFTKSession *session, SFTKObject *object)
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;
+ 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
+ * check the consistancy and Verify a DSA Parameter Object
*/
static CK_RV
sftk_handleDSAParameterObject(SFTKSession *session, SFTKObject *object)
@@ -1396,93 +1422,100 @@ sftk_handleDSAParameterObject(SFTKSession *session, SFTKObject *object)
CK_RV crv = CKR_TEMPLATE_INCOMPLETE;
PQGParams params;
PQGVerify vfy, *verify = NULL;
- SECStatus result,rv;
+ 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.
+ * 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
+ * - 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;
+ PRBool needVfy = PR_FALSE;
- primeAttr = sftk_FindAttribute(object,CKA_PRIME);
- if (primeAttr == NULL) goto loser;
+ 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;
+ 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);
+ baseAttr = sftk_FindAttribute(object, CKA_BASE);
if (baseAttr != NULL) {
- params.base.data = baseAttr->attrib.pValue;
- params.base.len = baseAttr->attrib.ulValueLen;
+ 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. */
+ 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 */
+ 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;
+ 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 */
+ 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;
+ 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;
+ vfy.seed.data = seedAttr->attrib.pValue;
+ vfy.seed.len = seedAttr->attrib.ulValueLen;
- verify = &vfy;
+ verify = &vfy;
} else if (needVfy) {
- goto loser; /* Verify always needs seed, if we need verify and not seed
- * then fail */
+ 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);
+ rv = PQG_VerifyParams(&params, verify, &result);
if (rv == SECSuccess) {
- crv = (result== SECSuccess) ? CKR_OK : CKR_ATTRIBUTE_VALUE_INVALID;
+ 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);
+ 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
+ * check the consistancy and initialize a Key Parameter Object
*/
static CK_RV
sftk_handleKeyParameterObject(SFTKSession *session, SFTKObject *object)
@@ -1493,16 +1526,17 @@ sftk_handleKeyParameterObject(SFTKSession *session, SFTKObject *object)
CK_RV crv;
/* verify the required fields */
- if ( !sftk_hasAttribute(object,CKA_KEY_TYPE) ) {
- return CKR_TEMPLATE_INCOMPLETE;
+ 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;
+ 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);
+ attribute = sftk_FindAttribute(object, CKA_KEY_TYPE);
if (!attribute) {
return CKR_ATTRIBUTE_VALUE_INVALID;
}
@@ -1510,16 +1544,16 @@ sftk_handleKeyParameterObject(SFTKSession *session, SFTKObject *object)
sftk_FreeAttribute(attribute);
switch (key_type) {
- case CKK_DSA:
- return sftk_handleDSAParameterObject(session,object);
-
- default:
- break;
+ 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
@@ -1538,104 +1572,107 @@ sftk_handleObject(SFTKObject *object, SFTKSession *session)
/* 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;
+ 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;
+ (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;
+ (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.
+ * 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
+ * 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
+ * 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);
+ 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);
+ attribute = sftk_FindAttribute(object, CKA_CLASS);
if (attribute == NULL) {
- return CKR_TEMPLATE_INCOMPLETE;
+ return CKR_TEMPLATE_INCOMPLETE;
}
object->objclass = *(CK_OBJECT_CLASS *)attribute->attrib.pValue;
sftk_FreeAttribute(attribute);
- /* Now handle the specific object class.
+ /* 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;
+ 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;
+ return crv;
}
/* Now link the object into the slot and session structures.
@@ -1644,10 +1681,10 @@ sftk_handleObject(SFTKObject *object, SFTKSession *session)
* causing the following test to be true.
*/
if (sftk_isToken(object->handle)) {
- sftk_convertSessionToToken(object);
+ sftk_convertSessionToToken(object);
} else {
- object->slot = slot;
- sftk_AddObject(session,object);
+ object->slot = slot;
+ sftk_AddObject(session, object);
}
return CKR_OK;
@@ -1657,152 +1694,158 @@ sftk_handleObject(SFTKObject *object, SFTKSession *session)
* ******************** 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 *
+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;
+ *crvp = CKR_KEY_TYPE_INCONSISTENT;
+ return NULL;
}
if (sftk_isToken(object->handle)) {
-/* ferret out the token 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;
+ *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;
+ *crvp = CKR_HOST_MEMORY;
+ return NULL;
}
pubKey = (NSSLOWKEYPublicKey *)
- PORT_ArenaAlloc(arena,sizeof(NSSLOWKEYPublicKey));
+ PORT_ArenaAlloc(arena, sizeof(NSSLOWKEYPublicKey));
if (pubKey == NULL) {
- PORT_FreeArena(arena,PR_FALSE);
- *crvp = CKR_HOST_MEMORY;
- return 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;
+ 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;
#ifndef NSS_DISABLE_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) {
- unsigned 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;
+ 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) {
+ unsigned int keyLen = pubKey->u.ec.ecParams.pointSize;
+
+ /* special note: We can't just use the first byte to distinguish
+ * between EC_POINT_FORM_UNCOMPRESSED and SEC_ASN1_OCTET_STRING.
+ * Both are 0x04. */
+
+ /* Handle the non-DER encoded case.
+ * Some curves are always pressumed to be non-DER.
+ */
+ if (pubKey->u.ec.publicValue.len == keyLen &&
+ (pubKey->u.ec.ecParams.fieldID.type == ec_field_plain ||
+ pubKey->u.ec.publicValue.data[0] == EC_POINT_FORM_UNCOMPRESSED)) {
+ break; /* key was not DER encoded, no need to unwrap */
+ }
+
+ PORT_Assert(pubKey->u.ec.ecParams.name != ECCurve25519);
+
+ /* 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_DISABLE_ECC */
- default:
- crv = CKR_KEY_TYPE_INCONSISTENT;
- break;
+ default:
+ crv = CKR_KEY_TYPE_INCONSISTENT;
+ break;
}
*crvp = crv;
if (crv != CKR_OK) {
- PORT_FreeArena(arena,PR_FALSE);
- return NULL;
+ PORT_FreeArena(arena, PR_FALSE);
+ return NULL;
}
object->objectInfo = pubKey;
- object->infoFree = (SFTKFree) nsslowkey_DestroyPublicKey;
+ object->infoFree = (SFTKFree)nsslowkey_DestroyPublicKey;
return pubKey;
}
@@ -1819,144 +1862,148 @@ sftk_mkPrivKey(SFTKObject *object, CK_KEY_TYPE key_type, CK_RV *crvp)
arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
if (arena == NULL) {
- *crvp = CKR_HOST_MEMORY;
- return 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;
+ 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;
+ 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;
#ifndef NSS_DISABLE_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;
- /* The following ifdef is needed for Linux arm distros and
- * Android as gcc 4.6 has a bug when targeting arm (but not
- * thumb). The bug has been fixed in gcc 4.7.
- * http://gcc.gnu.org/bugzilla/show_bug.cgi?id=56561
- */
-#if defined (__arm__) && !defined(__thumb__) && defined (__GNUC__)
- *crvp = CKR_HOST_MEMORY;
- break;
+ 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;
+/* The following ifdef is needed for Linux arm distros and
+ * Android as gcc 4.6 has a bug when targeting arm (but not
+ * thumb). The bug has been fixed in gcc 4.7.
+ * http://gcc.gnu.org/bugzilla/show_bug.cgi?id=56561
+ */
+#if defined(__arm__) && !defined(__thumb__) && defined(__GNUC__)
+ *crvp = CKR_HOST_MEMORY;
+ break;
#endif
- }
- break;
+ }
+ break;
#endif /* NSS_DISABLE_ECC */
- default:
- crv = CKR_KEY_TYPE_INCONSISTENT;
- break;
+ 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);
+ 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;
+ PORT_FreeArena(arena, PR_FALSE);
+ return NULL;
}
return privKey;
}
@@ -1985,156 +2032,164 @@ sftk_verifyRSAPrivateKey(SFTKObject *object, PRBool fillIfNeeded)
tmpKey.arena = NULL;
modulus = sftk_FindAttribute(object, CKA_MODULUS);
if (modulus) {
- tmpKey.modulus.data = modulus->attrib.pValue;
- tmpKey.modulus.len = modulus->attrib.ulValueLen;
- }
+ 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;
- }
+ 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;
- }
+ 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;
- }
+ 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;
+ tmpKey.publicExponent.data = publicExponent->attrib.pValue;
+ tmpKey.publicExponent.len = publicExponent->attrib.ulValueLen;
}
exponent1 = sftk_FindAttribute(object, CKA_EXPONENT_1);
if (exponent1) {
- tmpKey.exponent1.data = exponent1->attrib.pValue;
- tmpKey.exponent1.len = exponent1->attrib.ulValueLen;
+ tmpKey.exponent1.data = exponent1->attrib.pValue;
+ tmpKey.exponent1.len = exponent1->attrib.ulValueLen;
}
exponent2 = sftk_FindAttribute(object, CKA_EXPONENT_2);
if (exponent2) {
- tmpKey.exponent2.data = exponent2->attrib.pValue;
- tmpKey.exponent2.len = exponent2->attrib.ulValueLen;
+ tmpKey.exponent2.data = exponent2->attrib.pValue;
+ tmpKey.exponent2.len = exponent2->attrib.ulValueLen;
}
coefficient = sftk_FindAttribute(object, CKA_COEFFICIENT);
if (coefficient) {
- tmpKey.coefficient.data = coefficient->attrib.pValue;
- tmpKey.coefficient.len = coefficient->attrib.ulValueLen;
+ tmpKey.coefficient.data = coefficient->attrib.pValue;
+ tmpKey.coefficient.len = coefficient->attrib.ulValueLen;
}
if (fillIfNeeded) {
- /*
- * 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;
- }
+ /*
+ * 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;
+ }
}
rv = RSA_PrivateKeyCheck(&tmpKey);
if (rv != SECSuccess) {
- goto loser;
+ goto loser;
}
/* now that we have a fully populated key, set all our attribute values */
rv = SECFailure;
if (!modulus || modulus->attrib.pValue != tmpKey.modulus.data) {
- crv = sftk_forceAttribute(object,CKA_MODULUS,
+ crv = sftk_forceAttribute(object, CKA_MODULUS,
sftk_item_expand(&tmpKey.modulus));
- if (crv != CKR_OK) goto loser;
+ if (crv != CKR_OK)
+ goto loser;
}
if (!publicExponent ||
publicExponent->attrib.pValue != tmpKey.publicExponent.data) {
crv = sftk_forceAttribute(object, CKA_PUBLIC_EXPONENT,
sftk_item_expand(&tmpKey.publicExponent));
- if (crv != CKR_OK) goto loser;
+ if (crv != CKR_OK)
+ goto loser;
}
if (!privateExponent ||
privateExponent->attrib.pValue != tmpKey.privateExponent.data) {
crv = sftk_forceAttribute(object, CKA_PRIVATE_EXPONENT,
sftk_item_expand(&tmpKey.privateExponent));
- if (crv != CKR_OK) goto loser;
+ if (crv != CKR_OK)
+ goto loser;
}
if (!prime1 || prime1->attrib.pValue != tmpKey.prime1.data) {
crv = sftk_forceAttribute(object, CKA_PRIME_1,
sftk_item_expand(&tmpKey.prime1));
- if (crv != CKR_OK) goto loser;
+ if (crv != CKR_OK)
+ goto loser;
}
if (!prime2 || prime2->attrib.pValue != tmpKey.prime2.data) {
crv = sftk_forceAttribute(object, CKA_PRIME_2,
sftk_item_expand(&tmpKey.prime2));
- if (crv != CKR_OK) goto loser;
+ if (crv != CKR_OK)
+ goto loser;
}
if (!exponent1 || exponent1->attrib.pValue != tmpKey.exponent1.data) {
crv = sftk_forceAttribute(object, CKA_EXPONENT_1,
- sftk_item_expand(&tmpKey.exponent1));
- if (crv != CKR_OK) goto loser;
+ sftk_item_expand(&tmpKey.exponent1));
+ if (crv != CKR_OK)
+ goto loser;
}
if (!exponent2 || exponent2->attrib.pValue != tmpKey.exponent2.data) {
crv = sftk_forceAttribute(object, CKA_EXPONENT_2,
sftk_item_expand(&tmpKey.exponent2));
- if (crv != CKR_OK) goto loser;
+ if (crv != CKR_OK)
+ goto loser;
}
if (!coefficient || coefficient->attrib.pValue != tmpKey.coefficient.data) {
crv = sftk_forceAttribute(object, CKA_COEFFICIENT,
sftk_item_expand(&tmpKey.coefficient));
- if (crv != CKR_OK) goto loser;
+ if (crv != CKR_OK)
+ goto loser;
}
rv = SECSuccess;
- /* we're done (one way or the other), clean up all our stuff */
+/* we're done (one way or the other), clean up all our stuff */
loser:
if (tmpKey.arena) {
- PORT_FreeArena(tmpKey.arena,PR_TRUE);
+ PORT_FreeArena(tmpKey.arena, PR_TRUE);
}
if (modulus) {
- sftk_FreeAttribute(modulus);
+ sftk_FreeAttribute(modulus);
}
if (prime1) {
- sftk_FreeAttribute(prime1);
+ sftk_FreeAttribute(prime1);
}
if (prime2) {
- sftk_FreeAttribute(prime2);
+ sftk_FreeAttribute(prime2);
}
if (privateExponent) {
- sftk_FreeAttribute(privateExponent);
+ sftk_FreeAttribute(privateExponent);
}
if (publicExponent) {
- sftk_FreeAttribute(publicExponent);
+ sftk_FreeAttribute(publicExponent);
}
if (exponent1) {
- sftk_FreeAttribute(exponent1);
+ sftk_FreeAttribute(exponent1);
}
if (exponent2) {
- sftk_FreeAttribute(exponent2);
+ sftk_FreeAttribute(exponent2);
}
if (coefficient) {
- sftk_FreeAttribute(coefficient);
+ sftk_FreeAttribute(coefficient);
}
return rv;
}
/* Generate a low private key structure from an object */
NSSLOWKEYPrivateKey *
-sftk_GetPrivKey(SFTKObject *object,CK_KEY_TYPE key_type, CK_RV *crvp)
+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;
+ *crvp = CKR_KEY_TYPE_INCONSISTENT;
+ return NULL;
}
if (object->objectInfo) {
- *crvp = CKR_OK;
- return (NSSLOWKEYPrivateKey *)object->objectInfo;
+ *crvp = CKR_OK;
+ return (NSSLOWKEYPrivateKey *)object->objectInfo;
}
priv = sftk_mkPrivKey(object, key_type, crvp);
object->objectInfo = priv;
- object->infoFree = (SFTKFree) nsslowkey_DestroyPrivateKey;
+ object->infoFree = (SFTKFree)nsslowkey_DestroyPrivateKey;
return priv;
}
@@ -2150,8 +2205,8 @@ 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];
+ for (i = 0; i < length; i++) {
+ key[i] = parityTable[key[i] >> 1];
}
}
@@ -2166,10 +2221,10 @@ sftk_CheckDESKey(unsigned char *key)
/* 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;
- }
+ for (i = 0; i < sftk_desWeakTableSize; i++) {
+ if (PORT_Memcmp(key, sftk_desWeakTable[i], 8) == 0) {
+ return PR_TRUE;
+ }
}
return PR_FALSE;
}
@@ -2178,47 +2233,46 @@ sftk_CheckDESKey(unsigned char *key)
* check if a des or triple des key is weak.
*/
PRBool
-sftk_IsWeakKey(unsigned char *key,CK_KEY_TYPE key_type)
+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;
+ 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
+ * Start of PKCS 11 functions
*
**********************************************************************/
-
/* return the function list */
-CK_RV NSC_GetFunctionList(CK_FUNCTION_LIST_PTR *pFunctionList)
+CK_RV
+NSC_GetFunctionList(CK_FUNCTION_LIST_PTR *pFunctionList)
{
- CHECK_FORK();
-
- *pFunctionList = (CK_FUNCTION_LIST_PTR) &sftk_funcList;
+ *pFunctionList = (CK_FUNCTION_LIST_PTR)&sftk_funcList;
return CKR_OK;
}
/* return the function list */
-CK_RV C_GetFunctionList(CK_FUNCTION_LIST_PTR *pFunctionList)
+CK_RV
+C_GetFunctionList(CK_FUNCTION_LIST_PTR *pFunctionList)
{
- CHECK_FORK();
-
return NSC_GetFunctionList(pFunctionList);
}
@@ -2239,16 +2293,16 @@ 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);
+ 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;
}
@@ -2258,34 +2312,31 @@ 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;
+ 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);
+ "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 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
+static unsigned 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_FIPS_MODULE;
}
return NSC_NON_FIPS_MODULE;
}
@@ -2299,12 +2350,14 @@ 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);
+
+ 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;
+ if (slot && !all && !slot->present)
+ slot = NULL;
return slot;
}
@@ -2315,57 +2368,57 @@ sftk_SlotFromSessionHandle(CK_SESSION_HANDLE handle)
CK_ULONG moduleIndex = (handle >> 31) & 1;
if (slotIDIndex >= nscSlotCount[moduleIndex]) {
- return NULL;
+ return NULL;
}
return sftk_SlotFromID(nscSlotList[moduleIndex][slotIDIndex], PR_FALSE);
}
-
+
static CK_RV
sftk_RegisterSlot(SFTKSlot *slot, int moduleIndex)
{
PLHashEntry *entry;
- int index;
+ unsigned int index;
index = sftk_GetModuleIndex(slot->slotID);
/* make sure the slotID for this module is valid */
if (moduleIndex != index) {
- return CKR_SLOT_ID_INVALID;
+ 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;
- }
+ 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) {
+ 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;
- }
+ 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);
+ entry = PL_HashTableAdd(nscSlotHashTable[index], (void *)slot->slotID, slot);
if (entry == NULL) {
- return CKR_HOST_MEMORY;
+ return CKR_HOST_MEMORY;
}
slot->index = (nscSlotCount[index] & 0x7f) | ((index << 7) & 0x80);
nscSlotList[index][nscSlotCount[index]++] = slot->slotID;
@@ -2373,21 +2426,20 @@ sftk_RegisterSlot(SFTKSlot *slot, int moduleIndex)
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
+ * 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)
+ * 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.
@@ -2398,8 +2450,8 @@ sftk_RegisterSlot(SFTKSlot *slot, int moduleIndex)
*
*/
CK_RV
-SFTK_SlotReInit(SFTKSlot *slot, char *configdir, char *updatedir,
- char *updateID, sftk_token_parameters *params, int moduleIndex)
+SFTK_SlotReInit(SFTKSlot *slot, char *configdir, char *updatedir,
+ char *updateID, sftk_token_parameters *params, int moduleIndex)
{
PRBool needLogin = !params->noKeyDB;
CK_RV crv;
@@ -2416,46 +2468,50 @@ SFTK_SlotReInit(SFTKSlot *slot, char *configdir, char *updatedir,
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);
+ 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;
+ 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;
- }
+ /* 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;
+ }
+ /* Make sure the pin len is set to the Minimum allowed value for fips
+ * when in FIPS mode. NOTE: we don't set it if the database has not
+ * been initialized yet so that we can init into level1 mode if needed
+ */
+ if ((sftkdb_HasPasswordSet(slot->keyDB) == SECSuccess) &&
+ (moduleIndex == NSC_FIPS_MODULE) &&
+ (slot->minimumPinLen < FIPS_MIN_PIN)) {
+ slot->minimumPinLen = FIPS_MIN_PIN;
+ }
}
slot->present = PR_TRUE;
@@ -2471,7 +2527,7 @@ loser:
*/
CK_RV
SFTK_SlotInit(char *configdir, char *updatedir, char *updateID,
- sftk_token_parameters *params, int moduleIndex)
+ sftk_token_parameters *params, int moduleIndex)
{
unsigned int i;
CK_SLOT_ID slotID = params->slotID;
@@ -2486,78 +2542,77 @@ SFTK_SlotInit(char *configdir, char *updatedir, char *updateID,
slot = PORT_ZNew(SFTKSlot);
if (slot == NULL) {
- return CKR_HOST_MEMORY;
+ 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;
+ 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->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->sessionLockMask = slot->numSessionLocks - 1;
slot->slotLock = PZ_NewLock(nssILockSession);
if (slot->slotLock == NULL)
- goto mem_loser;
+ goto mem_loser;
slot->sessionLock = PORT_ZNewArray(PZLock *, slot->numSessionLocks);
if (slot->sessionLock == NULL)
- goto mem_loser;
- for (i=0; i < slot->numSessionLocks; i++) {
+ goto mem_loser;
+ for (i = 0; i < slot->numSessionLocks; i++) {
slot->sessionLock[i] = PZ_NewLock(nssILockSession);
- if (slot->sessionLock[i] == NULL)
- goto mem_loser;
+ if (slot->sessionLock[i] == NULL)
+ goto mem_loser;
}
slot->objectLock = PZ_NewLock(nssILockObject);
- if (slot->objectLock == NULL)
- goto mem_loser;
+ if (slot->objectLock == NULL)
+ goto mem_loser;
slot->pwCheckLock = PR_NewLock();
- if (slot->pwCheckLock == NULL)
- goto mem_loser;
+ if (slot->pwCheckLock == NULL)
+ goto mem_loser;
slot->head = PORT_ZNewArray(SFTKSession *, slot->sessHashSize);
- if (slot->head == NULL)
- goto mem_loser;
+ 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;
+ 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);
+ 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);
+ params, moduleIndex);
if (crv != CKR_OK) {
- goto loser;
+ goto loser;
}
crv = sftk_RegisterSlot(slot, moduleIndex);
if (crv != CKR_OK) {
- goto loser;
+ goto loser;
}
return CKR_OK;
mem_loser:
crv = CKR_HOST_MEMORY;
loser:
- SFTK_DestroySlotData(slot);
+ SFTK_DestroySlotData(slot);
return crv;
}
-
-CK_RV sftk_CloseAllSessions(SFTKSlot *slot, PRBool logout)
+CK_RV
+sftk_CloseAllSessions(SFTKSlot *slot, PRBool logout)
{
SFTKSession *session;
unsigned int i;
@@ -2566,21 +2621,21 @@ CK_RV sftk_CloseAllSessions(SFTKSlot *slot, PRBool logout)
/* 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.
+ * 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) {
+ 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 */
@@ -2588,31 +2643,33 @@ CK_RV sftk_CloseAllSessions(SFTKSlot *slot, PRBool logout)
* 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) {
- (void)PR_ATOMIC_DECREMENT(&slot->rwSessionCount);
- }
- } else {
- SKIP_AFTER_FORK(PZ_Unlock(lock));
- }
- if (session) sftk_FreeSession(session);
- } while (session != NULL);
+ 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) {
+ (void)PR_ATOMIC_DECREMENT(&slot->rwSessionCount);
+ }
+ } else {
+ SKIP_AFTER_FORK(PZ_Unlock(lock));
+ }
+ if (session)
+ sftk_FreeSession(session);
+ } while (session != NULL);
}
return CKR_OK;
}
@@ -2631,7 +2688,7 @@ static void
sftk_DBShutdown(SFTKSlot *slot)
{
SFTKDBHandle *certHandle;
- SFTKDBHandle *keyHandle;
+ SFTKDBHandle *keyHandle;
SKIP_AFTER_FORK(PZ_Lock(slot->slotLock));
certHandle = slot->certDB;
slot->certDB = NULL;
@@ -2639,10 +2696,10 @@ sftk_DBShutdown(SFTKSlot *slot)
slot->keyDB = NULL;
SKIP_AFTER_FORK(PZ_Unlock(slot->slotLock));
if (certHandle) {
- sftk_freeDB(certHandle);
+ sftk_freeDB(certHandle);
}
if (keyHandle) {
- sftk_freeDB(keyHandle);
+ sftk_freeDB(keyHandle);
}
}
@@ -2656,15 +2713,15 @@ SFTK_ShutdownSlot(SFTKSlot *slot)
* the sessHashSize variable guarentees we have all the session
* mechanism set up */
if (slot->head) {
- sftk_CloseAllSessions(slot, PR_TRUE);
- }
+ 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
+ * cache. slot->tokObjHashTable guarentees we have the token
* infrastructure set up. */
if (slot->tokObjHashTable) {
- SFTK_ClearTokenKeyHashTable(slot);
+ SFTK_ClearTokenKeyHashTable(slot);
}
/* clear the slot description for the next guy */
@@ -2686,19 +2743,19 @@ SFTK_DestroySlotData(SFTKSlot *slot)
SFTK_ShutdownSlot(slot);
if (slot->tokObjHashTable) {
- PL_HashTableDestroy(slot->tokObjHashTable);
- slot->tokObjHashTable = NULL;
+ PL_HashTableDestroy(slot->tokObjHashTable);
+ slot->tokObjHashTable = NULL;
}
if (slot->sessObjHashTable) {
- PORT_Free(slot->sessObjHashTable);
- slot->sessObjHashTable = NULL;
+ PORT_Free(slot->sessObjHashTable);
+ slot->sessObjHashTable = NULL;
}
slot->sessObjHashSize = 0;
if (slot->head) {
- PORT_Free(slot->head);
- slot->head = NULL;
+ PORT_Free(slot->head);
+ slot->head = NULL;
}
slot->sessHashSize = 0;
@@ -2707,22 +2764,22 @@ SFTK_DestroySlotData(SFTKSlot *slot)
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;
+ 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;
+ SKIP_AFTER_FORK(PZ_DestroyLock(slot->objectLock));
+ slot->objectLock = NULL;
}
if (slot->pwCheckLock) {
- SKIP_AFTER_FORK(PR_DestroyLock(slot->pwCheckLock));
- slot->pwCheckLock = NULL;
+ SKIP_AFTER_FORK(PR_DestroyLock(slot->pwCheckLock));
+ slot->pwCheckLock = NULL;
}
PORT_Free(slot);
return CKR_OK;
@@ -2732,105 +2789,121 @@ SFTK_DestroySlotData(SFTKSlot *slot)
* handle the SECMOD.db
*/
char **
-NSC_ModuleDBFunc(unsigned long function,char *parameters, void *args)
+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";
+ static char *success = "Success";
char **rvstr = NULL;
rvstr = NSSUTIL_DoModuleDBFunction(function, parameters, args);
if (rvstr != NULL) {
- return rvstr;
+ return rvstr;
}
if (PORT_GetError() != SEC_ERROR_LEGACY_DATABASE) {
- return NULL;
+ return NULL;
}
- /* The legacy database uses the old dbm, which is only linked with the
- * legacy DB handler, which is only callable from softoken */
+ /* 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);
+ &filename, &rw);
switch (function) {
- case SECMOD_MODULE_DB_FUNCTION_FIND:
- if (secmod == NULL) {
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- goto loser;
- }
- 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);
- goto loser;
- }
- 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);
- goto loser;
- }
- 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;
+ case SECMOD_MODULE_DB_FUNCTION_FIND:
+ if (secmod == NULL) {
+ PORT_SetError(SEC_ERROR_INVALID_ARGS);
+ goto loser;
+ }
+ 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);
+ goto loser;
+ }
+ 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);
+ goto loser;
+ }
+ 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;
}
loser:
- if (secmod) PR_smprintf_free(secmod);
- if (appName) PORT_Free(appName);
- if (filename) PORT_Free(filename);
+ if (secmod)
+ PR_smprintf_free(secmod);
+ if (appName)
+ PORT_Free(appName);
+ if (filename)
+ PORT_Free(filename);
return rvstr;
}
-static void nscFreeAllSlots(int moduleIndex)
+static void
+nscFreeAllSlots(int moduleIndex)
{
/* free all the slots */
SFTKSlot *slot = NULL;
@@ -2838,82 +2911,84 @@ static void nscFreeAllSlots(int moduleIndex)
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);
+ 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;
+ CK_SLOT_ID slotID = isFIPS ? PRIVATE_KEY_SLOT_ID : FIPS_SLOT_ID;
SFTKSlot *slot;
- int moduleIndex = isFIPS? NSC_NON_FIPS_MODULE : NSC_FIPS_MODULE;
+ int moduleIndex = isFIPS ? NSC_NON_FIPS_MODULE : NSC_FIPS_MODULE;
PLHashTable *tmpSlotHashTable = nscSlotHashTable[moduleIndex];
- slot = (SFTKSlot *) PL_HashTableLookup(tmpSlotHashTable, (void *)slotID);
+ slot = (SFTKSlot *)PL_HashTableLookup(tmpSlotHashTable, (void *)slotID);
if (slot == NULL) {
- return;
+ return;
}
sftk_DBShutdown(slot);
return;
}
/* NSC_Initialize initializes the Cryptoki library. */
-CK_RV nsc_CommonInitialize(CK_VOID_PTR pReserved, PRBool isFIPS)
+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;
+ CK_C_INITIALIZE_ARGS *init_args = (CK_C_INITIALIZE_ARGS *)pReserved;
int i;
- int moduleIndex = isFIPS? NSC_FIPS_MODULE : NSC_NON_FIPS_MODULE;
+ int moduleIndex = isFIPS ? NSC_FIPS_MODULE : NSC_NON_FIPS_MODULE;
if (isFIPS) {
- loginWaitTime = PR_SecondsToInterval(1);
+ loginWaitTime = PR_SecondsToInterval(1);
}
ENABLE_FORK_CHECK();
rv = SECOID_Init();
if (rv != SECSuccess) {
- crv = CKR_DEVICE_ERROR;
- return crv;
+ crv = CKR_DEVICE_ERROR;
+ return crv;
}
- rv = RNG_RNGInit(); /* initialize random number generator */
+ rv = RNG_RNGInit(); /* initialize random number generator */
if (rv != SECSuccess) {
- crv = CKR_DEVICE_ERROR;
- return crv;
+ crv = CKR_DEVICE_ERROR;
+ return crv;
}
- rv = BL_Init(); /* initialize freebl engine */
+ rv = BL_Init(); /* initialize freebl engine */
if (rv != SECSuccess) {
- crv = CKR_DEVICE_ERROR;
- return crv;
+ crv = CKR_DEVICE_ERROR;
+ return crv;
}
/* NOTE:
@@ -2922,7 +2997,7 @@ CK_RV nsc_CommonInitialize(CK_VOID_PTR pReserved, PRBool isFIPS)
* off from the rest on NSS.
*/
- /* initialize the key and cert db's */
+ /* 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) {
@@ -2943,44 +3018,43 @@ CK_RV nsc_CommonInitialize(CK_VOID_PTR pReserved, PRBool isFIPS)
}
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);
+ 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) {
+ 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);
+ }
+ loser:
+ sftk_freeParams(&paramStrings);
}
if (CKR_OK == crv) {
sftk_InitFreeLists();
@@ -3000,7 +3074,7 @@ loser:
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)) {
+ if (major > 5 || (5 == major && minor >= 10)) {
/* we are safe to use pthread_atfork */
usePthread_atfork = PR_TRUE;
}
@@ -3024,24 +3098,25 @@ loser:
return crv;
}
-CK_RV NSC_Initialize(CK_VOID_PTR pReserved)
+CK_RV
+NSC_Initialize(CK_VOID_PTR pReserved)
{
CK_RV crv;
-
+
sftk_ForkReset(pReserved, &crv);
if (nsc_init) {
- return CKR_CRYPTOKI_ALREADY_INITIALIZED;
+ return CKR_CRYPTOKI_ALREADY_INITIALIZED;
}
- crv = nsc_CommonInitialize(pReserved,PR_FALSE);
- nsc_init = (PRBool) (crv == CKR_OK);
+ crv = nsc_CommonInitialize(pReserved, PR_FALSE);
+ nsc_init = (PRBool)(crv == CKR_OK);
return crv;
}
-
-/* NSC_Finalize indicates that an application is done with the
+/* NSC_Finalize indicates that an application is done with the
* Cryptoki library.*/
-CK_RV nsc_CommonFinalize (CK_VOID_PTR pReserved, PRBool isFIPS)
+CK_RV
+nsc_CommonFinalize(CK_VOID_PTR pReserved, PRBool isFIPS)
{
/* propagate the fork status to freebl and util */
BL_SetForkState(parentForkedAfterC_Initialize);
@@ -3051,10 +3126,10 @@ CK_RV nsc_CommonFinalize (CK_VOID_PTR pReserved, PRBool isFIPS)
/* don't muck with the globals if our peer is still initialized */
if (isFIPS && nsc_init) {
- return CKR_OK;
+ return CKR_OK;
}
if (!isFIPS && nsf_init) {
- return CKR_OK;
+ return CKR_OK;
}
sftk_CleanupFreeLists();
@@ -3065,11 +3140,11 @@ CK_RV nsc_CommonFinalize (CK_VOID_PTR pReserved, PRBool isFIPS)
/* 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();
@@ -3091,7 +3166,7 @@ CK_RV nsc_CommonFinalize (CK_VOID_PTR pReserved, PRBool isFIPS)
}
#elif defined(CHECK_FORK_GETPID)
myPid = 0; /* allow reinitialization */
-#elif defined (CHECK_FORK_PTHREAD)
+#elif defined(CHECK_FORK_PTHREAD)
forked = PR_FALSE; /* allow reinitialization */
#endif
return CKR_OK;
@@ -3099,7 +3174,8 @@ CK_RV nsc_CommonFinalize (CK_VOID_PTR pReserved, PRBool isFIPS)
/* 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)
+PRBool
+sftk_ForkReset(CK_VOID_PTR pReserved, CK_RV *crv)
{
#ifndef NO_FORK_CHECK
if (PARENT_FORKED()) {
@@ -3123,9 +3199,10 @@ PRBool sftk_ForkReset(CK_VOID_PTR pReserved, CK_RV* crv)
return PR_FALSE;
}
-/* NSC_Finalize indicates that an application is done with the
+/* NSC_Finalize indicates that an application is done with the
* Cryptoki library.*/
-CK_RV NSC_Finalize (CK_VOID_PTR pReserved)
+CK_RV
+NSC_Finalize(CK_VOID_PTR pReserved)
{
CK_RV crv;
@@ -3138,7 +3215,7 @@ CK_RV NSC_Finalize (CK_VOID_PTR pReserved)
return CKR_OK;
}
- crv = nsc_CommonFinalize (pReserved, PR_FALSE);
+ crv = nsc_CommonFinalize(pReserved, PR_FALSE);
nsc_init = (PRBool) !(crv == CKR_OK);
@@ -3148,74 +3225,78 @@ CK_RV NSC_Finalize (CK_VOID_PTR pReserved)
extern const char __nss_softokn_version[];
/* NSC_GetInfo returns general information about Cryptoki. */
-CK_RV NSC_GetInfo(CK_INFO_PTR pInfo)
+CK_RV
+NSC_GetInfo(CK_INFO_PTR pInfo)
{
#define NSS_VERSION_VARIABLE __nss_softokn_version
#include "verref.h"
CHECK_FORK();
-
+
pInfo->cryptokiVersion.major = 2;
pInfo->cryptokiVersion.minor = 20;
- PORT_Memcpy(pInfo->manufacturerID,manufacturerID,32);
+ PORT_Memcpy(pInfo->manufacturerID, manufacturerID, 32);
pInfo->libraryVersion.major = SOFTOKEN_VMAJOR;
pInfo->libraryVersion.minor = SOFTOKEN_VMINOR;
- PORT_Memcpy(pInfo->libraryDescription,libraryDescription,32);
+ 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)
+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));
+ 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)
+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);
+ 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)
+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;
+ if (slot == NULL)
+ return CKR_SLOT_ID_INVALID;
- PORT_Memcpy(pInfo->manufacturerID,manufacturerID,
- sizeof(pInfo->manufacturerID));
- PORT_Memcpy(pInfo->slotDescription,slot->slotDescription,
- sizeof(pInfo->slotDescription));
+ 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;
+ 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;
- }
+ /* 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. */
@@ -3235,7 +3316,7 @@ static PRBool
sftk_checkNeedLogin(SFTKSlot *slot, SFTKDBHandle *keyHandle)
{
if (sftkdb_PWCached(keyHandle) == SECSuccess) {
- return slot->needLogin;
+ return slot->needLogin;
}
slot->needLogin = (PRBool)!sftk_hasNullPassword(slot, keyHandle);
return (slot->needLogin);
@@ -3245,100 +3326,103 @@ static PRBool
sftk_isBlank(const char *s, int len)
{
int i;
- for (i=0; i < len; i++) {
- if (s[i] != ' ') {
- return PR_FALSE;
- }
+ for (i = 0; i < len; i++) {
+ if (s[i] != ' ') {
+ return PR_FALSE;
+ }
}
return PR_TRUE;
}
-/* NSC_GetTokenInfo obtains information about a particular token in
+/* NSC_GetTokenInfo obtains information about a particular token in
* the system. */
-CK_RV NSC_GetTokenInfo(CK_SLOT_ID slotID,CK_TOKEN_INFO_PTR pInfo)
+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;
+
+ if (!nsc_init && !nsf_init)
+ return CKR_CRYPTOKI_NOT_INITIALIZED;
slot = sftk_SlotFromID(slotID, PR_FALSE);
- if (slot == NULL) return CKR_SLOT_ID_INVALID;
+ 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);
+ 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));
+ 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;
+ 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;
+ /*
+ * 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;
+ pInfo->hardwareVersion.major = CERT_DB_FILE_VERSION;
+ pInfo->hardwareVersion.minor = handle->version;
#else
- pInfo->hardwareVersion.major = 0;
- pInfo->hardwareVersion.minor = 0;
+ pInfo->hardwareVersion.major = 0;
+ pInfo->hardwareVersion.minor = 0;
#endif
sftk_freeDB(handle);
}
@@ -3351,107 +3435,129 @@ CK_RV NSC_GetTokenInfo(CK_SLOT_ID slotID,CK_TOKEN_INFO_PTR pInfo)
* 1 1 1
*/
if (!(pInfo->flags & CKF_LOGIN_REQUIRED) ||
- (pInfo->flags & CKF_USER_PIN_INITIALIZED)) {
- pInfo->flags |= CKF_TOKEN_INITIALIZED;
+ (pInfo->flags & CKF_USER_PIN_INITIALIZED)) {
+ pInfo->flags |= CKF_TOKEN_INITIALIZED;
}
return CKR_OK;
}
-/* NSC_GetMechanismList obtains a list of mechanism types
+/* 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_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;
+ /* 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
+/* 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)
+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++) {
+ 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;
- }
+ 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_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++) {
+ 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 (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) {
+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;
@@ -3461,33 +3567,36 @@ CK_RV NSC_InitToken(CK_SLOT_ID slotID,CK_CHAR_PTR pPin,
CHECK_FORK();
- if (slot == NULL) return CKR_SLOT_ID_INVALID;
+ 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;
+ return CKR_TOKEN_WRITE_PROTECTED;
}
- /* first, delete all our loaded key and cert objects from our
+ /* 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);
+ 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);
@@ -3495,59 +3604,59 @@ CK_RV NSC_InitToken(CK_SLOT_ID slotID,CK_CHAR_PTR pPin,
/* then clear out the key database */
handle = sftk_getKeyDB(slot);
if (handle == NULL) {
- return CKR_TOKEN_WRITE_PROTECTED;
+ return CKR_TOKEN_WRITE_PROTECTED;
}
rv = sftkdb_ResetKeyDB(handle);
sftk_freeDB(handle);
if (rv != SECSuccess) {
- return CKR_DEVICE_ERROR;
+ return CKR_DEVICE_ERROR;
}
/* finally mark all the user certs as non-user certs */
certHandle = sftk_getCertDB(slot);
- if (certHandle == NULL) return CKR_OK;
+ 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)
+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];
+ 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;
+ goto loser;
}
slot = sftk_SlotFromSession(sp);
if (slot == NULL) {
- goto loser;
+ goto loser;
}
handle = sftk_getKeyDB(slot);
if (handle == NULL) {
- crv = CKR_PIN_LEN_RANGE;
- goto loser;
+ crv = CKR_PIN_LEN_RANGE;
+ goto loser;
}
-
if (sp->info.state != CKS_RW_SO_FUNCTIONS) {
- crv = CKR_USER_NOT_LOGGED_IN;
- goto loser;
+ crv = CKR_USER_NOT_LOGGED_IN;
+ goto loser;
}
sftk_FreeSession(sp);
@@ -3555,85 +3664,94 @@ CK_RV NSC_InitPIN(CK_SESSION_HANDLE hSession,
/* make sure the pins aren't too long */
if (ulPinLen > SFTK_MAX_PIN) {
- crv = CKR_PIN_LEN_RANGE;
- goto loser;
+ crv = CKR_PIN_LEN_RANGE;
+ goto loser;
}
if (ulPinLen < (CK_ULONG)slot->minimumPinLen) {
- crv = CKR_PIN_LEN_RANGE;
- goto loser;
+ crv = CKR_PIN_LEN_RANGE;
+ goto loser;
}
if (sftkdb_HasPasswordSet(handle) != SECFailure) {
- crv = CKR_DEVICE_ERROR;
- goto loser;
+ crv = CKR_DEVICE_ERROR;
+ goto loser;
}
/* convert to null terminated string */
PORT_Memcpy(newPinStr, pPin, ulPinLen);
- newPinStr[ulPinLen] = 0;
+ 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_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;
+ if (ulPinLen == 0)
+ slot->needLogin = PR_FALSE;
+ /* database has been initialized, now force min password in FIPS
+ * mode. NOTE: if we are in level1, we may not have a password, but
+ * forcing it now will prevent an insufficient password from being set.
+ */
+ if ((sftk_GetModuleIndex(slot->slotID) == NSC_FIPS_MODULE) &&
+ (slot->minimumPinLen < FIPS_MIN_PIN)) {
+ slot->minimumPinLen = FIPS_MIN_PIN;
+ }
+ return CKR_OK;
}
crv = CKR_PIN_INCORRECT;
loser:
if (sp) {
- sftk_FreeSession(sp);
+ sftk_FreeSession(sp);
}
if (handle) {
- sftk_freeDB(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)
+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];
+ 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;
+ goto loser;
}
slot = sftk_SlotFromSession(sp);
if (!slot) {
- goto loser;
+ goto loser;
}
handle = sftk_getKeyDB(slot);
if (handle == NULL) {
- sftk_FreeSession(sp);
- return CKR_PIN_LEN_RANGE; /* XXX FIXME wrong return value */
+ 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;
+ crv = CKR_USER_NOT_LOGGED_IN;
+ goto loser;
}
sftk_FreeSession(sp);
@@ -3641,35 +3759,34 @@ CK_RV NSC_SetPIN(CK_SESSION_HANDLE hSession, CK_CHAR_PTR pOldPin,
/* make sure the pins aren't too long */
if ((ulNewLen > SFTK_MAX_PIN) || (ulOldLen > SFTK_MAX_PIN)) {
- crv = CKR_PIN_LEN_RANGE;
- goto loser;
+ crv = CKR_PIN_LEN_RANGE;
+ goto loser;
}
if (ulNewLen < (CK_ULONG)slot->minimumPinLen) {
- crv = CKR_PIN_LEN_RANGE;
- goto loser;
+ 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;
+ 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);
+ sftk_CloseAllSessions(slot, PR_FALSE);
}
if ((rv != SECSuccess) && (slot->slotID == FIPS_SLOT_ID)) {
- PR_Sleep(loginWaitTime);
+ PR_Sleep(loginWaitTime);
}
PR_Unlock(slot->pwCheckLock);
/* Now update our local copy of the pin */
if (rv == SECSuccess) {
- slot->needLogin = (PRBool)(ulNewLen != 0);
+ slot->needLogin = (PRBool)(ulNewLen != 0);
/* Reset login flags. */
if (ulNewLen == 0) {
PRBool tokenRemoved = PR_FALSE;
@@ -3685,22 +3802,23 @@ CK_RV NSC_SetPIN(CK_SESSION_HANDLE hSession, CK_CHAR_PTR pOldPin,
}
sftk_update_all_states(slot);
sftk_freeDB(handle);
- return CKR_OK;
+ return CKR_OK;
}
crv = CKR_PIN_INCORRECT;
loser:
if (sp) {
- sftk_FreeSession(sp);
+ sftk_FreeSession(sp);
}
if (handle) {
- sftk_freeDB(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)
+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;
@@ -3708,41 +3826,42 @@ CK_RV NSC_OpenSession(CK_SLOT_ID slotID, CK_FLAGS flags,
SFTKSession *sameID;
CHECK_FORK();
-
+
slot = sftk_SlotFromID(slotID, PR_FALSE);
- if (slot == NULL) return CKR_SLOT_ID_INVALID;
+ 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;
+ 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;
+ /* 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) {
- (void)PR_ATOMIC_INCREMENT(&slot->rwSessionCount);
+ (void)PR_ATOMIC_INCREMENT(&slot->rwSessionCount);
}
do {
PZLock *lock;
do {
- sessionID = (PR_ATOMIC_INCREMENT(&slot->sessionIDCount) & 0xffffff)
- | (slot->index << 24);
+ sessionID = (PR_ATOMIC_INCREMENT(&slot->sessionIDCount) & 0xffffff) | (slot->index << 24);
} while (sessionID == CK_INVALID_HANDLE);
- lock = SFTK_SESSION_LOCK(slot,sessionID);
+ 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);
+ sftkqueue_add(session, sessionID, slot->head, slot->sessHashSize);
} else {
- slot->sessionIDConflict++; /* for debugging */
+ slot->sessionIDConflict++; /* for debugging */
}
PZ_Unlock(lock);
} while (sameID != NULL);
@@ -3751,9 +3870,9 @@ CK_RV NSC_OpenSession(CK_SLOT_ID slotID, CK_FLAGS flags,
return CKR_OK;
}
-
/* NSC_CloseSession closes a session between an application and a token. */
-CK_RV NSC_CloseSession(CK_SESSION_HANDLE hSession)
+CK_RV
+NSC_CloseSession(CK_SESSION_HANDLE hSession)
{
SFTKSlot *slot;
SFTKSession *session;
@@ -3763,47 +3882,48 @@ CK_RV NSC_CloseSession(CK_SESSION_HANDLE hSession)
CHECK_FORK();
session = sftk_SessionFromHandle(hSession);
- if (session == NULL) return CKR_SESSION_HANDLE_INVALID;
+ if (session == NULL)
+ return CKR_SESSION_HANDLE_INVALID;
slot = sftk_SlotFromSession(session);
sessionFound = PR_FALSE;
/* lock */
- lock = SFTK_SESSION_LOCK(slot,hSession);
+ 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);
+ 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) {
- (void)PR_ATOMIC_DECREMENT(&slot->rwSessionCount);
- }
+ 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) {
+ (void)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)
+CK_RV
+NSC_CloseAllSessions(CK_SLOT_ID slotID)
{
SFTKSlot *slot;
@@ -3815,32 +3935,34 @@ CK_RV NSC_CloseAllSessions (CK_SLOT_ID slotID)
#endif
slot = sftk_SlotFromID(slotID, PR_FALSE);
- if (slot == NULL) return CKR_SLOT_ID_INVALID;
+ 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)
+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;
+ if (session == NULL)
+ return CKR_SESSION_HANDLE_INVALID;
- PORT_Memcpy(pInfo,&session->info,sizeof(CK_SESSION_INFO));
+ 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)
+CK_RV
+NSC_Login(CK_SESSION_HANDLE hSession, CK_USER_TYPE userType,
+ CK_CHAR_PTR pPin, CK_ULONG ulPinLen)
{
SFTKSlot *slot;
SFTKSession *session;
@@ -3848,7 +3970,7 @@ CK_RV NSC_Login(CK_SESSION_HANDLE hSession, CK_USER_TYPE userType,
CK_FLAGS sessionFlags;
SECStatus rv;
CK_RV crv;
- char pinStr[SFTK_MAX_PIN+1];
+ char pinStr[SFTK_MAX_PIN + 1];
PRBool tokenRemoved = PR_FALSE;
CHECK_FORK();
@@ -3856,13 +3978,13 @@ CK_RV NSC_Login(CK_SESSION_HANDLE hSession, CK_USER_TYPE userType,
/* get the slot */
slot = sftk_SlotFromSessionHandle(hSession);
if (slot == NULL) {
- return CKR_SESSION_HANDLE_INVALID;
+ return CKR_SESSION_HANDLE_INVALID;
}
/* make sure the session is valid */
session = sftk_SessionFromHandle(hSession);
if (session == NULL) {
- return CKR_SESSION_HANDLE_INVALID;
+ return CKR_SESSION_HANDLE_INVALID;
}
sessionFlags = session->info.flags;
sftk_FreeSession(session);
@@ -3870,24 +3992,28 @@ CK_RV NSC_Login(CK_SESSION_HANDLE hSession, CK_USER_TYPE userType,
/* can't log into the Netscape Slot */
if (slot->slotID == NETSCAPE_SLOT_ID) {
- return CKR_USER_TYPE_INVALID;
+ return CKR_USER_TYPE_INVALID;
}
- if (slot->isLoggedIn) return CKR_USER_ALREADY_LOGGED_IN;
+ 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;
+ if (ulPinLen > SFTK_MAX_PIN)
+ return CKR_PIN_LEN_RANGE;
/* convert to null terminated string */
- PORT_Memcpy(pinStr,pPin,ulPinLen);
- pinStr[ulPinLen] = 0;
+ if (ulPinLen) {
+ PORT_Memcpy(pinStr, pPin, ulPinLen);
+ }
+ pinStr[ulPinLen] = 0;
handle = sftk_getKeyDB(slot);
if (handle == NULL) {
- return CKR_USER_TYPE_INVALID;
+ return CKR_USER_TYPE_INVALID;
}
/*
@@ -3897,72 +4023,71 @@ CK_RV NSC_Login(CK_SESSION_HANDLE hSession, CK_USER_TYPE userType,
*/
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;
- }
+ /* 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;
+ 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);
+ rv = sftkdb_CheckPassword(handle, pinStr, &tokenRemoved);
if (tokenRemoved) {
- sftk_CloseAllSessions(slot, PR_FALSE);
+ sftk_CloseAllSessions(slot, PR_FALSE);
}
if ((rv != SECSuccess) && (slot->slotID == FIPS_SLOT_ID)) {
- PR_Sleep(loginWaitTime);
+ 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);
+ 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;
+ sftk_freeDB(handle);
+ handle = NULL;
- /* update all sessions */
- sftk_update_all_states(slot);
- return CKR_OK;
+ /* update all sessions */
+ sftk_update_all_states(slot);
+ return CKR_OK;
}
crv = CKR_PIN_INCORRECT;
done:
if (handle) {
- sftk_freeDB(handle);
+ sftk_freeDB(handle);
}
return crv;
}
/* NSC_Logout logs a user out from a token. */
-CK_RV NSC_Logout(CK_SESSION_HANDLE hSession)
+CK_RV
+NSC_Logout(CK_SESSION_HANDLE hSession)
{
SFTKSlot *slot = sftk_SlotFromSessionHandle(hSession);
SFTKSession *session;
@@ -3971,25 +4096,27 @@ CK_RV NSC_Logout(CK_SESSION_HANDLE hSession)
CHECK_FORK();
if (slot == NULL) {
- return CKR_SESSION_HANDLE_INVALID;
+ return CKR_SESSION_HANDLE_INVALID;
}
session = sftk_SessionFromHandle(hSession);
- if (session == NULL) return CKR_SESSION_HANDLE_INVALID;
+ if (session == NULL)
+ return CKR_SESSION_HANDLE_INVALID;
sftk_FreeSession(session);
session = NULL;
- if (!slot->isLoggedIn) return CKR_USER_NOT_LOGGED_IN;
+ 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);
+ sftkdb_ClearPassword(handle);
}
PZ_Unlock(slot->slotLock);
if (handle) {
- sftk_freeDB(handle);
+ sftk_freeDB(handle);
}
sftk_update_all_states(slot);
@@ -4004,8 +4131,9 @@ CK_RV NSC_Logout(CK_SESSION_HANDLE hSession)
* "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)
+static CK_RV
+sftk_CreateNewSlot(SFTKSlot *slot, CK_OBJECT_CLASS class,
+ SFTKObject *object)
{
PRBool isValidUserSlot = PR_FALSE;
PRBool isValidFIPSUserSlot = PR_FALSE;
@@ -4020,25 +4148,25 @@ static CK_RV sftk_CreateNewSlot(SFTKSlot *slot, CK_OBJECT_CLASS class,
CK_RV crv = CKR_OK;
if (class != CKO_NETSCAPE_DELSLOT && class != CKO_NETSCAPE_NEWSLOT) {
- return CKR_ATTRIBUTE_VALUE_INVALID;
+ return CKR_ATTRIBUTE_VALUE_INVALID;
}
if (class == CKO_NETSCAPE_NEWSLOT && slot->slotID == FIPS_SLOT_ID) {
- isFIPS = PR_TRUE;
+ isFIPS = PR_TRUE;
}
attribute = sftk_FindAttribute(object, CKA_NETSCAPE_MODULE_SPEC);
if (attribute == NULL) {
- return CKR_TEMPLATE_INCOMPLETE;
+ return CKR_TEMPLATE_INCOMPLETE;
}
paramString = (char *)attribute->attrib.pValue;
crv = sftk_parseParameters(paramString, &paramStrings, isFIPS);
if (crv != CKR_OK) {
- goto loser;
+ goto loser;
}
/* enforce only one at a time */
if (paramStrings.token_count != 1) {
- crv = CKR_ATTRIBUTE_VALUE_INVALID;
- goto loser;
+ crv = CKR_ATTRIBUTE_VALUE_INVALID;
+ goto loser;
}
slotID = paramStrings.tokens[0].slotID;
@@ -4050,50 +4178,50 @@ static CK_RV sftk_CreateNewSlot(SFTKSlot *slot, CK_OBJECT_CLASS class,
slotID <= SFTK_MAX_FIPS_USER_SLOT_ID);
if (class == CKO_NETSCAPE_DELSLOT) {
- if (slot->slotID == slotID) {
- isValidSlot = isValidUserSlot || isValidFIPSUserSlot;
- }
+ 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;
- }
+ /* 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;
+ 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;
- }
+ 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 */
+ /* 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);
+ 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);
+ crv = SFTK_SlotInit(paramStrings.configdir,
+ paramStrings.updatedir, paramStrings.updateID,
+ &paramStrings.tokens[0], moduleIndex);
}
loser:
@@ -4103,11 +4231,11 @@ loser:
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)
+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;
@@ -4123,49 +4251,49 @@ CK_RV NSC_CreateObject(CK_SESSION_HANDLE hSession,
*phObject = CK_INVALID_HANDLE;
if (slot == NULL) {
- return CKR_SESSION_HANDLE_INVALID;
+ 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;
+ 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;
- }
+ 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);
+ 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;
- }
+ 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);
+ crv = sftk_handleObject(object, session);
*phObject = object->handle;
done:
sftk_FreeSession(session);
@@ -4174,14 +4302,13 @@ done:
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)
+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;
+ SFTKObject *destObject, *srcObject;
SFTKSession *session;
CK_RV crv = CKR_OK;
SFTKSlot *slot = sftk_SlotFromSessionHandle(hSession);
@@ -4190,54 +4317,56 @@ CK_RV NSC_CopyObject(CK_SESSION_HANDLE hSession,
CHECK_FORK();
if (slot == NULL) {
- return CKR_SESSION_HANDLE_INVALID;
+ 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);
+ srcObject = sftk_ObjectFromHandle(hObject, session);
if (srcObject == NULL) {
- sftk_FreeSession(session);
- return CKR_OBJECT_HANDLE_INVALID;
+ 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_FreeSession(session);
sftk_FreeObject(srcObject);
- return CKR_HOST_MEMORY;
+ 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; }
+ 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_FreeSession(session);
sftk_FreeObject(srcObject);
- sftk_FreeObject(destObject);
- return crv;
+ 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);
+ 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;
- }
+ sftk_FreeObject(destObject);
+ return CKR_ATTRIBUTE_READ_ONLY;
+ }
}
/*
@@ -4246,28 +4375,28 @@ CK_RV NSC_CopyObject(CK_SESSION_HANDLE hSession,
/* 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);
+ crv = sftk_CopyObject(destObject, srcObject);
destObject->objclass = srcObject->objclass;
sftk_FreeObject(srcObject);
if (crv != CKR_OK) {
- sftk_FreeObject(destObject);
- sftk_FreeSession(session);
+ sftk_FreeObject(destObject);
+ sftk_FreeSession(session);
return crv;
}
- crv = sftk_handleObject(destObject,session);
+ 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)
+CK_RV
+NSC_GetObjectSize(CK_SESSION_HANDLE hSession,
+ CK_OBJECT_HANDLE hObject, CK_ULONG_PTR pulSize)
{
CHECK_FORK();
@@ -4275,10 +4404,10 @@ CK_RV NSC_GetObjectSize(CK_SESSION_HANDLE hSession,
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)
+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;
@@ -4291,7 +4420,7 @@ CK_RV NSC_GetAttributeValue(CK_SESSION_HANDLE hSession,
CHECK_FORK();
if (slot == NULL) {
- return CKR_SESSION_HANDLE_INVALID;
+ return CKR_SESSION_HANDLE_INVALID;
}
/*
* make sure we're allowed
@@ -4303,75 +4432,75 @@ CK_RV NSC_GetAttributeValue(CK_SESSION_HANDLE hSession,
/* 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;
+ 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);
+ object = sftk_ObjectFromHandle(hObject, session);
sftk_FreeSession(session);
if (object == NULL) {
- return CKR_OBJECT_HANDLE_INVALID;
+ 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;
+ (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);
+ 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);
@@ -4379,8 +4508,9 @@ CK_RV NSC_GetAttributeValue(CK_SESSION_HANDLE hSession,
}
/* 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)
+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;
@@ -4394,7 +4524,7 @@ CK_RV NSC_SetAttributeValue (CK_SESSION_HANDLE hSession,
CHECK_FORK();
if (slot == NULL) {
- return CKR_SESSION_HANDLE_INVALID;
+ return CKR_SESSION_HANDLE_INVALID;
}
/*
* make sure we're allowed
@@ -4404,65 +4534,66 @@ CK_RV NSC_SetAttributeValue (CK_SESSION_HANDLE hSession,
return CKR_SESSION_HANDLE_INVALID;
}
- object = sftk_ObjectFromHandle(hObject,session);
+ object = sftk_ObjectFromHandle(hObject, session);
if (object == NULL) {
sftk_FreeSession(session);
- return CKR_OBJECT_HANDLE_INVALID;
+ 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;
+ (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);
+ 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);
+ 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;
+ 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);
@@ -4474,36 +4605,34 @@ 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);
+ 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)
+ const CK_ATTRIBUTE *pTemplate, CK_ULONG ulCount)
{
CK_RV crv;
- int objectListSize = search->array_size-search->size;
+ 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;
+ 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];
+ 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);
@@ -4515,8 +4644,8 @@ sftk_searchDatabase(SFTKDBHandle *handle, SFTKSearchResults *search,
* 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)
+sftk_emailhack(SFTKSlot *slot, SFTKDBHandle *handle,
+ SFTKSearchResults *search, CK_ATTRIBUTE *pTemplate, CK_ULONG ulCount)
{
PRBool isCert = PR_FALSE;
int emailIndex = -1;
@@ -4528,28 +4657,27 @@ sftk_emailhack(SFTKSlot *slot, SFTKDBHandle *handle,
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 */
+ * 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;
+ 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;
+ return CKR_OK;
}
/* we are doing a cert and email search, find the SMimeEntry */
@@ -4559,30 +4687,30 @@ sftk_emailhack(SFTKSlot *slot, SFTKDBHandle *handle,
smime_template[1] = pTemplate[emailIndex];
smime_search.handles = (CK_OBJECT_HANDLE *)
- PORT_Alloc(sizeof(CK_OBJECT_HANDLE) * NSC_SEARCH_BLOCK_SIZE);
+ PORT_Alloc(sizeof(CK_OBJECT_HANDLE) * NSC_SEARCH_BLOCK_SIZE);
if (smime_search.handles == NULL) {
- crv = CKR_HOST_MEMORY;
- goto loser;
+ 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;
+ 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;
+ crv = CKR_HOST_MEMORY; /* is there any other reason for this failure? */
+ goto loser;
}
- attribute = sftk_FindAttribute(object,CKA_SUBJECT);
+ attribute = sftk_FindAttribute(object, CKA_SUBJECT);
if (attribute == NULL) {
- crv = CKR_ATTRIBUTE_TYPE_INVALID;
- goto loser;
+ crv = CKR_ATTRIBUTE_TYPE_INVALID;
+ goto loser;
}
/* now find the certs with that subject */
@@ -4593,70 +4721,73 @@ sftk_emailhack(SFTKSlot *slot, SFTKDBHandle *handle,
loser:
if (attribute) {
- sftk_FreeAttribute(attribute);
+ sftk_FreeAttribute(attribute);
}
if (object) {
- sftk_FreeObject(object);
+ sftk_FreeObject(object);
}
if (smime_search.handles) {
- PORT_Free(smime_search.handles);
+ PORT_Free(smime_search.handles);
}
return crv;
}
-
+
static void
sftk_pruneSearch(CK_ATTRIBUTE *pTemplate, CK_ULONG ulCount,
- PRBool *searchCertDB, PRBool *searchKeyDB) {
+ 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;
- }
+ 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_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);
+ 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);
+ 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
+/* 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)
+CK_RV
+NSC_FindObjectsInit(CK_SESSION_HANDLE hSession,
+ CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulCount)
{
SFTKSearchResults *search = NULL, *freeSearch = NULL;
SFTKSession *session = NULL;
@@ -4666,26 +4797,26 @@ CK_RV NSC_FindObjectsInit(CK_SESSION_HANDLE hSession,
PRBool isLoggedIn;
CHECK_FORK();
-
+
if (slot == NULL) {
- return CKR_SESSION_HANDLE_INVALID;
+ return CKR_SESSION_HANDLE_INVALID;
}
session = sftk_SessionFromHandle(hSession);
if (session == NULL) {
- crv = CKR_SESSION_HANDLE_INVALID;
- goto loser;
+ crv = CKR_SESSION_HANDLE_INVALID;
+ goto loser;
}
-
+
search = (SFTKSearchResults *)PORT_Alloc(sizeof(SFTKSearchResults));
if (search == NULL) {
- crv = CKR_HOST_MEMORY;
- goto loser;
+ crv = CKR_HOST_MEMORY;
+ goto loser;
}
search->handles = (CK_OBJECT_HANDLE *)
- PORT_Alloc(sizeof(CK_OBJECT_HANDLE) * NSC_SEARCH_BLOCK_SIZE);
+ PORT_Alloc(sizeof(CK_OBJECT_HANDLE) * NSC_SEARCH_BLOCK_SIZE);
if (search->handles == NULL) {
- crv = CKR_HOST_MEMORY;
- goto loser;
+ crv = CKR_HOST_MEMORY;
+ goto loser;
}
search->index = 0;
search->size = 0;
@@ -4693,24 +4824,24 @@ CK_RV NSC_FindObjectsInit(CK_SESSION_HANDLE hSession,
isLoggedIn = (PRBool)((!slot->needLogin) || slot->isLoggedIn);
crv = sftk_searchTokenList(slot, search, pTemplate, ulCount, &tokenOnly,
- isLoggedIn);
+ isLoggedIn);
if (crv != CKR_OK) {
- goto loser;
+ 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);
+ crv = sftk_searchObjectList(search, slot->sessObjHashTable,
+ slot->sessObjHashSize, slot->objectLock,
+ pTemplate, ulCount, isLoggedIn);
}
if (crv != CKR_OK) {
- goto loser;
+ goto loser;
}
if ((freeSearch = session->search) != NULL) {
- session->search = NULL;
- sftk_FreeSearch(freeSearch);
+ session->search = NULL;
+ sftk_FreeSearch(freeSearch);
}
session->search = search;
sftk_FreeSession(session);
@@ -4718,49 +4849,50 @@ CK_RV NSC_FindObjectsInit(CK_SESSION_HANDLE hSession,
loser:
if (search) {
- sftk_FreeSearch(search);
+ sftk_FreeSearch(search);
}
if (session) {
- sftk_FreeSession(session);
+ sftk_FreeSession(session);
}
return crv;
}
-
-/* NSC_FindObjects continues a search for token and session objects
+/* 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)
+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 transfer;
int left;
CHECK_FORK();
*pulObjectCount = 0;
session = sftk_SessionFromHandle(hSession);
- if (session == NULL) return CKR_SESSION_HANDLE_INVALID;
+ if (session == NULL)
+ return CKR_SESSION_HANDLE_INVALID;
if (session->search == NULL) {
- sftk_FreeSession(session);
- return CKR_OK;
+ 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));
+ PORT_Memcpy(phObject, &search->handles[search->index],
+ transfer * sizeof(CK_OBJECT_HANDLE));
} else {
- *phObject = CK_INVALID_HANDLE;
+ *phObject = CK_INVALID_HANDLE;
}
search->index += transfer;
if (search->index == search->size) {
- session->search = NULL;
- sftk_FreeSearch(search);
+ session->search = NULL;
+ sftk_FreeSearch(search);
}
*pulObjectCount = transfer;
sftk_FreeSession(session);
@@ -4768,7 +4900,8 @@ CK_RV NSC_FindObjects(CK_SESSION_HANDLE hSession,
}
/* NSC_FindObjectsFinal finishes a search for token and session objects. */
-CK_RV NSC_FindObjectsFinal(CK_SESSION_HANDLE hSession)
+CK_RV
+NSC_FindObjectsFinal(CK_SESSION_HANDLE hSession)
{
SFTKSession *session;
SFTKSearchResults *search;
@@ -4776,23 +4909,22 @@ CK_RV NSC_FindObjectsFinal(CK_SESSION_HANDLE hSession)
CHECK_FORK();
session = sftk_SessionFromHandle(hSession);
- if (session == NULL) return CKR_SESSION_HANDLE_INVALID;
+ if (session == NULL)
+ return CKR_SESSION_HANDLE_INVALID;
search = session->search;
session->search = NULL;
sftk_FreeSession(session);
if (search != NULL) {
- sftk_FreeSearch(search);
+ sftk_FreeSearch(search);
}
return CKR_OK;
}
-
-
-CK_RV NSC_WaitForSlotEvent(CK_FLAGS flags, CK_SLOT_ID_PTR pSlot,
- CK_VOID_PTR pReserved)
+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/nss/lib/softoken/pkcs11c.c b/nss/lib/softoken/pkcs11c.c
index 8755f24..d7b4bb9 100644
--- a/nss/lib/softoken/pkcs11c.c
+++ b/nss/lib/softoken/pkcs11c.c
@@ -6,11 +6,11 @@
*
* 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
+ * 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
+ * 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.
*
@@ -27,7 +27,7 @@
#include "lowkeyi.h"
#include "secder.h"
#include "secdig.h"
-#include "lowpbe.h" /* We do PBE below */
+#include "lowpbe.h" /* We do PBE below */
#include "pkcs11t.h"
#include "secoid.h"
#include "alghmac.h"
@@ -36,21 +36,22 @@
#include "secerr.h"
#include "prprf.h"
+#include "prenv.h"
-#define __PASTE(x,y) x##y
+#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
-
+ CK_RV __PASTE(NS, func)
+#define CK_NEED_ARG_LIST 1
+
#include "pkcs11f.h"
typedef struct {
@@ -58,23 +59,24 @@ typedef struct {
PRUint8 random[46];
} SSL3RSAPreMasterSecret;
-static void sftk_Null(void *data, PRBool freeit)
+static void
+sftk_Null(void *data, PRBool freeit)
{
return;
-}
+}
#ifndef NSS_DISABLE_ECC
#ifdef EC_DEBUG
-#define SEC_PRINT(str1, str2, num, sitem) \
+#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")
+ str1, str2, num, sitem->len); \
+ for (i = 0; i < sitem->len; i++) { \
+ printf("%02x:", sitem->data[i]); \
+ } \
+ printf("\n")
#else
#undef EC_DEBUG
-#define SEC_PRINT(a, b, c, d)
+#define SEC_PRINT(a, b, c, d)
#endif
#endif /* NSS_DISABLE_ECC */
@@ -92,7 +94,7 @@ 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
@@ -103,33 +105,33 @@ 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_DISABLE_ECC is 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;
+ 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_DISABLE_ECC is 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;
}
@@ -139,10 +141,10 @@ static CK_RV
sftk_MapDecryptError(int error)
{
switch (error) {
- case SEC_ERROR_BAD_DATA:
- return CKR_ENCRYPTED_DATA_INVALID;
- default:
- return sftk_MapCryptError(error);
+ case SEC_ERROR_BAD_DATA:
+ return CKR_ENCRYPTED_DATA_INVALID;
+ default:
+ return sftk_MapCryptError(error);
}
}
@@ -155,11 +157,10 @@ sftk_MapVerifyError(int error)
{
CK_RV crv = sftk_MapCryptError(error);
if (crv == CKR_DEVICE_ERROR)
- crv = CKR_SIGNATURE_INVALID;
+ 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.
@@ -171,45 +172,47 @@ sftk_cdmf2des(unsigned char *cdmfkey, unsigned char *deskey)
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;
+ unsigned int leng, i;
DESContext *descx;
SECStatus rv;
-
-
+
/* zero the parity bits */
- for (i=0; i < 8; i++) {
- enc_src[i] = cdmfkey[i] & 0xfe;
+ 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;
+ 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());
+ 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;
- }
+ 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;
+ 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());
+ DES_DestroyContext(descx, PR_TRUE);
+ if (rv != SECSuccess)
+ return sftk_MapCryptError(PORT_GetError());
- /* set the corret parity on our new des key */
+ /* 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)
@@ -222,7 +225,7 @@ NSC_DestroyObject(CK_SESSION_HANDLE hSession, CK_OBJECT_HANDLE hObject)
CHECK_FORK();
if (slot == NULL) {
- return CKR_SESSION_HANDLE_INVALID;
+ return CKR_SESSION_HANDLE_INVALID;
}
/*
* This whole block just makes sure we really can destroy the
@@ -233,30 +236,30 @@ NSC_DestroyObject(CK_SESSION_HANDLE hSession, CK_OBJECT_HANDLE hObject)
return CKR_SESSION_HANDLE_INVALID;
}
- object = sftk_ObjectFromHandle(hObject,session);
+ object = sftk_ObjectFromHandle(hObject, session);
if (object == NULL) {
- sftk_FreeSession(session);
- return CKR_OBJECT_HANDLE_INVALID;
+ 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;
+ (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_isTrue(object, CKA_TOKEN))) {
+ sftk_FreeSession(session);
+ sftk_FreeObject(object);
+ return CKR_SESSION_READ_ONLY;
}
- sftk_DeleteObject(session,object);
+ sftk_DeleteObject(session, object);
sftk_FreeSession(session);
@@ -272,7 +275,6 @@ NSC_DestroyObject(CK_SESSION_HANDLE hSession, CK_OBJECT_HANDLE hObject)
return (status != SFTK_DestroyFailure) ? CKR_OK : CKR_DEVICE_ERROR;
}
-
/*
************** Crypto Functions: Utilities ************************
*/
@@ -344,48 +346,48 @@ sftk_ValidateOaepParams(const CK_RSA_PKCS_OAEP_PARAMS *params)
return PR_TRUE;
}
-/*
+/*
* 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;
+ 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)
+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;
+ 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;
}
@@ -398,25 +400,26 @@ sftk_SetContextByType(SFTKSession *session, SFTKContextType type,
* 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)
+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);
+ 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))){
+ if ((context == NULL) || (context->type != type) || (needMulti && !(context->multi))) {
sftk_FreeSession(session);
- return CKR_OPERATION_NOT_INITIALIZED;
+ return CKR_OPERATION_NOT_INITIALIZED;
}
*contextPtr = context;
if (sessionPtr != NULL) {
- *sessionPtr = session;
+ *sessionPtr = session;
} else {
- sftk_FreeSession(session);
+ sftk_FreeSession(session);
}
return CKR_OK;
}
@@ -425,11 +428,11 @@ sftk_GetContext(CK_SESSION_HANDLE handle,SFTKSessionContext **contextPtr,
* Intuitive name for FreeContext/SetNullContext pair.
*/
static void
-sftk_TerminateOp( SFTKSession *session, SFTKContextType ctype,
- SFTKSessionContext *context )
+sftk_TerminateOp(SFTKSession *session, SFTKContextType ctype,
+ SFTKSessionContext *context)
{
- sftk_FreeContext( context );
- sftk_SetContextByType( session, ctype, NULL );
+ sftk_FreeContext(context);
+ sftk_SetContextByType(session, ctype, NULL);
}
/*
@@ -441,55 +444,55 @@ sftk_TerminateOp( SFTKSession *session, SFTKContextType ctype,
* 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)
+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;
+ if (sftk_ReturnContextByType(session, ctype) != NULL) {
+ return CKR_OPERATION_ACTIVE;
}
/* find the key */
if (keyPtr) {
- key = sftk_ObjectFromHandle(hKey,session);
+ 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;
+ 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;
+ if (key)
+ sftk_FreeObject(key);
+ return CKR_HOST_MEMORY;
}
context->type = ctype;
context->multi = PR_TRUE;
@@ -510,17 +513,17 @@ 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;
+ 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;
}
@@ -631,7 +634,7 @@ sftk_RSAEncryptOAEP(SFTKOAEPEncryptInfo *info, unsigned char *output,
maskHashAlg = GetHashTypeFromMechanism(info->params->mgf);
return RSA_EncryptOAEP(&info->key->u.rsa, hashAlg, maskHashAlg,
- (const unsigned char*)info->params->pSourceData,
+ (const unsigned char *)info->params->pSourceData,
info->params->ulSourceDataLen, NULL, 0,
output, outputLen, maxLen, input, inputLen);
}
@@ -655,15 +658,111 @@ sftk_RSADecryptOAEP(SFTKOAEPDecryptInfo *info, unsigned char *output,
maskHashAlg = GetHashTypeFromMechanism(info->params->mgf);
rv = RSA_DecryptOAEP(&info->key->u.rsa, hashAlg, maskHashAlg,
- (const unsigned char*)info->params->pSourceData,
+ (const unsigned char *)info->params->pSourceData,
info->params->ulSourceDataLen,
output, outputLen, maxLen, input, inputLen);
- if (rv != SECSuccess && PORT_GetError() == SEC_ERROR_LIBRARY_FAILURE) {
+ if (rv != SECSuccess && PORT_GetError() == SEC_ERROR_LIBRARY_FAILURE) {
sftk_fatalError = PR_TRUE;
}
return rv;
}
+static SFTKChaCha20Poly1305Info *
+sftk_ChaCha20Poly1305_CreateContext(const unsigned char *key,
+ unsigned int keyLen,
+ const CK_NSS_AEAD_PARAMS *params)
+{
+ SFTKChaCha20Poly1305Info *ctx;
+
+ if (params->ulNonceLen != sizeof(ctx->nonce)) {
+ PORT_SetError(SEC_ERROR_INPUT_LEN);
+ return NULL;
+ }
+
+ ctx = PORT_New(SFTKChaCha20Poly1305Info);
+ if (ctx == NULL) {
+ return NULL;
+ }
+
+ if (ChaCha20Poly1305_InitContext(&ctx->freeblCtx, key, keyLen,
+ params->ulTagLen) != SECSuccess) {
+ PORT_Free(ctx);
+ return NULL;
+ }
+
+ PORT_Memcpy(ctx->nonce, params->pNonce, sizeof(ctx->nonce));
+
+ /* AAD data and length must both be null, or both non-null. */
+ PORT_Assert((params->pAAD == NULL) == (params->ulAADLen == 0));
+
+ if (params->ulAADLen > sizeof(ctx->ad)) {
+ /* Need to allocate an overflow buffer for the additional data. */
+ ctx->adOverflow = (unsigned char *)PORT_Alloc(params->ulAADLen);
+ if (!ctx->adOverflow) {
+ PORT_Free(ctx);
+ return NULL;
+ }
+ PORT_Memcpy(ctx->adOverflow, params->pAAD, params->ulAADLen);
+ } else {
+ ctx->adOverflow = NULL;
+ if (params->pAAD) {
+ PORT_Memcpy(ctx->ad, params->pAAD, params->ulAADLen);
+ }
+ }
+ ctx->adLen = params->ulAADLen;
+
+ return ctx;
+}
+
+static void
+sftk_ChaCha20Poly1305_DestroyContext(SFTKChaCha20Poly1305Info *ctx,
+ PRBool freeit)
+{
+ ChaCha20Poly1305_DestroyContext(&ctx->freeblCtx, PR_FALSE);
+ if (ctx->adOverflow != NULL) {
+ PORT_Free(ctx->adOverflow);
+ ctx->adOverflow = NULL;
+ }
+ ctx->adLen = 0;
+ if (freeit) {
+ PORT_Free(ctx);
+ }
+}
+
+static SECStatus
+sftk_ChaCha20Poly1305_Encrypt(const SFTKChaCha20Poly1305Info *ctx,
+ unsigned char *output, unsigned int *outputLen,
+ unsigned int maxOutputLen,
+ const unsigned char *input, unsigned int inputLen)
+{
+ const unsigned char *ad = ctx->adOverflow;
+
+ if (ad == NULL) {
+ ad = ctx->ad;
+ }
+
+ return ChaCha20Poly1305_Seal(&ctx->freeblCtx, output, outputLen,
+ maxOutputLen, input, inputLen, ctx->nonce,
+ sizeof(ctx->nonce), ad, ctx->adLen);
+}
+
+static SECStatus
+sftk_ChaCha20Poly1305_Decrypt(const SFTKChaCha20Poly1305Info *ctx,
+ unsigned char *output, unsigned int *outputLen,
+ unsigned int maxOutputLen,
+ const unsigned char *input, unsigned int inputLen)
+{
+ const unsigned char *ad = ctx->adOverflow;
+
+ if (ad == NULL) {
+ ad = ctx->ad;
+ }
+
+ return ChaCha20Poly1305_Open(&ctx->freeblCtx, output, outputLen,
+ maxOutputLen, input, inputLen, ctx->nonce,
+ sizeof(ctx->nonce), ad, ctx->adLen);
+}
+
/** NSC_CryptInit initializes an encryption/Decryption operation.
*
* Always called by NSC_EncryptInit, NSC_DecryptInit, NSC_WrapKey,NSC_UnwrapKey.
@@ -672,9 +771,9 @@ sftk_RSADecryptOAEP(SFTKOAEPDecryptInfo *info, unsigned char *output,
*/
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)
+ CK_OBJECT_HANDLE hKey,
+ CK_ATTRIBUTE_TYPE mechUsage, CK_ATTRIBUTE_TYPE keyUsage,
+ SFTKContextType contextType, PRBool isEncrypt)
{
SFTKSession *session;
SFTKObject *key;
@@ -689,412 +788,439 @@ sftk_CryptInit(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism,
CK_RV crv = CKR_OK;
unsigned effectiveKeyLength;
unsigned char newdeskey[24];
- PRBool useNewKey=PR_FALSE;
+ PRBool useNewKey = PR_FALSE;
int t;
- crv = sftk_MechAllowsOperation(pMechanism->mechanism, mechUsage );
- if (crv != CKR_OK)
- return crv;
+ crv = sftk_MechAllowsOperation(pMechanism->mechanism, mechUsage);
+ if (crv != CKR_OK)
+ return crv;
session = sftk_SessionFromHandle(hSession);
- if (session == NULL) return CKR_SESSION_HANDLE_INVALID;
+ 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);
- 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;
+ 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
- ? sftk_RSAEncryptRaw : sftk_RSAEncrypt);
- } 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
- ? sftk_RSADecryptRaw : sftk_RSADecrypt);
- }
- context->destroy = sftk_Null;
- break;
- case CKM_RSA_PKCS_OAEP:
- if (key_type != CKK_RSA) {
- crv = CKR_KEY_TYPE_INCONSISTENT;
- break;
- }
- if (pMechanism->ulParameterLen != sizeof(CK_RSA_PKCS_OAEP_PARAMS) ||
- !sftk_ValidateOaepParams((CK_RSA_PKCS_OAEP_PARAMS*)pMechanism->pParameter)) {
- crv = CKR_MECHANISM_PARAM_INVALID;
- break;
- }
- context->multi = PR_FALSE;
- context->rsa = PR_TRUE;
- 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_RSAEncryptOAEP;
- 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_RSADecryptOAEP;
- 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;
+ 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
+ ? sftk_RSAEncryptRaw
+ : sftk_RSAEncrypt);
+ } 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
+ ? sftk_RSADecryptRaw
+ : sftk_RSADecrypt);
+ }
+ context->destroy = sftk_Null;
+ break;
+ case CKM_RSA_PKCS_OAEP:
+ if (key_type != CKK_RSA) {
+ crv = CKR_KEY_TYPE_INCONSISTENT;
+ break;
+ }
+ if (pMechanism->ulParameterLen != sizeof(CK_RSA_PKCS_OAEP_PARAMS) ||
+ !sftk_ValidateOaepParams((CK_RSA_PKCS_OAEP_PARAMS *)pMechanism->pParameter)) {
+ crv = CKR_MECHANISM_PARAM_INVALID;
+ break;
+ }
+ context->multi = PR_FALSE;
+ context->rsa = PR_TRUE;
+ 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_RSAEncryptOAEP;
+ 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_RSADecryptOAEP;
+ 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;
+ 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;
+ 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_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;
+ 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;
+ 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_NSS_CHACHA20_POLY1305:
+ if (pMechanism->ulParameterLen != sizeof(CK_NSS_AEAD_PARAMS)) {
+ crv = CKR_MECHANISM_PARAM_INVALID;
+ break;
+ }
+ context->multi = PR_FALSE;
+ if (key_type != CKK_NSS_CHACHA20) {
+ crv = CKR_KEY_TYPE_INCONSISTENT;
+ break;
+ }
+ att = sftk_FindAttribute(key, CKA_VALUE);
+ if (att == NULL) {
+ crv = CKR_KEY_HANDLE_INVALID;
+ break;
+ }
+ context->cipherInfo = sftk_ChaCha20Poly1305_CreateContext(
+ (unsigned char *)att->attrib.pValue, att->attrib.ulValueLen,
+ (CK_NSS_AEAD_PARAMS *)pMechanism->pParameter);
+ sftk_FreeAttribute(att);
+ if (context->cipherInfo == NULL) {
+ crv = sftk_MapCryptError(PORT_GetError());
+ break;
+ }
+ context->update = (SFTKCipher)(isEncrypt ? sftk_ChaCha20Poly1305_Encrypt : sftk_ChaCha20Poly1305_Decrypt);
+ context->destroy = (SFTKDestroy)sftk_ChaCha20Poly1305_DestroyContext;
+ break;
+
+ case CKM_NSS_AES_KEY_WRAP_PAD:
+ context->doPad = PR_TRUE;
+ /* fall thru */
+ case CKM_NSS_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_FreeSession(session);
+ return crv;
}
sftk_SetContextByType(session, contextType, context);
sftk_FreeSession(session);
@@ -1102,21 +1228,23 @@ finish_des:
}
/* NSC_EncryptInit initializes an encryption operation. */
-CK_RV NSC_EncryptInit(CK_SESSION_HANDLE hSession,
- CK_MECHANISM_PTR pMechanism, CK_OBJECT_HANDLE hKey)
+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);
+ 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)
+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 outlen, i;
unsigned int padoutlen = 0;
unsigned int maxout = *pulEncryptedPartLen;
CK_RV crv;
@@ -1125,79 +1253,79 @@ CK_RV NSC_EncryptUpdate(CK_SESSION_HANDLE hSession,
CHECK_FORK();
/* make sure we're legal */
- crv = sftk_GetContext(hSession,&context,SFTK_ENCRYPT,PR_TRUE,NULL);
- if (crv != CKR_OK) return crv;
+ 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;
+ 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;
+ *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;
- }
- }
+ /* 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);
+ 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)
+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 outlen, i;
unsigned int maxout = *pulLastEncryptedPartLen;
CK_RV crv;
SECStatus rv = SECSuccess;
@@ -1206,43 +1334,45 @@ CK_RV NSC_EncryptFinal(CK_SESSION_HANDLE hSession,
CHECK_FORK();
/* make sure we're legal */
- crv = sftk_GetContext(hSession,&context,SFTK_ENCRYPT,PR_TRUE,&session);
- if (crv != CKR_OK) return crv;
+ 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;
+ /* 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;
+ 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_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)
+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;
@@ -1251,94 +1381,95 @@ CK_RV NSC_Encrypt (CK_SESSION_HANDLE hSession, CK_BYTE_PTR pData,
CK_RV crv;
CK_RV crv2;
SECStatus rv = SECSuccess;
- SECItem pText;
+ SECItem pText;
pText.type = siBuffer;
pText.data = pData;
- pText.len = ulDataLen;
+ 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;
+ 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;
+ *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;
- }
- }
+ 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);
+ 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;
+ *pulEncryptedDataLen = (CK_ULONG)outlen;
if (pText.data != pData)
- PORT_ZFree(pText.data, pText.len);
+ PORT_ZFree(pText.data, pText.len);
fail:
- sftk_TerminateOp( session, SFTK_ENCRYPT, context );
+ 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)
+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);
+ 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)
+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;
@@ -1350,69 +1481,70 @@ CK_RV NSC_DecryptUpdate(CK_SESSION_HANDLE hSession,
CHECK_FORK();
/* make sure we're legal */
- crv = sftk_GetContext(hSession,&context,SFTK_DECRYPT,PR_TRUE,NULL);
- if (crv != CKR_OK) return crv;
+ 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);
-
+ PORT_Assert((context->padDataLength == 0) || context->padDataLength == context->blockSize);
if (context->doPad) {
- /* Check the data length for block ciphers. 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 we do the actual decrypt. We need to do the
- * check here to avoid returning a negative length to the caller
- * or reading before the beginning of the pEncryptedPart buffer.
- */
- if ((ulEncryptedPartLen == 0) ||
- (ulEncryptedPartLen % context->blockSize) != 0) {
- return CKR_ENCRYPTED_DATA_LEN_RANGE;
- }
+ /* Check the data length for block ciphers. 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 we do the actual decrypt. We need to do the
+ * check here to avoid returning a negative length to the caller
+ * or reading before the beginning of the pEncryptedPart buffer.
+ */
+ if ((ulEncryptedPartLen == 0) ||
+ (ulEncryptedPartLen % context->blockSize) != 0) {
+ return CKR_ENCRYPTED_DATA_LEN_RANGE;
+ }
}
if (!pPart) {
- if (context->doPad) {
- *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) {
+ *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;
+ /* 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());
+ 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)
+CK_RV
+NSC_DecryptFinal(CK_SESSION_HANDLE hSession,
+ CK_BYTE_PTR pLastPart, CK_ULONG_PTR pulLastPartLen)
{
SFTKSession *session;
SFTKSessionContext *context;
@@ -1424,60 +1556,62 @@ CK_RV NSC_DecryptFinal(CK_SESSION_HANDLE hSession,
CHECK_FORK();
/* make sure we're legal */
- crv = sftk_GetContext(hSession,&context,SFTK_DECRYPT,PR_TRUE,&session);
- if (crv != CKR_OK) return crv;
+ 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;
+ /* 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 );
+ /* 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)
+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;
@@ -1490,69 +1624,69 @@ CK_RV NSC_Decrypt(CK_SESSION_HANDLE hSession,
CHECK_FORK();
/* make sure we're legal */
- crv = sftk_GetContext(hSession,&context,SFTK_DECRYPT,PR_FALSE,&session);
- if (crv != CKR_OK) return crv;
+ crv = sftk_GetContext(hSession, &context, SFTK_DECRYPT, PR_FALSE, &session);
+ if (crv != CKR_OK)
+ return crv;
if (!pData) {
- *pulDataLen = ulEncryptedDataLen + context->blockSize;
- goto finish;
+ *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);
+ 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 );
+ 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)
+CK_RV
+NSC_DigestInit(CK_SESSION_HANDLE hSession,
+ CK_MECHANISM_PTR pMechanism)
{
SFTKSession *session;
SFTKSessionContext *context;
@@ -1561,61 +1695,60 @@ CK_RV NSC_DigestInit(CK_SESSION_HANDLE hSession,
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 (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;
+ 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_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)
+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;
@@ -1626,30 +1759,31 @@ CK_RV NSC_Digest(CK_SESSION_HANDLE hSession,
CHECK_FORK();
/* make sure we're legal */
- crv = sftk_GetContext(hSession,&context,SFTK_HASH,PR_FALSE,&session);
- if (crv != CKR_OK) return crv;
+ crv = sftk_GetContext(hSession, &context, SFTK_HASH, PR_FALSE, &session);
+ if (crv != CKR_OK)
+ return crv;
if (pDigest == NULL) {
- *pulDigestLen = context->maxLen;
- goto finish;
+ *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);
+ (*context->end)(context->cipherInfo, pDigest, &digestLen, maxout);
*pulDigestLen = digestLen;
- sftk_TerminateOp( session, SFTK_HASH, context );
+ 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)
+CK_RV
+NSC_DigestUpdate(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pPart,
+ CK_ULONG ulPartLen)
{
SFTKSessionContext *context;
CK_RV crv;
@@ -1657,17 +1791,18 @@ CK_RV NSC_DigestUpdate(CK_SESSION_HANDLE hSession,CK_BYTE_PTR pPart,
CHECK_FORK();
/* make sure we're legal */
- crv = sftk_GetContext(hSession,&context,SFTK_HASH,PR_TRUE,NULL);
- if (crv != CKR_OK) return crv;
+ 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)
+CK_RV
+NSC_DigestFinal(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pDigest,
+ CK_ULONG_PTR pulDigestLen)
{
SFTKSession *session;
SFTKSessionContext *context;
@@ -1679,14 +1814,15 @@ CK_RV NSC_DigestFinal(CK_SESSION_HANDLE hSession,CK_BYTE_PTR pDigest,
/* make sure we're legal */
crv = sftk_GetContext(hSession, &context, SFTK_HASH, PR_TRUE, &session);
- if (crv != CKR_OK) return crv;
+ if (crv != CKR_OK)
+ return crv;
if (pDigest != NULL) {
(*context->end)(context->cipherInfo, pDigest, &digestLen, maxout);
*pulDigestLen = digestLen;
- sftk_TerminateOp( session, SFTK_HASH, context );
+ sftk_TerminateOp(session, SFTK_HASH, context);
} else {
- *pulDigestLen = context->maxLen;
+ *pulDigestLen = context->maxLen;
}
sftk_FreeSession(session);
@@ -1695,22 +1831,23 @@ CK_RV NSC_DigestFinal(CK_SESSION_HANDLE hSession,CK_BYTE_PTR pDigest,
/*
* these helper functions are used by Generic Macing and Signing functions
- * that use hashes as part of their operations.
+ * 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; \
-}
+#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)
@@ -1722,40 +1859,40 @@ DOSUB(SHA512)
static SECStatus
sftk_SignCopy(
- CK_ULONG *copyLen,
- void *out, unsigned int *outLength,
- unsigned int maxLength,
- const unsigned char *hashResult,
- unsigned int hashResultLength)
+ 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;
+ toCopy = maxLength;
}
if (toCopy > hashResultLength) {
- toCopy = hashResultLength;
+ toCopy = hashResultLength;
}
memcpy(out, hashResult, toCopy);
if (outLength) {
- *outLength = toCopy;
+ *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)
+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 ;
+ 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)
+sftk_doHMACInit(SFTKSessionContext *context, HASH_HashType hash,
+ SFTKObject *key, CK_ULONG mac_size)
{
SFTKAttribute *keyval;
HMACContext *HMACcontext;
@@ -1764,38 +1901,39 @@ sftk_doHMACInit(SFTKSessionContext *context,HASH_HashType 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;
+ 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;
+ 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);
+ 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;
+ 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->hashUpdate = (SFTKHash)HMAC_Update;
+ context->end = (SFTKEnd)HMAC_Finish;
- context->hashdestroy = (SFTKDestroy) HMAC_Destroy;
+ context->hashdestroy = (SFTKDestroy)HMAC_Destroy;
intpointer = PORT_New(CK_ULONG);
if (intpointer == NULL) {
- return CKR_HOST_MEMORY;
+ 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->destroy = (SFTKDestroy)sftk_Space;
+ context->update = (SFTKCipher)sftk_SignCopy;
+ context->verify = (SFTKVerify)sftk_HMACCmp;
context->maxLen = hashObj->length;
HMAC_Begin(HMACcontext);
return CKR_OK;
@@ -1812,7 +1950,7 @@ sftk_doHMACInit(SFTKSessionContext *context,HASH_HashType hash,
* 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] = {
+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,
@@ -1822,7 +1960,7 @@ static unsigned char ssl_pad_1 [60] = {
0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
0x36, 0x36, 0x36, 0x36
};
-static unsigned char ssl_pad_2 [60] = {
+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,
@@ -1834,44 +1972,43 @@ static unsigned char ssl_pad_2 [60] = {
};
static SECStatus
-sftk_SSLMACSign(SFTKSSLMACInfo *info,unsigned char *sig,unsigned int *sigLen,
- unsigned int maxLen,unsigned char *hash, unsigned int hashLen)
+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);
+ 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)
+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;
+ 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)
+sftk_doSSLMACInit(SFTKSessionContext *context, SECOidTag oid,
+ SFTKObject *key, CK_ULONG mac_size)
{
SFTKAttribute *keyval;
SFTKBegin begin;
@@ -1880,43 +2017,46 @@ sftk_doSSLMACInit(SFTKSessionContext *context,SECOidTag oid,
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;
+ 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;
+ 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;
+ 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));
+ 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;
+ return CKR_HOST_MEMORY;
}
sslmacinfo->macSize = mac_size;
sslmacinfo->hashContext = context->hashInfo;
- PORT_Memcpy(sslmacinfo->key,keyval->attrib.pValue,
- keyval->attrib.ulValueLen);
+ 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->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;
}
@@ -1925,16 +2065,16 @@ sftk_doSSLMACInit(SFTKSessionContext *context,SECOidTag oid,
************** 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_OBJECT_HANDLE hKey, CK_ATTRIBUTE_TYPE keyUsage,
+ SFTKContextType contextType)
+
{
CK_MECHANISM cbc_mechanism;
CK_ULONG mac_bytes = SFTK_INVALID_MAC_SIZE;
@@ -1949,105 +2089,109 @@ sftk_InitCBCMac(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism,
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;
+ case CKM_RC2_MAC_GENERAL:
+ if (!pMechanism->pParameter) {
+ return CKR_MECHANISM_PARAM_INVALID;
+ }
+ 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;
+ 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;
+ /* 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.
@@ -2055,26 +2199,28 @@ sftk_InitCBCMac(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism,
if (mac_bytes == SFTK_INVALID_MAC_SIZE)
mac_bytes = blockSize >> 1;
else {
- if( mac_bytes > blockSize )
+ 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);
+ 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;
+ if (crv != CKR_OK)
+ return crv;
context->blockSize = blockSize;
context->macSize = mac_bytes;
return CKR_OK;
}
/*
- * encode RSA PKCS #1 Signature data before signing...
+ * encode RSA PKCS #1 Signature data before signing...
*/
static SECStatus
sftk_RSAHashSign(SFTKHashSignInfo *info, unsigned char *sig,
@@ -2094,12 +2240,12 @@ sftk_RSAHashSign(SFTKHashSignInfo *info, unsigned char *sig,
/* XXX Old template; want to expunge it eventually. */
static DERTemplate SECAlgorithmIDTemplate[] = {
{ DER_SEQUENCE,
- 0, NULL, sizeof(SECAlgorithmID) },
+ 0, NULL, sizeof(SECAlgorithmID) },
{ DER_OBJECT_ID,
- offsetof(SECAlgorithmID,algorithm), },
+ offsetof(SECAlgorithmID, algorithm) },
{ DER_OPTIONAL | DER_ANY,
- offsetof(SECAlgorithmID,parameters), },
- { 0, }
+ offsetof(SECAlgorithmID, parameters) },
+ { 0 }
};
/*
@@ -2108,17 +2254,17 @@ static DERTemplate SECAlgorithmIDTemplate[] = {
*/
static DERTemplate SGNDigestInfoTemplate[] = {
{ DER_SEQUENCE,
- 0, NULL, sizeof(SGNDigestInfo) },
+ 0, NULL, sizeof(SGNDigestInfo) },
{ DER_INLINE,
- offsetof(SGNDigestInfo,digestAlgorithm),
- SECAlgorithmIDTemplate, },
+ offsetof(SGNDigestInfo, digestAlgorithm),
+ SECAlgorithmIDTemplate },
{ DER_OCTET_STRING,
- offsetof(SGNDigestInfo,digest), },
- { 0, }
+ offsetof(SGNDigestInfo, digest) },
+ { 0 }
};
/*
- * encode RSA PKCS #1 Signature data before signing...
+ * encode RSA PKCS #1 Signature data before signing...
*/
SECStatus
RSA_HashSign(SECOidTag hashOid, NSSLOWKEYPrivateKey *key,
@@ -2159,7 +2305,7 @@ RSA_HashSign(SECOidTag hashOid, NSSLOWKEYPrivateKey *key,
sftk_fatalError = PR_TRUE;
}
- loser:
+loser:
SGN_DestroyDigestInfo(di);
if (arena != NULL) {
PORT_FreeArena(arena, PR_FALSE);
@@ -2207,7 +2353,6 @@ sftk_RSASignRaw(NSSLOWKEYPrivateKey *key, unsigned char *output,
sftk_fatalError = PR_TRUE;
}
return rv;
-
}
static SECStatus
@@ -2239,7 +2384,7 @@ sftk_RSASignPSS(SFTKHashSignInfo *info, unsigned char *sig,
static SECStatus
nsc_DSA_Verify_Stub(void *ctx, void *sigBuf, unsigned int sigLen,
- void *dataBuf, unsigned int dataLen)
+ void *dataBuf, unsigned int dataLen)
{
SECItem signature, digest;
NSSLOWKEYPublicKey *key = (NSSLOWKEYPublicKey *)ctx;
@@ -2266,7 +2411,7 @@ nsc_DSA_Sign_Stub(void *ctx, void *sigBuf,
digest.len = dataLen;
rv = DSA_SignDigest(&(key->u.dsa), &signature, &digest);
if (rv != SECSuccess && PORT_GetError() == SEC_ERROR_LIBRARY_FAILURE) {
- sftk_fatalError = PR_TRUE;
+ sftk_fatalError = PR_TRUE;
}
*sigLen = signature.len;
return rv;
@@ -2302,7 +2447,7 @@ nsc_ECDSASignStub(void *ctx, void *sigBuf,
digest.len = dataLen;
rv = ECDSA_SignDigest(&(key->u.ec), &signature, &digest);
if (rv != SECSuccess && PORT_GetError() == SEC_ERROR_LIBRARY_FAILURE) {
- sftk_fatalError = PR_TRUE;
+ sftk_fatalError = PR_TRUE;
}
*sigLen = signature.len;
return rv;
@@ -2311,28 +2456,29 @@ nsc_ECDSASignStub(void *ctx, void *sigBuf,
/* 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
+ * (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
+ * (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,
+ * (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
+ * (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
+ * 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
+ * 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)
+CK_RV
+NSC_SignInit(CK_SESSION_HANDLE hSession,
+ CK_MECHANISM_PTR pMechanism, CK_OBJECT_HANDLE hKey)
{
SFTKSession *session;
SFTKObject *key;
@@ -2346,293 +2492,300 @@ CK_RV NSC_SignInit(CK_SESSION_HANDLE hSession,
/* 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;
+ 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 (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;
+ 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_RSAHashSign; \
- 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) sftk_RSASign;
- goto finish_rsa;
- case CKM_RSA_X_509:
- context->update = (SFTKCipher) sftk_RSASignRaw;
-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) ||
- !sftk_ValidatePssParams((const CK_RSA_PKCS_PSS_PARAMS*)pMechanism->pParameter)) {
- 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_RSASignPSS;
- 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;
+#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_RSAHashSign; \
+ 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)sftk_RSASign;
+ goto finish_rsa;
+ case CKM_RSA_X_509:
+ context->update = (SFTKCipher)sftk_RSASignRaw;
+ 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) ||
+ !sftk_ValidatePssParams((const CK_RSA_PKCS_PSS_PARAMS *)pMechanism->pParameter)) {
+ 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_RSASignPSS;
+ 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;
#ifndef NSS_DISABLE_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;
+ 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_DISABLE_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, HASH_AlgNULL, 0);
- break;
- case CKM_TLS_MAC: {
- CK_TLS_MAC_PARAMS *tls12_mac_params;
- HASH_HashType tlsPrfHash;
- const char *label;
-
- if (pMechanism->ulParameterLen != sizeof(CK_TLS_MAC_PARAMS)) {
- crv = CKR_MECHANISM_PARAM_INVALID;
- break;
- }
- tls12_mac_params = (CK_TLS_MAC_PARAMS *)pMechanism->pParameter;
- if (tls12_mac_params->prfMechanism == CKM_TLS_PRF) {
- /* The TLS 1.0 and 1.1 PRF */
- tlsPrfHash = HASH_AlgNULL;
- if (tls12_mac_params->ulMacLength != 12) {
- crv = CKR_MECHANISM_PARAM_INVALID;
- break;
- }
- } else {
- /* The hash function for the TLS 1.2 PRF */
- tlsPrfHash =
- GetHashTypeFromMechanism(tls12_mac_params->prfMechanism);
- if (tlsPrfHash == HASH_AlgNULL ||
- tls12_mac_params->ulMacLength < 12) {
- crv = CKR_MECHANISM_PARAM_INVALID;
- break;
- }
- }
- if (tls12_mac_params->ulServerOrClient == 1) {
- label = "server finished";
- } else if (tls12_mac_params->ulServerOrClient == 2) {
- label = "client finished";
- } else {
- crv = CKR_MECHANISM_PARAM_INVALID;
- break;
- }
- crv = sftk_TLSPRFInit(context, key, key_type, tlsPrfHash,
- tls12_mac_params->ulMacLength);
- if (crv == CKR_OK) {
- context->hashUpdate(context->hashInfo, label, 15);
- }
- break;
- }
- case CKM_NSS_TLS_PRF_GENERAL_SHA256:
- crv = sftk_TLSPRFInit(context, key, key_type, HASH_AlgSHA256, 0);
- 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) {
- PORT_Free(ctx);
- 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 = (SFTKCipher) 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) {
- PORT_Free(ctx);
- 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 = (SFTKCipher) sftk_SignCopy;
- context->destroy = sftk_Space;
- context->maxLen = 64;
- context->multi = PR_TRUE;
- break;
- }
-
- default:
- crv = CKR_MECHANISM_INVALID;
- break;
+#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, HASH_AlgNULL, 0);
+ break;
+ case CKM_TLS_MAC: {
+ CK_TLS_MAC_PARAMS *tls12_mac_params;
+ HASH_HashType tlsPrfHash;
+ const char *label;
+
+ if (pMechanism->ulParameterLen != sizeof(CK_TLS_MAC_PARAMS)) {
+ crv = CKR_MECHANISM_PARAM_INVALID;
+ break;
+ }
+ tls12_mac_params = (CK_TLS_MAC_PARAMS *)pMechanism->pParameter;
+ if (tls12_mac_params->prfMechanism == CKM_TLS_PRF) {
+ /* The TLS 1.0 and 1.1 PRF */
+ tlsPrfHash = HASH_AlgNULL;
+ if (tls12_mac_params->ulMacLength != 12) {
+ crv = CKR_MECHANISM_PARAM_INVALID;
+ break;
+ }
+ } else {
+ /* The hash function for the TLS 1.2 PRF */
+ tlsPrfHash =
+ GetHashTypeFromMechanism(tls12_mac_params->prfMechanism);
+ if (tlsPrfHash == HASH_AlgNULL ||
+ tls12_mac_params->ulMacLength < 12) {
+ crv = CKR_MECHANISM_PARAM_INVALID;
+ break;
+ }
+ }
+ if (tls12_mac_params->ulServerOrClient == 1) {
+ label = "server finished";
+ } else if (tls12_mac_params->ulServerOrClient == 2) {
+ label = "client finished";
+ } else {
+ crv = CKR_MECHANISM_PARAM_INVALID;
+ break;
+ }
+ crv = sftk_TLSPRFInit(context, key, key_type, tlsPrfHash,
+ tls12_mac_params->ulMacLength);
+ if (crv == CKR_OK) {
+ context->hashUpdate(context->hashInfo, label, 15);
+ }
+ break;
+ }
+ case CKM_NSS_TLS_PRF_GENERAL_SHA256:
+ crv = sftk_TLSPRFInit(context, key, key_type, HASH_AlgSHA256, 0);
+ 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) {
+ PORT_Free(ctx);
+ 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 = (SFTKCipher)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) {
+ PORT_Free(ctx);
+ 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 = (SFTKCipher)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);
+ if (info)
+ PORT_Free(info);
sftk_FreeContext(context);
sftk_FreeSession(session);
return crv;
@@ -2645,12 +2798,13 @@ finish_rsa:
/** MAC one block of data by block cipher
*/
static CK_RV
-sftk_MACBlock( SFTKSessionContext *ctx, void *blk )
+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());
+ 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
@@ -2658,100 +2812,101 @@ sftk_MACBlock( SFTKSessionContext *ctx, void *blk )
* Call once, then terminate MACing operation.
*/
static CK_RV
-sftk_MACFinal( SFTKSessionContext *ctx )
+sftk_MACFinal(SFTKSessionContext *ctx)
{
unsigned int padLen = ctx->padDataLength;
/* pad and proceed the residual */
- if( padLen ) {
+ 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 );
+ 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)
+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;
+ 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 */
+ (*context->hashUpdate)(context->hashInfo, pPart, ulPartLen);
+ } else {
+ /* must be block cipher MACing */
- unsigned int blkSize = context->blockSize;
+ 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;
+ 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 );
+ if (ulPartLen < minInput) {
+ PORT_Memcpy(residual, pPart, ulPartLen);
context->padDataLength += ulPartLen;
goto cleanup;
}
/* MACing residual */
- if( context->padDataLength ) {
- PORT_Memcpy( residual, pPart, minInput );
+ if (context->padDataLength) {
+ PORT_Memcpy(residual, pPart, minInput);
ulPartLen -= minInput;
- pPart += minInput;
- if( CKR_OK != (crv = sftk_MACBlock( context, context->padBuf )) )
+ 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 )) )
+ while (ulPartLen >= blkSize) {
+ if (CKR_OK != (crv = sftk_MACBlock(context, pPart)))
goto terminate;
ulPartLen -= blkSize;
- pPart += blkSize;
+ pPart += blkSize;
}
/* save the residual */
- if( (context->padDataLength = ulPartLen) )
- PORT_Memcpy( context->padBuf, pPart, ulPartLen );
+ if ((context->padDataLength = ulPartLen))
+ PORT_Memcpy(context->padBuf, pPart, ulPartLen);
} /* blk cipher MACing */
- goto cleanup;
+ goto cleanup;
terminate:
- sftk_TerminateOp( session, type, context );
+ 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
+ * 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)
+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,
+/* 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)
+CK_RV
+NSC_SignFinal(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pSignature,
+ CK_ULONG_PTR pulSignatureLen)
{
SFTKSession *session;
SFTKSessionContext *context;
@@ -2762,19 +2917,21 @@ CK_RV NSC_SignFinal(CK_SESSION_HANDLE hSession,CK_BYTE_PTR pSignature,
CHECK_FORK();
/* make sure we're legal */
- crv = sftk_GetContext(hSession,&context,SFTK_SIGN,PR_TRUE,&session);
- if (crv != CKR_OK) return crv;
+ 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;
+ 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))
+ 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
@@ -2783,15 +2940,16 @@ CK_RV NSC_SignFinal(CK_SESSION_HANDLE hSession,CK_BYTE_PTR pSignature,
/* 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;
+ 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 );
+ if (CKR_OK == (crv = sftk_MACFinal(context)))
+ PORT_Memcpy(pSignature, context->macBuf, outlen);
}
- sftk_TerminateOp( session, SFTK_SIGN, context );
+ sftk_TerminateOp(session, SFTK_SIGN, context);
finish:
*pulSignatureLen = outlen;
sftk_FreeSession(session);
@@ -2799,11 +2957,12 @@ finish:
}
/* NSC_Sign signs (encrypts with private key) data in a single part,
- * where the signature is (will be) an appendix to the data,
+ * 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)
+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;
@@ -2812,33 +2971,34 @@ CK_RV NSC_Sign(CK_SESSION_HANDLE hSession,
CHECK_FORK();
/* make sure we're legal */
- crv = sftk_GetContext(hSession,&context,SFTK_SIGN,PR_FALSE,&session);
- if (crv != CKR_OK) return crv;
+ 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;
+ *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) ))
+ if (CKR_OK == (crv = NSC_SignUpdate(hSession, pData, ulDataLen)))
crv = NSC_SignFinal(hSession, pSignature, pulSignatureLen);
- } else {
- /* single-part PKC signature (e.g. CKM_ECDSA) */
+ } 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))
+ if (SECSuccess != (*context->update)(context->cipherInfo, pSignature,
+ &outlen, maxoutlen, pData, ulDataLen))
crv = sftk_MapCryptError(PORT_GetError());
- *pulSignatureLen = (CK_ULONG) outlen;
+ *pulSignatureLen = (CK_ULONG)outlen;
/* "too small" here is certainly continuable */
- if( crv != CKR_BUFFER_TOO_SMALL )
+ if (crv != CKR_BUFFER_TOO_SMALL)
sftk_TerminateOp(session, SFTK_SIGN, context);
} /* single-part */
@@ -2847,38 +3007,38 @@ finish:
return crv;
}
-
/*
************** Crypto Functions: Sign Recover ************************
*/
/* NSC_SignRecoverInit initializes a signature operation,
- * where the (digest) data can be recovered from the signature.
+ * 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)
+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;
+ 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.
+ * 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)
+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);
+ return NSC_Sign(hSession, pData, ulDataLen, pSignature, pulSignatureLen);
}
/*
@@ -2887,7 +3047,7 @@ CK_RV NSC_SignRecover(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pData,
/* Handle RSA Signature formatting */
static SECStatus
-sftk_hashCheckSign(SFTKHashVerifyInfo *info, const unsigned char *sig,
+sftk_hashCheckSign(SFTKHashVerifyInfo *info, const unsigned char *sig,
unsigned int sigLen, const unsigned char *digest,
unsigned int digestLen)
{
@@ -2922,19 +3082,19 @@ RSA_HashCheckSign(SECOidTag digestOid, NSSLOWKEYPublicKey *key,
pkcs1DigestInfo.data = pkcs1DigestInfoData;
pkcs1DigestInfo.len = bufferSize;
-
+
/* decrypt the block */
rv = RSA_CheckSignRecover(&key->u.rsa, pkcs1DigestInfo.data,
- &pkcs1DigestInfo.len, pkcs1DigestInfo.len,
- sig, sigLen);
+ &pkcs1DigestInfo.len, pkcs1DigestInfo.len,
+ sig, sigLen);
if (rv != SECSuccess) {
PORT_SetError(SEC_ERROR_BAD_SIGNATURE);
} else {
- digest.data = (PRUint8*) digestData;
+ digest.data = (PRUint8 *)digestData;
digest.len = digestLen;
rv = _SGN_VerifyPKCS1DigestInfo(
- digestOid, &digest, &pkcs1DigestInfo,
- PR_TRUE /*XXX: unsafeAllowMissingParameters*/);
+ digestOid, &digest, &pkcs1DigestInfo,
+ PR_TRUE /*XXX: unsafeAllowMissingParameters*/);
}
PORT_Free(pkcs1DigestInfoData);
@@ -2991,11 +3151,12 @@ sftk_RSACheckSignPSS(SFTKHashVerifyInfo *info, const unsigned char *sig,
params->sLen, sig, sigLen, digest, digestLen);
}
-/* NSC_VerifyInit initializes a verification operation,
- * where the signature is an appendix to the data,
+/* 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)
+CK_RV
+NSC_VerifyInit(CK_SESSION_HANDLE hSession,
+ CK_MECHANISM_PTR pMechanism, CK_OBJECT_HANDLE hKey)
{
SFTKSession *session;
SFTKObject *key;
@@ -3009,183 +3170,195 @@ CK_RV NSC_VerifyInit(CK_SESSION_HANDLE hSession,
/* 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;
+ 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 (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;
+ 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) sftk_RSACheckSign;
- goto finish_rsa;
- case CKM_RSA_X_509:
- context->verify = (SFTKVerify) sftk_RSACheckSignRaw;
-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) ||
- !sftk_ValidatePssParams((const CK_RSA_PKCS_PSS_PARAMS*)pMechanism->pParameter)) {
- 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_RSACheckSignPSS;
- 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;
+#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)sftk_RSACheckSign;
+ goto finish_rsa;
+ case CKM_RSA_X_509:
+ context->verify = (SFTKVerify)sftk_RSACheckSignRaw;
+ 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) ||
+ !sftk_ValidatePssParams((const CK_RSA_PKCS_PSS_PARAMS *)pMechanism->pParameter)) {
+ 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_RSACheckSignPSS;
+ 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;
#ifndef NSS_DISABLE_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;
+ 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_DISABLE_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, HASH_AlgNULL, 0);
- break;
- case CKM_NSS_TLS_PRF_GENERAL_SHA256:
- crv = sftk_TLSPRFInit(context, key, key_type, HASH_AlgSHA256, 0);
- break;
-
- default:
- crv = CKR_MECHANISM_INVALID;
- 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, HASH_AlgNULL, 0);
+ break;
+ case CKM_NSS_TLS_PRF_GENERAL_SHA256:
+ crv = sftk_TLSPRFInit(context, key, key_type, HASH_AlgSHA256, 0);
+ break;
+
+ default:
+ crv = CKR_MECHANISM_INVALID;
+ break;
}
if (crv != CKR_OK) {
- if (info) PORT_Free(info);
+ if (info)
+ PORT_Free(info);
sftk_FreeContext(context);
- sftk_FreeSession(session);
- return crv;
+ 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,
+/* 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)
+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;
@@ -3194,45 +3367,46 @@ CK_RV NSC_Verify(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pData,
CHECK_FORK();
/* make sure we're legal */
- crv = sftk_GetContext(hSession,&context,SFTK_VERIFY,PR_FALSE,&session);
- if (crv != CKR_OK) return crv;
+ 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)))
+ if (CKR_OK == (crv = NSC_VerifyUpdate(hSession, pData, ulDataLen)))
crv = NSC_VerifyFinal(hSession, pSignature, ulSignatureLen);
} else {
- if (SECSuccess != (*context->verify)(context->cipherInfo,pSignature,
+ if (SECSuccess != (*context->verify)(context->cipherInfo, pSignature,
ulSignatureLen, pData, ulDataLen))
crv = sftk_MapCryptError(PORT_GetError());
- sftk_TerminateOp( session, SFTK_VERIFY, context );
+ 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,
+/* 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)
+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,
+/* 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)
+CK_RV
+NSC_VerifyFinal(CK_SESSION_HANDLE hSession,
+ CK_BYTE_PTR pSignature, CK_ULONG ulSignatureLen)
{
SFTKSession *session;
SFTKSessionContext *context;
@@ -3240,34 +3414,33 @@ CK_RV NSC_VerifyFinal(CK_SESSION_HANDLE hSession,
CHECK_FORK();
- if (!pSignature)
- return CKR_ARGUMENTS_BAD;
+ 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;
-
+ 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,
+ 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;
+ /* 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;
+ if (PORT_Memcmp(pSignature, context->macBuf, ulSignatureLen))
+ crv = CKR_SIGNATURE_INVALID;
}
- sftk_TerminateOp( session, SFTK_VERIFY, context );
+ sftk_TerminateOp(session, SFTK_VERIFY, context);
sftk_FreeSession(session);
return crv;
-
}
/*
@@ -3303,11 +3476,12 @@ sftk_RSACheckSignRecoverRaw(NSSLOWKEYPublicKey *key, unsigned char *data,
sig, sigLen);
}
-/* NSC_VerifyRecoverInit initializes a signature verification operation,
- * where the data is recovered from the signature.
+/* 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)
+CK_RV
+NSC_VerifyRecoverInit(CK_SESSION_HANDLE hSession,
+ CK_MECHANISM_PTR pMechanism, CK_OBJECT_HANDLE hKey)
{
SFTKSession *session;
SFTKObject *key;
@@ -3319,56 +3493,58 @@ CK_RV NSC_VerifyRecoverInit(CK_SESSION_HANDLE hSession,
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 (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;
+ 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
- ? sftk_RSACheckSignRecoverRaw : sftk_RSACheckSignRecover);
- context->destroy = sftk_Null;
- break;
- default:
- crv = CKR_MECHANISM_INVALID;
- break;
+ 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
+ ? sftk_RSACheckSignRecoverRaw
+ : sftk_RSACheckSignRecover);
+ context->destroy = sftk_Null;
+ break;
+ default:
+ crv = CKR_MECHANISM_INVALID;
+ break;
}
if (crv != CKR_OK) {
PORT_Free(context);
- sftk_FreeSession(session);
- return crv;
+ 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.
+/* 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)
+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;
@@ -3380,35 +3556,37 @@ CK_RV NSC_VerifyRecover(CK_SESSION_HANDLE hSession,
CHECK_FORK();
/* make sure we're legal */
- crv = sftk_GetContext(hSession,&context,SFTK_VERIFY_RECOVER,
- PR_FALSE,&session);
- if (crv != CKR_OK) return crv;
+ 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;
+ /* 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;
+ 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());
+ return (rv == SECSuccess) ? CKR_OK : sftk_MapVerifyError(PORT_GetError());
}
/*
**************************** Random Functions: ************************
*/
-/* NSC_SeedRandom mixes additional seed material into the token's random number
+/* 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)
+CK_RV
+NSC_SeedRandom(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pSeed,
+ CK_ULONG ulSeedLen)
{
SECStatus rv;
@@ -3419,8 +3597,9 @@ CK_RV NSC_SeedRandom(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pSeed,
}
/* NSC_GenerateRandom generates random data. */
-CK_RV NSC_GenerateRandom(CK_SESSION_HANDLE hSession,
- CK_BYTE_PTR pRandomData, CK_ULONG ulRandomLen)
+CK_RV
+NSC_GenerateRandom(CK_SESSION_HANDLE hSession,
+ CK_BYTE_PTR pRandomData, CK_ULONG ulRandomLen)
{
SECStatus rv;
@@ -3438,35 +3617,35 @@ CK_RV NSC_GenerateRandom(CK_SESSION_HANDLE hSession,
**************************** 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)
+ 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;
+ 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;
+ 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_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;
+ return CKR_HOST_MEMORY;
}
PORT_Memcpy(buf, pbe_key->data, pbe_key->len);
@@ -3476,7 +3655,7 @@ nsc_pbe_key_gen(NSSPKCS5PBEParameter *pkcs5_pbe, CK_MECHANISM_PTR pMechanism,
if (iv.data) {
if (pbe_params && pbe_params->pInitVector != NULL) {
- PORT_Memcpy(pbe_params->pInitVector, iv.data, iv.len);
+ PORT_Memcpy(pbe_params->pInitVector, iv.data, iv.len);
}
PORT_Free(iv.data);
}
@@ -3484,24 +3663,24 @@ nsc_pbe_key_gen(NSSPKCS5PBEParameter *pkcs5_pbe, CK_MECHANISM_PTR pMechanism,
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;
- }
+ 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
@@ -3520,144 +3699,218 @@ nsc_parameter_gen(CK_KEY_TYPE key_type, SFTKObject *key)
attribute = sftk_FindAttribute(key, CKA_PRIME_BITS);
if (attribute == NULL) {
- return CKR_TEMPLATE_INCOMPLETE;
+ attribute = sftk_FindAttribute(key, CKA_PRIME);
+ if (attribute == NULL) {
+ return CKR_TEMPLATE_INCOMPLETE;
+ } else {
+ primeBits = attribute->attrib.ulValueLen;
+ sftk_FreeAttribute(attribute);
+ }
+ } else {
+ primeBits = (unsigned int)*(CK_ULONG *)attribute->attrib.pValue;
+ sftk_FreeAttribute(attribute);
}
- 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;
- }
+ 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);
+ attribute = sftk_FindAttribute(key, CKA_NSS_PQG_SEED_BITS);
if (attribute != NULL) {
- seedBits = (unsigned int) *(CK_ULONG *)attribute->attrib.pValue;
- sftk_FreeAttribute(attribute);
+ 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);
+ subprimeBits = (unsigned int)*(CK_ULONG *)attribute->attrib.pValue;
+ sftk_FreeAttribute(attribute);
+ }
+
+ /* if P and Q are supplied, we want to generate a new G */
+ attribute = sftk_FindAttribute(key, CKA_PRIME);
+ if (attribute != NULL) {
+ PLArenaPool *arena;
+
+ sftk_FreeAttribute(attribute);
+ arena = PORT_NewArena(1024);
+ if (arena == NULL) {
+ crv = CKR_HOST_MEMORY;
+ goto loser;
+ }
+ params = PORT_ArenaAlloc(arena, sizeof(*params));
+ if (params == NULL) {
+ crv = CKR_HOST_MEMORY;
+ goto loser;
+ }
+ params->arena = arena;
+ crv = sftk_Attribute2SSecItem(arena, &params->prime, key, CKA_PRIME);
+ if (crv != CKR_OK) {
+ goto loser;
+ }
+ crv = sftk_Attribute2SSecItem(arena, &params->subPrime,
+ key, CKA_SUBPRIME);
+ if (crv != CKR_OK) {
+ goto loser;
+ }
+
+ arena = PORT_NewArena(1024);
+ if (arena == NULL) {
+ crv = CKR_HOST_MEMORY;
+ goto loser;
+ }
+ vfy = PORT_ArenaAlloc(arena, sizeof(*vfy));
+ if (vfy == NULL) {
+ crv = CKR_HOST_MEMORY;
+ goto loser;
+ }
+ vfy->arena = arena;
+ crv = sftk_Attribute2SSecItem(arena, &vfy->seed, key, CKA_NSS_PQG_SEED);
+ if (crv != CKR_OK) {
+ goto loser;
+ }
+ crv = sftk_Attribute2SSecItem(arena, &vfy->h, key, CKA_NSS_PQG_H);
+ if (crv != CKR_OK) {
+ goto loser;
+ }
+ sftk_DeleteAttributeType(key, CKA_PRIME);
+ sftk_DeleteAttributeType(key, CKA_SUBPRIME);
+ sftk_DeleteAttributeType(key, CKA_NSS_PQG_SEED);
+ sftk_DeleteAttributeType(key, CKA_NSS_PQG_H);
}
- sftk_DeleteAttributeType(key,CKA_PRIME_BITS);
- sftk_DeleteAttributeType(key,CKA_SUBPRIME_BITS);
- sftk_DeleteAttributeType(key,CKA_NETSCAPE_PQG_SEED_BITS);
+ sftk_DeleteAttributeType(key, CKA_PRIME_BITS);
+ sftk_DeleteAttributeType(key, CKA_SUBPRIME_BITS);
+ sftk_DeleteAttributeType(key, CKA_NSS_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);
- }
+ 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 (subprimeBits == 0) {
+ subprimeBits = sftk_GetSubPrimeFromPrime(primeBits);
}
- if (seedBits == 0) {
- seedBits = primeBits;
- }
- rv = PQG_ParamGenV2(primeBits, subprimeBits, seedBits/8, &params, &vfy);
+ 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;
+ 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;
+ crv = sftk_AddAttributeType(key, CKA_NSS_PQG_COUNTER,
+ &counter, sizeof(counter));
+ crv = sftk_AddAttributeType(key, CKA_NSS_PQG_SEED,
+ vfy->seed.data, vfy->seed.len);
+ if (crv != CKR_OK)
+ goto loser;
+ crv = sftk_AddAttributeType(key, CKA_NSS_PQG_H,
+ vfy->h.data, vfy->h.len);
+ if (crv != CKR_OK)
+ goto loser;
loser:
- PQG_DestroyParams(params);
+ if (params) {
+ PQG_DestroyParams(params);
+ }
if (vfy) {
- PQG_DestroyVerify(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_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;
+ 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;
+ 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;
+ 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;
+ case CKM_NSS_CHACHA20_KEY_GEN:
+ *key_type = CKK_NSS_CHACHA20;
+ if (*key_length == 0)
+ crv = CKR_TEMPLATE_INCOMPLETE;
+ break;
+ default:
+ PORT_Assert(0);
+ crv = CKR_MECHANISM_INVALID;
+ break;
}
return crv;
@@ -3666,7 +3919,7 @@ nsc_SetupBulkKeyGen(CK_MECHANISM_TYPE mechanism, CK_KEY_TYPE *key_type,
CK_RV
nsc_SetupHMACKeyGen(CK_MECHANISM_PTR pMechanism, NSSPKCS5PBEParameter **pbe)
{
- SECItem salt;
+ SECItem salt;
CK_PBE_PARAMS *pbe_params = NULL;
NSSPKCS5PBEParameter *params;
PLArenaPool *arena = NULL;
@@ -3676,14 +3929,14 @@ nsc_SetupHMACKeyGen(CK_MECHANISM_PTR pMechanism, NSSPKCS5PBEParameter **pbe)
arena = PORT_NewArena(SEC_ASN1_DEFAULT_ARENA_SIZE);
if (arena == NULL) {
- return CKR_HOST_MEMORY;
+ return CKR_HOST_MEMORY;
}
- params = (NSSPKCS5PBEParameter *) PORT_ArenaZAlloc(arena,
- sizeof(NSSPKCS5PBEParameter));
+ params = (NSSPKCS5PBEParameter *)PORT_ArenaZAlloc(arena,
+ sizeof(NSSPKCS5PBEParameter));
if (params == NULL) {
- PORT_FreeArena(arena,PR_TRUE);
- return CKR_HOST_MEMORY;
+ PORT_FreeArena(arena, PR_TRUE);
+ return CKR_HOST_MEMORY;
}
params->poolp = arena;
@@ -3699,28 +3952,28 @@ nsc_SetupHMACKeyGen(CK_MECHANISM_PTR pMechanism, NSSPKCS5PBEParameter **pbe)
salt.data = (unsigned char *)pbe_params->pSalt;
salt.len = (unsigned int)pbe_params->ulSaltLen;
salt.type = siBuffer;
- rv = SECITEM_CopyItem(arena,&params->salt,&salt);
+ rv = SECITEM_CopyItem(arena, &params->salt, &salt);
if (rv != SECSuccess) {
- PORT_FreeArena(arena,PR_TRUE);
- return CKR_HOST_MEMORY;
+ 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;
+ 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;
@@ -3728,13 +3981,14 @@ nsc_SetupHMACKeyGen(CK_MECHANISM_PTR pMechanism, NSSPKCS5PBEParameter **pbe)
/* 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)
+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;
+ HASH_HashType hashType = HASH_AlgSHA1;
CK_PKCS5_PBKD2_PARAMS *pbkd2_params = NULL;
SECItem salt;
CK_ULONG iteration = 0;
@@ -3743,85 +3997,100 @@ nsc_SetupPBEKeyGen(CK_MECHANISM_PTR pMechanism, NSSPKCS5PBEParameter **pbe,
oid = SECOID_FindOIDByMechanism(pMechanism->mechanism);
if (oid == NULL) {
- return CKR_MECHANISM_INVALID;
+ 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;
+ pbkd2_params = (CK_PKCS5_PBKD2_PARAMS *)pMechanism->pParameter;
+ if (pbkd2_params == NULL) {
+ return CKR_MECHANISM_PARAM_INVALID;
+ }
+ switch (pbkd2_params->prf) {
+ case CKP_PKCS5_PBKD2_HMAC_SHA1:
+ hashType = HASH_AlgSHA1;
+ break;
+ case CKP_PKCS5_PBKD2_HMAC_SHA224:
+ hashType = HASH_AlgSHA224;
+ break;
+ case CKP_PKCS5_PBKD2_HMAC_SHA256:
+ hashType = HASH_AlgSHA256;
+ break;
+ case CKP_PKCS5_PBKD2_HMAC_SHA384:
+ hashType = HASH_AlgSHA384;
+ break;
+ case CKP_PKCS5_PBKD2_HMAC_SHA512:
+ hashType = HASH_AlgSHA512;
+ break;
+ default:
+ return CKR_MECHANISM_PARAM_INVALID;
+ }
+ 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;
+ 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);
+ params = nsspkcs5_NewParam(oid->offset, hashType, &salt, iteration);
if (params == NULL) {
- return CKR_MECHANISM_INVALID;
+ 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;
+ 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:
+ /* 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;
+ *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)
+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;
@@ -3834,12 +4103,16 @@ CK_RV NSC_GenerateKey(CK_SESSION_HANDLE hSession,
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;
+ 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
+ /* 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;
@@ -3855,206 +4128,232 @@ CK_RV NSC_GenerateKey(CK_SESSION_HANDLE hSession,
*/
key = sftk_NewObject(slot); /* fill in the handle later */
if (key == NULL) {
- return CKR_HOST_MEMORY;
+ 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;
+ 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;
+ 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);
+ 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_CDMF_KEY_GEN:
+ case CKM_DES_KEY_GEN:
+ case CKM_DES2_KEY_GEN:
+ case CKM_DES3_KEY_GEN:
+ checkWeak = PR_TRUE;
/* fall through */
- 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:
+ 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:
+ case CKM_NSS_CHACHA20_KEY_GEN:
#if NSS_SOFTOKEN_DOES_RC5
- case CKM_RC5_KEY_GEN:
+ 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;
+ 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;
/* fall through */
- 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;
+ 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;
- }
- if (sftk_isTrue(key, CKA_TOKEN)) {
- crv = CKR_TEMPLATE_INCONSISTENT;
+ 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;
+ break;
+ }
+ crv = CKR_OK;
+ break;
+ default:
+ crv = CKR_MECHANISM_INVALID;
break;
- }
- 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... */
+ /* 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 (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 );
+ 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;
+ 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; }
+ 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; }
+ 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; }
+ 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);
+ sftk_FreeObject(key);
return CKR_SESSION_HANDLE_INVALID;
}
/*
* handle the base object stuff
*/
- crv = sftk_handleObject(key,session);
+ 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 (crv == CKR_OK && sftk_isTrue(key, CKA_SENSITIVE)) {
+ crv = 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));
+ if (crv == CKR_OK && !sftk_isTrue(key, CKA_EXTRACTABLE)) {
+ crv = sftk_forceAttribute(key, CKA_NEVER_EXTRACTABLE, &cktrue, sizeof(CK_BBOOL));
+ }
+ if (crv == CKR_OK) {
+ *phKey = key->handle;
}
-
- *phKey = key->handle;
sftk_FreeObject(key);
return crv;
}
-#define PAIRWISE_DIGEST_LENGTH SHA1_LENGTH /* 160-bits */
-#define PAIRWISE_MESSAGE_LENGTH 20 /* 160-bits */
+#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.
@@ -4067,7 +4366,7 @@ jpake1:
*/
static CK_RV
sftk_PairwiseConsistencyCheck(CK_SESSION_HANDLE hSession,
- SFTKObject *publicKey, SFTKObject *privateKey, CK_KEY_TYPE keyType)
+ SFTKObject *publicKey, SFTKObject *privateKey, CK_KEY_TYPE keyType)
{
/*
* Key type Mechanism type
@@ -4082,7 +4381,7 @@ sftk_PairwiseConsistencyCheck(CK_SESSION_HANDLE hSession,
*
* None of these mechanisms has a parameter.
*/
- CK_MECHANISM mech = {0, NULL, 0};
+ CK_MECHANISM mech = { 0, NULL, 0 };
CK_ULONG modulusLen = 0;
CK_ULONG subPrimeLen = 0;
@@ -4103,146 +4402,145 @@ sftk_PairwiseConsistencyCheck(CK_SESSION_HANDLE hSession,
/* 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 *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);
+ 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;
+ 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);
+ /* 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);
+ 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;
- }
+ 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;
+ }
}
/**********************************************/
@@ -4250,75 +4548,83 @@ sftk_PairwiseConsistencyCheck(CK_SESSION_HANDLE hSession,
/**********************************************/
canSignVerify = sftk_isTrue(privateKey, CKA_SIGN);
-
+ /* Unfortunately CKA_SIGN is always true in lg dbs. We have to check the
+ * actual curve to determine if we can do sign/verify. */
+ if (canSignVerify && keyType == CKK_EC) {
+ NSSLOWKEYPrivateKey *privKey = sftk_GetPrivKey(privateKey, CKK_EC, &crv);
+ if (privKey && privKey->u.ec.ecParams.name == ECCurve25519) {
+ canSignVerify = PR_FALSE;
+ }
+ }
+
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;
+ /* 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;
#ifndef NSS_DISABLE_ECC
- case CKK_EC:
- signature_length = MAX_ECKEY_LEN * 2;
- mech.mechanism = CKM_ECDSA;
- break;
+ 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;
- }
+ 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;
+ }
}
/**********************************************/
@@ -4326,70 +4632,70 @@ sftk_PairwiseConsistencyCheck(CK_SESSION_HANDLE hSession,
/**********************************************/
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.
- */
+ 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,
+/* 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)
+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);
+ 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;
+ int public_modulus_bits = 0;
+ SECItem pubExp;
+ RSAPrivateKey *rsaPriv;
/* DSA */
- PQGParams pqgParam;
- DHParams dhParam;
- DSAPrivateKey * dsaPriv;
+ PQGParams pqgParam;
+ DHParams dhParam;
+ DSAPrivateKey *dsaPriv;
/* Diffie Hellman */
- DHPrivateKey * dhPriv;
+ DHPrivateKey *dhPriv;
#ifndef NSS_DISABLE_ECC
/* Elliptic Curve Cryptography */
- SECItem ecEncodedParams; /* DER Encoded parameters */
- ECPrivateKey * ecPriv;
- ECParams * ecParams;
+ SECItem ecEncodedParams; /* DER Encoded parameters */
+ ECPrivateKey *ecPriv;
+ ECParams *ecParams;
#endif /* NSS_DISABLE_ECC */
CHECK_FORK();
@@ -4402,435 +4708,462 @@ CK_RV NSC_GenerateKeyPair (CK_SESSION_HANDLE hSession,
*/
publicKey = sftk_NewObject(slot); /* fill in the handle later */
if (publicKey == NULL) {
- return CKR_HOST_MEMORY;
+ 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;
- }
+ 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;
+ 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;
+ 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;
+ 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) {
- continue;
- }
+ for (i = 0; i < (int)ulPrivateKeyAttributeCount; i++) {
+ if (pPrivateKeyTemplate[i].type == CKA_VALUE_BITS) {
+ continue;
+ }
- crv = sftk_AddAttributeType(privateKey,
- sftk_attr_expand(&pPrivateKeyTemplate[i]));
- if (crv != CKR_OK) break;
+ 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_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);
+ 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;
+ 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;
#ifndef NSS_DISABLE_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;
+ 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);
+ if (rv != SECSuccess) {
+ if (PORT_GetError() == SEC_ERROR_LIBRARY_FAILURE) {
+ sftk_fatalError = PR_TRUE;
+ }
+ PORT_FreeArena(ecParams->arena, PR_TRUE);
+ crv = sftk_MapCryptError(PORT_GetError());
+ break;
+ }
+
+ if (PR_GetEnvSecure("NSS_USE_DECODED_CKA_EC_POINT") ||
+ ecParams->fieldID.type == ec_field_plain) {
+ PORT_FreeArena(ecParams->arena, PR_TRUE);
+ crv = sftk_AddAttributeType(publicKey, CKA_EC_POINT,
+ sftk_item_expand(&ecPriv->publicValue));
+ } else {
+ PORT_FreeArena(ecParams->arena, PR_TRUE);
+ 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_DISABLE_ECC */
- default:
- crv = CKR_MECHANISM_INVALID;
+ default:
+ crv = CKR_MECHANISM_INVALID;
}
if (crv != CKR_OK) {
- sftk_FreeObject(privateKey);
- sftk_FreeObject(publicKey);
- return crv;
+ 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... */
+ /* 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;
+ 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;
+ if (session == NULL)
+ crv = CKR_SESSION_HANDLE_INVALID;
} while (0);
if (crv != CKR_OK) {
- sftk_FreeObject(privateKey);
- sftk_FreeObject(publicKey);
- return crv;
+ sftk_FreeObject(privateKey);
+ sftk_FreeObject(publicKey);
+ return crv;
}
/*
* handle the base object cleanup for the public Key
*/
- crv = sftk_handleObject(privateKey,session);
+ crv = sftk_handleObject(privateKey, session);
if (crv != CKR_OK) {
sftk_FreeSession(session);
- sftk_FreeObject(privateKey);
- sftk_FreeObject(publicKey);
- return crv;
+ sftk_FreeObject(privateKey);
+ sftk_FreeObject(publicKey);
+ return crv;
}
/*
@@ -4838,50 +5171,55 @@ ecgn_done:
* If we have any problems, we destroy the public Key we've
* created and linked.
*/
- crv = sftk_handleObject(publicKey,session);
+ 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;
+ 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(privateKey, CKA_SENSITIVE)) {
+ crv = 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 (crv == CKR_OK && sftk_isTrue(publicKey, CKA_SENSITIVE)) {
+ crv = 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 (crv == CKR_OK && !sftk_isTrue(privateKey, CKA_EXTRACTABLE)) {
+ crv = 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));
+ if (crv == CKR_OK && !sftk_isTrue(publicKey, CKA_EXTRACTABLE)) {
+ crv = sftk_forceAttribute(publicKey, CKA_NEVER_EXTRACTABLE,
+ &cktrue, sizeof(CK_BBOOL));
+ }
+
+ if (crv == CKR_OK) {
+ /* Perform FIPS 140-2 pairwise consistency check. */
+ crv = sftk_PairwiseConsistencyCheck(hSession,
+ publicKey, privateKey, key_type);
+ if (crv != CKR_OK) {
+ 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);
+ }
+ }
}
- /* 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;
+ NSC_DestroyObject(hSession, publicKey->handle);
+ sftk_FreeObject(publicKey);
+ NSC_DestroyObject(hSession, privateKey->handle);
+ sftk_FreeObject(privateKey);
+ return crv;
}
*phPrivateKey = privateKey->handle;
@@ -4892,7 +5230,8 @@ ecgn_done:
return CKR_OK;
}
-static SECItem *sftk_PackagePrivateKey(SFTKObject *key, CK_RV *crvp)
+static SECItem *
+sftk_PackagePrivateKey(SFTKObject *key, CK_RV *crvp)
{
NSSLOWKEYPrivateKey *lk = NULL;
NSSLOWKEYPrivateKeyInfo *pki = NULL;
@@ -4909,159 +5248,162 @@ static SECItem *sftk_PackagePrivateKey(SFTKObject *key, CK_RV *crvp)
int savelen;
#endif
- if(!key) {
- *crvp = CKR_KEY_HANDLE_INVALID; /* really can't happen */
- return NULL;
+ 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;
+ 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;
+ if (!lk) {
+ return NULL;
}
- arena = PORT_NewArena(2048); /* XXX different size? */
- if(!arena) {
- *crvp = CKR_HOST_MEMORY;
- rv = SECFailure;
- goto loser;
+ 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 = (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:
+ 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;
+ 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;
#ifndef NSS_DISABLE_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;
+ /* 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;
#ifdef EC_DEBUG
- fordebug = &pki->privateKey;
- SEC_PRINT("sftk_PackagePrivateKey()", "PrivateKey", lk->keyType,
- fordebug);
+ fordebug = &pki->privateKey;
+ SEC_PRINT("sftk_PackagePrivateKey()", "PrivateKey", lk->keyType,
+ fordebug);
#endif
- param = SECITEM_DupItem(&lk->u.ec.ecParams.DEREncoding);
+ param = SECITEM_DupItem(&lk->u.ec.ecParams.DEREncoding);
- algorithm = SEC_OID_ANSIX962_EC_PUBLIC_KEY;
- break;
+ algorithm = SEC_OID_ANSIX962_EC_PUBLIC_KEY;
+ break;
#endif /* NSS_DISABLE_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;
+ 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;
+ 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);
+ encodedKey = SEC_ASN1EncodeItem(NULL, NULL, pki,
+ nsslowkey_PrivateKeyInfoTemplate);
*crvp = encodedKey ? CKR_OK : CKR_DEVICE_ERROR;
#ifdef EC_DEBUG
fordebug = encodedKey;
SEC_PRINT("sftk_PackagePrivateKey()", "PrivateKeyInfo", lk->keyType,
- fordebug);
+ fordebug);
#endif
loser:
- if(arena) {
- PORT_FreeArena(arena, PR_TRUE);
+ if (arena) {
+ PORT_FreeArena(arena, PR_TRUE);
}
- if(lk && (lk != key->objectInfo)) {
- nsslowkey_DestroyPrivateKey(lk);
+ if (lk && (lk != key->objectInfo)) {
+ nsslowkey_DestroyPrivateKey(lk);
}
-
- if(param) {
- SECITEM_ZfreeItem((SECItem*)param, PR_TRUE);
+
+ if (param) {
+ SECITEM_ZfreeItem((SECItem *)param, PR_TRUE);
}
- if(rv != SECSuccess) {
- return NULL;
+ 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)
-{
+static CK_RV
+sftk_mapWrap(CK_RV crv)
+{
switch (crv) {
- case CKR_ENCRYPTED_DATA_INVALID: crv = CKR_WRAPPED_KEY_INVALID; break;
+ case CKR_ENCRYPTED_DATA_INVALID:
+ crv = CKR_WRAPPED_KEY_INVALID;
+ break;
}
- return crv;
+ 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)
+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;
@@ -5072,117 +5414,115 @@ CK_RV NSC_WrapKey(CK_SESSION_HANDLE hSession,
session = sftk_SessionFromHandle(hSession);
if (session == NULL) {
- return CKR_SESSION_HANDLE_INVALID;
+ return CKR_SESSION_HANDLE_INVALID;
}
- key = sftk_ObjectFromHandle(hKey,session);
+ 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;
+ 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);
@@ -5195,7 +5535,7 @@ CK_RV NSC_WrapKey(CK_SESSION_HANDLE hSession,
static SECStatus
sftk_unwrapPrivateKey(SFTKObject *key, SECItem *bpki)
{
- CK_BBOOL cktrue = CK_TRUE;
+ CK_BBOOL cktrue = CK_TRUE;
CK_KEY_TYPE keyType = CKK_RSA;
SECStatus rv = SECFailure;
const SEC_ASN1Template *keyTemplate, *paramTemplate;
@@ -5206,66 +5546,65 @@ sftk_unwrapPrivateKey(SFTKObject *key, SECItem *bpki)
CK_RV crv = CKR_KEY_TYPE_INCONSISTENT;
arena = PORT_NewArena(2048);
- if(!arena) {
- return SECFailure;
+ if (!arena) {
+ return SECFailure;
}
- pki = (NSSLOWKEYPrivateKeyInfo*)PORT_ArenaZAlloc(arena,
- sizeof(NSSLOWKEYPrivateKeyInfo));
- if(!pki) {
- PORT_FreeArena(arena, PR_FALSE);
- 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;
+ 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;
+ 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: */
+ 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: */
#ifndef NSS_DISABLE_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;
+ 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_DISABLE_ECC */
- default:
- keyTemplate = NULL;
- paramTemplate = NULL;
- paramDest = NULL;
- break;
+ default:
+ keyTemplate = NULL;
+ paramTemplate = NULL;
+ paramDest = NULL;
+ break;
}
- if(!keyTemplate) {
- goto loser;
+ if (!keyTemplate) {
+ goto loser;
}
/* decode the private key and any algorithm parameters */
@@ -5274,165 +5613,190 @@ sftk_unwrapPrivateKey(SFTKObject *key, SECItem *bpki)
#ifndef NSS_DISABLE_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;
- }
+ 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_DISABLE_ECC */
- if(rv != SECSuccess) {
- goto loser;
+ if (rv != SECSuccess) {
+ goto loser;
}
- if(paramDest && paramTemplate) {
- rv = SEC_QuickDERDecodeItem(arena, paramDest, paramTemplate,
- &(pki->algorithm.parameters));
- 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;
+ 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;
+ 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;
+ template = dhTemplate;
+ templateCount = sizeof(dhTemplate) / sizeof(CK_ATTRIBUTE);
+ keyType = CKK_DH;
+ break;
#endif
- /* what about fortezza??? */
+/* what about fortezza??? */
#ifndef NSS_DISABLE_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;
+ 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_DISABLE_ECC */
- default:
- crv = CKR_KEY_TYPE_INCONSISTENT;
- break;
+ default:
+ crv = CKR_KEY_TYPE_INCONSISTENT;
+ break;
}
loser:
- if(lpk) {
- nsslowkey_DestroyPrivateKey(lpk);
+ if (lpk) {
+ nsslowkey_DestroyPrivateKey(lpk);
}
- if(crv != CKR_OK) {
- return SECFailure;
+ 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)
+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;
+ unsigned char *buf = NULL;
CK_RV crv = CKR_OK;
int i;
CK_ULONG bsize = ulWrappedKeyLen;
@@ -5450,99 +5814,102 @@ CK_RV NSC_UnwrapKey(CK_SESSION_HANDLE hSession,
*/
key = sftk_NewObject(slot); /* fill in the handle later */
if (key == NULL) {
- return CKR_HOST_MEMORY;
+ 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;
- }
+ 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;
+ 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;
+ sftk_FreeObject(key);
+ return crv;
}
- crv = sftk_CryptInit(hSession,pMechanism,hUnwrappingKey,CKA_UNWRAP,
- CKA_UNWRAP, SFTK_DECRYPT, PR_FALSE);
+ 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);
+ sftk_FreeObject(key);
+ return sftk_mapWrap(crv);
}
- /* allocate the buffer to decrypt into
+ /* 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);
+ 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;
+ 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; }
+ if (crv != CKR_OK) {
+ sftk_FreeObject(key);
+ return crv;
+ }
/* get the session */
session = sftk_SessionFromHandle(hSession);
if (session == NULL) {
- sftk_FreeObject(key);
+ sftk_FreeObject(key);
return CKR_SESSION_HANDLE_INVALID;
}
/*
* handle the base object stuff
*/
- crv = sftk_handleObject(key,session);
+ crv = sftk_handleObject(key, session);
*phKey = key->handle;
sftk_FreeSession(session);
sftk_FreeObject(key);
return crv;
-
}
/*
@@ -5550,9 +5917,9 @@ CK_RV NSC_UnwrapKey(CK_SESSION_HANDLE hSession,
* 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)
+sftk_buildSSLKey(CK_SESSION_HANDLE hSession, SFTKObject *baseKey,
+ PRBool isMacKey, unsigned char *keyBlock, unsigned int keySize,
+ CK_OBJECT_HANDLE *keyHandle)
{
SFTKObject *key;
SFTKSession *session;
@@ -5565,43 +5932,57 @@ sftk_buildSSLKey(CK_SESSION_HANDLE hSession, SFTKObject *baseKey,
* 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;
+ 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;
+ 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;
+ 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; }
+ if (session == NULL) {
+ goto loser;
+ }
- crv = sftk_handleObject(key,session);
+ crv = sftk_handleObject(key, session);
sftk_FreeSession(session);
*keyHandle = key->handle;
loser:
- if (key) sftk_FreeObject(key);
+ if (key)
+ sftk_FreeObject(key);
return crv;
}
@@ -5611,20 +5992,20 @@ loser:
*/
static void
sftk_freeSSLKeys(CK_SESSION_HANDLE session,
- CK_SSL3_KEY_MAT_OUT *returnedMaterial )
+ 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);
- }
+ 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);
+ }
}
/*
@@ -5633,7 +6014,7 @@ sftk_freeSSLKeys(CK_SESSION_HANDLE session,
* semantics.
*/
static CK_RV
-sftk_DeriveSensitiveCheck(SFTKObject *baseKey,SFTKObject *destKey)
+sftk_DeriveSensitiveCheck(SFTKObject *baseKey, SFTKObject *destKey)
{
PRBool hasSensitive;
PRBool sensitive = PR_FALSE;
@@ -5643,46 +6024,49 @@ sftk_DeriveSensitiveCheck(SFTKObject *baseKey,SFTKObject *destKey)
SFTKAttribute *att;
hasSensitive = PR_FALSE;
- att = sftk_FindAttribute(destKey,CKA_SENSITIVE);
+ att = sftk_FindAttribute(destKey, CKA_SENSITIVE);
if (att) {
hasSensitive = PR_TRUE;
- sensitive = (PRBool) *(CK_BBOOL *)att->attrib.pValue;
- sftk_FreeAttribute(att);
+ sensitive = (PRBool) * (CK_BBOOL *)att->attrib.pValue;
+ sftk_FreeAttribute(att);
}
hasExtractable = PR_FALSE;
- att = sftk_FindAttribute(destKey,CKA_EXTRACTABLE);
+ att = sftk_FindAttribute(destKey, CKA_EXTRACTABLE);
if (att) {
hasExtractable = PR_TRUE;
- extractable = (PRBool) *(CK_BBOOL *)att->attrib.pValue;
- sftk_FreeAttribute(att);
+ 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_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;
+ 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;
+ 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;
+ 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,
@@ -5693,22 +6077,22 @@ sftk_DeriveSensitiveCheck(SFTKObject *baseKey,SFTKObject *destKey)
/*
* make known fixed PKCS #11 key types to their sizes in bytes
- */
+ */
unsigned long
-sftk_MapKeySize(CK_KEY_TYPE keyType)
+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;
+ 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;
}
@@ -5724,10 +6108,11 @@ sftk_MapKeySize(CK_KEY_TYPE keyType)
* 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 *, PRUint32),
- CK_ULONG HashLen)
+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 *, PRUint32),
+ CK_ULONG HashLen)
{
unsigned char *buffer = NULL, *output_buffer = NULL;
PRUint32 buffer_len, max_counter, i;
@@ -5738,26 +6123,26 @@ static CK_RV sftk_compute_ANSI_X9_63_kdf(CK_BYTE **key, CK_ULONG key_len, SECIte
* 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 CKR_ARGUMENTS_BAD;
+ return CKR_ARGUMENTS_BAD;
if (SharedInfo == NULL)
- SharedInfoLen = 0;
+ SharedInfoLen = 0;
buffer_len = SharedSecret->len + 4 + SharedInfoLen;
buffer = (CK_BYTE *)PORT_Alloc(buffer_len);
if (buffer == NULL) {
- crv = CKR_HOST_MEMORY;
- goto loser;
+ crv = CKR_HOST_MEMORY;
+ goto loser;
}
- max_counter = key_len/HashLen;
+ max_counter = key_len / HashLen;
if (key_len > max_counter * HashLen)
- max_counter++;
+ max_counter++;
output_buffer = (CK_BYTE *)PORT_Alloc(max_counter * HashLen);
if (output_buffer == NULL) {
- crv = CKR_HOST_MEMORY;
- goto loser;
+ crv = CKR_HOST_MEMORY;
+ goto loser;
}
/* Populate buffer with SharedSecret || Counter || [SharedInfo]
@@ -5768,61 +6153,62 @@ static CK_RV sftk_compute_ANSI_X9_63_kdf(CK_BYTE **key, CK_ULONG key_len, SECIte
buffer[SharedSecret->len + 2] = 0;
buffer[SharedSecret->len + 3] = 1;
if (SharedInfo) {
- PORT_Memcpy(&buffer[SharedSecret->len + 4], SharedInfo, SharedInfoLen);
+ 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) {
- /* 'Hash' should not fail. */
- crv = CKR_FUNCTION_FAILED;
- goto loser;
- }
+ for (i = 0; i < max_counter; i++) {
+ rv = Hash(&output_buffer[i * HashLen], buffer, buffer_len);
+ if (rv != SECSuccess) {
+ /* 'Hash' should not fail. */
+ crv = CKR_FUNCTION_FAILED;
+ goto loser;
+ }
- /* Increment counter (assumes max_counter < 255) */
- buffer[SharedSecret->len + 3]++;
+ /* 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);
+ PORT_Memset(output_buffer + key_len, 0, max_counter * HashLen - key_len);
}
*key = output_buffer;
return CKR_OK;
- loser:
- if (buffer) {
- PORT_ZFree(buffer, buffer_len);
- }
- if (output_buffer) {
- PORT_ZFree(output_buffer, max_counter * HashLen);
- }
- return crv;
+loser:
+ if (buffer) {
+ PORT_ZFree(buffer, buffer_len);
+ }
+ if (output_buffer) {
+ PORT_ZFree(output_buffer, max_counter * HashLen);
+ }
+ return crv;
}
-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)
+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);
+ 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);
+ 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);
+ 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);
+ 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);
+ return sftk_compute_ANSI_X9_63_kdf(key, key_len, SharedSecret, SharedInfo,
+ SharedInfoLen, SHA512_HashBuf, SHA512_LENGTH);
else
- return CKR_MECHANISM_INVALID;
+ return CKR_MECHANISM_INVALID;
}
#endif /* NSS_DISABLE_ECC */
@@ -5830,59 +6216,59 @@ static CK_RV sftk_ANSI_X9_63_kdf(CK_BYTE **key, CK_ULONG key_len,
* SSL Key generation given pre master secret
*/
#define NUM_MIXERS 9
-static const char * const mixers[NUM_MIXERS] = {
- "A",
- "BB",
- "CCC",
- "DDDD",
- "EEEEE",
- "FFFFFF",
+static const char *const mixers[NUM_MIXERS] = {
+ "A",
+ "BB",
+ "CCC",
+ "DDDD",
+ "EEEEE",
+ "FFFFFF",
"GGGGGGG",
"HHHHHHHH",
- "IIIIIIIII" };
+ "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)
+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;
+ 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;
CK_MECHANISM_TYPE mechanism = pMechanism->mechanism;
- PRBool isTLS = PR_FALSE;
- PRBool isDH = PR_FALSE;
- HASH_HashType tlsPrfHash = HASH_AlgNULL;
- 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;
+ PRBool isTLS = PR_FALSE;
+ PRBool isDH = PR_FALSE;
+ HASH_HashType tlsPrfHash = HASH_AlgNULL;
+ SECStatus rv;
+ int i;
+ unsigned int outLen;
+ unsigned char sha_out[SHA1_LENGTH];
+ unsigned char key_block[NUM_MIXERS * SFTK_MAX_MAC_LENGTH];
+ PRBool isFIPS;
+ HASH_HashType hashType;
+ PRBool extractValue = PR_TRUE;
CHECK_FORK();
@@ -5892,75 +6278,80 @@ CK_RV NSC_DeriveKey( CK_SESSION_HANDLE hSession,
/*
* now lets create an object to hang the attributes off of
*/
- if (phKey) *phKey = CK_INVALID_HANDLE;
+ if (phKey)
+ *phKey = CK_INVALID_HANDLE;
key = sftk_NewObject(slot); /* fill in the handle later */
if (key == NULL) {
- return CKR_HOST_MEMORY;
+ 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;
+ 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 (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 (crv != CKR_OK) { sftk_FreeObject(key); return crv; }
if (keySize == 0) {
- keySize = sftk_MapKeySize(keyType);
+ keySize = sftk_MapKeySize(keyType);
}
switch (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));
+ 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;
+ sftk_FreeObject(key);
+ return crv;
}
- /* look up the base key we're deriving with */
+ /* look up the base key we're deriving with */
session = sftk_SessionFromHandle(hSession);
if (session == NULL) {
- sftk_FreeObject(key);
+ sftk_FreeObject(key);
return CKR_SESSION_HANDLE_INVALID;
}
- sourceKey = sftk_ObjectFromHandle(hBaseKey,session);
+ sourceKey = sftk_ObjectFromHandle(hBaseKey, session);
sftk_FreeSession(session);
if (sourceKey == NULL) {
- sftk_FreeObject(key);
+ sftk_FreeObject(key);
return CKR_KEY_HANDLE_INVALID;
}
if (extractValue) {
/* get the value of the base key */
- att = sftk_FindAttribute(sourceKey,CKA_VALUE);
+ att = sftk_FindAttribute(sourceKey, CKA_VALUE);
if (att == NULL) {
sftk_FreeObject(key);
sftk_FreeObject(sourceKey);
@@ -5969,1283 +6360,1197 @@ CK_RV NSC_DeriveKey( CK_SESSION_HANDLE hSession,
}
switch (mechanism) {
- /*
- * generate the master secret
- */
- case CKM_TLS12_MASTER_KEY_DERIVE:
- case CKM_TLS12_MASTER_KEY_DERIVE_DH:
- case CKM_NSS_TLS_MASTER_KEY_DERIVE_SHA256:
- case CKM_NSS_TLS_MASTER_KEY_DERIVE_DH_SHA256:
- case CKM_TLS_MASTER_KEY_DERIVE:
- case CKM_TLS_MASTER_KEY_DERIVE_DH:
- 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 ((mechanism == CKM_TLS12_MASTER_KEY_DERIVE) ||
- (mechanism == CKM_TLS12_MASTER_KEY_DERIVE_DH)) {
- CK_TLS12_MASTER_KEY_DERIVE_PARAMS *tls12_master =
- (CK_TLS12_MASTER_KEY_DERIVE_PARAMS *) pMechanism->pParameter;
- tlsPrfHash = GetHashTypeFromMechanism(tls12_master->prfHashMechanism);
- if (tlsPrfHash == HASH_AlgNULL) {
- crv = CKR_MECHANISM_PARAM_INVALID;
- break;
- }
- } else if ((mechanism == CKM_NSS_TLS_MASTER_KEY_DERIVE_SHA256) ||
- (mechanism == CKM_NSS_TLS_MASTER_KEY_DERIVE_DH_SHA256)) {
- tlsPrfHash = HASH_AlgSHA256;
- }
-
- if ((mechanism != CKM_SSL3_MASTER_KEY_DERIVE) &&
- (mechanism != CKM_SSL3_MASTER_KEY_DERIVE_DH)) {
- isTLS = PR_TRUE;
- }
- if ((mechanism == CKM_SSL3_MASTER_KEY_DERIVE_DH) ||
- (mechanism == CKM_TLS_MASTER_KEY_DERIVE_DH) ||
- (mechanism == CKM_NSS_TLS_MASTER_KEY_DERIVE_DH_SHA256) ||
- (mechanism == CKM_TLS12_MASTER_KEY_DERIVE_DH)) {
- isDH = PR_TRUE;
- }
-
- /* first do the consistency 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;
-
- if (tlsPrfHash != HASH_AlgNULL) {
- status = TLS_P_hash(tlsPrfHash, &pms, "master secret",
- &crsr, &master, isFIPS);
- } else {
- 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;
- }
-
- /* Extended master key derivation [draft-ietf-tls-session-hash] */
- case CKM_NSS_TLS_EXTENDED_MASTER_KEY_DERIVE:
- case CKM_NSS_TLS_EXTENDED_MASTER_KEY_DERIVE_DH:
- {
- CK_NSS_TLS_EXTENDED_MASTER_KEY_DERIVE_PARAMS *ems_params;
- SSL3RSAPreMasterSecret *rsa_pms;
- SECStatus status;
- SECItem pms = { siBuffer, NULL, 0 };
- SECItem seed = { siBuffer, NULL, 0 };
- SECItem master = { siBuffer, NULL, 0 };
-
- ems_params = (CK_NSS_TLS_EXTENDED_MASTER_KEY_DERIVE_PARAMS*)
- pMechanism->pParameter;
-
- /* First do the consistency checks */
- if ((mechanism == CKM_NSS_TLS_EXTENDED_MASTER_KEY_DERIVE) &&
- (att->attrib.ulValueLen != SSL3_PMS_LENGTH)) {
- crv = CKR_KEY_TYPE_INCONSISTENT;
+ /*
+ * generate the master secret
+ */
+ case CKM_TLS12_MASTER_KEY_DERIVE:
+ case CKM_TLS12_MASTER_KEY_DERIVE_DH:
+ case CKM_NSS_TLS_MASTER_KEY_DERIVE_SHA256:
+ case CKM_NSS_TLS_MASTER_KEY_DERIVE_DH_SHA256:
+ case CKM_TLS_MASTER_KEY_DERIVE:
+ case CKM_TLS_MASTER_KEY_DERIVE_DH:
+ 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 ((mechanism == CKM_TLS12_MASTER_KEY_DERIVE) ||
+ (mechanism == CKM_TLS12_MASTER_KEY_DERIVE_DH)) {
+ CK_TLS12_MASTER_KEY_DERIVE_PARAMS *tls12_master =
+ (CK_TLS12_MASTER_KEY_DERIVE_PARAMS *)pMechanism->pParameter;
+ tlsPrfHash = GetHashTypeFromMechanism(tls12_master->prfHashMechanism);
+ if (tlsPrfHash == HASH_AlgNULL) {
+ crv = CKR_MECHANISM_PARAM_INVALID;
+ break;
+ }
+ } else if ((mechanism == CKM_NSS_TLS_MASTER_KEY_DERIVE_SHA256) ||
+ (mechanism == CKM_NSS_TLS_MASTER_KEY_DERIVE_DH_SHA256)) {
+ tlsPrfHash = HASH_AlgSHA256;
+ }
+
+ if ((mechanism != CKM_SSL3_MASTER_KEY_DERIVE) &&
+ (mechanism != CKM_SSL3_MASTER_KEY_DERIVE_DH)) {
+ isTLS = PR_TRUE;
+ }
+ if ((mechanism == CKM_SSL3_MASTER_KEY_DERIVE_DH) ||
+ (mechanism == CKM_TLS_MASTER_KEY_DERIVE_DH) ||
+ (mechanism == CKM_NSS_TLS_MASTER_KEY_DERIVE_DH_SHA256) ||
+ (mechanism == CKM_TLS12_MASTER_KEY_DERIVE_DH)) {
+ isDH = PR_TRUE;
+ }
+
+ /* first do the consistency 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;
+
+ if (tlsPrfHash != HASH_AlgNULL) {
+ status = TLS_P_hash(tlsPrfHash, &pms, "master secret",
+ &crsr, &master, isFIPS);
+ } else {
+ 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;
}
- 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;
+
+ /* Extended master key derivation [draft-ietf-tls-session-hash] */
+ case CKM_NSS_TLS_EXTENDED_MASTER_KEY_DERIVE:
+ case CKM_NSS_TLS_EXTENDED_MASTER_KEY_DERIVE_DH: {
+ CK_NSS_TLS_EXTENDED_MASTER_KEY_DERIVE_PARAMS *ems_params;
+ SSL3RSAPreMasterSecret *rsa_pms;
+ SECStatus status;
+ SECItem pms = { siBuffer, NULL, 0 };
+ SECItem seed = { siBuffer, NULL, 0 };
+ SECItem master = { siBuffer, NULL, 0 };
+
+ ems_params = (CK_NSS_TLS_EXTENDED_MASTER_KEY_DERIVE_PARAMS *)
+ pMechanism->pParameter;
+
+ /* First do the consistency checks */
+ if ((mechanism == CKM_NSS_TLS_EXTENDED_MASTER_KEY_DERIVE) &&
+ (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;
+ }
+
+ /* Do the key derivation */
+ pms.data = (unsigned char *)att->attrib.pValue;
+ pms.len = att->attrib.ulValueLen;
+ seed.data = ems_params->pSessionHash;
+ seed.len = ems_params->ulSessionHashLen;
+ master.data = key_block;
+ master.len = SSL3_MASTER_SECRET_LENGTH;
+ if (ems_params->prfHashMechanism == CKM_TLS_PRF) {
+ /*
+ * In this case, the session hash is the concatenation of SHA-1
+ * and MD5, so it should be 36 bytes long.
+ */
+ if (seed.len != MD5_LENGTH + SHA1_LENGTH) {
+ crv = CKR_TEMPLATE_INCONSISTENT;
+ break;
+ }
+
+ status = TLS_PRF(&pms, "extended master secret",
+ &seed, &master, isFIPS);
+ } else {
+ const SECHashObject *hashObj;
+
+ tlsPrfHash = GetHashTypeFromMechanism(ems_params->prfHashMechanism);
+ if (tlsPrfHash == HASH_AlgNULL) {
+ crv = CKR_MECHANISM_PARAM_INVALID;
+ break;
+ }
+
+ hashObj = HASH_GetRawHashObject(tlsPrfHash);
+ if (seed.len != hashObj->length) {
+ crv = CKR_TEMPLATE_INCONSISTENT;
+ break;
+ }
+
+ status = TLS_P_hash(tlsPrfHash, &pms, "extended master secret",
+ &seed, &master, isFIPS);
+ }
+ if (status != SECSuccess) {
+ crv = CKR_FUNCTION_FAILED;
+ break;
+ }
+
+ /* Reflect the version if required */
+ if (ems_params->pVersion) {
+ SFTKSessionObject *sessKey = sftk_narrowToSessionObject(key);
+ rsa_pms = (SSL3RSAPreMasterSecret *)att->attrib.pValue;
+ /* don't leak more key material than necessary for SSL to work */
+ if ((sessKey == NULL) || sessKey->wasDerived) {
+ ems_params->pVersion->major = 0xff;
+ ems_params->pVersion->minor = 0xff;
+ } else {
+ ems_params->pVersion->major = rsa_pms->client_version[0];
+ ems_params->pVersion->minor = rsa_pms->client_version[1];
+ }
+ }
+
+ /* Store the results */
+ crv = sftk_forceAttribute(key, CKA_VALUE, key_block,
+ SSL3_MASTER_SECRET_LENGTH);
break;
}
- sftk_FreeAttribute(att2);
- if (keyType != CKK_GENERIC_SECRET) {
- crv = CKR_KEY_FUNCTION_NOT_PERMITTED;
+
+ case CKM_TLS12_KEY_AND_MAC_DERIVE:
+ case CKM_NSS_TLS_KEY_AND_MAC_DERIVE_SHA256:
+ case CKM_TLS_KEY_AND_MAC_DERIVE:
+ 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];
+
+ if (mechanism == CKM_TLS12_KEY_AND_MAC_DERIVE) {
+ CK_TLS12_KEY_MAT_PARAMS *tls12_keys =
+ (CK_TLS12_KEY_MAT_PARAMS *)pMechanism->pParameter;
+ tlsPrfHash = GetHashTypeFromMechanism(tls12_keys->prfHashMechanism);
+ if (tlsPrfHash == HASH_AlgNULL) {
+ crv = CKR_MECHANISM_PARAM_INVALID;
+ break;
+ }
+ } else if (mechanism == CKM_NSS_TLS_KEY_AND_MAC_DERIVE_SHA256) {
+ tlsPrfHash = HASH_AlgSHA256;
+ }
+
+ if (mechanism != CKM_SSL3_KEY_AND_MAC_DERIVE) {
+ isTLS = PR_TRUE;
+ }
+
+ 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) {
+ MD5_DestroyContext(md5, PR_TRUE);
+ 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;
+ }
+
+ /* bIsExport must be false. */
+ if (ssl3_keys->bIsExport) {
+ MD5_DestroyContext(md5, PR_TRUE);
+ SHA1_DestroyContext(sha, PR_TRUE);
+ crv = CKR_MECHANISM_PARAM_INVALID;
+ break;
+ }
+
+ block_needed = 2 * (macSize + effKeySize + 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;
+
+ if (tlsPrfHash != HASH_AlgNULL) {
+ status = TLS_P_hash(tlsPrfHash, &master, "key expansion",
+ &srcr, &keyblk, isFIPS);
+ } else {
+ 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) {
+ /*
+ ** 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);
+ }
+
+ 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;
}
- if ((keySize != 0) && (keySize != SSL3_MASTER_SECRET_LENGTH)) {
- crv = CKR_KEY_FUNCTION_NOT_PERMITTED;
+
+ 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;
}
- /* Do the key derivation */
- pms.data = (unsigned char*) att->attrib.pValue;
- pms.len = att->attrib.ulValueLen;
- seed.data = ems_params->pSessionHash;
- seed.len = ems_params->ulSessionHashLen;
- master.data = key_block;
- master.len = SSL3_MASTER_SECRET_LENGTH;
- if (ems_params-> prfHashMechanism == CKM_TLS_PRF) {
- /*
- * In this case, the session hash is the concatenation of SHA-1
- * and MD5, so it should be 36 bytes long.
- */
- if (seed.len != MD5_LENGTH + SHA1_LENGTH) {
+ 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;
+ }
- status = TLS_PRF(&pms, "extended master secret",
- &seed, &master, isFIPS);
- } else {
- const SECHashObject *hashObj;
+ PORT_Memcpy(buf, att->attrib.pValue, att->attrib.ulValueLen);
+ PORT_Memcpy(buf + att->attrib.ulValueLen, stringPtr->pData,
+ stringPtr->ulLen);
- tlsPrfHash = GetHashTypeFromMechanism(ems_params->prfHashMechanism);
- if (tlsPrfHash == HASH_AlgNULL) {
- crv = CKR_MECHANISM_PARAM_INVALID;
+ 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;
}
- hashObj = HASH_GetRawHashObject(tlsPrfHash);
- if (seed.len != hashObj->length) {
+ 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;
+ }
- status = TLS_P_hash(tlsPrfHash, &pms, "extended master secret",
- &seed, &master, isFIPS);
- }
- if (status != SECSuccess) {
- crv = CKR_FUNCTION_FAILED;
+ 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;
- }
- /* Reflect the version if required */
- if (ems_params->pVersion) {
- SFTKSessionObject *sessKey = sftk_narrowToSessionObject(key);
- rsa_pms = (SSL3RSAPreMasterSecret *) att->attrib.pValue;
- /* don't leak more key material than necessary for SSL to work */
- if ((sessKey == NULL) || sessKey->wasDerived) {
- ems_params->pVersion->major = 0xff;
- ems_params->pVersion->minor = 0xff;
- } else {
- ems_params->pVersion->major = rsa_pms->client_version[0];
- ems_params->pVersion->minor = rsa_pms->client_version[1];
+ 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);
- /* Store the results */
- crv = sftk_forceAttribute(key, CKA_VALUE, key_block,
- SSL3_MASTER_SECRET_LENGTH);
- break;
- }
-
- case CKM_TLS12_KEY_AND_MAC_DERIVE:
- case CKM_NSS_TLS_KEY_AND_MAC_DERIVE_SHA256:
- case CKM_TLS_KEY_AND_MAC_DERIVE:
- 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];
-
- if (mechanism == CKM_TLS12_KEY_AND_MAC_DERIVE) {
- CK_TLS12_KEY_MAT_PARAMS *tls12_keys =
- (CK_TLS12_KEY_MAT_PARAMS *) pMechanism->pParameter;
- tlsPrfHash = GetHashTypeFromMechanism(tls12_keys->prfHashMechanism);
- if (tlsPrfHash == HASH_AlgNULL) {
- crv = CKR_MECHANISM_PARAM_INVALID;
- break;
- }
- } else if (mechanism == CKM_NSS_TLS_KEY_AND_MAC_DERIVE_SHA256) {
- tlsPrfHash = HASH_AlgSHA256;
- }
-
- if (mechanism != CKM_SSL3_KEY_AND_MAC_DERIVE) {
- isTLS = PR_TRUE;
- }
-
- 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;
-
- if (tlsPrfHash != HASH_AlgNULL) {
- status = TLS_P_hash(tlsPrfHash, &master, "key expansion",
- &srcr, &keyblk, isFIPS);
- } else {
- 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 1.0 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;
- }
+ 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);
-#ifndef NSS_DISABLE_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;
- unsigned 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 (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;
- crv = sftk_ANSI_X9_63_kdf(&secret, keySize,
- &tmp, mechParams->pSharedData,
- mechParams->ulSharedDataLen, mechParams->kdf);
- PORT_ZFree(tmp.data, tmp.len);
- if (crv != CKR_OK) {
- 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_DISABLE_ECC */
+ 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);
- /* 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;
+ crv = sftk_forceAttribute(key, CKA_VALUE, key_block, keySize);
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;
+ 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;
- }
- if (keySize == 0 || keySize > sizeof key_block ||
- (!params->bExpand && keySize > hashLen) ||
- (params->bExpand && keySize > 255 * hashLen)) {
- crv = CKR_TEMPLATE_INCONSISTENT;
+
+ 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;
- }
- crv = sftk_DeriveSensitiveCheck(sourceKey, key);
- if (crv != CKR_OK)
+
+ 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;
- /* HKDF-Extract(salt, base key value) */
- if (params->bExtract) {
- CK_BYTE * salt;
- CK_ULONG saltLen;
- HMACContext * hmac;
- unsigned int bufLen;
+ 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;
- salt = params->pSalt;
- saltLen = params->ulSaltLen;
- if (salt == NULL) {
- saltLen = hashLen;
- salt = buf;
- memset(salt, 0, saltLen);
+ 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;
}
- hmac = HMAC_Create(rawHash, salt, saltLen, isFIPS);
- if (!hmac) {
+
+ 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;
+ }
+
+#ifndef NSS_DISABLE_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;
+ unsigned int secretlen, 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;
}
- 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;
+
+ privKey = sftk_GetPrivKey(sourceKey, CKK_EC, &crv);
+ if (privKey == NULL) {
break;
}
- for (i = 1; i <= iterations; ++i) {
- unsigned len;
- HMAC_Begin(hmac);
- if (i > 1) {
- HMAC_Update(hmac, key_block + ((i-2) * hashLen), hashLen);
+
+ /* 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;
+
+ pubKeyLen = privKey->u.ec.ecParams.pointSize;
+
+ /* 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;
}
- if (params->ulInfoLen != 0) {
- HMAC_Update(hmac, params->pInfo, params->ulInfoLen);
+
+ rv = SEC_QuickDERDecodeItem(arena, &newPoint,
+ SEC_ASN1_GET(SEC_OctetStringTemplate),
+ &ecPoint);
+ if (rv != SECSuccess) {
+ goto ec_loser;
}
- HMAC_Update(hmac, &i, 1);
- HMAC_Finish(hmac, key_block + ((i-1) * hashLen), &len,
- hashLen);
- PORT_Assert(len == hashLen);
+ ecPoint = newPoint;
}
- HMAC_Destroy(hmac, PR_TRUE);
- okm = key_block;
+
+ if (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;
+ crv = sftk_ANSI_X9_63_kdf(&secret, keySize,
+ &tmp, mechParams->pSharedData,
+ mechParams->ulSharedDataLen, mechParams->kdf);
+ PORT_ZFree(tmp.data, tmp.len);
+ if (crv != CKR_OK) {
+ 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;
}
- /* 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)
+#endif /* NSS_DISABLE_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)
- crv = jpake_Round2(hashType,
- (CK_NSS_JPAKERound2Params *) pMechanism->pParameter,
- sourceKey, key);
- break;
+ if (crv != CKR_OK)
+ 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;
+ /* 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;
+ default:
+ crv = CKR_MECHANISM_INVALID;
}
if (att) {
sftk_FreeAttribute(att);
}
sftk_FreeObject(sourceKey);
- if (crv != CKR_OK) {
- if (key) sftk_FreeObject(key);
- return crv;
+ 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);
+ 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
+/* NSC_GetFunctionStatus obtains an updated status of a function running
* in parallel with an application. */
-CK_RV NSC_GetFunctionStatus(CK_SESSION_HANDLE hSession)
+CK_RV
+NSC_GetFunctionStatus(CK_SESSION_HANDLE hSession)
{
CHECK_FORK();
@@ -7253,20 +7558,22 @@ CK_RV NSC_GetFunctionStatus(CK_SESSION_HANDLE hSession)
}
/* NSC_CancelFunction cancels a function running in parallel */
-CK_RV NSC_CancelFunction(CK_SESSION_HANDLE hSession)
+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.
+/* 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)
+CK_RV
+NSC_GetOperationState(CK_SESSION_HANDLE hSession,
+ CK_BYTE_PTR pOperationState, CK_ULONG_PTR pulOperationStateLen)
{
SFTKSessionContext *context;
SFTKSession *session;
@@ -7277,39 +7584,38 @@ CK_RV NSC_GetOperationState(CK_SESSION_HANDLE hSession,
/* make sure we're legal */
crv = sftk_GetContext(hSession, &context, SFTK_HASH, PR_TRUE, &session);
- if (crv != CKR_OK) return crv;
+ if (crv != CKR_OK)
+ return crv;
- *pulOperationStateLen = context->cipherInfoLen + sizeof(CK_MECHANISM_TYPE)
- + sizeof(SFTKContextType);
+ *pulOperationStateLen = context->cipherInfoLen + sizeof(CK_MECHANISM_TYPE) + sizeof(SFTKContextType);
if (pOperationState == NULL) {
sftk_FreeSession(session);
- return CKR_OK;
+ return CKR_OK;
} else {
- if (pOSLen < *pulOperationStateLen) {
- return CKR_BUFFER_TOO_SMALL;
- }
+ if (pOSLen < *pulOperationStateLen) {
+ return CKR_BUFFER_TOO_SMALL;
+ }
}
- PORT_Memcpy(pOperationState,&context->type,sizeof(SFTKContextType));
+ PORT_Memcpy(pOperationState, &context->type, sizeof(SFTKContextType));
pOperationState += sizeof(SFTKContextType);
- PORT_Memcpy(pOperationState,&context->currentMech,
- sizeof(CK_MECHANISM_TYPE));
+ PORT_Memcpy(pOperationState, &context->currentMech,
+ sizeof(CK_MECHANISM_TYPE));
pOperationState += sizeof(CK_MECHANISM_TYPE);
- PORT_Memcpy(pOperationState,context->cipherInfo,context->cipherInfoLen);
+ 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;
-#define sftk_Decrement(stateSize,len) \
- stateSize = ((stateSize) > (CK_ULONG)(len)) ? \
- ((stateSize) - (CK_ULONG)(len)) : 0;
-
-/* NSC_SetOperationState restores the state of the cryptographic
+/* 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)
+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;
@@ -7320,122 +7626,130 @@ CK_RV NSC_SetOperationState(CK_SESSION_HANDLE hSession,
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;
+ /* 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
+/* 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
+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);
+ 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
+/* 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
+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);
+ 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
+/* 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
+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);
+ 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
+/* 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
+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_DecryptUpdate(hSession, pEncryptedData, ulEncryptedDataLen,
+ pData, pulDataLen);
+ if (crv != CKR_OK)
+ return crv;
crv = NSC_VerifyUpdate(hSession, pData, *pulDataLen);
return crv;
@@ -7444,7 +7758,8 @@ CK_RV NSC_DecryptVerifyUpdate(CK_SESSION_HANDLE hSession,
/* 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)
+CK_RV
+NSC_DigestKey(CK_SESSION_HANDLE hSession, CK_OBJECT_HANDLE hKey)
{
SFTKSession *session = NULL;
SFTKObject *key = NULL;
@@ -7454,27 +7769,29 @@ CK_RV NSC_DigestKey(CK_SESSION_HANDLE hSession, CK_OBJECT_HANDLE hKey)
CHECK_FORK();
session = sftk_SessionFromHandle(hSession);
- if (session == NULL) return CKR_SESSION_HANDLE_INVALID;
+ if (session == NULL)
+ return CKR_SESSION_HANDLE_INVALID;
- key = sftk_ObjectFromHandle(hKey,session);
+ key = sftk_ObjectFromHandle(hKey, session);
sftk_FreeSession(session);
- if (key == NULL) return CKR_KEY_HANDLE_INVALID;
+ 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;
+ sftk_FreeObject(key);
+ return CKR_KEY_TYPE_INCONSISTENT;
}
/* get the key value */
- att = sftk_FindAttribute(key,CKA_VALUE);
+ att = sftk_FindAttribute(key, CKA_VALUE);
sftk_FreeObject(key);
if (!att) {
- return CKR_KEY_HANDLE_INVALID;
+ return CKR_KEY_HANDLE_INVALID;
}
- crv = NSC_DigestUpdate(hSession,(CK_BYTE_PTR)att->attrib.pValue,
- att->attrib.ulValueLen);
+ crv = NSC_DigestUpdate(hSession, (CK_BYTE_PTR)att->attrib.pValue,
+ att->attrib.ulValueLen);
sftk_FreeAttribute(att);
return crv;
}
diff --git a/nss/lib/softoken/pkcs11i.h b/nss/lib/softoken/pkcs11i.h
index 1023a00..c5f21c3 100644
--- a/nss/lib/softoken/pkcs11i.h
+++ b/nss/lib/softoken/pkcs11i.h
@@ -10,14 +10,15 @@
#include "nssilock.h"
#include "seccomon.h"
#include "secoidt.h"
-#include "lowkeyti.h"
+#include "lowkeyti.h"
#include "pkcs11t.h"
-#include "sftkdbt.h"
+#include "sftkdbt.h"
+#include "chacha20poly1305.h"
#include "hasht.h"
-/*
- * Configuration Defines
+/*
+ * 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
@@ -25,24 +26,24 @@
* 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. */
+#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_CERT_BLOCK_SIZE 50
+#define NSC_SEARCH_BLOCK_SIZE 5
#define NSC_SLOT_LIST_BLOCK_SIZE 10
#define NSC_FIPS_MODULE 1
@@ -51,21 +52,21 @@
/* 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
+ * 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_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 */
+#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.
@@ -104,16 +105,17 @@ typedef struct SFTKHashSignInfoStr SFTKHashSignInfo;
typedef struct SFTKOAEPEncryptInfoStr SFTKOAEPEncryptInfo;
typedef struct SFTKOAEPDecryptInfoStr SFTKOAEPDecryptInfo;
typedef struct SFTKSSLMACInfoStr SFTKSSLMACInfo;
+typedef struct SFTKChaCha20Poly1305InfoStr SFTKChaCha20Poly1305Info;
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 *,const void *,unsigned int);
-typedef void (*SFTKEnd)(void *,void *,unsigned int *,unsigned int);
+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 *, const 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.
@@ -123,10 +125,10 @@ typedef void (*SFTKFree)(void *);
* ALWAYS: attribute can always be changed.
*/
typedef enum {
- SFTK_NEVER = 0,
- SFTK_ONCOPY = 1,
- SFTK_SENSITIVE = 2,
- SFTK_ALWAYS = 3
+ SFTK_NEVER = 0,
+ SFTK_ONCOPY = 1,
+ SFTK_SENSITIVE = 2,
+ SFTK_ALWAYS = 3
} SFTKModifyType;
/*
@@ -134,39 +136,38 @@ typedef enum {
* deleting an object.
*/
typedef enum {
- SFTK_DestroyFailure,
- SFTK_Destroyed,
- SFTK_Busy
+ SFTK_DestroyFailure,
+ SFTK_Destroyed,
+ SFTK_Busy
} SFTKFreeStatus;
/*
* attribute values of an object.
*/
struct SFTKAttributeStr {
- SFTKAttribute *next;
- SFTKAttribute *prev;
- PRBool freeAttr;
- PRBool freeData;
+ SFTKAttribute *next;
+ SFTKAttribute *prev;
+ PRBool freeAttr;
+ PRBool freeData;
/*must be called handle to make sftkqueue_find work */
- CK_ATTRIBUTE_TYPE handle;
- CK_ATTRIBUTE attrib;
+ 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;
+ SFTKObject *parent;
};
struct SFTKObjectFreeListStr {
- SFTKObject *head;
- PZLock *lock;
- int count;
+ SFTKObject *head;
+ PZLock *lock;
+ int count;
};
/*
@@ -174,54 +175,53 @@ struct SFTKObjectFreeListStr {
*/
struct SFTKObjectStr {
SFTKObject *next;
- SFTKObject *prev;
- CK_OBJECT_CLASS objclass;
- CK_OBJECT_HANDLE handle;
- int refCount;
- PZLock *refLock;
- SFTKSlot *slot;
- void *objectInfo;
- SFTKFree infoFree;
+ 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;
+ SFTKObject obj;
+ SECItem dbKey;
};
struct SFTKSessionObjectStr {
- SFTKObject obj;
+ SFTKObject obj;
SFTKObjectList sessionList;
- PZLock *attributeLock;
- SFTKSession *session;
- PRBool wasDerived;
+ PZLock *attributeLock;
+ SFTKSession *session;
+ PRBool wasDerived;
int nextAttr;
- SFTKAttribute attrList[MAX_OBJS_ATTRS];
- PRBool optimizeSpace;
- unsigned int hashSize;
- SFTKAttribute *head[1];
+ 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;
+ SFTKObjectListElement *next;
+ SFTKObject *object;
};
/*
* Area to hold Search results
*/
struct SFTKSearchResultsStr {
- CK_OBJECT_HANDLE *handles;
- int size;
- int index;
- int array_size;
+ CK_OBJECT_HANDLE *handles;
+ int size;
+ int index;
+ int array_size;
};
-
-/*
+/*
* the universal crypto/hash/sign/verify context structure
*/
typedef enum {
@@ -249,50 +249,50 @@ typedef enum {
* 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 */
+ 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];
+ 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;
+ 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];
+ 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];
};
/*
@@ -312,66 +312,66 @@ struct SFTKSessionStr {
* 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
+ * 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
+ * - 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 */
+ 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 */
+ CK_ULONG 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;
+ SECOidTag hashOid;
+ void *params;
+ NSSLOWKEYPublicKey *key;
};
struct SFTKHashSignInfoStr {
- SECOidTag hashOid;
- void *params;
- NSSLOWKEYPrivateKey *key;
+ SECOidTag hashOid;
+ void *params;
+ NSSLOWKEYPrivateKey *key;
};
/**
@@ -389,57 +389,67 @@ struct SFTKOAEPDecryptInfoStr {
/* 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;
+ void *hashContext;
+ SFTKBegin begin;
+ SFTKHash update;
+ SFTKEnd end;
+ CK_ULONG macSize;
+ int padSize;
+ unsigned char key[MAX_KEY_LEN];
+ unsigned int keySize;
+};
+
+/* SFTKChaCha20Poly1305Info saves the key, tag length, nonce,
+ * and additional data for a ChaCha20+Poly1305 AEAD operation. */
+struct SFTKChaCha20Poly1305InfoStr {
+ ChaCha20Poly1305Context freeblCtx;
+ unsigned char nonce[12];
+ unsigned char ad[16];
+ unsigned char *adOverflow;
+ unsigned int adLen;
};
/*
* Template based on SECItems, suitable for passing as arrays
*/
struct SFTKItemTemplateStr {
- CK_ATTRIBUTE_TYPE type;
- SECItem *item;
+ 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
+ templ[count].type = attr; \
+ templ[count].item = itemPtr
#define SFTK_MAX_ITEM_TEMPLATE 10
/*
* session handle modifiers
*/
-#define SFTK_SESSION_SLOT_MASK 0xff000000L
+#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
+#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
+#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_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)
+#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
+#define SFTK_MAX_PIN 255
/* minimum password/pin length (in Unicode characters) in FIPS mode */
-#define FIPS_MIN_PIN 7
+#define FIPS_MIN_PIN 7
/* slot ID's */
#define NETSCAPE_SLOT_ID 1
@@ -448,77 +458,89 @@ struct SFTKItemTemplateStr {
/* slot helper macros */
#define sftk_SlotFromSession(sp) ((sp)->slot)
-#define sftk_isToken(id) (((id) & SFTK_TOKEN_MASK) == SFTK_TOKEN_MAGIC)
+#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 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); \
+ (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; } \
+ 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);
+ 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; \
-
+ (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])
+/* 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) \
+/* 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
+#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;
@@ -532,7 +554,7 @@ typedef struct sftk_token_parametersStr {
char *tokdes;
char *slotdes;
char *updtokdes;
- int minPW;
+ int minPW;
PRBool readOnly;
PRBool noCertDB;
PRBool noKeyDB;
@@ -547,7 +569,7 @@ typedef struct sftk_parametersStr {
char *updateID;
char *secmodName;
char *man;
- char *libdes;
+ char *libdes;
PRBool readOnly;
PRBool noModDB;
PRBool noCertDB;
@@ -558,7 +580,6 @@ typedef struct sftk_parametersStr {
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"
@@ -569,55 +590,56 @@ SEC_BEGIN_PROTOS
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);
+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);
+ 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);
+ 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);
+ 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);
+ 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);
+ 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);
+ 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);
+ CK_ATTRIBUTE_TYPE type);
extern CK_RV sftk_Attribute2SecItem(PLArenaPool *arena, SECItem *item,
- SFTKObject *object, CK_ATTRIBUTE_TYPE type);
+ SFTKObject *object, CK_ATTRIBUTE_TYPE type);
extern CK_RV sftk_Attribute2SSecItem(PLArenaPool *arena, SECItem *item,
- SFTKObject *object,
- CK_ATTRIBUTE_TYPE type);
+ SFTKObject *object,
+ CK_ATTRIBUTE_TYPE type);
extern SFTKModifyType sftk_modifyType(CK_ATTRIBUTE_TYPE type,
- CK_OBJECT_CLASS inClass);
+ 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 void sftk_nullAttribute(SFTKObject *object, CK_ATTRIBUTE_TYPE type);
extern CK_RV sftk_GetULongAttribute(SFTKObject *object, CK_ATTRIBUTE_TYPE type,
- CK_ULONG *longData);
+ CK_ULONG *longData);
extern CK_RV sftk_forceAttribute(SFTKObject *object, CK_ATTRIBUTE_TYPE type,
- const void *value, unsigned int len);
+ const void *value, unsigned int len);
extern CK_RV sftk_defaultAttribute(SFTKObject *object, CK_ATTRIBUTE_TYPE type,
- const void *value, unsigned int len);
+ const void *value, unsigned int len);
extern unsigned int sftk_MapTrust(CK_TRUST trust, PRBool clientAuth);
extern SFTKObject *sftk_NewObject(SFTKSlot *slot);
@@ -626,7 +648,7 @@ 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);
+ 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.
@@ -634,11 +656,11 @@ extern void sftk_AddObject(SFTKSession *session, SFTKObject *object);
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);
+ SFTKObject **head, unsigned int size,
+ PZLock *lock, CK_ATTRIBUTE_PTR inTemplate,
+ int count, PRBool isLoggedIn);
extern SFTKObjectListElement *sftk_FreeObjectListElement(
- SFTKObjectListElement *objectList);
+ SFTKObjectListElement *objectList);
extern void sftk_FreeObjectList(SFTKObjectListElement *objectList);
extern void sftk_FreeSearch(SFTKSearchResults *search);
extern CK_RV sftk_handleObject(SFTKObject *object, SFTKSession *session);
@@ -648,20 +670,20 @@ 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);
+ 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);
+ CK_KEY_TYPE key_type, CK_RV *crvp);
extern NSSLOWKEYPrivateKey *sftk_GetPrivKey(SFTKObject *object,
- CK_KEY_TYPE key_type, CK_RV *crvp);
+ 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);
+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);
@@ -676,37 +698,32 @@ NSSLOWKEYPrivateKey *sftk_FindKeyByPublicKey(SFTKSlot *slot, SECItem *dbKey);
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 *);
+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);
+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);
+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) */
@@ -720,14 +737,14 @@ struct sftk_MACConstantTimeCtxStr {
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);
+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, const void *data, unsigned int len);
void sftk_SSLv3MACConstantTime_Update(void *pctx, const void *data, unsigned int len);
void sftk_MACConstantTime_EndHash(
- void *pctx, void *out, unsigned int *outLength, unsigned int maxLength);
+ void *pctx, void *out, unsigned int *outLength, unsigned int maxLength);
void sftk_MACConstantTime_DestroyContext(void *pctx, PRBool);
/****************************************
@@ -735,11 +752,11 @@ void sftk_MACConstantTime_DestroyContext(void *pctx, PRBool);
*/
extern CK_RV
-sftk_TLSPRFInit(SFTKSessionContext *context,
- SFTKObject * key,
- CK_KEY_TYPE key_type,
- HASH_HashType hash_alg,
- unsigned int out_len);
+sftk_TLSPRFInit(SFTKSessionContext *context,
+ SFTKObject *key,
+ CK_KEY_TYPE key_type,
+ HASH_HashType hash_alg,
+ unsigned int out_len);
SEC_END_PROTOS
diff --git a/nss/lib/softoken/pkcs11ni.h b/nss/lib/softoken/pkcs11ni.h
index 3375102..612842c 100644
--- a/nss/lib/softoken/pkcs11ni.h
+++ b/nss/lib/softoken/pkcs11ni.h
@@ -17,5 +17,4 @@
#define SFTK_MIN_FIPS_USER_SLOT_ID 101
#define SFTK_MAX_FIPS_USER_SLOT_ID 127
-
#endif /* _PKCS11NI_H_ */
diff --git a/nss/lib/softoken/pkcs11u.c b/nss/lib/softoken/pkcs11u.c
index de5cbbc..a5694ee 100644
--- a/nss/lib/softoken/pkcs11u.c
+++ b/nss/lib/softoken/pkcs11u.c
@@ -24,19 +24,19 @@
*/
static SFTKAttribute *
sftk_NewAttribute(SFTKObject *object,
- CK_ATTRIBUTE_TYPE type, const void *value, CK_ULONG len)
+ 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;
+ 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
@@ -46,7 +46,8 @@ sftk_NewAttribute(SFTKObject *object,
index = so->nextAttr++;
PZ_Unlock(so->attributeLock);
PORT_Assert(index < MAX_OBJS_ATTRS);
- if (index >= MAX_OBJS_ATTRS) return NULL;
+ if (index >= MAX_OBJS_ATTRS)
+ return NULL;
attribute = &so->attrList[index];
attribute->attrib.type = type;
@@ -54,19 +55,19 @@ sftk_NewAttribute(SFTKObject *object,
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;
+ 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.pValue = NULL;
+ attribute->attrib.ulValueLen = 0;
}
attribute->attrib.type = type;
attribute->handle = type;
@@ -82,13 +83,13 @@ 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);
+ 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);
}
@@ -100,21 +101,21 @@ void
sftk_FreeAttribute(SFTKAttribute *attribute)
{
if (attribute->freeAttr) {
- sftk_DestroyAttribute(attribute);
- return;
+ sftk_DestroyAttribute(attribute);
+ return;
}
}
-static SFTKAttribute *
-sftk_FindTokenAttribute(SFTKTokenObject *object,CK_ATTRIBUTE_TYPE type)
+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));
+ myattribute = (SFTKAttribute *)PORT_Alloc(sizeof(SFTKAttribute));
if (myattribute == NULL) {
- goto loser;
+ goto loser;
}
dbHandle = sftk_getDBForTokenObject(object->obj.slot, object->obj.handle);
@@ -128,59 +129,59 @@ sftk_FindTokenAttribute(SFTKTokenObject *object,CK_ATTRIBUTE_TYPE type)
myattribute->freeData = PR_FALSE;
crv = sftkdb_GetAttributeValue(dbHandle, object->obj.handle,
- &myattribute->attrib, 1);
+ &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);
- }
+ 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);
+ sftk_freeDB(dbHandle);
}
if (crv != CKR_OK) {
- if (myattribute) {
- myattribute->attrib.ulValueLen = 0;
- sftk_FreeAttribute(myattribute);
- myattribute = NULL;
- }
+ 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
+ * 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)
+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);
+ return sftk_FindTokenAttribute(sftk_narrowToTokenObject(object), type);
}
PZ_Lock(sessObject->attributeLock);
- sftkqueue_find(attribute,type,sessObject->head, sessObject->hashSize);
+ sftkqueue_find(attribute, type, sessObject->head, sessObject->hashSize);
PZ_Unlock(sessObject->attributeLock);
- return(attribute);
+ return (attribute);
}
/*
@@ -193,19 +194,19 @@ sftk_GetLengthInBits(unsigned char *buf, unsigned int bufLen)
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;
+ 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;
}
@@ -219,8 +220,8 @@ sftk_GetLengthInBits(unsigned char *buf, unsigned int bufLen)
* 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)
+sftk_ConstrainAttribute(SFTKObject *object, CK_ATTRIBUTE_TYPE type,
+ int minLength, int maxLength, int minMultiple)
{
SFTKAttribute *attribute;
int size;
@@ -228,24 +229,24 @@ sftk_ConstrainAttribute(SFTKObject *object, CK_ATTRIBUTE_TYPE type,
attribute = sftk_FindAttribute(object, type);
if (!attribute) {
- return CKR_TEMPLATE_INCOMPLETE;
+ return CKR_TEMPLATE_INCOMPLETE;
}
- ptr = (unsigned char *) attribute->attrib.pValue;
+ ptr = (unsigned char *)attribute->attrib.pValue;
if (ptr == NULL) {
- sftk_FreeAttribute(attribute);
- return CKR_ATTRIBUTE_VALUE_INVALID;
+ 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 ((minLength != 0) && (size < minLength)) {
+ return CKR_ATTRIBUTE_VALUE_INVALID;
}
- if ((maxLength != 0) && (size > maxLength)) {
- 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_ATTRIBUTE_VALUE_INVALID;
}
return CKR_OK;
}
@@ -273,17 +274,17 @@ sftk_hasAttributeToken(SFTKTokenObject *object, CK_ATTRIBUTE_TYPE type)
* return true if object has attribute
*/
PRBool
-sftk_hasAttribute(SFTKObject *object,CK_ATTRIBUTE_TYPE type)
+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);
+ return sftk_hasAttributeToken(sftk_narrowToTokenObject(object), type);
}
PZ_Lock(sessObject->attributeLock);
- sftkqueue_find(attribute,type,sessObject->head, sessObject->hashSize);
+ sftkqueue_find(attribute, type, sessObject->head, sessObject->hashSize);
PZ_Unlock(sessObject->attributeLock);
return (PRBool)(attribute != NULL);
@@ -293,49 +294,51 @@ sftk_hasAttribute(SFTKObject *object,CK_ATTRIBUTE_TYPE type)
* add an attribute to an object
*/
static void
-sftk_AddAttribute(SFTKObject *object,SFTKAttribute *attribute)
+sftk_AddAttribute(SFTKObject *object, SFTKAttribute *attribute)
{
SFTKSessionObject *sessObject = sftk_narrowToSessionObject(object);
- if (sessObject == NULL) return;
+ if (sessObject == NULL)
+ return;
PZ_Lock(sessObject->attributeLock);
- sftkqueue_add(attribute,attribute->handle,
- sessObject->head, sessObject->hashSize);
+ 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)
+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;
+ 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;
+ 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)
+ SFTKItemTemplate *itemTemplate, int itemTemplateCount)
{
CK_RV crv = CKR_OK;
@@ -349,87 +352,86 @@ sftk_MultipleAttribute2SecItem(PLArenaPool *arena, SFTKObject *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;
+ 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;
+ return CKR_OK;
}
/* don't allocate the template unless we need it */
if (itemTemplateCount > SFTK_MAX_ITEM_TEMPLATE) {
- template = PORT_NewArray(CK_ATTRIBUTE, itemTemplateCount);
+ template = PORT_NewArray(CK_ATTRIBUTE, itemTemplateCount);
} else {
- template = templateSpace;
+ template = templateSpace;
}
if (template == NULL) {
- crv = CKR_HOST_MEMORY;
- goto loser;
+ crv = CKR_HOST_MEMORY;
+ goto loser;
}
dbHandle = sftk_getDBForTokenObject(object->slot, object->handle);
if (dbHandle == NULL) {
- crv = CKR_OBJECT_HANDLE_INVALID;
- goto loser;
+ 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;
+ 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);
+ template, itemTemplateCount);
if (crv != CKR_OK) {
- goto loser;
+ 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;
- }
+ 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);
+ template, itemTemplateCount);
if (crv != CKR_OK) {
- goto loser;
+ 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;
+ /* 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);
+ PORT_Free(template);
}
if (dbHandle) {
- sftk_freeDB(dbHandle);
+ sftk_freeDB(dbHandle);
}
-
+
return crv;
}
-
/*
* delete an attribute from an object
*/
@@ -439,13 +441,13 @@ sftk_DeleteAttribute(SFTKObject *object, SFTKAttribute *attribute)
SFTKSessionObject *sessObject = sftk_narrowToSessionObject(object);
if (sessObject == NULL) {
- return ;
+ 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);
+ if (sftkqueue_is_queued(attribute, attribute->handle,
+ sessObject->head, sessObject->hashSize)) {
+ sftkqueue_delete(attribute, attribute->handle,
+ sessObject->head, sessObject->hashSize);
}
PZ_Unlock(sessObject->attributeLock);
}
@@ -455,13 +457,15 @@ sftk_DeleteAttribute(SFTKObject *object, SFTKAttribute *attribute)
* of that attribute.
*/
PRBool
-sftk_isTrue(SFTKObject *object,CK_ATTRIBUTE_TYPE type)
+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; }
+ attribute = sftk_FindAttribute(object, type);
+ if (attribute == NULL) {
+ return PR_FALSE;
+ }
tok = (PRBool)(*(CK_BBOOL *)attribute->attrib.pValue);
sftk_FreeAttribute(attribute);
@@ -474,29 +478,29 @@ sftk_isTrue(SFTKObject *object,CK_ATTRIBUTE_TYPE type)
* want to keep this info around in memory in the clear.
*/
void
-sftk_nullAttribute(SFTKObject *object,CK_ATTRIBUTE_TYPE type)
+sftk_nullAttribute(SFTKObject *object, CK_ATTRIBUTE_TYPE type)
{
SFTKAttribute *attribute;
- attribute=sftk_FindAttribute(object,type);
- if (attribute == NULL) return;
+ 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;
+ 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)
+sftk_forceTokenAttribute(SFTKObject *object, CK_ATTRIBUTE_TYPE type,
+ const void *value, unsigned int len)
{
CK_ATTRIBUTE attribute;
SFTKDBHandle *dbHandle = NULL;
@@ -505,7 +509,7 @@ sftk_forceTokenAttribute(SFTKObject *object,CK_ATTRIBUTE_TYPE type,
PORT_Assert(to);
if (to == NULL) {
- return CKR_DEVICE_ERROR;
+ return CKR_DEVICE_ERROR;
}
dbHandle = sftk_getDBForTokenObject(object->slot, object->handle);
@@ -518,13 +522,13 @@ sftk_forceTokenAttribute(SFTKObject *object,CK_ATTRIBUTE_TYPE type,
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)
+sftk_forceAttribute(SFTKObject *object, CK_ATTRIBUTE_TYPE type,
+ const void *value, unsigned int len)
{
SFTKAttribute *attribute;
void *att_val = NULL;
@@ -539,44 +543,44 @@ sftk_forceAttribute(SFTKObject *object,CK_ATTRIBUTE_TYPE type,
return CKR_DEVICE_ERROR;
}
if (sftk_isToken(object->handle)) {
- return sftk_forceTokenAttribute(object,type,value,len);
+ return sftk_forceTokenAttribute(object, type, value, len);
}
- attribute=sftk_FindAttribute(object,type);
- if (attribute == NULL) return sftk_AddAttributeType(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);
+ 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 (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;
+ attribute->attrib.pValue = att_val;
+ attribute->attrib.ulValueLen = len;
+ attribute->freeData = freeData;
}
sftk_FreeAttribute(attribute);
return CKR_OK;
@@ -587,24 +591,25 @@ sftk_forceAttribute(SFTKObject *object,CK_ATTRIBUTE_TYPE type,
* is allocated and needs to be freed with PORT_Free() When complete.
*/
char *
-sftk_getString(SFTKObject *object,CK_ATTRIBUTE_TYPE type)
+sftk_getString(SFTKObject *object, CK_ATTRIBUTE_TYPE type)
{
SFTKAttribute *attribute;
char *label = NULL;
- attribute=sftk_FindAttribute(object,type);
- if (attribute == NULL) return 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;
- }
+ 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;
+ PORT_Memcpy(label, attribute->attrib.pValue,
+ attribute->attrib.ulValueLen);
+ label[attribute->attrib.ulValueLen] = 0;
}
sftk_FreeAttribute(attribute);
return label;
@@ -612,88 +617,88 @@ sftk_getString(SFTKObject *object,CK_ATTRIBUTE_TYPE type)
/*
* decode when a particular attribute may be modified
- * SFTK_NEVER: This attribute must be set at object creation time and
+ * 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
+ * SFTK_ONCOPY: This attribute may be modified only when you copy the
* object.
- * SFTK_SENSITIVE: The CKA_SENSITIVE attribute can only be changed from
+ * 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
+ * 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;
+ 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;
}
@@ -703,68 +708,70 @@ sftk_modifyType(CK_ATTRIBUTE_TYPE type, CK_OBJECT_CLASS inClass)
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;
+ 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));
+ /* 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;
+ 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)
+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;
+ if (attribute == NULL)
+ return CKR_TEMPLATE_INCOMPLETE;
len = attribute->attrib.ulValueLen;
if (arena) {
- item->data = (unsigned char *) PORT_ArenaAlloc(arena,len);
+ item->data = (unsigned char *)PORT_ArenaAlloc(arena, len);
} else {
- item->data = (unsigned char *) PORT_Alloc(len);
+ item->data = (unsigned char *)PORT_Alloc(len);
}
if (item->data == NULL) {
- sftk_FreeAttribute(attribute);
- return CKR_HOST_MEMORY;
+ sftk_FreeAttribute(attribute);
+ return CKR_HOST_MEMORY;
}
item->len = len;
- PORT_Memcpy(item->data,attribute->attrib.pValue, 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)
+ CK_ULONG *longData)
{
SFTKAttribute *attribute;
attribute = sftk_FindAttribute(object, type);
- if (attribute == NULL) return CKR_TEMPLATE_INCOMPLETE;
+ if (attribute == NULL)
+ return CKR_TEMPLATE_INCOMPLETE;
if (attribute->attrib.ulValueLen != sizeof(CK_ULONG)) {
- return CKR_ATTRIBUTE_VALUE_INVALID;
+ return CKR_ATTRIBUTE_VALUE_INVALID;
}
*longData = *(CK_ULONG *)attribute->attrib.pValue;
@@ -773,23 +780,26 @@ sftk_GetULongAttribute(SFTKObject *object, CK_ATTRIBUTE_TYPE type,
}
void
-sftk_DeleteAttributeType(SFTKObject *object,CK_ATTRIBUTE_TYPE type)
+sftk_DeleteAttributeType(SFTKObject *object, CK_ATTRIBUTE_TYPE type)
{
SFTKAttribute *attribute;
attribute = sftk_FindAttribute(object, type);
- if (attribute == NULL) return ;
- sftk_DeleteAttribute(object,attribute);
+ 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)
+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);
+ attribute = sftk_NewAttribute(object, type, valPtr, length);
+ if (attribute == NULL) {
+ return CKR_HOST_MEMORY;
+ }
+ sftk_AddAttribute(object, attribute);
return CKR_OK;
}
@@ -810,17 +820,19 @@ sftk_lookupTokenKeyByHandle(SFTKSlot *slot, CK_OBJECT_HANDLE handle)
* a new lock. We use separate functions for this just in case I'm wrong.
*/
static void
-sftk_tokenKeyLock(SFTKSlot *slot) {
+sftk_tokenKeyLock(SFTKSlot *slot)
+{
SKIP_AFTER_FORK(PZ_Lock(slot->objectLock));
}
static void
-sftk_tokenKeyUnlock(SFTKSlot *slot) {
+sftk_tokenKeyUnlock(SFTKSlot *slot)
+{
SKIP_AFTER_FORK(PZ_Unlock(slot->objectLock));
}
static PRIntn
-sftk_freeHashItem(PLHashEntry* entry, PRIntn index, void *arg)
+sftk_freeHashItem(PLHashEntry *entry, PRIntn index, void *arg)
{
SECItem *item = (SECItem *)entry->value;
@@ -838,38 +850,36 @@ SFTK_ClearTokenKeyHashTable(SFTKSlot *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)
+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;
+ 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;
- }
+ return object;
+ }
}
- size = isSessionObject ? sizeof(SFTKSessionObject)
- + hashSize *sizeof(SFTKAttribute *) : sizeof(SFTKTokenObject);
+ size = isSessionObject ? sizeof(SFTKSessionObject) + hashSize * sizeof(SFTKAttribute *) : sizeof(SFTKTokenObject);
- object = (SFTKObject*)PORT_ZAlloc(size);
+ object = (SFTKObject *)PORT_ZAlloc(size);
if (isSessionObject && object) {
- ((SFTKSessionObject *)object)->hashSize = hashSize;
+ ((SFTKSessionObject *)object)->hashSize = hashSize;
}
*hasLocks = PR_FALSE;
return object;
@@ -877,70 +887,74 @@ sftk_GetObjectFromList(PRBool *hasLocks, PRBool optimizeSpace,
static void
sftk_PutObjectToList(SFTKObject *object, SFTKObjectFreeList *list,
- PRBool isSessionObject) {
+ 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;
+ 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;
+ SFTKSessionObject *so = (SFTKSessionObject *)object;
+ PZ_DestroyLock(so->attributeLock);
+ so->attributeLock = NULL;
}
if (object->refLock) {
- PZ_DestroyLock(object->refLock);
- object->refLock = NULL;
+ PZ_DestroyLock(object->refLock);
+ object->refLock = NULL;
}
PORT_Free(object);
}
static SFTKObject *
-sftk_freeObjectData(SFTKObject *object) {
- SFTKObject *next = object->next;
+sftk_freeObjectData(SFTKObject *object)
+{
+ SFTKObject *next = object->next;
- PORT_Free(object);
- return next;
+ PORT_Free(object);
+ return next;
}
static void
sftk_InitFreeList(SFTKObjectFreeList *list)
{
- list->lock = PZ_NewLock(nssILockObject);
+ if (!list->lock) {
+ list->lock = PZ_NewLock(nssILockObject);
+ }
}
-void sftk_InitFreeLists(void)
+void
+sftk_InitFreeLists(void)
{
sftk_InitFreeList(&sessionObjectList);
sftk_InitFreeList(&tokenObjectList);
}
-
+
static void
sftk_CleanupFreeList(SFTKObjectFreeList *list, PRBool isSessionList)
{
SFTKObject *object;
if (!list->lock) {
- return;
+ 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);
- }
+ 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;
@@ -956,7 +970,6 @@ sftk_CleanupFreeLists(void)
sftk_CleanupFreeList(&tokenObjectList, PR_FALSE);
}
-
/*
* Create a new object
*/
@@ -969,46 +982,47 @@ sftk_NewObject(SFTKSlot *slot)
unsigned int i;
unsigned int hashSize = 0;
- hashSize = (slot->optimizeSpace) ? SPACE_ATTRIBUTE_HASH_SIZE :
- TIME_ATTRIBUTE_HASH_SIZE;
+ hashSize = (slot->optimizeSpace) ? SPACE_ATTRIBUTE_HASH_SIZE : TIME_ATTRIBUTE_HASH_SIZE;
object = sftk_GetObjectFromList(&hasLocks, slot->optimizeSpace,
- &sessionObjectList, hashSize, PR_TRUE);
+ &sessionObjectList, hashSize, PR_TRUE);
if (object == NULL) {
- return 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;
+ 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 (!hasLocks)
+ object->refLock = PZ_NewLock(nssILockRefLock);
if (object->refLock == NULL) {
- PORT_Free(object);
- return NULL;
+ PORT_Free(object);
+ return NULL;
}
- if (!hasLocks) sessObject->attributeLock = PZ_NewLock(nssILockAttribute);
+ if (!hasLocks)
+ sessObject->attributeLock = PZ_NewLock(nssILockAttribute);
if (sessObject->attributeLock == NULL) {
- PZ_DestroyLock(object->refLock);
- PORT_Free(object);
- return NULL;
+ PZ_DestroyLock(object->refLock);
+ PORT_Free(object);
+ return NULL;
}
- for (i=0; i < sessObject->hashSize; i++) {
- sessObject->head[i] = NULL;
+ for (i = 0; i < sessObject->hashSize; i++) {
+ sessObject->head[i] = NULL;
}
object->objectInfo = NULL;
object->infoFree = NULL;
@@ -1018,21 +1032,21 @@ sftk_NewObject(SFTKSlot *slot)
static CK_RV
sftk_DestroySessionObjectData(SFTKSessionObject *so)
{
- int i;
+ 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;
+ 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;
}
/*
@@ -1050,23 +1064,23 @@ sftk_DestroyObject(SFTKObject *object)
/* delete the database value */
if (to) {
- if (to->dbKey.data) {
- PORT_Free(to->dbKey.data);
- to->dbKey.data = NULL;
- }
- }
+ if (to->dbKey.data) {
+ PORT_Free(to->dbKey.data);
+ to->dbKey.data = NULL;
+ }
+ }
if (so) {
- sftk_DestroySessionObjectData(so);
+ sftk_DestroySessionObjectData(so);
}
if (object->objectInfo) {
- (*object->infoFree)(object->objectInfo);
- object->objectInfo = NULL;
- object->infoFree = NULL;
+ (*object->infoFree)(object->objectInfo);
+ object->objectInfo = NULL;
+ object->infoFree = NULL;
}
if (so) {
- sftk_PutObjectToList(object,&sessionObjectList,PR_TRUE);
+ sftk_PutObjectToList(object, &sessionObjectList, PR_TRUE);
} else {
- sftk_PutObjectToList(object,&tokenObjectList,PR_FALSE);
+ sftk_PutObjectToList(object, &tokenObjectList, PR_FALSE);
}
return crv;
}
@@ -1086,17 +1100,17 @@ sftk_ObjectFromHandleOnSlot(CK_OBJECT_HANDLE handle, SFTKSlot *slot)
PRUint32 index = sftk_hash(handle, slot->sessObjHashSize);
if (sftk_isToken(handle)) {
- return sftk_NewTokenObject(slot, NULL, handle);
+ return sftk_NewTokenObject(slot, NULL, handle);
}
PZ_Lock(slot->objectLock);
sftkqueue_find2(object, handle, index, slot->sessObjHashTable);
if (object) {
- sftk_ReferenceObject(object);
+ sftk_ReferenceObject(object);
}
PZ_Unlock(slot->objectLock);
- return(object);
+ return (object);
}
/*
* look up and object structure from a handle. OBJECT_Handles only make
@@ -1108,10 +1122,9 @@ sftk_ObjectFromHandle(CK_OBJECT_HANDLE handle, SFTKSession *session)
{
SFTKSlot *slot = sftk_SlotFromSession(session);
- return sftk_ObjectFromHandleOnSlot(handle,slot);
+ return sftk_ObjectFromHandleOnSlot(handle, slot);
}
-
/*
* release a reference to an object handle
*/
@@ -1122,20 +1135,21 @@ sftk_FreeObject(SFTKObject *object)
CK_RV crv;
PZ_Lock(object->refLock);
- if (object->refCount == 1) destroy = PR_TRUE;
+ 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;
+ 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.
@@ -1157,14 +1171,14 @@ sftk_AddObject(SFTKSession *session, SFTKObject *object)
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);
+ PZ_Lock(session->objectLock);
+ sftkqueue_add(&so->sessionList, 0, session->objects, 0);
+ so->session = session;
+ PZ_Unlock(session->objectLock);
}
- sftk_AddSlotObject(slot,object);
+ sftk_AddSlotObject(slot, object);
sftk_ReferenceObject(object);
-}
+}
/*
* delete an object from a slot and session queue
@@ -1179,24 +1193,24 @@ sftk_DeleteObject(SFTKSession *session, SFTKObject *object)
/* 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 */
+ 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);
+ SFTKDBHandle *handle = sftk_getDBForTokenObject(slot, object->handle);
#ifdef DEBUG
SFTKTokenObject *to = sftk_narrowToTokenObject(object);
- PORT_Assert(to);
+ PORT_Assert(to);
#endif
- crv = sftkdb_DestroyObject(handle, object->handle);
- sftk_freeDB(handle);
- }
+ crv = sftkdb_DestroyObject(handle, object->handle);
+ sftk_freeDB(handle);
+ }
return crv;
}
@@ -1208,144 +1222,144 @@ sftk_DeleteObject(SFTKSession *session, SFTKObject *object)
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_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_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_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_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_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_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]);
+static const CK_ULONG dhPubKeyAttrsCount =
+ sizeof(dhPubKeyAttrs) / sizeof(dhPubKeyAttrs[0]);
#ifndef NSS_DISABLE_ECC
static const CK_ATTRIBUTE_TYPE ecPubKeyAttrs[] = {
CKA_EC_PARAMS, CKA_EC_POINT
};
-static const CK_ULONG ecPubKeyAttrsCount =
- sizeof(ecPubKeyAttrs)/sizeof(ecPubKeyAttrs[0]);
+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_ULONG commonPrivKeyAttrsCount =
+ sizeof(commonPrivKeyAttrs) / sizeof(commonPrivKeyAttrs[0]);
static const CK_ATTRIBUTE_TYPE rsaPrivKeyAttrs[] = {
- CKA_MODULUS, CKA_PUBLIC_EXPONENT, CKA_PRIVATE_EXPONENT,
+ 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_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_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]);
+static const CK_ULONG dhPrivKeyAttrsCount =
+ sizeof(dhPrivKeyAttrs) / sizeof(dhPrivKeyAttrs[0]);
#ifndef NSS_DISABLE_ECC
static const CK_ATTRIBUTE_TYPE ecPrivKeyAttrs[] = {
CKA_EC_PARAMS, CKA_VALUE
};
-static const CK_ULONG ecPrivKeyAttrsCount =
- sizeof(ecPrivKeyAttrs)/sizeof(ecPrivKeyAttrs[0]);
+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_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_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_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]);
+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)
+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);
- }
+ 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)
+stfk_CopyTokenPrivateKey(SFTKObject *destObject, SFTKTokenObject *src_to)
{
CK_RV crv;
CK_KEY_TYPE key_type;
@@ -1353,60 +1367,60 @@ stfk_CopyTokenPrivateKey(SFTKObject *destObject,SFTKTokenObject *src_to)
/* copy the common attributes for all keys first */
crv = stfk_CopyTokenAttributes(destObject, src_to, commonKeyAttrs,
- commonKeyAttrsCount);
+ commonKeyAttrsCount);
if (crv != CKR_OK) {
- goto fail;
+ goto fail;
}
/* copy the common attributes for all private keys next */
crv = stfk_CopyTokenAttributes(destObject, src_to, commonPrivKeyAttrs,
- commonPrivKeyAttrsCount);
+ commonPrivKeyAttrsCount);
if (crv != CKR_OK) {
- goto fail;
+ goto fail;
}
- attribute =sftk_FindAttribute(&src_to->obj, CKA_KEY_TYPE);
+ 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 */
+ * 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;
+ /* 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;
+ 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;
#ifndef NSS_DISABLE_ECC
- case CKK_EC:
- crv = stfk_CopyTokenAttributes(destObject, src_to, ecPrivKeyAttrs,
- ecPrivKeyAttrsCount);
- break;
+ 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. */
+ 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)
+stfk_CopyTokenPublicKey(SFTKObject *destObject, SFTKTokenObject *src_to)
{
CK_RV crv;
CK_KEY_TYPE key_type;
@@ -1414,69 +1428,69 @@ stfk_CopyTokenPublicKey(SFTKObject *destObject,SFTKTokenObject *src_to)
/* copy the common attributes for all keys first */
crv = stfk_CopyTokenAttributes(destObject, src_to, commonKeyAttrs,
- commonKeyAttrsCount);
+ commonKeyAttrsCount);
if (crv != CKR_OK) {
- goto fail;
+ goto fail;
}
/* copy the common attributes for all public keys next */
crv = stfk_CopyTokenAttributes(destObject, src_to, commonPubKeyAttrs,
- commonPubKeyAttrsCount);
+ commonPubKeyAttrsCount);
if (crv != CKR_OK) {
- goto fail;
+ goto fail;
}
- attribute =sftk_FindAttribute(&src_to->obj, CKA_KEY_TYPE);
+ 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 */
+ * 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;
+ /* 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;
+ 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;
#ifndef NSS_DISABLE_ECC
- case CKK_EC:
- crv = stfk_CopyTokenAttributes(destObject, src_to, ecPubKeyAttrs,
- ecPubKeyAttrsCount);
- break;
+ 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. */
+ 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)
+stfk_CopyTokenSecretKey(SFTKObject *destObject, SFTKTokenObject *src_to)
{
CK_RV crv;
crv = stfk_CopyTokenAttributes(destObject, src_to, commonKeyAttrs,
- commonKeyAttrsCount);
+ commonKeyAttrsCount);
if (crv != CKR_OK) {
- goto fail;
+ goto fail;
}
crv = stfk_CopyTokenAttributes(destObject, src_to, secretKeyAttrs,
- secretKeyAttrsCount);
+ secretKeyAttrsCount);
fail:
return crv;
}
@@ -1487,50 +1501,50 @@ fail:
* the token itself.
*/
CK_RV
-sftk_CopyTokenObject(SFTKObject *destObject,SFTKObject *srcObject)
+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 */
+ return CKR_DEVICE_ERROR; /* internal state inconsistant */
}
crv = stfk_CopyTokenAttributes(destObject, src_to, commonAttrs,
- commonAttrsCount);
+ commonAttrsCount);
if (crv != CKR_OK) {
- goto fail;
+ 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. */
+ 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;
@@ -1542,35 +1556,35 @@ fail:
* grabs the attribute locks for the src object for a *long* time.
*/
CK_RV
-sftk_CopyObject(SFTKObject *destObject,SFTKObject *srcObject)
+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);
+ 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);
+ 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);
@@ -1583,42 +1597,42 @@ sftk_CopyObject(SFTKObject *destObject,SFTKObject *srcObject)
/* add an object to a search list */
CK_RV
-AddToList(SFTKObjectListElement **list,SFTKObject *object)
+AddToList(SFTKObjectListElement **list, SFTKObject *object)
{
- SFTKObjectListElement *newElem =
- (SFTKObjectListElement *)PORT_Alloc(sizeof(SFTKObjectListElement));
+ SFTKObjectListElement *newElem =
+ (SFTKObjectListElement *)PORT_Alloc(sizeof(SFTKObjectListElement));
- if (newElem == NULL) return CKR_HOST_MEMORY;
+ if (newElem == NULL)
+ return CKR_HOST_MEMORY;
- newElem->next = *list;
- newElem->object = object;
- sftk_ReferenceObject(object);
+ 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)
+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;
- }
- }
+ 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_FALSE;
}
return PR_TRUE;
}
@@ -1627,25 +1641,26 @@ sftk_objectMatch(SFTKObject *object,CK_ATTRIBUTE_PTR theTemplate,int count)
* 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)
+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++) {
+ 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);
- }
- }
+ 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;
@@ -1670,7 +1685,8 @@ sftk_FreeObjectList(SFTKObjectListElement *objectList)
{
SFTKObjectListElement *ol;
- for (ol= objectList; ol != NULL; ol = sftk_FreeObjectListElement(ol)) {}
+ for (ol = objectList; ol != NULL; ol = sftk_FreeObjectListElement(ol)) {
+ }
}
/*
@@ -1680,7 +1696,7 @@ void
sftk_FreeSearch(SFTKSearchResults *search)
{
if (search->handles) {
- PORT_Free(search->handles);
+ PORT_Free(search->handles);
}
PORT_Free(search);
}
@@ -1692,22 +1708,22 @@ sftk_FreeSearch(SFTKSearchResults *search)
/* 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)
+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;
- }
+ 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;
- }
+ if (session->info.flags & CKF_RW_SESSION) {
+ session->info.state = CKS_RW_PUBLIC_SESSION;
+ } else {
+ session->info.state = CKS_RO_PUBLIC_SESSION;
+ }
}
}
@@ -1718,13 +1734,13 @@ 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);
+ 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);
}
}
@@ -1735,14 +1751,14 @@ void
sftk_FreeContext(SFTKSessionContext *context)
{
if (context->cipherInfo) {
- (*context->destroy)(context->cipherInfo,PR_TRUE);
+ (*context->destroy)(context->cipherInfo, PR_TRUE);
}
if (context->hashInfo) {
- (*context->hashdestroy)(context->hashInfo,PR_TRUE);
+ (*context->hashdestroy)(context->hashInfo, PR_TRUE);
}
if (context->key) {
- sftk_FreeObject(context->key);
- context->key = NULL;
+ sftk_FreeObject(context->key);
+ context->key = NULL;
}
PORT_Free(context);
}
@@ -1753,15 +1769,17 @@ sftk_FreeContext(SFTKSessionContext *context)
*/
SFTKSession *
sftk_NewSession(CK_SLOT_ID slotID, CK_NOTIFY notify, CK_VOID_PTR pApplication,
- CK_FLAGS flags)
+ CK_FLAGS flags)
{
SFTKSession *session;
SFTKSlot *slot = sftk_SlotFromID(slotID, PR_FALSE);
- if (slot == NULL) return NULL;
+ if (slot == NULL)
+ return NULL;
- session = (SFTKSession*)PORT_Alloc(sizeof(SFTKSession));
- if (session == NULL) return NULL;
+ session = (SFTKSession *)PORT_Alloc(sizeof(SFTKSession));
+ if (session == NULL)
+ return NULL;
session->next = session->prev = NULL;
session->refCount = 1;
@@ -1772,8 +1790,8 @@ sftk_NewSession(CK_SLOT_ID slotID, CK_NOTIFY notify, CK_VOID_PTR pApplication,
session->objectIDCount = 1;
session->objectLock = PZ_NewLock(nssILockObject);
if (session->objectLock == NULL) {
- PORT_Free(session);
- return NULL;
+ PORT_Free(session);
+ return NULL;
}
session->objects[0] = NULL;
@@ -1783,16 +1801,15 @@ sftk_NewSession(CK_SLOT_ID slotID, CK_NOTIFY notify, CK_VOID_PTR pApplication,
session->info.flags = flags;
session->info.slotID = slotID;
session->info.ulDeviceError = 0;
- sftk_update_state(slot,session);
+ sftk_update_state(slot, session);
return session;
}
-
/* free all the data associated with a session. */
static void
sftk_DestroySession(SFTKSession *session)
{
- SFTKObjectList *op,*next;
+ SFTKObjectList *op, *next;
PORT_Assert(session->refCount == 0);
/* clean out the attributes */
@@ -1801,26 +1818,25 @@ sftk_DestroySession(SFTKSession *session)
for (op = session->objects[0]; op != NULL; op = next) {
next = op->next;
/* paranoia */
- op->next = op->prev = NULL;
- sftk_DeleteObject(session,op->parent);
+ op->next = op->prev = NULL;
+ sftk_DeleteObject(session, op->parent);
}
PZ_DestroyLock(session->objectLock);
if (session->enc_context) {
- sftk_FreeContext(session->enc_context);
+ sftk_FreeContext(session->enc_context);
}
if (session->hash_context) {
- sftk_FreeContext(session->hash_context);
+ sftk_FreeContext(session->hash_context);
}
if (session->sign_context) {
- sftk_FreeContext(session->sign_context);
+ sftk_FreeContext(session->sign_context);
}
if (session->search) {
- sftk_FreeSearch(session->search);
+ sftk_FreeSearch(session->search);
}
PORT_Free(session);
}
-
/*
* look up a session structure from a session handle
* generate a reference to it.
@@ -1828,16 +1844,18 @@ sftk_DestroySession(SFTKSession *session)
SFTKSession *
sftk_SessionFromHandle(CK_SESSION_HANDLE handle)
{
- SFTKSlot *slot = sftk_SlotFromSessionHandle(handle);
+ SFTKSlot *slot = sftk_SlotFromSessionHandle(handle);
SFTKSession *session;
- PZLock *lock;
-
- if (!slot) return NULL;
- lock = SFTK_SESSION_LOCK(slot,handle);
+ 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++;
+ sftkqueue_find(session, handle, slot->head, slot->sessHashSize);
+ if (session)
+ session->refCount++;
PZ_Unlock(lock);
return (session);
@@ -1851,37 +1869,39 @@ sftk_FreeSession(SFTKSession *session)
{
PRBool destroy = PR_FALSE;
SFTKSlot *slot = sftk_SlotFromSession(session);
- PZLock *lock = SFTK_SESSION_LOCK(slot,session->handle);
+ PZLock *lock = SFTK_SESSION_LOCK(slot, session->handle);
PZ_Lock(lock);
- if (session->refCount == 1) destroy = PR_TRUE;
+ if (session->refCount == 1)
+ destroy = PR_TRUE;
session->refCount--;
PZ_Unlock(lock);
- if (destroy) sftk_DestroySession(session);
+ if (destroy)
+ sftk_DestroySession(session);
}
void
sftk_addHandle(SFTKSearchResults *search, CK_OBJECT_HANDLE handle)
{
if (search->handles == NULL) {
- return;
+ 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->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)
+static CK_RV
+handleToClass(SFTKSlot *slot, CK_OBJECT_HANDLE handle,
+ CK_OBJECT_CLASS *objClass)
{
SFTKDBHandle *dbHandle = sftk_getDBForTokenObject(slot, handle);
CK_ATTRIBUTE objClassTemplate;
@@ -1903,10 +1923,10 @@ sftk_NewTokenObject(SFTKSlot *slot, SECItem *dbKey, CK_OBJECT_HANDLE handle)
PRBool hasLocks = PR_FALSE;
CK_RV crv;
- object = sftk_GetObjectFromList(&hasLocks, PR_FALSE, &tokenObjectList, 0,
- PR_FALSE);
+ object = sftk_GetObjectFromList(&hasLocks, PR_FALSE, &tokenObjectList, 0,
+ PR_FALSE);
if (object == NULL) {
- return NULL;
+ return NULL;
}
object->handle = handle;
@@ -1914,26 +1934,23 @@ sftk_NewTokenObject(SFTKSlot *slot, SECItem *dbKey, CK_OBJECT_HANDLE handle)
* doesn't exist */
crv = handleToClass(slot, handle, &object->objclass);
if (crv != CKR_OK) {
- goto loser;
+ goto loser;
}
object->slot = slot;
object->objectInfo = NULL;
object->infoFree = NULL;
if (!hasLocks) {
- object->refLock = PZ_NewLock(nssILockRefLock);
+ object->refLock = PZ_NewLock(nssILockRefLock);
}
if (object->refLock == NULL) {
- goto loser;
+ goto loser;
}
object->refCount = 1;
return object;
loser:
- if (object) {
- (void) sftk_DestroyObject(object);
- }
+ (void)sftk_DestroyObject(object);
return NULL;
-
}
SFTKTokenObject *
@@ -1947,18 +1964,18 @@ sftk_convertSessionToToken(SFTKObject *obj)
sftk_DestroySessionObjectData(so);
PZ_DestroyLock(so->attributeLock);
if (to == NULL) {
- return NULL;
+ return NULL;
}
sftk_tokenKeyLock(so->obj.slot);
- key = sftk_lookupTokenKeyByHandle(so->obj.slot,so->obj.handle);
+ key = sftk_lookupTokenKeyByHandle(so->obj.slot, so->obj.handle);
if (key == NULL) {
- sftk_tokenKeyUnlock(so->obj.slot);
- return NULL;
+ sftk_tokenKeyUnlock(so->obj.slot);
+ return NULL;
}
- rv = SECITEM_CopyItem(NULL,&to->dbKey,key);
+ rv = SECITEM_CopyItem(NULL, &to->dbKey, key);
sftk_tokenKeyUnlock(so->obj.slot);
if (rv == SECFailure) {
- return NULL;
+ return NULL;
}
return to;
@@ -1975,4 +1992,3 @@ sftk_narrowToTokenObject(SFTKObject *obj)
{
return sftk_isToken(obj->handle) ? (SFTKTokenObject *)obj : NULL;
}
-
diff --git a/nss/lib/softoken/sdb.c b/nss/lib/softoken/sdb.c
index 1684860..0e321dd 100644
--- a/nss/lib/softoken/sdb.c
+++ b/nss/lib/softoken/sdb.c
@@ -6,11 +6,11 @@
*
* 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
+ * 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
+ * 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.
*
@@ -47,16 +47,16 @@
*/
static PRLock *sqlite_lock = NULL;
-#define LOCK_SQLITE() PR_Lock(sqlite_lock);
-#define UNLOCK_SQLITE() PR_Unlock(sqlite_lock);
+#define LOCK_SQLITE() PR_Lock(sqlite_lock);
+#define UNLOCK_SQLITE() PR_Unlock(sqlite_lock);
#else
-#define LOCK_SQLITE()
-#define UNLOCK_SQLITE()
+#define LOCK_SQLITE()
+#define UNLOCK_SQLITE()
#endif
typedef enum {
- SDB_CERT = 1,
- SDB_KEY = 2
+ SDB_CERT = 1,
+ SDB_KEY = 2
} sdbDataType;
/*
@@ -70,19 +70,19 @@ typedef enum {
* 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
+ * 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:
+ *
+ * total wait time for automatic operations:
* 1 second (SDB_SQLITE_BUSY_TIMEOUT/1000).
- * total wait time for manual operations:
+ * 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
+#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
@@ -98,20 +98,20 @@ typedef enum {
* 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 */
+ 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;
@@ -130,7 +130,7 @@ static const CK_ATTRIBUTE_TYPE known_attributes[] = {
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_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,
@@ -156,8 +156,8 @@ static const CK_ATTRIBUTE_TYPE known_attributes[] = {
CKA_NETSCAPE_DB, CKA_NETSCAPE_TRUST, CKA_NSS_OVERRIDE_EXTENSIONS
};
-static int known_attributes_size= sizeof(known_attributes)/
- sizeof(known_attributes[0]);
+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
@@ -172,20 +172,20 @@ const unsigned char SQLITE_EXPLICIT_NULL[] = { 0xa5, 0x0, 0x5a };
/*
* determine when we've completed our tasks
*/
-static int
+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;
+ *count = 0;
+ return 0;
}
if (err != SQLITE_BUSY) {
- return 1;
+ return 1;
}
/* err == SQLITE_BUSY, Dont' retry forever in this case */
if (++(*count) >= SDB_MAX_BUSY_RETRIES) {
- return 1;
+ return 1;
}
return 0;
}
@@ -228,21 +228,25 @@ sdb_getFallbackTempDir(void)
"/var/tmp",
"/usr/tmp",
"/tmp",
- NULL /* List terminator */
+ NULL /* List terminator */
};
unsigned int i;
struct stat buf;
const char *zDir = NULL;
azDirs[0] = sqlite3_temp_directory;
- azDirs[1] = getenv("TMPDIR");
+ azDirs[1] = PR_GetEnvSecure("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;
+ if (zDir == NULL)
+ continue;
+ if (stat(zDir, &buf))
+ continue;
+ if (!S_ISDIR(buf.st_mode))
+ continue;
+ if (access(zDir, 07))
+ continue;
break;
}
@@ -269,33 +273,33 @@ sdb_getTempDir(sqlite3 *sqlDB)
/* Obtain temporary filename in sqlite's directory for temporary tables */
sqlrv = sqlite3_file_control(sqlDB, 0, SQLITE_FCNTL_TEMPFILENAME,
- (void*)&tempName);
+ (void *)&tempName);
if (sqlrv == SQLITE_NOTFOUND) {
- /* SQLITE_FCNTL_TEMPFILENAME not implemented because we are using
- * an older SQLite. */
- return sdb_getFallbackTempDir();
+ /* SQLITE_FCNTL_TEMPFILENAME not implemented because we are using
+ * an older SQLite. */
+ return sdb_getFallbackTempDir();
}
if (sqlrv != SQLITE_OK) {
- return NULL;
+ 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);
+ /* 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);
@@ -309,48 +313,46 @@ 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;
+ /* 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)
+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);
+ (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.
@@ -368,7 +370,7 @@ sdb_measureAccess(const char *directory)
/* no directory, just return one */
if (directory == NULL) {
- return 1;
+ return 1;
}
/* our calculation assumes time is a 4 bytes == 32 bit integer */
@@ -376,10 +378,9 @@ sdb_measureAccess(const char *directory)
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 */
+ 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) {
@@ -392,7 +393,7 @@ sdb_measureAccess(const char *directory)
strcpy(temp, directory);
if (directory[directoryLength - 1] != PR_GetDirectorySeparator()) {
- temp[directoryLength++] = PR_GetDirectorySeparator();
+ temp[directoryLength++] = PR_GetDirectorySeparator();
}
tempStartOfFilename = temp + directoryLength;
maxFileNameLen = maxTempLen - directoryLength;
@@ -400,22 +401,22 @@ sdb_measureAccess(const char *directory)
/* 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. */
+ 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;
+ ".%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);
@@ -434,52 +435,52 @@ sdb_measureAccess(const char *directory)
*/
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)";
+ "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)
+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;
+ return CKR_HOST_MEMORY;
}
sqlerr = sqlite3_exec(sqlDB, newStr, NULL, 0, NULL);
sqlite3_free(newStr);
if (sqlerr != SQLITE_OK) {
- return sdb_mapSQLError(type, sqlerr);
+ 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;
+ 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;
+ 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;
+ 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;
+ return CKR_OK;
}
sqlerr = sqlite3_exec(sqlDB, newStr, NULL, 0, NULL);
sqlite3_free(newStr);
@@ -500,24 +501,23 @@ sdb_updateCache(SDBPrivate *sdb_p)
/* drop the old table */
newStr = sqlite3_mprintf(DROP_CACHE_CMD, sdb_p->cacheTable);
if (newStr == NULL) {
- return CKR_HOST_MEMORY;
+ return CKR_HOST_MEMORY;
}
sqlerr = sqlite3_exec(sdb_p->sqlReadDB, newStr, NULL, 0, NULL);
sqlite3_free(newStr);
- if ((sqlerr != SQLITE_OK) && (sqlerr != SQLITE_ERROR )) {
+ 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);
+ 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 );
+ 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();
+ /* we have a new cache! */
+ sdb_p->lastUpdateTime = PR_IntervalNow();
}
return error;
}
@@ -535,12 +535,12 @@ sdb_updateCache(SDBPrivate *sdb_p)
* 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.
+ * 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.
*
@@ -555,7 +555,7 @@ sdb_updateCache(SDBPrivate *sdb_p)
* and read operations return either the physical table or the cache
* depending on whether or not the cache exists.
*/
-static CK_RV
+static CK_RV
sdb_openDBLocal(SDBPrivate *sdb_p, sqlite3 **sqlDB, const char **table)
{
*sqlDB = NULL;
@@ -563,15 +563,15 @@ sdb_openDBLocal(SDBPrivate *sdb_p, sqlite3 **sqlDB, const char **table)
PR_EnterMonitor(sdb_p->dbMon);
if (table) {
- *table = sdb_p->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 */
+ *sqlDB = sdb_p->sqlXactDB;
+ /* only one thread can get here, safe to unlock */
PR_ExitMonitor(sdb_p->dbMon);
- return CKR_OK;
+ return CKR_OK;
}
/*
@@ -581,33 +581,32 @@ sdb_openDBLocal(SDBPrivate *sdb_p, sqlite3 **sqlDB, const char **table)
* 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);
+ PRIntervalTime now = PR_IntervalNow();
+ if ((now - sdb_p->lastUpdateTime) > sdb_p->updateInterval) {
+ sdb_updateCache(sdb_p);
}
- *table = sdb_p->cacheTable;
+ *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)
+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 */
+ if (sdb_p->sqlXactDB != sqlDB) {
+ /* if we weren't in a transaction, we got a lock */
PR_ExitMonitor(sdb_p->dbMon);
- }
- return CKR_OK;
+ }
+ return CKR_OK;
}
-
/*
* wrapper to sqlite3_open which also sets the busy_timeout
*/
@@ -623,14 +622,14 @@ sdb_openDB(const char *name, sqlite3 **sqlDB, int flags)
*sqlDB = NULL;
sqlerr = sqlite3_open(name, sqlDB);
if (sqlerr != SQLITE_OK) {
- return sqlerr;
+ return sqlerr;
}
sqlerr = sqlite3_busy_timeout(*sqlDB, SDB_SQLITE_BUSY_TIMEOUT);
if (sqlerr != SQLITE_OK) {
- sqlite3_close(*sqlDB);
- *sqlDB = NULL;
- return sqlerr;
+ sqlite3_close(*sqlDB);
+ *sqlDB = NULL;
+ return sqlerr;
}
return SQLITE_OK;
}
@@ -639,15 +638,16 @@ sdb_openDB(const char *name, sqlite3 **sqlDB, int flags)
* 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) {
+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;
+ return sqlerr;
}
/* if we are in a transaction, we may not be holding the monitor.
@@ -656,9 +656,9 @@ sdb_reopenDBLocal(SDBPrivate *sdb_p, sqlite3 **sqlDB) {
PR_EnterMonitor(sdb_p->dbMon);
/* update our view of the database */
if (sdb_p->sqlReadDB == *sqlDB) {
- sdb_p->sqlReadDB = newDB;
+ sdb_p->sqlReadDB = newDB;
} else if (sdb_p->sqlXactDB == *sqlDB) {
- sdb_p->sqlXactDB = newDB;
+ sdb_p->sqlXactDB = newDB;
}
PR_ExitMonitor(sdb_p->dbMon);
@@ -674,19 +674,18 @@ struct SDBFindStr {
sqlite3_stmt *findstmt;
};
-
-static const char FIND_OBJECTS_CMD[] = "SELECT ALL * FROM %s WHERE %s;";
+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)
+sdb_FindObjectsInit(SDB *sdb, const CK_ATTRIBUTE *template, CK_ULONG count,
+ SDBFind **find)
{
SDBPrivate *sdb_p = sdb->private;
- sqlite3 *sqlDB = NULL;
+ sqlite3 *sqlDB = NULL;
const char *table;
char *newStr, *findStr = NULL;
sqlite3_stmt *findstmt = NULL;
- char *join="";
+ char *join = "";
int sqlerr = SQLITE_OK;
CK_RV error = CKR_OK;
unsigned int i;
@@ -695,74 +694,73 @@ sdb_FindObjectsInit(SDB *sdb, const CK_ATTRIBUTE *template, CK_ULONG count,
*find = NULL;
error = sdb_openDBLocal(sdb_p, &sqlDB, &table);
if (error != CKR_OK) {
- goto loser;
+ 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;
+ 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;
+ error = CKR_HOST_MEMORY;
+ goto loser;
}
if (count == 0) {
- newStr = sqlite3_mprintf(FIND_OBJECTS_ALL_CMD, table);
+ newStr = sqlite3_mprintf(FIND_OBJECTS_ALL_CMD, table);
} else {
- newStr = sqlite3_mprintf(FIND_OBJECTS_CMD, table, findStr);
+ newStr = sqlite3_mprintf(FIND_OBJECTS_CMD, table, findStr);
}
sqlite3_free(findStr);
if (newStr == NULL) {
- error = CKR_HOST_MEMORY;
- goto loser;
+ 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);
+ 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;
- }
+ *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:
+loser:
if (findstmt) {
- sqlite3_reset(findstmt);
- sqlite3_finalize(findstmt);
+ sqlite3_reset(findstmt);
+ sqlite3_finalize(findstmt);
}
if (sqlDB) {
- sdb_closeDBLocal(sdb_p, sqlDB) ;
+ sdb_closeDBLocal(sdb_p, sqlDB);
}
- UNLOCK_SQLITE()
+ UNLOCK_SQLITE()
return error;
}
-
CK_RV
-sdb_FindObjects(SDB *sdb, SDBFind *sdbFind, CK_OBJECT_HANDLE *object,
- CK_ULONG arraySize, CK_ULONG *count)
+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;
@@ -772,29 +770,29 @@ sdb_FindObjects(SDB *sdb, SDBFind *sdbFind, CK_OBJECT_HANDLE *object,
*count = 0;
if (arraySize == 0) {
- return CKR_OK;
+ return CKR_OK;
}
- LOCK_SQLITE()
+ 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));
+ 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;
+ sqlerr = SQLITE_DONE;
}
- UNLOCK_SQLITE()
+ UNLOCK_SQLITE()
return sdb_mapSQLError(sdb_p->type, sqlerr);
}
@@ -807,27 +805,27 @@ sdb_FindObjectsFinal(SDB *sdb, SDBFind *sdbFind)
sqlite3 *sqlDB = sdbFind->sqlDB;
int sqlerr = SQLITE_OK;
- LOCK_SQLITE()
+ LOCK_SQLITE()
if (stmt) {
- sqlite3_reset(stmt);
- sqlerr = sqlite3_finalize(stmt);
+ sqlite3_reset(stmt);
+ sqlerr = sqlite3_finalize(stmt);
}
if (sqlDB) {
- sdb_closeDBLocal(sdb_p, sqlDB) ;
+ sdb_closeDBLocal(sdb_p, sqlDB);
}
PORT_Free(sdbFind);
- UNLOCK_SQLITE()
+ 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)
+sdb_GetAttributeValueNoLock(SDB *sdb, CK_OBJECT_HANDLE object_id,
+ CK_ATTRIBUTE *template, CK_ULONG count)
{
SDBPrivate *sdb_p = sdb->private;
- sqlite3 *sqlDB = NULL;
+ sqlite3 *sqlDB = NULL;
sqlite3_stmt *stmt = NULL;
char *getStr = NULL;
char *newStr = NULL;
@@ -838,125 +836,128 @@ sdb_GetAttributeValueNoLock(SDB *sdb, CK_OBJECT_HANDLE object_id,
int retry = 0;
unsigned 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) {
- unsigned 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;
+ 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) {
+ unsigned 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;
- }
+ 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);
+ sqlite3_reset(stmt);
+ sqlite3_finalize(stmt);
}
/* if we had to open a new database, free it now */
if (sqlDB) {
- sdb_closeDBLocal(sdb_p, 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)
+sdb_GetAttributeValue(SDB *sdb, CK_OBJECT_HANDLE object_id,
+ CK_ATTRIBUTE *template, CK_ULONG count)
{
CK_RV crv;
if (count == 0) {
- return CKR_OK;
+ return CKR_OK;
}
- LOCK_SQLITE()
+ LOCK_SQLITE()
crv = sdb_GetAttributeValueNoLock(sdb, object_id, template, count);
- UNLOCK_SQLITE()
+ 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)
+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 *sqlDB = NULL;
sqlite3_stmt *stmt = NULL;
char *setStr = NULL;
char *newStr = NULL;
@@ -966,82 +967,85 @@ sdb_SetAttributeValue(SDB *sdb, CK_OBJECT_HANDLE object_id,
unsigned int i;
if ((sdb->sdb_flags & SDB_RDONLY) != 0) {
- return CKR_TOKEN_WRITE_PROTECTED;
+ return CKR_TOKEN_WRITE_PROTECTED;
}
if (count == 0) {
- return CKR_OK;
+ return CKR_OK;
}
- LOCK_SQLITE()
+ 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;
+ 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;
+ return CKR_HOST_MEMORY;
}
- newStr = sqlite3_mprintf(SET_ATTRIBUTE_CMD, sdb_p->table, setStr);
+ newStr = sqlite3_mprintf(SET_ATTRIBUTE_CMD, sdb_p->table, setStr);
sqlite3_free(setStr);
if (newStr == NULL) {
- UNLOCK_SQLITE()
- return CKR_HOST_MEMORY;
+ UNLOCK_SQLITE()
+ return CKR_HOST_MEMORY;
}
error = sdb_openDBLocal(sdb_p, &sqlDB, NULL);
if (error != CKR_OK) {
- goto loser;
+ 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;
+ 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 + 1, 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));
+ 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);
+ sqlite3_free(newStr);
}
if (error == CKR_OK) {
- error = sdb_mapSQLError(sdb_p->type, sqlerr);
+ error = sdb_mapSQLError(sdb_p->type, sqlerr);
}
if (stmt) {
- sqlite3_reset(stmt);
- sqlite3_finalize(stmt);
+ sqlite3_reset(stmt);
+ sqlite3_finalize(stmt);
}
if (sqlDB) {
- sdb_closeDBLocal(sdb_p, sqlDB) ;
+ sdb_closeDBLocal(sdb_p, sqlDB);
}
- UNLOCK_SQLITE()
+ UNLOCK_SQLITE()
return error;
}
@@ -1054,9 +1058,9 @@ 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);
+ crv = sdb_GetAttributeValueNoLock(sdb, candidate, &template, 1);
if (crv == CKR_OBJECT_HANDLE_INVALID) {
- return PR_FALSE;
+ return PR_FALSE;
}
return PR_TRUE;
}
@@ -1076,24 +1080,24 @@ sdb_getObjectId(SDB *sdb)
*/
if (next_obj == CK_INVALID_HANDLE) {
PRTime time;
- time = PR_Now();
+ time = PR_Now();
- next_obj = (CK_OBJECT_HANDLE)(time & 0x3fffffffL);
+ 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;
- }
+ /* 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 */
@@ -1102,11 +1106,11 @@ sdb_getObjectId(SDB *sdb)
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)
+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 *sqlDB = NULL;
sqlite3_stmt *stmt = NULL;
char *columnStr = NULL;
char *valueStr = NULL;
@@ -1118,98 +1122,102 @@ sdb_CreateObject(SDB *sdb, CK_OBJECT_HANDLE *object_id,
unsigned int i;
if ((sdb->sdb_flags & SDB_RDONLY) != 0) {
- return CKR_TOKEN_WRITE_PROTECTED;
+ return CKR_TOKEN_WRITE_PROTECTED;
}
- LOCK_SQLITE()
- if ((*object_id != CK_INVALID_HANDLE) &&
- !sdb_objectExists(sdb, *object_id)) {
- this_object = *object_id;
+ LOCK_SQLITE()
+ if ((*object_id != CK_INVALID_HANDLE) &&
+ !sdb_objectExists(sdb, *object_id)) {
+ this_object = *object_id;
} else {
- this_object = sdb_getObjectId(sdb);
+ this_object = sdb_getObjectId(sdb);
}
if (this_object == CK_INVALID_HANDLE) {
- UNLOCK_SQLITE();
- return CKR_HOST_MEMORY;
+ 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;
+ 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);
+ 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;
+ goto loser;
}
sqlerr = sqlite3_prepare_v2(sqlDB, newStr, -1, &stmt, NULL);
- if (sqlerr != SQLITE_OK) goto loser;
+ 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;
+ 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));
+ 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);
+ sqlite3_free(newStr);
}
if (error == CKR_OK) {
- error = sdb_mapSQLError(sdb_p->type, sqlerr);
+ error = sdb_mapSQLError(sdb_p->type, sqlerr);
}
if (stmt) {
- sqlite3_reset(stmt);
- sqlite3_finalize(stmt);
+ sqlite3_reset(stmt);
+ sqlite3_finalize(stmt);
}
if (sqlDB) {
- sdb_closeDBLocal(sdb_p, sqlDB) ;
+ sdb_closeDBLocal(sdb_p, sqlDB);
}
- UNLOCK_SQLITE()
+ 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 *sqlDB = NULL;
sqlite3_stmt *stmt = NULL;
char *newStr = NULL;
int sqlerr = SQLITE_OK;
@@ -1217,51 +1225,54 @@ sdb_DestroyObject(SDB *sdb, CK_OBJECT_HANDLE object_id)
int retry = 0;
if ((sdb->sdb_flags & SDB_RDONLY) != 0) {
- return CKR_TOKEN_WRITE_PROTECTED;
+ return CKR_TOKEN_WRITE_PROTECTED;
}
- LOCK_SQLITE()
+ LOCK_SQLITE()
error = sdb_openDBLocal(sdb_p, &sqlDB, NULL);
if (error != CKR_OK) {
- goto loser;
+ goto loser;
}
- newStr = sqlite3_mprintf(DESTROY_CMD, sdb_p->table);
+ newStr = sqlite3_mprintf(DESTROY_CMD, sdb_p->table);
if (newStr == NULL) {
- error = CKR_HOST_MEMORY;
- goto loser;
+ error = CKR_HOST_MEMORY;
+ goto loser;
}
- sqlerr =sqlite3_prepare_v2(sqlDB, newStr, -1, &stmt, NULL);
+ 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;
+ 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));
+ 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);
+ error = sdb_mapSQLError(sdb_p->type, sqlerr);
}
if (stmt) {
- sqlite3_reset(stmt);
- sqlite3_finalize(stmt);
+ sqlite3_reset(stmt);
+ sqlite3_finalize(stmt);
}
if (sqlDB) {
- sdb_closeDBLocal(sdb_p, sqlDB) ;
+ sdb_closeDBLocal(sdb_p, sqlDB);
}
- UNLOCK_SQLITE()
+ UNLOCK_SQLITE()
return error;
}
-
+
static const char BEGIN_CMD[] = "BEGIN IMMEDIATE TRANSACTION;";
+
/*
* start a transaction.
*
@@ -1273,63 +1284,61 @@ CK_RV
sdb_Begin(SDB *sdb)
{
SDBPrivate *sdb_p = sdb->private;
- sqlite3 *sqlDB = NULL;
+ 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;
+ return CKR_TOKEN_WRITE_PROTECTED;
}
-
- LOCK_SQLITE()
+ 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;
+ goto loser;
}
- sqlerr =sqlite3_prepare_v2(sqlDB, BEGIN_CMD, -1, &stmt, NULL);
+ 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));
+ 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);
+ sqlite3_reset(stmt);
+ sqlite3_finalize(stmt);
}
loser:
error = sdb_mapSQLError(sdb_p->type, sqlerr);
- /* we are starting a new transaction,
+ /* 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();
+ /* 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);
- }
+ /* we failed to start our transaction,
+ * free any databases we opened. */
+ if (sqlDB) {
+ sqlite3_close(sqlDB);
+ }
}
- UNLOCK_SQLITE()
+ UNLOCK_SQLITE()
return error;
}
@@ -1339,19 +1348,18 @@ loser:
* these 2 are what the database will show. (no change in to former, change in
* the latter).
*/
-static CK_RV
+static CK_RV
sdb_complete(SDB *sdb, const char *cmd)
{
SDBPrivate *sdb_p = sdb->private;
- sqlite3 *sqlDB = NULL;
+ 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;
+ return CKR_TOKEN_WRITE_PROTECTED;
}
/* We must have a transation database, or we shouldn't have arrived here */
@@ -1359,40 +1367,40 @@ sdb_complete(SDB *sdb, const char *cmd)
PORT_Assert(sdb_p->sqlXactDB);
if (sdb_p->sqlXactDB == NULL) {
PR_ExitMonitor(sdb_p->dbMon);
- return CKR_GENERAL_ERROR; /* shouldn't happen */
+ return CKR_GENERAL_ERROR; /* shouldn't happen */
}
- PORT_Assert( sdb_p->sqlXactThread == PR_GetCurrentThread());
- if ( sdb_p->sqlXactThread != PR_GetCurrentThread()) {
+ 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 */
+ 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;
+ 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);
+ 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));
+ 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);
+ 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);
+ PR_EnterMonitor(sdb_p->dbMon);
+ sdb_updateCache(sdb_p);
+ PR_ExitMonitor(sdb_p->dbMon);
}
error = sdb_mapSQLError(sdb_p->type, sqlerr);
@@ -1409,9 +1417,9 @@ CK_RV
sdb_Commit(SDB *sdb)
{
CK_RV crv;
- LOCK_SQLITE()
- crv = sdb_complete(sdb,COMMIT_CMD);
- UNLOCK_SQLITE()
+ LOCK_SQLITE()
+ crv = sdb_complete(sdb, COMMIT_CMD);
+ UNLOCK_SQLITE()
return crv;
}
@@ -1420,9 +1428,9 @@ CK_RV
sdb_Abort(SDB *sdb)
{
CK_RV crv;
- LOCK_SQLITE()
- crv = sdb_complete(sdb,ROLLBACK_CMD);
- UNLOCK_SQLITE()
+ LOCK_SQLITE()
+ crv = sdb_complete(sdb, ROLLBACK_CMD);
+ UNLOCK_SQLITE()
return crv;
}
@@ -1433,17 +1441,17 @@ CK_RV
sdb_GetMetaData(SDB *sdb, const char *id, SECItem *item1, SECItem *item2)
{
SDBPrivate *sdb_p = sdb->private;
- sqlite3 *sqlDB = sdb_p->sqlXactDB;
+ 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()
+ LOCK_SQLITE()
error = sdb_openDBLocal(sdb_p, &sqlDB, NULL);
if (error != CKR_OK) {
- goto loser;
+ goto loser;
}
/* handle 'test' versions of the sqlite db */
@@ -1453,77 +1461,79 @@ sdb_GetMetaData(SDB *sdb, const char *id, SECItem *item1, SECItem *item2)
* 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);
+ 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;
+ 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));
+ 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;
- }
+ 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);
+ sqlite3_reset(stmt);
+ sqlite3_finalize(stmt);
}
if (sqlDB) {
- sdb_closeDBLocal(sdb_p, sqlDB) ;
+ sdb_closeDBLocal(sdb_p, sqlDB);
}
- UNLOCK_SQLITE()
+ UNLOCK_SQLITE()
return error;
}
static const char PW_CREATE_TABLE_CMD[] =
- "CREATE TABLE metaData (id PRIMARY KEY UNIQUE ON CONFLICT REPLACE, item1, item2);";
+ "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);";
+ "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)
+sdb_PutMetaData(SDB *sdb, const char *id, const SECItem *item1,
+ const SECItem *item2)
{
SDBPrivate *sdb_p = sdb->private;
- sqlite3 *sqlDB = sdb_p->sqlXactDB;
+ sqlite3 *sqlDB = sdb_p->sqlXactDB;
sqlite3_stmt *stmt = NULL;
int sqlerr = SQLITE_OK;
CK_RV error = CKR_OK;
@@ -1531,56 +1541,61 @@ sdb_PutMetaData(SDB *sdb, const char *id, const SECItem *item1,
const char *cmd = PW_CREATE_CMD;
if ((sdb->sdb_flags & SDB_RDONLY) != 0) {
- return CKR_TOKEN_WRITE_PROTECTED;
+ return CKR_TOKEN_WRITE_PROTECTED;
}
- LOCK_SQLITE()
+ LOCK_SQLITE()
error = sdb_openDBLocal(sdb_p, &sqlDB, NULL);
if (error != CKR_OK) {
- goto loser;
+ goto loser;
}
if (!tableExists(sqlDB, "metaData")) {
- sqlerr = sqlite3_exec(sqlDB, PW_CREATE_TABLE_CMD, NULL, 0, NULL);
- if (sqlerr != SQLITE_OK) goto loser;
+ sqlerr = sqlite3_exec(sqlDB, PW_CREATE_TABLE_CMD, NULL, 0, NULL);
+ if (sqlerr != SQLITE_OK)
+ goto loser;
}
if (item2 == NULL) {
- cmd = MD_CREATE_CMD;
+ cmd = MD_CREATE_CMD;
}
sqlerr = sqlite3_prepare_v2(sqlDB, cmd, -1, &stmt, NULL);
- if (sqlerr != SQLITE_OK) goto loser;
+ if (sqlerr != SQLITE_OK)
+ goto loser;
sqlerr = sqlite3_bind_text(stmt, 1, id, PORT_Strlen(id), SQLITE_STATIC);
- if (sqlerr != SQLITE_OK) goto loser;
+ 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 (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;
+ 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));
+ 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);
+ error = sdb_mapSQLError(sdb_p->type, sqlerr);
}
if (stmt) {
- sqlite3_reset(stmt);
- sqlite3_finalize(stmt);
+ sqlite3_reset(stmt);
+ sqlite3_finalize(stmt);
}
if (sqlDB) {
- sdb_closeDBLocal(sdb_p, sqlDB) ;
+ sdb_closeDBLocal(sdb_p, sqlDB);
}
- UNLOCK_SQLITE()
+ UNLOCK_SQLITE()
return error;
}
@@ -1590,54 +1605,54 @@ CK_RV
sdb_Reset(SDB *sdb)
{
SDBPrivate *sdb_p = sdb->private;
- sqlite3 *sqlDB = NULL;
+ 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;
+ return CKR_OBJECT_HANDLE_INVALID;
}
- LOCK_SQLITE()
+ LOCK_SQLITE()
error = sdb_openDBLocal(sdb_p, &sqlDB, NULL);
if (error != CKR_OK) {
- goto loser;
+ goto loser;
}
/* delete the key table */
- newStr = sqlite3_mprintf(RESET_CMD, sdb_p->table);
+ newStr = sqlite3_mprintf(RESET_CMD, sdb_p->table);
if (newStr == NULL) {
- error = CKR_HOST_MEMORY;
- goto loser;
+ error = CKR_HOST_MEMORY;
+ goto loser;
}
sqlerr = sqlite3_exec(sqlDB, newStr, NULL, 0, NULL);
sqlite3_free(newStr);
- if (sqlerr != SQLITE_OK) goto loser;
+ if (sqlerr != SQLITE_OK)
+ goto loser;
/* delete the password entry table */
- sqlerr = sqlite3_exec(sqlDB, "DROP TABLE IF EXISTS metaData;",
+ 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);
+ error = sdb_mapSQLError(sdb_p->type, sqlerr);
}
if (sqlDB) {
- sdb_closeDBLocal(sdb_p, sqlDB) ;
+ sdb_closeDBLocal(sdb_p, sqlDB);
}
- UNLOCK_SQLITE()
+ UNLOCK_SQLITE()
return error;
}
-
-CK_RV
-sdb_Close(SDB *sdb)
+CK_RV
+sdb_Close(SDB *sdb)
{
SDBPrivate *sdb_p = sdb->private;
int sqlerr = SQLITE_OK;
@@ -1646,30 +1661,31 @@ sdb_Close(SDB *sdb)
sqlerr = sqlite3_close(sdb_p->sqlReadDB);
PORT_Free(sdb_p->sqlDBName);
if (sdb_p->cacheTable) {
- sqlite3_free(sdb_p->cacheTable);
+ sqlite3_free(sdb_p->cacheTable);
}
if (sdb_p->dbMon) {
- PR_DestroyMonitor(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)
+static int
+tableExists(sqlite3 *sqlDB, const char *tableName)
{
- char * cmd = sqlite3_mprintf(CHECK_TABLE_CMD, tableName);
+ char *cmd = sqlite3_mprintf(CHECK_TABLE_CMD, tableName);
int sqlerr = SQLITE_OK;
if (cmd == NULL) {
- return 0;
+ return 0;
}
sqlerr = sqlite3_exec(sqlDB, cmd, NULL, 0, 0);
@@ -1678,7 +1694,8 @@ static int tableExists(sqlite3 *sqlDB, const char *tableName)
return (sqlerr == SQLITE_OK) ? 1 : 0;
}
-void sdb_SetForkState(PRBool forked)
+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.
@@ -1690,11 +1707,11 @@ void sdb_SetForkState(PRBool forked)
* initialize a single database
*/
static const char INIT_CMD[] =
- "CREATE TABLE %s (id PRIMARY KEY UNIQUE ON CONFLICT ABORT%s)";
+ "CREATE TABLE %s (id PRIMARY KEY UNIQUE ON CONFLICT ABORT%s)";
-CK_RV
+CK_RV
sdb_init(char *dbname, char *table, sdbDataType type, int *inUpdate,
- int *newInit, int flags, PRUint32 accessOps, SDB **pSdb)
+ int *newInit, int inFlags, PRUint32 accessOps, SDB **pSdb)
{
int i;
char *initStr = NULL;
@@ -1710,117 +1727,123 @@ sdb_init(char *dbname, char *table, sdbDataType type, int *inUpdate,
char *env;
PRBool enableCache = PR_FALSE;
PRBool create;
+ int flags = inFlags & 0x7;
*pSdb = NULL;
*inUpdate = 0;
- /* sqlite3 doesn't have a flag to specify that we want to
+ /* 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;
+ 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;
+ 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);
+
+ /*
+ * SQL created the file, but it doesn't set appropriate modes for
+ * a database.
+ *
+ * NO NSPR call for chmod? :(
+ */
+ if (create && chmod(dbname, 0600) != 0) {
+ error = sdb_mapSQLError(type, SQLITE_CANTOPEN);
+ goto loser;
}
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) {
+ 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;
- }
- 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) {
+ 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_SUBJECT_INDEX_CMD, table);
- if (newStr == NULL) {
+ 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) {
+ 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) {
+ 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;
- }
+ 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
@@ -1833,22 +1856,22 @@ sdb_init(char *dbname, char *table, sdbDataType type, int *inUpdate,
* on noticing that the cert database didn't exist (see newInit set above).
*/
if (type == SDB_KEY && !tableExists(sqlDB, "metaData")) {
- *newInit = 1;
+ *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
+ * 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
+ * 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.
*
@@ -1859,56 +1882,56 @@ sdb_init(char *dbname, char *table, sdbDataType type, int *inUpdate,
* always be used.
*
* It is expected that most applications would use the "auto" selection,
- * the environment variable is primarily to simplify testing, and to
+ * 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);
- }
+ env = PR_GetEnvSecure("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,
+ /* 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();
+ 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));
+ sdb = (SDB *)malloc(sizeof(SDB));
+ sdb_p = (SDBPrivate *)malloc(sizeof(SDBPrivate));
/* invariant fields */
sdb_p->sqlDBName = PORT_Strdup(dbname);
@@ -1918,14 +1941,14 @@ sdb_init(char *dbname, char *table, sdbDataType type, int *inUpdate,
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->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->sdb_flags = inFlags | SDB_HAS_META;
sdb->app_private = NULL;
sdb->sdb_FindObjectsInit = sdb_FindObjectsInit;
sdb->sdb_FindObjects = sdb_FindObjects;
@@ -1944,12 +1967,12 @@ sdb_init(char *dbname, char *table, sdbDataType type, int *inUpdate,
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;
+ 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;
@@ -1961,50 +1984,48 @@ sdb_init(char *dbname, char *table, sdbDataType type, int *inUpdate,
loser:
/* lots of stuff to do */
if (inTransaction) {
- sqlite3_exec(sqlDB, ROLLBACK_CMD, NULL, 0, NULL);
+ sqlite3_exec(sqlDB, ROLLBACK_CMD, NULL, 0, NULL);
}
if (sdb) {
- free(sdb);
+ free(sdb);
}
if (sdb_p) {
- free(sdb_p);
+ free(sdb_p);
}
if (sqlDB) {
- sqlite3_close(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)
+ int cert_version, int key_version, int flags,
+ SDB **certdb, SDB **keydb, int *newInit)
{
char *cert = sdb_BuildFileName(directory, certPrefix,
- "cert", cert_version);
+ "cert", cert_version);
char *key = sdb_BuildFileName(directory, keyPrefix,
- "key", key_version);
+ "key", key_version);
CK_RV error = CKR_OK;
int inUpdate;
PRUint32 accessOps;
- if (certdb)
- *certdb = NULL;
- if (keydb)
- *keydb = NULL;
+ 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;
- }
+ sqlite_lock = PR_NewLock();
+ if (sqlite_lock == NULL) {
+ error = CKR_HOST_MEMORY;
+ goto loser;
+ }
}
#endif
@@ -2013,12 +2034,12 @@ s_open(const char *directory, const char *certPrefix, const char *keyPrefix,
accessOps = 1;
{
char *env;
- env = PR_GetEnv("NSS_SDB_USE_CACHE");
+ env = PR_GetEnvSecure("NSS_SDB_USE_CACHE");
/* If the environment variable is set to yes or no, sdb_init() will
* ignore the value of accessOps, and we can skip the measuring.*/
if (!env || ((PORT_Strcasecmp(env, "no") != 0) &&
- (PORT_Strcasecmp(env, "yes") != 0))){
- accessOps = sdb_measureAccess(directory);
+ (PORT_Strcasecmp(env, "yes") != 0))) {
+ accessOps = sdb_measureAccess(directory);
}
}
@@ -2026,16 +2047,16 @@ s_open(const char *directory, const char *certPrefix, const char *keyPrefix,
* 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;
- }
+ /* 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:
+ * open the key data base:
* NOTE:if we want to implement a single database, we open
* the same database file as the certificate here.
*
@@ -2043,32 +2064,31 @@ s_open(const char *directory, const char *certPrefix, const char *keyPrefix,
* 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;
- }
+ /* 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);
+ sqlite3_free(cert);
}
if (key) {
- sqlite3_free(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);
- }
+ /* 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;
@@ -2079,8 +2099,8 @@ s_shutdown()
{
#ifdef SQLITE_UNSAFE_THREADS
if (sqlite_lock) {
- PR_DestroyLock(sqlite_lock);
- sqlite_lock = NULL;
+ PR_DestroyLock(sqlite_lock);
+ sqlite_lock = NULL;
}
#endif
return CKR_OK;
diff --git a/nss/lib/softoken/sdb.h b/nss/lib/softoken/sdb.h
index 2a855fb..04b873e 100644
--- a/nss/lib/softoken/sdb.h
+++ b/nss/lib/softoken/sdb.h
@@ -6,11 +6,11 @@
*
* 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
+ * 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
+ * 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.
*
@@ -35,44 +35,59 @@ typedef struct SDBStr SDB;
struct SDBStr {
void *private;
- int version;
- int reserved;
- int sdb_flags;
+ 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);
+ 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_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
+#define SDB_RDONLY 1
+#define SDB_RDWR 2
+#define SDB_CREATE 4
+#define SDB_HAS_META 8
+#define SDB_FIPS 0x10
#endif
diff --git a/nss/lib/softoken/sftkdb.c b/nss/lib/softoken/sftkdb.c
index 61f1e9e..52e5161 100644
--- a/nss/lib/softoken/sftkdb.c
+++ b/nss/lib/softoken/sftkdb.c
@@ -1,28 +1,28 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.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
+ * 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
+ * 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 "prprf.h"
#include "pratom.h"
#include "lgglue.h"
#include "utilpars.h"
@@ -41,84 +41,83 @@
#define BBP 8
static PRBool
-sftkdb_isULONGAttribute(CK_ATTRIBUTE_TYPE type)
+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;
+ 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)
+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;
+ 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)
+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;
+ 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;
}
@@ -129,11 +128,11 @@ sftkdb_isAuthenticatedAttribute(CK_ATTRIBUTE_TYPE type)
*/
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;
+ for (i = 0; i < SDB_ULONG_SIZE; i++) {
+ data[i] = (value >> (SDB_ULONG_SIZE - 1 - i) * BBP) & 0xff;
}
}
@@ -147,8 +146,8 @@ 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);
+ for (i = 0; i < SDB_ULONG_SIZE; i++) {
+ value |= (((CK_ULONG)data[i]) << (SDB_ULONG_SIZE - 1 - i) * BBP);
}
return value;
}
@@ -159,8 +158,8 @@ sftk_SDBULong2ULong(unsigned char *data)
* 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)
+sftkdb_fixupTemplateIn(const CK_ATTRIBUTE *template, int count,
+ unsigned char **dataOut)
{
int i;
int ulongCount = 0;
@@ -170,56 +169,55 @@ sftkdb_fixupTemplateIn(const CK_ATTRIBUTE *template, int count,
*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++;
- }
- }
+ 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;
+ return (CK_ATTRIBUTE *)template;
}
/* allocate space for new ULONGS */
- data = (unsigned char *)PORT_Alloc(SDB_ULONG_SIZE*ulongCount);
+ data = (unsigned char *)PORT_Alloc(SDB_ULONG_SIZE * ulongCount);
if (!data) {
- return NULL;
+ return NULL;
}
/* allocate new template */
- ntemplate = PORT_NewArray(CK_ATTRIBUTE,count);
+ ntemplate = PORT_NewArray(CK_ATTRIBUTE, count);
if (!ntemplate) {
- PORT_Free(data);
- return NULL;
+ 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;
- }
- }
+ 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";
/*
@@ -228,7 +226,7 @@ static const char SFTKDB_META_SIG_TEMPLATE[] = "sig_%s_%08x_%08x";
const char *
sftkdb_TypeString(SFTKDBHandle *handle)
{
- return (handle->type == SFTK_KEYDB_TYPE) ? "key" : "cert";
+ return (handle->type == SFTK_KEYDB_TYPE) ? "key" : "cert";
}
/*
@@ -244,9 +242,9 @@ sftkdb_TypeString(SFTKDBHandle *handle)
* 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)
+sftkdb_getAttributeSignature(SFTKDBHandle *handle, SFTKDBHandle *keyHandle,
+ CK_OBJECT_HANDLE objectID, CK_ATTRIBUTE_TYPE type,
+ SECItem *signText)
{
SDB *db;
char id[30];
@@ -255,8 +253,8 @@ sftkdb_getAttributeSignature(SFTKDBHandle *handle, SFTKDBHandle *keyHandle,
db = SFTK_GET_SDB(keyHandle);
sprintf(id, SFTKDB_META_SIG_TEMPLATE,
- sftkdb_TypeString(handle),
- (unsigned int)objectID, (unsigned int)type);
+ sftkdb_TypeString(handle),
+ (unsigned int)objectID, (unsigned int)type);
crv = (*db->sdb_GetMetaData)(db, id, signText, NULL);
return crv;
@@ -273,16 +271,16 @@ sftkdb_getAttributeSignature(SFTKDBHandle *handle, SFTKDBHandle *keyHandle,
* This function stores that pkcs5 signature.
*/
CK_RV
-sftkdb_PutAttributeSignature(SFTKDBHandle *handle, SDB *keyTarget,
- CK_OBJECT_HANDLE objectID, CK_ATTRIBUTE_TYPE type,
- SECItem *signText)
+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);
+ sftkdb_TypeString(handle),
+ (unsigned int)objectID, (unsigned int)type);
crv = (*keyTarget->sdb_PutMetaData)(keyTarget, id, signText, NULL);
return crv;
@@ -294,7 +292,7 @@ sftkdb_PutAttributeSignature(SFTKDBHandle *handle, SDB *keyTarget,
*/
static CK_RV
sftkdb_fixupTemplateOut(CK_ATTRIBUTE *template, CK_OBJECT_HANDLE objectID,
- CK_ATTRIBUTE *ntemplate, int count, SFTKDBHandle *handle)
+ CK_ATTRIBUTE *ntemplate, int count, SFTKDBHandle *handle)
{
int i;
CK_RV crv = CKR_OK;
@@ -307,130 +305,130 @@ sftkdb_fixupTemplateOut(CK_ATTRIBUTE *template, CK_OBJECT_HANDLE objectID,
/* 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;
-
- 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 */
- }
+ 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;
+
+ 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;
}
@@ -446,15 +444,15 @@ sftkdb_fixupTemplateOut(CK_ATTRIBUTE *template, CK_OBJECT_HANDLE objectID,
* 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
+ * 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.
+ * 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.
@@ -468,10 +466,10 @@ sftkdb_fixupTemplateOut(CK_ATTRIBUTE *template, CK_OBJECT_HANDLE objectID,
* 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)
+sftk_signTemplate(PLArenaPool *arena, SFTKDBHandle *handle,
+ PRBool mayBeUpdateDB,
+ CK_OBJECT_HANDLE objectID, const CK_ATTRIBUTE *template,
+ CK_ULONG count)
{
unsigned int i;
CK_RV crv;
@@ -483,112 +481,111 @@ sftk_signTemplate(PLArenaPool *arena, SFTKDBHandle *handle,
PORT_Assert(handle);
if (handle->type != SFTK_KEYDB_TYPE) {
- keyHandle = handle->peerDB;
- usingPeerDB = PR_TRUE;
+ keyHandle = handle->peerDB;
+ usingPeerDB = PR_TRUE;
}
/* no key DB defined? then no need to sign anything */
if (keyHandle == NULL) {
- crv = CKR_OK;
- goto loser;
+ crv = CKR_OK;
+ goto loser;
}
- /* When we are in a middle of an update, we have an update database set,
+ /* 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;
+ 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;
+ 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 = (*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;
+ 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;
+ /* 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(PLArenaPool *arena, SFTKDBHandle *handle,
- SDB *db, CK_OBJECT_HANDLE *objectID,
- CK_ATTRIBUTE *template, CK_ULONG count)
+ SDB *db, CK_OBJECT_HANDLE *objectID,
+ CK_ATTRIBUTE *template, CK_ULONG count)
{
CK_RV crv;
crv = (*db->sdb_CreateObject)(db, objectID, template, count);
if (crv != CKR_OK) {
- goto loser;
+ goto loser;
}
crv = sftk_signTemplate(arena, handle, (db == handle->update),
- *objectID, template, count);
+ *objectID, template, count);
loser:
return crv;
}
-
-CK_ATTRIBUTE *
-sftk_ExtractTemplate(PLArenaPool *arena, SFTKObject *object,
- SFTKDBHandle *handle,CK_ULONG *pcount,
- CK_RV *crv)
+CK_ATTRIBUTE *
+sftk_ExtractTemplate(PLArenaPool *arena, SFTKObject *object,
+ SFTKDBHandle *handle, CK_ULONG *pcount,
+ CK_RV *crv)
{
unsigned int count;
CK_ATTRIBUTE *template;
@@ -599,94 +596,93 @@ sftk_ExtractTemplate(PLArenaPool *arena, SFTKObject *object,
*crv = CKR_OK;
if (sessObject == NULL) {
- *crv = CKR_GENERAL_ERROR; /* internal programming error */
- return 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;
+ 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++;
- }
+ 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;
+ *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);
- }
- }
+ 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;
+ return NULL;
}
if (pcount) {
- *pcount = count;
+ *pcount = count;
}
return template;
-
}
/*
@@ -696,41 +692,40 @@ sftk_ExtractTemplate(PLArenaPool *arena, SFTKObject *object,
* modify the actual value in the template.
*/
static CK_ATTRIBUTE *
-sftkdb_getAttributeFromTemplate(CK_ATTRIBUTE_TYPE attribute,
- CK_ATTRIBUTE *ptemplate, CK_ULONG len)
+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];
- }
+ 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)
+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];
- }
+ 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 *findTemplate, CK_ULONG *findCount,
+ CK_ATTRIBUTE *ptemplate, int len)
{
CK_ATTRIBUTE *attr;
CK_ULONG count = 1;
@@ -741,69 +736,69 @@ sftkdb_getFindTemplate(CK_OBJECT_CLASS objectType, unsigned char *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;
+ 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;
@@ -815,8 +810,8 @@ sftkdb_getFindTemplate(CK_OBJECT_CLASS objectType, unsigned char *objTypeData,
* it does.
*/
static CK_RV
-sftkdb_lookupObject(SDB *db, CK_OBJECT_CLASS objectType,
- CK_OBJECT_HANDLE *id, CK_ATTRIBUTE *ptemplate, CK_ULONG len)
+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;
@@ -827,49 +822,48 @@ sftkdb_lookupObject(SDB *db, CK_OBJECT_CLASS objectType,
*id = CK_INVALID_HANDLE;
if (objectType == CKO_NSS_CRL) {
- return CKR_OK;
+ return CKR_OK;
}
crv = sftkdb_getFindTemplate(objectType, objTypeData,
- findTemplate, &count, ptemplate, len);
+ 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;
+ /* 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;
+ 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;
+ return crv;
}
(*db->sdb_FindObjects)(db, find, id, 1, &objCount);
(*db->sdb_FindObjectsFinal)(db, find);
if (objCount == 0) {
- *id = CK_INVALID_HANDLE;
+ *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)
+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
+ /* 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 *temp1 = NULL;
unsigned char *temp2 = NULL;
CK_ULONG objCount = 0;
SDBFind *find = NULL;
@@ -878,52 +872,52 @@ sftkdb_checkConflicts(SDB *db, CK_OBJECT_CLASS objectType,
CK_RV crv;
CK_ATTRIBUTE subject;
- /* Currently the only conflict is with nicknames pointing to the same
+ /* 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;
+ 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;
+ 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;
- }
+ 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;
- }
-
+ /* 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;
@@ -933,65 +927,64 @@ sftkdb_checkConflicts(SDB *db, CK_OBJECT_CLASS objectType,
crv = (*db->sdb_FindObjectsInit)(db, findTemplate, 2, &find);
if (crv != CKR_OK) {
- goto done;
+ goto done;
}
(*db->sdb_FindObjects)(db, find, &id, 1, &objCount);
(*db->sdb_FindObjectsFinal)(db, find);
- /* object count == 0 means no conflicting certs found,
+ /* object count == 0 means no conflicting certs found,
* go on with the operation */
if (objCount == 0) {
- crv = CKR_OK;
- goto done;
+ 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
+ /* 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 = 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.
+ 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;
+ 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
+ /* 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 */
+ crv = CKR_GENERAL_ERROR; /* clearly a programming error */
}
- /* exit point if we found a conflict */
+/* exit point if we found a conflict */
loser:
PORT_Free(temp1);
PORT_Free(temp2);
@@ -999,20 +992,20 @@ loser:
}
/*
- * try to update the template to fix any errors. This is only done
+ * 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
+ * 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.
+ * 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(PLArenaPool *arena, CK_OBJECT_CLASS objectType,
- CK_ATTRIBUTE *ptemplate, CK_ULONG *plen)
+ CK_ATTRIBUTE *ptemplate, CK_ULONG *plen)
{
CK_ATTRIBUTE *attr;
char *nickname, *newNickname;
@@ -1020,11 +1013,11 @@ sftkdb_resolveConflicts(PLArenaPool *arena, CK_OBJECT_CLASS objectType,
/* sanity checks. We should never get here with these errors */
if (objectType != CKO_CERTIFICATE) {
- return CKR_GENERAL_ERROR; /* shouldn't happen */
+ 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 */
+ return CKR_GENERAL_ERROR; /* shouldn't happen */
}
/* update the nickname */
@@ -1033,49 +1026,50 @@ sftkdb_resolveConflicts(PLArenaPool *arena, CK_OBJECT_CLASS objectType,
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 */ ;
+ 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 */
+ 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;
+ /* ... 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; end-- > 0;) {
- digit = nickname[end];
+ digit = nickname[end];
if (digit > '9' || digit < '0') {
- break;
+ break;
}
- if (digit < '9') {
- nickname[end]++;
- return CKR_OK;
- }
- nickname[end] = '0';
+ 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;
+ 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);
+ PORT_Memset(&newNickname[end + 1], '0', attr->ulValueLen - end);
attr->pValue = newNickname;
attr->ulValueLen++;
return CKR_OK;
@@ -1086,16 +1080,16 @@ sftkdb_resolveConflicts(PLArenaPool *arena, CK_OBJECT_CLASS objectType,
*/
static CK_RV
sftkdb_setAttributeValue(PLArenaPool *arena, SFTKDBHandle *handle,
- SDB *db, CK_OBJECT_HANDLE objectID, const CK_ATTRIBUTE *template,
- CK_ULONG count)
+ 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;
+ return crv;
}
- crv = sftk_signTemplate(arena, handle, db == handle->update,
- objectID, template, count);
+ crv = sftk_signTemplate(arena, handle, db == handle->update,
+ objectID, template, count);
return crv;
}
@@ -1103,8 +1097,8 @@ sftkdb_setAttributeValue(PLArenaPool *arena, SFTKDBHandle *handle,
* write a softoken object out to the database.
*/
CK_RV
-sftkdb_write(SFTKDBHandle *handle, SFTKObject *object,
- CK_OBJECT_HANDLE *objectID)
+sftkdb_write(SFTKDBHandle *handle, SFTKObject *object,
+ CK_OBJECT_HANDLE *objectID)
{
CK_ATTRIBUTE *template;
PLArenaPool *arena;
@@ -1117,34 +1111,34 @@ sftkdb_write(SFTKDBHandle *handle, SFTKObject *object,
*objectID = CK_INVALID_HANDLE;
if (handle == NULL) {
- return CKR_TOKEN_WRITE_PROTECTED;
+ 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 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;
+ return CKR_USER_NOT_LOGGED_IN;
}
arena = PORT_NewArena(256);
- if (arena == NULL) {
- return CKR_HOST_MEMORY;
+ if (arena == NULL) {
+ return CKR_HOST_MEMORY;
}
template = sftk_ExtractTemplate(arena, object, handle, &count, &crv);
if (!template) {
- goto loser;
+ goto loser;
}
crv = (*db->sdb_Begin)(db);
if (crv != CKR_OK) {
- goto loser;
+ goto loser;
}
inTransaction = PR_TRUE;
@@ -1152,9 +1146,9 @@ sftkdb_write(SFTKDBHandle *handle, SFTKObject *object,
* 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
+ * 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.
*
@@ -1165,24 +1159,24 @@ sftkdb_write(SFTKDBHandle *handle, SFTKObject *object,
/* make sure we don't have attributes that conflict with the existing DB */
crv = sftkdb_checkConflicts(db, object->objclass, template, count,
- CK_INVALID_HANDLE);
+ CK_INVALID_HANDLE);
if (crv != CKR_OK) {
- goto loser;
+ 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;
+ 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;
+ /* object already exists, modify it's attributes */
+ *objectID = id;
crv = sftkdb_setAttributeValue(arena, handle, db, id, template, count);
}
if (crv != CKR_OK) {
- goto loser;
+ goto loser;
}
crv = (*db->sdb_Commit)(db);
@@ -1190,27 +1184,27 @@ sftkdb_write(SFTKDBHandle *handle, SFTKObject *object,
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;
+ (*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);
+ PORT_FreeArena(arena, PR_FALSE);
}
if (crv == CKR_OK) {
- *objectID |= (handle->type | SFTK_TOKEN_TYPE);
- }
+ *objectID |= (handle->type | SFTK_TOKEN_TYPE);
+ }
return crv;
}
-
-CK_RV
+CK_RV
sftkdb_FindObjectsInit(SFTKDBHandle *handle, const CK_ATTRIBUTE *template,
- CK_ULONG count, SDBFind **find)
+ CK_ULONG count, SDBFind **find)
{
unsigned char *data = NULL;
CK_ATTRIBUTE *ntemplate = NULL;
@@ -1218,55 +1212,56 @@ sftkdb_FindObjectsInit(SFTKDBHandle *handle, const CK_ATTRIBUTE *template,
SDB *db;
if (handle == NULL) {
- return CKR_OK;
+ return CKR_OK;
}
db = SFTK_GET_SDB(handle);
- if (count != 0) {
- ntemplate = sftkdb_fixupTemplateIn(template, count, &data);
- if (ntemplate == NULL) {
- return CKR_HOST_MEMORY;
- }
+ if (count != 0) {
+ ntemplate = sftkdb_fixupTemplateIn(template, count, &data);
+ if (ntemplate == NULL) {
+ return CKR_HOST_MEMORY;
+ }
}
-
- crv = (*db->sdb_FindObjectsInit)(db, ntemplate,
- count, find);
+
+ crv = (*db->sdb_FindObjectsInit)(db, ntemplate,
+ count, find);
if (data) {
- PORT_Free(ntemplate);
- PORT_Free(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
+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;
+ *count = 0;
+ return CKR_OK;
}
db = SFTK_GET_SDB(handle);
- crv = (*db->sdb_FindObjects)(db, find, ids,
- arraySize, count);
+ crv = (*db->sdb_FindObjects)(db, find, ids,
+ arraySize, count);
if (crv == CKR_OK) {
- unsigned int i;
- for (i=0; i < *count; i++) {
- ids[i] |= (handle->type | SFTK_TOKEN_TYPE);
- }
+ unsigned 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)
+CK_RV
+sftkdb_FindObjectsFinal(SFTKDBHandle *handle, SDBFind *find)
{
SDB *db;
if (handle == NULL) {
- return CKR_OK;
+ return CKR_OK;
}
db = SFTK_GET_SDB(handle);
return (*db->sdb_FindObjectsFinal)(db, find);
@@ -1274,72 +1269,72 @@ CK_RV sftkdb_FindObjectsFinal(SFTKDBHandle *handle, SDBFind *find)
CK_RV
sftkdb_GetAttributeValue(SFTKDBHandle *handle, CK_OBJECT_HANDLE objectID,
- CK_ATTRIBUTE *template, CK_ULONG count)
+ CK_ATTRIBUTE *template, CK_ULONG count)
{
- CK_RV crv,crv2;
+ CK_RV crv, crv2;
CK_ATTRIBUTE *ntemplate;
unsigned char *data = NULL;
SDB *db;
if (handle == NULL) {
- return CKR_GENERAL_ERROR;
+ 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;
+ 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;
+ return CKR_OK;
}
ntemplate = sftkdb_fixupTemplateIn(template, count, &data);
if (ntemplate == NULL) {
- return CKR_HOST_MEMORY;
+ 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;
+ 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);
+ PORT_Free(ntemplate);
+ PORT_Free(data);
}
return crv;
-
}
CK_RV
sftkdb_SetAttributeValue(SFTKDBHandle *handle, SFTKObject *object,
- const CK_ATTRIBUTE *template, CK_ULONG count)
+ const CK_ATTRIBUTE *template, CK_ULONG count)
{
CK_ATTRIBUTE *ntemplate;
unsigned char *data = NULL;
@@ -1350,63 +1345,63 @@ sftkdb_SetAttributeValue(SFTKDBHandle *handle, SFTKObject *object,
PRBool inTransaction = PR_FALSE;
if (handle == NULL) {
- return CKR_TOKEN_WRITE_PROTECTED;
+ return CKR_TOKEN_WRITE_PROTECTED;
}
db = SFTK_GET_SDB(handle);
/* nothing to do */
if (count == 0) {
- return CKR_OK;
+ 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 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;
+ return CKR_USER_NOT_LOGGED_IN;
}
ntemplate = sftkdb_fixupTemplateIn(template, count, &data);
if (ntemplate == NULL) {
- return CKR_HOST_MEMORY;
+ 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;
+ goto loser;
}
arena = PORT_NewArena(256);
- if (arena == NULL) {
- crv = CKR_HOST_MEMORY;
- goto loser;
+ if (arena == NULL) {
+ crv = CKR_HOST_MEMORY;
+ goto loser;
}
crv = (*db->sdb_Begin)(db);
if (crv != CKR_OK) {
- goto loser;
+ goto loser;
}
inTransaction = PR_TRUE;
- crv = sftkdb_setAttributeValue(arena, handle, db,
- objectID, template, count);
+ crv = sftkdb_setAttributeValue(arena, handle, db,
+ objectID, template, count);
if (crv != CKR_OK) {
- goto loser;
+ goto loser;
}
crv = (*db->sdb_Commit)(db);
loser:
if (crv != CKR_OK && inTransaction) {
- (*db->sdb_Abort)(db);
+ (*db->sdb_Abort)(db);
}
if (data) {
- PORT_Free(ntemplate);
- PORT_Free(data);
+ PORT_Free(ntemplate);
+ PORT_Free(data);
}
if (arena) {
- PORT_FreeArena(arena, PR_FALSE);
+ PORT_FreeArena(arena, PR_FALSE);
}
return crv;
}
@@ -1418,22 +1413,22 @@ sftkdb_DestroyObject(SFTKDBHandle *handle, CK_OBJECT_HANDLE objectID)
SDB *db;
if (handle == NULL) {
- return CKR_TOKEN_WRITE_PROTECTED;
+ 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;
+ goto loser;
}
crv = (*db->sdb_DestroyObject)(db, objectID);
if (crv != CKR_OK) {
- goto loser;
+ goto loser;
}
crv = (*db->sdb_Commit)(db);
loser:
if (crv != CKR_OK) {
- (*db->sdb_Abort)(db);
+ (*db->sdb_Abort)(db);
}
return crv;
}
@@ -1445,38 +1440,38 @@ sftkdb_CloseDB(SFTKDBHandle *handle)
PRBool parentForkedAfterC_Initialize = PR_FALSE;
#endif
if (handle == NULL) {
- return CKR_OK;
+ return CKR_OK;
}
if (handle->update) {
if (handle->db->sdb_SetForkState) {
(*handle->db->sdb_SetForkState)(parentForkedAfterC_Initialize);
}
- (*handle->update->sdb_Close)(handle->update);
+ (*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);
+ (*handle->db->sdb_Close)(handle->db);
}
if (handle->passwordKey.data) {
- PORT_ZFree(handle->passwordKey.data, handle->passwordKey.len);
+ PORT_ZFree(handle->passwordKey.data, handle->passwordKey.len);
}
if (handle->passwordLock) {
- SKIP_AFTER_FORK(PZ_DestroyLock(handle->passwordLock));
+ SKIP_AFTER_FORK(PZ_DestroyLock(handle->passwordLock));
}
if (handle->updatePasswordKey) {
- SECITEM_FreeItem(handle->updatePasswordKey, PR_TRUE);
+ SECITEM_FreeItem(handle->updatePasswordKey, PR_TRUE);
}
if (handle->updateID) {
- PORT_Free(handle->updateID);
+ PORT_Free(handle->updateID);
}
PORT_Free(handle);
return CKR_OK;
}
/*
- * reset a database to it's uninitialized state.
+ * reset a database to it's uninitialized state.
*/
static CK_RV
sftkdb_ResetDB(SFTKDBHandle *handle)
@@ -1484,26 +1479,25 @@ sftkdb_ResetDB(SFTKDBHandle *handle)
CK_RV crv = CKR_OK;
SDB *db;
if (handle == NULL) {
- return CKR_TOKEN_WRITE_PROTECTED;
+ return CKR_TOKEN_WRITE_PROTECTED;
}
db = SFTK_GET_SDB(handle);
crv = (*db->sdb_Begin)(db);
if (crv != CKR_OK) {
- goto loser;
+ goto loser;
}
crv = (*db->sdb_Reset)(db);
if (crv != CKR_OK) {
- goto loser;
+ goto loser;
}
crv = (*db->sdb_Commit)(db);
loser:
if (crv != CKR_OK) {
- (*db->sdb_Abort)(db);
+ (*db->sdb_Abort)(db);
}
return crv;
}
-
CK_RV
sftkdb_Begin(SFTKDBHandle *handle)
{
@@ -1511,11 +1505,11 @@ sftkdb_Begin(SFTKDBHandle *handle)
SDB *db;
if (handle == NULL) {
- return CKR_OK;
+ return CKR_OK;
}
db = SFTK_GET_SDB(handle);
if (db) {
- crv = (*db->sdb_Begin)(db);
+ crv = (*db->sdb_Begin)(db);
}
return crv;
}
@@ -1527,11 +1521,11 @@ sftkdb_Commit(SFTKDBHandle *handle)
SDB *db;
if (handle == NULL) {
- return CKR_OK;
+ return CKR_OK;
}
db = SFTK_GET_SDB(handle);
if (db) {
- (*db->sdb_Commit)(db);
+ (*db->sdb_Commit)(db);
}
return crv;
}
@@ -1543,16 +1537,15 @@ sftkdb_Abort(SFTKDBHandle *handle)
SDB *db;
if (handle == NULL) {
- return CKR_OK;
+ return CKR_OK;
}
db = SFTK_GET_SDB(handle);
if (db) {
- crv = (db->sdb_Abort)(db);
+ crv = (db->sdb_Abort)(db);
}
return crv;
}
-
/*
* functions to update the database from an old database
*/
@@ -1571,7 +1564,7 @@ static const CK_ATTRIBUTE_TYPE known_attributes[] = {
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_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,
@@ -1597,45 +1590,45 @@ static const CK_ATTRIBUTE_TYPE known_attributes[] = {
CKA_NETSCAPE_DB, CKA_NETSCAPE_TRUST, CKA_NSS_OVERRIDE_EXTENSIONS
};
-static unsigned int known_attributes_size= sizeof(known_attributes)/
- sizeof(known_attributes[0]);
+static unsigned 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)
+ CK_ATTRIBUTE *ptemplate, CK_ULONG *max)
{
- unsigned int i,j;
+ unsigned int i, j;
CK_RV crv;
if (*max < known_attributes_size) {
- *max = known_attributes_size;
- return CKR_BUFFER_TOO_SMALL;
+ *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;
+ 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);
+ 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];
+ 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;
@@ -1645,11 +1638,11 @@ 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
+ * 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
+static PRBool
sftkdb_hasUpdate(const char *typeString, SDB *db, const char *updateID)
{
char *id;
@@ -1658,11 +1651,11 @@ sftkdb_hasUpdate(const char *typeString, SDB *db, const char *updateID)
unsigned char dummyData[SDB_MAX_META_DATA_LEN];
if (!updateID) {
- return PR_FALSE;
+ return PR_FALSE;
}
id = PR_smprintf(SFTKDB_META_UPDATE_TEMPLATE, typeString, updateID);
if (id == NULL) {
- return PR_FALSE;
+ return PR_FALSE;
}
dummy.data = dummyData;
dummy.len = sizeof(dummyData);
@@ -1686,7 +1679,7 @@ sftkdb_putUpdate(const char *typeString, SDB *db, const char *updateID)
/* if no id was given, nothing to do */
if (updateID == NULL) {
- return CKR_OK;
+ return CKR_OK;
}
dummy.data = (unsigned char *)updateID;
@@ -1694,7 +1687,7 @@ sftkdb_putUpdate(const char *typeString, SDB *db, const char *updateID)
id = PR_smprintf(SFTKDB_META_UPDATE_TEMPLATE, typeString, updateID);
if (id == NULL) {
- return PR_FALSE;
+ return PR_FALSE;
}
crv = (*db->sdb_PutMetaData)(db, id, &dummy, NULL);
@@ -1707,14 +1700,14 @@ sftkdb_putUpdate(const char *typeString, SDB *db, const char *updateID)
* 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)
+sftkdb_getULongFromTemplate(CK_ATTRIBUTE_TYPE type,
+ CK_ATTRIBUTE *ptemplate, CK_ULONG len)
{
CK_ATTRIBUTE *attr = sftkdb_getAttributeFromTemplate(type,
- ptemplate, len);
+ ptemplate, len);
if (attr && attr->pValue && attr->ulValueLen == SDB_ULONG_SIZE) {
- return sftk_SDBULong2ULong(attr->pValue);
+ return sftk_SDBULong2ULong(attr->pValue);
}
return (CK_ULONG)-1;
}
@@ -1723,12 +1716,12 @@ sftkdb_getULongFromTemplate(CK_ATTRIBUTE_TYPE type,
* 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
+ * 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
+ * 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
@@ -1738,34 +1731,34 @@ sftkdb_incrementCKAID(PLArenaPool *arena, CK_ATTRIBUTE *ptemplate)
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;
+ /* 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);
+ 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;
+ return CKR_HOST_MEMORY;
}
if (len > 0) {
- PORT_Memcpy(buf, ptemplate->pValue, len);
+ PORT_Memcpy(buf, ptemplate->pValue, len);
}
buf[len] = 0;
ptemplate->pValue = buf;
- ptemplate->ulValueLen = len+1;
+ ptemplate->ulValueLen = len + 1;
return CKR_OK;
}
@@ -1773,30 +1766,30 @@ sftkdb_incrementCKAID(PLArenaPool *arena, CK_ATTRIBUTE *ptemplate)
* drop an attribute from a template.
*/
void
-sftkdb_dropAttribute(CK_ATTRIBUTE *attr, CK_ATTRIBUTE *ptemplate,
- CK_ULONG *plen)
+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;
+ 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;
}
/*
@@ -1804,10 +1797,10 @@ sftkdb_dropAttribute(CK_ATTRIBUTE *attr, CK_ATTRIBUTE *ptemplate,
* 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
+ SFTKDB_DO_NOTHING = 0,
+ SFTKDB_ADD_OBJECT,
+ SFTKDB_MODIFY_OBJECT,
+ SFTKDB_DROP_ATTRIBUTE
} sftkdbUpdateStatus;
/*
@@ -1821,18 +1814,18 @@ typedef enum {
* 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
+ * 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(PLArenaPool *arena, CK_ATTRIBUTE *target,
- CK_ATTRIBUTE *source)
+ CK_ATTRIBUTE *source)
{
CK_ULONG targetTrust = sftkdb_getULongFromTemplate(target->type,
- target, 1);
+ target, 1);
CK_ULONG sourceTrust = sftkdb_getULongFromTemplate(target->type,
- source, 1);
+ source, 1);
/*
* try to pick the best solution between the source and the
@@ -1843,24 +1836,24 @@ sftkdb_reconcileTrustEntry(PLArenaPool *arena, CK_ATTRIBUTE *target,
/* they are the same, everything is already kosher */
if (targetTrust == sourceTrust) {
- return SFTKDB_DO_NOTHING;
+ 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;
+ /*
+ * 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;
+ /* overwriting the target in this case is OK */
+ return SFTKDB_MODIFY_OBJECT;
}
/* at this point we know that both attributes exist and have the
@@ -1868,31 +1861,29 @@ sftkdb_reconcileTrustEntry(PLArenaPool *arena, CK_ATTRIBUTE *target,
* ulValueLen for either attribute.
*/
if (sourceTrust == CKT_NSS_TRUST_UNKNOWN) {
- return SFTKDB_DROP_ATTRIBUTE;
+ 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;
+ /* 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.
+ /* 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,
+ * 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 ((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;
+ 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. */
@@ -1900,13 +1891,13 @@ sftkdb_reconcileTrustEntry(PLArenaPool *arena, CK_ATTRIBUTE *target,
}
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 };
+ { 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]))
+ (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
@@ -1914,249 +1905,242 @@ const CK_ATTRIBUTE_TYPE sftkdb_trustList[] =
*/
static sftkdbUpdateStatus
sftkdb_reconcileTrust(PLArenaPool *arena, SDB *db, CK_OBJECT_HANDLE id,
- CK_ATTRIBUTE *ptemplate, CK_ULONG *plen)
+ CK_ATTRIBUTE *ptemplate, CK_ULONG *plen)
{
CK_ATTRIBUTE trustTemplate[SFTK_TRUST_TEMPLATE_COUNT];
- unsigned char trustData[SFTK_TRUST_TEMPLATE_COUNT*SDB_ULONG_SIZE];
+ 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;
+ 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);
+ 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);
- }
+ /* 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);
- }
+ 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;
- }
- }
-
+ /* 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(PLArenaPool *arena, SDB *db, CK_OBJECT_HANDLE id,
- CK_ATTRIBUTE *ptemplate, CK_ULONG *plen)
+ 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}
+ { CKA_ID, NULL, 0 },
+ { CKA_LABEL, NULL, 0 }
};
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;
+ 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 */
(void)(*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;
+ 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);
- }
+ 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;
+ /* 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);
- }
+ 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;
+ /* 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
+ * To help readability, these have been defined
* as SFTK_DONT_UPDATE and SFTK_UPDATE respectively.
*/
static PRBool
sftkdb_updateObjectTemplate(PLArenaPool *arena, SDB *db,
- CK_OBJECT_CLASS objectType,
- CK_ATTRIBUTE *ptemplate, CK_ULONG *plen,
- CK_OBJECT_HANDLE *targetID)
+ 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);
+ 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;
+ 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;
- }
- }
+ 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)
+sftkdb_mergeObject(SFTKDBHandle *handle, CK_OBJECT_HANDLE id,
+ SECItem *key)
{
CK_ATTRIBUTE template[MAX_ATTRIBUTES];
CK_ATTRIBUTE *ptemplate;
@@ -2169,76 +2153,75 @@ sftkdb_mergeObject(SFTKDBHandle *handle, CK_OBJECT_HANDLE id,
PLArenaPool *arena = NULL;
arena = PORT_NewArena(256);
- if (arena == NULL) {
- return CKR_HOST_MEMORY;
+ 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);
- }
+ 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;
+ 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;
- }
+ 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);
+ crv = (*source->sdb_GetAttributeValue)(source, id,
+ ptemplate, max_attributes);
if (crv != CKR_OK) {
- goto loser;
+ goto loser;
}
objectType = sftkdb_getULongFromTemplate(CKA_CLASS, ptemplate,
- max_attributes);
+ 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
+ * 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);
+ 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;
- }
- }
+ 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);
+ PORT_FreeArena(arena, PR_TRUE);
}
return crv;
}
-
#define MAX_IDS 10
/*
@@ -2256,10 +2239,10 @@ sftkdb_Update(SFTKDBHandle *handle, SECItem *key)
unsigned int i;
if (handle == NULL) {
- return CKR_OK;
+ return CKR_OK;
}
if (handle->update == NULL) {
- return CKR_OK;
+ return CKR_OK;
}
/*
@@ -2268,38 +2251,39 @@ sftkdb_Update(SFTKDBHandle *handle, SECItem *key)
*/
crv = (*handle->db->sdb_Begin)(handle->db);
if (crv != CKR_OK) {
- goto loser;
+ 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;
+ 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;
+ /* 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;
+ 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);
- }
+ 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;
+ if (crv == CKR_OK)
+ crv = crv2;
loser:
/* no longer need the old key value */
@@ -2307,62 +2291,61 @@ loser:
/* 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;
- }
+ 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);
+ 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 (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;
+ (*handle->update->sdb_Close)(handle->update);
+ handle->update = NULL;
}
if (handle->updateID) {
- PORT_Free(handle->updateID);
- handle->updateID = NULL;
+ PORT_Free(handle->updateID);
+ handle->updateID = NULL;
}
sftkdb_FreeUpdatePasswordKey(handle);
if (updatePasswordKey) {
- SECITEM_ZfreeItem(updatePasswordKey, PR_TRUE);
+ SECITEM_ZfreeItem(updatePasswordKey, PR_TRUE);
}
handle->updateDBIsInit = PR_FALSE;
return crv;
@@ -2370,7 +2353,7 @@ done:
/******************************************************************
* DB handle managing functions.
- *
+ *
* These functions are called by softoken to initialize, acquire,
* and release database handles.
*/
@@ -2387,18 +2370,18 @@ sftk_freeDB(SFTKDBHandle *handle)
{
PRInt32 ref;
- if (!handle) return;
+ if (!handle)
+ return;
ref = PR_ATOMIC_DECREMENT(&handle->ref);
if (ref == 0) {
- sftkdb_CloseDB(handle);
+ sftkdb_CloseDB(handle);
}
return;
}
-
/*
- * acquire a database handle for a certificate db
- * (database for public objects)
+ * acquire a database handle for a certificate db
+ * (database for public objects)
*/
SFTKDBHandle *
sftk_getCertDB(SFTKSlot *slot)
@@ -2415,7 +2398,7 @@ sftk_getCertDB(SFTKSlot *slot)
}
/*
- * acquire a database handle for a key database
+ * acquire a database handle for a key database
* (database for private objects)
*/
SFTKDBHandle *
@@ -2456,24 +2439,24 @@ sftk_getDBForTokenObject(SFTKSlot *slot, CK_OBJECT_HANDLE objectID)
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;
+ 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;
}
/*
@@ -2487,12 +2470,12 @@ sftkdb_ResetKeyDB(SFTKDBHandle *handle)
/* only rest the key db */
if (handle->type != SFTK_KEYDB_TYPE) {
- return SECFailure;
+ return SECFailure;
}
crv = sftkdb_ResetDB(handle);
if (crv != CKR_OK) {
- /* set error */
- return SECFailure;
+ /* set error */
+ return SECFailure;
}
return SECSuccess;
}
@@ -2504,49 +2487,49 @@ sftk_oldVersionExists(const char *dir, int version)
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;
- }
+ 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)
+sftk_hasLegacyDB(const char *confdir, const char *certPrefix,
+ const char *keyPrefix, int certVersion, int keyVersion)
{
char *dir;
PRBool exists;
if (certPrefix == NULL) {
- certPrefix = "";
+ certPrefix = "";
}
if (keyPrefix == NULL) {
- keyPrefix = "";
+ keyPrefix = "";
}
- dir= PR_smprintf("%s/%scert", confdir, certPrefix);
+ dir = PR_smprintf("%s/%scert", confdir, certPrefix);
if (dir == NULL) {
- return PR_FALSE;
+ return PR_FALSE;
}
exists = sftk_oldVersionExists(dir, certVersion);
PR_smprintf_free(dir);
if (exists) {
- return PR_TRUE;
+ return PR_TRUE;
}
- dir= PR_smprintf("%s/%skey", confdir, keyPrefix);
+ dir = PR_smprintf("%s/%skey", confdir, keyPrefix);
if (dir == NULL) {
- return PR_FALSE;
+ return PR_FALSE;
}
exists = sftk_oldVersionExists(dir, keyVersion);
@@ -2561,13 +2544,13 @@ sftk_hasLegacyDB(const char *confdir, const char *certPrefix,
* calls the appropriate low level function to open the database.
* It also figures out whether or not to setup up automatic update.
*/
-CK_RV
+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 *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;
@@ -2579,14 +2562,17 @@ sftk_DBInit(const char *configdir, const char *certPrefix,
PRBool needUpdate = PR_FALSE;
if (!readOnly) {
- flags = SDB_CREATE;
+ flags = SDB_CREATE;
+ }
+ if (isFIPS) {
+ flags |= SDB_FIPS;
}
*certDB = NULL;
*keyDB = NULL;
if (noKeyDB && noCertDB) {
- return CKR_OK;
+ return CKR_OK;
}
confdir = _NSSUTIL_EvaluateConfigDir(configdir, &dbType, &appName);
@@ -2594,88 +2580,87 @@ sftk_DBInit(const char *configdir, const char *certPrefix,
* 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. */
+ case NSS_DB_TYPE_LEGACY:
+ crv = sftkdbCall_open(confdir, certPrefix, keyPrefix, 8, 3, flags,
+ noCertDB ? NULL : &certSDB, noKeyDB ? NULL : &keySDB);
+ break;
+ case NSS_DB_TYPE_MULTIACCESS:
+ crv = sftkdbCall_open(configdir, certPrefix, keyPrefix, 8, 3, flags,
+ 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) == 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,
+ 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;
+ goto done;
}
if (!noCertDB) {
- *certDB = sftk_NewDBHandle(certSDB, SFTK_CERTDB_TYPE);
+ *certDB = sftk_NewDBHandle(certSDB, SFTK_CERTDB_TYPE);
} else {
- *certDB = NULL;
+ *certDB = NULL;
}
if (!noKeyDB) {
- *keyDB = sftk_NewDBHandle(keySDB, SFTK_KEYDB_TYPE);
+ *keyDB = sftk_NewDBHandle(keySDB, SFTK_KEYDB_TYPE);
} else {
- *keyDB = NULL;
+ *keyDB = NULL;
}
/* link them together */
if (*certDB) {
- (*certDB)->peerDB = *keyDB;
+ (*certDB)->peerDB = *keyDB;
}
if (*keyDB) {
- (*keyDB)->peerDB = *certDB;
+ (*keyDB)->peerDB = *certDB;
}
/*
@@ -2683,51 +2668,49 @@ sftk_DBInit(const char *configdir, const char *certPrefix,
* 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);
- }
- }
+ SDB *updateCert = NULL;
+ SDB *updateKey = NULL;
+ CK_RV crv2;
+
+ crv2 = sftkdbCall_open(confdir, certPrefix, keyPrefix, 8, 3, flags,
+ 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);
+ PORT_Free(appName);
}
- return forceOpen ? CKR_OK : crv;
+ return forceOpen ? CKR_OK : crv;
}
-CK_RV
+CK_RV
sftkdb_Shutdown(void)
{
- s_shutdown();
- sftkdbCall_Shutdown();
- return CKR_OK;
+ s_shutdown();
+ sftkdbCall_Shutdown();
+ return CKR_OK;
}
-
diff --git a/nss/lib/softoken/sftkdb.h b/nss/lib/softoken/sftkdb.h
index beff9da..a47c896 100644
--- a/nss/lib/softoken/sftkdb.h
+++ b/nss/lib/softoken/sftkdb.h
@@ -7,16 +7,16 @@
#include "pkcs11t.h"
/* raw database stuff */
-CK_RV sftkdb_write(SFTKDBHandle *handle, SFTKObject *,CK_OBJECT_HANDLE *);
+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_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_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);
@@ -24,13 +24,13 @@ CK_RV sftkdb_closeDB(SFTKDBHandle *handle);
SECStatus sftkdb_PWIsInitialized(SFTKDBHandle *keydb);
SECStatus sftkdb_CheckPassword(SFTKDBHandle *keydb, const char *pw,
- PRBool *tokenRemoved);
+ 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_ChangePassword(SFTKDBHandle *keydb,
+ char *oldPin, char *newPin,
+ PRBool *tokenRemoved);
SECStatus sftkdb_ClearPassword(SFTKDBHandle *keydb);
PRBool sftkdb_InUpdateMerge(SFTKDBHandle *keydb);
PRBool sftkdb_NeedUpdateDBPassword(SFTKDBHandle *keydb);
@@ -57,15 +57,15 @@ void sftkdb_FreeUpdatePasswordKey(SFTKDBHandle *keydb);
* 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);
+ 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,
+SFTKDBHandle *sftk_getDBForTokenObject(SFTKSlot *slot,
CK_OBJECT_HANDLE objectID);
void sftk_freeDB(SFTKDBHandle *certHandle);
diff --git a/nss/lib/softoken/sftkdbt.h b/nss/lib/softoken/sftkdbt.h
index 684393c..77beb84 100644
--- a/nss/lib/softoken/sftkdbt.h
+++ b/nss/lib/softoken/sftkdbt.h
@@ -6,7 +6,7 @@
#define SFTKDBT_H 1
typedef struct SFTKDBHandleStr SFTKDBHandle;
-#define SDB_MAX_META_DATA_LEN 256
+#define SDB_MAX_META_DATA_LEN 256
#define SDB_ULONG_SIZE 4
#endif
diff --git a/nss/lib/softoken/sftkdbti.h b/nss/lib/softoken/sftkdbti.h
index eb777e4..4942e1b 100644
--- a/nss/lib/softoken/sftkdbti.h
+++ b/nss/lib/softoken/sftkdbti.h
@@ -9,17 +9,17 @@
* private defines
*/
struct SFTKDBHandleStr {
- SDB *db;
+ SDB *db;
PRInt32 ref;
- CK_OBJECT_HANDLE type;
+ CK_OBJECT_HANDLE type;
SECItem passwordKey;
SECItem *newKey;
SECItem *oldKey;
SECItem *updatePasswordKey;
PZLock *passwordLock;
SFTKDBHandle *peerDB;
- SDB *update;
- char *updateID;
+ SDB *update;
+ char *updateID;
PRBool updateDBIsInit;
};
@@ -34,27 +34,25 @@ struct SFTKDBHandleStr {
#define SFTK_MAX_IDS 10
#define SFTK_GET_SDB(handle) \
- ((handle)->update ? (handle)->update : (handle)->db)
+ ((handle)->update ? (handle)->update : (handle)->db)
SECStatus sftkdb_DecryptAttribute(SECItem *passKey, SECItem *cipherText,
- SECItem **plainText);
+ SECItem **plainText);
SECStatus sftkdb_EncryptAttribute(PLArenaPool *arena, SECItem *passKey,
- SECItem *plainText, SECItem **cipherText);
+ SECItem *plainText, SECItem **cipherText);
SECStatus sftkdb_SignAttribute(PLArenaPool *arena, SECItem *passKey,
- CK_OBJECT_HANDLE objectID,
- CK_ATTRIBUTE_TYPE attrType,
- SECItem *plainText, SECItem **sigText);
+ 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);
+ 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);
-
-
+CK_RV sftkdb_PutAttributeSignature(SFTKDBHandle *handle,
+ SDB *keyTarget, CK_OBJECT_HANDLE objectID,
+ CK_ATTRIBUTE_TYPE type, SECItem *signText);
#endif
diff --git a/nss/lib/softoken/sftkhmac.c b/nss/lib/softoken/sftkhmac.c
index f4e859b..be6344c 100644
--- a/nss/lib/softoken/sftkhmac.c
+++ b/nss/lib/softoken/sftkhmac.c
@@ -15,20 +15,20 @@ 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;
+ 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;
}
@@ -37,7 +37,7 @@ 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;
+ (CK_NSS_MAC_CONSTANT_TIME_PARAMS *)mech->pParameter;
sftk_MACConstantTimeCtx *ctx;
HASH_HashType alg;
SFTKAttribute *keyval;
@@ -45,29 +45,29 @@ SetupMAC(CK_MECHANISM_PTR mech, SFTKObject *key)
unsigned int secretLength;
if (mech->ulParameterLen != sizeof(CK_NSS_MAC_CONSTANT_TIME_PARAMS)) {
- return NULL;
+ return NULL;
}
alg = MACMechanismToHash(params->macAlg);
if (alg == HASH_AlgNULL) {
- return NULL;
+ return NULL;
}
- keyval = sftk_FindAttribute(key,CKA_VALUE);
+ keyval = sftk_FindAttribute(key, CKA_VALUE);
if (keyval == NULL) {
- return NULL;
+ return NULL;
}
secretLength = keyval->attrib.ulValueLen;
if (secretLength > sizeof(secret)) {
- sftk_FreeAttribute(keyval);
- return NULL;
+ sftk_FreeAttribute(keyval);
+ return NULL;
}
memcpy(secret, keyval->attrib.pValue, secretLength);
sftk_FreeAttribute(keyval);
ctx = PORT_Alloc(sizeof(sftk_MACConstantTimeCtx));
if (!ctx) {
- return NULL;
+ return NULL;
}
memcpy(ctx->secret, secret, secretLength);
@@ -82,15 +82,15 @@ 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;
+ (CK_NSS_MAC_CONSTANT_TIME_PARAMS *)mech->pParameter;
sftk_MACConstantTimeCtx *ctx;
if (params->ulHeaderLen > sizeof(ctx->header)) {
- return NULL;
+ return NULL;
}
ctx = SetupMAC(mech, key);
if (!ctx) {
- return NULL;
+ return NULL;
}
ctx->headerLength = params->ulHeaderLen;
@@ -102,30 +102,30 @@ 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;
+ (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;
+ params->macAlg != CKM_SSL3_SHA1_MAC) {
+ return NULL;
}
ctx = SetupMAC(mech, key);
if (!ctx) {
- return NULL;
+ return NULL;
}
if (params->macAlg == CKM_SSL3_MD5_MAC) {
- padLength = 48;
+ padLength = 48;
}
ctx->headerLength =
- ctx->secretLength +
- padLength +
- params->ulHeaderLen;
+ ctx->secretLength +
+ padLength +
+ params->ulHeaderLen;
if (ctx->headerLength > sizeof(ctx->header)) {
- goto loser;
+ goto loser;
}
j = 0;
@@ -145,41 +145,41 @@ loser:
void
sftk_HMACConstantTime_Update(void *pctx, const void *data, unsigned int len)
{
- sftk_MACConstantTimeCtx *ctx = (sftk_MACConstantTimeCtx *) pctx;
+ sftk_MACConstantTimeCtx *ctx = (sftk_MACConstantTimeCtx *)pctx;
PORT_CheckSuccess(HMAC_ConstantTime(
- ctx->mac, NULL, sizeof(ctx->mac),
- ctx->hash,
- ctx->secret, ctx->secretLength,
- ctx->header, ctx->headerLength,
- data, len,
- ctx->totalLength));
+ ctx->mac, NULL, sizeof(ctx->mac),
+ ctx->hash,
+ ctx->secret, ctx->secretLength,
+ ctx->header, ctx->headerLength,
+ data, len,
+ ctx->totalLength));
}
void
sftk_SSLv3MACConstantTime_Update(void *pctx, const void *data, unsigned int len)
{
- sftk_MACConstantTimeCtx *ctx = (sftk_MACConstantTimeCtx *) pctx;
+ sftk_MACConstantTimeCtx *ctx = (sftk_MACConstantTimeCtx *)pctx;
PORT_CheckSuccess(SSLv3_MAC_ConstantTime(
- ctx->mac, NULL, sizeof(ctx->mac),
- ctx->hash,
- ctx->secret, ctx->secretLength,
- ctx->header, ctx->headerLength,
- data, len,
- ctx->totalLength));
+ ctx->mac, NULL, sizeof(ctx->mac),
+ ctx->hash,
+ ctx->secret, ctx->secretLength,
+ ctx->header, ctx->headerLength,
+ data, len,
+ ctx->totalLength));
}
void
sftk_MACConstantTime_EndHash(void *pctx, void *out, unsigned int *outLength,
- unsigned int maxLength)
+ unsigned int maxLength)
{
- const sftk_MACConstantTimeCtx *ctx = (sftk_MACConstantTimeCtx *) pctx;
+ const sftk_MACConstantTimeCtx *ctx = (sftk_MACConstantTimeCtx *)pctx;
unsigned int toCopy = ctx->hash->length;
if (toCopy > maxLength) {
- toCopy = maxLength;
+ toCopy = maxLength;
}
memcpy(out, ctx->mac, toCopy);
if (outLength) {
- *outLength = toCopy;
+ *outLength = toCopy;
}
}
diff --git a/nss/lib/softoken/sftkpars.c b/nss/lib/softoken/sftkpars.c
index 465cbce..e972fe8 100644
--- a/nss/lib/softoken/sftkpars.c
+++ b/nss/lib/softoken/sftkpars.c
@@ -1,126 +1,131 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.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 "prprf.h"
#include "prenv.h"
#include "utilpars.h"
-#define FREE_CLEAR(p) if (p) { PORT_Free(p); p = NULL; }
+#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);
+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);
+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);
+ 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)
+sftk_parseTokenParameters(char *param, sftk_token_parameters *parsed)
{
int next;
char *tmp = NULL;
- char *index;
+ const 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;
+ 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;
+ const char *tokenIndex;
sftk_token_parameters *tokens = NULL;
- int i=0,count = 0,next;
+ int i = 0, count = 0, next;
- if ((tokenParams == NULL) || (*tokenParams == 0)) return;
+ 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++;
+ 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;
+ 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;
+ *tokenIndex && i < count; i++) {
+ char *name;
+ name = NSSUTIL_ArgGetLabel(tokenIndex, &next);
+ tokenIndex += next;
- tokens[i].slotID = NSSUTIL_ArgDecodeNumber(name);
+ 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);
+ 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;
+ return;
}
CK_RV
-sftk_parseParameters(char *param, sftk_parameters *parsed, PRBool isFIPS)
+sftk_parseParameters(char *param, sftk_parameters *parsed, PRBool isFIPS)
{
int next;
char *tmp = NULL;
- char *index;
+ const char *index;
char *certPrefix = NULL, *keyPrefix = NULL;
char *tokdes = NULL, *ptokdes = NULL, *pupdtokdes = NULL;
char *slotdes = NULL, *pslotdes = NULL;
@@ -131,78 +136,77 @@ sftk_parseParameters(char *param, sftk_parameters *parsed, PRBool isFIPS)
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)
+ 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;
- }
+ 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:
@@ -224,25 +228,24 @@ 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);
+ 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->libdes);
FREE_CLEAR(params->tokens);
FREE_CLEAR(params->updatedir);
FREE_CLEAR(params->updateID);
}
-
diff --git a/nss/lib/softoken/sftkpars.h b/nss/lib/softoken/sftkpars.h
index 6178dff..a7707fc 100644
--- a/nss/lib/softoken/sftkpars.h
+++ b/nss/lib/softoken/sftkpars.h
@@ -5,13 +5,10 @@
#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_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);
-
-
-
+char *sftk_argGetParamValue(char *paramName, char *parameters);
diff --git a/nss/lib/softoken/sftkpwd.c b/nss/lib/softoken/sftkpwd.c
index d8ce857..0b8c91b 100644
--- a/nss/lib/softoken/sftkpwd.c
+++ b/nss/lib/softoken/sftkpwd.c
@@ -1,28 +1,28 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.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
+ * 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
+ * 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 "prprf.h"
#include "secasn1.h"
#include "pratom.h"
#include "blapi.h"
@@ -33,9 +33,9 @@
#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).
@@ -46,45 +46,44 @@
* 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)
+ const char *pw, SECItem *key)
{
SHA1Context *cx = NULL;
SECStatus rv = SECFailure;
key->data = PORT_Alloc(SHA1_LENGTH);
if (key->data == NULL) {
- goto loser;
+ goto loser;
}
key->len = SHA1_LENGTH;
cx = SHA1_NewContext();
- if ( cx == NULL) {
- goto loser;
+ if (cx == NULL) {
+ goto loser;
}
SHA1_Begin(cx);
- if (salt && salt->data ) {
- SHA1_Update(cx, salt->data, salt->len);
+ 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);
+ SHA1_DestroyContext(cx, PR_TRUE);
}
if (rv != SECSuccess) {
- if (key->data != NULL) {
- PORT_ZFree(key->data,key->len);
- }
- key->data = NULL;
+ if (key->data != NULL) {
+ PORT_ZFree(key->data, key->len);
+ }
+ key->data = NULL;
}
return rv;
}
@@ -101,10 +100,10 @@ loser:
typedef struct sftkCipherValueStr sftkCipherValue;
struct sftkCipherValueStr {
PLArenaPool *arena;
- SECOidTag alg;
+ SECOidTag alg;
NSSPKCS5PBEParameter *param;
- SECItem salt;
- SECItem value;
+ SECItem salt;
+ SECItem value;
};
#define SFTK_CIPHERTEXT_VERSION 3
@@ -119,12 +118,12 @@ 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) },
+ 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) },
+ offsetof(SFTKDBEncryptedDataInfo, encryptedData) },
{ 0 }
};
@@ -141,20 +140,20 @@ sftkdb_decodeCipherText(SECItem *cipherText, sftkCipherValue *cipherValue)
arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
if (arena == NULL) {
- return SECFailure;
+ return SECFailure;
}
cipherValue->arena = NULL;
cipherValue->param = NULL;
rv = SEC_QuickDERDecodeItem(arena, &edi, sftkdb_EncryptedDataInfoTemplate,
- cipherText);
+ cipherText);
if (rv != SECSuccess) {
- goto loser;
+ goto loser;
}
cipherValue->alg = SECOID_GetAlgorithmTag(&edi.algorithm);
cipherValue->param = nsspkcs5_AlgidToParam(&edi.algorithm);
if (cipherValue->param == NULL) {
- goto loser;
+ goto loser;
}
cipherValue->value = edi.encryptedData;
cipherValue->arena = arena;
@@ -162,24 +161,22 @@ sftkdb_decodeCipherText(SECItem *cipherText, sftkCipherValue *cipherValue)
return SECSuccess;
loser:
if (cipherValue->param) {
- nsspkcs5_DestroyPBEParameter(cipherValue->param);
- cipherValue->param = NULL;
+ nsspkcs5_DestroyPBEParameter(cipherValue->param);
+ cipherValue->param = NULL;
}
if (arena) {
- PORT_FreeArena(arena,PR_FALSE);
+ 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,
+sftkdb_encodeCipherText(PLArenaPool *arena, sftkCipherValue *cipherValue,
SECItem **cipherText)
{
SFTKDBEncryptedDataInfo edi;
@@ -187,40 +184,38 @@ sftkdb_encodeCipherText(PLArenaPool *arena, sftkCipherValue *cipherValue,
SECStatus rv;
PLArenaPool *localArena = NULL;
-
localArena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
if (localArena == NULL) {
- return SECFailure;
+ return SECFailure;
}
- algid = nsspkcs5_CreateAlgorithmID(localArena, cipherValue->alg,
- cipherValue->param);
+ algid = nsspkcs5_CreateAlgorithmID(localArena, cipherValue->alg,
+ cipherValue->param);
if (algid == NULL) {
- rv = SECFailure;
- goto loser;
+ rv = SECFailure;
+ goto loser;
}
rv = SECOID_CopyAlgorithmID(localArena, &edi.algorithm, algid);
SECOID_DestroyAlgorithmID(algid, PR_TRUE);
if (rv != SECSuccess) {
- goto loser;
+ goto loser;
}
edi.encryptedData = cipherValue->value;
- *cipherText = SEC_ASN1EncodeItem(arena, NULL, &edi,
- sftkdb_EncryptedDataInfoTemplate);
+ *cipherText = SEC_ASN1EncodeItem(arena, NULL, &edi,
+ sftkdb_EncryptedDataInfoTemplate);
if (*cipherText == NULL) {
- rv = SECFailure;
+ rv = SECFailure;
}
loser:
if (localArena) {
- PORT_FreeArena(localArena,PR_FALSE);
+ PORT_FreeArena(localArena, PR_FALSE);
}
return rv;
}
-
/*
* Use our key to decode a cipherText block from the database.
*
@@ -228,7 +223,7 @@ loser:
* with SECITEM_FreeItem by the caller.
*/
SECStatus
-sftkdb_DecryptAttribute(SECItem *passKey, SECItem *cipherText, SECItem **plain)
+sftkdb_DecryptAttribute(SECItem *passKey, SECItem *cipherText, SECItem **plain)
{
SECStatus rv;
sftkCipherValue cipherValue;
@@ -236,22 +231,22 @@ sftkdb_DecryptAttribute(SECItem *passKey, SECItem *cipherText, SECItem **plain)
/* First get the cipher type */
rv = sftkdb_decodeCipherText(cipherText, &cipherValue);
if (rv != SECSuccess) {
- goto loser;
+ goto loser;
}
- *plain = nsspkcs5_CipherData(cipherValue.param, passKey, &cipherValue.value,
- PR_FALSE, NULL);
+ *plain = nsspkcs5_CipherData(cipherValue.param, passKey, &cipherValue.value,
+ PR_FALSE, NULL);
if (*plain == NULL) {
- rv = SECFailure;
- goto loser;
- }
+ rv = SECFailure;
+ goto loser;
+ }
loser:
if (cipherValue.param) {
- nsspkcs5_DestroyPBEParameter(cipherValue.param);
+ nsspkcs5_DestroyPBEParameter(cipherValue.param);
}
if (cipherValue.arena) {
- PORT_FreeArena(cipherValue.arena,PR_FALSE);
+ PORT_FreeArena(cipherValue.arena, PR_FALSE);
}
return rv;
}
@@ -263,8 +258,8 @@ loser:
* salt automatically.
*/
SECStatus
-sftkdb_EncryptAttribute(PLArenaPool *arena, SECItem *passKey,
- SECItem *plainText, SECItem **cipherText)
+sftkdb_EncryptAttribute(PLArenaPool *arena, SECItem *passKey,
+ SECItem *plainText, SECItem **cipherText)
{
SECStatus rv;
sftkCipherValue cipherValue;
@@ -275,32 +270,33 @@ sftkdb_EncryptAttribute(PLArenaPool *arena, SECItem *passKey,
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);
+ RNG_GenerateGlobalRandomBytes(saltData, cipherValue.salt.len);
- param = nsspkcs5_NewParam(cipherValue.alg, &cipherValue.salt, 1);
+ param = nsspkcs5_NewParam(cipherValue.alg, HASH_AlgSHA1, &cipherValue.salt,
+ 1);
if (param == NULL) {
- rv = SECFailure;
- goto loser;
+ rv = SECFailure;
+ goto loser;
}
cipher = nsspkcs5_CipherData(param, passKey, plainText, PR_TRUE, NULL);
if (cipher == NULL) {
- rv = SECFailure;
- goto loser;
- }
+ rv = SECFailure;
+ goto loser;
+ }
cipherValue.value = *cipher;
cipherValue.param = param;
rv = sftkdb_encodeCipherText(arena, &cipherValue, cipherText);
if (rv != SECSuccess) {
- goto loser;
+ goto loser;
}
loser:
if (cipher) {
- SECITEM_FreeItem(cipher, PR_TRUE);
+ SECITEM_FreeItem(cipher, PR_TRUE);
}
if (param) {
- nsspkcs5_DestroyPBEParameter(param);
+ nsspkcs5_DestroyPBEParameter(param);
}
return rv;
}
@@ -312,10 +308,10 @@ loser:
* 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)
+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;
@@ -326,23 +322,23 @@ sftkdb_pbehash(SECOidTag sigOid, SECItem *passKey,
hashType = HASH_FromHMACOid(param->encAlg);
if (hashType == HASH_AlgNULL) {
- PORT_SetError(SEC_ERROR_INVALID_ALGORITHM);
- return SECFailure;
+ PORT_SetError(SEC_ERROR_INVALID_ALGORITHM);
+ return SECFailure;
}
hashObj = HASH_GetRawHashObject(hashType);
if (hashObj == NULL) {
- goto loser;
+ goto loser;
}
key = nsspkcs5_ComputeKeyAndIV(param, passKey, NULL, PR_FALSE);
if (!key) {
- goto loser;
+ goto loser;
}
hashCx = HMAC_Create(hashObj, key->data, key->len, PR_TRUE);
if (!hashCx) {
- goto loser;
+ goto loser;
}
HMAC_Begin(hashCx);
/* Tie this value to a particular object. This is most important for
@@ -358,10 +354,10 @@ sftkdb_pbehash(SECOidTag sigOid, SECItem *passKey,
loser:
if (hashCx) {
- HMAC_Destroy(hashCx, PR_TRUE);
+ HMAC_Destroy(hashCx, PR_TRUE);
}
if (key) {
- SECITEM_FreeItem(key,PR_TRUE);
+ SECITEM_FreeItem(key, PR_TRUE);
}
return rv;
}
@@ -372,40 +368,39 @@ loser:
* plainText is the plainText of the attribute.
*/
SECStatus
-sftkdb_VerifyAttribute(SECItem *passKey, CK_OBJECT_HANDLE objectID,
- CK_ATTRIBUTE_TYPE attrType,
- SECItem *plainText, SECItem *signText)
+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;
+ goto loser;
}
signature.data = signData;
signature.len = sizeof(signData);
- rv = sftkdb_pbehash(signValue.alg, passKey, signValue.param,
- objectID, attrType, plainText, &signature);
+ rv = sftkdb_pbehash(signValue.alg, passKey, signValue.param,
+ objectID, attrType, plainText, &signature);
if (rv != SECSuccess) {
- goto loser;
+ goto loser;
}
- if (SECITEM_CompareItem(&signValue.value,&signature) != 0) {
- PORT_SetError(SEC_ERROR_BAD_SIGNATURE);
- rv = SECFailure;
+ if (SECITEM_CompareItem(&signValue.value, &signature) != 0) {
+ PORT_SetError(SEC_ERROR_BAD_SIGNATURE);
+ rv = SECFailure;
}
loser:
if (signValue.param) {
- nsspkcs5_DestroyPBEParameter(signValue.param);
+ nsspkcs5_DestroyPBEParameter(signValue.param);
}
if (signValue.arena) {
- PORT_FreeArena(signValue.arena,PR_FALSE);
+ PORT_FreeArena(signValue.arena, PR_FALSE);
}
return rv;
}
@@ -415,9 +410,9 @@ loser:
* 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)
+sftkdb_SignAttribute(PLArenaPool *arena, SECItem *passKey,
+ CK_OBJECT_HANDLE objectID, CK_ATTRIBUTE_TYPE attrType,
+ SECItem *plainText, SECItem **signature)
{
SECStatus rv;
sftkCipherValue signValue;
@@ -446,13 +441,13 @@ sftkdb_SignAttribute(PLArenaPool *arena, SECItem *passKey,
signValue.salt.data = saltData;
signValue.value.data = signData;
signValue.value.len = hmacLength;
- RNG_GenerateGlobalRandomBytes(saltData,prfLength);
+ RNG_GenerateGlobalRandomBytes(saltData, prfLength);
/* initialize our pkcs5 parameter */
- param = nsspkcs5_NewParam(signValue.alg, &signValue.salt, 1);
+ param = nsspkcs5_NewParam(signValue.alg, HASH_AlgSHA1, &signValue.salt, 1);
if (param == NULL) {
- rv = SECFailure;
- goto loser;
+ rv = SECFailure;
+ goto loser;
}
param->keyID = pbeBitGenIntegrityKey;
/* set the PKCS 5 v2 parameters, not extractable from the
@@ -462,47 +457,46 @@ sftkdb_SignAttribute(PLArenaPool *arena, SECItem *passKey,
param->keyLen = hmacLength;
rv = SECOID_SetAlgorithmID(param->poolp, &param->prfAlg, prfAlg, NULL);
if (rv != SECSuccess) {
- goto loser;
+ goto loser;
}
-
/* calculate the mac */
rv = sftkdb_pbehash(signValue.alg, passKey, param, objectID, attrType,
- plainText, &signValue.value);
+ plainText, &signValue.value);
if (rv != SECSuccess) {
- goto loser;
+ goto loser;
}
signValue.param = param;
/* write it out */
rv = sftkdb_encodeCipherText(arena, &signValue, signature);
if (rv != SECSuccess) {
- goto loser;
+ goto loser;
}
loser:
if (param) {
- nsspkcs5_DestroyPBEParameter(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
+ * We can used the key attached to the handle in sftkdb_EncryptAttribute
* and sftkdb_DecryptAttribute calls.
- */
-static void
+ */
+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;
+ PORT_Assert(keydb->type != SFTK_KEYDB_TYPE);
+ return;
}
/* an atomic pointer set would be nice */
@@ -533,10 +527,10 @@ PRBool
sftkdb_NeedUpdateDBPassword(SFTKDBHandle *keydb)
{
if (!sftkdb_InUpdateMerge(keydb)) {
- return PR_FALSE;
+ return PR_FALSE;
}
if (keydb->updateDBIsInit && !keydb->updatePasswordKey) {
- return PR_TRUE;
+ return PR_TRUE;
}
return PR_FALSE;
}
@@ -551,17 +545,17 @@ sftkdb_GetUpdatePasswordKey(SFTKDBHandle *handle)
/* if we're a cert db, fetch it from our peer key db */
if (handle->type == SFTK_CERTDB_TYPE) {
- handle = handle->peerDB;
+ handle = handle->peerDB;
}
/* don't have one */
if (!handle) {
- return NULL;
+ return NULL;
}
PZ_Lock(handle->passwordLock);
if (handle->updatePasswordKey) {
- key = SECITEM_DupItem(handle->updatePasswordKey);
+ key = SECITEM_DupItem(handle->updatePasswordKey);
}
PZ_Unlock(handle->passwordLock);
@@ -578,23 +572,23 @@ sftkdb_FreeUpdatePasswordKey(SFTKDBHandle *handle)
/* don't have one */
if (!handle) {
- return;
+ return;
}
/* if we're a cert db, we don't have one */
if (handle->type == SFTK_CERTDB_TYPE) {
- return;
+ return;
}
PZ_Lock(handle->passwordLock);
if (handle->updatePasswordKey) {
- key = handle->updatePasswordKey;
- handle->updatePasswordKey = NULL;
+ key = handle->updatePasswordKey;
+ handle->updatePasswordKey = NULL;
}
PZ_Unlock(handle->passwordLock);
if (key) {
- SECITEM_ZfreeItem(key, PR_TRUE);
+ SECITEM_ZfreeItem(key, PR_TRUE);
}
return;
@@ -602,24 +596,24 @@ sftkdb_FreeUpdatePasswordKey(SFTKDBHandle *handle)
/*
* 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,
+ * 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;
+ return keydb->db;
}
if (!sftkdb_InUpdateMerge(keydb)) {
- return keydb->update;
+ return keydb->update;
}
if (sftkdb_NeedUpdateDBPassword(keydb)) {
- return keydb->update;
+ return keydb->update;
}
return keydb->db;
}
@@ -629,7 +623,7 @@ sftk_getPWSDB(SFTKDBHandle *keydb)
* This is will show up outside of PKCS #11 as CKF_USER_PIN_INIT
* in the token flags.
*/
-SECStatus
+SECStatus
sftkdb_HasPasswordSet(SFTKDBHandle *keydb)
{
SECItem salt, value;
@@ -639,12 +633,12 @@ sftkdb_HasPasswordSet(SFTKDBHandle *keydb)
SDB *db;
if (keydb == NULL) {
- return SECFailure;
+ return SECFailure;
}
db = sftk_getPWSDB(keydb);
if (db == NULL) {
- return SECFailure;
+ return SECFailure;
}
salt.data = saltData;
@@ -654,13 +648,12 @@ sftkdb_HasPasswordSet(SFTKDBHandle *keydb)
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);
+ 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;
}
@@ -671,7 +664,7 @@ sftkdb_HasPasswordSet(SFTKDBHandle *keydb)
/*
* check if the supplied password is valid
*/
-SECStatus
+SECStatus
sftkdb_CheckPassword(SFTKDBHandle *keydb, const char *pw, PRBool *tokenRemoved)
{
SECStatus rv;
@@ -684,18 +677,19 @@ sftkdb_CheckPassword(SFTKDBHandle *keydb, const char *pw, PRBool *tokenRemoved)
CK_RV crv;
if (keydb == NULL) {
- return SECFailure;
+ return SECFailure;
}
db = sftk_getPWSDB(keydb);
if (db == NULL) {
- return SECFailure;
+ return SECFailure;
}
key.data = NULL;
key.len = 0;
- if (pw == NULL) pw="";
+ if (pw == NULL)
+ pw = "";
/* get the entry from the database */
salt.data = saltData;
@@ -704,148 +698,148 @@ sftkdb_CheckPassword(SFTKDBHandle *keydb, const char *pw, PRBool *tokenRemoved)
value.len = sizeof(valueData);
crv = (*db->sdb_GetMetaData)(db, "password", &salt, &value);
if (crv != CKR_OK) {
- rv = SECFailure;
- goto done;
+ 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;
+ goto done;
}
/* decrypt the entry value */
rv = sftkdb_DecryptAttribute(&key, &value, &result);
if (rv != SECSuccess) {
- goto done;
+ 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.
- *
- */
+ 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
+ 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.
+ *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);
- }
+ * 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); */
+ /*PORT_SetError( bad password); */
}
done:
if (key.data) {
- PORT_ZFree(key.data,key.len);
+ PORT_ZFree(key.data, key.len);
}
if (result) {
- SECITEM_FreeItem(result,PR_TRUE);
+ SECITEM_FreeItem(result, PR_TRUE);
}
return rv;
}
@@ -859,24 +853,23 @@ 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_OBJECT_HANDLE id, SECItem *newKey)
{
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},
+ { 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);
+ CK_ULONG authAttrCount = sizeof(authAttrs) / sizeof(CK_ATTRIBUTE);
unsigned int i, count;
SFTKDBHandle *keyHandle = handle;
SDB *keyTarget = NULL;
@@ -884,39 +877,39 @@ sftk_updateMacs(PLArenaPool *arena, SFTKDBHandle *handle,
id &= SFTK_OBJ_ID_MASK;
if (handle->type != SFTK_KEYDB_TYPE) {
- keyHandle = handle->peerDB;
+ keyHandle = handle->peerDB;
}
if (keyHandle == NULL) {
- return CKR_OK;
+ 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;
+ if ((keyTarget->sdb_flags & SDB_HAS_META) == 0) {
+ return CKR_OK;
}
/*
- * STEP 1: find the MACed attributes of this object
+ * STEP 1: find the MACed attributes of this object
*/
(void)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) {
- break;
- }
+ 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) {
+ break;
+ }
}
/* if count was zero, none were found, finished with MACs */
if (count == 0) {
- return CKR_OK;
+ return CKR_OK;
}
(void)sftkdb_GetAttributeValue(handle, id, authAttrs, authAttrCount);
@@ -924,48 +917,49 @@ sftk_updateMacs(PLArenaPool *arena, SFTKDBHandle *handle,
/* 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;
- }
+ 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_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);
+ { 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);
unsigned int i, count;
/*
@@ -980,74 +974,74 @@ sftk_updateEncrypted(PLArenaPool *arena, SFTKDBHandle *keydb,
* 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
+ 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 ((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;
+ /* no valid entries found, return error based on crv2 */
+ return crv2;
}
if (last == NULL) {
- last = &privAttrs[privAttrCount-1];
+ last = &privAttrs[privAttrCount - 1];
}
if (crv != CKR_OK) {
- return crv;
+ return crv;
}
/* read the attributes */
- count = (last-first)+1;
+ count = (last - first) + 1;
crv = sftkdb_GetAttributeValue(keydb, id, first, count);
if (crv != CKR_OK) {
- return crv;
+ 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);
+ 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
*/
@@ -1058,10 +1052,10 @@ sftk_updateEncrypted(PLArenaPool *arena, SFTKDBHandle *keydb,
return crv;
}
-
+
static CK_RV
-sftk_convertAttributes(SFTKDBHandle *handle,
- CK_OBJECT_HANDLE id, SECItem *newKey)
+sftk_convertAttributes(SFTKDBHandle *handle,
+ CK_OBJECT_HANDLE id, SECItem *newKey)
{
CK_RV crv = CKR_OK;
PLArenaPool *arena = NULL;
@@ -1069,7 +1063,7 @@ sftk_convertAttributes(SFTKDBHandle *handle,
/* get a new arena to simplify cleanup */
arena = PORT_NewArena(1024);
if (!arena) {
- return CKR_HOST_MEMORY;
+ return CKR_HOST_MEMORY;
}
/*
@@ -1077,14 +1071,14 @@ sftk_convertAttributes(SFTKDBHandle *handle,
*/
crv = sftk_updateMacs(arena, handle, id, newKey);
if (crv != CKR_OK) {
- goto loser;
+ goto loser;
}
if (handle->type == SFTK_KEYDB_TYPE) {
- crv = sftk_updateEncrypted(arena, handle, id, newKey);
- if (crv != CKR_OK) {
- goto loser;
- }
+ crv = sftk_updateEncrypted(arena, handle, id, newKey);
+ if (crv != CKR_OK) {
+ goto loser;
+ }
}
/* free up our mess */
@@ -1098,13 +1092,12 @@ loser:
return crv;
}
-
/*
* must be called with the old key active.
*/
CK_RV
-sftkdb_convertObjects(SFTKDBHandle *handle, CK_ATTRIBUTE *template,
- CK_ULONG count, SECItem *newKey)
+sftkdb_convertObjects(SFTKDBHandle *handle, CK_ATTRIBUTE *template,
+ CK_ULONG count, SECItem *newKey)
{
SDBFind *find = NULL;
CK_ULONG idCount = SFTK_MAX_IDS;
@@ -1115,26 +1108,26 @@ sftkdb_convertObjects(SFTKDBHandle *handle, CK_ATTRIBUTE *template,
crv = sftkdb_FindObjectsInit(handle, template, count, &find);
if (crv != CKR_OK) {
- return crv;
+ 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);
- }
+ 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;
+ if (crv == CKR_OK)
+ crv = crv2;
return crv;
}
-
/*
* change the database password.
*/
SECStatus
-sftkdb_ChangePassword(SFTKDBHandle *keydb,
+sftkdb_ChangePassword(SFTKDBHandle *keydb,
char *oldPin, char *newPin, PRBool *tokenRemoved)
{
SECStatus rv = SECSuccess;
@@ -1149,12 +1142,12 @@ sftkdb_ChangePassword(SFTKDBHandle *keydb,
SDB *db;
if (keydb == NULL) {
- return SECFailure;
+ return SECFailure;
}
db = SFTK_GET_SDB(keydb);
if (db == NULL) {
- return SECFailure;
+ return SECFailure;
}
newKey.data = NULL;
@@ -1162,8 +1155,8 @@ sftkdb_ChangePassword(SFTKDBHandle *keydb,
/* make sure we have a valid old pin */
crv = (*keydb->db->sdb_Begin)(keydb->db);
if (crv != CKR_OK) {
- rv = SECFailure;
- goto loser;
+ rv = SECFailure;
+ goto loser;
}
salt.data = saltData;
salt.len = sizeof(saltData);
@@ -1171,68 +1164,66 @@ sftkdb_ChangePassword(SFTKDBHandle *keydb,
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;
- }
+ rv = sftkdb_CheckPassword(keydb, oldPin, tokenRemoved);
+ if (rv == SECFailure) {
+ goto loser;
+ }
} else {
- salt.len = SHA1_LENGTH;
- RNG_GenerateGlobalRandomBytes(salt.data,salt.len);
+ salt.len = SHA1_LENGTH;
+ RNG_GenerateGlobalRandomBytes(salt.data, salt.len);
}
rv = sftkdb_passwordToKey(keydb, &salt, newPin, &newKey);
if (rv != SECSuccess) {
- goto loser;
+ goto loser;
}
-
/*
* convert encrypted entries here.
*/
crv = sftkdb_convertObjects(keydb, NULL, 0, &newKey);
if (crv != CKR_OK) {
- rv = SECFailure;
- goto loser;
+ 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;
- }
+ 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;
+ 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;
+ rv = SECFailure;
+ goto loser;
}
crv = (*keydb->db->sdb_Commit)(keydb->db);
if (crv != CKR_OK) {
- rv = SECFailure;
- goto loser;
+ rv = SECFailure;
+ goto loser;
}
keydb->newKey = NULL;
@@ -1241,15 +1232,15 @@ sftkdb_ChangePassword(SFTKDBHandle *keydb,
loser:
if (newKey.data) {
- PORT_ZFree(newKey.data,newKey.len);
+ PORT_ZFree(newKey.data, newKey.len);
}
if (result) {
- SECITEM_FreeItem(result, PR_TRUE);
+ SECITEM_FreeItem(result, PR_TRUE);
}
if (rv != SECSuccess) {
(*keydb->db->sdb_Abort)(keydb->db);
}
-
+
return rv;
}
@@ -1264,9 +1255,7 @@ sftkdb_ClearPassword(SFTKDBHandle *keydb)
oldKey.len = 0;
sftkdb_switchKeys(keydb, &oldKey);
if (oldKey.data) {
- PORT_ZFree(oldKey.data, oldKey.len);
+ PORT_ZFree(oldKey.data, oldKey.len);
}
return SECSuccess;
}
-
-
diff --git a/nss/lib/softoken/softkver.h b/nss/lib/softoken/softkver.h
index c7e25e1..cbdd29b 100644
--- a/nss/lib/softoken/softkver.h
+++ b/nss/lib/softoken/softkver.h
@@ -9,11 +9,7 @@
#define _SOFTKVER_H_
#ifndef NSS_DISABLE_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
@@ -25,11 +21,11 @@
* The format of the version string should be
* "<major version>.<minor version>[.<patch level>[.<build number>]][ <ECC>][ <Beta>]"
*/
-#define SOFTOKEN_VERSION "3.21" SOFTOKEN_ECC_STRING
-#define SOFTOKEN_VMAJOR 3
-#define SOFTOKEN_VMINOR 21
-#define SOFTOKEN_VPATCH 0
-#define SOFTOKEN_VBUILD 0
-#define SOFTOKEN_BETA PR_FALSE
+#define SOFTOKEN_VERSION "3.28.1" SOFTOKEN_ECC_STRING
+#define SOFTOKEN_VMAJOR 3
+#define SOFTOKEN_VMINOR 28
+#define SOFTOKEN_VPATCH 1
+#define SOFTOKEN_VBUILD 0
+#define SOFTOKEN_BETA PR_FALSE
#endif /* _SOFTKVER_H_ */
diff --git a/nss/lib/softoken/softoken.gyp b/nss/lib/softoken/softoken.gyp
new file mode 100644
index 0000000..8d72e60
--- /dev/null
+++ b/nss/lib/softoken/softoken.gyp
@@ -0,0 +1,71 @@
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+{
+ 'includes': [
+ '../../coreconf/config.gypi'
+ ],
+ 'targets': [
+ {
+ 'target_name': 'softokn',
+ 'type': 'static_library',
+ 'sources': [
+ 'fipsaudt.c',
+ 'fipstest.c',
+ 'fipstokn.c',
+ 'jpakesftk.c',
+ 'lgglue.c',
+ 'lowkey.c',
+ 'lowpbe.c',
+ 'padbuf.c',
+ 'pkcs11.c',
+ 'pkcs11c.c',
+ 'pkcs11u.c',
+ 'sdb.c',
+ 'sftkdb.c',
+ 'sftkhmac.c',
+ 'sftkpars.c',
+ 'sftkpwd.c',
+ 'softkver.c',
+ 'tlsprf.c'
+ ],
+ 'dependencies': [
+ '<(DEPTH)/exports.gyp:nss_exports',
+ '<(DEPTH)/lib/sqlite/sqlite.gyp:sqlite3',
+ '<(DEPTH)/lib/freebl/freebl.gyp:freebl',
+ ]
+ },
+ {
+ 'target_name': 'softokn3',
+ 'type': 'shared_library',
+ 'dependencies': [
+ 'softokn',
+ ],
+ 'conditions': [
+ [ 'moz_fold_libs==0', {
+ 'dependencies': [
+ '<(DEPTH)/lib/util/util.gyp:nssutil3',
+ ],
+ }, {
+ 'libraries': [
+ '<(moz_folded_library_name)',
+ ],
+ }],
+ ],
+ 'variables': {
+ 'mapfile': 'softokn.def'
+ }
+ }
+ ],
+ 'target_defaults': {
+ 'defines': [
+ 'SHLIB_SUFFIX=\"<(dll_suffix)\"',
+ 'SHLIB_PREFIX=\"<(dll_prefix)\"',
+ 'SOFTOKEN_LIB_NAME=\"libsoftokn3.so\"',
+ 'SHLIB_VERSION=\"3\"'
+ ]
+ },
+ 'variables': {
+ 'module': 'nss'
+ }
+}
diff --git a/nss/lib/softoken/softoken.h b/nss/lib/softoken/softoken.h
index fbd00b6..0e943d3 100644
--- a/nss/lib/softoken/softoken.h
+++ b/nss/lib/softoken/softoken.h
@@ -36,7 +36,7 @@ RSA_HashCheckSign(SECOidTag hashOid, NSSLOWKEYPublicKey *key,
const unsigned char *hash, unsigned int hashLen);
/*
-** Prepare a buffer for padded CBC encryption, growing to the appropriate
+** Prepare a buffer for padded CBC encryption, growing to the appropriate
** boundary, filling with the appropriate padding.
**
** blockSize must be a power of 2.
@@ -48,21 +48,20 @@ RSA_HashCheckSign(SECOidTag hashOid, NSSLOWKEYPublicKey *key,
** 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(PLArenaPool *arena, unsigned char *inbuf,
- unsigned int inlen, unsigned int *outlen,
- int blockSize);
-
+extern unsigned char *CBC_PadBuffer(PLArenaPool *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.
+** Power-Up selftests are required for FIPS.
*/
-extern CK_RV sftk_fipsPowerUpSelfTest( void );
+/* make sure Power-up selftests have been run. */
+extern CK_RV sftk_FIPSEntryOK(void);
/*
** make known fixed PKCS #11 key types to their sizes in bytes
-*/
+*/
unsigned long sftk_MapKeySize(CK_KEY_TYPE keyType);
/*
@@ -70,73 +69,73 @@ unsigned long sftk_MapKeySize(CK_KEY_TYPE keyType);
*/
extern PRBool sftk_audit_enabled;
-extern void sftk_LogAuditMessage(NSSAuditSeverity severity,
- NSSAuditType, const char *msg);
+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);
+ 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);
+ 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);
+ 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);
+ 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);
+ 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);
+ 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);
+ 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);
+ 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);
+ 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);
+ 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);
+ 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);
+ 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);
+ CK_OBJECT_HANDLE hKey, CK_RV rv);
/*
** FIPS 140-2 Error state
@@ -150,12 +149,12 @@ extern PRBool sftk_fatalError;
#ifdef DEBUG
-#define FORK_ASSERT() \
- { \
- char* forkAssert = getenv("NSS_STRICT_NOFORK"); \
- if ( (!forkAssert) || (0 == strcmp(forkAssert, "1")) ) { \
- PORT_Assert(0); \
- } \
+#define FORK_ASSERT() \
+ { \
+ char *forkAssert = PR_GetEnvSecure("NSS_STRICT_NOFORK"); \
+ if ((!forkAssert) || (0 == strcmp(forkAssert, "1"))) { \
+ PORT_Assert(0); \
+ } \
}
#else
@@ -170,8 +169,8 @@ extern PRBool sftk_fatalError;
* - getpid method
*/
-#if !defined (CHECK_FORK_MIXED) && !defined(CHECK_FORK_PTHREAD) && \
- !defined (CHECK_FORK_GETPID)
+#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
@@ -221,31 +220,32 @@ extern PRBool forked;
extern pid_t myPid;
#define PARENT_FORKED() (myPid && myPid != getpid())
-
+
#endif
extern PRBool parentForkedAfterC_Initialize;
extern PRBool sftkForkCheckDisabled;
-#define CHECK_FORK() \
- do { \
+#define CHECK_FORK() \
+ do { \
if (!sftkForkCheckDisabled && PARENT_FORKED()) { \
- FORK_ASSERT(); \
- return CKR_DEVICE_ERROR; \
- } \
+ FORK_ASSERT(); \
+ return CKR_DEVICE_ERROR; \
+ } \
} while (0)
-#define SKIP_AFTER_FORK(x) if (!parentForkedAfterC_Initialize) x
+#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; \
- } \
+#define ENABLE_FORK_CHECK() \
+ { \
+ char *doForkCheck = PR_GetEnvSecure("NSS_STRICT_NOFORK"); \
+ if (doForkCheck && !strcmp(doForkCheck, "DISABLED")) { \
+ sftkForkCheckDisabled = PR_TRUE; \
+ } \
}
-
#else
/* non-Unix platforms, or fork check disabled */
@@ -260,7 +260,6 @@ extern PRBool sftkForkCheckDisabled;
#endif
-
SEC_END_PROTOS
#endif /* _SOFTOKEN_H_ */
diff --git a/nss/lib/softoken/softokn.def b/nss/lib/softoken/softokn.def
index 24c5915..0c71a1b 100644
--- a/nss/lib/softoken/softokn.def
+++ b/nss/lib/softoken/softokn.def
@@ -5,13 +5,13 @@
;+#
;+# 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
+;+# 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.
+;+# 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.
+;+# 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 ";-"
diff --git a/nss/lib/softoken/softoknt.h b/nss/lib/softoken/softoknt.h
index 67dc294..0716898 100644
--- a/nss/lib/softoken/softoknt.h
+++ b/nss/lib/softoken/softoknt.h
@@ -8,15 +8,15 @@
#ifndef _SOFTOKNT_H_
#define _SOFTOKNT_H_
-#define NSS_SOFTOKEN_DEFAULT_CHUNKSIZE 2048
+#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 */
+ NSS_AUDIT_ERROR = 3, /* errors */
+ NSS_AUDIT_WARNING = 2, /* warning messages */
+ NSS_AUDIT_INFO = 1 /* informational messages */
} NSSAuditSeverity;
typedef enum {
diff --git a/nss/lib/softoken/tlsprf.c b/nss/lib/softoken/tlsprf.c
index 0ebad60..05e2468 100644
--- a/nss/lib/softoken/tlsprf.c
+++ b/nss/lib/softoken/tlsprf.c
@@ -8,71 +8,70 @@
#include "blapi.h"
#include "secerr.h"
-#define SFTK_OFFSETOF(str, memb) ((PRPtrdiff)(&(((str *)0)->memb)))
-
-static void sftk_TLSPRFNull(void *data, PRBool freeit)
+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. */
- HASH_HashType cxHashAlg; /* hash algorithm to use for TLS 1.2+ */
- unsigned int cxOutLen; /* bytes of output if nonzero */
- unsigned char cxBuf[512]; /* actual size may be larger than 512. */
+ 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. */
+ HASH_HashType cxHashAlg; /* hash algorithm to use for TLS 1.2+ */
+ unsigned int cxOutLen; /* bytes of output if nonzero */
+ 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)
+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 (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;
+ /* 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
+static void
sftk_TLSPRFEnd(TLSPRFContext *ctx, unsigned char *hashout,
- unsigned int *pDigestLen, unsigned int maxDigestLen)
+ 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. */
+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;
@@ -80,58 +79,57 @@ sftk_TLSPRFUpdate(TLSPRFContext *cx,
SECItem secretItem;
if (cx->cxRv != SECSuccess)
- return cx->cxRv;
+ return cx->cxRv;
secretItem.data = cx->cxBufPtr;
- secretItem.len = cx->cxKeyLen;
+ secretItem.len = cx->cxKeyLen;
seedItem.data = cx->cxBufPtr + cx->cxKeyLen;
- seedItem.len = cx->cxDataLen;
+ seedItem.len = cx->cxDataLen;
sigItem.data = sig;
if (cx->cxOutLen == 0) {
- sigItem.len = maxLen;
+ sigItem.len = maxLen;
} else if (cx->cxOutLen <= maxLen) {
- sigItem.len = cx->cxOutLen;
+ sigItem.len = cx->cxOutLen;
} else {
- PORT_SetError(SEC_ERROR_OUTPUT_LEN);
- return SECFailure;
+ PORT_SetError(SEC_ERROR_OUTPUT_LEN);
+ return SECFailure;
}
if (cx->cxHashAlg != HASH_AlgNULL) {
- rv = TLS_P_hash(cx->cxHashAlg, &secretItem, NULL, &seedItem, &sigItem,
- cx->cxIsFIPS);
+ rv = TLS_P_hash(cx->cxHashAlg, &secretItem, NULL, &seedItem, &sigItem,
+ cx->cxIsFIPS);
} else {
- rv = TLS_PRF(&secretItem, NULL, &seedItem, &sigItem, cx->cxIsFIPS);
+ rv = TLS_PRF(&secretItem, NULL, &seedItem, &sigItem, cx->cxIsFIPS);
}
if (rv == SECSuccess && sigLen != NULL)
- *sigLen = sigItem.len;
+ *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. */
+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;
+ unsigned char *tmp = (unsigned char *)PORT_Alloc(sigLen);
+ unsigned int tmpLen = sigLen;
+ SECStatus rv;
if (!tmp)
- return SECFailure;
+ 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);
+ /* 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));
+ rv = (SECStatus)(1 - !PORT_Memcmp(tmp, sig, sigLen));
}
PORT_ZFree(tmp, sigLen);
return rv;
@@ -141,27 +139,27 @@ 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);
+ 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,
- HASH_HashType hash_alg,
- unsigned int out_len)
+sftk_TLSPRFInit(SFTKSessionContext *context,
+ SFTKObject *key,
+ CK_KEY_TYPE key_type,
+ HASH_HashType hash_alg,
+ unsigned int out_len)
{
- SFTKAttribute * keyVal;
- TLSPRFContext * prf_cx;
- CK_RV crv = CKR_HOST_MEMORY;
- PRUint32 keySize;
- PRUint32 blockSize;
+ 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 */
+ return CKR_KEY_TYPE_INCONSISTENT; /* CKR_KEY_FUNCTION_NOT_PERMITTED */
context->multi = PR_TRUE;
@@ -169,33 +167,32 @@ sftk_TLSPRFInit(SFTKSessionContext *context,
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;
+ 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;
+ prf_cx->cxBufSize = blockSize - offsetof(TLSPRFContext, cxBuf);
+ prf_cx->cxRv = SECSuccess;
+ prf_cx->cxIsFIPS = (key->slot->slotID == FIPS_SLOT_ID);
+ prf_cx->cxBufPtr = prf_cx->cxBuf;
prf_cx->cxHashAlg = hash_alg;
- prf_cx->cxOutLen = out_len;
+ prf_cx->cxOutLen = out_len;
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;
+ 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);
+ if (keyVal)
+ sftk_FreeAttribute(keyVal);
return crv;
}
-
diff --git a/nss/lib/sqlite/Makefile b/nss/lib/sqlite/Makefile
index dd8ea14..9149368 100644
--- a/nss/lib/sqlite/Makefile
+++ b/nss/lib/sqlite/Makefile
@@ -14,6 +14,7 @@ include manifest.mn
# (2) Include "global" configuration information. (OPTIONAL) #
#######################################################################
+USE_GCOV =
include $(CORE_DEPTH)/coreconf/config.mk
#######################################################################
diff --git a/nss/lib/sqlite/README b/nss/lib/sqlite/README
index dbb9048..b3a726f 100644
--- a/nss/lib/sqlite/README
+++ b/nss/lib/sqlite/README
@@ -1,3 +1,3 @@
-This is SQLite 3.7.14.1.
+This is SQLite 3.10.2.
Local changes:
diff --git a/nss/lib/sqlite/exports.gyp b/nss/lib/sqlite/exports.gyp
new file mode 100644
index 0000000..0a424ba
--- /dev/null
+++ b/nss/lib/sqlite/exports.gyp
@@ -0,0 +1,25 @@
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+{
+ 'includes': [
+ '../../coreconf/config.gypi'
+ ],
+ 'targets': [
+ {
+ 'target_name': 'lib_sqlite_exports',
+ 'type': 'none',
+ 'copies': [
+ {
+ 'files': [
+ 'sqlite3.h'
+ ],
+ 'destination': '<(nss_private_dist_dir)/<(module)'
+ }
+ ]
+ }
+ ],
+ 'variables': {
+ 'module': 'nss'
+ }
+}
diff --git a/nss/lib/sqlite/sqlite.gyp b/nss/lib/sqlite/sqlite.gyp
new file mode 100644
index 0000000..6969893
--- /dev/null
+++ b/nss/lib/sqlite/sqlite.gyp
@@ -0,0 +1,50 @@
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+{
+ 'includes': [
+ '../../coreconf/config.gypi'
+ ],
+ 'conditions': [
+ ['use_system_sqlite==1', {
+ 'targets': [{
+ 'target_name': 'sqlite3',
+ 'type': 'none',
+ 'link_settings': {
+ 'libraries': ['<(sqlite_libs)'],
+ },
+ }],
+ }, {
+ 'targets': [
+ {
+ 'target_name': 'sqlite',
+ 'type': 'static_library',
+ 'sources': [
+ 'sqlite3.c'
+ ],
+ 'dependencies': [
+ '<(DEPTH)/exports.gyp:nss_exports'
+ ]
+ },
+ {
+ 'target_name': 'sqlite3',
+ 'type': 'shared_library',
+ 'dependencies': [
+ 'sqlite'
+ ],
+ 'variables': {
+ 'mapfile': 'sqlite.def'
+ }
+ }
+ ],
+ 'target_defaults': {
+ 'defines': [
+ 'SQLITE_THREADSAFE=1'
+ ]
+ },
+ 'variables': {
+ 'module': 'nss'
+ }
+ }]
+ ],
+}
diff --git a/nss/lib/sqlite/sqlite3.c b/nss/lib/sqlite/sqlite3.c
index 8f261e8..c0ab233 100644
--- a/nss/lib/sqlite/sqlite3.c
+++ b/nss/lib/sqlite/sqlite3.c
@@ -1,6 +1,6 @@
/******************************************************************************
** 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
+** version 3.10.2. 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
@@ -22,9 +22,6 @@
#ifndef SQLITE_PRIVATE
# define SQLITE_PRIVATE static
#endif
-#ifndef SQLITE_API
-# define SQLITE_API
-#endif
/************** Begin file sqliteInt.h ***************************************/
/*
** 2001 September 15
@@ -44,44 +41,15 @@
#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
+** Include the header file used to customize the compiler options for MSVC.
+** This should be done first so that it can successfully prevent spurious
+** compiler warnings due to subsequent content in this file and other files
+** that are included by this file.
*/
-#ifdef _HAVE_SQLITE_CONFIG_H
-#include "config.h"
-#endif
-
-/************** Include sqliteLimit.h in the middle of sqliteInt.h ***********/
-/************** Begin file sqliteLimit.h *************************************/
+/************** Include msvc.h in the middle of sqliteInt.h ******************/
+/************** Begin file msvc.h ********************************************/
/*
-** 2007 May 7
+** 2015 January 12
**
** The author disclaims copyright to this source code. In place of
** a legal notice, here is a blessing:
@@ -90,478 +58,158 @@
** 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
-
+** This file contains code that is specific to MSVC.
+*/
+#ifndef _MSVC_H_
+#define _MSVC_H_
+
+#if defined(_MSC_VER)
+#pragma warning(disable : 4054)
+#pragma warning(disable : 4055)
+#pragma warning(disable : 4100)
+#pragma warning(disable : 4127)
+#pragma warning(disable : 4130)
+#pragma warning(disable : 4152)
+#pragma warning(disable : 4189)
+#pragma warning(disable : 4206)
+#pragma warning(disable : 4210)
+#pragma warning(disable : 4232)
+#pragma warning(disable : 4244)
+#pragma warning(disable : 4305)
+#pragma warning(disable : 4306)
+#pragma warning(disable : 4702)
+#pragma warning(disable : 4706)
+#endif /* defined(_MSC_VER) */
+
+#endif /* _MSVC_H_ */
+
+/************** End of msvc.h ************************************************/
+/************** Continuing where we left off in sqliteInt.h ******************/
/*
-** The default size of a database page.
+** Special setup for VxWorks
*/
-#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
-
+/************** Include vxworks.h in the middle of sqliteInt.h ***************/
+/************** Begin file vxworks.h *****************************************/
/*
-** 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.
+** 2015-03-02
**
-** 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.
+** The author disclaims copyright to this source code. In place of
+** a legal notice, here is a blessing:
**
-** 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.
+** 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 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.
+** This file contains code that is specific to Wind River's VxWorks
*/
-#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(__RTP__) || defined(_WRS_KERNEL)
+/* This is VxWorks. Set up things specially for that OS
*/
-#if !defined(SQLITE_THREADSAFE)
-#if defined(THREADSAFE)
-# define SQLITE_THREADSAFE THREADSAFE
+#include <vxWorks.h>
+#include <pthread.h> /* amalgamator: dontcache */
+#define OS_VXWORKS 1
+#define SQLITE_OS_OTHER 0
+#define SQLITE_HOMEGROWN_RECURSIVE_MUTEX 1
+#define SQLITE_OMIT_LOAD_EXTENSION 1
+#define SQLITE_ENABLE_LOCKING_STYLE 0
+#define HAVE_UTIME 1
#else
-# define SQLITE_THREADSAFE 1 /* IMP: R-07272-22309 */
-#endif
-#endif
+/* This is not VxWorks. */
+#define OS_VXWORKS 0
+#endif /* defined(_WRS_KERNEL) */
-/*
-** 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
+/************** End of vxworks.h *********************************************/
+/************** Continuing where we left off in sqliteInt.h ******************/
/*
-** 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.)
+** 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.
**
-** 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.
+** 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.
**
-** 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.
+** 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.
**
-** 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.
+** 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.
**
-** 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.
+** Similar is true for Mac OS X. LFS is only supported on Mac OS X 9 and later.
*/
-#if !defined(NDEBUG) && !defined(SQLITE_DEBUG)
-# define NDEBUG 1
-#endif
-#if defined(NDEBUG) && defined(SQLITE_DEBUG)
-# undef NDEBUG
+#ifndef SQLITE_DISABLE_LFS
+# define _LARGE_FILE 1
+# ifndef _FILE_OFFSET_BITS
+# define _FILE_OFFSET_BITS 64
+# endif
+# define _LARGEFILE_SOURCE 1
#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__); }
+/* What version of GCC is being used. 0 means GCC is not being used */
+#ifdef __GNUC__
+# define GCC_VERSION (__GNUC__*1000000+__GNUC_MINOR__*1000+__GNUC_PATCHLEVEL__)
#else
-# define testcase(X)
+# define GCC_VERSION 0
#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)
+/* Needed for various definitions... */
+#if defined(__GNUC__) && !defined(_GNU_SOURCE)
+# define _GNU_SOURCE
#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)
+#if defined(__OpenBSD__) && !defined(_BSD_SOURCE)
+# define _BSD_SOURCE
#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.
+** For MinGW, check to see if we can include the header file containing its
+** version information, among other things. Normally, this internal MinGW
+** header file would [only] be included automatically by other MinGW header
+** files; however, the contained version information is now required by this
+** header file to work around binary compatibility issues (see below) and
+** this is the only known way to reliably obtain it. This entire #if block
+** would be completely unnecessary if there was any other way of detecting
+** MinGW via their preprocessor (e.g. if they customized their GCC to define
+** some MinGW-specific macros). When compiling for MinGW, either the
+** _HAVE_MINGW_H or _HAVE__MINGW_H (note the extra underscore) macro must be
+** defined; otherwise, detection of conditions specific to MinGW will be
+** disabled.
*/
-#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)
+#if defined(_HAVE_MINGW_H)
+# include "mingw.h"
+#elif defined(_HAVE__MINGW_H)
+# include "_mingw.h"
#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.
+** For MinGW version 4.x (and higher), check to see if the _USE_32BIT_TIME_T
+** define is required to maintain binary compatibility with the MSVC runtime
+** library in use (e.g. for Windows XP).
*/
-#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)
+#if !defined(_USE_32BIT_TIME_T) && !defined(_USE_64BIT_TIME_T) && \
+ defined(_WIN32) && !defined(_WIN64) && \
+ defined(__MINGW_MAJOR_VERSION) && __MINGW_MAJOR_VERSION >= 4 && \
+ defined(__MSVCRT__)
+# define _USE_32BIT_TIME_T
#endif
+/* The public SQLite interface. The _FILE_OFFSET_BITS macro must appear
+** first in QNX. Also, the _USE_32BIT_TIME_T macro must appear first for
+** MinGW.
+*/
/************** Include sqlite3.h in the middle of sqliteInt.h ***************/
/************** Begin file sqlite3.h *****************************************/
/*
@@ -589,7 +237,7 @@ SQLITE_PRIVATE void sqlite3Coverage(int);
**
** 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.
+** on how SQLite interfaces are supposed 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
@@ -609,21 +257,25 @@ extern "C" {
/*
-** Add the ability to override 'extern'
+** Provide the ability to override linkage features of the interface.
*/
#ifndef SQLITE_EXTERN
# define SQLITE_EXTERN extern
#endif
-
#ifndef SQLITE_API
# define SQLITE_API
#endif
-
+#ifndef SQLITE_CDECL
+# define SQLITE_CDECL
+#endif
+#ifndef SQLITE_STDCALL
+# define SQLITE_STDCALL
+#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
+** should not use deprecated interfaces - they are supported for backwards
** compatibility only. Application writers should be aware that
** experimental interfaces are subject to change in point releases.
**
@@ -673,9 +325,9 @@ extern "C" {
** [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"
+#define SQLITE_VERSION "3.10.2"
+#define SQLITE_VERSION_NUMBER 3010002
+#define SQLITE_SOURCE_ID "2016-01-20 15:27:19 17efb4209f97fb4971656086b138599a91a75ff9"
/*
** CAPI3REF: Run-Time Library Version Numbers
@@ -686,7 +338,7 @@ extern "C" {
** 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
+** the header, and thus ensure that the application is
** compiled with matching library and header files.
**
** <blockquote><pre>
@@ -708,9 +360,9 @@ extern "C" {
** 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);
+SQLITE_API const char *SQLITE_STDCALL sqlite3_libversion(void);
+SQLITE_API const char *SQLITE_STDCALL sqlite3_sourceid(void);
+SQLITE_API int SQLITE_STDCALL sqlite3_libversion_number(void);
/*
** CAPI3REF: Run-Time Library Compilation Options Diagnostics
@@ -735,8 +387,8 @@ SQLITE_API int sqlite3_libversion_number(void);
** [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);
+SQLITE_API int SQLITE_STDCALL sqlite3_compileoption_used(const char *zOptName);
+SQLITE_API const char *SQLITE_STDCALL sqlite3_compileoption_get(int N);
#endif
/*
@@ -767,7 +419,7 @@ SQLITE_API const char *sqlite3_compileoption_get(int N);
** 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
+** or [SQLITE_CONFIG_SERIALIZED]. ^(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()
@@ -775,7 +427,7 @@ SQLITE_API const char *sqlite3_compileoption_get(int N);
**
** See the [threading mode] documentation for additional information.
*/
-SQLITE_API int sqlite3_threadsafe(void);
+SQLITE_API int SQLITE_STDCALL sqlite3_threadsafe(void);
/*
** CAPI3REF: Database Connection Handle
@@ -832,10 +484,11 @@ typedef sqlite_uint64 sqlite3_uint64;
/*
** CAPI3REF: Closing A Database Connection
+** DESTRUCTOR: sqlite3
**
** ^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
+** ^Calls to sqlite3_close() and sqlite3_close_v2() return [SQLITE_OK] if
** the [sqlite3] object is successfully destroyed and all associated
** resources are deallocated.
**
@@ -843,7 +496,7 @@ typedef sqlite_uint64 sqlite3_uint64;
** 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
+** and/or 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
@@ -854,9 +507,9 @@ typedef sqlite_uint64 sqlite3_uint64;
** [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
+** sqlite3_close_v2() 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
+** [sqlite3_backup] objects then it returns [SQLITE_OK] and the deallocation
** of resources is deferred until all [prepared statements], [BLOB handles],
** and [sqlite3_backup] objects are also destroyed.
**
@@ -871,8 +524,8 @@ typedef sqlite_uint64 sqlite3_uint64;
** ^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*);
+SQLITE_API int SQLITE_STDCALL sqlite3_close(sqlite3*);
+SQLITE_API int SQLITE_STDCALL sqlite3_close_v2(sqlite3*);
/*
** The type for a callback function.
@@ -883,6 +536,7 @@ typedef int (*sqlite3_callback)(void*,int,char**, char**);
/*
** CAPI3REF: One-Step Query Execution Interface
+** METHOD: sqlite3
**
** The sqlite3_exec() interface is a convenience wrapper around
** [sqlite3_prepare_v2()], [sqlite3_step()], and [sqlite3_finalize()],
@@ -934,15 +588,15 @@ typedef int (*sqlite3_callback)(void*,int,char**, char**);
** Restrictions:
**
** <ul>
-** <li> The application must insure that the 1st parameter to sqlite3_exec()
+** <li> The application must ensure that the 1st parameter to sqlite3_exec()
** is a valid and open [database connection].
-** <li> The application must not close [database connection] specified by
+** <li> The application must not close the [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(
+SQLITE_API int SQLITE_STDCALL sqlite3_exec(
sqlite3*, /* An open database */
const char *sql, /* SQL to be evaluated */
int (*callback)(void*,int,char**,char**), /* Callback function */
@@ -952,16 +606,14 @@ SQLITE_API int sqlite3_exec(
/*
** CAPI3REF: Result Codes
-** KEYWORDS: SQLITE_OK {error code} {error codes}
-** KEYWORDS: {result code} {result codes}
+** KEYWORDS: {result code definitions}
**
** 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].
+** See also: [extended result code definitions]
*/
#define SQLITE_OK 0 /* Successful result */
/* beginning-of-error-codes */
@@ -991,32 +643,27 @@ SQLITE_API int sqlite3_exec(
#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_NOTICE 27 /* Notifications from sqlite3_log() */
+#define SQLITE_WARNING 28 /* Warnings from sqlite3_log() */
#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}
+** KEYWORDS: {extended result code definitions}
**
-** In its default configuration, SQLite API routines return one of 26 integer
-** [SQLITE_OK | result codes]. However, experience has shown that many of
+** In its default configuration, SQLite API routines return one of 30 integer
+** [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
+** about errors. These [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.
+** [sqlite3_extended_result_codes()] API. Or, the extended code for
+** the most recent error can be obtained using
+** [sqlite3_extended_errcode()].
*/
#define SQLITE_IOERR_READ (SQLITE_IOERR | (1<<8))
#define SQLITE_IOERR_SHORT_READ (SQLITE_IOERR | (2<<8))
@@ -1041,15 +688,38 @@ SQLITE_API int sqlite3_exec(
#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_IOERR_MMAP (SQLITE_IOERR | (24<<8))
+#define SQLITE_IOERR_GETTEMPPATH (SQLITE_IOERR | (25<<8))
+#define SQLITE_IOERR_CONVPATH (SQLITE_IOERR | (26<<8))
+#define SQLITE_IOERR_VNODE (SQLITE_IOERR | (27<<8))
+#define SQLITE_IOERR_AUTH (SQLITE_IOERR | (28<<8))
#define SQLITE_LOCKED_SHAREDCACHE (SQLITE_LOCKED | (1<<8))
#define SQLITE_BUSY_RECOVERY (SQLITE_BUSY | (1<<8))
+#define SQLITE_BUSY_SNAPSHOT (SQLITE_BUSY | (2<<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_CANTOPEN_CONVPATH (SQLITE_CANTOPEN | (4<<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_READONLY_ROLLBACK (SQLITE_READONLY | (3<<8))
+#define SQLITE_READONLY_DBMOVED (SQLITE_READONLY | (4<<8))
#define SQLITE_ABORT_ROLLBACK (SQLITE_ABORT | (2<<8))
+#define SQLITE_CONSTRAINT_CHECK (SQLITE_CONSTRAINT | (1<<8))
+#define SQLITE_CONSTRAINT_COMMITHOOK (SQLITE_CONSTRAINT | (2<<8))
+#define SQLITE_CONSTRAINT_FOREIGNKEY (SQLITE_CONSTRAINT | (3<<8))
+#define SQLITE_CONSTRAINT_FUNCTION (SQLITE_CONSTRAINT | (4<<8))
+#define SQLITE_CONSTRAINT_NOTNULL (SQLITE_CONSTRAINT | (5<<8))
+#define SQLITE_CONSTRAINT_PRIMARYKEY (SQLITE_CONSTRAINT | (6<<8))
+#define SQLITE_CONSTRAINT_TRIGGER (SQLITE_CONSTRAINT | (7<<8))
+#define SQLITE_CONSTRAINT_UNIQUE (SQLITE_CONSTRAINT | (8<<8))
+#define SQLITE_CONSTRAINT_VTAB (SQLITE_CONSTRAINT | (9<<8))
+#define SQLITE_CONSTRAINT_ROWID (SQLITE_CONSTRAINT |(10<<8))
+#define SQLITE_NOTICE_RECOVER_WAL (SQLITE_NOTICE | (1<<8))
+#define SQLITE_NOTICE_RECOVER_ROLLBACK (SQLITE_NOTICE | (2<<8))
+#define SQLITE_WARNING_AUTOINDEX (SQLITE_WARNING | (1<<8))
+#define SQLITE_AUTH_USER (SQLITE_AUTH | (1<<8))
/*
** CAPI3REF: Flags For File Open Operations
@@ -1103,7 +773,11 @@ SQLITE_API int sqlite3_exec(
** 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.
+** guaranteed to be unchanged. The SQLITE_IOCAP_UNDELETABLE_WHEN_OPEN
+** flag indicate that a file cannot be deleted when open. The
+** SQLITE_IOCAP_IMMUTABLE flag indicates that the file is on
+** read-only media and cannot be changed even by processes with
+** elevated privileges.
*/
#define SQLITE_IOCAP_ATOMIC 0x00000001
#define SQLITE_IOCAP_ATOMIC512 0x00000002
@@ -1118,6 +792,7 @@ SQLITE_API int sqlite3_exec(
#define SQLITE_IOCAP_SEQUENTIAL 0x00000400
#define SQLITE_IOCAP_UNDELETABLE_WHEN_OPEN 0x00000800
#define SQLITE_IOCAP_POWERSAFE_OVERWRITE 0x00001000
+#define SQLITE_IOCAP_IMMUTABLE 0x00002000
/*
** CAPI3REF: File Locking Levels
@@ -1224,7 +899,7 @@ struct sqlite3_file {
** 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.
+** A [file control opcodes | 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
@@ -1289,24 +964,30 @@ struct sqlite3_io_methods {
void (*xShmBarrier)(sqlite3_file*);
int (*xShmUnmap)(sqlite3_file*, int deleteFlag);
/* Methods above are valid for version 2 */
+ int (*xFetch)(sqlite3_file*, sqlite3_int64 iOfst, int iAmt, void **pp);
+ int (*xUnfetch)(sqlite3_file*, sqlite3_int64 iOfst, void *p);
+ /* Methods above are valid for version 3 */
/* Additional methods may be added in future releases */
};
/*
** CAPI3REF: Standard File Control Opcodes
+** KEYWORDS: {file control opcodes} {file control opcode}
**
** These integer constants are opcodes for the xFileControl method
** of the [sqlite3_io_methods] object and for the [sqlite3_file_control()]
** interface.
**
+** <ul>
+** <li>[[SQLITE_FCNTL_LOCKSTATE]]
** 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>
+** is used during testing and is only available when the SQLITE_TEST
+** compile-time option is used.
+**
** <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
@@ -1327,19 +1008,38 @@ struct sqlite3_io_methods {
** <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.
+** connection. See also [SQLITE_FCNTL_JOURNAL_POINTER].
+**
+** <li>[[SQLITE_FCNTL_JOURNAL_POINTER]]
+** The [SQLITE_FCNTL_JOURNAL_POINTER] opcode is used to obtain a pointer
+** to the [sqlite3_file] object associated with the journal file (either
+** the [rollback journal] or the [write-ahead log]) for a particular database
+** connection. See also [SQLITE_FCNTL_FILE_POINTER].
**
** <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.
+** No longer in use.
+**
+** <li>[[SQLITE_FCNTL_SYNC]]
+** The [SQLITE_FCNTL_SYNC] opcode is generated internally by SQLite and
+** sent to the VFS immediately before the xSync method is invoked on a
+** database file descriptor. Or, if the xSync method is not invoked
+** because the user has configured SQLite with
+** [PRAGMA synchronous | PRAGMA synchronous=OFF] it is invoked in place
+** of the xSync method. In most cases, the pointer argument passed with
+** this file-control is NULL. However, if the database file is being synced
+** as part of a multi-database commit, the argument points to a nul-terminated
+** string containing the transactions master-journal file name. VFSes that
+** do not need this signal 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_COMMIT_PHASETWO]]
+** The [SQLITE_FCNTL_COMMIT_PHASETWO] opcode is generated internally by SQLite
+** and sent to the VFS after a transaction has been committed immediately
+** but before the database is unlocked. VFSes that do not need this signal
+** 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
@@ -1401,6 +1101,15 @@ struct sqlite3_io_methods {
** pointer in case this file-control is not implemented. This file-control
** is intended for diagnostic use only.
**
+** <li>[[SQLITE_FCNTL_VFS_POINTER]]
+** ^The [SQLITE_FCNTL_VFS_POINTER] opcode finds a pointer to the top-level
+** [VFSes] currently in use. ^(The argument X in
+** sqlite3_file_control(db,SQLITE_FCNTL_VFS_POINTER,X) must be
+** of type "[sqlite3_vfs] **". This opcodes will set *X
+** to a pointer to the top-level VFS.)^
+** ^When there are multiple VFS shims in the stack, this opcode finds the
+** upper-most shim 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
@@ -1417,7 +1126,9 @@ struct sqlite3_io_methods {
** [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
+** prepared statement if result string is NULL, or that returns a copy
+** of the result string if the string is non-NULL.
+** ^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]
@@ -1425,7 +1136,8 @@ struct sqlite3_io_methods {
** 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
+** ^The [SQLITE_FCNTL_BUSYHANDLER]
+** 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
@@ -1436,19 +1148,65 @@ struct sqlite3_io_methods {
** current operation.
**
** <li>[[SQLITE_FCNTL_TEMPFILENAME]]
-** ^Application can invoke this file-control to have SQLite generate a
+** ^Application can invoke the [SQLITE_FCNTL_TEMPFILENAME] 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.
**
+** <li>[[SQLITE_FCNTL_MMAP_SIZE]]
+** The [SQLITE_FCNTL_MMAP_SIZE] file control is used to query or set the
+** maximum number of bytes that will be used for memory-mapped I/O.
+** The argument is a pointer to a value of type sqlite3_int64 that
+** is an advisory maximum number of bytes in the file to memory map. The
+** pointer is overwritten with the old value. The limit is not changed if
+** the value originally pointed to is negative, and so the current limit
+** can be queried by passing in a pointer to a negative number. This
+** file-control is used internally to implement [PRAGMA mmap_size].
+**
+** <li>[[SQLITE_FCNTL_TRACE]]
+** The [SQLITE_FCNTL_TRACE] file control provides advisory information
+** to the VFS about what the higher layers of the SQLite stack are doing.
+** This file control is used by some VFS activity tracing [shims].
+** The argument is a zero-terminated string. Higher layers in the
+** SQLite stack may generate instances of this file control if
+** the [SQLITE_USE_FCNTL_TRACE] compile-time option is enabled.
+**
+** <li>[[SQLITE_FCNTL_HAS_MOVED]]
+** The [SQLITE_FCNTL_HAS_MOVED] file control interprets its argument as a
+** pointer to an integer and it writes a boolean into that integer depending
+** on whether or not the file has been renamed, moved, or deleted since it
+** was first opened.
+**
+** <li>[[SQLITE_FCNTL_WIN32_SET_HANDLE]]
+** The [SQLITE_FCNTL_WIN32_SET_HANDLE] opcode is used for debugging. This
+** opcode causes the xFileControl method to swap the file handle with the one
+** pointed to by the pArg argument. This capability is used during testing
+** and only needs to be supported when SQLITE_TEST is defined.
+**
+** <li>[[SQLITE_FCNTL_WAL_BLOCK]]
+** The [SQLITE_FCNTL_WAL_BLOCK] is a signal to the VFS layer that it might
+** be advantageous to block on the next WAL lock if the lock is not immediately
+** available. The WAL subsystem issues this signal during rare
+** circumstances in order to fix a problem with priority inversion.
+** Applications should <em>not</em> use this file-control.
+**
+** <li>[[SQLITE_FCNTL_ZIPVFS]]
+** The [SQLITE_FCNTL_ZIPVFS] opcode is implemented by zipvfs only. All other
+** VFS should return SQLITE_NOTFOUND for this opcode.
+**
+** <li>[[SQLITE_FCNTL_RBU]]
+** The [SQLITE_FCNTL_RBU] opcode is implemented by the special VFS used by
+** the RBU extension only. All other VFS should return SQLITE_NOTFOUND for
+** this opcode.
** </ul>
*/
#define SQLITE_FCNTL_LOCKSTATE 1
-#define SQLITE_GET_LOCKPROXYFILE 2
-#define SQLITE_SET_LOCKPROXYFILE 3
-#define SQLITE_LAST_ERRNO 4
+#define SQLITE_FCNTL_GET_LOCKPROXYFILE 2
+#define SQLITE_FCNTL_SET_LOCKPROXYFILE 3
+#define SQLITE_FCNTL_LAST_ERRNO 4
#define SQLITE_FCNTL_SIZE_HINT 5
#define SQLITE_FCNTL_CHUNK_SIZE 6
#define SQLITE_FCNTL_FILE_POINTER 7
@@ -1461,6 +1219,23 @@ struct sqlite3_io_methods {
#define SQLITE_FCNTL_PRAGMA 14
#define SQLITE_FCNTL_BUSYHANDLER 15
#define SQLITE_FCNTL_TEMPFILENAME 16
+#define SQLITE_FCNTL_MMAP_SIZE 18
+#define SQLITE_FCNTL_TRACE 19
+#define SQLITE_FCNTL_HAS_MOVED 20
+#define SQLITE_FCNTL_SYNC 21
+#define SQLITE_FCNTL_COMMIT_PHASETWO 22
+#define SQLITE_FCNTL_WIN32_SET_HANDLE 23
+#define SQLITE_FCNTL_WAL_BLOCK 24
+#define SQLITE_FCNTL_ZIPVFS 25
+#define SQLITE_FCNTL_RBU 26
+#define SQLITE_FCNTL_VFS_POINTER 27
+#define SQLITE_FCNTL_JOURNAL_POINTER 28
+
+/* deprecated names */
+#define SQLITE_GET_LOCKPROXYFILE SQLITE_FCNTL_GET_LOCKPROXYFILE
+#define SQLITE_SET_LOCKPROXYFILE SQLITE_FCNTL_SET_LOCKPROXYFILE
+#define SQLITE_LAST_ERRNO SQLITE_FCNTL_LAST_ERRNO
+
/*
** CAPI3REF: Mutex Handle
@@ -1712,7 +1487,7 @@ struct sqlite3_vfs {
** </ul>
**
** When unlocking, the same SHARED or EXCLUSIVE flag must be supplied as
-** was given no the corresponding lock.
+** was given on the corresponding lock.
**
** The xShmLock method can transition between unlocked and SHARED or
** between unlocked and EXCLUSIVE. It cannot transition between SHARED
@@ -1809,10 +1584,10 @@ struct sqlite3_vfs {
** 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);
+SQLITE_API int SQLITE_STDCALL sqlite3_initialize(void);
+SQLITE_API int SQLITE_STDCALL sqlite3_shutdown(void);
+SQLITE_API int SQLITE_STDCALL sqlite3_os_init(void);
+SQLITE_API int SQLITE_STDCALL sqlite3_os_end(void);
/*
** CAPI3REF: Configuring The SQLite Library
@@ -1823,9 +1598,11 @@ SQLITE_API int sqlite3_os_end(void);
** 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()
+** <b>The sqlite3_config() interface is not threadsafe. The application
+** must ensure that no other SQLite interfaces are invoked by other
+** threads while sqlite3_config() is running.</b>
+**
+** The sqlite3_config() interface
** 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
@@ -1843,10 +1620,11 @@ SQLITE_API int sqlite3_os_end(void);
** ^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, ...);
+SQLITE_API int SQLITE_CDECL sqlite3_config(int, ...);
/*
** CAPI3REF: Configure database connections
+** METHOD: sqlite3
**
** The sqlite3_db_config() interface is used to make configuration
** changes to a [database connection]. The interface is similar to
@@ -1861,7 +1639,7 @@ SQLITE_API int sqlite3_config(int, ...);
** ^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, ...);
+SQLITE_API int SQLITE_CDECL sqlite3_db_config(sqlite3*, int op, ...);
/*
** CAPI3REF: Memory Allocation Routines
@@ -1905,7 +1683,7 @@ SQLITE_API int sqlite3_db_config(sqlite3*, int op, ...);
** 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,
+** 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
@@ -1995,31 +1773,33 @@ struct sqlite3_mem_methods {
** 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
+** <dd> ^(The SQLITE_CONFIG_MALLOC 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]
+** <dd> ^(The SQLITE_CONFIG_GETMALLOC 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:
+** <dd> ^The SQLITE_CONFIG_MEMSTATUS 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()]
+** <li> [sqlite3_status64()]
** </ul>)^
** ^Memory allocation statistics are enabled by default unless SQLite is
** compiled with [SQLITE_DEFAULT_MEMSTATUS]=0 in which case memory
@@ -2027,53 +1807,72 @@ struct sqlite3_mem_methods {
** </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
+** <dd> ^The SQLITE_CONFIG_SCRATCH option specifies a static memory buffer
+** that SQLite can use for scratch memory. ^(There are three arguments
+** to SQLITE_CONFIG_SCRATCH: 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.
+** and the maximum number of scratch allocations (N).)^
** 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
+** ^SQLite will not use more than one scratch buffers per thread.
+** ^SQLite will never request 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>
+** [sqlite3_malloc()] will be used to obtain the memory needed.<p>
+** ^When the application provides any amount of scratch memory using
+** SQLITE_CONFIG_SCRATCH, SQLite avoids unnecessary large
+** [sqlite3_malloc|heap allocations].
+** This can help [Robson proof|prevent memory allocation failures] due to heap
+** fragmentation in low-memory embedded systems.
+** </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).
+** <dd> ^The SQLITE_CONFIG_PAGECACHE option specifies a memory pool
+** that SQLite can use for the database page cache with the default page
+** cache implementation.
+** This configuration option is a no-op if an application-define page
+** cache implementation is loaded using the [SQLITE_CONFIG_PCACHE2].
+** ^There are three arguments to SQLITE_CONFIG_PAGECACHE: A pointer to
+** 8-byte aligned memory (pMem), the size of each page cache line (sz),
+** and the number of cache lines (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>
+** (a power of two between 512 and 65536) plus some extra bytes for each
+** page header. ^The number of extra bytes needed by the page header
+** can be determined using [SQLITE_CONFIG_PCACHE_HDRSZ].
+** ^It is harmless, apart from the wasted memory,
+** for the sz parameter to be larger than necessary. The pMem
+** argument must be either a NULL pointer or a pointer to an 8-byte
+** aligned block of memory of at least sz*N bytes, otherwise
+** subsequent behavior is undefined.
+** ^When pMem is not NULL, SQLite will strive to use the memory provided
+** to satisfy page cache needs, falling back to [sqlite3_malloc()] if
+** a page cache line is larger than sz bytes or if all of the pMem buffer
+** is exhausted.
+** ^If pMem is NULL and N is non-zero, then each database connection
+** does an initial bulk allocation for page cache memory
+** from [sqlite3_malloc()] sufficient for N cache lines if N is positive or
+** of -1024*N bytes if N is negative, . ^If additional
+** page cache memory is needed beyond what is provided by the initial
+** allocation, then SQLite goes to [sqlite3_malloc()] separately for each
+** additional cache line. </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,
+** <dd> ^The SQLITE_CONFIG_HEAP 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].
+** ^The SQLITE_CONFIG_HEAP option is only available if SQLite is compiled
+** with either [SQLITE_ENABLE_MEMSYS3] or [SQLITE_ENABLE_MEMSYS5] and returns
+** [SQLITE_ERROR] if invoked otherwise.
+** ^There are three arguments to SQLITE_CONFIG_HEAP:
+** 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
+** memory pointer is not NULL 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.
@@ -2081,11 +1880,11 @@ struct sqlite3_mem_methods {
** 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
+** <dd> ^(The SQLITE_CONFIG_MUTEX 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
@@ -2093,8 +1892,8 @@ struct sqlite3_mem_methods {
** 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
+** <dd> ^(The SQLITE_CONFIG_GETMUTEX 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
@@ -2106,28 +1905,30 @@ struct sqlite3_mem_methods {
** 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
+** <dd> ^(The SQLITE_CONFIG_LOOKASIDE option takes two arguments that determine
+** the default size of lookaside memory 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
+** slots allocated to each database connection.)^ ^(SQLITE_CONFIG_LOOKASIDE
+** sets the <i>default</i> lookaside size. The [SQLITE_DBCONFIG_LOOKASIDE]
+** option 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>
+** <dd> ^(The SQLITE_CONFIG_PCACHE2 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 [sqlite3_pcache_methods2] object.</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>
+** <dd> ^(The SQLITE_CONFIG_GETPCACHE2 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
+** <dd> The SQLITE_CONFIG_LOG option is used to configure the SQLite
+** global [error log].
+** (^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
@@ -2145,27 +1946,29 @@ struct sqlite3_mem_methods {
** 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
+** <dd>^(The SQLITE_CONFIG_URI 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
+** 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
+** 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_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
+** <dd>^The SQLITE_CONFIG_COVERING_INDEX_SCAN 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
+** 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.
**
@@ -2173,12 +1976,12 @@ struct sqlite3_mem_methods {
** <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>
+** </dd>
**
** [[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
+** [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
@@ -2188,7 +1991,49 @@ struct sqlite3_mem_methods {
** 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.
+** third parameter is passed NULL In this case. An example of using this
+** configuration option can be seen in the "test_sqllog.c" source file in
+** the canonical SQLite source tree.</dd>
+**
+** [[SQLITE_CONFIG_MMAP_SIZE]]
+** <dt>SQLITE_CONFIG_MMAP_SIZE
+** <dd>^SQLITE_CONFIG_MMAP_SIZE takes two 64-bit integer (sqlite3_int64) values
+** that are the default mmap size limit (the default setting for
+** [PRAGMA mmap_size]) and the maximum allowed mmap size limit.
+** ^The default setting can be overridden by each database connection using
+** either the [PRAGMA mmap_size] command, or by using the
+** [SQLITE_FCNTL_MMAP_SIZE] file control. ^(The maximum allowed mmap size
+** will be silently truncated if necessary so that it does not exceed the
+** compile-time maximum mmap size set by the
+** [SQLITE_MAX_MMAP_SIZE] compile-time option.)^
+** ^If either argument to this option is negative, then that argument is
+** changed to its compile-time default.
+**
+** [[SQLITE_CONFIG_WIN32_HEAPSIZE]]
+** <dt>SQLITE_CONFIG_WIN32_HEAPSIZE
+** <dd>^The SQLITE_CONFIG_WIN32_HEAPSIZE option is only available if SQLite is
+** compiled for Windows with the [SQLITE_WIN32_MALLOC] pre-processor macro
+** defined. ^SQLITE_CONFIG_WIN32_HEAPSIZE takes a 32-bit unsigned integer value
+** that specifies the maximum size of the created heap.
+**
+** [[SQLITE_CONFIG_PCACHE_HDRSZ]]
+** <dt>SQLITE_CONFIG_PCACHE_HDRSZ
+** <dd>^The SQLITE_CONFIG_PCACHE_HDRSZ option takes a single parameter which
+** is a pointer to an integer and writes into that integer the number of extra
+** bytes per page required for each page in [SQLITE_CONFIG_PAGECACHE].
+** The amount of extra space required can change depending on the compiler,
+** target platform, and SQLite version.
+**
+** [[SQLITE_CONFIG_PMASZ]]
+** <dt>SQLITE_CONFIG_PMASZ
+** <dd>^The SQLITE_CONFIG_PMASZ option takes a single parameter which
+** is an unsigned integer and sets the "Minimum PMA Size" for the multithreaded
+** sorter to that integer. The default minimum PMA Size is set by the
+** [SQLITE_SORTER_PMASZ] compile-time option. New threads are launched
+** to help with sort operations when multithreaded sorting
+** is enabled (using the [PRAGMA threads] command) and the amount of content
+** to be sorted exceeds the page size times the minimum of the
+** [PRAGMA cache_size] setting and this value.
** </dl>
*/
#define SQLITE_CONFIG_SINGLETHREAD 1 /* nil */
@@ -2212,6 +2057,10 @@ struct sqlite3_mem_methods {
#define SQLITE_CONFIG_GETPCACHE2 19 /* sqlite3_pcache_methods2* */
#define SQLITE_CONFIG_COVERING_INDEX_SCAN 20 /* int */
#define SQLITE_CONFIG_SQLLOG 21 /* xSqllog, void* */
+#define SQLITE_CONFIG_MMAP_SIZE 22 /* sqlite3_int64, sqlite3_int64 */
+#define SQLITE_CONFIG_WIN32_HEAPSIZE 23 /* int nByte */
+#define SQLITE_CONFIG_PCACHE_HDRSZ 24 /* int *psz */
+#define SQLITE_CONFIG_PMASZ 25 /* unsigned int szPma */
/*
** CAPI3REF: Database Connection Configuration Options
@@ -2278,29 +2127,33 @@ struct sqlite3_mem_methods {
/*
** CAPI3REF: Enable Or Disable Extended Result Codes
+** METHOD: sqlite3
**
** ^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);
+SQLITE_API int SQLITE_STDCALL sqlite3_extended_result_codes(sqlite3*, int onoff);
/*
** CAPI3REF: Last Insert Rowid
+** METHOD: sqlite3
**
-** ^Each entry in an SQLite table has a unique 64-bit signed
+** ^Each entry in most SQLite tables (except for [WITHOUT ROWID] tables)
+** 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.
+** ^The sqlite3_last_insert_rowid(D) interface returns the [rowid] of the
+** most recent successful [INSERT] into a rowid table or [virtual table]
+** on database connection D.
+** ^Inserts into [WITHOUT ROWID] tables are not recorded.
+** ^If no successful [INSERT]s into rowid tables
+** have ever occurred on the database connection D,
+** then sqlite3_last_insert_rowid(D) returns zero.
**
** ^(If an [INSERT] occurs within a trigger or within a [virtual table]
** method, then this routine will return the [rowid] of the inserted
@@ -2332,52 +2185,51 @@ SQLITE_API int sqlite3_extended_result_codes(sqlite3*, int onoff);
** unpredictable and might not equal either the old or the new
** last insert [rowid].
*/
-SQLITE_API sqlite3_int64 sqlite3_last_insert_rowid(sqlite3*);
+SQLITE_API sqlite3_int64 SQLITE_STDCALL sqlite3_last_insert_rowid(sqlite3*);
/*
** CAPI3REF: Count The Number Of Rows Modified
+** METHOD: sqlite3
**
-** ^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.)^
+** ^This function returns the number of rows modified, inserted or
+** deleted by the most recently completed INSERT, UPDATE or DELETE
+** statement on the database connection specified by the only parameter.
+** ^Executing any other type of SQL statement does not modify the value
+** returned by this function.
+**
+** ^Only changes made directly by the INSERT, UPDATE or DELETE statement are
+** considered - auxiliary changes caused by [CREATE TRIGGER | triggers],
+** [foreign key actions] or [REPLACE] constraint resolution are not counted.
+**
+** Changes to a view that are intercepted by
+** [INSTEAD OF trigger | INSTEAD OF triggers] are not counted. ^The value
+** returned by sqlite3_changes() immediately after an INSERT, UPDATE or
+** DELETE statement run on a view is always zero. Only changes made to real
+** tables are counted.
+**
+** Things are more complicated if the sqlite3_changes() function is
+** executed while a trigger program is running. This may happen if the
+** program uses the [changes() SQL function], or if some other callback
+** function invokes sqlite3_changes() directly. Essentially:
+**
+** <ul>
+** <li> ^(Before entering a trigger program the value returned by
+** sqlite3_changes() function is saved. After the trigger program
+** has finished, the original value is restored.)^
+**
+** <li> ^(Within a trigger program each INSERT, UPDATE and DELETE
+** statement sets the value returned by sqlite3_changes()
+** upon completion as normal. Of course, this value will not include
+** any changes performed by sub-triggers, as the sqlite3_changes()
+** value will be saved and restored after each sub-trigger has run.)^
+** </ul>
+**
+** ^This means that if the changes() SQL function (or similar) is used
+** by the first INSERT, UPDATE or DELETE statement within a trigger, it
+** returns the value as set when the calling statement began executing.
+** ^If it is used by the second or subsequent such statement within a trigger
+** program, the value returned reflects the number of rows modified by the
+** previous INSERT, UPDATE or DELETE statement within the same trigger.
**
** See also the [sqlite3_total_changes()] interface, the
** [count_changes pragma], and the [changes() SQL function].
@@ -2386,25 +2238,23 @@ SQLITE_API sqlite3_int64 sqlite3_last_insert_rowid(sqlite3*);
** while [sqlite3_changes()] is running then the value returned
** is unpredictable and not meaningful.
*/
-SQLITE_API int sqlite3_changes(sqlite3*);
+SQLITE_API int SQLITE_STDCALL sqlite3_changes(sqlite3*);
/*
** CAPI3REF: Total Number Of Rows Modified
+** METHOD: sqlite3
**
-** ^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()]).
-**
+** ^This function returns the total number of rows inserted, modified or
+** deleted by all [INSERT], [UPDATE] or [DELETE] statements completed
+** since the database connection was opened, including those executed as
+** part of trigger programs. ^Executing any other type of SQL statement
+** does not affect the value returned by sqlite3_total_changes().
+**
+** ^Changes made as part of [foreign key actions] are included in the
+** count, but those made as part of REPLACE constraint resolution are
+** not. ^Changes to a view that are intercepted by INSTEAD OF triggers
+** are not counted.
+**
** See also the [sqlite3_changes()] interface, the
** [count_changes pragma], and the [total_changes() SQL function].
**
@@ -2412,10 +2262,11 @@ SQLITE_API int sqlite3_changes(sqlite3*);
** while [sqlite3_total_changes()] is running then the value
** returned is unpredictable and not meaningful.
*/
-SQLITE_API int sqlite3_total_changes(sqlite3*);
+SQLITE_API int SQLITE_STDCALL sqlite3_total_changes(sqlite3*);
/*
** CAPI3REF: Interrupt A Long-Running Query
+** METHOD: sqlite3
**
** ^This function causes any pending database operation to abort and
** return at its earliest opportunity. This routine is typically
@@ -2451,7 +2302,7 @@ SQLITE_API int sqlite3_total_changes(sqlite3*);
** If the database connection closes while [sqlite3_interrupt()]
** is running then bad things will likely happen.
*/
-SQLITE_API void sqlite3_interrupt(sqlite3*);
+SQLITE_API void SQLITE_STDCALL sqlite3_interrupt(sqlite3*);
/*
** CAPI3REF: Determine If An SQL Statement Is Complete
@@ -2486,33 +2337,41 @@ SQLITE_API void sqlite3_interrupt(sqlite3*);
** 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);
+SQLITE_API int SQLITE_STDCALL sqlite3_complete(const char *sql);
+SQLITE_API int SQLITE_STDCALL 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]
+** KEYWORDS: {busy-handler callback} {busy handler}
+** METHOD: sqlite3
+**
+** ^The sqlite3_busy_handler(D,X,P) routine sets a callback function X
+** that might be invoked with argument P whenever
+** an attempt is made to access a database table associated with
+** [database connection] D when another thread
+** or process has the table locked.
+** The sqlite3_busy_handler() interface is used to implement
+** [sqlite3_busy_timeout()] and [PRAGMA busy_timeout].
+**
+** ^If the busy callback is NULL, then [SQLITE_BUSY]
** 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
+** been invoked previously for the same 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.
+** access the database and [SQLITE_BUSY] is returned
+** to the application.
** ^If the callback returns non-zero, then another attempt
-** is made to open the database for reading and the cycle repeats.
+** is made to access the database 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.
+** to the application 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
@@ -2526,57 +2385,48 @@ SQLITE_API int sqlite3_complete16(const void *sql);
**
** ^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.
+** or evaluating [PRAGMA busy_timeout=N] will change the
+** busy handler and thus clear any previously set busy handler.
**
** The busy callback should not take any actions which modify the
-** database connection that invoked the busy handler. Any such actions
+** database connection that invoked the busy handler. In other words,
+** the busy handler is not reentrant. 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*);
+SQLITE_API int SQLITE_STDCALL sqlite3_busy_handler(sqlite3*, int(*)(void*,int), void*);
/*
** CAPI3REF: Set A Busy Timeout
+** METHOD: sqlite3
**
** ^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].
+** [SQLITE_BUSY].
**
** ^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
+** [database connection] at any given moment. If another busy handler
** was defined (using [sqlite3_busy_handler()]) prior to calling
** this routine, that other busy handler is cleared.)^
+**
+** See also: [PRAGMA busy_timeout]
*/
-SQLITE_API int sqlite3_busy_timeout(sqlite3*, int ms);
+SQLITE_API int SQLITE_STDCALL sqlite3_busy_timeout(sqlite3*, int ms);
/*
** CAPI3REF: Convenience Routines For Running Queries
+** METHOD: sqlite3
**
** This is a legacy interface that is preserved for backwards compatibility.
** Use of this interface is not recommended.
@@ -2647,7 +2497,7 @@ SQLITE_API int sqlite3_busy_timeout(sqlite3*, int ms);
** reflected in subsequent calls to [sqlite3_errcode()] or
** [sqlite3_errmsg()].
*/
-SQLITE_API int sqlite3_get_table(
+SQLITE_API int SQLITE_STDCALL sqlite3_get_table(
sqlite3 *db, /* An open database */
const char *zSql, /* SQL to be evaluated */
char ***pazResult, /* Results of the query */
@@ -2655,13 +2505,17 @@ SQLITE_API int sqlite3_get_table(
int *pnColumn, /* Number of result columns written here */
char **pzErrmsg /* Error msg written here */
);
-SQLITE_API void sqlite3_free_table(char **result);
+SQLITE_API void SQLITE_STDCALL 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.
+** These routines understand most of the common K&R formatting options,
+** plus some additional non-standard formats, detailed below.
+** Note that some of the more obscure formatting options from recent
+** C-library standards are omitted from this implementation.
**
** ^The sqlite3_mprintf() and sqlite3_vmprintf() routines write their
** results into memory obtained from [sqlite3_malloc()].
@@ -2694,7 +2548,7 @@ SQLITE_API void sqlite3_free_table(char **result);
** 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.
+** is are "%q", "%Q", "%w" 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.
@@ -2747,14 +2601,20 @@ SQLITE_API void sqlite3_free_table(char **result);
** The code above will render a correct SQL statement in the zSQL
** variable even if the zText variable is a NULL pointer.
**
+** ^(The "%w" formatting option is like "%q" except that it expects to
+** be contained within double-quotes instead of single quotes, and it
+** escapes the double-quote character instead of the single-quote
+** character.)^ The "%w" formatting option is intended for safely inserting
+** table and column names into a constructed SQL statement.
+**
** ^(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);
+SQLITE_API char *SQLITE_CDECL sqlite3_mprintf(const char*,...);
+SQLITE_API char *SQLITE_STDCALL sqlite3_vmprintf(const char*, va_list);
+SQLITE_API char *SQLITE_CDECL sqlite3_snprintf(int,char*,const char*, ...);
+SQLITE_API char *SQLITE_STDCALL sqlite3_vsnprintf(int,char*,const char*, va_list);
/*
** CAPI3REF: Memory Allocation Subsystem
@@ -2771,6 +2631,10 @@ SQLITE_API char *sqlite3_vsnprintf(int,char*,const char*, va_list);
** sqlite3_malloc() is zero or negative then sqlite3_malloc() returns
** a NULL pointer.
**
+** ^The sqlite3_malloc64(N) routine works just like
+** sqlite3_malloc(N) except that N is an unsigned 64-bit integer instead
+** of a signed 32-bit integer.
+**
** ^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
@@ -2782,24 +2646,38 @@ SQLITE_API char *sqlite3_vsnprintf(int,char*,const char*, va_list);
** 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()
+** ^The sqlite3_realloc(X,N) interface attempts to resize a
+** prior memory allocation X to be at least N bytes.
+** ^If the X parameter to sqlite3_realloc(X,N)
** 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
+** sqlite3_malloc(N).
+** ^If the N parameter to sqlite3_realloc(X,N) 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.
+** sqlite3_free(X).
+** ^sqlite3_realloc(X,N) returns a pointer to a memory allocation
+** of at least N bytes in size or NULL if insufficient memory is available.
** ^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()
+** by sqlite3_realloc(X,N) and the prior allocation is freed.
+** ^If sqlite3_realloc(X,N) returns NULL and N is positive, then the
+** prior allocation is not freed.
+**
+** ^The sqlite3_realloc64(X,N) interfaces works the same as
+** sqlite3_realloc(X,N) except that N is a 64-bit unsigned integer instead
+** of a 32-bit signed integer.
+**
+** ^If X is a memory allocation previously obtained from sqlite3_malloc(),
+** sqlite3_malloc64(), sqlite3_realloc(), or sqlite3_realloc64(), then
+** sqlite3_msize(X) returns the size of that memory allocation in bytes.
+** ^The value returned by sqlite3_msize(X) might be larger than the number
+** of bytes requested when X was allocated. ^If X is a NULL pointer then
+** sqlite3_msize(X) returns zero. If X points to something that is not
+** the beginning of memory allocation, or if it points to a formerly
+** valid memory allocation that has now been freed, then the behavior
+** of sqlite3_msize(X) is undefined and possibly harmful.
+**
+** ^The memory returned by sqlite3_malloc(), sqlite3_realloc(),
+** sqlite3_malloc64(), and sqlite3_realloc64()
** 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.
@@ -2826,9 +2704,12 @@ SQLITE_API char *sqlite3_vsnprintf(int,char*,const char*, va_list);
** 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*);
+SQLITE_API void *SQLITE_STDCALL sqlite3_malloc(int);
+SQLITE_API void *SQLITE_STDCALL sqlite3_malloc64(sqlite3_uint64);
+SQLITE_API void *SQLITE_STDCALL sqlite3_realloc(void*, int);
+SQLITE_API void *SQLITE_STDCALL sqlite3_realloc64(void*, sqlite3_uint64);
+SQLITE_API void SQLITE_STDCALL sqlite3_free(void*);
+SQLITE_API sqlite3_uint64 SQLITE_STDCALL sqlite3_msize(void*);
/*
** CAPI3REF: Memory Allocator Statistics
@@ -2853,8 +2734,8 @@ SQLITE_API void sqlite3_free(void*);
** 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);
+SQLITE_API sqlite3_int64 SQLITE_STDCALL sqlite3_memory_used(void);
+SQLITE_API sqlite3_int64 SQLITE_STDCALL sqlite3_memory_highwater(int resetFlag);
/*
** CAPI3REF: Pseudo-Random Number Generator
@@ -2866,18 +2747,22 @@ SQLITE_API sqlite3_int64 sqlite3_memory_highwater(int resetFlag);
** 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
+** ^The P parameter can be a NULL pointer.
+**
+** ^If this routine has not been previously called or if the previous
+** call had N less than one or a NULL pointer for P, then the PRNG is
+** seeded using randomness obtained from the xRandomness method of
+** the default [sqlite3_vfs] object.
+** ^If the previous call to this routine had an N of 1 or more and a
+** non-NULL P then the pseudo-randomness is generated
** internally and without recourse to the [sqlite3_vfs] xRandomness
** method.
*/
-SQLITE_API void sqlite3_randomness(int N, void *P);
+SQLITE_API void SQLITE_STDCALL sqlite3_randomness(int N, void *P);
/*
** CAPI3REF: Compile-Time Authorization Callbacks
+** METHOD: sqlite3
**
** ^This routine registers an authorizer callback with a particular
** [database connection], supplied in the first argument.
@@ -2956,7 +2841,7 @@ SQLITE_API void sqlite3_randomness(int N, void *P);
** 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(
+SQLITE_API int SQLITE_STDCALL sqlite3_set_authorizer(
sqlite3*,
int (*xAuth)(void*,int,const char*,const char*,const char*,const char*),
void *pUserData
@@ -2971,8 +2856,8 @@ SQLITE_API int sqlite3_set_authorizer(
** [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.
+** Note that SQLITE_IGNORE is also used as a [conflict resolution mode]
+** returned 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 */
@@ -3030,9 +2915,11 @@ SQLITE_API int sqlite3_set_authorizer(
#define SQLITE_FUNCTION 31 /* NULL Function Name */
#define SQLITE_SAVEPOINT 32 /* Operation Savepoint Name */
#define SQLITE_COPY 0 /* No longer used */
+#define SQLITE_RECURSIVE 33 /* NULL NULL */
/*
** CAPI3REF: Tracing And Profiling Functions
+** METHOD: sqlite3
**
** These routines register callback functions that can be used for
** tracing and profiling the execution of SQL statements.
@@ -3045,6 +2932,9 @@ SQLITE_API int sqlite3_set_authorizer(
** as each triggered subprogram is entered. The callbacks for triggers
** contain a UTF-8 SQL comment that identifies the trigger.)^
**
+** The [SQLITE_TRACE_SIZE_LIMIT] compile-time option can be used to limit
+** the length of [bound parameter] expansion in the output of sqlite3_trace().
+**
** ^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
@@ -3056,12 +2946,13 @@ SQLITE_API int sqlite3_set_authorizer(
** 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*,
+SQLITE_API void *SQLITE_STDCALL sqlite3_trace(sqlite3*, void(*xTrace)(void*,const char*), void*);
+SQLITE_API SQLITE_EXPERIMENTAL void *SQLITE_STDCALL sqlite3_profile(sqlite3*,
void(*xProfile)(void*,const char*,sqlite3_uint64), void*);
/*
** CAPI3REF: Query Progress Callbacks
+** METHOD: sqlite3
**
** ^The sqlite3_progress_handler(D,N,X,P) interface causes the callback
** function X to be invoked periodically during long running calls to
@@ -3070,9 +2961,10 @@ SQLITE_API SQLITE_EXPERIMENTAL void *sqlite3_profile(sqlite3*,
** 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
+** callback function X. ^The parameter N is the approximate number of
** [virtual machine instructions] that are evaluated between successive
-** invocations of the callback X.
+** invocations of the callback X. ^If N is less than one then the progress
+** handler is disabled.
**
** ^Only a single progress handler may be defined at one time per
** [database connection]; setting a new progress handler cancels the
@@ -3090,10 +2982,11 @@ SQLITE_API SQLITE_EXPERIMENTAL void *sqlite3_profile(sqlite3*,
** database connections for the meaning of "modify" in this paragraph.
**
*/
-SQLITE_API void sqlite3_progress_handler(sqlite3*, int, int(*)(void*), void*);
+SQLITE_API void SQLITE_STDCALL sqlite3_progress_handler(sqlite3*, int, int(*)(void*), void*);
/*
** CAPI3REF: Opening A New Database Connection
+** CONSTRUCTOR: sqlite3
**
** ^These routines open an SQLite database file as specified by the
** filename argument. ^The filename argument is interpreted as UTF-8 for
@@ -3108,9 +3001,9 @@ SQLITE_API void sqlite3_progress_handler(sqlite3*, int, int(*)(void*), void*);
** 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.
+** ^The default encoding will be UTF-8 for databases created using
+** sqlite3_open() or sqlite3_open_v2(). ^The default encoding for databases
+** created using sqlite3_open16() will be UTF-16 in the native byte order.
**
** Whether or not an error occurs when it is opened, resources
** associated with the [database connection] handle should be released by
@@ -3198,13 +3091,14 @@ SQLITE_API void sqlite3_progress_handler(sqlite3*, int, int(*)(void*), void*);
** 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:").
+** ^(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:
+** SQLite and its built-in [VFSes] interpret the
+** following query parameters:
**
** <ul>
** <li> <b>vfs</b>: ^The "vfs" parameter may be used to specify the name of
@@ -3236,8 +3130,30 @@ SQLITE_API void sqlite3_progress_handler(sqlite3*, int, int(*)(void*), void*);
** 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
+** a URI filename, its value overrides any behavior requested by setting
** SQLITE_OPEN_PRIVATECACHE or SQLITE_OPEN_SHAREDCACHE flag.
+**
+** <li> <b>psow</b>: ^The psow parameter indicates whether or not the
+** [powersafe overwrite] property does or does not apply to the
+** storage media on which the database file resides.
+**
+** <li> <b>nolock</b>: ^The nolock parameter is a boolean query parameter
+** which if set disables file locking in rollback journal modes. This
+** is useful for accessing a database on a filesystem that does not
+** support locking. Caution: Database corruption might result if two
+** or more processes write to the same database and any one of those
+** processes uses nolock=1.
+**
+** <li> <b>immutable</b>: ^The immutable parameter is a boolean query
+** parameter that indicates that the database file is stored on
+** read-only media. ^When immutable is set, SQLite assumes that the
+** database file cannot be changed, even by a process with higher
+** privilege, and so the database is opened read-only and all locking
+** and change detection is disabled. Caution: Setting the immutable
+** property on a database file that does in fact change can result
+** in incorrect query results and/or [SQLITE_CORRUPT] errors.
+** See also: [SQLITE_IOCAP_IMMUTABLE].
+**
** </ul>
**
** ^Specifying an unknown parameter in the query component of a URI is not an
@@ -3267,8 +3183,9 @@ SQLITE_API void sqlite3_progress_handler(sqlite3*, int, int(*)(void*), void*);
** 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:/home/fred/data.db?vfs=unix-dotfile <td>
+** Open file "/home/fred/data.db". Use the special VFS "unix-dotfile"
+** that uses dot-files in place of posix advisory locking.
** <tr><td> file:data.db?mode=readonly <td>
** An error. "readonly" is not a valid option for the "mode" parameter.
** </table>
@@ -3294,15 +3211,15 @@ SQLITE_API void sqlite3_progress_handler(sqlite3*, int, int(*)(void*), void*);
**
** See also: [sqlite3_temp_directory]
*/
-SQLITE_API int sqlite3_open(
+SQLITE_API int SQLITE_STDCALL sqlite3_open(
const char *filename, /* Database filename (UTF-8) */
sqlite3 **ppDb /* OUT: SQLite db handle */
);
-SQLITE_API int sqlite3_open16(
+SQLITE_API int SQLITE_STDCALL sqlite3_open16(
const void *filename, /* Database filename (UTF-16) */
sqlite3 **ppDb /* OUT: SQLite db handle */
);
-SQLITE_API int sqlite3_open_v2(
+SQLITE_API int SQLITE_STDCALL sqlite3_open_v2(
const char *filename, /* Database filename (UTF-8) */
sqlite3 **ppDb, /* OUT: SQLite db handle */
int flags, /* Flags */
@@ -3348,19 +3265,22 @@ SQLITE_API int sqlite3_open_v2(
** 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);
+SQLITE_API const char *SQLITE_STDCALL sqlite3_uri_parameter(const char *zFilename, const char *zParam);
+SQLITE_API int SQLITE_STDCALL sqlite3_uri_boolean(const char *zFile, const char *zParam, int bDefault);
+SQLITE_API sqlite3_int64 SQLITE_STDCALL 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()
+** METHOD: sqlite3
+**
+** ^If the most recent sqlite3_* API call associated with
+** [database connection] D failed, then the sqlite3_errcode(D) interface
+** returns the numeric [result code] or [extended result code] for that
+** API call.
+** If the most recent API call was successful,
+** then 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.
@@ -3391,40 +3311,41 @@ SQLITE_API sqlite3_int64 sqlite3_uri_int64(const char*, const char*, sqlite3_int
** 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);
+SQLITE_API int SQLITE_STDCALL sqlite3_errcode(sqlite3 *db);
+SQLITE_API int SQLITE_STDCALL sqlite3_extended_errcode(sqlite3 *db);
+SQLITE_API const char *SQLITE_STDCALL sqlite3_errmsg(sqlite3*);
+SQLITE_API const void *SQLITE_STDCALL sqlite3_errmsg16(sqlite3*);
+SQLITE_API const char *SQLITE_STDCALL sqlite3_errstr(int);
/*
-** CAPI3REF: SQL Statement Object
+** CAPI3REF: Prepared 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".
+** An instance of this object represents a single SQL statement that
+** has been compiled into binary form and is ready to be evaluated.
+**
+** Think of each SQL statement as a separate computer program. The
+** original SQL text is source code. A prepared statement object
+** is the compiled object code. All SQL must be converted into a
+** prepared statement before it can be run.
**
-** The life of a statement object goes something like this:
+** The life-cycle of a prepared statement object usually goes 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_*()
+** <li> Create the prepared statement object using [sqlite3_prepare_v2()].
+** <li> Bind values to [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
+** <li> Reset the prepared 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
+** METHOD: sqlite3
**
** ^(This interface allows the size of various constructs to be limited
** on a connection by connection basis. The first parameter is the
@@ -3462,7 +3383,7 @@ typedef struct sqlite3_stmt sqlite3_stmt;
**
** New run-time limit categories may be added in future releases.
*/
-SQLITE_API int sqlite3_limit(sqlite3*, int id, int newVal);
+SQLITE_API int SQLITE_STDCALL sqlite3_limit(sqlite3*, int id, int newVal);
/*
** CAPI3REF: Run-Time Limit Categories
@@ -3514,6 +3435,10 @@ SQLITE_API int sqlite3_limit(sqlite3*, int id, int newVal);
**
** [[SQLITE_LIMIT_TRIGGER_DEPTH]] ^(<dt>SQLITE_LIMIT_TRIGGER_DEPTH</dt>
** <dd>The maximum depth of recursion for triggers.</dd>)^
+**
+** [[SQLITE_LIMIT_WORKER_THREADS]] ^(<dt>SQLITE_LIMIT_WORKER_THREADS</dt>
+** <dd>The maximum number of auxiliary worker threads that a single
+** [prepared statement] may start.</dd>)^
** </dl>
*/
#define SQLITE_LIMIT_LENGTH 0
@@ -3527,10 +3452,13 @@ SQLITE_API int sqlite3_limit(sqlite3*, int id, int newVal);
#define SQLITE_LIMIT_LIKE_PATTERN_LENGTH 8
#define SQLITE_LIMIT_VARIABLE_NUMBER 9
#define SQLITE_LIMIT_TRIGGER_DEPTH 10
+#define SQLITE_LIMIT_WORKER_THREADS 11
/*
** CAPI3REF: Compiling An SQL Statement
** KEYWORDS: {SQL statement compiler}
+** METHOD: sqlite3
+** CONSTRUCTOR: sqlite3_stmt
**
** To execute an SQL query, it must first be compiled into a byte-code
** program using one of these routines.
@@ -3544,16 +3472,14 @@ SQLITE_API int sqlite3_limit(sqlite3*, int id, int newVal);
** 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 the nByte argument is negative, then zSql is read up to the
+** first zero terminator. ^If nByte is positive, then it is the
+** number of bytes read from zSql. ^If nByte is zero, then no prepared
+** statement is generated.
+** If the caller knows that the supplied string is nul-terminated, then
+** there is a small performance advantage to passing an nByte parameter that
+** is the number of bytes in the input string <i>including</i>
+** the nul-terminator.
**
** ^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
@@ -3583,7 +3509,8 @@ SQLITE_API int sqlite3_limit(sqlite3*, int id, int newVal);
** <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.
+** statement and try to run it again. As many as [SQLITE_MAX_SCHEMA_RETRY]
+** retries will occur before sqlite3_step() gives up and returns an error.
** </li>
**
** <li>
@@ -3605,32 +3532,31 @@ SQLITE_API int sqlite3_limit(sqlite3*, int id, int newVal);
** 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(
+SQLITE_API int SQLITE_STDCALL 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(
+SQLITE_API int SQLITE_STDCALL 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(
+SQLITE_API int SQLITE_STDCALL 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(
+SQLITE_API int SQLITE_STDCALL sqlite3_prepare16_v2(
sqlite3 *db, /* Database handle */
const void *zSql, /* SQL statement, UTF-16 encoded */
int nByte, /* Maximum length of zSql in bytes. */
@@ -3640,15 +3566,17 @@ SQLITE_API int sqlite3_prepare16_v2(
/*
** CAPI3REF: Retrieving Statement SQL
+** METHOD: sqlite3_stmt
**
** ^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);
+SQLITE_API const char *SQLITE_STDCALL sqlite3_sql(sqlite3_stmt *pStmt);
/*
** CAPI3REF: Determine If An SQL Statement Writes The Database
+** METHOD: sqlite3_stmt
**
** ^The sqlite3_stmt_readonly(X) interface returns true (non-zero) if
** and only if the [prepared statement] X makes no direct changes to
@@ -3676,14 +3604,16 @@ SQLITE_API const char *sqlite3_sql(sqlite3_stmt *pStmt);
** 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);
+SQLITE_API int SQLITE_STDCALL sqlite3_stmt_readonly(sqlite3_stmt *pStmt);
/*
** CAPI3REF: Determine If A Prepared Statement Has Been Reset
+** METHOD: sqlite3_stmt
**
** ^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
+** [sqlite3_step(S)] but has neither run to completion (returned
+** [SQLITE_DONE] from [sqlite3_step(S)]) nor
** 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]
@@ -3695,7 +3625,7 @@ SQLITE_API int sqlite3_stmt_readonly(sqlite3_stmt *pStmt);
** for example, in diagnostic routines to search for prepared
** statements that are holding a transaction open.
*/
-SQLITE_API int sqlite3_stmt_busy(sqlite3_stmt*);
+SQLITE_API int SQLITE_STDCALL sqlite3_stmt_busy(sqlite3_stmt*);
/*
** CAPI3REF: Dynamically Typed Value Object
@@ -3710,7 +3640,9 @@ SQLITE_API int sqlite3_stmt_busy(sqlite3_stmt*);
** 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.
+** whether or not it requires a protected sqlite3_value. The
+** [sqlite3_value_dup()] interface can be used to construct a new
+** protected sqlite3_value from an unprotected sqlite3_value.
**
** The terms "protected" and "unprotected" refer to whether or not
** a mutex is held. An internal mutex is held for a protected
@@ -3754,6 +3686,7 @@ 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}
+** METHOD: sqlite3_stmt
**
** ^(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
@@ -3787,6 +3720,9 @@ typedef struct sqlite3_context sqlite3_context;
** parameter [SQLITE_LIMIT_VARIABLE_NUMBER] (default value: 999).
**
** ^The third argument is the value to bind to the parameter.
+** ^If the third parameter to sqlite3_bind_text() or sqlite3_bind_text16()
+** or sqlite3_bind_blob() is a NULL pointer then the fourth parameter
+** is ignored and the end result is the same as sqlite3_bind_null().
**
** ^(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
@@ -3797,18 +3733,18 @@ typedef struct sqlite3_context sqlite3_context;
** 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
+** or sqlite3_bind_text16() or sqlite3_bind_text64() 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
+** ^The fifth argument to the BLOB and string binding interfaces
+** 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.
+** to dispose of the BLOB or string even if the call to bind API 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.
@@ -3816,6 +3752,14 @@ typedef struct sqlite3_context sqlite3_context;
** SQLite makes its own private copy of the data immediately, before
** the sqlite3_bind_*() routine returns.
**
+** ^The sixth argument to sqlite3_bind_text64() must be one of
+** [SQLITE_UTF8], [SQLITE_UTF16], [SQLITE_UTF16BE], or [SQLITE_UTF16LE]
+** to specify the encoding of the text in the third parameter. If
+** the sixth argument to sqlite3_bind_text64() is not one of the
+** allowed values shown above, or if the text encoding is different
+** from the encoding specified by the sixth parameter, then the behavior
+** is undefined.
+**
** ^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.
@@ -3836,24 +3780,33 @@ typedef struct sqlite3_context sqlite3_context;
**
** ^The sqlite3_bind_* routines return [SQLITE_OK] on success or an
** [error code] if anything goes wrong.
+** ^[SQLITE_TOOBIG] might be returned if the size of a string or BLOB
+** exceeds limits imposed by [sqlite3_limit]([SQLITE_LIMIT_LENGTH]) or
+** [SQLITE_MAX_LENGTH].
** ^[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);
+SQLITE_API int SQLITE_STDCALL sqlite3_bind_blob(sqlite3_stmt*, int, const void*, int n, void(*)(void*));
+SQLITE_API int SQLITE_STDCALL sqlite3_bind_blob64(sqlite3_stmt*, int, const void*, sqlite3_uint64,
+ void(*)(void*));
+SQLITE_API int SQLITE_STDCALL sqlite3_bind_double(sqlite3_stmt*, int, double);
+SQLITE_API int SQLITE_STDCALL sqlite3_bind_int(sqlite3_stmt*, int, int);
+SQLITE_API int SQLITE_STDCALL sqlite3_bind_int64(sqlite3_stmt*, int, sqlite3_int64);
+SQLITE_API int SQLITE_STDCALL sqlite3_bind_null(sqlite3_stmt*, int);
+SQLITE_API int SQLITE_STDCALL sqlite3_bind_text(sqlite3_stmt*,int,const char*,int,void(*)(void*));
+SQLITE_API int SQLITE_STDCALL sqlite3_bind_text16(sqlite3_stmt*, int, const void*, int, void(*)(void*));
+SQLITE_API int SQLITE_STDCALL sqlite3_bind_text64(sqlite3_stmt*, int, const char*, sqlite3_uint64,
+ void(*)(void*), unsigned char encoding);
+SQLITE_API int SQLITE_STDCALL sqlite3_bind_value(sqlite3_stmt*, int, const sqlite3_value*);
+SQLITE_API int SQLITE_STDCALL sqlite3_bind_zeroblob(sqlite3_stmt*, int, int n);
+SQLITE_API int SQLITE_STDCALL sqlite3_bind_zeroblob64(sqlite3_stmt*, int, sqlite3_uint64);
/*
** CAPI3REF: Number Of SQL Parameters
+** METHOD: sqlite3_stmt
**
** ^This routine can be used to find the number of [SQL parameters]
** in a [prepared statement]. SQL parameters are tokens of the
@@ -3870,10 +3823,11 @@ SQLITE_API int sqlite3_bind_zeroblob(sqlite3_stmt*, int, int n);
** [sqlite3_bind_parameter_name()], and
** [sqlite3_bind_parameter_index()].
*/
-SQLITE_API int sqlite3_bind_parameter_count(sqlite3_stmt*);
+SQLITE_API int SQLITE_STDCALL sqlite3_bind_parameter_count(sqlite3_stmt*);
/*
** CAPI3REF: Name Of A Host Parameter
+** METHOD: sqlite3_stmt
**
** ^The sqlite3_bind_parameter_name(P,N) interface returns
** the name of the N-th [SQL parameter] in the [prepared statement] P.
@@ -3897,10 +3851,11 @@ SQLITE_API int sqlite3_bind_parameter_count(sqlite3_stmt*);
** [sqlite3_bind_parameter_count()], and
** [sqlite3_bind_parameter_index()].
*/
-SQLITE_API const char *sqlite3_bind_parameter_name(sqlite3_stmt*, int);
+SQLITE_API const char *SQLITE_STDCALL sqlite3_bind_parameter_name(sqlite3_stmt*, int);
/*
** CAPI3REF: Index Of A Parameter With A Given Name
+** METHOD: sqlite3_stmt
**
** ^Return the index of an SQL parameter given its name. ^The
** index value returned is suitable for use as the second
@@ -3911,21 +3866,23 @@ SQLITE_API const char *sqlite3_bind_parameter_name(sqlite3_stmt*, int);
**
** See also: [sqlite3_bind_blob|sqlite3_bind()],
** [sqlite3_bind_parameter_count()], and
-** [sqlite3_bind_parameter_index()].
+** [sqlite3_bind_parameter_name()].
*/
-SQLITE_API int sqlite3_bind_parameter_index(sqlite3_stmt*, const char *zName);
+SQLITE_API int SQLITE_STDCALL sqlite3_bind_parameter_index(sqlite3_stmt*, const char *zName);
/*
** CAPI3REF: Reset All Bindings On A Prepared Statement
+** METHOD: sqlite3_stmt
**
** ^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*);
+SQLITE_API int SQLITE_STDCALL sqlite3_clear_bindings(sqlite3_stmt*);
/*
** CAPI3REF: Number Of Columns In A Result Set
+** METHOD: sqlite3_stmt
**
** ^Return the number of columns in the result set returned by the
** [prepared statement]. ^This routine returns 0 if pStmt is an SQL
@@ -3933,10 +3890,11 @@ SQLITE_API int sqlite3_clear_bindings(sqlite3_stmt*);
**
** See also: [sqlite3_data_count()]
*/
-SQLITE_API int sqlite3_column_count(sqlite3_stmt *pStmt);
+SQLITE_API int SQLITE_STDCALL sqlite3_column_count(sqlite3_stmt *pStmt);
/*
** CAPI3REF: Column Names In A Result Set
+** METHOD: sqlite3_stmt
**
** ^These routines return the name assigned to a particular column
** in the result set of a [SELECT] statement. ^The sqlite3_column_name()
@@ -3961,11 +3919,12 @@ SQLITE_API int sqlite3_column_count(sqlite3_stmt *pStmt);
** 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);
+SQLITE_API const char *SQLITE_STDCALL sqlite3_column_name(sqlite3_stmt*, int N);
+SQLITE_API const void *SQLITE_STDCALL sqlite3_column_name16(sqlite3_stmt*, int N);
/*
** CAPI3REF: Source Of Data In A Query Result
+** METHOD: sqlite3_stmt
**
** ^These routines provide a means to determine the database, table, and
** table column that is the origin of a particular result column in
@@ -4009,15 +3968,16 @@ SQLITE_API const void *sqlite3_column_name16(sqlite3_stmt*, int N);
** 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);
+SQLITE_API const char *SQLITE_STDCALL sqlite3_column_database_name(sqlite3_stmt*,int);
+SQLITE_API const void *SQLITE_STDCALL sqlite3_column_database_name16(sqlite3_stmt*,int);
+SQLITE_API const char *SQLITE_STDCALL sqlite3_column_table_name(sqlite3_stmt*,int);
+SQLITE_API const void *SQLITE_STDCALL sqlite3_column_table_name16(sqlite3_stmt*,int);
+SQLITE_API const char *SQLITE_STDCALL sqlite3_column_origin_name(sqlite3_stmt*,int);
+SQLITE_API const void *SQLITE_STDCALL sqlite3_column_origin_name16(sqlite3_stmt*,int);
/*
** CAPI3REF: Declared Datatype Of A Query Result
+** METHOD: sqlite3_stmt
**
** ^(The first parameter is a [prepared statement].
** If this statement is a [SELECT] statement and the Nth column of the
@@ -4045,11 +4005,12 @@ SQLITE_API const void *sqlite3_column_origin_name16(sqlite3_stmt*,int);
** 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);
+SQLITE_API const char *SQLITE_STDCALL sqlite3_column_decltype(sqlite3_stmt*,int);
+SQLITE_API const void *SQLITE_STDCALL sqlite3_column_decltype16(sqlite3_stmt*,int);
/*
** CAPI3REF: Evaluate An SQL Statement
+** METHOD: sqlite3_stmt
**
** After a [prepared statement] has been prepared using either
** [sqlite3_prepare_v2()] or [sqlite3_prepare16_v2()] or one of the legacy
@@ -4125,10 +4086,11 @@ SQLITE_API const void *sqlite3_column_decltype16(sqlite3_stmt*,int);
** 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*);
+SQLITE_API int SQLITE_STDCALL sqlite3_step(sqlite3_stmt*);
/*
** CAPI3REF: Number of columns in a result set
+** METHOD: sqlite3_stmt
**
** ^The sqlite3_data_count(P) interface returns the number of columns in the
** current row of the result set of [prepared statement] P.
@@ -4145,7 +4107,7 @@ SQLITE_API int sqlite3_step(sqlite3_stmt*);
**
** See also: [sqlite3_column_count()]
*/
-SQLITE_API int sqlite3_data_count(sqlite3_stmt *pStmt);
+SQLITE_API int SQLITE_STDCALL sqlite3_data_count(sqlite3_stmt *pStmt);
/*
** CAPI3REF: Fundamental Datatypes
@@ -4182,8 +4144,7 @@ SQLITE_API int sqlite3_data_count(sqlite3_stmt *pStmt);
/*
** CAPI3REF: Result Values From A Query
** KEYWORDS: {column access functions}
-**
-** These routines form the "result set" interface.
+** METHOD: sqlite3_stmt
**
** ^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
@@ -4244,13 +4205,14 @@ SQLITE_API int sqlite3_data_count(sqlite3_stmt *pStmt);
** 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()].
+** <b>Warning:</b> ^The object returned by [sqlite3_column_value()] is an
+** [unprotected sqlite3_value] object. In a multithreaded environment,
+** an unprotected sqlite3_value object may only be used safely 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.
+** or [sqlite3_value_bytes()], the behavior is not threadsafe.
**
** These routines attempt to convert the value where appropriate. ^For
** example, if the internal representation is FLOAT and a text result
@@ -4264,29 +4226,23 @@ SQLITE_API int sqlite3_data_count(sqlite3_stmt *pStmt);
**
** <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> NULL <td> TEXT <td> Result is a NULL pointer
+** <tr><td> NULL <td> BLOB <td> Result is a 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> INTEGER <td> [CAST] 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> FLOAT <td> BLOB <td> [CAST] to BLOB
+** <tr><td> TEXT <td> INTEGER <td> [CAST] to INTEGER
+** <tr><td> TEXT <td> FLOAT <td> [CAST] to REAL
** <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> INTEGER <td> [CAST] to INTEGER
+** <tr><td> BLOB <td> FLOAT <td> [CAST] to REAL
** <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.
@@ -4311,7 +4267,7 @@ SQLITE_API int sqlite3_data_count(sqlite3_stmt *pStmt);
** 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
+** The safest policy is to invoke these routines
** in one of the following ways:
**
** <ul>
@@ -4331,8 +4287,8 @@ SQLITE_API int sqlite3_data_count(sqlite3_stmt *pStmt);
** ^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
+** and BLOBs is freed automatically. Do <em>not</em> pass the pointers returned
+** from [sqlite3_column_blob()], [sqlite3_column_text()], etc. into
** [sqlite3_free()].
**
** ^(If a memory allocation error occurs during the evaluation of any
@@ -4341,19 +4297,20 @@ SQLITE_API int sqlite3_data_count(sqlite3_stmt *pStmt);
** 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);
+SQLITE_API const void *SQLITE_STDCALL sqlite3_column_blob(sqlite3_stmt*, int iCol);
+SQLITE_API int SQLITE_STDCALL sqlite3_column_bytes(sqlite3_stmt*, int iCol);
+SQLITE_API int SQLITE_STDCALL sqlite3_column_bytes16(sqlite3_stmt*, int iCol);
+SQLITE_API double SQLITE_STDCALL sqlite3_column_double(sqlite3_stmt*, int iCol);
+SQLITE_API int SQLITE_STDCALL sqlite3_column_int(sqlite3_stmt*, int iCol);
+SQLITE_API sqlite3_int64 SQLITE_STDCALL sqlite3_column_int64(sqlite3_stmt*, int iCol);
+SQLITE_API const unsigned char *SQLITE_STDCALL sqlite3_column_text(sqlite3_stmt*, int iCol);
+SQLITE_API const void *SQLITE_STDCALL sqlite3_column_text16(sqlite3_stmt*, int iCol);
+SQLITE_API int SQLITE_STDCALL sqlite3_column_type(sqlite3_stmt*, int iCol);
+SQLITE_API sqlite3_value *SQLITE_STDCALL sqlite3_column_value(sqlite3_stmt*, int iCol);
/*
** CAPI3REF: Destroy A Prepared Statement Object
+** DESTRUCTOR: sqlite3_stmt
**
** ^The sqlite3_finalize() function is called to delete a [prepared statement].
** ^If the most recent evaluation of the statement encountered no errors
@@ -4377,10 +4334,11 @@ SQLITE_API sqlite3_value *sqlite3_column_value(sqlite3_stmt*, int iCol);
** 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);
+SQLITE_API int SQLITE_STDCALL sqlite3_finalize(sqlite3_stmt *pStmt);
/*
** CAPI3REF: Reset A Prepared Statement Object
+** METHOD: sqlite3_stmt
**
** The sqlite3_reset() function is called to reset a [prepared statement]
** object back to its initial state, ready to be re-executed.
@@ -4403,13 +4361,14 @@ SQLITE_API int sqlite3_finalize(sqlite3_stmt *pStmt);
** ^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);
+SQLITE_API int SQLITE_STDCALL 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}
+** METHOD: sqlite3
**
** ^These functions (collectively known as "function creation routines")
** are used to add SQL functions or aggregates or to redefine the behavior
@@ -4441,15 +4400,24 @@ SQLITE_API int sqlite3_reset(sqlite3_stmt *pStmt);
**
** ^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.
+** its parameters. The application should set this parameter to
+** [SQLITE_UTF16LE] if the function implementation invokes
+** [sqlite3_value_text16le()] on an input, or [SQLITE_UTF16BE] if the
+** implementation invokes [sqlite3_value_text16be()] on an input, or
+** [SQLITE_UTF16] if [sqlite3_value_text16()] is used, or [SQLITE_UTF8]
+** otherwise. ^The same SQL function may be registered multiple times using
+** different preferred text encodings, with different implementations for
+** each encoding.
** ^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 fourth parameter may optionally be ORed with [SQLITE_DETERMINISTIC]
+** to signal that the function will always return the same result given
+** the same inputs within a single SQL statement. Most SQL functions are
+** deterministic. The built-in [random()] SQL function is an example of a
+** function that is not deterministic. The SQLite query planner is able to
+** perform additional optimizations on deterministic functions, so use
+** of the [SQLITE_DETERMINISTIC] flag is recommended where possible.
**
** ^(The fifth parameter is an arbitrary pointer. The implementation of the
** function can gain access to this pointer using [sqlite3_user_data()].)^
@@ -4493,7 +4461,7 @@ SQLITE_API int sqlite3_reset(sqlite3_stmt *pStmt);
** close the database connection nor finalize or reset the prepared
** statement in which the function is running.
*/
-SQLITE_API int sqlite3_create_function(
+SQLITE_API int SQLITE_STDCALL sqlite3_create_function(
sqlite3 *db,
const char *zFunctionName,
int nArg,
@@ -4503,7 +4471,7 @@ SQLITE_API int sqlite3_create_function(
void (*xStep)(sqlite3_context*,int,sqlite3_value**),
void (*xFinal)(sqlite3_context*)
);
-SQLITE_API int sqlite3_create_function16(
+SQLITE_API int SQLITE_STDCALL sqlite3_create_function16(
sqlite3 *db,
const void *zFunctionName,
int nArg,
@@ -4513,7 +4481,7 @@ SQLITE_API int sqlite3_create_function16(
void (*xStep)(sqlite3_context*,int,sqlite3_value**),
void (*xFinal)(sqlite3_context*)
);
-SQLITE_API int sqlite3_create_function_v2(
+SQLITE_API int SQLITE_STDCALL sqlite3_create_function_v2(
sqlite3 *db,
const char *zFunctionName,
int nArg,
@@ -4531,38 +4499,50 @@ SQLITE_API int sqlite3_create_function_v2(
** 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_UTF8 1 /* IMP: R-37514-35566 */
+#define SQLITE_UTF16LE 2 /* IMP: R-03371-37637 */
+#define SQLITE_UTF16BE 3 /* IMP: R-51971-34154 */
#define SQLITE_UTF16 4 /* Use native byte order */
-#define SQLITE_ANY 5 /* sqlite3_create_function only */
+#define SQLITE_ANY 5 /* Deprecated */
#define SQLITE_UTF16_ALIGNED 8 /* sqlite3_create_collation only */
/*
+** CAPI3REF: Function Flags
+**
+** These constants may be ORed together with the
+** [SQLITE_UTF8 | preferred text encoding] as the fourth argument
+** to [sqlite3_create_function()], [sqlite3_create_function16()], or
+** [sqlite3_create_function_v2()].
+*/
+#define SQLITE_DETERMINISTIC 0x800
+
+/*
** 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.
+** the use of these functions. To encourage programmers to avoid
+** these functions, we will not explain 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);
+SQLITE_API SQLITE_DEPRECATED int SQLITE_STDCALL sqlite3_aggregate_count(sqlite3_context*);
+SQLITE_API SQLITE_DEPRECATED int SQLITE_STDCALL sqlite3_expired(sqlite3_stmt*);
+SQLITE_API SQLITE_DEPRECATED int SQLITE_STDCALL sqlite3_transfer_bindings(sqlite3_stmt*, sqlite3_stmt*);
+SQLITE_API SQLITE_DEPRECATED int SQLITE_STDCALL sqlite3_global_recover(void);
+SQLITE_API SQLITE_DEPRECATED void SQLITE_STDCALL sqlite3_thread_cleanup(void);
+SQLITE_API SQLITE_DEPRECATED int SQLITE_STDCALL sqlite3_memory_alarm(void(*)(void*,sqlite3_int64,int),
+ void*,sqlite3_int64);
#endif
/*
-** CAPI3REF: Obtaining SQL Function Parameter Values
+** CAPI3REF: Obtaining SQL Values
+** METHOD: sqlite3_value
**
** 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 function or aggregate.
**
** The xFunc (for scalar functions) or xStep (for aggregates) parameters
** to [sqlite3_create_function()] and [sqlite3_create_function16()]
@@ -4577,7 +4557,7 @@ SQLITE_API SQLITE_DEPRECATED int sqlite3_memory_alarm(void(*)(void*,sqlite3_int6
** 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
+** 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
@@ -4602,21 +4582,55 @@ SQLITE_API SQLITE_DEPRECATED int sqlite3_memory_alarm(void(*)(void*,sqlite3_int6
** 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*);
+SQLITE_API const void *SQLITE_STDCALL sqlite3_value_blob(sqlite3_value*);
+SQLITE_API int SQLITE_STDCALL sqlite3_value_bytes(sqlite3_value*);
+SQLITE_API int SQLITE_STDCALL sqlite3_value_bytes16(sqlite3_value*);
+SQLITE_API double SQLITE_STDCALL sqlite3_value_double(sqlite3_value*);
+SQLITE_API int SQLITE_STDCALL sqlite3_value_int(sqlite3_value*);
+SQLITE_API sqlite3_int64 SQLITE_STDCALL sqlite3_value_int64(sqlite3_value*);
+SQLITE_API const unsigned char *SQLITE_STDCALL sqlite3_value_text(sqlite3_value*);
+SQLITE_API const void *SQLITE_STDCALL sqlite3_value_text16(sqlite3_value*);
+SQLITE_API const void *SQLITE_STDCALL sqlite3_value_text16le(sqlite3_value*);
+SQLITE_API const void *SQLITE_STDCALL sqlite3_value_text16be(sqlite3_value*);
+SQLITE_API int SQLITE_STDCALL sqlite3_value_type(sqlite3_value*);
+SQLITE_API int SQLITE_STDCALL sqlite3_value_numeric_type(sqlite3_value*);
+
+/*
+** CAPI3REF: Finding The Subtype Of SQL Values
+** METHOD: sqlite3_value
+**
+** The sqlite3_value_subtype(V) function returns the subtype for
+** an [application-defined SQL function] argument V. The subtype
+** information can be used to pass a limited amount of context from
+** one SQL function to another. Use the [sqlite3_result_subtype()]
+** routine to set the subtype for the return value of an SQL function.
+**
+** SQLite makes no use of subtype itself. It merely passes the subtype
+** from the result of one [application-defined SQL function] into the
+** input of another.
+*/
+SQLITE_API unsigned int SQLITE_STDCALL sqlite3_value_subtype(sqlite3_value*);
+
+/*
+** CAPI3REF: Copy And Free SQL Values
+** METHOD: sqlite3_value
+**
+** ^The sqlite3_value_dup(V) interface makes a copy of the [sqlite3_value]
+** object D and returns a pointer to that copy. ^The [sqlite3_value] returned
+** is a [protected sqlite3_value] object even if the input is not.
+** ^The sqlite3_value_dup(V) interface returns NULL if V is NULL or if a
+** memory allocation fails.
+**
+** ^The sqlite3_value_free(V) interface frees an [sqlite3_value] object
+** previously obtained from [sqlite3_value_dup()]. ^If V is a NULL pointer
+** then sqlite3_value_free(V) is a harmless no-op.
+*/
+SQLITE_API sqlite3_value *SQLITE_STDCALL sqlite3_value_dup(const sqlite3_value*);
+SQLITE_API void SQLITE_STDCALL sqlite3_value_free(sqlite3_value*);
/*
** CAPI3REF: Obtain Aggregate Function Context
+** METHOD: sqlite3_context
**
** Implementations of aggregate SQL functions use this
** routine to allocate memory for storing their state.
@@ -4634,14 +4648,17 @@ SQLITE_API int sqlite3_value_numeric_type(sqlite3_value*);
** 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 sqlite3_aggregate_context(C,N) routine returns a NULL pointer
+** when first called 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.)^
+** allocation.)^ Within the xFinal callback, it is customary to set
+** N=0 in calls to sqlite3_aggregate_context(C,N) so that no
+** pointless memory allocations occur.
**
** ^SQLite automatically frees the memory allocated by
** sqlite3_aggregate_context() when the aggregate query concludes.
@@ -4654,10 +4671,11 @@ SQLITE_API int sqlite3_value_numeric_type(sqlite3_value*);
** 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);
+SQLITE_API void *SQLITE_STDCALL sqlite3_aggregate_context(sqlite3_context*, int nBytes);
/*
** CAPI3REF: User Data For Functions
+** METHOD: sqlite3_context
**
** ^The sqlite3_user_data() interface returns a copy of
** the pointer that was the pUserData parameter (the 5th parameter)
@@ -4668,10 +4686,11 @@ SQLITE_API void *sqlite3_aggregate_context(sqlite3_context*, int nBytes);
** 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*);
+SQLITE_API void *SQLITE_STDCALL sqlite3_user_data(sqlite3_context*);
/*
** CAPI3REF: Database Connection For Functions
+** METHOD: sqlite3_context
**
** ^The sqlite3_context_db_handle() interface returns a copy of
** the pointer to the [database connection] (the 1st parameter)
@@ -4679,52 +4698,61 @@ SQLITE_API void *sqlite3_user_data(sqlite3_context*);
** and [sqlite3_create_function16()] routines that originally
** registered the application defined function.
*/
-SQLITE_API sqlite3 *sqlite3_context_db_handle(sqlite3_context*);
+SQLITE_API sqlite3 *SQLITE_STDCALL sqlite3_context_db_handle(sqlite3_context*);
/*
** CAPI3REF: Function Auxiliary Data
+** METHOD: sqlite3_context
**
-** The following two functions may be used by scalar SQL functions to
+** These functions may be used by (non-aggregate) 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.
+** some circumstances the associated metadata may be preserved. An example
+** of where this might be useful is in a regular-expression matching
+** function. The compiled version of the regular expression can be stored as
+** metadata associated with the pattern string.
+** Then as long as the pattern string remains the same,
+** the compiled regular expression can be reused on multiple
+** invocations of the same function.
**
** ^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.
+** value to the application-defined function. ^If there is no metadata
+** associated with the function argument, this sqlite3_get_auxdata() interface
+** returns a NULL pointer.
+**
+** ^The sqlite3_set_auxdata(C,N,P,X) interface saves P as metadata for the N-th
+** argument of the application-defined function. ^Subsequent
+** calls to sqlite3_get_auxdata(C,N) return P from the most recent
+** sqlite3_set_auxdata(C,N,P,X) call if the metadata is still valid or
+** NULL if the metadata has been discarded.
+** ^After each call to sqlite3_set_auxdata(C,N,P,X) where X is not NULL,
+** SQLite will invoke the destructor function X with parameter P exactly
+** once, when the metadata is discarded.
+** SQLite is free to discard the metadata at any time, including: <ul>
+** <li> when the corresponding function parameter changes, or
+** <li> when [sqlite3_reset()] or [sqlite3_finalize()] is called for the
+** SQL statement, or
+** <li> when sqlite3_set_auxdata() is invoked again on the same parameter, or
+** <li> during the original sqlite3_set_auxdata() call when a memory
+** allocation error occurs. </ul>)^
+**
+** Note the last bullet in particular. The destructor X in
+** sqlite3_set_auxdata(C,N,P,X) might be called immediately, before the
+** sqlite3_set_auxdata() interface even returns. Hence sqlite3_set_auxdata()
+** should be called near the end of the function implementation and the
+** function implementation should not make any use of P after
+** sqlite3_set_auxdata() has been called.
**
** ^(In practice, metadata is preserved between function calls for
-** expressions that are constant at compile time. This includes literal
-** values and [parameters].)^
+** function parameters that are compile-time constants, including literal
+** values and [parameters] and expressions composed from the same.)^
**
** 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*));
+SQLITE_API void *SQLITE_STDCALL sqlite3_get_auxdata(sqlite3_context*, int N);
+SQLITE_API void SQLITE_STDCALL sqlite3_set_auxdata(sqlite3_context*, int N, void*, void (*)(void*));
/*
@@ -4739,7 +4767,7 @@ SQLITE_API void sqlite3_set_auxdata(sqlite3_context*, int N, void*, void (*)(voi
** the content before returning.
**
** The typedef is necessary to work around problems in certain
-** C++ compilers. See ticket #2191.
+** C++ compilers.
*/
typedef void (*sqlite3_destructor_type)(void*);
#define SQLITE_STATIC ((sqlite3_destructor_type)0)
@@ -4747,6 +4775,7 @@ typedef void (*sqlite3_destructor_type)(void*);
/*
** CAPI3REF: Setting The Result Of An SQL Function
+** METHOD: sqlite3_context
**
** These routines are used by the xFunc or xFinal callbacks that
** implement SQL functions and aggregates. See
@@ -4762,9 +4791,9 @@ typedef void (*sqlite3_destructor_type)(void*);
** 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_zeroblob(C,N) and sqlite3_result_zeroblob64(C,N)
+** interfaces set the result of the application-defined function to be
+** a BLOB containing all zero bytes and N bytes in size.
**
** ^The sqlite3_result_double() interface sets the result from
** an application-defined function to be a floating point value specified
@@ -4813,6 +4842,10 @@ typedef void (*sqlite3_destructor_type)(void*);
** 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.
+** ^The sqlite3_result_text64() interface sets the return value of an
+** application-defined function to be a text string in an encoding
+** specified by the fifth (and last) parameter, which must be one
+** of [SQLITE_UTF8], [SQLITE_UTF16], [SQLITE_UTF16BE], or [SQLITE_UTF16LE].
** ^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
@@ -4842,7 +4875,7 @@ typedef void (*sqlite3_destructor_type)(void*);
** from [sqlite3_malloc()] before it returns.
**
** ^The sqlite3_result_value() interface sets the result of
-** the application-defined function to be a copy the
+** the application-defined function to be a copy of 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
@@ -4855,25 +4888,46 @@ typedef void (*sqlite3_destructor_type)(void*);
** 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);
+SQLITE_API void SQLITE_STDCALL sqlite3_result_blob(sqlite3_context*, const void*, int, void(*)(void*));
+SQLITE_API void SQLITE_STDCALL sqlite3_result_blob64(sqlite3_context*,const void*,
+ sqlite3_uint64,void(*)(void*));
+SQLITE_API void SQLITE_STDCALL sqlite3_result_double(sqlite3_context*, double);
+SQLITE_API void SQLITE_STDCALL sqlite3_result_error(sqlite3_context*, const char*, int);
+SQLITE_API void SQLITE_STDCALL sqlite3_result_error16(sqlite3_context*, const void*, int);
+SQLITE_API void SQLITE_STDCALL sqlite3_result_error_toobig(sqlite3_context*);
+SQLITE_API void SQLITE_STDCALL sqlite3_result_error_nomem(sqlite3_context*);
+SQLITE_API void SQLITE_STDCALL sqlite3_result_error_code(sqlite3_context*, int);
+SQLITE_API void SQLITE_STDCALL sqlite3_result_int(sqlite3_context*, int);
+SQLITE_API void SQLITE_STDCALL sqlite3_result_int64(sqlite3_context*, sqlite3_int64);
+SQLITE_API void SQLITE_STDCALL sqlite3_result_null(sqlite3_context*);
+SQLITE_API void SQLITE_STDCALL sqlite3_result_text(sqlite3_context*, const char*, int, void(*)(void*));
+SQLITE_API void SQLITE_STDCALL sqlite3_result_text64(sqlite3_context*, const char*,sqlite3_uint64,
+ void(*)(void*), unsigned char encoding);
+SQLITE_API void SQLITE_STDCALL sqlite3_result_text16(sqlite3_context*, const void*, int, void(*)(void*));
+SQLITE_API void SQLITE_STDCALL sqlite3_result_text16le(sqlite3_context*, const void*, int,void(*)(void*));
+SQLITE_API void SQLITE_STDCALL sqlite3_result_text16be(sqlite3_context*, const void*, int,void(*)(void*));
+SQLITE_API void SQLITE_STDCALL sqlite3_result_value(sqlite3_context*, sqlite3_value*);
+SQLITE_API void SQLITE_STDCALL sqlite3_result_zeroblob(sqlite3_context*, int n);
+SQLITE_API int SQLITE_STDCALL sqlite3_result_zeroblob64(sqlite3_context*, sqlite3_uint64 n);
+
+
+/*
+** CAPI3REF: Setting The Subtype Of An SQL Function
+** METHOD: sqlite3_context
+**
+** The sqlite3_result_subtype(C,T) function causes the subtype of
+** the result from the [application-defined SQL function] with
+** [sqlite3_context] C to be the value T. Only the lower 8 bits
+** of the subtype T are preserved in current versions of SQLite;
+** higher order bits are discarded.
+** The number of subtype bytes preserved by SQLite might increase
+** in future releases of SQLite.
+*/
+SQLITE_API void SQLITE_STDCALL sqlite3_result_subtype(sqlite3_context*,unsigned int);
/*
** CAPI3REF: Define New Collating Sequences
+** METHOD: sqlite3
**
** ^These functions add, remove, or modify a [collation] associated
** with the [database connection] specified as the first argument.
@@ -4951,14 +5005,14 @@ SQLITE_API void sqlite3_result_zeroblob(sqlite3_context*, int n);
**
** See also: [sqlite3_collation_needed()] and [sqlite3_collation_needed16()].
*/
-SQLITE_API int sqlite3_create_collation(
+SQLITE_API int SQLITE_STDCALL 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(
+SQLITE_API int SQLITE_STDCALL sqlite3_create_collation_v2(
sqlite3*,
const char *zName,
int eTextRep,
@@ -4966,7 +5020,7 @@ SQLITE_API int sqlite3_create_collation_v2(
int(*xCompare)(void*,int,const void*,int,const void*),
void(*xDestroy)(void*)
);
-SQLITE_API int sqlite3_create_collation16(
+SQLITE_API int SQLITE_STDCALL sqlite3_create_collation16(
sqlite3*,
const void *zName,
int eTextRep,
@@ -4976,6 +5030,7 @@ SQLITE_API int sqlite3_create_collation16(
/*
** CAPI3REF: Collation Needed Callbacks
+** METHOD: sqlite3
**
** ^To avoid having to register all collation sequences before a database
** can be used, a single callback function may be registered with the
@@ -5000,12 +5055,12 @@ SQLITE_API int sqlite3_create_collation16(
** [sqlite3_create_collation()], [sqlite3_create_collation16()], or
** [sqlite3_create_collation_v2()].
*/
-SQLITE_API int sqlite3_collation_needed(
+SQLITE_API int SQLITE_STDCALL sqlite3_collation_needed(
sqlite3*,
void*,
void(*)(void*,sqlite3*,int eTextRep,const char*)
);
-SQLITE_API int sqlite3_collation_needed16(
+SQLITE_API int SQLITE_STDCALL sqlite3_collation_needed16(
sqlite3*,
void*,
void(*)(void*,sqlite3*,int eTextRep,const void*)
@@ -5019,10 +5074,15 @@ SQLITE_API int sqlite3_collation_needed16(
** The code to implement this API is not available in the public release
** of SQLite.
*/
-SQLITE_API int sqlite3_key(
+SQLITE_API int SQLITE_STDCALL sqlite3_key(
sqlite3 *db, /* Database to be rekeyed */
const void *pKey, int nKey /* The key */
);
+SQLITE_API int SQLITE_STDCALL sqlite3_key_v2(
+ sqlite3 *db, /* Database to be rekeyed */
+ const char *zDbName, /* Name of the database */
+ const void *pKey, int nKey /* The key */
+);
/*
** Change the key on an open database. If the current database is not
@@ -5032,8 +5092,13 @@ SQLITE_API int sqlite3_key(
** The code to implement this API is not available in the public release
** of SQLite.
*/
-SQLITE_API int sqlite3_rekey(
+SQLITE_API int SQLITE_STDCALL sqlite3_rekey(
+ sqlite3 *db, /* Database to be rekeyed */
+ const void *pKey, int nKey /* The new key */
+);
+SQLITE_API int SQLITE_STDCALL sqlite3_rekey_v2(
sqlite3 *db, /* Database to be rekeyed */
+ const char *zDbName, /* Name of the database */
const void *pKey, int nKey /* The new key */
);
@@ -5041,7 +5106,7 @@ SQLITE_API int sqlite3_rekey(
** Specify the activation key for a SEE database. Unless
** activated, none of the SEE routines will work.
*/
-SQLITE_API void sqlite3_activate_see(
+SQLITE_API void SQLITE_STDCALL sqlite3_activate_see(
const char *zPassPhrase /* Activation phrase */
);
#endif
@@ -5051,7 +5116,7 @@ SQLITE_API void sqlite3_activate_see(
** Specify the activation key for a CEROD database. Unless
** activated, none of the CEROD routines will work.
*/
-SQLITE_API void sqlite3_activate_cerod(
+SQLITE_API void SQLITE_STDCALL sqlite3_activate_cerod(
const char *zPassPhrase /* Activation phrase */
);
#endif
@@ -5073,7 +5138,7 @@ SQLITE_API void sqlite3_activate_cerod(
** all, then the behavior of sqlite3_sleep() may deviate from the description
** in the previous paragraphs.
*/
-SQLITE_API int sqlite3_sleep(int);
+SQLITE_API int SQLITE_STDCALL sqlite3_sleep(int);
/*
** CAPI3REF: Name Of The Folder Holding Temporary Files
@@ -5085,6 +5150,13 @@ SQLITE_API int sqlite3_sleep(int);
** is a NULL pointer, then SQLite performs a search for an appropriate
** temporary file directory.
**
+** Applications are strongly discouraged from using this global variable.
+** It is required to set a temporary folder on Windows Runtime (WinRT).
+** But for all other platforms, it is highly recommended that applications
+** neither read nor write this variable. This global variable is a relic
+** that exists for backwards compatibility of legacy applications and should
+** be avoided in new projects.
+**
** 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
@@ -5103,6 +5175,11 @@ SQLITE_API int sqlite3_sleep(int);
** 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.
+** Except when requested by the [temp_store_directory pragma], SQLite
+** does not free the memory that sqlite3_temp_directory points to. If
+** the application wants that memory to be freed, it must do
+** so itself, taking care to only do so after all [database connection]
+** objects have been destroyed.
**
** <b>Note to Windows Runtime users:</b> The temporary directory must be set
** prior to calling [sqlite3_open] or [sqlite3_open_v2]. Otherwise, various
@@ -5161,6 +5238,7 @@ SQLITE_API char *sqlite3_data_directory;
/*
** CAPI3REF: Test For Auto-Commit Mode
** KEYWORDS: {autocommit mode}
+** METHOD: sqlite3
**
** ^The sqlite3_get_autocommit() interface returns non-zero or
** zero if the given database connection is or is not in autocommit mode,
@@ -5179,10 +5257,11 @@ SQLITE_API char *sqlite3_data_directory;
** connection while this routine is running, then the return value
** is undefined.
*/
-SQLITE_API int sqlite3_get_autocommit(sqlite3*);
+SQLITE_API int SQLITE_STDCALL sqlite3_get_autocommit(sqlite3*);
/*
** CAPI3REF: Find The Database Handle Of A Prepared Statement
+** METHOD: sqlite3_stmt
**
** ^The sqlite3_db_handle interface returns the [database connection] handle
** to which a [prepared statement] belongs. ^The [database connection]
@@ -5191,10 +5270,11 @@ SQLITE_API int sqlite3_get_autocommit(sqlite3*);
** 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*);
+SQLITE_API sqlite3 *SQLITE_STDCALL sqlite3_db_handle(sqlite3_stmt*);
/*
** CAPI3REF: Return The Filename For A Database Connection
+** METHOD: sqlite3
**
** ^The sqlite3_db_filename(D,N) interface returns a pointer to a filename
** associated with database N of connection D. ^The main database file
@@ -5207,19 +5287,21 @@ SQLITE_API sqlite3 *sqlite3_db_handle(sqlite3_stmt*);
** 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);
+SQLITE_API const char *SQLITE_STDCALL sqlite3_db_filename(sqlite3 *db, const char *zDbName);
/*
** CAPI3REF: Determine if a database is read-only
+** METHOD: sqlite3
**
** ^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);
+SQLITE_API int SQLITE_STDCALL sqlite3_db_readonly(sqlite3 *db, const char *zDbName);
/*
** CAPI3REF: Find the next prepared statement
+** METHOD: sqlite3
**
** ^This interface returns a pointer to the next [prepared statement] after
** pStmt associated with the [database connection] pDb. ^If pStmt is NULL
@@ -5231,10 +5313,11 @@ SQLITE_API int sqlite3_db_readonly(sqlite3 *db, const char *zDbName);
** [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);
+SQLITE_API sqlite3_stmt *SQLITE_STDCALL sqlite3_next_stmt(sqlite3 *pDb, sqlite3_stmt *pStmt);
/*
** CAPI3REF: Commit And Rollback Notification Callbacks
+** METHOD: sqlite3
**
** ^The sqlite3_commit_hook() interface registers a callback
** function to be invoked whenever a transaction is [COMMIT | committed].
@@ -5279,20 +5362,22 @@ SQLITE_API sqlite3_stmt *sqlite3_next_stmt(sqlite3 *pDb, sqlite3_stmt *pStmt);
**
** 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*);
+SQLITE_API void *SQLITE_STDCALL sqlite3_commit_hook(sqlite3*, int(*)(void*), void*);
+SQLITE_API void *SQLITE_STDCALL sqlite3_rollback_hook(sqlite3*, void(*)(void *), void*);
/*
** CAPI3REF: Data Change Notification Callbacks
+** METHOD: sqlite3
**
** ^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.
+** to be invoked whenever a row is updated, inserted or deleted in
+** a rowid table.
** ^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.
+** row is updated, inserted or deleted in a rowid table.
** ^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],
@@ -5305,6 +5390,7 @@ SQLITE_API void *sqlite3_rollback_hook(sqlite3*, void(*)(void *), void*);
**
** ^(The update hook is not invoked when internal system tables are
** modified (i.e. sqlite_master and sqlite_sequence).)^
+** ^The update hook is not invoked when [WITHOUT ROWID] tables are modified.
**
** ^In the current implementation, the update hook
** is not invoked when duplication rows are deleted because of an
@@ -5328,7 +5414,7 @@ SQLITE_API void *sqlite3_rollback_hook(sqlite3*, void(*)(void *), void*);
** See also the [sqlite3_commit_hook()] and [sqlite3_rollback_hook()]
** interfaces.
*/
-SQLITE_API void *sqlite3_update_hook(
+SQLITE_API void *SQLITE_STDCALL sqlite3_update_hook(
sqlite3*,
void(*)(void *,int ,char const *,char const *,sqlite3_int64),
void*
@@ -5358,12 +5444,17 @@ SQLITE_API void *sqlite3_update_hook(
** future releases of SQLite. Applications that care about shared
** cache setting should set it explicitly.
**
+** Note: This method is disabled on MacOS X 10.7 and iOS version 5.0
+** and will always return SQLITE_MISUSE. On those systems,
+** shared cache mode should be enabled per-database connection via
+** [sqlite3_open_v2()] with [SQLITE_OPEN_SHAREDCACHE].
+**
** 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);
+SQLITE_API int SQLITE_STDCALL sqlite3_enable_shared_cache(int);
/*
** CAPI3REF: Attempt To Free Heap Memory
@@ -5379,20 +5470,21 @@ SQLITE_API int sqlite3_enable_shared_cache(int);
**
** See also: [sqlite3_db_release_memory()]
*/
-SQLITE_API int sqlite3_release_memory(int);
+SQLITE_API int SQLITE_STDCALL sqlite3_release_memory(int);
/*
** CAPI3REF: Free Memory Used By A Database Connection
+** METHOD: sqlite3
**
** ^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
+** [sqlite3_release_memory()] interface, this interface is in effect even
+** when the [SQLITE_ENABLE_MEMORY_MANAGEMENT] compile-time option is
** omitted.
**
** See also: [sqlite3_release_memory()]
*/
-SQLITE_API int sqlite3_db_release_memory(sqlite3*);
+SQLITE_API int SQLITE_STDCALL sqlite3_db_release_memory(sqlite3*);
/*
** CAPI3REF: Impose A Limit On Heap Size
@@ -5444,7 +5536,7 @@ SQLITE_API int sqlite3_db_release_memory(sqlite3*);
** 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);
+SQLITE_API sqlite3_int64 SQLITE_STDCALL sqlite3_soft_heap_limit64(sqlite3_int64 N);
/*
** CAPI3REF: Deprecated Soft Heap Limit Interface
@@ -5455,26 +5547,34 @@ SQLITE_API sqlite3_int64 sqlite3_soft_heap_limit64(sqlite3_int64 N);
** 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);
+SQLITE_API SQLITE_DEPRECATED void SQLITE_STDCALL 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.
+** METHOD: sqlite3
+**
+** ^(The sqlite3_table_column_metadata(X,D,T,C,....) routine returns
+** information about column C of table T in database D
+** on [database connection] X.)^ ^The sqlite3_table_column_metadata()
+** interface returns SQLITE_OK and fills in the non-NULL pointers in
+** the final five arguments with appropriate values if the specified
+** column exists. ^The sqlite3_table_column_metadata() interface returns
+** SQLITE_ERROR and if the specified column does not exist.
+** ^If the column-name parameter to sqlite3_table_column_metadata() is a
+** NULL pointer, then this routine simply checks for the existance of the
+** table and returns SQLITE_OK if the table exists and SQLITE_ERROR if it
+** does not.
**
** ^The column is identified by the second, third and fourth parameters to
-** this function. ^The second parameter is either the name of the database
+** 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
+** 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.
+** name of the desired column, respectively.
**
** ^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
@@ -5493,16 +5593,17 @@ SQLITE_API SQLITE_DEPRECATED void sqlite3_soft_heap_limit(int N);
** </blockquote>)^
**
** ^The memory pointed to by the character pointers returned for the
-** declaration type and collation sequence is valid only until the next
+** declaration type and collation sequence is valid 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
+** ^If the specified column is "rowid", "oid" or "_rowid_" and the table
+** is not a [WITHOUT ROWID] table 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:
+** [INTEGER PRIMARY KEY] column, then the outputs
+** for the [rowid] are set as follows:
**
** <pre>
** data type: "INTEGER"
@@ -5512,15 +5613,11 @@ SQLITE_API SQLITE_DEPRECATED void sqlite3_soft_heap_limit(int N);
** 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.
+** ^This function causes all database schemas to be read from disk and
+** parsed, if that has not already been done, and returns an error if
+** any errors are encountered while loading the schema.
*/
-SQLITE_API int sqlite3_table_column_metadata(
+SQLITE_API int SQLITE_STDCALL sqlite3_table_column_metadata(
sqlite3 *db, /* Connection handle */
const char *zDbName, /* Database name or NULL */
const char *zTableName, /* Table name */
@@ -5534,15 +5631,25 @@ SQLITE_API int sqlite3_table_column_metadata(
/*
** CAPI3REF: Load An Extension
+** METHOD: sqlite3
**
** ^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.
+** [SQLite extension] library contained in the file zFile. If
+** the file cannot be loaded directly, attempts are made to load
+** with various operating-system specific extensions added.
+** So for example, if "samplelib" cannot be loaded, then names like
+** "samplelib.so" or "samplelib.dylib" or "samplelib.dll" might
+** be tried also.
**
** ^The entry point is zProc.
-** ^zProc may be 0, in which case the name of the entry point
-** defaults to "sqlite3_extension_init".
+** ^(zProc may be 0, in which case SQLite will try to come up with an
+** entry point name on its own. It first tries "sqlite3_extension_init".
+** If that does not work, it constructs a name "sqlite3_X_init" where the
+** X is consists of the lower-case equivalent of all ASCII alphabetic
+** characters in the filename from the last "/" to the first following
+** "." and omitting any initial "lib".)^
** ^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
@@ -5557,7 +5664,7 @@ SQLITE_API int sqlite3_table_column_metadata(
**
** See also the [load_extension() SQL function].
*/
-SQLITE_API int sqlite3_load_extension(
+SQLITE_API int SQLITE_STDCALL 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 */
@@ -5566,25 +5673,26 @@ SQLITE_API int sqlite3_load_extension(
/*
** CAPI3REF: Enable Or Disable Extension Loading
+** METHOD: sqlite3
**
** ^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
+** 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.
+** ^Extension loading is off by default.
** ^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);
+SQLITE_API int SQLITE_STDCALL 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
+** 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
@@ -5612,9 +5720,22 @@ SQLITE_API int sqlite3_enable_load_extension(sqlite3 *db, int onoff);
** 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()].
+** See also: [sqlite3_reset_auto_extension()]
+** and [sqlite3_cancel_auto_extension()]
+*/
+SQLITE_API int SQLITE_STDCALL sqlite3_auto_extension(void (*xEntryPoint)(void));
+
+/*
+** CAPI3REF: Cancel Automatic Extension Loading
+**
+** ^The [sqlite3_cancel_auto_extension(X)] interface unregisters the
+** initialization routine X that was registered using a prior call to
+** [sqlite3_auto_extension(X)]. ^The [sqlite3_cancel_auto_extension(X)]
+** routine returns 1 if initialization routine X was successfully
+** unregistered and it returns 0 if X was not on the list of initialization
+** routines.
*/
-SQLITE_API int sqlite3_auto_extension(void (*xEntryPoint)(void));
+SQLITE_API int SQLITE_STDCALL sqlite3_cancel_auto_extension(void (*xEntryPoint)(void));
/*
** CAPI3REF: Reset Automatic Extension Loading
@@ -5622,7 +5743,7 @@ SQLITE_API int sqlite3_auto_extension(void (*xEntryPoint)(void));
** ^This interface disables all automatic extensions previously
** registered using [sqlite3_auto_extension()].
*/
-SQLITE_API void sqlite3_reset_auto_extension(void);
+SQLITE_API void SQLITE_STDCALL sqlite3_reset_auto_extension(void);
/*
** The interface to the virtual-table mechanism is currently considered
@@ -5724,6 +5845,17 @@ struct sqlite3_module {
** ^Information about the ORDER BY clause is stored in aOrderBy[].
** ^Each term of aOrderBy records a column of the ORDER BY clause.
**
+** The colUsed field indicates which columns of the virtual table may be
+** required by the current scan. Virtual table columns are numbered from
+** zero in the order in which they appear within the CREATE TABLE statement
+** passed to sqlite3_declare_vtab(). For the first 63 columns (columns 0-62),
+** the corresponding bit is set within the colUsed mask if the column may be
+** required by SQLite. If the table has at least 64 columns and any column
+** to the right of the first 63 is required, then bit 63 of colUsed is also
+** set. In other words, column iCol may be required if the expression
+** (colUsed & ((sqlite3_uint64)1 << (iCol>=63 ? 63 : iCol))) evaluates to
+** non-zero.
+**
** 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
@@ -5740,10 +5872,40 @@ struct sqlite3_module {
** 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).
+** ^The estimatedCost value is an estimate of the cost of a particular
+** strategy. A cost of N indicates that the cost of the strategy is similar
+** to a linear scan of an SQLite table with N rows. A cost of log(N)
+** indicates that the expense of the operation is similar to that of a
+** binary search on a unique indexed field of an SQLite table with N rows.
+**
+** ^The estimatedRows value is an estimate of the number of rows that
+** will be returned by the strategy.
+**
+** The xBestIndex method may optionally populate the idxFlags field with a
+** mask of SQLITE_INDEX_SCAN_* flags. Currently there is only one such flag -
+** SQLITE_INDEX_SCAN_UNIQUE. If the xBestIndex method sets this flag, SQLite
+** assumes that the strategy may visit at most one row.
+**
+** Additionally, if xBestIndex sets the SQLITE_INDEX_SCAN_UNIQUE flag, then
+** SQLite also assumes that if a call to the xUpdate() method is made as
+** part of the same statement to delete or update a virtual table row and the
+** implementation returns SQLITE_CONSTRAINT, then there is no need to rollback
+** any database changes. In other words, if the xUpdate() returns
+** SQLITE_CONSTRAINT, the database contents must be exactly as they were
+** before xUpdate was called. By contrast, if SQLITE_INDEX_SCAN_UNIQUE is not
+** set and xUpdate returns SQLITE_CONSTRAINT, any database changes made by
+** the xUpdate method are automatically rolled back by SQLite.
+**
+** IMPORTANT: The estimatedRows field was added to the sqlite3_index_info
+** structure for SQLite version 3.8.2. If a virtual table extension is
+** used with an SQLite version earlier than 3.8.2, the results of attempting
+** to read or write the estimatedRows field are undefined (but are likely
+** to included crashing the application). The estimatedRows field should
+** therefore only be used if [sqlite3_libversion_number()] returns a
+** value greater than or equal to 3008002. Similarly, the idxFlags field
+** was added for version 3.9.0. It may therefore only be used if
+** sqlite3_libversion_number() returns a value greater than or equal to
+** 3009000.
*/
struct sqlite3_index_info {
/* Inputs */
@@ -5768,10 +5930,21 @@ struct sqlite3_index_info {
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 */
+ double estimatedCost; /* Estimated cost of using this index */
+ /* Fields below are only available in SQLite 3.8.2 and later */
+ sqlite3_int64 estimatedRows; /* Estimated number of rows returned */
+ /* Fields below are only available in SQLite 3.9.0 and later */
+ int idxFlags; /* Mask of SQLITE_INDEX_SCAN_* flags */
+ /* Fields below are only available in SQLite 3.10.0 and later */
+ sqlite3_uint64 colUsed; /* Input: Mask of columns used by statement */
};
/*
+** CAPI3REF: Virtual Table Scan Flags
+*/
+#define SQLITE_INDEX_SCAN_UNIQUE 1 /* Scan visits at most 1 row */
+
+/*
** CAPI3REF: Virtual Table Constraint Operator Codes
**
** These macros defined the allowed values for the
@@ -5779,15 +5952,19 @@ struct sqlite3_index_info {
** 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
+#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
+#define SQLITE_INDEX_CONSTRAINT_LIKE 65
+#define SQLITE_INDEX_CONSTRAINT_GLOB 66
+#define SQLITE_INDEX_CONSTRAINT_REGEXP 67
/*
** CAPI3REF: Register A Virtual Table Implementation
+** METHOD: sqlite3
**
** ^These routines are used to register a new [virtual table module] name.
** ^Module names must be registered before
@@ -5811,13 +5988,13 @@ struct sqlite3_index_info {
** interface is equivalent to sqlite3_create_module_v2() with a NULL
** destructor.
*/
-SQLITE_API int sqlite3_create_module(
+SQLITE_API int SQLITE_STDCALL 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(
+SQLITE_API int SQLITE_STDCALL 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 */
@@ -5845,7 +6022,7 @@ SQLITE_API int sqlite3_create_module_v2(
*/
struct sqlite3_vtab {
const sqlite3_module *pModule; /* The module for this virtual table */
- int nRef; /* NO LONGER USED */
+ int nRef; /* Number of open cursors */
char *zErrMsg; /* Error message from sqlite3_mprintf() */
/* Virtual table implementations will typically add additional fields */
};
@@ -5880,10 +6057,11 @@ struct sqlite3_vtab_cursor {
** 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);
+SQLITE_API int SQLITE_STDCALL sqlite3_declare_vtab(sqlite3*, const char *zSQL);
/*
** CAPI3REF: Overload A Function For A Virtual Table
+** METHOD: sqlite3
**
** ^(Virtual tables can provide alternative implementations of functions
** using the [xFindFunction] method of the [virtual table module].
@@ -5898,7 +6076,7 @@ SQLITE_API int sqlite3_declare_vtab(sqlite3*, const char *zSQL);
** 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);
+SQLITE_API int SQLITE_STDCALL sqlite3_overload_function(sqlite3*, const char *zFuncName, int nArg);
/*
** The interface to the virtual-table mechanism defined above (back up
@@ -5926,6 +6104,8 @@ typedef struct sqlite3_blob sqlite3_blob;
/*
** CAPI3REF: Open A BLOB For Incremental I/O
+** METHOD: sqlite3
+** CONSTRUCTOR: sqlite3_blob
**
** ^(This interfaces opens a [BLOB handle | handle] to the BLOB located
** in row iRow, column zColumn, table zTable in database zDb;
@@ -5935,26 +6115,42 @@ typedef struct sqlite3_blob sqlite3_blob;
** SELECT zColumn FROM zDb.zTable WHERE [rowid] = iRow;
** </pre>)^
**
+** ^(Parameter zDb is not the filename that contains the database, but
+** rather the symbolic name of the database. For attached databases, this is
+** the name that appears after the AS keyword in the [ATTACH] statement.
+** For the main database file, the database name is "main". For TEMP
+** tables, the database name is "temp".)^
+**
** ^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.
+** and write access. ^If the flags parameter is zero, the BLOB is opened for
+** read-only access.
+**
+** ^(On success, [SQLITE_OK] is returned and the new [BLOB handle] is stored
+** in *ppBlob. Otherwise an [error code] is returned and, unless the error
+** code is SQLITE_MISUSE, *ppBlob is set to NULL.)^ ^This means that, provided
+** the API is not misused, it is always safe to call [sqlite3_blob_close()]
+** on *ppBlob after this function it returns.
+**
+** This function fails with SQLITE_ERROR if any of the following are true:
+** <ul>
+** <li> ^(Database zDb does not exist)^,
+** <li> ^(Table zTable does not exist within database zDb)^,
+** <li> ^(Table zTable is a WITHOUT ROWID table)^,
+** <li> ^(Column zColumn does not exist)^,
+** <li> ^(Row iRow is not present in the table)^,
+** <li> ^(The specified column of row iRow contains a value that is not
+** a TEXT or BLOB value)^,
+** <li> ^(Column zColumn is part of an index, PRIMARY KEY or UNIQUE
+** constraint and the blob is being opened for read/write access)^,
+** <li> ^([foreign key constraints | Foreign key constraints] are enabled,
+** column zColumn is part of a [child key] definition and the blob is
+** being opened for read/write access)^.
+** </ul>
+**
+** ^Unless it returns SQLITE_MISUSE, this function sets the
+** [database connection] error code and message accessible via
+** [sqlite3_errcode()] and [sqlite3_errmsg()] and related functions.
+**
**
** ^(If the row that a BLOB handle points to is modified by an
** [UPDATE], [DELETE], or by [ON CONFLICT] side-effects
@@ -5973,14 +6169,13 @@ typedef struct sqlite3_blob sqlite3_blob;
** 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.
+** and the built-in [zeroblob] SQL function may be used to create a
+** zero-filled blob to read or write using the incremental-blob 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(
+SQLITE_API int SQLITE_STDCALL sqlite3_blob_open(
sqlite3*,
const char *zDb,
const char *zTable,
@@ -5992,6 +6187,7 @@ SQLITE_API int sqlite3_blob_open(
/*
** CAPI3REF: Move a BLOB Handle to a New Row
+** METHOD: sqlite3_blob
**
** ^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
@@ -6012,34 +6208,34 @@ SQLITE_API int sqlite3_blob_open(
**
** ^This function sets the database handle error code and message.
*/
-SQLITE_API SQLITE_EXPERIMENTAL int sqlite3_blob_reopen(sqlite3_blob *, sqlite3_int64);
+SQLITE_API int SQLITE_STDCALL sqlite3_blob_reopen(sqlite3_blob *, sqlite3_int64);
/*
** CAPI3REF: Close A BLOB Handle
+** DESTRUCTOR: sqlite3_blob
**
-** ^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.
+** ^This function closes an open [BLOB handle]. ^(The BLOB handle is closed
+** unconditionally. Even if this routine returns an error code, the
+** handle is still closed.)^
**
-** ^(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.)^
+** ^If the blob handle being closed was opened for read-write access, and if
+** the database is in auto-commit mode and there are no other open read-write
+** blob handles or active write statements, the current transaction is
+** committed. ^If an error occurs while committing the transaction, an error
+** code is returned and the transaction rolled back.
**
-** ^(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.
+** Calling this function with an argument that is not a NULL pointer or an
+** open blob handle results in undefined behaviour. ^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. ^Otherwise, if this function
+** is passed a valid open blob handle, the values returned by the
+** sqlite3_errcode() and sqlite3_errmsg() functions are set before returning.
*/
-SQLITE_API int sqlite3_blob_close(sqlite3_blob *);
+SQLITE_API int SQLITE_STDCALL sqlite3_blob_close(sqlite3_blob *);
/*
** CAPI3REF: Return The Size Of An Open BLOB
+** METHOD: sqlite3_blob
**
** ^Returns the size in bytes of the BLOB accessible via the
** successfully opened [BLOB handle] in its only argument. ^The
@@ -6051,10 +6247,11 @@ SQLITE_API int sqlite3_blob_close(sqlite3_blob *);
** 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 *);
+SQLITE_API int SQLITE_STDCALL sqlite3_blob_bytes(sqlite3_blob *);
/*
** CAPI3REF: Read Data From A BLOB Incrementally
+** METHOD: sqlite3_blob
**
** ^(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
@@ -6079,26 +6276,33 @@ SQLITE_API int sqlite3_blob_bytes(sqlite3_blob *);
**
** See also: [sqlite3_blob_write()].
*/
-SQLITE_API int sqlite3_blob_read(sqlite3_blob *, void *Z, int N, int iOffset);
+SQLITE_API int SQLITE_STDCALL sqlite3_blob_read(sqlite3_blob *, void *Z, int N, int iOffset);
/*
** CAPI3REF: Write Data Into A BLOB Incrementally
+** METHOD: sqlite3_blob
**
-** ^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.
+** ^(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.)^
+**
+** ^(On success, sqlite3_blob_write() returns SQLITE_OK.
+** Otherwise, an [error code] or an [extended error code] is returned.)^
+** ^Unless SQLITE_MISUSE is returned, this function sets the
+** [database connection] error code and message accessible via
+** [sqlite3_errcode()] and [sqlite3_errmsg()] and related functions.
**
** ^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
+** 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.
+** [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. ^If N or iOffset are less
+** than zero [SQLITE_ERROR] is returned and no data is written.
**
** ^An attempt to write to an expired [BLOB handle] fails with an
** error code of [SQLITE_ABORT]. ^Writes to the BLOB that occurred
@@ -6107,9 +6311,6 @@ SQLITE_API int sqlite3_blob_read(sqlite3_blob *, void *Z, int N, int iOffset);
** 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
@@ -6117,7 +6318,7 @@ SQLITE_API int sqlite3_blob_read(sqlite3_blob *, void *Z, int N, int iOffset);
**
** See also: [sqlite3_blob_read()].
*/
-SQLITE_API int sqlite3_blob_write(sqlite3_blob *, const void *z, int n, int iOffset);
+SQLITE_API int SQLITE_STDCALL sqlite3_blob_write(sqlite3_blob *, const void *z, int n, int iOffset);
/*
** CAPI3REF: Virtual File System Objects
@@ -6148,9 +6349,9 @@ SQLITE_API int sqlite3_blob_write(sqlite3_blob *, const void *z, int n, int iOff
** ^(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*);
+SQLITE_API sqlite3_vfs *SQLITE_STDCALL sqlite3_vfs_find(const char *zVfsName);
+SQLITE_API int SQLITE_STDCALL sqlite3_vfs_register(sqlite3_vfs*, int makeDflt);
+SQLITE_API int SQLITE_STDCALL sqlite3_vfs_unregister(sqlite3_vfs*);
/*
** CAPI3REF: Mutexes
@@ -6162,45 +6363,51 @@ SQLITE_API int sqlite3_vfs_unregister(sqlite3_vfs*);
**
** The SQLite source code contains multiple implementations
** of these mutex routines. An appropriate implementation
-** is selected automatically at compile-time. ^(The following
+** 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>)^
+** </ul>
**
-** ^The SQLITE_MUTEX_NOOP implementation is a set of routines
+** 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
+** 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
+** 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().)^
+** 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:
+** mutex and returns a pointer to it. ^The sqlite3_mutex_alloc()
+** routine returns NULL if it is unable to allocate the requested
+** mutex. The argument to sqlite3_mutex_alloc() must 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_OPEN
** <li> SQLITE_MUTEX_STATIC_PRNG
** <li> SQLITE_MUTEX_STATIC_LRU
-** <li> SQLITE_MUTEX_STATIC_LRU2
-** </ul>)^
+** <li> SQLITE_MUTEX_STATIC_PMEM
+** <li> SQLITE_MUTEX_STATIC_APP1
+** <li> SQLITE_MUTEX_STATIC_APP2
+** <li> SQLITE_MUTEX_STATIC_APP3
+** <li> SQLITE_MUTEX_STATIC_VFS1
+** <li> SQLITE_MUTEX_STATIC_VFS2
+** <li> SQLITE_MUTEX_STATIC_VFS3
+** </ul>
**
** ^The first two constants (SQLITE_MUTEX_FAST and SQLITE_MUTEX_RECURSIVE)
** cause sqlite3_mutex_alloc() to create
@@ -6208,14 +6415,14 @@ SQLITE_API int sqlite3_vfs_unregister(sqlite3_vfs*);
** 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
+** 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
+** a pointer to a static preexisting mutex. ^Nine 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
@@ -6224,16 +6431,13 @@ SQLITE_API int sqlite3_vfs_unregister(sqlite3_vfs*);
**
** ^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
+** returns a different mutex on every call. ^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.
+** allocated dynamic mutex. Attempting to deallocate a static
+** mutex results in undefined behavior.
**
** ^The sqlite3_mutex_enter() and sqlite3_mutex_try() routines attempt
** to enter a mutex. ^If another thread is already within the mutex,
@@ -6241,23 +6445,21 @@ SQLITE_API int sqlite3_vfs_unregister(sqlite3_vfs*);
** 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,
+** 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.)^
+** can enter.)^ If the same thread tries to enter any mutex other
+** than an SQLITE_MUTEX_RECURSIVE more than once, the behavior is undefined.
**
** ^(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.)^
+** 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
+** 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.)^
+** calling thread or is not currently allocated.
**
** ^If the argument to sqlite3_mutex_enter(), sqlite3_mutex_try(), or
** sqlite3_mutex_leave() is a NULL pointer, then all three routines
@@ -6265,11 +6467,11 @@ SQLITE_API int sqlite3_vfs_unregister(sqlite3_vfs*);
**
** 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*);
+SQLITE_API sqlite3_mutex *SQLITE_STDCALL sqlite3_mutex_alloc(int);
+SQLITE_API void SQLITE_STDCALL sqlite3_mutex_free(sqlite3_mutex*);
+SQLITE_API void SQLITE_STDCALL sqlite3_mutex_enter(sqlite3_mutex*);
+SQLITE_API int SQLITE_STDCALL sqlite3_mutex_try(sqlite3_mutex*);
+SQLITE_API void SQLITE_STDCALL sqlite3_mutex_leave(sqlite3_mutex*);
/*
** CAPI3REF: Mutex Methods Object
@@ -6278,9 +6480,9 @@ SQLITE_API void sqlite3_mutex_leave(sqlite3_mutex*);
** 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
+** sufficient, however the application 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
+** does not provide a suitable implementation. In this case, the application
** 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
@@ -6321,13 +6523,13 @@ SQLITE_API void sqlite3_mutex_leave(sqlite3_mutex*);
** (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
+** 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
+** 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.
**
@@ -6353,34 +6555,34 @@ struct sqlite3_mutex_methods {
** CAPI3REF: Mutex Verification Routines
**
** The sqlite3_mutex_held() and sqlite3_mutex_notheld() routines
-** are intended for use inside assert() statements. ^The SQLite core
+** 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
+** 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
+** 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
+** 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
+** 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
+** 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()
+** 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*);
+SQLITE_API int SQLITE_STDCALL sqlite3_mutex_held(sqlite3_mutex*);
+SQLITE_API int SQLITE_STDCALL sqlite3_mutex_notheld(sqlite3_mutex*);
#endif
/*
@@ -6403,9 +6605,16 @@ SQLITE_API int sqlite3_mutex_notheld(sqlite3_mutex*);
#define SQLITE_MUTEX_STATIC_LRU 6 /* lru page list */
#define SQLITE_MUTEX_STATIC_LRU2 7 /* NOT USED */
#define SQLITE_MUTEX_STATIC_PMEM 7 /* sqlite3PageMalloc() */
+#define SQLITE_MUTEX_STATIC_APP1 8 /* For use by application */
+#define SQLITE_MUTEX_STATIC_APP2 9 /* For use by application */
+#define SQLITE_MUTEX_STATIC_APP3 10 /* For use by application */
+#define SQLITE_MUTEX_STATIC_VFS1 11 /* For use by built-in VFS */
+#define SQLITE_MUTEX_STATIC_VFS2 12 /* For use by extension VFS */
+#define SQLITE_MUTEX_STATIC_VFS3 13 /* For use by application VFS */
/*
** CAPI3REF: Retrieve the mutex for a database connection
+** METHOD: sqlite3
**
** ^This interface returns a pointer the [sqlite3_mutex] object that
** serializes access to the [database connection] given in the argument
@@ -6413,10 +6622,11 @@ SQLITE_API int sqlite3_mutex_notheld(sqlite3_mutex*);
** ^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*);
+SQLITE_API sqlite3_mutex *SQLITE_STDCALL sqlite3_db_mutex(sqlite3*);
/*
** CAPI3REF: Low-Level Control Of Database Files
+** METHOD: sqlite3
**
** ^The [sqlite3_file_control()] interface makes a direct call to the
** xFileControl method for the [sqlite3_io_methods] object associated
@@ -6447,7 +6657,7 @@ SQLITE_API sqlite3_mutex *sqlite3_db_mutex(sqlite3*);
**
** See also: [SQLITE_FCNTL_LOCKSTATE]
*/
-SQLITE_API int sqlite3_file_control(sqlite3*, const char *zDbName, int op, void*);
+SQLITE_API int SQLITE_STDCALL sqlite3_file_control(sqlite3*, const char *zDbName, int op, void*);
/*
** CAPI3REF: Testing Interface
@@ -6466,7 +6676,7 @@ SQLITE_API int sqlite3_file_control(sqlite3*, const char *zDbName, int op, void*
** 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, ...);
+SQLITE_API int SQLITE_CDECL sqlite3_test_control(int op, ...);
/*
** CAPI3REF: Testing Interface Operation Codes
@@ -6494,13 +6704,19 @@ SQLITE_API int sqlite3_test_control(int op, ...);
#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
+#define SQLITE_TESTCTRL_EXPLAIN_STMT 19 /* NOT USED */
+#define SQLITE_TESTCTRL_NEVER_CORRUPT 20
+#define SQLITE_TESTCTRL_VDBE_COVERAGE 21
+#define SQLITE_TESTCTRL_BYTEORDER 22
+#define SQLITE_TESTCTRL_ISINIT 23
+#define SQLITE_TESTCTRL_SORTER_MMAP 24
+#define SQLITE_TESTCTRL_IMPOSTER 25
+#define SQLITE_TESTCTRL_LAST 25
/*
** CAPI3REF: SQLite Runtime Status
**
-** ^This interface is used to retrieve runtime status information
+** ^These interfaces are 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
@@ -6514,19 +6730,22 @@ SQLITE_API int sqlite3_test_control(int op, ...);
** ^(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.
+** ^The sqlite3_status() and sqlite3_status64() routines return
+** 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.
+** If either the current value or the highwater mark is too large to
+** be represented by a 32-bit integer, then the values returned by
+** sqlite3_status() are undefined.
**
** See also: [sqlite3_db_status()]
*/
-SQLITE_API int sqlite3_status(int op, int *pCurrent, int *pHighwater, int resetFlag);
+SQLITE_API int SQLITE_STDCALL sqlite3_status(int op, int *pCurrent, int *pHighwater, int resetFlag);
+SQLITE_API int SQLITE_STDCALL sqlite3_status64(
+ int op,
+ sqlite3_int64 *pCurrent,
+ sqlite3_int64 *pHighwater,
+ int resetFlag
+);
/*
@@ -6605,7 +6824,8 @@ SQLITE_API int sqlite3_status(int op, int *pCurrent, int *pHighwater, int resetF
** 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
+** <dd>The *pHighwater parameter records the deepest parser stack.
+** The *pCurrent value is undefined. The *pHighwater value is only
** meaningful if SQLite is compiled with [YYTRACKMAXSTACKDEPTH].</dd>)^
** </dl>
**
@@ -6624,6 +6844,7 @@ SQLITE_API int sqlite3_status(int op, int *pCurrent, int *pHighwater, int resetF
/*
** CAPI3REF: Database Connection Status
+** METHOD: sqlite3
**
** ^This interface is used to retrieve runtime status information
** about a single [database connection]. ^The first argument is the
@@ -6644,7 +6865,7 @@ SQLITE_API int sqlite3_status(int op, int *pCurrent, int *pHighwater, int resetF
**
** See also: [sqlite3_status()] and [sqlite3_stmt_status()].
*/
-SQLITE_API int sqlite3_db_status(sqlite3*, int op, int *pCur, int *pHiwtr, int resetFlg);
+SQLITE_API int SQLITE_STDCALL sqlite3_db_status(sqlite3*, int op, int *pCur, int *pHiwtr, int resetFlg);
/*
** CAPI3REF: Status Parameters for database connections
@@ -6686,12 +6907,12 @@ SQLITE_API int sqlite3_db_status(sqlite3*, int op, int *pCur, int *pHiwtr, int r
** 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
+** <dd>This parameter returns the approximate number 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
+** <dd>This parameter returns the approximate number 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
@@ -6700,7 +6921,7 @@ SQLITE_API int sqlite3_db_status(sqlite3*, int op, int *pCur, int *pHiwtr, int r
** ^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
+** <dd>This parameter returns the approximate number 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.
@@ -6728,6 +6949,12 @@ SQLITE_API int sqlite3_db_status(sqlite3*, int op, int *pCur, int *pHiwtr, int r
** on subsequent SQLITE_DBSTATUS_CACHE_WRITE requests is undefined.)^ ^The
** highwater mark associated with SQLITE_DBSTATUS_CACHE_WRITE is always 0.
** </dd>
+**
+** [[SQLITE_DBSTATUS_DEFERRED_FKS]] ^(<dt>SQLITE_DBSTATUS_DEFERRED_FKS</dt>
+** <dd>This parameter returns zero for the current value if and only if
+** all foreign key constraints (deferred or immediate) have been
+** resolved.)^ ^The highwater mark is always 0.
+** </dd>
** </dl>
*/
#define SQLITE_DBSTATUS_LOOKASIDE_USED 0
@@ -6740,11 +6967,13 @@ SQLITE_API int sqlite3_db_status(sqlite3*, int op, int *pCur, int *pHiwtr, int r
#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 */
+#define SQLITE_DBSTATUS_DEFERRED_FKS 10
+#define SQLITE_DBSTATUS_MAX 10 /* Largest defined DBSTATUS */
/*
** CAPI3REF: Prepared Statement Status
+** METHOD: sqlite3_stmt
**
** ^(Each prepared statement maintains various
** [SQLITE_STMTSTATUS counters] that measure the number
@@ -6766,7 +6995,7 @@ SQLITE_API int sqlite3_db_status(sqlite3*, int op, int *pCur, int *pHiwtr, int r
**
** See also: [sqlite3_status()] and [sqlite3_db_status()].
*/
-SQLITE_API int sqlite3_stmt_status(sqlite3_stmt*, int op,int resetFlg);
+SQLITE_API int SQLITE_STDCALL sqlite3_stmt_status(sqlite3_stmt*, int op,int resetFlg);
/*
** CAPI3REF: Status Parameters for prepared statements
@@ -6794,11 +7023,21 @@ SQLITE_API int sqlite3_stmt_status(sqlite3_stmt*, int op,int resetFlg);
** 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>
+**
+** [[SQLITE_STMTSTATUS_VM_STEP]] <dt>SQLITE_STMTSTATUS_VM_STEP</dt>
+** <dd>^This is the number of virtual machine operations executed
+** by the prepared statement if that number is less than or equal
+** to 2147483647. The number of virtual machine operations can be
+** used as a proxy for the total work done by the prepared statement.
+** If the number of virtual machine operations exceeds 2147483647
+** then the value returned by this statement status code is undefined.
+** </dd>
** </dl>
*/
#define SQLITE_STMTSTATUS_FULLSCAN_STEP 1
#define SQLITE_STMTSTATUS_SORT 2
#define SQLITE_STMTSTATUS_AUTOINDEX 3
+#define SQLITE_STMTSTATUS_VM_STEP 4
/*
** CAPI3REF: Custom Page Cache Object
@@ -6935,7 +7174,7 @@ struct sqlite3_pcache_page {
** 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><th> createFlag <th> Behavior 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.
@@ -7083,6 +7322,10 @@ typedef struct sqlite3_backup sqlite3_backup;
** must be different or else sqlite3_backup_init(D,N,S,M) will fail with
** an error.
**
+** ^A call to sqlite3_backup_init() will fail, returning SQLITE_ERROR, if
+** there is already a read or read-write transaction open on the
+** destination database.
+**
** ^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.
@@ -7175,20 +7418,20 @@ typedef struct sqlite3_backup sqlite3_backup;
** is not a permanent error and does not affect the return value of
** sqlite3_backup_finish().
**
-** [[sqlite3_backup__remaining()]] [[sqlite3_backup_pagecount()]]
+** [[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.
+** ^The sqlite3_backup_remaining() routine returns the number of pages still
+** to be backed up at the conclusion of the most recent sqlite3_backup_step().
+** ^The sqlite3_backup_pagecount() routine returns the total number of pages
+** in the source database at the conclusion of the most recent
+** sqlite3_backup_step().
+** ^(The values returned by these functions are only updated by
+** sqlite3_backup_step(). If the source database is modified in a way that
+** changes the size of the source database or the number of pages remaining,
+** those changes are not reflected in the output of sqlite3_backup_pagecount()
+** and sqlite3_backup_remaining() until after the next
+** sqlite3_backup_step().)^
**
** <b>Concurrent Usage of Database Handles</b>
**
@@ -7221,19 +7464,20 @@ typedef struct sqlite3_backup sqlite3_backup;
** 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(
+SQLITE_API sqlite3_backup *SQLITE_STDCALL 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);
+SQLITE_API int SQLITE_STDCALL sqlite3_backup_step(sqlite3_backup *p, int nPage);
+SQLITE_API int SQLITE_STDCALL sqlite3_backup_finish(sqlite3_backup *p);
+SQLITE_API int SQLITE_STDCALL sqlite3_backup_remaining(sqlite3_backup *p);
+SQLITE_API int SQLITE_STDCALL sqlite3_backup_pagecount(sqlite3_backup *p);
/*
** CAPI3REF: Unlock Notification
+** METHOD: sqlite3
**
** ^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
@@ -7346,7 +7590,7 @@ SQLITE_API int sqlite3_backup_pagecount(sqlite3_backup *p);
** the special "DROP TABLE/INDEX" case, the extended error code is just
** SQLITE_LOCKED.)^
*/
-SQLITE_API int sqlite3_unlock_notify(
+SQLITE_API int SQLITE_STDCALL sqlite3_unlock_notify(
sqlite3 *pBlocked, /* Waiting connection */
void (*xNotify)(void **apArg, int nArg), /* Callback function to invoke */
void *pNotifyArg /* Argument to pass to xNotify */
@@ -7361,13 +7605,53 @@ SQLITE_API int sqlite3_unlock_notify(
** 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);
+SQLITE_API int SQLITE_STDCALL sqlite3_stricmp(const char *, const char *);
+SQLITE_API int SQLITE_STDCALL sqlite3_strnicmp(const char *, const char *, int);
+
+/*
+** CAPI3REF: String Globbing
+*
+** ^The [sqlite3_strglob(P,X)] interface returns zero if and only if
+** string X matches the [GLOB] pattern P.
+** ^The definition of [GLOB] pattern matching used in
+** [sqlite3_strglob(P,X)] is the same as for the "X GLOB P" operator in the
+** SQL dialect understood by SQLite. ^The [sqlite3_strglob(P,X)] function
+** is case sensitive.
+**
+** Note that this routine returns zero on a match and non-zero if the strings
+** do not match, the same as [sqlite3_stricmp()] and [sqlite3_strnicmp()].
+**
+** See also: [sqlite3_strlike()].
+*/
+SQLITE_API int SQLITE_STDCALL sqlite3_strglob(const char *zGlob, const char *zStr);
+
+/*
+** CAPI3REF: String LIKE Matching
+*
+** ^The [sqlite3_strlike(P,X,E)] interface returns zero if and only if
+** string X matches the [LIKE] pattern P with escape character E.
+** ^The definition of [LIKE] pattern matching used in
+** [sqlite3_strlike(P,X,E)] is the same as for the "X LIKE P ESCAPE E"
+** operator in the SQL dialect understood by SQLite. ^For "X LIKE P" without
+** the ESCAPE clause, set the E parameter of [sqlite3_strlike(P,X,E)] to 0.
+** ^As with the LIKE operator, the [sqlite3_strlike(P,X,E)] function is case
+** insensitive - equivalent upper and lower case ASCII characters match
+** one another.
+**
+** ^The [sqlite3_strlike(P,X,E)] function matches Unicode characters, though
+** only ASCII characters are case folded.
+**
+** Note that this routine returns zero on a match and non-zero if the strings
+** do not match, the same as [sqlite3_stricmp()] and [sqlite3_strnicmp()].
+**
+** See also: [sqlite3_strglob()].
+*/
+SQLITE_API int SQLITE_STDCALL sqlite3_strlike(const char *zGlob, const char *zStr, unsigned int cEsc);
/*
** CAPI3REF: Error Logging Interface
**
-** ^The [sqlite3_log()] interface writes a message into the error log
+** ^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.
@@ -7385,18 +7669,17 @@ SQLITE_API int sqlite3_strnicmp(const char *, const char *, int);
** a few hundred characters, it will be truncated to the length of the
** buffer.
*/
-SQLITE_API void sqlite3_log(int iErrCode, const char *zFormat, ...);
+SQLITE_API void SQLITE_CDECL sqlite3_log(int iErrCode, const char *zFormat, ...);
/*
** CAPI3REF: Write-Ahead Log Commit Hook
+** METHOD: sqlite3
**
** ^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]).
+** is invoked each time data is committed to a database in 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
+** ^(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
@@ -7422,7 +7705,7 @@ SQLITE_API void sqlite3_log(int iErrCode, const char *zFormat, ...);
** [wal_autocheckpoint pragma] both invoke [sqlite3_wal_hook()] and will
** those overwrite any prior [sqlite3_wal_hook()] settings.
*/
-SQLITE_API void *sqlite3_wal_hook(
+SQLITE_API void *SQLITE_STDCALL sqlite3_wal_hook(
sqlite3*,
int(*)(void *,sqlite3*,const char*,int),
void*
@@ -7430,6 +7713,7 @@ SQLITE_API void *sqlite3_wal_hook(
/*
** CAPI3REF: Configure an auto-checkpoint
+** METHOD: sqlite3
**
** ^The [sqlite3_wal_autocheckpoint(D,N)] is a wrapper around
** [sqlite3_wal_hook()] that causes any database on [database connection] D
@@ -7447,103 +7731,132 @@ SQLITE_API void *sqlite3_wal_hook(
** ^The [wal_autocheckpoint pragma] can be used to invoke this interface
** from SQL.
**
+** ^Checkpoints initiated by this mechanism are
+** [sqlite3_wal_checkpoint_v2|PASSIVE].
+**
** ^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);
+SQLITE_API int SQLITE_STDCALL sqlite3_wal_autocheckpoint(sqlite3 *db, int N);
/*
** CAPI3REF: Checkpoint a database
+** METHOD: sqlite3
**
-** ^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 sqlite3_wal_checkpoint(D,X) is equivalent to
+** [sqlite3_wal_checkpoint_v2](D,X,[SQLITE_CHECKPOINT_PASSIVE],0,0).)^
**
-** ^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.
+** In brief, sqlite3_wal_checkpoint(D,X) causes the content in the
+** [write-ahead log] for database X on [database connection] D to be
+** transferred into the database file and for the write-ahead log to
+** be reset. See the [checkpointing] documentation for addition
+** information.
**
-** See also: [sqlite3_wal_checkpoint_v2()]
+** This interface used to be the only way to cause a checkpoint to
+** occur. But then the newer and more powerful [sqlite3_wal_checkpoint_v2()]
+** interface was added. This interface is retained for backwards
+** compatibility and as a convenience for applications that need to manually
+** start a callback but which do not need the full power (and corresponding
+** complication) of [sqlite3_wal_checkpoint_v2()].
*/
-SQLITE_API int sqlite3_wal_checkpoint(sqlite3 *db, const char *zDb);
+SQLITE_API int SQLITE_STDCALL sqlite3_wal_checkpoint(sqlite3 *db, const char *zDb);
/*
** CAPI3REF: Checkpoint a database
+** METHOD: sqlite3
**
-** 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:
+** ^(The sqlite3_wal_checkpoint_v2(D,X,M,L,C) interface runs a checkpoint
+** operation on database X of [database connection] D in mode M. Status
+** information is written back into integers pointed to by L and C.)^
+** ^(The M parameter must be a valid [checkpoint mode]:)^
**
** <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.
+** ^Checkpoint as many frames as possible without waiting for any database
+** readers or writers to finish, then sync the database file if all frames
+** in the log were checkpointed. ^The [busy-handler callback]
+** is never invoked in the SQLITE_CHECKPOINT_PASSIVE mode.
+** ^On the other hand, passive mode might leave the checkpoint unfinished
+** if there are concurrent readers or writers.
**
** <dt>SQLITE_CHECKPOINT_FULL<dd>
-** This mode blocks (calls the busy-handler callback) until there is no
+** ^This mode blocks (it invokes the
+** [sqlite3_busy_handler|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.
+** snapshot. ^It then checkpoints all frames in the log file and syncs the
+** database file. ^This mode blocks new database writers while it is pending,
+** but new database readers are allowed to continue unimpeded.
**
** <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.
+** ^This mode works the same way as SQLITE_CHECKPOINT_FULL with the addition
+** that 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 writer will restart the log file from the beginning.
+** ^Like SQLITE_CHECKPOINT_FULL, this mode blocks new
+** database writer attempts while it is pending, but does not impede readers.
+**
+** <dt>SQLITE_CHECKPOINT_TRUNCATE<dd>
+** ^This mode works the same way as SQLITE_CHECKPOINT_RESTART with the
+** addition that it also truncates the log file to zero bytes just prior
+** to a successful return.
** </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
+** ^If pnLog is not NULL, then *pnLog is set to the total number of frames in
+** the log file or to -1 if the checkpoint could not run because
+** of an error or because the database is not in [WAL mode]. ^If pnCkpt is not
+** NULL,then *pnCkpt is set to the total number of checkpointed frames in the
+** log file (including any that were already checkpointed before the function
+** was called) or to -1 if the checkpoint could not run due to an error or
+** because the database is not in WAL mode. ^Note that upon successful
+** completion of an SQLITE_CHECKPOINT_TRUNCATE, the log file will have been
+** truncated to zero bytes and so both *pnLog and *pnCkpt will be set to zero.
+**
+** ^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
+** 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 SQLITE_CHECKPOINT_FULL, RESTART and TRUNCATE 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.
+** 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
+** ^If parameter zDb is NULL or points to a zero length string, then the
+** specified operation is attempted on all WAL databases [attached] to
+** [database connection] db. 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
+** attached databases and SQLITE_BUSY is returned at the end. ^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
+** and the error code is 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
+** ^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.
+**
+** ^Unless it returns SQLITE_MISUSE,
+** the sqlite3_wal_checkpoint_v2() interface
+** sets the error information that is queried by
+** [sqlite3_errcode()] and [sqlite3_errmsg()].
+**
+** ^The [PRAGMA wal_checkpoint] command can be used to invoke this interface
+** from SQL.
*/
-SQLITE_API int sqlite3_wal_checkpoint_v2(
+SQLITE_API int SQLITE_STDCALL sqlite3_wal_checkpoint_v2(
sqlite3 *db, /* Database handle */
const char *zDb, /* Name of attached database (or NULL) */
int eMode, /* SQLITE_CHECKPOINT_* value */
@@ -7552,16 +7865,18 @@ SQLITE_API int sqlite3_wal_checkpoint_v2(
);
/*
-** CAPI3REF: Checkpoint operation parameters
+** CAPI3REF: Checkpoint Mode Values
+** KEYWORDS: {checkpoint mode}
**
-** 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.
+** These constants define all valid values for the "checkpoint mode" passed
+** as the third parameter to the [sqlite3_wal_checkpoint_v2()] interface.
+** See the [sqlite3_wal_checkpoint_v2()] documentation for details on the
+** meaning of each of these checkpoint modes.
*/
-#define SQLITE_CHECKPOINT_PASSIVE 0
-#define SQLITE_CHECKPOINT_FULL 1
-#define SQLITE_CHECKPOINT_RESTART 2
+#define SQLITE_CHECKPOINT_PASSIVE 0 /* Do as much as possible w/o blocking */
+#define SQLITE_CHECKPOINT_FULL 1 /* Wait for writers, then checkpoint */
+#define SQLITE_CHECKPOINT_RESTART 2 /* Like FULL but wait for for readers */
+#define SQLITE_CHECKPOINT_TRUNCATE 3 /* Like RESTART but also truncate WAL */
/*
** CAPI3REF: Virtual Table Interface Configuration
@@ -7577,7 +7892,7 @@ SQLITE_API int sqlite3_wal_checkpoint_v2(
** this function. (See [SQLITE_VTAB_CONSTRAINT_SUPPORT].) Further options
** may be added in the future.
*/
-SQLITE_API int sqlite3_vtab_config(sqlite3*, int op, ...);
+SQLITE_API int SQLITE_CDECL sqlite3_vtab_config(sqlite3*, int op, ...);
/*
** CAPI3REF: Virtual Table Configuration Options
@@ -7630,10 +7945,11 @@ SQLITE_API int sqlite3_vtab_config(sqlite3*, int op, ...);
** of the SQL statement that triggered the call to the [xUpdate] method of the
** [virtual table].
*/
-SQLITE_API int sqlite3_vtab_on_conflict(sqlite3 *);
+SQLITE_API int SQLITE_STDCALL sqlite3_vtab_on_conflict(sqlite3 *);
/*
** CAPI3REF: Conflict resolution modes
+** KEYWORDS: {conflict resolution mode}
**
** These constants are returned by [sqlite3_vtab_on_conflict()] to
** inform a [virtual table] implementation what the [ON CONFLICT] mode
@@ -7649,7 +7965,232 @@ SQLITE_API int sqlite3_vtab_on_conflict(sqlite3 *);
/* #define SQLITE_ABORT 4 // Also an error code */
#define SQLITE_REPLACE 5
+/*
+** CAPI3REF: Prepared Statement Scan Status Opcodes
+** KEYWORDS: {scanstatus options}
+**
+** The following constants can be used for the T parameter to the
+** [sqlite3_stmt_scanstatus(S,X,T,V)] interface. Each constant designates a
+** different metric for sqlite3_stmt_scanstatus() to return.
+**
+** When the value returned to V is a string, space to hold that string is
+** managed by the prepared statement S and will be automatically freed when
+** S is finalized.
+**
+** <dl>
+** [[SQLITE_SCANSTAT_NLOOP]] <dt>SQLITE_SCANSTAT_NLOOP</dt>
+** <dd>^The [sqlite3_int64] variable pointed to by the T parameter will be
+** set to the total number of times that the X-th loop has run.</dd>
+**
+** [[SQLITE_SCANSTAT_NVISIT]] <dt>SQLITE_SCANSTAT_NVISIT</dt>
+** <dd>^The [sqlite3_int64] variable pointed to by the T parameter will be set
+** to the total number of rows examined by all iterations of the X-th loop.</dd>
+**
+** [[SQLITE_SCANSTAT_EST]] <dt>SQLITE_SCANSTAT_EST</dt>
+** <dd>^The "double" variable pointed to by the T parameter will be set to the
+** query planner's estimate for the average number of rows output from each
+** iteration of the X-th loop. If the query planner's estimates was accurate,
+** then this value will approximate the quotient NVISIT/NLOOP and the
+** product of this value for all prior loops with the same SELECTID will
+** be the NLOOP value for the current loop.
+**
+** [[SQLITE_SCANSTAT_NAME]] <dt>SQLITE_SCANSTAT_NAME</dt>
+** <dd>^The "const char *" variable pointed to by the T parameter will be set
+** to a zero-terminated UTF-8 string containing the name of the index or table
+** used for the X-th loop.
+**
+** [[SQLITE_SCANSTAT_EXPLAIN]] <dt>SQLITE_SCANSTAT_EXPLAIN</dt>
+** <dd>^The "const char *" variable pointed to by the T parameter will be set
+** to a zero-terminated UTF-8 string containing the [EXPLAIN QUERY PLAN]
+** description for the X-th loop.
+**
+** [[SQLITE_SCANSTAT_SELECTID]] <dt>SQLITE_SCANSTAT_SELECT</dt>
+** <dd>^The "int" variable pointed to by the T parameter will be set to the
+** "select-id" for the X-th loop. The select-id identifies which query or
+** subquery the loop is part of. The main query has a select-id of zero.
+** The select-id is the same value as is output in the first column
+** of an [EXPLAIN QUERY PLAN] query.
+** </dl>
+*/
+#define SQLITE_SCANSTAT_NLOOP 0
+#define SQLITE_SCANSTAT_NVISIT 1
+#define SQLITE_SCANSTAT_EST 2
+#define SQLITE_SCANSTAT_NAME 3
+#define SQLITE_SCANSTAT_EXPLAIN 4
+#define SQLITE_SCANSTAT_SELECTID 5
+
+/*
+** CAPI3REF: Prepared Statement Scan Status
+** METHOD: sqlite3_stmt
+**
+** This interface returns information about the predicted and measured
+** performance for pStmt. Advanced applications can use this
+** interface to compare the predicted and the measured performance and
+** issue warnings and/or rerun [ANALYZE] if discrepancies are found.
+**
+** Since this interface is expected to be rarely used, it is only
+** available if SQLite is compiled using the [SQLITE_ENABLE_STMT_SCANSTATUS]
+** compile-time option.
+**
+** The "iScanStatusOp" parameter determines which status information to return.
+** The "iScanStatusOp" must be one of the [scanstatus options] or the behavior
+** of this interface is undefined.
+** ^The requested measurement is written into a variable pointed to by
+** the "pOut" parameter.
+** Parameter "idx" identifies the specific loop to retrieve statistics for.
+** Loops are numbered starting from zero. ^If idx is out of range - less than
+** zero or greater than or equal to the total number of loops used to implement
+** the statement - a non-zero value is returned and the variable that pOut
+** points to is unchanged.
+**
+** ^Statistics might not be available for all loops in all statements. ^In cases
+** where there exist loops with no available statistics, this function behaves
+** as if the loop did not exist - it returns non-zero and leave the variable
+** that pOut points to unchanged.
+**
+** See also: [sqlite3_stmt_scanstatus_reset()]
+*/
+SQLITE_API int SQLITE_STDCALL sqlite3_stmt_scanstatus(
+ sqlite3_stmt *pStmt, /* Prepared statement for which info desired */
+ int idx, /* Index of loop to report on */
+ int iScanStatusOp, /* Information desired. SQLITE_SCANSTAT_* */
+ void *pOut /* Result written here */
+);
+
+/*
+** CAPI3REF: Zero Scan-Status Counters
+** METHOD: sqlite3_stmt
+**
+** ^Zero all [sqlite3_stmt_scanstatus()] related event counters.
+**
+** This API is only available if the library is built with pre-processor
+** symbol [SQLITE_ENABLE_STMT_SCANSTATUS] defined.
+*/
+SQLITE_API void SQLITE_STDCALL sqlite3_stmt_scanstatus_reset(sqlite3_stmt*);
+
+/*
+** CAPI3REF: Flush caches to disk mid-transaction
+**
+** ^If a write-transaction is open on [database connection] D when the
+** [sqlite3_db_cacheflush(D)] interface invoked, any dirty
+** pages in the pager-cache that are not currently in use are written out
+** to disk. A dirty page may be in use if a database cursor created by an
+** active SQL statement is reading from it, or if it is page 1 of a database
+** file (page 1 is always "in use"). ^The [sqlite3_db_cacheflush(D)]
+** interface flushes caches for all schemas - "main", "temp", and
+** any [attached] databases.
+**
+** ^If this function needs to obtain extra database locks before dirty pages
+** can be flushed to disk, it does so. ^If those locks cannot be obtained
+** immediately and there is a busy-handler callback configured, it is invoked
+** in the usual manner. ^If the required lock still cannot be obtained, then
+** the database is skipped and an attempt made to flush any dirty pages
+** belonging to the next (if any) database. ^If any databases are skipped
+** because locks cannot be obtained, but no other error occurs, this
+** function returns SQLITE_BUSY.
+**
+** ^If any other error occurs while flushing dirty pages to disk (for
+** example an IO error or out-of-memory condition), then processing is
+** abandoned and an SQLite [error code] is returned to the caller immediately.
+**
+** ^Otherwise, if no error occurs, [sqlite3_db_cacheflush()] returns SQLITE_OK.
+**
+** ^This function does not set the database handle error code or message
+** returned by the [sqlite3_errcode()] and [sqlite3_errmsg()] functions.
+*/
+SQLITE_API int SQLITE_STDCALL sqlite3_db_cacheflush(sqlite3*);
+
+/*
+** CAPI3REF: Database Snapshot
+** KEYWORDS: {snapshot}
+** EXPERIMENTAL
+**
+** An instance of the snapshot object records the state of a [WAL mode]
+** database for some specific point in history.
+**
+** In [WAL mode], multiple [database connections] that are open on the
+** same database file can each be reading a different historical version
+** of the database file. When a [database connection] begins a read
+** transaction, that connection sees an unchanging copy of the database
+** as it existed for the point in time when the transaction first started.
+** Subsequent changes to the database from other connections are not seen
+** by the reader until a new read transaction is started.
+**
+** The sqlite3_snapshot object records state information about an historical
+** version of the database file so that it is possible to later open a new read
+** transaction that sees that historical version of the database rather than
+** the most recent version.
+**
+** The constructor for this object is [sqlite3_snapshot_get()]. The
+** [sqlite3_snapshot_open()] method causes a fresh read transaction to refer
+** to an historical snapshot (if possible). The destructor for
+** sqlite3_snapshot objects is [sqlite3_snapshot_free()].
+*/
+typedef struct sqlite3_snapshot sqlite3_snapshot;
+/*
+** CAPI3REF: Record A Database Snapshot
+** EXPERIMENTAL
+**
+** ^The [sqlite3_snapshot_get(D,S,P)] interface attempts to make a
+** new [sqlite3_snapshot] object that records the current state of
+** schema S in database connection D. ^On success, the
+** [sqlite3_snapshot_get(D,S,P)] interface writes a pointer to the newly
+** created [sqlite3_snapshot] object into *P and returns SQLITE_OK.
+** ^If schema S of [database connection] D is not a [WAL mode] database
+** that is in a read transaction, then [sqlite3_snapshot_get(D,S,P)]
+** leaves the *P value unchanged and returns an appropriate [error code].
+**
+** The [sqlite3_snapshot] object returned from a successful call to
+** [sqlite3_snapshot_get()] must be freed using [sqlite3_snapshot_free()]
+** to avoid a memory leak.
+**
+** The [sqlite3_snapshot_get()] interface is only available when the
+** SQLITE_ENABLE_SNAPSHOT compile-time option is used.
+*/
+SQLITE_API SQLITE_EXPERIMENTAL int SQLITE_STDCALL sqlite3_snapshot_get(
+ sqlite3 *db,
+ const char *zSchema,
+ sqlite3_snapshot **ppSnapshot
+);
+
+/*
+** CAPI3REF: Start a read transaction on an historical snapshot
+** EXPERIMENTAL
+**
+** ^The [sqlite3_snapshot_open(D,S,P)] interface attempts to move the
+** read transaction that is currently open on schema S of
+** [database connection] D so that it refers to historical [snapshot] P.
+** ^The [sqlite3_snapshot_open()] interface returns SQLITE_OK on success
+** or an appropriate [error code] if it fails.
+**
+** ^In order to succeed, a call to [sqlite3_snapshot_open(D,S,P)] must be
+** the first operation, apart from other sqlite3_snapshot_open() calls,
+** following the [BEGIN] that starts a new read transaction.
+** ^A [snapshot] will fail to open if it has been overwritten by a
+** [checkpoint].
+**
+** The [sqlite3_snapshot_open()] interface is only available when the
+** SQLITE_ENABLE_SNAPSHOT compile-time option is used.
+*/
+SQLITE_API SQLITE_EXPERIMENTAL int SQLITE_STDCALL sqlite3_snapshot_open(
+ sqlite3 *db,
+ const char *zSchema,
+ sqlite3_snapshot *pSnapshot
+);
+
+/*
+** CAPI3REF: Destroy a snapshot
+** EXPERIMENTAL
+**
+** ^The [sqlite3_snapshot_free(P)] interface destroys [sqlite3_snapshot] P.
+** The application must eventually free every [sqlite3_snapshot] object
+** using this routine to avoid a memory leak.
+**
+** The [sqlite3_snapshot_free()] interface is only available when the
+** SQLITE_ENABLE_SNAPSHOT compile-time option is used.
+*/
+SQLITE_API SQLITE_EXPERIMENTAL void SQLITE_STDCALL sqlite3_snapshot_free(sqlite3_snapshot*);
/*
** Undo the hack that converts floating point types to integer for
@@ -7662,7 +8203,7 @@ SQLITE_API int sqlite3_vtab_on_conflict(sqlite3 *);
#if 0
} /* End of the 'extern "C"' block */
#endif
-#endif
+#endif /* _SQLITE3_H_ */
/*
** 2010 August 30
@@ -7686,6 +8227,16 @@ extern "C" {
#endif
typedef struct sqlite3_rtree_geometry sqlite3_rtree_geometry;
+typedef struct sqlite3_rtree_query_info sqlite3_rtree_query_info;
+
+/* The double-precision datatype used by RTree depends on the
+** SQLITE_RTREE_INT_ONLY compile-time option.
+*/
+#ifdef SQLITE_RTREE_INT_ONLY
+ typedef sqlite3_int64 sqlite3_rtree_dbl;
+#else
+ typedef double sqlite3_rtree_dbl;
+#endif
/*
** Register a geometry callback named zGeom that can be used as part of an
@@ -7693,14 +8244,10 @@ typedef struct sqlite3_rtree_geometry sqlite3_rtree_geometry;
**
** SELECT ... FROM <rtree> WHERE <rtree col> MATCH $zGeom(... params ...)
*/
-SQLITE_API int sqlite3_rtree_geometry_callback(
+SQLITE_API int SQLITE_STDCALL 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
+ int (*xGeom)(sqlite3_rtree_geometry*, int, sqlite3_rtree_dbl*,int*),
void *pContext
);
@@ -7712,11 +8259,62 @@ SQLITE_API int sqlite3_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 */
+ sqlite3_rtree_dbl *aParam; /* Parameters passed to SQL geom function */
void *pUser; /* Callback implementation user data */
void (*xDelUser)(void *); /* Called by SQLite to clean up pUser */
};
+/*
+** Register a 2nd-generation geometry callback named zScore that can be
+** used as part of an R-Tree geometry query as follows:
+**
+** SELECT ... FROM <rtree> WHERE <rtree col> MATCH $zQueryFunc(... params ...)
+*/
+SQLITE_API int SQLITE_STDCALL sqlite3_rtree_query_callback(
+ sqlite3 *db,
+ const char *zQueryFunc,
+ int (*xQueryFunc)(sqlite3_rtree_query_info*),
+ void *pContext,
+ void (*xDestructor)(void*)
+);
+
+
+/*
+** A pointer to a structure of the following type is passed as the
+** argument to scored geometry callback registered using
+** sqlite3_rtree_query_callback().
+**
+** Note that the first 5 fields of this structure are identical to
+** sqlite3_rtree_geometry. This structure is a subclass of
+** sqlite3_rtree_geometry.
+*/
+struct sqlite3_rtree_query_info {
+ void *pContext; /* pContext from when function registered */
+ int nParam; /* Number of function parameters */
+ sqlite3_rtree_dbl *aParam; /* value of function parameters */
+ void *pUser; /* callback can use this, if desired */
+ void (*xDelUser)(void*); /* function to free pUser */
+ sqlite3_rtree_dbl *aCoord; /* Coordinates of node or entry to check */
+ unsigned int *anQueue; /* Number of pending entries in the queue */
+ int nCoord; /* Number of coordinates */
+ int iLevel; /* Level of current node or entry */
+ int mxLevel; /* The largest iLevel value in the tree */
+ sqlite3_int64 iRowid; /* Rowid for current entry */
+ sqlite3_rtree_dbl rParentScore; /* Score of parent node */
+ int eParentWithin; /* Visibility of parent node */
+ int eWithin; /* OUT: Visiblity */
+ sqlite3_rtree_dbl rScore; /* OUT: Write the score here */
+ /* The following fields are only available in 3.8.11 and later */
+ sqlite3_value **apSqlParam; /* Original SQL values of parameters */
+};
+
+/*
+** Allowed values for sqlite3_rtree_query.eWithin and .eParentWithin.
+*/
+#define NOT_WITHIN 0 /* Object completely outside of query region */
+#define PARTLY_WITHIN 1 /* Object partially overlaps query region */
+#define FULLY_WITHIN 2 /* Object fully contained within query region */
+
#if 0
} /* end of the 'extern "C"' block */
@@ -7724,9 +8322,1075 @@ struct sqlite3_rtree_geometry {
#endif /* ifndef _SQLITE3RTREE_H_ */
+/*
+** 2014 May 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.
+**
+******************************************************************************
+**
+** Interfaces to extend FTS5. Using the interfaces defined in this file,
+** FTS5 may be extended with:
+**
+** * custom tokenizers, and
+** * custom auxiliary functions.
+*/
+
+
+#ifndef _FTS5_H
+#define _FTS5_H
+
+
+#if 0
+extern "C" {
+#endif
+
+/*************************************************************************
+** CUSTOM AUXILIARY FUNCTIONS
+**
+** Virtual table implementations may overload SQL functions by implementing
+** the sqlite3_module.xFindFunction() method.
+*/
+
+typedef struct Fts5ExtensionApi Fts5ExtensionApi;
+typedef struct Fts5Context Fts5Context;
+typedef struct Fts5PhraseIter Fts5PhraseIter;
+
+typedef void (*fts5_extension_function)(
+ const Fts5ExtensionApi *pApi, /* API offered by current FTS version */
+ Fts5Context *pFts, /* First arg to pass to pApi functions */
+ sqlite3_context *pCtx, /* Context for returning result/error */
+ int nVal, /* Number of values in apVal[] array */
+ sqlite3_value **apVal /* Array of trailing arguments */
+);
+
+struct Fts5PhraseIter {
+ const unsigned char *a;
+ const unsigned char *b;
+};
+
+/*
+** EXTENSION API FUNCTIONS
+**
+** xUserData(pFts):
+** Return a copy of the context pointer the extension function was
+** registered with.
+**
+** xColumnTotalSize(pFts, iCol, pnToken):
+** If parameter iCol is less than zero, set output variable *pnToken
+** to the total number of tokens in the FTS5 table. Or, if iCol is
+** non-negative but less than the number of columns in the table, return
+** the total number of tokens in column iCol, considering all rows in
+** the FTS5 table.
+**
+** If parameter iCol is greater than or equal to the number of columns
+** in the table, SQLITE_RANGE is returned. Or, if an error occurs (e.g.
+** an OOM condition or IO error), an appropriate SQLite error code is
+** returned.
+**
+** xColumnCount(pFts):
+** Return the number of columns in the table.
+**
+** xColumnSize(pFts, iCol, pnToken):
+** If parameter iCol is less than zero, set output variable *pnToken
+** to the total number of tokens in the current row. Or, if iCol is
+** non-negative but less than the number of columns in the table, set
+** *pnToken to the number of tokens in column iCol of the current row.
+**
+** If parameter iCol is greater than or equal to the number of columns
+** in the table, SQLITE_RANGE is returned. Or, if an error occurs (e.g.
+** an OOM condition or IO error), an appropriate SQLite error code is
+** returned.
+**
+** xColumnText:
+** This function attempts to retrieve the text of column iCol of the
+** current document. If successful, (*pz) is set to point to a buffer
+** containing the text in utf-8 encoding, (*pn) is set to the size in bytes
+** (not characters) of the buffer and SQLITE_OK is returned. Otherwise,
+** if an error occurs, an SQLite error code is returned and the final values
+** of (*pz) and (*pn) are undefined.
+**
+** xPhraseCount:
+** Returns the number of phrases in the current query expression.
+**
+** xPhraseSize:
+** Returns the number of tokens in phrase iPhrase of the query. Phrases
+** are numbered starting from zero.
+**
+** xInstCount:
+** Set *pnInst to the total number of occurrences of all phrases within
+** the query within the current row. Return SQLITE_OK if successful, or
+** an error code (i.e. SQLITE_NOMEM) if an error occurs.
+**
+** xInst:
+** Query for the details of phrase match iIdx within the current row.
+** Phrase matches are numbered starting from zero, so the iIdx argument
+** should be greater than or equal to zero and smaller than the value
+** output by xInstCount().
+**
+** Returns SQLITE_OK if successful, or an error code (i.e. SQLITE_NOMEM)
+** if an error occurs.
+**
+** xRowid:
+** Returns the rowid of the current row.
+**
+** xTokenize:
+** Tokenize text using the tokenizer belonging to the FTS5 table.
+**
+** xQueryPhrase(pFts5, iPhrase, pUserData, xCallback):
+** This API function is used to query the FTS table for phrase iPhrase
+** of the current query. Specifically, a query equivalent to:
+**
+** ... FROM ftstable WHERE ftstable MATCH $p ORDER BY rowid
+**
+** with $p set to a phrase equivalent to the phrase iPhrase of the
+** current query is executed. For each row visited, the callback function
+** passed as the fourth argument is invoked. The context and API objects
+** passed to the callback function may be used to access the properties of
+** each matched row. Invoking Api.xUserData() returns a copy of the pointer
+** passed as the third argument to pUserData.
+**
+** If the callback function returns any value other than SQLITE_OK, the
+** query is abandoned and the xQueryPhrase function returns immediately.
+** If the returned value is SQLITE_DONE, xQueryPhrase returns SQLITE_OK.
+** Otherwise, the error code is propagated upwards.
+**
+** If the query runs to completion without incident, SQLITE_OK is returned.
+** Or, if some error occurs before the query completes or is aborted by
+** the callback, an SQLite error code is returned.
+**
+**
+** xSetAuxdata(pFts5, pAux, xDelete)
+**
+** Save the pointer passed as the second argument as the extension functions
+** "auxiliary data". The pointer may then be retrieved by the current or any
+** future invocation of the same fts5 extension function made as part of
+** of the same MATCH query using the xGetAuxdata() API.
+**
+** Each extension function is allocated a single auxiliary data slot for
+** each FTS query (MATCH expression). If the extension function is invoked
+** more than once for a single FTS query, then all invocations share a
+** single auxiliary data context.
+**
+** If there is already an auxiliary data pointer when this function is
+** invoked, then it is replaced by the new pointer. If an xDelete callback
+** was specified along with the original pointer, it is invoked at this
+** point.
+**
+** The xDelete callback, if one is specified, is also invoked on the
+** auxiliary data pointer after the FTS5 query has finished.
+**
+** If an error (e.g. an OOM condition) occurs within this function, an
+** the auxiliary data is set to NULL and an error code returned. If the
+** xDelete parameter was not NULL, it is invoked on the auxiliary data
+** pointer before returning.
+**
+**
+** xGetAuxdata(pFts5, bClear)
+**
+** Returns the current auxiliary data pointer for the fts5 extension
+** function. See the xSetAuxdata() method for details.
+**
+** If the bClear argument is non-zero, then the auxiliary data is cleared
+** (set to NULL) before this function returns. In this case the xDelete,
+** if any, is not invoked.
+**
+**
+** xRowCount(pFts5, pnRow)
+**
+** This function is used to retrieve the total number of rows in the table.
+** In other words, the same value that would be returned by:
+**
+** SELECT count(*) FROM ftstable;
+**
+** xPhraseFirst()
+** This function is used, along with type Fts5PhraseIter and the xPhraseNext
+** method, to iterate through all instances of a single query phrase within
+** the current row. This is the same information as is accessible via the
+** xInstCount/xInst APIs. While the xInstCount/xInst APIs are more convenient
+** to use, this API may be faster under some circumstances. To iterate
+** through instances of phrase iPhrase, use the following code:
+**
+** Fts5PhraseIter iter;
+** int iCol, iOff;
+** for(pApi->xPhraseFirst(pFts, iPhrase, &iter, &iCol, &iOff);
+** iOff>=0;
+** pApi->xPhraseNext(pFts, &iter, &iCol, &iOff)
+** ){
+** // An instance of phrase iPhrase at offset iOff of column iCol
+** }
+**
+** The Fts5PhraseIter structure is defined above. Applications should not
+** modify this structure directly - it should only be used as shown above
+** with the xPhraseFirst() and xPhraseNext() API methods.
+**
+** xPhraseNext()
+** See xPhraseFirst above.
+*/
+struct Fts5ExtensionApi {
+ int iVersion; /* Currently always set to 1 */
+
+ void *(*xUserData)(Fts5Context*);
+
+ int (*xColumnCount)(Fts5Context*);
+ int (*xRowCount)(Fts5Context*, sqlite3_int64 *pnRow);
+ int (*xColumnTotalSize)(Fts5Context*, int iCol, sqlite3_int64 *pnToken);
+
+ int (*xTokenize)(Fts5Context*,
+ const char *pText, int nText, /* Text to tokenize */
+ void *pCtx, /* Context passed to xToken() */
+ int (*xToken)(void*, int, const char*, int, int, int) /* Callback */
+ );
+
+ int (*xPhraseCount)(Fts5Context*);
+ int (*xPhraseSize)(Fts5Context*, int iPhrase);
+
+ int (*xInstCount)(Fts5Context*, int *pnInst);
+ int (*xInst)(Fts5Context*, int iIdx, int *piPhrase, int *piCol, int *piOff);
+
+ sqlite3_int64 (*xRowid)(Fts5Context*);
+ int (*xColumnText)(Fts5Context*, int iCol, const char **pz, int *pn);
+ int (*xColumnSize)(Fts5Context*, int iCol, int *pnToken);
+
+ int (*xQueryPhrase)(Fts5Context*, int iPhrase, void *pUserData,
+ int(*)(const Fts5ExtensionApi*,Fts5Context*,void*)
+ );
+ int (*xSetAuxdata)(Fts5Context*, void *pAux, void(*xDelete)(void*));
+ void *(*xGetAuxdata)(Fts5Context*, int bClear);
+
+ void (*xPhraseFirst)(Fts5Context*, int iPhrase, Fts5PhraseIter*, int*, int*);
+ void (*xPhraseNext)(Fts5Context*, Fts5PhraseIter*, int *piCol, int *piOff);
+};
+
+/*
+** CUSTOM AUXILIARY FUNCTIONS
+*************************************************************************/
+
+/*************************************************************************
+** CUSTOM TOKENIZERS
+**
+** Applications may also register custom tokenizer types. A tokenizer
+** is registered by providing fts5 with a populated instance of the
+** following structure. All structure methods must be defined, setting
+** any member of the fts5_tokenizer struct to NULL leads to undefined
+** behaviour. The structure methods are expected to function as follows:
+**
+** xCreate:
+** This function is used to allocate and inititalize a tokenizer instance.
+** A tokenizer instance is required to actually tokenize text.
+**
+** The first argument passed to this function is a copy of the (void*)
+** pointer provided by the application when the fts5_tokenizer object
+** was registered with FTS5 (the third argument to xCreateTokenizer()).
+** The second and third arguments are an array of nul-terminated strings
+** containing the tokenizer arguments, if any, specified following the
+** tokenizer name as part of the CREATE VIRTUAL TABLE statement used
+** to create the FTS5 table.
+**
+** The final argument is an output variable. If successful, (*ppOut)
+** should be set to point to the new tokenizer handle and SQLITE_OK
+** returned. If an error occurs, some value other than SQLITE_OK should
+** be returned. In this case, fts5 assumes that the final value of *ppOut
+** is undefined.
+**
+** xDelete:
+** This function is invoked to delete a tokenizer handle previously
+** allocated using xCreate(). Fts5 guarantees that this function will
+** be invoked exactly once for each successful call to xCreate().
+**
+** xTokenize:
+** This function is expected to tokenize the nText byte string indicated
+** by argument pText. pText may or may not be nul-terminated. The first
+** argument passed to this function is a pointer to an Fts5Tokenizer object
+** returned by an earlier call to xCreate().
+**
+** The second argument indicates the reason that FTS5 is requesting
+** tokenization of the supplied text. This is always one of the following
+** four values:
+**
+** <ul><li> <b>FTS5_TOKENIZE_DOCUMENT</b> - A document is being inserted into
+** or removed from the FTS table. The tokenizer is being invoked to
+** determine the set of tokens to add to (or delete from) the
+** FTS index.
+**
+** <li> <b>FTS5_TOKENIZE_QUERY</b> - A MATCH query is being executed
+** against the FTS index. The tokenizer is being called to tokenize
+** a bareword or quoted string specified as part of the query.
+**
+** <li> <b>(FTS5_TOKENIZE_QUERY | FTS5_TOKENIZE_PREFIX)</b> - Same as
+** FTS5_TOKENIZE_QUERY, except that the bareword or quoted string is
+** followed by a "*" character, indicating that the last token
+** returned by the tokenizer will be treated as a token prefix.
+**
+** <li> <b>FTS5_TOKENIZE_AUX</b> - The tokenizer is being invoked to
+** satisfy an fts5_api.xTokenize() request made by an auxiliary
+** function. Or an fts5_api.xColumnSize() request made by the same
+** on a columnsize=0 database.
+** </ul>
+**
+** For each token in the input string, the supplied callback xToken() must
+** be invoked. The first argument to it should be a copy of the pointer
+** passed as the second argument to xTokenize(). The third and fourth
+** arguments are a pointer to a buffer containing the token text, and the
+** size of the token in bytes. The 4th and 5th arguments are the byte offsets
+** of the first byte of and first byte immediately following the text from
+** which the token is derived within the input.
+**
+** The second argument passed to the xToken() callback ("tflags") should
+** normally be set to 0. The exception is if the tokenizer supports
+** synonyms. In this case see the discussion below for details.
+**
+** FTS5 assumes the xToken() callback is invoked for each token in the
+** order that they occur within the input text.
+**
+** If an xToken() callback returns any value other than SQLITE_OK, then
+** the tokenization should be abandoned and the xTokenize() method should
+** immediately return a copy of the xToken() return value. Or, if the
+** input buffer is exhausted, xTokenize() should return SQLITE_OK. Finally,
+** if an error occurs with the xTokenize() implementation itself, it
+** may abandon the tokenization and return any error code other than
+** SQLITE_OK or SQLITE_DONE.
+**
+** SYNONYM SUPPORT
+**
+** Custom tokenizers may also support synonyms. Consider a case in which a
+** user wishes to query for a phrase such as "first place". Using the
+** built-in tokenizers, the FTS5 query 'first + place' will match instances
+** of "first place" within the document set, but not alternative forms
+** such as "1st place". In some applications, it would be better to match
+** all instances of "first place" or "1st place" regardless of which form
+** the user specified in the MATCH query text.
+**
+** There are several ways to approach this in FTS5:
+**
+** <ol><li> By mapping all synonyms to a single token. In this case, the
+** In the above example, this means that the tokenizer returns the
+** same token for inputs "first" and "1st". Say that token is in
+** fact "first", so that when the user inserts the document "I won
+** 1st place" entries are added to the index for tokens "i", "won",
+** "first" and "place". If the user then queries for '1st + place',
+** the tokenizer substitutes "first" for "1st" and the query works
+** as expected.
+**
+** <li> By adding multiple synonyms for a single term to the FTS index.
+** In this case, when tokenizing query text, the tokenizer may
+** provide multiple synonyms for a single term within the document.
+** FTS5 then queries the index for each synonym individually. For
+** example, faced with the query:
+**
+** <codeblock>
+** ... MATCH 'first place'</codeblock>
+**
+** the tokenizer offers both "1st" and "first" as synonyms for the
+** first token in the MATCH query and FTS5 effectively runs a query
+** similar to:
+**
+** <codeblock>
+** ... MATCH '(first OR 1st) place'</codeblock>
+**
+** except that, for the purposes of auxiliary functions, the query
+** still appears to contain just two phrases - "(first OR 1st)"
+** being treated as a single phrase.
+**
+** <li> By adding multiple synonyms for a single term to the FTS index.
+** Using this method, when tokenizing document text, the tokenizer
+** provides multiple synonyms for each token. So that when a
+** document such as "I won first place" is tokenized, entries are
+** added to the FTS index for "i", "won", "first", "1st" and
+** "place".
+**
+** This way, even if the tokenizer does not provide synonyms
+** when tokenizing query text (it should not - to do would be
+** inefficient), it doesn't matter if the user queries for
+** 'first + place' or '1st + place', as there are entires in the
+** FTS index corresponding to both forms of the first token.
+** </ol>
+**
+** Whether it is parsing document or query text, any call to xToken that
+** specifies a <i>tflags</i> argument with the FTS5_TOKEN_COLOCATED bit
+** is considered to supply a synonym for the previous token. For example,
+** when parsing the document "I won first place", a tokenizer that supports
+** synonyms would call xToken() 5 times, as follows:
+**
+** <codeblock>
+** xToken(pCtx, 0, "i", 1, 0, 1);
+** xToken(pCtx, 0, "won", 3, 2, 5);
+** xToken(pCtx, 0, "first", 5, 6, 11);
+** xToken(pCtx, FTS5_TOKEN_COLOCATED, "1st", 3, 6, 11);
+** xToken(pCtx, 0, "place", 5, 12, 17);
+**</codeblock>
+**
+** It is an error to specify the FTS5_TOKEN_COLOCATED flag the first time
+** xToken() is called. Multiple synonyms may be specified for a single token
+** by making multiple calls to xToken(FTS5_TOKEN_COLOCATED) in sequence.
+** There is no limit to the number of synonyms that may be provided for a
+** single token.
+**
+** In many cases, method (1) above is the best approach. It does not add
+** extra data to the FTS index or require FTS5 to query for multiple terms,
+** so it is efficient in terms of disk space and query speed. However, it
+** does not support prefix queries very well. If, as suggested above, the
+** token "first" is subsituted for "1st" by the tokenizer, then the query:
+**
+** <codeblock>
+** ... MATCH '1s*'</codeblock>
+**
+** will not match documents that contain the token "1st" (as the tokenizer
+** will probably not map "1s" to any prefix of "first").
+**
+** For full prefix support, method (3) may be preferred. In this case,
+** because the index contains entries for both "first" and "1st", prefix
+** queries such as 'fi*' or '1s*' will match correctly. However, because
+** extra entries are added to the FTS index, this method uses more space
+** within the database.
+**
+** Method (2) offers a midpoint between (1) and (3). Using this method,
+** a query such as '1s*' will match documents that contain the literal
+** token "1st", but not "first" (assuming the tokenizer is not able to
+** provide synonyms for prefixes). However, a non-prefix query like '1st'
+** will match against "1st" and "first". This method does not require
+** extra disk space, as no extra entries are added to the FTS index.
+** On the other hand, it may require more CPU cycles to run MATCH queries,
+** as separate queries of the FTS index are required for each synonym.
+**
+** When using methods (2) or (3), it is important that the tokenizer only
+** provide synonyms when tokenizing document text (method (2)) or query
+** text (method (3)), not both. Doing so will not cause any errors, but is
+** inefficient.
+*/
+typedef struct Fts5Tokenizer Fts5Tokenizer;
+typedef struct fts5_tokenizer fts5_tokenizer;
+struct fts5_tokenizer {
+ int (*xCreate)(void*, const char **azArg, int nArg, Fts5Tokenizer **ppOut);
+ void (*xDelete)(Fts5Tokenizer*);
+ int (*xTokenize)(Fts5Tokenizer*,
+ void *pCtx,
+ int flags, /* Mask of FTS5_TOKENIZE_* flags */
+ const char *pText, int nText,
+ int (*xToken)(
+ void *pCtx, /* Copy of 2nd argument to xTokenize() */
+ int tflags, /* Mask of FTS5_TOKEN_* flags */
+ const char *pToken, /* Pointer to buffer containing token */
+ int nToken, /* Size of token in bytes */
+ int iStart, /* Byte offset of token within input text */
+ int iEnd /* Byte offset of end of token within input text */
+ )
+ );
+};
+
+/* Flags that may be passed as the third argument to xTokenize() */
+#define FTS5_TOKENIZE_QUERY 0x0001
+#define FTS5_TOKENIZE_PREFIX 0x0002
+#define FTS5_TOKENIZE_DOCUMENT 0x0004
+#define FTS5_TOKENIZE_AUX 0x0008
+
+/* Flags that may be passed by the tokenizer implementation back to FTS5
+** as the third argument to the supplied xToken callback. */
+#define FTS5_TOKEN_COLOCATED 0x0001 /* Same position as prev. token */
+
+/*
+** END OF CUSTOM TOKENIZERS
+*************************************************************************/
+
+/*************************************************************************
+** FTS5 EXTENSION REGISTRATION API
+*/
+typedef struct fts5_api fts5_api;
+struct fts5_api {
+ int iVersion; /* Currently always set to 2 */
+
+ /* Create a new tokenizer */
+ int (*xCreateTokenizer)(
+ fts5_api *pApi,
+ const char *zName,
+ void *pContext,
+ fts5_tokenizer *pTokenizer,
+ void (*xDestroy)(void*)
+ );
+
+ /* Find an existing tokenizer */
+ int (*xFindTokenizer)(
+ fts5_api *pApi,
+ const char *zName,
+ void **ppContext,
+ fts5_tokenizer *pTokenizer
+ );
+
+ /* Create a new auxiliary function */
+ int (*xCreateFunction)(
+ fts5_api *pApi,
+ const char *zName,
+ void *pContext,
+ fts5_extension_function xFunction,
+ void (*xDestroy)(void*)
+ );
+};
+
+/*
+** END OF REGISTRATION API
+*************************************************************************/
+
+#if 0
+} /* end of the 'extern "C"' block */
+#endif
+
+#endif /* _FTS5_H */
+
+
/************** End of sqlite3.h *********************************************/
/************** Continuing where we left off in sqliteInt.h ******************/
+
+/*
+** 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 suggested maximum number of in-memory pages to use for
+** the main database table and for temporary tables.
+**
+** IMPLEMENTATION-OF: R-31093-59126 The default suggested cache size
+** is 2000 pages.
+** IMPLEMENTATION-OF: R-48205-43578 The default suggested cache size can be
+** altered using the SQLITE_DEFAULT_CACHE_SIZE compile-time options.
+*/
+#ifndef SQLITE_DEFAULT_CACHE_SIZE
+# define SQLITE_DEFAULT_CACHE_SIZE 2000
+#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
+
+/*
+** 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_WITHIN(P,S,E) macro checks to see if pointer P points to
+** something between S (inclusive) and E (exclusive).
+**
+** In other words, S is a buffer and E is a pointer to the first byte after
+** the end of buffer S. This macro returns true if P points to something
+** contained within the buffer S.
+*/
+#if defined(HAVE_STDINT_H)
+# define SQLITE_WITHIN(P,S,E) \
+ ((uintptr_t)(P)>=(uintptr_t)(S) && (uintptr_t)(P)<(uintptr_t)(E))
+#else
+# define SQLITE_WITHIN(P,S,E) ((P)>=(S) && (P)<(E))
+#endif
+
+/*
+** A macro to hint to the compiler that a function should not be
+** inlined.
+*/
+#if defined(__GNUC__)
+# define SQLITE_NOINLINE __attribute__((noinline))
+#elif defined(_MSC_VER) && _MSC_VER>=1310
+# define SQLITE_NOINLINE __declspec(noinline)
+#else
+# define SQLITE_NOINLINE
+#endif
+
+/*
+** Make sure that the compiler intrinsics we desire are enabled when
+** compiling with an appropriate version of MSVC unless prevented by
+** the SQLITE_DISABLE_INTRINSIC define.
+*/
+#if !defined(SQLITE_DISABLE_INTRINSIC)
+# if defined(_MSC_VER) && _MSC_VER>=1300
+# if !defined(_WIN32_WCE)
+# include <intrin.h>
+# pragma intrinsic(_byteswap_ushort)
+# pragma intrinsic(_byteswap_ulong)
+# pragma intrinsic(_ReadWriteBarrier)
+# else
+# include <cmnintrin.h>
+# endif
+# endif
+#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 library 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
+
+/*
+** EVIDENCE-OF: R-25715-37072 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.
+*/
+#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.
+**
+** 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 and fchmod() on OpenBSD.
+** But _XOPEN_SOURCE define causes problems for Mac OS X, so omit
+** it.
+*/
+#if !defined(_XOPEN_SOURCE) && !defined(__DARWIN__) && !defined(__APPLE__)
+# define _XOPEN_SOURCE 600
+#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 faster by disabling the
+** 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
+
+/*
+** Enable SQLITE_ENABLE_EXPLAIN_COMMENTS if SQLITE_DEBUG is turned on.
+*/
+#if !defined(SQLITE_ENABLE_EXPLAIN_COMMENTS) && defined(SQLITE_DEBUG)
+# define SQLITE_ENABLE_EXPLAIN_COMMENTS 1
+#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 they 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
+
+/*
+** Declarations used for tracing the operating system interfaces.
+*/
+#if defined(SQLITE_FORCE_OS_TRACE) || defined(SQLITE_TEST) || \
+ (defined(SQLITE_DEBUG) && SQLITE_OS_WIN)
+ extern int sqlite3OSTrace;
+# define OSTRACE(X) if( sqlite3OSTrace ) sqlite3DebugPrintf X
+# define SQLITE_HAVE_OS_TRACE
+#else
+# define OSTRACE(X)
+# undef SQLITE_HAVE_OS_TRACE
+#endif
+
+/*
+** Is the sqlite3ErrName() function needed in the build? Currently,
+** it is needed by "mutex_w32.c" (when debugging), "os_win.c" (when
+** OSTRACE is enabled), and by several "test*.c" files (which are
+** compiled using SQLITE_TEST).
+*/
+#if defined(SQLITE_HAVE_OS_TRACE) || defined(SQLITE_TEST) || \
+ (defined(SQLITE_DEBUG) && SQLITE_OS_WIN)
+# define SQLITE_NEED_ERR_NAME
+#else
+# undef SQLITE_NEED_ERR_NAME
+#endif
+
+/*
+** Return true (non-zero) if the input is an 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. These hints could,
+** in theory, be used by the compiler to generate better code, but
+** currently they are just comments for human readers.
+*/
+#define likely(X) (X)
+#define unlikely(X) (X)
+
/************** Include hash.h in the middle of sqliteInt.h ******************/
/************** Begin file hash.h ********************************************/
/*
@@ -7740,7 +9404,7 @@ struct sqlite3_rtree_geometry {
** May you share freely, never taking more than you give.
**
*************************************************************************
-** This is the header file for the generic hash-table implemenation
+** This is the header file for the generic hash-table implementation
** used in SQLite.
*/
#ifndef _SQLITE_HASH_H_
@@ -7790,15 +9454,15 @@ struct Hash {
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 */
+ const char *pKey; /* 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 *sqlite3HashInsert(Hash*, const char *pKey, void *pData);
+SQLITE_PRIVATE void *sqlite3HashFind(const Hash*, const char *pKey);
SQLITE_PRIVATE void sqlite3HashClear(Hash*);
/*
@@ -7830,163 +9494,173 @@ SQLITE_PRIVATE void sqlite3HashClear(Hash*);
/************** 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_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_WITHOUT 25
+#define TK_COMMA 26
+#define TK_ID 27
+#define TK_INDEXED 28
+#define TK_ABORT 29
+#define TK_ACTION 30
+#define TK_AFTER 31
+#define TK_ANALYZE 32
+#define TK_ASC 33
+#define TK_ATTACH 34
+#define TK_BEFORE 35
+#define TK_BY 36
+#define TK_CASCADE 37
+#define TK_CAST 38
+#define TK_COLUMNKW 39
+#define TK_CONFLICT 40
+#define TK_DATABASE 41
+#define TK_DESC 42
+#define TK_DETACH 43
+#define TK_EACH 44
+#define TK_FAIL 45
+#define TK_FOR 46
+#define TK_IGNORE 47
+#define TK_INITIALLY 48
+#define TK_INSTEAD 49
+#define TK_LIKE_KW 50
+#define TK_MATCH 51
+#define TK_NO 52
+#define TK_KEY 53
+#define TK_OF 54
+#define TK_OFFSET 55
+#define TK_PRAGMA 56
+#define TK_RAISE 57
+#define TK_RECURSIVE 58
+#define TK_REPLACE 59
+#define TK_RESTRICT 60
+#define TK_ROW 61
+#define TK_TRIGGER 62
+#define TK_VACUUM 63
+#define TK_VIEW 64
+#define TK_VIRTUAL 65
+#define TK_WITH 66
+#define TK_REINDEX 67
+#define TK_RENAME 68
+#define TK_CTIME_KW 69
+#define TK_ANY 70
+#define TK_OR 71
+#define TK_AND 72
+#define TK_IS 73
+#define TK_BETWEEN 74
+#define TK_IN 75
+#define TK_ISNULL 76
+#define TK_NOTNULL 77
+#define TK_NE 78
+#define TK_EQ 79
+#define TK_GT 80
+#define TK_LE 81
+#define TK_LT 82
+#define TK_GE 83
+#define TK_ESCAPE 84
+#define TK_BITAND 85
+#define TK_BITOR 86
+#define TK_LSHIFT 87
+#define TK_RSHIFT 88
+#define TK_PLUS 89
+#define TK_MINUS 90
+#define TK_STAR 91
+#define TK_SLASH 92
+#define TK_REM 93
+#define TK_CONCAT 94
+#define TK_COLLATE 95
+#define TK_BITNOT 96
+#define TK_STRING 97
+#define TK_JOIN_KW 98
+#define TK_CONSTRAINT 99
+#define TK_DEFAULT 100
+#define TK_NULL 101
+#define TK_PRIMARY 102
+#define TK_UNIQUE 103
+#define TK_CHECK 104
+#define TK_REFERENCES 105
+#define TK_AUTOINCR 106
+#define TK_ON 107
+#define TK_INSERT 108
+#define TK_DELETE 109
+#define TK_UPDATE 110
+#define TK_SET 111
+#define TK_DEFERRABLE 112
+#define TK_FOREIGN 113
+#define TK_DROP 114
+#define TK_UNION 115
+#define TK_ALL 116
+#define TK_EXCEPT 117
+#define TK_INTERSECT 118
+#define TK_SELECT 119
+#define TK_VALUES 120
+#define TK_DISTINCT 121
+#define TK_DOT 122
+#define TK_FROM 123
+#define TK_JOIN 124
+#define TK_USING 125
+#define TK_ORDER 126
+#define TK_GROUP 127
+#define TK_HAVING 128
+#define TK_LIMIT 129
+#define TK_WHERE 130
+#define TK_INTO 131
+#define TK_INTEGER 132
+#define TK_FLOAT 133
+#define TK_BLOB 134
+#define TK_VARIABLE 135
+#define TK_CASE 136
+#define TK_WHEN 137
+#define TK_THEN 138
+#define TK_ELSE 139
+#define TK_INDEX 140
+#define TK_ALTER 141
+#define TK_ADD 142
+#define TK_TO_TEXT 143
+#define TK_TO_BLOB 144
+#define TK_TO_NUMERIC 145
+#define TK_TO_INT 146
+#define TK_TO_REAL 147
+#define TK_ISNOT 148
+#define TK_END_OF_FILE 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
+#define TK_UMINUS 155
+#define TK_UPLUS 156
+#define TK_REGISTER 157
+#define TK_ASTERISK 158
+#define TK_SPACE 159
+#define TK_ILLEGAL 160
+
+/* The token codes above must all fit in 8 bits */
+#define TKFLG_MASK 0xff
+
+/* Flags that can be added to a token code when it is not
+** being stored in a u8: */
+#define TKFLG_DONTFOLD 0x100 /* Omit constant folding optimizations */
/************** End of parse.h ***********************************************/
/************** Continuing where we left off in sqliteInt.h ******************/
@@ -8052,6 +9726,37 @@ SQLITE_PRIVATE void sqlite3HashClear(Hash*);
*/
#ifndef SQLITE_TEMP_STORE
# define SQLITE_TEMP_STORE 1
+# define SQLITE_TEMP_STORE_xc 1 /* Exclude from ctime.c */
+#endif
+
+/*
+** If no value has been provided for SQLITE_MAX_WORKER_THREADS, or if
+** SQLITE_TEMP_STORE is set to 3 (never use temporary files), set it
+** to zero.
+*/
+#if SQLITE_TEMP_STORE==3 || SQLITE_THREADSAFE==0
+# undef SQLITE_MAX_WORKER_THREADS
+# define SQLITE_MAX_WORKER_THREADS 0
+#endif
+#ifndef SQLITE_MAX_WORKER_THREADS
+# define SQLITE_MAX_WORKER_THREADS 8
+#endif
+#ifndef SQLITE_DEFAULT_WORKER_THREADS
+# define SQLITE_DEFAULT_WORKER_THREADS 0
+#endif
+#if SQLITE_DEFAULT_WORKER_THREADS>SQLITE_MAX_WORKER_THREADS
+# undef SQLITE_MAX_WORKER_THREADS
+# define SQLITE_MAX_WORKER_THREADS SQLITE_DEFAULT_WORKER_THREADS
+#endif
+
+/*
+** The default initial allocation for the pagecache when using separate
+** pagecaches for each database connection. A positive number is the
+** number of pages. A negative number N translations means that a buffer
+** of -1024*N bytes is allocated and used for as many pages as it will hold.
+*/
+#ifndef SQLITE_DEFAULT_PCACHE_INITSZ
+# define SQLITE_DEFAULT_PCACHE_INITSZ 100
#endif
/*
@@ -8063,6 +9768,17 @@ SQLITE_PRIVATE void sqlite3HashClear(Hash*);
#endif
/*
+** Macros to compute minimum and maximum of two numbers.
+*/
+#define MIN(A,B) ((A)<(B)?(A):(B))
+#define MAX(A,B) ((A)>(B)?(A):(B))
+
+/*
+** Swap two objects of type TYPE.
+*/
+#define SWAP(TYPE,A,B) {TYPE t=A; A=B; B=t;}
+
+/*
** Check to see if this machine uses EBCDIC. (Yes, believe it or
** not, there are still machines out there that use EBCDIC.)
*/
@@ -8146,23 +9862,79 @@ typedef INT8_TYPE i8; /* 1-byte signed integer */
#endif
/*
-** Macros to determine whether the machine is big or little endian,
-** evaluated at runtime.
+** Estimated quantities used for query planning are stored as 16-bit
+** logarithms. For quantity X, the value stored is 10*log2(X). This
+** gives a possible range of values of approximately 1.0e986 to 1e-986.
+** But the allowed values are "grainy". Not every value is representable.
+** For example, quantities 16 and 17 are both represented by a LogEst
+** of 40. However, since LogEst quantities are suppose to be estimates,
+** not exact values, this imprecision is not a problem.
+**
+** "LogEst" is short for "Logarithmic Estimate".
+**
+** Examples:
+** 1 -> 0 20 -> 43 10000 -> 132
+** 2 -> 10 25 -> 46 25000 -> 146
+** 3 -> 16 100 -> 66 1000000 -> 199
+** 4 -> 20 1000 -> 99 1048576 -> 200
+** 10 -> 33 1024 -> 100 4294967296 -> 320
+**
+** The LogEst can be negative to indicate fractional values.
+** Examples:
+**
+** 0.5 -> -10 0.1 -> -33 0.0625 -> -40
+*/
+typedef INT16_TYPE LogEst;
+
+/*
+** Set the SQLITE_PTRSIZE macro to the number of bytes in a pointer
*/
-#if defined(i386) || defined(__i386__) || defined(_M_IX86)\
- || defined(__x86_64) || defined(__x86_64__)
+#ifndef SQLITE_PTRSIZE
+# if defined(__SIZEOF_POINTER__)
+# define SQLITE_PTRSIZE __SIZEOF_POINTER__
+# elif defined(i386) || defined(__i386__) || defined(_M_IX86) || \
+ defined(_M_ARM) || defined(__arm__) || defined(__x86)
+# define SQLITE_PTRSIZE 4
+# else
+# define SQLITE_PTRSIZE 8
+# endif
+#endif
+
+/*
+** Macros to determine whether the machine is big or little endian,
+** and whether or not that determination is run-time or compile-time.
+**
+** For best performance, an attempt is made to guess at the byte-order
+** using C-preprocessor macros. If that is unsuccessful, or if
+** -DSQLITE_RUNTIME_BYTEORDER=1 is set, then byte-order is determined
+** at run-time.
+*/
+#if (defined(i386) || defined(__i386__) || defined(_M_IX86) || \
+ defined(__x86_64) || defined(__x86_64__) || defined(_M_X64) || \
+ defined(_M_AMD64) || defined(_M_ARM) || defined(__x86) || \
+ defined(__arm__)) && !defined(SQLITE_RUNTIME_BYTEORDER)
+# define SQLITE_BYTEORDER 1234
# define SQLITE_BIGENDIAN 0
# define SQLITE_LITTLEENDIAN 1
# define SQLITE_UTF16NATIVE SQLITE_UTF16LE
-#else
+#endif
+#if (defined(sparc) || defined(__ppc__)) \
+ && !defined(SQLITE_RUNTIME_BYTEORDER)
+# define SQLITE_BYTEORDER 4321
+# define SQLITE_BIGENDIAN 1
+# define SQLITE_LITTLEENDIAN 0
+# define SQLITE_UTF16NATIVE SQLITE_UTF16BE
+#endif
+#if !defined(SQLITE_BYTEORDER)
# ifdef SQLITE_AMALGAMATION
-SQLITE_PRIVATE const int sqlite3one = 1;
+ const int sqlite3one = 1;
# else
-SQLITE_PRIVATE const int sqlite3one;
+ extern const int sqlite3one;
# endif
+# define SQLITE_BYTEORDER 0 /* 0 means "unknown at compile-time" */
# define SQLITE_BIGENDIAN (*(char *)(&sqlite3one)==0)
# define SQLITE_LITTLEENDIAN (*(char *)(&sqlite3one)==1)
-# define SQLITE_UTF16NATIVE (SQLITE_BIGENDIAN?SQLITE_UTF16BE:SQLITE_UTF16LE)
+# define SQLITE_UTF16NATIVE (SQLITE_BIGENDIAN?SQLITE_UTF16BE:SQLITE_UTF16LE)
#endif
/*
@@ -8190,7 +9962,7 @@ SQLITE_PRIVATE const int sqlite3one;
** all alignment restrictions correct.
**
** Except, if SQLITE_4_BYTE_ALIGNED_MALLOC is defined, then the
-** underlying malloc() implemention might return us 4-byte aligned
+** underlying malloc() implementation might return us 4-byte aligned
** pointers. In that case, only verify 4-byte alignment.
*/
#ifdef SQLITE_4_BYTE_ALIGNED_MALLOC
@@ -8199,6 +9971,75 @@ SQLITE_PRIVATE const int sqlite3one;
# define EIGHT_BYTE_ALIGNMENT(X) ((((char*)(X) - (char*)0)&7)==0)
#endif
+/*
+** Disable MMAP on platforms where it is known to not work
+*/
+#if defined(__OpenBSD__) || defined(__QNXNTO__)
+# undef SQLITE_MAX_MMAP_SIZE
+# define SQLITE_MAX_MMAP_SIZE 0
+#endif
+
+/*
+** Default maximum size of memory used by memory-mapped I/O in the VFS
+*/
+#ifdef __APPLE__
+# include <TargetConditionals.h>
+# if TARGET_OS_IPHONE
+# undef SQLITE_MAX_MMAP_SIZE
+# define SQLITE_MAX_MMAP_SIZE 0
+# endif
+#endif
+#ifndef SQLITE_MAX_MMAP_SIZE
+# if defined(__linux__) \
+ || defined(_WIN32) \
+ || (defined(__APPLE__) && defined(__MACH__)) \
+ || defined(__sun) \
+ || defined(__FreeBSD__) \
+ || defined(__DragonFly__)
+# define SQLITE_MAX_MMAP_SIZE 0x7fff0000 /* 2147418112 */
+# else
+# define SQLITE_MAX_MMAP_SIZE 0
+# endif
+# define SQLITE_MAX_MMAP_SIZE_xc 1 /* exclude from ctime.c */
+#endif
+
+/*
+** The default MMAP_SIZE is zero on all platforms. Or, even if a larger
+** default MMAP_SIZE is specified at compile-time, make sure that it does
+** not exceed the maximum mmap size.
+*/
+#ifndef SQLITE_DEFAULT_MMAP_SIZE
+# define SQLITE_DEFAULT_MMAP_SIZE 0
+# define SQLITE_DEFAULT_MMAP_SIZE_xc 1 /* Exclude from ctime.c */
+#endif
+#if SQLITE_DEFAULT_MMAP_SIZE>SQLITE_MAX_MMAP_SIZE
+# undef SQLITE_DEFAULT_MMAP_SIZE
+# define SQLITE_DEFAULT_MMAP_SIZE SQLITE_MAX_MMAP_SIZE
+#endif
+
+/*
+** Only one of SQLITE_ENABLE_STAT3 or SQLITE_ENABLE_STAT4 can be defined.
+** Priority is given to SQLITE_ENABLE_STAT4. If either are defined, also
+** define SQLITE_ENABLE_STAT3_OR_STAT4
+*/
+#ifdef SQLITE_ENABLE_STAT4
+# undef SQLITE_ENABLE_STAT3
+# define SQLITE_ENABLE_STAT3_OR_STAT4 1
+#elif SQLITE_ENABLE_STAT3
+# define SQLITE_ENABLE_STAT3_OR_STAT4 1
+#elif SQLITE_ENABLE_STAT3_OR_STAT4
+# undef SQLITE_ENABLE_STAT3_OR_STAT4
+#endif
+
+/*
+** SELECTTRACE_ENABLED will be either 1 or 0 depending on whether or not
+** the Select query generator tracing logic is turned on.
+*/
+#if defined(SQLITE_DEBUG) || defined(SQLITE_ENABLE_SELECTTRACE)
+# define SELECTTRACE_ENABLED 1
+#else
+# define SELECTTRACE_ENABLED 0
+#endif
/*
** An instance of the following structure is used to store the busy-handler
@@ -8241,6 +10082,11 @@ struct BusyHandler {
#define ArraySize(X) ((int)(sizeof(X)/sizeof(X[0])))
/*
+** Determine if the argument is a power of two
+*/
+#define IsPowerOfTwo(X) (((X)&((X)-1))==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
@@ -8268,8 +10114,8 @@ struct BusyHandler {
#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);
+SQLITE_API int SQLITE_STDCALL sqlite3_wsd_init(int N, int J);
+SQLITE_API void *SQLITE_STDCALL sqlite3_wsd_find(void *K, int L);
#else
#define SQLITE_WSD
#define GLOBAL(t,v) v
@@ -8323,15 +10169,18 @@ typedef struct LookasideSlot LookasideSlot;
typedef struct Module Module;
typedef struct NameContext NameContext;
typedef struct Parse Parse;
+typedef struct PrintfArguments PrintfArguments;
typedef struct RowSet RowSet;
typedef struct Savepoint Savepoint;
typedef struct Select Select;
+typedef struct SQLiteThread SQLiteThread;
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 TreeView TreeView;
typedef struct Trigger Trigger;
typedef struct TriggerPrg TriggerPrg;
typedef struct TriggerStep TriggerStep;
@@ -8339,9 +10188,8 @@ 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;
+typedef struct With With;
/*
** Defer sourcing vdbe.h and btree.h until after the "u8" and
@@ -8371,7 +10219,7 @@ typedef struct WhereLevel WhereLevel;
/* TODO: This definition is just included so other modules compile. It
** needs to be revisited.
*/
-#define SQLITE_N_BTREE_META 10
+#define SQLITE_N_BTREE_META 16
/*
** If defined as non-zero, auto-vacuum is enabled by default. Otherwise
@@ -8415,24 +10263,26 @@ SQLITE_PRIVATE int sqlite3BtreeOpen(
SQLITE_PRIVATE int sqlite3BtreeClose(Btree*);
SQLITE_PRIVATE int sqlite3BtreeSetCacheSize(Btree*,int);
-SQLITE_PRIVATE int sqlite3BtreeSetSafetyLevel(Btree*,int,int,int);
+SQLITE_PRIVATE int sqlite3BtreeSetSpillSize(Btree*,int);
+#if SQLITE_MAX_MMAP_SIZE>0
+SQLITE_PRIVATE int sqlite3BtreeSetMmapLimit(Btree*,sqlite3_int64);
+#endif
+SQLITE_PRIVATE int sqlite3BtreeSetPagerFlags(Btree*,unsigned);
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 sqlite3BtreeGetOptimalReserve(Btree*);
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 sqlite3BtreeRollback(Btree*,int,int);
SQLITE_PRIVATE int sqlite3BtreeBeginStmt(Btree*,int);
SQLITE_PRIVATE int sqlite3BtreeCreateTable(Btree*, int*, int flags);
SQLITE_PRIVATE int sqlite3BtreeIsInTrans(Btree*);
@@ -8464,7 +10314,8 @@ SQLITE_PRIVATE int sqlite3BtreeIncrVacuum(Btree *);
SQLITE_PRIVATE int sqlite3BtreeDropTable(Btree*, int, int*);
SQLITE_PRIVATE int sqlite3BtreeClearTable(Btree*, int, int*);
-SQLITE_PRIVATE void sqlite3BtreeTripAllCursors(Btree*, int);
+SQLITE_PRIVATE int sqlite3BtreeClearTableOfCursor(BtCursor*);
+SQLITE_PRIVATE int sqlite3BtreeTripAllCursors(Btree*, int, int);
SQLITE_PRIVATE void sqlite3BtreeGetMeta(Btree *pBtree, int idx, u32 *pValue);
SQLITE_PRIVATE int sqlite3BtreeUpdateMeta(Btree*, int idx, u32 value);
@@ -8482,6 +10333,11 @@ SQLITE_PRIVATE int sqlite3BtreeNewDb(Btree *p);
** 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).
+**
+** The BTREE_DATA_VERSION value is not really a value stored in the header.
+** It is a read-only number computed by the pager. But we merge it with
+** the header value access routines since its access pattern is the same.
+** Call it a "virtual meta value".
*/
#define BTREE_FREE_PAGE_COUNT 0
#define BTREE_SCHEMA_VERSION 1
@@ -8491,12 +10347,69 @@ SQLITE_PRIVATE int sqlite3BtreeNewDb(Btree *p);
#define BTREE_TEXT_ENCODING 5
#define BTREE_USER_VERSION 6
#define BTREE_INCR_VACUUM 7
+#define BTREE_APPLICATION_ID 8
+#define BTREE_DATA_VERSION 15 /* A virtual meta-value */
/*
-** Values that may be OR'd together to form the second argument of an
-** sqlite3BtreeCursorHints() call.
+** Kinds of hints that can be passed into the sqlite3BtreeCursorHint()
+** interface.
+**
+** BTREE_HINT_RANGE (arguments: Expr*, Mem*)
+**
+** The first argument is an Expr* (which is guaranteed to be constant for
+** the lifetime of the cursor) that defines constraints on which rows
+** might be fetched with this cursor. The Expr* tree may contain
+** TK_REGISTER nodes that refer to values stored in the array of registers
+** passed as the second parameter. In other words, if Expr.op==TK_REGISTER
+** then the value of the node is the value in Mem[pExpr.iTable]. Any
+** TK_COLUMN node in the expression tree refers to the Expr.iColumn-th
+** column of the b-tree of the cursor. The Expr tree will not contain
+** any function calls nor subqueries nor references to b-trees other than
+** the cursor being hinted.
+**
+** The design of the _RANGE hint is aid b-tree implementations that try
+** to prefetch content from remote machines - to provide those
+** implementations with limits on what needs to be prefetched and thereby
+** reduce network bandwidth.
+**
+** Note that BTREE_HINT_FLAGS with BTREE_BULKLOAD is the only hint used by
+** standard SQLite. The other hints are provided for extentions that use
+** the SQLite parser and code generator but substitute their own storage
+** engine.
*/
-#define BTREE_BULKLOAD 0x00000001
+#define BTREE_HINT_RANGE 0 /* Range constraints on queries */
+
+/*
+** Values that may be OR'd together to form the argument to the
+** BTREE_HINT_FLAGS hint for sqlite3BtreeCursorHint():
+**
+** The BTREE_BULKLOAD flag is set on index cursors when the index is going
+** to be filled with content that is already in sorted order.
+**
+** The BTREE_SEEK_EQ flag is set on cursors that will get OP_SeekGE or
+** OP_SeekLE opcodes for a range search, but where the range of entries
+** selected will all have the same key. In other words, the cursor will
+** be used only for equality key searches.
+**
+*/
+#define BTREE_BULKLOAD 0x00000001 /* Used to full index in sorted order */
+#define BTREE_SEEK_EQ 0x00000002 /* EQ seeks only - no range seeks */
+
+/*
+** Flags passed as the third argument to sqlite3BtreeCursor().
+**
+** For read-only cursors the wrFlag argument is always zero. For read-write
+** cursors it may be set to either (BTREE_WRCSR|BTREE_FORDELETE) or
+** (BTREE_WRCSR). If the BTREE_FORDELETE flag is set, then the cursor will
+** only be used by SQLite for the following:
+**
+** * to seek to and delete specific entries, and/or
+**
+** * to read values that will be used to create keys that other
+** BTREE_FORDELETE cursors will seek to and delete.
+*/
+#define BTREE_WRCSR 0x00000004 /* read-write cursor */
+#define BTREE_FORDELETE 0x00000008 /* Cursor is for seek/delete only */
SQLITE_PRIVATE int sqlite3BtreeCursor(
Btree*, /* BTree containing table to open */
@@ -8507,6 +10420,10 @@ SQLITE_PRIVATE int sqlite3BtreeCursor(
);
SQLITE_PRIVATE int sqlite3BtreeCursorSize(void);
SQLITE_PRIVATE void sqlite3BtreeCursorZero(BtCursor*);
+SQLITE_PRIVATE void sqlite3BtreeCursorHintFlags(BtCursor*, unsigned);
+#ifdef SQLITE_ENABLE_CURSOR_HINTS
+SQLITE_PRIVATE void sqlite3BtreeCursorHint(BtCursor*, int, ...);
+#endif
SQLITE_PRIVATE int sqlite3BtreeCloseCursor(BtCursor*);
SQLITE_PRIVATE int sqlite3BtreeMovetoUnpacked(
@@ -8516,8 +10433,9 @@ SQLITE_PRIVATE int sqlite3BtreeMovetoUnpacked(
int bias,
int *pRes
);
-SQLITE_PRIVATE int sqlite3BtreeCursorHasMoved(BtCursor*, int*);
-SQLITE_PRIVATE int sqlite3BtreeDelete(BtCursor*);
+SQLITE_PRIVATE int sqlite3BtreeCursorHasMoved(BtCursor*);
+SQLITE_PRIVATE int sqlite3BtreeCursorRestore(BtCursor*, int*);
+SQLITE_PRIVATE int sqlite3BtreeDelete(BtCursor*, int);
SQLITE_PRIVATE int sqlite3BtreeInsert(BtCursor*, const void *pKey, i64 nKey,
const void *pData, int nData,
int nZero, int bias, int seekResult);
@@ -8528,21 +10446,21 @@ 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 const void *sqlite3BtreeKeyFetch(BtCursor*, u32 *pAmt);
+SQLITE_PRIVATE const void *sqlite3BtreeDataFetch(BtCursor*, u32 *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 sqlite3BtreeIncrblobCursor(BtCursor *);
SQLITE_PRIVATE void sqlite3BtreeClearCursor(BtCursor *);
SQLITE_PRIVATE int sqlite3BtreeSetVersion(Btree *pBt, int iVersion);
-SQLITE_PRIVATE void sqlite3BtreeCursorHints(BtCursor *, unsigned int mask);
+SQLITE_PRIVATE int sqlite3BtreeCursorHasHint(BtCursor*, unsigned int mask);
+SQLITE_PRIVATE int sqlite3BtreeIsReadonly(Btree *pBt);
+SQLITE_PRIVATE int sqlite3HeaderSizeBtree(void);
#ifndef NDEBUG
SQLITE_PRIVATE int sqlite3BtreeCursorIsValid(BtCursor*);
@@ -8638,7 +10556,6 @@ 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;
@@ -8655,29 +10572,35 @@ struct VdbeOp {
int p1; /* First operand */
int p2; /* Second parameter (often the jump destination) */
int p3; /* The third parameter */
- union { /* fourth parameter */
+ union p4union { /* 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 */
+ sqlite3_context *pCtx; /* Used when p4type is P4_FUNCCTX */
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 */
+#ifdef SQLITE_ENABLE_CURSOR_HINTS
+ Expr *pExpr; /* Used when p4type is P4_EXPR */
+#endif
int (*xAdvance)(BtCursor *, int *);
} p4;
-#ifdef SQLITE_DEBUG
+#ifdef SQLITE_ENABLE_EXPLAIN_COMMENTS
char *zComment; /* Comment to improve readability */
#endif
#ifdef VDBE_PROFILE
- int cnt; /* Number of times this instruction was executed */
+ u32 cnt; /* Number of times this instruction was executed */
u64 cycles; /* Total time spent executing this instruction */
#endif
+#ifdef SQLITE_VDBE_COVERAGE
+ int iSrcLine; /* Source-code line that generated this opcode */
+#endif
};
typedef struct VdbeOp VdbeOp;
@@ -8716,7 +10639,7 @@ typedef struct VdbeOpList VdbeOpList;
#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_EXPR (-7) /* P4 is a pointer to an Expr tree */
#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 */
@@ -8727,16 +10650,13 @@ typedef struct VdbeOpList VdbeOpList;
#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() */
+#define P4_FUNCCTX (-20) /* P4 is a pointer to an sqlite3_context object */
-/* 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)
+/* Error message codes for OP_Halt */
+#define P5_ConstraintNotNull 1
+#define P5_ConstraintUnique 2
+#define P5_ConstraintCheck 3
+#define P5_ConstraintFK 4
/*
** The Vdbe.aColName array contains 5n Mem structures, where n is the
@@ -8772,190 +10692,202 @@ typedef struct VdbeOpList VdbeOpList;
/************** 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
-
+/* See the tool/mkopcodeh.tcl script for details */
+#define OP_Savepoint 1
+#define OP_AutoCommit 2
+#define OP_Transaction 3
+#define OP_SorterNext 4
+#define OP_PrevIfOpen 5
+#define OP_NextIfOpen 6
+#define OP_Prev 7
+#define OP_Next 8
+#define OP_Checkpoint 9
+#define OP_JournalMode 10
+#define OP_Vacuum 11
+#define OP_VFilter 12 /* synopsis: iplan=r[P3] zplan='P4' */
+#define OP_VUpdate 13 /* synopsis: data=r[P3@P2] */
+#define OP_Goto 14
+#define OP_Gosub 15
+#define OP_Return 16
+#define OP_InitCoroutine 17
+#define OP_EndCoroutine 18
+#define OP_Not 19 /* same as TK_NOT, synopsis: r[P2]= !r[P1] */
+#define OP_Yield 20
+#define OP_HaltIfNull 21 /* synopsis: if r[P3]=null halt */
+#define OP_Halt 22
+#define OP_Integer 23 /* synopsis: r[P2]=P1 */
+#define OP_Int64 24 /* synopsis: r[P2]=P4 */
+#define OP_String 25 /* synopsis: r[P2]='P4' (len=P1) */
+#define OP_Null 26 /* synopsis: r[P2..P3]=NULL */
+#define OP_SoftNull 27 /* synopsis: r[P1]=NULL */
+#define OP_Blob 28 /* synopsis: r[P2]=P4 (len=P1) */
+#define OP_Variable 29 /* synopsis: r[P2]=parameter(P1,P4) */
+#define OP_Move 30 /* synopsis: r[P2@P3]=r[P1@P3] */
+#define OP_Copy 31 /* synopsis: r[P2@P3+1]=r[P1@P3+1] */
+#define OP_SCopy 32 /* synopsis: r[P2]=r[P1] */
+#define OP_IntCopy 33 /* synopsis: r[P2]=r[P1] */
+#define OP_ResultRow 34 /* synopsis: output=r[P1@P2] */
+#define OP_CollSeq 35
+#define OP_Function0 36 /* synopsis: r[P3]=func(r[P2@P5]) */
+#define OP_Function 37 /* synopsis: r[P3]=func(r[P2@P5]) */
+#define OP_AddImm 38 /* synopsis: r[P1]=r[P1]+P2 */
+#define OP_MustBeInt 39
+#define OP_RealAffinity 40
+#define OP_Cast 41 /* synopsis: affinity(r[P1]) */
+#define OP_Permutation 42
+#define OP_Compare 43 /* synopsis: r[P1@P3] <-> r[P2@P3] */
+#define OP_Jump 44
+#define OP_Once 45
+#define OP_If 46
+#define OP_IfNot 47
+#define OP_Column 48 /* synopsis: r[P3]=PX */
+#define OP_Affinity 49 /* synopsis: affinity(r[P1@P2]) */
+#define OP_MakeRecord 50 /* synopsis: r[P3]=mkrec(r[P1@P2]) */
+#define OP_Count 51 /* synopsis: r[P2]=count() */
+#define OP_ReadCookie 52
+#define OP_SetCookie 53
+#define OP_ReopenIdx 54 /* synopsis: root=P2 iDb=P3 */
+#define OP_OpenRead 55 /* synopsis: root=P2 iDb=P3 */
+#define OP_OpenWrite 56 /* synopsis: root=P2 iDb=P3 */
+#define OP_OpenAutoindex 57 /* synopsis: nColumn=P2 */
+#define OP_OpenEphemeral 58 /* synopsis: nColumn=P2 */
+#define OP_SorterOpen 59
+#define OP_SequenceTest 60 /* synopsis: if( cursor[P1].ctr++ ) pc = P2 */
+#define OP_OpenPseudo 61 /* synopsis: P3 columns in r[P2] */
+#define OP_Close 62
+#define OP_ColumnsUsed 63
+#define OP_SeekLT 64 /* synopsis: key=r[P3@P4] */
+#define OP_SeekLE 65 /* synopsis: key=r[P3@P4] */
+#define OP_SeekGE 66 /* synopsis: key=r[P3@P4] */
+#define OP_SeekGT 67 /* synopsis: key=r[P3@P4] */
+#define OP_Seek 68 /* synopsis: intkey=r[P2] */
+#define OP_NoConflict 69 /* synopsis: key=r[P3@P4] */
+#define OP_NotFound 70 /* synopsis: key=r[P3@P4] */
+#define OP_Or 71 /* same as TK_OR, synopsis: r[P3]=(r[P1] || r[P2]) */
+#define OP_And 72 /* same as TK_AND, synopsis: r[P3]=(r[P1] && r[P2]) */
+#define OP_Found 73 /* synopsis: key=r[P3@P4] */
+#define OP_NotExists 74 /* synopsis: intkey=r[P3] */
+#define OP_Sequence 75 /* synopsis: r[P2]=cursor[P1].ctr++ */
+#define OP_IsNull 76 /* same as TK_ISNULL, synopsis: if r[P1]==NULL goto P2 */
+#define OP_NotNull 77 /* same as TK_NOTNULL, synopsis: if r[P1]!=NULL goto P2 */
+#define OP_Ne 78 /* same as TK_NE, synopsis: if r[P1]!=r[P3] goto P2 */
+#define OP_Eq 79 /* same as TK_EQ, synopsis: if r[P1]==r[P3] goto P2 */
+#define OP_Gt 80 /* same as TK_GT, synopsis: if r[P1]>r[P3] goto P2 */
+#define OP_Le 81 /* same as TK_LE, synopsis: if r[P1]<=r[P3] goto P2 */
+#define OP_Lt 82 /* same as TK_LT, synopsis: if r[P1]<r[P3] goto P2 */
+#define OP_Ge 83 /* same as TK_GE, synopsis: if r[P1]>=r[P3] goto P2 */
+#define OP_NewRowid 84 /* synopsis: r[P2]=rowid */
+#define OP_BitAnd 85 /* same as TK_BITAND, synopsis: r[P3]=r[P1]&r[P2] */
+#define OP_BitOr 86 /* same as TK_BITOR, synopsis: r[P3]=r[P1]|r[P2] */
+#define OP_ShiftLeft 87 /* same as TK_LSHIFT, synopsis: r[P3]=r[P2]<<r[P1] */
+#define OP_ShiftRight 88 /* same as TK_RSHIFT, synopsis: r[P3]=r[P2]>>r[P1] */
+#define OP_Add 89 /* same as TK_PLUS, synopsis: r[P3]=r[P1]+r[P2] */
+#define OP_Subtract 90 /* same as TK_MINUS, synopsis: r[P3]=r[P2]-r[P1] */
+#define OP_Multiply 91 /* same as TK_STAR, synopsis: r[P3]=r[P1]*r[P2] */
+#define OP_Divide 92 /* same as TK_SLASH, synopsis: r[P3]=r[P2]/r[P1] */
+#define OP_Remainder 93 /* same as TK_REM, synopsis: r[P3]=r[P2]%r[P1] */
+#define OP_Concat 94 /* same as TK_CONCAT, synopsis: r[P3]=r[P2]+r[P1] */
+#define OP_Insert 95 /* synopsis: intkey=r[P3] data=r[P2] */
+#define OP_BitNot 96 /* same as TK_BITNOT, synopsis: r[P1]= ~r[P1] */
+#define OP_String8 97 /* same as TK_STRING, synopsis: r[P2]='P4' */
+#define OP_InsertInt 98 /* synopsis: intkey=P3 data=r[P2] */
+#define OP_Delete 99
+#define OP_ResetCount 100
+#define OP_SorterCompare 101 /* synopsis: if key(P1)!=trim(r[P3],P4) goto P2 */
+#define OP_SorterData 102 /* synopsis: r[P2]=data */
+#define OP_RowKey 103 /* synopsis: r[P2]=key */
+#define OP_RowData 104 /* synopsis: r[P2]=data */
+#define OP_Rowid 105 /* synopsis: r[P2]=rowid */
+#define OP_NullRow 106
+#define OP_Last 107
+#define OP_SorterSort 108
+#define OP_Sort 109
+#define OP_Rewind 110
+#define OP_SorterInsert 111
+#define OP_IdxInsert 112 /* synopsis: key=r[P2] */
+#define OP_IdxDelete 113 /* synopsis: key=r[P2@P3] */
+#define OP_IdxRowid 114 /* synopsis: r[P2]=rowid */
+#define OP_IdxLE 115 /* synopsis: key=r[P3@P4] */
+#define OP_IdxGT 116 /* synopsis: key=r[P3@P4] */
+#define OP_IdxLT 117 /* synopsis: key=r[P3@P4] */
+#define OP_IdxGE 118 /* synopsis: key=r[P3@P4] */
+#define OP_Destroy 119
+#define OP_Clear 120
+#define OP_ResetSorter 121
+#define OP_CreateIndex 122 /* synopsis: r[P2]=root iDb=P1 */
+#define OP_CreateTable 123 /* synopsis: r[P2]=root iDb=P1 */
+#define OP_ParseSchema 124
+#define OP_LoadAnalysis 125
+#define OP_DropTable 126
+#define OP_DropIndex 127
+#define OP_DropTrigger 128
+#define OP_IntegrityCk 129
+#define OP_RowSetAdd 130 /* synopsis: rowset(P1)=r[P2] */
+#define OP_RowSetRead 131 /* synopsis: r[P3]=rowset(P1) */
+#define OP_RowSetTest 132 /* synopsis: if r[P3] in rowset(P1) goto P2 */
+#define OP_Real 133 /* same as TK_FLOAT, synopsis: r[P2]=P4 */
+#define OP_Program 134
+#define OP_Param 135
+#define OP_FkCounter 136 /* synopsis: fkctr[P1]+=P2 */
+#define OP_FkIfZero 137 /* synopsis: if fkctr[P1]==0 goto P2 */
+#define OP_MemMax 138 /* synopsis: r[P1]=max(r[P1],r[P2]) */
+#define OP_IfPos 139 /* synopsis: if r[P1]>0 then r[P1]-=P3, goto P2 */
+#define OP_SetIfNotPos 140 /* synopsis: if r[P1]<=0 then r[P2]=P3 */
+#define OP_IfNotZero 141 /* synopsis: if r[P1]!=0 then r[P1]-=P3, goto P2 */
+#define OP_DecrJumpZero 142 /* synopsis: if (--r[P1])==0 goto P2 */
+#define OP_JumpZeroIncr 143 /* synopsis: if (r[P1]++)==0 ) goto P2 */
+#define OP_AggStep0 144 /* synopsis: accum=r[P3] step(r[P2@P5]) */
+#define OP_AggStep 145 /* synopsis: accum=r[P3] step(r[P2@P5]) */
+#define OP_AggFinal 146 /* synopsis: accum=r[P1] N=P2 */
+#define OP_IncrVacuum 147
+#define OP_Expire 148
+#define OP_TableLock 149 /* synopsis: iDb=P1 root=P2 write=P3 */
+#define OP_VBegin 150
+#define OP_VCreate 151
+#define OP_VDestroy 152
+#define OP_VOpen 153
+#define OP_VColumn 154 /* synopsis: r[P3]=vcolumn(P2) */
+#define OP_VNext 155
+#define OP_VRename 156
+#define OP_Pagecount 157
+#define OP_MaxPgcnt 158
+#define OP_Init 159 /* synopsis: Start at P2 */
+#define OP_CursorHint 160
+#define OP_Noop 161
+#define OP_Explain 162
/* 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_IN1 0x0002 /* in1: P1 is an input */
+#define OPFLG_IN2 0x0004 /* in2: P2 is an input */
+#define OPFLG_IN3 0x0008 /* in3: P3 is an input */
+#define OPFLG_OUT2 0x0010 /* out2: P2 is an output */
+#define OPFLG_OUT3 0x0020 /* 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,}
+/* 0 */ 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01,\
+/* 8 */ 0x01, 0x00, 0x10, 0x00, 0x01, 0x00, 0x01, 0x01,\
+/* 16 */ 0x02, 0x01, 0x02, 0x12, 0x03, 0x08, 0x00, 0x10,\
+/* 24 */ 0x10, 0x10, 0x10, 0x00, 0x10, 0x10, 0x00, 0x00,\
+/* 32 */ 0x10, 0x10, 0x00, 0x00, 0x00, 0x00, 0x02, 0x03,\
+/* 40 */ 0x02, 0x02, 0x00, 0x00, 0x01, 0x01, 0x03, 0x03,\
+/* 48 */ 0x00, 0x00, 0x00, 0x10, 0x10, 0x08, 0x00, 0x00,\
+/* 56 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\
+/* 64 */ 0x09, 0x09, 0x09, 0x09, 0x04, 0x09, 0x09, 0x26,\
+/* 72 */ 0x26, 0x09, 0x09, 0x10, 0x03, 0x03, 0x0b, 0x0b,\
+/* 80 */ 0x0b, 0x0b, 0x0b, 0x0b, 0x10, 0x26, 0x26, 0x26,\
+/* 88 */ 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x00,\
+/* 96 */ 0x12, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\
+/* 104 */ 0x00, 0x10, 0x00, 0x01, 0x01, 0x01, 0x01, 0x04,\
+/* 112 */ 0x04, 0x00, 0x10, 0x01, 0x01, 0x01, 0x01, 0x10,\
+/* 120 */ 0x00, 0x00, 0x10, 0x10, 0x00, 0x00, 0x00, 0x00,\
+/* 128 */ 0x00, 0x00, 0x06, 0x23, 0x0b, 0x10, 0x01, 0x10,\
+/* 136 */ 0x00, 0x01, 0x04, 0x03, 0x06, 0x03, 0x03, 0x03,\
+/* 144 */ 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,\
+/* 152 */ 0x00, 0x00, 0x00, 0x01, 0x00, 0x10, 0x10, 0x01,\
+/* 160 */ 0x00, 0x00, 0x00,}
/************** End of opcodes.h *********************************************/
/************** Continuing where we left off in vdbe.h ***********************/
@@ -8964,22 +10896,29 @@ typedef struct VdbeOpList VdbeOpList;
** 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 Vdbe *sqlite3VdbeCreate(Parse*);
SQLITE_PRIVATE int sqlite3VdbeAddOp0(Vdbe*,int);
SQLITE_PRIVATE int sqlite3VdbeAddOp1(Vdbe*,int,int);
SQLITE_PRIVATE int sqlite3VdbeAddOp2(Vdbe*,int,int,int);
+SQLITE_PRIVATE int sqlite3VdbeGoto(Vdbe*,int);
+SQLITE_PRIVATE int sqlite3VdbeLoadString(Vdbe*,int,const char*);
+SQLITE_PRIVATE void sqlite3VdbeMultiLoad(Vdbe*,int,const char*,...);
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 sqlite3VdbeAddOp4Dup8(Vdbe*,int,int,int,int,const u8*,int);
SQLITE_PRIVATE int sqlite3VdbeAddOp4Int(Vdbe*,int,int,int,int,int);
-SQLITE_PRIVATE int sqlite3VdbeAddOpList(Vdbe*, int nOp, VdbeOpList const *aOp);
+SQLITE_PRIVATE int sqlite3VdbeAddOpList(Vdbe*, int nOp, VdbeOpList const *aOp, int iLineno);
SQLITE_PRIVATE void sqlite3VdbeAddParseSchemaOp(Vdbe*,int,char*);
+SQLITE_PRIVATE void sqlite3VdbeChangeOpcode(Vdbe*, u32 addr, u8);
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 int sqlite3VdbeDeletePriorOpcode(Vdbe*, u8 op);
SQLITE_PRIVATE void sqlite3VdbeChangeP4(Vdbe*, int addr, const char *zP4, int N);
+SQLITE_PRIVATE void sqlite3VdbeSetP4KeyInfo(Parse*, Index*);
SQLITE_PRIVATE void sqlite3VdbeUsesBtree(Vdbe*, int);
SQLITE_PRIVATE VdbeOp *sqlite3VdbeGetOp(Vdbe*, int);
SQLITE_PRIVATE int sqlite3VdbeMakeLabel(Vdbe*);
@@ -8992,7 +10931,6 @@ 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*);
@@ -9004,29 +10942,89 @@ 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 sqlite3_value *sqlite3VdbeGetBoundValue(Vdbe*, int, u8);
SQLITE_PRIVATE void sqlite3VdbeSetVarmask(Vdbe*, int);
#ifndef SQLITE_OMIT_TRACE
SQLITE_PRIVATE char *sqlite3VdbeExpandSql(Vdbe*, const char*);
#endif
+SQLITE_PRIVATE int sqlite3MemCompare(const Mem*, const Mem*, const CollSeq*);
SQLITE_PRIVATE void sqlite3VdbeRecordUnpack(KeyInfo*,int,const void*,UnpackedRecord*);
SQLITE_PRIVATE int sqlite3VdbeRecordCompare(int,const void*,UnpackedRecord*);
+SQLITE_PRIVATE int sqlite3VdbeRecordCompareWithSkip(int, const void *, UnpackedRecord *, int);
SQLITE_PRIVATE UnpackedRecord *sqlite3VdbeAllocUnpackedRecord(KeyInfo *, char *, int, char **);
+typedef int (*RecordCompare)(int,const void*,UnpackedRecord*);
+SQLITE_PRIVATE RecordCompare sqlite3VdbeFindCompare(UnpackedRecord*);
+
#ifndef SQLITE_OMIT_TRIGGER
SQLITE_PRIVATE void sqlite3VdbeLinkSubProgram(Vdbe *, SubProgram *);
#endif
-
-#ifndef NDEBUG
+/* Use SQLITE_ENABLE_COMMENTS to enable generation of extra comments on
+** each VDBE opcode.
+**
+** Use the SQLITE_ENABLE_MODULE_COMMENTS macro to see some extra no-op
+** comments in VDBE programs that show key decision points in the code
+** generator.
+*/
+#ifdef SQLITE_ENABLE_EXPLAIN_COMMENTS
SQLITE_PRIVATE void sqlite3VdbeComment(Vdbe*, const char*, ...);
# define VdbeComment(X) sqlite3VdbeComment X
SQLITE_PRIVATE void sqlite3VdbeNoopComment(Vdbe*, const char*, ...);
# define VdbeNoopComment(X) sqlite3VdbeNoopComment X
+# ifdef SQLITE_ENABLE_MODULE_COMMENTS
+# define VdbeModuleComment(X) sqlite3VdbeNoopComment X
+# else
+# define VdbeModuleComment(X)
+# endif
#else
# define VdbeComment(X)
# define VdbeNoopComment(X)
+# define VdbeModuleComment(X)
+#endif
+
+/*
+** The VdbeCoverage macros are used to set a coverage testing point
+** for VDBE branch instructions. The coverage testing points are line
+** numbers in the sqlite3.c source file. VDBE branch coverage testing
+** only works with an amalagmation build. That's ok since a VDBE branch
+** coverage build designed for testing the test suite only. No application
+** should ever ship with VDBE branch coverage measuring turned on.
+**
+** VdbeCoverage(v) // Mark the previously coded instruction
+** // as a branch
+**
+** VdbeCoverageIf(v, conditional) // Mark previous if conditional true
+**
+** VdbeCoverageAlwaysTaken(v) // Previous branch is always taken
+**
+** VdbeCoverageNeverTaken(v) // Previous branch is never taken
+**
+** Every VDBE branch operation must be tagged with one of the macros above.
+** If not, then when "make test" is run with -DSQLITE_VDBE_COVERAGE and
+** -DSQLITE_DEBUG then an ALWAYS() will fail in the vdbeTakeBranch()
+** routine in vdbe.c, alerting the developer to the missed tag.
+*/
+#ifdef SQLITE_VDBE_COVERAGE
+SQLITE_PRIVATE void sqlite3VdbeSetLineNumber(Vdbe*,int);
+# define VdbeCoverage(v) sqlite3VdbeSetLineNumber(v,__LINE__)
+# define VdbeCoverageIf(v,x) if(x)sqlite3VdbeSetLineNumber(v,__LINE__)
+# define VdbeCoverageAlwaysTaken(v) sqlite3VdbeSetLineNumber(v,2);
+# define VdbeCoverageNeverTaken(v) sqlite3VdbeSetLineNumber(v,1);
+# define VDBE_OFFSET_LINENO(x) (__LINE__+x)
+#else
+# define VdbeCoverage(v)
+# define VdbeCoverageIf(v,x)
+# define VdbeCoverageAlwaysTaken(v)
+# define VdbeCoverageNeverTaken(v)
+# define VDBE_OFFSET_LINENO(x) 0
+#endif
+
+#ifdef SQLITE_ENABLE_STMT_SCANSTATUS
+SQLITE_PRIVATE void sqlite3VdbeScanStatus(Vdbe*, int, int, int, LogEst, const char*);
+#else
+# define sqlite3VdbeScanStatus(a,b,c,d,e)
#endif
#endif
@@ -9116,6 +11114,24 @@ typedef struct PgHdr DbPage;
#define PAGER_JOURNALMODE_WAL 5 /* Use write-ahead logging */
/*
+** Flags that make up the mask passed to sqlite3PagerGet().
+*/
+#define PAGER_GET_NOCONTENT 0x01 /* Do not load data from disk */
+#define PAGER_GET_READONLY 0x02 /* Read-only page is acceptable */
+
+/*
+** Flags for sqlite3PagerSetFlags()
+*/
+#define PAGER_SYNCHRONOUS_OFF 0x01 /* PRAGMA synchronous=OFF */
+#define PAGER_SYNCHRONOUS_NORMAL 0x02 /* PRAGMA synchronous=NORMAL */
+#define PAGER_SYNCHRONOUS_FULL 0x03 /* PRAGMA synchronous=FULL */
+#define PAGER_SYNCHRONOUS_MASK 0x03 /* Mask for three values above */
+#define PAGER_FULLFSYNC 0x04 /* PRAGMA fullfsync=ON */
+#define PAGER_CKPT_FULLFSYNC 0x08 /* PRAGMA checkpoint_fullfsync=ON */
+#define PAGER_CACHESPILL 0x10 /* PRAGMA cache_spill=ON */
+#define PAGER_FLAGS_MASK 0x1c /* All above except SYNCHRONOUS */
+
+/*
** 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.
@@ -9137,23 +11153,29 @@ 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);
+#ifdef SQLITE_HAS_CODEC
+SQLITE_PRIVATE void sqlite3PagerAlignReserve(Pager*,Pager*);
+#endif
SQLITE_PRIVATE int sqlite3PagerMaxPageCount(Pager*, int);
SQLITE_PRIVATE void sqlite3PagerSetCachesize(Pager*, int);
+SQLITE_PRIVATE int sqlite3PagerSetSpillsize(Pager*, int);
+SQLITE_PRIVATE void sqlite3PagerSetMmapLimit(Pager *, sqlite3_int64);
SQLITE_PRIVATE void sqlite3PagerShrink(Pager*);
-SQLITE_PRIVATE void sqlite3PagerSetSafetyLevel(Pager*,int,int,int);
+SQLITE_PRIVATE void sqlite3PagerSetFlags(Pager*,unsigned);
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*);
+SQLITE_PRIVATE int sqlite3PagerFlush(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 int sqlite3PagerGet(Pager *pPager, Pgno pgno, DbPage **ppPage, int clrFlag);
SQLITE_PRIVATE DbPage *sqlite3PagerLookup(Pager *pPager, Pgno pgno);
SQLITE_PRIVATE void sqlite3PagerRef(DbPage*);
SQLITE_PRIVATE void sqlite3PagerUnref(DbPage*);
+SQLITE_PRIVATE void sqlite3PagerUnrefNotNull(DbPage*);
/* Operations on page references. */
SQLITE_PRIVATE int sqlite3PagerWrite(DbPage*);
@@ -9168,7 +11190,7 @@ 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 sqlite3PagerSync(Pager *pPager, const char *zMaster);
SQLITE_PRIVATE int sqlite3PagerCommitPhaseTwo(Pager*);
SQLITE_PRIVATE int sqlite3PagerRollback(Pager*);
SQLITE_PRIVATE int sqlite3PagerOpenSavepoint(Pager *pPager, int n);
@@ -9181,6 +11203,10 @@ 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);
+# ifdef SQLITE_ENABLE_SNAPSHOT
+SQLITE_PRIVATE int sqlite3PagerSnapshotGet(Pager *pPager, sqlite3_snapshot **ppSnapshot);
+SQLITE_PRIVATE int sqlite3PagerSnapshotOpen(Pager *pPager, sqlite3_snapshot *pSnapshot);
+# endif
#endif
#ifdef SQLITE_ENABLE_ZIPVFS
@@ -9189,11 +11215,15 @@ SQLITE_PRIVATE int sqlite3PagerWalFramesize(Pager *pPager);
/* Functions used to query pager state and configuration. */
SQLITE_PRIVATE u8 sqlite3PagerIsreadonly(Pager*);
-SQLITE_PRIVATE int sqlite3PagerRefcount(Pager*);
+SQLITE_PRIVATE u32 sqlite3PagerDataVersion(Pager*);
+#ifdef SQLITE_DEBUG
+SQLITE_PRIVATE int sqlite3PagerRefcount(Pager*);
+#endif
SQLITE_PRIVATE int sqlite3PagerMemUsed(Pager*);
SQLITE_PRIVATE const char *sqlite3PagerFilename(Pager*, int);
-SQLITE_PRIVATE const sqlite3_vfs *sqlite3PagerVfs(Pager*);
+SQLITE_PRIVATE sqlite3_vfs *sqlite3PagerVfs(Pager*);
SQLITE_PRIVATE sqlite3_file *sqlite3PagerFile(Pager*);
+SQLITE_PRIVATE sqlite3_file *sqlite3PagerJrnlFile(Pager*);
SQLITE_PRIVATE const char *sqlite3PagerJournalname(Pager*);
SQLITE_PRIVATE int sqlite3PagerNosync(Pager*);
SQLITE_PRIVATE void *sqlite3PagerTempSpace(Pager*);
@@ -9205,6 +11235,8 @@ SQLITE_PRIVATE int sqlite3SectorSize(sqlite3_file *);
/* Functions used to truncate the database file. */
SQLITE_PRIVATE void sqlite3PagerTruncateImage(Pager*,Pgno);
+SQLITE_PRIVATE void sqlite3PagerRekey(DbPage*, Pgno, u16);
+
#if defined(SQLITE_HAS_CODEC) && !defined(SQLITE_OMIT_WAL)
SQLITE_PRIVATE void *sqlite3PagerCodec(DbPage *);
#endif
@@ -9278,12 +11310,14 @@ struct PgHdr {
};
/* 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 */
+#define PGHDR_CLEAN 0x001 /* Page not on the PCache.pDirty list */
+#define PGHDR_DIRTY 0x002 /* Page is on the PCache.pDirty list */
+#define PGHDR_WRITEABLE 0x004 /* Journaled and ready to modify */
+#define PGHDR_NEED_SYNC 0x008 /* Fsync the rollback journal before
+ ** writing this page to the database */
+#define PGHDR_NEED_READ 0x010 /* Content is unread */
+#define PGHDR_DONT_WRITE 0x020 /* Do not write content to disk */
+#define PGHDR_MMAP 0x040 /* This is an mmap page object */
/* Initialize and shutdown the page cache subsystem */
SQLITE_PRIVATE int sqlite3PcacheInitialize(void);
@@ -9298,7 +11332,7 @@ SQLITE_PRIVATE void sqlite3PCacheBufferSetup(void *, int sz, int n);
** Under memory stress, invoke xStress to try to make pages clean.
** Only clean and unpinned pages can be reclaimed.
*/
-SQLITE_PRIVATE void sqlite3PcacheOpen(
+SQLITE_PRIVATE int sqlite3PcacheOpen(
int szPage, /* Size of every page */
int szExtra, /* Extra space associated with each page */
int bPurgeable, /* True if pages are on backing store */
@@ -9308,7 +11342,7 @@ SQLITE_PRIVATE void sqlite3PcacheOpen(
);
/* Modify the page-size after the cache has been created. */
-SQLITE_PRIVATE void sqlite3PcacheSetPageSize(PCache *, int);
+SQLITE_PRIVATE int sqlite3PcacheSetPageSize(PCache *, int);
/* Return the size in bytes of a PCache object. Used to preallocate
** storage space.
@@ -9318,7 +11352,9 @@ 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 sqlite3_pcache_page *sqlite3PcacheFetch(PCache*, Pgno, int createFlag);
+SQLITE_PRIVATE int sqlite3PcacheFetchStress(PCache*, Pgno, sqlite3_pcache_page**);
+SQLITE_PRIVATE PgHdr *sqlite3PcacheFetchFinish(PCache*, Pgno, sqlite3_pcache_page *pPage);
SQLITE_PRIVATE void sqlite3PcacheRelease(PgHdr*);
SQLITE_PRIVATE void sqlite3PcacheDrop(PgHdr*); /* Remove page from cache */
@@ -9374,6 +11410,13 @@ SQLITE_PRIVATE void sqlite3PcacheSetCachesize(PCache *, int);
SQLITE_PRIVATE int sqlite3PcacheGetCachesize(PCache *);
#endif
+/* Set or get the suggested spill-size for the specified pager-cache.
+**
+** The spill-size is the minimum number of pages in cache before the cache
+** will attempt to spill dirty pages by calling xStress.
+*/
+SQLITE_PRIVATE int sqlite3PcacheSetSpillsize(PCache *, int);
+
/* Free up as much memory as possible from the page cache */
SQLITE_PRIVATE void sqlite3PcacheShrink(PCache*);
@@ -9388,6 +11431,10 @@ SQLITE_PRIVATE void sqlite3PcacheStats(int*,int*,int*,int*);
SQLITE_PRIVATE void sqlite3PCacheSetDefault(void);
+/* Return the header size */
+SQLITE_PRIVATE int sqlite3HeaderSizePcache(void);
+SQLITE_PRIVATE int sqlite3HeaderSizePcache1(void);
+
#endif /* _PCACHE_H_ */
/************** End of pcache.h **********************************************/
@@ -9418,91 +11465,71 @@ SQLITE_PRIVATE void sqlite3PCacheSetDefault(void);
#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.
+** Attempt to automatically detect the operating system and setup the
+** necessary pre-processor macros for it.
*/
-#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
-
+/************** Include os_setup.h in the middle of os.h *********************/
+/************** Begin file os_setup.h ****************************************/
/*
-** Determine if we are dealing with Windows NT.
+** 2013 November 25
**
-** We ought to be able to determine if we are compiling for win98 or winNT
-** using the _WIN32_WINNT macro as follows:
+** The author disclaims copyright to this source code. In place of
+** a legal notice, here is a blessing:
**
-** #if defined(_WIN32_WINNT)
-** # define SQLITE_OS_WINNT 1
-** #else
-** # define SQLITE_OS_WINNT 0
-** #endif
+** 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.
+**
+******************************************************************************
**
-** 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.
+** This file contains pre-processor directives related to operating system
+** detection and/or setup.
*/
-#if SQLITE_OS_WIN && !defined(SQLITE_OS_WINNT)
-# define SQLITE_OS_WINNT 1
-#endif
+#ifndef _OS_SETUP_H_
+#define _OS_SETUP_H_
/*
-** Determine if we are dealing with WindowsCE - which has a much
-** reduced API.
+** 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 three will be 1. The other two will be 0.
*/
-#if defined(_WIN32_WCE)
-# define SQLITE_OS_WINCE 1
+#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
-# define SQLITE_OS_WINCE 0
+# ifndef SQLITE_OS_WIN
+# define SQLITE_OS_WIN 0
+# endif
#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
+#endif /* _OS_SETUP_H_ */
-/*
-** 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
+/************** End of os_setup.h ********************************************/
+/************** Continuing where we left off in os.h *************************/
/* If the SET_FULLSYNC macro is not defined above, then make it
** a no-op
@@ -9598,7 +11625,7 @@ SQLITE_PRIVATE void sqlite3PCacheSetDefault(void);
** shared locks begins at SHARED_FIRST.
**
** The same locking strategy and
-** byte ranges are used for Unix. This leaves open the possiblity of having
+** byte ranges are used for Unix. This leaves open the possibility 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
@@ -9656,6 +11683,8 @@ 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);
+SQLITE_PRIVATE int sqlite3OsFetch(sqlite3_file *id, i64, int, void **);
+SQLITE_PRIVATE int sqlite3OsUnfetch(sqlite3_file *, i64, void *);
/*
@@ -9715,7 +11744,7 @@ SQLITE_PRIVATE int sqlite3OsCloseFree(sqlite3_file *);
** 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
+** mutexes implementation cannot be overridden
** at start-time.
**
** SQLITE_MUTEX_NOOP For single-threaded applications. No
@@ -9773,7 +11802,6 @@ SQLITE_PRIVATE int sqlite3OsCloseFree(sqlite3_file *);
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) */
};
@@ -9805,7 +11833,7 @@ struct Schema {
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 */
+ u16 schemaFlags; /* Flags associated with this schema */
int cache_size; /* Number of pages to use in the cache */
};
@@ -9813,10 +11841,10 @@ struct Schema {
** 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)
+#define DbHasProperty(D,I,P) (((D)->aDb[I].pSchema->schemaFlags&(P))==(P))
+#define DbHasAnyProperty(D,I,P) (((D)->aDb[I].pSchema->schemaFlags&(P))!=0)
+#define DbSetProperty(D,I,P) (D)->aDb[I].pSchema->schemaFlags|=(P)
+#define DbClearProperty(D,I,P) (D)->aDb[I].pSchema->schemaFlags&=~(P)
/*
** Allowed values for the DB.pSchema->flags field.
@@ -9836,7 +11864,7 @@ struct Schema {
** 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)
+#define SQLITE_N_LIMIT (SQLITE_LIMIT_WORKER_THREADS+1)
/*
** Lookaside malloc is a set of fixed-size buffers that can be used
@@ -9883,6 +11911,45 @@ struct FuncDefHash {
FuncDef *a[23]; /* Hash table for functions */
};
+#ifdef SQLITE_USER_AUTHENTICATION
+/*
+** Information held in the "sqlite3" database connection object and used
+** to manage user authentication.
+*/
+typedef struct sqlite3_userauth sqlite3_userauth;
+struct sqlite3_userauth {
+ u8 authLevel; /* Current authentication level */
+ int nAuthPW; /* Size of the zAuthPW in bytes */
+ char *zAuthPW; /* Password used to authenticate */
+ char *zAuthUser; /* User name used to authenticate */
+};
+
+/* Allowed values for sqlite3_userauth.authLevel */
+#define UAUTH_Unknown 0 /* Authentication not yet checked */
+#define UAUTH_Fail 1 /* User authentication failed */
+#define UAUTH_User 2 /* Authenticated as a normal user */
+#define UAUTH_Admin 3 /* Authenticated as an administrator */
+
+/* Functions used only by user authorization logic */
+SQLITE_PRIVATE int sqlite3UserAuthTable(const char*);
+SQLITE_PRIVATE int sqlite3UserAuthCheckLogin(sqlite3*,const char*,u8*);
+SQLITE_PRIVATE void sqlite3UserAuthInit(sqlite3*);
+SQLITE_PRIVATE void sqlite3CryptFunc(sqlite3_context*,int,sqlite3_value**);
+
+#endif /* SQLITE_USER_AUTHENTICATION */
+
+/*
+** typedef for the authorization callback function.
+*/
+#ifdef SQLITE_USER_AUTHENTICATION
+ typedef int (*sqlite3_xauth)(void*,int,const char*,const char*,const char*,
+ const char*, const char*);
+#else
+ typedef int (*sqlite3_xauth)(void*,int,const char*,const char*,const char*,
+ const char*);
+#endif
+
+
/*
** Each database connection is an instance of the following structure.
*/
@@ -9895,10 +11962,12 @@ struct sqlite3 {
int nDb; /* Number of backends currently in use */
int flags; /* Miscellaneous flags. See below */
i64 lastRowid; /* ROWID of most recent insert (see above) */
+ i64 szMmap; /* Default mmap_size setting */
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 enc; /* Text encoding */
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 */
@@ -9912,15 +11981,19 @@ struct sqlite3 {
int nChange; /* Value returned by sqlite3_changes() */
int nTotalChange; /* Value returned by sqlite3_total_changes() */
int aLimit[SQLITE_N_LIMIT]; /* Limits */
+ int nMaxSorterMmap; /* Maximum size of regions mapped by sorter */
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 */
+ u8 imposterTable; /* Building an imposter table */
} 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 nVdbeActive; /* Number of VDBEs currently running */
+ int nVdbeRead; /* Number of active VDBEs that read or write */
+ int nVdbeWrite; /* Number of active VDBEs that read and write */
+ int nVdbeExec; /* Number of nested calls to VdbeExec() */
+ int nVDestroy; /* Number of active OP_VDestroy operations */
int nExtension; /* Number of loaded extensions */
void **aExtension; /* Array of shared library handles */
void (*xTrace)(void*,const char*); /* Trace function */
@@ -9941,22 +12014,19 @@ struct sqlite3 {
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 */
+ sqlite3_xauth xAuth; /* 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 */
+ unsigned nProgressOps; /* Number of opcodes for progress callback */
#endif
#ifndef SQLITE_OMIT_VIRTUALTABLE
int nVTrans; /* Allocated size of aVTrans */
@@ -9974,8 +12044,8 @@ struct sqlite3 {
int nSavepoint; /* Number of non-transaction savepoints */
int nStatement; /* Number of nested statement-transactions */
i64 nDeferredCons; /* Net deferred constraints this transaction. */
+ i64 nDeferredImmCons; /* Net deferred immediate constraints */
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.
@@ -9993,42 +12063,53 @@ struct sqlite3 {
void (*xUnlockNotify)(void **, int); /* Unlock notify callback */
sqlite3 *pNextBlocked; /* Next in list of all blocked connections */
#endif
+#ifdef SQLITE_USER_AUTHENTICATION
+ sqlite3_userauth auth; /* User authentication information */
+#endif
};
/*
** A macro to discover the encoding of a database.
*/
-#define ENC(db) ((db)->aDb[0].pSchema->enc)
+#define SCHEMA_ENC(db) ((db)->aDb[0].pSchema->enc)
+#define ENC(db) ((db)->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, */
+#define SQLITE_FullFSync 0x00000004 /* Use full fsync on the backend */
+#define SQLITE_CkptFullFSync 0x00000008 /* Use full fsync for checkpoint */
+#define SQLITE_CacheSpill 0x00000010 /* OK to spill pager cache */
+#define SQLITE_FullColNames 0x00000020 /* Show full column names on SELECT */
+#define SQLITE_ShortColNames 0x00000040 /* Show short columns names */
+#define SQLITE_CountRows 0x00000080 /* 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 */
+#define SQLITE_NullCallback 0x00000100 /* 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 */
+#define SQLITE_SqlTrace 0x00000200 /* Debug print SQL as it executes */
+#define SQLITE_VdbeListing 0x00000400 /* Debug listings of VDBE programs */
+#define SQLITE_WriteSchema 0x00000800 /* OK to update SQLITE_MASTER */
+#define SQLITE_VdbeAddopTrace 0x00001000 /* Trace sqlite3VdbeAddOp() calls */
+#define SQLITE_IgnoreChecks 0x00002000 /* Do not enforce check constraints */
+#define SQLITE_ReadUncommitted 0x0004000 /* For shared-cache mode */
+#define SQLITE_LegacyFileFmt 0x00008000 /* Create new databases in format 1 */
+#define SQLITE_RecoveryMode 0x00010000 /* Ignore schema errors */
+#define SQLITE_ReverseOrder 0x00020000 /* Reverse unordered SELECTs */
+#define SQLITE_RecTriggers 0x00040000 /* Enable recursive triggers */
+#define SQLITE_ForeignKeys 0x00080000 /* Enforce foreign key constraints */
+#define SQLITE_AutoIndex 0x00100000 /* Enable automatic indexes */
+#define SQLITE_PreferBuiltin 0x00200000 /* Preference to built-in funcs */
+#define SQLITE_LoadExtension 0x00400000 /* Enable load_extension */
+#define SQLITE_EnableTrigger 0x00800000 /* True to enable triggers */
+#define SQLITE_DeferFKs 0x01000000 /* Defer all FK constraints */
+#define SQLITE_QueryOnly 0x02000000 /* Disable database changes */
+#define SQLITE_VdbeEQP 0x04000000 /* Debug EXPLAIN QUERY PLAN */
+#define SQLITE_Vacuum 0x08000000 /* Currently in a VACUUM */
+#define SQLITE_CellSizeCk 0x10000000 /* Check btree cell sizes on load */
+
/*
** Bits of the sqlite3.dbOptFlags field that are used by the
@@ -10039,11 +12120,15 @@ struct sqlite3 {
#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 */
+/* not used 0x0010 // Was: SQLITE_IdxRealAsInt */
#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_Transitive 0x0200 /* Transitive constraints */
+#define SQLITE_OmitNoopJoin 0x0400 /* Omit unused tables in joins */
+#define SQLITE_Stat34 0x0800 /* Use STAT3 or STAT4 data */
+#define SQLITE_CursorHints 0x2000 /* Add OP_CursorHint opcodes */
#define SQLITE_AllOpts 0xffff /* All optimizations */
/*
@@ -10058,6 +12143,12 @@ struct sqlite3 {
#endif
/*
+** Return true if it OK to factor constant expressions into the initialization
+** code. The argument is a Parse object for the code generator.
+*/
+#define ConstFactorOk(P) ((P)->okConstFactor)
+
+/*
** 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.
@@ -10077,8 +12168,7 @@ struct sqlite3 {
*/
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_* */
+ u16 funcFlags; /* 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 */
@@ -10111,17 +12201,24 @@ struct FuncDestructor {
/*
** Possible values for FuncDef.flags. Note that the _LENGTH and _TYPEOF
-** values must correspond to OPFLAG_LENGTHARG and OPFLAG_TYPEOFARG. There
+** values must correspond to OPFLAG_LENGTHARG and OPFLAG_TYPEOFARG. And
+** SQLITE_FUNC_CONSTANT must be the same as SQLITE_DETERMINISTIC. 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 */
+#define SQLITE_FUNC_ENCMASK 0x0003 /* SQLITE_UTF8, SQLITE_UTF16BE or UTF16LE */
+#define SQLITE_FUNC_LIKE 0x0004 /* Candidate for the LIKE optimization */
+#define SQLITE_FUNC_CASE 0x0008 /* Case-sensitive LIKE-type function */
+#define SQLITE_FUNC_EPHEM 0x0010 /* Ephemeral. Delete with VDBE */
+#define SQLITE_FUNC_NEEDCOLL 0x0020 /* sqlite3GetFuncCollSeq() might be called*/
+#define SQLITE_FUNC_LENGTH 0x0040 /* Built-in length() function */
+#define SQLITE_FUNC_TYPEOF 0x0080 /* Built-in typeof() function */
+#define SQLITE_FUNC_COUNT 0x0100 /* Built-in count(*) aggregate */
+#define SQLITE_FUNC_COALESCE 0x0200 /* Built-in coalesce() or ifnull() */
+#define SQLITE_FUNC_UNLIKELY 0x0400 /* Built-in unlikely() function */
+#define SQLITE_FUNC_CONSTANT 0x0800 /* Constant inputs give a constant output */
+#define SQLITE_FUNC_MINMAX 0x1000 /* True for min() and max() aggregates */
+#define SQLITE_FUNC_SLOCHNG 0x2000 /* "Slow Change". Value constant during a
+ ** single query - might change over time */
/*
** The following three macros, FUNCTION(), LIKEFUNC() and AGGREGATE() are
@@ -10134,6 +12231,15 @@ struct FuncDestructor {
** as the user-data (sqlite3_user_data()) for the function. If
** argument bNC is true, then the SQLITE_FUNC_NEEDCOLL flag is set.
**
+** VFUNCTION(zName, nArg, iArg, bNC, xFunc)
+** Like FUNCTION except it omits the SQLITE_FUNC_CONSTANT flag.
+**
+** DFUNCTION(zName, nArg, iArg, bNC, xFunc)
+** Like FUNCTION except it omits the SQLITE_FUNC_CONSTANT flag and
+** adds the SQLITE_FUNC_SLOCHNG flag. Used for date & time functions
+** and functions like sqlite_version() that can change, but not during
+** a single query.
+**
** 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
@@ -10149,18 +12255,28 @@ struct FuncDestructor {
** parameter.
*/
#define FUNCTION(zName, nArg, iArg, bNC, xFunc) \
- {nArg, SQLITE_UTF8, (bNC*SQLITE_FUNC_NEEDCOLL), \
+ {nArg, SQLITE_FUNC_CONSTANT|SQLITE_UTF8|(bNC*SQLITE_FUNC_NEEDCOLL), \
+ SQLITE_INT_TO_PTR(iArg), 0, xFunc, 0, 0, #zName, 0, 0}
+#define VFUNCTION(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 DFUNCTION(zName, nArg, iArg, bNC, xFunc) \
+ {nArg, SQLITE_FUNC_SLOCHNG|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, \
+ {nArg,SQLITE_FUNC_CONSTANT|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, \
+ {nArg, SQLITE_FUNC_SLOCHNG|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}
+ {nArg, SQLITE_FUNC_CONSTANT|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, \
+ {nArg, SQLITE_UTF8|(nc*SQLITE_FUNC_NEEDCOLL), \
+ SQLITE_INT_TO_PTR(arg), 0, 0, xStep,xFinal,#zName,0,0}
+#define AGGREGATE2(zName, nArg, arg, nc, xStep, xFinal, extraFlags) \
+ {nArg, SQLITE_UTF8|(nc*SQLITE_FUNC_NEEDCOLL)|extraFlags, \
SQLITE_INT_TO_PTR(arg), 0, 0, xStep,xFinal,#zName,0,0}
/*
@@ -10172,6 +12288,7 @@ struct FuncDestructor {
struct Savepoint {
char *zName; /* Savepoint name (nul-terminated) */
i64 nDeferredCons; /* Number of deferred fk violations */
+ i64 nDeferredImmCons; /* Number of deferred imm fk. */
Savepoint *pNext; /* Parent savepoint (if any) */
};
@@ -10194,6 +12311,7 @@ struct Module {
const char *zName; /* Name passed to create_module() */
void *pAux; /* pAux passed to create_module() */
void (*xDestroy)(void *); /* Module destructor function */
+ Table *pEpoTab; /* Eponymous table for this module */
};
/*
@@ -10208,7 +12326,8 @@ struct 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 */
+ u8 szEst; /* Estimated size of value in this column. sizeof(INT)==1 */
+ u8 colFlags; /* Boolean properties. See COLFLAG_ defines below */
};
/* Allowed values for Column.colFlags:
@@ -10238,6 +12357,7 @@ struct CollSeq {
*/
#define SQLITE_SO_ASC 0 /* Sort in ascending order */
#define SQLITE_SO_DESC 1 /* Sort in ascending order */
+#define SQLITE_SO_UNDEFINED -1 /* No sort order specified */
/*
** Column affinity types.
@@ -10246,18 +12366,18 @@ struct CollSeq {
** '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,
+** 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.
+** for a numeric type is a single comparison. And the BLOB type is first.
*/
-#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 SQLITE_AFF_BLOB 'A'
+#define SQLITE_AFF_TEXT 'B'
+#define SQLITE_AFF_NUMERIC 'C'
+#define SQLITE_AFF_INTEGER 'D'
+#define SQLITE_AFF_REAL 'E'
#define sqlite3IsNumericAffinity(X) ((X)>=SQLITE_AFF_NUMERIC)
@@ -10265,15 +12385,21 @@ struct CollSeq {
** The SQLITE_AFF_MASK values masks off the significant bits of an
** affinity value.
*/
-#define SQLITE_AFF_MASK 0x67
+#define SQLITE_AFF_MASK 0x47
/*
** Additional bit values that can be ORed with an affinity without
** changing the affinity.
+**
+** The SQLITE_NOTNULL flag is a combination of NULLEQ and JUMPIFNULL.
+** It causes an assert() to fire if either operand to a comparison
+** operator is NULL. It is added to certain comparison operators to
+** prove that the operands are always NOT NULL.
*/
-#define SQLITE_JUMPIFNULL 0x08 /* jumps if either operand is NULL */
-#define SQLITE_STOREP2 0x10 /* Store result in reg[P2] rather than jump */
+#define SQLITE_JUMPIFNULL 0x10 /* jumps if either operand is NULL */
+#define SQLITE_STOREP2 0x20 /* Store result in reg[P2] rather than jump */
#define SQLITE_NULLEQ 0x80 /* NULL=NULL */
+#define SQLITE_NOTNULL 0x90 /* Assert that operands are never NULL */
/*
** An object of this type is created for each virtual table present in
@@ -10328,34 +12454,8 @@ struct VTable {
};
/*
-** 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.
+** The schema for each SQL table and view is represented in memory
+** by an instance of the following structure.
*/
struct Table {
char *zName; /* Name of the table or view */
@@ -10364,14 +12464,17 @@ struct 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 */
+ /* ... also used as column name list in a VIEW */
+ int tnum; /* Root BTree page for this table */
+ i16 iPKey; /* If not negative, use aCol[iPKey] as the rowid */
i16 nCol; /* Number of columns in this table */
u16 nRef; /* Number of pointers to this Table */
+ LogEst nRowLogEst; /* Estimated rows in table - from sqlite_stat1 table */
+ LogEst szTabRow; /* Estimated size of each table row in bytes */
+#ifdef SQLITE_ENABLE_COSTMULT
+ LogEst costMult; /* Cost multiplier for using this table */
+#endif
u8 tabFlags; /* Mask of TF_* values */
u8 keyConf; /* What to do in case of uniqueness conflict on iPKey */
#ifndef SQLITE_OMIT_ALTERTABLE
@@ -10379,7 +12482,7 @@ struct Table {
#endif
#ifndef SQLITE_OMIT_VIRTUALTABLE
int nModuleArg; /* Number of arguments to the module */
- char **azModuleArg; /* Text of all module args. [0] is module name */
+ char **azModuleArg; /* 0: module 1: schema 2: vtab name 3...: args */
VTable *pVTable; /* List of VTable objects. */
#endif
Trigger *pTrigger; /* List of triggers stored in pSchema */
@@ -10388,13 +12491,22 @@ struct Table {
};
/*
-** Allowed values for Tabe.tabFlags.
+** Allowed values for Table.tabFlags.
+**
+** TF_OOOHidden applies to tables or view that have hidden columns that are
+** followed by non-hidden columns. Example: "CREATE VIRTUAL TABLE x USING
+** vtab1(a HIDDEN, b);". Since "b" is a non-hidden column but "a" is hidden,
+** the TF_OOOHidden attribute would apply in this case. Such tables require
+** special handling during INSERT processing.
*/
#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 */
+#define TF_WithoutRowid 0x20 /* No rowid. PRIMARY KEY is the key */
+#define TF_NoVisibleRowid 0x40 /* No user-visible "rowid" column */
+#define TF_OOOHidden 0x80 /* Out-of-Order hidden columns */
/*
@@ -10404,13 +12516,33 @@ struct Table {
*/
#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
/*
+** Macros to determine if a column is hidden. IsOrdinaryHiddenColumn()
+** only works for non-virtual tables (ordinary tables and views) and is
+** always false unless SQLITE_ENABLE_HIDDEN_COLUMNS is defined. The
+** IsHiddenColumn() macro is general purpose.
+*/
+#if defined(SQLITE_ENABLE_HIDDEN_COLUMNS)
+# define IsHiddenColumn(X) (((X)->colFlags & COLFLAG_HIDDEN)!=0)
+# define IsOrdinaryHiddenColumn(X) (((X)->colFlags & COLFLAG_HIDDEN)!=0)
+#elif !defined(SQLITE_OMIT_VIRTUALTABLE)
+# define IsHiddenColumn(X) (((X)->colFlags & COLFLAG_HIDDEN)!=0)
+# define IsOrdinaryHiddenColumn(X) 0
+#else
+# define IsHiddenColumn(X) 0
+# define IsOrdinaryHiddenColumn(X) 0
+#endif
+
+
+/* Does the table have a rowid */
+#define HasRowid(X) (((X)->tabFlags & TF_WithoutRowid)==0)
+#define VisibleRowid(X) (((X)->tabFlags & TF_NoVisibleRowid)==0)
+
+/*
** Each foreign key constraint is an instance of the following structure.
**
** A foreign key is associated with two tables. The "from" table is
@@ -10424,26 +12556,35 @@ struct Table {
** );
**
** For foreign key "fk1", the from-table is "ex1" and the to-table is "ex2".
+** Equivalent names:
+**
+** from-table == child-table
+** to-table == parent-table
**
** 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.
+**
+** The list of all parents for child Table X is held at X.pFKey.
+**
+** A list of all children for a table named Z (which might not even exist)
+** is held in Schema.fkeyHash with a hash key of Z.
*/
struct FKey {
Table *pFrom; /* Table containing the REFERENCES clause (aka: Child) */
- FKey *pNextFrom; /* Next foreign key in pFrom */
+ FKey *pNextFrom; /* Next FKey with the same in pFrom. Next parent of 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 */
+ FKey *pNextTo; /* Next with the same zTo. Next child of zTo. */
+ FKey *pPrevTo; /* Previous with the same 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 */
+ 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 NULL use PRIMARY KEY */
+ } aCol[1]; /* One entry for each of nCol columns */
};
/*
@@ -10483,26 +12624,31 @@ struct FKey {
#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 */
+#define OE_Default 10 /* 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.
+**
+** Note that aSortOrder[] and aColl[] have nField+1 slots. There
+** are nField slots for the columns of an index then one extra slot
+** for the rowid at the end.
*/
struct KeyInfo {
- sqlite3 *db; /* The database connection */
+ u32 nRef; /* Number of references to this KeyInfo object */
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 */
+ u16 nField; /* Number of key columns in the index */
+ u16 nXField; /* Number of columns beyond the key columns */
+ sqlite3 *db; /* The database connection */
+ u8 *aSortOrder; /* Sort order for each column. */
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.
+** This object holds a record which has been parsed out into individual
+** fields, for the purposes of doing a comparison.
**
** 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
@@ -10510,23 +12656,42 @@ struct KeyInfo {
** 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.
+** An instance of this object serves as a "key" for doing a search on
+** an index b+tree. The goal of the search is to find the entry that
+** is closed to the key described by this object. This object might hold
+** just a prefix of the key. The number of fields is given by
+** pKeyInfo->nField.
+**
+** The r1 and r2 fields are the values to return if this key is less than
+** or greater than a key in the btree, respectively. These are normally
+** -1 and +1 respectively, but might be inverted to +1 and -1 if the b-tree
+** is in DESC order.
+**
+** The key comparison functions actually return default_rc when they find
+** an equals comparison. default_rc can be -1, 0, or +1. If there are
+** multiple entries in the b-tree with the same key (when only looking
+** at the first pKeyInfo->nFields,) then default_rc can be set to -1 to
+** cause the search to find the last match, or +1 to cause the search to
+** find the first match.
+**
+** The key comparison functions will set eqSeen to true if they ever
+** get and equal results when comparing this structure to a b-tree record.
+** When default_rc!=0, the search might end up on the record immediately
+** before the first match or immediately after the last match. The
+** eqSeen field will indicate whether or not an exact match exists in the
+** b-tree.
*/
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 */
+ u16 nField; /* Number of entries in apMem[] */
+ i8 default_rc; /* Comparison result if keys are equal */
+ u8 errCode; /* Error detected by xRecordCompare (CORRUPT or NOMEM) */
+ i8 r1; /* Value to return if (lhs > rhs) */
+ i8 r2; /* Value to return if (rhs < lhs) */
+ u8 eqSeen; /* True if an equality comparison has been seen */
};
-/*
-** 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
@@ -10553,45 +12718,78 @@ struct UnpackedRecord {
** 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.
+**
+** While parsing a CREATE TABLE or CREATE INDEX statement in order to
+** generate VDBE code (as opposed to parsing one read from an sqlite_master
+** table as part of parsing an existing database schema), transient instances
+** of this structure may be created. In this case the Index.tnum variable is
+** used to store the address of a VDBE instruction, not a database page
+** number (it cannot - the database page is not allocated until the VDBE
+** program is executed). See convertToWithoutRowidTable() for details.
*/
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
+ char *zName; /* Name of this index */
+ i16 *aiColumn; /* Which columns are used by this index. 1st is 0 */
+ LogEst *aiRowLogEst; /* From 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; /* for each column: True==DESC, False==ASC */
+ const char **azColl; /* Array of collation sequence names for index */
+ Expr *pPartIdxWhere; /* WHERE clause for partial indices */
+ ExprList *aColExpr; /* Column expressions */
+ int tnum; /* DB Page containing root of this index */
+ LogEst szIdxRow; /* Estimated average row size in bytes */
+ u16 nKeyCol; /* Number of columns forming the key */
+ u16 nColumn; /* Number of columns stored in the index */
+ u8 onError; /* OE_Abort, OE_Ignore, OE_Replace, or OE_None */
+ unsigned idxType:2; /* 1==UNIQUE, 2==PRIMARY KEY, 0==CREATE INDEX */
+ unsigned bUnordered:1; /* Use this index for == or IN queries only */
+ unsigned uniqNotNull:1; /* True if UNIQUE and NOT NULL for all columns */
+ unsigned isResized:1; /* True if resizeIndexObject() has been called */
+ unsigned isCovering:1; /* True if this is a covering index */
+ unsigned noSkipScan:1; /* Do not try to use skip-scan if true */
+#ifdef SQLITE_ENABLE_STAT3_OR_STAT4
int nSample; /* Number of elements in aSample[] */
- tRowcnt avgEq; /* Average nEq value for key values not in aSample */
+ int nSampleCol; /* Size of IndexSample.anEq[] and so on */
+ tRowcnt *aAvgEq; /* Average nEq values for keys not in aSample */
IndexSample *aSample; /* Samples of the left-most key */
+ tRowcnt *aiRowEst; /* Non-logarithmic stat1 data for this index */
+ tRowcnt nRowEst0; /* Non-logarithmic number of rows in the index */
#endif
};
/*
+** Allowed values for Index.idxType
+*/
+#define SQLITE_IDXTYPE_APPDEF 0 /* Created using CREATE INDEX */
+#define SQLITE_IDXTYPE_UNIQUE 1 /* Implements a UNIQUE constraint */
+#define SQLITE_IDXTYPE_PRIMARYKEY 2 /* Is the PRIMARY KEY for the table */
+
+/* Return true if index X is a PRIMARY KEY index */
+#define IsPrimaryKeyIndex(X) ((X)->idxType==SQLITE_IDXTYPE_PRIMARYKEY)
+
+/* Return true if index X is a UNIQUE index */
+#define IsUniqueIndex(X) ((X)->onError!=OE_None)
+
+/* The Index.aiColumn[] values are normally positive integer. But
+** there are some negative values that have special meaning:
+*/
+#define XN_ROWID (-1) /* Indexed column is the rowid */
+#define XN_EXPR (-2) /* Indexed column is an expression */
+
+/*
** 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 */
+ void *p; /* Pointer to sampled record */
+ int n; /* Size of record in bytes */
+ tRowcnt *anEq; /* Est. number of rows where the key equals this sample */
+ tRowcnt *anLt; /* Est. number of rows where key is less than this sample */
+ tRowcnt *anDLt; /* Est. number of distinct keys less than this sample */
};
/*
@@ -10628,6 +12826,7 @@ struct AggInfo {
int sortingIdx; /* Cursor number of the sorting index */
int sortingIdxPTab; /* Cursor number of pseudo-table */
int nSortingColumn; /* Number of columns in the sorting index */
+ int mnReg, mxReg; /* Range of registers allocated for aCol and aFunc */
ExprList *pGroupBy; /* The group by clause */
struct AggInfo_col { /* For each column used in source tables */
Table *pTab; /* Source table */
@@ -10732,7 +12931,7 @@ typedef int ynVar;
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 */
+ u32 flags; /* Various flags. EP_* See below */
union {
char *zToken; /* Token value. Zero terminated and dequoted */
int iValue; /* Non-negative integer value if EP_IntValue */
@@ -10746,8 +12945,8 @@ struct Expr {
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>)" */
+ ExprList *pList; /* op = IN, EXISTS, SELECT, CASE, FUNCTION, BETWEEN */
+ Select *pSelect; /* EP_xIsSelect and op = IN, EXISTS, SELECT */
} x;
/* If the EP_Reduced flag is set in the Expr.flags mask, then no
@@ -10760,12 +12959,12 @@ struct Expr {
#endif
int iTable; /* TK_COLUMN: cursor number of table holding column
** TK_REGISTER: register number
- ** TK_TRIGGER: 1 -> new, 0 -> old */
+ ** TK_TRIGGER: 1 -> new, 0 -> old
+ ** EP_Unlikely: 134217728 times likelihood */
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 */
@@ -10776,51 +12975,55 @@ struct Expr {
/*
** 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() */
+#define EP_FromJoin 0x000001 /* Originates in ON/USING clause of outer join */
+#define EP_Agg 0x000002 /* Contains one or more aggregate functions */
+#define EP_Resolved 0x000004 /* IDs have been resolved to COLUMNs */
+#define EP_Error 0x000008 /* Expression contains one or more errors */
+#define EP_Distinct 0x000010 /* Aggregate function with DISTINCT keyword */
+#define EP_VarSelect 0x000020 /* pSelect is correlated, not constant */
+#define EP_DblQuoted 0x000040 /* token.z was originally in "..." */
+#define EP_InfixFunc 0x000080 /* True for an infix function: LIKE, GLOB, etc */
+#define EP_Collate 0x000100 /* Tree contains a TK_COLLATE operator */
+#define EP_Generic 0x000200 /* Ignore COLLATE or affinity on this tree */
+#define EP_IntValue 0x000400 /* Integer value contained in u.iValue */
+#define EP_xIsSelect 0x000800 /* x.pSelect is valid (otherwise x.pList is) */
+#define EP_Skip 0x001000 /* COLLATE, AS, or UNLIKELY */
+#define EP_Reduced 0x002000 /* Expr struct EXPR_REDUCEDSIZE bytes only */
+#define EP_TokenOnly 0x004000 /* Expr struct EXPR_TOKENONLYSIZE bytes only */
+#define EP_Static 0x008000 /* Held in memory not obtained from malloc() */
+#define EP_MemToken 0x010000 /* Need to sqlite3DbFree() Expr.zToken */
+#define EP_NoReduce 0x020000 /* Cannot EXPRDUP_REDUCE this Expr */
+#define EP_Unlikely 0x040000 /* unlikely() or likelihood() function */
+#define EP_ConstFunc 0x080000 /* A SQLITE_FUNC_CONSTANT or _SLOCHNG function */
+#define EP_CanBeNull 0x100000 /* Can be null despite NOT NULL constraint */
+#define EP_Subquery 0x200000 /* Tree contains a TK_SELECT operator */
+#define EP_Alias 0x400000 /* Is an alias for a result set column */
+
+/*
+** Combinations of two or more EP_* flags
+*/
+#define EP_Propagate (EP_Collate|EP_Subquery) /* Propagate these bits up tree */
/*
-** The following are the meanings of bits in the Expr.flags2 field.
+** These macros can be used to test, set, or clear bits in the
+** Expr.flags field.
*/
-#define EP2_MallocedToken 0x0001 /* Need to sqlite3DbFree() Expr.zToken */
-#define EP2_Irreducible 0x0002 /* Cannot EXPRDUP_REDUCE this Expr */
+#define ExprHasProperty(E,P) (((E)->flags&(P))!=0)
+#define ExprHasAllProperty(E,P) (((E)->flags&(P))==(P))
+#define ExprSetProperty(E,P) (E)->flags|=(P)
+#define ExprClearProperty(E,P) (E)->flags&=~(P)
-/*
-** 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.
+/* The ExprSetVVAProperty() macro is used for Verification, Validation,
+** and Accreditation only. It works like ExprSetProperty() during VVA
+** processes but is a no-op for delivery.
*/
#ifdef SQLITE_DEBUG
-# define ExprSetIrreducible(X) (X)->flags2 |= EP2_Irreducible
+# define ExprSetVVAProperty(E,P) (E)->flags|=(P)
#else
-# define ExprSetIrreducible(X)
+# define ExprSetVVAProperty(E,P)
#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.
@@ -10842,18 +13045,32 @@ struct Expr {
** 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.
+**
+** By default the Expr.zSpan field holds a human-readable description of
+** the expression that is used in the generation of error messages and
+** column labels. In this case, Expr.zSpan is typically the text of a
+** column expression as it exists in a SELECT statement. However, if
+** the bSpanIsTab flag is set, then zSpan is overloaded to mean the name
+** of the result column in the form: DATABASE.TABLE.COLUMN. This later
+** form is used for name resolution with nested FROM clauses.
*/
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 */
+ 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 */
+ unsigned done :1; /* A flag to indicate when processing is finished */
+ unsigned bSpanIsTab :1; /* zSpan holds DB.TABLE.COLUMN */
+ unsigned reusable :1; /* Constant expression is reusable */
+ union {
+ struct {
+ u16 iOrderByCol; /* For ORDER BY, column number in result set */
+ u16 iAlias; /* Index into Parse.aAlias[] for zName */
+ } x;
+ int iConstExprReg; /* Register in which Expr value is cached */
+ } u;
} *a; /* Alloc a power of two greater or equal to nExpr */
};
@@ -10906,6 +13123,12 @@ typedef u64 Bitmask;
#define BMS ((int)(sizeof(Bitmask)*8))
/*
+** A bit in a Bitmask
+*/
+#define MASKBIT(n) (((Bitmask)1)<<(n))
+#define MASKBIT32(n) (((unsigned int)1)<<(n))
+
+/*
** 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.
@@ -10925,8 +13148,8 @@ typedef u64 Bitmask;
** 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 */
+ int nSrc; /* Number of tables or subqueries in the FROM clause */
+ u32 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 */
@@ -10936,10 +13159,16 @@ struct SrcList {
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 */
+ int regResult; /* Registers holding results of a co-routine */
+ struct {
+ u8 jointype; /* Type of join between this able and the previous */
+ unsigned notIndexed :1; /* True if there is a NOT INDEXED clause */
+ unsigned isIndexedBy :1; /* True if there is an INDEXED BY clause */
+ unsigned isTabFunc :1; /* True if table-valued-function syntax */
+ unsigned isCorrelated :1; /* True if sub-query is correlated */
+ unsigned viaCoroutine :1; /* Implemented as a co-routine */
+ unsigned isRecursive :1; /* True for recursive reference in WITH */
+ } fg;
#ifndef SQLITE_OMIT_EXPLAIN
u8 iSelectId; /* If pSelect!=0, the id of the sub-select in EQP */
#endif
@@ -10947,8 +13176,11 @@ struct SrcList {
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 */
+ union {
+ char *zIndexedBy; /* Identifier from "INDEXED BY <zIndex>" clause */
+ ExprList *pFuncArg; /* Arguments to table-valued-function */
+ } u1;
+ Index *pIBIndex; /* Index structure corresponding to u1.zIndexedBy */
} a[1]; /* One entry for each identifier on the list */
};
@@ -10965,78 +13197,6 @@ struct SrcList {
/*
-** 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.
*/
@@ -11048,34 +13208,16 @@ struct WhereLevel {
#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 */
+#define WHERE_NO_AUTOINDEX 0x0080 /* Disallow automatic indexes */
+#define WHERE_GROUPBY 0x0100 /* pOrderBy is really a GROUP BY */
+#define WHERE_DISTINCTBY 0x0200 /* pOrderby is really a DISTINCT clause */
+#define WHERE_WANT_DISTINCT 0x0400 /* All output needs to be distinct */
+#define WHERE_SORTBYGROUP 0x0800 /* Support sqlite3WhereIsSorted() */
+#define WHERE_REOPEN_IDX 0x1000 /* Try to use OP_ReopenIdx */
+#define WHERE_ONEPASS_MULTIROW 0x2000 /* ONEPASS is ok with multiple rows */
-/*
-** 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.
+/* Allowed return values from sqlite3WhereIsDistinct()
*/
-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 */
@@ -11105,21 +13247,28 @@ struct WhereInfo {
struct NameContext {
Parse *pParse; /* The parser */
SrcList *pSrcList; /* One or more tables used to resolve names */
- ExprList *pEList; /* Optional list of named expressions */
+ ExprList *pEList; /* Optional list of result-set columns */
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 */
+ u16 ncFlags; /* Zero or more NC_* flags defined below */
};
/*
** Allowed values for the NameContext, ncFlags field.
+**
+** Note: NC_MinMaxAgg must have the same value as SF_MinMaxAgg and
+** SQLITE_FUNC_MINMAX.
+**
*/
-#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 */
+#define NC_AllowAgg 0x0001 /* Aggregate functions are allowed here */
+#define NC_HasAgg 0x0002 /* One or more aggregate functions seen */
+#define NC_IsCheck 0x0004 /* True if resolving names in a CHECK constraint */
+#define NC_InAggFunc 0x0008 /* True if analyzing arguments to an agg func */
+#define NC_PartIdx 0x0010 /* True if resolving a partial index WHERE */
+#define NC_IdxExpr 0x0020 /* True if resolving columns of CREATE INDEX */
+#define NC_MinMaxAgg 0x1000 /* min/max aggregates seen. See note above */
/*
** An instance of the following structure contains all information
@@ -11146,8 +13295,11 @@ struct Select {
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 */
+#if SELECTTRACE_ENABLED
+ char zSelName[12]; /* Symbolic name of this SELECT use for debugging */
+#endif
+ int addrOpenEphm[2]; /* OP_OpenEphem opcodes related to this select */
+ u64 nSelectRow; /* Estimated number of result rows */
SrcList *pSrc; /* The FROM clause */
Expr *pWhere; /* The WHERE clause */
ExprList *pGroupBy; /* The GROUP BY clause */
@@ -11155,9 +13307,9 @@ struct Select {
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. */
+ With *pWith; /* WITH clause attached to this select. Or NULL. */
};
/*
@@ -11165,45 +13317,117 @@ struct Select {
** "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 SF_All 0x0002 /* Includes the ALL keyword */
+#define SF_Resolved 0x0004 /* Identifiers have been resolved */
+#define SF_Aggregate 0x0008 /* Contains aggregate functions */
+#define SF_UsesEphemeral 0x0010 /* Uses the OpenEphemeral opcode */
+#define SF_Expanded 0x0020 /* sqlite3SelectExpand() called on this */
+#define SF_HasTypeInfo 0x0040 /* FROM subqueries have Table metadata */
+#define SF_Compound 0x0080 /* Part of a compound query */
+#define SF_Values 0x0100 /* Synthesized from VALUES clause */
+#define SF_MultiValue 0x0200 /* Single VALUES term with multiple rows */
+#define SF_NestedFrom 0x0400 /* Part of a parenthesized FROM clause */
+#define SF_MaybeConvert 0x0800 /* Need convertCompoundSelectToSubquery() */
+#define SF_MinMaxAgg 0x1000 /* Aggregate containing min() or max() */
+#define SF_Recursive 0x2000 /* The recursive part of a recursive CTE */
+#define SF_Converted 0x4000 /* By convertCompoundSelectToSubquery() */
+#define SF_IncludeHidden 0x8000 /* Include hidden columns in output */
+
+
+/*
+** The results of a SELECT can be distributed in several ways, as defined
+** by one of the following macros. The "SRT" prefix means "SELECT Result
+** Type".
+**
+** SRT_Union Store results as a key in a temporary index
+** identified by pDest->iSDParm.
+**
+** SRT_Except Remove results from the temporary index 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.
+**
+** All of the above are free to ignore their ORDER BY clause. Those that
+** follow must honor the ORDER BY clause.
+**
+** 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_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
+** and the result row is stored in pDest->nDest registers
+** starting with pDest->iSdst.
+**
+** SRT_Table Store results in temporary table pDest->iSDParm.
+** SRT_Fifo This is like SRT_EphemTab except that the table
+** is assumed to already be open. SRT_Fifo has
+** the additional property of being able to ignore
+** the ORDER BY clause.
+**
+** SRT_DistFifo Store results in a temporary table pDest->iSDParm.
+** But also use temporary table pDest->iSDParm+1 as
+** a record of all prior results and ignore any duplicate
+** rows. Name means: "Distinct Fifo".
+**
+** SRT_Queue Store results in priority queue pDest->iSDParm (really
+** an index). Append a sequence number so that all entries
+** are distinct.
+**
+** SRT_DistQueue Store results in priority queue pDest->iSDParm only if
+** the same record has never been stored before. The
+** index at pDest->iSDParm+1 hold all prior stores.
*/
#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 */
+#define SRT_Fifo 5 /* Store result as data with an automatic rowid */
+#define SRT_DistFifo 6 /* Like SRT_Fifo, but unique results only */
+#define SRT_Queue 7 /* Store result in an queue */
+#define SRT_DistQueue 8 /* Like SRT_Queue, but unique results only */
/* The ORDER BY clause is ignored for all of the above */
-#define IgnorableOrderby(X) ((X->eDest)<=SRT_Discard)
+#define IgnorableOrderby(X) ((X->eDest)<=SRT_DistQueue)
-#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 */
+#define SRT_Output 9 /* Output each row of result */
+#define SRT_Mem 10 /* Store result in a memory cell */
+#define SRT_Set 11 /* Store results as keys in an index */
+#define SRT_EphemTab 12 /* Create transient tab and store like SRT_Table */
+#define SRT_Coroutine 13 /* Generate a single row of result */
+#define SRT_Table 14 /* Store result as data with an automatic rowid */
/*
** 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 */
+ 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 */
+ ExprList *pOrderBy; /* Key columns for SRT_Queue and SRT_DistQueue */
};
/*
@@ -11259,9 +13483,19 @@ struct TriggerPrg {
** The yDbMask datatype for the bitmask of all attached databases.
*/
#if SQLITE_MAX_ATTACHED>30
- typedef sqlite3_uint64 yDbMask;
+ typedef unsigned char yDbMask[(SQLITE_MAX_ATTACHED+9)/8];
+# define DbMaskTest(M,I) (((M)[(I)/8]&(1<<((I)&7)))!=0)
+# define DbMaskZero(M) memset((M),0,sizeof(M))
+# define DbMaskSet(M,I) (M)[(I)/8]|=(1<<((I)&7))
+# define DbMaskAllZero(M) sqlite3DbMaskAllZero(M)
+# define DbMaskNonZero(M) (sqlite3DbMaskAllZero(M)==0)
#else
typedef unsigned int yDbMask;
+# define DbMaskTest(M,I) (((M)&(((yDbMask)1)<<(I)))!=0)
+# define DbMaskZero(M) (M)=0
+# define DbMaskSet(M,I) (M)|=(((yDbMask)1)<<(I))
+# define DbMaskAllZero(M) (M)==0
+# define DbMaskNonZero(M) (M)!=0
#endif
/*
@@ -11289,11 +13523,10 @@ struct Parse {
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 */
+ u8 hasCompound; /* Need to invoke convertCompoundSelectToSubquery() */
+ u8 okConstFactor; /* OK to factor out constants */
int aTempReg[8]; /* Holding area for temporary registers */
int nRangeReg; /* Size of the temporary register block */
int iRangeReg; /* First register in temporary register block */
@@ -11302,25 +13535,35 @@ struct Parse {
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 nOpAlloc; /* Number of slots allocated for Vdbe.aOp[] */
+ int szOpAlloc; /* Bytes of memory space allocated for Vdbe.aOp[] */
+ int iFixedOp; /* Never back out opcodes iFixedOp-1 or earlier */
int ckBase; /* Base register of data during check constraints */
+ int iSelfTab; /* Table of an index whose exprs are being coded */
int iCacheLevel; /* ColCache valid when aColCache[].iLevel<=iCacheLevel */
int iCacheCnt; /* Counter used to generate aColCache[].lru values */
+ int nLabel; /* Number of labels used */
+ int *aLabel; /* Space to hold the labels */
struct yColCache {
int iTable; /* Table cursor number */
- int iColumn; /* Table column number */
+ i16 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 */
+ ExprList *pConstExpr;/* Constant expressions */
+ Token constraintName;/* Name of the constraint currently being parsed */
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 */
+#if SELECTTRACE_ENABLED
+ int nSelect; /* Number of SELECT statements seen */
+ int nSelectIndent; /* How far to indent SELECTTRACE() output */
+#endif
#ifndef SQLITE_OMIT_SHARED_CACHE
int nTableLock; /* Number of locks in aTableLock */
TableLock *aTableLock; /* Required table locks for shared-cache mode */
@@ -11330,18 +13573,24 @@ struct Parse {
/* 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 */
+ int addrCrTab; /* Address of OP_CreateTable opcode on CREATE TABLE */
+ u32 nQueryLoop; /* Est number of iterations of a query (10*log2(N)) */
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 */
+ /************************************************************************
+ ** Above is constant between recursions. Below is reset before and after
+ ** each recursion. The boundary between these two regions is determined
+ ** using offsetof(Parse,nVar) so the nVar field must be the first field
+ ** in the recursive region.
+ ************************************************************************/
int nVar; /* Number of '?' variables seen in the SQL so far */
int nzVar; /* Number of available slots in azVar[] */
+ u8 iPkSortOrder; /* ASC or DESC for INTEGER PRIMARY KEY */
u8 explain; /* True if the EXPLAIN flag is found on the query */
#ifndef SQLITE_OMIT_VIRTUALTABLE
u8 declareVtab; /* True if inside sqlite3_declare_vtab() */
@@ -11355,7 +13604,6 @@ struct Parse {
#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 */
@@ -11368,6 +13616,8 @@ struct Parse {
#endif
Table *pZombieTab; /* List of Table objects to delete after code gen */
TriggerPrg *pTriggerPrg; /* Linked list of coded triggers */
+ With *pWith; /* Current WITH clause, or NULL */
+ With *pWithToFree; /* Free this WITH object at the end of the parse */
};
/*
@@ -11392,15 +13642,17 @@ struct AuthContext {
** Bitfield flags for P5 value in various opcodes.
*/
#define OPFLAG_NCHANGE 0x01 /* Set to update db->nChange */
+#define OPFLAG_EPHEM 0x01 /* OP_Column: Ephemeral output is ok */
#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_SEEKEQ 0x02 /* OP_Open** cursor uses EQ seek only */
+#define OPFLAG_FORDELETE 0x08 /* OP_Open is opening for-delete csr */
+#define OPFLAG_P2ISREG 0x10 /* P2 to OP_Open** is a register number */
#define OPFLAG_PERMUTE 0x01 /* OP_Compare: use the permutation */
/*
@@ -11459,7 +13711,7 @@ struct Trigger {
* 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.
+ * zTarget -> Dequoted 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 ...
@@ -11467,12 +13719,12 @@ struct Trigger {
* inserted into.
*
* (op == TK_DELETE)
- * target -> A token holding the quoted name of the table to delete from.
+ * zTarget -> Dequoted 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.
+ * zTarget -> Dequoted name of the table to update.
* 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
@@ -11484,10 +13736,10 @@ 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 */
+ Select *pSelect; /* SELECT statement or RHS of INSERT INTO SELECT ... */
+ char *zTarget; /* 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 */
+ ExprList *pExprList; /* SET clause for UPDATE. */
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 */
@@ -11502,6 +13754,7 @@ typedef struct DbFixer DbFixer;
struct DbFixer {
Parse *pParse; /* The parsing context. Error messages written here */
Schema *pSchema; /* Fix items to this schema */
+ int bVarOnly; /* Check for variable references only */
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 */
@@ -11515,13 +13768,14 @@ 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 */
+ u32 nChar; /* Length of the string so far */
+ u32 nAlloc; /* Amount of space allocated in zText */
+ u32 mxAlloc; /* Maximum allowed allocation. 0 for no malloc usage */
+ u8 accError; /* STRACCUM_NOMEM or STRACCUM_TOOBIG */
+ u8 bMalloced; /* zText points to allocated space */
};
+#define STRACCUM_NOMEM 1
+#define STRACCUM_TOOBIG 2
/*
** A pointer to this structure is used to communicate information
@@ -11546,6 +13800,7 @@ struct Sqlite3Config {
int bOpenUri; /* True to interpret filenames as URIs */
int bUseCis; /* Use covering indices for full-scans */
int mxStrlen; /* Maximum string length */
+ int neverCorrupt; /* Database is always well-formed */
int szLookaside; /* Default lookaside buffer size */
int nLookaside; /* Default lookaside buffer count */
sqlite3_mem_methods m; /* Low-level memory allocation interface */
@@ -11554,6 +13809,8 @@ struct Sqlite3Config {
void *pHeap; /* Heap storage space */
int nHeap; /* Size of pHeap[] */
int mnReq, mxReq; /* Min and max heap requests sizes */
+ sqlite3_int64 szMmap; /* mmap() space per open file */
+ sqlite3_int64 mxMmap; /* Maximum value for szMmap */
void *pScratch; /* Scratch memory */
int szScratch; /* Size of each scratch buffer */
int nScratch; /* Number of scratch buffers */
@@ -11562,6 +13819,7 @@ struct Sqlite3Config {
int nPage; /* Number of pages in pPage[] */
int mxParserStack; /* maximum depth of the parser stack */
int sharedCacheEnabled; /* true if shared-cache mode enabled */
+ u32 szPma; /* Maximum Sorter PMA size */
/* The above might be initialized to non-zero. The following need to always
** initially be zero, however. */
int isInit; /* True after initialization has finished */
@@ -11569,30 +13827,62 @@ struct Sqlite3Config {
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 */
+ sqlite3_mutex *pInitMutex; /* Mutex used by sqlite3_initialize() */
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
+#ifdef SQLITE_VDBE_COVERAGE
+ /* The following callback (if not NULL) is invoked on every VDBE branch
+ ** operation. Set the callback using SQLITE_TESTCTRL_VDBE_COVERAGE.
+ */
+ void (*xVdbeBranch)(void*,int iSrcLine,u8 eThis,u8 eMx); /* Callback */
+ void *pVdbeBranchArg; /* 1st argument */
+#endif
+#ifndef SQLITE_OMIT_BUILTIN_TEST
+ int (*xTestCallback)(int); /* Invoked by sqlite3FaultSim() */
+#endif
+ int bLocaltimeFault; /* True to fail localtime() calls */
};
/*
+** This macro is used inside of assert() statements to indicate that
+** the assert is only valid on a well-formed database. Instead of:
+**
+** assert( X );
+**
+** One writes:
+**
+** assert( X || CORRUPT_DB );
+**
+** CORRUPT_DB is true during normal operation. CORRUPT_DB does not indicate
+** that the database is definitely corrupt, only that it might be corrupt.
+** For most test cases, CORRUPT_DB is set to false using a special
+** sqlite3_test_control(). This enables assert() statements to prove
+** things that are always true for well-formed databases.
+*/
+#define CORRUPT_DB (sqlite3Config.neverCorrupt==0)
+
+/*
** Context pointer passed down through the tree-walk.
*/
struct Walker {
int (*xExprCallback)(Walker*, Expr*); /* Callback for expressions */
int (*xSelectCallback)(Walker*,Select*); /* Callback for SELECTs */
+ void (*xSelectCallback2)(Walker*,Select*);/* Second callback for SELECTs */
Parse *pParse; /* Parser context. */
int walkerDepth; /* Number of subqueries */
+ u8 eCode; /* A small processing code */
union { /* Extra data for callback */
NameContext *pNC; /* Naming context */
- int i; /* Integer value */
+ int n; /* A counter */
+ int iCur; /* A cursor number */
SrcList *pSrcList; /* FROM clause */
struct SrcCount *pSrcCount; /* Counting column references */
+ struct CCurHint *pCCurHint; /* Used by codeCursorHint() */
} u;
};
@@ -11602,6 +13892,7 @@ SQLITE_PRIVATE int sqlite3WalkExprList(Walker*, ExprList*);
SQLITE_PRIVATE int sqlite3WalkSelect(Walker*, Select*);
SQLITE_PRIVATE int sqlite3WalkSelectExpr(Walker*, Select*);
SQLITE_PRIVATE int sqlite3WalkSelectFrom(Walker*, Select*);
+SQLITE_PRIVATE int sqlite3ExprWalkNoop(Walker*, Expr*);
/*
** Return code from the parse-tree walking primitives and their
@@ -11612,6 +13903,32 @@ SQLITE_PRIVATE int sqlite3WalkSelectFrom(Walker*, Select*);
#define WRC_Abort 2 /* Abandon the tree walk */
/*
+** An instance of this structure represents a set of one or more CTEs
+** (common table expressions) created by a single WITH clause.
+*/
+struct With {
+ int nCte; /* Number of CTEs in the WITH clause */
+ With *pOuter; /* Containing WITH clause, or NULL */
+ struct Cte { /* For each CTE in the WITH clause.... */
+ char *zName; /* Name of this CTE */
+ ExprList *pCols; /* List of explicit column names, or NULL */
+ Select *pSelect; /* The definition of this CTE */
+ const char *zCteErr; /* Error message for circular references */
+ } a[1];
+};
+
+#ifdef SQLITE_DEBUG
+/*
+** An instance of the TreeView object is used for printing the content of
+** data structures on sqlite3DebugPrintf() using a tree-like view.
+*/
+struct TreeView {
+ int iLevel; /* Which level of the tree we are on */
+ u8 bLine[100]; /* Draw vertical in column i if bLine[i] is true */
+};
+#endif /* SQLITE_DEBUG */
+
+/*
** 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.
*/
@@ -11638,11 +13955,11 @@ SQLITE_PRIVATE int sqlite3CantopenError(int);
/*
** 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.
+** SQLITE_ENABLE_FTS3 macro. But to avoid confusion we also call
+** the SQLITE_ENABLE_FTS4 macro to serve as an alias for SQLITE_ENABLE_FTS3.
*/
#if defined(SQLITE_ENABLE_FTS4) && !defined(SQLITE_ENABLE_FTS3)
-# define SQLITE_ENABLE_FTS3
+# define SQLITE_ENABLE_FTS3 1
#endif
/*
@@ -11676,6 +13993,9 @@ SQLITE_PRIVATE int sqlite3CantopenError(int);
# define sqlite3Isxdigit(x) isxdigit((unsigned char)(x))
# define sqlite3Tolower(x) tolower((unsigned char)(x))
#endif
+#ifndef SQLITE_OMIT_COMPILEOPTION_DIAGS
+SQLITE_PRIVATE int sqlite3IsIdChar(u8);
+#endif
/*
** Internal function prototypes
@@ -11686,15 +14006,15 @@ SQLITE_PRIVATE int sqlite3Strlen30(const char*);
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 void *sqlite3Malloc(u64);
+SQLITE_PRIVATE void *sqlite3MallocZero(u64);
+SQLITE_PRIVATE void *sqlite3DbMallocZero(sqlite3*, u64);
+SQLITE_PRIVATE void *sqlite3DbMallocRaw(sqlite3*, u64);
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 char *sqlite3DbStrNDup(sqlite3*,const char*, u64);
+SQLITE_PRIVATE void *sqlite3Realloc(void*, u64);
+SQLITE_PRIVATE void *sqlite3DbReallocOrFree(sqlite3 *, void *, u64);
+SQLITE_PRIVATE void *sqlite3DbRealloc(sqlite3 *, void *, u64);
SQLITE_PRIVATE void sqlite3DbFree(sqlite3*, void*);
SQLITE_PRIVATE int sqlite3MallocSize(void*);
SQLITE_PRIVATE int sqlite3DbMallocSize(sqlite3*, void*);
@@ -11703,7 +14023,9 @@ SQLITE_PRIVATE void sqlite3ScratchFree(void*);
SQLITE_PRIVATE void *sqlite3PageMalloc(int);
SQLITE_PRIVATE void sqlite3PageFree(void*);
SQLITE_PRIVATE void sqlite3MemSetDefault(void);
+#ifndef SQLITE_OMIT_BUILTIN_TEST
SQLITE_PRIVATE void sqlite3BenignMallocHooks(void (*)(void), void (*)(void));
+#endif
SQLITE_PRIVATE int sqlite3HeapNearlyFull(void);
/*
@@ -11739,10 +14061,20 @@ SQLITE_PRIVATE sqlite3_mutex *sqlite3MutexAlloc(int);
SQLITE_PRIVATE int sqlite3MutexInit(void);
SQLITE_PRIVATE int sqlite3MutexEnd(void);
#endif
+#if !defined(SQLITE_MUTEX_OMIT) && !defined(SQLITE_MUTEX_NOOP)
+SQLITE_PRIVATE void sqlite3MemoryBarrier(void);
+#else
+# define sqlite3MemoryBarrier()
+#endif
+
+SQLITE_PRIVATE sqlite3_int64 sqlite3StatusValue(int);
+SQLITE_PRIVATE void sqlite3StatusUp(int, int);
+SQLITE_PRIVATE void sqlite3StatusDown(int, int);
+SQLITE_PRIVATE void sqlite3StatusHighwater(int, int);
-SQLITE_PRIVATE int sqlite3StatusValue(int);
-SQLITE_PRIVATE void sqlite3StatusAdd(int, int);
-SQLITE_PRIVATE void sqlite3StatusSet(int, int);
+/* Access to mutexes used by sqlite3_status() */
+SQLITE_PRIVATE sqlite3_mutex *sqlite3Pcache1Mutex(void);
+SQLITE_PRIVATE sqlite3_mutex *sqlite3MallocMutex(void);
#ifndef SQLITE_OMIT_FLOATING_POINT
SQLITE_PRIVATE int sqlite3IsNaN(double);
@@ -11750,43 +14082,38 @@ SQLITE_PRIVATE int sqlite3IsNaN(double);
# 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
+/*
+** An instance of the following structure holds information about SQL
+** functions arguments that are the parameters to the printf() function.
+*/
+struct PrintfArguments {
+ int nArg; /* Total number of arguments */
+ int nUsed; /* Number of arguments used so far */
+ sqlite3_value **apArg; /* The argument values */
+};
+
+#define SQLITE_PRINTF_INTERNAL 0x01
+#define SQLITE_PRINTF_SQLFUNC 0x02
+SQLITE_PRIVATE void sqlite3VXPrintf(StrAccum*, u32, const char*, va_list);
+SQLITE_PRIVATE void sqlite3XPrintf(StrAccum*, u32, const char*, ...);
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)
+#if defined(SQLITE_DEBUG) || defined(SQLITE_HAVE_OS_TRACE)
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
+#if defined(SQLITE_DEBUG)
+SQLITE_PRIVATE void sqlite3TreeViewExpr(TreeView*, const Expr*, u8);
+SQLITE_PRIVATE void sqlite3TreeViewExprList(TreeView*, const ExprList*, u8, const char*);
+SQLITE_PRIVATE void sqlite3TreeViewSelect(TreeView*, const Select*, u8);
+SQLITE_PRIVATE void sqlite3TreeViewWith(TreeView*, const With*, u8);
#endif
-SQLITE_PRIVATE void sqlite3SetString(char **, sqlite3*, const char*, ...);
+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);
@@ -11806,9 +14133,11 @@ 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 sqlite3ExprListSetSortOrder(ExprList*,int);
SQLITE_PRIVATE void sqlite3ExprListSetName(Parse*,ExprList*,Token*,int);
SQLITE_PRIVATE void sqlite3ExprListSetSpan(Parse*,ExprList*,ExprSpan*);
SQLITE_PRIVATE void sqlite3ExprListDelete(sqlite3*, ExprList*);
+SQLITE_PRIVATE u32 sqlite3ExprListFlags(const ExprList*);
SQLITE_PRIVATE int sqlite3Init(sqlite3*, char**);
SQLITE_PRIVATE int sqlite3InitCallback(void*, int, char**, char**);
SQLITE_PRIVATE void sqlite3Pragma(Parse*,Token*,Token*,Token*,int);
@@ -11817,9 +14146,18 @@ SQLITE_PRIVATE void sqlite3ResetOneSchema(sqlite3*,int);
SQLITE_PRIVATE void sqlite3CollapseDatabaseArray(sqlite3*);
SQLITE_PRIVATE void sqlite3BeginParse(Parse*,int);
SQLITE_PRIVATE void sqlite3CommitInternalChanges(sqlite3*);
+SQLITE_PRIVATE void sqlite3DeleteColumnNames(sqlite3*,Table*);
+SQLITE_PRIVATE int sqlite3ColumnsFromExprList(Parse*,ExprList*,i16*,Column**);
SQLITE_PRIVATE Table *sqlite3ResultSetOfSelect(Parse*,Select*);
SQLITE_PRIVATE void sqlite3OpenMasterTable(Parse *, int);
+SQLITE_PRIVATE Index *sqlite3PrimaryKeyIndex(Table*);
+SQLITE_PRIVATE i16 sqlite3ColumnOfIndex(Index*, i16);
SQLITE_PRIVATE void sqlite3StartTable(Parse*,Token*,Token*,int,int,int,int);
+#if SQLITE_ENABLE_HIDDEN_COLUMNS
+SQLITE_PRIVATE void sqlite3ColumnPropertiesFromName(Table*, Column*);
+#else
+# define sqlite3ColumnPropertiesFromName(T,C) /* no-op */
+#endif
SQLITE_PRIVATE void sqlite3AddColumn(Parse*,Token*);
SQLITE_PRIVATE void sqlite3AddNotNull(Parse*, int);
SQLITE_PRIVATE void sqlite3AddPrimaryKey(Parse*, ExprList*, int, int, int);
@@ -11827,27 +14165,36 @@ 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 void sqlite3EndTable(Parse*,Token*,Token*,u8,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 *);
+#ifdef SQLITE_OMIT_BUILTIN_TEST
+# define sqlite3FaultSim(X) SQLITE_OK
+#else
+SQLITE_PRIVATE int sqlite3FaultSim(int);
+#endif
+
SQLITE_PRIVATE Bitvec *sqlite3BitvecCreate(u32);
SQLITE_PRIVATE int sqlite3BitvecTest(Bitvec*, u32);
+SQLITE_PRIVATE int sqlite3BitvecTestNotNull(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*);
+#ifndef SQLITE_OMIT_BUILTIN_TEST
SQLITE_PRIVATE int sqlite3BitvecBuiltinTest(int,int*);
+#endif
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 sqlite3RowSetTest(RowSet*, int iBatch, i64);
SQLITE_PRIVATE int sqlite3RowSetNext(RowSet*, i64*);
-SQLITE_PRIVATE void sqlite3CreateView(Parse*,Token*,Token*,Token*,Select*,int,int);
+SQLITE_PRIVATE void sqlite3CreateView(Parse*,Token*,Token*,Token*,ExprList*,Select*,int,int);
#if !defined(SQLITE_OMIT_VIEW) || !defined(SQLITE_OMIT_VIRTUALTABLE)
SQLITE_PRIVATE int sqlite3ViewGetColumnNames(Parse*,Table*);
@@ -11855,6 +14202,9 @@ SQLITE_PRIVATE int sqlite3ViewGetColumnNames(Parse*,Table*);
# define sqlite3ViewGetColumnNames(A,B) 0
#endif
+#if SQLITE_MAX_ATTACHED>30
+SQLITE_PRIVATE int sqlite3DbMaskAllZero(yDbMask);
+#endif
SQLITE_PRIVATE void sqlite3DropTable(Parse*, SrcList*, int, int);
SQLITE_PRIVATE void sqlite3CodeDropTable(Parse*, Table*, int, int);
SQLITE_PRIVATE void sqlite3DeleteTable(sqlite3*, Table*);
@@ -11865,8 +14215,7 @@ SQLITE_PRIVATE void sqlite3AutoincrementEnd(Parse *pParse);
# 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 sqlite3Insert(Parse*, SrcList*, 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*);
@@ -11875,45 +14224,65 @@ 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 void sqlite3SrcListFuncArgs(Parse*, SrcList*, ExprList*);
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 *sqlite3AllocateIndexObject(sqlite3*,i16,int,char**);
SQLITE_PRIVATE Index *sqlite3CreateIndex(Parse*,Token*,Token*,SrcList*,ExprList*,int,Token*,
- Token*, int, int);
+ Expr*, 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*);
+ Expr*,ExprList*,u16,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 *);
+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 u64 sqlite3WhereOutputRowCount(WhereInfo*);
+SQLITE_PRIVATE int sqlite3WhereIsDistinct(WhereInfo*);
+SQLITE_PRIVATE int sqlite3WhereIsOrdered(WhereInfo*);
+SQLITE_PRIVATE int sqlite3WhereIsSorted(WhereInfo*);
+SQLITE_PRIVATE int sqlite3WhereContinueLabel(WhereInfo*);
+SQLITE_PRIVATE int sqlite3WhereBreakLabel(WhereInfo*);
+SQLITE_PRIVATE int sqlite3WhereOkOnePass(WhereInfo*, int*);
+#define ONEPASS_OFF 0 /* Use of ONEPASS not allowed */
+#define ONEPASS_SINGLE 1 /* ONEPASS valid for a single row update */
+#define ONEPASS_MULTI 2 /* ONEPASS is valid for multiple rows */
+SQLITE_PRIVATE void sqlite3ExprCodeLoadIndexColumn(Parse*, Index*, int, int, int);
SQLITE_PRIVATE int sqlite3ExprCodeGetColumn(Parse*, Table*, int, int, int, u8);
+SQLITE_PRIVATE void sqlite3ExprCodeGetColumnToReg(Parse*, Table*, int, int, int);
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 sqlite3ExprCachePop(Parse*);
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 void sqlite3ExprCode(Parse*, Expr*, int);
+SQLITE_PRIVATE void sqlite3ExprCodeCopy(Parse*, Expr*, int);
+SQLITE_PRIVATE void sqlite3ExprCodeFactorable(Parse*, Expr*, int);
+SQLITE_PRIVATE void sqlite3ExprCodeAtInit(Parse*, Expr*, int, u8);
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 sqlite3ExprCodeAndCache(Parse*, Expr*, int);
+SQLITE_PRIVATE int sqlite3ExprCodeExprList(Parse*, ExprList*, int, int, u8);
+#define SQLITE_ECEL_DUP 0x01 /* Deep, not shallow copies */
+#define SQLITE_ECEL_FACTOR 0x02 /* Factor out constant terms */
+#define SQLITE_ECEL_REF 0x04 /* Use ExprList.u.x.iOrderByCol */
SQLITE_PRIVATE void sqlite3ExprIfTrue(Parse*, Expr*, int, int);
SQLITE_PRIVATE void sqlite3ExprIfFalse(Parse*, Expr*, int, int);
+SQLITE_PRIVATE void sqlite3ExprIfFalseDup(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 *);
@@ -11923,15 +14292,17 @@ 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 int sqlite3ExprCompare(Expr*, Expr*, int);
+SQLITE_PRIVATE int sqlite3ExprListCompare(ExprList*, ExprList*, int);
+SQLITE_PRIVATE int sqlite3ExprImpliesExpr(Expr*, Expr*, int);
SQLITE_PRIVATE void sqlite3ExprAnalyzeAggregates(NameContext*, Expr*);
SQLITE_PRIVATE void sqlite3ExprAnalyzeAggList(NameContext*,ExprList*);
SQLITE_PRIVATE int sqlite3FunctionUsesThisSrc(Expr*, SrcList*);
SQLITE_PRIVATE Vdbe *sqlite3GetVdbe(Parse*);
+#ifndef SQLITE_OMIT_BUILTIN_TEST
SQLITE_PRIVATE void sqlite3PrngSaveState(void);
SQLITE_PRIVATE void sqlite3PrngRestoreState(void);
-SQLITE_PRIVATE void sqlite3PrngResetState(void);
+#endif
SQLITE_PRIVATE void sqlite3RollbackAll(sqlite3*,int);
SQLITE_PRIVATE void sqlite3CodeVerifySchema(Parse*, int);
SQLITE_PRIVATE void sqlite3CodeVerifyNamedSchema(Parse*, const char *zDb);
@@ -11943,28 +14314,40 @@ 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 sqlite3ExprIsConstantOrFunction(Expr*, u8);
+SQLITE_PRIVATE int sqlite3ExprIsTableConstant(Expr*,int);
+#ifdef SQLITE_ENABLE_CURSOR_HINTS
+SQLITE_PRIVATE int sqlite3ExprContainsSubquery(Expr*);
+#endif
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 sqlite3GenerateRowDelete(
+ Parse*,Table*,Trigger*,int,int,int,i16,u8,u8,u8,int);
+SQLITE_PRIVATE void sqlite3GenerateRowIndexDelete(Parse*, Table*, int, int, int*, int);
+SQLITE_PRIVATE int sqlite3GenerateIndexKey(Parse*, Index*, int, int, int, int*,Index*,int);
+SQLITE_PRIVATE void sqlite3ResolvePartIdxLabel(Parse*,int);
+SQLITE_PRIVATE void sqlite3GenerateConstraintChecks(Parse*,Table*,int*,int,int,int,int,
+ u8,u8,int,int*);
+SQLITE_PRIVATE void sqlite3CompleteInsertion(Parse*,Table*,int,int,int,int*,int,int,int);
+SQLITE_PRIVATE int sqlite3OpenTableAndIndices(Parse*, Table*, int, u8, int, u8*, 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 void sqlite3HaltConstraint(Parse*, int, int, char*, i8, u8);
+SQLITE_PRIVATE void sqlite3UniqueConstraint(Parse*, int, Index*);
+SQLITE_PRIVATE void sqlite3RowidConstraint(Parse*, int, Table*);
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);
+#if SELECTTRACE_ENABLED
+SQLITE_PRIVATE void sqlite3SelectSetName(Select*,const char*);
+#else
+# define sqlite3SelectSetName(A,B)
+#endif
SQLITE_PRIVATE void sqlite3FuncDefInsert(FuncDefHash*, FuncDef*);
SQLITE_PRIVATE FuncDef *sqlite3FindFunction(sqlite3*,const char*,int,int,u8,u8);
SQLITE_PRIVATE void sqlite3RegisterBuiltinFunctions(sqlite3*);
@@ -11993,13 +14376,14 @@ SQLITE_PRIVATE void sqlite3CodeRowTriggerDirect(Parse *, Trigger *, Table *, i
SQLITE_PRIVATE void sqlite3DeleteTriggerStep(sqlite3*, TriggerStep*);
SQLITE_PRIVATE TriggerStep *sqlite3TriggerSelectStep(sqlite3*,Select*);
SQLITE_PRIVATE TriggerStep *sqlite3TriggerInsertStep(sqlite3*,Token*, IdList*,
- ExprList*,Select*,u8);
+ 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))
+# define sqlite3IsToplevel(p) ((p)->pToplevel==0)
#else
# define sqlite3TriggersExist(B,C,D,E,F) 0
# define sqlite3DeleteTrigger(A,B)
@@ -12009,6 +14393,7 @@ SQLITE_PRIVATE u32 sqlite3TriggerColmask(Parse*,Trigger*,ExprList*,int,int,Tab
# define sqlite3CodeRowTriggerDirect(A,B,C,D,E,F)
# define sqlite3TriggerList(X, Y) 0
# define sqlite3ParseToplevel(p) p
+# define sqlite3IsToplevel(p) 1
# define sqlite3TriggerColmask(A,B,C,D,E,F,G) 0
#endif
@@ -12029,7 +14414,7 @@ SQLITE_PRIVATE int sqlite3AuthReadCol(Parse*, const char *, const char *, int)
#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 void 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*);
@@ -12041,59 +14426,60 @@ 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**);
+SQLITE_PRIVATE LogEst sqlite3LogEst(u64);
+SQLITE_PRIVATE LogEst sqlite3LogEstAdd(LogEst,LogEst);
+#ifndef SQLITE_OMIT_VIRTUALTABLE
+SQLITE_PRIVATE LogEst sqlite3LogEstFromDouble(double);
+#endif
+SQLITE_PRIVATE u64 sqlite3LogEstToInt(LogEst);
/*
** 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).
+** file.
*/
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 );
-**
+** The common case is for a varint to be a single byte. They following
+** macros handle the common case without a procedure call, but then call
+** the procedure for larger varints.
*/
-#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 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:\
+ sqlite3PutVarint((A),(B)))
#define getVarint sqlite3GetVarint
#define putVarint sqlite3PutVarint
-SQLITE_PRIVATE const char *sqlite3IndexAffinityStr(Vdbe *, Index *);
-SQLITE_PRIVATE void sqlite3TableAffinityStr(Vdbe *, Table *);
+SQLITE_PRIVATE const char *sqlite3IndexAffinityStr(sqlite3*, Index*);
+SQLITE_PRIVATE void sqlite3TableAffinity(Vdbe*, Table*, int);
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 int sqlite3DecOrHexToI64(const char*, i64*);
+SQLITE_PRIVATE void sqlite3ErrorWithMsg(sqlite3*, int, const char*,...);
+SQLITE_PRIVATE void sqlite3Error(sqlite3*,int);
SQLITE_PRIVATE void *sqlite3HexToBlob(sqlite3*, const char *z, int n);
SQLITE_PRIVATE u8 sqlite3HexToInt(int h);
SQLITE_PRIVATE int sqlite3TwoPartName(Parse *, Token *, Token *, Token **);
+
+#if defined(SQLITE_NEED_ERR_NAME)
+SQLITE_PRIVATE const char *sqlite3ErrName(int);
+#endif
+
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 *sqlite3ExprAddCollateToken(Parse *pParse, Expr*, const Token*, int);
SQLITE_PRIVATE Expr *sqlite3ExprAddCollateString(Parse*,Expr*,const char*);
SQLITE_PRIVATE Expr *sqlite3ExprSkipCollate(Expr*);
SQLITE_PRIVATE int sqlite3CheckCollSeq(Parse *, CollSeq *);
@@ -12108,22 +14494,21 @@ SQLITE_PRIVATE void sqlite3FileSuffix3(const char*, char*);
#else
# define sqlite3FileSuffix3(X,Y)
#endif
-SQLITE_PRIVATE u8 sqlite3GetBoolean(const char *z,int);
+SQLITE_PRIVATE u8 sqlite3GetBoolean(const char *z,u8);
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 sqlite3ValueSetNull(sqlite3_value*);
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 char sqlite3StrBINARY[];
SQLITE_PRIVATE const unsigned char sqlite3UpperToLower[];
SQLITE_PRIVATE const unsigned char sqlite3CtypeMap[];
SQLITE_PRIVATE const Token sqlite3IntTokens[];
@@ -12142,14 +14527,18 @@ 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 void sqlite3SelectWrongNumTermsError(Parse *pParse, Select *p);
+SQLITE_PRIVATE int sqlite3MatchSpanName(const char*, const char*, const char*, const char*);
SQLITE_PRIVATE int sqlite3ResolveExprNames(NameContext*, Expr*);
+SQLITE_PRIVATE int sqlite3ResolveExprListNames(NameContext*, ExprList*);
SQLITE_PRIVATE void sqlite3ResolveSelectNames(Parse*, Select*, NameContext*);
+SQLITE_PRIVATE void sqlite3ResolveSelfReference(Parse*,Table*,int,Expr*,ExprList*);
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 char sqlite3AffinityType(const char*, u8*);
SQLITE_PRIVATE void sqlite3Analyze(Parse*, Token*, Token*);
SQLITE_PRIVATE int sqlite3InvokeBusyHandler(BusyHandler*);
SQLITE_PRIVATE int sqlite3FindDb(sqlite3*, Token*);
@@ -12163,7 +14552,13 @@ 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 KeyInfo *sqlite3KeyInfoAlloc(sqlite3*,int,int);
+SQLITE_PRIVATE void sqlite3KeyInfoUnref(KeyInfo*);
+SQLITE_PRIVATE KeyInfo *sqlite3KeyInfoRef(KeyInfo*);
+SQLITE_PRIVATE KeyInfo *sqlite3KeyInfoOfIndex(Parse*, Index*);
+#ifdef SQLITE_DEBUG
+SQLITE_PRIVATE int sqlite3KeyInfoIsWriteable(KeyInfo*);
+#endif
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*),
@@ -12172,9 +14567,10 @@ SQLITE_PRIVATE int sqlite3CreateFunc(sqlite3 *, const char *, int, int, void *,
SQLITE_PRIVATE int sqlite3ApiExit(sqlite3 *db, int);
SQLITE_PRIVATE int sqlite3OpenTempDatabase(Parse *);
-SQLITE_PRIVATE void sqlite3StrAccumInit(StrAccum*, char*, int, int);
+SQLITE_PRIVATE void sqlite3StrAccumInit(StrAccum*, sqlite3*, char*, int, int);
SQLITE_PRIVATE void sqlite3StrAccumAppend(StrAccum*,const char*,int);
-SQLITE_PRIVATE void sqlite3AppendSpace(StrAccum*,int);
+SQLITE_PRIVATE void sqlite3StrAccumAppendAll(StrAccum*,const char*);
+SQLITE_PRIVATE void sqlite3AppendChar(StrAccum*,int,char);
SQLITE_PRIVATE char *sqlite3StrAccumFinish(StrAccum*);
SQLITE_PRIVATE void sqlite3StrAccumReset(StrAccum*);
SQLITE_PRIVATE void sqlite3SelectDestInit(SelectDest*,int,int);
@@ -12183,10 +14579,18 @@ SQLITE_PRIVATE Expr *sqlite3CreateColumnExpr(sqlite3 *, SrcList *, int, int);
SQLITE_PRIVATE void sqlite3BackupRestart(sqlite3_backup *);
SQLITE_PRIVATE void sqlite3BackupUpdate(sqlite3_backup *, Pgno, const u8 *);
+#ifdef SQLITE_ENABLE_STAT3_OR_STAT4
+SQLITE_PRIVATE void sqlite3AnalyzeFunctions(void);
+SQLITE_PRIVATE int sqlite3Stat4ProbeSetValue(Parse*,Index*,UnpackedRecord**,Expr*,u8,int,int*);
+SQLITE_PRIVATE int sqlite3Stat4ValueFromExpr(Parse*, Expr*, u8, sqlite3_value**);
+SQLITE_PRIVATE void sqlite3Stat4ProbeFree(UnpackedRecord*);
+SQLITE_PRIVATE int sqlite3Stat4Column(sqlite3*, const void*, int, int, sqlite3_value**);
+#endif
+
/*
** The interface to the LEMON-generated parser
*/
-SQLITE_PRIVATE void *sqlite3ParserAlloc(void*(*)(size_t));
+SQLITE_PRIVATE void *sqlite3ParserAlloc(void*(*)(u64));
SQLITE_PRIVATE void sqlite3ParserFree(void*, void(*)(void*));
SQLITE_PRIVATE void sqlite3Parser(void*, int, Token, Parse*);
#ifdef YYTRACKMAXSTACKDEPTH
@@ -12224,16 +14628,19 @@ SQLITE_PRIVATE int sqlite3Utf8To8(unsigned char*);
#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 sqlite3VtabSync(sqlite3 *db, Vdbe*);
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 void sqlite3VtabImportErrmsg(Vdbe*, sqlite3_vtab*);
SQLITE_PRIVATE VTable *sqlite3GetVTable(sqlite3*, Table*);
# define sqlite3VtabInSync(db) ((db)->nVTrans>0 && (db)->aVTrans==0)
#endif
+SQLITE_PRIVATE int sqlite3VtabEponymousTableInit(Parse*,Module*);
+SQLITE_PRIVATE void sqlite3VtabEponymousTableClear(sqlite3*,Module*);
SQLITE_PRIVATE void sqlite3VtabMakeWritable(Parse*,Table*);
SQLITE_PRIVATE void sqlite3VtabBeginParse(Parse*, Token*, Token*, Token*, int);
SQLITE_PRIVATE void sqlite3VtabFinishParse(Parse*, Token*);
@@ -12245,8 +14652,10 @@ 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 sqlite3_int64 sqlite3StmtCurrentTime(sqlite3_context*);
SQLITE_PRIVATE int sqlite3VdbeParameterIndex(Vdbe*, const char*, int);
SQLITE_PRIVATE int sqlite3TransferBindings(sqlite3_stmt *, sqlite3_stmt *);
+SQLITE_PRIVATE void sqlite3ParserReset(Parse*);
SQLITE_PRIVATE int sqlite3Reprepare(Vdbe*);
SQLITE_PRIVATE void sqlite3ExprListCheckLength(Parse*, ExprList*, const char*);
SQLITE_PRIVATE CollSeq *sqlite3BinaryCompareCollSeq(Parse *, Expr *, Expr *);
@@ -12256,6 +14665,14 @@ SQLITE_PRIVATE const char *sqlite3JournalModename(int);
SQLITE_PRIVATE int sqlite3Checkpoint(sqlite3*, int, int, int*, int*);
SQLITE_PRIVATE int sqlite3WalDefaultHook(void*,sqlite3*,const char*,int);
#endif
+#ifndef SQLITE_OMIT_CTE
+SQLITE_PRIVATE With *sqlite3WithAdd(Parse*,With*,Token*,ExprList*,Select*);
+SQLITE_PRIVATE void sqlite3WithDelete(sqlite3*,With*);
+SQLITE_PRIVATE void sqlite3WithPush(Parse*, With*, u8);
+#else
+#define sqlite3WithPush(x,y,z)
+#define sqlite3WithDelete(x,y)
+#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
@@ -12265,23 +14682,25 @@ SQLITE_PRIVATE int sqlite3WalDefaultHook(void*,sqlite3*,const char*,int);
** 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 sqlite3FkCheck(Parse*, Table*, int, int, int*, int);
SQLITE_PRIVATE void sqlite3FkDropTable(Parse*, SrcList *, Table*);
-SQLITE_PRIVATE void sqlite3FkActions(Parse*, Table*, ExprList*, int);
+SQLITE_PRIVATE void sqlite3FkActions(Parse*, Table*, ExprList*, int, int*, 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 sqlite3FkActions(a,b,c,d,e,f)
+ #define sqlite3FkCheck(a,b,c,d,e,f)
#define sqlite3FkDropTable(a,b,c)
- #define sqlite3FkOldmask(a,b) 0
- #define sqlite3FkRequired(a,b,c,d) 0
+ #define sqlite3FkOldmask(a,b) 0
+ #define sqlite3FkRequired(a,b,c,d) 0
#endif
#ifndef SQLITE_OMIT_FOREIGN_KEY
SQLITE_PRIVATE void sqlite3FkDelete(sqlite3 *, Table*);
+SQLITE_PRIVATE int sqlite3FkLocateIndex(Parse*,Table*,FKey*,Index**,int**);
#else
#define sqlite3FkDelete(a,b)
+ #define sqlite3FkLocateIndex(a,b,c,d,e)
#endif
@@ -12304,10 +14723,21 @@ SQLITE_PRIVATE void sqlite3EndBenignMalloc(void);
#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*);
+/*
+** Allowed return values from sqlite3FindInIndex()
+*/
+#define IN_INDEX_ROWID 1 /* Search the rowid of the table */
+#define IN_INDEX_EPH 2 /* Search an ephemeral b-tree */
+#define IN_INDEX_INDEX_ASC 3 /* Existing index ASCENDING */
+#define IN_INDEX_INDEX_DESC 4 /* Existing index DESCENDING */
+#define IN_INDEX_NOOP 5 /* No table available. Use comparisons */
+/*
+** Allowed flags for the 3rd parameter to sqlite3FindInIndex().
+*/
+#define IN_INDEX_NOOP_OK 0x0001 /* OK to return IN_INDEX_NOOP */
+#define IN_INDEX_MEMBERSHIP 0x0002 /* IN operator used for membership test */
+#define IN_INDEX_LOOP 0x0004 /* IN operator used as a loop */
+SQLITE_PRIVATE int sqlite3FindInIndex(Parse *, Expr *, u32, int*);
#ifdef SQLITE_ENABLE_ATOMIC_WRITE
SQLITE_PRIVATE int sqlite3JournalOpen(sqlite3_vfs *, const char *, sqlite3_file *, int, int);
@@ -12323,12 +14753,11 @@ SQLITE_PRIVATE void sqlite3MemJournalOpen(sqlite3_file *);
SQLITE_PRIVATE int sqlite3MemJournalSize(void);
SQLITE_PRIVATE int sqlite3IsMemJournal(sqlite3_file *);
+SQLITE_PRIVATE void sqlite3ExprSetHeightAndFlags(Parse *pParse, Expr *p);
#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
@@ -12358,7 +14787,7 @@ SQLITE_PRIVATE void sqlite3ParserTrace(FILE*, char *);
#ifdef SQLITE_ENABLE_IOTRACE
# define IOTRACE(A) if( sqlite3IoTrace ){ sqlite3IoTrace A; }
SQLITE_PRIVATE void sqlite3VdbeIOTraceSql(Vdbe*);
-SQLITE_PRIVATE void (*sqlite3IoTrace)(const char*,...);
+SQLITE_API SQLITE_EXTERN void (SQLITE_CDECL *sqlite3IoTrace)(const char*,...);
#else
# define IOTRACE(A)
# define sqlite3VdbeIOTraceSql(X)
@@ -12402,10 +14831,21 @@ SQLITE_PRIVATE int sqlite3MemdebugNoType(void*,u8);
# define sqlite3MemdebugNoType(X,Y) 1
#endif
#define MEMTYPE_HEAP 0x01 /* General heap allocations */
-#define MEMTYPE_LOOKASIDE 0x02 /* Might have been lookaside memory */
+#define MEMTYPE_LOOKASIDE 0x02 /* Heap that might have been lookaside */
#define MEMTYPE_SCRATCH 0x04 /* Scratch allocations */
#define MEMTYPE_PCACHE 0x08 /* Page cache allocations */
-#define MEMTYPE_DB 0x10 /* Uses sqlite3DbMalloc, not sqlite_malloc */
+
+/*
+** Threading interface
+*/
+#if SQLITE_MAX_WORKER_THREADS>0
+SQLITE_PRIVATE int sqlite3ThreadCreate(SQLiteThread**,void*(*)(void*),void*);
+SQLITE_PRIVATE int sqlite3ThreadJoin(SQLiteThread*, void**);
+#endif
+
+#if defined(SQLITE_ENABLE_DBSTAT_VTAB) || defined(SQLITE_TEST)
+SQLITE_PRIVATE int sqlite3DbstatRegister(sqlite3*);
+#endif
#endif /* _SQLITEINT_H_ */
@@ -12423,8 +14863,9 @@ SQLITE_PRIVATE int sqlite3MemdebugNoType(void*,u8);
**
*************************************************************************
**
-** This file contains definitions of global variables and contants.
+** This file contains definitions of global variables and constants.
*/
+/* #include "sqliteInt.h" */
/* An array to map all upper-case characters into their corresponding
** lower-case character.
@@ -12458,16 +14899,16 @@ SQLITE_PRIVATE const unsigned char sqlite3UpperToLower[] = {
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 */
+ 96, 97, 98, 99,100,101,102,103,104,105,106,107,108,109,110,111, /* 6x */
+ 112,113,114,115,116,117,118,119,120,121,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 */
+ 144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,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 */
+ 224,225,162,163,164,165,166,167,168,169,234,235,236,237,238,239, /* Ex */
+ 240,241,242,243,244,245,246,247,248,249,250,251,252,253,254,255, /* Fx */
#endif
};
@@ -12541,14 +14982,36 @@ SQLITE_PRIVATE const unsigned char sqlite3CtypeMap[256] = {
};
#endif
+/* EVIDENCE-OF: R-02982-34736 In order to maintain full backwards
+** compatibility for legacy applications, the URI filename capability is
+** disabled by default.
+**
+** EVIDENCE-OF: R-38799-08373 URI filenames can be enabled or disabled
+** using the SQLITE_USE_URI=1 or SQLITE_USE_URI=0 compile-time options.
+**
+** EVIDENCE-OF: R-43642-56306 By default, URI handling is globally
+** disabled. The default value may be changed by compiling with the
+** SQLITE_USE_URI symbol defined.
+*/
#ifndef SQLITE_USE_URI
# define SQLITE_USE_URI 0
#endif
+/* EVIDENCE-OF: R-38720-18127 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.
+*/
#ifndef SQLITE_ALLOW_COVERING_INDEX_SCAN
# define SQLITE_ALLOW_COVERING_INDEX_SCAN 1
#endif
+/* The minimum PMA size is set to this value multiplied by the database
+** page size in bytes.
+*/
+#ifndef SQLITE_SORTER_PMASZ
+# define SQLITE_SORTER_PMASZ 250
+#endif
+
/*
** The following singleton contains the global configuration for
** the SQLite library.
@@ -12560,6 +15023,7 @@ SQLITE_PRIVATE SQLITE_WSD struct Sqlite3Config sqlite3Config = {
SQLITE_USE_URI, /* bOpenUri */
SQLITE_ALLOW_COVERING_INDEX_SCAN, /* bUseCis */
0x7ffffffe, /* mxStrlen */
+ 0, /* neverCorrupt */
128, /* szLookaside */
500, /* nLookaside */
{0,0,0,0,0,0,0,0}, /* m */
@@ -12568,32 +15032,41 @@ SQLITE_PRIVATE SQLITE_WSD struct Sqlite3Config sqlite3Config = {
(void*)0, /* pHeap */
0, /* nHeap */
0, 0, /* mnHeap, mxHeap */
+ SQLITE_DEFAULT_MMAP_SIZE, /* szMmap */
+ SQLITE_MAX_MMAP_SIZE, /* mxMmap */
(void*)0, /* pScratch */
0, /* szScratch */
0, /* nScratch */
(void*)0, /* pPage */
0, /* szPage */
- 0, /* nPage */
+ SQLITE_DEFAULT_PCACHE_INITSZ, /* nPage */
0, /* mxParserStack */
0, /* sharedCacheEnabled */
+ SQLITE_SORTER_PMASZ, /* szPma */
/* All the rest should always be initialized to zero */
0, /* isInit */
0, /* inProgress */
0, /* isMutexInit */
0, /* isMallocInit */
0, /* isPCacheInit */
- 0, /* pInitMutex */
0, /* nRefInitMutex */
+ 0, /* pInitMutex */
0, /* xLog */
0, /* pLogArg */
- 0, /* bLocaltimeFault */
#ifdef SQLITE_ENABLE_SQLLOG
0, /* xSqllog */
- 0 /* pSqllogArg */
+ 0, /* pSqllogArg */
+#endif
+#ifdef SQLITE_VDBE_COVERAGE
+ 0, /* xVdbeBranch */
+ 0, /* pVbeBranchArg */
+#endif
+#ifndef SQLITE_OMIT_BUILTIN_TEST
+ 0, /* xTestCallback */
#endif
+ 0 /* bLocaltimeFault */
};
-
/*
** Hash table for global functions - functions common to all
** database connections. After initialization, this table is
@@ -12625,13 +15098,14 @@ SQLITE_PRIVATE const Token sqlite3IntTokens[] = {
**
** 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.
+** Changing the pending byte during operation will result in undefined
+** and incorrect behavior.
*/
#ifndef SQLITE_OMIT_WSD
SQLITE_PRIVATE int sqlite3PendingByte = 0x40000000;
#endif
+/* #include "opcodes.h" */
/*
** Properties of opcodes. The OPFLG_INITIALIZER macro is
** created by mkopcodeh.awk during compilation. Data is obtained
@@ -12640,6 +15114,11 @@ SQLITE_PRIVATE int sqlite3PendingByte = 0x40000000;
*/
SQLITE_PRIVATE const unsigned char sqlite3OpcodeProperty[] = OPFLG_INITIALIZER;
+/*
+** Name of the default collating sequence
+*/
+SQLITE_PRIVATE const char sqlite3StrBINARY[] = "BINARY";
+
/************** End of global.c **********************************************/
/************** Begin file ctime.c *******************************************/
/*
@@ -12660,6 +15139,7 @@ SQLITE_PRIVATE const unsigned char sqlite3OpcodeProperty[] = OPFLG_INITIALIZER;
#ifndef SQLITE_OMIT_COMPILEOPTION_DIAGS
+/* #include "sqliteInt.h" */
/*
** An array of names of all compile-time options. This array should
@@ -12676,339 +15156,366 @@ static const char * const azCompileOpt[] = {
#define CTIMEOPT_VAL_(opt) #opt
#define CTIMEOPT_VAL(opt) CTIMEOPT_VAL_(opt)
-#ifdef SQLITE_32BIT_ROWID
+#if SQLITE_32BIT_ROWID
"32BIT_ROWID",
#endif
-#ifdef SQLITE_4_BYTE_ALIGNED_MALLOC
+#if SQLITE_4_BYTE_ALIGNED_MALLOC
"4_BYTE_ALIGNED_MALLOC",
#endif
-#ifdef SQLITE_CASE_SENSITIVE_LIKE
+#if SQLITE_CASE_SENSITIVE_LIKE
"CASE_SENSITIVE_LIKE",
#endif
-#ifdef SQLITE_CHECK_PAGES
+#if SQLITE_CHECK_PAGES
"CHECK_PAGES",
#endif
-#ifdef SQLITE_COVERAGE_TEST
+#if SQLITE_COVERAGE_TEST
"COVERAGE_TEST",
#endif
-#ifdef SQLITE_CURDIR
- "CURDIR",
-#endif
-#ifdef SQLITE_DEBUG
+#if SQLITE_DEBUG
"DEBUG",
#endif
-#ifdef SQLITE_DEFAULT_LOCKING_MODE
+#if SQLITE_DEFAULT_LOCKING_MODE
"DEFAULT_LOCKING_MODE=" CTIMEOPT_VAL(SQLITE_DEFAULT_LOCKING_MODE),
#endif
-#ifdef SQLITE_DISABLE_DIRSYNC
+#if defined(SQLITE_DEFAULT_MMAP_SIZE) && !defined(SQLITE_DEFAULT_MMAP_SIZE_xc)
+ "DEFAULT_MMAP_SIZE=" CTIMEOPT_VAL(SQLITE_DEFAULT_MMAP_SIZE),
+#endif
+#if SQLITE_DISABLE_DIRSYNC
"DISABLE_DIRSYNC",
#endif
-#ifdef SQLITE_DISABLE_LFS
+#if SQLITE_DISABLE_LFS
"DISABLE_LFS",
#endif
-#ifdef SQLITE_ENABLE_ATOMIC_WRITE
+#if SQLITE_ENABLE_8_3_NAMES
+ "ENABLE_8_3_NAMES",
+#endif
+#if SQLITE_ENABLE_API_ARMOR
+ "ENABLE_API_ARMOR",
+#endif
+#if SQLITE_ENABLE_ATOMIC_WRITE
"ENABLE_ATOMIC_WRITE",
#endif
-#ifdef SQLITE_ENABLE_CEROD
+#if SQLITE_ENABLE_CEROD
"ENABLE_CEROD",
#endif
-#ifdef SQLITE_ENABLE_COLUMN_METADATA
+#if SQLITE_ENABLE_COLUMN_METADATA
"ENABLE_COLUMN_METADATA",
#endif
-#ifdef SQLITE_ENABLE_EXPENSIVE_ASSERT
+#if SQLITE_ENABLE_DBSTAT_VTAB
+ "ENABLE_DBSTAT_VTAB",
+#endif
+#if SQLITE_ENABLE_EXPENSIVE_ASSERT
"ENABLE_EXPENSIVE_ASSERT",
#endif
-#ifdef SQLITE_ENABLE_FTS1
+#if SQLITE_ENABLE_FTS1
"ENABLE_FTS1",
#endif
-#ifdef SQLITE_ENABLE_FTS2
+#if SQLITE_ENABLE_FTS2
"ENABLE_FTS2",
#endif
-#ifdef SQLITE_ENABLE_FTS3
+#if SQLITE_ENABLE_FTS3
"ENABLE_FTS3",
#endif
-#ifdef SQLITE_ENABLE_FTS3_PARENTHESIS
+#if SQLITE_ENABLE_FTS3_PARENTHESIS
"ENABLE_FTS3_PARENTHESIS",
#endif
-#ifdef SQLITE_ENABLE_FTS4
+#if SQLITE_ENABLE_FTS4
"ENABLE_FTS4",
#endif
-#ifdef SQLITE_ENABLE_ICU
+#if SQLITE_ENABLE_FTS5
+ "ENABLE_FTS5",
+#endif
+#if SQLITE_ENABLE_ICU
"ENABLE_ICU",
#endif
-#ifdef SQLITE_ENABLE_IOTRACE
+#if SQLITE_ENABLE_IOTRACE
"ENABLE_IOTRACE",
#endif
-#ifdef SQLITE_ENABLE_LOAD_EXTENSION
+#if SQLITE_ENABLE_JSON1
+ "ENABLE_JSON1",
+#endif
+#if SQLITE_ENABLE_LOAD_EXTENSION
"ENABLE_LOAD_EXTENSION",
#endif
-#ifdef SQLITE_ENABLE_LOCKING_STYLE
+#if SQLITE_ENABLE_LOCKING_STYLE
"ENABLE_LOCKING_STYLE=" CTIMEOPT_VAL(SQLITE_ENABLE_LOCKING_STYLE),
#endif
-#ifdef SQLITE_ENABLE_MEMORY_MANAGEMENT
+#if SQLITE_ENABLE_MEMORY_MANAGEMENT
"ENABLE_MEMORY_MANAGEMENT",
#endif
-#ifdef SQLITE_ENABLE_MEMSYS3
+#if SQLITE_ENABLE_MEMSYS3
"ENABLE_MEMSYS3",
#endif
-#ifdef SQLITE_ENABLE_MEMSYS5
+#if SQLITE_ENABLE_MEMSYS5
"ENABLE_MEMSYS5",
#endif
-#ifdef SQLITE_ENABLE_OVERSIZE_CELL_CHECK
+#if SQLITE_ENABLE_OVERSIZE_CELL_CHECK
"ENABLE_OVERSIZE_CELL_CHECK",
#endif
-#ifdef SQLITE_ENABLE_RTREE
+#if SQLITE_ENABLE_RTREE
"ENABLE_RTREE",
#endif
-#ifdef SQLITE_ENABLE_STAT3
+#if defined(SQLITE_ENABLE_STAT4)
+ "ENABLE_STAT4",
+#elif defined(SQLITE_ENABLE_STAT3)
"ENABLE_STAT3",
#endif
-#ifdef SQLITE_ENABLE_UNLOCK_NOTIFY
+#if SQLITE_ENABLE_UNLOCK_NOTIFY
"ENABLE_UNLOCK_NOTIFY",
#endif
-#ifdef SQLITE_ENABLE_UPDATE_DELETE_LIMIT
+#if SQLITE_ENABLE_UPDATE_DELETE_LIMIT
"ENABLE_UPDATE_DELETE_LIMIT",
#endif
-#ifdef SQLITE_HAS_CODEC
+#if SQLITE_HAS_CODEC
"HAS_CODEC",
#endif
-#ifdef SQLITE_HAVE_ISNAN
+#if HAVE_ISNAN || SQLITE_HAVE_ISNAN
"HAVE_ISNAN",
#endif
-#ifdef SQLITE_HOMEGROWN_RECURSIVE_MUTEX
+#if SQLITE_HOMEGROWN_RECURSIVE_MUTEX
"HOMEGROWN_RECURSIVE_MUTEX",
#endif
-#ifdef SQLITE_IGNORE_AFP_LOCK_ERRORS
+#if SQLITE_IGNORE_AFP_LOCK_ERRORS
"IGNORE_AFP_LOCK_ERRORS",
#endif
-#ifdef SQLITE_IGNORE_FLOCK_LOCK_ERRORS
+#if SQLITE_IGNORE_FLOCK_LOCK_ERRORS
"IGNORE_FLOCK_LOCK_ERRORS",
#endif
#ifdef SQLITE_INT64_TYPE
"INT64_TYPE",
#endif
-#ifdef SQLITE_LOCK_TRACE
+#ifdef SQLITE_LIKE_DOESNT_MATCH_BLOBS
+ "LIKE_DOESNT_MATCH_BLOBS",
+#endif
+#if SQLITE_LOCK_TRACE
"LOCK_TRACE",
#endif
+#if defined(SQLITE_MAX_MMAP_SIZE) && !defined(SQLITE_MAX_MMAP_SIZE_xc)
+ "MAX_MMAP_SIZE=" CTIMEOPT_VAL(SQLITE_MAX_MMAP_SIZE),
+#endif
#ifdef SQLITE_MAX_SCHEMA_RETRY
"MAX_SCHEMA_RETRY=" CTIMEOPT_VAL(SQLITE_MAX_SCHEMA_RETRY),
#endif
-#ifdef SQLITE_MEMDEBUG
+#if SQLITE_MEMDEBUG
"MEMDEBUG",
#endif
-#ifdef SQLITE_MIXED_ENDIAN_64BIT_FLOAT
+#if SQLITE_MIXED_ENDIAN_64BIT_FLOAT
"MIXED_ENDIAN_64BIT_FLOAT",
#endif
-#ifdef SQLITE_NO_SYNC
+#if SQLITE_NO_SYNC
"NO_SYNC",
#endif
-#ifdef SQLITE_OMIT_ALTERTABLE
+#if SQLITE_OMIT_ALTERTABLE
"OMIT_ALTERTABLE",
#endif
-#ifdef SQLITE_OMIT_ANALYZE
+#if SQLITE_OMIT_ANALYZE
"OMIT_ANALYZE",
#endif
-#ifdef SQLITE_OMIT_ATTACH
+#if SQLITE_OMIT_ATTACH
"OMIT_ATTACH",
#endif
-#ifdef SQLITE_OMIT_AUTHORIZATION
+#if SQLITE_OMIT_AUTHORIZATION
"OMIT_AUTHORIZATION",
#endif
-#ifdef SQLITE_OMIT_AUTOINCREMENT
+#if SQLITE_OMIT_AUTOINCREMENT
"OMIT_AUTOINCREMENT",
#endif
-#ifdef SQLITE_OMIT_AUTOINIT
+#if SQLITE_OMIT_AUTOINIT
"OMIT_AUTOINIT",
#endif
-#ifdef SQLITE_OMIT_AUTOMATIC_INDEX
+#if SQLITE_OMIT_AUTOMATIC_INDEX
"OMIT_AUTOMATIC_INDEX",
#endif
-#ifdef SQLITE_OMIT_AUTORESET
+#if SQLITE_OMIT_AUTORESET
"OMIT_AUTORESET",
#endif
-#ifdef SQLITE_OMIT_AUTOVACUUM
+#if SQLITE_OMIT_AUTOVACUUM
"OMIT_AUTOVACUUM",
#endif
-#ifdef SQLITE_OMIT_BETWEEN_OPTIMIZATION
+#if SQLITE_OMIT_BETWEEN_OPTIMIZATION
"OMIT_BETWEEN_OPTIMIZATION",
#endif
-#ifdef SQLITE_OMIT_BLOB_LITERAL
+#if SQLITE_OMIT_BLOB_LITERAL
"OMIT_BLOB_LITERAL",
#endif
-#ifdef SQLITE_OMIT_BTREECOUNT
+#if SQLITE_OMIT_BTREECOUNT
"OMIT_BTREECOUNT",
#endif
-#ifdef SQLITE_OMIT_BUILTIN_TEST
+#if SQLITE_OMIT_BUILTIN_TEST
"OMIT_BUILTIN_TEST",
#endif
-#ifdef SQLITE_OMIT_CAST
+#if SQLITE_OMIT_CAST
"OMIT_CAST",
#endif
-#ifdef SQLITE_OMIT_CHECK
+#if SQLITE_OMIT_CHECK
"OMIT_CHECK",
#endif
-/* // redundant
-** #ifdef SQLITE_OMIT_COMPILEOPTION_DIAGS
-** "OMIT_COMPILEOPTION_DIAGS",
-** #endif
-*/
-#ifdef SQLITE_OMIT_COMPLETE
+#if SQLITE_OMIT_COMPLETE
"OMIT_COMPLETE",
#endif
-#ifdef SQLITE_OMIT_COMPOUND_SELECT
+#if SQLITE_OMIT_COMPOUND_SELECT
"OMIT_COMPOUND_SELECT",
#endif
-#ifdef SQLITE_OMIT_DATETIME_FUNCS
+#if SQLITE_OMIT_CTE
+ "OMIT_CTE",
+#endif
+#if SQLITE_OMIT_DATETIME_FUNCS
"OMIT_DATETIME_FUNCS",
#endif
-#ifdef SQLITE_OMIT_DECLTYPE
+#if SQLITE_OMIT_DECLTYPE
"OMIT_DECLTYPE",
#endif
-#ifdef SQLITE_OMIT_DEPRECATED
+#if SQLITE_OMIT_DEPRECATED
"OMIT_DEPRECATED",
#endif
-#ifdef SQLITE_OMIT_DISKIO
+#if SQLITE_OMIT_DISKIO
"OMIT_DISKIO",
#endif
-#ifdef SQLITE_OMIT_EXPLAIN
+#if SQLITE_OMIT_EXPLAIN
"OMIT_EXPLAIN",
#endif
-#ifdef SQLITE_OMIT_FLAG_PRAGMAS
+#if SQLITE_OMIT_FLAG_PRAGMAS
"OMIT_FLAG_PRAGMAS",
#endif
-#ifdef SQLITE_OMIT_FLOATING_POINT
+#if SQLITE_OMIT_FLOATING_POINT
"OMIT_FLOATING_POINT",
#endif
-#ifdef SQLITE_OMIT_FOREIGN_KEY
+#if SQLITE_OMIT_FOREIGN_KEY
"OMIT_FOREIGN_KEY",
#endif
-#ifdef SQLITE_OMIT_GET_TABLE
+#if SQLITE_OMIT_GET_TABLE
"OMIT_GET_TABLE",
#endif
-#ifdef SQLITE_OMIT_INCRBLOB
+#if SQLITE_OMIT_INCRBLOB
"OMIT_INCRBLOB",
#endif
-#ifdef SQLITE_OMIT_INTEGRITY_CHECK
+#if SQLITE_OMIT_INTEGRITY_CHECK
"OMIT_INTEGRITY_CHECK",
#endif
-#ifdef SQLITE_OMIT_LIKE_OPTIMIZATION
+#if SQLITE_OMIT_LIKE_OPTIMIZATION
"OMIT_LIKE_OPTIMIZATION",
#endif
-#ifdef SQLITE_OMIT_LOAD_EXTENSION
+#if SQLITE_OMIT_LOAD_EXTENSION
"OMIT_LOAD_EXTENSION",
#endif
-#ifdef SQLITE_OMIT_LOCALTIME
+#if SQLITE_OMIT_LOCALTIME
"OMIT_LOCALTIME",
#endif
-#ifdef SQLITE_OMIT_LOOKASIDE
+#if SQLITE_OMIT_LOOKASIDE
"OMIT_LOOKASIDE",
#endif
-#ifdef SQLITE_OMIT_MEMORYDB
+#if SQLITE_OMIT_MEMORYDB
"OMIT_MEMORYDB",
#endif
-#ifdef SQLITE_OMIT_MERGE_SORT
- "OMIT_MERGE_SORT",
-#endif
-#ifdef SQLITE_OMIT_OR_OPTIMIZATION
+#if SQLITE_OMIT_OR_OPTIMIZATION
"OMIT_OR_OPTIMIZATION",
#endif
-#ifdef SQLITE_OMIT_PAGER_PRAGMAS
+#if SQLITE_OMIT_PAGER_PRAGMAS
"OMIT_PAGER_PRAGMAS",
#endif
-#ifdef SQLITE_OMIT_PRAGMA
+#if SQLITE_OMIT_PRAGMA
"OMIT_PRAGMA",
#endif
-#ifdef SQLITE_OMIT_PROGRESS_CALLBACK
+#if SQLITE_OMIT_PROGRESS_CALLBACK
"OMIT_PROGRESS_CALLBACK",
#endif
-#ifdef SQLITE_OMIT_QUICKBALANCE
+#if SQLITE_OMIT_QUICKBALANCE
"OMIT_QUICKBALANCE",
#endif
-#ifdef SQLITE_OMIT_REINDEX
+#if SQLITE_OMIT_REINDEX
"OMIT_REINDEX",
#endif
-#ifdef SQLITE_OMIT_SCHEMA_PRAGMAS
+#if SQLITE_OMIT_SCHEMA_PRAGMAS
"OMIT_SCHEMA_PRAGMAS",
#endif
-#ifdef SQLITE_OMIT_SCHEMA_VERSION_PRAGMAS
+#if SQLITE_OMIT_SCHEMA_VERSION_PRAGMAS
"OMIT_SCHEMA_VERSION_PRAGMAS",
#endif
-#ifdef SQLITE_OMIT_SHARED_CACHE
+#if SQLITE_OMIT_SHARED_CACHE
"OMIT_SHARED_CACHE",
#endif
-#ifdef SQLITE_OMIT_SUBQUERY
+#if SQLITE_OMIT_SUBQUERY
"OMIT_SUBQUERY",
#endif
-#ifdef SQLITE_OMIT_TCL_VARIABLE
+#if SQLITE_OMIT_TCL_VARIABLE
"OMIT_TCL_VARIABLE",
#endif
-#ifdef SQLITE_OMIT_TEMPDB
+#if SQLITE_OMIT_TEMPDB
"OMIT_TEMPDB",
#endif
-#ifdef SQLITE_OMIT_TRACE
+#if SQLITE_OMIT_TRACE
"OMIT_TRACE",
#endif
-#ifdef SQLITE_OMIT_TRIGGER
+#if SQLITE_OMIT_TRIGGER
"OMIT_TRIGGER",
#endif
-#ifdef SQLITE_OMIT_TRUNCATE_OPTIMIZATION
+#if SQLITE_OMIT_TRUNCATE_OPTIMIZATION
"OMIT_TRUNCATE_OPTIMIZATION",
#endif
-#ifdef SQLITE_OMIT_UTF16
+#if SQLITE_OMIT_UTF16
"OMIT_UTF16",
#endif
-#ifdef SQLITE_OMIT_VACUUM
+#if SQLITE_OMIT_VACUUM
"OMIT_VACUUM",
#endif
-#ifdef SQLITE_OMIT_VIEW
+#if SQLITE_OMIT_VIEW
"OMIT_VIEW",
#endif
-#ifdef SQLITE_OMIT_VIRTUALTABLE
+#if SQLITE_OMIT_VIRTUALTABLE
"OMIT_VIRTUALTABLE",
#endif
-#ifdef SQLITE_OMIT_WAL
+#if SQLITE_OMIT_WAL
"OMIT_WAL",
#endif
-#ifdef SQLITE_OMIT_WSD
+#if SQLITE_OMIT_WSD
"OMIT_WSD",
#endif
-#ifdef SQLITE_OMIT_XFER_OPT
+#if SQLITE_OMIT_XFER_OPT
"OMIT_XFER_OPT",
#endif
-#ifdef SQLITE_PERFORMANCE_TRACE
+#if SQLITE_PERFORMANCE_TRACE
"PERFORMANCE_TRACE",
#endif
-#ifdef SQLITE_PROXY_DEBUG
+#if SQLITE_PROXY_DEBUG
"PROXY_DEBUG",
#endif
-#ifdef SQLITE_RTREE_INT_ONLY
+#if SQLITE_RTREE_INT_ONLY
"RTREE_INT_ONLY",
#endif
-#ifdef SQLITE_SECURE_DELETE
+#if SQLITE_SECURE_DELETE
"SECURE_DELETE",
#endif
-#ifdef SQLITE_SMALL_STACK
+#if SQLITE_SMALL_STACK
"SMALL_STACK",
#endif
-#ifdef SQLITE_SOUNDEX
+#if SQLITE_SOUNDEX
"SOUNDEX",
#endif
-#ifdef SQLITE_TCL
+#if SQLITE_SYSTEM_MALLOC
+ "SYSTEM_MALLOC",
+#endif
+#if SQLITE_TCL
"TCL",
#endif
-#ifdef SQLITE_TEMP_STORE
+#if defined(SQLITE_TEMP_STORE) && !defined(SQLITE_TEMP_STORE_xc)
"TEMP_STORE=" CTIMEOPT_VAL(SQLITE_TEMP_STORE),
#endif
-#ifdef SQLITE_TEST
+#if SQLITE_TEST
"TEST",
#endif
-#ifdef SQLITE_THREADSAFE
+#if defined(SQLITE_THREADSAFE)
"THREADSAFE=" CTIMEOPT_VAL(SQLITE_THREADSAFE),
#endif
-#ifdef SQLITE_USE_ALLOCA
+#if SQLITE_USE_ALLOCA
"USE_ALLOCA",
#endif
-#ifdef SQLITE_ZERO_MALLOC
+#if SQLITE_USER_AUTHENTICATION
+ "USER_AUTHENTICATION",
+#endif
+#if SQLITE_WIN32_MALLOC
+ "WIN32_MALLOC",
+#endif
+#if SQLITE_ZERO_MALLOC
"ZERO_MALLOC"
#endif
};
@@ -13020,16 +15527,26 @@ static const char * const azCompileOpt[] = {
** 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){
+SQLITE_API int SQLITE_STDCALL sqlite3_compileoption_used(const char *zOptName){
int i, n;
+
+#if SQLITE_ENABLE_API_ARMOR
+ if( zOptName==0 ){
+ (void)SQLITE_MISUSE_BKPT;
+ return 0;
+ }
+#endif
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;
+ if( sqlite3StrNICmp(zOptName, azCompileOpt[i], n)==0
+ && sqlite3IsIdChar((unsigned char)azCompileOpt[i][n])==0
+ ){
+ return 1;
+ }
}
return 0;
}
@@ -13038,7 +15555,7 @@ SQLITE_API int sqlite3_compileoption_used(const char *zOptName){
** 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){
+SQLITE_API const char *SQLITE_STDCALL sqlite3_compileoption_get(int N){
if( N>=0 && N<ArraySize(azCompileOpt) ){
return azCompileOpt[N];
}
@@ -13064,6 +15581,7 @@ SQLITE_API const char *sqlite3_compileoption_get(int N){
** This module implements the sqlite3_status() interface and related
** functionality.
*/
+/* #include "sqliteInt.h" */
/************** Include vdbeInt.h in the middle of status.c ******************/
/************** Begin file vdbeInt.h *****************************************/
/*
@@ -13087,6 +15605,25 @@ SQLITE_API const char *sqlite3_compileoption_get(int N){
#define _VDBEINT_H_
/*
+** 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 50
+#endif
+
+/*
+** VDBE_DISPLAY_P4 is true or false depending on whether or not the
+** "explain" P4 display logic is enabled.
+*/
+#if !defined(SQLITE_OMIT_EXPLAIN) || !defined(NDEBUG) \
+ || defined(VDBE_PROFILE) || defined(SQLITE_DEBUG)
+# define VDBE_DISPLAY_P4 1
+#else
+# define VDBE_DISPLAY_P4 0
+#endif
+
+/*
** SQL is translated into a sequence of instructions to be
** executed by a virtual machine. Each instruction is an instance
** of the following structure.
@@ -13096,7 +15633,7 @@ typedef struct VdbeOp Op;
/*
** Boolean values
*/
-typedef unsigned char Bool;
+typedef unsigned Bool;
/* Opaque type used by code in vdbesort.c */
typedef struct VdbeSorter VdbeSorter;
@@ -13104,44 +15641,54 @@ typedef struct VdbeSorter VdbeSorter;
/* Opaque type used by the explainer */
typedef struct Explain Explain;
+/* Elements of the linked list at Vdbe.pAuxData */
+typedef struct AuxData AuxData;
+
+/* Types of VDBE cursors */
+#define CURTYPE_BTREE 0
+#define CURTYPE_SORTER 1
+#define CURTYPE_VTAB 2
+#define CURTYPE_PSEUDO 3
+
/*
-** 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.
+** A VdbeCursor is an superclass (a wrapper) for various cursor objects:
+**
+** * A b-tree cursor
+** - In the main database or in an ephemeral database
+** - On either an index or a table
+** * A sorter
+** * A virtual table
+** * A one-row "pseudotable" stored in a single register
*/
struct VdbeCursor {
- BtCursor *pCursor; /* The cursor structure of the backend */
+ u8 eCurType; /* One of the CURTYPE_* values above */
+ i8 iDb; /* Index of cursor database in db->aDb[] (or -1) */
+ u8 nullRow; /* True if pointing to a row with no data */
+ u8 deferredMoveto; /* A call to sqlite3BtreeMoveto() is needed */
+ u8 isTable; /* True for rowid tables. False for indexes */
+#ifdef SQLITE_DEBUG
+ u8 seekOp; /* Most recent seek operation on this cursor */
+#endif
+ Bool isEphemeral:1; /* True for an ephemeral table */
+ Bool useRandomRowid:1;/* Generate new record numbers semi-randomly */
+ Bool isOrdered:1; /* True if the underlying table is BTREE_UNORDERED */
+ Pgno pgnoRoot; /* Root page of the open btree cursor */
+ i16 nField; /* Number of fields in the header */
+ u16 nHdrParsed; /* Number of header fields parsed so far */
+ union {
+ BtCursor *pCursor; /* CURTYPE_BTREE. Btree cursor */
+ sqlite3_vtab_cursor *pVCur; /* CURTYPE_VTAB. Vtab cursor */
+ int pseudoTableReg; /* CURTYPE_PSEUDO. Reg holding content. */
+ VdbeSorter *pSorter; /* CURTYPE_SORTER. Sorter object */
+ } uc;
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 */
+ int seekResult; /* Result of previous sqlite3BtreeMoveto() */
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;
+#ifdef SQLITE_ENABLE_COLUMN_USED_MASK
+ u64 maskUsed; /* Mask of columns used by this cursor */
+#endif
/* Cached information about the header for the data record that the
** cursor is currently pointing to. Only valid if cacheStatus matches
@@ -13153,10 +15700,15 @@ struct VdbeCursor {
** 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 */
+ u32 payloadSize; /* Total number of bytes in the record */
+ u32 szRow; /* Byte available in aRow */
+ u32 iHdrOffset; /* Offset to next unparsed byte of the header */
+ const u8 *aRow; /* Data for the current row, if all on one page */
+ u32 *aOffset; /* Pointer to aType[nField] */
+ u32 aType[1]; /* Type values for all entries in the record */
+ /* 2*nField extra array elements allocated for aType[], beyond the one
+ ** static element declared in the structure. nField total array slots for
+ ** aType[] and nField+1 array slots for aOffset[] */
};
typedef struct VdbeCursor VdbeCursor;
@@ -13186,19 +15738,21 @@ 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 */
+ i64 *anExec; /* Event counters from 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 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) */
+ int nChange; /* Statement changes (Vdbe.nChange) */
+ int nDbChange; /* Value of db->nChange */
};
#define VdbeFrameMem(p) ((Mem *)&((u8 *)p)[ROUND8(sizeof(VdbeFrame))])
@@ -13214,28 +15768,37 @@ struct VdbeFrame {
** 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 {
+ union MemValue {
+ double r; /* Real value used when MEM_Real is set in flags */
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 */
+ u8 eSubtype; /* Subtype for this value */
+ int n; /* Number of characters in string value, excluding '\0' */
+ char *z; /* String or BLOB value */
+ /* ShallowCopy only needs to copy the information above */
+ char *zMalloc; /* Space to hold MEM_Str or MEM_Blob if szMalloc>0 */
+ int szMalloc; /* Size of the zMalloc allocation */
+ u32 uTemp; /* Transient storage for serial_type in OP_MakeRecord */
+ sqlite3 *db; /* The associated database connection */
+ void (*xDel)(void*);/* Destructor for Mem.z - only valid if MEM_Dyn */
#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() */
};
+/*
+** Size of struct Mem not including the Mem.zMalloc member or anything that
+** follows.
+*/
+#define MEMCELLSIZE offsetof(Mem,zMalloc)
+
/* One or more of the following flags are set to indicate the validOK
** representations of the value stored in the Mem struct.
**
@@ -13253,9 +15816,10 @@ struct Mem {
#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_AffMask 0x001f /* Mask of affinity bits */
#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_Undefined 0x0080 /* Value is undefined */
#define MEM_Cleared 0x0100 /* NULL set by OP_Null, not from data */
#define MEM_TypeMask 0x01ff /* Mask of type bits */
@@ -13266,7 +15830,7 @@ struct Mem {
** 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_Dyn 0x0400 /* Need to call Mem.xDel() 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 */
@@ -13287,30 +15851,26 @@ struct Mem {
** 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 */
+#define memIsValid(M) ((M)->flags & MEM_Undefined)==0
+#endif
+
+/*
+** Each auxiliary data pointer stored by a user defined function
+** implementation calling sqlite3_set_auxdata() is stored in an instance
+** of this structure. All such structures associated with a single VM
+** are stored in a linked list headed at Vdbe.pAuxData. All are destroyed
+** when the VM is halted (if not before).
+*/
+struct AuxData {
+ int iOp; /* Instruction number of OP_Function opcode */
+ int iArg; /* Index of function argument. */
+ void *pAux; /* Aux data pointer */
+ void (*xDelete)(void *); /* Destructor for the aux data */
+ AuxData *pNext; /* Next element in list */
};
/*
-** The "context" argument for a installable function. A pointer to an
+** The "context" argument for an installable function. A pointer to an
** instance of this structure is the first argument to the routines used
** implement the SQL functions.
**
@@ -13323,13 +15883,16 @@ struct VdbeFunc {
** (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 */
+ Mem *pOut; /* The return value is stored here */
+ FuncDef *pFunc; /* Pointer to function information */
+ Mem *pMem; /* Memory cell used to store aggregate context */
+ Vdbe *pVdbe; /* The VM that owns this context */
+ int iOp; /* Instruction number of OP_Function */
+ int isError; /* Error code returned by the function. */
+ u8 skipFlag; /* Skip accumulator loading if true */
+ u8 fErrorOrAux; /* isError!=0 or pVdbe->pAuxData modified */
+ u8 argc; /* Number of arguments */
+ sqlite3_value *argv[1]; /* Argument set */
};
/*
@@ -13349,20 +15912,22 @@ struct Explain {
*/
typedef unsigned bft; /* Bit Field Type */
+typedef struct ScanStatus ScanStatus;
+struct ScanStatus {
+ int addrExplain; /* OP_Explain for loop */
+ int addrLoop; /* Address of "loops" counter */
+ int addrVisit; /* Address of "rows visited" counter */
+ int iSelectID; /* The "Select-ID" for this loop */
+ LogEst nEst; /* Estimated output rows per loop */
+ char *zName; /* Name of table or index */
+};
+
/*
** 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 */
@@ -13371,13 +15936,10 @@ struct Vdbe {
Mem **apArg; /* Arguments to currently executing user function */
Mem *aColName; /* Column names to return */
Mem *pResultSet; /* Pointer to an array of results */
+ Parse *pParse; /* Parsing context used to create this Vdbe */
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[] */
+ int 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 */
@@ -13389,36 +15951,35 @@ struct Vdbe {
u32 cacheCtr; /* VdbeCursor row cache generation counter */
int pc; /* The program counter */
int rc; /* Value to return */
+#ifdef SQLITE_DEBUG
+ int rcApp; /* errcode set by sqlite3_result_error_code() */
+#endif
+ u16 nResColumn; /* Number of columns in one row of the result set */
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 readOnly:1; /* True for statements that do not write */
+ bft bIsReader:1; /* True for statements that read */
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() */
+ u32 aCounter[5]; /* Counters used by sqlite3_stmt_status() */
#ifndef SQLITE_OMIT_TRACE
i64 startTime; /* Time when query started - used for profiling */
#endif
+ i64 iCurrentTime; /* Value of julianday('now') for this statement */
i64 nFkConstraint; /* Number of imm. FK constraints this VM */
i64 nStmtDefCons; /* Number of def. constraints when stmt started */
+ i64 nStmtDefImmCons; /* Number of def. imm 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 */
@@ -13426,6 +15987,12 @@ struct Vdbe {
SubProgram *pProgram; /* Linked list of all sub-programs used by VM */
int nOnceFlag; /* Size of array aOnceFlag[] */
u8 *aOnceFlag; /* Flags for OP_Once */
+ AuxData *pAuxData; /* Linked list of auxdata allocations */
+#ifdef SQLITE_ENABLE_STMT_SCANSTATUS
+ i64 *anExec; /* Number of times each op has been executed */
+ int nScan; /* Entries in aScan[] */
+ ScanStatus *aScan; /* Scan definitions for sqlite3_stmt_scanstatus() */
+#endif
};
/*
@@ -13439,22 +16006,24 @@ struct Vdbe {
/*
** Function prototypes
*/
+SQLITE_PRIVATE void sqlite3VdbeError(Vdbe*, const char *, ...);
SQLITE_PRIVATE void sqlite3VdbeFreeCursor(Vdbe *, VdbeCursor*);
void sqliteVdbePopStack(Vdbe*,int);
SQLITE_PRIVATE int sqlite3VdbeCursorMoveto(VdbeCursor*);
+SQLITE_PRIVATE int sqlite3VdbeCursorRestore(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 u8 sqlite3VdbeOneByteSerialTypeLen(u8);
+SQLITE_PRIVATE u32 sqlite3VdbeSerialType(Mem*, int, u32*);
+SQLITE_PRIVATE u32 sqlite3VdbeSerialPut(unsigned char*, Mem*, u32);
SQLITE_PRIVATE u32 sqlite3VdbeSerialGet(const unsigned char*, u32, Mem*);
-SQLITE_PRIVATE void sqlite3VdbeDeleteAuxData(VdbeFunc*, int);
+SQLITE_PRIVATE void sqlite3VdbeDeleteAuxData(Vdbe*, int, 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 sqlite3VdbeIdxKeyCompare(sqlite3*,VdbeCursor*,UnpackedRecord*,int*);
+SQLITE_PRIVATE int sqlite3VdbeIdxRowid(sqlite3*, BtCursor*, i64*);
SQLITE_PRIVATE int sqlite3VdbeExec(Vdbe*);
SQLITE_PRIVATE int sqlite3VdbeList(Vdbe*);
SQLITE_PRIVATE int sqlite3VdbeHalt(Vdbe*);
@@ -13471,49 +16040,40 @@ SQLITE_PRIVATE void sqlite3VdbeMemSetInt64(Mem*, i64);
#else
SQLITE_PRIVATE void sqlite3VdbeMemSetDouble(Mem*, double);
#endif
+SQLITE_PRIVATE void sqlite3VdbeMemInit(Mem*,sqlite3*,u16);
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 int sqlite3VdbeMemStringify(Mem*, u8, u8);
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 sqlite3VdbeMemCast(Mem*,u8,u8);
+SQLITE_PRIVATE int sqlite3VdbeMemFromBtree(BtCursor*,u32,u32,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);
+#define VdbeMemDynamic(X) \
+ (((X)->flags&(MEM_Agg|MEM_Dyn|MEM_RowSet|MEM_Frame))!=0)
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 sqlite3VdbeMemClearAndResize(Mem *pMem, int n);
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 int sqlite3VdbeSorterInit(sqlite3 *, int, VdbeCursor *);
+SQLITE_PRIVATE void sqlite3VdbeSorterReset(sqlite3 *, VdbeSorter *);
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
+SQLITE_PRIVATE int sqlite3VdbeSorterRewind(const VdbeCursor *, int *);
+SQLITE_PRIVATE int sqlite3VdbeSorterWrite(const VdbeCursor *, Mem *);
+SQLITE_PRIVATE int sqlite3VdbeSorterCompare(const VdbeCursor *, Mem *, int, int *);
#if !defined(SQLITE_OMIT_SHARED_CACHE) && SQLITE_THREADSAFE>0
SQLITE_PRIVATE void sqlite3VdbeEnter(Vdbe*);
@@ -13525,6 +16085,7 @@ SQLITE_PRIVATE void sqlite3VdbeLeave(Vdbe*);
#ifdef SQLITE_DEBUG
SQLITE_PRIVATE void sqlite3VdbeMemAboutToChange(Vdbe*,Mem*);
+SQLITE_PRIVATE int sqlite3VdbeCheckMemInvariants(Mem*);
#endif
#ifndef SQLITE_OMIT_FOREIGN_KEY
@@ -13556,12 +16117,34 @@ SQLITE_PRIVATE int sqlite3VdbeMemExpandBlob(Mem *);
/*
** Variables in which to record status information.
*/
+#if SQLITE_PTRSIZE>4
+typedef sqlite3_int64 sqlite3StatValueType;
+#else
+typedef u32 sqlite3StatValueType;
+#endif
typedef struct sqlite3StatType sqlite3StatType;
static SQLITE_WSD struct sqlite3StatType {
- int nowValue[10]; /* Current value */
- int mxValue[10]; /* Maximum value */
+ sqlite3StatValueType nowValue[10]; /* Current value */
+ sqlite3StatValueType mxValue[10]; /* Maximum value */
} sqlite3Stat = { {0,}, {0,} };
+/*
+** Elements of sqlite3Stat[] are protected by either the memory allocator
+** mutex, or by the pcache1 mutex. The following array determines which.
+*/
+static const char statMutex[] = {
+ 0, /* SQLITE_STATUS_MEMORY_USED */
+ 1, /* SQLITE_STATUS_PAGECACHE_USED */
+ 1, /* SQLITE_STATUS_PAGECACHE_OVERFLOW */
+ 0, /* SQLITE_STATUS_SCRATCH_USED */
+ 0, /* SQLITE_STATUS_SCRATCH_OVERFLOW */
+ 0, /* SQLITE_STATUS_MALLOC_SIZE */
+ 0, /* SQLITE_STATUS_PARSER_STACK */
+ 1, /* SQLITE_STATUS_PAGECACHE_SIZE */
+ 0, /* SQLITE_STATUS_SCRATCH_SIZE */
+ 0, /* SQLITE_STATUS_MALLOC_COUNT */
+};
+
/* The "wsdStat" macro will resolve to the status information
** state vector. If writable static data is unsupported on the target,
@@ -13578,63 +16161,118 @@ static SQLITE_WSD struct sqlite3StatType {
#endif
/*
-** Return the current value of a status parameter.
+** Return the current value of a status parameter. The caller must
+** be holding the appropriate mutex.
*/
-SQLITE_PRIVATE int sqlite3StatusValue(int op){
+SQLITE_PRIVATE sqlite3_int64 sqlite3StatusValue(int op){
wsdStatInit;
assert( op>=0 && op<ArraySize(wsdStat.nowValue) );
+ assert( op>=0 && op<ArraySize(statMutex) );
+ assert( sqlite3_mutex_held(statMutex[op] ? sqlite3Pcache1Mutex()
+ : sqlite3MallocMutex()) );
return wsdStat.nowValue[op];
}
/*
-** Add N to the value of a status record. It is assumed that the
-** caller holds appropriate locks.
+** Add N to the value of a status record. The caller must hold the
+** appropriate mutex. (Locking is checked by assert()).
+**
+** The StatusUp() routine can accept positive or negative values for N.
+** The value of N is added to the current status value and the high-water
+** mark is adjusted if necessary.
+**
+** The StatusDown() routine lowers the current value by N. The highwater
+** mark is unchanged. N must be non-negative for StatusDown().
*/
-SQLITE_PRIVATE void sqlite3StatusAdd(int op, int N){
+SQLITE_PRIVATE void sqlite3StatusUp(int op, int N){
wsdStatInit;
assert( op>=0 && op<ArraySize(wsdStat.nowValue) );
+ assert( op>=0 && op<ArraySize(statMutex) );
+ assert( sqlite3_mutex_held(statMutex[op] ? sqlite3Pcache1Mutex()
+ : sqlite3MallocMutex()) );
wsdStat.nowValue[op] += N;
if( wsdStat.nowValue[op]>wsdStat.mxValue[op] ){
wsdStat.mxValue[op] = wsdStat.nowValue[op];
}
}
+SQLITE_PRIVATE void sqlite3StatusDown(int op, int N){
+ wsdStatInit;
+ assert( N>=0 );
+ assert( op>=0 && op<ArraySize(statMutex) );
+ assert( sqlite3_mutex_held(statMutex[op] ? sqlite3Pcache1Mutex()
+ : sqlite3MallocMutex()) );
+ assert( op>=0 && op<ArraySize(wsdStat.nowValue) );
+ wsdStat.nowValue[op] -= N;
+}
/*
-** Set the value of a status to X.
+** Adjust the highwater mark if necessary.
+** The caller must hold the appropriate mutex.
*/
-SQLITE_PRIVATE void sqlite3StatusSet(int op, int X){
+SQLITE_PRIVATE void sqlite3StatusHighwater(int op, int X){
+ sqlite3StatValueType newValue;
wsdStatInit;
+ assert( X>=0 );
+ newValue = (sqlite3StatValueType)X;
assert( op>=0 && op<ArraySize(wsdStat.nowValue) );
- wsdStat.nowValue[op] = X;
- if( wsdStat.nowValue[op]>wsdStat.mxValue[op] ){
- wsdStat.mxValue[op] = wsdStat.nowValue[op];
+ assert( op>=0 && op<ArraySize(statMutex) );
+ assert( sqlite3_mutex_held(statMutex[op] ? sqlite3Pcache1Mutex()
+ : sqlite3MallocMutex()) );
+ assert( op==SQLITE_STATUS_MALLOC_SIZE
+ || op==SQLITE_STATUS_PAGECACHE_SIZE
+ || op==SQLITE_STATUS_SCRATCH_SIZE
+ || op==SQLITE_STATUS_PARSER_STACK );
+ if( newValue>wsdStat.mxValue[op] ){
+ wsdStat.mxValue[op] = newValue;
}
}
/*
** 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){
+SQLITE_API int SQLITE_STDCALL sqlite3_status64(
+ int op,
+ sqlite3_int64 *pCurrent,
+ sqlite3_int64 *pHighwater,
+ int resetFlag
+){
+ sqlite3_mutex *pMutex;
wsdStatInit;
if( op<0 || op>=ArraySize(wsdStat.nowValue) ){
return SQLITE_MISUSE_BKPT;
}
+#ifdef SQLITE_ENABLE_API_ARMOR
+ if( pCurrent==0 || pHighwater==0 ) return SQLITE_MISUSE_BKPT;
+#endif
+ pMutex = statMutex[op] ? sqlite3Pcache1Mutex() : sqlite3MallocMutex();
+ sqlite3_mutex_enter(pMutex);
*pCurrent = wsdStat.nowValue[op];
*pHighwater = wsdStat.mxValue[op];
if( resetFlag ){
wsdStat.mxValue[op] = wsdStat.nowValue[op];
}
+ sqlite3_mutex_leave(pMutex);
+ (void)pMutex; /* Prevent warning when SQLITE_THREADSAFE=0 */
return SQLITE_OK;
}
+SQLITE_API int SQLITE_STDCALL sqlite3_status(int op, int *pCurrent, int *pHighwater, int resetFlag){
+ sqlite3_int64 iCur, iHwtr;
+ int rc;
+#ifdef SQLITE_ENABLE_API_ARMOR
+ if( pCurrent==0 || pHighwater==0 ) return SQLITE_MISUSE_BKPT;
+#endif
+ rc = sqlite3_status64(op, &iCur, &iHwtr, resetFlag);
+ if( rc==0 ){
+ *pCurrent = (int)iCur;
+ *pHighwater = (int)iHwtr;
+ }
+ return rc;
+}
/*
** Query status information for a single database connection
*/
-SQLITE_API int sqlite3_db_status(
+SQLITE_API int SQLITE_STDCALL sqlite3_db_status(
sqlite3 *db, /* The database connection whose status is desired */
int op, /* Status verb */
int *pCurrent, /* Write current value here */
@@ -13642,6 +16280,11 @@ SQLITE_API int sqlite3_db_status(
int resetFlag /* Reset high-water mark if true */
){
int rc = SQLITE_OK; /* Return code */
+#ifdef SQLITE_ENABLE_API_ARMOR
+ if( !sqlite3SafetyCheckOk(db) || pCurrent==0|| pHighwater==0 ){
+ return SQLITE_MISUSE_BKPT;
+ }
+#endif
sqlite3_mutex_enter(db->mutex);
switch( op ){
case SQLITE_DBSTATUS_LOOKASIDE_USED: {
@@ -13713,10 +16356,10 @@ SQLITE_API int sqlite3_db_status(
+ 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);
+ nByte += sqlite3_msize(pSchema->tblHash.ht);
+ nByte += sqlite3_msize(pSchema->trigHash.ht);
+ nByte += sqlite3_msize(pSchema->idxHash.ht);
+ nByte += sqlite3_msize(pSchema->fkeyHash.ht);
for(p=sqliteHashFirst(&pSchema->trigHash); p; p=sqliteHashNext(p)){
sqlite3DeleteTrigger(db, (Trigger*)sqliteHashData(p));
@@ -13750,7 +16393,7 @@ SQLITE_API int sqlite3_db_status(
}
db->pnBytesFreed = 0;
- *pHighwater = 0;
+ *pHighwater = 0; /* IMP: R-64479-57858 */
*pCurrent = nByte;
break;
@@ -13775,11 +16418,23 @@ SQLITE_API int sqlite3_db_status(
sqlite3PagerCacheStat(pPager, op, resetFlag, &nRet);
}
}
- *pHighwater = 0;
+ *pHighwater = 0; /* IMP: R-42420-56072 */
+ /* IMP: R-54100-20147 */
+ /* IMP: R-29431-39229 */
*pCurrent = nRet;
break;
}
+ /* Set *pCurrent to non-zero if there are unresolved deferred foreign
+ ** key constraints. Set *pCurrent to zero if all foreign key constraints
+ ** have been satisfied. The *pHighwater is always set to zero.
+ */
+ case SQLITE_DBSTATUS_DEFERRED_FKS: {
+ *pHighwater = 0; /* IMP: R-11967-56545 */
+ *pCurrent = db->nDeferredImmCons>0 || db->nDeferredCons>0;
+ break;
+ }
+
default: {
rc = SQLITE_ERROR;
}
@@ -13808,7 +16463,7 @@ SQLITE_API int sqlite3_db_status(
** 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
+** 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.
@@ -13816,14 +16471,14 @@ SQLITE_API int sqlite3_db_status(
** 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
+** This implementation 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
+** 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
@@ -13835,6 +16490,7 @@ SQLITE_API int sqlite3_db_status(
** Willmann-Bell, Inc
** Richmond, Virginia (USA)
*/
+/* #include "sqliteInt.h" */
/* #include <stdlib.h> */
/* #include <assert.h> */
#include <time.h>
@@ -13856,6 +16512,7 @@ struct DateTime {
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 */
+ char tzSet; /* Timezone was set explicitly */
};
@@ -13949,6 +16606,7 @@ static int parseTimezone(const char *zDate, DateTime *p){
p->tz = sgn*(nMn + nHr*60);
zulu_time:
while( sqlite3Isspace(*zDate) ){ zDate++; }
+ p->tzSet = 1;
return *zDate!=0;
}
@@ -14085,8 +16743,8 @@ static int parseYyyyMmDd(const char *zDate, DateTime *p){
** 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->iJD = sqlite3StmtCurrentTime(context);
+ if( p->iJD>0 ){
p->validJD = 1;
return 0;
}else{
@@ -14095,7 +16753,7 @@ static int setDateTimeToCurrent(sqlite3_context *context, DateTime *p){
}
/*
-** Attempt to parse the given string into a Julian Day Number. Return
+** 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:
@@ -14146,7 +16804,7 @@ static void computeYMD(DateTime *p){
A = Z + 1 + A - (A/4);
B = A + 1524;
C = (int)((B - 122.1)/365.25);
- D = (36525*C)/100;
+ D = (36525*(C&32767))/100;
E = (int)((B-D)/30.6001);
X1 = (int)(30.6001*E);
p->D = B - D - X1;
@@ -14203,8 +16861,9 @@ static void clearYMD_HMS_TZ(DateTime *p){
** 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)
+#if !HAVE_LOCALTIME_R && !HAVE_LOCALTIME_S \
+ && defined(_MSC_VER) && defined(_CRT_INSECURE_DEPRECATE)
+#undef HAVE_LOCALTIME_S
#define HAVE_LOCALTIME_S 1
#endif
@@ -14217,11 +16876,14 @@ static void clearYMD_HMS_TZ(DateTime *p){
**
** If the sqlite3GlobalConfig.bLocaltimeFault variable is true then this
** routine will always fail.
+**
+** EVIDENCE-OF: R-62172-00036 In this implementation, the standard C
+** library function localtime_r() is used to assist in the calculation of
+** local time.
*/
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)
+#if !HAVE_LOCALTIME_R && !HAVE_LOCALTIME_S
struct tm *pX;
#if SQLITE_THREADSAFE>0
sqlite3_mutex *mutex = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER);
@@ -14238,7 +16900,7 @@ static int osLocaltime(time_t *t, struct tm *pTm){
#ifndef SQLITE_OMIT_BUILTIN_TEST
if( sqlite3GlobalConfig.bLocaltimeFault ) return 1;
#endif
-#if defined(HAVE_LOCALTIME_R) && HAVE_LOCALTIME_R
+#if HAVE_LOCALTIME_R
rc = localtime_r(t, pTm)==0;
#else
rc = localtime_s(pTm, t);
@@ -14273,6 +16935,11 @@ static sqlite3_int64 localtimeOffset(
x = *p;
computeYMD_HMS(&x);
if( x.Y<1971 || x.Y>=2038 ){
+ /* EVIDENCE-OF: R-55269-29598 The localtime_r() C function normally only
+ ** works for years between 1970 and 2037. For dates outside this range,
+ ** SQLite attempts to map the year into an equivalent year within this
+ ** range, do the calculation, then map the year back.
+ */
x.Y = 2000;
x.M = 1;
x.D = 1;
@@ -14372,13 +17039,18 @@ static int parseModifier(sqlite3_context *pCtx, const char *zMod, DateTime *p){
}
#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);
+ if( p->tzSet==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);
+ }
+ p->tzSet = 1;
+ }else{
+ rc = SQLITE_OK;
}
}
#endif
@@ -14657,7 +17329,7 @@ static void dateFunc(
** %f ** fractional seconds SS.SSS
** %H hour 00-24
** %j day of year 000-366
-** %J ** Julian day number
+** %J ** julian day number
** %m month 01-12
** %M minute 00-59
** %s seconds since 1970-01-01
@@ -14677,8 +17349,10 @@ static void strftimeFunc(
size_t i,j;
char *z;
sqlite3 *db;
- const char *zFmt = (const char*)sqlite3_value_text(argv[0]);
+ const char *zFmt;
char zBuf[100];
+ if( argc==0 ) return;
+ zFmt = (const char*)sqlite3_value_text(argv[0]);
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++){
@@ -14869,10 +17543,10 @@ static void currentTimeFunc(
UNUSED_PARAMETER(argc);
UNUSED_PARAMETER(argv);
- db = sqlite3_context_db_handle(context);
- if( sqlite3OsCurrentTimeInt64(db->pVfs, &iT) ) return;
+ iT = sqlite3StmtCurrentTime(context);
+ if( iT<=0 ) return;
t = iT/1000 - 10000*(sqlite3_int64)21086676;
-#ifdef HAVE_GMTIME_R
+#if HAVE_GMTIME_R
pTm = gmtime_r(&t, &sNow);
#else
sqlite3_mutex_enter(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER));
@@ -14895,14 +17569,14 @@ static void currentTimeFunc(
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 ),
+ DFUNCTION(julianday, -1, 0, 0, juliandayFunc ),
+ DFUNCTION(date, -1, 0, 0, dateFunc ),
+ DFUNCTION(time, -1, 0, 0, timeFunc ),
+ DFUNCTION(datetime, -1, 0, 0, datetimeFunc ),
+ DFUNCTION(strftime, -1, 0, 0, strftimeFunc ),
+ DFUNCTION(current_time, 0, 0, 0, ctimeFunc ),
+ DFUNCTION(current_timestamp, 0, 0, 0, ctimestampFunc),
+ DFUNCTION(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),
@@ -14936,6 +17610,7 @@ SQLITE_PRIVATE void sqlite3RegisterDateTimeFunctions(void){
** architectures.
*/
#define _SQLITE_OS_C_ 1
+/* #include "sqliteInt.h" */
#undef _SQLITE_OS_C_
/*
@@ -15028,7 +17703,21 @@ SQLITE_PRIVATE int sqlite3OsCheckReservedLock(sqlite3_file *id, int *pResOut){
** 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);
+#ifdef SQLITE_TEST
+ if( op!=SQLITE_FCNTL_COMMIT_PHASETWO ){
+ /* Faults are not injected into COMMIT_PHASETWO because, assuming SQLite
+ ** is using a regular VFS, it is called after the corresponding
+ ** transaction has been committed. Injecting a fault at this point
+ ** confuses the test scripts - the COMMIT comand returns SQLITE_NOMEM
+ ** but the transaction is committed anyway.
+ **
+ ** The core must call OsFileControl() though, not OsFileControlHint(),
+ ** as if a custom VFS (e.g. zipvfs) returns an error here, it probably
+ ** means the commit really has failed and an error should be returned
+ ** to the user. */
+ DO_OS_MALLOC_TEST(id);
+ }
+#endif
return id->pMethods->xFileControl(id, op, pArg);
}
SQLITE_PRIVATE void sqlite3OsFileControlHint(sqlite3_file *id, int op, void *pArg){
@@ -15062,6 +17751,26 @@ SQLITE_PRIVATE int sqlite3OsShmMap(
return id->pMethods->xShmMap(id, iPage, pgsz, bExtend, pp);
}
+#if SQLITE_MAX_MMAP_SIZE>0
+/* The real implementation of xFetch and xUnfetch */
+SQLITE_PRIVATE int sqlite3OsFetch(sqlite3_file *id, i64 iOff, int iAmt, void **pp){
+ DO_OS_MALLOC_TEST(id);
+ return id->pMethods->xFetch(id, iOff, iAmt, pp);
+}
+SQLITE_PRIVATE int sqlite3OsUnfetch(sqlite3_file *id, i64 iOff, void *p){
+ return id->pMethods->xUnfetch(id, iOff, p);
+}
+#else
+/* No-op stubs to use when memory-mapped I/O is disabled */
+SQLITE_PRIVATE int sqlite3OsFetch(sqlite3_file *id, i64 iOff, int iAmt, void **pp){
+ *pp = 0;
+ return SQLITE_OK;
+}
+SQLITE_PRIVATE int sqlite3OsUnfetch(sqlite3_file *id, i64 iOff, void *p){
+ return SQLITE_OK;
+}
+#endif
+
/*
** The next group of routines are convenience wrappers around the
** VFS methods.
@@ -15196,7 +17905,7 @@ static sqlite3_vfs * SQLITE_WSD vfsList = 0;
** 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){
+SQLITE_API sqlite3_vfs *SQLITE_STDCALL sqlite3_vfs_find(const char *zVfs){
sqlite3_vfs *pVfs = 0;
#if SQLITE_THREADSAFE
sqlite3_mutex *mutex;
@@ -15242,12 +17951,16 @@ static void vfsUnlink(sqlite3_vfs *pVfs){
** VFS multiple times. The new VFS becomes the default if makeDflt is
** true.
*/
-SQLITE_API int sqlite3_vfs_register(sqlite3_vfs *pVfs, int makeDflt){
+SQLITE_API int SQLITE_STDCALL 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
+#ifdef SQLITE_ENABLE_API_ARMOR
+ if( pVfs==0 ) return SQLITE_MISUSE_BKPT;
+#endif
+
MUTEX_LOGIC( mutex = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER); )
sqlite3_mutex_enter(mutex);
vfsUnlink(pVfs);
@@ -15266,7 +17979,7 @@ SQLITE_API int sqlite3_vfs_register(sqlite3_vfs *pVfs, int makeDflt){
/*
** Unregister a VFS so that it is no longer accessible.
*/
-SQLITE_API int sqlite3_vfs_unregister(sqlite3_vfs *pVfs){
+SQLITE_API int SQLITE_STDCALL sqlite3_vfs_unregister(sqlite3_vfs *pVfs){
#if SQLITE_THREADSAFE
sqlite3_mutex *mutex = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER);
#endif
@@ -15304,6 +18017,7 @@ SQLITE_API int sqlite3_vfs_unregister(sqlite3_vfs *pVfs){
** during a hash table resize is a benign fault.
*/
+/* #include "sqliteInt.h" */
#ifndef SQLITE_OMIT_BUILTIN_TEST
@@ -15385,6 +18099,7 @@ SQLITE_PRIVATE void sqlite3EndBenignMalloc(void){
** are merely placeholders. Real drivers must be substituted using
** sqlite3_config() before SQLite will operate.
*/
+/* #include "sqliteInt.h" */
/*
** This version of the memory allocator is the default. It is
@@ -15471,6 +18186,7 @@ SQLITE_PRIVATE void sqlite3MemSetDefault(void){
** be necessary when compiling for Delphi,
** for example.
*/
+/* #include "sqliteInt.h" */
/*
** This version of the memory allocator is the default. It is
@@ -15478,16 +18194,6 @@ SQLITE_PRIVATE void sqlite3MemSetDefault(void){
** 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)
/*
@@ -15510,22 +18216,48 @@ static malloc_zone_t* _sqliteZone_;
** 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))
+#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
+/*
+** The malloc.h header file is needed for malloc_usable_size() function
+** on some systems (e.g. Linux).
+*/
+#if HAVE_MALLOC_H && HAVE_MALLOC_USABLE_SIZE
+# define SQLITE_USE_MALLOC_H 1
+# define SQLITE_USE_MALLOC_USABLE_SIZE 1
+/*
+** 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. Using the _msize() function also requires
+** the malloc.h header file.
+*/
+#elif defined(_MSC_VER) && !defined(SQLITE_WITHOUT_MSIZE)
+# define SQLITE_USE_MALLOC_H
+# define SQLITE_USE_MSIZE
#endif
+/*
+** Include the malloc.h header file, if necessary. Also set define macro
+** SQLITE_MALLOCSIZE to the appropriate function name, which is _msize()
+** for MSVC and malloc_usable_size() for most other systems (e.g. Linux).
+** The memory size function can always be overridden manually by defining
+** the macro SQLITE_MALLOCSIZE to the desired function name.
+*/
+#if defined(SQLITE_USE_MALLOC_H)
+# include <malloc.h>
+# if defined(SQLITE_USE_MALLOC_USABLE_SIZE)
+# if !defined(SQLITE_MALLOCSIZE)
+# define SQLITE_MALLOCSIZE(x) malloc_usable_size(x)
+# endif
+# elif defined(SQLITE_USE_MSIZE)
+# if !defined(SQLITE_MALLOCSIZE)
+# define SQLITE_MALLOCSIZE _msize
+# endif
+# endif
+#endif /* defined(SQLITE_USE_MALLOC_H) */
+
#endif /* __APPLE__ or not __APPLE__ */
/*
@@ -15585,10 +18317,11 @@ static void sqlite3MemFree(void *pPrior){
*/
static int sqlite3MemSize(void *pPrior){
#ifdef SQLITE_MALLOCSIZE
- return pPrior ? (int)SQLITE_MALLOCSIZE(pPrior) : 0;
+ assert( pPrior!=0 );
+ return (int)SQLITE_MALLOCSIZE(pPrior);
#else
sqlite3_int64 *p;
- if( pPrior==0 ) return 0;
+ assert( pPrior!=0 );
p = (sqlite3_int64*)pPrior;
p--;
return (int)p[0];
@@ -15601,7 +18334,7 @@ static int sqlite3MemSize(void *pPrior){
**
** 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
+** redirected to xMalloc. Similarly, we know that nByte>0 because
** cases where nByte<=0 will have been intercepted by higher-level
** routines and redirected to xFree.
*/
@@ -15730,6 +18463,7 @@ SQLITE_PRIVATE void sqlite3MemSetDefault(void){
** This file contains implementations of the low-level memory allocation
** routines specified in the sqlite3_mem_methods object.
*/
+/* #include "sqliteInt.h" */
/*
** This version of the memory allocator is used only if the
@@ -15889,7 +18623,7 @@ static int sqlite3MemSize(void *p){
return 0;
}
pHdr = sqlite3MemsysGetHeader(p);
- return pHdr->iSize;
+ return (int)pHdr->iSize;
}
/*
@@ -15931,7 +18665,7 @@ static void randomFill(char *pBuf, int nByte){
x = SQLITE_PTR_TO_INT(pBuf);
y = nByte | 1;
while( nByte >= 4 ){
- x = (x>>1) ^ (-(x&1) & 0xd0000001);
+ x = (x>>1) ^ (-(int)(x&1) & 0xd0000001);
y = y*1103515245 + 12345;
r = x ^ y;
*(int*)pBuf = r;
@@ -15939,7 +18673,7 @@ static void randomFill(char *pBuf, int nByte){
nByte -= 4;
}
while( nByte-- > 0 ){
- x = (x>>1) ^ (-(x&1) & 0xd0000001);
+ x = (x>>1) ^ (-(int)(x&1) & 0xd0000001);
y = y*1103515245 + 12345;
r = x ^ y;
*(pBuf++) = r & 0xff;
@@ -16034,9 +18768,9 @@ static void sqlite3MemFree(void *pPrior){
}
z = (char*)pBt;
z -= pHdr->nTitle;
- adjustStats(pHdr->iSize, -1);
+ adjustStats((int)pHdr->iSize, -1);
randomFill(z, sizeof(void*)*pHdr->nBacktraceSlots + sizeof(*pHdr) +
- pHdr->iSize + sizeof(int) + pHdr->nTitle);
+ (int)pHdr->iSize + sizeof(int) + pHdr->nTitle);
free(z);
sqlite3_mutex_leave(mem.mutex);
}
@@ -16058,9 +18792,9 @@ static void *sqlite3MemRealloc(void *pPrior, int nByte){
pOldHdr = sqlite3MemsysGetHeader(pPrior);
pNew = sqlite3MemMalloc(nByte);
if( pNew ){
- memcpy(pNew, pPrior, nByte<pOldHdr->iSize ? nByte : pOldHdr->iSize);
+ memcpy(pNew, pPrior, (int)(nByte<pOldHdr->iSize ? nByte : pOldHdr->iSize));
if( nByte>pOldHdr->iSize ){
- randomFill(&((char*)pNew)[pOldHdr->iSize], nByte - pOldHdr->iSize);
+ randomFill(&((char*)pNew)[pOldHdr->iSize], nByte - (int)pOldHdr->iSize);
}
sqlite3MemFree(pPrior);
}
@@ -16104,7 +18838,7 @@ SQLITE_PRIVATE void sqlite3MemdebugSetType(void *p, u8 eType){
** This routine is designed for use within an assert() statement, to
** verify the type of an allocation. For example:
**
-** assert( sqlite3MemdebugHasType(p, MEMTYPE_DB) );
+** assert( sqlite3MemdebugHasType(p, MEMTYPE_HEAP) );
*/
SQLITE_PRIVATE int sqlite3MemdebugHasType(void *p, u8 eType){
int rc = 1;
@@ -16126,7 +18860,7 @@ SQLITE_PRIVATE int sqlite3MemdebugHasType(void *p, u8 eType){
** This routine is designed for use within an assert() statement, to
** verify the type of an allocation. For example:
**
-** assert( sqlite3MemdebugNoType(p, MEMTYPE_DB) );
+** assert( sqlite3MemdebugNoType(p, MEMTYPE_LOOKASIDE) );
*/
SQLITE_PRIVATE int sqlite3MemdebugNoType(void *p, u8 eType){
int rc = 1;
@@ -16175,7 +18909,7 @@ SQLITE_PRIVATE void sqlite3MemdebugSync(){
for(pHdr=mem.pFirst; pHdr; pHdr=pHdr->pNext){
void **pBt = (void**)pHdr;
pBt -= pHdr->nBacktraceSlots;
- mem.xBacktrace(pHdr->iSize, pHdr->nBacktrace-1, &pBt[1]);
+ mem.xBacktrace((int)pHdr->iSize, pHdr->nBacktrace-1, &pBt[1]);
}
}
@@ -16264,6 +18998,7 @@ SQLITE_PRIVATE int sqlite3MemdebugMallocCount(){
** This version of the memory allocation subsystem is included
** in the build only if SQLITE_ENABLE_MEMSYS3 is defined.
*/
+/* #include "sqliteInt.h" */
/*
** This version of the memory allocator is only built into the library
@@ -16716,7 +19451,7 @@ static void memsys3FreeUnsafe(void *pOld){
*/
static int memsys3Size(void *p){
Mem3Block *pBlock;
- if( p==0 ) return 0;
+ assert( p!=0 );
pBlock = (Mem3Block*)p;
assert( (pBlock[-1].u.hdr.size4x&1)!=0 );
return (pBlock[-1].u.hdr.size4x&~3)*2 - 4;
@@ -16955,10 +19690,10 @@ SQLITE_PRIVATE const sqlite3_mem_methods *sqlite3MemGetMemsys3(void){
**
** This memory allocator uses the following algorithm:
**
-** 1. All memory allocations sizes are rounded up to a power of 2.
+** 1. All memory allocation 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.
+** then the two blocks are coalesced into the single larger block.
**
** 3. New memory is allocated from the first available free block.
**
@@ -16978,6 +19713,7 @@ SQLITE_PRIVATE const sqlite3_mem_methods *sqlite3MemGetMemsys3(void){
** The sqlite3_status() logic tracks the maximum values of n and M so
** that an application can, at any time, verify this constraint.
*/
+/* #include "sqliteInt.h" */
/*
** This version of the memory allocator is used only when
@@ -17046,7 +19782,7 @@ static SQLITE_WSD struct Mem5Global {
/*
** 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.
+ ** aiFreelist[2] holds free blocks of size szAtom*4. And so forth.
*/
int aiFreelist[LOGMAX+1];
@@ -17059,13 +19795,13 @@ static SQLITE_WSD struct Mem5Global {
} mem5;
/*
-** Access the static variable through a macro for SQLITE_OMIT_WSD
+** 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.
+** structures, return a pointer to the idx-th such link.
*/
#define MEM5LINK(idx) ((Mem5Link *)(&mem5.zPool[(idx)*mem5.szAtom]))
@@ -17112,9 +19848,7 @@ static void memsys5Link(int i, int iLogsize){
}
/*
-** 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.
+** Obtain or release the mutex needed to access global data structures.
*/
static void memsys5Enter(void){
sqlite3_mutex_enter(mem5.mutex);
@@ -17124,44 +19858,23 @@ static void memsys5Leave(void){
}
/*
-** 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.
+** Return the size of an outstanding allocation, in bytes.
+** 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));
- }
+ int iSize, i;
+ assert( p!=0 );
+ i = (int)(((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 guarantees that nByte is positive.
**
** The caller has obtained a mutex prior to invoking this
** routine so there is never any chance that two or more
@@ -17179,30 +19892,27 @@ static void *memsys5MallocUnsafe(int nByte){
/* Keep track of the maximum allocation request. Even unfulfilled
** requests are counted */
if( (u32)nByte>mem5.maxRequest ){
+ /* 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;
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++){}
+ 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++){}
+ for(iBin=iLogsize; iBin<=LOGMAX && mem5.aiFreelist[iBin]<0; iBin++){}
if( iBin>LOGMAX ){
testcase( sqlite3GlobalConfig.xLog!=0 );
sqlite3_log(SQLITE_NOMEM, "failed to allocate %u bytes", nByte);
return 0;
}
- i = memsys5UnlinkFirst(iBin);
+ i = mem5.aiFreelist[iBin];
+ memsys5Unlink(i, iBin);
while( iBin>iLogsize ){
int newSize;
@@ -17222,6 +19932,12 @@ static void *memsys5MallocUnsafe(int nByte){
if( mem5.maxCount<mem5.currentCount ) mem5.maxCount = mem5.currentCount;
if( mem5.maxOut<mem5.currentOut ) mem5.maxOut = mem5.currentOut;
+#ifdef SQLITE_DEBUG
+ /* Make sure the allocated memory does not assume that it is set to zero
+ ** or retains a value from a previous allocation */
+ memset(&mem5.zPool[i*mem5.szAtom], 0xAA, iFullSz);
+#endif
+
/* Return a pointer to the allocated memory. */
return (void*)&mem5.zPool[i*mem5.szAtom];
}
@@ -17236,7 +19952,7 @@ static void memsys5FreeUnsafe(void *pOld){
/* 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;
+ iBlock = (int)(((u8 *)pOld-mem5.zPool)/mem5.szAtom);
/* Check that the pointer pOld points to a valid, non-free block. */
assert( iBlock>=0 && iBlock<mem5.nBlock );
@@ -17279,11 +19995,18 @@ static void memsys5FreeUnsafe(void *pOld){
}
size *= 2;
}
+
+#ifdef SQLITE_DEBUG
+ /* Overwrite freed memory with the 0x55 bit pattern to verify that it is
+ ** not used after being freed */
+ memset(&mem5.zPool[iBlock*mem5.szAtom], 0x55, size);
+#endif
+
memsys5Link(iBlock, iLogsize);
}
/*
-** Allocate nBytes of memory
+** Allocate nBytes of memory.
*/
static void *memsys5Malloc(int nBytes){
sqlite3_int64 *p = 0;
@@ -17333,13 +20056,11 @@ static void *memsys5Realloc(void *pPrior, int nBytes){
if( nBytes<=nOld ){
return pPrior;
}
- memsys5Enter();
- p = memsys5MallocUnsafe(nBytes);
+ p = memsys5Malloc(nBytes);
if( p ){
memcpy(p, pPrior, nOld);
- memsys5FreeUnsafe(pPrior);
+ memsys5Free(pPrior);
}
- memsys5Leave();
return p;
}
@@ -17526,6 +20247,7 @@ SQLITE_PRIVATE const sqlite3_mem_methods *sqlite3MemGetMemsys5(void){
**
** This file contains code that is common across all mutex implementations.
*/
+/* #include "sqliteInt.h" */
#if defined(SQLITE_DEBUG) && !defined(SQLITE_MUTEX_OMIT)
/*
@@ -17534,7 +20256,7 @@ SQLITE_PRIVATE const sqlite3_mem_methods *sqlite3MemGetMemsys5(void){
** allocate a mutex while the system is uninitialized.
*/
static SQLITE_WSD int mutexIsInit = 0;
-#endif /* SQLITE_DEBUG */
+#endif /* SQLITE_DEBUG && !defined(SQLITE_MUTEX_OMIT) */
#ifndef SQLITE_MUTEX_OMIT
@@ -17557,11 +20279,18 @@ SQLITE_PRIVATE int sqlite3MutexInit(void){
}else{
pFrom = sqlite3NoopMutex();
}
- memcpy(pTo, pFrom, offsetof(sqlite3_mutex_methods, xMutexAlloc));
- memcpy(&pTo->xMutexFree, &pFrom->xMutexFree,
- sizeof(*pTo) - offsetof(sqlite3_mutex_methods, xMutexFree));
+ pTo->xMutexInit = pFrom->xMutexInit;
+ pTo->xMutexEnd = pFrom->xMutexEnd;
+ pTo->xMutexFree = pFrom->xMutexFree;
+ pTo->xMutexEnter = pFrom->xMutexEnter;
+ pTo->xMutexTry = pFrom->xMutexTry;
+ pTo->xMutexLeave = pFrom->xMutexLeave;
+ pTo->xMutexHeld = pFrom->xMutexHeld;
+ pTo->xMutexNotheld = pFrom->xMutexNotheld;
+ sqlite3MemoryBarrier();
pTo->xMutexAlloc = pFrom->xMutexAlloc;
}
+ assert( sqlite3GlobalConfig.mutex.xMutexInit );
rc = sqlite3GlobalConfig.mutex.xMutexInit();
#ifdef SQLITE_DEBUG
@@ -17591,10 +20320,12 @@ SQLITE_PRIVATE int sqlite3MutexEnd(void){
/*
** Retrieve a pointer to a static mutex or allocate a new dynamic one.
*/
-SQLITE_API sqlite3_mutex *sqlite3_mutex_alloc(int id){
+SQLITE_API sqlite3_mutex *SQLITE_STDCALL sqlite3_mutex_alloc(int id){
#ifndef SQLITE_OMIT_AUTOINIT
- if( sqlite3_initialize() ) return 0;
+ if( id<=SQLITE_MUTEX_RECURSIVE && sqlite3_initialize() ) return 0;
+ if( id>SQLITE_MUTEX_RECURSIVE && sqlite3MutexInit() ) return 0;
#endif
+ assert( sqlite3GlobalConfig.mutex.xMutexAlloc );
return sqlite3GlobalConfig.mutex.xMutexAlloc(id);
}
@@ -17603,14 +20334,16 @@ SQLITE_PRIVATE sqlite3_mutex *sqlite3MutexAlloc(int id){
return 0;
}
assert( GLOBAL(int, mutexIsInit) );
+ assert( sqlite3GlobalConfig.mutex.xMutexAlloc );
return sqlite3GlobalConfig.mutex.xMutexAlloc(id);
}
/*
** Free a dynamic mutex.
*/
-SQLITE_API void sqlite3_mutex_free(sqlite3_mutex *p){
+SQLITE_API void SQLITE_STDCALL sqlite3_mutex_free(sqlite3_mutex *p){
if( p ){
+ assert( sqlite3GlobalConfig.mutex.xMutexFree );
sqlite3GlobalConfig.mutex.xMutexFree(p);
}
}
@@ -17619,8 +20352,9 @@ SQLITE_API void sqlite3_mutex_free(sqlite3_mutex *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){
+SQLITE_API void SQLITE_STDCALL sqlite3_mutex_enter(sqlite3_mutex *p){
if( p ){
+ assert( sqlite3GlobalConfig.mutex.xMutexEnter );
sqlite3GlobalConfig.mutex.xMutexEnter(p);
}
}
@@ -17629,9 +20363,10 @@ SQLITE_API void sqlite3_mutex_enter(sqlite3_mutex *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){
+SQLITE_API int SQLITE_STDCALL sqlite3_mutex_try(sqlite3_mutex *p){
int rc = SQLITE_OK;
if( p ){
+ assert( sqlite3GlobalConfig.mutex.xMutexTry );
return sqlite3GlobalConfig.mutex.xMutexTry(p);
}
return rc;
@@ -17643,8 +20378,9 @@ SQLITE_API int sqlite3_mutex_try(sqlite3_mutex *p){
** 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){
+SQLITE_API void SQLITE_STDCALL sqlite3_mutex_leave(sqlite3_mutex *p){
if( p ){
+ assert( sqlite3GlobalConfig.mutex.xMutexLeave );
sqlite3GlobalConfig.mutex.xMutexLeave(p);
}
}
@@ -17654,10 +20390,12 @@ SQLITE_API void sqlite3_mutex_leave(sqlite3_mutex *p){
** 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){
+SQLITE_API int SQLITE_STDCALL sqlite3_mutex_held(sqlite3_mutex *p){
+ assert( p==0 || sqlite3GlobalConfig.mutex.xMutexHeld );
return p==0 || sqlite3GlobalConfig.mutex.xMutexHeld(p);
}
-SQLITE_API int sqlite3_mutex_notheld(sqlite3_mutex *p){
+SQLITE_API int SQLITE_STDCALL sqlite3_mutex_notheld(sqlite3_mutex *p){
+ assert( p==0 || sqlite3GlobalConfig.mutex.xMutexNotheld );
return p==0 || sqlite3GlobalConfig.mutex.xMutexNotheld(p);
}
#endif
@@ -17693,6 +20431,7 @@ SQLITE_API int sqlite3_mutex_notheld(sqlite3_mutex *p){
** that does error checking on mutexes to make sure they are being
** called correctly.
*/
+/* #include "sqliteInt.h" */
#ifndef SQLITE_MUTEX_OMIT
@@ -17774,7 +20513,7 @@ static int debugMutexEnd(void){ return SQLITE_OK; }
** that means that a mutex could not be allocated.
*/
static sqlite3_mutex *debugMutexAlloc(int id){
- static sqlite3_debug_mutex aStatic[6];
+ static sqlite3_debug_mutex aStatic[SQLITE_MUTEX_STATIC_VFS3 - 1];
sqlite3_debug_mutex *pNew = 0;
switch( id ){
case SQLITE_MUTEX_FAST:
@@ -17787,8 +20526,12 @@ static sqlite3_mutex *debugMutexAlloc(int id){
break;
}
default: {
- assert( id-2 >= 0 );
- assert( id-2 < (int)(sizeof(aStatic)/sizeof(aStatic[0])) );
+#ifdef SQLITE_ENABLE_API_ARMOR
+ if( id-2<0 || id-2>=ArraySize(aStatic) ){
+ (void)SQLITE_MISUSE_BKPT;
+ return 0;
+ }
+#endif
pNew = &aStatic[id-2];
pNew->id = id;
break;
@@ -17803,8 +20546,13 @@ static sqlite3_mutex *debugMutexAlloc(int id){
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);
+ if( p->id==SQLITE_MUTEX_RECURSIVE || p->id==SQLITE_MUTEX_FAST ){
+ sqlite3_free(p);
+ }else{
+#ifdef SQLITE_ENABLE_API_ARMOR
+ (void)SQLITE_MISUSE_BKPT;
+#endif
+ }
}
/*
@@ -17887,6 +20635,7 @@ SQLITE_PRIVATE sqlite3_mutex_methods const *sqlite3DefaultMutex(void){
*************************************************************************
** This file contains the C functions that implement mutexes for pthreads
*/
+/* #include "sqliteInt.h" */
/*
** The code in this file is only used if we are compiling threadsafe
@@ -17915,15 +20664,19 @@ SQLITE_PRIVATE sqlite3_mutex_methods const *sqlite3DefaultMutex(void){
*/
struct sqlite3_mutex {
pthread_mutex_t mutex; /* Mutex controlling the lock */
-#if SQLITE_MUTEX_NREF
+#if SQLITE_MUTEX_NREF || defined(SQLITE_ENABLE_API_ARMOR)
int id; /* Mutex type */
+#endif
+#if SQLITE_MUTEX_NREF
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 }
+#define SQLITE3_MUTEX_INITIALIZER {PTHREAD_MUTEX_INITIALIZER,0,0,(pthread_t)0,0}
+#elif defined(SQLITE_ENABLE_API_ARMOR)
+#define SQLITE3_MUTEX_INITIALIZER { PTHREAD_MUTEX_INITIALIZER, 0 }
#else
#define SQLITE3_MUTEX_INITIALIZER { PTHREAD_MUTEX_INITIALIZER }
#endif
@@ -17954,6 +20707,19 @@ static int pthreadMutexNotheld(sqlite3_mutex *p){
#endif
/*
+** Try to provide a memory barrier operation, needed for initialization
+** and also for the implementation of xShmBarrier in the VFS in cases
+** where SQLite is compiled without mutexes.
+*/
+SQLITE_PRIVATE void sqlite3MemoryBarrier(void){
+#if defined(SQLITE_MEMORY_BARRIER)
+ SQLITE_MEMORY_BARRIER;
+#elif defined(__GNUC__) && GCC_VERSION>=4001000
+ __sync_synchronize();
+#endif
+}
+
+/*
** Initialize and deinitialize the mutex subsystem.
*/
static int pthreadMutexInit(void){ return SQLITE_OK; }
@@ -17971,10 +20737,16 @@ static int pthreadMutexEnd(void){ return SQLITE_OK; }
** <li> SQLITE_MUTEX_RECURSIVE
** <li> SQLITE_MUTEX_STATIC_MASTER
** <li> SQLITE_MUTEX_STATIC_MEM
-** <li> SQLITE_MUTEX_STATIC_MEM2
+** <li> SQLITE_MUTEX_STATIC_OPEN
** <li> SQLITE_MUTEX_STATIC_PRNG
** <li> SQLITE_MUTEX_STATIC_LRU
** <li> SQLITE_MUTEX_STATIC_PMEM
+** <li> SQLITE_MUTEX_STATIC_APP1
+** <li> SQLITE_MUTEX_STATIC_APP2
+** <li> SQLITE_MUTEX_STATIC_APP3
+** <li> SQLITE_MUTEX_STATIC_VFS1
+** <li> SQLITE_MUTEX_STATIC_VFS2
+** <li> SQLITE_MUTEX_STATIC_VFS3
** </ul>
**
** The first two constants cause sqlite3_mutex_alloc() to create
@@ -18008,6 +20780,12 @@ static sqlite3_mutex *pthreadMutexAlloc(int iType){
SQLITE3_MUTEX_INITIALIZER,
SQLITE3_MUTEX_INITIALIZER,
SQLITE3_MUTEX_INITIALIZER,
+ SQLITE3_MUTEX_INITIALIZER,
+ SQLITE3_MUTEX_INITIALIZER,
+ SQLITE3_MUTEX_INITIALIZER,
+ SQLITE3_MUTEX_INITIALIZER,
+ SQLITE3_MUTEX_INITIALIZER,
+ SQLITE3_MUTEX_INITIALIZER,
SQLITE3_MUTEX_INITIALIZER
};
sqlite3_mutex *p;
@@ -18027,32 +20805,30 @@ static sqlite3_mutex *pthreadMutexAlloc(int iType){
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;
+#ifdef SQLITE_ENABLE_API_ARMOR
+ if( iType-2<0 || iType-2>=ArraySize(staticMutexes) ){
+ (void)SQLITE_MISUSE_BKPT;
+ return 0;
+ }
#endif
+ p = &staticMutexes[iType-2];
break;
}
}
+#if SQLITE_MUTEX_NREF || defined(SQLITE_ENABLE_API_ARMOR)
+ if( p ) p->id = iType;
+#endif
return p;
}
@@ -18064,9 +20840,18 @@ static sqlite3_mutex *pthreadMutexAlloc(int iType){
*/
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);
+#if SQLITE_ENABLE_API_ARMOR
+ if( p->id==SQLITE_MUTEX_FAST || p->id==SQLITE_MUTEX_RECURSIVE )
+#endif
+ {
+ pthread_mutex_destroy(&p->mutex);
+ sqlite3_free(p);
+ }
+#ifdef SQLITE_ENABLE_API_ARMOR
+ else{
+ (void)SQLITE_MISUSE_BKPT;
+ }
+#endif
}
/*
@@ -18238,12 +21023,315 @@ SQLITE_PRIVATE sqlite3_mutex_methods const *sqlite3DefaultMutex(void){
** May you share freely, never taking more than you give.
**
*************************************************************************
-** This file contains the C functions that implement mutexes for win32
+** This file contains the C functions that implement mutexes for Win32.
+*/
+/* #include "sqliteInt.h" */
+
+#if SQLITE_OS_WIN
+/*
+** Include code that is common to all os_*.c files
+*/
+/************** Include os_common.h in the middle of mutex_w32.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
+
+/*
+** 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 mutex_w32.c ******************/
+
+/*
+** Include the header file for the Windows VFS.
+*/
+/************** Include os_win.h in the middle of mutex_w32.c ****************/
+/************** Begin file os_win.h ******************************************/
+/*
+** 2013 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 that is specific to Windows.
+*/
+#ifndef _OS_WIN_H_
+#define _OS_WIN_H_
+
+/*
+** Include the primary Windows SDK header file.
+*/
+#include "windows.h"
+
+#ifdef __CYGWIN__
+# include <sys/cygwin.h>
+# include <errno.h> /* amalgamator: dontcache */
+#endif
+
+/*
+** Determine if we are dealing with Windows NT.
+**
+** We ought to be able to determine if we are compiling for Windows 9x or
+** Windows NT using the _WIN32_WINNT macro as follows:
+**
+** #if defined(_WIN32_WINNT)
+** # define SQLITE_OS_WINNT 1
+** #else
+** # define SQLITE_OS_WINNT 0
+** #endif
+**
+** However, Visual Studio 2005 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 Windows NT 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 Windows CE - 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
+
+/*
+** For WinCE, some API function parameters do not appear to be declared as
+** volatile.
*/
+#if SQLITE_OS_WINCE
+# define SQLITE_WIN32_VOLATILE
+#else
+# define SQLITE_WIN32_VOLATILE volatile
+#endif
+
+/*
+** For some Windows sub-platforms, the _beginthreadex() / _endthreadex()
+** functions are not available (e.g. those not using MSVC, Cygwin, etc).
+*/
+#if SQLITE_OS_WIN && !SQLITE_OS_WINCE && !SQLITE_OS_WINRT && \
+ SQLITE_THREADSAFE>0 && !defined(__CYGWIN__)
+# define SQLITE_OS_WIN_THREADS 1
+#else
+# define SQLITE_OS_WIN_THREADS 0
+#endif
+
+#endif /* _OS_WIN_H_ */
+
+/************** End of os_win.h **********************************************/
+/************** Continuing where we left off in mutex_w32.c ******************/
+#endif
/*
** The code in this file is only used if we are compiling multithreaded
-** on a win32 system.
+** on a Win32 system.
*/
#ifdef SQLITE_MUTEX_W32
@@ -18256,48 +21344,22 @@ struct sqlite3_mutex {
#ifdef SQLITE_DEBUG
volatile int nRef; /* Number of enterances */
volatile DWORD owner; /* Thread holding this mutex */
- int trace; /* True to trace changes */
+ volatile 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.
+** These are the initializer values used when declaring a "static" mutex
+** on Win32. It should be noted that all mutexes require initialization
+** on the Win32 platform.
*/
-#if 0
-#if SQLITE_OS_WINCE || SQLITE_OS_WINRT
-# define mutexIsNT() (1)
+#define SQLITE_W32_MUTEX_INITIALIZER { 0 }
+
+#ifdef SQLITE_DEBUG
+#define SQLITE3_MUTEX_INITIALIZER { SQLITE_W32_MUTEX_INITIALIZER, 0, \
+ 0L, (DWORD)0, 0 }
#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 */
+#define SQLITE3_MUTEX_INITIALIZER { SQLITE_W32_MUTEX_INITIALIZER, 0 }
#endif
#ifdef SQLITE_DEBUG
@@ -18308,20 +21370,45 @@ struct sqlite3_mutex {
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();
+ DWORD tid = GetCurrentThreadId();
return winMutexNotheld2(p, tid);
}
#endif
+/*
+** Try to provide a memory barrier operation, needed for initialization
+** and also for the xShmBarrier method of the VFS in cases when SQLite is
+** compiled without mutexes (SQLITE_THREADSAFE=0).
+*/
+SQLITE_PRIVATE void sqlite3MemoryBarrier(void){
+#if defined(SQLITE_MEMORY_BARRIER)
+ SQLITE_MEMORY_BARRIER;
+#elif defined(__GNUC__)
+ __sync_synchronize();
+#elif !defined(SQLITE_DISABLE_INTRINSIC) && \
+ defined(_MSC_VER) && _MSC_VER>=1300
+ _ReadWriteBarrier();
+#elif defined(MemoryBarrier)
+ MemoryBarrier();
+#endif
+}
/*
** Initialize and deinitialize the mutex subsystem.
*/
-static sqlite3_mutex winMutex_staticMutexes[6] = {
+static sqlite3_mutex winMutex_staticMutexes[] = {
+ SQLITE3_MUTEX_INITIALIZER,
+ SQLITE3_MUTEX_INITIALIZER,
+ SQLITE3_MUTEX_INITIALIZER,
+ SQLITE3_MUTEX_INITIALIZER,
+ SQLITE3_MUTEX_INITIALIZER,
+ SQLITE3_MUTEX_INITIALIZER,
SQLITE3_MUTEX_INITIALIZER,
SQLITE3_MUTEX_INITIALIZER,
SQLITE3_MUTEX_INITIALIZER,
@@ -18329,17 +21416,20 @@ static sqlite3_mutex winMutex_staticMutexes[6] = {
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 int winMutex_isNt = -1; /* <0 means "need to query" */
+
+/* As the winMutexInit() and winMutexEnd() functions are called as part
+** of the sqlite3_initialize() and sqlite3_shutdown() processing, the
+** "interlocked" magic used here is probably not strictly necessary.
*/
-static long winMutex_lock = 0;
+static LONG SQLITE_WIN32_VOLATILE winMutex_lock = 0;
-SQLITE_API void sqlite3_win32_sleep(DWORD milliseconds); /* os_win.c */
+SQLITE_API int SQLITE_STDCALL sqlite3_win32_is_nt(void); /* os_win.c */
+SQLITE_API void SQLITE_STDCALL sqlite3_win32_sleep(DWORD milliseconds); /* os_win.c */
-static int winMutexInit(void){
+static int winMutexInit(void){
/* The first to increment to 1 does actual initialization */
if( InterlockedCompareExchange(&winMutex_lock, 1, 0)==0 ){
int i;
@@ -18352,16 +21442,17 @@ static int winMutexInit(void){
}
winMutex_isInit = 1;
}else{
- /* Someone else is in the process of initing the static mutexes */
+ /* Another thread is (in the process of) initializing the static
+ ** mutexes */
while( !winMutex_isInit ){
sqlite3_win32_sleep(1);
}
}
- return SQLITE_OK;
+ return SQLITE_OK;
}
-static int winMutexEnd(void){
- /* The first to decrement to 0 does actual shutdown
+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 ){
@@ -18372,7 +21463,7 @@ static int winMutexEnd(void){
winMutex_isInit = 0;
}
}
- return SQLITE_OK;
+ return SQLITE_OK;
}
/*
@@ -18387,10 +21478,16 @@ static int winMutexEnd(void){
** <li> SQLITE_MUTEX_RECURSIVE
** <li> SQLITE_MUTEX_STATIC_MASTER
** <li> SQLITE_MUTEX_STATIC_MEM
-** <li> SQLITE_MUTEX_STATIC_MEM2
+** <li> SQLITE_MUTEX_STATIC_OPEN
** <li> SQLITE_MUTEX_STATIC_PRNG
** <li> SQLITE_MUTEX_STATIC_LRU
** <li> SQLITE_MUTEX_STATIC_PMEM
+** <li> SQLITE_MUTEX_STATIC_APP1
+** <li> SQLITE_MUTEX_STATIC_APP2
+** <li> SQLITE_MUTEX_STATIC_APP3
+** <li> SQLITE_MUTEX_STATIC_VFS1
+** <li> SQLITE_MUTEX_STATIC_VFS2
+** <li> SQLITE_MUTEX_STATIC_VFS3
** </ul>
**
** The first two constants cause sqlite3_mutex_alloc() to create
@@ -18413,7 +21510,7 @@ static int winMutexEnd(void){
**
** 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
+** 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.
*/
@@ -18424,9 +21521,12 @@ static sqlite3_mutex *winMutexAlloc(int iType){
case SQLITE_MUTEX_FAST:
case SQLITE_MUTEX_RECURSIVE: {
p = sqlite3MallocZero( sizeof(*p) );
- if( p ){
-#ifdef SQLITE_DEBUG
+ if( p ){
p->id = iType;
+#ifdef SQLITE_DEBUG
+#ifdef SQLITE_WIN32_MUTEX_TRACE_DYNAMIC
+ p->trace = 1;
+#endif
#endif
#if SQLITE_OS_WINRT
InitializeCriticalSectionEx(&p->mutex, 0, 0);
@@ -18437,12 +21537,18 @@ static sqlite3_mutex *winMutexAlloc(int iType){
break;
}
default: {
- assert( winMutex_isInit==1 );
- assert( iType-2 >= 0 );
- assert( iType-2 < ArraySize(winMutex_staticMutexes) );
+#ifdef SQLITE_ENABLE_API_ARMOR
+ if( iType-2<0 || iType-2>=ArraySize(winMutex_staticMutexes) ){
+ (void)SQLITE_MISUSE_BKPT;
+ return 0;
+ }
+#endif
p = &winMutex_staticMutexes[iType-2];
-#ifdef SQLITE_DEBUG
p->id = iType;
+#ifdef SQLITE_DEBUG
+#ifdef SQLITE_WIN32_MUTEX_TRACE_STATIC
+ p->trace = 1;
+#endif
#endif
break;
}
@@ -18459,9 +21565,14 @@ static sqlite3_mutex *winMutexAlloc(int iType){
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);
+ if( p->id==SQLITE_MUTEX_FAST || p->id==SQLITE_MUTEX_RECURSIVE ){
+ DeleteCriticalSection(&p->mutex);
+ sqlite3_free(p);
+ }else{
+#ifdef SQLITE_ENABLE_API_ARMOR
+ (void)SQLITE_MISUSE_BKPT;
+#endif
+ }
}
/*
@@ -18476,30 +21587,39 @@ static void winMutexFree(sqlite3_mutex *p){
** more than once, the behavior is undefined.
*/
static void winMutexEnter(sqlite3_mutex *p){
+#if defined(SQLITE_DEBUG) || defined(SQLITE_TEST)
+ DWORD tid = GetCurrentThreadId();
+#endif
#ifdef SQLITE_DEBUG
- DWORD tid = GetCurrentThreadId();
+ assert( p );
assert( p->id==SQLITE_MUTEX_RECURSIVE || winMutexNotheld2(p, tid) );
+#else
+ assert( p );
#endif
+ assert( winMutex_isInit==1 );
EnterCriticalSection(&p->mutex);
#ifdef SQLITE_DEBUG
assert( p->nRef>0 || p->owner==0 );
- p->owner = tid;
+ p->owner = tid;
p->nRef++;
if( p->trace ){
- printf("enter mutex %p (%d) with nRef=%d\n", p, p->trace, p->nRef);
+ OSTRACE(("ENTER-MUTEX tid=%lu, mutex=%p (%d), nRef=%d\n",
+ tid, p, p->trace, p->nRef));
}
#endif
}
+
static int winMutexTry(sqlite3_mutex *p){
-#ifndef NDEBUG
- DWORD tid = GetCurrentThreadId();
+#if defined(SQLITE_DEBUG) || defined(SQLITE_TEST)
+ DWORD tid = GetCurrentThreadId();
#endif
int rc = SQLITE_BUSY;
+ assert( p );
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.
+ ** fail.
**
** The TryEnterCriticalSection() interface is only available on WinNT.
** And some windows compilers complain if you try to use it without
@@ -18507,18 +21627,27 @@ static int winMutexTry(sqlite3_mutex *p){
** For that reason, we will omit this optimization for now. See
** ticket #2685.
*/
-#if 0
- if( mutexIsNT() && TryEnterCriticalSection(&p->mutex) ){
+#if defined(_WIN32_WINNT) && _WIN32_WINNT >= 0x0400
+ assert( winMutex_isInit==1 );
+ assert( winMutex_isNt>=-1 && winMutex_isNt<=1 );
+ if( winMutex_isNt<0 ){
+ winMutex_isNt = sqlite3_win32_is_nt();
+ }
+ assert( winMutex_isNt==0 || winMutex_isNt==1 );
+ if( winMutex_isNt && TryEnterCriticalSection(&p->mutex) ){
+#ifdef SQLITE_DEBUG
p->owner = tid;
p->nRef++;
+#endif
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);
+ if( p->trace ){
+ OSTRACE(("TRY-MUTEX tid=%lu, mutex=%p (%d), owner=%lu, nRef=%d, rc=%s\n",
+ tid, p, p->trace, p->owner, p->nRef, sqlite3ErrName(rc)));
}
#endif
return rc;
@@ -18531,18 +21660,23 @@ static int winMutexTry(sqlite3_mutex *p){
** is not currently allocated. SQLite will never do either.
*/
static void winMutexLeave(sqlite3_mutex *p){
-#ifndef NDEBUG
+#if defined(SQLITE_DEBUG) || defined(SQLITE_TEST)
DWORD tid = GetCurrentThreadId();
+#endif
+ assert( p );
+#ifdef SQLITE_DEBUG
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
+ assert( winMutex_isInit==1 );
LeaveCriticalSection(&p->mutex);
#ifdef SQLITE_DEBUG
if( p->trace ){
- printf("leave mutex %p (%d) with nRef=%d\n", p, p->trace, p->nRef);
+ OSTRACE(("LEAVE-MUTEX tid=%lu, mutex=%p (%d), nRef=%d\n",
+ tid, p, p->trace, p->nRef));
}
#endif
}
@@ -18564,9 +21698,9 @@ SQLITE_PRIVATE sqlite3_mutex_methods const *sqlite3DefaultMutex(void){
0
#endif
};
-
return &sMutex;
}
+
#endif /* SQLITE_MUTEX_W32 */
/************** End of mutex_w32.c *******************************************/
@@ -18585,6 +21719,7 @@ SQLITE_PRIVATE sqlite3_mutex_methods const *sqlite3DefaultMutex(void){
**
** Memory allocation functions used throughout sqlite.
*/
+/* #include "sqliteInt.h" */
/* #include <stdarg.h> */
/*
@@ -18592,7 +21727,7 @@ SQLITE_PRIVATE sqlite3_mutex_methods const *sqlite3DefaultMutex(void){
** 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){
+SQLITE_API int SQLITE_STDCALL sqlite3_release_memory(int n){
#ifdef SQLITE_ENABLE_MEMORY_MANAGEMENT
return sqlite3PcacheReleaseMemory(n);
#else
@@ -18617,16 +21752,7 @@ typedef struct ScratchFreeslot {
*/
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;
+ sqlite3_int64 alarmThreshold; /* The soft heap limit */
/*
** Pointers to the end of sqlite3GlobalConfig.pScratch memory
@@ -18643,54 +21769,32 @@ static SQLITE_WSD struct Mem0Global {
** sqlite3_soft_heap_limit() setting.
*/
int nearlyFull;
-} mem0 = { 0, 0, 0, 0, 0, 0, 0, 0 };
+} mem0 = { 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.
+** Return the memory allocator mutex. sqlite3_status() needs it.
*/
-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;
+SQLITE_PRIVATE sqlite3_mutex *sqlite3MallocMutex(void){
+ return mem0.mutex;
}
#ifndef SQLITE_OMIT_DEPRECATED
/*
-** Deprecated external interface. Internal/core SQLite code
-** should call sqlite3MemoryAlarm.
+** Deprecated external interface. It used to set an alarm callback
+** that was invoked when memory usage grew too large. Now it is a
+** no-op.
*/
-SQLITE_API int sqlite3_memory_alarm(
+SQLITE_API int SQLITE_STDCALL sqlite3_memory_alarm(
void(*xCallback)(void *pArg, sqlite3_int64 used,int N),
void *pArg,
sqlite3_int64 iThreshold
){
- return sqlite3MemoryAlarm(xCallback, pArg, iThreshold);
+ (void)xCallback;
+ (void)pArg;
+ (void)iThreshold;
+ return SQLITE_OK;
}
#endif
@@ -18698,27 +21802,29 @@ SQLITE_API int sqlite3_memory_alarm(
** 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){
+SQLITE_API sqlite3_int64 SQLITE_STDCALL sqlite3_soft_heap_limit64(sqlite3_int64 n){
sqlite3_int64 priorLimit;
sqlite3_int64 excess;
+ sqlite3_int64 nUsed;
#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);
+ if( n<0 ){
+ sqlite3_mutex_leave(mem0.mutex);
+ return priorLimit;
}
+ mem0.alarmThreshold = n;
+ nUsed = sqlite3StatusValue(SQLITE_STATUS_MEMORY_USED);
+ mem0.nearlyFull = (n>0 && n<=nUsed);
+ sqlite3_mutex_leave(mem0.mutex);
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){
+SQLITE_API void SQLITE_STDCALL sqlite3_soft_heap_limit(int n){
if( n<0 ) n = 0;
sqlite3_soft_heap_limit64(n);
}
@@ -18727,13 +21833,12 @@ SQLITE_API void sqlite3_soft_heap_limit(int n){
** Initialize the memory allocation subsystem.
*/
SQLITE_PRIVATE int sqlite3MallocInit(void){
+ int rc;
if( sqlite3GlobalConfig.m.xMalloc==0 ){
sqlite3MemSetDefault();
}
memset(&mem0, 0, sizeof(mem0));
- if( sqlite3GlobalConfig.bCoreMutex ){
- mem0.mutex = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MEM);
- }
+ mem0.mutex = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MEM);
if( sqlite3GlobalConfig.pScratch && sqlite3GlobalConfig.szScratch>=100
&& sqlite3GlobalConfig.nScratch>0 ){
int i, n, sz;
@@ -18757,12 +21862,13 @@ SQLITE_PRIVATE int sqlite3MallocInit(void){
sqlite3GlobalConfig.nScratch = 0;
}
if( sqlite3GlobalConfig.pPage==0 || sqlite3GlobalConfig.szPage<512
- || sqlite3GlobalConfig.nPage<1 ){
+ || sqlite3GlobalConfig.nPage<=0 ){
sqlite3GlobalConfig.pPage = 0;
sqlite3GlobalConfig.szPage = 0;
- sqlite3GlobalConfig.nPage = 0;
}
- return sqlite3GlobalConfig.m.xInit(sqlite3GlobalConfig.m.pAppData);
+ rc = sqlite3GlobalConfig.m.xInit(sqlite3GlobalConfig.m.pAppData);
+ if( rc!=SQLITE_OK ) memset(&mem0, 0, sizeof(mem0));
+ return rc;
}
/*
@@ -18787,11 +21893,9 @@ SQLITE_PRIVATE void sqlite3MallocEnd(void){
/*
** 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 */
+SQLITE_API sqlite3_int64 SQLITE_STDCALL sqlite3_memory_used(void){
+ sqlite3_int64 res, mx;
+ sqlite3_status64(SQLITE_STATUS_MEMORY_USED, &res, &mx, 0);
return res;
}
@@ -18800,31 +21904,20 @@ SQLITE_API sqlite3_int64 sqlite3_memory_used(void){
** 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;
+SQLITE_API sqlite3_int64 SQLITE_STDCALL sqlite3_memory_highwater(int resetFlag){
+ sqlite3_int64 res, mx;
+ sqlite3_status64(SQLITE_STATUS_MEMORY_USED, &res, &mx, resetFlag);
+ return mx;
}
/*
** 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;
+ if( mem0.alarmThreshold<=0 ) return;
sqlite3_mutex_leave(mem0.mutex);
- xCallback(pArg, nowUsed, nByte);
+ sqlite3_release_memory(nByte);
sqlite3_mutex_enter(mem0.mutex);
- mem0.alarmCallback = xCallback;
- mem0.alarmArg = pArg;
}
/*
@@ -18836,9 +21929,9 @@ static int mallocWithAlarm(int n, void **pp){
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);
+ sqlite3StatusHighwater(SQLITE_STATUS_MALLOC_SIZE, n);
+ if( mem0.alarmThreshold>0 ){
+ sqlite3_int64 nUsed = sqlite3StatusValue(SQLITE_STATUS_MEMORY_USED);
if( nUsed >= mem0.alarmThreshold - nFull ){
mem0.nearlyFull = 1;
sqlite3MallocAlarm(nFull);
@@ -18848,15 +21941,15 @@ static int mallocWithAlarm(int n, void **pp){
}
p = sqlite3GlobalConfig.m.xMalloc(nFull);
#ifdef SQLITE_ENABLE_MEMORY_MANAGEMENT
- if( p==0 && mem0.alarmCallback ){
+ if( p==0 && mem0.alarmThreshold>0 ){
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);
+ sqlite3StatusUp(SQLITE_STATUS_MEMORY_USED, nFull);
+ sqlite3StatusUp(SQLITE_STATUS_MALLOC_COUNT, 1);
}
*pp = p;
return nFull;
@@ -18866,11 +21959,9 @@ static int mallocWithAlarm(int n, void **pp){
** 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){
+SQLITE_PRIVATE void *sqlite3Malloc(u64 n){
void *p;
- if( n<=0 /* IMP: R-65312-04917 */
- || n>=0x7fffff00
- ){
+ if( n==0 || 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
@@ -18879,12 +21970,12 @@ SQLITE_PRIVATE void *sqlite3Malloc(int n){
p = 0;
}else if( sqlite3GlobalConfig.bMemstat ){
sqlite3_mutex_enter(mem0.mutex);
- mallocWithAlarm(n, &p);
+ mallocWithAlarm((int)n, &p);
sqlite3_mutex_leave(mem0.mutex);
}else{
- p = sqlite3GlobalConfig.m.xMalloc(n);
+ p = sqlite3GlobalConfig.m.xMalloc((int)n);
}
- assert( EIGHT_BYTE_ALIGNMENT(p) ); /* IMP: R-04675-44850 */
+ assert( EIGHT_BYTE_ALIGNMENT(p) ); /* IMP: R-11148-40995 */
return p;
}
@@ -18893,7 +21984,13 @@ SQLITE_PRIVATE void *sqlite3Malloc(int n){
** First make sure the memory subsystem is initialized, then do the
** allocation.
*/
-SQLITE_API void *sqlite3_malloc(int n){
+SQLITE_API void *SQLITE_STDCALL sqlite3_malloc(int n){
+#ifndef SQLITE_OMIT_AUTOINIT
+ if( sqlite3_initialize() ) return 0;
+#endif
+ return n<=0 ? 0 : sqlite3Malloc(n);
+}
+SQLITE_API void *SQLITE_STDCALL sqlite3_malloc64(sqlite3_uint64 n){
#ifndef SQLITE_OMIT_AUTOINIT
if( sqlite3_initialize() ) return 0;
#endif
@@ -18924,22 +22021,20 @@ SQLITE_PRIVATE void *sqlite3ScratchMalloc(int n){
assert( n>0 );
sqlite3_mutex_enter(mem0.mutex);
+ sqlite3StatusHighwater(SQLITE_STATUS_SCRATCH_SIZE, n);
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);
+ sqlite3StatusUp(SQLITE_STATUS_SCRATCH_USED, 1);
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 = sqlite3Malloc(n);
+ if( sqlite3GlobalConfig.bMemstat && p ){
+ sqlite3_mutex_enter(mem0.mutex);
+ sqlite3StatusUp(SQLITE_STATUS_SCRATCH_OVERFLOW, sqlite3MallocSize(p));
sqlite3_mutex_leave(mem0.mutex);
- p = sqlite3GlobalConfig.m.xMalloc(n);
}
sqlite3MemdebugSetType(p, MEMTYPE_SCRATCH);
}
@@ -18947,11 +22042,12 @@ SQLITE_PRIVATE void *sqlite3ScratchMalloc(int n){
#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 );
+ /* EVIDENCE-OF: R-12970-05880 SQLite will not use more than one scratch
+ ** buffers per thread.
+ **
+ ** This can only be checked in single-threaded mode.
+ */
+ assert( scratchAllocOut==0 );
if( p ) scratchAllocOut++;
#endif
@@ -18969,7 +22065,7 @@ SQLITE_PRIVATE void sqlite3ScratchFree(void *p){
scratchAllocOut--;
#endif
- if( p>=sqlite3GlobalConfig.pScratch && p<mem0.pScratchEnd ){
+ if( SQLITE_WITHIN(p, sqlite3GlobalConfig.pScratch, mem0.pScratchEnd) ){
/* Release memory from the SQLITE_CONFIG_SCRATCH allocation */
ScratchFreeslot *pSlot;
pSlot = (ScratchFreeslot*)p;
@@ -18978,19 +22074,19 @@ SQLITE_PRIVATE void sqlite3ScratchFree(void *p){
mem0.pScratchFree = pSlot;
mem0.nScratchFree++;
assert( mem0.nScratchFree <= (u32)sqlite3GlobalConfig.nScratch );
- sqlite3StatusAdd(SQLITE_STATUS_SCRATCH_USED, -1);
+ sqlite3StatusDown(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) );
+ assert( sqlite3MemdebugNoType(p, (u8)~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);
+ sqlite3StatusDown(SQLITE_STATUS_SCRATCH_OVERFLOW, iSize);
+ sqlite3StatusDown(SQLITE_STATUS_MEMORY_USED, iSize);
+ sqlite3StatusDown(SQLITE_STATUS_MALLOC_COUNT, 1);
sqlite3GlobalConfig.m.xFree(p);
sqlite3_mutex_leave(mem0.mutex);
}else{
@@ -19005,7 +22101,7 @@ SQLITE_PRIVATE void sqlite3ScratchFree(void *p){
*/
#ifndef SQLITE_OMIT_LOOKASIDE
static int isLookaside(sqlite3 *db, void *p){
- return p && p>=db->lookaside.pStart && p<db->lookaside.pEnd;
+ return SQLITE_WITHIN(p, db->lookaside.pStart, db->lookaside.pEnd);
}
#else
#define isLookaside(A,B) 0
@@ -19017,32 +22113,43 @@ static int isLookaside(sqlite3 *db, void *p){
*/
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) );
+ assert( p!=0 );
+ if( db==0 || !isLookaside(db,p) ){
+#if SQLITE_DEBUG
+ if( db==0 ){
+ assert( sqlite3MemdebugNoType(p, (u8)~MEMTYPE_HEAP) );
+ assert( sqlite3MemdebugHasType(p, MEMTYPE_HEAP) );
+ }else{
+ assert( sqlite3MemdebugHasType(p, (MEMTYPE_LOOKASIDE|MEMTYPE_HEAP)) );
+ assert( sqlite3MemdebugNoType(p, (u8)~(MEMTYPE_LOOKASIDE|MEMTYPE_HEAP)) );
+ }
+#endif
return sqlite3GlobalConfig.m.xSize(p);
+ }else{
+ assert( sqlite3_mutex_held(db->mutex) );
+ return db->lookaside.sz;
}
}
+SQLITE_API sqlite3_uint64 SQLITE_STDCALL sqlite3_msize(void *p){
+ assert( sqlite3MemdebugNoType(p, (u8)~MEMTYPE_HEAP) );
+ assert( sqlite3MemdebugHasType(p, MEMTYPE_HEAP) );
+ return p ? sqlite3GlobalConfig.m.xSize(p) : 0;
+}
/*
** Free memory previously obtained from sqlite3Malloc().
*/
-SQLITE_API void sqlite3_free(void *p){
+SQLITE_API void SQLITE_STDCALL sqlite3_free(void *p){
if( p==0 ) return; /* IMP: R-49053-54554 */
- assert( sqlite3MemdebugNoType(p, MEMTYPE_DB) );
assert( sqlite3MemdebugHasType(p, MEMTYPE_HEAP) );
+ assert( sqlite3MemdebugNoType(p, (u8)~MEMTYPE_HEAP) );
if( sqlite3GlobalConfig.bMemstat ){
sqlite3_mutex_enter(mem0.mutex);
- sqlite3StatusAdd(SQLITE_STATUS_MEMORY_USED, -sqlite3MallocSize(p));
- sqlite3StatusAdd(SQLITE_STATUS_MALLOC_COUNT, -1);
+ sqlite3StatusDown(SQLITE_STATUS_MEMORY_USED, sqlite3MallocSize(p));
+ sqlite3StatusDown(SQLITE_STATUS_MALLOC_COUNT, 1);
sqlite3GlobalConfig.m.xFree(p);
sqlite3_mutex_leave(mem0.mutex);
}else{
@@ -19051,14 +22158,23 @@ SQLITE_API void sqlite3_free(void *p){
}
/*
+** Add the size of memory allocation "p" to the count in
+** *db->pnBytesFreed.
+*/
+static SQLITE_NOINLINE void measureAllocationSize(sqlite3 *db, void *p){
+ *db->pnBytesFreed += sqlite3DbMallocSize(db,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( p==0 ) return;
if( db ){
if( db->pnBytesFreed ){
- *db->pnBytesFreed += sqlite3DbMallocSize(db, p);
+ measureAllocationSize(db, p);
return;
}
if( isLookaside(db, p) ){
@@ -19073,8 +22189,8 @@ SQLITE_PRIVATE void sqlite3DbFree(sqlite3 *db, void *p){
return;
}
}
- assert( sqlite3MemdebugHasType(p, MEMTYPE_DB) );
- assert( sqlite3MemdebugHasType(p, MEMTYPE_LOOKASIDE|MEMTYPE_HEAP) );
+ assert( sqlite3MemdebugHasType(p, (MEMTYPE_LOOKASIDE|MEMTYPE_HEAP)) );
+ assert( sqlite3MemdebugNoType(p, (u8)~(MEMTYPE_LOOKASIDE|MEMTYPE_HEAP)) );
assert( db!=0 || sqlite3MemdebugNoType(p, MEMTYPE_LOOKASIDE) );
sqlite3MemdebugSetType(p, MEMTYPE_HEAP);
sqlite3_free(p);
@@ -19083,14 +22199,16 @@ SQLITE_PRIVATE void sqlite3DbFree(sqlite3 *db, void *p){
/*
** Change the size of an existing memory allocation
*/
-SQLITE_PRIVATE void *sqlite3Realloc(void *pOld, int nBytes){
+SQLITE_PRIVATE void *sqlite3Realloc(void *pOld, u64 nBytes){
int nOld, nNew, nDiff;
void *pNew;
+ assert( sqlite3MemdebugHasType(pOld, MEMTYPE_HEAP) );
+ assert( sqlite3MemdebugNoType(pOld, (u8)~MEMTYPE_HEAP) );
if( pOld==0 ){
- return sqlite3Malloc(nBytes); /* IMP: R-28354-25769 */
+ return sqlite3Malloc(nBytes); /* IMP: R-04300-56712 */
}
- if( nBytes<=0 ){
- sqlite3_free(pOld); /* IMP: R-31593-10574 */
+ if( nBytes==0 ){
+ sqlite3_free(pOld); /* IMP: R-26507-47431 */
return 0;
}
if( nBytes>=0x7fffff00 ){
@@ -19101,33 +22219,31 @@ SQLITE_PRIVATE void *sqlite3Realloc(void *pOld, int nBytes){
/* 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);
+ nNew = sqlite3GlobalConfig.m.xRoundup((int)nBytes);
if( nOld==nNew ){
pNew = pOld;
}else if( sqlite3GlobalConfig.bMemstat ){
sqlite3_mutex_enter(mem0.mutex);
- sqlite3StatusSet(SQLITE_STATUS_MALLOC_SIZE, nBytes);
+ sqlite3StatusHighwater(SQLITE_STATUS_MALLOC_SIZE, (int)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);
+ if( pNew==0 && mem0.alarmThreshold>0 ){
+ sqlite3MallocAlarm((int)nBytes);
pNew = sqlite3GlobalConfig.m.xRealloc(pOld, nNew);
}
if( pNew ){
nNew = sqlite3MallocSize(pNew);
- sqlite3StatusAdd(SQLITE_STATUS_MEMORY_USED, nNew-nOld);
+ sqlite3StatusUp(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 */
+ assert( EIGHT_BYTE_ALIGNMENT(pNew) ); /* IMP: R-11148-40995 */
return pNew;
}
@@ -19135,7 +22251,14 @@ SQLITE_PRIVATE void *sqlite3Realloc(void *pOld, int nBytes){
** 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){
+SQLITE_API void *SQLITE_STDCALL sqlite3_realloc(void *pOld, int n){
+#ifndef SQLITE_OMIT_AUTOINIT
+ if( sqlite3_initialize() ) return 0;
+#endif
+ if( n<0 ) n = 0; /* IMP: R-26507-47431 */
+ return sqlite3Realloc(pOld, n);
+}
+SQLITE_API void *SQLITE_STDCALL sqlite3_realloc64(void *pOld, sqlite3_uint64 n){
#ifndef SQLITE_OMIT_AUTOINIT
if( sqlite3_initialize() ) return 0;
#endif
@@ -19146,10 +22269,10 @@ SQLITE_API void *sqlite3_realloc(void *pOld, int n){
/*
** Allocate and zero memory.
*/
-SQLITE_PRIVATE void *sqlite3MallocZero(int n){
+SQLITE_PRIVATE void *sqlite3MallocZero(u64 n){
void *p = sqlite3Malloc(n);
if( p ){
- memset(p, 0, n);
+ memset(p, 0, (size_t)n);
}
return p;
}
@@ -19158,10 +22281,10 @@ SQLITE_PRIVATE void *sqlite3MallocZero(int n){
** Allocate and zero memory. If the allocation fails, make
** the mallocFailed flag in the connection pointer.
*/
-SQLITE_PRIVATE void *sqlite3DbMallocZero(sqlite3 *db, int n){
+SQLITE_PRIVATE void *sqlite3DbMallocZero(sqlite3 *db, u64 n){
void *p = sqlite3DbMallocRaw(db, n);
if( p ){
- memset(p, 0, n);
+ memset(p, 0, (size_t)n);
}
return p;
}
@@ -19184,7 +22307,7 @@ SQLITE_PRIVATE void *sqlite3DbMallocZero(sqlite3 *db, int n){
** 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){
+SQLITE_PRIVATE void *sqlite3DbMallocRaw(sqlite3 *db, u64 n){
void *p;
assert( db==0 || sqlite3_mutex_held(db->mutex) );
assert( db==0 || db->pnBytesFreed==0 );
@@ -19219,8 +22342,8 @@ SQLITE_PRIVATE void *sqlite3DbMallocRaw(sqlite3 *db, int n){
if( !p && db ){
db->mallocFailed = 1;
}
- sqlite3MemdebugSetType(p, MEMTYPE_DB |
- ((db && db->lookaside.bEnabled) ? MEMTYPE_LOOKASIDE : MEMTYPE_HEAP));
+ sqlite3MemdebugSetType(p,
+ (db && db->lookaside.bEnabled) ? MEMTYPE_LOOKASIDE : MEMTYPE_HEAP);
return p;
}
@@ -19228,7 +22351,7 @@ SQLITE_PRIVATE void *sqlite3DbMallocRaw(sqlite3 *db, int n){
** 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){
+SQLITE_PRIVATE void *sqlite3DbRealloc(sqlite3 *db, void *p, u64 n){
void *pNew = 0;
assert( db!=0 );
assert( sqlite3_mutex_held(db->mutex) );
@@ -19246,15 +22369,14 @@ SQLITE_PRIVATE void *sqlite3DbRealloc(sqlite3 *db, void *p, int n){
sqlite3DbFree(db, p);
}
}else{
- assert( sqlite3MemdebugHasType(p, MEMTYPE_DB) );
- assert( sqlite3MemdebugHasType(p, MEMTYPE_LOOKASIDE|MEMTYPE_HEAP) );
+ assert( sqlite3MemdebugHasType(p, (MEMTYPE_LOOKASIDE|MEMTYPE_HEAP)) );
+ assert( sqlite3MemdebugNoType(p, (u8)~(MEMTYPE_LOOKASIDE|MEMTYPE_HEAP)) );
sqlite3MemdebugSetType(p, MEMTYPE_HEAP);
- pNew = sqlite3_realloc(p, n);
+ pNew = sqlite3_realloc64(p, n);
if( !pNew ){
- sqlite3MemdebugSetType(p, MEMTYPE_DB|MEMTYPE_HEAP);
db->mallocFailed = 1;
}
- sqlite3MemdebugSetType(pNew, MEMTYPE_DB |
+ sqlite3MemdebugSetType(pNew,
(db->lookaside.bEnabled ? MEMTYPE_LOOKASIDE : MEMTYPE_HEAP));
}
}
@@ -19265,7 +22387,7 @@ SQLITE_PRIVATE void *sqlite3DbRealloc(sqlite3 *db, void *p, int n){
** 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){
+SQLITE_PRIVATE void *sqlite3DbReallocOrFree(sqlite3 *db, void *p, u64 n){
void *pNew;
pNew = sqlite3DbRealloc(db, p, n);
if( !pNew ){
@@ -19295,7 +22417,7 @@ SQLITE_PRIVATE char *sqlite3DbStrDup(sqlite3 *db, const char *z){
}
return zNew;
}
-SQLITE_PRIVATE char *sqlite3DbStrNDup(sqlite3 *db, const char *z, int n){
+SQLITE_PRIVATE char *sqlite3DbStrNDup(sqlite3 *db, const char *z, u64 n){
char *zNew;
if( z==0 ){
return 0;
@@ -19303,28 +22425,28 @@ SQLITE_PRIVATE char *sqlite3DbStrNDup(sqlite3 *db, const char *z, int n){
assert( (n&0x7fffffff)==n );
zNew = sqlite3DbMallocRaw(db, n+1);
if( zNew ){
- memcpy(zNew, z, n);
+ memcpy(zNew, z, (size_t)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.
+** Free any prior content in *pz and replace it with a copy of zNew.
*/
-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);
+SQLITE_PRIVATE void sqlite3SetString(char **pz, sqlite3 *db, const char *zNew){
sqlite3DbFree(db, *pz);
- *pz = z;
+ *pz = sqlite3DbStrDup(db, zNew);
}
+/*
+** Take actions at the end of an API call to indicate an OOM error
+*/
+static SQLITE_NOINLINE int apiOomError(sqlite3 *db){
+ db->mallocFailed = 0;
+ sqlite3Error(db, SQLITE_NOMEM);
+ return SQLITE_NOMEM;
+}
/*
** This function must be called before exiting any API function (i.e.
@@ -19335,40 +22457,36 @@ SQLITE_PRIVATE void sqlite3SetString(char **pz, sqlite3 *db, const char *zFormat
** 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.
+** If an OOM as 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
+ /* If the db handle 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;
+ assert( db!=0 );
+ assert( sqlite3_mutex_held(db->mutex) );
+ if( db->mallocFailed || rc==SQLITE_IOERR_NOMEM ){
+ return apiOomError(db);
}
- return rc & (db ? db->errMask : 0xff);
+ return rc & db->errMask;
}
/************** 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().
+** the public domain.
**
**************************************************************************
**
** 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.
+** SQLite.
*/
+/* #include "sqliteInt.h" */
/*
** Conversion types fall into various categories as defined by the
@@ -19491,20 +22609,32 @@ static char et_getdigit(LONGDOUBLE_TYPE *val, int *cnt){
#endif /* SQLITE_OMIT_FLOATING_POINT */
/*
-** Append N space characters to the given string buffer.
+** Set the StrAccum object to an error mode.
*/
-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);
- }
+static void setStrAccumError(StrAccum *p, u8 eError){
+ assert( eError==STRACCUM_NOMEM || eError==STRACCUM_TOOBIG );
+ p->accError = eError;
+ p->nAlloc = 0;
}
/*
+** Extra argument values from a PrintfArguments object
+*/
+static sqlite3_int64 getIntArg(PrintfArguments *p){
+ if( p->nArg<=p->nUsed ) return 0;
+ return sqlite3_value_int64(p->apArg[p->nUsed++]);
+}
+static double getDoubleArg(PrintfArguments *p){
+ if( p->nArg<=p->nUsed ) return 0.0;
+ return sqlite3_value_double(p->apArg[p->nUsed++]);
+}
+static char *getTextArg(PrintfArguments *p){
+ if( p->nArg<=p->nUsed ) return 0;
+ return (char*)sqlite3_value_text(p->apArg[p->nUsed++]);
+}
+
+
+/*
** On machines with a small stack size, you can redefine the
** SQLITE_PRINT_BUF_SIZE to be something smaller, if desired.
*/
@@ -19517,10 +22647,10 @@ SQLITE_PRIVATE void sqlite3AppendSpace(StrAccum *pAccum, int N){
** 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 */
+ StrAccum *pAccum, /* Accumulate results here */
+ u32 bFlags, /* SQLITE_PRINTF_* flags */
+ const char *fmt, /* Format string */
+ va_list ap /* arguments */
){
int c; /* Next character in the format string */
char *bufpt; /* Pointer to the conversion buffer */
@@ -19538,13 +22668,15 @@ SQLITE_PRIVATE void sqlite3VXPrintf(
etByte flag_longlong; /* True if the "ll" flag is present */
etByte done; /* Loop termination flag */
etByte xtype = 0; /* Conversion paradigm */
+ u8 bArgList; /* True for SQLITE_PRINTF_SQLFUNC */
+ u8 useIntern; /* Ok to use internal conversions (ex: %T) */
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 */
+ char *zExtra = 0; /* 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 */
@@ -19552,17 +22684,28 @@ SQLITE_PRIVATE void sqlite3VXPrintf(
etByte flag_dp; /* True if decimal point should be shown */
etByte flag_rtz; /* True if trailing zeros should be removed */
#endif
+ PrintfArguments *pArgList = 0; /* Arguments for SQLITE_PRINTF_SQLFUNC */
char buf[etBUFSIZE]; /* Conversion buffer */
bufpt = 0;
+ if( bFlags ){
+ if( (bArgList = (bFlags & SQLITE_PRINTF_SQLFUNC))!=0 ){
+ pArgList = va_arg(ap, PrintfArguments*);
+ }
+ useIntern = bFlags & SQLITE_PRINTF_INTERNAL;
+ }else{
+ bArgList = useIntern = 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 HAVE_STRCHRNUL
+ fmt = strchrnul(fmt, '%');
+#else
+ do{ fmt++; }while( *fmt && *fmt != '%' );
+#endif
+ sqlite3StrAccumAppend(pAccum, bufpt, (int)(fmt - bufpt));
+ if( *fmt==0 ) break;
}
if( (c=(*++fmt))==0 ){
sqlite3StrAccumAppend(pAccum, "%", 1);
@@ -19584,37 +22727,66 @@ SQLITE_PRIVATE void sqlite3VXPrintf(
}
}while( !done && (c=(*++fmt))!=0 );
/* Get the field width */
- width = 0;
if( c=='*' ){
- width = va_arg(ap,int);
+ if( bArgList ){
+ width = (int)getIntArg(pArgList);
+ }else{
+ width = va_arg(ap,int);
+ }
if( width<0 ){
flag_leftjustify = 1;
- width = -width;
+ width = width >= -2147483647 ? -width : 0;
}
c = *++fmt;
}else{
+ unsigned wx = 0;
while( c>='0' && c<='9' ){
- width = width*10 + c - '0';
+ wx = wx*10 + c - '0';
c = *++fmt;
}
+ testcase( wx>0x7fffffff );
+ width = wx & 0x7fffffff;
+ }
+ assert( width>=0 );
+#ifdef SQLITE_PRINTF_PRECISION_LIMIT
+ if( width>SQLITE_PRINTF_PRECISION_LIMIT ){
+ width = SQLITE_PRINTF_PRECISION_LIMIT;
}
+#endif
+
/* Get the precision */
if( c=='.' ){
- precision = 0;
c = *++fmt;
if( c=='*' ){
- precision = va_arg(ap,int);
- if( precision<0 ) precision = -precision;
+ if( bArgList ){
+ precision = (int)getIntArg(pArgList);
+ }else{
+ precision = va_arg(ap,int);
+ }
c = *++fmt;
+ if( precision<0 ){
+ precision = precision >= -2147483647 ? -precision : -1;
+ }
}else{
+ unsigned px = 0;
while( c>='0' && c<='9' ){
- precision = precision*10 + c - '0';
+ px = px*10 + c - '0';
c = *++fmt;
}
+ testcase( px>0x7fffffff );
+ precision = px & 0x7fffffff;
}
}else{
precision = -1;
}
+ assert( precision>=(-1) );
+#ifdef SQLITE_PRINTF_PRECISION_LIMIT
+ if( precision>SQLITE_PRINTF_PRECISION_LIMIT ){
+ precision = SQLITE_PRINTF_PRECISION_LIMIT;
+ }
+#endif
+
+
/* Get the conversion type modifier */
if( c=='l' ){
flag_long = 1;
@@ -19634,7 +22806,7 @@ SQLITE_PRIVATE void sqlite3VXPrintf(
for(idx=0; idx<ArraySize(fmtinfo); idx++){
if( c==fmtinfo[idx].fmttype ){
infop = &fmtinfo[idx];
- if( useExtended || (infop->flags & FLAG_INTERN)==0 ){
+ if( useIntern || (infop->flags & FLAG_INTERN)==0 ){
xtype = infop->type;
}else{
return;
@@ -19642,7 +22814,6 @@ SQLITE_PRIVATE void sqlite3VXPrintf(
break;
}
}
- zExtra = 0;
/*
** At this point, variables are initialized as follows:
@@ -19674,7 +22845,9 @@ SQLITE_PRIVATE void sqlite3VXPrintf(
case etRADIX:
if( infop->flags & FLAG_SIGNED ){
i64 v;
- if( flag_longlong ){
+ if( bArgList ){
+ v = getIntArg(pArgList);
+ }else if( flag_longlong ){
v = va_arg(ap,i64);
}else if( flag_long ){
v = va_arg(ap,long int);
@@ -19695,7 +22868,9 @@ SQLITE_PRIVATE void sqlite3VXPrintf(
else prefix = 0;
}
}else{
- if( flag_longlong ){
+ if( bArgList ){
+ longvalue = (u64)getIntArg(pArgList);
+ }else if( flag_longlong ){
longvalue = va_arg(ap,u64);
}else if( flag_long ){
longvalue = va_arg(ap,unsigned long int);
@@ -19715,7 +22890,7 @@ SQLITE_PRIVATE void sqlite3VXPrintf(
nOut = precision + 10;
zOut = zExtra = sqlite3Malloc( nOut );
if( zOut==0 ){
- pAccum->mallocFailed = 1;
+ setStrAccumError(pAccum, STRACCUM_NOMEM);
return;
}
}
@@ -19730,10 +22905,8 @@ SQLITE_PRIVATE void sqlite3VXPrintf(
*(--bufpt) = zOrd[x*2];
}
{
- register const char *cset; /* Use registers for speed */
- register int base;
- cset = &aDigits[infop->charset];
- base = infop->base;
+ const char *cset = &aDigits[infop->charset];
+ u8 base = infop->base;
do{ /* Convert to ascii */
*(--bufpt) = cset[longvalue%base];
longvalue = longvalue/base;
@@ -19755,7 +22928,11 @@ SQLITE_PRIVATE void sqlite3VXPrintf(
case etFLOAT:
case etEXP:
case etGENERIC:
- realvalue = va_arg(ap,double);
+ if( bArgList ){
+ realvalue = getDoubleArg(pArgList);
+ }else{
+ realvalue = va_arg(ap,double);
+ }
#ifdef SQLITE_OMIT_FLOATING_POINT
length = 0;
#else
@@ -19769,13 +22946,8 @@ SQLITE_PRIVATE void sqlite3VXPrintf(
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
+ testcase( precision>0xfff );
+ for(idx=precision&0xfff, rounder=0.5; idx>0; idx--, rounder*=0.1){}
if( xtype==etFLOAT ) realvalue += rounder;
/* Normalize realvalue to within 10.0 > realvalue >= 1.0 */
exp = 0;
@@ -19787,21 +22959,16 @@ SQLITE_PRIVATE void sqlite3VXPrintf(
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>=1e10*scale && exp<=350 ){ scale *= 1e10; exp+=10; }
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);
+ bufpt = buf;
+ buf[0] = prefix;
+ memcpy(buf+(prefix!=0),"Inf",4);
+ length = 3+(prefix!=0);
break;
}
}
@@ -19830,10 +22997,11 @@ SQLITE_PRIVATE void sqlite3VXPrintf(
}else{
e2 = exp;
}
- if( e2+precision+width > etBUFSIZE - 15 ){
- bufpt = zExtra = sqlite3Malloc( e2+precision+width+15 );
+ if( MAX(e2,0)+(i64)precision+(i64)width > etBUFSIZE - 15 ){
+ bufpt = zExtra
+ = sqlite3Malloc( MAX(e2,0)+(i64)precision+(i64)width+15 );
if( bufpt==0 ){
- pAccum->mallocFailed = 1;
+ setStrAccumError(pAccum, STRACCUM_NOMEM);
return;
}
}
@@ -19916,7 +23084,9 @@ SQLITE_PRIVATE void sqlite3VXPrintf(
#endif /* !defined(SQLITE_OMIT_FLOATING_POINT) */
break;
case etSIZE:
- *(va_arg(ap,int*)) = pAccum->nChar;
+ if( !bArgList ){
+ *(va_arg(ap,int*)) = pAccum->nChar;
+ }
length = width = 0;
break;
case etPERCENT:
@@ -19925,19 +23095,32 @@ SQLITE_PRIVATE void sqlite3VXPrintf(
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;
+ if( bArgList ){
+ bufpt = getTextArg(pArgList);
+ c = bufpt ? bufpt[0] : 0;
}else{
- length =1;
+ c = va_arg(ap,int);
}
+ if( precision>1 ){
+ width -= precision-1;
+ if( width>1 && !flag_leftjustify ){
+ sqlite3AppendChar(pAccum, width-1, ' ');
+ width = 0;
+ }
+ sqlite3AppendChar(pAccum, precision-1, c);
+ }
+ length = 1;
+ buf[0] = c;
bufpt = buf;
break;
case etSTRING:
case etDYNSTRING:
- bufpt = va_arg(ap,char*);
+ if( bArgList ){
+ bufpt = getTextArg(pArgList);
+ xtype = etSTRING;
+ }else{
+ bufpt = va_arg(ap,char*);
+ }
if( bufpt==0 ){
bufpt = "";
}else if( xtype==etDYNSTRING ){
@@ -19949,14 +23132,20 @@ SQLITE_PRIVATE void sqlite3VXPrintf(
length = sqlite3Strlen30(bufpt);
}
break;
- case etSQLESCAPE:
- case etSQLESCAPE2:
- case etSQLESCAPE3: {
+ case etSQLESCAPE: /* Escape ' characters */
+ case etSQLESCAPE2: /* Escape ' and enclose in '...' */
+ case etSQLESCAPE3: { /* Escape " characters */
int i, j, k, n, isnull;
int needQuote;
char ch;
char q = ((xtype==etSQLESCAPE3)?'"':'\''); /* Quote character */
- char *escarg = va_arg(ap,char*);
+ char *escarg;
+
+ if( bArgList ){
+ escarg = getTextArg(pArgList);
+ }else{
+ escarg = va_arg(ap,char*);
+ }
isnull = escarg==0;
if( isnull ) escarg = (xtype==etSQLESCAPE2 ? "NULL" : "(NULL)");
k = precision;
@@ -19964,11 +23153,11 @@ SQLITE_PRIVATE void sqlite3VXPrintf(
if( ch==q ) n++;
}
needQuote = !isnull && xtype==etSQLESCAPE2;
- n += i + 1 + needQuote*2;
+ n += i + 3;
if( n>etBUFSIZE ){
bufpt = zExtra = sqlite3Malloc( n );
if( bufpt==0 ){
- pAccum->mallocFailed = 1;
+ setStrAccumError(pAccum, STRACCUM_NOMEM);
return;
}
}else{
@@ -19991,7 +23180,8 @@ SQLITE_PRIVATE void sqlite3VXPrintf(
}
case etTOKEN: {
Token *pToken = va_arg(ap, Token*);
- if( pToken ){
+ assert( bArgList==0 );
+ if( pToken && pToken->n ){
sqlite3StrAccumAppend(pAccum, (const char*)pToken->z, pToken->n);
}
length = width = 0;
@@ -20001,12 +23191,13 @@ SQLITE_PRIVATE void sqlite3VXPrintf(
SrcList *pSrc = va_arg(ap, SrcList*);
int k = va_arg(ap, int);
struct SrcList_item *pItem = &pSrc->a[k];
+ assert( bArgList==0 );
assert( k>=0 && k<pSrc->nSrc );
if( pItem->zDatabase ){
- sqlite3StrAccumAppend(pAccum, pItem->zDatabase, -1);
+ sqlite3StrAccumAppendAll(pAccum, pItem->zDatabase);
sqlite3StrAccumAppend(pAccum, ".", 1);
}
- sqlite3StrAccumAppend(pAccum, pItem->zName, -1);
+ sqlite3StrAccumAppendAll(pAccum, pItem->zName);
length = width = 0;
break;
}
@@ -20020,101 +23211,145 @@ SQLITE_PRIVATE void sqlite3VXPrintf(
** "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);
- }
+ width -= length;
+ if( width>0 && !flag_leftjustify ) sqlite3AppendChar(pAccum, width, ' ');
+ sqlite3StrAccumAppend(pAccum, bufpt, length);
+ if( width>0 && flag_leftjustify ) sqlite3AppendChar(pAccum, width, ' ');
+
+ if( zExtra ){
+ sqlite3DbFree(pAccum->db, zExtra);
+ zExtra = 0;
}
- sqlite3_free(zExtra);
}/* End for loop over the format string */
} /* End of function */
/*
-** Append N bytes of text from z to the StrAccum object.
+** Enlarge the memory allocation on a StrAccum object so that it is
+** able to accept at least N more bytes of text.
+**
+** Return the number of bytes of text that StrAccum is able to accept
+** after the attempted enlargement. The value returned might be zero.
*/
-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;
+static int sqlite3StrAccumEnlarge(StrAccum *p, int N){
+ char *zNew;
+ assert( p->nChar+(i64)N >= p->nAlloc ); /* Only called if really needed */
+ if( p->accError ){
+ testcase(p->accError==STRACCUM_TOOBIG);
+ testcase(p->accError==STRACCUM_NOMEM);
+ return 0;
}
- assert( p->zText!=0 || p->nChar==0 );
- if( N<0 ){
- N = sqlite3Strlen30(z);
+ if( p->mxAlloc==0 ){
+ N = p->nAlloc - p->nChar - 1;
+ setStrAccumError(p, STRACCUM_TOOBIG);
+ return N;
+ }else{
+ char *zOld = p->bMalloced ? p->zText : 0;
+ i64 szNew = p->nChar;
+ assert( (p->zText==0 || p->zText==p->zBase)==(p->bMalloced==0) );
+ szNew += N + 1;
+ if( szNew+p->nChar<=p->mxAlloc ){
+ /* Force exponential buffer size growth as long as it does not overflow,
+ ** to avoid having to call this routine too often */
+ szNew += p->nChar;
+ }
+ if( szNew > p->mxAlloc ){
+ sqlite3StrAccumReset(p);
+ setStrAccumError(p, STRACCUM_TOOBIG);
+ return 0;
+ }else{
+ p->nAlloc = (int)szNew;
+ }
+ if( p->db ){
+ zNew = sqlite3DbRealloc(p->db, zOld, p->nAlloc);
+ }else{
+ zNew = sqlite3_realloc64(zOld, p->nAlloc);
+ }
+ if( zNew ){
+ assert( p->zText!=0 || p->nChar==0 );
+ if( !p->bMalloced && p->nChar>0 ) memcpy(zNew, p->zText, p->nChar);
+ p->zText = zNew;
+ p->nAlloc = sqlite3DbMallocSize(p->db, zNew);
+ p->bMalloced = 1;
+ }else{
+ sqlite3StrAccumReset(p);
+ setStrAccumError(p, STRACCUM_NOMEM);
+ return 0;
+ }
}
- if( N==0 || NEVER(z==0) ){
+ return N;
+}
+
+/*
+** Append N copies of character c to the given string buffer.
+*/
+SQLITE_PRIVATE void sqlite3AppendChar(StrAccum *p, int N, char c){
+ testcase( p->nChar + (i64)N > 0x7fffffff );
+ if( p->nChar+(i64)N >= p->nAlloc && (N = sqlite3StrAccumEnlarge(p, N))<=0 ){
return;
}
+ assert( (p->zText==p->zBase)==(p->bMalloced==0) );
+ while( (N--)>0 ) p->zText[p->nChar++] = c;
+}
+
+/*
+** The StrAccum "p" is not large enough to accept N new bytes of z[].
+** So enlarge if first, then do the append.
+**
+** This is a helper routine to sqlite3StrAccumAppend() that does special-case
+** work (enlarging the buffer) using tail recursion, so that the
+** sqlite3StrAccumAppend() routine can use fast calling semantics.
+*/
+static void SQLITE_NOINLINE enlargeAndAppend(StrAccum *p, const char *z, int N){
+ N = sqlite3StrAccumEnlarge(p, N);
+ if( N>0 ){
+ memcpy(&p->zText[p->nChar], z, N);
+ p->nChar += N;
+ }
+ assert( (p->zText==0 || p->zText==p->zBase)==(p->bMalloced==0) );
+}
+
+/*
+** Append N bytes of text from z to the StrAccum object. Increase the
+** size of the memory allocation for StrAccum if necessary.
+*/
+SQLITE_PRIVATE void sqlite3StrAccumAppend(StrAccum *p, const char *z, int N){
+ assert( z!=0 || N==0 );
+ assert( p->zText!=0 || p->nChar==0 || p->accError );
+ assert( N>=0 );
+ assert( p->accError==0 || p->nAlloc==0 );
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;
- }
- }
+ enlargeAndAppend(p,z,N);
+ }else{
+ assert( p->zText );
+ p->nChar += N;
+ memcpy(&p->zText[p->nChar-N], z, N);
}
- assert( p->zText );
- memcpy(&p->zText[p->nChar], z, N);
- p->nChar += N;
}
/*
+** Append the complete text of zero-terminated string z[] to the p string.
+*/
+SQLITE_PRIVATE void sqlite3StrAccumAppendAll(StrAccum *p, const char *z){
+ sqlite3StrAccumAppend(p, z, sqlite3Strlen30(z));
+}
+
+
+/*
** 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 ){
+ assert( (p->zText==p->zBase)==(p->bMalloced==0) );
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->mxAlloc>0 && p->bMalloced==0 ){
+ p->zText = sqlite3DbMallocRaw(p->db, p->nChar+1 );
if( p->zText ){
memcpy(p->zText, p->zBase, p->nChar+1);
+ p->bMalloced = 1;
}else{
- p->mallocFailed = 1;
+ setStrAccumError(p, STRACCUM_NOMEM);
}
}
}
@@ -20125,28 +23360,36 @@ SQLITE_PRIVATE char *sqlite3StrAccumFinish(StrAccum *p){
** 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);
- }
+ assert( (p->zText==0 || p->zText==p->zBase)==(p->bMalloced==0) );
+ if( p->bMalloced ){
+ sqlite3DbFree(p->db, p->zText);
+ p->bMalloced = 0;
}
p->zText = 0;
}
/*
-** Initialize a string accumulator
+** Initialize a string accumulator.
+**
+** p: The accumulator to be initialized.
+** db: Pointer to a database connection. May be NULL. Lookaside
+** memory is used if not NULL. db->mallocFailed is set appropriately
+** when not NULL.
+** zBase: An initial buffer. May be NULL in which case the initial buffer
+** is malloced.
+** n: Size of zBase in bytes. If total space requirements never exceed
+** n then no memory allocations ever occur.
+** mx: Maximum number of bytes to accumulate. If mx==0 then no memory
+** allocations will ever occur.
*/
-SQLITE_PRIVATE void sqlite3StrAccumInit(StrAccum *p, char *zBase, int n, int mx){
+SQLITE_PRIVATE void sqlite3StrAccumInit(StrAccum *p, sqlite3 *db, char *zBase, int n, int mx){
p->zText = p->zBase = zBase;
- p->db = 0;
+ p->db = db;
p->nChar = 0;
p->nAlloc = n;
p->mxAlloc = mx;
- p->useMalloc = 1;
- p->tooBig = 0;
- p->mallocFailed = 0;
+ p->accError = 0;
+ p->bMalloced = 0;
}
/*
@@ -20158,12 +23401,11 @@ SQLITE_PRIVATE char *sqlite3VMPrintf(sqlite3 *db, const char *zFormat, va_list a
char zBase[SQLITE_PRINT_BUF_SIZE];
StrAccum acc;
assert( db!=0 );
- sqlite3StrAccumInit(&acc, zBase, sizeof(zBase),
+ sqlite3StrAccumInit(&acc, db, zBase, sizeof(zBase),
db->aLimit[SQLITE_LIMIT_LENGTH]);
- acc.db = db;
- sqlite3VXPrintf(&acc, 1, zFormat, ap);
+ sqlite3VXPrintf(&acc, SQLITE_PRINTF_INTERNAL, zFormat, ap);
z = sqlite3StrAccumFinish(&acc);
- if( acc.mallocFailed ){
+ if( acc.accError==STRACCUM_NOMEM ){
db->mallocFailed = 1;
}
return z;
@@ -20183,36 +23425,24 @@ SQLITE_PRIVATE char *sqlite3MPrintf(sqlite3 *db, const char *zFormat, ...){
}
/*
-** 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){
+SQLITE_API char *SQLITE_STDCALL sqlite3_vmprintf(const char *zFormat, va_list ap){
char *z;
char zBase[SQLITE_PRINT_BUF_SIZE];
StrAccum acc;
+
+#ifdef SQLITE_ENABLE_API_ARMOR
+ if( zFormat==0 ){
+ (void)SQLITE_MISUSE_BKPT;
+ return 0;
+ }
+#endif
#ifndef SQLITE_OMIT_AUTOINIT
if( sqlite3_initialize() ) return 0;
#endif
- sqlite3StrAccumInit(&acc, zBase, sizeof(zBase), SQLITE_MAX_LENGTH);
- acc.useMalloc = 2;
+ sqlite3StrAccumInit(&acc, 0, zBase, sizeof(zBase), SQLITE_MAX_LENGTH);
sqlite3VXPrintf(&acc, 0, zFormat, ap);
z = sqlite3StrAccumFinish(&acc);
return z;
@@ -20222,7 +23452,7 @@ SQLITE_API char *sqlite3_vmprintf(const char *zFormat, va_list ap){
** Print into memory obtained from sqlite3_malloc()(). Omit the internal
** %-conversion extensions.
*/
-SQLITE_API char *sqlite3_mprintf(const char *zFormat, ...){
+SQLITE_API char *SQLITE_CDECL sqlite3_mprintf(const char *zFormat, ...){
va_list ap;
char *z;
#ifndef SQLITE_OMIT_AUTOINIT
@@ -20247,15 +23477,21 @@ SQLITE_API char *sqlite3_mprintf(const char *zFormat, ...){
**
** sqlite3_vsnprintf() is the varargs version.
*/
-SQLITE_API char *sqlite3_vsnprintf(int n, char *zBuf, const char *zFormat, va_list ap){
+SQLITE_API char *SQLITE_STDCALL 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;
+#ifdef SQLITE_ENABLE_API_ARMOR
+ if( zBuf==0 || zFormat==0 ) {
+ (void)SQLITE_MISUSE_BKPT;
+ if( zBuf ) zBuf[0] = 0;
+ return zBuf;
+ }
+#endif
+ sqlite3StrAccumInit(&acc, 0, zBuf, n, 0);
sqlite3VXPrintf(&acc, 0, zFormat, ap);
return sqlite3StrAccumFinish(&acc);
}
-SQLITE_API char *sqlite3_snprintf(int n, char *zBuf, const char *zFormat, ...){
+SQLITE_API char *SQLITE_CDECL sqlite3_snprintf(int n, char *zBuf, const char *zFormat, ...){
char *z;
va_list ap;
va_start(ap,zFormat);
@@ -20272,13 +23508,17 @@ SQLITE_API char *sqlite3_snprintf(int n, char *zBuf, const char *zFormat, ...){
** 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.
+**
+** sqlite3VXPrintf() might ask for *temporary* memory allocations for
+** certain format characters (%q) or for very large precisions or widths.
+** Care must be taken that any sqlite3_log() calls that occur while the
+** memory mutex is held do not use these mechanisms.
*/
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;
+ sqlite3StrAccumInit(&acc, 0, zMsg, sizeof(zMsg), 0);
sqlite3VXPrintf(&acc, 0, zFormat, ap);
sqlite3GlobalConfig.xLog(sqlite3GlobalConfig.pLogArg, iErrCode,
sqlite3StrAccumFinish(&acc));
@@ -20287,7 +23527,7 @@ static void renderLogMsg(int iErrCode, const char *zFormat, va_list ap){
/*
** Format and write a message to the log if logging is enabled.
*/
-SQLITE_API void sqlite3_log(int iErrCode, const char *zFormat, ...){
+SQLITE_API void SQLITE_CDECL sqlite3_log(int iErrCode, const char *zFormat, ...){
va_list ap; /* Vararg list */
if( sqlite3GlobalConfig.xLog ){
va_start(ap, zFormat);
@@ -20296,7 +23536,7 @@ SQLITE_API void sqlite3_log(int iErrCode, const char *zFormat, ...){
}
}
-#if defined(SQLITE_DEBUG)
+#if defined(SQLITE_DEBUG) || defined(SQLITE_HAVE_OS_TRACE)
/*
** A version of printf() that understands %lld. Used for debugging.
** The printf() built into some versions of windows does not understand %lld
@@ -20306,8 +23546,7 @@ SQLITE_PRIVATE void sqlite3DebugPrintf(const char *zFormat, ...){
va_list ap;
StrAccum acc;
char zBuf[500];
- sqlite3StrAccumInit(&acc, zBuf, sizeof(zBuf), 0);
- acc.useMalloc = 0;
+ sqlite3StrAccumInit(&acc, 0, zBuf, sizeof(zBuf), 0);
va_start(ap,zFormat);
sqlite3VXPrintf(&acc, 0, zFormat, ap);
va_end(ap);
@@ -20317,19 +23556,508 @@ SQLITE_PRIVATE void sqlite3DebugPrintf(const char *zFormat, ...){
}
#endif
-#ifndef SQLITE_OMIT_TRACE
+
/*
-** variable-argument wrapper around sqlite3VXPrintf().
+** variable-argument wrapper around sqlite3VXPrintf(). The bFlags argument
+** can contain the bit SQLITE_PRINTF_INTERNAL enable internal formats.
*/
-SQLITE_PRIVATE void sqlite3XPrintf(StrAccum *p, const char *zFormat, ...){
+SQLITE_PRIVATE void sqlite3XPrintf(StrAccum *p, u32 bFlags, const char *zFormat, ...){
va_list ap;
va_start(ap,zFormat);
- sqlite3VXPrintf(p, 1, zFormat, ap);
+ sqlite3VXPrintf(p, bFlags, zFormat, ap);
va_end(ap);
}
-#endif
/************** End of printf.c **********************************************/
+/************** Begin file treeview.c ****************************************/
+/*
+** 2015-06-08
+**
+** 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 to implement the TreeView debugging routines.
+** These routines print a parse tree to standard output for debugging and
+** analysis.
+**
+** The interfaces in this file is only available when compiling
+** with SQLITE_DEBUG.
+*/
+/* #include "sqliteInt.h" */
+#ifdef SQLITE_DEBUG
+
+/*
+** Add a new subitem to the tree. The moreToFollow flag indicates that this
+** is not the last item in the tree.
+*/
+static TreeView *sqlite3TreeViewPush(TreeView *p, u8 moreToFollow){
+ if( p==0 ){
+ p = sqlite3_malloc64( sizeof(*p) );
+ if( p==0 ) return 0;
+ memset(p, 0, sizeof(*p));
+ }else{
+ p->iLevel++;
+ }
+ assert( moreToFollow==0 || moreToFollow==1 );
+ if( p->iLevel<sizeof(p->bLine) ) p->bLine[p->iLevel] = moreToFollow;
+ return p;
+}
+
+/*
+** Finished with one layer of the tree
+*/
+static void sqlite3TreeViewPop(TreeView *p){
+ if( p==0 ) return;
+ p->iLevel--;
+ if( p->iLevel<0 ) sqlite3_free(p);
+}
+
+/*
+** Generate a single line of output for the tree, with a prefix that contains
+** all the appropriate tree lines
+*/
+static void sqlite3TreeViewLine(TreeView *p, const char *zFormat, ...){
+ va_list ap;
+ int i;
+ StrAccum acc;
+ char zBuf[500];
+ sqlite3StrAccumInit(&acc, 0, zBuf, sizeof(zBuf), 0);
+ if( p ){
+ for(i=0; i<p->iLevel && i<sizeof(p->bLine)-1; i++){
+ sqlite3StrAccumAppend(&acc, p->bLine[i] ? "| " : " ", 4);
+ }
+ sqlite3StrAccumAppend(&acc, p->bLine[i] ? "|-- " : "'-- ", 4);
+ }
+ va_start(ap, zFormat);
+ sqlite3VXPrintf(&acc, 0, zFormat, ap);
+ va_end(ap);
+ if( zBuf[acc.nChar-1]!='\n' ) sqlite3StrAccumAppend(&acc, "\n", 1);
+ sqlite3StrAccumFinish(&acc);
+ fprintf(stdout,"%s", zBuf);
+ fflush(stdout);
+}
+
+/*
+** Shorthand for starting a new tree item that consists of a single label
+*/
+static void sqlite3TreeViewItem(TreeView *p, const char *zLabel,u8 moreFollows){
+ p = sqlite3TreeViewPush(p, moreFollows);
+ sqlite3TreeViewLine(p, "%s", zLabel);
+}
+
+/*
+** Generate a human-readable description of a WITH clause.
+*/
+SQLITE_PRIVATE void sqlite3TreeViewWith(TreeView *pView, const With *pWith, u8 moreToFollow){
+ int i;
+ if( pWith==0 ) return;
+ if( pWith->nCte==0 ) return;
+ if( pWith->pOuter ){
+ sqlite3TreeViewLine(pView, "WITH (0x%p, pOuter=0x%p)",pWith,pWith->pOuter);
+ }else{
+ sqlite3TreeViewLine(pView, "WITH (0x%p)", pWith);
+ }
+ if( pWith->nCte>0 ){
+ pView = sqlite3TreeViewPush(pView, 1);
+ for(i=0; i<pWith->nCte; i++){
+ StrAccum x;
+ char zLine[1000];
+ const struct Cte *pCte = &pWith->a[i];
+ sqlite3StrAccumInit(&x, 0, zLine, sizeof(zLine), 0);
+ sqlite3XPrintf(&x, 0, "%s", pCte->zName);
+ if( pCte->pCols && pCte->pCols->nExpr>0 ){
+ char cSep = '(';
+ int j;
+ for(j=0; j<pCte->pCols->nExpr; j++){
+ sqlite3XPrintf(&x, 0, "%c%s", cSep, pCte->pCols->a[j].zName);
+ cSep = ',';
+ }
+ sqlite3XPrintf(&x, 0, ")");
+ }
+ sqlite3XPrintf(&x, 0, " AS");
+ sqlite3StrAccumFinish(&x);
+ sqlite3TreeViewItem(pView, zLine, i<pWith->nCte-1);
+ sqlite3TreeViewSelect(pView, pCte->pSelect, 0);
+ sqlite3TreeViewPop(pView);
+ }
+ sqlite3TreeViewPop(pView);
+ }
+}
+
+
+/*
+** Generate a human-readable description of a the Select object.
+*/
+SQLITE_PRIVATE void sqlite3TreeViewSelect(TreeView *pView, const Select *p, u8 moreToFollow){
+ int n = 0;
+ int cnt = 0;
+ pView = sqlite3TreeViewPush(pView, moreToFollow);
+ if( p->pWith ){
+ sqlite3TreeViewWith(pView, p->pWith, 1);
+ cnt = 1;
+ sqlite3TreeViewPush(pView, 1);
+ }
+ do{
+ sqlite3TreeViewLine(pView, "SELECT%s%s (0x%p) selFlags=0x%x",
+ ((p->selFlags & SF_Distinct) ? " DISTINCT" : ""),
+ ((p->selFlags & SF_Aggregate) ? " agg_flag" : ""), p, p->selFlags
+ );
+ if( cnt++ ) sqlite3TreeViewPop(pView);
+ if( p->pPrior ){
+ n = 1000;
+ }else{
+ n = 0;
+ if( p->pSrc && p->pSrc->nSrc ) n++;
+ if( p->pWhere ) n++;
+ if( p->pGroupBy ) n++;
+ if( p->pHaving ) n++;
+ if( p->pOrderBy ) n++;
+ if( p->pLimit ) n++;
+ if( p->pOffset ) n++;
+ }
+ sqlite3TreeViewExprList(pView, p->pEList, (n--)>0, "result-set");
+ if( p->pSrc && p->pSrc->nSrc ){
+ int i;
+ pView = sqlite3TreeViewPush(pView, (n--)>0);
+ sqlite3TreeViewLine(pView, "FROM");
+ for(i=0; i<p->pSrc->nSrc; i++){
+ struct SrcList_item *pItem = &p->pSrc->a[i];
+ StrAccum x;
+ char zLine[100];
+ sqlite3StrAccumInit(&x, 0, zLine, sizeof(zLine), 0);
+ sqlite3XPrintf(&x, 0, "{%d,*}", pItem->iCursor);
+ if( pItem->zDatabase ){
+ sqlite3XPrintf(&x, 0, " %s.%s", pItem->zDatabase, pItem->zName);
+ }else if( pItem->zName ){
+ sqlite3XPrintf(&x, 0, " %s", pItem->zName);
+ }
+ if( pItem->pTab ){
+ sqlite3XPrintf(&x, 0, " tabname=%Q", pItem->pTab->zName);
+ }
+ if( pItem->zAlias ){
+ sqlite3XPrintf(&x, 0, " (AS %s)", pItem->zAlias);
+ }
+ if( pItem->fg.jointype & JT_LEFT ){
+ sqlite3XPrintf(&x, 0, " LEFT-JOIN");
+ }
+ sqlite3StrAccumFinish(&x);
+ sqlite3TreeViewItem(pView, zLine, i<p->pSrc->nSrc-1);
+ if( pItem->pSelect ){
+ sqlite3TreeViewSelect(pView, pItem->pSelect, 0);
+ }
+ if( pItem->fg.isTabFunc ){
+ sqlite3TreeViewExprList(pView, pItem->u1.pFuncArg, 0, "func-args:");
+ }
+ sqlite3TreeViewPop(pView);
+ }
+ sqlite3TreeViewPop(pView);
+ }
+ if( p->pWhere ){
+ sqlite3TreeViewItem(pView, "WHERE", (n--)>0);
+ sqlite3TreeViewExpr(pView, p->pWhere, 0);
+ sqlite3TreeViewPop(pView);
+ }
+ if( p->pGroupBy ){
+ sqlite3TreeViewExprList(pView, p->pGroupBy, (n--)>0, "GROUPBY");
+ }
+ if( p->pHaving ){
+ sqlite3TreeViewItem(pView, "HAVING", (n--)>0);
+ sqlite3TreeViewExpr(pView, p->pHaving, 0);
+ sqlite3TreeViewPop(pView);
+ }
+ if( p->pOrderBy ){
+ sqlite3TreeViewExprList(pView, p->pOrderBy, (n--)>0, "ORDERBY");
+ }
+ if( p->pLimit ){
+ sqlite3TreeViewItem(pView, "LIMIT", (n--)>0);
+ sqlite3TreeViewExpr(pView, p->pLimit, 0);
+ sqlite3TreeViewPop(pView);
+ }
+ if( p->pOffset ){
+ sqlite3TreeViewItem(pView, "OFFSET", (n--)>0);
+ sqlite3TreeViewExpr(pView, p->pOffset, 0);
+ sqlite3TreeViewPop(pView);
+ }
+ if( p->pPrior ){
+ const char *zOp = "UNION";
+ switch( p->op ){
+ case TK_ALL: zOp = "UNION ALL"; break;
+ case TK_INTERSECT: zOp = "INTERSECT"; break;
+ case TK_EXCEPT: zOp = "EXCEPT"; break;
+ }
+ sqlite3TreeViewItem(pView, zOp, 1);
+ }
+ p = p->pPrior;
+ }while( p!=0 );
+ sqlite3TreeViewPop(pView);
+}
+
+/*
+** Generate a human-readable explanation of an expression tree.
+*/
+SQLITE_PRIVATE void sqlite3TreeViewExpr(TreeView *pView, const Expr *pExpr, u8 moreToFollow){
+ const char *zBinOp = 0; /* Binary operator */
+ const char *zUniOp = 0; /* Unary operator */
+ char zFlgs[30];
+ pView = sqlite3TreeViewPush(pView, moreToFollow);
+ if( pExpr==0 ){
+ sqlite3TreeViewLine(pView, "nil");
+ sqlite3TreeViewPop(pView);
+ return;
+ }
+ if( pExpr->flags ){
+ sqlite3_snprintf(sizeof(zFlgs),zFlgs," flags=0x%x",pExpr->flags);
+ }else{
+ zFlgs[0] = 0;
+ }
+ switch( pExpr->op ){
+ case TK_AGG_COLUMN: {
+ sqlite3TreeViewLine(pView, "AGG{%d:%d}%s",
+ pExpr->iTable, pExpr->iColumn, zFlgs);
+ break;
+ }
+ case TK_COLUMN: {
+ if( pExpr->iTable<0 ){
+ /* This only happens when coding check constraints */
+ sqlite3TreeViewLine(pView, "COLUMN(%d)%s", pExpr->iColumn, zFlgs);
+ }else{
+ sqlite3TreeViewLine(pView, "{%d:%d}%s",
+ pExpr->iTable, pExpr->iColumn, zFlgs);
+ }
+ break;
+ }
+ case TK_INTEGER: {
+ if( pExpr->flags & EP_IntValue ){
+ sqlite3TreeViewLine(pView, "%d", pExpr->u.iValue);
+ }else{
+ sqlite3TreeViewLine(pView, "%s", pExpr->u.zToken);
+ }
+ break;
+ }
+#ifndef SQLITE_OMIT_FLOATING_POINT
+ case TK_FLOAT: {
+ sqlite3TreeViewLine(pView,"%s", pExpr->u.zToken);
+ break;
+ }
+#endif
+ case TK_STRING: {
+ sqlite3TreeViewLine(pView,"%Q", pExpr->u.zToken);
+ break;
+ }
+ case TK_NULL: {
+ sqlite3TreeViewLine(pView,"NULL");
+ break;
+ }
+#ifndef SQLITE_OMIT_BLOB_LITERAL
+ case TK_BLOB: {
+ sqlite3TreeViewLine(pView,"%s", pExpr->u.zToken);
+ break;
+ }
+#endif
+ case TK_VARIABLE: {
+ sqlite3TreeViewLine(pView,"VARIABLE(%s,%d)",
+ pExpr->u.zToken, pExpr->iColumn);
+ break;
+ }
+ case TK_REGISTER: {
+ sqlite3TreeViewLine(pView,"REGISTER(%d)", pExpr->iTable);
+ break;
+ }
+ case TK_ID: {
+ sqlite3TreeViewLine(pView,"ID \"%w\"", pExpr->u.zToken);
+ break;
+ }
+#ifndef SQLITE_OMIT_CAST
+ case TK_CAST: {
+ /* Expressions of the form: CAST(pLeft AS token) */
+ sqlite3TreeViewLine(pView,"CAST %Q", pExpr->u.zToken);
+ sqlite3TreeViewExpr(pView, pExpr->pLeft, 0);
+ 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_DOT: zBinOp = "DOT"; 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: {
+ sqlite3TreeViewLine(pView, "COLLATE %Q", pExpr->u.zToken);
+ sqlite3TreeViewExpr(pView, pExpr->pLeft, 0);
+ break;
+ }
+
+ case TK_AGG_FUNCTION:
+ case TK_FUNCTION: {
+ ExprList *pFarg; /* List of function arguments */
+ if( ExprHasProperty(pExpr, EP_TokenOnly) ){
+ pFarg = 0;
+ }else{
+ pFarg = pExpr->x.pList;
+ }
+ if( pExpr->op==TK_AGG_FUNCTION ){
+ sqlite3TreeViewLine(pView, "AGG_FUNCTION%d %Q",
+ pExpr->op2, pExpr->u.zToken);
+ }else{
+ sqlite3TreeViewLine(pView, "FUNCTION %Q", pExpr->u.zToken);
+ }
+ if( pFarg ){
+ sqlite3TreeViewExprList(pView, pFarg, 0, 0);
+ }
+ break;
+ }
+#ifndef SQLITE_OMIT_SUBQUERY
+ case TK_EXISTS: {
+ sqlite3TreeViewLine(pView, "EXISTS-expr");
+ sqlite3TreeViewSelect(pView, pExpr->x.pSelect, 0);
+ break;
+ }
+ case TK_SELECT: {
+ sqlite3TreeViewLine(pView, "SELECT-expr");
+ sqlite3TreeViewSelect(pView, pExpr->x.pSelect, 0);
+ break;
+ }
+ case TK_IN: {
+ sqlite3TreeViewLine(pView, "IN");
+ sqlite3TreeViewExpr(pView, pExpr->pLeft, 1);
+ if( ExprHasProperty(pExpr, EP_xIsSelect) ){
+ sqlite3TreeViewSelect(pView, pExpr->x.pSelect, 0);
+ }else{
+ sqlite3TreeViewExprList(pView, pExpr->x.pList, 0, 0);
+ }
+ 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;
+ sqlite3TreeViewLine(pView, "BETWEEN");
+ sqlite3TreeViewExpr(pView, pX, 1);
+ sqlite3TreeViewExpr(pView, pY, 1);
+ sqlite3TreeViewExpr(pView, pZ, 0);
+ 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.
+ */
+ sqlite3TreeViewLine(pView, "%s(%d)",
+ pExpr->iTable ? "NEW" : "OLD", pExpr->iColumn);
+ break;
+ }
+ case TK_CASE: {
+ sqlite3TreeViewLine(pView, "CASE");
+ sqlite3TreeViewExpr(pView, pExpr->pLeft, 1);
+ sqlite3TreeViewExprList(pView, pExpr->x.pList, 0, 0);
+ 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;
+ }
+ sqlite3TreeViewLine(pView, "RAISE %s(%Q)", zType, pExpr->u.zToken);
+ break;
+ }
+#endif
+ default: {
+ sqlite3TreeViewLine(pView, "op=%d", pExpr->op);
+ break;
+ }
+ }
+ if( zBinOp ){
+ sqlite3TreeViewLine(pView, "%s%s", zBinOp, zFlgs);
+ sqlite3TreeViewExpr(pView, pExpr->pLeft, 1);
+ sqlite3TreeViewExpr(pView, pExpr->pRight, 0);
+ }else if( zUniOp ){
+ sqlite3TreeViewLine(pView, "%s%s", zUniOp, zFlgs);
+ sqlite3TreeViewExpr(pView, pExpr->pLeft, 0);
+ }
+ sqlite3TreeViewPop(pView);
+}
+
+/*
+** Generate a human-readable explanation of an expression list.
+*/
+SQLITE_PRIVATE void sqlite3TreeViewExprList(
+ TreeView *pView,
+ const ExprList *pList,
+ u8 moreToFollow,
+ const char *zLabel
+){
+ int i;
+ pView = sqlite3TreeViewPush(pView, moreToFollow);
+ if( zLabel==0 || zLabel[0]==0 ) zLabel = "LIST";
+ if( pList==0 ){
+ sqlite3TreeViewLine(pView, "%s (empty)", zLabel);
+ }else{
+ sqlite3TreeViewLine(pView, "%s", zLabel);
+ for(i=0; i<pList->nExpr; i++){
+ int j = pList->a[i].u.x.iOrderByCol;
+ if( j ){
+ sqlite3TreeViewPush(pView, 0);
+ sqlite3TreeViewLine(pView, "iOrderByCol=%d", j);
+ }
+ sqlite3TreeViewExpr(pView, pList->a[i].pExpr, i<pList->nExpr-1);
+ if( j ) sqlite3TreeViewPop(pView);
+ }
+ }
+ sqlite3TreeViewPop(pView);
+}
+
+#endif /* SQLITE_DEBUG */
+
+/************** End of treeview.c ********************************************/
/************** Begin file random.c ******************************************/
/*
** 2001 September 15
@@ -20348,6 +24076,7 @@ SQLITE_PRIVATE void sqlite3XPrintf(StrAccum *p, const char *zFormat, ...){
** Random numbers are used by some of the database backends in order
** to generate random integer keys for tables or random filenames.
*/
+/* #include "sqliteInt.h" */
/* All threads share a single random number generator.
@@ -20360,24 +24089,11 @@ static SQLITE_WSD struct sqlite3PrngType {
} 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.
+** Return N random bytes.
*/
-static u8 randomByte(void){
+SQLITE_API void SQLITE_STDCALL sqlite3_randomness(int N, void *pBuf){
unsigned char t;
-
+ unsigned char *zBuf = pBuf;
/* The "wsdPrng" macro will resolve to the pseudo-random number generator
** state vector. If writable static data is unsupported on the target,
@@ -20392,6 +24108,24 @@ static u8 randomByte(void){
# define wsdPrng sqlite3Prng
#endif
+#if SQLITE_THREADSAFE
+ sqlite3_mutex *mutex;
+#endif
+
+#ifndef SQLITE_OMIT_AUTOINIT
+ if( sqlite3_initialize() ) return;
+#endif
+
+#if SQLITE_THREADSAFE
+ mutex = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_PRNG);
+#endif
+
+ sqlite3_mutex_enter(mutex);
+ if( N<=0 || pBuf==0 ){
+ wsdPrng.isInit = 0;
+ sqlite3_mutex_leave(mutex);
+ return;
+ }
/* Initialize the state of the random number generator once,
** the first time this routine is called. The seed value does
@@ -20420,29 +24154,16 @@ static u8 randomByte(void){
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();
- }
+ assert( N>0 );
+ do{
+ 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];
+ *(zBuf++) = wsdPrng.s[t];
+ }while( --N );
sqlite3_mutex_leave(mutex);
}
@@ -20471,12 +24192,286 @@ SQLITE_PRIVATE void sqlite3PrngRestoreState(void){
sizeof(sqlite3Prng)
);
}
-SQLITE_PRIVATE void sqlite3PrngResetState(void){
- GLOBAL(struct sqlite3PrngType, sqlite3Prng).isInit = 0;
-}
#endif /* SQLITE_OMIT_BUILTIN_TEST */
/************** End of random.c **********************************************/
+/************** Begin file threads.c *****************************************/
+/*
+** 2012 July 21
+**
+** 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 presents a simple cross-platform threading interface for
+** use internally by SQLite.
+**
+** A "thread" can be created using sqlite3ThreadCreate(). This thread
+** runs independently of its creator until it is joined using
+** sqlite3ThreadJoin(), at which point it terminates.
+**
+** Threads do not have to be real. It could be that the work of the
+** "thread" is done by the main thread at either the sqlite3ThreadCreate()
+** or sqlite3ThreadJoin() call. This is, in fact, what happens in
+** single threaded systems. Nothing in SQLite requires multiple threads.
+** This interface exists so that applications that want to take advantage
+** of multiple cores can do so, while also allowing applications to stay
+** single-threaded if desired.
+*/
+/* #include "sqliteInt.h" */
+#if SQLITE_OS_WIN
+/* # include "os_win.h" */
+#endif
+
+#if SQLITE_MAX_WORKER_THREADS>0
+
+/********************************* Unix Pthreads ****************************/
+#if SQLITE_OS_UNIX && defined(SQLITE_MUTEX_PTHREADS) && SQLITE_THREADSAFE>0
+
+#define SQLITE_THREADS_IMPLEMENTED 1 /* Prevent the single-thread code below */
+/* #include <pthread.h> */
+
+/* A running thread */
+struct SQLiteThread {
+ pthread_t tid; /* Thread ID */
+ int done; /* Set to true when thread finishes */
+ void *pOut; /* Result returned by the thread */
+ void *(*xTask)(void*); /* The thread routine */
+ void *pIn; /* Argument to the thread */
+};
+
+/* Create a new thread */
+SQLITE_PRIVATE int sqlite3ThreadCreate(
+ SQLiteThread **ppThread, /* OUT: Write the thread object here */
+ void *(*xTask)(void*), /* Routine to run in a separate thread */
+ void *pIn /* Argument passed into xTask() */
+){
+ SQLiteThread *p;
+ int rc;
+
+ assert( ppThread!=0 );
+ assert( xTask!=0 );
+ /* This routine is never used in single-threaded mode */
+ assert( sqlite3GlobalConfig.bCoreMutex!=0 );
+
+ *ppThread = 0;
+ p = sqlite3Malloc(sizeof(*p));
+ if( p==0 ) return SQLITE_NOMEM;
+ memset(p, 0, sizeof(*p));
+ p->xTask = xTask;
+ p->pIn = pIn;
+ /* If the SQLITE_TESTCTRL_FAULT_INSTALL callback is registered to a
+ ** function that returns SQLITE_ERROR when passed the argument 200, that
+ ** forces worker threads to run sequentially and deterministically
+ ** for testing purposes. */
+ if( sqlite3FaultSim(200) ){
+ rc = 1;
+ }else{
+ rc = pthread_create(&p->tid, 0, xTask, pIn);
+ }
+ if( rc ){
+ p->done = 1;
+ p->pOut = xTask(pIn);
+ }
+ *ppThread = p;
+ return SQLITE_OK;
+}
+
+/* Get the results of the thread */
+SQLITE_PRIVATE int sqlite3ThreadJoin(SQLiteThread *p, void **ppOut){
+ int rc;
+
+ assert( ppOut!=0 );
+ if( NEVER(p==0) ) return SQLITE_NOMEM;
+ if( p->done ){
+ *ppOut = p->pOut;
+ rc = SQLITE_OK;
+ }else{
+ rc = pthread_join(p->tid, ppOut) ? SQLITE_ERROR : SQLITE_OK;
+ }
+ sqlite3_free(p);
+ return rc;
+}
+
+#endif /* SQLITE_OS_UNIX && defined(SQLITE_MUTEX_PTHREADS) */
+/******************************** End Unix Pthreads *************************/
+
+
+/********************************* Win32 Threads ****************************/
+#if SQLITE_OS_WIN_THREADS
+
+#define SQLITE_THREADS_IMPLEMENTED 1 /* Prevent the single-thread code below */
+#include <process.h>
+
+/* A running thread */
+struct SQLiteThread {
+ void *tid; /* The thread handle */
+ unsigned id; /* The thread identifier */
+ void *(*xTask)(void*); /* The routine to run as a thread */
+ void *pIn; /* Argument to xTask */
+ void *pResult; /* Result of xTask */
+};
+
+/* Thread procedure Win32 compatibility shim */
+static unsigned __stdcall sqlite3ThreadProc(
+ void *pArg /* IN: Pointer to the SQLiteThread structure */
+){
+ SQLiteThread *p = (SQLiteThread *)pArg;
+
+ assert( p!=0 );
+#if 0
+ /*
+ ** This assert appears to trigger spuriously on certain
+ ** versions of Windows, possibly due to _beginthreadex()
+ ** and/or CreateThread() not fully setting their thread
+ ** ID parameter before starting the thread.
+ */
+ assert( p->id==GetCurrentThreadId() );
+#endif
+ assert( p->xTask!=0 );
+ p->pResult = p->xTask(p->pIn);
+
+ _endthreadex(0);
+ return 0; /* NOT REACHED */
+}
+
+/* Create a new thread */
+SQLITE_PRIVATE int sqlite3ThreadCreate(
+ SQLiteThread **ppThread, /* OUT: Write the thread object here */
+ void *(*xTask)(void*), /* Routine to run in a separate thread */
+ void *pIn /* Argument passed into xTask() */
+){
+ SQLiteThread *p;
+
+ assert( ppThread!=0 );
+ assert( xTask!=0 );
+ *ppThread = 0;
+ p = sqlite3Malloc(sizeof(*p));
+ if( p==0 ) return SQLITE_NOMEM;
+ /* If the SQLITE_TESTCTRL_FAULT_INSTALL callback is registered to a
+ ** function that returns SQLITE_ERROR when passed the argument 200, that
+ ** forces worker threads to run sequentially and deterministically
+ ** (via the sqlite3FaultSim() term of the conditional) for testing
+ ** purposes. */
+ if( sqlite3GlobalConfig.bCoreMutex==0 || sqlite3FaultSim(200) ){
+ memset(p, 0, sizeof(*p));
+ }else{
+ p->xTask = xTask;
+ p->pIn = pIn;
+ p->tid = (void*)_beginthreadex(0, 0, sqlite3ThreadProc, p, 0, &p->id);
+ if( p->tid==0 ){
+ memset(p, 0, sizeof(*p));
+ }
+ }
+ if( p->xTask==0 ){
+ p->id = GetCurrentThreadId();
+ p->pResult = xTask(pIn);
+ }
+ *ppThread = p;
+ return SQLITE_OK;
+}
+
+SQLITE_PRIVATE DWORD sqlite3Win32Wait(HANDLE hObject); /* os_win.c */
+
+/* Get the results of the thread */
+SQLITE_PRIVATE int sqlite3ThreadJoin(SQLiteThread *p, void **ppOut){
+ DWORD rc;
+ BOOL bRc;
+
+ assert( ppOut!=0 );
+ if( NEVER(p==0) ) return SQLITE_NOMEM;
+ if( p->xTask==0 ){
+ /* assert( p->id==GetCurrentThreadId() ); */
+ rc = WAIT_OBJECT_0;
+ assert( p->tid==0 );
+ }else{
+ assert( p->id!=0 && p->id!=GetCurrentThreadId() );
+ rc = sqlite3Win32Wait((HANDLE)p->tid);
+ assert( rc!=WAIT_IO_COMPLETION );
+ bRc = CloseHandle((HANDLE)p->tid);
+ assert( bRc );
+ }
+ if( rc==WAIT_OBJECT_0 ) *ppOut = p->pResult;
+ sqlite3_free(p);
+ return (rc==WAIT_OBJECT_0) ? SQLITE_OK : SQLITE_ERROR;
+}
+
+#endif /* SQLITE_OS_WIN_THREADS */
+/******************************** End Win32 Threads *************************/
+
+
+/********************************* Single-Threaded **************************/
+#ifndef SQLITE_THREADS_IMPLEMENTED
+/*
+** This implementation does not actually create a new thread. It does the
+** work of the thread in the main thread, when either the thread is created
+** or when it is joined
+*/
+
+/* A running thread */
+struct SQLiteThread {
+ void *(*xTask)(void*); /* The routine to run as a thread */
+ void *pIn; /* Argument to xTask */
+ void *pResult; /* Result of xTask */
+};
+
+/* Create a new thread */
+SQLITE_PRIVATE int sqlite3ThreadCreate(
+ SQLiteThread **ppThread, /* OUT: Write the thread object here */
+ void *(*xTask)(void*), /* Routine to run in a separate thread */
+ void *pIn /* Argument passed into xTask() */
+){
+ SQLiteThread *p;
+
+ assert( ppThread!=0 );
+ assert( xTask!=0 );
+ *ppThread = 0;
+ p = sqlite3Malloc(sizeof(*p));
+ if( p==0 ) return SQLITE_NOMEM;
+ if( (SQLITE_PTR_TO_INT(p)/17)&1 ){
+ p->xTask = xTask;
+ p->pIn = pIn;
+ }else{
+ p->xTask = 0;
+ p->pResult = xTask(pIn);
+ }
+ *ppThread = p;
+ return SQLITE_OK;
+}
+
+/* Get the results of the thread */
+SQLITE_PRIVATE int sqlite3ThreadJoin(SQLiteThread *p, void **ppOut){
+
+ assert( ppOut!=0 );
+ if( NEVER(p==0) ) return SQLITE_NOMEM;
+ if( p->xTask ){
+ *ppOut = p->xTask(p->pIn);
+ }else{
+ *ppOut = p->pResult;
+ }
+ sqlite3_free(p);
+
+#if defined(SQLITE_TEST)
+ {
+ void *pTstAlloc = sqlite3Malloc(10);
+ if (!pTstAlloc) return SQLITE_NOMEM;
+ sqlite3_free(pTstAlloc);
+ }
+#endif
+
+ return SQLITE_OK;
+}
+
+#endif /* !defined(SQLITE_THREADS_IMPLEMENTED) */
+/****************************** End Single-Threaded *************************/
+#endif /* SQLITE_MAX_WORKER_THREADS>0 */
+
+/************** End of threads.c *********************************************/
/************** Begin file utf.c *********************************************/
/*
** 2004 April 13
@@ -20513,15 +24508,17 @@ SQLITE_PRIVATE void sqlite3PrngResetState(void){
** 0xfe 0xff big-endian utf-16 follows
**
*/
+/* #include "sqliteInt.h" */
/* #include <assert.h> */
+/* #include "vdbeInt.h" */
-#ifndef SQLITE_AMALGAMATION
+#if !defined(SQLITE_AMALGAMATION) && SQLITE_BYTEORDER==0
/*
** The following constant value is used by the SQLITE_BIGENDIAN and
** SQLITE_LITTLEENDIAN macros.
*/
SQLITE_PRIVATE const int sqlite3one = 1;
-#endif /* SQLITE_AMALGAMATION */
+#endif /* SQLITE_AMALGAMATION && SQLITE_BYTEORDER==0 */
/*
** This lookup table is used to help decode the first byte of
@@ -20626,8 +24623,8 @@ static const unsigned char sqlite3Utf8Trans1[] = {
** 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
+** * This routine accepts over-length UTF8 encodings
+** for unicode values 0x80 and greater. It does not change over-length
** encodings to 0xfffd as some systems recommend.
*/
#define READ_UTF8(zIn, zTerm, c) \
@@ -20677,7 +24674,7 @@ SQLITE_PRIVATE u32 sqlite3Utf8Read(
** 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){
+SQLITE_PRIVATE SQLITE_NOINLINE 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 */
@@ -20792,12 +24789,13 @@ SQLITE_PRIVATE int sqlite3VdbeMemTranslate(Mem *pMem, u8 desiredEnc){
*z = 0;
assert( (pMem->n+(desiredEnc==SQLITE_UTF8?1:2))<=len );
+ c = pMem->flags;
sqlite3VdbeMemRelease(pMem);
- pMem->flags &= ~(MEM_Static|MEM_Dyn|MEM_Ephem);
+ pMem->flags = MEM_Str|MEM_Term|(c&MEM_AffMask);
pMem->enc = desiredEnc;
- pMem->flags |= (MEM_Term|MEM_Dyn);
pMem->z = (char*)zOut;
pMem->zMalloc = pMem->z;
+ pMem->szMalloc = sqlite3DbMallocSize(pMem->db, pMem->z);
translate_out:
#if defined(TRANSLATE_TRACE) && defined(SQLITE_DEBUG)
@@ -20923,38 +24921,11 @@ SQLITE_PRIVATE char *sqlite3Utf16to8(sqlite3 *db, const void *z, int nByte, u8 e
}
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.
@@ -21052,8 +25023,9 @@ SQLITE_PRIVATE void sqlite3UtfSelfTest(void){
** strings, and stuff like that.
**
*/
+/* #include "sqliteInt.h" */
/* #include <stdarg.h> */
-#ifdef SQLITE_HAVE_ISNAN
+#if HAVE_ISNAN || SQLITE_HAVE_ISNAN
# include <math.h>
#endif
@@ -21067,6 +25039,24 @@ SQLITE_PRIVATE void sqlite3Coverage(int x){
}
#endif
+/*
+** Give a callback to the test harness that can be used to simulate faults
+** in places where it is difficult or expensive to do so purely by means
+** of inputs.
+**
+** The intent of the integer argument is to let the fault simulator know
+** which of multiple sqlite3FaultSim() calls has been hit.
+**
+** Return whatever integer value the test callback returns, or return
+** SQLITE_OK if no test callback is installed.
+*/
+#ifndef SQLITE_OMIT_BUILTIN_TEST
+SQLITE_PRIVATE int sqlite3FaultSim(int iTest){
+ int (*xCallback)(int) = sqlite3GlobalConfig.xTestCallback;
+ return xCallback ? xCallback(iTest) : SQLITE_OK;
+}
+#endif
+
#ifndef SQLITE_OMIT_FLOATING_POINT
/*
** Return true if the floating point value is Not a Number (NaN).
@@ -21076,7 +25066,7 @@ SQLITE_PRIVATE void sqlite3Coverage(int x){
*/
SQLITE_PRIVATE int sqlite3IsNaN(double x){
int rc; /* The value return */
-#if !defined(SQLITE_HAVE_ISNAN)
+#if !SQLITE_HAVE_ISNAN && !HAVE_ISNAN
/*
** Systems that support the isnan() library function should probably
** make use of it by compiling with -DSQLITE_HAVE_ISNAN. But we have
@@ -21106,9 +25096,9 @@ SQLITE_PRIVATE int sqlite3IsNaN(double x){
volatile double y = x;
volatile double z = y;
rc = (y!=z);
-#else /* if defined(SQLITE_HAVE_ISNAN) */
+#else /* if HAVE_ISNAN */
rc = isnan(x);
-#endif /* SQLITE_HAVE_ISNAN */
+#endif /* HAVE_ISNAN */
testcase( rc );
return rc;
}
@@ -21123,10 +25113,17 @@ SQLITE_PRIVATE int sqlite3IsNaN(double x){
** 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);
+ return 0x3fffffff & (int)strlen(z);
+}
+
+/*
+** Set the current error code to err_code and clear any prior error message.
+*/
+SQLITE_PRIVATE void sqlite3Error(sqlite3 *db, int err_code){
+ assert( db!=0 );
+ db->errCode = err_code;
+ if( db->pErr ) sqlite3ValueSetNull(db->pErr);
}
/*
@@ -21150,19 +25147,18 @@ SQLITE_PRIVATE int sqlite3Strlen30(const char *z){
** 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);
- }
+SQLITE_PRIVATE void sqlite3ErrorWithMsg(sqlite3 *db, int err_code, const char *zFormat, ...){
+ assert( db!=0 );
+ db->errCode = err_code;
+ if( zFormat==0 ){
+ sqlite3Error(db, err_code);
+ }else if( db->pErr || (db->pErr = sqlite3ValueNew(db))!=0 ){
+ 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);
}
}
@@ -21176,12 +25172,12 @@ SQLITE_PRIVATE void sqlite3Error(sqlite3 *db, int err_code, const char *zFormat,
** %T Insert a token
** %S Insert the first element of a SrcList
**
-** This function should be used to report any error that occurs whilst
+** This function should be used to report any error that occurs while
** 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.).
+** Functions sqlite3Error() or sqlite3ErrorWithMsg() should be used
+** during statement execution (sqlite3_step() etc.).
*/
SQLITE_PRIVATE void sqlite3ErrorMsg(Parse *pParse, const char *zFormat, ...){
char *zMsg;
@@ -21214,7 +25210,7 @@ SQLITE_PRIVATE void sqlite3ErrorMsg(Parse *pParse, const char *zFormat, ...){
** occur.
**
** 2002-Feb-14: This routine is extended to remove MS-Access style
-** brackets from around identifers. For example: "[a-b-c]" becomes
+** brackets from around identifiers. For example: "[a-b-c]" becomes
** "a-b-c".
*/
SQLITE_PRIVATE int sqlite3Dequote(char *z){
@@ -21229,7 +25225,8 @@ SQLITE_PRIVATE int sqlite3Dequote(char *z){
case '[': quote = ']'; break; /* For MS SqlServer compatibility */
default: return -1;
}
- for(i=1, j=0; ALWAYS(z[i]); i++){
+ for(i=1, j=0;; i++){
+ assert( z[i] );
if( z[i]==quote ){
if( z[i+1]==quote ){
z[j++] = quote;
@@ -21258,15 +25255,25 @@ SQLITE_PRIVATE int sqlite3Dequote(char *z){
** 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){
+SQLITE_API int SQLITE_STDCALL sqlite3_stricmp(const char *zLeft, const char *zRight){
register unsigned char *a, *b;
+ if( zLeft==0 ){
+ return zRight ? -1 : 0;
+ }else if( zRight==0 ){
+ return 1;
+ }
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){
+SQLITE_API int SQLITE_STDCALL sqlite3_strnicmp(const char *zLeft, const char *zRight, int N){
register unsigned char *a, *b;
+ if( zLeft==0 ){
+ return zRight ? -1 : 0;
+ }else if( zRight==0 ){
+ return 1;
+ }
a = (unsigned char *)zLeft;
b = (unsigned char *)zRight;
while( N-- > 0 && *a!=0 && UpperToLower[*a]==UpperToLower[*b]){ a++; b++; }
@@ -21297,7 +25304,7 @@ SQLITE_API int sqlite3_strnicmp(const char *zLeft, const char *zRight, int N){
*/
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);
+ int incr;
const char *zEnd = z + length;
/* sign * significand * (10 ^ (esign * exponent)) */
int sign = 1; /* sign of significand */
@@ -21308,10 +25315,22 @@ SQLITE_PRIVATE int sqlite3AtoF(const char *z, double *pResult, int length, u8 en
int eValid = 1; /* True exponent is either not used or is well-formed */
double result;
int nDigits = 0;
+ int nonNum = 0;
+ assert( enc==SQLITE_UTF8 || enc==SQLITE_UTF16LE || enc==SQLITE_UTF16BE );
*pResult = 0.0; /* Default return value, in case of an error */
- if( enc==SQLITE_UTF16BE ) z++;
+ if( enc==SQLITE_UTF8 ){
+ incr = 1;
+ }else{
+ int i;
+ incr = 2;
+ assert( SQLITE_UTF16LE==2 && SQLITE_UTF16BE==3 );
+ for(i=3-enc; i<length && z[i]==0; i+=2){}
+ nonNum = i<length;
+ zEnd = z+i+enc-3;
+ z += (enc&1);
+ }
/* skip leading spaces */
while( z<zEnd && sqlite3Isspace(*z) ) z+=incr;
@@ -21444,7 +25463,7 @@ do_atof_calc:
*pResult = result;
/* return true if number and no extra non-whitespace chracters after */
- return z>=zEnd && nDigits>0 && eValid;
+ return z>=zEnd && nDigits>0 && eValid && nonNum==0;
#else
return !sqlite3Atoi64(z, pResult, length, enc);
#endif /* SQLITE_OMIT_FLOATING_POINT */
@@ -21481,33 +25500,45 @@ static int compare2pow63(const char *zNum, int incr){
return c;
}
-
/*
-** Convert zNum to a 64-bit signed integer.
+** Convert zNum to a 64-bit signed integer. zNum must be decimal. This
+** routine does *not* accept hexadecimal notation.
**
** 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 exactly 9223372036854775808, return 2. This special
+** case is broken out because while 9223372036854775808 cannot be a
+** signed 64-bit integer, its negative -9223372036854775808 can be.
**
** If zNum is too big for a 64-bit integer and is not
-** 9223372036854665808 then return 1.
+** 9223372036854775808 or if zNum contains any non-numeric text,
+** 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);
+ int incr;
u64 u = 0;
int neg = 0; /* assume positive */
int i;
int c = 0;
+ int nonNum = 0;
const char *zStart;
const char *zEnd = zNum + length;
- if( enc==SQLITE_UTF16BE ) zNum++;
+ assert( enc==SQLITE_UTF8 || enc==SQLITE_UTF16LE || enc==SQLITE_UTF16BE );
+ if( enc==SQLITE_UTF8 ){
+ incr = 1;
+ }else{
+ incr = 2;
+ assert( SQLITE_UTF16LE==2 && SQLITE_UTF16BE==3 );
+ for(i=3-enc; i<length && zNum[i]==0; i+=2){}
+ nonNum = i<length;
+ zEnd = zNum+i+enc-3;
+ zNum += (enc&1);
+ }
while( zNum<zEnd && sqlite3Isspace(*zNum) ) zNum+=incr;
if( zNum<zEnd ){
if( *zNum=='-' ){
@@ -21523,7 +25554,7 @@ SQLITE_PRIVATE int sqlite3Atoi64(const char *zNum, i64 *pNum, int length, u8 enc
u = u*10 + c - '0';
}
if( u>LARGEST_INT64 ){
- *pNum = SMALLEST_INT64;
+ *pNum = neg ? SMALLEST_INT64 : LARGEST_INT64;
}else if( neg ){
*pNum = -(i64)u;
}else{
@@ -21532,7 +25563,8 @@ SQLITE_PRIVATE int sqlite3Atoi64(const char *zNum, i64 *pNum, int length, u8 enc
testcase( i==18 );
testcase( i==19 );
testcase( i==20 );
- if( (c!=0 && &zNum[i]<zEnd) || (i==0 && zStart==zNum) || i>19*incr ){
+ if( (c!=0 && &zNum[i]<zEnd) || (i==0 && zStart==zNum)
+ || i>19*incr || nonNum ){
/* zNum is empty or contains non-numeric text or is longer
** than 19 digits (thus guaranteeing that it is too large) */
return 1;
@@ -21554,16 +25586,49 @@ SQLITE_PRIVATE int sqlite3Atoi64(const char *zNum, i64 *pNum, int length, u8 enc
/* 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;
}
}
}
/*
+** Transform a UTF-8 integer literal, in either decimal or hexadecimal,
+** into a 64-bit signed integer. This routine accepts hexadecimal literals,
+** whereas sqlite3Atoi64() does not.
+**
+** Returns:
+**
+** 0 Successful transformation. Fits in a 64-bit signed integer.
+** 1 Integer too large for a 64-bit signed integer or is malformed
+** 2 Special case of 9223372036854775808
+*/
+SQLITE_PRIVATE int sqlite3DecOrHexToI64(const char *z, i64 *pOut){
+#ifndef SQLITE_OMIT_HEX_INTEGER
+ if( z[0]=='0'
+ && (z[1]=='x' || z[1]=='X')
+ && sqlite3Isxdigit(z[2])
+ ){
+ u64 u = 0;
+ int i, k;
+ for(i=2; z[i]=='0'; i++){}
+ for(k=i; sqlite3Isxdigit(z[k]); k++){
+ u = u*16 + sqlite3HexToInt(z[k]);
+ }
+ memcpy(pOut, &u, 8);
+ return (z[k]==0 && k-i<=16) ? 0 : 1;
+ }else
+#endif /* SQLITE_OMIT_HEX_INTEGER */
+ {
+ return sqlite3Atoi64(z, pOut, sqlite3Strlen30(z), SQLITE_UTF8);
+ }
+}
+
+/*
** If zNum represents an integer that will fit in 32-bits, then set
** *pValue to that integer and return true. Otherwise return false.
**
+** This routine accepts both decimal and hexadecimal notation for integers.
+**
** Any non-numeric characters that following zNum are ignored.
** This is different from sqlite3Atoi64() which requires the
** input number to be zero-terminated.
@@ -21578,6 +25643,25 @@ SQLITE_PRIVATE int sqlite3GetInt32(const char *zNum, int *pValue){
}else if( zNum[0]=='+' ){
zNum++;
}
+#ifndef SQLITE_OMIT_HEX_INTEGER
+ else if( zNum[0]=='0'
+ && (zNum[1]=='x' || zNum[1]=='X')
+ && sqlite3Isxdigit(zNum[2])
+ ){
+ u32 u = 0;
+ zNum += 2;
+ while( zNum[0]=='0' ) zNum++;
+ for(i=0; sqlite3Isxdigit(zNum[i]) && i<8; i++){
+ u = u*16 + sqlite3HexToInt(zNum[i]);
+ }
+ if( (u&0x80000000)==0 && sqlite3Isxdigit(zNum[i])==0 ){
+ memcpy(pValue, &u, 4);
+ return 1;
+ }else{
+ return 0;
+ }
+ }
+#endif
while( zNum[0]=='0' ) zNum++;
for(i=0; i<11 && (c = zNum[i] - '0')>=0 && c<=9; i++){
v = v*10 + c;
@@ -21642,7 +25726,7 @@ SQLITE_PRIVATE int sqlite3Atoi(const char *z){
** 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){
+static int SQLITE_NOINLINE putVarint64(unsigned char *p, u64 v){
int i, j, n;
u8 buf[10];
if( v & (((u64)0xff000000)<<32) ){
@@ -21666,28 +25750,17 @@ SQLITE_PRIVATE int sqlite3PutVarint(unsigned char *p, u64 v){
}
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;
+SQLITE_PRIVATE int sqlite3PutVarint(unsigned char *p, u64 v){
+ if( v<=0x7f ){
+ p[0] = v&0x7f;
return 1;
}
-#endif
- if( (v & ~0x3fff)==0 ){
- p[0] = (u8)((v>>7) | 0x80);
- p[1] = (u8)(v & 0x7f);
+ if( v<=0x3fff ){
+ p[0] = ((v>>7)&0x7f)|0x80;
+ p[1] = v&0x7f;
return 2;
}
- return sqlite3PutVarint(p, v);
+ return putVarint64(p,v);
}
/*
@@ -21780,7 +25853,8 @@ SQLITE_PRIVATE u8 sqlite3GetVarint(const unsigned char *p, u64 *v){
/* a: p0<<28 | p2<<14 | p4 (unmasked) */
if (!(a&0x80))
{
- /* we can skip these cause they were (effectively) done above in calc'ing s */
+ /* we can skip these cause they were (effectively) done above
+ ** while calculating s */
/* a &= (0x7f<<28)|(0x7f<<14)|(0x7f); */
/* b &= (0x7f<<14)|(0x7f); */
b = b<<7;
@@ -22001,11 +26075,8 @@ SQLITE_PRIVATE u8 sqlite3GetVarint32(const unsigned char *p, u32 *v){
** 64-bit integer.
*/
SQLITE_PRIVATE int sqlite3VarintLen(u64 v){
- int i = 0;
- do{
- i++;
- v >>= 7;
- }while( v!=0 && ALWAYS(i<9) );
+ int i;
+ for(i=1; (v >>= 7)!=0; i++){ assert( i<9 ); }
return i;
}
@@ -22014,13 +26085,40 @@ SQLITE_PRIVATE int sqlite3VarintLen(u64 v){
** 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];
+#if SQLITE_BYTEORDER==4321
+ u32 x;
+ memcpy(&x,p,4);
+ return x;
+#elif SQLITE_BYTEORDER==1234 && !defined(SQLITE_DISABLE_INTRINSIC) \
+ && defined(__GNUC__) && GCC_VERSION>=4003000
+ u32 x;
+ memcpy(&x,p,4);
+ return __builtin_bswap32(x);
+#elif SQLITE_BYTEORDER==1234 && !defined(SQLITE_DISABLE_INTRINSIC) \
+ && defined(_MSC_VER) && _MSC_VER>=1300
+ u32 x;
+ memcpy(&x,p,4);
+ return _byteswap_ulong(x);
+#else
+ testcase( p[0]&0x80 );
+ return ((unsigned)p[0]<<24) | (p[1]<<16) | (p[2]<<8) | p[3];
+#endif
}
SQLITE_PRIVATE void sqlite3Put4byte(unsigned char *p, u32 v){
+#if SQLITE_BYTEORDER==4321
+ memcpy(p,&v,4);
+#elif SQLITE_BYTEORDER==1234 && defined(__GNUC__) && GCC_VERSION>=4003000
+ u32 x = __builtin_bswap32(v);
+ memcpy(p,&x,4);
+#elif SQLITE_BYTEORDER==1234 && defined(_MSC_VER) && _MSC_VER>=1300
+ u32 x = _byteswap_ulong(v);
+ memcpy(p,&x,4);
+#else
p[0] = (u8)(v>>24);
p[1] = (u8)(v>>16);
p[2] = (u8)(v>>8);
p[3] = (u8)v;
+#endif
}
@@ -22135,13 +26233,12 @@ SQLITE_PRIVATE int sqlite3AddInt64(i64 *pA, i64 iB){
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;
}
+ *pA += iB;
return 0;
}
SQLITE_PRIVATE int sqlite3SubInt64(i64 *pA, i64 iB){
@@ -22165,9 +26262,18 @@ SQLITE_PRIVATE int sqlite3MulInt64(i64 *pA, i64 iB){
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;
+ if( iA1==0 ){
+ if( iB1==0 ){
+ *pA *= iB;
+ return 0;
+ }
+ r = iA0*iB1;
+ }else if( iB1==0 ){
+ r = iA1*iB0;
+ }else{
+ /* If both iA1 and iB1 are non-zero, overflow will result */
+ return 1;
+ }
testcase( r==(-TWOPOWER31)-1 );
testcase( r==(-TWOPOWER31) );
testcase( r==TWOPOWER31 );
@@ -22220,6 +26326,85 @@ SQLITE_PRIVATE void sqlite3FileSuffix3(const char *zBaseFilename, char *z){
}
#endif
+/*
+** Find (an approximate) sum of two LogEst values. This computation is
+** not a simple "+" operator because LogEst is stored as a logarithmic
+** value.
+**
+*/
+SQLITE_PRIVATE LogEst sqlite3LogEstAdd(LogEst a, LogEst b){
+ static const unsigned char x[] = {
+ 10, 10, /* 0,1 */
+ 9, 9, /* 2,3 */
+ 8, 8, /* 4,5 */
+ 7, 7, 7, /* 6,7,8 */
+ 6, 6, 6, /* 9,10,11 */
+ 5, 5, 5, /* 12-14 */
+ 4, 4, 4, 4, /* 15-18 */
+ 3, 3, 3, 3, 3, 3, /* 19-24 */
+ 2, 2, 2, 2, 2, 2, 2, /* 25-31 */
+ };
+ if( a>=b ){
+ if( a>b+49 ) return a;
+ if( a>b+31 ) return a+1;
+ return a+x[a-b];
+ }else{
+ if( b>a+49 ) return b;
+ if( b>a+31 ) return b+1;
+ return b+x[b-a];
+ }
+}
+
+/*
+** Convert an integer into a LogEst. In other words, compute an
+** approximation for 10*log2(x).
+*/
+SQLITE_PRIVATE LogEst sqlite3LogEst(u64 x){
+ static LogEst a[] = { 0, 2, 3, 5, 6, 7, 8, 9 };
+ LogEst y = 40;
+ if( x<8 ){
+ if( x<2 ) return 0;
+ while( x<8 ){ y -= 10; x <<= 1; }
+ }else{
+ while( x>255 ){ y += 40; x >>= 4; }
+ while( x>15 ){ y += 10; x >>= 1; }
+ }
+ return a[x&7] + y - 10;
+}
+
+#ifndef SQLITE_OMIT_VIRTUALTABLE
+/*
+** Convert a double into a LogEst
+** In other words, compute an approximation for 10*log2(x).
+*/
+SQLITE_PRIVATE LogEst sqlite3LogEstFromDouble(double x){
+ u64 a;
+ LogEst e;
+ assert( sizeof(x)==8 && sizeof(a)==8 );
+ if( x<=1 ) return 0;
+ if( x<=2000000000 ) return sqlite3LogEst((u64)x);
+ memcpy(&a, &x, 8);
+ e = (a>>52) - 1022;
+ return e*10;
+}
+#endif /* SQLITE_OMIT_VIRTUALTABLE */
+
+/*
+** Convert a LogEst into an integer.
+*/
+SQLITE_PRIVATE u64 sqlite3LogEstToInt(LogEst x){
+ u64 n;
+ if( x<10 ) return 1;
+ n = x%10;
+ x /= 10;
+ if( n>=5 ) n -= 2;
+ else if( n>=1 ) n -= 1;
+ if( x>=3 ){
+ return x>60 ? (u64)LARGEST_INT64 : (n+8)<<(x-3);
+ }
+ return (n+8)>>(3-x);
+}
+
/************** End of util.c ************************************************/
/************** Begin file hash.c ********************************************/
/*
@@ -22236,6 +26421,7 @@ SQLITE_PRIVATE void sqlite3FileSuffix3(const char *zBaseFilename, char *z){
** This is the implementation of generic hash-tables
** used in SQLite.
*/
+/* #include "sqliteInt.h" */
/* #include <assert.h> */
/* Turn bulk memory into a hash table object by initializing the
@@ -22275,12 +26461,11 @@ SQLITE_PRIVATE void sqlite3HashClear(Hash *pH){
/*
** 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--;
+static unsigned int strHash(const char *z){
+ unsigned int h = 0;
+ unsigned char c;
+ while( (c = (unsigned char)*z++)!=0 ){
+ h = (h<<3) ^ h ^ sqlite3UpperToLower[c];
}
return h;
}
@@ -22352,7 +26537,7 @@ static int rehash(Hash *pH, unsigned int new_size){
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;
+ unsigned int h = strHash(elem->pKey) % new_size;
next_elem = elem->next;
insertElement(pH, &new_ht[h], elem);
}
@@ -22360,28 +26545,33 @@ static int rehash(Hash *pH, unsigned int new_size){
}
/* 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.
+** hash table that matches the given key. The hash for this key is
+** also computed and returned in the *pH parameter.
*/
-static HashElem *findElementGivenHash(
+static HashElem *findElementWithHash(
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. */
+ unsigned int *pHash /* Write the hash value here */
){
HashElem *elem; /* Used to loop thru the element list */
int count; /* Number of elements left to test */
+ unsigned int h; /* The computed hash */
if( pH->ht ){
- struct _ht *pEntry = &pH->ht[h];
+ struct _ht *pEntry;
+ h = strHash(pKey) % pH->htsize;
+ pEntry = &pH->ht[h];
elem = pEntry->chain;
count = pEntry->count;
}else{
+ h = 0;
elem = pH->first;
count = pH->count;
}
- while( count-- && ALWAYS(elem) ){
- if( elem->nKey==nKey && sqlite3StrNICmp(elem->pKey,pKey,nKey)==0 ){
+ *pHash = h;
+ while( count-- ){
+ assert( elem!=0 );
+ if( sqlite3StrICmp(elem->pKey,pKey)==0 ){
return elem;
}
elem = elem->next;
@@ -22424,26 +26614,20 @@ static void removeElementGivenHash(
}
/* 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
+** that matches pKey. 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){
+SQLITE_PRIVATE void *sqlite3HashFind(const Hash *pH, const char *pKey){
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);
+ elem = findElementWithHash(pH, pKey, &h);
return elem ? elem->data : 0;
}
-/* Insert an element into the hash table pH. The key is pKey,nKey
+/* Insert an element into the hash table pH. The key is pKey
** and the data is "data".
**
** If no element exists with a matching key, then a new
@@ -22457,20 +26641,14 @@ SQLITE_PRIVATE void *sqlite3HashFind(const Hash *pH, const char *pKey, int nKey)
** 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){
+SQLITE_PRIVATE void *sqlite3HashInsert(Hash *pH, const char *pKey, 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);
+ elem = findElementWithHash(pH,pKey,&h);
if( elem ){
void *old_data = elem->data;
if( data==0 ){
@@ -22478,7 +26656,6 @@ SQLITE_PRIVATE void *sqlite3HashInsert(Hash *pH, const char *pKey, int nKey, voi
}else{
elem->data = data;
elem->pKey = pKey;
- assert(nKey==elem->nKey);
}
return old_data;
}
@@ -22486,180 +26663,194 @@ SQLITE_PRIVATE void *sqlite3HashInsert(Hash *pH, const char *pKey, int nKey, voi
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;
+ h = strHash(pKey) % pH->htsize;
}
}
- if( pH->ht ){
- insertElement(pH, &pH->ht[h], new_elem);
- }else{
- insertElement(pH, 0, new_elem);
- }
+ insertElement(pH, pH->ht ? &pH->ht[h] : 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)
+/* See the tool/mkopcodec.tcl script for details. */
+#if !defined(SQLITE_OMIT_EXPLAIN) \
+ || defined(VDBE_PROFILE) \
+ || defined(SQLITE_DEBUG)
+#if defined(SQLITE_ENABLE_EXPLAIN_COMMENTS) || defined(SQLITE_DEBUG)
+# define OpHelp(X) "\0" X
+#else
+# define OpHelp(X)
+#endif
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",
+ /* 1 */ "Savepoint" OpHelp(""),
+ /* 2 */ "AutoCommit" OpHelp(""),
+ /* 3 */ "Transaction" OpHelp(""),
+ /* 4 */ "SorterNext" OpHelp(""),
+ /* 5 */ "PrevIfOpen" OpHelp(""),
+ /* 6 */ "NextIfOpen" OpHelp(""),
+ /* 7 */ "Prev" OpHelp(""),
+ /* 8 */ "Next" OpHelp(""),
+ /* 9 */ "Checkpoint" OpHelp(""),
+ /* 10 */ "JournalMode" OpHelp(""),
+ /* 11 */ "Vacuum" OpHelp(""),
+ /* 12 */ "VFilter" OpHelp("iplan=r[P3] zplan='P4'"),
+ /* 13 */ "VUpdate" OpHelp("data=r[P3@P2]"),
+ /* 14 */ "Goto" OpHelp(""),
+ /* 15 */ "Gosub" OpHelp(""),
+ /* 16 */ "Return" OpHelp(""),
+ /* 17 */ "InitCoroutine" OpHelp(""),
+ /* 18 */ "EndCoroutine" OpHelp(""),
+ /* 19 */ "Not" OpHelp("r[P2]= !r[P1]"),
+ /* 20 */ "Yield" OpHelp(""),
+ /* 21 */ "HaltIfNull" OpHelp("if r[P3]=null halt"),
+ /* 22 */ "Halt" OpHelp(""),
+ /* 23 */ "Integer" OpHelp("r[P2]=P1"),
+ /* 24 */ "Int64" OpHelp("r[P2]=P4"),
+ /* 25 */ "String" OpHelp("r[P2]='P4' (len=P1)"),
+ /* 26 */ "Null" OpHelp("r[P2..P3]=NULL"),
+ /* 27 */ "SoftNull" OpHelp("r[P1]=NULL"),
+ /* 28 */ "Blob" OpHelp("r[P2]=P4 (len=P1)"),
+ /* 29 */ "Variable" OpHelp("r[P2]=parameter(P1,P4)"),
+ /* 30 */ "Move" OpHelp("r[P2@P3]=r[P1@P3]"),
+ /* 31 */ "Copy" OpHelp("r[P2@P3+1]=r[P1@P3+1]"),
+ /* 32 */ "SCopy" OpHelp("r[P2]=r[P1]"),
+ /* 33 */ "IntCopy" OpHelp("r[P2]=r[P1]"),
+ /* 34 */ "ResultRow" OpHelp("output=r[P1@P2]"),
+ /* 35 */ "CollSeq" OpHelp(""),
+ /* 36 */ "Function0" OpHelp("r[P3]=func(r[P2@P5])"),
+ /* 37 */ "Function" OpHelp("r[P3]=func(r[P2@P5])"),
+ /* 38 */ "AddImm" OpHelp("r[P1]=r[P1]+P2"),
+ /* 39 */ "MustBeInt" OpHelp(""),
+ /* 40 */ "RealAffinity" OpHelp(""),
+ /* 41 */ "Cast" OpHelp("affinity(r[P1])"),
+ /* 42 */ "Permutation" OpHelp(""),
+ /* 43 */ "Compare" OpHelp("r[P1@P3] <-> r[P2@P3]"),
+ /* 44 */ "Jump" OpHelp(""),
+ /* 45 */ "Once" OpHelp(""),
+ /* 46 */ "If" OpHelp(""),
+ /* 47 */ "IfNot" OpHelp(""),
+ /* 48 */ "Column" OpHelp("r[P3]=PX"),
+ /* 49 */ "Affinity" OpHelp("affinity(r[P1@P2])"),
+ /* 50 */ "MakeRecord" OpHelp("r[P3]=mkrec(r[P1@P2])"),
+ /* 51 */ "Count" OpHelp("r[P2]=count()"),
+ /* 52 */ "ReadCookie" OpHelp(""),
+ /* 53 */ "SetCookie" OpHelp(""),
+ /* 54 */ "ReopenIdx" OpHelp("root=P2 iDb=P3"),
+ /* 55 */ "OpenRead" OpHelp("root=P2 iDb=P3"),
+ /* 56 */ "OpenWrite" OpHelp("root=P2 iDb=P3"),
+ /* 57 */ "OpenAutoindex" OpHelp("nColumn=P2"),
+ /* 58 */ "OpenEphemeral" OpHelp("nColumn=P2"),
+ /* 59 */ "SorterOpen" OpHelp(""),
+ /* 60 */ "SequenceTest" OpHelp("if( cursor[P1].ctr++ ) pc = P2"),
+ /* 61 */ "OpenPseudo" OpHelp("P3 columns in r[P2]"),
+ /* 62 */ "Close" OpHelp(""),
+ /* 63 */ "ColumnsUsed" OpHelp(""),
+ /* 64 */ "SeekLT" OpHelp("key=r[P3@P4]"),
+ /* 65 */ "SeekLE" OpHelp("key=r[P3@P4]"),
+ /* 66 */ "SeekGE" OpHelp("key=r[P3@P4]"),
+ /* 67 */ "SeekGT" OpHelp("key=r[P3@P4]"),
+ /* 68 */ "Seek" OpHelp("intkey=r[P2]"),
+ /* 69 */ "NoConflict" OpHelp("key=r[P3@P4]"),
+ /* 70 */ "NotFound" OpHelp("key=r[P3@P4]"),
+ /* 71 */ "Or" OpHelp("r[P3]=(r[P1] || r[P2])"),
+ /* 72 */ "And" OpHelp("r[P3]=(r[P1] && r[P2])"),
+ /* 73 */ "Found" OpHelp("key=r[P3@P4]"),
+ /* 74 */ "NotExists" OpHelp("intkey=r[P3]"),
+ /* 75 */ "Sequence" OpHelp("r[P2]=cursor[P1].ctr++"),
+ /* 76 */ "IsNull" OpHelp("if r[P1]==NULL goto P2"),
+ /* 77 */ "NotNull" OpHelp("if r[P1]!=NULL goto P2"),
+ /* 78 */ "Ne" OpHelp("if r[P1]!=r[P3] goto P2"),
+ /* 79 */ "Eq" OpHelp("if r[P1]==r[P3] goto P2"),
+ /* 80 */ "Gt" OpHelp("if r[P1]>r[P3] goto P2"),
+ /* 81 */ "Le" OpHelp("if r[P1]<=r[P3] goto P2"),
+ /* 82 */ "Lt" OpHelp("if r[P1]<r[P3] goto P2"),
+ /* 83 */ "Ge" OpHelp("if r[P1]>=r[P3] goto P2"),
+ /* 84 */ "NewRowid" OpHelp("r[P2]=rowid"),
+ /* 85 */ "BitAnd" OpHelp("r[P3]=r[P1]&r[P2]"),
+ /* 86 */ "BitOr" OpHelp("r[P3]=r[P1]|r[P2]"),
+ /* 87 */ "ShiftLeft" OpHelp("r[P3]=r[P2]<<r[P1]"),
+ /* 88 */ "ShiftRight" OpHelp("r[P3]=r[P2]>>r[P1]"),
+ /* 89 */ "Add" OpHelp("r[P3]=r[P1]+r[P2]"),
+ /* 90 */ "Subtract" OpHelp("r[P3]=r[P2]-r[P1]"),
+ /* 91 */ "Multiply" OpHelp("r[P3]=r[P1]*r[P2]"),
+ /* 92 */ "Divide" OpHelp("r[P3]=r[P2]/r[P1]"),
+ /* 93 */ "Remainder" OpHelp("r[P3]=r[P2]%r[P1]"),
+ /* 94 */ "Concat" OpHelp("r[P3]=r[P2]+r[P1]"),
+ /* 95 */ "Insert" OpHelp("intkey=r[P3] data=r[P2]"),
+ /* 96 */ "BitNot" OpHelp("r[P1]= ~r[P1]"),
+ /* 97 */ "String8" OpHelp("r[P2]='P4'"),
+ /* 98 */ "InsertInt" OpHelp("intkey=P3 data=r[P2]"),
+ /* 99 */ "Delete" OpHelp(""),
+ /* 100 */ "ResetCount" OpHelp(""),
+ /* 101 */ "SorterCompare" OpHelp("if key(P1)!=trim(r[P3],P4) goto P2"),
+ /* 102 */ "SorterData" OpHelp("r[P2]=data"),
+ /* 103 */ "RowKey" OpHelp("r[P2]=key"),
+ /* 104 */ "RowData" OpHelp("r[P2]=data"),
+ /* 105 */ "Rowid" OpHelp("r[P2]=rowid"),
+ /* 106 */ "NullRow" OpHelp(""),
+ /* 107 */ "Last" OpHelp(""),
+ /* 108 */ "SorterSort" OpHelp(""),
+ /* 109 */ "Sort" OpHelp(""),
+ /* 110 */ "Rewind" OpHelp(""),
+ /* 111 */ "SorterInsert" OpHelp(""),
+ /* 112 */ "IdxInsert" OpHelp("key=r[P2]"),
+ /* 113 */ "IdxDelete" OpHelp("key=r[P2@P3]"),
+ /* 114 */ "IdxRowid" OpHelp("r[P2]=rowid"),
+ /* 115 */ "IdxLE" OpHelp("key=r[P3@P4]"),
+ /* 116 */ "IdxGT" OpHelp("key=r[P3@P4]"),
+ /* 117 */ "IdxLT" OpHelp("key=r[P3@P4]"),
+ /* 118 */ "IdxGE" OpHelp("key=r[P3@P4]"),
+ /* 119 */ "Destroy" OpHelp(""),
+ /* 120 */ "Clear" OpHelp(""),
+ /* 121 */ "ResetSorter" OpHelp(""),
+ /* 122 */ "CreateIndex" OpHelp("r[P2]=root iDb=P1"),
+ /* 123 */ "CreateTable" OpHelp("r[P2]=root iDb=P1"),
+ /* 124 */ "ParseSchema" OpHelp(""),
+ /* 125 */ "LoadAnalysis" OpHelp(""),
+ /* 126 */ "DropTable" OpHelp(""),
+ /* 127 */ "DropIndex" OpHelp(""),
+ /* 128 */ "DropTrigger" OpHelp(""),
+ /* 129 */ "IntegrityCk" OpHelp(""),
+ /* 130 */ "RowSetAdd" OpHelp("rowset(P1)=r[P2]"),
+ /* 131 */ "RowSetRead" OpHelp("r[P3]=rowset(P1)"),
+ /* 132 */ "RowSetTest" OpHelp("if r[P3] in rowset(P1) goto P2"),
+ /* 133 */ "Real" OpHelp("r[P2]=P4"),
+ /* 134 */ "Program" OpHelp(""),
+ /* 135 */ "Param" OpHelp(""),
+ /* 136 */ "FkCounter" OpHelp("fkctr[P1]+=P2"),
+ /* 137 */ "FkIfZero" OpHelp("if fkctr[P1]==0 goto P2"),
+ /* 138 */ "MemMax" OpHelp("r[P1]=max(r[P1],r[P2])"),
+ /* 139 */ "IfPos" OpHelp("if r[P1]>0 then r[P1]-=P3, goto P2"),
+ /* 140 */ "SetIfNotPos" OpHelp("if r[P1]<=0 then r[P2]=P3"),
+ /* 141 */ "IfNotZero" OpHelp("if r[P1]!=0 then r[P1]-=P3, goto P2"),
+ /* 142 */ "DecrJumpZero" OpHelp("if (--r[P1])==0 goto P2"),
+ /* 143 */ "JumpZeroIncr" OpHelp("if (r[P1]++)==0 ) goto P2"),
+ /* 144 */ "AggStep0" OpHelp("accum=r[P3] step(r[P2@P5])"),
+ /* 145 */ "AggStep" OpHelp("accum=r[P3] step(r[P2@P5])"),
+ /* 146 */ "AggFinal" OpHelp("accum=r[P1] N=P2"),
+ /* 147 */ "IncrVacuum" OpHelp(""),
+ /* 148 */ "Expire" OpHelp(""),
+ /* 149 */ "TableLock" OpHelp("iDb=P1 root=P2 write=P3"),
+ /* 150 */ "VBegin" OpHelp(""),
+ /* 151 */ "VCreate" OpHelp(""),
+ /* 152 */ "VDestroy" OpHelp(""),
+ /* 153 */ "VOpen" OpHelp(""),
+ /* 154 */ "VColumn" OpHelp("r[P3]=vcolumn(P2)"),
+ /* 155 */ "VNext" OpHelp(""),
+ /* 156 */ "VRename" OpHelp(""),
+ /* 157 */ "Pagecount" OpHelp(""),
+ /* 158 */ "MaxPgcnt" OpHelp(""),
+ /* 159 */ "Init" OpHelp("Start at P2"),
+ /* 160 */ "CursorHint" OpHelp(""),
+ /* 161 */ "Noop" OpHelp(""),
+ /* 162 */ "Explain" OpHelp(""),
};
return azName[i];
}
@@ -22712,15 +26903,9 @@ SQLITE_PRIVATE const char *sqlite3OpcodeName(int i){
** * Definitions of sqlite3_vfs objects for all locking methods
** plus implementations of sqlite3_os_init() and sqlite3_os_end().
*/
+/* #include "sqliteInt.h" */
#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:
@@ -22747,44 +26932,6 @@ SQLITE_PRIVATE const char *sqlite3OpcodeName(int i){
#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>
@@ -22794,23 +26941,34 @@ SQLITE_PRIVATE const char *sqlite3OpcodeName(int i){
/* #include <time.h> */
#include <sys/time.h>
#include <errno.h>
-#ifndef SQLITE_OMIT_WAL
-#include <sys/mman.h>
+#if !defined(SQLITE_OMIT_WAL) || SQLITE_MAX_MMAP_SIZE>0
+# 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
+# include <sys/file.h>
+# include <sys/param.h>
#endif /* SQLITE_ENABLE_LOCKING_STYLE */
-#if defined(__APPLE__) || (SQLITE_ENABLE_LOCKING_STYLE && !OS_VXWORKS)
+#if defined(__APPLE__) && ((__MAC_OS_X_VERSION_MIN_REQUIRED > 1050) || \
+ (__IPHONE_OS_VERSION_MIN_REQUIRED > 2000))
+# if (!defined(TARGET_OS_EMBEDDED) || (TARGET_OS_EMBEDDED==0)) \
+ && (!defined(TARGET_IPHONE_SIMULATOR) || (TARGET_IPHONE_SIMULATOR==0))
+# define HAVE_GETHOSTUUID 1
+# else
+# warning "gethostuuid() is disabled."
+# endif
+#endif
+
+
+#if OS_VXWORKS
+/* # include <sys/ioctl.h> */
+# include <semaphore.h>
+# include <limits.h>
+#endif /* OS_VXWORKS */
+
+#if defined(__APPLE__) || SQLITE_ENABLE_LOCKING_STYLE
# include <sys/mount.h>
#endif
@@ -22851,6 +27009,10 @@ SQLITE_PRIVATE const char *sqlite3OpcodeName(int i){
*/
#define MAX_PATHNAME 512
+/* Always cast the getpid() return type for compatibility with
+** kernel modules in VxWorks. */
+#define osGetpid(X) (pid_t)getpid()
+
/*
** 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
@@ -22893,6 +27055,13 @@ struct unixFile {
const char *zPath; /* Name of the file */
unixShm *pShm; /* Shared memory segment information */
int szChunk; /* Configured by FCNTL_CHUNK_SIZE */
+#if SQLITE_MAX_MMAP_SIZE>0
+ int nFetchOut; /* Number of outstanding xFetch refs */
+ sqlite3_int64 mmapSize; /* Usable size of mapping at pMapRegion */
+ sqlite3_int64 mmapSizeActual; /* Actual size of mapping at pMapRegion */
+ sqlite3_int64 mmapSizeMax; /* Configured FCNTL_MMAP_SIZE value */
+ void *pMapRegion; /* Memory mapped region */
+#endif
#ifdef __QNXNTO__
int sectorSize; /* Device sector size */
int deviceCharacteristics; /* Precomputed device characteristics */
@@ -22917,7 +27086,9 @@ struct unixFile {
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.
@@ -22926,6 +27097,12 @@ struct unixFile {
#endif
};
+/* This variable holds the process id (pid) from when the xRandomness()
+** method was called. If xOpen() is called from a different process id,
+** indicating that a fork() has occurred, the PRNG will be reset.
+*/
+static pid_t randomnessPid = 0;
+
/*
** Allowed values for the unixFile.ctrlFlags bitmask:
*/
@@ -22978,16 +27155,6 @@ struct unixFile {
# 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.
@@ -23183,6 +27350,25 @@ SQLITE_API int sqlite3_open_file_count = 0;
#endif
/*
+** HAVE_MREMAP defaults to true on Linux and false everywhere else.
+*/
+#if !defined(HAVE_MREMAP)
+# if defined(__linux__) && defined(_GNU_SOURCE)
+# define HAVE_MREMAP 1
+# else
+# define HAVE_MREMAP 0
+# endif
+#endif
+
+/*
+** Explicitly call the 64-bit version of lseek() on Android. Otherwise, lseek()
+** is the 32-bit version, even if _FILE_OFFSET_BITS=64 is defined.
+*/
+#ifdef __ANDROID__
+# define lseek lseek64
+#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.
@@ -23194,17 +27380,9 @@ 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*);
+static int unixGetpagesize(void);
/*
** Many system calls are accessed through pointer-to-functions so that
@@ -23213,7 +27391,7 @@ static int openDirectory(const char*, int*);
** to all overrideable system calls.
*/
static struct unix_syscall {
- const char *zName; /* Name of the sytem call */
+ const char *zName; /* Name of the system call */
sqlite3_syscall_ptr pCurrent; /* Current value of the system call */
sqlite3_syscall_ptr pDefault; /* Default value */
} aSyscall[] = {
@@ -23288,11 +27466,7 @@ static struct unix_syscall {
#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
+ { "fchmod", (sqlite3_syscall_ptr)fchmod, 0 },
#define osFchmod ((int(*)(int,mode_t))aSyscall[14].pCurrent)
#if defined(HAVE_POSIX_FALLOCATE) && HAVE_POSIX_FALLOCATE
@@ -23314,14 +27488,50 @@ static struct unix_syscall {
{ "rmdir", (sqlite3_syscall_ptr)rmdir, 0 },
#define osRmdir ((int(*)(const char*))aSyscall[19].pCurrent)
- { "fchown", (sqlite3_syscall_ptr)posixFchown, 0 },
+ { "fchown", (sqlite3_syscall_ptr)fchown, 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)
+ { "geteuid", (sqlite3_syscall_ptr)geteuid, 0 },
+#define osGeteuid ((uid_t(*)(void))aSyscall[21].pCurrent)
+
+#if !defined(SQLITE_OMIT_WAL) || SQLITE_MAX_MMAP_SIZE>0
+ { "mmap", (sqlite3_syscall_ptr)mmap, 0 },
+#define osMmap ((void*(*)(void*,size_t,int,int,int,off_t))aSyscall[22].pCurrent)
+
+ { "munmap", (sqlite3_syscall_ptr)munmap, 0 },
+#define osMunmap ((void*(*)(void*,size_t))aSyscall[23].pCurrent)
+
+#if HAVE_MREMAP
+ { "mremap", (sqlite3_syscall_ptr)mremap, 0 },
+#else
+ { "mremap", (sqlite3_syscall_ptr)0, 0 },
+#endif
+#define osMremap ((void*(*)(void*,size_t,size_t,int,...))aSyscall[24].pCurrent)
+
+ { "getpagesize", (sqlite3_syscall_ptr)unixGetpagesize, 0 },
+#define osGetpagesize ((int(*)(void))aSyscall[25].pCurrent)
+
+ { "readlink", (sqlite3_syscall_ptr)readlink, 0 },
+#define osReadlink ((ssize_t(*)(const char*,char*,size_t))aSyscall[26].pCurrent)
+
+#endif
}; /* End of the overrideable system calls */
+
+/*
+** 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 robustFchown(int fd, uid_t uid, gid_t gid){
+#if OS_VXWORKS
+ return 0;
+#else
+ return osGeteuid() ? 0 : osFchown(fd,uid,gid);
+#endif
+}
+
/*
** This is the xSetSystemCall() method of sqlite3_vfs for all of the
** "unix" VFSes. Return SQLITE_OK opon successfully updating the
@@ -23406,6 +27616,15 @@ static const char *unixNextSystemCall(sqlite3_vfs *p, const char *zName){
}
/*
+** Do not accept any file descriptor less than this value, in order to avoid
+** opening database file using file descriptors that are commonly used for
+** standard input, output, and error.
+*/
+#ifndef SQLITE_MINIMUM_FILE_DESCRIPTOR
+# define SQLITE_MINIMUM_FILE_DESCRIPTOR 3
+#endif
+
+/*
** Invoke open(). Do so multiple times, until it either succeeds or
** fails for some reason other than EINTR.
**
@@ -23424,27 +27643,38 @@ static const char *unixNextSystemCall(sqlite3_vfs *p, const char *zName){
*/
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{
+ mode_t m2 = m ? m : SQLITE_DEFAULT_FILE_PERMISSIONS;
+ while(1){
#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( fd<0 ){
+ if( errno==EINTR ) continue;
+ break;
+ }
+ if( fd>=SQLITE_MINIMUM_FILE_DESCRIPTOR ) break;
+ osClose(fd);
+ sqlite3_log(SQLITE_WARNING,
+ "attempt to open \"%s\" as file descriptor %d", z, fd);
+ fd = -1;
+ if( osOpen("/dev/null", f, m)<0 ) break;
+ }
+ if( fd>=0 ){
+ if( m!=0 ){
+ struct stat statbuf;
+ if( osFstat(fd, &statbuf)==0
+ && statbuf.st_size==0
+ && (statbuf.st_mode&0777)!=m
+ ){
+ osFchmod(fd, m);
+ }
+ }
#if defined(FD_CLOEXEC) && (!defined(O_CLOEXEC) || O_CLOEXEC==0)
- if( fd>=0 ) osFcntl(fd, F_SETFD, osFcntl(fd, F_GETFD, 0) | FD_CLOEXEC);
+ osFcntl(fd, F_SETFD, osFcntl(fd, F_GETFD, 0) | FD_CLOEXEC);
#endif
+ }
return fd;
}
@@ -23463,22 +27693,22 @@ static int robust_open(const char *z, int f, mode_t m){
** unixEnterLeave()
*/
static void unixEnterMutex(void){
- sqlite3_mutex_enter(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER));
+ sqlite3_mutex_enter(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_VFS1));
}
static void unixLeaveMutex(void){
- sqlite3_mutex_leave(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER));
+ sqlite3_mutex_leave(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_VFS1));
}
#ifdef SQLITE_DEBUG
static int unixMutexHeld(void) {
- return sqlite3_mutex_held(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER));
+ return sqlite3_mutex_held(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_VFS1));
}
#endif
-#if defined(SQLITE_TEST) && defined(SQLITE_DEBUG)
+#ifdef SQLITE_HAVE_OS_TRACE
/*
** Helper function for printing out trace information from debugging
-** binaries. This returns the string represetation of the supplied
+** binaries. This returns the string representation of the supplied
** integer lock-type.
*/
static const char *azFileLock(int eFileLock){
@@ -23555,9 +27785,22 @@ static int lockTrace(int fd, int op, struct flock *p){
/*
** Retry ftruncate() calls that fail due to EINTR
+**
+** All calls to ftruncate() within this file should be made through
+** this wrapper. On the Android platform, bypassing the logic below
+** could lead to a corrupt database.
*/
static int robust_ftruncate(int h, sqlite3_int64 sz){
int rc;
+#ifdef __ANDROID__
+ /* On Android, ftruncate() always uses 32-bit offsets, even if
+ ** _FILE_OFFSET_BITS=64 is defined. This means it is unsafe to attempt to
+ ** truncate a file to any size larger than 2GiB. Silently ignore any
+ ** such attempts. */
+ if( sz>(sqlite3_int64)0x7FFFFFFF ){
+ rc = SQLITE_OK;
+ }else
+#endif
do{ rc = osFtruncate(h,sz); }while( rc<0 && errno==EINTR );
return rc;
}
@@ -23573,23 +27816,12 @@ static int robust_ftruncate(int h, sqlite3_int64 sz){
** should handle ENOLCK, ENOTSUP, EOPNOTSUPP separately.
*/
static int sqliteErrorFromPosixError(int posixError, int sqliteIOErr) {
+ assert( (sqliteIOErr == SQLITE_IOERR_LOCK) ||
+ (sqliteIOErr == SQLITE_IOERR_UNLOCK) ||
+ (sqliteIOErr == SQLITE_IOERR_RDLOCK) ||
+ (sqliteIOErr == SQLITE_IOERR_CHECKRESERVEDLOCK) );
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 EACCES:
case EAGAIN:
case ETIMEDOUT:
case EBUSY:
@@ -23599,58 +27831,15 @@ static int sqliteErrorFromPosixError(int posixError, int sqliteIOErr) {
* 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 ***************
**
@@ -23736,7 +27925,7 @@ static struct vxworksFileId *vxworksFindFileId(const char *zAbsoluteName){
assert( zAbsoluteName[0]=='/' );
n = (int)strlen(zAbsoluteName);
- pNew = sqlite3_malloc( sizeof(*pNew) + (n+1) );
+ pNew = sqlite3_malloc64( sizeof(*pNew) + (n+1) );
if( pNew==0 ) return 0;
pNew->zCanonicalName = (char*)&pNew[1];
memcpy(pNew->zCanonicalName, zAbsoluteName, n+1);
@@ -23928,7 +28117,7 @@ static unixInodeInfo *inodeList = 0;
/*
**
-** This function - unixLogError_x(), is only ever called via the macro
+** This function - unixLogErrorAtLine(), is only ever called via the macro
** unixLogError().
**
** It is invoked after an error occurs in an OS function and errno has been
@@ -23986,7 +28175,6 @@ static int unixLogErrorAtLine(
zErr = strerror(iErrno);
#endif
- assert( errcode!=SQLITE_OK );
if( zPath==0 ) zPath = "";
sqlite3_log(errcode,
"os_unix.c:%d: (%d) %s(%s) - %s",
@@ -24017,6 +28205,14 @@ static void robust_close(unixFile *pFile, int h, int lineno){
}
/*
+** Set the pFile->lastErrno. Do this in a subroutine as that provides
+** a convenient place to set a breakpoint.
+*/
+static void storeLastErrno(unixFile *pFile, int error){
+ pFile->lastErrno = error;
+}
+
+/*
** Close all file descriptors accumuated in the unixInodeInfo->pUnused list.
*/
static void closePendingFds(unixFile *pFile){
@@ -24089,8 +28285,8 @@ static int findInodeInfo(
fd = pFile->h;
rc = osFstat(fd, &statbuf);
if( rc!=0 ){
- pFile->lastErrno = errno;
-#ifdef EOVERFLOW
+ storeLastErrno(pFile, errno);
+#if defined(EOVERFLOW) && defined(SQLITE_DISABLE_LFS)
if( pFile->lastErrno==EOVERFLOW ) return SQLITE_NOLFS;
#endif
return SQLITE_IOERR;
@@ -24110,12 +28306,12 @@ static int findInodeInfo(
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;
+ storeLastErrno(pFile, errno);
return SQLITE_IOERR;
}
rc = osFstat(fd, &statbuf);
if( rc!=0 ){
- pFile->lastErrno = errno;
+ storeLastErrno(pFile, errno);
return SQLITE_IOERR;
}
}
@@ -24133,7 +28329,7 @@ static int findInodeInfo(
pInode = pInode->pNext;
}
if( pInode==0 ){
- pInode = sqlite3_malloc( sizeof(*pInode) );
+ pInode = sqlite3_malloc64( sizeof(*pInode) );
if( pInode==0 ){
return SQLITE_NOMEM;
}
@@ -24151,6 +28347,51 @@ static int findInodeInfo(
return SQLITE_OK;
}
+/*
+** Return TRUE if pFile has been renamed or unlinked since it was first opened.
+*/
+static int fileHasMoved(unixFile *pFile){
+#if OS_VXWORKS
+ return pFile->pInode!=0 && pFile->pId!=pFile->pInode->fileId.pId;
+#else
+ struct stat buf;
+ return pFile->pInode!=0 &&
+ (osStat(pFile->zPath, &buf)!=0 || buf.st_ino!=pFile->pInode->fileId.ino);
+#endif
+}
+
+
+/*
+** Check a unixFile that is a database. Verify the following:
+**
+** (1) There is exactly one hard link on the file
+** (2) The file is not a symbolic link
+** (3) The file has not been renamed or unlinked
+**
+** Issue sqlite3_log(SQLITE_WARNING,...) messages if anything is not right.
+*/
+static void verifyDbFile(unixFile *pFile){
+ struct stat buf;
+ int rc;
+ rc = osFstat(pFile->h, &buf);
+ if( rc!=0 ){
+ sqlite3_log(SQLITE_WARNING, "cannot fstat db file %s", pFile->zPath);
+ return;
+ }
+ if( buf.st_nlink==0 && (pFile->ctrlFlags & UNIXFILE_DELETE)==0 ){
+ sqlite3_log(SQLITE_WARNING, "file unlinked while open: %s", pFile->zPath);
+ return;
+ }
+ if( buf.st_nlink>1 ){
+ sqlite3_log(SQLITE_WARNING, "multiple links to file: %s", pFile->zPath);
+ return;
+ }
+ if( fileHasMoved(pFile) ){
+ sqlite3_log(SQLITE_WARNING, "file renamed while open: %s", pFile->zPath);
+ return;
+ }
+}
+
/*
** This routine checks if there is a RESERVED lock held on the specified
@@ -24166,6 +28407,7 @@ static int unixCheckReservedLock(sqlite3_file *id, int *pResOut){
SimulateIOError( return SQLITE_IOERR_CHECKRESERVEDLOCK; );
assert( pFile );
+ assert( pFile->eFileLock<=SHARED_LOCK );
unixEnterMutex(); /* Because pFile->pInode is shared across threads */
/* Check if a thread in this process holds such a lock */
@@ -24184,7 +28426,7 @@ static int unixCheckReservedLock(sqlite3_file *id, int *pResOut){
lock.l_type = F_WRLCK;
if( osFcntl(pFile->h, F_GETLK, &lock) ){
rc = SQLITE_IOERR_CHECKRESERVEDLOCK;
- pFile->lastErrno = errno;
+ storeLastErrno(pFile, errno);
} else if( lock.l_type!=F_UNLCK ){
reserved = 1;
}
@@ -24222,9 +28464,7 @@ static int unixFileLock(unixFile *pFile, struct flock *pLock){
unixInodeInfo *pInode = pFile->pInode;
assert( unixMutexHeld() );
assert( pInode!=0 );
- if( ((pFile->ctrlFlags & UNIXFILE_EXCL)!=0 || pInode->bProcessLock)
- && ((pFile->ctrlFlags & UNIXFILE_RDONLY)==0)
- ){
+ if( (pFile->ctrlFlags & (UNIXFILE_EXCL|UNIXFILE_RDONLY))==UNIXFILE_EXCL ){
if( pInode->bProcessLock==0 ){
struct flock lock;
assert( pInode->nLock==0 );
@@ -24317,7 +28557,8 @@ static int unixLock(sqlite3_file *id, int eFileLock){
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()));
+ azFileLock(pFile->pInode->eFileLock), pFile->pInode->nShared,
+ osGetpid(0)));
/* 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
@@ -24384,7 +28625,7 @@ static int unixLock(sqlite3_file *id, int eFileLock){
tErrno = errno;
rc = sqliteErrorFromPosixError(tErrno, SQLITE_IOERR_LOCK);
if( rc!=SQLITE_BUSY ){
- pFile->lastErrno = tErrno;
+ storeLastErrno(pFile, tErrno);
}
goto end_lock;
}
@@ -24419,7 +28660,7 @@ static int unixLock(sqlite3_file *id, int eFileLock){
if( rc ){
if( rc!=SQLITE_BUSY ){
- pFile->lastErrno = tErrno;
+ storeLastErrno(pFile, tErrno);
}
goto end_lock;
}else{
@@ -24452,7 +28693,7 @@ static int unixLock(sqlite3_file *id, int eFileLock){
tErrno = errno;
rc = sqliteErrorFromPosixError(tErrno, SQLITE_IOERR_LOCK);
if( rc!=SQLITE_BUSY ){
- pFile->lastErrno = tErrno;
+ storeLastErrno(pFile, tErrno);
}
}
}
@@ -24525,7 +28766,7 @@ static int posixUnlock(sqlite3_file *id, int eFileLock, int handleNFSUnlock){
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()));
+ osGetpid(0)));
assert( eFileLock<=SHARED_LOCK );
if( pFile->eFileLock<=eFileLock ){
@@ -24559,7 +28800,6 @@ static int posixUnlock(sqlite3_file *id, int eFileLock, int handleNFSUnlock){
** 4: [RRRR.]
*/
if( eFileLock==SHARED_LOCK ){
-
#if !defined(__APPLE__) || !SQLITE_ENABLE_LOCKING_STYLE
(void)handleNFSUnlock;
assert( handleNFSUnlock==0 );
@@ -24576,9 +28816,7 @@ static int posixUnlock(sqlite3_file *id, int eFileLock, int handleNFSUnlock){
if( unixFileLock(pFile, &lock)==(-1) ){
tErrno = errno;
rc = SQLITE_IOERR_UNLOCK;
- if( IS_LOCK_ERROR(rc) ){
- pFile->lastErrno = tErrno;
- }
+ storeLastErrno(pFile, tErrno);
goto end_unlock;
}
lock.l_type = F_RDLCK;
@@ -24589,7 +28827,7 @@ static int posixUnlock(sqlite3_file *id, int eFileLock, int handleNFSUnlock){
tErrno = errno;
rc = sqliteErrorFromPosixError(tErrno, SQLITE_IOERR_RDLOCK);
if( IS_LOCK_ERROR(rc) ){
- pFile->lastErrno = tErrno;
+ storeLastErrno(pFile, tErrno);
}
goto end_unlock;
}
@@ -24600,9 +28838,7 @@ static int posixUnlock(sqlite3_file *id, int eFileLock, int handleNFSUnlock){
if( unixFileLock(pFile, &lock)==(-1) ){
tErrno = errno;
rc = SQLITE_IOERR_UNLOCK;
- if( IS_LOCK_ERROR(rc) ){
- pFile->lastErrno = tErrno;
- }
+ storeLastErrno(pFile, tErrno);
goto end_unlock;
}
}else
@@ -24620,7 +28856,7 @@ static int posixUnlock(sqlite3_file *id, int eFileLock, int handleNFSUnlock){
** SQLITE_BUSY would confuse the upper layer (in practice it causes
** an assert to fail). */
rc = SQLITE_IOERR_RDLOCK;
- pFile->lastErrno = errno;
+ storeLastErrno(pFile, errno);
goto end_unlock;
}
}
@@ -24633,7 +28869,7 @@ static int posixUnlock(sqlite3_file *id, int eFileLock, int handleNFSUnlock){
pInode->eFileLock = SHARED_LOCK;
}else{
rc = SQLITE_IOERR_UNLOCK;
- pFile->lastErrno = errno;
+ storeLastErrno(pFile, errno);
goto end_unlock;
}
}
@@ -24651,7 +28887,7 @@ static int posixUnlock(sqlite3_file *id, int eFileLock, int handleNFSUnlock){
pInode->eFileLock = NO_LOCK;
}else{
rc = SQLITE_IOERR_UNLOCK;
- pFile->lastErrno = errno;
+ storeLastErrno(pFile, errno);
pInode->eFileLock = NO_LOCK;
pFile->eFileLock = NO_LOCK;
}
@@ -24682,9 +28918,17 @@ end_unlock:
** the requested locking level, this routine is a no-op.
*/
static int unixUnlock(sqlite3_file *id, int eFileLock){
+#if SQLITE_MAX_MMAP_SIZE>0
+ assert( eFileLock==SHARED_LOCK || ((unixFile *)id)->nFetchOut==0 );
+#endif
return posixUnlock(id, eFileLock, 0);
}
+#if SQLITE_MAX_MMAP_SIZE>0
+static int unixMapfile(unixFile *pFd, i64 nByte);
+static void unixUnmapfile(unixFile *pFd);
+#endif
+
/*
** This function performs the parts of the "close file" operation
** common to all locking schemes. It closes the directory and file
@@ -24697,6 +28941,9 @@ static int unixUnlock(sqlite3_file *id, int eFileLock){
*/
static int closeUnixFile(sqlite3_file *id){
unixFile *pFile = (unixFile*)id;
+#if SQLITE_MAX_MMAP_SIZE>0
+ unixUnmapfile(pFile);
+#endif
if( pFile->h>=0 ){
robust_close(pFile, pFile->h, __LINE__);
pFile->h = -1;
@@ -24710,6 +28957,13 @@ static int closeUnixFile(sqlite3_file *id){
pFile->pId = 0;
}
#endif
+#ifdef SQLITE_UNLINK_AFTER_CLOSE
+ if( pFile->ctrlFlags & UNIXFILE_DELETE ){
+ osUnlink(pFile->zPath);
+ sqlite3_free(*(char**)&pFile->zPath);
+ pFile->zPath = 0;
+ }
+#endif
OSTRACE(("CLOSE %-3d\n", pFile->h));
OpenCounter(-1);
sqlite3_free(pFile->pUnused);
@@ -24723,6 +28977,7 @@ static int closeUnixFile(sqlite3_file *id){
static int unixClose(sqlite3_file *id){
int rc = SQLITE_OK;
unixFile *pFile = (unixFile *)id;
+ verifyDbFile(pFile);
unixUnlock(id, NO_LOCK);
unixEnterMutex();
@@ -24791,7 +29046,7 @@ static int nolockClose(sqlite3_file *id) {
/******************************************************************************
************************* Begin dot-file Locking ******************************
**
-** The dotfile locking implementation uses the existance of separate lock
+** The dotfile locking implementation uses the existence 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:
**
@@ -24806,7 +29061,7 @@ static int nolockClose(sqlite3_file *id) {
**
** 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
+** The existence of a lock directory implies an EXCLUSIVE lock. All other
** lock types (SHARED, RESERVED, PENDING) are mapped into EXCLUSIVE.
*/
@@ -24834,17 +29089,7 @@ static int dotlockCheckReservedLock(sqlite3_file *id, int *pResOut) {
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;
- }
+ reserved = osAccess((const char*)pFile->lockingContext, 0)==0;
OSTRACE(("TEST WR-LOCK %d %d %d (dotlock)\n", pFile->h, rc, reserved));
*pResOut = reserved;
return rc;
@@ -24906,8 +29151,8 @@ static int dotlockLock(sqlite3_file *id, int eFileLock) {
rc = SQLITE_BUSY;
} else {
rc = sqliteErrorFromPosixError(tErrno, SQLITE_IOERR_LOCK);
- if( IS_LOCK_ERROR(rc) ){
- pFile->lastErrno = tErrno;
+ if( rc!=SQLITE_BUSY ){
+ storeLastErrno(pFile, tErrno);
}
}
return rc;
@@ -24934,7 +29179,7 @@ static int dotlockUnlock(sqlite3_file *id, int eFileLock) {
assert( pFile );
OSTRACE(("UNLOCK %d %d was %d pid=%d (dotlock)\n", pFile->h, eFileLock,
- pFile->eFileLock, getpid()));
+ pFile->eFileLock, osGetpid(0)));
assert( eFileLock<=SHARED_LOCK );
/* no-op if possible */
@@ -24953,15 +29198,13 @@ static int dotlockUnlock(sqlite3_file *id, int eFileLock) {
/* 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 ){
+ if( tErrno==ENOENT ){
+ rc = SQLITE_OK;
+ }else{
rc = SQLITE_IOERR_UNLOCK;
- }
- if( IS_LOCK_ERROR(rc) ){
- pFile->lastErrno = tErrno;
+ storeLastErrno(pFile, tErrno);
}
return rc;
}
@@ -24973,14 +29216,11 @@ static int dotlockUnlock(sqlite3_file *id, int eFileLock) {
** 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;
+ unixFile *pFile = (unixFile*)id;
+ assert( id!=0 );
+ dotlockUnlock(id, NO_LOCK);
+ sqlite3_free(pFile->lockingContext);
+ return closeUnixFile(id);
}
/****************** End of the dot-file lock implementation *******************
******************************************************************************/
@@ -24997,10 +29237,9 @@ static int dotlockClose(sqlite3_file *id) {
** 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.
+** Omit this section if SQLITE_ENABLE_LOCKING_STYLE is turned off
*/
-#if SQLITE_ENABLE_LOCKING_STYLE && !OS_VXWORKS
+#if SQLITE_ENABLE_LOCKING_STYLE
/*
** Retry flock() calls that fail with EINTR
@@ -25047,10 +29286,8 @@ static int flockCheckReservedLock(sqlite3_file *id, int *pResOut){
int tErrno = errno;
/* unlock failed with an error */
lrc = SQLITE_IOERR_UNLOCK;
- if( IS_LOCK_ERROR(lrc) ){
- pFile->lastErrno = tErrno;
- rc = lrc;
- }
+ storeLastErrno(pFile, tErrno);
+ rc = lrc;
}
} else {
int tErrno = errno;
@@ -25058,7 +29295,7 @@ static int flockCheckReservedLock(sqlite3_file *id, int *pResOut){
/* someone else might have it reserved */
lrc = sqliteErrorFromPosixError(tErrno, SQLITE_IOERR_LOCK);
if( IS_LOCK_ERROR(lrc) ){
- pFile->lastErrno = tErrno;
+ storeLastErrno(pFile, tErrno);
rc = lrc;
}
}
@@ -25124,7 +29361,7 @@ static int flockLock(sqlite3_file *id, int eFileLock) {
/* didn't get, must be busy */
rc = sqliteErrorFromPosixError(tErrno, SQLITE_IOERR_LOCK);
if( IS_LOCK_ERROR(rc) ){
- pFile->lastErrno = tErrno;
+ storeLastErrno(pFile, tErrno);
}
} else {
/* got it, set the type and return ok */
@@ -25153,7 +29390,7 @@ static int flockUnlock(sqlite3_file *id, int eFileLock) {
assert( pFile );
OSTRACE(("UNLOCK %d %d was %d pid=%d (flock)\n", pFile->h, eFileLock,
- pFile->eFileLock, getpid()));
+ pFile->eFileLock, osGetpid(0)));
assert( eFileLock<=SHARED_LOCK );
/* no-op if possible */
@@ -25183,12 +29420,9 @@ static int flockUnlock(sqlite3_file *id, int eFileLock) {
** Close a file.
*/
static int flockClose(sqlite3_file *id) {
- int rc = SQLITE_OK;
- if( id ){
- flockUnlock(id, NO_LOCK);
- rc = closeUnixFile(id);
- }
- return rc;
+ assert( id!=0 );
+ flockUnlock(id, NO_LOCK);
+ return closeUnixFile(id);
}
#endif /* SQLITE_ENABLE_LOCKING_STYLE && !OS_VXWORK */
@@ -25214,7 +29448,7 @@ static int flockClose(sqlite3_file *id) {
** 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) {
+static int semXCheckReservedLock(sqlite3_file *id, int *pResOut) {
int rc = SQLITE_OK;
int reserved = 0;
unixFile *pFile = (unixFile*)id;
@@ -25231,13 +29465,12 @@ static int semCheckReservedLock(sqlite3_file *id, int *pResOut) {
/* 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;
+ storeLastErrno(pFile, tErrno);
} else {
/* someone else has the lock when we are in NO_LOCK */
reserved = (pFile->eFileLock < SHARED_LOCK);
@@ -25282,9 +29515,8 @@ static int semCheckReservedLock(sqlite3_file *id, int *pResOut) {
** This routine will only increase a lock. Use the sqlite3OsUnlock()
** routine to lower a locking level.
*/
-static int semLock(sqlite3_file *id, int eFileLock) {
+static int semXLock(sqlite3_file *id, int eFileLock) {
unixFile *pFile = (unixFile*)id;
- int fd;
sem_t *pSem = pFile->pInode->pSem;
int rc = SQLITE_OK;
@@ -25316,14 +29548,14 @@ static int semLock(sqlite3_file *id, int eFileLock) {
** 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) {
+static int semXUnlock(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()));
+ pFile->eFileLock, osGetpid(0)));
assert( eFileLock<=SHARED_LOCK );
/* no-op if possible */
@@ -25342,7 +29574,7 @@ static int semUnlock(sqlite3_file *id, int eFileLock) {
int rc, tErrno = errno;
rc = sqliteErrorFromPosixError(tErrno, SQLITE_IOERR_UNLOCK);
if( IS_LOCK_ERROR(rc) ){
- pFile->lastErrno = tErrno;
+ storeLastErrno(pFile, tErrno);
}
return rc;
}
@@ -25353,10 +29585,10 @@ static int semUnlock(sqlite3_file *id, int eFileLock) {
/*
** Close a file.
*/
-static int semClose(sqlite3_file *id) {
+static int semXClose(sqlite3_file *id) {
if( id ){
unixFile *pFile = (unixFile*)id;
- semUnlock(id, NO_LOCK);
+ semXUnlock(id, NO_LOCK);
assert( pFile );
unixEnterMutex();
releaseInodeInfo(pFile);
@@ -25444,7 +29676,7 @@ static int afpSetLock(
setLockFlag ? SQLITE_IOERR_LOCK : SQLITE_IOERR_UNLOCK);
#endif /* SQLITE_IGNORE_AFP_LOCK_ERRORS */
if( IS_LOCK_ERROR(rc) ){
- pFile->lastErrno = tErrno;
+ storeLastErrno(pFile, tErrno);
}
return rc;
} else {
@@ -25537,7 +29769,7 @@ static int afpLock(sqlite3_file *id, int eFileLock){
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()));
+ azFileLock(pInode->eFileLock), pInode->nShared , osGetpid(0)));
/* 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
@@ -25627,7 +29859,7 @@ static int afpLock(sqlite3_file *id, int eFileLock){
lrc2 = afpSetLock(context->dbPath, pFile, PENDING_BYTE, 1, 0);
if( IS_LOCK_ERROR(lrc1) ) {
- pFile->lastErrno = lrc1Errno;
+ storeLastErrno(pFile, lrc1Errno);
rc = lrc1;
goto afp_end_lock;
} else if( IS_LOCK_ERROR(lrc2) ){
@@ -25723,7 +29955,7 @@ static int afpUnlock(sqlite3_file *id, int eFileLock) {
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()));
+ osGetpid(0)));
assert( eFileLock<=SHARED_LOCK );
if( pFile->eFileLock<=eFileLock ){
@@ -25815,23 +30047,22 @@ static int afpUnlock(sqlite3_file *id, int eFileLock) {
*/
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();
+ unixFile *pFile = (unixFile*)id;
+ assert( id!=0 );
+ 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;
}
@@ -25886,7 +30117,7 @@ static int nfsUnlock(sqlite3_file *id, int eFileLock){
** 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.
+** in 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
@@ -25900,7 +30131,7 @@ static int seekAndRead(unixFile *id, sqlite3_int64 offset, void *pBuf, int cnt){
#endif
TIMER_START;
assert( cnt==(cnt&0x1ffff) );
- cnt &= 0x1ffff;
+ assert( id->h>2 );
do{
#if defined(USE_PREAD)
got = osPread(id->h, pBuf, cnt, offset);
@@ -25910,13 +30141,9 @@ static int seekAndRead(unixFile *id, sqlite3_int64 offset, void *pBuf, int cnt){
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;
- }
+ SimulateIOError( newOffset = -1 );
+ if( newOffset<0 ){
+ storeLastErrno((unixFile*)id, errno);
return -1;
}
got = osRead(id->h, pBuf, cnt);
@@ -25925,7 +30152,7 @@ static int seekAndRead(unixFile *id, sqlite3_int64 offset, void *pBuf, int cnt){
if( got<0 ){
if( errno==EINTR ){ got = 1; continue; }
prior = 0;
- ((unixFile*)id)->lastErrno = errno;
+ storeLastErrno((unixFile*)id, errno);
break;
}else if( got>0 ){
cnt -= got;
@@ -25954,6 +30181,8 @@ static int unixRead(
unixFile *pFile = (unixFile *)id;
int got;
assert( id );
+ assert( offset>=0 );
+ 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. */
@@ -25964,6 +30193,23 @@ static int unixRead(
);
#endif
+#if SQLITE_MAX_MMAP_SIZE>0
+ /* Deal with as much of this read request as possible by transfering
+ ** data from the memory mapping using memcpy(). */
+ if( offset<pFile->mmapSize ){
+ if( offset+amt <= pFile->mmapSize ){
+ memcpy(pBuf, &((u8 *)(pFile->pMapRegion))[offset], amt);
+ return SQLITE_OK;
+ }else{
+ int nCopy = pFile->mmapSize - offset;
+ memcpy(pBuf, &((u8 *)(pFile->pMapRegion))[offset], nCopy);
+ pBuf = &((u8 *)pBuf)[nCopy];
+ amt -= nCopy;
+ offset += nCopy;
+ }
+ }
+#endif
+
got = seekAndRead(pFile, offset, pBuf, amt);
if( got==amt ){
return SQLITE_OK;
@@ -25971,7 +30217,7 @@ static int unixRead(
/* lastErrno set by seekAndRead */
return SQLITE_IOERR_READ;
}else{
- pFile->lastErrno = 0; /* not a system error */
+ storeLastErrno(pFile, 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;
@@ -25979,46 +30225,60 @@ static int unixRead(
}
/*
-** 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.
+** Attempt to seek the file-descriptor passed as the first argument to
+** absolute offset iOff, then attempt to write nBuf bytes of data from
+** pBuf to it. If an error occurs, return -1 and set *piErrno. Otherwise,
+** return the actual number of bytes written (which may be less than
+** nBuf).
*/
-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;
+static int seekAndWriteFd(
+ int fd, /* File descriptor to write to */
+ i64 iOff, /* File offset to begin writing at */
+ const void *pBuf, /* Copy data from this buffer to the file */
+ int nBuf, /* Size of buffer pBuf in bytes */
+ int *piErrno /* OUT: Error number if error occurs */
+){
+ int rc = 0; /* Value returned by system call */
+
+ assert( nBuf==(nBuf&0x1ffff) );
+ assert( fd>2 );
+ assert( piErrno!=0 );
+ nBuf &= 0x1ffff;
TIMER_START;
+
#if defined(USE_PREAD)
- do{ got = osPwrite(id->h, pBuf, cnt, offset); }while( got<0 && errno==EINTR );
+ do{ rc = (int)osPwrite(fd, pBuf, nBuf, iOff); }while( rc<0 && errno==EINTR );
#elif defined(USE_PREAD64)
- do{ got = osPwrite64(id->h, pBuf, cnt, offset);}while( got<0 && errno==EINTR);
+ do{ rc = (int)osPwrite64(fd, pBuf, nBuf, iOff);}while( rc<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;
+ i64 iSeek = lseek(fd, iOff, SEEK_SET);
+ SimulateIOError( iSeek = -1 );
+ if( iSeek<0 ){
+ rc = -1;
+ break;
}
- got = osWrite(id->h, pBuf, cnt);
- }while( got<0 && errno==EINTR );
+ rc = osWrite(fd, pBuf, nBuf);
+ }while( rc<0 && errno==EINTR );
#endif
+
TIMER_END;
- if( got<0 ){
- ((unixFile*)id)->lastErrno = errno;
- }
+ OSTRACE(("WRITE %-3d %5d %7lld %llu\n", fd, rc, iOff, TIMER_ELAPSED));
+
+ if( rc<0 ) *piErrno = errno;
+ return rc;
+}
- OSTRACE(("WRITE %-3d %5d %7lld %llu\n", id->h, got, offset, TIMER_ELAPSED));
- return got;
+
+/*
+** 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){
+ return seekAndWriteFd(id->h, offset, pBuf, cnt, &id->lastErrno);
}
@@ -26068,7 +30328,24 @@ static int unixWrite(
}
#endif
- while( amt>0 && (wrote = seekAndWrite(pFile, offset, pBuf, amt))>0 ){
+#if defined(SQLITE_MMAP_READWRITE) && SQLITE_MAX_MMAP_SIZE>0
+ /* Deal with as much of this write request as possible by transfering
+ ** data from the memory mapping using memcpy(). */
+ if( offset<pFile->mmapSize ){
+ if( offset+amt <= pFile->mmapSize ){
+ memcpy(&((u8 *)(pFile->pMapRegion))[offset], pBuf, amt);
+ return SQLITE_OK;
+ }else{
+ int nCopy = pFile->mmapSize - offset;
+ memcpy(&((u8 *)(pFile->pMapRegion))[offset], pBuf, nCopy);
+ pBuf = &((u8 *)pBuf)[nCopy];
+ amt -= nCopy;
+ offset += nCopy;
+ }
+ }
+#endif
+
+ while( (wrote = seekAndWrite(pFile, offset, pBuf, amt))<amt && wrote>0 ){
amt -= wrote;
offset += wrote;
pBuf = &((char*)pBuf)[wrote];
@@ -26076,12 +30353,12 @@ static int unixWrite(
SimulateIOError(( wrote=(-1), amt=1 ));
SimulateDiskfullError(( wrote=0, amt=1 ));
- if( amt>0 ){
+ if( amt>wrote ){
if( wrote<0 && pFile->lastErrno!=ENOSPC ){
/* lastErrno set by seekAndWrite */
return SQLITE_IOERR_WRITE;
}else{
- pFile->lastErrno = 0; /* not a system error */
+ storeLastErrno(pFile, 0); /* not a system error */
return SQLITE_FULL;
}
}
@@ -26102,9 +30379,9 @@ SQLITE_API int sqlite3_fullsync_count = 0;
** 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
+** then simply compile with -Dfdatasync=fdatasync or -DHAVE_FDATASYNC
*/
-#if !defined(fdatasync)
+#if !defined(fdatasync) && !HAVE_FDATASYNC
# define fdatasync fsync
#endif
@@ -26172,10 +30449,15 @@ static int full_fsync(int fd, int fullSync, int dataOnly){
#endif
/* If we compiled with the SQLITE_NO_SYNC flag, then syncing is a
- ** no-op
+ ** no-op. But go ahead and call fstat() to validate the file
+ ** descriptor as we need a method to provoke a failure during
+ ** coverate testing.
*/
#ifdef SQLITE_NO_SYNC
- rc = SQLITE_OK;
+ {
+ struct stat buf;
+ rc = osFstat(fd, &buf);
+ }
#elif HAVE_FULLFSYNC
if( fullSync ){
rc = osFcntl(fd, F_FULLFSYNC, 0);
@@ -26241,16 +30523,20 @@ static int openDirectory(const char *zFilename, int *pFd){
char zDirname[MAX_PATHNAME+1];
sqlite3_snprintf(MAX_PATHNAME, zDirname, "%s", zFilename);
- for(ii=(int)strlen(zDirname); ii>1 && zDirname[ii]!='/'; ii--);
+ for(ii=(int)strlen(zDirname); ii>0 && 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));
- }
+ }else{
+ if( zDirname[0]!='/' ) zDirname[0] = '.';
+ zDirname[1] = 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));
+ if( fd>=0 ) return SQLITE_OK;
+ return unixLogError(SQLITE_CANTOPEN_BKPT, "openDirectory", zDirname);
}
/*
@@ -26290,12 +30576,12 @@ static int unixSync(sqlite3_file *id, int flags){
rc = full_fsync(pFile->h, isFullsync, isDataOnly);
SimulateIOError( rc=1 );
if( rc ){
- pFile->lastErrno = errno;
+ storeLastErrno(pFile, 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)
+ ** is set. This is a one-time occurrence. Many systems (examples: AIX)
** are unable to fsync a directory, so ignore errors on the fsync.
*/
if( pFile->ctrlFlags & UNIXFILE_DIRSYNC ){
@@ -26303,10 +30589,11 @@ static int unixSync(sqlite3_file *id, int flags){
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 ){
+ if( rc==SQLITE_OK ){
full_fsync(dirfd, 0, 0);
robust_close(pFile, dirfd, __LINE__);
- }else if( rc==SQLITE_CANTOPEN ){
+ }else{
+ assert( rc==SQLITE_CANTOPEN );
rc = SQLITE_OK;
}
pFile->ctrlFlags &= ~UNIXFILE_DIRSYNC;
@@ -26332,9 +30619,9 @@ static int unixTruncate(sqlite3_file *id, i64 nByte){
nByte = ((nByte + pFile->szChunk - 1)/pFile->szChunk) * pFile->szChunk;
}
- rc = robust_ftruncate(pFile->h, (off_t)nByte);
+ rc = robust_ftruncate(pFile->h, nByte);
if( rc ){
- pFile->lastErrno = errno;
+ storeLastErrno(pFile, errno);
return unixLogError(SQLITE_IOERR_TRUNCATE, "ftruncate", pFile->zPath);
}else{
#ifdef SQLITE_DEBUG
@@ -26350,6 +30637,16 @@ static int unixTruncate(sqlite3_file *id, i64 nByte){
}
#endif
+#if SQLITE_MAX_MMAP_SIZE>0
+ /* If the file was just truncated to a size smaller than the currently
+ ** mapped region, reduce the effective mapping size as well. SQLite will
+ ** use read() and write() to access data beyond this point from now on.
+ */
+ if( nByte<pFile->mmapSize ){
+ pFile->mmapSize = nByte;
+ }
+#endif
+
return SQLITE_OK;
}
}
@@ -26364,7 +30661,7 @@ static int unixFileSize(sqlite3_file *id, i64 *pSize){
rc = osFstat(((unixFile*)id)->h, &buf);
SimulateIOError( rc=1 );
if( rc!=0 ){
- ((unixFile*)id)->lastErrno = errno;
+ storeLastErrno((unixFile*)id, errno);
return SQLITE_IOERR_FSTAT;
}
*pSize = buf.st_size;
@@ -26400,7 +30697,9 @@ static int fcntlSizeHint(unixFile *pFile, i64 nByte){
i64 nSize; /* Required file size */
struct stat buf; /* Used to hold return values of fstat() */
- if( osFstat(pFile->h, &buf) ) return SQLITE_IOERR_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 ){
@@ -26415,34 +30714,49 @@ static int fcntlSizeHint(unixFile *pFile, i64 nByte){
}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.
+ /* If the OS does not have posix_fallocate(), fake it. Write a
+ ** single byte to the last byte in each block that falls entirely
+ ** within the extended region. Then, if required, a single byte
+ ** at offset (nSize-1), to set the size of the file correctly.
+ ** This is a similar technique to that used by glibc on systems
+ ** that do not have a real fallocate() call.
*/
int nBlk = buf.st_blksize; /* File-system block size */
+ int nWrite = 0; /* Number of bytes written by seekAndWrite */
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);
+ iWrite = (buf.st_size/nBlk)*nBlk + nBlk - 1;
+ assert( iWrite>=buf.st_size );
+ assert( ((iWrite+1)%nBlk)==0 );
+ for(/*no-op*/; iWrite<nSize+nBlk-1; iWrite+=nBlk ){
+ if( iWrite>=nSize ) iWrite = nSize - 1;
+ nWrite = seekAndWrite(pFile, iWrite, "", 1);
if( nWrite!=1 ) return SQLITE_IOERR_WRITE;
- iWrite += nBlk;
}
#endif
}
}
+#if SQLITE_MAX_MMAP_SIZE>0
+ if( pFile->mmapSizeMax>0 && nByte>pFile->mmapSize ){
+ int rc;
+ if( pFile->szChunk<=0 ){
+ if( robust_ftruncate(pFile->h, nByte) ){
+ storeLastErrno(pFile, errno);
+ return unixLogError(SQLITE_IOERR_TRUNCATE, "ftruncate", pFile->zPath);
+ }
+ }
+
+ rc = unixMapfile(pFile, nByte);
+ return rc;
+ }
+#endif
+
return SQLITE_OK;
}
/*
-** If *pArg is inititially negative then this is a query. Set *pArg to
+** If *pArg is initially 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.
@@ -26470,7 +30784,7 @@ static int unixFileControl(sqlite3_file *id, int op, void *pArg){
*(int*)pArg = pFile->eFileLock;
return SQLITE_OK;
}
- case SQLITE_LAST_ERRNO: {
+ case SQLITE_FCNTL_LAST_ERRNO: {
*(int*)pArg = pFile->lastErrno;
return SQLITE_OK;
}
@@ -26498,13 +30812,35 @@ static int unixFileControl(sqlite3_file *id, int op, void *pArg){
return SQLITE_OK;
}
case SQLITE_FCNTL_TEMPFILENAME: {
- char *zTFile = sqlite3_malloc( pFile->pVfs->mxPathname );
+ char *zTFile = sqlite3_malloc64( pFile->pVfs->mxPathname );
if( zTFile ){
unixGetTempname(pFile->pVfs->mxPathname, zTFile);
*(char**)pArg = zTFile;
}
return SQLITE_OK;
}
+ case SQLITE_FCNTL_HAS_MOVED: {
+ *(int*)pArg = fileHasMoved(pFile);
+ return SQLITE_OK;
+ }
+#if SQLITE_MAX_MMAP_SIZE>0
+ case SQLITE_FCNTL_MMAP_SIZE: {
+ i64 newLimit = *(i64*)pArg;
+ int rc = SQLITE_OK;
+ if( newLimit>sqlite3GlobalConfig.mxMmap ){
+ newLimit = sqlite3GlobalConfig.mxMmap;
+ }
+ *(i64*)pArg = pFile->mmapSizeMax;
+ if( newLimit>=0 && newLimit!=pFile->mmapSizeMax && pFile->nFetchOut==0 ){
+ pFile->mmapSizeMax = newLimit;
+ if( pFile->mmapSize>0 ){
+ unixUnmapfile(pFile);
+ rc = unixMapfile(pFile, -1);
+ }
+ }
+ return rc;
+ }
+#endif
#ifdef SQLITE_DEBUG
/* The pager calls this method to signal that it has done
** a rollback and that the database is therefore unchanged and
@@ -26517,8 +30853,8 @@ static int unixFileControl(sqlite3_file *id, int op, void *pArg){
}
#endif
#if SQLITE_ENABLE_LOCKING_STYLE && defined(__APPLE__)
- case SQLITE_SET_LOCKPROXYFILE:
- case SQLITE_GET_LOCKPROXYFILE: {
+ case SQLITE_FCNTL_SET_LOCKPROXYFILE:
+ case SQLITE_FCNTL_GET_LOCKPROXYFILE: {
return proxyFileControl(id,op,pArg);
}
#endif /* SQLITE_ENABLE_LOCKING_STYLE && defined(__APPLE__) */
@@ -26627,7 +30963,7 @@ static int unixSectorSize(sqlite3_file *id){
** 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
+** However, that choice is controversial 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,
@@ -26649,8 +30985,27 @@ static int unixDeviceCharacteristics(sqlite3_file *id){
return rc;
}
-#ifndef SQLITE_OMIT_WAL
+#if !defined(SQLITE_OMIT_WAL) || SQLITE_MAX_MMAP_SIZE>0
+/*
+** Return the system page size.
+**
+** This function should not be called directly by other code in this file.
+** Instead, it should be called via macro osGetpagesize().
+*/
+static int unixGetpagesize(void){
+#if OS_VXWORKS
+ return 1024;
+#elif defined(_BSD_SOURCE)
+ return getpagesize();
+#else
+ return (int)sysconf(_SC_PAGESIZE);
+#endif
+}
+
+#endif /* !defined(SQLITE_OMIT_WAL) || SQLITE_MAX_MMAP_SIZE>0 */
+
+#ifndef SQLITE_OMIT_WAL
/*
** Object used to represent an shared memory buffer.
@@ -26734,22 +31089,24 @@ struct unixShm {
** otherwise.
*/
static int unixShmSystemLock(
- unixShmNode *pShmNode, /* Apply locks to this open shared-memory segment */
+ unixFile *pFile, /* Open connection to the WAL file */
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() */
+ unixShmNode *pShmNode; /* Apply locks to this open shared-memory segment */
+ 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 */
+ pShmNode = pFile->pInode->pShmNode;
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 );
+ assert( n>=1 && n<=SQLITE_SHM_NLOCK );
if( pShmNode->h>=0 ){
/* Initialize the locking parameters */
@@ -26767,7 +31124,7 @@ static int unixShmSystemLock(
#ifdef SQLITE_DEBUG
{ u16 mask;
OSTRACE(("SHM-LOCK "));
- mask = (1<<(ofst+n)) - (1<<ofst);
+ mask = ofst>31 ? 0xffff : (1<<(ofst+n)) - (1<<ofst);
if( rc==SQLITE_OK ){
if( lockType==F_UNLCK ){
OSTRACE(("unlock %d ok", ofst));
@@ -26801,6 +31158,22 @@ static int unixShmSystemLock(
return rc;
}
+/*
+** Return the minimum number of 32KB shm regions that should be mapped at
+** a time, assuming that each mapping must be an integer multiple of the
+** current system page-size.
+**
+** Usually, this is 1. The exception seems to be systems that are configured
+** to use 64KB pages - in this case each mapping must cover at least two
+** shm regions.
+*/
+static int unixShmRegionPerMap(void){
+ int shmsz = 32*1024; /* SHM region size */
+ int pgsz = osGetpagesize(); /* System page size */
+ assert( ((pgsz-1)&pgsz)==0 ); /* Page size must be a power of 2 */
+ if( pgsz<shmsz ) return 1;
+ return pgsz/shmsz;
+}
/*
** Purge the unixShmNodeList list of all entries with unixShmNode.nRef==0.
@@ -26811,13 +31184,14 @@ static int unixShmSystemLock(
static void unixShmPurge(unixFile *pFd){
unixShmNode *p = pFd->pInode->pShmNode;
assert( unixMutexHeld() );
- if( p && p->nRef==0 ){
+ if( p && ALWAYS(p->nRef==0) ){
+ int nShmPerMap = unixShmRegionPerMap();
int i;
assert( p->pInode==pFd->pInode );
sqlite3_mutex_free(p->mutex);
- for(i=0; i<p->nRegion; i++){
+ for(i=0; i<p->nRegion; i+=nShmPerMap){
if( p->h>=0 ){
- munmap(p->apRegion[i], p->szRegion);
+ osMunmap(p->apRegion[i], p->szRegion);
}else{
sqlite3_free(p->apRegion[i]);
}
@@ -26876,7 +31250,7 @@ static int unixOpenSharedMemory(unixFile *pDbFd){
int nShmFilename; /* Size of the SHM filename in bytes */
/* Allocate space for the new unixShm object. */
- p = sqlite3_malloc( sizeof(*p) );
+ p = sqlite3_malloc64( sizeof(*p) );
if( p==0 ) return SQLITE_NOMEM;
memset(p, 0, sizeof(*p));
assert( pDbFd->pShm==0 );
@@ -26889,12 +31263,15 @@ static int unixOpenSharedMemory(unixFile *pDbFd){
pShmNode = pInode->pShmNode;
if( pShmNode==0 ){
struct stat sStat; /* fstat() info for database file */
+#ifndef SQLITE_SHM_DIRECTORY
+ const char *zBasePath = pDbFd->zPath;
+#endif
/* 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 ){
+ if( osFstat(pDbFd->h, &sStat) ){
rc = SQLITE_IOERR_FSTAT;
goto shm_open_err;
}
@@ -26902,9 +31279,9 @@ static int unixOpenSharedMemory(unixFile *pDbFd){
#ifdef SQLITE_SHM_DIRECTORY
nShmFilename = sizeof(SQLITE_SHM_DIRECTORY) + 31;
#else
- nShmFilename = 6 + (int)strlen(pDbFd->zPath);
+ nShmFilename = 6 + (int)strlen(zBasePath);
#endif
- pShmNode = sqlite3_malloc( sizeof(*pShmNode) + nShmFilename );
+ pShmNode = sqlite3_malloc64( sizeof(*pShmNode) + nShmFilename );
if( pShmNode==0 ){
rc = SQLITE_NOMEM;
goto shm_open_err;
@@ -26916,7 +31293,7 @@ static int unixOpenSharedMemory(unixFile *pDbFd){
SQLITE_SHM_DIRECTORY "/sqlite-shm-%x-%x",
(u32)sStat.st_ino, (u32)sStat.st_dev);
#else
- sqlite3_snprintf(nShmFilename, zShmFilename, "%s-shm", pDbFd->zPath);
+ sqlite3_snprintf(nShmFilename, zShmFilename, "%s-shm", zBasePath);
sqlite3FileSuffix3(pDbFd->zPath, zShmFilename);
#endif
pShmNode->h = -1;
@@ -26944,19 +31321,19 @@ static int unixOpenSharedMemory(unixFile *pDbFd){
** 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);
+ robustFchown(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( unixShmSystemLock(pDbFd, 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);
+ rc = unixShmSystemLock(pDbFd, F_RDLCK, UNIX_SHM_DMS, 1);
}
if( rc ) goto shm_open_err;
}
@@ -27022,6 +31399,8 @@ static int unixShmMap(
unixShm *p;
unixShmNode *pShmNode;
int rc = SQLITE_OK;
+ int nShmPerMap = unixShmRegionPerMap();
+ int nReqRegion;
/* If the shared-memory file has not yet been opened, open it now. */
if( pDbFd->pShm==0 ){
@@ -27037,9 +31416,12 @@ static int unixShmMap(
assert( pShmNode->h>=0 || pDbFd->pInode->bProcessLock==1 );
assert( pShmNode->h<0 || pDbFd->pInode->bProcessLock==0 );
- if( pShmNode->nRegion<=iRegion ){
+ /* Minimum number of regions required to be mapped. */
+ nReqRegion = ((iRegion+nShmPerMap) / nShmPerMap) * nShmPerMap;
+
+ if( pShmNode->nRegion<nReqRegion ){
char **apNew; /* New apRegion[] array */
- int nByte = (iRegion+1)*szRegion; /* Minimum required file size */
+ int nByte = nReqRegion*szRegion; /* Minimum required file size */
struct stat sStat; /* Used by fstat() */
pShmNode->szRegion = szRegion;
@@ -27057,40 +31439,51 @@ static int unixShmMap(
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);
+ if( !bExtend ){
goto shmpage_out;
}
-#else
- if( robust_ftruncate(pShmNode->h, nByte) ){
- rc = unixLogError(SQLITE_IOERR_SHMSIZE, "ftruncate",
- pShmNode->zFilename);
- goto shmpage_out;
+
+ /* Alternatively, if bExtend is true, extend the file. Do this by
+ ** writing a single byte to the end of each (OS) page being
+ ** allocated or extended. Technically, we need only write to the
+ ** last page in order to extend the file. But writing to all new
+ ** pages forces the OS to allocate them immediately, which reduces
+ ** the chances of SIGBUS while accessing the mapped region later on.
+ */
+ else{
+ static const int pgsz = 4096;
+ int iPg;
+
+ /* Write to the last byte of each newly allocated or extended page */
+ assert( (nByte % pgsz)==0 );
+ for(iPg=(sStat.st_size/pgsz); iPg<(nByte/pgsz); iPg++){
+ int x = 0;
+ if( seekAndWriteFd(pShmNode->h, iPg*pgsz + pgsz-1, "", 1, &x)!=1 ){
+ const char *zFile = pShmNode->zFilename;
+ rc = unixLogError(SQLITE_IOERR_SHMSIZE, "write", zFile);
+ goto shmpage_out;
+ }
+ }
}
-#endif
}
}
/* Map the requested memory region into this processes address space. */
apNew = (char **)sqlite3_realloc(
- pShmNode->apRegion, (iRegion+1)*sizeof(char *)
+ pShmNode->apRegion, nReqRegion*sizeof(char *)
);
if( !apNew ){
rc = SQLITE_IOERR_NOMEM;
goto shmpage_out;
}
pShmNode->apRegion = apNew;
- while(pShmNode->nRegion<=iRegion){
+ while( pShmNode->nRegion<nReqRegion ){
+ int nMap = szRegion*nShmPerMap;
+ int i;
void *pMem;
if( pShmNode->h>=0 ){
- pMem = mmap(0, szRegion,
+ pMem = osMmap(0, nMap,
pShmNode->isReadonly ? PROT_READ : PROT_READ|PROT_WRITE,
MAP_SHARED, pShmNode->h, szRegion*(i64)pShmNode->nRegion
);
@@ -27099,15 +31492,18 @@ static int unixShmMap(
goto shmpage_out;
}
}else{
- pMem = sqlite3_malloc(szRegion);
+ pMem = sqlite3_malloc64(szRegion);
if( pMem==0 ){
rc = SQLITE_NOMEM;
goto shmpage_out;
}
memset(pMem, 0, szRegion);
}
- pShmNode->apRegion[pShmNode->nRegion] = pMem;
- pShmNode->nRegion++;
+
+ for(i=0; i<nShmPerMap; i++){
+ pShmNode->apRegion[pShmNode->nRegion+i] = &((char*)pMem)[szRegion*i];
+ }
+ pShmNode->nRegion += nShmPerMap;
}
}
@@ -27170,7 +31566,7 @@ static int unixShmLock(
/* Unlock the system-level locks */
if( (mask & allMask)==0 ){
- rc = unixShmSystemLock(pShmNode, F_UNLCK, ofst+UNIX_SHM_BASE, n);
+ rc = unixShmSystemLock(pDbFd, F_UNLCK, ofst+UNIX_SHM_BASE, n);
}else{
rc = SQLITE_OK;
}
@@ -27198,7 +31594,7 @@ static int unixShmLock(
/* 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);
+ rc = unixShmSystemLock(pDbFd, F_RDLCK, ofst+UNIX_SHM_BASE, n);
}else{
rc = SQLITE_OK;
}
@@ -27223,7 +31619,7 @@ static int unixShmLock(
** also mark the local connection as being locked.
*/
if( rc==SQLITE_OK ){
- rc = unixShmSystemLock(pShmNode, F_WRLCK, ofst+UNIX_SHM_BASE, n);
+ rc = unixShmSystemLock(pDbFd, F_WRLCK, ofst+UNIX_SHM_BASE, n);
if( rc==SQLITE_OK ){
assert( (p->sharedMask & mask)==0 );
p->exclMask |= mask;
@@ -27232,7 +31628,7 @@ static int unixShmLock(
}
sqlite3_mutex_leave(pShmNode->mutex);
OSTRACE(("SHM-LOCK shmid-%d, pid-%d got %03x,%03x\n",
- p->id, getpid(), p->sharedMask, p->exclMask));
+ p->id, osGetpid(0), p->sharedMask, p->exclMask));
return rc;
}
@@ -27246,7 +31642,8 @@ static void unixShmBarrier(
sqlite3_file *fd /* Database file holding the shared memory */
){
UNUSED_PARAMETER(fd);
- unixEnterMutex();
+ sqlite3MemoryBarrier(); /* compiler-defined memory barrier */
+ unixEnterMutex(); /* Also mutex, for redundancy */
unixLeaveMutex();
}
@@ -27291,7 +31688,9 @@ static int unixShmUnmap(
assert( pShmNode->nRef>0 );
pShmNode->nRef--;
if( pShmNode->nRef==0 ){
- if( deleteFlag && pShmNode->h>=0 ) osUnlink(pShmNode->zFilename);
+ if( deleteFlag && pShmNode->h>=0 ){
+ osUnlink(pShmNode->zFilename);
+ }
unixShmPurge(pDbFd);
}
unixLeaveMutex();
@@ -27307,6 +31706,223 @@ static int unixShmUnmap(
# define unixShmUnmap 0
#endif /* #ifndef SQLITE_OMIT_WAL */
+#if SQLITE_MAX_MMAP_SIZE>0
+/*
+** If it is currently memory mapped, unmap file pFd.
+*/
+static void unixUnmapfile(unixFile *pFd){
+ assert( pFd->nFetchOut==0 );
+ if( pFd->pMapRegion ){
+ osMunmap(pFd->pMapRegion, pFd->mmapSizeActual);
+ pFd->pMapRegion = 0;
+ pFd->mmapSize = 0;
+ pFd->mmapSizeActual = 0;
+ }
+}
+
+/*
+** Attempt to set the size of the memory mapping maintained by file
+** descriptor pFd to nNew bytes. Any existing mapping is discarded.
+**
+** If successful, this function sets the following variables:
+**
+** unixFile.pMapRegion
+** unixFile.mmapSize
+** unixFile.mmapSizeActual
+**
+** If unsuccessful, an error message is logged via sqlite3_log() and
+** the three variables above are zeroed. In this case SQLite should
+** continue accessing the database using the xRead() and xWrite()
+** methods.
+*/
+static void unixRemapfile(
+ unixFile *pFd, /* File descriptor object */
+ i64 nNew /* Required mapping size */
+){
+ const char *zErr = "mmap";
+ int h = pFd->h; /* File descriptor open on db file */
+ u8 *pOrig = (u8 *)pFd->pMapRegion; /* Pointer to current file mapping */
+ i64 nOrig = pFd->mmapSizeActual; /* Size of pOrig region in bytes */
+ u8 *pNew = 0; /* Location of new mapping */
+ int flags = PROT_READ; /* Flags to pass to mmap() */
+
+ assert( pFd->nFetchOut==0 );
+ assert( nNew>pFd->mmapSize );
+ assert( nNew<=pFd->mmapSizeMax );
+ assert( nNew>0 );
+ assert( pFd->mmapSizeActual>=pFd->mmapSize );
+ assert( MAP_FAILED!=0 );
+
+#ifdef SQLITE_MMAP_READWRITE
+ if( (pFd->ctrlFlags & UNIXFILE_RDONLY)==0 ) flags |= PROT_WRITE;
+#endif
+
+ if( pOrig ){
+#if HAVE_MREMAP
+ i64 nReuse = pFd->mmapSize;
+#else
+ const int szSyspage = osGetpagesize();
+ i64 nReuse = (pFd->mmapSize & ~(szSyspage-1));
+#endif
+ u8 *pReq = &pOrig[nReuse];
+
+ /* Unmap any pages of the existing mapping that cannot be reused. */
+ if( nReuse!=nOrig ){
+ osMunmap(pReq, nOrig-nReuse);
+ }
+
+#if HAVE_MREMAP
+ pNew = osMremap(pOrig, nReuse, nNew, MREMAP_MAYMOVE);
+ zErr = "mremap";
+#else
+ pNew = osMmap(pReq, nNew-nReuse, flags, MAP_SHARED, h, nReuse);
+ if( pNew!=MAP_FAILED ){
+ if( pNew!=pReq ){
+ osMunmap(pNew, nNew - nReuse);
+ pNew = 0;
+ }else{
+ pNew = pOrig;
+ }
+ }
+#endif
+
+ /* The attempt to extend the existing mapping failed. Free it. */
+ if( pNew==MAP_FAILED || pNew==0 ){
+ osMunmap(pOrig, nReuse);
+ }
+ }
+
+ /* If pNew is still NULL, try to create an entirely new mapping. */
+ if( pNew==0 ){
+ pNew = osMmap(0, nNew, flags, MAP_SHARED, h, 0);
+ }
+
+ if( pNew==MAP_FAILED ){
+ pNew = 0;
+ nNew = 0;
+ unixLogError(SQLITE_OK, zErr, pFd->zPath);
+
+ /* If the mmap() above failed, assume that all subsequent mmap() calls
+ ** will probably fail too. Fall back to using xRead/xWrite exclusively
+ ** in this case. */
+ pFd->mmapSizeMax = 0;
+ }
+ pFd->pMapRegion = (void *)pNew;
+ pFd->mmapSize = pFd->mmapSizeActual = nNew;
+}
+
+/*
+** Memory map or remap the file opened by file-descriptor pFd (if the file
+** is already mapped, the existing mapping is replaced by the new). Or, if
+** there already exists a mapping for this file, and there are still
+** outstanding xFetch() references to it, this function is a no-op.
+**
+** If parameter nByte is non-negative, then it is the requested size of
+** the mapping to create. Otherwise, if nByte is less than zero, then the
+** requested size is the size of the file on disk. The actual size of the
+** created mapping is either the requested size or the value configured
+** using SQLITE_FCNTL_MMAP_LIMIT, whichever is smaller.
+**
+** SQLITE_OK is returned if no error occurs (even if the mapping is not
+** recreated as a result of outstanding references) or an SQLite error
+** code otherwise.
+*/
+static int unixMapfile(unixFile *pFd, i64 nMap){
+ assert( nMap>=0 || pFd->nFetchOut==0 );
+ assert( nMap>0 || (pFd->mmapSize==0 && pFd->pMapRegion==0) );
+ if( pFd->nFetchOut>0 ) return SQLITE_OK;
+
+ if( nMap<0 ){
+ struct stat statbuf; /* Low-level file information */
+ if( osFstat(pFd->h, &statbuf) ){
+ return SQLITE_IOERR_FSTAT;
+ }
+ nMap = statbuf.st_size;
+ }
+ if( nMap>pFd->mmapSizeMax ){
+ nMap = pFd->mmapSizeMax;
+ }
+
+ assert( nMap>0 || (pFd->mmapSize==0 && pFd->pMapRegion==0) );
+ if( nMap!=pFd->mmapSize ){
+ unixRemapfile(pFd, nMap);
+ }
+
+ return SQLITE_OK;
+}
+#endif /* SQLITE_MAX_MMAP_SIZE>0 */
+
+/*
+** If possible, return a pointer to a mapping of file fd starting at offset
+** iOff. The mapping must be valid for at least nAmt bytes.
+**
+** If such a pointer can be obtained, store it in *pp and return SQLITE_OK.
+** Or, if one cannot but no error occurs, set *pp to 0 and return SQLITE_OK.
+** Finally, if an error does occur, return an SQLite error code. The final
+** value of *pp is undefined in this case.
+**
+** If this function does return a pointer, the caller must eventually
+** release the reference by calling unixUnfetch().
+*/
+static int unixFetch(sqlite3_file *fd, i64 iOff, int nAmt, void **pp){
+#if SQLITE_MAX_MMAP_SIZE>0
+ unixFile *pFd = (unixFile *)fd; /* The underlying database file */
+#endif
+ *pp = 0;
+
+#if SQLITE_MAX_MMAP_SIZE>0
+ if( pFd->mmapSizeMax>0 ){
+ if( pFd->pMapRegion==0 ){
+ int rc = unixMapfile(pFd, -1);
+ if( rc!=SQLITE_OK ) return rc;
+ }
+ if( pFd->mmapSize >= iOff+nAmt ){
+ *pp = &((u8 *)pFd->pMapRegion)[iOff];
+ pFd->nFetchOut++;
+ }
+ }
+#endif
+ return SQLITE_OK;
+}
+
+/*
+** If the third argument is non-NULL, then this function releases a
+** reference obtained by an earlier call to unixFetch(). The second
+** argument passed to this function must be the same as the corresponding
+** argument that was passed to the unixFetch() invocation.
+**
+** Or, if the third argument is NULL, then this function is being called
+** to inform the VFS layer that, according to POSIX, any existing mapping
+** may now be invalid and should be unmapped.
+*/
+static int unixUnfetch(sqlite3_file *fd, i64 iOff, void *p){
+#if SQLITE_MAX_MMAP_SIZE>0
+ unixFile *pFd = (unixFile *)fd; /* The underlying database file */
+ UNUSED_PARAMETER(iOff);
+
+ /* If p==0 (unmap the entire file) then there must be no outstanding
+ ** xFetch references. Or, if p!=0 (meaning it is an xFetch reference),
+ ** then there must be at least one outstanding. */
+ assert( (p==0)==(pFd->nFetchOut==0) );
+
+ /* If p!=0, it must match the iOff value. */
+ assert( p==0 || p==&((u8 *)pFd->pMapRegion)[iOff] );
+
+ if( p ){
+ pFd->nFetchOut--;
+ }else{
+ unixUnmapfile(pFd);
+ }
+
+ assert( pFd->nFetchOut>=0 );
+#else
+ UNUSED_PARAMETER(fd);
+ UNUSED_PARAMETER(p);
+ UNUSED_PARAMETER(iOff);
+#endif
+ return SQLITE_OK;
+}
+
/*
** Here ends the implementation of all sqlite3_file methods.
**
@@ -27326,7 +31942,7 @@ static int unixShmUnmap(
** looks at the filesystem type and tries to guess the best locking
** strategy from that.
**
-** For finder-funtion F, two objects are created:
+** For finder-function F, two objects are created:
**
** (1) The real finder-function named "FImpt()".
**
@@ -27347,7 +31963,7 @@ static int unixShmUnmap(
** * 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) \
+#define IOMETHODS(FINDER,METHOD,VERSION,CLOSE,LOCK,UNLOCK,CKLOCK,SHMMAP) \
static const sqlite3_io_methods METHOD = { \
VERSION, /* iVersion */ \
CLOSE, /* xClose */ \
@@ -27362,10 +31978,12 @@ static const sqlite3_io_methods METHOD = { \
unixFileControl, /* xFileControl */ \
unixSectorSize, /* xSectorSize */ \
unixDeviceCharacteristics, /* xDeviceCapabilities */ \
- unixShmMap, /* xShmMap */ \
+ SHMMAP, /* xShmMap */ \
unixShmLock, /* xShmLock */ \
unixShmBarrier, /* xShmBarrier */ \
- unixShmUnmap /* xShmUnmap */ \
+ unixShmUnmap, /* xShmUnmap */ \
+ unixFetch, /* xFetch */ \
+ unixUnfetch, /* xUnfetch */ \
}; \
static const sqlite3_io_methods *FINDER##Impl(const char *z, unixFile *p){ \
UNUSED_PARAMETER(z); UNUSED_PARAMETER(p); \
@@ -27382,20 +32000,22 @@ static const sqlite3_io_methods *(*const FINDER)(const char*,unixFile *p) \
IOMETHODS(
posixIoFinder, /* Finder function name */
posixIoMethods, /* sqlite3_io_methods object name */
- 2, /* shared memory is enabled */
+ 3, /* shared memory and mmap are enabled */
unixClose, /* xClose method */
unixLock, /* xLock method */
unixUnlock, /* xUnlock method */
- unixCheckReservedLock /* xCheckReservedLock method */
+ unixCheckReservedLock, /* xCheckReservedLock method */
+ unixShmMap /* xShmMap method */
)
IOMETHODS(
nolockIoFinder, /* Finder function name */
nolockIoMethods, /* sqlite3_io_methods object name */
- 1, /* shared memory is disabled */
+ 3, /* shared memory is disabled */
nolockClose, /* xClose method */
nolockLock, /* xLock method */
nolockUnlock, /* xUnlock method */
- nolockCheckReservedLock /* xCheckReservedLock method */
+ nolockCheckReservedLock, /* xCheckReservedLock method */
+ 0 /* xShmMap method */
)
IOMETHODS(
dotlockIoFinder, /* Finder function name */
@@ -27404,10 +32024,11 @@ IOMETHODS(
dotlockClose, /* xClose method */
dotlockLock, /* xLock method */
dotlockUnlock, /* xUnlock method */
- dotlockCheckReservedLock /* xCheckReservedLock method */
+ dotlockCheckReservedLock, /* xCheckReservedLock method */
+ 0 /* xShmMap method */
)
-#if SQLITE_ENABLE_LOCKING_STYLE && !OS_VXWORKS
+#if SQLITE_ENABLE_LOCKING_STYLE
IOMETHODS(
flockIoFinder, /* Finder function name */
flockIoMethods, /* sqlite3_io_methods object name */
@@ -27415,7 +32036,8 @@ IOMETHODS(
flockClose, /* xClose method */
flockLock, /* xLock method */
flockUnlock, /* xUnlock method */
- flockCheckReservedLock /* xCheckReservedLock method */
+ flockCheckReservedLock, /* xCheckReservedLock method */
+ 0 /* xShmMap method */
)
#endif
@@ -27424,10 +32046,11 @@ 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 */
+ semXClose, /* xClose method */
+ semXLock, /* xLock method */
+ semXUnlock, /* xUnlock method */
+ semXCheckReservedLock, /* xCheckReservedLock method */
+ 0 /* xShmMap method */
)
#endif
@@ -27439,7 +32062,8 @@ IOMETHODS(
afpClose, /* xClose method */
afpLock, /* xLock method */
afpUnlock, /* xUnlock method */
- afpCheckReservedLock /* xCheckReservedLock method */
+ afpCheckReservedLock, /* xCheckReservedLock method */
+ 0 /* xShmMap method */
)
#endif
@@ -27464,7 +32088,8 @@ IOMETHODS(
proxyClose, /* xClose method */
proxyLock, /* xLock method */
proxyUnlock, /* xUnlock method */
- proxyCheckReservedLock /* xCheckReservedLock method */
+ proxyCheckReservedLock, /* xCheckReservedLock method */
+ 0 /* xShmMap method */
)
#endif
@@ -27477,7 +32102,8 @@ IOMETHODS(
unixClose, /* xClose method */
unixLock, /* xLock method */
nfsUnlock, /* xUnlock method */
- unixCheckReservedLock /* xCheckReservedLock method */
+ unixCheckReservedLock, /* xCheckReservedLock method */
+ 0 /* xShmMap method */
)
#endif
@@ -27547,15 +32173,13 @@ static const sqlite3_io_methods
#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.
+#if OS_VXWORKS
+/*
+** This "finder" function for VxWorks checks to see if posix advisory
+** locking works. If it does, then that is what is used. If it does not
+** work, then fallback to named semaphore locking.
*/
-static const sqlite3_io_methods *autolockIoFinderImpl(
+static const sqlite3_io_methods *vxworksIoFinderImpl(
const char *filePath, /* name of the database file */
unixFile *pNew /* the open file object */
){
@@ -27581,12 +32205,12 @@ static const sqlite3_io_methods *autolockIoFinderImpl(
}
}
static const sqlite3_io_methods
- *(*const autolockIoFinder)(const char*,unixFile*) = autolockIoFinderImpl;
+ *(*const vxworksIoFinder)(const char*,unixFile*) = vxworksIoFinderImpl;
-#endif /* OS_VXWORKS && SQLITE_ENABLE_LOCKING_STYLE */
+#endif /* OS_VXWORKS */
/*
-** An abstract type for a pointer to a IO method finder function:
+** An abstract type for a pointer to an IO method finder function:
*/
typedef const sqlite3_io_methods *(*finder_type)(const char*,unixFile*);
@@ -27633,11 +32257,14 @@ static int fillInUnixFile(
pNew->pVfs = pVfs;
pNew->zPath = zFilename;
pNew->ctrlFlags = (u8)ctrlFlags;
+#if SQLITE_MAX_MMAP_SIZE>0
+ pNew->mmapSizeMax = sqlite3GlobalConfig.szMmap;
+#endif
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 ){
+ if( strcmp(pVfs->zName,"unix-excl")==0 ){
pNew->ctrlFlags |= UNIXFILE_EXCL;
}
@@ -27669,7 +32296,7 @@ static int fillInUnixFile(
unixEnterMutex();
rc = findInodeInfo(pNew, &pNew->pInode);
if( rc!=SQLITE_OK ){
- /* If an error occured in findInodeInfo(), close the file descriptor
+ /* If an error occurred in findInodeInfo(), close the file descriptor
** immediately, before releasing the mutex. findInodeInfo() may fail
** in two scenarios:
**
@@ -27699,7 +32326,7 @@ static int fillInUnixFile(
** the afpLockingContext.
*/
afpLockingContext *pCtx;
- pNew->lockingContext = pCtx = sqlite3_malloc( sizeof(*pCtx) );
+ pNew->lockingContext = pCtx = sqlite3_malloc64( sizeof(*pCtx) );
if( pCtx==0 ){
rc = SQLITE_NOMEM;
}else{
@@ -27729,7 +32356,7 @@ static int fillInUnixFile(
int nFilename;
assert( zFilename!=0 );
nFilename = (int)strlen(zFilename) + 6;
- zLockFile = (char *)sqlite3_malloc(nFilename);
+ zLockFile = (char *)sqlite3_malloc64(nFilename);
if( zLockFile==0 ){
rc = SQLITE_NOMEM;
}else{
@@ -27762,21 +32389,21 @@ static int fillInUnixFile(
}
#endif
- pNew->lastErrno = 0;
+ storeLastErrno(pNew, 0);
#if OS_VXWORKS
if( rc!=SQLITE_OK ){
if( h>=0 ) robust_close(pNew, h, __LINE__);
h = -1;
osUnlink(zFilename);
- isDelete = 0;
+ pNew->ctrlFlags |= UNIXFILE_DELETE;
}
- 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);
+ verifyDbFile(pNew);
}
return rc;
}
@@ -27792,13 +32419,13 @@ static const char *unixTempFileDir(void){
"/var/tmp",
"/usr/tmp",
"/tmp",
- 0 /* List terminator */
+ "."
};
unsigned int i;
struct stat buf;
- const char *zDir = 0;
+ const char *zDir = sqlite3_temp_directory;
- azDirs[0] = sqlite3_temp_directory;
+ if( !azDirs[0] ) azDirs[0] = getenv("SQLITE_TMPDIR");
if( !azDirs[1] ) azDirs[1] = getenv("TMPDIR");
for(i=0; i<sizeof(azDirs)/sizeof(azDirs[0]); zDir=azDirs[i++]){
if( zDir==0 ) continue;
@@ -27816,12 +32443,8 @@ static const char *unixTempFileDir(void){
** 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;
+ int iLimit = 0;
/* 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
@@ -27830,24 +32453,14 @@ static int unixGetTempname(int nBuf, char *zBuf){
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;
+ u64 r;
+ sqlite3_randomness(sizeof(r), &r);
+ assert( nBuf>2 );
+ zBuf[nBuf-2] = 0;
+ sqlite3_snprintf(nBuf, zBuf, "%s/"SQLITE_TEMP_FILE_PREFIX"%llx%c",
+ zDir, r, 0);
+ if( zBuf[nBuf-2]!=0 || (iLimit++)>10 ) return SQLITE_ERROR;
}while( osAccess(zBuf,0)==0 );
return SQLITE_OK;
}
@@ -27895,7 +32508,7 @@ static UnixUnusedFd *findReusableFd(const char *zPath, int flags){
** 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. */
+ ** not searching for a reusable file descriptor are not dire. */
if( 0==osStat(zPath, &sStat) ){
unixInodeInfo *pInode;
@@ -27926,7 +32539,7 @@ static UnixUnusedFd *findReusableFd(const char *zPath, int flags){
** 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
+** In most 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
@@ -27969,16 +32582,19 @@ static int findCreateFileMode(
** 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]!='-' ){
+#ifndef SQLITE_ENABLE_8_3_NAMES
+ /* In the normal case (8+3 filenames disabled) the journal filename
+ ** is guaranteed to contain a '-' character. */
assert( nDb>0 );
- assert( zPath[nDb]!='\n' );
+ assert( sqlite3Isalnum(zPath[nDb]) );
+#else
+ /* If 8+3 names are possible, then the journal file might not contain
+ ** a '-' character. So check for that case and return early. */
+ if( nDb==0 || zPath[nDb]=='.' ) return SQLITE_OK;
+#endif
nDb--;
}
-#endif
memcpy(zDb, zPath, nDb);
zDb[nDb] = '\0';
@@ -28086,6 +32702,16 @@ static int unixOpen(
|| eType==SQLITE_OPEN_TRANSIENT_DB || eType==SQLITE_OPEN_WAL
);
+ /* Detect a pid change and reset the PRNG. There is a race condition
+ ** here such that two or more threads all trying to open databases at
+ ** the same instant might all reset the PRNG. But multiple resets
+ ** are harmless.
+ */
+ if( randomnessPid!=osGetpid(0) ){
+ randomnessPid = osGetpid(0);
+ sqlite3_randomness(0,0);
+ }
+
memset(p, 0, sizeof(unixFile));
if( eType==SQLITE_OPEN_MAIN_DB ){
@@ -28094,7 +32720,7 @@ static int unixOpen(
if( pUnused ){
fd = pUnused->fd;
}else{
- pUnused = sqlite3_malloc(sizeof(*pUnused));
+ pUnused = sqlite3_malloc64(sizeof(*pUnused));
if( !pUnused ){
return SQLITE_NOMEM;
}
@@ -28109,7 +32735,7 @@ static int unixOpen(
}else if( !zName ){
/* If zName is NULL, the upper layer is requesting a temp file. */
assert(isDelete && !syncDir);
- rc = unixGetTempname(MAX_PATHNAME+2, zTmpname);
+ rc = unixGetTempname(pVfs->mxPathname, zTmpname);
if( rc!=SQLITE_OK ){
return rc;
}
@@ -28142,7 +32768,8 @@ static int unixOpen(
}
fd = robust_open(zName, openFlags, openMode);
OSTRACE(("OPENX %-3d %s 0%o\n", fd, zName, openFlags));
- if( fd<0 && errno!=EISDIR && isReadWrite && !isExclusive ){
+ assert( !isExclusive || (openFlags & O_CREAT)!=0 );
+ if( fd<0 && errno!=EISDIR && isReadWrite ){
/* Failed to open the file for read/write access. Try read-only. */
flags &= ~(SQLITE_OPEN_READWRITE|SQLITE_OPEN_CREATE);
openFlags &= ~(O_RDWR|O_CREAT);
@@ -28161,7 +32788,7 @@ static int unixOpen(
** the same as the original database.
*/
if( flags & (SQLITE_OPEN_WAL|SQLITE_OPEN_MAIN_JOURNAL) ){
- osFchown(fd, uid, gid);
+ robustFchown(fd, uid, gid);
}
}
assert( fd>=0 );
@@ -28177,6 +32804,12 @@ static int unixOpen(
if( isDelete ){
#if OS_VXWORKS
zPath = zName;
+#elif defined(SQLITE_UNLINK_AFTER_CLOSE)
+ zPath = sqlite3_mprintf("%s", zName);
+ if( zPath==0 ){
+ robust_close(p, fd, __LINE__);
+ return SQLITE_NOMEM;
+ }
#else
osUnlink(zName);
#endif
@@ -28192,13 +32825,16 @@ static int unixOpen(
#if defined(__APPLE__) || SQLITE_ENABLE_LOCKING_STYLE
if( fstatfs(fd, &fsInfo) == -1 ){
- ((unixFile*)pFile)->lastErrno = errno;
+ storeLastErrno(p, 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;
}
+ if (0 == strncmp("exfat", fsInfo.f_fstypename, 5)) {
+ ((unixFile*)pFile)->fsFlags |= SQLITE_FSFLAGS_IS_MSDOS;
+ }
#endif
/* Set up appropriate ctrlFlags */
@@ -28221,19 +32857,6 @@ static int unixOpen(
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 ){
@@ -28277,7 +32900,11 @@ static int unixDelete(
UNUSED_PARAMETER(NotUsed);
SimulateIOError(return SQLITE_IOERR_DELETE);
if( osUnlink(zPath)==(-1) ){
- if( errno==ENOENT ){
+ if( errno==ENOENT
+#if OS_VXWORKS
+ || osAccess(zPath,0)!=0
+#endif
+ ){
rc = SQLITE_IOERR_DELETE_NOENT;
}else{
rc = unixLogError(SQLITE_IOERR_DELETE, "unlink", zPath);
@@ -28298,7 +32925,8 @@ static int unixDelete(
rc = unixLogError(SQLITE_IOERR_DIR_FSYNC, "fsync", zPath);
}
robust_close(0, fd, __LINE__);
- }else if( rc==SQLITE_CANTOPEN ){
+ }else{
+ assert( rc==SQLITE_CANTOPEN );
rc = SQLITE_OK;
}
}
@@ -28307,7 +32935,7 @@ static int unixDelete(
}
/*
-** Test the existance of or access permissions of file zPath. The
+** Test the existence 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
@@ -28322,29 +32950,19 @@ static int unixAccess(
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;
+ assert( pResOut!=0 );
- default:
- assert(!"Invalid flags argument");
- }
- *pResOut = (osAccess(zPath, amode)==0);
- if( flags==SQLITE_ACCESS_EXISTS && *pResOut ){
+ /* The spec says there are three possible values for flags. But only
+ ** two of them are actually used */
+ assert( flags==SQLITE_ACCESS_EXISTS || flags==SQLITE_ACCESS_READWRITE );
+
+ if( flags==SQLITE_ACCESS_EXISTS ){
struct stat buf;
- if( 0==osStat(zPath, &buf) && buf.st_size==0 ){
- *pResOut = 0;
- }
+ *pResOut = (0==osStat(zPath, &buf) && buf.st_size>0);
+ }else{
+ *pResOut = osAccess(zPath, W_OK|R_OK)==0;
}
return SQLITE_OK;
}
@@ -28365,6 +32983,7 @@ static int unixFullPathname(
int nOut, /* Size of output buffer in bytes */
char *zOut /* Output buffer */
){
+ int nByte;
/* 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
@@ -28376,17 +32995,54 @@ static int unixFullPathname(
assert( pVfs->mxPathname==MAX_PATHNAME );
UNUSED_PARAMETER(pVfs);
- zOut[nOut-1] = '\0';
- if( zPath[0]=='/' ){
+ /* Attempt to resolve the path as if it were a symbolic link. If it is
+ ** a symbolic link, the resolved path is stored in buffer zOut[]. Or, if
+ ** the identified file is not a symbolic link or does not exist, then
+ ** zPath is copied directly into zOut. Either way, nByte is left set to
+ ** the size of the string copied into zOut[] in bytes. */
+ nByte = osReadlink(zPath, zOut, nOut-1);
+ if( nByte<0 ){
+ if( errno!=EINVAL && errno!=ENOENT ){
+ return unixLogError(SQLITE_CANTOPEN_BKPT, "readlink", zPath);
+ }
sqlite3_snprintf(nOut, zOut, "%s", zPath);
+ nByte = sqlite3Strlen30(zOut);
}else{
+ zOut[nByte] = '\0';
+ }
+
+ /* If buffer zOut[] now contains an absolute path there is nothing more
+ ** to do. If it contains a relative path, do the following:
+ **
+ ** * move the relative path string so that it is at the end of th
+ ** zOut[] buffer.
+ ** * Call getcwd() to read the path of the current working directory
+ ** into the start of the zOut[] buffer.
+ ** * Append a '/' character to the cwd string and move the
+ ** relative path back within the buffer so that it immediately
+ ** follows the '/'.
+ **
+ ** This code is written so that if the combination of the CWD and relative
+ ** path are larger than the allocated size of zOut[] the CWD is silently
+ ** truncated to make it fit. This is Ok, as SQLite refuses to open any
+ ** file for which this function returns a full path larger than (nOut-8)
+ ** bytes in size. */
+ testcase( nByte==nOut-5 );
+ testcase( nByte==nOut-4 );
+ if( zOut[0]!='/' && nByte<nOut-4 ){
int nCwd;
- if( osGetcwd(zOut, nOut-1)==0 ){
+ int nRem = nOut-nByte-1;
+ memmove(&zOut[nRem], zOut, nByte+1);
+ zOut[nRem-1] = '\0';
+ if( osGetcwd(zOut, nRem-1)==0 ){
return unixLogError(SQLITE_CANTOPEN_BKPT, "getcwd", zPath);
}
- nCwd = (int)strlen(zOut);
- sqlite3_snprintf(nOut-nCwd, &zOut[nCwd], "/%s", zPath);
+ nCwd = sqlite3Strlen30(zOut);
+ assert( nCwd<=nRem-1 );
+ zOut[nCwd] = '/';
+ memmove(&zOut[nCwd+1], &zOut[nRem], nByte+1);
}
+
return SQLITE_OK;
}
@@ -28473,18 +33129,18 @@ static int unixRandomness(sqlite3_vfs *NotUsed, int nBuf, char *zBuf){
** tests repeatable.
*/
memset(zBuf, 0, nBuf);
-#if !defined(SQLITE_TEST)
+ randomnessPid = osGetpid(0);
+#if !defined(SQLITE_TEST) && !defined(SQLITE_OMIT_RANDOMNESS)
{
- int pid, fd, got;
+ int 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);
+ memcpy(&zBuf[sizeof(t)], &randomnessPid, sizeof(randomnessPid));
+ assert( sizeof(t)+sizeof(randomnessPid)<=(size_t)nBuf );
+ nBuf = sizeof(t) + sizeof(randomnessPid);
}else{
do{ got = osRead(fd, zBuf, nBuf); }while( got<0 && errno==EINTR );
robust_close(0, fd, __LINE__);
@@ -28556,11 +33212,8 @@ static int unixCurrentTimeInt64(sqlite3_vfs *NotUsed, sqlite3_int64 *piNow){
*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;
- }
+ (void)gettimeofday(&sNow, 0); /* Cannot fail given valid arguments */
+ *piNow = unixEpoch + 1000*(sqlite3_int64)sNow.tv_sec + sNow.tv_usec/1000;
#endif
#ifdef SQLITE_TEST
@@ -28572,6 +33225,7 @@ static int unixCurrentTimeInt64(sqlite3_vfs *NotUsed, sqlite3_int64 *piNow){
return rc;
}
+#if 0 /* Not used */
/*
** Find the current time (in Universal Coordinated Time). Write the
** current time and date as a Julian Day number into *prNow and
@@ -28585,7 +33239,11 @@ static int unixCurrentTime(sqlite3_vfs *NotUsed, double *prNow){
*prNow = i/86400000.0;
return rc;
}
+#else
+# define unixCurrentTime 0
+#endif
+#if 0 /* Not used */
/*
** We added the xGetLastError() method with the intention of providing
** better low-level error messages when operating-system problems come up
@@ -28599,6 +33257,9 @@ static int unixGetLastError(sqlite3_vfs *NotUsed, int NotUsed2, char *NotUsed3){
UNUSED_PARAMETER(NotUsed3);
return 0;
}
+#else
+# define unixGetLastError 0
+#endif
/*
@@ -28655,9 +33316,10 @@ static int unixGetLastError(sqlite3_vfs *NotUsed, int NotUsed2, char *NotUsed3){
**
** C APIs
**
-** sqlite3_file_control(db, dbname, SQLITE_SET_LOCKPROXYFILE,
+** sqlite3_file_control(db, dbname, SQLITE_FCNTL_SET_LOCKPROXYFILE,
** <proxy_path> | ":auto:");
-** sqlite3_file_control(db, dbname, SQLITE_GET_LOCKPROXYFILE, &<proxy_path>);
+** sqlite3_file_control(db, dbname, SQLITE_FCNTL_GET_LOCKPROXYFILE,
+** &<proxy_path>);
**
**
** SQL pragmas
@@ -28698,7 +33360,7 @@ static int unixGetLastError(sqlite3_vfs *NotUsed, int NotUsed2, char *NotUsed3){
** 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
+** If the conch file does not exist, or its 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
@@ -28750,7 +33412,7 @@ static int unixGetLastError(sqlite3_vfs *NotUsed, int NotUsed2, char *NotUsed3){
** 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
+** files (explicitly calling the SQLITE_FCNTL_SET_LOCKPROXYFILE pragma or
** sqlite_file_control API is not affected by SQLITE_FORCE_PROXY_LOCKING).
*/
@@ -28771,6 +33433,7 @@ struct proxyLockingContext {
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 */
+ int nFails; /* Number of conch taking failures */
void *oldLockingContext; /* Original lockingcontext to restore on close */
sqlite3_io_methods const *pOldMethod; /* Original I/O methods for close */
};
@@ -28792,7 +33455,7 @@ static int proxyGetLockPath(const char *dbPath, char *lPath, size_t maxLen){
{
if( !confstr(_CS_DARWIN_USER_TEMP_DIR, lPath, maxLen) ){
OSTRACE(("GETLOCKPATH failed %s errno=%d pid=%d\n",
- lPath, errno, getpid()));
+ lPath, errno, osGetpid(0)));
return SQLITE_IOERR_LOCK;
}
len = strlcat(lPath, "sqliteplocks", maxLen);
@@ -28814,7 +33477,7 @@ static int proxyGetLockPath(const char *dbPath, char *lPath, size_t maxLen){
}
lPath[i+len]='\0';
strlcat(lPath, ":auto:", maxLen);
- OSTRACE(("GETLOCKPATH proxy lock path=%s pid=%d\n", lPath, getpid()));
+ OSTRACE(("GETLOCKPATH proxy lock path=%s pid=%d\n", lPath, osGetpid(0)));
return SQLITE_OK;
}
@@ -28841,7 +33504,7 @@ static int proxyCreateLockPath(const char *lockPath){
if( err!=EEXIST ) {
OSTRACE(("CREATELOCKPATH FAILED creating %s, "
"'%s' proxy lock path=%s pid=%d\n",
- buf, strerror(err), lockPath, getpid()));
+ buf, strerror(err), lockPath, osGetpid(0)));
return err;
}
}
@@ -28850,7 +33513,7 @@ static int proxyCreateLockPath(const char *lockPath){
}
buf[i] = lockPath[i];
}
- OSTRACE(("CREATELOCKPATH proxy lock path=%s pid=%d\n", lockPath, getpid()));
+ OSTRACE(("CREATELOCKPATH proxy lock path=%s pid=%d\n",lockPath,osGetpid(0)));
return 0;
}
@@ -28884,7 +33547,7 @@ static int proxyCreateUnixFile(
if( pUnused ){
fd = pUnused->fd;
}else{
- pUnused = sqlite3_malloc(sizeof(*pUnused));
+ pUnused = sqlite3_malloc64(sizeof(*pUnused));
if( !pUnused ){
return SQLITE_NOMEM;
}
@@ -28917,7 +33580,7 @@ static int proxyCreateUnixFile(
}
}
- pNew = (unixFile *)sqlite3_malloc(sizeof(*pNew));
+ pNew = (unixFile *)sqlite3_malloc64(sizeof(*pNew));
if( pNew==NULL ){
rc = SQLITE_NOMEM;
goto end_create_proxy;
@@ -28950,8 +33613,10 @@ SQLITE_API int sqlite3_hostid_num = 0;
#define PROXY_HOSTIDLEN 16 /* conch file host id length */
+#ifdef HAVE_GETHOSTUUID
/* Not always defined in the headers as it ought to be */
extern int gethostuuid(uuid_t id, const struct timespec *wait);
+#endif
/* get the host ID via gethostuuid(), pHostID must point to PROXY_HOSTIDLEN
** bytes of writable memory.
@@ -28959,10 +33624,9 @@ extern int gethostuuid(uuid_t id, const struct timespec *wait);
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
+#ifdef HAVE_GETHOSTUUID
{
- static const struct timespec timeout = {1, 0}; /* 1 sec timeout */
+ struct timespec timeout = {1, 0}; /* 1 sec timeout */
if( gethostuuid(pHostID, &timeout) ){
int err = errno;
if( pError ){
@@ -29077,7 +33741,7 @@ static int proxyConchLock(unixFile *pFile, uuid_t myHostID, int lockType){
*/
struct stat buf;
if( osFstat(conchFile->h, &buf) ){
- pFile->lastErrno = errno;
+ storeLastErrno(pFile, errno);
return SQLITE_IOERR_LOCK;
}
@@ -29097,7 +33761,7 @@ static int proxyConchLock(unixFile *pFile, uuid_t myHostID, int lockType){
char tBuf[PROXY_MAXCONCHLEN];
int len = osPread(conchFile->h, tBuf, PROXY_MAXCONCHLEN, 0);
if( len<0 ){
- pFile->lastErrno = errno;
+ storeLastErrno(pFile, errno);
return SQLITE_IOERR_LOCK;
}
if( len>PROXY_PATHINDEX && tBuf[0]==(char)PROXY_CONCHVERSION){
@@ -29117,7 +33781,7 @@ static int proxyConchLock(unixFile *pFile, uuid_t myHostID, int lockType){
if( 0==proxyBreakConchLock(pFile, myHostID) ){
rc = SQLITE_OK;
if( lockType==EXCLUSIVE_LOCK ){
- rc = conchFile->pMethod->xLock((sqlite3_file*)conchFile, SHARED_LOCK);
+ rc = conchFile->pMethod->xLock((sqlite3_file*)conchFile, SHARED_LOCK);
}
if( !rc ){
rc = conchFile->pMethod->xLock((sqlite3_file*)conchFile, lockType);
@@ -29155,11 +33819,12 @@ static int proxyTakeConch(unixFile *pFile){
int forceNewLockPath = 0;
OSTRACE(("TAKECONCH %d for %s pid=%d\n", conchFile->h,
- (pCtx->lockProxyPath ? pCtx->lockProxyPath : ":auto:"), getpid()));
+ (pCtx->lockProxyPath ? pCtx->lockProxyPath : ":auto:"),
+ osGetpid(0)));
rc = proxyGetHostID(myHostID, &pError);
if( (rc&0xff)==SQLITE_IOERR ){
- pFile->lastErrno = pError;
+ storeLastErrno(pFile, pError);
goto end_takeconch;
}
rc = proxyConchLock(pFile, myHostID, SHARED_LOCK);
@@ -29170,7 +33835,7 @@ static int proxyTakeConch(unixFile *pFile){
readLen = seekAndRead((unixFile*)conchFile, 0, readBuf, PROXY_MAXCONCHLEN);
if( readLen<0 ){
/* I/O error: lastErrno set by seekAndRead */
- pFile->lastErrno = conchFile->lastErrno;
+ storeLastErrno(pFile, conchFile->lastErrno);
rc = SQLITE_IOERR_READ;
goto end_takeconch;
}else if( readLen<=(PROXY_HEADERLEN+PROXY_HOSTIDLEN) ||
@@ -29243,7 +33908,7 @@ static int proxyTakeConch(unixFile *pFile){
rc = proxyConchLock(pFile, myHostID, EXCLUSIVE_LOCK);
}
}else{
- rc = conchFile->pMethod->xLock((sqlite3_file*)conchFile, EXCLUSIVE_LOCK);
+ rc = proxyConchLock(pFile, myHostID, EXCLUSIVE_LOCK);
}
if( rc==SQLITE_OK ){
char writeBuffer[PROXY_MAXCONCHLEN];
@@ -29252,7 +33917,8 @@ static int proxyTakeConch(unixFile *pFile){
writeBuffer[0] = (char)PROXY_CONCHVERSION;
memcpy(&writeBuffer[PROXY_HEADERLEN], myHostID, PROXY_HOSTIDLEN);
if( pCtx->lockProxyPath!=NULL ){
- strlcpy(&writeBuffer[PROXY_PATHINDEX], pCtx->lockProxyPath, MAXPATHLEN);
+ strlcpy(&writeBuffer[PROXY_PATHINDEX], pCtx->lockProxyPath,
+ MAXPATHLEN);
}else{
strlcpy(&writeBuffer[PROXY_PATHINDEX], tempLockPath, MAXPATHLEN);
}
@@ -29364,7 +34030,7 @@ static int proxyReleaseConch(unixFile *pFile){
conchFile = pCtx->conchFile;
OSTRACE(("RELEASECONCH %d for %s pid=%d\n", conchFile->h,
(pCtx->lockProxyPath ? pCtx->lockProxyPath : ":auto:"),
- getpid()));
+ osGetpid(0)));
if( pCtx->conchHeld>0 ){
rc = conchFile->pMethod->xUnlock((sqlite3_file*)conchFile, NO_LOCK);
}
@@ -29376,7 +34042,7 @@ static int proxyReleaseConch(unixFile *pFile){
/*
** Given the name of a database file, compute the name of its conch file.
-** Store the conch filename in memory obtained from sqlite3_malloc().
+** Store the conch filename in memory obtained from sqlite3_malloc64().
** Make *pConchPath point to the new name. Return SQLITE_OK on success
** or SQLITE_NOMEM if unable to obtain memory.
**
@@ -29392,7 +34058,7 @@ static int proxyCreateConchPathname(char *dbPath, char **pConchPath){
/* 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);
+ *pConchPath = conchPath = (char *)sqlite3_malloc64(len + 8);
if( conchPath==0 ){
return SQLITE_NOMEM;
}
@@ -29464,7 +34130,8 @@ static int proxyGetDbPathForUnixFile(unixFile *pFile, char *dbPath){
/* 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);
+ strlcpy(dbPath, ((afpLockingContext *)pFile->lockingContext)->dbPath,
+ MAXPATHLEN);
} else
#endif
if( pFile->pMethod == &dotlockIoMethods ){
@@ -29505,9 +34172,9 @@ static int proxyTransformUnixFile(unixFile *pFile, const char *path) {
}
OSTRACE(("TRANSPROXY %d for %s pid=%d\n", pFile->h,
- (lockPath ? lockPath : ":auto:"), getpid()));
+ (lockPath ? lockPath : ":auto:"), osGetpid(0)));
- pCtx = sqlite3_malloc( sizeof(*pCtx) );
+ pCtx = sqlite3_malloc64( sizeof(*pCtx) );
if( pCtx==0 ){
return SQLITE_NOMEM;
}
@@ -29577,7 +34244,7 @@ static int proxyTransformUnixFile(unixFile *pFile, const char *path) {
*/
static int proxyFileControl(sqlite3_file *id, int op, void *pArg){
switch( op ){
- case SQLITE_GET_LOCKPROXYFILE: {
+ case SQLITE_FCNTL_GET_LOCKPROXYFILE: {
unixFile *pFile = (unixFile*)id;
if( pFile->pMethod == &proxyIoMethods ){
proxyLockingContext *pCtx = (proxyLockingContext*)pFile->lockingContext;
@@ -29592,13 +34259,16 @@ static int proxyFileControl(sqlite3_file *id, int op, void *pArg){
}
return SQLITE_OK;
}
- case SQLITE_SET_LOCKPROXYFILE: {
+ case SQLITE_FCNTL_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 */
+ /* turn off proxy locking - not supported. If support is added for
+ ** switching proxy locking mode off then it will need to fail if
+ ** the journal mode is WAL mode.
+ */
rc = SQLITE_ERROR /*SQLITE_PROTOCOL? SQLITE_MISUSE?*/;
}else{
/* turn off proxy locking - already off - NOOP */
@@ -29728,7 +34398,7 @@ static int proxyUnlock(sqlite3_file *id, int eFileLock) {
** Close a file that uses proxy locks.
*/
static int proxyClose(sqlite3_file *id) {
- if( id ){
+ if( ALWAYS(id) ){
unixFile *pFile = (unixFile*)id;
proxyLockingContext *pCtx = (proxyLockingContext *)pFile->lockingContext;
unixFile *lockProxy = pCtx->lockProxy;
@@ -29789,7 +34459,7 @@ static int proxyClose(sqlite3_file *id) {
** necessarily been initialized when this routine is called, and so they
** should not be used.
*/
-SQLITE_API int sqlite3_os_init(void){
+SQLITE_API int SQLITE_STDCALL 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
@@ -29843,8 +34513,10 @@ SQLITE_API int sqlite3_os_init(void){
** array cannot be const.
*/
static sqlite3_vfs aVfs[] = {
-#if SQLITE_ENABLE_LOCKING_STYLE && (OS_VXWORKS || defined(__APPLE__))
+#if SQLITE_ENABLE_LOCKING_STYLE && defined(__APPLE__)
UNIXVFS("unix", autolockIoFinder ),
+#elif OS_VXWORKS
+ UNIXVFS("unix", vxworksIoFinder ),
#else
UNIXVFS("unix", posixIoFinder ),
#endif
@@ -29854,11 +34526,11 @@ SQLITE_API int sqlite3_os_init(void){
#if OS_VXWORKS
UNIXVFS("unix-namedsem", semIoFinder ),
#endif
-#if SQLITE_ENABLE_LOCKING_STYLE
+#if SQLITE_ENABLE_LOCKING_STYLE || OS_VXWORKS
UNIXVFS("unix-posix", posixIoFinder ),
-#if !OS_VXWORKS
- UNIXVFS("unix-flock", flockIoFinder ),
#endif
+#if SQLITE_ENABLE_LOCKING_STYLE
+ UNIXVFS("unix-flock", flockIoFinder ),
#endif
#if SQLITE_ENABLE_LOCKING_STYLE && defined(__APPLE__)
UNIXVFS("unix-afp", afpIoFinder ),
@@ -29870,7 +34542,7 @@ SQLITE_API int sqlite3_os_init(void){
/* Double-check that the aSyscall[] array has been constructed
** correctly. See ticket [bb3a86e890c8e96ab] */
- assert( ArraySize(aSyscall)==22 );
+ assert( ArraySize(aSyscall)==27 );
/* Register all VFSes defined in the aVfs[] array */
for(i=0; i<(sizeof(aVfs)/sizeof(sqlite3_vfs)); i++){
@@ -29886,7 +34558,7 @@ SQLITE_API int sqlite3_os_init(void){
** to release dynamically allocated objects. But not on unix.
** This routine is a no-op for unix.
*/
-SQLITE_API int sqlite3_os_end(void){
+SQLITE_API int SQLITE_STDCALL sqlite3_os_end(void){
return SQLITE_OK;
}
@@ -29908,12 +34580,9 @@ SQLITE_API int sqlite3_os_end(void){
**
** This file contains code that is specific to Windows.
*/
+/* #include "sqliteInt.h" */
#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
*/
@@ -29950,16 +34619,6 @@ SQLITE_API int sqlite3_os_end(void){
# 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.
@@ -30128,19 +34787,29 @@ SQLITE_API int sqlite3_open_file_count = 0;
/************** Continuing where we left off in os_win.c *********************/
/*
+** Include the header file for the Windows VFS.
+*/
+/* #include "os_win.h" */
+
+/*
** 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\
+# error "WAL mode requires support from the Windows NT kernel, compile\
with SQLITE_OMIT_WAL."
#endif
+#if !SQLITE_OS_WINNT && SQLITE_MAX_MMAP_SIZE>0
+# error "Memory mapped files require support from the Windows NT kernel,\
+ compile with SQLITE_MAX_MMAP_SIZE=0."
+#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
+#if !SQLITE_OS_WINCE && !SQLITE_OS_WINRT && !defined(SQLITE_WIN32_NO_ANSI)
# define SQLITE_WIN32_HAS_ANSI
#endif
@@ -30148,16 +34817,128 @@ SQLITE_API int sqlite3_open_file_count = 0;
** 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
+#if (SQLITE_OS_WINCE || SQLITE_OS_WINNT || SQLITE_OS_WINRT) && \
+ !defined(SQLITE_WIN32_NO_WIDE)
# define SQLITE_WIN32_HAS_WIDE
#endif
/*
+** Make sure at least one set of Win32 APIs is available.
+*/
+#if !defined(SQLITE_WIN32_HAS_ANSI) && !defined(SQLITE_WIN32_HAS_WIDE)
+# error "At least one of SQLITE_WIN32_HAS_ANSI and SQLITE_WIN32_HAS_WIDE\
+ must be defined."
+#endif
+
+/*
+** Define the required Windows SDK version constants if they are not
+** already available.
+*/
+#ifndef NTDDI_WIN8
+# define NTDDI_WIN8 0x06020000
+#endif
+
+#ifndef NTDDI_WINBLUE
+# define NTDDI_WINBLUE 0x06030000
+#endif
+
+/*
+** Check to see if the GetVersionEx[AW] functions are deprecated on the
+** target system. GetVersionEx was first deprecated in Win8.1.
+*/
+#ifndef SQLITE_WIN32_GETVERSIONEX
+# if defined(NTDDI_VERSION) && NTDDI_VERSION >= NTDDI_WINBLUE
+# define SQLITE_WIN32_GETVERSIONEX 0 /* GetVersionEx() is deprecated */
+# else
+# define SQLITE_WIN32_GETVERSIONEX 1 /* GetVersionEx() is current */
+# endif
+#endif
+
+/*
+** This constant should already be defined (in the "WinDef.h" SDK file).
+*/
+#ifndef MAX_PATH
+# define MAX_PATH (260)
+#endif
+
+/*
+** Maximum pathname length (in chars) for Win32. This should normally be
+** MAX_PATH.
+*/
+#ifndef SQLITE_WIN32_MAX_PATH_CHARS
+# define SQLITE_WIN32_MAX_PATH_CHARS (MAX_PATH)
+#endif
+
+/*
+** This constant should already be defined (in the "WinNT.h" SDK file).
+*/
+#ifndef UNICODE_STRING_MAX_CHARS
+# define UNICODE_STRING_MAX_CHARS (32767)
+#endif
+
+/*
+** Maximum pathname length (in chars) for WinNT. This should normally be
+** UNICODE_STRING_MAX_CHARS.
+*/
+#ifndef SQLITE_WINNT_MAX_PATH_CHARS
+# define SQLITE_WINNT_MAX_PATH_CHARS (UNICODE_STRING_MAX_CHARS)
+#endif
+
+/*
+** Maximum pathname length (in bytes) for Win32. The MAX_PATH macro is in
+** characters, so we allocate 4 bytes per character assuming worst-case of
+** 4-bytes-per-character for UTF8.
+*/
+#ifndef SQLITE_WIN32_MAX_PATH_BYTES
+# define SQLITE_WIN32_MAX_PATH_BYTES (SQLITE_WIN32_MAX_PATH_CHARS*4)
+#endif
+
+/*
+** Maximum pathname length (in bytes) for WinNT. This should normally be
+** UNICODE_STRING_MAX_CHARS * sizeof(WCHAR).
+*/
+#ifndef SQLITE_WINNT_MAX_PATH_BYTES
+# define SQLITE_WINNT_MAX_PATH_BYTES \
+ (sizeof(WCHAR) * SQLITE_WINNT_MAX_PATH_CHARS)
+#endif
+
+/*
+** Maximum error message length (in chars) for WinRT.
+*/
+#ifndef SQLITE_WIN32_MAX_ERRMSG_CHARS
+# define SQLITE_WIN32_MAX_ERRMSG_CHARS (1024)
+#endif
+
+/*
+** Returns non-zero if the character should be treated as a directory
+** separator.
+*/
+#ifndef winIsDirSep
+# define winIsDirSep(a) (((a) == '/') || ((a) == '\\'))
+#endif
+
+/*
+** This macro is used when a local variable is set to a value that is
+** [sometimes] not used by the code (e.g. via conditional compilation).
+*/
+#ifndef UNUSED_VARIABLE_VALUE
+# define UNUSED_VARIABLE_VALUE(x) (void)(x)
+#endif
+
+/*
+** Returns the character that should be used as the directory separator.
+*/
+#ifndef winGetDirSep
+# define winGetDirSep() '\\'
+#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)?
+** mode or memory mapped files (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)
+#if SQLITE_WIN32_FILEMAPPING_API && \
+ (!defined(SQLITE_OMIT_WAL) || SQLITE_MAX_MMAP_SIZE>0)
/*
** Two of the file mapping APIs are different under WinRT. Figure out which
** set we need.
@@ -30182,23 +34963,18 @@ 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.
+** These file mapping APIs are 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
+WINBASEAPI BOOL WINAPI FlushViewOfFile(LPCVOID, SIZE_T);
+WINBASEAPI BOOL WINAPI UnmapViewOfFile(LPCVOID);
+#endif /* SQLITE_WIN32_FILEMAPPING_API */
/*
** Some Microsoft compilers lack this definition.
*/
#ifndef INVALID_FILE_ATTRIBUTES
-# define INVALID_FILE_ATTRIBUTES ((DWORD)-1)
+# define INVALID_FILE_ATTRIBUTES ((DWORD)-1)
#endif
#ifndef FILE_FLAG_MASK
@@ -30210,7 +34986,7 @@ WINBASEAPI BOOL WINAPI UnmapViewOfFile(LPCVOID);
#endif
#ifndef SQLITE_OMIT_WAL
-/* Forward references */
+/* Forward references to structures used for WAL */
typedef struct winShm winShm; /* A connection to shared-memory */
typedef struct winShmNode winShmNode; /* A region of shared-memory */
#endif
@@ -30248,16 +35024,25 @@ struct winFile {
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 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
+#if SQLITE_MAX_MMAP_SIZE>0
+ int nFetchOut; /* Number of outstanding xFetch references */
+ HANDLE hMap; /* Handle for accessing memory mapping */
+ void *pMapRegion; /* Area memory mapped */
+ sqlite3_int64 mmapSize; /* Usable size of mapped region */
+ sqlite3_int64 mmapSizeActual; /* Actual size of mapped region */
+ sqlite3_int64 mmapSizeMax; /* Configured FCNTL_MMAP_SIZE value */
+#endif
};
/*
** Allowed values for winFile.ctrlFlags
*/
+#define WINFILE_RDONLY 0x02 /* Connection is read only */
#define WINFILE_PERSIST_WAL 0x04 /* Persistent WAL mode */
#define WINFILE_PSOW 0x10 /* SQLITE_IOCAP_POWERSAFE_OVERWRITE */
@@ -30331,6 +35116,7 @@ struct winFile {
# define SQLITE_WIN32_HEAP_FLAGS (0)
#endif
+
/*
** The winMemData structure stores information required by the Win32-specific
** sqlite3_mem_methods implementation.
@@ -30338,30 +35124,41 @@ struct winFile {
typedef struct winMemData winMemData;
struct winMemData {
#ifndef NDEBUG
- u32 magic; /* Magic number to detect structure corruption. */
+ u32 magic1; /* 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
+ u32 magic2; /* Magic number to detect structure corruption. */
+#endif
};
#ifndef NDEBUG
-#define WINMEM_MAGIC 0x42b2830b
+#define WINMEM_MAGIC1 0x42b2830b
+#define WINMEM_MAGIC2 0xbd4d7cf4
#endif
static struct winMemData win_mem_data = {
#ifndef NDEBUG
- WINMEM_MAGIC,
+ WINMEM_MAGIC1,
#endif
NULL, FALSE
+#ifndef NDEBUG
+ ,WINMEM_MAGIC2
+#endif
};
#ifndef NDEBUG
-#define winMemAssertMagic() assert( win_mem_data.magic==WINMEM_MAGIC )
+#define winMemAssertMagic1() assert( win_mem_data.magic1==WINMEM_MAGIC1 )
+#define winMemAssertMagic2() assert( win_mem_data.magic2==WINMEM_MAGIC2 )
+#define winMemAssertMagic() winMemAssertMagic1(); winMemAssertMagic2();
#else
#define winMemAssertMagic()
#endif
-#define winMemGetHeap() win_mem_data.hHeap
+#define winMemGetDataPtr() &win_mem_data
+#define winMemGetHeap() win_mem_data.hHeap
+#define winMemGetOwned() win_mem_data.bOwned
static void *winMemMalloc(int nBytes);
static void winMemFree(void *pPrior);
@@ -30387,9 +35184,9 @@ SQLITE_PRIVATE const sqlite3_mem_methods *sqlite3MemGetWin32(void);
** can manually set this value to 1 to emulate Win98 behavior.
*/
#ifdef SQLITE_TEST
-SQLITE_API int sqlite3_os_type = 0;
+SQLITE_API LONG SQLITE_WIN32_VOLATILE sqlite3_os_type = 0;
#else
-static int sqlite3_os_type = 0;
+static LONG SQLITE_WIN32_VOLATILE sqlite3_os_type = 0;
#endif
#ifndef SYSCALL
@@ -30411,7 +35208,7 @@ static int sqlite3_os_type = 0;
** to all overrideable system calls.
*/
static struct win_syscall {
- const char *zName; /* Name of the sytem call */
+ const char *zName; /* Name of the system call */
sqlite3_syscall_ptr pCurrent; /* Current value of the system call */
sqlite3_syscall_ptr pDefault; /* Default value */
} aSyscall[] = {
@@ -30464,7 +35261,7 @@ static struct win_syscall {
LPSECURITY_ATTRIBUTES,DWORD,DWORD,HANDLE))aSyscall[5].pCurrent)
#if (!SQLITE_OS_WINRT && defined(SQLITE_WIN32_HAS_ANSI) && \
- !defined(SQLITE_OMIT_WAL))
+ (!defined(SQLITE_OMIT_WAL) || SQLITE_MAX_MMAP_SIZE>0))
{ "CreateFileMappingA", (SYSCALL)CreateFileMappingA, 0 },
#else
{ "CreateFileMappingA", (SYSCALL)0, 0 },
@@ -30474,7 +35271,7 @@ static struct win_syscall {
DWORD,DWORD,DWORD,LPCSTR))aSyscall[6].pCurrent)
#if SQLITE_OS_WINCE || (!SQLITE_OS_WINRT && defined(SQLITE_WIN32_HAS_WIDE) && \
- !defined(SQLITE_OMIT_WAL))
+ (!defined(SQLITE_OMIT_WAL) || SQLITE_MAX_MMAP_SIZE>0))
{ "CreateFileMappingW", (SYSCALL)CreateFileMappingW, 0 },
#else
{ "CreateFileMappingW", (SYSCALL)0, 0 },
@@ -30694,7 +35491,8 @@ static struct win_syscall {
#define osGetTickCount ((DWORD(WINAPI*)(VOID))aSyscall[33].pCurrent)
-#if defined(SQLITE_WIN32_HAS_ANSI)
+#if defined(SQLITE_WIN32_HAS_ANSI) && defined(SQLITE_WIN32_GETVERSIONEX) && \
+ SQLITE_WIN32_GETVERSIONEX
{ "GetVersionExA", (SYSCALL)GetVersionExA, 0 },
#else
{ "GetVersionExA", (SYSCALL)0, 0 },
@@ -30703,10 +35501,20 @@ static struct win_syscall {
#define osGetVersionExA ((BOOL(WINAPI*)( \
LPOSVERSIONINFOA))aSyscall[34].pCurrent)
+#if !SQLITE_OS_WINRT && defined(SQLITE_WIN32_HAS_WIDE) && \
+ defined(SQLITE_WIN32_GETVERSIONEX) && SQLITE_WIN32_GETVERSIONEX
+ { "GetVersionExW", (SYSCALL)GetVersionExW, 0 },
+#else
+ { "GetVersionExW", (SYSCALL)0, 0 },
+#endif
+
+#define osGetVersionExW ((BOOL(WINAPI*)( \
+ LPOSVERSIONINFOW))aSyscall[35].pCurrent)
+
{ "HeapAlloc", (SYSCALL)HeapAlloc, 0 },
#define osHeapAlloc ((LPVOID(WINAPI*)(HANDLE,DWORD, \
- SIZE_T))aSyscall[35].pCurrent)
+ SIZE_T))aSyscall[36].pCurrent)
#if !SQLITE_OS_WINRT
{ "HeapCreate", (SYSCALL)HeapCreate, 0 },
@@ -30715,7 +35523,7 @@ static struct win_syscall {
#endif
#define osHeapCreate ((HANDLE(WINAPI*)(DWORD,SIZE_T, \
- SIZE_T))aSyscall[36].pCurrent)
+ SIZE_T))aSyscall[37].pCurrent)
#if !SQLITE_OS_WINRT
{ "HeapDestroy", (SYSCALL)HeapDestroy, 0 },
@@ -30723,21 +35531,21 @@ static struct win_syscall {
{ "HeapDestroy", (SYSCALL)0, 0 },
#endif
-#define osHeapDestroy ((BOOL(WINAPI*)(HANDLE))aSyscall[37].pCurrent)
+#define osHeapDestroy ((BOOL(WINAPI*)(HANDLE))aSyscall[38].pCurrent)
{ "HeapFree", (SYSCALL)HeapFree, 0 },
-#define osHeapFree ((BOOL(WINAPI*)(HANDLE,DWORD,LPVOID))aSyscall[38].pCurrent)
+#define osHeapFree ((BOOL(WINAPI*)(HANDLE,DWORD,LPVOID))aSyscall[39].pCurrent)
{ "HeapReAlloc", (SYSCALL)HeapReAlloc, 0 },
#define osHeapReAlloc ((LPVOID(WINAPI*)(HANDLE,DWORD,LPVOID, \
- SIZE_T))aSyscall[39].pCurrent)
+ SIZE_T))aSyscall[40].pCurrent)
{ "HeapSize", (SYSCALL)HeapSize, 0 },
#define osHeapSize ((SIZE_T(WINAPI*)(HANDLE,DWORD, \
- LPCVOID))aSyscall[40].pCurrent)
+ LPCVOID))aSyscall[41].pCurrent)
#if !SQLITE_OS_WINRT
{ "HeapValidate", (SYSCALL)HeapValidate, 0 },
@@ -30746,7 +35554,15 @@ static struct win_syscall {
#endif
#define osHeapValidate ((BOOL(WINAPI*)(HANDLE,DWORD, \
- LPCVOID))aSyscall[41].pCurrent)
+ LPCVOID))aSyscall[42].pCurrent)
+
+#if !SQLITE_OS_WINCE && !SQLITE_OS_WINRT
+ { "HeapCompact", (SYSCALL)HeapCompact, 0 },
+#else
+ { "HeapCompact", (SYSCALL)0, 0 },
+#endif
+
+#define osHeapCompact ((UINT(WINAPI*)(HANDLE,DWORD))aSyscall[43].pCurrent)
#if defined(SQLITE_WIN32_HAS_ANSI) && !defined(SQLITE_OMIT_LOAD_EXTENSION)
{ "LoadLibraryA", (SYSCALL)LoadLibraryA, 0 },
@@ -30754,7 +35570,7 @@ static struct win_syscall {
{ "LoadLibraryA", (SYSCALL)0, 0 },
#endif
-#define osLoadLibraryA ((HMODULE(WINAPI*)(LPCSTR))aSyscall[42].pCurrent)
+#define osLoadLibraryA ((HMODULE(WINAPI*)(LPCSTR))aSyscall[44].pCurrent)
#if !SQLITE_OS_WINRT && defined(SQLITE_WIN32_HAS_WIDE) && \
!defined(SQLITE_OMIT_LOAD_EXTENSION)
@@ -30763,7 +35579,7 @@ static struct win_syscall {
{ "LoadLibraryW", (SYSCALL)0, 0 },
#endif
-#define osLoadLibraryW ((HMODULE(WINAPI*)(LPCWSTR))aSyscall[43].pCurrent)
+#define osLoadLibraryW ((HMODULE(WINAPI*)(LPCWSTR))aSyscall[45].pCurrent)
#if !SQLITE_OS_WINRT
{ "LocalFree", (SYSCALL)LocalFree, 0 },
@@ -30771,7 +35587,7 @@ static struct win_syscall {
{ "LocalFree", (SYSCALL)0, 0 },
#endif
-#define osLocalFree ((HLOCAL(WINAPI*)(HLOCAL))aSyscall[44].pCurrent)
+#define osLocalFree ((HLOCAL(WINAPI*)(HLOCAL))aSyscall[46].pCurrent)
#if !SQLITE_OS_WINCE && !SQLITE_OS_WINRT
{ "LockFile", (SYSCALL)LockFile, 0 },
@@ -30781,7 +35597,7 @@ static struct win_syscall {
#ifndef osLockFile
#define osLockFile ((BOOL(WINAPI*)(HANDLE,DWORD,DWORD,DWORD, \
- DWORD))aSyscall[45].pCurrent)
+ DWORD))aSyscall[47].pCurrent)
#endif
#if !SQLITE_OS_WINCE
@@ -30792,36 +35608,37 @@ static struct win_syscall {
#ifndef osLockFileEx
#define osLockFileEx ((BOOL(WINAPI*)(HANDLE,DWORD,DWORD,DWORD,DWORD, \
- LPOVERLAPPED))aSyscall[46].pCurrent)
+ LPOVERLAPPED))aSyscall[48].pCurrent)
#endif
-#if SQLITE_OS_WINCE || (!SQLITE_OS_WINRT && !defined(SQLITE_OMIT_WAL))
+#if SQLITE_OS_WINCE || (!SQLITE_OS_WINRT && \
+ (!defined(SQLITE_OMIT_WAL) || SQLITE_MAX_MMAP_SIZE>0))
{ "MapViewOfFile", (SYSCALL)MapViewOfFile, 0 },
#else
{ "MapViewOfFile", (SYSCALL)0, 0 },
#endif
#define osMapViewOfFile ((LPVOID(WINAPI*)(HANDLE,DWORD,DWORD,DWORD, \
- SIZE_T))aSyscall[47].pCurrent)
+ SIZE_T))aSyscall[49].pCurrent)
{ "MultiByteToWideChar", (SYSCALL)MultiByteToWideChar, 0 },
#define osMultiByteToWideChar ((int(WINAPI*)(UINT,DWORD,LPCSTR,int,LPWSTR, \
- int))aSyscall[48].pCurrent)
+ int))aSyscall[50].pCurrent)
{ "QueryPerformanceCounter", (SYSCALL)QueryPerformanceCounter, 0 },
#define osQueryPerformanceCounter ((BOOL(WINAPI*)( \
- LARGE_INTEGER*))aSyscall[49].pCurrent)
+ LARGE_INTEGER*))aSyscall[51].pCurrent)
{ "ReadFile", (SYSCALL)ReadFile, 0 },
#define osReadFile ((BOOL(WINAPI*)(HANDLE,LPVOID,DWORD,LPDWORD, \
- LPOVERLAPPED))aSyscall[50].pCurrent)
+ LPOVERLAPPED))aSyscall[52].pCurrent)
{ "SetEndOfFile", (SYSCALL)SetEndOfFile, 0 },
-#define osSetEndOfFile ((BOOL(WINAPI*)(HANDLE))aSyscall[51].pCurrent)
+#define osSetEndOfFile ((BOOL(WINAPI*)(HANDLE))aSyscall[53].pCurrent)
#if !SQLITE_OS_WINRT
{ "SetFilePointer", (SYSCALL)SetFilePointer, 0 },
@@ -30830,7 +35647,7 @@ static struct win_syscall {
#endif
#define osSetFilePointer ((DWORD(WINAPI*)(HANDLE,LONG,PLONG, \
- DWORD))aSyscall[52].pCurrent)
+ DWORD))aSyscall[54].pCurrent)
#if !SQLITE_OS_WINRT
{ "Sleep", (SYSCALL)Sleep, 0 },
@@ -30838,12 +35655,12 @@ static struct win_syscall {
{ "Sleep", (SYSCALL)0, 0 },
#endif
-#define osSleep ((VOID(WINAPI*)(DWORD))aSyscall[53].pCurrent)
+#define osSleep ((VOID(WINAPI*)(DWORD))aSyscall[55].pCurrent)
{ "SystemTimeToFileTime", (SYSCALL)SystemTimeToFileTime, 0 },
#define osSystemTimeToFileTime ((BOOL(WINAPI*)(CONST SYSTEMTIME*, \
- LPFILETIME))aSyscall[54].pCurrent)
+ LPFILETIME))aSyscall[56].pCurrent)
#if !SQLITE_OS_WINCE && !SQLITE_OS_WINRT
{ "UnlockFile", (SYSCALL)UnlockFile, 0 },
@@ -30853,7 +35670,7 @@ static struct win_syscall {
#ifndef osUnlockFile
#define osUnlockFile ((BOOL(WINAPI*)(HANDLE,DWORD,DWORD,DWORD, \
- DWORD))aSyscall[55].pCurrent)
+ DWORD))aSyscall[57].pCurrent)
#endif
#if !SQLITE_OS_WINCE
@@ -30863,25 +35680,25 @@ static struct win_syscall {
#endif
#define osUnlockFileEx ((BOOL(WINAPI*)(HANDLE,DWORD,DWORD,DWORD, \
- LPOVERLAPPED))aSyscall[56].pCurrent)
+ LPOVERLAPPED))aSyscall[58].pCurrent)
-#if SQLITE_OS_WINCE || !defined(SQLITE_OMIT_WAL)
+#if SQLITE_OS_WINCE || !defined(SQLITE_OMIT_WAL) || SQLITE_MAX_MMAP_SIZE>0
{ "UnmapViewOfFile", (SYSCALL)UnmapViewOfFile, 0 },
#else
{ "UnmapViewOfFile", (SYSCALL)0, 0 },
#endif
-#define osUnmapViewOfFile ((BOOL(WINAPI*)(LPCVOID))aSyscall[57].pCurrent)
+#define osUnmapViewOfFile ((BOOL(WINAPI*)(LPCVOID))aSyscall[59].pCurrent)
{ "WideCharToMultiByte", (SYSCALL)WideCharToMultiByte, 0 },
#define osWideCharToMultiByte ((int(WINAPI*)(UINT,DWORD,LPCWSTR,int,LPSTR,int, \
- LPCSTR,LPBOOL))aSyscall[58].pCurrent)
+ LPCSTR,LPBOOL))aSyscall[60].pCurrent)
{ "WriteFile", (SYSCALL)WriteFile, 0 },
#define osWriteFile ((BOOL(WINAPI*)(HANDLE,LPCVOID,DWORD,LPDWORD, \
- LPOVERLAPPED))aSyscall[59].pCurrent)
+ LPOVERLAPPED))aSyscall[61].pCurrent)
#if SQLITE_OS_WINRT
{ "CreateEventExW", (SYSCALL)CreateEventExW, 0 },
@@ -30890,7 +35707,7 @@ static struct win_syscall {
#endif
#define osCreateEventExW ((HANDLE(WINAPI*)(LPSECURITY_ATTRIBUTES,LPCWSTR, \
- DWORD,DWORD))aSyscall[60].pCurrent)
+ DWORD,DWORD))aSyscall[62].pCurrent)
#if !SQLITE_OS_WINRT
{ "WaitForSingleObject", (SYSCALL)WaitForSingleObject, 0 },
@@ -30899,16 +35716,16 @@ static struct win_syscall {
#endif
#define osWaitForSingleObject ((DWORD(WINAPI*)(HANDLE, \
- DWORD))aSyscall[61].pCurrent)
+ DWORD))aSyscall[63].pCurrent)
-#if SQLITE_OS_WINRT
+#if !SQLITE_OS_WINCE
{ "WaitForSingleObjectEx", (SYSCALL)WaitForSingleObjectEx, 0 },
#else
{ "WaitForSingleObjectEx", (SYSCALL)0, 0 },
#endif
#define osWaitForSingleObjectEx ((DWORD(WINAPI*)(HANDLE,DWORD, \
- BOOL))aSyscall[62].pCurrent)
+ BOOL))aSyscall[64].pCurrent)
#if SQLITE_OS_WINRT
{ "SetFilePointerEx", (SYSCALL)SetFilePointerEx, 0 },
@@ -30917,7 +35734,7 @@ static struct win_syscall {
#endif
#define osSetFilePointerEx ((BOOL(WINAPI*)(HANDLE,LARGE_INTEGER, \
- PLARGE_INTEGER,DWORD))aSyscall[63].pCurrent)
+ PLARGE_INTEGER,DWORD))aSyscall[65].pCurrent)
#if SQLITE_OS_WINRT
{ "GetFileInformationByHandleEx", (SYSCALL)GetFileInformationByHandleEx, 0 },
@@ -30926,16 +35743,16 @@ static struct win_syscall {
#endif
#define osGetFileInformationByHandleEx ((BOOL(WINAPI*)(HANDLE, \
- FILE_INFO_BY_HANDLE_CLASS,LPVOID,DWORD))aSyscall[64].pCurrent)
+ FILE_INFO_BY_HANDLE_CLASS,LPVOID,DWORD))aSyscall[66].pCurrent)
-#if SQLITE_OS_WINRT && !defined(SQLITE_OMIT_WAL)
+#if SQLITE_OS_WINRT && (!defined(SQLITE_OMIT_WAL) || SQLITE_MAX_MMAP_SIZE>0)
{ "MapViewOfFileFromApp", (SYSCALL)MapViewOfFileFromApp, 0 },
#else
{ "MapViewOfFileFromApp", (SYSCALL)0, 0 },
#endif
#define osMapViewOfFileFromApp ((LPVOID(WINAPI*)(HANDLE,ULONG,ULONG64, \
- SIZE_T))aSyscall[65].pCurrent)
+ SIZE_T))aSyscall[67].pCurrent)
#if SQLITE_OS_WINRT
{ "CreateFile2", (SYSCALL)CreateFile2, 0 },
@@ -30944,7 +35761,7 @@ static struct win_syscall {
#endif
#define osCreateFile2 ((HANDLE(WINAPI*)(LPCWSTR,DWORD,DWORD,DWORD, \
- LPCREATEFILE2_EXTENDED_PARAMETERS))aSyscall[66].pCurrent)
+ LPCREATEFILE2_EXTENDED_PARAMETERS))aSyscall[68].pCurrent)
#if SQLITE_OS_WINRT && !defined(SQLITE_OMIT_LOAD_EXTENSION)
{ "LoadPackagedLibrary", (SYSCALL)LoadPackagedLibrary, 0 },
@@ -30953,7 +35770,7 @@ static struct win_syscall {
#endif
#define osLoadPackagedLibrary ((HMODULE(WINAPI*)(LPCWSTR, \
- DWORD))aSyscall[67].pCurrent)
+ DWORD))aSyscall[69].pCurrent)
#if SQLITE_OS_WINRT
{ "GetTickCount64", (SYSCALL)GetTickCount64, 0 },
@@ -30961,7 +35778,7 @@ static struct win_syscall {
{ "GetTickCount64", (SYSCALL)0, 0 },
#endif
-#define osGetTickCount64 ((ULONGLONG(WINAPI*)(VOID))aSyscall[68].pCurrent)
+#define osGetTickCount64 ((ULONGLONG(WINAPI*)(VOID))aSyscall[70].pCurrent)
#if SQLITE_OS_WINRT
{ "GetNativeSystemInfo", (SYSCALL)GetNativeSystemInfo, 0 },
@@ -30970,7 +35787,7 @@ static struct win_syscall {
#endif
#define osGetNativeSystemInfo ((VOID(WINAPI*)( \
- LPSYSTEM_INFO))aSyscall[69].pCurrent)
+ LPSYSTEM_INFO))aSyscall[71].pCurrent)
#if defined(SQLITE_WIN32_HAS_ANSI)
{ "OutputDebugStringA", (SYSCALL)OutputDebugStringA, 0 },
@@ -30978,7 +35795,7 @@ static struct win_syscall {
{ "OutputDebugStringA", (SYSCALL)0, 0 },
#endif
-#define osOutputDebugStringA ((VOID(WINAPI*)(LPCSTR))aSyscall[70].pCurrent)
+#define osOutputDebugStringA ((VOID(WINAPI*)(LPCSTR))aSyscall[72].pCurrent)
#if defined(SQLITE_WIN32_HAS_WIDE)
{ "OutputDebugStringW", (SYSCALL)OutputDebugStringW, 0 },
@@ -30986,20 +35803,62 @@ static struct win_syscall {
{ "OutputDebugStringW", (SYSCALL)0, 0 },
#endif
-#define osOutputDebugStringW ((VOID(WINAPI*)(LPCWSTR))aSyscall[71].pCurrent)
+#define osOutputDebugStringW ((VOID(WINAPI*)(LPCWSTR))aSyscall[73].pCurrent)
{ "GetProcessHeap", (SYSCALL)GetProcessHeap, 0 },
-#define osGetProcessHeap ((HANDLE(WINAPI*)(VOID))aSyscall[72].pCurrent)
+#define osGetProcessHeap ((HANDLE(WINAPI*)(VOID))aSyscall[74].pCurrent)
-#if SQLITE_OS_WINRT && !defined(SQLITE_OMIT_WAL)
+#if SQLITE_OS_WINRT && (!defined(SQLITE_OMIT_WAL) || SQLITE_MAX_MMAP_SIZE>0)
{ "CreateFileMappingFromApp", (SYSCALL)CreateFileMappingFromApp, 0 },
#else
{ "CreateFileMappingFromApp", (SYSCALL)0, 0 },
#endif
#define osCreateFileMappingFromApp ((HANDLE(WINAPI*)(HANDLE, \
- LPSECURITY_ATTRIBUTES,ULONG,ULONG64,LPCWSTR))aSyscall[73].pCurrent)
+ LPSECURITY_ATTRIBUTES,ULONG,ULONG64,LPCWSTR))aSyscall[75].pCurrent)
+
+/*
+** NOTE: On some sub-platforms, the InterlockedCompareExchange "function"
+** is really just a macro that uses a compiler intrinsic (e.g. x64).
+** So do not try to make this is into a redefinable interface.
+*/
+#if defined(InterlockedCompareExchange)
+ { "InterlockedCompareExchange", (SYSCALL)0, 0 },
+
+#define osInterlockedCompareExchange InterlockedCompareExchange
+#else
+ { "InterlockedCompareExchange", (SYSCALL)InterlockedCompareExchange, 0 },
+
+#define osInterlockedCompareExchange ((LONG(WINAPI*)(LONG \
+ SQLITE_WIN32_VOLATILE*, LONG,LONG))aSyscall[76].pCurrent)
+#endif /* defined(InterlockedCompareExchange) */
+
+#if !SQLITE_OS_WINCE && !SQLITE_OS_WINRT && SQLITE_WIN32_USE_UUID
+ { "UuidCreate", (SYSCALL)UuidCreate, 0 },
+#else
+ { "UuidCreate", (SYSCALL)0, 0 },
+#endif
+
+#define osUuidCreate ((RPC_STATUS(RPC_ENTRY*)(UUID*))aSyscall[77].pCurrent)
+
+#if !SQLITE_OS_WINCE && !SQLITE_OS_WINRT && SQLITE_WIN32_USE_UUID
+ { "UuidCreateSequential", (SYSCALL)UuidCreateSequential, 0 },
+#else
+ { "UuidCreateSequential", (SYSCALL)0, 0 },
+#endif
+
+#define osUuidCreateSequential \
+ ((RPC_STATUS(RPC_ENTRY*)(UUID*))aSyscall[78].pCurrent)
+
+#if !defined(SQLITE_NO_SYNC) && SQLITE_MAX_MMAP_SIZE>0
+ { "FlushViewOfFile", (SYSCALL)FlushViewOfFile, 0 },
+#else
+ { "FlushViewOfFile", (SYSCALL)0, 0 },
+#endif
+
+#define osFlushViewOfFile \
+ ((BOOL(WINAPI*)(LPCVOID,SIZE_T))aSyscall[79].pCurrent)
}; /* End of the overrideable system calls */
@@ -31086,12 +35945,100 @@ static const char *winNextSystemCall(sqlite3_vfs *p, const char *zName){
return 0;
}
+#ifdef SQLITE_WIN32_MALLOC
+/*
+** If a Win32 native heap has been configured, this function will attempt to
+** compact it. Upon success, SQLITE_OK will be returned. Upon failure, one
+** of SQLITE_NOMEM, SQLITE_ERROR, or SQLITE_NOTFOUND will be returned. The
+** "pnLargest" argument, if non-zero, will be used to return the size of the
+** largest committed free block in the heap, in bytes.
+*/
+SQLITE_API int SQLITE_STDCALL sqlite3_win32_compact_heap(LPUINT pnLargest){
+ int rc = SQLITE_OK;
+ UINT nLargest = 0;
+ 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, NULL) );
+#endif
+#if !SQLITE_OS_WINCE && !SQLITE_OS_WINRT
+ if( (nLargest=osHeapCompact(hHeap, SQLITE_WIN32_HEAP_FLAGS))==0 ){
+ DWORD lastErrno = osGetLastError();
+ if( lastErrno==NO_ERROR ){
+ sqlite3_log(SQLITE_NOMEM, "failed to HeapCompact (no space), heap=%p",
+ (void*)hHeap);
+ rc = SQLITE_NOMEM;
+ }else{
+ sqlite3_log(SQLITE_ERROR, "failed to HeapCompact (%lu), heap=%p",
+ osGetLastError(), (void*)hHeap);
+ rc = SQLITE_ERROR;
+ }
+ }
+#else
+ sqlite3_log(SQLITE_NOTFOUND, "failed to HeapCompact, heap=%p",
+ (void*)hHeap);
+ rc = SQLITE_NOTFOUND;
+#endif
+ if( pnLargest ) *pnLargest = nLargest;
+ return rc;
+}
+
+/*
+** If a Win32 native heap has been configured, this function will attempt to
+** destroy and recreate it. If the Win32 native heap is not isolated and/or
+** the sqlite3_memory_used() function does not return zero, SQLITE_BUSY will
+** be returned and no changes will be made to the Win32 native heap.
+*/
+SQLITE_API int SQLITE_STDCALL sqlite3_win32_reset_heap(){
+ int rc;
+ MUTEX_LOGIC( sqlite3_mutex *pMaster; ) /* The main static mutex */
+ MUTEX_LOGIC( sqlite3_mutex *pMem; ) /* The memsys static mutex */
+ MUTEX_LOGIC( pMaster = sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_MASTER); )
+ MUTEX_LOGIC( pMem = sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_MEM); )
+ sqlite3_mutex_enter(pMaster);
+ sqlite3_mutex_enter(pMem);
+ winMemAssertMagic();
+ if( winMemGetHeap()!=NULL && winMemGetOwned() && sqlite3_memory_used()==0 ){
+ /*
+ ** At this point, there should be no outstanding memory allocations on
+ ** the heap. Also, since both the master and memsys locks are currently
+ ** being held by us, no other function (i.e. from another thread) should
+ ** be able to even access the heap. Attempt to destroy and recreate our
+ ** isolated Win32 native heap now.
+ */
+ assert( winMemGetHeap()!=NULL );
+ assert( winMemGetOwned() );
+ assert( sqlite3_memory_used()==0 );
+ winMemShutdown(winMemGetDataPtr());
+ assert( winMemGetHeap()==NULL );
+ assert( !winMemGetOwned() );
+ assert( sqlite3_memory_used()==0 );
+ rc = winMemInit(winMemGetDataPtr());
+ assert( rc!=SQLITE_OK || winMemGetHeap()!=NULL );
+ assert( rc!=SQLITE_OK || winMemGetOwned() );
+ assert( rc!=SQLITE_OK || sqlite3_memory_used()==0 );
+ }else{
+ /*
+ ** The Win32 native heap cannot be modified because it may be in use.
+ */
+ rc = SQLITE_BUSY;
+ }
+ sqlite3_mutex_leave(pMem);
+ sqlite3_mutex_leave(pMaster);
+ return rc;
+}
+#endif /* SQLITE_WIN32_MALLOC */
+
/*
** This function outputs the specified (ANSI) string to the Win32 debugger
** (if available).
*/
-SQLITE_API void sqlite3_win32_write_debug(char *zBuf, int nBuf){
+SQLITE_API void SQLITE_STDCALL sqlite3_win32_write_debug(const 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. */
@@ -31131,7 +36078,7 @@ SQLITE_API void sqlite3_win32_write_debug(char *zBuf, int nBuf){
static HANDLE sleepObj = NULL;
#endif
-SQLITE_API void sqlite3_win32_sleep(DWORD milliseconds){
+SQLITE_API void SQLITE_STDCALL sqlite3_win32_sleep(DWORD milliseconds){
#if SQLITE_OS_WINRT
if ( sleepObj==NULL ){
sleepObj = osCreateEventExW(NULL, NULL, CREATE_EVENT_MANUAL_RESET,
@@ -31144,6 +36091,16 @@ SQLITE_API void sqlite3_win32_sleep(DWORD milliseconds){
#endif
}
+#if SQLITE_MAX_WORKER_THREADS>0 && !SQLITE_OS_WINCE && !SQLITE_OS_WINRT && \
+ SQLITE_THREADSAFE>0
+SQLITE_PRIVATE DWORD sqlite3Win32Wait(HANDLE hObject){
+ DWORD rc;
+ while( (rc = osWaitForSingleObjectEx(hObject, INFINITE,
+ TRUE))==WAIT_IO_COMPLETION ){}
+ return rc;
+}
+#endif
+
/*
** Return true (non-zero) if we are running under WinNT, Win2K, WinXP,
** or WinCE. Return false (zero) for Win95, Win98, or WinME.
@@ -31155,21 +36112,55 @@ SQLITE_API void sqlite3_win32_sleep(DWORD milliseconds){
** 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)
+
+#if !defined(SQLITE_WIN32_GETVERSIONEX) || !SQLITE_WIN32_GETVERSIONEX
+# define osIsNT() (1)
+#elif SQLITE_OS_WINCE || SQLITE_OS_WINRT || !defined(SQLITE_WIN32_HAS_ANSI)
+# define osIsNT() (1)
#elif !defined(SQLITE_WIN32_HAS_WIDE)
-# define isNT() (0)
+# define osIsNT() (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;
+# define osIsNT() ((sqlite3_os_type==2) || sqlite3_win32_is_nt())
+#endif
+
+/*
+** This function determines if the machine is running a version of Windows
+** based on the NT kernel.
+*/
+SQLITE_API int SQLITE_STDCALL sqlite3_win32_is_nt(void){
+#if SQLITE_OS_WINRT
+ /*
+ ** NOTE: The WinRT sub-platform is always assumed to be based on the NT
+ ** kernel.
+ */
+ return 1;
+#elif defined(SQLITE_WIN32_GETVERSIONEX) && SQLITE_WIN32_GETVERSIONEX
+ if( osInterlockedCompareExchange(&sqlite3_os_type, 0, 0)==0 ){
+#if defined(SQLITE_WIN32_HAS_ANSI)
+ OSVERSIONINFOA sInfo;
+ sInfo.dwOSVersionInfoSize = sizeof(sInfo);
+ osGetVersionExA(&sInfo);
+ osInterlockedCompareExchange(&sqlite3_os_type,
+ (sInfo.dwPlatformId == VER_PLATFORM_WIN32_NT) ? 2 : 1, 0);
+#elif defined(SQLITE_WIN32_HAS_WIDE)
+ OSVERSIONINFOW sInfo;
+ sInfo.dwOSVersionInfoSize = sizeof(sInfo);
+ osGetVersionExW(&sInfo);
+ osInterlockedCompareExchange(&sqlite3_os_type,
+ (sInfo.dwPlatformId == VER_PLATFORM_WIN32_NT) ? 2 : 1, 0);
+#endif
}
+ return osInterlockedCompareExchange(&sqlite3_os_type, 2, 2)==2;
+#elif SQLITE_TEST
+ return osInterlockedCompareExchange(&sqlite3_os_type, 2, 2)==2;
+#else
+ /*
+ ** NOTE: All sub-platforms where the GetVersionEx[AW] functions are
+ ** deprecated are always assumed to be based on the NT kernel.
+ */
+ return 1;
#endif
+}
#ifdef SQLITE_WIN32_MALLOC
/*
@@ -31184,12 +36175,12 @@ static void *winMemMalloc(int nBytes){
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) );
+ 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",
+ sqlite3_log(SQLITE_NOMEM, "failed to HeapAlloc %u bytes (%lu), heap=%p",
nBytes, osGetLastError(), (void*)hHeap);
}
return p;
@@ -31206,11 +36197,11 @@ static void winMemFree(void *pPrior){
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) );
+ 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",
+ sqlite3_log(SQLITE_NOMEM, "failed to HeapFree block %p (%lu), heap=%p",
pPrior, osGetLastError(), (void*)hHeap);
}
}
@@ -31227,7 +36218,7 @@ static void *winMemRealloc(void *pPrior, int nBytes){
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) );
+ assert( osHeapValidate(hHeap, SQLITE_WIN32_HEAP_FLAGS, pPrior) );
#endif
assert( nBytes>=0 );
if( !pPrior ){
@@ -31236,7 +36227,7 @@ static void *winMemRealloc(void *pPrior, int nBytes){
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",
+ sqlite3_log(SQLITE_NOMEM, "failed to %s %u bytes (%lu), heap=%p",
pPrior ? "HeapReAlloc" : "HeapAlloc", nBytes, osGetLastError(),
(void*)hHeap);
}
@@ -31255,12 +36246,12 @@ static int winMemSize(void *p){
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) );
+ assert( osHeapValidate(hHeap, SQLITE_WIN32_HEAP_FLAGS, p) );
#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",
+ sqlite3_log(SQLITE_NOMEM, "failed to HeapSize block %p (%lu), heap=%p",
p, osGetLastError(), (void*)hHeap);
return 0;
}
@@ -31281,18 +36272,25 @@ static int winMemInit(void *pAppData){
winMemData *pWinMemData = (winMemData *)pAppData;
if( !pWinMemData ) return SQLITE_ERROR;
- assert( pWinMemData->magic==WINMEM_MAGIC );
+ assert( pWinMemData->magic1==WINMEM_MAGIC1 );
+ assert( pWinMemData->magic2==WINMEM_MAGIC2 );
#if !SQLITE_OS_WINRT && SQLITE_WIN32_HEAP_CREATE
if( !pWinMemData->hHeap ){
+ DWORD dwInitialSize = SQLITE_WIN32_HEAP_INIT_SIZE;
+ DWORD dwMaximumSize = (DWORD)sqlite3GlobalConfig.nHeap;
+ if( dwMaximumSize==0 ){
+ dwMaximumSize = SQLITE_WIN32_HEAP_MAX_SIZE;
+ }else if( dwInitialSize>dwMaximumSize ){
+ dwInitialSize = dwMaximumSize;
+ }
pWinMemData->hHeap = osHeapCreate(SQLITE_WIN32_HEAP_FLAGS,
- SQLITE_WIN32_HEAP_INIT_SIZE,
- SQLITE_WIN32_HEAP_MAX_SIZE);
+ dwInitialSize, dwMaximumSize);
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);
+ "failed to HeapCreate (%lu), flags=%u, initSize=%lu, maxSize=%lu",
+ osGetLastError(), SQLITE_WIN32_HEAP_FLAGS, dwInitialSize,
+ dwMaximumSize);
return SQLITE_NOMEM;
}
pWinMemData->bOwned = TRUE;
@@ -31302,7 +36300,7 @@ static int winMemInit(void *pAppData){
pWinMemData->hHeap = osGetProcessHeap();
if( !pWinMemData->hHeap ){
sqlite3_log(SQLITE_NOMEM,
- "failed to GetProcessHeap (%d)", osGetLastError());
+ "failed to GetProcessHeap (%lu)", osGetLastError());
return SQLITE_NOMEM;
}
pWinMemData->bOwned = FALSE;
@@ -31323,6 +36321,9 @@ static void winMemShutdown(void *pAppData){
winMemData *pWinMemData = (winMemData *)pAppData;
if( !pWinMemData ) return;
+ assert( pWinMemData->magic1==WINMEM_MAGIC1 );
+ assert( pWinMemData->magic2==WINMEM_MAGIC2 );
+
if( pWinMemData->hHeap ){
assert( pWinMemData->hHeap!=INVALID_HANDLE_VALUE );
#if !SQLITE_OS_WINRT && defined(SQLITE_WIN32_MALLOC_VALIDATE)
@@ -31330,7 +36331,7 @@ static void winMemShutdown(void *pAppData){
#endif
if( pWinMemData->bOwned ){
if( !osHeapDestroy(pWinMemData->hHeap) ){
- sqlite3_log(SQLITE_NOMEM, "failed to HeapDestroy (%d), heap=%p",
+ sqlite3_log(SQLITE_NOMEM, "failed to HeapDestroy (%lu), heap=%p",
osGetLastError(), (void*)pWinMemData->hHeap);
}
pWinMemData->bOwned = FALSE;
@@ -31367,11 +36368,11 @@ SQLITE_PRIVATE void sqlite3MemSetDefault(void){
#endif /* SQLITE_WIN32_MALLOC */
/*
-** Convert a UTF-8 string to Microsoft Unicode (UTF-16?).
+** 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){
+static LPWSTR winUtf8ToUnicode(const char *zFilename){
int nChar;
LPWSTR zWideFilename;
@@ -31396,7 +36397,7 @@ static LPWSTR utf8ToUnicode(const char *zFilename){
** Convert Microsoft Unicode to UTF-8. Space to hold the returned string is
** obtained from sqlite3_malloc().
*/
-static char *unicodeToUtf8(LPCWSTR zWideFilename){
+static char *winUnicodeToUtf8(LPCWSTR zWideFilename){
int nByte;
char *zFilename;
@@ -31420,11 +36421,11 @@ static char *unicodeToUtf8(LPCWSTR zWideFilename){
/*
** 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){
+static LPWSTR winMbcsToUnicode(const char *zFilename){
int nByte;
LPWSTR zMbcsFilename;
int codepage = osAreFileApisANSI() ? CP_ACP : CP_OEMCP;
@@ -31454,7 +36455,7 @@ static LPWSTR mbcsToUnicode(const char *zFilename){
** Space to hold the returned string is obtained from
** sqlite3_malloc().
*/
-static char *unicodeToMbcs(LPCWSTR zWideFilename){
+static char *winUnicodeToMbcs(LPCWSTR zWideFilename){
int nByte;
char *zFilename;
int codepage = osAreFileApisANSI() ? CP_ACP : CP_OEMCP;
@@ -31480,32 +36481,32 @@ static char *unicodeToMbcs(LPCWSTR zWideFilename){
** 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){
+SQLITE_API char *SQLITE_STDCALL sqlite3_win32_mbcs_to_utf8(const char *zFilename){
char *zFilenameUtf8;
LPWSTR zTmpWide;
- zTmpWide = mbcsToUnicode(zFilename);
+ zTmpWide = winMbcsToUnicode(zFilename);
if( zTmpWide==0 ){
return 0;
}
- zFilenameUtf8 = unicodeToUtf8(zTmpWide);
+ zFilenameUtf8 = winUnicodeToUtf8(zTmpWide);
sqlite3_free(zTmpWide);
return zFilenameUtf8;
}
/*
-** Convert UTF-8 to multibyte character string. Space to hold the
+** 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){
+SQLITE_API char *SQLITE_STDCALL sqlite3_win32_utf8_to_mbcs(const char *zFilename){
char *zFilenameMbcs;
LPWSTR zTmpWide;
- zTmpWide = utf8ToUnicode(zFilename);
+ zTmpWide = winUtf8ToUnicode(zFilename);
if( zTmpWide==0 ){
return 0;
}
- zFilenameMbcs = unicodeToMbcs(zTmpWide);
+ zFilenameMbcs = winUnicodeToMbcs(zTmpWide);
sqlite3_free(zTmpWide);
return zFilenameMbcs;
}
@@ -31517,7 +36518,7 @@ SQLITE_API char *sqlite3_win32_utf8_to_mbcs(const char *zFilename){
** 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){
+SQLITE_API int SQLITE_STDCALL sqlite3_win32_set_directory(DWORD type, LPCWSTR zValue){
char **ppDirectory = 0;
#ifndef SQLITE_OMIT_AUTOINIT
int rc = sqlite3_initialize();
@@ -31535,7 +36536,7 @@ SQLITE_API int sqlite3_win32_set_directory(DWORD type, LPCWSTR zValue){
if( ppDirectory ){
char *zValueUtf8 = 0;
if( zValue && zValue[0] ){
- zValueUtf8 = unicodeToUtf8(zValue);
+ zValueUtf8 = winUnicodeToUtf8(zValue);
if ( zValueUtf8==0 ){
return SQLITE_NOMEM;
}
@@ -31548,11 +36549,11 @@ SQLITE_API int sqlite3_win32_set_directory(DWORD type, LPCWSTR zValue){
}
/*
-** The return value of getLastErrorMsg
+** The return value of winGetLastErrorMsg
** 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){
+static int winGetLastErrorMsg(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.
@@ -31560,16 +36561,16 @@ static int getLastErrorMsg(DWORD lastErrno, int nBuf, char *zBuf){
DWORD dwLen = 0;
char *zOut = 0;
- if( isNT() ){
+ if( osIsNT() ){
#if SQLITE_OS_WINRT
- WCHAR zTempWide[MAX_PATH+1]; /* NOTE: Somewhat arbitrary. */
+ WCHAR zTempWide[SQLITE_WIN32_MAX_ERRMSG_CHARS+1];
dwLen = osFormatMessageW(FORMAT_MESSAGE_FROM_SYSTEM |
FORMAT_MESSAGE_IGNORE_INSERTS,
NULL,
lastErrno,
0,
zTempWide,
- MAX_PATH,
+ SQLITE_WIN32_MAX_ERRMSG_CHARS,
0);
#else
LPWSTR zTempWide = NULL;
@@ -31586,7 +36587,7 @@ static int getLastErrorMsg(DWORD lastErrno, int nBuf, char *zBuf){
if( dwLen > 0 ){
/* allocate a buffer and convert to UTF8 */
sqlite3BeginBenignMalloc();
- zOut = unicodeToUtf8(zTempWide);
+ zOut = winUnicodeToUtf8(zTempWide);
sqlite3EndBenignMalloc();
#if !SQLITE_OS_WINRT
/* free the system buffer allocated by FormatMessage */
@@ -31617,7 +36618,7 @@ static int getLastErrorMsg(DWORD lastErrno, int nBuf, char *zBuf){
}
#endif
if( 0 == dwLen ){
- sqlite3_snprintf(nBuf, zBuf, "OsError 0x%x (%u)", lastErrno, lastErrno);
+ sqlite3_snprintf(nBuf, zBuf, "OsError 0x%lx (%lu)", lastErrno, lastErrno);
}else{
/* copy a maximum of nBuf chars to output buffer */
sqlite3_snprintf(nBuf, zBuf, "%s", zOut);
@@ -31634,11 +36635,11 @@ static int getLastErrorMsg(DWORD lastErrno, int nBuf, char *zBuf){
**
** 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
+** 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).
+** 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.
*/
@@ -31654,13 +36655,13 @@ static int winLogErrorAtLine(
int i; /* Loop counter */
zMsg[0] = 0;
- getLastErrorMsg(lastErrno, sizeof(zMsg), zMsg);
+ winGetLastErrorMsg(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",
+ "os_win.c:%d: (%lu) %s(%s) - %s",
iLine, lastErrno, zFunc, zPath, zMsg
);
@@ -31669,7 +36670,7 @@ static int winLogErrorAtLine(
/*
** The number of times that a ReadFile(), WriteFile(), and DeleteFile()
-** will be retried following a locking error - probably caused by
+** 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.
*/
@@ -31679,29 +36680,60 @@ static int winLogErrorAtLine(
#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;
+static int winIoerrRetry = SQLITE_WIN32_IOERR_RETRY;
+static int winIoerrRetryDelay = SQLITE_WIN32_IOERR_RETRY_DELAY;
+
+/*
+** The "winIoerrCanRetry1" macro is used to determine if a particular I/O
+** error code obtained via GetLastError() is eligible to be retried. It
+** must accept the error code DWORD as its only argument and should return
+** non-zero if the error code is transient in nature and the operation
+** responsible for generating the original error might succeed upon being
+** retried. The argument to this macro should be a variable.
+**
+** Additionally, a macro named "winIoerrCanRetry2" may be defined. If it
+** is defined, it will be consulted only when the macro "winIoerrCanRetry1"
+** returns zero. The "winIoerrCanRetry2" macro is completely optional and
+** may be used to include additional error codes in the set that should
+** result in the failing I/O operation being retried by the caller. If
+** defined, the "winIoerrCanRetry2" macro must exhibit external semantics
+** identical to those of the "winIoerrCanRetry1" macro.
+*/
+#if !defined(winIoerrCanRetry1)
+#define winIoerrCanRetry1(a) (((a)==ERROR_ACCESS_DENIED) || \
+ ((a)==ERROR_SHARING_VIOLATION) || \
+ ((a)==ERROR_LOCK_VIOLATION) || \
+ ((a)==ERROR_DEV_NOT_EXIST) || \
+ ((a)==ERROR_NETNAME_DELETED) || \
+ ((a)==ERROR_SEM_TIMEOUT) || \
+ ((a)==ERROR_NETWORK_UNREACHABLE))
+#endif
/*
** 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){
+static int winRetryIoerr(int *pnRetry, DWORD *pError){
DWORD e = osGetLastError();
- if( *pnRetry>=win32IoerrRetry ){
+ if( *pnRetry>=winIoerrRetry ){
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));
+ if( winIoerrCanRetry1(e) ){
+ sqlite3_win32_sleep(winIoerrRetryDelay*(1+*pnRetry));
++*pnRetry;
return 1;
}
+#if defined(winIoerrCanRetry2)
+ else if( winIoerrCanRetry2(e) ){
+ sqlite3_win32_sleep(winIoerrRetryDelay*(1+*pnRetry));
+ ++*pnRetry;
+ return 1;
+ }
+#endif
if( pError ){
*pError = e;
}
@@ -31711,11 +36743,11 @@ static int retryIoerr(int *pnRetry, DWORD *pError){
/*
** Log a I/O error retry episode.
*/
-static void logIoerr(int nRetry){
+static void winLogIoerr(int nRetry, int lineno){
if( nRetry ){
- sqlite3_log(SQLITE_IOERR,
- "delayed %dms for lock/sharing conflict",
- win32IoerrRetryDelay*nRetry*(nRetry+1)/2
+ sqlite3_log(SQLITE_NOTICE,
+ "delayed %dms for lock/sharing conflict at line %d",
+ winIoerrRetryDelay*nRetry*(nRetry+1)/2, lineno
);
}
}
@@ -31724,9 +36756,10 @@ static void logIoerr(int nRetry){
/*************************************************************************
** This section contains code for WinCE only.
*/
+#if !defined(SQLITE_MSVC_LOCALTIME_API) || !SQLITE_MSVC_LOCALTIME_API
/*
-** Windows CE does not have a localtime() function. So create a
-** substitute.
+** The MSVC CRT on Windows CE may not have a localtime() function. So
+** create a substitute.
*/
/* #include <time.h> */
struct tm *__cdecl localtime(const time_t *t)
@@ -31750,6 +36783,7 @@ struct tm *__cdecl localtime(const time_t *t)
y.tm_sec = pTm.wSecond;
return &y;
}
+#endif
#define HANDLE_TO_WINFILE(a) (winFile*)&((char*)a)[-(int)offsetof(winFile,h)]
@@ -31771,15 +36805,17 @@ static void winceMutexAcquire(HANDLE h){
** Create the mutex and shared memory used for locking in the file
** descriptor pFile
*/
-static BOOL winceCreateLock(const char *zFilename, winFile *pFile){
+static int winceCreateLock(const char *zFilename, winFile *pFile){
LPWSTR zTok;
LPWSTR zName;
+ DWORD lastErrno;
+ BOOL bLogged = FALSE;
BOOL bInit = TRUE;
- zName = utf8ToUnicode(zFilename);
+ zName = winUtf8ToUnicode(zFilename);
if( zName==0 ){
/* out of memory */
- return FALSE;
+ return SQLITE_IOERR_NOMEM;
}
/* Initialize the local lockdata */
@@ -31796,60 +36832,68 @@ static BOOL winceCreateLock(const char *zFilename, winFile *pFile){
pFile->hMutex = osCreateMutexW(NULL, FALSE, zName);
if (!pFile->hMutex){
pFile->lastErrno = osGetLastError();
- winLogError(SQLITE_ERROR, pFile->lastErrno, "winceCreateLock1", zFilename);
sqlite3_free(zName);
- return FALSE;
+ return winLogError(SQLITE_IOERR, pFile->lastErrno,
+ "winceCreateLock1", zFilename);
}
/* Acquire the mutex before continuing */
winceMutexAcquire(pFile->hMutex);
-
- /* Since the names of named mutexes, semaphores, file mappings etc are
+
+ /* 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);
+ zName);
- /* Set a flag that indicates we're the first to create the memory so it
+ /* Set a flag that indicates we're the first to create the memory so it
** must be zero-initialized */
- if (osGetLastError() == ERROR_ALREADY_EXISTS){
+ lastErrno = osGetLastError();
+ if (lastErrno == 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,
+ 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){
+ if( !pFile->shared ){
pFile->lastErrno = osGetLastError();
- winLogError(SQLITE_ERROR, pFile->lastErrno,
- "winceCreateLock2", zFilename);
+ winLogError(SQLITE_IOERR, pFile->lastErrno,
+ "winceCreateLock2", zFilename);
+ bLogged = TRUE;
osCloseHandle(pFile->hShared);
pFile->hShared = NULL;
}
}
/* If shared memory could not be created, then close the mutex and fail */
- if (pFile->hShared == NULL){
+ if( pFile->hShared==NULL ){
+ if( !bLogged ){
+ pFile->lastErrno = lastErrno;
+ winLogError(SQLITE_IOERR, pFile->lastErrno,
+ "winceCreateLock3", zFilename);
+ bLogged = TRUE;
+ }
winceMutexRelease(pFile->hMutex);
osCloseHandle(pFile->hMutex);
pFile->hMutex = NULL;
- return FALSE;
+ return SQLITE_IOERR;
}
-
+
/* Initialize the shared memory if we're supposed to */
- if (bInit) {
+ if( bInit ){
memset(pFile->shared, 0, sizeof(winceLock));
}
winceMutexRelease(pFile->hMutex);
- return TRUE;
+ return SQLITE_OK;
}
/*
@@ -31880,13 +36924,13 @@ static void winceDestroyLock(winFile *pFile){
osCloseHandle(pFile->hShared);
/* Done with the mutex */
- winceMutexRelease(pFile->hMutex);
+ winceMutexRelease(pFile->hMutex);
osCloseHandle(pFile->hMutex);
pFile->hMutex = NULL;
}
}
-/*
+/*
** An implementation of the LockFile() API of Windows for CE
*/
static BOOL winceLockFile(
@@ -31928,7 +36972,8 @@ static BOOL winceLockFile(
}
/* Want a pending lock? */
- else if (dwFileOffsetLow == (DWORD)PENDING_BYTE && nNumberOfBytesToLockLow == 1){
+ 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;
@@ -31938,7 +36983,8 @@ static BOOL winceLockFile(
}
/* Want a reserved lock? */
- else if (dwFileOffsetLow == (DWORD)RESERVED_BYTE && nNumberOfBytesToLockLow == 1){
+ else if (dwFileOffsetLow == (DWORD)RESERVED_BYTE
+ && nNumberOfBytesToLockLow == 1){
if (pFile->shared->bReserved == 0) {
pFile->shared->bReserved = TRUE;
pFile->local.bReserved = TRUE;
@@ -31981,7 +37027,8 @@ static BOOL winceUnlockFile(
/* Did we just have a reader lock? */
else if (pFile->local.nReaders){
- assert(nNumberOfBytesToUnlockLow == (DWORD)SHARED_SIZE || nNumberOfBytesToUnlockLow == 1);
+ assert(nNumberOfBytesToUnlockLow == (DWORD)SHARED_SIZE
+ || nNumberOfBytesToUnlockLow == 1);
pFile->local.nReaders --;
if (pFile->local.nReaders == 0)
{
@@ -31992,7 +37039,8 @@ static BOOL winceUnlockFile(
}
/* Releasing a pending lock */
- else if (dwFileOffsetLow == (DWORD)PENDING_BYTE && nNumberOfBytesToUnlockLow == 1){
+ else if (dwFileOffsetLow == (DWORD)PENDING_BYTE
+ && nNumberOfBytesToUnlockLow == 1){
if (pFile->local.bPending){
pFile->local.bPending = FALSE;
pFile->shared->bPending = FALSE;
@@ -32000,7 +37048,8 @@ static BOOL winceUnlockFile(
}
}
/* Releasing a reserved lock */
- else if (dwFileOffsetLow == (DWORD)RESERVED_BYTE && nNumberOfBytesToUnlockLow == 1){
+ else if (dwFileOffsetLow == (DWORD)RESERVED_BYTE
+ && nNumberOfBytesToUnlockLow == 1){
if (pFile->local.bReserved) {
pFile->local.bReserved = FALSE;
pFile->shared->bReserved = FALSE;
@@ -32035,7 +37084,7 @@ static BOOL winLockFile(
return winceLockFile(phFile, offsetLow, offsetHigh,
numBytesLow, numBytesHigh);
#else
- if( isNT() ){
+ if( osIsNT() ){
OVERLAPPED ovlp;
memset(&ovlp, 0, sizeof(OVERLAPPED));
ovlp.Offset = offsetLow;
@@ -32066,7 +37115,7 @@ static BOOL winUnlockFile(
return winceUnlockFile(phFile, offsetLow, offsetHigh,
numBytesLow, numBytesHigh);
#else
- if( isNT() ){
+ if( osIsNT() ){
OVERLAPPED ovlp;
memset(&ovlp, 0, sizeof(OVERLAPPED));
ovlp.Offset = offsetLow;
@@ -32092,25 +37141,27 @@ static BOOL winUnlockFile(
#endif
/*
-** Move the current position of the file handle passed as the first
-** argument to offset iOffset within the file. If successful, return 0.
+** 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){
+static int winSeekFile(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() */
+ OSTRACE(("SEEK file=%p, offset=%lld\n", pFile->h, iOffset));
+
upperBits = (LONG)((iOffset>>32) & 0x7fffffff);
lowerBits = (LONG)(iOffset & 0xffffffff);
- /* API oddity: If successful, SetFilePointer() returns a dword
+ /* 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
+ ** 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 occurred, it is also necessary to call
** GetLastError().
*/
dwRet = osSetFilePointer(pFile->h, lowerBits, &upperBits, FILE_BEGIN);
@@ -32119,10 +37170,12 @@ static int seekWinFile(winFile *pFile, sqlite3_int64 iOffset){
&& ((lastErrno = osGetLastError())!=NO_ERROR)) ){
pFile->lastErrno = lastErrno;
winLogError(SQLITE_IOERR_SEEK, pFile->lastErrno,
- "seekWinFile", pFile->zPath);
+ "winSeekFile", pFile->zPath);
+ OSTRACE(("SEEK file=%p, rc=SQLITE_IOERR_SEEK\n", pFile->h));
return 1;
}
+ OSTRACE(("SEEK file=%p, rc=SQLITE_OK\n", pFile->h));
return 0;
#else
/*
@@ -32138,14 +37191,22 @@ static int seekWinFile(winFile *pFile, sqlite3_int64 iOffset){
if(!bRet){
pFile->lastErrno = osGetLastError();
winLogError(SQLITE_IOERR_SEEK, pFile->lastErrno,
- "seekWinFile", pFile->zPath);
+ "winSeekFile", pFile->zPath);
+ OSTRACE(("SEEK file=%p, rc=SQLITE_IOERR_SEEK\n", pFile->h));
return 1;
}
+ OSTRACE(("SEEK file=%p, rc=SQLITE_OK\n", pFile->h));
return 0;
#endif
}
+#if SQLITE_MAX_MMAP_SIZE>0
+/* Forward references to VFS helper methods used for memory mapped files */
+static int winMapfile(winFile*, sqlite3_int64);
+static int winUnmapfile(winFile*);
+#endif
+
/*
** Close a file.
**
@@ -32165,7 +37226,14 @@ static int winClose(sqlite3_file *id){
#ifndef SQLITE_OMIT_WAL
assert( pFile->pShm==0 );
#endif
- OSTRACE(("CLOSE %d\n", pFile->h));
+ assert( pFile->h!=NULL && pFile->h!=INVALID_HANDLE_VALUE );
+ OSTRACE(("CLOSE pid=%lu, pFile=%p, file=%p\n",
+ osGetCurrentProcessId(), pFile, pFile->h));
+
+#if SQLITE_MAX_MMAP_SIZE>0
+ winUnmapfile(pFile);
+#endif
+
do{
rc = osCloseHandle(pFile->h);
/* SimulateIOError( rc=0; cnt=MX_CLOSE_ATTEMPT; ); */
@@ -32177,7 +37245,7 @@ static int winClose(sqlite3_file *id){
int cnt = 0;
while(
osDeleteFileW(pFile->zDeleteOnClose)==0
- && osGetFileAttributesW(pFile->zDeleteOnClose)!=0xffffffff
+ && osGetFileAttributesW(pFile->zDeleteOnClose)!=0xffffffff
&& cnt++ < WINCE_DELETION_ATTEMPTS
){
sqlite3_win32_sleep(100); /* Wait a little before trying again */
@@ -32185,11 +37253,12 @@ static int winClose(sqlite3_file *id){
sqlite3_free(pFile->zDeleteOnClose);
}
#endif
- OSTRACE(("CLOSE %d %s\n", pFile->h, rc ? "ok" : "failed"));
if( rc ){
pFile->h = NULL;
}
OpenCounter(-1);
+ OSTRACE(("CLOSE pid=%lu, pFile=%p, file=%p, rc=%s\n",
+ osGetCurrentProcessId(), pFile, pFile->h, rc ? "ok" : "failed"));
return rc ? SQLITE_OK
: winLogError(SQLITE_IOERR_CLOSE, osGetLastError(),
"winClose", pFile->zPath);
@@ -32206,7 +37275,7 @@ static int winRead(
int amt, /* Number of bytes to read */
sqlite3_int64 offset /* Begin reading at this offset */
){
-#if !SQLITE_OS_WINCE
+#if !SQLITE_OS_WINCE && !defined(SQLITE_WIN32_NO_OVERLAPPED)
OVERLAPPED overlapped; /* The offset for ReadFile. */
#endif
winFile *pFile = (winFile*)id; /* file handle */
@@ -32214,11 +37283,36 @@ static int winRead(
int nRetry = 0; /* Number of retrys */
assert( id!=0 );
+ assert( amt>0 );
+ assert( offset>=0 );
SimulateIOError(return SQLITE_IOERR_READ);
- OSTRACE(("READ %d lock=%d\n", pFile->h, pFile->locktype));
+ OSTRACE(("READ pid=%lu, pFile=%p, file=%p, buffer=%p, amount=%d, "
+ "offset=%lld, lock=%d\n", osGetCurrentProcessId(), pFile,
+ pFile->h, pBuf, amt, offset, pFile->locktype));
+
+#if SQLITE_MAX_MMAP_SIZE>0
+ /* Deal with as much of this read request as possible by transfering
+ ** data from the memory mapping using memcpy(). */
+ if( offset<pFile->mmapSize ){
+ if( offset+amt <= pFile->mmapSize ){
+ memcpy(pBuf, &((u8 *)(pFile->pMapRegion))[offset], amt);
+ OSTRACE(("READ-MMAP pid=%lu, pFile=%p, file=%p, rc=SQLITE_OK\n",
+ osGetCurrentProcessId(), pFile, pFile->h));
+ return SQLITE_OK;
+ }else{
+ int nCopy = (int)(pFile->mmapSize - offset);
+ memcpy(pBuf, &((u8 *)(pFile->pMapRegion))[offset], nCopy);
+ pBuf = &((u8 *)pBuf)[nCopy];
+ amt -= nCopy;
+ offset += nCopy;
+ }
+ }
+#endif
-#if SQLITE_OS_WINCE
- if( seekWinFile(pFile, offset) ){
+#if SQLITE_OS_WINCE || defined(SQLITE_WIN32_NO_OVERLAPPED)
+ if( winSeekFile(pFile, offset) ){
+ OSTRACE(("READ pid=%lu, pFile=%p, file=%p, rc=SQLITE_FULL\n",
+ osGetCurrentProcessId(), pFile, pFile->h));
return SQLITE_FULL;
}
while( !osReadFile(pFile->h, pBuf, amt, &nRead, 0) ){
@@ -32230,18 +37324,24 @@ static int winRead(
osGetLastError()!=ERROR_HANDLE_EOF ){
#endif
DWORD lastErrno;
- if( retryIoerr(&nRetry, &lastErrno) ) continue;
+ if( winRetryIoerr(&nRetry, &lastErrno) ) continue;
pFile->lastErrno = lastErrno;
+ OSTRACE(("READ pid=%lu, pFile=%p, file=%p, rc=SQLITE_IOERR_READ\n",
+ osGetCurrentProcessId(), pFile, pFile->h));
return winLogError(SQLITE_IOERR_READ, pFile->lastErrno,
- "winRead", pFile->zPath);
+ "winRead", pFile->zPath);
}
- logIoerr(nRetry);
+ winLogIoerr(nRetry, __LINE__);
if( nRead<(DWORD)amt ){
/* Unread parts of the buffer must be zero-filled */
memset(&((char*)pBuf)[nRead], 0, amt-nRead);
+ OSTRACE(("READ pid=%lu, pFile=%p, file=%p, rc=SQLITE_IOERR_SHORT_READ\n",
+ osGetCurrentProcessId(), pFile, pFile->h));
return SQLITE_IOERR_SHORT_READ;
}
+ OSTRACE(("READ pid=%lu, pFile=%p, file=%p, rc=SQLITE_OK\n",
+ osGetCurrentProcessId(), pFile, pFile->h));
return SQLITE_OK;
}
@@ -32255,7 +37355,7 @@ static int winWrite(
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 */
+ int rc = 0; /* True if error has occurred, else false */
winFile *pFile = (winFile*)id; /* File handle */
int nRetry = 0; /* Number of retries */
@@ -32264,15 +37364,36 @@ static int winWrite(
SimulateIOError(return SQLITE_IOERR_WRITE);
SimulateDiskfullError(return SQLITE_FULL);
- OSTRACE(("WRITE %d lock=%d\n", pFile->h, pFile->locktype));
+ OSTRACE(("WRITE pid=%lu, pFile=%p, file=%p, buffer=%p, amount=%d, "
+ "offset=%lld, lock=%d\n", osGetCurrentProcessId(), pFile,
+ pFile->h, pBuf, amt, offset, pFile->locktype));
+
+#if defined(SQLITE_MMAP_READWRITE) && SQLITE_MAX_MMAP_SIZE>0
+ /* Deal with as much of this write request as possible by transfering
+ ** data from the memory mapping using memcpy(). */
+ if( offset<pFile->mmapSize ){
+ if( offset+amt <= pFile->mmapSize ){
+ memcpy(&((u8 *)(pFile->pMapRegion))[offset], pBuf, amt);
+ OSTRACE(("WRITE-MMAP pid=%lu, pFile=%p, file=%p, rc=SQLITE_OK\n",
+ osGetCurrentProcessId(), pFile, pFile->h));
+ return SQLITE_OK;
+ }else{
+ int nCopy = (int)(pFile->mmapSize - offset);
+ memcpy(&((u8 *)(pFile->pMapRegion))[offset], pBuf, nCopy);
+ pBuf = &((u8 *)pBuf)[nCopy];
+ amt -= nCopy;
+ offset += nCopy;
+ }
+ }
+#endif
-#if SQLITE_OS_WINCE
- rc = seekWinFile(pFile, offset);
+#if SQLITE_OS_WINCE || defined(SQLITE_WIN32_NO_OVERLAPPED)
+ rc = winSeekFile(pFile, offset);
if( rc==0 ){
#else
{
#endif
-#if !SQLITE_OS_WINCE
+#if !SQLITE_OS_WINCE && !defined(SQLITE_WIN32_NO_OVERLAPPED)
OVERLAPPED overlapped; /* The offset for WriteFile. */
#endif
u8 *aRem = (u8 *)pBuf; /* Data yet to be written */
@@ -32280,19 +37401,19 @@ static int winWrite(
DWORD nWrite; /* Bytes written by each WriteFile() call */
DWORD lastErrno = NO_ERROR; /* Value returned by GetLastError() */
-#if !SQLITE_OS_WINCE
+#if !SQLITE_OS_WINCE && !defined(SQLITE_WIN32_NO_OVERLAPPED)
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 SQLITE_OS_WINCE || defined(SQLITE_WIN32_NO_OVERLAPPED)
if( !osWriteFile(pFile->h, aRem, nRem, &nWrite, 0) ){
#else
if( !osWriteFile(pFile->h, aRem, nRem, &nWrite, &overlapped) ){
#endif
- if( retryIoerr(&nRetry, &lastErrno) ) continue;
+ if( winRetryIoerr(&nRetry, &lastErrno) ) continue;
break;
}
assert( nWrite==0 || nWrite<=(DWORD)nRem );
@@ -32300,7 +37421,7 @@ static int winWrite(
lastErrno = osGetLastError();
break;
}
-#if !SQLITE_OS_WINCE
+#if !SQLITE_OS_WINCE && !defined(SQLITE_WIN32_NO_OVERLAPPED)
offset += nWrite;
overlapped.Offset = (LONG)(offset & 0xffffffff);
overlapped.OffsetHigh = (LONG)((offset>>32) & 0x7fffffff);
@@ -32317,13 +37438,20 @@ static int winWrite(
if( rc ){
if( ( pFile->lastErrno==ERROR_HANDLE_DISK_FULL )
|| ( pFile->lastErrno==ERROR_DISK_FULL )){
- return SQLITE_FULL;
+ OSTRACE(("WRITE pid=%lu, pFile=%p, file=%p, rc=SQLITE_FULL\n",
+ osGetCurrentProcessId(), pFile, pFile->h));
+ return winLogError(SQLITE_FULL, pFile->lastErrno,
+ "winWrite1", pFile->zPath);
}
+ OSTRACE(("WRITE pid=%lu, pFile=%p, file=%p, rc=SQLITE_IOERR_WRITE\n",
+ osGetCurrentProcessId(), pFile, pFile->h));
return winLogError(SQLITE_IOERR_WRITE, pFile->lastErrno,
- "winWrite", pFile->zPath);
+ "winWrite2", pFile->zPath);
}else{
- logIoerr(nRetry);
+ winLogIoerr(nRetry, __LINE__);
}
+ OSTRACE(("WRITE pid=%lu, pFile=%p, file=%p, rc=SQLITE_OK\n",
+ osGetCurrentProcessId(), pFile, pFile->h));
return SQLITE_OK;
}
@@ -32333,11 +37461,12 @@ static int winWrite(
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 */
+ DWORD lastErrno;
assert( pFile );
-
- OSTRACE(("TRUNCATE %d %lld\n", pFile->h, nByte));
SimulateIOError(return SQLITE_IOERR_TRUNCATE);
+ OSTRACE(("TRUNCATE pid=%lu, pFile=%p, file=%p, size=%lld, lock=%d\n",
+ osGetCurrentProcessId(), pFile, pFile->h, nByte, pFile->locktype));
/* 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
@@ -32349,16 +37478,28 @@ static int winTruncate(sqlite3_file *id, sqlite3_int64 nByte){
}
/* SetEndOfFile() returns non-zero when successful, or zero when it fails. */
- if( seekWinFile(pFile, nByte) ){
+ if( winSeekFile(pFile, nByte) ){
rc = winLogError(SQLITE_IOERR_TRUNCATE, pFile->lastErrno,
- "winTruncate1", pFile->zPath);
- }else if( 0==osSetEndOfFile(pFile->h) ){
- pFile->lastErrno = osGetLastError();
+ "winTruncate1", pFile->zPath);
+ }else if( 0==osSetEndOfFile(pFile->h) &&
+ ((lastErrno = osGetLastError())!=ERROR_USER_MAPPED_FILE) ){
+ pFile->lastErrno = lastErrno;
rc = winLogError(SQLITE_IOERR_TRUNCATE, pFile->lastErrno,
- "winTruncate2", pFile->zPath);
+ "winTruncate2", pFile->zPath);
+ }
+
+#if SQLITE_MAX_MMAP_SIZE>0
+ /* If the file was truncated to a size smaller than the currently
+ ** mapped region, reduce the effective mapping size as well. SQLite will
+ ** use read() and write() to access data beyond this point from now on.
+ */
+ if( pFile->pMapRegion && nByte<pFile->mmapSize ){
+ pFile->mmapSize = nByte;
}
+#endif
- OSTRACE(("TRUNCATE %d %lld %s\n", pFile->h, nByte, rc ? "failed" : "ok"));
+ OSTRACE(("TRUNCATE pid=%lu, pFile=%p, file=%p, rc=%s\n",
+ osGetCurrentProcessId(), pFile, pFile->h, sqlite3ErrName(rc)));
return rc;
}
@@ -32382,7 +37523,7 @@ static int winSync(sqlite3_file *id, int flags){
BOOL rc;
#endif
#if !defined(NDEBUG) || !defined(SQLITE_NO_SYNC) || \
- (defined(SQLITE_TEST) && defined(SQLITE_DEBUG))
+ defined(SQLITE_HAVE_OS_TRACE)
/*
** Used when SQLITE_NO_SYNC is not defined and by the assert() and/or
** OSTRACE() macros.
@@ -32398,13 +37539,15 @@ static int winSync(sqlite3_file *id, int flags){
|| (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 );
+ OSTRACE(("SYNC pid=%lu, pFile=%p, file=%p, flags=%x, lock=%d\n",
+ osGetCurrentProcessId(), pFile, pFile->h, flags,
+ pFile->locktype));
+
#ifndef SQLITE_TEST
UNUSED_PARAMETER(flags);
#else
@@ -32418,16 +37561,38 @@ static int winSync(sqlite3_file *id, int flags){
** no-op
*/
#ifdef SQLITE_NO_SYNC
+ OSTRACE(("SYNC-NOP pid=%lu, pFile=%p, file=%p, rc=SQLITE_OK\n",
+ osGetCurrentProcessId(), pFile, pFile->h));
return SQLITE_OK;
#else
+#if SQLITE_MAX_MMAP_SIZE>0
+ if( pFile->pMapRegion ){
+ if( osFlushViewOfFile(pFile->pMapRegion, 0) ){
+ OSTRACE(("SYNC-MMAP pid=%lu, pFile=%p, pMapRegion=%p, "
+ "rc=SQLITE_OK\n", osGetCurrentProcessId(),
+ pFile, pFile->pMapRegion));
+ }else{
+ pFile->lastErrno = osGetLastError();
+ OSTRACE(("SYNC-MMAP pid=%lu, pFile=%p, pMapRegion=%p, "
+ "rc=SQLITE_IOERR_MMAP\n", osGetCurrentProcessId(),
+ pFile, pFile->pMapRegion));
+ return winLogError(SQLITE_IOERR_MMAP, pFile->lastErrno,
+ "winSync1", pFile->zPath);
+ }
+ }
+#endif
rc = osFlushFileBuffers(pFile->h);
SimulateIOError( rc=FALSE );
if( rc ){
+ OSTRACE(("SYNC pid=%lu, pFile=%p, file=%p, rc=SQLITE_OK\n",
+ osGetCurrentProcessId(), pFile, pFile->h));
return SQLITE_OK;
}else{
pFile->lastErrno = osGetLastError();
+ OSTRACE(("SYNC pid=%lu, pFile=%p, file=%p, rc=SQLITE_IOERR_FSYNC\n",
+ osGetCurrentProcessId(), pFile, pFile->h));
return winLogError(SQLITE_IOERR_FSYNC, pFile->lastErrno,
- "winSync", pFile->zPath);
+ "winSync2", pFile->zPath);
}
#endif
}
@@ -32440,7 +37605,10 @@ static int winFileSize(sqlite3_file *id, sqlite3_int64 *pSize){
int rc = SQLITE_OK;
assert( id!=0 );
+ assert( pSize!=0 );
SimulateIOError(return SQLITE_IOERR_FSTAT);
+ OSTRACE(("SIZE file=%p, pSize=%p\n", pFile->h, pSize));
+
#if SQLITE_OS_WINRT
{
FILE_STANDARD_INFO info;
@@ -32465,10 +37633,12 @@ static int winFileSize(sqlite3_file *id, sqlite3_int64 *pSize){
&& ((lastErrno = osGetLastError())!=NO_ERROR) ){
pFile->lastErrno = lastErrno;
rc = winLogError(SQLITE_IOERR_FSTAT, pFile->lastErrno,
- "winFileSize", pFile->zPath);
+ "winFileSize", pFile->zPath);
}
}
#endif
+ OSTRACE(("SIZE file=%p, pSize=%p, *pSize=%lld, rc=%s\n",
+ pFile->h, pSize, *pSize, sqlite3ErrName(rc)));
return rc;
}
@@ -32508,9 +37678,10 @@ static int winFileSize(sqlite3_file *id, sqlite3_int64 *pSize){
** Different API routines are called depending on whether or not this
** is Win9x or WinNT.
*/
-static int getReadLock(winFile *pFile){
+static int winGetReadLock(winFile *pFile){
int res;
- if( isNT() ){
+ OSTRACE(("READ-LOCK file=%p, lock=%d\n", pFile->h, pFile->locktype));
+ if( osIsNT() ){
#if SQLITE_OS_WINCE
/*
** NOTE: Windows CE is handled differently here due its lack of the Win32
@@ -32535,16 +37706,18 @@ static int getReadLock(winFile *pFile){
pFile->lastErrno = osGetLastError();
/* No need to log a failure to lock */
}
+ OSTRACE(("READ-LOCK file=%p, result=%d\n", pFile->h, res));
return res;
}
/*
** Undo a readlock
*/
-static int unlockReadLock(winFile *pFile){
+static int winUnlockReadLock(winFile *pFile){
int res;
DWORD lastErrno;
- if( isNT() ){
+ OSTRACE(("READ-UNLOCK file=%p, lock=%d\n", pFile->h, pFile->locktype));
+ if( osIsNT() ){
res = winUnlockFile(&pFile->h, SHARED_FIRST, 0, SHARED_SIZE, 0);
}
#ifdef SQLITE_WIN32_HAS_ANSI
@@ -32555,8 +37728,9 @@ static int unlockReadLock(winFile *pFile){
if( res==0 && ((lastErrno = osGetLastError())!=ERROR_NOT_LOCKED) ){
pFile->lastErrno = lastErrno;
winLogError(SQLITE_IOERR_UNLOCK, pFile->lastErrno,
- "unlockReadLock", pFile->zPath);
+ "winUnlockReadLock", pFile->zPath);
}
+ OSTRACE(("READ-UNLOCK file=%p, result=%d\n", pFile->h, res));
return res;
}
@@ -32595,17 +37769,24 @@ static int winLock(sqlite3_file *id, int locktype){
DWORD lastErrno = NO_ERROR;
assert( id!=0 );
- OSTRACE(("LOCK %d %d was %d(%d)\n",
- pFile->h, locktype, pFile->locktype, pFile->sharedLockByte));
+ OSTRACE(("LOCK file=%p, oldLock=%d(%d), newLock=%d\n",
+ pFile->h, pFile->locktype, pFile->sharedLockByte, locktype));
/* 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 ){
+ OSTRACE(("LOCK-HELD file=%p, rc=SQLITE_OK\n", pFile->h));
return SQLITE_OK;
}
+ /* Do not allow any kind of write-lock on a read-only database
+ */
+ if( (pFile->ctrlFlags & WINFILE_RDONLY)!=0 && locktype>=RESERVED_LOCK ){
+ return SQLITE_IOERR_LOCK;
+ }
+
/* Make sure the locking sequence is correct
*/
assert( pFile->locktype!=NO_LOCK || locktype==SHARED_LOCK );
@@ -32630,7 +37811,16 @@ static int winLock(sqlite3_file *id, int locktype){
** 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));
+ lastErrno = osGetLastError();
+ OSTRACE(("LOCK-PENDING-FAIL file=%p, count=%d, result=%d\n",
+ pFile->h, cnt, res));
+ if( lastErrno==ERROR_INVALID_HANDLE ){
+ pFile->lastErrno = lastErrno;
+ rc = SQLITE_IOERR_LOCK;
+ OSTRACE(("LOCK-FAIL file=%p, count=%d, rc=%s\n",
+ pFile->h, cnt, sqlite3ErrName(rc)));
+ return rc;
+ }
if( cnt ) sqlite3_win32_sleep(1);
}
gotPendingLock = res;
@@ -32643,7 +37833,7 @@ static int winLock(sqlite3_file *id, int locktype){
*/
if( locktype==SHARED_LOCK && res ){
assert( pFile->locktype==NO_LOCK );
- res = getReadLock(pFile);
+ res = winGetReadLock(pFile);
if( res ){
newLocktype = SHARED_LOCK;
}else{
@@ -32674,16 +37864,14 @@ static int winLock(sqlite3_file *id, int locktype){
*/
if( locktype==EXCLUSIVE_LOCK && res ){
assert( pFile->locktype>=SHARED_LOCK );
- res = unlockReadLock(pFile);
- OSTRACE(("unreadlock = %d\n", res));
+ res = winUnlockReadLock(pFile);
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);
+ winGetReadLock(pFile);
}
}
@@ -32700,12 +37888,14 @@ static int winLock(sqlite3_file *id, int locktype){
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;
+ OSTRACE(("LOCK-FAIL file=%p, wanted=%d, got=%d\n",
+ pFile->h, locktype, newLocktype));
}
pFile->locktype = (u8)newLocktype;
+ OSTRACE(("LOCK file=%p, lock=%d, rc=%s\n",
+ pFile->h, pFile->locktype, sqlite3ErrName(rc)));
return rc;
}
@@ -32715,24 +37905,27 @@ static int winLock(sqlite3_file *id, int locktype){
** non-zero, otherwise zero.
*/
static int winCheckReservedLock(sqlite3_file *id, int *pResOut){
- int rc;
+ int res;
winFile *pFile = (winFile*)id;
SimulateIOError( return SQLITE_IOERR_CHECKRESERVEDLOCK; );
+ OSTRACE(("TEST-WR-LOCK file=%p, pResOut=%p\n", pFile->h, pResOut));
assert( id!=0 );
if( pFile->locktype>=RESERVED_LOCK ){
- rc = 1;
- OSTRACE(("TEST WR-LOCK %d %d (local)\n", pFile->h, rc));
+ res = 1;
+ OSTRACE(("TEST-WR-LOCK file=%p, result=%d (local)\n", pFile->h, res));
}else{
- rc = winLockFile(&pFile->h, SQLITE_LOCKFILE_FLAGS, RESERVED_BYTE, 0, 1, 0);
- if( rc ){
+ res = winLockFile(&pFile->h, SQLITE_LOCKFILEEX_FLAGS,RESERVED_BYTE,0,1,0);
+ if( res ){
winUnlockFile(&pFile->h, RESERVED_BYTE, 0, 1, 0);
}
- rc = !rc;
- OSTRACE(("TEST WR-LOCK %d %d (remote)\n", pFile->h, rc));
+ res = !res;
+ OSTRACE(("TEST-WR-LOCK file=%p, result=%d (remote)\n", pFile->h, res));
}
- *pResOut = rc;
+ *pResOut = res;
+ OSTRACE(("TEST-WR-LOCK file=%p, pResOut=%p, *pResOut=%d, rc=SQLITE_OK\n",
+ pFile->h, pResOut, *pResOut));
return SQLITE_OK;
}
@@ -32753,33 +37946,35 @@ static int winUnlock(sqlite3_file *id, int locktype){
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));
+ OSTRACE(("UNLOCK file=%p, oldLock=%d(%d), newLock=%d\n",
+ pFile->h, pFile->locktype, pFile->sharedLockByte, locktype));
type = pFile->locktype;
if( type>=EXCLUSIVE_LOCK ){
winUnlockFile(&pFile->h, SHARED_FIRST, 0, SHARED_SIZE, 0);
- if( locktype==SHARED_LOCK && !getReadLock(pFile) ){
+ if( locktype==SHARED_LOCK && !winGetReadLock(pFile) ){
/* This should never happen. We should always be able to
** reacquire the read lock */
rc = winLogError(SQLITE_IOERR_UNLOCK, osGetLastError(),
- "winUnlock", pFile->zPath);
+ "winUnlock", pFile->zPath);
}
}
if( type>=RESERVED_LOCK ){
winUnlockFile(&pFile->h, RESERVED_BYTE, 0, 1, 0);
}
if( locktype==NO_LOCK && type>=SHARED_LOCK ){
- unlockReadLock(pFile);
+ winUnlockReadLock(pFile);
}
if( type>=PENDING_LOCK ){
winUnlockFile(&pFile->h, PENDING_BYTE, 0, 1, 0);
}
pFile->locktype = (u8)locktype;
+ OSTRACE(("UNLOCK file=%p, lock=%d, rc=%s\n",
+ pFile->h, pFile->locktype, sqlite3ErrName(rc)));
return rc;
}
/*
-** If *pArg is inititially negative then this is a query. Set *pArg to
+** If *pArg is initially 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.
@@ -32794,25 +37989,31 @@ static void winModeBit(winFile *pFile, unsigned char mask, int *pArg){
}
}
-/* Forward declaration */
-static int getTempname(int nBuf, char *zBuf);
+/* Forward references to VFS helper methods used for temporary files */
+static int winGetTempname(sqlite3_vfs *, char **);
+static int winIsDir(const void *);
+static BOOL winIsDriveLetterAndColon(const char *);
/*
** Control and query of the open file handle.
*/
static int winFileControl(sqlite3_file *id, int op, void *pArg){
winFile *pFile = (winFile*)id;
+ OSTRACE(("FCNTL file=%p, op=%d, pArg=%p\n", pFile->h, op, pArg));
switch( op ){
case SQLITE_FCNTL_LOCKSTATE: {
*(int*)pArg = pFile->locktype;
+ OSTRACE(("FCNTL file=%p, rc=SQLITE_OK\n", pFile->h));
return SQLITE_OK;
}
case SQLITE_LAST_ERRNO: {
*(int*)pArg = (int)pFile->lastErrno;
+ OSTRACE(("FCNTL file=%p, rc=SQLITE_OK\n", pFile->h));
return SQLITE_OK;
}
case SQLITE_FCNTL_CHUNK_SIZE: {
pFile->szChunk = *(int *)pArg;
+ OSTRACE(("FCNTL file=%p, rc=SQLITE_OK\n", pFile->h));
return SQLITE_OK;
}
case SQLITE_FCNTL_SIZE_HINT: {
@@ -32827,45 +38028,83 @@ static int winFileControl(sqlite3_file *id, int op, void *pArg){
SimulateIOErrorBenign(0);
}
}
+ OSTRACE(("FCNTL file=%p, rc=%s\n", pFile->h, sqlite3ErrName(rc)));
return rc;
}
+ OSTRACE(("FCNTL file=%p, rc=SQLITE_OK\n", pFile->h));
return SQLITE_OK;
}
case SQLITE_FCNTL_PERSIST_WAL: {
winModeBit(pFile, WINFILE_PERSIST_WAL, (int*)pArg);
+ OSTRACE(("FCNTL file=%p, rc=SQLITE_OK\n", pFile->h));
return SQLITE_OK;
}
case SQLITE_FCNTL_POWERSAFE_OVERWRITE: {
winModeBit(pFile, WINFILE_PSOW, (int*)pArg);
+ OSTRACE(("FCNTL file=%p, rc=SQLITE_OK\n", pFile->h));
return SQLITE_OK;
}
case SQLITE_FCNTL_VFSNAME: {
- *(char**)pArg = sqlite3_mprintf("win32");
+ *(char**)pArg = sqlite3_mprintf("%s", pFile->pVfs->zName);
+ OSTRACE(("FCNTL file=%p, rc=SQLITE_OK\n", pFile->h));
return SQLITE_OK;
}
case SQLITE_FCNTL_WIN32_AV_RETRY: {
int *a = (int*)pArg;
if( a[0]>0 ){
- win32IoerrRetry = a[0];
+ winIoerrRetry = a[0];
}else{
- a[0] = win32IoerrRetry;
+ a[0] = winIoerrRetry;
}
if( a[1]>0 ){
- win32IoerrRetryDelay = a[1];
+ winIoerrRetryDelay = a[1];
}else{
- a[1] = win32IoerrRetryDelay;
+ a[1] = winIoerrRetryDelay;
}
+ OSTRACE(("FCNTL file=%p, rc=SQLITE_OK\n", pFile->h));
+ return SQLITE_OK;
+ }
+#ifdef SQLITE_TEST
+ case SQLITE_FCNTL_WIN32_SET_HANDLE: {
+ LPHANDLE phFile = (LPHANDLE)pArg;
+ HANDLE hOldFile = pFile->h;
+ pFile->h = *phFile;
+ *phFile = hOldFile;
+ OSTRACE(("FCNTL oldFile=%p, newFile=%p, rc=SQLITE_OK\n",
+ hOldFile, pFile->h));
return SQLITE_OK;
}
+#endif
case SQLITE_FCNTL_TEMPFILENAME: {
- char *zTFile = sqlite3_malloc( pFile->pVfs->mxPathname );
- if( zTFile ){
- getTempname(pFile->pVfs->mxPathname, zTFile);
+ char *zTFile = 0;
+ int rc = winGetTempname(pFile->pVfs, &zTFile);
+ if( rc==SQLITE_OK ){
*(char**)pArg = zTFile;
}
- return SQLITE_OK;
+ OSTRACE(("FCNTL file=%p, rc=%s\n", pFile->h, sqlite3ErrName(rc)));
+ return rc;
}
+#if SQLITE_MAX_MMAP_SIZE>0
+ case SQLITE_FCNTL_MMAP_SIZE: {
+ i64 newLimit = *(i64*)pArg;
+ int rc = SQLITE_OK;
+ if( newLimit>sqlite3GlobalConfig.mxMmap ){
+ newLimit = sqlite3GlobalConfig.mxMmap;
+ }
+ *(i64*)pArg = pFile->mmapSizeMax;
+ if( newLimit>=0 && newLimit!=pFile->mmapSizeMax && pFile->nFetchOut==0 ){
+ pFile->mmapSizeMax = newLimit;
+ if( pFile->mmapSize>0 ){
+ winUnmapfile(pFile);
+ rc = winMapfile(pFile, -1);
+ }
+ }
+ OSTRACE(("FCNTL file=%p, rc=%s\n", pFile->h, sqlite3ErrName(rc)));
+ return rc;
+ }
+#endif
}
+ OSTRACE(("FCNTL file=%p, rc=SQLITE_NOTFOUND\n", pFile->h));
return SQLITE_NOTFOUND;
}
@@ -32893,23 +38132,23 @@ static int winDeviceCharacteristics(sqlite3_file *id){
((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;
+static SYSTEM_INFO winSysInfo;
+
+#ifndef SQLITE_OMIT_WAL
/*
** Helper functions to obtain and relinquish the global mutex. The
-** global mutex is used to protect the winLockInfo objects used by
+** 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()
+** 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()
@@ -32917,14 +38156,14 @@ SYSTEM_INFO winSysInfo;
** winShmLeaveMutex()
*/
static void winShmEnterMutex(void){
- sqlite3_mutex_enter(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER));
+ sqlite3_mutex_enter(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_VFS1));
}
static void winShmLeaveMutex(void){
- sqlite3_mutex_leave(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER));
+ sqlite3_mutex_leave(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_VFS1));
}
-#ifdef SQLITE_DEBUG
+#ifndef NDEBUG
static int winShmMutexHeld(void) {
- return sqlite3_mutex_held(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER));
+ return sqlite3_mutex_held(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_VFS1));
}
#endif
@@ -32939,10 +38178,10 @@ static int winShmMutexHeld(void) {
** this object or while reading or writing the following fields:
**
** nRef
-** pNext
+** pNext
**
** The following fields are read-only after the object is created:
-**
+**
** fid
** zFilename
**
@@ -32967,7 +38206,7 @@ struct winShmNode {
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
+#if defined(SQLITE_DEBUG) || defined(SQLITE_HAVE_OS_TRACE)
u8 nextShmId; /* Next available winShm.id value */
#endif
};
@@ -32998,7 +38237,7 @@ struct winShm {
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
+#if defined(SQLITE_DEBUG) || defined(SQLITE_HAVE_OS_TRACE)
u8 id; /* Id of this connection with its winShmNode */
#endif
};
@@ -33026,6 +38265,9 @@ static int winShmSystemLock(
/* Access to the winShmNode object is serialized by the caller */
assert( sqlite3_mutex_held(pFile->mutex) || pFile->nRef==0 );
+ OSTRACE(("SHM-LOCK file=%p, lock=%d, offset=%d, size=%d\n",
+ pFile->hFile.h, lockType, ofst, nByte));
+
/* Release/Acquire the system-level lock */
if( lockType==_SHM_UNLCK ){
rc = winUnlockFile(&pFile->hFile.h, ofst, 0, nByte, 0);
@@ -33035,7 +38277,7 @@ static int winShmSystemLock(
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{
@@ -33043,11 +38285,9 @@ static int winShmSystemLock(
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));
+ OSTRACE(("SHM-LOCK file=%p, func=%s, errno=%lu, rc=%s\n",
+ pFile->hFile.h, (lockType == _SHM_UNLCK) ? "winUnlockFile" :
+ "winLockFile", pFile->lastErrno, sqlite3ErrName(rc)));
return rc;
}
@@ -33065,24 +38305,25 @@ static int winDelete(sqlite3_vfs *,const char*,int);
static void winShmPurge(sqlite3_vfs *pVfs, int deleteFlag){
winShmNode **pp;
winShmNode *p;
- BOOL bRc;
assert( winShmMutexHeld() );
+ OSTRACE(("SHM-PURGE pid=%lu, deleteFlag=%d\n",
+ osGetCurrentProcessId(), deleteFlag));
pp = &winShmNodeList;
while( (p = *pp)!=0 ){
if( p->nRef==0 ){
int i;
- if( p->mutex ) sqlite3_mutex_free(p->mutex);
+ 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"));
+ BOOL bRc = osUnmapViewOfFile(p->aRegion[i].pMap);
+ OSTRACE(("SHM-PURGE-UNMAP pid=%lu, region=%d, rc=%s\n",
+ osGetCurrentProcessId(), i, bRc ? "ok" : "failed"));
+ UNUSED_VARIABLE_VALUE(bRc);
bRc = osCloseHandle(p->aRegion[i].hMap);
- OSTRACE(("SHM-PURGE pid-%d close region=%d %s\n",
- (int)osGetCurrentProcessId(), i,
- bRc ? "ok" : "failed"));
+ OSTRACE(("SHM-PURGE-CLOSE pid=%lu, region=%d, rc=%s\n",
+ osGetCurrentProcessId(), i, bRc ? "ok" : "failed"));
+ UNUSED_VARIABLE_VALUE(bRc);
}
- if( p->hFile.h != INVALID_HANDLE_VALUE ){
+ if( p->hFile.h!=NULL && p->hFile.h!=INVALID_HANDLE_VALUE ){
SimulateIOErrorBenign(1);
winClose((sqlite3_file *)&p->hFile);
SimulateIOErrorBenign(0);
@@ -33132,7 +38373,7 @@ static int winOpenSharedMemory(winFile *pDbFd){
}
pNew->zFilename = (char*)&pNew[1];
sqlite3_snprintf(nName+15, pNew->zFilename, "%s-shm", pDbFd->zPath);
- sqlite3FileSuffix3(pDbFd->zPath, pNew->zFilename);
+ 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.
@@ -33162,20 +38403,20 @@ static int winOpenSharedMemory(winFile *pDbFd){
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 */
+ SQLITE_OPEN_WAL | SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE,
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 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);
+ "winOpenShm", pDbFd->zPath);
}
}
if( rc==SQLITE_OK ){
@@ -33187,7 +38428,7 @@ static int winOpenSharedMemory(winFile *pDbFd){
/* Make the new connection a child of the winShmNode */
p->pShmNode = pShmNode;
-#ifdef SQLITE_DEBUG
+#if defined(SQLITE_DEBUG) || defined(SQLITE_HAVE_OS_TRACE)
p->id = pShmNode->nextShmId++;
#endif
pShmNode->nRef++;
@@ -33198,7 +38439,7 @@ static int winOpenSharedMemory(winFile *pDbFd){
** 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
+ ** at pShmNode->pFirst. This must be done while holding the pShmNode->mutex
** mutex.
*/
sqlite3_mutex_enter(pShmNode->mutex);
@@ -33218,7 +38459,7 @@ shm_open_err:
}
/*
-** Close a connection to shared-memory. Delete the underlying
+** Close a connection to shared-memory. Delete the underlying
** storage if deleteFlag is true.
*/
static int winShmUnmap(
@@ -33307,7 +38548,7 @@ static int winShmLock(
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" */
@@ -33346,7 +38587,7 @@ static int winShmLock(
break;
}
}
-
+
/* Get the exclusive locks at the system level. Then if successful
** also mark the local connection as being locked.
*/
@@ -33359,14 +38600,14 @@ static int winShmLock(
}
}
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"));
+ OSTRACE(("SHM-LOCK pid=%lu, id=%d, sharedMask=%03x, exclMask=%03x, rc=%s\n",
+ osGetCurrentProcessId(), p->id, p->sharedMask, p->exclMask,
+ sqlite3ErrName(rc)));
return rc;
}
/*
-** Implement a memory barrier or memory fence on shared memory.
+** 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.
@@ -33375,28 +38616,28 @@ static void winShmBarrier(
sqlite3_file *fd /* Database holding the shared memory */
){
UNUSED_PARAMETER(fd);
- /* MemoryBarrier(); // does not work -- do not know why not */
- winShmEnterMutex();
+ sqlite3MemoryBarrier(); /* compiler-defined memory barrier */
+ winShmEnterMutex(); /* Also mutex, for redundancy */
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
+** 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
+** 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
+** 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(
@@ -33407,16 +38648,16 @@ static int winShmMap(
void volatile **pp /* OUT: Mapped memory */
){
winFile *pDbFd = (winFile*)fd;
- winShm *p = pDbFd->pShm;
+ winShm *pShm = pDbFd->pShm;
winShmNode *pShmNode;
int rc = SQLITE_OK;
- if( !p ){
+ if( !pShm ){
rc = winOpenSharedMemory(pDbFd);
if( rc!=SQLITE_OK ) return rc;
- p = pDbFd->pShm;
+ pShm = pDbFd->pShm;
}
- pShmNode = p->pShmNode;
+ pShmNode = pShm->pShmNode;
sqlite3_mutex_enter(pShmNode->mutex);
assert( szRegion==pShmNode->szRegion || pShmNode->nRegion==0 );
@@ -33435,7 +38676,7 @@ static int winShmMap(
rc = winFileSize((sqlite3_file *)&pShmNode->hFile, &sz);
if( rc!=SQLITE_OK ){
rc = winLogError(SQLITE_IOERR_SHMSIZE, osGetLastError(),
- "winShmMap1", pDbFd->zPath);
+ "winShmMap1", pDbFd->zPath);
goto shmpage_out;
}
@@ -33450,13 +38691,13 @@ static int winShmMap(
rc = winTruncate((sqlite3_file *)&pShmNode->hFile, nByte);
if( rc!=SQLITE_OK ){
rc = winLogError(SQLITE_IOERR_SHMSIZE, osGetLastError(),
- "winShmMap2", pDbFd->zPath);
+ "winShmMap2", pDbFd->zPath);
goto shmpage_out;
}
}
/* Map the requested memory region into this processes address space. */
- apNew = (struct ShmRegion *)sqlite3_realloc(
+ apNew = (struct ShmRegion *)sqlite3_realloc64(
pShmNode->aRegion, (iRegion+1)*sizeof(apNew[0])
);
if( !apNew ){
@@ -33468,22 +38709,22 @@ static int winShmMap(
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,
+ hMap = osCreateFileMappingW(pShmNode->hFile.h,
NULL, PAGE_READWRITE, 0, nByte, NULL
);
#elif defined(SQLITE_WIN32_HAS_ANSI)
- hMap = osCreateFileMappingA(pShmNode->hFile.h,
+ 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,
+ OSTRACE(("SHM-MAP-CREATE pid=%lu, region=%d, size=%d, rc=%s\n",
+ osGetCurrentProcessId(), pShmNode->nRegion, nByte,
hMap ? "ok" : "failed"));
if( hMap ){
int iOffset = pShmNode->nRegion*szRegion;
@@ -33497,14 +38738,14 @@ static int winShmMap(
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,
+ OSTRACE(("SHM-MAP-MAP pid=%lu, region=%d, offset=%d, size=%d, rc=%s\n",
+ osGetCurrentProcessId(), pShmNode->nRegion, iOffset,
szRegion, pMap ? "ok" : "failed"));
}
if( !pMap ){
pShmNode->lastErrno = osGetLastError();
rc = winLogError(SQLITE_IOERR_SHMMAP, pShmNode->lastErrno,
- "winShmMap3", pDbFd->zPath);
+ "winShmMap3", pDbFd->zPath);
if( hMap ) osCloseHandle(hMap);
goto shmpage_out;
}
@@ -33536,6 +38777,233 @@ shmpage_out:
#endif /* #ifndef SQLITE_OMIT_WAL */
/*
+** Cleans up the mapped region of the specified file, if any.
+*/
+#if SQLITE_MAX_MMAP_SIZE>0
+static int winUnmapfile(winFile *pFile){
+ assert( pFile!=0 );
+ OSTRACE(("UNMAP-FILE pid=%lu, pFile=%p, hMap=%p, pMapRegion=%p, "
+ "mmapSize=%lld, mmapSizeActual=%lld, mmapSizeMax=%lld\n",
+ osGetCurrentProcessId(), pFile, pFile->hMap, pFile->pMapRegion,
+ pFile->mmapSize, pFile->mmapSizeActual, pFile->mmapSizeMax));
+ if( pFile->pMapRegion ){
+ if( !osUnmapViewOfFile(pFile->pMapRegion) ){
+ pFile->lastErrno = osGetLastError();
+ OSTRACE(("UNMAP-FILE pid=%lu, pFile=%p, pMapRegion=%p, "
+ "rc=SQLITE_IOERR_MMAP\n", osGetCurrentProcessId(), pFile,
+ pFile->pMapRegion));
+ return winLogError(SQLITE_IOERR_MMAP, pFile->lastErrno,
+ "winUnmapfile1", pFile->zPath);
+ }
+ pFile->pMapRegion = 0;
+ pFile->mmapSize = 0;
+ pFile->mmapSizeActual = 0;
+ }
+ if( pFile->hMap!=NULL ){
+ if( !osCloseHandle(pFile->hMap) ){
+ pFile->lastErrno = osGetLastError();
+ OSTRACE(("UNMAP-FILE pid=%lu, pFile=%p, hMap=%p, rc=SQLITE_IOERR_MMAP\n",
+ osGetCurrentProcessId(), pFile, pFile->hMap));
+ return winLogError(SQLITE_IOERR_MMAP, pFile->lastErrno,
+ "winUnmapfile2", pFile->zPath);
+ }
+ pFile->hMap = NULL;
+ }
+ OSTRACE(("UNMAP-FILE pid=%lu, pFile=%p, rc=SQLITE_OK\n",
+ osGetCurrentProcessId(), pFile));
+ return SQLITE_OK;
+}
+
+/*
+** Memory map or remap the file opened by file-descriptor pFd (if the file
+** is already mapped, the existing mapping is replaced by the new). Or, if
+** there already exists a mapping for this file, and there are still
+** outstanding xFetch() references to it, this function is a no-op.
+**
+** If parameter nByte is non-negative, then it is the requested size of
+** the mapping to create. Otherwise, if nByte is less than zero, then the
+** requested size is the size of the file on disk. The actual size of the
+** created mapping is either the requested size or the value configured
+** using SQLITE_FCNTL_MMAP_SIZE, whichever is smaller.
+**
+** SQLITE_OK is returned if no error occurs (even if the mapping is not
+** recreated as a result of outstanding references) or an SQLite error
+** code otherwise.
+*/
+static int winMapfile(winFile *pFd, sqlite3_int64 nByte){
+ sqlite3_int64 nMap = nByte;
+ int rc;
+
+ assert( nMap>=0 || pFd->nFetchOut==0 );
+ OSTRACE(("MAP-FILE pid=%lu, pFile=%p, size=%lld\n",
+ osGetCurrentProcessId(), pFd, nByte));
+
+ if( pFd->nFetchOut>0 ) return SQLITE_OK;
+
+ if( nMap<0 ){
+ rc = winFileSize((sqlite3_file*)pFd, &nMap);
+ if( rc ){
+ OSTRACE(("MAP-FILE pid=%lu, pFile=%p, rc=SQLITE_IOERR_FSTAT\n",
+ osGetCurrentProcessId(), pFd));
+ return SQLITE_IOERR_FSTAT;
+ }
+ }
+ if( nMap>pFd->mmapSizeMax ){
+ nMap = pFd->mmapSizeMax;
+ }
+ nMap &= ~(sqlite3_int64)(winSysInfo.dwPageSize - 1);
+
+ if( nMap==0 && pFd->mmapSize>0 ){
+ winUnmapfile(pFd);
+ }
+ if( nMap!=pFd->mmapSize ){
+ void *pNew = 0;
+ DWORD protect = PAGE_READONLY;
+ DWORD flags = FILE_MAP_READ;
+
+ winUnmapfile(pFd);
+#ifdef SQLITE_MMAP_READWRITE
+ if( (pFd->ctrlFlags & WINFILE_RDONLY)==0 ){
+ protect = PAGE_READWRITE;
+ flags |= FILE_MAP_WRITE;
+ }
+#endif
+#if SQLITE_OS_WINRT
+ pFd->hMap = osCreateFileMappingFromApp(pFd->h, NULL, protect, nMap, NULL);
+#elif defined(SQLITE_WIN32_HAS_WIDE)
+ pFd->hMap = osCreateFileMappingW(pFd->h, NULL, protect,
+ (DWORD)((nMap>>32) & 0xffffffff),
+ (DWORD)(nMap & 0xffffffff), NULL);
+#elif defined(SQLITE_WIN32_HAS_ANSI)
+ pFd->hMap = osCreateFileMappingA(pFd->h, NULL, protect,
+ (DWORD)((nMap>>32) & 0xffffffff),
+ (DWORD)(nMap & 0xffffffff), NULL);
+#endif
+ if( pFd->hMap==NULL ){
+ pFd->lastErrno = osGetLastError();
+ rc = winLogError(SQLITE_IOERR_MMAP, pFd->lastErrno,
+ "winMapfile1", pFd->zPath);
+ /* Log the error, but continue normal operation using xRead/xWrite */
+ OSTRACE(("MAP-FILE-CREATE pid=%lu, pFile=%p, rc=%s\n",
+ osGetCurrentProcessId(), pFd, sqlite3ErrName(rc)));
+ return SQLITE_OK;
+ }
+ assert( (nMap % winSysInfo.dwPageSize)==0 );
+ assert( sizeof(SIZE_T)==sizeof(sqlite3_int64) || nMap<=0xffffffff );
+#if SQLITE_OS_WINRT
+ pNew = osMapViewOfFileFromApp(pFd->hMap, flags, 0, (SIZE_T)nMap);
+#else
+ pNew = osMapViewOfFile(pFd->hMap, flags, 0, 0, (SIZE_T)nMap);
+#endif
+ if( pNew==NULL ){
+ osCloseHandle(pFd->hMap);
+ pFd->hMap = NULL;
+ pFd->lastErrno = osGetLastError();
+ rc = winLogError(SQLITE_IOERR_MMAP, pFd->lastErrno,
+ "winMapfile2", pFd->zPath);
+ /* Log the error, but continue normal operation using xRead/xWrite */
+ OSTRACE(("MAP-FILE-MAP pid=%lu, pFile=%p, rc=%s\n",
+ osGetCurrentProcessId(), pFd, sqlite3ErrName(rc)));
+ return SQLITE_OK;
+ }
+ pFd->pMapRegion = pNew;
+ pFd->mmapSize = nMap;
+ pFd->mmapSizeActual = nMap;
+ }
+
+ OSTRACE(("MAP-FILE pid=%lu, pFile=%p, rc=SQLITE_OK\n",
+ osGetCurrentProcessId(), pFd));
+ return SQLITE_OK;
+}
+#endif /* SQLITE_MAX_MMAP_SIZE>0 */
+
+/*
+** If possible, return a pointer to a mapping of file fd starting at offset
+** iOff. The mapping must be valid for at least nAmt bytes.
+**
+** If such a pointer can be obtained, store it in *pp and return SQLITE_OK.
+** Or, if one cannot but no error occurs, set *pp to 0 and return SQLITE_OK.
+** Finally, if an error does occur, return an SQLite error code. The final
+** value of *pp is undefined in this case.
+**
+** If this function does return a pointer, the caller must eventually
+** release the reference by calling winUnfetch().
+*/
+static int winFetch(sqlite3_file *fd, i64 iOff, int nAmt, void **pp){
+#if SQLITE_MAX_MMAP_SIZE>0
+ winFile *pFd = (winFile*)fd; /* The underlying database file */
+#endif
+ *pp = 0;
+
+ OSTRACE(("FETCH pid=%lu, pFile=%p, offset=%lld, amount=%d, pp=%p\n",
+ osGetCurrentProcessId(), fd, iOff, nAmt, pp));
+
+#if SQLITE_MAX_MMAP_SIZE>0
+ if( pFd->mmapSizeMax>0 ){
+ if( pFd->pMapRegion==0 ){
+ int rc = winMapfile(pFd, -1);
+ if( rc!=SQLITE_OK ){
+ OSTRACE(("FETCH pid=%lu, pFile=%p, rc=%s\n",
+ osGetCurrentProcessId(), pFd, sqlite3ErrName(rc)));
+ return rc;
+ }
+ }
+ if( pFd->mmapSize >= iOff+nAmt ){
+ *pp = &((u8 *)pFd->pMapRegion)[iOff];
+ pFd->nFetchOut++;
+ }
+ }
+#endif
+
+ OSTRACE(("FETCH pid=%lu, pFile=%p, pp=%p, *pp=%p, rc=SQLITE_OK\n",
+ osGetCurrentProcessId(), fd, pp, *pp));
+ return SQLITE_OK;
+}
+
+/*
+** If the third argument is non-NULL, then this function releases a
+** reference obtained by an earlier call to winFetch(). The second
+** argument passed to this function must be the same as the corresponding
+** argument that was passed to the winFetch() invocation.
+**
+** Or, if the third argument is NULL, then this function is being called
+** to inform the VFS layer that, according to POSIX, any existing mapping
+** may now be invalid and should be unmapped.
+*/
+static int winUnfetch(sqlite3_file *fd, i64 iOff, void *p){
+#if SQLITE_MAX_MMAP_SIZE>0
+ winFile *pFd = (winFile*)fd; /* The underlying database file */
+
+ /* If p==0 (unmap the entire file) then there must be no outstanding
+ ** xFetch references. Or, if p!=0 (meaning it is an xFetch reference),
+ ** then there must be at least one outstanding. */
+ assert( (p==0)==(pFd->nFetchOut==0) );
+
+ /* If p!=0, it must match the iOff value. */
+ assert( p==0 || p==&((u8 *)pFd->pMapRegion)[iOff] );
+
+ OSTRACE(("UNFETCH pid=%lu, pFile=%p, offset=%lld, p=%p\n",
+ osGetCurrentProcessId(), pFd, iOff, p));
+
+ if( p ){
+ pFd->nFetchOut--;
+ }else{
+ /* FIXME: If Windows truly always prevents truncating or deleting a
+ ** file while a mapping is held, then the following winUnmapfile() call
+ ** is unnecessary can be omitted - potentially improving
+ ** performance. */
+ winUnmapfile(pFd);
+ }
+
+ assert( pFd->nFetchOut>=0 );
+#endif
+
+ OSTRACE(("UNFETCH pid=%lu, pFile=%p, rc=SQLITE_OK\n",
+ osGetCurrentProcessId(), fd));
+ return SQLITE_OK;
+}
+
+/*
** Here ends the implementation of all sqlite3_file methods.
**
********************** End sqlite3_file Methods *******************************
@@ -33546,7 +39014,7 @@ shmpage_out:
** sqlite3_file for win32.
*/
static const sqlite3_io_methods winIoMethod = {
- 2, /* iVersion */
+ 3, /* iVersion */
winClose, /* xClose */
winRead, /* xRead */
winWrite, /* xWrite */
@@ -33562,7 +39030,9 @@ static const sqlite3_io_methods winIoMethod = {
winShmMap, /* xShmMap */
winShmLock, /* xShmLock */
winShmBarrier, /* xShmBarrier */
- winShmUnmap /* xShmUnmap */
+ winShmUnmap, /* xShmUnmap */
+ winFetch, /* xFetch */
+ winUnfetch /* xUnfetch */
};
/****************************************************************************
@@ -33572,16 +39042,37 @@ static const sqlite3_io_methods winIoMethod = {
** sqlite3_vfs object.
*/
+#if defined(__CYGWIN__)
+/*
+** Convert a filename from whatever the underlying operating system
+** supports for filenames into UTF-8. Space to hold the result is
+** obtained from malloc and must be freed by the calling function.
+*/
+static char *winConvertToUtf8Filename(const void *zFilename){
+ char *zConverted = 0;
+ if( osIsNT() ){
+ zConverted = winUnicodeToUtf8(zFilename);
+ }
+#ifdef SQLITE_WIN32_HAS_ANSI
+ else{
+ zConverted = sqlite3_win32_mbcs_to_utf8(zFilename);
+ }
+#endif
+ /* caller will handle out of memory */
+ return zConverted;
+}
+#endif
+
/*
** 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){
+static void *winConvertFromUtf8Filename(const char *zFilename){
void *zConverted = 0;
- if( isNT() ){
- zConverted = utf8ToUnicode(zFilename);
+ if( osIsNT() ){
+ zConverted = winUtf8ToUnicode(zFilename);
}
#ifdef SQLITE_WIN32_HAS_ANSI
else{
@@ -33593,73 +39084,243 @@ static void *convertUtf8Filename(const char *zFilename){
}
/*
-** Create a temporary file name in zBuf. zBuf must be big enough to
-** hold at pVfs->mxPathname characters.
+** This function returns non-zero if the specified UTF-8 string buffer
+** ends with a directory separator character or one was successfully
+** added to it.
+*/
+static int winMakeEndInDirSep(int nBuf, char *zBuf){
+ if( zBuf ){
+ int nLen = sqlite3Strlen30(zBuf);
+ if( nLen>0 ){
+ if( winIsDirSep(zBuf[nLen-1]) ){
+ return 1;
+ }else if( nLen+1<nBuf ){
+ zBuf[nLen] = winGetDirSep();
+ zBuf[nLen+1] = '\0';
+ return 1;
+ }
+ }
+ }
+ return 0;
+}
+
+/*
+** Create a temporary file name and store the resulting pointer into pzBuf.
+** The pointer returned in pzBuf must be freed via sqlite3_free().
*/
-static int getTempname(int nBuf, char *zBuf){
+static int winGetTempname(sqlite3_vfs *pVfs, char **pzBuf){
static char zChars[] =
"abcdefghijklmnopqrstuvwxyz"
"ABCDEFGHIJKLMNOPQRSTUVWXYZ"
"0123456789";
size_t i, j;
- int nTempPath;
- char zTempPath[MAX_PATH+2];
+ int nPre = sqlite3Strlen30(SQLITE_TEMP_FILE_PREFIX);
+ int nMax, nBuf, nDir, nLen;
+ char *zBuf;
/* 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.
+ ** function failing.
*/
SimulateIOError( return SQLITE_IOERR );
- memset(zTempPath, 0, MAX_PATH+2);
+ /* Allocate a temporary buffer to store the fully qualified file
+ ** name for the temporary file. If this fails, we cannot continue.
+ */
+ nMax = pVfs->mxPathname; nBuf = nMax + 2;
+ zBuf = sqlite3MallocZero( nBuf );
+ if( !zBuf ){
+ OSTRACE(("TEMP-FILENAME rc=SQLITE_IOERR_NOMEM\n"));
+ return SQLITE_IOERR_NOMEM;
+ }
+ /* Figure out the effective temporary directory. First, check if one
+ ** has been explicitly set by the application; otherwise, use the one
+ ** configured by the operating system.
+ */
+ nDir = nMax - (nPre + 15);
+ assert( nDir>0 );
if( sqlite3_temp_directory ){
- sqlite3_snprintf(MAX_PATH-30, zTempPath, "%s", sqlite3_temp_directory);
+ int nDirLen = sqlite3Strlen30(sqlite3_temp_directory);
+ if( nDirLen>0 ){
+ if( !winIsDirSep(sqlite3_temp_directory[nDirLen-1]) ){
+ nDirLen++;
+ }
+ if( nDirLen>nDir ){
+ sqlite3_free(zBuf);
+ OSTRACE(("TEMP-FILENAME rc=SQLITE_ERROR\n"));
+ return winLogError(SQLITE_ERROR, 0, "winGetTempname1", 0);
+ }
+ sqlite3_snprintf(nMax, zBuf, "%s", sqlite3_temp_directory);
+ }
}
-#if !SQLITE_OS_WINRT
- else if( isNT() ){
+#if defined(__CYGWIN__)
+ else{
+ static const char *azDirs[] = {
+ 0, /* getenv("SQLITE_TMPDIR") */
+ 0, /* getenv("TMPDIR") */
+ 0, /* getenv("TMP") */
+ 0, /* getenv("TEMP") */
+ 0, /* getenv("USERPROFILE") */
+ "/var/tmp",
+ "/usr/tmp",
+ "/tmp",
+ ".",
+ 0 /* List terminator */
+ };
+ unsigned int i;
+ const char *zDir = 0;
+
+ if( !azDirs[0] ) azDirs[0] = getenv("SQLITE_TMPDIR");
+ if( !azDirs[1] ) azDirs[1] = getenv("TMPDIR");
+ if( !azDirs[2] ) azDirs[2] = getenv("TMP");
+ if( !azDirs[3] ) azDirs[3] = getenv("TEMP");
+ if( !azDirs[4] ) azDirs[4] = getenv("USERPROFILE");
+ for(i=0; i<sizeof(azDirs)/sizeof(azDirs[0]); zDir=azDirs[i++]){
+ void *zConverted;
+ if( zDir==0 ) continue;
+ /* If the path starts with a drive letter followed by the colon
+ ** character, assume it is already a native Win32 path; otherwise,
+ ** it must be converted to a native Win32 path via the Cygwin API
+ ** prior to using it.
+ */
+ if( winIsDriveLetterAndColon(zDir) ){
+ zConverted = winConvertFromUtf8Filename(zDir);
+ if( !zConverted ){
+ sqlite3_free(zBuf);
+ OSTRACE(("TEMP-FILENAME rc=SQLITE_IOERR_NOMEM\n"));
+ return SQLITE_IOERR_NOMEM;
+ }
+ if( winIsDir(zConverted) ){
+ sqlite3_snprintf(nMax, zBuf, "%s", zDir);
+ sqlite3_free(zConverted);
+ break;
+ }
+ sqlite3_free(zConverted);
+ }else{
+ zConverted = sqlite3MallocZero( nMax+1 );
+ if( !zConverted ){
+ sqlite3_free(zBuf);
+ OSTRACE(("TEMP-FILENAME rc=SQLITE_IOERR_NOMEM\n"));
+ return SQLITE_IOERR_NOMEM;
+ }
+ if( cygwin_conv_path(
+ osIsNT() ? CCP_POSIX_TO_WIN_W : CCP_POSIX_TO_WIN_A, zDir,
+ zConverted, nMax+1)<0 ){
+ sqlite3_free(zConverted);
+ sqlite3_free(zBuf);
+ OSTRACE(("TEMP-FILENAME rc=SQLITE_IOERR_CONVPATH\n"));
+ return winLogError(SQLITE_IOERR_CONVPATH, (DWORD)errno,
+ "winGetTempname2", zDir);
+ }
+ if( winIsDir(zConverted) ){
+ /* At this point, we know the candidate directory exists and should
+ ** be used. However, we may need to convert the string containing
+ ** its name into UTF-8 (i.e. if it is UTF-16 right now).
+ */
+ char *zUtf8 = winConvertToUtf8Filename(zConverted);
+ if( !zUtf8 ){
+ sqlite3_free(zConverted);
+ sqlite3_free(zBuf);
+ OSTRACE(("TEMP-FILENAME rc=SQLITE_IOERR_NOMEM\n"));
+ return SQLITE_IOERR_NOMEM;
+ }
+ sqlite3_snprintf(nMax, zBuf, "%s", zUtf8);
+ sqlite3_free(zUtf8);
+ sqlite3_free(zConverted);
+ break;
+ }
+ sqlite3_free(zConverted);
+ }
+ }
+ }
+#elif !SQLITE_OS_WINRT && !defined(__CYGWIN__)
+ else if( osIsNT() ){
char *zMulti;
- WCHAR zWidePath[MAX_PATH];
- osGetTempPathW(MAX_PATH-30, zWidePath);
- zMulti = unicodeToUtf8(zWidePath);
+ LPWSTR zWidePath = sqlite3MallocZero( nMax*sizeof(WCHAR) );
+ if( !zWidePath ){
+ sqlite3_free(zBuf);
+ OSTRACE(("TEMP-FILENAME rc=SQLITE_IOERR_NOMEM\n"));
+ return SQLITE_IOERR_NOMEM;
+ }
+ if( osGetTempPathW(nMax, zWidePath)==0 ){
+ sqlite3_free(zWidePath);
+ sqlite3_free(zBuf);
+ OSTRACE(("TEMP-FILENAME rc=SQLITE_IOERR_GETTEMPPATH\n"));
+ return winLogError(SQLITE_IOERR_GETTEMPPATH, osGetLastError(),
+ "winGetTempname2", 0);
+ }
+ zMulti = winUnicodeToUtf8(zWidePath);
if( zMulti ){
- sqlite3_snprintf(MAX_PATH-30, zTempPath, "%s", zMulti);
+ sqlite3_snprintf(nMax, zBuf, "%s", zMulti);
sqlite3_free(zMulti);
+ sqlite3_free(zWidePath);
}else{
+ sqlite3_free(zWidePath);
+ sqlite3_free(zBuf);
+ OSTRACE(("TEMP-FILENAME rc=SQLITE_IOERR_NOMEM\n"));
return SQLITE_IOERR_NOMEM;
}
}
#ifdef SQLITE_WIN32_HAS_ANSI
else{
char *zUtf8;
- char zMbcsPath[MAX_PATH];
- osGetTempPathA(MAX_PATH-30, zMbcsPath);
+ char *zMbcsPath = sqlite3MallocZero( nMax );
+ if( !zMbcsPath ){
+ sqlite3_free(zBuf);
+ OSTRACE(("TEMP-FILENAME rc=SQLITE_IOERR_NOMEM\n"));
+ return SQLITE_IOERR_NOMEM;
+ }
+ if( osGetTempPathA(nMax, zMbcsPath)==0 ){
+ sqlite3_free(zBuf);
+ OSTRACE(("TEMP-FILENAME rc=SQLITE_IOERR_GETTEMPPATH\n"));
+ return winLogError(SQLITE_IOERR_GETTEMPPATH, osGetLastError(),
+ "winGetTempname3", 0);
+ }
zUtf8 = sqlite3_win32_mbcs_to_utf8(zMbcsPath);
if( zUtf8 ){
- sqlite3_snprintf(MAX_PATH-30, zTempPath, "%s", zUtf8);
+ sqlite3_snprintf(nMax, zBuf, "%s", zUtf8);
sqlite3_free(zUtf8);
}else{
+ sqlite3_free(zBuf);
+ OSTRACE(("TEMP-FILENAME rc=SQLITE_IOERR_NOMEM\n"));
return SQLITE_IOERR_NOMEM;
}
}
-#endif
-#endif
+#endif /* SQLITE_WIN32_HAS_ANSI */
+#endif /* !SQLITE_OS_WINRT */
- /* Check that the output buffer is large enough for the temporary file
- ** name. If it is not, return SQLITE_ERROR.
+ /*
+ ** Check to make sure the temporary directory ends with an appropriate
+ ** separator. If it does not and there is not enough space left to add
+ ** one, fail.
*/
- nTempPath = sqlite3Strlen30(zTempPath);
+ if( !winMakeEndInDirSep(nDir+1, zBuf) ){
+ sqlite3_free(zBuf);
+ OSTRACE(("TEMP-FILENAME rc=SQLITE_ERROR\n"));
+ return winLogError(SQLITE_ERROR, 0, "winGetTempname4", 0);
+ }
- if( (nTempPath + sqlite3Strlen30(SQLITE_TEMP_FILE_PREFIX) + 18) >= nBuf ){
- return SQLITE_ERROR;
+ /*
+ ** Check that the output buffer is large enough for the temporary file
+ ** name in the following format:
+ **
+ ** "<temporary_directory>/etilqs_XXXXXXXXXXXXXXX\0\0"
+ **
+ ** If not, return SQLITE_ERROR. The number 17 is used here in order to
+ ** account for the space used by the 15 character random suffix and the
+ ** two trailing NUL characters. The final directory separator character
+ ** has already added if it was not already present.
+ */
+ nLen = sqlite3Strlen30(zBuf);
+ if( (nLen + nPre + 17) > nBuf ){
+ sqlite3_free(zBuf);
+ OSTRACE(("TEMP-FILENAME rc=SQLITE_ERROR\n"));
+ return winLogError(SQLITE_ERROR, 0, "winGetTempname5", 0);
}
- for(i=nTempPath; i>0 && zTempPath[i-1]=='\\'; i--){}
- zTempPath[i] = 0;
+ sqlite3_snprintf(nBuf-16-nLen, zBuf+nLen, SQLITE_TEMP_FILE_PREFIX);
- 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++){
@@ -33667,9 +39328,10 @@ static int getTempname(int nBuf, char *zBuf){
}
zBuf[j] = 0;
zBuf[j+1] = 0;
+ *pzBuf = zBuf;
- OSTRACE(("TEMP FILENAME: %s\n", zBuf));
- return SQLITE_OK;
+ OSTRACE(("TEMP-FILENAME name=%s, rc=SQLITE_OK\n", zBuf));
+ return SQLITE_OK;
}
/*
@@ -33682,13 +39344,13 @@ static int winIsDir(const void *zConverted){
int rc = 0;
DWORD lastErrno;
- if( isNT() ){
+ if( osIsNT() ){
int cnt = 0;
WIN32_FILE_ATTRIBUTE_DATA sAttrData;
memset(&sAttrData, 0, sizeof(sAttrData));
while( !(rc = osGetFileAttributesExW((LPCWSTR)zConverted,
GetFileExInfoStandard,
- &sAttrData)) && retryIoerr(&cnt, &lastErrno) ){}
+ &sAttrData)) && winRetryIoerr(&cnt, &lastErrno) ){}
if( !rc ){
return 0; /* Invalid name? */
}
@@ -33705,14 +39367,14 @@ static int winIsDir(const void *zConverted){
** Open a file.
*/
static int winOpen(
- sqlite3_vfs *pVfs, /* Not used */
+ sqlite3_vfs *pVfs, /* Used to get maximum path name length */
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 lastErrno = 0;
DWORD dwDesiredAccess;
DWORD dwShareMode;
DWORD dwCreationDisposition;
@@ -33728,7 +39390,7 @@ static int winOpen(
/* 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 */
+ char *zTmpname = 0; /* For temporary filename, if necessary. */
int rc = SQLITE_OK; /* Function Return Code */
#if !defined(NDEBUG) || SQLITE_OS_WINCE
@@ -33738,22 +39400,23 @@ static int winOpen(
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_MASTER_JOURNAL
+ || eType==SQLITE_OPEN_MAIN_JOURNAL
|| eType==SQLITE_OPEN_WAL
));
#endif
- /* Check the following statements are true:
+ OSTRACE(("OPEN name=%s, pFile=%p, flags=%x, pOutFlags=%p\n",
+ zUtf8Name, id, flags, pOutFlags));
+
+ /* Check the following statements are true:
**
- ** (a) Exactly one of the READWRITE and READONLY flags must be set, and
+ ** (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.
@@ -33763,7 +39426,7 @@ static int winOpen(
assert(isExclusive==0 || isCreate);
assert(isDelete==0 || isCreate);
- /* The main DB, main journal, WAL file and master journal are never
+ /* 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 );
@@ -33771,31 +39434,31 @@ static int winOpen(
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
+ 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);
+ assert( pFile!=0 );
+ memset(pFile, 0, sizeof(winFile));
+ pFile->h = INVALID_HANDLE_VALUE;
#if SQLITE_OS_WINRT
- if( !sqlite3_temp_directory ){
+ if( !zUtf8Name && !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 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);
+ assert( isDelete && !isOpenJournal );
+ rc = winGetTempname(pVfs, &zTmpname);
if( rc!=SQLITE_OK ){
+ OSTRACE(("OPEN name=%s, rc=%s", zUtf8Name, sqlite3ErrName(rc)));
return rc;
}
zUtf8Name = zTmpname;
@@ -33806,16 +39469,20 @@ static int winOpen(
** sqlite3_uri_parameter().
*/
assert( (eType!=SQLITE_OPEN_MAIN_DB) || (flags & SQLITE_OPEN_URI) ||
- zUtf8Name[strlen(zUtf8Name)+1]==0 );
+ zUtf8Name[sqlite3Strlen30(zUtf8Name)+1]==0 );
/* Convert the filename to the system encoding. */
- zConverted = convertUtf8Filename(zUtf8Name);
+ zConverted = winConvertFromUtf8Filename(zUtf8Name);
if( zConverted==0 ){
+ sqlite3_free(zTmpname);
+ OSTRACE(("OPEN name=%s, rc=SQLITE_IOERR_NOMEM", zUtf8Name));
return SQLITE_IOERR_NOMEM;
}
if( winIsDir(zConverted) ){
sqlite3_free(zConverted);
+ sqlite3_free(zTmpname);
+ OSTRACE(("OPEN name=%s, rc=SQLITE_CANTOPEN_ISDIR", zUtf8Name));
return SQLITE_CANTOPEN_ISDIR;
}
@@ -33825,8 +39492,8 @@ static int winOpen(
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"
+ /* 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 ){
@@ -33861,7 +39528,7 @@ static int winOpen(
dwFlagsAndAttributes |= FILE_FLAG_RANDOM_ACCESS;
#endif
- if( isNT() ){
+ if( osIsNT() ){
#if SQLITE_OS_WINRT
CREATEFILE2_EXTENDED_PARAMETERS extendedParameters;
extendedParameters.dwSize = sizeof(CREATEFILE2_EXTENDED_PARAMETERS);
@@ -33876,7 +39543,7 @@ static int winOpen(
dwShareMode,
dwCreationDisposition,
&extendedParameters))==INVALID_HANDLE_VALUE &&
- retryIoerr(&cnt, &lastErrno) ){
+ winRetryIoerr(&cnt, &lastErrno) ){
/* Noop */
}
#else
@@ -33886,7 +39553,7 @@ static int winOpen(
dwCreationDisposition,
dwFlagsAndAttributes,
NULL))==INVALID_HANDLE_VALUE &&
- retryIoerr(&cnt, &lastErrno) ){
+ winRetryIoerr(&cnt, &lastErrno) ){
/* Noop */
}
#endif
@@ -33899,24 +39566,26 @@ static int winOpen(
dwCreationDisposition,
dwFlagsAndAttributes,
NULL))==INVALID_HANDLE_VALUE &&
- retryIoerr(&cnt, &lastErrno) ){
+ winRetryIoerr(&cnt, &lastErrno) ){
/* Noop */
}
}
#endif
- logIoerr(cnt);
+ winLogIoerr(cnt, __LINE__);
- OSTRACE(("OPEN %d %s 0x%lx %s\n",
- h, zName, dwDesiredAccess,
- h==INVALID_HANDLE_VALUE ? "failed" : "ok"));
+ OSTRACE(("OPEN file=%p, name=%s, access=%lx, rc=%s\n", h, zUtf8Name,
+ 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);
+ sqlite3_free(zTmpname);
if( isReadWrite && !isExclusive ){
- return winOpen(pVfs, zName, id,
- ((flags|SQLITE_OPEN_READONLY)&~(SQLITE_OPEN_CREATE|SQLITE_OPEN_READWRITE)), pOutFlags);
+ return winOpen(pVfs, zName, id,
+ ((flags|SQLITE_OPEN_READONLY) &
+ ~(SQLITE_OPEN_CREATE|SQLITE_OPEN_READWRITE)),
+ pOutFlags);
}else{
return SQLITE_CANTOPEN_BKPT;
}
@@ -33930,26 +39599,19 @@ static int winOpen(
}
}
- 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;
- }
+ OSTRACE(("OPEN file=%p, name=%s, access=%lx, pOutFlags=%p, *pOutFlags=%d, "
+ "rc=%s\n", h, zUtf8Name, dwDesiredAccess, pOutFlags, pOutFlags ?
+ *pOutFlags : 0, (h==INVALID_HANDLE_VALUE) ? "failed" : "ok"));
#if SQLITE_OS_WINCE
if( isReadWrite && eType==SQLITE_OPEN_MAIN_DB
- && !winceCreateLock(zName, pFile)
+ && (rc = winceCreateLock(zName, pFile))!=SQLITE_OK
){
osCloseHandle(h);
sqlite3_free(zConverted);
- return SQLITE_CANTOPEN_BKPT;
+ sqlite3_free(zTmpname);
+ OSTRACE(("OPEN-CE-LOCK name=%s, rc=%s\n", zName, sqlite3ErrName(rc)));
+ return rc;
}
if( isTemp ){
pFile->zDeleteOnClose = zConverted;
@@ -33959,6 +39621,26 @@ static int winOpen(
sqlite3_free(zConverted);
}
+ sqlite3_free(zTmpname);
+ pFile->pMethod = &winIoMethod;
+ pFile->pVfs = pVfs;
+ pFile->h = h;
+ if( isReadonly ){
+ pFile->ctrlFlags |= WINFILE_RDONLY;
+ }
+ if( sqlite3_uri_boolean(zName, "psow", SQLITE_POWERSAFE_OVERWRITE) ){
+ pFile->ctrlFlags |= WINFILE_PSOW;
+ }
+ pFile->lastErrno = NO_ERROR;
+ pFile->zPath = zName;
+#if SQLITE_MAX_MMAP_SIZE>0
+ pFile->hMap = NULL;
+ pFile->pMapRegion = 0;
+ pFile->mmapSize = 0;
+ pFile->mmapSizeActual = 0;
+ pFile->mmapSizeMax = sqlite3GlobalConfig.szMmap;
+#endif
+
OpenCounter(+1);
return rc;
}
@@ -33983,17 +39665,20 @@ static int winDelete(
int cnt = 0;
int rc;
DWORD attr;
- DWORD lastErrno;
+ DWORD lastErrno = 0;
void *zConverted;
UNUSED_PARAMETER(pVfs);
UNUSED_PARAMETER(syncDir);
SimulateIOError(return SQLITE_IOERR_DELETE);
- zConverted = convertUtf8Filename(zFilename);
+ OSTRACE(("DELETE name=%s, syncDir=%d\n", zFilename, syncDir));
+
+ zConverted = winConvertFromUtf8Filename(zFilename);
if( zConverted==0 ){
+ OSTRACE(("DELETE name=%s, rc=SQLITE_IOERR_NOMEM\n", zFilename));
return SQLITE_IOERR_NOMEM;
}
- if( isNT() ){
+ if( osIsNT() ){
do {
#if SQLITE_OS_WINRT
WIN32_FILE_ATTRIBUTE_DATA sAttrData;
@@ -34003,7 +39688,8 @@ static int winDelete(
attr = sAttrData.dwFileAttributes;
}else{
lastErrno = osGetLastError();
- if( lastErrno==ERROR_FILE_NOT_FOUND || lastErrno==ERROR_PATH_NOT_FOUND ){
+ if( lastErrno==ERROR_FILE_NOT_FOUND
+ || lastErrno==ERROR_PATH_NOT_FOUND ){
rc = SQLITE_IOERR_DELETE_NOENT; /* Already gone? */
}else{
rc = SQLITE_ERROR;
@@ -34015,7 +39701,8 @@ static int winDelete(
#endif
if ( attr==INVALID_FILE_ATTRIBUTES ){
lastErrno = osGetLastError();
- if( lastErrno==ERROR_FILE_NOT_FOUND || lastErrno==ERROR_PATH_NOT_FOUND ){
+ if( lastErrno==ERROR_FILE_NOT_FOUND
+ || lastErrno==ERROR_PATH_NOT_FOUND ){
rc = SQLITE_IOERR_DELETE_NOENT; /* Already gone? */
}else{
rc = SQLITE_ERROR;
@@ -34030,7 +39717,7 @@ static int winDelete(
rc = SQLITE_OK; /* Deleted OK. */
break;
}
- if ( !retryIoerr(&cnt, &lastErrno) ){
+ if ( !winRetryIoerr(&cnt, &lastErrno) ){
rc = SQLITE_ERROR; /* No more retries. */
break;
}
@@ -34042,7 +39729,8 @@ static int winDelete(
attr = osGetFileAttributesA(zConverted);
if ( attr==INVALID_FILE_ATTRIBUTES ){
lastErrno = osGetLastError();
- if( lastErrno==ERROR_FILE_NOT_FOUND || lastErrno==ERROR_PATH_NOT_FOUND ){
+ if( lastErrno==ERROR_FILE_NOT_FOUND
+ || lastErrno==ERROR_PATH_NOT_FOUND ){
rc = SQLITE_IOERR_DELETE_NOENT; /* Already gone? */
}else{
rc = SQLITE_ERROR;
@@ -34057,7 +39745,7 @@ static int winDelete(
rc = SQLITE_OK; /* Deleted OK. */
break;
}
- if ( !retryIoerr(&cnt, &lastErrno) ){
+ if ( !winRetryIoerr(&cnt, &lastErrno) ){
rc = SQLITE_ERROR; /* No more retries. */
break;
}
@@ -34065,18 +39753,17 @@ static int winDelete(
}
#endif
if( rc && rc!=SQLITE_IOERR_DELETE_NOENT ){
- rc = winLogError(SQLITE_IOERR_DELETE, lastErrno,
- "winDelete", zFilename);
+ rc = winLogError(SQLITE_IOERR_DELETE, lastErrno, "winDelete", zFilename);
}else{
- logIoerr(cnt);
+ winLogIoerr(cnt, __LINE__);
}
sqlite3_free(zConverted);
- OSTRACE(("DELETE \"%s\" %s\n", zFilename, (rc ? "failed" : "ok" )));
+ OSTRACE(("DELETE name=%s, rc=%s\n", zFilename, sqlite3ErrName(rc)));
return rc;
}
/*
-** Check the existance and status of a file.
+** Check the existence and status of a file.
*/
static int winAccess(
sqlite3_vfs *pVfs, /* Not used on win32 */
@@ -34086,39 +39773,43 @@ static int winAccess(
){
DWORD attr;
int rc = 0;
- DWORD lastErrno;
+ DWORD lastErrno = 0;
void *zConverted;
UNUSED_PARAMETER(pVfs);
SimulateIOError( return SQLITE_IOERR_ACCESS; );
- zConverted = convertUtf8Filename(zFilename);
+ OSTRACE(("ACCESS name=%s, flags=%x, pResOut=%p\n",
+ zFilename, flags, pResOut));
+
+ zConverted = winConvertFromUtf8Filename(zFilename);
if( zConverted==0 ){
+ OSTRACE(("ACCESS name=%s, rc=SQLITE_IOERR_NOMEM\n", zFilename));
return SQLITE_IOERR_NOMEM;
}
- if( isNT() ){
+ if( osIsNT() ){
int cnt = 0;
WIN32_FILE_ATTRIBUTE_DATA sAttrData;
memset(&sAttrData, 0, sizeof(sAttrData));
while( !(rc = osGetFileAttributesExW((LPCWSTR)zConverted,
- GetFileExInfoStandard,
- &sAttrData)) && retryIoerr(&cnt, &lastErrno) ){}
+ GetFileExInfoStandard,
+ &sAttrData)) && winRetryIoerr(&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.nFileSizeHigh==0
&& sAttrData.nFileSizeLow==0 ){
attr = INVALID_FILE_ATTRIBUTES;
}else{
attr = sAttrData.dwFileAttributes;
}
}else{
- logIoerr(cnt);
+ winLogIoerr(cnt, __LINE__);
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;
+ return winLogError(SQLITE_IOERR_ACCESS, lastErrno, "winAccess",
+ zFilename);
}else{
attr = INVALID_FILE_ATTRIBUTES;
}
@@ -34143,9 +39834,20 @@ static int winAccess(
assert(!"Invalid flags argument");
}
*pResOut = rc;
+ OSTRACE(("ACCESS name=%s, pResOut=%p, *pResOut=%d, rc=SQLITE_OK\n",
+ zFilename, pResOut, *pResOut));
return SQLITE_OK;
}
+/*
+** Returns non-zero if the specified path name starts with a drive letter
+** followed by a colon character.
+*/
+static BOOL winIsDriveLetterAndColon(
+ const char *zPathname
+){
+ return ( sqlite3Isalpha(zPathname[0]) && zPathname[1]==':' );
+}
/*
** Returns non-zero if the specified path name should be used verbatim. If
@@ -34163,7 +39865,7 @@ static BOOL winIsVerbatimPathname(
** 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]=='\\' ){
+ if ( winIsDirSep(zPathname[0]) ){
return TRUE;
}
@@ -34173,7 +39875,7 @@ static BOOL winIsVerbatimPathname(
** attempt to treat it as a relative path name (i.e. they should simply use
** it verbatim).
*/
- if ( sqlite3Isalpha(zPathname[0]) && zPathname[1]==':' ){
+ if ( winIsDriveLetterAndColon(zPathname) ){
return TRUE;
}
@@ -34195,11 +39897,10 @@ static int winFullPathname(
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) ){
/*
@@ -34208,18 +39909,48 @@ static int winFullPathname(
** 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);
+ char *zOut = sqlite3MallocZero( pVfs->mxPathname+1 );
+ if( !zOut ){
+ return SQLITE_IOERR_NOMEM;
+ }
+ if( cygwin_conv_path(
+ (osIsNT() ? CCP_POSIX_TO_WIN_W : CCP_POSIX_TO_WIN_A) |
+ CCP_RELATIVE, zRelative, zOut, pVfs->mxPathname+1)<0 ){
+ sqlite3_free(zOut);
+ return winLogError(SQLITE_CANTOPEN_CONVPATH, (DWORD)errno,
+ "winFullPathname1", zRelative);
+ }else{
+ char *zUtf8 = winConvertToUtf8Filename(zOut);
+ if( !zUtf8 ){
+ sqlite3_free(zOut);
+ return SQLITE_IOERR_NOMEM;
+ }
+ sqlite3_snprintf(MIN(nFull, pVfs->mxPathname), zFull, "%s%c%s",
+ sqlite3_data_directory, winGetDirSep(), zUtf8);
+ sqlite3_free(zUtf8);
+ sqlite3_free(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);
+ char *zOut = sqlite3MallocZero( pVfs->mxPathname+1 );
+ if( !zOut ){
+ return SQLITE_IOERR_NOMEM;
+ }
+ if( cygwin_conv_path(
+ (osIsNT() ? CCP_POSIX_TO_WIN_W : CCP_POSIX_TO_WIN_A),
+ zRelative, zOut, pVfs->mxPathname+1)<0 ){
+ sqlite3_free(zOut);
+ return winLogError(SQLITE_CANTOPEN_CONVPATH, (DWORD)errno,
+ "winFullPathname2", zRelative);
+ }else{
+ char *zUtf8 = winConvertToUtf8Filename(zOut);
+ if( !zUtf8 ){
+ sqlite3_free(zOut);
+ return SQLITE_IOERR_NOMEM;
+ }
+ sqlite3_snprintf(MIN(nFull, pVfs->mxPathname), zFull, "%s", zUtf8);
+ sqlite3_free(zUtf8);
+ sqlite3_free(zOut);
+ }
}
return SQLITE_OK;
#endif
@@ -34235,8 +39966,8 @@ static int winFullPathname(
** 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);
+ sqlite3_snprintf(MIN(nFull, pVfs->mxPathname), zFull, "%s%c%s",
+ sqlite3_data_directory, winGetDirSep(), zRelative);
}else{
sqlite3_snprintf(MIN(nFull, pVfs->mxPathname), zFull, "%s", zRelative);
}
@@ -34251,7 +39982,7 @@ static int winFullPathname(
/* 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]==':' ){
+ if( zRelative[0]=='/' && winIsDriveLetterAndColon(zRelative+1) ){
zRelative++;
}
@@ -34268,22 +39999,21 @@ static int winFullPathname(
** 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);
+ sqlite3_snprintf(MIN(nFull, pVfs->mxPathname), zFull, "%s%c%s",
+ sqlite3_data_directory, winGetDirSep(), zRelative);
return SQLITE_OK;
}
- zConverted = convertUtf8Filename(zRelative);
+ zConverted = winConvertFromUtf8Filename(zRelative);
if( zConverted==0 ){
return SQLITE_IOERR_NOMEM;
}
- if( isNT() ){
+ if( osIsNT() ){
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;
+ return winLogError(SQLITE_CANTOPEN_FULLPATH, osGetLastError(),
+ "winFullPathname1", zRelative);
}
nByte += 3;
zTemp = sqlite3MallocZero( nByte*sizeof(zTemp[0]) );
@@ -34293,14 +40023,13 @@ static int winFullPathname(
}
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;
+ return winLogError(SQLITE_CANTOPEN_FULLPATH, osGetLastError(),
+ "winFullPathname2", zRelative);
}
sqlite3_free(zConverted);
- zOut = unicodeToUtf8(zTemp);
+ zOut = winUnicodeToUtf8(zTemp);
sqlite3_free(zTemp);
}
#ifdef SQLITE_WIN32_HAS_ANSI
@@ -34308,10 +40037,9 @@ static int winFullPathname(
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;
+ return winLogError(SQLITE_CANTOPEN_FULLPATH, osGetLastError(),
+ "winFullPathname3", zRelative);
}
nByte += 3;
zTemp = sqlite3MallocZero( nByte*sizeof(zTemp[0]) );
@@ -34321,11 +40049,10 @@ static int winFullPathname(
}
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;
+ return winLogError(SQLITE_CANTOPEN_FULLPATH, osGetLastError(),
+ "winFullPathname4", zRelative);
}
sqlite3_free(zConverted);
zOut = sqlite3_win32_mbcs_to_utf8(zTemp);
@@ -34347,18 +40074,32 @@ static int winFullPathname(
** 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);
+#if defined(__CYGWIN__)
+ int nFull = pVfs->mxPathname+1;
+ char *zFull = sqlite3MallocZero( nFull );
+ void *zConverted = 0;
+ if( zFull==0 ){
+ OSTRACE(("DLOPEN name=%s, handle=%p\n", zFilename, (void*)0));
+ return 0;
+ }
+ if( winFullPathname(pVfs, zFilename, nFull, zFull)!=SQLITE_OK ){
+ sqlite3_free(zFull);
+ OSTRACE(("DLOPEN name=%s, handle=%p\n", zFilename, (void*)0));
+ return 0;
+ }
+ zConverted = winConvertFromUtf8Filename(zFull);
+ sqlite3_free(zFull);
+#else
+ void *zConverted = winConvertFromUtf8Filename(zFilename);
UNUSED_PARAMETER(pVfs);
+#endif
if( zConverted==0 ){
+ OSTRACE(("DLOPEN name=%s, handle=%p\n", zFilename, (void*)0));
return 0;
}
- if( isNT() ){
+ if( osIsNT() ){
#if SQLITE_OS_WINRT
h = osLoadPackagedLibrary((LPCWSTR)zConverted, 0);
#else
@@ -34370,20 +40111,26 @@ static void *winDlOpen(sqlite3_vfs *pVfs, const char *zFilename){
h = osLoadLibraryA((char*)zConverted);
}
#endif
+ OSTRACE(("DLOPEN name=%s, handle=%p\n", zFilename, (void*)h));
sqlite3_free(zConverted);
return (void*)h;
}
static void winDlError(sqlite3_vfs *pVfs, int nBuf, char *zBufOut){
UNUSED_PARAMETER(pVfs);
- getLastErrorMsg(osGetLastError(), nBuf, zBufOut);
+ winGetLastErrorMsg(osGetLastError(), nBuf, zBufOut);
}
-static void (*winDlSym(sqlite3_vfs *pVfs, void *pHandle, const char *zSymbol))(void){
+static void (*winDlSym(sqlite3_vfs *pVfs,void *pH,const char *zSym))(void){
+ FARPROC proc;
UNUSED_PARAMETER(pVfs);
- return (void(*)(void))osGetProcAddressA((HANDLE)pHandle, zSymbol);
+ proc = osGetProcAddressA((HANDLE)pH, zSym);
+ OSTRACE(("DLSYM handle=%p, symbol=%s, address=%p\n",
+ (void*)pH, zSym, (void*)proc));
+ return (void(*)(void))proc;
}
static void winDlClose(sqlite3_vfs *pVfs, void *pHandle){
UNUSED_PARAMETER(pVfs);
osFreeLibrary((HANDLE)pHandle);
+ OSTRACE(("DLCLOSE handle=%p\n", (void*)pHandle));
}
#else /* if SQLITE_OMIT_LOAD_EXTENSION is defined: */
#define winDlOpen 0
@@ -34399,7 +40146,7 @@ static void winDlClose(sqlite3_vfs *pVfs, void *pHandle){
static int winRandomness(sqlite3_vfs *pVfs, int nBuf, char *zBuf){
int n = 0;
UNUSED_PARAMETER(pVfs);
-#if defined(SQLITE_TEST)
+#if defined(SQLITE_TEST) || defined(SQLITE_OMIT_RANDOMNESS)
n = nBuf;
memset(zBuf, 0, nBuf);
#else
@@ -34433,7 +40180,23 @@ static int winRandomness(sqlite3_vfs *pVfs, int nBuf, char *zBuf){
memcpy(&zBuf[n], &i, sizeof(i));
n += sizeof(i);
}
+#if !SQLITE_OS_WINCE && !SQLITE_OS_WINRT && SQLITE_WIN32_USE_UUID
+ if( sizeof(UUID)<=nBuf-n ){
+ UUID id;
+ memset(&id, 0, sizeof(UUID));
+ osUuidCreate(&id);
+ memcpy(&zBuf[n], &id, sizeof(UUID));
+ n += sizeof(UUID);
+ }
+ if( sizeof(UUID)<=nBuf-n ){
+ UUID id;
+ memset(&id, 0, sizeof(UUID));
+ osUuidCreateSequential(&id);
+ memcpy(&zBuf[n], &id, sizeof(UUID));
+ n += sizeof(UUID);
+ }
#endif
+#endif /* defined(SQLITE_TEST) || defined(SQLITE_ZERO_PRNG_SEED) */
return n;
}
@@ -34463,12 +40226,12 @@ SQLITE_API int sqlite3_current_time = 0; /* Fake system time in seconds since 1
** 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
+** 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 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;
@@ -34476,8 +40239,9 @@ static int winCurrentTimeInt64(sqlite3_vfs *pVfs, sqlite3_int64 *piNow){
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;
+ static const sqlite3_int64 max32BitValue =
+ (sqlite3_int64)2000000000 + (sqlite3_int64)2000000000 +
+ (sqlite3_int64)294967296;
#if SQLITE_OS_WINCE
SYSTEMTIME time;
@@ -34491,7 +40255,7 @@ static int winCurrentTimeInt64(sqlite3_vfs *pVfs, sqlite3_int64 *piNow){
#endif
*piNow = winFiletimeEpoch +
- ((((sqlite3_int64)ft.dwHighDateTime)*max32BitValue) +
+ ((((sqlite3_int64)ft.dwHighDateTime)*max32BitValue) +
(sqlite3_int64)ft.dwLowDateTime)/(sqlite3_int64)10000;
#ifdef SQLITE_TEST
@@ -34550,17 +40314,17 @@ static int winCurrentTime(sqlite3_vfs *pVfs, double *prNow){
*/
static int winGetLastError(sqlite3_vfs *pVfs, int nBuf, char *zBuf){
UNUSED_PARAMETER(pVfs);
- return getLastErrorMsg(osGetLastError(), nBuf, zBuf);
+ return winGetLastErrorMsg(osGetLastError(), nBuf, zBuf);
}
/*
** Initialize and deinitialize the operating system interface.
*/
-SQLITE_API int sqlite3_os_init(void){
+SQLITE_API int SQLITE_STDCALL sqlite3_os_init(void){
static sqlite3_vfs winVfs = {
3, /* iVersion */
sizeof(winFile), /* szOsFile */
- MAX_PATH, /* mxPathname */
+ SQLITE_WIN32_MAX_PATH_BYTES, /* mxPathname */
0, /* pNext */
"win32", /* zName */
0, /* pAppData */
@@ -34581,12 +40345,37 @@ SQLITE_API int sqlite3_os_init(void){
winGetSystemCall, /* xGetSystemCall */
winNextSystemCall, /* xNextSystemCall */
};
+#if defined(SQLITE_WIN32_HAS_WIDE)
+ static sqlite3_vfs winLongPathVfs = {
+ 3, /* iVersion */
+ sizeof(winFile), /* szOsFile */
+ SQLITE_WINNT_MAX_PATH_BYTES, /* mxPathname */
+ 0, /* pNext */
+ "win32-longpath", /* 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 */
+ };
+#endif
/* Double-check that the aSyscall[] array has been constructed
** correctly. See ticket [bb3a86e890c8e96ab] */
- assert( ArraySize(aSyscall)==74 );
+ assert( ArraySize(aSyscall)==80 );
-#ifndef SQLITE_OMIT_WAL
/* get memory map allocation granularity */
memset(&winSysInfo, 0, sizeof(SYSTEM_INFO));
#if SQLITE_OS_WINRT
@@ -34594,14 +40383,19 @@ SQLITE_API int sqlite3_os_init(void){
#else
osGetSystemInfo(&winSysInfo);
#endif
- assert(winSysInfo.dwAllocationGranularity > 0);
-#endif
+ assert( winSysInfo.dwAllocationGranularity>0 );
+ assert( winSysInfo.dwPageSize>0 );
sqlite3_vfs_register(&winVfs, 1);
- return SQLITE_OK;
+
+#if defined(SQLITE_WIN32_HAS_WIDE)
+ sqlite3_vfs_register(&winLongPathVfs, 0);
+#endif
+
+ return SQLITE_OK;
}
-SQLITE_API int sqlite3_os_end(void){
+SQLITE_API int SQLITE_STDCALL sqlite3_os_end(void){
#if SQLITE_OS_WINRT
if( sleepObj!=NULL ){
osCloseHandle(sleepObj);
@@ -34651,13 +40445,15 @@ SQLITE_API int sqlite3_os_end(void){
** 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.
*/
+/* #include "sqliteInt.h" */
/* 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*))
+#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.
@@ -34688,7 +40484,7 @@ SQLITE_API int sqlite3_os_end(void){
/*
** A bitmap is an instance of the following structure.
**
-** This bitmap records the existance of zero or more bits
+** This bitmap records the existence of zero or more bits
** with values between 1 and iSize, inclusive.
**
** There are three possible representations of the bitmap.
@@ -34742,10 +40538,10 @@ SQLITE_PRIVATE Bitvec *sqlite3BitvecCreate(u32 iSize){
** 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;
+SQLITE_PRIVATE int sqlite3BitvecTestNotNull(Bitvec *p, u32 i){
+ assert( p!=0 );
i--;
+ if( i>=p->iSize ) return 0;
while( p->iDivisor ){
u32 bin = i/p->iDivisor;
i = i%p->iDivisor;
@@ -34765,6 +40561,9 @@ SQLITE_PRIVATE int sqlite3BitvecTest(Bitvec *p, u32 i){
return 0;
}
}
+SQLITE_PRIVATE int sqlite3BitvecTest(Bitvec *p, u32 i){
+ return p!=0 && sqlite3BitvecTestNotNull(p,i);
+}
/*
** Set the i-th bit. Return 0 on success and an error code if
@@ -34957,7 +40756,7 @@ SQLITE_PRIVATE int sqlite3BitvecBuiltinTest(int sz, int *aOp){
** bits to act as the reference */
pBitvec = sqlite3BitvecCreate( sz );
pV = sqlite3MallocZero( (sz+7)/8 + 1 );
- pTmpSpace = sqlite3_malloc(BITVEC_SZ);
+ pTmpSpace = sqlite3_malloc64(BITVEC_SZ);
if( pBitvec==0 || pV==0 || pTmpSpace==0 ) goto bitvec_end;
/* NULL pBitvec tests */
@@ -35037,6 +40836,7 @@ bitvec_end:
*************************************************************************
** This file implements that page cache.
*/
+/* #include "sqliteInt.h" */
/*
** A complete page cache is an instance of this structure.
@@ -35044,119 +40844,111 @@ bitvec_end:
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 nRefSum; /* Sum of ref counts over all pages */
int szCache; /* Configured cache size */
+ int szSpill; /* Size before spilling occurs */
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 */
+ u8 bPurgeable; /* True if pages are on backing store */
+ u8 eCreate; /* eCreate value for for xFetch() */
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 */
+/* Allowed values for second argument to pcacheManageDirtyList() */
+#define PCACHE_DIRTYLIST_REMOVE 1 /* Remove pPage from dirty list */
+#define PCACHE_DIRTYLIST_ADD 2 /* Add pPage to the dirty list */
+#define PCACHE_DIRTYLIST_FRONT 3 /* Move pPage to the front of the list */
/*
-** Remove page pPage from the list of dirty pages.
+** Manage pPage's participation on the dirty list. Bits of the addRemove
+** argument determines what operation to do. The 0x01 bit means first
+** remove pPage from the dirty list. The 0x02 means add pPage back to
+** the dirty list. Doing both moves pPage to the front of the dirty list.
*/
-static void pcacheRemoveFromDirtyList(PgHdr *pPage){
+static void pcacheManageDirtyList(PgHdr *pPage, u8 addRemove){
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;
+ if( addRemove & PCACHE_DIRTYLIST_REMOVE ){
+ 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;
}
- p->pSynced = pSynced;
- }
-
- if( pPage->pDirtyNext ){
- pPage->pDirtyNext->pDirtyPrev = pPage->pDirtyPrev;
- }else{
- assert( pPage==p->pDirtyTail );
- p->pDirtyTail = pPage->pDirtyPrev;
+
+ 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;
+ if( p->pDirty==0 && p->bPurgeable ){
+ assert( p->eCreate==1 );
+ p->eCreate = 2;
+ }
+ }
+ pPage->pDirtyNext = 0;
+ pPage->pDirtyPrev = 0;
}
- if( pPage->pDirtyPrev ){
- pPage->pDirtyPrev->pDirtyNext = pPage->pDirtyNext;
- }else{
- assert( pPage==p->pDirty );
- p->pDirty = pPage->pDirtyNext;
+ if( addRemove & PCACHE_DIRTYLIST_ADD ){
+ 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;
+ }else{
+ p->pDirtyTail = pPage;
+ if( p->bPurgeable ){
+ assert( p->eCreate==2 );
+ p->eCreate = 1;
+ }
+ }
+ p->pDirty = pPage;
+ if( !p->pSynced && 0==(pPage->flags&PGHDR_NEED_SYNC) ){
+ p->pSynced = pPage;
+ }
}
- 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).
+** 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 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;
+static void pcacheUnpin(PgHdr *p){
+ if( p->pCache->bPurgeable ){
+ sqlite3GlobalConfig.pcache2.xUnpin(p->pCache->pCache, p->pPage, 0);
}
- 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.
+** Compute the number of pages of cache requested. p->szCache is the
+** cache size requested by the "PRAGMA cache_size" statement.
*/
-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);
+static int numberOfCachePages(PCache *p){
+ if( p->szCache>=0 ){
+ /* IMPLEMENTATION-OF: R-42059-47211 If the argument N is positive then the
+ ** suggested cache size is set to N. */
+ return p->szCache;
+ }else{
+ /* IMPLEMENTATION-OF: R-61436-13639 If the argument N is negative, then
+ ** the number of cache pages is adjusted to use approximately abs(N*1024)
+ ** bytes of memory. */
+ return (int)((-1024*(i64)p->szCache)/(p->szPage+p->szExtra));
}
}
@@ -35192,7 +40984,7 @@ SQLITE_PRIVATE int sqlite3PcacheSize(void){ return sizeof(PCache); }
** The caller discovers how much space needs to be allocated by
** calling sqlite3PcacheSize().
*/
-SQLITE_PRIVATE void sqlite3PcacheOpen(
+SQLITE_PRIVATE int sqlite3PcacheOpen(
int szPage, /* Size of every page */
int szExtra, /* Extra space associated with each page */
int bPurgeable, /* True if pages are on backing store */
@@ -35201,85 +40993,115 @@ SQLITE_PRIVATE void sqlite3PcacheOpen(
PCache *p /* Preallocated space for the PCache */
){
memset(p, 0, sizeof(PCache));
- p->szPage = szPage;
+ p->szPage = 1;
p->szExtra = szExtra;
p->bPurgeable = bPurgeable;
+ p->eCreate = 2;
p->xStress = xStress;
p->pStress = pStress;
p->szCache = 100;
+ p->szSpill = 1;
+ return sqlite3PcacheSetPageSize(p, szPage);
}
/*
** 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));
+SQLITE_PRIVATE int sqlite3PcacheSetPageSize(PCache *pCache, int szPage){
+ assert( pCache->nRefSum==0 && pCache->pDirty==0 );
+ if( pCache->szPage ){
+ sqlite3_pcache *pNew;
+ pNew = sqlite3GlobalConfig.pcache2.xCreate(
+ szPage, pCache->szExtra + ROUND8(sizeof(PgHdr)),
+ pCache->bPurgeable
+ );
+ if( pNew==0 ) return SQLITE_NOMEM;
+ sqlite3GlobalConfig.pcache2.xCachesize(pNew, numberOfCachePages(pCache));
+ if( pCache->pCache ){
+ sqlite3GlobalConfig.pcache2.xDestroy(pCache->pCache);
+ }
+ pCache->pCache = pNew;
+ pCache->szPage = szPage;
}
+ return SQLITE_OK;
}
/*
** Try to obtain a page from the cache.
+**
+** This routine returns a pointer to an sqlite3_pcache_page object if
+** such an object is already in cache, or if a new one is created.
+** This routine returns a NULL pointer if the object was not in cache
+** and could not be created.
+**
+** The createFlags should be 0 to check for existing pages and should
+** be 3 (not 1, but 3) to try to create a new page.
+**
+** If the createFlag is 0, then NULL is always returned if the page
+** is not already in the cache. If createFlag is 1, then a new page
+** is created only if that can be done without spilling dirty pages
+** and without exceeding the cache size limit.
+**
+** The caller needs to invoke sqlite3PcacheFetchFinish() to properly
+** initialize the sqlite3_pcache_page object and convert it into a
+** PgHdr object. The sqlite3PcacheFetch() and sqlite3PcacheFetchFinish()
+** routines are split this way for performance reasons. When separated
+** they can both (usually) operate without having to push values to
+** the stack on entry and pop them back off on exit, which saves a
+** lot of pushing and popping.
*/
-SQLITE_PRIVATE int sqlite3PcacheFetch(
+SQLITE_PRIVATE sqlite3_pcache_page *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 */
+ int createFlag /* If true, create page if it does not exist already */
){
- sqlite3_pcache_page *pPage = 0;
- PgHdr *pPgHdr = 0;
int eCreate;
assert( pCache!=0 );
- assert( createFlag==1 || createFlag==0 );
+ assert( pCache->pCache!=0 );
+ assert( createFlag==3 || createFlag==0 );
assert( pgno>0 );
- /* If the pluggable cache (sqlite3_pcache*) has not been allocated,
- ** allocate it now.
+ /* eCreate defines what to do if the page does not exist.
+ ** 0 Do not allocate a new page. (createFlag==0)
+ ** 1 Allocate a new page if doing so is inexpensive.
+ ** (createFlag==1 AND bPurgeable AND pDirty)
+ ** 2 Allocate a new page even it doing so is difficult.
+ ** (createFlag==1 AND !(bPurgeable AND pDirty)
*/
- 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);
- }
+ eCreate = createFlag & pCache->eCreate;
+ assert( eCreate==0 || eCreate==1 || eCreate==2 );
+ assert( createFlag==0 || pCache->eCreate==eCreate );
+ assert( createFlag==0 || eCreate==1+(!pCache->bPurgeable||!pCache->pDirty) );
+ return sqlite3GlobalConfig.pcache2.xFetch(pCache->pCache, pgno, eCreate);
+}
- if( !pPage && eCreate==1 ){
- PgHdr *pPg;
+/*
+** If the sqlite3PcacheFetch() routine is unable to allocate a new
+** page because new clean pages are available for reuse and the cache
+** size limit has been reached, then this routine can be invoked to
+** try harder to allocate a page. This routine might invoke the stress
+** callback to spill dirty pages to the journal. It will then try to
+** allocate the new page and will only fail to allocate a new page on
+** an OOM error.
+**
+** This routine should be invoked only after sqlite3PcacheFetch() fails.
+*/
+SQLITE_PRIVATE int sqlite3PcacheFetchStress(
+ PCache *pCache, /* Obtain the page from this cache */
+ Pgno pgno, /* Page number to obtain */
+ sqlite3_pcache_page **ppPage /* Write result here */
+){
+ PgHdr *pPg;
+ if( pCache->eCreate==2 ) return 0;
+ if( sqlite3PcachePagecount(pCache)>pCache->szSpill ){
/* 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
@@ -35295,62 +41117,84 @@ SQLITE_PRIVATE int sqlite3PcacheFetch(
"spill page %d making room for %d - cache used: %d/%d",
pPg->pgno, pgno,
sqlite3GlobalConfig.pcache.xPagecount(pCache->pCache),
- numberOfCachePages(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);
}
+ *ppPage = sqlite3GlobalConfig.pcache2.xFetch(pCache->pCache, pgno, 2);
+ return *ppPage==0 ? SQLITE_NOMEM : SQLITE_OK;
+}
- 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;
- }
+/*
+** This is a helper routine for sqlite3PcacheFetchFinish()
+**
+** In the uncommon case where the page being fetched has not been
+** initialized, this routine is invoked to do the initialization.
+** This routine is broken out into a separate function since it
+** requires extra stack manipulation that can be avoided in the common
+** case.
+*/
+static SQLITE_NOINLINE PgHdr *pcacheFetchFinishWithInit(
+ PCache *pCache, /* Obtain the page from this cache */
+ Pgno pgno, /* Page number obtained */
+ sqlite3_pcache_page *pPage /* Page obtained by prior PcacheFetch() call */
+){
+ PgHdr *pPgHdr;
+ assert( pPage!=0 );
+ pPgHdr = (PgHdr*)pPage->pExtra;
+ assert( pPgHdr->pPage==0 );
+ 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;
+ pPgHdr->flags = PGHDR_CLEAN;
+ return sqlite3PcacheFetchFinish(pCache,pgno,pPage);
+}
+
+/*
+** This routine converts the sqlite3_pcache_page object returned by
+** sqlite3PcacheFetch() into an initialized PgHdr object. This routine
+** must be called after sqlite3PcacheFetch() in order to get a usable
+** result.
+*/
+SQLITE_PRIVATE PgHdr *sqlite3PcacheFetchFinish(
+ PCache *pCache, /* Obtain the page from this cache */
+ Pgno pgno, /* Page number obtained */
+ sqlite3_pcache_page *pPage /* Page obtained by prior PcacheFetch() call */
+){
+ PgHdr *pPgHdr;
+
+ assert( pPage!=0 );
+ pPgHdr = (PgHdr *)pPage->pExtra;
+
+ if( !pPgHdr->pPage ){
+ return pcacheFetchFinishWithInit(pCache, pgno, pPage);
}
- *ppPage = pPgHdr;
- return (pPgHdr==0 && eCreate) ? SQLITE_NOMEM : SQLITE_OK;
+ pCache->nRefSum++;
+ pPgHdr->nRef++;
+ return pPgHdr;
}
/*
** 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.
+** reference count drops to 0, then it is made eligible for recycling.
*/
-SQLITE_PRIVATE void sqlite3PcacheRelease(PgHdr *p){
+SQLITE_PRIVATE void SQLITE_NOINLINE 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 ){
+ p->pCache->nRefSum--;
+ if( (--p->nRef)==0 ){
+ if( p->flags&PGHDR_CLEAN ){
pcacheUnpin(p);
- }else{
+ }else if( p->pDirtyPrev!=0 ){
/* Move the page to the head of the dirty list. */
- pcacheRemoveFromDirtyList(p);
- pcacheAddToDirtyList(p);
+ pcacheManageDirtyList(p, PCACHE_DIRTYLIST_FRONT);
}
}
}
@@ -35361,6 +41205,7 @@ SQLITE_PRIVATE void sqlite3PcacheRelease(PgHdr *p){
SQLITE_PRIVATE void sqlite3PcacheRef(PgHdr *p){
assert(p->nRef>0);
p->nRef++;
+ p->pCache->nRefSum++;
}
/*
@@ -35369,17 +41214,12 @@ SQLITE_PRIVATE void sqlite3PcacheRef(PgHdr *p){
** 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);
+ pcacheManageDirtyList(p, PCACHE_DIRTYLIST_REMOVE);
}
- pCache = p->pCache;
- pCache->nRef--;
- if( p->pgno==1 ){
- pCache->pPage1 = 0;
- }
- sqlite3GlobalConfig.pcache2.xUnpin(pCache->pCache, p->pPage, 1);
+ p->pCache->nRefSum--;
+ sqlite3GlobalConfig.pcache2.xUnpin(p->pCache->pCache, p->pPage, 1);
}
/*
@@ -35387,11 +41227,14 @@ SQLITE_PRIVATE void sqlite3PcacheDrop(PgHdr *p){
** 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);
+ if( p->flags & (PGHDR_CLEAN|PGHDR_DONT_WRITE) ){
+ p->flags &= ~PGHDR_DONT_WRITE;
+ if( p->flags & PGHDR_CLEAN ){
+ p->flags ^= (PGHDR_DIRTY|PGHDR_CLEAN);
+ assert( (p->flags & (PGHDR_DIRTY|PGHDR_CLEAN))==PGHDR_DIRTY );
+ pcacheManageDirtyList(p, PCACHE_DIRTYLIST_ADD);
+ }
}
}
@@ -35401,8 +41244,10 @@ SQLITE_PRIVATE void sqlite3PcacheMakeDirty(PgHdr *p){
*/
SQLITE_PRIVATE void sqlite3PcacheMakeClean(PgHdr *p){
if( (p->flags & PGHDR_DIRTY) ){
- pcacheRemoveFromDirtyList(p);
- p->flags &= ~(PGHDR_DIRTY|PGHDR_NEED_SYNC);
+ assert( (p->flags & PGHDR_CLEAN)==0 );
+ pcacheManageDirtyList(p, PCACHE_DIRTYLIST_REMOVE);
+ p->flags &= ~(PGHDR_DIRTY|PGHDR_NEED_SYNC|PGHDR_WRITEABLE);
+ p->flags |= PGHDR_CLEAN;
if( p->nRef==0 ){
pcacheUnpin(p);
}
@@ -35440,8 +41285,7 @@ SQLITE_PRIVATE void sqlite3PcacheMove(PgHdr *p, Pgno newPgno){
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);
+ pcacheManageDirtyList(p, PCACHE_DIRTYLIST_FRONT);
}
}
@@ -35470,9 +41314,14 @@ SQLITE_PRIVATE void sqlite3PcacheTruncate(PCache *pCache, Pgno pgno){
sqlite3PcacheMakeClean(p);
}
}
- if( pgno==0 && pCache->pPage1 ){
- memset(pCache->pPage1->pData, 0, pCache->szPage);
- pgno = 1;
+ if( pgno==0 && pCache->nRefSum ){
+ sqlite3_pcache_page *pPage1;
+ pPage1 = sqlite3GlobalConfig.pcache2.xFetch(pCache->pCache,1,0);
+ if( ALWAYS(pPage1) ){ /* Page 1 is always available in cache, because
+ ** pCache->nRefSum>0 */
+ memset(pPage1->pBuf, 0, pCache->szPage);
+ pgno = 1;
+ }
}
sqlite3GlobalConfig.pcache2.xTruncate(pCache->pCache, pgno+1);
}
@@ -35482,9 +41331,8 @@ SQLITE_PRIVATE void sqlite3PcacheTruncate(PCache *pCache, Pgno pgno){
** Close a cache.
*/
SQLITE_PRIVATE void sqlite3PcacheClose(PCache *pCache){
- if( pCache->pCache ){
- sqlite3GlobalConfig.pcache2.xDestroy(pCache->pCache);
- }
+ assert( pCache->pCache!=0 );
+ sqlite3GlobalConfig.pcache2.xDestroy(pCache->pCache);
}
/*
@@ -35576,10 +41424,13 @@ SQLITE_PRIVATE PgHdr *sqlite3PcacheDirtyList(PCache *pCache){
}
/*
-** Return the total number of referenced pages held by the cache.
+** Return the total number of references to all pages held by the cache.
+**
+** This is not the total number of pages referenced, but the sum of the
+** reference count for all pages.
*/
SQLITE_PRIVATE int sqlite3PcacheRefCount(PCache *pCache){
- return pCache->nRef;
+ return pCache->nRefSum;
}
/*
@@ -35593,11 +41444,8 @@ SQLITE_PRIVATE int sqlite3PcachePageRefcount(PgHdr *p){
** 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;
+ assert( pCache->pCache!=0 );
+ return sqlite3GlobalConfig.pcache2.xPagecount(pCache->pCache);
}
#ifdef SQLITE_TEST
@@ -35613,22 +41461,46 @@ SQLITE_PRIVATE int sqlite3PcacheGetCachesize(PCache *pCache){
** Set the suggested cache-size value.
*/
SQLITE_PRIVATE void sqlite3PcacheSetCachesize(PCache *pCache, int mxPage){
+ assert( pCache->pCache!=0 );
pCache->szCache = mxPage;
- if( pCache->pCache ){
- sqlite3GlobalConfig.pcache2.xCachesize(pCache->pCache,
- numberOfCachePages(pCache));
+ sqlite3GlobalConfig.pcache2.xCachesize(pCache->pCache,
+ numberOfCachePages(pCache));
+}
+
+/*
+** Set the suggested cache-spill value. Make no changes if if the
+** argument is zero. Return the effective cache-spill size, which will
+** be the larger of the szSpill and szCache.
+*/
+SQLITE_PRIVATE int sqlite3PcacheSetSpillsize(PCache *p, int mxPage){
+ int res;
+ assert( p->pCache!=0 );
+ if( mxPage ){
+ if( mxPage<0 ){
+ mxPage = (int)((-1024*(i64)mxPage)/(p->szPage+p->szExtra));
+ }
+ p->szSpill = mxPage;
}
+ res = numberOfCachePages(p);
+ if( res<p->szSpill ) res = p->szSpill;
+ return res;
}
/*
** 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);
- }
+ assert( pCache->pCache!=0 );
+ sqlite3GlobalConfig.pcache2.xShrink(pCache->pCache);
}
+/*
+** Return the size of the header added by this middleware layer
+** in the page-cache hierarchy.
+*/
+SQLITE_PRIVATE int sqlite3HeaderSizePcache(void){ return ROUND8(sizeof(PgHdr)); }
+
+
#if defined(SQLITE_CHECK_PAGES) || defined(SQLITE_DEBUG)
/*
** For all dirty pages currently in the cache, invoke the specified
@@ -35660,18 +41532,100 @@ SQLITE_PRIVATE void sqlite3PcacheIterateDirty(PCache *pCache, void (*xIter)(PgHd
** 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
+** If the default page cache implementation is overridden, then neither of
** these two features are available.
+**
+** A Page cache line looks like this:
+**
+** -------------------------------------------------------------
+** | database page content | PgHdr1 | MemPage | PgHdr |
+** -------------------------------------------------------------
+**
+** The database page content is up front (so that buffer overreads tend to
+** flow harmlessly into the PgHdr1, MemPage, and PgHdr extensions). MemPage
+** is the extension added by the btree.c module containing information such
+** as the database page number and how that database page is used. PgHdr
+** is added by the pcache.c layer and contains information used to keep track
+** of which pages are "dirty". PgHdr1 is an extension added by this
+** module (pcache1.c). The PgHdr1 header is a subclass of sqlite3_pcache_page.
+** PgHdr1 contains information needed to look up a page by its page number.
+** The superclass sqlite3_pcache_page.pBuf points to the start of the
+** database page content and sqlite3_pcache_page.pExtra points to PgHdr.
+**
+** The size of the extension (MemPage+PgHdr+PgHdr1) can be determined at
+** runtime using sqlite3_config(SQLITE_CONFIG_PCACHE_HDRSZ, &size). The
+** sizes of the extensions sum to 272 bytes on x64 for 3.8.10, but this
+** size can vary according to architecture, compile-time options, and
+** SQLite library version number.
+**
+** If SQLITE_PCACHE_SEPARATE_HEADER is defined, then the extension is obtained
+** using a separate memory allocation from the database page content. This
+** seeks to overcome the "clownshoe" problem (also called "internal
+** fragmentation" in academic literature) of allocating a few bytes more
+** than a power of two with the memory allocator rounding up to the next
+** power of two, and leaving the rounded-up space unused.
+**
+** This module tracks pointers to PgHdr1 objects. Only pcache.c communicates
+** with this module. Information is passed back and forth as PgHdr1 pointers.
+**
+** The pcache.c and pager.c modules deal pointers to PgHdr objects.
+** The btree.c module deals with pointers to MemPage objects.
+**
+** SOURCE OF PAGE CACHE MEMORY:
+**
+** Memory for a page might come from any of three sources:
+**
+** (1) The general-purpose memory allocator - sqlite3Malloc()
+** (2) Global page-cache memory provided using sqlite3_config() with
+** SQLITE_CONFIG_PAGECACHE.
+** (3) PCache-local bulk allocation.
+**
+** The third case is a chunk of heap memory (defaulting to 100 pages worth)
+** that is allocated when the page cache is created. The size of the local
+** bulk allocation can be adjusted using
+**
+** sqlite3_config(SQLITE_CONFIG_PAGECACHE, (void*)0, 0, N).
+**
+** If N is positive, then N pages worth of memory are allocated using a single
+** sqlite3Malloc() call and that memory is used for the first N pages allocated.
+** Or if N is negative, then -1024*N bytes of memory are allocated and used
+** for as many pages as can be accomodated.
+**
+** Only one of (2) or (3) can be used. Once the memory available to (2) or
+** (3) is exhausted, subsequent allocations fail over to the general-purpose
+** memory allocator (1).
+**
+** Earlier versions of SQLite used only methods (1) and (2). But experiments
+** show that method (3) with N==100 provides about a 5% performance boost for
+** common workloads.
*/
-
+/* #include "sqliteInt.h" */
typedef struct PCache1 PCache1;
typedef struct PgHdr1 PgHdr1;
typedef struct PgFreeslot PgFreeslot;
typedef struct PGroup PGroup;
+/*
+** 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; /* Base class. Must be first. pBuf & pExtra */
+ unsigned int iKey; /* Key value (page number) */
+ u8 isPinned; /* Page in use, not on the LRU list */
+ u8 isBulkLocal; /* This page from bulk local storage */
+ u8 isAnchor; /* This is the PGroup.lru element */
+ 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 */
+};
+
/* 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
+** of one or more PCaches that are able to recycle each other's unpinned
** pages when they are under memory pressure. A PGroup is an instance of
** the following object.
**
@@ -35698,7 +41652,7 @@ struct PGroup {
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 */
+ PgHdr1 lru; /* The beginning and end of the LRU list */
};
/* Each page cache is an instance of the following object. Every
@@ -35716,8 +41670,9 @@ struct PCache1 {
** 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 szPage; /* Size of database content section */
+ int szExtra; /* sizeof(MemPage)+sizeof(PgHdr) */
+ int szAlloc; /* Total size of one pcache line */
int bPurgeable; /* True if cache is purgeable */
unsigned int nMin; /* Minimum number of pages reserved */
unsigned int nMax; /* Configured "cache_size" value */
@@ -35731,26 +41686,13 @@ struct PCache1 {
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 */
+ PgHdr1 *pFree; /* List of unused pcache-local pages */
+ void *pBulk; /* Bulk memory used by pcache-local */
};
/*
-** 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.
+** Free slots in the allocator used to divide up the global page cache
+** buffer provided using the SQLITE_CONFIG_PAGECACHE mechanism.
*/
struct PgFreeslot {
PgFreeslot *pNext; /* Next free slot */
@@ -35768,10 +41710,12 @@ static SQLITE_WSD struct PCacheGlobal {
** The nFreeSlot and pFree values do require mutex protection.
*/
int isInit; /* True if initialized */
+ int separateCache; /* Use a new PGroup for each PCache */
+ int nInitPage; /* Initial bulk allocation size */
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 */
+ void *pStart, *pEnd; /* Bounds of global page cache memory */
/* Above requires no mutex. Use mutex below for variable that follow. */
sqlite3_mutex *mutex; /* Mutex for accessing the following: */
PgFreeslot *pFree; /* Free page blocks */
@@ -35793,12 +41737,20 @@ static SQLITE_WSD struct PCacheGlobal {
/*
** 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)
+#if !defined(SQLITE_ENABLE_MEMORY_MANAGEMENT) || SQLITE_THREADSAFE==0
+# define pcache1EnterMutex(X) assert((X)->mutex==0)
+# define pcache1LeaveMutex(X) assert((X)->mutex==0)
+# define PCACHE1_MIGHT_USE_GROUP_MUTEX 0
+#else
+# define pcache1EnterMutex(X) sqlite3_mutex_enter((X)->mutex)
+# define pcache1LeaveMutex(X) sqlite3_mutex_leave((X)->mutex)
+# define PCACHE1_MIGHT_USE_GROUP_MUTEX 1
+#endif
/******************************************************************************/
/******** 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
@@ -35811,6 +41763,7 @@ static SQLITE_WSD struct PCacheGlobal {
SQLITE_PRIVATE void sqlite3PCacheBufferSetup(void *pBuf, int sz, int n){
if( pcache1.isInit ){
PgFreeslot *p;
+ if( pBuf==0 ) sz = n = 0;
sz = ROUNDDOWN8(sz);
pcache1.szSlot = sz;
pcache1.nSlot = pcache1.nFreeSlot = n;
@@ -35829,6 +41782,44 @@ SQLITE_PRIVATE void sqlite3PCacheBufferSetup(void *pBuf, int sz, int n){
}
/*
+** Try to initialize the pCache->pFree and pCache->pBulk fields. Return
+** true if pCache->pFree ends up containing one or more free pages.
+*/
+static int pcache1InitBulk(PCache1 *pCache){
+ i64 szBulk;
+ char *zBulk;
+ if( pcache1.nInitPage==0 ) return 0;
+ /* Do not bother with a bulk allocation if the cache size very small */
+ if( pCache->nMax<3 ) return 0;
+ sqlite3BeginBenignMalloc();
+ if( pcache1.nInitPage>0 ){
+ szBulk = pCache->szAlloc * (i64)pcache1.nInitPage;
+ }else{
+ szBulk = -1024 * (i64)pcache1.nInitPage;
+ }
+ if( szBulk > pCache->szAlloc*(i64)pCache->nMax ){
+ szBulk = pCache->szAlloc*pCache->nMax;
+ }
+ zBulk = pCache->pBulk = sqlite3Malloc( szBulk );
+ sqlite3EndBenignMalloc();
+ if( zBulk ){
+ int nBulk = sqlite3MallocSize(zBulk)/pCache->szAlloc;
+ int i;
+ for(i=0; i<nBulk; i++){
+ PgHdr1 *pX = (PgHdr1*)&zBulk[pCache->szPage];
+ pX->page.pBuf = zBulk;
+ pX->page.pExtra = &pX[1];
+ pX->isBulkLocal = 1;
+ pX->isAnchor = 0;
+ pX->pNext = pCache->pFree;
+ pCache->pFree = pX;
+ zBulk += pCache->szAlloc;
+ }
+ }
+ return pCache->pFree!=0;
+}
+
+/*
** 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
@@ -35840,7 +41831,6 @@ SQLITE_PRIVATE void sqlite3PCacheBufferSetup(void *pBuf, int sz, int n){
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;
@@ -35849,7 +41839,8 @@ static void *pcache1Alloc(int nByte){
pcache1.nFreeSlot--;
pcache1.bUnderPressure = pcache1.nFreeSlot<pcache1.nReserve;
assert( pcache1.nFreeSlot>=0 );
- sqlite3StatusAdd(SQLITE_STATUS_PAGECACHE_USED, 1);
+ sqlite3StatusHighwater(SQLITE_STATUS_PAGECACHE_SIZE, nByte);
+ sqlite3StatusUp(SQLITE_STATUS_PAGECACHE_USED, 1);
}
sqlite3_mutex_leave(pcache1.mutex);
}
@@ -35862,7 +41853,8 @@ static void *pcache1Alloc(int nByte){
if( p ){
int sz = sqlite3MallocSize(p);
sqlite3_mutex_enter(pcache1.mutex);
- sqlite3StatusAdd(SQLITE_STATUS_PAGECACHE_OVERFLOW, sz);
+ sqlite3StatusHighwater(SQLITE_STATUS_PAGECACHE_SIZE, nByte);
+ sqlite3StatusUp(SQLITE_STATUS_PAGECACHE_OVERFLOW, sz);
sqlite3_mutex_leave(pcache1.mutex);
}
#endif
@@ -35874,13 +41866,13 @@ static void *pcache1Alloc(int nByte){
/*
** Free an allocated buffer obtained from pcache1Alloc().
*/
-static int pcache1Free(void *p){
+static void pcache1Free(void *p){
int nFreed = 0;
- if( p==0 ) return 0;
- if( p>=pcache1.pStart && p<pcache1.pEnd ){
+ if( p==0 ) return;
+ if( SQLITE_WITHIN(p, pcache1.pStart, pcache1.pEnd) ){
PgFreeslot *pSlot;
sqlite3_mutex_enter(pcache1.mutex);
- sqlite3StatusAdd(SQLITE_STATUS_PAGECACHE_USED, -1);
+ sqlite3StatusDown(SQLITE_STATUS_PAGECACHE_USED, 1);
pSlot = (PgFreeslot*)p;
pSlot->pNext = pcache1.pFree;
pcache1.pFree = pSlot;
@@ -35891,15 +41883,14 @@ static int pcache1Free(void *p){
}else{
assert( sqlite3MemdebugHasType(p, MEMTYPE_PCACHE) );
sqlite3MemdebugSetType(p, MEMTYPE_HEAP);
- nFreed = sqlite3MallocSize(p);
#ifndef SQLITE_DISABLE_PAGECACHE_OVERFLOW_STATS
+ nFreed = sqlite3MallocSize(p);
sqlite3_mutex_enter(pcache1.mutex);
- sqlite3StatusAdd(SQLITE_STATUS_PAGECACHE_OVERFLOW, -nFreed);
+ sqlite3StatusDown(SQLITE_STATUS_PAGECACHE_OVERFLOW, nFreed);
sqlite3_mutex_leave(pcache1.mutex);
#endif
sqlite3_free(p);
}
- return nFreed;
}
#ifdef SQLITE_ENABLE_MEMORY_MANAGEMENT
@@ -35923,58 +41914,72 @@ static int pcache1MemSize(void *p){
/*
** Allocate a new page object initially associated with cache pCache.
*/
-static PgHdr1 *pcache1AllocPage(PCache1 *pCache){
+static PgHdr1 *pcache1AllocPage(PCache1 *pCache, int benignMalloc){
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);
+ if( pCache->pFree || (pCache->nPage==0 && pcache1InitBulk(pCache)) ){
+ p = pCache->pFree;
+ pCache->pFree = p->pNext;
+ p->pNext = 0;
+ }else{
+#ifdef SQLITE_ENABLE_MEMORY_MANAGEMENT
+ /* The group mutex must be released before pcache1Alloc() is called. This
+ ** is because it might call sqlite3_release_memory(), which assumes that
+ ** this mutex is not held. */
+ assert( pcache1.separateCache==0 );
+ assert( pCache->pGroup==&pcache1.grp );
+ pcache1LeaveMutex(pCache->pGroup);
+#endif
+ if( benignMalloc ){ sqlite3BeginBenignMalloc(); }
#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;
- }
+ 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];
+ pPg = pcache1Alloc(pCache->szAlloc);
+ p = (PgHdr1 *)&((u8 *)pPg)[pCache->szPage];
#endif
- pcache1EnterMutex(pCache->pGroup);
-
- if( pPg ){
+ if( benignMalloc ){ sqlite3EndBenignMalloc(); }
+#ifdef SQLITE_ENABLE_MEMORY_MANAGEMENT
+ pcache1EnterMutex(pCache->pGroup);
+#endif
+ if( pPg==0 ) return 0;
p->page.pBuf = pPg;
p->page.pExtra = &p[1];
- if( pCache->bPurgeable ){
- pCache->pGroup->nCurrentPage++;
- }
- return p;
+ p->isBulkLocal = 0;
+ p->isAnchor = 0;
}
- return 0;
+ if( pCache->bPurgeable ){
+ pCache->pGroup->nCurrentPage++;
+ }
+ return p;
}
/*
** 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) );
+ PCache1 *pCache;
+ assert( p!=0 );
+ pCache = p->pCache;
+ assert( sqlite3_mutex_held(p->pCache->pGroup->mutex) );
+ if( p->isBulkLocal ){
+ p->pNext = pCache->pFree;
+ pCache->pFree = p;
+ }else{
pcache1Free(p->page.pBuf);
#ifdef SQLITE_PCACHE_SEPARATE_HEADER
sqlite3_free(p);
#endif
- if( pCache->bPurgeable ){
- pCache->pGroup->nCurrentPage--;
- }
+ }
+ if( pCache->bPurgeable ){
+ pCache->pGroup->nCurrentPage--;
}
}
@@ -36028,7 +42033,7 @@ static int pcache1UnderMemoryPressure(PCache1 *pCache){
**
** The PCache mutex must be held when this function is called.
*/
-static int pcache1ResizeHash(PCache1 *p){
+static void pcache1ResizeHash(PCache1 *p){
PgHdr1 **apNew;
unsigned int nNew;
unsigned int i;
@@ -36060,8 +42065,6 @@ static int pcache1ResizeHash(PCache1 *p){
p->apHash = apNew;
p->nHash = nNew;
}
-
- return (p->apHash ? SQLITE_OK : SQLITE_NOMEM);
}
/*
@@ -36070,44 +42073,36 @@ static int pcache1ResizeHash(PCache1 *p){
** 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){
+static PgHdr1 *pcache1PinPage(PgHdr1 *pPage){
PCache1 *pCache;
- PGroup *pGroup;
- if( pPage==0 ) return;
+ assert( pPage!=0 );
+ assert( pPage->isPinned==0 );
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--;
- }
+ assert( pPage->pLruNext );
+ assert( pPage->pLruPrev );
+ assert( sqlite3_mutex_held(pCache->pGroup->mutex) );
+ pPage->pLruPrev->pLruNext = pPage->pLruNext;
+ pPage->pLruNext->pLruPrev = pPage->pLruPrev;
+ pPage->pLruNext = 0;
+ pPage->pLruPrev = 0;
+ pPage->isPinned = 1;
+ assert( pPage->isAnchor==0 );
+ assert( pCache->pGroup->lru.isAnchor==1 );
+ pCache->nRecyclable--;
+ return pPage;
}
/*
** Remove the page supplied as an argument from the hash table
** (PCache1.apHash structure) that it is currently stored in.
+** Also free the page if freePage is true.
**
** The PGroup mutex must be held when this function is called.
*/
-static void pcache1RemoveFromHash(PgHdr1 *pPage){
+static void pcache1RemoveFromHash(PgHdr1 *pPage, int freeFlag){
unsigned int h;
PCache1 *pCache = pPage->pCache;
PgHdr1 **pp;
@@ -36118,20 +42113,28 @@ static void pcache1RemoveFromHash(PgHdr1 *pPage){
*pp = (*pp)->pNext;
pCache->nPage--;
+ if( freeFlag ) pcache1FreePage(pPage);
}
/*
** 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){
+static void pcache1EnforceMaxPage(PCache1 *pCache){
+ PGroup *pGroup = pCache->pGroup;
+ PgHdr1 *p;
assert( sqlite3_mutex_held(pGroup->mutex) );
- while( pGroup->nCurrentPage>pGroup->nMaxPage && pGroup->pLruTail ){
- PgHdr1 *p = pGroup->pLruTail;
+ while( pGroup->nCurrentPage>pGroup->nMaxPage
+ && (p=pGroup->lru.pLruPrev)->isAnchor==0
+ ){
assert( p->pCache->pGroup==pGroup );
+ assert( p->isPinned==0 );
pcache1PinPage(p);
- pcache1RemoveFromHash(p);
- pcache1FreePage(p);
+ pcache1RemoveFromHash(p, 1);
+ }
+ if( pCache->nPage==0 && pCache->pBulk ){
+ sqlite3_free(pCache->pBulk);
+ pCache->pBulk = pCache->pFree = 0;
}
}
@@ -36156,7 +42159,7 @@ static void pcache1TruncateUnsafe(
if( pPage->iKey>=iLimit ){
pCache->nPage--;
*pp = pPage->pNext;
- pcache1PinPage(pPage);
+ if( !pPage->isPinned ) pcache1PinPage(pPage);
pcache1FreePage(pPage);
}else{
pp = &pPage->pNext;
@@ -36177,10 +42180,45 @@ static int pcache1Init(void *NotUsed){
UNUSED_PARAMETER(NotUsed);
assert( pcache1.isInit==0 );
memset(&pcache1, 0, sizeof(pcache1));
+
+
+ /*
+ ** The pcache1.separateCache variable is true if each PCache has its own
+ ** private PGroup (mode-1). pcache1.separateCache is false if the single
+ ** PGroup in pcache1.grp is used for all page caches (mode-2).
+ **
+ ** * Always use a unified cache (mode-2) if ENABLE_MEMORY_MANAGEMENT
+ **
+ ** * Use a unified cache in single-threaded applications that have
+ ** configured a start-time buffer for use as page-cache memory using
+ ** sqlite3_config(SQLITE_CONFIG_PAGECACHE, pBuf, sz, N) with non-NULL
+ ** pBuf argument.
+ **
+ ** * Otherwise use separate caches (mode-1)
+ */
+#if defined(SQLITE_ENABLE_MEMORY_MANAGEMENT)
+ pcache1.separateCache = 0;
+#elif SQLITE_THREADSAFE
+ pcache1.separateCache = sqlite3GlobalConfig.pPage==0
+ || sqlite3GlobalConfig.bCoreMutex>0;
+#else
+ pcache1.separateCache = sqlite3GlobalConfig.pPage==0;
+#endif
+
+#if SQLITE_THREADSAFE
if( sqlite3GlobalConfig.bCoreMutex ){
pcache1.grp.mutex = sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_LRU);
pcache1.mutex = sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_PMEM);
}
+#endif
+ if( pcache1.separateCache
+ && sqlite3GlobalConfig.nPage!=0
+ && sqlite3GlobalConfig.pPage==0
+ ){
+ pcache1.nInitPage = sqlite3GlobalConfig.nPage;
+ }else{
+ pcache1.nInitPage = 0;
+ }
pcache1.grp.mxPinned = 10;
pcache1.isInit = 1;
return SQLITE_OK;
@@ -36197,6 +42235,9 @@ static void pcache1Shutdown(void *NotUsed){
memset(&pcache1, 0, sizeof(pcache1));
}
+/* forward declaration */
+static void pcache1Destroy(sqlite3_pcache *p);
+
/*
** Implementation of the sqlite3_pcache.xCreate method.
**
@@ -36207,46 +42248,38 @@ static sqlite3_pcache *pcache1Create(int szPage, int szExtra, int bPurgeable){
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;
+ sz = sizeof(PCache1) + sizeof(PGroup)*pcache1.separateCache;
pCache = (PCache1 *)sqlite3MallocZero(sz);
if( pCache ){
- if( separateCache ){
+ if( pcache1.separateCache ){
pGroup = (PGroup*)&pCache[1];
pGroup->mxPinned = 10;
}else{
pGroup = &pcache1.grp;
}
+ if( pGroup->lru.isAnchor==0 ){
+ pGroup->lru.isAnchor = 1;
+ pGroup->lru.pLruPrev = pGroup->lru.pLruNext = &pGroup->lru;
+ }
pCache->pGroup = pGroup;
pCache->szPage = szPage;
pCache->szExtra = szExtra;
+ pCache->szAlloc = szPage + szExtra + ROUND8(sizeof(PgHdr1));
pCache->bPurgeable = (bPurgeable ? 1 : 0);
+ pcache1EnterMutex(pGroup);
+ pcache1ResizeHash(pCache);
if( bPurgeable ){
pCache->nMin = 10;
- pcache1EnterMutex(pGroup);
pGroup->nMinPage += pCache->nMin;
pGroup->mxPinned = pGroup->nMaxPage + 10 - pGroup->nMinPage;
- pcache1LeaveMutex(pGroup);
+ }
+ pcache1LeaveMutex(pGroup);
+ if( pCache->nHash==0 ){
+ pcache1Destroy((sqlite3_pcache*)pCache);
+ pCache = 0;
}
}
return (sqlite3_pcache *)pCache;
@@ -36266,7 +42299,7 @@ static void pcache1Cachesize(sqlite3_pcache *p, int nMax){
pGroup->mxPinned = pGroup->nMaxPage + 10 - pGroup->nMinPage;
pCache->nMax = nMax;
pCache->n90pct = pCache->nMax*9/10;
- pcache1EnforceMaxPage(pGroup);
+ pcache1EnforceMaxPage(pCache);
pcache1LeaveMutex(pGroup);
}
}
@@ -36284,7 +42317,7 @@ static void pcache1Shrink(sqlite3_pcache *p){
pcache1EnterMutex(pGroup);
savedMaxPage = pGroup->nMaxPage;
pGroup->nMaxPage = 0;
- pcache1EnforceMaxPage(pGroup);
+ pcache1EnforceMaxPage(pCache);
pGroup->nMaxPage = savedMaxPage;
pcache1LeaveMutex(pGroup);
}
@@ -36302,6 +42335,84 @@ static int pcache1Pagecount(sqlite3_pcache *p){
return n;
}
+
+/*
+** Implement steps 3, 4, and 5 of the pcache1Fetch() algorithm described
+** in the header of the pcache1Fetch() procedure.
+**
+** This steps are broken out into a separate procedure because they are
+** usually not needed, and by avoiding the stack initialization required
+** for these steps, the main pcache1Fetch() procedure can run faster.
+*/
+static SQLITE_NOINLINE PgHdr1 *pcache1FetchStage2(
+ PCache1 *pCache,
+ unsigned int iKey,
+ int createFlag
+){
+ unsigned int nPinned;
+ PGroup *pGroup = pCache->pGroup;
+ PgHdr1 *pPage = 0;
+
+ /* 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) && pCache->nRecyclable<nPinned)
+ )){
+ return 0;
+ }
+
+ if( pCache->nPage>=pCache->nHash ) pcache1ResizeHash(pCache);
+ assert( pCache->nHash>0 && pCache->apHash );
+
+ /* Step 4. Try to recycle a page. */
+ if( pCache->bPurgeable
+ && !pGroup->lru.pLruPrev->isAnchor
+ && ((pCache->nPage+1>=pCache->nMax) || pcache1UnderMemoryPressure(pCache))
+ ){
+ PCache1 *pOther;
+ pPage = pGroup->lru.pLruPrev;
+ assert( pPage->isPinned==0 );
+ pcache1RemoveFromHash(pPage, 0);
+ pcache1PinPage(pPage);
+ pOther = pPage->pCache;
+ if( pOther->szAlloc != pCache->szAlloc ){
+ 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 ){
+ pPage = pcache1AllocPage(pCache, createFlag==1);
+ }
+
+ 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;
+ pPage->isPinned = 1;
+ *(void **)pPage->page.pExtra = 0;
+ pCache->apHash[h] = pPage;
+ if( iKey>pCache->iMaxKey ){
+ pCache->iMaxKey = iKey;
+ }
+ }
+ return pPage;
+}
+
/*
** Implementation of the sqlite3_pcache.xFetch method.
**
@@ -36355,117 +42466,80 @@ static int pcache1Pagecount(sqlite3_pcache *p){
** proceed to step 5.
**
** 5. Otherwise, allocate and return a new page buffer.
+**
+** There are two versions of this routine. pcache1FetchWithMutex() is
+** the general case. pcache1FetchNoMutex() is a faster implementation for
+** the common case where pGroup->mutex is NULL. The pcache1Fetch() wrapper
+** invokes the appropriate routine.
*/
-static sqlite3_pcache_page *pcache1Fetch(
+static PgHdr1 *pcache1FetchNoMutex(
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;
- }
+ pPage = pCache->apHash[iKey % pCache->nHash];
+ while( pPage && pPage->iKey!=iKey ){ pPage = pPage->pNext; }
- /* 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;
+ /* Step 2: If the page was found in the hash table, then return it.
+ ** If the page was not in the hash table and createFlag is 0, abort.
+ ** Otherwise (page not in hash and createFlag!=0) continue with
+ ** subsequent steps to try to create the page. */
+ if( pPage ){
+ if( !pPage->isPinned ){
+ return pcache1PinPage(pPage);
}else{
- pGroup->nCurrentPage -= (pOther->bPurgeable - pCache->bPurgeable);
+ return pPage;
}
+ }else if( createFlag ){
+ /* Steps 3, 4, and 5 implemented by this subroutine */
+ return pcache1FetchStage2(pCache, iKey, createFlag);
+ }else{
+ return 0;
}
+}
+#if PCACHE1_MIGHT_USE_GROUP_MUTEX
+static PgHdr1 *pcache1FetchWithMutex(
+ sqlite3_pcache *p,
+ unsigned int iKey,
+ int createFlag
+){
+ PCache1 *pCache = (PCache1 *)p;
+ PgHdr1 *pPage;
- /* 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;
- }
+ pcache1EnterMutex(pCache->pGroup);
+ pPage = pcache1FetchNoMutex(p, iKey, createFlag);
+ assert( pPage==0 || pCache->iMaxKey>=iKey );
+ pcache1LeaveMutex(pCache->pGroup);
+ return pPage;
+}
+#endif
+static sqlite3_pcache_page *pcache1Fetch(
+ sqlite3_pcache *p,
+ unsigned int iKey,
+ int createFlag
+){
+#if PCACHE1_MIGHT_USE_GROUP_MUTEX || defined(SQLITE_DEBUG)
+ PCache1 *pCache = (PCache1 *)p;
+#endif
-fetch_out:
- if( pPage && iKey>pCache->iMaxKey ){
- pCache->iMaxKey = iKey;
+ assert( offsetof(PgHdr1,page)==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 );
+ assert( pCache->nHash>0 );
+#if PCACHE1_MIGHT_USE_GROUP_MUTEX
+ if( pCache->pGroup->mutex ){
+ return (sqlite3_pcache_page*)pcache1FetchWithMutex(p, iKey, createFlag);
+ }else
+#endif
+ {
+ return (sqlite3_pcache_page*)pcache1FetchNoMutex(p, iKey, createFlag);
}
- pcache1LeaveMutex(pGroup);
- return &pPage->page;
}
@@ -36490,22 +42564,18 @@ static void pcache1Unpin(
** part of the PGroup LRU list.
*/
assert( pPage->pLruPrev==0 && pPage->pLruNext==0 );
- assert( pGroup->pLruHead!=pPage && pGroup->pLruTail!=pPage );
+ assert( pPage->isPinned==1 );
if( reuseUnlikely || pGroup->nCurrentPage>pGroup->nMaxPage ){
- pcache1RemoveFromHash(pPage);
- pcache1FreePage(pPage);
+ pcache1RemoveFromHash(pPage, 1);
}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;
- }
+ PgHdr1 **ppFirst = &pGroup->lru.pLruNext;
+ pPage->pLruPrev = &pGroup->lru;
+ (pPage->pLruNext = *ppFirst)->pLruPrev = pPage;
+ *ppFirst = pPage;
pCache->nRecyclable++;
+ pPage->isPinned = 0;
}
pcache1LeaveMutex(pCache->pGroup);
@@ -36580,8 +42650,9 @@ static void pcache1Destroy(sqlite3_pcache *p){
assert( pGroup->nMinPage >= pCache->nMin );
pGroup->nMinPage -= pCache->nMin;
pGroup->mxPinned = pGroup->nMaxPage + 10 - pGroup->nMinPage;
- pcache1EnforceMaxPage(pGroup);
+ pcache1EnforceMaxPage(pCache);
pcache1LeaveMutex(pGroup);
+ sqlite3_free(pCache->pBulk);
sqlite3_free(pCache->apHash);
sqlite3_free(pCache);
}
@@ -36610,6 +42681,19 @@ SQLITE_PRIVATE void sqlite3PCacheSetDefault(void){
sqlite3_config(SQLITE_CONFIG_PCACHE2, &defaultMethods);
}
+/*
+** Return the size of the header on each page of this PCACHE implementation.
+*/
+SQLITE_PRIVATE int sqlite3HeaderSizePcache1(void){ return ROUND8(sizeof(PgHdr1)); }
+
+/*
+** Return the global mutex used by this PCACHE implementation. The
+** sqlite3_status() routine needs access to this mutex.
+*/
+SQLITE_PRIVATE sqlite3_mutex *sqlite3Pcache1Mutex(void){
+ return pcache1.mutex;
+}
+
#ifdef SQLITE_ENABLE_MEMORY_MANAGEMENT
/*
** This function is called to free superfluous dynamically allocated memory
@@ -36624,17 +42708,20 @@ 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 ){
+ if( sqlite3GlobalConfig.nPage==0 ){
PgHdr1 *p;
pcache1EnterMutex(&pcache1.grp);
- while( (nReq<0 || nFree<nReq) && ((p=pcache1.grp.pLruTail)!=0) ){
+ while( (nReq<0 || nFree<nReq)
+ && (p=pcache1.grp.lru.pLruPrev)!=0
+ && p->isAnchor==0
+ ){
nFree += pcache1MemSize(p->page.pBuf);
#ifdef SQLITE_PCACHE_SEPARATE_HEADER
nFree += sqlite3MemSize(p);
#endif
+ assert( p->isPinned==0 );
pcache1PinPage(p);
- pcache1RemoveFromHash(p);
- pcache1FreePage(p);
+ pcache1RemoveFromHash(p, 1);
}
pcache1LeaveMutex(&pcache1.grp);
}
@@ -36655,7 +42742,8 @@ SQLITE_PRIVATE void sqlite3PcacheStats(
){
PgHdr1 *p;
int nRecyclable = 0;
- for(p=pcache1.grp.pLruHead; p; p=p->pLruNext){
+ for(p=pcache1.grp.lru.pLruNext; p && !p->isAnchor; p=p->pLruNext){
+ assert( p->isPinned==0 );
nRecyclable++;
}
*pnCurrent = pcache1.grp.nCurrentPage;
@@ -36719,7 +42807,7 @@ SQLITE_PRIVATE void sqlite3PcacheStats(
** 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
+** The cost of an INSERT is roughly constant. (Sometimes 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
@@ -36729,6 +42817,7 @@ SQLITE_PRIVATE void sqlite3PcacheStats(
** There is an added cost of O(N) when switching between TEST and
** SMALLEST primitives.
*/
+/* #include "sqliteInt.h" */
/*
@@ -36780,8 +42869,8 @@ struct RowSet {
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 */
+ u16 rsFlags; /* Various flags */
+ int iBatch; /* Current insert batch */
};
/*
@@ -37111,11 +43200,11 @@ SQLITE_PRIVATE int sqlite3RowSetNext(RowSet *p, i64 *pRowid){
** 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
+** If this is the first test of a new batch and if there exist entries
+** on pRowSet->pEntry, then sort those entries into the forest at
** pRowSet->pForest so that they can be tested.
*/
-SQLITE_PRIVATE int sqlite3RowSetTest(RowSet *pRowSet, u8 iBatch, sqlite3_int64 iRowid){
+SQLITE_PRIVATE int sqlite3RowSetTest(RowSet *pRowSet, int iBatch, sqlite3_int64 iRowid){
struct RowSetEntry *p, *pTree;
/* This routine is never called after sqlite3RowSetNext() */
@@ -37198,6 +43287,7 @@ SQLITE_PRIVATE int sqlite3RowSetTest(RowSet *pRowSet, u8 iBatch, sqlite3_int64 i
** another is writing.
*/
#ifndef SQLITE_OMIT_DISKIO
+/* #include "sqliteInt.h" */
/************** Include wal.h in the middle of pager.c ***********************/
/************** Begin file wal.h *********************************************/
/*
@@ -37219,6 +43309,7 @@ SQLITE_PRIVATE int sqlite3RowSetTest(RowSet *pRowSet, u8 iBatch, sqlite3_int64 i
#ifndef _WAL_H_
#define _WAL_H_
+/* #include "sqliteInt.h" */
/* Additional values that can be added to the sync_flags argument of
** sqlite3WalFrames():
@@ -37232,7 +43323,6 @@ SQLITE_PRIVATE int sqlite3RowSetTest(RowSet *pRowSet, u8 iBatch, sqlite3_int64 i
# 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
@@ -37245,6 +43335,8 @@ SQLITE_PRIVATE int sqlite3RowSetTest(RowSet *pRowSet, u8 iBatch, sqlite3_int64 i
# define sqlite3WalExclusiveMode(y,z) 0
# define sqlite3WalHeapMemory(z) 0
# define sqlite3WalFramesize(z) 0
+# define sqlite3WalFindFrame(x,y,z) 0
+# define sqlite3WalFile(x) 0
#else
#define WAL_SAVEPOINT_NDATA 4
@@ -37272,7 +43364,8 @@ 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);
+SQLITE_PRIVATE int sqlite3WalFindFrame(Wal *, Pgno, u32 *);
+SQLITE_PRIVATE int sqlite3WalReadFrame(Wal *, u32, int, u8 *);
/* If the WAL is not empty, return the size of the database. */
SQLITE_PRIVATE Pgno sqlite3WalDbsize(Wal *pWal);
@@ -37326,6 +43419,11 @@ SQLITE_PRIVATE int sqlite3WalExclusiveMode(Wal *pWal, int op);
*/
SQLITE_PRIVATE int sqlite3WalHeapMemory(Wal *pWal);
+#ifdef SQLITE_ENABLE_SNAPSHOT
+SQLITE_PRIVATE int sqlite3WalSnapshotGet(Wal *pWal, sqlite3_snapshot **ppSnapshot);
+SQLITE_PRIVATE void sqlite3WalSnapshotOpen(Wal *pWal, sqlite3_snapshot *pSnapshot);
+#endif
+
#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).
@@ -37333,6 +43431,9 @@ SQLITE_PRIVATE int sqlite3WalHeapMemory(Wal *pWal);
SQLITE_PRIVATE int sqlite3WalFramesize(Wal *pWal);
#endif
+/* Return the sqlite3_file object for the WAL file */
+SQLITE_PRIVATE sqlite3_file *sqlite3WalFile(Wal *pWal);
+
#endif /* ifndef SQLITE_OMIT_WAL */
#endif /* _WAL_H_ */
@@ -37393,12 +43494,12 @@ SQLITE_PRIVATE int sqlite3WalFramesize(Wal *pWal);
** 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
+** pages can be changed arbitrarily without affecting 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
+** journal is rolled back, the resulting database file will be logically
** equivalent to the database file at the beginning of the transaction.
**
** (8) When a transaction is rolled back, the xTruncate method of the VFS
@@ -37590,7 +43691,7 @@ int sqlite3PagerTrace=1; /* True to enable tracing */
** * 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
+** If no error occurred, 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.
**
@@ -37695,7 +43796,7 @@ int sqlite3PagerTrace=1; /* True to enable tracing */
**
** 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
+** in the file-system that needs to be rolled back (as part of an 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
@@ -37771,7 +43872,14 @@ struct PagerSavepoint {
};
/*
-** A open page cache is an instance of struct Pager. A description of
+** Bits of the Pager.doNotSpill flag. See further description below.
+*/
+#define SPILLFLAG_OFF 0x01 /* Never spill cache. Set via pragma */
+#define SPILLFLAG_ROLLBACK 0x02 /* Current rolling back, so do not spill */
+#define SPILLFLAG_NOSYNC 0x04 /* Spill is ok, but do not sync */
+
+/*
+** An open page cache is an instance of struct Pager. A description of
** some of the more important member variables follows:
**
** eState
@@ -37836,23 +43944,25 @@ struct PagerSavepoint {
** journal file from being successfully finalized, the setMaster flag
** is cleared anyway (and the pager will move to ERROR state).
**
-** doNotSpill, doNotSyncSpill
+** doNotSpill
**
-** 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).
+** This variables control the behavior 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
+** When bits SPILLFLAG_OFF or SPILLFLAG_ROLLBACK of doNotSpill are set,
+** writing to the database from pagerStress() is disabled altogether.
+** The SPILLFLAG_ROLLBACK case 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().
+** while it is being traversed by code in pager_playback(). The SPILLFLAG_OFF
+** case is a user preference.
**
-** 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.
+** If the SPILLFLAG_NOSYNC bit is set, 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
**
@@ -37934,13 +44044,14 @@ struct Pager {
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 tempFile; /* zFilename is a temporary or immutable file */
+ u8 noLock; /* Do not lock (except in WAL mode) */
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
+ ** routine operation. 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
@@ -37952,8 +44063,9 @@ struct Pager {
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 */
+ u8 bUseFetch; /* True to use xFetch() */
+ u8 hasHeldSharedLock; /* True if a shared lock has ever been held */
Pgno dbSize; /* Number of pages in the database */
Pgno dbOrigSize; /* dbSize before the current transaction */
Pgno dbFileSize; /* Number of pages in the database file */
@@ -37971,7 +44083,12 @@ struct Pager {
sqlite3_backup *pBackup; /* Pointer to list of ongoing backup processes */
PagerSavepoint *aSavepoint; /* Array of active savepoints */
int nSavepoint; /* Number of elements in aSavepoint[] */
+ u32 iDataVersion; /* Changes whenever database content changes */
char dbFileVers[16]; /* Changes whenever database file changes */
+
+ int nMmapOut; /* Number of mmap pages currently outstanding */
+ sqlite3_int64 szMmap; /* Desired maximum mmap size */
+ PgHdr *pMmapFreelist; /* List of free mmap page headers (pDirty) */
/*
** End of the routinely-changing class members
***************************************************************************/
@@ -38083,6 +44200,16 @@ static const unsigned char aJournalMagic[] = {
#endif
/*
+** The macro USEFETCH is true if we are allowed to use the xFetch and xUnfetch
+** interfaces to access the database using memory-mapped I/O.
+*/
+#if SQLITE_MAX_MMAP_SIZE>0
+# define USEFETCH(x) ((x)->bUseFetch)
+#else
+# define USEFETCH(x) 0
+#endif
+
+/*
** The maximum legal page number is (2^31 - 1).
*/
#define PAGER_MAX_PGNO 2147483647
@@ -38099,7 +44226,7 @@ static const unsigned char aJournalMagic[] = {
**
** if( pPager->jfd->pMethods ){ ...
*/
-#define isOpen(pFd) ((pFd)->pMethods)
+#define isOpen(pFd) ((pFd)->pMethods!=0)
/*
** Return true if this pager uses a write-ahead log instead of the usual
@@ -38316,24 +44443,27 @@ static char *print_pager_state(Pager *p){
** PagerSavepoint.pInSavepoint.
*/
static int subjRequiresPage(PgHdr *pPg){
- Pgno pgno = pPg->pgno;
Pager *pPager = pPg->pPager;
+ PagerSavepoint *p;
+ Pgno pgno = pPg->pgno;
int i;
for(i=0; i<pPager->nSavepoint; i++){
- PagerSavepoint *p = &pPager->aSavepoint[i];
- if( p->nOrig>=pgno && 0==sqlite3BitvecTest(p->pInSavepoint, pgno) ){
+ p = &pPager->aSavepoint[i];
+ if( p->nOrig>=pgno && 0==sqlite3BitvecTestNotNull(p->pInSavepoint, pgno) ){
return 1;
}
}
return 0;
}
+#ifdef SQLITE_DEBUG
/*
** Return true if the page is already in the journal file.
*/
-static int pageInJournal(PgHdr *pPg){
- return sqlite3BitvecTest(pPg->pPager->pInJournal, pPg->pgno);
+static int pageInJournal(Pager *pPager, PgHdr *pPg){
+ return sqlite3BitvecTest(pPager->pInJournal, pPg->pgno);
}
+#endif
/*
** Read a 32-bit integer from the given file descriptor. Store the integer
@@ -38384,7 +44514,7 @@ static int pagerUnlockDb(Pager *pPager, int eLock){
assert( eLock!=NO_LOCK || pagerUseWal(pPager)==0 );
if( isOpen(pPager->fd) ){
assert( pPager->eLock>=eLock );
- rc = sqlite3OsUnlock(pPager->fd, eLock);
+ rc = pPager->noLock ? SQLITE_OK : sqlite3OsUnlock(pPager->fd, eLock);
if( pPager->eLock!=UNKNOWN_LOCK ){
pPager->eLock = (u8)eLock;
}
@@ -38408,7 +44538,7 @@ static int pagerLockDb(Pager *pPager, int eLock){
assert( eLock==SHARED_LOCK || eLock==RESERVED_LOCK || eLock==EXCLUSIVE_LOCK );
if( pPager->eLock<eLock || pPager->eLock==UNKNOWN_LOCK ){
- rc = sqlite3OsLock(pPager->fd, eLock);
+ rc = pPager->noLock ? SQLITE_OK : 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))
@@ -38539,6 +44669,7 @@ static int readMasterJournal(sqlite3_file *pJrnl, char *zMaster, u32 nMaster){
|| szJ<16
|| SQLITE_OK!=(rc = read32bits(pJrnl, szJ-16, &len))
|| len>=nMaster
+ || len==0
|| SQLITE_OK!=(rc = read32bits(pJrnl, szJ-12, &cksum))
|| SQLITE_OK!=(rc = sqlite3OsRead(pJrnl, aMagic, 8, szJ-8))
|| memcmp(aMagic, aJournalMagic, 8)
@@ -38716,7 +44847,7 @@ static int writeJournalHdr(Pager *pPager){
memset(zHeader, 0, sizeof(aJournalMagic)+4);
}
- /* The random check-hash initialiser */
+ /* The random check-hash initializer */
sqlite3_randomness(sizeof(pPager->cksumInit), &pPager->cksumInit);
put32bits(&zHeader[sizeof(aJournalMagic)+4], pPager->cksumInit);
/* The initial database size */
@@ -38916,12 +45047,11 @@ static int writeMasterJournal(Pager *pPager, const char *zMaster){
if( !zMaster
|| pPager->journalMode==PAGER_JOURNALMODE_MEMORY
- || pPager->journalMode==PAGER_JOURNALMODE_OFF
+ || !isOpen(pPager->jfd)
){
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 */
@@ -38945,7 +45075,8 @@ static int writeMasterJournal(Pager *pPager, const char *zMaster){
|| (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)))
+ || (0 != (rc = sqlite3OsWrite(pPager->jfd, aJournalMagic, 8,
+ iHdrOff+4+nMaster+8)))
){
return rc;
}
@@ -38970,29 +45101,23 @@ static int writeMasterJournal(Pager *pPager, const char *zMaster){
}
/*
-** 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){
+ pPager->iDataVersion++;
sqlite3BackupRestart(pPager->pBackup);
sqlite3PcacheClear(pPager->pPCache);
}
/*
+** Return the pPager->iDataVersion value
+*/
+SQLITE_PRIVATE u32 sqlite3PagerDataVersion(Pager *pPager){
+ assert( pPager->eState>PAGER_OPEN );
+ return pPager->iDataVersion;
+}
+
+/*
** 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.
@@ -39114,6 +45239,7 @@ static void pager_unlock(Pager *pPager){
pPager->changeCountDone = pPager->tempFile;
pPager->eState = PAGER_OPEN;
pPager->errCode = SQLITE_OK;
+ if( USEFETCH(pPager) ) sqlite3OsUnfetch(pPager->fd, 0, 0);
}
pPager->journalOff = 0;
@@ -39155,6 +45281,8 @@ static int pager_error(Pager *pPager, int rc){
return rc;
}
+static int pager_truncate(Pager *pPager, Pgno nPage);
+
/*
** This routine ends a transaction. A transaction is usually ended by
** either a COMMIT or a ROLLBACK operation. This routine may be called
@@ -39208,7 +45336,7 @@ static int pager_error(Pager *pPager, int rc){
** to the first error encountered (the journal finalization one) is
** returned.
*/
-static int pager_end_transaction(Pager *pPager, int hasMaster){
+static int pager_end_transaction(Pager *pPager, int hasMaster, int bCommit){
int rc = SQLITE_OK; /* Error code from journal finalization operation */
int rc2 = SQLITE_OK; /* Error code from db file unlock operation */
@@ -39245,6 +45373,14 @@ static int pager_end_transaction(Pager *pPager, int hasMaster){
rc = SQLITE_OK;
}else{
rc = sqlite3OsTruncate(pPager->jfd, 0);
+ if( rc==SQLITE_OK && pPager->fullSync ){
+ /* Make sure the new file size is written into the inode right away.
+ ** Otherwise the journal might resurrect following a power loss and
+ ** cause the last transaction to roll back. See
+ ** https://bugzilla.mozilla.org/show_bug.cgi?id=1072773
+ */
+ rc = sqlite3OsSync(pPager->jfd, pPager->syncFlags);
+ }
}
pPager->journalOff = 0;
}else if( pPager->journalMode==PAGER_JOURNALMODE_PERSIST
@@ -39273,10 +45409,10 @@ static int pager_end_transaction(Pager *pPager, int hasMaster){
#ifdef SQLITE_CHECK_PAGES
sqlite3PcacheIterateDirty(pPager->pPCache, pager_set_pagehash);
if( pPager->dbSize==0 && sqlite3PcacheRefCount(pPager->pPCache)>0 ){
- PgHdr *p = pager_lookup(pPager, 1);
+ PgHdr *p = sqlite3PagerLookup(pPager, 1);
if( p ){
p->pageHash = 0;
- sqlite3PagerUnref(p);
+ sqlite3PagerUnrefNotNull(p);
}
}
#endif
@@ -39294,7 +45430,22 @@ static int pager_end_transaction(Pager *pPager, int hasMaster){
*/
rc2 = sqlite3WalEndWriteTransaction(pPager->pWal);
assert( rc2==SQLITE_OK );
+ }else if( rc==SQLITE_OK && bCommit && pPager->dbFileSize>pPager->dbSize ){
+ /* This branch is taken when committing a transaction in rollback-journal
+ ** mode if the database file on disk is larger than the database image.
+ ** At this point the journal has been finalized and the transaction
+ ** successfully committed, but the EXCLUSIVE lock is still held on the
+ ** file. So it is safe to truncate the database file to its minimum
+ ** required size. */
+ assert( pPager->eLock==EXCLUSIVE_LOCK );
+ rc = pager_truncate(pPager, pPager->dbSize);
+ }
+
+ if( rc==SQLITE_OK && bCommit && isOpen(pPager->fd) ){
+ rc = sqlite3OsFileControl(pPager->fd, SQLITE_FCNTL_COMMIT_PHASETWO, 0);
+ if( rc==SQLITE_NOTFOUND ) rc = SQLITE_OK;
}
+
if( !pPager->exclusiveMode
&& (!pagerUseWal(pPager) || sqlite3WalExclusiveMode(pPager->pWal, 0))
){
@@ -39333,7 +45484,7 @@ static void pagerUnlockAndRollback(Pager *pPager){
sqlite3EndBenignMalloc();
}else if( !pPager->exclusiveMode ){
assert( pPager->eState==PAGER_READER );
- pager_end_transaction(pPager, 0);
+ pager_end_transaction(pPager, 0, 0);
}
}
pager_unlock(pPager);
@@ -39383,6 +45534,20 @@ static void pagerReportSize(Pager *pPager){
# define pagerReportSize(X) /* No-op if we do not support a codec */
#endif
+#ifdef SQLITE_HAS_CODEC
+/*
+** Make sure the number of reserved bits is the same in the destination
+** pager as it is in the source. This comes up when a VACUUM changes the
+** number of reserved bits to the "optimal" amount.
+*/
+SQLITE_PRIVATE void sqlite3PagerAlignReserve(Pager *pDest, Pager *pSrc){
+ if( pDest->nReserve!=pSrc->nReserve ){
+ pDest->nReserve = pSrc->nReserve;
+ pagerReportSize(pDest);
+ }
+}
+#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.
@@ -39485,7 +45650,7 @@ static int pager_playback_one_page(
}
}
- /* If this page has already been played by before during the current
+ /* If this page has already been played back before during the current
** rollback, then don't bother to play it back again.
*/
if( pDone && (rc = sqlite3BitvecSet(pDone, pgno))!=SQLITE_OK ){
@@ -39537,7 +45702,7 @@ static int pager_playback_one_page(
if( pagerUseWal(pPager) ){
pPg = 0;
}else{
- pPg = pager_lookup(pPager, pgno);
+ pPg = sqlite3PagerLookup(pPager, pgno);
}
assert( pPg || !MEMDB );
assert( pPager->eState!=PAGER_OPEN || pPg==0 );
@@ -39557,7 +45722,7 @@ static int pager_playback_one_page(
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);
+ rc = sqlite3OsWrite(pPager->fd, (u8 *)aData, pPager->pageSize, ofst);
if( pgno>pPager->dbFileSize ){
pPager->dbFileSize = pgno;
}
@@ -39584,11 +45749,11 @@ static int pager_playback_one_page(
** 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--;
+ assert( (pPager->doNotSpill & SPILLFLAG_ROLLBACK)==0 );
+ pPager->doNotSpill |= SPILLFLAG_ROLLBACK;
+ rc = sqlite3PagerGet(pPager, pgno, &pPg, 1);
+ assert( (pPager->doNotSpill & SPILLFLAG_ROLLBACK)!=0 );
+ pPager->doNotSpill &= ~SPILLFLAG_ROLLBACK;
if( rc!=SQLITE_OK ) return rc;
pPg->flags &= ~PGHDR_NEED_READ;
sqlite3PcacheMakeDirty(pPg);
@@ -39717,7 +45882,7 @@ static int pager_delmaster(Pager *pPager, const char *zMaster){
rc = sqlite3OsFileSize(pMaster, &nMasterJournal);
if( rc!=SQLITE_OK ) goto delmaster_out;
nMasterPtr = pVfs->mxPathname+1;
- zMasterJournal = sqlite3Malloc((int)nMasterJournal + nMasterPtr + 1);
+ zMasterJournal = sqlite3Malloc(nMasterJournal + nMasterPtr + 1);
if( !zMasterJournal ){
rc = SQLITE_NOMEM;
goto delmaster_out;
@@ -39786,7 +45951,7 @@ delmaster_out:
** 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
+** Or, it 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
@@ -39845,7 +46010,7 @@ SQLITE_PRIVATE int sqlite3SectorSize(sqlite3_file *pFile){
/*
** 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
+** of the open database file. The sector size will be used
** to determine the size and alignment of journal header and
** master journal pointers within created journal files.
**
@@ -39948,6 +46113,7 @@ static int pager_playback(Pager *pPager, int isHot){
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 */
+ int nPlayback = 0; /* Total number of pages restored from journal */
/* Figure out how many records are in the journal. Abort early if
** the journal is empty.
@@ -40048,7 +46214,9 @@ static int pager_playback(Pager *pPager, int isHot){
needPagerReset = 0;
}
rc = pager_playback_one_page(pPager,&pPager->journalOff,0,1,0);
- if( rc!=SQLITE_OK ){
+ if( rc==SQLITE_OK ){
+ nPlayback++;
+ }else{
if( rc==SQLITE_DONE ){
pPager->journalOff = szJ;
break;
@@ -40105,10 +46273,10 @@ end_playback:
if( rc==SQLITE_OK
&& (pPager->eState>=PAGER_WRITER_DBMOD || pPager->eState==PAGER_OPEN)
){
- rc = sqlite3PagerSync(pPager);
+ rc = sqlite3PagerSync(pPager, 0);
}
if( rc==SQLITE_OK ){
- rc = pager_end_transaction(pPager, zMaster[0]!='\0');
+ rc = pager_end_transaction(pPager, zMaster[0]!='\0', 0);
testcase( rc!=SQLITE_OK );
}
if( rc==SQLITE_OK && zMaster[0] && res ){
@@ -40118,6 +46286,10 @@ end_playback:
rc = pager_delmaster(pPager, zMaster);
testcase( rc!=SQLITE_OK );
}
+ if( isHot && nPlayback ){
+ sqlite3_log(SQLITE_NOTICE_RECOVER_ROLLBACK, "recovered %d pages from %s",
+ nPlayback, pPager->zJournal);
+ }
/* The Pager.sectorSize variable may have been updated while rolling
** back a journal created by a process with a different sector size
@@ -40139,27 +46311,22 @@ end_playback:
** If an IO error occurs, then the IO error is returned to the caller.
** Otherwise, SQLITE_OK is returned.
*/
-static int readDbPage(PgHdr *pPg){
+static int readDbPage(PgHdr *pPg, u32 iFrame){
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) ){
+#ifndef SQLITE_OMIT_WAL
+ if( iFrame ){
/* Try to pull the page from the write-ahead log. */
- rc = sqlite3WalRead(pPager->pWal, pgno, &isInWal, pgsz, pPg->pData);
- }
- if( rc==SQLITE_OK && !isInWal ){
+ rc = sqlite3WalReadFrame(pPager->pWal, iFrame, pgsz, pPg->pData);
+ }else
+#endif
+ {
i64 iOffset = (pgno-1)*(i64)pPager->pageSize;
rc = sqlite3OsRead(pPager->fd, pPg->pData, pgsz, iOffset);
if( rc==SQLITE_IOERR_SHORT_READ ){
@@ -40178,7 +46345,7 @@ static int readDbPage(PgHdr *pPg){
**
** 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
+ ** white noise equaling 16 bytes of 0xff is vanishingly small so
** we should still be ok.
*/
memset(pPager->dbFileVers, 0xff, sizeof(pPager->dbFileVers));
@@ -40238,16 +46405,21 @@ static int pagerUndoCallback(void *pCtx, Pgno iPg){
Pager *pPager = (Pager *)pCtx;
PgHdr *pPg;
+ assert( pagerUseWal(pPager) );
pPg = sqlite3PagerLookup(pPager, iPg);
if( pPg ){
if( sqlite3PcachePageRefcount(pPg)==1 ){
sqlite3PcacheDrop(pPg);
}else{
- rc = readDbPage(pPg);
+ u32 iFrame = 0;
+ rc = sqlite3WalFindFrame(pPager->pWal, pPg->pgno, &iFrame);
+ if( rc==SQLITE_OK ){
+ rc = readDbPage(pPg, iFrame);
+ }
if( rc==SQLITE_OK ){
pPager->xReiniter(pPg);
}
- sqlite3PagerUnref(pPg);
+ sqlite3PagerUnrefNotNull(pPg);
}
}
@@ -40307,9 +46479,7 @@ static int pagerWalFrames(
){
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 );
@@ -40326,7 +46496,6 @@ static int pagerWalFrames(
** 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){
@@ -40346,7 +46515,6 @@ static int pagerWalFrames(
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);
}
@@ -40387,6 +46555,7 @@ static int pagerBeginReadTransaction(Pager *pPager){
rc = sqlite3WalBeginReadTransaction(pPager->pWal, &changed);
if( rc!=SQLITE_OK || changed ){
pager_reset(pPager);
+ if( USEFETCH(pPager) ) sqlite3OsUnfetch(pPager->fd, 0, 0);
}
return rc;
@@ -40415,11 +46584,10 @@ static int pagerPagecount(Pager *pPager, Pgno *pnPage){
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 the number of pages in the database is not available from the
+ ** WAL sub-system, determine the page counte 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 up the result.
*/
if( nPage==0 ){
i64 n = 0; /* Size of db file in bytes */
@@ -40642,13 +46810,45 @@ static int pagerPlaybackSavepoint(Pager *pPager, PagerSavepoint *pSavepoint){
}
/*
-** Change the maximum number of in-memory pages that are allowed.
+** Change the maximum number of in-memory pages that are allowed
+** before attempting to recycle clean and unused pages.
*/
SQLITE_PRIVATE void sqlite3PagerSetCachesize(Pager *pPager, int mxPage){
sqlite3PcacheSetCachesize(pPager->pPCache, mxPage);
}
/*
+** Change the maximum number of in-memory pages that are allowed
+** before attempting to spill pages to journal.
+*/
+SQLITE_PRIVATE int sqlite3PagerSetSpillsize(Pager *pPager, int mxPage){
+ return sqlite3PcacheSetSpillsize(pPager->pPCache, mxPage);
+}
+
+/*
+** Invoke SQLITE_FCNTL_MMAP_SIZE based on the current value of szMmap.
+*/
+static void pagerFixMaplimit(Pager *pPager){
+#if SQLITE_MAX_MMAP_SIZE>0
+ sqlite3_file *fd = pPager->fd;
+ if( isOpen(fd) && fd->pMethods->iVersion>=3 ){
+ sqlite3_int64 sz;
+ sz = pPager->szMmap;
+ pPager->bUseFetch = (sz>0);
+ sqlite3OsFileControlHint(pPager->fd, SQLITE_FCNTL_MMAP_SIZE, &sz);
+ }
+#endif
+}
+
+/*
+** Change the maximum size of any memory mapping made of the database file.
+*/
+SQLITE_PRIVATE void sqlite3PagerSetMmapLimit(Pager *pPager, sqlite3_int64 szMmap){
+ pPager->szMmap = szMmap;
+ pagerFixMaplimit(pPager);
+}
+
+/*
** Free as much memory as possible from the pager.
*/
SQLITE_PRIVATE void sqlite3PagerShrink(Pager *pPager){
@@ -40656,9 +46856,12 @@ SQLITE_PRIVATE void sqlite3PagerShrink(Pager *pPager){
}
/*
-** 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:
+** Adjust settings of the pager to those specified in the pgFlags parameter.
+**
+** The "level" in pgFlags & PAGER_SYNCHRONOUS_MASK sets the robustness
+** of the database to damage due to OS crashes or power failures by
+** changing the number of syncs()s when writing the journals.
+** There are three levels:
**
** OFF sqlite3OsSync() is never called. This is the default
** for temporary and transient files.
@@ -40699,22 +46902,21 @@ SQLITE_PRIVATE void sqlite3PagerShrink(Pager *pPager){
** and FULL=3.
*/
#ifndef SQLITE_OMIT_PAGER_PRAGMAS
-SQLITE_PRIVATE void sqlite3PagerSetSafetyLevel(
+SQLITE_PRIVATE void sqlite3PagerSetFlags(
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 */
+ unsigned pgFlags /* Various flags */
){
+ unsigned level = pgFlags & PAGER_SYNCHRONOUS_MASK;
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 ){
+ }else if( pgFlags & PAGER_FULLFSYNC ){
pPager->syncFlags = SQLITE_SYNC_FULL;
pPager->ckptSyncFlags = SQLITE_SYNC_FULL;
- }else if( bCkptFullFsync ){
+ }else if( pgFlags & PAGER_CKPT_FULLFSYNC ){
pPager->syncFlags = SQLITE_SYNC_NORMAL;
pPager->ckptSyncFlags = SQLITE_SYNC_FULL;
}else{
@@ -40725,6 +46927,11 @@ SQLITE_PRIVATE void sqlite3PagerSetSafetyLevel(
if( pPager->fullSync ){
pPager->walSyncFlags |= WAL_SYNC_TRANSACTIONS;
}
+ if( pgFlags & PAGER_CACHESPILL ){
+ pPager->doNotSpill &= ~SPILLFLAG_OFF;
+ }else{
+ pPager->doNotSpill |= SPILLFLAG_OFF;
+ }
}
#endif
@@ -40869,11 +47076,15 @@ SQLITE_PRIVATE int sqlite3PagerSetPagesize(Pager *pPager, u32 *pPageSize, int nR
if( rc==SQLITE_OK ){
pager_reset(pPager);
- pPager->dbSize = (Pgno)((nByte+pageSize-1)/pageSize);
- pPager->pageSize = pageSize;
+ rc = sqlite3PcacheSetPageSize(pPager->pPCache, pageSize);
+ }
+ if( rc==SQLITE_OK ){
sqlite3PageFree(pPager->pTmpSpace);
pPager->pTmpSpace = pNew;
- sqlite3PcacheSetPageSize(pPager->pPCache, pageSize);
+ pPager->dbSize = (Pgno)((nByte+pageSize-1)/pageSize);
+ pPager->pageSize = pageSize;
+ }else{
+ sqlite3PageFree(pNew);
}
}
@@ -40883,6 +47094,7 @@ SQLITE_PRIVATE int sqlite3PagerSetPagesize(Pager *pPager, u32 *pPageSize, int nR
assert( nReserve>=0 && nReserve<1000 );
pPager->nReserve = (i16)nReserve;
pagerReportSize(pPager);
+ pagerFixMaplimit(pPager);
}
return rc;
}
@@ -41006,7 +47218,7 @@ 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
+ ** already held), or one of the transitions that the busy-handler
** may be invoked during, according to the comment above
** sqlite3PagerSetBusyhandler().
*/
@@ -41036,7 +47248,7 @@ static int pager_wait_on_lock(Pager *pPager, int locktype){
** 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
+** this happened, the correct behavior 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
@@ -41060,12 +47272,26 @@ static void assertTruncateConstraint(Pager *pPager){
** 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.
+**
+** This function is only called right before committing a transaction.
+** Once this function has been called, the transaction must either be
+** rolled back or committed. It is not safe to call this function and
+** then continue writing to the database.
*/
SQLITE_PRIVATE void sqlite3PagerTruncateImage(Pager *pPager, Pgno nPage){
assert( pPager->dbSize>=nPage );
assert( pPager->eState>=PAGER_WRITER_CACHEMOD );
pPager->dbSize = nPage;
- assertTruncateConstraint(pPager);
+
+ /* At one point the code here called assertTruncateConstraint() to
+ ** ensure that all pages being truncated away by this operation are,
+ ** if one or more savepoints are open, present in the savepoint
+ ** journal so that they can be restored if the savepoint is rolled
+ ** back. This is no longer necessary as this function is now only
+ ** called right before committing a transaction. So although the
+ ** Pager object may still have open savepoints (Pager.nSavepoint!=0),
+ ** they cannot be rolled back. So the assertTruncateConstraint() call
+ ** is no longer correct. */
}
@@ -41095,6 +47321,81 @@ static int pagerSyncHotJournal(Pager *pPager){
}
/*
+** Obtain a reference to a memory mapped page object for page number pgno.
+** The new object will use the pointer pData, obtained from xFetch().
+** If successful, set *ppPage to point to the new page reference
+** and return SQLITE_OK. Otherwise, return an SQLite error code and set
+** *ppPage to zero.
+**
+** Page references obtained by calling this function should be released
+** by calling pagerReleaseMapPage().
+*/
+static int pagerAcquireMapPage(
+ Pager *pPager, /* Pager object */
+ Pgno pgno, /* Page number */
+ void *pData, /* xFetch()'d data for this page */
+ PgHdr **ppPage /* OUT: Acquired page object */
+){
+ PgHdr *p; /* Memory mapped page to return */
+
+ if( pPager->pMmapFreelist ){
+ *ppPage = p = pPager->pMmapFreelist;
+ pPager->pMmapFreelist = p->pDirty;
+ p->pDirty = 0;
+ memset(p->pExtra, 0, pPager->nExtra);
+ }else{
+ *ppPage = p = (PgHdr *)sqlite3MallocZero(sizeof(PgHdr) + pPager->nExtra);
+ if( p==0 ){
+ sqlite3OsUnfetch(pPager->fd, (i64)(pgno-1) * pPager->pageSize, pData);
+ return SQLITE_NOMEM;
+ }
+ p->pExtra = (void *)&p[1];
+ p->flags = PGHDR_MMAP;
+ p->nRef = 1;
+ p->pPager = pPager;
+ }
+
+ assert( p->pExtra==(void *)&p[1] );
+ assert( p->pPage==0 );
+ assert( p->flags==PGHDR_MMAP );
+ assert( p->pPager==pPager );
+ assert( p->nRef==1 );
+
+ p->pgno = pgno;
+ p->pData = pData;
+ pPager->nMmapOut++;
+
+ return SQLITE_OK;
+}
+
+/*
+** Release a reference to page pPg. pPg must have been returned by an
+** earlier call to pagerAcquireMapPage().
+*/
+static void pagerReleaseMapPage(PgHdr *pPg){
+ Pager *pPager = pPg->pPager;
+ pPager->nMmapOut--;
+ pPg->pDirty = pPager->pMmapFreelist;
+ pPager->pMmapFreelist = pPg;
+
+ assert( pPager->fd->pMethods->iVersion>=3 );
+ sqlite3OsUnfetch(pPager->fd, (i64)(pPg->pgno-1)*pPager->pageSize, pPg->pData);
+}
+
+/*
+** Free all PgHdr objects stored in the Pager.pMmapFreelist list.
+*/
+static void pagerFreeMapHdrs(Pager *pPager){
+ PgHdr *p;
+ PgHdr *pNext;
+ for(p=pPager->pMmapFreelist; p; p=pNext){
+ pNext = p->pDirty;
+ sqlite3_free(p);
+ }
+}
+
+
+/*
** Shutdown the page cache. Free all memory and close all files.
**
** If a transaction was in progress when this routine is called, that
@@ -41114,6 +47415,7 @@ SQLITE_PRIVATE int sqlite3PagerClose(Pager *pPager){
assert( assert_pager_state(pPager) );
disable_simulated_io_errors();
sqlite3BeginBenignMalloc();
+ pagerFreeMapHdrs(pPager);
/* pPager->errCode = 0; */
pPager->exclusiveMode = 0;
#ifndef SQLITE_OMIT_WAL
@@ -41375,7 +47677,10 @@ static int pager_write_pagelist(Pager *pPager, PgHdr *pList){
** file size will be.
*/
assert( rc!=SQLITE_OK || isOpen(pPager->fd) );
- if( rc==SQLITE_OK && pPager->dbSize>pPager->dbHintSize ){
+ if( rc==SQLITE_OK
+ && pPager->dbHintSize<pPager->dbSize
+ && (pList->pDirty || pList->pgno>pPager->dbHintSize)
+ ){
sqlite3_int64 szFile = pPager->pageSize * (sqlite3_int64)pPager->dbSize;
sqlite3OsFileControlHint(pPager->fd, SQLITE_FCNTL_SIZE_HINT, &szFile);
pPager->dbHintSize = pPager->dbSize;
@@ -41456,8 +47761,6 @@ static int openSubJournal(Pager *pPager){
/*
** 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.
@@ -41477,7 +47780,7 @@ static int subjournalPage(PgHdr *pPg){
assert( isOpen(pPager->jfd) || pagerUseWal(pPager) );
assert( isOpen(pPager->sjfd) || pPager->nSubRec==0 );
assert( pagerUseWal(pPager)
- || pageInJournal(pPg)
+ || pageInJournal(pPager, pPg)
|| pPg->pgno>pPager->dbOrigSize
);
rc = openSubJournal(pPager);
@@ -41504,6 +47807,13 @@ static int subjournalPage(PgHdr *pPg){
}
return rc;
}
+static int subjournalPageIfRequired(PgHdr *pPg){
+ if( subjRequiresPage(pPg) ){
+ return subjournalPage(pPg);
+ }else{
+ return SQLITE_OK;
+ }
+}
/*
** This function is called by the pcache layer when it has reached some
@@ -41531,33 +47841,37 @@ static int pagerStress(void *p, PgHdr *pPg){
assert( pPg->pPager==pPager );
assert( pPg->flags&PGHDR_DIRTY );
- /* The doNotSyncSpill flag is set during times when doing a sync of
+ /* The doNotSpill NOSYNC bit 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.
+ ** The doNotSpill ROLLBACK and OFF bits inhibits all cache spilling
+ ** regardless of whether or not a sync is required. This is set during
+ ** a rollback or by user request, respectively.
**
** 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
+ ** lead to database corruption. In the current implementation it
+ ** is impossible for sqlite3PcacheFetch() to be called with createFlag==3
** 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 ){
+ testcase( pPager->doNotSpill & SPILLFLAG_ROLLBACK );
+ testcase( pPager->doNotSpill & SPILLFLAG_OFF );
+ testcase( pPager->doNotSpill & SPILLFLAG_NOSYNC );
+ if( pPager->doNotSpill
+ && ((pPager->doNotSpill & (SPILLFLAG_ROLLBACK|SPILLFLAG_OFF))!=0
+ || (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);
- }
+ rc = subjournalPageIfRequired(pPg);
if( rc==SQLITE_OK ){
rc = pagerWalFrames(pPager, pPg, 0, 0);
}
@@ -41570,39 +47884,6 @@ static int pagerStress(void *p, PgHdr *pPg){
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 );
@@ -41619,6 +47900,25 @@ static int pagerStress(void *p, PgHdr *pPg){
return pager_error(pPager, rc);
}
+/*
+** Flush all unreferenced dirty pages to disk.
+*/
+SQLITE_PRIVATE int sqlite3PagerFlush(Pager *pPager){
+ int rc = pPager->errCode;
+ if( !MEMDB ){
+ PgHdr *pList = sqlite3PcacheDirtyList(pPager->pPCache);
+ assert( assert_pager_state(pPager) );
+ while( rc==SQLITE_OK && pList ){
+ PgHdr *pNext = pList->pDirty;
+ if( pList->nRef==0 ){
+ rc = pagerStress((void*)pPager, pList);
+ }
+ pList = pNext;
+ }
+ }
+
+ return rc;
+}
/*
** Allocate and initialize a new Pager object and put a pointer to it
@@ -41811,30 +48111,38 @@ SQLITE_PRIVATE int sqlite3PagerOpen(
** + 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;
+ if( rc==SQLITE_OK ){
+ int iDc = sqlite3OsDeviceCharacteristics(pPager->fd);
+ if( !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;
+ {
+ 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
+ }
+ pPager->noLock = sqlite3_uri_boolean(zFilename, "nolock", 0);
+ if( (iDc & SQLITE_IOCAP_IMMUTABLE)!=0
+ || sqlite3_uri_boolean(zFilename, "immutable", 0) ){
+ vfsFlags |= SQLITE_OPEN_READONLY;
+ goto act_like_temp_file;
+ }
}
}else{
/* If a temporary file is requested, it is not opened immediately.
@@ -41844,10 +48152,14 @@ SQLITE_PRIVATE int sqlite3PagerOpen(
** 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.
+ **
+ ** This branch also runs for files marked as immutable.
*/
+act_like_temp_file:
tempFile = 1;
- pPager->eState = PAGER_READER;
- pPager->eLock = EXCLUSIVE_LOCK;
+ pPager->eState = PAGER_READER; /* Pretend we already have a lock */
+ pPager->eLock = EXCLUSIVE_LOCK; /* Pretend we are in EXCLUSIVE mode */
+ pPager->noLock = 1; /* Do no locking */
readOnly = (vfsFlags&SQLITE_OPEN_READONLY);
}
@@ -41860,22 +48172,23 @@ SQLITE_PRIVATE int sqlite3PagerOpen(
testcase( rc!=SQLITE_OK );
}
- /* If an error occurred in either of the blocks above, free the
- ** Pager structure and close the file.
+ /* Initialize the PCache object. */
+ if( rc==SQLITE_OK ){
+ assert( nExtra<1000 );
+ nExtra = ROUND8(nExtra);
+ rc = sqlite3PcacheOpen(szPageDflt, nExtra, !memDb,
+ !memDb?pagerStress:0, (void *)pPager, pPager->pPCache);
+ }
+
+ /* If an error occurred above, free the Pager structure and close the file.
*/
if( rc!=SQLITE_OK ){
- assert( !pPager->pTmpSpace );
sqlite3OsClose(pPager->fd);
+ sqlite3PageFree(pPager->pTmpSpace);
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))
@@ -41888,9 +48201,6 @@ SQLITE_PRIVATE int sqlite3PagerOpen(
/* 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
@@ -41929,12 +48239,37 @@ SQLITE_PRIVATE int sqlite3PagerOpen(
/* pPager->pBusyHandlerArg = 0; */
pPager->xReiniter = xReinit;
/* memset(pPager->aHash, 0, sizeof(pPager->aHash)); */
+ /* pPager->szMmap = SQLITE_DEFAULT_MMAP_SIZE // will be set by btree.c */
*ppPager = pPager;
return SQLITE_OK;
}
+/* Verify that the database file has not be deleted or renamed out from
+** under the pager. Return SQLITE_OK if the database is still were it ought
+** to be on disk. Return non-zero (SQLITE_READONLY_DBMOVED or some other error
+** code from sqlite3OsAccess()) if the database has gone missing.
+*/
+static int databaseIsUnmoved(Pager *pPager){
+ int bHasMoved = 0;
+ int rc;
+
+ if( pPager->tempFile ) return SQLITE_OK;
+ if( pPager->dbSize==0 ) return SQLITE_OK;
+ assert( pPager->zFilename && pPager->zFilename[0] );
+ rc = sqlite3OsFileControl(pPager->fd, SQLITE_FCNTL_HAS_MOVED, &bHasMoved);
+ if( rc==SQLITE_NOTFOUND ){
+ /* If the HAS_MOVED file-control is unimplemented, assume that the file
+ ** has not been moved. That is the historical behavior of SQLite: prior to
+ ** version 3.8.3, it never checked */
+ rc = SQLITE_OK;
+ }else if( rc==SQLITE_OK && bHasMoved ){
+ rc = SQLITE_READONLY_DBMOVED;
+ }
+ return rc;
+}
+
/*
** This function is called after transitioning from PAGER_UNLOCK to
@@ -42000,15 +48335,17 @@ static int hasHotJournal(Pager *pPager, int *pExists){
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 ){
+ /* If the database is zero pages in size, that means that either (1) the
+ ** journal is a remnant from a prior database with the same name where
+ ** the database file but not the journal was deleted, or (2) the initial
+ ** transaction that populates a new database is being rolled back.
+ ** In either case, the journal file can be deleted. However, take care
+ ** not to delete the journal file if it is already open due to
+ ** journal_mode=PERSIST.
+ */
+ if( nPage==0 && !jrnlOpen ){
sqlite3BeginBenignMalloc();
if( pagerLockDb(pPager, RESERVED_LOCK)==SQLITE_OK ){
sqlite3OsDelete(pVfs, pPager->zJournal, 0);
@@ -42038,7 +48375,7 @@ static int hasHotJournal(Pager *pPager, int *pExists){
*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 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
@@ -42059,7 +48396,7 @@ static int hasHotJournal(Pager *pPager, int *pExists){
/*
** This function is called to obtain a shared lock on the database file.
-** It is illegal to call sqlite3PagerAcquire() until after this function
+** It is illegal to call sqlite3PagerGet() 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.
**
@@ -42118,6 +48455,11 @@ SQLITE_PRIVATE int sqlite3PagerSharedLock(Pager *pPager){
goto failed;
}
if( bHotJournal ){
+ if( pPager->readOnly ){
+ rc = SQLITE_READONLY_ROLLBACK;
+ goto failed;
+ }
+
/* 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
@@ -42215,16 +48557,14 @@ SQLITE_PRIVATE int sqlite3PagerSharedLock(Pager *pPager){
);
}
- 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.
+ if( !pPager->tempFile && pPager->hasHeldSharedLock ){
+ /* The shared-lock has just been acquired then check to
+ ** see if the database has been modified. If the database has changed,
+ ** flush the cache. The hasHeldSharedLock flag prevents this from
+ ** occurring on the very first access to a file, in order to save a
+ ** single unnecessary sqlite3OsRead() call at the start-up.
**
- ** Database changes is detected by looking at 15 bytes beginning
+ ** Database changes are 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
@@ -42243,7 +48583,7 @@ SQLITE_PRIVATE int sqlite3PagerSharedLock(Pager *pPager){
if( nPage>0 ){
IOTRACE(("CKVERS %p %d\n", pPager, sizeof(dbFileVers)));
rc = sqlite3OsRead(pPager->fd, &dbFileVers, sizeof(dbFileVers), 24);
- if( rc!=SQLITE_OK ){
+ if( rc!=SQLITE_OK && rc!=SQLITE_IOERR_SHORT_READ ){
goto failed;
}
}else{
@@ -42252,6 +48592,16 @@ SQLITE_PRIVATE int sqlite3PagerSharedLock(Pager *pPager){
if( memcmp(pPager->dbFileVers, dbFileVers, sizeof(dbFileVers))!=0 ){
pager_reset(pPager);
+
+ /* Unmap the database file. It is possible that external processes
+ ** may have truncated the database file and then extended it back
+ ** to its original size while this process was not holding a lock.
+ ** In this case there may exist a Pager.pMap mapping that appears
+ ** to be the right size but is not actually valid. Avoid this
+ ** possibility by unmapping the db here. */
+ if( USEFETCH(pPager) ){
+ sqlite3OsUnfetch(pPager->fd, 0, 0);
+ }
}
}
@@ -42280,6 +48630,7 @@ SQLITE_PRIVATE int sqlite3PagerSharedLock(Pager *pPager){
assert( pPager->eState==PAGER_OPEN );
}else{
pPager->eState = PAGER_READER;
+ pPager->hasHeldSharedLock = 1;
}
return rc;
}
@@ -42293,7 +48644,7 @@ SQLITE_PRIVATE int sqlite3PagerSharedLock(Pager *pPager){
** nothing to rollback, so this routine is a no-op.
*/
static void pagerUnlockIfUnused(Pager *pPager){
- if( (sqlite3PcacheRefCount(pPager->pPCache)==0) ){
+ if( pPager->nMmapOut==0 && (sqlite3PcacheRefCount(pPager->pPCache)==0) ){
pagerUnlockAndRollback(pPager);
}
}
@@ -42321,7 +48672,7 @@ static void pagerUnlockIfUnused(Pager *pPager){
** 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:
+** of the page. This occurs in two scenarios:
**
** a) When reading a free-list leaf page from the database, and
**
@@ -42348,28 +48699,93 @@ static void pagerUnlockIfUnused(Pager *pPager){
** Since Lookup() never goes to disk, it never has to deal with locks
** or journal files.
*/
-SQLITE_PRIVATE int sqlite3PagerAcquire(
+SQLITE_PRIVATE int sqlite3PagerGet(
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 flags /* PAGER_GET_XXX flags */
){
- int rc;
- PgHdr *pPg;
+ int rc = SQLITE_OK;
+ PgHdr *pPg = 0;
+ u32 iFrame = 0; /* Frame to read from WAL file */
+ const int noContent = (flags & PAGER_GET_NOCONTENT);
+
+ /* It is acceptable to use a read-only (mmap) page for any page except
+ ** page 1 if there is no write-transaction open or the ACQUIRE_READONLY
+ ** flag was specified by the caller. And so long as the db is not a
+ ** temporary or in-memory database. */
+ const int bMmapOk = (pgno>1 && USEFETCH(pPager)
+ && (pPager->eState==PAGER_READER || (flags & PAGER_GET_READONLY))
+#ifdef SQLITE_HAS_CODEC
+ && pPager->xCodec==0
+#endif
+ );
+ /* Optimization note: Adding the "pgno<=1" term before "pgno==0" here
+ ** allows the compiler optimizer to reuse the results of the "pgno>1"
+ ** test in the previous statement, and avoid testing pgno==0 in the
+ ** common case where pgno is large. */
+ if( pgno<=1 && pgno==0 ){
+ return SQLITE_CORRUPT_BKPT;
+ }
assert( pPager->eState>=PAGER_READER );
assert( assert_pager_state(pPager) );
+ assert( noContent==0 || bMmapOk==0 );
- if( pgno==0 ){
- return SQLITE_CORRUPT_BKPT;
- }
+ assert( pPager->hasHeldSharedLock==1 );
/* 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( bMmapOk && pagerUseWal(pPager) ){
+ rc = sqlite3WalFindFrame(pPager->pWal, pgno, &iFrame);
+ if( rc!=SQLITE_OK ) goto pager_acquire_err;
+ }
+
+ if( bMmapOk && iFrame==0 ){
+ void *pData = 0;
+
+ rc = sqlite3OsFetch(pPager->fd,
+ (i64)(pgno-1) * pPager->pageSize, pPager->pageSize, &pData
+ );
+
+ if( rc==SQLITE_OK && pData ){
+ if( pPager->eState>PAGER_READER ){
+ pPg = sqlite3PagerLookup(pPager, pgno);
+ }
+ if( pPg==0 ){
+ rc = pagerAcquireMapPage(pPager, pgno, pData, &pPg);
+ }else{
+ sqlite3OsUnfetch(pPager->fd, (i64)(pgno-1)*pPager->pageSize, pData);
+ }
+ if( pPg ){
+ assert( rc==SQLITE_OK );
+ *ppPage = pPg;
+ return SQLITE_OK;
+ }
+ }
+ if( rc!=SQLITE_OK ){
+ goto pager_acquire_err;
+ }
+ }
+
+ {
+ sqlite3_pcache_page *pBase;
+ pBase = sqlite3PcacheFetch(pPager->pPCache, pgno, 3);
+ if( pBase==0 ){
+ rc = sqlite3PcacheFetchStress(pPager->pPCache, pgno, &pBase);
+ if( rc!=SQLITE_OK ) goto pager_acquire_err;
+ if( pBase==0 ){
+ pPg = *ppPage = 0;
+ rc = SQLITE_NOMEM;
+ goto pager_acquire_err;
+ }
+ }
+ pPg = *ppPage = sqlite3PcacheFetchFinish(pPager->pPCache, pgno, pBase);
+ assert( pPg!=0 );
+ }
}
if( rc!=SQLITE_OK ){
@@ -42379,10 +48795,11 @@ SQLITE_PRIVATE int sqlite3PagerAcquire(
pPg = 0;
goto pager_acquire_err;
}
- assert( (*ppPage)->pgno==pgno );
- assert( (*ppPage)->pPager==pPager || (*ppPage)->pPager==0 );
+ assert( pPg==(*ppPage) );
+ assert( pPg->pgno==pgno );
+ assert( pPg->pPager==pPager || pPg->pPager==0 );
- if( (*ppPage)->pPager && !noContent ){
+ if( pPg->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) );
@@ -42393,7 +48810,6 @@ SQLITE_PRIVATE int sqlite3PagerAcquire(
/* 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
@@ -42427,9 +48843,13 @@ SQLITE_PRIVATE int sqlite3PagerAcquire(
memset(pPg->pData, 0, pPager->pageSize);
IOTRACE(("ZERO %p %d\n", pPager, pgno));
}else{
+ if( pagerUseWal(pPager) && bMmapOk==0 ){
+ rc = sqlite3WalFindFrame(pPager->pWal, pgno, &iFrame);
+ if( rc!=SQLITE_OK ) goto pager_acquire_err;
+ }
assert( pPg->pPager==pPager );
pPager->aStat[PAGER_STAT_MISS]++;
- rc = readDbPage(pPg);
+ rc = readDbPage(pPg, iFrame);
if( rc!=SQLITE_OK ){
goto pager_acquire_err;
}
@@ -42462,13 +48882,14 @@ pager_acquire_err:
** has ever happened.
*/
SQLITE_PRIVATE DbPage *sqlite3PagerLookup(Pager *pPager, Pgno pgno){
- PgHdr *pPg = 0;
+ sqlite3_pcache_page *pPage;
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;
+ pPage = sqlite3PcacheFetch(pPager->pPCache, pgno, 0);
+ assert( pPage==0 || pPager->hasHeldSharedLock );
+ if( pPage==0 ) return 0;
+ return sqlite3PcacheFetchFinish(pPager->pPCache, pgno, pPage);
}
/*
@@ -42479,12 +48900,19 @@ SQLITE_PRIVATE DbPage *sqlite3PagerLookup(Pager *pPager, Pgno pgno){
** 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;
+SQLITE_PRIVATE void sqlite3PagerUnrefNotNull(DbPage *pPg){
+ Pager *pPager;
+ assert( pPg!=0 );
+ pPager = pPg->pPager;
+ if( pPg->flags & PGHDR_MMAP ){
+ pagerReleaseMapPage(pPg);
+ }else{
sqlite3PcacheRelease(pPg);
- pagerUnlockIfUnused(pPager);
}
+ pagerUnlockIfUnused(pPager);
+}
+SQLITE_PRIVATE void sqlite3PagerUnref(DbPage *pPg){
+ if( pPg ) sqlite3PagerUnrefNotNull(pPg);
}
/*
@@ -42539,13 +48967,19 @@ static int pager_open_journal(Pager *pPager){
(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
+
+ /* Verify that the database still has the same name as it did when
+ ** it was originally opened. */
+ rc = databaseIsUnmoved(pPager);
+ if( rc==SQLITE_OK ){
+#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) );
}
@@ -42611,7 +49045,7 @@ SQLITE_PRIVATE int sqlite3PagerBegin(Pager *pPager, int exFlag, int subjInMemory
if( rc!=SQLITE_OK ){
return rc;
}
- sqlite3WalExclusiveMode(pPager->pWal, 1);
+ (void)sqlite3WalExclusiveMode(pPager->pWal, 1);
}
/* Grab the write lock on the log file. If successful, upgrade to
@@ -42659,6 +49093,59 @@ SQLITE_PRIVATE int sqlite3PagerBegin(Pager *pPager, int exFlag, int subjInMemory
}
/*
+** Write page pPg onto the end of the rollback journal.
+*/
+static SQLITE_NOINLINE int pagerAddPageToRollbackJournal(PgHdr *pPg){
+ Pager *pPager = pPg->pPager;
+ int rc;
+ 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, pPg->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);
+ assert( rc==SQLITE_OK || rc==SQLITE_NOMEM );
+ 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
@@ -42666,7 +49153,6 @@ SQLITE_PRIVATE int sqlite3PagerBegin(Pager *pPager, int exFlag, int subjInMemory
** of any open savepoints as appropriate.
*/
static int pager_write(PgHdr *pPg){
- void *pData = pPg->pData;
Pager *pPager = pPg->pPager;
int rc = SQLITE_OK;
@@ -42679,15 +49165,8 @@ static int pager_write(PgHdr *pPg){
|| 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;
-
+ assert( pPager->errCode==0 );
+ assert( pPager->readOnly==0 );
CHECK_PAGE(pPg);
/* The journal file needs to be opened. Higher level routines have already
@@ -42706,93 +49185,142 @@ static int pager_write(PgHdr *pPg){
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.
- */
+ /* Mark the page that is about to be modified as dirty. */
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.
- */
+
+ /* If a rollback journal is in use, them make sure the page that is about
+ ** to change is in the rollback journal, or if the page is a new page off
+ ** then end of the file, make sure it is marked as PGHDR_NEED_SYNC.
+ */
+ assert( (pPager->pInJournal!=0) == isOpen(pPager->jfd) );
+ if( pPager->pInJournal!=0
+ && sqlite3BitvecTestNotNull(pPager->pInJournal, pPg->pgno)==0
+ ){
+ assert( pagerUseWal(pPager)==0 );
+ if( pPg->pgno<=pPager->dbOrigSize ){
+ rc = pagerAddPageToRollbackJournal(pPg);
+ if( rc!=SQLITE_OK ){
+ 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)));
+ }
+ }
- 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;
+ /* The PGHDR_DIRTY bit is set above when the page was added to the dirty-list
+ ** and before writing the page into the rollback journal. Wait until now,
+ ** after the page has been successfully journalled, before setting the
+ ** PGHDR_WRITEABLE bit that indicates that the page can be safely modified.
+ */
+ pPg->flags |= PGHDR_WRITEABLE;
+
+ /* If the statement journal is open and the page is not in it,
+ ** then write the page into the statement journal.
+ */
+ if( pPager->nSavepoint>0 ){
+ rc = subjournalPageIfRequired(pPg);
+ }
- 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;
+ /* Update the database size and return. */
+ if( pPager->dbSize<pPg->pgno ){
+ pPager->dbSize = pPg->pgno;
+ }
+ return rc;
+}
+
+/*
+** This is a variant of sqlite3PagerWrite() that runs when the sector size
+** is larger than the page size. SQLite makes the (reasonable) assumption that
+** all bytes of a sector are written together by hardware. Hence, all bytes of
+** a sector need to be journalled in case of a power loss in the middle of
+** a write.
+**
+** Usually, the sector size is less than or equal to the page size, in which
+** case pages can be individually written. This routine only runs in the
+** exceptional case where the page size is smaller than the sector size.
+*/
+static SQLITE_NOINLINE int pagerWriteLargeSector(PgHdr *pPg){
+ int rc = SQLITE_OK; /* Return code */
+ 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 */
+ Pager *pPager = pPg->pPager; /* The pager that owns pPg */
+ Pgno nPagePerSector = (pPager->sectorSize/pPager->pageSize);
+
+ /* Set the doNotSpill NOSYNC bit 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->doNotSpill & SPILLFLAG_NOSYNC)==0 );
+ pPager->doNotSpill |= SPILLFLAG_NOSYNC;
+
+ /* 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, 0);
+ if( rc==SQLITE_OK ){
+ rc = pager_write(pPage);
+ if( pPage->flags&PGHDR_NEED_SYNC ){
+ needSync = 1;
+ }
+ sqlite3PagerUnrefNotNull(pPage);
}
- 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);
+ }else if( (pPage = sqlite3PagerLookup(pPager, pg))!=0 ){
+ if( pPage->flags&PGHDR_NEED_SYNC ){
+ needSync = 1;
+ }
+ sqlite3PagerUnrefNotNull(pPage);
}
}
- /* Update the database size and return.
+ /* 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( pPager->dbSize<pPg->pgno ){
- pPager->dbSize = pPg->pgno;
+ if( rc==SQLITE_OK && needSync ){
+ assert( !MEMDB );
+ for(ii=0; ii<nPage; ii++){
+ PgHdr *pPage = sqlite3PagerLookup(pPager, pg1+ii);
+ if( pPage ){
+ pPage->flags |= PGHDR_NEED_SYNC;
+ sqlite3PagerUnrefNotNull(pPage);
+ }
+ }
}
+
+ assert( (pPager->doNotSpill & SPILLFLAG_NOSYNC)!=0 );
+ pPager->doNotSpill &= ~SPILLFLAG_NOSYNC;
return rc;
}
@@ -42810,95 +49338,21 @@ static int pager_write(PgHdr *pPg){
** 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;
+SQLITE_PRIVATE int sqlite3PagerWrite(PgHdr *pPg){
Pager *pPager = pPg->pPager;
- Pgno nPagePerSector = (pPager->sectorSize/pPager->pageSize);
-
+ assert( (pPg->flags & PGHDR_MMAP)==0 );
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--;
+ if( pPager->errCode ){
+ return pPager->errCode;
+ }else if( (pPg->flags & PGHDR_WRITEABLE)!=0 && pPager->dbSize>=pPg->pgno ){
+ if( pPager->nSavepoint ) return subjournalPageIfRequired(pPg);
+ return SQLITE_OK;
+ }else if( pPager->sectorSize > (u32)pPager->pageSize ){
+ return pagerWriteLargeSector(pPg);
}else{
- rc = pager_write(pDbPage);
+ return pager_write(pPg);
}
- return rc;
}
/*
@@ -42908,7 +49362,7 @@ SQLITE_PRIVATE int sqlite3PagerWrite(DbPage *pDbPage){
*/
#ifndef NDEBUG
SQLITE_PRIVATE int sqlite3PagerIswriteable(DbPage *pPg){
- return pPg->flags&PGHDR_DIRTY;
+ return pPg->flags & PGHDR_WRITEABLE;
}
#endif
@@ -42932,6 +49386,7 @@ SQLITE_PRIVATE void sqlite3PagerDontWrite(PgHdr *pPg){
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;
+ pPg->flags &= ~PGHDR_WRITEABLE;
pager_set_pagehash(pPg);
}
}
@@ -42990,7 +49445,7 @@ static int pager_incr_changecounter(Pager *pPager, int isDirectMode){
assert( !pPager->tempFile && isOpen(pPager->fd) );
/* Open page 1 of the file for writing. */
- rc = sqlite3PagerGet(pPager, 1, &pPgHdr);
+ rc = sqlite3PagerGet(pPager, 1, &pPgHdr, 0);
assert( pPgHdr==0 || rc==SQLITE_OK );
/* If page one was fetched successfully, and this function is not
@@ -43016,6 +49471,11 @@ static int pager_incr_changecounter(Pager *pPager, int isDirectMode){
pPager->aStat[PAGER_STAT_WRITE]++;
}
if( rc==SQLITE_OK ){
+ /* Update the pager's copy of the change-counter. Otherwise, the
+ ** next time a read transaction is opened the cache will be
+ ** flushed (as the change-counter values will not match). */
+ const void *pCopy = (const void *)&((const char *)zBuf)[24];
+ memcpy(&pPager->dbFileVers, pCopy, sizeof(pPager->dbFileVers));
pPager->changeCountDone = 1;
}
}else{
@@ -43036,17 +49496,17 @@ static int pager_incr_changecounter(Pager *pPager, int isDirectMode){
** 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){
+SQLITE_PRIVATE int sqlite3PagerSync(Pager *pPager, const char *zMaster){
int rc = SQLITE_OK;
- if( !pPager->noSync ){
+
+ if( isOpen(pPager->fd) ){
+ void *pArg = (void*)zMaster;
+ rc = sqlite3OsFileControl(pPager->fd, SQLITE_FCNTL_SYNC, pArg);
+ if( rc==SQLITE_NOTFOUND ) rc = SQLITE_OK;
+ }
+ if( rc==SQLITE_OK && !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;
}
@@ -43063,14 +49523,17 @@ SQLITE_PRIVATE int sqlite3PagerSync(Pager *pPager){
** 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
- );
+ int rc = pPager->errCode;
assert( assert_pager_state(pPager) );
- if( 0==pagerUseWal(pPager) ){
- rc = pager_wait_on_lock(pPager, EXCLUSIVE_LOCK);
+ if( 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;
}
@@ -43137,7 +49600,7 @@ SQLITE_PRIVATE int sqlite3PagerCommitPhaseOne(
if( pList==0 ){
/* Must have at least one page for the WAL commit flag.
** Ticket [2d1a5c67dfc2363e44f29d9bbd57f] 2011-05-18 */
- rc = sqlite3PagerGet(pPager, 1, &pPageOne);
+ rc = sqlite3PagerGet(pPager, 1, &pPageOne, 0);
pList = pPageOne;
pList->pDirty = 0;
}
@@ -43202,36 +49665,6 @@ SQLITE_PRIVATE int sqlite3PagerCommitPhaseOne(
#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.
@@ -43259,11 +49692,14 @@ SQLITE_PRIVATE int sqlite3PagerCommitPhaseOne(
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 ){
+
+ /* If the file on disk is smaller than the database image, use
+ ** pager_truncate to grow the file here. This can happen if the database
+ ** image was extended as part of the current transaction and then the
+ ** last page in the db image moved to the free-list. In this case the
+ ** last page is never written out to disk, leaving the database file
+ ** undersized. Fix this now if it is the case. */
+ 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);
@@ -43272,7 +49708,7 @@ SQLITE_PRIVATE int sqlite3PagerCommitPhaseOne(
/* Finally, sync the database file. */
if( !noSync ){
- rc = sqlite3PagerSync(pPager);
+ rc = sqlite3PagerSync(pPager, zMaster);
}
IOTRACE(("DBSYNC %p\n", pPager))
}
@@ -43336,7 +49772,8 @@ SQLITE_PRIVATE int sqlite3PagerCommitPhaseTwo(Pager *pPager){
}
PAGERTRACE(("COMMIT %d\n", PAGERID(pPager)));
- rc = pager_end_transaction(pPager, pPager->setMaster);
+ pPager->iDataVersion++;
+ rc = pager_end_transaction(pPager, pPager->setMaster, 1);
return pager_error(pPager, rc);
}
@@ -43381,11 +49818,11 @@ SQLITE_PRIVATE int sqlite3PagerRollback(Pager *pPager){
if( pagerUseWal(pPager) ){
int rc2;
rc = sqlite3PagerSavepoint(pPager, SAVEPOINT_ROLLBACK, -1);
- rc2 = pager_end_transaction(pPager, pPager->setMaster);
+ rc2 = pager_end_transaction(pPager, pPager->setMaster, 0);
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);
+ rc = pager_end_transaction(pPager, 0, 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.
@@ -43400,8 +49837,10 @@ SQLITE_PRIVATE int sqlite3PagerRollback(Pager *pPager){
}
assert( pPager->eState==PAGER_READER || rc!=SQLITE_OK );
- assert( rc==SQLITE_OK || rc==SQLITE_FULL
- || rc==SQLITE_NOMEM || (rc&0xFF)==SQLITE_IOERR );
+ assert( rc==SQLITE_OK || rc==SQLITE_FULL || rc==SQLITE_CORRUPT
+ || rc==SQLITE_NOMEM || (rc&0xFF)==SQLITE_IOERR
+ || rc==SQLITE_CANTOPEN
+ );
/* 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.
@@ -43417,12 +49856,14 @@ SQLITE_PRIVATE u8 sqlite3PagerIsreadonly(Pager *pPager){
return pPager->readOnly;
}
+#ifdef SQLITE_DEBUG
/*
-** Return the number of references to the pager.
+** Return the sum of the reference counts for all pages held by pPager.
*/
SQLITE_PRIVATE int sqlite3PagerRefcount(Pager *pPager){
return sqlite3PcacheRefCount(pPager->pPCache);
}
+#endif
/*
** Return the approximate number of bytes of memory currently
@@ -43505,54 +49946,62 @@ SQLITE_PRIVATE int sqlite3PagerIsMemdb(Pager *pPager){
** 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){
+static SQLITE_NOINLINE int pagerOpenSavepoint(Pager *pPager, int nSavepoint){
int rc = SQLITE_OK; /* Return code */
int nCurrent = pPager->nSavepoint; /* Current number of savepoints */
+ int ii; /* Iterator variable */
+ PagerSavepoint *aNew; /* New Pager.aSavepoint array */
assert( pPager->eState>=PAGER_WRITER_LOCKED );
assert( assert_pager_state(pPager) );
+ assert( nSavepoint>nCurrent && pPager->useJournal );
- 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;
- /* 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 ){
+ /* 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;
}
- 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;
+ if( pagerUseWal(pPager) ){
+ sqlite3WalSavepoint(pPager->pWal, aNew[ii].aWalData);
}
- assert( pPager->nSavepoint==nSavepoint );
- assertTruncateConstraint(pPager);
+ pPager->nSavepoint = ii+1;
}
-
+ assert( pPager->nSavepoint==nSavepoint );
+ assertTruncateConstraint(pPager);
return rc;
}
+SQLITE_PRIVATE int sqlite3PagerOpenSavepoint(Pager *pPager, int nSavepoint){
+ assert( pPager->eState>=PAGER_WRITER_LOCKED );
+ assert( assert_pager_state(pPager) );
+
+ if( nSavepoint>pPager->nSavepoint && pPager->useJournal ){
+ return pagerOpenSavepoint(pPager, nSavepoint);
+ }else{
+ return SQLITE_OK;
+ }
+}
+
/*
** This function is called to rollback or release (commit) a savepoint.
@@ -43648,7 +50097,7 @@ SQLITE_PRIVATE const char *sqlite3PagerFilename(Pager *pPager, int nullIfMemDb){
/*
** Return the VFS structure for the pager.
*/
-SQLITE_PRIVATE const sqlite3_vfs *sqlite3PagerVfs(Pager *pPager){
+SQLITE_PRIVATE sqlite3_vfs *sqlite3PagerVfs(Pager *pPager){
return pPager->pVfs;
}
@@ -43662,6 +50111,18 @@ SQLITE_PRIVATE sqlite3_file *sqlite3PagerFile(Pager *pPager){
}
/*
+** Return the file handle for the journal file (if it exists).
+** This will be either the rollback journal or the WAL file.
+*/
+SQLITE_PRIVATE sqlite3_file *sqlite3PagerJrnlFile(Pager *pPager){
+#if SQLITE_OMIT_WAL
+ return pPager->jfd;
+#else
+ return pPager->pWal ? sqlite3WalFile(pPager->pWal) : pPager->jfd;
+#endif
+}
+
+/*
** Return the full pathname of the journal file.
*/
SQLITE_PRIVATE const char *sqlite3PagerJournalname(Pager *pPager){
@@ -43697,7 +50158,27 @@ SQLITE_PRIVATE void sqlite3PagerSetCodec(
SQLITE_PRIVATE void *sqlite3PagerGetCodec(Pager *pPager){
return pPager->pCodec;
}
-#endif
+
+/*
+** 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;
+}
+
+/*
+** Return the current pager state
+*/
+SQLITE_PRIVATE int sqlite3PagerState(Pager *pPager){
+ return pPager->eState;
+}
+#endif /* SQLITE_HAS_CODEC */
#ifndef SQLITE_OMIT_AUTOVACUUM
/*
@@ -43763,9 +50244,8 @@ SQLITE_PRIVATE int sqlite3PagerMovepage(Pager *pPager, DbPage *pPg, Pgno pgno, i
** 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))
+ if( (pPg->flags & PGHDR_DIRTY)!=0
+ && SQLITE_OK!=(rc = subjournalPageIfRequired(pPg))
){
return rc;
}
@@ -43783,7 +50263,8 @@ SQLITE_PRIVATE int sqlite3PagerMovepage(Pager *pPager, DbPage *pPg, Pgno pgno, i
*/
if( (pPg->flags&PGHDR_NEED_SYNC) && !isCommit ){
needSyncPgno = pPg->pgno;
- assert( pageInJournal(pPg) || pPg->pgno>pPager->dbOrigSize );
+ assert( pPager->journalMode==PAGER_JOURNALMODE_OFF ||
+ pageInJournal(pPager, pPg) || pPg->pgno>pPager->dbOrigSize );
assert( pPg->flags&PGHDR_DIRTY );
}
@@ -43793,7 +50274,7 @@ SQLITE_PRIVATE int sqlite3PagerMovepage(Pager *pPager, DbPage *pPg, Pgno pgno, i
** for the page moved there.
*/
pPg->flags &= ~PGHDR_NEED_SYNC;
- pPgOld = pager_lookup(pPager, pgno);
+ pPgOld = sqlite3PagerLookup(pPager, pgno);
assert( !pPgOld || pPgOld->nRef==1 );
if( pPgOld ){
pPg->flags |= (pPgOld->flags&PGHDR_NEED_SYNC);
@@ -43817,7 +50298,7 @@ SQLITE_PRIVATE int sqlite3PagerMovepage(Pager *pPager, DbPage *pPg, Pgno pgno, i
if( MEMDB ){
assert( pPgOld );
sqlite3PcacheMove(pPgOld, origPgno);
- sqlite3PagerUnref(pPgOld);
+ sqlite3PagerUnrefNotNull(pPgOld);
}
if( needSyncPgno ){
@@ -43836,7 +50317,7 @@ SQLITE_PRIVATE int sqlite3PagerMovepage(Pager *pPager, DbPage *pPg, Pgno pgno, i
** the journal file twice, but that is not a problem.
*/
PgHdr *pPgHdr;
- rc = sqlite3PagerGet(pPager, needSyncPgno, &pPgHdr);
+ rc = sqlite3PagerGet(pPager, needSyncPgno, &pPgHdr, 0);
if( rc!=SQLITE_OK ){
if( needSyncPgno<=pPager->dbOrigSize ){
assert( pPager->pTmpSpace!=0 );
@@ -43846,7 +50327,7 @@ SQLITE_PRIVATE int sqlite3PagerMovepage(Pager *pPager, DbPage *pPg, Pgno pgno, i
}
pPgHdr->flags |= PGHDR_NEED_SYNC;
sqlite3PcacheMakeDirty(pPgHdr);
- sqlite3PagerUnref(pPgHdr);
+ sqlite3PagerUnrefNotNull(pPgHdr);
}
return SQLITE_OK;
@@ -43854,6 +50335,18 @@ SQLITE_PRIVATE int sqlite3PagerMovepage(Pager *pPager, DbPage *pPg, Pgno pgno, i
#endif
/*
+** The page handle passed as the first argument refers to a dirty page
+** with a page number other than iNew. This function changes the page's
+** page number to iNew and sets the value of the PgHdr.flags field to
+** the value passed as the third parameter.
+*/
+SQLITE_PRIVATE void sqlite3PagerRekey(DbPage *pPg, Pgno iNew, u16 flags){
+ assert( pPg->pgno!=iNew );
+ pPg->flags = flags;
+ sqlite3PcacheMove(pPg, iNew);
+}
+
+/*
** Return a pointer to the data for the specified page.
*/
SQLITE_PRIVATE void *sqlite3PagerGetData(DbPage *pPg){
@@ -43998,6 +50491,8 @@ SQLITE_PRIVATE int sqlite3PagerSetJournalMode(Pager *pPager, int eMode){
}
assert( state==pPager->eState );
}
+ }else if( eMode==PAGER_JOURNALMODE_OFF ){
+ sqlite3OsClose(pPager->jfd);
}
}
@@ -44069,7 +50564,8 @@ SQLITE_PRIVATE int sqlite3PagerCheckpoint(Pager *pPager, int eMode, int *pnLog,
int rc = SQLITE_OK;
if( pPager->pWal ){
rc = sqlite3WalCheckpoint(pPager->pWal, eMode,
- pPager->xBusyHandler, pPager->pBusyHandlerArg,
+ (eMode==SQLITE_CHECKPOINT_PASSIVE ? 0 : pPager->xBusyHandler),
+ pPager->pBusyHandlerArg,
pPager->ckptSyncFlags, pPager->pageSize, (u8 *)pPager->pTmpSpace,
pnLog, pnCkpt
);
@@ -44133,11 +50629,12 @@ static int pagerOpenWal(Pager *pPager){
** (e.g. due to malloc() failure), return an error code.
*/
if( rc==SQLITE_OK ){
- rc = sqlite3WalOpen(pPager->pVfs,
+ rc = sqlite3WalOpen(pPager->pVfs,
pPager->fd, pPager->zWal, pPager->exclusiveMode,
pPager->journalSizeLimit, &pPager->pWal
);
}
+ pagerFixMaplimit(pPager);
return rc;
}
@@ -44228,11 +50725,40 @@ SQLITE_PRIVATE int sqlite3PagerCloseWal(Pager *pPager){
rc = sqlite3WalClose(pPager->pWal, pPager->ckptSyncFlags,
pPager->pageSize, (u8*)pPager->pTmpSpace);
pPager->pWal = 0;
+ pagerFixMaplimit(pPager);
}
}
return rc;
}
+#ifdef SQLITE_ENABLE_SNAPSHOT
+/*
+** If this is a WAL database, obtain a snapshot handle for the snapshot
+** currently open. Otherwise, return an error.
+*/
+SQLITE_PRIVATE int sqlite3PagerSnapshotGet(Pager *pPager, sqlite3_snapshot **ppSnapshot){
+ int rc = SQLITE_ERROR;
+ if( pPager->pWal ){
+ rc = sqlite3WalSnapshotGet(pPager->pWal, ppSnapshot);
+ }
+ return rc;
+}
+
+/*
+** If this is a WAL database, store a pointer to pSnapshot. Next time a
+** read transaction is opened, attempt to read from the snapshot it
+** identifies. If this is not a WAL database, return an error.
+*/
+SQLITE_PRIVATE int sqlite3PagerSnapshotOpen(Pager *pPager, sqlite3_snapshot *pSnapshot){
+ int rc = SQLITE_OK;
+ if( pPager->pWal ){
+ sqlite3WalSnapshotOpen(pPager->pWal, pSnapshot);
+ }else{
+ rc = SQLITE_ERROR;
+ }
+ return rc;
+}
+#endif /* SQLITE_ENABLE_SNAPSHOT */
#endif /* !SQLITE_OMIT_WAL */
#ifdef SQLITE_ENABLE_ZIPVFS
@@ -44244,25 +50770,11 @@ SQLITE_PRIVATE int sqlite3PagerCloseWal(Pager *pPager){
** is empty, return 0.
*/
SQLITE_PRIVATE int sqlite3PagerWalFramesize(Pager *pPager){
- assert( pPager->eState==PAGER_READER );
+ 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 */
@@ -44512,6 +51024,7 @@ SQLITE_PRIVATE void *sqlite3PagerCodec(PgHdr *pPg){
*/
#ifndef SQLITE_OMIT_WAL
+/* #include "wal.h" */
/*
** Trace output macros
@@ -44541,7 +51054,8 @@ SQLITE_PRIVATE int sqlite3WalTrace = 0;
/*
** Indices of various locking bytes. WAL_NREADER is the number
-** of available reader locks and should be at least 3.
+** of available reader locks and should be at least 3. The default
+** is SQLITE_SHM_NLOCK==8 and WAL_NREADER==5.
*/
#define WAL_WRITE_LOCK 0
#define WAL_ALL_BUT_WRITE 1
@@ -44561,7 +51075,10 @@ 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.
+** object followed by one instance of the WalCkptInfo object.
+** For all versions of SQLite through 3.10.0 and probably beyond,
+** the locking bytes (WalCkptInfo.aLock) start at offset 120 and
+** the total header size is 136 bytes.
**
** 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
@@ -44594,6 +51111,16 @@ struct WalIndexHdr {
** However, a WAL_WRITE_LOCK thread can move the value of nBackfill from
** mxFrame back to zero when the WAL is reset.
**
+** nBackfillAttempted is the largest value of nBackfill that a checkpoint
+** has attempted to achieve. Normally nBackfill==nBackfillAtempted, however
+** the nBackfillAttempted is set before any backfilling is done and the
+** nBackfill is only set after all backfilling completes. So if a checkpoint
+** crashes, nBackfillAttempted might be larger than nBackfill. The
+** WalIndexHdr.mxFrame must never be less than nBackfillAttempted.
+**
+** The aLock[] field is a set of bytes used for locking. These bytes should
+** never be read or written.
+**
** 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)
@@ -44633,6 +51160,9 @@ struct WalIndexHdr {
struct WalCkptInfo {
u32 nBackfill; /* Number of WAL frames backfilled into DB */
u32 aReadMark[WAL_NREADER]; /* Reader marks */
+ u8 aLock[SQLITE_SHM_NLOCK]; /* Reserved space for locks */
+ u32 nBackfillAttempted; /* WAL frames perhaps written, or maybe not */
+ u32 notUsed0; /* Available for future enhancements */
};
#define READMARK_NOT_USED 0xffffffff
@@ -44642,9 +51172,8 @@ struct WalCkptInfo {
** 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)
+#define WALINDEX_LOCK_OFFSET (sizeof(WalIndexHdr)*2+offsetof(WalCkptInfo,aLock))
+#define WALINDEX_HDR_SIZE (sizeof(WalIndexHdr)*2+sizeof(WalCkptInfo))
/* Size of header before each frame in wal */
#define WAL_FRAME_HDRSIZE 24
@@ -44697,11 +51226,15 @@ struct Wal {
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 */
+ u32 minFrame; /* Ignore wal frames before this one */
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
+#ifdef SQLITE_ENABLE_SNAPSHOT
+ WalIndexHdr *pSnapshot; /* Start transaction here if not NULL */
+#endif
};
/*
@@ -44791,7 +51324,7 @@ static int walIndexPage(Wal *pWal, int iPage, volatile u32 **ppPage){
if( pWal->nWiData<=iPage ){
int nByte = sizeof(u32*)*(iPage+1);
volatile u32 **apNew;
- apNew = (volatile u32 **)sqlite3_realloc((void *)pWal->apWiData, nByte);
+ apNew = (volatile u32 **)sqlite3_realloc64((void *)pWal->apWiData, nByte);
if( !apNew ){
*ppPage = 0;
return SQLITE_NOMEM;
@@ -44843,7 +51376,7 @@ static volatile WalIndexHdr *walIndexHdr(Wal *pWal){
** 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
+** returns the value that would be produced by interpreting the 4 bytes
** of the input value as a little-endian integer.
*/
#define BYTESWAP32(x) ( \
@@ -44917,9 +51450,9 @@ static void walIndexWriteHdr(Wal *pWal){
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));
+ memcpy((void*)&aHdr[1], (const void*)&pWal->hdr, sizeof(WalIndexHdr));
walShmBarrier(pWal);
- memcpy((void *)&aHdr[0], (void *)&pWal->hdr, sizeof(WalIndexHdr));
+ memcpy((void*)&aHdr[0], (const void*)&pWal->hdr, sizeof(WalIndexHdr));
}
/*
@@ -45220,13 +51753,13 @@ static void walCleanupHash(Wal *pWal){
** via the hash table even after the cleanup.
*/
if( iLimit ){
- int i; /* Loop counter */
+ int j; /* 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;
+ for(j=1; j<=iLimit; j++){
+ for(iKey=walHash(aPgno[j]); aHash[iKey]; iKey=walNextHash(iKey)){
+ if( aHash[iKey]==j ) break;
}
- assert( aHash[iKey]==i );
+ assert( aHash[iKey]==j );
}
}
#endif /* SQLITE_ENABLE_EXPENSIVE_ASSERT */
@@ -45257,7 +51790,7 @@ static int walIndexAppend(Wal *pWal, u32 iFrame, u32 iPage){
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.
+ ** entire hash table and aPgno[] array before proceeding.
*/
if( idx==1 ){
int nByte = (int)((u8 *)&aHash[HASHTABLE_NSLOT] - (u8 *)&aPgno[1]);
@@ -45415,7 +51948,7 @@ static int walIndexRecover(Wal *pWal){
/* Malloc a buffer to read frames into. */
szFrame = szPage + WAL_FRAME_HDRSIZE;
- aFrame = (u8 *)sqlite3_malloc(szFrame);
+ aFrame = (u8 *)sqlite3_malloc64(szFrame);
if( !aFrame ){
rc = SQLITE_NOMEM;
goto recovery_error;
@@ -45466,6 +51999,7 @@ finished:
*/
pInfo = walCkptInfo(pWal);
pInfo->nBackfill = 0;
+ pInfo->nBackfillAttempted = pWal->hdr.mxFrame;
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;
@@ -45476,8 +52010,9 @@ finished:
** checkpointing the log file.
*/
if( pWal->hdr.nPage ){
- sqlite3_log(SQLITE_OK, "Recovered %d frames from WAL file %s",
- pWal->hdr.nPage, pWal->zWalName
+ sqlite3_log(SQLITE_NOTICE_RECOVER_WAL,
+ "recovered %d frames from WAL file %s",
+ pWal->hdr.mxFrame, pWal->zWalName
);
}
}
@@ -45536,7 +52071,11 @@ SQLITE_PRIVATE int sqlite3WalOpen(
/* 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.
+ ** For that matter, if the lock offset ever changes from its initial design
+ ** value of 120, we need to know that so there is an assert() to check it.
*/
+ assert( 120==WALINDEX_LOCK_OFFSET );
+ assert( 136==WALINDEX_HDR_SIZE );
#ifdef WIN_SHM_BASE
assert( WIN_SHM_BASE==WALINDEX_LOCK_OFFSET );
#endif
@@ -45574,7 +52113,7 @@ SQLITE_PRIVATE int sqlite3WalOpen(
sqlite3OsClose(pRet->pWalFd);
sqlite3_free(pRet);
}else{
- int iDC = sqlite3OsDeviceCharacteristics(pRet->pWalFd);
+ int iDC = sqlite3OsDeviceCharacteristics(pDbFd);
if( iDC & SQLITE_IOCAP_SEQUENTIAL ){ pRet->syncHeader = 0; }
if( iDC & SQLITE_IOCAP_POWERSAFE_OVERWRITE ){
pRet->padToSectorBoundary = 0;
@@ -45727,7 +52266,7 @@ static void walMergesort(
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 */
+ u32 iSub = 0; /* Index into aSub array */
struct Sublist aSub[13]; /* Array of sub-lists */
memset(aSub, 0, sizeof(aSub));
@@ -45738,7 +52277,9 @@ static void walMergesort(
nMerge = 1;
aMerge = &aList[iList];
for(iSub=0; iList & (1<<iSub); iSub++){
- struct Sublist *p = &aSub[iSub];
+ struct Sublist *p;
+ assert( iSub<ArraySize(aSub) );
+ 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);
@@ -45749,7 +52290,9 @@ static void walMergesort(
for(iSub++; iSub<ArraySize(aSub); iSub++){
if( nList & (1<<iSub) ){
- struct Sublist *p = &aSub[iSub];
+ struct Sublist *p;
+ assert( iSub<ArraySize(aSub) );
+ 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);
@@ -45772,7 +52315,7 @@ static void walMergesort(
** Free an iterator allocated by walIteratorInit().
*/
static void walIteratorFree(WalIterator *p){
- sqlite3ScratchFree(p);
+ sqlite3_free(p);
}
/*
@@ -45807,7 +52350,7 @@ static int walIteratorInit(Wal *pWal, WalIterator **pp){
nByte = sizeof(WalIterator)
+ (nSegment-1)*sizeof(struct WalSegment)
+ iLast*sizeof(ht_slot);
- p = (WalIterator *)sqlite3ScratchMalloc(nByte);
+ p = (WalIterator *)sqlite3_malloc64(nByte);
if( !p ){
return SQLITE_NOMEM;
}
@@ -45817,7 +52360,7 @@ static int walIteratorInit(Wal *pWal, WalIterator **pp){
/* Allocate temporary space used by the merge-sort routine. This block
** of memory will be freed before this function returns.
*/
- aTmp = (ht_slot *)sqlite3ScratchMalloc(
+ aTmp = (ht_slot *)sqlite3_malloc64(
sizeof(ht_slot) * (iLast>HASHTABLE_NPAGE?HASHTABLE_NPAGE:iLast)
);
if( !aTmp ){
@@ -45854,7 +52397,7 @@ static int walIteratorInit(Wal *pWal, WalIterator **pp){
p->aSegment[i].aPgno = (u32 *)aPgno;
}
}
- sqlite3ScratchFree(aTmp);
+ sqlite3_free(aTmp);
if( rc!=SQLITE_OK ){
walIteratorFree(p);
@@ -45892,6 +52435,39 @@ static int walPagesize(Wal *pWal){
}
/*
+** The following is guaranteed when this function is called:
+**
+** a) the WRITER lock is held,
+** b) the entire log file has been checkpointed, and
+** c) any existing readers are reading exclusively from the database
+** file - there are no readers that may attempt to read a frame from
+** the log file.
+**
+** This function updates the shared-memory structures so that the next
+** client to write to the database (which may be this one) does so by
+** writing frames into the start of the log file.
+**
+** The value of parameter salt1 is used as the aSalt[1] value in the
+** new wal-index header. It should be passed a pseudo-random value (i.e.
+** one obtained from sqlite3_randomness()).
+*/
+static void walRestartHdr(Wal *pWal, u32 salt1){
+ volatile WalCkptInfo *pInfo = walCkptInfo(pWal);
+ 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]));
+ memcpy(&pWal->hdr.aSalt[1], &salt1, 4);
+ walIndexWriteHdr(pWal);
+ pInfo->nBackfill = 0;
+ pInfo->nBackfillAttempted = 0;
+ pInfo->aReadMark[1] = 0;
+ for(i=2; i<WAL_NREADER; i++) pInfo->aReadMark[i] = READMARK_NOT_USED;
+ assert( pInfo->aReadMark[0]==0 );
+}
+
+/*
** 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.
**
@@ -45914,7 +52490,7 @@ static int walPagesize(Wal *pWal){
** 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.
+** This is the only routine that will increase the value of nBackfill.
** (A WAL reset or recovery will revert nBackfill to zero, but not increase
** its value.)
**
@@ -45925,12 +52501,12 @@ static int walPagesize(Wal *pWal){
static int walCheckpoint(
Wal *pWal, /* Wal connection */
int eMode, /* One of PASSIVE, FULL or RESTART */
- int (*xBusyCall)(void*), /* Function to call when busy */
+ int (*xBusy)(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 rc = SQLITE_OK; /* Return code */
int szPage; /* Database page-size */
WalIterator *pIter = 0; /* Wal iterator context */
u32 iDbpage = 0; /* Next database page to write */
@@ -45939,122 +52515,156 @@ static int walCheckpoint(
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;
+ if( pInfo->nBackfill<pWal->hdr.mxFrame ){
- /* Allocate the iterator */
- rc = walIteratorInit(pWal, &pIter);
- if( rc!=SQLITE_OK ){
- return rc;
- }
- assert( pIter );
+ /* Allocate the iterator */
+ rc = walIteratorInit(pWal, &pIter);
+ if( rc!=SQLITE_OK ){
+ return rc;
+ }
+ assert( pIter );
- if( eMode!=SQLITE_CHECKPOINT_PASSIVE ) xBusy = xBusyCall;
+ /* EVIDENCE-OF: R-62920-47450 The busy-handler callback is never invoked
+ ** in the SQLITE_CHECKPOINT_PASSIVE mode. */
+ assert( eMode!=SQLITE_CHECKPOINT_PASSIVE || xBusy==0 );
- /* 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;
+ /* 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++){
+ /* Thread-sanitizer reports that the following is an unsafe read,
+ ** as some other thread may be in the process of updating the value
+ ** of the aReadMark[] slot. The assumption here is that if that is
+ ** happening, the other client may only be increasing the value,
+ ** not decreasing it. So assuming either that either the "old" or
+ ** "new" version of the value is read, and not some arbitrary value
+ ** that would never be written by a real client, things are still
+ ** safe. */
+ 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;
+ 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);
- }
+ pInfo->nBackfillAttempted = mxSafeFrame;
- /* 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);
+ /* Sync the WAL to disk */
+ if( sync_flags ){
+ rc = sqlite3OsSync(pWal->pWalFd, sync_flags);
}
- }
- /* 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 the database 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);
+ }
+ }
- /* 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);
+
+ /* 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 ){
- pInfo->nBackfill = mxSafeFrame;
+ 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);
- }
+ /* 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( 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 this is an SQLITE_CHECKPOINT_RESTART or TRUNCATE 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 );
+ }else if( eMode>=SQLITE_CHECKPOINT_RESTART ){
+ u32 salt1;
+ sqlite3_randomness(4, &salt1);
+ assert( pInfo->nBackfill==pWal->hdr.mxFrame );
rc = walBusyLock(pWal, xBusy, pBusyArg, WAL_READ_LOCK(1), WAL_NREADER-1);
if( rc==SQLITE_OK ){
+ if( eMode==SQLITE_CHECKPOINT_TRUNCATE ){
+ /* IMPLEMENTATION-OF: R-44699-57140 This mode works the same way as
+ ** SQLITE_CHECKPOINT_RESTART with the addition that it also
+ ** truncates the log file to zero bytes just prior to a
+ ** successful return.
+ **
+ ** In theory, it might be safe to do this without updating the
+ ** wal-index header in shared memory, as all subsequent reader or
+ ** writer clients should see that the entire log file has been
+ ** checkpointed and behave accordingly. This seems unsafe though,
+ ** as it would leave the system in a state where the contents of
+ ** the wal-index header do not match the contents of the
+ ** file-system. To avoid this, update the wal-index header to
+ ** indicate that the log file contains zero valid frames. */
+ walRestartHdr(pWal, salt1);
+ rc = sqlite3OsTruncate(pWal->pWalFd, 0);
+ }
walUnlockExclusive(pWal, WAL_READ_LOCK(1), WAL_NREADER-1);
}
}
@@ -46217,7 +52827,7 @@ static int walIndexTryHdr(Wal *pWal, int *pChanged){
** 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
+** changed by this operation. If pWal->hdr is unchanged, set *pChanged
** to 0.
**
** If the wal-index header is successfully read, return SQLITE_OK.
@@ -46346,6 +52956,7 @@ static int walTryBeginRead(Wal *pWal, int *pChanged, int useWal, int cnt){
int mxI; /* Index of largest aReadMark[] value */
int i; /* Loop counter */
int rc = SQLITE_OK; /* Return code */
+ u32 mxFrame; /* Wal frame to lock to */
assert( pWal->readLock<0 ); /* Not currently locked */
@@ -46363,8 +52974,8 @@ static int walTryBeginRead(Wal *pWal, int *pChanged, int useWal, int cnt){
** 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.
+ ** so that on the 100th (and last) RETRY we delay for 323 milliseconds.
+ ** The total delay time before giving up is less than 10 seconds.
*/
if( cnt>5 ){
int nDelay = 1; /* Pause time in microseconds */
@@ -46372,7 +52983,7 @@ static int walTryBeginRead(Wal *pWal, int *pChanged, int useWal, int cnt){
VVA_ONLY( pWal->lockError = 1; )
return SQLITE_PROTOCOL;
}
- if( cnt>=10 ) nDelay = (cnt-9)*238; /* Max delay 21ms. Total delay 996ms */
+ if( cnt>=10 ) nDelay = (cnt-9)*(cnt-9)*39;
sqlite3OsSleep(pWal->pVfs, nDelay);
}
@@ -46409,7 +53020,12 @@ static int walTryBeginRead(Wal *pWal, int *pChanged, int useWal, int cnt){
}
pInfo = walCkptInfo(pWal);
- if( !useWal && pInfo->nBackfill==pWal->hdr.mxFrame ){
+ if( !useWal && pInfo->nBackfill==pWal->hdr.mxFrame
+#ifdef SQLITE_ENABLE_SNAPSHOT
+ && (pWal->pSnapshot==0 || pWal->hdr.mxFrame==0
+ || 0==memcmp(&pWal->hdr, pWal->pSnapshot, sizeof(WalIndexHdr)))
+#endif
+ ){
/* The WAL has been completely backfilled (or it is empty).
** and can be safely ignored.
*/
@@ -46421,7 +53037,7 @@ static int walTryBeginRead(Wal *pWal, int *pChanged, int useWal, int cnt){
** 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
+ ** 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
@@ -46447,70 +53063,88 @@ static int walTryBeginRead(Wal *pWal, int *pChanged, int useWal, int cnt){
*/
mxReadMark = 0;
mxI = 0;
+ mxFrame = pWal->hdr.mxFrame;
+#ifdef SQLITE_ENABLE_SNAPSHOT
+ if( pWal->pSnapshot && pWal->pSnapshot->mxFrame<mxFrame ){
+ mxFrame = pWal->pSnapshot->mxFrame;
+ }
+#endif
for(i=1; i<WAL_NREADER; i++){
u32 thisMark = pInfo->aReadMark[i];
- if( mxReadMark<=thisMark && thisMark<=pWal->hdr.mxFrame ){
+ if( mxReadMark<=thisMark && thisMark<=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( (pWal->readOnly & WAL_SHM_RDONLY)==0
+ && (mxReadMark<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] = 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;
- }
+ }
+ 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;
- }
+ 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.
+ **
+ ** Before checking that the live wal-index header has not changed
+ ** since it was read, set Wal.minFrame to the first frame in the wal
+ ** file that has not yet been checkpointed. This client will not need
+ ** to read any frames earlier than minFrame from the wal file - they
+ ** can be safely read directly from the database file.
+ **
+ ** Because a ShmBarrier() call is made between taking the copy of
+ ** nBackfill and checking that the wal-header in shared-memory still
+ ** matches the one cached in pWal->hdr, it is guaranteed that the
+ ** checkpointer that set nBackfill was not working with a wal-index
+ ** header newer than that cached in pWal->hdr. If it were, that could
+ ** cause a problem. The checkpointer could omit to checkpoint
+ ** a version of page X that lies before pWal->minFrame (call that version
+ ** A) on the basis that there is a newer version (version B) of the same
+ ** page later in the wal file. But if version B happens to like past
+ ** frame pWal->hdr.mxFrame - then the client would incorrectly assume
+ ** that it can read version A from the database file. However, since
+ ** we can guarantee that the checkpointer that set nBackfill could not
+ ** see any pages past pWal->hdr.mxFrame, this problem does not come up.
+ */
+ pWal->minFrame = pInfo->nBackfill+1;
+ 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;
}
@@ -46533,6 +53167,14 @@ SQLITE_PRIVATE int sqlite3WalBeginReadTransaction(Wal *pWal, int *pChanged){
int rc; /* Return code */
int cnt = 0; /* Number of TryBeginRead attempts */
+#ifdef SQLITE_ENABLE_SNAPSHOT
+ int bChanged = 0;
+ WalIndexHdr *pSnapshot = pWal->pSnapshot;
+ if( pSnapshot && memcmp(pSnapshot, &pWal->hdr, sizeof(WalIndexHdr))!=0 ){
+ bChanged = 1;
+ }
+#endif
+
do{
rc = walTryBeginRead(pWal, pChanged, 0, ++cnt);
}while( rc==WAL_RETRY );
@@ -46540,6 +53182,66 @@ SQLITE_PRIVATE int sqlite3WalBeginReadTransaction(Wal *pWal, int *pChanged){
testcase( (rc&0xff)==SQLITE_IOERR );
testcase( rc==SQLITE_PROTOCOL );
testcase( rc==SQLITE_OK );
+
+#ifdef SQLITE_ENABLE_SNAPSHOT
+ if( rc==SQLITE_OK ){
+ if( pSnapshot && memcmp(pSnapshot, &pWal->hdr, sizeof(WalIndexHdr))!=0 ){
+ /* At this point the client has a lock on an aReadMark[] slot holding
+ ** a value equal to or smaller than pSnapshot->mxFrame, but pWal->hdr
+ ** is populated with the wal-index header corresponding to the head
+ ** of the wal file. Verify that pSnapshot is still valid before
+ ** continuing. Reasons why pSnapshot might no longer be valid:
+ **
+ ** (1) The WAL file has been reset since the snapshot was taken.
+ ** In this case, the salt will have changed.
+ **
+ ** (2) A checkpoint as been attempted that wrote frames past
+ ** pSnapshot->mxFrame into the database file. Note that the
+ ** checkpoint need not have completed for this to cause problems.
+ */
+ volatile WalCkptInfo *pInfo = walCkptInfo(pWal);
+
+ assert( pWal->readLock>0 || pWal->hdr.mxFrame==0 );
+ assert( pInfo->aReadMark[pWal->readLock]<=pSnapshot->mxFrame );
+
+ /* It is possible that there is a checkpointer thread running
+ ** concurrent with this code. If this is the case, it may be that the
+ ** checkpointer has already determined that it will checkpoint
+ ** snapshot X, where X is later in the wal file than pSnapshot, but
+ ** has not yet set the pInfo->nBackfillAttempted variable to indicate
+ ** its intent. To avoid the race condition this leads to, ensure that
+ ** there is no checkpointer process by taking a shared CKPT lock
+ ** before checking pInfo->nBackfillAttempted. */
+ rc = walLockShared(pWal, WAL_CKPT_LOCK);
+
+ if( rc==SQLITE_OK ){
+ /* Check that the wal file has not been wrapped. Assuming that it has
+ ** not, also check that no checkpointer has attempted to checkpoint any
+ ** frames beyond pSnapshot->mxFrame. If either of these conditions are
+ ** true, return SQLITE_BUSY_SNAPSHOT. Otherwise, overwrite pWal->hdr
+ ** with *pSnapshot and set *pChanged as appropriate for opening the
+ ** snapshot. */
+ if( !memcmp(pSnapshot->aSalt, pWal->hdr.aSalt, sizeof(pWal->hdr.aSalt))
+ && pSnapshot->mxFrame>=pInfo->nBackfillAttempted
+ ){
+ assert( pWal->readLock>0 );
+ memcpy(&pWal->hdr, pSnapshot, sizeof(WalIndexHdr));
+ *pChanged = bChanged;
+ }else{
+ rc = SQLITE_BUSY_SNAPSHOT;
+ }
+
+ /* Release the shared CKPT lock obtained above. */
+ walUnlockShared(pWal, WAL_CKPT_LOCK);
+ }
+
+
+ if( rc!=SQLITE_OK ){
+ sqlite3WalEndReadTransaction(pWal);
+ }
+ }
+ }
+#endif
return rc;
}
@@ -46556,23 +53258,22 @@ SQLITE_PRIVATE void sqlite3WalEndReadTransaction(Wal *pWal){
}
/*
-** 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.
+** Search the wal file for page pgno. If found, set *piRead to the frame that
+** contains the page. Otherwise, if pgno is not in the wal file, set *piRead
+** to zero.
**
-** 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.
+** Return SQLITE_OK if successful, or an error code if an error occurs. If an
+** error does occur, the final value of *piRead is undefined.
*/
-SQLITE_PRIVATE int sqlite3WalRead(
+SQLITE_PRIVATE int sqlite3WalFindFrame(
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 *piRead /* OUT: Frame number (or zero) */
){
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 */
+ int iMinHash;
/* This routine is only be called from within a read transaction. */
assert( pWal->readLock>=0 || pWal->lockError );
@@ -46584,7 +53285,7 @@ SQLITE_PRIVATE int sqlite3WalRead(
** WAL were empty.
*/
if( iLast==0 || pWal->readLock==0 ){
- *pInWal = 0;
+ *piRead = 0;
return SQLITE_OK;
}
@@ -46613,7 +53314,8 @@ SQLITE_PRIVATE int sqlite3WalRead(
** 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--){
+ iMinHash = walFramePage(pWal->minFrame);
+ for(iHash=walFramePage(iLast); iHash>=iMinHash && 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] */
@@ -46628,8 +53330,8 @@ SQLITE_PRIVATE int sqlite3WalRead(
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 */
+ if( iFrame<=iLast && iFrame>=pWal->minFrame && aPgno[aHash[iKey]]==pgno ){
+ assert( iFrame>iRead || CORRUPT_DB );
iRead = iFrame;
}
if( (nCollide--)==0 ){
@@ -46645,7 +53347,8 @@ SQLITE_PRIVATE int sqlite3WalRead(
{
u32 iRead2 = 0;
u32 iTest;
- for(iTest=iLast; iTest>0; iTest--){
+ assert( pWal->minFrame>0 );
+ for(iTest=iLast; iTest>=pWal->minFrame; iTest--){
if( walFramePgno(pWal, iTest)==pgno ){
iRead2 = iTest;
break;
@@ -46655,26 +53358,31 @@ SQLITE_PRIVATE int sqlite3WalRead(
}
#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;
+ *piRead = iRead;
return SQLITE_OK;
}
+/*
+** Read the contents of frame iRead from the wal file into buffer pOut
+** (which is nOut bytes in size). Return SQLITE_OK if successful, or an
+** error code otherwise.
+*/
+SQLITE_PRIVATE int sqlite3WalReadFrame(
+ Wal *pWal, /* WAL handle */
+ u32 iRead, /* Frame to read */
+ int nOut, /* Size of buffer pOut in bytes */
+ u8 *pOut /* Buffer to write page data to */
+){
+ 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;
+ /* testcase( IS_BIG_INT(iOffset) ); // requires a 4GiB WAL */
+ return sqlite3OsRead(pWal->pWalFd, pOut, (nOut>sz ? sz : nOut), iOffset);
+}
/*
** Return the size of the database in pages (or zero, if unknown).
@@ -46727,7 +53435,7 @@ SQLITE_PRIVATE int sqlite3WalBeginWriteTransaction(Wal *pWal){
if( memcmp(&pWal->hdr, (void *)walIndexHdr(pWal), sizeof(WalIndexHdr))!=0 ){
walUnlockExclusive(pWal, WAL_WRITE_LOCK, 1);
pWal->writeLock = 0;
- rc = SQLITE_BUSY;
+ rc = SQLITE_BUSY_SNAPSHOT;
}
return rc;
@@ -46789,7 +53497,6 @@ SQLITE_PRIVATE int sqlite3WalUndo(Wal *pWal, int (*xUndo)(void *, Pgno), void *p
}
if( iMax!=pWal->hdr.mxFrame ) walCleanupHash(pWal);
}
- assert( rc==SQLITE_OK );
return rc;
}
@@ -46838,7 +53545,6 @@ SQLITE_PRIVATE int sqlite3WalSavepointUndo(Wal *pWal, u32 *aWalData){
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
@@ -46871,20 +53577,8 @@ static int walRestartLog(Wal *pWal){
** 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 );
+ ** to handle if this transaction is rolled back. */
+ walRestartHdr(pWal, salt1);
walUnlockExclusive(pWal, WAL_READ_LOCK(1), WAL_NREADER-1);
}else if( rc!=SQLITE_BUSY ){
return rc;
@@ -46941,7 +53635,7 @@ static int walWriteToLog(
iAmt -= iFirstAmt;
pContent = (void*)(iFirstAmt + (char*)pContent);
assert( p->syncFlags & (SQLITE_SYNC_NORMAL|SQLITE_SYNC_FULL) );
- rc = sqlite3OsSync(p->pFd, p->syncFlags);
+ rc = sqlite3OsSync(p->pFd, p->syncFlags & SQLITE_SYNC_MASK);
if( iAmt==0 || rc ) return rc;
}
rc = sqlite3OsWrite(p->pFd, pContent, iAmt, iOffset);
@@ -47086,7 +53780,7 @@ SQLITE_PRIVATE int sqlite3WalFrames(
**
** 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.
+ ** or synchronous==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
@@ -47172,7 +53866,7 @@ SQLITE_PRIVATE int sqlite3WalFrames(
*/
SQLITE_PRIVATE int sqlite3WalCheckpoint(
Wal *pWal, /* Wal connection */
- int eMode, /* PASSIVE, FULL or RESTART */
+ int eMode, /* PASSIVE, FULL, RESTART, or TRUNCATE */
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) */
@@ -47184,29 +53878,42 @@ SQLITE_PRIVATE int sqlite3WalCheckpoint(
int rc; /* Return code */
int isChanged = 0; /* True if a new wal-index header is loaded */
int eMode2 = eMode; /* Mode to pass to walCheckpoint() */
+ int (*xBusy2)(void*) = xBusy; /* Busy handler for eMode2 */
assert( pWal->ckptLock==0 );
assert( pWal->writeLock==0 );
+ /* EVIDENCE-OF: R-62920-47450 The busy-handler callback is never invoked
+ ** in the SQLITE_CHECKPOINT_PASSIVE mode. */
+ assert( eMode!=SQLITE_CHECKPOINT_PASSIVE || xBusy==0 );
+
if( pWal->readOnly ) return SQLITE_READONLY;
WALTRACE(("WAL%p: checkpoint begins\n", pWal));
+
+ /* IMPLEMENTATION-OF: R-62028-47212 All calls obtain an exclusive
+ ** "checkpoint" lock on the database file. */
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. */
+ /* EVIDENCE-OF: R-10421-19736 If any other process is running a
+ ** checkpoint operation at the same time, the lock cannot be obtained and
+ ** SQLITE_BUSY is returned.
+ ** EVIDENCE-OF: R-53820-33897 Even if there is a busy-handler configured,
+ ** it will not be invoked in this case.
+ */
+ testcase( rc==SQLITE_BUSY );
+ testcase( xBusy!=0 );
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.
+ /* IMPLEMENTATION-OF: R-59782-36818 The SQLITE_CHECKPOINT_FULL, RESTART and
+ ** TRUNCATE modes also obtain the exclusive "writer" lock on the database
+ ** file.
**
- ** 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.
+ ** EVIDENCE-OF: R-60642-04082 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.
*/
if( eMode!=SQLITE_CHECKPOINT_PASSIVE ){
rc = walBusyLock(pWal, xBusy, pBusyArg, WAL_WRITE_LOCK, 1);
@@ -47214,6 +53921,7 @@ SQLITE_PRIVATE int sqlite3WalCheckpoint(
pWal->writeLock = 1;
}else if( rc==SQLITE_BUSY ){
eMode2 = SQLITE_CHECKPOINT_PASSIVE;
+ xBusy2 = 0;
rc = SQLITE_OK;
}
}
@@ -47221,6 +53929,9 @@ SQLITE_PRIVATE int sqlite3WalCheckpoint(
/* Read the wal-index header. */
if( rc==SQLITE_OK ){
rc = walIndexReadHdr(pWal, &isChanged);
+ if( isChanged && pWal->pDbFd->pMethods->iVersion>=3 ){
+ sqlite3OsUnfetch(pWal->pDbFd, 0, 0);
+ }
}
/* Copy data from the log to the database file. */
@@ -47228,7 +53939,7 @@ SQLITE_PRIVATE int sqlite3WalCheckpoint(
if( pWal->hdr.mxFrame && walPagesize(pWal)!=nBuf ){
rc = SQLITE_CORRUPT_BKPT;
}else{
- rc = walCheckpoint(pWal, eMode2, xBusy, pBusyArg, sync_flags, zBuf);
+ rc = walCheckpoint(pWal, eMode2, xBusy2, pBusyArg, sync_flags, zBuf);
}
/* If no error occurred, set the output variables. */
@@ -47340,6 +54051,35 @@ SQLITE_PRIVATE int sqlite3WalHeapMemory(Wal *pWal){
return (pWal && pWal->exclusiveMode==WAL_HEAPMEMORY_MODE );
}
+#ifdef SQLITE_ENABLE_SNAPSHOT
+/* Create a snapshot object. The content of a snapshot is opaque to
+** every other subsystem, so the WAL module can put whatever it needs
+** in the object.
+*/
+SQLITE_PRIVATE int sqlite3WalSnapshotGet(Wal *pWal, sqlite3_snapshot **ppSnapshot){
+ int rc = SQLITE_OK;
+ WalIndexHdr *pRet;
+
+ assert( pWal->readLock>=0 && pWal->writeLock==0 );
+
+ pRet = (WalIndexHdr*)sqlite3_malloc(sizeof(WalIndexHdr));
+ if( pRet==0 ){
+ rc = SQLITE_NOMEM;
+ }else{
+ memcpy(pRet, &pWal->hdr, sizeof(WalIndexHdr));
+ *ppSnapshot = (sqlite3_snapshot*)pRet;
+ }
+
+ return rc;
+}
+
+/* Try to open on pSnapshot when the next read-transaction starts
+*/
+SQLITE_PRIVATE void sqlite3WalSnapshotOpen(Wal *pWal, sqlite3_snapshot *pSnapshot){
+ pWal->pSnapshot = (WalIndexHdr*)pSnapshot;
+}
+#endif /* SQLITE_ENABLE_SNAPSHOT */
+
#ifdef SQLITE_ENABLE_ZIPVFS
/*
** If the argument is not NULL, it points to a Wal object that holds a
@@ -47352,6 +54092,12 @@ SQLITE_PRIVATE int sqlite3WalFramesize(Wal *pWal){
}
#endif
+/* Return the sqlite3_file object for the WAL file
+*/
+SQLITE_PRIVATE sqlite3_file *sqlite3WalFile(Wal *pWal){
+ return pWal->pWalFd;
+}
+
#endif /* #ifndef SQLITE_OMIT_WAL */
/************** End of wal.c *************************************************/
@@ -47386,7 +54132,7 @@ SQLITE_PRIVATE int sqlite3WalFramesize(Wal *pWal){
** May you share freely, never taking more than you give.
**
*************************************************************************
-** This file implements a external (disk-based) database using BTrees.
+** This file implements an external (disk-based) database using BTrees.
** For a detailed discussion of BTrees, refer to
**
** Donald E. Knuth, THE ART OF COMPUTER PROGRAMMING, Volume 3:
@@ -47433,13 +54179,13 @@ SQLITE_PRIVATE int sqlite3WalFramesize(Wal *pWal){
**
** OFFSET SIZE DESCRIPTION
** 0 16 Header string: "SQLite format 3\000"
-** 16 2 Page size in bytes.
+** 16 2 Page size in bytes. (1 means 65536)
** 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
+** 21 1 Max embedded payload fraction (must be 64)
+** 22 1 Min embedded payload fraction (must be 32)
+** 23 1 Min leaf payload fraction (must be 32)
** 24 4 File change counter
** 28 4 Reserved for future use
** 32 4 First freelist page
@@ -47453,9 +54199,10 @@ SQLITE_PRIVATE int sqlite3WalFramesize(Wal *pWal){
** 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
+** 68 4 Application-ID
+** 72 20 unused
+** 92 4 The version-valid-for number
+** 96 4 SQLITE_VERSION_NUMBER
**
** All of the integer values are big-endian (most significant byte first).
**
@@ -47511,7 +54258,7 @@ SQLITE_PRIVATE int sqlite3WalFramesize(Wal *pWal){
**
** 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
+** only keys and no data. The intkey flag means that the key is an integer
** which is stored in the key size entry of the cell header rather than in
** the payload area.
**
@@ -47589,6 +54336,7 @@ SQLITE_PRIVATE int sqlite3WalFramesize(Wal *pWal){
** 4 Number of leaf pointers on this page
** * zero or more pages numbers of leaves
*/
+/* #include "sqliteInt.h" */
/* The following value is the maximum cell size assuming a maximum page
@@ -47606,6 +54354,7 @@ SQLITE_PRIVATE int sqlite3WalFramesize(Wal *pWal){
/* Forward declarations */
typedef struct MemPage MemPage;
typedef struct BtLock BtLock;
+typedef struct CellInfo CellInfo;
/*
** This is a magic string that appears at the beginning of every
@@ -47648,12 +54397,14 @@ typedef struct BtLock BtLock;
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 intKey; /* True if table b-trees. False for index b-trees */
+ u8 intKeyLeaf; /* True if the leaf of an intKey table */
+ u8 noPayload; /* True if internal intKey page (thus w/o data) */
+ u8 leaf; /* True if a leaf page */
u8 hdrOffset; /* 100 for page 1. 0 otherwise */
u8 childPtrSize; /* 0 if leaf==1. 4 if leaf==0 */
u8 max1bytePayload; /* min(maxLocal,127) */
+ u8 bBusy; /* Prevent endless loops on corrupt database files */
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 */
@@ -47667,7 +54418,10 @@ struct MemPage {
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 */
+ u8 *aDataOfst; /* Same as aData for leaves. aData+4 for interior */
DbPage *pDbPage; /* Pager page handle */
+ u16 (*xCellSize)(MemPage*,u8*); /* cellSizePtr method */
+ void (*xParseCell)(MemPage*,u8*,CellInfo*); /* btreeParseCell method */
Pgno pgno; /* Page number for this page */
};
@@ -47723,8 +54477,10 @@ struct 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 */
+ u8 hasIncrblobCur; /* True if there are one or more Incrblob cursors */
int wantToLock; /* Number of nested calls to sqlite3BtreeEnter() */
int nBackup; /* Number of backup operations reading this btree */
+ u32 iDataVersion; /* Combines with pBt->pPager->iDataVersion */
Btree *pNext; /* List of other sharable Btrees from the same db */
Btree *pPrev; /* Back pointer of the same list */
#ifndef SQLITE_OMIT_SHARED_CACHE
@@ -47787,9 +54543,13 @@ struct BtShared {
#ifndef SQLITE_OMIT_AUTOVACUUM
u8 autoVacuum; /* True if auto-vacuum is enabled */
u8 incrVacuum; /* True if incr-vacuum is enabled */
+ u8 bDoTruncate; /* True to truncate db on commit */
#endif
u8 inTransaction; /* Transaction state */
u8 max1bytePayload; /* Maximum first byte of cell for a 1-byte payload */
+#ifdef SQLITE_HAS_CODEC
+ u8 optimalReserve; /* Desired amount of reserved space per page */
+#endif
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 */
@@ -47809,7 +54569,7 @@ struct BtShared {
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 */
+ u8 *pTmpSpace; /* Temp space sufficient to hold a single cell */
};
/*
@@ -47828,15 +54588,11 @@ struct BtShared {
** 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 */
+ i64 nKey; /* The key for INTKEY tables, or nPayload otherwise */
+ u8 *pPayload; /* Pointer to the start of payload */
+ u32 nPayload; /* Bytes of payload */
+ u16 nLocal; /* Amount of payload held locally, not on overflow */
u16 nSize; /* Size of the cell content on the main b-tree page */
};
@@ -47864,45 +54620,65 @@ struct CellInfo {
**
** Fields in this structure are accessed under the BtShared.mutex
** found at self->pBt->mutex.
+**
+** skipNext meaning:
+** eState==SKIPNEXT && skipNext>0: Next sqlite3BtreeNext() is no-op.
+** eState==SKIPNEXT && skipNext<0: Next sqlite3BtreePrevious() is no-op.
+** eState==FAULT: Cursor fault with skipNext as error code.
*/
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
+ BtCursor *pNext; /* Forms a linked list of all cursors */
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 */
+ i64 nKey; /* Size of pKey, or last integer key */
+ void *pKey; /* Saved key that was cursor last known position */
+ Pgno pgnoRoot; /* The root page of this tree */
+ int nOvflAlloc; /* Allocated size of aOverflow[] array */
+ int skipNext; /* Prev() is noop if negative. Next() is noop if positive.
+ ** Error code if eState==CURSOR_FAULT */
+ u8 curFlags; /* zero or more BTCF_* flags defined below */
+ u8 curPagerFlags; /* Flags to send to sqlite3PagerGet() */
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 */
+ u8 hints; /* As configured by CursorSetHints() */
+ /* All fields above are zeroed when the cursor is allocated. See
+ ** sqlite3BtreeCursorZero(). Fields that follow must be manually
+ ** initialized. */
+ i8 iPage; /* Index of current page in apPage */
+ u8 curIntKey; /* Value of apPage[0]->intKey */
+ struct KeyInfo *pKeyInfo; /* Argument passed to comparison function */
+ void *padding1; /* Make object size a multiple of 16 */
u16 aiIdx[BTCURSOR_MAX_DEPTH]; /* Current index in apPage[i] */
MemPage *apPage[BTCURSOR_MAX_DEPTH]; /* Pages from root to current page */
};
/*
+** Legal values for BtCursor.curFlags
+*/
+#define BTCF_WriteFlag 0x01 /* True if a write cursor */
+#define BTCF_ValidNKey 0x02 /* True if info.nKey is valid */
+#define BTCF_ValidOvfl 0x04 /* True if aOverflow is valid */
+#define BTCF_AtLast 0x08 /* Cursor is pointing ot the last entry */
+#define BTCF_Incrblob 0x10 /* True if an incremental I/O handle */
+#define BTCF_Multiple 0x20 /* Maybe another cursor on the same btree */
+
+/*
** 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_VALID:
+** Cursor points to a valid entry. getPayload() etc. may be called.
+**
+** CURSOR_SKIPNEXT:
+** Cursor is valid except that the Cursor.skipNext field is non-zero
+** indicating that the next sqlite3BtreeNext() or sqlite3BtreePrevious()
+** operation should be a no-op.
+**
** 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
@@ -47911,16 +54687,17 @@ struct BtCursor {
** seek the cursor to the saved position.
**
** CURSOR_FAULT:
-** A unrecoverable error (an I/O error or a malloc failure) has occurred
+** An 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
+** should return the error code stored in BtCursor.skipNext
*/
#define CURSOR_INVALID 0
#define CURSOR_VALID 1
-#define CURSOR_REQUIRESEEK 2
-#define CURSOR_FAULT 3
+#define CURSOR_SKIPNEXT 2
+#define CURSOR_REQUIRESEEK 3
+#define CURSOR_FAULT 4
/*
** The database page the PENDING_BYTE occupies. This page is never used.
@@ -48024,7 +54801,10 @@ struct IntegrityCk {
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 */
+ const char *zPfx; /* Error message prefix */
+ int v1, v2; /* Values for up to two %d fields in zPfx */
StrAccum errMsg; /* Accumulate the error message text here */
+ u32 *heap; /* Min-heap used for analyzing cell coverage */
};
/*
@@ -48035,6 +54815,23 @@ struct IntegrityCk {
#define get4byte sqlite3Get4byte
#define put4byte sqlite3Put4byte
+/*
+** get2byteAligned(), unlike get2byte(), requires that its argument point to a
+** two-byte aligned address. get2bytea() is only used for accessing the
+** cell addresses in a btree header.
+*/
+#if SQLITE_BYTEORDER==4321
+# define get2byteAligned(x) (*(u16*)(x))
+#elif SQLITE_BYTEORDER==1234 && !defined(SQLITE_DISABLE_INTRINSIC) \
+ && GCC_VERSION>=4008000
+# define get2byteAligned(x) __builtin_bswap16(*(u16*)(x))
+#elif SQLITE_BYTEORDER==1234 && !defined(SQLITE_DISABLE_INTRINSIC) \
+ && defined(_MSC_VER) && _MSC_VER>=1300
+# define get2byteAligned(x) _byteswap_ushort(*(u16*)(x))
+#else
+# define get2byteAligned(x) ((x)[0]<<8 | (x)[1])
+#endif
+
/************** End of btreeInt.h ********************************************/
/************** Continuing where we left off in btmutex.c ********************/
#ifndef SQLITE_OMIT_SHARED_CACHE
@@ -48059,7 +54856,7 @@ static void lockBtreeMutex(Btree *p){
** Release the BtShared mutex associated with B-Tree handle p and
** clear the p->locked boolean.
*/
-static void unlockBtreeMutex(Btree *p){
+static void SQLITE_NOINLINE unlockBtreeMutex(Btree *p){
BtShared *pBt = p->pBt;
assert( p->locked==1 );
assert( sqlite3_mutex_held(pBt->mutex) );
@@ -48070,6 +54867,9 @@ static void unlockBtreeMutex(Btree *p){
p->locked = 0;
}
+/* Forward reference */
+static void SQLITE_NOINLINE btreeLockCarefully(Btree *p);
+
/*
** Enter a mutex on the given BTree object.
**
@@ -48087,8 +54887,6 @@ static void unlockBtreeMutex(Btree *p){
** 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
@@ -48113,9 +54911,20 @@ SQLITE_PRIVATE void sqlite3BtreeEnter(Btree *p){
if( !p->sharable ) return;
p->wantToLock++;
if( p->locked ) return;
+ btreeLockCarefully(p);
+}
+
+/* This is a helper function for sqlite3BtreeLock(). By moving
+** complex, but seldom used logic, out of sqlite3BtreeLock() and
+** into this routine, we avoid unnecessary stack pointer changes
+** and thus help the sqlite3BtreeLock() routine to run much faster
+** in the common case.
+*/
+static void SQLITE_NOINLINE btreeLockCarefully(Btree *p){
+ Btree *pLater;
/* In most cases, we should be able to acquire the lock we
- ** want without having to go throught the ascending lock
+ ** want without having to go through the ascending lock
** procedure that follows. Just be sure not to block.
*/
if( sqlite3_mutex_try(p->pBt->mutex)==SQLITE_OK ){
@@ -48145,10 +54954,12 @@ SQLITE_PRIVATE void sqlite3BtreeEnter(Btree *p){
}
}
+
/*
** Exit the recursive mutex on a Btree.
*/
SQLITE_PRIVATE void sqlite3BtreeLeave(Btree *p){
+ assert( sqlite3_mutex_held(p->db->mutex) );
if( p->sharable ){
assert( p->wantToLock>0 );
p->wantToLock--;
@@ -48320,10 +55131,11 @@ SQLITE_PRIVATE void sqlite3BtreeEnterAll(sqlite3 *db){
** May you share freely, never taking more than you give.
**
*************************************************************************
-** This file implements a external (disk-based) database using BTrees.
+** This file implements an 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.
*/
+/* #include "btreeInt.h" */
/*
** The header string that appears at the beginning of every
@@ -48353,6 +55165,25 @@ int sqlite3BtreeTrace=1; /* True to enable tracing */
*/
#define get2byteNotZero(X) (((((int)get2byte(X))-1)&0xffff)+1)
+/*
+** Values passed as the 5th argument to allocateBtreePage()
+*/
+#define BTALLOC_ANY 0 /* Allocate any page */
+#define BTALLOC_EXACT 1 /* Allocate exact page if possible */
+#define BTALLOC_LE 2 /* Allocate any page <= the parameter */
+
+/*
+** Macro IfNotOmitAV(x) returns (x) if SQLITE_OMIT_AUTOVACUUM is not
+** defined, or 0 if it is. For example:
+**
+** bIncrVacuum = IfNotOmitAV(pBtShared->incrVacuum);
+*/
+#ifndef SQLITE_OMIT_AUTOVACUUM
+#define IfNotOmitAV(expr) (expr)
+#else
+#define IfNotOmitAV(expr) 0
+#endif
+
#ifndef SQLITE_OMIT_SHARED_CACHE
/*
** A list of BtShared objects that are eligible for participation
@@ -48377,7 +55208,7 @@ static BtShared *SQLITE_WSD sqlite3SharedCacheList = 0;
** 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){
+SQLITE_API int SQLITE_STDCALL sqlite3_enable_shared_cache(int enable){
sqlite3GlobalConfig.sharedCacheEnabled = enable;
return SQLITE_OK;
}
@@ -48453,7 +55284,7 @@ static int hasSharedCacheTableLock(
** 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) ){
+ if( isIndex && (!pSchema || (pSchema->schemaFlags&DB_SchemaLoaded)==0) ){
return 1;
}
@@ -48466,6 +55297,12 @@ static int hasSharedCacheTableLock(
for(p=sqliteHashFirst(&pSchema->idxHash); p; p=sqliteHashNext(p)){
Index *pIdx = (Index *)sqliteHashData(p);
if( pIdx->tnum==(int)iRoot ){
+ if( iTab ){
+ /* Two or more indexes share the same root page. There must
+ ** be imposter tables. So just return true. The assert is not
+ ** useful in that case. */
+ return 1;
+ }
iTab = pIdx->pTable->tnum;
}
}
@@ -48737,16 +55574,11 @@ static int cursorHoldsMutex(BtCursor *p){
}
#endif
-
-#ifndef SQLITE_OMIT_INCRBLOB
/*
-** Invalidate the overflow page-list cache for cursor pCur, if any.
+** Invalidate the overflow cache of the cursor passed as the first argument.
+** on the shared btree structure pBt.
*/
-static void invalidateOverflowCache(BtCursor *pCur){
- assert( cursorHoldsMutex(pCur) );
- sqlite3_free(pCur->aOverflow);
- pCur->aOverflow = 0;
-}
+#define invalidateOverflowCache(pCur) (pCur->curFlags &= ~BTCF_ValidOvfl)
/*
** Invalidate the overflow page-list cache for all cursors opened
@@ -48760,6 +55592,7 @@ static void invalidateAllOverflowCache(BtShared *pBt){
}
}
+#ifndef SQLITE_OMIT_INCRBLOB
/*
** This function is called before modifying the contents of a table
** to invalidate any incrblob cursors that are open on the
@@ -48779,19 +55612,21 @@ static void invalidateIncrblobCursors(
int isClearTable /* True if all rows are being deleted */
){
BtCursor *p;
- BtShared *pBt = pBtree->pBt;
+ if( pBtree->hasIncrblobCur==0 ) return;
assert( sqlite3BtreeHoldsMutex(pBtree) );
- for(p=pBt->pCursor; p; p=p->pNext){
- if( p->isIncrblobHandle && (isClearTable || p->info.nKey==iRow) ){
- p->eState = CURSOR_INVALID;
+ pBtree->hasIncrblobCur = 0;
+ for(p=pBtree->pBt->pCursor; p; p=p->pNext){
+ if( (p->curFlags & BTCF_Incrblob)!=0 ){
+ pBtree->hasIncrblobCur = 1;
+ if( isClearTable || p->info.nKey==iRow ){
+ p->eState = CURSOR_INVALID;
+ }
}
}
}
#else
- /* Stub functions when INCRBLOB is omitted */
- #define invalidateOverflowCache(x)
- #define invalidateAllOverflowCache(x)
+ /* Stub function when INCRBLOB is omitted */
#define invalidateIncrblobCursors(x,y,z)
#endif /* SQLITE_OMIT_INCRBLOB */
@@ -48867,15 +55702,32 @@ static void btreeClearHasContent(BtShared *pBt){
}
/*
-** Save the current cursor position in the variables BtCursor.nKey
-** and BtCursor.pKey. The cursor's state is set to CURSOR_REQUIRESEEK.
+** Release all of the apPage[] pages for a cursor.
+*/
+static void btreeReleaseAllCursorPages(BtCursor *pCur){
+ int i;
+ for(i=0; i<=pCur->iPage; i++){
+ releasePage(pCur->apPage[i]);
+ pCur->apPage[i] = 0;
+ }
+ pCur->iPage = -1;
+}
+
+/*
+** The cursor passed as the only argument must point to a valid entry
+** when this function is called (i.e. have eState==CURSOR_VALID). This
+** function saves the current cursor key in variables pCur->nKey and
+** pCur->pKey. SQLITE_OK is returned if successful or an SQLite error
+** code otherwise.
**
-** The caller must ensure that the cursor is valid (has eState==CURSOR_VALID)
-** prior to calling this routine.
+** If the cursor is open on an intkey table, then the integer key
+** (the rowid) is stored in pCur->nKey and pCur->pKey is left set to
+** NULL. If the cursor is open on a non-intkey table, then pCur->pKey is
+** set to point to a malloced buffer pCur->nKey bytes in size containing
+** the key.
*/
-static int saveCursorPosition(BtCursor *pCur){
+static int saveCursorKey(BtCursor *pCur){
int rc;
-
assert( CURSOR_VALID==pCur->eState );
assert( 0==pCur->pKey );
assert( cursorHoldsMutex(pCur) );
@@ -48887,10 +55739,9 @@ static int saveCursorPosition(BtCursor *pCur){
** 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 );
+ ** data. */
+ if( 0==pCur->curIntKey ){
+ void *pKey = sqlite3Malloc( pCur->nKey );
if( pKey ){
rc = sqlite3BtreeKey(pCur, 0, (int)pCur->nKey, pKey);
if( rc==SQLITE_OK ){
@@ -48902,40 +55753,100 @@ static int saveCursorPosition(BtCursor *pCur){
rc = SQLITE_NOMEM;
}
}
- assert( !pCur->apPage[0]->intKey || !pCur->pKey );
+ assert( !pCur->curIntKey || !pCur->pKey );
+ return rc;
+}
+
+/*
+** 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 || CURSOR_SKIPNEXT==pCur->eState );
+ assert( 0==pCur->pKey );
+ assert( cursorHoldsMutex(pCur) );
+
+ if( pCur->eState==CURSOR_SKIPNEXT ){
+ pCur->eState = CURSOR_VALID;
+ }else{
+ pCur->skipNext = 0;
+ }
+ rc = saveCursorKey(pCur);
if( rc==SQLITE_OK ){
- int i;
- for(i=0; i<=pCur->iPage; i++){
- releasePage(pCur->apPage[i]);
- pCur->apPage[i] = 0;
- }
- pCur->iPage = -1;
+ btreeReleaseAllCursorPages(pCur);
pCur->eState = CURSOR_REQUIRESEEK;
}
- invalidateOverflowCache(pCur);
+ pCur->curFlags &= ~(BTCF_ValidNKey|BTCF_ValidOvfl|BTCF_AtLast);
return rc;
}
+/* Forward reference */
+static int SQLITE_NOINLINE saveCursorsOnList(BtCursor*,Pgno,BtCursor*);
+
/*
** 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()).
+** the table with root-page iRoot. "Saving the cursor position" means that
+** the location in the btree is remembered in such a way that it can be
+** moved back to the same spot after the btree has been modified. This
+** routine is called just before cursor pExcept is used to modify the
+** table, for example in BtreeDelete() or BtreeInsert().
+**
+** If there are two or more cursors on the same btree, then all such
+** cursors should have their BTCF_Multiple flag set. The btreeCursor()
+** routine enforces that rule. This routine only needs to be called in
+** the uncommon case when pExpect has the BTCF_Multiple flag set.
+**
+** If pExpect!=NULL and if no other cursors are found on the same root-page,
+** then the BTCF_Multiple flag on pExpect is cleared, to avoid another
+** pointless call to this routine.
+**
+** Implementation note: This routine merely checks to see if any cursors
+** need to be saved. It calls out to saveCursorsOnList() in the (unusual)
+** event that cursors are in need to being saved.
*/
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;
+ if( p!=pExcept && (0==iRoot || p->pgnoRoot==iRoot) ) break;
+ }
+ if( p ) return saveCursorsOnList(p, iRoot, pExcept);
+ if( pExcept ) pExcept->curFlags &= ~BTCF_Multiple;
+ return SQLITE_OK;
+}
+
+/* This helper routine to saveAllCursors does the actual work of saving
+** the cursors if and when a cursor is found that actually requires saving.
+** The common case is that no cursors need to be saved, so this routine is
+** broken out from its caller to avoid unnecessary stack pointer movement.
+*/
+static int SQLITE_NOINLINE saveCursorsOnList(
+ BtCursor *p, /* The first cursor that needs saving */
+ Pgno iRoot, /* Only save cursor with this iRoot. Save all if zero */
+ BtCursor *pExcept /* Do not save this cursor */
+){
+ do{
+ if( p!=pExcept && (0==iRoot || p->pgnoRoot==iRoot) ){
+ if( p->eState==CURSOR_VALID || p->eState==CURSOR_SKIPNEXT ){
+ int rc = saveCursorPosition(p);
+ if( SQLITE_OK!=rc ){
+ return rc;
+ }
+ }else{
+ testcase( p->iPage>0 );
+ btreeReleaseAllCursorPages(p);
}
}
- }
+ p = p->pNext;
+ }while( p );
return SQLITE_OK;
}
@@ -48963,7 +55874,7 @@ static int btreeMoveto(
){
int rc; /* Status code */
UnpackedRecord *pIdxKey; /* Unpacked index key */
- char aSpace[150]; /* Temp space for pIdxKey - to avoid a malloc */
+ char aSpace[200]; /* Temp space for pIdxKey - to avoid a malloc */
char *pFree = 0;
if( pKey ){
@@ -48973,6 +55884,10 @@ static int btreeMoveto(
);
if( pIdxKey==0 ) return SQLITE_NOMEM;
sqlite3VdbeRecordUnpack(pCur->pKeyInfo, (int)nKey, pKey, pIdxKey);
+ if( pIdxKey->nField==0 ){
+ sqlite3DbFree(pCur->pKeyInfo->db, pFree);
+ return SQLITE_CORRUPT_BKPT;
+ }
}else{
pIdxKey = 0;
}
@@ -48992,17 +55907,22 @@ static int btreeMoveto(
*/
static int btreeRestoreCursorPosition(BtCursor *pCur){
int rc;
+ int skipNext;
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);
+ rc = btreeMoveto(pCur, pCur->pKey, pCur->nKey, 0, &skipNext);
if( rc==SQLITE_OK ){
sqlite3_free(pCur->pKey);
pCur->pKey = 0;
assert( pCur->eState==CURSOR_VALID || pCur->eState==CURSOR_INVALID );
+ pCur->skipNext |= skipNext;
+ if( pCur->skipNext && pCur->eState==CURSOR_VALID ){
+ pCur->eState = CURSOR_SKIPNEXT;
+ }
}
return rc;
}
@@ -49013,29 +55933,73 @@ static int btreeRestoreCursorPosition(BtCursor *pCur){
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.
+** Determine whether or not a cursor has moved from the position where
+** it was last placed, or has been invalidated for any other reason.
+** Cursors can move when the row they are pointing at is deleted out
+** from under them, for example. Cursor might also move if a btree
+** is rebalanced.
+**
+** Calling this routine with a NULL cursor pointer returns false.
**
-** 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.
+** Use the separate sqlite3BtreeCursorRestore() routine to restore a cursor
+** back to where it ought to be if this routine returns true.
*/
-SQLITE_PRIVATE int sqlite3BtreeCursorHasMoved(BtCursor *pCur, int *pHasMoved){
+SQLITE_PRIVATE int sqlite3BtreeCursorHasMoved(BtCursor *pCur){
+ return pCur->eState!=CURSOR_VALID;
+}
+
+/*
+** This routine restores a cursor back to its original position after it
+** has been moved by some outside activity (such as a btree rebalance or
+** a row having been deleted out from under the cursor).
+**
+** On success, the *pDifferentRow parameter is false if the cursor is left
+** pointing at exactly the same row. *pDifferntRow is the row the cursor
+** was pointing to has been deleted, forcing the cursor to point to some
+** nearby row.
+**
+** This routine should only be called for a cursor that just returned
+** TRUE from sqlite3BtreeCursorHasMoved().
+*/
+SQLITE_PRIVATE int sqlite3BtreeCursorRestore(BtCursor *pCur, int *pDifferentRow){
int rc;
+ assert( pCur!=0 );
+ assert( pCur->eState!=CURSOR_VALID );
rc = restoreCursorPosition(pCur);
if( rc ){
- *pHasMoved = 1;
+ *pDifferentRow = 1;
return rc;
}
- if( pCur->eState!=CURSOR_VALID || pCur->skipNext!=0 ){
- *pHasMoved = 1;
+ if( pCur->eState!=CURSOR_VALID ){
+ *pDifferentRow = 1;
}else{
- *pHasMoved = 0;
+ assert( pCur->skipNext==0 );
+ *pDifferentRow = 0;
}
return SQLITE_OK;
}
+#ifdef SQLITE_ENABLE_CURSOR_HINTS
+/*
+** Provide hints to the cursor. The particular hint given (and the type
+** and number of the varargs parameters) is determined by the eHintType
+** parameter. See the definitions of the BTREE_HINT_* macros for details.
+*/
+SQLITE_PRIVATE void sqlite3BtreeCursorHint(BtCursor *pCur, int eHintType, ...){
+ /* Used only by system that substitute their own storage engine */
+}
+#endif
+
+/*
+** Provide flag hints to the cursor.
+*/
+SQLITE_PRIVATE void sqlite3BtreeCursorHintFlags(BtCursor *pCur, unsigned x){
+ assert( x==BTREE_SEEK_EQ || x==BTREE_BULKLOAD || x==0 );
+ pCur->hints = x;
+}
+
+
#ifndef SQLITE_OMIT_AUTOVACUUM
/*
** Given a page number of a regular database page, return the page
@@ -49089,7 +56053,7 @@ static void ptrmapPut(BtShared *pBt, Pgno key, u8 eType, Pgno parent, int *pRC){
return;
}
iPtrmap = PTRMAP_PAGENO(pBt, key);
- rc = sqlite3PagerGet(pBt->pPager, iPtrmap, &pDbPage);
+ rc = sqlite3PagerGet(pBt->pPager, iPtrmap, &pDbPage, 0);
if( rc!=SQLITE_OK ){
*pRC = rc;
return;
@@ -49132,7 +56096,7 @@ static int ptrmapGet(BtShared *pBt, Pgno key, u8 *pEType, Pgno *pPgno){
assert( sqlite3_mutex_held(pBt->mutex) );
iPtrmap = PTRMAP_PAGENO(pBt, key);
- rc = sqlite3PagerGet(pBt->pPager, iPtrmap, &pDbPage);
+ rc = sqlite3PagerGet(pBt->pPager, iPtrmap, &pDbPage, 0);
if( rc!=0 ){
return rc;
}
@@ -49164,127 +56128,218 @@ static int ptrmapGet(BtShared *pBt, Pgno key, u8 *pEType, Pgno *pPgno){
** the page, 1 means the second cell, and so forth) return a pointer
** to the cell content.
**
+** findCellPastPtr() does the same except it skips past the initial
+** 4-byte child pointer found on interior pages, if there is one.
+**
** 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)))))
+ ((P)->aData + ((P)->maskPage & get2byteAligned(&(P)->aCellIdx[2*(I)])))
+#define findCellPastPtr(P,I) \
+ ((P)->aDataOfst + ((P)->maskPage & get2byteAligned(&(P)->aCellIdx[2*(I)])))
/*
-** This a more complex version of findCell() that works for
-** pages that do contain overflow cells.
+** This is common tail processing for btreeParseCellPtr() and
+** btreeParseCellPtrIndex() for the case when the cell does not fit entirely
+** on a single B-tree page. Make necessary adjustments to the CellInfo
+** structure.
*/
-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--;
- }
+static SQLITE_NOINLINE void btreeParseCellAdjustSizeForOverflow(
+ MemPage *pPage, /* Page containing the cell */
+ u8 *pCell, /* Pointer to the cell text. */
+ CellInfo *pInfo /* Fill in this structure */
+){
+ /* 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 + (pInfo->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;
}
- return findCell(pPage, iCell);
+ pInfo->nSize = (u16)(&pInfo->pPayload[pInfo->nLocal] - pCell) + 4;
}
/*
-** 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.
+** The following routines are implementations of the MemPage.xParseCell()
+** method.
+**
+** Parse a cell content block and fill in the CellInfo structure.
**
-** Within this file, the parseCell() macro can be called instead of
-** btreeParseCellPtr(). Using some compilers, this will be faster.
+** btreeParseCellPtr() => table btree leaf nodes
+** btreeParseCellNoPayload() => table btree internal nodes
+** btreeParseCellPtrIndex() => index btree nodes
+**
+** There is also a wrapper function btreeParseCell() that works for
+** all MemPage types and that references the cell by index rather than
+** by pointer.
*/
+static void btreeParseCellPtrNoPayload(
+ MemPage *pPage, /* Page containing the cell */
+ u8 *pCell, /* Pointer to the cell text. */
+ CellInfo *pInfo /* Fill in this structure */
+){
+ assert( sqlite3_mutex_held(pPage->pBt->mutex) );
+ assert( pPage->leaf==0 );
+ assert( pPage->noPayload );
+ assert( pPage->childPtrSize==4 );
+#ifndef SQLITE_DEBUG
+ UNUSED_PARAMETER(pPage);
+#endif
+ pInfo->nSize = 4 + getVarint(&pCell[4], (u64*)&pInfo->nKey);
+ pInfo->nPayload = 0;
+ pInfo->nLocal = 0;
+ pInfo->pPayload = 0;
+ return;
+}
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 */
+ u8 *pIter; /* For scanning through pCell */
u32 nPayload; /* Number of bytes of cell payload */
+ u64 iKey; /* Extracted Key value */
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;
+ assert( pPage->intKeyLeaf || pPage->noPayload );
+ assert( pPage->noPayload==0 );
+ assert( pPage->intKeyLeaf );
+ assert( pPage->childPtrSize==0 );
+ pIter = pCell;
+
+ /* The next block of code is equivalent to:
+ **
+ ** pIter += getVarint32(pIter, nPayload);
+ **
+ ** The code is inlined to avoid a function call.
+ */
+ nPayload = *pIter;
+ if( nPayload>=0x80 ){
+ u8 *pEnd = &pIter[8];
+ nPayload &= 0x7f;
+ do{
+ nPayload = (nPayload<<7) | (*++pIter & 0x7f);
+ }while( (*pIter)>=0x80 && pIter<pEnd );
+ }
+ pIter++;
+
+ /* The next block of code is equivalent to:
+ **
+ ** pIter += getVarint(pIter, (u64*)&pInfo->nKey);
+ **
+ ** The code is inlined to avoid a function call.
+ */
+ iKey = *pIter;
+ if( iKey>=0x80 ){
+ u8 *pEnd = &pIter[7];
+ iKey &= 0x7f;
+ while(1){
+ iKey = (iKey<<7) | (*++pIter & 0x7f);
+ if( (*pIter)<0x80 ) break;
+ if( pIter>=pEnd ){
+ iKey = (iKey<<8) | *++pIter;
+ break;
+ }
}
- n += getVarint(&pCell[n], (u64*)&pInfo->nKey);
- pInfo->nData = nPayload;
- }else{
- pInfo->nData = 0;
- n += getVarint32(&pCell[n], nPayload);
- pInfo->nKey = nPayload;
}
+ pIter++;
+
+ pInfo->nKey = *(i64*)&iKey;
pInfo->nPayload = nPayload;
- pInfo->nHeader = n;
+ pInfo->pPayload = pIter;
testcase( nPayload==pPage->maxLocal );
testcase( nPayload==pPage->maxLocal+1 );
- if( likely(nPayload<=pPage->maxLocal) ){
+ if( 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->nSize = nPayload + (u16)(pIter - pCell);
+ if( pInfo->nSize<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 */
+ btreeParseCellAdjustSizeForOverflow(pPage, pCell, pInfo);
+ }
+}
+static void btreeParseCellPtrIndex(
+ MemPage *pPage, /* Page containing the cell */
+ u8 *pCell, /* Pointer to the cell text. */
+ CellInfo *pInfo /* Fill in this structure */
+){
+ u8 *pIter; /* For scanning through pCell */
+ u32 nPayload; /* Number of bytes of cell payload */
- 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;
+ assert( sqlite3_mutex_held(pPage->pBt->mutex) );
+ assert( pPage->leaf==0 || pPage->leaf==1 );
+ assert( pPage->intKeyLeaf==0 );
+ assert( pPage->noPayload==0 );
+ pIter = pCell + pPage->childPtrSize;
+ nPayload = *pIter;
+ if( nPayload>=0x80 ){
+ u8 *pEnd = &pIter[8];
+ nPayload &= 0x7f;
+ do{
+ nPayload = (nPayload<<7) | (*++pIter & 0x7f);
+ }while( *(pIter)>=0x80 && pIter<pEnd );
+ }
+ pIter++;
+ pInfo->nKey = nPayload;
+ pInfo->nPayload = nPayload;
+ pInfo->pPayload = pIter;
+ testcase( nPayload==pPage->maxLocal );
+ testcase( nPayload==pPage->maxLocal+1 );
+ if( nPayload<=pPage->maxLocal ){
+ /* This is the (easy) common case where the entire payload fits
+ ** on the local page. No overflow is required.
+ */
+ pInfo->nSize = nPayload + (u16)(pIter - pCell);
+ if( pInfo->nSize<4 ) pInfo->nSize = 4;
+ pInfo->nLocal = (u16)nPayload;
+ }else{
+ btreeParseCellAdjustSizeForOverflow(pPage, pCell, pInfo);
}
}
-#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);
+ pPage->xParseCell(pPage, findCell(pPage, iCell), pInfo);
}
/*
+** The following routines are implementations of the MemPage.xCellSize
+** method.
+**
** 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.
+**
+** cellSizePtrNoPayload() => table internal nodes
+** cellSizePtr() => all index nodes & table leaf nodes
*/
static u16 cellSizePtr(MemPage *pPage, u8 *pCell){
- u8 *pIter = &pCell[pPage->childPtrSize];
- u32 nSize;
+ u8 *pIter = pCell + pPage->childPtrSize; /* For looping over bytes of pCell */
+ u8 *pEnd; /* End mark for a varint */
+ u32 nSize; /* Size value to return */
#ifdef SQLITE_DEBUG
/* The value returned by this function should always be the same as
@@ -49292,29 +56347,32 @@ static u16 cellSizePtr(MemPage *pPage, u8 *pCell){
** 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);
+ pPage->xParseCell(pPage, pCell, &debuginfo);
#endif
+ assert( pPage->noPayload==0 );
+ nSize = *pIter;
+ if( nSize>=0x80 ){
+ pEnd = &pIter[8];
+ nSize &= 0x7f;
+ do{
+ nSize = (nSize<<7) | (*++pIter & 0x7f);
+ }while( *(pIter)>=0x80 && pIter<pEnd );
+ }
+ pIter++;
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 ){
+ if( nSize<=pPage->maxLocal ){
+ nSize += (u32)(pIter - pCell);
+ if( nSize<4 ) nSize = 4;
+ }else{
int minLocal = pPage->minLocal;
nSize = minLocal + (nSize - minLocal) % (pPage->pBt->usableSize - 4);
testcase( nSize==pPage->maxLocal );
@@ -49322,24 +56380,39 @@ static u16 cellSizePtr(MemPage *pPage, u8 *pCell){
if( nSize>pPage->maxLocal ){
nSize = minLocal;
}
- nSize += 4;
+ nSize += 4 + (u16)(pIter - pCell);
}
- nSize += (u32)(pIter - pCell);
+ assert( nSize==debuginfo.nSize || CORRUPT_DB );
+ return (u16)nSize;
+}
+static u16 cellSizePtrNoPayload(MemPage *pPage, u8 *pCell){
+ u8 *pIter = pCell + 4; /* For looping over bytes of pCell */
+ u8 *pEnd; /* End mark for a varint */
- /* The minimum size of any cell is 4 bytes. */
- if( nSize<4 ){
- nSize = 4;
- }
+#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;
+ pPage->xParseCell(pPage, pCell, &debuginfo);
+#else
+ UNUSED_PARAMETER(pPage);
+#endif
- assert( nSize==debuginfo.nSize );
- return (u16)nSize;
+ assert( pPage->childPtrSize==4 );
+ pEnd = pIter + 9;
+ while( (*pIter++)&0x80 && pIter<pEnd );
+ assert( debuginfo.nSize==(u16)(pIter - pCell) || CORRUPT_DB );
+ return (u16)(pIter - pCell);
}
+
#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));
+ return pPage->xCellSize(pPage, findCell(pPage, iCell));
}
#endif
@@ -49353,10 +56426,9 @@ 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]);
+ pPage->xParseCell(pPage, pCell, &info);
+ if( info.nLocal<info.nPayload ){
+ Pgno ovfl = get4byte(&pCell[info.nSize-4]);
ptrmapPut(pPage->pBt, ovfl, PTRMAP_OVERFLOW1, pPage->pgno, pRC);
}
}
@@ -49368,10 +56440,15 @@ static void ptrmapPutOvflPtr(MemPage *pPage, u8 *pCell, int *pRC){
** 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.
+**
+** EVIDENCE-OF: R-44582-60138 SQLite may from time to time reorganize a
+** b-tree page so that there are no freeblocks or fragment bytes, all
+** unused bytes are contained in the unallocated space region, and all
+** cells are packed tightly at the end of the page.
*/
static int defragmentPage(MemPage *pPage){
int i; /* Loop counter */
- int pc; /* Address of a i-th cell */
+ int pc; /* Address of the 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 */
@@ -49380,6 +56457,7 @@ static int defragmentPage(MemPage *pPage){
int nCell; /* Number of cells on the page */
unsigned char *data; /* The page data */
unsigned char *temp; /* Temp area for cell content */
+ unsigned char *src; /* Source of content */
int iCellFirst; /* First allowable cell index */
int iCellLast; /* Last possible cell index */
@@ -49389,15 +56467,13 @@ static int defragmentPage(MemPage *pPage){
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;
+ temp = 0;
+ src = 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;
@@ -49407,31 +56483,31 @@ static int defragmentPage(MemPage *pPage){
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 PRAGMA cell_size_check=ON.
*/
if( pc<iCellFirst || pc>iCellLast ){
return SQLITE_CORRUPT_BKPT;
}
-#endif
assert( pc>=iCellFirst && pc<=iCellLast );
- size = cellSizePtr(pPage, &temp[pc]);
+ size = pPage->xCellSize(pPage, &src[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);
+ if( temp==0 ){
+ int x;
+ if( cbrk==pc ) continue;
+ temp = sqlite3PagerTempSpace(pPage->pBt->pPager);
+ x = get2byte(&data[hdr+5]);
+ memcpy(&temp[x], &data[x], (cbrk+size) - x);
+ src = temp;
+ }
+ memcpy(&data[cbrk], &src[pc], size);
}
assert( cbrk>=iCellFirst );
put2byte(&data[hdr+5], cbrk);
@@ -49447,6 +56523,70 @@ static int defragmentPage(MemPage *pPage){
}
/*
+** Search the free-list on page pPg for space to store a cell nByte bytes in
+** size. If one can be found, return a pointer to the space and remove it
+** from the free-list.
+**
+** If no suitable space can be found on the free-list, return NULL.
+**
+** This function may detect corruption within pPg. If corruption is
+** detected then *pRc is set to SQLITE_CORRUPT and NULL is returned.
+**
+** Slots on the free list that are between 1 and 3 bytes larger than nByte
+** will be ignored if adding the extra space to the fragmentation count
+** causes the fragmentation count to exceed 60.
+*/
+static u8 *pageFindSlot(MemPage *pPg, int nByte, int *pRc){
+ const int hdr = pPg->hdrOffset;
+ u8 * const aData = pPg->aData;
+ int iAddr = hdr + 1;
+ int pc = get2byte(&aData[iAddr]);
+ int x;
+ int usableSize = pPg->pBt->usableSize;
+
+ assert( pc>0 );
+ do{
+ int size; /* Size of the free slot */
+ /* EVIDENCE-OF: R-06866-39125 Freeblocks are always connected in order of
+ ** increasing offset. */
+ if( pc>usableSize-4 || pc<iAddr+4 ){
+ *pRc = SQLITE_CORRUPT_BKPT;
+ return 0;
+ }
+ /* EVIDENCE-OF: R-22710-53328 The third and fourth bytes of each
+ ** freeblock form a big-endian integer which is the size of the freeblock
+ ** in bytes, including the 4-byte header. */
+ size = get2byte(&aData[pc+2]);
+ if( (x = size - nByte)>=0 ){
+ testcase( x==4 );
+ testcase( x==3 );
+ if( pc < pPg->cellOffset+2*pPg->nCell || size+pc > usableSize ){
+ *pRc = SQLITE_CORRUPT_BKPT;
+ return 0;
+ }else if( x<4 ){
+ /* EVIDENCE-OF: R-11498-58022 In a well-formed b-tree page, the total
+ ** number of bytes in fragments may not exceed 60. */
+ if( aData[hdr+7]>57 ) return 0;
+
+ /* Remove the slot from the free-list. Update the number of
+ ** fragmented bytes within the page. */
+ memcpy(&aData[iAddr], &aData[pc], 2);
+ aData[hdr+7] += (u8)x;
+ }else{
+ /* The slot remains on the free-list. Reduce its size to account
+ ** for the portion used by the new allocation. */
+ put2byte(&aData[pc+2], x);
+ }
+ return &aData[pc + x];
+ }
+ iAddr = pc;
+ pc = get2byte(&aData[pc]);
+ }while( pc );
+
+ return 0;
+}
+
+/*
** 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
@@ -49462,11 +56602,9 @@ static int defragmentPage(MemPage *pPage){
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 rc = SQLITE_OK; /* Integer return code */
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 );
@@ -49474,62 +56612,50 @@ static int allocateSpace(MemPage *pPage, int nByte, int *pIdx){
assert( nByte>=0 ); /* Minimum cell size is 4 */
assert( pPage->nFree>=nByte );
assert( pPage->nOverflow==0 );
- usableSize = pPage->pBt->usableSize;
- assert( nByte < usableSize-8 );
+ assert( nByte < (int)(pPage->pBt->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;
+ assert( gap<=65536 );
+ /* EVIDENCE-OF: R-29356-02391 If the database uses a 65536-byte page size
+ ** and the reserved space is zero (the usual value for reserved space)
+ ** then the cell content offset of an empty page wants to be 65536.
+ ** However, that integer is too large to be stored in a 2-byte unsigned
+ ** integer, so a value of 0 is used in its place. */
+ top = get2byte(&data[hdr+5]);
+ assert( top<=(int)pPage->pBt->usableSize ); /* Prevent by getAndInitPage() */
+ if( gap>top ){
+ if( top==0 && pPage->pBt->usableSize==65536 ){
+ top = 65536;
+ }else{
+ return SQLITE_CORRUPT_BKPT;
+ }
+ }
+
+ /* If there is enough space between gap and top for one more cell pointer
+ ** array entry offset, and if the freelist is not empty, then search the
+ ** freelist looking for a free slot big enough to satisfy the request.
+ */
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;
- }
+ if( (data[hdr+2] || data[hdr+1]) && gap+2<=top ){
+ u8 *pSpace = pageFindSlot(pPage, nByte, &rc);
+ if( pSpace ){
+ assert( pSpace>=data && (pSpace - data)<65536 );
+ *pIdx = (int)(pSpace - data);
+ return SQLITE_OK;
+ }else if( rc ){
+ return rc;
}
}
- /* Check to make sure there is enough space in the gap to satisfy
- ** the allocation. If not, defragment.
+ /* The request could not be fulfilled using a freelist slot. Check
+ ** to see if defragmentation is necessary.
*/
testcase( gap+2+nByte==top );
if( gap+2+nByte>top ){
+ assert( pPage->nCell>0 || CORRUPT_DB );
rc = defragmentPage(pPage);
if( rc ) return rc;
top = get2byteNotZero(&data[hdr+5]);
@@ -49552,90 +56678,101 @@ static int allocateSpace(MemPage *pPage, int nByte, int *pIdx){
/*
** 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;
+** The first byte of the new free block is pPage->aData[iStart]
+** and the size of the block is iSize bytes.
+**
+** Adjacent freeblocks are coalesced.
+**
+** Note that even though the freeblock list was checked by btreeInitPage(),
+** that routine will not detect overlap between cells or freeblocks. Nor
+** does it detect cells or freeblocks that encrouch into the reserved bytes
+** at the end of the page. So do additional corruption checks inside this
+** routine and return SQLITE_CORRUPT if any problems are found.
+*/
+static int freeSpace(MemPage *pPage, u16 iStart, u16 iSize){
+ u16 iPtr; /* Address of ptr to next freeblock */
+ u16 iFreeBlk; /* Address of the next freeblock */
+ u8 hdr; /* Page header size. 0 or 100 */
+ u8 nFrag = 0; /* Reduction in fragmentation */
+ u16 iOrigSize = iSize; /* Original value of iSize */
+ u32 iLast = pPage->pBt->usableSize-4; /* Largest possible freeblock offset */
+ u32 iEnd = iStart + iSize; /* First byte past the iStart buffer */
+ unsigned char *data = pPage->aData; /* Page content */
assert( pPage->pBt!=0 );
assert( sqlite3PagerIswriteable(pPage->pDbPage) );
- assert( start>=pPage->hdrOffset+6+pPage->childPtrSize );
- assert( (start + size) <= (int)pPage->pBt->usableSize );
+ assert( CORRUPT_DB || iStart>=pPage->hdrOffset+6+pPage->childPtrSize );
+ assert( CORRUPT_DB || iEnd <= pPage->pBt->usableSize );
assert( sqlite3_mutex_held(pPage->pBt->mutex) );
- assert( size>=0 ); /* Minimum cell size is 4 */
+ assert( iSize>=4 ); /* Minimum cell size is 4 */
+ assert( iStart<=iLast );
+ /* Overwrite deleted information with zeros when the secure_delete
+ ** option is enabled */
if( pPage->pBt->btsFlags & BTS_SECURE_DELETE ){
- /* Overwrite deleted information with zeros when the secure_delete
- ** option is enabled */
- memset(&data[start], 0, size);
+ memset(&data[iStart], 0, iSize);
}
- /* 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.
+ /* The list of freeblocks must be in ascending order. Find the
+ ** spot on the list where iStart should be inserted.
*/
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;
+ iPtr = hdr + 1;
+ if( data[iPtr+1]==0 && data[iPtr]==0 ){
+ iFreeBlk = 0; /* Shortcut for the case when the freelist is empty */
+ }else{
+ while( (iFreeBlk = get2byte(&data[iPtr]))>0 && iFreeBlk<iStart ){
+ if( iFreeBlk<iPtr+4 ) return SQLITE_CORRUPT_BKPT;
+ iPtr = iFreeBlk;
}
- 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( iFreeBlk>iLast ) return SQLITE_CORRUPT_BKPT;
+ assert( iFreeBlk>iPtr || iFreeBlk==0 );
+
+ /* At this point:
+ ** iFreeBlk: First freeblock after iStart, or zero if none
+ ** iPtr: The address of a pointer to iFreeBlk
+ **
+ ** Check to see if iFreeBlk should be coalesced onto the end of iStart.
+ */
+ if( iFreeBlk && iEnd+3>=iFreeBlk ){
+ nFrag = iFreeBlk - iEnd;
+ if( iEnd>iFreeBlk ) return SQLITE_CORRUPT_BKPT;
+ iEnd = iFreeBlk + get2byte(&data[iFreeBlk+2]);
+ if( iEnd > pPage->pBt->usableSize ) return SQLITE_CORRUPT_BKPT;
+ iSize = iEnd - iStart;
+ iFreeBlk = get2byte(&data[iFreeBlk]);
}
- }
-
- /* 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) );
+
+ /* If iPtr is another freeblock (that is, if iPtr is not the freelist
+ ** pointer in the page header) then check to see if iStart should be
+ ** coalesced onto the end of iPtr.
+ */
+ if( iPtr>hdr+1 ){
+ int iPtrEnd = iPtr + get2byte(&data[iPtr+2]);
+ if( iPtrEnd+3>=iStart ){
+ if( iPtrEnd>iStart ) return SQLITE_CORRUPT_BKPT;
+ nFrag += iStart - iPtrEnd;
+ iSize = iEnd - iPtr;
+ iStart = iPtr;
+ }
+ }
+ if( nFrag>data[hdr+7] ) return SQLITE_CORRUPT_BKPT;
+ data[hdr+7] -= nFrag;
+ }
+ if( iStart==get2byte(&data[hdr+5]) ){
+ /* The new freeblock is at the beginning of the cell content area,
+ ** so just extend the cell content area rather than create another
+ ** freelist entry */
+ if( iPtr!=hdr+1 ) return SQLITE_CORRUPT_BKPT;
+ put2byte(&data[hdr+1], iFreeBlk);
+ put2byte(&data[hdr+5], iEnd);
+ }else{
+ /* Insert the new freeblock into the freelist */
+ put2byte(&data[iPtr], iStart);
+ put2byte(&data[iStart], iFreeBlk);
+ put2byte(&data[iStart+2], iSize);
+ }
+ pPage->nFree += iOrigSize;
return SQLITE_OK;
}
@@ -49659,18 +56796,44 @@ static int decodeFlags(MemPage *pPage, int flagByte){
pPage->leaf = (u8)(flagByte>>3); assert( PTF_LEAF == 1<<3 );
flagByte &= ~PTF_LEAF;
pPage->childPtrSize = 4-4*pPage->leaf;
+ pPage->xCellSize = cellSizePtr;
pBt = pPage->pBt;
if( flagByte==(PTF_LEAFDATA | PTF_INTKEY) ){
+ /* EVIDENCE-OF: R-03640-13415 A value of 5 means the page is an interior
+ ** table b-tree page. */
+ assert( (PTF_LEAFDATA|PTF_INTKEY)==5 );
+ /* EVIDENCE-OF: R-20501-61796 A value of 13 means the page is a leaf
+ ** table b-tree page. */
+ assert( (PTF_LEAFDATA|PTF_INTKEY|PTF_LEAF)==13 );
pPage->intKey = 1;
- pPage->hasData = pPage->leaf;
+ if( pPage->leaf ){
+ pPage->intKeyLeaf = 1;
+ pPage->noPayload = 0;
+ pPage->xParseCell = btreeParseCellPtr;
+ }else{
+ pPage->intKeyLeaf = 0;
+ pPage->noPayload = 1;
+ pPage->xCellSize = cellSizePtrNoPayload;
+ pPage->xParseCell = btreeParseCellPtrNoPayload;
+ }
pPage->maxLocal = pBt->maxLeaf;
pPage->minLocal = pBt->minLeaf;
}else if( flagByte==PTF_ZERODATA ){
+ /* EVIDENCE-OF: R-27225-53936 A value of 2 means the page is an interior
+ ** index b-tree page. */
+ assert( (PTF_ZERODATA)==2 );
+ /* EVIDENCE-OF: R-16571-11615 A value of 10 means the page is a leaf
+ ** index b-tree page. */
+ assert( (PTF_ZERODATA|PTF_LEAF)==10 );
pPage->intKey = 0;
- pPage->hasData = 0;
+ pPage->intKeyLeaf = 0;
+ pPage->noPayload = 0;
+ pPage->xParseCell = btreeParseCellPtrIndex;
pPage->maxLocal = pBt->maxLocal;
pPage->minLocal = pBt->minLocal;
}else{
+ /* EVIDENCE-OF: R-47608-56469 Any other value for the b-tree page type is
+ ** an error. */
return SQLITE_CORRUPT_BKPT;
}
pPage->max1bytePayload = pBt->max1bytePayload;
@@ -49689,6 +56852,7 @@ static int decodeFlags(MemPage *pPage, int flagByte){
static int btreeInitPage(MemPage *pPage){
assert( pPage->pBt!=0 );
+ assert( pPage->pBt->db!=0 );
assert( sqlite3_mutex_held(pPage->pBt->mutex) );
assert( pPage->pgno==sqlite3PagerPagenumber(pPage->pDbPage) );
assert( pPage == sqlite3PagerGetExtra(pPage->pDbPage) );
@@ -49710,21 +56874,34 @@ static int btreeInitPage(MemPage *pPage){
hdr = pPage->hdrOffset;
data = pPage->aData;
+ /* EVIDENCE-OF: R-28594-02890 The one-byte flag at offset 0 indicating
+ ** the b-tree page type. */
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->cellOffset = cellOffset = hdr + 8 + pPage->childPtrSize;
pPage->aDataEnd = &data[usableSize];
pPage->aCellIdx = &data[cellOffset];
+ pPage->aDataOfst = &data[pPage->childPtrSize];
+ /* EVIDENCE-OF: R-58015-48175 The two-byte integer at offset 5 designates
+ ** the start of the cell content area. A zero value for this integer is
+ ** interpreted as 65536. */
top = get2byteNotZero(&data[hdr+5]);
+ /* EVIDENCE-OF: R-37002-32774 The two-byte integer at offset 3 gives the
+ ** number of cells on the page. */
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) );
+ /* EVIDENCE-OF: R-24089-57979 If a page contains no cells (which is only
+ ** possible for a root page of a table that contains no rows) then the
+ ** offset to the cell content area will equal the page size minus the
+ ** bytes of reserved space. */
+ assert( pPage->nCell>0 || top==usableSize || CORRUPT_DB );
/* A malformed database page might cause us to read past the end
** of page when parsing a cell.
@@ -49735,20 +56912,19 @@ static int btreeInitPage(MemPage *pPage){
*/
iCellFirst = cellOffset + 2*pPage->nCell;
iCellLast = usableSize - 4;
-#if defined(SQLITE_ENABLE_OVERSIZE_CELL_CHECK)
- {
+ if( pBt->db->flags & SQLITE_CellSizeCk ){
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]);
+ pc = get2byteAligned(&data[cellOffset+i*2]);
testcase( pc==iCellFirst );
testcase( pc==iCellLast );
if( pc<iCellFirst || pc>iCellLast ){
return SQLITE_CORRUPT_BKPT;
}
- sz = cellSizePtr(pPage, &data[pc]);
+ sz = pPage->xCellSize(pPage, &data[pc]);
testcase( pc+sz==usableSize );
if( pc+sz>usableSize ){
return SQLITE_CORRUPT_BKPT;
@@ -49756,15 +56932,21 @@ static int btreeInitPage(MemPage *pPage){
}
if( !pPage->leaf ) iCellLast++;
}
-#endif
- /* Compute the total free space on the page */
+ /* Compute the total free space on the page
+ ** EVIDENCE-OF: R-23588-34450 The two-byte integer at offset 1 gives the
+ ** start of the first freeblock on the page, or is zero if there are no
+ ** freeblocks. */
pc = get2byte(&data[hdr+1]);
- nFree = data[hdr+7] + top;
+ nFree = data[hdr+7] + top; /* Init nFree to non-freeblock free space */
while( pc>0 ){
u16 next, size;
if( pc<iCellFirst || pc>iCellLast ){
- /* Start of free block is off the page */
+ /* EVIDENCE-OF: R-55530-52930 In a well-formed b-tree page, there will
+ ** always be at least one cell before the first freeblock.
+ **
+ ** Or, the freeblock is off the end of the page
+ */
return SQLITE_CORRUPT_BKPT;
}
next = get2byte(&data[pc]);
@@ -49813,16 +56995,16 @@ static void zeroPage(MemPage *pPage, int flags){
memset(&data[hdr], 0, pBt->usableSize - hdr);
}
data[hdr] = (char)flags;
- first = hdr + 8 + 4*((flags&PTF_LEAF)==0 ?1:0);
+ first = hdr + ((flags&PTF_LEAF)==0 ? 12 : 8);
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->aDataOfst = &data[pPage->childPtrSize];
pPage->nOverflow = 0;
assert( pBt->pageSize>=512 && pBt->pageSize<=65536 );
pPage->maskPage = (u16)(pBt->pageSize - 1);
@@ -49837,20 +57019,23 @@ static void zeroPage(MemPage *pPage, int flags){
*/
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;
+ if( pgno!=pPage->pgno ){
+ pPage->aData = sqlite3PagerGetData(pDbPage);
+ pPage->pDbPage = pDbPage;
+ pPage->pBt = pBt;
+ pPage->pgno = pgno;
+ pPage->hdrOffset = pgno==1 ? 100 : 0;
+ }
+ assert( pPage->aData==sqlite3PagerGetData(pDbPage) );
return pPage;
}
/*
** Get a page from the pager. Initialize the MemPage.pBt and
-** MemPage.aData elements if needed.
+** MemPage.aData elements if needed. See also: btreeGetUnusedPage().
**
-** 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
+** If the PAGER_GET_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
@@ -49860,13 +57045,14 @@ 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 flags /* PAGER_GET_NOCONTENT or PAGER_GET_READONLY */
){
int rc;
DbPage *pDbPage;
+ assert( flags==0 || flags==PAGER_GET_NOCONTENT || flags==PAGER_GET_READONLY );
assert( sqlite3_mutex_held(pBt->mutex) );
- rc = sqlite3PagerAcquire(pBt->pPager, pgno, (DbPage**)&pDbPage, noContent);
+ rc = sqlite3PagerGet(pBt->pPager, pgno, (DbPage**)&pDbPage, flags);
if( rc ) return rc;
*ppPage = btreePageFromDbPage(pDbPage, pgno, pBt);
return SQLITE_OK;
@@ -49897,37 +57083,67 @@ static Pgno btreePagecount(BtShared *pBt){
SQLITE_PRIVATE u32 sqlite3BtreeLastPage(Btree *p){
assert( sqlite3BtreeHoldsMutex(p) );
assert( ((p->pBt->nPage)&0x8000000)==0 );
- return (int)btreePagecount(p->pBt);
+ return 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().
+** Get a page from the pager and initialize it.
+**
+** If pCur!=0 then the page is being fetched as part of a moveToChild()
+** call. Do additional sanity checking on the page in this case.
+** And if the fetch fails, this routine must decrement pCur->iPage.
+**
+** The page is fetched as read-write unless pCur is not NULL and is
+** a read-only cursor.
**
-** If an error occurs, then the value *ppPage is set to is undefined. It
+** If an error occurs, then *ppPage 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 */
+ BtShared *pBt, /* The database file */
+ Pgno pgno, /* Number of the page to get */
+ MemPage **ppPage, /* Write the page pointer here */
+ BtCursor *pCur, /* Cursor to receive the page, or NULL */
+ int bReadOnly /* True for a read-only page */
){
int rc;
+ DbPage *pDbPage;
assert( sqlite3_mutex_held(pBt->mutex) );
+ assert( pCur==0 || ppPage==&pCur->apPage[pCur->iPage] );
+ assert( pCur==0 || bReadOnly==pCur->curPagerFlags );
+ assert( pCur==0 || pCur->iPage>0 );
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);
- }
+ goto getAndInitPage_error;
+ }
+ rc = sqlite3PagerGet(pBt->pPager, pgno, (DbPage**)&pDbPage, bReadOnly);
+ if( rc ){
+ goto getAndInitPage_error;
+ }
+ *ppPage = (MemPage*)sqlite3PagerGetExtra(pDbPage);
+ if( (*ppPage)->isInit==0 ){
+ btreePageFromDbPage(pDbPage, pgno, pBt);
+ rc = btreeInitPage(*ppPage);
+ if( rc!=SQLITE_OK ){
+ releasePage(*ppPage);
+ goto getAndInitPage_error;
}
}
+ assert( (*ppPage)->pgno==pgno );
+ assert( (*ppPage)->aData==sqlite3PagerGetData(pDbPage) );
+ /* If obtaining a child page for a cursor, we must verify that the page is
+ ** compatible with the root page. */
+ if( pCur && ((*ppPage)->nCell<1 || (*ppPage)->intKey!=pCur->curIntKey) ){
+ rc = SQLITE_CORRUPT_BKPT;
+ releasePage(*ppPage);
+ goto getAndInitPage_error;
+ }
+ return SQLITE_OK;
+
+getAndInitPage_error:
+ if( pCur ) pCur->iPage--;
testcase( pgno==0 );
assert( pgno!=0 || rc==SQLITE_CORRUPT );
return rc;
@@ -49937,17 +57153,49 @@ static int getAndInitPage(
** Release a MemPage. This should be called once for each prior
** call to btreeGetPage.
*/
+static void releasePageNotNull(MemPage *pPage){
+ assert( pPage->aData );
+ assert( pPage->pBt );
+ assert( pPage->pDbPage!=0 );
+ assert( sqlite3PagerGetExtra(pPage->pDbPage) == (void*)pPage );
+ assert( sqlite3PagerGetData(pPage->pDbPage)==pPage->aData );
+ assert( sqlite3_mutex_held(pPage->pBt->mutex) );
+ sqlite3PagerUnrefNotNull(pPage->pDbPage);
+}
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);
+ if( pPage ) releasePageNotNull(pPage);
+}
+
+/*
+** Get an unused page.
+**
+** This works just like btreeGetPage() with the addition:
+**
+** * If the page is already in use for some other purpose, immediately
+** release it and return an SQLITE_CURRUPT error.
+** * Make sure the isInit flag is clear
+*/
+static int btreeGetUnusedPage(
+ BtShared *pBt, /* The btree */
+ Pgno pgno, /* Number of the page to fetch */
+ MemPage **ppPage, /* Return the page in this parameter */
+ int flags /* PAGER_GET_NOCONTENT or PAGER_GET_READONLY */
+){
+ int rc = btreeGetPage(pBt, pgno, ppPage, flags);
+ if( rc==SQLITE_OK ){
+ if( sqlite3PagerPageRefcount((*ppPage)->pDbPage)>1 ){
+ releasePage(*ppPage);
+ *ppPage = 0;
+ return SQLITE_CORRUPT_BKPT;
+ }
+ (*ppPage)->isInit = 0;
+ }else{
+ *ppPage = 0;
}
+ return rc;
}
+
/*
** 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
@@ -50070,16 +57318,18 @@ SQLITE_PRIVATE int sqlite3BtreeOpen(
*/
if( isTempDb==0 && (isMemdb==0 || (vfsFlags&SQLITE_OPEN_URI)!=0) ){
if( vfsFlags & SQLITE_OPEN_SHAREDCACHE ){
+ int nFilename = sqlite3Strlen30(zFilename)+1;
int nFullPathname = pVfs->mxPathname+1;
- char *zFullPathname = sqlite3Malloc(nFullPathname);
+ char *zFullPathname = sqlite3Malloc(MAX(nFullPathname,nFilename));
MUTEX_LOGIC( sqlite3_mutex *mutexShared; )
+
p->sharable = 1;
if( !zFullPathname ){
sqlite3_free(p);
return SQLITE_NOMEM;
}
if( isMemdb ){
- memcpy(zFullPathname, zFilename, sqlite3Strlen30(zFilename)+1);
+ memcpy(zFullPathname, zFilename, nFilename);
}else{
rc = sqlite3OsFullPathname(pVfs, zFilename,
nFullPathname, zFullPathname);
@@ -50136,8 +57386,8 @@ SQLITE_PRIVATE int sqlite3BtreeOpen(
** 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(i64)==8 );
+ assert( sizeof(u64)==8 );
assert( sizeof(u32)==4 );
assert( sizeof(u16)==2 );
assert( sizeof(Pgno)==4 );
@@ -50150,6 +57400,7 @@ SQLITE_PRIVATE int sqlite3BtreeOpen(
rc = sqlite3PagerOpen(pVfs, &pBt->pPager, zFilename,
EXTRA_SIZE, flags, vfsFlags, pageReinit);
if( rc==SQLITE_OK ){
+ sqlite3PagerSetMmapLimit(pBt->pPager, db->szMmap);
rc = sqlite3PagerReadFileheader(pBt->pPager,sizeof(zDbHeader),zDbHeader);
}
if( rc!=SQLITE_OK ){
@@ -50166,6 +57417,9 @@ SQLITE_PRIVATE int sqlite3BtreeOpen(
#ifdef SQLITE_SECURE_DELETE
pBt->btsFlags |= BTS_SECURE_DELETE;
#endif
+ /* EVIDENCE-OF: R-51873-39618 The page size for a database file is
+ ** determined by the 2-byte integer located at an offset of 16 bytes from
+ ** the beginning of the database file. */
pBt->pageSize = (zDbHeader[16]<<8) | (zDbHeader[17]<<16);
if( pBt->pageSize<512 || pBt->pageSize>SQLITE_MAX_PAGE_SIZE
|| ((pBt->pageSize-1)&pBt->pageSize)!=0 ){
@@ -50184,6 +57438,9 @@ SQLITE_PRIVATE int sqlite3BtreeOpen(
#endif
nReserve = 0;
}else{
+ /* EVIDENCE-OF: R-37497-42412 The size of the reserved region is
+ ** determined by the one-byte unsigned integer found at an offset of 20
+ ** into the database file header. */
nReserve = zDbHeader[20];
pBt->btsFlags |= BTS_PAGESIZE_FIXED;
#ifndef SQLITE_OMIT_AUTOVACUUM
@@ -50318,11 +57575,32 @@ static int removeFromSharingList(BtShared *pBt){
/*
** Make sure pBt->pTmpSpace points to an allocation of
-** MX_CELL_SIZE(pBt) bytes.
+** MX_CELL_SIZE(pBt) bytes with a 4-byte prefix for a left-child
+** pointer.
*/
static void allocateTempSpace(BtShared *pBt){
if( !pBt->pTmpSpace ){
pBt->pTmpSpace = sqlite3PageMalloc( pBt->pageSize );
+
+ /* One of the uses of pBt->pTmpSpace is to format cells before
+ ** inserting them into a leaf page (function fillInCell()). If
+ ** a cell is less than 4 bytes in size, it is rounded up to 4 bytes
+ ** by the various routines that manipulate binary cells. Which
+ ** can mean that fillInCell() only initializes the first 2 or 3
+ ** bytes of pTmpSpace, but that the first 4 bytes are copied from
+ ** it into a database page. This is not actually a problem, but it
+ ** does cause a valgrind error when the 1 or 2 bytes of unitialized
+ ** data is passed to system call write(). So to avoid this error,
+ ** zero the first 4 bytes of temp space here.
+ **
+ ** Also: Provide four bytes of initialized space before the
+ ** beginning of pTmpSpace as an area available to prepend the
+ ** left-child pointer to the beginning of a cell.
+ */
+ if( pBt->pTmpSpace ){
+ memset(pBt->pTmpSpace, 0, 8);
+ pBt->pTmpSpace += 4;
+ }
}
}
@@ -50330,8 +57608,11 @@ static void allocateTempSpace(BtShared *pBt){
** Free the pBt->pTmpSpace allocation
*/
static void freeTempSpace(BtShared *pBt){
- sqlite3PageFree( pBt->pTmpSpace);
- pBt->pTmpSpace = 0;
+ if( pBt->pTmpSpace ){
+ pBt->pTmpSpace -= 4;
+ sqlite3PageFree(pBt->pTmpSpace);
+ pBt->pTmpSpace = 0;
+ }
}
/*
@@ -50357,7 +57638,7 @@ SQLITE_PRIVATE int sqlite3BtreeClose(Btree *p){
** The call to sqlite3BtreeRollback() drops any table-locks held by
** this handle.
*/
- sqlite3BtreeRollback(p, SQLITE_OK);
+ sqlite3BtreeRollback(p, SQLITE_OK, 0);
sqlite3BtreeLeave(p);
/* If there are still other outstanding references to the shared-btree
@@ -50393,19 +57674,11 @@ SQLITE_PRIVATE int sqlite3BtreeClose(Btree *p){
}
/*
-** 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.
+** Change the "soft" limit on the number of pages in the cache.
+** Unused and unmodified pages will be recycled when the number of
+** pages in the cache exceeds this soft limit. But the size of the
+** cache is allowed to grow larger than this limit if it contains
+** dirty pages or pages still in active use.
*/
SQLITE_PRIVATE int sqlite3BtreeSetCacheSize(Btree *p, int mxPage){
BtShared *pBt = p->pBt;
@@ -50417,6 +57690,41 @@ SQLITE_PRIVATE int sqlite3BtreeSetCacheSize(Btree *p, int mxPage){
}
/*
+** Change the "spill" limit on the number of pages in the cache.
+** If the number of pages exceeds this limit during a write transaction,
+** the pager might attempt to "spill" pages to the journal early in
+** order to free up memory.
+**
+** The value returned is the current spill size. If zero is passed
+** as an argument, no changes are made to the spill size setting, so
+** using mxPage of 0 is a way to query the current spill size.
+*/
+SQLITE_PRIVATE int sqlite3BtreeSetSpillSize(Btree *p, int mxPage){
+ BtShared *pBt = p->pBt;
+ int res;
+ assert( sqlite3_mutex_held(p->db->mutex) );
+ sqlite3BtreeEnter(p);
+ res = sqlite3PagerSetSpillsize(pBt->pPager, mxPage);
+ sqlite3BtreeLeave(p);
+ return res;
+}
+
+#if SQLITE_MAX_MMAP_SIZE>0
+/*
+** Change the limit on the amount of the database file that may be
+** memory mapped.
+*/
+SQLITE_PRIVATE int sqlite3BtreeSetMmapLimit(Btree *p, sqlite3_int64 szMmap){
+ BtShared *pBt = p->pBt;
+ assert( sqlite3_mutex_held(p->db->mutex) );
+ sqlite3BtreeEnter(p);
+ sqlite3PagerSetMmapLimit(pBt->pPager, szMmap);
+ sqlite3BtreeLeave(p);
+ return SQLITE_OK;
+}
+#endif /* SQLITE_MAX_MMAP_SIZE>0 */
+
+/*
** 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
@@ -50425,17 +57733,14 @@ SQLITE_PRIVATE int sqlite3BtreeSetCacheSize(Btree *p, int mxPage){
** probability of damage to near zero but with a write performance reduction.
*/
#ifndef SQLITE_OMIT_PAGER_PRAGMAS
-SQLITE_PRIVATE int sqlite3BtreeSetSafetyLevel(
+SQLITE_PRIVATE int sqlite3BtreeSetPagerFlags(
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 */
+ unsigned pgFlags /* Various PAGER_* flags */
){
BtShared *pBt = p->pBt;
assert( sqlite3_mutex_held(p->db->mutex) );
- assert( level>=1 && level<=3 );
sqlite3BtreeEnter(p);
- sqlite3PagerSetSafetyLevel(pBt->pPager, level, fullSync, ckptFullSync);
+ sqlite3PagerSetFlags(pBt->pPager, pgFlags);
sqlite3BtreeLeave(p);
return SQLITE_OK;
}
@@ -50481,6 +57786,9 @@ SQLITE_PRIVATE int sqlite3BtreeSetPageSize(Btree *p, int pageSize, int nReserve,
BtShared *pBt = p->pBt;
assert( nReserve>=-1 && nReserve<=255 );
sqlite3BtreeEnter(p);
+#if SQLITE_HAS_CODEC
+ if( nReserve>pBt->optimalReserve ) pBt->optimalReserve = (u8)nReserve;
+#endif
if( pBt->btsFlags & BTS_PAGESIZE_FIXED ){
sqlite3BtreeLeave(p);
return SQLITE_READONLY;
@@ -50492,7 +57800,7 @@ SQLITE_PRIVATE int sqlite3BtreeSetPageSize(Btree *p, int pageSize, int nReserve,
if( pageSize>=512 && pageSize<=SQLITE_MAX_PAGE_SIZE &&
((pageSize-1)&pageSize)==0 ){
assert( (pageSize & 7)==0 );
- assert( !pBt->pPage1 && !pBt->pCursor );
+ assert( !pBt->pCursor );
pBt->pageSize = (u32)pageSize;
freeTempSpace(pBt);
}
@@ -50510,7 +57818,6 @@ 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
@@ -50520,28 +57827,36 @@ SQLITE_PRIVATE int sqlite3BtreeGetPageSize(Btree *p){
** 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.
+** database handle that owns *p, causing undefined behavior.
*/
SQLITE_PRIVATE int sqlite3BtreeGetReserveNoMutex(Btree *p){
+ int n;
assert( sqlite3_mutex_held(p->pBt->mutex) );
- return p->pBt->pageSize - p->pBt->usableSize;
+ n = p->pBt->pageSize - p->pBt->usableSize;
+ return n;
}
-#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.
+**
+** If SQLITE_HAS_MUTEX is defined then the number returned is the
+** greater of the current reserved space and the maximum requested
+** reserve space.
*/
-SQLITE_PRIVATE int sqlite3BtreeGetReserve(Btree *p){
+SQLITE_PRIVATE int sqlite3BtreeGetOptimalReserve(Btree *p){
int n;
sqlite3BtreeEnter(p);
- n = p->pBt->pageSize - p->pBt->usableSize;
+ n = sqlite3BtreeGetReserveNoMutex(p);
+#ifdef SQLITE_HAS_CODEC
+ if( n<p->pBt->optimalReserve ) n = p->pBt->optimalReserve;
+#endif
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.
@@ -50572,7 +57887,6 @@ SQLITE_PRIVATE int sqlite3BtreeSecureDelete(Btree *p, int newFlag){
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'
@@ -50657,6 +57971,9 @@ static int lockBtree(BtShared *pBt){
u32 usableSize;
u8 *page1 = pPage1->aData;
rc = SQLITE_NOTADB;
+ /* EVIDENCE-OF: R-43737-39999 Every valid SQLite database file begins
+ ** with the following 16 bytes (in hex): 53 51 4c 69 74 65 20 66 6f 72 6d
+ ** 61 74 20 33 00. */
if( memcmp(page1, zMagicHeader, 16)!=0 ){
goto page1_init_failed;
}
@@ -50697,15 +58014,21 @@ static int lockBtree(BtShared *pBt){
}
#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.
+ /* EVIDENCE-OF: R-15465-20813 The maximum and minimum embedded payload
+ ** fractions and the leaf payload fraction values must be 64, 32, and 32.
+ **
** 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;
}
+ /* EVIDENCE-OF: R-51873-39618 The page size for a database file is
+ ** determined by the 2-byte integer located at an offset of 16 bytes from
+ ** the beginning of the database file. */
pageSize = (page1[16]<<8) | (page1[17]<<16);
+ /* EVIDENCE-OF: R-25008-21688 The size of a page is a power of two
+ ** between 512 and 65536 inclusive. */
if( ((pageSize-1)&pageSize)!=0
|| pageSize>SQLITE_MAX_PAGE_SIZE
|| pageSize<=256
@@ -50713,6 +58036,13 @@ static int lockBtree(BtShared *pBt){
goto page1_init_failed;
}
assert( (pageSize & 7)==0 );
+ /* EVIDENCE-OF: R-59310-51205 The "reserved space" size in the 1-byte
+ ** integer at offset 20 is the number of bytes of space at the end of
+ ** each page to reserve for extensions.
+ **
+ ** EVIDENCE-OF: R-37497-42412 The size of the reserved region is
+ ** determined by the one-byte unsigned integer found at an offset of 20
+ ** into the database file header. */
usableSize = pageSize - page1[20];
if( (u32)pageSize!=pBt->pageSize ){
/* After reading the first page of the database assuming a page size
@@ -50733,6 +58063,9 @@ static int lockBtree(BtShared *pBt){
rc = SQLITE_CORRUPT_BKPT;
goto page1_init_failed;
}
+ /* EVIDENCE-OF: R-28312-64704 However, the usable size is not allowed to
+ ** be less than 480. In other words, if the page size is 512, then the
+ ** reserved space size cannot exceed 32. */
if( usableSize<480 ){
goto page1_init_failed;
}
@@ -50777,6 +58110,30 @@ page1_init_failed:
return rc;
}
+#ifndef NDEBUG
+/*
+** Return the number of cursors open on pBt. This is for use
+** in assert() expressions, so it is only compiled if NDEBUG is not
+** defined.
+**
+** Only write cursors are counted if wrOnly is true. If wrOnly is
+** false then all cursors are counted.
+**
+** For the purposes of this routine, a cursor is any cursor that
+** is capable of reading or writing to the database. Cursors that
+** have been tripped into the CURSOR_FAULT state are not counted.
+*/
+static int countValidCursors(BtShared *pBt, int wrOnly){
+ BtCursor *pCur;
+ int r = 0;
+ for(pCur=pBt->pCursor; pCur; pCur=pCur->pNext){
+ if( (wrOnly==0 || (pCur->curFlags & BTCF_WriteFlag)!=0)
+ && pCur->eState!=CURSOR_FAULT ) r++;
+ }
+ return r;
+}
+#endif
+
/*
** 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
@@ -50787,13 +58144,13 @@ page1_init_failed:
*/
static void unlockBtreeIfUnused(BtShared *pBt){
assert( sqlite3_mutex_held(pBt->mutex) );
- assert( pBt->pCursor==0 || pBt->inTransaction>TRANS_NONE );
+ assert( countValidCursors(pBt,0)==0 || pBt->inTransaction>TRANS_NONE );
if( pBt->inTransaction==TRANS_NONE && pBt->pPage1!=0 ){
- assert( pBt->pPage1->aData );
+ MemPage *pPage1 = pBt->pPage1;
+ assert( pPage1->aData );
assert( sqlite3PagerRefcount(pBt->pPager)==1 );
- assert( pBt->pPage1->aData );
- releasePage(pBt->pPage1);
pBt->pPage1 = 0;
+ releasePageNotNull(pPage1);
}
}
@@ -50905,6 +58262,7 @@ SQLITE_PRIVATE int sqlite3BtreeBeginTrans(Btree *p, int wrflag){
if( p->inTrans==TRANS_WRITE || (p->inTrans==TRANS_READ && !wrflag) ){
goto trans_begun;
}
+ assert( pBt->inTransaction==TRANS_WRITE || IfNotOmitAV(pBt->bDoTruncate)==0 );
/* Write transactions are not possible on a read-only database */
if( (pBt->btsFlags & BTS_READ_ONLY)!=0 && wrflag ){
@@ -51097,20 +58455,22 @@ static int modifyPagePointer(MemPage *pPage, Pgno iFrom, Pgno iTo, u8 eType){
u8 isInitOrig = pPage->isInit;
int i;
int nCell;
+ int rc;
- btreeInitPage(pPage);
+ rc = btreeInitPage(pPage);
+ if( rc ) return rc;
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])
+ pPage->xParseCell(pPage, pCell, &info);
+ if( info.nLocal<info.nPayload
+ && pCell+info.nSize-1<=pPage->aData+pPage->maskPage
+ && iFrom==get4byte(pCell+info.nSize-4)
){
- put4byte(&pCell[info.iOverflow], iTo);
+ put4byte(pCell+info.nSize-4, iTo);
break;
}
}else{
@@ -51221,24 +58581,23 @@ static int relocatePage(
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.
+** 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. Or, if an error
+** occurs, return some other error code.
+**
+** More specifically, this function attempts to re-organize the database so
+** that the last page of the file currently in use is no longer in use.
**
-** 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.
+** Parameter nFin is the number of pages that this database would contain
+** were this function called until it returns SQLITE_DONE.
**
-** 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.
+** If the bCommit parameter is non-zero, this function assumes that the
+** caller will keep calling incrVacuumStep() until it returns SQLITE_DONE
+** or an error. bCommit is passed true for an auto-vacuum-on-commit
+** operation, or false for an incremental vacuum.
*/
-static int incrVacuumStep(BtShared *pBt, Pgno nFin, Pgno iLastPg){
+static int incrVacuumStep(BtShared *pBt, Pgno nFin, Pgno iLastPg, int bCommit){
Pgno nFreeList; /* Number of pages still on the free-list */
int rc;
@@ -51263,15 +58622,15 @@ static int incrVacuumStep(BtShared *pBt, Pgno nFin, Pgno iLastPg){
}
if( eType==PTRMAP_FREEPAGE ){
- if( nFin==0 ){
+ if( bCommit==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
+ ** if bCommit 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);
+ rc = allocateBtreePage(pBt, &pFreePg, &iFreePg, iLastPg, BTALLOC_EXACT);
if( rc!=SQLITE_OK ){
return rc;
}
@@ -51281,34 +58640,37 @@ static int incrVacuumStep(BtShared *pBt, Pgno nFin, Pgno iLastPg){
} else {
Pgno iFreePg; /* Index of free page to move pLastPg to */
MemPage *pLastPg;
+ u8 eMode = BTALLOC_ANY; /* Mode parameter for allocateBtreePage() */
+ Pgno iNear = 0; /* nearby parameter for allocateBtreePage() */
rc = btreeGetPage(pBt, iLastPg, &pLastPg, 0);
if( rc!=SQLITE_OK ){
return rc;
}
- /* If nFin is zero, this loop runs exactly once and page pLastPg
+ /* If bCommit 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
+ ** On the other hand, if bCommit is greater than zero, then keep
** looping until a free-page located within the first nFin pages
** of the file is found.
*/
+ if( bCommit==0 ){
+ eMode = BTALLOC_LE;
+ iNear = nFin;
+ }
do {
MemPage *pFreePg;
- rc = allocateBtreePage(pBt, &pFreePg, &iFreePg, 0, 0);
+ rc = allocateBtreePage(pBt, &pFreePg, &iFreePg, iNear, eMode);
if( rc!=SQLITE_OK ){
releasePage(pLastPg);
return rc;
}
releasePage(pFreePg);
- }while( nFin!=0 && iFreePg>nFin );
+ }while( bCommit && iFreePg>nFin );
assert( iFreePg<iLastPg );
- rc = sqlite3PagerWrite(pLastPg->pDbPage);
- if( rc==SQLITE_OK ){
- rc = relocatePage(pBt, pLastPg, eType, iPtrPage, iFreePg, nFin!=0);
- }
+ rc = relocatePage(pBt, pLastPg, eType, iPtrPage, iFreePg, bCommit);
releasePage(pLastPg);
if( rc!=SQLITE_OK ){
return rc;
@@ -51316,30 +58678,40 @@ static int incrVacuumStep(BtShared *pBt, Pgno nFin, Pgno iLastPg){
}
}
- 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;
- }
- }
+ if( bCommit==0 ){
+ do {
iLastPg--;
- }
- sqlite3PagerTruncateImage(pBt->pPager, iLastPg);
+ }while( iLastPg==PENDING_BYTE_PAGE(pBt) || PTRMAP_ISPAGE(pBt, iLastPg) );
+ pBt->bDoTruncate = 1;
pBt->nPage = iLastPg;
}
return SQLITE_OK;
}
/*
+** The database opened by the first argument is an auto-vacuum database
+** nOrig pages in size containing nFree free pages. Return the expected
+** size of the database in pages following an auto-vacuum operation.
+*/
+static Pgno finalDbSize(BtShared *pBt, Pgno nOrig, Pgno nFree){
+ int nEntry; /* Number of entries on one ptrmap page */
+ Pgno nPtrmap; /* Number of PtrMap pages to be freed */
+ Pgno nFin; /* Return value */
+
+ 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--;
+ }
+
+ return nFin;
+}
+
+/*
** A write-transaction must be opened before calling this function.
** It performs a single unit of work towards an incremental vacuum.
**
@@ -51356,11 +58728,24 @@ SQLITE_PRIVATE int sqlite3BtreeIncrVacuum(Btree *p){
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);
+ Pgno nOrig = btreePagecount(pBt);
+ Pgno nFree = get4byte(&pBt->pPage1->aData[36]);
+ Pgno nFin = finalDbSize(pBt, nOrig, nFree);
+
+ if( nOrig<nFin ){
+ rc = SQLITE_CORRUPT_BKPT;
+ }else if( nFree>0 ){
+ rc = saveAllCursors(pBt, 0, 0);
+ if( rc==SQLITE_OK ){
+ invalidateAllOverflowCache(pBt);
+ rc = incrVacuumStep(pBt, nFin, nOrig, 0);
+ }
+ if( rc==SQLITE_OK ){
+ rc = sqlite3PagerWrite(pBt->pPage1->pDbPage);
+ put4byte(&pBt->pPage1->aData[28], pBt->nPage);
+ }
+ }else{
+ rc = SQLITE_DONE;
}
}
sqlite3BtreeLeave(p);
@@ -51369,7 +58754,7 @@ SQLITE_PRIVATE int sqlite3BtreeIncrVacuum(Btree *p){
/*
** This routine is called prior to sqlite3PagerCommit when a transaction
-** is commited for an auto-vacuum database.
+** is committed 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.
@@ -51379,7 +58764,7 @@ SQLITE_PRIVATE int sqlite3BtreeIncrVacuum(Btree *p){
static int autoVacuumCommit(BtShared *pBt){
int rc = SQLITE_OK;
Pager *pPager = pBt->pPager;
- VVA_ONLY( int nRef = sqlite3PagerRefcount(pPager) );
+ VVA_ONLY( int nRef = sqlite3PagerRefcount(pPager); )
assert( sqlite3_mutex_held(pBt->mutex) );
invalidateAllOverflowCache(pBt);
@@ -51387,9 +58772,7 @@ static int autoVacuumCommit(BtShared *pBt){
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);
@@ -51402,26 +58785,20 @@ static int autoVacuumCommit(BtShared *pBt){
}
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--;
- }
+ nFin = finalDbSize(pBt, nOrig, nFree);
if( nFin>nOrig ) return SQLITE_CORRUPT_BKPT;
-
+ if( nFin<nOrig ){
+ rc = saveAllCursors(pBt, 0, 0);
+ }
for(iFree=nOrig; iFree>nFin && rc==SQLITE_OK; iFree--){
- rc = incrVacuumStep(pBt, nFin, iFree);
+ rc = incrVacuumStep(pBt, nFin, iFree, 1);
}
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->bDoTruncate = 1;
pBt->nPage = nFin;
}
if( rc!=SQLITE_OK ){
@@ -51429,7 +58806,7 @@ static int autoVacuumCommit(BtShared *pBt){
}
}
- assert( nRef==sqlite3PagerRefcount(pPager) );
+ assert( nRef>=sqlite3PagerRefcount(pPager) );
return rc;
}
@@ -51476,6 +58853,9 @@ SQLITE_PRIVATE int sqlite3BtreeCommitPhaseOne(Btree *p, const char *zMaster){
return rc;
}
}
+ if( pBt->bDoTruncate ){
+ sqlite3PagerTruncateImage(pBt->pPager, pBt->nPage);
+ }
#endif
rc = sqlite3PagerCommitPhaseOne(pBt->pPager, zMaster, 0);
sqlite3BtreeLeave(p);
@@ -51489,10 +58869,13 @@ SQLITE_PRIVATE int sqlite3BtreeCommitPhaseOne(Btree *p, const char *zMaster){
*/
static void btreeEndTransaction(Btree *p){
BtShared *pBt = p->pBt;
+ sqlite3 *db = p->db;
assert( sqlite3BtreeHoldsMutex(p) );
- btreeClearHasContent(pBt);
- if( p->inTrans>TRANS_NONE && p->db->activeVdbeCnt>1 ){
+#ifndef SQLITE_OMIT_AUTOVACUUM
+ pBt->bDoTruncate = 0;
+#endif
+ if( p->inTrans>TRANS_NONE && db->nVdbeRead>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. */
@@ -51565,7 +58948,9 @@ SQLITE_PRIVATE int sqlite3BtreeCommitPhaseTwo(Btree *p, int bCleanup){
sqlite3BtreeLeave(p);
return rc;
}
+ p->iDataVersion--; /* Compensate for pPager->iDataVersion++; */
pBt->inTransaction = TRANS_READ;
+ btreeClearHasContent(pBt);
}
btreeEndTransaction(p);
@@ -51587,83 +58972,93 @@ SQLITE_PRIVATE int sqlite3BtreeCommit(Btree *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){
+** code to errCode for every cursor on any BtShared that pBtree
+** references. Or if the writeOnly flag is set to 1, then only
+** trip write cursors and leave read cursors unchanged.
+**
+** Every cursor is a candidate to be 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. If the writeOnly
+** flag is true, then only write-cursors need be tripped - read-only
+** cursors save their current positions so that they may continue
+** following the rollback. Or, if writeOnly is false, all cursors are
+** tripped. In general, writeOnly is false if the transaction being
+** rolled back modified the database schema. In this case b-tree root
+** pages may be moved or deleted from the database altogether, making
+** it unsafe for read cursors to continue.
+**
+** If the writeOnly flag is true and an error is encountered while
+** saving the current position of a read-only cursor, all cursors,
+** including all read-cursors are tripped.
+**
+** SQLITE_OK is returned if successful, or if an error occurs while
+** saving a cursor position, an SQLite error code.
+*/
+SQLITE_PRIVATE int sqlite3BtreeTripAllCursors(Btree *pBtree, int errCode, int writeOnly){
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;
+ int rc = SQLITE_OK;
+
+ assert( (writeOnly==0 || writeOnly==1) && BTCF_WriteFlag==1 );
+ if( pBtree ){
+ sqlite3BtreeEnter(pBtree);
+ for(p=pBtree->pBt->pCursor; p; p=p->pNext){
+ int i;
+ if( writeOnly && (p->curFlags & BTCF_WriteFlag)==0 ){
+ if( p->eState==CURSOR_VALID || p->eState==CURSOR_SKIPNEXT ){
+ rc = saveCursorPosition(p);
+ if( rc!=SQLITE_OK ){
+ (void)sqlite3BtreeTripAllCursors(pBtree, rc, 0);
+ break;
+ }
+ }
+ }else{
+ 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);
}
- sqlite3BtreeLeave(pBtree);
+ return rc;
}
/*
-** 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.
+** Rollback the transaction in progress.
+**
+** If tripCode is not SQLITE_OK then cursors will be invalidated (tripped).
+** Only write cursors are tripped if writeOnly is true but all cursors are
+** tripped if writeOnly is false. Any attempt to use
+** a tripped cursor 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){
+SQLITE_PRIVATE int sqlite3BtreeRollback(Btree *p, int tripCode, int writeOnly){
int rc;
BtShared *pBt = p->pBt;
MemPage *pPage1;
+ assert( writeOnly==1 || writeOnly==0 );
+ assert( tripCode==SQLITE_ABORT_ROLLBACK || tripCode==SQLITE_OK );
sqlite3BtreeEnter(p);
if( tripCode==SQLITE_OK ){
rc = tripCode = saveAllCursors(pBt, 0, 0);
+ if( rc ) writeOnly = 0;
}else{
rc = SQLITE_OK;
}
if( tripCode ){
- sqlite3BtreeTripAllCursors(p, tripCode);
+ int rc2 = sqlite3BtreeTripAllCursors(p, tripCode, writeOnly);
+ assert( rc==SQLITE_OK || (writeOnly==0 && rc2==SQLITE_OK) );
+ if( rc2!=SQLITE_OK ) rc = rc2;
}
btreeIntegrity(p);
@@ -51687,8 +59082,9 @@ SQLITE_PRIVATE int sqlite3BtreeRollback(Btree *p, int tripCode){
pBt->nPage = nPage;
releasePage(pPage1);
}
- assert( countWriteCursors(pBt)==0 );
+ assert( countValidCursors(pBt, 1)==0 );
pBt->inTransaction = TRANS_READ;
+ btreeClearHasContent(pBt);
}
btreeEndTransaction(p);
@@ -51697,7 +59093,7 @@ SQLITE_PRIVATE int sqlite3BtreeRollback(Btree *p, int tripCode){
}
/*
-** Start a statement subtransaction. The subtransaction can can be rolled
+** Start a statement subtransaction. The subtransaction 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.
@@ -51810,24 +59206,30 @@ static int btreeCursor(
BtCursor *pCur /* Space for new cursor */
){
BtShared *pBt = p->pBt; /* Shared b-tree handle */
+ BtCursor *pX; /* Looping over other all cursors */
assert( sqlite3BtreeHoldsMutex(p) );
- assert( wrFlag==0 || wrFlag==1 );
+ assert( wrFlag==0
+ || wrFlag==BTREE_WRCSR
+ || wrFlag==(BTREE_WRCSR|BTREE_FORDELETE)
+ );
/* 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( hasSharedCacheTableLock(p, iTable, pKeyInfo!=0, (wrFlag?2: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 );
+ assert( wrFlag==0 || (pBt->btsFlags & BTS_READ_ONLY)==0 );
- if( NEVER(wrFlag && (pBt->btsFlags & BTS_READ_ONLY)!=0) ){
- return SQLITE_READONLY;
+ if( wrFlag ){
+ allocateTempSpace(pBt);
+ if( pBt->pTmpSpace==0 ) return SQLITE_NOMEM;
}
if( iTable==1 && btreePagecount(pBt)==0 ){
assert( wrFlag==0 );
@@ -51841,14 +59243,19 @@ static int btreeCursor(
pCur->pKeyInfo = pKeyInfo;
pCur->pBtree = p;
pCur->pBt = pBt;
- pCur->wrFlag = (u8)wrFlag;
- pCur->pNext = pBt->pCursor;
- if( pCur->pNext ){
- pCur->pNext->pPrev = pCur;
+ pCur->curFlags = wrFlag ? BTCF_WriteFlag : 0;
+ pCur->curPagerFlags = wrFlag ? 0 : PAGER_GET_READONLY;
+ /* If there are two or more cursors on the same btree, then all such
+ ** cursors *must* have the BTCF_Multiple flag set. */
+ for(pX=pBt->pCursor; pX; pX=pX->pNext){
+ if( pX->pgnoRoot==(Pgno)iTable ){
+ pX->curFlags |= BTCF_Multiple;
+ pCur->curFlags |= BTCF_Multiple;
+ }
}
+ pCur->pNext = pBt->pCursor;
pBt->pCursor = pCur;
pCur->eState = CURSOR_INVALID;
- pCur->cachedRowid = 0;
return SQLITE_OK;
}
SQLITE_PRIVATE int sqlite3BtreeCursor(
@@ -51859,9 +59266,13 @@ SQLITE_PRIVATE int sqlite3BtreeCursor(
BtCursor *pCur /* Write new cursor here */
){
int rc;
- sqlite3BtreeEnter(p);
- rc = btreeCursor(p, iTable, wrFlag, pKeyInfo, pCur);
- sqlite3BtreeLeave(p);
+ if( iTable<1 ){
+ rc = SQLITE_CORRUPT_BKPT;
+ }else{
+ sqlite3BtreeEnter(p);
+ rc = btreeCursor(p, iTable, wrFlag, pKeyInfo, pCur);
+ sqlite3BtreeLeave(p);
+ }
return rc;
}
@@ -51890,36 +59301,6 @@ SQLITE_PRIVATE void sqlite3BtreeCursorZero(BtCursor *p){
}
/*
-** 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.
*/
@@ -51930,19 +59311,24 @@ SQLITE_PRIVATE int sqlite3BtreeCloseCursor(BtCursor *pCur){
BtShared *pBt = pCur->pBt;
sqlite3BtreeEnter(pBtree);
sqlite3BtreeClearCursor(pCur);
- if( pCur->pPrev ){
- pCur->pPrev->pNext = pCur->pNext;
- }else{
+ assert( pBt->pCursor!=0 );
+ if( pBt->pCursor==pCur ){
pBt->pCursor = pCur->pNext;
- }
- if( pCur->pNext ){
- pCur->pNext->pPrev = pCur->pPrev;
+ }else{
+ BtCursor *pPrev = pBt->pCursor;
+ do{
+ if( pPrev->pNext==pCur ){
+ pPrev->pNext = pCur->pNext;
+ break;
+ }
+ pPrev = pPrev->pNext;
+ }while( ALWAYS(pPrev) );
}
for(i=0; i<=pCur->iPage; i++){
releasePage(pCur->apPage[i]);
}
unlockBtreeIfUnused(pBt);
- invalidateOverflowCache(pCur);
+ sqlite3_free(pCur->aOverflow);
/* sqlite3_free(pCur); */
sqlite3BtreeLeave(pBtree);
}
@@ -51956,13 +59342,6 @@ SQLITE_PRIVATE int sqlite3BtreeCloseCursor(BtCursor *pCur){
**
** 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){
@@ -51970,33 +59349,20 @@ SQLITE_PRIVATE int sqlite3BtreeCloseCursor(BtCursor *pCur){
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 );
+ assert( CORRUPT_DB || 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); \
+static SQLITE_NOINLINE void getCellInfo(BtCursor *pCur){
+ if( pCur->info.nSize==0 ){
+ int iPage = pCur->iPage;
+ pCur->curFlags |= BTCF_ValidNKey;
+ btreeParseCell(pCur->apPage[iPage],pCur->aiIdx[iPage],&pCur->info);
+ }else{
+ assertCellInfo(pCur);
}
-#endif /* _MSC_VER */
+}
#ifndef NDEBUG /* The next routine used only within assert() statements */
/*
@@ -52023,13 +59389,9 @@ SQLITE_PRIVATE int sqlite3BtreeCursorIsValid(BtCursor *pCur){
*/
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;
- }
+ assert( pCur->eState==CURSOR_VALID );
+ getCellInfo(pCur);
+ *pSize = pCur->info.nKey;
return SQLITE_OK;
}
@@ -52048,8 +59410,11 @@ SQLITE_PRIVATE int sqlite3BtreeKeySize(BtCursor *pCur, i64 *pSize){
SQLITE_PRIVATE int sqlite3BtreeDataSize(BtCursor *pCur, u32 *pSize){
assert( cursorHoldsMutex(pCur) );
assert( pCur->eState==CURSOR_VALID );
+ assert( pCur->iPage>=0 );
+ assert( pCur->iPage<BTCURSOR_MAX_DEPTH );
+ assert( pCur->apPage[pCur->iPage]->intKeyLeaf==1 );
getCellInfo(pCur);
- *pSize = pCur->info.nData;
+ *pSize = pCur->info.nPayload;
return SQLITE_OK;
}
@@ -52113,7 +59478,7 @@ static int getOverflowPage(
assert( next==0 || rc==SQLITE_DONE );
if( rc==SQLITE_OK ){
- rc = btreeGetPage(pBt, ovfl, &pPage, 0);
+ rc = btreeGetPage(pBt, ovfl, &pPage, (ppPage==0) ? PAGER_GET_READONLY : 0);
assert( rc==SQLITE_OK || pPage==0 );
if( rc==SQLITE_OK ){
next = get4byte(pPage->aData);
@@ -52163,10 +59528,12 @@ static int copyPayload(
/*
** 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).
+** for the entry that the pCur cursor is pointing to. The eOp
+** argument is interpreted as follows:
+**
+** 0: The operation is a read. Populate the overflow cache.
+** 1: The operation is a write. Populate the overflow cache.
+** 2: The operation is a read. Do not populate the overflow cache.
**
** A total of "amt" bytes are read or written beginning at "offset".
** Data is read to or from the buffer pBuf.
@@ -52174,11 +59541,11 @@ static int copyPayload(
** 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.
+** If the current cursor entry uses one or more overflow pages and the
+** eOp argument is not 2, this function may allocate space for and lazily
+** populates 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
@@ -52198,23 +59565,28 @@ static int accessPayload(
){
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 */
+#ifdef SQLITE_DIRECT_OVERFLOW_READ
+ unsigned char * const pBufStart = pBuf;
+ int bEnd; /* True if reading to end of data */
+#endif
assert( pPage );
assert( pCur->eState==CURSOR_VALID );
assert( pCur->aiIdx[pCur->iPage]<pPage->nCell );
assert( cursorHoldsMutex(pCur) );
+ assert( eOp!=2 || offset==0 ); /* Always start from beginning for eOp==2 */
getCellInfo(pCur);
- aPayload = pCur->info.pCell + pCur->info.nHeader;
- nKey = (pPage->intKey ? 0 : (int)pCur->info.nKey);
+ aPayload = pCur->info.pPayload;
+#ifdef SQLITE_DIRECT_OVERFLOW_READ
+ bEnd = offset+amt==pCur->info.nPayload;
+#endif
+ assert( offset+amt <= pCur->info.nPayload );
- if( NEVER(offset+amt > nKey+pCur->info.nData)
- || &aPayload[pCur->info.nLocal] > &pPage->aData[pBt->usableSize]
- ){
+ if( &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;
}
@@ -52225,7 +59597,7 @@ static int accessPayload(
if( a+offset>pCur->info.nLocal ){
a = pCur->info.nLocal - offset;
}
- rc = copyPayload(&aPayload[offset], pBuf, a, eOp, pPage->pDbPage);
+ rc = copyPayload(&aPayload[offset], pBuf, a, (eOp & 0x01), pPage->pDbPage);
offset = 0;
pBuf += a;
amt -= a;
@@ -52233,27 +59605,37 @@ static int accessPayload(
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 the BtCursor.aOverflow[] has not been allocated, allocate it now.
+ ** Except, do not allocate aOverflow[] for eOp==2.
+ **
+ ** The aOverflow[] 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 ){
+ if( eOp!=2 && (pCur->curFlags & BTCF_ValidOvfl)==0 ){
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( nOvfl>pCur->nOvflAlloc ){
+ Pgno *aNew = (Pgno*)sqlite3Realloc(
+ pCur->aOverflow, nOvfl*2*sizeof(Pgno)
+ );
+ if( aNew==0 ){
+ rc = SQLITE_NOMEM;
+ }else{
+ pCur->nOvflAlloc = nOvfl*2;
+ pCur->aOverflow = aNew;
+ }
+ }
+ if( rc==SQLITE_OK ){
+ memset(pCur->aOverflow, 0, nOvfl*sizeof(Pgno));
+ pCur->curFlags |= BTCF_ValidOvfl;
}
}
@@ -52261,22 +59643,23 @@ static int accessPayload(
** entry for the first required overflow page is valid, skip
** directly to it.
*/
- if( pCur->aOverflow && pCur->aOverflow[offset/ovflSize] ){
+ if( (pCur->curFlags & BTCF_ValidOvfl)!=0
+ && 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);
+ if( (pCur->curFlags & BTCF_ValidOvfl)!=0 ){
+ assert( pCur->aOverflow[iIdx]==0
+ || pCur->aOverflow[iIdx]==nextPage
+ || CORRUPT_DB );
pCur->aOverflow[iIdx] = nextPage;
}
-#endif
if( offset>=ovflSize ){
/* The only reason to read this page is to obtain the page
@@ -52284,13 +59667,18 @@ static int accessPayload(
** data is not required. So first try to lookup the overflow
** page-list cache, if any, then fall back to the getOverflowPage()
** function.
+ **
+ ** Note that the aOverflow[] array must be allocated because eOp!=2
+ ** here. If eOp==2, then offset==0 and this branch is never taken.
*/
-#ifndef SQLITE_OMIT_INCRBLOB
- if( pCur->aOverflow && pCur->aOverflow[iIdx+1] ){
+ assert( eOp!=2 );
+ assert( pCur->curFlags & BTCF_ValidOvfl );
+ assert( pCur->pBtree->db==pBt->db );
+ if( pCur->aOverflow[iIdx+1] ){
nextPage = pCur->aOverflow[iIdx+1];
- } else
-#endif
+ }else{
rc = getOverflowPage(pBt, nextPage, 0, &nextPage);
+ }
offset -= ovflSize;
}else{
/* Need to read this page properly. It contains some of the
@@ -52312,19 +59700,24 @@ static int accessPayload(
** 3) the database is file-backed, and
** 4) there is no open write-transaction, and
** 5) the database is not a WAL database,
+ ** 6) all data from the page is being read.
+ ** 7) at least 4 bytes have already been read into the output buffer
**
** 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) */
+ if( (eOp&0x01)==0 /* (1) */
&& offset==0 /* (2) */
+ && (bEnd || a==ovflSize) /* (6) */
&& pBt->inTransaction==TRANS_READ /* (4) */
&& (fd = sqlite3PagerFile(pBt->pPager))->pMethods /* (3) */
&& pBt->pPage1->aData[19]==0x01 /* (5) */
+ && &pBuf[-4]>=pBufStart /* (7) */
){
u8 aSave[4];
u8 *aWrite = &pBuf[-4];
+ assert( aWrite>=pBufStart ); /* hence (7) */
memcpy(aSave, aWrite, 4);
rc = sqlite3OsRead(fd, aWrite, a+4, (i64)pBt->pageSize*(nextPage-1));
nextPage = get4byte(aWrite);
@@ -52334,11 +59727,13 @@ static int accessPayload(
{
DbPage *pDbPage;
- rc = sqlite3PagerGet(pBt->pPager, nextPage, &pDbPage);
+ rc = sqlite3PagerGet(pBt->pPager, nextPage, &pDbPage,
+ ((eOp&0x01)==0 ? PAGER_GET_READONLY : 0)
+ );
if( rc==SQLITE_OK ){
aPayload = sqlite3PagerGetData(pDbPage);
nextPage = get4byte(aPayload);
- rc = copyPayload(&aPayload[offset+4], pBuf, a, eOp, pDbPage);
+ rc = copyPayload(&aPayload[offset+4], pBuf, a, (eOp&0x01), pDbPage);
sqlite3PagerUnref(pDbPage);
offset = 0;
}
@@ -52357,7 +59752,7 @@ static int accessPayload(
/*
** Read part of the key associated with cursor pCur. Exactly
-** "amt" bytes will be transfered into pBuf[]. The transfer
+** "amt" bytes will be transferred into pBuf[]. The transfer
** begins at "offset".
**
** The caller must ensure that pCur is pointing to a valid row
@@ -52407,10 +59802,10 @@ SQLITE_PRIVATE int sqlite3BtreeData(BtCursor *pCur, u32 offset, u32 amt, void *p
/*
** 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.
+** the key if index btrees (pPage->intKey==0) and is the data for
+** table btrees (pPage->intKey==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
@@ -52423,41 +59818,23 @@ SQLITE_PRIVATE int sqlite3BtreeData(BtCursor *pCur, u32 offset, u32 amt, void *p
** page of the database. The data might change or move the next time
** any btree routine is called.
*/
-static const unsigned char *fetchPayload(
+static const void *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 */
+ u32 *pAmt /* Write the number of available bytes here */
){
- unsigned char *aPayload;
- MemPage *pPage;
- u32 nKey;
- u32 nLocal;
-
+ u32 amt;
assert( pCur!=0 && pCur->iPage>=0 && pCur->apPage[pCur->iPage]);
assert( pCur->eState==CURSOR_VALID );
+ assert( sqlite3_mutex_held(pCur->pBtree->db->mutex) );
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;
+ assert( pCur->aiIdx[pCur->iPage]<pCur->apPage[pCur->iPage]->nCell );
+ assert( pCur->info.nSize>0 );
+ assert( pCur->info.pPayload>pCur->apPage[pCur->iPage]->aData || CORRUPT_DB );
+ assert( pCur->info.pPayload<pCur->apPage[pCur->iPage]->aDataEnd ||CORRUPT_DB);
+ amt = (int)(pCur->apPage[pCur->iPage]->aDataEnd - pCur->info.pPayload);
+ if( pCur->info.nLocal<amt ) amt = pCur->info.nLocal;
+ *pAmt = amt;
+ return (void*)pCur->info.pPayload;
}
@@ -52475,23 +59852,11 @@ static const unsigned char *fetchPayload(
** 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 *sqlite3BtreeKeyFetch(BtCursor *pCur, u32 *pAmt){
+ return fetchPayload(pCur, pAmt);
}
-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;
+SQLITE_PRIVATE const void *sqlite3BtreeDataFetch(BtCursor *pCur, u32 *pAmt){
+ return fetchPayload(pCur, pAmt);
}
@@ -52505,32 +59870,24 @@ SQLITE_PRIVATE const void *sqlite3BtreeDataFetch(BtCursor *pCur, int *pAmt){
** 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 );
+ assert( pCur->iPage>=0 );
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;
+ pCur->curFlags &= ~(BTCF_ValidNKey|BTCF_ValidOvfl);
+ pCur->iPage++;
+ pCur->aiIdx[pCur->iPage] = 0;
+ return getAndInitPage(pBt, newPgno, &pCur->apPage[pCur->iPage],
+ pCur, pCur->curPagerFlags);
}
-#if 0
+#if SQLITE_DEBUG
/*
** Page pParent is an internal (non-leaf) tree page. This function
** asserts that page number iChild is the left-child if the iIdx'th
@@ -52539,6 +59896,8 @@ static int moveToChild(BtCursor *pCur, u32 newPgno){
** the page.
*/
static void assertParentIndex(MemPage *pParent, int iIdx, Pgno iChild){
+ if( CORRUPT_DB ) return; /* The conditions tested below might not be true
+ ** in a corrupt database */
assert( iIdx<=pParent->nCell );
if( iIdx==pParent->nCell ){
assert( get4byte(&pParent->aData[pParent->hdrOffset+8])==iChild );
@@ -52563,25 +59922,15 @@ static void moveToParent(BtCursor *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;
+ pCur->curFlags &= ~(BTCF_ValidNKey|BTCF_ValidOvfl);
+ releasePageNotNull(pCur->apPage[pCur->iPage--]);
}
/*
@@ -52608,8 +59957,6 @@ static void moveToParent(BtCursor *pCur){
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 );
@@ -52624,55 +59971,56 @@ static int moveToRoot(BtCursor *pCur){
}
if( pCur->iPage>=0 ){
- int i;
- for(i=1; i<=pCur->iPage; i++){
- releasePage(pCur->apPage[i]);
+ while( pCur->iPage ){
+ assert( pCur->apPage[pCur->iPage]!=0 );
+ releasePageNotNull(pCur->apPage[pCur->iPage--]);
}
- pCur->iPage = 0;
}else if( pCur->pgnoRoot==0 ){
pCur->eState = CURSOR_INVALID;
return SQLITE_OK;
}else{
- rc = getAndInitPage(pBt, pCur->pgnoRoot, &pCur->apPage[0]);
+ assert( pCur->iPage==(-1) );
+ rc = getAndInitPage(pCur->pBtree->pBt, pCur->pgnoRoot, &pCur->apPage[0],
+ 0, pCur->curPagerFlags);
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;
- }
+ pCur->curIntKey = pCur->apPage[0]->intKey;
}
-
- /* 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 );
+
+ /* 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.
+ **
+ ** Earlier versions of SQLite assumed that this test could not fail
+ ** if the root page was already loaded when this function was called (i.e.
+ ** if pCur->iPage>=0). But this is not so if the database is corrupted
+ ** in such a way that page pRoot is linked into a second b-tree table
+ ** (or the freelist). */
+ assert( pRoot->intKey==1 || pRoot->intKey==0 );
+ if( pRoot->isInit==0 || (pCur->pKeyInfo==0)!=pRoot->intKey ){
+ return SQLITE_CORRUPT_BKPT;
+ }
pCur->aiIdx[0] = 0;
pCur->info.nSize = 0;
- pCur->atLast = 0;
- pCur->validNKey = 0;
+ pCur->curFlags &= ~(BTCF_AtLast|BTCF_ValidNKey|BTCF_ValidOvfl);
- if( pRoot->nCell==0 && !pRoot->leaf ){
+ if( pRoot->nCell>0 ){
+ pCur->eState = CURSOR_VALID;
+ }else if( !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);
+ pCur->eState = CURSOR_INVALID;
}
return rc;
}
@@ -52716,17 +60064,16 @@ static int moveToRightmost(BtCursor *pCur){
assert( cursorHoldsMutex(pCur) );
assert( pCur->eState==CURSOR_VALID );
- while( rc==SQLITE_OK && !(pPage = pCur->apPage[pCur->iPage])->leaf ){
+ while( !(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 ) return rc;
}
- if( rc==SQLITE_OK ){
- pCur->aiIdx[pCur->iPage] = pPage->nCell-1;
- pCur->info.nSize = 0;
- pCur->validNKey = 0;
- }
- return rc;
+ pCur->aiIdx[pCur->iPage] = pPage->nCell-1;
+ assert( pCur->info.nSize==0 );
+ assert( (pCur->curFlags & BTCF_ValidNKey)==0 );
+ return SQLITE_OK;
}
/* Move the cursor to the first entry in the table. Return SQLITE_OK
@@ -52763,7 +60110,7 @@ SQLITE_PRIVATE int sqlite3BtreeLast(BtCursor *pCur, int *pRes){
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 ){
+ if( CURSOR_VALID==pCur->eState && (pCur->curFlags & BTCF_AtLast)!=0 ){
#ifdef SQLITE_DEBUG
/* This block serves to assert() that the cursor really does point
** to the last entry in the b-tree. */
@@ -52786,7 +60133,12 @@ SQLITE_PRIVATE int sqlite3BtreeLast(BtCursor *pCur, int *pRes){
assert( pCur->eState==CURSOR_VALID );
*pRes = 0;
rc = moveToRightmost(pCur);
- pCur->atLast = rc==SQLITE_OK ?1:0;
+ if( rc==SQLITE_OK ){
+ pCur->curFlags |= BTCF_AtLast;
+ }else{
+ pCur->curFlags &= ~BTCF_AtLast;
+ }
+
}
}
return rc;
@@ -52819,6 +60171,8 @@ SQLITE_PRIVATE int sqlite3BtreeLast(BtCursor *pCur, int *pRes){
** *pRes>0 The cursor is left pointing at an entry that
** is larger than intKey/pIdxKey.
**
+** For index tables, the pIdxKey->eqSeen field is set to 1 if there
+** exists an entry in the table that exactly matches pIdxKey.
*/
SQLITE_PRIVATE int sqlite3BtreeMovetoUnpacked(
BtCursor *pCur, /* The cursor to be moved */
@@ -52828,6 +60182,7 @@ SQLITE_PRIVATE int sqlite3BtreeMovetoUnpacked(
int *pRes /* Write search results here */
){
int rc;
+ RecordCompare xRecordCompare;
assert( cursorHoldsMutex(pCur) );
assert( sqlite3_mutex_held(pCur->pBtree->db->mutex) );
@@ -52836,19 +60191,30 @@ SQLITE_PRIVATE int sqlite3BtreeMovetoUnpacked(
/* 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->eState==CURSOR_VALID && (pCur->curFlags & BTCF_ValidNKey)!=0
+ && pCur->curIntKey
){
if( pCur->info.nKey==intKey ){
*pRes = 0;
return SQLITE_OK;
}
- if( pCur->atLast && pCur->info.nKey<intKey ){
+ if( (pCur->curFlags & BTCF_AtLast)!=0 && pCur->info.nKey<intKey ){
*pRes = -1;
return SQLITE_OK;
}
}
+ if( pIdxKey ){
+ xRecordCompare = sqlite3VdbeFindCompare(pIdxKey);
+ pIdxKey->errCode = 0;
+ assert( pIdxKey->default_rc==1
+ || pIdxKey->default_rc==0
+ || pIdxKey->default_rc==-1
+ );
+ }else{
+ xRecordCompare = 0; /* All keys are integers */
+ }
+
rc = moveToRoot(pCur);
if( rc ){
return rc;
@@ -52861,12 +60227,13 @@ SQLITE_PRIVATE int sqlite3BtreeMovetoUnpacked(
assert( pCur->pgnoRoot==0 || pCur->apPage[pCur->iPage]->nCell==0 );
return SQLITE_OK;
}
- assert( pCur->apPage[0]->intKey || pIdxKey );
+ assert( pCur->apPage[0]->intKey==pCur->curIntKey );
+ assert( pCur->curIntKey || pIdxKey );
for(;;){
- int lwr, upr, idx;
+ int lwr, upr, idx, c;
Pgno chldPg;
MemPage *pPage = pCur->apPage[pCur->iPage];
- int c;
+ u8 *pCell; /* Pointer to current cell in pPage */
/* pPage->nCell must be greater than zero. If this is the root-page
** the cursor would have been INVALID above and this for(;;) loop
@@ -52878,35 +60245,47 @@ SQLITE_PRIVATE int sqlite3BtreeMovetoUnpacked(
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 ){
+ assert( biasRight==0 || biasRight==1 );
+ idx = upr>>(1-biasRight); /* idx = biasRight ? upr : (lwr+upr)/2; */
+ pCur->aiIdx[pCur->iPage] = (u16)idx;
+ if( xRecordCompare==0 ){
+ for(;;){
i64 nCellKey;
- if( pPage->hasData ){
- u32 dummy;
- pCell += getVarint32(pCell, dummy);
+ pCell = findCellPastPtr(pPage, idx);
+ if( pPage->intKeyLeaf ){
+ while( 0x80 <= *(pCell++) ){
+ if( pCell>=pPage->aDataEnd ) return SQLITE_CORRUPT_BKPT;
+ }
}
getVarint(pCell, (u64*)&nCellKey);
- if( nCellKey==intKey ){
- c = 0;
- }else if( nCellKey<intKey ){
- c = -1;
+ if( nCellKey<intKey ){
+ lwr = idx+1;
+ if( lwr>upr ){ c = -1; break; }
+ }else if( nCellKey>intKey ){
+ upr = idx-1;
+ if( lwr>upr ){ c = +1; break; }
}else{
- assert( nCellKey>intKey );
- c = +1;
+ assert( nCellKey==intKey );
+ pCur->curFlags |= BTCF_ValidNKey;
+ pCur->info.nKey = nCellKey;
+ pCur->aiIdx[pCur->iPage] = (u16)idx;
+ if( !pPage->leaf ){
+ lwr = idx;
+ goto moveto_next_layer;
+ }else{
+ *pRes = 0;
+ rc = SQLITE_OK;
+ goto moveto_finish;
+ }
}
- pCur->validNKey = 1;
- pCur->info.nKey = nCellKey;
- }else{
+ assert( lwr+upr>=0 );
+ idx = (lwr+upr)>>1; /* idx = (lwr+upr)/2; */
+ }
+ }else{
+ for(;;){
+ int nCell; /* Size of the pCell cell in bytes */
+ pCell = findCellPastPtr(pPage, idx);
+
/* 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
@@ -52915,88 +60294,99 @@ SQLITE_PRIVATE int sqlite3BtreeMovetoUnpacked(
** 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 */
- ){
+ nCell = pCell[0];
+ if( nCell<=pPage->max1bytePayload ){
/* 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);
+ c = xRecordCompare(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);
+ c = xRecordCompare(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. */
+ ** buffer before VdbeRecordCompare() can be called.
+ **
+ ** If the record is corrupt, the xRecordCompare routine may read
+ ** up to two varints past the end of the buffer. An extra 18
+ ** bytes of padding is allocated at the end of the buffer in
+ ** case this happens. */
void *pCellKey;
u8 * const pCellBody = pCell - pPage->childPtrSize;
- btreeParseCellPtr(pPage, pCellBody, &pCur->info);
+ pPage->xParseCell(pPage, pCellBody, &pCur->info);
nCell = (int)pCur->info.nKey;
- pCellKey = sqlite3Malloc( nCell );
+ testcase( nCell<0 ); /* True if key size is 2^32 or more */
+ testcase( nCell==0 ); /* Invalid key size: 0x80 0x80 0x00 */
+ testcase( nCell==1 ); /* Invalid key size: 0x80 0x80 0x01 */
+ testcase( nCell==2 ); /* Minimum legal index key size */
+ if( nCell<2 ){
+ rc = SQLITE_CORRUPT_BKPT;
+ goto moveto_finish;
+ }
+ pCellKey = sqlite3Malloc( nCell+18 );
if( pCellKey==0 ){
rc = SQLITE_NOMEM;
goto moveto_finish;
}
- rc = accessPayload(pCur, 0, nCell, (unsigned char*)pCellKey, 0);
+ pCur->aiIdx[pCur->iPage] = (u16)idx;
+ rc = accessPayload(pCur, 0, nCell, (unsigned char*)pCellKey, 2);
if( rc ){
sqlite3_free(pCellKey);
goto moveto_finish;
}
- c = sqlite3VdbeRecordCompare(nCell, pCellKey, pIdxKey);
+ c = xRecordCompare(nCell, pCellKey, pIdxKey);
sqlite3_free(pCellKey);
}
- }
- if( c==0 ){
- if( pPage->intKey && !pPage->leaf ){
- lwr = idx;
- break;
+ assert(
+ (pIdxKey->errCode!=SQLITE_CORRUPT || c==0)
+ && (pIdxKey->errCode!=SQLITE_NOMEM || pCur->pBtree->db->mallocFailed)
+ );
+ if( c<0 ){
+ lwr = idx+1;
+ }else if( c>0 ){
+ upr = idx-1;
}else{
+ assert( c==0 );
*pRes = 0;
rc = SQLITE_OK;
+ pCur->aiIdx[pCur->iPage] = (u16)idx;
+ if( pIdxKey->errCode ) rc = SQLITE_CORRUPT;
goto moveto_finish;
}
+ if( lwr>upr ) break;
+ assert( lwr+upr>=0 );
+ idx = (lwr+upr)>>1; /* idx = (lwr+upr)/2 */
}
- 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 );
+ pCur->aiIdx[pCur->iPage] = (u16)idx;
*pRes = c;
rc = SQLITE_OK;
goto moveto_finish;
}
+moveto_next_layer:
+ if( lwr>=pPage->nCell ){
+ chldPg = get4byte(&pPage->aData[pPage->hdrOffset+8]);
+ }else{
+ chldPg = get4byte(findCell(pPage, lwr));
+ }
pCur->aiIdx[pCur->iPage] = (u16)lwr;
- pCur->info.nSize = 0;
- pCur->validNKey = 0;
rc = moveToChild(pCur, chldPg);
- if( rc ) goto moveto_finish;
+ if( rc ) break;
}
moveto_finish:
+ pCur->info.nSize = 0;
+ pCur->curFlags &= ~(BTCF_ValidNKey|BTCF_ValidOvfl);
return rc;
}
@@ -53021,28 +60411,50 @@ SQLITE_PRIVATE int sqlite3BtreeEof(BtCursor *pCur){
** 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){
+**
+** The main entry point is sqlite3BtreeNext(). That routine is optimized
+** for the common case of merely incrementing the cell counter BtCursor.aiIdx
+** to the next cell on the current page. The (slower) btreeNext() helper
+** routine is called when it is necessary to move to a different page or
+** to restore the cursor.
+**
+** The calling function will set *pRes to 0 or 1. The initial *pRes value
+** will be 1 if the cursor being stepped corresponds to an SQL index and
+** if this routine could have been skipped if that SQL index had been
+** a unique index. Otherwise the caller will have set *pRes to zero.
+** Zero is the common case. The btree implementation is free to use the
+** initial *pRes value as a hint to improve performance, but the current
+** SQLite btree implementation does not. (Note that the comdb2 btree
+** implementation does use this hint, however.)
+*/
+static SQLITE_NOINLINE int btreeNext(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;
+ assert( pCur->skipNext==0 || pCur->eState!=CURSOR_VALID );
+ assert( *pRes==0 );
+ if( pCur->eState!=CURSOR_VALID ){
+ assert( (pCur->curFlags & BTCF_ValidOvfl)==0 );
+ rc = restoreCursorPosition(pCur);
+ if( rc!=SQLITE_OK ){
+ return rc;
+ }
+ if( CURSOR_INVALID==pCur->eState ){
+ *pRes = 1;
+ return SQLITE_OK;
+ }
+ if( pCur->skipNext ){
+ assert( pCur->eState==CURSOR_VALID || pCur->eState==CURSOR_SKIPNEXT );
+ pCur->eState = CURSOR_VALID;
+ if( pCur->skipNext>0 ){
+ pCur->skipNext = 0;
+ return SQLITE_OK;
+ }
+ pCur->skipNext = 0;
+ }
}
- pCur->skipNext = 0;
pPage = pCur->apPage[pCur->iPage];
idx = ++pCur->aiIdx[pCur->iPage];
@@ -53055,15 +60467,11 @@ SQLITE_PRIVATE int sqlite3BtreeNext(BtCursor *pCur, int *pRes){
** 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;
+ return moveToLeftmost(pCur);
}
do{
if( pCur->iPage==0 ){
@@ -53074,58 +60482,97 @@ SQLITE_PRIVATE int sqlite3BtreeNext(BtCursor *pCur, int *pRes){
moveToParent(pCur);
pPage = pCur->apPage[pCur->iPage];
}while( pCur->aiIdx[pCur->iPage]>=pPage->nCell );
- *pRes = 0;
if( pPage->intKey ){
- rc = sqlite3BtreeNext(pCur, pRes);
+ return sqlite3BtreeNext(pCur, pRes);
}else{
- rc = SQLITE_OK;
+ return SQLITE_OK;
}
- return rc;
}
+ if( pPage->leaf ){
+ return SQLITE_OK;
+ }else{
+ return moveToLeftmost(pCur);
+ }
+}
+SQLITE_PRIVATE int sqlite3BtreeNext(BtCursor *pCur, int *pRes){
+ MemPage *pPage;
+ assert( cursorHoldsMutex(pCur) );
+ assert( pRes!=0 );
+ assert( *pRes==0 || *pRes==1 );
+ assert( pCur->skipNext==0 || pCur->eState!=CURSOR_VALID );
+ pCur->info.nSize = 0;
+ pCur->curFlags &= ~(BTCF_ValidNKey|BTCF_ValidOvfl);
*pRes = 0;
+ if( pCur->eState!=CURSOR_VALID ) return btreeNext(pCur, pRes);
+ pPage = pCur->apPage[pCur->iPage];
+ if( (++pCur->aiIdx[pCur->iPage])>=pPage->nCell ){
+ pCur->aiIdx[pCur->iPage]--;
+ return btreeNext(pCur, pRes);
+ }
if( pPage->leaf ){
return SQLITE_OK;
+ }else{
+ return moveToLeftmost(pCur);
}
- 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){
+**
+** The main entry point is sqlite3BtreePrevious(). That routine is optimized
+** for the common case of merely decrementing the cell counter BtCursor.aiIdx
+** to the previous cell on the current page. The (slower) btreePrevious()
+** helper routine is called when it is necessary to move to a different page
+** or to restore the cursor.
+**
+** The calling function will set *pRes to 0 or 1. The initial *pRes value
+** will be 1 if the cursor being stepped corresponds to an SQL index and
+** if this routine could have been skipped if that SQL index had been
+** a unique index. Otherwise the caller will have set *pRes to zero.
+** Zero is the common case. The btree implementation is free to use the
+** initial *pRes value as a hint to improve performance, but the current
+** SQLite btree implementation does not. (Note that the comdb2 btree
+** implementation does use this hint, however.)
+*/
+static SQLITE_NOINLINE int btreePrevious(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;
+ assert( pRes!=0 );
+ assert( *pRes==0 );
+ assert( pCur->skipNext==0 || pCur->eState!=CURSOR_VALID );
+ assert( (pCur->curFlags & (BTCF_AtLast|BTCF_ValidOvfl|BTCF_ValidNKey))==0 );
+ assert( pCur->info.nSize==0 );
+ if( pCur->eState!=CURSOR_VALID ){
+ rc = restoreCursorPosition(pCur);
+ if( rc!=SQLITE_OK ){
+ return rc;
+ }
+ if( CURSOR_INVALID==pCur->eState ){
+ *pRes = 1;
+ return SQLITE_OK;
+ }
+ if( pCur->skipNext ){
+ assert( pCur->eState==CURSOR_VALID || pCur->eState==CURSOR_SKIPNEXT );
+ pCur->eState = CURSOR_VALID;
+ if( pCur->skipNext<0 ){
+ pCur->skipNext = 0;
+ return SQLITE_OK;
+ }
+ pCur->skipNext = 0;
+ }
}
- 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;
- }
+ if( rc ) return rc;
rc = moveToRightmost(pCur);
}else{
while( pCur->aiIdx[pCur->iPage]==0 ){
@@ -53136,8 +60583,8 @@ SQLITE_PRIVATE int sqlite3BtreePrevious(BtCursor *pCur, int *pRes){
}
moveToParent(pCur);
}
- pCur->info.nSize = 0;
- pCur->validNKey = 0;
+ assert( pCur->info.nSize==0 );
+ assert( (pCur->curFlags & (BTCF_ValidNKey|BTCF_ValidOvfl))==0 );
pCur->aiIdx[pCur->iPage]--;
pPage = pCur->apPage[pCur->iPage];
@@ -53147,9 +60594,25 @@ SQLITE_PRIVATE int sqlite3BtreePrevious(BtCursor *pCur, int *pRes){
rc = SQLITE_OK;
}
}
- *pRes = 0;
return rc;
}
+SQLITE_PRIVATE int sqlite3BtreePrevious(BtCursor *pCur, int *pRes){
+ assert( cursorHoldsMutex(pCur) );
+ assert( pRes!=0 );
+ assert( *pRes==0 || *pRes==1 );
+ assert( pCur->skipNext==0 || pCur->eState!=CURSOR_VALID );
+ *pRes = 0;
+ pCur->curFlags &= ~(BTCF_AtLast|BTCF_ValidOvfl|BTCF_ValidNKey);
+ pCur->info.nSize = 0;
+ if( pCur->eState!=CURSOR_VALID
+ || pCur->aiIdx[pCur->iPage]==0
+ || pCur->apPage[pCur->iPage]->leaf==0
+ ){
+ return btreePrevious(pCur, pRes);
+ }
+ pCur->aiIdx[pCur->iPage]--;
+ return SQLITE_OK;
+}
/*
** Allocate a new page from the database file.
@@ -53160,24 +60623,25 @@ SQLITE_PRIVATE int sqlite3BtreePrevious(BtCursor *pCur, int *pRes){
** 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.
+** an error. *ppPage is set to NULL in the event of an error.
**
-** If the "nearby" parameter is not 0, then a (feeble) effort is made to
+** If the "nearby" parameter is not 0, then an 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.
+** If the eMode parameter is BTALLOC_EXACT and the nearby page exists
+** anywhere on the free-list, then it is guaranteed to be returned. If
+** eMode is BTALLOC_LT then the page returned will be less than or equal
+** to nearby if any such page exists. If eMode is BTALLOC_ANY then there
+** are no restrictions on which page is returned.
*/
static int allocateBtreePage(
- BtShared *pBt,
- MemPage **ppPage,
- Pgno *pPgno,
- Pgno nearby,
- u8 exact
+ BtShared *pBt, /* The btree */
+ MemPage **ppPage, /* Store pointer to the allocated page here */
+ Pgno *pPgno, /* Store the page number here */
+ Pgno nearby, /* Search for a page near this one */
+ u8 eMode /* BTALLOC_EXACT, BTALLOC_LT, or BTALLOC_ANY */
){
MemPage *pPage1;
int rc;
@@ -53188,8 +60652,11 @@ static int allocateBtreePage(
Pgno mxPage; /* Total size of the database file */
assert( sqlite3_mutex_held(pBt->mutex) );
+ assert( eMode==BTALLOC_ANY || (nearby>0 && IfNotOmitAV(pBt->autoVacuum)) );
pPage1 = pBt->pPage1;
mxPage = btreePagecount(pBt);
+ /* EVIDENCE-OF: R-05119-02637 The 4-byte big-endian integer at offset 36
+ ** stores stores the total number of pages on the freelist. */
n = get4byte(&pPage1->aData[36]);
testcase( n==mxPage-1 );
if( n>=mxPage ){
@@ -53199,22 +60666,26 @@ static int allocateBtreePage(
/* 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' */
+ u32 nSearch = 0; /* Count of the number of search attempts */
- /* If the 'exact' parameter was true and a query of the pointer-map
+ /* If eMode==BTALLOC_EXACT 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;
+ if( eMode==BTALLOC_EXACT ){
+ if( 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;
+ }else if( eMode==BTALLOC_LE ){
+ searchList = 1;
}
#endif
@@ -53227,20 +60698,27 @@ static int allocateBtreePage(
/* 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.
+ ** free-list until the page 'nearby' is located (eMode==BTALLOC_EXACT)
+ ** or until a page less than 'nearby' is located (eMode==BTALLOC_LT)
*/
do {
pPrevTrunk = pTrunk;
if( pPrevTrunk ){
+ /* EVIDENCE-OF: R-01506-11053 The first integer on a freelist trunk page
+ ** is the page number of the next freelist trunk page in the list or
+ ** zero if this is the last freelist trunk page. */
iTrunk = get4byte(&pPrevTrunk->aData[0]);
}else{
+ /* EVIDENCE-OF: R-59841-13798 The 4-byte big-endian integer at offset 32
+ ** stores the page number of the first page of the freelist, or zero if
+ ** the freelist is empty. */
iTrunk = get4byte(&pPage1->aData[32]);
}
testcase( iTrunk==mxPage );
- if( iTrunk>mxPage ){
+ if( iTrunk>mxPage || nSearch++ > n ){
rc = SQLITE_CORRUPT_BKPT;
}else{
- rc = btreeGetPage(pBt, iTrunk, &pTrunk, 0);
+ rc = btreeGetUnusedPage(pBt, iTrunk, &pTrunk, 0);
}
if( rc ){
pTrunk = 0;
@@ -53248,8 +60726,9 @@ static int allocateBtreePage(
}
assert( pTrunk!=0 );
assert( pTrunk->aData!=0 );
-
- k = get4byte(&pTrunk->aData[4]); /* # of leaves on this trunk page */
+ /* EVIDENCE-OF: R-13523-04394 The second integer on a freelist trunk page
+ ** is the number of leaf page pointers to follow. */
+ k = get4byte(&pTrunk->aData[4]);
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
@@ -53269,11 +60748,13 @@ static int allocateBtreePage(
rc = SQLITE_CORRUPT_BKPT;
goto end_allocate_page;
#ifndef SQLITE_OMIT_AUTOVACUUM
- }else if( searchList && nearby==iTrunk ){
+ }else if( searchList
+ && (nearby==iTrunk || (iTrunk<nearby && eMode==BTALLOC_LE))
+ ){
/* The list is being searched and this trunk page is the page
** to allocate, regardless of whether it has leaves.
*/
- assert( *pPgno==iTrunk );
+ *pPgno = iTrunk;
*ppPage = pTrunk;
searchList = 0;
rc = sqlite3PagerWrite(pTrunk->pDbPage);
@@ -53302,7 +60783,7 @@ static int allocateBtreePage(
goto end_allocate_page;
}
testcase( iNewTrunk==mxPage );
- rc = btreeGetPage(pBt, iNewTrunk, &pNewTrunk, 0);
+ rc = btreeGetUnusedPage(pBt, iNewTrunk, &pNewTrunk, 0);
if( rc!=SQLITE_OK ){
goto end_allocate_page;
}
@@ -53336,14 +60817,24 @@ static int allocateBtreePage(
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;
+ if( eMode==BTALLOC_LE ){
+ for(i=0; i<k; i++){
+ iPage = get4byte(&aData[8+i*4]);
+ if( iPage<=nearby ){
+ closest = i;
+ break;
+ }
+ }
+ }else{
+ int dist;
+ 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{
@@ -53357,7 +60848,9 @@ static int allocateBtreePage(
goto end_allocate_page;
}
testcase( iPage==mxPage );
- if( !searchList || iPage==nearby ){
+ if( !searchList
+ || (iPage==nearby || (iPage<nearby && eMode==BTALLOC_LE))
+ ){
int noContent;
*pPgno = iPage;
TRACE(("ALLOCATE: %d was leaf %d of %d on trunk %d"
@@ -53369,12 +60862,13 @@ static int allocateBtreePage(
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);
+ noContent = !btreeGetHasContent(pBt, *pPgno)? PAGER_GET_NOCONTENT : 0;
+ rc = btreeGetUnusedPage(pBt, *pPgno, ppPage, noContent);
if( rc==SQLITE_OK ){
rc = sqlite3PagerWrite((*ppPage)->pDbPage);
if( rc!=SQLITE_OK ){
releasePage(*ppPage);
+ *ppPage = 0;
}
}
searchList = 0;
@@ -53384,8 +60878,26 @@ static int allocateBtreePage(
pPrevTrunk = 0;
}while( searchList );
}else{
- /* There are no pages on the freelist, so create a new page at the
- ** end of the file */
+ /* There are no pages on the freelist, so append a new page to the
+ ** database image.
+ **
+ ** Normally, new pages allocated by this block can be requested from the
+ ** pager layer with the 'no-content' flag set. This prevents the pager
+ ** from trying to read the pages content from disk. However, if the
+ ** current transaction has already run one or more incremental-vacuum
+ ** steps, then the page we are about to allocate may contain content
+ ** that is required in the event of a rollback. In this case, do
+ ** not set the no-content flag. This causes the pager to load and journal
+ ** the current page content before overwriting it.
+ **
+ ** Note that the pager will not actually attempt to load or journal
+ ** content for any page that really does lie past the end of the database
+ ** file on disk. So the effects of disabling the no-content optimization
+ ** here are confined to those pages that lie between the end of the
+ ** database image and the end of the database file.
+ */
+ int bNoContent = (0==IfNotOmitAV(pBt->bDoTruncate))? PAGER_GET_NOCONTENT:0;
+
rc = sqlite3PagerWrite(pBt->pPage1->pDbPage);
if( rc ) return rc;
pBt->nPage++;
@@ -53400,7 +60912,7 @@ static int allocateBtreePage(
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);
+ rc = btreeGetUnusedPage(pBt, pBt->nPage, &pPg, bNoContent);
if( rc==SQLITE_OK ){
rc = sqlite3PagerWrite(pPg->pDbPage);
releasePage(pPg);
@@ -53414,11 +60926,12 @@ static int allocateBtreePage(
*pPgno = pBt->nPage;
assert( *pPgno!=PENDING_BYTE_PAGE(pBt) );
- rc = btreeGetPage(pBt, *pPgno, ppPage, 1);
+ rc = btreeGetUnusedPage(pBt, *pPgno, ppPage, bNoContent);
if( rc ) return rc;
rc = sqlite3PagerWrite((*ppPage)->pDbPage);
if( rc!=SQLITE_OK ){
releasePage(*ppPage);
+ *ppPage = 0;
}
TRACE(("ALLOCATE: %d from end of file\n", *pPgno));
}
@@ -53428,16 +60941,8 @@ static int allocateBtreePage(
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) );
+ assert( rc!=SQLITE_OK || sqlite3PagerPageRefcount((*ppPage)->pDbPage)<=1 );
+ assert( rc!=SQLITE_OK || (*ppPage)->isInit==0 );
return rc;
}
@@ -53462,9 +60967,10 @@ static int freePage2(BtShared *pBt, MemPage *pMemPage, Pgno iPage){
int nFree; /* Initial number of pages on free-list */
assert( sqlite3_mutex_held(pBt->mutex) );
- assert( iPage>1 );
+ assert( CORRUPT_DB || iPage>1 );
assert( !pMemPage || pMemPage->pgno==iPage );
+ if( iPage<2 ) return SQLITE_CORRUPT_BKPT;
if( pMemPage ){
pPage = pMemPage;
sqlite3PagerRef(pPage->pDbPage);
@@ -53534,6 +61040,11 @@ static int freePage2(BtShared *pBt, MemPage *pMemPage, Pgno iPage){
** 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".
+ **
+ ** EVIDENCE-OF: R-19920-11576 However, newer versions of SQLite still
+ ** avoid using the last six entries in the freelist trunk page array in
+ ** order that database files created by newer versions of SQLite can be
+ ** read by older versions of SQLite.
*/
rc = sqlite3PagerWrite(pTrunk->pDbPage);
if( rc==SQLITE_OK ){
@@ -53582,9 +61093,15 @@ static void freePage(MemPage *pPage, int *pRC){
}
/*
-** Free any overflow pages associated with the given Cell.
+** Free any overflow pages associated with the given Cell. Write the
+** local Cell size (the number of bytes on the original page, omitting
+** overflow) into *pnSize.
*/
-static int clearCell(MemPage *pPage, unsigned char *pCell){
+static int clearCell(
+ MemPage *pPage, /* The page that contains the Cell */
+ unsigned char *pCell, /* First byte of the Cell */
+ u16 *pnSize /* Write the size of the Cell here */
+){
BtShared *pBt = pPage->pBt;
CellInfo info;
Pgno ovflPgno;
@@ -53593,18 +61110,21 @@ static int clearCell(MemPage *pPage, unsigned char *pCell){
u32 ovflPageSize;
assert( sqlite3_mutex_held(pPage->pBt->mutex) );
- btreeParseCellPtr(pPage, pCell, &info);
- if( info.iOverflow==0 ){
+ pPage->xParseCell(pPage, pCell, &info);
+ *pnSize = info.nSize;
+ if( info.nLocal==info.nPayload ){
return SQLITE_OK; /* No overflow pages. Return without doing anything */
}
- if( pCell+info.iOverflow+3 > pPage->aData+pPage->maskPage ){
+ if( pCell+info.nSize-1 > pPage->aData+pPage->maskPage ){
return SQLITE_CORRUPT_BKPT; /* Cell extends past end of page */
}
- ovflPgno = get4byte(&pCell[info.iOverflow]);
+ ovflPgno = get4byte(pCell + info.nSize - 4);
assert( pBt->usableSize > 4 );
ovflPageSize = pBt->usableSize - 4;
nOvfl = (info.nPayload - info.nLocal + ovflPageSize - 1)/ovflPageSize;
- assert( ovflPgno==0 || nOvfl>0 );
+ assert( nOvfl>0 ||
+ (CORRUPT_DB && (info.nPayload + ovflPageSize)<ovflPageSize)
+ );
while( nOvfl-- ){
Pgno iNext = 0;
MemPage *pOvfl = 0;
@@ -53677,7 +61197,6 @@ static int fillInCell(
BtShared *pBt = pPage->pBt;
Pgno pgnoOvfl = 0;
int nHeader;
- CellInfo info;
assert( sqlite3_mutex_held(pPage->pBt->mutex) );
@@ -53687,40 +61206,71 @@ static int fillInCell(
|| sqlite3PagerIswriteable(pPage->pDbPage) );
/* Fill in the header. */
- nHeader = 0;
- if( !pPage->leaf ){
- nHeader += 4;
- }
- if( pPage->hasData ){
- nHeader += putVarint(&pCell[nHeader], nData+nZero);
+ nHeader = pPage->childPtrSize;
+ nPayload = nData + nZero;
+ if( pPage->intKeyLeaf ){
+ nHeader += putVarint32(&pCell[nHeader], nPayload);
}else{
- nData = nZero = 0;
+ assert( nData==0 );
+ assert( 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;
+ /* Fill in the payload size */
if( pPage->intKey ){
pSrc = pData;
nSrc = nData;
nData = 0;
}else{
- if( NEVER(nKey>0x7fffffff || pKey==0) ){
- return SQLITE_CORRUPT_BKPT;
- }
- nPayload += (int)nKey;
+ assert( nKey<=0x7fffffff && pKey!=0 );
+ nPayload = (int)nKey;
pSrc = pKey;
nSrc = (int)nKey;
}
- *pnSize = info.nSize;
- spaceLeft = info.nLocal;
+ if( nPayload<=pPage->maxLocal ){
+ n = nHeader + nPayload;
+ testcase( n==3 );
+ testcase( n==4 );
+ if( n<4 ) n = 4;
+ *pnSize = n;
+ spaceLeft = nPayload;
+ pPrior = pCell;
+ }else{
+ int mn = pPage->minLocal;
+ n = mn + (nPayload - mn) % (pPage->pBt->usableSize - 4);
+ testcase( n==pPage->maxLocal );
+ testcase( n==pPage->maxLocal+1 );
+ if( n > pPage->maxLocal ) n = mn;
+ spaceLeft = n;
+ *pnSize = n + nHeader + 4;
+ pPrior = &pCell[nHeader+n];
+ }
pPayload = &pCell[nHeader];
- pPrior = &pCell[info.iOverflow];
+ /* At this point variables should be set as follows:
+ **
+ ** nPayload Total payload size in bytes
+ ** pPayload Begin writing payload here
+ ** spaceLeft Space available at pPayload. If nPayload>spaceLeft,
+ ** that means content must spill into overflow pages.
+ ** *pnSize Size of the local cell (not counting overflow pages)
+ ** pPrior Where to write the pgno of the first overflow page
+ **
+ ** Use a call to btreeParseCellPtr() to verify that the values above
+ ** were computed correctly.
+ */
+#if SQLITE_DEBUG
+ {
+ CellInfo info;
+ pPage->xParseCell(pPage, pCell, &info);
+ assert( nHeader=(int)(info.pPayload - pCell) );
+ assert( info.nKey==nKey );
+ assert( *pnSize == info.nSize );
+ assert( spaceLeft == info.nLocal );
+ }
+#endif
+
+ /* Write the payload into the local Cell and any extra into overflow pages */
while( nPayload>0 ){
if( spaceLeft==0 ){
#ifndef SQLITE_OMIT_AUTOVACUUM
@@ -53742,7 +61292,7 @@ static int fillInCell(
** 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
+ ** may misinterpret the uninitialized values and delete the
** wrong pages from the database.
*/
if( pBt->autoVacuum && rc==SQLITE_OK ){
@@ -53820,14 +61370,13 @@ 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( CORRUPT_DB || sz==cellSize(pPage, idx) );
assert( sqlite3PagerIswriteable(pPage->pDbPage) );
assert( sqlite3_mutex_held(pPage->pBt->mutex) );
data = pPage->aData;
@@ -53845,15 +61394,18 @@ static void dropCell(MemPage *pPage, int idx, int sz, int *pRC){
*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;
+ if( pPage->nCell==0 ){
+ memset(&data[hdr+1], 0, 4);
+ data[hdr+7] = 0;
+ put2byte(&data[hdr+5], pPage->pBt->usableSize);
+ pPage->nFree = pPage->pBt->usableSize - pPage->hdrOffset
+ - pPage->childPtrSize - 8;
+ }else{
+ memmove(ptr, ptr+2, 2*(pPage->nCell - idx));
+ put2byte(&data[hdr+3], pPage->nCell);
+ pPage->nFree += 2;
+ }
}
/*
@@ -53867,11 +61419,6 @@ static void dropCell(MemPage *pPage, int idx, int sz, int *pRC){
** 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 */
@@ -53884,19 +61431,14 @@ static void insertCell(
){
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);
+ u8 *pIns; /* The point in pPage->aCellIdx[] where no cell inserted */
if( *pRC ) return;
assert( i>=0 && i<=pPage->nCell+pPage->nOverflow );
- assert( pPage->nCell<=MX_CELL(pPage->pBt) && MX_CELL(pPage->pBt)<=10921 );
+ assert( MX_CELL(pPage->pBt)<=10921 );
+ assert( pPage->nCell<=MX_CELL(pPage->pBt) || CORRUPT_DB );
assert( pPage->nOverflow<=ArraySize(pPage->apOvfl) );
assert( ArraySize(pPage->apOvfl)==ArraySize(pPage->aiOvfl) );
assert( sqlite3_mutex_held(pPage->pBt->mutex) );
@@ -53905,10 +61447,10 @@ static void insertCell(
** 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) );
+ assert( sz==pPage->xCellSize(pPage, pCell) || (sz==8 && iChild>0) );
if( pPage->nOverflow || sz+2>pPage->nFree ){
if( pTemp ){
- memcpy(pTemp+nSkip, pCell+nSkip, sz-nSkip);
+ memcpy(pTemp, pCell, sz);
pCell = pTemp;
}
if( iChild ){
@@ -53918,6 +61460,14 @@ static void insertCell(
assert( j<(int)(sizeof(pPage->apOvfl)/sizeof(pPage->apOvfl[0])) );
pPage->apOvfl[j] = pCell;
pPage->aiOvfl[j] = (u16)i;
+
+ /* When multiple overflows occur, they are always sequential and in
+ ** sorted order. This invariants arise because multiple overflows can
+ ** only occur when inserting divider cells into the parent page during
+ ** balancing, and the dividers are adjacent and sorted.
+ */
+ assert( j==0 || pPage->aiOvfl[j-1]<(u16)i ); /* Overflows in sorted order */
+ assert( j==0 || i==pPage->aiOvfl[j-1]+1 ); /* Overflows are sequential */
}else{
int rc = sqlite3PagerWrite(pPage->pDbPage);
if( rc!=SQLITE_OK ){
@@ -53926,30 +61476,26 @@ static void insertCell(
}
assert( sqlite3PagerIswriteable(pPage->pDbPage) );
data = pPage->aData;
- cellOffset = pPage->cellOffset;
- end = cellOffset + 2*pPage->nCell;
- ins = cellOffset + 2*i;
+ assert( &data[pPage->cellOffset]==pPage->aCellIdx );
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 );
+ /* The allocateSpace() routine guarantees the following properties
+ ** if it returns successfully */
+ assert( idx >= 0 );
+ assert( idx >= pPage->cellOffset+2*pPage->nCell+2 || CORRUPT_DB );
assert( idx+sz <= (int)pPage->pBt->usableSize );
- pPage->nCell++;
pPage->nFree -= (u16)(2 + sz);
- memcpy(&data[idx+nSkip], pCell+nSkip, sz-nSkip);
+ memcpy(&data[idx], pCell, sz);
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);
+ pIns = pPage->aCellIdx + i*2;
+ memmove(pIns+2, pIns, 2*(pPage->nCell - i));
+ put2byte(pIns, idx);
+ pPage->nCell++;
+ /* increment the cell count */
+ if( (++data[pPage->hdrOffset+4])==0 ) data[pPage->hdrOffset+3]++;
+ assert( get2byte(&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
@@ -53962,45 +61508,328 @@ static void insertCell(
}
/*
-** Add a list of cells to a page. The page should be initially empty.
-** The cells are guaranteed to fit on the page.
+** A CellArray object contains a cache of pointers and sizes for a
+** consecutive sequence of cells that might be held multiple pages.
+*/
+typedef struct CellArray CellArray;
+struct CellArray {
+ int nCell; /* Number of cells in apCell[] */
+ MemPage *pRef; /* Reference page */
+ u8 **apCell; /* All cells begin balanced */
+ u16 *szCell; /* Local size of all cells in apCell[] */
+};
+
+/*
+** Make sure the cell sizes at idx, idx+1, ..., idx+N-1 have been
+** computed.
+*/
+static void populateCellCache(CellArray *p, int idx, int N){
+ assert( idx>=0 && idx+N<=p->nCell );
+ while( N>0 ){
+ assert( p->apCell[idx]!=0 );
+ if( p->szCell[idx]==0 ){
+ p->szCell[idx] = p->pRef->xCellSize(p->pRef, p->apCell[idx]);
+ }else{
+ assert( CORRUPT_DB ||
+ p->szCell[idx]==p->pRef->xCellSize(p->pRef, p->apCell[idx]) );
+ }
+ idx++;
+ N--;
+ }
+}
+
+/*
+** Return the size of the Nth element of the cell array
+*/
+static SQLITE_NOINLINE u16 computeCellSize(CellArray *p, int N){
+ assert( N>=0 && N<p->nCell );
+ assert( p->szCell[N]==0 );
+ p->szCell[N] = p->pRef->xCellSize(p->pRef, p->apCell[N]);
+ return p->szCell[N];
+}
+static u16 cachedCellSize(CellArray *p, int N){
+ assert( N>=0 && N<p->nCell );
+ if( p->szCell[N] ) return p->szCell[N];
+ return computeCellSize(p, N);
+}
+
+/*
+** Array apCell[] contains pointers to nCell b-tree page cells. The
+** szCell[] array contains the size in bytes of each cell. This function
+** replaces the current contents of page pPg with the contents of the cell
+** array.
+**
+** Some of the cells in apCell[] may currently be stored in pPg. This
+** function works around problems caused by this by making a copy of any
+** such cells before overwriting the page data.
+**
+** The MemPage.nFree field is invalidated by this function. It is the
+** responsibility of the caller to set it correctly.
*/
-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 */
+static int rebuildPage(
+ MemPage *pPg, /* Edit this page */
+ int nCell, /* Final number of cells on page */
+ u8 **apCell, /* Array of cells */
+ u16 *szCell /* Array of cell sizes */
){
- 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 */
+ const int hdr = pPg->hdrOffset; /* Offset of header on pPg */
+ u8 * const aData = pPg->aData; /* Pointer to data for pPg */
+ const int usableSize = pPg->pBt->usableSize;
+ u8 * const pEnd = &aData[usableSize];
+ int i;
+ u8 *pCellptr = pPg->aCellIdx;
+ u8 *pTmp = sqlite3PagerTempSpace(pPg->pBt->pPager);
+ u8 *pData;
- 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) );
+ i = get2byte(&aData[hdr+5]);
+ memcpy(&pTmp[i], &aData[i], usableSize - i);
+
+ pData = pEnd;
+ for(i=0; i<nCell; i++){
+ u8 *pCell = apCell[i];
+ if( SQLITE_WITHIN(pCell,aData,pEnd) ){
+ pCell = &pTmp[pCell - aData];
+ }
+ pData -= szCell[i];
+ put2byte(pCellptr, (pData - aData));
+ pCellptr += 2;
+ if( pData < pCellptr ) return SQLITE_CORRUPT_BKPT;
+ memcpy(pData, pCell, szCell[i]);
+ assert( szCell[i]==pPg->xCellSize(pPg, pCell) || CORRUPT_DB );
+ testcase( szCell[i]!=pPg->xCellSize(pPg,pCell) );
+ }
+
+ /* The pPg->nFree field is now set incorrectly. The caller will fix it. */
+ pPg->nCell = nCell;
+ pPg->nOverflow = 0;
+
+ put2byte(&aData[hdr+1], 0);
+ put2byte(&aData[hdr+3], pPg->nCell);
+ put2byte(&aData[hdr+5], pData - aData);
+ aData[hdr+7] = 0x00;
+ return SQLITE_OK;
+}
+
+/*
+** Array apCell[] contains nCell pointers to b-tree cells. Array szCell
+** contains the size in bytes of each such cell. This function attempts to
+** add the cells stored in the array to page pPg. If it cannot (because
+** the page needs to be defragmented before the cells will fit), non-zero
+** is returned. Otherwise, if the cells are added successfully, zero is
+** returned.
+**
+** Argument pCellptr points to the first entry in the cell-pointer array
+** (part of page pPg) to populate. After cell apCell[0] is written to the
+** page body, a 16-bit offset is written to pCellptr. And so on, for each
+** cell in the array. It is the responsibility of the caller to ensure
+** that it is safe to overwrite this part of the cell-pointer array.
+**
+** When this function is called, *ppData points to the start of the
+** content area on page pPg. If the size of the content area is extended,
+** *ppData is updated to point to the new start of the content area
+** before returning.
+**
+** Finally, argument pBegin points to the byte immediately following the
+** end of the space required by this page for the cell-pointer area (for
+** all cells - not just those inserted by the current call). If the content
+** area must be extended to before this point in order to accomodate all
+** cells in apCell[], then the cells do not fit and non-zero is returned.
+*/
+static int pageInsertArray(
+ MemPage *pPg, /* Page to add cells to */
+ u8 *pBegin, /* End of cell-pointer array */
+ u8 **ppData, /* IN/OUT: Page content -area pointer */
+ u8 *pCellptr, /* Pointer to cell-pointer area */
+ int iFirst, /* Index of first cell to add */
+ int nCell, /* Number of cells to add to pPg */
+ CellArray *pCArray /* Array of cells */
+){
+ int i;
+ u8 *aData = pPg->aData;
+ u8 *pData = *ppData;
+ int iEnd = iFirst + nCell;
+ assert( CORRUPT_DB || pPg->hdrOffset==0 ); /* Never called on page 1 */
+ for(i=iFirst; i<iEnd; i++){
+ int sz, rc;
+ u8 *pSlot;
+ sz = cachedCellSize(pCArray, i);
+ if( (aData[1]==0 && aData[2]==0) || (pSlot = pageFindSlot(pPg,sz,&rc))==0 ){
+ pData -= sz;
+ if( pData<pBegin ) return 1;
+ pSlot = pData;
+ }
+ /* pSlot and pCArray->apCell[i] will never overlap on a well-formed
+ ** database. But they might for a corrupt database. Hence use memmove()
+ ** since memcpy() sends SIGABORT with overlapping buffers on OpenBSD */
+ assert( (pSlot+sz)<=pCArray->apCell[i]
+ || pSlot>=(pCArray->apCell[i]+sz)
+ || CORRUPT_DB );
+ memmove(pSlot, pCArray->apCell[i], sz);
+ put2byte(pCellptr, (pSlot - aData));
+ pCellptr += 2;
+ }
+ *ppData = pData;
+ return 0;
+}
+
+/*
+** Array apCell[] contains nCell pointers to b-tree cells. Array szCell
+** contains the size in bytes of each such cell. This function adds the
+** space associated with each cell in the array that is currently stored
+** within the body of pPg to the pPg free-list. The cell-pointers and other
+** fields of the page are not updated.
+**
+** This function returns the total number of cells added to the free-list.
+*/
+static int pageFreeArray(
+ MemPage *pPg, /* Page to edit */
+ int iFirst, /* First cell to delete */
+ int nCell, /* Cells to delete */
+ CellArray *pCArray /* Array of cells */
+){
+ u8 * const aData = pPg->aData;
+ u8 * const pEnd = &aData[pPg->pBt->usableSize];
+ u8 * const pStart = &aData[pPg->hdrOffset + 8 + pPg->childPtrSize];
+ int nRet = 0;
+ int i;
+ int iEnd = iFirst + nCell;
+ u8 *pFree = 0;
+ int szFree = 0;
+
+ for(i=iFirst; i<iEnd; i++){
+ u8 *pCell = pCArray->apCell[i];
+ if( SQLITE_WITHIN(pCell, pStart, pEnd) ){
+ int sz;
+ /* No need to use cachedCellSize() here. The sizes of all cells that
+ ** are to be freed have already been computing while deciding which
+ ** cells need freeing */
+ sz = pCArray->szCell[i]; assert( sz>0 );
+ if( pFree!=(pCell + sz) ){
+ if( pFree ){
+ assert( pFree>aData && (pFree - aData)<65536 );
+ freeSpace(pPg, (u16)(pFree - aData), szFree);
+ }
+ pFree = pCell;
+ szFree = sz;
+ if( pFree+sz>pEnd ) return 0;
+ }else{
+ pFree = pCell;
+ szFree += sz;
+ }
+ nRet++;
+ }
+ }
+ if( pFree ){
+ assert( pFree>aData && (pFree - aData)<65536 );
+ freeSpace(pPg, (u16)(pFree - aData), szFree);
+ }
+ return nRet;
+}
+
+/*
+** apCell[] and szCell[] contains pointers to and sizes of all cells in the
+** pages being balanced. The current page, pPg, has pPg->nCell cells starting
+** with apCell[iOld]. After balancing, this page should hold nNew cells
+** starting at apCell[iNew].
+**
+** This routine makes the necessary adjustments to pPg so that it contains
+** the correct cells after being balanced.
+**
+** The pPg->nFree field is invalid when this function returns. It is the
+** responsibility of the caller to set it correctly.
+*/
+static int editPage(
+ MemPage *pPg, /* Edit this page */
+ int iOld, /* Index of first cell currently on page */
+ int iNew, /* Index of new first cell on page */
+ int nNew, /* Final number of cells on page */
+ CellArray *pCArray /* Array of cells and sizes */
+){
+ u8 * const aData = pPg->aData;
+ const int hdr = pPg->hdrOffset;
+ u8 *pBegin = &pPg->aCellIdx[nNew * 2];
+ int nCell = pPg->nCell; /* Cells stored on pPg */
+ u8 *pData;
+ u8 *pCellptr;
+ int i;
+ int iOldEnd = iOld + pPg->nCell + pPg->nOverflow;
+ int iNewEnd = iNew + nNew;
+
+#ifdef SQLITE_DEBUG
+ u8 *pTmp = sqlite3PagerTempSpace(pPg->pBt->pPager);
+ memcpy(pTmp, aData, pPg->pBt->usableSize);
+#endif
+
+ /* Remove cells from the start and end of the page */
+ if( iOld<iNew ){
+ int nShift = pageFreeArray(pPg, iOld, iNew-iOld, pCArray);
+ memmove(pPg->aCellIdx, &pPg->aCellIdx[nShift*2], nCell*2);
+ nCell -= nShift;
+ }
+ if( iNewEnd < iOldEnd ){
+ nCell -= pageFreeArray(pPg, iNewEnd, iOldEnd - iNewEnd, pCArray);
+ }
+
+ pData = &aData[get2byteNotZero(&aData[hdr+5])];
+ if( pData<pBegin ) goto editpage_fail;
+
+ /* Add cells to the start of the page */
+ if( iNew<iOld ){
+ int nAdd = MIN(nNew,iOld-iNew);
+ assert( (iOld-iNew)<nNew || nCell==0 || CORRUPT_DB );
+ pCellptr = pPg->aCellIdx;
+ memmove(&pCellptr[nAdd*2], pCellptr, nCell*2);
+ if( pageInsertArray(
+ pPg, pBegin, &pData, pCellptr,
+ iNew, nAdd, pCArray
+ ) ) goto editpage_fail;
+ nCell += nAdd;
+ }
+
+ /* Add any overflow cells */
+ for(i=0; i<pPg->nOverflow; i++){
+ int iCell = (iOld + pPg->aiOvfl[i]) - iNew;
+ if( iCell>=0 && iCell<nNew ){
+ pCellptr = &pPg->aCellIdx[iCell * 2];
+ memmove(&pCellptr[2], pCellptr, (nCell - iCell) * 2);
+ nCell++;
+ if( pageInsertArray(
+ pPg, pBegin, &pData, pCellptr,
+ iCell+iNew, 1, pCArray
+ ) ) goto editpage_fail;
+ }
+ }
+
+ /* Append cells to the end of the page */
+ pCellptr = &pPg->aCellIdx[nCell*2];
+ if( pageInsertArray(
+ pPg, pBegin, &pData, pCellptr,
+ iNew+nCell, nNew-nCell, pCArray
+ ) ) goto editpage_fail;
+
+ pPg->nCell = nNew;
+ pPg->nOverflow = 0;
- /* Check that the page has just been zeroed by zeroPage() */
- assert( pPage->nCell==0 );
- assert( get2byteNotZero(&data[hdr+5])==nUsable );
+ put2byte(&aData[hdr+3], pPg->nCell);
+ put2byte(&aData[hdr+5], pData - aData);
- 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);
+#ifdef SQLITE_DEBUG
+ for(i=0; i<nNew && !CORRUPT_DB; i++){
+ u8 *pCell = pCArray->apCell[i+iNew];
+ int iOff = get2byteAligned(&pPg->aCellIdx[i*2]);
+ if( pCell>=aData && pCell<&aData[pPg->pBt->usableSize] ){
+ pCell = &pTmp[pCell - aData];
+ }
+ assert( 0==memcmp(pCell, &aData[iOff],
+ pCArray->pRef->xCellSize(pCArray->pRef, pCArray->apCell[i+iNew])) );
}
- put2byte(&data[hdr+3], nCell);
- put2byte(&data[hdr+5], cellbody);
- pPage->nFree -= (nCell*2 + nUsable - cellbody);
- pPage->nCell = (u16)nCell;
+#endif
+
+ return SQLITE_OK;
+ editpage_fail:
+ /* Unable to edit this page. Rebuild it from scratch instead. */
+ populateCellCache(pCArray, iNew, nNew);
+ return rebuildPage(pPg, nNew, &pCArray->apCell[iNew], &pCArray->szCell[iNew]);
}
/*
@@ -54054,7 +61883,7 @@ static int balance_quick(MemPage *pParent, MemPage *pPage, u8 *pSpace){
assert( pPage->nOverflow==1 );
/* This error condition is now caught prior to reaching this function */
- if( pPage->nCell==0 ) return SQLITE_CORRUPT_BKPT;
+ if( NEVER(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
@@ -54066,13 +61895,15 @@ static int balance_quick(MemPage *pParent, MemPage *pPage, u8 *pSpace){
u8 *pOut = &pSpace[4];
u8 *pCell = pPage->apOvfl[0];
- u16 szCell = cellSizePtr(pPage, pCell);
+ u16 szCell = pPage->xCellSize(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);
+ rc = rebuildPage(pNew, 1, &pCell, &szCell);
+ if( NEVER(rc) ) return rc;
+ pNew->nFree = pBt->usableSize - pNew->cellOffset - 2 - szCell;
/* If this is an auto-vacuum database, update the pointer map
** with entries for the new page, and any pointer from the
@@ -54144,9 +61975,9 @@ static int ptrmapCheckPages(MemPage **apPage, int nPage){
u8 *z;
z = findCell(pPage, j);
- btreeParseCellPtr(pPage, z, &info);
- if( info.iOverflow ){
- Pgno ovfl = get4byte(&z[info.iOverflow]);
+ pPage->xParseCell(pPage, z, &info);
+ if( info.nLocal<info.nPayload ){
+ Pgno ovfl = get4byte(&z[info.nSize-4]);
ptrmapGet(pBt, ovfl, &e, &n);
assert( n==pPage->pgno && e==PTRMAP_OVERFLOW1 );
}
@@ -54264,9 +62095,6 @@ static void copyNodeContent(MemPage *pFrom, MemPage *pTo, int *pRC){
** 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 */
@@ -54275,7 +62103,6 @@ static int balance_nonroot(
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[] */
@@ -54286,22 +62113,27 @@ static int balance_nonroot(
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[] */
+ int cntNew[NB+2]; /* Index in b.paCell[] of cell after i-th page */
+ int cntOld[NB+2]; /* Old index in b.apCell[] */
+ int szNew[NB+2]; /* Combined size of cells placed on i-th page */
u8 *aSpace1; /* Space for copies of dividers cells */
Pgno pgno; /* Temp var to store a page number in */
-
+ u8 abDone[NB+2]; /* True after i'th new page is populated */
+ Pgno aPgno[NB+2]; /* Page numbers of new pages before shuffling */
+ Pgno aPgOrder[NB+2]; /* Copy of aPgno[] used for sorting pages */
+ u16 aPgFlags[NB+2]; /* flags field of new pages before shuffling */
+ CellArray b; /* Parsed information on cells being balanced */
+
+ memset(abDone, 0, sizeof(abDone));
+ b.nCell = 0;
+ b.apCell = 0;
pBt = pParent->pBt;
assert( sqlite3_mutex_held(pBt->mutex) );
assert( sqlite3PagerIswriteable(pParent->pDbPage) );
@@ -54343,7 +62175,6 @@ static int balance_nonroot(
}else if( iParentIdx==i ){
nxDiv = i-2+bBulk;
}else{
- assert( bBulk==0 );
nxDiv = iParentIdx-1;
}
i = 2-bBulk;
@@ -54356,7 +62187,7 @@ static int balance_nonroot(
}
pgno = get4byte(pRight);
while( 1 ){
- rc = getAndInitPage(pBt, pgno, &apOld[i]);
+ rc = getAndInitPage(pBt, pgno, &apOld[i], 0, 0);
if( rc ){
memset(apOld, 0, (i+1)*sizeof(MemPage*));
goto balance_cleanup;
@@ -54367,12 +62198,12 @@ static int balance_nonroot(
if( i+nxDiv==pParent->aiOvfl[0] && pParent->nOverflow ){
apDiv[i] = pParent->apOvfl[0];
pgno = get4byte(apDiv[i]);
- szNew[i] = cellSizePtr(pParent, apDiv[i]);
+ szNew[i] = pParent->xCellSize(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]);
+ szNew[i] = pParent->xCellSize(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.
@@ -54410,138 +62241,209 @@ static int balance_nonroot(
/*
** 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 ){
+ nMaxCells*sizeof(u8*) /* b.apCell */
+ + nMaxCells*sizeof(u16) /* b.szCell */
+ + pBt->pageSize; /* aSpace1 */
+
+ /* EVIDENCE-OF: R-28375-38319 SQLite will never request a scratch buffer
+ ** that is more than 6 times the database page size. */
+ assert( szScratch<=6*(int)pBt->pageSize );
+ b.apCell = sqlite3ScratchMalloc( szScratch );
+ if( b.apCell==0 ){
rc = SQLITE_NOMEM;
goto balance_cleanup;
}
- szCell = (u16*)&apCell[nMaxCells];
- aSpace1 = (u8*)&szCell[nMaxCells];
+ b.szCell = (u16*)&b.apCell[nMaxCells];
+ aSpace1 = (u8*)&b.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.
+ ** into the local b.apCell[] array. Make copies of the divider cells
+ ** into space obtained from aSpace1[]. The divider cells have already
+ ** been removed 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
+ ** into aSpace1[]. In this way, all cells in b.apCell[] are without
** child pointers. If siblings are not leaves, then all cell in
- ** apCell[] include child pointers. Either way, all cells in apCell[]
+ ** b.apCell[] include child pointers. Either way, all cells in b.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;
+ b.pRef = apOld[0];
+ leafCorrection = b.pRef->leaf*4;
+ leafData = b.pRef->intKeyLeaf;
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;
+ MemPage *pOld = apOld[i];
+ int limit = pOld->nCell;
+ u8 *aData = pOld->aData;
+ u16 maskPage = pOld->maskPage;
+ u8 *piCell = aData + pOld->cellOffset;
+ u8 *piEnd;
+
+ /* Verify that all sibling pages are of the same "type" (table-leaf,
+ ** table-interior, index-leaf, or index-interior).
+ */
+ if( pOld->aData[0]!=apOld[0]->aData[0] ){
+ rc = SQLITE_CORRUPT_BKPT;
+ goto balance_cleanup;
+ }
+
+ /* Load b.apCell[] with pointers to all cells in pOld. If pOld
+ ** constains overflow cells, include them in the b.apCell[] array
+ ** in the correct spot.
+ **
+ ** Note that when there are multiple overflow cells, it is always the
+ ** case that they are sequential and adjacent. This invariant arises
+ ** because multiple overflows can only occurs when inserting divider
+ ** cells into a parent on a prior balance, and divider cells are always
+ ** adjacent and are inserted in order. There is an assert() tagged
+ ** with "NOTE 1" in the overflow cell insertion loop to prove this
+ ** invariant.
+ **
+ ** This must be done in advance. Once the balance starts, the cell
+ ** offset section of the btree page will be overwritten and we will no
+ ** long be able to find the cells if a pointer to each cell is not saved
+ ** first.
+ */
+ memset(&b.szCell[b.nCell], 0, sizeof(b.szCell[0])*limit);
if( pOld->nOverflow>0 ){
+ memset(&b.szCell[b.nCell+limit], 0, sizeof(b.szCell[0])*pOld->nOverflow);
+ limit = pOld->aiOvfl[0];
for(j=0; j<limit; j++){
- assert( nCell<nMaxCells );
- apCell[nCell] = findOverflowCell(pOld, j);
- szCell[nCell] = cellSizePtr(pOld, apCell[nCell]);
- nCell++;
+ b.apCell[b.nCell] = aData + (maskPage & get2byteAligned(piCell));
+ piCell += 2;
+ b.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++;
+ for(k=0; k<pOld->nOverflow; k++){
+ assert( k==0 || pOld->aiOvfl[k-1]+1==pOld->aiOvfl[k] );/* NOTE 1 */
+ b.apCell[b.nCell] = pOld->apOvfl[k];
+ b.nCell++;
}
- }
+ }
+ piEnd = aData + pOld->cellOffset + 2*pOld->nCell;
+ while( piCell<piEnd ){
+ assert( b.nCell<nMaxCells );
+ b.apCell[b.nCell] = aData + (maskPage & get2byteAligned(piCell));
+ piCell += 2;
+ b.nCell++;
+ }
+
+ cntOld[i] = b.nCell;
if( i<nOld-1 && !leafData){
u16 sz = (u16)szNew[i];
u8 *pTemp;
- assert( nCell<nMaxCells );
- szCell[nCell] = sz;
+ assert( b.nCell<nMaxCells );
+ b.szCell[b.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;
+ b.apCell[b.nCell] = pTemp+leafCorrection;
assert( leafCorrection==0 || leafCorrection==4 );
- szCell[nCell] = szCell[nCell] - leafCorrection;
+ b.szCell[b.nCell] = b.szCell[b.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);
+ memcpy(b.apCell[b.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;
+ while( b.szCell[b.nCell]<4 ){
+ /* Do not allow any cells smaller than 4 bytes. If a smaller cell
+ ** does exist, pad it with 0x00 bytes. */
+ assert( b.szCell[b.nCell]==3 || CORRUPT_DB );
+ assert( b.apCell[b.nCell]==&aSpace1[iSpace1-3] || CORRUPT_DB );
+ aSpace1[iSpace1++] = 0x00;
+ b.szCell[b.nCell]++;
}
}
- nCell++;
+ b.nCell++;
}
}
/*
- ** Figure out the number of pages needed to hold all nCell cells.
+ ** Figure out the number of pages needed to hold all b.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.
+ ** in b.apCell[] of the cell that divides page i from page i+1.
+ ** cntNew[k] should equal b.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
+ ** cntNew[i]: Index in b.apCell[] and b.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++;
+ for(i=0; i<nOld; i++){
+ MemPage *p = apOld[i];
+ szNew[i] = usableSpace - p->nFree;
+ if( szNew[i]<0 ){ rc = SQLITE_CORRUPT_BKPT; goto balance_cleanup; }
+ for(j=0; j<p->nOverflow; j++){
+ szNew[i] += 2 + p->xCellSize(p, p->apOvfl[j]);
+ }
+ cntNew[i] = cntOld[i];
+ }
+ k = nOld;
+ for(i=0; i<k; i++){
+ int sz;
+ while( szNew[i]>usableSpace ){
+ if( i+1>=k ){
+ k = i+2;
+ if( k>NB+2 ){ rc = SQLITE_CORRUPT_BKPT; goto balance_cleanup; }
+ szNew[k-1] = 0;
+ cntNew[k-1] = b.nCell;
+ }
+ sz = 2 + cachedCellSize(&b, cntNew[i]-1);
+ szNew[i] -= sz;
+ if( !leafData ){
+ if( cntNew[i]<b.nCell ){
+ sz = 2 + cachedCellSize(&b, cntNew[i]);
+ }else{
+ sz = 0;
+ }
+ }
+ szNew[i+1] += sz;
+ cntNew[i]--;
+ }
+ while( cntNew[i]<b.nCell ){
+ sz = 2 + cachedCellSize(&b, cntNew[i]);
+ if( szNew[i]+sz>usableSpace ) break;
+ szNew[i] += sz;
+ cntNew[i]++;
+ if( !leafData ){
+ if( cntNew[i]<b.nCell ){
+ sz = 2 + cachedCellSize(&b, cntNew[i]);
+ }else{
+ sz = 0;
+ }
+ }
+ szNew[i+1] -= sz;
+ }
+ if( cntNew[i]>=b.nCell ){
+ k = i+1;
+ }else if( cntNew[i] <= (i>0 ? cntNew[i-1] : 0) ){
+ rc = SQLITE_CORRUPT_BKPT;
+ goto balance_cleanup;
+ }
+ }
/*
** 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.
+ ** on the left side (siblings with smaller keys). The left siblings are
+ ** always nearly full, while the right-most sibling might be nearly empty.
+ ** The next 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
@@ -54555,46 +62457,46 @@ static int balance_nonroot(
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;
- }
+ (void)cachedCellSize(&b, d);
+ do{
+ assert( d<nMaxCells );
+ assert( r<nMaxCells );
+ (void)cachedCellSize(&b, r);
+ if( szRight!=0
+ && (bBulk || szRight+b.szCell[d]+2 > szLeft-(b.szCell[r]+2)) ){
+ break;
+ }
+ szRight += b.szCell[d] + 2;
+ szLeft -= b.szCell[r] + 2;
+ cntNew[i-1] = r;
+ r--;
+ d--;
+ }while( r>=0 );
szNew[i] = szRight;
szNew[i-1] = szLeft;
+ if( cntNew[i-1] <= (i>1 ? cntNew[i-2] : 0) ){
+ rc = SQLITE_CORRUPT_BKPT;
+ goto balance_cleanup;
+ }
}
- /* 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.
+ /* Sanity check: For a non-corrupt database file one of the follwing
+ ** must be true:
+ ** (1) We found one or more cells (cntNew[0])>0), or
+ ** (2) 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.
*/
-#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
+ assert( cntNew[0]>0 || (pParent->pgno==1 && pParent->nCell==0) || CORRUPT_DB);
+ TRACE(("BALANCE: old: %d(nc=%d) %d(nc=%d) %d(nc=%d)\n",
+ apOld[0]->pgno, apOld[0]->nCell,
+ nOld>=2 ? apOld[1]->pgno : 0, nOld>=2 ? apOld[1]->nCell : 0,
+ nOld>=3 ? apOld[2]->pgno : 0, nOld>=3 ? apOld[2]->nCell : 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;
@@ -54608,8 +62510,10 @@ static int balance_nonroot(
assert( i>0 );
rc = allocateBtreePage(pBt, &pNew, &pgno, (bBulk ? 1 : pgno), 0);
if( rc ) goto balance_cleanup;
+ zeroPage(pNew, pageFlags);
apNew[i] = pNew;
nNew++;
+ cntOld[i] = b.nCell;
/* Set the pointer-map entry for the new sibling page. */
if( ISAUTOVACUUM ){
@@ -54621,135 +62525,249 @@ static int balance_nonroot(
}
}
- /* 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.
+ ** Reassign page numbers so that the new pages are in ascending order.
+ ** This helps to keep entries in the disk file in order so that a scan
+ ** of the table is closer to 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.
+ ** An O(n^2) insertion sort algorithm is used, but since n is never more
+ ** than (NB+2) (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.
+ ** 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;
+ for(i=0; i<nNew; i++){
+ aPgOrder[i] = aPgno[i] = apNew[i]->pgno;
+ aPgFlags[i] = apNew[i]->pDbPage->flags;
+ for(j=0; j<i; j++){
+ if( aPgno[j]==aPgno[i] ){
+ /* This branch is taken if the set of sibling pages somehow contains
+ ** duplicate entries. This can happen if the database is corrupt.
+ ** It would be simpler to detect this as part of the loop below, but
+ ** we do the detection here in order to avoid populating the pager
+ ** cache with two separate objects associated with the same
+ ** page number. */
+ assert( CORRUPT_DB );
+ rc = SQLITE_CORRUPT_BKPT;
+ goto balance_cleanup;
}
}
- if( minI>i ){
- MemPage *pT;
- pT = apNew[i];
- apNew[i] = apNew[minI];
- apNew[minI] = pT;
+ }
+ for(i=0; i<nNew; i++){
+ int iBest = 0; /* aPgno[] index of page number to use */
+ for(j=1; j<nNew; j++){
+ if( aPgOrder[j]<aPgOrder[iBest] ) iBest = j;
+ }
+ pgno = aPgOrder[iBest];
+ aPgOrder[iBest] = 0xffffffff;
+ if( iBest!=i ){
+ if( iBest>i ){
+ sqlite3PagerRekey(apNew[iBest]->pDbPage, pBt->nPage+iBest+1, 0);
+ }
+ sqlite3PagerRekey(apNew[i]->pDbPage, pgno, aPgFlags[iBest]);
+ apNew[i]->pgno = pgno;
}
}
- TRACE(("new: %d(%d) %d(%d) %d(%d) %d(%d) %d(%d)\n",
- apNew[0]->pgno, szNew[0],
+
+ TRACE(("BALANCE: new: %d(%d nc=%d) %d(%d nc=%d) %d(%d nc=%d) "
+ "%d(%d nc=%d) %d(%d nc=%d)\n",
+ apNew[0]->pgno, szNew[0], cntNew[0],
nNew>=2 ? apNew[1]->pgno : 0, nNew>=2 ? szNew[1] : 0,
+ nNew>=2 ? cntNew[1] - cntNew[0] - !leafData : 0,
nNew>=3 ? apNew[2]->pgno : 0, nNew>=3 ? szNew[2] : 0,
+ nNew>=3 ? cntNew[2] - cntNew[1] - !leafData : 0,
nNew>=4 ? apNew[3]->pgno : 0, nNew>=4 ? szNew[3] : 0,
- nNew>=5 ? apNew[4]->pgno : 0, nNew>=5 ? szNew[4] : 0));
+ nNew>=4 ? cntNew[3] - cntNew[2] - !leafData : 0,
+ nNew>=5 ? apNew[4]->pgno : 0, nNew>=5 ? szNew[4] : 0,
+ nNew>=5 ? cntNew[4] - cntNew[3] - !leafData : 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.
+ /* If the sibling pages are not leaves, ensure that the right-child pointer
+ ** of the right-most new sibling page is set to the value that was
+ ** originally in the same field of the right-most old sibling page. */
+ if( (pageFlags & PTF_LEAF)==0 && nOld!=nNew ){
+ MemPage *pOld = (nNew>nOld ? apNew : apOld)[nOld-1];
+ memcpy(&apNew[nNew-1]->aData[8], &pOld->aData[8], 4);
+ }
+
+ /* Make any required updates to pointer map entries associated with
+ ** cells stored on sibling pages following the balance operation. Pointer
+ ** map entries associated with divider cells are set by the insertCell()
+ ** routine. The associated pointer map entries are:
+ **
+ ** a) if the cell contains a reference to an overflow chain, the
+ ** entry associated with the first page in the overflow chain, and
+ **
+ ** b) if the sibling pages are not leaves, the child page associated
+ ** with the cell.
+ **
+ ** If the sibling pages are not leaves, then the pointer map entry
+ ** associated with the right-child of each sibling may also need to be
+ ** updated. This happens below, after the sibling pages have been
+ ** populated, not here.
*/
- j = 0;
- for(i=0; i<nNew; i++){
- /* Assemble the new sibling page. */
+ if( ISAUTOVACUUM ){
+ MemPage *pNew = apNew[0];
+ u8 *aOld = pNew->aData;
+ int cntOldNext = pNew->nCell + pNew->nOverflow;
+ int usableSize = pBt->usableSize;
+ int iNew = 0;
+ int iOld = 0;
+
+ for(i=0; i<b.nCell; i++){
+ u8 *pCell = b.apCell[i];
+ if( i==cntOldNext ){
+ MemPage *pOld = (++iOld)<nNew ? apNew[iOld] : apOld[iOld];
+ cntOldNext += pOld->nCell + pOld->nOverflow + !leafData;
+ aOld = pOld->aData;
+ }
+ if( i==cntNew[iNew] ){
+ pNew = apNew[++iNew];
+ if( !leafData ) continue;
+ }
+
+ /* Cell pCell is destined for new sibling page pNew. Originally, it
+ ** was either part of sibling page iOld (possibly an overflow cell),
+ ** or else the divider cell to the left of sibling page iOld. So,
+ ** if sibling page iOld had the same page number as pNew, and if
+ ** pCell really was a part of sibling page iOld (not a divider or
+ ** overflow cell), we can skip updating the pointer map entries. */
+ if( iOld>=nNew
+ || pNew->pgno!=aPgno[iOld]
+ || !SQLITE_WITHIN(pCell,aOld,&aOld[usableSize])
+ ){
+ if( !leafCorrection ){
+ ptrmapPut(pBt, get4byte(pCell), PTRMAP_BTREE, pNew->pgno, &rc);
+ }
+ if( cachedCellSize(&b,i)>pNew->minLocal ){
+ ptrmapPutOvflPtr(pNew, pCell, &rc);
+ }
+ if( rc ) goto balance_cleanup;
+ }
+ }
+ }
+
+ /* Insert new divider cells into pParent. */
+ for(i=0; i<nNew-1; i++){
+ u8 *pCell;
+ u8 *pTemp;
+ int sz;
MemPage *pNew = apNew[i];
+ j = cntNew[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 );
+ assert( b.apCell[j]!=0 );
+ pCell = b.apCell[j];
+ sz = b.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 b.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--;
+ pNew->xParseCell(pNew, b.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( b.szCell[j]==4 ){
+ assert(leafCorrection==4);
+ sz = pParent->xCellSize(pParent, pCell);
+ }
+ }
+ iOvflSpace += sz;
+ assert( sz<=pBt->maxLocal+23 );
+ assert( iOvflSpace <= (int)pBt->pageSize );
+ insertCell(pParent, nxDiv+i, pCell, sz, pTemp, pNew->pgno, &rc);
+ if( rc!=SQLITE_OK ) goto balance_cleanup;
+ assert( sqlite3PagerIswriteable(pParent->pDbPage) );
+ }
- j = cntNew[i];
+ /* Now update the actual sibling pages. The order in which they are updated
+ ** is important, as this code needs to avoid disrupting any page from which
+ ** cells may still to be read. In practice, this means:
+ **
+ ** (1) If cells are moving left (from apNew[iPg] to apNew[iPg-1])
+ ** then it is not safe to update page apNew[iPg] until after
+ ** the left-hand sibling apNew[iPg-1] has been updated.
+ **
+ ** (2) If cells are moving right (from apNew[iPg] to apNew[iPg+1])
+ ** then it is not safe to update page apNew[iPg] until after
+ ** the right-hand sibling apNew[iPg+1] has been updated.
+ **
+ ** If neither of the above apply, the page is safe to update.
+ **
+ ** The iPg value in the following loop starts at nNew-1 goes down
+ ** to 0, then back up to nNew-1 again, thus making two passes over
+ ** the pages. On the initial downward pass, only condition (1) above
+ ** needs to be tested because (2) will always be true from the previous
+ ** step. On the upward pass, both conditions are always true, so the
+ ** upwards pass simply processes pages that were missed on the downward
+ ** pass.
+ */
+ for(i=1-nNew; i<nNew; i++){
+ int iPg = i<0 ? -i : i;
+ assert( iPg>=0 && iPg<nNew );
+ if( abDone[iPg] ) continue; /* Skip pages already processed */
+ if( i>=0 /* On the upwards pass, or... */
+ || cntOld[iPg-1]>=cntNew[iPg-1] /* Condition (1) is true */
+ ){
+ int iNew;
+ int iOld;
+ int nNewCell;
- /* 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;
+ /* Verify condition (1): If cells are moving left, update iPg
+ ** only after iPg-1 has already been updated. */
+ assert( iPg==0 || cntOld[iPg-1]>=cntNew[iPg-1] || abDone[iPg-1] );
- 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;
+ /* Verify condition (2): If cells are moving right, update iPg
+ ** only after iPg+1 has already been updated. */
+ assert( cntNew[iPg]>=cntOld[iPg] || abDone[iPg+1] );
+
+ if( iPg==0 ){
+ iNew = iOld = 0;
+ nNewCell = cntNew[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);
- }
+ iOld = iPg<nOld ? (cntOld[iPg-1] + !leafData) : b.nCell;
+ iNew = cntNew[iPg-1] + !leafData;
+ nNewCell = cntNew[iPg] - iNew;
}
- 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++;
+ rc = editPage(apNew[iPg], iOld, iNew, nNewCell, &b);
+ if( rc ) goto balance_cleanup;
+ abDone[iPg]++;
+ apNew[iPg]->nFree = usableSpace-szNew[iPg];
+ assert( apNew[iPg]->nOverflow==0 );
+ assert( apNew[iPg]->nCell==nNewCell );
}
}
- assert( j==nCell );
+
+ /* All pages have been processed exactly once */
+ assert( memcmp(abDone, "\01\01\01\01\01", nNew)==0 );
+
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
@@ -54762,132 +62780,56 @@ static int balance_nonroot(
** 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 );
+ ** It is critical that the child page be defragmented before being
+ ** copied into the parent, because if the parent is page 1 then it will
+ ** by smaller than the child due to the database header, and so all the
+ ** free space needs to be up front.
+ */
+ assert( nNew==1 || CORRUPT_DB );
+ rc = defragmentPage(apNew[0]);
+ testcase( rc!=SQLITE_OK );
assert( apNew[0]->nFree ==
- (get2byte(&apNew[0]->aData[5])-apNew[0]->cellOffset-apNew[0]->nCell*2)
+ (get2byte(&apNew[0]->aData[5])-apNew[0]->cellOffset-apNew[0]->nCell*2)
+ || rc!=SQLITE_OK
);
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);
- }
- }
+ }else if( ISAUTOVACUUM && !leafCorrection ){
+ /* Fix the pointer map entries associated with the right-child of each
+ ** sibling page. All other pointer map entries have already been taken
+ ** care of. */
+ for(i=0; i<nNew; i++){
+ u32 key = get4byte(&apNew[i]->aData[8]);
+ ptrmapPut(pBt, key, PTRMAP_BTREE, apNew[i]->pgno, &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);
- }
- }
+ assert( pParent->isInit );
+ TRACE(("BALANCE: finished: old=%d new=%d cells=%d\n",
+ nOld, nNew, b.nCell));
+
+ /* Free any old pages that were not reused as new pages.
+ */
+ for(i=nNew; i<nOld; i++){
+ freePage(apOld[i], &rc);
+ }
#if 0
+ if( ISAUTOVACUUM && rc==SQLITE_OK && apNew[0]->isInit ){
/* 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));
+#endif
/*
** Cleanup before returning.
*/
balance_cleanup:
- sqlite3ScratchFree(apCell);
+ sqlite3ScratchFree(b.apCell);
for(i=0; i<nOld; i++){
releasePage(apOld[i]);
}
@@ -54897,9 +62839,6 @@ balance_cleanup:
return rc;
}
-#if defined(_MSC_VER) && _MSC_VER >= 1700 && defined(_M_ARM)
-#pragma optimize("", on)
-#endif
/*
@@ -55018,7 +62957,7 @@ static int balance(BtCursor *pCur){
rc = sqlite3PagerWrite(pParent->pDbPage);
if( rc==SQLITE_OK ){
#ifndef SQLITE_OMIT_QUICKBALANCE
- if( pPage->hasData
+ if( pPage->intKeyLeaf
&& pPage->nOverflow==1
&& pPage->aiOvfl[0]==pPage->nCell
&& pParent->pgno!=1
@@ -55027,7 +62966,7 @@ static int balance(BtCursor *pCur){
/* 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
+ ** happens, the next iteration 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.
@@ -55060,7 +62999,8 @@ static int balance(BtCursor *pCur){
** 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);
+ rc = balance_nonroot(pParent, iIdx, pSpace, iPage==1,
+ pCur->hints&BTREE_BULKLOAD);
if( pFree ){
/* If pFree is not NULL, it points to the pSpace buffer used
** by a previous call to balance_nonroot(). Its contents are
@@ -55081,6 +63021,7 @@ static int balance(BtCursor *pCur){
/* The next iteration of the do-loop balances the parent page. */
releasePage(pPage);
pCur->iPage--;
+ assert( pCur->iPage>=0 );
}
}while( rc==SQLITE_OK );
@@ -55104,7 +63045,7 @@ static int balance(BtCursor *pCur){
** 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
+** a positive value if pCur points at an entry that is larger than
** (pKey, nKey)).
**
** If the seekResult parameter is non-zero, then the caller guarantees that
@@ -55137,7 +63078,8 @@ SQLITE_PRIVATE int sqlite3BtreeInsert(
}
assert( cursorHoldsMutex(pCur) );
- assert( pCur->wrFlag && pBt->inTransaction==TRANS_WRITE
+ assert( (pCur->curFlags & BTCF_WriteFlag)!=0
+ && pBt->inTransaction==TRANS_WRITE
&& (pBt->btsFlags & BTS_READ_ONLY)==0 );
assert( hasSharedCacheTableLock(p, pCur->pgnoRoot, pCur->pKeyInfo!=0, 2) );
@@ -55159,17 +63101,28 @@ SQLITE_PRIVATE int sqlite3BtreeInsert(
** 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( pCur->curFlags & BTCF_Multiple ){
+ 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 ){
+ assert( pKey==0 );
+ /* If this is an insert into a table b-tree, invalidate any incrblob
+ ** cursors open on the row being replaced */
invalidateIncrblobCursors(p, nKey, 0);
- }
- if( !loc ){
+ /* If the cursor is currently on the last row and we are appending a
+ ** new row onto the end, set the "loc" to avoid an unnecessary
+ ** btreeMoveto() call */
+ if( (pCur->curFlags&BTCF_ValidNKey)!=0 && nKey>0
+ && pCur->info.nKey==nKey-1 ){
+ loc = -1;
+ }else if( loc==0 ){
+ rc = sqlite3BtreeMovetoUnpacked(pCur, 0, nKey, appendBias, &loc);
+ if( rc ) return rc;
+ }
+ }else if( loc==0 ){
rc = btreeMoveto(pCur, pKey, nKey, appendBias, &loc);
if( rc ) return rc;
}
@@ -55183,12 +63136,11 @@ SQLITE_PRIVATE int sqlite3BtreeInsert(
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;
+ assert( newCell!=0 );
rc = fillInCell(pPage, newCell, pKey, nKey, pData, nData, nZero, &szNew);
if( rc ) goto end_insert;
- assert( szNew==cellSizePtr(pPage, newCell) );
+ assert( szNew==pPage->xCellSize(pPage, newCell) );
assert( szNew <= MX_CELL_SIZE(pBt) );
idx = pCur->aiIdx[pCur->iPage];
if( loc==0 ){
@@ -55202,8 +63154,7 @@ SQLITE_PRIVATE int sqlite3BtreeInsert(
if( !pPage->leaf ){
memcpy(newCell, oldCell, 4);
}
- szOld = cellSizePtr(pPage, oldCell);
- rc = clearCell(pPage, oldCell);
+ rc = clearCell(pPage, oldCell, &szOld);
dropCell(pPage, idx, szOld, &rc);
if( rc ) goto end_insert;
}else if( loc<0 && pPage->nCell>0 ){
@@ -55215,9 +63166,9 @@ SQLITE_PRIVATE int sqlite3BtreeInsert(
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()
+ /* If no error has occurred 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
+ ** the cursor, zero the BtCursor.info.nSize and BTCF_ValidNKey
** variables.
**
** Previous versions of SQLite called moveToRoot() to move the cursor
@@ -55236,8 +63187,8 @@ SQLITE_PRIVATE int sqlite3BtreeInsert(
** 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 ){
+ pCur->curFlags &= ~(BTCF_ValidNKey);
rc = balance(pCur);
/* Must make sure nOverflow is reset to zero even if the balance()
@@ -55254,10 +63205,15 @@ end_insert:
}
/*
-** Delete the entry that the cursor is pointing to. The cursor
-** is left pointing at a arbitrary location.
+** Delete the entry that the cursor is pointing to.
+**
+** If the second parameter is zero, then the cursor is left pointing at an
+** arbitrary location after the delete. If it is non-zero, then the cursor
+** is left in a state such that the next call to BtreeNext() or BtreePrev()
+** moves it to the same row as it would if the call to BtreeDelete() had
+** been omitted.
*/
-SQLITE_PRIVATE int sqlite3BtreeDelete(BtCursor *pCur){
+SQLITE_PRIVATE int sqlite3BtreeDelete(BtCursor *pCur, int bPreserve){
Btree *p = pCur->pBtree;
BtShared *pBt = p->pBt;
int rc; /* Return code */
@@ -55265,19 +63221,17 @@ SQLITE_PRIVATE int sqlite3BtreeDelete(BtCursor *pCur){
unsigned char *pCell; /* Pointer to cell to delete */
int iCellIdx; /* Index of cell to delete */
int iCellDepth; /* Depth of node containing pCell */
+ u16 szCell; /* Size of the cell being deleted */
+ int bSkipnext = 0; /* Leaf cursor in SKIPNEXT state */
assert( cursorHoldsMutex(pCur) );
assert( pBt->inTransaction==TRANS_WRITE );
assert( (pBt->btsFlags & BTS_READ_ONLY)==0 );
- assert( pCur->wrFlag );
+ assert( pCur->curFlags & BTCF_WriteFlag );
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. */
- }
+ assert( pCur->aiIdx[pCur->iPage]<pCur->apPage[pCur->iPage]->nCell );
+ assert( pCur->eState==CURSOR_VALID );
iCellDepth = pCur->iPage;
iCellIdx = pCur->aiIdx[iCellDepth];
@@ -55292,18 +63246,17 @@ SQLITE_PRIVATE int sqlite3BtreeDelete(BtCursor *pCur){
** 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;
+ int notUsed = 0;
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;
+ ** making any modifications. */
+ if( pCur->curFlags & BTCF_Multiple ){
+ 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. */
@@ -55311,10 +63264,35 @@ SQLITE_PRIVATE int sqlite3BtreeDelete(BtCursor *pCur){
invalidateIncrblobCursors(p, pCur->info.nKey, 0);
}
+ /* If the bPreserve flag is set to true, then the cursor position must
+ ** be preserved following this delete operation. If the current delete
+ ** will cause a b-tree rebalance, then this is done by saving the cursor
+ ** key and leaving the cursor in CURSOR_REQUIRESEEK state before
+ ** returning.
+ **
+ ** Or, if the current delete will not cause a rebalance, then the cursor
+ ** will be left in CURSOR_SKIPNEXT state pointing to the entry immediately
+ ** before or after the deleted entry. In this case set bSkipnext to true. */
+ if( bPreserve ){
+ if( !pPage->leaf
+ || (pPage->nFree+cellSizePtr(pPage,pCell)+2)>(int)(pBt->usableSize*2/3)
+ ){
+ /* A b-tree rebalance will be required after deleting this entry.
+ ** Save the cursor key. */
+ rc = saveCursorKey(pCur);
+ if( rc ) return rc;
+ }else{
+ bSkipnext = 1;
+ }
+ }
+
+ /* 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 = sqlite3PagerWrite(pPage->pDbPage);
if( rc ) return rc;
- rc = clearCell(pPage, pCell);
- dropCell(pPage, iCellIdx, cellSizePtr(pPage, pCell), &rc);
+ rc = clearCell(pPage, pCell, &szCell);
+ dropCell(pPage, iCellIdx, szCell, &rc);
if( rc ) return rc;
/* If the cell deleted was not located on a leaf page, then the cursor
@@ -55329,12 +63307,11 @@ SQLITE_PRIVATE int sqlite3BtreeDelete(BtCursor *pCur){
unsigned char *pTmp;
pCell = findCell(pLeaf, pLeaf->nCell-1);
- nCell = cellSizePtr(pLeaf, pCell);
+ if( pCell<&pLeaf->aData[4] ) return SQLITE_CORRUPT_BKPT;
+ nCell = pLeaf->xCellSize(pLeaf, pCell);
assert( MX_CELL_SIZE(pBt) >= nCell );
-
- allocateTempSpace(pBt);
pTmp = pBt->pTmpSpace;
-
+ assert( pTmp!=0 );
rc = sqlite3PagerWrite(pLeaf->pDbPage);
insertCell(pPage, iCellIdx, pCell-4, nCell+4, pTmp, n, &rc);
dropCell(pLeaf, pLeaf->nCell-1, nCell, &rc);
@@ -55365,7 +63342,23 @@ SQLITE_PRIVATE int sqlite3BtreeDelete(BtCursor *pCur){
}
if( rc==SQLITE_OK ){
- moveToRoot(pCur);
+ if( bSkipnext ){
+ assert( bPreserve && (pCur->iPage==iCellDepth || CORRUPT_DB) );
+ assert( pPage==pCur->apPage[pCur->iPage] );
+ assert( (pPage->nCell>0 || CORRUPT_DB) && iCellIdx<=pPage->nCell );
+ pCur->eState = CURSOR_SKIPNEXT;
+ if( iCellIdx>=pPage->nCell ){
+ pCur->skipNext = -1;
+ pCur->aiIdx[iCellDepth] = pPage->nCell-1;
+ }else{
+ pCur->skipNext = 1;
+ }
+ }else{
+ rc = moveToRoot(pCur);
+ if( bPreserve ){
+ pCur->eState = CURSOR_REQUIRESEEK;
+ }
+ }
}
return rc;
}
@@ -55423,13 +63416,14 @@ static int btreeCreateTable(Btree *p, int *piTable, int createTabFlags){
pgnoRoot==PENDING_BYTE_PAGE(pBt) ){
pgnoRoot++;
}
- assert( pgnoRoot>=3 );
+ assert( pgnoRoot>=3 || CORRUPT_DB );
+ testcase( 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);
+ rc = allocateBtreePage(pBt, &pPageMove, &pgnoMove, pgnoRoot, BTALLOC_EXACT);
if( rc!=SQLITE_OK ){
return rc;
}
@@ -55444,7 +63438,14 @@ static int btreeCreateTable(Btree *p, int *piTable, int createTabFlags){
u8 eType = 0;
Pgno iPtrPage = 0;
+ /* Save the positions of any open cursors. This is required in
+ ** case they are holding a reference to an xFetch reference
+ ** corresponding to page pgnoRoot. */
+ rc = saveAllCursors(pBt, 0, 0);
releasePage(pPageMove);
+ if( rc!=SQLITE_OK ){
+ return rc;
+ }
/* Move the page currently at pgnoRoot to pgnoMove. */
rc = btreeGetPage(pBt, pgnoRoot, &pRoot, 0);
@@ -55538,37 +63539,46 @@ static int clearDatabasePage(
int rc;
unsigned char *pCell;
int i;
+ int hdr;
+ u16 szCell;
assert( sqlite3_mutex_held(pBt->mutex) );
if( pgno>btreePagecount(pBt) ){
return SQLITE_CORRUPT_BKPT;
}
-
- rc = getAndInitPage(pBt, pgno, &pPage);
+ rc = getAndInitPage(pBt, pgno, &pPage, 0, 0);
if( rc ) return rc;
+ if( pPage->bBusy ){
+ rc = SQLITE_CORRUPT_BKPT;
+ goto cleardatabasepage_out;
+ }
+ pPage->bBusy = 1;
+ hdr = pPage->hdrOffset;
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);
+ rc = clearCell(pPage, pCell, &szCell);
if( rc ) goto cleardatabasepage_out;
}
if( !pPage->leaf ){
- rc = clearDatabasePage(pBt, get4byte(&pPage->aData[8]), 1, pnChange);
+ rc = clearDatabasePage(pBt, get4byte(&pPage->aData[hdr+8]), 1, pnChange);
if( rc ) goto cleardatabasepage_out;
}else if( pnChange ){
- assert( pPage->intKey );
+ assert( pPage->intKey || CORRUPT_DB );
+ testcase( !pPage->intKey );
*pnChange += pPage->nCell;
}
if( freePageFlag ){
freePage(pPage, &rc);
}else if( (rc = sqlite3PagerWrite(pPage->pDbPage))==0 ){
- zeroPage(pPage, pPage->aData[0] | PTF_LEAF);
+ zeroPage(pPage, pPage->aData[hdr] | PTF_LEAF);
}
cleardatabasepage_out:
+ pPage->bBusy = 0;
releasePage(pPage);
return rc;
}
@@ -55606,6 +63616,15 @@ SQLITE_PRIVATE int sqlite3BtreeClearTable(Btree *p, int iTable, int *pnChange){
}
/*
+** Delete all information from the single table that pCur is open on.
+**
+** This routine only work for pCur on an ephemeral table.
+*/
+SQLITE_PRIVATE int sqlite3BtreeClearTableOfCursor(BtCursor *pCur){
+ return sqlite3BtreeClearTable(pCur->pBtree, pCur->pgnoRoot, 0);
+}
+
+/*
** 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.
@@ -55749,6 +63768,13 @@ SQLITE_PRIVATE int sqlite3BtreeDropTable(Btree *p, int iTable, int *piMoved){
** 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].
+**
+** This routine treats Meta[BTREE_DATA_VERSION] as a special case. Instead
+** of reading the value out of the header, it instead loads the "DataVersion"
+** from the pager. The BTREE_DATA_VERSION value is not actually stored in the
+** database file. It is a number computed by the pager. But its access
+** pattern is the same as header meta values, and so it is convenient to
+** read it from this routine.
*/
SQLITE_PRIVATE void sqlite3BtreeGetMeta(Btree *p, int idx, u32 *pMeta){
BtShared *pBt = p->pBt;
@@ -55759,7 +63785,11 @@ SQLITE_PRIVATE void sqlite3BtreeGetMeta(Btree *p, int idx, u32 *pMeta){
assert( pBt->pPage1 );
assert( idx>=0 && idx<=15 );
- *pMeta = get4byte(&pBt->pPage1->aData[36 + idx*4]);
+ if( idx==BTREE_DATA_VERSION ){
+ *pMeta = sqlite3PagerDataVersion(pBt->pPager) + p->iDataVersion;
+ }else{
+ *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. */
@@ -55850,7 +63880,7 @@ SQLITE_PRIVATE int sqlite3BtreeCount(BtCursor *pCur, i64 *pnEntry){
if( pCur->iPage==0 ){
/* All pages of the b-tree have been visited. Return successfully. */
*pnEntry = nEntry;
- return SQLITE_OK;
+ return moveToRoot(pCur);
}
moveToParent(pCur);
}while ( pCur->aiIdx[pCur->iPage]>=pCur->apPage[pCur->iPage]->nCell );
@@ -55889,7 +63919,6 @@ SQLITE_PRIVATE Pager *sqlite3BtreePager(Btree *p){
*/
static void checkAppendMsg(
IntegrityCk *pCheck,
- char *zMsg1,
const char *zFormat,
...
){
@@ -55901,12 +63930,12 @@ static void checkAppendMsg(
if( pCheck->errMsg.nChar ){
sqlite3StrAccumAppend(&pCheck->errMsg, "\n", 1);
}
- if( zMsg1 ){
- sqlite3StrAccumAppend(&pCheck->errMsg, zMsg1, -1);
+ if( pCheck->zPfx ){
+ sqlite3XPrintf(&pCheck->errMsg, 0, pCheck->zPfx, pCheck->v1, pCheck->v2);
}
sqlite3VXPrintf(&pCheck->errMsg, 1, zFormat, ap);
va_end(ap);
- if( pCheck->errMsg.mallocFailed ){
+ if( pCheck->errMsg.accError==STRACCUM_NOMEM ){
pCheck->mallocFailed = 1;
}
}
@@ -55935,19 +63964,19 @@ static void setPageReferenced(IntegrityCk *pCheck, Pgno iPg){
/*
** 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
+** Return 1 if there are 2 or 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){
+static int checkRef(IntegrityCk *pCheck, Pgno iPage){
if( iPage==0 ) return 1;
if( iPage>pCheck->nPage ){
- checkAppendMsg(pCheck, zContext, "invalid page number %d", iPage);
+ checkAppendMsg(pCheck, "invalid page number %d", iPage);
return 1;
}
if( getPageReferenced(pCheck, iPage) ){
- checkAppendMsg(pCheck, zContext, "2nd reference to page %d", iPage);
+ checkAppendMsg(pCheck, "2nd reference to page %d", iPage);
return 1;
}
setPageReferenced(pCheck, iPage);
@@ -55964,8 +63993,7 @@ 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) */
+ Pgno iParent /* Expected pointer map parent page number */
){
int rc;
u8 ePtrmapType;
@@ -55974,12 +64002,12 @@ static void checkPtrmap(
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);
+ checkAppendMsg(pCheck, "Failed to read ptrmap key=%d", iChild);
return;
}
if( ePtrmapType!=eType || iPtrmapParent!=iParent ){
- checkAppendMsg(pCheck, zContext,
+ checkAppendMsg(pCheck,
"Bad ptr map entry key=%d expected=(%d,%d) got=(%d,%d)",
iChild, eType, iParent, ePtrmapType, iPtrmapParent);
}
@@ -55994,8 +64022,7 @@ 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 N /* Expected number of pages in the list */
){
int i;
int expected = N;
@@ -56004,14 +64031,14 @@ static void checkList(
DbPage *pOvflPage;
unsigned char *pOvflData;
if( iPage<1 ){
- checkAppendMsg(pCheck, zContext,
+ checkAppendMsg(pCheck,
"%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);
+ if( checkRef(pCheck, iPage) ) break;
+ if( sqlite3PagerGet(pCheck->pPager, (Pgno)iPage, &pOvflPage, 0) ){
+ checkAppendMsg(pCheck, "failed to get page %d", iPage);
break;
}
pOvflData = (unsigned char *)sqlite3PagerGetData(pOvflPage);
@@ -56019,11 +64046,11 @@ static void checkList(
int n = get4byte(&pOvflData[4]);
#ifndef SQLITE_OMIT_AUTOVACUUM
if( pCheck->pBt->autoVacuum ){
- checkPtrmap(pCheck, iPage, PTRMAP_FREEPAGE, 0, zContext);
+ checkPtrmap(pCheck, iPage, PTRMAP_FREEPAGE, 0);
}
#endif
if( n>(int)pCheck->pBt->usableSize/4-2 ){
- checkAppendMsg(pCheck, zContext,
+ checkAppendMsg(pCheck,
"freelist leaf count too big on page %d", iPage);
N--;
}else{
@@ -56031,10 +64058,10 @@ static void checkList(
Pgno iFreePage = get4byte(&pOvflData[8+i*4]);
#ifndef SQLITE_OMIT_AUTOVACUUM
if( pCheck->pBt->autoVacuum ){
- checkPtrmap(pCheck, iFreePage, PTRMAP_FREEPAGE, 0, zContext);
+ checkPtrmap(pCheck, iFreePage, PTRMAP_FREEPAGE, 0);
}
#endif
- checkRef(pCheck, iFreePage, zContext);
+ checkRef(pCheck, iFreePage);
}
N -= n;
}
@@ -56047,16 +64074,71 @@ static void checkList(
*/
if( pCheck->pBt->autoVacuum && N>0 ){
i = get4byte(pOvflData);
- checkPtrmap(pCheck, i, PTRMAP_OVERFLOW2, iPage, zContext);
+ checkPtrmap(pCheck, i, PTRMAP_OVERFLOW2, iPage);
}
}
#endif
iPage = get4byte(pOvflData);
sqlite3PagerUnref(pOvflPage);
+
+ if( isFreeList && N<(iPage!=0) ){
+ checkAppendMsg(pCheck, "free-page count in header is too small");
+ }
}
}
#endif /* SQLITE_OMIT_INTEGRITY_CHECK */
+/*
+** An implementation of a min-heap.
+**
+** aHeap[0] is the number of elements on the heap. aHeap[1] is the
+** root element. The daughter nodes of aHeap[N] are aHeap[N*2]
+** and aHeap[N*2+1].
+**
+** The heap property is this: Every node is less than or equal to both
+** of its daughter nodes. A consequence of the heap property is that the
+** root node aHeap[1] is always the minimum value currently in the heap.
+**
+** The btreeHeapInsert() routine inserts an unsigned 32-bit number onto
+** the heap, preserving the heap property. The btreeHeapPull() routine
+** removes the root element from the heap (the minimum value in the heap)
+** and then moves other nodes around as necessary to preserve the heap
+** property.
+**
+** This heap is used for cell overlap and coverage testing. Each u32
+** entry represents the span of a cell or freeblock on a btree page.
+** The upper 16 bits are the index of the first byte of a range and the
+** lower 16 bits are the index of the last byte of that range.
+*/
+static void btreeHeapInsert(u32 *aHeap, u32 x){
+ u32 j, i = ++aHeap[0];
+ aHeap[i] = x;
+ while( (j = i/2)>0 && aHeap[j]>aHeap[i] ){
+ x = aHeap[j];
+ aHeap[j] = aHeap[i];
+ aHeap[i] = x;
+ i = j;
+ }
+}
+static int btreeHeapPull(u32 *aHeap, u32 *pOut){
+ u32 j, i, x;
+ if( (x = aHeap[0])==0 ) return 0;
+ *pOut = aHeap[1];
+ aHeap[1] = aHeap[x];
+ aHeap[x] = 0xffffffff;
+ aHeap[0]--;
+ i = 1;
+ while( (j = i*2)<=aHeap[0] ){
+ if( aHeap[j]>aHeap[j+1] ) j++;
+ if( aHeap[i]<aHeap[j] ) break;
+ x = aHeap[i];
+ aHeap[i] = aHeap[j];
+ aHeap[j] = x;
+ i = j;
+ }
+ return 1;
+}
+
#ifndef SQLITE_OMIT_INTEGRITY_CHECK
/*
** Do various sanity checks on a single page of a tree. Return
@@ -56067,221 +64149,257 @@ static void checkList(
**
** 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.
+** 2. Make sure integer cell keys are in order.
+** 3. Check the integrity of overflow pages.
+** 4. Recursively call checkTreePage on all children.
+** 5. Verify that the depth of all children is the same.
*/
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
+ i64 *piMinKey, /* Write minimum integer primary key here */
+ i64 maxKey /* Error if integer primary key greater than this */
){
- 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);
+ MemPage *pPage = 0; /* The page being analyzed */
+ int i; /* Loop counter */
+ int rc; /* Result code from subroutine call */
+ int depth = -1, d2; /* Depth of a subtree */
+ int pgno; /* Page number */
+ int nFrag; /* Number of fragmented bytes on the page */
+ int hdr; /* Offset to the page header */
+ int cellStart; /* Offset to the start of the cell pointer array */
+ int nCell; /* Number of cells */
+ int doCoverageCheck = 1; /* True if cell coverage checking should be done */
+ int keyCanBeEqual = 1; /* True if IPK can be equal to maxKey
+ ** False if IPK must be strictly less than maxKey */
+ u8 *data; /* Page content */
+ u8 *pCell; /* Cell content */
+ u8 *pCellIdx; /* Next element of the cell pointer array */
+ BtShared *pBt; /* The BtShared object that owns pPage */
+ u32 pc; /* Address of a cell */
+ u32 usableSize; /* Usable size of the page */
+ u32 contentOffset; /* Offset to the start of the cell content area */
+ u32 *heap = 0; /* Min-heap used for checking cell coverage */
+ u32 x, prev = 0; /* Next and previous entry on the min-heap */
+ const char *saved_zPfx = pCheck->zPfx;
+ int saved_v1 = pCheck->v1;
+ int saved_v2 = pCheck->v2;
+ u8 savedIsInit = 0;
/* Check that the page exists
*/
pBt = pCheck->pBt;
usableSize = pBt->usableSize;
if( iPage==0 ) return 0;
- if( checkRef(pCheck, iPage, zParentContext) ) return 0;
+ if( checkRef(pCheck, iPage) ) return 0;
+ pCheck->zPfx = "Page %d: ";
+ pCheck->v1 = iPage;
if( (rc = btreeGetPage(pBt, (Pgno)iPage, &pPage, 0))!=0 ){
- checkAppendMsg(pCheck, zContext,
+ checkAppendMsg(pCheck,
"unable to get the page. error code=%d", rc);
- return 0;
+ goto end_of_check;
}
/* Clear MemPage.isInit to make sure the corruption detection code in
** btreeInitPage() is executed. */
+ savedIsInit = pPage->isInit;
pPage->isInit = 0;
if( (rc = btreeInitPage(pPage))!=0 ){
assert( rc==SQLITE_CORRUPT ); /* The only possible error from InitPage */
- checkAppendMsg(pCheck, zContext,
+ checkAppendMsg(pCheck,
"btreeInitPage() returns error code %d", rc);
- releasePage(pPage);
- return 0;
+ goto end_of_check;
}
+ data = pPage->aData;
+ hdr = pPage->hdrOffset;
- /* Check out all the cells.
- */
- depth = 0;
- for(i=0; i<pPage->nCell && pCheck->mxErr; i++){
- u8 *pCell;
- u32 sz;
+ /* Set up for cell analysis */
+ pCheck->zPfx = "On tree page %d cell %d: ";
+ contentOffset = get2byteNotZero(&data[hdr+5]);
+ assert( contentOffset<=usableSize ); /* Enforced by btreeInitPage() */
+
+ /* EVIDENCE-OF: R-37002-32774 The two-byte integer at offset 3 gives the
+ ** number of cells on the page. */
+ nCell = get2byte(&data[hdr+3]);
+ assert( pPage->nCell==nCell );
+
+ /* EVIDENCE-OF: R-23882-45353 The cell pointer array of a b-tree page
+ ** immediately follows the b-tree page header. */
+ cellStart = hdr + 12 - 4*pPage->leaf;
+ assert( pPage->aCellIdx==&data[cellStart] );
+ pCellIdx = &data[cellStart + 2*(nCell-1)];
+
+ if( !pPage->leaf ){
+ /* Analyze the right-child page of internal pages */
+ pgno = get4byte(&data[hdr+8]);
+#ifndef SQLITE_OMIT_AUTOVACUUM
+ if( pBt->autoVacuum ){
+ pCheck->zPfx = "On page %d at right child: ";
+ checkPtrmap(pCheck, pgno, PTRMAP_BTREE, iPage);
+ }
+#endif
+ depth = checkTreePage(pCheck, pgno, &maxKey, maxKey);
+ keyCanBeEqual = 0;
+ }else{
+ /* For leaf pages, the coverage check will occur in the same loop
+ ** as the other cell checks, so initialize the heap. */
+ heap = pCheck->heap;
+ heap[0] = 0;
+ }
+
+ /* EVIDENCE-OF: R-02776-14802 The cell pointer array consists of K 2-byte
+ ** integer offsets to the cell contents. */
+ for(i=nCell-1; i>=0 && pCheck->mxErr; i--){
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);
+ /* Check cell size */
+ pCheck->v2 = i;
+ assert( pCellIdx==&data[cellStart + i*2] );
+ pc = get2byteAligned(pCellIdx);
+ pCellIdx -= 2;
+ if( pc<contentOffset || pc>usableSize-4 ){
+ checkAppendMsg(pCheck, "Offset %d out of range %d..%d",
+ pc, contentOffset, usableSize-4);
+ doCoverageCheck = 0;
+ continue;
+ }
+ pCell = &data[pc];
+ pPage->xParseCell(pPage, pCell, &info);
+ if( pc+info.nSize>usableSize ){
+ checkAppendMsg(pCheck, "Extends off end of page");
+ doCoverageCheck = 0;
+ continue;
+ }
+
+ /* Check for integer primary key out of range */
+ if( pPage->intKey ){
+ if( keyCanBeEqual ? (info.nKey > maxKey) : (info.nKey >= maxKey) ){
+ checkAppendMsg(pCheck, "Rowid %lld out of order", info.nKey);
}
- nMaxKey = info.nKey;
+ maxKey = 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]);
+
+ /* Check the content overflow list */
+ if( info.nPayload>info.nLocal ){
+ int nPage; /* Number of pages on the overflow chain */
+ Pgno pgnoOvfl; /* First page of the overflow chain */
+ assert( pc + info.nSize - 4 <= usableSize );
+ nPage = (info.nPayload - info.nLocal + usableSize - 5)/(usableSize - 4);
+ pgnoOvfl = get4byte(&pCell[info.nSize - 4]);
#ifndef SQLITE_OMIT_AUTOVACUUM
if( pBt->autoVacuum ){
- checkPtrmap(pCheck, pgnoOvfl, PTRMAP_OVERFLOW1, iPage, zContext);
+ checkPtrmap(pCheck, pgnoOvfl, PTRMAP_OVERFLOW1, iPage);
}
#endif
- checkList(pCheck, 0, pgnoOvfl, nPage, zContext);
+ checkList(pCheck, 0, pgnoOvfl, nPage);
}
- /* Check sanity of left child page.
- */
if( !pPage->leaf ){
+ /* Check sanity of left child page for internal pages */
pgno = get4byte(pCell);
#ifndef SQLITE_OMIT_AUTOVACUUM
if( pBt->autoVacuum ){
- checkPtrmap(pCheck, pgno, PTRMAP_BTREE, iPage, zContext);
+ checkPtrmap(pCheck, pgno, PTRMAP_BTREE, iPage);
}
#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);
+ d2 = checkTreePage(pCheck, pgno, &maxKey, maxKey);
+ keyCanBeEqual = 0;
+ if( d2!=depth ){
+ checkAppendMsg(pCheck, "Child page depth differs");
+ depth = d2;
}
+ }else{
+ /* Populate the coverage-checking heap for leaf pages */
+ btreeHeapInsert(heap, (pc<<16)|(pc+info.nSize-1));
}
}
+ *piMinKey = maxKey;
/* 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]++;
+ pCheck->zPfx = 0;
+ if( doCoverageCheck && pCheck->mxErr>0 ){
+ /* For leaf pages, the min-heap has already been initialized and the
+ ** cells have already been inserted. But for internal pages, that has
+ ** not yet been done, so do it now */
+ if( !pPage->leaf ){
+ heap = pCheck->heap;
+ heap[0] = 0;
+ for(i=nCell-1; i>=0; i--){
+ u32 size;
+ pc = get2byteAligned(&data[cellStart+i*2]);
+ size = pPage->xCellSize(pPage, &data[pc]);
+ btreeHeapInsert(heap, (pc<<16)|(pc+size-1));
}
}
+ /* Add the freeblocks to the min-heap
+ **
+ ** EVIDENCE-OF: R-20690-50594 The second field of the b-tree page header
+ ** is the offset of the first freeblock, or zero if there are no
+ ** freeblocks on the page.
+ */
i = get2byte(&data[hdr+1]);
while( i>0 ){
int size, j;
- assert( i<=usableSize-4 ); /* Enforced by btreeInitPage() */
+ assert( (u32)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]++;
+ assert( (u32)(i+size)<=usableSize ); /* Enforced by btreeInitPage() */
+ btreeHeapInsert(heap, (((u32)i)<<16)|(i+size-1));
+ /* EVIDENCE-OF: R-58208-19414 The first 2 bytes of a freeblock are a
+ ** big-endian integer which is the offset in the b-tree page of the next
+ ** freeblock in the chain, or zero if the freeblock is the last on the
+ ** chain. */
j = get2byte(&data[i]);
+ /* EVIDENCE-OF: R-06866-39125 Freeblocks are always connected in order of
+ ** increasing offset. */
assert( j==0 || j>i+size ); /* Enforced by btreeInitPage() */
- assert( j<=usableSize-4 ); /* Enforced by btreeInitPage() */
+ assert( (u32)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);
+ /* Analyze the min-heap looking for overlap between cells and/or
+ ** freeblocks, and counting the number of untracked bytes in nFrag.
+ **
+ ** Each min-heap entry is of the form: (start_address<<16)|end_address.
+ ** There is an implied first entry the covers the page header, the cell
+ ** pointer index, and the gap between the cell pointer index and the start
+ ** of cell content.
+ **
+ ** The loop below pulls entries from the min-heap in order and compares
+ ** the start_address against the previous end_address. If there is an
+ ** overlap, that means bytes are used multiple times. If there is a gap,
+ ** that gap is added to the fragmentation count.
+ */
+ nFrag = 0;
+ prev = contentOffset - 1; /* Implied first min-heap entry */
+ while( btreeHeapPull(heap,&x) ){
+ if( (prev&0xffff)>=(x>>16) ){
+ checkAppendMsg(pCheck,
+ "Multiple uses for byte %u of page %d", x>>16, iPage);
break;
+ }else{
+ nFrag += (x>>16) - (prev&0xffff) - 1;
+ prev = x;
}
}
- if( cnt!=data[hdr+7] ){
- checkAppendMsg(pCheck, 0,
+ nFrag += usableSize - (prev&0xffff) - 1;
+ /* EVIDENCE-OF: R-43263-13491 The total number of bytes in all fragments
+ ** is stored in the fifth field of the b-tree page header.
+ ** EVIDENCE-OF: R-07161-27322 The one-byte integer at offset 7 gives the
+ ** number of fragmented free bytes within the cell content area.
+ */
+ if( heap[0]==0 && nFrag!=data[hdr+7] ){
+ checkAppendMsg(pCheck,
"Fragmentation of %d bytes reported as %d on page %d",
- cnt, data[hdr+7], iPage);
+ nFrag, data[hdr+7], iPage);
}
}
- sqlite3PageFree(hit);
+
+end_of_check:
+ if( !doCoverageCheck ) pPage->isInit = savedIsInit;
releasePage(pPage);
+ pCheck->zPfx = saved_zPfx;
+ pCheck->v1 = saved_v1;
+ pCheck->v2 = saved_v2;
return depth+1;
}
#endif /* SQLITE_OMIT_INTEGRITY_CHECK */
@@ -56308,60 +64426,74 @@ SQLITE_PRIVATE char *sqlite3BtreeIntegrityCheck(
int *pnErr /* Write number of errors seen to this variable */
){
Pgno i;
- int nRef;
IntegrityCk sCheck;
BtShared *pBt = p->pBt;
+ int savedDbFlags = pBt->db->flags;
char zErr[100];
+ VVA_ONLY( int nRef );
sqlite3BtreeEnter(p);
assert( p->inTrans>TRANS_NONE && pBt->inTransaction>TRANS_NONE );
- nRef = sqlite3PagerRefcount(pBt->pPager);
+ assert( (nRef = sqlite3PagerRefcount(pBt->pPager))>=0 );
sCheck.pBt = pBt;
sCheck.pPager = pBt->pPager;
sCheck.nPage = btreePagecount(sCheck.pBt);
sCheck.mxErr = mxErr;
sCheck.nErr = 0;
sCheck.mallocFailed = 0;
- *pnErr = 0;
+ sCheck.zPfx = 0;
+ sCheck.v1 = 0;
+ sCheck.v2 = 0;
+ sCheck.aPgRef = 0;
+ sCheck.heap = 0;
+ sqlite3StrAccumInit(&sCheck.errMsg, 0, zErr, sizeof(zErr), SQLITE_MAX_LENGTH);
if( sCheck.nPage==0 ){
- sqlite3BtreeLeave(p);
- return 0;
+ goto integrity_ck_cleanup;
}
sCheck.aPgRef = sqlite3MallocZero((sCheck.nPage / 8)+ 1);
if( !sCheck.aPgRef ){
- *pnErr = 1;
- sqlite3BtreeLeave(p);
- return 0;
+ sCheck.mallocFailed = 1;
+ goto integrity_ck_cleanup;
}
+ sCheck.heap = (u32*)sqlite3PageMalloc( pBt->pageSize );
+ if( sCheck.heap==0 ){
+ sCheck.mallocFailed = 1;
+ goto integrity_ck_cleanup;
+ }
+
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
*/
+ sCheck.zPfx = "Main freelist: ";
checkList(&sCheck, 1, get4byte(&pBt->pPage1->aData[32]),
- get4byte(&pBt->pPage1->aData[36]), "Main freelist: ");
+ get4byte(&pBt->pPage1->aData[36]));
+ sCheck.zPfx = 0;
/* Check all the tables.
*/
+ testcase( pBt->db->flags & SQLITE_CellSizeCk );
+ pBt->db->flags &= ~SQLITE_CellSizeCk;
for(i=0; (int)i<nRoot && sCheck.mxErr; i++){
+ i64 notUsed;
if( aRoot[i]==0 ) continue;
#ifndef SQLITE_OMIT_AUTOVACUUM
if( pBt->autoVacuum && aRoot[i]>1 ){
- checkPtrmap(&sCheck, aRoot[i], PTRMAP_ROOTPAGE, 0, 0);
+ checkPtrmap(&sCheck, aRoot[i], PTRMAP_ROOTPAGE, 0);
}
#endif
- checkTreePage(&sCheck, aRoot[i], "List of tree roots: ", NULL, NULL);
+ checkTreePage(&sCheck, aRoot[i], &notUsed, LARGEST_INT64);
}
+ pBt->db->flags = savedDbFlags;
/* 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);
+ checkAppendMsg(&sCheck, "Page %d is never used", i);
}
#else
/* If the database supports auto-vacuum, make sure no tables contain
@@ -56369,37 +64501,29 @@ SQLITE_PRIVATE char *sqlite3BtreeIntegrityCheck(
*/
if( getPageReferenced(&sCheck, i)==0 &&
(PTRMAP_PAGENO(pBt, i)!=i || !pBt->autoVacuum) ){
- checkAppendMsg(&sCheck, 0, "Page %d is never used", i);
+ checkAppendMsg(&sCheck, "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);
+ checkAppendMsg(&sCheck, "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);
+integrity_ck_cleanup:
+ sqlite3PageFree(sCheck.heap);
sqlite3_free(sCheck.aPgRef);
if( sCheck.mallocFailed ){
sqlite3StrAccumReset(&sCheck.errMsg);
- *pnErr = sCheck.nErr+1;
- return 0;
+ sCheck.nErr++;
}
*pnErr = sCheck.nErr;
if( sCheck.nErr==0 ) sqlite3StrAccumReset(&sCheck.errMsg);
+ /* Make sure this analysis did not leave any unref() pages. */
+ assert( nRef==sqlite3PagerRefcount(pBt->pPager) );
+ sqlite3BtreeLeave(p);
return sqlite3StrAccumFinish(&sCheck.errMsg);
}
#endif /* SQLITE_OMIT_INTEGRITY_CHECK */
@@ -56564,7 +64688,7 @@ SQLITE_PRIVATE int sqlite3BtreePutData(BtCursor *pCsr, u32 offset, u32 amt, void
int rc;
assert( cursorHoldsMutex(pCsr) );
assert( sqlite3_mutex_held(pCsr->pBtree->db->mutex) );
- assert( pCsr->isIncrblobHandle );
+ assert( pCsr->curFlags & BTCF_Incrblob );
rc = restoreCursorPosition(pCsr);
if( rc!=SQLITE_OK ){
@@ -56575,6 +64699,17 @@ SQLITE_PRIVATE int sqlite3BtreePutData(BtCursor *pCsr, u32 offset, u32 amt, void
return SQLITE_ABORT;
}
+ /* Save the positions of all other cursors open on this table. This is
+ ** required in case any of them are holding references to an xFetch
+ ** version of the b-tree page modified by the accessPayload call below.
+ **
+ ** Note that pCsr must be open on a INTKEY table and saveCursorPosition()
+ ** and hence saveAllCursors() cannot fail on a BTREE_INTKEY table, hence
+ ** saveAllCursors can only return SQLITE_OK.
+ */
+ VVA_ONLY(rc =) saveAllCursors(pCsr->pBt, pCsr->pgnoRoot, pCsr);
+ assert( rc==SQLITE_OK );
+
/* Check some assumptions:
** (a) the cursor is open for writing,
** (b) there is a read/write transaction open,
@@ -56582,7 +64717,7 @@ SQLITE_PRIVATE int sqlite3BtreePutData(BtCursor *pCsr, u32 offset, u32 amt, void
** (d) there are no conflicting read-locks, and
** (e) the cursor points at a valid row of an intKey table.
*/
- if( !pCsr->wrFlag ){
+ if( (pCsr->curFlags & BTCF_WriteFlag)==0 ){
return SQLITE_READONLY;
}
assert( (pCsr->pBt->btsFlags & BTS_READ_ONLY)==0
@@ -56595,20 +64730,11 @@ SQLITE_PRIVATE int sqlite3BtreePutData(BtCursor *pCsr, u32 offset, u32 amt, void
}
/*
-** 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()).
+** Mark this cursor as an incremental blob cursor.
*/
-SQLITE_PRIVATE void sqlite3BtreeCacheOverflow(BtCursor *pCur){
- assert( cursorHoldsMutex(pCur) );
- assert( sqlite3_mutex_held(pCur->pBtree->db->mutex) );
- invalidateOverflowCache(pCur);
- pCur->isIncrblobHandle = 1;
+SQLITE_PRIVATE void sqlite3BtreeIncrblobCursor(BtCursor *pCur){
+ pCur->curFlags |= BTCF_Incrblob;
+ pCur->pBtree->hasIncrblobCur = 1;
}
#endif
@@ -56649,14 +64775,25 @@ SQLITE_PRIVATE int sqlite3BtreeSetVersion(Btree *pBtree, int iVersion){
}
/*
-** set the mask of hint flags for cursor pCsr. Currently the only valid
-** values are 0 and BTREE_BULKLOAD.
+** Return true if the cursor has a hint specified. This routine is
+** only used from within assert() statements
+*/
+SQLITE_PRIVATE int sqlite3BtreeCursorHasHint(BtCursor *pCsr, unsigned int mask){
+ return (pCsr->hints & mask)!=0;
+}
+
+/*
+** Return true if the given Btree is read-only.
*/
-SQLITE_PRIVATE void sqlite3BtreeCursorHints(BtCursor *pCsr, unsigned int mask){
- assert( mask==BTREE_BULKLOAD || mask==0 );
- pCsr->hints = mask;
+SQLITE_PRIVATE int sqlite3BtreeIsReadonly(Btree *p){
+ return (p->pBt->btsFlags & BTS_READ_ONLY)!=0;
}
+/*
+** Return the size of the header added to each page by this module.
+*/
+SQLITE_PRIVATE int sqlite3HeaderSizeBtree(void){ return ROUND8(sizeof(MemPage)); }
+
/************** End of btree.c ***********************************************/
/************** Begin file backup.c ******************************************/
/*
@@ -56673,12 +64810,8 @@ SQLITE_PRIVATE void sqlite3BtreeCursorHints(BtCursor *pCsr, unsigned int mask){
** 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
+/* #include "sqliteInt.h" */
+/* #include "btreeInt.h" */
/*
** Structure allocated for each backup operation.
@@ -56752,15 +64885,16 @@ static Btree *findBtree(sqlite3 *pErrorDb, sqlite3 *pDb, const char *zDb){
int rc = 0;
pParse = sqlite3StackAllocZero(pErrorDb, sizeof(*pParse));
if( pParse==0 ){
- sqlite3Error(pErrorDb, SQLITE_NOMEM, "out of memory");
+ sqlite3ErrorWithMsg(pErrorDb, SQLITE_NOMEM, "out of memory");
rc = SQLITE_NOMEM;
}else{
pParse->db = pDb;
if( sqlite3OpenTempDatabase(pParse) ){
- sqlite3Error(pErrorDb, pParse->rc, "%s", pParse->zErrMsg);
+ sqlite3ErrorWithMsg(pErrorDb, pParse->rc, "%s", pParse->zErrMsg);
rc = SQLITE_ERROR;
}
sqlite3DbFree(pErrorDb, pParse->zErrMsg);
+ sqlite3ParserReset(pParse);
sqlite3StackFree(pErrorDb, pParse);
}
if( rc ){
@@ -56769,7 +64903,7 @@ static Btree *findBtree(sqlite3 *pErrorDb, sqlite3 *pDb, const char *zDb){
}
if( i<0 ){
- sqlite3Error(pErrorDb, SQLITE_ERROR, "unknown database %s", zDb);
+ sqlite3ErrorWithMsg(pErrorDb, SQLITE_ERROR, "unknown database %s", zDb);
return 0;
}
@@ -56787,6 +64921,20 @@ static int setDestPgsz(sqlite3_backup *p){
}
/*
+** Check that there is no open read-transaction on the b-tree passed as the
+** second argument. If there is not, return SQLITE_OK. Otherwise, if there
+** is an open read-transaction, return SQLITE_ERROR and leave an error
+** message in database handle db.
+*/
+static int checkReadTransaction(sqlite3 *db, Btree *p){
+ if( sqlite3BtreeIsInReadTrans(p) ){
+ sqlite3ErrorWithMsg(db, SQLITE_ERROR, "destination database is in use");
+ return SQLITE_ERROR;
+ }
+ return SQLITE_OK;
+}
+
+/*
** 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.
@@ -56794,7 +64942,7 @@ static int setDestPgsz(sqlite3_backup *p){
** 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(
+SQLITE_API sqlite3_backup *SQLITE_STDCALL sqlite3_backup_init(
sqlite3* pDestDb, /* Database to write to */
const char *zDestDb, /* Name of database within pDestDb */
sqlite3* pSrcDb, /* Database connection to read from */
@@ -56802,6 +64950,13 @@ SQLITE_API sqlite3_backup *sqlite3_backup_init(
){
sqlite3_backup *p; /* Value to return */
+#ifdef SQLITE_ENABLE_API_ARMOR
+ if( !sqlite3SafetyCheckOk(pSrcDb)||!sqlite3SafetyCheckOk(pDestDb) ){
+ (void)SQLITE_MISUSE_BKPT;
+ return 0;
+ }
+#endif
+
/* 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
@@ -56814,7 +64969,7 @@ SQLITE_API sqlite3_backup *sqlite3_backup_init(
sqlite3_mutex_enter(pDestDb->mutex);
if( pSrcDb==pDestDb ){
- sqlite3Error(
+ sqlite3ErrorWithMsg(
pDestDb, SQLITE_ERROR, "source and destination must be distinct"
);
p = 0;
@@ -56825,7 +64980,7 @@ SQLITE_API sqlite3_backup *sqlite3_backup_init(
** sqlite3_backup_finish(). */
p = (sqlite3_backup *)sqlite3MallocZero(sizeof(sqlite3_backup));
if( !p ){
- sqlite3Error(pDestDb, SQLITE_NOMEM, 0);
+ sqlite3Error(pDestDb, SQLITE_NOMEM);
}
}
@@ -56838,12 +64993,15 @@ SQLITE_API sqlite3_backup *sqlite3_backup_init(
p->iNext = 1;
p->isAttached = 0;
- if( 0==p->pSrc || 0==p->pDest || setDestPgsz(p)==SQLITE_NOMEM ){
+ if( 0==p->pSrc || 0==p->pDest
+ || setDestPgsz(p)==SQLITE_NOMEM
+ || checkReadTransaction(pDestDb, p->pDest)!=SQLITE_OK
+ ){
/* 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.
- */
+ ** error was hit. Or there is a transaction open on the destination
+ ** database. 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;
}
@@ -56871,7 +65029,12 @@ static int isFatalError(int rc){
** page iSrcPg from the source database. Copy this data into the
** destination database.
*/
-static int backupOnePage(sqlite3_backup *p, Pgno iSrcPg, const u8 *zSrcData){
+static int backupOnePage(
+ sqlite3_backup *p, /* Backup handle */
+ Pgno iSrcPg, /* Source database page to backup */
+ const u8 *zSrcData, /* Source database page data */
+ int bUpdate /* True for an update, false otherwise */
+){
Pager * const pDestPager = sqlite3BtreePager(p->pDest);
const int nSrcPgsz = sqlite3BtreeGetPageSize(p->pSrc);
int nDestPgsz = sqlite3BtreeGetPageSize(p->pDest);
@@ -56882,7 +65045,7 @@ static int backupOnePage(sqlite3_backup *p, Pgno iSrcPg, const u8 *zSrcData){
** 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);
+ int nDestReserve = sqlite3BtreeGetOptimalReserve(p->pDest);
#endif
int rc = SQLITE_OK;
i64 iOff;
@@ -56928,7 +65091,7 @@ static int backupOnePage(sqlite3_backup *p, Pgno iSrcPg, const u8 *zSrcData){
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))
+ if( SQLITE_OK==(rc = sqlite3PagerGet(pDestPager, iDest, &pDestPg, 0))
&& SQLITE_OK==(rc = sqlite3PagerWrite(pDestPg))
){
const u8 *zIn = &zSrcData[iOff%nSrcPgsz];
@@ -56944,6 +65107,9 @@ static int backupOnePage(sqlite3_backup *p, Pgno iSrcPg, const u8 *zSrcData){
*/
memcpy(zOut, zIn, nCopy);
((u8 *)sqlite3PagerGetExtra(pDestPg))[0] = 0;
+ if( iOff==0 && bUpdate==0 ){
+ sqlite3Put4byte(&zOut[28], sqlite3BtreeLastPage(p->pSrc));
+ }
}
sqlite3PagerUnref(pDestPg);
}
@@ -56984,12 +65150,15 @@ static void attachBackupObject(sqlite3_backup *p){
/*
** Copy nPage pages from the source b-tree to the destination.
*/
-SQLITE_API int sqlite3_backup_step(sqlite3_backup *p, int nPage){
+SQLITE_API int SQLITE_STDCALL 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 */
+#ifdef SQLITE_ENABLE_API_ARMOR
+ if( p==0 ) return SQLITE_MISUSE_BKPT;
+#endif
sqlite3_mutex_enter(p->pSrcDb->mutex);
sqlite3BtreeEnter(p->pSrc);
if( p->pDestDb ){
@@ -57048,9 +65217,9 @@ SQLITE_API int sqlite3_backup_step(sqlite3_backup *p, int nPage){
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);
+ rc = sqlite3PagerGet(pSrcPager, iSrcPg, &pSrcPg,PAGER_GET_READONLY);
if( rc==SQLITE_OK ){
- rc = backupOnePage(p, iSrcPg, sqlite3PagerGetData(pSrcPg));
+ rc = backupOnePage(p, iSrcPg, sqlite3PagerGetData(pSrcPg), 0);
sqlite3PagerUnref(pSrcPg);
}
}
@@ -57113,7 +65282,6 @@ SQLITE_API int sqlite3_backup_step(sqlite3_backup *p, int nPage){
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,
@@ -57127,6 +65295,8 @@ SQLITE_API int sqlite3_backup_step(sqlite3_backup *p, int nPage){
*/
const i64 iSize = (i64)pgszSrc * (i64)nSrcPage;
sqlite3_file * const pFile = sqlite3PagerFile(pDestPager);
+ Pgno iPg;
+ int nDstPage;
i64 iOff;
i64 iEnd;
@@ -57137,13 +65307,26 @@ SQLITE_API int sqlite3_backup_step(sqlite3_backup *p, int nPage){
&& iSize>=PENDING_BYTE && iSize<=PENDING_BYTE+pgszDest
));
- /* This call ensures that all data required to recreate the original
+ /* This block 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);
+ sqlite3PagerPagecount(pDestPager, &nDstPage);
+ for(iPg=nDestTruncate; rc==SQLITE_OK && iPg<=(Pgno)nDstPage; iPg++){
+ if( iPg!=PENDING_BYTE_PAGE(p->pDest->pBt) ){
+ DbPage *pPg;
+ rc = sqlite3PagerGet(pDestPager, iPg, &pPg, 0);
+ if( rc==SQLITE_OK ){
+ rc = sqlite3PagerWrite(pPg);
+ sqlite3PagerUnref(pPg);
+ }
+ }
+ }
+ if( rc==SQLITE_OK ){
+ rc = sqlite3PagerCommitPhaseOne(pDestPager, 0, 1);
+ }
/* Write the extra pages and truncate the database file as required */
iEnd = MIN(PENDING_BYTE + pgszDest, iSize);
@@ -57154,7 +65337,7 @@ SQLITE_API int sqlite3_backup_step(sqlite3_backup *p, int nPage){
){
PgHdr *pSrcPg = 0;
const Pgno iSrcPg = (Pgno)((iOff/pgszSrc)+1);
- rc = sqlite3PagerGet(pSrcPager, iSrcPg, &pSrcPg);
+ rc = sqlite3PagerGet(pSrcPager, iSrcPg, &pSrcPg, 0);
if( rc==SQLITE_OK ){
u8 *zData = sqlite3PagerGetData(pSrcPg);
rc = sqlite3OsWrite(pFile, zData, pgszSrc, iOff);
@@ -57167,9 +65350,10 @@ SQLITE_API int sqlite3_backup_step(sqlite3_backup *p, int nPage){
/* Sync the database file to disk. */
if( rc==SQLITE_OK ){
- rc = sqlite3PagerSync(pDestPager);
+ rc = sqlite3PagerSync(pDestPager, 0);
}
}else{
+ sqlite3PagerTruncateImage(pDestPager, nDestTruncate);
rc = sqlite3PagerCommitPhaseOne(pDestPager, 0, 0);
}
@@ -57210,7 +65394,7 @@ SQLITE_API int sqlite3_backup_step(sqlite3_backup *p, int nPage){
/*
** Release all resources associated with an sqlite3_backup* handle.
*/
-SQLITE_API int sqlite3_backup_finish(sqlite3_backup *p){
+SQLITE_API int SQLITE_STDCALL 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 */
@@ -57237,14 +65421,14 @@ SQLITE_API int sqlite3_backup_finish(sqlite3_backup *p){
}
/* If a transaction is still open on the Btree, roll it back. */
- sqlite3BtreeRollback(p->pDest, SQLITE_OK);
+ sqlite3BtreeRollback(p->pDest, SQLITE_OK, 0);
/* 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 ){
+ sqlite3Error(p->pDestDb, rc);
+
+ /* Exit the mutexes and free the backup context structure. */
sqlite3LeaveMutexAndCloseZombie(p->pDestDb);
}
sqlite3BtreeLeave(p->pSrc);
@@ -57262,7 +65446,13 @@ SQLITE_API int sqlite3_backup_finish(sqlite3_backup *p){
** 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){
+SQLITE_API int SQLITE_STDCALL sqlite3_backup_remaining(sqlite3_backup *p){
+#ifdef SQLITE_ENABLE_API_ARMOR
+ if( p==0 ){
+ (void)SQLITE_MISUSE_BKPT;
+ return 0;
+ }
+#endif
return p->nRemaining;
}
@@ -57270,7 +65460,13 @@ SQLITE_API int sqlite3_backup_remaining(sqlite3_backup *p){
** 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){
+SQLITE_API int SQLITE_STDCALL sqlite3_backup_pagecount(sqlite3_backup *p){
+#ifdef SQLITE_ENABLE_API_ARMOR
+ if( p==0 ){
+ (void)SQLITE_MISUSE_BKPT;
+ return 0;
+ }
+#endif
return p->nPagecount;
}
@@ -57286,9 +65482,13 @@ SQLITE_API int sqlite3_backup_pagecount(sqlite3_backup *p){
** 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){
+static SQLITE_NOINLINE void backupUpdate(
+ sqlite3_backup *p,
+ Pgno iPage,
+ const u8 *aData
+){
+ assert( p!=0 );
+ do{
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
@@ -57298,14 +65498,17 @@ SQLITE_PRIVATE void sqlite3BackupUpdate(sqlite3_backup *pBackup, Pgno iPage, con
int rc;
assert( p->pDestDb );
sqlite3_mutex_enter(p->pDestDb->mutex);
- rc = backupOnePage(p, iPage, aData);
+ rc = backupOnePage(p, iPage, aData, 1);
sqlite3_mutex_leave(p->pDestDb->mutex);
assert( rc!=SQLITE_BUSY && rc!=SQLITE_LOCKED );
if( rc!=SQLITE_OK ){
p->rc = rc;
}
}
- }
+ }while( (p = p->pNext)!=0 );
+}
+SQLITE_PRIVATE void sqlite3BackupUpdate(sqlite3_backup *pBackup, Pgno iPage, const u8 *aData){
+ if( pBackup ) backupUpdate(pBackup, iPage, aData);
}
/*
@@ -57363,6 +65566,10 @@ SQLITE_PRIVATE int sqlite3BtreeCopyFile(Btree *pTo, Btree *pFrom){
b.pDest = pTo;
b.iNext = 1;
+#ifdef SQLITE_HAS_CODEC
+ sqlite3PagerAlignReserve(sqlite3BtreePager(pTo), sqlite3BtreePager(pFrom));
+#endif
+
/* 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
@@ -57406,6 +65613,55 @@ copy_finished:
** only within the VDBE. Interface routines refer to a Mem using the
** name sqlite_value
*/
+/* #include "sqliteInt.h" */
+/* #include "vdbeInt.h" */
+
+#ifdef SQLITE_DEBUG
+/*
+** Check invariants on a Mem object.
+**
+** This routine is intended for use inside of assert() statements, like
+** this: assert( sqlite3VdbeCheckMemInvariants(pMem) );
+*/
+SQLITE_PRIVATE int sqlite3VdbeCheckMemInvariants(Mem *p){
+ /* If MEM_Dyn is set then Mem.xDel!=0.
+ ** Mem.xDel is might not be initialized if MEM_Dyn is clear.
+ */
+ assert( (p->flags & MEM_Dyn)==0 || p->xDel!=0 );
+
+ /* MEM_Dyn may only be set if Mem.szMalloc==0. In this way we
+ ** ensure that if Mem.szMalloc>0 then it is safe to do
+ ** Mem.z = Mem.zMalloc without having to check Mem.flags&MEM_Dyn.
+ ** That saves a few cycles in inner loops. */
+ assert( (p->flags & MEM_Dyn)==0 || p->szMalloc==0 );
+
+ /* Cannot be both MEM_Int and MEM_Real at the same time */
+ assert( (p->flags & (MEM_Int|MEM_Real))!=(MEM_Int|MEM_Real) );
+
+ /* The szMalloc field holds the correct memory allocation size */
+ assert( p->szMalloc==0
+ || p->szMalloc==sqlite3DbMallocSize(p->db,p->zMalloc) );
+
+ /* If p holds a string or blob, the Mem.z must point to exactly
+ ** one of the following:
+ **
+ ** (1) Memory in Mem.zMalloc and managed by the Mem object
+ ** (2) Memory to be freed using Mem.xDel
+ ** (3) An ephemeral string or blob
+ ** (4) A static string or blob
+ */
+ if( (p->flags & (MEM_Str|MEM_Blob)) && p->n>0 ){
+ assert(
+ ((p->szMalloc>0 && p->z==p->zMalloc)? 1 : 0) +
+ ((p->flags&MEM_Dyn)!=0 ? 1 : 0) +
+ ((p->flags&MEM_Ephem)!=0 ? 1 : 0) +
+ ((p->flags&MEM_Static)!=0 ? 1 : 0) == 1
+ );
+ }
+ return 1;
+}
+#endif
+
/*
** If pMem is an object with a valid string representation, this routine
@@ -57421,7 +65677,9 @@ copy_finished:
** between formats.
*/
SQLITE_PRIVATE int sqlite3VdbeChangeEncoding(Mem *pMem, int desiredEnc){
+#ifndef SQLITE_OMIT_UTF16
int rc;
+#endif
assert( (pMem->flags&MEM_RowSet)==0 );
assert( desiredEnc==SQLITE_UTF8 || desiredEnc==SQLITE_UTF16LE
|| desiredEnc==SQLITE_UTF16BE );
@@ -57446,64 +65704,84 @@ SQLITE_PRIVATE int sqlite3VdbeChangeEncoding(Mem *pMem, int desiredEnc){
/*
** 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)
- );
+** min(n,32) bytes.
+**
+** If the bPreserve argument is true, then copy of the content of
+** pMem->z into the new allocation. pMem must be either a string or
+** blob if bPreserve is true. If bPreserve is false, any prior content
+** in pMem->z is discarded.
+*/
+SQLITE_PRIVATE SQLITE_NOINLINE int sqlite3VdbeMemGrow(Mem *pMem, int n, int bPreserve){
+ assert( sqlite3VdbeCheckMemInvariants(pMem) );
assert( (pMem->flags&MEM_RowSet)==0 );
- /* If the preserve flag is set to true, then the memory cell must already
+ /* If the bPreserve 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 ){
+ assert( bPreserve==0 || pMem->flags&(MEM_Blob|MEM_Str) );
+ testcase( bPreserve && pMem->z==0 );
+
+ assert( pMem->szMalloc==0
+ || pMem->szMalloc==sqlite3DbMallocSize(pMem->db, pMem->zMalloc) );
+ if( pMem->szMalloc<n ){
+ if( n<32 ) n = 32;
+ if( bPreserve && pMem->szMalloc>0 && pMem->z==pMem->zMalloc ){
pMem->z = pMem->zMalloc = sqlite3DbReallocOrFree(pMem->db, pMem->z, n);
- preserve = 0;
+ bPreserve = 0;
}else{
- sqlite3DbFree(pMem->db, pMem->zMalloc);
+ if( pMem->szMalloc>0 ) sqlite3DbFree(pMem->db, pMem->zMalloc);
pMem->zMalloc = sqlite3DbMallocRaw(pMem->db, n);
}
+ if( pMem->zMalloc==0 ){
+ sqlite3VdbeMemSetNull(pMem);
+ pMem->z = 0;
+ pMem->szMalloc = 0;
+ return SQLITE_NOMEM;
+ }else{
+ pMem->szMalloc = sqlite3DbMallocSize(pMem->db, pMem->zMalloc);
+ }
}
- if( pMem->z && preserve && pMem->zMalloc && pMem->z!=pMem->zMalloc ){
+ if( bPreserve && pMem->z && pMem->z!=pMem->zMalloc ){
memcpy(pMem->zMalloc, pMem->z, pMem->n);
}
- if( pMem->flags&MEM_Dyn && pMem->xDel ){
- assert( pMem->xDel!=SQLITE_DYNAMIC );
+ if( (pMem->flags&MEM_Dyn)!=0 ){
+ assert( pMem->xDel!=0 && 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->flags &= ~(MEM_Dyn|MEM_Ephem|MEM_Static);
+ return SQLITE_OK;
+}
+
+/*
+** Change the pMem->zMalloc allocation to be at least szNew bytes.
+** If pMem->zMalloc already meets or exceeds the requested size, this
+** routine is a no-op.
+**
+** Any prior string or blob content in the pMem object may be discarded.
+** The pMem->xDel destructor is called, if it exists. Though MEM_Str
+** and MEM_Blob values may be discarded, MEM_Int, MEM_Real, and MEM_Null
+** values are preserved.
+**
+** Return SQLITE_OK on success or an error code (probably SQLITE_NOMEM)
+** if unable to complete the resizing.
+*/
+SQLITE_PRIVATE int sqlite3VdbeMemClearAndResize(Mem *pMem, int szNew){
+ assert( szNew>0 );
+ assert( (pMem->flags & MEM_Dyn)==0 || pMem->szMalloc==0 );
+ if( pMem->szMalloc<szNew ){
+ return sqlite3VdbeMemGrow(pMem, szNew, 0);
}
- pMem->xDel = 0;
- return (pMem->z ? SQLITE_OK : SQLITE_NOMEM);
+ assert( (pMem->flags & MEM_Dyn)==0 );
+ pMem->z = pMem->zMalloc;
+ pMem->flags &= (MEM_Null|MEM_Int|MEM_Real);
+ return SQLITE_OK;
}
/*
-** 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.
+** Change pMem so that its MEM_Str or MEM_Blob value is stored in
+** MEM.zMalloc, where it can be safely written.
**
** Return SQLITE_OK on success or SQLITE_NOMEM if malloc fails.
*/
@@ -57513,17 +65791,18 @@ SQLITE_PRIVATE int sqlite3VdbeMemMakeWriteable(Mem *pMem){
assert( (pMem->flags&MEM_RowSet)==0 );
ExpandBlob(pMem);
f = pMem->flags;
- if( (f&(MEM_Str|MEM_Blob)) && pMem->z!=pMem->zMalloc ){
+ if( (f&(MEM_Str|MEM_Blob)) && (pMem->szMalloc==0 || 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;
+ }
+ pMem->flags &= ~MEM_Ephem;
#ifdef SQLITE_DEBUG
- pMem->pScopyFrom = 0;
+ pMem->pScopyFrom = 0;
#endif
- }
return SQLITE_OK;
}
@@ -57557,15 +65836,11 @@ SQLITE_PRIVATE int sqlite3VdbeMemExpandBlob(Mem *pMem){
}
#endif
-
/*
-** Make sure the given Mem is \u0000 terminated.
+** It is already known that pMem contains an unterminated string.
+** Add the zero terminator.
*/
-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 */
- }
+static SQLITE_NOINLINE int vdbeMemAddTerminator(Mem *pMem){
if( sqlite3VdbeMemGrow(pMem, pMem->n+2, 1) ){
return SQLITE_NOMEM;
}
@@ -57576,20 +65851,34 @@ SQLITE_PRIVATE int sqlite3VdbeMemNulTerminate(Mem *pMem){
}
/*
+** Make sure the given Mem is \u0000 terminated.
+*/
+SQLITE_PRIVATE int sqlite3VdbeMemNulTerminate(Mem *pMem){
+ assert( pMem->db==0 || sqlite3_mutex_held(pMem->db->mutex) );
+ testcase( (pMem->flags & (MEM_Term|MEM_Str))==(MEM_Term|MEM_Str) );
+ testcase( (pMem->flags & (MEM_Term|MEM_Str))==0 );
+ if( (pMem->flags & (MEM_Term|MEM_Str))!=MEM_Str ){
+ return SQLITE_OK; /* Nothing to do */
+ }else{
+ return vdbeMemAddTerminator(pMem);
+ }
+}
+
+/*
** 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.
+** Existing representations MEM_Int and MEM_Real are invalidated if
+** bForce is true but are retained if bForce is false.
**
** 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.
+** user and the latter is an internal programming error.
*/
-SQLITE_PRIVATE int sqlite3VdbeMemStringify(Mem *pMem, int enc){
- int rc = SQLITE_OK;
+SQLITE_PRIVATE int sqlite3VdbeMemStringify(Mem *pMem, u8 enc, u8 bForce){
int fg = pMem->flags;
const int nByte = 32;
@@ -57601,11 +65890,11 @@ SQLITE_PRIVATE int sqlite3VdbeMemStringify(Mem *pMem, int enc){
assert( EIGHT_BYTE_ALIGNMENT(pMem) );
- if( sqlite3VdbeMemGrow(pMem, nByte, 0) ){
+ if( sqlite3VdbeMemClearAndResize(pMem, nByte) ){
return SQLITE_NOMEM;
}
- /* For a Real or Integer, use sqlite3_mprintf() to produce the UTF-8
+ /* For a Real or Integer, use sqlite3_snprintf() to produce the UTF-8
** string representation of the value. Then, if the required encoding
** is UTF-16le or UTF-16be do a translation.
**
@@ -57615,13 +65904,14 @@ SQLITE_PRIVATE int sqlite3VdbeMemStringify(Mem *pMem, int enc){
sqlite3_snprintf(nByte, pMem->z, "%lld", pMem->u.i);
}else{
assert( fg & MEM_Real );
- sqlite3_snprintf(nByte, pMem->z, "%!.15g", pMem->r);
+ sqlite3_snprintf(nByte, pMem->z, "%!.15g", pMem->u.r);
}
pMem->n = sqlite3Strlen30(pMem->z);
pMem->enc = SQLITE_UTF8;
pMem->flags |= MEM_Str|MEM_Term;
+ if( bForce ) pMem->flags &= ~(MEM_Int|MEM_Real);
sqlite3VdbeChangeEncoding(pMem, enc);
- return rc;
+ return SQLITE_OK;
}
/*
@@ -57636,69 +65926,96 @@ SQLITE_PRIVATE int sqlite3VdbeMemFinalize(Mem *pMem, FuncDef *pFunc){
int rc = SQLITE_OK;
if( ALWAYS(pFunc && pFunc->xFinalize) ){
sqlite3_context ctx;
+ Mem t;
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;
+ memset(&t, 0, sizeof(t));
+ t.flags = MEM_Null;
+ t.db = pMem->db;
+ ctx.pOut = &t;
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));
+ assert( (pMem->flags & MEM_Dyn)==0 );
+ if( pMem->szMalloc>0 ) sqlite3DbFree(pMem->db, pMem->zMalloc);
+ memcpy(pMem, &t, sizeof(t));
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.
+** If the memory cell contains a value that must be freed by
+** invoking the external callback in Mem.xDel, then this routine
+** will free that value. It also sets Mem.flags to MEM_Null.
+**
+** This is a helper routine for sqlite3VdbeMemSetNull() and
+** for sqlite3VdbeMemRelease(). Use those other routines as the
+** entry point for releasing Mem resources.
*/
-SQLITE_PRIVATE void sqlite3VdbeMemReleaseExternal(Mem *p){
+static SQLITE_NOINLINE void vdbeMemClearExternAndSetNull(Mem *p){
assert( p->db==0 || sqlite3_mutex_held(p->db->mutex) );
+ assert( VdbeMemDynamic(p) );
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 ){
+ testcase( p->flags & MEM_Dyn );
+ }
+ if( p->flags&MEM_Dyn ){
assert( (p->flags&MEM_RowSet)==0 );
- assert( p->xDel!=SQLITE_DYNAMIC );
+ assert( p->xDel!=SQLITE_DYNAMIC && p->xDel!=0 );
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);
+ VdbeFrame *pFrame = p->u.pFrame;
+ pFrame->pParent = pFrame->v->pDelFrame;
+ pFrame->v->pDelFrame = pFrame;
}
+ p->flags = MEM_Null;
}
/*
-** 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).
+** Release memory held by the Mem p, both external memory cleared
+** by p->xDel and memory in p->zMalloc.
+**
+** This is a helper routine invoked by sqlite3VdbeMemRelease() in
+** the unusual case where there really is memory in p that needs
+** to be freed.
*/
-SQLITE_PRIVATE void sqlite3VdbeMemRelease(Mem *p){
- VdbeMemRelease(p);
- sqlite3DbFree(p->db, p->zMalloc);
+static SQLITE_NOINLINE void vdbeMemClear(Mem *p){
+ if( VdbeMemDynamic(p) ){
+ vdbeMemClearExternAndSetNull(p);
+ }
+ if( p->szMalloc ){
+ sqlite3DbFree(p->db, p->zMalloc);
+ p->szMalloc = 0;
+ }
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.
+** Release any memory resources held by the Mem. Both the memory that is
+** free by Mem.xDel and the Mem.zMalloc allocation are freed.
**
-** 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.
+** Use this routine prior to clean up prior to abandoning a Mem, or to
+** reset a Mem back to its minimum memory utilization.
+**
+** Use sqlite3VdbeMemSetNull() to release just the Mem.xDel space
+** prior to inserting new content into the Mem.
+*/
+SQLITE_PRIVATE void sqlite3VdbeMemRelease(Mem *p){
+ assert( sqlite3VdbeCheckMemInvariants(p) );
+ if( VdbeMemDynamic(p) || p->szMalloc ){
+ vdbeMemClear(p);
+ }
+}
+
+/*
+** Convert a 64-bit IEEE double into a 64-bit signed integer.
+** If the double is out of range of a 64-bit signed integer then
+** return the closest available 64-bit signed integer.
*/
static i64 doubleToInt64(double r){
#ifdef SQLITE_OMIT_FLOATING_POINT
@@ -57715,14 +66032,10 @@ static i64 doubleToInt64(double r){
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. */
+ if( r<=(double)minInt ){
return minInt;
+ }else if( r>=(double)maxInt ){
+ return maxInt;
}else{
return (i64)r;
}
@@ -57735,7 +66048,7 @@ static i64 doubleToInt64(double r){
** 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
+** it into an 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.
@@ -57748,11 +66061,10 @@ SQLITE_PRIVATE i64 sqlite3VdbeIntValue(Mem *pMem){
if( flags & MEM_Int ){
return pMem->u.i;
}else if( flags & MEM_Real ){
- return doubleToInt64(pMem->r);
+ return doubleToInt64(pMem->u.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{
@@ -57770,7 +66082,7 @@ 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;
+ return pMem->u.r;
}else if( pMem->flags & MEM_Int ){
return (double)pMem->u.i;
}else if( pMem->flags & (MEM_Str|MEM_Blob) ){
@@ -57789,12 +66101,13 @@ SQLITE_PRIVATE double sqlite3VdbeRealValue(Mem *pMem){
** MEM_Int if we can.
*/
SQLITE_PRIVATE void sqlite3VdbeIntegerAffinity(Mem *pMem){
+ i64 ix;
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);
+ ix = doubleToInt64(pMem->u.r);
/* Only mark the value as an integer if
**
@@ -57804,19 +66117,11 @@ SQLITE_PRIVATE void sqlite3VdbeIntegerAffinity(Mem *pMem){
**
** 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;
+ ** values to wrap around.
+ */
+ if( pMem->u.r==ix && ix>SMALLEST_INT64 && ix<LARGEST_INT64 ){
+ pMem->u.i = ix;
+ MemSetTypeFlag(pMem, MEM_Int);
}
}
@@ -57841,7 +66146,7 @@ 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);
+ pMem->u.r = sqlite3VdbeRealValue(pMem);
MemSetTypeFlag(pMem, MEM_Real);
return SQLITE_OK;
}
@@ -57861,7 +66166,7 @@ SQLITE_PRIVATE int sqlite3VdbeMemNumerify(Mem *pMem){
if( 0==sqlite3Atoi64(pMem->z, &pMem->u.i, pMem->n, pMem->enc) ){
MemSetTypeFlag(pMem, MEM_Int);
}else{
- pMem->r = sqlite3VdbeRealValue(pMem);
+ pMem->u.r = sqlite3VdbeRealValue(pMem);
MemSetTypeFlag(pMem, MEM_Real);
sqlite3VdbeIntegerAffinity(pMem);
}
@@ -57872,19 +66177,83 @@ SQLITE_PRIVATE int sqlite3VdbeMemNumerify(Mem *pMem){
}
/*
+** Cast the datatype of the value in pMem according to the affinity
+** "aff". Casting is different from applying affinity in that a cast
+** is forced. In other words, the value is converted into the desired
+** affinity even if that results in loss of data. This routine is
+** used (for example) to implement the SQL "cast()" operator.
+*/
+SQLITE_PRIVATE void sqlite3VdbeMemCast(Mem *pMem, u8 aff, u8 encoding){
+ if( pMem->flags & MEM_Null ) return;
+ switch( aff ){
+ case SQLITE_AFF_BLOB: { /* Really a cast to BLOB */
+ if( (pMem->flags & MEM_Blob)==0 ){
+ sqlite3ValueApplyAffinity(pMem, SQLITE_AFF_TEXT, encoding);
+ assert( pMem->flags & MEM_Str || pMem->db->mallocFailed );
+ MemSetTypeFlag(pMem, MEM_Blob);
+ }else{
+ pMem->flags &= ~(MEM_TypeMask&~MEM_Blob);
+ }
+ break;
+ }
+ case SQLITE_AFF_NUMERIC: {
+ sqlite3VdbeMemNumerify(pMem);
+ break;
+ }
+ case SQLITE_AFF_INTEGER: {
+ sqlite3VdbeMemIntegerify(pMem);
+ break;
+ }
+ case SQLITE_AFF_REAL: {
+ sqlite3VdbeMemRealify(pMem);
+ break;
+ }
+ default: {
+ assert( aff==SQLITE_AFF_TEXT );
+ assert( MEM_Str==(MEM_Blob>>3) );
+ pMem->flags |= (pMem->flags&MEM_Blob)>>3;
+ sqlite3ValueApplyAffinity(pMem, SQLITE_AFF_TEXT, encoding);
+ assert( pMem->flags & MEM_Str || pMem->db->mallocFailed );
+ pMem->flags &= ~(MEM_Int|MEM_Real|MEM_Blob|MEM_Zero);
+ break;
+ }
+ }
+}
+
+/*
+** Initialize bulk memory to be a consistent Mem object.
+**
+** The minimum amount of initialization feasible is performed.
+*/
+SQLITE_PRIVATE void sqlite3VdbeMemInit(Mem *pMem, sqlite3 *db, u16 flags){
+ assert( (flags & ~MEM_TypeMask)==0 );
+ pMem->flags = flags;
+ pMem->db = db;
+ pMem->szMalloc = 0;
+}
+
+
+/*
** Delete any previous value and set the value stored in *pMem to NULL.
+**
+** This routine calls the Mem.xDel destructor to dispose of values that
+** require the destructor. But it preserves the Mem.zMalloc memory allocation.
+** To free all resources, use sqlite3VdbeMemRelease(), which both calls this
+** routine to invoke the destructor and deallocates Mem.zMalloc.
+**
+** Use this routine to reset the Mem prior to insert a new value.
+**
+** Use sqlite3VdbeMemRelease() to complete erase the Mem prior to abandoning it.
*/
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);
+ if( VdbeMemDynamic(pMem) ){
+ vdbeMemClearExternAndSetNull(pMem);
+ }else{
+ pMem->flags = MEM_Null;
}
- MemSetTypeFlag(pMem, MEM_Null);
- pMem->type = SQLITE_NULL;
+}
+SQLITE_PRIVATE void sqlite3ValueSetNull(sqlite3_value *p){
+ sqlite3VdbeMemSetNull((Mem*)p);
}
/*
@@ -57894,19 +66263,22 @@ SQLITE_PRIVATE void sqlite3VdbeMemSetNull(Mem *pMem){
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;
+ pMem->z = 0;
+}
-#ifdef SQLITE_OMIT_INCRBLOB
- sqlite3VdbeMemGrow(pMem, n, 0);
- if( pMem->z ){
- pMem->n = n;
- memset(pMem->z, 0, n);
- }
-#endif
+/*
+** The pMem is known to contain content that needs to be destroyed prior
+** to a value change. So invoke the destructor, then set the value to
+** a 64-bit integer.
+*/
+static SQLITE_NOINLINE void vdbeReleaseAndSetInt64(Mem *pMem, i64 val){
+ sqlite3VdbeMemSetNull(pMem);
+ pMem->u.i = val;
+ pMem->flags = MEM_Int;
}
/*
@@ -57914,10 +66286,12 @@ SQLITE_PRIVATE void sqlite3VdbeMemSetZeroBlob(Mem *pMem, int n){
** 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;
+ if( VdbeMemDynamic(pMem) ){
+ vdbeReleaseAndSetInt64(pMem, val);
+ }else{
+ pMem->u.i = val;
+ pMem->flags = MEM_Int;
+ }
}
#ifndef SQLITE_OMIT_FLOATING_POINT
@@ -57926,13 +66300,10 @@ SQLITE_PRIVATE void sqlite3VdbeMemSetInt64(Mem *pMem, i64 val){
** manifest type REAL.
*/
SQLITE_PRIVATE void sqlite3VdbeMemSetDouble(Mem *pMem, double val){
- if( sqlite3IsNaN(val) ){
- sqlite3VdbeMemSetNull(pMem);
- }else{
- sqlite3VdbeMemRelease(pMem);
- pMem->r = val;
+ sqlite3VdbeMemSetNull(pMem);
+ if( !sqlite3IsNaN(val) ){
+ pMem->u.r = val;
pMem->flags = MEM_Real;
- pMem->type = SQLITE_FLOAT;
}
}
#endif
@@ -57949,10 +66320,11 @@ SQLITE_PRIVATE void sqlite3VdbeMemSetRowSet(Mem *pMem){
pMem->zMalloc = sqlite3DbMallocRaw(db, 64);
if( db->mallocFailed ){
pMem->flags = MEM_Null;
+ pMem->szMalloc = 0;
}else{
assert( pMem->zMalloc );
- pMem->u.pRowSet = sqlite3RowSetInit(db, pMem->zMalloc,
- sqlite3DbMallocSize(db, pMem->zMalloc));
+ pMem->szMalloc = sqlite3DbMallocSize(db, pMem->zMalloc);
+ pMem->u.pRowSet = sqlite3RowSetInit(db, pMem->zMalloc, pMem->szMalloc);
assert( pMem->u.pRowSet!=0 );
pMem->flags = MEM_RowSet;
}
@@ -57976,7 +66348,7 @@ SQLITE_PRIVATE int sqlite3VdbeMemTooBig(Mem *p){
#ifdef SQLITE_DEBUG
/*
-** This routine prepares a memory cell for modication by breaking
+** This routine prepares a memory cell for modification by breaking
** its link to a shallow copy and by marking any current shallow
** copies of this cell as invalid.
**
@@ -57988,7 +66360,7 @@ SQLITE_PRIVATE void sqlite3VdbeMemAboutToChange(Vdbe *pVdbe, Mem *pMem){
Mem *pX;
for(i=1, pX=&pVdbe->aMem[1]; i<=pVdbe->nMem; i++, pX++){
if( pX->pScopyFrom==pMem ){
- pX->flags |= MEM_Invalid;
+ pX->flags |= MEM_Undefined;
pX->pScopyFrom = 0;
}
}
@@ -57996,10 +66368,6 @@ SQLITE_PRIVATE void sqlite3VdbeMemAboutToChange(Vdbe *pVdbe, Mem *pMem){
}
#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
@@ -58007,11 +66375,16 @@ SQLITE_PRIVATE void sqlite3VdbeMemAboutToChange(Vdbe *pVdbe, Mem *pMem){
** 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).
*/
+static SQLITE_NOINLINE void vdbeClrCopy(Mem *pTo, const Mem *pFrom, int eType){
+ vdbeMemClearExternAndSetNull(pTo);
+ assert( !VdbeMemDynamic(pTo) );
+ sqlite3VdbeMemShallowCopy(pTo, pFrom, eType);
+}
SQLITE_PRIVATE void sqlite3VdbeMemShallowCopy(Mem *pTo, const Mem *pFrom, int srcType){
assert( (pFrom->flags & MEM_RowSet)==0 );
- VdbeMemRelease(pTo);
+ assert( pTo->db==pFrom->db );
+ if( VdbeMemDynamic(pTo) ){ vdbeClrCopy(pTo,pFrom,srcType); return; }
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 );
@@ -58026,11 +66399,14 @@ SQLITE_PRIVATE void sqlite3VdbeMemShallowCopy(Mem *pTo, const Mem *pFrom, int sr
SQLITE_PRIVATE int sqlite3VdbeMemCopy(Mem *pTo, const Mem *pFrom){
int rc = SQLITE_OK;
+ /* The pFrom==0 case in the following assert() is when an sqlite3_value
+ ** from sqlite3_value_dup() is used as the argument
+ ** to sqlite3_result_value(). */
+ assert( pTo->db==pFrom->db || pFrom->db==0 );
assert( (pFrom->flags & MEM_RowSet)==0 );
- VdbeMemRelease(pTo);
+ if( VdbeMemDynamic(pTo) ) vdbeMemClearExternAndSetNull(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;
@@ -58055,8 +66431,7 @@ SQLITE_PRIVATE void sqlite3VdbeMemMove(Mem *pTo, Mem *pFrom){
sqlite3VdbeMemRelease(pTo);
memcpy(pTo, pFrom, sizeof(Mem));
pFrom->flags = MEM_Null;
- pFrom->xDel = 0;
- pFrom->zMalloc = 0;
+ pFrom->szMalloc = 0;
}
/*
@@ -58103,7 +66478,8 @@ SQLITE_PRIVATE int sqlite3VdbeMemSetStr(
if( nByte<0 ){
assert( enc!=0 );
if( enc==SQLITE_UTF8 ){
- for(nByte=0; nByte<=iLimit && z[nByte]; nByte++){}
+ nByte = sqlite3Strlen30(z);
+ if( nByte>iLimit ) nByte = iLimit+1;
}else{
for(nByte=0; nByte<=iLimit && (z[nByte] | z[nByte+1]); nByte+=2){}
}
@@ -58122,14 +66498,17 @@ SQLITE_PRIVATE int sqlite3VdbeMemSetStr(
if( nByte>iLimit ){
return SQLITE_TOOBIG;
}
- if( sqlite3VdbeMemGrow(pMem, nAlloc, 0) ){
+ testcase( nAlloc==0 );
+ testcase( nAlloc==31 );
+ testcase( nAlloc==32 );
+ if( sqlite3VdbeMemClearAndResize(pMem, MAX(nAlloc,32)) ){
return SQLITE_NOMEM;
}
memcpy(pMem->z, z, nAlloc);
}else if( xDel==SQLITE_DYNAMIC ){
sqlite3VdbeMemRelease(pMem);
pMem->zMalloc = pMem->z = (char *)z;
- pMem->xDel = 0;
+ pMem->szMalloc = sqlite3DbMallocSize(pMem->db, pMem->zMalloc);
}else{
sqlite3VdbeMemRelease(pMem);
pMem->z = (char *)z;
@@ -58140,7 +66519,6 @@ SQLITE_PRIVATE int sqlite3VdbeMemSetStr(
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) ){
@@ -58156,148 +66534,60 @@ SQLITE_PRIVATE int sqlite3VdbeMemSetStr(
}
/*
-** 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.
+** The pMem object must have been initialized. This routine will use
+** pMem->zMalloc to hold the content from the btree, if possible. New
+** pMem->zMalloc space will be allocated if necessary. The calling routine
+** is responsible for making sure that the pMem object is eventually
+** destroyed.
**
** 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.
*/
+static SQLITE_NOINLINE int vdbeMemFromBtreeResize(
+ BtCursor *pCur, /* Cursor pointing at record to retrieve. */
+ u32 offset, /* Offset from the start of data to return bytes from. */
+ u32 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. */
+){
+ int rc;
+ pMem->flags = MEM_Null;
+ if( SQLITE_OK==(rc = sqlite3VdbeMemClearAndResize(pMem, amt+2)) ){
+ if( key ){
+ rc = sqlite3BtreeKey(pCur, offset, amt, pMem->z);
+ }else{
+ rc = sqlite3BtreeData(pCur, offset, amt, pMem->z);
+ }
+ if( rc==SQLITE_OK ){
+ pMem->z[amt] = 0;
+ pMem->z[amt+1] = 0;
+ pMem->flags = MEM_Blob|MEM_Term;
+ pMem->n = (int)amt;
+ }else{
+ sqlite3VdbeMemRelease(pMem);
+ }
+ }
+ return rc;
+}
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. */
+ u32 offset, /* Offset from the start of data to return bytes from. */
+ u32 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 */
+ u32 available = 0; /* Number of bytes available on the local btree page */
int rc = SQLITE_OK; /* Return code */
assert( sqlite3BtreeCursorIsValid(pCur) );
+ assert( !VdbeMemDynamic(pMem) );
/* Note: the calls to BtreeKeyFetch() and DataFetch() below assert()
** that both the BtShared and database handle mutexes are held. */
@@ -58309,55 +66599,36 @@ SQLITE_PRIVATE int sqlite3VdbeMemFromBtree(
}
assert( zData!=0 );
- if( offset+amt<=available && (pMem->flags&MEM_Dyn)==0 ){
- sqlite3VdbeMemRelease(pMem);
+ if( offset+amt<=available ){
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 = (int)amt;
+ }else{
+ rc = vdbeMemFromBtreeResize(pCur, offset, amt, key, 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.
+/*
+** The pVal argument is known to be a value other than NULL.
+** Convert it into a string with encoding enc and return a pointer
+** to a zero-terminated version of that string.
*/
-SQLITE_PRIVATE const void *sqlite3ValueText(sqlite3_value* pVal, u8 enc){
- if( !pVal ) return 0;
-
+static SQLITE_NOINLINE const void *valueToText(sqlite3_value* pVal, u8 enc){
+ assert( pVal!=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);
+ assert( (pVal->flags & (MEM_Null))==0 );
+ if( pVal->flags & (MEM_Blob|MEM_Str) ){
+ pVal->flags |= MEM_Str;
+ if( pVal->flags & MEM_Zero ){
+ sqlite3VdbeMemExpandBlob(pVal);
+ }
+ if( pVal->enc != (enc & ~SQLITE_UTF16_ALIGNED) ){
+ 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 ){
@@ -58366,8 +66637,7 @@ SQLITE_PRIVATE const void *sqlite3ValueText(sqlite3_value* pVal, u8 enc){
}
sqlite3VdbeMemNulTerminate(pVal); /* IMP: R-31275-44060 */
}else{
- assert( (pVal->flags&MEM_Blob)==0 );
- sqlite3VdbeMemStringify(pVal, enc);
+ sqlite3VdbeMemStringify(pVal, enc, 0);
assert( 0==(1&SQLITE_PTR_TO_INT(pVal->z)) );
}
assert(pVal->enc==(enc & ~SQLITE_UTF16_ALIGNED) || pVal->db==0
@@ -58379,6 +66649,30 @@ SQLITE_PRIVATE const void *sqlite3ValueText(sqlite3_value* pVal, u8 enc){
}
}
+/* 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_Str|MEM_Term))==(MEM_Str|MEM_Term) && pVal->enc==enc ){
+ return pVal->z;
+ }
+ if( pVal->flags&MEM_Null ){
+ return 0;
+ }
+ return valueToText(pVal, enc);
+}
+
/*
** Create a new sqlite3_value object.
*/
@@ -58386,50 +66680,229 @@ 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.
+** Context object passed by sqlite3Stat4ProbeSetValue() through to
+** valueNew(). See comments above valueNew() for details.
+*/
+struct ValueNewStat4Ctx {
+ Parse *pParse;
+ Index *pIdx;
+ UnpackedRecord **ppRec;
+ int iVal;
+};
+
+/*
+** Allocate and return a pointer to a new sqlite3_value object. If
+** the second argument to this function is NULL, the object is allocated
+** by calling sqlite3ValueNew().
**
-** 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.
+** Otherwise, if the second argument is non-zero, then this function is
+** being called indirectly by sqlite3Stat4ProbeSetValue(). If it has not
+** already been allocated, allocate the UnpackedRecord structure that
+** that function will return to its caller here. Then return a pointer to
+** an sqlite3_value within the UnpackedRecord.a[] array.
*/
-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 */
+static sqlite3_value *valueNew(sqlite3 *db, struct ValueNewStat4Ctx *p){
+#ifdef SQLITE_ENABLE_STAT3_OR_STAT4
+ if( p ){
+ UnpackedRecord *pRec = p->ppRec[0];
+
+ if( pRec==0 ){
+ Index *pIdx = p->pIdx; /* Index being probed */
+ int nByte; /* Bytes of space to allocate */
+ int i; /* Counter variable */
+ int nCol = pIdx->nColumn; /* Number of index columns including rowid */
+
+ nByte = sizeof(Mem) * nCol + ROUND8(sizeof(UnpackedRecord));
+ pRec = (UnpackedRecord*)sqlite3DbMallocZero(db, nByte);
+ if( pRec ){
+ pRec->pKeyInfo = sqlite3KeyInfoOfIndex(p->pParse, pIdx);
+ if( pRec->pKeyInfo ){
+ assert( pRec->pKeyInfo->nField+pRec->pKeyInfo->nXField==nCol );
+ assert( pRec->pKeyInfo->enc==ENC(db) );
+ pRec->aMem = (Mem *)((u8*)pRec + ROUND8(sizeof(UnpackedRecord)));
+ for(i=0; i<nCol; i++){
+ pRec->aMem[i].flags = MEM_Null;
+ pRec->aMem[i].db = db;
+ }
+ }else{
+ sqlite3DbFree(db, pRec);
+ pRec = 0;
+ }
+ }
+ if( pRec==0 ) return 0;
+ p->ppRec[0] = pRec;
+ }
+
+ pRec->nField = p->iVal+1;
+ return &pRec->aMem[p->iVal];
+ }
+#else
+ UNUSED_PARAMETER(p);
+#endif /* defined(SQLITE_ENABLE_STAT3_OR_STAT4) */
+ return sqlite3ValueNew(db);
+}
+
+/*
+** The expression object indicated by the second argument is guaranteed
+** to be a scalar SQL function. If
+**
+** * all function arguments are SQL literals,
+** * one of the SQLITE_FUNC_CONSTANT or _SLOCHNG function flags is set, and
+** * the SQLITE_FUNC_NEEDCOLL function flag is not set,
+**
+** then this routine attempts to invoke the SQL function. Assuming no
+** error occurs, output parameter (*ppVal) is set to point to a value
+** object containing the result before returning SQLITE_OK.
+**
+** Affinity aff is applied to the result of the function before returning.
+** If the result is a text value, the sqlite3_value object uses encoding
+** enc.
+**
+** If the conditions above are not met, this function returns SQLITE_OK
+** and sets (*ppVal) to NULL. Or, if an error occurs, (*ppVal) is set to
+** NULL and an SQLite error code returned.
+*/
+#ifdef SQLITE_ENABLE_STAT3_OR_STAT4
+static int valueFromFunction(
+ sqlite3 *db, /* The database connection */
+ Expr *p, /* The expression to evaluate */
+ u8 enc, /* Encoding to use */
+ u8 aff, /* Affinity to use */
+ sqlite3_value **ppVal, /* Write the new value here */
+ struct ValueNewStat4Ctx *pCtx /* Second argument for valueNew() */
+){
+ sqlite3_context ctx; /* Context object for function invocation */
+ sqlite3_value **apVal = 0; /* Function arguments */
+ int nVal = 0; /* Size of apVal[] array */
+ FuncDef *pFunc = 0; /* Function definition */
+ sqlite3_value *pVal = 0; /* New value */
+ int rc = SQLITE_OK; /* Return code */
+ int nName; /* Size of function name in bytes */
+ ExprList *pList = 0; /* Function arguments */
+ int i; /* Iterator variable */
+
+ assert( pCtx!=0 );
+ assert( (p->flags & EP_TokenOnly)==0 );
+ pList = p->x.pList;
+ if( pList ) nVal = pList->nExpr;
+ nName = sqlite3Strlen30(p->u.zToken);
+ pFunc = sqlite3FindFunction(db, p->u.zToken, nName, nVal, enc, 0);
+ assert( pFunc );
+ if( (pFunc->funcFlags & (SQLITE_FUNC_CONSTANT|SQLITE_FUNC_SLOCHNG))==0
+ || (pFunc->funcFlags & SQLITE_FUNC_NEEDCOLL)
+ ){
+ return SQLITE_OK;
+ }
+
+ if( pList ){
+ apVal = (sqlite3_value**)sqlite3DbMallocZero(db, sizeof(apVal[0]) * nVal);
+ if( apVal==0 ){
+ rc = SQLITE_NOMEM;
+ goto value_from_function_out;
+ }
+ for(i=0; i<nVal; i++){
+ rc = sqlite3ValueFromExpr(db, pList->a[i].pExpr, enc, aff, &apVal[i]);
+ if( apVal[i]==0 || rc!=SQLITE_OK ) goto value_from_function_out;
+ }
+ }
+
+ pVal = valueNew(db, pCtx);
+ if( pVal==0 ){
+ rc = SQLITE_NOMEM;
+ goto value_from_function_out;
+ }
+
+ assert( pCtx->pParse->rc==SQLITE_OK );
+ memset(&ctx, 0, sizeof(ctx));
+ ctx.pOut = pVal;
+ ctx.pFunc = pFunc;
+ pFunc->xFunc(&ctx, nVal, apVal);
+ if( ctx.isError ){
+ rc = ctx.isError;
+ sqlite3ErrorMsg(pCtx->pParse, "%s", sqlite3_value_text(pVal));
+ }else{
+ sqlite3ValueApplyAffinity(pVal, aff, SQLITE_UTF8);
+ assert( rc==SQLITE_OK );
+ rc = sqlite3VdbeChangeEncoding(pVal, enc);
+ if( rc==SQLITE_OK && sqlite3VdbeMemTooBig(pVal) ){
+ rc = SQLITE_TOOBIG;
+ pCtx->pParse->nErr++;
+ }
+ }
+ pCtx->pParse->rc = rc;
+
+ value_from_function_out:
+ if( rc!=SQLITE_OK ){
+ pVal = 0;
+ }
+ if( apVal ){
+ for(i=0; i<nVal; i++){
+ sqlite3ValueFree(apVal[i]);
+ }
+ sqlite3DbFree(db, apVal);
+ }
+
+ *ppVal = pVal;
+ return rc;
+}
+#else
+# define valueFromFunction(a,b,c,d,e,f) SQLITE_OK
+#endif /* defined(SQLITE_ENABLE_STAT3_OR_STAT4) */
+
+/*
+** Extract a value from the supplied expression in the manner described
+** above sqlite3ValueFromExpr(). Allocate the sqlite3_value object
+** using valueNew().
+**
+** If pCtx is NULL and an error occurs after the sqlite3_value object
+** has been allocated, it is freed before returning. Or, if pCtx is not
+** NULL, it is assumed that the caller will free any allocated object
+** in all cases.
+*/
+static int valueFromExpr(
+ 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 */
+ struct ValueNewStat4Ctx *pCtx /* Second argument for valueNew() */
){
int op;
char *zVal = 0;
sqlite3_value *pVal = 0;
int negInt = 1;
const char *zNeg = "";
+ int rc = SQLITE_OK;
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
+ while( (op = pExpr->op)==TK_UPLUS ) pExpr = pExpr->pLeft;
if( NEVER(op==TK_REGISTER) ) op = pExpr->op2;
-#endif
+
+ /* Compressed expressions only appear when parsing the DEFAULT clause
+ ** on a table column definition, and hence only when pCtx==0. This
+ ** check ensures that an EP_TokenOnly expression is never passed down
+ ** into valueFromFunction(). */
+ assert( (pExpr->flags & EP_TokenOnly)==0 || pCtx==0 );
+
+ if( op==TK_CAST ){
+ u8 aff = sqlite3AffinityType(pExpr->u.zToken,0);
+ rc = valueFromExpr(db, pExpr->pLeft, enc, aff, ppVal, pCtx);
+ testcase( rc!=SQLITE_OK );
+ if( *ppVal ){
+ sqlite3VdbeMemCast(*ppVal, aff, SQLITE_UTF8);
+ sqlite3ValueApplyAffinity(*ppVal, affinity, SQLITE_UTF8);
+ }
+ return rc;
+ }
/* Handle negative integers in a single step. This is needed in the
** case when the value is -9223372036854775808.
@@ -58443,7 +66916,7 @@ SQLITE_PRIVATE int sqlite3ValueFromExpr(
}
if( op==TK_STRING || op==TK_FLOAT || op==TK_INTEGER ){
- pVal = sqlite3ValueNew(db);
+ pVal = valueNew(db, pCtx);
if( pVal==0 ) goto no_mem;
if( ExprHasProperty(pExpr, EP_IntValue) ){
sqlite3VdbeMemSetInt64(pVal, (i64)pExpr->u.iValue*negInt);
@@ -58451,33 +66924,34 @@ SQLITE_PRIVATE int sqlite3ValueFromExpr(
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 ){
+ if( (op==TK_INTEGER || op==TK_FLOAT ) && affinity==SQLITE_AFF_BLOB ){
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);
+ rc = 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) ){
+ if( SQLITE_OK==sqlite3ValueFromExpr(db,pExpr->pLeft,enc,affinity,&pVal)
+ && pVal!=0
+ ){
sqlite3VdbeMemNumerify(pVal);
- if( pVal->u.i==SMALLEST_INT64 ){
- pVal->flags &= MEM_Int;
- pVal->flags |= MEM_Real;
- pVal->r = (double)LARGEST_INT64;
+ if( pVal->flags & MEM_Real ){
+ pVal->u.r = -pVal->u.r;
+ }else if( pVal->u.i==SMALLEST_INT64 ){
+ pVal->u.r = -(double)SMALLEST_INT64;
+ MemSetTypeFlag(pVal, MEM_Real);
}else{
pVal->u.i = -pVal->u.i;
}
- pVal->r = -pVal->r;
sqlite3ValueApplyAffinity(pVal, affinity, enc);
}
}else if( op==TK_NULL ){
- pVal = sqlite3ValueNew(db);
+ pVal = valueNew(db, pCtx);
if( pVal==0 ) goto no_mem;
}
#ifndef SQLITE_OMIT_BLOB_LITERAL
@@ -58485,7 +66959,7 @@ SQLITE_PRIVATE int sqlite3ValueFromExpr(
int nVal;
assert( pExpr->u.zToken[0]=='x' || pExpr->u.zToken[0]=='X' );
assert( pExpr->u.zToken[1]=='\'' );
- pVal = sqlite3ValueNew(db);
+ pVal = valueNew(db, pCtx);
if( !pVal ) goto no_mem;
zVal = &pExpr->u.zToken[2];
nVal = sqlite3Strlen30(zVal)-1;
@@ -58495,21 +66969,306 @@ SQLITE_PRIVATE int sqlite3ValueFromExpr(
}
#endif
- if( pVal ){
- sqlite3VdbeMemStoreType(pVal);
+#ifdef SQLITE_ENABLE_STAT3_OR_STAT4
+ else if( op==TK_FUNCTION && pCtx!=0 ){
+ rc = valueFromFunction(db, pExpr, enc, affinity, &pVal, pCtx);
}
+#endif
+
*ppVal = pVal;
- return SQLITE_OK;
+ return rc;
no_mem:
db->mallocFailed = 1;
sqlite3DbFree(db, zVal);
- sqlite3ValueFree(pVal);
- *ppVal = 0;
+ assert( *ppVal==0 );
+#ifdef SQLITE_ENABLE_STAT3_OR_STAT4
+ if( pCtx==0 ) sqlite3ValueFree(pVal);
+#else
+ assert( pCtx==0 ); sqlite3ValueFree(pVal);
+#endif
return SQLITE_NOMEM;
}
/*
+** 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 */
+){
+ return valueFromExpr(db, pExpr, enc, affinity, ppVal, 0);
+}
+
+#ifdef SQLITE_ENABLE_STAT3_OR_STAT4
+/*
+** The implementation of the sqlite_record() function. This function accepts
+** a single argument of any type. The return value is a formatted database
+** record (a blob) containing the argument value.
+**
+** This is used to convert the value stored in the 'sample' column of the
+** sqlite_stat3 table to the record format SQLite uses internally.
+*/
+static void recordFunc(
+ sqlite3_context *context,
+ int argc,
+ sqlite3_value **argv
+){
+ const int file_format = 1;
+ u32 iSerial; /* Serial type */
+ int nSerial; /* Bytes of space for iSerial as varint */
+ u32 nVal; /* Bytes of space required for argv[0] */
+ int nRet;
+ sqlite3 *db;
+ u8 *aRet;
+
+ UNUSED_PARAMETER( argc );
+ iSerial = sqlite3VdbeSerialType(argv[0], file_format, &nVal);
+ nSerial = sqlite3VarintLen(iSerial);
+ db = sqlite3_context_db_handle(context);
+
+ nRet = 1 + nSerial + nVal;
+ aRet = sqlite3DbMallocRaw(db, nRet);
+ if( aRet==0 ){
+ sqlite3_result_error_nomem(context);
+ }else{
+ aRet[0] = nSerial+1;
+ putVarint32(&aRet[1], iSerial);
+ sqlite3VdbeSerialPut(&aRet[1+nSerial], argv[0], iSerial);
+ sqlite3_result_blob(context, aRet, nRet, SQLITE_TRANSIENT);
+ sqlite3DbFree(db, aRet);
+ }
+}
+
+/*
+** Register built-in functions used to help read ANALYZE data.
+*/
+SQLITE_PRIVATE void sqlite3AnalyzeFunctions(void){
+ static SQLITE_WSD FuncDef aAnalyzeTableFuncs[] = {
+ FUNCTION(sqlite_record, 1, 0, 0, recordFunc),
+ };
+ int i;
+ FuncDefHash *pHash = &GLOBAL(FuncDefHash, sqlite3GlobalFunctions);
+ FuncDef *aFunc = (FuncDef*)&GLOBAL(FuncDef, aAnalyzeTableFuncs);
+ for(i=0; i<ArraySize(aAnalyzeTableFuncs); i++){
+ sqlite3FuncDefInsert(pHash, &aFunc[i]);
+ }
+}
+
+/*
+** Attempt to extract a value from pExpr and use it to construct *ppVal.
+**
+** If pAlloc is not NULL, then an UnpackedRecord object is created for
+** pAlloc if one does not exist and the new value is added to the
+** UnpackedRecord object.
+**
+** A value is extracted in the following cases:
+**
+** * (pExpr==0). In this case the value is assumed to be an SQL NULL,
+**
+** * The expression is a bound variable, and this is a reprepare, or
+**
+** * The expression is a literal value.
+**
+** On success, *ppVal is made to point to the extracted value. The caller
+** is responsible for ensuring that the value is eventually freed.
+*/
+static int stat4ValueFromExpr(
+ Parse *pParse, /* Parse context */
+ Expr *pExpr, /* The expression to extract a value from */
+ u8 affinity, /* Affinity to use */
+ struct ValueNewStat4Ctx *pAlloc,/* How to allocate space. Or NULL */
+ sqlite3_value **ppVal /* OUT: New value object (or NULL) */
+){
+ int rc = SQLITE_OK;
+ sqlite3_value *pVal = 0;
+ sqlite3 *db = pParse->db;
+
+ /* Skip over any TK_COLLATE nodes */
+ pExpr = sqlite3ExprSkipCollate(pExpr);
+
+ if( !pExpr ){
+ pVal = valueNew(db, pAlloc);
+ if( pVal ){
+ sqlite3VdbeMemSetNull((Mem*)pVal);
+ }
+ }else if( pExpr->op==TK_VARIABLE
+ || NEVER(pExpr->op==TK_REGISTER && pExpr->op2==TK_VARIABLE)
+ ){
+ Vdbe *v;
+ int iBindVar = pExpr->iColumn;
+ sqlite3VdbeSetVarmask(pParse->pVdbe, iBindVar);
+ if( (v = pParse->pReprepare)!=0 ){
+ pVal = valueNew(db, pAlloc);
+ if( pVal ){
+ rc = sqlite3VdbeMemCopy((Mem*)pVal, &v->aVar[iBindVar-1]);
+ if( rc==SQLITE_OK ){
+ sqlite3ValueApplyAffinity(pVal, affinity, ENC(db));
+ }
+ pVal->db = pParse->db;
+ }
+ }
+ }else{
+ rc = valueFromExpr(db, pExpr, ENC(db), affinity, &pVal, pAlloc);
+ }
+
+ assert( pVal==0 || pVal->db==db );
+ *ppVal = pVal;
+ return rc;
+}
+
+/*
+** This function is used to allocate and populate UnpackedRecord
+** structures intended to be compared against sample index keys stored
+** in the sqlite_stat4 table.
+**
+** A single call to this function attempts to populates field iVal (leftmost
+** is 0 etc.) of the unpacked record with a value extracted from expression
+** pExpr. Extraction of values is possible if:
+**
+** * (pExpr==0). In this case the value is assumed to be an SQL NULL,
+**
+** * The expression is a bound variable, and this is a reprepare, or
+**
+** * The sqlite3ValueFromExpr() function is able to extract a value
+** from the expression (i.e. the expression is a literal value).
+**
+** If a value can be extracted, the affinity passed as the 5th argument
+** is applied to it before it is copied into the UnpackedRecord. Output
+** parameter *pbOk is set to true if a value is extracted, or false
+** otherwise.
+**
+** When this function is called, *ppRec must either point to an object
+** allocated by an earlier call to this function, or must be NULL. If it
+** is NULL and a value can be successfully extracted, a new UnpackedRecord
+** is allocated (and *ppRec set to point to it) before returning.
+**
+** Unless an error is encountered, SQLITE_OK is returned. It is not an
+** error if a value cannot be extracted from pExpr. If an error does
+** occur, an SQLite error code is returned.
+*/
+SQLITE_PRIVATE int sqlite3Stat4ProbeSetValue(
+ Parse *pParse, /* Parse context */
+ Index *pIdx, /* Index being probed */
+ UnpackedRecord **ppRec, /* IN/OUT: Probe record */
+ Expr *pExpr, /* The expression to extract a value from */
+ u8 affinity, /* Affinity to use */
+ int iVal, /* Array element to populate */
+ int *pbOk /* OUT: True if value was extracted */
+){
+ int rc;
+ sqlite3_value *pVal = 0;
+ struct ValueNewStat4Ctx alloc;
+
+ alloc.pParse = pParse;
+ alloc.pIdx = pIdx;
+ alloc.ppRec = ppRec;
+ alloc.iVal = iVal;
+
+ rc = stat4ValueFromExpr(pParse, pExpr, affinity, &alloc, &pVal);
+ assert( pVal==0 || pVal->db==pParse->db );
+ *pbOk = (pVal!=0);
+ return rc;
+}
+
+/*
+** Attempt to extract a value from expression pExpr using the methods
+** as described for sqlite3Stat4ProbeSetValue() above.
+**
+** If successful, set *ppVal to point to a new value object and return
+** SQLITE_OK. If no value can be extracted, but no other error occurs
+** (e.g. OOM), return SQLITE_OK and set *ppVal to NULL. Or, if an error
+** does occur, return an SQLite error code. The final value of *ppVal
+** is undefined in this case.
+*/
+SQLITE_PRIVATE int sqlite3Stat4ValueFromExpr(
+ Parse *pParse, /* Parse context */
+ Expr *pExpr, /* The expression to extract a value from */
+ u8 affinity, /* Affinity to use */
+ sqlite3_value **ppVal /* OUT: New value object (or NULL) */
+){
+ return stat4ValueFromExpr(pParse, pExpr, affinity, 0, ppVal);
+}
+
+/*
+** Extract the iCol-th column from the nRec-byte record in pRec. Write
+** the column value into *ppVal. If *ppVal is initially NULL then a new
+** sqlite3_value object is allocated.
+**
+** If *ppVal is initially NULL then the caller is responsible for
+** ensuring that the value written into *ppVal is eventually freed.
+*/
+SQLITE_PRIVATE int sqlite3Stat4Column(
+ sqlite3 *db, /* Database handle */
+ const void *pRec, /* Pointer to buffer containing record */
+ int nRec, /* Size of buffer pRec in bytes */
+ int iCol, /* Column to extract */
+ sqlite3_value **ppVal /* OUT: Extracted value */
+){
+ u32 t; /* a column type code */
+ int nHdr; /* Size of the header in the record */
+ int iHdr; /* Next unread header byte */
+ int iField; /* Next unread data byte */
+ int szField; /* Size of the current data field */
+ int i; /* Column index */
+ u8 *a = (u8*)pRec; /* Typecast byte array */
+ Mem *pMem = *ppVal; /* Write result into this Mem object */
+
+ assert( iCol>0 );
+ iHdr = getVarint32(a, nHdr);
+ if( nHdr>nRec || iHdr>=nHdr ) return SQLITE_CORRUPT_BKPT;
+ iField = nHdr;
+ for(i=0; i<=iCol; i++){
+ iHdr += getVarint32(&a[iHdr], t);
+ testcase( iHdr==nHdr );
+ testcase( iHdr==nHdr+1 );
+ if( iHdr>nHdr ) return SQLITE_CORRUPT_BKPT;
+ szField = sqlite3VdbeSerialTypeLen(t);
+ iField += szField;
+ }
+ testcase( iField==nRec );
+ testcase( iField==nRec+1 );
+ if( iField>nRec ) return SQLITE_CORRUPT_BKPT;
+ if( pMem==0 ){
+ pMem = *ppVal = sqlite3ValueNew(db);
+ if( pMem==0 ) return SQLITE_NOMEM;
+ }
+ sqlite3VdbeSerialGet(&a[iField-szField], t, pMem);
+ pMem->enc = ENC(db);
+ return SQLITE_OK;
+}
+
+/*
+** Unless it is NULL, the argument must be an UnpackedRecord object returned
+** by an earlier call to sqlite3Stat4ProbeSetValue(). This call deletes
+** the object.
+*/
+SQLITE_PRIVATE void sqlite3Stat4ProbeFree(UnpackedRecord *pRec){
+ if( pRec ){
+ int i;
+ int nCol = pRec->pKeyInfo->nField+pRec->pKeyInfo->nXField;
+ Mem *aMem = pRec->aMem;
+ sqlite3 *db = aMem[0].db;
+ for(i=0; i<nCol; i++){
+ sqlite3VdbeMemRelease(&aMem[i]);
+ }
+ sqlite3KeyInfoUnref(pRec->pKeyInfo);
+ sqlite3DbFree(db, pRec);
+ }
+}
+#endif /* ifdef SQLITE_ENABLE_STAT4 */
+
+/*
** Change the string value of an sqlite3_value object
*/
SQLITE_PRIVATE void sqlite3ValueSetStr(
@@ -58532,19 +67291,28 @@ SQLITE_PRIVATE void sqlite3ValueFree(sqlite3_value *v){
}
/*
-** Return the number of bytes in the sqlite3_value object assuming
-** that it uses the encoding "enc"
+** The sqlite3ValueBytes() routine returns the number of bytes in the
+** sqlite3_value object assuming that it uses the encoding "enc".
+** The valueBytes() routine is a helper function.
*/
+static SQLITE_NOINLINE int valueBytes(sqlite3_value *pVal, u8 enc){
+ return valueToText(pVal, enc)!=0 ? pVal->n : 0;
+}
SQLITE_PRIVATE int sqlite3ValueBytes(sqlite3_value *pVal, u8 enc){
Mem *p = (Mem*)pVal;
- if( (p->flags & MEM_Blob)!=0 || sqlite3ValueText(pVal, enc) ){
+ assert( (p->flags & MEM_Null)==0 || (p->flags & (MEM_Str|MEM_Blob))==0 );
+ if( (p->flags & MEM_Str)!=0 && pVal->enc==enc ){
+ return p->n;
+ }
+ if( (p->flags & MEM_Blob)!=0 ){
if( p->flags & MEM_Zero ){
return p->n + p->u.nZero;
}else{
return p->n;
}
}
- return 0;
+ if( p->flags & MEM_Null ) return 0;
+ return valueBytes(pVal, enc);
}
/************** End of vdbemem.c *********************************************/
@@ -58561,27 +67329,16 @@ SQLITE_PRIVATE int sqlite3ValueBytes(sqlite3_value *pVal, u8 enc){
**
*************************************************************************
** 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.
+** a VDBE (or an "sqlite3_stmt" as it is known to the outside world.)
*/
-
-
-
-/*
-** 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
-
+/* #include "sqliteInt.h" */
+/* #include "vdbeInt.h" */
/*
** Create a new virtual database engine.
*/
-SQLITE_PRIVATE Vdbe *sqlite3VdbeCreate(sqlite3 *db){
+SQLITE_PRIVATE Vdbe *sqlite3VdbeCreate(Parse *pParse){
+ sqlite3 *db = pParse->db;
Vdbe *p;
p = sqlite3DbMallocZero(db, sizeof(Vdbe) );
if( p==0 ) return 0;
@@ -58593,10 +67350,26 @@ SQLITE_PRIVATE Vdbe *sqlite3VdbeCreate(sqlite3 *db){
p->pPrev = 0;
db->pVdbe = p;
p->magic = VDBE_MAGIC_INIT;
+ p->pParse = pParse;
+ assert( pParse->aLabel==0 );
+ assert( pParse->nLabel==0 );
+ assert( pParse->nOpAlloc==0 );
+ assert( pParse->szOpAlloc==0 );
return p;
}
/*
+** Change the error string stored in Vdbe.zErrMsg
+*/
+SQLITE_PRIVATE void sqlite3VdbeError(Vdbe *p, const char *zFormat, ...){
+ va_list ap;
+ sqlite3DbFree(p->db, p->zErrMsg);
+ va_start(ap, zFormat);
+ p->zErrMsg = sqlite3VMPrintf(p->db, zFormat, ap);
+ va_end(ap);
+}
+
+/*
** Remember the SQL string for a prepared statement.
*/
SQLITE_PRIVATE void sqlite3VdbeSetSql(Vdbe *p, const char *z, int n, int isPrepareV2){
@@ -58613,9 +67386,9 @@ SQLITE_PRIVATE void sqlite3VdbeSetSql(Vdbe *p, const char *z, int n, int isPrepa
/*
** Return the SQL associated with a prepared statement
*/
-SQLITE_API const char *sqlite3_sql(sqlite3_stmt *pStmt){
+SQLITE_API const char *SQLITE_STDCALL sqlite3_sql(sqlite3_stmt *pStmt){
Vdbe *p = (Vdbe *)pStmt;
- return (p && p->isPrepareV2) ? p->zSql : 0;
+ return p ? p->zSql : 0;
}
/*
@@ -58639,35 +67412,56 @@ SQLITE_PRIVATE void sqlite3VdbeSwap(Vdbe *pA, Vdbe *pB){
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.
+** Resize the Vdbe.aOp array so that it is at least nOp elements larger
+** than its current size. nOp is guaranteed to be less than or equal
+** to 1024/sizeof(Op).
**
** If an out-of-memory error occurs while resizing the array, return
-** SQLITE_NOMEM. In this case Vdbe.aOp and Vdbe.nOpAlloc remain
+** SQLITE_NOMEM. In this case Vdbe.aOp and Parse.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){
+static int growOpArray(Vdbe *v, int nOp){
VdbeOp *pNew;
+ Parse *p = v->pParse;
+
+ /* The SQLITE_TEST_REALLOC_STRESS compile-time option is designed to force
+ ** more frequent reallocs and hence provide more opportunities for
+ ** simulated OOM faults. SQLITE_TEST_REALLOC_STRESS is generally used
+ ** during testing only. With SQLITE_TEST_REALLOC_STRESS grow the op array
+ ** by the minimum* amount required until the size reaches 512. Normal
+ ** operation (without SQLITE_TEST_REALLOC_STRESS) is to double the current
+ ** size of the op array or add 1KB of space, whichever is smaller. */
+#ifdef SQLITE_TEST_REALLOC_STRESS
+ int nNew = (p->nOpAlloc>=512 ? p->nOpAlloc*2 : p->nOpAlloc+nOp);
+#else
int nNew = (p->nOpAlloc ? p->nOpAlloc*2 : (int)(1024/sizeof(Op)));
- pNew = sqlite3DbRealloc(p->db, p->aOp, nNew*sizeof(Op));
+ UNUSED_PARAMETER(nOp);
+#endif
+
+ assert( nOp<=(1024/sizeof(Op)) );
+ assert( nNew>=(p->nOpAlloc+nOp) );
+ pNew = sqlite3DbRealloc(p->db, v->aOp, nNew*sizeof(Op));
if( pNew ){
- p->nOpAlloc = sqlite3DbMallocSize(p->db, pNew)/sizeof(Op);
- p->aOp = pNew;
+ p->szOpAlloc = sqlite3DbMallocSize(p->db, pNew);
+ p->nOpAlloc = p->szOpAlloc/sizeof(Op);
+ v->aOp = pNew;
}
return (pNew ? SQLITE_OK : SQLITE_NOMEM);
}
+#ifdef SQLITE_DEBUG
+/* This routine is just a convenient place to set a breakpoint that will
+** fire after each opcode is inserted and displayed using
+** "PRAGMA vdbe_addoptrace=on".
+*/
+static void test_addop_breakpoint(void){
+ static int n = 0;
+ n++;
+}
+#endif
+
/*
** Add a new instruction to the list of instructions current in the
** VDBE. Return the address of the new instruction.
@@ -58684,6 +67478,12 @@ static int growOpArray(Vdbe *p){
** the sqlite3VdbeChangeP4() function to change the value of the P4
** operand.
*/
+static SQLITE_NOINLINE int growOp3(Vdbe *p, int op, int p1, int p2, int p3){
+ assert( p->pParse->nOpAlloc<=p->nOp );
+ if( growOpArray(p, 1) ) return 1;
+ assert( p->pParse->nOpAlloc>p->nOp );
+ return sqlite3VdbeAddOp3(p, op, p1, p2, p3);
+}
SQLITE_PRIVATE int sqlite3VdbeAddOp3(Vdbe *p, int op, int p1, int p2, int p3){
int i;
VdbeOp *pOp;
@@ -58691,10 +67491,8 @@ SQLITE_PRIVATE int sqlite3VdbeAddOp3(Vdbe *p, int op, int p1, int p2, int p3){
i = p->nOp;
assert( p->magic==VDBE_MAGIC_INIT );
assert( op>0 && op<0xff );
- if( p->nOpAlloc<=i ){
- if( growOpArray(p) ){
- return 1;
- }
+ if( p->pParse->nOpAlloc<=i ){
+ return growOp3(p, op, p1, p2, p3);
}
p->nOp++;
pOp = &p->aOp[i];
@@ -58705,14 +67503,31 @@ SQLITE_PRIVATE int sqlite3VdbeAddOp3(Vdbe *p, int op, int p1, int p2, int p3){
pOp->p3 = p3;
pOp->p4.p = 0;
pOp->p4type = P4_NOTUSED;
-#ifdef SQLITE_DEBUG
+#ifdef SQLITE_ENABLE_EXPLAIN_COMMENTS
pOp->zComment = 0;
- if( sqlite3VdbeAddopTrace ) sqlite3VdbePrintOp(0, i, &p->aOp[i]);
+#endif
+#ifdef SQLITE_DEBUG
+ if( p->db->flags & SQLITE_VdbeAddopTrace ){
+ int jj, kk;
+ Parse *pParse = p->pParse;
+ for(jj=kk=0; jj<SQLITE_N_COLCACHE; jj++){
+ struct yColCache *x = pParse->aColCache + jj;
+ if( x->iLevel>pParse->iCacheLevel || x->iReg==0 ) continue;
+ printf(" r[%d]={%d:%d}", x->iReg, x->iTable, x->iColumn);
+ kk++;
+ }
+ if( kk ) printf("\n");
+ sqlite3VdbePrintOp(0, i, &p->aOp[i]);
+ test_addop_breakpoint();
+ }
#endif
#ifdef VDBE_PROFILE
pOp->cycles = 0;
pOp->cnt = 0;
#endif
+#ifdef SQLITE_VDBE_COVERAGE
+ pOp->iSrcLine = 0;
+#endif
return i;
}
SQLITE_PRIVATE int sqlite3VdbeAddOp0(Vdbe *p, int op){
@@ -58725,6 +67540,44 @@ SQLITE_PRIVATE int sqlite3VdbeAddOp2(Vdbe *p, int op, int p1, int p2){
return sqlite3VdbeAddOp3(p, op, p1, p2, 0);
}
+/* Generate code for an unconditional jump to instruction iDest
+*/
+SQLITE_PRIVATE int sqlite3VdbeGoto(Vdbe *p, int iDest){
+ return sqlite3VdbeAddOp3(p, OP_Goto, 0, iDest, 0);
+}
+
+/* Generate code to cause the string zStr to be loaded into
+** register iDest
+*/
+SQLITE_PRIVATE int sqlite3VdbeLoadString(Vdbe *p, int iDest, const char *zStr){
+ return sqlite3VdbeAddOp4(p, OP_String8, 0, iDest, 0, zStr, 0);
+}
+
+/*
+** Generate code that initializes multiple registers to string or integer
+** constants. The registers begin with iDest and increase consecutively.
+** One register is initialized for each characgter in zTypes[]. For each
+** "s" character in zTypes[], the register is a string if the argument is
+** not NULL, or OP_Null if the value is a null pointer. For each "i" character
+** in zTypes[], the register is initialized to an integer.
+*/
+SQLITE_PRIVATE void sqlite3VdbeMultiLoad(Vdbe *p, int iDest, const char *zTypes, ...){
+ va_list ap;
+ int i;
+ char c;
+ va_start(ap, zTypes);
+ for(i=0; (c = zTypes[i])!=0; i++){
+ if( c=='s' ){
+ const char *z = va_arg(ap, const char*);
+ int addr = sqlite3VdbeAddOp2(p, z==0 ? OP_Null : OP_String8, 0, iDest++);
+ if( z ) sqlite3VdbeChangeP4(p, addr, z, 0);
+ }else{
+ assert( c=='i' );
+ sqlite3VdbeAddOp2(p, OP_Integer, va_arg(ap, int), iDest++);
+ }
+ }
+ va_end(ap);
+}
/*
** Add an opcode that includes the p4 value as a pointer.
@@ -58744,6 +67597,24 @@ SQLITE_PRIVATE int sqlite3VdbeAddOp4(
}
/*
+** Add an opcode that includes the p4 value with a P4_INT64 or
+** P4_REAL type.
+*/
+SQLITE_PRIVATE int sqlite3VdbeAddOp4Dup8(
+ 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 u8 *zP4, /* The P4 operand */
+ int p4type /* P4 operand type */
+){
+ char *p4copy = sqlite3DbMallocRaw(sqlite3VdbeDb(p), 8);
+ if( p4copy ) memcpy(p4copy, zP4, 8);
+ return sqlite3VdbeAddOp4(p, op, p1, p2, p3, p4copy, p4type);
+}
+
+/*
** 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.
@@ -58788,9 +67659,10 @@ SQLITE_PRIVATE int sqlite3VdbeAddOp4Int(
**
** Zero is returned if a malloc() fails.
*/
-SQLITE_PRIVATE int sqlite3VdbeMakeLabel(Vdbe *p){
+SQLITE_PRIVATE int sqlite3VdbeMakeLabel(Vdbe *v){
+ Parse *p = v->pParse;
int i = p->nLabel++;
- assert( p->magic==VDBE_MAGIC_INIT );
+ assert( v->magic==VDBE_MAGIC_INIT );
if( (i & (i-1))==0 ){
p->aLabel = sqlite3DbReallocOrFree(p->db, p->aLabel,
(i*2+1)*sizeof(p->aLabel[0]));
@@ -58798,7 +67670,7 @@ SQLITE_PRIVATE int sqlite3VdbeMakeLabel(Vdbe *p){
if( p->aLabel ){
p->aLabel[i] = -1;
}
- return -1-i;
+ return ADDR(i);
}
/*
@@ -58806,13 +67678,16 @@ SQLITE_PRIVATE int sqlite3VdbeMakeLabel(Vdbe *p){
** 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 );
+SQLITE_PRIVATE void sqlite3VdbeResolveLabel(Vdbe *v, int x){
+ Parse *p = v->pParse;
+ int j = ADDR(x);
+ assert( v->magic==VDBE_MAGIC_INIT );
+ assert( j<p->nLabel );
+ assert( j>=0 );
if( p->aLabel ){
- p->aLabel[j] = p->nOp;
+ p->aLabel[j] = v->nOp;
}
+ p->iFixedOp = v->nOp - 1;
}
/*
@@ -58904,6 +67779,7 @@ static Op *opIterNext(VdbeOpIter *p){
** * OP_VUpdate
** * OP_VRename
** * OP_FkCounter with P2==0 (immediate foreign key constraint)
+** * OP_CreateTable and OP_InitCoroutine (for CREATE TABLE AS SELECT ...)
**
** Then check that the value of Parse.mayAbort is true if an
** ABORT may be thrown, or false otherwise. Return true if it does
@@ -58914,6 +67790,9 @@ static Op *opIterNext(VdbeOpIter *p){
*/
SQLITE_PRIVATE int sqlite3VdbeAssertMayAbort(Vdbe *v, int mayAbort){
int hasAbort = 0;
+ int hasFkCounter = 0;
+ int hasCreateTable = 0;
+ int hasInitCoroutine = 0;
Op *pOp;
VdbeOpIter sIter;
memset(&sIter, 0, sizeof(sIter));
@@ -58922,81 +67801,121 @@ SQLITE_PRIVATE int sqlite3VdbeAssertMayAbort(Vdbe *v, int mayAbort){
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))
+ && ((pOp->p1&0xff)==SQLITE_CONSTRAINT && pOp->p2==OE_Abort))
){
hasAbort = 1;
break;
}
+ if( opcode==OP_CreateTable ) hasCreateTable = 1;
+ if( opcode==OP_InitCoroutine ) hasInitCoroutine = 1;
+#ifndef SQLITE_OMIT_FOREIGN_KEY
+ if( opcode==OP_FkCounter && pOp->p1==0 && pOp->p2==1 ){
+ hasFkCounter = 1;
+ }
+#endif
}
sqlite3DbFree(v->db, sIter.apSub);
- /* Return true if hasAbort==mayAbort. Or if a malloc failure occured.
+ /* Return true if hasAbort==mayAbort. Or if a malloc failure occurred.
** 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 );
+ return ( v->db->mallocFailed || hasAbort==mayAbort || hasFkCounter
+ || (hasCreateTable && hasInitCoroutine) );
}
#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 after all opcodes have been inserted. It loops
+** through all the opcodes and fixes up some details.
+**
+** (1) For each jump instruction with a negative P2 value (a label)
+** resolve the P2 value to an actual address.
**
-** This routine is called once after all opcodes have been inserted.
+** (2) Compute the maximum number of arguments used by any SQL function
+** and store that value in *pMaxFuncArgs.
**
-** 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.
+** (3) Update the Vdbe.readOnly and Vdbe.bIsReader flags to accurately
+** indicate what the prepared statement actually does.
**
-** The Op.opflags field is set on all opcodes.
+** (4) Initialize the p4.xAdvance pointer on opcodes that use it.
+**
+** (5) Reclaim the memory allocated for storing labels.
*/
static void resolveP2Values(Vdbe *p, int *pMaxFuncArgs){
int i;
int nMaxArgs = *pMaxFuncArgs;
Op *pOp;
- int *aLabel = p->aLabel;
+ Parse *pParse = p->pParse;
+ int *aLabel = pParse->aLabel;
p->readOnly = 1;
+ p->bIsReader = 0;
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;
+ /* NOTE: Be sure to update mkopcodeh.awk when adding or removing
+ ** cases from this switch! */
+ switch( opcode ){
+ case OP_Transaction: {
+ if( pOp->p2!=0 ) p->readOnly = 0;
+ /* fall thru */
+ }
+ case OP_AutoCommit:
+ case OP_Savepoint: {
+ p->bIsReader = 1;
+ break;
+ }
+#ifndef SQLITE_OMIT_WAL
+ case OP_Checkpoint:
+#endif
+ case OP_Vacuum:
+ case OP_JournalMode: {
+ p->readOnly = 0;
+ p->bIsReader = 1;
+ break;
+ }
#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;
+ case OP_VUpdate: {
+ if( pOp->p2>nMaxArgs ) nMaxArgs = pOp->p2;
+ break;
+ }
+ case OP_VFilter: {
+ int n;
+ assert( p->nOp - i >= 3 );
+ assert( pOp[-1].opcode==OP_Integer );
+ n = pOp[-1].p1;
+ if( n>nMaxArgs ) nMaxArgs = n;
+ break;
+ }
#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;
+ case OP_Next:
+ case OP_NextIfOpen:
+ case OP_SorterNext: {
+ pOp->p4.xAdvance = sqlite3BtreeNext;
+ pOp->p4type = P4_ADVANCE;
+ break;
+ }
+ case OP_Prev:
+ case OP_PrevIfOpen: {
+ pOp->p4.xAdvance = sqlite3BtreePrevious;
+ pOp->p4type = P4_ADVANCE;
+ break;
+ }
}
+ pOp->opflags = sqlite3OpcodeProperty[opcode];
if( (pOp->opflags & OPFLG_JUMP)!=0 && pOp->p2<0 ){
- assert( -1-pOp->p2<p->nLabel );
- pOp->p2 = aLabel[-1-pOp->p2];
+ assert( ADDR(pOp->p2)<pParse->nLabel );
+ pOp->p2 = aLabel[ADDR(pOp->p2)];
}
}
- sqlite3DbFree(p->db, p->aLabel);
- p->aLabel = 0;
-
+ sqlite3DbFree(p->db, pParse->aLabel);
+ pParse->aLabel = 0;
+ pParse->nLabel = 0;
*pMaxFuncArgs = nMaxArgs;
+ assert( p->bIsReader!=0 || DbMaskAllZero(p->btreeMask) );
}
/*
@@ -59023,7 +67942,7 @@ SQLITE_PRIVATE VdbeOp *sqlite3VdbeTakeOpArray(Vdbe *p, int *pnOp, int *pnMaxArg)
assert( aOp && !p->db->mallocFailed );
/* Check that sqlite3VdbeUsesBtree() was not called on this VM */
- assert( p->btreeMask==0 );
+ assert( DbMaskAllZero(p->btreeMask) );
resolveP2Values(p, pnMaxArg);
*pnOp = p->nOp;
@@ -59035,86 +67954,89 @@ SQLITE_PRIVATE VdbeOp *sqlite3VdbeTakeOpArray(Vdbe *p, int *pnOp, int *pnMaxArg)
** 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;
+SQLITE_PRIVATE int sqlite3VdbeAddOpList(Vdbe *p, int nOp, VdbeOpList const *aOp, int iLineno){
+ int addr, i;
+ VdbeOp *pOut;
+ assert( nOp>0 );
assert( p->magic==VDBE_MAGIC_INIT );
- if( p->nOp + nOp > p->nOpAlloc && growOpArray(p) ){
+ if( p->nOp + nOp > p->pParse->nOpAlloc && growOpArray(p, nOp) ){
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]);
- }
+ pOut = &p->aOp[addr];
+ for(i=0; i<nOp; i++, aOp++, pOut++){
+ pOut->opcode = aOp->opcode;
+ pOut->p1 = aOp->p1;
+ pOut->p2 = aOp->p2;
+ assert( aOp->p2>=0 );
+ pOut->p3 = aOp->p3;
+ pOut->p4type = P4_NOTUSED;
+ pOut->p4.p = 0;
+ pOut->p5 = 0;
+#ifdef SQLITE_ENABLE_EXPLAIN_COMMENTS
+ pOut->zComment = 0;
+#endif
+#ifdef SQLITE_VDBE_COVERAGE
+ pOut->iSrcLine = iLineno+i;
+#else
+ (void)iLineno;
#endif
+#ifdef SQLITE_DEBUG
+ if( p->db->flags & SQLITE_VdbeAddopTrace ){
+ sqlite3VdbePrintOp(0, i+addr, &p->aOp[i+addr]);
}
- p->nOp += nOp;
+#endif
}
+ p->nOp += nOp;
return addr;
}
+#if defined(SQLITE_ENABLE_STMT_SCANSTATUS)
/*
-** 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.
+** Add an entry to the array of counters managed by sqlite3_stmt_scanstatus().
*/
-SQLITE_PRIVATE void sqlite3VdbeChangeP1(Vdbe *p, u32 addr, int val){
- assert( p!=0 );
- if( ((u32)p->nOp)>addr ){
- p->aOp[addr].p1 = val;
+SQLITE_PRIVATE void sqlite3VdbeScanStatus(
+ Vdbe *p, /* VM to add scanstatus() to */
+ int addrExplain, /* Address of OP_Explain (or 0) */
+ int addrLoop, /* Address of loop counter */
+ int addrVisit, /* Address of rows visited counter */
+ LogEst nEst, /* Estimated number of output rows */
+ const char *zName /* Name of table or index being scanned */
+){
+ int nByte = (p->nScan+1) * sizeof(ScanStatus);
+ ScanStatus *aNew;
+ aNew = (ScanStatus*)sqlite3DbRealloc(p->db, p->aScan, nByte);
+ if( aNew ){
+ ScanStatus *pNew = &aNew[p->nScan++];
+ pNew->addrExplain = addrExplain;
+ pNew->addrLoop = addrLoop;
+ pNew->addrVisit = addrVisit;
+ pNew->nEst = nEst;
+ pNew->zName = sqlite3DbStrDup(p->db, zName);
+ p->aScan = aNew;
}
}
+#endif
+
/*
-** Change the value of the P2 operand for a specific instruction.
-** This routine is useful for setting a jump destination.
+** Change the value of the opcode, or P1, P2, P3, or P5 operands
+** for a specific instruction.
*/
+SQLITE_PRIVATE void sqlite3VdbeChangeOpcode(Vdbe *p, u32 addr, u8 iNewOpcode){
+ sqlite3VdbeGetOp(p,addr)->opcode = iNewOpcode;
+}
+SQLITE_PRIVATE void sqlite3VdbeChangeP1(Vdbe *p, u32 addr, int val){
+ sqlite3VdbeGetOp(p,addr)->p1 = val;
+}
SQLITE_PRIVATE void sqlite3VdbeChangeP2(Vdbe *p, u32 addr, int val){
- assert( p!=0 );
- if( ((u32)p->nOp)>addr ){
- p->aOp[addr].p2 = val;
- }
+ sqlite3VdbeGetOp(p,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;
- }
+ sqlite3VdbeGetOp(p,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;
- }
+SQLITE_PRIVATE void sqlite3VdbeChangeP5(Vdbe *p, u8 p5){
+ sqlite3VdbeGetOp(p,-1)->p5 = p5;
}
/*
@@ -59122,8 +68044,8 @@ SQLITE_PRIVATE void sqlite3VdbeChangeP5(Vdbe *p, u8 val){
** 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);
+ p->pParse->iFixedOp = p->nOp - 1;
+ sqlite3VdbeChangeP2(p, addr, p->nOp);
}
@@ -59132,7 +68054,7 @@ SQLITE_PRIVATE void sqlite3VdbeJumpHere(Vdbe *p, int addr){
** the FuncDef is not ephermal, then do nothing.
*/
static void freeEphemeralFunction(sqlite3 *db, FuncDef *pDef){
- if( ALWAYS(pDef) && (pDef->flags & SQLITE_FUNC_EPHEM)!=0 ){
+ if( ALWAYS(pDef) && (pDef->funcFlags & SQLITE_FUNC_EPHEM)!=0 ){
sqlite3DbFree(db, pDef);
}
}
@@ -59146,24 +68068,29 @@ static void freeP4(sqlite3 *db, int p4type, void *p4){
if( p4 ){
assert( db );
switch( p4type ){
+ case P4_FUNCCTX: {
+ freeEphemeralFunction(db, ((sqlite3_context*)p4)->pFunc);
+ /* Fall through into the next case */
+ }
case P4_REAL:
case P4_INT64:
case P4_DYNAMIC:
- case P4_KEYINFO:
- case P4_INTARRAY:
- case P4_KEYINFO_HANDOFF: {
+ case P4_INTARRAY: {
sqlite3DbFree(db, p4);
break;
}
- case P4_MPRINTF: {
- if( db->pnBytesFreed==0 ) sqlite3_free(p4);
+ case P4_KEYINFO: {
+ if( db->pnBytesFreed==0 ) sqlite3KeyInfoUnref((KeyInfo*)p4);
+ break;
+ }
+#ifdef SQLITE_ENABLE_CURSOR_HINTS
+ case P4_EXPR: {
+ sqlite3ExprDelete(db, (Expr*)p4);
break;
}
- case P4_VDBEFUNC: {
- VdbeFunc *pVdbeFunc = (VdbeFunc *)p4;
- freeEphemeralFunction(db, pVdbeFunc->pFunc);
- if( db->pnBytesFreed==0 ) sqlite3VdbeDeleteAuxData(pVdbeFunc, 0);
- sqlite3DbFree(db, pVdbeFunc);
+#endif
+ case P4_MPRINTF: {
+ if( db->pnBytesFreed==0 ) sqlite3_free(p4);
break;
}
case P4_FUNCDEF: {
@@ -59175,7 +68102,7 @@ static void freeP4(sqlite3 *db, int p4type, void *p4){
sqlite3ValueFree((sqlite3_value*)p4);
}else{
Mem *p = (Mem*)p4;
- sqlite3DbFree(db, p->zMalloc);
+ if( p->szMalloc ) sqlite3DbFree(db, p->zMalloc);
sqlite3DbFree(db, p);
}
break;
@@ -59198,7 +68125,7 @@ static void vdbeFreeOpArray(sqlite3 *db, Op *aOp, int nOp){
Op *pOp;
for(pOp=aOp; pOp<&aOp[nOp]; pOp++){
freeP4(db, pOp->p4type, pOp->p4.p);
-#ifdef SQLITE_DEBUG
+#ifdef SQLITE_ENABLE_EXPLAIN_COMMENTS
sqlite3DbFree(db, pOp->zComment);
#endif
}
@@ -59220,7 +68147,7 @@ SQLITE_PRIVATE void sqlite3VdbeLinkSubProgram(Vdbe *pVdbe, SubProgram *p){
** Change the opcode at addr into OP_Noop
*/
SQLITE_PRIVATE void sqlite3VdbeChangeToNoop(Vdbe *p, int addr){
- if( p->aOp ){
+ if( addr<p->nOp ){
VdbeOp *pOp = &p->aOp[addr];
sqlite3 *db = p->db;
freeP4(db, pOp->p4type, pOp->p4.p);
@@ -59230,6 +68157,19 @@ SQLITE_PRIVATE void sqlite3VdbeChangeToNoop(Vdbe *p, int addr){
}
/*
+** If the last opcode is "op" and it is not a jump destination,
+** then remove it. Return true if and only if an opcode was removed.
+*/
+SQLITE_PRIVATE int sqlite3VdbeDeletePriorOpcode(Vdbe *p, u8 op){
+ if( (p->nOp-1)>(p->pParse->iFixedOp) && p->aOp[p->nOp-1].opcode==op ){
+ sqlite3VdbeChangeToNoop(p, p->nOp-1);
+ return 1;
+ }else{
+ return 0;
+ }
+}
+
+/*
** 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
@@ -59239,14 +68179,6 @@ SQLITE_PRIVATE void sqlite3VdbeChangeToNoop(Vdbe *p, int addr){
** 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
@@ -59261,7 +68193,7 @@ SQLITE_PRIVATE void sqlite3VdbeChangeP4(Vdbe *p, int addr, const char *zP4, int
db = p->db;
assert( p->magic==VDBE_MAGIC_INIT );
if( p->aOp==0 || db->mallocFailed ){
- if ( n!=P4_KEYINFO && n!=P4_VTAB ) {
+ if( n!=P4_VTAB ){
freeP4(db, n, (void*)*(char**)&zP4);
}
return;
@@ -59272,7 +68204,9 @@ SQLITE_PRIVATE void sqlite3VdbeChangeP4(Vdbe *p, int addr, const char *zP4, int
addr = p->nOp - 1;
}
pOp = &p->aOp[addr];
- assert( pOp->p4type==P4_NOTUSED || pOp->p4type==P4_INT32 );
+ assert( pOp->p4type==P4_NOTUSED
+ || pOp->p4type==P4_INT32
+ || pOp->p4type==P4_KEYINFO );
freeP4(db, pOp->p4type, pOp->p4.p);
pOp->p4.p = 0;
if( n==P4_INT32 ){
@@ -59284,28 +68218,17 @@ SQLITE_PRIVATE void sqlite3VdbeChangeP4(Vdbe *p, int addr, const char *zP4, int
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;
+#ifdef SQLITE_ENABLE_CURSOR_HINTS
+ }else if( n==P4_EXPR ){
+ /* Responsibility for deleting the Expr tree is handed over to the
+ ** VDBE by this operation. The caller should have already invoked
+ ** sqlite3ExprDup() or whatever other routine is needed to make a
+ ** private copy of the tree. */
+ pOp->p4.pExpr = (Expr*)zP4;
+ pOp->p4type = P4_EXPR;
+#endif
}else if( n==P4_VTAB ){
pOp->p4.p = (void*)zP4;
pOp->p4type = P4_VTAB;
@@ -59321,7 +68244,19 @@ SQLITE_PRIVATE void sqlite3VdbeChangeP4(Vdbe *p, int addr, const char *zP4, int
}
}
-#ifndef NDEBUG
+/*
+** Set the P4 on the most recently added opcode to the KeyInfo for the
+** index given.
+*/
+SQLITE_PRIVATE void sqlite3VdbeSetP4KeyInfo(Parse *pParse, Index *pIdx){
+ Vdbe *v = pParse->pVdbe;
+ assert( v!=0 );
+ assert( pIdx!=0 );
+ sqlite3VdbeChangeP4(v, -1, (char*)sqlite3KeyInfoOfIndex(pParse, pIdx),
+ P4_KEYINFO);
+}
+
+#ifdef SQLITE_ENABLE_EXPLAIN_COMMENTS
/*
** Change the comment on the most recently coded instruction. Or
** insert a No-op and add the comment to that new instruction. This
@@ -59356,6 +68291,15 @@ SQLITE_PRIVATE void sqlite3VdbeNoopComment(Vdbe *p, const char *zFormat, ...){
}
#endif /* NDEBUG */
+#ifdef SQLITE_VDBE_COVERAGE
+/*
+** Set the value if the iSrcLine field for the previously coded instruction.
+*/
+SQLITE_PRIVATE void sqlite3VdbeSetLineNumber(Vdbe *v, int iLine){
+ sqlite3VdbeGetOp(v,-1)->iSrcLine = iLine;
+}
+#endif /* SQLITE_VDBE_COVERAGE */
+
/*
** Return the opcode for a given address. If the address is -1, then
** return the most recently inserted opcode.
@@ -59364,18 +68308,10 @@ SQLITE_PRIVATE void sqlite3VdbeNoopComment(Vdbe *p, const char *zFormat, ...){
** 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
+** after an 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
@@ -59383,9 +68319,6 @@ SQLITE_PRIVATE VdbeOp *sqlite3VdbeGetOp(Vdbe *p, int addr){
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 );
@@ -59396,8 +68329,174 @@ SQLITE_PRIVATE VdbeOp *sqlite3VdbeGetOp(Vdbe *p, int addr){
}
}
-#if !defined(SQLITE_OMIT_EXPLAIN) || !defined(NDEBUG) \
- || defined(VDBE_PROFILE) || defined(SQLITE_DEBUG)
+#if defined(SQLITE_ENABLE_EXPLAIN_COMMENTS)
+/*
+** Return an integer value for one of the parameters to the opcode pOp
+** determined by character c.
+*/
+static int translateP(char c, const Op *pOp){
+ if( c=='1' ) return pOp->p1;
+ if( c=='2' ) return pOp->p2;
+ if( c=='3' ) return pOp->p3;
+ if( c=='4' ) return pOp->p4.i;
+ return pOp->p5;
+}
+
+/*
+** Compute a string for the "comment" field of a VDBE opcode listing.
+**
+** The Synopsis: field in comments in the vdbe.c source file gets converted
+** to an extra string that is appended to the sqlite3OpcodeName(). In the
+** absence of other comments, this synopsis becomes the comment on the opcode.
+** Some translation occurs:
+**
+** "PX" -> "r[X]"
+** "PX@PY" -> "r[X..X+Y-1]" or "r[x]" if y is 0 or 1
+** "PX@PY+1" -> "r[X..X+Y]" or "r[x]" if y is 0
+** "PY..PY" -> "r[X..Y]" or "r[x]" if y<=x
+*/
+static int displayComment(
+ const Op *pOp, /* The opcode to be commented */
+ const char *zP4, /* Previously obtained value for P4 */
+ char *zTemp, /* Write result here */
+ int nTemp /* Space available in zTemp[] */
+){
+ const char *zOpName;
+ const char *zSynopsis;
+ int nOpName;
+ int ii, jj;
+ zOpName = sqlite3OpcodeName(pOp->opcode);
+ nOpName = sqlite3Strlen30(zOpName);
+ if( zOpName[nOpName+1] ){
+ int seenCom = 0;
+ char c;
+ zSynopsis = zOpName += nOpName + 1;
+ for(ii=jj=0; jj<nTemp-1 && (c = zSynopsis[ii])!=0; ii++){
+ if( c=='P' ){
+ c = zSynopsis[++ii];
+ if( c=='4' ){
+ sqlite3_snprintf(nTemp-jj, zTemp+jj, "%s", zP4);
+ }else if( c=='X' ){
+ sqlite3_snprintf(nTemp-jj, zTemp+jj, "%s", pOp->zComment);
+ seenCom = 1;
+ }else{
+ int v1 = translateP(c, pOp);
+ int v2;
+ sqlite3_snprintf(nTemp-jj, zTemp+jj, "%d", v1);
+ if( strncmp(zSynopsis+ii+1, "@P", 2)==0 ){
+ ii += 3;
+ jj += sqlite3Strlen30(zTemp+jj);
+ v2 = translateP(zSynopsis[ii], pOp);
+ if( strncmp(zSynopsis+ii+1,"+1",2)==0 ){
+ ii += 2;
+ v2++;
+ }
+ if( v2>1 ){
+ sqlite3_snprintf(nTemp-jj, zTemp+jj, "..%d", v1+v2-1);
+ }
+ }else if( strncmp(zSynopsis+ii+1, "..P3", 4)==0 && pOp->p3==0 ){
+ ii += 4;
+ }
+ }
+ jj += sqlite3Strlen30(zTemp+jj);
+ }else{
+ zTemp[jj++] = c;
+ }
+ }
+ if( !seenCom && jj<nTemp-5 && pOp->zComment ){
+ sqlite3_snprintf(nTemp-jj, zTemp+jj, "; %s", pOp->zComment);
+ jj += sqlite3Strlen30(zTemp+jj);
+ }
+ if( jj<nTemp ) zTemp[jj] = 0;
+ }else if( pOp->zComment ){
+ sqlite3_snprintf(nTemp, zTemp, "%s", pOp->zComment);
+ jj = sqlite3Strlen30(zTemp);
+ }else{
+ zTemp[0] = 0;
+ jj = 0;
+ }
+ return jj;
+}
+#endif /* SQLITE_DEBUG */
+
+#if VDBE_DISPLAY_P4 && defined(SQLITE_ENABLE_CURSOR_HINTS)
+/*
+** Translate the P4.pExpr value for an OP_CursorHint opcode into text
+** that can be displayed in the P4 column of EXPLAIN output.
+*/
+static int displayP4Expr(int nTemp, char *zTemp, Expr *pExpr){
+ const char *zOp = 0;
+ int n;
+ switch( pExpr->op ){
+ case TK_STRING:
+ sqlite3_snprintf(nTemp, zTemp, "%Q", pExpr->u.zToken);
+ break;
+ case TK_INTEGER:
+ sqlite3_snprintf(nTemp, zTemp, "%d", pExpr->u.iValue);
+ break;
+ case TK_NULL:
+ sqlite3_snprintf(nTemp, zTemp, "NULL");
+ break;
+ case TK_REGISTER: {
+ sqlite3_snprintf(nTemp, zTemp, "r[%d]", pExpr->iTable);
+ break;
+ }
+ case TK_COLUMN: {
+ if( pExpr->iColumn<0 ){
+ sqlite3_snprintf(nTemp, zTemp, "rowid");
+ }else{
+ sqlite3_snprintf(nTemp, zTemp, "c%d", (int)pExpr->iColumn);
+ }
+ break;
+ }
+ case TK_LT: zOp = "LT"; break;
+ case TK_LE: zOp = "LE"; break;
+ case TK_GT: zOp = "GT"; break;
+ case TK_GE: zOp = "GE"; break;
+ case TK_NE: zOp = "NE"; break;
+ case TK_EQ: zOp = "EQ"; break;
+ case TK_IS: zOp = "IS"; break;
+ case TK_ISNOT: zOp = "ISNOT"; break;
+ case TK_AND: zOp = "AND"; break;
+ case TK_OR: zOp = "OR"; break;
+ case TK_PLUS: zOp = "ADD"; break;
+ case TK_STAR: zOp = "MUL"; break;
+ case TK_MINUS: zOp = "SUB"; break;
+ case TK_REM: zOp = "REM"; break;
+ case TK_BITAND: zOp = "BITAND"; break;
+ case TK_BITOR: zOp = "BITOR"; break;
+ case TK_SLASH: zOp = "DIV"; break;
+ case TK_LSHIFT: zOp = "LSHIFT"; break;
+ case TK_RSHIFT: zOp = "RSHIFT"; break;
+ case TK_CONCAT: zOp = "CONCAT"; break;
+ case TK_UMINUS: zOp = "MINUS"; break;
+ case TK_UPLUS: zOp = "PLUS"; break;
+ case TK_BITNOT: zOp = "BITNOT"; break;
+ case TK_NOT: zOp = "NOT"; break;
+ case TK_ISNULL: zOp = "ISNULL"; break;
+ case TK_NOTNULL: zOp = "NOTNULL"; break;
+
+ default:
+ sqlite3_snprintf(nTemp, zTemp, "%s", "expr");
+ break;
+ }
+
+ if( zOp ){
+ sqlite3_snprintf(nTemp, zTemp, "%s(", zOp);
+ n = sqlite3Strlen30(zTemp);
+ n += displayP4Expr(nTemp-n, zTemp+n, pExpr->pLeft);
+ if( n<nTemp-1 && pExpr->pRight ){
+ zTemp[n++] = ',';
+ n += displayP4Expr(nTemp-n, zTemp+n, pExpr->pRight);
+ }
+ sqlite3_snprintf(nTemp-n, zTemp+n, ")");
+ }
+ return sqlite3Strlen30(zTemp);
+}
+#endif /* VDBE_DISPLAY_P4 && defined(SQLITE_ENABLE_CURSOR_HINTS) */
+
+
+#if VDBE_DISPLAY_P4
/*
** Compute a string that describes the P4 parameter for an opcode.
** Use zTemp for any required temporary buffer space.
@@ -59406,19 +68505,23 @@ 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);
+ sqlite3_snprintf(nTemp, zTemp, "k(%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 ){
+ if( n==6 && memcmp(zColl,"BINARY",6)==0 ){
+ zColl = "B";
+ n = 1;
+ }
+ if( i+n>nTemp-7 ){
memcpy(&zTemp[i],",...",4);
+ i += 4;
break;
}
zTemp[i++] = ',';
@@ -59433,9 +68536,15 @@ static char *displayP4(Op *pOp, char *zTemp, int nTemp){
assert( i<nTemp );
break;
}
+#ifdef SQLITE_ENABLE_CURSOR_HINTS
+ case P4_EXPR: {
+ displayP4Expr(nTemp, zTemp, pOp->p4.pExpr);
+ break;
+ }
+#endif
case P4_COLLSEQ: {
CollSeq *pColl = pOp->p4.pColl;
- sqlite3_snprintf(nTemp, zTemp, "collseq(%.20s)", pColl->zName);
+ sqlite3_snprintf(nTemp, zTemp, "(%.20s)", pColl->zName);
break;
}
case P4_FUNCDEF: {
@@ -59443,6 +68552,13 @@ static char *displayP4(Op *pOp, char *zTemp, int nTemp){
sqlite3_snprintf(nTemp, zTemp, "%s(%d)", pDef->zName, pDef->nArg);
break;
}
+#ifdef SQLITE_DEBUG
+ case P4_FUNCCTX: {
+ FuncDef *pDef = pOp->p4.pCtx->pFunc;
+ sqlite3_snprintf(nTemp, zTemp, "%s(%d)", pDef->zName, pDef->nArg);
+ break;
+ }
+#endif
case P4_INT64: {
sqlite3_snprintf(nTemp, zTemp, "%lld", *pOp->p4.pI64);
break;
@@ -59462,7 +68578,7 @@ static char *displayP4(Op *pOp, char *zTemp, int nTemp){
}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);
+ sqlite3_snprintf(nTemp, zTemp, "%.16g", pMem->u.r);
}else if( pMem->flags & MEM_Null ){
sqlite3_snprintf(nTemp, zTemp, "NULL");
}else{
@@ -59474,7 +68590,7 @@ static char *displayP4(Op *pOp, char *zTemp, int nTemp){
#ifndef SQLITE_OMIT_VIRTUALTABLE
case P4_VTAB: {
sqlite3_vtab *pVtab = pOp->p4.pVtab->pVtab;
- sqlite3_snprintf(nTemp, zTemp, "vtab:%p:%p", pVtab, pVtab->pModule);
+ sqlite3_snprintf(nTemp, zTemp, "vtab:%p", pVtab);
break;
}
#endif
@@ -59501,7 +68617,7 @@ static char *displayP4(Op *pOp, char *zTemp, int nTemp){
assert( zP4!=0 );
return zP4;
}
-#endif
+#endif /* VDBE_DISPLAY_P4 */
/*
** Declare to the Vdbe that the BTree object at db->aDb[i] is used.
@@ -59514,9 +68630,9 @@ static char *displayP4(Op *pOp, char *zTemp, int nTemp){
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;
+ DbMaskSet(p->btreeMask, i);
if( i!=1 && sqlite3BtreeSharable(p->db->aDb[i].pBt) ){
- p->lockMask |= ((yDbMask)1)<<i;
+ DbMaskSet(p->lockMask, i);
}
}
@@ -59544,16 +68660,15 @@ SQLITE_PRIVATE void sqlite3VdbeUsesBtree(Vdbe *p, int i){
*/
SQLITE_PRIVATE void sqlite3VdbeEnter(Vdbe *p){
int i;
- yDbMask mask;
sqlite3 *db;
Db *aDb;
int nDb;
- if( p->lockMask==0 ) return; /* The common case */
+ if( DbMaskAllZero(p->lockMask) ) 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) ){
+ for(i=0; i<nDb; i++){
+ if( i!=1 && DbMaskTest(p->lockMask,i) && ALWAYS(aDb[i].pBt!=0) ){
sqlite3BtreeEnter(aDb[i].pBt);
}
}
@@ -59564,22 +68679,24 @@ SQLITE_PRIVATE void sqlite3VdbeEnter(Vdbe *p){
/*
** Unlock all of the btrees previously locked by a call to sqlite3VdbeEnter().
*/
-SQLITE_PRIVATE void sqlite3VdbeLeave(Vdbe *p){
+static SQLITE_NOINLINE void vdbeLeave(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) ){
+ for(i=0; i<nDb; i++){
+ if( i!=1 && DbMaskTest(p->lockMask,i) && ALWAYS(aDb[i].pBt!=0) ){
sqlite3BtreeLeave(aDb[i].pBt);
}
}
}
+SQLITE_PRIVATE void sqlite3VdbeLeave(Vdbe *p){
+ if( DbMaskAllZero(p->lockMask) ) return; /* The common case */
+ vdbeLeave(p);
+}
#endif
#if defined(VDBE_PROFILE) || defined(SQLITE_DEBUG)
@@ -59589,16 +68706,21 @@ SQLITE_PRIVATE void sqlite3VdbeLeave(Vdbe *p){
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";
+ char zCom[100];
+ static const char *zFormat1 = "%4d %-13s %4d %4d %4d %-13s %.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 : ""
+#ifdef SQLITE_ENABLE_EXPLAIN_COMMENTS
+ displayComment(pOp, zP4, zCom, sizeof(zCom));
#else
- ""
+ zCom[0] = 0;
#endif
+ /* NB: The sqlite3OpcodeName() function is implemented by code created
+ ** by the mkopcodeh.awk and mkopcodec.awk scripts which extract the
+ ** information from the vdbe.c source text */
+ fprintf(pOut, zFormat1, pc,
+ sqlite3OpcodeName(pOp->opcode), pOp->p1, pOp->p2, pOp->p3, zP4, pOp->p5,
+ zCom
);
fflush(pOut);
}
@@ -59609,17 +68731,18 @@ SQLITE_PRIVATE void sqlite3VdbePrintOp(FILE *pOut, int pc, Op *pOp){
*/
static void releaseMemArray(Mem *p, int N){
if( p && N ){
- Mem *pEnd;
+ Mem *pEnd = &p[N];
sqlite3 *db = p->db;
u8 malloc_failed = db->mallocFailed;
if( db->pnBytesFreed ){
- for(pEnd=&p[N]; p<pEnd; p++){
- sqlite3DbFree(db, p->zMalloc);
- }
+ do{
+ if( p->szMalloc ) sqlite3DbFree(db, p->zMalloc);
+ }while( (++p)<pEnd );
return;
}
- for(pEnd=&p[N]; p<pEnd; p++){
+ do{
assert( (&p[1])==pEnd || p[0].db==p[1].db );
+ assert( sqlite3VdbeCheckMemInvariants(p) );
/* This block is really an inlined version of sqlite3VdbeMemRelease()
** that takes advantage of the fact that the memory cell value is
@@ -59633,15 +68756,19 @@ static void releaseMemArray(Mem *p, int N){
** with no indexes using a single prepared INSERT statement, bind()
** and reset(). Inserts are grouped into a transaction.
*/
+ testcase( p->flags & MEM_Agg );
+ testcase( p->flags & MEM_Dyn );
+ testcase( p->flags & MEM_Frame );
+ testcase( p->flags & MEM_RowSet );
if( p->flags&(MEM_Agg|MEM_Dyn|MEM_Frame|MEM_RowSet) ){
sqlite3VdbeMemRelease(p);
- }else if( p->zMalloc ){
+ }else if( p->szMalloc ){
sqlite3DbFree(db, p->zMalloc);
- p->zMalloc = 0;
+ p->szMalloc = 0;
}
- p->flags = MEM_Invalid;
- }
+ p->flags = MEM_Undefined;
+ }while( (++p)<pEnd );
db->mallocFailed = malloc_failed;
}
}
@@ -59742,9 +68869,9 @@ SQLITE_PRIVATE int sqlite3VdbeList(
}else if( db->u1.isInterrupted ){
p->rc = SQLITE_INTERRUPT;
rc = SQLITE_ERROR;
- sqlite3SetString(&p->zErrMsg, db, "%s", sqlite3ErrStr(p->rc));
+ sqlite3VdbeError(p, sqlite3ErrStr(p->rc));
}else{
- char *z;
+ char *zP4;
Op *pOp;
if( i<p->nOp ){
/* The output line number is small enough that we are still in the
@@ -59762,15 +68889,13 @@ SQLITE_PRIVATE int sqlite3VdbeList(
}
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 */
+ 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++;
@@ -59796,60 +68921,53 @@ SQLITE_PRIVATE int sqlite3VdbeList(
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 */
+ if( sqlite3VdbeMemClearAndResize(pMem, 100) ){ /* 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);
+ pMem->flags = MEM_Str|MEM_Term;
+ zP4 = displayP4(pOp, pMem->z, pMem->szMalloc);
+ if( zP4!=pMem->z ){
+ sqlite3VdbeMemSetStr(pMem, zP4, -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) ){
+ if( sqlite3VdbeMemClearAndResize(pMem, 4) ){
assert( p->db->mallocFailed );
return SQLITE_ERROR;
}
- pMem->flags = MEM_Dyn|MEM_Str|MEM_Term;
+ pMem->flags = 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;
+#ifdef SQLITE_ENABLE_EXPLAIN_COMMENTS
+ if( sqlite3VdbeMemClearAndResize(pMem, 500) ){
+ assert( p->db->mallocFailed );
+ return SQLITE_ERROR;
}
+ pMem->flags = MEM_Str|MEM_Term;
+ pMem->n = displayComment(pOp, zP4, pMem->z, 500);
+ pMem->enc = SQLITE_UTF8;
+#else
+ pMem->flags = MEM_Null; /* Comment */
+#endif
}
p->nResColumn = 8 - 4*(p->explain-1);
@@ -59866,15 +68984,17 @@ SQLITE_PRIVATE int sqlite3VdbeList(
** 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);
+ const char *z = 0;
+ if( p->zSql ){
+ z = p->zSql;
+ }else if( p->nOp>=1 ){
+ const VdbeOp *pOp = &p->aOp[0];
+ if( pOp->opcode==OP_Init && pOp->p4.z!=0 ){
+ z = pOp->p4.z;
+ while( sqlite3Isspace(*z) ) z++;
+ }
}
+ if( z ) printf("SQL: [%s]\n", z);
}
#endif
@@ -59888,7 +69008,7 @@ SQLITE_PRIVATE void sqlite3VdbeIOTraceSql(Vdbe *p){
if( sqlite3IoTrace==0 ) return;
if( nOp<1 ) return;
pOp = &p->aOp[0];
- if( pOp->opcode==OP_Trace && pOp->p4.z!=0 ){
+ if( pOp->opcode==OP_Init && pOp->p4.z!=0 ){
int i, j;
char z[1000];
sqlite3_snprintf(sizeof(z), z, "%s", pOp->p4.z);
@@ -59921,30 +69041,31 @@ SQLITE_PRIVATE void sqlite3VdbeIOTraceSql(Vdbe *p){
**
** 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.
+** pFrom points to *pnFrom bytes of available space. New space is allocated
+** from the end of the pFrom buffer and *pnFrom is decremented.
**
-** *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.
+** *pnNeeded is a counter of the number of bytes of space that have failed
+** to allocate. If there is insufficient space in pFrom to satisfy the
+** request, then increment *pnNeeded 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;
+ u8 *pFrom, /* Memory available for allocation */
+ int *pnFrom, /* IN/OUT: Space available at pFrom */
+ int *pnNeeded /* If allocation cannot be made, increment *pnByte */
+){
+ assert( EIGHT_BYTE_ALIGNMENT(pFrom) );
+ if( pBuf==0 ){
+ nByte = ROUND8(nByte);
+ if( nByte <= *pnFrom ){
+ *pnFrom -= nByte;
+ pBuf = &pFrom[*pnFrom];
+ }else{
+ *pnNeeded += nByte;
+ }
}
+ assert( EIGHT_BYTE_ALIGNMENT(pBuf) );
return pBuf;
}
@@ -59991,13 +69112,13 @@ SQLITE_PRIVATE void sqlite3VdbeRewind(Vdbe *p){
/*
** 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.
+** as allocating registers 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.
+** This function may be called exactly once on 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
+** to run. After this routine is called, further 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
@@ -60017,14 +69138,15 @@ SQLITE_PRIVATE void sqlite3VdbeMakeReady(
int nArg; /* Number of arguments in subprograms */
int nOnce; /* Number of OP_Once instructions */
int n; /* Loop counter */
+ int nFree; /* Available free space */
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 );
+ assert( pParse==p->pParse );
db = p->db;
assert( db->mallocFailed==0 );
nVar = pParse->nVar;
@@ -60045,20 +69167,27 @@ SQLITE_PRIVATE void sqlite3VdbeMakeReady(
*/
nMem += nCursor;
- /* Allocate space for memory registers, SQL variables, VDBE cursors and
- ** an array to marshal SQL function arguments in.
+ /* zCsr will initially point to nFree bytes of unused space at the
+ ** end of the opcode array, p->aOp. The computation of nFree is
+ ** conservative - it might be smaller than the true number of free
+ ** bytes, but never larger. nFree must be a multiple of 8 - it is
+ ** rounded down if is not.
*/
- zCsr = (u8*)&p->aOp[p->nOp]; /* Memory avaliable for allocation */
- zEnd = (u8*)&p->aOp[p->nOpAlloc]; /* First byte past end of zCsr[] */
+ n = ROUND8(sizeof(Op)*p->nOp); /* Bytes of opcode space used */
+ zCsr = &((u8*)p->aOp)[n]; /* Unused opcode space */
+ assert( EIGHT_BYTE_ALIGNMENT(zCsr) );
+ nFree = ROUNDDOWN8(pParse->szOpAlloc - n); /* Bytes of unused space */
+ assert( nFree>=0 );
+ if( nFree>0 ){
+ memset(zCsr, 0, nFree);
+ assert( EIGHT_BYTE_ALIGNMENT(&zCsr[nFree]) );
+ }
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
@@ -60073,21 +69202,24 @@ SQLITE_PRIVATE void sqlite3VdbeMakeReady(
*/
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->aMem = allocSpace(p->aMem, nMem*sizeof(Mem), zCsr, &nFree, &nByte);
+ p->aVar = allocSpace(p->aVar, nVar*sizeof(Mem), zCsr, &nFree, &nByte);
+ p->apArg = allocSpace(p->apArg, nArg*sizeof(Mem*), zCsr, &nFree, &nByte);
+ p->azVar = allocSpace(p->azVar, nVar*sizeof(char*), zCsr, &nFree, &nByte);
p->apCsr = allocSpace(p->apCsr, nCursor*sizeof(VdbeCursor*),
- &zCsr, zEnd, &nByte);
- p->aOnceFlag = allocSpace(p->aOnceFlag, nOnce, &zCsr, zEnd, &nByte);
+ zCsr, &nFree, &nByte);
+ p->aOnceFlag = allocSpace(p->aOnceFlag, nOnce, zCsr, &nFree, &nByte);
+#ifdef SQLITE_ENABLE_STMT_SCANSTATUS
+ p->anExec = allocSpace(p->anExec, p->nOp*sizeof(i64), zCsr, &nFree, &nByte);
+#endif
if( nByte ){
p->pFree = sqlite3DbMallocZero(db, nByte);
}
zCsr = p->pFree;
- zEnd = &zCsr[nByte];
+ nFree = nByte;
}while( nByte && !db->mallocFailed );
- p->nCursor = (u16)nCursor;
+ p->nCursor = nCursor;
p->nOnceFlag = nOnce;
if( p->aVar ){
p->nVar = (ynVar)nVar;
@@ -60096,7 +69228,7 @@ SQLITE_PRIVATE void sqlite3VdbeMakeReady(
p->aVar[n].db = db;
}
}
- if( p->azVar ){
+ if( p->azVar && pParse->nzVar>0 ){
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]));
@@ -60105,7 +69237,7 @@ SQLITE_PRIVATE void sqlite3VdbeMakeReady(
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].flags = MEM_Undefined;
p->aMem[n].db = db;
}
}
@@ -60121,23 +69253,50 @@ 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);
- }
+ assert( pCx->pBt==0 || pCx->eCurType==CURTYPE_BTREE );
+ switch( pCx->eCurType ){
+ case CURTYPE_SORTER: {
+ sqlite3VdbeSorterClose(p->db, pCx);
+ break;
+ }
+ case CURTYPE_BTREE: {
+ if( pCx->pBt ){
+ sqlite3BtreeClose(pCx->pBt);
+ /* The pCx->pCursor will be close automatically, if it exists, by
+ ** the call above. */
+ }else{
+ assert( pCx->uc.pCursor!=0 );
+ sqlite3BtreeCloseCursor(pCx->uc.pCursor);
+ }
+ break;
+ }
#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;
- }
+ case CURTYPE_VTAB: {
+ sqlite3_vtab_cursor *pVCur = pCx->uc.pVCur;
+ const sqlite3_module *pModule = pVCur->pVtab->pModule;
+ assert( pVCur->pVtab->nRef>0 );
+ pVCur->pVtab->nRef--;
+ pModule->xClose(pVCur);
+ break;
+ }
#endif
+ }
+}
+
+/*
+** Close all cursors in the current frame.
+*/
+static void closeCursorsInFrame(Vdbe *p){
+ 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;
+ }
+ }
+ }
}
/*
@@ -60147,6 +69306,10 @@ SQLITE_PRIVATE void sqlite3VdbeFreeCursor(Vdbe *p, VdbeCursor *pCx){
*/
SQLITE_PRIVATE int sqlite3VdbeFrameRestore(VdbeFrame *pFrame){
Vdbe *v = pFrame->v;
+ closeCursorsInFrame(v);
+#ifdef SQLITE_ENABLE_STMT_SCANSTATUS
+ v->anExec = pFrame->anExec;
+#endif
v->aOnceFlag = pFrame->aOnceFlag;
v->nOnceFlag = pFrame->nOnceFlag;
v->aOp = pFrame->aOp;
@@ -60157,6 +69320,7 @@ SQLITE_PRIVATE int sqlite3VdbeFrameRestore(VdbeFrame *pFrame){
v->nCursor = pFrame->nCursor;
v->db->lastRowid = pFrame->lastRowid;
v->nChange = pFrame->nChange;
+ v->db->nChange = pFrame->nDbChange;
return pFrame->pc;
}
@@ -60173,20 +69337,11 @@ static void closeAllCursors(Vdbe *p){
VdbeFrame *pFrame;
for(pFrame=p->pFrame; pFrame->pParent; pFrame=pFrame->pParent);
sqlite3VdbeFrameRestore(pFrame);
+ p->pFrame = 0;
+ p->nFrame = 0;
}
- 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;
- }
- }
- }
+ assert( p->nFrame==0 );
+ closeCursorsInFrame(p);
if( p->aMem ){
releaseMemArray(&p->aMem[1], p->nMem);
}
@@ -60195,14 +69350,14 @@ static void closeAllCursors(Vdbe *p){
p->pDelFrame = pDel->pParent;
sqlite3VdbeFrameDelete(pDel);
}
+
+ /* Delete any auxdata allocations made by the VM */
+ if( p->pAuxData ) sqlite3VdbeDeleteAuxData(p, -1, 0);
+ assert( p->pAuxData==0 );
}
/*
-** 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.
+** Clean up the VM after a single run.
*/
static void Cleanup(Vdbe *p){
sqlite3 *db = p->db;
@@ -60213,7 +69368,7 @@ static void Cleanup(Vdbe *p){
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 );
+ for(i=1; i<=p->nMem; i++) assert( p->aMem[i].flags==MEM_Undefined );
}
#endif
@@ -60303,7 +69458,7 @@ static int vdbeCommit(sqlite3 *db, Vdbe *p){
** required, as an xSync() callback may add an attached database
** to the transaction.
*/
- rc = sqlite3VtabSync(db, &p->zErrMsg);
+ rc = sqlite3VtabSync(db, p);
/* This loop determines (a) if the commit hook should be invoked and
** (b) how many database files have open write transactions, not
@@ -60329,7 +69484,7 @@ static int vdbeCommit(sqlite3 *db, Vdbe *p){
if( needXcommit && db->xCommitCallback ){
rc = db->xCommitCallback(db->pCommitArg);
if( rc ){
- return SQLITE_CONSTRAINT;
+ return SQLITE_CONSTRAINT_COMMITHOOK;
}
}
@@ -60370,7 +69525,7 @@ static int vdbeCommit(sqlite3 *db, Vdbe *p){
/* The complex case - There is a multi-file write-transaction active.
** This requires a master journal file to ensure the transaction is
- ** committed atomicly.
+ ** committed atomically.
*/
#ifndef SQLITE_OMIT_DISKIO
else{
@@ -60489,7 +69644,7 @@ static int vdbeCommit(sqlite3 *db, Vdbe *p){
** doing this the directory is synced again before any individual
** transaction files are deleted.
*/
- rc = sqlite3OsDelete(pVfs, zMaster, 1);
+ rc = sqlite3OsDelete(pVfs, zMaster, needSync);
sqlite3DbFree(db, zMaster);
zMaster = 0;
if( rc ){
@@ -60522,7 +69677,7 @@ static int vdbeCommit(sqlite3 *db, Vdbe *p){
}
/*
-** This routine checks that the sqlite3.activeVdbeCnt count variable
+** This routine checks that the sqlite3.nVdbeActive 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
@@ -60535,16 +69690,19 @@ static void checkActiveVdbeCnt(sqlite3 *db){
Vdbe *p;
int cnt = 0;
int nWrite = 0;
+ int nRead = 0;
p = db->pVdbe;
while( p ){
- if( p->magic==VDBE_MAGIC_RUN && p->pc>=0 ){
+ if( sqlite3_stmt_busy((sqlite3_stmt*)p) ){
cnt++;
if( p->readOnly==0 ) nWrite++;
+ if( p->bIsReader ) nRead++;
}
p = p->pNext;
}
- assert( cnt==db->activeVdbeCnt );
- assert( nWrite==db->writeVdbeCnt );
+ assert( cnt==db->nVdbeActive );
+ assert( nWrite==db->nVdbeWrite );
+ assert( nRead==db->nVdbeRead );
}
#else
#define checkActiveVdbeCnt(x)
@@ -60555,7 +69713,7 @@ static void checkActiveVdbeCnt(sqlite3 *db){
** 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.
+** statement transaction is committed.
**
** If an IO error occurs, an SQLITE_IOERR_XXX error code is returned.
** Otherwise SQLITE_OK.
@@ -60566,7 +69724,7 @@ SQLITE_PRIVATE int sqlite3VdbeCloseStatement(Vdbe *p, int eOp){
/* 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.
+ ** is that an IO error may have occurred, causing an emergency rollback.
** In this case (db->nStatement==0), and there is nothing to do.
*/
if( db->nStatement && p->iStatement ){
@@ -60609,6 +69767,7 @@ SQLITE_PRIVATE int sqlite3VdbeCloseStatement(Vdbe *p, int eOp){
** the statement transaction was opened. */
if( eOp==SAVEPOINT_ROLLBACK ){
db->nDeferredCons = p->nStmtDefCons;
+ db->nDeferredImmCons = p->nStmtDefImmCons;
}
}
return rc;
@@ -60621,16 +69780,18 @@ SQLITE_PRIVATE int sqlite3VdbeCloseStatement(Vdbe *p, int eOp){
** 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.
+** SQLITE_ERROR, set the result of the VM to SQLITE_CONSTRAINT_FOREIGNKEY
+** 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;
+ if( (deferred && (db->nDeferredCons+db->nDeferredImmCons)>0)
+ || (!deferred && p->nFkConstraint>0)
+ ){
+ p->rc = SQLITE_CONSTRAINT_FOREIGNKEY;
p->errorAction = OE_Abort;
- sqlite3SetString(&p->zErrMsg, db, "foreign key constraint failed");
+ sqlite3VdbeError(p, "FOREIGN KEY constraint failed");
return SQLITE_ERROR;
}
return SQLITE_OK;
@@ -60680,8 +69841,9 @@ SQLITE_PRIVATE int sqlite3VdbeHalt(Vdbe *p){
}
checkActiveVdbeCnt(db);
- /* No commit or rollback needed if the program never started */
- if( p->pc>=0 ){
+ /* No commit or rollback needed if the program never started or if the
+ ** SQL statement does not read or write a database file. */
+ if( p->pc>=0 && p->bIsReader ){
int mrc; /* Primary error code from p->rc */
int eStatementOp = 0;
int isSpecialError; /* Set to true if a 'special' error */
@@ -60691,7 +69853,6 @@ SQLITE_PRIVATE int sqlite3VdbeHalt(Vdbe *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 ){
@@ -60702,7 +69863,7 @@ SQLITE_PRIVATE int sqlite3VdbeHalt(Vdbe *p){
**
** 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
+ ** occurred 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.
@@ -60717,6 +69878,7 @@ SQLITE_PRIVATE int sqlite3VdbeHalt(Vdbe *p){
sqlite3RollbackAll(db, SQLITE_ABORT_ROLLBACK);
sqlite3CloseSavepoints(db);
db->autoCommit = 1;
+ p->nChange = 0;
}
}
}
@@ -60734,7 +69896,7 @@ SQLITE_PRIVATE int sqlite3VdbeHalt(Vdbe *p){
*/
if( !sqlite3VtabInSync(db)
&& db->autoCommit
- && db->writeVdbeCnt==(p->readOnly==0)
+ && db->nVdbeWrite==(p->readOnly==0)
){
if( p->rc==SQLITE_OK || (p->errorAction==OE_Fail && !isSpecialError) ){
rc = sqlite3VdbeCheckFk(p, 1);
@@ -60743,7 +69905,7 @@ SQLITE_PRIVATE int sqlite3VdbeHalt(Vdbe *p){
sqlite3VdbeLeave(p);
return SQLITE_ERROR;
}
- rc = SQLITE_CONSTRAINT;
+ rc = SQLITE_CONSTRAINT_FOREIGNKEY;
}else{
/* The auto-commit flag is true, the vdbe program was successful
** or hit an 'OR FAIL' constraint and there are no deferred foreign
@@ -60757,12 +69919,16 @@ SQLITE_PRIVATE int sqlite3VdbeHalt(Vdbe *p){
}else if( rc!=SQLITE_OK ){
p->rc = rc;
sqlite3RollbackAll(db, SQLITE_OK);
+ p->nChange = 0;
}else{
db->nDeferredCons = 0;
+ db->nDeferredImmCons = 0;
+ db->flags &= ~SQLITE_DeferFKs;
sqlite3CommitInternalChanges(db);
}
}else{
sqlite3RollbackAll(db, SQLITE_OK);
+ p->nChange = 0;
}
db->nStatement = 0;
}else if( eStatementOp==0 ){
@@ -60774,6 +69940,7 @@ SQLITE_PRIVATE int sqlite3VdbeHalt(Vdbe *p){
sqlite3RollbackAll(db, SQLITE_ABORT_ROLLBACK);
sqlite3CloseSavepoints(db);
db->autoCommit = 1;
+ p->nChange = 0;
}
}
@@ -60786,7 +69953,7 @@ SQLITE_PRIVATE int sqlite3VdbeHalt(Vdbe *p){
if( eStatementOp ){
rc = sqlite3VdbeCloseStatement(p, eStatementOp);
if( rc ){
- if( p->rc==SQLITE_OK || p->rc==SQLITE_CONSTRAINT ){
+ if( p->rc==SQLITE_OK || (p->rc&0xff)==SQLITE_CONSTRAINT ){
p->rc = rc;
sqlite3DbFree(db, p->zErrMsg);
p->zErrMsg = 0;
@@ -60794,6 +69961,7 @@ SQLITE_PRIVATE int sqlite3VdbeHalt(Vdbe *p){
sqlite3RollbackAll(db, SQLITE_ABORT_ROLLBACK);
sqlite3CloseSavepoints(db);
db->autoCommit = 1;
+ p->nChange = 0;
}
}
@@ -60815,11 +69983,12 @@ SQLITE_PRIVATE int sqlite3VdbeHalt(Vdbe *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 );
+ db->nVdbeActive--;
+ if( !p->readOnly ) db->nVdbeWrite--;
+ if( p->bIsReader ) db->nVdbeRead--;
+ assert( db->nVdbeActive>=db->nVdbeRead );
+ assert( db->nVdbeRead>=db->nVdbeWrite );
+ assert( db->nVdbeWrite>=0 );
}
p->magic = VDBE_MAGIC_HALT;
checkActiveVdbeCnt(db);
@@ -60835,7 +70004,7 @@ SQLITE_PRIVATE int sqlite3VdbeHalt(Vdbe *p){
sqlite3ConnectionUnlocked(db);
}
- assert( db->activeVdbeCnt>0 || db->autoCommit==0 || db->nStatement==0 );
+ assert( db->nVdbeActive>0 || db->autoCommit==0 || db->nStatement==0 );
return (p->rc==SQLITE_BUSY ? SQLITE_BUSY : SQLITE_OK);
}
@@ -60862,12 +70031,13 @@ SQLITE_PRIVATE int sqlite3VdbeTransferError(Vdbe *p){
if( p->zErrMsg ){
u8 mallocFailed = db->mallocFailed;
sqlite3BeginBenignMalloc();
+ if( db->pErr==0 ) db->pErr = sqlite3ValueNew(db);
sqlite3ValueSetStr(db->pErr, -1, p->zErrMsg, SQLITE_UTF8, SQLITE_TRANSIENT);
sqlite3EndBenignMalloc();
db->mallocFailed = mallocFailed;
db->errCode = rc;
}else{
- sqlite3Error(db, rc, 0);
+ sqlite3Error(db, rc);
}
return rc;
}
@@ -60930,8 +70100,7 @@ SQLITE_PRIVATE int sqlite3VdbeReset(Vdbe *p){
** 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);
+ sqlite3ErrorWithMsg(db, p->rc, p->zErrMsg ? "%s" : 0, p->zErrMsg);
sqlite3DbFree(db, p->zErrMsg);
p->zErrMsg = 0;
}
@@ -60952,18 +70121,31 @@ SQLITE_PRIVATE int sqlite3VdbeReset(Vdbe *p){
fprintf(out, "%02x", p->aOp[i].opcode);
}
fprintf(out, "\n");
+ if( p->zSql ){
+ char c, pc = 0;
+ fprintf(out, "-- ");
+ for(i=0; (c = p->zSql[i])!=0; i++){
+ if( pc=='\n' ) fprintf(out, "-- ");
+ putc(c, out);
+ pc = c;
+ }
+ if( pc!='\n' ) fprintf(out, "\n");
+ }
for(i=0; i<p->nOp; i++){
- fprintf(out, "%6d %10lld %8lld ",
+ char zHdr[100];
+ sqlite3_snprintf(sizeof(zHdr), zHdr, "%6u %12llu %8llu ",
p->aOp[i].cnt,
p->aOp[i].cycles,
p->aOp[i].cnt>0 ? p->aOp[i].cycles/p->aOp[i].cnt : 0
);
+ fprintf(out, "%s", zHdr);
sqlite3VdbePrintOp(out, i, &p->aOp[i]);
}
fclose(out);
}
}
#endif
+ p->iCurrentTime = 0;
p->magic = VDBE_MAGIC_INIT;
return p->rc & db->errMask;
}
@@ -60983,20 +70165,36 @@ SQLITE_PRIVATE int sqlite3VdbeFinalize(Vdbe *p){
}
/*
-** 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.
+** If parameter iOp is less than zero, then invoke the destructor for
+** all auxiliary data pointers currently cached by the VM passed as
+** the first argument.
+**
+** Or, if iOp is greater than or equal to zero, then the destructor is
+** only invoked for those auxiliary data pointers created by the user
+** function invoked by the OP_Function opcode at instruction iOp of
+** VM pVdbe, and only then if:
+**
+** * the associated function parameter is the 32nd or later (counting
+** from left to right), or
+**
+** * the corresponding bit in argument mask is clear (where the first
+** function parameter corresponds to bit 0 etc.).
*/
-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 ){
+SQLITE_PRIVATE void sqlite3VdbeDeleteAuxData(Vdbe *pVdbe, int iOp, int mask){
+ AuxData **pp = &pVdbe->pAuxData;
+ while( *pp ){
+ AuxData *pAux = *pp;
+ if( (iOp<0)
+ || (pAux->iOp==iOp && (pAux->iArg>31 || !(mask & MASKBIT32(pAux->iArg))))
+ ){
+ testcase( pAux->iArg==31 );
if( pAux->xDelete ){
pAux->xDelete(pAux->pAux);
}
- pAux->pAux = 0;
+ *pp = pAux->pNext;
+ sqlite3DbFree(pVdbe->db, pAux);
+ }else{
+ pp= &pAux->pNext;
}
}
}
@@ -61022,13 +70220,14 @@ SQLITE_PRIVATE void sqlite3VdbeClearObject(sqlite3 *db, Vdbe *p){
}
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);
+#ifdef SQLITE_ENABLE_STMT_SCANSTATUS
+ for(i=0; i<p->nScan; i++){
+ sqlite3DbFree(db, p->aScan[i].zName);
+ }
+ sqlite3DbFree(db, p->aScan);
#endif
}
@@ -61057,6 +70256,60 @@ SQLITE_PRIVATE void sqlite3VdbeDelete(Vdbe *p){
}
/*
+** The cursor "p" has a pending seek operation that has not yet been
+** carried out. Seek the cursor now. If an error occurs, return
+** the appropriate error code.
+*/
+static int SQLITE_NOINLINE handleDeferredMoveto(VdbeCursor *p){
+ int res, rc;
+#ifdef SQLITE_TEST
+ extern int sqlite3_search_count;
+#endif
+ assert( p->deferredMoveto );
+ assert( p->isTable );
+ assert( p->eCurType==CURTYPE_BTREE );
+ rc = sqlite3BtreeMovetoUnpacked(p->uc.pCursor, 0, p->movetoTarget, 0, &res);
+ if( rc ) return rc;
+ if( res!=0 ) return SQLITE_CORRUPT_BKPT;
+#ifdef SQLITE_TEST
+ sqlite3_search_count++;
+#endif
+ p->deferredMoveto = 0;
+ p->cacheStatus = CACHE_STALE;
+ return SQLITE_OK;
+}
+
+/*
+** Something has moved cursor "p" out of place. Maybe the row it was
+** pointed to was deleted out from under it. Or maybe the btree was
+** rebalanced. Whatever the cause, try to restore "p" to the place it
+** is supposed to be pointing. If the row was deleted out from under the
+** cursor, set the cursor to point to a NULL row.
+*/
+static int SQLITE_NOINLINE handleMovedCursor(VdbeCursor *p){
+ int isDifferentRow, rc;
+ assert( p->eCurType==CURTYPE_BTREE );
+ assert( p->uc.pCursor!=0 );
+ assert( sqlite3BtreeCursorHasMoved(p->uc.pCursor) );
+ rc = sqlite3BtreeCursorRestore(p->uc.pCursor, &isDifferentRow);
+ p->cacheStatus = CACHE_STALE;
+ if( isDifferentRow ) p->nullRow = 1;
+ return rc;
+}
+
+/*
+** Check to ensure that the cursor is valid. Restore the cursor
+** if need be. Return any I/O error from the restore operation.
+*/
+SQLITE_PRIVATE int sqlite3VdbeCursorRestore(VdbeCursor *p){
+ assert( p->eCurType==CURTYPE_BTREE );
+ if( sqlite3BtreeCursorHasMoved(p->uc.pCursor) ){
+ return handleMovedCursor(p);
+ }
+ return SQLITE_OK;
+}
+
+/*
** 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.
@@ -61070,29 +70323,12 @@ SQLITE_PRIVATE void sqlite3VdbeDelete(Vdbe *p){
** 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;
+ if( p->eCurType==CURTYPE_BTREE ){
+ if( p->deferredMoveto ){
+ return handleDeferredMoveto(p);
+ }
+ if( sqlite3BtreeCursorHasMoved(p->uc.pCursor) ){
+ return handleMovedCursor(p);
}
}
return SQLITE_OK;
@@ -61116,7 +70352,7 @@ SQLITE_PRIVATE int sqlite3VdbeCursorMoveto(VdbeCursor *p){
** 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.
+** serial-type and data blob separately.
**
** The following table describes the various storage classes for data:
**
@@ -61143,11 +70379,13 @@ SQLITE_PRIVATE int sqlite3VdbeCursorMoveto(VdbeCursor *p){
/*
** Return the serial-type for the value stored in pMem.
*/
-SQLITE_PRIVATE u32 sqlite3VdbeSerialType(Mem *pMem, int file_format){
+SQLITE_PRIVATE u32 sqlite3VdbeSerialType(Mem *pMem, int file_format, u32 *pLen){
int flags = pMem->flags;
- int n;
+ u32 n;
+ assert( pLen!=0 );
if( flags&MEM_Null ){
+ *pLen = 0;
return 0;
}
if( flags&MEM_Int ){
@@ -61156,44 +70394,76 @@ SQLITE_PRIVATE u32 sqlite3VdbeSerialType(Mem *pMem, int file_format){
i64 i = pMem->u.i;
u64 u;
if( i<0 ){
- if( i<(-MAX_6BYTE) ) return 6;
- /* Previous test prevents: u = -(-9223372036854775808) */
- u = -i;
+ u = ~i;
}else{
u = i;
}
if( u<=127 ){
- return ((i&1)==i && file_format>=4) ? 8+(u32)u : 1;
+ if( (i&1)==i && file_format>=4 ){
+ *pLen = 0;
+ return 8+(u32)u;
+ }else{
+ *pLen = 1;
+ return 1;
+ }
}
- if( u<=32767 ) return 2;
- if( u<=8388607 ) return 3;
- if( u<=2147483647 ) return 4;
- if( u<=MAX_6BYTE ) return 5;
+ if( u<=32767 ){ *pLen = 2; return 2; }
+ if( u<=8388607 ){ *pLen = 3; return 3; }
+ if( u<=2147483647 ){ *pLen = 4; return 4; }
+ if( u<=MAX_6BYTE ){ *pLen = 6; return 5; }
+ *pLen = 8;
return 6;
}
if( flags&MEM_Real ){
+ *pLen = 8;
return 7;
}
assert( pMem->db->mallocFailed || flags&(MEM_Str|MEM_Blob) );
- n = pMem->n;
+ assert( pMem->n>=0 );
+ n = (u32)pMem->n;
if( flags & MEM_Zero ){
n += pMem->u.nZero;
}
- assert( n>=0 );
+ *pLen = n;
return ((n*2) + 12 + ((flags&MEM_Str)!=0));
}
/*
+** The sizes for serial types less than 128
+*/
+static const u8 sqlite3SmallTypeSizes[] = {
+ /* 0 1 2 3 4 5 6 7 8 9 */
+/* 0 */ 0, 1, 2, 3, 4, 6, 8, 8, 0, 0,
+/* 10 */ 0, 0, 0, 0, 1, 1, 2, 2, 3, 3,
+/* 20 */ 4, 4, 5, 5, 6, 6, 7, 7, 8, 8,
+/* 30 */ 9, 9, 10, 10, 11, 11, 12, 12, 13, 13,
+/* 40 */ 14, 14, 15, 15, 16, 16, 17, 17, 18, 18,
+/* 50 */ 19, 19, 20, 20, 21, 21, 22, 22, 23, 23,
+/* 60 */ 24, 24, 25, 25, 26, 26, 27, 27, 28, 28,
+/* 70 */ 29, 29, 30, 30, 31, 31, 32, 32, 33, 33,
+/* 80 */ 34, 34, 35, 35, 36, 36, 37, 37, 38, 38,
+/* 90 */ 39, 39, 40, 40, 41, 41, 42, 42, 43, 43,
+/* 100 */ 44, 44, 45, 45, 46, 46, 47, 47, 48, 48,
+/* 110 */ 49, 49, 50, 50, 51, 51, 52, 52, 53, 53,
+/* 120 */ 54, 54, 55, 55, 56, 56, 57, 57
+};
+
+/*
** Return the length of the data corresponding to the supplied serial-type.
*/
SQLITE_PRIVATE u32 sqlite3VdbeSerialTypeLen(u32 serial_type){
- if( serial_type>=12 ){
+ if( serial_type>=128 ){
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];
+ assert( serial_type<12
+ || sqlite3SmallTypeSizes[serial_type]==(serial_type - 12)/2 );
+ return sqlite3SmallTypeSizes[serial_type];
}
}
+SQLITE_PRIVATE u8 sqlite3VdbeOneByteSerialTypeLen(u8 serial_type){
+ assert( serial_type<128 );
+ return sqlite3SmallTypeSizes[serial_type];
+}
/*
** If we are on an architecture with mixed-endian floating
@@ -61253,21 +70523,15 @@ static u64 floatSwap(u64 in){
** 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.
+** nBuf is the amount of space left in buf[]. The caller is responsible
+** for allocating enough space to buf[] to hold the entire field, exclusive
+** of the pMem->u.nZero bytes for a MEM_Zero value.
**
** 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);
+SQLITE_PRIVATE u32 sqlite3VdbeSerialPut(u8 *buf, Mem *pMem, u32 serial_type){
u32 len;
/* Integer and Real */
@@ -61275,18 +70539,18 @@ SQLITE_PRIVATE u32 sqlite3VdbeSerialPut(u8 *buf, int nBuf, Mem *pMem, int file_f
u64 v;
u32 i;
if( serial_type==7 ){
- assert( sizeof(v)==sizeof(pMem->r) );
- memcpy(&v, &pMem->r, sizeof(v));
+ assert( sizeof(v)==sizeof(pMem->u.r) );
+ memcpy(&v, &pMem->u.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);
+ len = i = sqlite3SmallTypeSizes[serial_type];
+ assert( i>0 );
+ do{
+ buf[--i] = (u8)(v&0xFF);
v >>= 8;
- }
+ }while( i );
return len;
}
@@ -61294,17 +70558,8 @@ SQLITE_PRIVATE u32 sqlite3VdbeSerialPut(u8 *buf, int nBuf, Mem *pMem, int file_f
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);
- }
+ if( len>0 ) memcpy(buf, pMem->z, len);
return len;
}
@@ -61312,10 +70567,60 @@ SQLITE_PRIVATE u32 sqlite3VdbeSerialPut(u8 *buf, int nBuf, Mem *pMem, int file_f
return 0;
}
+/* Input "x" is a sequence of unsigned characters that represent a
+** big-endian integer. Return the equivalent native integer
+*/
+#define ONE_BYTE_INT(x) ((i8)(x)[0])
+#define TWO_BYTE_INT(x) (256*(i8)((x)[0])|(x)[1])
+#define THREE_BYTE_INT(x) (65536*(i8)((x)[0])|((x)[1]<<8)|(x)[2])
+#define FOUR_BYTE_UINT(x) (((u32)(x)[0]<<24)|((x)[1]<<16)|((x)[2]<<8)|(x)[3])
+#define FOUR_BYTE_INT(x) (16777216*(i8)((x)[0])|((x)[1]<<16)|((x)[2]<<8)|(x)[3])
+
/*
** 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.
+**
+** This function is implemented as two separate routines for performance.
+** The few cases that require local variables are broken out into a separate
+** routine so that in most cases the overhead of moving the stack pointer
+** is avoided.
*/
+static u32 SQLITE_NOINLINE serialGet(
+ const unsigned char *buf, /* Buffer to deserialize from */
+ u32 serial_type, /* Serial type to deserialize */
+ Mem *pMem /* Memory cell to write value into */
+){
+ u64 x = FOUR_BYTE_UINT(buf);
+ u32 y = FOUR_BYTE_UINT(buf+4);
+ x = (x<<32) + y;
+ if( serial_type==6 ){
+ /* EVIDENCE-OF: R-29851-52272 Value is a big-endian 64-bit
+ ** twos-complement integer. */
+ pMem->u.i = *(i64*)&x;
+ pMem->flags = MEM_Int;
+ testcase( pMem->u.i<0 );
+ }else{
+ /* EVIDENCE-OF: R-57343-49114 Value is a big-endian IEEE 754-2008 64-bit
+ ** floating point number. */
+#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
+ assert( sizeof(x)==8 && sizeof(pMem->u.r)==8 );
+ swapMixedEndianFloat(x);
+ memcpy(&pMem->u.r, &x, sizeof(x));
+ pMem->flags = sqlite3IsNaN(pMem->u.r) ? MEM_Null : MEM_Real;
+ }
+ return 8;
+}
SQLITE_PRIVATE u32 sqlite3VdbeSerialGet(
const unsigned char *buf, /* Buffer to deserialize from */
u32 serial_type, /* Serial type to deserialize */
@@ -61324,91 +70629,83 @@ SQLITE_PRIVATE u32 sqlite3VdbeSerialGet(
switch( serial_type ){
case 10: /* Reserved for future use */
case 11: /* Reserved for future use */
- case 0: { /* NULL */
+ case 0: { /* Null */
+ /* EVIDENCE-OF: R-24078-09375 Value is a NULL. */
pMem->flags = MEM_Null;
break;
}
- case 1: { /* 1-byte signed integer */
- pMem->u.i = (signed char)buf[0];
+ case 1: {
+ /* EVIDENCE-OF: R-44885-25196 Value is an 8-bit twos-complement
+ ** integer. */
+ pMem->u.i = ONE_BYTE_INT(buf);
pMem->flags = MEM_Int;
+ testcase( pMem->u.i<0 );
return 1;
}
case 2: { /* 2-byte signed integer */
- pMem->u.i = (((signed char)buf[0])<<8) | buf[1];
+ /* EVIDENCE-OF: R-49794-35026 Value is a big-endian 16-bit
+ ** twos-complement integer. */
+ pMem->u.i = TWO_BYTE_INT(buf);
pMem->flags = MEM_Int;
+ testcase( pMem->u.i<0 );
return 2;
}
case 3: { /* 3-byte signed integer */
- pMem->u.i = (((signed char)buf[0])<<16) | (buf[1]<<8) | buf[2];
+ /* EVIDENCE-OF: R-37839-54301 Value is a big-endian 24-bit
+ ** twos-complement integer. */
+ pMem->u.i = THREE_BYTE_INT(buf);
pMem->flags = MEM_Int;
+ testcase( pMem->u.i<0 );
return 3;
}
case 4: { /* 4-byte signed integer */
- pMem->u.i = (buf[0]<<24) | (buf[1]<<16) | (buf[2]<<8) | buf[3];
+ /* EVIDENCE-OF: R-01849-26079 Value is a big-endian 32-bit
+ ** twos-complement integer. */
+ pMem->u.i = FOUR_BYTE_INT(buf);
+#ifdef __HP_cc
+ /* Work around a sign-extension bug in the HP compiler for HP/UX */
+ if( buf[0]&0x80 ) pMem->u.i |= 0xffffffff80000000LL;
+#endif
pMem->flags = MEM_Int;
+ testcase( pMem->u.i<0 );
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;
+ /* EVIDENCE-OF: R-50385-09674 Value is a big-endian 48-bit
+ ** twos-complement integer. */
+ pMem->u.i = FOUR_BYTE_UINT(buf+2) + (((i64)1)<<32)*TWO_BYTE_INT(buf);
pMem->flags = MEM_Int;
+ testcase( pMem->u.i<0 );
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;
+ /* These use local variables, so do them in a separate routine
+ ** to avoid having to move the frame pointer in the common case */
+ return serialGet(buf,serial_type,pMem);
}
case 8: /* Integer 0 */
case 9: { /* Integer 1 */
+ /* EVIDENCE-OF: R-12976-22893 Value is the integer 0. */
+ /* EVIDENCE-OF: R-18143-12121 Value is the integer 1. */
pMem->u.i = serial_type-8;
pMem->flags = MEM_Int;
return 0;
}
default: {
- u32 len = (serial_type-12)/2;
+ /* EVIDENCE-OF: R-14606-31564 Value is a BLOB that is (N-12)/2 bytes in
+ ** length.
+ ** EVIDENCE-OF: R-28401-00140 Value is a string in the text encoding and
+ ** (N-13)/2 bytes in length. */
+ static const u16 aFlag[] = { MEM_Blob|MEM_Ephem, MEM_Str|MEM_Ephem };
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;
+ pMem->n = (serial_type-12)/2;
+ pMem->flags = aFlag[serial_type&1];
+ return pMem->n;
}
}
return 0;
}
-
/*
** This routine is used to allocate sufficient space for an UnpackedRecord
** structure large enough to be used with sqlite3VdbeRecordUnpack() if
@@ -61473,63 +70770,59 @@ SQLITE_PRIVATE void sqlite3VdbeRecordUnpack(
u32 szHdr;
Mem *pMem = p->aMem;
- p->flags = 0;
+ p->default_rc = 0;
assert( EIGHT_BYTE_ALIGNMENT(pMem) );
idx = getVarint32(aKey, szHdr);
d = szHdr;
u = 0;
- while( idx<szHdr && u<p->nField && d<=nKey ){
+ while( idx<szHdr && 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;
+ pMem->szMalloc = 0;
d += sqlite3VdbeSerialGet(&aKey[d], serial_type, pMem);
pMem++;
- u++;
+ if( (++u)>=p->nField ) break;
}
assert( u<=pKeyInfo->nField + 1 );
p->nField = u;
}
+#if SQLITE_DEBUG
/*
-** 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.
+** This function compares two index or table record keys in the same way
+** as the sqlite3VdbeRecordCompare() routine. Unlike VdbeRecordCompare(),
+** this function deserializes and compares values using the
+** sqlite3VdbeSerialGet() and sqlite3MemCompare() functions. It is used
+** in assert() statements to ensure that the optimized code in
+** sqlite3VdbeRecordCompare() returns results with these two primitives.
**
-** 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.
+** Return true if the result of comparison is equivalent to desiredResult.
+** Return false if there is a disagreement.
*/
-SQLITE_PRIVATE int sqlite3VdbeRecordCompare(
+static int vdbeRecordCompareDebug(
int nKey1, const void *pKey1, /* Left key */
- UnpackedRecord *pPKey2 /* Right key */
+ const UnpackedRecord *pPKey2, /* Right key */
+ int desiredResult /* Correct answer */
){
- int d1; /* Offset into aKey[] of next data element */
+ u32 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;
+ if( pKeyInfo->db==0 ) return 1;
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 */
+ VVA_ONLY( mem1.szMalloc = 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.
@@ -61541,15 +70834,29 @@ SQLITE_PRIVATE int sqlite3VdbeRecordCompare(
/* mem1.u.i = 0; // not needed, here to silence compiler warning */
idx1 = getVarint32(aKey1, szHdr1);
+ if( szHdr1>98307 ) return SQLITE_CORRUPT;
d1 = szHdr1;
- nField = pKeyInfo->nField;
+ assert( pKeyInfo->nField+pKeyInfo->nXField>=pPKey2->nField || CORRUPT_DB );
assert( pKeyInfo->aSortOrder!=0 );
- while( idx1<szHdr1 && i<pPKey2->nField ){
+ assert( pKeyInfo->nField>0 );
+ assert( idx1<=szHdr1 || CORRUPT_DB );
+ do{
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;
+
+ /* Verify that there is enough key space remaining to avoid
+ ** a buffer overread. The "d1+serial_type1+2" subexpression will
+ ** always be greater than or equal to the amount of required key space.
+ ** Use that approximation to avoid the more expensive call to
+ ** sqlite3VdbeSerialTypeLen() in the common case.
+ */
+ if( d1+serial_type1+2>(u32)nKey1
+ && d1+sqlite3VdbeSerialTypeLen(serial_type1)>(u32)nKey1
+ ){
+ break;
+ }
/* Extract the values to be compared.
*/
@@ -61557,58 +70864,689 @@ SQLITE_PRIVATE int sqlite3VdbeRecordCompare(
/* Do the comparison
*/
- rc = sqlite3MemCompare(&mem1, &pPKey2->aMem[i],
- i<nField ? pKeyInfo->aColl[i] : 0);
+ rc = sqlite3MemCompare(&mem1, &pPKey2->aMem[i], pKeyInfo->aColl[i]);
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;
+ assert( mem1.szMalloc==0 ); /* See comment below */
+ if( pKeyInfo->aSortOrder[i] ){
+ rc = -rc; /* Invert the result for DESC sort order. */
}
-
- /* 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;
+ goto debugCompareEnd;
}
i++;
- }
+ }while( idx1<szHdr1 && i<pPKey2->nField );
/* 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 );
+ assert( mem1.szMalloc==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;
+ ** all the fields up to that point were equal. Return the default_rc
+ ** value. */
+ rc = pPKey2->default_rc;
+
+debugCompareEnd:
+ if( desiredResult==0 && rc==0 ) return 1;
+ if( desiredResult<0 && rc<0 ) return 1;
+ if( desiredResult>0 && rc>0 ) return 1;
+ if( CORRUPT_DB ) return 1;
+ if( pKeyInfo->db->mallocFailed ) return 1;
+ return 0;
+}
+#endif
+
+#if SQLITE_DEBUG
+/*
+** Count the number of fields (a.k.a. columns) in the record given by
+** pKey,nKey. The verify that this count is less than or equal to the
+** limit given by pKeyInfo->nField + pKeyInfo->nXField.
+**
+** If this constraint is not satisfied, it means that the high-speed
+** vdbeRecordCompareInt() and vdbeRecordCompareString() routines will
+** not work correctly. If this assert() ever fires, it probably means
+** that the KeyInfo.nField or KeyInfo.nXField values were computed
+** incorrectly.
+*/
+static void vdbeAssertFieldCountWithinLimits(
+ int nKey, const void *pKey, /* The record to verify */
+ const KeyInfo *pKeyInfo /* Compare size with this KeyInfo */
+){
+ int nField = 0;
+ u32 szHdr;
+ u32 idx;
+ u32 notUsed;
+ const unsigned char *aKey = (const unsigned char*)pKey;
+
+ if( CORRUPT_DB ) return;
+ idx = getVarint32(aKey, szHdr);
+ assert( nKey>=0 );
+ assert( szHdr<=(u32)nKey );
+ while( idx<szHdr ){
+ idx += getVarint32(aKey+idx, notUsed);
+ nField++;
}
- return rc;
+ assert( nField <= pKeyInfo->nField+pKeyInfo->nXField );
}
+#else
+# define vdbeAssertFieldCountWithinLimits(A,B,C)
+#endif
+
+/*
+** Both *pMem1 and *pMem2 contain string values. Compare the two values
+** using the collation sequence pColl. As usual, return a negative , zero
+** or positive value if *pMem1 is less than, equal to or greater than
+** *pMem2, respectively. Similar in spirit to "rc = (*pMem1) - (*pMem2);".
+*/
+static int vdbeCompareMemString(
+ const Mem *pMem1,
+ const Mem *pMem2,
+ const CollSeq *pColl,
+ u8 *prcErr /* If an OOM occurs, set to SQLITE_NOMEM */
+){
+ 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{
+ int rc;
+ const void *v1, *v2;
+ int n1, n2;
+ Mem c1;
+ Mem c2;
+ sqlite3VdbeMemInit(&c1, pMem1->db, MEM_Null);
+ sqlite3VdbeMemInit(&c2, pMem1->db, MEM_Null);
+ 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);
+ if( (v1==0 || v2==0) && prcErr ) *prcErr = SQLITE_NOMEM;
+ return rc;
+ }
+}
+
+/*
+** Compare two blobs. Return negative, zero, or positive if the first
+** is less than, equal to, or greater than the second, respectively.
+** If one blob is a prefix of the other, then the shorter is the lessor.
+*/
+static SQLITE_NOINLINE int sqlite3BlobCompare(const Mem *pB1, const Mem *pB2){
+ int c = memcmp(pB1->z, pB2->z, pB1->n>pB2->n ? pB2->n : pB1->n);
+ if( c ) return c;
+ return pB1->n - pB2->n;
+}
+
+/*
+** Do a comparison between a 64-bit signed integer and a 64-bit floating-point
+** number. Return negative, zero, or positive if the first (i64) is less than,
+** equal to, or greater than the second (double).
+*/
+static int sqlite3IntFloatCompare(i64 i, double r){
+ if( sizeof(LONGDOUBLE_TYPE)>8 ){
+ LONGDOUBLE_TYPE x = (LONGDOUBLE_TYPE)i;
+ if( x<r ) return -1;
+ if( x>r ) return +1;
+ return 0;
+ }else{
+ i64 y;
+ double s;
+ if( r<-9223372036854775808.0 ) return +1;
+ if( r>9223372036854775807.0 ) return -1;
+ y = (i64)r;
+ if( i<y ) return -1;
+ if( i>y ){
+ if( y==SMALLEST_INT64 && r>0.0 ) return -1;
+ return +1;
+ }
+ s = (double)i;
+ if( s<r ) return -1;
+ if( s>r ) return +1;
+ return 0;
+ }
+}
+
+/*
+** 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 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);
+ }
+
+ /* At least one of the two values is a number
+ */
+ if( combined_flags&(MEM_Int|MEM_Real) ){
+ if( (f1 & f2 & MEM_Int)!=0 ){
+ if( pMem1->u.i < pMem2->u.i ) return -1;
+ if( pMem1->u.i > pMem2->u.i ) return +1;
+ return 0;
+ }
+ if( (f1 & f2 & MEM_Real)!=0 ){
+ if( pMem1->u.r < pMem2->u.r ) return -1;
+ if( pMem1->u.r > pMem2->u.r ) return +1;
+ return 0;
+ }
+ if( (f1&MEM_Int)!=0 ){
+ if( (f2&MEM_Real)!=0 ){
+ return sqlite3IntFloatCompare(pMem1->u.i, pMem2->u.r);
+ }else{
+ return -1;
+ }
+ }
+ if( (f1&MEM_Real)!=0 ){
+ if( (f2&MEM_Int)!=0 ){
+ return -sqlite3IntFloatCompare(pMem2->u.i, pMem1->u.r);
+ }else{
+ return -1;
+ }
+ }
+ return +1;
+ }
+
+ /* 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 || pMem1->db->mallocFailed );
+ 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 ){
+ return vdbeCompareMemString(pMem1, pMem2, pColl, 0);
+ }
+ /* 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(). */
+ return sqlite3BlobCompare(pMem1, pMem2);
+}
+
+
+/*
+** The first argument passed to this function is a serial-type that
+** corresponds to an integer - all values between 1 and 9 inclusive
+** except 7. The second points to a buffer containing an integer value
+** serialized according to serial_type. This function deserializes
+** and returns the value.
+*/
+static i64 vdbeRecordDecodeInt(u32 serial_type, const u8 *aKey){
+ u32 y;
+ assert( CORRUPT_DB || (serial_type>=1 && serial_type<=9 && serial_type!=7) );
+ switch( serial_type ){
+ case 0:
+ case 1:
+ testcase( aKey[0]&0x80 );
+ return ONE_BYTE_INT(aKey);
+ case 2:
+ testcase( aKey[0]&0x80 );
+ return TWO_BYTE_INT(aKey);
+ case 3:
+ testcase( aKey[0]&0x80 );
+ return THREE_BYTE_INT(aKey);
+ case 4: {
+ testcase( aKey[0]&0x80 );
+ y = FOUR_BYTE_UINT(aKey);
+ return (i64)*(int*)&y;
+ }
+ case 5: {
+ testcase( aKey[0]&0x80 );
+ return FOUR_BYTE_UINT(aKey+2) + (((i64)1)<<32)*TWO_BYTE_INT(aKey);
+ }
+ case 6: {
+ u64 x = FOUR_BYTE_UINT(aKey);
+ testcase( aKey[0]&0x80 );
+ x = (x<<32) | FOUR_BYTE_UINT(aKey+4);
+ return (i64)*(i64*)&x;
+ }
+ }
+
+ return (serial_type - 8);
+}
+
+/*
+** 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 the OP_MakeRecord opcode of the VDBE. The pPKey2
+** key must be a parsed key such as obtained from
+** sqlite3VdbeParseRecord.
+**
+** If argument bSkip is non-zero, it is assumed that the caller has already
+** determined that the first fields of the keys are equal.
+**
+** Key1 and Key2 do not have to contain the same number of fields. If all
+** fields that appear in both keys are equal, then pPKey2->default_rc is
+** returned.
+**
+** If database corruption is discovered, set pPKey2->errCode to
+** SQLITE_CORRUPT and return 0. If an OOM error is encountered,
+** pPKey2->errCode is set to SQLITE_NOMEM and, if it is not NULL, the
+** malloc-failed flag set on database handle (pPKey2->pKeyInfo->db).
+*/
+SQLITE_PRIVATE int sqlite3VdbeRecordCompareWithSkip(
+ int nKey1, const void *pKey1, /* Left key */
+ UnpackedRecord *pPKey2, /* Right key */
+ int bSkip /* If true, skip the first field */
+){
+ u32 d1; /* Offset into aKey[] of next data element */
+ int i; /* Index of next field to compare */
+ u32 szHdr1; /* Size of record header in bytes */
+ u32 idx1; /* Offset of first type in header */
+ int rc = 0; /* Return value */
+ Mem *pRhs = pPKey2->aMem; /* Next field of pPKey2 to compare */
+ KeyInfo *pKeyInfo = pPKey2->pKeyInfo;
+ const unsigned char *aKey1 = (const unsigned char *)pKey1;
+ Mem mem1;
+
+ /* If bSkip is true, then the caller has already determined that the first
+ ** two elements in the keys are equal. Fix the various stack variables so
+ ** that this routine begins comparing at the second field. */
+ if( bSkip ){
+ u32 s1;
+ idx1 = 1 + getVarint32(&aKey1[1], s1);
+ szHdr1 = aKey1[0];
+ d1 = szHdr1 + sqlite3VdbeSerialTypeLen(s1);
+ i = 1;
+ pRhs++;
+ }else{
+ idx1 = getVarint32(aKey1, szHdr1);
+ d1 = szHdr1;
+ if( d1>(unsigned)nKey1 ){
+ pPKey2->errCode = (u8)SQLITE_CORRUPT_BKPT;
+ return 0; /* Corruption */
+ }
+ i = 0;
+ }
+
+ VVA_ONLY( mem1.szMalloc = 0; ) /* Only needed by assert() statements */
+ assert( pPKey2->pKeyInfo->nField+pPKey2->pKeyInfo->nXField>=pPKey2->nField
+ || CORRUPT_DB );
+ assert( pPKey2->pKeyInfo->aSortOrder!=0 );
+ assert( pPKey2->pKeyInfo->nField>0 );
+ assert( idx1<=szHdr1 || CORRUPT_DB );
+ do{
+ u32 serial_type;
+
+ /* RHS is an integer */
+ if( pRhs->flags & MEM_Int ){
+ serial_type = aKey1[idx1];
+ testcase( serial_type==12 );
+ if( serial_type>=10 ){
+ rc = +1;
+ }else if( serial_type==0 ){
+ rc = -1;
+ }else if( serial_type==7 ){
+ sqlite3VdbeSerialGet(&aKey1[d1], serial_type, &mem1);
+ rc = -sqlite3IntFloatCompare(pRhs->u.i, mem1.u.r);
+ }else{
+ i64 lhs = vdbeRecordDecodeInt(serial_type, &aKey1[d1]);
+ i64 rhs = pRhs->u.i;
+ if( lhs<rhs ){
+ rc = -1;
+ }else if( lhs>rhs ){
+ rc = +1;
+ }
+ }
+ }
+
+ /* RHS is real */
+ else if( pRhs->flags & MEM_Real ){
+ serial_type = aKey1[idx1];
+ if( serial_type>=10 ){
+ /* Serial types 12 or greater are strings and blobs (greater than
+ ** numbers). Types 10 and 11 are currently "reserved for future
+ ** use", so it doesn't really matter what the results of comparing
+ ** them to numberic values are. */
+ rc = +1;
+ }else if( serial_type==0 ){
+ rc = -1;
+ }else{
+ sqlite3VdbeSerialGet(&aKey1[d1], serial_type, &mem1);
+ if( serial_type==7 ){
+ if( mem1.u.r<pRhs->u.r ){
+ rc = -1;
+ }else if( mem1.u.r>pRhs->u.r ){
+ rc = +1;
+ }
+ }else{
+ rc = sqlite3IntFloatCompare(mem1.u.i, pRhs->u.r);
+ }
+ }
+ }
+
+ /* RHS is a string */
+ else if( pRhs->flags & MEM_Str ){
+ getVarint32(&aKey1[idx1], serial_type);
+ testcase( serial_type==12 );
+ if( serial_type<12 ){
+ rc = -1;
+ }else if( !(serial_type & 0x01) ){
+ rc = +1;
+ }else{
+ mem1.n = (serial_type - 12) / 2;
+ testcase( (d1+mem1.n)==(unsigned)nKey1 );
+ testcase( (d1+mem1.n+1)==(unsigned)nKey1 );
+ if( (d1+mem1.n) > (unsigned)nKey1 ){
+ pPKey2->errCode = (u8)SQLITE_CORRUPT_BKPT;
+ return 0; /* Corruption */
+ }else if( pKeyInfo->aColl[i] ){
+ mem1.enc = pKeyInfo->enc;
+ mem1.db = pKeyInfo->db;
+ mem1.flags = MEM_Str;
+ mem1.z = (char*)&aKey1[d1];
+ rc = vdbeCompareMemString(
+ &mem1, pRhs, pKeyInfo->aColl[i], &pPKey2->errCode
+ );
+ }else{
+ int nCmp = MIN(mem1.n, pRhs->n);
+ rc = memcmp(&aKey1[d1], pRhs->z, nCmp);
+ if( rc==0 ) rc = mem1.n - pRhs->n;
+ }
+ }
+ }
+
+ /* RHS is a blob */
+ else if( pRhs->flags & MEM_Blob ){
+ getVarint32(&aKey1[idx1], serial_type);
+ testcase( serial_type==12 );
+ if( serial_type<12 || (serial_type & 0x01) ){
+ rc = -1;
+ }else{
+ int nStr = (serial_type - 12) / 2;
+ testcase( (d1+nStr)==(unsigned)nKey1 );
+ testcase( (d1+nStr+1)==(unsigned)nKey1 );
+ if( (d1+nStr) > (unsigned)nKey1 ){
+ pPKey2->errCode = (u8)SQLITE_CORRUPT_BKPT;
+ return 0; /* Corruption */
+ }else{
+ int nCmp = MIN(nStr, pRhs->n);
+ rc = memcmp(&aKey1[d1], pRhs->z, nCmp);
+ if( rc==0 ) rc = nStr - pRhs->n;
+ }
+ }
+ }
+
+ /* RHS is null */
+ else{
+ serial_type = aKey1[idx1];
+ rc = (serial_type!=0);
+ }
+
+ if( rc!=0 ){
+ if( pKeyInfo->aSortOrder[i] ){
+ rc = -rc;
+ }
+ assert( vdbeRecordCompareDebug(nKey1, pKey1, pPKey2, rc) );
+ assert( mem1.szMalloc==0 ); /* See comment below */
+ return rc;
+ }
+
+ i++;
+ pRhs++;
+ d1 += sqlite3VdbeSerialTypeLen(serial_type);
+ idx1 += sqlite3VarintLen(serial_type);
+ }while( idx1<(unsigned)szHdr1 && i<pPKey2->nField && d1<=(unsigned)nKey1 );
+
+ /* 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.szMalloc==0 );
+
+ /* rc==0 here means that one or both of the keys ran out of fields and
+ ** all the fields up to that point were equal. Return the default_rc
+ ** value. */
+ assert( CORRUPT_DB
+ || vdbeRecordCompareDebug(nKey1, pKey1, pPKey2, pPKey2->default_rc)
+ || pKeyInfo->db->mallocFailed
+ );
+ pPKey2->eqSeen = 1;
+ return pPKey2->default_rc;
+}
+SQLITE_PRIVATE int sqlite3VdbeRecordCompare(
+ int nKey1, const void *pKey1, /* Left key */
+ UnpackedRecord *pPKey2 /* Right key */
+){
+ return sqlite3VdbeRecordCompareWithSkip(nKey1, pKey1, pPKey2, 0);
+}
+
+
+/*
+** This function is an optimized version of sqlite3VdbeRecordCompare()
+** that (a) the first field of pPKey2 is an integer, and (b) the
+** size-of-header varint at the start of (pKey1/nKey1) fits in a single
+** byte (i.e. is less than 128).
+**
+** To avoid concerns about buffer overreads, this routine is only used
+** on schemas where the maximum valid header size is 63 bytes or less.
+*/
+static int vdbeRecordCompareInt(
+ int nKey1, const void *pKey1, /* Left key */
+ UnpackedRecord *pPKey2 /* Right key */
+){
+ const u8 *aKey = &((const u8*)pKey1)[*(const u8*)pKey1 & 0x3F];
+ int serial_type = ((const u8*)pKey1)[1];
+ int res;
+ u32 y;
+ u64 x;
+ i64 v = pPKey2->aMem[0].u.i;
+ i64 lhs;
+
+ vdbeAssertFieldCountWithinLimits(nKey1, pKey1, pPKey2->pKeyInfo);
+ assert( (*(u8*)pKey1)<=0x3F || CORRUPT_DB );
+ switch( serial_type ){
+ case 1: { /* 1-byte signed integer */
+ lhs = ONE_BYTE_INT(aKey);
+ testcase( lhs<0 );
+ break;
+ }
+ case 2: { /* 2-byte signed integer */
+ lhs = TWO_BYTE_INT(aKey);
+ testcase( lhs<0 );
+ break;
+ }
+ case 3: { /* 3-byte signed integer */
+ lhs = THREE_BYTE_INT(aKey);
+ testcase( lhs<0 );
+ break;
+ }
+ case 4: { /* 4-byte signed integer */
+ y = FOUR_BYTE_UINT(aKey);
+ lhs = (i64)*(int*)&y;
+ testcase( lhs<0 );
+ break;
+ }
+ case 5: { /* 6-byte signed integer */
+ lhs = FOUR_BYTE_UINT(aKey+2) + (((i64)1)<<32)*TWO_BYTE_INT(aKey);
+ testcase( lhs<0 );
+ break;
+ }
+ case 6: { /* 8-byte signed integer */
+ x = FOUR_BYTE_UINT(aKey);
+ x = (x<<32) | FOUR_BYTE_UINT(aKey+4);
+ lhs = *(i64*)&x;
+ testcase( lhs<0 );
+ break;
+ }
+ case 8:
+ lhs = 0;
+ break;
+ case 9:
+ lhs = 1;
+ break;
+
+ /* This case could be removed without changing the results of running
+ ** this code. Including it causes gcc to generate a faster switch
+ ** statement (since the range of switch targets now starts at zero and
+ ** is contiguous) but does not cause any duplicate code to be generated
+ ** (as gcc is clever enough to combine the two like cases). Other
+ ** compilers might be similar. */
+ case 0: case 7:
+ return sqlite3VdbeRecordCompare(nKey1, pKey1, pPKey2);
+
+ default:
+ return sqlite3VdbeRecordCompare(nKey1, pKey1, pPKey2);
+ }
+
+ if( v>lhs ){
+ res = pPKey2->r1;
+ }else if( v<lhs ){
+ res = pPKey2->r2;
+ }else if( pPKey2->nField>1 ){
+ /* The first fields of the two keys are equal. Compare the trailing
+ ** fields. */
+ res = sqlite3VdbeRecordCompareWithSkip(nKey1, pKey1, pPKey2, 1);
+ }else{
+ /* The first fields of the two keys are equal and there are no trailing
+ ** fields. Return pPKey2->default_rc in this case. */
+ res = pPKey2->default_rc;
+ pPKey2->eqSeen = 1;
+ }
+
+ assert( vdbeRecordCompareDebug(nKey1, pKey1, pPKey2, res) );
+ return res;
+}
+
+/*
+** This function is an optimized version of sqlite3VdbeRecordCompare()
+** that (a) the first field of pPKey2 is a string, that (b) the first field
+** uses the collation sequence BINARY and (c) that the size-of-header varint
+** at the start of (pKey1/nKey1) fits in a single byte.
+*/
+static int vdbeRecordCompareString(
+ int nKey1, const void *pKey1, /* Left key */
+ UnpackedRecord *pPKey2 /* Right key */
+){
+ const u8 *aKey1 = (const u8*)pKey1;
+ int serial_type;
+ int res;
+
+ assert( pPKey2->aMem[0].flags & MEM_Str );
+ vdbeAssertFieldCountWithinLimits(nKey1, pKey1, pPKey2->pKeyInfo);
+ getVarint32(&aKey1[1], serial_type);
+ if( serial_type<12 ){
+ res = pPKey2->r1; /* (pKey1/nKey1) is a number or a null */
+ }else if( !(serial_type & 0x01) ){
+ res = pPKey2->r2; /* (pKey1/nKey1) is a blob */
+ }else{
+ int nCmp;
+ int nStr;
+ int szHdr = aKey1[0];
+
+ nStr = (serial_type-12) / 2;
+ if( (szHdr + nStr) > nKey1 ){
+ pPKey2->errCode = (u8)SQLITE_CORRUPT_BKPT;
+ return 0; /* Corruption */
+ }
+ nCmp = MIN( pPKey2->aMem[0].n, nStr );
+ res = memcmp(&aKey1[szHdr], pPKey2->aMem[0].z, nCmp);
+
+ if( res==0 ){
+ res = nStr - pPKey2->aMem[0].n;
+ if( res==0 ){
+ if( pPKey2->nField>1 ){
+ res = sqlite3VdbeRecordCompareWithSkip(nKey1, pKey1, pPKey2, 1);
+ }else{
+ res = pPKey2->default_rc;
+ pPKey2->eqSeen = 1;
+ }
+ }else if( res>0 ){
+ res = pPKey2->r2;
+ }else{
+ res = pPKey2->r1;
+ }
+ }else if( res>0 ){
+ res = pPKey2->r2;
+ }else{
+ res = pPKey2->r1;
+ }
+ }
+
+ assert( vdbeRecordCompareDebug(nKey1, pKey1, pPKey2, res)
+ || CORRUPT_DB
+ || pPKey2->pKeyInfo->db->mallocFailed
+ );
+ return res;
+}
+
+/*
+** Return a pointer to an sqlite3VdbeRecordCompare() compatible function
+** suitable for comparing serialized records to the unpacked record passed
+** as the only argument.
+*/
+SQLITE_PRIVATE RecordCompare sqlite3VdbeFindCompare(UnpackedRecord *p){
+ /* varintRecordCompareInt() and varintRecordCompareString() both assume
+ ** that the size-of-header varint that occurs at the start of each record
+ ** fits in a single byte (i.e. is 127 or less). varintRecordCompareInt()
+ ** also assumes that it is safe to overread a buffer by at least the
+ ** maximum possible legal header size plus 8 bytes. Because there is
+ ** guaranteed to be at least 74 (but not 136) bytes of padding following each
+ ** buffer passed to varintRecordCompareInt() this makes it convenient to
+ ** limit the size of the header to 64 bytes in cases where the first field
+ ** is an integer.
+ **
+ ** The easiest way to enforce this limit is to consider only records with
+ ** 13 fields or less. If the first field is an integer, the maximum legal
+ ** header size is (12*5 + 1 + 1) bytes. */
+ if( (p->pKeyInfo->nField + p->pKeyInfo->nXField)<=13 ){
+ int flags = p->aMem[0].flags;
+ if( p->pKeyInfo->aSortOrder[0] ){
+ p->r1 = 1;
+ p->r2 = -1;
+ }else{
+ p->r1 = -1;
+ p->r2 = 1;
+ }
+ if( (flags & MEM_Int) ){
+ return vdbeRecordCompareInt;
+ }
+ testcase( flags & MEM_Real );
+ testcase( flags & MEM_Null );
+ testcase( flags & MEM_Blob );
+ if( (flags & (MEM_Real|MEM_Null|MEM_Blob))==0 && p->pKeyInfo->aColl[0]==0 ){
+ assert( flags & MEM_Str );
+ return vdbeRecordCompareString;
+ }
+ }
+
+ return sqlite3VdbeRecordCompare;
+}
/*
** pCur points at an index entry created using the OP_MakeRecord opcode.
@@ -61626,8 +71564,6 @@ SQLITE_PRIVATE int sqlite3VdbeIdxRowid(sqlite3 *db, BtCursor *pCur, i64 *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
@@ -61639,8 +71575,8 @@ SQLITE_PRIVATE int sqlite3VdbeIdxRowid(sqlite3 *db, BtCursor *pCur, i64 *rowid){
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);
+ sqlite3VdbeMemInit(&m, db, 0);
+ rc = sqlite3VdbeMemFromBtree(pCur, 0, (u32)nCellKey, 1, &m);
if( rc ){
return rc;
}
@@ -61667,7 +71603,7 @@ SQLITE_PRIVATE int sqlite3VdbeIdxRowid(sqlite3 *db, BtCursor *pCur, i64 *rowid){
if( unlikely(typeRowid<1 || typeRowid>9 || typeRowid==7) ){
goto idx_rowid_corruption;
}
- lenRowid = sqlite3VdbeSerialTypeLen(typeRowid);
+ lenRowid = sqlite3SmallTypeSizes[typeRowid];
testcase( (u32)m.n==szHdr+lenRowid );
if( unlikely((u32)m.n<szHdr+lenRowid) ){
goto idx_rowid_corruption;
@@ -61682,7 +71618,7 @@ SQLITE_PRIVATE int sqlite3VdbeIdxRowid(sqlite3 *db, BtCursor *pCur, i64 *rowid){
/* 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 );
+ testcase( m.szMalloc!=0 );
sqlite3VdbeMemRelease(&m);
return SQLITE_CORRUPT_BKPT;
}
@@ -61699,30 +71635,32 @@ idx_rowid_corruption:
** 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 */
+ sqlite3 *db, /* Database connection */
+ VdbeCursor *pC, /* The cursor to compare against */
+ UnpackedRecord *pUnpacked, /* Unpacked version of key */
+ int *res /* Write the comparison result here */
){
i64 nCellKey = 0;
int rc;
- BtCursor *pCur = pC->pCursor;
+ BtCursor *pCur;
Mem m;
+ assert( pC->eCurType==CURTYPE_BTREE );
+ pCur = pC->uc.pCursor;
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
+ /* nCellKey will always be between 0 and 0xffffffff because of the way
** 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);
+ sqlite3VdbeMemInit(&m, db, 0);
+ rc = sqlite3VdbeMemFromBtree(pCur, 0, (u32)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;
@@ -61778,7 +71716,7 @@ SQLITE_PRIVATE sqlite3 *sqlite3VdbeDb(Vdbe *v){
**
** The returned value must be freed by the caller using sqlite3ValueFree().
*/
-SQLITE_PRIVATE sqlite3_value *sqlite3VdbeGetValue(Vdbe *v, int iVar, u8 aff){
+SQLITE_PRIVATE sqlite3_value *sqlite3VdbeGetBoundValue(Vdbe *v, int iVar, u8 aff){
assert( iVar>0 );
if( v ){
Mem *pMem = &v->aVar[iVar-1];
@@ -61787,7 +71725,6 @@ SQLITE_PRIVATE sqlite3_value *sqlite3VdbeGetValue(Vdbe *v, int iVar, u8 aff){
if( pRet ){
sqlite3VdbeMemCopy((Mem *)pRet, pMem);
sqlite3ValueApplyAffinity(pRet, aff, SQLITE_UTF8);
- sqlite3VdbeMemStoreType((Mem *)pRet);
}
return pRet;
}
@@ -61809,6 +71746,21 @@ SQLITE_PRIVATE void sqlite3VdbeSetVarmask(Vdbe *v, int iVar){
}
}
+#ifndef SQLITE_OMIT_VIRTUALTABLE
+/*
+** 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).
+*/
+SQLITE_PRIVATE void sqlite3VtabImportErrmsg(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;
+}
+#endif /* SQLITE_OMIT_VIRTUALTABLE */
+
/************** End of vdbeaux.c *********************************************/
/************** Begin file vdbeapi.c *****************************************/
/*
@@ -61826,6 +71778,8 @@ SQLITE_PRIVATE void sqlite3VdbeSetVarmask(Vdbe *v, int iVar){
** This file contains code use to implement APIs that are part of the
** VDBE.
*/
+/* #include "sqliteInt.h" */
+/* #include "vdbeInt.h" */
#ifndef SQLITE_OMIT_DEPRECATED
/*
@@ -61836,7 +71790,7 @@ SQLITE_PRIVATE void sqlite3VdbeSetVarmask(Vdbe *v, int iVar){
** collating sequences are registered or if an authorizer function is
** added or changed.
*/
-SQLITE_API int sqlite3_expired(sqlite3_stmt *pStmt){
+SQLITE_API int SQLITE_STDCALL sqlite3_expired(sqlite3_stmt *pStmt){
Vdbe *p = (Vdbe*)pStmt;
return p==0 || p->expired;
}
@@ -61864,6 +71818,31 @@ static int vdbeSafetyNotNull(Vdbe *p){
}
}
+#ifndef SQLITE_OMIT_TRACE
+/*
+** Invoke the profile callback. This routine is only called if we already
+** know that the profile callback is defined and needs to be invoked.
+*/
+static SQLITE_NOINLINE void invokeProfileCallback(sqlite3 *db, Vdbe *p){
+ sqlite3_int64 iNow;
+ assert( p->startTime>0 );
+ assert( db->xProfile!=0 );
+ assert( db->init.busy==0 );
+ assert( p->zSql!=0 );
+ sqlite3OsCurrentTimeInt64(db->pVfs, &iNow);
+ db->xProfile(db->pProfileArg, p->zSql, (iNow - p->startTime)*1000000);
+ p->startTime = 0;
+}
+/*
+** The checkProfileCallback(DB,P) macro checks to see if a profile callback
+** is needed, and it invokes the callback if it is needed.
+*/
+# define checkProfileCallback(DB,P) \
+ if( ((P)->startTime)>0 ){ invokeProfileCallback(DB,P); }
+#else
+# define checkProfileCallback(DB,P) /*no-op*/
+#endif
+
/*
** The following routine destroys a virtual machine that is created by
** the sqlite3_compile() routine. The integer returned is an SQLITE_
@@ -61873,7 +71852,7 @@ static int vdbeSafetyNotNull(Vdbe *p){
** 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){
+SQLITE_API int SQLITE_STDCALL sqlite3_finalize(sqlite3_stmt *pStmt){
int rc;
if( pStmt==0 ){
/* IMPLEMENTATION-OF: R-57228-12904 Invoking sqlite3_finalize() on a NULL
@@ -61884,6 +71863,7 @@ SQLITE_API int sqlite3_finalize(sqlite3_stmt *pStmt){
sqlite3 *db = v->db;
if( vdbeSafety(v) ) return SQLITE_MISUSE_BKPT;
sqlite3_mutex_enter(db->mutex);
+ checkProfileCallback(db, v);
rc = sqlite3VdbeFinalize(v);
rc = sqlite3ApiExit(db, rc);
sqlite3LeaveMutexAndCloseZombie(db);
@@ -61899,18 +71879,20 @@ SQLITE_API int sqlite3_finalize(sqlite3_stmt *pStmt){
** 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){
+SQLITE_API int SQLITE_STDCALL sqlite3_reset(sqlite3_stmt *pStmt){
int rc;
if( pStmt==0 ){
rc = SQLITE_OK;
}else{
Vdbe *v = (Vdbe*)pStmt;
- sqlite3_mutex_enter(v->db->mutex);
+ sqlite3 *db = v->db;
+ sqlite3_mutex_enter(db->mutex);
+ checkProfileCallback(db, v);
rc = sqlite3VdbeReset(v);
sqlite3VdbeRewind(v);
- assert( (rc & (v->db->errMask))==rc );
- rc = sqlite3ApiExit(v->db, rc);
- sqlite3_mutex_leave(v->db->mutex);
+ assert( (rc & (db->errMask))==rc );
+ rc = sqlite3ApiExit(db, rc);
+ sqlite3_mutex_leave(db->mutex);
}
return rc;
}
@@ -61918,7 +71900,7 @@ SQLITE_API int sqlite3_reset(sqlite3_stmt *pStmt){
/*
** Set all the parameters in the compiled SQL statement to NULL.
*/
-SQLITE_API int sqlite3_clear_bindings(sqlite3_stmt *pStmt){
+SQLITE_API int SQLITE_STDCALL sqlite3_clear_bindings(sqlite3_stmt *pStmt){
int i;
int rc = SQLITE_OK;
Vdbe *p = (Vdbe*)pStmt;
@@ -61942,57 +71924,133 @@ SQLITE_API int sqlite3_clear_bindings(sqlite3_stmt *pStmt){
** The following routines extract information from a Mem or sqlite3_value
** structure.
*/
-SQLITE_API const void *sqlite3_value_blob(sqlite3_value *pVal){
+SQLITE_API const void *SQLITE_STDCALL sqlite3_value_blob(sqlite3_value *pVal){
Mem *p = (Mem*)pVal;
if( p->flags & (MEM_Blob|MEM_Str) ){
- sqlite3VdbeMemExpandBlob(p);
- p->flags &= ~MEM_Str;
+ if( sqlite3VdbeMemExpandBlob(p)!=SQLITE_OK ){
+ assert( p->flags==MEM_Null && p->z==0 );
+ return 0;
+ }
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){
+SQLITE_API int SQLITE_STDCALL sqlite3_value_bytes(sqlite3_value *pVal){
return sqlite3ValueBytes(pVal, SQLITE_UTF8);
}
-SQLITE_API int sqlite3_value_bytes16(sqlite3_value *pVal){
+SQLITE_API int SQLITE_STDCALL sqlite3_value_bytes16(sqlite3_value *pVal){
return sqlite3ValueBytes(pVal, SQLITE_UTF16NATIVE);
}
-SQLITE_API double sqlite3_value_double(sqlite3_value *pVal){
+SQLITE_API double SQLITE_STDCALL sqlite3_value_double(sqlite3_value *pVal){
return sqlite3VdbeRealValue((Mem*)pVal);
}
-SQLITE_API int sqlite3_value_int(sqlite3_value *pVal){
+SQLITE_API int SQLITE_STDCALL sqlite3_value_int(sqlite3_value *pVal){
return (int)sqlite3VdbeIntValue((Mem*)pVal);
}
-SQLITE_API sqlite_int64 sqlite3_value_int64(sqlite3_value *pVal){
+SQLITE_API sqlite_int64 SQLITE_STDCALL sqlite3_value_int64(sqlite3_value *pVal){
return sqlite3VdbeIntValue((Mem*)pVal);
}
-SQLITE_API const unsigned char *sqlite3_value_text(sqlite3_value *pVal){
+SQLITE_API unsigned int SQLITE_STDCALL sqlite3_value_subtype(sqlite3_value *pVal){
+ return ((Mem*)pVal)->eSubtype;
+}
+SQLITE_API const unsigned char *SQLITE_STDCALL 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){
+SQLITE_API const void *SQLITE_STDCALL sqlite3_value_text16(sqlite3_value* pVal){
return sqlite3ValueText(pVal, SQLITE_UTF16NATIVE);
}
-SQLITE_API const void *sqlite3_value_text16be(sqlite3_value *pVal){
+SQLITE_API const void *SQLITE_STDCALL sqlite3_value_text16be(sqlite3_value *pVal){
return sqlite3ValueText(pVal, SQLITE_UTF16BE);
}
-SQLITE_API const void *sqlite3_value_text16le(sqlite3_value *pVal){
+SQLITE_API const void *SQLITE_STDCALL 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;
+/* EVIDENCE-OF: R-12793-43283 Every value in SQLite has one of five
+** fundamental datatypes: 64-bit signed integer 64-bit IEEE floating
+** point number string BLOB NULL
+*/
+SQLITE_API int SQLITE_STDCALL sqlite3_value_type(sqlite3_value* pVal){
+ static const u8 aType[] = {
+ SQLITE_BLOB, /* 0x00 */
+ SQLITE_NULL, /* 0x01 */
+ SQLITE_TEXT, /* 0x02 */
+ SQLITE_NULL, /* 0x03 */
+ SQLITE_INTEGER, /* 0x04 */
+ SQLITE_NULL, /* 0x05 */
+ SQLITE_INTEGER, /* 0x06 */
+ SQLITE_NULL, /* 0x07 */
+ SQLITE_FLOAT, /* 0x08 */
+ SQLITE_NULL, /* 0x09 */
+ SQLITE_FLOAT, /* 0x0a */
+ SQLITE_NULL, /* 0x0b */
+ SQLITE_INTEGER, /* 0x0c */
+ SQLITE_NULL, /* 0x0d */
+ SQLITE_INTEGER, /* 0x0e */
+ SQLITE_NULL, /* 0x0f */
+ SQLITE_BLOB, /* 0x10 */
+ SQLITE_NULL, /* 0x11 */
+ SQLITE_TEXT, /* 0x12 */
+ SQLITE_NULL, /* 0x13 */
+ SQLITE_INTEGER, /* 0x14 */
+ SQLITE_NULL, /* 0x15 */
+ SQLITE_INTEGER, /* 0x16 */
+ SQLITE_NULL, /* 0x17 */
+ SQLITE_FLOAT, /* 0x18 */
+ SQLITE_NULL, /* 0x19 */
+ SQLITE_FLOAT, /* 0x1a */
+ SQLITE_NULL, /* 0x1b */
+ SQLITE_INTEGER, /* 0x1c */
+ SQLITE_NULL, /* 0x1d */
+ SQLITE_INTEGER, /* 0x1e */
+ SQLITE_NULL, /* 0x1f */
+ };
+ return aType[pVal->flags&MEM_AffMask];
+}
+
+/* Make a copy of an sqlite3_value object
+*/
+SQLITE_API sqlite3_value *SQLITE_STDCALL sqlite3_value_dup(const sqlite3_value *pOrig){
+ sqlite3_value *pNew;
+ if( pOrig==0 ) return 0;
+ pNew = sqlite3_malloc( sizeof(*pNew) );
+ if( pNew==0 ) return 0;
+ memset(pNew, 0, sizeof(*pNew));
+ memcpy(pNew, pOrig, MEMCELLSIZE);
+ pNew->flags &= ~MEM_Dyn;
+ pNew->db = 0;
+ if( pNew->flags&(MEM_Str|MEM_Blob) ){
+ pNew->flags &= ~(MEM_Static|MEM_Dyn);
+ pNew->flags |= MEM_Ephem;
+ if( sqlite3VdbeMemMakeWriteable(pNew)!=SQLITE_OK ){
+ sqlite3ValueFree(pNew);
+ pNew = 0;
+ }
+ }
+ return pNew;
}
+/* Destroy an sqlite3_value object previously obtained from
+** sqlite3_value_dup().
+*/
+SQLITE_API void SQLITE_STDCALL sqlite3_value_free(sqlite3_value *pOld){
+ sqlite3ValueFree(pOld);
+}
+
+
/**************************** sqlite3_result_ *******************************
** The following routines are used by user-defined functions to specify
** the function result.
**
-** The setStrOrError() funtion calls sqlite3VdbeMemSetStr() to store the
+** The setStrOrError() function 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
+**
+** The invokeValueDestructor(P,X) routine invokes destructor function X()
+** on value P is not going to be used and need to be destroyed.
*/
static void setResultStrOrError(
sqlite3_context *pCtx, /* Function context */
@@ -62001,116 +72059,183 @@ static void setResultStrOrError(
u8 enc, /* Encoding of z. 0 for BLOBs */
void (*xDel)(void*) /* Destructor function */
){
- if( sqlite3VdbeMemSetStr(&pCtx->s, z, n, enc, xDel)==SQLITE_TOOBIG ){
+ if( sqlite3VdbeMemSetStr(pCtx->pOut, z, n, enc, xDel)==SQLITE_TOOBIG ){
sqlite3_result_error_toobig(pCtx);
}
}
-SQLITE_API void sqlite3_result_blob(
+static int invokeValueDestructor(
+ const void *p, /* Value to destroy */
+ void (*xDel)(void*), /* The destructor */
+ sqlite3_context *pCtx /* Set a SQLITE_TOOBIG error if no NULL */
+){
+ assert( xDel!=SQLITE_DYNAMIC );
+ if( xDel==0 ){
+ /* noop */
+ }else if( xDel==SQLITE_TRANSIENT ){
+ /* noop */
+ }else{
+ xDel((void*)p);
+ }
+ if( pCtx ) sqlite3_result_error_toobig(pCtx);
+ return SQLITE_TOOBIG;
+}
+SQLITE_API void SQLITE_STDCALL 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) );
+ assert( sqlite3_mutex_held(pCtx->pOut->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 SQLITE_STDCALL sqlite3_result_blob64(
+ sqlite3_context *pCtx,
+ const void *z,
+ sqlite3_uint64 n,
+ void (*xDel)(void *)
+){
+ assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) );
+ assert( xDel!=SQLITE_DYNAMIC );
+ if( n>0x7fffffff ){
+ (void)invokeValueDestructor(z, xDel, pCtx);
+ }else{
+ setResultStrOrError(pCtx, z, (int)n, 0, xDel);
+ }
}
-SQLITE_API void sqlite3_result_error(sqlite3_context *pCtx, const char *z, int n){
- assert( sqlite3_mutex_held(pCtx->s.db->mutex) );
+SQLITE_API void SQLITE_STDCALL sqlite3_result_double(sqlite3_context *pCtx, double rVal){
+ assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) );
+ sqlite3VdbeMemSetDouble(pCtx->pOut, rVal);
+}
+SQLITE_API void SQLITE_STDCALL sqlite3_result_error(sqlite3_context *pCtx, const char *z, int n){
+ assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) );
pCtx->isError = SQLITE_ERROR;
- sqlite3VdbeMemSetStr(&pCtx->s, z, n, SQLITE_UTF8, SQLITE_TRANSIENT);
+ pCtx->fErrorOrAux = 1;
+ sqlite3VdbeMemSetStr(pCtx->pOut, 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) );
+SQLITE_API void SQLITE_STDCALL sqlite3_result_error16(sqlite3_context *pCtx, const void *z, int n){
+ assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) );
pCtx->isError = SQLITE_ERROR;
- sqlite3VdbeMemSetStr(&pCtx->s, z, n, SQLITE_UTF16NATIVE, SQLITE_TRANSIENT);
+ pCtx->fErrorOrAux = 1;
+ sqlite3VdbeMemSetStr(pCtx->pOut, 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 SQLITE_STDCALL sqlite3_result_int(sqlite3_context *pCtx, int iVal){
+ assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) );
+ sqlite3VdbeMemSetInt64(pCtx->pOut, (i64)iVal);
+}
+SQLITE_API void SQLITE_STDCALL sqlite3_result_int64(sqlite3_context *pCtx, i64 iVal){
+ assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) );
+ sqlite3VdbeMemSetInt64(pCtx->pOut, 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 SQLITE_STDCALL sqlite3_result_null(sqlite3_context *pCtx){
+ assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) );
+ sqlite3VdbeMemSetNull(pCtx->pOut);
}
-SQLITE_API void sqlite3_result_null(sqlite3_context *pCtx){
- assert( sqlite3_mutex_held(pCtx->s.db->mutex) );
- sqlite3VdbeMemSetNull(&pCtx->s);
+SQLITE_API void SQLITE_STDCALL sqlite3_result_subtype(sqlite3_context *pCtx, unsigned int eSubtype){
+ assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) );
+ pCtx->pOut->eSubtype = eSubtype & 0xff;
}
-SQLITE_API void sqlite3_result_text(
+SQLITE_API void SQLITE_STDCALL sqlite3_result_text(
sqlite3_context *pCtx,
const char *z,
int n,
void (*xDel)(void *)
){
- assert( sqlite3_mutex_held(pCtx->s.db->mutex) );
+ assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) );
setResultStrOrError(pCtx, z, n, SQLITE_UTF8, xDel);
}
+SQLITE_API void SQLITE_STDCALL sqlite3_result_text64(
+ sqlite3_context *pCtx,
+ const char *z,
+ sqlite3_uint64 n,
+ void (*xDel)(void *),
+ unsigned char enc
+){
+ assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) );
+ assert( xDel!=SQLITE_DYNAMIC );
+ if( enc==SQLITE_UTF16 ) enc = SQLITE_UTF16NATIVE;
+ if( n>0x7fffffff ){
+ (void)invokeValueDestructor(z, xDel, pCtx);
+ }else{
+ setResultStrOrError(pCtx, z, (int)n, enc, xDel);
+ }
+}
#ifndef SQLITE_OMIT_UTF16
-SQLITE_API void sqlite3_result_text16(
+SQLITE_API void SQLITE_STDCALL sqlite3_result_text16(
sqlite3_context *pCtx,
const void *z,
int n,
void (*xDel)(void *)
){
- assert( sqlite3_mutex_held(pCtx->s.db->mutex) );
+ assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) );
setResultStrOrError(pCtx, z, n, SQLITE_UTF16NATIVE, xDel);
}
-SQLITE_API void sqlite3_result_text16be(
+SQLITE_API void SQLITE_STDCALL sqlite3_result_text16be(
sqlite3_context *pCtx,
const void *z,
int n,
void (*xDel)(void *)
){
- assert( sqlite3_mutex_held(pCtx->s.db->mutex) );
+ assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) );
setResultStrOrError(pCtx, z, n, SQLITE_UTF16BE, xDel);
}
-SQLITE_API void sqlite3_result_text16le(
+SQLITE_API void SQLITE_STDCALL sqlite3_result_text16le(
sqlite3_context *pCtx,
const void *z,
int n,
void (*xDel)(void *)
){
- assert( sqlite3_mutex_held(pCtx->s.db->mutex) );
+ assert( sqlite3_mutex_held(pCtx->pOut->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 SQLITE_STDCALL sqlite3_result_value(sqlite3_context *pCtx, sqlite3_value *pValue){
+ assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) );
+ sqlite3VdbeMemCopy(pCtx->pOut, pValue);
+}
+SQLITE_API void SQLITE_STDCALL sqlite3_result_zeroblob(sqlite3_context *pCtx, int n){
+ assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) );
+ sqlite3VdbeMemSetZeroBlob(pCtx->pOut, n);
+}
+SQLITE_API int SQLITE_STDCALL sqlite3_result_zeroblob64(sqlite3_context *pCtx, u64 n){
+ Mem *pOut = pCtx->pOut;
+ assert( sqlite3_mutex_held(pOut->db->mutex) );
+ if( n>(u64)pOut->db->aLimit[SQLITE_LIMIT_LENGTH] ){
+ return SQLITE_TOOBIG;
+ }
+ sqlite3VdbeMemSetZeroBlob(pCtx->pOut, (int)n);
+ return SQLITE_OK;
}
-SQLITE_API void sqlite3_result_error_code(sqlite3_context *pCtx, int errCode){
+SQLITE_API void SQLITE_STDCALL sqlite3_result_error_code(sqlite3_context *pCtx, int errCode){
pCtx->isError = errCode;
- if( pCtx->s.flags & MEM_Null ){
- sqlite3VdbeMemSetStr(&pCtx->s, sqlite3ErrStr(errCode), -1,
+ pCtx->fErrorOrAux = 1;
+#ifdef SQLITE_DEBUG
+ if( pCtx->pVdbe ) pCtx->pVdbe->rcApp = errCode;
+#endif
+ if( pCtx->pOut->flags & MEM_Null ){
+ sqlite3VdbeMemSetStr(pCtx->pOut, 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) );
+SQLITE_API void SQLITE_STDCALL sqlite3_result_error_toobig(sqlite3_context *pCtx){
+ assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) );
pCtx->isError = SQLITE_TOOBIG;
- sqlite3VdbeMemSetStr(&pCtx->s, "string or blob too big", -1,
+ pCtx->fErrorOrAux = 1;
+ sqlite3VdbeMemSetStr(pCtx->pOut, "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);
+SQLITE_API void SQLITE_STDCALL sqlite3_result_error_nomem(sqlite3_context *pCtx){
+ assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) );
+ sqlite3VdbeMemSetNull(pCtx->pOut);
pCtx->isError = SQLITE_NOMEM;
- pCtx->s.db->mallocFailed = 1;
+ pCtx->fErrorOrAux = 1;
+ pCtx->pOut->db->mallocFailed = 1;
}
/*
@@ -62124,7 +72249,10 @@ static int doWalCallbacks(sqlite3 *db){
for(i=0; i<db->nDb; i++){
Btree *pBt = db->aDb[i].pBt;
if( pBt ){
- int nEntry = sqlite3PagerWalCallback(sqlite3BtreePager(pBt));
+ int nEntry;
+ sqlite3BtreeEnter(pBt);
+ nEntry = sqlite3PagerWalCallback(sqlite3BtreePager(pBt));
+ sqlite3BtreeLeave(pBt);
if( db->xWalCallback && nEntry>0 && rc==SQLITE_OK ){
rc = db->xWalCallback(db->pWalArg, db, db->aDb[i].zName, nEntry);
}
@@ -62134,6 +72262,7 @@ static int doWalCallbacks(sqlite3 *db){
return rc;
}
+
/*
** Execute the statement pStmt, either until a row of data is ready, the
** statement is completely executed or an error occurs.
@@ -62166,7 +72295,7 @@ static int sqlite3Step(Vdbe *p){
** or SQLITE_BUSY error.
*/
#ifdef SQLITE_OMIT_AUTORESET
- if( p->rc==SQLITE_BUSY || p->rc==SQLITE_LOCKED ){
+ if( (rc = p->rc&0xff)==SQLITE_BUSY || rc==SQLITE_LOCKED ){
sqlite3_reset((sqlite3_stmt*)p);
}else{
return SQLITE_MISUSE_BKPT;
@@ -62193,41 +72322,44 @@ static int sqlite3Step(Vdbe *p){
** reset the interrupt flag. This prevents a call to sqlite3_interrupt
** from interrupting a statement that has not yet started.
*/
- if( db->activeVdbeCnt==0 ){
+ if( db->nVdbeActive==0 ){
db->u1.isInterrupted = 0;
}
- assert( db->writeVdbeCnt>0 || db->autoCommit==0 || db->nDeferredCons==0 );
+ assert( db->nVdbeWrite>0 || db->autoCommit==0
+ || (db->nDeferredCons==0 && db->nDeferredImmCons==0)
+ );
#ifndef SQLITE_OMIT_TRACE
- if( db->xProfile && !db->init.busy ){
+ if( db->xProfile && !db->init.busy && p->zSql ){
sqlite3OsCurrentTimeInt64(db->pVfs, &p->startTime);
+ }else{
+ assert( p->startTime==0 );
}
#endif
- db->activeVdbeCnt++;
- if( p->readOnly==0 ) db->writeVdbeCnt++;
+ db->nVdbeActive++;
+ if( p->readOnly==0 ) db->nVdbeWrite++;
+ if( p->bIsReader ) db->nVdbeRead++;
p->pc = 0;
}
+#ifdef SQLITE_DEBUG
+ p->rcApp = SQLITE_OK;
+#endif
#ifndef SQLITE_OMIT_EXPLAIN
if( p->explain ){
rc = sqlite3VdbeList(p);
}else
#endif /* SQLITE_OMIT_EXPLAIN */
{
- db->vdbeExecCnt++;
+ db->nVdbeExec++;
rc = sqlite3VdbeExec(p);
- db->vdbeExecCnt--;
+ db->nVdbeExec--;
}
#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);
- }
+ /* If the statement completed successfully, invoke the profile callback */
+ if( rc!=SQLITE_ROW ) checkProfileCallback(db, p);
#endif
if( rc==SQLITE_DONE ){
@@ -62251,12 +72383,12 @@ end_of_step:
** were called on statement p.
*/
assert( rc==SQLITE_ROW || rc==SQLITE_DONE || rc==SQLITE_ERROR
- || rc==SQLITE_BUSY || rc==SQLITE_MISUSE
+ || (rc&0xff)==SQLITE_BUSY || rc==SQLITE_MISUSE
);
- assert( p->rc!=SQLITE_ROW && p->rc!=SQLITE_DONE );
+ assert( (p->rc!=SQLITE_ROW && p->rc!=SQLITE_DONE) || p->rc==p->rcApp );
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
+ ** error has occurred, 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);
@@ -62265,19 +72397,11 @@ end_of_step:
}
/*
-** 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){
+SQLITE_API int SQLITE_STDCALL 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 */
@@ -62291,13 +72415,15 @@ SQLITE_API int sqlite3_step(sqlite3_stmt *pStmt){
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 ){
+ && cnt++ < SQLITE_MAX_SCHEMA_RETRY ){
+ int savedPc = v->pc;
+ rc2 = rc = sqlite3Reprepare(v);
+ if( rc!=SQLITE_OK) break;
sqlite3_reset(pStmt);
- v->doingRerun = 1;
+ if( savedPc>=0 ) v->doingRerun = 1;
assert( v->expired==0 );
}
- if( rc2!=SQLITE_OK && ALWAYS(v->isPrepareV2) && ALWAYS(db->pErr) ){
+ if( rc2!=SQLITE_OK ){
/* 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
@@ -62321,11 +72447,12 @@ SQLITE_API int sqlite3_step(sqlite3_stmt *pStmt){
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){
+SQLITE_API void *SQLITE_STDCALL sqlite3_user_data(sqlite3_context *p){
assert( p && p->pFunc );
return p->pFunc->pUserData;
}
@@ -62340,9 +72467,32 @@ SQLITE_API void *sqlite3_user_data(sqlite3_context *p){
** 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;
+SQLITE_API sqlite3 *SQLITE_STDCALL sqlite3_context_db_handle(sqlite3_context *p){
+ assert( p && p->pOut );
+ return p->pOut->db;
+}
+
+/*
+** Return the current time for a statement. If the current time
+** is requested more than once within the same run of a single prepared
+** statement, the exact same time is returned for each invocation regardless
+** of the amount of time that elapses between invocations. In other words,
+** the time returned is always the time of the first call.
+*/
+SQLITE_PRIVATE sqlite3_int64 sqlite3StmtCurrentTime(sqlite3_context *p){
+ int rc;
+#ifndef SQLITE_ENABLE_STAT3_OR_STAT4
+ sqlite3_int64 *piTime = &p->pVdbe->iCurrentTime;
+ assert( p->pVdbe!=0 );
+#else
+ sqlite3_int64 iTime = 0;
+ sqlite3_int64 *piTime = p->pVdbe!=0 ? &p->pVdbe->iCurrentTime : &iTime;
+#endif
+ if( *piTime==0 ){
+ rc = sqlite3OsCurrentTimeInt64(p->pOut->db->pVfs, piTime);
+ if( rc ) *piTime = 0;
+ }
+ return *piTime;
}
/*
@@ -62368,82 +72518,102 @@ SQLITE_PRIVATE void sqlite3InvalidFunction(
}
/*
+** Create a new aggregate context for p and return a pointer to
+** its pMem->z element.
+*/
+static SQLITE_NOINLINE void *createAggContext(sqlite3_context *p, int nByte){
+ Mem *pMem = p->pMem;
+ assert( (pMem->flags & MEM_Agg)==0 );
+ if( nByte<=0 ){
+ sqlite3VdbeMemSetNull(pMem);
+ pMem->z = 0;
+ }else{
+ sqlite3VdbeMemClearAndResize(pMem, nByte);
+ pMem->flags = MEM_Agg;
+ pMem->u.pDef = p->pFunc;
+ if( pMem->z ){
+ memset(pMem->z, 0, nByte);
+ }
+ }
+ return (void*)pMem->z;
+}
+
+/*
** 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;
+SQLITE_API void *SQLITE_STDCALL sqlite3_aggregate_context(sqlite3_context *p, int nByte){
assert( p && p->pFunc && p->pFunc->xStep );
- assert( sqlite3_mutex_held(p->s.db->mutex) );
- pMem = p->pMem;
+ assert( sqlite3_mutex_held(p->pOut->db->mutex) );
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);
- }
- }
+ if( (p->pMem->flags & MEM_Agg)==0 ){
+ return createAggContext(p, nByte);
+ }else{
+ return (void*)p->pMem->z;
}
- return (void*)pMem->z;
}
/*
-** Return the auxilary data pointer, if any, for the iArg'th argument to
+** Return the auxiliary 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;
+SQLITE_API void *SQLITE_STDCALL sqlite3_get_auxdata(sqlite3_context *pCtx, int iArg){
+ AuxData *pAuxData;
- assert( sqlite3_mutex_held(pCtx->s.db->mutex) );
- pVdbeFunc = pCtx->pVdbeFunc;
- if( !pVdbeFunc || iArg>=pVdbeFunc->nAux || iArg<0 ){
- return 0;
+ assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) );
+#if SQLITE_ENABLE_STAT3_OR_STAT4
+ if( pCtx->pVdbe==0 ) return 0;
+#else
+ assert( pCtx->pVdbe!=0 );
+#endif
+ for(pAuxData=pCtx->pVdbe->pAuxData; pAuxData; pAuxData=pAuxData->pNext){
+ if( pAuxData->iOp==pCtx->iOp && pAuxData->iArg==iArg ) break;
}
- return pVdbeFunc->apAux[iArg].pAux;
+
+ return (pAuxData ? pAuxData->pAux : 0);
}
/*
-** Set the auxilary data pointer and delete function, for the iArg'th
+** Set the auxiliary 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(
+SQLITE_API void SQLITE_STDCALL sqlite3_set_auxdata(
sqlite3_context *pCtx,
int iArg,
void *pAux,
void (*xDelete)(void*)
){
- struct AuxData *pAuxData;
- VdbeFunc *pVdbeFunc;
+ AuxData *pAuxData;
+ Vdbe *pVdbe = pCtx->pVdbe;
+
+ assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) );
if( iArg<0 ) goto failed;
+#ifdef SQLITE_ENABLE_STAT3_OR_STAT4
+ if( pVdbe==0 ) goto failed;
+#else
+ assert( pVdbe!=0 );
+#endif
- 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;
+ for(pAuxData=pVdbe->pAuxData; pAuxData; pAuxData=pAuxData->pNext){
+ if( pAuxData->iOp==pCtx->iOp && pAuxData->iArg==iArg ) break;
}
-
- pAuxData = &pVdbeFunc->apAux[iArg];
- if( pAuxData->pAux && pAuxData->xDelete ){
+ if( pAuxData==0 ){
+ pAuxData = sqlite3DbMallocZero(pVdbe->db, sizeof(AuxData));
+ if( !pAuxData ) goto failed;
+ pAuxData->iOp = pCtx->iOp;
+ pAuxData->iArg = iArg;
+ pAuxData->pNext = pVdbe->pAuxData;
+ pVdbe->pAuxData = pAuxData;
+ if( pCtx->fErrorOrAux==0 ){
+ pCtx->isError = 0;
+ pCtx->fErrorOrAux = 1;
+ }
+ }else if( pAuxData->xDelete ){
pAuxData->xDelete(pAuxData->pAux);
}
+
pAuxData->pAux = pAux;
pAuxData->xDelete = xDelete;
return;
@@ -62456,7 +72626,7 @@ failed:
#ifndef SQLITE_OMIT_DEPRECATED
/*
-** Return the number of times the Step function of a aggregate has been
+** Return the number of times the Step function of an aggregate has been
** called.
**
** This function is deprecated. Do not use it for new code. It is
@@ -62464,7 +72634,7 @@ failed:
** implementations should keep their own counts within their aggregate
** context.
*/
-SQLITE_API int sqlite3_aggregate_count(sqlite3_context *p){
+SQLITE_API int SQLITE_STDCALL sqlite3_aggregate_count(sqlite3_context *p){
assert( p && p->pMem && p->pFunc && p->pFunc->xStep );
return p->pMem->n;
}
@@ -62473,7 +72643,7 @@ SQLITE_API int sqlite3_aggregate_count(sqlite3_context *p){
/*
** Return the number of columns in the result set for the statement pStmt.
*/
-SQLITE_API int sqlite3_column_count(sqlite3_stmt *pStmt){
+SQLITE_API int SQLITE_STDCALL sqlite3_column_count(sqlite3_stmt *pStmt){
Vdbe *pVm = (Vdbe *)pStmt;
return pVm ? pVm->nResColumn : 0;
}
@@ -62482,12 +72652,48 @@ SQLITE_API int sqlite3_column_count(sqlite3_stmt *pStmt){
** 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){
+SQLITE_API int SQLITE_STDCALL sqlite3_data_count(sqlite3_stmt *pStmt){
Vdbe *pVm = (Vdbe *)pStmt;
if( pVm==0 || pVm->pResultSet==0 ) return 0;
return pVm->nResColumn;
}
+/*
+** Return a pointer to static memory containing an SQL NULL value.
+*/
+static const Mem *columnNullValue(void){
+ /* 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
+ = {
+ /* .u = */ {0},
+ /* .flags = */ (u16)MEM_Null,
+ /* .enc = */ (u8)0,
+ /* .eSubtype = */ (u8)0,
+ /* .n = */ (int)0,
+ /* .z = */ (char*)0,
+ /* .zMalloc = */ (char*)0,
+ /* .szMalloc = */ (int)0,
+ /* .uTemp = */ (u32)0,
+ /* .db = */ (sqlite3*)0,
+ /* .xDel = */ (void(*)(void*))0,
+#ifdef SQLITE_DEBUG
+ /* .pScopyFrom = */ (Mem*)0,
+ /* .pFiller = */ (void*)0,
+#endif
+ };
+ return &nullMem;
+}
/*
** Check to see if column iCol of the given statement is valid. If
@@ -62504,32 +72710,11 @@ static Mem *columnMem(sqlite3_stmt *pStmt, int i){
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);
+ sqlite3Error(pVm->db, SQLITE_RANGE);
}
- pOut = (Mem*)&nullMem;
+ pOut = (Mem*)columnNullValue();
}
return pOut;
}
@@ -62570,7 +72755,7 @@ static void columnMallocFailure(sqlite3_stmt *pStmt)
** 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){
+SQLITE_API const void *SQLITE_STDCALL 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
@@ -62580,37 +72765,37 @@ SQLITE_API const void *sqlite3_column_blob(sqlite3_stmt *pStmt, int i){
columnMallocFailure(pStmt);
return val;
}
-SQLITE_API int sqlite3_column_bytes(sqlite3_stmt *pStmt, int i){
+SQLITE_API int SQLITE_STDCALL 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){
+SQLITE_API int SQLITE_STDCALL 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){
+SQLITE_API double SQLITE_STDCALL 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){
+SQLITE_API int SQLITE_STDCALL 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_API sqlite_int64 SQLITE_STDCALL 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){
+SQLITE_API const unsigned char *SQLITE_STDCALL 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){
+SQLITE_API sqlite3_value *SQLITE_STDCALL sqlite3_column_value(sqlite3_stmt *pStmt, int i){
Mem *pOut = columnMem(pStmt, i);
if( pOut->flags&MEM_Static ){
pOut->flags &= ~MEM_Static;
@@ -62620,25 +72805,18 @@ SQLITE_API sqlite3_value *sqlite3_column_value(sqlite3_stmt *pStmt, int i){
return (sqlite3_value *)pOut;
}
#ifndef SQLITE_OMIT_UTF16
-SQLITE_API const void *sqlite3_column_text16(sqlite3_stmt *pStmt, int i){
+SQLITE_API const void *SQLITE_STDCALL 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){
+SQLITE_API int SQLITE_STDCALL 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.
@@ -62661,11 +72839,19 @@ static const void *columnName(
const void *(*xFunc)(Mem*),
int useType
){
- const void *ret = 0;
- Vdbe *p = (Vdbe *)pStmt;
+ const void *ret;
+ Vdbe *p;
int n;
- sqlite3 *db = p->db;
-
+ sqlite3 *db;
+#ifdef SQLITE_ENABLE_API_ARMOR
+ if( pStmt==0 ){
+ (void)SQLITE_MISUSE_BKPT;
+ return 0;
+ }
+#endif
+ ret = 0;
+ p = (Vdbe *)pStmt;
+ db = p->db;
assert( db!=0 );
n = sqlite3_column_count(pStmt);
if( N<n && N>=0 ){
@@ -62689,12 +72875,12 @@ static const void *columnName(
** 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){
+SQLITE_API const char *SQLITE_STDCALL 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){
+SQLITE_API const void *SQLITE_STDCALL sqlite3_column_name16(sqlite3_stmt *pStmt, int N){
return columnName(
pStmt, N, (const void*(*)(Mem*))sqlite3_value_text16, COLNAME_NAME);
}
@@ -62714,12 +72900,12 @@ SQLITE_API const void *sqlite3_column_name16(sqlite3_stmt *pStmt, int N){
** 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){
+SQLITE_API const char *SQLITE_STDCALL 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){
+SQLITE_API const void *SQLITE_STDCALL sqlite3_column_decltype16(sqlite3_stmt *pStmt, int N){
return columnName(
pStmt, N, (const void*(*)(Mem*))sqlite3_value_text16, COLNAME_DECLTYPE);
}
@@ -62730,14 +72916,14 @@ SQLITE_API const void *sqlite3_column_decltype16(sqlite3_stmt *pStmt, int N){
/*
** 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.
+** anything else which is not an unambiguous reference to a database column.
*/
-SQLITE_API const char *sqlite3_column_database_name(sqlite3_stmt *pStmt, int N){
+SQLITE_API const char *SQLITE_STDCALL 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){
+SQLITE_API const void *SQLITE_STDCALL sqlite3_column_database_name16(sqlite3_stmt *pStmt, int N){
return columnName(
pStmt, N, (const void*(*)(Mem*))sqlite3_value_text16, COLNAME_DATABASE);
}
@@ -62746,14 +72932,14 @@ SQLITE_API const void *sqlite3_column_database_name16(sqlite3_stmt *pStmt, int N
/*
** 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.
+** anything else which is not an unambiguous reference to a database column.
*/
-SQLITE_API const char *sqlite3_column_table_name(sqlite3_stmt *pStmt, int N){
+SQLITE_API const char *SQLITE_STDCALL 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){
+SQLITE_API const void *SQLITE_STDCALL sqlite3_column_table_name16(sqlite3_stmt *pStmt, int N){
return columnName(
pStmt, N, (const void*(*)(Mem*))sqlite3_value_text16, COLNAME_TABLE);
}
@@ -62762,14 +72948,14 @@ SQLITE_API const void *sqlite3_column_table_name16(sqlite3_stmt *pStmt, int N){
/*
** 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.
+** anything else which is not an unambiguous reference to a database column.
*/
-SQLITE_API const char *sqlite3_column_origin_name(sqlite3_stmt *pStmt, int N){
+SQLITE_API const char *SQLITE_STDCALL 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){
+SQLITE_API const void *SQLITE_STDCALL sqlite3_column_origin_name16(sqlite3_stmt *pStmt, int N){
return columnName(
pStmt, N, (const void*(*)(Mem*))sqlite3_value_text16, COLNAME_COLUMN);
}
@@ -62799,14 +72985,14 @@ static int vdbeUnbind(Vdbe *p, int i){
}
sqlite3_mutex_enter(p->db->mutex);
if( p->magic!=VDBE_MAGIC_RUN || p->pc>=0 ){
- sqlite3Error(p->db, SQLITE_MISUSE, 0);
+ sqlite3Error(p->db, SQLITE_MISUSE);
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);
+ sqlite3Error(p->db, SQLITE_RANGE);
sqlite3_mutex_leave(p->db->mutex);
return SQLITE_RANGE;
}
@@ -62814,7 +73000,7 @@ static int vdbeUnbind(Vdbe *p, int i){
pVar = &p->aVar[i];
sqlite3VdbeMemRelease(pVar);
pVar->flags = MEM_Null;
- sqlite3Error(p->db, SQLITE_OK, 0);
+ sqlite3Error(p->db, SQLITE_OK);
/* 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.
@@ -62856,7 +73042,7 @@ static int bindText(
if( rc==SQLITE_OK && encoding!=0 ){
rc = sqlite3VdbeChangeEncoding(pVar, ENC(p->db));
}
- sqlite3Error(p->db, rc, 0);
+ sqlite3Error(p->db, rc);
rc = sqlite3ApiExit(p->db, rc);
}
sqlite3_mutex_leave(p->db->mutex);
@@ -62870,7 +73056,7 @@ static int bindText(
/*
** Bind a blob value to an SQL statement variable.
*/
-SQLITE_API int sqlite3_bind_blob(
+SQLITE_API int SQLITE_STDCALL sqlite3_bind_blob(
sqlite3_stmt *pStmt,
int i,
const void *zData,
@@ -62879,7 +73065,21 @@ SQLITE_API int sqlite3_bind_blob(
){
return bindText(pStmt, i, zData, nData, xDel, 0);
}
-SQLITE_API int sqlite3_bind_double(sqlite3_stmt *pStmt, int i, double rValue){
+SQLITE_API int SQLITE_STDCALL sqlite3_bind_blob64(
+ sqlite3_stmt *pStmt,
+ int i,
+ const void *zData,
+ sqlite3_uint64 nData,
+ void (*xDel)(void*)
+){
+ assert( xDel!=SQLITE_DYNAMIC );
+ if( nData>0x7fffffff ){
+ return invokeValueDestructor(zData, xDel, 0);
+ }else{
+ return bindText(pStmt, i, zData, (int)nData, xDel, 0);
+ }
+}
+SQLITE_API int SQLITE_STDCALL sqlite3_bind_double(sqlite3_stmt *pStmt, int i, double rValue){
int rc;
Vdbe *p = (Vdbe *)pStmt;
rc = vdbeUnbind(p, i);
@@ -62889,10 +73089,10 @@ SQLITE_API int sqlite3_bind_double(sqlite3_stmt *pStmt, int i, double rValue){
}
return rc;
}
-SQLITE_API int sqlite3_bind_int(sqlite3_stmt *p, int i, int iValue){
+SQLITE_API int SQLITE_STDCALL 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){
+SQLITE_API int SQLITE_STDCALL sqlite3_bind_int64(sqlite3_stmt *pStmt, int i, sqlite_int64 iValue){
int rc;
Vdbe *p = (Vdbe *)pStmt;
rc = vdbeUnbind(p, i);
@@ -62902,7 +73102,7 @@ SQLITE_API int sqlite3_bind_int64(sqlite3_stmt *pStmt, int i, sqlite_int64 iValu
}
return rc;
}
-SQLITE_API int sqlite3_bind_null(sqlite3_stmt *pStmt, int i){
+SQLITE_API int SQLITE_STDCALL sqlite3_bind_null(sqlite3_stmt *pStmt, int i){
int rc;
Vdbe *p = (Vdbe*)pStmt;
rc = vdbeUnbind(p, i);
@@ -62911,7 +73111,7 @@ SQLITE_API int sqlite3_bind_null(sqlite3_stmt *pStmt, int i){
}
return rc;
}
-SQLITE_API int sqlite3_bind_text(
+SQLITE_API int SQLITE_STDCALL sqlite3_bind_text(
sqlite3_stmt *pStmt,
int i,
const char *zData,
@@ -62920,8 +73120,24 @@ SQLITE_API int sqlite3_bind_text(
){
return bindText(pStmt, i, zData, nData, xDel, SQLITE_UTF8);
}
+SQLITE_API int SQLITE_STDCALL sqlite3_bind_text64(
+ sqlite3_stmt *pStmt,
+ int i,
+ const char *zData,
+ sqlite3_uint64 nData,
+ void (*xDel)(void*),
+ unsigned char enc
+){
+ assert( xDel!=SQLITE_DYNAMIC );
+ if( nData>0x7fffffff ){
+ return invokeValueDestructor(zData, xDel, 0);
+ }else{
+ if( enc==SQLITE_UTF16 ) enc = SQLITE_UTF16NATIVE;
+ return bindText(pStmt, i, zData, (int)nData, xDel, enc);
+ }
+}
#ifndef SQLITE_OMIT_UTF16
-SQLITE_API int sqlite3_bind_text16(
+SQLITE_API int SQLITE_STDCALL sqlite3_bind_text16(
sqlite3_stmt *pStmt,
int i,
const void *zData,
@@ -62931,15 +73147,15 @@ SQLITE_API int sqlite3_bind_text16(
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){
+SQLITE_API int SQLITE_STDCALL sqlite3_bind_value(sqlite3_stmt *pStmt, int i, const sqlite3_value *pValue){
int rc;
- switch( pValue->type ){
+ switch( sqlite3_value_type((sqlite3_value*)pValue) ){
case SQLITE_INTEGER: {
rc = sqlite3_bind_int64(pStmt, i, pValue->u.i);
break;
}
case SQLITE_FLOAT: {
- rc = sqlite3_bind_double(pStmt, i, pValue->r);
+ rc = sqlite3_bind_double(pStmt, i, pValue->u.r);
break;
}
case SQLITE_BLOB: {
@@ -62962,7 +73178,7 @@ SQLITE_API int sqlite3_bind_value(sqlite3_stmt *pStmt, int i, const sqlite3_valu
}
return rc;
}
-SQLITE_API int sqlite3_bind_zeroblob(sqlite3_stmt *pStmt, int i, int n){
+SQLITE_API int SQLITE_STDCALL sqlite3_bind_zeroblob(sqlite3_stmt *pStmt, int i, int n){
int rc;
Vdbe *p = (Vdbe *)pStmt;
rc = vdbeUnbind(p, i);
@@ -62972,12 +73188,26 @@ SQLITE_API int sqlite3_bind_zeroblob(sqlite3_stmt *pStmt, int i, int n){
}
return rc;
}
+SQLITE_API int SQLITE_STDCALL sqlite3_bind_zeroblob64(sqlite3_stmt *pStmt, int i, sqlite3_uint64 n){
+ int rc;
+ Vdbe *p = (Vdbe *)pStmt;
+ sqlite3_mutex_enter(p->db->mutex);
+ if( n>(u64)p->db->aLimit[SQLITE_LIMIT_LENGTH] ){
+ rc = SQLITE_TOOBIG;
+ }else{
+ assert( (n & 0x7FFFFFFF)==n );
+ rc = sqlite3_bind_zeroblob(pStmt, i, n);
+ }
+ rc = sqlite3ApiExit(p->db, rc);
+ 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){
+SQLITE_API int SQLITE_STDCALL sqlite3_bind_parameter_count(sqlite3_stmt *pStmt){
Vdbe *p = (Vdbe*)pStmt;
return p ? p->nVar : 0;
}
@@ -62988,7 +73218,7 @@ SQLITE_API int sqlite3_bind_parameter_count(sqlite3_stmt *pStmt){
**
** The result is always UTF-8.
*/
-SQLITE_API const char *sqlite3_bind_parameter_name(sqlite3_stmt *pStmt, int i){
+SQLITE_API const char *SQLITE_STDCALL sqlite3_bind_parameter_name(sqlite3_stmt *pStmt, int i){
Vdbe *p = (Vdbe*)pStmt;
if( p==0 || i<1 || i>p->nzVar ){
return 0;
@@ -63009,14 +73239,14 @@ SQLITE_PRIVATE int sqlite3VdbeParameterIndex(Vdbe *p, const char *zName, int nNa
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 ){
+ if( z && strncmp(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){
+SQLITE_API int SQLITE_STDCALL sqlite3_bind_parameter_index(sqlite3_stmt *pStmt, const char *zName){
return sqlite3VdbeParameterIndex((Vdbe*)pStmt, zName, sqlite3Strlen30(zName));
}
@@ -63042,7 +73272,7 @@ SQLITE_PRIVATE int sqlite3TransferBindings(sqlite3_stmt *pFromStmt, sqlite3_stmt
** Deprecated external interface. Internal/core SQLite code
** should call sqlite3TransferBindings.
**
-** Is is misuse to call this routine with statements from different
+** It 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.
**
@@ -63050,7 +73280,7 @@ SQLITE_PRIVATE int sqlite3TransferBindings(sqlite3_stmt *pFromStmt, sqlite3_stmt
** 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){
+SQLITE_API int SQLITE_STDCALL sqlite3_transfer_bindings(sqlite3_stmt *pFromStmt, sqlite3_stmt *pToStmt){
Vdbe *pFrom = (Vdbe*)pFromStmt;
Vdbe *pTo = (Vdbe*)pToStmt;
if( pFrom->nVar!=pTo->nVar ){
@@ -63072,7 +73302,7 @@ SQLITE_API int sqlite3_transfer_bindings(sqlite3_stmt *pFromStmt, sqlite3_stmt *
** 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){
+SQLITE_API sqlite3 *SQLITE_STDCALL sqlite3_db_handle(sqlite3_stmt *pStmt){
return pStmt ? ((Vdbe*)pStmt)->db : 0;
}
@@ -63080,16 +73310,16 @@ SQLITE_API sqlite3 *sqlite3_db_handle(sqlite3_stmt *pStmt){
** Return true if the prepared statement is guaranteed to not modify the
** database.
*/
-SQLITE_API int sqlite3_stmt_readonly(sqlite3_stmt *pStmt){
+SQLITE_API int SQLITE_STDCALL 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){
+SQLITE_API int SQLITE_STDCALL sqlite3_stmt_busy(sqlite3_stmt *pStmt){
Vdbe *v = (Vdbe*)pStmt;
- return v!=0 && v->pc>0 && v->magic==VDBE_MAGIC_RUN;
+ return v!=0 && v->pc>=0 && v->magic==VDBE_MAGIC_RUN;
}
/*
@@ -63098,8 +73328,14 @@ SQLITE_API int sqlite3_stmt_busy(sqlite3_stmt *pStmt){
** 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){
+SQLITE_API sqlite3_stmt *SQLITE_STDCALL sqlite3_next_stmt(sqlite3 *pDb, sqlite3_stmt *pStmt){
sqlite3_stmt *pNext;
+#ifdef SQLITE_ENABLE_API_ARMOR
+ if( !sqlite3SafetyCheckOk(pDb) ){
+ (void)SQLITE_MISUSE_BKPT;
+ return 0;
+ }
+#endif
sqlite3_mutex_enter(pDb->mutex);
if( pStmt==0 ){
pNext = (sqlite3_stmt*)pDb->pVdbe;
@@ -63113,12 +73349,88 @@ SQLITE_API sqlite3_stmt *sqlite3_next_stmt(sqlite3 *pDb, sqlite3_stmt *pStmt){
/*
** Return the value of a status counter for a prepared statement
*/
-SQLITE_API int sqlite3_stmt_status(sqlite3_stmt *pStmt, int op, int resetFlag){
+SQLITE_API int SQLITE_STDCALL 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;
+ u32 v;
+#ifdef SQLITE_ENABLE_API_ARMOR
+ if( !pStmt ){
+ (void)SQLITE_MISUSE_BKPT;
+ return 0;
+ }
+#endif
+ v = pVdbe->aCounter[op];
+ if( resetFlag ) pVdbe->aCounter[op] = 0;
+ return (int)v;
+}
+
+#ifdef SQLITE_ENABLE_STMT_SCANSTATUS
+/*
+** Return status data for a single loop within query pStmt.
+*/
+SQLITE_API int SQLITE_STDCALL sqlite3_stmt_scanstatus(
+ sqlite3_stmt *pStmt, /* Prepared statement being queried */
+ int idx, /* Index of loop to report on */
+ int iScanStatusOp, /* Which metric to return */
+ void *pOut /* OUT: Write the answer here */
+){
+ Vdbe *p = (Vdbe*)pStmt;
+ ScanStatus *pScan;
+ if( idx<0 || idx>=p->nScan ) return 1;
+ pScan = &p->aScan[idx];
+ switch( iScanStatusOp ){
+ case SQLITE_SCANSTAT_NLOOP: {
+ *(sqlite3_int64*)pOut = p->anExec[pScan->addrLoop];
+ break;
+ }
+ case SQLITE_SCANSTAT_NVISIT: {
+ *(sqlite3_int64*)pOut = p->anExec[pScan->addrVisit];
+ break;
+ }
+ case SQLITE_SCANSTAT_EST: {
+ double r = 1.0;
+ LogEst x = pScan->nEst;
+ while( x<100 ){
+ x += 10;
+ r *= 0.5;
+ }
+ *(double*)pOut = r*sqlite3LogEstToInt(x);
+ break;
+ }
+ case SQLITE_SCANSTAT_NAME: {
+ *(const char**)pOut = pScan->zName;
+ break;
+ }
+ case SQLITE_SCANSTAT_EXPLAIN: {
+ if( pScan->addrExplain ){
+ *(const char**)pOut = p->aOp[ pScan->addrExplain ].p4.z;
+ }else{
+ *(const char**)pOut = 0;
+ }
+ break;
+ }
+ case SQLITE_SCANSTAT_SELECTID: {
+ if( pScan->addrExplain ){
+ *(int*)pOut = p->aOp[ pScan->addrExplain ].p1;
+ }else{
+ *(int*)pOut = -1;
+ }
+ break;
+ }
+ default: {
+ return 1;
+ }
+ }
+ return 0;
+}
+
+/*
+** Zero all counters associated with the sqlite3_stmt_scanstatus() data.
+*/
+SQLITE_API void SQLITE_STDCALL sqlite3_stmt_scanstatus_reset(sqlite3_stmt *pStmt){
+ Vdbe *p = (Vdbe*)pStmt;
+ memset(p->anExec, 0, p->nOp * sizeof(i64));
}
+#endif /* SQLITE_ENABLE_STMT_SCANSTATUS */
/************** End of vdbeapi.c *********************************************/
/************** Begin file vdbetrace.c ***************************************/
@@ -63139,6 +73451,8 @@ SQLITE_API int sqlite3_stmt_status(sqlite3_stmt *pStmt, int op, int resetFlag){
**
** The Vdbe parse-tree explainer is also found here.
*/
+/* #include "sqliteInt.h" */
+/* #include "vdbeInt.h" */
#ifndef SQLITE_OMIT_TRACE
@@ -63169,19 +73483,24 @@ static int findNextHostParameter(const char *zSql, int *pnToken){
/*
** This function returns a pointer to a nul-terminated string in memory
-** obtained from sqlite3DbMalloc(). If sqlite3.vdbeExecCnt is 1, then the
+** obtained from sqlite3DbMalloc(). If sqlite3.nVdbeExec 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,
+** their current bindings. Or, if sqlite3.nVdbeExec is greater than 1,
** then the returned string holds a copy of zRawSql with "-- " prepended
** to each line of text.
**
+** If the SQLITE_TRACE_SIZE_LIMIT macro is defined to an integer, then
+** then long strings and blobs are truncated to that many bytes. This
+** can be used to prevent unreasonably large trace strings when dealing
+** with large (multi-megabyte) strings and blobs.
+**
** 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
+** the host parameter index is found by scanning the prepared
** 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.
@@ -63201,16 +73520,18 @@ SQLITE_PRIVATE char *sqlite3VdbeExpandSql(
char zBase[100]; /* Initial working space */
db = p->db;
- sqlite3StrAccumInit(&out, zBase, sizeof(zBase),
+ sqlite3StrAccumInit(&out, db, zBase, sizeof(zBase),
db->aLimit[SQLITE_LIMIT_LENGTH]);
- out.db = db;
- if( db->vdbeExecCnt>1 ){
+ if( db->nVdbeExec>1 ){
while( *zRawSql ){
const char *zStart = zRawSql;
while( *(zRawSql++)!='\n' && *zRawSql );
sqlite3StrAccumAppend(&out, "-- ", 3);
+ assert( (zRawSql - zStart) > 0 );
sqlite3StrAccumAppend(&out, zStart, (int)(zRawSql-zStart));
}
+ }else if( p->nVar==0 ){
+ sqlite3StrAccumAppend(&out, zRawSql, sqlite3Strlen30(zRawSql));
}else{
while( zRawSql[0] ){
n = findNextHostParameter(zRawSql, &nToken);
@@ -63227,10 +73548,12 @@ SQLITE_PRIVATE char *sqlite3VdbeExpandSql(
idx = nextIndex;
}
}else{
- assert( zRawSql[0]==':' || zRawSql[0]=='$' || zRawSql[0]=='@' );
+ assert( zRawSql[0]==':' || zRawSql[0]=='$' ||
+ zRawSql[0]=='@' || zRawSql[0]=='#' );
testcase( zRawSql[0]==':' );
testcase( zRawSql[0]=='$' );
testcase( zRawSql[0]=='@' );
+ testcase( zRawSql[0]=='#' );
idx = sqlite3VdbeParameterIndex(p, zRawSql, nToken);
assert( idx>0 );
}
@@ -63241,34 +73564,57 @@ SQLITE_PRIVATE char *sqlite3VdbeExpandSql(
if( pVar->flags & MEM_Null ){
sqlite3StrAccumAppend(&out, "NULL", 4);
}else if( pVar->flags & MEM_Int ){
- sqlite3XPrintf(&out, "%lld", pVar->u.i);
+ sqlite3XPrintf(&out, 0, "%lld", pVar->u.i);
}else if( pVar->flags & MEM_Real ){
- sqlite3XPrintf(&out, "%!.15g", pVar->r);
+ sqlite3XPrintf(&out, 0, "%!.15g", pVar->u.r);
}else if( pVar->flags & MEM_Str ){
+ int nOut; /* Number of bytes of the string text to include in output */
#ifndef SQLITE_OMIT_UTF16
u8 enc = ENC(db);
+ Mem utf8;
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
+ pVar = &utf8;
+ }
#endif
- {
- sqlite3XPrintf(&out, "'%.*q'", pVar->n, pVar->z);
+ nOut = pVar->n;
+#ifdef SQLITE_TRACE_SIZE_LIMIT
+ if( nOut>SQLITE_TRACE_SIZE_LIMIT ){
+ nOut = SQLITE_TRACE_SIZE_LIMIT;
+ while( nOut<pVar->n && (pVar->z[nOut]&0xc0)==0x80 ){ nOut++; }
}
+#endif
+ sqlite3XPrintf(&out, 0, "'%.*q'", nOut, pVar->z);
+#ifdef SQLITE_TRACE_SIZE_LIMIT
+ if( nOut<pVar->n ){
+ sqlite3XPrintf(&out, 0, "/*+%d bytes*/", pVar->n-nOut);
+ }
+#endif
+#ifndef SQLITE_OMIT_UTF16
+ if( enc!=SQLITE_UTF8 ) sqlite3VdbeMemRelease(&utf8);
+#endif
}else if( pVar->flags & MEM_Zero ){
- sqlite3XPrintf(&out, "zeroblob(%d)", pVar->u.nZero);
+ sqlite3XPrintf(&out, 0, "zeroblob(%d)", pVar->u.nZero);
}else{
+ int nOut; /* Number of bytes of the blob to include in output */
assert( pVar->flags & MEM_Blob );
sqlite3StrAccumAppend(&out, "x'", 2);
- for(i=0; i<pVar->n; i++){
- sqlite3XPrintf(&out, "%02x", pVar->z[i]&0xff);
+ nOut = pVar->n;
+#ifdef SQLITE_TRACE_SIZE_LIMIT
+ if( nOut>SQLITE_TRACE_SIZE_LIMIT ) nOut = SQLITE_TRACE_SIZE_LIMIT;
+#endif
+ for(i=0; i<nOut; i++){
+ sqlite3XPrintf(&out, 0, "%02x", pVar->z[i]&0xff);
}
sqlite3StrAccumAppend(&out, "'", 1);
+#ifdef SQLITE_TRACE_SIZE_LIMIT
+ if( nOut<pVar->n ){
+ sqlite3XPrintf(&out, 0, "/*+%d bytes*/", pVar->n-nOut);
+ }
+#endif
}
}
}
@@ -63277,121 +73623,6 @@ SQLITE_PRIVATE char *sqlite3VdbeExpandSql(
#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 ********************************************/
/*
@@ -63405,33 +73636,8 @@ SQLITE_PRIVATE const char *sqlite3VdbeExplanation(Vdbe *pVdbe){
** 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.
+** The code in this file implements the function that runs the
+** bytecode of a prepared statement.
**
** Various scripts scan this source file in order to generate HTML
** documentation, headers files, or other derived files. The formatting
@@ -63439,11 +73645,17 @@ SQLITE_PRIVATE const char *sqlite3VdbeExplanation(Vdbe *pVdbe){
** in this file for details. If in doubt, do not deviate from existing
** commenting and indentation practices when changing or adding code.
*/
+/* #include "sqliteInt.h" */
+/* #include "vdbeInt.h" */
/*
** Invoke this macro on memory cells just prior to changing the
** value of the cell. This macro verifies that shallow copies are
-** not misused.
+** not misused. A shallow copy of a string or blob just copies a
+** pointer to the string or blob, not the content. If the original
+** is changed while the copy is still in use, the string or blob might
+** be changed out from under the copy. This macro verifies that nothing
+** like that ever happens.
*/
#ifdef SQLITE_DEBUG
# define memAboutToChange(P,M) sqlite3VdbeMemAboutToChange(P,M)
@@ -63502,7 +73714,7 @@ static void updateMaxBlobsize(Mem *p){
#endif
/*
-** The next global variable is incremented each type the OP_Found opcode
+** The next global variable is incremented each time 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
@@ -63523,11 +73735,45 @@ SQLITE_API int sqlite3_found_count = 0;
#endif
/*
+** Invoke the VDBE coverage callback, if that callback is defined. This
+** feature is used for test suite validation only and does not appear an
+** production builds.
+**
+** M is an integer, 2 or 3, that indices how many different ways the
+** branch can go. It is usually 2. "I" is the direction the branch
+** goes. 0 means falls through. 1 means branch is taken. 2 means the
+** second alternative branch is taken.
+**
+** iSrcLine is the source code line (from the __LINE__ macro) that
+** generated the VDBE instruction. This instrumentation assumes that all
+** source code is in a single file (the amalgamation). Special values 1
+** and 2 for the iSrcLine parameter mean that this particular branch is
+** always taken or never taken, respectively.
+*/
+#if !defined(SQLITE_VDBE_COVERAGE)
+# define VdbeBranchTaken(I,M)
+#else
+# define VdbeBranchTaken(I,M) vdbeTakeBranch(pOp->iSrcLine,I,M)
+ static void vdbeTakeBranch(int iSrcLine, u8 I, u8 M){
+ if( iSrcLine<=2 && ALWAYS(iSrcLine>0) ){
+ M = iSrcLine;
+ /* Assert the truth of VdbeCoverageAlwaysTaken() and
+ ** VdbeCoverageNeverTaken() */
+ assert( (M & I)==I );
+ }else{
+ if( sqlite3GlobalConfig.xVdbeBranch==0 ) return; /*NO_TEST*/
+ sqlite3GlobalConfig.xVdbeBranch(sqlite3GlobalConfig.pVdbeBranchArg,
+ iSrcLine,I,M);
+ }
+ }
+#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)) \
+ if(((P)->flags&(MEM_Str|MEM_Blob))==0 && sqlite3VdbeMemStringify(P,enc,0)) \
{ goto no_mem; }
/*
@@ -63539,42 +73785,14 @@ SQLITE_API int sqlite3_found_count = 0;
**
** 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.
+** converts an MEM_Ephem string into a string with P.z==P.zMalloc.
*/
#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;
- }
-}
+#define isSorter(x) ((x)->eCurType==CURTYPE_SORTER)
/*
** Allocate VdbeCursor number iCur. Return a pointer to it. Return NULL
@@ -63585,7 +73803,7 @@ static VdbeCursor *allocateCursor(
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 */
+ u8 eCurType /* Type of the new cursor */
){
/* 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
@@ -63610,27 +73828,25 @@ static VdbeCursor *allocateCursor(
int nByte;
VdbeCursor *pCx = 0;
nByte =
- ROUND8(sizeof(VdbeCursor)) +
- (isBtreeCursor?sqlite3BtreeCursorSize():0) +
- 2*nField*sizeof(u32);
+ ROUND8(sizeof(VdbeCursor)) + 2*sizeof(u32)*nField +
+ (eCurType==CURTYPE_BTREE?sqlite3BtreeCursorSize():0);
assert( iCur<p->nCursor );
if( p->apCsr[iCur] ){
sqlite3VdbeFreeCursor(p, p->apCsr[iCur]);
p->apCsr[iCur] = 0;
}
- if( SQLITE_OK==sqlite3VdbeMemGrow(pMem, nByte, 0) ){
+ if( SQLITE_OK==sqlite3VdbeMemClearAndResize(pMem, nByte) ){
p->apCsr[iCur] = pCx = (VdbeCursor*)pMem->z;
memset(pCx, 0, sizeof(VdbeCursor));
+ pCx->eCurType = eCurType;
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);
+ pCx->aOffset = &pCx->aType[nField];
+ if( eCurType==CURTYPE_BTREE ){
+ pCx->uc.pCursor = (BtCursor*)
+ &pMem->z[ROUND8(sizeof(VdbeCursor))+2*sizeof(u32)*nField];
+ sqlite3BtreeCursorZero(pCx->uc.pCursor);
}
}
return pCx;
@@ -63641,21 +73857,29 @@ static VdbeCursor *allocateCursor(
** 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.
+**
+** If the bTryForInt flag is true, then extra effort is made to give
+** an integer representation. Strings that look like floating point
+** values but which have no fractional component (example: '48.00')
+** will have a MEM_Int representation when bTryForInt is true.
+**
+** If bTryForInt is false, then if the input string contains a decimal
+** point or exponential notation, the result is only MEM_Real, even
+** if there is an exact integer representation of the quantity.
*/
-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;
- }
+static void applyNumericAffinity(Mem *pRec, int bTryForInt){
+ double rValue;
+ i64 iValue;
+ u8 enc = pRec->enc;
+ assert( (pRec->flags & (MEM_Str|MEM_Int|MEM_Real))==MEM_Str );
+ 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->u.r = rValue;
+ pRec->flags |= MEM_Real;
+ if( bTryForInt ) sqlite3VdbeIntegerAffinity(pRec);
}
}
@@ -63674,7 +73898,7 @@ static void applyNumericAffinity(Mem *pRec){
** SQLITE_AFF_TEXT:
** Convert pRec to a text representation.
**
-** SQLITE_AFF_NONE:
+** SQLITE_AFF_BLOB:
** No-op. pRec is unchanged.
*/
static void applyAffinity(
@@ -63682,22 +73906,25 @@ static void applyAffinity(
char affinity, /* The affinity to be applied */
u8 enc /* Use this text encoding */
){
- if( affinity==SQLITE_AFF_TEXT ){
+ if( affinity>=SQLITE_AFF_NUMERIC ){
+ assert( affinity==SQLITE_AFF_INTEGER || affinity==SQLITE_AFF_REAL
+ || affinity==SQLITE_AFF_NUMERIC );
+ if( (pRec->flags & MEM_Int)==0 ){
+ if( (pRec->flags & MEM_Real)==0 ){
+ if( pRec->flags & MEM_Str ) applyNumericAffinity(pRec,1);
+ }else{
+ sqlite3VdbeIntegerAffinity(pRec);
+ }
+ }
+ }else 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);
+ sqlite3VdbeMemStringify(pRec, enc, 1);
}
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);
- }
}
}
@@ -63707,13 +73934,14 @@ static void applyAffinity(
** 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);
+SQLITE_API int SQLITE_STDCALL sqlite3_value_numeric_type(sqlite3_value *pVal){
+ int eType = sqlite3_value_type(pVal);
+ if( eType==SQLITE_TEXT ){
+ Mem *pMem = (Mem*)pVal;
+ applyNumericAffinity(pMem, 0);
+ eType = sqlite3_value_type(pVal);
}
- return pMem->type;
+ return eType;
}
/*
@@ -63728,6 +73956,41 @@ SQLITE_PRIVATE void sqlite3ValueApplyAffinity(
applyAffinity((Mem *)pVal, affinity, enc);
}
+/*
+** pMem currently only holds a string type (or maybe a BLOB that we can
+** interpret as a string if we want to). Compute its corresponding
+** numeric type, if has one. Set the pMem->u.r and pMem->u.i fields
+** accordingly.
+*/
+static u16 SQLITE_NOINLINE computeNumericType(Mem *pMem){
+ assert( (pMem->flags & (MEM_Int|MEM_Real))==0 );
+ assert( (pMem->flags & (MEM_Str|MEM_Blob))!=0 );
+ if( sqlite3AtoF(pMem->z, &pMem->u.r, pMem->n, pMem->enc)==0 ){
+ return 0;
+ }
+ if( sqlite3Atoi64(pMem->z, &pMem->u.i, pMem->n, pMem->enc)==SQLITE_OK ){
+ return MEM_Int;
+ }
+ return MEM_Real;
+}
+
+/*
+** Return the numeric type for pMem, either MEM_Int or MEM_Real or both or
+** none.
+**
+** Unlike applyNumericAffinity(), this routine does not modify pMem->flags.
+** But it does set pMem->u.r and pMem->u.i appropriately.
+*/
+static u16 numericType(Mem *pMem){
+ if( pMem->flags & (MEM_Int|MEM_Real) ){
+ return pMem->flags & (MEM_Int|MEM_Real);
+ }
+ if( pMem->flags & (MEM_Str|MEM_Blob) ){
+ return computeNumericType(pMem);
+ }
+ return 0;
+}
+
#ifdef SQLITE_DEBUG
/*
** Write a nice string representation of the contents of cell pMem
@@ -63815,37 +74078,36 @@ SQLITE_PRIVATE void sqlite3VdbeMemPrettyPrint(Mem *pMem, char *zBuf){
/*
** Print the value of a register for tracing purposes:
*/
-static void memTracePrint(FILE *out, Mem *p){
- if( p->flags & MEM_Invalid ){
- fprintf(out, " undefined");
+static void memTracePrint(Mem *p){
+ if( p->flags & MEM_Undefined ){
+ printf(" undefined");
}else if( p->flags & MEM_Null ){
- fprintf(out, " NULL");
+ printf(" NULL");
}else if( (p->flags & (MEM_Int|MEM_Str))==(MEM_Int|MEM_Str) ){
- fprintf(out, " si:%lld", p->u.i);
+ printf(" si:%lld", p->u.i);
}else if( p->flags & MEM_Int ){
- fprintf(out, " i:%lld", p->u.i);
+ printf(" i:%lld", p->u.i);
#ifndef SQLITE_OMIT_FLOATING_POINT
}else if( p->flags & MEM_Real ){
- fprintf(out, " r:%g", p->r);
+ printf(" r:%g", p->u.r);
#endif
}else if( p->flags & MEM_RowSet ){
- fprintf(out, " (rowset)");
+ printf(" (rowset)");
}else{
char zBuf[200];
sqlite3VdbeMemPrettyPrint(p, zBuf);
- fprintf(out, " ");
- fprintf(out, "%s", zBuf);
+ printf(" %s", zBuf);
}
}
-static void registerTrace(FILE *out, int iReg, Mem *p){
- fprintf(out, "REG[%d] = ", iReg);
- memTracePrint(out, p);
- fprintf(out, "\n");
+static void registerTrace(int iReg, Mem *p){
+ printf("REG[%d] = ", iReg);
+ memTracePrint(p);
+ printf("\n");
}
#endif
#ifdef SQLITE_DEBUG
-# define REGISTER_TRACE(R,M) if(p->trace)registerTrace(p->trace,R,M)
+# define REGISTER_TRACE(R,M) if(db->flags&SQLITE_VdbeTrace)registerTrace(R,M)
#else
# define REGISTER_TRACE(R,M)
#endif
@@ -63950,20 +74212,6 @@ SQLITE_PRIVATE sqlite_uint64 sqlite3Hwtime(void){ return ((sqlite_uint64)0); }
#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
@@ -63985,506 +74233,61 @@ static int checkSavepointCount(sqlite3 *db){
#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).
+** Return the register of pOp->p2 after first preparing it to be
+** overwritten with an integer value.
*/
-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;
+static SQLITE_NOINLINE Mem *out2PrereleaseWithClear(Mem *pOut){
+ sqlite3VdbeMemSetNull(pOut);
+ pOut->flags = MEM_Int;
+ return pOut;
+}
+static Mem *out2Prerelease(Vdbe *p, VdbeOp *pOp){
+ Mem *pOut;
+ assert( pOp->p2>0 );
+ assert( pOp->p2<=(p->nMem-p->nCursor) );
+ pOut = &p->aMem[pOp->p2];
+ memAboutToChange(p, pOut);
+ if( VdbeMemDynamic(pOut) ){
+ return out2PrereleaseWithClear(pOut);
+ }else{
+ pOut->flags = MEM_Int;
+ return pOut;
+ }
}
/*
-** 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.
+** Execute as much of a VDBE program as we can.
+** This is the core of sqlite3_step().
*/
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 */
+ Op *pOp = aOp; /* Current operation */
+#if defined(SQLITE_DEBUG) || defined(VDBE_PROFILE)
+ Op *pOrigOp; /* Value of pOp at the top of the loop */
+#endif
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 */
+ int iCompare = 0; /* Result of last OP_Compare operation */
+ unsigned nVmStep = 0; /* Number of virtual machine steps */
#ifndef SQLITE_OMIT_PROGRESS_CALLBACK
- int checkProgress; /* True if progress callbacks are enabled */
- int nProgressOps = 0; /* Opcodes executed since progress callback. */
+ unsigned nProgressLimit = 0;/* Invoke xProgress() when nVmStep reaches this */
#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
- ********************************************************************/
+ /*** INSERT STACK UNION HERE ***/
assert( p->magic==VDBE_MAGIC_RUN ); /* sqlite3_step() verifies this */
sqlite3VdbeEnter(p);
@@ -64493,46 +74296,65 @@ SQLITE_PRIVATE int sqlite3VdbeExec(
** sqlite3_column_text16() failed. */
goto no_mem;
}
- assert( p->rc==SQLITE_OK || p->rc==SQLITE_BUSY );
+ assert( p->rc==SQLITE_OK || (p->rc&0xff)==SQLITE_BUSY );
+ assert( p->bIsReader || p->readOnly!=0 );
p->rc = SQLITE_OK;
+ p->iCurrentTime = 0;
assert( p->explain==0 );
p->pResultSet = 0;
db->busyHandler.nBusy = 0;
- CHECK_FOR_INTERRUPT;
+ if( db->u1.isInterrupted ) goto abort_due_to_interrupt;
sqlite3VdbeIOTraceSql(p);
#ifndef SQLITE_OMIT_PROGRESS_CALLBACK
- checkProgress = db->xProgress!=0;
+ if( db->xProgress ){
+ u32 iPrior = p->aCounter[SQLITE_STMTSTATUS_VM_STEP];
+ assert( 0 < db->nProgressOps );
+ nProgressLimit = db->nProgressOps - (iPrior % db->nProgressOps);
+ }
#endif
#ifdef SQLITE_DEBUG
sqlite3BeginBenignMalloc();
- if( p->pc==0 && (p->db->flags & SQLITE_VdbeListing)!=0 ){
+ if( p->pc==0
+ && (p->db->flags & (SQLITE_VdbeListing|SQLITE_VdbeEQP|SQLITE_VdbeTrace))!=0
+ ){
int i;
- printf("VDBE Program Listing:\n");
+ int once = 1;
sqlite3VdbePrintSql(p);
- for(i=0; i<p->nOp; i++){
- sqlite3VdbePrintOp(stdout, i, &aOp[i]);
+ if( p->db->flags & SQLITE_VdbeListing ){
+ printf("VDBE Program Listing:\n");
+ for(i=0; i<p->nOp; i++){
+ sqlite3VdbePrintOp(stdout, i, &aOp[i]);
+ }
}
+ if( p->db->flags & SQLITE_VdbeEQP ){
+ for(i=0; i<p->nOp; i++){
+ if( aOp[i].opcode==OP_Explain ){
+ if( once ) printf("VDBE Query Plan:\n");
+ printf("%s\n", aOp[i].p4.z);
+ once = 0;
+ }
+ }
+ }
+ if( p->db->flags & SQLITE_VdbeTrace ) printf("VDBE Trace:\n");
}
sqlite3EndBenignMalloc();
#endif
- for(pc=p->pc; rc==SQLITE_OK; pc++){
- assert( pc>=0 && pc<p->nOp );
+ for(pOp=&aOp[p->pc]; rc==SQLITE_OK; pOp++){
+ assert( pOp>=aOp && pOp<&aOp[p->nOp]);
if( db->mallocFailed ) goto no_mem;
#ifdef VDBE_PROFILE
- origPc = pc;
start = sqlite3Hwtime();
#endif
- pOp = &aOp[pc];
+ nVmStep++;
+#ifdef SQLITE_ENABLE_STMT_SCANSTATUS
+ if( p->anExec ) p->anExec[(int)(pOp-aOp)]++;
+#endif
/* 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);
+ if( db->flags & SQLITE_VdbeTrace ){
+ sqlite3VdbePrintOp(stdout, (int)(pOp - aOp), pOp);
}
#endif
@@ -64549,73 +74371,44 @@ SQLITE_PRIVATE int sqlite3VdbeExec(
}
#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
+ assert( pOp->opflags==sqlite3OpcodeProperty[pOp->opcode] );
if( (pOp->opflags & OPFLG_IN1)!=0 ){
assert( pOp->p1>0 );
- assert( pOp->p1<=p->nMem );
+ assert( pOp->p1<=(p->nMem-p->nCursor) );
assert( memIsValid(&aMem[pOp->p1]) );
+ assert( sqlite3VdbeCheckMemInvariants(&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( pOp->p2<=(p->nMem-p->nCursor) );
assert( memIsValid(&aMem[pOp->p2]) );
+ assert( sqlite3VdbeCheckMemInvariants(&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( pOp->p3<=(p->nMem-p->nCursor) );
assert( memIsValid(&aMem[pOp->p3]) );
+ assert( sqlite3VdbeCheckMemInvariants(&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 );
+ assert( pOp->p2<=(p->nMem-p->nCursor) );
memAboutToChange(p, &aMem[pOp->p2]);
}
if( (pOp->opflags & OPFLG_OUT3)!=0 ){
assert( pOp->p3>0 );
- assert( pOp->p3<=p->nMem );
+ assert( pOp->p3<=(p->nMem-p->nCursor) );
memAboutToChange(p, &aMem[pOp->p3]);
}
#endif
+#if defined(SQLITE_DEBUG) || defined(VDBE_PROFILE)
+ pOrigOp = pOp;
+#endif
switch( pOp->opcode ){
@@ -64639,7 +74432,7 @@ SQLITE_PRIVATE int sqlite3VdbeExec(
**
** 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
+** Keywords include: in1, in2, in3, out2, out3. See
** the mkopcodeh.awk script for additional information.
**
** Documentation about VDBE opcodes is generated by scanning this file
@@ -64660,10 +74453,45 @@ SQLITE_PRIVATE int sqlite3VdbeExec(
** The next instruction executed will be
** the one at index P2 from the beginning of
** the program.
+**
+** The P1 parameter is not actually used by this opcode. However, it
+** is sometimes set to 1 instead of 0 as a hint to the command-line shell
+** that this Goto is the bottom of a loop and that the lines from P2 down
+** to the current line should be indented for EXPLAIN output.
*/
case OP_Goto: { /* jump */
- CHECK_FOR_INTERRUPT;
- pc = pOp->p2 - 1;
+jump_to_p2_and_check_for_interrupt:
+ pOp = &aOp[pOp->p2 - 1];
+
+ /* Opcodes that are used as the bottom of a loop (OP_Next, OP_Prev,
+ ** OP_VNext, OP_RowSetNext, or OP_SorterNext) all jump here upon
+ ** completion. Check to see if sqlite3_interrupt() has been called
+ ** or if the progress callback needs to be invoked.
+ **
+ ** This code uses unstructured "goto" statements and does not look clean.
+ ** But that is not due to sloppy coding habits. The code is written this
+ ** way for performance, to avoid having to run the interrupt and progress
+ ** checks on every opcode. This helps sqlite3_step() to run about 1.5%
+ ** faster according to "valgrind --tool=cachegrind" */
+check_for_interrupt:
+ if( db->u1.isInterrupted ) goto abort_due_to_interrupt;
+#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( db->xProgress!=0 && nVmStep>=nProgressLimit ){
+ assert( db->nProgressOps!=0 );
+ nProgressLimit = nVmStep + db->nProgressOps - (nVmStep%db->nProgressOps);
+ if( db->xProgress(db->pProgressArg) ){
+ rc = SQLITE_INTERRUPT;
+ goto vdbe_error_halt;
+ }
+ }
+#endif
+
break;
}
@@ -64673,51 +74501,110 @@ case OP_Goto: { /* jump */
** and then jump to address P2.
*/
case OP_Gosub: { /* jump */
- assert( pOp->p1>0 && pOp->p1<=p->nMem );
+ assert( pOp->p1>0 && pOp->p1<=(p->nMem-p->nCursor) );
pIn1 = &aMem[pOp->p1];
- assert( (pIn1->flags & MEM_Dyn)==0 );
+ assert( VdbeMemDynamic(pIn1)==0 );
memAboutToChange(p, pIn1);
pIn1->flags = MEM_Int;
- pIn1->u.i = pc;
+ pIn1->u.i = (int)(pOp-aOp);
REGISTER_TRACE(pOp->p1, pIn1);
- pc = pOp->p2 - 1;
+
+ /* Most jump operations do a goto to this spot in order to update
+ ** the pOp pointer. */
+jump_to_p2:
+ pOp = &aOp[pOp->p2 - 1];
break;
}
/* Opcode: Return P1 * * * *
**
-** Jump to the next instruction after the address in register P1.
+** Jump to the next instruction after the address in register P1. After
+** the jump, register P1 becomes undefined.
*/
case OP_Return: { /* in1 */
pIn1 = &aMem[pOp->p1];
- assert( pIn1->flags & MEM_Int );
- pc = (int)pIn1->u.i;
+ assert( pIn1->flags==MEM_Int );
+ pOp = &aOp[pIn1->u.i];
+ pIn1->flags = MEM_Undefined;
break;
}
-/* Opcode: Yield P1 * * * *
+/* Opcode: InitCoroutine P1 P2 P3 * *
+**
+** Set up register P1 so that it will Yield to the coroutine
+** located at address P3.
+**
+** If P2!=0 then the coroutine implementation immediately follows
+** this opcode. So jump over the coroutine implementation to
+** address P2.
+**
+** See also: EndCoroutine
+*/
+case OP_InitCoroutine: { /* jump */
+ assert( pOp->p1>0 && pOp->p1<=(p->nMem-p->nCursor) );
+ assert( pOp->p2>=0 && pOp->p2<p->nOp );
+ assert( pOp->p3>=0 && pOp->p3<p->nOp );
+ pOut = &aMem[pOp->p1];
+ assert( !VdbeMemDynamic(pOut) );
+ pOut->u.i = pOp->p3 - 1;
+ pOut->flags = MEM_Int;
+ if( pOp->p2 ) goto jump_to_p2;
+ break;
+}
+
+/* Opcode: EndCoroutine P1 * * * *
+**
+** The instruction at the address in register P1 is a Yield.
+** Jump to the P2 parameter of that Yield.
+** After the jump, register P1 becomes undefined.
+**
+** See also: InitCoroutine
+*/
+case OP_EndCoroutine: { /* in1 */
+ VdbeOp *pCaller;
+ pIn1 = &aMem[pOp->p1];
+ assert( pIn1->flags==MEM_Int );
+ assert( pIn1->u.i>=0 && pIn1->u.i<p->nOp );
+ pCaller = &aOp[pIn1->u.i];
+ assert( pCaller->opcode==OP_Yield );
+ assert( pCaller->p2>=0 && pCaller->p2<p->nOp );
+ pOp = &aOp[pCaller->p2 - 1];
+ pIn1->flags = MEM_Undefined;
+ break;
+}
+
+/* Opcode: Yield P1 P2 * * *
+**
+** Swap the program counter with the value in register P1. This
+** has the effect of yielding to a coroutine.
**
-** Swap the program counter with the value in register P1.
+** If the coroutine that is launched by this instruction ends with
+** Yield or Return then continue to the next instruction. But if
+** the coroutine launched by this instruction ends with
+** EndCoroutine, then jump to P2 rather than continuing with the
+** next instruction.
+**
+** See also: InitCoroutine
*/
-case OP_Yield: { /* in1 */
-#if 0 /* local variables moved into u.aa */
+case OP_Yield: { /* in1, jump */
int pcDest;
-#endif /* local variables moved into u.aa */
pIn1 = &aMem[pOp->p1];
- assert( (pIn1->flags & MEM_Dyn)==0 );
+ assert( VdbeMemDynamic(pIn1)==0 );
pIn1->flags = MEM_Int;
- u.aa.pcDest = (int)pIn1->u.i;
- pIn1->u.i = pc;
+ pcDest = (int)pIn1->u.i;
+ pIn1->u.i = (int)(pOp - aOp);
REGISTER_TRACE(pOp->p1, pIn1);
- pc = u.aa.pcDest;
+ pOp = &aOp[pcDest];
break;
}
-/* Opcode: HaltIfNull P1 P2 P3 P4 *
+/* Opcode: HaltIfNull P1 P2 P3 P4 P5
+** Synopsis: if r[P3]=null halt
**
** 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.
+** The P5 parameter should be 1.
*/
case OP_HaltIfNull: { /* in3 */
pIn3 = &aMem[pOp->p3];
@@ -64725,7 +74612,7 @@ case OP_HaltIfNull: { /* in3 */
/* Fall through into OP_Halt */
}
-/* Opcode: Halt P1 P2 * P4 *
+/* Opcode: Halt P1 P2 * P4 P5
**
** Exit immediately. All open cursors, etc are closed
** automatically.
@@ -64740,71 +74627,107 @@ case OP_HaltIfNull: { /* in3 */
**
** If P4 is not null then it is an error message string.
**
+** P5 is a value between 0 and 4, inclusive, that modifies the P4 string.
+**
+** 0: (no change)
+** 1: NOT NULL contraint failed: P4
+** 2: UNIQUE constraint failed: P4
+** 3: CHECK constraint failed: P4
+** 4: FOREIGN KEY constraint failed: P4
+**
+** If P5 is not zero and P4 is NULL, then everything after the ":" is
+** omitted.
+**
** 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: {
+ const char *zType;
+ const char *zLogFmt;
+ VdbeFrame *pFrame;
+ int pcx;
+
+ pcx = (int)(pOp - aOp);
if( pOp->p1==SQLITE_OK && p->pFrame ){
/* Halt the sub-program. Return control to the parent frame. */
- VdbeFrame *pFrame = p->pFrame;
+ pFrame = p->pFrame;
p->pFrame = pFrame->pParent;
p->nFrame--;
sqlite3VdbeSetChanges(db, p->nChange);
- pc = sqlite3VdbeFrameRestore(pFrame);
+ pcx = sqlite3VdbeFrameRestore(pFrame);
lastRowid = db->lastRowid;
if( pOp->p2==OE_Ignore ){
- /* Instruction pc is the OP_Program that invoked the sub-program
+ /* Instruction pcx 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;
+ pcx = p->aOp[pcx].p2-1;
}
aOp = p->aOp;
aMem = p->aMem;
+ pOp = &aOp[pcx];
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);
+ p->pc = pcx;
+ if( p->rc ){
+ if( pOp->p5 ){
+ static const char * const azType[] = { "NOT NULL", "UNIQUE", "CHECK",
+ "FOREIGN KEY" };
+ assert( pOp->p5>=1 && pOp->p5<=4 );
+ testcase( pOp->p5==1 );
+ testcase( pOp->p5==2 );
+ testcase( pOp->p5==3 );
+ testcase( pOp->p5==4 );
+ zType = azType[pOp->p5-1];
+ }else{
+ zType = 0;
+ }
+ assert( zType!=0 || pOp->p4.z!=0 );
+ zLogFmt = "abort at %d in [%s]: %s";
+ if( zType && pOp->p4.z ){
+ sqlite3VdbeError(p, "%s constraint failed: %s", zType, pOp->p4.z);
+ }else if( pOp->p4.z ){
+ sqlite3VdbeError(p, "%s", pOp->p4.z);
+ }else{
+ sqlite3VdbeError(p, "%s constraint failed", zType);
+ }
+ sqlite3_log(pOp->p1, zLogFmt, pcx, p->zSql, p->zErrMsg);
}
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 );
+ assert( rc==SQLITE_OK || (p->rc&0xff)==SQLITE_CONSTRAINT );
+ assert( rc==SQLITE_OK || db->nDeferredCons>0 || db->nDeferredImmCons>0 );
rc = p->rc ? SQLITE_ERROR : SQLITE_DONE;
}
goto vdbe_return;
}
/* Opcode: Integer P1 P2 * * *
+** Synopsis: r[P2]=P1
**
** The 32-bit integer value P1 is written into register P2.
*/
-case OP_Integer: { /* out2-prerelease */
+case OP_Integer: { /* out2 */
+ pOut = out2Prerelease(p, pOp);
pOut->u.i = pOp->p1;
break;
}
/* Opcode: Int64 * P2 * P4 *
+** Synopsis: r[P2]=P4
**
** P4 is a pointer to a 64-bit integer value.
** Write that value into register P2.
*/
-case OP_Int64: { /* out2-prerelease */
+case OP_Int64: { /* out2 */
+ pOut = out2Prerelease(p, pOp);
assert( pOp->p4.pI64!=0 );
pOut->u.i = *pOp->p4.pI64;
break;
@@ -64812,25 +74735,31 @@ case OP_Int64: { /* out2-prerelease */
#ifndef SQLITE_OMIT_FLOATING_POINT
/* Opcode: Real * P2 * P4 *
+** Synopsis: r[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 */
+case OP_Real: { /* same as TK_FLOAT, out2 */
+ pOut = out2Prerelease(p, pOp);
pOut->flags = MEM_Real;
assert( !sqlite3IsNaN(*pOp->p4.pReal) );
- pOut->r = *pOp->p4.pReal;
+ pOut->u.r = *pOp->p4.pReal;
break;
}
#endif
/* Opcode: String8 * P2 * P4 *
+** Synopsis: r[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.
+** into a String opcode before it is executed for the first time. During
+** this transformation, the length of string P4 is computed and stored
+** as the P1 parameter.
*/
-case OP_String8: { /* same as TK_STRING, out2-prerelease */
+case OP_String8: { /* same as TK_STRING, out2 */
assert( pOp->p4.z!=0 );
+ pOut = out2Prerelease(p, pOp);
pOp->opcode = OP_String;
pOp->p1 = sqlite3Strlen30(pOp->p4.z);
@@ -64839,11 +74768,10 @@ case OP_String8: { /* same as TK_STRING, out2-prerelease */
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;
+ assert( pOut->szMalloc>0 && pOut->zMalloc==pOut->z );
+ assert( VdbeMemDynamic(pOut)==0 );
+ pOut->szMalloc = 0;
pOut->flags |= MEM_Static;
- pOut->flags &= ~MEM_Dyn;
if( pOp->p4type==P4_DYNAMIC ){
sqlite3DbFree(db, pOp->p4.z);
}
@@ -64858,21 +74786,38 @@ case OP_String8: { /* same as TK_STRING, out2-prerelease */
/* Fall through to the next case, OP_String */
}
-/* Opcode: String P1 P2 * P4 *
+/* Opcode: String P1 P2 P3 P4 P5
+** Synopsis: r[P2]='P4' (len=P1)
**
** The string value P4 of length P1 (bytes) is stored in register P2.
+**
+** If P5!=0 and the content of register P3 is greater than zero, then
+** the datatype of the register P2 is converted to BLOB. The content is
+** the same sequence of bytes, it is merely interpreted as a BLOB instead
+** of a string, as if it had been CAST.
*/
-case OP_String: { /* out2-prerelease */
+case OP_String: { /* out2 */
assert( pOp->p4.z!=0 );
+ pOut = out2Prerelease(p, pOp);
pOut->flags = MEM_Str|MEM_Static|MEM_Term;
pOut->z = pOp->p4.z;
pOut->n = pOp->p1;
pOut->enc = encoding;
UPDATE_MAX_BLOBSIZE(pOut);
+#ifndef SQLITE_LIKE_DOESNT_MATCH_BLOBS
+ if( pOp->p5 ){
+ assert( pOp->p3>0 );
+ assert( pOp->p3<=(p->nMem-p->nCursor) );
+ pIn3 = &aMem[pOp->p3];
+ assert( pIn3->flags & MEM_Int );
+ if( pIn3->u.i ) pOut->flags = MEM_Blob|MEM_Static|MEM_Term;
+ }
+#endif
break;
}
/* Opcode: Null P1 P2 P3 * *
+** Synopsis: r[P2..P3]=NULL
**
** 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
@@ -64883,32 +74828,47 @@ case OP_String: { /* out2-prerelease */
** 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 */
+case OP_Null: { /* out2 */
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 = out2Prerelease(p, pOp);
+ cnt = pOp->p3-pOp->p2;
+ assert( pOp->p3<=(p->nMem-p->nCursor) );
+ pOut->flags = nullFlag = pOp->p1 ? (MEM_Null|MEM_Cleared) : MEM_Null;
+ while( cnt>0 ){
pOut++;
memAboutToChange(p, pOut);
- VdbeMemRelease(pOut);
- pOut->flags = u.ab.nullFlag;
- u.ab.cnt--;
+ sqlite3VdbeMemSetNull(pOut);
+ pOut->flags = nullFlag;
+ cnt--;
}
break;
}
+/* Opcode: SoftNull P1 * * * *
+** Synopsis: r[P1]=NULL
+**
+** Set register P1 to have the value NULL as seen by the OP_MakeRecord
+** instruction, but do not free any string or blob memory associated with
+** the register, so that if the value was a string or blob that was
+** previously copied using OP_SCopy, the copies will continue to be valid.
+*/
+case OP_SoftNull: {
+ assert( pOp->p1>0 && pOp->p1<=(p->nMem-p->nCursor) );
+ pOut = &aMem[pOp->p1];
+ pOut->flags = (pOut->flags|MEM_Null)&~MEM_Undefined;
+ break;
+}
-/* Opcode: Blob P1 P2 * P4
+/* Opcode: Blob P1 P2 * P4 *
+** Synopsis: r[P2]=P4 (len=P1)
**
** P4 points to a blob of data P1 bytes long. Store this
** blob in register P2.
*/
-case OP_Blob: { /* out2-prerelease */
+case OP_Blob: { /* out2 */
assert( pOp->p1 <= SQLITE_MAX_LENGTH );
+ pOut = out2Prerelease(p, pOp);
sqlite3VdbeMemSetStr(pOut, pOp->p4.z, pOp->p1, 0, 0);
pOut->enc = encoding;
UPDATE_MAX_BLOBSIZE(pOut);
@@ -64916,73 +74876,71 @@ case OP_Blob: { /* out2-prerelease */
}
/* Opcode: Variable P1 P2 * P4 *
+** Synopsis: r[P2]=parameter(P1,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.
+** If the parameter is named, then its name appears in P4.
** The P4 value is used by sqlite3_bind_parameter_name().
*/
-case OP_Variable: { /* out2-prerelease */
-#if 0 /* local variables moved into u.ac */
+case OP_Variable: { /* out2 */
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) ){
+ pVar = &p->aVar[pOp->p1 - 1];
+ if( sqlite3VdbeMemTooBig(pVar) ){
goto too_big;
}
- sqlite3VdbeMemShallowCopy(pOut, u.ac.pVar, MEM_Static);
+ pOut = out2Prerelease(p, pOp);
+ sqlite3VdbeMemShallowCopy(pOut, pVar, MEM_Static);
UPDATE_MAX_BLOBSIZE(pOut);
break;
}
/* Opcode: Move P1 P2 P3 * *
+** Synopsis: r[P2@P3]=r[P1@P3]
**
-** Move the values in register P1..P1+P3 over into
-** registers P2..P2+P3. Registers P1..P1+P3 are
+** Move the P3 values in register P1..P1+P3-1 over into
+** registers P2..P2+P3-1. Registers P1..P1+P3-1 are
** left holding a NULL. It is an error for register ranges
-** P1..P1+P3 and P2..P2+P3 to overlap.
+** P1..P1+P3-1 and P2..P2+P3-1 to overlap. It is an error
+** for P3 to be less than 1.
*/
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] );
+
+ n = pOp->p3;
+ p1 = pOp->p1;
+ p2 = pOp->p2;
+ assert( n>0 && p1>0 && p2>0 );
+ assert( p1+n<=p2 || p2+n<=p1 );
+
+ pIn1 = &aMem[p1];
+ pOut = &aMem[p2];
+ do{
+ assert( pOut<=&aMem[(p->nMem-p->nCursor)] );
+ assert( pIn1<=&aMem[(p->nMem-p->nCursor)] );
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;
+ if( pOut->pScopyFrom>=&aMem[p1] && pOut->pScopyFrom<pOut ){
+ pOut->pScopyFrom += pOp->p2 - p1;
}
#endif
- pIn1->zMalloc = u.ad.zMalloc;
- REGISTER_TRACE(u.ad.p2++, pOut);
+ Deephemeralize(pOut);
+ REGISTER_TRACE(p2++, pOut);
pIn1++;
pOut++;
- }
+ }while( --n );
break;
}
/* Opcode: Copy P1 P2 P3 * *
+** Synopsis: r[P2@P3+1]=r[P1@P3+1]
**
** Make a copy of registers P1..P1+P3 into registers P2..P2+P3.
**
@@ -64990,11 +74948,9 @@ case OP_Move: {
** 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;
+ n = pOp->p3;
pIn1 = &aMem[pOp->p1];
pOut = &aMem[pOp->p2];
assert( pOut!=pIn1 );
@@ -65004,8 +74960,8 @@ case OP_Copy: {
#ifdef SQLITE_DEBUG
pOut->pScopyFrom = 0;
#endif
- REGISTER_TRACE(pOp->p2+pOp->p3-u.ae.n, pOut);
- if( (u.ae.n--)==0 ) break;
+ REGISTER_TRACE(pOp->p2+pOp->p3-n, pOut);
+ if( (n--)==0 ) break;
pOut++;
pIn1++;
}
@@ -65013,6 +74969,7 @@ case OP_Copy: {
}
/* Opcode: SCopy P1 P2 * * *
+** Synopsis: r[P2]=r[P1]
**
** Make a shallow copy of register P1 into register P2.
**
@@ -65024,7 +74981,7 @@ case OP_Copy: {
** during the lifetime of the copy. Use OP_Copy to make a complete
** copy.
*/
-case OP_SCopy: { /* in1, out2 */
+case OP_SCopy: { /* out2 */
pIn1 = &aMem[pOp->p1];
pOut = &aMem[pOp->p2];
assert( pOut!=pIn1 );
@@ -65032,26 +74989,52 @@ case OP_SCopy: { /* in1, out2 */
#ifdef SQLITE_DEBUG
if( pOut->pScopyFrom==0 ) pOut->pScopyFrom = pIn1;
#endif
- REGISTER_TRACE(pOp->p2, pOut);
+ break;
+}
+
+/* Opcode: IntCopy P1 P2 * * *
+** Synopsis: r[P2]=r[P1]
+**
+** Transfer the integer value held in register P1 into register P2.
+**
+** This is an optimized version of SCopy that works only for integer
+** values.
+*/
+case OP_IntCopy: { /* out2 */
+ pIn1 = &aMem[pOp->p1];
+ assert( (pIn1->flags & MEM_Int)!=0 );
+ pOut = &aMem[pOp->p2];
+ sqlite3VdbeMemSetInt64(pOut, pIn1->u.i);
break;
}
/* Opcode: ResultRow P1 P2 * * *
+** Synopsis: output=r[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.
+** structure to provide access to the r(P1)..r(P1+P2-1) 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 );
+ assert( pOp->p1+pOp->p2<=(p->nMem-p->nCursor)+1 );
+
+#ifndef SQLITE_OMIT_PROGRESS_CALLBACK
+ /* Run the progress counter just before returning.
+ */
+ if( db->xProgress!=0
+ && nVmStep>=nProgressLimit
+ && db->xProgress(db->pProgressArg)!=0
+ ){
+ rc = SQLITE_INTERRUPT;
+ goto vdbe_error_halt;
+ }
+#endif
/* If this statement has violated immediate foreign key constraints, do
** not return the number of rows modified. And do not RELEASE the statement
@@ -65062,8 +75045,8 @@ case OP_ResultRow: {
break;
}
- /* If the SQLITE_CountRows flag is set in sqlite3.flags mask, then
- ** DML statements invoke this opcode to return the number of rows
+ /* 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.
**
@@ -65090,26 +75073,26 @@ case OP_ResultRow: {
** 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]);
+ pMem = p->pResultSet = &aMem[pOp->p1];
+ for(i=0; i<pOp->p2; i++){
+ assert( memIsValid(&pMem[i]) );
+ Deephemeralize(&pMem[i]);
+ assert( (pMem[i].flags & MEM_Ephem)==0
+ || (pMem[i].flags & (MEM_Str|MEM_Blob))==0 );
+ sqlite3VdbeMemNulTerminate(&pMem[i]);
+ REGISTER_TRACE(pOp->p1+i, &pMem[i]);
}
if( db->mallocFailed ) goto no_mem;
/* Return SQLITE_ROW
*/
- p->pc = pc + 1;
+ p->pc = (int)(pOp - aOp) + 1;
rc = SQLITE_ROW;
goto vdbe_return;
}
/* Opcode: Concat P1 P2 P3 * *
+** Synopsis: r[P3]=r[P2]+r[P1]
**
** Add the text in register P1 onto the end of the text in
** register P2 and store the result in register P3.
@@ -65122,9 +75105,7 @@ case OP_ResultRow: {
** 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];
@@ -65137,34 +75118,36 @@ case OP_Concat: { /* same as TK_CONCAT, in1, in2, out3 */
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] ){
+ nByte = pIn1->n + pIn2->n;
+ if( nByte>db->aLimit[SQLITE_LIMIT_LENGTH] ){
goto too_big;
}
- MemSetTypeFlag(pOut, MEM_Str);
- if( sqlite3VdbeMemGrow(pOut, (int)u.ag.nByte+2, pOut==pIn2) ){
+ if( sqlite3VdbeMemGrow(pOut, (int)nByte+2, pOut==pIn2) ){
goto no_mem;
}
+ MemSetTypeFlag(pOut, MEM_Str);
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->z[nByte]=0;
+ pOut->z[nByte+1] = 0;
pOut->flags |= MEM_Term;
- pOut->n = (int)u.ag.nByte;
+ pOut->n = (int)nByte;
pOut->enc = encoding;
UPDATE_MAX_BLOBSIZE(pOut);
break;
}
/* Opcode: Add P1 P2 P3 * *
+** Synopsis: r[P3]=r[P1]+r[P2]
**
** 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 * *
+** Synopsis: r[P3]=r[P1]*r[P2]
**
**
** Multiply the value in register P1 by the value in register P2
@@ -65172,12 +75155,14 @@ case OP_Concat: { /* same as TK_CONCAT, in1, in2, out3 */
** If either input is NULL, the result is NULL.
*/
/* Opcode: Subtract P1 P2 P3 * *
+** Synopsis: r[P3]=r[P2]-r[P1]
**
** 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 * *
+** Synopsis: r[P3]=r[P2]/r[P1]
**
** 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
@@ -65185,10 +75170,11 @@ case OP_Concat: { /* same as TK_CONCAT, in1, in2, out3 */
** NULL, the result is NULL.
*/
/* Opcode: Remainder P1 P2 P3 * *
+** Synopsis: r[P3]=r[P2]%r[P1]
**
-** 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.
+** Compute the remainder after integer register P2 is divided by
+** register P1 and store the result in register P3.
+** If the value in register P1 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 */
@@ -65196,79 +75182,79 @@ 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 */
+ u16 flags; /* Combined MEM_* flags from both inputs */
+ u16 type1; /* Numeric type of left operand */
+ u16 type2; /* Numeric type of right operand */
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);
+ type1 = numericType(pIn1);
pIn2 = &aMem[pOp->p2];
- applyNumericAffinity(pIn2);
+ type2 = numericType(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;
+ flags = pIn1->flags | pIn2->flags;
+ if( (flags & MEM_Null)!=0 ) goto arithmetic_result_is_null;
+ if( (type1 & type2 & MEM_Int)!=0 ){
+ iA = pIn1->u.i;
+ iB = pIn2->u.i;
+ 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_Add: if( sqlite3AddInt64(&iB,iA) ) goto fp_math; break;
+ case OP_Subtract: if( sqlite3SubInt64(&iB,iA) ) goto fp_math; break;
+ case OP_Multiply: if( sqlite3MulInt64(&iB,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;
+ if( iA==0 ) goto arithmetic_result_is_null;
+ if( iA==-1 && iB==SMALLEST_INT64 ) goto fp_math;
+ iB /= 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;
+ if( iA==0 ) goto arithmetic_result_is_null;
+ if( iA==-1 ) iA = 1;
+ iB %= iA;
break;
}
}
- pOut->u.i = u.ah.iB;
+ pOut->u.i = iB;
MemSetTypeFlag(pOut, MEM_Int);
}else{
- u.ah.bIntint = 0;
+ bIntint = 0;
fp_math:
- u.ah.rA = sqlite3VdbeRealValue(pIn1);
- u.ah.rB = sqlite3VdbeRealValue(pIn2);
+ rA = sqlite3VdbeRealValue(pIn1);
+ 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_Add: rB += rA; break;
+ case OP_Subtract: rB -= rA; break;
+ case OP_Multiply: rB *= 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;
+ if( rA==(double)0 ) goto arithmetic_result_is_null;
+ rB /= 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);
+ iA = (i64)rA;
+ iB = (i64)rB;
+ if( iA==0 ) goto arithmetic_result_is_null;
+ if( iA==-1 ) iA = 1;
+ rB = (double)(iB % iA);
break;
}
}
#ifdef SQLITE_OMIT_FLOATING_POINT
- pOut->u.i = u.ah.rB;
+ pOut->u.i = rB;
MemSetTypeFlag(pOut, MEM_Int);
#else
- if( sqlite3IsNaN(u.ah.rB) ){
+ if( sqlite3IsNaN(rB) ){
goto arithmetic_result_is_null;
}
- pOut->r = u.ah.rB;
+ pOut->u.r = rB;
MemSetTypeFlag(pOut, MEM_Real);
- if( (u.ah.flags & MEM_Real)==0 && !u.ah.bIntint ){
+ if( ((type1|type2)&MEM_Real)==0 && !bIntint ){
sqlite3VdbeIntegerAffinity(pOut);
}
#endif
@@ -65293,7 +75279,7 @@ arithmetic_result_is_null:
**
** 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.
+** publicly. Only built-in functions have access to this feature.
*/
case OP_CollSeq: {
assert( pOp->p4type==P4_COLLSEQ );
@@ -65303,9 +75289,10 @@ case OP_CollSeq: {
break;
}
-/* Opcode: Function P1 P2 P3 P4 P5
+/* Opcode: Function0 P1 P2 P3 P4 P5
+** Synopsis: r[P3]=func(r[P2@P5])
**
-** Invoke a user function (P4 is a pointer to a Function structure that
+** Invoke a user function (P4 is a pointer to a FuncDef object 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.
@@ -65317,125 +75304,119 @@ case OP_CollSeq: {
** sqlite3_set_auxdata() API may be safely retained until the next
** invocation of this opcode.
**
-** See also: AggStep and AggFinal
+** See also: Function, AggStep, AggFinal
+*/
+/* Opcode: Function P1 P2 P3 P4 P5
+** Synopsis: r[P3]=func(r[P2@P5])
+**
+** Invoke a user function (P4 is a pointer to an sqlite3_context object that
+** contains a pointer to the function to be run) 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.
+**
+** SQL functions are initially coded as OP_Function0 with P4 pointing
+** to a FuncDef object. But on first evaluation, the P4 operand is
+** automatically converted into an sqlite3_context object and the operation
+** changed to this OP_Function opcode. In this way, the initialization of
+** the sqlite3_context object occurs only once, rather than once for each
+** evaluation of the function.
+**
+** See also: Function0, AggStep, AggFinal
*/
+case OP_Function0: {
+ int n;
+ sqlite3_context *pCtx;
+
+ assert( pOp->p4type==P4_FUNCDEF );
+ n = pOp->p5;
+ assert( pOp->p3>0 && pOp->p3<=(p->nMem-p->nCursor) );
+ assert( n==0 || (pOp->p2>0 && pOp->p2+n<=(p->nMem-p->nCursor)+1) );
+ assert( pOp->p3<pOp->p2 || pOp->p3>=pOp->p2+n );
+ pCtx = sqlite3DbMallocRaw(db, sizeof(*pCtx) + (n-1)*sizeof(sqlite3_value*));
+ if( pCtx==0 ) goto no_mem;
+ pCtx->pOut = 0;
+ pCtx->pFunc = pOp->p4.pFunc;
+ pCtx->iOp = (int)(pOp - aOp);
+ pCtx->pVdbe = p;
+ pCtx->argc = n;
+ pOp->p4type = P4_FUNCCTX;
+ pOp->p4.pCtx = pCtx;
+ pOp->opcode = OP_Function;
+ /* Fall through into OP_Function */
+}
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 */
+ sqlite3_context *pCtx;
- 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( pOp->p4type==P4_FUNCCTX );
+ pCtx = pOp->p4.pCtx;
- 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;
+ /* If this function is inside of a trigger, the register array in aMem[]
+ ** might change from one evaluation to the next. The next block of code
+ ** checks to see if the register array has changed, and if so it
+ ** reinitializes the relavant parts of the sqlite3_context object */
+ pOut = &aMem[pOp->p3];
+ if( pCtx->pOut != pOut ){
+ pCtx->pOut = pOut;
+ for(i=pCtx->argc-1; i>=0; i--) pCtx->argv[i] = &aMem[pOp->p2+i];
}
- 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;
+ memAboutToChange(p, pCtx->pOut);
+#ifdef SQLITE_DEBUG
+ for(i=0; i<pCtx->argc; i++){
+ assert( memIsValid(pCtx->argv[i]) );
+ REGISTER_TRACE(pOp->p2+i, pCtx->argv[i]);
}
+#endif
+ MemSetTypeFlag(pCtx->pOut, MEM_Null);
+ pCtx->fErrorOrAux = 0;
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;
- }
+ (*pCtx->pFunc->xFunc)(pCtx, pCtx->argc, pCtx->argv); /* IMP: R-24505-23230 */
+ lastRowid = db->lastRowid; /* Remember rowid changes made by xFunc */
/* 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;
+ if( pCtx->fErrorOrAux ){
+ if( pCtx->isError ){
+ sqlite3VdbeError(p, "%s", sqlite3_value_text(pCtx->pOut));
+ rc = pCtx->isError;
+ }
+ sqlite3VdbeDeleteAuxData(p, pCtx->iOp, pOp->p1);
}
/* 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( pOut->flags & (MEM_Str|MEM_Blob) ){
+ sqlite3VdbeChangeEncoding(pCtx->pOut, encoding);
+ if( sqlite3VdbeMemTooBig(pCtx->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);
+ REGISTER_TRACE(pOp->p3, pCtx->pOut);
+ UPDATE_MAX_BLOBSIZE(pCtx->pOut);
break;
}
/* Opcode: BitAnd P1 P2 P3 * *
+** Synopsis: r[P3]=r[P1]&r[P2]
**
** 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 * *
+** Synopsis: r[P3]=r[P1]|r[P2]
**
** 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 * *
+** Synopsis: r[P3]=r[P2]<<r[P1]
**
** Shift the integer value in register P2 to the left by the
** number of bits specified by the integer in register P1.
@@ -65443,6 +75424,7 @@ case OP_Function: {
** If either input is NULL, the result is NULL.
*/
/* Opcode: ShiftRight P1 P2 P3 * *
+** Synopsis: r[P3]=r[P2]>>r[P1]
**
** Shift the integer value in register P2 to the right by the
** number of bits specified by the integer in register P1.
@@ -65453,12 +75435,10 @@ 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];
@@ -65467,43 +75447,44 @@ case OP_ShiftRight: { /* same as TK_RSHIFT, in1, in2, out3 */
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 );
+ iA = sqlite3VdbeIntValue(pIn2);
+ iB = sqlite3VdbeIntValue(pIn1);
+ op = pOp->opcode;
+ if( op==OP_BitAnd ){
+ iA &= iB;
+ }else if( op==OP_BitOr ){
+ iA |= iB;
+ }else if( iB!=0 ){
+ assert( op==OP_ShiftRight || op==OP_ShiftLeft );
/* If shifting by a negative amount, shift in the other direction */
- if( u.aj.iB<0 ){
+ if( 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;
+ op = 2*OP_ShiftLeft + 1 - op;
+ iB = iB>(-64) ? -iB : 64;
}
- if( u.aj.iB>=64 ){
- u.aj.iA = (u.aj.iA>=0 || u.aj.op==OP_ShiftLeft) ? 0 : -1;
+ if( iB>=64 ){
+ iA = (iA>=0 || 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;
+ memcpy(&uA, &iA, sizeof(uA));
+ if( op==OP_ShiftLeft ){
+ uA <<= iB;
}else{
- u.aj.uA >>= u.aj.iB;
+ uA >>= 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);
+ if( iA<0 ) uA |= ((((u64)0xffffffff)<<32)|0xffffffff) << (64-iB);
}
- memcpy(&u.aj.iA, &u.aj.uA, sizeof(u.aj.iA));
+ memcpy(&iA, &uA, sizeof(iA));
}
}
- pOut->u.i = u.aj.iA;
+ pOut->u.i = iA;
MemSetTypeFlag(pOut, MEM_Int);
break;
}
/* Opcode: AddImm P1 P2 * * *
+** Synopsis: r[P1]=r[P1]+P2
**
** Add the constant P2 to the value in register P1.
** The result is always an integer.
@@ -65527,17 +75508,19 @@ case OP_AddImm: { /* in1 */
*/
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;
+ applyAffinity(pIn1, SQLITE_AFF_NUMERIC, encoding);
+ VdbeBranchTaken((pIn1->flags&MEM_Int)==0, 2);
+ if( (pIn1->flags & MEM_Int)==0 ){
+ if( pOp->p2==0 ){
+ rc = SQLITE_MISMATCH;
+ goto abort_due_to_error;
+ }else{
+ goto jump_to_p2;
+ }
}
- }else{
- MemSetTypeFlag(pIn1, MEM_Int);
}
+ MemSetTypeFlag(pIn1, MEM_Int);
break;
}
@@ -65561,107 +75544,39 @@ case OP_RealAffinity: { /* in1 */
#endif
#ifndef SQLITE_OMIT_CAST
-/* Opcode: ToText P1 * * * *
+/* Opcode: Cast P1 P2 * * *
+** Synopsis: affinity(r[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.
+** Force the value in register P1 to be the type defined by P2.
+**
+** <ul>
+** <li value="97"> TEXT
+** <li value="98"> BLOB
+** <li value="99"> NUMERIC
+** <li value="100"> INTEGER
+** <li value="101"> REAL
+** </ul>
**
** A NULL value is not changed by this routine. It remains NULL.
*/
-case OP_ToText: { /* same as TK_TO_TEXT, in1 */
+case OP_Cast: { /* in1 */
+ assert( pOp->p2>=SQLITE_AFF_BLOB && pOp->p2<=SQLITE_AFF_REAL );
+ testcase( pOp->p2==SQLITE_AFF_TEXT );
+ testcase( pOp->p2==SQLITE_AFF_BLOB );
+ testcase( pOp->p2==SQLITE_AFF_NUMERIC );
+ testcase( pOp->p2==SQLITE_AFF_INTEGER );
+ testcase( pOp->p2==SQLITE_AFF_REAL );
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);
+ sqlite3VdbeMemCast(pIn1, pOp->p2, encoding);
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
+** Synopsis: if r[P1]<r[P3] goto P2
**
** Compare the values in register P1 and P3. If reg(P3)<reg(P1) then
** jump to address P2.
@@ -65696,6 +75611,7 @@ case OP_ToReal: { /* same as TK_TO_REAL, in1 */
** bit set.
*/
/* Opcode: Ne P1 P2 P3 P4 P5
+** Synopsis: if r[P1]!=r[P3] goto P2
**
** 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
@@ -65708,6 +75624,7 @@ case OP_ToReal: { /* same as TK_TO_REAL, in1 */
** the SQLITE_NULLEQ flag were omitted from P5.
*/
/* Opcode: Eq P1 P2 P3 P4 P5
+** Synopsis: if r[P1]==r[P3] goto P2
**
** This works just like the Lt opcode except that the jump is taken if
** the operands in registers P1 and P3 are equal.
@@ -65720,18 +75637,21 @@ case OP_ToReal: { /* same as TK_TO_REAL, in1 */
** the SQLITE_NULLEQ flag were omitted from P5.
*/
/* Opcode: Le P1 P2 P3 P4 P5
+** Synopsis: if r[P1]<=r[P3] goto P2
**
** 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
+** Synopsis: if r[P1]>r[P3] goto P2
**
** 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
+** Synopsis: if r[P1]>=r[P3] goto P2
**
** 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
@@ -65743,18 +75663,16 @@ 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 ){
+ flags1 = pIn1->flags;
+ flags3 = pIn3->flags;
+ if( (flags1 | 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
@@ -65762,14 +75680,15 @@ case OP_Ge: { /* same as TK_GE, jump, in1, in3 */
** 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
+ assert( (flags1 & MEM_Cleared)==0 );
+ assert( (pOp->p5 & SQLITE_JUMPIFNULL)==0 );
+ if( (flags1&MEM_Null)!=0
+ && (flags3&MEM_Null)!=0
+ && (flags3&MEM_Cleared)==0
){
- u.ak.res = 0; /* Results are equal */
+ res = 0; /* Results are equal */
}else{
- u.ak.res = 1; /* Results are not equal */
+ res = 1; /* Results are not equal */
}
}else{
/* SQLITE_NULLEQ is clear and at least one operand is NULL,
@@ -65778,49 +75697,81 @@ case OP_Ge: { /* same as TK_GE, jump, in1, in3 */
*/
if( pOp->p5 & SQLITE_STOREP2 ){
pOut = &aMem[pOp->p2];
+ memAboutToChange(p, pOut);
MemSetTypeFlag(pOut, MEM_Null);
REGISTER_TRACE(pOp->p2, pOut);
- }else if( pOp->p5 & SQLITE_JUMPIFNULL ){
- pc = pOp->p2-1;
+ }else{
+ VdbeBranchTaken(2,3);
+ if( pOp->p5 & SQLITE_JUMPIFNULL ){
+ goto jump_to_p2;
+ }
}
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;
+ affinity = pOp->p5 & SQLITE_AFF_MASK;
+ if( affinity>=SQLITE_AFF_NUMERIC ){
+ if( (flags1 & (MEM_Int|MEM_Real|MEM_Str))==MEM_Str ){
+ applyNumericAffinity(pIn1,0);
+ }
+ if( (flags3 & (MEM_Int|MEM_Real|MEM_Str))==MEM_Str ){
+ applyNumericAffinity(pIn3,0);
+ }
+ }else if( affinity==SQLITE_AFF_TEXT ){
+ if( (flags1 & MEM_Str)==0 && (flags1 & (MEM_Int|MEM_Real))!=0 ){
+ testcase( pIn1->flags & MEM_Int );
+ testcase( pIn1->flags & MEM_Real );
+ sqlite3VdbeMemStringify(pIn1, encoding, 1);
+ testcase( (flags1&MEM_Dyn) != (pIn1->flags&MEM_Dyn) );
+ flags1 = (pIn1->flags & ~MEM_TypeMask) | (flags1 & MEM_TypeMask);
+ }
+ if( (flags3 & MEM_Str)==0 && (flags3 & (MEM_Int|MEM_Real))!=0 ){
+ testcase( pIn3->flags & MEM_Int );
+ testcase( pIn3->flags & MEM_Real );
+ sqlite3VdbeMemStringify(pIn3, encoding, 1);
+ testcase( (flags3&MEM_Dyn) != (pIn3->flags&MEM_Dyn) );
+ flags3 = (pIn3->flags & ~MEM_TypeMask) | (flags3 & MEM_TypeMask);
+ }
}
-
assert( pOp->p4type==P4_COLLSEQ || pOp->p4.pColl==0 );
- ExpandBlob(pIn1);
- ExpandBlob(pIn3);
- u.ak.res = sqlite3MemCompare(pIn3, pIn1, pOp->p4.pColl);
+ if( flags1 & MEM_Zero ){
+ sqlite3VdbeMemExpandBlob(pIn1);
+ flags1 &= ~MEM_Zero;
+ }
+ if( flags3 & MEM_Zero ){
+ sqlite3VdbeMemExpandBlob(pIn3);
+ flags3 &= ~MEM_Zero;
+ }
+ 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;
+ case OP_Eq: res = res==0; break;
+ case OP_Ne: res = res!=0; break;
+ case OP_Lt: res = res<0; break;
+ case OP_Le: res = res<=0; break;
+ case OP_Gt: res = res>0; break;
+ default: res = res>=0; break;
}
+ /* Undo any changes made by applyAffinity() to the input registers. */
+ assert( (pIn1->flags & MEM_Dyn) == (flags1 & MEM_Dyn) );
+ pIn1->flags = flags1;
+ assert( (pIn3->flags & MEM_Dyn) == (flags3 & MEM_Dyn) );
+ pIn3->flags = flags3;
+
if( pOp->p5 & SQLITE_STOREP2 ){
pOut = &aMem[pOp->p2];
memAboutToChange(p, pOut);
MemSetTypeFlag(pOut, MEM_Int);
- pOut->u.i = u.ak.res;
+ pOut->u.i = res;
REGISTER_TRACE(pOp->p2, pOut);
- }else if( u.ak.res ){
- pc = pOp->p2-1;
+ }else{
+ VdbeBranchTaken(res!=0, (pOp->p5 & SQLITE_NULLEQ)?2:3);
+ if( res ){
+ goto jump_to_p2;
+ }
}
-
- /* 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;
}
@@ -65841,6 +75792,7 @@ case OP_Permutation: {
}
/* Opcode: Compare P1 P2 P3 P4 P5
+** Synopsis: r[P1@P3] <-> r[P2@P3]
**
** 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
@@ -65860,7 +75812,6 @@ case OP_Permutation: {
** and strings are less than blobs.
*/
case OP_Compare: {
-#if 0 /* local variables moved into u.al */
int n;
int i;
int p1;
@@ -65869,38 +75820,37 @@ case OP_Compare: {
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;
+ n = pOp->p3;
+ pKeyInfo = pOp->p4.pKeyInfo;
+ assert( n>0 );
+ assert( pKeyInfo!=0 );
+ p1 = pOp->p1;
+ 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 );
+ for(k=0; k<n; k++) if( aPermute[k]>mx ) mx = aPermute[k];
+ assert( p1>0 && p1+mx<=(p->nMem-p->nCursor)+1 );
+ assert( p2>0 && p2+mx<=(p->nMem-p->nCursor)+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 );
+ assert( p1>0 && p1+n<=(p->nMem-p->nCursor)+1 );
+ assert( p2>0 && p2+n<=(p->nMem-p->nCursor)+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);
+ for(i=0; i<n; i++){
+ idx = aPermute ? aPermute[i] : i;
+ assert( memIsValid(&aMem[p1+idx]) );
+ assert( memIsValid(&aMem[p2+idx]) );
+ REGISTER_TRACE(p1+idx, &aMem[p1+idx]);
+ REGISTER_TRACE(p2+idx, &aMem[p2+idx]);
+ assert( i<pKeyInfo->nField );
+ pColl = pKeyInfo->aColl[i];
+ bRev = pKeyInfo->aSortOrder[i];
+ iCompare = sqlite3MemCompare(&aMem[p1+idx], &aMem[p2+idx], pColl);
if( iCompare ){
- if( u.al.bRev ) iCompare = -iCompare;
+ if( bRev ) iCompare = -iCompare;
break;
}
}
@@ -65916,16 +75866,17 @@ case OP_Compare: {
*/
case OP_Jump: { /* jump */
if( iCompare<0 ){
- pc = pOp->p1 - 1;
+ VdbeBranchTaken(0,3); pOp = &aOp[pOp->p1 - 1];
}else if( iCompare==0 ){
- pc = pOp->p2 - 1;
+ VdbeBranchTaken(1,3); pOp = &aOp[pOp->p2 - 1];
}else{
- pc = pOp->p3 - 1;
+ VdbeBranchTaken(2,3); pOp = &aOp[pOp->p3 - 1];
}
break;
}
/* Opcode: And P1 P2 P3 * *
+** Synopsis: r[P3]=(r[P1] && r[P2])
**
** Take the logical AND of the values in registers P1 and P2 and
** write the result into register P3.
@@ -65935,6 +75886,7 @@ case OP_Jump: { /* jump */
** a NULL output.
*/
/* Opcode: Or P1 P2 P3 * *
+** Synopsis: r[P3]=(r[P1] || r[P2])
**
** Take the logical OR of the values in register P1 and P2 and
** store the answer in register P3.
@@ -65945,41 +75897,40 @@ case OP_Jump: { /* jump */
*/
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;
+ v1 = 2;
}else{
- u.am.v1 = sqlite3VdbeIntValue(pIn1)!=0;
+ v1 = sqlite3VdbeIntValue(pIn1)!=0;
}
pIn2 = &aMem[pOp->p2];
if( pIn2->flags & MEM_Null ){
- u.am.v2 = 2;
+ v2 = 2;
}else{
- u.am.v2 = sqlite3VdbeIntValue(pIn2)!=0;
+ 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];
+ v1 = and_logic[v1*3+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];
+ v1 = or_logic[v1*3+v2];
}
pOut = &aMem[pOp->p3];
- if( u.am.v1==2 ){
+ if( v1==2 ){
MemSetTypeFlag(pOut, MEM_Null);
}else{
- pOut->u.i = u.am.v1;
+ pOut->u.i = v1;
MemSetTypeFlag(pOut, MEM_Int);
}
break;
}
/* Opcode: Not P1 P2 * * *
+** Synopsis: r[P2]= !r[P1]
**
** Interpret the value in register P1 as a boolean value. Store the
** boolean complement in register P2. If the value in register P1 is
@@ -65988,15 +75939,16 @@ case OP_Or: { /* same as TK_OR, in1, in2, out3 */
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));
+ sqlite3VdbeMemSetNull(pOut);
+ if( (pIn1->flags & MEM_Null)==0 ){
+ pOut->flags = MEM_Int;
+ pOut->u.i = !sqlite3VdbeIntValue(pIn1);
}
break;
}
/* Opcode: BitNot P1 P2 * * *
+** Synopsis: r[P1]= ~r[P1]
**
** Interpret the content of register P1 as an integer. Store the
** ones-complement of the P1 value into register P2. If P1 holds
@@ -66005,23 +75957,30 @@ case OP_Not: { /* same as TK_NOT, in1, out2 */
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));
+ sqlite3VdbeMemSetNull(pOut);
+ if( (pIn1->flags & MEM_Null)==0 ){
+ pOut->flags = MEM_Int;
+ pOut->u.i = ~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.
+** Check the "once" flag number P1. If it is set, jump to instruction P2.
+** Otherwise, set the flag and fall through to the next instruction.
+** In other words, this opcode causes all following opcodes up through P2
+** (but not including P2) to run just once and to be skipped on subsequent
+** times through the loop.
+**
+** All "once" flags are initially cleared whenever a prepared statement
+** first begins to run.
*/
case OP_Once: { /* jump */
assert( pOp->p1<p->nOnceFlag );
+ VdbeBranchTaken(p->aOnceFlag[pOp->p1]!=0, 2);
if( p->aOnceFlag[pOp->p1] ){
- pc = pOp->p2-1;
+ goto jump_to_p2;
}else{
p->aOnceFlag[pOp->p1] = 1;
}
@@ -66032,61 +75991,65 @@ case OP_Once: { /* jump */
**
** 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.
+** in P1 is NULL then take the jump if and only 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.
+** in P1 is NULL then take the jump if and only if P3 is non-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;
+ c = pOp->p3;
}else{
#ifdef SQLITE_OMIT_FLOATING_POINT
- u.an.c = sqlite3VdbeIntValue(pIn1)!=0;
+ c = sqlite3VdbeIntValue(pIn1)!=0;
#else
- u.an.c = sqlite3VdbeRealValue(pIn1)!=0.0;
+ c = sqlite3VdbeRealValue(pIn1)!=0.0;
#endif
- if( pOp->opcode==OP_IfNot ) u.an.c = !u.an.c;
+ if( pOp->opcode==OP_IfNot ) c = !c;
}
- if( u.an.c ){
- pc = pOp->p2-1;
+ VdbeBranchTaken(c!=0, 2);
+ if( c ){
+ goto jump_to_p2;
}
break;
}
/* Opcode: IsNull P1 P2 * * *
+** Synopsis: if r[P1]==NULL goto 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];
+ VdbeBranchTaken( (pIn1->flags & MEM_Null)!=0, 2);
if( (pIn1->flags & MEM_Null)!=0 ){
- pc = pOp->p2 - 1;
+ goto jump_to_p2;
}
break;
}
/* Opcode: NotNull P1 P2 * * *
+** Synopsis: if r[P1]!=NULL goto 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];
+ VdbeBranchTaken( (pIn1->flags & MEM_Null)==0, 2);
if( (pIn1->flags & MEM_Null)==0 ){
- pc = pOp->p2 - 1;
+ goto jump_to_p2;
}
break;
}
/* Opcode: Column P1 P2 P3 P4 P5
+** Synopsis: r[P3]=PX
**
** Interpret the data that cursor P1 points to as a structure built using
** the MakeRecord instruction. (See the MakeRecord opcode for additional
@@ -66111,320 +76074,255 @@ case OP_NotNull: { /* same as TK_NOTNULL, jump, in1 */
** 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 */
+ const u8 *zData; /* Part of the record being decoded */
+ const u8 *zHdr; /* Next unparsed byte of the header */
+ const 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 */
+ u64 offset64; /* 64-bit offset */
+ u32 avail; /* Number of bytes of available data */
u32 t; /* A type code from the record header */
+ u16 fx; /* pDest->flags value */
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;
+ p2 = pOp->p2;
+ assert( pOp->p3>0 && pOp->p3<=(p->nMem-p->nCursor) );
+ pDest = &aMem[pOp->p3];
+ memAboutToChange(p, pDest);
+ assert( pOp->p1>=0 && pOp->p1<p->nCursor );
+ pC = p->apCsr[pOp->p1];
+ assert( pC!=0 );
+ assert( p2<pC->nField );
+ aOffset = pC->aOffset;
+ assert( pC->eCurType!=CURTYPE_VTAB );
+ assert( pC->eCurType!=CURTYPE_PSEUDO || pC->nullRow );
+ assert( pC->eCurType!=CURTYPE_SORTER );
+ pCrsr = pC->uc.pCursor;
+
+ /* If the cursor cache is stale, bring it up-to-date */
+ rc = sqlite3VdbeCursorMoveto(pC);
+ if( rc ) goto abort_due_to_error;
+ if( pC->cacheStatus!=p->cacheCtr ){
+ if( pC->nullRow ){
+ if( pC->eCurType==CURTYPE_PSEUDO ){
+ assert( pC->uc.pseudoTableReg>0 );
+ pReg = &aMem[pC->uc.pseudoTableReg];
+ assert( pReg->flags & MEM_Blob );
+ assert( memIsValid(pReg) );
+ pC->payloadSize = pC->szRow = avail = pReg->n;
+ pC->aRow = (u8*)pReg->z;
+ }else{
+ sqlite3VdbeMemSetNull(pDest);
+ goto op_column_out;
+ }
+ }else{
+ assert( pC->eCurType==CURTYPE_BTREE );
+ assert( pCrsr );
+ if( pC->isTable==0 ){
+ assert( sqlite3BtreeCursorIsValid(pCrsr) );
+ VVA_ONLY(rc =) sqlite3BtreeKeySize(pCrsr, &payloadSize64);
+ assert( rc==SQLITE_OK ); /* True because of CursorMoveto() call above */
+ /* sqlite3BtreeParseCellPtr() uses getVarint32() to extract the
+ ** payload size, so it is impossible for payloadSize64 to be
+ ** larger than 32 bits. */
+ assert( (payloadSize64 & SQLITE_MAX_U32)==(u64)payloadSize64 );
+ pC->aRow = sqlite3BtreeKeyFetch(pCrsr, &avail);
+ pC->payloadSize = (u32)payloadSize64;
+ }else{
+ assert( sqlite3BtreeCursorIsValid(pCrsr) );
+ VVA_ONLY(rc =) sqlite3BtreeDataSize(pCrsr, &pC->payloadSize);
+ assert( rc==SQLITE_OK ); /* DataSize() cannot fail */
+ pC->aRow = sqlite3BtreeDataFetch(pCrsr, &avail);
+ }
+ assert( avail<=65536 ); /* Maximum page size is 64KiB */
+ if( pC->payloadSize <= (u32)avail ){
+ pC->szRow = pC->payloadSize;
+ }else if( pC->payloadSize > (u32)db->aLimit[SQLITE_LIMIT_LENGTH] ){
+ goto too_big;
+ }else{
+ pC->szRow = avail;
+ }
}
- 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;
- }
+ pC->cacheStatus = p->cacheCtr;
+ pC->iHdrOffset = getVarint32(pC->aRow, offset);
+ pC->nHdrParsed = 0;
+ aOffset[0] = offset;
- /* 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;
+ if( avail<offset ){
+ /* pC->aRow does not have to hold the entire row, but it does at least
+ ** need to cover the header of the record. If pC->aRow does not contain
+ ** the complete header, then set it to zero, forcing the header to be
+ ** dynamically allocated. */
+ pC->aRow = 0;
+ pC->szRow = 0;
- /* 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.
+ /* 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.
*/
- 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;
+ if( offset > 98307 || offset > pC->payloadSize ){
+ rc = SQLITE_CORRUPT_BKPT;
+ goto op_column_error;
}
}
- /* 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.
+ /* The following goto is an optimization. It can be omitted and
+ ** everything will still work. But OP_Column is measurably faster
+ ** by skipping the subsequent conditional, which is always true.
*/
- if( u.ao.offset > 98307 ){
- rc = SQLITE_CORRUPT_BKPT;
- goto op_column_out;
- }
+ assert( pC->nHdrParsed<=p2 ); /* Conditional skipped */
+ goto op_column_read_header;
+ }
- /* 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.
+ /* Make sure at least the first p2+1 entries of the header have been
+ ** parsed and valid information is in aOffset[] and pC->aType[].
+ */
+ if( pC->nHdrParsed<=p2 ){
+ /* If there is more header available for parsing in the record, try
+ ** to extract additional fields up through the p2+1-th field
*/
- 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;
+ op_column_read_header:
+ if( pC->iHdrOffset<aOffset[0] ){
+ /* Make sure zData points to enough of the record to cover the header. */
+ if( pC->aRow==0 ){
+ memset(&sMem, 0, sizeof(sMem));
+ rc = sqlite3VdbeMemFromBtree(pCrsr, 0, aOffset[0], !pC->isTable, &sMem);
+ if( rc!=SQLITE_OK ) goto op_column_error;
+ zData = (u8*)sMem.z;
+ }else{
+ zData = pC->aRow;
}
- 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++;
+
+ /* Fill in pC->aType[i] and aOffset[i] values through the p2-th field. */
+ i = pC->nHdrParsed;
+ offset64 = aOffset[i];
+ zHdr = zData + pC->iHdrOffset;
+ zEndHdr = zData + aOffset[0];
+ assert( i<=p2 && zHdr<zEndHdr );
+ do{
+ if( (t = zHdr[0])<0x80 ){
+ zHdr++;
+ offset64 += sqlite3VdbeOneByteSerialTypeLen(t);
}else{
- u.ao.zIdx += sqlite3GetVarint32(u.ao.zIdx, &u.ao.t);
+ zHdr += sqlite3GetVarint32(zHdr, &t);
+ offset64 += sqlite3VdbeSerialTypeLen(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;
+ pC->aType[i++] = t;
+ aOffset[i] = (u32)(offset64 & 0xffffffff);
+ }while( i<=p2 && zHdr<zEndHdr );
+ pC->nHdrParsed = i;
+ pC->iHdrOffset = (u32)(zHdr - zData);
+ if( pC->aRow==0 ) sqlite3VdbeMemRelease(&sMem);
+
+ /* The record is corrupt if any of the following are true:
+ ** (1) the bytes of the header extend past the declared header size
+ ** (2) the entire header was used but not all data was used
+ ** (3) the end of the data extends beyond the end of the record.
+ */
+ if( (zHdr>=zEndHdr && (zHdr>zEndHdr || offset64!=pC->payloadSize))
+ || (offset64 > pC->payloadSize)
+ ){
+ rc = SQLITE_CORRUPT_BKPT;
+ goto op_column_error;
}
+ }else{
+ t = 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 after trying to extract new entries from the header, nHdrParsed is
+ ** still not up to p2, that means that the record has fewer than p2
+ ** columns. So the result will be either the default value or a NULL.
*/
- 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;
+ if( pC->nHdrParsed<=p2 ){
+ if( pOp->p4type==P4_MEM ){
+ sqlite3VdbeMemShallowCopy(pDest, pOp->p4.pMem, MEM_Static);
}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;
+ sqlite3VdbeMemSetNull(pDest);
}
- sqlite3VdbeSerialGet((u8*)u.ao.zData, u.ao.t, u.ao.pDest);
+ goto op_column_out;
}
- 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);
- }
+ t = pC->aType[p2];
}
- /* 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.
+ /* Extract the content for the p2+1-th column. Control can only
+ ** reach this point if aOffset[p2], aOffset[p2+1], and pC->aType[p2] are
+ ** all valid.
*/
- 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;
+ assert( p2<pC->nHdrParsed );
+ assert( rc==SQLITE_OK );
+ assert( sqlite3VdbeCheckMemInvariants(pDest) );
+ if( VdbeMemDynamic(pDest) ) sqlite3VdbeMemSetNull(pDest);
+ assert( t==pC->aType[p2] );
+ if( pC->szRow>=aOffset[p2+1] ){
+ /* This is the common case where the desired content fits on the original
+ ** page - where the content is not on an overflow page */
+ sqlite3VdbeSerialGet(pC->aRow+aOffset[p2], t, pDest);
+ }else{
+ /* This branch happens only when content is on overflow pages */
+ if( ((pOp->p5 & (OPFLAG_LENGTHARG|OPFLAG_TYPEOFARG))!=0
+ && ((t>=12 && (t&1)==0) || (pOp->p5 & OPFLAG_TYPEOFARG)!=0))
+ || (len = sqlite3VdbeSerialTypeLen(t))==0
+ ){
+ /* Content is irrelevant for
+ ** 1. the typeof() function,
+ ** 2. the length(X) function if X is a blob, and
+ ** 3. if the content length is zero.
+ ** So we might as well use bogus content rather than reading
+ ** content from disk. NULL will work for the value for strings
+ ** and blobs and whatever is in the payloadSize64 variable
+ ** will work for everything else. */
+ sqlite3VdbeSerialGet(t<=13 ? (u8*)&payloadSize64 : 0, t, pDest);
+ }else{
+ rc = sqlite3VdbeMemFromBtree(pCrsr, aOffset[p2], len, !pC->isTable,
+ pDest);
+ if( rc!=SQLITE_OK ){
+ goto op_column_error;
+ }
+ sqlite3VdbeSerialGet((const u8*)pDest->z, t, pDest);
+ pDest->flags &= ~MEM_Ephem;
+ }
}
-
- rc = sqlite3VdbeMemMakeWriteable(u.ao.pDest);
+ pDest->enc = encoding;
op_column_out:
- UPDATE_MAX_BLOBSIZE(u.ao.pDest);
- REGISTER_TRACE(pOp->p3, u.ao.pDest);
+ /* If the column value is an ephemeral string, go ahead and persist
+ ** that string in case the cursor moves before the column value is
+ ** used. The following code does the equivalent of Deephemeralize()
+ ** but does it faster. */
+ if( (pDest->flags & MEM_Ephem)!=0 && pDest->z ){
+ fx = pDest->flags & (MEM_Str|MEM_Blob);
+ assert( fx!=0 );
+ zData = (const u8*)pDest->z;
+ len = pDest->n;
+ if( sqlite3VdbeMemClearAndResize(pDest, len+2) ) goto no_mem;
+ memcpy(pDest->z, zData, len);
+ pDest->z[len] = 0;
+ pDest->z[len+1] = 0;
+ pDest->flags = fx|MEM_Term;
+ }
+op_column_error:
+ UPDATE_MAX_BLOBSIZE(pDest);
+ REGISTER_TRACE(pOp->p3, pDest);
break;
}
/* Opcode: Affinity P1 P2 * P4 *
+** Synopsis: affinity(r[P1@P2])
**
** Apply affinities to a range of P2 registers starting with P1.
**
@@ -66433,26 +76331,24 @@ op_column_out:
** 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 );
+ zAffinity = pOp->p4.z;
+ assert( zAffinity!=0 );
+ assert( zAffinity[pOp->p2]==0 );
pIn1 = &aMem[pOp->p1];
- while( (u.ap.cAff = *(u.ap.zAffinity++))!=0 ){
- assert( pIn1 <= &p->aMem[p->nMem] );
+ while( (cAff = *(zAffinity++))!=0 ){
+ assert( pIn1 <= &p->aMem[(p->nMem-p->nCursor)] );
assert( memIsValid(pIn1) );
- ExpandBlob(pIn1);
- applyAffinity(pIn1, u.ap.cAff, encoding);
+ applyAffinity(pIn1, cAff, encoding);
pIn1++;
}
break;
}
/* Opcode: MakeRecord P1 P2 P3 P4 *
+** Synopsis: r[P3]=mkrec(r[P1@P2])
**
** Convert P2 registers beginning with P1 into the [record format]
** use as a data record in a database table or as a key
@@ -66465,16 +76361,15 @@ case OP_Affinity: {
** 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.
+** If P4 is NULL then all index fields have the affinity BLOB.
*/
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 */
+ i64 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 */
@@ -66482,102 +76377,125 @@ case OP_MakeRecord: {
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 */
+ int i; /* Space used in zNewRecord[] header */
+ int j; /* Space used in zNewRecord[] content */
+ u32 len; /* Length of a field */
/* 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 |
+ ** | 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.
+ ** and so forth.
**
- ** Each type field is a varint representing the serial type of the
+ ** 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;
+ nData = 0; /* Number of bytes of data space */
+ nHdr = 0; /* Number of bytes of header space */
+ nZero = 0; /* Number of zero bytes at the end of the record */
+ nField = pOp->p1;
+ zAffinity = pOp->p4.z;
+ assert( nField>0 && pOp->p2>0 && pOp->p2+nField<=(p->nMem-p->nCursor)+1 );
+ pData0 = &aMem[nField];
+ nField = pOp->p2;
+ pLast = &pData0[nField-1];
+ 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.
+ /* Apply the requested affinity to all inputs
*/
- 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;
- }
+ assert( pData0<=pLast );
+ if( zAffinity ){
+ pRec = pData0;
+ do{
+ applyAffinity(pRec++, *(zAffinity++), encoding);
+ assert( zAffinity[0]==0 || pRec<=pLast );
+ }while( zAffinity[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] ){
+ /* Loop through the elements that will make up the record to figure
+ ** out how much space is required for the new record.
+ */
+ pRec = pLast;
+ do{
+ assert( memIsValid(pRec) );
+ pRec->uTemp = serial_type = sqlite3VdbeSerialType(pRec, file_format, &len);
+ if( pRec->flags & MEM_Zero ){
+ if( nData ){
+ if( sqlite3VdbeMemExpandBlob(pRec) ) goto no_mem;
+ }else{
+ nZero += pRec->u.nZero;
+ len -= pRec->u.nZero;
+ }
+ }
+ nData += len;
+ testcase( serial_type==127 );
+ testcase( serial_type==128 );
+ nHdr += serial_type<=127 ? 1 : sqlite3VarintLen(serial_type);
+ }while( (--pRec)>=pData0 );
+
+ /* EVIDENCE-OF: R-22564-11647 The header begins with a single varint
+ ** which determines the total number of bytes in the header. The varint
+ ** value is the size of the header in bytes including the size varint
+ ** itself. */
+ testcase( nHdr==126 );
+ testcase( nHdr==127 );
+ if( nHdr<=126 ){
+ /* The common case */
+ nHdr += 1;
+ }else{
+ /* Rare case of a really large header */
+ nVarint = sqlite3VarintLen(nHdr);
+ nHdr += nVarint;
+ if( nVarint<sqlite3VarintLen(nHdr) ) nHdr++;
+ }
+ nByte = nHdr+nData;
+ if( nByte+nZero>db->aLimit[SQLITE_LIMIT_LENGTH] ){
goto too_big;
}
- /* Make sure the output register has a buffer large enough to store
+ /* 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).
+ ** sqlite3VdbeMemClearAndResize() could clobber the value before it is used).
*/
- if( sqlite3VdbeMemGrow(pOut, (int)u.aq.nByte, 0) ){
+ if( sqlite3VdbeMemClearAndResize(pOut, (int)nByte) ){
goto no_mem;
}
- u.aq.zNewRecord = (u8 *)pOut->z;
+ 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;
+ i = putVarint32(zNewRecord, nHdr);
+ j = nHdr;
+ assert( pData0<=pLast );
+ pRec = pData0;
+ do{
+ serial_type = pRec->uTemp;
+ /* EVIDENCE-OF: R-06529-47362 Following the size varint are one or more
+ ** additional varints, one per column. */
+ i += putVarint32(&zNewRecord[i], serial_type); /* serial type */
+ /* EVIDENCE-OF: R-64536-51728 The values for each column in the record
+ ** immediately follow the header. */
+ j += sqlite3VdbeSerialPut(&zNewRecord[j], pRec, serial_type); /* content */
+ }while( (++pRec)<=pLast );
+ assert( i==nHdr );
+ assert( j==nByte );
+
+ assert( pOp->p3>0 && pOp->p3<=(p->nMem-p->nCursor) );
+ pOut->n = (int)nByte;
+ pOut->flags = MEM_Blob;
+ if( nZero ){
+ pOut->u.nZero = nZero;
pOut->flags |= MEM_Zero;
}
pOut->enc = SQLITE_UTF8; /* In case the blob is ever converted to text */
@@ -66587,24 +76505,23 @@ case OP_MakeRecord: {
}
/* Opcode: Count P1 P2 * * *
+** Synopsis: r[P2]=count()
**
** 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 */
+case OP_Count: { /* out2 */
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;
+ assert( p->apCsr[pOp->p1]->eCurType==CURTYPE_BTREE );
+ pCrsr = p->apCsr[pOp->p1]->uc.pCursor;
+ assert( pCrsr );
+ nEntry = 0; /* Not needed. Only used to silence a warning. */
+ rc = sqlite3BtreeCount(pCrsr, &nEntry);
+ pOut = out2Prerelease(p, pOp);
+ pOut->u.i = nEntry;
break;
}
#endif
@@ -66616,7 +76533,6 @@ case OP_Count: { /* out2-prerelease */
** 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;
@@ -66625,29 +76541,28 @@ case OP_Savepoint: {
Savepoint *pTmp;
int iSavepoint;
int ii;
-#endif /* local variables moved into u.as */
- u.as.p1 = pOp->p1;
- u.as.zName = pOp->p4.z;
+ p1 = pOp->p1;
+ 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 that the 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( p1==SAVEPOINT_BEGIN||p1==SAVEPOINT_RELEASE||p1==SAVEPOINT_ROLLBACK );
assert( db->pSavepoint || db->isTransactionSavepoint==0 );
assert( checkSavepointCount(db) );
+ assert( p->bIsReader );
- if( u.as.p1==SAVEPOINT_BEGIN ){
- if( db->writeVdbeCnt>0 ){
- /* A new savepoint cannot be created if there are active write
+ if( p1==SAVEPOINT_BEGIN ){
+ if( db->nVdbeWrite>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");
+ sqlite3VdbeError(p, "cannot open savepoint - SQL statements in progress");
rc = SQLITE_BUSY;
}else{
- u.as.nName = sqlite3Strlen30(u.as.zName);
+ nName = sqlite3Strlen30(zName);
#ifndef SQLITE_OMIT_VIRTUALTABLE
/* This call is Ok even if this savepoint is actually a transaction
@@ -66661,11 +76576,11 @@ case OP_Savepoint: {
#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);
-
+ pNew = sqlite3DbMallocRaw(db, sizeof(Savepoint)+nName+1);
+ if( pNew ){
+ pNew->zName = (char *)&pNew[1];
+ memcpy(pNew->zName, zName, nName+1);
+
/* If there is no open transaction, then mark this as a special
** "transaction savepoint". */
if( db->autoCommit ){
@@ -66674,50 +76589,50 @@ case OP_Savepoint: {
}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;
+ pNew->pNext = db->pSavepoint;
+ db->pSavepoint = pNew;
+ pNew->nDeferredCons = db->nDeferredCons;
+ pNew->nDeferredImmCons = db->nDeferredImmCons;
}
}
}else{
- u.as.iSavepoint = 0;
+ 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
+ pSavepoint = db->pSavepoint;
+ pSavepoint && sqlite3StrICmp(pSavepoint->zName, zName);
+ pSavepoint = pSavepoint->pNext
){
- u.as.iSavepoint++;
+ iSavepoint++;
}
- if( !u.as.pSavepoint ){
- sqlite3SetString(&p->zErrMsg, db, "no such savepoint: %s", u.as.zName);
+ if( !pSavepoint ){
+ sqlite3VdbeError(p, "no such savepoint: %s", 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
+ }else if( db->nVdbeWrite>0 && 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"
- );
+ sqlite3VdbeError(p, "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.
+ ** 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 ){
+ int isTransaction = pSavepoint->pNext==0 && db->isTransactionSavepoint;
+ if( isTransaction && p1==SAVEPOINT_RELEASE ){
if( (rc = sqlite3VdbeCheckFk(p, 1))!=SQLITE_OK ){
goto vdbe_return;
}
db->autoCommit = 1;
if( sqlite3VdbeHalt(p)==SQLITE_BUSY ){
- p->pc = pc;
+ p->pc = (int)(pOp - aOp);
db->autoCommit = 0;
p->rc = rc = SQLITE_BUSY;
goto vdbe_return;
@@ -66725,51 +76640,59 @@ case OP_Savepoint: {
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);
+ int isSchemaChange;
+ iSavepoint = db->nSavepoint - iSavepoint - 1;
+ if( p1==SAVEPOINT_ROLLBACK ){
+ isSchemaChange = (db->flags & SQLITE_InternChanges)!=0;
+ for(ii=0; ii<db->nDb; ii++){
+ rc = sqlite3BtreeTripAllCursors(db->aDb[ii].pBt,
+ SQLITE_ABORT_ROLLBACK,
+ isSchemaChange==0);
+ if( rc!=SQLITE_OK ) goto abort_due_to_error;
}
+ }else{
+ isSchemaChange = 0;
}
- 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);
+ for(ii=0; ii<db->nDb; ii++){
+ rc = sqlite3BtreeSavepoint(db->aDb[ii].pBt, p1, iSavepoint);
if( rc!=SQLITE_OK ){
goto abort_due_to_error;
}
}
- if( u.as.p1==SAVEPOINT_ROLLBACK && (db->flags&SQLITE_InternChanges)!=0 ){
+ if( isSchemaChange ){
sqlite3ExpirePreparedStatements(db);
sqlite3ResetAllSchemasOfConnection(db);
db->flags = (db->flags | SQLITE_InternChanges);
}
}
-
- /* Regardless of whether this is a RELEASE or ROLLBACK, destroy all
+
+ /* 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);
+ while( db->pSavepoint!=pSavepoint ){
+ pTmp = db->pSavepoint;
+ db->pSavepoint = pTmp->pNext;
+ sqlite3DbFree(db, 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
+ /* 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( p1==SAVEPOINT_RELEASE ){
+ assert( pSavepoint==db->pSavepoint );
+ db->pSavepoint = pSavepoint->pNext;
+ sqlite3DbFree(db, pSavepoint);
if( !isTransaction ){
db->nSavepoint--;
}
}else{
- db->nDeferredCons = u.as.pSavepoint->nDeferredCons;
+ db->nDeferredCons = pSavepoint->nDeferredCons;
+ db->nDeferredImmCons = pSavepoint->nDeferredImmCons;
}
- if( !isTransaction ){
- rc = sqlite3VtabSavepoint(db, u.as.p1, u.as.iSavepoint);
+ if( !isTransaction || p1==SAVEPOINT_ROLLBACK ){
+ rc = sqlite3VtabSavepoint(db, p1, iSavepoint);
if( rc!=SQLITE_OK ) goto abort_due_to_error;
}
}
@@ -66788,52 +76711,40 @@ case OP_Savepoint: {
** 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 */
+ desiredAutoCommit = pOp->p1;
+ iRollback = pOp->p2;
+ turnOnAC = desiredAutoCommit && !db->autoCommit;
+ assert( desiredAutoCommit==1 || desiredAutoCommit==0 );
+ assert( desiredAutoCommit==1 || iRollback==0 );
+ assert( db->nVdbeActive>0 ); /* At least this one VM is active */
+ assert( p->bIsReader );
-#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( turnOnAC && !iRollback && db->nVdbeWrite>0 ){
/* If this instruction implements a COMMIT and other VMs are writing
- ** return an error indicating that the other VMs must complete first.
+ ** return an error indicating that the other VMs must complete first.
*/
- sqlite3SetString(&p->zErrMsg, db, "cannot commit transaction - "
- "SQL statements in progress");
+ sqlite3VdbeError(p, "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 );
+ }else if( desiredAutoCommit!=db->autoCommit ){
+ if( iRollback ){
+ assert( 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;
- }
+ db->autoCommit = (u8)desiredAutoCommit;
+ }
+ if( sqlite3VdbeHalt(p)==SQLITE_BUSY ){
+ p->pc = (int)(pOp - aOp);
+ db->autoCommit = (u8)(1-desiredAutoCommit);
+ p->rc = rc = SQLITE_BUSY;
+ goto vdbe_return;
}
assert( db->nStatement==0 );
sqlite3CloseSavepoints(db);
@@ -66844,35 +76755,29 @@ case OP_AutoCommit: {
}
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":
+ sqlite3VdbeError(p,
+ (!desiredAutoCommit)?"cannot start a transaction within a transaction":(
+ (iRollback)?"cannot rollback - no transaction is active":
"cannot commit - no transaction is active"));
-
+
rc = SQLITE_ERROR;
}
break;
}
-/* Opcode: Transaction P1 P2 * * *
+/* Opcode: Transaction P1 P2 P3 P4 P5
**
-** 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.
+** Begin a transaction on database P1 if a transaction is not already
+** active.
+** If P2 is non-zero, then a write-transaction is started, or if a
+** read-transaction is already active, it is upgraded to a write-transaction.
+** If P2 is zero, then a read-transaction is started.
**
** 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.
@@ -66883,48 +76788,100 @@ case OP_AutoCommit: {
** 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.
+** If P5!=0 then this opcode also checks the schema cookie against P3
+** and the schema generation counter against P4.
+** 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. If the schema
+** cookie in P3 differs from the schema cookie in the database header or
+** if the schema generation counter in P4 differs from the current
+** generation counter, then an SQLITE_SCHEMA error is raised and execution
+** halts. The sqlite3_step() wrapper function might then reprepare the
+** statement and rerun it from the beginning.
*/
case OP_Transaction: {
-#if 0 /* local variables moved into u.au */
Btree *pBt;
-#endif /* local variables moved into u.au */
+ int iMeta;
+ int iGen;
+ assert( p->bIsReader );
+ assert( p->readOnly==0 || pOp->p2==0 );
assert( pOp->p1>=0 && pOp->p1<db->nDb );
- assert( (p->btreeMask & (((yDbMask)1)<<pOp->p1))!=0 );
- u.au.pBt = db->aDb[pOp->p1].pBt;
+ assert( DbMaskTest(p->btreeMask, pOp->p1) );
+ if( pOp->p2 && (db->flags & SQLITE_QueryOnly)!=0 ){
+ rc = SQLITE_READONLY;
+ goto abort_due_to_error;
+ }
+ 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;
+ if( pBt ){
+ rc = sqlite3BtreeBeginTrans(pBt, pOp->p2);
+ testcase( rc==SQLITE_BUSY_SNAPSHOT );
+ testcase( rc==SQLITE_BUSY_RECOVERY );
+ if( (rc&0xff)==SQLITE_BUSY ){
+ p->pc = (int)(pOp - aOp);
+ p->rc = rc;
goto vdbe_return;
}
if( rc!=SQLITE_OK ){
goto abort_due_to_error;
}
- if( pOp->p2 && p->usesStmtJournal
- && (db->autoCommit==0 || db->activeVdbeCnt>1)
+ if( pOp->p2 && p->usesStmtJournal
+ && (db->autoCommit==0 || db->nVdbeRead>1)
){
- assert( sqlite3BtreeIsInTrans(u.au.pBt) );
+ assert( sqlite3BtreeIsInTrans(pBt) );
if( p->iStatement==0 ){
assert( db->nStatement>=0 && db->nSavepoint>=0 );
- db->nStatement++;
+ 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);
+ rc = sqlite3BtreeBeginStmt(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;
+ p->nStmtDefImmCons = db->nDeferredImmCons;
}
+
+ /* Gather the schema version number for checking:
+ ** IMPLEMENTATION-OF: R-32195-19465 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.
+ */
+ sqlite3BtreeGetMeta(pBt, BTREE_SCHEMA_VERSION, (u32 *)&iMeta);
+ iGen = db->aDb[pOp->p1].pSchema->iGeneration;
+ }else{
+ iGen = iMeta = 0;
+ }
+ assert( pOp->p5==0 || pOp->p4type==P4_INT32 );
+ if( pOp->p5 && (iMeta!=pOp->p3 || iGen!=pOp->p4.i) ){
+ 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!=iMeta ){
+ sqlite3ResetOneSchema(db, pOp->p1);
+ }
+ p->expired = 1;
+ rc = SQLITE_SCHEMA;
}
break;
}
@@ -66941,22 +76898,22 @@ case OP_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 */
+case OP_ReadCookie: { /* out2 */
int iMeta;
int iDb;
int iCookie;
-#endif /* local variables moved into u.av */
- u.av.iDb = pOp->p1;
- u.av.iCookie = pOp->p3;
+ assert( p->bIsReader );
+ iDb = pOp->p1;
+ 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 );
+ assert( iDb>=0 && iDb<db->nDb );
+ assert( db->aDb[iDb].pBt!=0 );
+ assert( DbMaskTest(p->btreeMask, iDb) );
- sqlite3BtreeGetMeta(db->aDb[u.av.iDb].pBt, u.av.iCookie, (u32 *)&u.av.iMeta);
- pOut->u.i = u.av.iMeta;
+ sqlite3BtreeGetMeta(db->aDb[iDb].pBt, iCookie, (u32 *)&iMeta);
+ pOut = out2Prerelease(p, pOp);
+ pOut->u.i = iMeta;
break;
}
@@ -66971,26 +76928,25 @@ case OP_ReadCookie: { /* out2-prerelease */
** 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( DbMaskTest(p->btreeMask, pOp->p1) );
+ assert( p->readOnly==0 );
+ pDb = &db->aDb[pOp->p1];
+ assert( 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);
+ rc = sqlite3BtreeUpdateMeta(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;
+ 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;
+ pDb->pSchema->file_format = (u8)pIn3->u.i;
}
if( pOp->p1==1 ){
/* Invalidate all prepared statements whenever the TEMP database
@@ -67001,68 +76957,8 @@ case OP_SetCookie: { /* in3 */
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
+** Synopsis: root=P2 iDb=P3
**
** 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.
@@ -67090,9 +76986,24 @@ case OP_VerifyCookie: {
** 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.
+** See also: OpenWrite, ReopenIdx
+*/
+/* Opcode: ReopenIdx P1 P2 P3 P4 P5
+** Synopsis: root=P2 iDb=P3
+**
+** The ReopenIdx opcode works exactly like ReadOpen except that it first
+** checks to see if the cursor on P1 is already open with a root page
+** number of P2 and if it is this opcode becomes a no-op. In other words,
+** if the cursor is already open, do not reopen it.
+**
+** The ReopenIdx opcode may only be used with P5==0 and with P4 being
+** a P4_KEYINFO object. Furthermore, the P3 value must be the same as
+** every other ReopenIdx or OpenRead for the same cursor number.
+**
+** See the OpenRead opcode documentation for additional information.
*/
/* Opcode: OpenWrite P1 P2 P3 P4 P5
+** Synopsis: root=P2 iDb=P3
**
** 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
@@ -67111,9 +77022,7 @@ case OP_VerifyCookie: {
**
** See also OpenRead.
*/
-case OP_OpenRead:
-case OP_OpenWrite: {
-#if 0 /* local variables moved into u.ay */
+case OP_ReopenIdx: {
int nField;
KeyInfo *pKeyInfo;
int p2;
@@ -67122,82 +77031,103 @@ case OP_OpenWrite: {
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 );
+ assert( pOp->p5==0 || pOp->p5==OPFLAG_SEEKEQ );
+ assert( pOp->p4type==P4_KEYINFO );
+ pCur = p->apCsr[pOp->p1];
+ if( pCur && pCur->pgnoRoot==(u32)pOp->p2 ){
+ assert( pCur->iDb==pOp->p3 ); /* Guaranteed by the code generator */
+ goto open_cursor_set_hints;
+ }
+ /* If the cursor is not currently open or is open on a different
+ ** index, then fall through into OP_OpenRead to force a reopen */
+case OP_OpenRead:
+case OP_OpenWrite:
+
+ assert( pOp->opcode==OP_OpenWrite || pOp->p5==0 || pOp->p5==OPFLAG_SEEKEQ );
+ assert( p->bIsReader );
+ assert( pOp->opcode==OP_OpenRead || pOp->opcode==OP_ReopenIdx
+ || p->readOnly==0 );
if( p->expired ){
- rc = SQLITE_ABORT;
+ rc = SQLITE_ABORT_ROLLBACK;
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 );
+ nField = 0;
+ pKeyInfo = 0;
+ p2 = pOp->p2;
+ iDb = pOp->p3;
+ assert( iDb>=0 && iDb<db->nDb );
+ assert( DbMaskTest(p->btreeMask, iDb) );
+ pDb = &db->aDb[iDb];
+ pX = pDb->pBt;
+ assert( 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;
+ assert( OPFLAG_FORDELETE==BTREE_FORDELETE );
+ wrFlag = BTREE_WRCSR | (pOp->p5 & OPFLAG_FORDELETE);
+ assert( sqlite3SchemaMutexHeld(db, iDb, 0) );
+ if( pDb->pSchema->file_format < p->minWriteFileFormat ){
+ p->minWriteFileFormat = pDb->pSchema->file_format;
}
}else{
- u.ay.wrFlag = 0;
+ wrFlag = 0;
}
if( pOp->p5 & OPFLAG_P2ISREG ){
- assert( u.ay.p2>0 );
- assert( u.ay.p2<=p->nMem );
- pIn2 = &aMem[u.ay.p2];
+ assert( p2>0 );
+ assert( p2<=(p->nMem-p->nCursor) );
+ pIn2 = &aMem[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.
+ p2 = (int)pIn2->u.i;
+ /* The p2 value always comes from a prior OP_CreateTable opcode and
+ ** that opcode will always set the 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) ) {
+ if( NEVER(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;
+ pKeyInfo = pOp->p4.pKeyInfo;
+ assert( pKeyInfo->enc==ENC(db) );
+ assert( pKeyInfo->db==db );
+ nField = pKeyInfo->nField+pKeyInfo->nXField;
}else if( pOp->p4type==P4_INT32 ){
- u.ay.nField = pOp->p4.i;
+ 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
+ assert( nField>=0 );
+ testcase( nField==0 ); /* Table with INTEGER PRIMARY KEY and nothing else */
+ pCur = allocateCursor(p, pOp->p1, nField, iDb, CURTYPE_BTREE);
+ if( pCur==0 ) goto no_mem;
+ pCur->nullRow = 1;
+ pCur->isOrdered = 1;
+ pCur->pgnoRoot = p2;
+ rc = sqlite3BtreeCursor(pX, p2, wrFlag, pKeyInfo, pCur->uc.pCursor);
+ pCur->pKeyInfo = pKeyInfo;
+ /* Set the VdbeCursor.isTable variable. 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;
+ ** since moved into the btree layer. */
+ pCur->isTable = pOp->p4type!=P4_KEYINFO;
+
+open_cursor_set_hints:
+ assert( OPFLAG_BULKCSR==BTREE_BULKLOAD );
+ assert( OPFLAG_SEEKEQ==BTREE_SEEK_EQ );
+ testcase( pOp->p5 & OPFLAG_BULKCSR );
+#ifdef SQLITE_ENABLE_CURSOR_HINTS
+ testcase( pOp->p2 & OPFLAG_SEEKEQ );
+#endif
+ sqlite3BtreeCursorHintFlags(pCur->uc.pCursor,
+ (pOp->p5 & (OPFLAG_BULKCSR|OPFLAG_SEEKEQ)));
break;
}
/* Opcode: OpenEphemeral P1 P2 * P4 P5
+** Synopsis: nColumn=P2
**
** Open a new cursor P1 to a transient table.
** The cursor is always opened read/write even if
@@ -67209,18 +77139,13 @@ case OP_OpenWrite: {
** 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 *
+** Synopsis: nColumn=P2
**
** This opcode works the same as OP_OpenEphemeral. It has a
** different name to distinguish its use. Tables created using
@@ -67229,24 +77154,25 @@ case OP_OpenWrite: {
*/
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 =
+ KeyInfo *pKeyInfo;
+
+ 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,
+ assert( pOp->p2>=0 );
+ pCx = allocateCursor(p, pOp->p1, pOp->p2, -1, CURTYPE_BTREE);
+ if( pCx==0 ) goto no_mem;
+ pCx->nullRow = 1;
+ pCx->isEphemeral = 1;
+ rc = sqlite3BtreeOpen(db->pVfs, 0, db, &pCx->pBt,
BTREE_OMIT_JOURNAL | BTREE_SINGLE | pOp->p5, vfsFlags);
if( rc==SQLITE_OK ){
- rc = sqlite3BtreeBeginTrans(u.az.pCx->pBt, 1);
+ rc = sqlite3BtreeBeginTrans(pCx->pBt, 1);
}
if( rc==SQLITE_OK ){
/* If a transient index is required, create it by calling
@@ -67254,60 +77180,78 @@ case OP_OpenEphemeral: {
** 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 ){
+ if( (pKeyInfo = pOp->p4.pKeyInfo)!=0 ){
int pgno;
assert( pOp->p4type==P4_KEYINFO );
- rc = sqlite3BtreeCreateTable(u.az.pCx->pBt, &pgno, BTREE_BLOBKEY | pOp->p5);
+ rc = sqlite3BtreeCreateTable(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);
+ assert( pKeyInfo->db==db );
+ assert( pKeyInfo->enc==ENC(db) );
+ pCx->pKeyInfo = pKeyInfo;
+ rc = sqlite3BtreeCursor(pCx->pBt, pgno, BTREE_WRCSR,
+ pKeyInfo, pCx->uc.pCursor);
}
- u.az.pCx->isTable = 0;
+ pCx->isTable = 0;
}else{
- rc = sqlite3BtreeCursor(u.az.pCx->pBt, MASTER_ROOT, 1, 0, u.az.pCx->pCursor);
- u.az.pCx->isTable = 1;
+ rc = sqlite3BtreeCursor(pCx->pBt, MASTER_ROOT, BTREE_WRCSR,
+ 0, pCx->uc.pCursor);
+ pCx->isTable = 1;
}
}
- u.az.pCx->isOrdered = (pOp->p5!=BTREE_UNORDERED);
- u.az.pCx->isIndex = !u.az.pCx->isTable;
+ pCx->isOrdered = (pOp->p5!=BTREE_UNORDERED);
break;
}
-/* Opcode: SorterOpen P1 P2 * P4 *
+/* Opcode: SorterOpen P1 P2 P3 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.
+**
+** If argument P3 is non-zero, then it indicates that the sorter may
+** assume that a stable sort considering the first P3 fields of each
+** key is sufficient to produce the required results.
*/
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
+
+ assert( pOp->p1>=0 );
+ assert( pOp->p2>=0 );
+ pCx = allocateCursor(p, pOp->p1, pOp->p2, -1, CURTYPE_SORTER);
+ if( pCx==0 ) goto no_mem;
+ pCx->pKeyInfo = pOp->p4.pKeyInfo;
+ assert( pCx->pKeyInfo->db==db );
+ assert( pCx->pKeyInfo->enc==ENC(db) );
+ rc = sqlite3VdbeSorterInit(db, pOp->p3, pCx);
break;
}
-/* Opcode: OpenPseudo P1 P2 P3 * P5
+/* Opcode: SequenceTest P1 P2 * * *
+** Synopsis: if( cursor[P1].ctr++ ) pc = P2
+**
+** P1 is a sorter cursor. If the sequence counter is currently zero, jump
+** to P2. Regardless of whether or not the jump is taken, increment the
+** the sequence value.
+*/
+case OP_SequenceTest: {
+ VdbeCursor *pC;
+ assert( pOp->p1>=0 && pOp->p1<p->nCursor );
+ pC = p->apCsr[pOp->p1];
+ assert( isSorter(pC) );
+ if( (pC->seqCount++)==0 ){
+ goto jump_to_p2;
+ }
+ break;
+}
+
+/* Opcode: OpenPseudo P1 P2 P3 * *
+** Synopsis: P3 columns in r[P2]
**
** 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.
+** row of data. The content of that one row is the content of memory
+** register P2. In other words, cursor P1 becomes an alias for the
+** MEM_Blob content contained in register 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
@@ -67318,18 +77262,16 @@ case OP_SorterOpen: {
** 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;
+ assert( pOp->p3>=0 );
+ pCx = allocateCursor(p, pOp->p1, pOp->p3, -1, CURTYPE_PSEUDO);
+ if( pCx==0 ) goto no_mem;
+ pCx->nullRow = 1;
+ pCx->uc.pseudoTableReg = pOp->p2;
+ pCx->isTable = 1;
+ assert( pOp->p5==0 );
break;
}
@@ -67345,7 +77287,28 @@ case OP_Close: {
break;
}
-/* Opcode: SeekGe P1 P2 P3 P4 *
+#ifdef SQLITE_ENABLE_COLUMN_USED_MASK
+/* Opcode: ColumnsUsed P1 * * P4 *
+**
+** This opcode (which only exists if SQLite was compiled with
+** SQLITE_ENABLE_COLUMN_USED_MASK) identifies which columns of the
+** table or index for cursor P1 are used. P4 is a 64-bit integer
+** (P4_INT64) in which the first 63 bits are one for each of the
+** first 63 columns of the table or index that are actually used
+** by the cursor. The high-order bit is set if any column after
+** the 64th is used.
+*/
+case OP_ColumnsUsed: {
+ VdbeCursor *pC;
+ pC = p->apCsr[pOp->p1];
+ assert( pC->eCurType==CURTYPE_BTREE );
+ pC->maskUsed = *(u64*)pOp->p4.pI64;
+ break;
+}
+#endif
+
+/* Opcode: SeekGE P1 P2 P3 P4 *
+** Synopsis: key=r[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
@@ -67356,9 +77319,21 @@ case OP_Close: {
** 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
+** If the cursor P1 was opened using the OPFLAG_SEEKEQ flag, then this
+** opcode will always land on a record that equally equals the key, or
+** else jump immediately to P2. When the cursor is OPFLAG_SEEKEQ, this
+** opcode must be followed by an IdxLE opcode with the same arguments.
+** The IdxLE opcode will be skipped if this opcode succeeds, but the
+** IdxLE opcode will be used on subsequent loop iterations.
+**
+** This opcode leaves the cursor configured to move in forward order,
+** from the beginning toward the end. In other words, the cursor is
+** configured to use Next, not Prev.
+**
+** See also: Found, NotFound, SeekLt, SeekGt, SeekLe
*/
-/* Opcode: SeekGt P1 P2 P3 P4 *
+/* Opcode: SeekGT P1 P2 P3 P4 *
+** Synopsis: key=r[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
@@ -67369,9 +77344,14 @@ case OP_Close: {
** 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
+** This opcode leaves the cursor configured to move in forward order,
+** from the beginning toward the end. In other words, the cursor is
+** configured to use Next, not Prev.
+**
+** See also: Found, NotFound, SeekLt, SeekGe, SeekLe
*/
-/* Opcode: SeekLt P1 P2 P3 P4 *
+/* Opcode: SeekLT P1 P2 P3 P4 *
+** Synopsis: key=r[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
@@ -67382,9 +77362,14 @@ case OP_Close: {
** 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
+** This opcode leaves the cursor configured to move in reverse order,
+** from the end toward the beginning. In other words, the cursor is
+** configured to use Prev, not Next.
+**
+** See also: Found, NotFound, SeekGt, SeekGe, SeekLe
*/
-/* Opcode: SeekLe P1 P2 P3 P4 *
+/* Opcode: SeekLE P1 P2 P3 P4 *
+** Synopsis: key=r[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
@@ -67395,163 +77380,188 @@ case OP_Close: {
** 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 */
+** This opcode leaves the cursor configured to move in reverse order,
+** from the end toward the beginning. In other words, the cursor is
+** configured to use Prev, not Next.
+**
+** If the cursor P1 was opened using the OPFLAG_SEEKEQ flag, then this
+** opcode will always land on a record that equally equals the key, or
+** else jump immediately to P2. When the cursor is OPFLAG_SEEKEQ, this
+** opcode must be followed by an IdxGE opcode with the same arguments.
+** The IdxGE opcode will be skipped if this opcode succeeds, but the
+** IdxGE opcode will be used on subsequent loop iterations.
+**
+** See also: Found, NotFound, SeekGt, SeekGe, SeekLt
+*/
+case OP_SeekLT: /* jump, in3 */
+case OP_SeekLE: /* jump, in3 */
+case OP_SeekGE: /* jump, in3 */
+case OP_SeekGT: { /* jump, in3 */
+ int res; /* Comparison result */
+ int oc; /* Opcode */
+ VdbeCursor *pC; /* The cursor to seek */
+ UnpackedRecord r; /* The key to seek for */
+ int nField; /* Number of columns or fields in the key */
+ i64 iKey; /* The rowid we are to seek to */
+ int eqOnly; /* Only interested in == results */
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--;
- }
+ pC = p->apCsr[pOp->p1];
+ assert( pC!=0 );
+ assert( pC->eCurType==CURTYPE_BTREE );
+ assert( OP_SeekLE == OP_SeekLT+1 );
+ assert( OP_SeekGE == OP_SeekLT+2 );
+ assert( OP_SeekGT == OP_SeekLT+3 );
+ assert( pC->isOrdered );
+ assert( pC->uc.pCursor!=0 );
+ oc = pOp->opcode;
+ eqOnly = 0;
+ pC->nullRow = 0;
+#ifdef SQLITE_DEBUG
+ pC->seekOp = pOp->opcode;
+#endif
+
+ if( pC->isTable ){
+ /* The BTREE_SEEK_EQ flag is only set on index cursors */
+ assert( sqlite3BtreeCursorHasHint(pC->uc.pCursor, BTREE_SEEK_EQ)==0 );
+
+ /* 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 convert it. */
+ pIn3 = &aMem[pOp->p3];
+ if( (pIn3->flags & (MEM_Int|MEM_Real|MEM_Str))==MEM_Str ){
+ applyNumericAffinity(pIn3, 0);
+ }
+ iKey = sqlite3VdbeIntValue(pIn3);
+
+ /* 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 */
+ VdbeBranchTaken(1,2); goto jump_to_p2;
+ break;
}
- 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 the approximation iKey is larger than the actual real search
+ ** term, substitute >= for > and < for <=. e.g. if the search term
+ ** is 4.9 and the integer approximation 5:
+ **
+ ** (x > 4.9) -> (x >= 5)
+ ** (x <= 4.9) -> (x < 5)
+ */
+ if( pIn3->u.r<(double)iKey ){
+ assert( OP_SeekGE==(OP_SeekGT-1) );
+ assert( OP_SeekLT==(OP_SeekLE-1) );
+ assert( (OP_SeekLE & 0x0001)==(OP_SeekGT & 0x0001) );
+ if( (oc & 0x0001)==(OP_SeekGT & 0x0001) ) oc--;
}
- if( u.bc.res==0 ){
- u.bc.pC->rowidIsValid = 1;
- u.bc.pC->lastRowid = u.bc.iKey;
+
+ /* If the approximation iKey is smaller than the actual real search
+ ** term, substitute <= for < and > for >=. */
+ else if( pIn3->u.r>(double)iKey ){
+ assert( OP_SeekLE==(OP_SeekLT+1) );
+ assert( OP_SeekGT==(OP_SeekGE+1) );
+ assert( (OP_SeekLT & 0x0001)==(OP_SeekGE & 0x0001) );
+ if( (oc & 0x0001)==(OP_SeekLT & 0x0001) ) oc++;
}
- }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;
+ }
+ rc = sqlite3BtreeMovetoUnpacked(pC->uc.pCursor, 0, (u64)iKey, 0, &res);
+ pC->movetoTarget = iKey; /* Used by OP_Delete */
+ if( rc!=SQLITE_OK ){
+ goto abort_due_to_error;
+ }
+ }else{
+ /* For a cursor with the BTREE_SEEK_EQ hint, only the OP_SeekGE and
+ ** OP_SeekLE opcodes are allowed, and these must be immediately followed
+ ** by an OP_IdxGT or OP_IdxLT opcode, respectively, with the same key.
+ */
+ if( sqlite3BtreeCursorHasHint(pC->uc.pCursor, BTREE_SEEK_EQ) ){
+ eqOnly = 1;
+ assert( pOp->opcode==OP_SeekGE || pOp->opcode==OP_SeekLE );
+ assert( pOp[1].opcode==OP_IdxLT || pOp[1].opcode==OP_IdxGT );
+ assert( pOp[1].p1==pOp[0].p1 );
+ assert( pOp[1].p2==pOp[0].p2 );
+ assert( pOp[1].p3==pOp[0].p3 );
+ assert( pOp[1].p4.i==pOp[0].p4.i );
+ }
- /* 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 );
+ nField = pOp->p4.i;
+ assert( pOp->p4type==P4_INT32 );
+ assert( nField>0 );
+ r.pKeyInfo = pC->pKeyInfo;
+ r.nField = (u16)nField;
+
+ /* The next line of code computes as follows, only faster:
+ ** if( oc==OP_SeekGT || oc==OP_SeekLE ){
+ ** r.default_rc = -1;
+ ** }else{
+ ** r.default_rc = +1;
+ ** }
+ */
+ r.default_rc = ((1 & (oc - OP_SeekLT)) ? -1 : +1);
+ assert( oc!=OP_SeekGT || r.default_rc==-1 );
+ assert( oc!=OP_SeekLE || r.default_rc==-1 );
+ assert( oc!=OP_SeekGE || r.default_rc==+1 );
+ assert( oc!=OP_SeekLT || r.default_rc==+1 );
- u.bc.r.aMem = &aMem[pOp->p3];
+ 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]) ); }
+ { int i; for(i=0; i<r.nField; i++) assert( memIsValid(&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;
+ ExpandBlob(r.aMem);
+ r.eqSeen = 0;
+ rc = sqlite3BtreeMovetoUnpacked(pC->uc.pCursor, &r, 0, 0, &res);
+ if( rc!=SQLITE_OK ){
+ goto abort_due_to_error;
+ }
+ if( eqOnly && r.eqSeen==0 ){
+ assert( res!=0 );
+ goto seek_not_found;
}
- u.bc.pC->deferredMoveto = 0;
- u.bc.pC->cacheStatus = CACHE_STALE;
+ }
+ pC->deferredMoveto = 0;
+ pC->cacheStatus = CACHE_STALE;
#ifdef SQLITE_TEST
- sqlite3_search_count++;
+ 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;
- }
+ if( oc>=OP_SeekGE ){ assert( oc==OP_SeekGE || oc==OP_SeekGT );
+ if( res<0 || (res==0 && oc==OP_SeekGT) ){
+ res = 0;
+ rc = sqlite3BtreeNext(pC->uc.pCursor, &res);
+ if( rc!=SQLITE_OK ) goto abort_due_to_error;
}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;
+ res = 0;
}
}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;
+ assert( oc==OP_SeekLT || oc==OP_SeekLE );
+ if( res>0 || (res==0 && oc==OP_SeekLT) ){
+ res = 0;
+ rc = sqlite3BtreePrevious(pC->uc.pCursor, &res);
+ if( rc!=SQLITE_OK ) goto abort_due_to_error;
+ }else{
+ /* res might be negative because the table is empty. Check to
+ ** see if this is the case.
+ */
+ res = sqlite3BtreeEof(pC->uc.pCursor);
+ }
+ }
+seek_not_found:
+ assert( pOp->p2>0 );
+ VdbeBranchTaken(res!=0,2);
+ if( res ){
+ goto jump_to_p2;
+ }else if( eqOnly ){
+ assert( pOp[1].opcode==OP_IdxLT || pOp[1].opcode==OP_IdxGT );
+ pOp++; /* Skip the OP_IdxLt or OP_IdxGT that follows */
}
break;
}
/* Opcode: Seek P1 P2 * * *
+** Synopsis: intkey=r[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.
@@ -67561,26 +77571,24 @@ case OP_SeekGt: { /* jump, in3 */
** 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;
- }
+ pC = p->apCsr[pOp->p1];
+ assert( pC!=0 );
+ assert( pC->eCurType==CURTYPE_BTREE );
+ assert( pC->uc.pCursor!=0 );
+ assert( pC->isTable );
+ pC->nullRow = 0;
+ pIn2 = &aMem[pOp->p2];
+ pC->movetoTarget = sqlite3VdbeIntValue(pIn2);
+ pC->deferredMoveto = 1;
break;
}
/* Opcode: Found P1 P2 P3 P4 *
+** Synopsis: key=r[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
@@ -67589,8 +77597,15 @@ case OP_Seek: { /* in2 */
** 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.
+**
+** This operation leaves the cursor in a state where it can be
+** advanced in the forward direction. The Next instruction will work,
+** but not the Prev instruction.
+**
+** See also: NotFound, NoConflict, NotExists. SeekGe
*/
/* Opcode: NotFound P1 P2 P3 P4 *
+** Synopsis: key=r[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
@@ -67602,231 +77617,196 @@ case OP_Seek: { /* in2 */
** falls through to the next instruction and P1 is left pointing at the
** matching entry.
**
-** See also: Found, NotExists, IsUnique
+** This operation leaves the cursor in a state where it cannot be
+** advanced in either direction. In other words, the Next and Prev
+** opcodes do not work after this operation.
+**
+** See also: Found, NotExists, NoConflict
*/
+/* Opcode: NoConflict P1 P2 P3 P4 *
+** Synopsis: key=r[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
+** contains any NULL value, jump immediately to P2. If all terms of the
+** record are not-NULL then a check is done to determine if any row in the
+** P1 index btree has a matching key prefix. If there are no matches, jump
+** immediately to P2. If there is a match, fall through and leave the P1
+** cursor pointing to the matching row.
+**
+** This opcode is similar to OP_NotFound with the exceptions that the
+** branch is always taken if any part of the search key input is NULL.
+**
+** This operation leaves the cursor in a state where it cannot be
+** advanced in either direction. In other words, the Next and Prev
+** opcodes do not work after this operation.
+**
+** See also: NotFound, Found, NotExists
+*/
+case OP_NoConflict: /* jump, in3 */
case OP_NotFound: /* jump, in3 */
case OP_Found: { /* jump, in3 */
-#if 0 /* local variables moved into u.be */
int alreadyExists;
+ int takeJump;
+ int ii;
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 */
+ char aTempRec[ROUND8(sizeof(UnpackedRecord)) + sizeof(Mem)*4 + 7];
#ifdef SQLITE_TEST
- sqlite3_found_count++;
+ if( pOp->opcode!=OP_NoConflict ) 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 );
+ pC = p->apCsr[pOp->p1];
+ assert( pC!=0 );
+#ifdef SQLITE_DEBUG
+ pC->seekOp = pOp->opcode;
+#endif
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;
+ assert( pC->eCurType==CURTYPE_BTREE );
+ assert( pC->uc.pCursor!=0 );
+ assert( pC->isTable==0 );
+ pFree = 0;
+ if( pOp->p4.i>0 ){
+ r.pKeyInfo = pC->pKeyInfo;
+ r.nField = (u16)pOp->p4.i;
+ r.aMem = pIn3;
+ for(ii=0; ii<r.nField; ii++){
+ assert( memIsValid(&r.aMem[ii]) );
+ ExpandBlob(&r.aMem[ii]);
#ifdef SQLITE_DEBUG
- { int i; for(i=0; i<u.be.r.nField; i++) assert( memIsValid(&u.be.r.aMem[i]) ); }
+ if( ii ) REGISTER_TRACE(pOp->p3+ii, &r.aMem[ii]);
#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;
+ pIdxKey = &r;
+ }else{
+ pIdxKey = sqlite3VdbeAllocUnpackedRecord(
+ pC->pKeyInfo, aTempRec, sizeof(aTempRec), &pFree
+ );
+ if( pIdxKey==0 ) goto no_mem;
+ assert( pIn3->flags & MEM_Blob );
+ ExpandBlob(pIn3);
+ sqlite3VdbeRecordUnpack(pC->pKeyInfo, pIn3->n, pIn3->z, pIdxKey);
+ }
+ pIdxKey->default_rc = 0;
+ takeJump = 0;
+ if( pOp->opcode==OP_NoConflict ){
+ /* For the OP_NoConflict opcode, take the jump if any of the
+ ** input fields are NULL, since any key with a NULL will not
+ ** conflict */
+ for(ii=0; ii<pIdxKey->nField; ii++){
+ if( pIdxKey->aMem[ii].flags & MEM_Null ){
+ takeJump = 1;
+ break;
+ }
}
- u.be.alreadyExists = (u.be.res==0);
- u.be.pC->deferredMoveto = 0;
- u.be.pC->cacheStatus = CACHE_STALE;
}
+ rc = sqlite3BtreeMovetoUnpacked(pC->uc.pCursor, pIdxKey, 0, 0, &res);
+ sqlite3DbFree(db, pFree);
+ if( rc!=SQLITE_OK ){
+ break;
+ }
+ pC->seekResult = res;
+ alreadyExists = (res==0);
+ pC->nullRow = 1-alreadyExists;
+ pC->deferredMoveto = 0;
+ pC->cacheStatus = CACHE_STALE;
if( pOp->opcode==OP_Found ){
- if( u.be.alreadyExists ) pc = pOp->p2 - 1;
+ VdbeBranchTaken(alreadyExists!=0,2);
+ if( alreadyExists ) goto jump_to_p2;
}else{
- if( !u.be.alreadyExists ) pc = pOp->p2 - 1;
+ VdbeBranchTaken(takeJump||alreadyExists==0,2);
+ if( takeJump || !alreadyExists ) goto jump_to_p2;
}
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.
+/* Opcode: NotExists P1 P2 P3 * *
+** Synopsis: intkey=r[P3]
**
-** 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
+** P1 is the index of a cursor open on an SQL table btree (with integer
+** keys). P3 is an integer rowid. If P1 does not contain a record with
+** rowid P3 then jump immediately to P2. Or, if P2 is 0, raise an
+** SQLITE_CORRUPT error. If P1 does contain a record with rowid P3 then
+** leave the cursor pointing at that record and fall 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 OP_NotFound opcode performs the same operation on index btrees
+** (with arbitrary multi-value keys).
**
-** 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.
+** This opcode leaves the cursor in a state where it cannot be advanced
+** in either direction. In other words, the Next and Prev opcodes will
+** not work following this opcode.
**
-** See also: Found, NotFound, IsUnique
+** See also: Found, NotFound, NoConflict
*/
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;
+ pC = p->apCsr[pOp->p1];
+ assert( pC!=0 );
+#ifdef SQLITE_DEBUG
+ pC->seekOp = 0;
+#endif
+ assert( pC->isTable );
+ assert( pC->eCurType==CURTYPE_BTREE );
+ pCrsr = pC->uc.pCursor;
+ assert( pCrsr!=0 );
+ res = 0;
+ iKey = pIn3->u.i;
+ rc = sqlite3BtreeMovetoUnpacked(pCrsr, 0, iKey, 0, &res);
+ assert( rc==SQLITE_OK || res==0 );
+ pC->movetoTarget = iKey; /* Used by OP_Delete */
+ pC->nullRow = 0;
+ pC->cacheStatus = CACHE_STALE;
+ pC->deferredMoveto = 0;
+ VdbeBranchTaken(res!=0,2);
+ pC->seekResult = res;
+ if( res!=0 ){
+ assert( rc==SQLITE_OK );
+ if( pOp->p2==0 ){
+ rc = SQLITE_CORRUPT_BKPT;
+ }else{
+ goto jump_to_p2;
+ }
}
break;
}
/* Opcode: Sequence P1 P2 * * *
+** Synopsis: r[P2]=cursor[P1].ctr++
**
** 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 */
+case OP_Sequence: { /* out2 */
assert( pOp->p1>=0 && pOp->p1<p->nCursor );
assert( p->apCsr[pOp->p1]!=0 );
+ assert( p->apCsr[pOp->p1]->eCurType!=CURTYPE_VTAB );
+ pOut = out2Prerelease(p, pOp);
pOut->u.i = p->apCsr[pOp->p1]->seqCount++;
break;
}
/* Opcode: NewRowid P1 P2 P3 * *
+** Synopsis: r[P2]=rowid
**
** 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
@@ -67840,24 +77820,23 @@ case OP_Sequence: { /* out2-prerelease */
** 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 */
+case OP_NewRowid: { /* out2 */
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;
+ v = 0;
+ res = 0;
+ pOut = out2Prerelease(p, pOp);
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{
+ pC = p->apCsr[pOp->p1];
+ assert( pC!=0 );
+ assert( pC->eCurType==CURTYPE_BTREE );
+ assert( pC->uc.pCursor!=0 );
+ {
/* The next rowid or record number (different terms for the same
** thing) is obtained in a two-step algorithm.
**
@@ -67871,7 +77850,7 @@ case OP_NewRowid: { /* out2-prerelease */
** succeeded. If the random rowid does exist, we select a new one
** and try again, up to 100 times.
*/
- assert( u.bh.pC->isTable );
+ assert( pC->isTable );
#ifdef SQLITE_32BIT_ROWID
# define MAX_ROWID 0x7fffffff
@@ -67883,101 +77862,85 @@ case OP_NewRowid: { /* out2-prerelease */
# 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 */
+ if( !pC->useRandomRowid ){
+ rc = sqlite3BtreeLast(pC->uc.pCursor, &res);
+ if( rc!=SQLITE_OK ){
+ goto abort_due_to_error;
+ }
+ if( res ){
+ v = 1; /* IMP: R-61914-48074 */
+ }else{
+ assert( sqlite3BtreeCursorIsValid(pC->uc.pCursor) );
+ rc = sqlite3BtreeKeySize(pC->uc.pCursor, &v);
+ assert( rc==SQLITE_OK ); /* Cannot fail following BtreeLast() */
+ if( v>=MAX_ROWID ){
+ pC->useRandomRowid = 1;
}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 */
- }
+ v++; /* IMP: R-29538-34987 */
}
}
+ }
#ifndef SQLITE_OMIT_AUTOINCREMENT
- if( pOp->p3 ){
+ if( pOp->p3 ){
+ /* Assert that P3 is a valid memory cell. */
+ assert( pOp->p3>0 );
+ if( p->pFrame ){
+ for(pFrame=p->pFrame; pFrame->pParent; pFrame=pFrame->pParent);
/* 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;
+ assert( pOp->p3<=pFrame->nMem );
+ pMem = &pFrame->aMem[pOp->p3];
+ }else{
+ /* Assert that P3 is a valid memory cell. */
+ assert( pOp->p3<=(p->nMem-p->nCursor) );
+ pMem = &aMem[pOp->p3];
+ memAboutToChange(p, pMem);
}
-#endif
+ assert( memIsValid(pMem) );
- sqlite3BtreeSetCachedRowid(u.bh.pC->pCursor, u.bh.v<MAX_ROWID ? u.bh.v+1 : 0);
+ REGISTER_TRACE(pOp->p3, pMem);
+ sqlite3VdbeMemIntegerify(pMem);
+ assert( (pMem->flags & MEM_Int)!=0 ); /* mem(P3) holds an integer */
+ if( pMem->u.i==MAX_ROWID || pC->useRandomRowid ){
+ rc = SQLITE_FULL; /* IMP: R-12275-61338 */
+ goto abort_due_to_error;
+ }
+ if( v<pMem->u.i+1 ){
+ v = pMem->u.i + 1;
+ }
+ pMem->u.i = v;
}
- if( u.bh.pC->useRandomRowid ){
+#endif
+ if( 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 ){
+ cnt = 0;
+ do{
+ sqlite3_randomness(sizeof(v), &v);
+ v &= (MAX_ROWID>>1); v++; /* Ensure that v is greater than zero */
+ }while( ((rc = sqlite3BtreeMovetoUnpacked(pC->uc.pCursor, 0, (u64)v,
+ 0, &res))==SQLITE_OK)
+ && (res==0)
+ && (++cnt<100));
+ if( rc==SQLITE_OK && res==0 ){
rc = SQLITE_FULL; /* IMP: R-38219-53002 */
goto abort_due_to_error;
}
- assert( u.bh.v>0 ); /* EV: R-40812-03570 */
+ assert( v>0 ); /* EV: R-40812-03570 */
}
- u.bh.pC->rowidIsValid = 0;
- u.bh.pC->deferredMoveto = 0;
- u.bh.pC->cacheStatus = CACHE_STALE;
+ pC->deferredMoveto = 0;
+ pC->cacheStatus = CACHE_STALE;
}
- pOut->u.i = u.bh.v;
+ pOut->u.i = v;
break;
}
/* Opcode: Insert P1 P2 P3 P4 P5
+** Synopsis: intkey=r[P3] data=r[P2]
**
** 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
@@ -68017,13 +77980,13 @@ case OP_NewRowid: { /* out2-prerelease */
** for indices is OP_IdxInsert.
*/
/* Opcode: InsertInt P1 P2 P3 P4 P5
+** Synopsis: intkey=P3 data=r[P2]
**
** 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 */
@@ -68033,72 +77996,70 @@ case OP_InsertInt: {
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];
+ 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);
+ assert( memIsValid(pData) );
+ pC = p->apCsr[pOp->p1];
+ assert( pC!=0 );
+ assert( pC->eCurType==CURTYPE_BTREE );
+ assert( pC->uc.pCursor!=0 );
+ assert( pC->isTable );
+ REGISTER_TRACE(pOp->p2, 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;
+ pKey = &aMem[pOp->p3];
+ assert( pKey->flags & MEM_Int );
+ assert( memIsValid(pKey) );
+ REGISTER_TRACE(pOp->p3, pKey);
+ iKey = pKey->u.i;
}else{
assert( pOp->opcode==OP_InsertInt );
- u.bi.iKey = pOp->p3;
+ 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;
+ if( pOp->p5 & OPFLAG_LASTROWID ) db->lastRowid = lastRowid = iKey;
+ if( pData->flags & MEM_Null ){
+ pData->z = 0;
+ pData->n = 0;
}else{
- assert( u.bi.pData->flags & (MEM_Blob|MEM_Str) );
+ assert( 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;
+ seekResult = ((pOp->p5 & OPFLAG_USESEEKRESULT) ? pC->seekResult : 0);
+ if( pData->flags & MEM_Zero ){
+ nZero = pData->u.nZero;
}else{
- u.bi.nZero = 0;
+ 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
+ rc = sqlite3BtreeInsert(pC->uc.pCursor, 0, iKey,
+ pData->z, pData->n, nZero,
+ (pOp->p5 & OPFLAG_APPEND)!=0, seekResult
);
- u.bi.pC->rowidIsValid = 0;
- u.bi.pC->deferredMoveto = 0;
- u.bi.pC->cacheStatus = CACHE_STALE;
+ pC->deferredMoveto = 0;
+ 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 );
+ zDb = db->aDb[pC->iDb].zName;
+ zTbl = pOp->p4.z;
+ op = ((pOp->p5 & OPFLAG_ISUPDATE) ? SQLITE_UPDATE : SQLITE_INSERT);
+ assert( pC->isTable );
+ db->xUpdateCallback(db->pUpdateArg, op, zDb, zTbl, iKey);
+ assert( pC->iDb>=0 );
}
break;
}
-/* Opcode: Delete P1 P2 * P4 *
+/* Opcode: Delete P1 P2 * P4 P5
**
** 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 P5 parameter is non-zero, 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. As a result, in this case it is OK to delete a record from within a
+** Next loop. If P5 is zero, then the cursor is left in an undefined state.
**
** If the OPFLAG_NCHANGE flag of P2 is set, then the row change count is
** incremented (otherwise not).
@@ -68112,47 +78073,40 @@ case OP_InsertInt: {
** 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 */
+ u8 hasUpdateCallback;
- 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 */
+ pC = p->apCsr[pOp->p1];
+ assert( pC!=0 );
+ assert( pC->eCurType==CURTYPE_BTREE );
+ assert( pC->uc.pCursor!=0 );
+ assert( pC->deferredMoveto==0 );
- /* 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;
+ hasUpdateCallback = db->xUpdateCallback && pOp->p4.z && pC->isTable;
+ if( pOp->p5 && hasUpdateCallback ){
+ sqlite3BtreeKeySize(pC->uc.pCursor, &pC->movetoTarget);
}
- /* 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;
+#ifdef SQLITE_DEBUG
+ /* The seek operation that positioned the cursor prior to OP_Delete will
+ ** have also set the pC->movetoTarget field to the rowid of the row that
+ ** is being deleted */
+ if( pOp->p4.z && pC->isTable && pOp->p5==0 ){
+ i64 iKey = 0;
+ sqlite3BtreeKeySize(pC->uc.pCursor, &iKey);
+ assert( pC->movetoTarget==iKey );
+ }
+#endif
+
+ rc = sqlite3BtreeDelete(pC->uc.pCursor, pOp->p5);
+ 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( rc==SQLITE_OK && hasUpdateCallback ){
+ db->xUpdateCallback(db->pUpdateArg, SQLITE_DELETE,
+ db->aDb[pC->iDb].zName, pOp->p4.z, pC->movetoTarget);
+ assert( pC->iDb>=0 );
}
if( pOp->p2 & OPFLAG_NCHANGE ) p->nChange++;
break;
@@ -68170,51 +78124,65 @@ case OP_ResetCount: {
break;
}
-/* Opcode: SorterCompare P1 P2 P3
+/* Opcode: SorterCompare P1 P2 P3 P4
+** Synopsis: if key(P1)!=trim(r[P3],P4) goto P2
+**
+** P1 is a sorter cursor. This instruction compares a prefix of the
+** record blob in register P3 against a prefix of the entry that
+** the sorter cursor currently points to. Only the first P4 fields
+** of r[P3] and the sorter record are compared.
+**
+** If either P3 or the sorter contains a NULL in one of their significant
+** fields (not counting the P4 fields at the end which are ignored) then
+** the comparison is assumed to be equal.
**
-** 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.
+** Fall through to next instruction if the two records compare equal to
+** each other. Jump to P2 if they are different.
*/
case OP_SorterCompare: {
-#if 0 /* local variables moved into u.bk */
VdbeCursor *pC;
int res;
-#endif /* local variables moved into u.bk */
+ int nKeyCol;
- u.bk.pC = p->apCsr[pOp->p1];
- assert( isSorter(u.bk.pC) );
+ pC = p->apCsr[pOp->p1];
+ assert( isSorter(pC) );
+ assert( pOp->p4type==P4_INT32 );
pIn3 = &aMem[pOp->p3];
- rc = sqlite3VdbeSorterCompare(u.bk.pC, pIn3, &u.bk.res);
- if( u.bk.res ){
- pc = pOp->p2-1;
- }
+ nKeyCol = pOp->p4.i;
+ res = 0;
+ rc = sqlite3VdbeSorterCompare(pC, pIn3, nKeyCol, &res);
+ VdbeBranchTaken(res!=0,2);
+ if( res ) goto jump_to_p2;
break;
};
-/* Opcode: SorterData P1 P2 * * *
+/* Opcode: SorterData P1 P2 P3 * *
+** Synopsis: r[P2]=data
**
** Write into register P2 the current sorter data for sorter cursor P1.
+** Then clear the column header cache on cursor P3.
+**
+** This opcode is normally use to move a record out of the sorter and into
+** a register that is the source for a pseudo-table cursor created using
+** OpenPseudo. That pseudo-table cursor is the one that is identified by
+** parameter P3. Clearing the P3 column cache as part of this opcode saves
+** us from having to issue a separate NullRow instruction to clear that cache.
*/
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
+ pC = p->apCsr[pOp->p1];
+ assert( isSorter(pC) );
+ rc = sqlite3VdbeSorterRowkey(pC, pOut);
+ assert( rc!=SQLITE_OK || (pOut->flags & MEM_Blob) );
+ assert( pOp->p1>=0 && pOp->p1<p->nCursor );
+ p->apCsr[pOp->p3]->cacheStatus = CACHE_STALE;
break;
}
/* Opcode: RowData P1 P2 * * *
+** Synopsis: r[P2]=data
**
** Write into register P2 the complete row data for cursor P1.
** There is no interpretation of the data.
@@ -68225,10 +78193,11 @@ case OP_SorterData: {
** of a real table, not a pseudo-table.
*/
/* Opcode: RowKey P1 P2 * * *
+** Synopsis: r[P2]=key
**
** 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
+** The key is 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)
@@ -68236,69 +78205,74 @@ case OP_SorterData: {
*/
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) );
+ pC = p->apCsr[pOp->p1];
+ assert( pC!=0 );
+ assert( pC->eCurType==CURTYPE_BTREE );
+ assert( isSorter(pC)==0 );
+ assert( pC->isTable || pOp->opcode!=OP_RowData );
+ assert( pC->isTable==0 || pOp->opcode==OP_RowData );
+ assert( pC->nullRow==0 );
+ assert( pC->uc.pCursor!=0 );
+ pCrsr = pC->uc.pCursor;
/* 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.
+ ** the cursor. If this where not the case, on of the following assert()s
+ ** would fail. Should this ever change (because of changes in the code
+ ** generator) then the fix would be to insert a call to
+ ** sqlite3VdbeCursorMoveto().
*/
- assert( u.bm.pC->deferredMoveto==0 );
- rc = sqlite3VdbeCursorMoveto(u.bm.pC);
- if( NEVER(rc!=SQLITE_OK) ) goto abort_due_to_error;
+ assert( pC->deferredMoveto==0 );
+ assert( sqlite3BtreeCursorIsValid(pCrsr) );
+#if 0 /* Not required due to the previous to assert() statements */
+ rc = sqlite3VdbeCursorMoveto(pC);
+ if( rc!=SQLITE_OK ) goto abort_due_to_error;
+#endif
- if( u.bm.pC->isIndex ){
- assert( !u.bm.pC->isTable );
- VVA_ONLY(rc =) sqlite3BtreeKeySize(u.bm.pCrsr, &u.bm.n64);
+ if( pC->isTable==0 ){
+ assert( !pC->isTable );
+ VVA_ONLY(rc =) sqlite3BtreeKeySize(pCrsr, &n64);
assert( rc==SQLITE_OK ); /* True because of CursorMoveto() call above */
- if( u.bm.n64>db->aLimit[SQLITE_LIMIT_LENGTH] ){
+ if( n64>db->aLimit[SQLITE_LIMIT_LENGTH] ){
goto too_big;
}
- u.bm.n = (u32)u.bm.n64;
+ n = (u32)n64;
}else{
- VVA_ONLY(rc =) sqlite3BtreeDataSize(u.bm.pCrsr, &u.bm.n);
+ VVA_ONLY(rc =) sqlite3BtreeDataSize(pCrsr, &n);
assert( rc==SQLITE_OK ); /* DataSize() cannot fail */
- if( u.bm.n>(u32)db->aLimit[SQLITE_LIMIT_LENGTH] ){
+ if( n>(u32)db->aLimit[SQLITE_LIMIT_LENGTH] ){
goto too_big;
}
}
- if( sqlite3VdbeMemGrow(pOut, u.bm.n, 0) ){
+ testcase( n==0 );
+ if( sqlite3VdbeMemClearAndResize(pOut, MAX(n,32)) ){
goto no_mem;
}
- pOut->n = u.bm.n;
+ pOut->n = n;
MemSetTypeFlag(pOut, MEM_Blob);
- if( u.bm.pC->isIndex ){
- rc = sqlite3BtreeKey(u.bm.pCrsr, 0, u.bm.n, pOut->z);
+ if( pC->isTable==0 ){
+ rc = sqlite3BtreeKey(pCrsr, 0, n, pOut->z);
}else{
- rc = sqlite3BtreeData(u.bm.pCrsr, 0, u.bm.n, pOut->z);
+ rc = sqlite3BtreeData(pCrsr, 0, n, pOut->z);
}
pOut->enc = SQLITE_UTF8; /* In case the blob is ever cast to text */
UPDATE_MAX_BLOBSIZE(pOut);
+ REGISTER_TRACE(pOp->p2, pOut);
break;
}
/* Opcode: Rowid P1 P2 * * *
+** Synopsis: r[P2]=rowid
**
** Store in register P2 an integer which is the key of the table entry that
** P1 is currently point to.
@@ -68307,43 +78281,44 @@ case OP_RowData: {
** 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 */
+case OP_Rowid: { /* out2 */
VdbeCursor *pC;
i64 v;
sqlite3_vtab *pVtab;
const sqlite3_module *pModule;
-#endif /* local variables moved into u.bn */
+ pOut = out2Prerelease(p, pOp);
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 ){
+ pC = p->apCsr[pOp->p1];
+ assert( pC!=0 );
+ assert( pC->eCurType!=CURTYPE_PSEUDO || pC->nullRow );
+ if( pC->nullRow ){
pOut->flags = MEM_Null;
break;
- }else if( u.bn.pC->deferredMoveto ){
- u.bn.v = u.bn.pC->movetoTarget;
+ }else if( pC->deferredMoveto ){
+ v = 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);
+ }else if( pC->eCurType==CURTYPE_VTAB ){
+ assert( pC->uc.pVCur!=0 );
+ pVtab = pC->uc.pVCur->pVtab;
+ pModule = pVtab->pModule;
+ assert( pModule->xRowid );
+ rc = pModule->xRowid(pC->uc.pVCur, &v);
+ sqlite3VtabImportErrmsg(p, pVtab);
#endif /* SQLITE_OMIT_VIRTUALTABLE */
}else{
- assert( u.bn.pC->pCursor!=0 );
- rc = sqlite3VdbeCursorMoveto(u.bn.pC);
+ assert( pC->eCurType==CURTYPE_BTREE );
+ assert( pC->uc.pCursor!=0 );
+ rc = sqlite3VdbeCursorRestore(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 */
+ if( pC->nullRow ){
+ pOut->flags = MEM_Null;
+ break;
}
+ rc = sqlite3BtreeKeySize(pC->uc.pCursor, &v);
+ assert( rc==SQLITE_OK ); /* Always so because of CursorRestore() above */
}
- pOut->u.i = u.bn.v;
+ pOut->u.i = v;
break;
}
@@ -68354,51 +78329,55 @@ case OP_Rowid: { /* out2-prerelease */
** 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);
+ pC = p->apCsr[pOp->p1];
+ assert( pC!=0 );
+ pC->nullRow = 1;
+ pC->cacheStatus = CACHE_STALE;
+ if( pC->eCurType==CURTYPE_BTREE ){
+ assert( pC->uc.pCursor!=0 );
+ sqlite3BtreeClearCursor(pC->uc.pCursor);
}
break;
}
-/* Opcode: Last P1 P2 * * *
+/* Opcode: Last P1 P2 P3 * *
**
-** The next use of the Rowid or Column or Next instruction for P1
+** The next use of the Rowid or Column or Prev 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.
+**
+** This opcode leaves the cursor configured to move in reverse order,
+** from the end toward the beginning. In other words, the cursor is
+** configured to use Prev, not Next.
*/
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;
+ pC = p->apCsr[pOp->p1];
+ assert( pC!=0 );
+ assert( pC->eCurType==CURTYPE_BTREE );
+ pCrsr = pC->uc.pCursor;
+ res = 0;
+ assert( pCrsr!=0 );
+ rc = sqlite3BtreeLast(pCrsr, &res);
+ pC->nullRow = (u8)res;
+ pC->deferredMoveto = 0;
+ pC->cacheStatus = CACHE_STALE;
+ pC->seekResult = pOp->p3;
+#ifdef SQLITE_DEBUG
+ pC->seekOp = OP_Last;
+#endif
+ if( pOp->p2>0 ){
+ VdbeBranchTaken(res!=0,2);
+ if( res ) goto jump_to_p2;
}
break;
}
@@ -68417,64 +78396,74 @@ case OP_Last: { /* jump */
** 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]++;
+ p->aCounter[SQLITE_STMTSTATUS_SORT]++;
/* 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.
+** If the table or index is empty, jump immediately to P2.
+** If the table or index is not empty, fall through to the following
+** instruction.
+**
+** This opcode leaves the cursor configured to move in forward order,
+** from the beginning toward the end. In other words, the cursor is
+** configured to use Next, not Prev.
*/
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;
+ pC = p->apCsr[pOp->p1];
+ assert( pC!=0 );
+ assert( isSorter(pC)==(pOp->opcode==OP_SorterSort) );
+ res = 1;
+#ifdef SQLITE_DEBUG
+ pC->seekOp = OP_Rewind;
+#endif
+ if( isSorter(pC) ){
+ rc = sqlite3VdbeSorterRewind(pC, &res);
+ }else{
+ assert( pC->eCurType==CURTYPE_BTREE );
+ pCrsr = pC->uc.pCursor;
+ assert( pCrsr );
+ rc = sqlite3BtreeFirst(pCrsr, &res);
+ pC->deferredMoveto = 0;
+ pC->cacheStatus = CACHE_STALE;
}
+ pC->nullRow = (u8)res;
+ assert( pOp->p2>0 && pOp->p2<p->nOp );
+ VdbeBranchTaken(res!=0,2);
+ if( res ) goto jump_to_p2;
break;
}
-/* Opcode: Next P1 P2 * P4 P5
+/* Opcode: Next P1 P2 P3 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.
+** The Next opcode is only valid following an SeekGT, SeekGE, or
+** OP_Rewind opcode used to position the cursor. Next is not allowed
+** to follow SeekLT, SeekLE, or OP_Last.
+**
+** The P1 cursor must be for a real table, not a pseudo-table. P1 must have
+** been opened prior to this opcode or the program will segfault.
+**
+** The P3 value is a hint to the btree implementation. If P3==1, that
+** means P1 is an SQL index and that this instruction could have been
+** omitted if that index had been unique. P3 is usually 0. P3 is
+** always either 0 or 1.
**
** P4 is always of type P4_ADVANCE. The function pointer points to
** sqlite3BtreeNext().
@@ -68482,16 +78471,32 @@ case OP_Rewind: { /* jump */
** If P5 is positive and the jump is taken, then event counter
** number P5-1 in the prepared statement is incremented.
**
-** See also: Prev
+** See also: Prev, NextIfOpen
+*/
+/* Opcode: NextIfOpen P1 P2 P3 P4 P5
+**
+** This opcode works just like Next except that if cursor P1 is not
+** open it behaves a no-op.
*/
-/* Opcode: Prev P1 P2 * * P5
+/* Opcode: Prev P1 P2 P3 P4 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.
+**
+** The Prev opcode is only valid following an SeekLT, SeekLE, or
+** OP_Last opcode used to position the cursor. Prev is not allowed
+** to follow SeekGT, SeekGE, or OP_Rewind.
+**
+** The P1 cursor must be for a real table, not a pseudo-table. If P1 is
+** not open then the behavior is undefined.
+**
+** The P3 value is a hint to the btree implementation. If P3==1, that
+** means P1 is an SQL index and that this instruction could have been
+** omitted if that index had been unique. P3 is usually 0. P3 is
+** always either 0 or 1.
**
** P4 is always of type P4_ADVANCE. The function pointer points to
** sqlite3BtreePrevious().
@@ -68499,50 +78504,68 @@ case OP_Rewind: { /* jump */
** 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 */
+/* Opcode: PrevIfOpen P1 P2 P3 P4 P5
+**
+** This opcode works just like Prev except that if cursor P1 is not
+** open it behaves a no-op.
+*/
+case OP_SorterNext: { /* jump */
VdbeCursor *pC;
int res;
-#endif /* local variables moved into u.br */
- CHECK_FOR_INTERRUPT;
+ pC = p->apCsr[pOp->p1];
+ assert( isSorter(pC) );
+ res = 0;
+ rc = sqlite3VdbeSorterNext(db, pC, &res);
+ goto next_tail;
+case OP_PrevIfOpen: /* jump */
+case OP_NextIfOpen: /* jump */
+ if( p->apCsr[pOp->p1]==0 ) break;
+ /* Fall through */
+case OP_Prev: /* jump */
+case OP_Next: /* jump */
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]++;
+ assert( pOp->p5<ArraySize(p->aCounter) );
+ pC = p->apCsr[pOp->p1];
+ res = pOp->p3;
+ assert( pC!=0 );
+ assert( pC->deferredMoveto==0 );
+ assert( pC->eCurType==CURTYPE_BTREE );
+ assert( res==0 || (res==1 && pC->isTable==0) );
+ testcase( res==1 );
+ assert( pOp->opcode!=OP_Next || pOp->p4.xAdvance==sqlite3BtreeNext );
+ assert( pOp->opcode!=OP_Prev || pOp->p4.xAdvance==sqlite3BtreePrevious );
+ assert( pOp->opcode!=OP_NextIfOpen || pOp->p4.xAdvance==sqlite3BtreeNext );
+ assert( pOp->opcode!=OP_PrevIfOpen || pOp->p4.xAdvance==sqlite3BtreePrevious);
+
+ /* The Next opcode is only used after SeekGT, SeekGE, and Rewind.
+ ** The Prev opcode is only used after SeekLT, SeekLE, and Last. */
+ assert( pOp->opcode!=OP_Next || pOp->opcode!=OP_NextIfOpen
+ || pC->seekOp==OP_SeekGT || pC->seekOp==OP_SeekGE
+ || pC->seekOp==OP_Rewind || pC->seekOp==OP_Found);
+ assert( pOp->opcode!=OP_Prev || pOp->opcode!=OP_PrevIfOpen
+ || pC->seekOp==OP_SeekLT || pC->seekOp==OP_SeekLE
+ || pC->seekOp==OP_Last );
+
+ rc = pOp->p4.xAdvance(pC->uc.pCursor, &res);
+next_tail:
+ pC->cacheStatus = CACHE_STALE;
+ VdbeBranchTaken(res==0,2);
+ if( res==0 ){
+ pC->nullRow = 0;
+ p->aCounter[pOp->p5]++;
#ifdef SQLITE_TEST
sqlite3_search_count++;
#endif
+ goto jump_to_p2_and_check_for_interrupt;
+ }else{
+ pC->nullRow = 1;
}
- u.br.pC->rowidIsValid = 0;
- break;
+ goto check_for_interrupt;
}
/* Opcode: IdxInsert P1 P2 P3 * P5
+** Synopsis: key=r[P2]
**
** Register P2 holds an SQL index key made using the
** MakeRecord instructions. This opcode writes that key
@@ -68551,87 +78574,89 @@ case OP_Next: { /* jump */
** P3 is a flag that provides a hint to the b-tree layer that this
** insert is likely to be an append.
**
+** If P5 has the OPFLAG_NCHANGE bit set, then the change counter is
+** incremented by this instruction. If the OPFLAG_NCHANGE bit is clear,
+** then the change counter is unchanged.
+**
+** If P5 has the OPFLAG_USESEEKRESULT bit set, then the cursor must have
+** just done a seek to the spot where the new entry is to be inserted.
+** This flag avoids doing an extra seek.
+**
** 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) );
+ pC = p->apCsr[pOp->p1];
+ assert( pC!=0 );
+ assert( isSorter(pC)==(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;
- }
+ if( pOp->p5 & OPFLAG_NCHANGE ) p->nChange++;
+ assert( pC->eCurType==CURTYPE_BTREE || pOp->opcode==OP_SorterInsert );
+ assert( pC->isTable==0 );
+ rc = ExpandBlob(pIn2);
+ if( rc==SQLITE_OK ){
+ if( pOp->opcode==OP_SorterInsert ){
+ rc = sqlite3VdbeSorterWrite(pC, pIn2);
+ }else{
+ nKey = pIn2->n;
+ zKey = pIn2->z;
+ rc = sqlite3BtreeInsert(pC->uc.pCursor, zKey, nKey, "", 0, 0, pOp->p3,
+ ((pOp->p5 & OPFLAG_USESEEKRESULT) ? pC->seekResult : 0)
+ );
+ assert( pC->deferredMoveto==0 );
+ pC->cacheStatus = CACHE_STALE;
}
}
break;
}
/* Opcode: IdxDelete P1 P2 P3 * *
+** Synopsis: key=r[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->p2>0 && pOp->p2+pOp->p3<=(p->nMem-p->nCursor)+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];
+ pC = p->apCsr[pOp->p1];
+ assert( pC!=0 );
+ assert( pC->eCurType==CURTYPE_BTREE );
+ pCrsr = pC->uc.pCursor;
+ assert( pCrsr!=0 );
+ assert( pOp->p5==0 );
+ r.pKeyInfo = pC->pKeyInfo;
+ r.nField = (u16)pOp->p3;
+ r.default_rc = 0;
+ 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]) ); }
+ { int i; for(i=0; i<r.nField; i++) assert( memIsValid(&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;
+ rc = sqlite3BtreeMovetoUnpacked(pCrsr, &r, 0, 0, &res);
+ if( rc==SQLITE_OK && res==0 ){
+ rc = sqlite3BtreeDelete(pCrsr, 0);
}
+ assert( pC->deferredMoveto==0 );
+ pC->cacheStatus = CACHE_STALE;
break;
}
/* Opcode: IdxRowid P1 P2 * * *
+** Synopsis: r[P2]=rowid
**
** 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
@@ -68639,99 +78664,127 @@ case OP_IdxDelete: {
**
** See also: Rowid, MakeRecord.
*/
-case OP_IdxRowid: { /* out2-prerelease */
-#if 0 /* local variables moved into u.bu */
+case OP_IdxRowid: { /* out2 */
BtCursor *pCrsr;
VdbeCursor *pC;
i64 rowid;
-#endif /* local variables moved into u.bu */
+ pOut = out2Prerelease(p, pOp);
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;
+ pC = p->apCsr[pOp->p1];
+ assert( pC!=0 );
+ assert( pC->eCurType==CURTYPE_BTREE );
+ pCrsr = pC->uc.pCursor;
+ assert( pCrsr!=0 );
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;
+ assert( pC->isTable==0 );
+ assert( pC->deferredMoveto==0 );
+
+ /* sqlite3VbeCursorRestore() can only fail if the record has been deleted
+ ** out from under the cursor. That will never happend for an IdxRowid
+ ** opcode, hence the NEVER() arround the check of the return value.
+ */
+ rc = sqlite3VdbeCursorRestore(pC);
+ if( NEVER(rc!=SQLITE_OK) ) goto abort_due_to_error;
+
+ if( !pC->nullRow ){
+ rowid = 0; /* Not needed. Only used to silence a warning. */
+ rc = sqlite3VdbeIdxRowid(db, pCrsr, &rowid);
+ if( rc!=SQLITE_OK ){
+ goto abort_due_to_error;
}
+ pOut->u.i = rowid;
+ pOut->flags = MEM_Int;
}
break;
}
/* Opcode: IdxGE P1 P2 P3 P4 P5
+** Synopsis: key=r[P3@P4]
**
** 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.
+** key that omits the PRIMARY KEY. Compare this key value against the index
+** that P1 is currently pointing to, ignoring the PRIMARY KEY or ROWID
+** fields at the end.
**
** 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.
+*/
+/* Opcode: IdxGT P1 P2 P3 P4 P5
+** Synopsis: key=r[P3@P4]
**
-** 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.
+** The P4 register values beginning with P3 form an unpacked index
+** key that omits the PRIMARY KEY. Compare this key value against the index
+** that P1 is currently pointing to, ignoring the PRIMARY KEY or ROWID
+** fields at the end.
+**
+** If the P1 index entry is greater than the key value
+** then jump to P2. Otherwise fall through to the next instruction.
*/
/* Opcode: IdxLT P1 P2 P3 P4 P5
+** Synopsis: key=r[P3@P4]
**
** 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.
+** key that omits the PRIMARY KEY or ROWID. Compare this key value against
+** the index that P1 is currently pointing to, ignoring the PRIMARY KEY or
+** 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.
+*/
+/* Opcode: IdxLE P1 P2 P3 P4 P5
+** Synopsis: key=r[P3@P4]
+**
+** The P4 register values beginning with P3 form an unpacked index
+** key that omits the PRIMARY KEY or ROWID. Compare this key value against
+** the index that P1 is currently pointing to, ignoring the PRIMARY KEY or
+** ROWID on the P1 index.
**
-** 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.
+** If the P1 index entry is less than or equal to the key value then jump
+** to P2. Otherwise fall through to the next instruction.
*/
+case OP_IdxLE: /* jump */
+case OP_IdxGT: /* jump */
case OP_IdxLT: /* jump */
-case OP_IdxGE: { /* jump */
-#if 0 /* local variables moved into u.bv */
+case OP_IdxGE: { /* jump */
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];
+ pC = p->apCsr[pOp->p1];
+ assert( pC!=0 );
+ assert( pC->isOrdered );
+ assert( pC->eCurType==CURTYPE_BTREE );
+ assert( pC->uc.pCursor!=0);
+ assert( pC->deferredMoveto==0 );
+ assert( pOp->p5==0 || pOp->p5==1 );
+ assert( pOp->p4type==P4_INT32 );
+ r.pKeyInfo = pC->pKeyInfo;
+ r.nField = (u16)pOp->p4.i;
+ if( pOp->opcode<OP_IdxLT ){
+ assert( pOp->opcode==OP_IdxLE || pOp->opcode==OP_IdxGT );
+ r.default_rc = -1;
+ }else{
+ assert( pOp->opcode==OP_IdxGE || pOp->opcode==OP_IdxLT );
+ r.default_rc = 0;
+ }
+ 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]) ); }
+ { int i; for(i=0; i<r.nField; i++) assert( memIsValid(&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 ;
- }
+ res = 0; /* Not needed. Only used to silence a warning. */
+ rc = sqlite3VdbeIdxKeyCompare(db, pC, &r, &res);
+ assert( (OP_IdxLE&1)==(OP_IdxLT&1) && (OP_IdxGE&1)==(OP_IdxGT&1) );
+ if( (pOp->opcode&1)==(OP_IdxLT&1) ){
+ assert( pOp->opcode==OP_IdxLE || pOp->opcode==OP_IdxLT );
+ res = -res;
+ }else{
+ assert( pOp->opcode==OP_IdxGE || pOp->opcode==OP_IdxGT );
+ res++;
}
+ VdbeBranchTaken(res>0,2);
+ if( res>0 ) goto jump_to_p2;
break;
}
@@ -68755,41 +78808,29 @@ case OP_IdxGE: { /* jump */
**
** See also: Clear
*/
-case OP_Destroy: { /* out2-prerelease */
-#if 0 /* local variables moved into u.bw */
+case OP_Destroy: { /* out2 */
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
+ assert( p->readOnly==0 );
+ pOut = out2Prerelease(p, pOp);
pOut->flags = MEM_Null;
- if( u.bw.iCnt>1 ){
+ if( db->nVdbeRead > db->nVDestroy+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);
+ iDb = pOp->p3;
+ assert( DbMaskTest(p->btreeMask, iDb) );
+ iMoved = 0; /* Not needed. Only to silence a warning. */
+ rc = sqlite3BtreeDropTable(db->aDb[iDb].pBt, pOp->p1, &iMoved);
pOut->flags = MEM_Int;
- pOut->u.i = u.bw.iMoved;
+ pOut->u.i = iMoved;
#ifndef SQLITE_OMIT_AUTOVACUUM
- if( rc==SQLITE_OK && u.bw.iMoved!=0 ){
- sqlite3RootPageMoved(db, u.bw.iDb, u.bw.iMoved, pOp->p1);
+ if( rc==SQLITE_OK && iMoved!=0 ){
+ sqlite3RootPageMoved(db, iDb, 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;
+ assert( resetSchemaOnFault==0 || resetSchemaOnFault==iDb+1 );
+ resetSchemaOnFault = iDb+1;
}
#endif
}
@@ -68815,27 +78856,51 @@ case OP_Destroy: { /* out2-prerelease */
** 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 );
+
+ nChange = 0;
+ assert( p->readOnly==0 );
+ assert( DbMaskTest(p->btreeMask, pOp->p2) );
rc = sqlite3BtreeClearTable(
- db->aDb[pOp->p2].pBt, pOp->p1, (pOp->p3 ? &u.bx.nChange : 0)
+ db->aDb[pOp->p2].pBt, pOp->p1, (pOp->p3 ? &nChange : 0)
);
if( pOp->p3 ){
- p->nChange += u.bx.nChange;
+ p->nChange += nChange;
if( pOp->p3>0 ){
assert( memIsValid(&aMem[pOp->p3]) );
memAboutToChange(p, &aMem[pOp->p3]);
- aMem[pOp->p3].u.i += u.bx.nChange;
+ aMem[pOp->p3].u.i += nChange;
}
}
break;
}
+/* Opcode: ResetSorter P1 * * * *
+**
+** Delete all contents from the ephemeral table or sorter
+** that is open on cursor P1.
+**
+** This opcode only works for cursors used for sorting and
+** opened with OP_OpenEphemeral or OP_SorterOpen.
+*/
+case OP_ResetSorter: {
+ VdbeCursor *pC;
+
+ assert( pOp->p1>=0 && pOp->p1<p->nCursor );
+ pC = p->apCsr[pOp->p1];
+ assert( pC!=0 );
+ if( isSorter(pC) ){
+ sqlite3VdbeSorterReset(db, pC->uc.pSorter);
+ }else{
+ assert( pC->eCurType==CURTYPE_BTREE );
+ assert( pC->isEphemeral );
+ rc = sqlite3BtreeClearTableOfCursor(pC->uc.pCursor);
+ }
+ break;
+}
+
/* Opcode: CreateTable P1 P2 * * *
+** Synopsis: r[P2]=root iDb=P1
**
** 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
@@ -68849,6 +78914,7 @@ case OP_Clear: {
** See also: CreateIndex
*/
/* Opcode: CreateIndex P1 P2 * * *
+** Synopsis: r[P2]=root iDb=P1
**
** 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
@@ -68857,27 +78923,27 @@ case OP_Clear: {
**
** 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 */
+case OP_CreateIndex: /* out2 */
+case OP_CreateTable: { /* out2 */
int pgno;
int flags;
Db *pDb;
-#endif /* local variables moved into u.by */
- u.by.pgno = 0;
+ pOut = out2Prerelease(p, pOp);
+ 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 );
+ assert( DbMaskTest(p->btreeMask, pOp->p1) );
+ assert( p->readOnly==0 );
+ pDb = &db->aDb[pOp->p1];
+ assert( pDb->pBt!=0 );
if( pOp->opcode==OP_CreateTable ){
- /* u.by.flags = BTREE_INTKEY; */
- u.by.flags = BTREE_INTKEY;
+ /* flags = BTREE_INTKEY; */
+ flags = BTREE_INTKEY;
}else{
- u.by.flags = BTREE_BLOBKEY;
+ flags = BTREE_BLOBKEY;
}
- rc = sqlite3BtreeCreateTable(u.by.pDb->pBt, &u.by.pgno, u.by.flags);
- pOut->u.i = u.by.pgno;
+ rc = sqlite3BtreeCreateTable(pDb->pBt, &pgno, flags);
+ pOut->u.i = pgno;
break;
}
@@ -68890,44 +78956,42 @@ case OP_CreateTable: { /* out2-prerelease */
** 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
+ ** 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) );
+ for(iDb=0; iDb<db->nDb; iDb++){
+ assert( iDb==1 || sqlite3BtreeHoldsMutex(db->aDb[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) );
+ iDb = pOp->p1;
+ assert( iDb>=0 && iDb<db->nDb );
+ assert( DbHasProperty(db, 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,
+ zMaster = SCHEMA_TABLE(iDb);
+ initData.db = db;
+ initData.iDb = pOp->p1;
+ initData.pzErrMsg = &p->zErrMsg;
+ 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 ){
+ db->aDb[iDb].zName, zMaster, pOp->p4.z);
+ if( zSql==0 ){
rc = SQLITE_NOMEM;
}else{
assert( db->init.busy==0 );
db->init.busy = 1;
- u.bz.initData.rc = SQLITE_OK;
+ 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);
+ rc = sqlite3_exec(db, zSql, sqlite3InitCallback, &initData, 0);
+ if( rc==SQLITE_OK ) rc = initData.rc;
+ sqlite3DbFree(db, zSql);
db->init.busy = 0;
}
}
@@ -68935,7 +78999,7 @@ case OP_ParseSchema: {
if( rc==SQLITE_NOMEM ){
goto no_mem;
}
- break;
+ break;
}
#if !defined(SQLITE_OMIT_ANALYZE)
@@ -68956,7 +79020,8 @@ case OP_LoadAnalysis: {
**
** 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
+** is dropped from disk (using the Destroy opcode) in order to keep
+** the internal representation of the
** schema consistent with what is on disk.
*/
case OP_DropTable: {
@@ -68968,7 +79033,8 @@ case OP_DropTable: {
**
** 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
+** is dropped from disk (using the Destroy opcode)
+** in order to keep the internal representation of the
** schema consistent with what is on disk.
*/
case OP_DropIndex: {
@@ -68980,7 +79046,8 @@ case OP_DropIndex: {
**
** 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
+** is dropped from disk (using the Destroy opcode) in order to keep
+** the internal representation of the
** schema consistent with what is on disk.
*/
case OP_DropTrigger: {
@@ -69011,41 +79078,40 @@ case OP_DropTrigger: {
** 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 );
+
+ assert( p->bIsReader );
+ nRoot = pOp->p2;
+ assert( nRoot>0 );
+ aRoot = sqlite3DbMallocRaw(db, sizeof(int)*(nRoot+1) );
+ if( aRoot==0 ) goto no_mem;
+ assert( pOp->p3>0 && pOp->p3<=(p->nMem-p->nCursor) );
+ pnErr = &aMem[pOp->p3];
+ assert( (pnErr->flags & MEM_Int)!=0 );
+ assert( (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]);
+ for(j=0; j<nRoot; j++){
+ aRoot[j] = (int)sqlite3VdbeIntValue(&pIn1[j]);
}
- u.ca.aRoot[u.ca.j] = 0;
+ aRoot[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;
+ assert( DbMaskTest(p->btreeMask, pOp->p5) );
+ z = sqlite3BtreeIntegrityCheck(db->aDb[pOp->p5].pBt, aRoot, nRoot,
+ (int)pnErr->u.i, &nErr);
+ sqlite3DbFree(db, aRoot);
+ pnErr->u.i -= nErr;
sqlite3VdbeMemSetNull(pIn1);
- if( u.ca.nErr==0 ){
- assert( u.ca.z==0 );
- }else if( u.ca.z==0 ){
+ if( nErr==0 ){
+ assert( z==0 );
+ }else if( z==0 ){
goto no_mem;
}else{
- sqlite3VdbeMemSetStr(pIn1, u.ca.z, -1, SQLITE_UTF8, sqlite3_free);
+ sqlite3VdbeMemSetStr(pIn1, z, -1, SQLITE_UTF8, sqlite3_free);
}
UPDATE_MAX_BLOBSIZE(pIn1);
sqlite3VdbeChangeEncoding(pIn1, encoding);
@@ -69054,6 +79120,7 @@ case OP_IntegrityCk: {
#endif /* SQLITE_OMIT_INTEGRITY_CHECK */
/* Opcode: RowSetAdd P1 P2 * * *
+** Synopsis: rowset(P1)=r[P2]
**
** Insert the integer value held by register P2 into a boolean index
** held in register P1.
@@ -69073,31 +79140,33 @@ case OP_RowSetAdd: { /* in1, in2 */
}
/* Opcode: RowSetRead P1 P2 P3 * *
+** Synopsis: r[P3]=rowset(P1)
**
** 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
+ if( (pIn1->flags & MEM_RowSet)==0
+ || sqlite3RowSetNext(pIn1->u.pRowSet, &val)==0
){
/* The boolean index is empty */
sqlite3VdbeMemSetNull(pIn1);
- pc = pOp->p2 - 1;
+ VdbeBranchTaken(1,2);
+ goto jump_to_p2_and_check_for_interrupt;
}else{
/* A value was pulled from the index */
- sqlite3VdbeMemSetInt64(&aMem[pOp->p3], u.cb.val);
+ VdbeBranchTaken(0,2);
+ sqlite3VdbeMemSetInt64(&aMem[pOp->p3], val);
}
- break;
+ goto check_for_interrupt;
}
/* Opcode: RowSetTest P1 P2 P3 P4
+** Synopsis: if r[P3] in rowset(P1) goto P2
**
** Register P3 is assumed to hold a 64-bit integer value. If register P1
** contains a RowSet object and that RowSet object contains
@@ -69121,14 +79190,12 @@ case OP_RowSetRead: { /* jump, in1, out3 */
** 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;
+ iSet = pOp->p4.i;
assert( pIn3->flags&MEM_Int );
/* If there is anything other than a rowset object in memory cell P1,
@@ -69140,17 +79207,13 @@ case OP_RowSetTest: { /* jump, in1, in3 */
}
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;
- }
+ assert( iSet==-1 || iSet>=0 );
+ if( iSet ){
+ exists = sqlite3RowSetTest(pIn1->u.pRowSet, iSet, pIn3->u.i);
+ VdbeBranchTaken(exists!=0,2);
+ if( exists ) goto jump_to_p2;
}
- if( u.cc.iSet>=0 ){
+ if( iSet>=0 ){
sqlite3RowSetInsert(pIn1->u.pRowSet, pIn3->u.i);
}
break;
@@ -69159,7 +79222,7 @@ case OP_RowSetTest: { /* jump, in1, in3 */
#ifndef SQLITE_OMIT_TRIGGER
-/* Opcode: Program P1 P2 P3 P4 *
+/* Opcode: Program P1 P2 P3 P4 P5
**
** Execute the trigger program passed as P4 (type P4_SUBPROGRAM).
**
@@ -69171,9 +79234,10 @@ case OP_RowSetTest: { /* jump, in1, in3 */
** memory required by the sub-vdbe at runtime.
**
** P4 is a pointer to the VM containing the trigger program.
+**
+** If P5 is non-zero, then recursive program invocation is enabled.
*/
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 */
@@ -69182,99 +79246,105 @@ case OP_Program: { /* jump */
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
+ pProgram = pOp->p4.pProgram;
+ pRt = &aMem[pOp->p3];
+ assert( 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
+ **
+ ** 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
+ ** 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;
+ t = pProgram->token;
+ for(pFrame=p->pFrame; pFrame && pFrame->token!=t; pFrame=pFrame->pParent);
+ if( pFrame ) break;
}
if( p->nFrame>=db->aLimit[SQLITE_LIMIT_TRIGGER_DEPTH] ){
rc = SQLITE_ERROR;
- sqlite3SetString(&p->zErrMsg, db, "too many levels of trigger recursion");
+ sqlite3VdbeError(p, "too many levels of trigger recursion");
break;
}
- /* Register u.cd.pRt is used to store the memory required to save the state
+ /* Register 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
+ ** the trigger program. If this trigger has been fired before, then 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
+ if( (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.
+ ** variable 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 ){
+ nMem = pProgram->nMem + pProgram->nCsr;
+ nByte = ROUND8(sizeof(VdbeFrame))
+ + nMem * sizeof(Mem)
+ + pProgram->nCsr * sizeof(VdbeCursor *)
+ + pProgram->nOnce * sizeof(u8);
+ pFrame = sqlite3DbMallocZero(db, nByte);
+ if( !pFrame ){
goto no_mem;
}
- sqlite3VdbeMemRelease(u.cd.pRt);
- u.cd.pRt->flags = MEM_Frame;
- u.cd.pRt->u.pFrame = u.cd.pFrame;
+ sqlite3VdbeMemRelease(pRt);
+ pRt->flags = MEM_Frame;
+ pRt->u.pFrame = 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;
+ pFrame->v = p;
+ pFrame->nChildMem = nMem;
+ pFrame->nChildCsr = pProgram->nCsr;
+ pFrame->pc = (int)(pOp - aOp);
+ pFrame->aMem = p->aMem;
+ pFrame->nMem = p->nMem;
+ pFrame->apCsr = p->apCsr;
+ pFrame->nCursor = p->nCursor;
+ pFrame->aOp = p->aOp;
+ pFrame->nOp = p->nOp;
+ pFrame->token = pProgram->token;
+ pFrame->aOnceFlag = p->aOnceFlag;
+ pFrame->nOnceFlag = p->nOnceFlag;
+#ifdef SQLITE_ENABLE_STMT_SCANSTATUS
+ pFrame->anExec = p->anExec;
+#endif
- 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;
+ pEnd = &VdbeFrameMem(pFrame)[pFrame->nChildMem];
+ for(pMem=VdbeFrameMem(pFrame); pMem!=pEnd; pMem++){
+ pMem->flags = MEM_Undefined;
+ 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 );
+ pFrame = pRt->u.pFrame;
+ assert( pProgram->nMem+pProgram->nCsr==pFrame->nChildMem );
+ assert( pProgram->nCsr==pFrame->nChildCsr );
+ assert( (int)(pOp - aOp)==pFrame->pc );
}
p->nFrame++;
- u.cd.pFrame->pParent = p->pFrame;
- u.cd.pFrame->lastRowid = lastRowid;
- u.cd.pFrame->nChange = p->nChange;
+ pFrame->pParent = p->pFrame;
+ pFrame->lastRowid = lastRowid;
+ pFrame->nChange = p->nChange;
+ pFrame->nDbChange = p->db->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->pFrame = pFrame;
+ p->aMem = aMem = &VdbeFrameMem(pFrame)[-1];
+ p->nMem = pFrame->nChildMem;
+ p->nCursor = (u16)pFrame->nChildCsr;
p->apCsr = (VdbeCursor **)&aMem[p->nMem+1];
- p->aOp = aOp = u.cd.pProgram->aOp;
- p->nOp = u.cd.pProgram->nOp;
+ p->aOp = aOp = pProgram->aOp;
+ p->nOp = pProgram->nOp;
p->aOnceFlag = (u8 *)&p->apCsr[p->nCursor];
- p->nOnceFlag = u.cd.pProgram->nOnce;
- pc = -1;
+ p->nOnceFlag = pProgram->nOnce;
+#ifdef SQLITE_ENABLE_STMT_SCANSTATUS
+ p->anExec = 0;
+#endif
+ pOp = &aOp[-1];
memset(p->aOnceFlag, 0, p->nOnceFlag);
break;
@@ -69292,14 +79362,13 @@ case OP_Program: { /* jump */
** 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 */
+case OP_Param: { /* out2 */
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);
+ pOut = out2Prerelease(p, pOp);
+ pFrame = p->pFrame;
+ pIn = &pFrame->aMem[pOp->p1 + pFrame->aOp[pFrame->pc].p1];
+ sqlite3VdbeMemShallowCopy(pOut, pIn, MEM_Ephem);
break;
}
@@ -69307,6 +79376,7 @@ case OP_Param: { /* out2-prerelease */
#ifndef SQLITE_OMIT_FOREIGN_KEY
/* Opcode: FkCounter P1 P2 * * *
+** Synopsis: fkctr[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
@@ -69314,7 +79384,9 @@ case OP_Param: { /* out2-prerelease */
** statement counter is incremented (immediate foreign key constraints).
*/
case OP_FkCounter: {
- if( pOp->p1 ){
+ if( db->flags & SQLITE_DeferFKs ){
+ db->nDeferredImmCons += pOp->p2;
+ }else if( pOp->p1 ){
db->nDeferredCons += pOp->p2;
}else{
p->nFkConstraint += pOp->p2;
@@ -69323,6 +79395,7 @@ case OP_FkCounter: {
}
/* Opcode: FkIfZero P1 P2 * * *
+** Synopsis: if fkctr[P1]==0 goto 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
@@ -69335,9 +79408,11 @@ case OP_FkCounter: {
*/
case OP_FkIfZero: { /* jump */
if( pOp->p1 ){
- if( db->nDeferredCons==0 ) pc = pOp->p2-1;
+ VdbeBranchTaken(db->nDeferredCons==0 && db->nDeferredImmCons==0, 2);
+ if( db->nDeferredCons==0 && db->nDeferredImmCons==0 ) goto jump_to_p2;
}else{
- if( p->nFkConstraint==0 ) pc = pOp->p2-1;
+ VdbeBranchTaken(p->nFkConstraint==0 && db->nDeferredImmCons==0, 2);
+ if( p->nFkConstraint==0 && db->nDeferredImmCons==0 ) goto jump_to_p2;
}
break;
}
@@ -69345,6 +79420,7 @@ case OP_FkIfZero: { /* jump */
#ifndef SQLITE_OMIT_AUTOINCREMENT
/* Opcode: MemMax P1 P2 * * *
+** Synopsis: r[P1]=max(r[P1],r[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
@@ -69355,143 +79431,212 @@ case OP_FkIfZero: { /* jump */
** 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];
+ for(pFrame=p->pFrame; pFrame->pParent; pFrame=pFrame->pParent);
+ pIn1 = &pFrame->aMem[pOp->p1];
}else{
- u.cf.pIn1 = &aMem[pOp->p1];
+ pIn1 = &aMem[pOp->p1];
}
- assert( memIsValid(u.cf.pIn1) );
- sqlite3VdbeMemIntegerify(u.cf.pIn1);
+ assert( memIsValid(pIn1) );
+ sqlite3VdbeMemIntegerify(pIn1);
pIn2 = &aMem[pOp->p2];
sqlite3VdbeMemIntegerify(pIn2);
- if( u.cf.pIn1->u.i<pIn2->u.i){
- u.cf.pIn1->u.i = pIn2->u.i;
+ if( pIn1->u.i<pIn2->u.i){
+ pIn1->u.i = pIn2->u.i;
}
break;
}
#endif /* SQLITE_OMIT_AUTOINCREMENT */
-/* Opcode: IfPos P1 P2 * * *
+/* Opcode: IfPos P1 P2 P3 * *
+** Synopsis: if r[P1]>0 then r[P1]-=P3, goto P2
**
-** If the value of register P1 is 1 or greater, jump to P2.
+** Register P1 must contain an integer.
+** If the value of register P1 is 1 or greater, subtract P3 from the
+** value in P1 and 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.
+** If the initial value of register P1 is less than 1, then the
+** value is unchanged and control passes through to the next instruction.
*/
case OP_IfPos: { /* jump, in1 */
pIn1 = &aMem[pOp->p1];
assert( pIn1->flags&MEM_Int );
+ VdbeBranchTaken( pIn1->u.i>0, 2);
if( pIn1->u.i>0 ){
- pc = pOp->p2 - 1;
+ pIn1->u.i -= pOp->p3;
+ goto jump_to_p2;
}
break;
}
-/* Opcode: IfNeg P1 P2 * * *
+/* Opcode: SetIfNotPos P1 P2 P3 * *
+** Synopsis: if r[P1]<=0 then r[P2]=P3
**
-** If the value of register P1 is less than zero, jump to P2.
+** Register P1 must contain an integer.
+** If the value of register P1 is not positive (if it is less than 1) then
+** set the value of register P2 to be the integer P3.
+*/
+case OP_SetIfNotPos: { /* in1, in2 */
+ pIn1 = &aMem[pOp->p1];
+ assert( pIn1->flags&MEM_Int );
+ if( pIn1->u.i<=0 ){
+ pOut = out2Prerelease(p, pOp);
+ pOut->u.i = pOp->p3;
+ }
+ break;
+}
+
+/* Opcode: IfNotZero P1 P2 P3 * *
+** Synopsis: if r[P1]!=0 then r[P1]-=P3, goto 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.
+** Register P1 must contain an integer. If the content of register P1 is
+** initially nonzero, then subtract P3 from the value in register P1 and
+** jump to P2. If register P1 is initially zero, leave it unchanged
+** and fall through.
*/
-case OP_IfNeg: { /* jump, in1 */
+case OP_IfNotZero: { /* jump, in1 */
pIn1 = &aMem[pOp->p1];
assert( pIn1->flags&MEM_Int );
- if( pIn1->u.i<0 ){
- pc = pOp->p2 - 1;
+ VdbeBranchTaken(pIn1->u.i<0, 2);
+ if( pIn1->u.i ){
+ pIn1->u.i -= pOp->p3;
+ goto jump_to_p2;
}
break;
}
-/* Opcode: IfZero P1 P2 P3 * *
+/* Opcode: DecrJumpZero P1 P2 * * *
+** Synopsis: if (--r[P1])==0 goto P2
**
-** 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.
+** Register P1 must hold an integer. Decrement the value in register P1
+** then jump to P2 if the new value is exactly zero.
+*/
+case OP_DecrJumpZero: { /* jump, in1 */
+ pIn1 = &aMem[pOp->p1];
+ assert( pIn1->flags&MEM_Int );
+ pIn1->u.i--;
+ VdbeBranchTaken(pIn1->u.i==0, 2);
+ if( pIn1->u.i==0 ) goto jump_to_p2;
+ break;
+}
+
+
+/* Opcode: JumpZeroIncr P1 P2 * * *
+** Synopsis: if (r[P1]++)==0 ) goto 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.
+** The register P1 must contain an integer. If register P1 is initially
+** zero, then jump to P2. Increment register P1 regardless of whether or
+** not the jump is taken.
*/
-case OP_IfZero: { /* jump, in1 */
+case OP_JumpZeroIncr: { /* 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;
- }
+ VdbeBranchTaken(pIn1->u.i==0, 2);
+ if( (pIn1->u.i++)==0 ) goto jump_to_p2;
break;
}
-/* Opcode: AggStep * P2 P3 P4 P5
+/* Opcode: AggStep0 * P2 P3 P4 P5
+** Synopsis: accum=r[P3] step(r[P2@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.
+** structure that specifies the function. Register P3 is the
+** accumulator.
**
** The P5 arguments are taken from register P2 and its
** successors.
*/
-case OP_AggStep: {
-#if 0 /* local variables moved into u.cg */
+/* Opcode: AggStep * P2 P3 P4 P5
+** Synopsis: accum=r[P3] step(r[P2@P5])
+**
+** Execute the step function for an aggregate. The
+** function has P5 arguments. P4 is a pointer to an sqlite3_context
+** object that is used to run the function. Register P3 is
+** as the accumulator.
+**
+** The P5 arguments are taken from register P2 and its
+** successors.
+**
+** This opcode is initially coded as OP_AggStep0. On first evaluation,
+** the FuncDef stored in P4 is converted into an sqlite3_context and
+** the opcode is changed. In this way, the initialization of the
+** sqlite3_context only happens once, instead of on each call to the
+** step function.
+*/
+case OP_AggStep0: {
int n;
+ sqlite3_context *pCtx;
+
+ assert( pOp->p4type==P4_FUNCDEF );
+ n = pOp->p5;
+ assert( pOp->p3>0 && pOp->p3<=(p->nMem-p->nCursor) );
+ assert( n==0 || (pOp->p2>0 && pOp->p2+n<=(p->nMem-p->nCursor)+1) );
+ assert( pOp->p3<pOp->p2 || pOp->p3>=pOp->p2+n );
+ pCtx = sqlite3DbMallocRaw(db, sizeof(*pCtx) + (n-1)*sizeof(sqlite3_value*));
+ if( pCtx==0 ) goto no_mem;
+ pCtx->pMem = 0;
+ pCtx->pFunc = pOp->p4.pFunc;
+ pCtx->iOp = (int)(pOp - aOp);
+ pCtx->pVdbe = p;
+ pCtx->argc = n;
+ pOp->p4type = P4_FUNCCTX;
+ pOp->p4.pCtx = pCtx;
+ pOp->opcode = OP_AggStep;
+ /* Fall through into OP_AggStep */
+}
+case OP_AggStep: {
int i;
+ sqlite3_context *pCtx;
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;
+ Mem t;
+
+ assert( pOp->p4type==P4_FUNCCTX );
+ pCtx = pOp->p4.pCtx;
+ pMem = &aMem[pOp->p3];
+
+ /* If this function is inside of a trigger, the register array in aMem[]
+ ** might change from one evaluation to the next. The next block of code
+ ** checks to see if the register array has changed, and if so it
+ ** reinitializes the relavant parts of the sqlite3_context object */
+ if( pCtx->pMem != pMem ){
+ pCtx->pMem = pMem;
+ for(i=pCtx->argc-1; i>=0; i--) pCtx->argv[i] = &aMem[pOp->p2+i];
+ }
+
+#ifdef SQLITE_DEBUG
+ for(i=0; i<pCtx->argc; i++){
+ assert( memIsValid(pCtx->argv[i]) );
+ REGISTER_TRACE(pOp->p2+i, pCtx->argv[i]);
}
- (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;
+#endif
+
+ pMem->n++;
+ sqlite3VdbeMemInit(&t, db, MEM_Null);
+ pCtx->pOut = &t;
+ pCtx->fErrorOrAux = 0;
+ pCtx->skipFlag = 0;
+ (pCtx->pFunc->xStep)(pCtx,pCtx->argc,pCtx->argv); /* IMP: R-24505-23230 */
+ if( pCtx->fErrorOrAux ){
+ if( pCtx->isError ){
+ sqlite3VdbeError(p, "%s", sqlite3_value_text(&t));
+ rc = pCtx->isError;
+ }
+ sqlite3VdbeMemRelease(&t);
+ }else{
+ assert( t.flags==MEM_Null );
}
- if( u.cg.ctx.skipFlag ){
+ if( pCtx->skipFlag ){
assert( pOp[-1].opcode==OP_CollSeq );
- u.cg.i = pOp[-1].p1;
- if( u.cg.i ) sqlite3VdbeMemSetInt64(&aMem[u.cg.i], 1);
+ i = pOp[-1].p1;
+ if( i ) sqlite3VdbeMemSetInt64(&aMem[i], 1);
}
-
- sqlite3VdbeMemRelease(&u.cg.ctx.s);
-
break;
}
/* Opcode: AggFinal P1 P2 * P4 *
+** Synopsis: accum=r[P1] N=P2
**
** Execute the finalizer function for an aggregate. P1 is
** the memory location that is the accumulator for the aggregate.
@@ -69504,19 +79649,17 @@ case OP_AggStep: {
** 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);
+ assert( pOp->p1>0 && pOp->p1<=(p->nMem-p->nCursor) );
+ pMem = &aMem[pOp->p1];
+ assert( (pMem->flags & ~(MEM_Null|MEM_Agg))==0 );
+ rc = sqlite3VdbeMemFinalize(pMem, pOp->p4.pFunc);
if( rc ){
- sqlite3SetString(&p->zErrMsg, db, "%s", sqlite3_value_text(u.ch.pMem));
+ sqlite3VdbeError(p, "%s", sqlite3_value_text(pMem));
}
- sqlite3VdbeChangeEncoding(u.ch.pMem, encoding);
- UPDATE_MAX_BLOBSIZE(u.ch.pMem);
- if( sqlite3VdbeMemTooBig(u.ch.pMem) ){
+ sqlite3VdbeChangeEncoding(pMem, encoding);
+ UPDATE_MAX_BLOBSIZE(pMem);
+ if( sqlite3VdbeMemTooBig(pMem) ){
goto too_big;
}
break;
@@ -69526,8 +79669,8 @@ case OP_AggFinal: {
/* 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
+** WAL mode. Parameter P2 is one of SQLITE_CHECKPOINT_PASSIVE, FULL,
+** RESTART, or TRUNCATE. 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
@@ -69535,32 +79678,32 @@ case OP_AggFinal: {
** 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( p->readOnly==0 );
+ aRes[0] = 0;
+ aRes[1] = aRes[2] = -1;
assert( pOp->p2==SQLITE_CHECKPOINT_PASSIVE
|| pOp->p2==SQLITE_CHECKPOINT_FULL
|| pOp->p2==SQLITE_CHECKPOINT_RESTART
+ || pOp->p2==SQLITE_CHECKPOINT_TRUNCATE
);
- rc = sqlite3Checkpoint(db, pOp->p1, pOp->p2, &u.ci.aRes[1], &u.ci.aRes[2]);
+ rc = sqlite3Checkpoint(db, pOp->p1, pOp->p2, &aRes[1], &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]);
+ aRes[0] = 1;
}
+ for(i=0, pMem = &aMem[pOp->p3]; i<3; i++, pMem++){
+ sqlite3VdbeMemSetInt64(pMem, (i64)aRes[i]);
+ }
break;
};
#endif
#ifndef SQLITE_OMIT_PRAGMA
-/* Opcode: JournalMode P1 P2 P3 * P5
+/* Opcode: JournalMode P1 P2 P3 * *
**
** 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
@@ -69571,8 +79714,7 @@ case OP_Checkpoint: {
**
** Write a string containing the final journal-mode to register P2.
*/
-case OP_JournalMode: { /* out2-prerelease */
-#if 0 /* local variables moved into u.cj */
+case OP_JournalMode: { /* out2 */
Btree *pBt; /* Btree to change journal mode of */
Pager *pPager; /* Pager associated with pBt */
int eNew; /* New journal mode */
@@ -69580,85 +79722,85 @@ case OP_JournalMode: { /* out2-prerelease */
#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
+ pOut = out2Prerelease(p, pOp);
+ eNew = pOp->p3;
+ assert( eNew==PAGER_JOURNALMODE_DELETE
+ || eNew==PAGER_JOURNALMODE_TRUNCATE
+ || eNew==PAGER_JOURNALMODE_PERSIST
+ || eNew==PAGER_JOURNALMODE_OFF
+ || eNew==PAGER_JOURNALMODE_MEMORY
+ || eNew==PAGER_JOURNALMODE_WAL
+ || eNew==PAGER_JOURNALMODE_QUERY
);
assert( pOp->p1>=0 && pOp->p1<db->nDb );
+ assert( p->readOnly==0 );
- 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;
+ pBt = db->aDb[pOp->p1].pBt;
+ pPager = sqlite3BtreePager(pBt);
+ eOld = sqlite3PagerGetJournalMode(pPager);
+ if( eNew==PAGER_JOURNALMODE_QUERY ) eNew = eOld;
+ if( !sqlite3PagerOkToChangeJournalMode(pPager) ) eNew = eOld;
#ifndef SQLITE_OMIT_WAL
- u.cj.zFilename = sqlite3PagerFilename(u.cj.pPager, 1);
+ zFilename = sqlite3PagerFilename(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
+ ** 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 */
+ if( eNew==PAGER_JOURNALMODE_WAL
+ && (sqlite3Strlen30(zFilename)==0 /* Temp file */
+ || !sqlite3PagerWalSupported(pPager)) /* No shared-memory support */
){
- u.cj.eNew = u.cj.eOld;
+ eNew = eOld;
}
- if( (u.cj.eNew!=u.cj.eOld)
- && (u.cj.eOld==PAGER_JOURNALMODE_WAL || u.cj.eNew==PAGER_JOURNALMODE_WAL)
+ if( (eNew!=eOld)
+ && (eOld==PAGER_JOURNALMODE_WAL || eNew==PAGER_JOURNALMODE_WAL)
){
- if( !db->autoCommit || db->activeVdbeCnt>1 ){
+ if( !db->autoCommit || db->nVdbeRead>1 ){
rc = SQLITE_ERROR;
- sqlite3SetString(&p->zErrMsg, db,
+ sqlite3VdbeError(p,
"cannot change %s wal mode from within a transaction",
- (u.cj.eNew==PAGER_JOURNALMODE_WAL ? "into" : "out of")
+ (eNew==PAGER_JOURNALMODE_WAL ? "into" : "out of")
);
break;
}else{
-
- if( u.cj.eOld==PAGER_JOURNALMODE_WAL ){
+
+ if( 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.
+ ** 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);
+ rc = sqlite3PagerCloseWal(pPager);
if( rc==SQLITE_OK ){
- sqlite3PagerSetJournalMode(u.cj.pPager, u.cj.eNew);
+ sqlite3PagerSetJournalMode(pPager, eNew);
}
- }else if( u.cj.eOld==PAGER_JOURNALMODE_MEMORY ){
+ }else if( eOld==PAGER_JOURNALMODE_MEMORY ){
/* Cannot transition directly from MEMORY to WAL. Use mode OFF
** as an intermediate */
- sqlite3PagerSetJournalMode(u.cj.pPager, PAGER_JOURNALMODE_OFF);
+ sqlite3PagerSetJournalMode(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 );
+ assert( sqlite3BtreeIsInTrans(pBt)==0 );
if( rc==SQLITE_OK ){
- rc = sqlite3BtreeSetVersion(u.cj.pBt, (u.cj.eNew==PAGER_JOURNALMODE_WAL ? 2 : 1));
+ rc = sqlite3BtreeSetVersion(pBt, (eNew==PAGER_JOURNALMODE_WAL ? 2 : 1));
}
}
}
#endif /* ifndef SQLITE_OMIT_WAL */
if( rc ){
- u.cj.eNew = u.cj.eOld;
+ eNew = eOld;
}
- u.cj.eNew = sqlite3PagerSetJournalMode(u.cj.pPager, u.cj.eNew);
+ eNew = sqlite3PagerSetJournalMode(pPager, eNew);
- pOut = &aMem[pOp->p2];
pOut->flags = MEM_Str|MEM_Static|MEM_Term;
- pOut->z = (char *)sqlite3JournalModename(u.cj.eNew);
+ pOut->z = (char *)sqlite3JournalModename(eNew);
pOut->n = sqlite3Strlen30(pOut->z);
pOut->enc = SQLITE_UTF8;
sqlite3VdbeChangeEncoding(pOut, encoding);
@@ -69674,6 +79816,7 @@ case OP_JournalMode: { /* out2-prerelease */
** a transaction.
*/
case OP_Vacuum: {
+ assert( p->readOnly==0 );
rc = sqlite3RunVacuum(&p->zErrMsg, db);
break;
}
@@ -69687,17 +79830,17 @@ case OP_Vacuum: {
** 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);
+ assert( DbMaskTest(p->btreeMask, pOp->p1) );
+ assert( p->readOnly==0 );
+ pBt = db->aDb[pOp->p1].pBt;
+ rc = sqlite3BtreeIncrVacuum(pBt);
+ VdbeBranchTaken(rc==SQLITE_DONE,2);
if( rc==SQLITE_DONE ){
- pc = pOp->p2 - 1;
rc = SQLITE_OK;
+ goto jump_to_p2;
}
break;
}
@@ -69705,12 +79848,13 @@ case OP_IncrVacuum: { /* jump */
/* 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()).
+** Cause precompiled statements to expire. When an expired statement
+** is executed using sqlite3_step() it will either automatically
+** reprepare itself (if it was originally created using sqlite3_prepare_v2())
+** or it will fail with SQLITE_SCHEMA.
**
** If P1 is 0, then all SQL statements become expired. If P1 is non-zero,
-** then only the currently executing statement is affected.
+** then only the currently executing statement is expired.
*/
case OP_Expire: {
if( !pOp->p1 ){
@@ -69723,6 +79867,7 @@ case OP_Expire: {
#ifndef SQLITE_OMIT_SHARED_CACHE
/* Opcode: TableLock P1 P2 P3 P4 *
+** Synopsis: iDb=P1 root=P2 write=P3
**
** Obtain a lock on a particular table. This instruction is only used when
** the shared-cache feature is enabled.
@@ -69741,12 +79886,12 @@ case OP_TableLock: {
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( DbMaskTest(p->btreeMask, p1) );
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);
+ sqlite3VdbeError(p, "database table is locked: %s", z);
}
}
break;
@@ -69764,24 +79909,38 @@ case OP_TableLock: {
** 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);
+ pVTab = pOp->p4.pVtab;
+ rc = sqlite3VtabBegin(db, pVTab);
+ if( pVTab ) sqlite3VtabImportErrmsg(p, pVTab->pVtab);
break;
}
#endif /* SQLITE_OMIT_VIRTUALTABLE */
#ifndef SQLITE_OMIT_VIRTUALTABLE
-/* Opcode: VCreate P1 * * P4 *
+/* Opcode: VCreate P1 P2 * * *
**
-** P4 is the name of a virtual table in database P1. Call the xCreate method
-** for that table.
+** P2 is a register that holds 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);
+ Mem sMem; /* For storing the record being decoded */
+ const char *zTab; /* Name of the virtual table */
+
+ memset(&sMem, 0, sizeof(sMem));
+ sMem.db = db;
+ /* Because P2 is always a static string, it is impossible for the
+ ** sqlite3VdbeMemCopy() to fail */
+ assert( (aMem[pOp->p2].flags & MEM_Str)!=0 );
+ assert( (aMem[pOp->p2].flags & MEM_Static)!=0 );
+ rc = sqlite3VdbeMemCopy(&sMem, &aMem[pOp->p2]);
+ assert( rc==SQLITE_OK );
+ zTab = (const char*)sqlite3_value_text(&sMem);
+ assert( zTab || db->mallocFailed );
+ if( zTab ){
+ rc = sqlite3VtabCallCreate(db, pOp->p1, zTab, &p->zErrMsg);
+ }
+ sqlite3VdbeMemRelease(&sMem);
break;
}
#endif /* SQLITE_OMIT_VIRTUALTABLE */
@@ -69793,9 +79952,9 @@ case OP_VCreate: {
** of that table.
*/
case OP_VDestroy: {
- p->inVtabMethod = 2;
+ db->nVDestroy++;
rc = sqlite3VtabCallDestroy(db, pOp->p1, pOp->p4.z);
- p->inVtabMethod = 0;
+ db->nVDestroy--;
break;
}
#endif /* SQLITE_OMIT_VIRTUALTABLE */
@@ -69808,32 +79967,35 @@ case OP_VDestroy: {
** 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_cursor *pVCur;
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);
+ const sqlite3_module *pModule;
+
+ assert( p->bIsReader );
+ pCur = 0;
+ pVCur = 0;
+ pVtab = pOp->p4.pVtab->pVtab;
+ if( pVtab==0 || NEVER(pVtab->pModule==0) ){
+ rc = SQLITE_LOCKED;
+ break;
+ }
+ pModule = pVtab->pModule;
+ rc = pModule->xOpen(pVtab, &pVCur);
+ sqlite3VtabImportErrmsg(p, pVtab);
if( SQLITE_OK==rc ){
/* Initialize sqlite3_vtab_cursor base class */
- u.cm.pVtabCursor->pVtab = u.cm.pVtab;
+ pVCur->pVtab = 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;
+ /* Initialize vdbe cursor object */
+ pCur = allocateCursor(p, pOp->p1, 0, -1, CURTYPE_VTAB);
+ if( pCur ){
+ pCur->uc.pVCur = pVCur;
+ pVtab->nRef++;
}else{
- db->mallocFailed = 1;
- u.cm.pModule->xClose(u.cm.pVtabCursor);
+ assert( db->mallocFailed );
+ pModule->xClose(pVCur);
+ goto no_mem;
}
}
break;
@@ -69842,6 +80004,7 @@ case OP_VOpen: {
#ifndef SQLITE_OMIT_VIRTUALTABLE
/* Opcode: VFilter P1 P2 P3 P4 *
+** Synopsis: iplan=r[P3] zplan='P4'
**
** P1 is a cursor opened using VOpen. P2 is an address to jump to if
** the filtered result set is empty.
@@ -69860,115 +80023,90 @@ case OP_VOpen: {
** 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_cursor *pVCur;
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;
+
+ pQuery = &aMem[pOp->p3];
+ pArgc = &pQuery[1];
+ pCur = p->apCsr[pOp->p1];
+ assert( memIsValid(pQuery) );
+ REGISTER_TRACE(pOp->p3, pQuery);
+ assert( pCur->eCurType==CURTYPE_VTAB );
+ pVCur = pCur->uc.pVCur;
+ pVtab = pVCur->pVtab;
+ pModule = 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;
+ assert( (pQuery->flags&MEM_Int)!=0 && pArgc->flags==MEM_Int );
+ nArg = (int)pArgc->u.i;
+ iQuery = (int)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;
- }
+ res = 0;
+ apArg = p->apArg;
+ for(i = 0; i<nArg; i++){
+ apArg[i] = &pArgc[i+1];
}
- u.cn.pCur->nullRow = 0;
-
+ rc = pModule->xFilter(pVCur, iQuery, pOp->p4.z, nArg, apArg);
+ sqlite3VtabImportErrmsg(p, pVtab);
+ if( rc==SQLITE_OK ){
+ res = pModule->xEof(pVCur);
+ }
+ pCur->nullRow = 0;
+ VdbeBranchTaken(res!=0,2);
+ if( res ) goto jump_to_p2;
break;
}
#endif /* SQLITE_OMIT_VIRTUALTABLE */
#ifndef SQLITE_OMIT_VIRTUALTABLE
/* Opcode: VColumn P1 P2 P3 * *
+** Synopsis: r[P3]=vcolumn(P2)
**
** 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);
+ assert( pCur->eCurType==CURTYPE_VTAB );
+ assert( pOp->p3>0 && pOp->p3<=(p->nMem-p->nCursor) );
+ pDest = &aMem[pOp->p3];
+ memAboutToChange(p, pDest);
if( pCur->nullRow ){
- sqlite3VdbeMemSetNull(u.co.pDest);
+ sqlite3VdbeMemSetNull(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) ){
+ pVtab = pCur->uc.pVCur->pVtab;
+ pModule = pVtab->pModule;
+ assert( pModule->xColumn );
+ memset(&sContext, 0, sizeof(sContext));
+ sContext.pOut = pDest;
+ MemSetTypeFlag(pDest, MEM_Null);
+ rc = pModule->xColumn(pCur->uc.pVCur, &sContext, pOp->p2);
+ sqlite3VtabImportErrmsg(p, pVtab);
+ if( sContext.isError ){
+ rc = sContext.isError;
+ }
+ sqlite3VdbeChangeEncoding(pDest, encoding);
+ REGISTER_TRACE(pOp->p3, pDest);
+ UPDATE_MAX_BLOBSIZE(pDest);
+
+ if( sqlite3VdbeMemTooBig(pDest) ){
goto too_big;
}
break;
@@ -69983,42 +80121,38 @@ case OP_VColumn: {
** 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 ){
+ res = 0;
+ pCur = p->apCsr[pOp->p1];
+ assert( pCur->eCurType==CURTYPE_VTAB );
+ if( pCur->nullRow ){
break;
}
- u.cp.pVtab = u.cp.pCur->pVtabCursor->pVtab;
- u.cp.pModule = u.cp.pVtab->pModule;
- assert( u.cp.pModule->xNext );
+ pVtab = pCur->uc.pVCur->pVtab;
+ pModule = pVtab->pModule;
+ assert( 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
+ ** 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);
+ rc = pModule->xNext(pCur->uc.pVCur);
+ sqlite3VtabImportErrmsg(p, pVtab);
if( rc==SQLITE_OK ){
- u.cp.res = u.cp.pModule->xEof(u.cp.pCur->pVtabCursor);
+ res = pModule->xEof(pCur->uc.pVCur);
}
-
- if( !u.cp.res ){
+ VdbeBranchTaken(!res,2);
+ if( !res ){
/* If there is data, jump to P2 */
- pc = pOp->p2 - 1;
+ goto jump_to_p2_and_check_for_interrupt;
}
- break;
+ goto check_for_interrupt;
}
#endif /* SQLITE_OMIT_VIRTUALTABLE */
@@ -70030,24 +80164,23 @@ case OP_VNext: { /* jump */
** 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);
+
+ pVtab = pOp->p4.pVtab->pVtab;
+ pName = &aMem[pOp->p1];
+ assert( pVtab->pModule->xRename );
+ assert( memIsValid(pName) );
+ assert( p->readOnly==0 );
+ REGISTER_TRACE(pOp->p1, pName);
+ assert( pName->flags & MEM_Str );
+ testcase( pName->enc==SQLITE_UTF8 );
+ testcase( pName->enc==SQLITE_UTF16BE );
+ testcase( pName->enc==SQLITE_UTF16LE );
+ rc = sqlite3VdbeChangeEncoding(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);
+ rc = pVtab->pModule->xRename(pVtab, pName->z);
+ sqlite3VtabImportErrmsg(p, pVtab);
p->expired = 0;
}
break;
@@ -70055,7 +80188,8 @@ case OP_VRename: {
#endif
#ifndef SQLITE_OMIT_VIRTUALTABLE
-/* Opcode: VUpdate P1 P2 P3 P4 *
+/* Opcode: VUpdate P1 P2 P3 P4 P5
+** Synopsis: data=r[P3@P2]
**
** P4 is a pointer to a virtual table object, an sqlite3_vtab structure.
** This opcode invokes the corresponding xUpdate method. P2 values
@@ -70077,45 +80211,50 @@ case OP_VRename: {
** 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.
+**
+** P5 is the error actions (OE_Replace, OE_Fail, OE_Ignore, etc) to
+** apply in the case of a constraint failure on an insert or update.
*/
case OP_VUpdate: {
-#if 0 /* local variables moved into u.cr */
sqlite3_vtab *pVtab;
- sqlite3_module *pModule;
+ const 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
+ 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( p->readOnly==0 );
+ pVtab = pOp->p4.pVtab->pVtab;
+ if( pVtab==0 || NEVER(pVtab->pModule==0) ){
+ rc = SQLITE_LOCKED;
+ break;
+ }
+ pModule = pVtab->pModule;
+ nArg = pOp->p2;
assert( pOp->p4type==P4_VTAB );
- if( ALWAYS(u.cr.pModule->xUpdate) ){
+ if( ALWAYS(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++;
+ apArg = p->apArg;
+ pX = &aMem[pOp->p3];
+ for(i=0; i<nArg; i++){
+ assert( memIsValid(pX) );
+ memAboutToChange(p, pX);
+ apArg[i] = pX;
+ pX++;
}
db->vtabOnConflict = pOp->p5;
- rc = u.cr.pModule->xUpdate(u.cr.pVtab, u.cr.nArg, u.cr.apArg, &u.cr.rowid);
+ rc = pModule->xUpdate(pVtab, nArg, apArg, &rowid);
db->vtabOnConflict = vtabOnConflict;
- importVtabErrMsg(p, u.cr.pVtab);
+ sqlite3VtabImportErrmsg(p, 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;
+ assert( nArg>1 && apArg[0] && (apArg[0]->flags&MEM_Null) );
+ db->lastRowid = lastRowid = rowid;
}
- if( rc==SQLITE_CONSTRAINT && pOp->p4.pVtab->bConstraint ){
+ if( (rc&0xff)==SQLITE_CONSTRAINT && pOp->p4.pVtab->bConstraint ){
if( pOp->p5==OE_Ignore ){
rc = SQLITE_OK;
}else{
@@ -70134,7 +80273,8 @@ case OP_VUpdate: {
**
** Write the current number of pages in database P1 to memory cell P2.
*/
-case OP_Pagecount: { /* out2-prerelease */
+case OP_Pagecount: { /* out2 */
+ pOut = out2Prerelease(p, pOp);
pOut->u.i = sqlite3BtreeLastPage(db->aDb[pOp->p1].pBt);
break;
}
@@ -70150,10 +80290,11 @@ case OP_Pagecount: { /* out2-prerelease */
**
** Store the maximum page count after the change in register P2.
*/
-case OP_MaxPgcnt: { /* out2-prerelease */
+case OP_MaxPgcnt: { /* out2 */
unsigned int newMax;
Btree *pBt;
+ pOut = out2Prerelease(p, pOp);
pBt = db->aDb[pOp->p1].pBt;
newMax = 0;
if( pOp->p3 ){
@@ -70166,37 +80307,75 @@ case OP_MaxPgcnt: { /* out2-prerelease */
#endif
-#ifndef SQLITE_OMIT_TRACE
-/* Opcode: Trace * * * P4 *
+/* Opcode: Init * P2 * P4 *
+** Synopsis: Start at P2
+**
+** Programs contain a single instance of this opcode as the very first
+** opcode.
**
** If tracing is enabled (by the sqlite3_trace()) interface, then
** the UTF-8 string contained in P4 is emitted on the trace callback.
+** Or if P4 is blank, use the string returned by sqlite3_sql().
+**
+** If P2 is not zero, jump to instruction P2.
*/
-case OP_Trace: {
-#if 0 /* local variables moved into u.cs */
+case OP_Init: { /* jump */
char *zTrace;
char *z;
-#endif /* local variables moved into u.cs */
+#ifndef SQLITE_OMIT_TRACE
if( db->xTrace
&& !p->doingRerun
- && (u.cs.zTrace = (pOp->p4.z ? pOp->p4.z : p->zSql))!=0
+ && (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);
+ z = sqlite3VdbeExpandSql(p, zTrace);
+ db->xTrace(db->pTraceArg, z);
+ sqlite3DbFree(db, z);
+ }
+#ifdef SQLITE_USE_FCNTL_TRACE
+ zTrace = (pOp->p4.z ? pOp->p4.z : p->zSql);
+ if( zTrace ){
+ int i;
+ for(i=0; i<db->nDb; i++){
+ if( DbMaskTest(p->btreeMask, i)==0 ) continue;
+ sqlite3_file_control(db, db->aDb[i].zName, SQLITE_FCNTL_TRACE, zTrace);
+ }
}
+#endif /* SQLITE_USE_FCNTL_TRACE */
#ifdef SQLITE_DEBUG
if( (db->flags & SQLITE_SqlTrace)!=0
- && (u.cs.zTrace = (pOp->p4.z ? pOp->p4.z : p->zSql))!=0
+ && (zTrace = (pOp->p4.z ? pOp->p4.z : p->zSql))!=0
){
- sqlite3DebugPrintf("SQL-trace: %s\n", u.cs.zTrace);
+ sqlite3DebugPrintf("SQL-trace: %s\n", zTrace);
}
#endif /* SQLITE_DEBUG */
+#endif /* SQLITE_OMIT_TRACE */
+ if( pOp->p2 ) goto jump_to_p2;
break;
}
-#endif
+#ifdef SQLITE_ENABLE_CURSOR_HINTS
+/* Opcode: CursorHint P1 * * P4 *
+**
+** Provide a hint to cursor P1 that it only needs to return rows that
+** satisfy the Expr in P4. TK_REGISTER terms in the P4 expression refer
+** to values currently held in registers. TK_COLUMN terms in the P4
+** expression refer to columns in the b-tree to which cursor P1 is pointing.
+*/
+case OP_CursorHint: {
+ VdbeCursor *pC;
+
+ assert( pOp->p1>=0 && pOp->p1<p->nCursor );
+ assert( pOp->p4type==P4_EXPR );
+ pC = p->apCsr[pOp->p1];
+ if( pC ){
+ assert( pC->eCurType==CURTYPE_BTREE );
+ sqlite3BtreeCursorHint(pC->uc.pCursor, BTREE_HINT_RANGE,
+ pOp->p4.pExpr, aMem);
+ }
+ break;
+}
+#endif /* SQLITE_ENABLE_CURSOR_HINTS */
/* Opcode: Noop * * * * *
**
@@ -70224,13 +80403,9 @@ default: { /* This is really OP_Noop and OP_Explain */
#ifdef VDBE_PROFILE
{
- u64 elapsed = sqlite3Hwtime() - start;
- pOp->cycles += elapsed;
- pOp->cnt++;
-#if 0
- fprintf(stdout, "%10llu ", elapsed);
- sqlite3VdbePrintOp(stdout, origPc, &aOp[origPc]);
-#endif
+ u64 endTime = sqlite3Hwtime();
+ if( endTime>start ) pOrigOp->cycles += endTime - start;
+ pOrigOp->cnt++;
}
#endif
@@ -70240,16 +80415,16 @@ default: { /* This is really OP_Noop and OP_Explain */
** the evaluator loop. So we can leave it out when NDEBUG is defined.
*/
#ifndef NDEBUG
- assert( pc>=-1 && pc<p->nOp );
+ assert( pOp>=&aOp[-1] && pOp<&aOp[p->nOp-1] );
#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( db->flags & SQLITE_VdbeTrace ){
+ if( rc!=0 ) printf("rc=%d\n",rc);
+ if( pOrigOp->opflags & (OPFLG_OUT2) ){
+ registerTrace(pOrigOp->p2, &aMem[pOrigOp->p2]);
}
- if( pOp->opflags & OPFLG_OUT3 ){
- registerTrace(p->trace, pOp->p3, &aMem[pOp->p3]);
+ if( pOrigOp->opflags & OPFLG_OUT3 ){
+ registerTrace(pOrigOp->p3, &aMem[pOrigOp->p3]);
}
}
#endif /* SQLITE_DEBUG */
@@ -70264,7 +80439,7 @@ vdbe_error_halt:
p->rc = rc;
testcase( sqlite3GlobalConfig.xLog!=0 );
sqlite3_log(rc, "statement aborts at %d: [%s] %s",
- pc, p->zSql, p->zErrMsg);
+ (int)(pOp - aOp), p->zSql, p->zErrMsg);
sqlite3VdbeHalt(p);
if( rc==SQLITE_IOERR_NOMEM ) db->mallocFailed = 1;
rc = SQLITE_ERROR;
@@ -70277,6 +80452,8 @@ vdbe_error_halt:
** top. */
vdbe_return:
db->lastRowid = lastRowid;
+ testcase( nVmStep>0 );
+ p->aCounter[SQLITE_STMTSTATUS_VM_STEP] += (int)nVmStep;
sqlite3VdbeLeave(p);
return rc;
@@ -70284,7 +80461,7 @@ vdbe_return:
** is encountered.
*/
too_big:
- sqlite3SetString(&p->zErrMsg, db, "string or blob too big");
+ sqlite3VdbeError(p, "string or blob too big");
rc = SQLITE_TOOBIG;
goto vdbe_error_halt;
@@ -70292,7 +80469,7 @@ too_big:
*/
no_mem:
db->mallocFailed = 1;
- sqlite3SetString(&p->zErrMsg, db, "out of memory");
+ sqlite3VdbeError(p, "out of memory");
rc = SQLITE_NOMEM;
goto vdbe_error_halt;
@@ -70303,7 +80480,7 @@ 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));
+ sqlite3VdbeError(p, "%s", sqlite3ErrStr(rc));
}
goto vdbe_error_halt;
@@ -70314,10 +80491,11 @@ abort_due_to_interrupt:
assert( db->u1.isInterrupted );
rc = SQLITE_INTERRUPT;
p->rc = rc;
- sqlite3SetString(&p->zErrMsg, db, "%s", sqlite3ErrStr(rc));
+ sqlite3VdbeError(p, "%s", sqlite3ErrStr(rc));
goto vdbe_error_halt;
}
+
/************** End of vdbe.c ************************************************/
/************** Begin file vdbeblob.c ****************************************/
/*
@@ -70335,6 +80513,8 @@ abort_due_to_interrupt:
** This file contains code used to implement incremental BLOB I/O.
*/
+/* #include "sqliteInt.h" */
+/* #include "vdbeInt.h" */
#ifndef SQLITE_OMIT_INCRBLOB
@@ -70384,7 +80564,8 @@ static int blobSeekToRow(Incrblob *p, sqlite3_int64 iRow, char **pzErr){
rc = sqlite3_step(p->pStmt);
if( rc==SQLITE_ROW ){
- u32 type = v->apCsr[0]->aType[p->iCol];
+ VdbeCursor *pC = v->apCsr[0];
+ u32 type = pC->aType[p->iCol];
if( type<12 ){
zErr = sqlite3MPrintf(p->db, "cannot open value of type %s",
type==0?"null": type==7?"real": "integer"
@@ -70393,12 +80574,10 @@ static int blobSeekToRow(Incrblob *p, sqlite3_int64 iRow, char **pzErr){
sqlite3_finalize(p->pStmt);
p->pStmt = 0;
}else{
- p->iOffset = v->apCsr[0]->aOffset[p->iCol];
+ p->iOffset = pC->aType[p->iCol + pC->nField];
p->nByte = sqlite3VdbeSerialTypeLen(type);
- p->pCsr = v->apCsr[0]->pCursor;
- sqlite3BtreeEnterCursor(p->pCsr);
- sqlite3BtreeCacheOverflow(p->pCsr);
- sqlite3BtreeLeaveCursor(p->pCsr);
+ p->pCsr = pC->uc.pCursor;
+ sqlite3BtreeIncrblobCursor(p->pCsr);
}
}
@@ -70425,7 +80604,7 @@ static int blobSeekToRow(Incrblob *p, sqlite3_int64 iRow, char **pzErr){
/*
** Open a blob handle.
*/
-SQLITE_API int sqlite3_blob_open(
+SQLITE_API int SQLITE_STDCALL 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 */
@@ -70452,22 +80631,20 @@ SQLITE_API int sqlite3_blob_open(
** which closes the b-tree cursor and (possibly) commits the
** transaction.
*/
+ static const int iLn = VDBE_OFFSET_LINENO(4);
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 */
-
+ /* {OP_Transaction, 0, 0, 0}, // 0: Inserted separately */
+ {OP_TableLock, 0, 0, 0}, /* 1: 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 */
+ {OP_OpenRead, 0, 0, 0}, /* 2: Open cursor 0 for reading */
+ {OP_OpenWrite, 0, 0, 0}, /* 3: Open cursor 0 for read/write */
+ {OP_Variable, 1, 1, 1}, /* 4: Push the rowid to the stack */
+ {OP_NotExists, 0, 10, 1}, /* 5: Seek the cursor */
+ {OP_Column, 0, 0, 1}, /* 6 */
+ {OP_ResultRow, 1, 0, 0}, /* 7 */
+ {OP_Goto, 0, 4, 0}, /* 8 */
+ {OP_Close, 0, 0, 0}, /* 9 */
+ {OP_Halt, 0, 0, 0}, /* 10 */
};
int rc = SQLITE_OK;
@@ -70476,8 +80653,18 @@ SQLITE_API int sqlite3_blob_open(
Parse *pParse = 0;
Incrblob *pBlob = 0;
- flags = !!flags; /* flags = (flags ? 1 : 0); */
+#ifdef SQLITE_ENABLE_API_ARMOR
+ if( ppBlob==0 ){
+ return SQLITE_MISUSE_BKPT;
+ }
+#endif
*ppBlob = 0;
+#ifdef SQLITE_ENABLE_API_ARMOR
+ if( !sqlite3SafetyCheckOk(db) || zTable==0 ){
+ return SQLITE_MISUSE_BKPT;
+ }
+#endif
+ flags = !!flags; /* flags = (flags ? 1 : 0); */
sqlite3_mutex_enter(db->mutex);
@@ -70498,6 +80685,10 @@ SQLITE_API int sqlite3_blob_open(
pTab = 0;
sqlite3ErrorMsg(pParse, "cannot open virtual table: %s", zTable);
}
+ if( pTab && !HasRowid(pTab) ){
+ pTab = 0;
+ sqlite3ErrorMsg(pParse, "cannot open table without rowid: %s", zTable);
+ }
#ifndef SQLITE_OMIT_VIEW
if( pTab && pTab->pSelect ){
pTab = 0;
@@ -70555,8 +80746,9 @@ SQLITE_API int sqlite3_blob_open(
#endif
for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){
int j;
- for(j=0; j<pIdx->nColumn; j++){
- if( pIdx->aiColumn[j]==iCol ){
+ for(j=0; j<pIdx->nKeyCol; j++){
+ /* FIXME: Be smarter about indexes that use expressions */
+ if( pIdx->aiColumn[j]==iCol || pIdx->aiColumn[j]==XN_EXPR ){
zFault = "indexed";
}
}
@@ -70570,42 +80762,37 @@ SQLITE_API int sqlite3_blob_open(
}
}
- pBlob->pStmt = (sqlite3_stmt *)sqlite3VdbeCreate(db);
+ pBlob->pStmt = (sqlite3_stmt *)sqlite3VdbeCreate(pParse);
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);
+ sqlite3VdbeAddOp4Int(v, OP_Transaction, iDb, flags,
+ pTab->pSchema->schema_cookie,
+ pTab->pSchema->iGeneration);
+ sqlite3VdbeChangeP5(v, 1);
+ sqlite3VdbeAddOpList(v, ArraySize(openBlob), openBlob, iLn);
/* 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);
+ sqlite3VdbeChangeToNoop(v, 1);
#else
- sqlite3VdbeChangeP1(v, 2, iDb);
- sqlite3VdbeChangeP2(v, 2, pTab->tnum);
- sqlite3VdbeChangeP3(v, 2, flags);
- sqlite3VdbeChangeP4(v, 2, pTab->zName, P4_TRANSIENT);
+ sqlite3VdbeChangeP1(v, 1, iDb);
+ sqlite3VdbeChangeP2(v, 1, pTab->tnum);
+ sqlite3VdbeChangeP3(v, 1, flags);
+ sqlite3VdbeChangeP4(v, 1, 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);
+ sqlite3VdbeChangeToNoop(v, 3 - flags);
+ sqlite3VdbeChangeP2(v, 2 + flags, pTab->tnum);
+ sqlite3VdbeChangeP3(v, 2 + flags, iDb);
/* Configure the number of columns. Configure the cursor to
** think that the table has one more column than it really
@@ -70614,8 +80801,8 @@ SQLITE_API int sqlite3_blob_open(
** 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);
+ sqlite3VdbeChangeP4(v, 2+flags, SQLITE_INT_TO_PTR(pTab->nCol+1),P4_INT32);
+ sqlite3VdbeChangeP2(v, 6, pTab->nCol);
if( !db->mallocFailed ){
pParse->nVar = 1;
pParse->nMem = 1;
@@ -70633,7 +80820,7 @@ SQLITE_API int sqlite3_blob_open(
}
sqlite3_bind_int64(pBlob->pStmt, 1, iRow);
rc = blobSeekToRow(pBlob, iRow, &zErr);
- } while( (++nAttempt)<5 && rc==SQLITE_SCHEMA );
+ } while( (++nAttempt)<SQLITE_MAX_SCHEMA_RETRY && rc==SQLITE_SCHEMA );
blob_open_out:
if( rc==SQLITE_OK && db->mallocFailed==0 ){
@@ -70642,8 +80829,9 @@ blob_open_out:
if( pBlob && pBlob->pStmt ) sqlite3VdbeFinalize((Vdbe *)pBlob->pStmt);
sqlite3DbFree(db, pBlob);
}
- sqlite3Error(db, rc, (zErr ? "%s" : 0), zErr);
+ sqlite3ErrorWithMsg(db, rc, (zErr ? "%s" : 0), zErr);
sqlite3DbFree(db, zErr);
+ sqlite3ParserReset(pParse);
sqlite3StackFree(db, pParse);
rc = sqlite3ApiExit(db, rc);
sqlite3_mutex_leave(db->mutex);
@@ -70654,7 +80842,7 @@ blob_open_out:
** Close a blob handle that was previously created using
** sqlite3_blob_open().
*/
-SQLITE_API int sqlite3_blob_close(sqlite3_blob *pBlob){
+SQLITE_API int SQLITE_STDCALL sqlite3_blob_close(sqlite3_blob *pBlob){
Incrblob *p = (Incrblob *)pBlob;
int rc;
sqlite3 *db;
@@ -70691,10 +80879,9 @@ static int blobReadWrite(
sqlite3_mutex_enter(db->mutex);
v = (Vdbe*)p->pStmt;
- if( n<0 || iOffset<0 || (iOffset+n)>p->nByte ){
+ if( n<0 || iOffset<0 || ((sqlite3_int64)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.
@@ -70712,10 +80899,10 @@ static int blobReadWrite(
sqlite3VdbeFinalize(v);
p->pStmt = 0;
}else{
- db->errCode = rc;
v->rc = rc;
}
}
+ sqlite3Error(db, rc);
rc = sqlite3ApiExit(db, rc);
sqlite3_mutex_leave(db->mutex);
return rc;
@@ -70724,14 +80911,14 @@ static int blobReadWrite(
/*
** Read data from a blob handle.
*/
-SQLITE_API int sqlite3_blob_read(sqlite3_blob *pBlob, void *z, int n, int iOffset){
+SQLITE_API int SQLITE_STDCALL 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){
+SQLITE_API int SQLITE_STDCALL sqlite3_blob_write(sqlite3_blob *pBlob, const void *z, int n, int iOffset){
return blobReadWrite(pBlob, (void *)z, n, iOffset, sqlite3BtreePutData);
}
@@ -70741,7 +80928,7 @@ SQLITE_API int sqlite3_blob_write(sqlite3_blob *pBlob, const void *z, int n, int
** 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){
+SQLITE_API int SQLITE_STDCALL sqlite3_blob_bytes(sqlite3_blob *pBlob){
Incrblob *p = (Incrblob *)pBlob;
return (p && p->pStmt) ? p->nByte : 0;
}
@@ -70756,7 +80943,7 @@ SQLITE_API int sqlite3_blob_bytes(sqlite3_blob *pBlob){
** 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){
+SQLITE_API int SQLITE_STDCALL sqlite3_blob_reopen(sqlite3_blob *pBlob, sqlite3_int64 iRow){
int rc;
Incrblob *p = (Incrblob *)pBlob;
sqlite3 *db;
@@ -70774,7 +80961,7 @@ SQLITE_API int sqlite3_blob_reopen(sqlite3_blob *pBlob, sqlite3_int64 iRow){
char *zErr;
rc = blobSeekToRow(p, iRow, &zErr);
if( rc!=SQLITE_OK ){
- sqlite3Error(db, rc, (zErr ? "%s" : 0), zErr);
+ sqlite3ErrorWithMsg(db, rc, (zErr ? "%s" : 0), zErr);
sqlite3DbFree(db, zErr);
}
assert( rc!=SQLITE_SCHEMA );
@@ -70791,7 +80978,7 @@ SQLITE_API int sqlite3_blob_reopen(sqlite3_blob *pBlob, sqlite3_int64 iRow){
/************** End of vdbeblob.c ********************************************/
/************** Begin file vdbesort.c ****************************************/
/*
-** 2011 July 9
+** 2011-07-09
**
** The author disclaims copyright to this source code. In place of
** a legal notice, here is a blessing:
@@ -70802,78 +80989,240 @@ SQLITE_API int sqlite3_blob_reopen(sqlite3_blob *pBlob, sqlite3_int64 iRow){
**
*************************************************************************
** 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).
+** a VdbeCursor to sort large numbers of keys for CREATE INDEX statements
+** or by SELECT statements with ORDER BY clauses that cannot be satisfied
+** using indexes and without LIMIT clauses.
+**
+** The VdbeSorter object implements a multi-threaded external merge sort
+** algorithm that is efficient even if the number of elements being sorted
+** exceeds the available memory.
+**
+** Here is the (internal, non-API) interface between this module and the
+** rest of the SQLite system:
+**
+** sqlite3VdbeSorterInit() Create a new VdbeSorter object.
+**
+** sqlite3VdbeSorterWrite() Add a single new row to the VdbeSorter
+** object. The row is a binary blob in the
+** OP_MakeRecord format that contains both
+** the ORDER BY key columns and result columns
+** in the case of a SELECT w/ ORDER BY, or
+** the complete record for an index entry
+** in the case of a CREATE INDEX.
+**
+** sqlite3VdbeSorterRewind() Sort all content previously added.
+** Position the read cursor on the
+** first sorted element.
+**
+** sqlite3VdbeSorterNext() Advance the read cursor to the next sorted
+** element.
+**
+** sqlite3VdbeSorterRowkey() Return the complete binary blob for the
+** row currently under the read cursor.
+**
+** sqlite3VdbeSorterCompare() Compare the binary blob for the row
+** currently under the read cursor against
+** another binary blob X and report if
+** X is strictly less than the read cursor.
+** Used to enforce uniqueness in a
+** CREATE UNIQUE INDEX statement.
+**
+** sqlite3VdbeSorterClose() Close the VdbeSorter object and reclaim
+** all resources.
+**
+** sqlite3VdbeSorterReset() Refurbish the VdbeSorter for reuse. This
+** is like Close() followed by Init() only
+** much faster.
+**
+** The interfaces above must be called in a particular order. Write() can
+** only occur in between Init()/Reset() and Rewind(). Next(), Rowkey(), and
+** Compare() can only occur in between Rewind() and Close()/Reset(). i.e.
+**
+** Init()
+** for each record: Write()
+** Rewind()
+** Rowkey()/Compare()
+** Next()
+** Close()
+**
+** Algorithm:
+**
+** Records passed to the sorter via calls to Write() are initially held
+** unsorted in main memory. Assuming the amount of memory used never exceeds
+** a threshold, when Rewind() is called the set of records is sorted using
+** an in-memory merge sort. In this case, no temporary files are required
+** and subsequent calls to Rowkey(), Next() and Compare() read records
+** directly from main memory.
+**
+** If the amount of space used to store records in main memory exceeds the
+** threshold, then the set of records currently in memory are sorted and
+** written to a temporary file in "Packed Memory Array" (PMA) format.
+** A PMA created at this point is known as a "level-0 PMA". Higher levels
+** of PMAs may be created by merging existing PMAs together - for example
+** merging two or more level-0 PMAs together creates a level-1 PMA.
+**
+** The threshold for the amount of main memory to use before flushing
+** records to a PMA is roughly the same as the limit configured for the
+** page-cache of the main database. Specifically, the threshold is set to
+** the value returned by "PRAGMA main.page_size" multipled by
+** that returned by "PRAGMA main.cache_size", in bytes.
+**
+** If the sorter is running in single-threaded mode, then all PMAs generated
+** are appended to a single temporary file. Or, if the sorter is running in
+** multi-threaded mode then up to (N+1) temporary files may be opened, where
+** N is the configured number of worker threads. In this case, instead of
+** sorting the records and writing the PMA to a temporary file itself, the
+** calling thread usually launches a worker thread to do so. Except, if
+** there are already N worker threads running, the main thread does the work
+** itself.
+**
+** The sorter is running in multi-threaded mode if (a) the library was built
+** with pre-processor symbol SQLITE_MAX_WORKER_THREADS set to a value greater
+** than zero, and (b) worker threads have been enabled at runtime by calling
+** "PRAGMA threads=N" with some value of N greater than 0.
+**
+** When Rewind() is called, any data remaining in memory is flushed to a
+** final PMA. So at this point the data is stored in some number of sorted
+** PMAs within temporary files on disk.
+**
+** If there are fewer than SORTER_MAX_MERGE_COUNT PMAs in total and the
+** sorter is running in single-threaded mode, then these PMAs are merged
+** incrementally as keys are retreived from the sorter by the VDBE. The
+** MergeEngine object, described in further detail below, performs this
+** merge.
+**
+** Or, if running in multi-threaded mode, then a background thread is
+** launched to merge the existing PMAs. Once the background thread has
+** merged T bytes of data into a single sorted PMA, the main thread
+** begins reading keys from that PMA while the background thread proceeds
+** with merging the next T bytes of data. And so on.
+**
+** Parameter T is set to half the value of the memory threshold used
+** by Write() above to determine when to create a new PMA.
+**
+** If there are more than SORTER_MAX_MERGE_COUNT PMAs in total when
+** Rewind() is called, then a hierarchy of incremental-merges is used.
+** First, T bytes of data from the first SORTER_MAX_MERGE_COUNT PMAs on
+** disk are merged together. Then T bytes of data from the second set, and
+** so on, such that no operation ever merges more than SORTER_MAX_MERGE_COUNT
+** PMAs at a time. This done is to improve locality.
+**
+** If running in multi-threaded mode and there are more than
+** SORTER_MAX_MERGE_COUNT PMAs on disk when Rewind() is called, then more
+** than one background thread may be created. Specifically, there may be
+** one background thread for each temporary file on disk, and one background
+** thread to merge the output of each of the others to a single PMA for
+** the main thread to read from.
+*/
+/* #include "sqliteInt.h" */
+/* #include "vdbeInt.h" */
+
+/*
+** If SQLITE_DEBUG_SORTER_THREADS is defined, this module outputs various
+** messages to stderr that may be helpful in understanding the performance
+** characteristics of the sorter in multi-threaded mode.
*/
+#if 0
+# define SQLITE_DEBUG_SORTER_THREADS 1
+#endif
+/*
+** Hard-coded maximum amount of data to accumulate in memory before flushing
+** to a level 0 PMA. The purpose of this limit is to prevent various integer
+** overflows. 512MiB.
+*/
+#define SQLITE_MAX_PMASZ (1<<29)
-#ifndef SQLITE_OMIT_MERGE_SORT
+/*
+** Private objects used by the sorter
+*/
+typedef struct MergeEngine MergeEngine; /* Merge PMAs together */
+typedef struct PmaReader PmaReader; /* Incrementally read one PMA */
+typedef struct PmaWriter PmaWriter; /* Incrementally write one PMA */
+typedef struct SorterRecord SorterRecord; /* A record being sorted */
+typedef struct SortSubtask SortSubtask; /* A sub-task in the sort process */
+typedef struct SorterFile SorterFile; /* Temporary file object wrapper */
+typedef struct SorterList SorterList; /* In-memory list of records */
+typedef struct IncrMerger IncrMerger; /* Read & merge multiple PMAs */
-typedef struct VdbeSorterIter VdbeSorterIter;
-typedef struct SorterRecord SorterRecord;
-typedef struct FileWriter FileWriter;
+/*
+** A container for a temp file handle and the current amount of data
+** stored in the file.
+*/
+struct SorterFile {
+ sqlite3_file *pFd; /* File handle */
+ i64 iEof; /* Bytes of data stored in pFd */
+};
/*
-** NOTES ON DATA STRUCTURE USED FOR N-WAY MERGES:
+** An in-memory list of objects to be sorted.
**
-** 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.
+** If aMemory==0 then each object is allocated separately and the objects
+** are connected using SorterRecord.u.pNext. If aMemory!=0 then all objects
+** are stored in the aMemory[] bulk memory, one right after the other, and
+** are connected using SorterRecord.u.iNext.
+*/
+struct SorterList {
+ SorterRecord *pList; /* Linked list of records */
+ u8 *aMemory; /* If non-NULL, bulk memory to hold pList */
+ int szPMA; /* Size of pList as PMA in bytes */
+};
+
+/*
+** The MergeEngine object is used to combine two or more smaller PMAs into
+** one big PMA using a merge operation. Separate PMAs all need to be
+** combined into one big PMA in order to be able to step through the sorted
+** records in order.
**
-** 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 aReadr[] array contains a PmaReader object for each of the PMAs being
+** merged. An aReadr[] object either points to a valid key or else is at EOF.
+** ("EOF" means "End Of File". When aReadr[] is at EOF there is no more data.)
+** 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 PMAs being merged. The extra aReadr[] 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 MergeEngine.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
+** pairs of PMA keys together. Element i contains the result of
+** comparing aReadr[2*i-N] and aReadr[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
+** The (N/4) elements of aTree[] that precede the final (N/2) described
+** above contains the index of the smallest of each block of 4 PmaReaders
+** And so on. So that aTree[1] contains the index of the PmaReader 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
+** aReadr[0] -> Banana
+** aReadr[1] -> Feijoa
+** aReadr[2] -> Elderberry
+** aReadr[3] -> Currant
+** aReadr[4] -> Grapefruit
+** aReadr[5] -> Apple
+** aReadr[6] -> Durian
+** aReadr[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
+** PmaReader 5). When the Next() operation is invoked, PmaReader 5 will
** be advanced to the next key in its segment. Say the next key is
** "Eggplant":
**
-** aIter[5] -> Eggplant
+** aReadr[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
+** The contents of aTree[] are updated first by comparing the new PmaReader
+** 5 key to the current key of PmaReader 4 (still "Grapefruit"). The PmaReader
** 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
+** The value of PmaReader 6 - "Durian" - is now smaller than that of PmaReader
** 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:
**
@@ -70883,97 +81232,250 @@ typedef struct FileWriter FileWriter;
** key comparison operations are required, where N is the number of segments
** being merged (rounded up to the next power of 2).
*/
+struct MergeEngine {
+ int nTree; /* Used size of aTree/aReadr (power of 2) */
+ SortSubtask *pTask; /* Used by this thread only */
+ int *aTree; /* Current state of incremental merge */
+ PmaReader *aReadr; /* Array of PmaReaders to merge data from */
+};
+
+/*
+** This object represents a single thread of control in a sort operation.
+** Exactly VdbeSorter.nTask instances of this object are allocated
+** as part of each VdbeSorter object. Instances are never allocated any
+** other way. VdbeSorter.nTask is set to the number of worker threads allowed
+** (see SQLITE_CONFIG_WORKER_THREADS) plus one (the main thread). Thus for
+** single-threaded operation, there is exactly one instance of this object
+** and for multi-threaded operation there are two or more instances.
+**
+** Essentially, this structure contains all those fields of the VdbeSorter
+** structure for which each thread requires a separate instance. For example,
+** each thread requries its own UnpackedRecord object to unpack records in
+** as part of comparison operations.
+**
+** Before a background thread is launched, variable bDone is set to 0. Then,
+** right before it exits, the thread itself sets bDone to 1. This is used for
+** two purposes:
+**
+** 1. When flushing the contents of memory to a level-0 PMA on disk, to
+** attempt to select a SortSubtask for which there is not already an
+** active background thread (since doing so causes the main thread
+** to block until it finishes).
+**
+** 2. If SQLITE_DEBUG_SORTER_THREADS is defined, to determine if a call
+** to sqlite3ThreadJoin() is likely to block. Cases that are likely to
+** block provoke debugging output.
+**
+** In both cases, the effects of the main thread seeing (bDone==0) even
+** after the thread has finished are not dire. So we don't worry about
+** memory barriers and such here.
+*/
+typedef int (*SorterCompare)(SortSubtask*,int*,const void*,int,const void*,int);
+struct SortSubtask {
+ SQLiteThread *pThread; /* Background thread, if any */
+ int bDone; /* Set if thread is finished but not joined */
+ VdbeSorter *pSorter; /* Sorter that owns this sub-task */
+ UnpackedRecord *pUnpacked; /* Space to unpack a record */
+ SorterList list; /* List for thread to write to a PMA */
+ int nPMA; /* Number of PMAs currently in file */
+ SorterCompare xCompare; /* Compare function to use */
+ SorterFile file; /* Temp file for level-0 PMAs */
+ SorterFile file2; /* Space for other PMAs */
+};
+
+
+/*
+** Main sorter structure. A single instance of this is allocated for each
+** sorter cursor created by the VDBE.
+**
+** mxKeysize:
+** As records are added to the sorter by calls to sqlite3VdbeSorterWrite(),
+** this variable is updated so as to be set to the size on disk of the
+** largest record in the sorter.
+*/
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 */
+ int mxKeysize; /* Largest serialized key seen so far */
+ int pgsz; /* Main database page size */
+ PmaReader *pReader; /* Readr data from here after Rewind() */
+ MergeEngine *pMerger; /* Or here, if bUseThreads==0 */
+ sqlite3 *db; /* Database connection */
+ KeyInfo *pKeyInfo; /* How to compare records */
+ UnpackedRecord *pUnpacked; /* Used by VdbeSorterCompare() */
+ SorterList list; /* List of in-memory records */
+ int iMemory; /* Offset of free space in list.aMemory */
+ int nMemory; /* Size of list.aMemory allocation in bytes */
+ u8 bUsePMA; /* True if one or more PMAs created */
+ u8 bUseThreads; /* True to use background threads */
+ u8 iPrev; /* Previous thread used to flush PMA */
+ u8 nTask; /* Size of aTask[] array */
+ u8 typeMask;
+ SortSubtask aTask[1]; /* One or more subtasks */
+};
+
+#define SORTER_TYPE_INTEGER 0x01
+#define SORTER_TYPE_TEXT 0x02
+
+/*
+** An instance of the following object is used to read records out of a
+** PMA, in sorted order. The next key to be read is cached in nKey/aKey.
+** aKey might point into aMap or into aBuffer. If neither of those locations
+** contain a contiguous representation of the key, then aAlloc is allocated
+** and the key is copied into aAlloc and aKey is made to poitn to aAlloc.
+**
+** pFd==0 at EOF.
+*/
+struct PmaReader {
+ i64 iReadOff; /* Current read offset */
+ i64 iEof; /* 1 byte past EOF for this PmaReader */
+ int nAlloc; /* Bytes of space at aAlloc */
+ int nKey; /* Number of bytes in key */
+ sqlite3_file *pFd; /* File handle we are reading from */
+ u8 *aAlloc; /* Space for aKey if aBuffer and pMap wont work */
+ u8 *aKey; /* Pointer to current key */
+ u8 *aBuffer; /* Current read buffer */
+ int nBuffer; /* Size of read buffer in bytes */
+ u8 *aMap; /* Pointer to mapping of entire file */
+ IncrMerger *pIncr; /* Incremental merger */
};
/*
-** 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 */
+** Normally, a PmaReader object iterates through an existing PMA stored
+** within a temp file. However, if the PmaReader.pIncr variable points to
+** an object of the following type, it may be used to iterate/merge through
+** multiple PMAs simultaneously.
+**
+** There are two types of IncrMerger object - single (bUseThread==0) and
+** multi-threaded (bUseThread==1).
+**
+** A multi-threaded IncrMerger object uses two temporary files - aFile[0]
+** and aFile[1]. Neither file is allowed to grow to more than mxSz bytes in
+** size. When the IncrMerger is initialized, it reads enough data from
+** pMerger to populate aFile[0]. It then sets variables within the
+** corresponding PmaReader object to read from that file and kicks off
+** a background thread to populate aFile[1] with the next mxSz bytes of
+** sorted record data from pMerger.
+**
+** When the PmaReader reaches the end of aFile[0], it blocks until the
+** background thread has finished populating aFile[1]. It then exchanges
+** the contents of the aFile[0] and aFile[1] variables within this structure,
+** sets the PmaReader fields to read from the new aFile[0] and kicks off
+** another background thread to populate the new aFile[1]. And so on, until
+** the contents of pMerger are exhausted.
+**
+** A single-threaded IncrMerger does not open any temporary files of its
+** own. Instead, it has exclusive access to mxSz bytes of space beginning
+** at offset iStartOff of file pTask->file2. And instead of using a
+** background thread to prepare data for the PmaReader, with a single
+** threaded IncrMerger the allocate part of pTask->file2 is "refilled" with
+** keys from pMerger by the calling thread whenever the PmaReader runs out
+** of data.
+*/
+struct IncrMerger {
+ SortSubtask *pTask; /* Task that owns this merger */
+ MergeEngine *pMerger; /* Merge engine thread reads data from */
+ i64 iStartOff; /* Offset to start writing file at */
+ int mxSz; /* Maximum bytes of data to store */
+ int bEof; /* Set to true when merge is finished */
+ int bUseThread; /* True to use a bg thread for this object */
+ SorterFile aFile[2]; /* aFile[0] for reading, [1] for writing */
};
/*
-** 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.
+** An instance of this object is used for writing a PMA.
+**
+** The PMA is written one record at a time. Each record is of an arbitrary
+** size. But I/O is more efficient if it occurs in page-sized blocks where
+** each block is aligned on a page boundary. This object caches writes to
+** the PMA so that aligned, page-size blocks are written.
*/
-struct FileWriter {
+struct PmaWriter {
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 */
+ sqlite3_file *pFd; /* File handle 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.
+** This object is the header on a single record while that record is being
+** held in memory and prior to being written out as part of a PMA.
+**
+** How the linked list is connected depends on how memory is being managed
+** by this module. If using a separate allocation for each in-memory record
+** (VdbeSorter.list.aMemory==0), then the list is always connected using the
+** SorterRecord.u.pNext pointers.
+**
+** Or, if using the single large allocation method (VdbeSorter.list.aMemory!=0),
+** then while records are being accumulated the list is linked using the
+** SorterRecord.u.iNext offset. This is because the aMemory[] array may
+** be sqlite3Realloc()ed while records are being accumulated. Once the VM
+** has finished passing records to the sorter, or when the in-memory buffer
+** is full, the list is sorted. As part of the sorting process, it is
+** converted to use the SorterRecord.u.pNext pointers. See function
+** vdbeSorterSort() for details.
*/
struct SorterRecord {
- void *pVal;
- int nVal;
- SorterRecord *pNext;
+ int nVal; /* Size of the record in bytes */
+ union {
+ SorterRecord *pNext; /* Pointer to next record in list */
+ int iNext; /* Offset within aMemory of next record */
+ } u;
+ /* The data for the record immediately follows this header */
};
-/* Minimum allowable value for the VdbeSorter.nWorking variable */
-#define SORTER_MIN_WORKING 10
+/* Return a pointer to the buffer containing the record data for SorterRecord
+** object p. Should be used as if:
+**
+** void *SRVAL(SorterRecord *p) { return (void*)&p[1]; }
+*/
+#define SRVAL(p) ((void*)((SorterRecord*)(p) + 1))
+
-/* Maximum number of segments to merge in a single pass. */
+/* Maximum number of PMAs that a single MergeEngine can merge */
#define SORTER_MAX_MERGE_COUNT 16
+static int vdbeIncrSwap(IncrMerger*);
+static void vdbeIncrFree(IncrMerger *);
+
/*
-** Free all memory belonging to the VdbeSorterIter object passed as the second
+** Free all memory belonging to the PmaReader object passed as the
** 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));
+static void vdbePmaReaderClear(PmaReader *pReadr){
+ sqlite3_free(pReadr->aAlloc);
+ sqlite3_free(pReadr->aBuffer);
+ if( pReadr->aMap ) sqlite3OsUnfetch(pReadr->pFd, 0, pReadr->aMap);
+ vdbeIncrFree(pReadr->pIncr);
+ memset(pReadr, 0, sizeof(PmaReader));
}
/*
-** Read nByte bytes of data from the stream of data iterated by object p.
+** Read the next nByte bytes of data from the PMA 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
+** The buffer returned in *ppOut is only valid until the
** next call to this function.
*/
-static int vdbeSorterIterRead(
- sqlite3 *db, /* Database handle (for malloc) */
- VdbeSorterIter *p, /* Iterator */
+static int vdbePmaReadBlob(
+ PmaReader *p, /* PmaReader from which to take the blob */
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 */
+
+ if( p->aMap ){
+ *ppOut = &p->aMap[p->iReadOff];
+ p->iReadOff += nByte;
+ return SQLITE_OK;
+ }
+
assert( p->aBuffer );
/* If there is no more data to be read from the buffer, read the next
@@ -70992,8 +81494,8 @@ static int vdbeSorterIterRead(
}
assert( nRead>0 );
- /* Read data from the file. Return early if an error occurs. */
- rc = sqlite3OsRead(p->pFile, p->aBuffer, nRead, p->iReadOff);
+ /* Readr data from the file. Return early if an error occurs. */
+ rc = sqlite3OsRead(p->pFd, p->aBuffer, nRead, p->iReadOff);
assert( rc!=SQLITE_IOERR_SHORT_READ );
if( rc!=SQLITE_OK ) return rc;
}
@@ -71013,11 +81515,13 @@ static int vdbeSorterIterRead(
/* Extend the p->aAlloc[] allocation if required. */
if( p->nAlloc<nByte ){
- int nNew = p->nAlloc*2;
+ u8 *aNew;
+ int nNew = MAX(128, p->nAlloc*2);
while( nByte>nNew ) nNew = nNew*2;
- p->aAlloc = sqlite3DbReallocOrFree(db, p->aAlloc, nNew);
- if( !p->aAlloc ) return SQLITE_NOMEM;
+ aNew = sqlite3Realloc(p->aAlloc, nNew);
+ if( !aNew ) return SQLITE_NOMEM;
p->nAlloc = nNew;
+ p->aAlloc = aNew;
}
/* Copy as much data as is available in the buffer into the start of
@@ -71029,13 +81533,13 @@ static int vdbeSorterIterRead(
/* 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 rc; /* vdbePmaReadBlob() 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);
+ rc = vdbePmaReadBlob(p, nCopy, &aNext);
if( rc!=SQLITE_OK ) return rc;
assert( aNext!=p->aAlloc );
memcpy(&p->aAlloc[nByte - nRem], aNext, nCopy);
@@ -71052,236 +81556,445 @@ static int vdbeSorterIterRead(
** 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){
+static int vdbePmaReadVarint(PmaReader *p, u64 *pnOut){
int iBuf;
- iBuf = p->iReadOff % p->nBuffer;
- if( iBuf && (p->nBuffer-iBuf)>=9 ){
- p->iReadOff += sqlite3GetVarint(&p->aBuffer[iBuf], pnOut);
+ if( p->aMap ){
+ p->iReadOff += sqlite3GetVarint(&p->aMap[p->iReadOff], 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);
+ 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 = vdbePmaReadBlob(p, 1, &a);
+ if( rc ) return rc;
+ aVarint[(i++)&0xf] = a[0];
+ }while( (a[0]&0x80)!=0 );
+ sqlite3GetVarint(aVarint, pnOut);
+ }
}
return SQLITE_OK;
}
+/*
+** Attempt to memory map file pFile. If successful, set *pp to point to the
+** new mapping and return SQLITE_OK. If the mapping is not attempted
+** (because the file is too large or the VFS layer is configured not to use
+** mmap), return SQLITE_OK and set *pp to NULL.
+**
+** Or, if an error occurs, return an SQLite error code. The final value of
+** *pp is undefined in this case.
+*/
+static int vdbeSorterMapFile(SortSubtask *pTask, SorterFile *pFile, u8 **pp){
+ int rc = SQLITE_OK;
+ if( pFile->iEof<=(i64)(pTask->pSorter->db->nMaxSorterMmap) ){
+ sqlite3_file *pFd = pFile->pFd;
+ if( pFd->pMethods->iVersion>=3 ){
+ rc = sqlite3OsFetch(pFd, 0, (int)pFile->iEof, (void**)pp);
+ testcase( rc!=SQLITE_OK );
+ }
+ }
+ return rc;
+}
/*
-** 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.
+** Attach PmaReader pReadr to file pFile (if it is not already attached to
+** that file) and seek it to offset iOff within the file. Return SQLITE_OK
+** if successful, or an SQLite error code if an error occurs.
*/
-static int vdbeSorterIterNext(
- sqlite3 *db, /* Database handle (for sqlite3DbMalloc() ) */
- VdbeSorterIter *pIter /* Iterator to advance */
+static int vdbePmaReaderSeek(
+ SortSubtask *pTask, /* Task context */
+ PmaReader *pReadr, /* Reader whose cursor is to be moved */
+ SorterFile *pFile, /* Sorter file to read from */
+ i64 iOff /* Offset in pFile */
){
- int rc; /* Return Code */
+ int rc = SQLITE_OK;
+
+ assert( pReadr->pIncr==0 || pReadr->pIncr->bEof==0 );
+
+ if( sqlite3FaultSim(201) ) return SQLITE_IOERR_READ;
+ if( pReadr->aMap ){
+ sqlite3OsUnfetch(pReadr->pFd, 0, pReadr->aMap);
+ pReadr->aMap = 0;
+ }
+ pReadr->iReadOff = iOff;
+ pReadr->iEof = pFile->iEof;
+ pReadr->pFd = pFile->pFd;
+
+ rc = vdbeSorterMapFile(pTask, pFile, &pReadr->aMap);
+ if( rc==SQLITE_OK && pReadr->aMap==0 ){
+ int pgsz = pTask->pSorter->pgsz;
+ int iBuf = pReadr->iReadOff % pgsz;
+ if( pReadr->aBuffer==0 ){
+ pReadr->aBuffer = (u8*)sqlite3Malloc(pgsz);
+ if( pReadr->aBuffer==0 ) rc = SQLITE_NOMEM;
+ pReadr->nBuffer = pgsz;
+ }
+ if( rc==SQLITE_OK && iBuf ){
+ int nRead = pgsz - iBuf;
+ if( (pReadr->iReadOff + nRead) > pReadr->iEof ){
+ nRead = (int)(pReadr->iEof - pReadr->iReadOff);
+ }
+ rc = sqlite3OsRead(
+ pReadr->pFd, &pReadr->aBuffer[iBuf], nRead, pReadr->iReadOff
+ );
+ testcase( rc!=SQLITE_OK );
+ }
+ }
+
+ return rc;
+}
+
+/*
+** Advance PmaReader pReadr to the next key in its PMA. Return SQLITE_OK if
+** no error occurs, or an SQLite error code if one does.
+*/
+static int vdbePmaReaderNext(PmaReader *pReadr){
+ int rc = SQLITE_OK; /* 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;
+
+ if( pReadr->iReadOff>=pReadr->iEof ){
+ IncrMerger *pIncr = pReadr->pIncr;
+ int bEof = 1;
+ if( pIncr ){
+ rc = vdbeIncrSwap(pIncr);
+ if( rc==SQLITE_OK && pIncr->bEof==0 ){
+ rc = vdbePmaReaderSeek(
+ pIncr->pTask, pReadr, &pIncr->aFile[0], pIncr->iStartOff
+ );
+ bEof = 0;
+ }
+ }
+
+ if( bEof ){
+ /* This is an EOF condition */
+ vdbePmaReaderClear(pReadr);
+ testcase( rc!=SQLITE_OK );
+ return rc;
+ }
}
- rc = vdbeSorterIterVarint(db, pIter, &nRec);
if( rc==SQLITE_OK ){
- pIter->nKey = (int)nRec;
- rc = vdbeSorterIterRead(db, pIter, (int)nRec, &pIter->aKey);
+ rc = vdbePmaReadVarint(pReadr, &nRec);
+ }
+ if( rc==SQLITE_OK ){
+ pReadr->nKey = (int)nRec;
+ rc = vdbePmaReadBlob(pReadr, (int)nRec, &pReadr->aKey);
+ testcase( rc!=SQLITE_OK );
}
return rc;
}
/*
-** Initialize iterator pIter to scan through the PMA stored in file pFile
+** Initialize PmaReader pReadr 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
+** leaves the PmaReader pointing to the first key in the PMA (or EOF if the
** PMA is empty).
+**
+** If the pnByte parameter is NULL, then it is assumed that the file
+** contains a single PMA, and that that PMA omits the initial length varint.
*/
-static int vdbeSorterIterInit(
- sqlite3 *db, /* Database handle */
- const VdbeSorter *pSorter, /* Sorter object */
+static int vdbePmaReaderInit(
+ SortSubtask *pTask, /* Task context */
+ SorterFile *pFile, /* Sorter file to read from */
i64 iStart, /* Start offset in pFile */
- VdbeSorterIter *pIter, /* Iterator to populate */
+ PmaReader *pReadr, /* PmaReader 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;
+ int rc;
- 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 );
- }
+ assert( pFile->iEof>iStart );
+ assert( pReadr->aAlloc==0 && pReadr->nAlloc==0 );
+ assert( pReadr->aBuffer==0 );
+ assert( pReadr->aMap==0 );
- 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;
- }
+ rc = vdbePmaReaderSeek(pTask, pReadr, pFile, iStart);
+ if( rc==SQLITE_OK ){
+ u64 nByte; /* Size of PMA in bytes */
+ rc = vdbePmaReadVarint(pReadr, &nByte);
+ pReadr->iEof = pReadr->iReadOff + nByte;
+ *pnByte += nByte;
}
if( rc==SQLITE_OK ){
- rc = vdbeSorterIterNext(db, pIter);
+ rc = vdbePmaReaderNext(pReadr);
}
return rc;
}
+/*
+** A version of vdbeSorterCompare() that assumes that it has already been
+** determined that the first field of key1 is equal to the first field of
+** key2.
+*/
+static int vdbeSorterCompareTail(
+ SortSubtask *pTask, /* Subtask context (for pKeyInfo) */
+ int *pbKey2Cached, /* True if pTask->pUnpacked is pKey2 */
+ const void *pKey1, int nKey1, /* Left side of comparison */
+ const void *pKey2, int nKey2 /* Right side of comparison */
+){
+ UnpackedRecord *r2 = pTask->pUnpacked;
+ if( *pbKey2Cached==0 ){
+ sqlite3VdbeRecordUnpack(pTask->pSorter->pKeyInfo, nKey2, pKey2, r2);
+ *pbKey2Cached = 1;
+ }
+ return sqlite3VdbeRecordCompareWithSkip(nKey1, pKey1, r2, 1);
+}
/*
** 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 */
+** size nKey2 bytes). Use (pTask->pKeyInfo) for the collation sequences
+** used by the comparison. Return the result of the comparison.
+**
+** If IN/OUT parameter *pbKey2Cached is true when this function is called,
+** it is assumed that (pTask->pUnpacked) contains the unpacked version
+** of key2. If it is false, (pTask->pUnpacked) is populated with the unpacked
+** version of key2 and *pbKey2Cached set to true before returning.
+**
+** If an OOM error is encountered, (pTask->pUnpacked->error_rc) is set
+** to SQLITE_NOMEM.
+*/
+static int vdbeSorterCompare(
+ SortSubtask *pTask, /* Subtask context (for pKeyInfo) */
+ int *pbKey2Cached, /* True if pTask->pUnpacked is pKey2 */
const void *pKey1, int nKey1, /* Left side of comparison */
- const void *pKey2, int nKey2, /* Right side of comparison */
- int *pRes /* OUT: Result of comparison */
+ const void *pKey2, int nKey2 /* Right side of comparison */
){
- KeyInfo *pKeyInfo = pCsr->pKeyInfo;
- VdbeSorter *pSorter = pCsr->pSorter;
- UnpackedRecord *r2 = pSorter->pUnpacked;
- int i;
+ UnpackedRecord *r2 = pTask->pUnpacked;
+ if( !*pbKey2Cached ){
+ sqlite3VdbeRecordUnpack(pTask->pSorter->pKeyInfo, nKey2, pKey2, r2);
+ *pbKey2Cached = 1;
+ }
+ return sqlite3VdbeRecordCompare(nKey1, pKey1, r2);
+}
- if( pKey2 ){
- sqlite3VdbeRecordUnpack(pKeyInfo, nKey2, pKey2, r2);
+/*
+** A specially optimized version of vdbeSorterCompare() that assumes that
+** the first field of each key is a TEXT value and that the collation
+** sequence to compare them with is BINARY.
+*/
+static int vdbeSorterCompareText(
+ SortSubtask *pTask, /* Subtask context (for pKeyInfo) */
+ int *pbKey2Cached, /* True if pTask->pUnpacked is pKey2 */
+ const void *pKey1, int nKey1, /* Left side of comparison */
+ const void *pKey2, int nKey2 /* Right side of comparison */
+){
+ const u8 * const p1 = (const u8 * const)pKey1;
+ const u8 * const p2 = (const u8 * const)pKey2;
+ const u8 * const v1 = &p1[ p1[0] ]; /* Pointer to value 1 */
+ const u8 * const v2 = &p2[ p2[0] ]; /* Pointer to value 2 */
+
+ int n1;
+ int n2;
+ int res;
+
+ getVarint32(&p1[1], n1); n1 = (n1 - 13) / 2;
+ getVarint32(&p2[1], n2); n2 = (n2 - 13) / 2;
+ res = memcmp(v1, v2, MIN(n1, n2));
+ if( res==0 ){
+ res = n1 - n2;
}
- 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;
- }
+ if( res==0 ){
+ if( pTask->pSorter->pKeyInfo->nField>1 ){
+ res = vdbeSorterCompareTail(
+ pTask, pbKey2Cached, pKey1, nKey1, pKey2, nKey2
+ );
+ }
+ }else{
+ if( pTask->pSorter->pKeyInfo->aSortOrder[0] ){
+ res = res * -1;
}
- r2->flags |= UNPACKED_PREFIX_MATCH;
}
- *pRes = sqlite3VdbeRecordCompare(nKey1, pKey1, r2);
+ return res;
}
/*
-** 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.
+** A specially optimized version of vdbeSorterCompare() that assumes that
+** the first field of each key is an INTEGER value.
*/
-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 );
+static int vdbeSorterCompareInt(
+ SortSubtask *pTask, /* Subtask context (for pKeyInfo) */
+ int *pbKey2Cached, /* True if pTask->pUnpacked is pKey2 */
+ const void *pKey1, int nKey1, /* Left side of comparison */
+ const void *pKey2, int nKey2 /* Right side of comparison */
+){
+ const u8 * const p1 = (const u8 * const)pKey1;
+ const u8 * const p2 = (const u8 * const)pKey2;
+ const int s1 = p1[1]; /* Left hand serial type */
+ const int s2 = p2[1]; /* Right hand serial type */
+ const u8 * const v1 = &p1[ p1[0] ]; /* Pointer to value 1 */
+ const u8 * const v2 = &p2[ p2[0] ]; /* Pointer to value 2 */
+ int res; /* Return value */
+
+ assert( (s1>0 && s1<7) || s1==8 || s1==9 );
+ assert( (s2>0 && s2<7) || s2==8 || s2==9 );
+
+ if( s1>7 && s2>7 ){
+ res = s1 - s2;
+ }else{
+ if( s1==s2 ){
+ if( (*v1 ^ *v2) & 0x80 ){
+ /* The two values have different signs */
+ res = (*v1 & 0x80) ? -1 : +1;
+ }else{
+ /* The two values have the same sign. Compare using memcmp(). */
+ static const u8 aLen[] = {0, 1, 2, 3, 4, 6, 8 };
+ int i;
+ res = 0;
+ for(i=0; i<aLen[s1]; i++){
+ if( (res = v1[i] - v2[i]) ) break;
+ }
+ }
+ }else{
+ if( s2>7 ){
+ res = +1;
+ }else if( s1>7 ){
+ res = -1;
+ }else{
+ res = s1 - s2;
+ }
+ assert( res!=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];
+ if( res>0 ){
+ if( *v1 & 0x80 ) res = -1;
+ }else{
+ if( *v2 & 0x80 ) res = +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;
+ if( res==0 ){
+ if( pTask->pSorter->pKeyInfo->nField>1 ){
+ res = vdbeSorterCompareTail(
+ pTask, pbKey2Cached, pKey1, nKey1, pKey2, nKey2
+ );
}
+ }else if( pTask->pSorter->pKeyInfo->aSortOrder[0] ){
+ res = res * -1;
}
- pSorter->aTree[iOut] = iRes;
- return SQLITE_OK;
+ return res;
}
/*
** Initialize the temporary index cursor just opened as a sorter cursor.
+**
+** Usually, the sorter module uses the value of (pCsr->pKeyInfo->nField)
+** to determine the number of fields that should be compared from the
+** records being sorted. However, if the value passed as argument nField
+** is non-zero and the sorter is able to guarantee a stable sort, nField
+** is used instead. This is used when sorting records for a CREATE INDEX
+** statement. In this case, keys are always delivered to the sorter in
+** order of the primary key, which happens to be make up the final part
+** of the records being sorted. So if the sort is stable, there is never
+** any reason to compare PK fields and they can be ignored for a small
+** performance boost.
+**
+** The sorter can guarantee a stable sort when running in single-threaded
+** mode, but not in multi-threaded mode.
+**
+** SQLITE_OK is returned if successful, or an SQLite error code otherwise.
*/
-SQLITE_PRIVATE int sqlite3VdbeSorterInit(sqlite3 *db, VdbeCursor *pCsr){
+SQLITE_PRIVATE int sqlite3VdbeSorterInit(
+ sqlite3 *db, /* Database connection (for malloc()) */
+ int nField, /* Number of key fields in each record */
+ VdbeCursor *pCsr /* Cursor that holds the new sorter */
+){
int pgsz; /* Page size of main database */
+ int i; /* Used to iterate through aTask[] */
int mxCache; /* Cache size */
VdbeSorter *pSorter; /* The new sorter */
- char *d; /* Dummy */
+ KeyInfo *pKeyInfo; /* Copy of pCsr->pKeyInfo with db==0 */
+ int szKeyInfo; /* Size of pCsr->pKeyInfo in bytes */
+ int sz; /* Size of pSorter in bytes */
+ int rc = SQLITE_OK;
+#if SQLITE_MAX_WORKER_THREADS==0
+# define nWorker 0
+#else
+ int nWorker;
+#endif
+
+ /* Initialize the upper limit on the number of worker threads */
+#if SQLITE_MAX_WORKER_THREADS>0
+ if( sqlite3TempInMemory(db) || sqlite3GlobalConfig.bCoreMutex==0 ){
+ nWorker = 0;
+ }else{
+ nWorker = db->aLimit[SQLITE_LIMIT_WORKER_THREADS];
+ }
+#endif
+
+ /* Do not allow the total number of threads (main thread + all workers)
+ ** to exceed the maximum merge count */
+#if SQLITE_MAX_WORKER_THREADS>=SORTER_MAX_MERGE_COUNT
+ if( nWorker>=SORTER_MAX_MERGE_COUNT ){
+ nWorker = SORTER_MAX_MERGE_COUNT-1;
+ }
+#endif
assert( pCsr->pKeyInfo && pCsr->pBt==0 );
- pCsr->pSorter = pSorter = sqlite3DbMallocZero(db, sizeof(VdbeSorter));
+ assert( pCsr->eCurType==CURTYPE_SORTER );
+ szKeyInfo = sizeof(KeyInfo) + (pCsr->pKeyInfo->nField-1)*sizeof(CollSeq*);
+ sz = sizeof(VdbeSorter) + nWorker * sizeof(SortSubtask);
+
+ pSorter = (VdbeSorter*)sqlite3DbMallocZero(db, sz + szKeyInfo);
+ pCsr->uc.pSorter = pSorter;
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 );
+ rc = SQLITE_NOMEM;
+ }else{
+ pSorter->pKeyInfo = pKeyInfo = (KeyInfo*)((u8*)pSorter + sz);
+ memcpy(pKeyInfo, pCsr->pKeyInfo, szKeyInfo);
+ pKeyInfo->db = 0;
+ if( nField && nWorker==0 ){
+ pKeyInfo->nXField += (pKeyInfo->nField - nField);
+ pKeyInfo->nField = nField;
+ }
+ pSorter->pgsz = pgsz = sqlite3BtreeGetPageSize(db->aDb[0].pBt);
+ pSorter->nTask = nWorker + 1;
+ pSorter->iPrev = (u8)(nWorker - 1);
+ pSorter->bUseThreads = (pSorter->nTask>1);
+ pSorter->db = db;
+ for(i=0; i<pSorter->nTask; i++){
+ SortSubtask *pTask = &pSorter->aTask[i];
+ pTask->pSorter = pSorter;
+ }
+
+ if( !sqlite3TempInMemory(db) ){
+ u32 szPma = sqlite3GlobalConfig.szPma;
+ pSorter->mnPmaSize = szPma * pgsz;
+ mxCache = db->aDb[0].pSchema->cache_size;
+ if( mxCache<(int)szPma ) mxCache = (int)szPma;
+ pSorter->mxPmaSize = MIN((i64)mxCache*pgsz, SQLITE_MAX_PMASZ);
+
+ /* EVIDENCE-OF: R-26747-61719 When the application provides any amount of
+ ** scratch memory using SQLITE_CONFIG_SCRATCH, SQLite avoids unnecessary
+ ** large heap allocations.
+ */
+ if( sqlite3GlobalConfig.pScratch==0 ){
+ assert( pSorter->iMemory==0 );
+ pSorter->nMemory = pgsz;
+ pSorter->list.aMemory = (u8*)sqlite3Malloc(pgsz);
+ if( !pSorter->list.aMemory ) rc = SQLITE_NOMEM;
+ }
+ }
- 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;
+ if( (pKeyInfo->nField+pKeyInfo->nXField)<13
+ && (pKeyInfo->aColl[0]==0 || pKeyInfo->aColl[0]==db->pDfltColl)
+ ){
+ pSorter->typeMask = SORTER_TYPE_INTEGER | SORTER_TYPE_TEXT;
+ }
}
- return SQLITE_OK;
+ return rc;
}
+#undef nWorker /* Defined at the top of this function */
/*
** Free the list of sorted records starting at pRecord.
@@ -71290,76 +82003,343 @@ static void vdbeSorterRecordFree(sqlite3 *db, SorterRecord *pRecord){
SorterRecord *p;
SorterRecord *pNext;
for(p=pRecord; p; p=pNext){
- pNext = p->pNext;
+ pNext = p->u.pNext;
sqlite3DbFree(db, p);
}
}
/*
+** Free all resources owned by the object indicated by argument pTask. All
+** fields of *pTask are zeroed before returning.
+*/
+static void vdbeSortSubtaskCleanup(sqlite3 *db, SortSubtask *pTask){
+ sqlite3DbFree(db, pTask->pUnpacked);
+#if SQLITE_MAX_WORKER_THREADS>0
+ /* pTask->list.aMemory can only be non-zero if it was handed memory
+ ** from the main thread. That only occurs SQLITE_MAX_WORKER_THREADS>0 */
+ if( pTask->list.aMemory ){
+ sqlite3_free(pTask->list.aMemory);
+ }else
+#endif
+ {
+ assert( pTask->list.aMemory==0 );
+ vdbeSorterRecordFree(0, pTask->list.pList);
+ }
+ if( pTask->file.pFd ){
+ sqlite3OsCloseFree(pTask->file.pFd);
+ }
+ if( pTask->file2.pFd ){
+ sqlite3OsCloseFree(pTask->file2.pFd);
+ }
+ memset(pTask, 0, sizeof(SortSubtask));
+}
+
+#ifdef SQLITE_DEBUG_SORTER_THREADS
+static void vdbeSorterWorkDebug(SortSubtask *pTask, const char *zEvent){
+ i64 t;
+ int iTask = (pTask - pTask->pSorter->aTask);
+ sqlite3OsCurrentTimeInt64(pTask->pSorter->db->pVfs, &t);
+ fprintf(stderr, "%lld:%d %s\n", t, iTask, zEvent);
+}
+static void vdbeSorterRewindDebug(const char *zEvent){
+ i64 t;
+ sqlite3OsCurrentTimeInt64(sqlite3_vfs_find(0), &t);
+ fprintf(stderr, "%lld:X %s\n", t, zEvent);
+}
+static void vdbeSorterPopulateDebug(
+ SortSubtask *pTask,
+ const char *zEvent
+){
+ i64 t;
+ int iTask = (pTask - pTask->pSorter->aTask);
+ sqlite3OsCurrentTimeInt64(pTask->pSorter->db->pVfs, &t);
+ fprintf(stderr, "%lld:bg%d %s\n", t, iTask, zEvent);
+}
+static void vdbeSorterBlockDebug(
+ SortSubtask *pTask,
+ int bBlocked,
+ const char *zEvent
+){
+ if( bBlocked ){
+ i64 t;
+ sqlite3OsCurrentTimeInt64(pTask->pSorter->db->pVfs, &t);
+ fprintf(stderr, "%lld:main %s\n", t, zEvent);
+ }
+}
+#else
+# define vdbeSorterWorkDebug(x,y)
+# define vdbeSorterRewindDebug(y)
+# define vdbeSorterPopulateDebug(x,y)
+# define vdbeSorterBlockDebug(x,y,z)
+#endif
+
+#if SQLITE_MAX_WORKER_THREADS>0
+/*
+** Join thread pTask->thread.
+*/
+static int vdbeSorterJoinThread(SortSubtask *pTask){
+ int rc = SQLITE_OK;
+ if( pTask->pThread ){
+#ifdef SQLITE_DEBUG_SORTER_THREADS
+ int bDone = pTask->bDone;
+#endif
+ void *pRet = SQLITE_INT_TO_PTR(SQLITE_ERROR);
+ vdbeSorterBlockDebug(pTask, !bDone, "enter");
+ (void)sqlite3ThreadJoin(pTask->pThread, &pRet);
+ vdbeSorterBlockDebug(pTask, !bDone, "exit");
+ rc = SQLITE_PTR_TO_INT(pRet);
+ assert( pTask->bDone==1 );
+ pTask->bDone = 0;
+ pTask->pThread = 0;
+ }
+ return rc;
+}
+
+/*
+** Launch a background thread to run xTask(pIn).
+*/
+static int vdbeSorterCreateThread(
+ SortSubtask *pTask, /* Thread will use this task object */
+ void *(*xTask)(void*), /* Routine to run in a separate thread */
+ void *pIn /* Argument passed into xTask() */
+){
+ assert( pTask->pThread==0 && pTask->bDone==0 );
+ return sqlite3ThreadCreate(&pTask->pThread, xTask, pIn);
+}
+
+/*
+** Join all outstanding threads launched by SorterWrite() to create
+** level-0 PMAs.
+*/
+static int vdbeSorterJoinAll(VdbeSorter *pSorter, int rcin){
+ int rc = rcin;
+ int i;
+
+ /* This function is always called by the main user thread.
+ **
+ ** If this function is being called after SorterRewind() has been called,
+ ** it is possible that thread pSorter->aTask[pSorter->nTask-1].pThread
+ ** is currently attempt to join one of the other threads. To avoid a race
+ ** condition where this thread also attempts to join the same object, join
+ ** thread pSorter->aTask[pSorter->nTask-1].pThread first. */
+ for(i=pSorter->nTask-1; i>=0; i--){
+ SortSubtask *pTask = &pSorter->aTask[i];
+ int rc2 = vdbeSorterJoinThread(pTask);
+ if( rc==SQLITE_OK ) rc = rc2;
+ }
+ return rc;
+}
+#else
+# define vdbeSorterJoinAll(x,rcin) (rcin)
+# define vdbeSorterJoinThread(pTask) SQLITE_OK
+#endif
+
+/*
+** Allocate a new MergeEngine object capable of handling up to
+** nReader PmaReader inputs.
+**
+** nReader is automatically rounded up to the next power of two.
+** nReader may not exceed SORTER_MAX_MERGE_COUNT even after rounding up.
+*/
+static MergeEngine *vdbeMergeEngineNew(int nReader){
+ int N = 2; /* Smallest power of two >= nReader */
+ int nByte; /* Total bytes of space to allocate */
+ MergeEngine *pNew; /* Pointer to allocated object to return */
+
+ assert( nReader<=SORTER_MAX_MERGE_COUNT );
+
+ while( N<nReader ) N += N;
+ nByte = sizeof(MergeEngine) + N * (sizeof(int) + sizeof(PmaReader));
+
+ pNew = sqlite3FaultSim(100) ? 0 : (MergeEngine*)sqlite3MallocZero(nByte);
+ if( pNew ){
+ pNew->nTree = N;
+ pNew->pTask = 0;
+ pNew->aReadr = (PmaReader*)&pNew[1];
+ pNew->aTree = (int*)&pNew->aReadr[N];
+ }
+ return pNew;
+}
+
+/*
+** Free the MergeEngine object passed as the only argument.
+*/
+static void vdbeMergeEngineFree(MergeEngine *pMerger){
+ int i;
+ if( pMerger ){
+ for(i=0; i<pMerger->nTree; i++){
+ vdbePmaReaderClear(&pMerger->aReadr[i]);
+ }
+ }
+ sqlite3_free(pMerger);
+}
+
+/*
+** Free all resources associated with the IncrMerger object indicated by
+** the first argument.
+*/
+static void vdbeIncrFree(IncrMerger *pIncr){
+ if( pIncr ){
+#if SQLITE_MAX_WORKER_THREADS>0
+ if( pIncr->bUseThread ){
+ vdbeSorterJoinThread(pIncr->pTask);
+ if( pIncr->aFile[0].pFd ) sqlite3OsCloseFree(pIncr->aFile[0].pFd);
+ if( pIncr->aFile[1].pFd ) sqlite3OsCloseFree(pIncr->aFile[1].pFd);
+ }
+#endif
+ vdbeMergeEngineFree(pIncr->pMerger);
+ sqlite3_free(pIncr);
+ }
+}
+
+/*
+** Reset a sorting cursor back to its original empty state.
+*/
+SQLITE_PRIVATE void sqlite3VdbeSorterReset(sqlite3 *db, VdbeSorter *pSorter){
+ int i;
+ (void)vdbeSorterJoinAll(pSorter, SQLITE_OK);
+ assert( pSorter->bUseThreads || pSorter->pReader==0 );
+#if SQLITE_MAX_WORKER_THREADS>0
+ if( pSorter->pReader ){
+ vdbePmaReaderClear(pSorter->pReader);
+ sqlite3DbFree(db, pSorter->pReader);
+ pSorter->pReader = 0;
+ }
+#endif
+ vdbeMergeEngineFree(pSorter->pMerger);
+ pSorter->pMerger = 0;
+ for(i=0; i<pSorter->nTask; i++){
+ SortSubtask *pTask = &pSorter->aTask[i];
+ vdbeSortSubtaskCleanup(db, pTask);
+ pTask->pSorter = pSorter;
+ }
+ if( pSorter->list.aMemory==0 ){
+ vdbeSorterRecordFree(0, pSorter->list.pList);
+ }
+ pSorter->list.pList = 0;
+ pSorter->list.szPMA = 0;
+ pSorter->bUsePMA = 0;
+ pSorter->iMemory = 0;
+ pSorter->mxKeysize = 0;
+ sqlite3DbFree(db, pSorter->pUnpacked);
+ pSorter->pUnpacked = 0;
+}
+
+/*
** Free any cursor components allocated by sqlite3VdbeSorterXXX routines.
*/
SQLITE_PRIVATE void sqlite3VdbeSorterClose(sqlite3 *db, VdbeCursor *pCsr){
- VdbeSorter *pSorter = pCsr->pSorter;
+ VdbeSorter *pSorter;
+ assert( pCsr->eCurType==CURTYPE_SORTER );
+ pSorter = pCsr->uc.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);
+ sqlite3VdbeSorterReset(db, pSorter);
+ sqlite3_free(pSorter->list.aMemory);
sqlite3DbFree(db, pSorter);
- pCsr->pSorter = 0;
+ pCsr->uc.pSorter = 0;
}
}
+#if SQLITE_MAX_MMAP_SIZE>0
+/*
+** The first argument is a file-handle open on a temporary file. The file
+** is guaranteed to be nByte bytes or smaller in size. This function
+** attempts to extend the file to nByte bytes in size and to ensure that
+** the VFS has memory mapped it.
+**
+** Whether or not the file does end up memory mapped of course depends on
+** the specific VFS implementation.
+*/
+static void vdbeSorterExtendFile(sqlite3 *db, sqlite3_file *pFd, i64 nByte){
+ if( nByte<=(i64)(db->nMaxSorterMmap) && pFd->pMethods->iVersion>=3 ){
+ void *p = 0;
+ int chunksize = 4*1024;
+ sqlite3OsFileControlHint(pFd, SQLITE_FCNTL_CHUNK_SIZE, &chunksize);
+ sqlite3OsFileControlHint(pFd, SQLITE_FCNTL_SIZE_HINT, &nByte);
+ sqlite3OsFetch(pFd, 0, (int)nByte, &p);
+ sqlite3OsUnfetch(pFd, 0, p);
+ }
+}
+#else
+# define vdbeSorterExtendFile(x,y,z)
+#endif
+
/*
** 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.
+** set *ppFd to point to the malloc'd file-handle and return SQLITE_OK.
+** Otherwise, set *ppFd to 0 and return an SQLite error code.
*/
-static int vdbeSorterOpenTempFile(sqlite3 *db, sqlite3_file **ppFile){
- int dummy;
- return sqlite3OsOpenMalloc(db->pVfs, 0, ppFile,
+static int vdbeSorterOpenTempFile(
+ sqlite3 *db, /* Database handle doing sort */
+ i64 nExtend, /* Attempt to extend file to this size */
+ sqlite3_file **ppFd
+){
+ int rc;
+ if( sqlite3FaultSim(202) ) return SQLITE_IOERR_ACCESS;
+ rc = sqlite3OsOpenMalloc(db->pVfs, 0, ppFd,
SQLITE_OPEN_TEMP_JOURNAL |
SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE |
- SQLITE_OPEN_EXCLUSIVE | SQLITE_OPEN_DELETEONCLOSE, &dummy
+ SQLITE_OPEN_EXCLUSIVE | SQLITE_OPEN_DELETEONCLOSE, &rc
);
+ if( rc==SQLITE_OK ){
+ i64 max = SQLITE_MAX_MMAP_SIZE;
+ sqlite3OsFileControlHint(*ppFd, SQLITE_FCNTL_MMAP_SIZE, (void*)&max);
+ if( nExtend>0 ){
+ vdbeSorterExtendFile(db, *ppFd, nExtend);
+ }
+ }
+ return rc;
}
/*
+** If it has not already been allocated, allocate the UnpackedRecord
+** structure at pTask->pUnpacked. Return SQLITE_OK if successful (or
+** if no allocation was required), or SQLITE_NOMEM otherwise.
+*/
+static int vdbeSortAllocUnpacked(SortSubtask *pTask){
+ if( pTask->pUnpacked==0 ){
+ char *pFree;
+ pTask->pUnpacked = sqlite3VdbeAllocUnpackedRecord(
+ pTask->pSorter->pKeyInfo, 0, 0, &pFree
+ );
+ assert( pTask->pUnpacked==(UnpackedRecord*)pFree );
+ if( pFree==0 ) return SQLITE_NOMEM;
+ pTask->pUnpacked->nField = pTask->pSorter->pKeyInfo->nField;
+ pTask->pUnpacked->errCode = 0;
+ }
+ return SQLITE_OK;
+}
+
+
+/*
** 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 */
+ SortSubtask *pTask, /* Calling thread context */
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;
+ int bCached = 0;
while( p1 && p2 ){
int res;
- vdbeSorterCompare(pCsr, 0, p1->pVal, p1->nVal, pVal2, p2->nVal, &res);
+ res = pTask->xCompare(
+ pTask, &bCached, SRVAL(p1), p1->nVal, SRVAL(p2), p2->nVal
+ );
+
if( res<=0 ){
*pp = p1;
- pp = &p1->pNext;
- p1 = p1->pNext;
- pVal2 = 0;
+ pp = &p1->u.pNext;
+ p1 = p1->u.pNext;
}else{
*pp = p2;
- pp = &p2->pNext;
- p2 = p2->pNext;
- if( p2==0 ) break;
- pVal2 = p2->pVal;
+ pp = &p2->u.pNext;
+ p2 = p2->u.pNext;
+ bCached = 0;
}
}
*pp = p1 ? p1 : p2;
@@ -71367,27 +82347,56 @@ static void vdbeSorterMerge(
}
/*
-** 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.
+** Return the SorterCompare function to compare values collected by the
+** sorter object passed as the only argument.
*/
-static int vdbeSorterSort(const VdbeCursor *pCsr){
+static SorterCompare vdbeSorterGetCompare(VdbeSorter *p){
+ if( p->typeMask==SORTER_TYPE_INTEGER ){
+ return vdbeSorterCompareInt;
+ }else if( p->typeMask==SORTER_TYPE_TEXT ){
+ return vdbeSorterCompareText;
+ }
+ return vdbeSorterCompare;
+}
+
+/*
+** Sort the linked list of records headed at pTask->pList. Return
+** SQLITE_OK if successful, or an SQLite error code (i.e. SQLITE_NOMEM) if
+** an error occurs.
+*/
+static int vdbeSorterSort(SortSubtask *pTask, SorterList *pList){
int i;
SorterRecord **aSlot;
SorterRecord *p;
- VdbeSorter *pSorter = pCsr->pSorter;
+ int rc;
+
+ rc = vdbeSortAllocUnpacked(pTask);
+ if( rc!=SQLITE_OK ) return rc;
+
+ p = pList->pList;
+ pTask->xCompare = vdbeSorterGetCompare(pTask->pSorter);
aSlot = (SorterRecord **)sqlite3MallocZero(64 * sizeof(SorterRecord *));
if( !aSlot ){
return SQLITE_NOMEM;
}
- p = pSorter->pRecord;
while( p ){
- SorterRecord *pNext = p->pNext;
- p->pNext = 0;
+ SorterRecord *pNext;
+ if( pList->aMemory ){
+ if( (u8*)p==pList->aMemory ){
+ pNext = 0;
+ }else{
+ assert( p->u.iNext<sqlite3MallocSize(pList->aMemory) );
+ pNext = (SorterRecord*)&pList->aMemory[p->u.iNext];
+ }
+ }else{
+ pNext = p->u.pNext;
+ }
+
+ p->u.pNext = 0;
for(i=0; aSlot[i]; i++){
- vdbeSorterMerge(pCsr, p, aSlot[i], &p);
+ vdbeSorterMerge(pTask, p, aSlot[i], &p);
aSlot[i] = 0;
}
aSlot[i] = p;
@@ -71396,42 +82405,43 @@ static int vdbeSorterSort(const VdbeCursor *pCsr){
p = 0;
for(i=0; i<64; i++){
- vdbeSorterMerge(pCsr, p, aSlot[i], &p);
+ vdbeSorterMerge(pTask, p, aSlot[i], &p);
}
- pSorter->pRecord = p;
+ pList->pList = p;
sqlite3_free(aSlot);
- return SQLITE_OK;
+ assert( pTask->pUnpacked->errCode==SQLITE_OK
+ || pTask->pUnpacked->errCode==SQLITE_NOMEM
+ );
+ return pTask->pUnpacked->errCode;
}
/*
-** Initialize a file-writer object.
+** Initialize a PMA-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 */
+static void vdbePmaWriterInit(
+ sqlite3_file *pFd, /* File handle to write to */
+ PmaWriter *p, /* Object to populate */
+ int nBuf, /* Buffer size */
+ i64 iStart /* Offset of pFd to begin writing at */
){
- int nBuf = sqlite3BtreeGetPageSize(db->aDb[0].pBt);
-
- memset(p, 0, sizeof(FileWriter));
- p->aBuffer = (u8 *)sqlite3DbMallocRaw(db, nBuf);
+ memset(p, 0, sizeof(PmaWriter));
+ p->aBuffer = (u8*)sqlite3Malloc(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;
+ p->pFd = pFd;
}
}
/*
-** Write nData bytes of data to the file-write object. Return SQLITE_OK
+** Write nData bytes of data to the PMA. Return SQLITE_OK
** if successful, or an SQLite error code if an error occurs.
*/
-static void fileWriterWrite(FileWriter *p, u8 *pData, int nData){
+static void vdbePmaWriteBlob(PmaWriter *p, u8 *pData, int nData){
int nRem = nData;
while( nRem>0 && p->eFWErr==0 ){
int nCopy = nRem;
@@ -71442,7 +82452,7 @@ static void fileWriterWrite(FileWriter *p, u8 *pData, int nData){
memcpy(&p->aBuffer[p->iBufEnd], &pData[nData-nRem], nCopy);
p->iBufEnd += nCopy;
if( p->iBufEnd==p->nBuffer ){
- p->eFWErr = sqlite3OsWrite(p->pFile,
+ p->eFWErr = sqlite3OsWrite(p->pFd,
&p->aBuffer[p->iBufStart], p->iBufEnd - p->iBufStart,
p->iWriteOff + p->iBufStart
);
@@ -71456,43 +82466,44 @@ static void fileWriterWrite(FileWriter *p, u8 *pData, int nData){
}
/*
-** 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.
+** Flush any buffered data to disk and clean up the PMA-writer object.
+** The results of using the PMA-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){
+static int vdbePmaWriterFinish(PmaWriter *p, i64 *piEof){
int rc;
if( p->eFWErr==0 && ALWAYS(p->aBuffer) && p->iBufEnd>p->iBufStart ){
- p->eFWErr = sqlite3OsWrite(p->pFile,
+ p->eFWErr = sqlite3OsWrite(p->pFd,
&p->aBuffer[p->iBufStart], p->iBufEnd - p->iBufStart,
p->iWriteOff + p->iBufStart
);
}
*piEof = (p->iWriteOff + p->iBufEnd);
- sqlite3DbFree(db, p->aBuffer);
+ sqlite3_free(p->aBuffer);
rc = p->eFWErr;
- memset(p, 0, sizeof(FileWriter));
+ memset(p, 0, sizeof(PmaWriter));
return rc;
}
/*
-** Write value iVal encoded as a varint to the file-write object. Return
+** Write value iVal encoded as a varint to the PMA. Return
** SQLITE_OK if successful, or an SQLite error code if an error occurs.
*/
-static void fileWriterWriteVarint(FileWriter *p, u64 iVal){
+static void vdbePmaWriteVarint(PmaWriter *p, u64 iVal){
int nByte;
u8 aByte[10];
nByte = sqlite3PutVarint(aByte, iVal);
- fileWriterWrite(p, aByte, nByte);
+ vdbePmaWriteBlob(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.
+** Write the current contents of in-memory linked-list pList to a level-0
+** PMA in the temp file belonging to sub-task pTask. Return SQLITE_OK if
+** successful, or an SQLite error code otherwise.
**
** The format of a PMA is:
**
@@ -71503,76 +82514,256 @@ static void fileWriterWriteVarint(FileWriter *p, u64 iVal){
** 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){
+static int vdbeSorterListToPMA(SortSubtask *pTask, SorterList *pList){
+ sqlite3 *db = pTask->pSorter->db;
int rc = SQLITE_OK; /* Return code */
- VdbeSorter *pSorter = pCsr->pSorter;
- FileWriter writer;
+ PmaWriter writer; /* Object used to write to the file */
- memset(&writer, 0, sizeof(FileWriter));
+#ifdef SQLITE_DEBUG
+ /* Set iSz to the expected size of file pTask->file after writing the PMA.
+ ** This is used by an assert() statement at the end of this function. */
+ i64 iSz = pList->szPMA + sqlite3VarintLen(pList->szPMA) + pTask->file.iEof;
+#endif
- if( pSorter->nInMemory==0 ){
- assert( pSorter->pRecord==0 );
- return rc;
+ vdbeSorterWorkDebug(pTask, "enter");
+ memset(&writer, 0, sizeof(PmaWriter));
+ assert( pList->szPMA>0 );
+
+ /* If the first temporary PMA file has not been opened, open it now. */
+ if( pTask->file.pFd==0 ){
+ rc = vdbeSorterOpenTempFile(db, 0, &pTask->file.pFd);
+ assert( rc!=SQLITE_OK || pTask->file.pFd );
+ assert( pTask->file.iEof==0 );
+ assert( pTask->nPMA==0 );
}
- rc = vdbeSorterSort(pCsr);
+ /* Try to get the file to memory map */
+ if( rc==SQLITE_OK ){
+ vdbeSorterExtendFile(db, pTask->file.pFd, pTask->file.iEof+pList->szPMA+9);
+ }
- /* 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 );
+ /* Sort the list */
+ if( rc==SQLITE_OK ){
+ rc = vdbeSorterSort(pTask, pList);
}
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);
+ vdbePmaWriterInit(pTask->file.pFd, &writer, pTask->pSorter->pgsz,
+ pTask->file.iEof);
+ pTask->nPMA++;
+ vdbePmaWriteVarint(&writer, pList->szPMA);
+ for(p=pList->pList; p; p=pNext){
+ pNext = p->u.pNext;
+ vdbePmaWriteVarint(&writer, p->nVal);
+ vdbePmaWriteBlob(&writer, SRVAL(p), p->nVal);
+ if( pList->aMemory==0 ) sqlite3_free(p);
+ }
+ pList->pList = p;
+ rc = vdbePmaWriterFinish(&writer, &pTask->file.iEof);
+ }
+
+ vdbeSorterWorkDebug(pTask, "exit");
+ assert( rc!=SQLITE_OK || pList->pList==0 );
+ assert( rc!=SQLITE_OK || pTask->file.iEof==iSz );
+ return rc;
+}
+
+/*
+** Advance the MergeEngine to its next entry.
+** Set *pbEof to true there is no next entry because
+** the MergeEngine has reached the end of all its inputs.
+**
+** Return SQLITE_OK if successful or an error code if an error occurs.
+*/
+static int vdbeMergeEngineStep(
+ MergeEngine *pMerger, /* The merge engine to advance to the next row */
+ int *pbEof /* Set TRUE at EOF. Set false for more content */
+){
+ int rc;
+ int iPrev = pMerger->aTree[1];/* Index of PmaReader to advance */
+ SortSubtask *pTask = pMerger->pTask;
+
+ /* Advance the current PmaReader */
+ rc = vdbePmaReaderNext(&pMerger->aReadr[iPrev]);
+
+ /* Update contents of aTree[] */
+ if( rc==SQLITE_OK ){
+ int i; /* Index of aTree[] to recalculate */
+ PmaReader *pReadr1; /* First PmaReader to compare */
+ PmaReader *pReadr2; /* Second PmaReader to compare */
+ int bCached = 0;
+
+ /* Find the first two PmaReaders to compare. The one that was just
+ ** advanced (iPrev) and the one next to it in the array. */
+ pReadr1 = &pMerger->aReadr[(iPrev & 0xFFFE)];
+ pReadr2 = &pMerger->aReadr[(iPrev | 0x0001)];
+
+ for(i=(pMerger->nTree+iPrev)/2; i>0; i=i/2){
+ /* Compare pReadr1 and pReadr2. Store the result in variable iRes. */
+ int iRes;
+ if( pReadr1->pFd==0 ){
+ iRes = +1;
+ }else if( pReadr2->pFd==0 ){
+ iRes = -1;
+ }else{
+ iRes = pTask->xCompare(pTask, &bCached,
+ pReadr1->aKey, pReadr1->nKey, pReadr2->aKey, pReadr2->nKey
+ );
+ }
+
+ /* If pReadr1 contained the smaller value, set aTree[i] to its index.
+ ** Then set pReadr2 to the next PmaReader to compare to pReadr1. In this
+ ** case there is no cache of pReadr2 in pTask->pUnpacked, so set
+ ** pKey2 to point to the record belonging to pReadr2.
+ **
+ ** Alternatively, if pReadr2 contains the smaller of the two values,
+ ** set aTree[i] to its index and update pReadr1. If vdbeSorterCompare()
+ ** was actually called above, then pTask->pUnpacked now contains
+ ** a value equivalent to pReadr2. So set pKey2 to NULL to prevent
+ ** vdbeSorterCompare() from decoding pReadr2 again.
+ **
+ ** If the two values were equal, then the value from the oldest
+ ** PMA should be considered smaller. The VdbeSorter.aReadr[] array
+ ** is sorted from oldest to newest, so pReadr1 contains older values
+ ** than pReadr2 iff (pReadr1<pReadr2). */
+ if( iRes<0 || (iRes==0 && pReadr1<pReadr2) ){
+ pMerger->aTree[i] = (int)(pReadr1 - pMerger->aReadr);
+ pReadr2 = &pMerger->aReadr[ pMerger->aTree[i ^ 0x0001] ];
+ bCached = 0;
+ }else{
+ if( pReadr1->pFd ) bCached = 0;
+ pMerger->aTree[i] = (int)(pReadr2 - pMerger->aReadr);
+ pReadr1 = &pMerger->aReadr[ pMerger->aTree[i ^ 0x0001] ];
+ }
+ }
+ *pbEof = (pMerger->aReadr[pMerger->aTree[1]].pFd==0);
+ }
+
+ return (rc==SQLITE_OK ? pTask->pUnpacked->errCode : rc);
+}
+
+#if SQLITE_MAX_WORKER_THREADS>0
+/*
+** The main routine for background threads that write level-0 PMAs.
+*/
+static void *vdbeSorterFlushThread(void *pCtx){
+ SortSubtask *pTask = (SortSubtask*)pCtx;
+ int rc; /* Return code */
+ assert( pTask->bDone==0 );
+ rc = vdbeSorterListToPMA(pTask, &pTask->list);
+ pTask->bDone = 1;
+ return SQLITE_INT_TO_PTR(rc);
+}
+#endif /* SQLITE_MAX_WORKER_THREADS>0 */
+
+/*
+** Flush the current contents of VdbeSorter.list to a new PMA, possibly
+** using a background thread.
+*/
+static int vdbeSorterFlushPMA(VdbeSorter *pSorter){
+#if SQLITE_MAX_WORKER_THREADS==0
+ pSorter->bUsePMA = 1;
+ return vdbeSorterListToPMA(&pSorter->aTask[0], &pSorter->list);
+#else
+ int rc = SQLITE_OK;
+ int i;
+ SortSubtask *pTask = 0; /* Thread context used to create new PMA */
+ int nWorker = (pSorter->nTask-1);
+
+ /* Set the flag to indicate that at least one PMA has been written.
+ ** Or will be, anyhow. */
+ pSorter->bUsePMA = 1;
+
+ /* Select a sub-task to sort and flush the current list of in-memory
+ ** records to disk. If the sorter is running in multi-threaded mode,
+ ** round-robin between the first (pSorter->nTask-1) tasks. Except, if
+ ** the background thread from a sub-tasks previous turn is still running,
+ ** skip it. If the first (pSorter->nTask-1) sub-tasks are all still busy,
+ ** fall back to using the final sub-task. The first (pSorter->nTask-1)
+ ** sub-tasks are prefered as they use background threads - the final
+ ** sub-task uses the main thread. */
+ for(i=0; i<nWorker; i++){
+ int iTest = (pSorter->iPrev + i + 1) % nWorker;
+ pTask = &pSorter->aTask[iTest];
+ if( pTask->bDone ){
+ rc = vdbeSorterJoinThread(pTask);
+ }
+ if( rc!=SQLITE_OK || pTask->pThread==0 ) break;
+ }
+
+ if( rc==SQLITE_OK ){
+ if( i==nWorker ){
+ /* Use the foreground thread for this operation */
+ rc = vdbeSorterListToPMA(&pSorter->aTask[nWorker], &pSorter->list);
+ }else{
+ /* Launch a background thread for this operation */
+ u8 *aMem = pTask->list.aMemory;
+ void *pCtx = (void*)pTask;
+
+ assert( pTask->pThread==0 && pTask->bDone==0 );
+ assert( pTask->list.pList==0 );
+ assert( pTask->list.aMemory==0 || pSorter->list.aMemory!=0 );
+
+ pSorter->iPrev = (u8)(pTask - pSorter->aTask);
+ pTask->list = pSorter->list;
+ pSorter->list.pList = 0;
+ pSorter->list.szPMA = 0;
+ if( aMem ){
+ pSorter->list.aMemory = aMem;
+ pSorter->nMemory = sqlite3MallocSize(aMem);
+ }else if( pSorter->list.aMemory ){
+ pSorter->list.aMemory = sqlite3Malloc(pSorter->nMemory);
+ if( !pSorter->list.aMemory ) return SQLITE_NOMEM;
+ }
+
+ rc = vdbeSorterCreateThread(pTask, vdbeSorterFlushThread, pCtx);
}
- pSorter->pRecord = p;
- rc = fileWriterFinish(db, &writer, &pSorter->iWriteOff);
}
return rc;
+#endif /* SQLITE_MAX_WORKER_THREADS!=0 */
}
/*
** Add a record to the sorter.
*/
SQLITE_PRIVATE int sqlite3VdbeSorterWrite(
- sqlite3 *db, /* Database handle */
- const VdbeCursor *pCsr, /* Sorter cursor */
+ const VdbeCursor *pCsr, /* Sorter cursor */
Mem *pVal /* Memory cell containing record */
){
- VdbeSorter *pSorter = pCsr->pSorter;
+ VdbeSorter *pSorter;
int rc = SQLITE_OK; /* Return Code */
SorterRecord *pNew; /* New list element */
+ int bFlush; /* True to flush contents of memory to PMA */
+ int nReq; /* Bytes of memory required */
+ int nPMA; /* Bytes of PMA space required */
+ int t; /* serial type of first record field */
- assert( pSorter );
- pSorter->nInMemory += sqlite3VarintLen(pVal->n) + pVal->n;
-
- pNew = (SorterRecord *)sqlite3DbMallocRaw(db, pVal->n + sizeof(SorterRecord));
- if( pNew==0 ){
- rc = SQLITE_NOMEM;
+ assert( pCsr->eCurType==CURTYPE_SORTER );
+ pSorter = pCsr->uc.pSorter;
+ getVarint32((const u8*)&pVal->z[1], t);
+ if( t>0 && t<10 && t!=7 ){
+ pSorter->typeMask &= SORTER_TYPE_INTEGER;
+ }else if( t>10 && (t & 0x01) ){
+ pSorter->typeMask &= SORTER_TYPE_TEXT;
}else{
- pNew->pVal = (void *)&pNew[1];
- memcpy(pNew->pVal, pVal->z, pVal->n);
- pNew->nVal = pVal->n;
- pNew->pNext = pSorter->pRecord;
- pSorter->pRecord = pNew;
+ pSorter->typeMask = 0;
}
- /* See if the contents of the sorter should now be written out. They
- ** are written out when either of the following are true:
+ assert( pSorter );
+
+ /* Figure out whether or not the current contents of memory should be
+ ** flushed to a PMA before continuing. If so, do so.
+ **
+ ** If using the single large allocation mode (pSorter->aMemory!=0), then
+ ** flush the contents of memory to a new PMA if (a) at least one value is
+ ** already in memory and (b) the new value will not fit in memory.
+ **
+ ** Or, if using separate allocations for each record, flush the contents
+ ** of memory to a PMA if either of the following are true:
**
** * The total memory allocated for the in-memory list is greater
** than (page-size * cache-size), or
@@ -71580,161 +82771,811 @@ SQLITE_PRIVATE int sqlite3VdbeSorterWrite(
** * 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;
+ nReq = pVal->n + sizeof(SorterRecord);
+ nPMA = pVal->n + sqlite3VarintLen(pVal->n);
+ if( pSorter->mxPmaSize ){
+ if( pSorter->list.aMemory ){
+ bFlush = pSorter->iMemory && (pSorter->iMemory+nReq) > pSorter->mxPmaSize;
+ }else{
+ bFlush = (
+ (pSorter->list.szPMA > pSorter->mxPmaSize)
+ || (pSorter->list.szPMA > pSorter->mnPmaSize && sqlite3HeapNearlyFull())
+ );
+ }
+ if( bFlush ){
+ rc = vdbeSorterFlushPMA(pSorter);
+ pSorter->list.szPMA = 0;
+ pSorter->iMemory = 0;
+ assert( rc!=SQLITE_OK || pSorter->list.pList==0 );
+ }
+ }
+
+ pSorter->list.szPMA += nPMA;
+ if( nPMA>pSorter->mxKeysize ){
+ pSorter->mxKeysize = nPMA;
+ }
+
+ if( pSorter->list.aMemory ){
+ int nMin = pSorter->iMemory + nReq;
+
+ if( nMin>pSorter->nMemory ){
+ u8 *aNew;
+ int nNew = pSorter->nMemory * 2;
+ while( nNew < nMin ) nNew = nNew*2;
+ if( nNew > pSorter->mxPmaSize ) nNew = pSorter->mxPmaSize;
+ if( nNew < nMin ) nNew = nMin;
+
+ aNew = sqlite3Realloc(pSorter->list.aMemory, nNew);
+ if( !aNew ) return SQLITE_NOMEM;
+ pSorter->list.pList = (SorterRecord*)(
+ aNew + ((u8*)pSorter->list.pList - pSorter->list.aMemory)
+ );
+ pSorter->list.aMemory = aNew;
+ pSorter->nMemory = nNew;
+ }
+
+ pNew = (SorterRecord*)&pSorter->list.aMemory[pSorter->iMemory];
+ pSorter->iMemory += ROUND8(nReq);
+ pNew->u.iNext = (int)((u8*)(pSorter->list.pList) - pSorter->list.aMemory);
+ }else{
+ pNew = (SorterRecord *)sqlite3Malloc(nReq);
+ if( pNew==0 ){
+ return SQLITE_NOMEM;
+ }
+ pNew->u.pNext = pSorter->list.pList;
+ }
+
+ memcpy(SRVAL(pNew), pVal->z, pVal->n);
+ pNew->nVal = pVal->n;
+ pSorter->list.pList = pNew;
+
+ return rc;
+}
+
+/*
+** Read keys from pIncr->pMerger and populate pIncr->aFile[1]. The format
+** of the data stored in aFile[1] is the same as that used by regular PMAs,
+** except that the number-of-bytes varint is omitted from the start.
+*/
+static int vdbeIncrPopulate(IncrMerger *pIncr){
+ int rc = SQLITE_OK;
+ int rc2;
+ i64 iStart = pIncr->iStartOff;
+ SorterFile *pOut = &pIncr->aFile[1];
+ SortSubtask *pTask = pIncr->pTask;
+ MergeEngine *pMerger = pIncr->pMerger;
+ PmaWriter writer;
+ assert( pIncr->bEof==0 );
+
+ vdbeSorterPopulateDebug(pTask, "enter");
+
+ vdbePmaWriterInit(pOut->pFd, &writer, pTask->pSorter->pgsz, iStart);
+ while( rc==SQLITE_OK ){
+ int dummy;
+ PmaReader *pReader = &pMerger->aReadr[ pMerger->aTree[1] ];
+ int nKey = pReader->nKey;
+ i64 iEof = writer.iWriteOff + writer.iBufEnd;
+
+ /* Check if the output file is full or if the input has been exhausted.
+ ** In either case exit the loop. */
+ if( pReader->pFd==0 ) break;
+ if( (iEof + nKey + sqlite3VarintLen(nKey))>(iStart + pIncr->mxSz) ) break;
+
+ /* Write the next key to the output. */
+ vdbePmaWriteVarint(&writer, nKey);
+ vdbePmaWriteBlob(&writer, pReader->aKey, nKey);
+ assert( pIncr->pMerger->pTask==pTask );
+ rc = vdbeMergeEngineStep(pIncr->pMerger, &dummy);
+ }
+
+ rc2 = vdbePmaWriterFinish(&writer, &pOut->iEof);
+ if( rc==SQLITE_OK ) rc = rc2;
+ vdbeSorterPopulateDebug(pTask, "exit");
+ return rc;
+}
+
+#if SQLITE_MAX_WORKER_THREADS>0
+/*
+** The main routine for background threads that populate aFile[1] of
+** multi-threaded IncrMerger objects.
+*/
+static void *vdbeIncrPopulateThread(void *pCtx){
+ IncrMerger *pIncr = (IncrMerger*)pCtx;
+ void *pRet = SQLITE_INT_TO_PTR( vdbeIncrPopulate(pIncr) );
+ pIncr->pTask->bDone = 1;
+ return pRet;
+}
+
+/*
+** Launch a background thread to populate aFile[1] of pIncr.
+*/
+static int vdbeIncrBgPopulate(IncrMerger *pIncr){
+ void *p = (void*)pIncr;
+ assert( pIncr->bUseThread );
+ return vdbeSorterCreateThread(pIncr->pTask, vdbeIncrPopulateThread, p);
+}
#endif
- rc = vdbeSorterListToPMA(db, pCsr);
- pSorter->nInMemory = 0;
- assert( rc!=SQLITE_OK || (nExpect==pSorter->iWriteOff) );
+
+/*
+** This function is called when the PmaReader corresponding to pIncr has
+** finished reading the contents of aFile[0]. Its purpose is to "refill"
+** aFile[0] such that the PmaReader should start rereading it from the
+** beginning.
+**
+** For single-threaded objects, this is accomplished by literally reading
+** keys from pIncr->pMerger and repopulating aFile[0].
+**
+** For multi-threaded objects, all that is required is to wait until the
+** background thread is finished (if it is not already) and then swap
+** aFile[0] and aFile[1] in place. If the contents of pMerger have not
+** been exhausted, this function also launches a new background thread
+** to populate the new aFile[1].
+**
+** SQLITE_OK is returned on success, or an SQLite error code otherwise.
+*/
+static int vdbeIncrSwap(IncrMerger *pIncr){
+ int rc = SQLITE_OK;
+
+#if SQLITE_MAX_WORKER_THREADS>0
+ if( pIncr->bUseThread ){
+ rc = vdbeSorterJoinThread(pIncr->pTask);
+
+ if( rc==SQLITE_OK ){
+ SorterFile f0 = pIncr->aFile[0];
+ pIncr->aFile[0] = pIncr->aFile[1];
+ pIncr->aFile[1] = f0;
+ }
+
+ if( rc==SQLITE_OK ){
+ if( pIncr->aFile[0].iEof==pIncr->iStartOff ){
+ pIncr->bEof = 1;
+ }else{
+ rc = vdbeIncrBgPopulate(pIncr);
+ }
+ }
+ }else
+#endif
+ {
+ rc = vdbeIncrPopulate(pIncr);
+ pIncr->aFile[0] = pIncr->aFile[1];
+ if( pIncr->aFile[0].iEof==pIncr->iStartOff ){
+ pIncr->bEof = 1;
+ }
}
return rc;
}
/*
-** Helper function for sqlite3VdbeSorterRewind().
+** Allocate and return a new IncrMerger object to read data from pMerger.
+**
+** If an OOM condition is encountered, return NULL. In this case free the
+** pMerger argument before returning.
*/
-static int vdbeSorterInitMerge(
- sqlite3 *db, /* Database handle */
- const VdbeCursor *pCsr, /* Cursor handle for this sorter */
- i64 *pnByte /* Sum of bytes in all opened PMAs */
+static int vdbeIncrMergerNew(
+ SortSubtask *pTask, /* The thread that will be using the new IncrMerger */
+ MergeEngine *pMerger, /* The MergeEngine that the IncrMerger will control */
+ IncrMerger **ppOut /* Write the new IncrMerger here */
+){
+ int rc = SQLITE_OK;
+ IncrMerger *pIncr = *ppOut = (IncrMerger*)
+ (sqlite3FaultSim(100) ? 0 : sqlite3MallocZero(sizeof(*pIncr)));
+ if( pIncr ){
+ pIncr->pMerger = pMerger;
+ pIncr->pTask = pTask;
+ pIncr->mxSz = MAX(pTask->pSorter->mxKeysize+9,pTask->pSorter->mxPmaSize/2);
+ pTask->file2.iEof += pIncr->mxSz;
+ }else{
+ vdbeMergeEngineFree(pMerger);
+ rc = SQLITE_NOMEM;
+ }
+ return rc;
+}
+
+#if SQLITE_MAX_WORKER_THREADS>0
+/*
+** Set the "use-threads" flag on object pIncr.
+*/
+static void vdbeIncrMergerSetThreads(IncrMerger *pIncr){
+ pIncr->bUseThread = 1;
+ pIncr->pTask->file2.iEof -= pIncr->mxSz;
+}
+#endif /* SQLITE_MAX_WORKER_THREADS>0 */
+
+
+
+/*
+** Recompute pMerger->aTree[iOut] by comparing the next keys on the
+** two PmaReaders that feed that entry. Neither of the PmaReaders
+** are advanced. This routine merely does the comparison.
+*/
+static void vdbeMergeEngineCompare(
+ MergeEngine *pMerger, /* Merge engine containing PmaReaders to compare */
+ int iOut /* Store the result in pMerger->aTree[iOut] */
+){
+ int i1;
+ int i2;
+ int iRes;
+ PmaReader *p1;
+ PmaReader *p2;
+
+ assert( iOut<pMerger->nTree && iOut>0 );
+
+ if( iOut>=(pMerger->nTree/2) ){
+ i1 = (iOut - pMerger->nTree/2) * 2;
+ i2 = i1 + 1;
+ }else{
+ i1 = pMerger->aTree[iOut*2];
+ i2 = pMerger->aTree[iOut*2+1];
+ }
+
+ p1 = &pMerger->aReadr[i1];
+ p2 = &pMerger->aReadr[i2];
+
+ if( p1->pFd==0 ){
+ iRes = i2;
+ }else if( p2->pFd==0 ){
+ iRes = i1;
+ }else{
+ SortSubtask *pTask = pMerger->pTask;
+ int bCached = 0;
+ int res;
+ assert( pTask->pUnpacked!=0 ); /* from vdbeSortSubtaskMain() */
+ res = pTask->xCompare(
+ pTask, &bCached, p1->aKey, p1->nKey, p2->aKey, p2->nKey
+ );
+ if( res<=0 ){
+ iRes = i1;
+ }else{
+ iRes = i2;
+ }
+ }
+
+ pMerger->aTree[iOut] = iRes;
+}
+
+/*
+** Allowed values for the eMode parameter to vdbeMergeEngineInit()
+** and vdbePmaReaderIncrMergeInit().
+**
+** Only INCRINIT_NORMAL is valid in single-threaded builds (when
+** SQLITE_MAX_WORKER_THREADS==0). The other values are only used
+** when there exists one or more separate worker threads.
+*/
+#define INCRINIT_NORMAL 0
+#define INCRINIT_TASK 1
+#define INCRINIT_ROOT 2
+
+/*
+** Forward reference required as the vdbeIncrMergeInit() and
+** vdbePmaReaderIncrInit() routines are called mutually recursively when
+** building a merge tree.
+*/
+static int vdbePmaReaderIncrInit(PmaReader *pReadr, int eMode);
+
+/*
+** Initialize the MergeEngine object passed as the second argument. Once this
+** function returns, the first key of merged data may be read from the
+** MergeEngine object in the usual fashion.
+**
+** If argument eMode is INCRINIT_ROOT, then it is assumed that any IncrMerge
+** objects attached to the PmaReader objects that the merger reads from have
+** already been populated, but that they have not yet populated aFile[0] and
+** set the PmaReader objects up to read from it. In this case all that is
+** required is to call vdbePmaReaderNext() on each PmaReader to point it at
+** its first key.
+**
+** Otherwise, if eMode is any value other than INCRINIT_ROOT, then use
+** vdbePmaReaderIncrMergeInit() to initialize each PmaReader that feeds data
+** to pMerger.
+**
+** SQLITE_OK is returned if successful, or an SQLite error code otherwise.
+*/
+static int vdbeMergeEngineInit(
+ SortSubtask *pTask, /* Thread that will run pMerger */
+ MergeEngine *pMerger, /* MergeEngine to initialize */
+ int eMode /* One of the INCRINIT_XXX constants */
){
- 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 */
+ int i; /* For looping over PmaReader objects */
+ int nTree = pMerger->nTree;
+
+ /* eMode is always INCRINIT_NORMAL in single-threaded mode */
+ assert( SQLITE_MAX_WORKER_THREADS>0 || eMode==INCRINIT_NORMAL );
+
+ /* Verify that the MergeEngine is assigned to a single thread */
+ assert( pMerger->pTask==0 );
+ pMerger->pTask = pTask;
+
+ for(i=0; i<nTree; i++){
+ if( SQLITE_MAX_WORKER_THREADS>0 && eMode==INCRINIT_ROOT ){
+ /* PmaReaders should be normally initialized in order, as if they are
+ ** reading from the same temp file this makes for more linear file IO.
+ ** However, in the INCRINIT_ROOT case, if PmaReader aReadr[nTask-1] is
+ ** in use it will block the vdbePmaReaderNext() call while it uses
+ ** the main thread to fill its buffer. So calling PmaReaderNext()
+ ** on this PmaReader before any of the multi-threaded PmaReaders takes
+ ** better advantage of multi-processor hardware. */
+ rc = vdbePmaReaderNext(&pMerger->aReadr[nTree-i-1]);
+ }else{
+ rc = vdbePmaReaderIncrInit(&pMerger->aReadr[i], INCRINIT_NORMAL);
+ }
+ if( rc!=SQLITE_OK ) return rc;
+ }
- /* 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;
+ for(i=pMerger->nTree-1; i>0; i--){
+ vdbeMergeEngineCompare(pMerger, i);
}
+ return pTask->pUnpacked->errCode;
+}
- /* Initialize the aTree[] array. */
- for(i=pSorter->nTree-1; rc==SQLITE_OK && i>0; i--){
- rc = vdbeSorterDoCompare(pCsr, i);
+/*
+** The PmaReader passed as the first argument is guaranteed to be an
+** incremental-reader (pReadr->pIncr!=0). This function serves to open
+** and/or initialize the temp file related fields of the IncrMerge
+** object at (pReadr->pIncr).
+**
+** If argument eMode is set to INCRINIT_NORMAL, then all PmaReaders
+** in the sub-tree headed by pReadr are also initialized. Data is then
+** loaded into the buffers belonging to pReadr and it is set to point to
+** the first key in its range.
+**
+** If argument eMode is set to INCRINIT_TASK, then pReadr is guaranteed
+** to be a multi-threaded PmaReader and this function is being called in a
+** background thread. In this case all PmaReaders in the sub-tree are
+** initialized as for INCRINIT_NORMAL and the aFile[1] buffer belonging to
+** pReadr is populated. However, pReadr itself is not set up to point
+** to its first key. A call to vdbePmaReaderNext() is still required to do
+** that.
+**
+** The reason this function does not call vdbePmaReaderNext() immediately
+** in the INCRINIT_TASK case is that vdbePmaReaderNext() assumes that it has
+** to block on thread (pTask->thread) before accessing aFile[1]. But, since
+** this entire function is being run by thread (pTask->thread), that will
+** lead to the current background thread attempting to join itself.
+**
+** Finally, if argument eMode is set to INCRINIT_ROOT, it may be assumed
+** that pReadr->pIncr is a multi-threaded IncrMerge objects, and that all
+** child-trees have already been initialized using IncrInit(INCRINIT_TASK).
+** In this case vdbePmaReaderNext() is called on all child PmaReaders and
+** the current PmaReader set to point to the first key in its range.
+**
+** SQLITE_OK is returned if successful, or an SQLite error code otherwise.
+*/
+static int vdbePmaReaderIncrMergeInit(PmaReader *pReadr, int eMode){
+ int rc = SQLITE_OK;
+ IncrMerger *pIncr = pReadr->pIncr;
+ SortSubtask *pTask = pIncr->pTask;
+ sqlite3 *db = pTask->pSorter->db;
+
+ /* eMode is always INCRINIT_NORMAL in single-threaded mode */
+ assert( SQLITE_MAX_WORKER_THREADS>0 || eMode==INCRINIT_NORMAL );
+
+ rc = vdbeMergeEngineInit(pTask, pIncr->pMerger, eMode);
+
+ /* Set up the required files for pIncr. A multi-theaded IncrMerge object
+ ** requires two temp files to itself, whereas a single-threaded object
+ ** only requires a region of pTask->file2. */
+ if( rc==SQLITE_OK ){
+ int mxSz = pIncr->mxSz;
+#if SQLITE_MAX_WORKER_THREADS>0
+ if( pIncr->bUseThread ){
+ rc = vdbeSorterOpenTempFile(db, mxSz, &pIncr->aFile[0].pFd);
+ if( rc==SQLITE_OK ){
+ rc = vdbeSorterOpenTempFile(db, mxSz, &pIncr->aFile[1].pFd);
+ }
+ }else
+#endif
+ /*if( !pIncr->bUseThread )*/{
+ if( pTask->file2.pFd==0 ){
+ assert( pTask->file2.iEof>0 );
+ rc = vdbeSorterOpenTempFile(db, pTask->file2.iEof, &pTask->file2.pFd);
+ pTask->file2.iEof = 0;
+ }
+ if( rc==SQLITE_OK ){
+ pIncr->aFile[1].pFd = pTask->file2.pFd;
+ pIncr->iStartOff = pTask->file2.iEof;
+ pTask->file2.iEof += mxSz;
+ }
+ }
+ }
+
+#if SQLITE_MAX_WORKER_THREADS>0
+ if( rc==SQLITE_OK && pIncr->bUseThread ){
+ /* Use the current thread to populate aFile[1], even though this
+ ** PmaReader is multi-threaded. If this is an INCRINIT_TASK object,
+ ** then this function is already running in background thread
+ ** pIncr->pTask->thread.
+ **
+ ** If this is the INCRINIT_ROOT object, then it is running in the
+ ** main VDBE thread. But that is Ok, as that thread cannot return
+ ** control to the VDBE or proceed with anything useful until the
+ ** first results are ready from this merger object anyway.
+ */
+ assert( eMode==INCRINIT_ROOT || eMode==INCRINIT_TASK );
+ rc = vdbeIncrPopulate(pIncr);
+ }
+#endif
+
+ if( rc==SQLITE_OK && (SQLITE_MAX_WORKER_THREADS==0 || eMode!=INCRINIT_TASK) ){
+ rc = vdbePmaReaderNext(pReadr);
}
- *pnByte = nByte;
return rc;
}
+#if SQLITE_MAX_WORKER_THREADS>0
/*
-** Once the sorter has been populated, this function is called to prepare
-** for iterating through its contents in sorted order.
+** The main routine for vdbePmaReaderIncrMergeInit() operations run in
+** background threads.
*/
-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 */
+static void *vdbePmaReaderBgIncrInit(void *pCtx){
+ PmaReader *pReader = (PmaReader*)pCtx;
+ void *pRet = SQLITE_INT_TO_PTR(
+ vdbePmaReaderIncrMergeInit(pReader,INCRINIT_TASK)
+ );
+ pReader->pIncr->pTask->bDone = 1;
+ return pRet;
+}
+#endif
- assert( pSorter );
+/*
+** If the PmaReader passed as the first argument is not an incremental-reader
+** (if pReadr->pIncr==0), then this function is a no-op. Otherwise, it invokes
+** the vdbePmaReaderIncrMergeInit() function with the parameters passed to
+** this routine to initialize the incremental merge.
+**
+** If the IncrMerger object is multi-threaded (IncrMerger.bUseThread==1),
+** then a background thread is launched to call vdbePmaReaderIncrMergeInit().
+** Or, if the IncrMerger is single threaded, the same function is called
+** using the current thread.
+*/
+static int vdbePmaReaderIncrInit(PmaReader *pReadr, int eMode){
+ IncrMerger *pIncr = pReadr->pIncr; /* Incremental merger */
+ int rc = SQLITE_OK; /* Return code */
+ if( pIncr ){
+#if SQLITE_MAX_WORKER_THREADS>0
+ assert( pIncr->bUseThread==0 || eMode==INCRINIT_TASK );
+ if( pIncr->bUseThread ){
+ void *pCtx = (void*)pReadr;
+ rc = vdbeSorterCreateThread(pIncr->pTask, vdbePmaReaderBgIncrInit, pCtx);
+ }else
+#endif
+ {
+ rc = vdbePmaReaderIncrMergeInit(pReadr, eMode);
+ }
+ }
+ return rc;
+}
- /* 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);
+/*
+** Allocate a new MergeEngine object to merge the contents of nPMA level-0
+** PMAs from pTask->file. If no error occurs, set *ppOut to point to
+** the new object and return SQLITE_OK. Or, if an error does occur, set *ppOut
+** to NULL and return an SQLite error code.
+**
+** When this function is called, *piOffset is set to the offset of the
+** first PMA to read from pTask->file. Assuming no error occurs, it is
+** set to the offset immediately following the last byte of the last
+** PMA before returning. If an error does occur, then the final value of
+** *piOffset is undefined.
+*/
+static int vdbeMergeEngineLevel0(
+ SortSubtask *pTask, /* Sorter task to read from */
+ int nPMA, /* Number of PMAs to read */
+ i64 *piOffset, /* IN/OUT: Readr offset in pTask->file */
+ MergeEngine **ppOut /* OUT: New merge-engine */
+){
+ MergeEngine *pNew; /* Merge engine to return */
+ i64 iOff = *piOffset;
+ int i;
+ int rc = SQLITE_OK;
+
+ *ppOut = pNew = vdbeMergeEngineNew(nPMA);
+ if( pNew==0 ) rc = SQLITE_NOMEM;
+
+ for(i=0; i<nPMA && rc==SQLITE_OK; i++){
+ i64 nDummy;
+ PmaReader *pReadr = &pNew->aReadr[i];
+ rc = vdbePmaReaderInit(pTask, &pTask->file, iOff, pReadr, &nDummy);
+ iOff = pReadr->iEof;
}
- /* Write the current in-memory list to a PMA. */
- rc = vdbeSorterListToPMA(db, pCsr);
- if( rc!=SQLITE_OK ) return rc;
+ if( rc!=SQLITE_OK ){
+ vdbeMergeEngineFree(pNew);
+ *ppOut = 0;
+ }
+ *piOffset = iOff;
+ 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;
+/*
+** Return the depth of a tree comprising nPMA PMAs, assuming a fanout of
+** SORTER_MAX_MERGE_COUNT. The returned value does not include leaf nodes.
+**
+** i.e.
+**
+** nPMA<=16 -> TreeDepth() == 0
+** nPMA<=256 -> TreeDepth() == 1
+** nPMA<=65536 -> TreeDepth() == 2
+*/
+static int vdbeSorterTreeDepth(int nPMA){
+ int nDepth = 0;
+ i64 nDiv = SORTER_MAX_MERGE_COUNT;
+ while( nDiv < (i64)nPMA ){
+ nDiv = nDiv * SORTER_MAX_MERGE_COUNT;
+ nDepth++;
+ }
+ return nDepth;
+}
- do {
- int iNew; /* Index of new, merged, PMA */
+/*
+** pRoot is the root of an incremental merge-tree with depth nDepth (according
+** to vdbeSorterTreeDepth()). pLeaf is the iSeq'th leaf to be added to the
+** tree, counting from zero. This function adds pLeaf to the tree.
+**
+** If successful, SQLITE_OK is returned. If an error occurs, an SQLite error
+** code is returned and pLeaf is freed.
+*/
+static int vdbeSorterAddToTree(
+ SortSubtask *pTask, /* Task context */
+ int nDepth, /* Depth of tree according to TreeDepth() */
+ int iSeq, /* Sequence number of leaf within tree */
+ MergeEngine *pRoot, /* Root of tree */
+ MergeEngine *pLeaf /* Leaf to add to tree */
+){
+ int rc = SQLITE_OK;
+ int nDiv = 1;
+ int i;
+ MergeEngine *p = pRoot;
+ IncrMerger *pIncr;
- 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 */
+ rc = vdbeIncrMergerNew(pTask, pLeaf, &pIncr);
- memset(&writer, 0, sizeof(FileWriter));
+ for(i=1; i<nDepth; i++){
+ nDiv = nDiv * SORTER_MAX_MERGE_COUNT;
+ }
- /* 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;
+ for(i=1; i<nDepth && rc==SQLITE_OK; i++){
+ int iIter = (iSeq / nDiv) % SORTER_MAX_MERGE_COUNT;
+ PmaReader *pReadr = &p->aReadr[iIter];
+
+ if( pReadr->pIncr==0 ){
+ MergeEngine *pNew = vdbeMergeEngineNew(SORTER_MAX_MERGE_COUNT);
+ if( pNew==0 ){
+ rc = SQLITE_NOMEM;
+ }else{
+ rc = vdbeIncrMergerNew(pTask, pNew, &pReadr->pIncr);
}
+ }
+ if( rc==SQLITE_OK ){
+ p = pReadr->pIncr->pMerger;
+ nDiv = nDiv / SORTER_MAX_MERGE_COUNT;
+ }
+ }
+
+ if( rc==SQLITE_OK ){
+ p->aReadr[iSeq % SORTER_MAX_MERGE_COUNT].pIncr = pIncr;
+ }else{
+ vdbeIncrFree(pIncr);
+ }
+ return rc;
+}
- /* Open the second temp file, if it is not already open. */
- if( pTemp2==0 ){
- assert( iWrite2==0 );
- rc = vdbeSorterOpenTempFile(db, &pTemp2);
+/*
+** This function is called as part of a SorterRewind() operation on a sorter
+** that has already written two or more level-0 PMAs to one or more temp
+** files. It builds a tree of MergeEngine/IncrMerger/PmaReader objects that
+** can be used to incrementally merge all PMAs on disk.
+**
+** If successful, SQLITE_OK is returned and *ppOut set to point to the
+** MergeEngine object at the root of the tree before returning. Or, if an
+** error occurs, an SQLite error code is returned and the final value
+** of *ppOut is undefined.
+*/
+static int vdbeSorterMergeTreeBuild(
+ VdbeSorter *pSorter, /* The VDBE cursor that implements the sort */
+ MergeEngine **ppOut /* Write the MergeEngine here */
+){
+ MergeEngine *pMain = 0;
+ int rc = SQLITE_OK;
+ int iTask;
+
+#if SQLITE_MAX_WORKER_THREADS>0
+ /* If the sorter uses more than one task, then create the top-level
+ ** MergeEngine here. This MergeEngine will read data from exactly
+ ** one PmaReader per sub-task. */
+ assert( pSorter->bUseThreads || pSorter->nTask==1 );
+ if( pSorter->nTask>1 ){
+ pMain = vdbeMergeEngineNew(pSorter->nTask);
+ if( pMain==0 ) rc = SQLITE_NOMEM;
+ }
+#endif
+
+ for(iTask=0; rc==SQLITE_OK && iTask<pSorter->nTask; iTask++){
+ SortSubtask *pTask = &pSorter->aTask[iTask];
+ assert( pTask->nPMA>0 || SQLITE_MAX_WORKER_THREADS>0 );
+ if( SQLITE_MAX_WORKER_THREADS==0 || pTask->nPMA ){
+ MergeEngine *pRoot = 0; /* Root node of tree for this task */
+ int nDepth = vdbeSorterTreeDepth(pTask->nPMA);
+ i64 iReadOff = 0;
+
+ if( pTask->nPMA<=SORTER_MAX_MERGE_COUNT ){
+ rc = vdbeMergeEngineLevel0(pTask, pTask->nPMA, &iReadOff, &pRoot);
+ }else{
+ int i;
+ int iSeq = 0;
+ pRoot = vdbeMergeEngineNew(SORTER_MAX_MERGE_COUNT);
+ if( pRoot==0 ) rc = SQLITE_NOMEM;
+ for(i=0; i<pTask->nPMA && rc==SQLITE_OK; i += SORTER_MAX_MERGE_COUNT){
+ MergeEngine *pMerger = 0; /* New level-0 PMA merger */
+ int nReader; /* Number of level-0 PMAs to merge */
+
+ nReader = MIN(pTask->nPMA - i, SORTER_MAX_MERGE_COUNT);
+ rc = vdbeMergeEngineLevel0(pTask, nReader, &iReadOff, &pMerger);
+ if( rc==SQLITE_OK ){
+ rc = vdbeSorterAddToTree(pTask, nDepth, iSeq++, pRoot, pMerger);
+ }
+ }
}
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 );
+#if SQLITE_MAX_WORKER_THREADS>0
+ if( pMain!=0 ){
+ rc = vdbeIncrMergerNew(pTask, pRoot, &pMain->aReadr[iTask].pIncr);
+ }else
+#endif
+ {
+ assert( pMain==0 );
+ pMain = pRoot;
+ }
+ }else{
+ vdbeMergeEngineFree(pRoot);
+ }
+ }
+ }
+
+ if( rc!=SQLITE_OK ){
+ vdbeMergeEngineFree(pMain);
+ pMain = 0;
+ }
+ *ppOut = pMain;
+ return rc;
+}
- fileWriterWriteVarint(&writer, pIter->nKey);
- fileWriterWrite(&writer, pIter->aKey, pIter->nKey);
- rc = sqlite3VdbeSorterNext(db, pCsr, &bEof);
+/*
+** This function is called as part of an sqlite3VdbeSorterRewind() operation
+** on a sorter that has written two or more PMAs to temporary files. It sets
+** up either VdbeSorter.pMerger (for single threaded sorters) or pReader
+** (for multi-threaded sorters) so that it can be used to iterate through
+** all records stored in the sorter.
+**
+** SQLITE_OK is returned if successful, or an SQLite error code otherwise.
+*/
+static int vdbeSorterSetupMerge(VdbeSorter *pSorter){
+ int rc; /* Return code */
+ SortSubtask *pTask0 = &pSorter->aTask[0];
+ MergeEngine *pMain = 0;
+#if SQLITE_MAX_WORKER_THREADS
+ sqlite3 *db = pTask0->pSorter->db;
+ int i;
+ SorterCompare xCompare = vdbeSorterGetCompare(pSorter);
+ for(i=0; i<pSorter->nTask; i++){
+ pSorter->aTask[i].xCompare = xCompare;
+ }
+#endif
+
+ rc = vdbeSorterMergeTreeBuild(pSorter, &pMain);
+ if( rc==SQLITE_OK ){
+#if SQLITE_MAX_WORKER_THREADS
+ assert( pSorter->bUseThreads==0 || pSorter->nTask>1 );
+ if( pSorter->bUseThreads ){
+ int iTask;
+ PmaReader *pReadr = 0;
+ SortSubtask *pLast = &pSorter->aTask[pSorter->nTask-1];
+ rc = vdbeSortAllocUnpacked(pLast);
+ if( rc==SQLITE_OK ){
+ pReadr = (PmaReader*)sqlite3DbMallocZero(db, sizeof(PmaReader));
+ pSorter->pReader = pReadr;
+ if( pReadr==0 ) rc = SQLITE_NOMEM;
+ }
+ if( rc==SQLITE_OK ){
+ rc = vdbeIncrMergerNew(pLast, pMain, &pReadr->pIncr);
+ if( rc==SQLITE_OK ){
+ vdbeIncrMergerSetThreads(pReadr->pIncr);
+ for(iTask=0; iTask<(pSorter->nTask-1); iTask++){
+ IncrMerger *pIncr;
+ if( (pIncr = pMain->aReadr[iTask].pIncr) ){
+ vdbeIncrMergerSetThreads(pIncr);
+ assert( pIncr->pTask!=pLast );
+ }
+ }
+ for(iTask=0; rc==SQLITE_OK && iTask<pSorter->nTask; iTask++){
+ /* Check that:
+ **
+ ** a) The incremental merge object is configured to use the
+ ** right task, and
+ ** b) If it is using task (nTask-1), it is configured to run
+ ** in single-threaded mode. This is important, as the
+ ** root merge (INCRINIT_ROOT) will be using the same task
+ ** object.
+ */
+ PmaReader *p = &pMain->aReadr[iTask];
+ assert( p->pIncr==0 || (
+ (p->pIncr->pTask==&pSorter->aTask[iTask]) /* a */
+ && (iTask!=pSorter->nTask-1 || p->pIncr->bUseThread==0) /* b */
+ ));
+ rc = vdbePmaReaderIncrInit(p, INCRINIT_TASK);
+ }
}
- rc2 = fileWriterFinish(db, &writer, &iWrite2);
- if( rc==SQLITE_OK ) rc = rc2;
+ pMain = 0;
+ }
+ if( rc==SQLITE_OK ){
+ rc = vdbePmaReaderIncrMergeInit(pReadr, INCRINIT_ROOT);
}
+ }else
+#endif
+ {
+ rc = vdbeMergeEngineInit(pTask0, pMain, INCRINIT_NORMAL);
+ pSorter->pMerger = pMain;
+ pMain = 0;
}
+ }
- if( pSorter->nPMA<=SORTER_MAX_MERGE_COUNT ){
- break;
+ if( rc!=SQLITE_OK ){
+ vdbeMergeEngineFree(pMain);
+ }
+ return rc;
+}
+
+
+/*
+** Once the sorter has been populated by calls to sqlite3VdbeSorterWrite,
+** this function is called to prepare for iterating through the records
+** in sorted order.
+*/
+SQLITE_PRIVATE int sqlite3VdbeSorterRewind(const VdbeCursor *pCsr, int *pbEof){
+ VdbeSorter *pSorter;
+ int rc = SQLITE_OK; /* Return code */
+
+ assert( pCsr->eCurType==CURTYPE_SORTER );
+ pSorter = pCsr->uc.pSorter;
+ 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->bUsePMA==0 ){
+ if( pSorter->list.pList ){
+ *pbEof = 0;
+ rc = vdbeSorterSort(&pSorter->aTask[0], &pSorter->list);
}else{
- sqlite3_file *pTmp = pSorter->pTemp1;
- pSorter->nPMA = iNew;
- pSorter->pTemp1 = pTemp2;
- pTemp2 = pTmp;
- pSorter->iWriteOff = iWrite2;
- pSorter->iReadOff = 0;
- iWrite2 = 0;
+ *pbEof = 1;
}
- }while( rc==SQLITE_OK );
+ return rc;
+ }
+
+ /* Write the current in-memory list to a PMA. When the VdbeSorterWrite()
+ ** function flushes the contents of memory to disk, it immediately always
+ ** creates a new list consisting of a single key immediately afterwards.
+ ** So the list is never empty at this point. */
+ assert( pSorter->list.pList );
+ rc = vdbeSorterFlushPMA(pSorter);
- if( pTemp2 ){
- sqlite3OsCloseFree(pTemp2);
+ /* Join all threads */
+ rc = vdbeSorterJoinAll(pSorter, rc);
+
+ vdbeSorterRewindDebug("rewind");
+
+ /* Assuming no errors have occurred, set up a merger structure to
+ ** incrementally read and merge all remaining PMAs. */
+ assert( pSorter->pReader==0 );
+ if( rc==SQLITE_OK ){
+ rc = vdbeSorterSetupMerge(pSorter);
+ *pbEof = 0;
}
- *pbEof = (pSorter->aIter[pSorter->aTree[1]].pFile==0);
+
+ vdbeSorterRewindDebug("rewinddone");
return rc;
}
@@ -71742,25 +83583,33 @@ SQLITE_PRIVATE int sqlite3VdbeSorterRewind(sqlite3 *db, const VdbeCursor *pCsr,
** Advance to the next element in the sorter.
*/
SQLITE_PRIVATE int sqlite3VdbeSorterNext(sqlite3 *db, const VdbeCursor *pCsr, int *pbEof){
- VdbeSorter *pSorter = pCsr->pSorter;
+ VdbeSorter *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);
+ assert( pCsr->eCurType==CURTYPE_SORTER );
+ pSorter = pCsr->uc.pSorter;
+ assert( pSorter->bUsePMA || (pSorter->pReader==0 && pSorter->pMerger==0) );
+ if( pSorter->bUsePMA ){
+ assert( pSorter->pReader==0 || pSorter->pMerger==0 );
+ assert( pSorter->bUseThreads==0 || pSorter->pReader );
+ assert( pSorter->bUseThreads==1 || pSorter->pMerger );
+#if SQLITE_MAX_WORKER_THREADS>0
+ if( pSorter->bUseThreads ){
+ rc = vdbePmaReaderNext(pSorter->pReader);
+ *pbEof = (pSorter->pReader->pFd==0);
+ }else
+#endif
+ /*if( !pSorter->bUseThreads )*/ {
+ assert( pSorter->pMerger!=0 );
+ assert( pSorter->pMerger->pTask==(&pSorter->aTask[0]) );
+ rc = vdbeMergeEngineStep(pSorter->pMerger, pbEof);
}
-
- *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;
+ SorterRecord *pFree = pSorter->list.pList;
+ pSorter->list.pList = pFree->u.pNext;
+ pFree->u.pNext = 0;
+ if( pSorter->list.aMemory==0 ) vdbeSorterRecordFree(db, pFree);
+ *pbEof = !pSorter->list.pList;
rc = SQLITE_OK;
}
return rc;
@@ -71775,14 +83624,21 @@ static void *vdbeSorterRowkey(
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;
+ if( pSorter->bUsePMA ){
+ PmaReader *pReader;
+#if SQLITE_MAX_WORKER_THREADS>0
+ if( pSorter->bUseThreads ){
+ pReader = pSorter->pReader;
+ }else
+#endif
+ /*if( !pSorter->bUseThreads )*/{
+ pReader = &pSorter->pMerger->aReadr[pSorter->pMerger->aTree[1]];
+ }
+ *pnKey = pReader->nKey;
+ pKey = pReader->aKey;
}else{
- *pnKey = pSorter->pRecord->nVal;
- pKey = pSorter->pRecord->pVal;
+ *pnKey = pSorter->list.pList->nVal;
+ pKey = SRVAL(pSorter->list.pList);
}
return pKey;
}
@@ -71791,11 +83647,13 @@ static void *vdbeSorterRowkey(
** Copy the current sorter key into the memory cell pOut.
*/
SQLITE_PRIVATE int sqlite3VdbeSorterRowkey(const VdbeCursor *pCsr, Mem *pOut){
- VdbeSorter *pSorter = pCsr->pSorter;
+ VdbeSorter *pSorter;
void *pKey; int nKey; /* Sorter key to copy into pOut */
+ assert( pCsr->eCurType==CURTYPE_SORTER );
+ pSorter = pCsr->uc.pSorter;
pKey = vdbeSorterRowkey(pSorter, &nKey);
- if( sqlite3VdbeMemGrow(pOut, nKey, 0) ){
+ if( sqlite3VdbeMemClearAndResize(pOut, nKey) ){
return SQLITE_NOMEM;
}
pOut->n = nKey;
@@ -71810,26 +83668,55 @@ SQLITE_PRIVATE int sqlite3VdbeSorterRowkey(const VdbeCursor *pCsr, Mem *pOut){
** 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 the sorter cursor key contains any NULL values, consider it to be
+** less than pVal. Even if pVal also contains NULL values.
+**
** 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.
+**
+** This routine forms the core of the OP_SorterCompare opcode, which in
+** turn is used to verify uniqueness when constructing a UNIQUE INDEX.
*/
SQLITE_PRIVATE int sqlite3VdbeSorterCompare(
const VdbeCursor *pCsr, /* Sorter cursor */
Mem *pVal, /* Value to compare to current sorter key */
+ int nKeyCol, /* Compare this many columns */
int *pRes /* OUT: Result of comparison */
){
- VdbeSorter *pSorter = pCsr->pSorter;
+ VdbeSorter *pSorter;
+ UnpackedRecord *r2;
+ KeyInfo *pKeyInfo;
+ int i;
void *pKey; int nKey; /* Sorter key to compare pVal with */
+ assert( pCsr->eCurType==CURTYPE_SORTER );
+ pSorter = pCsr->uc.pSorter;
+ r2 = pSorter->pUnpacked;
+ pKeyInfo = pCsr->pKeyInfo;
+ if( r2==0 ){
+ char *p;
+ r2 = pSorter->pUnpacked = sqlite3VdbeAllocUnpackedRecord(pKeyInfo,0,0,&p);
+ assert( pSorter->pUnpacked==(UnpackedRecord*)p );
+ if( r2==0 ) return SQLITE_NOMEM;
+ r2->nField = nKeyCol;
+ }
+ assert( r2->nField==nKeyCol );
+
pKey = vdbeSorterRowkey(pSorter, &nKey);
- vdbeSorterCompare(pCsr, 1, pVal->z, pVal->n, pKey, nKey, pRes);
+ sqlite3VdbeRecordUnpack(pKeyInfo, nKey, pKey, r2);
+ for(i=0; i<nKeyCol; i++){
+ if( r2->aMem[i].flags & MEM_Null ){
+ *pRes = -1;
+ return SQLITE_OK;
+ }
+ }
+
+ *pRes = sqlite3VdbeRecordCompare(pVal->n, pVal->z, r2);
return SQLITE_OK;
}
-#endif /* #ifndef SQLITE_OMIT_MERGE_SORT */
-
/************** End of vdbesort.c ********************************************/
/************** Begin file journal.c *****************************************/
/*
@@ -71859,6 +83746,7 @@ SQLITE_PRIVATE int sqlite3VdbeSorterCompare(
** 2) The sqlite3JournalCreate() function is called.
*/
#ifdef SQLITE_ENABLE_ATOMIC_WRITE
+/* #include "sqliteInt.h" */
/*
@@ -71892,6 +83780,14 @@ static int createFile(JournalFile *p){
assert(p->iSize<=p->nBuf);
rc = sqlite3OsWrite(p->pReal, p->zBuf, p->iSize, 0);
}
+ if( rc!=SQLITE_OK ){
+ /* If an error occurred while writing to the file, close it before
+ ** returning. This way, SQLite uses the in-memory journal data to
+ ** roll back changes made to the internal page-cache before this
+ ** function was called. */
+ sqlite3OsClose(pReal);
+ p->pReal = 0;
+ }
}
}
return rc;
@@ -72098,6 +83994,7 @@ SQLITE_PRIVATE int sqlite3JournalSize(sqlite3_vfs *pVfs){
** The in-memory rollback journal is used to journal transactions for
** ":memory:" databases and when the journal_mode=MEMORY pragma is used.
*/
+/* #include "sqliteInt.h" */
/* Forward references to internal structures */
typedef struct MemJournal MemJournal;
@@ -72109,17 +84006,11 @@ typedef struct FileChunk FileChunk;
**
** 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
+** a power-of-two allocation. This minimizes 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.
*/
@@ -72313,7 +84204,9 @@ static const struct sqlite3_io_methods MemJournalMethods = {
0, /* xShmMap */
0, /* xShmLock */
0, /* xShmBarrier */
- 0 /* xShmUnlock */
+ 0, /* xShmUnmap */
+ 0, /* xFetch */
+ 0 /* xUnfetch */
};
/*
@@ -72357,13 +84250,14 @@ SQLITE_PRIVATE int sqlite3MemJournalSize(void){
** This file contains routines used for walking the parser tree for
** an SQL statement.
*/
+/* #include "sqliteInt.h" */
/* #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
+** of the expression, while descending. (In other words, the callback
** is invoked before visiting children.)
**
** The return value from the callback should be one of the WRC_*
@@ -72387,7 +84281,7 @@ SQLITE_PRIVATE int sqlite3WalkExpr(Walker *pWalker, Expr *pExpr){
testcase( ExprHasProperty(pExpr, EP_Reduced) );
rc = pWalker->xExprCallback(pWalker, pExpr);
if( rc==WRC_Continue
- && !ExprHasAnyProperty(pExpr,EP_TokenOnly) ){
+ && !ExprHasProperty(pExpr,EP_TokenOnly) ){
if( sqlite3WalkExpr(pWalker, pExpr->pLeft) ) return WRC_Abort;
if( sqlite3WalkExpr(pWalker, pExpr->pRight) ) return WRC_Abort;
if( ExprHasProperty(pExpr, EP_xIsSelect) ){
@@ -72449,6 +84343,11 @@ SQLITE_PRIVATE int sqlite3WalkSelectFrom(Walker *pWalker, Select *p){
if( sqlite3WalkSelect(pWalker, pItem->pSelect) ){
return WRC_Abort;
}
+ if( pItem->fg.isTabFunc
+ && sqlite3WalkExprList(pWalker, pItem->u1.pFuncArg)
+ ){
+ return WRC_Abort;
+ }
}
}
return WRC_Continue;
@@ -72457,7 +84356,12 @@ SQLITE_PRIVATE int sqlite3WalkSelectFrom(Walker *pWalker, Select *p){
/*
** 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.
+** on the compound select chain, p->pPrior.
+**
+** If it is not NULL, the xSelectCallback() callback is invoked before
+** the walk of the expressions and FROM clause. The xSelectCallback2()
+** method, if it is not NULL, is invoked following the walk of the
+** expressions and FROM clause.
**
** Return WRC_Continue under normal conditions. Return WRC_Abort if
** there is an abort request.
@@ -72467,18 +84371,25 @@ SQLITE_PRIVATE int sqlite3WalkSelectFrom(Walker *pWalker, Select *p){
*/
SQLITE_PRIVATE int sqlite3WalkSelect(Walker *pWalker, Select *p){
int rc;
- if( p==0 || pWalker->xSelectCallback==0 ) return WRC_Continue;
+ if( p==0 || (pWalker->xSelectCallback==0 && pWalker->xSelectCallback2==0) ){
+ return WRC_Continue;
+ }
rc = WRC_Continue;
pWalker->walkerDepth++;
while( p ){
- rc = pWalker->xSelectCallback(pWalker, p);
- if( rc ) break;
+ if( pWalker->xSelectCallback ){
+ rc = pWalker->xSelectCallback(pWalker, p);
+ if( rc ) break;
+ }
if( sqlite3WalkSelectExpr(pWalker, p)
|| sqlite3WalkSelectFrom(pWalker, p)
){
pWalker->walkerDepth--;
return WRC_Abort;
}
+ if( pWalker->xSelectCallback2 ){
+ pWalker->xSelectCallback2(pWalker, p);
+ }
p = p->pPrior;
}
pWalker->walkerDepth--;
@@ -72503,6 +84414,7 @@ SQLITE_PRIVATE int sqlite3WalkSelect(Walker *pWalker, Select *p){
** resolve all identifiers by associating them with a particular
** table and column.
*/
+/* #include "sqliteInt.h" */
/* #include <stdlib.h> */
/* #include <string.h> */
@@ -72516,7 +84428,7 @@ SQLITE_PRIVATE int sqlite3WalkSelect(Walker *pWalker, Select *p){
** 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;
+ if( pExpr->op==TK_AGG_FUNCTION ) pExpr->op2 += pWalker->u.n;
return WRC_Continue;
}
static void incrAggFunctionDepth(Expr *pExpr, int N){
@@ -72524,7 +84436,7 @@ static void incrAggFunctionDepth(Expr *pExpr, int N){
Walker w;
memset(&w, 0, sizeof(w));
w.xExprCallback = incrAggDepth;
- w.u.i = N;
+ w.u.n = N;
sqlite3WalkExpr(&w, pExpr);
}
}
@@ -72533,29 +84445,6 @@ static void incrAggFunctionDepth(Expr *pExpr, int N){
** 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:
**
@@ -72566,7 +84455,7 @@ static void incrAggFunctionDepth(Expr *pExpr, int N){
** 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
+** alias is removed from the original expression. The usual 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.
@@ -72586,22 +84475,14 @@ static void resolveAlias(
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( zType[0]!='G' ) incrAggFunctionDepth(pDup, nSubquery);
if( pExpr->op==TK_COLLATE ){
pDup = sqlite3ExprAddCollateString(pParse, pDup, pExpr->u.zToken);
}
+ ExprSetProperty(pDup, EP_Alias);
/* Before calling sqlite3ExprDelete(), set the EP_Static flag. This
** prevents ExprDelete() from deleting the Expr structure itself,
@@ -72616,7 +84497,7 @@ static void resolveAlias(
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;
+ pExpr->flags |= EP_MemToken;
}
sqlite3DbFree(db, pDup);
}
@@ -72638,6 +84519,35 @@ static int nameInUsingClause(IdList *pUsing, const char *zCol){
return 0;
}
+/*
+** Subqueries stores the original database, table and column names for their
+** result sets in ExprList.a[].zSpan, in the form "DATABASE.TABLE.COLUMN".
+** Check to see if the zSpan given to this routine matches the zDb, zTab,
+** and zCol. If any of zDb, zTab, and zCol are NULL then those fields will
+** match anything.
+*/
+SQLITE_PRIVATE int sqlite3MatchSpanName(
+ const char *zSpan,
+ const char *zCol,
+ const char *zTab,
+ const char *zDb
+){
+ int n;
+ for(n=0; ALWAYS(zSpan[n]) && zSpan[n]!='.'; n++){}
+ if( zDb && (sqlite3StrNICmp(zSpan, zDb, n)!=0 || zDb[n]!=0) ){
+ return 0;
+ }
+ zSpan += n+1;
+ for(n=0; ALWAYS(zSpan[n]) && zSpan[n]!='.'; n++){}
+ if( zTab && (sqlite3StrNICmp(zSpan, zTab, n)!=0 || zTab[n]!=0) ){
+ return 0;
+ }
+ zSpan += n+1;
+ if( zCol && sqlite3StrICmp(zSpan, zCol)!=0 ){
+ return 0;
+ }
+ return 1;
+}
/*
** Given the name of a column of the form X.Y.Z or Y.Z or just Z, look up
@@ -72683,16 +84593,42 @@ static int lookupName(
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;
+ int isTrigger = 0; /* True if resolved to a trigger column */
+ Table *pTab = 0; /* Table hold the row */
+ Column *pCol; /* A column of pTab */
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) );
+ assert( !ExprHasProperty(pExpr, EP_TokenOnly|EP_Reduced) );
/* Initialize the node to no-match */
pExpr->iTable = -1;
pExpr->pTab = 0;
- ExprSetIrreducible(pExpr);
+ ExprSetVVAProperty(pExpr, EP_NoReduce);
+
+ /* Translate the schema name in zDb into a pointer to the corresponding
+ ** schema. If not found, pSchema will remain NULL and nothing will match
+ ** resulting in an appropriate error message toward the end of this routine
+ */
+ if( zDb ){
+ testcase( pNC->ncFlags & NC_PartIdx );
+ testcase( pNC->ncFlags & NC_IsCheck );
+ if( (pNC->ncFlags & (NC_PartIdx|NC_IsCheck))!=0 ){
+ /* Silently ignore database qualifiers inside CHECK constraints and
+ ** partial indices. Do not raise errors because that might break
+ ** legacy and because it does not hurt anything to just ignore the
+ ** database name. */
+ zDb = 0;
+ }else{
+ for(i=0; i<db->nDb; i++){
+ assert( db->aDb[i].zName );
+ if( sqlite3StrICmp(db->aDb[i].zName,zDb)==0 ){
+ pSchema = db->aDb[i].pSchema;
+ break;
+ }
+ }
+ }
+ }
/* Start at the inner-most context and move outward until a match is found */
while( pNC && cnt==0 ){
@@ -72701,32 +84637,34 @@ static int lookupName(
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( pItem->pSelect && (pItem->pSelect->selFlags & SF_NestedFrom)!=0 ){
+ int hit = 0;
+ pEList = pItem->pSelect->pEList;
+ for(j=0; j<pEList->nExpr; j++){
+ if( sqlite3MatchSpanName(pEList->a[j].zSpan, zCol, zTab, zDb) ){
+ cnt++;
+ cntTab = 2;
+ pMatch = pItem;
+ pExpr->iColumn = j;
+ hit = 1;
}
}
+ if( hit || zTab==0 ) continue;
+ }
+ if( zDb && pTab->pSchema!=pSchema ){
+ continue;
+ }
+ if( zTab ){
+ const char *zTabName = pItem->zAlias ? pItem->zAlias : pTab->zName;
+ assert( zTabName!=0 );
+ if( sqlite3StrICmp(zTabName, zTab)!=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++){
@@ -72736,29 +84674,35 @@ static int lookupName(
** USING clause, then skip this match.
*/
if( cnt==1 ){
- if( pItem->jointype & JT_NATURAL ) continue;
+ if( pItem->fg.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;
}
}
}
- }
+ if( pMatch ){
+ pExpr->iTable = pMatch->iCursor;
+ pExpr->pTab = pMatch->pTab;
+ /* RIGHT JOIN not (yet) supported */
+ assert( (pMatch->fg.jointype & JT_RIGHT)==0 );
+ if( (pMatch->fg.jointype & JT_LEFT)!=0 ){
+ ExprSetProperty(pExpr, EP_CanBeNull);
+ }
+ pSchema = pExpr->pTab->pSchema;
+ }
+ } /* if( pSrcList ) */
#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 ){
+ if( zDb==0 && zTab!=0 && cntTab==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;
@@ -72766,14 +84710,15 @@ static int lookupName(
}else if( op!=TK_INSERT && sqlite3StrICmp("old",zTab)==0 ){
pExpr->iTable = 0;
pTab = pParse->pTriggerTab;
+ }else{
+ pTab = 0;
}
if( pTab ){
int iCol;
pSchema = pTab->pSchema;
cntTab++;
- for(iCol=0; iCol<pTab->nCol; iCol++){
- Column *pCol = &pTab->aCol[iCol];
+ for(iCol=0, pCol=pTab->aCol; iCol<pTab->nCol; iCol++, pCol++){
if( sqlite3StrICmp(pCol->zName, zCol)==0 ){
if( iCol==pTab->iPKey ){
iCol = -1;
@@ -72781,8 +84726,9 @@ static int lookupName(
break;
}
}
- if( iCol>=pTab->nCol && sqlite3IsRowid(zCol) ){
- iCol = -1; /* IMP: R-44911-55124 */
+ if( iCol>=pTab->nCol && sqlite3IsRowid(zCol) && VisibleRowid(pTab) ){
+ /* IMP: R-51414-32910 */
+ iCol = -1;
}
if( iCol<pTab->nCol ){
cnt++;
@@ -72808,9 +84754,15 @@ static int lookupName(
/*
** Perhaps the name is a reference to the ROWID
*/
- if( cnt==0 && cntTab==1 && sqlite3IsRowid(zCol) ){
+ if( cnt==0
+ && cntTab==1
+ && pMatch
+ && (pNC->ncFlags & NC_IdxExpr)==0
+ && sqlite3IsRowid(zCol)
+ && VisibleRowid(pMatch->pTab)
+ ){
cnt = 1;
- pExpr->iColumn = -1; /* IMP: R-44911-55124 */
+ pExpr->iColumn = -1;
pExpr->affinity = SQLITE_AFF_INTEGER;
}
@@ -72825,8 +84777,17 @@ static int lookupName(
** 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.
+ **
+ ** The ability to use an output result-set column in the WHERE, GROUP BY,
+ ** or HAVING clauses, or as part of a larger expression in the ORDER BY
+ ** clause is not standard SQL. This is a (goofy) SQLite extension, that
+ ** is supported for backwards compatibility only. Hence, we issue a warning
+ ** on sqlite3_log() whenever the capability is used.
*/
- if( cnt==0 && (pEList = pNC->pEList)!=0 && zTab==0 ){
+ if( (pEList = pNC->pEList)!=0
+ && zTab==0
+ && cnt==0
+ ){
for(j=0; j<pEList->nExpr; j++){
char *zAs = pEList->a[j].zName;
if( zAs!=0 && sqlite3StrICmp(zAs, zCol)==0 ){
@@ -72917,7 +84878,9 @@ static int lookupName(
lookupname_end:
if( cnt==1 ){
assert( pNC!=0 );
- sqlite3AuthRead(pParse, pExpr, pSchema, pNC->pSrcList);
+ if( !ExprHasProperty(pExpr, EP_Alias) ){
+ 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(;;){
@@ -72956,6 +84919,41 @@ SQLITE_PRIVATE Expr *sqlite3CreateColumnExpr(sqlite3 *db, SrcList *pSrc, int iSr
}
/*
+** Report an error that an expression is not valid for some set of
+** pNC->ncFlags values determined by validMask.
+*/
+static void notValid(
+ Parse *pParse, /* Leave error message here */
+ NameContext *pNC, /* The name context */
+ const char *zMsg, /* Type of error */
+ int validMask /* Set of contexts for which prohibited */
+){
+ assert( (validMask&~(NC_IsCheck|NC_PartIdx|NC_IdxExpr))==0 );
+ if( (pNC->ncFlags & validMask)!=0 ){
+ const char *zIn = "partial index WHERE clauses";
+ if( pNC->ncFlags & NC_IdxExpr ) zIn = "index expressions";
+#ifndef SQLITE_OMIT_CHECK
+ else if( pNC->ncFlags & NC_IsCheck ) zIn = "CHECK constraints";
+#endif
+ sqlite3ErrorMsg(pParse, "%s prohibited in %s", zMsg, zIn);
+ }
+}
+
+/*
+** Expression p should encode a floating point value between 1.0 and 0.0.
+** Return 1024 times this value. Or return -1 if p is not a floating point
+** value between 1.0 and 0.0.
+*/
+static int exprProbability(Expr *p){
+ double r = -1.0;
+ if( p->op!=TK_FLOAT ) return -1;
+ sqlite3AtoF(p->u.zToken, &r, sqlite3Strlen30(p->u.zToken), SQLITE_UTF8);
+ assert( r>=0.0 );
+ if( r>1.0 ) return -1;
+ return (int)(r*134217728.0);
+}
+
+/*
** This routine is callback for sqlite3WalkExpr().
**
** Resolve symbolic names into TK_COLUMN operators for the current
@@ -72975,7 +84973,7 @@ static int resolveExprStep(Walker *pWalker, Expr *pExpr){
pParse = pNC->pParse;
assert( pParse==pWalker->pParse );
- if( ExprHasAnyProperty(pExpr, EP_Resolved) ) return WRC_Prune;
+ if( ExprHasProperty(pExpr, EP_Resolved) ) return WRC_Prune;
ExprSetProperty(pExpr, EP_Resolved);
#ifndef NDEBUG
if( pNC->pSrcList && pNC->pSrcList->nAlloc>0 ){
@@ -73005,7 +85003,8 @@ static int resolveExprStep(Walker *pWalker, Expr *pExpr){
pExpr->affinity = SQLITE_AFF_INTEGER;
break;
}
-#endif /* defined(SQLITE_ENABLE_UPDATE_DELETE_LIMIT) && !defined(SQLITE_OMIT_SUBQUERY) */
+#endif /* defined(SQLITE_ENABLE_UPDATE_DELETE_LIMIT)
+ && !defined(SQLITE_OMIT_SUBQUERY) */
/* A lone identifier is the name of a column.
*/
@@ -73023,6 +85022,8 @@ static int resolveExprStep(Walker *pWalker, Expr *pExpr){
Expr *pRight;
/* if( pSrcList==0 ) break; */
+ notValid(pParse, pNC, "the \".\" operator", NC_IdxExpr);
+ /*notValid(pParse, pNC, "the \".\" operator", NC_PartIdx|NC_IsCheck, 1);*/
pRight = pExpr->pRight;
if( pRight->op==TK_ID ){
zDb = 0;
@@ -73039,7 +85040,6 @@ static int resolveExprStep(Walker *pWalker, Expr *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 */
@@ -73052,8 +85052,8 @@ static int resolveExprStep(Walker *pWalker, Expr *pExpr){
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) );
+ notValid(pParse, pNC, "functions", NC_PartIdx);
zId = pExpr->u.zToken;
nId = sqlite3Strlen30(zId);
pDef = sqlite3FindFunction(pParse->db, zId, nId, n, enc, 0);
@@ -73066,9 +85066,30 @@ static int resolveExprStep(Walker *pWalker, Expr *pExpr){
}
}else{
is_agg = pDef->xFunc==0;
- }
+ if( pDef->funcFlags & SQLITE_FUNC_UNLIKELY ){
+ ExprSetProperty(pExpr, EP_Unlikely|EP_Skip);
+ if( n==2 ){
+ pExpr->iTable = exprProbability(pList->a[1].pExpr);
+ if( pExpr->iTable<0 ){
+ sqlite3ErrorMsg(pParse,
+ "second argument to likelihood() must be a "
+ "constant between 0.0 and 1.0");
+ pNC->nErr++;
+ }
+ }else{
+ /* EVIDENCE-OF: R-61304-29449 The unlikely(X) function is
+ ** equivalent to likelihood(X, 0.0625).
+ ** EVIDENCE-OF: R-01283-11636 The unlikely(X) function is
+ ** short-hand for likelihood(X,0.0625).
+ ** EVIDENCE-OF: R-36850-34127 The likely(X) function is short-hand
+ ** for likelihood(X,0.9375).
+ ** EVIDENCE-OF: R-53436-40973 The likely(X) function is equivalent
+ ** to likelihood(X,0.9375). */
+ /* TUNING: unlikely() probability is 0.0625. likely() is 0.9375 */
+ pExpr->iTable = pDef->zName[0]=='u' ? 8388608 : 125829120;
+ }
+ }
#ifndef SQLITE_OMIT_AUTHORIZATION
- if( pDef ){
auth = sqlite3AuthCheck(pParse, SQLITE_FUNCTION, 0, pDef->zName, 0);
if( auth!=SQLITE_OK ){
if( auth==SQLITE_DENY ){
@@ -73079,13 +85100,25 @@ static int resolveExprStep(Walker *pWalker, Expr *pExpr){
pExpr->op = TK_NULL;
return WRC_Prune;
}
- }
#endif
+ if( pDef->funcFlags & (SQLITE_FUNC_CONSTANT|SQLITE_FUNC_SLOCHNG) ){
+ /* For the purposes of the EP_ConstFunc flag, date and time
+ ** functions and other functions that change slowly are considered
+ ** constant because they are constant for the duration of one query */
+ ExprSetProperty(pExpr,EP_ConstFunc);
+ }
+ if( (pDef->funcFlags & SQLITE_FUNC_CONSTANT)==0 ){
+ /* Date/time functions that use 'now', and other functions like
+ ** sqlite_version() that might change over time cannot be used
+ ** in an index. */
+ notValid(pParse, pNC, "non-deterministic functions", NC_IdxExpr);
+ }
+ }
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 ){
+ }else if( no_such_func && pParse->db->init.busy==0 ){
sqlite3ErrorMsg(pParse, "no such function: %.*s", nId, zId);
pNC->nErr++;
}else if( wrong_num_args ){
@@ -73103,7 +85136,13 @@ static int resolveExprStep(Walker *pWalker, Expr *pExpr){
pExpr->op2++;
pNC2 = pNC2->pNext;
}
- if( pNC2 ) pNC2->ncFlags |= NC_HasAgg;
+ assert( pDef!=0 );
+ if( pNC2 ){
+ assert( SQLITE_FUNC_MINMAX==NC_MinMaxAgg );
+ testcase( (pDef->funcFlags & SQLITE_FUNC_MINMAX)!=0 );
+ pNC2->ncFlags |= NC_HasAgg | (pDef->funcFlags & SQLITE_FUNC_MINMAX);
+
+ }
pNC->ncFlags |= NC_AllowAgg;
}
/* FIX ME: Compute pExpr->affinity based on the expected return
@@ -73119,11 +85158,7 @@ static int resolveExprStep(Walker *pWalker, Expr *pExpr){
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
+ notValid(pParse, pNC, "subqueries", NC_IsCheck|NC_PartIdx|NC_IdxExpr);
sqlite3WalkSelect(pWalker, pExpr->x.pSelect);
assert( pNC->nRef>=nRef );
if( nRef!=pNC->nRef ){
@@ -73132,14 +85167,10 @@ static int resolveExprStep(Walker *pWalker, Expr *pExpr){
}
break;
}
-#ifndef SQLITE_OMIT_CHECK
case TK_VARIABLE: {
- if( (pNC->ncFlags & NC_IsCheck)!=0 ){
- sqlite3ErrorMsg(pParse,"parameters prohibited in CHECK constraints");
- }
+ notValid(pParse, pNC, "parameters", NC_IsCheck|NC_PartIdx|NC_IdxExpr);
break;
}
-#endif
}
return (pParse->nErr || pParse->db->mallocFailed) ? WRC_Abort : WRC_Continue;
}
@@ -73230,7 +85261,7 @@ static int resolveOrderByTermToExprList(
** result-set entry.
*/
for(i=0; i<pEList->nExpr; i++){
- if( sqlite3ExprCompare(pEList->a[i].pExpr, pE)<2 ){
+ if( sqlite3ExprCompare(pEList->a[i].pExpr, pE, -1)<2 ){
return i+1;
}
}
@@ -73331,12 +85362,14 @@ static int resolveCompoundOrderBy(
if( pItem->pExpr==pE ){
pItem->pExpr = pNew;
}else{
- assert( pItem->pExpr->op==TK_COLLATE );
- assert( pItem->pExpr->pLeft==pE );
- pItem->pExpr->pLeft = pNew;
+ Expr *pParent = pItem->pExpr;
+ assert( pParent->op==TK_COLLATE );
+ while( pParent->pLeft->op==TK_COLLATE ) pParent = pParent->pLeft;
+ assert( pParent->pLeft==pE );
+ pParent->pLeft = pNew;
}
sqlite3ExprDelete(db, pE);
- pItem->iOrderByCol = (u16)iCol;
+ pItem->u.x.iOrderByCol = (u16)iCol;
pItem->done = 1;
}else{
moreToDo = 1;
@@ -73357,8 +85390,8 @@ static int resolveCompoundOrderBy(
/*
** 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
+** result set expression (as determined by the ExprList.a.u.x.iOrderByCol
+** 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
@@ -73385,12 +85418,13 @@ SQLITE_PRIVATE int sqlite3ResolveOrderGroupBy(
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 ){
+ if( pItem->u.x.iOrderByCol ){
+ if( pItem->u.x.iOrderByCol>pEList->nExpr ){
resolveOutOfRangeError(pParse, zType, i+1, pEList->nExpr);
return 1;
}
- resolveAlias(pParse, pEList, pItem->iOrderByCol-1, pItem->pExpr, zType,0);
+ resolveAlias(pParse, pEList, pItem->u.x.iOrderByCol-1, pItem->pExpr,
+ zType,0);
}
}
return 0;
@@ -73405,7 +85439,7 @@ SQLITE_PRIVATE int sqlite3ResolveOrderGroupBy(
** 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
+** the order-by term is an identifier 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().
@@ -73431,16 +85465,19 @@ static int resolveOrderGroupBy(
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;
+ Expr *pE2 = sqlite3ExprSkipCollate(pE);
+ if( zType[0]!='G' ){
+ iCol = resolveAsName(pParse, pSelect->pEList, pE2);
+ 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->u.x.iOrderByCol = (u16)iCol;
+ continue;
+ }
}
- if( sqlite3ExprIsInteger(sqlite3ExprSkipCollate(pE), &iCol) ){
+ if( sqlite3ExprIsInteger(pE2, &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 */
@@ -73448,18 +85485,18 @@ static int resolveOrderGroupBy(
resolveOutOfRangeError(pParse, zType, i+1, nResult);
return 1;
}
- pItem->iOrderByCol = (u16)iCol;
+ pItem->u.x.iOrderByCol = (u16)iCol;
continue;
}
/* Otherwise, treat the ORDER BY term as an ordinary expression */
- pItem->iOrderByCol = 0;
+ pItem->u.x.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;
+ if( sqlite3ExprCompare(pE, pSelect->pEList->a[j].pExpr, -1)==0 ){
+ pItem->u.x.iOrderByCol = j+1;
}
}
}
@@ -73467,7 +85504,7 @@ static int resolveOrderGroupBy(
}
/*
-** Resolve names in the SELECT statement p and all of its descendents.
+** Resolve names in the SELECT statement p and all of its descendants.
*/
static int resolveSelectStep(Walker *pWalker, Select *p){
NameContext *pOuterNC; /* Context that contains this SELECT */
@@ -73475,7 +85512,6 @@ static int resolveSelectStep(Walker *pWalker, Select *p){
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 */
@@ -73520,22 +85556,19 @@ static int resolveSelectStep(Walker *pWalker, Select *p){
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;
- }
+
+ /* If the SF_Converted flags is set, then this Select object was
+ ** was created by the convertCompoundSelectToSubquery() function.
+ ** In this case the ORDER BY clause (p->pOrderBy) should be resolved
+ ** as if it were part of the sub-query, not the parent. This block
+ ** moves the pOrderBy down to the sub-query. It will be moved back
+ ** after the names have been resolved. */
+ if( p->selFlags & SF_Converted ){
+ Select *pSub = p->pSrc->a[0].pSelect;
+ assert( p->pSrc->nSrc==1 && p->pOrderBy );
+ assert( pSub->pPrior && pSub->pOrderBy==0 );
+ pSub->pOrderBy = p->pOrderBy;
+ p->pOrderBy = 0;
}
/* Recursively resolve names in all subqueries
@@ -73551,7 +85584,7 @@ static int resolveSelectStep(Walker *pWalker, Select *p){
** 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. */
+ ** pItem->fg.isCorrelated flag if this is the case. */
for(pNC=pOuterNC; pNC; pNC=pNC->pNext) nRef += pNC->nRef;
if( pItem->zName ) pParse->zAuthContext = pItem->zName;
@@ -73560,18 +85593,29 @@ static int resolveSelectStep(Walker *pWalker, Select *p){
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);
+ assert( pItem->fg.isCorrelated==0 && nRef<=0 );
+ pItem->fg.isCorrelated = (nRef!=0);
}
}
+ /* 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. */
+ if( sqlite3ResolveExprListNames(&sNC, p->pEList) ) return WRC_Abort;
+
/* 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;
+ assert( NC_MinMaxAgg==SF_MinMaxAgg );
+ p->selFlags |= SF_Aggregate | (sNC.ncFlags&NC_MinMaxAgg);
}else{
sNC.ncFlags &= ~NC_AllowAgg;
}
@@ -73583,7 +85627,7 @@ static int resolveSelectStep(Walker *pWalker, Select *p){
return WRC_Abort;
}
- /* Add the expression list to the name-context before parsing the
+ /* Add the output column 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.
@@ -73592,10 +85636,17 @@ static int resolveSelectStep(Walker *pWalker, Select *p){
** re-evaluated for each reference to it.
*/
sNC.pEList = p->pEList;
- if( sqlite3ResolveExprNames(&sNC, p->pWhere) ||
- sqlite3ResolveExprNames(&sNC, p->pHaving)
- ){
- return WRC_Abort;
+ if( sqlite3ResolveExprNames(&sNC, p->pHaving) ) return WRC_Abort;
+ if( sqlite3ResolveExprNames(&sNC, p->pWhere) ) return WRC_Abort;
+
+ /* Resolve names in table-valued-function arguments */
+ for(i=0; i<p->pSrc->nSrc; i++){
+ struct SrcList_item *pItem = &p->pSrc->a[i];
+ if( pItem->fg.isTabFunc
+ && sqlite3ResolveExprListNames(&sNC, pItem->u1.pFuncArg)
+ ){
+ return WRC_Abort;
+ }
}
/* The ORDER BY and GROUP BY clauses may not refer to terms in
@@ -73604,12 +85655,30 @@ static int resolveSelectStep(Walker *pWalker, Select *p){
sNC.pNext = 0;
sNC.ncFlags |= NC_AllowAgg;
+ /* If this is a converted compound query, move the ORDER BY clause from
+ ** the sub-query back to the parent query. At this point each term
+ ** within the ORDER BY clause has been transformed to an integer value.
+ ** These integers will be replaced by copies of the corresponding result
+ ** set expressions by the call to resolveOrderGroupBy() below. */
+ if( p->selFlags & SF_Converted ){
+ Select *pSub = p->pSrc->a[0].pSelect;
+ p->pOrderBy = pSub->pOrderBy;
+ pSub->pOrderBy = 0;
+ }
+
/* 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 there is an ORDER BY clause on a term of a compound-select other
+ ** than the right-most term, then that is a syntax error. But the error
+ ** is not detected until much later, and so we need to go ahead and
+ ** resolve those symbols on the incorrect ORDER BY for consistency.
*/
- if( !isCompound && resolveOrderGroupBy(&sNC, p, p->pOrderBy, "ORDER") ){
+ if( isCompound<=nCompound /* Defer right-most ORDER BY of a compound */
+ && resolveOrderGroupBy(&sNC, p, p->pOrderBy, "ORDER")
+ ){
return WRC_Abort;
}
if( db->mallocFailed ){
@@ -73634,6 +85703,13 @@ static int resolveSelectStep(Walker *pWalker, Select *p){
}
}
+ /* If this is part of a compound SELECT, check that it has the right
+ ** number of expressions in the select list. */
+ if( p->pNext && p->pEList->nExpr!=p->pNext->pEList->nExpr ){
+ sqlite3SelectWrongNumTermsError(pParse, p->pNext);
+ return WRC_Abort;
+ }
+
/* Advance to the next term of the compound
*/
p = p->pPrior;
@@ -73702,7 +85778,7 @@ SQLITE_PRIVATE int sqlite3ResolveExprNames(
NameContext *pNC, /* Namespace to resolve expressions in. */
Expr *pExpr /* The expression to be analyzed. */
){
- u8 savedHasAgg;
+ u16 savedHasAgg;
Walker w;
if( pExpr==0 ) return 0;
@@ -73715,8 +85791,9 @@ SQLITE_PRIVATE int sqlite3ResolveExprNames(
pParse->nHeight += pExpr->nHeight;
}
#endif
- savedHasAgg = pNC->ncFlags & NC_HasAgg;
- pNC->ncFlags &= ~NC_HasAgg;
+ savedHasAgg = pNC->ncFlags & (NC_HasAgg|NC_MinMaxAgg);
+ pNC->ncFlags &= ~(NC_HasAgg|NC_MinMaxAgg);
+ memset(&w, 0, sizeof(w));
w.xExprCallback = resolveExprStep;
w.xSelectCallback = resolveSelectStep;
w.pParse = pNC->pParse;
@@ -73730,12 +85807,28 @@ SQLITE_PRIVATE int sqlite3ResolveExprNames(
}
if( pNC->ncFlags & NC_HasAgg ){
ExprSetProperty(pExpr, EP_Agg);
- }else if( savedHasAgg ){
- pNC->ncFlags |= NC_HasAgg;
}
+ pNC->ncFlags |= savedHasAgg;
return ExprHasProperty(pExpr, EP_Error);
}
+/*
+** Resolve all names for all expression in an expression list. This is
+** just like sqlite3ResolveExprNames() except that it works for an expression
+** list rather than a single expression.
+*/
+SQLITE_PRIVATE int sqlite3ResolveExprListNames(
+ NameContext *pNC, /* Namespace to resolve expressions in. */
+ ExprList *pList /* The expression list to be analyzed. */
+){
+ int i;
+ if( pList ){
+ for(i=0; i<pList->nExpr; i++){
+ if( sqlite3ResolveExprNames(pNC, pList->a[i].pExpr) ) return WRC_Abort;
+ }
+ }
+ return WRC_Continue;
+}
/*
** Resolve all names in all expressions of a SELECT and in all
@@ -73757,6 +85850,7 @@ SQLITE_PRIVATE void sqlite3ResolveSelectNames(
Walker w;
assert( p!=0 );
+ memset(&w, 0, sizeof(w));
w.xExprCallback = resolveExprStep;
w.xSelectCallback = resolveSelectStep;
w.pParse = pParse;
@@ -73764,6 +85858,41 @@ SQLITE_PRIVATE void sqlite3ResolveSelectNames(
sqlite3WalkSelect(&w, p);
}
+/*
+** Resolve names in expressions that can only reference a single table:
+**
+** * CHECK constraints
+** * WHERE clauses on partial indices
+**
+** The Expr.iTable value for Expr.op==TK_COLUMN nodes of the expression
+** is set to -1 and the Expr.iColumn value is set to the column number.
+**
+** Any errors cause an error message to be set in pParse.
+*/
+SQLITE_PRIVATE void sqlite3ResolveSelfReference(
+ Parse *pParse, /* Parsing context */
+ Table *pTab, /* The table being referenced */
+ int type, /* NC_IsCheck or NC_PartIdx or NC_IdxExpr */
+ Expr *pExpr, /* Expression to resolve. May be NULL. */
+ ExprList *pList /* Expression list to resolve. May be NUL. */
+){
+ SrcList sSrc; /* Fake SrcList for pParse->pNewTable */
+ NameContext sNC; /* Name context for pParse->pNewTable */
+
+ assert( type==NC_IsCheck || type==NC_PartIdx || type==NC_IdxExpr );
+ memset(&sNC, 0, sizeof(sNC));
+ memset(&sSrc, 0, sizeof(sSrc));
+ sSrc.nSrc = 1;
+ sSrc.a[0].zName = pTab->zName;
+ sSrc.a[0].pTab = pTab;
+ sSrc.a[0].iCursor = -1;
+ sNC.pParse = pParse;
+ sNC.pSrcList = &sSrc;
+ sNC.ncFlags = type;
+ if( sqlite3ResolveExprNames(&sNC, pExpr) ) return;
+ if( pList ) sqlite3ResolveExprListNames(&sNC, pList);
+}
+
/************** End of resolve.c *********************************************/
/************** Begin file expr.c ********************************************/
/*
@@ -73780,6 +85909,7 @@ SQLITE_PRIVATE void sqlite3ResolveSelectNames(
** This file contains routines used for analyzing expressions and
** for generating VDBE code that evaluates expressions in SQLite.
*/
+/* #include "sqliteInt.h" */
/*
** Return the 'affinity' of the expression pExpr if any.
@@ -73789,7 +85919,7 @@ SQLITE_PRIVATE void sqlite3ResolveSelectNames(
** 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
+** i.e. the WHERE clause expressions in the following statements all
** have an affinity:
**
** CREATE TABLE t1(a);
@@ -73800,6 +85930,7 @@ SQLITE_PRIVATE void sqlite3ResolveSelectNames(
SQLITE_PRIVATE char sqlite3ExprAffinity(Expr *pExpr){
int op;
pExpr = sqlite3ExprSkipCollate(pExpr);
+ if( pExpr->flags & EP_Generic ) return 0;
op = pExpr->op;
if( op==TK_SELECT ){
assert( pExpr->flags&EP_xIsSelect );
@@ -73808,7 +85939,7 @@ SQLITE_PRIVATE char sqlite3ExprAffinity(Expr *pExpr){
#ifndef SQLITE_OMIT_CAST
if( op==TK_CAST ){
assert( !ExprHasProperty(pExpr, EP_IntValue) );
- return sqlite3AffinityType(pExpr->u.zToken);
+ return sqlite3AffinityType(pExpr->u.zToken, 0);
}
#endif
if( (op==TK_AGG_COLUMN || op==TK_COLUMN || op==TK_REGISTER)
@@ -73832,12 +85963,17 @@ SQLITE_PRIVATE char sqlite3ExprAffinity(Expr *pExpr){
** 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){
+SQLITE_PRIVATE Expr *sqlite3ExprAddCollateToken(
+ Parse *pParse, /* Parsing context */
+ Expr *pExpr, /* Add the "COLLATE" clause to this expression */
+ const Token *pCollName, /* Name of collating sequence */
+ int dequote /* True to dequote pCollName */
+){
if( pCollName->n>0 ){
- Expr *pNew = sqlite3ExprAlloc(pParse->db, TK_COLLATE, pCollName, 1);
+ Expr *pNew = sqlite3ExprAlloc(pParse->db, TK_COLLATE, pCollName, dequote);
if( pNew ){
pNew->pLeft = pExpr;
- pNew->flags |= EP_Collate;
+ pNew->flags |= EP_Collate|EP_Skip;
pExpr = pNew;
}
}
@@ -73848,17 +85984,25 @@ SQLITE_PRIVATE Expr *sqlite3ExprAddCollateString(Parse *pParse, Expr *pExpr, con
assert( zC!=0 );
s.z = zC;
s.n = sqlite3Strlen30(s.z);
- return sqlite3ExprAddCollateToken(pParse, pExpr, &s);
+ return sqlite3ExprAddCollateToken(pParse, pExpr, &s, 0);
}
/*
-** Skip over any TK_COLLATE and/or TK_AS operators at the root of
-** an expression.
+** Skip over any TK_COLLATE operators and any unlikely()
+** or likelihood() function 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;
- }
+ while( pExpr && ExprHasProperty(pExpr, EP_Skip) ){
+ if( ExprHasProperty(pExpr, EP_Unlikely) ){
+ assert( !ExprHasProperty(pExpr, EP_xIsSelect) );
+ assert( pExpr->x.pList->nExpr>0 );
+ assert( pExpr->op==TK_FUNCTION );
+ pExpr = pExpr->x.pList->a[0].pExpr;
+ }else{
+ assert( pExpr->op==TK_COLLATE );
+ pExpr = pExpr->pLeft;
+ }
+ }
return pExpr;
}
@@ -73877,23 +86021,18 @@ SQLITE_PRIVATE CollSeq *sqlite3ExprCollSeq(Parse *pParse, Expr *pExpr){
Expr *p = pExpr;
while( p ){
int op = p->op;
+ if( p->flags & EP_Generic ) break;
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);
- }
+ if( op==TK_COLLATE || (op==TK_REGISTER && p->op2==TK_COLLATE) ){
+ pColl = sqlite3GetCollSeq(pParse, ENC(db), 0, p->u.zToken);
break;
}
- if( p->pTab!=0
- && (op==TK_AGG_COLUMN || op==TK_COLUMN
+ if( (op==TK_AGG_COLUMN || op==TK_COLUMN
|| op==TK_REGISTER || op==TK_TRIGGER)
+ && p->pTab!=0
){
/* op==TK_REGISTER && p->pTab!=0 happens when pExpr was originally
** a TK_COLUMN but was previously evaluated and cached in a register */
@@ -73905,10 +86044,25 @@ SQLITE_PRIVATE CollSeq *sqlite3ExprCollSeq(Parse *pParse, Expr *pExpr){
break;
}
if( p->flags & EP_Collate ){
- if( ALWAYS(p->pLeft) && (p->pLeft->flags & EP_Collate)!=0 ){
+ if( p->pLeft && (p->pLeft->flags & EP_Collate)!=0 ){
p = p->pLeft;
}else{
- p = p->pRight;
+ Expr *pNext = p->pRight;
+ /* The Expr.x union is never used at the same time as Expr.pRight */
+ assert( p->x.pList==0 || p->pRight==0 );
+ /* p->flags holds EP_Collate and p->pLeft->flags does not. And
+ ** p->x.pSelect cannot. So if p->x.pLeft exists, it must hold at
+ ** least one EP_Collate. Thus the following two ALWAYS. */
+ if( p->x.pList!=0 && ALWAYS(!ExprHasProperty(p, EP_xIsSelect)) ){
+ int i;
+ for(i=0; ALWAYS(i<p->x.pList->nExpr); i++){
+ if( ExprHasProperty(p->x.pList->a[i].pExpr, EP_Collate) ){
+ pNext = p->x.pList->a[i].pExpr;
+ break;
+ }
+ }
+ }
+ p = pNext;
}
}else{
break;
@@ -73934,13 +86088,13 @@ SQLITE_PRIVATE char sqlite3CompareAffinity(Expr *pExpr, char aff2){
if( sqlite3IsNumericAffinity(aff1) || sqlite3IsNumericAffinity(aff2) ){
return SQLITE_AFF_NUMERIC;
}else{
- return SQLITE_AFF_NONE;
+ return SQLITE_AFF_BLOB;
}
}else if( !aff1 && !aff2 ){
/* Neither side of the comparison is a column. Compare the
** results directly.
*/
- return SQLITE_AFF_NONE;
+ return SQLITE_AFF_BLOB;
}else{
/* One side is a column, the other is not. Use the columns affinity. */
assert( aff1==0 || aff2==0 );
@@ -73964,7 +86118,7 @@ static char comparisonAffinity(Expr *pExpr){
}else if( ExprHasProperty(pExpr, EP_xIsSelect) ){
aff = sqlite3CompareAffinity(pExpr->x.pSelect->pEList->a[0].pExpr, aff);
}else if( !aff ){
- aff = SQLITE_AFF_NONE;
+ aff = SQLITE_AFF_BLOB;
}
return aff;
}
@@ -73978,7 +86132,7 @@ static char comparisonAffinity(Expr *pExpr){
SQLITE_PRIVATE int sqlite3IndexAffinityOk(Expr *pExpr, char idx_affinity){
char aff = comparisonAffinity(pExpr);
switch( aff ){
- case SQLITE_AFF_NONE:
+ case SQLITE_AFF_BLOB:
return 1;
case SQLITE_AFF_TEXT:
return idx_affinity==SQLITE_AFF_TEXT;
@@ -74114,6 +86268,9 @@ static void heightOfSelect(Select *p, int *pnHeight){
** 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.
+**
+** Also propagate EP_Propagate flags up from Expr.x.pList to Expr.flags,
+** if appropriate.
*/
static void exprSetHeight(Expr *p){
int nHeight = 0;
@@ -74121,8 +86278,9 @@ static void exprSetHeight(Expr *p){
heightOfExpr(p->pRight, &nHeight);
if( ExprHasProperty(p, EP_xIsSelect) ){
heightOfSelect(p->x.pSelect, &nHeight);
- }else{
+ }else if( p->x.pList ){
heightOfExprList(p->x.pList, &nHeight);
+ p->flags |= EP_Propagate & sqlite3ExprListFlags(p->x.pList);
}
p->nHeight = nHeight + 1;
}
@@ -74131,8 +86289,12 @@ static void exprSetHeight(Expr *p){
** 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.
+**
+** Also propagate all EP_Propagate flags from the Expr.x.pList into
+** Expr.flags.
*/
-SQLITE_PRIVATE void sqlite3ExprSetHeight(Parse *pParse, Expr *p){
+SQLITE_PRIVATE void sqlite3ExprSetHeightAndFlags(Parse *pParse, Expr *p){
+ if( pParse->nErr ) return;
exprSetHeight(p);
sqlite3ExprCheckHeight(pParse, p->nHeight);
}
@@ -74146,8 +86308,17 @@ SQLITE_PRIVATE int sqlite3SelectExprHeight(Select *p){
heightOfSelect(p, &nHeight);
return nHeight;
}
-#else
- #define exprSetHeight(y)
+#else /* ABOVE: Height enforcement enabled. BELOW: Height enforcement off */
+/*
+** Propagate all EP_Propagate flags from the Expr.x.pList into
+** Expr.flags.
+*/
+SQLITE_PRIVATE void sqlite3ExprSetHeightAndFlags(Parse *pParse, Expr *p){
+ if( p && p->x.pList && !ExprHasProperty(p, EP_xIsSelect) ){
+ p->flags |= EP_Propagate & sqlite3ExprListFlags(p->x.pList);
+ }
+}
+#define exprSetHeight(y)
#endif /* SQLITE_MAX_EXPR_DEPTH>0 */
/*
@@ -74159,7 +86330,7 @@ SQLITE_PRIVATE int sqlite3SelectExprHeight(Select *p){
** 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
+** If dequote is false, no dequoting is performed. 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.
@@ -74249,18 +86420,18 @@ SQLITE_PRIVATE void sqlite3ExprAttachSubtrees(
}else{
if( pRight ){
pRoot->pRight = pRight;
- pRoot->flags |= EP_Collate & pRight->flags;
+ pRoot->flags |= EP_Propagate & pRight->flags;
}
if( pLeft ){
pRoot->pLeft = pLeft;
- pRoot->flags |= EP_Collate & pLeft->flags;
+ pRoot->flags |= EP_Propagate & pLeft->flags;
}
exprSetHeight(pRoot);
}
}
/*
-** Allocate a Expr node which joins as many as two subtrees.
+** Allocate an 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,
@@ -74274,11 +86445,11 @@ SQLITE_PRIVATE Expr *sqlite3PExpr(
const Token *pToken /* Argument token */
){
Expr *p;
- if( op==TK_AND && pLeft && pRight ){
+ if( op==TK_AND && pParse->nErr==0 ){
/* Take advantage of short-circuit false optimization for AND */
p = sqlite3ExprAnd(pParse->db, pLeft, pRight);
}else{
- p = sqlite3ExprAlloc(pParse->db, op, pToken, 1);
+ p = sqlite3ExprAlloc(pParse->db, op & TKFLG_MASK, pToken, 1);
sqlite3ExprAttachSubtrees(pParse->db, p, pLeft, pRight);
}
if( p ) {
@@ -74288,16 +86459,25 @@ SQLITE_PRIVATE Expr *sqlite3PExpr(
}
/*
-** 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.)
+** If the expression is always either TRUE or FALSE (respectively),
+** then return 1. If one cannot determine the truth value of the
+** expression at compile-time return 0.
+**
+** This is an optimization. If is OK to return 0 here even if
+** the expression really is always false or false (a false negative).
+** But it is a bug to return 1 if the expression might have different
+** boolean values in different 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 exprAlwaysTrue(Expr *p){
+ int v = 0;
+ if( ExprHasProperty(p, EP_FromJoin) ) return 0;
+ if( !sqlite3ExprIsInteger(p, &v) ) return 0;
+ return v!=0;
+}
static int exprAlwaysFalse(Expr *p){
int v = 0;
if( ExprHasProperty(p, EP_FromJoin) ) return 0;
@@ -74344,7 +86524,7 @@ SQLITE_PRIVATE Expr *sqlite3ExprFunction(Parse *pParse, ExprList *pList, Token *
}
pNew->x.pList = pList;
assert( !ExprHasProperty(pNew, EP_xIsSelect) );
- sqlite3ExprSetHeight(pParse, pNew);
+ sqlite3ExprSetHeightAndFlags(pParse, pNew);
return pNew;
}
@@ -74361,7 +86541,7 @@ SQLITE_PRIVATE Expr *sqlite3ExprFunction(Parse *pParse, ExprList *pList, Token *
**
** 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
+** instance of the wildcard, the next sequential variable number is
** assigned.
*/
SQLITE_PRIVATE void sqlite3ExprAssignVarNumber(Parse *pParse, Expr *pExpr){
@@ -74369,7 +86549,7 @@ SQLITE_PRIVATE void sqlite3ExprAssignVarNumber(Parse *pParse, Expr *pExpr){
const char *z;
if( pExpr==0 ) return;
- assert( !ExprHasAnyProperty(pExpr, EP_IntValue|EP_Reduced|EP_TokenOnly) );
+ assert( !ExprHasProperty(pExpr, EP_IntValue|EP_Reduced|EP_TokenOnly) );
z = pExpr->u.zToken;
assert( z!=0 );
assert( z[0]!=0 );
@@ -74405,7 +86585,7 @@ SQLITE_PRIVATE void sqlite3ExprAssignVarNumber(Parse *pParse, Expr *pExpr){
*/
ynVar i;
for(i=0; i<pParse->nzVar; i++){
- if( pParse->azVar[i] && memcmp(pParse->azVar[i],z,n+1)==0 ){
+ if( pParse->azVar[i] && strcmp(pParse->azVar[i],z)==0 ){
pExpr->iColumn = x = (ynVar)i+1;
break;
}
@@ -74439,12 +86619,12 @@ 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) ){
+ if( !ExprHasProperty(p, EP_TokenOnly) ){
+ /* The Expr.x union is never used at the same time as Expr.pRight */
+ assert( p->x.pList==0 || p->pRight==0 );
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_MemToken) ) sqlite3DbFree(db, p->u.zToken);
if( ExprHasProperty(p, EP_xIsSelect) ){
sqlite3SelectDelete(db, p->x.pSelect);
}else{
@@ -74496,7 +86676,7 @@ static int exprStructSize(Expr *p){
** 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
+** make an 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.
@@ -74504,16 +86684,19 @@ static int exprStructSize(Expr *p){
static int dupedExprStructSize(Expr *p, int flags){
int nSize;
assert( flags==EXPRDUP_REDUCE || flags==0 ); /* Only one flag value allowed */
+ assert( EXPR_FULLSIZE<=0xfff );
+ assert( (0xfff & (EP_Reduced|EP_TokenOnly))==0 );
if( 0==(flags&EXPRDUP_REDUCE) ){
nSize = EXPR_FULLSIZE;
}else{
- assert( !ExprHasAnyProperty(p, EP_TokenOnly|EP_Reduced) );
+ assert( !ExprHasProperty(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 ){
+ assert( !ExprHasProperty(p, EP_MemToken) );
+ assert( !ExprHasProperty(p, EP_NoReduce) );
+ if( p->pLeft || p->x.pList ){
nSize = EXPR_REDUCEDSIZE | EP_Reduced;
}else{
+ assert( p->pRight==0 );
nSize = EXPR_TOKENONLYSIZE | EP_TokenOnly;
}
}
@@ -74562,11 +86745,12 @@ static int dupedExprSize(Expr *p, int flags){
** 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
+** if any. Before returning, *pzBuffer is set to the first byte past 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 */
+ assert( flags==0 || flags==EXPRDUP_REDUCE );
if( p ){
const int isReduced = (flags&EXPRDUP_REDUCE);
u8 *zAlloc;
@@ -74601,13 +86785,15 @@ static Expr *exprDup(sqlite3 *db, Expr *p, int flags, u8 **pzBuffer){
assert( ExprHasProperty(p, EP_Reduced)==0 );
memcpy(zAlloc, p, nNewSize);
}else{
- int nSize = exprStructSize(p);
+ u32 nSize = (u32)exprStructSize(p);
memcpy(zAlloc, p, nSize);
- memset(&zAlloc[nSize], 0, EXPR_FULLSIZE-nSize);
+ if( nSize<EXPR_FULLSIZE ){
+ 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 &= ~(EP_Reduced|EP_TokenOnly|EP_Static|EP_MemToken);
pNew->flags |= nStructSize & (EP_Reduced|EP_TokenOnly);
pNew->flags |= staticFlag;
@@ -74627,7 +86813,7 @@ static Expr *exprDup(sqlite3 *db, Expr *p, int flags, u8 **pzBuffer){
}
/* Fill in pNew->pLeft and pNew->pRight. */
- if( ExprHasAnyProperty(pNew, EP_Reduced|EP_TokenOnly) ){
+ if( ExprHasProperty(pNew, EP_Reduced|EP_TokenOnly) ){
zAlloc += dupedExprNodeSize(p, flags);
if( ExprHasProperty(pNew, EP_Reduced) ){
pNew->pLeft = exprDup(db, p->pLeft, EXPRDUP_REDUCE, &zAlloc);
@@ -74637,8 +86823,7 @@ static Expr *exprDup(sqlite3 *db, Expr *p, int flags, u8 **pzBuffer){
*pzBuffer = zAlloc;
}
}else{
- pNew->flags2 = 0;
- if( !ExprHasAnyProperty(p, EP_TokenOnly) ){
+ if( !ExprHasProperty(p, EP_TokenOnly) ){
pNew->pLeft = sqlite3ExprDup(db, p->pLeft, 0);
pNew->pRight = sqlite3ExprDup(db, p->pRight, 0);
}
@@ -74650,6 +86835,33 @@ static Expr *exprDup(sqlite3 *db, Expr *p, int flags, u8 **pzBuffer){
}
/*
+** Create and return a deep copy of the object passed as the second
+** argument. If an OOM condition is encountered, NULL is returned
+** and the db->mallocFailed flag set.
+*/
+#ifndef SQLITE_OMIT_CTE
+static With *withDup(sqlite3 *db, With *p){
+ With *pRet = 0;
+ if( p ){
+ int nByte = sizeof(*p) + sizeof(p->a[0]) * (p->nCte-1);
+ pRet = sqlite3DbMallocZero(db, nByte);
+ if( pRet ){
+ int i;
+ pRet->nCte = p->nCte;
+ for(i=0; i<p->nCte; i++){
+ pRet->a[i].pSelect = sqlite3SelectDup(db, p->a[i].pSelect, 0);
+ pRet->a[i].pCols = sqlite3ExprListDup(db, p->a[i].pCols, 0);
+ pRet->a[i].zName = sqlite3DbStrDup(db, p->a[i].zName);
+ }
+ }
+ }
+ return pRet;
+}
+#else
+# define withDup(x,y) 0
+#endif
+
+/*
** 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)
@@ -74667,6 +86879,7 @@ static Expr *exprDup(sqlite3 *db, Expr *p, int flags, u8 **pzBuffer){
** part of the in-memory representation of the database schema.
*/
SQLITE_PRIVATE Expr *sqlite3ExprDup(sqlite3 *db, Expr *p, int flags){
+ assert( flags==0 || flags==EXPRDUP_REDUCE );
return exprDup(db, p, flags, 0);
}
SQLITE_PRIVATE ExprList *sqlite3ExprListDup(sqlite3 *db, ExprList *p, int flags){
@@ -74676,7 +86889,6 @@ SQLITE_PRIVATE ExprList *sqlite3ExprListDup(sqlite3 *db, ExprList *p, int flags)
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]) );
@@ -74692,8 +86904,8 @@ SQLITE_PRIVATE ExprList *sqlite3ExprListDup(sqlite3 *db, ExprList *p, int flags)
pItem->zSpan = sqlite3DbStrDup(db, pOldItem->zSpan);
pItem->sortOrder = pOldItem->sortOrder;
pItem->done = 0;
- pItem->iOrderByCol = pOldItem->iOrderByCol;
- pItem->iAlias = pOldItem->iAlias;
+ pItem->bSpanIsTab = pOldItem->bSpanIsTab;
+ pItem->u = pOldItem->u;
}
return pNew;
}
@@ -74723,15 +86935,18 @@ SQLITE_PRIVATE SrcList *sqlite3SrcListDup(sqlite3 *db, SrcList *p, int flags){
pNewItem->zDatabase = sqlite3DbStrDup(db, pOldItem->zDatabase);
pNewItem->zName = sqlite3DbStrDup(db, pOldItem->zName);
pNewItem->zAlias = sqlite3DbStrDup(db, pOldItem->zAlias);
- pNewItem->jointype = pOldItem->jointype;
+ pNewItem->fg = pOldItem->fg;
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;
+ if( pNewItem->fg.isIndexedBy ){
+ pNewItem->u1.zIndexedBy = sqlite3DbStrDup(db, pOldItem->u1.zIndexedBy);
+ }
+ pNewItem->pIBIndex = pOldItem->pIBIndex;
+ if( pNewItem->fg.isTabFunc ){
+ pNewItem->u1.pFuncArg =
+ sqlite3ExprListDup(db, pOldItem->u1.pFuncArg, flags);
+ }
pTab = pNewItem->pTab = pOldItem->pTab;
if( pTab ){
pTab->nRef++;
@@ -74786,10 +87001,11 @@ SQLITE_PRIVATE Select *sqlite3SelectDup(sqlite3 *db, Select *p, int 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;
+ pNew->nSelectRow = p->nSelectRow;
+ pNew->pWith = withDup(db, p->pWith);
+ sqlite3SelectSetName(pNew, p->zSelName);
return pNew;
}
#else
@@ -74846,6 +87062,20 @@ no_mem:
}
/*
+** Set the sort order for the last element on the given ExprList.
+*/
+SQLITE_PRIVATE void sqlite3ExprListSetSortOrder(ExprList *p, int iSortOrder){
+ if( p==0 ) return;
+ assert( SQLITE_SO_UNDEFINED<0 && SQLITE_SO_ASC>=0 && SQLITE_SO_DESC>0 );
+ assert( p->nExpr>0 );
+ if( iSortOrder<0 ){
+ assert( p->a[p->nExpr-1].sortOrder==SQLITE_SO_ASC );
+ return;
+ }
+ p->a[p->nExpr-1].sortOrder = (u8)iSortOrder;
+}
+
+/*
** Set the ExprList.a[].zName element of the most recently added item
** on the expression list.
**
@@ -74930,34 +87160,67 @@ SQLITE_PRIVATE void sqlite3ExprListDelete(sqlite3 *db, ExprList *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.
+** Return the bitwise-OR of all Expr.flags fields in the given
+** ExprList.
+*/
+SQLITE_PRIVATE u32 sqlite3ExprListFlags(const ExprList *pList){
+ int i;
+ u32 m = 0;
+ if( pList ){
+ for(i=0; i<pList->nExpr; i++){
+ Expr *pExpr = pList->a[i].pExpr;
+ if( ALWAYS(pExpr) ) m |= pExpr->flags;
+ }
+ }
+ return m;
+}
+
+/*
+** These routines are Walker callbacks used to check expressions to
+** see if they are "constant" for some definition of constant. The
+** Walker.eCode value determines the type of "constant" we are looking
+** for.
**
** These callback routines are used to implement the following:
**
-** sqlite3ExprIsConstant()
-** sqlite3ExprIsConstantNotJoin()
-** sqlite3ExprIsConstantOrFunction()
+** sqlite3ExprIsConstant() pWalker->eCode==1
+** sqlite3ExprIsConstantNotJoin() pWalker->eCode==2
+** sqlite3ExprIsTableConstant() pWalker->eCode==3
+** sqlite3ExprIsConstantOrFunction() pWalker->eCode==4 or 5
+**
+** In all cases, the callbacks set Walker.eCode=0 and abort if the expression
+** is found to not be a constant.
**
+** The sqlite3ExprIsConstantOrFunction() is used for evaluating expressions
+** in a CREATE TABLE statement. The Walker.eCode value is 5 when parsing
+** an existing schema and 4 when processing a new statement. A bound
+** parameter raises an error for new statements, but is silently converted
+** to NULL for existing schemas. This allows sqlite_master tables that
+** contain a bound parameter because they were generated by older versions
+** of SQLite to be parsed by newer versions of SQLite without raising a
+** malformed schema error.
*/
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
+ /* If pWalker->eCode is 2 then any term of the expression that comes from
+ ** the ON or USING clauses of a left join disqualifies the expression
** from being considered constant. */
- if( pWalker->u.i==3 && ExprHasAnyProperty(pExpr, EP_FromJoin) ){
- pWalker->u.i = 0;
+ if( pWalker->eCode==2 && ExprHasProperty(pExpr, EP_FromJoin) ){
+ pWalker->eCode = 0;
return WRC_Abort;
}
switch( pExpr->op ){
/* Consider functions to be constant if all their arguments are constant
- ** and pWalker->u.i==2 */
+ ** and either pWalker->eCode==4 or 5 or the function has the
+ ** SQLITE_FUNC_CONST flag. */
case TK_FUNCTION:
- if( pWalker->u.i==2 ) return 0;
- /* Fall through */
+ if( pWalker->eCode>=4 || ExprHasProperty(pExpr,EP_ConstFunc) ){
+ return WRC_Continue;
+ }else{
+ pWalker->eCode = 0;
+ return WRC_Abort;
+ }
case TK_ID:
case TK_COLUMN:
case TK_AGG_FUNCTION:
@@ -74966,8 +87229,25 @@ static int exprNodeIsConstant(Walker *pWalker, Expr *pExpr){
testcase( pExpr->op==TK_COLUMN );
testcase( pExpr->op==TK_AGG_FUNCTION );
testcase( pExpr->op==TK_AGG_COLUMN );
- pWalker->u.i = 0;
- return WRC_Abort;
+ if( pWalker->eCode==3 && pExpr->iTable==pWalker->u.iCur ){
+ return WRC_Continue;
+ }else{
+ pWalker->eCode = 0;
+ return WRC_Abort;
+ }
+ case TK_VARIABLE:
+ if( pWalker->eCode==5 ){
+ /* Silently convert bound parameters that appear inside of CREATE
+ ** statements into a NULL when parsing the CREATE statement text out
+ ** of the sqlite_master table */
+ pExpr->op = TK_NULL;
+ }else if( pWalker->eCode==4 ){
+ /* A bound parameter in a CREATE statement that originates from
+ ** sqlite3_prepare() causes an error */
+ pWalker->eCode = 0;
+ return WRC_Abort;
+ }
+ /* Fall through */
default:
testcase( pExpr->op==TK_SELECT ); /* selectNodeIsConstant will disallow */
testcase( pExpr->op==TK_EXISTS ); /* selectNodeIsConstant will disallow */
@@ -74976,20 +87256,22 @@ static int exprNodeIsConstant(Walker *pWalker, Expr *pExpr){
}
static int selectNodeIsConstant(Walker *pWalker, Select *NotUsed){
UNUSED_PARAMETER(NotUsed);
- pWalker->u.i = 0;
+ pWalker->eCode = 0;
return WRC_Abort;
}
-static int exprIsConst(Expr *p, int initFlag){
+static int exprIsConst(Expr *p, int initFlag, int iCur){
Walker w;
- w.u.i = initFlag;
+ memset(&w, 0, sizeof(w));
+ w.eCode = initFlag;
w.xExprCallback = exprNodeIsConstant;
w.xSelectCallback = selectNodeIsConstant;
+ w.u.iCur = iCur;
sqlite3WalkExpr(&w, p);
- return w.u.i;
+ return w.eCode;
}
/*
-** Walk an expression tree. Return 1 if the expression is constant
+** Walk an expression tree. Return non-zero 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")
@@ -74997,21 +87279,31 @@ static int exprIsConst(Expr *p, int initFlag){
** a constant.
*/
SQLITE_PRIVATE int sqlite3ExprIsConstant(Expr *p){
- return exprIsConst(p, 1);
+ return exprIsConst(p, 1, 0);
}
/*
-** Walk an expression tree. Return 1 if the expression is constant
+** Walk an expression tree. Return non-zero 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);
+ return exprIsConst(p, 2, 0);
+}
+
+/*
+** Walk an expression tree. Return non-zero if the expression is constant
+** for any single row of the table with cursor iCur. In other words, the
+** expression must not refer to any non-deterministic function nor any
+** table other than iCur.
+*/
+SQLITE_PRIVATE int sqlite3ExprIsTableConstant(Expr *p, int iCur){
+ return exprIsConst(p, 3, iCur);
}
/*
-** Walk an expression tree. Return 1 if the expression is constant
+** Walk an expression tree. Return non-zero if the expression is constant
** or a function call with constant arguments. Return and 0 if there
** are any variables.
**
@@ -75019,9 +87311,26 @@ SQLITE_PRIVATE int sqlite3ExprIsConstantNotJoin(Expr *p){
** is considered a variable but a single-quoted string (ex: 'abc') is
** a constant.
*/
-SQLITE_PRIVATE int sqlite3ExprIsConstantOrFunction(Expr *p){
- return exprIsConst(p, 2);
+SQLITE_PRIVATE int sqlite3ExprIsConstantOrFunction(Expr *p, u8 isInit){
+ assert( isInit==0 || isInit==1 );
+ return exprIsConst(p, 4+isInit, 0);
+}
+
+#ifdef SQLITE_ENABLE_CURSOR_HINTS
+/*
+** Walk an expression tree. Return 1 if the expression contains a
+** subquery of some kind. Return 0 if there are no subqueries.
+*/
+SQLITE_PRIVATE int sqlite3ExprContainsSubquery(Expr *p){
+ Walker w;
+ memset(&w, 0, sizeof(w));
+ w.eCode = 1;
+ w.xExprCallback = sqlite3ExprWalkNoop;
+ w.xSelectCallback = selectNodeIsConstant;
+ sqlite3WalkExpr(&w, p);
+ return w.eCode==0;
}
+#endif
/*
** If the expression p codes a constant integer that is small enough
@@ -75049,6 +87358,7 @@ SQLITE_PRIVATE int sqlite3ExprIsInteger(Expr *p, int *pValue){
case TK_UMINUS: {
int v;
if( sqlite3ExprIsInteger(p->pLeft, &v) ){
+ assert( v!=(-2147483647-1) );
*pValue = -v;
rc = 1;
}
@@ -75084,30 +87394,16 @@ SQLITE_PRIVATE int sqlite3ExprCanBeNull(const Expr *p){
case TK_FLOAT:
case TK_BLOB:
return 0;
+ case TK_COLUMN:
+ assert( p->pTab!=0 );
+ return ExprHasProperty(p, EP_CanBeNull) ||
+ (p->iColumn>=0 && p->pTab->aCol[p->iColumn].notNull==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.
@@ -75119,7 +87415,7 @@ SQLITE_PRIVATE void sqlite3ExprCodeIsNullJump(
*/
SQLITE_PRIVATE int sqlite3ExprNeedsNoAffinityChange(const Expr *p, char aff){
u8 op;
- if( aff==SQLITE_AFF_NONE ) return 1;
+ if( aff==SQLITE_AFF_BLOB ) return 1;
while( p->op==TK_UPLUS || p->op==TK_UMINUS ){ p = p->pLeft; }
op = p->op;
if( op==TK_REGISTER ) op = p->op2;
@@ -75210,6 +87506,40 @@ SQLITE_PRIVATE int sqlite3CodeOnce(Parse *pParse){
}
/*
+** Generate code that checks the left-most column of index table iCur to see if
+** it contains any NULL entries. Cause the register at regHasNull to be set
+** to a non-NULL value if iCur contains no NULLs. Cause register regHasNull
+** to be set to NULL if iCur contains one or more NULL values.
+*/
+static void sqlite3SetHasNullFlag(Vdbe *v, int iCur, int regHasNull){
+ int addr1;
+ sqlite3VdbeAddOp2(v, OP_Integer, 0, regHasNull);
+ addr1 = sqlite3VdbeAddOp1(v, OP_Rewind, iCur); VdbeCoverage(v);
+ sqlite3VdbeAddOp3(v, OP_Column, iCur, 0, regHasNull);
+ sqlite3VdbeChangeP5(v, OPFLAG_TYPEOFARG);
+ VdbeComment((v, "first_entry_in(%d)", iCur));
+ sqlite3VdbeJumpHere(v, addr1);
+}
+
+
+#ifndef SQLITE_OMIT_SUBQUERY
+/*
+** The argument is an IN operator with a list (not a subquery) on the
+** right-hand side. Return TRUE if that list is constant.
+*/
+static int sqlite3InRhsIsConstant(Expr *pIn){
+ Expr *pLHS;
+ int res;
+ assert( !ExprHasProperty(pIn, EP_xIsSelect) );
+ pLHS = pIn->pLeft;
+ pIn->pLeft = 0;
+ res = sqlite3ExprIsConstant(pIn);
+ pIn->pLeft = pLHS;
+ return res;
+}
+#endif
+
+/*
** 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.
@@ -75218,15 +87548,18 @@ SQLITE_PRIVATE int sqlite3CodeOnce(Parse *pParse){
** 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
+** A cursor is opened on the b-tree object that is 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.
+** IN_INDEX_ROWID - The cursor was opened on a database table.
+** IN_INDEX_INDEX_ASC - The cursor was opened on an ascending index.
+** IN_INDEX_INDEX_DESC - The cursor was opened on a descending index.
+** IN_INDEX_EPH - The cursor was opened on a specially created and
+** populated epheremal table.
+** IN_INDEX_NOOP - No cursor was allocated. The IN operator must be
+** implemented as a sequence of comparisons.
**
** An existing b-tree might be used if the RHS expression pX is a simple
** subquery such as:
@@ -75235,64 +87568,69 @@ SQLITE_PRIVATE int sqlite3CodeOnce(Parse *pParse){
**
** 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
+** pX->iTable made to point to the ephemeral table instead of an
+** existing table.
+**
+** The inFlags parameter must contain exactly one of the bits
+** IN_INDEX_MEMBERSHIP or IN_INDEX_LOOP. If inFlags contains
+** IN_INDEX_MEMBERSHIP, then the generated table will be used for a
+** fast membership test. When the IN_INDEX_LOOP bit is set, the
+** IN index will be used to loop over all values of the RHS of the
+** IN operator.
+**
+** When IN_INDEX_LOOP is used (and the b-tree will be used to iterate
+** through the set members) then the b-tree must not contain duplicates.
+** 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
+** When IN_INDEX_MEMBERSHIP is used (and the b-tree will be used
+** for fast set membership tests) then 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.
**
+** If the IN_INDEX_NOOP_OK and IN_INDEX_MEMBERSHIP are both set and
+** if the RHS of the IN operator is a list (not a subquery) then this
+** routine might decide that creating an ephemeral b-tree for membership
+** testing is too expensive and return IN_INDEX_NOOP. In that case, the
+** calling routine should implement the IN operator using a sequence
+** of Eq or Ne comparison operations.
+**
** 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
+** might need to know whether or not the RHS side of the IN operator
+** contains a NULL. If prRhsHasNull is not a NULL pointer and
+** 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
-** }
+** to *prRhsHasNull. If there is no chance that the (...) contains a
+** NULL value, then *prRhsHasNull is left unchanged.
**
-** in order to avoid running the <test if data structure contains null>
-** test more often than is necessary.
+** If a register is allocated and its location stored in *prRhsHasNull, then
+** the value in that register will be NULL if the b-tree contains one or more
+** NULL values, and it will be some non-NULL value if the b-tree contains no
+** NULL values.
*/
#ifndef SQLITE_OMIT_SUBQUERY
-SQLITE_PRIVATE int sqlite3FindInIndex(Parse *pParse, Expr *pX, int *prNotFound){
+SQLITE_PRIVATE int sqlite3FindInIndex(Parse *pParse, Expr *pX, u32 inFlags, int *prRhsHasNull){
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 */
+ int mustBeUnique; /* True if RHS must be unique */
Vdbe *v = sqlite3GetVdbe(pParse); /* Virtual machine being coded */
assert( pX->op==TK_IN );
+ mustBeUnique = (inFlags & IN_INDEX_LOOP)!=0;
/* 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) ){
+ if( 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 */
+ i16 iCol; /* Index of column <column> */
+ i16 iDb; /* Database idx for pTab */
assert( p ); /* Because of isCandidateForInOpt(p) */
assert( p->pEList!=0 ); /* Because of isCandidateForInOpt(p) */
@@ -75300,9 +87638,9 @@ SQLITE_PRIVATE int sqlite3FindInIndex(Parse *pParse, Expr *pX, int *prNotFound){
assert( p->pSrc!=0 ); /* Because of isCandidateForInOpt(p) */
pTab = p->pSrc->a[0].pTab;
pExpr = p->pEList->a[0].pExpr;
- iCol = pExpr->iColumn;
+ iCol = (i16)pExpr->iColumn;
- /* Code an OP_VerifyCookie and OP_TableLock for <table>. */
+ /* Code an OP_Transaction and OP_TableLock for <table>. */
iDb = sqlite3SchemaToIndex(db, pTab->pSchema);
sqlite3CodeVerifySchema(pParse, iDb);
sqlite3TableLock(pParse, iDb, pTab->tnum, 0, pTab->zName);
@@ -75313,9 +87651,8 @@ SQLITE_PRIVATE int sqlite3FindInIndex(Parse *pParse, Expr *pX, int *prNotFound){
*/
assert(v);
if( iCol<0 ){
- int iAddr;
-
- iAddr = sqlite3CodeOnce(pParse);
+ int iAddr = sqlite3CodeOnce(pParse);
+ VdbeCoverage(v);
sqlite3OpenTable(pParse, iTab, iDb, pTab, OP_OpenRead);
eType = IN_INDEX_ROWID;
@@ -75338,45 +87675,55 @@ SQLITE_PRIVATE int sqlite3FindInIndex(Parse *pParse, Expr *pX, int *prNotFound){
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))
+ && (!mustBeUnique || (pIdx->nKeyCol==1 && IsUniqueIndex(pIdx)))
){
- int iAddr;
- char *pKey;
-
- pKey = (char *)sqlite3IndexKeyinfo(pParse, pIdx);
- iAddr = sqlite3CodeOnce(pParse);
-
- sqlite3VdbeAddOp4(v, OP_OpenRead, iTab, pIdx->tnum, iDb,
- pKey,P4_KEYINFO_HANDOFF);
+ int iAddr = sqlite3CodeOnce(pParse); VdbeCoverage(v);
+ sqlite3VdbeAddOp3(v, OP_OpenRead, iTab, pIdx->tnum, iDb);
+ sqlite3VdbeSetP4KeyInfo(pParse, pIdx);
VdbeComment((v, "%s", pIdx->zName));
- eType = IN_INDEX_INDEX;
+ assert( IN_INDEX_INDEX_DESC == IN_INDEX_INDEX_ASC+1 );
+ eType = IN_INDEX_INDEX_ASC + pIdx->aSortOrder[0];
- sqlite3VdbeJumpHere(v, iAddr);
- if( prNotFound && !pTab->aCol[iCol].notNull ){
- *prNotFound = ++pParse->nMem;
- sqlite3VdbeAddOp2(v, OP_Null, 0, *prNotFound);
+ if( prRhsHasNull && !pTab->aCol[iCol].notNull ){
+ *prRhsHasNull = ++pParse->nMem;
+ sqlite3SetHasNullFlag(v, iTab, *prRhsHasNull);
}
+ sqlite3VdbeJumpHere(v, iAddr);
}
}
}
}
+ /* If no preexisting index is available for the IN clause
+ ** and IN_INDEX_NOOP is an allowed reply
+ ** and the RHS of the IN operator is a list, not a subquery
+ ** and the RHS is not contant or has two or fewer terms,
+ ** then it is not worth creating an ephemeral table to evaluate
+ ** the IN operator so return IN_INDEX_NOOP.
+ */
+ if( eType==0
+ && (inFlags & IN_INDEX_NOOP_OK)
+ && !ExprHasProperty(pX, EP_xIsSelect)
+ && (!sqlite3InRhsIsConstant(pX) || pX->x.pList->nExpr<=2)
+ ){
+ eType = IN_INDEX_NOOP;
+ }
+
+
if( eType==0 ){
- /* Could not found an existing table or index to use as the RHS b-tree.
+ /* Could not find 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;
+ u32 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) ){
+ if( inFlags & IN_INDEX_LOOP ){
+ pParse->nQueryLoop = 0;
+ if( pX->pLeft->iColumn<0 && !ExprHasProperty(pX, EP_xIsSelect) ){
eType = IN_INDEX_ROWID;
}
+ }else if( prRhsHasNull ){
+ *prRhsHasNull = rMayHaveNull = ++pParse->nMem;
}
sqlite3CodeSubselect(pParse, pX, rMayHaveNull, eType==IN_INDEX_ROWID);
pParse->nQueryLoop = savedNQueryLoop;
@@ -75407,15 +87754,9 @@ SQLITE_PRIVATE int sqlite3FindInIndex(Parse *pParse, Expr *pX, int *prNotFound){
**
** 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.
+** 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.
**
** 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.
@@ -75424,10 +87765,10 @@ SQLITE_PRIVATE int sqlite3FindInIndex(Parse *pParse, Expr *pX, int *prNotFound){
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 rHasNullFlag, /* 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 jmpIfDynamic = -1; /* One-time test address */
int rReg = 0; /* Register storing resulting */
Vdbe *v = sqlite3GetVdbe(pParse);
if( NEVER(v==0) ) return 0;
@@ -75443,15 +87784,16 @@ SQLITE_PRIVATE int sqlite3CodeSubselect(
** 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);
+ if( !ExprHasProperty(pExpr, EP_VarSelect) ){
+ jmpIfDynamic = sqlite3CodeOnce(pParse); VdbeCoverage(v);
}
#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
+ char *zMsg = sqlite3MPrintf(pParse->db, "EXECUTE %s%s SUBQUERY %d",
+ jmpIfDynamic>=0?"":"CORRELATED ",
+ pExpr->op==TK_IN?"LIST":"SCALAR",
+ pParse->iNextSelectId
);
sqlite3VdbeAddOp4(v, OP_Explain, pParse->iSelectId, 0, 0, zMsg, P4_DYNAMIC);
}
@@ -75460,14 +87802,9 @@ SQLITE_PRIVATE int sqlite3CodeSubselect(
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);
- }
+ KeyInfo *pKeyInfo = 0; /* Key information */
affinity = sqlite3ExprAffinity(pLeft);
@@ -75486,10 +87823,7 @@ SQLITE_PRIVATE int sqlite3CodeSubselect(
*/
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;
+ pKeyInfo = isRowid ? 0 : sqlite3KeyInfoAlloc(pParse->db, 1, 1);
if( ExprHasProperty(pExpr, EP_xIsSelect) ){
/* Case 1: expr IN (SELECT ...)
@@ -75497,6 +87831,7 @@ SQLITE_PRIVATE int sqlite3CodeSubselect(
** Generate code to write the results of the select into the temporary
** table allocated and opened above.
*/
+ Select *pSelect = pExpr->x.pSelect;
SelectDest dest;
ExprList *pEList;
@@ -75504,15 +87839,20 @@ SQLITE_PRIVATE int sqlite3CodeSubselect(
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) ){
+ pSelect->iLimit = 0;
+ testcase( pSelect->selFlags & SF_Distinct );
+ testcase( pKeyInfo==0 ); /* Caused by OOM in sqlite3KeyInfoAlloc() */
+ if( sqlite3Select(pParse, pSelect, &dest) ){
+ sqlite3KeyInfoUnref(pKeyInfo);
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);
- }
+ pEList = pSelect->pEList;
+ assert( pKeyInfo!=0 ); /* OOM will cause exit after sqlite3Select() */
+ assert( pEList!=0 );
+ assert( pEList->nExpr>0 );
+ assert( sqlite3KeyInfoIsWriteable(pKeyInfo) );
+ pKeyInfo->aColl[0] = sqlite3BinaryCompareCollSeq(pParse, pExpr->pLeft,
+ pEList->a[0].pExpr);
}else if( ALWAYS(pExpr->x.pList!=0) ){
/* Case 2: expr IN (exprlist)
**
@@ -75527,15 +87867,17 @@ SQLITE_PRIVATE int sqlite3CodeSubselect(
int r1, r2, r3;
if( !affinity ){
- affinity = SQLITE_AFF_NONE;
+ affinity = SQLITE_AFF_BLOB;
+ }
+ if( pKeyInfo ){
+ assert( sqlite3KeyInfoIsWriteable(pKeyInfo) );
+ pKeyInfo->aColl[0] = sqlite3ExprCollSeq(pParse, pExpr->pLeft);
}
- 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);
+ if( isRowid ) sqlite3VdbeAddOp2(v, OP_Null, 0, r2);
for(i=pList->nExpr, pItem=pList->a; i>0; i--, pItem++){
Expr *pE2 = pItem->pExpr;
int iValToIns;
@@ -75545,9 +87887,9 @@ SQLITE_PRIVATE int sqlite3CodeSubselect(
** 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;
+ if( jmpIfDynamic>=0 && !sqlite3ExprIsConstant(pE2) ){
+ sqlite3VdbeChangeToNoop(v, jmpIfDynamic);
+ jmpIfDynamic = -1;
}
/* Evaluate the expression and insert it into the temp table */
@@ -75558,6 +87900,7 @@ SQLITE_PRIVATE int sqlite3CodeSubselect(
if( isRowid ){
sqlite3VdbeAddOp2(v, OP_MustBeInt, r3,
sqlite3VdbeCurrentAddr(v)+2);
+ VdbeCoverage(v);
sqlite3VdbeAddOp3(v, OP_Insert, pExpr->iTable, r2, r3);
}else{
sqlite3VdbeAddOp4(v, OP_MakeRecord, r3, 1, r2, &affinity, 1);
@@ -75569,8 +87912,8 @@ SQLITE_PRIVATE int sqlite3CodeSubselect(
sqlite3ReleaseTempReg(pParse, r1);
sqlite3ReleaseTempReg(pParse, r2);
}
- if( !isRowid ){
- sqlite3VdbeChangeP4(v, addr, (void *)&keyInfo, P4_KEYINFO);
+ if( pKeyInfo ){
+ sqlite3VdbeChangeP4(v, addr, (void *)pKeyInfo, P4_KEYINFO);
}
break;
}
@@ -75596,6 +87939,7 @@ SQLITE_PRIVATE int sqlite3CodeSubselect(
sqlite3SelectDestInit(&dest, 0, ++pParse->nMem);
if( pExpr->op==TK_SELECT ){
dest.eDest = SRT_Mem;
+ dest.iSdst = dest.iSDParm;
sqlite3VdbeAddOp2(v, OP_Null, 0, dest.iSDParm);
VdbeComment((v, "Init subquery result"));
}else{
@@ -75607,19 +87951,24 @@ SQLITE_PRIVATE int sqlite3CodeSubselect(
pSel->pLimit = sqlite3PExpr(pParse, TK_INTEGER, 0, 0,
&sqlite3IntTokens[1]);
pSel->iLimit = 0;
+ pSel->selFlags &= ~SF_MultiValue;
if( sqlite3Select(pParse, pSel, &dest) ){
return 0;
}
rReg = dest.iSDParm;
- ExprSetIrreducible(pExpr);
+ ExprSetVVAProperty(pExpr, EP_NoReduce);
break;
}
}
- if( testAddr>=0 ){
- sqlite3VdbeJumpHere(v, testAddr);
+ if( rHasNullFlag ){
+ sqlite3SetHasNullFlag(v, pExpr->iTable, rHasNullFlag);
}
- sqlite3ExprCachePop(pParse, 1);
+
+ if( jmpIfDynamic>=0 ){
+ sqlite3VdbeJumpHere(v, jmpIfDynamic);
+ }
+ sqlite3ExprCachePop(pParse);
return rReg;
}
@@ -75638,7 +87987,7 @@ SQLITE_PRIVATE int sqlite3CodeSubselect(
** 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
+** This routine generates code that jumps 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.
@@ -75661,7 +88010,9 @@ static void sqlite3ExprCodeIN(
v = pParse->pVdbe;
assert( v!=0 ); /* OOM detected prior to this routine */
VdbeNoopComment((v, "begin IN expr"));
- eType = sqlite3FindInIndex(pParse, pExpr, &rRhsHasNull);
+ eType = sqlite3FindInIndex(pParse, pExpr,
+ IN_INDEX_MEMBERSHIP | IN_INDEX_NOOP_OK,
+ destIfFalse==destIfNull ? 0 : &rRhsHasNull);
/* Figure out the affinity to use to create a key from the results
** of the expression. affinityStr stores a static string suitable for
@@ -75675,101 +88026,122 @@ static void sqlite3ExprCodeIN(
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 sqlite3FindInIndex() did not find or create an index that is
+ ** suitable for evaluating the IN operator, then evaluate using a
+ ** sequence of comparisons.
*/
- 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);
+ if( eType==IN_INDEX_NOOP ){
+ ExprList *pList = pExpr->x.pList;
+ CollSeq *pColl = sqlite3ExprCollSeq(pParse, pExpr->pLeft);
+ int labelOk = sqlite3VdbeMakeLabel(v);
+ int r2, regToFree;
+ int regCkNull = 0;
+ int ii;
+ assert( !ExprHasProperty(pExpr, EP_xIsSelect) );
+ if( destIfNull!=destIfFalse ){
+ regCkNull = sqlite3GetTempReg(pParse);
+ sqlite3VdbeAddOp3(v, OP_BitAnd, r1, r1, regCkNull);
+ }
+ for(ii=0; ii<pList->nExpr; ii++){
+ r2 = sqlite3ExprCodeTemp(pParse, pList->a[ii].pExpr, &regToFree);
+ if( regCkNull && sqlite3ExprCanBeNull(pList->a[ii].pExpr) ){
+ sqlite3VdbeAddOp3(v, OP_BitAnd, regCkNull, r2, regCkNull);
+ }
+ if( ii<pList->nExpr-1 || destIfNull!=destIfFalse ){
+ sqlite3VdbeAddOp4(v, OP_Eq, r1, labelOk, r2,
+ (void*)pColl, P4_COLLSEQ);
+ VdbeCoverageIf(v, ii<pList->nExpr-1);
+ VdbeCoverageIf(v, ii==pList->nExpr-1);
+ sqlite3VdbeChangeP5(v, affinity);
+ }else{
+ assert( destIfNull==destIfFalse );
+ sqlite3VdbeAddOp4(v, OP_Ne, r1, destIfFalse, r2,
+ (void*)pColl, P4_COLLSEQ); VdbeCoverage(v);
+ sqlite3VdbeChangeP5(v, affinity | SQLITE_JUMPIFNULL);
+ }
+ sqlite3ReleaseTempReg(pParse, regToFree);
+ }
+ if( regCkNull ){
+ sqlite3VdbeAddOp2(v, OP_IsNull, regCkNull, destIfNull); VdbeCoverage(v);
+ sqlite3VdbeGoto(v, destIfFalse);
+ }
+ sqlite3VdbeResolveLabel(v, labelOk);
+ sqlite3ReleaseTempReg(pParse, regCkNull);
}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 the LHS is NULL, then the result is either false or NULL depending
+ ** on whether the RHS is empty or not, respectively.
*/
- 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.
+ if( sqlite3ExprCanBeNull(pExpr->pLeft) ){
+ if( destIfNull==destIfFalse ){
+ /* Shortcut for the common case where the false and NULL outcomes are
+ ** the same. */
+ sqlite3VdbeAddOp2(v, OP_IsNull, r1, destIfNull); VdbeCoverage(v);
+ }else{
+ int addr1 = sqlite3VdbeAddOp1(v, OP_NotNull, r1); VdbeCoverage(v);
+ sqlite3VdbeAddOp2(v, OP_Rewind, pExpr->iTable, destIfFalse);
+ VdbeCoverage(v);
+ sqlite3VdbeGoto(v, destIfNull);
+ sqlite3VdbeJumpHere(v, addr1);
+ }
+ }
+
+ if( eType==IN_INDEX_ROWID ){
+ /* In this case, the RHS is the ROWID of table b-tree
*/
- sqlite3VdbeAddOp4Int(v, OP_NotFound, pExpr->iTable, destIfFalse, r1, 1);
-
+ sqlite3VdbeAddOp2(v, OP_MustBeInt, r1, destIfFalse); VdbeCoverage(v);
+ sqlite3VdbeAddOp3(v, OP_NotExists, pExpr->iTable, destIfFalse, r1);
+ VdbeCoverage(v);
}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.
+ /* In this case, the RHS is an index b-tree.
*/
- 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.
+ 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.
*/
- sqlite3VdbeJumpHere(v, j1);
+ assert( destIfFalse!=destIfNull || rRhsHasNull==0 );
+ if( rRhsHasNull==0 ){
+ /* 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);
+ VdbeCoverage(v);
+ }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 addr1;
+
+ /* First check to see if the LHS is contained in the RHS. If so,
+ ** then the answer is TRUE the presence of NULLs in the RHS does
+ ** not matter. If the LHS is not contained in the RHS, then the
+ ** answer is NULL if the RHS contains NULLs and the answer is
+ ** FALSE if the RHS is NULL-free.
+ */
+ addr1 = sqlite3VdbeAddOp4Int(v, OP_Found, pExpr->iTable, 0, r1, 1);
+ VdbeCoverage(v);
+ sqlite3VdbeAddOp2(v, OP_IsNull, rRhsHasNull, destIfNull);
+ VdbeCoverage(v);
+ sqlite3VdbeGoto(v, destIfFalse);
+ sqlite3VdbeJumpHere(v, addr1);
+ }
}
}
sqlite3ReleaseTempReg(pParse, r1);
- sqlite3ExprCachePop(pParse, 1);
+ sqlite3ExprCachePop(pParse);
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
@@ -75782,12 +88154,10 @@ static char *dup8bytes(Vdbe *v, const char *in){
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);
+ sqlite3VdbeAddOp4Dup8(v, OP_Real, 0, iMem, 0, (u8*)&value, P4_REAL);
}
}
#endif
@@ -75811,17 +88181,22 @@ static void codeInteger(Parse *pParse, Expr *pExpr, int negFlag, int iMem){
i64 value;
const char *z = pExpr->u.zToken;
assert( z!=0 );
- c = sqlite3Atoi64(z, &value, sqlite3Strlen30(z), SQLITE_UTF8);
+ c = sqlite3DecOrHexToI64(z, &value);
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);
+ sqlite3VdbeAddOp4Dup8(v, OP_Int64, 0, iMem, 0, (u8*)&value, P4_INT64);
}else{
#ifdef SQLITE_OMIT_FLOATING_POINT
sqlite3ErrorMsg(pParse, "oversized integer: %s%s", negFlag ? "-" : "", z);
#else
- codeReal(v, z, negFlag, iMem);
+#ifndef SQLITE_OMIT_HEX_INTEGER
+ if( sqlite3_strnicmp(z,"0x",2)==0 ){
+ sqlite3ErrorMsg(pParse, "hex literal too big: %s", z);
+ }else
+#endif
+ {
+ codeReal(v, z, negFlag, iMem);
+ }
#endif
}
}
@@ -75850,7 +88225,8 @@ SQLITE_PRIVATE void sqlite3ExprCacheStore(Parse *pParse, int iTab, int iCol, int
int idxLru;
struct yColCache *p;
- assert( iReg>0 ); /* Register numbers are always positive */
+ /* Unless an error has occurred, register numbers are always positive. */
+ assert( iReg>0 || pParse->nErr || pParse->db->mallocFailed );
assert( iCol>=-1 && iCol<32768 ); /* Finite column numbers */
/* The SQLITE_ColumnCache flag disables the column cache. This is used
@@ -75928,19 +88304,28 @@ SQLITE_PRIVATE void sqlite3ExprCacheRemove(Parse *pParse, int iReg, int nReg){
*/
SQLITE_PRIVATE void sqlite3ExprCachePush(Parse *pParse){
pParse->iCacheLevel++;
+#ifdef SQLITE_DEBUG
+ if( pParse->db->flags & SQLITE_VdbeAddopTrace ){
+ printf("PUSH to %d\n", pParse->iCacheLevel);
+ }
+#endif
}
/*
** 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.
+** the previous sqlite3ExprCachePush operation. In other words, restore
+** the cache to the state it was in prior the most recent Push.
*/
-SQLITE_PRIVATE void sqlite3ExprCachePop(Parse *pParse, int N){
+SQLITE_PRIVATE void sqlite3ExprCachePop(Parse *pParse){
int i;
struct yColCache *p;
- assert( N>0 );
- assert( pParse->iCacheLevel>=N );
- pParse->iCacheLevel -= N;
+ assert( pParse->iCacheLevel>=1 );
+ pParse->iCacheLevel--;
+#ifdef SQLITE_DEBUG
+ if( pParse->db->flags & SQLITE_VdbeAddopTrace ){
+ printf("POP to %d\n", pParse->iCacheLevel);
+ }
+#endif
for(i=0, p=pParse->aColCache; i<SQLITE_N_COLCACHE; i++, p++){
if( p->iReg && p->iLevel>pParse->iCacheLevel ){
cacheEntryClear(pParse, p);
@@ -75965,21 +88350,47 @@ static void sqlite3ExprCachePinRegister(Parse *pParse, int iReg){
}
}
+/* Generate code that will load into register regOut a value that is
+** appropriate for the iIdxCol-th column of index pIdx.
+*/
+SQLITE_PRIVATE void sqlite3ExprCodeLoadIndexColumn(
+ Parse *pParse, /* The parsing context */
+ Index *pIdx, /* The index whose column is to be loaded */
+ int iTabCur, /* Cursor pointing to a table row */
+ int iIdxCol, /* The column of the index to be loaded */
+ int regOut /* Store the index column value in this register */
+){
+ i16 iTabCol = pIdx->aiColumn[iIdxCol];
+ if( iTabCol==XN_EXPR ){
+ assert( pIdx->aColExpr );
+ assert( pIdx->aColExpr->nExpr>iIdxCol );
+ pParse->iSelfTab = iTabCur;
+ sqlite3ExprCodeCopy(pParse, pIdx->aColExpr->a[iIdxCol].pExpr, regOut);
+ }else{
+ sqlite3ExprCodeGetColumnOfTable(pParse->pVdbe, pIdx->pTable, iTabCur,
+ iTabCol, regOut);
+ }
+}
+
/*
** 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 iTabCur, /* The table cursor. Or the PK cursor for WITHOUT ROWID */
int iCol, /* Index of the column to extract */
- int regOut /* Extract the valud into this register */
+ int regOut /* Extract the value 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);
+ int x = iCol;
+ if( !HasRowid(pTab) ){
+ x = sqlite3ColumnOfIndex(sqlite3PrimaryKeyIndex(pTab), iCol);
+ }
+ sqlite3VdbeAddOp3(v, op, iTabCur, x, regOut);
}
if( iCol>=0 ){
sqlite3ColumnDefault(v, pTab, iCol, regOut);
@@ -75988,9 +88399,12 @@ SQLITE_PRIVATE void sqlite3ExprCodeGetColumnOfTable(
/*
** 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.
+** table pTab and store the column value in a register.
+**
+** An effort is made to store the column value in register iReg. This
+** is not garanteeed for GetColumn() - the result can be stored in
+** any register. But the result is guaranteed to land in register iReg
+** for GetColumnToReg().
**
** 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.
@@ -76001,7 +88415,7 @@ SQLITE_PRIVATE int sqlite3ExprCodeGetColumn(
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 */
+ u8 p5 /* P5 value for OP_Column + FLAGS */
){
Vdbe *v = pParse->pVdbe;
int i;
@@ -76023,6 +88437,17 @@ SQLITE_PRIVATE int sqlite3ExprCodeGetColumn(
}
return iReg;
}
+SQLITE_PRIVATE void sqlite3ExprCodeGetColumnToReg(
+ 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 */
+){
+ int r1 = sqlite3ExprCodeGetColumn(pParse, pTab, iColumn, iTable, iReg, 0);
+ if( r1!=iReg ) sqlite3VdbeAddOp2(pParse->pVdbe, OP_SCopy, r1, iReg);
+}
+
/*
** Clear all column cache entries.
@@ -76031,6 +88456,11 @@ SQLITE_PRIVATE void sqlite3ExprCacheClear(Parse *pParse){
int i;
struct yColCache *p;
+#if SQLITE_DEBUG
+ if( pParse->db->flags & SQLITE_VdbeAddopTrace ){
+ printf("CLEAR\n");
+ }
+#endif
for(i=0, p=pParse->aColCache; i<SQLITE_N_COLCACHE; i++, p++){
if( p->iReg ){
cacheEntryClear(pParse, p);
@@ -76052,16 +88482,9 @@ SQLITE_PRIVATE void sqlite3ExprCacheAffinityChange(Parse *pParse, int iStart, in
** 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;
- }
- }
+ sqlite3VdbeAddOp3(pParse->pVdbe, OP_Move, iFrom, iTo, nReg);
+ sqlite3ExprCacheRemove(pParse, iFrom, nReg);
}
#if defined(SQLITE_DEBUG) || defined(SQLITE_COVERAGE_TEST)
@@ -76084,6 +88507,16 @@ static int usedAsColumnCache(Parse *pParse, int iFrom, int iTo){
#endif /* SQLITE_DEBUG || SQLITE_COVERAGE_TEST */
/*
+** Convert an expression node to a TK_REGISTER
+*/
+static void exprToRegister(Expr *p, int iReg){
+ p->op2 = p->op;
+ p->op = TK_REGISTER;
+ p->iTable = iReg;
+ ExprClearProperty(p, EP_Skip);
+}
+
+/*
** 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.
@@ -76102,6 +88535,7 @@ SQLITE_PRIVATE int sqlite3ExprCodeTarget(Parse *pParse, Expr *pExpr, int target)
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 */
+ Expr tempX; /* Temporary expression node */
assert( target>0 && target<=pParse->nMem );
if( v==0 ){
@@ -76130,15 +88564,21 @@ SQLITE_PRIVATE int sqlite3ExprCodeTarget(Parse *pParse, Expr *pExpr, int target)
/* 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);
+ int iTab = pExpr->iTable;
+ if( iTab<0 ){
+ if( pParse->ckBase>0 ){
+ /* Generating CHECK constraints or inserting into partial index */
+ inReg = pExpr->iColumn + pParse->ckBase;
+ break;
+ }else{
+ /* Coding an expression that is part of an index where column names
+ ** in the index refer to the table to which the index belongs */
+ iTab = pParse->iSelfTab;
+ }
}
+ inReg = sqlite3ExprCodeGetColumn(pParse, pExpr->pTab,
+ pExpr->iColumn, iTab, target,
+ pExpr->op2);
break;
}
case TK_INTEGER: {
@@ -76154,7 +88594,7 @@ SQLITE_PRIVATE int sqlite3ExprCodeTarget(Parse *pParse, Expr *pExpr, int target)
#endif
case TK_STRING: {
assert( !ExprHasProperty(pExpr, EP_IntValue) );
- sqlite3VdbeAddOp4(v, OP_String8, 0, target, 0, pExpr->u.zToken, 0);
+ sqlite3VdbeLoadString(v, target, pExpr->u.zToken);
break;
}
case TK_NULL: {
@@ -76193,33 +88633,16 @@ SQLITE_PRIVATE int sqlite3ExprCodeTarget(Parse *pParse, Expr *pExpr, int target)
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);
+ sqlite3VdbeAddOp2(v, OP_Cast, target,
+ sqlite3AffinityType(pExpr->u.zToken, 0));
testcase( usedAsColumnCache(pParse, inReg, inReg) );
sqlite3ExprCacheAffinityChange(pParse, inReg, 1);
break;
@@ -76231,22 +88654,16 @@ SQLITE_PRIVATE int sqlite3ExprCodeTarget(Parse *pParse, Expr *pExpr, int target)
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);
+ assert(TK_LT==OP_Lt); testcase(op==OP_Lt); VdbeCoverageIf(v,op==OP_Lt);
+ assert(TK_LE==OP_Le); testcase(op==OP_Le); VdbeCoverageIf(v,op==OP_Le);
+ assert(TK_GT==OP_Gt); testcase(op==OP_Gt); VdbeCoverageIf(v,op==OP_Gt);
+ assert(TK_GE==OP_Ge); testcase(op==OP_Ge); VdbeCoverageIf(v,op==OP_Ge);
+ assert(TK_EQ==OP_Eq); testcase(op==OP_Eq); VdbeCoverageIf(v,op==OP_Eq);
+ assert(TK_NE==OP_Ne); testcase(op==OP_Ne); VdbeCoverageIf(v,op==OP_Ne);
testcase( regFree1==0 );
testcase( regFree2==0 );
break;
@@ -76260,6 +88677,8 @@ SQLITE_PRIVATE int sqlite3ExprCodeTarget(Parse *pParse, Expr *pExpr, int target)
op = (op==TK_IS) ? TK_EQ : TK_NE;
codeCompare(pParse, pExpr->pLeft, pExpr->pRight, op,
r1, r2, inReg, SQLITE_STOREP2 | SQLITE_NULLEQ);
+ VdbeCoverageIf(v, op==TK_EQ);
+ VdbeCoverageIf(v, op==TK_NE);
testcase( regFree1==0 );
testcase( regFree2==0 );
break;
@@ -76276,28 +88695,17 @@ SQLITE_PRIVATE int sqlite3ExprCodeTarget(Parse *pParse, Expr *pExpr, int target)
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 );
+ assert( TK_AND==OP_And ); testcase( op==TK_AND );
+ assert( TK_OR==OP_Or ); testcase( op==TK_OR );
+ assert( TK_PLUS==OP_Add ); testcase( op==TK_PLUS );
+ assert( TK_MINUS==OP_Subtract ); testcase( op==TK_MINUS );
+ assert( TK_REM==OP_Remainder ); testcase( op==TK_REM );
+ assert( TK_BITAND==OP_BitAnd ); testcase( op==TK_BITAND );
+ assert( TK_BITOR==OP_BitOr ); testcase( op==TK_BITOR );
+ assert( TK_SLASH==OP_Divide ); testcase( op==TK_SLASH );
+ assert( TK_LSHIFT==OP_ShiftLeft ); testcase( op==TK_LSHIFT );
+ assert( TK_RSHIFT==OP_ShiftRight ); testcase( op==TK_RSHIFT );
+ assert( TK_CONCAT==OP_Concat ); testcase( op==TK_CONCAT );
r1 = sqlite3ExprCodeTemp(pParse, pExpr->pLeft, &regFree1);
r2 = sqlite3ExprCodeTemp(pParse, pExpr->pRight, &regFree2);
sqlite3VdbeAddOp3(v, op, r2, r1, target);
@@ -76316,8 +88724,10 @@ SQLITE_PRIVATE int sqlite3ExprCodeTarget(Parse *pParse, Expr *pExpr, int target)
codeReal(v, pLeft->u.zToken, 1, target);
#endif
}else{
- regFree1 = r1 = sqlite3GetTempReg(pParse);
- sqlite3VdbeAddOp2(v, OP_Integer, 0, r1);
+ tempX.op = TK_INTEGER;
+ tempX.flags = EP_IntValue|EP_TokenOnly;
+ tempX.u.iValue = 0;
+ r1 = sqlite3ExprCodeTemp(pParse, &tempX, &regFree1);
r2 = sqlite3ExprCodeTemp(pParse, pExpr->pLeft, &regFree2);
sqlite3VdbeAddOp3(v, OP_Subtract, r2, r1, target);
testcase( regFree2==0 );
@@ -76327,10 +88737,8 @@ SQLITE_PRIVATE int sqlite3ExprCodeTarget(Parse *pParse, Expr *pExpr, int target)
}
case TK_BITNOT:
case TK_NOT: {
- assert( TK_BITNOT==OP_BitNot );
- assert( TK_NOT==OP_Not );
- testcase( op==TK_BITNOT );
- testcase( op==TK_NOT );
+ assert( TK_BITNOT==OP_BitNot ); testcase( op==TK_BITNOT );
+ assert( TK_NOT==OP_Not ); testcase( op==TK_NOT );
r1 = sqlite3ExprCodeTemp(pParse, pExpr->pLeft, &regFree1);
testcase( regFree1==0 );
inReg = target;
@@ -76340,15 +88748,15 @@ SQLITE_PRIVATE int sqlite3ExprCodeTarget(Parse *pParse, Expr *pExpr, int target)
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 );
+ assert( TK_ISNULL==OP_IsNull ); testcase( op==TK_ISNULL );
+ assert( TK_NOTNULL==OP_NotNull ); 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);
+ VdbeCoverageIf(v, op==TK_ISNULL);
+ VdbeCoverageIf(v, op==TK_NOTNULL);
+ sqlite3VdbeAddOp2(v, OP_Integer, 0, target);
sqlite3VdbeJumpHere(v, addr);
break;
}
@@ -76362,22 +88770,19 @@ SQLITE_PRIVATE int sqlite3ExprCodeTarget(Parse *pParse, Expr *pExpr, int target)
}
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 */
+ u32 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) ){
+ if( ExprHasProperty(pExpr, EP_TokenOnly) ){
pFarg = 0;
}else{
pFarg = pExpr->x.pList;
@@ -76387,40 +88792,63 @@ SQLITE_PRIVATE int sqlite3ExprCodeTarget(Parse *pParse, Expr *pExpr, int target)
zId = pExpr->u.zToken;
nId = sqlite3Strlen30(zId);
pDef = sqlite3FindFunction(db, zId, nId, nFarg, enc, 0);
- if( pDef==0 ){
+ if( pDef==0 || pDef->xFunc==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
+ ** IFNULL() functions. This avoids unnecessary evaluation of
** arguments past the first non-NULL argument.
*/
- if( pDef->flags & SQLITE_FUNC_COALESCE ){
+ if( pDef->funcFlags & 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);
+ VdbeCoverage(v);
sqlite3ExprCacheRemove(pParse, target, 1);
sqlite3ExprCachePush(pParse);
sqlite3ExprCode(pParse, pFarg->a[i].pExpr, target);
- sqlite3ExprCachePop(pParse, 1);
+ sqlite3ExprCachePop(pParse);
}
sqlite3VdbeResolveLabel(v, endCoalesce);
break;
}
+ /* The UNLIKELY() function is a no-op. The result is the value
+ ** of the first argument.
+ */
+ if( pDef->funcFlags & SQLITE_FUNC_UNLIKELY ){
+ assert( nFarg>=1 );
+ inReg = sqlite3ExprCodeTarget(pParse, pFarg->a[0].pExpr, target);
+ break;
+ }
+ for(i=0; i<nFarg; i++){
+ if( i<32 && sqlite3ExprIsConstant(pFarg->a[i].pExpr) ){
+ testcase( i==31 );
+ constMask |= MASKBIT32(i);
+ }
+ if( (pDef->funcFlags & SQLITE_FUNC_NEEDCOLL)!=0 && !pColl ){
+ pColl = sqlite3ExprCollSeq(pParse, pFarg->a[i].pExpr);
+ }
+ }
if( pFarg ){
- r1 = sqlite3GetTempRange(pParse, nFarg);
+ if( constMask ){
+ r1 = pParse->nMem+1;
+ pParse->nMem += nFarg;
+ }else{
+ 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 ){
+ if( (pDef->funcFlags & (SQLITE_FUNC_LENGTH|SQLITE_FUNC_TYPEOF))!=0 ){
u8 exprOp;
assert( nFarg==1 );
assert( pFarg->a[0].pExpr!=0 );
@@ -76428,14 +88856,16 @@ SQLITE_PRIVATE int sqlite3ExprCodeTarget(Parse *pParse, Expr *pExpr, int target)
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;
+ testcase( pDef->funcFlags & OPFLAG_LENGTHARG );
+ pFarg->a[0].pExpr->op2 =
+ pDef->funcFlags & (OPFLAG_LENGTHARG|OPFLAG_TYPEOFARG);
}
}
sqlite3ExprCachePush(pParse); /* Ticket 2ea2425d34be */
- sqlite3ExprCodeExprList(pParse, pFarg, r1, 1);
- sqlite3ExprCachePop(pParse, 1); /* Ticket 2ea2425d34be */
+ sqlite3ExprCodeExprList(pParse, pFarg, r1, 0,
+ SQLITE_ECEL_DUP|SQLITE_ECEL_FACTOR);
+ sqlite3ExprCachePop(pParse); /* Ticket 2ea2425d34be */
}else{
r1 = 0;
}
@@ -76458,22 +88888,14 @@ SQLITE_PRIVATE int sqlite3ExprCodeTarget(Parse *pParse, Expr *pExpr, int target)
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( pDef->funcFlags & 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,
+ sqlite3VdbeAddOp4(v, OP_Function0, constMask, r1, target,
(char*)pDef, P4_FUNCDEF);
sqlite3VdbeChangeP5(v, (u8)nFarg);
- if( nFarg ){
+ if( nFarg && constMask==0 ){
sqlite3ReleaseTempRange(pParse, r1, nFarg);
}
break;
@@ -76523,13 +88945,14 @@ SQLITE_PRIVATE int sqlite3ExprCodeTarget(Parse *pParse, Expr *pExpr, int target)
r3 = sqlite3GetTempReg(pParse);
r4 = sqlite3GetTempReg(pParse);
codeCompare(pParse, pLeft, pRight, OP_Ge,
- r1, r2, r3, SQLITE_STOREP2);
+ r1, r2, r3, SQLITE_STOREP2); VdbeCoverage(v);
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);
+ VdbeCoverage(v);
sqlite3VdbeAddOp3(v, OP_And, r3, r4, target);
sqlite3ReleaseTempReg(pParse, r3);
sqlite3ReleaseTempReg(pParse, r4);
@@ -76584,7 +89007,10 @@ SQLITE_PRIVATE int sqlite3ExprCodeTarget(Parse *pParse, Expr *pExpr, int 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. */
+ ** integer. Use OP_RealAffinity to make sure it is really real.
+ **
+ ** EVIDENCE-OF: R-60985-57662 SQLite will convert the value back to
+ ** floating point when extracting it from the record. */
if( pExpr->iColumn>=0
&& pTab->aCol[pExpr->iColumn].affinity==SQLITE_AFF_REAL
){
@@ -76607,9 +89033,9 @@ SQLITE_PRIVATE int sqlite3ExprCodeTarget(Parse *pParse, Expr *pExpr, int target)
** 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.
+ ** Y is in the last element of pExpr->x.pList if pExpr->x.pList->nExpr is
+ ** odd. The Y is also optional. If the number of elements in x.pList
+ ** is even, then Y is omitted and the "otherwise" result 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,
@@ -76624,27 +89050,23 @@ SQLITE_PRIVATE int sqlite3ExprCodeTarget(Parse *pParse, Expr *pExpr, int target)
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;
+ tempX = *pX;
testcase( pX->op==TK_COLUMN );
- testcase( pX->op==TK_REGISTER );
- cacheX.iTable = sqlite3ExprCodeTemp(pParse, pX, &regFree1);
+ exprToRegister(&tempX, sqlite3ExprCodeTemp(pParse, pX, &regFree1));
testcase( regFree1==0 );
- cacheX.op = TK_REGISTER;
opCompare.op = TK_EQ;
- opCompare.pLeft = &cacheX;
+ opCompare.pLeft = &tempX;
pTest = &opCompare;
/* Ticket b351d95f9cd5ef17e9d9dbae18f5ca8611190001:
** The value in regFree1 might get SCopy-ed into the file result.
@@ -76652,7 +89074,7 @@ SQLITE_PRIVATE int sqlite3ExprCodeTarget(Parse *pParse, Expr *pExpr, int target)
** purposes and possibly overwritten. */
regFree1 = 0;
}
- for(i=0; i<nExpr; i=i+2){
+ for(i=0; i<nExpr-1; i=i+2){
sqlite3ExprCachePush(pParse);
if( pX ){
assert( pTest!=0 );
@@ -76664,16 +89086,15 @@ SQLITE_PRIVATE int sqlite3ExprCodeTarget(Parse *pParse, Expr *pExpr, int target)
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);
+ sqlite3VdbeGoto(v, endLabel);
+ sqlite3ExprCachePop(pParse);
sqlite3VdbeResolveLabel(v, nextCase);
}
- if( pExpr->pRight ){
+ if( (nExpr&1)!=0 ){
sqlite3ExprCachePush(pParse);
- sqlite3ExprCode(pParse, pExpr->pRight, target);
- sqlite3ExprCachePop(pParse, 1);
+ sqlite3ExprCode(pParse, pEList->a[nExpr-1].pExpr, target);
+ sqlite3ExprCachePop(pParse);
}else{
sqlite3VdbeAddOp2(v, OP_Null, 0, target);
}
@@ -76701,8 +89122,10 @@ SQLITE_PRIVATE int sqlite3ExprCodeTarget(Parse *pParse, Expr *pExpr, int target)
if( pExpr->affinity==OE_Ignore ){
sqlite3VdbeAddOp4(
v, OP_Halt, SQLITE_OK, OE_Ignore, 0, pExpr->u.zToken,0);
+ VdbeCoverage(v);
}else{
- sqlite3HaltConstraint(pParse, pExpr->affinity, pExpr->u.zToken, 0);
+ sqlite3HaltConstraint(pParse, SQLITE_CONSTRAINT_TRIGGER,
+ pExpr->affinity, pExpr->u.zToken, 0, 0);
}
break;
@@ -76715,6 +89138,28 @@ SQLITE_PRIVATE int sqlite3ExprCodeTarget(Parse *pParse, Expr *pExpr, int target)
}
/*
+** Factor out the code of the given expression to initialization time.
+*/
+SQLITE_PRIVATE void sqlite3ExprCodeAtInit(
+ Parse *pParse, /* Parsing context */
+ Expr *pExpr, /* The expression to code when the VDBE initializes */
+ int regDest, /* Store the value in this register */
+ u8 reusable /* True if this expression is reusable */
+){
+ ExprList *p;
+ assert( ConstFactorOk(pParse) );
+ p = pParse->pConstExpr;
+ pExpr = sqlite3ExprDup(pParse->db, pExpr, 0);
+ p = sqlite3ExprListAppend(pParse, p, pExpr);
+ if( p ){
+ struct ExprList_item *pItem = &p->a[p->nExpr-1];
+ pItem->u.iConstExprReg = regDest;
+ pItem->reusable = reusable;
+ }
+ pParse->pConstExpr = p;
+}
+
+/*
** Generate code to evaluate an expression and store the results
** into a register. Return the register number where the results
** are stored.
@@ -76722,15 +89167,40 @@ SQLITE_PRIVATE int sqlite3ExprCodeTarget(Parse *pParse, Expr *pExpr, int target)
** 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.
+**
+** If pExpr is a constant, then this routine might generate this
+** code to fill the register in the initialization section of the
+** VDBE program, in order to factor it out of the evaluation loop.
*/
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;
+ int r2;
+ pExpr = sqlite3ExprSkipCollate(pExpr);
+ if( ConstFactorOk(pParse)
+ && pExpr->op!=TK_REGISTER
+ && sqlite3ExprIsConstantNotJoin(pExpr)
+ ){
+ ExprList *p = pParse->pConstExpr;
+ int i;
+ *pReg = 0;
+ if( p ){
+ struct ExprList_item *pItem;
+ for(pItem=p->a, i=p->nExpr; i>0; pItem++, i--){
+ if( pItem->reusable && sqlite3ExprCompare(pItem->pExpr,pExpr,-1)==0 ){
+ return pItem->u.iConstExprReg;
+ }
+ }
+ }
+ r2 = ++pParse->nMem;
+ sqlite3ExprCodeAtInit(pParse, pExpr, r2, 1);
}else{
- sqlite3ReleaseTempReg(pParse, r1);
- *pReg = 0;
+ int r1 = sqlite3GetTempReg(pParse);
+ r2 = sqlite3ExprCodeTarget(pParse, pExpr, r1);
+ if( r2==r1 ){
+ *pReg = r1;
+ }else{
+ sqlite3ReleaseTempReg(pParse, r1);
+ *pReg = 0;
+ }
}
return r2;
}
@@ -76740,7 +89210,7 @@ SQLITE_PRIVATE int sqlite3ExprCodeTemp(Parse *pParse, Expr *pExpr, int *pReg){
** results in register target. The results are guaranteed to appear
** in register target.
*/
-SQLITE_PRIVATE int sqlite3ExprCode(Parse *pParse, Expr *pExpr, int target){
+SQLITE_PRIVATE void sqlite3ExprCode(Parse *pParse, Expr *pExpr, int target){
int inReg;
assert( target>0 && target<=pParse->nMem );
@@ -76748,475 +89218,115 @@ SQLITE_PRIVATE int sqlite3ExprCode(Parse *pParse, Expr *pExpr, int target){
sqlite3VdbeAddOp2(pParse->pVdbe, OP_Copy, pExpr->iTable, target);
}else{
inReg = sqlite3ExprCodeTarget(pParse, pExpr, target);
- assert( pParse->pVdbe || pParse->db->mallocFailed );
+ assert( pParse->pVdbe!=0 || 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.
+** Make a transient copy of expression pExpr and then code it using
+** sqlite3ExprCode(). This routine works just like sqlite3ExprCode()
+** except that the input expression is guaranteed to be unchanged.
*/
-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,")");
- }
+SQLITE_PRIVATE void sqlite3ExprCodeCopy(Parse *pParse, Expr *pExpr, int target){
+ sqlite3 *db = pParse->db;
+ pExpr = sqlite3ExprDup(db, pExpr, 0);
+ if( !db->mallocFailed ) sqlite3ExprCode(pParse, pExpr, target);
+ sqlite3ExprDelete(db, pExpr);
}
-#endif /* defined(SQLITE_ENABLE_TREE_EXPLAIN) */
-#if defined(SQLITE_ENABLE_TREE_EXPLAIN)
/*
-** Generate a human-readable explanation of an expression list.
+** Generate code that will evaluate expression pExpr and store the
+** results in register target. The results are guaranteed to appear
+** in register target. If the expression is constant, then this routine
+** might choose to code the expression at initialization time.
*/
-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);
+SQLITE_PRIVATE void sqlite3ExprCodeFactorable(Parse *pParse, Expr *pExpr, int target){
+ if( pParse->okConstFactor && sqlite3ExprIsConstant(pExpr) ){
+ sqlite3ExprCodeAtInit(pParse, pExpr, target, 0);
}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);
+ sqlite3ExprCode(pParse, pExpr, target);
}
}
-#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.
+** Generate code that evaluates the given expression and puts the result
+** in register target.
**
-** * 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.
+** 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.
**
-** 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.
+** This routine is used for expressions that are used multiple
+** times. They are evaluated once and the results of the expression
+** are reused.
*/
-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;
-}
+SQLITE_PRIVATE void sqlite3ExprCodeAndCache(Parse *pParse, Expr *pExpr, int target){
+ Vdbe *v = pParse->pVdbe;
+ int iMem;
-/*
-** 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);
+ assert( target>0 );
+ assert( pExpr->op!=TK_REGISTER );
+ sqlite3ExprCode(pParse, pExpr, target);
+ iMem = ++pParse->nMem;
+ sqlite3VdbeAddOp2(v, OP_Copy, target, iMem);
+ exprToRegister(pExpr, iMem);
}
-
/*
** 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.
+**
+** The SQLITE_ECEL_DUP flag prevents the arguments from being
+** filled using OP_SCopy. OP_Copy must be used instead.
+**
+** The SQLITE_ECEL_FACTOR argument allows constant arguments to be
+** factored out into initialization code.
+**
+** The SQLITE_ECEL_REF flag means that expressions in the list with
+** ExprList.a[].u.x.iOrderByCol>0 have already been evaluated and stored
+** in registers at srcReg, and so the value can be copied from there.
*/
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 */
+ int srcReg, /* Source registers if SQLITE_ECEL_REF */
+ u8 flags /* SQLITE_ECEL_* flags */
){
struct ExprList_item *pItem;
- int i, n;
+ int i, j, n;
+ u8 copyOp = (flags & SQLITE_ECEL_DUP) ? OP_Copy : OP_SCopy;
+ Vdbe *v = pParse->pVdbe;
assert( pList!=0 );
assert( target>0 );
assert( pParse->pVdbe!=0 ); /* Never gets this far otherwise */
n = pList->nExpr;
+ if( !ConstFactorOk(pParse) ) flags &= ~SQLITE_ECEL_FACTOR;
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);
+ if( (flags & SQLITE_ECEL_REF)!=0 && (j = pList->a[i].u.x.iOrderByCol)>0 ){
+ sqlite3VdbeAddOp2(v, copyOp, j+srcReg-1, target+i);
+ }else if( (flags & SQLITE_ECEL_FACTOR)!=0 && sqlite3ExprIsConstant(pExpr) ){
+ sqlite3ExprCodeAtInit(pParse, pExpr, target+i, 0);
+ }else{
+ int inReg = sqlite3ExprCodeTarget(pParse, pExpr, target+i);
+ if( inReg!=target+i ){
+ VdbeOp *pOp;
+ if( copyOp==OP_Copy
+ && (pOp=sqlite3VdbeGetOp(v, -1))->opcode==OP_Copy
+ && pOp->p1+pOp->p3+1==inReg
+ && pOp->p2+pOp->p3+1==target+i
+ ){
+ pOp->p3++;
+ }else{
+ sqlite3VdbeAddOp2(v, copyOp, inReg, target+i);
+ }
+ }
}
}
return n;
@@ -77232,7 +89342,7 @@ SQLITE_PRIVATE int sqlite3ExprCodeExprList(
** x>=y AND x<=z
**
** Code it as such, taking care to do the common subexpression
-** elementation of x.
+** elimination of x.
*/
static void exprCodeBetween(
Parse *pParse, /* Parsing and code generating context */
@@ -77258,8 +89368,7 @@ static void exprCodeBetween(
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;
+ exprToRegister(&exprX, sqlite3ExprCodeTemp(pParse, &exprX, &regFree1));
if( jumpIfTrue ){
sqlite3ExprIfTrue(pParse, &exprAnd, dest, jumpIfNull);
}else{
@@ -77300,24 +89409,26 @@ SQLITE_PRIVATE void sqlite3ExprIfTrue(Parse *pParse, Expr *pExpr, int dest, int
int r1, r2;
assert( jumpIfNull==SQLITE_JUMPIFNULL || jumpIfNull==0 );
- if( NEVER(v==0) ) return; /* Existance of VDBE checked by caller */
+ if( NEVER(v==0) ) return; /* Existence 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);
+ sqlite3ExprCachePush(pParse);
sqlite3ExprIfTrue(pParse, pExpr->pRight, dest, jumpIfNull);
sqlite3VdbeResolveLabel(v, d2);
- sqlite3ExprCachePop(pParse, 1);
+ sqlite3ExprCachePop(pParse);
break;
}
case TK_OR: {
testcase( jumpIfNull==0 );
sqlite3ExprIfTrue(pParse, pExpr->pLeft, dest, jumpIfNull);
+ sqlite3ExprCachePush(pParse);
sqlite3ExprIfTrue(pParse, pExpr->pRight, dest, jumpIfNull);
+ sqlite3ExprCachePop(pParse);
break;
}
case TK_NOT: {
@@ -77331,23 +89442,17 @@ SQLITE_PRIVATE void sqlite3ExprIfTrue(Parse *pParse, Expr *pExpr, int dest, int
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);
+ assert(TK_LT==OP_Lt); testcase(op==OP_Lt); VdbeCoverageIf(v,op==OP_Lt);
+ assert(TK_LE==OP_Le); testcase(op==OP_Le); VdbeCoverageIf(v,op==OP_Le);
+ assert(TK_GT==OP_Gt); testcase(op==OP_Gt); VdbeCoverageIf(v,op==OP_Gt);
+ assert(TK_GE==OP_Ge); testcase(op==OP_Ge); VdbeCoverageIf(v,op==OP_Ge);
+ assert(TK_EQ==OP_Eq); testcase(op==OP_Eq); VdbeCoverageIf(v,op==OP_Eq);
+ assert(TK_NE==OP_Ne); testcase(op==OP_Ne); VdbeCoverageIf(v,op==OP_Ne);
testcase( regFree1==0 );
testcase( regFree2==0 );
break;
@@ -77361,18 +89466,20 @@ SQLITE_PRIVATE void sqlite3ExprIfTrue(Parse *pParse, Expr *pExpr, int dest, int
op = (op==TK_IS) ? TK_EQ : TK_NE;
codeCompare(pParse, pExpr->pLeft, pExpr->pRight, op,
r1, r2, dest, SQLITE_NULLEQ);
+ VdbeCoverageIf(v, op==TK_EQ);
+ VdbeCoverageIf(v, op==TK_NE);
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 );
+ assert( TK_ISNULL==OP_IsNull ); testcase( op==TK_ISNULL );
+ assert( TK_NOTNULL==OP_NotNull ); testcase( op==TK_NOTNULL );
r1 = sqlite3ExprCodeTemp(pParse, pExpr->pLeft, &regFree1);
sqlite3VdbeAddOp2(v, op, r1, dest);
+ VdbeCoverageIf(v, op==TK_ISNULL);
+ VdbeCoverageIf(v, op==TK_NOTNULL);
testcase( regFree1==0 );
break;
}
@@ -77386,16 +89493,23 @@ SQLITE_PRIVATE void sqlite3ExprIfTrue(Parse *pParse, Expr *pExpr, int dest, int
int destIfFalse = sqlite3VdbeMakeLabel(v);
int destIfNull = jumpIfNull ? dest : destIfFalse;
sqlite3ExprCodeIN(pParse, pExpr, destIfFalse, destIfNull);
- sqlite3VdbeAddOp2(v, OP_Goto, 0, dest);
+ sqlite3VdbeGoto(v, 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 );
+ if( exprAlwaysTrue(pExpr) ){
+ sqlite3VdbeGoto(v, dest);
+ }else if( exprAlwaysFalse(pExpr) ){
+ /* No-op */
+ }else{
+ r1 = sqlite3ExprCodeTemp(pParse, pExpr, &regFree1);
+ sqlite3VdbeAddOp3(v, OP_If, r1, dest, jumpIfNull!=0);
+ VdbeCoverage(v);
+ testcase( regFree1==0 );
+ testcase( jumpIfNull==0 );
+ }
break;
}
}
@@ -77420,7 +89534,7 @@ SQLITE_PRIVATE void sqlite3ExprIfFalse(Parse *pParse, Expr *pExpr, int dest, int
int r1, r2;
assert( jumpIfNull==SQLITE_JUMPIFNULL || jumpIfNull==0 );
- if( NEVER(v==0) ) return; /* Existance of VDBE checked by caller */
+ if( NEVER(v==0) ) return; /* Existence of VDBE checked by caller */
if( pExpr==0 ) return;
/* The value of pExpr->op and op are related as follows:
@@ -77458,17 +89572,19 @@ SQLITE_PRIVATE void sqlite3ExprIfFalse(Parse *pParse, Expr *pExpr, int dest, int
case TK_AND: {
testcase( jumpIfNull==0 );
sqlite3ExprIfFalse(pParse, pExpr->pLeft, dest, jumpIfNull);
+ sqlite3ExprCachePush(pParse);
sqlite3ExprIfFalse(pParse, pExpr->pRight, dest, jumpIfNull);
+ sqlite3ExprCachePop(pParse);
break;
}
case TK_OR: {
int d2 = sqlite3VdbeMakeLabel(v);
testcase( jumpIfNull==0 );
- sqlite3ExprCachePush(pParse);
sqlite3ExprIfTrue(pParse, pExpr->pLeft, d2, jumpIfNull^SQLITE_JUMPIFNULL);
+ sqlite3ExprCachePush(pParse);
sqlite3ExprIfFalse(pParse, pExpr->pRight, dest, jumpIfNull);
sqlite3VdbeResolveLabel(v, d2);
- sqlite3ExprCachePop(pParse, 1);
+ sqlite3ExprCachePop(pParse);
break;
}
case TK_NOT: {
@@ -77482,17 +89598,17 @@ SQLITE_PRIVATE void sqlite3ExprIfFalse(Parse *pParse, Expr *pExpr, int dest, int
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);
+ assert(TK_LT==OP_Lt); testcase(op==OP_Lt); VdbeCoverageIf(v,op==OP_Lt);
+ assert(TK_LE==OP_Le); testcase(op==OP_Le); VdbeCoverageIf(v,op==OP_Le);
+ assert(TK_GT==OP_Gt); testcase(op==OP_Gt); VdbeCoverageIf(v,op==OP_Gt);
+ assert(TK_GE==OP_Ge); testcase(op==OP_Ge); VdbeCoverageIf(v,op==OP_Ge);
+ assert(TK_EQ==OP_Eq); testcase(op==OP_Eq); VdbeCoverageIf(v,op==OP_Eq);
+ assert(TK_NE==OP_Ne); testcase(op==OP_Ne); VdbeCoverageIf(v,op==OP_Ne);
testcase( regFree1==0 );
testcase( regFree2==0 );
break;
@@ -77506,16 +89622,18 @@ SQLITE_PRIVATE void sqlite3ExprIfFalse(Parse *pParse, Expr *pExpr, int dest, int
op = (pExpr->op==TK_IS) ? TK_NE : TK_EQ;
codeCompare(pParse, pExpr->pLeft, pExpr->pRight, op,
r1, r2, dest, SQLITE_NULLEQ);
+ VdbeCoverageIf(v, op==TK_EQ);
+ VdbeCoverageIf(v, op==TK_NE);
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( op==TK_ISNULL ); VdbeCoverageIf(v, op==TK_ISNULL);
+ testcase( op==TK_NOTNULL ); VdbeCoverageIf(v, op==TK_NOTNULL);
testcase( regFree1==0 );
break;
}
@@ -77537,10 +89655,17 @@ SQLITE_PRIVATE void sqlite3ExprIfFalse(Parse *pParse, Expr *pExpr, int dest, int
}
#endif
default: {
- r1 = sqlite3ExprCodeTemp(pParse, pExpr, &regFree1);
- sqlite3VdbeAddOp3(v, OP_IfNot, r1, dest, jumpIfNull!=0);
- testcase( regFree1==0 );
- testcase( jumpIfNull==0 );
+ if( exprAlwaysFalse(pExpr) ){
+ sqlite3VdbeGoto(v, dest);
+ }else if( exprAlwaysTrue(pExpr) ){
+ /* no-op */
+ }else{
+ r1 = sqlite3ExprCodeTemp(pParse, pExpr, &regFree1);
+ sqlite3VdbeAddOp3(v, OP_IfNot, r1, dest, jumpIfNull!=0);
+ VdbeCoverage(v);
+ testcase( regFree1==0 );
+ testcase( jumpIfNull==0 );
+ }
break;
}
}
@@ -77549,11 +89674,32 @@ SQLITE_PRIVATE void sqlite3ExprIfFalse(Parse *pParse, Expr *pExpr, int dest, int
}
/*
+** Like sqlite3ExprIfFalse() except that a copy is made of pExpr before
+** code generation, and that copy is deleted after code generation. This
+** ensures that the original pExpr is unchanged.
+*/
+SQLITE_PRIVATE void sqlite3ExprIfFalseDup(Parse *pParse, Expr *pExpr, int dest,int jumpIfNull){
+ sqlite3 *db = pParse->db;
+ Expr *pCopy = sqlite3ExprDup(db, pExpr, 0);
+ if( db->mallocFailed==0 ){
+ sqlite3ExprIfFalse(pParse, pCopy, dest, jumpIfNull);
+ }
+ sqlite3ExprDelete(db, pCopy);
+}
+
+
+/*
** 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.
**
+** If any subelement of pB has Expr.iTable==(-1) then it is allowed
+** to compare equal to an equivalent element in pA with Expr.iTable==iTab.
+**
+** The pA side might be using TK_REGISTER. If that is the case and pB is
+** not using TK_REGISTER but is otherwise equivalent, then still return 0.
+**
** 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
@@ -77564,39 +89710,46 @@ SQLITE_PRIVATE void sqlite3ExprIfFalse(Parse *pParse, Expr *pExpr, int dest, int
** 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 ){
+SQLITE_PRIVATE int sqlite3ExprCompare(Expr *pA, Expr *pB, int iTab){
+ u32 combinedFlags;
+ 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) ){
+ combinedFlags = pA->flags | pB->flags;
+ if( combinedFlags & EP_IntValue ){
+ if( (pA->flags&pB->flags&EP_IntValue)!=0 && pA->u.iValue==pB->u.iValue ){
+ return 0;
+ }
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 ){
+ if( pA->op==TK_COLLATE && sqlite3ExprCompare(pA->pLeft, pB, iTab)<2 ){
return 1;
}
- if( pB->op==TK_COLLATE && sqlite3ExprCompare(pA, pB->pLeft)<2 ){
+ if( pB->op==TK_COLLATE && sqlite3ExprCompare(pA, pB->pLeft, iTab)<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 ){
+ if( pA->op!=TK_COLUMN && pA->op!=TK_AGG_COLUMN && pA->u.zToken ){
+ if( pA->op==TK_FUNCTION ){
+ if( sqlite3StrICmp(pA->u.zToken,pB->u.zToken)!=0 ) return 2;
+ }else if( strcmp(pA->u.zToken,pB->u.zToken)!=0 ){
return pA->op==TK_COLLATE ? 1 : 2;
}
}
+ if( (pA->flags & EP_Distinct)!=(pB->flags & EP_Distinct) ) return 2;
+ if( ALWAYS((combinedFlags & EP_TokenOnly)==0) ){
+ if( combinedFlags & EP_xIsSelect ) return 2;
+ if( sqlite3ExprCompare(pA->pLeft, pB->pLeft, iTab) ) return 2;
+ if( sqlite3ExprCompare(pA->pRight, pB->pRight, iTab) ) return 2;
+ if( sqlite3ExprListCompare(pA->x.pList, pB->x.pList, iTab) ) return 2;
+ if( ALWAYS((combinedFlags & EP_Reduced)==0) && pA->op!=TK_STRING ){
+ if( pA->iColumn!=pB->iColumn ) return 2;
+ if( pA->iTable!=pB->iTable
+ && (pA->iTable!=iTab || NEVER(pB->iTable>=0)) ) return 2;
+ }
+ }
return 0;
}
@@ -77604,6 +89757,9 @@ SQLITE_PRIVATE int sqlite3ExprCompare(Expr *pA, Expr *pB){
** Compare two ExprList objects. Return 0 if they are identical and
** non-zero if they differ in any way.
**
+** If any subelement of pB has Expr.iTable==(-1) then it is allowed
+** to compare equal to an equivalent element in pA with Expr.iTable==iTab.
+**
** 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
@@ -77612,7 +89768,7 @@ SQLITE_PRIVATE int sqlite3ExprCompare(Expr *pA, Expr *pB){
** 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){
+SQLITE_PRIVATE int sqlite3ExprListCompare(ExprList *pA, ExprList *pB, int iTab){
int i;
if( pA==0 && pB==0 ) return 0;
if( pA==0 || pB==0 ) return 1;
@@ -77621,7 +89777,46 @@ SQLITE_PRIVATE int sqlite3ExprListCompare(ExprList *pA, ExprList *pB){
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;
+ if( sqlite3ExprCompare(pExprA, pExprB, iTab) ) return 1;
+ }
+ return 0;
+}
+
+/*
+** Return true if we can prove the pE2 will always be true if pE1 is
+** true. Return false if we cannot complete the proof or if pE2 might
+** be false. Examples:
+**
+** pE1: x==5 pE2: x==5 Result: true
+** pE1: x>0 pE2: x==5 Result: false
+** pE1: x=21 pE2: x=21 OR y=43 Result: true
+** pE1: x!=123 pE2: x IS NOT NULL Result: true
+** pE1: x!=?1 pE2: x IS NOT NULL Result: true
+** pE1: x IS NULL pE2: x IS NOT NULL Result: false
+** pE1: x IS ?2 pE2: x IS NOT NULL Reuslt: false
+**
+** When comparing TK_COLUMN nodes between pE1 and pE2, if pE2 has
+** Expr.iTable<0 then assume a table number given by iTab.
+**
+** When in doubt, return false. Returning true might give a performance
+** improvement. Returning false might cause a performance reduction, but
+** it will always give the correct answer and is hence always safe.
+*/
+SQLITE_PRIVATE int sqlite3ExprImpliesExpr(Expr *pE1, Expr *pE2, int iTab){
+ if( sqlite3ExprCompare(pE1, pE2, iTab)==0 ){
+ return 1;
+ }
+ if( pE2->op==TK_OR
+ && (sqlite3ExprImpliesExpr(pE1, pE2->pLeft, iTab)
+ || sqlite3ExprImpliesExpr(pE1, pE2->pRight, iTab) )
+ ){
+ return 1;
+ }
+ if( pE2->op==TK_NOTNULL
+ && sqlite3ExprCompare(pE1->pLeft, pE2->pLeft, iTab)==0
+ && (pE1->op!=TK_ISNULL && pE1->op!=TK_IS)
+ ){
+ return 1;
}
return 0;
}
@@ -77651,10 +89846,11 @@ static int exprSrcCount(Walker *pWalker, Expr *pExpr){
int i;
struct SrcCount *p = pWalker->u.pSrcCount;
SrcList *pSrc = p->pSrc;
- for(i=0; i<pSrc->nSrc; i++){
+ int nSrc = pSrc ? pSrc->nSrc : 0;
+ for(i=0; i<nSrc; i++){
if( pExpr->iTable==pSrc->a[i].iCursor ) break;
}
- if( i<pSrc->nSrc ){
+ if( i<nSrc ){
p->nThis++;
}else{
p->nOther++;
@@ -77738,7 +89934,7 @@ static int analyzeAggregate(Walker *pWalker, Expr *pExpr){
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) );
+ assert( !ExprHasProperty(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.
@@ -77787,7 +89983,7 @@ static int analyzeAggregate(Walker *pWalker, Expr *pExpr){
** Convert the pExpr to be a TK_AGG_COLUMN referring to that
** pAggInfo->aCol[] entry.
*/
- ExprSetIrreducible(pExpr);
+ ExprSetVVAProperty(pExpr, EP_NoReduce);
pExpr->pAggInfo = pAggInfo;
pExpr->op = TK_AGG_COLUMN;
pExpr->iAgg = (i16)k;
@@ -77806,7 +90002,7 @@ static int analyzeAggregate(Walker *pWalker, Expr *pExpr){
*/
struct AggInfo_func *pItem = pAggInfo->aFunc;
for(i=0; i<pAggInfo->nFunc; i++, pItem++){
- if( sqlite3ExprCompare(pItem->pExpr, pExpr)==0 ){
+ if( sqlite3ExprCompare(pItem->pExpr, pExpr, -1)==0 ){
break;
}
}
@@ -77833,8 +90029,8 @@ static int analyzeAggregate(Walker *pWalker, Expr *pExpr){
}
/* Make pExpr point to the appropriate pAggInfo->aFunc[] entry
*/
- assert( !ExprHasAnyProperty(pExpr, EP_TokenOnly|EP_Reduced) );
- ExprSetIrreducible(pExpr);
+ assert( !ExprHasProperty(pExpr, EP_TokenOnly|EP_Reduced) );
+ ExprSetVVAProperty(pExpr, EP_NoReduce);
pExpr->iAgg = (i16)i;
pExpr->pAggInfo = pAggInfo;
return WRC_Prune;
@@ -77901,7 +90097,7 @@ SQLITE_PRIVATE int sqlite3GetTempReg(Parse *pParse){
** 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 deallocation is deferred until the column cache line that uses
** the register becomes stale.
*/
SQLITE_PRIVATE void sqlite3ReleaseTempReg(Parse *pParse, int iReg){
@@ -77967,6 +90163,7 @@ SQLITE_PRIVATE void sqlite3ClearTempRegCache(Parse *pParse){
** This file contains C code routines that used to generate VDBE code
** that implements the ALTER TABLE command.
*/
+/* #include "sqliteInt.h" */
/*
** The code in this file only exists if we are not omitting the
@@ -78031,8 +90228,8 @@ static void renameTableFunc(
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);
+ zRet = sqlite3MPrintf(db, "%.*s\"%w\"%s", (int)(((u8*)tname.z) - zSql),
+ zSql, zTableName, tname.z+tname.n);
sqlite3_result_text(context, zRet, -1, SQLITE_DYNAMIC);
}
}
@@ -78070,6 +90267,7 @@ static void renameParentFunc(
int token; /* Type of token */
UNUSED_PARAMETER(NotUsed);
+ if( zInput==0 || zOld==0 ) return;
for(z=zInput; *z; z=z+n){
n = sqlite3GetToken(z, &token);
if( token==TK_REFERENCES ){
@@ -78079,12 +90277,13 @@ static void renameParentFunc(
n = sqlite3GetToken(z, &token);
}while( token==TK_SPACE );
+ if( token==TK_ILLEGAL ) break;
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
+ (zOutput?zOutput:""), (int)(z-zInput), zInput, (const char *)zNew
);
sqlite3DbFree(db, zOutput);
zOutput = zOut;
@@ -78127,8 +90326,8 @@ static void renameTriggerFunc(
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
+ ** statement is that the table name is the first token that is immediately
+ ** preceded by either TK_ON or TK_DOT and immediately followed by one
** of TK_WHEN, TK_BEGIN or TK_FOR.
*/
if( zSql ){
@@ -78170,8 +90369,8 @@ static void renameTriggerFunc(
/* 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);
+ zRet = sqlite3MPrintf(db, "%.*s\"%w\"%s", (int)(((u8*)tname.z) - zSql),
+ zSql, zTableName, tname.z+tname.n);
sqlite3_result_text(context, zRet, -1, SQLITE_DYNAMIC);
}
}
@@ -78423,7 +90622,7 @@ SQLITE_PRIVATE void sqlite3AlterRenameTable(
}
#endif
- /* Begin a transaction and code the VerifyCookie for database iDb.
+ /* Begin a transaction 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.
@@ -78443,7 +90642,7 @@ SQLITE_PRIVATE void sqlite3AlterRenameTable(
#ifndef SQLITE_OMIT_VIRTUALTABLE
if( pVTab ){
int i = ++pParse->nMem;
- sqlite3VdbeAddOp4(v, OP_String8, 0, i, 0, zName, 0);
+ sqlite3VdbeLoadString(v, i, zName);
sqlite3VdbeAddOp4(v, OP_VRename, i, 0, 0,(const char*)pVTab, P4_VTAB);
sqlite3MayAbort(pParse);
}
@@ -78554,13 +90753,14 @@ SQLITE_PRIVATE void sqlite3MinimumFileFormat(Parse *pParse, int iDb, int minForm
if( ALWAYS(v) ){
int r1 = sqlite3GetTempReg(pParse);
int r2 = sqlite3GetTempReg(pParse);
- int j1;
+ int addr1;
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);
+ addr1 = sqlite3VdbeAddOp3(v, OP_Ge, r2, 0, r1);
+ sqlite3VdbeChangeP5(v, SQLITE_NOTNULL); VdbeCoverage(v);
sqlite3VdbeAddOp3(v, OP_SetCookie, iDb, BTREE_FILE_FORMAT, r2);
- sqlite3VdbeJumpHere(v, j1);
+ sqlite3VdbeJumpHere(v, addr1);
sqlite3ReleaseTempReg(pParse, r1);
sqlite3ReleaseTempReg(pParse, r2);
}
@@ -78641,8 +90841,11 @@ SQLITE_PRIVATE void sqlite3AlterFinishAddColumn(Parse *pParse, Token *pColDef){
** can handle (i.e. not CURRENT_TIME etc.)
*/
if( pDflt ){
- sqlite3_value *pVal;
- if( sqlite3ValueFromExpr(db, pDflt, SQLITE_UTF8, SQLITE_AFF_NONE, &pVal) ){
+ sqlite3_value *pVal = 0;
+ int rc;
+ rc = sqlite3ValueFromExpr(db, pDflt, SQLITE_UTF8, SQLITE_AFF_BLOB, &pVal);
+ assert( rc==SQLITE_OK || rc==SQLITE_NOMEM );
+ if( rc!=SQLITE_OK ){
db->mallocFailed = 1;
return;
}
@@ -78782,7 +90985,7 @@ exit_begin_add_column:
/************** End of alter.c ***********************************************/
/************** Begin file analyze.c *****************************************/
/*
-** 2005 July 8
+** 2005-07-08
**
** The author disclaims copyright to this source code. In place of
** a legal notice, here is a blessing:
@@ -78803,15 +91006,23 @@ exit_begin_add_column:
** 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);
+** CREATE TABLE sqlite_stat4(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
+** The sqlite_stat2 table is superseded 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.
+** SQLITE_ENABLE_STAT3 defined. The functionality of sqlite_stat3
+** is a superset of sqlite_stat2. The sqlite_stat4 is an enhanced
+** version of sqlite_stat3 and is only available when compiled with
+** SQLITE_ENABLE_STAT4 and in SQLite versions 3.8.1 and later. It is
+** not possible to enable both STAT3 and STAT4 at the same time. If they
+** are both enabled, then STAT4 takes precedence.
+**
+** For most applications, sqlite_stat1 provides all the statistics required
+** for the query planner to make good choices.
**
** Format of sqlite_stat1:
**
@@ -78819,7 +91030,8 @@ exit_begin_add_column:
** 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
+** list is the number of rows in the index. (This is the same as the
+** number of rows in the table, except for partial indices.) 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
@@ -78866,53 +91078,82 @@ exit_begin_add_column:
**
** Format for sqlite_stat3:
**
-** The sqlite_stat3 is an enhancement to sqlite_stat2. A new name is
-** used to avoid compatibility problems.
+** The sqlite_stat3 format is a subset of sqlite_stat4. Hence, the
+** sqlite_stat4 format will be described first. Further information
+** about sqlite_stat3 follows the sqlite_stat4 description.
+**
+** Format for sqlite_stat4:
+**
+** As with sqlite_stat2, the sqlite_stat4 table contains histogram data
+** to aid the query planner in choosing good indices based on the values
+** that indexed columns are compared against in the WHERE clauses of
+** queries.
**
-** 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 sqlite_stat4 table contains 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
+** of the INTEGER PRIMARY KEY. The sample column is a blob which is the
+** binary encoding of a key from the index. The nEq column is a
+** list of integers. The first integer is the approximate number
+** of entries in the index whose left-most column exactly matches
+** the left-most column of the sample. The second integer in nEq
+** is the approximate number of entries in the index where the
+** first two columns match the first two columns of the sample.
+** And so forth. nLt is another list of integers that show the approximate
+** number of entries that are strictly less than the sample. The first
+** integer in nLt contains the number of entries in the index where the
+** left-most column is less than the left-most column of the sample.
+** The K-th integer in the nLt entry is the number of index entries
+** where the first K columns are less than the first K columns of the
+** sample. The nDLt column is like nLt except that it contains the
+** number of distinct entries in the index that are less than the
+** sample.
+**
+** There can be an arbitrary number of sqlite_stat4 entries per index.
+** The ANALYZE command will typically generate sqlite_stat4 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.
+** large nEq values.
+**
+** Format for sqlite_stat3 redux:
+**
+** The sqlite_stat3 table is like sqlite_stat4 except that it only
+** looks at the left-most column of the index. The sqlite_stat3.sample
+** column contains the actual value of the left-most column instead
+** of a blob encoding of the complete index key as is found in
+** sqlite_stat4.sample. The nEq, nLt, and nDLt entries of sqlite_stat3
+** all contain just a single integer which is the same as the first
+** integer in the equivalent columns in sqlite_stat4.
*/
#ifndef SQLITE_OMIT_ANALYZE
+/* #include "sqliteInt.h" */
+
+#if defined(SQLITE_ENABLE_STAT4)
+# define IsStat4 1
+# define IsStat3 0
+#elif defined(SQLITE_ENABLE_STAT3)
+# define IsStat4 0
+# define IsStat3 1
+#else
+# define IsStat4 0
+# define IsStat3 0
+# undef SQLITE_STAT4_SAMPLES
+# define SQLITE_STAT4_SAMPLES 1
+#endif
+#define IsStat34 (IsStat3+IsStat4) /* 1 for STAT3 or STAT4. 0 otherwise */
/*
-** 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)
+** This routine generates code that opens the sqlite_statN tables.
+** The sqlite_stat1 table is always relevant. sqlite_stat2 is now
+** obsolete. sqlite_stat3 and sqlite_stat4 are only opened when
+** appropriate compile-time options are provided.
**
-** 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.
+** If the sqlite_statN tables do not previously exist, 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.
+** the sqlite_statN 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 */
@@ -78926,18 +91167,24 @@ static void openStatTable(
const char *zCols;
} aTable[] = {
{ "sqlite_stat1", "tbl,idx,stat" },
-#ifdef SQLITE_ENABLE_STAT3
+#if defined(SQLITE_ENABLE_STAT4)
+ { "sqlite_stat4", "tbl,idx,neq,nlt,ndlt,sample" },
+ { "sqlite_stat3", 0 },
+#elif defined(SQLITE_ENABLE_STAT3)
{ "sqlite_stat3", "tbl,idx,neq,nlt,ndlt,sample" },
+ { "sqlite_stat4", 0 },
+#else
+ { "sqlite_stat3", 0 },
+ { "sqlite_stat4", 0 },
#endif
};
-
- int aRoot[] = {0, 0};
- u8 aCreateTbl[] = {0, 0};
-
int i;
sqlite3 *db = pParse->db;
Db *pDb;
Vdbe *v = sqlite3GetVdbe(pParse);
+ int aRoot[ArraySize(aTable)];
+ u8 aCreateTbl[ArraySize(aTable)];
+
if( v==0 ) return;
assert( sqlite3BtreeHoldsAllMutexes(db) );
assert( sqlite3VdbeDb(v)==db );
@@ -78950,258 +91197,742 @@ static void openStatTable(
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;
+ if( aTable[i].zCols ){
+ /* The sqlite_statN 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;
+ aCreateTbl[i] = 0;
sqlite3TableLock(pParse, iDb, aRoot[i], 1, zTab);
if( zWhere ){
sqlite3NestedParse(pParse,
- "DELETE FROM %Q.%s WHERE %s=%Q", pDb->zName, zTab, zWhereType, zWhere
+ "DELETE FROM %Q.%s WHERE %s=%Q",
+ pDb->zName, zTab, zWhereType, zWhere
);
}else{
- /* The sqlite_stat[12] table already exists. Delete all rows. */
+ /* The sqlite_stat[134] 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);
+ /* Open the sqlite_stat[134] tables for writing. */
+ for(i=0; aTable[i].zCols; i++){
+ assert( i<ArraySize(aTable) );
+ sqlite3VdbeAddOp4Int(v, OP_OpenWrite, iStatCur+i, aRoot[i], iDb, 3);
sqlite3VdbeChangeP5(v, aCreateTbl[i]);
+ VdbeComment((v, aTable[i].zName));
}
}
/*
-** Recommended number of samples for sqlite_stat3
+** Recommended number of samples for sqlite_stat4
*/
-#ifndef SQLITE_STAT3_SAMPLES
-# define SQLITE_STAT3_SAMPLES 24
+#ifndef SQLITE_STAT4_SAMPLES
+# define SQLITE_STAT4_SAMPLES 24
#endif
/*
-** Three SQL functions - stat3_init(), stat3_push(), and stat3_pop() -
+** Three SQL functions - stat_init(), stat_push(), and stat_get() -
** share an instance of the following structure to hold their state
** information.
*/
-typedef struct Stat3Accum Stat3Accum;
-struct Stat3Accum {
+typedef struct Stat4Accum Stat4Accum;
+typedef struct Stat4Sample Stat4Sample;
+struct Stat4Sample {
+ tRowcnt *anEq; /* sqlite_stat4.nEq */
+ tRowcnt *anDLt; /* sqlite_stat4.nDLt */
+#ifdef SQLITE_ENABLE_STAT3_OR_STAT4
+ tRowcnt *anLt; /* sqlite_stat4.nLt */
+ union {
+ i64 iRowid; /* Rowid in main table of the key */
+ u8 *aRowid; /* Key for WITHOUT ROWID tables */
+ } u;
+ u32 nRowid; /* Sizeof aRowid[] */
+ u8 isPSample; /* True if a periodic sample */
+ int iCol; /* If !isPSample, the reason for inclusion */
+ u32 iHash; /* Tiebreaker hash */
+#endif
+};
+struct Stat4Accum {
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 nCol; /* Number of columns in index + pk/rowid */
+ int nKeyCol; /* Number of index columns w/o the pk/rowid */
int mxSample; /* Maximum number of samples to accumulate */
- int nSample; /* Current number of samples */
+ Stat4Sample current; /* Current row as a Stat4Sample */
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 */
+ Stat4Sample *aBest; /* Array of nCol best samples */
+ int iMin; /* Index in a[] of entry with minimum score */
+ int nSample; /* Current number of samples */
+ int iGet; /* Index of current sample accessed by stat_get() */
+ Stat4Sample *a; /* Array of mxSample Stat4Sample objects */
+ sqlite3 *db; /* Database connection, for malloc() */
};
-#ifdef SQLITE_ENABLE_STAT3
+/* Reclaim memory used by a Stat4Sample
+*/
+#ifdef SQLITE_ENABLE_STAT3_OR_STAT4
+static void sampleClear(sqlite3 *db, Stat4Sample *p){
+ assert( db!=0 );
+ if( p->nRowid ){
+ sqlite3DbFree(db, p->u.aRowid);
+ p->nRowid = 0;
+ }
+}
+#endif
+
+/* Initialize the BLOB value of a ROWID
+*/
+#ifdef SQLITE_ENABLE_STAT3_OR_STAT4
+static void sampleSetRowid(sqlite3 *db, Stat4Sample *p, int n, const u8 *pData){
+ assert( db!=0 );
+ if( p->nRowid ) sqlite3DbFree(db, p->u.aRowid);
+ p->u.aRowid = sqlite3DbMallocRaw(db, n);
+ if( p->u.aRowid ){
+ p->nRowid = n;
+ memcpy(p->u.aRowid, pData, n);
+ }else{
+ p->nRowid = 0;
+ }
+}
+#endif
+
+/* Initialize the INTEGER value of a ROWID.
+*/
+#ifdef SQLITE_ENABLE_STAT3_OR_STAT4
+static void sampleSetRowidInt64(sqlite3 *db, Stat4Sample *p, i64 iRowid){
+ assert( db!=0 );
+ if( p->nRowid ) sqlite3DbFree(db, p->u.aRowid);
+ p->nRowid = 0;
+ p->u.iRowid = iRowid;
+}
+#endif
+
+
+/*
+** Copy the contents of object (*pFrom) into (*pTo).
+*/
+#ifdef SQLITE_ENABLE_STAT3_OR_STAT4
+static void sampleCopy(Stat4Accum *p, Stat4Sample *pTo, Stat4Sample *pFrom){
+ pTo->isPSample = pFrom->isPSample;
+ pTo->iCol = pFrom->iCol;
+ pTo->iHash = pFrom->iHash;
+ memcpy(pTo->anEq, pFrom->anEq, sizeof(tRowcnt)*p->nCol);
+ memcpy(pTo->anLt, pFrom->anLt, sizeof(tRowcnt)*p->nCol);
+ memcpy(pTo->anDLt, pFrom->anDLt, sizeof(tRowcnt)*p->nCol);
+ if( pFrom->nRowid ){
+ sampleSetRowid(p->db, pTo, pFrom->nRowid, pFrom->u.aRowid);
+ }else{
+ sampleSetRowidInt64(p->db, pTo, pFrom->u.iRowid);
+ }
+}
+#endif
+
/*
-** 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).
+** Reclaim all memory of a Stat4Accum structure.
+*/
+static void stat4Destructor(void *pOld){
+ Stat4Accum *p = (Stat4Accum*)pOld;
+#ifdef SQLITE_ENABLE_STAT3_OR_STAT4
+ int i;
+ for(i=0; i<p->nCol; i++) sampleClear(p->db, p->aBest+i);
+ for(i=0; i<p->mxSample; i++) sampleClear(p->db, p->a+i);
+ sampleClear(p->db, &p->current);
+#endif
+ sqlite3DbFree(p->db, p);
+}
+
+/*
+** Implementation of the stat_init(N,K,C) SQL function. The three parameters
+** are:
+** N: The number of columns in the index including the rowid/pk (note 1)
+** K: The number of columns in the index excluding the rowid/pk.
+** C: The number of rows in the index (note 2)
+**
+** Note 1: In the special case of the covering index that implements a
+** WITHOUT ROWID table, N is the number of PRIMARY KEY columns, not the
+** total number of columns in the table.
+**
+** Note 2: C is only used for STAT3 and STAT4.
**
-** This routine allocates the Stat3Accum object.
+** For indexes on ordinary rowid tables, N==K+1. But for indexes on
+** WITHOUT ROWID tables, N=K+P where P is the number of columns in the
+** PRIMARY KEY of the table. The covering index that implements the
+** original WITHOUT ROWID table as N==K as a special case.
**
-** The return value is the Stat3Accum object (P).
+** This routine allocates the Stat4Accum object in heap memory. The return
+** value is a pointer to the Stat4Accum object. The datatype of the
+** return value is BLOB, but it is really just a pointer to the Stat4Accum
+** object.
*/
-static void stat3Init(
+static void statInit(
sqlite3_context *context,
int argc,
sqlite3_value **argv
){
- Stat3Accum *p;
- tRowcnt nRow;
- int mxSample;
- int n;
+ Stat4Accum *p;
+ int nCol; /* Number of columns in index being sampled */
+ int nKeyCol; /* Number of key columns */
+ int nColUp; /* nCol rounded up for alignment */
+ int n; /* Bytes of space to allocate */
+ sqlite3 *db; /* Database connection */
+#ifdef SQLITE_ENABLE_STAT3_OR_STAT4
+ int mxSample = SQLITE_STAT4_SAMPLES;
+#endif
+ /* Decode the three function arguments */
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 );
+ nCol = sqlite3_value_int(argv[0]);
+ assert( nCol>0 );
+ nColUp = sizeof(tRowcnt)<8 ? (nCol+1)&~1 : nCol;
+ nKeyCol = sqlite3_value_int(argv[1]);
+ assert( nKeyCol<=nCol );
+ assert( nKeyCol>0 );
+
+ /* Allocate the space required for the Stat4Accum object */
+ n = sizeof(*p)
+ + sizeof(tRowcnt)*nColUp /* Stat4Accum.anEq */
+ + sizeof(tRowcnt)*nColUp /* Stat4Accum.anDLt */
+#ifdef SQLITE_ENABLE_STAT3_OR_STAT4
+ + sizeof(tRowcnt)*nColUp /* Stat4Accum.anLt */
+ + sizeof(Stat4Sample)*(nCol+mxSample) /* Stat4Accum.aBest[], a[] */
+ + sizeof(tRowcnt)*3*nColUp*(nCol+mxSample)
+#endif
+ ;
+ db = sqlite3_context_db_handle(context);
+ p = sqlite3DbMallocZero(db, 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 */
+
+ p->db = db;
+ p->nRow = 0;
+ p->nCol = nCol;
+ p->nKeyCol = nKeyCol;
+ p->current.anDLt = (tRowcnt*)&p[1];
+ p->current.anEq = &p->current.anDLt[nColUp];
+
+#ifdef SQLITE_ENABLE_STAT3_OR_STAT4
+ {
+ u8 *pSpace; /* Allocated space not yet assigned */
+ int i; /* Used to iterate through p->aSample[] */
+
+ p->iGet = -1;
+ p->mxSample = mxSample;
+ p->nPSample = (tRowcnt)(sqlite3_value_int64(argv[2])/(mxSample/3+1) + 1);
+ p->current.anLt = &p->current.anEq[nColUp];
+ p->iPrn = 0x689e962d*(u32)nCol ^ 0xd0944565*(u32)sqlite3_value_int(argv[2]);
+
+ /* Set up the Stat4Accum.a[] and aBest[] arrays */
+ p->a = (struct Stat4Sample*)&p->current.anLt[nColUp];
+ p->aBest = &p->a[mxSample];
+ pSpace = (u8*)(&p->a[mxSample+nCol]);
+ for(i=0; i<(mxSample+nCol); i++){
+ p->a[i].anEq = (tRowcnt *)pSpace; pSpace += (sizeof(tRowcnt) * nColUp);
+ p->a[i].anLt = (tRowcnt *)pSpace; pSpace += (sizeof(tRowcnt) * nColUp);
+ p->a[i].anDLt = (tRowcnt *)pSpace; pSpace += (sizeof(tRowcnt) * nColUp);
+ }
+ assert( (pSpace - (u8*)p)==n );
+
+ for(i=0; i<nCol; i++){
+ p->aBest[i].iCol = i;
+ }
+ }
+#endif
+
+ /* Return a pointer to the allocated object to the caller. Note that
+ ** only the pointer (the 2nd parameter) matters. The size of the object
+ ** (given by the 3rd parameter) is never used and can be any positive
+ ** value. */
+ sqlite3_result_blob(context, p, sizeof(*p), stat4Destructor);
+}
+static const FuncDef statInitFuncdef = {
+ 2+IsStat34, /* nArg */
+ SQLITE_UTF8, /* funcFlags */
+ 0, /* pUserData */
+ 0, /* pNext */
+ statInit, /* xFunc */
+ 0, /* xStep */
+ 0, /* xFinalize */
+ "stat_init", /* zName */
+ 0, /* pHash */
+ 0 /* pDestructor */
};
+#ifdef SQLITE_ENABLE_STAT4
+/*
+** pNew and pOld are both candidate non-periodic samples selected for
+** the same column (pNew->iCol==pOld->iCol). Ignoring this column and
+** considering only any trailing columns and the sample hash value, this
+** function returns true if sample pNew is to be preferred over pOld.
+** In other words, if we assume that the cardinalities of the selected
+** column for pNew and pOld are equal, is pNew to be preferred over pOld.
+**
+** This function assumes that for each argument sample, the contents of
+** the anEq[] array from pSample->anEq[pSample->iCol+1] onwards are valid.
+*/
+static int sampleIsBetterPost(
+ Stat4Accum *pAccum,
+ Stat4Sample *pNew,
+ Stat4Sample *pOld
+){
+ int nCol = pAccum->nCol;
+ int i;
+ assert( pNew->iCol==pOld->iCol );
+ for(i=pNew->iCol+1; i<nCol; i++){
+ if( pNew->anEq[i]>pOld->anEq[i] ) return 1;
+ if( pNew->anEq[i]<pOld->anEq[i] ) return 0;
+ }
+ if( pNew->iHash>pOld->iHash ) return 1;
+ return 0;
+}
+#endif
+#ifdef SQLITE_ENABLE_STAT3_OR_STAT4
/*
-** 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.
+** Return true if pNew is to be preferred over pOld.
+**
+** This function assumes that for each argument sample, the contents of
+** the anEq[] array from pSample->anEq[pSample->iCol] onwards are valid.
+*/
+static int sampleIsBetter(
+ Stat4Accum *pAccum,
+ Stat4Sample *pNew,
+ Stat4Sample *pOld
+){
+ tRowcnt nEqNew = pNew->anEq[pNew->iCol];
+ tRowcnt nEqOld = pOld->anEq[pOld->iCol];
+
+ assert( pOld->isPSample==0 && pNew->isPSample==0 );
+ assert( IsStat4 || (pNew->iCol==0 && pOld->iCol==0) );
+
+ if( (nEqNew>nEqOld) ) return 1;
+#ifdef SQLITE_ENABLE_STAT4
+ if( nEqNew==nEqOld ){
+ if( pNew->iCol<pOld->iCol ) return 1;
+ return (pNew->iCol==pOld->iCol && sampleIsBetterPost(pAccum, pNew, pOld));
+ }
+ return 0;
+#else
+ return (nEqNew==nEqOld && pNew->iHash>pOld->iHash);
+#endif
+}
+
+/*
+** Copy the contents of sample *pNew into the p->a[] array. If necessary,
+** remove the least desirable sample from p->a[] to make room.
+*/
+static void sampleInsert(Stat4Accum *p, Stat4Sample *pNew, int nEqZero){
+ Stat4Sample *pSample = 0;
+ int i;
+
+ assert( IsStat4 || nEqZero==0 );
+
+#ifdef SQLITE_ENABLE_STAT4
+ if( pNew->isPSample==0 ){
+ Stat4Sample *pUpgrade = 0;
+ assert( pNew->anEq[pNew->iCol]>0 );
+
+ /* This sample is being added because the prefix that ends in column
+ ** iCol occurs many times in the table. However, if we have already
+ ** added a sample that shares this prefix, there is no need to add
+ ** this one. Instead, upgrade the priority of the highest priority
+ ** existing sample that shares this prefix. */
+ for(i=p->nSample-1; i>=0; i--){
+ Stat4Sample *pOld = &p->a[i];
+ if( pOld->anEq[pNew->iCol]==0 ){
+ if( pOld->isPSample ) return;
+ assert( pOld->iCol>pNew->iCol );
+ assert( sampleIsBetter(p, pNew, pOld) );
+ if( pUpgrade==0 || sampleIsBetter(p, pOld, pUpgrade) ){
+ pUpgrade = pOld;
+ }
+ }
+ }
+ if( pUpgrade ){
+ pUpgrade->iCol = pNew->iCol;
+ pUpgrade->anEq[pUpgrade->iCol] = pNew->anEq[pUpgrade->iCol];
+ goto find_new_min;
+ }
+ }
+#endif
+
+ /* If necessary, remove sample iMin to make room for the new sample. */
+ if( p->nSample>=p->mxSample ){
+ Stat4Sample *pMin = &p->a[p->iMin];
+ tRowcnt *anEq = pMin->anEq;
+ tRowcnt *anLt = pMin->anLt;
+ tRowcnt *anDLt = pMin->anDLt;
+ sampleClear(p->db, pMin);
+ memmove(pMin, &pMin[1], sizeof(p->a[0])*(p->nSample-p->iMin-1));
+ pSample = &p->a[p->nSample-1];
+ pSample->nRowid = 0;
+ pSample->anEq = anEq;
+ pSample->anDLt = anDLt;
+ pSample->anLt = anLt;
+ p->nSample = p->mxSample-1;
+ }
+
+ /* The "rows less-than" for the rowid column must be greater than that
+ ** for the last sample in the p->a[] array. Otherwise, the samples would
+ ** be out of order. */
+#ifdef SQLITE_ENABLE_STAT4
+ assert( p->nSample==0
+ || pNew->anLt[p->nCol-1] > p->a[p->nSample-1].anLt[p->nCol-1] );
+#endif
+
+ /* Insert the new sample */
+ pSample = &p->a[p->nSample];
+ sampleCopy(p, pSample, pNew);
+ p->nSample++;
+
+ /* Zero the first nEqZero entries in the anEq[] array. */
+ memset(pSample->anEq, 0, sizeof(tRowcnt)*nEqZero);
+
+#ifdef SQLITE_ENABLE_STAT4
+ find_new_min:
+#endif
+ if( p->nSample>=p->mxSample ){
+ int iMin = -1;
+ for(i=0; i<p->mxSample; i++){
+ if( p->a[i].isPSample ) continue;
+ if( iMin<0 || sampleIsBetter(p, &p->a[iMin], &p->a[i]) ){
+ iMin = i;
+ }
+ }
+ assert( iMin>=0 );
+ p->iMin = iMin;
+ }
+}
+#endif /* SQLITE_ENABLE_STAT3_OR_STAT4 */
+
+/*
+** Field iChng of the index being scanned has changed. So at this point
+** p->current contains a sample that reflects the previous row of the
+** index. The value of anEq[iChng] and subsequent anEq[] elements are
+** correct at this point.
+*/
+static void samplePushPrevious(Stat4Accum *p, int iChng){
+#ifdef SQLITE_ENABLE_STAT4
+ int i;
+
+ /* Check if any samples from the aBest[] array should be pushed
+ ** into IndexSample.a[] at this point. */
+ for(i=(p->nCol-2); i>=iChng; i--){
+ Stat4Sample *pBest = &p->aBest[i];
+ pBest->anEq[i] = p->current.anEq[i];
+ if( p->nSample<p->mxSample || sampleIsBetter(p, pBest, &p->a[p->iMin]) ){
+ sampleInsert(p, pBest, i);
+ }
+ }
+
+ /* Update the anEq[] fields of any samples already collected. */
+ for(i=p->nSample-1; i>=0; i--){
+ int j;
+ for(j=iChng; j<p->nCol; j++){
+ if( p->a[i].anEq[j]==0 ) p->a[i].anEq[j] = p->current.anEq[j];
+ }
+ }
+#endif
+
+#if defined(SQLITE_ENABLE_STAT3) && !defined(SQLITE_ENABLE_STAT4)
+ if( iChng==0 ){
+ tRowcnt nLt = p->current.anLt[0];
+ tRowcnt nEq = p->current.anEq[0];
+
+ /* Check if this is to be a periodic sample. If so, add it. */
+ if( (nLt/p->nPSample)!=(nLt+nEq)/p->nPSample ){
+ p->current.isPSample = 1;
+ sampleInsert(p, &p->current, 0);
+ p->current.isPSample = 0;
+ }else
+
+ /* Or if it is a non-periodic sample. Add it in this case too. */
+ if( p->nSample<p->mxSample
+ || sampleIsBetter(p, &p->current, &p->a[p->iMin])
+ ){
+ sampleInsert(p, &p->current, 0);
+ }
+ }
+#endif
+
+#ifndef SQLITE_ENABLE_STAT3_OR_STAT4
+ UNUSED_PARAMETER( p );
+ UNUSED_PARAMETER( iChng );
+#endif
+}
+
+/*
+** Implementation of the stat_push SQL function: stat_push(P,C,R)
+** Arguments:
+**
+** P Pointer to the Stat4Accum object created by stat_init()
+** C Index of left-most column to differ from previous row
+** R Rowid for the current row. Might be a key record for
+** WITHOUT ROWID tables.
+**
+** This SQL function always returns NULL. It's purpose it to accumulate
+** statistical data and/or samples in the Stat4Accum object about the
+** index being analyzed. The stat_get() SQL function will later be used to
+** extract relevant information for constructing the sqlite_statN tables.
**
-** The return value is NULL.
+** The R parameter is only used for STAT3 and STAT4
*/
-static void stat3Push(
+static void statPush(
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;
+ /* The three function arguments */
+ Stat4Accum *p = (Stat4Accum*)sqlite3_value_blob(argv[0]);
+ int iChng = sqlite3_value_int(argv[1]);
+
+ UNUSED_PARAMETER( argc );
+ UNUSED_PARAMETER( context );
+ assert( p->nCol>0 );
+ assert( iChng<p->nCol );
+
+ if( p->nRow==0 ){
+ /* This is the first call to this function. Do initialization. */
+ for(i=0; i<p->nCol; i++) p->current.anEq[i] = 1;
}else{
- if( nEq>p->a[iMin].nEq || (nEq==p->a[iMin].nEq && h>p->a[iMin].iHash) ){
- doInsert = 1;
+ /* Second and subsequent calls get processed here */
+ samplePushPrevious(p, iChng);
+
+ /* Update anDLt[], anLt[] and anEq[] to reflect the values that apply
+ ** to the current row of the index. */
+ for(i=0; i<iChng; i++){
+ p->current.anEq[i]++;
+ }
+ for(i=iChng; i<p->nCol; i++){
+ p->current.anDLt[i]++;
+#ifdef SQLITE_ENABLE_STAT3_OR_STAT4
+ p->current.anLt[i] += p->current.anEq[i];
+#endif
+ p->current.anEq[i] = 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];
+ p->nRow++;
+#ifdef SQLITE_ENABLE_STAT3_OR_STAT4
+ if( sqlite3_value_type(argv[2])==SQLITE_INTEGER ){
+ sampleSetRowidInt64(p->db, &p->current, sqlite3_value_int64(argv[2]));
}else{
- pSample = &p->a[p->nSample++];
+ sampleSetRowid(p->db, &p->current, sqlite3_value_bytes(argv[2]),
+ sqlite3_value_blob(argv[2]));
}
- pSample->iRowid = rowid;
- pSample->nEq = nEq;
- pSample->nLt = nLt;
- pSample->nDLt = nDLt;
- pSample->iHash = h;
- pSample->isPSample = isPSample;
+ p->current.iHash = p->iPrn = p->iPrn*1103515245 + 12345;
+#endif
- /* 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;
+#ifdef SQLITE_ENABLE_STAT4
+ {
+ tRowcnt nLt = p->current.anLt[p->nCol-1];
+
+ /* Check if this is to be a periodic sample. If so, add it. */
+ if( (nLt/p->nPSample)!=(nLt+1)/p->nPSample ){
+ p->current.isPSample = 1;
+ p->current.iCol = 0;
+ sampleInsert(p, &p->current, p->nCol-1);
+ p->current.isPSample = 0;
+ }
+
+ /* Update the aBest[] array. */
+ for(i=0; i<(p->nCol-1); i++){
+ p->current.iCol = i;
+ if( i>=iChng || sampleIsBetterPost(p, &p->current, &p->aBest[i]) ){
+ sampleCopy(p, &p->aBest[i], &p->current);
}
}
- p->iMin = iMin;
}
+#endif
}
-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 */
+static const FuncDef statPushFuncdef = {
+ 2+IsStat34, /* nArg */
+ SQLITE_UTF8, /* funcFlags */
+ 0, /* pUserData */
+ 0, /* pNext */
+ statPush, /* xFunc */
+ 0, /* xStep */
+ 0, /* xFinalize */
+ "stat_push", /* zName */
+ 0, /* pHash */
+ 0 /* pDestructor */
};
+#define STAT_GET_STAT1 0 /* "stat" column of stat1 table */
+#define STAT_GET_ROWID 1 /* "rowid" column of stat[34] entry */
+#define STAT_GET_NEQ 2 /* "neq" column of stat[34] entry */
+#define STAT_GET_NLT 3 /* "nlt" column of stat[34] entry */
+#define STAT_GET_NDLT 4 /* "ndlt" column of stat[34] entry */
+
/*
-** 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.
+** Implementation of the stat_get(P,J) SQL function. This routine is
+** used to query statistical information that has been gathered into
+** the Stat4Accum object by prior calls to stat_push(). The P parameter
+** has type BLOB but it is really just a pointer to the Stat4Accum object.
+** The content to returned is determined by the parameter J
+** which is one of the STAT_GET_xxxx values defined above.
**
-** argc==2 result: rowid
-** argc==3 result: nEq
-** argc==4 result: nLt
-** argc==5 result: nDLt
+** If neither STAT3 nor STAT4 are enabled, then J is always
+** STAT_GET_STAT1 and is hence omitted and this routine becomes
+** a one-parameter function, stat_get(P), that always returns the
+** stat1 table entry information.
*/
-static void stat3Get(
+static void statGet(
sqlite3_context *context,
int argc,
sqlite3_value **argv
){
- int n = sqlite3_value_int(argv[1]);
- Stat3Accum *p = (Stat3Accum*)sqlite3_value_blob(argv[0]);
+ Stat4Accum *p = (Stat4Accum*)sqlite3_value_blob(argv[0]);
+#ifdef SQLITE_ENABLE_STAT3_OR_STAT4
+ /* STAT3 and STAT4 have a parameter on this routine. */
+ int eCall = sqlite3_value_int(argv[1]);
+ assert( argc==2 );
+ assert( eCall==STAT_GET_STAT1 || eCall==STAT_GET_NEQ
+ || eCall==STAT_GET_ROWID || eCall==STAT_GET_NLT
+ || eCall==STAT_GET_NDLT
+ );
+ if( eCall==STAT_GET_STAT1 )
+#else
+ assert( argc==1 );
+#endif
+ {
+ /* Return the value to store in the "stat" column of the sqlite_stat1
+ ** table for this index.
+ **
+ ** The value is a string composed of a list of integers describing
+ ** 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 indexed column. This additional integer is an estimate of
+ ** the number of rows matched by a stabbing query on the index using
+ ** a key with the corresponding number of fields. In other words,
+ ** if the index is on columns (a,b) and the sqlite_stat1 value is
+ ** "100 10 2", then SQLite estimates that:
+ **
+ ** * the index contains 100 rows,
+ ** * "WHERE a=?" matches 10 rows, and
+ ** * "WHERE a=? AND b=?" matches 2 rows.
+ **
+ ** If D is the count of distinct values and K is the total number of
+ ** rows, then each estimate is computed as:
+ **
+ ** I = (K+D-1)/D
+ */
+ char *z;
+ int i;
- 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 */
+ char *zRet = sqlite3MallocZero( (p->nKeyCol+1)*25 );
+ if( zRet==0 ){
+ sqlite3_result_error_nomem(context);
+ return;
+ }
+
+ sqlite3_snprintf(24, zRet, "%llu", (u64)p->nRow);
+ z = zRet + sqlite3Strlen30(zRet);
+ for(i=0; i<p->nKeyCol; i++){
+ u64 nDistinct = p->current.anDLt[i] + 1;
+ u64 iVal = (p->nRow + nDistinct - 1) / nDistinct;
+ sqlite3_snprintf(24, z, " %llu", iVal);
+ z += sqlite3Strlen30(z);
+ assert( p->current.anEq[i] );
+ }
+ assert( z[0]=='\0' && z>zRet );
+
+ sqlite3_result_text(context, zRet, -1, sqlite3_free);
+ }
+#ifdef SQLITE_ENABLE_STAT3_OR_STAT4
+ else if( eCall==STAT_GET_ROWID ){
+ if( p->iGet<0 ){
+ samplePushPrevious(p, 0);
+ p->iGet = 0;
+ }
+ if( p->iGet<p->nSample ){
+ Stat4Sample *pS = p->a + p->iGet;
+ if( pS->nRowid==0 ){
+ sqlite3_result_int64(context, pS->u.iRowid);
+ }else{
+ sqlite3_result_blob(context, pS->u.aRowid, pS->nRowid,
+ SQLITE_TRANSIENT);
+ }
+ }
+ }else{
+ tRowcnt *aCnt = 0;
+ assert( p->iGet<p->nSample );
+ switch( eCall ){
+ case STAT_GET_NEQ: aCnt = p->a[p->iGet].anEq; break;
+ case STAT_GET_NLT: aCnt = p->a[p->iGet].anLt; break;
+ default: {
+ aCnt = p->a[p->iGet].anDLt;
+ p->iGet++;
+ break;
+ }
+ }
+ if( IsStat3 ){
+ sqlite3_result_int64(context, (i64)aCnt[0]);
+ }else{
+ char *zRet = sqlite3MallocZero(p->nCol * 25);
+ if( zRet==0 ){
+ sqlite3_result_error_nomem(context);
+ }else{
+ int i;
+ char *z = zRet;
+ for(i=0; i<p->nCol; i++){
+ sqlite3_snprintf(24, z, "%llu ", (u64)aCnt[i]);
+ z += sqlite3Strlen30(z);
+ }
+ assert( z[0]=='\0' && z>zRet );
+ z[-1] = '\0';
+ sqlite3_result_text(context, zRet, -1, sqlite3_free);
+ }
+ }
+ }
+#endif /* SQLITE_ENABLE_STAT3_OR_STAT4 */
+#ifndef SQLITE_DEBUG
+ UNUSED_PARAMETER( argc );
+#endif
+}
+static const FuncDef statGetFuncdef = {
+ 1+IsStat34, /* nArg */
+ SQLITE_UTF8, /* funcFlags */
+ 0, /* pUserData */
+ 0, /* pNext */
+ statGet, /* xFunc */
+ 0, /* xStep */
+ 0, /* xFinalize */
+ "stat_get", /* zName */
+ 0, /* pHash */
+ 0 /* pDestructor */
+};
+static void callStatGet(Vdbe *v, int regStat4, int iParam, int regOut){
+ assert( regOut!=regStat4 && regOut!=regStat4+1 );
+#ifdef SQLITE_ENABLE_STAT3_OR_STAT4
+ sqlite3VdbeAddOp2(v, OP_Integer, iParam, regStat4+1);
+#elif SQLITE_DEBUG
+ assert( iParam==STAT_GET_STAT1 );
+#else
+ UNUSED_PARAMETER( iParam );
+#endif
+ sqlite3VdbeAddOp3(v, OP_Function0, 0, regStat4, regOut);
+ sqlite3VdbeChangeP4(v, -1, (char*)&statGetFuncdef, P4_FUNCDEF);
+ sqlite3VdbeChangeP5(v, 1 + IsStat34);
+}
/*
** Generate code to do an analysis of all indices associated with
@@ -79212,41 +91943,31 @@ static void analyzeOneTable(
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 */
+ int iMem, /* Available memory locations begin here */
+ int iTab /* Next available cursor */
){
sqlite3 *db = pParse->db; /* Database handle */
Index *pIdx; /* An index to being analyzed */
int iIdxCur; /* Cursor open on index being analyzed */
+ int iTabCur; /* Table cursor */
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 */
+ u8 needTableCnt = 1; /* True to count the table */
+ int regNewRowid = iMem++; /* Rowid for the inserted record */
+ int regStat4 = iMem++; /* Register to hold Stat4Accum object */
+ int regChng = iMem++; /* Index of changed index field */
+#ifdef SQLITE_ENABLE_STAT3_OR_STAT4
+ int regRowid = iMem++; /* Rowid argument passed to stat_push() */
+#endif
+ int regTemp = iMem++; /* Temporary use register */
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 */
-
+ int regStat1 = iMem++; /* Value for the stat column of sqlite_stat1 */
+ int regPrev = iMem; /* MUST BE LAST (see below) */
+ pParse->nMem = MAX(pParse->nMem, iMem);
v = sqlite3GetVdbe(pParse);
if( v==0 || NEVER(pTab==0) ){
return;
@@ -79255,7 +91976,7 @@ static void analyzeOneTable(
/* Do not gather statistics on views or virtual tables */
return;
}
- if( memcmp(pTab->zName, "sqlite_", 7)==0 ){
+ if( sqlite3_strlike("sqlite_%", pTab->zName, 0)==0 ){
/* Do not gather statistics on system tables */
return;
}
@@ -79270,215 +91991,272 @@ static void analyzeOneTable(
}
#endif
- /* Establish a read-lock on the table at the shared-cache level. */
+ /* Establish a read-lock on the table at the shared-cache level.
+ ** Open a read-only cursor on the table. Also allocate a cursor number
+ ** to use for scanning indexes (iIdxCur). No index cursor is opened at
+ ** this time though. */
sqlite3TableLock(pParse, iDb, pTab->tnum, 0, pTab->zName);
+ iTabCur = iTab++;
+ iIdxCur = iTab++;
+ pParse->nTab = MAX(pParse->nTab, iTab);
+ sqlite3OpenTable(pParse, iTabCur, iDb, pTab, OP_OpenRead);
+ sqlite3VdbeLoadString(v, regTabname, 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 */
+ int nCol; /* Number of columns in pIdx. "N" */
+ int addrRewind; /* Address of "OP_Rewind iIdxCur" */
+ int addrNextRow; /* Address of "next_row:" */
+ const char *zIdxName; /* Name of the index */
+ int nColTest; /* Number of columns to test for changes */
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);
+ if( pIdx->pPartIdxWhere==0 ) needTableCnt = 0;
+ if( !HasRowid(pTab) && IsPrimaryKeyIndex(pIdx) ){
+ nCol = pIdx->nKeyCol;
+ zIdxName = pTab->zName;
+ nColTest = nCol - 1;
+ }else{
+ nCol = pIdx->nColumn;
+ zIdxName = pIdx->zName;
+ nColTest = pIdx->uniqNotNull ? pIdx->nKeyCol-1 : nCol-1;
}
- /* 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);
+ sqlite3VdbeLoadString(v, regIdxname, zIdxName);
+ VdbeComment((v, "Analysis for %s.%s", pTab->zName, zIdxName));
-#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.
+ /*
+ ** Pseudo-code for loop that calls stat_push():
+ **
+ ** Rewind csr
+ ** if eof(csr) goto end_of_scan;
+ ** regChng = 0
+ ** goto chng_addr_0;
**
- ** iMem:
- ** The total number of rows in the table.
+ ** next_row:
+ ** regChng = 0
+ ** if( idx(0) != regPrev(0) ) goto chng_addr_0
+ ** regChng = 1
+ ** if( idx(1) != regPrev(1) ) goto chng_addr_1
+ ** ...
+ ** regChng = N
+ ** goto chng_addr_N
**
- ** 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.
+ ** chng_addr_0:
+ ** regPrev(0) = idx(0)
+ ** chng_addr_1:
+ ** regPrev(1) = idx(1)
+ ** ...
**
- ** iMem+nCol+1 .. Mem+2*nCol:
- ** Previous value of indexed columns, from left to right.
+ ** endDistinctTest:
+ ** regRowid = idx(rowid)
+ ** stat_push(P, regChng, regRowid)
+ ** Next csr
+ ** if !eof(csr) goto next_row;
**
- ** Cells iMem through iMem+nCol are initialized to 0. The others are
- ** initialized to contain an SQL NULL.
+ ** end_of_scan:
*/
- 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 */
+ /* Make sure there are enough memory cells allocated to accommodate
+ ** the regPrev array and a trailing rowid (the rowid slot is required
+ ** when building a record to insert into the sample column of
+ ** the sqlite_stat4 table. */
+ pParse->nMem = MAX(pParse->nMem, regPrev+nColTest);
- 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);
+ /* Open a read-only cursor on the index being analyzed. */
+ assert( iDb==sqlite3SchemaToIndex(db, pIdx->pSchema) );
+ sqlite3VdbeAddOp3(v, OP_OpenRead, iIdxCur, pIdx->tnum, iDb);
+ sqlite3VdbeSetP4KeyInfo(pParse, pIdx);
+ VdbeComment((v, "%s", pIdx->zName));
- 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.
+ /* Invoke the stat_init() function. The arguments are:
+ **
+ ** (1) the number of columns in the index including the rowid
+ ** (or for a WITHOUT ROWID table, the number of PK columns),
+ ** (2) the number of columns in the key without the rowid/pk
+ ** (3) the number of rows in the index,
**
- ** 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
+ ** The third argument is only used for STAT3 and STAT4
+ */
+#ifdef SQLITE_ENABLE_STAT3_OR_STAT4
+ sqlite3VdbeAddOp2(v, OP_Count, iIdxCur, regStat4+3);
+#endif
+ sqlite3VdbeAddOp2(v, OP_Integer, nCol, regStat4+1);
+ sqlite3VdbeAddOp2(v, OP_Integer, pIdx->nKeyCol, regStat4+2);
+ sqlite3VdbeAddOp3(v, OP_Function0, 0, regStat4+1, regStat4);
+ sqlite3VdbeChangeP4(v, -1, (char*)&statInitFuncdef, P4_FUNCDEF);
+ sqlite3VdbeChangeP5(v, 2+IsStat34);
+
+ /* Implementation of the following:
+ **
+ ** Rewind csr
+ ** if eof(csr) goto end_of_scan;
+ ** regChng = 0
+ ** goto next_push_0;
**
- ** 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);
+ addrRewind = sqlite3VdbeAddOp1(v, OP_Rewind, iIdxCur);
+ VdbeCoverage(v);
+ sqlite3VdbeAddOp2(v, OP_Integer, 0, regChng);
+ addrNextRow = sqlite3VdbeCurrentAddr(v);
+
+ if( nColTest>0 ){
+ int endDistinctTest = sqlite3VdbeMakeLabel(v);
+ int *aGotoChng; /* Array of jump instruction addresses */
+ aGotoChng = sqlite3DbMallocRaw(db, sizeof(int)*nColTest);
+ if( aGotoChng==0 ) continue;
+
+ /*
+ ** next_row:
+ ** regChng = 0
+ ** if( idx(0) != regPrev(0) ) goto chng_addr_0
+ ** regChng = 1
+ ** if( idx(1) != regPrev(1) ) goto chng_addr_1
+ ** ...
+ ** regChng = N
+ ** goto endDistinctTest
+ */
+ sqlite3VdbeAddOp0(v, OP_Goto);
+ addrNextRow = sqlite3VdbeCurrentAddr(v);
+ if( nColTest==1 && pIdx->nKeyCol==1 && IsUniqueIndex(pIdx) ){
+ /* For a single-column UNIQUE index, once we have found a non-NULL
+ ** row, we know that all the rest will be distinct, so skip
+ ** subsequent distinctness tests. */
+ sqlite3VdbeAddOp2(v, OP_NotNull, regPrev, endDistinctTest);
+ VdbeCoverage(v);
+ }
+ for(i=0; i<nColTest; i++){
+ char *pColl = (char*)sqlite3LocateCollSeq(pParse, pIdx->azColl[i]);
+ sqlite3VdbeAddOp2(v, OP_Integer, i, regChng);
+ sqlite3VdbeAddOp3(v, OP_Column, iIdxCur, i, regTemp);
+ aGotoChng[i] =
+ sqlite3VdbeAddOp4(v, OP_Ne, regTemp, 0, regPrev+i, pColl, P4_COLLSEQ);
+ sqlite3VdbeChangeP5(v, SQLITE_NULLEQ);
+ VdbeCoverage(v);
+ }
+ sqlite3VdbeAddOp2(v, OP_Integer, nColTest, regChng);
+ sqlite3VdbeGoto(v, endDistinctTest);
+
+
+ /*
+ ** chng_addr_0:
+ ** regPrev(0) = idx(0)
+ ** chng_addr_1:
+ ** regPrev(1) = idx(1)
+ ** ...
+ */
+ sqlite3VdbeJumpHere(v, addrNextRow-1);
+ for(i=0; i<nColTest; i++){
+ sqlite3VdbeJumpHere(v, aGotoChng[i]);
+ sqlite3VdbeAddOp3(v, OP_Column, iIdxCur, i, regPrev+i);
+ }
+ sqlite3VdbeResolveLabel(v, endDistinctTest);
+ sqlite3DbFree(db, aGotoChng);
}
- 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);
+
+ /*
+ ** chng_addr_N:
+ ** regRowid = idx(rowid) // STAT34 only
+ ** stat_push(P, regChng, regRowid) // 3rd parameter STAT34 only
+ ** Next csr
+ ** if !eof(csr) goto next_row;
+ */
+#ifdef SQLITE_ENABLE_STAT3_OR_STAT4
+ assert( regRowid==(regStat4+2) );
+ if( HasRowid(pTab) ){
+ sqlite3VdbeAddOp2(v, OP_IdxRowid, iIdxCur, regRowid);
+ }else{
+ Index *pPk = sqlite3PrimaryKeyIndex(pIdx->pTable);
+ int j, k, regKey;
+ regKey = sqlite3GetTempRange(pParse, pPk->nKeyCol);
+ for(j=0; j<pPk->nKeyCol; j++){
+ k = sqlite3ColumnOfIndex(pIdx, pPk->aiColumn[j]);
+ assert( k>=0 && k<pTab->nCol );
+ sqlite3VdbeAddOp3(v, OP_Column, iIdxCur, k, regKey+j);
+ VdbeComment((v, "%s", pTab->aCol[pPk->aiColumn[j]].zName));
+ }
+ sqlite3VdbeAddOp3(v, OP_MakeRecord, regKey, pPk->nKeyCol, regRowid);
+ sqlite3ReleaseTempRange(pParse, regKey, pPk->nKeyCol);
+ }
+#endif
+ assert( regChng==(regStat4+1) );
+ sqlite3VdbeAddOp3(v, OP_Function0, 1, regStat4, regTemp);
+ sqlite3VdbeChangeP4(v, -1, (char*)&statPushFuncdef, P4_FUNCDEF);
+ sqlite3VdbeChangeP5(v, 2+IsStat34);
+ sqlite3VdbeAddOp2(v, OP_Next, iIdxCur, addrNextRow); VdbeCoverage(v);
+
+ /* Add the entry to the stat1 table. */
+ callStatGet(v, regStat4, STAT_GET_STAT1, regStat1);
+ assert( "BBB"[0]==SQLITE_AFF_TEXT );
+ sqlite3VdbeAddOp4(v, OP_MakeRecord, regTabname, 3, regTemp, "BBB", 0);
sqlite3VdbeAddOp2(v, OP_NewRowid, iStatCur, regNewRowid);
- sqlite3VdbeAddOp3(v, OP_Insert, iStatCur, regRec, regNewRowid);
+ sqlite3VdbeAddOp3(v, OP_Insert, iStatCur, regTemp, regNewRowid);
sqlite3VdbeChangeP5(v, OPFLAG_APPEND);
+
+ /* Add the entries to the stat3 or stat4 table. */
+#ifdef SQLITE_ENABLE_STAT3_OR_STAT4
+ {
+ int regEq = regStat1;
+ int regLt = regStat1+1;
+ int regDLt = regStat1+2;
+ int regSample = regStat1+3;
+ int regCol = regStat1+4;
+ int regSampleRowid = regCol + nCol;
+ int addrNext;
+ int addrIsNull;
+ u8 seekOp = HasRowid(pTab) ? OP_NotExists : OP_NotFound;
+
+ pParse->nMem = MAX(pParse->nMem, regCol+nCol);
+
+ addrNext = sqlite3VdbeCurrentAddr(v);
+ callStatGet(v, regStat4, STAT_GET_ROWID, regSampleRowid);
+ addrIsNull = sqlite3VdbeAddOp1(v, OP_IsNull, regSampleRowid);
+ VdbeCoverage(v);
+ callStatGet(v, regStat4, STAT_GET_NEQ, regEq);
+ callStatGet(v, regStat4, STAT_GET_NLT, regLt);
+ callStatGet(v, regStat4, STAT_GET_NDLT, regDLt);
+ sqlite3VdbeAddOp4Int(v, seekOp, iTabCur, addrNext, regSampleRowid, 0);
+ /* We know that the regSampleRowid row exists because it was read by
+ ** the previous loop. Thus the not-found jump of seekOp will never
+ ** be taken */
+ VdbeCoverageNeverTaken(v);
+#ifdef SQLITE_ENABLE_STAT3
+ sqlite3ExprCodeLoadIndexColumn(pParse, pIdx, iTabCur, 0, regSample);
+#else
+ for(i=0; i<nCol; i++){
+ sqlite3ExprCodeLoadIndexColumn(pParse, pIdx, iTabCur, i, regCol+i);
+ }
+ sqlite3VdbeAddOp3(v, OP_MakeRecord, regCol, nCol, regSample);
+#endif
+ sqlite3VdbeAddOp3(v, OP_MakeRecord, regTabname, 6, regTemp);
+ sqlite3VdbeAddOp2(v, OP_NewRowid, iStatCur+1, regNewRowid);
+ sqlite3VdbeAddOp3(v, OP_Insert, iStatCur+1, regTemp, regNewRowid);
+ sqlite3VdbeAddOp2(v, OP_Goto, 1, addrNext); /* P1==1 for end-of-loop */
+ sqlite3VdbeJumpHere(v, addrIsNull);
+ }
+#endif /* SQLITE_ENABLE_STAT3_OR_STAT4 */
+
+ /* End of analysis */
+ sqlite3VdbeJumpHere(v, addrRewind);
}
- /* 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.
+
+ /* 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);
+ if( pOnlyIdx==0 && needTableCnt ){
VdbeComment((v, "%s", pTab->zName));
- sqlite3VdbeAddOp2(v, OP_Count, iIdxCur, regStat1);
- sqlite3VdbeAddOp1(v, OP_Close, iIdxCur);
- jZeroRows = sqlite3VdbeAddOp1(v, OP_IfNot, regStat1);
- }else{
+ sqlite3VdbeAddOp2(v, OP_Count, iTabCur, regStat1);
+ jZeroRows = sqlite3VdbeAddOp1(v, OP_IfNot, regStat1); VdbeCoverage(v);
+ sqlite3VdbeAddOp2(v, OP_Null, 0, regIdxname);
+ assert( "BBB"[0]==SQLITE_AFF_TEXT );
+ sqlite3VdbeAddOp4(v, OP_MakeRecord, regTabname, 3, regTemp, "BBB", 0);
+ sqlite3VdbeAddOp2(v, OP_NewRowid, iStatCur, regNewRowid);
+ sqlite3VdbeAddOp3(v, OP_Insert, iStatCur, regTemp, regNewRowid);
+ sqlite3VdbeChangeP5(v, OPFLAG_APPEND);
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);
}
@@ -79502,16 +92280,18 @@ static void analyzeDatabase(Parse *pParse, int iDb){
HashElem *k;
int iStatCur;
int iMem;
+ int iTab;
sqlite3BeginWriteOperation(pParse, 0, iDb);
iStatCur = pParse->nTab;
pParse->nTab += 3;
openStatTable(pParse, iDb, iStatCur, 0, 0);
iMem = pParse->nMem+1;
+ iTab = pParse->nTab;
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);
+ analyzeOneTable(pParse, pTab, 0, iStatCur, iMem, iTab);
}
loadAnalysis(pParse, iDb);
}
@@ -79536,7 +92316,7 @@ static void analyzeTable(Parse *pParse, Table *pTab, Index *pOnlyIdx){
}else{
openStatTable(pParse, iDb, iStatCur, pTab->zName, "tbl");
}
- analyzeOneTable(pParse, pTab, pOnlyIdx, iStatCur, pParse->nMem+1);
+ analyzeOneTable(pParse, pTab, pOnlyIdx, iStatCur,pParse->nMem+1,pParse->nTab);
loadAnalysis(pParse, iDb);
}
@@ -79560,6 +92340,7 @@ SQLITE_PRIVATE void sqlite3Analyze(Parse *pParse, Token *pName1, Token *pName2){
Table *pTab;
Index *pIdx;
Token *pTableName;
+ Vdbe *v;
/* Read the database schema. If an error occurs, leave an error message
** and code in pParse and return NULL. */
@@ -79607,6 +92388,8 @@ SQLITE_PRIVATE void sqlite3Analyze(Parse *pParse, Token *pName1, Token *pName2){
}
}
}
+ v = sqlite3GetVdbe(pParse);
+ if( v ) sqlite3VdbeAddOp0(v, OP_Expire);
}
/*
@@ -79620,6 +92403,71 @@ struct analysisInfo {
};
/*
+** The first argument points to a nul-terminated string containing a
+** list of space separated integers. Read the first nOut of these into
+** the array aOut[].
+*/
+static void decodeIntArray(
+ char *zIntArray, /* String containing int array to decode */
+ int nOut, /* Number of slots in aOut[] */
+ tRowcnt *aOut, /* Store integers here */
+ LogEst *aLog, /* Or, if aOut==0, here */
+ Index *pIndex /* Handle extra flags for this index, if not NULL */
+){
+ char *z = zIntArray;
+ int c;
+ int i;
+ tRowcnt v;
+
+#ifdef SQLITE_ENABLE_STAT3_OR_STAT4
+ if( z==0 ) z = "";
+#else
+ assert( z!=0 );
+#endif
+ for(i=0; *z && i<nOut; i++){
+ v = 0;
+ while( (c=z[0])>='0' && c<='9' ){
+ v = v*10 + c - '0';
+ z++;
+ }
+#ifdef SQLITE_ENABLE_STAT3_OR_STAT4
+ if( aOut ) aOut[i] = v;
+ if( aLog ) aLog[i] = sqlite3LogEst(v);
+#else
+ assert( aOut==0 );
+ UNUSED_PARAMETER(aOut);
+ assert( aLog!=0 );
+ aLog[i] = sqlite3LogEst(v);
+#endif
+ if( *z==' ' ) z++;
+ }
+#ifndef SQLITE_ENABLE_STAT3_OR_STAT4
+ assert( pIndex!=0 ); {
+#else
+ if( pIndex ){
+#endif
+ pIndex->bUnordered = 0;
+ pIndex->noSkipScan = 0;
+ while( z[0] ){
+ if( sqlite3_strglob("unordered*", z)==0 ){
+ pIndex->bUnordered = 1;
+ }else if( sqlite3_strglob("sz=[0-9]*", z)==0 ){
+ pIndex->szIdxRow = sqlite3LogEst(sqlite3Atoi(z+3));
+ }else if( sqlite3_strglob("noskipscan*", z)==0 ){
+ pIndex->noSkipScan = 1;
+ }
+#ifdef SQLITE_ENABLE_COSTMULT
+ else if( sqlite3_strglob("costmult=[0-9]*",z)==0 ){
+ pIndex->pTable->costMult = sqlite3LogEst(sqlite3Atoi(z+9));
+ }
+#endif
+ while( z[0]!=0 && z[0]!=' ' ) z++;
+ while( z[0]==' ' ) z++;
+ }
+ }
+}
+
+/*
** This callback is invoked once for each index when reading the
** sqlite_stat1 table.
**
@@ -79634,8 +92482,6 @@ 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 );
@@ -79648,28 +92494,41 @@ static int analysisLoader(void *pData, int argc, char **argv, char **NotUsed){
if( pTable==0 ){
return 0;
}
- if( argv[1] ){
- pIndex = sqlite3FindIndex(pInfo->db, argv[1], pInfo->zDatabase);
- }else{
+ if( argv[1]==0 ){
pIndex = 0;
+ }else if( sqlite3_stricmp(argv[0],argv[1])==0 ){
+ pIndex = sqlite3PrimaryKeyIndex(pTable);
+ }else{
+ pIndex = sqlite3FindIndex(pInfo->db, argv[1], pInfo->zDatabase);
}
- 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;
+
+ if( pIndex ){
+ tRowcnt *aiRowEst = 0;
+ int nCol = pIndex->nKeyCol+1;
+#ifdef SQLITE_ENABLE_STAT3_OR_STAT4
+ /* Index.aiRowEst may already be set here if there are duplicate
+ ** sqlite_stat1 entries for this index. In that case just clobber
+ ** the old data with the new instead of allocating a new array. */
+ if( pIndex->aiRowEst==0 ){
+ pIndex->aiRowEst = (tRowcnt*)sqlite3MallocZero(sizeof(tRowcnt) * nCol);
+ if( pIndex->aiRowEst==0 ) pInfo->db->mallocFailed = 1;
}
+ aiRowEst = pIndex->aiRowEst;
+#endif
+ pIndex->bUnordered = 0;
+ decodeIntArray((char*)z, nCol, aiRowEst, pIndex->aiRowLogEst, pIndex);
+ if( pIndex->pPartIdxWhere==0 ) pTable->nRowLogEst = pIndex->aiRowLogEst[0];
+ }else{
+ Index fakeIdx;
+ fakeIdx.szIdxRow = pTable->szTabRow;
+#ifdef SQLITE_ENABLE_COSTMULT
+ fakeIdx.pTable = pTable;
+#endif
+ decodeIntArray((char*)z, 1, 0, &pTable->nRowLogEst, &fakeIdx);
+ pTable->szTabRow = fakeIdx.szIdxRow;
}
+
return 0;
}
@@ -79678,14 +92537,12 @@ static int analysisLoader(void *pData, int argc, char **argv, char **NotUsed){
** and its contents.
*/
SQLITE_PRIVATE void sqlite3DeleteIndexSamples(sqlite3 *db, Index *pIdx){
-#ifdef SQLITE_ENABLE_STAT3
+#ifdef SQLITE_ENABLE_STAT3_OR_STAT4
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, p->p);
}
sqlite3DbFree(db, pIdx->aSample);
}
@@ -79696,31 +92553,114 @@ SQLITE_PRIVATE void sqlite3DeleteIndexSamples(sqlite3 *db, Index *pIdx){
#else
UNUSED_PARAMETER(db);
UNUSED_PARAMETER(pIdx);
-#endif
+#endif /* SQLITE_ENABLE_STAT3_OR_STAT4 */
}
-#ifdef SQLITE_ENABLE_STAT3
+#ifdef SQLITE_ENABLE_STAT3_OR_STAT4
/*
-** Load content from the sqlite_stat3 table into the Index.aSample[]
-** arrays of all indices.
+** Populate the pIdx->aAvgEq[] array based on the samples currently
+** stored in pIdx->aSample[].
*/
-static int loadStat3(sqlite3 *db, const char *zDb){
+static void initAvgEq(Index *pIdx){
+ if( pIdx ){
+ IndexSample *aSample = pIdx->aSample;
+ IndexSample *pFinal = &aSample[pIdx->nSample-1];
+ int iCol;
+ int nCol = 1;
+ if( pIdx->nSampleCol>1 ){
+ /* If this is stat4 data, then calculate aAvgEq[] values for all
+ ** sample columns except the last. The last is always set to 1, as
+ ** once the trailing PK fields are considered all index keys are
+ ** unique. */
+ nCol = pIdx->nSampleCol-1;
+ pIdx->aAvgEq[nCol] = 1;
+ }
+ for(iCol=0; iCol<nCol; iCol++){
+ int nSample = pIdx->nSample;
+ int i; /* Used to iterate through samples */
+ tRowcnt sumEq = 0; /* Sum of the nEq values */
+ tRowcnt avgEq = 0;
+ tRowcnt nRow; /* Number of rows in index */
+ i64 nSum100 = 0; /* Number of terms contributing to sumEq */
+ i64 nDist100; /* Number of distinct values in index */
+
+ if( !pIdx->aiRowEst || iCol>=pIdx->nKeyCol || pIdx->aiRowEst[iCol+1]==0 ){
+ nRow = pFinal->anLt[iCol];
+ nDist100 = (i64)100 * pFinal->anDLt[iCol];
+ nSample--;
+ }else{
+ nRow = pIdx->aiRowEst[0];
+ nDist100 = ((i64)100 * pIdx->aiRowEst[0]) / pIdx->aiRowEst[iCol+1];
+ }
+ pIdx->nRowEst0 = nRow;
+
+ /* Set nSum to the number of distinct (iCol+1) field prefixes that
+ ** occur in the stat4 table for this index. Set sumEq to the sum of
+ ** the nEq values for column iCol for the same set (adding the value
+ ** only once where there exist duplicate prefixes). */
+ for(i=0; i<nSample; i++){
+ if( i==(pIdx->nSample-1)
+ || aSample[i].anDLt[iCol]!=aSample[i+1].anDLt[iCol]
+ ){
+ sumEq += aSample[i].anEq[iCol];
+ nSum100 += 100;
+ }
+ }
+
+ if( nDist100>nSum100 ){
+ avgEq = ((i64)100 * (nRow - sumEq))/(nDist100 - nSum100);
+ }
+ if( avgEq==0 ) avgEq = 1;
+ pIdx->aAvgEq[iCol] = avgEq;
+ }
+ }
+}
+
+/*
+** Look up an index by name. Or, if the name of a WITHOUT ROWID table
+** is supplied instead, find the PRIMARY KEY index for that table.
+*/
+static Index *findIndexOrPrimaryKey(
+ sqlite3 *db,
+ const char *zName,
+ const char *zDb
+){
+ Index *pIdx = sqlite3FindIndex(db, zName, zDb);
+ if( pIdx==0 ){
+ Table *pTab = sqlite3FindTable(db, zName, zDb);
+ if( pTab && !HasRowid(pTab) ) pIdx = sqlite3PrimaryKeyIndex(pTab);
+ }
+ return pIdx;
+}
+
+/*
+** Load the content from either the sqlite_stat4 or sqlite_stat3 table
+** into the relevant Index.aSample[] arrays.
+**
+** Arguments zSql1 and zSql2 must point to SQL statements that return
+** data equivalent to the following (statements are different for stat3,
+** see the caller of this function for details):
+**
+** zSql1: SELECT idx,count(*) FROM %Q.sqlite_stat4 GROUP BY idx
+** zSql2: SELECT idx,neq,nlt,ndlt,sample FROM %Q.sqlite_stat4
+**
+** where %Q is replaced with the database name before the SQL is executed.
+*/
+static int loadStatTbl(
+ sqlite3 *db, /* Database handle */
+ int bStat3, /* Assume single column records only */
+ const char *zSql1, /* SQL statement 1 (see above) */
+ const char *zSql2, /* SQL statement 2 (see above) */
+ const char *zDb /* Database name (e.g. "main") */
+){
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);
+ zSql = sqlite3MPrintf(db, zSql1, zDb);
if( !zSql ){
return SQLITE_NOMEM;
}
@@ -79729,30 +92669,54 @@ static int loadStat3(sqlite3 *db, const char *zDb){
if( rc ) return rc;
while( sqlite3_step(pStmt)==SQLITE_ROW ){
+ int nIdxCol = 1; /* Number of columns in stat4 records */
+
char *zIndex; /* Index name */
Index *pIdx; /* Pointer to the index object */
int nSample; /* Number of samples */
+ int nByte; /* Bytes of space required */
+ int i; /* Bytes of space required */
+ tRowcnt *pSpace;
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];
+ pIdx = findIndexOrPrimaryKey(db, zIndex, zDb);
+ assert( pIdx==0 || bStat3 || pIdx->nSample==0 );
+ /* Index.nSample is non-zero at this point if data has already been
+ ** loaded from the stat4 table. In this case ignore stat3 data. */
+ if( pIdx==0 || pIdx->nSample ) continue;
+ if( bStat3==0 ){
+ assert( !HasRowid(pIdx->pTable) || pIdx->nColumn==pIdx->nKeyCol+1 );
+ if( !HasRowid(pIdx->pTable) && IsPrimaryKeyIndex(pIdx) ){
+ nIdxCol = pIdx->nKeyCol;
+ }else{
+ nIdxCol = pIdx->nColumn;
+ }
+ }
+ pIdx->nSampleCol = nIdxCol;
+ nByte = sizeof(IndexSample) * nSample;
+ nByte += sizeof(tRowcnt) * nIdxCol * 3 * nSample;
+ nByte += nIdxCol * sizeof(tRowcnt); /* Space for Index.aAvgEq[] */
+
+ pIdx->aSample = sqlite3DbMallocZero(db, nByte);
if( pIdx->aSample==0 ){
- db->mallocFailed = 1;
sqlite3_finalize(pStmt);
return SQLITE_NOMEM;
}
+ pSpace = (tRowcnt*)&pIdx->aSample[nSample];
+ pIdx->aAvgEq = pSpace; pSpace += nIdxCol;
+ for(i=0; i<nSample; i++){
+ pIdx->aSample[i].anEq = pSpace; pSpace += nIdxCol;
+ pIdx->aSample[i].anLt = pSpace; pSpace += nIdxCol;
+ pIdx->aSample[i].anDLt = pSpace; pSpace += nIdxCol;
+ }
+ assert( ((u8*)pSpace)-nByte==(u8*)(pIdx->aSample) );
}
rc = sqlite3_finalize(pStmt);
if( rc ) return rc;
- zSql = sqlite3MPrintf(db,
- "SELECT idx,neq,nlt,ndlt,sample FROM %Q.sqlite_stat3", zDb);
+ zSql = sqlite3MPrintf(db, zSql2, zDb);
if( !zSql ){
return SQLITE_NOMEM;
}
@@ -79761,86 +92725,88 @@ static int loadStat3(sqlite3 *db, const char *zDb){
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 */
+ char *zIndex; /* Index name */
+ Index *pIdx; /* Pointer to the index object */
+ int nCol = 1; /* Number of columns in index */
zIndex = (char *)sqlite3_column_text(pStmt, 0);
if( zIndex==0 ) continue;
- pIdx = sqlite3FindIndex(db, zIndex, zDb);
+ pIdx = findIndexOrPrimaryKey(db, zIndex, zDb);
if( pIdx==0 ) continue;
- if( pIdx==pPrevIdx ){
- idx++;
- }else{
+ /* This next condition is true if data has already been loaded from
+ ** the sqlite_stat4 table. In this case ignore stat3 data. */
+ nCol = pIdx->nSampleCol;
+ if( bStat3 && nCol>1 ) continue;
+ if( pIdx!=pPrevIdx ){
+ initAvgEq(pPrevIdx);
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);
- }
- }
}
+ pSample = &pIdx->aSample[pIdx->nSample];
+ decodeIntArray((char*)sqlite3_column_text(pStmt,1),nCol,pSample->anEq,0,0);
+ decodeIntArray((char*)sqlite3_column_text(pStmt,2),nCol,pSample->anLt,0,0);
+ decodeIntArray((char*)sqlite3_column_text(pStmt,3),nCol,pSample->anDLt,0,0);
+
+ /* Take a copy of the sample. Add two 0x00 bytes the end of the buffer.
+ ** This is in case the sample record is corrupted. In that case, the
+ ** sqlite3VdbeRecordCompare() may read up to two varints past the
+ ** end of the allocated buffer before it realizes it is dealing with
+ ** a corrupt record. Adding the two 0x00 bytes prevents this from causing
+ ** a buffer overread. */
+ pSample->n = sqlite3_column_bytes(pStmt, 4);
+ pSample->p = sqlite3DbMallocZero(db, pSample->n + 2);
+ if( pSample->p==0 ){
+ sqlite3_finalize(pStmt);
+ return SQLITE_NOMEM;
+ }
+ memcpy(pSample->p, sqlite3_column_blob(pStmt, 4), pSample->n);
+ pIdx->nSample++;
}
- return sqlite3_finalize(pStmt);
+ rc = sqlite3_finalize(pStmt);
+ if( rc==SQLITE_OK ) initAvgEq(pPrevIdx);
+ return rc;
}
-#endif /* SQLITE_ENABLE_STAT3 */
/*
-** Load the content of the sqlite_stat1 and sqlite_stat3 tables. The
+** Load content from the sqlite_stat4 and sqlite_stat3 tables into
+** the Index.aSample[] arrays of all indices.
+*/
+static int loadStat4(sqlite3 *db, const char *zDb){
+ int rc = SQLITE_OK; /* Result codes from subroutines */
+
+ assert( db->lookaside.bEnabled==0 );
+ if( sqlite3FindTable(db, "sqlite_stat4", zDb) ){
+ rc = loadStatTbl(db, 0,
+ "SELECT idx,count(*) FROM %Q.sqlite_stat4 GROUP BY idx",
+ "SELECT idx,neq,nlt,ndlt,sample FROM %Q.sqlite_stat4",
+ zDb
+ );
+ }
+
+ if( rc==SQLITE_OK && sqlite3FindTable(db, "sqlite_stat3", zDb) ){
+ rc = loadStatTbl(db, 1,
+ "SELECT idx,count(*) FROM %Q.sqlite_stat3 GROUP BY idx",
+ "SELECT idx,neq,nlt,ndlt,sqlite_record(sample) FROM %Q.sqlite_stat3",
+ zDb
+ );
+ }
+
+ return rc;
+}
+#endif /* SQLITE_ENABLE_STAT3_OR_STAT4 */
+
+/*
+** Load the content of the sqlite_stat1 and sqlite_stat3/4 tables. The
** contents of sqlite_stat1 are used to populate the Index.aiRowEst[]
-** arrays. The contents of sqlite_stat3 are used to populate the
+** arrays. The contents of sqlite_stat3/4 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
+** is returned. In this case, even if SQLITE_ENABLE_STAT3/4 was defined
+** during compilation and the sqlite_stat3/4 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
+** If SQLITE_ENABLE_STAT3/4 was defined during compilation and the
+** sqlite_stat4 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.
**
@@ -79862,7 +92828,7 @@ SQLITE_PRIVATE int sqlite3AnalysisLoad(sqlite3 *db, int iDb){
for(i=sqliteHashFirst(&db->aDb[iDb].pSchema->idxHash);i;i=sqliteHashNext(i)){
Index *pIdx = sqliteHashData(i);
sqlite3DefaultRowEst(pIdx);
-#ifdef SQLITE_ENABLE_STAT3
+#ifdef SQLITE_ENABLE_STAT3_OR_STAT4
sqlite3DeleteIndexSamples(db, pIdx);
pIdx->aSample = 0;
#endif
@@ -79886,14 +92852,19 @@ SQLITE_PRIVATE int sqlite3AnalysisLoad(sqlite3 *db, int iDb){
}
- /* Load the statistics from the sqlite_stat3 table. */
-#ifdef SQLITE_ENABLE_STAT3
- if( rc==SQLITE_OK ){
+ /* Load the statistics from the sqlite_stat4 table. */
+#ifdef SQLITE_ENABLE_STAT3_OR_STAT4
+ if( rc==SQLITE_OK && OptimizationEnabled(db, SQLITE_Stat34) ){
int lookasideEnabled = db->lookaside.bEnabled;
db->lookaside.bEnabled = 0;
- rc = loadStat3(db, sInfo.zDatabase);
+ rc = loadStat4(db, sInfo.zDatabase);
db->lookaside.bEnabled = lookasideEnabled;
}
+ for(i=sqliteHashFirst(&db->aDb[iDb].pSchema->idxHash);i;i=sqliteHashNext(i)){
+ Index *pIdx = sqliteHashData(i);
+ sqlite3_free(pIdx->aiRowEst);
+ pIdx->aiRowEst = 0;
+ }
#endif
if( rc==SQLITE_NOMEM ){
@@ -79920,6 +92891,7 @@ SQLITE_PRIVATE int sqlite3AnalysisLoad(sqlite3 *db, int iDb){
*************************************************************************
** This file contains code used to implement the ATTACH and DETACH commands.
*/
+/* #include "sqliteInt.h" */
#ifndef SQLITE_OMIT_ATTACH
/*
@@ -79946,10 +92918,6 @@ static int resolveAttachExpr(NameContext *pName, Expr *pExpr)
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;
}
@@ -80017,7 +92985,7 @@ static void attachFunc(
}
}
- /* Allocate the new entry in the db->aDb[] array and initialise the schema
+ /* Allocate the new entry in the db->aDb[] array and initialize the schema
** hash tables.
*/
if( db->aDb==db->aDbStatic ){
@@ -80034,7 +93002,7 @@ static void attachFunc(
/* 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.
+ ** or may not be initialized.
*/
flags = db->openFlags;
rc = sqlite3ParseUri(db->pVfs->zName, zFile, &flags, &pVfs, &zPath, &zErr);
@@ -80062,10 +93030,15 @@ static void attachFunc(
"attached databases must use the same text encoding as main database");
rc = SQLITE_ERROR;
}
+ sqlite3BtreeEnter(aNew->pBt);
pPager = sqlite3BtreePager(aNew->pBt);
sqlite3PagerLockingMode(pPager, db->dfltLockMode);
sqlite3BtreeSecureDelete(aNew->pBt,
sqlite3BtreeSecureDelete(db->aDb[0].pBt,-1) );
+#ifndef SQLITE_OMIT_PAGER_PRAGMAS
+ sqlite3BtreeSetPagerFlags(aNew->pBt, 3 | (db->flags & PAGER_FLAGS_MASK));
+#endif
+ sqlite3BtreeLeave(aNew->pBt);
}
aNew->safety_level = 3;
aNew->zName = sqlite3DbStrDup(db, zName);
@@ -80098,7 +93071,7 @@ static void attachFunc(
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 ){
+ if( nKey>0 || sqlite3BtreeGetOptimalReserve(db->aDb[0].pBt)>0 ){
rc = sqlite3CodecAttach(db, db->nDb-1, zKey, nKey);
}
break;
@@ -80116,6 +93089,15 @@ static void attachFunc(
rc = sqlite3Init(db, &zErrDyn);
sqlite3BtreeLeaveAll(db);
}
+#ifdef SQLITE_USER_AUTHENTICATION
+ if( rc==SQLITE_OK ){
+ u8 newAuth = 0;
+ rc = sqlite3UserAuthCheckLogin(db, zName, &newAuth);
+ if( newAuth<db->auth.authLevel ){
+ rc = SQLITE_AUTH_USER;
+ }
+ }
+#endif
if( rc ){
int iDb = db->nDb - 1;
assert( iDb>=2 );
@@ -80196,7 +93178,7 @@ static void detachFunc(
sqlite3BtreeClose(pDb->pBt);
pDb->pBt = 0;
pDb->pSchema = 0;
- sqlite3ResetAllSchemasOfConnection(db);
+ sqlite3CollapseDatabaseArray(db);
return;
detach_error:
@@ -80230,7 +93212,6 @@ static void codeAttach(
SQLITE_OK!=(rc = resolveAttachExpr(&sName, pDbname)) ||
SQLITE_OK!=(rc = resolveAttachExpr(&sName, pKey))
){
- pParse->nErr++;
goto attach_end;
}
@@ -80258,7 +93239,7 @@ static void codeAttach(
assert( v || db->mallocFailed );
if( v ){
- sqlite3VdbeAddOp3(v, OP_Function, 0, regArgs+3-pFunc->nArg, regArgs+3);
+ sqlite3VdbeAddOp3(v, OP_Function0, 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);
@@ -80284,8 +93265,7 @@ attach_end:
SQLITE_PRIVATE void sqlite3Detach(Parse *pParse, Expr *pDbname){
static const FuncDef detach_func = {
1, /* nArg */
- SQLITE_UTF8, /* iPrefEnc */
- 0, /* flags */
+ SQLITE_UTF8, /* funcFlags */
0, /* pUserData */
0, /* pNext */
detachFunc, /* xFunc */
@@ -80306,8 +93286,7 @@ SQLITE_PRIVATE void sqlite3Detach(Parse *pParse, Expr *pDbname){
SQLITE_PRIVATE void sqlite3Attach(Parse *pParse, Expr *p, Expr *pDbname, Expr *pKey){
static const FuncDef attach_func = {
3, /* nArg */
- SQLITE_UTF8, /* iPrefEnc */
- 0, /* flags */
+ SQLITE_UTF8, /* funcFlags */
0, /* pUserData */
0, /* pNext */
attachFunc, /* xFunc */
@@ -80324,11 +93303,8 @@ SQLITE_PRIVATE void sqlite3Attach(Parse *pParse, Expr *p, Expr *pDbname, Expr *p
/*
** 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(
+SQLITE_PRIVATE void 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 */
@@ -80337,7 +93313,6 @@ SQLITE_PRIVATE int sqlite3FixInit(
){
sqlite3 *db;
- if( NEVER(iDb<0) || iDb==1 ) return 0;
db = pParse->db;
assert( db->nDb>iDb );
pFix->pParse = pParse;
@@ -80345,7 +93320,7 @@ SQLITE_PRIVATE int sqlite3FixInit(
pFix->pSchema = db->aDb[iDb].pSchema;
pFix->zType = zType;
pFix->pName = pName;
- return 1;
+ pFix->bVarOnly = (iDb==1);
}
/*
@@ -80373,15 +93348,17 @@ SQLITE_PRIVATE int sqlite3FixSrcList(
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;
+ if( pFix->bVarOnly==0 ){
+ 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;
}
- 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;
@@ -80404,9 +93381,21 @@ SQLITE_PRIVATE int sqlite3FixSelect(
if( sqlite3FixExpr(pFix, pSelect->pWhere) ){
return 1;
}
+ if( sqlite3FixExprList(pFix, pSelect->pGroupBy) ){
+ return 1;
+ }
if( sqlite3FixExpr(pFix, pSelect->pHaving) ){
return 1;
}
+ if( sqlite3FixExprList(pFix, pSelect->pOrderBy) ){
+ return 1;
+ }
+ if( sqlite3FixExpr(pFix, pSelect->pLimit) ){
+ return 1;
+ }
+ if( sqlite3FixExpr(pFix, pSelect->pOffset) ){
+ return 1;
+ }
pSelect = pSelect->pPrior;
}
return 0;
@@ -80416,7 +93405,15 @@ SQLITE_PRIVATE int sqlite3FixExpr(
Expr *pExpr /* The expression to be fixed to one database */
){
while( pExpr ){
- if( ExprHasAnyProperty(pExpr, EP_TokenOnly) ) break;
+ if( pExpr->op==TK_VARIABLE ){
+ if( pFix->pParse->db->init.busy ){
+ pExpr->op = TK_NULL;
+ }else{
+ sqlite3ErrorMsg(pFix->pParse, "%s cannot use variables", pFix->zType);
+ return 1;
+ }
+ }
+ if( ExprHasProperty(pExpr, EP_TokenOnly) ) break;
if( ExprHasProperty(pExpr, EP_xIsSelect) ){
if( sqlite3FixSelect(pFix, pExpr->x.pSelect) ) return 1;
}else{
@@ -80484,6 +93481,7 @@ SQLITE_PRIVATE int sqlite3FixTriggerStep(
** systems that do not need this facility may omit it by recompiling
** the library with -DSQLITE_OMIT_AUTHORIZATION=1
*/
+/* #include "sqliteInt.h" */
/*
** All of the code in this file may be omitted by defining a single
@@ -80536,13 +93534,16 @@ SQLITE_PRIVATE int sqlite3FixTriggerStep(
** Setting the auth function to NULL disables this hook. The default
** setting of the auth function is NULL.
*/
-SQLITE_API int sqlite3_set_authorizer(
+SQLITE_API int SQLITE_STDCALL sqlite3_set_authorizer(
sqlite3 *db,
int (*xAuth)(void*,int,const char*,const char*,const char*,const char*),
void *pArg
){
+#ifdef SQLITE_ENABLE_API_ARMOR
+ if( !sqlite3SafetyCheckOk(db) ) return SQLITE_MISUSE_BKPT;
+#endif
sqlite3_mutex_enter(db->mutex);
- db->xAuth = xAuth;
+ db->xAuth = (sqlite3_xauth)xAuth;
db->pAuthArg = pArg;
sqlite3ExpirePreparedStatements(db);
sqlite3_mutex_leave(db->mutex);
@@ -80577,7 +93578,11 @@ SQLITE_PRIVATE int sqlite3AuthReadCol(
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);
+ rc = db->xAuth(db->pAuthArg, SQLITE_READ, zTab,zCol,zDb,pParse->zAuthContext
+#ifdef SQLITE_USER_AUTHENTICATION
+ ,db->auth.zAuthUser
+#endif
+ );
if( rc==SQLITE_DENY ){
if( db->nDb>2 || iDb!=0 ){
sqlite3ErrorMsg(pParse, "access to %s.%s.%s is prohibited",zDb,zTab,zCol);
@@ -80677,7 +93682,11 @@ SQLITE_PRIVATE int sqlite3AuthCheck(
if( db->xAuth==0 ){
return SQLITE_OK;
}
- rc = db->xAuth(db->pAuthArg, code, zArg1, zArg2, zArg3, pParse->zAuthContext);
+ rc = db->xAuth(db->pAuthArg, code, zArg1, zArg2, zArg3, pParse->zAuthContext
+#ifdef SQLITE_USER_AUTHENTICATION
+ ,db->auth.zAuthUser
+#endif
+ );
if( rc==SQLITE_DENY ){
sqlite3ErrorMsg(pParse, "not authorized");
pParse->rc = SQLITE_AUTH;
@@ -80743,6 +93752,7 @@ SQLITE_PRIVATE void sqlite3AuthContextPop(AuthContext *pContext){
** COMMIT
** ROLLBACK
*/
+/* #include "sqliteInt.h" */
/*
** This routine is called when a new SQL statement is beginning to
@@ -80834,6 +93844,19 @@ static void codeTableLocks(Parse *pParse){
#endif
/*
+** Return TRUE if the given yDbMask object is empty - if it contains no
+** 1 bits. This routine is used by the DbMaskAllZero() and DbMaskNotZero()
+** macros when SQLITE_MAX_ATTACHED is greater than 30.
+*/
+#if SQLITE_MAX_ATTACHED>30
+SQLITE_PRIVATE int sqlite3DbMaskAllZero(yDbMask m){
+ int i;
+ for(i=0; i<sizeof(yDbMask); i++) if( m[i] ) return 0;
+ return 1;
+}
+#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
@@ -80849,9 +93872,11 @@ SQLITE_PRIVATE void sqlite3FinishCoding(Parse *pParse){
assert( pParse->pToplevel==0 );
db = pParse->db;
- if( db->mallocFailed ) return;
if( pParse->nested ) return;
- if( pParse->nErr ) return;
+ if( db->mallocFailed || pParse->nErr ){
+ if( pParse->rc==SQLITE_OK ) pParse->rc = SQLITE_ERROR;
+ return;
+ }
/* Begin by generating some termination code at the end of the
** vdbe program
@@ -80860,38 +93885,52 @@ SQLITE_PRIVATE void sqlite3FinishCoding(Parse *pParse){
assert( !pParse->isMultiWrite
|| sqlite3VdbeAssertMayAbort(v, pParse->mayAbort));
if( v ){
+ while( sqlite3VdbeDeletePriorOpcode(v, OP_Close) ){}
sqlite3VdbeAddOp0(v, OP_Halt);
+#if SQLITE_USER_AUTHENTICATION
+ if( pParse->nTableLock>0 && db->init.busy==0 ){
+ sqlite3UserAuthInit(db);
+ if( db->auth.authLevel<UAUTH_User ){
+ pParse->rc = SQLITE_AUTH_USER;
+ sqlite3ErrorMsg(pParse, "user not authenticated");
+ return;
+ }
+ }
+#endif
+
/* 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;
+ if( db->mallocFailed==0
+ && (DbMaskNonZero(pParse->cookieMask) || pParse->pConstExpr)
+ ){
+ int iDb, i;
+ assert( sqlite3VdbeGetOp(v, 0)->opcode==OP_Init );
+ sqlite3VdbeJumpHere(v, 0);
+ for(iDb=0; iDb<db->nDb; iDb++){
+ if( DbMaskTest(pParse->cookieMask, iDb)==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);
- }
+ sqlite3VdbeAddOp4Int(v,
+ OP_Transaction, /* Opcode */
+ iDb, /* P1 */
+ DbMaskTest(pParse->writeMask,iDb), /* P2 */
+ pParse->cookieValue[iDb], /* P3 */
+ db->aDb[iDb].pSchema->iGeneration /* P4 */
+ );
+ if( db->init.busy==0 ) sqlite3VdbeChangeP5(v, 1);
+ VdbeComment((v,
+ "usesStmtJournal=%d", pParse->mayAbort && pParse->isMultiWrite));
}
#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;
+ 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,
@@ -80904,19 +93943,24 @@ SQLITE_PRIVATE void sqlite3FinishCoding(Parse *pParse){
*/
sqlite3AutoincrementBegin(pParse);
+ /* Code constant expressions that where factored out of inner loops */
+ if( pParse->pConstExpr ){
+ ExprList *pEL = pParse->pConstExpr;
+ pParse->okConstFactor = 0;
+ for(i=0; i<pEL->nExpr; i++){
+ sqlite3ExprCode(pParse, pEL->a[i].pExpr, pEL->a[i].u.iConstExprReg);
+ }
+ }
+
/* Finally, jump back to the beginning of the executable code. */
- sqlite3VdbeAddOp2(v, OP_Goto, 0, pParse->cookieGoto);
+ sqlite3VdbeGoto(v, 1);
}
}
/* 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
+ if( v && pParse->nErr==0 && !db->mallocFailed ){
assert( pParse->iCacheLevel==0 ); /* Disables and re-enables match */
/* A minimum of one cursor is required if autoincrement is used
* See ticket [a696379c1f08866] */
@@ -80931,8 +93975,7 @@ SQLITE_PRIVATE void sqlite3FinishCoding(Parse *pParse){
pParse->nMem = 0;
pParse->nSet = 0;
pParse->nVar = 0;
- pParse->cookieMask = 0;
- pParse->cookieGoto = 0;
+ DbMaskZero(pParse->cookieMask);
}
/*
@@ -80973,6 +94016,16 @@ SQLITE_PRIVATE void sqlite3NestedParse(Parse *pParse, const char *zFormat, ...){
pParse->nested--;
}
+#if SQLITE_USER_AUTHENTICATION
+/*
+** Return TRUE if zTable is the name of the system table that stores the
+** list of users and their access credentials.
+*/
+SQLITE_PRIVATE int sqlite3UserAuthTable(const char *zTable){
+ return sqlite3_stricmp(zTable, "sqlite_user")==0;
+}
+#endif
+
/*
** Locate the in-memory structure that describes a particular database
** table given the name of that table and (optionally) the name of the
@@ -80988,16 +94041,21 @@ SQLITE_PRIVATE void sqlite3NestedParse(Parse *pParse, const char *zFormat, ...){
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) );
+#if SQLITE_USER_AUTHENTICATION
+ /* Only the admin user is allowed to know that the sqlite_user table
+ ** exists */
+ if( db->auth.authLevel<UAUTH_Admin && sqlite3UserAuthTable(zName)!=0 ){
+ return 0;
+ }
+#endif
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);
+ p = sqlite3HashFind(&db->aDb[j].pSchema->tblHash, zName);
if( p ) break;
}
return p;
@@ -81030,6 +94088,17 @@ SQLITE_PRIVATE Table *sqlite3LocateTable(
p = sqlite3FindTable(pParse->db, zName, zDbase);
if( p==0 ){
const char *zMsg = isView ? "no such view" : "no such table";
+#ifndef SQLITE_OMIT_VIRTUALTABLE
+ if( sqlite3FindDbName(pParse->db, zDbase)<1 ){
+ /* If zName is the not the name of a table in the schema created using
+ ** CREATE, then check to see if it is the name of an virtual table that
+ ** can be an eponymous virtual table. */
+ Module *pMod = (Module*)sqlite3HashFind(&pParse->db->aModule, zName);
+ if( pMod && sqlite3VtabEponymousTableInit(pParse, pMod) ){
+ return pMod->pEpoTab;
+ }
+ }
+#endif
if( zDbase ){
sqlite3ErrorMsg(pParse, "%s: %s.%s", zMsg, zDbase, zName);
}else{
@@ -81037,6 +94106,7 @@ SQLITE_PRIVATE Table *sqlite3LocateTable(
}
pParse->checkSchema = 1;
}
+
return p;
}
@@ -81080,7 +94150,6 @@ SQLITE_PRIVATE Table *sqlite3LocateTableItem(
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++){
@@ -81089,7 +94158,7 @@ SQLITE_PRIVATE Index *sqlite3FindIndex(sqlite3 *db, const char *zName, const cha
assert( pSchema );
if( zDb && sqlite3StrICmp(zDb, db->aDb[j].zName) ) continue;
assert( sqlite3SchemaMutexHeld(db, j, 0) );
- p = sqlite3HashFind(&pSchema->idxHash, zName, nName);
+ p = sqlite3HashFind(&pSchema->idxHash, zName);
if( p ) break;
}
return p;
@@ -81102,7 +94171,13 @@ static void freeIndex(sqlite3 *db, Index *p){
#ifndef SQLITE_OMIT_ANALYZE
sqlite3DeleteIndexSamples(db, p);
#endif
+ sqlite3ExprDelete(db, p->pPartIdxWhere);
+ sqlite3ExprListDelete(db, p->aColExpr);
sqlite3DbFree(db, p->zColAff);
+ if( p->isResized ) sqlite3DbFree(db, (void *)p->azColl);
+#ifdef SQLITE_ENABLE_STAT3_OR_STAT4
+ sqlite3_free(p->aiRowEst);
+#endif
sqlite3DbFree(db, p);
}
@@ -81114,13 +94189,11 @@ static void freeIndex(sqlite3 *db, Index *p){
*/
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);
+ pIndex = sqlite3HashInsert(pHash, zIdxName, 0);
if( ALWAYS(pIndex) ){
if( pIndex->pTable->pIndex==pIndex ){
pIndex->pTable->pIndex = pIndex->pNext;
@@ -81226,7 +94299,7 @@ SQLITE_PRIVATE void sqlite3CommitInternalChanges(sqlite3 *db){
** Delete memory allocated for the column names of a table or view (the
** Table.aCol[] array).
*/
-static void sqliteDeleteColumnNames(sqlite3 *db, Table *pTable){
+SQLITE_PRIVATE void sqlite3DeleteColumnNames(sqlite3 *db, Table *pTable){
int i;
Column *pCol;
assert( pTable!=0 );
@@ -81280,7 +94353,7 @@ SQLITE_PRIVATE void sqlite3DeleteTable(sqlite3 *db, Table *pTable){
if( !db || db->pnBytesFreed==0 ){
char *zName = pIndex->zName;
TESTONLY ( Index *pOld = ) sqlite3HashInsert(
- &pIndex->pSchema->idxHash, zName, sqlite3Strlen30(zName), 0
+ &pIndex->pSchema->idxHash, zName, 0
);
assert( db==0 || sqlite3SchemaMutexHeld(db, 0, pIndex->pSchema) );
assert( pOld==pIndex || pOld==0 );
@@ -81293,13 +94366,11 @@ SQLITE_PRIVATE void sqlite3DeleteTable(sqlite3 *db, Table *pTable){
/* Delete the Table structure itself.
*/
- sqliteDeleteColumnNames(db, pTable);
+ sqlite3DeleteColumnNames(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
@@ -81323,8 +94394,7 @@ SQLITE_PRIVATE void sqlite3UnlinkAndDeleteTable(sqlite3 *db, int iDb, const char
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);
+ p = sqlite3HashInsert(&pDb->pSchema->tblHash, zTabName, 0);
sqlite3DeleteTable(db, p);
db->flags |= SQLITE_InternChanges;
}
@@ -81360,8 +94430,7 @@ SQLITE_PRIVATE char *sqlite3NameFromToken(sqlite3 *db, Token *pName){
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 */
+ sqlite3VdbeAddOp4Int(v, OP_OpenWrite, 0, MASTER_ROOT, iDb, 5);
if( p->nTab==0 ){
p->nTab = 1;
}
@@ -81431,14 +94500,12 @@ SQLITE_PRIVATE int sqlite3TwoPartName(
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{
@@ -81467,6 +94534,27 @@ SQLITE_PRIVATE int sqlite3CheckObjectName(Parse *pParse, const char *zName){
}
/*
+** Return the PRIMARY KEY index of a table
+*/
+SQLITE_PRIVATE Index *sqlite3PrimaryKeyIndex(Table *pTab){
+ Index *p;
+ for(p=pTab->pIndex; p && !IsPrimaryKeyIndex(p); p=p->pNext){}
+ return p;
+}
+
+/*
+** Return the column of index pIdx that corresponds to table
+** column iCol. Return -1 if not found.
+*/
+SQLITE_PRIVATE i16 sqlite3ColumnOfIndex(Index *pIdx, i16 iCol){
+ int i;
+ for(i=0; i<pIdx->nColumn; i++){
+ if( iCol==pIdx->aiColumn[i] ) return i;
+ }
+ return -1;
+}
+
+/*
** 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
@@ -81576,7 +94664,7 @@ SQLITE_PRIVATE void sqlite3StartTable(
if( !noErr ){
sqlite3ErrorMsg(pParse, "table %T already exists", pName);
}else{
- assert( !db->init.busy );
+ assert( !db->init.busy || CORRUPT_DB );
sqlite3CodeVerifySchema(pParse, iDb);
}
goto begin_table_error;
@@ -81598,7 +94686,7 @@ SQLITE_PRIVATE void sqlite3StartTable(
pTable->iPKey = -1;
pTable->pSchema = db->aDb[iDb].pSchema;
pTable->nRef = 1;
- pTable->nRowEst = 1000000;
+ pTable->nRowLogEst = 200; assert( 200==sqlite3LogEst(1048576) );
assert( pParse->pNewTable==0 );
pParse->pNewTable = pTable;
@@ -81622,10 +94710,12 @@ SQLITE_PRIVATE void sqlite3StartTable(
** now.
*/
if( !db->init.busy && (v = sqlite3GetVdbe(pParse))!=0 ){
- int j1;
+ int addr1;
int fileFormat;
int reg1, reg2, reg3;
- sqlite3BeginWriteOperation(pParse, 0, iDb);
+ /* nullRow[] is an OP_Record encoding of a row containing 5 NULLs */
+ static const char nullRow[] = { 6, 0, 0, 0, 0, 0 };
+ sqlite3BeginWriteOperation(pParse, 1, iDb);
#ifndef SQLITE_OMIT_VIRTUALTABLE
if( isVirtual ){
@@ -81641,14 +94731,14 @@ SQLITE_PRIVATE void sqlite3StartTable(
reg3 = ++pParse->nMem;
sqlite3VdbeAddOp3(v, OP_ReadCookie, iDb, reg3, BTREE_FILE_FORMAT);
sqlite3VdbeUsesBtree(v, iDb);
- j1 = sqlite3VdbeAddOp1(v, OP_If, reg3);
+ addr1 = sqlite3VdbeAddOp1(v, OP_If, reg3); VdbeCoverage(v);
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);
+ sqlite3VdbeJumpHere(v, addr1);
/* This just creates a place-holder record in the sqlite_master table.
** The record created does not contain anything yet. It will be replaced
@@ -81665,11 +94755,11 @@ SQLITE_PRIVATE void sqlite3StartTable(
}else
#endif
{
- sqlite3VdbeAddOp2(v, OP_CreateTable, iDb, reg2);
+ pParse->addrCrTab = sqlite3VdbeAddOp2(v, OP_CreateTable, iDb, reg2);
}
sqlite3OpenMasterTable(pParse, iDb);
sqlite3VdbeAddOp2(v, OP_NewRowid, 0, reg1);
- sqlite3VdbeAddOp2(v, OP_Null, 0, reg3);
+ sqlite3VdbeAddOp4(v, OP_Blob, 6, reg3, 0, nullRow, P4_STATIC);
sqlite3VdbeAddOp3(v, OP_Insert, 0, reg3, reg1);
sqlite3VdbeChangeP5(v, OPFLAG_APPEND);
sqlite3VdbeAddOp0(v, OP_Close);
@@ -81684,18 +94774,19 @@ begin_table_error:
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.
+/* Set properties of a table column based on the (magical)
+** name of the column.
*/
-#define STRICMP(x, y) (\
-sqlite3UpperToLower[*(unsigned char *)(x)]== \
-sqlite3UpperToLower[*(unsigned char *)(y)] \
-&& sqlite3StrICmp((x)+1,(y)+1)==0 )
+#if SQLITE_ENABLE_HIDDEN_COLUMNS
+SQLITE_PRIVATE void sqlite3ColumnPropertiesFromName(Table *pTab, Column *pCol){
+ if( sqlite3_strnicmp(pCol->zName, "__hidden__", 10)==0 ){
+ pCol->colFlags |= COLFLAG_HIDDEN;
+ }else if( pTab && pCol!=pTab->aCol && (pCol[-1].colFlags & COLFLAG_HIDDEN) ){
+ pTab->tabFlags |= TF_OOOHidden;
+ }
+}
+#endif
+
/*
** Add a new column to the table currently being constructed.
@@ -81721,7 +94812,7 @@ SQLITE_PRIVATE void sqlite3AddColumn(Parse *pParse, Token *pName){
z = sqlite3NameFromToken(db, pName);
if( z==0 ) return;
for(i=0; i<p->nCol; i++){
- if( STRICMP(z, p->aCol[i].zName) ){
+ if( sqlite3_stricmp(z, p->aCol[i].zName)==0 ){
sqlite3ErrorMsg(pParse, "duplicate column name: %s", z);
sqlite3DbFree(db, z);
return;
@@ -81739,12 +94830,14 @@ SQLITE_PRIVATE void sqlite3AddColumn(Parse *pParse, Token *pName){
pCol = &p->aCol[p->nCol];
memset(pCol, 0, sizeof(p->aCol[0]));
pCol->zName = z;
+ sqlite3ColumnPropertiesFromName(p, pCol);
/* If there is no type specified, columns have the default affinity
- ** 'NONE'. If there is a type specified, then sqlite3AddColumnType() will
+ ** 'BLOB'. If there is a type specified, then sqlite3AddColumnType() will
** be called next to set pCol->affinity correctly.
*/
- pCol->affinity = SQLITE_AFF_NONE;
+ pCol->affinity = SQLITE_AFF_BLOB;
+ pCol->szEst = 1;
p->nCol++;
}
@@ -81778,7 +94871,7 @@ SQLITE_PRIVATE void sqlite3AddNotNull(Parse *pParse, int onError){
** 'CHAR' | SQLITE_AFF_TEXT
** 'CLOB' | SQLITE_AFF_TEXT
** 'TEXT' | SQLITE_AFF_TEXT
-** 'BLOB' | SQLITE_AFF_NONE
+** 'BLOB' | SQLITE_AFF_BLOB
** 'REAL' | SQLITE_AFF_REAL
** 'FLOA' | SQLITE_AFF_REAL
** 'DOUB' | SQLITE_AFF_REAL
@@ -81786,22 +94879,26 @@ SQLITE_PRIVATE void sqlite3AddNotNull(Parse *pParse, int onError){
** If none of the substrings in the above table are found,
** SQLITE_AFF_NUMERIC is returned.
*/
-SQLITE_PRIVATE char sqlite3AffinityType(const char *zIn){
+SQLITE_PRIVATE char sqlite3AffinityType(const char *zIn, u8 *pszEst){
u32 h = 0;
char aff = SQLITE_AFF_NUMERIC;
+ const char *zChar = 0;
- if( zIn ) while( zIn[0] ){
+ if( zIn==0 ) return aff;
+ while( zIn[0] ){
h = (h<<8) + sqlite3UpperToLower[(*zIn)&0xff];
zIn++;
if( h==(('c'<<24)+('h'<<16)+('a'<<8)+'r') ){ /* CHAR */
- aff = SQLITE_AFF_TEXT;
+ aff = SQLITE_AFF_TEXT;
+ zChar = zIn;
}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;
+ aff = SQLITE_AFF_BLOB;
+ if( zIn[0]=='(' ) zChar = zIn;
#ifndef SQLITE_OMIT_FLOATING_POINT
}else if( h==(('r'<<24)+('e'<<16)+('a'<<8)+'l') /* REAL */
&& aff==SQLITE_AFF_NUMERIC ){
@@ -81819,6 +94916,28 @@ SQLITE_PRIVATE char sqlite3AffinityType(const char *zIn){
}
}
+ /* If pszEst is not NULL, store an estimate of the field size. The
+ ** estimate is scaled so that the size of an integer is 1. */
+ if( pszEst ){
+ *pszEst = 1; /* default size is approx 4 bytes */
+ if( aff<SQLITE_AFF_NUMERIC ){
+ if( zChar ){
+ while( zChar[0] ){
+ if( sqlite3Isdigit(zChar[0]) ){
+ int v = 0;
+ sqlite3GetInt32(zChar, &v);
+ v = v/4 + 1;
+ if( v>255 ) v = 255;
+ *pszEst = v; /* BLOB(k), VARCHAR(k), CHAR(k) -> r=(k/4+1) */
+ break;
+ }
+ zChar++;
+ }
+ }else{
+ *pszEst = 5; /* BLOB, TEXT, CLOB -> r=5 (approx 20 bytes)*/
+ }
+ }
+ }
return aff;
}
@@ -81838,9 +94957,10 @@ SQLITE_PRIVATE void sqlite3AddColumnType(Parse *pParse, Token *pType){
p = pParse->pNewTable;
if( p==0 || NEVER(p->nCol<1) ) return;
pCol = &p->aCol[p->nCol-1];
- assert( pCol->zType==0 );
+ assert( pCol->zType==0 || CORRUPT_DB );
+ sqlite3DbFree(pParse->db, pCol->zType);
pCol->zType = sqlite3NameFromToken(pParse->db, pType);
- pCol->affinity = sqlite3AffinityType(pCol->zType);
+ pCol->affinity = sqlite3AffinityType(pCol->zType, &pCol->szEst);
}
/*
@@ -81860,7 +94980,7 @@ SQLITE_PRIVATE void sqlite3AddDefaultValue(Parse *pParse, ExprSpan *pSpan){
p = pParse->pNewTable;
if( p!=0 ){
pCol = &(p->aCol[p->nCol-1]);
- if( !sqlite3ExprIsConstantOrFunction(pSpan->pExpr) ){
+ if( !sqlite3ExprIsConstantOrFunction(pSpan->pExpr, db->init.busy) ){
sqlite3ErrorMsg(pParse, "default value of column [%s] is not constant",
pCol->zName);
}else{
@@ -81879,6 +94999,30 @@ SQLITE_PRIVATE void sqlite3AddDefaultValue(Parse *pParse, ExprSpan *pSpan){
}
/*
+** Backwards Compatibility Hack:
+**
+** Historical versions of SQLite accepted strings as column names in
+** indexes and PRIMARY KEY constraints and in UNIQUE constraints. Example:
+**
+** CREATE TABLE xyz(a,b,c,d,e,PRIMARY KEY('a'),UNIQUE('b','c' COLLATE trim)
+** CREATE INDEX abc ON xyz('c','d' DESC,'e' COLLATE nocase DESC);
+**
+** This is goofy. But to preserve backwards compatibility we continue to
+** accept it. This routine does the necessary conversion. It converts
+** the expression given in its argument from a TK_STRING into a TK_ID
+** if the expression is just a TK_STRING with an optional COLLATE clause.
+** If the epxression is anything other than TK_STRING, the expression is
+** unchanged.
+*/
+static void sqlite3StringToId(Expr *p){
+ if( p->op==TK_STRING ){
+ p->op = TK_ID;
+ }else if( p->op==TK_COLLATE && p->pLeft->op==TK_STRING ){
+ p->pLeft->op = TK_ID;
+ }
+}
+
+/*
** 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.
@@ -81906,6 +95050,7 @@ SQLITE_PRIVATE void sqlite3AddPrimaryKey(
Table *pTab = pParse->pNewTable;
char *zType = 0;
int iCol = -1, i;
+ int nTerm;
if( pTab==0 || IN_DECLARE_VTAB ) goto primary_key_exit;
if( pTab->tabFlags & TF_HasPrimaryKey ){
sqlite3ErrorMsg(pParse,
@@ -81916,28 +95061,35 @@ SQLITE_PRIVATE void sqlite3AddPrimaryKey(
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;
+ zType = pTab->aCol[iCol].zType;
+ nTerm = 1;
+ }else{
+ nTerm = pList->nExpr;
+ for(i=0; i<nTerm; i++){
+ Expr *pCExpr = sqlite3ExprSkipCollate(pList->a[i].pExpr);
+ assert( pCExpr!=0 );
+ sqlite3StringToId(pCExpr);
+ if( pCExpr->op==TK_ID ){
+ const char *zCName = pCExpr->u.zToken;
+ for(iCol=0; iCol<pTab->nCol; iCol++){
+ if( sqlite3StrICmp(zCName, pTab->aCol[iCol].zName)==0 ){
+ pTab->aCol[iCol].colFlags |= COLFLAG_PRIMKEY;
+ zType = pTab->aCol[iCol].zType;
+ 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 ){
+ if( nTerm==1
+ && zType && sqlite3StrICmp(zType, "INTEGER")==0
+ && sortOrder!=SQLITE_SO_DESC
+ ){
pTab->iPKey = iCol;
pTab->keyConf = (u8)onError;
assert( autoInc==0 || autoInc==1 );
pTab->tabFlags |= autoInc*TF_Autoincrement;
+ if( pList ) pParse->iPkSortOrder = pList->a[0].sortOrder;
}else if( autoInc ){
#ifndef SQLITE_OMIT_AUTOINCREMENT
sqlite3ErrorMsg(pParse, "AUTOINCREMENT is only allowed on an "
@@ -81945,9 +95097,10 @@ SQLITE_PRIVATE void sqlite3AddPrimaryKey(
#endif
}else{
Index *p;
- p = sqlite3CreateIndex(pParse, 0, 0, 0, pList, onError, 0, 0, sortOrder, 0);
+ p = sqlite3CreateIndex(pParse, 0, 0, 0, pList, onError, 0,
+ 0, sortOrder, 0);
if( p ){
- p->autoIndex = 2;
+ p->idxType = SQLITE_IDXTYPE_PRIMARYKEY;
}
pList = 0;
}
@@ -81966,7 +95119,10 @@ SQLITE_PRIVATE void sqlite3AddCheckConstraint(
){
#ifndef SQLITE_OMIT_CHECK
Table *pTab = pParse->pNewTable;
- if( pTab && !IN_DECLARE_VTAB ){
+ sqlite3 *db = pParse->db;
+ if( pTab && !IN_DECLARE_VTAB
+ && !sqlite3BtreeIsReadonly(db->aDb[db->init.iDb].pBt)
+ ){
pTab->pCheck = sqlite3ExprListAppend(pParse, pTab->pCheck, pCheckExpr);
if( pParse->constraintName.n ){
sqlite3ExprListSetName(pParse, pTab->pCheck, &pParse->constraintName, 1);
@@ -81996,6 +95152,7 @@ SQLITE_PRIVATE void sqlite3AddCollateType(Parse *pParse, Token *pToken){
if( sqlite3LocateCollSeq(pParse, zColl) ){
Index *pIdx;
+ sqlite3DbFree(db, p->aCol[i].zColl);
p->aCol[i].zColl = zColl;
/* If the column is declared as "<name> PRIMARY KEY COLLATE <type>",
@@ -82003,7 +95160,7 @@ SQLITE_PRIVATE void sqlite3AddCollateType(Parse *pParse, Token *pToken){
** collation type was added. Correct this if it is the case.
*/
for(pIdx=p->pIndex; pIdx; pIdx=pIdx->pNext){
- assert( pIdx->nColumn==1 );
+ assert( pIdx->nKeyCol==1 );
if( pIdx->aiColumn[0]==i ){
pIdx->azColl[0] = p->aCol[i].zColl;
}
@@ -82111,10 +95268,10 @@ static void identPut(char *z, int *pIdx, char *zSignedIdent){
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];
- }
+ needQuote = sqlite3Isdigit(zIdent[0])
+ || sqlite3KeywordCode(zIdent, j)!=TK_ID
+ || zIdent[j]!=0
+ || j==0;
if( needQuote ) z[i++] = '"';
for(j=0; zIdent[j]; j++){
@@ -82162,8 +95319,8 @@ static char *createTableStmt(sqlite3 *db, Table *p){
zStmt[k++] = '(';
for(pCol=p->aCol, i=0; i<p->nCol; i++, pCol++){
static const char * const azType[] = {
+ /* SQLITE_AFF_BLOB */ "",
/* SQLITE_AFF_TEXT */ " TEXT",
- /* SQLITE_AFF_NONE */ "",
/* SQLITE_AFF_NUMERIC */ " NUM",
/* SQLITE_AFF_INTEGER */ " INT",
/* SQLITE_AFF_REAL */ " REAL"
@@ -82175,18 +95332,18 @@ static char *createTableStmt(sqlite3 *db, Table *p){
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) );
+ assert( pCol->affinity-SQLITE_AFF_BLOB >= 0 );
+ assert( pCol->affinity-SQLITE_AFF_BLOB < ArraySize(azType) );
+ testcase( pCol->affinity==SQLITE_AFF_BLOB );
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];
+ zType = azType[pCol->affinity - SQLITE_AFF_BLOB];
len = sqlite3Strlen30(zType);
- assert( pCol->affinity==SQLITE_AFF_NONE
- || pCol->affinity==sqlite3AffinityType(zType) );
+ assert( pCol->affinity==SQLITE_AFF_BLOB
+ || pCol->affinity==sqlite3AffinityType(zType, 0) );
memcpy(&zStmt[k], zType, len);
k += len;
assert( k<=n );
@@ -82196,6 +95353,211 @@ static char *createTableStmt(sqlite3 *db, Table *p){
}
/*
+** Resize an Index object to hold N columns total. Return SQLITE_OK
+** on success and SQLITE_NOMEM on an OOM error.
+*/
+static int resizeIndexObject(sqlite3 *db, Index *pIdx, int N){
+ char *zExtra;
+ int nByte;
+ if( pIdx->nColumn>=N ) return SQLITE_OK;
+ assert( pIdx->isResized==0 );
+ nByte = (sizeof(char*) + sizeof(i16) + 1)*N;
+ zExtra = sqlite3DbMallocZero(db, nByte);
+ if( zExtra==0 ) return SQLITE_NOMEM;
+ memcpy(zExtra, pIdx->azColl, sizeof(char*)*pIdx->nColumn);
+ pIdx->azColl = (const char**)zExtra;
+ zExtra += sizeof(char*)*N;
+ memcpy(zExtra, pIdx->aiColumn, sizeof(i16)*pIdx->nColumn);
+ pIdx->aiColumn = (i16*)zExtra;
+ zExtra += sizeof(i16)*N;
+ memcpy(zExtra, pIdx->aSortOrder, pIdx->nColumn);
+ pIdx->aSortOrder = (u8*)zExtra;
+ pIdx->nColumn = N;
+ pIdx->isResized = 1;
+ return SQLITE_OK;
+}
+
+/*
+** Estimate the total row width for a table.
+*/
+static void estimateTableWidth(Table *pTab){
+ unsigned wTable = 0;
+ const Column *pTabCol;
+ int i;
+ for(i=pTab->nCol, pTabCol=pTab->aCol; i>0; i--, pTabCol++){
+ wTable += pTabCol->szEst;
+ }
+ if( pTab->iPKey<0 ) wTable++;
+ pTab->szTabRow = sqlite3LogEst(wTable*4);
+}
+
+/*
+** Estimate the average size of a row for an index.
+*/
+static void estimateIndexWidth(Index *pIdx){
+ unsigned wIndex = 0;
+ int i;
+ const Column *aCol = pIdx->pTable->aCol;
+ for(i=0; i<pIdx->nColumn; i++){
+ i16 x = pIdx->aiColumn[i];
+ assert( x<pIdx->pTable->nCol );
+ wIndex += x<0 ? 1 : aCol[pIdx->aiColumn[i]].szEst;
+ }
+ pIdx->szIdxRow = sqlite3LogEst(wIndex*4);
+}
+
+/* Return true if value x is found any of the first nCol entries of aiCol[]
+*/
+static int hasColumn(const i16 *aiCol, int nCol, int x){
+ while( nCol-- > 0 ) if( x==*(aiCol++) ) return 1;
+ return 0;
+}
+
+/*
+** This routine runs at the end of parsing a CREATE TABLE statement that
+** has a WITHOUT ROWID clause. The job of this routine is to convert both
+** internal schema data structures and the generated VDBE code so that they
+** are appropriate for a WITHOUT ROWID table instead of a rowid table.
+** Changes include:
+**
+** (1) Convert the OP_CreateTable into an OP_CreateIndex. There is
+** no rowid btree for a WITHOUT ROWID. Instead, the canonical
+** data storage is a covering index btree.
+** (2) Bypass the creation of the sqlite_master table entry
+** for the PRIMARY KEY as the primary key index is now
+** identified by the sqlite_master table entry of the table itself.
+** (3) Set the Index.tnum of the PRIMARY KEY Index object in the
+** schema to the rootpage from the main table.
+** (4) Set all columns of the PRIMARY KEY schema object to be NOT NULL.
+** (5) Add all table columns to the PRIMARY KEY Index object
+** so that the PRIMARY KEY is a covering index. The surplus
+** columns are part of KeyInfo.nXField and are not used for
+** sorting or lookup or uniqueness checks.
+** (6) Replace the rowid tail on all automatically generated UNIQUE
+** indices with the PRIMARY KEY columns.
+*/
+static void convertToWithoutRowidTable(Parse *pParse, Table *pTab){
+ Index *pIdx;
+ Index *pPk;
+ int nPk;
+ int i, j;
+ sqlite3 *db = pParse->db;
+ Vdbe *v = pParse->pVdbe;
+
+ /* Convert the OP_CreateTable opcode that would normally create the
+ ** root-page for the table into an OP_CreateIndex opcode. The index
+ ** created will become the PRIMARY KEY index.
+ */
+ if( pParse->addrCrTab ){
+ assert( v );
+ sqlite3VdbeChangeOpcode(v, pParse->addrCrTab, OP_CreateIndex);
+ }
+
+ /* Locate the PRIMARY KEY index. Or, if this table was originally
+ ** an INTEGER PRIMARY KEY table, create a new PRIMARY KEY index.
+ */
+ if( pTab->iPKey>=0 ){
+ ExprList *pList;
+ Token ipkToken;
+ ipkToken.z = pTab->aCol[pTab->iPKey].zName;
+ ipkToken.n = sqlite3Strlen30(ipkToken.z);
+ pList = sqlite3ExprListAppend(pParse, 0,
+ sqlite3ExprAlloc(db, TK_ID, &ipkToken, 0));
+ if( pList==0 ) return;
+ pList->a[0].sortOrder = pParse->iPkSortOrder;
+ assert( pParse->pNewTable==pTab );
+ pPk = sqlite3CreateIndex(pParse, 0, 0, 0, pList, pTab->keyConf, 0, 0, 0, 0);
+ if( pPk==0 ) return;
+ pPk->idxType = SQLITE_IDXTYPE_PRIMARYKEY;
+ pTab->iPKey = -1;
+ }else{
+ pPk = sqlite3PrimaryKeyIndex(pTab);
+
+ /* Bypass the creation of the PRIMARY KEY btree and the sqlite_master
+ ** table entry. This is only required if currently generating VDBE
+ ** code for a CREATE TABLE (not when parsing one as part of reading
+ ** a database schema). */
+ if( v ){
+ assert( db->init.busy==0 );
+ sqlite3VdbeChangeOpcode(v, pPk->tnum, OP_Goto);
+ }
+
+ /*
+ ** Remove all redundant columns from the PRIMARY KEY. For example, change
+ ** "PRIMARY KEY(a,b,a,b,c,b,c,d)" into just "PRIMARY KEY(a,b,c,d)". Later
+ ** code assumes the PRIMARY KEY contains no repeated columns.
+ */
+ for(i=j=1; i<pPk->nKeyCol; i++){
+ if( hasColumn(pPk->aiColumn, j, pPk->aiColumn[i]) ){
+ pPk->nColumn--;
+ }else{
+ pPk->aiColumn[j++] = pPk->aiColumn[i];
+ }
+ }
+ pPk->nKeyCol = j;
+ }
+ pPk->isCovering = 1;
+ assert( pPk!=0 );
+ nPk = pPk->nKeyCol;
+
+ /* Make sure every column of the PRIMARY KEY is NOT NULL. (Except,
+ ** do not enforce this for imposter tables.) */
+ if( !db->init.imposterTable ){
+ for(i=0; i<nPk; i++){
+ pTab->aCol[pPk->aiColumn[i]].notNull = OE_Abort;
+ }
+ pPk->uniqNotNull = 1;
+ }
+
+ /* The root page of the PRIMARY KEY is the table root page */
+ pPk->tnum = pTab->tnum;
+
+ /* Update the in-memory representation of all UNIQUE indices by converting
+ ** the final rowid column into one or more columns of the PRIMARY KEY.
+ */
+ for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){
+ int n;
+ if( IsPrimaryKeyIndex(pIdx) ) continue;
+ for(i=n=0; i<nPk; i++){
+ if( !hasColumn(pIdx->aiColumn, pIdx->nKeyCol, pPk->aiColumn[i]) ) n++;
+ }
+ if( n==0 ){
+ /* This index is a superset of the primary key */
+ pIdx->nColumn = pIdx->nKeyCol;
+ continue;
+ }
+ if( resizeIndexObject(db, pIdx, pIdx->nKeyCol+n) ) return;
+ for(i=0, j=pIdx->nKeyCol; i<nPk; i++){
+ if( !hasColumn(pIdx->aiColumn, pIdx->nKeyCol, pPk->aiColumn[i]) ){
+ pIdx->aiColumn[j] = pPk->aiColumn[i];
+ pIdx->azColl[j] = pPk->azColl[i];
+ j++;
+ }
+ }
+ assert( pIdx->nColumn>=pIdx->nKeyCol+n );
+ assert( pIdx->nColumn>=j );
+ }
+
+ /* Add all table columns to the PRIMARY KEY index
+ */
+ if( nPk<pTab->nCol ){
+ if( resizeIndexObject(db, pPk, pTab->nCol) ) return;
+ for(i=0, j=nPk; i<pTab->nCol; i++){
+ if( !hasColumn(pPk->aiColumn, j, i) ){
+ assert( j<pPk->nColumn );
+ pPk->aiColumn[j] = i;
+ pPk->azColl[j] = sqlite3StrBINARY;
+ j++;
+ }
+ }
+ assert( pPk->nColumn==j );
+ assert( pTab->nCol==j );
+ }else{
+ pPk->nColumn = pTab->nCol;
+ }
+}
+
+/*
** This routine is called to report the final ")" that terminates
** a CREATE TABLE statement.
**
@@ -82218,58 +95580,63 @@ static char *createTableStmt(sqlite3 *db, Table *p){
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 */
+ Token *pEnd, /* The ')' before options in the CREATE TABLE */
+ u8 tabOpts, /* Extra table options. Usually 0. */
Select *pSelect /* Select from a "CREATE ... AS SELECT" */
){
- Table *p;
- sqlite3 *db = pParse->db;
- int iDb;
+ Table *p; /* The new table */
+ sqlite3 *db = pParse->db; /* The database connection */
+ int iDb; /* Database in which the table lives */
+ Index *pIdx; /* An implied index of the table */
- if( (pEnd==0 && pSelect==0) || db->mallocFailed ){
+ if( pEnd==0 && pSelect==0 ){
return;
}
+ assert( !db->mallocFailed );
p = pParse->pNewTable;
if( p==0 ) return;
assert( !db->init.busy || !pSelect );
+ /* 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;
+ }
+
+ /* Special processing for WITHOUT ROWID Tables */
+ if( tabOpts & TF_WithoutRowid ){
+ if( (p->tabFlags & TF_Autoincrement) ){
+ sqlite3ErrorMsg(pParse,
+ "AUTOINCREMENT not allowed on WITHOUT ROWID tables");
+ return;
+ }
+ if( (p->tabFlags & TF_HasPrimaryKey)==0 ){
+ sqlite3ErrorMsg(pParse, "PRIMARY KEY missing on table %s", p->zName);
+ }else{
+ p->tabFlags |= TF_WithoutRowid | TF_NoVisibleRowid;
+ convertToWithoutRowidTable(pParse, p);
+ }
+ }
+
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;
- }
- }
+ sqlite3ResolveSelfReference(pParse, p, NC_IsCheck, 0, p->pCheck);
}
#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;
+ /* Estimate the average row size for the table and for all implied indices */
+ estimateTableWidth(p);
+ for(pIdx=p->pIndex; pIdx; pIdx=pIdx->pNext){
+ estimateIndexWidth(pIdx);
}
/* If not initializing, then create a record for the new table
@@ -82319,33 +95686,55 @@ SQLITE_PRIVATE void sqlite3EndTable(
** be redundant.
*/
if( pSelect ){
- SelectDest dest;
- Table *pSelTab;
-
+ SelectDest dest; /* Where the SELECT should store results */
+ int regYield; /* Register holding co-routine entry-point */
+ int addrTop; /* Top of the co-routine */
+ int regRec; /* A record to be insert into the new table */
+ int regRowid; /* Rowid of the next row to insert */
+ int addrInsLoop; /* Top of the loop for inserting rows */
+ Table *pSelTab; /* A table that describes the SELECT results */
+
+ regYield = ++pParse->nMem;
+ regRec = ++pParse->nMem;
+ regRowid = ++pParse->nMem;
assert(pParse->nTab==1);
+ sqlite3MayAbort(pParse);
sqlite3VdbeAddOp3(v, OP_OpenWrite, 1, pParse->regRoot, iDb);
sqlite3VdbeChangeP5(v, OPFLAG_P2ISREG);
pParse->nTab = 2;
- sqlite3SelectDestInit(&dest, SRT_Table, 1);
+ addrTop = sqlite3VdbeCurrentAddr(v) + 1;
+ sqlite3VdbeAddOp3(v, OP_InitCoroutine, regYield, 0, addrTop);
+ sqlite3SelectDestInit(&dest, SRT_Coroutine, regYield);
sqlite3Select(pParse, pSelect, &dest);
+ sqlite3VdbeAddOp1(v, OP_EndCoroutine, regYield);
+ sqlite3VdbeJumpHere(v, addrTop - 1);
+ if( pParse->nErr ) return;
+ 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);
+ addrInsLoop = sqlite3VdbeAddOp1(v, OP_Yield, dest.iSDParm);
+ VdbeCoverage(v);
+ sqlite3VdbeAddOp3(v, OP_MakeRecord, dest.iSdst, dest.nSdst, regRec);
+ sqlite3TableAffinity(v, p, 0);
+ sqlite3VdbeAddOp2(v, OP_NewRowid, 1, regRowid);
+ sqlite3VdbeAddOp3(v, OP_Insert, 1, regRec, regRowid);
+ sqlite3VdbeGoto(v, addrInsLoop);
+ sqlite3VdbeJumpHere(v, addrInsLoop);
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;
+ Token *pEnd2 = tabOpts ? &pParse->sLastToken : pEnd;
+ n = (int)(pEnd2->z - pParse->sNameToken.z);
+ if( pEnd2->z[0]!=';' ) n += pEnd2->n;
zStmt = sqlite3MPrintf(db,
"CREATE %s %.*s", zType2, n, pParse->sNameToken.z
);
@@ -82388,7 +95777,7 @@ SQLITE_PRIVATE void sqlite3EndTable(
/* Reparse everything to update our internal data structures */
sqlite3VdbeAddParseSchemaOp(v, iDb,
- sqlite3MPrintf(db, "tbl_name='%q'", p->zName));
+ sqlite3MPrintf(db, "tbl_name='%q' AND type!='trigger'", p->zName));
}
@@ -82398,8 +95787,7 @@ SQLITE_PRIVATE void sqlite3EndTable(
Table *pOld;
Schema *pSchema = p->pSchema;
assert( sqlite3SchemaMutexHeld(db, iDb, 0) );
- pOld = sqlite3HashInsert(&pSchema->tblHash, p->zName,
- sqlite3Strlen30(p->zName),p);
+ pOld = sqlite3HashInsert(&pSchema->tblHash, p->zName, p);
if( pOld ){
assert( p==pOld ); /* Malloc must have failed inside HashInsert() */
db->mallocFailed = 1;
@@ -82432,6 +95820,7 @@ SQLITE_PRIVATE void sqlite3CreateView(
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 */
+ ExprList *pCNames, /* Optional list of view column names */
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 */
@@ -82447,23 +95836,15 @@ SQLITE_PRIVATE void sqlite3CreateView(
if( pParse->nVar>0 ){
sqlite3ErrorMsg(pParse, "parameters are not allowed in views");
- sqlite3SelectDelete(db, pSelect);
- return;
+ goto create_view_fail;
}
sqlite3StartTable(pParse, pName1, pName2, isTemp, 1, 0, noErr);
p = pParse->pNewTable;
- if( p==0 || pParse->nErr ){
- sqlite3SelectDelete(db, pSelect);
- return;
- }
+ if( p==0 || pParse->nErr ) goto create_view_fail;
sqlite3TwoPartName(pParse, pName1, pName2, &pName);
iDb = sqlite3SchemaToIndex(db, p->pSchema);
- if( sqlite3FixInit(&sFix, pParse, iDb, "view", pName)
- && sqlite3FixSelect(&sFix, pSelect)
- ){
- sqlite3SelectDelete(db, pSelect);
- return;
- }
+ sqlite3FixInit(&sFix, pParse, iDb, "view", pName);
+ if( sqlite3FixSelect(&sFix, pSelect) ) goto create_view_fail;
/* Make a copy of the entire SELECT statement that defines the view.
** This will force all the Expr.token.z values to be dynamically
@@ -82471,30 +95852,31 @@ SQLITE_PRIVATE void sqlite3CreateView(
** 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);
- }
+ p->pCheck = sqlite3ExprListDup(db, pCNames, EXPRDUP_REDUCE);
+ if( db->mallocFailed ) goto create_view_fail;
/* 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]!=';' ){
+ assert( sEnd.z[0]!=0 );
+ if( sEnd.z[0]!=';' ){
sEnd.z += sEnd.n;
}
sEnd.n = 0;
n = (int)(sEnd.z - pBegin->z);
+ assert( n>0 );
z = pBegin->z;
- while( ALWAYS(n>0) && sqlite3Isspace(z[n-1]) ){ n--; }
+ while( 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);
+ sqlite3EndTable(pParse, 0, &sEnd, 0, 0);
+
+create_view_fail:
+ sqlite3SelectDelete(db, pSelect);
+ sqlite3ExprListDelete(db, pCNames);
return;
}
#endif /* SQLITE_OMIT_VIEW */
@@ -82511,7 +95893,8 @@ SQLITE_PRIVATE int sqlite3ViewGetColumnNames(Parse *pParse, Table *pTable){
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*);
+ sqlite3_xauth xAuth; /* Saved xAuth pointer */
+ u8 bEnabledLA; /* Saved db->lookaside.bEnabled state */
assert( pTable );
@@ -82557,40 +95940,46 @@ SQLITE_PRIVATE int sqlite3ViewGetColumnNames(Parse *pParse, Table *pTable){
** 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;
+ bEnabledLA = db->lookaside.bEnabled;
+ if( pTable->pCheck ){
db->lookaside.bEnabled = 0;
+ sqlite3ColumnsFromExprList(pParse, pTable->pCheck,
+ &pTable->nCol, &pTable->aCol);
+ }else{
+ pSel = sqlite3SelectDup(db, pTable->pSelect, 0);
+ if( pSel ){
+ 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;
+ xAuth = db->xAuth;
+ db->xAuth = 0;
+ pSelTab = sqlite3ResultSetOfSelect(pParse, pSel);
+ db->xAuth = xAuth;
#else
- pSelTab = sqlite3ResultSetOfSelect(pParse, pSel);
+ 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;
+ 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) );
+ }else{
+ pTable->nCol = 0;
+ nErr++;
+ }
+ sqlite3SelectDelete(db, pSel);
+ } else {
nErr++;
}
- sqlite3SelectDelete(db, pSel);
- } else {
- nErr++;
}
+ db->lookaside.bEnabled = bEnabledLA;
+ pTable->pSchema->schemaFlags |= DB_UnresetViews;
#endif /* SQLITE_OMIT_VIEW */
return nErr;
}
@@ -82607,7 +95996,7 @@ static void sqliteViewResetAll(sqlite3 *db, int idx){
for(i=sqliteHashFirst(&db->aDb[idx].pSchema->tblHash); i;i=sqliteHashNext(i)){
Table *pTab = sqliteHashData(i);
if( pTab->pSelect ){
- sqliteDeleteColumnNames(db, pTab);
+ sqlite3DeleteColumnNames(db, pTab);
pTab->aCol = 0;
pTab->nCol = 0;
}
@@ -82760,7 +96149,7 @@ static void sqlite3ClearStatTables(
){
int i;
const char *zDbName = pParse->db->aDb[iDb].zName;
- for(i=1; i<=3; i++){
+ for(i=1; i<=4; i++){
char zTab[24];
sqlite3_snprintf(sizeof(zTab),zTab,"sqlite_stat%d",i);
if( sqlite3FindTable(pParse->db, zTab, zDbName) ){
@@ -82820,7 +96209,7 @@ SQLITE_PRIVATE void sqlite3CodeDropTable(Parse *pParse, Table *pTab, int iDb, in
/* 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
+ ** dropped. Triggers are handled separately because a trigger can be
** created in the temp database that refers to a table in another
** database.
*/
@@ -82857,6 +96246,7 @@ SQLITE_PRIVATE void sqlite3DropTable(Parse *pParse, SrcList *pName, int isView,
}
assert( pParse->nErr==0 );
assert( pName->nSrc==1 );
+ if( sqlite3ReadSchema(pParse) ) goto exit_drop_table;
if( noErr ) db->suppressErr++;
pTab = sqlite3LocateTableItem(pParse, isView, &pName->a[0]);
if( noErr ) db->suppressErr--;
@@ -82949,8 +96339,8 @@ exit_drop_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
+** the table referred to (a.k.a the "parent" table). pToCol is a list
+** of tables in the parent pTo table. flags contains all
** information about the conflict resolution algorithms specified
** in the ON DELETE, ON UPDATE and ON INSERT clauses.
**
@@ -83050,7 +96440,7 @@ SQLITE_PRIVATE void sqlite3CreateForeignKey(
assert( sqlite3SchemaMutexHeld(db, 0, p->pSchema) );
pNextTo = (FKey *)sqlite3HashInsert(&p->pSchema->fkeyHash,
- pFKey->zTo, sqlite3Strlen30(pFKey->zTo), (void *)pFKey
+ pFKey->zTo, (void *)pFKey
);
if( pNextTo==pFKey ){
db->mallocFailed = 1;
@@ -83110,12 +96500,10 @@ static void sqlite3RefillIndex(Parse *pParse, Index *pIndex, int memRootPage){
int addr1; /* Address of top of loop */
int addr2; /* Address to jump to for next iteration */
int tnum; /* Root page of index */
+ int iPartIdxLabel; /* Jump to this label to skip a row */
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 */
+ int regRecord; /* Register holding assembled index record */
sqlite3 *db = pParse->db; /* The database connection */
int iDb = sqlite3SchemaToIndex(db, pIndex->pSchema);
@@ -83135,73 +96523,48 @@ static void sqlite3RefillIndex(Parse *pParse, Index *pIndex, int memRootPage){
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));
+ pKey = sqlite3KeyInfoOfIndex(pParse, pIndex);
-#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
+ sqlite3VdbeAddOp4(v, OP_SorterOpen, iSorter, 0, pIndex->nKeyCol, (char*)
+ sqlite3KeyInfoRef(pKey), P4_KEYINFO);
/* 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);
+ addr1 = sqlite3VdbeAddOp2(v, OP_Rewind, iTab, 0); VdbeCoverage(v);
regRecord = sqlite3GetTempReg(pParse);
-#ifndef SQLITE_OMIT_MERGE_SORT
- sqlite3GenerateIndexKey(pParse, pIndex, iTab, regRecord, 1);
+ sqlite3GenerateIndexKey(pParse,pIndex,iTab,regRecord,0,&iPartIdxLabel,0,0);
sqlite3VdbeAddOp2(v, OP_SorterInsert, iSorter, regRecord);
- sqlite3VdbeAddOp2(v, OP_Next, iTab, addr1+1);
+ sqlite3ResolvePartIdxLabel(pParse, iPartIdxLabel);
+ sqlite3VdbeAddOp2(v, OP_Next, iTab, addr1+1); VdbeCoverage(v);
sqlite3VdbeJumpHere(v, addr1);
- addr1 = sqlite3VdbeAddOp2(v, OP_SorterSort, iSorter, 0);
- if( pIndex->onError!=OE_None ){
+ if( memRootPage<0 ) sqlite3VdbeAddOp2(v, OP_Clear, tnum, iDb);
+ sqlite3VdbeAddOp4(v, OP_OpenWrite, iIdx, tnum, iDb,
+ (char *)pKey, P4_KEYINFO);
+ sqlite3VdbeChangeP5(v, OPFLAG_BULKCSR|((memRootPage>=0)?OPFLAG_P2ISREG:0));
+
+ addr1 = sqlite3VdbeAddOp2(v, OP_SorterSort, iSorter, 0); VdbeCoverage(v);
+ assert( pKey!=0 || db->mallocFailed || pParse->nErr );
+ if( IsUniqueIndex(pIndex) && pKey!=0 ){
int j2 = sqlite3VdbeCurrentAddr(v) + 3;
- sqlite3VdbeAddOp2(v, OP_Goto, 0, j2);
+ sqlite3VdbeGoto(v, j2);
addr2 = sqlite3VdbeCurrentAddr(v);
- sqlite3VdbeAddOp3(v, OP_SorterCompare, iSorter, j2, regRecord);
- sqlite3HaltConstraint(
- pParse, OE_Abort, "indexed columns are not unique", P4_STATIC
- );
+ sqlite3VdbeAddOp4Int(v, OP_SorterCompare, iSorter, j2, regRecord,
+ pIndex->nKeyCol); VdbeCoverage(v);
+ sqlite3UniqueConstraint(pParse, OE_Abort, pIndex);
}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_SorterData, iSorter, regRecord, iIdx);
+ sqlite3VdbeAddOp3(v, OP_Last, iIdx, 0, -1);
sqlite3VdbeAddOp3(v, OP_IdxInsert, iIdx, regRecord, 0);
sqlite3VdbeChangeP5(v, OPFLAG_USESEEKRESULT);
-#endif
sqlite3ReleaseTempReg(pParse, regRecord);
- sqlite3VdbeAddOp2(v, OP_SorterNext, iSorter, addr2);
+ sqlite3VdbeAddOp2(v, OP_SorterNext, iSorter, addr2); VdbeCoverage(v);
sqlite3VdbeJumpHere(v, addr1);
sqlite3VdbeAddOp1(v, OP_Close, iTab);
@@ -83210,6 +96573,41 @@ static void sqlite3RefillIndex(Parse *pParse, Index *pIndex, int memRootPage){
}
/*
+** Allocate heap space to hold an Index object with nCol columns.
+**
+** Increase the allocation size to provide an extra nExtra bytes
+** of 8-byte aligned space after the Index object and return a
+** pointer to this extra space in *ppExtra.
+*/
+SQLITE_PRIVATE Index *sqlite3AllocateIndexObject(
+ sqlite3 *db, /* Database connection */
+ i16 nCol, /* Total number of columns in the index */
+ int nExtra, /* Number of bytes of extra space to alloc */
+ char **ppExtra /* Pointer to the "extra" space */
+){
+ Index *p; /* Allocated index object */
+ int nByte; /* Bytes of space for Index object + arrays */
+
+ nByte = ROUND8(sizeof(Index)) + /* Index structure */
+ ROUND8(sizeof(char*)*nCol) + /* Index.azColl */
+ ROUND8(sizeof(LogEst)*(nCol+1) + /* Index.aiRowLogEst */
+ sizeof(i16)*nCol + /* Index.aiColumn */
+ sizeof(u8)*nCol); /* Index.aSortOrder */
+ p = sqlite3DbMallocZero(db, nByte + nExtra);
+ if( p ){
+ char *pExtra = ((char*)p)+ROUND8(sizeof(Index));
+ p->azColl = (const char**)pExtra; pExtra += ROUND8(sizeof(char*)*nCol);
+ p->aiRowLogEst = (LogEst*)pExtra; pExtra += sizeof(LogEst)*(nCol+1);
+ p->aiColumn = (i16*)pExtra; pExtra += sizeof(i16)*nCol;
+ p->aSortOrder = (u8*)pExtra;
+ p->nColumn = nCol;
+ p->nKeyCol = nCol - 1;
+ *ppExtra = ((char*)p) + nByte;
+ }
+ return p;
+}
+
+/*
** 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
@@ -83223,7 +96621,7 @@ static void sqlite3RefillIndex(Parse *pParse, Index *pIndex, int memRootPage){
**
** 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).
+** as the tables primary key (Index.idxType==SQLITE_IDXTYPE_PRIMARYKEY)
*/
SQLITE_PRIVATE Index *sqlite3CreateIndex(
Parse *pParse, /* All information about this parse */
@@ -83233,7 +96631,7 @@ SQLITE_PRIVATE Index *sqlite3CreateIndex(
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 */
+ Expr *pPIWhere, /* WHERE clause for partial indices */
int sortOrder, /* Sort order of primary key when pList==NULL */
int ifNotExist /* Omit error if index already exists */
){
@@ -83243,7 +96641,6 @@ SQLITE_PRIVATE Index *sqlite3CreateIndex(
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;
@@ -83251,13 +96648,12 @@ SQLITE_PRIVATE Index *sqlite3CreateIndex(
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;
+ int nExtra = 0; /* Space allocated for zExtra[] */
+ int nExtraCol; /* Number of extra columns needed */
+ char *zExtra = 0; /* Extra space after the Index object */
+ Index *pPk = 0; /* PRIMARY KEY index for WITHOUT ROWID tables */
- 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 ){
+ if( db->mallocFailed || IN_DECLARE_VTAB || pParse->nErr>0 ){
goto exit_create_index;
}
if( SQLITE_OK!=sqlite3ReadSchema(pParse) ){
@@ -83291,9 +96687,8 @@ SQLITE_PRIVATE Index *sqlite3CreateIndex(
}
#endif
- if( sqlite3FixInit(&sFix, pParse, iDb, "index", pName) &&
- sqlite3FixSrcList(&sFix, pTblName)
- ){
+ sqlite3FixInit(&sFix, pParse, iDb, "index", pName);
+ if( sqlite3FixSrcList(&sFix, pTblName) ){
/* Because the parser constructs pTblName from a single identifier,
** sqlite3FixSrcList can never fail. */
assert(0);
@@ -83301,7 +96696,13 @@ SQLITE_PRIVATE Index *sqlite3CreateIndex(
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 );
+ if( iDb==1 && db->aDb[iDb].pSchema!=pTab->pSchema ){
+ sqlite3ErrorMsg(pParse,
+ "cannot create a TEMP index on non-TEMP table \"%s\"",
+ pTab->zName);
+ goto exit_create_index;
+ }
+ if( !HasRowid(pTab) ) pPk = sqlite3PrimaryKeyIndex(pTab);
}else{
assert( pName==0 );
assert( pStart==0 );
@@ -83314,7 +96715,11 @@ SQLITE_PRIVATE Index *sqlite3CreateIndex(
assert( pTab!=0 );
assert( pParse->nErr==0 );
if( sqlite3StrNICmp(pTab->zName, "sqlite_", 7)==0
- && memcmp(&pTab->zName[7],"altertab_",9)!=0 ){
+ && db->init.busy==0
+#if SQLITE_USER_AUTHENTICATION
+ && sqlite3UserAuthTable(pTab->zName)==0
+#endif
+ && sqlite3StrNICmp(&pTab->zName[7],"altertab_",9)!=0 ){
sqlite3ErrorMsg(pParse, "table %s may not be indexed", pTab->zName);
goto exit_create_index;
}
@@ -83397,12 +96802,16 @@ SQLITE_PRIVATE Index *sqlite3CreateIndex(
** 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);
+ Token prevCol;
+ prevCol.z = pTab->aCol[pTab->nCol-1].zName;
+ prevCol.n = sqlite3Strlen30(prevCol.z);
+ pList = sqlite3ExprListAppend(pParse, 0,
+ sqlite3ExprAlloc(db, TK_ID, &prevCol, 0));
if( pList==0 ) goto exit_create_index;
- sqlite3ExprListSetName(pParse, pList, &nullId, 0);
- pList->a[0].sortOrder = (u8)sortOrder;
+ assert( pList->nExpr==1 );
+ sqlite3ExprListSetSortOrder(pList, sortOrder);
+ }else{
+ sqlite3ExprListCheckLength(pParse, pList, "index");
}
/* Figure out how many bytes of space are required to store explicitly
@@ -83410,11 +96819,9 @@ SQLITE_PRIVATE Index *sqlite3CreateIndex(
*/
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));
- }
+ assert( pExpr!=0 );
+ if( pExpr->op==TK_COLLATE ){
+ nExtra += (1 + sqlite3Strlen30(pExpr->u.zToken));
}
}
@@ -83422,35 +96829,28 @@ SQLITE_PRIVATE Index *sqlite3CreateIndex(
** 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 */
- );
+ nExtraCol = pPk ? pPk->nKeyCol : 1;
+ pIndex = sqlite3AllocateIndexObject(db, pList->nExpr + nExtraCol,
+ nName + nExtra + 1, &zExtra);
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->aiRowLogEst) );
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]);
+ pIndex->zName = zExtra;
+ zExtra += 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->uniqNotNull = onError!=OE_None;
+ pIndex->idxType = pName ? SQLITE_IDXTYPE_APPDEF : SQLITE_IDXTYPE_UNIQUE;
pIndex->pSchema = db->aDb[iDb].pSchema;
+ pIndex->nKeyCol = pList->nExpr;
+ if( pPIWhere ){
+ sqlite3ResolveSelfReference(pParse, pTab, NC_PartIdx, pPIWhere, 0);
+ pIndex->pPartIdxWhere = pPIWhere;
+ pPIWhere = 0;
+ }
assert( sqlite3SchemaMutexHeld(db, iDb, 0) );
/* Check to see if we should honor DESC requests on index columns
@@ -83461,50 +96861,65 @@ SQLITE_PRIVATE Index *sqlite3CreateIndex(
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.
+ /* Analyze the list of expressions that form the terms of the index and
+ ** report any errors. In the common case where the expression is exactly
+ ** a table column, store that column in aiColumn[]. For general expressions,
+ ** populate pIndex->aColExpr and store XN_EXPR (-2) in aiColumn[].
**
- ** 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.
+ ** TODO: Issue a warning if two or more columns of the index are identical.
+ ** TODO: Issue a warning if the table primary key is used as part of the
+ ** index key.
*/
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;
+ Expr *pCExpr; /* The i-th index expression */
+ int requestedSortOrder; /* ASC or DESC on the i-th expression */
+ const char *zColl; /* Collation sequence name */
+
+ sqlite3StringToId(pListItem->pExpr);
+ sqlite3ResolveSelfReference(pParse, pTab, NC_IdxExpr, pListItem->pExpr, 0);
+ if( pParse->nErr ) goto exit_create_index;
+ pCExpr = sqlite3ExprSkipCollate(pListItem->pExpr);
+ if( pCExpr->op!=TK_COLUMN ){
+ if( pTab==pParse->pNewTable ){
+ sqlite3ErrorMsg(pParse, "expressions prohibited in PRIMARY KEY and "
+ "UNIQUE constraints");
+ goto exit_create_index;
+ }
+ if( pIndex->aColExpr==0 ){
+ ExprList *pCopy = sqlite3ExprListDup(db, pList, 0);
+ pIndex->aColExpr = pCopy;
+ if( !db->mallocFailed ){
+ assert( pCopy!=0 );
+ pListItem = &pCopy->a[i];
+ }
+ }
+ j = XN_EXPR;
+ pIndex->aiColumn[i] = XN_EXPR;
+ pIndex->uniqNotNull = 0;
+ }else{
+ j = pCExpr->iColumn;
+ assert( j<=0x7fff );
+ if( j<0 ){
+ j = pTab->iPKey;
+ }else if( pTab->aCol[j].notNull==0 ){
+ pIndex->uniqNotNull = 0;
+ }
+ pIndex->aiColumn[i] = (i16)j;
}
- pIndex->aiColumn[i] = j;
- if( pListItem->pExpr
- && (pColl = sqlite3ExprCollSeq(pParse, pListItem->pExpr))!=0
- ){
+ zColl = 0;
+ if( pListItem->pExpr->op==TK_COLLATE ){
int nColl;
- zColl = pColl->zName;
+ zColl = pListItem->pExpr->u.zToken;
nColl = sqlite3Strlen30(zColl) + 1;
assert( nExtra>=nColl );
memcpy(zExtra, zColl, nColl);
zColl = zExtra;
zExtra += nColl;
nExtra -= nColl;
- }else{
+ }else if( j>=0 ){
zColl = pTab->aCol[j].zColl;
- if( !zColl ){
- zColl = "BINARY";
- }
}
+ if( !zColl ) zColl = sqlite3StrBINARY;
if( !db->init.busy && !sqlite3LocateCollSeq(pParse, zColl) ){
goto exit_create_index;
}
@@ -83512,7 +96927,31 @@ SQLITE_PRIVATE Index *sqlite3CreateIndex(
requestedSortOrder = pListItem->sortOrder & sortOrderMask;
pIndex->aSortOrder[i] = (u8)requestedSortOrder;
}
+
+ /* Append the table key to the end of the index. For WITHOUT ROWID
+ ** tables (when pPk!=0) this will be the declared PRIMARY KEY. For
+ ** normal tables (when pPk==0) this will be the rowid.
+ */
+ if( pPk ){
+ for(j=0; j<pPk->nKeyCol; j++){
+ int x = pPk->aiColumn[j];
+ assert( x>=0 );
+ if( hasColumn(pIndex->aiColumn, pIndex->nKeyCol, x) ){
+ pIndex->nColumn--;
+ }else{
+ pIndex->aiColumn[i] = x;
+ pIndex->azColl[i] = pPk->azColl[j];
+ pIndex->aSortOrder[i] = pPk->aSortOrder[j];
+ i++;
+ }
+ }
+ assert( i==pIndex->nColumn );
+ }else{
+ pIndex->aiColumn[i] = XN_ROWID;
+ pIndex->azColl[i] = sqlite3StrBINARY;
+ }
sqlite3DefaultRowEst(pIndex);
+ if( pParse->pNewTable==0 ) estimateIndexWidth(pIndex);
if( pTab==pParse->pNewTable ){
/* This routine has been called to create an automatic index as a
@@ -83539,27 +96978,28 @@ SQLITE_PRIVATE Index *sqlite3CreateIndex(
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 );
+ assert( IsUniqueIndex(pIdx) );
+ assert( pIdx->idxType!=SQLITE_IDXTYPE_APPDEF );
+ assert( IsUniqueIndex(pIndex) );
- if( pIdx->nColumn!=pIndex->nColumn ) continue;
- for(k=0; k<pIdx->nColumn; k++){
+ if( pIdx->nKeyCol!=pIndex->nKeyCol ) continue;
+ for(k=0; k<pIdx->nKeyCol; k++){
const char *z1;
const char *z2;
+ assert( pIdx->aiColumn[k]>=0 );
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( k==pIdx->nKeyCol ){
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.
+ ** explicitly specified behavior for the index.
*/
if( !(pIdx->onError==OE_Default || pIndex->onError==OE_Default) ){
sqlite3ErrorMsg(pParse,
@@ -83569,6 +97009,7 @@ SQLITE_PRIVATE Index *sqlite3CreateIndex(
pIdx->onError = pIndex->onError;
}
}
+ pRet = pIdx;
goto exit_create_index;
}
}
@@ -83577,12 +97018,12 @@ SQLITE_PRIVATE Index *sqlite3CreateIndex(
/* Link the new Index structure to its table and to the other
** in-memory database structures.
*/
+ assert( pParse->nErr==0 );
if( db->init.busy ){
Index *p;
assert( sqlite3SchemaMutexHeld(db, 0, pIndex->pSchema) );
p = sqlite3HashInsert(&pIndex->pSchema->idxHash,
- pIndex->zName, sqlite3Strlen30(pIndex->zName),
- pIndex);
+ pIndex->zName, pIndex);
if( p ){
assert( p==pIndex ); /* Malloc must have failed */
db->mallocFailed = 1;
@@ -83594,22 +97035,20 @@ SQLITE_PRIVATE Index *sqlite3CreateIndex(
}
}
- /* 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.
+ /* If this is the initial CREATE INDEX statement (or CREATE TABLE if the
+ ** index is an implied index for a UNIQUE or PRIMARY KEY constraint) then
+ ** emit code to allocate the index rootpage on disk and make an entry for
+ ** the index in the sqlite_master table and populate the index with
+ ** content. But, do not do this if we are simply reading the sqlite_master
+ ** table to parse the schema, or if this index is the PRIMARY KEY index
+ ** of a WITHOUT ROWID table.
**
- ** 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
+ ** If pTblName==0 it means this index is generated as an implied PRIMARY KEY
+ ** or UNIQUE index in 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 ) */
+ else if( HasRowid(pTab) || pTblName!=0 ){
Vdbe *v;
char *zStmt;
int iMem = ++pParse->nMem;
@@ -83617,22 +97056,26 @@ SQLITE_PRIVATE Index *sqlite3CreateIndex(
v = sqlite3GetVdbe(pParse);
if( v==0 ) goto exit_create_index;
-
- /* Create the rootpage for the index
- */
sqlite3BeginWriteOperation(pParse, 1, iDb);
+
+ /* Create the rootpage for the index using CreateIndex. But before
+ ** doing so, code a Noop instruction and store its address in
+ ** Index.tnum. This is required in case this index is actually a
+ ** PRIMARY KEY and the table is actually a WITHOUT ROWID table. In
+ ** that case the convertToWithoutRowidTable() routine will replace
+ ** the Noop with a Goto to jump over the VDBE code generated below. */
+ pIndex->tnum = sqlite3VdbeAddOp0(v, OP_Noop);
sqlite3VdbeAddOp2(v, OP_CreateIndex, iDb, iMem);
/* Gather the complete text of the CREATE INDEX statement into
** the zStmt variable
*/
if( pStart ){
- assert( pEnd!=0 );
+ int n = (int)(pParse->sLastToken.z - pName->z) + pParse->sLastToken.n;
+ if( pName->z[n-1]==';' ) n--;
/* 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);
+ onError==OE_None ? "" : " UNIQUE", n, pName->z);
}else{
/* An automatic index created by a PRIMARY KEY or UNIQUE constraint */
/* zStmt = sqlite3MPrintf(""); */
@@ -83661,6 +97104,8 @@ SQLITE_PRIVATE Index *sqlite3CreateIndex(
sqlite3MPrintf(db, "name='%q' AND type='index'", pIndex->zName));
sqlite3VdbeAddOp1(v, OP_Expire, 0);
}
+
+ sqlite3VdbeJumpHere(v, pIndex->tnum);
}
/* When adding an index to the list of indices for a table, make
@@ -83688,10 +97133,8 @@ SQLITE_PRIVATE Index *sqlite3CreateIndex(
/* Clean up before exiting */
exit_create_index:
- if( pIndex ){
- sqlite3DbFree(db, pIndex->zColAff);
- sqlite3DbFree(db, pIndex);
- }
+ if( pIndex ) freeIndex(db, pIndex);
+ sqlite3ExprDelete(db, pPIWhere);
sqlite3ExprListDelete(db, pList);
sqlite3SrcListDelete(db, pTblName);
sqlite3DbFree(db, zName);
@@ -83702,11 +97145,11 @@ exit_create_index:
** 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.
+** aiRowEst[0] is supposed 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 rows that match any particular combination of the first 2 columns
** of the index. And so forth. It must always be the case that
*
** aiRowEst[N]<=aiRowEst[N-1]
@@ -83717,20 +97160,27 @@ exit_create_index:
** are based on typical values found in actual indices.
*/
SQLITE_PRIVATE void sqlite3DefaultRowEst(Index *pIdx){
- tRowcnt *a = pIdx->aiRowEst;
+ /* 10, 9, 8, 7, 6 */
+ LogEst aVal[] = { 33, 32, 30, 28, 26 };
+ LogEst *a = pIdx->aiRowLogEst;
+ int nCopy = MIN(ArraySize(aVal), pIdx->nKeyCol);
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;
+
+ /* Set the first entry (number of rows in the index) to the estimated
+ ** number of rows in the table. Or 10, if the estimated number of rows
+ ** in the table is less than that. */
+ a[0] = pIdx->pTable->nRowLogEst;
+ if( a[0]<33 ) a[0] = 33; assert( 33==sqlite3LogEst(10) );
+
+ /* Estimate that a[1] is 10, a[2] is 9, a[3] is 8, a[4] is 7, a[5] is
+ ** 6 and each subsequent value (if any) is 5. */
+ memcpy(&a[1], aVal, nCopy*sizeof(LogEst));
+ for(i=nCopy+1; i<=pIdx->nKeyCol; i++){
+ a[i] = 23; assert( 23==sqlite3LogEst(5) );
}
+
+ assert( 0==sqlite3LogEst(1) );
+ if( IsUniqueIndex(pIdx) ) a[pIdx->nKeyCol] = 0;
}
/*
@@ -83761,7 +97211,7 @@ SQLITE_PRIVATE void sqlite3DropIndex(Parse *pParse, SrcList *pName, int ifExists
pParse->checkSchema = 1;
goto exit_drop_index;
}
- if( pIndex->autoIndex ){
+ if( pIndex->idxType!=SQLITE_IDXTYPE_APPDEF ){
sqlite3ErrorMsg(pParse, "index associated with UNIQUE "
"or PRIMARY KEY constraint cannot be dropped", 0);
goto exit_drop_index;
@@ -83930,7 +97380,7 @@ SQLITE_PRIVATE SrcList *sqlite3SrcListEnlarge(
assert( iStart<=pSrc->nSrc );
/* Allocate additional space if needed */
- if( pSrc->nSrc+nExtra>pSrc->nAlloc ){
+ if( (u32)pSrc->nSrc+nExtra>pSrc->nAlloc ){
SrcList *pNew;
int nAlloc = pSrc->nSrc+nExtra;
int nGot;
@@ -83942,7 +97392,7 @@ SQLITE_PRIVATE SrcList *sqlite3SrcListEnlarge(
}
pSrc = pNew;
nGot = (sqlite3DbMallocSize(db, pNew) - sizeof(*pSrc))/sizeof(pSrc->a[0])+1;
- pSrc->nAlloc = (u16)nGot;
+ pSrc->nAlloc = nGot;
}
/* Move existing slots that come after the newly inserted slots
@@ -83950,7 +97400,7 @@ SQLITE_PRIVATE SrcList *sqlite3SrcListEnlarge(
for(i=pSrc->nSrc-1; i>=iStart; i--){
pSrc->a[i+nExtra] = pSrc->a[i];
}
- pSrc->nSrc += (i16)nExtra;
+ pSrc->nSrc += nExtra;
/* Zero the newly allocated slots */
memset(&pSrc->a[iStart], 0, sizeof(pSrc->a[0])*nExtra);
@@ -84058,7 +97508,8 @@ SQLITE_PRIVATE void sqlite3SrcListDelete(sqlite3 *db, SrcList *pList){
sqlite3DbFree(db, pItem->zDatabase);
sqlite3DbFree(db, pItem->zName);
sqlite3DbFree(db, pItem->zAlias);
- sqlite3DbFree(db, pItem->zIndex);
+ if( pItem->fg.isIndexedBy ) sqlite3DbFree(db, pItem->u1.zIndexedBy);
+ if( pItem->fg.isTabFunc ) sqlite3ExprListDelete(db, pItem->u1.pFuncArg);
sqlite3DeleteTable(db, pItem->pTab);
sqlite3SelectDelete(db, pItem->pSelect);
sqlite3ExprDelete(db, pItem->pOn);
@@ -84074,7 +97525,7 @@ SQLITE_PRIVATE void sqlite3SrcListDelete(sqlite3 *db, SrcList *pList){
** 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
+** usual case. If the term has an 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
@@ -84131,18 +97582,38 @@ SQLITE_PRIVATE void sqlite3SrcListIndexedBy(Parse *pParse, SrcList *p, Token *pI
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 );
+ assert( pItem->fg.notIndexed==0 );
+ assert( pItem->fg.isIndexedBy==0 );
+ assert( pItem->fg.isTabFunc==0 );
if( pIndexedBy->n==1 && !pIndexedBy->z ){
/* A "NOT INDEXED" clause was supplied. See parse.y
** construct "indexed_opt" for details. */
- pItem->notIndexed = 1;
+ pItem->fg.notIndexed = 1;
}else{
- pItem->zIndex = sqlite3NameFromToken(pParse->db, pIndexedBy);
+ pItem->u1.zIndexedBy = sqlite3NameFromToken(pParse->db, pIndexedBy);
+ pItem->fg.isIndexedBy = (pItem->u1.zIndexedBy!=0);
}
}
}
/*
+** Add the list of function arguments to the SrcList entry for a
+** table-valued-function.
+*/
+SQLITE_PRIVATE void sqlite3SrcListFuncArgs(Parse *pParse, SrcList *p, ExprList *pList){
+ if( p ){
+ struct SrcList_item *pItem = &p->a[p->nSrc-1];
+ assert( pItem->fg.notIndexed==0 );
+ assert( pItem->fg.isIndexedBy==0 );
+ assert( pItem->fg.isTabFunc==0 );
+ pItem->u1.pFuncArg = pList;
+ pItem->fg.isTabFunc = 1;
+ }else{
+ sqlite3ExprListDelete(pParse->db, pList);
+ }
+}
+
+/*
** 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
@@ -84160,11 +97631,10 @@ SQLITE_PRIVATE void sqlite3SrcListIndexedBy(Parse *pParse, SrcList *p, Token *pI
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[i].fg.jointype = p->a[i-1].fg.jointype;
}
- p->a[0].jointype = 0;
+ p->a[0].fg.jointype = 0;
}
}
@@ -84282,59 +97752,24 @@ SQLITE_PRIVATE int sqlite3OpenTempDatabase(Parse *pParse){
}
/*
-** 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.
+** Record the fact that the schema cookie will need to be verified
+** for database iDb. The code to actually verify the schema cookie
+** will occur at the end of the top-level VDBE and will be generated
+** later, by sqlite3FinishCoding().
*/
SQLITE_PRIVATE void sqlite3CodeVerifySchema(Parse *pParse, int iDb){
Parse *pToplevel = sqlite3ParseToplevel(pParse);
+ sqlite3 *db = pToplevel->db;
-#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);
- }
+ assert( iDb>=0 && iDb<db->nDb );
+ assert( db->aDb[iDb].pBt!=0 || iDb==1 );
+ assert( iDb<SQLITE_MAX_ATTACHED+2 );
+ assert( sqlite3SchemaMutexHeld(db, iDb, 0) );
+ if( DbMaskTest(pToplevel->cookieMask, iDb)==0 ){
+ DbMaskSet(pToplevel->cookieMask, iDb);
+ pToplevel->cookieValue[iDb] = db->aDb[iDb].pSchema->schema_cookie;
+ if( !OMIT_TEMPDB && iDb==1 ){
+ sqlite3OpenTempDatabase(pToplevel);
}
}
}
@@ -84370,7 +97805,7 @@ SQLITE_PRIVATE void sqlite3CodeVerifyNamedSchema(Parse *pParse, const char *zDb)
SQLITE_PRIVATE void sqlite3BeginWriteOperation(Parse *pParse, int setStatement, int iDb){
Parse *pToplevel = sqlite3ParseToplevel(pParse);
sqlite3CodeVerifySchema(pParse, iDb);
- pToplevel->writeMask |= ((yDbMask)1)<<iDb;
+ DbMaskSet(pToplevel->writeMask, iDb);
pToplevel->isMultiWrite |= setStatement;
}
@@ -84412,12 +97847,76 @@ SQLITE_PRIVATE void sqlite3MayAbort(Parse *pParse){
** 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){
+SQLITE_PRIVATE void sqlite3HaltConstraint(
+ Parse *pParse, /* Parsing context */
+ int errCode, /* extended error code */
+ int onError, /* Constraint type */
+ char *p4, /* Error message */
+ i8 p4type, /* P4_STATIC or P4_TRANSIENT */
+ u8 p5Errmsg /* P5_ErrMsg type */
+){
Vdbe *v = sqlite3GetVdbe(pParse);
+ assert( (errCode&0xff)==SQLITE_CONSTRAINT );
if( onError==OE_Abort ){
sqlite3MayAbort(pParse);
}
- sqlite3VdbeAddOp4(v, OP_Halt, SQLITE_CONSTRAINT, onError, 0, p4, p4type);
+ sqlite3VdbeAddOp4(v, OP_Halt, errCode, onError, 0, p4, p4type);
+ if( p5Errmsg ) sqlite3VdbeChangeP5(v, p5Errmsg);
+}
+
+/*
+** Code an OP_Halt due to UNIQUE or PRIMARY KEY constraint violation.
+*/
+SQLITE_PRIVATE void sqlite3UniqueConstraint(
+ Parse *pParse, /* Parsing context */
+ int onError, /* Constraint type */
+ Index *pIdx /* The index that triggers the constraint */
+){
+ char *zErr;
+ int j;
+ StrAccum errMsg;
+ Table *pTab = pIdx->pTable;
+
+ sqlite3StrAccumInit(&errMsg, pParse->db, 0, 0, 200);
+ if( pIdx->aColExpr ){
+ sqlite3XPrintf(&errMsg, 0, "index '%q'", pIdx->zName);
+ }else{
+ for(j=0; j<pIdx->nKeyCol; j++){
+ char *zCol;
+ assert( pIdx->aiColumn[j]>=0 );
+ zCol = pTab->aCol[pIdx->aiColumn[j]].zName;
+ if( j ) sqlite3StrAccumAppend(&errMsg, ", ", 2);
+ sqlite3XPrintf(&errMsg, 0, "%s.%s", pTab->zName, zCol);
+ }
+ }
+ zErr = sqlite3StrAccumFinish(&errMsg);
+ sqlite3HaltConstraint(pParse,
+ IsPrimaryKeyIndex(pIdx) ? SQLITE_CONSTRAINT_PRIMARYKEY
+ : SQLITE_CONSTRAINT_UNIQUE,
+ onError, zErr, P4_DYNAMIC, P5_ConstraintUnique);
+}
+
+
+/*
+** Code an OP_Halt due to non-unique rowid.
+*/
+SQLITE_PRIVATE void sqlite3RowidConstraint(
+ Parse *pParse, /* Parsing context */
+ int onError, /* Conflict resolution algorithm */
+ Table *pTab /* The table with the non-unique rowid */
+){
+ char *zMsg;
+ int rc;
+ if( pTab->iPKey>=0 ){
+ zMsg = sqlite3MPrintf(pParse->db, "%s.%s", pTab->zName,
+ pTab->aCol[pTab->iPKey].zName);
+ rc = SQLITE_CONSTRAINT_PRIMARYKEY;
+ }else{
+ zMsg = sqlite3MPrintf(pParse->db, "%s.rowid", pTab->zName);
+ rc = SQLITE_CONSTRAINT_ROWID;
+ }
+ sqlite3HaltConstraint(pParse, rc, onError, zMsg, P4_DYNAMIC,
+ P5_ConstraintUnique);
}
/*
@@ -84430,8 +97929,8 @@ static int collationMatch(const char *zColl, Index *pIndex){
assert( zColl!=0 );
for(i=0; i<pIndex->nColumn; i++){
const char *z = pIndex->azColl[i];
- assert( z!=0 );
- if( 0==sqlite3StrICmp(z, zColl) ){
+ assert( z!=0 || pIndex->aiColumn[i]<0 );
+ if( pIndex->aiColumn[i]>=0 && 0==sqlite3StrICmp(z, zColl) ){
return 1;
}
}
@@ -84550,41 +98049,111 @@ SQLITE_PRIVATE void sqlite3Reindex(Parse *pParse, Token *pName1, Token *pName2){
#endif
/*
-** Return a dynamicly allocated KeyInfo structure that can be used
-** with OP_OpenRead or OP_OpenWrite to access database index pIdx.
+** Return a KeyInfo structure that is appropriate for the given Index.
**
-** 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.
+** The KeyInfo structure for an index is cached in the Index object.
+** So there might be multiple references to the returned pointer. The
+** caller should not try to modify the KeyInfo object.
+**
+** The caller should invoke sqlite3KeyInfoUnref() on the returned object
+** when it has finished using it.
*/
-SQLITE_PRIVATE KeyInfo *sqlite3IndexKeyinfo(Parse *pParse, Index *pIdx){
+SQLITE_PRIVATE KeyInfo *sqlite3KeyInfoOfIndex(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);
-
+ int nKey = pIdx->nKeyCol;
+ KeyInfo *pKey;
+ if( pParse->nErr ) return 0;
+ if( pIdx->uniqNotNull ){
+ pKey = sqlite3KeyInfoAlloc(pParse->db, nKey, nCol-nKey);
+ }else{
+ pKey = sqlite3KeyInfoAlloc(pParse->db, nCol, 0);
+ }
if( pKey ){
- pKey->db = pParse->db;
- pKey->aSortOrder = (u8 *)&(pKey->aColl[nCol]);
- assert( &pKey->aSortOrder[nCol]==&(((u8 *)pKey)[nBytes]) );
+ assert( sqlite3KeyInfoIsWriteable(pKey) );
for(i=0; i<nCol; i++){
- char *zColl = pIdx->azColl[i];
- assert( zColl );
- pKey->aColl[i] = sqlite3LocateCollSeq(pParse, zColl);
+ const char *zColl = pIdx->azColl[i];
+ pKey->aColl[i] = zColl==sqlite3StrBINARY ? 0 :
+ sqlite3LocateCollSeq(pParse, zColl);
pKey->aSortOrder[i] = pIdx->aSortOrder[i];
}
- pKey->nField = (u16)nCol;
+ if( pParse->nErr ){
+ sqlite3KeyInfoUnref(pKey);
+ pKey = 0;
+ }
+ }
+ return pKey;
+}
+
+#ifndef SQLITE_OMIT_CTE
+/*
+** This routine is invoked once per CTE by the parser while parsing a
+** WITH clause.
+*/
+SQLITE_PRIVATE With *sqlite3WithAdd(
+ Parse *pParse, /* Parsing context */
+ With *pWith, /* Existing WITH clause, or NULL */
+ Token *pName, /* Name of the common-table */
+ ExprList *pArglist, /* Optional column name list for the table */
+ Select *pQuery /* Query used to initialize the table */
+){
+ sqlite3 *db = pParse->db;
+ With *pNew;
+ char *zName;
+
+ /* Check that the CTE name is unique within this WITH clause. If
+ ** not, store an error in the Parse structure. */
+ zName = sqlite3NameFromToken(pParse->db, pName);
+ if( zName && pWith ){
+ int i;
+ for(i=0; i<pWith->nCte; i++){
+ if( sqlite3StrICmp(zName, pWith->a[i].zName)==0 ){
+ sqlite3ErrorMsg(pParse, "duplicate WITH table name: %s", zName);
+ }
+ }
}
- if( pParse->nErr ){
- sqlite3DbFree(db, pKey);
- pKey = 0;
+ if( pWith ){
+ int nByte = sizeof(*pWith) + (sizeof(pWith->a[1]) * pWith->nCte);
+ pNew = sqlite3DbRealloc(db, pWith, nByte);
+ }else{
+ pNew = sqlite3DbMallocZero(db, sizeof(*pWith));
+ }
+ assert( zName!=0 || pNew==0 );
+ assert( db->mallocFailed==0 || pNew==0 );
+
+ if( pNew==0 ){
+ sqlite3ExprListDelete(db, pArglist);
+ sqlite3SelectDelete(db, pQuery);
+ sqlite3DbFree(db, zName);
+ pNew = pWith;
+ }else{
+ pNew->a[pNew->nCte].pSelect = pQuery;
+ pNew->a[pNew->nCte].pCols = pArglist;
+ pNew->a[pNew->nCte].zName = zName;
+ pNew->a[pNew->nCte].zCteErr = 0;
+ pNew->nCte++;
+ }
+
+ return pNew;
+}
+
+/*
+** Free the contents of the With object passed as the second argument.
+*/
+SQLITE_PRIVATE void sqlite3WithDelete(sqlite3 *db, With *pWith){
+ if( pWith ){
+ int i;
+ for(i=0; i<pWith->nCte; i++){
+ struct Cte *pCte = &pWith->a[i];
+ sqlite3ExprListDelete(db, pCte->pCols);
+ sqlite3SelectDelete(db, pCte->pSelect);
+ sqlite3DbFree(db, pCte->zName);
+ }
+ sqlite3DbFree(db, pWith);
}
- return pKey;
}
+#endif /* !defined(SQLITE_OMIT_CTE) */
/************** End of build.c ***********************************************/
/************** Begin file callback.c ****************************************/
@@ -84604,6 +98173,7 @@ SQLITE_PRIVATE KeyInfo *sqlite3IndexKeyinfo(Parse *pParse, Index *pIdx){
** of user defined functions and collation sequences.
*/
+/* #include "sqliteInt.h" */
/*
** Invoke the 'collation needed' callback to request a collation sequence
@@ -84731,7 +98301,7 @@ SQLITE_PRIVATE int sqlite3CheckCollSeq(Parse *pParse, CollSeq *pColl){
**
** 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.
+** preferred 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
@@ -84743,11 +98313,11 @@ static CollSeq *findCollSeqEntry(
int create /* Create a new entry if true */
){
CollSeq *pColl;
- int nName = sqlite3Strlen30(zName);
- pColl = sqlite3HashFind(&db->aCollSeq, zName, nName);
+ pColl = sqlite3HashFind(&db->aCollSeq, zName);
if( 0==pColl && create ){
- pColl = sqlite3DbMallocZero(db, 3*sizeof(*pColl) + nName + 1 );
+ int nName = sqlite3Strlen30(zName);
+ pColl = sqlite3DbMallocZero(db, 3*sizeof(*pColl) + nName + 1);
if( pColl ){
CollSeq *pDel = 0;
pColl[0].zName = (char*)&pColl[3];
@@ -84758,7 +98328,7 @@ static CollSeq *findCollSeqEntry(
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);
+ pDel = sqlite3HashInsert(&db->aCollSeq, pColl[0].zName, pColl);
/* If a malloc() failure occurred in sqlite3HashInsert(), it will
** return the pColl pointer to be deleted (because it wasn't added
@@ -84859,9 +98429,9 @@ static int matchQuality(
}
/* Bonus points if the text encoding matches */
- if( enc==p->iPrefEnc ){
+ if( enc==(p->funcFlags & SQLITE_FUNC_ENCMASK) ){
match += 2; /* Exact encoding match */
- }else if( (enc & p->iPrefEnc & 2)!=0 ){
+ }else if( (enc & p->funcFlags & 2)!=0 ){
match += 1; /* Both are UTF16, but with different byte orders */
}
@@ -84946,7 +98516,6 @@ SQLITE_PRIVATE FuncDef *sqlite3FindFunction(
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.
@@ -84995,7 +98564,7 @@ SQLITE_PRIVATE FuncDef *sqlite3FindFunction(
(pBest = sqlite3DbMallocZero(db, sizeof(*pBest)+nName+1))!=0 ){
pBest->zName = (char *)&pBest[1];
pBest->nArg = (u16)nArg;
- pBest->iPrefEnc = enc;
+ pBest->funcFlags = enc;
memcpy(pBest->zName, zName, nName);
pBest->zName[nName] = 0;
sqlite3FuncDefInsert(&db->aFunc, pBest);
@@ -85037,9 +98606,9 @@ SQLITE_PRIVATE void sqlite3SchemaClear(void *p){
sqlite3HashClear(&temp1);
sqlite3HashClear(&pSchema->fkeyHash);
pSchema->pSeqTab = 0;
- if( pSchema->flags & DB_SchemaLoaded ){
+ if( pSchema->schemaFlags & DB_SchemaLoaded ){
pSchema->iGeneration++;
- pSchema->flags &= ~DB_SchemaLoaded;
+ pSchema->schemaFlags &= ~DB_SchemaLoaded;
}
}
@@ -85082,6 +98651,7 @@ SQLITE_PRIVATE Schema *sqlite3SchemaGet(sqlite3 *db, Btree *pBt){
** This file contains C code routines that are called by the parser
** in order to generate code for DELETE FROM statements.
*/
+/* #include "sqliteInt.h" */
/*
** While a SrcList can in general represent multiple tables and subqueries
@@ -85159,33 +98729,27 @@ 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 */
+ int iCur /* Cursor number for ephemeral table */
){
SelectDest dest;
- Select *pDup;
+ Select *pSel;
+ SrcList *pFrom;
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;
- }
+ int iDb = sqlite3SchemaToIndex(db, pView->pSchema);
+ pWhere = sqlite3ExprDup(db, pWhere, 0);
+ pFrom = sqlite3SrcListAppend(db, 0, 0, 0);
+ if( pFrom ){
+ assert( pFrom->nSrc==1 );
+ pFrom->a[0].zName = sqlite3DbStrDup(db, pView->zName);
+ pFrom->a[0].zDatabase = sqlite3DbStrDup(db, db->aDb[iDb].zName);
+ assert( pFrom->a[0].pOn==0 );
+ assert( pFrom->a[0].pUsing==0 );
+ }
+ pSel = sqlite3SelectNew(pParse, 0, pFrom, pWhere, 0, 0, 0,
+ SF_IncludeHidden, 0, 0);
sqlite3SelectDestInit(&dest, SRT_EphemTab, iCur);
- sqlite3Select(pParse, pDup, &dest);
- sqlite3SelectDelete(db, pDup);
+ sqlite3Select(pParse, pSel, &dest);
+ sqlite3SelectDelete(db, pSel);
}
#endif /* !defined(SQLITE_OMIT_VIEW) && !defined(SQLITE_OMIT_TRIGGER) */
@@ -85205,7 +98769,7 @@ SQLITE_PRIVATE Expr *sqlite3LimitWhere(
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. */
+ char *zStmtType /* Either DELETE or UPDATE. For err msgs. */
){
Expr *pWhereRowid = NULL; /* WHERE rowid .. */
Expr *pInClause = NULL; /* WHERE rowid IN ( select ) */
@@ -85265,7 +98829,7 @@ SQLITE_PRIVATE Expr *sqlite3LimitWhere(
pInClause->x.pSelect = pSelect;
pInClause->flags |= EP_xIsSelect;
- sqlite3ExprSetHeight(pParse, pInClause);
+ sqlite3ExprSetHeightAndFlags(pParse, pInClause);
return pInClause;
/* something went wrong. clean up anything allocated. */
@@ -85280,7 +98844,8 @@ limit_where_cleanup_2:
sqlite3ExprDelete(pParse->db, pOffset);
return 0;
}
-#endif /* defined(SQLITE_ENABLE_UPDATE_DELETE_LIMIT) && !defined(SQLITE_OMIT_SUBQUERY) */
+#endif /* defined(SQLITE_ENABLE_UPDATE_DELETE_LIMIT) */
+ /* && !defined(SQLITE_OMIT_SUBQUERY) */
/*
** Generate code for a DELETE FROM statement.
@@ -85297,21 +98862,37 @@ SQLITE_PRIVATE void sqlite3DeleteFrom(
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 */
+ int iTabCur; /* Cursor number for the table */
+ int iDataCur = 0; /* VDBE cursor for the canonical data source */
+ int iIdxCur = 0; /* Cursor number of the first index */
+ int nIdx; /* Number of indices */
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 */
-
+ int eOnePass; /* ONEPASS_OFF or _SINGLE or _MULTI */
+ int aiCurOnePass[2]; /* The write cursors opened by WHERE_ONEPASS */
+ u8 *aToOpen = 0; /* Open cursor iTabCur+j if aToOpen[j] is true */
+ Index *pPk; /* The PRIMARY KEY index on the table */
+ int iPk = 0; /* First of nPk registers holding PRIMARY KEY value */
+ i16 nPk = 1; /* Number of columns in the PRIMARY KEY */
+ int iKey; /* Memory cell holding key of row to be deleted */
+ i16 nKey; /* Number of memory cells in the row key */
+ int iEphCur = 0; /* Ephemeral table holding all primary key values */
+ int iRowSet = 0; /* Register for rowset of rows to delete */
+ int addrBypass = 0; /* Address of jump over the delete logic */
+ int addrLoop = 0; /* Top of the delete loop */
+ int addrEphOpen = 0; /* Instruction to open the Ephemeral table */
+
#ifndef SQLITE_OMIT_TRIGGER
int isView; /* True if attempting to delete from a view */
Trigger *pTrigger; /* List of table triggers, if required */
+ int bComplex; /* True if there are either triggers or FKs */
#endif
memset(&sContext, 0, sizeof(sContext));
@@ -85335,9 +98916,11 @@ SQLITE_PRIVATE void sqlite3DeleteFrom(
#ifndef SQLITE_OMIT_TRIGGER
pTrigger = sqlite3TriggersExist(pParse, pTab, TK_DELETE, 0, 0);
isView = pTab->pSelect!=0;
+ bComplex = pTrigger || sqlite3FkRequired(pParse, pTab, 0, 0);
#else
# define pTrigger 0
# define isView 0
+# define bComplex 0
#endif
#ifdef SQLITE_OMIT_VIEW
# undef isView
@@ -85363,11 +98946,11 @@ SQLITE_PRIVATE void sqlite3DeleteFrom(
}
assert(!isView || pTrigger);
- /* Assign cursor number to the table and all its indices.
+ /* Assign cursor numbers 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){
+ iTabCur = pTabList->a[0].iCursor = pParse->nTab++;
+ for(nIdx=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, nIdx++){
pParse->nTab++;
}
@@ -85387,11 +98970,12 @@ SQLITE_PRIVATE void sqlite3DeleteFrom(
sqlite3BeginWriteOperation(pParse, 1, iDb);
/* If we are trying to delete from a view, realize that view into
- ** a ephemeral table.
+ ** an ephemeral table.
*/
#if !defined(SQLITE_OMIT_VIEW) && !defined(SQLITE_OMIT_TRIGGER)
if( isView ){
- sqlite3MaterializeView(pParse, pTab, pWhere, iCur);
+ sqlite3MaterializeView(pParse, pTab, pWhere, iTabCur);
+ iDataCur = iIdxCur = iTabCur;
}
#endif
@@ -85417,82 +99001,199 @@ SQLITE_PRIVATE void sqlite3DeleteFrom(
** 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)
+ if( rcauth==SQLITE_OK
+ && pWhere==0
+ && !bComplex
+ && !IsVirtual(pTab)
){
assert( !isView );
- sqlite3VdbeAddOp4(v, OP_Clear, pTab->tnum, iDb, memCnt,
- pTab->zName, P4_STATIC);
+ sqlite3TableLock(pParse, iDb, pTab->tnum, 1, pTab->zName);
+ if( HasRowid(pTab) ){
+ 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.
+ u16 wcf = WHERE_ONEPASS_DESIRED|WHERE_DUPLICATES_OK;
+ wcf |= (bComplex ? 0 : WHERE_ONEPASS_MULTIROW);
+ if( HasRowid(pTab) ){
+ /* For a rowid table, initialize the RowSet to an empty set */
+ pPk = 0;
+ nPk = 1;
+ iRowSet = ++pParse->nMem;
+ sqlite3VdbeAddOp2(v, OP_Null, 0, iRowSet);
+ }else{
+ /* For a WITHOUT ROWID table, create an ephemeral table used to
+ ** hold all primary keys for rows to be deleted. */
+ pPk = sqlite3PrimaryKeyIndex(pTab);
+ assert( pPk!=0 );
+ nPk = pPk->nKeyCol;
+ iPk = pParse->nMem+1;
+ pParse->nMem += nPk;
+ iEphCur = pParse->nTab++;
+ addrEphOpen = sqlite3VdbeAddOp2(v, OP_OpenEphemeral, iEphCur, nPk);
+ sqlite3VdbeSetP4KeyInfo(pParse, pPk);
+ }
+
+ /* Construct a query to find the rowid or primary key for every row
+ ** to be deleted, based on the WHERE clause. Set variable eOnePass
+ ** to indicate the strategy used to implement this delete:
+ **
+ ** ONEPASS_OFF: Two-pass approach - use a FIFO for rowids/PK values.
+ ** ONEPASS_SINGLE: One-pass approach - at most one row deleted.
+ ** ONEPASS_MULTI: One-pass approach - any number of rows may be deleted.
*/
- sqlite3VdbeAddOp2(v, OP_Null, 0, iRowSet);
- pWInfo = sqlite3WhereBegin(
- pParse, pTabList, pWhere, 0, 0, WHERE_DUPLICATES_OK, 0
- );
+ pWInfo = sqlite3WhereBegin(pParse, pTabList, pWhere, 0, 0, wcf, iTabCur+1);
if( pWInfo==0 ) goto delete_from_cleanup;
- regRowid = sqlite3ExprCodeGetColumn(pParse, pTab, -1, iCur, iRowid, 0);
- sqlite3VdbeAddOp2(v, OP_RowSetAdd, iRowSet, regRowid);
+ eOnePass = sqlite3WhereOkOnePass(pWInfo, aiCurOnePass);
+ assert( IsVirtual(pTab)==0 || eOnePass!=ONEPASS_MULTI );
+ assert( IsVirtual(pTab) || bComplex || eOnePass!=ONEPASS_OFF );
+
+ /* Keep track of the number of rows to be deleted */
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);
-
+
+ /* Extract the rowid or primary key for the current row */
+ if( pPk ){
+ for(i=0; i<nPk; i++){
+ assert( pPk->aiColumn[i]>=0 );
+ sqlite3ExprCodeGetColumnOfTable(v, pTab, iTabCur,
+ pPk->aiColumn[i], iPk+i);
+ }
+ iKey = iPk;
+ }else{
+ iKey = pParse->nMem + 1;
+ iKey = sqlite3ExprCodeGetColumn(pParse, pTab, -1, iTabCur, iKey, 0);
+ if( iKey>pParse->nMem ) pParse->nMem = iKey;
+ }
+
+ if( eOnePass!=ONEPASS_OFF ){
+ /* For ONEPASS, no need to store the rowid/primary-key. There is only
+ ** one, so just keep it in its register(s) and fall through to the
+ ** delete code. */
+ nKey = nPk; /* OP_Found will use an unpacked key */
+ aToOpen = sqlite3DbMallocRaw(db, nIdx+2);
+ if( aToOpen==0 ){
+ sqlite3WhereEnd(pWInfo);
+ goto delete_from_cleanup;
+ }
+ memset(aToOpen, 1, nIdx+1);
+ aToOpen[nIdx+1] = 0;
+ if( aiCurOnePass[0]>=0 ) aToOpen[aiCurOnePass[0]-iTabCur] = 0;
+ if( aiCurOnePass[1]>=0 ) aToOpen[aiCurOnePass[1]-iTabCur] = 0;
+ if( addrEphOpen ) sqlite3VdbeChangeToNoop(v, addrEphOpen);
+ }else{
+ if( pPk ){
+ /* Add the PK key for this row to the temporary table */
+ iKey = ++pParse->nMem;
+ nKey = 0; /* Zero tells OP_Found to use a composite key */
+ sqlite3VdbeAddOp4(v, OP_MakeRecord, iPk, nPk, iKey,
+ sqlite3IndexAffinityStr(pParse->db, pPk), nPk);
+ sqlite3VdbeAddOp2(v, OP_IdxInsert, iEphCur, iKey);
+ }else{
+ /* Add the rowid of the row to be deleted to the RowSet */
+ nKey = 1; /* OP_Seek always uses a single rowid */
+ sqlite3VdbeAddOp2(v, OP_RowSetAdd, iRowSet, iKey);
+ }
+ }
+
+ /* If this DELETE cannot use the ONEPASS strategy, this is the
+ ** end of the WHERE loop */
+ if( eOnePass!=ONEPASS_OFF ){
+ addrBypass = sqlite3VdbeMakeLabel(v);
+ }else{
+ sqlite3WhereEnd(pWInfo);
+ }
+
/* 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. */
+ ** triggers.
+ */
if( !isView ){
- sqlite3OpenTableAndIndices(pParse, pTab, iCur, OP_OpenWrite);
+ int iAddrOnce = 0;
+ u8 p5 = (eOnePass==ONEPASS_OFF ? 0 : OPFLAG_FORDELETE);
+ if( eOnePass==ONEPASS_MULTI ){
+ iAddrOnce = sqlite3CodeOnce(pParse); VdbeCoverage(v);
+ }
+ testcase( IsVirtual(pTab) );
+ sqlite3OpenTableAndIndices(pParse, pTab, OP_OpenWrite, p5, iTabCur,
+ aToOpen, &iDataCur, &iIdxCur);
+ assert( pPk || IsVirtual(pTab) || iDataCur==iTabCur );
+ assert( pPk || IsVirtual(pTab) || iIdxCur==iDataCur+1 );
+ if( eOnePass==ONEPASS_MULTI ) sqlite3VdbeJumpHere(v, iAddrOnce);
}
-
- addr = sqlite3VdbeAddOp3(v, OP_RowSetRead, iRowSet, end, iRowid);
-
+
+ /* Set up a loop over the rowids/primary-keys that were found in the
+ ** where-clause loop above.
+ */
+ if( eOnePass!=ONEPASS_OFF ){
+ assert( nKey==nPk ); /* OP_Found will use an unpacked key */
+ if( !IsVirtual(pTab) && aToOpen[iDataCur-iTabCur] ){
+ assert( pPk!=0 || pTab->pSelect!=0 );
+ sqlite3VdbeAddOp4Int(v, OP_NotFound, iDataCur, addrBypass, iKey, nKey);
+ VdbeCoverage(v);
+ }
+ }else if( pPk ){
+ addrLoop = sqlite3VdbeAddOp1(v, OP_Rewind, iEphCur); VdbeCoverage(v);
+ sqlite3VdbeAddOp2(v, OP_RowKey, iEphCur, iKey);
+ assert( nKey==0 ); /* OP_Found will use a composite key */
+ }else{
+ addrLoop = sqlite3VdbeAddOp3(v, OP_RowSetRead, iRowSet, 0, iKey);
+ VdbeCoverage(v);
+ assert( nKey==1 );
+ }
+
/* 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);
+ sqlite3VdbeAddOp4(v, OP_VUpdate, 0, 1, iKey, pVTab, P4_VTAB);
sqlite3VdbeChangeP5(v, OE_Abort);
+ assert( eOnePass==ONEPASS_OFF || eOnePass==ONEPASS_SINGLE );
sqlite3MayAbort(pParse);
+ if( eOnePass==ONEPASS_SINGLE && sqlite3IsToplevel(pParse) ){
+ pParse->isMultiWrite = 0;
+ }
}else
#endif
{
int count = (pParse->nested==0); /* True to count changes */
- sqlite3GenerateRowDelete(pParse, pTab, iCur, iRowid, count, pTrigger, OE_Default);
+ int iIdxNoSeek = -1;
+ if( bComplex==0 && aiCurOnePass[1]!=iDataCur ){
+ iIdxNoSeek = aiCurOnePass[1];
+ }
+ sqlite3GenerateRowDelete(pParse, pTab, pTrigger, iDataCur, iIdxCur,
+ iKey, nKey, count, OE_Default, eOnePass, iIdxNoSeek);
}
-
- /* End of the delete loop */
- sqlite3VdbeAddOp2(v, OP_Goto, 0, addr);
- sqlite3VdbeResolveLabel(v, end);
-
+
+ /* End of the loop over all rowids/primary-keys. */
+ if( eOnePass!=ONEPASS_OFF ){
+ sqlite3VdbeResolveLabel(v, addrBypass);
+ sqlite3WhereEnd(pWInfo);
+ }else if( pPk ){
+ sqlite3VdbeAddOp2(v, OP_Next, iEphCur, addrLoop+1); VdbeCoverage(v);
+ sqlite3VdbeJumpHere(v, addrLoop);
+ }else{
+ sqlite3VdbeGoto(v, addrLoop);
+ sqlite3VdbeJumpHere(v, addrLoop);
+ }
+
/* 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);
+ if( !pPk ) sqlite3VdbeAddOp1(v, OP_Close, iDataCur);
+ for(i=0, pIdx=pTab->pIndex; pIdx; i++, pIdx=pIdx->pNext){
+ sqlite3VdbeAddOp1(v, OP_Close, iIdxCur + i);
}
- sqlite3VdbeAddOp1(v, OP_Close, iCur);
}
- }
+ } /* End non-truncate path */
/* Update the sqlite_sequence table by storing the content of the
** maximum rowid counter values recorded while inserting into
@@ -85516,10 +99217,11 @@ delete_from_cleanup:
sqlite3AuthContextPop(&sContext);
sqlite3SrcListDelete(db, pTabList);
sqlite3ExprDelete(db, pWhere);
+ sqlite3DbFree(db, aToOpen);
return;
}
/* Make sure "isView" and other macros defined above are undefined. Otherwise
-** thely may interfere with compilation of other functions in this file
+** they 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
@@ -85530,50 +99232,83 @@ delete_from_cleanup:
/*
** This routine generates VDBE code that causes a single row of a
-** single table to be deleted.
+** single table to be deleted. Both the original table entry and
+** all indices are removed.
**
-** The VDBE must be in a particular state when this routine is called.
-** These are the requirements:
+** Preconditions:
**
-** 1. A read/write cursor pointing to pTab, the table containing the row
-** to be deleted, must be opened as cursor number $iCur.
+** 1. iDataCur is an open cursor on the btree that is the canonical data
+** store for the table. (This will be either the table itself,
+** in the case of a rowid table, or the PRIMARY KEY index in the case
+** of a WITHOUT ROWID table.)
**
** 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.
+** cursor number iIdxCur+i for the i-th index.
+**
+** 3. The primary key for the row to be deleted must be stored in a
+** sequence of nPk memory cells starting at iPk. If nPk==0 that means
+** that a search record formed from OP_MakeRecord is contained in the
+** single memory location iPk.
+**
+** eMode:
+** Parameter eMode may be passed either ONEPASS_OFF (0), ONEPASS_SINGLE, or
+** ONEPASS_MULTI. If eMode is not ONEPASS_OFF, then the cursor
+** iDataCur already points to the row to delete. If eMode is ONEPASS_OFF
+** then this function must seek iDataCur to the entry identified by iPk
+** and nPk before reading from it.
+**
+** If eMode is ONEPASS_MULTI, then this call is being made as part
+** of a ONEPASS delete that affects multiple rows. In this case, if
+** iIdxNoSeek is a valid cursor number (>=0), then its position should
+** be preserved following the delete operation. Or, if iIdxNoSeek is not
+** a valid cursor number, the position of iDataCur should be preserved
+** instead.
+**
+** iIdxNoSeek:
+** If iIdxNoSeek is a valid cursor number (>=0), then it identifies an
+** index cursor (from within array of cursors starting at iIdxCur) that
+** already points to the index entry to be deleted.
*/
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 */
+ int iDataCur, /* Cursor from which column data is extracted */
+ int iIdxCur, /* First index cursor */
+ int iPk, /* First memory cell containing the PRIMARY KEY */
+ i16 nPk, /* Number of PRIMARY KEY memory cells */
+ u8 count, /* If non-zero, increment the row change counter */
+ u8 onconf, /* Default ON CONFLICT policy for triggers */
+ u8 eMode, /* ONEPASS_OFF, _SINGLE, or _MULTI. See above */
+ int iIdxNoSeek /* Cursor number of cursor that does not need seeking */
){
Vdbe *v = pParse->pVdbe; /* Vdbe */
int iOld = 0; /* First register in OLD.* array */
int iLabel; /* Label resolved to end of generated code */
+ u8 opSeek; /* Seek opcode */
/* Vdbe is guaranteed to have been allocated by this stage. */
assert( v );
+ VdbeModuleComment((v, "BEGIN: GenRowDel(%d,%d,%d,%d)",
+ iDataCur, iIdxCur, iPk, (int)nPk));
/* 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);
+ opSeek = HasRowid(pTab) ? OP_NotExists : OP_NotFound;
+ if( eMode==ONEPASS_OFF ){
+ sqlite3VdbeAddOp4Int(v, opSeek, iDataCur, iLabel, iPk, nPk);
+ VdbeCoverageIf(v, opSeek==OP_NotExists);
+ VdbeCoverageIf(v, opSeek==OP_NotFound);
+ }
/* 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.* */
+ int addrStart; /* Start of BEFORE trigger programs */
/* TODO: Could use temporary registers here. Also could attempt to
** avoid copying the contents of the rowid register. */
@@ -85586,45 +99321,57 @@ SQLITE_PRIVATE void sqlite3GenerateRowDelete(
/* 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);
+ sqlite3VdbeAddOp2(v, OP_Copy, iPk, iOld);
for(iCol=0; iCol<pTab->nCol; iCol++){
- if( mask==0xffffffff || mask&(1<<iCol) ){
- sqlite3ExprCodeGetColumnOfTable(v, pTab, iCur, iCol, iOld+iCol+1);
+ testcase( mask!=0xffffffff && iCol==31 );
+ testcase( mask!=0xffffffff && iCol==32 );
+ if( mask==0xffffffff || (iCol<=31 && (mask & MASKBIT32(iCol))!=0) ){
+ sqlite3ExprCodeGetColumnOfTable(v, pTab, iDataCur, iCol, iOld+iCol+1);
}
}
/* Invoke BEFORE DELETE trigger programs. */
+ addrStart = sqlite3VdbeCurrentAddr(v);
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);
+ /* If any BEFORE triggers were coded, then seek the cursor to the
+ ** row to be deleted again. It may be that the BEFORE triggers moved
+ ** the cursor or of already deleted the row that the cursor was
+ ** pointing to.
+ */
+ if( addrStart<sqlite3VdbeCurrentAddr(v) ){
+ sqlite3VdbeAddOp4Int(v, opSeek, iDataCur, iLabel, iPk, nPk);
+ VdbeCoverageIf(v, opSeek==OP_NotExists);
+ VdbeCoverageIf(v, opSeek==OP_NotFound);
+ }
/* 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);
+ sqlite3FkCheck(pParse, pTab, iOld, 0, 0, 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));
+ sqlite3GenerateRowIndexDelete(pParse, pTab, iDataCur, iIdxCur,0,iIdxNoSeek);
+ sqlite3VdbeAddOp2(v, OP_Delete, iDataCur, (count?OPFLAG_NCHANGE:0));
if( count ){
sqlite3VdbeChangeP4(v, -1, pTab->zName, P4_TRANSIENT);
}
+ if( iIdxNoSeek>=0 ){
+ sqlite3VdbeAddOp1(v, OP_Delete, iIdxNoSeek);
+ }
+ sqlite3VdbeChangeP5(v, eMode==ONEPASS_MULTI);
}
/* 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);
+ sqlite3FkActions(pParse, pTab, 0, iOld, 0, 0);
/* Invoke AFTER DELETE trigger programs. */
sqlite3CodeRowTrigger(pParse, pTrigger,
@@ -85635,93 +99382,156 @@ SQLITE_PRIVATE void sqlite3GenerateRowDelete(
** trigger programs were invoked. Or if a trigger program throws a
** RAISE(IGNORE) exception. */
sqlite3VdbeResolveLabel(v, iLabel);
+ VdbeModuleComment((v, "END: GenRowDel()"));
}
/*
** This routine generates VDBE code that causes the deletion of all
-** index entries associated with a single row of a single table.
+** index entries associated with a single row of a single table, pTab
**
-** The VDBE must be in a particular state when this routine is called.
-** These are the requirements:
+** Preconditions:
**
-** 1. A read/write cursor pointing to pTab, the table containing the row
-** to be deleted, must be opened as cursor number "iCur".
+** 1. A read/write cursor "iDataCur" must be open on the canonical storage
+** btree for the table pTab. (This will be either the table itself
+** for rowid tables or to the primary key index for WITHOUT ROWID
+** tables.)
**
** 2. Read/write cursors for all indices of pTab must be open as
-** cursor number iCur+i for the i-th index.
+** cursor number iIdxCur+i for the i-th index. (The pTab->pIndex
+** index is the 0-th index.)
**
-** 3. The "iCur" cursor must be pointing to the row that is to be
-** deleted.
+** 3. The "iDataCur" cursor must be already be positioned on 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;
+ int iDataCur, /* Cursor of table holding data. */
+ int iIdxCur, /* First index cursor */
+ int *aRegIdx, /* Only delete if aRegIdx!=0 && aRegIdx[i]>0 */
+ int iIdxNoSeek /* Do not delete from this cursor */
+){
+ int i; /* Index loop counter */
+ int r1 = -1; /* Register holding an index key */
+ int iPartIdxLabel; /* Jump destination for skipping partial index entries */
+ Index *pIdx; /* Current index */
+ Index *pPrior = 0; /* Prior index */
+ Vdbe *v; /* The prepared statement under construction */
+ Index *pPk; /* PRIMARY KEY index, or NULL for rowid tables */
- 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);
+ v = pParse->pVdbe;
+ pPk = HasRowid(pTab) ? 0 : sqlite3PrimaryKeyIndex(pTab);
+ for(i=0, pIdx=pTab->pIndex; pIdx; i++, pIdx=pIdx->pNext){
+ assert( iIdxCur+i!=iDataCur || pPk==pIdx );
+ if( aRegIdx!=0 && aRegIdx[i]==0 ) continue;
+ if( pIdx==pPk ) continue;
+ if( iIdxCur+i==iIdxNoSeek ) continue;
+ VdbeModuleComment((v, "GenRowIdxDel for %s", pIdx->zName));
+ r1 = sqlite3GenerateIndexKey(pParse, pIdx, iDataCur, 0, 1,
+ &iPartIdxLabel, pPrior, r1);
+ sqlite3VdbeAddOp3(v, OP_IdxDelete, iIdxCur+i, r1,
+ pIdx->uniqNotNull ? pIdx->nKeyCol : pIdx->nColumn);
+ sqlite3ResolvePartIdxLabel(pParse, iPartIdxLabel);
+ pPrior = pIdx;
}
}
/*
-** Generate code that will assemble an index key and put it in register
+** Generate code that will assemble an index key and stores 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.
+** the entry that needs indexing. If pTab is a WITHOUT ROWID table, then
+** iCur must be the cursor of the PRIMARY KEY index.
**
** 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.
+**
+** If *piPartIdxLabel is not NULL, fill it in with a label and jump
+** to that label if pIdx is a partial index that should be skipped.
+** The label should be resolved using sqlite3ResolvePartIdxLabel().
+** A partial index should be skipped if its WHERE clause evaluates
+** to false or null. If pIdx is not a partial index, *piPartIdxLabel
+** will be set to zero which is an empty label that is ignored by
+** sqlite3ResolvePartIdxLabel().
+**
+** The pPrior and regPrior parameters are used to implement a cache to
+** avoid unnecessary register loads. If pPrior is not NULL, then it is
+** a pointer to a different index for which an index key has just been
+** computed into register regPrior. If the current pIdx index is generating
+** its key into the same sequence of registers and if pPrior and pIdx share
+** a column in common, then the register corresponding to that column already
+** holds the correct value and the loading of that register is skipped.
+** This optimization is helpful when doing a DELETE or an INTEGRITY_CHECK
+** on a table with multiple indices, and especially with the ROWID or
+** PRIMARY KEY columns of the index.
*/
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 */
+ Parse *pParse, /* Parsing context */
+ Index *pIdx, /* The index for which to generate a key */
+ int iDataCur, /* Cursor number from which to take column data */
+ int regOut, /* Put the new key into this register if not 0 */
+ int prefixOnly, /* Compute only a unique prefix of the key */
+ int *piPartIdxLabel, /* OUT: Jump to this label to skip partial index */
+ Index *pPrior, /* Previously generated index key */
+ int regPrior /* Register holding previous generated key */
){
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);
+ if( piPartIdxLabel ){
+ if( pIdx->pPartIdxWhere ){
+ *piPartIdxLabel = sqlite3VdbeMakeLabel(v);
+ pParse->iSelfTab = iDataCur;
+ sqlite3ExprCachePush(pParse);
+ sqlite3ExprIfFalseDup(pParse, pIdx->pPartIdxWhere, *piPartIdxLabel,
+ SQLITE_JUMPIFNULL);
}else{
- sqlite3VdbeAddOp3(v, OP_Column, iCur, idx, regBase+j);
- sqlite3ColumnDefault(v, pTab, idx, -1);
+ *piPartIdxLabel = 0;
}
}
- if( doMakeRec ){
- const char *zAff;
- if( pTab->pSelect
- || OptimizationDisabled(pParse->db, SQLITE_IdxRealAsInt)
+ nCol = (prefixOnly && pIdx->uniqNotNull) ? pIdx->nKeyCol : pIdx->nColumn;
+ regBase = sqlite3GetTempRange(pParse, nCol);
+ if( pPrior && (regBase!=regPrior || pPrior->pPartIdxWhere) ) pPrior = 0;
+ for(j=0; j<nCol; j++){
+ if( pPrior
+ && pPrior->aiColumn[j]==pIdx->aiColumn[j]
+ && pPrior->aiColumn[j]!=XN_EXPR
){
- zAff = 0;
- }else{
- zAff = sqlite3IndexAffinityStr(v, pIdx);
+ /* This column was already computed by the previous index */
+ continue;
}
- sqlite3VdbeAddOp3(v, OP_MakeRecord, regBase, nCol+1, regOut);
- sqlite3VdbeChangeP4(v, -1, zAff, P4_TRANSIENT);
+ sqlite3ExprCodeLoadIndexColumn(pParse, pIdx, iDataCur, j, regBase+j);
+ /* If the column affinity is REAL but the number is an integer, then it
+ ** might be stored in the table as an integer (using a compact
+ ** representation) then converted to REAL by an OP_RealAffinity opcode.
+ ** But we are getting ready to store this value back into an index, where
+ ** it should be converted by to INTEGER again. So omit the OP_RealAffinity
+ ** opcode if it is present */
+ sqlite3VdbeDeletePriorOpcode(v, OP_RealAffinity);
}
- sqlite3ReleaseTempRange(pParse, regBase, nCol+1);
+ if( regOut ){
+ sqlite3VdbeAddOp3(v, OP_MakeRecord, regBase, nCol, regOut);
+ }
+ sqlite3ReleaseTempRange(pParse, regBase, nCol);
return regBase;
}
+/*
+** If a prior call to sqlite3GenerateIndexKey() generated a jump-over label
+** because it was a partial index, then this routine should be called to
+** resolve that label.
+*/
+SQLITE_PRIVATE void sqlite3ResolvePartIdxLabel(Parse *pParse, int iLabel){
+ if( iLabel ){
+ sqlite3VdbeResolveLabel(pParse->pVdbe, iLabel);
+ sqlite3ExprCachePop(pParse);
+ }
+}
+
/************** End of delete.c **********************************************/
/************** Begin file func.c ********************************************/
/*
@@ -85735,21 +99545,25 @@ SQLITE_PRIVATE int sqlite3GenerateIndexKey(
** 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.
+** This file contains the C-language implementations for many of the SQL
+** functions of SQLite. (Some function, and in particular the date and
+** time functions, are implemented separately.)
*/
+/* #include "sqliteInt.h" */
/* #include <stdlib.h> */
/* #include <assert.h> */
+/* #include "vdbeInt.h" */
/*
** Return the collating function associated with a function.
*/
static CollSeq *sqlite3GetFuncCollSeq(sqlite3_context *context){
- return context->pColl;
+ VdbeOp *pOp;
+ assert( context->pVdbe!=0 );
+ pOp = &context->pVdbe->aOp[context->iOp-1];
+ assert( pOp->opcode==OP_CollSeq );
+ assert( pOp->p4type==P4_COLLSEQ );
+ return pOp->p4.pColl;
}
/*
@@ -85861,9 +99675,9 @@ static void absFunc(sqlite3_context *context, int argc, sqlite3_value **argv){
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
+ if( iVal==SMALLEST_INT64 ){
+ /* IMP: R-31676-45509 If X is the integer -9223372036854775808
+ ** 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;
@@ -85881,8 +99695,8 @@ static void absFunc(sqlite3_context *context, int argc, sqlite3_value **argv){
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.
+ ** IMP: R-01992-00519 Abs(X) returns 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;
@@ -85943,6 +99757,32 @@ static void instrFunc(
}
/*
+** Implementation of the printf() function.
+*/
+static void printfFunc(
+ sqlite3_context *context,
+ int argc,
+ sqlite3_value **argv
+){
+ PrintfArguments x;
+ StrAccum str;
+ const char *zFormat;
+ int n;
+ sqlite3 *db = sqlite3_context_db_handle(context);
+
+ if( argc>=1 && (zFormat = (const char*)sqlite3_value_text(argv[0]))!=0 ){
+ x.nArg = argc-1;
+ x.nUsed = 0;
+ x.apArg = argv+1;
+ sqlite3StrAccumInit(&str, db, 0, 0, db->aLimit[SQLITE_LIMIT_LENGTH]);
+ sqlite3XPrintf(&str, SQLITE_PRINTF_SQLFUNC, zFormat, &x);
+ n = str.nChar;
+ sqlite3_result_text(context, sqlite3StrAccumFinish(&str), n,
+ SQLITE_DYNAMIC);
+ }
+}
+
+/*
** Implementation of the substr() function.
**
** substr(x,p1,p2) returns p2 characters of x[] beginning with p1.
@@ -85952,7 +99792,7 @@ static void instrFunc(
**
** If p1 is negative, then we begin abs(p1) from the end of x[].
**
-** If p2 is negative, return the p2 characters preceeding p1.
+** If p2 is negative, return the p2 characters preceding p1.
*/
static void substrFunc(
sqlite3_context *context,
@@ -85989,6 +99829,14 @@ static void substrFunc(
}
}
}
+#ifdef SQLITE_SUBSTR_COMPATIBILITY
+ /* If SUBSTR_COMPATIBILITY is defined then substr(X,0,N) work the same as
+ ** as substr(X,1,N) - it returns the first N characters of X. This
+ ** is essentially a back-out of the bug-fix in check-in [5fc125d362df4b8]
+ ** from 2009-02-02 for compatibility of applications that exploited the
+ ** old buggy behavior. */
+ if( p1==0 ) p1 = 1; /* <rdar://problem/6778339> */
+#endif
if( argc==3 ){
p2 = sqlite3_value_int(argv[2]);
if( p2<0 ){
@@ -86026,13 +99874,14 @@ static void substrFunc(
for(z2=z; *z2 && p2; p2--){
SQLITE_SKIP_UTF8(z2);
}
- sqlite3_result_text(context, (char*)z, (int)(z2-z), SQLITE_TRANSIENT);
+ sqlite3_result_text64(context, (char*)z, z2-z, SQLITE_TRANSIENT,
+ SQLITE_UTF8);
}else{
if( p1+p2>len ){
p2 = len-p1;
if( p2<0 ) p2 = 0;
}
- sqlite3_result_blob(context, (char*)&z[p1], (int)p2, SQLITE_TRANSIENT);
+ sqlite3_result_blob64(context, (char*)&z[p1], (u64)p2, SQLITE_TRANSIENT);
}
}
@@ -86075,7 +99924,7 @@ static void roundFunc(sqlite3_context *context, int argc, sqlite3_value **argv){
#endif
/*
-** Allocate nByte bytes of space using sqlite3_malloc(). If the
+** Allocate nByte bytes of space using sqlite3Malloc(). 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
@@ -86091,7 +99940,7 @@ static void *contextMalloc(sqlite3_context *context, i64 nByte){
sqlite3_result_error_toobig(context);
z = 0;
}else{
- z = sqlite3Malloc((int)nByte);
+ z = sqlite3Malloc(nByte);
if( !z ){
sqlite3_result_error_nomem(context);
}
@@ -86142,14 +99991,14 @@ static void lowerFunc(sqlite3_context *context, int argc, sqlite3_value **argv){
}
/*
-** 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.
+** Some functions like COALESCE() and IFNULL() and UNLIKELY() 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. The noopFunc macro provides this.
+** noopFunc 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 */
+#define noopFunc versionFunc /* Substitute function - never called */
/*
** Implementation of random(). Return a random integer.
@@ -86262,15 +100111,15 @@ struct compareInfo {
/*
** 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.
+** character is exactly one byte in size. Also, provde the Utf8Read()
+** macro for fast reading of the next character in the common case where
+** the next character is ASCII.
*/
#if defined(SQLITE_EBCDIC)
-# define sqlite3Utf8Read(A) (*((*A)++))
-# define GlogUpperToLower(A) A = sqlite3UpperToLower[A]
+# define sqlite3Utf8Read(A) (*((*A)++))
+# define Utf8Read(A) (*(A++))
#else
-# define GlogUpperToLower(A) if( !((A)&~0x7f) ){ A = sqlite3UpperToLower[A]; }
+# define Utf8Read(A) (A[0]<0x80?*(A++):sqlite3Utf8Read(&A))
#endif
static const struct compareInfo globInfo = { '*', '?', '[', 0 };
@@ -86283,7 +100132,7 @@ 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
+** potentially be a "glob" or "like" expression. Return true (1) if they
** are the same and false (0) if they are different.
**
** Globbing rules:
@@ -86303,11 +100152,18 @@ static const struct compareInfo likeInfoAlt = { '%', '_', 0, 0 };
** "[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.
+** Like matching rules:
+**
+** '%' Matches any sequence of zero or more characters
+**
+*** '_' Matches any one character
+**
+** Ec Where E is the "esc" character and c is any other
+** character, including '%', '_', and esc, match exactly c.
**
-** Hints: to match '*' or '?', put them in "[]". Like this:
+** The comments within this routine usually assume glob matching.
**
-** abc[*]xyz Matches "abc*xyz" only
+** This routine is usually quick, but can be N**2 in the worst case.
*/
static int patternCompare(
const u8 *zPattern, /* The glob pattern */
@@ -86315,109 +100171,142 @@ static int patternCompare(
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 ){
+ u32 c, c2; /* Next pattern and input string chars */
+ u32 matchOne = pInfo->matchOne; /* "?" or "_" */
+ u32 matchAll = pInfo->matchAll; /* "*" or "%" */
+ u32 matchOther; /* "[" or the escape character */
+ u8 noCase = pInfo->noCase; /* True if uppercase==lowercase */
+ const u8 *zEscaped = 0; /* One past the last escaped input char */
+
+ /* The GLOB operator does not have an ESCAPE clause. And LIKE does not
+ ** have the matchSet operator. So we either have to look for one or
+ ** the other, never both. Hence the single variable matchOther is used
+ ** to store the one we have to look for.
+ */
+ matchOther = esc ? esc : pInfo->matchSet;
+
+ while( (c = Utf8Read(zPattern))!=0 ){
+ if( c==matchAll ){ /* Match "*" */
+ /* Skip over multiple "*" characters in the pattern. If there
+ ** are also "?" characters, skip those as well, but consume a
+ ** single character of the input string for each "?" skipped */
+ while( (c=Utf8Read(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 1; /* "*" at the end of the pattern matches */
+ }else if( c==matchOther ){
+ if( esc ){
+ c = sqlite3Utf8Read(&zPattern);
+ if( c==0 ) return 0;
+ }else{
+ /* "[...]" immediately follows the "*". We have to do a slow
+ ** recursive search in this case, but it is an unusual case. */
+ assert( matchOther<0x80 ); /* '[' is a single-byte character */
+ while( *zString
+ && patternCompare(&zPattern[-1],zString,pInfo,esc)==0 ){
+ SQLITE_SKIP_UTF8(zString);
+ }
+ return *zString!=0;
}
- return *zString!=0;
}
- while( (c2 = sqlite3Utf8Read(&zString))!=0 ){
+
+ /* At this point variable c contains the first character of the
+ ** pattern string past the "*". Search in the input string for the
+ ** first matching character and recursively contine the match from
+ ** that point.
+ **
+ ** For a case-insensitive search, set variable cx to be the same as
+ ** c but in the other case and search the input string for either
+ ** c or cx.
+ */
+ if( c<=0x80 ){
+ u32 cx;
if( noCase ){
- GlogUpperToLower(c2);
- GlogUpperToLower(c);
- while( c2 != 0 && c2 != c ){
- c2 = sqlite3Utf8Read(&zString);
- GlogUpperToLower(c2);
- }
+ cx = sqlite3Toupper(c);
+ c = sqlite3Tolower(c);
}else{
- while( c2 != 0 && c2 != c ){
- c2 = sqlite3Utf8Read(&zString);
- }
+ cx = c;
+ }
+ while( (c2 = *(zString++))!=0 ){
+ if( c2!=c && c2!=cx ) continue;
+ if( patternCompare(zPattern,zString,pInfo,esc) ) return 1;
+ }
+ }else{
+ while( (c2 = Utf8Read(zString))!=0 ){
+ if( c2!=c ) continue;
+ if( patternCompare(zPattern,zString,pInfo,esc) ) return 1;
}
- 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;
+ }
+ if( c==matchOther ){
+ if( esc ){
+ c = sqlite3Utf8Read(&zPattern);
+ if( c==0 ) return 0;
+ zEscaped = zPattern;
+ }else{
+ u32 prior_c = 0;
+ int seen = 0;
+ int invert = 0;
+ c = sqlite3Utf8Read(&zString);
+ if( c==0 ) return 0;
c2 = sqlite3Utf8Read(&zPattern);
- }
- while( c2 && c2!=']' ){
- if( c2=='-' && zPattern[0]!=']' && zPattern[0]!=0 && prior_c>0 ){
+ if( c2=='^' ){
+ invert = 1;
c2 = sqlite3Utf8Read(&zPattern);
- if( c>=prior_c && c<=c2 ) seen = 1;
- prior_c = 0;
- }else{
- if( c==c2 ){
- seen = 1;
+ }
+ 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;
}
- prior_c = c2;
+ c2 = sqlite3Utf8Read(&zPattern);
}
- 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;
+ if( c2==0 || (seen ^ invert)==0 ){
+ return 0;
+ }
+ continue;
}
- prevEscape = 0;
}
+ c2 = Utf8Read(zString);
+ if( c==c2 ) continue;
+ if( noCase && c<0x80 && c2<0x80 && sqlite3Tolower(c)==sqlite3Tolower(c2) ){
+ continue;
+ }
+ if( c==matchOne && zPattern!=zEscaped && c2!=0 ) continue;
+ return 0;
}
return *zString==0;
}
/*
+** The sqlite3_strglob() interface.
+*/
+SQLITE_API int SQLITE_STDCALL sqlite3_strglob(const char *zGlobPattern, const char *zString){
+ return patternCompare((u8*)zGlobPattern, (u8*)zString, &globInfo, 0)==0;
+}
+
+/*
+** The sqlite3_strlike() interface.
+*/
+SQLITE_API int SQLITE_STDCALL sqlite3_strlike(const char *zPattern, const char *zStr, unsigned int esc){
+ return patternCompare((u8*)zPattern, (u8*)zStr, &likeInfoNorm, esc)==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.
@@ -86449,6 +100338,17 @@ static void likeFunc(
int nPat;
sqlite3 *db = sqlite3_context_db_handle(context);
+#ifdef SQLITE_LIKE_DOESNT_MATCH_BLOBS
+ if( sqlite3_value_type(argv[0])==SQLITE_BLOB
+ || sqlite3_value_type(argv[1])==SQLITE_BLOB
+ ){
+#ifdef SQLITE_TEST
+ sqlite3_like_count++;
+#endif
+ sqlite3_result_int(context, 0);
+ return;
+ }
+#endif
zB = sqlite3_value_text(argv[0]);
zA = sqlite3_value_text(argv[1]);
@@ -86604,10 +100504,6 @@ static const char hexdigits[] = {
};
/*
-** 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
@@ -86687,6 +100583,62 @@ static void quoteFunc(sqlite3_context *context, int argc, sqlite3_value **argv){
}
/*
+** The unicode() function. Return the integer unicode code-point value
+** for the first character of the input string.
+*/
+static void unicodeFunc(
+ sqlite3_context *context,
+ int argc,
+ sqlite3_value **argv
+){
+ const unsigned char *z = sqlite3_value_text(argv[0]);
+ (void)argc;
+ if( z && z[0] ) sqlite3_result_int(context, sqlite3Utf8Read(&z));
+}
+
+/*
+** The char() function takes zero or more arguments, each of which is
+** an integer. It constructs a string where each character of the string
+** is the unicode character for the corresponding integer argument.
+*/
+static void charFunc(
+ sqlite3_context *context,
+ int argc,
+ sqlite3_value **argv
+){
+ unsigned char *z, *zOut;
+ int i;
+ zOut = z = sqlite3_malloc64( argc*4+1 );
+ if( z==0 ){
+ sqlite3_result_error_nomem(context);
+ return;
+ }
+ for(i=0; i<argc; i++){
+ sqlite3_int64 x;
+ unsigned c;
+ x = sqlite3_value_int64(argv[i]);
+ if( x<0 || x>0x10ffff ) x = 0xfffd;
+ c = (unsigned)(x & 0x1fffff);
+ 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);
+ } \
+ }
+ sqlite3_result_text64(context, (char*)z, zOut-z, sqlite3_free, SQLITE_UTF8);
+}
+
+/*
** The hex() function. Interpret the argument as a blob. Return
** a hexadecimal rendering as text.
*/
@@ -86724,23 +100676,21 @@ static void zeroblobFunc(
sqlite3_value **argv
){
i64 n;
- sqlite3 *db = sqlite3_context_db_handle(context);
+ int rc;
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 */
+ if( n<0 ) n = 0;
+ rc = sqlite3_result_zeroblob64(context, n); /* IMP: R-00293-64994 */
+ if( rc ){
+ sqlite3_result_error_code(context, rc);
}
}
/*
** 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
+** from A by replacing every occurrence of B with C. The match
** must be exact. Collating sequences are not used.
*/
static void replaceFunc(
@@ -86804,7 +100754,7 @@ static void replaceFunc(
return;
}
zOld = zOut;
- zOut = sqlite3_realloc(zOut, (int)nOut);
+ zOut = sqlite3_realloc64(zOut, (int)nOut);
if( zOut==0 ){
sqlite3_result_error_nomem(context);
sqlite3_free(zOld);
@@ -87133,6 +101083,7 @@ static void minmaxStep(
sqlite3SkipAccumulatorLoad(context);
}
}else{
+ pBest->db = sqlite3_context_db_handle(context);
sqlite3VdbeMemCopy(pBest, pArg);
}
}
@@ -87165,8 +101116,7 @@ static void groupConcatStep(
if( pAccum ){
sqlite3 *db = sqlite3_context_db_handle(context);
- int firstTerm = pAccum->useMalloc==0;
- pAccum->useMalloc = 2;
+ int firstTerm = pAccum->mxAlloc==0;
pAccum->mxAlloc = db->aLimit[SQLITE_LIMIT_LENGTH];
if( !firstTerm ){
if( argc==2 ){
@@ -87176,20 +101126,20 @@ static void groupConcatStep(
zSep = ",";
nSep = 1;
}
- sqlite3StrAccumAppend(pAccum, zSep, nSep);
+ if( nSep ) sqlite3StrAccumAppend(pAccum, zSep, nSep);
}
zVal = (char*)sqlite3_value_text(argv[0]);
nVal = sqlite3_value_bytes(argv[0]);
- sqlite3StrAccumAppend(pAccum, zVal, nVal);
+ if( zVal ) sqlite3StrAccumAppend(pAccum, zVal, nVal);
}
}
static void groupConcatFinalize(sqlite3_context *context){
StrAccum *pAccum;
pAccum = sqlite3_aggregate_context(context, 0);
if( pAccum ){
- if( pAccum->tooBig ){
+ if( pAccum->accError==STRACCUM_TOOBIG ){
sqlite3_result_error_toobig(context);
- }else if( pAccum->mallocFailed ){
+ }else if( pAccum->accError==STRACCUM_NOMEM ){
sqlite3_result_error_nomem(context);
}else{
sqlite3_result_text(context, sqlite3StrAccumFinish(pAccum), -1,
@@ -87219,7 +101169,7 @@ static void setLikeOptFlag(sqlite3 *db, const char *zName, u8 flagVal){
pDef = sqlite3FindFunction(db, zName, sqlite3Strlen30(zName),
2, SQLITE_UTF8, 0);
if( ALWAYS(pDef) ){
- pDef->flags = flagVal;
+ pDef->funcFlags |= flagVal;
}
}
@@ -87250,6 +101200,11 @@ SQLITE_PRIVATE void sqlite3RegisterLikeFunctions(sqlite3 *db, int caseSensitive)
** 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.
+**
+** *pIsNocase is set to true if uppercase and lowercase are equivalent for
+** the function (default for LIKE). If the function makes the distinction
+** between uppercase and lowercase (as does GLOB) then *pIsNocase is set to
+** false.
*/
SQLITE_PRIVATE int sqlite3IsLikeFunction(sqlite3 *db, Expr *pExpr, int *pIsNocase, char *aWc){
FuncDef *pDef;
@@ -87263,7 +101218,7 @@ SQLITE_PRIVATE int sqlite3IsLikeFunction(sqlite3 *db, Expr *pExpr, int *pIsNocas
pDef = sqlite3FindFunction(db, pExpr->u.zToken,
sqlite3Strlen30(pExpr->u.zToken),
2, SQLITE_UTF8, 0);
- if( NEVER(pDef==0) || (pDef->flags & SQLITE_FUNC_LIKE)==0 ){
+ if( NEVER(pDef==0) || (pDef->funcFlags & SQLITE_FUNC_LIKE)==0 ){
return 0;
}
@@ -87275,12 +101230,12 @@ SQLITE_PRIVATE int sqlite3IsLikeFunction(sqlite3 *db, Expr *pExpr, int *pIsNocas
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;
+ *pIsNocase = (pDef->funcFlags & SQLITE_FUNC_CASE)==0;
return 1;
}
/*
-** All all of the FuncDef structures in the aBuiltinFunc[] array above
+** 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()).
**
@@ -87304,15 +101259,20 @@ SQLITE_PRIVATE void sqlite3RegisterGlobalFunctions(void){
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 ),
+ AGGREGATE2(min, 1, 0, 1, minmaxStep, minMaxFinalize,
+ SQLITE_FUNC_MINMAX ),
FUNCTION(max, -1, 1, 1, minmaxFunc ),
FUNCTION(max, 0, 1, 1, 0 ),
- AGGREGATE(max, 1, 1, 1, minmaxStep, minMaxFinalize ),
+ AGGREGATE2(max, 1, 1, 1, minmaxStep, minMaxFinalize,
+ SQLITE_FUNC_MINMAX ),
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(printf, -1, 0, 0, printfFunc ),
+ FUNCTION(unicode, 1, 0, 0, unicodeFunc ),
+ FUNCTION(char, -1, 0, 0, charFunc ),
FUNCTION(abs, 1, 0, 0, absFunc ),
#ifndef SQLITE_OMIT_FLOATING_POINT
FUNCTION(round, 1, 0, 0, roundFunc ),
@@ -87322,37 +101282,43 @@ SQLITE_PRIVATE void sqlite3RegisterGlobalFunctions(void){
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),
+ FUNCTION2(coalesce, -1, 0, 0, noopFunc, 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 ),
+ FUNCTION2(ifnull, 2, 0, 0, noopFunc, SQLITE_FUNC_COALESCE),
+ FUNCTION2(unlikely, 1, 0, 0, noopFunc, SQLITE_FUNC_UNLIKELY),
+ FUNCTION2(likelihood, 2, 0, 0, noopFunc, SQLITE_FUNC_UNLIKELY),
+ FUNCTION2(likely, 1, 0, 0, noopFunc, SQLITE_FUNC_UNLIKELY),
+ VFUNCTION(random, 0, 0, 0, randomFunc ),
+ VFUNCTION(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 ),
+ DFUNCTION(sqlite_version, 0, 0, 0, versionFunc ),
+ DFUNCTION(sqlite_source_id, 0, 0, 0, sourceidFunc ),
FUNCTION(sqlite_log, 2, 0, 0, errlogFunc ),
+#if SQLITE_USER_AUTHENTICATION
+ FUNCTION(sqlite_crypt, 2, 0, 0, sqlite3CryptFunc ),
+#endif
#ifndef SQLITE_OMIT_COMPILEOPTION_DIAGS
- FUNCTION(sqlite_compileoption_used,1, 0, 0, compileoptionusedFunc ),
- FUNCTION(sqlite_compileoption_get, 1, 0, 0, compileoptiongetFunc ),
+ DFUNCTION(sqlite_compileoption_used,1, 0, 0, compileoptionusedFunc ),
+ DFUNCTION(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 ),
+ VFUNCTION(last_insert_rowid, 0, 0, 0, last_insert_rowid),
+ VFUNCTION(changes, 0, 0, 0, changes ),
+ VFUNCTION(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 ),
+ VFUNCTION(load_extension, 1, 0, 0, loadExt ),
+ VFUNCTION(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},
+ AGGREGATE2(count, 0, 0, 0, countStep, countFinalize,
+ SQLITE_FUNC_COUNT ),
AGGREGATE(count, 1, 0, 0, countStep, countFinalize ),
AGGREGATE(group_concat, 1, 0, 0, groupConcatStep, groupConcatFinalize),
AGGREGATE(group_concat, 2, 0, 0, groupConcatStep, groupConcatFinalize),
@@ -87378,6 +101344,9 @@ SQLITE_PRIVATE void sqlite3RegisterGlobalFunctions(void){
#ifndef SQLITE_OMIT_ALTERTABLE
sqlite3AlterFunctions();
#endif
+#if defined(SQLITE_ENABLE_STAT3) || defined(SQLITE_ENABLE_STAT4)
+ sqlite3AnalyzeFunctions();
+#endif
}
/************** End of func.c ************************************************/
@@ -87395,6 +101364,7 @@ SQLITE_PRIVATE void sqlite3RegisterGlobalFunctions(void){
** This file contains code used by the compiler to add foreign key
** support to compiled SQL statements.
*/
+/* #include "sqliteInt.h" */
#ifndef SQLITE_OMIT_FOREIGN_KEY
#ifndef SQLITE_OMIT_TRIGGER
@@ -87404,8 +101374,9 @@ SQLITE_PRIVATE void sqlite3RegisterGlobalFunctions(void){
** --------------------------
**
** 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
+** If an immediate foreign key constraint is violated,
+** SQLITE_CONSTRAINT_FOREIGNKEY 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.
@@ -87469,7 +101440,8 @@ SQLITE_PRIVATE void sqlite3RegisterGlobalFunctions(void){
** 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
+** constraint counter is greater than zero,
+** it returns SQLITE_CONSTRAINT_FOREIGNKEY
** 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
@@ -87525,7 +101497,7 @@ SQLITE_PRIVATE void sqlite3RegisterGlobalFunctions(void){
** 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.
+** search the schema for 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
@@ -87554,14 +101526,14 @@ SQLITE_PRIVATE void sqlite3RegisterGlobalFunctions(void){
**
** 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
+** consists of 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(
+SQLITE_PRIVATE int sqlite3FkLocateIndex(
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 */
@@ -87606,7 +101578,7 @@ static int locateFkeyIndex(
}
for(pIdx=pParent->pIndex; pIdx; pIdx=pIdx->pNext){
- if( pIdx->nColumn==nCol && pIdx->onError!=OE_None ){
+ if( pIdx->nKeyCol==nCol && IsUniqueIndex(pIdx) ){
/* 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. */
@@ -87614,8 +101586,8 @@ static int locateFkeyIndex(
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 ){
+ ** identified by the test. */
+ if( IsPrimaryKeyIndex(pIdx) ){
if( aiCol ){
int i;
for(i=0; i<nCol; i++) aiCol[i] = pFKey->aCol[i].iFrom;
@@ -87629,17 +101601,17 @@ static int locateFkeyIndex(
** 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 */
+ i16 iCol = pIdx->aiColumn[i]; /* Index of column in parent tbl */
+ const char *zDfltColl; /* Def. collation for column */
char *zIdxCol; /* Name of indexed column */
+ if( iCol<0 ) break; /* No foreign keys against expression indexes */
+
/* 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( !zDfltColl ) zDfltColl = sqlite3StrBINARY;
if( sqlite3StrICmp(pIdx->azColl[i], zDfltColl) ) break;
zIdxCol = pParent->aCol[iCol].zName;
@@ -87658,7 +101630,9 @@ static int locateFkeyIndex(
if( !pIdx ){
if( !pParse->disableTriggers ){
- sqlite3ErrorMsg(pParse, "foreign key mismatch");
+ sqlite3ErrorMsg(pParse,
+ "foreign key mismatch - \"%w\" referencing \"%w\"",
+ pFKey->pFrom->zName, pFKey->zTo);
}
sqlite3DbFree(pParse->db, aiCol);
return 1;
@@ -87719,10 +101693,11 @@ static void fkLookupParent(
** search for a matching row in the parent table. */
if( nIncr<0 ){
sqlite3VdbeAddOp2(v, OP_FkIfZero, pFKey->isDeferred, iOk);
+ VdbeCoverage(v);
}
for(i=0; i<pFKey->nCol; i++){
int iReg = aiCol[i] + regData + 1;
- sqlite3VdbeAddOp2(v, OP_IsNull, iReg, iOk);
+ sqlite3VdbeAddOp2(v, OP_IsNull, iReg, iOk); VdbeCoverage(v);
}
if( isIgnore==0 ){
@@ -87739,18 +101714,20 @@ static void fkLookupParent(
** 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);
+ VdbeCoverage(v);
/* 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);
+ sqlite3VdbeAddOp3(v, OP_Eq, regData, iOk, regTemp); VdbeCoverage(v);
+ sqlite3VdbeChangeP5(v, SQLITE_NOTNULL);
}
sqlite3OpenTable(pParse, iCur, iDb, pTab, OP_OpenRead);
- sqlite3VdbeAddOp3(v, OP_NotExists, iCur, 0, regTemp);
- sqlite3VdbeAddOp2(v, OP_Goto, 0, iOk);
+ sqlite3VdbeAddOp3(v, OP_NotExists, iCur, 0, regTemp); VdbeCoverage(v);
+ sqlite3VdbeGoto(v, iOk);
sqlite3VdbeJumpHere(v, sqlite3VdbeCurrentAddr(v)-2);
sqlite3VdbeJumpHere(v, iMustBeInt);
sqlite3ReleaseTempReg(pParse, regTemp);
@@ -87758,10 +101735,9 @@ static void fkLookupParent(
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);
+ sqlite3VdbeSetP4KeyInfo(pParse, pIdx);
for(i=0; i<nCol; i++){
sqlite3VdbeAddOp2(v, OP_Copy, aiCol[i]+1+regData, regTemp+i);
}
@@ -87781,38 +101757,41 @@ static void fkLookupParent(
for(i=0; i<nCol; i++){
int iChild = aiCol[i]+1+regData;
int iParent = pIdx->aiColumn[i]+1+regData;
+ assert( pIdx->aiColumn[i]>=0 );
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);
+ sqlite3VdbeAddOp3(v, OP_Ne, iChild, iJump, iParent); VdbeCoverage(v);
sqlite3VdbeChangeP5(v, SQLITE_JUMPIFNULL);
}
- sqlite3VdbeAddOp2(v, OP_Goto, 0, iOk);
+ sqlite3VdbeGoto(v, iOk);
}
- sqlite3VdbeAddOp3(v, OP_MakeRecord, regTemp, nCol, regRec);
- sqlite3VdbeChangeP4(v, -1, sqlite3IndexAffinityStr(v,pIdx), P4_TRANSIENT);
- sqlite3VdbeAddOp4Int(v, OP_Found, iCur, iOk, regRec, 0);
+ sqlite3VdbeAddOp4(v, OP_MakeRecord, regTemp, nCol, regRec,
+ sqlite3IndexAffinityStr(pParse->db,pIdx), nCol);
+ sqlite3VdbeAddOp4Int(v, OP_Found, iCur, iOk, regRec, 0); VdbeCoverage(v);
sqlite3ReleaseTempReg(pParse, regRec);
sqlite3ReleaseTempRange(pParse, regTemp, nCol);
}
}
- if( !pFKey->isDeferred && !pParse->pToplevel && !pParse->isMultiWrite ){
+ if( !pFKey->isDeferred && !(pParse->db->flags & SQLITE_DeferFKs)
+ && !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
- );
+ sqlite3HaltConstraint(pParse, SQLITE_CONSTRAINT_FOREIGNKEY,
+ OE_Abort, 0, P4_STATIC, P5_ConstraintFK);
}else{
if( nIncr>0 && pFKey->isDeferred==0 ){
- sqlite3ParseToplevel(pParse)->mayAbort = 1;
+ sqlite3MayAbort(pParse);
}
sqlite3VdbeAddOp2(v, OP_FkCounter, pFKey->isDeferred, nIncr);
}
@@ -87821,6 +101800,62 @@ static void fkLookupParent(
sqlite3VdbeAddOp1(v, OP_Close, iCur);
}
+
+/*
+** Return an Expr object that refers to a memory register corresponding
+** to column iCol of table pTab.
+**
+** regBase is the first of an array of register that contains the data
+** for pTab. regBase itself holds the rowid. regBase+1 holds the first
+** column. regBase+2 holds the second column, and so forth.
+*/
+static Expr *exprTableRegister(
+ Parse *pParse, /* Parsing and code generating context */
+ Table *pTab, /* The table whose content is at r[regBase]... */
+ int regBase, /* Contents of table pTab */
+ i16 iCol /* Which column of pTab is desired */
+){
+ Expr *pExpr;
+ Column *pCol;
+ const char *zColl;
+ sqlite3 *db = pParse->db;
+
+ pExpr = sqlite3Expr(db, TK_REGISTER, 0);
+ if( pExpr ){
+ if( iCol>=0 && iCol!=pTab->iPKey ){
+ pCol = &pTab->aCol[iCol];
+ pExpr->iTable = regBase + iCol + 1;
+ pExpr->affinity = pCol->affinity;
+ zColl = pCol->zColl;
+ if( zColl==0 ) zColl = db->pDfltColl->zName;
+ pExpr = sqlite3ExprAddCollateString(pParse, pExpr, zColl);
+ }else{
+ pExpr->iTable = regBase;
+ pExpr->affinity = SQLITE_AFF_INTEGER;
+ }
+ }
+ return pExpr;
+}
+
+/*
+** Return an Expr object that refers to column iCol of table pTab which
+** has cursor iCur.
+*/
+static Expr *exprTableColumn(
+ sqlite3 *db, /* The database connection */
+ Table *pTab, /* The table whose column is desired */
+ int iCursor, /* The open cursor on the table */
+ i16 iCol /* The column that is wanted */
+){
+ Expr *pExpr = sqlite3Expr(db, TK_COLUMN, 0);
+ if( pExpr ){
+ pExpr->pTab = pTab;
+ pExpr->iTable = iCursor;
+ pExpr->iColumn = iCol;
+ }
+ return pExpr;
+}
+
/*
** 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
@@ -87828,6 +101863,10 @@ static void fkLookupParent(
** 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.
**
+** Parameter nIncr is passed -1 when inserting a row (as this may decrease
+** the number of FK violations in the db) or +1 when deleting one (as this
+** may increase the number of FK constraint problems).
+**
** 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:
@@ -87836,13 +101875,13 @@ static void fkLookupParent(
** --------------------------------------------------------------------------
** DELETE immediate Increment the "immediate constraint counter".
** Or, if the ON (UPDATE|DELETE) action is RESTRICT,
-** throw a "foreign key constraint failed" exception.
+** 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.
+** throw a "FOREIGN KEY constraint failed" exception.
**
** INSERT deferred Decrement the "deferred constraint counter".
**
@@ -87851,12 +101890,12 @@ static void fkLookupParent(
*/
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 */
+ SrcList *pSrc, /* The child table to be scanned */
+ Table *pTab, /* The parent table */
+ Index *pIdx, /* Index on parent covering the foreign key */
+ FKey *pFKey, /* The foreign key linking pSrc to pTab */
int *aiCol, /* Map from pIdx cols to child table cols */
- int regData, /* Referenced table data starts here */
+ int regData, /* Parent row data starts here */
int nIncr /* Amount to increment deferred counter by */
){
sqlite3 *db = pParse->db; /* Database handle */
@@ -87867,10 +101906,14 @@ static void fkScanChildren(
int iFkIfZero = 0; /* Address of OP_FkIfZero */
Vdbe *v = sqlite3GetVdbe(pParse);
- assert( !pIdx || pIdx->pTable==pTab );
+ assert( pIdx==0 || pIdx->pTable==pTab );
+ assert( pIdx==0 || pIdx->nKeyCol==pFKey->nCol );
+ assert( pIdx!=0 || pFKey->nCol==1 );
+ assert( pIdx!=0 || HasRowid(pTab) );
if( nIncr<0 ){
iFkIfZero = sqlite3VdbeAddOp2(v, OP_FkIfZero, pFKey->isDeferred, 0);
+ VdbeCoverage(v);
}
/* Create an Expr object representing an SQL expression like:
@@ -87885,29 +101928,11 @@ static void fkScanChildren(
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 */
+ i16 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 = pIdx ? pIdx->aiColumn[i] : -1;
+ pLeft = exprTableRegister(pParse, pTab, regData, iCol);
iCol = aiCol ? aiCol[i] : pFKey->aCol[0].iFrom;
assert( iCol>=0 );
zCol = pFKey->pFrom->aCol[iCol].zName;
@@ -87916,24 +101941,40 @@ static void fkScanChildren(
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 the child table is the same as the parent table, then add terms
+ ** to the WHERE clause that prevent this entry from being scanned.
+ ** The added WHERE clause terms are like this:
+ **
+ ** $current_rowid!=rowid
+ ** NOT( $current_a==a AND $current_b==b AND ... )
+ **
+ ** The first form is used for rowid tables. The second form is used
+ ** for WITHOUT ROWID tables. In the second form, the primary key is
+ ** (a,b,...)
+ */
if( pTab==pFKey->pFrom && nIncr>0 ){
- Expr *pEq; /* Expression (pLeft = pRight) */
+ Expr *pNe; /* 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);
+ if( HasRowid(pTab) ){
+ pLeft = exprTableRegister(pParse, pTab, regData, -1);
+ pRight = exprTableColumn(db, pTab, pSrc->a[0].iCursor, -1);
+ pNe = sqlite3PExpr(pParse, TK_NE, pLeft, pRight, 0);
+ }else{
+ Expr *pEq, *pAll = 0;
+ Index *pPk = sqlite3PrimaryKeyIndex(pTab);
+ assert( pIdx!=0 );
+ for(i=0; i<pPk->nKeyCol; i++){
+ i16 iCol = pIdx->aiColumn[i];
+ assert( iCol>=0 );
+ pLeft = exprTableRegister(pParse, pTab, regData, iCol);
+ pRight = exprTableColumn(db, pTab, pSrc->a[0].iCursor, iCol);
+ pEq = sqlite3PExpr(pParse, TK_EQ, pLeft, pRight, 0);
+ pAll = sqlite3ExprAnd(db, pAll, pEq);
+ }
+ pNe = sqlite3PExpr(pParse, TK_NOT, pAll, 0, 0);
+ }
+ pWhere = sqlite3ExprAnd(db, pWhere, pNe);
}
/* Resolve the references in the WHERE clause. */
@@ -87943,13 +101984,9 @@ static void fkScanChildren(
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. */
+ ** clause. For each row found, increment either the deferred or immediate
+ ** foreign key constraint counter. */
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);
@@ -87963,8 +102000,8 @@ static void fkScanChildren(
}
/*
-** 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,
+** This function returns a linked list of FKey objects (connected by
+** FKey.pNextTo) holding all children of table pTab. For example,
** given the following schema:
**
** CREATE TABLE t1(a PRIMARY KEY);
@@ -87977,8 +102014,7 @@ static void fkScanChildren(
** table).
*/
SQLITE_PRIVATE FKey *sqlite3FkReferences(Table *pTab){
- int nName = sqlite3Strlen30(pTab->zName);
- return (FKey *)sqlite3HashFind(&pTab->pSchema->fkeyHash, pTab->zName, nName);
+ return (FKey *)sqlite3HashFind(&pTab->pSchema->fkeyHash, pTab->zName);
}
/*
@@ -88032,11 +102068,11 @@ SQLITE_PRIVATE void sqlite3FkDropTable(Parse *pParse, SrcList *pName, Table *pTa
** when this statement is run. */
FKey *p;
for(p=pTab->pFKey; p; p=p->pNextFrom){
- if( p->isDeferred ) break;
+ if( p->isDeferred || (db->flags & SQLITE_DeferFKs) ) break;
}
if( !p ) return;
iSkip = sqlite3VdbeMakeLabel(v);
- sqlite3VdbeAddOp2(v, OP_FkIfZero, 1, iSkip);
+ sqlite3VdbeAddOp2(v, OP_FkIfZero, 1, iSkip); VdbeCoverage(v);
}
pParse->disableTriggers = 1;
@@ -88046,11 +102082,18 @@ SQLITE_PRIVATE void sqlite3FkDropTable(Parse *pParse, SrcList *pName, Table *pTa
/* 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
- );
+ ** transactions are not able to rollback schema changes.
+ **
+ ** If the SQLITE_DeferFKs flag is set, then this is not required, as
+ ** the statement transaction will not be rolled back even if FK
+ ** constraints are violated.
+ */
+ if( (db->flags & SQLITE_DeferFKs)==0 ){
+ sqlite3VdbeAddOp2(v, OP_FkIfZero, 0, sqlite3VdbeCurrentAddr(v)+2);
+ VdbeCoverage(v);
+ sqlite3HaltConstraint(pParse, SQLITE_CONSTRAINT_FOREIGNKEY,
+ OE_Abort, 0, P4_STATIC, P5_ConstraintFK);
+ }
if( iSkip ){
sqlite3VdbeResolveLabel(v, iSkip);
@@ -88058,6 +102101,88 @@ SQLITE_PRIVATE void sqlite3FkDropTable(Parse *pParse, SrcList *pName, Table *pTa
}
}
+
+/*
+** The second argument points to an FKey object representing a foreign key
+** for which pTab is the child table. An UPDATE statement against pTab
+** is currently being processed. For each column of the table that is
+** actually updated, the corresponding element in the aChange[] array
+** is zero or greater (if a column is unmodified the corresponding element
+** is set to -1). If the rowid column is modified by the UPDATE statement
+** the bChngRowid argument is non-zero.
+**
+** This function returns true if any of the columns that are part of the
+** child key for FK constraint *p are modified.
+*/
+static int fkChildIsModified(
+ Table *pTab, /* Table being updated */
+ FKey *p, /* Foreign key for which pTab is the child */
+ int *aChange, /* Array indicating modified columns */
+ int bChngRowid /* True if rowid is modified by this update */
+){
+ int i;
+ for(i=0; i<p->nCol; i++){
+ int iChildKey = p->aCol[i].iFrom;
+ if( aChange[iChildKey]>=0 ) return 1;
+ if( iChildKey==pTab->iPKey && bChngRowid ) return 1;
+ }
+ return 0;
+}
+
+/*
+** The second argument points to an FKey object representing a foreign key
+** for which pTab is the parent table. An UPDATE statement against pTab
+** is currently being processed. For each column of the table that is
+** actually updated, the corresponding element in the aChange[] array
+** is zero or greater (if a column is unmodified the corresponding element
+** is set to -1). If the rowid column is modified by the UPDATE statement
+** the bChngRowid argument is non-zero.
+**
+** This function returns true if any of the columns that are part of the
+** parent key for FK constraint *p are modified.
+*/
+static int fkParentIsModified(
+ Table *pTab,
+ FKey *p,
+ int *aChange,
+ int bChngRowid
+){
+ int i;
+ for(i=0; i<p->nCol; i++){
+ char *zKey = p->aCol[i].zCol;
+ int iKey;
+ for(iKey=0; iKey<pTab->nCol; iKey++){
+ if( aChange[iKey]>=0 || (iKey==pTab->iPKey && bChngRowid) ){
+ Column *pCol = &pTab->aCol[iKey];
+ if( zKey ){
+ if( 0==sqlite3StrICmp(pCol->zName, zKey) ) return 1;
+ }else if( pCol->colFlags & COLFLAG_PRIMKEY ){
+ return 1;
+ }
+ }
+ }
+ }
+ return 0;
+}
+
+/*
+** Return true if the parser passed as the first argument is being
+** used to code a trigger that is really a "SET NULL" action belonging
+** to trigger pFKey.
+*/
+static int isSetNullAction(Parse *pParse, FKey *pFKey){
+ Parse *pTop = sqlite3ParseToplevel(pParse);
+ if( pTop->pTriggerPrg ){
+ Trigger *p = pTop->pTriggerPrg->pTrigger;
+ if( (p==pFKey->apTrigger[0] && pFKey->aAction[0]==OE_SetNull)
+ || (p==pFKey->apTrigger[1] && pFKey->aAction[1]==OE_SetNull)
+ ){
+ return 1;
+ }
+ }
+ return 0;
+}
+
/*
** This function is called when inserting, deleting or updating a row of
** table pTab to generate VDBE code to perform foreign key constraint
@@ -88082,7 +102207,9 @@ 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 */
+ int regNew, /* New row data is stored here */
+ int *aChange, /* Array indicating UPDATEd columns (or 0) */
+ int bChngRowid /* True if rowid is UPDATEd */
){
sqlite3 *db = pParse->db; /* Database handle */
FKey *pFKey; /* Used to iterate through FKs */
@@ -88108,7 +102235,14 @@ SQLITE_PRIVATE void sqlite3FkCheck(
int *aiCol;
int iCol;
int i;
- int isIgnore = 0;
+ int bIgnore = 0;
+
+ if( aChange
+ && sqlite3_stricmp(pTab->zName, pFKey->zTo)!=0
+ && fkChildIsModified(pTab, pFKey, aChange, bChngRowid)==0
+ ){
+ continue;
+ }
/* 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
@@ -88119,7 +102253,7 @@ SQLITE_PRIVATE void sqlite3FkCheck(
}else{
pTo = sqlite3LocateTable(pParse, 0, pFKey->zTo, zDb);
}
- if( !pTo || locateFkeyIndex(pParse, pTo, pFKey, &pIdx, &aiFree) ){
+ if( !pTo || sqlite3FkLocateIndex(pParse, pTo, pFKey, &pIdx, &aiFree) ){
assert( isIgnoreErrors==0 || (regOld!=0 && regNew==0) );
if( !isIgnoreErrors || db->mallocFailed ) return;
if( pTo==0 ){
@@ -88134,7 +102268,7 @@ SQLITE_PRIVATE void sqlite3FkCheck(
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_IsNull, iReg, iJump); VdbeCoverage(v);
}
sqlite3VdbeAddOp2(v, OP_FkCounter, pFKey->isDeferred, -1);
}
@@ -88152,6 +102286,7 @@ SQLITE_PRIVATE void sqlite3FkCheck(
if( aiCol[i]==pTab->iPKey ){
aiCol[i] = -1;
}
+ assert( pIdx==0 || pIdx->aiColumn[i]>=0 );
#ifndef SQLITE_OMIT_AUTHORIZATION
/* Request permission to read the parent key columns. If the
** authorization callback returns SQLITE_IGNORE, behave as if any
@@ -88160,7 +102295,7 @@ SQLITE_PRIVATE void sqlite3FkCheck(
int rcauth;
char *zCol = pTo->aCol[pIdx ? pIdx->aiColumn[i] : pTo->iPKey].zName;
rcauth = sqlite3AuthReadCol(pParse, pTo->zName, zCol, iDb);
- isIgnore = (rcauth==SQLITE_IGNORE);
+ bIgnore = (rcauth==SQLITE_IGNORE);
}
#endif
}
@@ -88175,39 +102310,51 @@ SQLITE_PRIVATE void sqlite3FkCheck(
/* 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);
+ fkLookupParent(pParse, iDb, pTo, pIdx, pFKey, aiCol, regOld, -1, bIgnore);
}
- if( regNew!=0 ){
+ if( regNew!=0 && !isSetNullAction(pParse, pFKey) ){
/* 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);
+ ** be found, adding the child row has violated the FK constraint.
+ **
+ ** If this operation is being performed as part of a trigger program
+ ** that is actually a "SET NULL" action belonging to this very
+ ** foreign key, then omit this scan altogether. As all child key
+ ** values are guaranteed to be NULL, it is not possible for adding
+ ** this row to cause an FK violation. */
+ fkLookupParent(pParse, iDb, pTo, pIdx, pFKey, aiCol, regNew, +1, bIgnore);
}
sqlite3DbFree(db, aiFree);
}
- /* Loop through all the foreign key constraints that refer to this table */
+ /* Loop through all the foreign key constraints that refer to this table.
+ ** (the "child" constraints) */
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 ){
+ if( aChange && fkParentIsModified(pTab, pFKey, aChange, bChngRowid)==0 ){
+ continue;
+ }
+
+ if( !pFKey->isDeferred && !(db->flags & SQLITE_DeferFKs)
+ && !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. */
+ /* Inserting a single row into a parent table cannot cause (or fix)
+ ** an immediate foreign key violation. So do nothing in this case. */
continue;
}
- if( locateFkeyIndex(pParse, pTab, pFKey, &pIdx, &aiCol) ){
+ if( sqlite3FkLocateIndex(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. */
+ /* Create a SrcList structure containing the child table. We need the
+ ** child table as a SrcList for sqlite3WhereBegin() */
pSrc = sqlite3SrcListAppend(db, 0, 0, 0);
if( pSrc ){
struct SrcList_item *pItem = pSrc->a;
@@ -88220,13 +102367,28 @@ SQLITE_PRIVATE void sqlite3FkCheck(
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. */
+ int eAction = pFKey->aAction[aChange!=0];
fkScanChildren(pParse, pSrc, pTab, pIdx, pFKey, aiCol, regOld, 1);
+ /* If this is a deferred FK constraint, or a CASCADE or SET NULL
+ ** action applies, then any foreign key violations caused by
+ ** removing the parent key will be rectified by the action trigger.
+ ** So do not set the "may-abort" flag in this case.
+ **
+ ** Note 1: If the FK is declared "ON UPDATE CASCADE", then the
+ ** may-abort flag will eventually be set on this statement anyway
+ ** (when this function is called as part of processing the UPDATE
+ ** within the action trigger).
+ **
+ ** Note 2: At first glance it may seem like SQLite could simply omit
+ ** all OP_FkCounter related scans when either CASCADE or SET NULL
+ ** applies. The trouble starts if the CASCADE or SET NULL action
+ ** trigger causes other triggers or action rules attached to the
+ ** child table to fire. In these cases the fk constraint counters
+ ** might be set incorrectly if any OP_FkCounter related scans are
+ ** omitted. */
+ if( !pFKey->isDeferred && eAction!=OE_Cascade && eAction!=OE_SetNull ){
+ sqlite3MayAbort(pParse);
+ }
}
pItem->zName = 0;
sqlite3SrcListDelete(db, pSrc);
@@ -88254,15 +102416,19 @@ SQLITE_PRIVATE u32 sqlite3FkOldmask(
}
for(p=sqlite3FkReferences(pTab); p; p=p->pNextTo){
Index *pIdx = 0;
- locateFkeyIndex(pParse, pTab, p, &pIdx, 0);
+ sqlite3FkLocateIndex(pParse, pTab, p, &pIdx, 0);
if( pIdx ){
- for(i=0; i<pIdx->nColumn; i++) mask |= COLUMN_MASK(pIdx->aiColumn[i]);
+ for(i=0; i<pIdx->nKeyCol; i++){
+ assert( pIdx->aiColumn[i]>=0 );
+ 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
@@ -88292,32 +102458,16 @@ SQLITE_PRIVATE int sqlite3FkRequired(
}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;
- }
+ if( fkChildIsModified(pTab, p, aChange, 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;
- }
- }
- }
+ if( fkParentIsModified(pTab, p, aChange, chngRowid) ) return 1;
}
}
}
@@ -88380,7 +102530,7 @@ static Trigger *fkActionTrigger(
int i; /* Iterator variable */
Expr *pWhen = 0; /* WHEN clause for the trigger */
- if( locateFkeyIndex(pParse, pTab, pFKey, &pIdx, &aiCol) ) return 0;
+ if( sqlite3FkLocateIndex(pParse, pTab, pFKey, &pIdx, &aiCol) ) return 0;
assert( aiCol || pFKey->nCol==1 );
for(i=0; i<pFKey->nCol; i++){
@@ -88393,7 +102543,9 @@ static Trigger *fkActionTrigger(
iFromCol = aiCol ? aiCol[i] : pFKey->aCol[0].iFrom;
assert( iFromCol>=0 );
- tToCol.z = pIdx ? pTab->aCol[pIdx->aiColumn[i]].zName : "oid";
+ assert( pIdx!=0 || (pTab->iPKey>=0 && pTab->iPKey<pTab->nCol) );
+ assert( pIdx==0 || pIdx->aiColumn[i]>=0 );
+ tToCol.z = pTab->aCol[pIdx ? pIdx->aiColumn[i] : pTab->iPKey].zName;
tFromCol.z = pFKey->pFrom->aCol[iFromCol].zName;
tToCol.n = sqlite3Strlen30(tToCol.z);
@@ -88405,10 +102557,10 @@ static Trigger *fkActionTrigger(
** 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)
+ sqlite3ExprAlloc(db, TK_ID, &tOld, 0),
+ sqlite3ExprAlloc(db, TK_ID, &tToCol, 0)
, 0),
- sqlite3PExpr(pParse, TK_ID, 0, 0, &tFromCol)
+ sqlite3ExprAlloc(db, TK_ID, &tFromCol, 0)
, 0);
pWhere = sqlite3ExprAnd(db, pWhere, pEq);
@@ -88420,12 +102572,12 @@ static Trigger *fkActionTrigger(
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),
+ sqlite3ExprAlloc(db, TK_ID, &tOld, 0),
+ sqlite3ExprAlloc(db, TK_ID, &tToCol, 0),
0),
sqlite3PExpr(pParse, TK_DOT,
- sqlite3PExpr(pParse, TK_ID, 0, 0, &tNew),
- sqlite3PExpr(pParse, TK_ID, 0, 0, &tToCol),
+ sqlite3ExprAlloc(db, TK_ID, &tNew, 0),
+ sqlite3ExprAlloc(db, TK_ID, &tToCol, 0),
0),
0);
pWhen = sqlite3ExprAnd(db, pWhen, pEq);
@@ -88435,8 +102587,8 @@ static Trigger *fkActionTrigger(
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)
+ sqlite3ExprAlloc(db, TK_ID, &tNew, 0),
+ sqlite3ExprAlloc(db, TK_ID, &tToCol, 0)
, 0);
}else if( action==OE_SetDflt ){
Expr *pDflt = pFKey->pFrom->aCol[iFromCol].pDflt;
@@ -88463,7 +102615,7 @@ static Trigger *fkActionTrigger(
tFrom.z = zFrom;
tFrom.n = nFrom;
- pRaise = sqlite3Expr(db, TK_RAISE, "foreign key constraint failed");
+ pRaise = sqlite3Expr(db, TK_RAISE, "FOREIGN KEY constraint failed");
if( pRaise ){
pRaise->affinity = OE_Abort;
}
@@ -88483,13 +102635,12 @@ static Trigger *fkActionTrigger(
pTrigger = (Trigger *)sqlite3DbMallocZero(db,
sizeof(Trigger) + /* struct Trigger */
sizeof(TriggerStep) + /* Single step in trigger program */
- nFrom + 1 /* Space for pStep->target.z */
+ nFrom + 1 /* Space for pStep->zTarget */
);
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->zTarget = (char *)&pStep[1];
+ memcpy((char *)pStep->zTarget, zFrom, nFrom);
pStep->pWhere = sqlite3ExprDup(db, pWhere, EXPRDUP_REDUCE);
pStep->pExprList = sqlite3ExprListDup(db, pList, EXPRDUP_REDUCE);
@@ -88543,7 +102694,9 @@ 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 */
+ int regOld, /* Address of array containing old row */
+ int *aChange, /* Array indicating UPDATEd columns (or 0) */
+ int bChngRowid /* True if rowid is UPDATEd */
){
/* If foreign-key support is enabled, iterate through all FKs that
** refer to table pTab. If there is an action associated with the FK
@@ -88552,9 +102705,11 @@ SQLITE_PRIVATE void sqlite3FkActions(
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);
+ if( aChange==0 || fkParentIsModified(pTab, pFKey, aChange, bChngRowid) ){
+ Trigger *pAct = fkActionTrigger(pParse, pTab, pFKey, pChanges);
+ if( pAct ){
+ sqlite3CodeRowTriggerDirect(pParse, pAct, pTab, regOld, OE_Abort, 0);
+ }
}
}
}
@@ -88581,7 +102736,7 @@ SQLITE_PRIVATE void sqlite3FkDelete(sqlite3 *db, Table *pTab){
}else{
void *p = (void *)pFKey->pNextTo;
const char *z = (p ? pFKey->pNextTo->zTo : pFKey->zTo);
- sqlite3HashInsert(&pTab->pSchema->fkeyHash, z, sqlite3Strlen30(z), p);
+ sqlite3HashInsert(&pTab->pSchema->fkeyHash, z, p);
}
if( pFKey->pNextTo ){
pFKey->pNextTo->pPrevTo = pFKey->pPrevTo;
@@ -88621,12 +102776,19 @@ SQLITE_PRIVATE void sqlite3FkDelete(sqlite3 *db, Table *pTab){
** This file contains C code routines that are called by the parser
** to handle INSERT statements in SQLite.
*/
+/* #include "sqliteInt.h" */
/*
-** Generate code that will open a table for reading.
+** Generate code that will
+**
+** (1) acquire a lock for table pTab then
+** (2) open pTab as cursor iCur.
+**
+** If pTab is a WITHOUT ROWID table, then it is the PRIMARY KEY index
+** for that table that is actually opened.
*/
SQLITE_PRIVATE void sqlite3OpenTable(
- Parse *p, /* Generate code into this VDBE */
+ Parse *pParse, /* 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 */
@@ -88634,12 +102796,21 @@ SQLITE_PRIVATE void sqlite3OpenTable(
){
Vdbe *v;
assert( !IsVirtual(pTab) );
- v = sqlite3GetVdbe(p);
+ v = sqlite3GetVdbe(pParse);
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));
+ sqlite3TableLock(pParse, iDb, pTab->tnum,
+ (opcode==OP_OpenWrite)?1:0, pTab->zName);
+ if( HasRowid(pTab) ){
+ sqlite3VdbeAddOp4Int(v, opcode, iCur, pTab->tnum, iDb, pTab->nCol);
+ VdbeComment((v, "%s", pTab->zName));
+ }else{
+ Index *pPk = sqlite3PrimaryKeyIndex(pTab);
+ assert( pPk!=0 );
+ assert( pPk->tnum==pTab->tnum );
+ sqlite3VdbeAddOp3(v, opcode, iCur, pPk->tnum, iDb);
+ sqlite3VdbeSetP4KeyInfo(pParse, pPk);
+ VdbeComment((v, "%s", pTab->zName));
+ }
}
/*
@@ -88649,20 +102820,20 @@ SQLITE_PRIVATE void sqlite3OpenTable(
**
** Character Column affinity
** ------------------------------
-** 'a' TEXT
-** 'b' NONE
-** 'c' NUMERIC
-** 'd' INTEGER
-** 'e' REAL
+** 'A' BLOB
+** 'B' TEXT
+** 'C' NUMERIC
+** 'D' INTEGER
+** 'F' REAL
**
-** An extra 'd' is appended to the end of the string to cover the
+** 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){
+SQLITE_PRIVATE const char *sqlite3IndexAffinityStr(sqlite3 *db, 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
@@ -88674,16 +102845,26 @@ SQLITE_PRIVATE const char *sqlite3IndexAffinityStr(Vdbe *v, Index *pIdx){
*/
int n;
Table *pTab = pIdx->pTable;
- sqlite3 *db = sqlite3VdbeDb(v);
- pIdx->zColAff = (char *)sqlite3DbMallocRaw(0, pIdx->nColumn+2);
+ pIdx->zColAff = (char *)sqlite3DbMallocRaw(0, pIdx->nColumn+1);
if( !pIdx->zColAff ){
db->mallocFailed = 1;
return 0;
}
for(n=0; n<pIdx->nColumn; n++){
- pIdx->zColAff[n] = pTab->aCol[pIdx->aiColumn[n]].affinity;
+ i16 x = pIdx->aiColumn[n];
+ if( x>=0 ){
+ pIdx->zColAff[n] = pTab->aCol[x].affinity;
+ }else if( x==XN_ROWID ){
+ pIdx->zColAff[n] = SQLITE_AFF_INTEGER;
+ }else{
+ char aff;
+ assert( x==XN_EXPR );
+ assert( pIdx->aColExpr!=0 );
+ aff = sqlite3ExprAffinity(pIdx->aColExpr->a[n].pExpr);
+ if( aff==0 ) aff = SQLITE_AFF_BLOB;
+ pIdx->zColAff[n] = aff;
+ }
}
- pIdx->zColAff[n++] = SQLITE_AFF_INTEGER;
pIdx->zColAff[n] = 0;
}
@@ -88691,32 +102872,30 @@ SQLITE_PRIVATE const char *sqlite3IndexAffinityStr(Vdbe *v, Index *pIdx){
}
/*
-** 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:
+** Compute the affinity string for table pTab, if it has not already been
+** computed. As an optimization, omit trailing SQLITE_AFF_BLOB affinities.
+**
+** If the affinity exists (if it is no entirely SQLITE_AFF_BLOB values) and
+** if iReg>0 then code an OP_Affinity opcode that will set the affinities
+** for register iReg and following. Or if affinities exists and iReg==0,
+** then just set the P4 operand of the previous opcode (which should be
+** an OP_MakeRecord) to the affinity string.
+**
+** A column affinity string has one character per 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;
+** 'A' BLOB
+** 'B' TEXT
+** 'C' NUMERIC
+** 'D' INTEGER
+** 'E' REAL
+*/
+SQLITE_PRIVATE void sqlite3TableAffinity(Vdbe *v, Table *pTab, int iReg){
+ int i;
+ char *zColAff = pTab->zColAff;
+ if( zColAff==0 ){
sqlite3 *db = sqlite3VdbeDb(v);
-
zColAff = (char *)sqlite3DbMallocRaw(0, pTab->nCol+1);
if( !zColAff ){
db->mallocFailed = 1;
@@ -88726,22 +102905,28 @@ SQLITE_PRIVATE void sqlite3TableAffinityStr(Vdbe *v, Table *pTab){
for(i=0; i<pTab->nCol; i++){
zColAff[i] = pTab->aCol[i].affinity;
}
- zColAff[pTab->nCol] = '\0';
-
+ do{
+ zColAff[i--] = 0;
+ }while( i>=0 && zColAff[i]==SQLITE_AFF_BLOB );
pTab->zColAff = zColAff;
}
-
- sqlite3VdbeChangeP4(v, -1, pTab->zColAff, P4_TRANSIENT);
+ i = sqlite3Strlen30(zColAff);
+ if( i ){
+ if( iReg ){
+ sqlite3VdbeAddOp4(v, OP_Affinity, iReg, i, 0, zColAff, i);
+ }else{
+ sqlite3VdbeChangeP4(v, -1, zColAff, i);
+ }
+ }
}
/*
** 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
+** have been opened at any point in the VDBE 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.
+** run without using a temporary table for the results of the SELECT.
*/
-static int readsTable(Parse *p, int iStartAddr, int iDb, Table *pTab){
+static int readsTable(Parse *p, int iDb, Table *pTab){
Vdbe *v = sqlite3GetVdbe(p);
int i;
int iEnd = sqlite3VdbeCurrentAddr(v);
@@ -88749,7 +102934,7 @@ static int readsTable(Parse *p, int iStartAddr, int iDb, Table *pTab){
VTable *pVTab = IsVirtual(pTab) ? sqlite3GetVTable(p->db, pTab) : 0;
#endif
- for(i=iStartAddr; i<iEnd; i++){
+ for(i=1; i<iEnd; i++){
VdbeOp *pOp = sqlite3VdbeGetOp(v, i);
assert( pOp!=0 );
if( pOp->opcode==OP_OpenRead && pOp->p3==iDb ){
@@ -88839,7 +103024,7 @@ SQLITE_PRIVATE void sqlite3AutoincrementBegin(Parse *pParse){
/* 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( sqlite3IsToplevel(pParse) );
assert( v ); /* We failed long ago if this is not so */
for(p = pParse->pAinc; p; p = p->pNext){
@@ -88849,15 +103034,15 @@ SQLITE_PRIVATE void sqlite3AutoincrementBegin(Parse *pParse){
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);
+ sqlite3VdbeLoadString(v, memId-1, p->pTab->zName);
+ sqlite3VdbeAddOp2(v, OP_Rewind, 0, addr+9); VdbeCoverage(v);
sqlite3VdbeAddOp3(v, OP_Column, 0, 0, memId);
- sqlite3VdbeAddOp3(v, OP_Ne, memId-1, addr+7, memId);
+ sqlite3VdbeAddOp3(v, OP_Ne, memId-1, addr+7, memId); VdbeCoverage(v);
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);
+ sqlite3VdbeGoto(v, addr+9);
+ sqlite3VdbeAddOp2(v, OP_Next, 0, addr+2); VdbeCoverage(v);
sqlite3VdbeAddOp2(v, OP_Integer, 0, memId);
sqlite3VdbeAddOp0(v, OP_Close);
}
@@ -88892,25 +103077,16 @@ SQLITE_PRIVATE void sqlite3AutoincrementEnd(Parse *pParse){
assert( v );
for(p = pParse->pAinc; p; p = p->pNext){
Db *pDb = &db->aDb[p->iDb];
- int j1, j2, j3, j4, j5;
+ int addr1;
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);
+ addr1 = sqlite3VdbeAddOp1(v, OP_NotNull, memId+1); VdbeCoverage(v);
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);
+ sqlite3VdbeJumpHere(v, addr1);
sqlite3VdbeAddOp3(v, OP_MakeRecord, memId-1, 2, iRec);
sqlite3VdbeAddOp3(v, OP_Insert, 0, iRec, memId+1);
sqlite3VdbeChangeP5(v, OPFLAG_APPEND);
@@ -88928,97 +103104,6 @@ SQLITE_PRIVATE void sqlite3AutoincrementEnd(Parse *pParse){
#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 */
@@ -89029,27 +103114,30 @@ static int xferOptimization(
);
/*
-** This routine is call to handle SQL of the following forms:
+** This routine is called to handle SQL of the following forms:
**
-** insert into TABLE (IDLIST) values(EXPRLIST)
+** insert into TABLE (IDLIST) values(EXPRLIST),(EXPRLIST),...
** insert into TABLE (IDLIST) select
+** insert into TABLE (IDLIST) default values
**
** 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.
+** then a list of all (non-hidden) 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.
+** For the pSelect parameter holds the values to be inserted for the
+** first two forms shown above. A VALUES clause is really just short-hand
+** for a SELECT statement that omits the FROM clause and everything else
+** that follows. If the pSelect parameter is NULL, that means that the
+** DEFAULT VALUES form of the INSERT statement is intended.
**
** The code generated follows one of four templates. For a simple
-** select with data coming from a VALUES clause, the code executes
+** insert with data coming from a single-row 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
+** put VALUES clause expressions into registers
** write the resulting record into <table>
** cleanup
**
@@ -89081,7 +103169,6 @@ static int xferOptimization(
** 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
@@ -89090,12 +103177,9 @@ static int xferOptimization(
** yield X
** end loop
** cleanup after the SELECT
-** EOF <- 1
-** yield X
-** goto A
+** end-coroutine X
** B: open write cursor to <table> and its indices
-** C: yield X
-** if EOF goto D
+** C: yield X, at EOF goto D
** insert the select result into <table> from R..R+n
** goto C
** D: cleanup
@@ -89103,10 +103187,9 @@ static int xferOptimization(
** 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
+** we have to use an 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
@@ -89115,12 +103198,9 @@ static int xferOptimization(
** yield X
** end loop
** cleanup after the SELECT
-** EOF <- 1
-** yield X
-** halt-error
+** end co-routine R
** B: open temp table
-** L: yield X
-** if EOF goto M
+** L: yield X, at EOF goto M
** insert row from R..R+n into temp table
** goto L
** M: open write cursor to <table> and its indices
@@ -89133,7 +103213,6 @@ static int xferOptimization(
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 */
@@ -89147,18 +103226,21 @@ SQLITE_PRIVATE void sqlite3Insert(
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 iDataCur = 0; /* VDBE cursor that is the main data repository */
+ int iIdxCur = 0; /* First index cursor */
+ int ipkColumn = -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 */
+ u8 useTempTable = 0; /* Store SELECT results in intermediate table */
+ u8 appendFlag = 0; /* True if the insert is likely to be an append */
+ u8 withoutRowid; /* 0 for normal table. 1 for WITHOUT ROWID table */
+ u8 bIdListInOrder; /* True if IDLIST is in table order */
+ ExprList *pList = 0; /* List of VALUES() to be inserted */
/* Register allocations */
int regFromSelect = 0;/* Base register for data coming from SELECT */
@@ -89167,7 +103249,6 @@ SQLITE_PRIVATE void sqlite3Insert(
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
@@ -89182,6 +103263,17 @@ SQLITE_PRIVATE void sqlite3Insert(
goto insert_cleanup;
}
+ /* If the Select object is really just a simple VALUES() list with a
+ ** single row (the common case) then keep that one row of values
+ ** and discard the other (unused) parts of the pSelect object
+ */
+ if( pSelect && (pSelect->selFlags & SF_Values)!=0 && pSelect->pPrior==0 ){
+ pList = pSelect->pEList;
+ pSelect->pEList = 0;
+ sqlite3SelectDelete(db, pSelect);
+ pSelect = 0;
+ }
+
/* Locate the table into which we will be inserting new information.
*/
assert( pTabList->nSrc==1 );
@@ -89198,6 +103290,7 @@ SQLITE_PRIVATE void sqlite3Insert(
if( sqlite3AuthCheck(pParse, SQLITE_INSERT, pTab->zName, 0, zDb) ){
goto insert_cleanup;
}
+ withoutRowid = !HasRowid(pTab);
/* Figure out if we have any triggers and if the table being
** inserted into is a view
@@ -89217,16 +103310,13 @@ SQLITE_PRIVATE void sqlite3Insert(
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).
+ ** ViewGetColumnNames() is a no-op if pTab is not a view.
*/
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
+ /* Cannot insert into a read-only table.
*/
if( sqlite3IsReadOnly(pParse, pTab, tmask) ){
goto insert_cleanup;
@@ -89261,33 +103351,94 @@ SQLITE_PRIVATE void sqlite3Insert(
*/
regAutoinc = autoIncBegin(pParse, iDb, pTab);
+ /* Allocate registers for holding the rowid of the new row,
+ ** the content of the new row, and the assembled row record.
+ */
+ regRowid = regIns = pParse->nMem+1;
+ pParse->nMem += pTab->nCol + 1;
+ if( IsVirtual(pTab) ){
+ regRowid++;
+ pParse->nMem++;
+ }
+ regData = regRowid+1;
+
+ /* 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 ipkColumn variable
+ ** the index into IDLIST of the primary key column. ipkColumn is
+ ** the index of the primary key as it appears in IDLIST, not as
+ ** is appears in the original table. (The index of the INTEGER
+ ** PRIMARY KEY in the original table is pTab->iPKey.)
+ */
+ bIdListInOrder = (pTab->tabFlags & TF_OOOHidden)==0;
+ 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( i!=j ) bIdListInOrder = 0;
+ if( j==pTab->iPKey ){
+ ipkColumn = i; assert( !withoutRowid );
+ }
+ break;
+ }
+ }
+ if( j>=pTab->nCol ){
+ if( sqlite3IsRowid(pColumn->a[i].zName) && !withoutRowid ){
+ ipkColumn = i;
+ bIdListInOrder = 0;
+ }else{
+ sqlite3ErrorMsg(pParse, "table %S has no column named %s",
+ pTabList, 0, pColumn->a[i].zName);
+ pParse->checkSchema = 1;
+ goto insert_cleanup;
+ }
+ }
+ }
+ }
+
/* 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;
+ /* Data is coming from a SELECT or from a multi-row VALUES clause.
+ ** Generate a co-routine to run the SELECT. */
+ int regYield; /* Register holding co-routine entry-point */
+ int addrTop; /* Top of the co-routine */
+ int rc; /* Result code */
+
+ regYield = ++pParse->nMem;
+ addrTop = sqlite3VdbeCurrentAddr(v) + 1;
+ sqlite3VdbeAddOp3(v, OP_InitCoroutine, regYield, 0, addrTop);
+ sqlite3SelectDestInit(&dest, SRT_Coroutine, regYield);
+ dest.iSdst = bIdListInOrder ? regData : 0;
+ dest.nSdst = pTab->nCol;
+ rc = sqlite3Select(pParse, pSelect, &dest);
regFromSelect = dest.iSdst;
+ if( rc || db->mallocFailed || pParse->nErr ) goto insert_cleanup;
+ sqlite3VdbeAddOp1(v, OP_EndCoroutine, regYield);
+ sqlite3VdbeJumpHere(v, addrTop - 1); /* label B: */
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
+ ** FALSE if each output 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) ){
+ if( pTrigger || readsTable(pParse, iDb, pTab) ){
useTempTable = 1;
}
@@ -89297,55 +103448,60 @@ SQLITE_PRIVATE void sqlite3Insert(
** here is from the 4th template:
**
** B: open temp table
- ** L: yield X
- ** if EOF goto M
+ ** L: yield X, goto M at EOF
** 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 */
+ int addrL; /* Label "L" */
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);
+ addrL = sqlite3VdbeAddOp1(v, OP_Yield, dest.iSDParm); VdbeCoverage(v);
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);
+ sqlite3VdbeGoto(v, addrL);
+ sqlite3VdbeJumpHere(v, addrL);
sqlite3ReleaseTempReg(pParse, regRec);
sqlite3ReleaseTempReg(pParse, regTempRowid);
}
}else{
- /* This is the case if the data for the INSERT is coming from a VALUES
- ** clause
+ /* This is the case if the data for the INSERT is coming from a
+ ** single-row 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) ){
+ if( pList ){
+ nColumn = pList->nExpr;
+ if( sqlite3ResolveExprListNames(&sNC, pList) ){
goto insert_cleanup;
}
+ }else{
+ nColumn = 0;
}
}
+ /* If there is no IDLIST term but the table has an integer primary
+ ** key, the set the ipkColumn variable to the integer primary key
+ ** column index in the original table definition.
+ */
+ if( pColumn==0 && nColumn>0 ){
+ ipkColumn = pTab->iPKey;
+ }
+
/* 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);
- }
+ for(i=0; i<pTab->nCol; i++){
+ nHidden += (IsHiddenColumn(&pTab->aCol[i]) ? 1 : 0);
}
if( pColumn==0 && nColumn && nColumn!=(pTab->nCol-nHidden) ){
sqlite3ErrorMsg(pParse,
@@ -89357,52 +103513,6 @@ SQLITE_PRIVATE void sqlite3Insert(
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
*/
@@ -89414,9 +103524,8 @@ SQLITE_PRIVATE void sqlite3Insert(
/* 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);
+ nIdx = sqlite3OpenTableAndIndices(pParse, pTab, OP_OpenWrite, 0, -1, 0,
+ &iDataCur, &iIdxCur);
aRegIdx = sqlite3DbMallocRaw(db, sizeof(int)*(nIdx+1));
if( aRegIdx==0 ){
goto insert_cleanup;
@@ -89431,39 +103540,27 @@ SQLITE_PRIVATE void sqlite3Insert(
/* This block codes the top of loop only. The complete loop is the
** following pseudocode (template 4):
**
- ** rewind temp table
+ ** rewind temp table, if empty goto D
** C: loop over rows of intermediate table
** transfer values form intermediate table into <table>
** end loop
** D: ...
*/
- addrInsTop = sqlite3VdbeAddOp1(v, OP_Rewind, srcTab);
+ addrInsTop = sqlite3VdbeAddOp1(v, OP_Rewind, srcTab); VdbeCoverage(v);
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
+ ** C: yield X, at 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);
+ addrInsTop = addrCont = sqlite3VdbeAddOp1(v, OP_Yield, dest.iSDParm);
+ VdbeCoverage(v);
}
- /* 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);
@@ -89476,20 +103573,21 @@ SQLITE_PRIVATE void sqlite3Insert(
** 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 ){
+ if( ipkColumn<0 ){
sqlite3VdbeAddOp2(v, OP_Integer, -1, regCols);
}else{
- int j1;
+ int addr1;
+ assert( !withoutRowid );
if( useTempTable ){
- sqlite3VdbeAddOp3(v, OP_Column, srcTab, keyColumn, regCols);
+ sqlite3VdbeAddOp3(v, OP_Column, srcTab, ipkColumn, regCols);
}else{
assert( pSelect==0 ); /* Otherwise useTempTable is true */
- sqlite3ExprCode(pParse, pList->a[keyColumn].pExpr, regCols);
+ sqlite3ExprCode(pParse, pList->a[ipkColumn].pExpr, regCols);
}
- j1 = sqlite3VdbeAddOp1(v, OP_NotNull, regCols);
+ addr1 = sqlite3VdbeAddOp1(v, OP_NotNull, regCols); VdbeCoverage(v);
sqlite3VdbeAddOp2(v, OP_Integer, -1, regCols);
- sqlite3VdbeJumpHere(v, j1);
- sqlite3VdbeAddOp1(v, OP_MustBeInt, regCols);
+ sqlite3VdbeJumpHere(v, addr1);
+ sqlite3VdbeAddOp1(v, OP_MustBeInt, regCols); VdbeCoverage(v);
}
/* Cannot have triggers on a virtual table. If it were possible,
@@ -89499,15 +103597,14 @@ SQLITE_PRIVATE void sqlite3Insert(
/* Create the new column data
*/
- for(i=0; i<pTab->nCol; i++){
- if( pColumn==0 ){
- j = i;
- }else{
+ for(i=j=0; i<pTab->nCol; i++){
+ if( pColumn ){
for(j=0; j<pColumn->nId; j++){
if( pColumn->a[j].idx==i ) break;
}
}
- if( (!useTempTable && !pList) || (pColumn && j>=pColumn->nId) ){
+ if( (!useTempTable && !pList) || (pColumn && j>=pColumn->nId)
+ || (pColumn==0 && IsOrdinaryHiddenColumn(&pTab->aCol[i])) ){
sqlite3ExprCode(pParse, pTab->aCol[i].pDflt, regCols+i+1);
}else if( useTempTable ){
sqlite3VdbeAddOp3(v, OP_Column, srcTab, j, regCols+i+1);
@@ -89515,6 +103612,7 @@ SQLITE_PRIVATE void sqlite3Insert(
assert( pSelect==0 ); /* Otherwise useTempTable is true */
sqlite3ExprCodeAndCache(pParse, pList->a[j].pExpr, regCols+i+1);
}
+ if( pColumn==0 && !IsOrdinaryHiddenColumn(&pTab->aCol[i]) ) j++;
}
/* If this is an INSERT on a view with an INSTEAD OF INSERT trigger,
@@ -89523,8 +103621,7 @@ SQLITE_PRIVATE void sqlite3Insert(
** table column affinities.
*/
if( !isView ){
- sqlite3VdbeAddOp2(v, OP_Affinity, regCols+1, pTab->nCol);
- sqlite3TableAffinityStr(v, pTab);
+ sqlite3TableAffinity(v, pTab, regCols+1);
}
/* Fire BEFORE or INSTEAD OF triggers */
@@ -89534,29 +103631,27 @@ SQLITE_PRIVATE void sqlite3Insert(
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.
+ /* Compute the content of the next row to insert into a range of
+ ** registers beginning at regIns.
*/
if( !isView ){
if( IsVirtual(pTab) ){
/* The row that the VUpdate opcode will delete: none */
sqlite3VdbeAddOp2(v, OP_Null, 0, regIns);
}
- if( keyColumn>=0 ){
+ if( ipkColumn>=0 ){
if( useTempTable ){
- sqlite3VdbeAddOp3(v, OP_Column, srcTab, keyColumn, regRowid);
+ sqlite3VdbeAddOp3(v, OP_Column, srcTab, ipkColumn, regRowid);
}else if( pSelect ){
- sqlite3VdbeAddOp2(v, OP_SCopy, regFromSelect+keyColumn, regRowid);
+ sqlite3VdbeAddOp2(v, OP_Copy, regFromSelect+ipkColumn, regRowid);
}else{
VdbeOp *pOp;
- sqlite3ExprCode(pParse, pList->a[keyColumn].pExpr, regRowid);
+ sqlite3ExprCode(pParse, pList->a[ipkColumn].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->p1 = iDataCur;
pOp->p2 = regRowid;
pOp->p3 = regAutoinc;
}
@@ -89565,26 +103660,26 @@ SQLITE_PRIVATE void sqlite3Insert(
** to generate a unique primary key value.
*/
if( !appendFlag ){
- int j1;
+ int addr1;
if( !IsVirtual(pTab) ){
- j1 = sqlite3VdbeAddOp1(v, OP_NotNull, regRowid);
- sqlite3VdbeAddOp3(v, OP_NewRowid, baseCur, regRowid, regAutoinc);
- sqlite3VdbeJumpHere(v, j1);
+ addr1 = sqlite3VdbeAddOp1(v, OP_NotNull, regRowid); VdbeCoverage(v);
+ sqlite3VdbeAddOp3(v, OP_NewRowid, iDataCur, regRowid, regAutoinc);
+ sqlite3VdbeJumpHere(v, addr1);
}else{
- j1 = sqlite3VdbeCurrentAddr(v);
- sqlite3VdbeAddOp2(v, OP_IsNull, regRowid, j1+2);
+ addr1 = sqlite3VdbeCurrentAddr(v);
+ sqlite3VdbeAddOp2(v, OP_IsNull, regRowid, addr1+2); VdbeCoverage(v);
}
- sqlite3VdbeAddOp1(v, OP_MustBeInt, regRowid);
+ sqlite3VdbeAddOp1(v, OP_MustBeInt, regRowid); VdbeCoverage(v);
}
- }else if( IsVirtual(pTab) ){
+ }else if( IsVirtual(pTab) || withoutRowid ){
sqlite3VdbeAddOp2(v, OP_Null, 0, regRowid);
}else{
- sqlite3VdbeAddOp3(v, OP_NewRowid, baseCur, regRowid, regAutoinc);
+ sqlite3VdbeAddOp3(v, OP_NewRowid, iDataCur, regRowid, regAutoinc);
appendFlag = 1;
}
autoIncStep(pParse, regAutoinc, regRowid);
- /* Push onto the stack, data for all columns of the new entry, beginning
+ /* Compute data for all columns of the new entry, beginning
** with the first column.
*/
nHidden = 0;
@@ -89592,15 +103687,15 @@ SQLITE_PRIVATE void sqlite3Insert(
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);
+ ** Whenever this column is read, the rowid will be substituted
+ ** in its place. Hence, fill this column with a NULL to avoid
+ ** taking up data space with information that will never be used.
+ ** As there may be shallow copies of this value, make it a soft-NULL */
+ sqlite3VdbeAddOp1(v, OP_SoftNull, iRegStore);
continue;
}
if( pColumn==0 ){
if( IsHiddenColumn(&pTab->aCol[i]) ){
- assert( IsVirtual(pTab) );
j = -1;
nHidden++;
}else{
@@ -89612,11 +103707,13 @@ SQLITE_PRIVATE void sqlite3Insert(
}
}
if( j<0 || nColumn==0 || (pColumn && j>=pColumn->nId) ){
- sqlite3ExprCode(pParse, pTab->aCol[i].pDflt, iRegStore);
+ sqlite3ExprCodeFactorable(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);
+ if( regFromSelect!=regData ){
+ sqlite3VdbeAddOp2(v, OP_SCopy, regFromSelect+j, iRegStore);
+ }
}else{
sqlite3ExprCode(pParse, pList->a[j].pExpr, iRegStore);
}
@@ -89636,13 +103733,12 @@ SQLITE_PRIVATE void sqlite3Insert(
#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
+ sqlite3GenerateConstraintChecks(pParse, pTab, aRegIdx, iDataCur, iIdxCur,
+ regIns, 0, ipkColumn>=0, onError, endOfLoop, &isReplace
);
+ sqlite3FkCheck(pParse, pTab, 0, regIns, 0, 0);
+ sqlite3CompleteInsertion(pParse, pTab, iDataCur, iIdxCur,
+ regIns, aRegIdx, 0, appendFlag, isReplace==0);
}
}
@@ -89663,19 +103759,19 @@ SQLITE_PRIVATE void sqlite3Insert(
*/
sqlite3VdbeResolveLabel(v, endOfLoop);
if( useTempTable ){
- sqlite3VdbeAddOp2(v, OP_Next, srcTab, addrCont);
+ sqlite3VdbeAddOp2(v, OP_Next, srcTab, addrCont); VdbeCoverage(v);
sqlite3VdbeJumpHere(v, addrInsTop);
sqlite3VdbeAddOp1(v, OP_Close, srcTab);
}else if( pSelect ){
- sqlite3VdbeAddOp2(v, OP_Goto, 0, addrCont);
+ sqlite3VdbeGoto(v, 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);
+ if( iDataCur<iIdxCur ) sqlite3VdbeAddOp1(v, OP_Close, iDataCur);
+ for(idx=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, idx++){
+ sqlite3VdbeAddOp1(v, OP_Close, idx+iIdxCur);
}
}
@@ -89708,7 +103804,7 @@ insert_cleanup:
}
/* Make sure "isView" and other macros defined above are undefined. Otherwise
-** thely may interfere with compilation of other functions in this file
+** they 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
@@ -89720,36 +103816,48 @@ insert_cleanup:
#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.
+** Generate code to do constraint checks prior to an INSERT or an UPDATE
+** on table pTab.
**
-** 2. The data in the first column of the entry after the update.
+** The regNewData parameter is the first register in a range that contains
+** the data to be inserted or the data after the update. There will be
+** pTab->nCol+1 registers in this range. The first register (the one
+** that regNewData points to) will contain the new rowid, or NULL in the
+** case of a WITHOUT ROWID table. The second register in the range will
+** contain the content of the first table column. The third register will
+** contain the content of the second table column. And so forth.
**
-** i. Data from middle columns...
+** The regOldData parameter is similar to regNewData except that it contains
+** the data prior to an UPDATE rather than afterwards. regOldData is zero
+** for an INSERT. This routine can distinguish between UPDATE and INSERT by
+** checking regOldData for zero.
**
-** N. The data in the last column of the entry after the update.
+** For an UPDATE, the pkChng boolean is true if the true primary key (the
+** rowid for a normal table or the PRIMARY KEY for a WITHOUT ROWID table)
+** might be modified by the UPDATE. If pkChng is false, then the key of
+** the iDataCur content table is guaranteed to be unchanged by the UPDATE.
**
-** The regRowid parameter is the index of the register containing (1).
+** For an INSERT, the pkChng boolean indicates whether or not the rowid
+** was explicitly specified as part of the INSERT statement. If pkChng
+** is zero, it means that the either rowid is computed automatically or
+** that the table is a WITHOUT ROWID table and has no rowid. On an INSERT,
+** pkChng will only be true if the INSERT statement provides an integer
+** value for either the rowid column or its INTEGER PRIMARY KEY alias.
**
-** 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
+** The code generated by this routine will 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.
+** at pTab->pIndex.
+**
+** The caller must have already opened writeable cursors on the main
+** table and all applicable indices (that is to say, all indices for which
+** aRegIdx[] is not zero). iDataCur is the cursor for the main table when
+** inserting or updating a rowid table, or the cursor for the PRIMARY KEY
+** index when operating on a WITHOUT ROWID table. iIdxCur is the cursor
+** for the first index in the pTab->pIndex list. Cursors for other indices
+** are at iIdxCur+N for the N-th element of the pTab->pIndex list.
**
** This routine also generates code to check constraints. NOT NULL,
** CHECK, and UNIQUE constraints are all checked. If a constraint fails,
@@ -89759,22 +103867,23 @@ insert_cleanup:
** Constraint type Action What Happens
** --------------- ---------- ----------------------------------------
** any ROLLBACK The current transaction is rolled back and
-** sqlite3_exec() returns immediately with a
+** sqlite3_step() 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
+** cause sqlite3_step() to return immediately
** with SQLITE_CONSTRAINT.
**
-** any FAIL Sqlite3_exec() returns immediately with a
+** any FAIL Sqlite3_step() returns immediately with a
** return code of SQLITE_CONSTRAINT. The
** transaction is not rolled back and any
-** prior changes are retained.
+** changes to prior rows are retained.
**
-** any IGNORE The record number and data is popped from
-** the stack and there is an immediate jump
-** to label ignoreDest.
+** any IGNORE The attempt in insert or update the current
+** row is skipped, without throwing an error.
+** Processing continues with the next row.
+** (There is an immediate jump to ignoreDest.)
**
** NOT NULL REPLACE The NULL value is replace by the default
** value for that column. If the default value
@@ -89789,44 +103898,59 @@ insert_cleanup:
** 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 */
+ Parse *pParse, /* The parser context */
+ Table *pTab, /* The table being inserted or updated */
+ int *aRegIdx, /* Use register aRegIdx[i] for index i. 0 for unused */
+ int iDataCur, /* Canonical data cursor (main table or PK index) */
+ int iIdxCur, /* First index cursor */
+ int regNewData, /* First register in a range holding values to insert */
+ int regOldData, /* Previous content. 0 for INSERTs */
+ u8 pkChng, /* Non-zero if the rowid or PRIMARY KEY changed */
+ u8 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 */
+){
+ Vdbe *v; /* VDBE under constrution */
Index *pIdx; /* Pointer to one of the indices */
+ Index *pPk = 0; /* The PRIMARY KEY index */
sqlite3 *db; /* Database connection */
+ int i; /* loop counter */
+ int ix; /* Index loop counter */
+ int nCol; /* Number of columns */
+ int onError; /* Conflict resolution strategy */
+ int addr1; /* Address of jump instruction */
int seenReplace = 0; /* True if REPLACE is used to resolve INT PK conflict */
- int regOldRowid = (rowidChng && isUpdate) ? rowidChng : regRowid;
-
+ int nPkField; /* Number of fields in PRIMARY KEY. 1 for ROWID tables */
+ int ipkTop = 0; /* Top of the rowid change constraint check */
+ int ipkBottom = 0; /* Bottom of the rowid change constraint check */
+ u8 isUpdate; /* True if this is an UPDATE operation */
+ u8 bAffinityDone = 0; /* True if the OP_Affinity operation has been run */
+ int regRowid = -1; /* Register holding ROWID value */
+
+ isUpdate = regOldData!=0;
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;
+
+ /* pPk is the PRIMARY KEY index for WITHOUT ROWID tables and NULL for
+ ** normal rowid tables. nPkField is the number of key fields in the
+ ** pPk index or 1 for a rowid table. In other words, nPkField is the
+ ** number of fields in the true primary key of the table. */
+ if( HasRowid(pTab) ){
+ pPk = 0;
+ nPkField = 1;
+ }else{
+ pPk = sqlite3PrimaryKeyIndex(pTab);
+ nPkField = pPk->nKeyCol;
+ }
+
+ /* Record that this module has started */
+ VdbeModuleComment((v, "BEGIN: GenCnstCks(%d,%d,%d,%d,%d)",
+ iDataCur, iIdxCur, regNewData, regOldData, pkChng));
/* Test all NOT NULL constraints.
*/
@@ -89849,25 +103973,28 @@ SQLITE_PRIVATE void sqlite3GenerateConstraintChecks(
switch( onError ){
case OE_Abort:
sqlite3MayAbort(pParse);
+ /* Fall through */
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);
+ char *zMsg = sqlite3MPrintf(db, "%s.%s", pTab->zName,
+ pTab->aCol[i].zName);
+ sqlite3VdbeAddOp4(v, OP_HaltIfNull, SQLITE_CONSTRAINT_NOTNULL, onError,
+ regNewData+1+i, zMsg, P4_DYNAMIC);
+ sqlite3VdbeChangeP5(v, P5_ConstraintNotNull);
+ VdbeCoverage(v);
break;
}
case OE_Ignore: {
- sqlite3VdbeAddOp2(v, OP_IsNull, regData+i, ignoreDest);
+ sqlite3VdbeAddOp2(v, OP_IsNull, regNewData+1+i, ignoreDest);
+ VdbeCoverage(v);
break;
}
default: {
assert( onError==OE_Replace );
- j1 = sqlite3VdbeAddOp1(v, OP_NotNull, regData+i);
- sqlite3ExprCode(pParse, pTab->aCol[i].pDflt, regData+i);
- sqlite3VdbeJumpHere(v, j1);
+ addr1 = sqlite3VdbeAddOp1(v, OP_NotNull, regNewData+1+i);
+ VdbeCoverage(v);
+ sqlite3ExprCode(pParse, pTab->aCol[i].pDflt, regNewData+1+i);
+ sqlite3VdbeJumpHere(v, addr1);
break;
}
}
@@ -89878,44 +104005,69 @@ SQLITE_PRIVATE void sqlite3GenerateConstraintChecks(
#ifndef SQLITE_OMIT_CHECK
if( pTab->pCheck && (db->flags & SQLITE_IgnoreChecks)==0 ){
ExprList *pCheck = pTab->pCheck;
- pParse->ckBase = regData;
+ pParse->ckBase = regNewData+1;
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);
+ sqlite3VdbeGoto(v, ignoreDest);
}else{
- char *zConsName = pCheck->a[i].zName;
+ char *zName = pCheck->a[i].zName;
+ if( zName==0 ) zName = pTab->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);
+ sqlite3HaltConstraint(pParse, SQLITE_CONSTRAINT_CHECK,
+ onError, zName, P4_TRANSIENT,
+ P5_ConstraintCheck);
}
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 rowid is changing, make sure the new rowid does not previously
+ ** exist in the table.
*/
- if( rowidChng ){
+ if( pkChng && pPk==0 ){
+ int addrRowidOk = sqlite3VdbeMakeLabel(v);
+
+ /* Figure out what action to take in case of a rowid collision */
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);
+ /* pkChng!=0 does not mean that the rowid has change, only that
+ ** it might have changed. Skip the conflict logic below if the rowid
+ ** is unchanged. */
+ sqlite3VdbeAddOp3(v, OP_Eq, regNewData, addrRowidOk, regOldData);
+ sqlite3VdbeChangeP5(v, SQLITE_NOTNULL);
+ VdbeCoverage(v);
+ }
+
+ /* If the response to a rowid conflict is REPLACE but the response
+ ** to some other UNIQUE constraint is FAIL or IGNORE, then we need
+ ** to defer the running of the rowid conflict checking until after
+ ** the UNIQUE constraints have run.
+ */
+ if( onError==OE_Replace && overrideError!=OE_Replace ){
+ for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){
+ if( pIdx->onError==OE_Ignore || pIdx->onError==OE_Fail ){
+ ipkTop = sqlite3VdbeAddOp0(v, OP_Goto);
+ break;
+ }
+ }
}
- j3 = sqlite3VdbeAddOp3(v, OP_NotExists, baseCur, 0, regRowid);
+
+ /* Check to see if the new rowid already exists in the table. Skip
+ ** the following conflict logic if it does not. */
+ sqlite3VdbeAddOp3(v, OP_NotExists, iDataCur, addrRowidOk, regNewData);
+ VdbeCoverage(v);
+
+ /* Generate code that deals with a rowid collision */
switch( onError ){
default: {
onError = OE_Abort;
@@ -89924,8 +104076,7 @@ SQLITE_PRIVATE void sqlite3GenerateConstraintChecks(
case OE_Rollback:
case OE_Abort:
case OE_Fail: {
- sqlite3HaltConstraint(
- pParse, onError, "PRIMARY KEY must be unique", P4_STATIC);
+ sqlite3RowidConstraint(pParse, onError, pTab);
break;
}
case OE_Replace: {
@@ -89957,57 +104108,103 @@ SQLITE_PRIVATE void sqlite3GenerateConstraintChecks(
}
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);
+ sqlite3GenerateRowDelete(pParse, pTab, pTrigger, iDataCur, iIdxCur,
+ regNewData, 1, 0, OE_Replace,
+ ONEPASS_SINGLE, -1);
+ }else{
+ if( pTab->pIndex ){
+ sqlite3MultiWrite(pParse);
+ sqlite3GenerateRowIndexDelete(pParse, pTab, iDataCur, iIdxCur,0,-1);
+ }
}
seenReplace = 1;
break;
}
case OE_Ignore: {
- assert( seenReplace==0 );
- sqlite3VdbeAddOp2(v, OP_Goto, 0, ignoreDest);
+ /*assert( seenReplace==0 );*/
+ sqlite3VdbeGoto(v, ignoreDest);
break;
}
}
- sqlite3VdbeJumpHere(v, j3);
- if( isUpdate ){
- sqlite3VdbeJumpHere(v, j2);
+ sqlite3VdbeResolveLabel(v, addrRowidOk);
+ if( ipkTop ){
+ ipkBottom = sqlite3VdbeAddOp0(v, OP_Goto);
+ sqlite3VdbeJumpHere(v, ipkTop);
}
}
/* 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);
+ ** Compute the revised record entries for indices as we go.
+ **
+ ** This loop also handles the case of the PRIMARY KEY index for a
+ ** WITHOUT ROWID table.
+ */
+ for(ix=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, ix++){
+ int regIdx; /* Range of registers hold conent for pIdx */
+ int regR; /* Range of registers holding conflicting PK */
+ int iThisCur; /* Cursor for this UNIQUE index */
+ int addrUniqueOk; /* Jump here if the UNIQUE constraint is satisfied */
+
+ if( aRegIdx[ix]==0 ) continue; /* Skip indices that do not change */
+ if( bAffinityDone==0 ){
+ sqlite3TableAffinity(v, pTab, regNewData+1);
+ bAffinityDone = 1;
+ }
+ iThisCur = iIdxCur+ix;
+ addrUniqueOk = sqlite3VdbeMakeLabel(v);
+
+ /* Skip partial indices for which the WHERE clause is not true */
+ if( pIdx->pPartIdxWhere ){
+ sqlite3VdbeAddOp2(v, OP_Null, 0, aRegIdx[ix]);
+ pParse->ckBase = regNewData+1;
+ sqlite3ExprIfFalseDup(pParse, pIdx->pPartIdxWhere, addrUniqueOk,
+ SQLITE_JUMPIFNULL);
+ pParse->ckBase = 0;
+ }
+
+ /* Create a record for this index entry as it should appear after
+ ** the insert or update. Store that record in the aRegIdx[ix] register
+ */
+ regIdx = sqlite3GetTempRange(pParse, pIdx->nColumn);
for(i=0; i<pIdx->nColumn; i++){
- int idx = pIdx->aiColumn[i];
- if( idx==pTab->iPKey ){
- sqlite3VdbeAddOp2(v, OP_SCopy, regRowid, regIdx+i);
+ int iField = pIdx->aiColumn[i];
+ int x;
+ if( iField==XN_EXPR ){
+ pParse->ckBase = regNewData+1;
+ sqlite3ExprCodeCopy(pParse, pIdx->aColExpr->a[i].pExpr, regIdx+i);
+ pParse->ckBase = 0;
+ VdbeComment((v, "%s column %d", pIdx->zName, i));
}else{
- sqlite3VdbeAddOp2(v, OP_SCopy, regData+idx, regIdx+i);
+ if( iField==XN_ROWID || iField==pTab->iPKey ){
+ if( regRowid==regIdx+i ) continue; /* ROWID already in regIdx+i */
+ x = regNewData;
+ regRowid = pIdx->pPartIdxWhere ? -1 : regIdx+i;
+ }else{
+ x = iField + regNewData + 1;
+ }
+ sqlite3VdbeAddOp2(v, iField<0 ? OP_IntCopy : OP_SCopy, x, regIdx+i);
+ VdbeComment((v, "%s", iField<0 ? "rowid" : pTab->aCol[iField].zName));
}
}
- 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);
+ sqlite3VdbeAddOp3(v, OP_MakeRecord, regIdx, pIdx->nColumn, aRegIdx[ix]);
+ VdbeComment((v, "for %s", pIdx->zName));
+ sqlite3ExprCacheAffinityChange(pParse, regIdx, pIdx->nColumn);
- /* Find out what action to take in case there is an indexing conflict */
+ /* In an UPDATE operation, if this index is the PRIMARY KEY index
+ ** of a WITHOUT ROWID table and there has been no change the
+ ** primary key, then no collision is possible. The collision detection
+ ** logic below can all be skipped. */
+ if( isUpdate && pPk==pIdx && pkChng==0 ){
+ sqlite3VdbeResolveLabel(v, addrUniqueOk);
+ continue;
+ }
+
+ /* Find out what action to take in case there is a uniqueness conflict */
onError = pIdx->onError;
if( onError==OE_None ){
- sqlite3ReleaseTempRange(pParse, regIdx, pIdx->nColumn+1);
+ sqlite3ReleaseTempRange(pParse, regIdx, pIdx->nColumn);
+ sqlite3VdbeResolveLabel(v, addrUniqueOk);
continue; /* pIdx is not a UNIQUE index */
}
if( overrideError!=OE_Default ){
@@ -90015,18 +104212,66 @@ SQLITE_PRIVATE void sqlite3GenerateConstraintChecks(
}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);
+ sqlite3VdbeAddOp4Int(v, OP_NoConflict, iThisCur, addrUniqueOk,
+ regIdx, pIdx->nKeyCol); VdbeCoverage(v);
+
+ /* Generate code to handle collisions */
+ regR = (pIdx==pPk) ? regIdx : sqlite3GetTempRange(pParse, nPkField);
+ if( isUpdate || onError==OE_Replace ){
+ if( HasRowid(pTab) ){
+ sqlite3VdbeAddOp2(v, OP_IdxRowid, iThisCur, regR);
+ /* Conflict only if the rowid of the existing index entry
+ ** is different from old-rowid */
+ if( isUpdate ){
+ sqlite3VdbeAddOp3(v, OP_Eq, regR, addrUniqueOk, regOldData);
+ sqlite3VdbeChangeP5(v, SQLITE_NOTNULL);
+ VdbeCoverage(v);
+ }
+ }else{
+ int x;
+ /* Extract the PRIMARY KEY from the end of the index entry and
+ ** store it in registers regR..regR+nPk-1 */
+ if( pIdx!=pPk ){
+ for(i=0; i<pPk->nKeyCol; i++){
+ assert( pPk->aiColumn[i]>=0 );
+ x = sqlite3ColumnOfIndex(pIdx, pPk->aiColumn[i]);
+ sqlite3VdbeAddOp3(v, OP_Column, iThisCur, x, regR+i);
+ VdbeComment((v, "%s.%s", pTab->zName,
+ pTab->aCol[pPk->aiColumn[i]].zName));
+ }
+ }
+ if( isUpdate ){
+ /* If currently processing the PRIMARY KEY of a WITHOUT ROWID
+ ** table, only conflict if the new PRIMARY KEY values are actually
+ ** different from the old.
+ **
+ ** For a UNIQUE index, only conflict if the PRIMARY KEY values
+ ** of the matched index row are different from the original PRIMARY
+ ** KEY values of this row before the update. */
+ int addrJump = sqlite3VdbeCurrentAddr(v)+pPk->nKeyCol;
+ int op = OP_Ne;
+ int regCmp = (IsPrimaryKeyIndex(pIdx) ? regIdx : regR);
+
+ for(i=0; i<pPk->nKeyCol; i++){
+ char *p4 = (char*)sqlite3LocateCollSeq(pParse, pPk->azColl[i]);
+ x = pPk->aiColumn[i];
+ assert( x>=0 );
+ if( i==(pPk->nKeyCol-1) ){
+ addrJump = addrUniqueOk;
+ op = OP_Eq;
+ }
+ sqlite3VdbeAddOp4(v, op,
+ regOldData+1+x, addrJump, regCmp+i, p4, P4_COLLSEQ
+ );
+ sqlite3VdbeChangeP5(v, SQLITE_NOTNULL);
+ VdbeCoverageIf(v, op==OP_Eq);
+ VdbeCoverageIf(v, op==OP_Ne);
+ }
+ }
+ }
+ }
/* Generate code that executes if the new index entry is not unique */
assert( onError==OE_Rollback || onError==OE_Abort || onError==OE_Fail
@@ -90035,30 +104280,11 @@ SQLITE_PRIVATE void sqlite3GenerateConstraintChecks(
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);
+ sqlite3UniqueConstraint(pParse, onError, pIdx);
break;
}
case OE_Ignore: {
- assert( seenReplace==0 );
- sqlite3VdbeAddOp2(v, OP_Goto, 0, ignoreDest);
+ sqlite3VdbeGoto(v, ignoreDest);
break;
}
default: {
@@ -90068,26 +104294,30 @@ SQLITE_PRIVATE void sqlite3GenerateConstraintChecks(
if( db->flags&SQLITE_RecTriggers ){
pTrigger = sqlite3TriggersExist(pParse, pTab, TK_DELETE, 0, 0);
}
- sqlite3GenerateRowDelete(
- pParse, pTab, baseCur, regR, 0, pTrigger, OE_Replace
- );
+ sqlite3GenerateRowDelete(pParse, pTab, pTrigger, iDataCur, iIdxCur,
+ regR, nPkField, 0, OE_Replace,
+ (pIdx==pPk ? ONEPASS_SINGLE : ONEPASS_OFF), -1);
seenReplace = 1;
break;
}
}
- sqlite3VdbeJumpHere(v, j3);
- sqlite3ReleaseTempReg(pParse, regR);
+ sqlite3VdbeResolveLabel(v, addrUniqueOk);
+ sqlite3ReleaseTempRange(pParse, regIdx, pIdx->nColumn);
+ if( regR!=regIdx ) sqlite3ReleaseTempRange(pParse, regR, nPkField);
}
-
- if( pbMayReplace ){
- *pbMayReplace = seenReplace;
+ if( ipkTop ){
+ sqlite3VdbeGoto(v, ipkTop+1);
+ sqlite3VdbeJumpHere(v, ipkBottom);
}
+
+ *pbMayReplace = seenReplace;
+ VdbeModuleComment((v, "END: GenCnstCks(%d)", 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
+** A consecutive range of registers starting at regNewData contains the
** rowid and the content to be inserted.
**
** The arguments to this routine should be the same as the first six
@@ -90096,36 +104326,46 @@ SQLITE_PRIVATE void 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 iDataCur, /* Cursor of the canonical data source */
+ int iIdxCur, /* First index cursor */
+ int regNewData, /* 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;
+ Vdbe *v; /* Prepared statements under construction */
+ Index *pIdx; /* An index being inserted or updated */
+ u8 pik_flags; /* flag values passed to the btree insert */
+ int regData; /* Content registers (after the rowid) */
+ int regRec; /* Register holding assembled record for the table */
+ int i; /* Loop counter */
+ u8 bAffinityDone = 0; /* True if OP_Affinity has been run already */
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--){
+ for(i=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, i++){
if( aRegIdx[i]==0 ) continue;
- sqlite3VdbeAddOp2(v, OP_IdxInsert, baseCur+i+1, aRegIdx[i]);
- if( useSeekResult ){
- sqlite3VdbeChangeP5(v, OPFLAG_USESEEKRESULT);
+ bAffinityDone = 1;
+ if( pIdx->pPartIdxWhere ){
+ sqlite3VdbeAddOp2(v, OP_IsNull, aRegIdx[i], sqlite3VdbeCurrentAddr(v)+2);
+ VdbeCoverage(v);
}
+ sqlite3VdbeAddOp2(v, OP_IdxInsert, iIdxCur+i, aRegIdx[i]);
+ pik_flags = 0;
+ if( useSeekResult ) pik_flags = OPFLAG_USESEEKRESULT;
+ if( IsPrimaryKeyIndex(pIdx) && !HasRowid(pTab) ){
+ assert( pParse->nested==0 );
+ pik_flags |= OPFLAG_NCHANGE;
+ }
+ if( pik_flags ) sqlite3VdbeChangeP5(v, pik_flags);
}
- regData = regRowid + 1;
+ if( !HasRowid(pTab) ) return;
+ regData = regNewData + 1;
regRec = sqlite3GetTempReg(pParse);
sqlite3VdbeAddOp3(v, OP_MakeRecord, regData, pTab->nCol, regRec);
- sqlite3TableAffinityStr(v, pTab);
+ if( !bAffinityDone ) sqlite3TableAffinity(v, pTab, 0);
sqlite3ExprCacheAffinityChange(pParse, regData, pTab->nCol);
if( pParse->nested ){
pik_flags = 0;
@@ -90139,7 +104379,7 @@ SQLITE_PRIVATE void sqlite3CompleteInsertion(
if( useSeekResult ){
pik_flags |= OPFLAG_USESEEKRESULT;
}
- sqlite3VdbeAddOp3(v, OP_Insert, baseCur, regRec, regRowid);
+ sqlite3VdbeAddOp3(v, OP_Insert, iDataCur, regRec, regNewData);
if( !pParse->nested ){
sqlite3VdbeChangeP4(v, -1, pTab->zName, P4_TRANSIENT);
}
@@ -90147,39 +104387,77 @@ SQLITE_PRIVATE void sqlite3CompleteInsertion(
}
/*
-** 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.
+** Allocate cursors for the pTab table and all its indices and generate
+** code to open and initialized those cursors.
+**
+** The cursor for the object that contains the complete data (normally
+** the table itself, but the PRIMARY KEY index in the case of a WITHOUT
+** ROWID table) is returned in *piDataCur. The first index cursor is
+** returned in *piIdxCur. The number of indices is returned.
+**
+** Use iBase as the first cursor (either the *piDataCur for rowid tables
+** or the first index for WITHOUT ROWID tables) if it is non-negative.
+** If iBase is negative, then allocate the next available cursor.
**
-** Return the number of indices on the table.
+** For a rowid table, *piDataCur will be exactly one less than *piIdxCur.
+** For a WITHOUT ROWID table, *piDataCur will be somewhere in the range
+** of *piIdxCurs, depending on where the PRIMARY KEY index appears on the
+** pTab->pIndex list.
+**
+** If pTab is a virtual table, then this routine is a no-op and the
+** *piDataCur and *piIdxCur values are left uninitialized.
*/
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 op, /* OP_OpenRead or OP_OpenWrite */
+ u8 p5, /* P5 value for OP_Open* instructions */
+ int iBase, /* Use this for the table cursor, if there is one */
+ u8 *aToOpen, /* If not NULL: boolean for each table and index */
+ int *piDataCur, /* Write the database source cursor number here */
+ int *piIdxCur /* Write the first index cursor number here */
){
int i;
int iDb;
+ int iDataCur;
Index *pIdx;
Vdbe *v;
- if( IsVirtual(pTab) ) return 0;
+ assert( op==OP_OpenRead || op==OP_OpenWrite );
+ assert( op==OP_OpenWrite || p5==0 );
+ if( IsVirtual(pTab) ){
+ /* This routine is a no-op for virtual tables. Leave the output
+ ** variables *piDataCur and *piIdxCur uninitialized so that valgrind
+ ** can detect if they are used by mistake in the caller. */
+ 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( iBase<0 ) iBase = pParse->nTab;
+ iDataCur = iBase++;
+ if( piDataCur ) *piDataCur = iDataCur;
+ if( HasRowid(pTab) && (aToOpen==0 || aToOpen[0]) ){
+ sqlite3OpenTable(pParse, iDataCur, iDb, pTab, op);
+ }else{
+ sqlite3TableLock(pParse, iDb, pTab->tnum, op==OP_OpenWrite, pTab->zName);
}
- if( pParse->nTab<baseCur+i ){
- pParse->nTab = baseCur+i;
+ if( piIdxCur ) *piIdxCur = iBase;
+ for(i=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, i++){
+ int iIdxCur = iBase++;
+ assert( pIdx->pSchema==pTab->pSchema );
+ if( IsPrimaryKeyIndex(pIdx) && !HasRowid(pTab) && piDataCur ){
+ *piDataCur = iIdxCur;
+ }
+ if( aToOpen==0 || aToOpen[i+1] ){
+ sqlite3VdbeAddOp3(v, op, iIdxCur, pIdx->tnum, iDb);
+ sqlite3VdbeSetP4KeyInfo(pParse, pIdx);
+ sqlite3VdbeChangeP5(v, p5);
+ VdbeComment((v, "%s", pIdx->zName));
+ }
}
- return i-1;
+ if( iBase>pParse->nTab ) pParse->nTab = iBase;
+ return i;
}
@@ -90188,7 +104466,7 @@ SQLITE_PRIVATE int sqlite3OpenTableAndIndices(
** 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.
+** is happening when it is supposed to.
*/
SQLITE_API int sqlite3_xferopt_count;
#endif /* SQLITE_TEST */
@@ -90196,20 +104474,6 @@ SQLITE_API int sqlite3_xferopt_count;
#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:
@@ -90218,28 +104482,39 @@ static int xferCompatibleCollation(const char *z1, const char *z2){
** * 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
+** * The index has the exact same WHERE clause
*/
static int xferCompatibleIndex(Index *pDest, Index *pSrc){
int i;
assert( pDest && pSrc );
assert( pDest->pTable!=pSrc->pTable );
- if( pDest->nColumn!=pSrc->nColumn ){
+ if( pDest->nKeyCol!=pSrc->nKeyCol ){
return 0; /* Different number of columns */
}
if( pDest->onError!=pSrc->onError ){
return 0; /* Different conflict resolution strategies */
}
- for(i=0; i<pSrc->nColumn; i++){
+ for(i=0; i<pSrc->nKeyCol; i++){
if( pSrc->aiColumn[i]!=pDest->aiColumn[i] ){
return 0; /* Different columns indexed */
}
+ if( pSrc->aiColumn[i]==XN_EXPR ){
+ assert( pSrc->aColExpr!=0 && pDest->aColExpr!=0 );
+ if( sqlite3ExprCompare(pSrc->aColExpr->a[i].pExpr,
+ pDest->aColExpr->a[i].pExpr, -1)!=0 ){
+ return 0; /* Different expressions in the index */
+ }
+ }
if( pSrc->aSortOrder[i]!=pDest->aSortOrder[i] ){
return 0; /* Different sort orders */
}
- if( !xferCompatibleCollation(pSrc->azColl[i],pDest->azColl[i]) ){
+ if( sqlite3_stricmp(pSrc->azColl[i],pDest->azColl[i])!=0 ){
return 0; /* Different collating sequences */
}
}
+ if( sqlite3ExprCompare(pSrc->pPartIdxWhere, pDest->pPartIdxWhere, -1) ){
+ return 0; /* Different WHERE clauses */
+ }
/* If no test above fails then the indices must be compatible */
return 1;
@@ -90251,7 +104526,7 @@ static int xferCompatibleIndex(Index *pDest, Index *pSrc){
** 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
+** Columns are not decoded and reassembled, 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.
@@ -90277,6 +104552,7 @@ static int xferOptimization(
int onError, /* How to handle constraint errors */
int iDbDest /* The database of pDest */
){
+ sqlite3 *db = pParse->db;
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 */
@@ -90285,10 +104561,9 @@ static int xferOptimization(
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 */
+ int emptyDestTest = 0; /* Address of test for empty pDest */
+ int emptySrcTest = 0; /* 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 */
@@ -90296,6 +104571,12 @@ static int xferOptimization(
if( pSelect==0 ){
return 0; /* Must be of the form INSERT INTO ... SELECT ... */
}
+ if( pParse->pWith || pSelect->pWith ){
+ /* Do not attempt to process this query if there are an WITH clauses
+ ** attached to it. Proceeding may generate a false "no such table: xxx"
+ ** error if pSelect reads from a CTE named "xxx". */
+ return 0;
+ }
if( sqlite3TriggerList(pParse, pDest) ){
return 0; /* tab1 must not have triggers */
}
@@ -90342,7 +104623,7 @@ static int xferOptimization(
return 0; /* The result set must have exactly one column */
}
assert( pEList->a[0].pExpr );
- if( pEList->a[0].pExpr->op!=TK_ALL ){
+ if( pEList->a[0].pExpr->op!=TK_ASTERISK ){
return 0; /* The result set must be the special operator "*" */
}
@@ -90358,6 +104639,9 @@ static int xferOptimization(
if( pSrc==pDest ){
return 0; /* tab1 and tab2 may not be the same table */
}
+ if( HasRowid(pDest)!=HasRowid(pSrc) ){
+ return 0; /* source and destination must both be WITHOUT ROWID or not */
+ }
#ifndef SQLITE_OMIT_VIRTUALTABLE
if( pSrc->tabFlags & TF_Virtual ){
return 0; /* tab2 must not be a virtual table */
@@ -90373,18 +104657,34 @@ static int xferOptimization(
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 ){
+ Column *pDestCol = &pDest->aCol[i];
+ Column *pSrcCol = &pSrc->aCol[i];
+#ifdef SQLITE_ENABLE_HIDDEN_COLUMNS
+ if( (db->flags & SQLITE_Vacuum)==0
+ && (pDestCol->colFlags | pSrcCol->colFlags) & COLFLAG_HIDDEN
+ ){
+ return 0; /* Neither table may have __hidden__ columns */
+ }
+#endif
+ if( pDestCol->affinity!=pSrcCol->affinity ){
return 0; /* Affinity must be the same on all columns */
}
- if( !xferCompatibleCollation(pDest->aCol[i].zColl, pSrc->aCol[i].zColl) ){
+ if( sqlite3_stricmp(pDestCol->zColl, pSrcCol->zColl)!=0 ){
return 0; /* Collating sequence must be the same on all columns */
}
- if( pDest->aCol[i].notNull && !pSrc->aCol[i].notNull ){
+ if( pDestCol->notNull && !pSrcCol->notNull ){
return 0; /* tab2 must be NOT NULL if tab1 is */
}
+ /* Default values for second and subsequent columns need to match. */
+ if( i>0
+ && ((pDestCol->zDflt==0)!=(pSrcCol->zDflt==0)
+ || (pDestCol->zDflt && strcmp(pDestCol->zDflt, pSrcCol->zDflt)!=0))
+ ){
+ return 0; /* Default values must be the same for all columns */
+ }
}
for(pDestIdx=pDest->pIndex; pDestIdx; pDestIdx=pDestIdx->pNext){
- if( pDestIdx->onError!=OE_None ){
+ if( IsUniqueIndex(pDestIdx) ){
destHasUniqueIdx = 1;
}
for(pSrcIdx=pSrc->pIndex; pSrcIdx; pSrcIdx=pSrcIdx->pNext){
@@ -90395,7 +104695,7 @@ static int xferOptimization(
}
}
#ifndef SQLITE_OMIT_CHECK
- if( pDest->pCheck && sqlite3ExprListCompare(pSrc->pCheck, pDest->pCheck) ){
+ if( pDest->pCheck && sqlite3ExprListCompare(pSrc->pCheck,pDest->pCheck,-1) ){
return 0; /* Tables have different CHECK constraints. Ticket #2252 */
}
#endif
@@ -90407,11 +104707,11 @@ static int xferOptimization(
** 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 ){
+ if( (db->flags & SQLITE_ForeignKeys)!=0 && pDest->pFKey!=0 ){
return 0;
}
#endif
- if( (pParse->db->flags & SQLITE_CountRows)!=0 ){
+ if( (db->flags & SQLITE_CountRows)!=0 ){
return 0; /* xfer opt does not play well with PRAGMA count_changes */
}
@@ -90422,21 +104722,28 @@ static int xferOptimization(
#ifdef SQLITE_TEST
sqlite3_xferopt_count++;
#endif
- iDbSrc = sqlite3SchemaToIndex(pParse->db, pSrc->pSchema);
+ iDbSrc = sqlite3SchemaToIndex(db, pSrc->pSchema);
v = sqlite3GetVdbe(pParse);
sqlite3CodeVerifySchema(pParse, iDbSrc);
iSrc = pParse->nTab++;
iDest = pParse->nTab++;
regAutoinc = autoIncBegin(pParse, iDbDest, pDest);
+ regData = sqlite3GetTempReg(pParse);
+ regRowid = sqlite3GetTempReg(pParse);
sqlite3OpenTable(pParse, iDest, iDbDest, pDest, OP_OpenWrite);
- if( (pDest->iPKey<0 && pDest->pIndex!=0) /* (1) */
+ assert( HasRowid(pDest) || destHasUniqueIdx );
+ if( (db->flags & SQLITE_Vacuum)==0 && (
+ (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:
+ ** only if the destination table is initially empty. Unless the
+ ** SQLITE_Vacuum flag is set, this block generates code to make
+ ** that determination. If SQLITE_Vacuum is set, then the destination
+ ** table is always empty.
+ **
+ ** 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
@@ -90447,60 +104754,91 @@ static int xferOptimization(
**
** (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);
+ addr1 = sqlite3VdbeAddOp2(v, OP_Rewind, iDest, 0); VdbeCoverage(v);
+ emptyDestTest = sqlite3VdbeAddOp0(v, OP_Goto);
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);
+ if( HasRowid(pSrc) ){
+ sqlite3OpenTable(pParse, iSrc, iDbSrc, pSrc, OP_OpenRead);
+ emptySrcTest = sqlite3VdbeAddOp2(v, OP_Rewind, iSrc, 0); VdbeCoverage(v);
+ if( pDest->iPKey>=0 ){
+ addr1 = sqlite3VdbeAddOp2(v, OP_Rowid, iSrc, regRowid);
+ addr2 = sqlite3VdbeAddOp3(v, OP_NotExists, iDest, 0, regRowid);
+ VdbeCoverage(v);
+ sqlite3RowidConstraint(pParse, onError, pDest);
+ 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); VdbeCoverage(v);
+ sqlite3VdbeAddOp2(v, OP_Close, iSrc, 0);
+ sqlite3VdbeAddOp2(v, OP_Close, iDest, 0);
}else{
- addr1 = sqlite3VdbeAddOp2(v, OP_Rowid, iSrc, regRowid);
- assert( (pDest->tabFlags & TF_Autoincrement)==0 );
+ sqlite3TableLock(pParse, iDbDest, pDest->tnum, 1, pDest->zName);
+ sqlite3TableLock(pParse, iDbSrc, pSrc->tnum, 0, pSrc->zName);
}
- 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){
+ u8 idxInsFlags = 0;
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);
+ sqlite3VdbeAddOp3(v, OP_OpenRead, iSrc, pSrcIdx->tnum, iDbSrc);
+ sqlite3VdbeSetP4KeyInfo(pParse, pSrcIdx);
VdbeComment((v, "%s", pSrcIdx->zName));
- pKey = sqlite3IndexKeyinfo(pParse, pDestIdx);
- sqlite3VdbeAddOp4(v, OP_OpenWrite, iDest, pDestIdx->tnum, iDbDest,
- (char*)pKey, P4_KEYINFO_HANDOFF);
+ sqlite3VdbeAddOp3(v, OP_OpenWrite, iDest, pDestIdx->tnum, iDbDest);
+ sqlite3VdbeSetP4KeyInfo(pParse, pDestIdx);
+ sqlite3VdbeChangeP5(v, OPFLAG_BULKCSR);
VdbeComment((v, "%s", pDestIdx->zName));
- addr1 = sqlite3VdbeAddOp2(v, OP_Rewind, iSrc, 0);
+ addr1 = sqlite3VdbeAddOp2(v, OP_Rewind, iSrc, 0); VdbeCoverage(v);
sqlite3VdbeAddOp2(v, OP_RowKey, iSrc, regData);
+ if( db->flags & SQLITE_Vacuum ){
+ /* This INSERT command is part of a VACUUM operation, which guarantees
+ ** that the destination table is empty. If all indexed columns use
+ ** collation sequence BINARY, then it can also be assumed that the
+ ** index will be populated by inserting keys in strictly sorted
+ ** order. In this case, instead of seeking within the b-tree as part
+ ** of every OP_IdxInsert opcode, an OP_Last is added before the
+ ** OP_IdxInsert to seek to the point within the b-tree where each key
+ ** should be inserted. This is faster.
+ **
+ ** If any of the indexed columns use a collation sequence other than
+ ** BINARY, this optimization is disabled. This is because the user
+ ** might change the definition of a collation sequence and then run
+ ** a VACUUM command. In that case keys may not be written in strictly
+ ** sorted order. */
+ for(i=0; i<pSrcIdx->nColumn; i++){
+ const char *zColl = pSrcIdx->azColl[i];
+ assert( sqlite3_stricmp(sqlite3StrBINARY, zColl)!=0
+ || sqlite3StrBINARY==zColl );
+ if( sqlite3_stricmp(sqlite3StrBINARY, zColl) ) break;
+ }
+ if( i==pSrcIdx->nColumn ){
+ idxInsFlags = OPFLAG_USESEEKRESULT;
+ sqlite3VdbeAddOp3(v, OP_Last, iDest, 0, -1);
+ }
+ }
+ if( !HasRowid(pSrc) && pDestIdx->idxType==2 ){
+ idxInsFlags |= OPFLAG_NCHANGE;
+ }
sqlite3VdbeAddOp3(v, OP_IdxInsert, iDest, regData, 1);
- sqlite3VdbeAddOp2(v, OP_Next, iSrc, addr1+1);
+ sqlite3VdbeChangeP5(v, idxInsFlags);
+ sqlite3VdbeAddOp2(v, OP_Next, iSrc, addr1+1); VdbeCoverage(v);
sqlite3VdbeJumpHere(v, addr1);
+ sqlite3VdbeAddOp2(v, OP_Close, iSrc, 0);
+ sqlite3VdbeAddOp2(v, OP_Close, iDest, 0);
}
- sqlite3VdbeJumpHere(v, emptySrcTest);
+ if( emptySrcTest ) 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);
@@ -90531,6 +104869,7 @@ static int xferOptimization(
** accessed by users of the library.
*/
+/* #include "sqliteInt.h" */
/*
** Execute SQL code. Return one of the SQLITE_ success/failure
@@ -90542,7 +104881,7 @@ static int xferOptimization(
** argument to xCallback(). If xCallback=NULL then no callback
** is invoked, even for queries.
*/
-SQLITE_API int sqlite3_exec(
+SQLITE_API int SQLITE_STDCALL 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 */
@@ -90553,20 +104892,19 @@ SQLITE_API int sqlite3_exec(
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] ){
+ sqlite3Error(db, SQLITE_OK);
+ while( rc==SQLITE_OK && zSql[0] ){
int nCol;
char **azVals = 0;
pStmt = 0;
- rc = sqlite3_prepare(db, zSql, -1, &pStmt, &zLeftover);
+ rc = sqlite3_prepare_v2(db, zSql, -1, &pStmt, &zLeftover);
assert( rc==SQLITE_OK || pStmt==0 );
if( rc!=SQLITE_OK ){
continue;
@@ -90612,10 +104950,13 @@ SQLITE_API int sqlite3_exec(
}
}
if( xCallback(pArg, nCol, azVals, azCols) ){
+ /* EVIDENCE-OF: R-38229-40159 If the callback function to
+ ** sqlite3_exec() returns non-zero, then sqlite3_exec() will
+ ** return SQLITE_ABORT. */
rc = SQLITE_ABORT;
sqlite3VdbeFinalize((Vdbe *)pStmt);
pStmt = 0;
- sqlite3Error(db, SQLITE_ABORT, 0);
+ sqlite3Error(db, SQLITE_ABORT);
goto exec_out;
}
}
@@ -90623,11 +104964,8 @@ SQLITE_API int sqlite3_exec(
if( rc!=SQLITE_ROW ){
rc = sqlite3VdbeFinalize((Vdbe *)pStmt);
pStmt = 0;
- if( rc!=SQLITE_SCHEMA ){
- nRetry = 0;
- zSql = zLeftover;
- while( sqlite3Isspace(zSql[0]) ) zSql++;
- }
+ zSql = zLeftover;
+ while( sqlite3Isspace(zSql[0]) ) zSql++;
break;
}
}
@@ -90641,14 +104979,14 @@ exec_out:
sqlite3DbFree(db, azCols);
rc = sqlite3ApiExit(db, rc);
- if( rc!=SQLITE_OK && ALWAYS(rc==sqlite3_errcode(db)) && pzErrMsg ){
+ if( rc!=SQLITE_OK && 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);
+ sqlite3Error(db, SQLITE_NOMEM);
}
}else if( pzErrMsg ){
*pzErrMsg = 0;
@@ -90700,6 +105038,7 @@ exec_out:
*/
#ifndef _SQLITE3EXT_H_
#define _SQLITE3EXT_H_
+/* #include "sqlite3.h" */
typedef struct sqlite3_api_routines sqlite3_api_routines;
@@ -90710,7 +105049,7 @@ typedef struct sqlite3_api_routines sqlite3_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
+** versions of SQLite will not be able to load each other's shared
** libraries!
*/
struct sqlite3_api_routines {
@@ -90918,11 +105257,54 @@ struct sqlite3_api_routines {
int (*blob_reopen)(sqlite3_blob*,sqlite3_int64);
int (*vtab_config)(sqlite3*,int op,...);
int (*vtab_on_conflict)(sqlite3*);
+ /* Version 3.7.16 and later */
+ int (*close_v2)(sqlite3*);
+ const char *(*db_filename)(sqlite3*,const char*);
+ int (*db_readonly)(sqlite3*,const char*);
+ int (*db_release_memory)(sqlite3*);
+ const char *(*errstr)(int);
+ int (*stmt_busy)(sqlite3_stmt*);
+ int (*stmt_readonly)(sqlite3_stmt*);
+ int (*stricmp)(const char*,const char*);
+ int (*uri_boolean)(const char*,const char*,int);
+ sqlite3_int64 (*uri_int64)(const char*,const char*,sqlite3_int64);
+ const char *(*uri_parameter)(const char*,const char*);
+ char *(*vsnprintf)(int,char*,const char*,va_list);
+ int (*wal_checkpoint_v2)(sqlite3*,const char*,int,int*,int*);
+ /* Version 3.8.7 and later */
+ int (*auto_extension)(void(*)(void));
+ int (*bind_blob64)(sqlite3_stmt*,int,const void*,sqlite3_uint64,
+ void(*)(void*));
+ int (*bind_text64)(sqlite3_stmt*,int,const char*,sqlite3_uint64,
+ void(*)(void*),unsigned char);
+ int (*cancel_auto_extension)(void(*)(void));
+ int (*load_extension)(sqlite3*,const char*,const char*,char**);
+ void *(*malloc64)(sqlite3_uint64);
+ sqlite3_uint64 (*msize)(void*);
+ void *(*realloc64)(void*,sqlite3_uint64);
+ void (*reset_auto_extension)(void);
+ void (*result_blob64)(sqlite3_context*,const void*,sqlite3_uint64,
+ void(*)(void*));
+ void (*result_text64)(sqlite3_context*,const char*,sqlite3_uint64,
+ void(*)(void*), unsigned char);
+ int (*strglob)(const char*,const char*);
+ /* Version 3.8.11 and later */
+ sqlite3_value *(*value_dup)(const sqlite3_value*);
+ void (*value_free)(sqlite3_value*);
+ int (*result_zeroblob64)(sqlite3_context*,sqlite3_uint64);
+ int (*bind_zeroblob64)(sqlite3_stmt*, int, sqlite3_uint64);
+ /* Version 3.9.0 and later */
+ unsigned int (*value_subtype)(sqlite3_value*);
+ void (*result_subtype)(sqlite3_context*,unsigned int);
+ /* Version 3.10.0 and later */
+ int (*status64)(int,sqlite3_int64*,sqlite3_int64*,int);
+ int (*strlike)(const char*,const char*,unsigned int);
+ int (*db_cacheflush)(sqlite3*);
};
/*
** The following macros redefine the API routines so that they are
-** redirected throught the global sqlite3_api structure.
+** redirected through 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
@@ -90931,7 +105313,7 @@ struct sqlite3_api_routines {
** the API. So the redefinition macros are only valid if the
** SQLITE_CORE macros is undefined.
*/
-#ifndef SQLITE_CORE
+#if !defined(SQLITE_CORE) && !defined(SQLITE_OMIT_LOAD_EXTENSION)
#define sqlite3_aggregate_context sqlite3_api->aggregate_context
#ifndef SQLITE_OMIT_DEPRECATED
#define sqlite3_aggregate_count sqlite3_api->aggregate_count
@@ -91058,6 +105440,7 @@ struct sqlite3_api_routines {
#define sqlite3_value_text16le sqlite3_api->value_text16le
#define sqlite3_value_type sqlite3_api->value_type
#define sqlite3_vmprintf sqlite3_api->vmprintf
+#define sqlite3_vsnprintf sqlite3_api->vsnprintf
#define sqlite3_overload_function sqlite3_api->overload_function
#define sqlite3_prepare_v2 sqlite3_api->prepare_v2
#define sqlite3_prepare16_v2 sqlite3_api->prepare16_v2
@@ -91121,15 +105504,67 @@ struct sqlite3_api_routines {
#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;
+/* Version 3.7.16 and later */
+#define sqlite3_close_v2 sqlite3_api->close_v2
+#define sqlite3_db_filename sqlite3_api->db_filename
+#define sqlite3_db_readonly sqlite3_api->db_readonly
+#define sqlite3_db_release_memory sqlite3_api->db_release_memory
+#define sqlite3_errstr sqlite3_api->errstr
+#define sqlite3_stmt_busy sqlite3_api->stmt_busy
+#define sqlite3_stmt_readonly sqlite3_api->stmt_readonly
+#define sqlite3_stricmp sqlite3_api->stricmp
+#define sqlite3_uri_boolean sqlite3_api->uri_boolean
+#define sqlite3_uri_int64 sqlite3_api->uri_int64
+#define sqlite3_uri_parameter sqlite3_api->uri_parameter
+#define sqlite3_uri_vsnprintf sqlite3_api->vsnprintf
+#define sqlite3_wal_checkpoint_v2 sqlite3_api->wal_checkpoint_v2
+/* Version 3.8.7 and later */
+#define sqlite3_auto_extension sqlite3_api->auto_extension
+#define sqlite3_bind_blob64 sqlite3_api->bind_blob64
+#define sqlite3_bind_text64 sqlite3_api->bind_text64
+#define sqlite3_cancel_auto_extension sqlite3_api->cancel_auto_extension
+#define sqlite3_load_extension sqlite3_api->load_extension
+#define sqlite3_malloc64 sqlite3_api->malloc64
+#define sqlite3_msize sqlite3_api->msize
+#define sqlite3_realloc64 sqlite3_api->realloc64
+#define sqlite3_reset_auto_extension sqlite3_api->reset_auto_extension
+#define sqlite3_result_blob64 sqlite3_api->result_blob64
+#define sqlite3_result_text64 sqlite3_api->result_text64
+#define sqlite3_strglob sqlite3_api->strglob
+/* Version 3.8.11 and later */
+#define sqlite3_value_dup sqlite3_api->value_dup
+#define sqlite3_value_free sqlite3_api->value_free
+#define sqlite3_result_zeroblob64 sqlite3_api->result_zeroblob64
+#define sqlite3_bind_zeroblob64 sqlite3_api->bind_zeroblob64
+/* Version 3.9.0 and later */
+#define sqlite3_value_subtype sqlite3_api->value_subtype
+#define sqlite3_result_subtype sqlite3_api->result_subtype
+/* Version 3.10.0 and later */
+#define sqlite3_status64 sqlite3_api->status64
+#define sqlite3_strlike sqlite3_api->strlike
+#define sqlite3_db_cacheflush sqlite3_api->db_cacheflush
+#endif /* !defined(SQLITE_CORE) && !defined(SQLITE_OMIT_LOAD_EXTENSION) */
+
+#if !defined(SQLITE_CORE) && !defined(SQLITE_OMIT_LOAD_EXTENSION)
+ /* This case when the file really is being compiled as a loadable
+ ** extension */
+# define SQLITE_EXTENSION_INIT1 const sqlite3_api_routines *sqlite3_api=0;
+# define SQLITE_EXTENSION_INIT2(v) sqlite3_api=v;
+# define SQLITE_EXTENSION_INIT3 \
+ extern const sqlite3_api_routines *sqlite3_api;
+#else
+ /* This case when the file is being statically linked into the
+ ** application */
+# define SQLITE_EXTENSION_INIT1 /*no-op*/
+# define SQLITE_EXTENSION_INIT2(v) (void)v; /* unused parameter */
+# define SQLITE_EXTENSION_INIT3 /*no-op*/
+#endif
#endif /* _SQLITE3EXT_H_ */
/************** End of sqlite3ext.h ******************************************/
/************** Continuing where we left off in loadext.c ********************/
+/* #include "sqliteInt.h" */
/* #include <string.h> */
#ifndef SQLITE_OMIT_LOAD_EXTENSION
@@ -91146,7 +105581,6 @@ struct sqlite3_api_routines {
# 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
@@ -91490,6 +105924,44 @@ static const sqlite3_api_routines sqlite3Apis = {
sqlite3_blob_reopen,
sqlite3_vtab_config,
sqlite3_vtab_on_conflict,
+ sqlite3_close_v2,
+ sqlite3_db_filename,
+ sqlite3_db_readonly,
+ sqlite3_db_release_memory,
+ sqlite3_errstr,
+ sqlite3_stmt_busy,
+ sqlite3_stmt_readonly,
+ sqlite3_stricmp,
+ sqlite3_uri_boolean,
+ sqlite3_uri_int64,
+ sqlite3_uri_parameter,
+ sqlite3_vsnprintf,
+ sqlite3_wal_checkpoint_v2,
+ /* Version 3.8.7 and later */
+ sqlite3_auto_extension,
+ sqlite3_bind_blob64,
+ sqlite3_bind_text64,
+ sqlite3_cancel_auto_extension,
+ sqlite3_load_extension,
+ sqlite3_malloc64,
+ sqlite3_msize,
+ sqlite3_realloc64,
+ sqlite3_reset_auto_extension,
+ sqlite3_result_blob64,
+ sqlite3_result_text64,
+ sqlite3_strglob,
+ /* Version 3.8.11 and later */
+ (sqlite3_value*(*)(const sqlite3_value*))sqlite3_value_dup,
+ sqlite3_value_free,
+ sqlite3_result_zeroblob64,
+ sqlite3_bind_zeroblob64,
+ /* Version 3.9.0 and later */
+ sqlite3_value_subtype,
+ sqlite3_result_subtype,
+ /* Version 3.10.0 and later */
+ sqlite3_status64,
+ sqlite3_strlike,
+ sqlite3_db_cacheflush
};
/*
@@ -91514,8 +105986,23 @@ static int sqlite3LoadExtension(
void *handle;
int (*xInit)(sqlite3*,char**,const sqlite3_api_routines*);
char *zErrmsg = 0;
+ const char *zEntry;
+ char *zAltEntry = 0;
void **aHandle;
- int nMsg = 300 + sqlite3Strlen30(zFile);
+ u64 nMsg = 300 + sqlite3Strlen30(zFile);
+ int ii;
+
+ /* Shared library endings to try if zFile cannot be loaded as written */
+ static const char *azEndings[] = {
+#if SQLITE_OS_WIN
+ "dll"
+#elif defined(__APPLE__)
+ "dylib"
+#else
+ "so"
+#endif
+ };
+
if( pzErrMsg ) *pzErrMsg = 0;
@@ -91532,14 +106019,20 @@ static int sqlite3LoadExtension(
return SQLITE_ERROR;
}
- if( zProc==0 ){
- zProc = "sqlite3_extension_init";
- }
+ zEntry = zProc ? zProc : "sqlite3_extension_init";
handle = sqlite3OsDlOpen(pVfs, zFile);
+#if SQLITE_OS_UNIX || SQLITE_OS_WIN
+ for(ii=0; ii<ArraySize(azEndings) && handle==0; ii++){
+ char *zAltFile = sqlite3_mprintf("%s.%s", zFile, azEndings[ii]);
+ if( zAltFile==0 ) return SQLITE_NOMEM;
+ handle = sqlite3OsDlOpen(pVfs, zAltFile);
+ sqlite3_free(zAltFile);
+ }
+#endif
if( handle==0 ){
if( pzErrMsg ){
- *pzErrMsg = zErrmsg = sqlite3_malloc(nMsg);
+ *pzErrMsg = zErrmsg = sqlite3_malloc64(nMsg);
if( zErrmsg ){
sqlite3_snprintf(nMsg, zErrmsg,
"unable to open shared library [%s]", zFile);
@@ -91549,20 +106042,57 @@ static int sqlite3LoadExtension(
return SQLITE_ERROR;
}
xInit = (int(*)(sqlite3*,char**,const sqlite3_api_routines*))
- sqlite3OsDlSym(pVfs, handle, zProc);
+ sqlite3OsDlSym(pVfs, handle, zEntry);
+
+ /* If no entry point was specified and the default legacy
+ ** entry point name "sqlite3_extension_init" was not found, then
+ ** construct an entry point name "sqlite3_X_init" where the X is
+ ** replaced by the lowercase value of every ASCII alphabetic
+ ** character in the filename after the last "/" upto the first ".",
+ ** and eliding the first three characters if they are "lib".
+ ** Examples:
+ **
+ ** /usr/local/lib/libExample5.4.3.so ==> sqlite3_example_init
+ ** C:/lib/mathfuncs.dll ==> sqlite3_mathfuncs_init
+ */
+ if( xInit==0 && zProc==0 ){
+ int iFile, iEntry, c;
+ int ncFile = sqlite3Strlen30(zFile);
+ zAltEntry = sqlite3_malloc64(ncFile+30);
+ if( zAltEntry==0 ){
+ sqlite3OsDlClose(pVfs, handle);
+ return SQLITE_NOMEM;
+ }
+ memcpy(zAltEntry, "sqlite3_", 8);
+ for(iFile=ncFile-1; iFile>=0 && zFile[iFile]!='/'; iFile--){}
+ iFile++;
+ if( sqlite3_strnicmp(zFile+iFile, "lib", 3)==0 ) iFile += 3;
+ for(iEntry=8; (c = zFile[iFile])!=0 && c!='.'; iFile++){
+ if( sqlite3Isalpha(c) ){
+ zAltEntry[iEntry++] = (char)sqlite3UpperToLower[(unsigned)c];
+ }
+ }
+ memcpy(zAltEntry+iEntry, "_init", 6);
+ zEntry = zAltEntry;
+ xInit = (int(*)(sqlite3*,char**,const sqlite3_api_routines*))
+ sqlite3OsDlSym(pVfs, handle, zEntry);
+ }
if( xInit==0 ){
if( pzErrMsg ){
- nMsg += sqlite3Strlen30(zProc);
- *pzErrMsg = zErrmsg = sqlite3_malloc(nMsg);
+ nMsg += sqlite3Strlen30(zEntry);
+ *pzErrMsg = zErrmsg = sqlite3_malloc64(nMsg);
if( zErrmsg ){
sqlite3_snprintf(nMsg, zErrmsg,
- "no entry point [%s] in shared library [%s]", zProc,zFile);
+ "no entry point [%s] in shared library [%s]", zEntry, zFile);
sqlite3OsDlError(pVfs, nMsg-1, zErrmsg);
}
- sqlite3OsDlClose(pVfs, handle);
}
+ sqlite3OsDlClose(pVfs, handle);
+ sqlite3_free(zAltEntry);
return SQLITE_ERROR;
- }else if( xInit(db, &zErrmsg, &sqlite3Apis) ){
+ }
+ sqlite3_free(zAltEntry);
+ if( xInit(db, &zErrmsg, &sqlite3Apis) ){
if( pzErrMsg ){
*pzErrMsg = sqlite3_mprintf("error during initialization: %s", zErrmsg);
}
@@ -91585,7 +106115,7 @@ static int sqlite3LoadExtension(
db->aExtension[db->nExtension++] = handle;
return SQLITE_OK;
}
-SQLITE_API int sqlite3_load_extension(
+SQLITE_API int SQLITE_STDCALL 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 */
@@ -91616,7 +106146,7 @@ SQLITE_PRIVATE void sqlite3CloseExtensions(sqlite3 *db){
** 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){
+SQLITE_API int SQLITE_STDCALL sqlite3_enable_load_extension(sqlite3 *db, int onoff){
sqlite3_mutex_enter(db->mutex);
if( onoff ){
db->flags |= SQLITE_LoadExtension;
@@ -91649,7 +106179,7 @@ static const sqlite3_api_routines sqlite3Apis = { 0 };
*/
typedef struct sqlite3AutoExtList sqlite3AutoExtList;
static SQLITE_WSD struct sqlite3AutoExtList {
- int nExt; /* Number of entries in aExt[] */
+ u32 nExt; /* Number of entries in aExt[] */
void (**aExt)(void); /* Pointers to the extension init functions */
} sqlite3Autoext = { 0, 0 };
@@ -91673,7 +106203,7 @@ static SQLITE_WSD struct sqlite3AutoExtList {
** Register a statically linked extension that is automatically
** loaded by every new database connection.
*/
-SQLITE_API int sqlite3_auto_extension(void (*xInit)(void)){
+SQLITE_API int SQLITE_STDCALL sqlite3_auto_extension(void (*xInit)(void)){
int rc = SQLITE_OK;
#ifndef SQLITE_OMIT_AUTOINIT
rc = sqlite3_initialize();
@@ -91682,7 +106212,7 @@ SQLITE_API int sqlite3_auto_extension(void (*xInit)(void)){
}else
#endif
{
- int i;
+ u32 i;
#if SQLITE_THREADSAFE
sqlite3_mutex *mutex = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER);
#endif
@@ -91692,9 +106222,9 @@ SQLITE_API int sqlite3_auto_extension(void (*xInit)(void)){
if( wsdAutoext.aExt[i]==xInit ) break;
}
if( i==wsdAutoext.nExt ){
- int nByte = (wsdAutoext.nExt+1)*sizeof(wsdAutoext.aExt[0]);
+ u64 nByte = (wsdAutoext.nExt+1)*sizeof(wsdAutoext.aExt[0]);
void (**aNew)(void);
- aNew = sqlite3_realloc(wsdAutoext.aExt, nByte);
+ aNew = sqlite3_realloc64(wsdAutoext.aExt, nByte);
if( aNew==0 ){
rc = SQLITE_NOMEM;
}else{
@@ -91710,9 +106240,38 @@ SQLITE_API int sqlite3_auto_extension(void (*xInit)(void)){
}
/*
+** Cancel a prior call to sqlite3_auto_extension. Remove xInit from the
+** set of routines that is invoked for each new database connection, if it
+** is currently on the list. If xInit is not on the list, then this
+** routine is a no-op.
+**
+** Return 1 if xInit was found on the list and removed. Return 0 if xInit
+** was not on the list.
+*/
+SQLITE_API int SQLITE_STDCALL sqlite3_cancel_auto_extension(void (*xInit)(void)){
+#if SQLITE_THREADSAFE
+ sqlite3_mutex *mutex = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER);
+#endif
+ int i;
+ int n = 0;
+ wsdAutoextInit;
+ sqlite3_mutex_enter(mutex);
+ for(i=(int)wsdAutoext.nExt-1; i>=0; i--){
+ if( wsdAutoext.aExt[i]==xInit ){
+ wsdAutoext.nExt--;
+ wsdAutoext.aExt[i] = wsdAutoext.aExt[wsdAutoext.nExt];
+ n++;
+ break;
+ }
+ }
+ sqlite3_mutex_leave(mutex);
+ return n;
+}
+
+/*
** Reset the automatic extension loading mechanism.
*/
-SQLITE_API void sqlite3_reset_auto_extension(void){
+SQLITE_API void SQLITE_STDCALL sqlite3_reset_auto_extension(void){
#ifndef SQLITE_OMIT_AUTOINIT
if( sqlite3_initialize()==SQLITE_OK )
#endif
@@ -91735,7 +106294,7 @@ SQLITE_API void sqlite3_reset_auto_extension(void){
** If anything goes wrong, set an error in the database connection.
*/
SQLITE_PRIVATE void sqlite3AutoLoadExtensions(sqlite3 *db){
- int i;
+ u32 i;
int go = 1;
int rc;
int (*xInit)(sqlite3*,char**,const sqlite3_api_routines*);
@@ -91761,7 +106320,7 @@ SQLITE_PRIVATE void sqlite3AutoLoadExtensions(sqlite3 *db){
sqlite3_mutex_leave(mutex);
zErrmsg = 0;
if( xInit && (rc = xInit(db, &zErrmsg, &sqlite3Apis))!=0 ){
- sqlite3Error(db, rc,
+ sqlite3ErrorWithMsg(db, rc,
"automatic extension loading failed: %s", zErrmsg);
go = 0;
}
@@ -91784,6 +106343,492 @@ SQLITE_PRIVATE void sqlite3AutoLoadExtensions(sqlite3 *db){
*************************************************************************
** This file contains code used to implement the PRAGMA command.
*/
+/* #include "sqliteInt.h" */
+
+#if !defined(SQLITE_ENABLE_LOCKING_STYLE)
+# if defined(__APPLE__)
+# define SQLITE_ENABLE_LOCKING_STYLE 1
+# else
+# define SQLITE_ENABLE_LOCKING_STYLE 0
+# endif
+#endif
+
+/***************************************************************************
+** The "pragma.h" include file is an automatically generated file that
+** that includes the PragType_XXXX macro definitions and the aPragmaName[]
+** object. This ensures that the aPragmaName[] table is arranged in
+** lexicographical order to facility a binary search of the pragma name.
+** Do not edit pragma.h directly. Edit and rerun the script in at
+** ../tool/mkpragmatab.tcl. */
+/************** Include pragma.h in the middle of pragma.c *******************/
+/************** Begin file pragma.h ******************************************/
+/* DO NOT EDIT!
+** This file is automatically generated by the script at
+** ../tool/mkpragmatab.tcl. To update the set of pragmas, edit
+** that script and rerun it.
+*/
+#define PragTyp_HEADER_VALUE 0
+#define PragTyp_AUTO_VACUUM 1
+#define PragTyp_FLAG 2
+#define PragTyp_BUSY_TIMEOUT 3
+#define PragTyp_CACHE_SIZE 4
+#define PragTyp_CACHE_SPILL 5
+#define PragTyp_CASE_SENSITIVE_LIKE 6
+#define PragTyp_COLLATION_LIST 7
+#define PragTyp_COMPILE_OPTIONS 8
+#define PragTyp_DATA_STORE_DIRECTORY 9
+#define PragTyp_DATABASE_LIST 10
+#define PragTyp_DEFAULT_CACHE_SIZE 11
+#define PragTyp_ENCODING 12
+#define PragTyp_FOREIGN_KEY_CHECK 13
+#define PragTyp_FOREIGN_KEY_LIST 14
+#define PragTyp_INCREMENTAL_VACUUM 15
+#define PragTyp_INDEX_INFO 16
+#define PragTyp_INDEX_LIST 17
+#define PragTyp_INTEGRITY_CHECK 18
+#define PragTyp_JOURNAL_MODE 19
+#define PragTyp_JOURNAL_SIZE_LIMIT 20
+#define PragTyp_LOCK_PROXY_FILE 21
+#define PragTyp_LOCKING_MODE 22
+#define PragTyp_PAGE_COUNT 23
+#define PragTyp_MMAP_SIZE 24
+#define PragTyp_PAGE_SIZE 25
+#define PragTyp_SECURE_DELETE 26
+#define PragTyp_SHRINK_MEMORY 27
+#define PragTyp_SOFT_HEAP_LIMIT 28
+#define PragTyp_STATS 29
+#define PragTyp_SYNCHRONOUS 30
+#define PragTyp_TABLE_INFO 31
+#define PragTyp_TEMP_STORE 32
+#define PragTyp_TEMP_STORE_DIRECTORY 33
+#define PragTyp_THREADS 34
+#define PragTyp_WAL_AUTOCHECKPOINT 35
+#define PragTyp_WAL_CHECKPOINT 36
+#define PragTyp_ACTIVATE_EXTENSIONS 37
+#define PragTyp_HEXKEY 38
+#define PragTyp_KEY 39
+#define PragTyp_REKEY 40
+#define PragTyp_LOCK_STATUS 41
+#define PragTyp_PARSER_TRACE 42
+#define PragFlag_NeedSchema 0x01
+#define PragFlag_ReadOnly 0x02
+static const struct sPragmaNames {
+ const char *const zName; /* Name of pragma */
+ u8 ePragTyp; /* PragTyp_XXX value */
+ u8 mPragFlag; /* Zero or more PragFlag_XXX values */
+ u32 iArg; /* Extra argument */
+} aPragmaNames[] = {
+#if defined(SQLITE_HAS_CODEC) || defined(SQLITE_ENABLE_CEROD)
+ { /* zName: */ "activate_extensions",
+ /* ePragTyp: */ PragTyp_ACTIVATE_EXTENSIONS,
+ /* ePragFlag: */ 0,
+ /* iArg: */ 0 },
+#endif
+#if !defined(SQLITE_OMIT_SCHEMA_VERSION_PRAGMAS)
+ { /* zName: */ "application_id",
+ /* ePragTyp: */ PragTyp_HEADER_VALUE,
+ /* ePragFlag: */ 0,
+ /* iArg: */ BTREE_APPLICATION_ID },
+#endif
+#if !defined(SQLITE_OMIT_AUTOVACUUM)
+ { /* zName: */ "auto_vacuum",
+ /* ePragTyp: */ PragTyp_AUTO_VACUUM,
+ /* ePragFlag: */ PragFlag_NeedSchema,
+ /* iArg: */ 0 },
+#endif
+#if !defined(SQLITE_OMIT_FLAG_PRAGMAS)
+#if !defined(SQLITE_OMIT_AUTOMATIC_INDEX)
+ { /* zName: */ "automatic_index",
+ /* ePragTyp: */ PragTyp_FLAG,
+ /* ePragFlag: */ 0,
+ /* iArg: */ SQLITE_AutoIndex },
+#endif
+#endif
+ { /* zName: */ "busy_timeout",
+ /* ePragTyp: */ PragTyp_BUSY_TIMEOUT,
+ /* ePragFlag: */ 0,
+ /* iArg: */ 0 },
+#if !defined(SQLITE_OMIT_PAGER_PRAGMAS)
+ { /* zName: */ "cache_size",
+ /* ePragTyp: */ PragTyp_CACHE_SIZE,
+ /* ePragFlag: */ PragFlag_NeedSchema,
+ /* iArg: */ 0 },
+#endif
+#if !defined(SQLITE_OMIT_FLAG_PRAGMAS)
+ { /* zName: */ "cache_spill",
+ /* ePragTyp: */ PragTyp_CACHE_SPILL,
+ /* ePragFlag: */ 0,
+ /* iArg: */ 0 },
+#endif
+ { /* zName: */ "case_sensitive_like",
+ /* ePragTyp: */ PragTyp_CASE_SENSITIVE_LIKE,
+ /* ePragFlag: */ 0,
+ /* iArg: */ 0 },
+ { /* zName: */ "cell_size_check",
+ /* ePragTyp: */ PragTyp_FLAG,
+ /* ePragFlag: */ 0,
+ /* iArg: */ SQLITE_CellSizeCk },
+#if !defined(SQLITE_OMIT_FLAG_PRAGMAS)
+ { /* zName: */ "checkpoint_fullfsync",
+ /* ePragTyp: */ PragTyp_FLAG,
+ /* ePragFlag: */ 0,
+ /* iArg: */ SQLITE_CkptFullFSync },
+#endif
+#if !defined(SQLITE_OMIT_SCHEMA_PRAGMAS)
+ { /* zName: */ "collation_list",
+ /* ePragTyp: */ PragTyp_COLLATION_LIST,
+ /* ePragFlag: */ 0,
+ /* iArg: */ 0 },
+#endif
+#if !defined(SQLITE_OMIT_COMPILEOPTION_DIAGS)
+ { /* zName: */ "compile_options",
+ /* ePragTyp: */ PragTyp_COMPILE_OPTIONS,
+ /* ePragFlag: */ 0,
+ /* iArg: */ 0 },
+#endif
+#if !defined(SQLITE_OMIT_FLAG_PRAGMAS)
+ { /* zName: */ "count_changes",
+ /* ePragTyp: */ PragTyp_FLAG,
+ /* ePragFlag: */ 0,
+ /* iArg: */ SQLITE_CountRows },
+#endif
+#if !defined(SQLITE_OMIT_PAGER_PRAGMAS) && SQLITE_OS_WIN
+ { /* zName: */ "data_store_directory",
+ /* ePragTyp: */ PragTyp_DATA_STORE_DIRECTORY,
+ /* ePragFlag: */ 0,
+ /* iArg: */ 0 },
+#endif
+#if !defined(SQLITE_OMIT_SCHEMA_VERSION_PRAGMAS)
+ { /* zName: */ "data_version",
+ /* ePragTyp: */ PragTyp_HEADER_VALUE,
+ /* ePragFlag: */ PragFlag_ReadOnly,
+ /* iArg: */ BTREE_DATA_VERSION },
+#endif
+#if !defined(SQLITE_OMIT_SCHEMA_PRAGMAS)
+ { /* zName: */ "database_list",
+ /* ePragTyp: */ PragTyp_DATABASE_LIST,
+ /* ePragFlag: */ PragFlag_NeedSchema,
+ /* iArg: */ 0 },
+#endif
+#if !defined(SQLITE_OMIT_PAGER_PRAGMAS) && !defined(SQLITE_OMIT_DEPRECATED)
+ { /* zName: */ "default_cache_size",
+ /* ePragTyp: */ PragTyp_DEFAULT_CACHE_SIZE,
+ /* ePragFlag: */ PragFlag_NeedSchema,
+ /* iArg: */ 0 },
+#endif
+#if !defined(SQLITE_OMIT_FLAG_PRAGMAS)
+#if !defined(SQLITE_OMIT_FOREIGN_KEY) && !defined(SQLITE_OMIT_TRIGGER)
+ { /* zName: */ "defer_foreign_keys",
+ /* ePragTyp: */ PragTyp_FLAG,
+ /* ePragFlag: */ 0,
+ /* iArg: */ SQLITE_DeferFKs },
+#endif
+#endif
+#if !defined(SQLITE_OMIT_FLAG_PRAGMAS)
+ { /* zName: */ "empty_result_callbacks",
+ /* ePragTyp: */ PragTyp_FLAG,
+ /* ePragFlag: */ 0,
+ /* iArg: */ SQLITE_NullCallback },
+#endif
+#if !defined(SQLITE_OMIT_UTF16)
+ { /* zName: */ "encoding",
+ /* ePragTyp: */ PragTyp_ENCODING,
+ /* ePragFlag: */ 0,
+ /* iArg: */ 0 },
+#endif
+#if !defined(SQLITE_OMIT_FOREIGN_KEY) && !defined(SQLITE_OMIT_TRIGGER)
+ { /* zName: */ "foreign_key_check",
+ /* ePragTyp: */ PragTyp_FOREIGN_KEY_CHECK,
+ /* ePragFlag: */ PragFlag_NeedSchema,
+ /* iArg: */ 0 },
+#endif
+#if !defined(SQLITE_OMIT_FOREIGN_KEY)
+ { /* zName: */ "foreign_key_list",
+ /* ePragTyp: */ PragTyp_FOREIGN_KEY_LIST,
+ /* ePragFlag: */ PragFlag_NeedSchema,
+ /* iArg: */ 0 },
+#endif
+#if !defined(SQLITE_OMIT_FLAG_PRAGMAS)
+#if !defined(SQLITE_OMIT_FOREIGN_KEY) && !defined(SQLITE_OMIT_TRIGGER)
+ { /* zName: */ "foreign_keys",
+ /* ePragTyp: */ PragTyp_FLAG,
+ /* ePragFlag: */ 0,
+ /* iArg: */ SQLITE_ForeignKeys },
+#endif
+#endif
+#if !defined(SQLITE_OMIT_SCHEMA_VERSION_PRAGMAS)
+ { /* zName: */ "freelist_count",
+ /* ePragTyp: */ PragTyp_HEADER_VALUE,
+ /* ePragFlag: */ PragFlag_ReadOnly,
+ /* iArg: */ BTREE_FREE_PAGE_COUNT },
+#endif
+#if !defined(SQLITE_OMIT_FLAG_PRAGMAS)
+ { /* zName: */ "full_column_names",
+ /* ePragTyp: */ PragTyp_FLAG,
+ /* ePragFlag: */ 0,
+ /* iArg: */ SQLITE_FullColNames },
+ { /* zName: */ "fullfsync",
+ /* ePragTyp: */ PragTyp_FLAG,
+ /* ePragFlag: */ 0,
+ /* iArg: */ SQLITE_FullFSync },
+#endif
+#if defined(SQLITE_HAS_CODEC)
+ { /* zName: */ "hexkey",
+ /* ePragTyp: */ PragTyp_HEXKEY,
+ /* ePragFlag: */ 0,
+ /* iArg: */ 0 },
+ { /* zName: */ "hexrekey",
+ /* ePragTyp: */ PragTyp_HEXKEY,
+ /* ePragFlag: */ 0,
+ /* iArg: */ 0 },
+#endif
+#if !defined(SQLITE_OMIT_FLAG_PRAGMAS)
+#if !defined(SQLITE_OMIT_CHECK)
+ { /* zName: */ "ignore_check_constraints",
+ /* ePragTyp: */ PragTyp_FLAG,
+ /* ePragFlag: */ 0,
+ /* iArg: */ SQLITE_IgnoreChecks },
+#endif
+#endif
+#if !defined(SQLITE_OMIT_AUTOVACUUM)
+ { /* zName: */ "incremental_vacuum",
+ /* ePragTyp: */ PragTyp_INCREMENTAL_VACUUM,
+ /* ePragFlag: */ PragFlag_NeedSchema,
+ /* iArg: */ 0 },
+#endif
+#if !defined(SQLITE_OMIT_SCHEMA_PRAGMAS)
+ { /* zName: */ "index_info",
+ /* ePragTyp: */ PragTyp_INDEX_INFO,
+ /* ePragFlag: */ PragFlag_NeedSchema,
+ /* iArg: */ 0 },
+ { /* zName: */ "index_list",
+ /* ePragTyp: */ PragTyp_INDEX_LIST,
+ /* ePragFlag: */ PragFlag_NeedSchema,
+ /* iArg: */ 0 },
+ { /* zName: */ "index_xinfo",
+ /* ePragTyp: */ PragTyp_INDEX_INFO,
+ /* ePragFlag: */ PragFlag_NeedSchema,
+ /* iArg: */ 1 },
+#endif
+#if !defined(SQLITE_OMIT_INTEGRITY_CHECK)
+ { /* zName: */ "integrity_check",
+ /* ePragTyp: */ PragTyp_INTEGRITY_CHECK,
+ /* ePragFlag: */ PragFlag_NeedSchema,
+ /* iArg: */ 0 },
+#endif
+#if !defined(SQLITE_OMIT_PAGER_PRAGMAS)
+ { /* zName: */ "journal_mode",
+ /* ePragTyp: */ PragTyp_JOURNAL_MODE,
+ /* ePragFlag: */ PragFlag_NeedSchema,
+ /* iArg: */ 0 },
+ { /* zName: */ "journal_size_limit",
+ /* ePragTyp: */ PragTyp_JOURNAL_SIZE_LIMIT,
+ /* ePragFlag: */ 0,
+ /* iArg: */ 0 },
+#endif
+#if defined(SQLITE_HAS_CODEC)
+ { /* zName: */ "key",
+ /* ePragTyp: */ PragTyp_KEY,
+ /* ePragFlag: */ 0,
+ /* iArg: */ 0 },
+#endif
+#if !defined(SQLITE_OMIT_FLAG_PRAGMAS)
+ { /* zName: */ "legacy_file_format",
+ /* ePragTyp: */ PragTyp_FLAG,
+ /* ePragFlag: */ 0,
+ /* iArg: */ SQLITE_LegacyFileFmt },
+#endif
+#if !defined(SQLITE_OMIT_PAGER_PRAGMAS) && SQLITE_ENABLE_LOCKING_STYLE
+ { /* zName: */ "lock_proxy_file",
+ /* ePragTyp: */ PragTyp_LOCK_PROXY_FILE,
+ /* ePragFlag: */ 0,
+ /* iArg: */ 0 },
+#endif
+#if defined(SQLITE_DEBUG) || defined(SQLITE_TEST)
+ { /* zName: */ "lock_status",
+ /* ePragTyp: */ PragTyp_LOCK_STATUS,
+ /* ePragFlag: */ 0,
+ /* iArg: */ 0 },
+#endif
+#if !defined(SQLITE_OMIT_PAGER_PRAGMAS)
+ { /* zName: */ "locking_mode",
+ /* ePragTyp: */ PragTyp_LOCKING_MODE,
+ /* ePragFlag: */ 0,
+ /* iArg: */ 0 },
+ { /* zName: */ "max_page_count",
+ /* ePragTyp: */ PragTyp_PAGE_COUNT,
+ /* ePragFlag: */ PragFlag_NeedSchema,
+ /* iArg: */ 0 },
+ { /* zName: */ "mmap_size",
+ /* ePragTyp: */ PragTyp_MMAP_SIZE,
+ /* ePragFlag: */ 0,
+ /* iArg: */ 0 },
+ { /* zName: */ "page_count",
+ /* ePragTyp: */ PragTyp_PAGE_COUNT,
+ /* ePragFlag: */ PragFlag_NeedSchema,
+ /* iArg: */ 0 },
+ { /* zName: */ "page_size",
+ /* ePragTyp: */ PragTyp_PAGE_SIZE,
+ /* ePragFlag: */ 0,
+ /* iArg: */ 0 },
+#endif
+#if defined(SQLITE_DEBUG) && !defined(SQLITE_OMIT_PARSER_TRACE)
+ { /* zName: */ "parser_trace",
+ /* ePragTyp: */ PragTyp_PARSER_TRACE,
+ /* ePragFlag: */ 0,
+ /* iArg: */ 0 },
+#endif
+#if !defined(SQLITE_OMIT_FLAG_PRAGMAS)
+ { /* zName: */ "query_only",
+ /* ePragTyp: */ PragTyp_FLAG,
+ /* ePragFlag: */ 0,
+ /* iArg: */ SQLITE_QueryOnly },
+#endif
+#if !defined(SQLITE_OMIT_INTEGRITY_CHECK)
+ { /* zName: */ "quick_check",
+ /* ePragTyp: */ PragTyp_INTEGRITY_CHECK,
+ /* ePragFlag: */ PragFlag_NeedSchema,
+ /* iArg: */ 0 },
+#endif
+#if !defined(SQLITE_OMIT_FLAG_PRAGMAS)
+ { /* zName: */ "read_uncommitted",
+ /* ePragTyp: */ PragTyp_FLAG,
+ /* ePragFlag: */ 0,
+ /* iArg: */ SQLITE_ReadUncommitted },
+ { /* zName: */ "recursive_triggers",
+ /* ePragTyp: */ PragTyp_FLAG,
+ /* ePragFlag: */ 0,
+ /* iArg: */ SQLITE_RecTriggers },
+#endif
+#if defined(SQLITE_HAS_CODEC)
+ { /* zName: */ "rekey",
+ /* ePragTyp: */ PragTyp_REKEY,
+ /* ePragFlag: */ 0,
+ /* iArg: */ 0 },
+#endif
+#if !defined(SQLITE_OMIT_FLAG_PRAGMAS)
+ { /* zName: */ "reverse_unordered_selects",
+ /* ePragTyp: */ PragTyp_FLAG,
+ /* ePragFlag: */ 0,
+ /* iArg: */ SQLITE_ReverseOrder },
+#endif
+#if !defined(SQLITE_OMIT_SCHEMA_VERSION_PRAGMAS)
+ { /* zName: */ "schema_version",
+ /* ePragTyp: */ PragTyp_HEADER_VALUE,
+ /* ePragFlag: */ 0,
+ /* iArg: */ BTREE_SCHEMA_VERSION },
+#endif
+#if !defined(SQLITE_OMIT_PAGER_PRAGMAS)
+ { /* zName: */ "secure_delete",
+ /* ePragTyp: */ PragTyp_SECURE_DELETE,
+ /* ePragFlag: */ 0,
+ /* iArg: */ 0 },
+#endif
+#if !defined(SQLITE_OMIT_FLAG_PRAGMAS)
+ { /* zName: */ "short_column_names",
+ /* ePragTyp: */ PragTyp_FLAG,
+ /* ePragFlag: */ 0,
+ /* iArg: */ SQLITE_ShortColNames },
+#endif
+ { /* zName: */ "shrink_memory",
+ /* ePragTyp: */ PragTyp_SHRINK_MEMORY,
+ /* ePragFlag: */ 0,
+ /* iArg: */ 0 },
+ { /* zName: */ "soft_heap_limit",
+ /* ePragTyp: */ PragTyp_SOFT_HEAP_LIMIT,
+ /* ePragFlag: */ 0,
+ /* iArg: */ 0 },
+#if !defined(SQLITE_OMIT_FLAG_PRAGMAS)
+#if defined(SQLITE_DEBUG)
+ { /* zName: */ "sql_trace",
+ /* ePragTyp: */ PragTyp_FLAG,
+ /* ePragFlag: */ 0,
+ /* iArg: */ SQLITE_SqlTrace },
+#endif
+#endif
+#if !defined(SQLITE_OMIT_SCHEMA_PRAGMAS)
+ { /* zName: */ "stats",
+ /* ePragTyp: */ PragTyp_STATS,
+ /* ePragFlag: */ PragFlag_NeedSchema,
+ /* iArg: */ 0 },
+#endif
+#if !defined(SQLITE_OMIT_PAGER_PRAGMAS)
+ { /* zName: */ "synchronous",
+ /* ePragTyp: */ PragTyp_SYNCHRONOUS,
+ /* ePragFlag: */ PragFlag_NeedSchema,
+ /* iArg: */ 0 },
+#endif
+#if !defined(SQLITE_OMIT_SCHEMA_PRAGMAS)
+ { /* zName: */ "table_info",
+ /* ePragTyp: */ PragTyp_TABLE_INFO,
+ /* ePragFlag: */ PragFlag_NeedSchema,
+ /* iArg: */ 0 },
+#endif
+#if !defined(SQLITE_OMIT_PAGER_PRAGMAS)
+ { /* zName: */ "temp_store",
+ /* ePragTyp: */ PragTyp_TEMP_STORE,
+ /* ePragFlag: */ 0,
+ /* iArg: */ 0 },
+ { /* zName: */ "temp_store_directory",
+ /* ePragTyp: */ PragTyp_TEMP_STORE_DIRECTORY,
+ /* ePragFlag: */ 0,
+ /* iArg: */ 0 },
+#endif
+ { /* zName: */ "threads",
+ /* ePragTyp: */ PragTyp_THREADS,
+ /* ePragFlag: */ 0,
+ /* iArg: */ 0 },
+#if !defined(SQLITE_OMIT_SCHEMA_VERSION_PRAGMAS)
+ { /* zName: */ "user_version",
+ /* ePragTyp: */ PragTyp_HEADER_VALUE,
+ /* ePragFlag: */ 0,
+ /* iArg: */ BTREE_USER_VERSION },
+#endif
+#if !defined(SQLITE_OMIT_FLAG_PRAGMAS)
+#if defined(SQLITE_DEBUG)
+ { /* zName: */ "vdbe_addoptrace",
+ /* ePragTyp: */ PragTyp_FLAG,
+ /* ePragFlag: */ 0,
+ /* iArg: */ SQLITE_VdbeAddopTrace },
+ { /* zName: */ "vdbe_debug",
+ /* ePragTyp: */ PragTyp_FLAG,
+ /* ePragFlag: */ 0,
+ /* iArg: */ SQLITE_SqlTrace|SQLITE_VdbeListing|SQLITE_VdbeTrace },
+ { /* zName: */ "vdbe_eqp",
+ /* ePragTyp: */ PragTyp_FLAG,
+ /* ePragFlag: */ 0,
+ /* iArg: */ SQLITE_VdbeEQP },
+ { /* zName: */ "vdbe_listing",
+ /* ePragTyp: */ PragTyp_FLAG,
+ /* ePragFlag: */ 0,
+ /* iArg: */ SQLITE_VdbeListing },
+ { /* zName: */ "vdbe_trace",
+ /* ePragTyp: */ PragTyp_FLAG,
+ /* ePragFlag: */ 0,
+ /* iArg: */ SQLITE_VdbeTrace },
+#endif
+#endif
+#if !defined(SQLITE_OMIT_WAL)
+ { /* zName: */ "wal_autocheckpoint",
+ /* ePragTyp: */ PragTyp_WAL_AUTOCHECKPOINT,
+ /* ePragFlag: */ 0,
+ /* iArg: */ 0 },
+ { /* zName: */ "wal_checkpoint",
+ /* ePragTyp: */ PragTyp_WAL_CHECKPOINT,
+ /* ePragFlag: */ PragFlag_NeedSchema,
+ /* iArg: */ 0 },
+#endif
+#if !defined(SQLITE_OMIT_FLAG_PRAGMAS)
+ { /* zName: */ "writable_schema",
+ /* ePragTyp: */ PragTyp_FLAG,
+ /* ePragFlag: */ 0,
+ /* iArg: */ SQLITE_WriteSchema|SQLITE_RecoveryMode },
+#endif
+};
+/* Number of pragmas: 60 on by default, 73 total. */
+
+/************** End of pragma.h **********************************************/
+/************** Continuing where we left off in pragma.c *********************/
/*
** Interpret the given string as a safety level. Return 0 for OFF,
@@ -91796,7 +106841,7 @@ SQLITE_PRIVATE void sqlite3AutoLoadExtensions(sqlite3 *db){
** 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){
+static u8 getSafetyLevel(const char *z, int omitFull, u8 dflt){
/* 123456789 123456789 */
static const char zText[] = "onoffalseyestruefull";
static const u8 iOffset[] = {0, 1, 2, 4, 9, 12, 16};
@@ -91818,7 +106863,7 @@ static u8 getSafetyLevel(const char *z, int omitFull, int dflt){
/*
** Interpret the given string as a boolean value.
*/
-SQLITE_PRIVATE u8 sqlite3GetBoolean(const char *z, int dflt){
+SQLITE_PRIVATE u8 sqlite3GetBoolean(const char *z, u8 dflt){
return getSafetyLevel(z,1,dflt)!=0;
}
@@ -91915,104 +106960,76 @@ static int changeTempStorage(Parse *pParse, const char *zStorageType){
#endif /* SQLITE_PAGER_PRAGMAS */
/*
-** Generate code to return a single integer value.
+** Set the names of the first N columns to the values in azCol[]
*/
-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));
+static void setAllColumnNames(
+ Vdbe *v, /* The query under construction */
+ int N, /* Number of columns */
+ const char **azCol /* Names of columns */
+){
+ int i;
+ sqlite3VdbeSetNumCols(v, N);
+ for(i=0; i<N; i++){
+ sqlite3VdbeSetColName(v, i, COLNAME_NAME, azCol[i], SQLITE_STATIC);
}
- 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);
+}
+static void setOneColumnName(Vdbe *v, const char *z){
+ setAllColumnNames(v, 1, &z);
}
-#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 },
+** Generate code to return a single integer value.
+*/
+static void returnSingleInt(Vdbe *v, const char *zLabel, i64 value){
+ sqlite3VdbeAddOp4Dup8(v, OP_Int64, 0, 1, 0, (const u8*)&value, P4_INT64);
+ setOneColumnName(v, zLabel);
+ sqlite3VdbeAddOp2(v, OP_ResultRow, 1, 1);
+}
- /* 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);
- }
+/*
+** Generate code to return a single text value.
+*/
+static void returnSingleText(
+ Vdbe *v, /* Prepared statement under construction */
+ const char *zLabel, /* Name of the result column */
+ const char *zValue /* Value to be returned */
+){
+ if( zValue ){
+ sqlite3VdbeLoadString(v, 1, (const char*)zValue);
+ setOneColumnName(v, zLabel);
+ sqlite3VdbeAddOp2(v, OP_ResultRow, 1, 1);
+ }
+}
- 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);
- }
+/*
+** Set the safety_level and pager flags for pager iDb. Or if iDb<0
+** set these values for all pagers.
+*/
+#ifndef SQLITE_OMIT_PAGER_PRAGMAS
+static void setAllPagerFlags(sqlite3 *db){
+ if( db->autoCommit ){
+ Db *pDb = db->aDb;
+ int n = db->nDb;
+ assert( SQLITE_FullFSync==PAGER_FULLFSYNC );
+ assert( SQLITE_CkptFullFSync==PAGER_CKPT_FULLFSYNC );
+ assert( SQLITE_CacheSpill==PAGER_CACHESPILL );
+ assert( (PAGER_FULLFSYNC | PAGER_CKPT_FULLFSYNC | PAGER_CACHESPILL)
+ == PAGER_FLAGS_MASK );
+ assert( (pDb->safety_level & PAGER_SYNCHRONOUS_MASK)==pDb->safety_level );
+ while( (n--) > 0 ){
+ if( pDb->pBt ){
+ sqlite3BtreeSetPagerFlags(pDb->pBt,
+ pDb->safety_level | (db->flags & PAGER_FLAGS_MASK) );
}
-
- return 1;
+ pDb++;
}
}
- return 0;
}
-#endif /* SQLITE_OMIT_FLAG_PRAGMAS */
+#else
+# define setAllPagerFlags(X) /* no-op */
+#endif
+
/*
** Return a human-readable name for a constraint resolution action.
@@ -92062,7 +107079,7 @@ SQLITE_PRIVATE const char *sqlite3JournalModename(int eMode){
**
** Pragmas are of this form:
**
-** PRAGMA [database.]id [= value]
+** PRAGMA [schema.]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
@@ -92074,8 +107091,8 @@ SQLITE_PRIVATE const char *sqlite3JournalModename(int eMode){
*/
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 *pId1, /* First part of [schema.]id field */
+ Token *pId2, /* Second part of [schema.]id field, or NULL */
Token *pValue, /* Token for <value>, or NULL */
int minusFlag /* True if a '-' sign preceded <value> */
){
@@ -92083,18 +107100,20 @@ SQLITE_PRIVATE void sqlite3Pragma(
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 iDb; /* Database index for <database> */
+ int lwr, upr, mid = 0; /* Binary search bounds */
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 */
+ Vdbe *v = sqlite3GetVdbe(pParse); /* Prepared statement */
+ const struct sPragmaNames *pPragma;
if( v==0 ) return;
sqlite3VdbeRunOnlyOnce(v);
pParse->nMem = 2;
- /* Interpret the [database.] part of the pragma statement. iDb is the
+ /* Interpret the [schema.] 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;
@@ -92124,6 +107143,17 @@ SQLITE_PRIVATE void sqlite3Pragma(
/* 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.
+ **
+ ** IMPLEMENTATION-OF: R-12238-55120 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.
+ **
+ ** IMPLEMENTATION-OF: R-29875-31678 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.
*/
aFcntl[0] = 0;
aFcntl[1] = zLeft;
@@ -92132,28 +107162,48 @@ SQLITE_PRIVATE void sqlite3Pragma(
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 ){
+ returnSingleText(v, "result", aFcntl[0]);
+ sqlite3_free(aFcntl[0]);
+ goto pragma_out;
+ }
+ if( rc!=SQLITE_NOTFOUND ){
if( aFcntl[0] ){
sqlite3ErrorMsg(pParse, "%s", aFcntl[0]);
sqlite3_free(aFcntl[0]);
}
pParse->nErr++;
pParse->rc = rc;
- }else
-
-
+ goto pragma_out;
+ }
+
+ /* Locate the pragma in the lookup table */
+ lwr = 0;
+ upr = ArraySize(aPragmaNames)-1;
+ while( lwr<=upr ){
+ mid = (lwr+upr)/2;
+ rc = sqlite3_stricmp(zLeft, aPragmaNames[mid].zName);
+ if( rc==0 ) break;
+ if( rc<0 ){
+ upr = mid - 1;
+ }else{
+ lwr = mid + 1;
+ }
+ }
+ if( lwr>upr ) goto pragma_out;
+ pPragma = &aPragmaNames[mid];
+
+ /* Make sure the database schema is loaded if the pragma requires that */
+ if( (pPragma->mPragFlag & PragFlag_NeedSchema)!=0 ){
+ if( sqlite3ReadSchema(pParse) ) goto pragma_out;
+ }
+
+ /* Jump to the appropriate pragma handler */
+ switch( pPragma->ePragTyp ){
+
#if !defined(SQLITE_OMIT_PAGER_PRAGMAS) && !defined(SQLITE_OMIT_DEPRECATED)
/*
- ** PRAGMA [database.]default_cache_size
- ** PRAGMA [database.]default_cache_size=N
+ ** PRAGMA [schema.]default_cache_size
+ ** PRAGMA [schema.]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
@@ -92167,25 +107217,25 @@ SQLITE_PRIVATE void sqlite3Pragma(
** size. But continue to take the absolute value of the default cache
** size of historical compatibility.
*/
- if( sqlite3StrICmp(zLeft,"default_cache_size")==0 ){
+ case PragTyp_DEFAULT_CACHE_SIZE: {
+ static const int iLn = VDBE_OFFSET_LINENO(2);
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_IfPos, 1, 8, 0},
{ OP_Integer, 0, 2, 0},
{ OP_Subtract, 1, 2, 1},
- { OP_IfPos, 1, 7, 0},
+ { OP_IfPos, 1, 8, 0},
{ OP_Integer, 0, 1, 0}, /* 6 */
+ { OP_Noop, 0, 0, 0},
{ 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);
+ setOneColumnName(v, "cache_size");
pParse->nMem += 2;
- addr = sqlite3VdbeAddOpList(v, ArraySize(getCacheSize), getCacheSize);
+ addr = sqlite3VdbeAddOpList(v, ArraySize(getCacheSize), getCacheSize,iLn);
sqlite3VdbeChangeP1(v, addr, iDb);
sqlite3VdbeChangeP1(v, addr+1, iDb);
sqlite3VdbeChangeP1(v, addr+6, SQLITE_DEFAULT_CACHE_SIZE);
@@ -92198,25 +107248,26 @@ SQLITE_PRIVATE void sqlite3Pragma(
pDb->pSchema->cache_size = size;
sqlite3BtreeSetCacheSize(pDb->pBt, pDb->pSchema->cache_size);
}
- }else
+ break;
+ }
#endif /* !SQLITE_OMIT_PAGER_PRAGMAS && !SQLITE_OMIT_DEPRECATED */
#if !defined(SQLITE_OMIT_PAGER_PRAGMAS)
/*
- ** PRAGMA [database.]page_size
- ** PRAGMA [database.]page_size=N
+ ** PRAGMA [schema.]page_size
+ ** PRAGMA [schema.]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 ){
+ case PragTyp_PAGE_SIZE: {
Btree *pBt = pDb->pBt;
assert( pBt!=0 );
if( !zRight ){
int size = ALWAYS(pBt) ? sqlite3BtreeGetPageSize(pBt) : 0;
- returnSingleInt(pParse, "page_size", size);
+ returnSingleInt(v, "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().
@@ -92226,17 +107277,18 @@ SQLITE_PRIVATE void sqlite3Pragma(
db->mallocFailed = 1;
}
}
- }else
+ break;
+ }
/*
- ** PRAGMA [database.]secure_delete
- ** PRAGMA [database.]secure_delete=ON/OFF
+ ** PRAGMA [schema.]secure_delete
+ ** PRAGMA [schema.]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 ){
+ case PragTyp_SECURE_DELETE: {
Btree *pBt = pDb->pBt;
int b = -1;
assert( pBt!=0 );
@@ -92250,12 +107302,13 @@ SQLITE_PRIVATE void sqlite3Pragma(
}
}
b = sqlite3BtreeSecureDelete(pBt, b);
- returnSingleInt(pParse, "secure_delete", b);
- }else
+ returnSingleInt(v, "secure_delete", b);
+ break;
+ }
/*
- ** PRAGMA [database.]max_page_count
- ** PRAGMA [database.]max_page_count=N
+ ** PRAGMA [schema.]max_page_count
+ ** PRAGMA [schema.]max_page_count=N
**
** The first form reports the current setting for the
** maximum number of pages in the database file. The
@@ -92266,15 +107319,12 @@ SQLITE_PRIVATE void sqlite3Pragma(
** change. The only purpose is to provide an easy way to test
** the sqlite3AbsInt32() function.
**
- ** PRAGMA [database.]page_count
+ ** PRAGMA [schema.]page_count
**
** Return the number of pages in the specified database.
*/
- if( sqlite3StrICmp(zLeft,"page_count")==0
- || sqlite3StrICmp(zLeft,"max_page_count")==0
- ){
+ case PragTyp_PAGE_COUNT: {
int iReg;
- if( sqlite3ReadSchema(pParse) ) goto pragma_out;
sqlite3CodeVerifySchema(pParse, iDb);
iReg = ++pParse->nMem;
if( sqlite3Tolower(zLeft[0])=='p' ){
@@ -92286,13 +107336,14 @@ SQLITE_PRIVATE void sqlite3Pragma(
sqlite3VdbeAddOp2(v, OP_ResultRow, iReg, 1);
sqlite3VdbeSetNumCols(v, 1);
sqlite3VdbeSetColName(v, 0, COLNAME_NAME, zLeft, SQLITE_TRANSIENT);
- }else
+ break;
+ }
/*
- ** PRAGMA [database.]locking_mode
- ** PRAGMA [database.]locking_mode = (normal|exclusive)
+ ** PRAGMA [schema.]locking_mode
+ ** PRAGMA [schema.]locking_mode = (normal|exclusive)
*/
- if( sqlite3StrICmp(zLeft,"locking_mode")==0 ){
+ case PragTyp_LOCKING_MODE: {
const char *zRet = "normal";
int eMode = getLockingMode(zRight);
@@ -92325,36 +107376,25 @@ SQLITE_PRIVATE void sqlite3Pragma(
eMode = sqlite3PagerLockingMode(pPager, eMode);
}
- assert(eMode==PAGER_LOCKINGMODE_NORMAL||eMode==PAGER_LOCKINGMODE_EXCLUSIVE);
+ 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
+ returnSingleText(v, "locking_mode", zRet);
+ break;
+ }
/*
- ** PRAGMA [database.]journal_mode
- ** PRAGMA [database.]journal_mode =
+ ** PRAGMA [schema.]journal_mode
+ ** PRAGMA [schema.]journal_mode =
** (delete|persist|off|truncate|memory|wal|off)
*/
- if( sqlite3StrICmp(zLeft,"journal_mode")==0 ){
+ case PragTyp_JOURNAL_MODE: {
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);
-
+ setOneColumnName(v, "journal_mode");
if( zRight==0 ){
/* If there is no "=MODE" part of the pragma, do a query for the
** current mode */
@@ -92383,116 +107423,107 @@ SQLITE_PRIVATE void sqlite3Pragma(
}
}
sqlite3VdbeAddOp2(v, OP_ResultRow, 1, 1);
- }else
+ break;
+ }
/*
- ** PRAGMA [database.]journal_size_limit
- ** PRAGMA [database.]journal_size_limit=N
+ ** PRAGMA [schema.]journal_size_limit
+ ** PRAGMA [schema.]journal_size_limit=N
**
** Get or set the size limit on rollback journal files.
*/
- if( sqlite3StrICmp(zLeft,"journal_size_limit")==0 ){
+ case PragTyp_JOURNAL_SIZE_LIMIT: {
Pager *pPager = sqlite3BtreePager(pDb->pBt);
i64 iLimit = -2;
if( zRight ){
- sqlite3Atoi64(zRight, &iLimit, 1000000, SQLITE_UTF8);
+ sqlite3DecOrHexToI64(zRight, &iLimit);
if( iLimit<-1 ) iLimit = -1;
}
iLimit = sqlite3PagerJournalSizeLimit(pPager, iLimit);
- returnSingleInt(pParse, "journal_size_limit", iLimit);
- }else
+ returnSingleInt(v, "journal_size_limit", iLimit);
+ break;
+ }
#endif /* SQLITE_OMIT_PAGER_PRAGMAS */
/*
- ** PRAGMA [database.]auto_vacuum
- ** PRAGMA [database.]auto_vacuum=N
+ ** PRAGMA [schema.]auto_vacuum
+ ** PRAGMA [schema.]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 ){
+ case PragTyp_AUTO_VACUUM: {
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);
+ returnSingleInt(v, "auto_vacuum", sqlite3BtreeGetAutoVacuum(pBt));
}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.
+ /* 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.
*/
- 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);
- }
+ static const int iLn = VDBE_OFFSET_LINENO(2);
+ 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, iLn);
+ 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
+ break;
+ }
#endif
/*
- ** PRAGMA [database.]incremental_vacuum(N)
+ ** PRAGMA [schema.]incremental_vacuum(N)
**
** Do N steps of incremental vacuuming on a database.
*/
#ifndef SQLITE_OMIT_AUTOVACUUM
- if( sqlite3StrICmp(zLeft,"incremental_vacuum")==0 ){
+ case PragTyp_INCREMENTAL_VACUUM: {
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);
+ addr = sqlite3VdbeAddOp1(v, OP_IncrVacuum, iDb); VdbeCoverage(v);
sqlite3VdbeAddOp1(v, OP_ResultRow, 1);
sqlite3VdbeAddOp2(v, OP_AddImm, 1, -1);
- sqlite3VdbeAddOp2(v, OP_IfPos, 1, addr);
+ sqlite3VdbeAddOp2(v, OP_IfPos, 1, addr); VdbeCoverage(v);
sqlite3VdbeJumpHere(v, addr);
- }else
+ break;
+ }
#endif
#ifndef SQLITE_OMIT_PAGER_PRAGMAS
/*
- ** PRAGMA [database.]cache_size
- ** PRAGMA [database.]cache_size=N
+ ** PRAGMA [schema.]cache_size
+ ** PRAGMA [schema.]cache_size=N
**
** The first form reports the current local setting for the
** page cache size. The second form sets the local
@@ -92501,17 +107532,104 @@ SQLITE_PRIVATE void sqlite3Pragma(
** 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;
+ case PragTyp_CACHE_SIZE: {
assert( sqlite3SchemaMutexHeld(db, iDb, 0) );
if( !zRight ){
- returnSingleInt(pParse, "cache_size", pDb->pSchema->cache_size);
+ returnSingleInt(v, "cache_size", pDb->pSchema->cache_size);
}else{
int size = sqlite3Atoi(zRight);
pDb->pSchema->cache_size = size;
sqlite3BtreeSetCacheSize(pDb->pBt, pDb->pSchema->cache_size);
}
- }else
+ break;
+ }
+
+ /*
+ ** PRAGMA [schema.]cache_spill
+ ** PRAGMA cache_spill=BOOLEAN
+ ** PRAGMA [schema.]cache_spill=N
+ **
+ ** The first form reports the current local setting for the
+ ** page cache spill size. The second form turns cache spill on
+ ** or off. When turnning cache spill on, the size is set to the
+ ** current cache_size. The third form sets a spill size that
+ ** may be different form the cache size.
+ ** 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 the number of cache_spill pages is less then the number of
+ ** cache_size pages, no spilling occurs until the page count exceeds
+ ** the number of cache_size pages.
+ **
+ ** The cache_spill=BOOLEAN setting applies to all attached schemas,
+ ** not just the schema specified.
+ */
+ case PragTyp_CACHE_SPILL: {
+ assert( sqlite3SchemaMutexHeld(db, iDb, 0) );
+ if( !zRight ){
+ returnSingleInt(v, "cache_spill",
+ (db->flags & SQLITE_CacheSpill)==0 ? 0 :
+ sqlite3BtreeSetSpillSize(pDb->pBt,0));
+ }else{
+ int size = 1;
+ if( sqlite3GetInt32(zRight, &size) ){
+ sqlite3BtreeSetSpillSize(pDb->pBt, size);
+ }
+ if( sqlite3GetBoolean(zRight, size!=0) ){
+ db->flags |= SQLITE_CacheSpill;
+ }else{
+ db->flags &= ~SQLITE_CacheSpill;
+ }
+ setAllPagerFlags(db);
+ }
+ break;
+ }
+
+ /*
+ ** PRAGMA [schema.]mmap_size(N)
+ **
+ ** Used to set mapping size limit. The mapping size limit is
+ ** used to limit the aggregate size of all memory mapped regions of the
+ ** database file. If this parameter is set to zero, then memory mapping
+ ** is not used at all. If N is negative, then the default memory map
+ ** limit determined by sqlite3_config(SQLITE_CONFIG_MMAP_SIZE) is set.
+ ** The parameter N is measured in bytes.
+ **
+ ** This value is advisory. The underlying VFS is free to memory map
+ ** as little or as much as it wants. Except, if N is set to 0 then the
+ ** upper layers will never invoke the xFetch interfaces to the VFS.
+ */
+ case PragTyp_MMAP_SIZE: {
+ sqlite3_int64 sz;
+#if SQLITE_MAX_MMAP_SIZE>0
+ assert( sqlite3SchemaMutexHeld(db, iDb, 0) );
+ if( zRight ){
+ int ii;
+ sqlite3DecOrHexToI64(zRight, &sz);
+ if( sz<0 ) sz = sqlite3GlobalConfig.szMmap;
+ if( pId2->n==0 ) db->szMmap = sz;
+ for(ii=db->nDb-1; ii>=0; ii--){
+ if( db->aDb[ii].pBt && (ii==iDb || pId2->n==0) ){
+ sqlite3BtreeSetMmapLimit(db->aDb[ii].pBt, sz);
+ }
+ }
+ }
+ sz = -1;
+ rc = sqlite3_file_control(db, zDb, SQLITE_FCNTL_MMAP_SIZE, &sz);
+#else
+ sz = 0;
+ rc = SQLITE_OK;
+#endif
+ if( rc==SQLITE_OK ){
+ returnSingleInt(v, "mmap_size", sz);
+ }else if( rc!=SQLITE_NOTFOUND ){
+ pParse->nErr++;
+ pParse->rc = rc;
+ }
+ break;
+ }
/*
** PRAGMA temp_store
@@ -92524,13 +107642,14 @@ SQLITE_PRIVATE void sqlite3Pragma(
** Note that it is possible for the library compile-time options to
** override this setting
*/
- if( sqlite3StrICmp(zLeft, "temp_store")==0 ){
+ case PragTyp_TEMP_STORE: {
if( !zRight ){
- returnSingleInt(pParse, "temp_store", db->temp_store);
+ returnSingleInt(v, "temp_store", db->temp_store);
}else{
changeTempStorage(pParse, zRight);
}
- }else
+ break;
+ }
/*
** PRAGMA temp_store_directory
@@ -92542,15 +107661,9 @@ SQLITE_PRIVATE void sqlite3Pragma(
** If temporary directory is changed, then invalidateTempStorage.
**
*/
- if( sqlite3StrICmp(zLeft, "temp_store_directory")==0 ){
+ case PragTyp_TEMP_STORE_DIRECTORY: {
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);
- }
+ returnSingleText(v, "temp_store_directory", sqlite3_temp_directory);
}else{
#ifndef SQLITE_OMIT_WSD
if( zRight[0] ){
@@ -92575,7 +107688,8 @@ SQLITE_PRIVATE void sqlite3Pragma(
}
#endif /* SQLITE_OMIT_WSD */
}
- }else
+ break;
+ }
#if SQLITE_OS_WIN
/*
@@ -92591,15 +107705,9 @@ SQLITE_PRIVATE void sqlite3Pragma(
** by this setting, regardless of its value.
**
*/
- if( sqlite3StrICmp(zLeft, "data_store_directory")==0 ){
+ case PragTyp_DATA_STORE_DIRECTORY: {
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);
- }
+ returnSingleText(v, "data_store_directory", sqlite3_data_directory);
}else{
#ifndef SQLITE_OMIT_WSD
if( zRight[0] ){
@@ -92618,40 +107726,27 @@ SQLITE_PRIVATE void sqlite3Pragma(
}
#endif /* SQLITE_OMIT_WSD */
}
- }else
+ break;
+ }
#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 ){
+ ** PRAGMA [schema.]lock_proxy_file
+ ** PRAGMA [schema.]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.
+ **
+ */
+ case PragTyp_LOCK_PROXY_FILE: {
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);
- }
+ returnSingleText(v, "lock_proxy_file", proxy_file_path);
}else{
Pager *pPager = sqlite3BtreePager(pDb->pBt);
sqlite3_file *pFile = sqlite3PagerFile(pPager);
@@ -92668,38 +107763,71 @@ SQLITE_PRIVATE void sqlite3Pragma(
goto pragma_out;
}
}
- }else
+ break;
+ }
#endif /* SQLITE_ENABLE_LOCKING_STYLE */
/*
- ** PRAGMA [database.]synchronous
- ** PRAGMA [database.]synchronous=OFF|ON|NORMAL|FULL
+ ** PRAGMA [schema.]synchronous
+ ** PRAGMA [schema.]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;
+ case PragTyp_SYNCHRONOUS: {
if( !zRight ){
- returnSingleInt(pParse, "synchronous", pDb->safety_level-1);
+ returnSingleInt(v, "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;
+ int iLevel = (getSafetyLevel(zRight,0,1)+1) & PAGER_SYNCHRONOUS_MASK;
+ if( iLevel==0 ) iLevel = 1;
+ pDb->safety_level = iLevel;
+ setAllPagerFlags(db);
}
}
- }else
+ break;
+ }
#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
+ case PragTyp_FLAG: {
+ if( zRight==0 ){
+ returnSingleInt(v, pPragma->zName, (db->flags & pPragma->iArg)!=0 );
+ }else{
+ int mask = pPragma->iArg; /* 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 SQLITE_USER_AUTHENTICATION
+ if( db->auth.authLevel==UAUTH_User ){
+ /* Do not allow non-admin users to modify the schema arbitrarily */
+ mask &= ~(SQLITE_WriteSchema);
+ }
+#endif
+
+ if( sqlite3GetBoolean(zRight, 0) ){
+ db->flags |= mask;
+ }else{
+ db->flags &= ~mask;
+ if( mask==SQLITE_DeferFKs ) db->nDeferredImmCons = 0;
+ }
+
+ /* 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);
+ setAllPagerFlags(db);
+ }
+ break;
+ }
#endif /* SQLITE_OMIT_FLAG_PRAGMAS */
#ifndef SQLITE_OMIT_SCHEMA_PRAGMAS
@@ -92715,167 +107843,200 @@ SQLITE_PRIVATE void sqlite3Pragma(
** 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 ){
+ case PragTyp_TABLE_INFO: if( zRight ){
Table *pTab;
- if( sqlite3ReadSchema(pParse) ) goto pragma_out;
pTab = sqlite3FindTable(db, zRight, zDb);
if( pTab ){
- int i;
+ static const char *azCol[] = {
+ "cid", "name", "type", "notnull", "dflt_value", "pk"
+ };
+ int i, k;
int nHidden = 0;
Column *pCol;
- sqlite3VdbeSetNumCols(v, 6);
+ Index *pPk = sqlite3PrimaryKeyIndex(pTab);
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);
+ sqlite3CodeVerifySchema(pParse, iDb);
+ setAllColumnNames(v, 6, azCol); assert( 6==ArraySize(azCol) );
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);
+ if( (pCol->colFlags & COLFLAG_PRIMKEY)==0 ){
+ k = 0;
+ }else if( pPk==0 ){
+ k = 1;
}else{
- sqlite3VdbeAddOp2(v, OP_Null, 0, 5);
+ for(k=1; k<=pTab->nCol && pPk->aiColumn[k-1]!=i; k++){}
}
- sqlite3VdbeAddOp2(v, OP_Integer,
- (pCol->colFlags&COLFLAG_PRIMKEY)!=0, 6);
+ sqlite3VdbeMultiLoad(v, 1, "issisi",
+ i-nHidden,
+ pCol->zName,
+ pCol->zType ? pCol->zType : "",
+ pCol->notNull ? 1 : 0,
+ pCol->zDflt,
+ k);
sqlite3VdbeAddOp2(v, OP_ResultRow, 1, 6);
}
}
- }else
+ }
+ break;
- if( sqlite3StrICmp(zLeft, "index_info")==0 && zRight ){
+ case PragTyp_STATS: {
+ static const char *azCol[] = { "table", "index", "width", "height" };
+ Index *pIdx;
+ HashElem *i;
+ v = sqlite3GetVdbe(pParse);
+ pParse->nMem = 4;
+ sqlite3CodeVerifySchema(pParse, iDb);
+ setAllColumnNames(v, 4, azCol); assert( 4==ArraySize(azCol) );
+ for(i=sqliteHashFirst(&pDb->pSchema->tblHash); i; i=sqliteHashNext(i)){
+ Table *pTab = sqliteHashData(i);
+ sqlite3VdbeMultiLoad(v, 1, "ssii",
+ pTab->zName,
+ 0,
+ (int)sqlite3LogEstToInt(pTab->szTabRow),
+ (int)sqlite3LogEstToInt(pTab->nRowLogEst));
+ sqlite3VdbeAddOp2(v, OP_ResultRow, 1, 4);
+ for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){
+ sqlite3VdbeMultiLoad(v, 2, "sii",
+ pIdx->zName,
+ (int)sqlite3LogEstToInt(pIdx->szIdxRow),
+ (int)sqlite3LogEstToInt(pIdx->aiRowLogEst[0]));
+ sqlite3VdbeAddOp2(v, OP_ResultRow, 1, 4);
+ }
+ }
+ }
+ break;
+
+ case PragTyp_INDEX_INFO: if( zRight ){
Index *pIdx;
Table *pTab;
- if( sqlite3ReadSchema(pParse) ) goto pragma_out;
pIdx = sqlite3FindIndex(db, zRight, zDb);
if( pIdx ){
+ static const char *azCol[] = {
+ "seqno", "cid", "name", "desc", "coll", "key"
+ };
int i;
+ int mx;
+ if( pPragma->iArg ){
+ /* PRAGMA index_xinfo (newer version with more rows and columns) */
+ mx = pIdx->nColumn;
+ pParse->nMem = 6;
+ }else{
+ /* PRAGMA index_info (legacy version) */
+ mx = pIdx->nKeyCol;
+ pParse->nMem = 3;
+ }
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);
+ sqlite3CodeVerifySchema(pParse, iDb);
+ assert( pParse->nMem<=ArraySize(azCol) );
+ setAllColumnNames(v, pParse->nMem, azCol);
+ for(i=0; i<mx; i++){
+ i16 cnum = pIdx->aiColumn[i];
+ sqlite3VdbeMultiLoad(v, 1, "iis", i, cnum,
+ cnum<0 ? 0 : pTab->aCol[cnum].zName);
+ if( pPragma->iArg ){
+ sqlite3VdbeMultiLoad(v, 4, "isi",
+ pIdx->aSortOrder[i],
+ pIdx->azColl[i],
+ i<pIdx->nKeyCol);
+ }
+ sqlite3VdbeAddOp2(v, OP_ResultRow, 1, pParse->nMem);
}
}
- }else
+ }
+ break;
- if( sqlite3StrICmp(zLeft, "index_list")==0 && zRight ){
+ case PragTyp_INDEX_LIST: if( zRight ){
Index *pIdx;
Table *pTab;
- if( sqlite3ReadSchema(pParse) ) goto pragma_out;
+ int i;
pTab = sqlite3FindTable(db, zRight, zDb);
if( pTab ){
+ static const char *azCol[] = {
+ "seq", "name", "unique", "origin", "partial"
+ };
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;
- }
+ pParse->nMem = 5;
+ sqlite3CodeVerifySchema(pParse, iDb);
+ setAllColumnNames(v, 5, azCol); assert( 5==ArraySize(azCol) );
+ for(pIdx=pTab->pIndex, i=0; pIdx; pIdx=pIdx->pNext, i++){
+ const char *azOrigin[] = { "c", "u", "pk" };
+ sqlite3VdbeMultiLoad(v, 1, "isisi",
+ i,
+ pIdx->zName,
+ IsUniqueIndex(pIdx),
+ azOrigin[pIdx->idxType],
+ pIdx->pPartIdxWhere!=0);
+ sqlite3VdbeAddOp2(v, OP_ResultRow, 1, 5);
}
}
- }else
+ }
+ break;
- if( sqlite3StrICmp(zLeft, "database_list")==0 ){
+ case PragTyp_DATABASE_LIST: {
+ static const char *azCol[] = { "seq", "name", "file" };
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);
+ setAllColumnNames(v, 3, azCol); assert( 3==ArraySize(azCol) );
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);
+ sqlite3VdbeMultiLoad(v, 1, "iss",
+ i,
+ db->aDb[i].zName,
+ sqlite3BtreeGetFilename(db->aDb[i].pBt));
sqlite3VdbeAddOp2(v, OP_ResultRow, 1, 3);
}
- }else
+ }
+ break;
- if( sqlite3StrICmp(zLeft, "collation_list")==0 ){
+ case PragTyp_COLLATION_LIST: {
+ static const char *azCol[] = { "seq", "name" };
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);
+ setAllColumnNames(v, 2, azCol); assert( 2==ArraySize(azCol) );
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);
+ sqlite3VdbeMultiLoad(v, 1, "is", i++, pColl->zName);
sqlite3VdbeAddOp2(v, OP_ResultRow, 1, 2);
}
- }else
+ }
+ break;
#endif /* SQLITE_OMIT_SCHEMA_PRAGMAS */
#ifndef SQLITE_OMIT_FOREIGN_KEY
- if( sqlite3StrICmp(zLeft, "foreign_key_list")==0 && zRight ){
+ case PragTyp_FOREIGN_KEY_LIST: if( 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 ){
+ static const char *azCol[] = {
+ "id", "seq", "table", "from", "to", "on_update", "on_delete",
+ "match"
+ };
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);
+ sqlite3CodeVerifySchema(pParse, iDb);
+ setAllColumnNames(v, 8, azCol); assert( 8==ArraySize(azCol) );
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);
+ sqlite3VdbeMultiLoad(v, 1, "iissssss",
+ i,
+ j,
+ pFK->zTo,
+ pTab->aCol[pFK->aCol[j].iFrom].zName,
+ pFK->aCol[j].zCol,
+ actionName(pFK->aAction[1]), /* ON UPDATE */
+ actionName(pFK->aAction[0]), /* ON DELETE */
+ "NONE");
sqlite3VdbeAddOp2(v, OP_ResultRow, 1, 8);
}
++i;
@@ -92883,51 +108044,166 @@ SQLITE_PRIVATE void sqlite3Pragma(
}
}
}
- }else
+ }
+ break;
+#endif /* !defined(SQLITE_OMIT_FOREIGN_KEY) */
+
+#ifndef SQLITE_OMIT_FOREIGN_KEY
+#ifndef SQLITE_OMIT_TRIGGER
+ case PragTyp_FOREIGN_KEY_CHECK: {
+ FKey *pFK; /* A foreign key constraint */
+ Table *pTab; /* Child table contain "REFERENCES" keyword */
+ Table *pParent; /* Parent table that child points to */
+ Index *pIdx; /* Index in the parent table */
+ int i; /* Loop counter: Foreign key number for pTab */
+ int j; /* Loop counter: Field of the foreign key */
+ HashElem *k; /* Loop counter: Next table in schema */
+ int x; /* result variable */
+ int regResult; /* 3 registers to hold a result row */
+ int regKey; /* Register to hold key for checking the FK */
+ int regRow; /* Registers to hold a row from pTab */
+ int addrTop; /* Top of a loop checking foreign keys */
+ int addrOk; /* Jump here if the key is OK */
+ int *aiCols; /* child to parent column mapping */
+ static const char *azCol[] = { "table", "rowid", "parent", "fkid" };
+
+ regResult = pParse->nMem+1;
+ pParse->nMem += 4;
+ regKey = ++pParse->nMem;
+ regRow = ++pParse->nMem;
+ v = sqlite3GetVdbe(pParse);
+ setAllColumnNames(v, 4, azCol); assert( 4==ArraySize(azCol) );
+ sqlite3CodeVerifySchema(pParse, iDb);
+ k = sqliteHashFirst(&db->aDb[iDb].pSchema->tblHash);
+ while( k ){
+ if( zRight ){
+ pTab = sqlite3LocateTable(pParse, 0, zRight, zDb);
+ k = 0;
+ }else{
+ pTab = (Table*)sqliteHashData(k);
+ k = sqliteHashNext(k);
+ }
+ if( pTab==0 || pTab->pFKey==0 ) continue;
+ sqlite3TableLock(pParse, iDb, pTab->tnum, 0, pTab->zName);
+ if( pTab->nCol+regRow>pParse->nMem ) pParse->nMem = pTab->nCol + regRow;
+ sqlite3OpenTable(pParse, 0, iDb, pTab, OP_OpenRead);
+ sqlite3VdbeLoadString(v, regResult, pTab->zName);
+ for(i=1, pFK=pTab->pFKey; pFK; i++, pFK=pFK->pNextFrom){
+ pParent = sqlite3FindTable(db, pFK->zTo, zDb);
+ if( pParent==0 ) continue;
+ pIdx = 0;
+ sqlite3TableLock(pParse, iDb, pParent->tnum, 0, pParent->zName);
+ x = sqlite3FkLocateIndex(pParse, pParent, pFK, &pIdx, 0);
+ if( x==0 ){
+ if( pIdx==0 ){
+ sqlite3OpenTable(pParse, i, iDb, pParent, OP_OpenRead);
+ }else{
+ sqlite3VdbeAddOp3(v, OP_OpenRead, i, pIdx->tnum, iDb);
+ sqlite3VdbeSetP4KeyInfo(pParse, pIdx);
+ }
+ }else{
+ k = 0;
+ break;
+ }
+ }
+ assert( pParse->nErr>0 || pFK==0 );
+ if( pFK ) break;
+ if( pParse->nTab<i ) pParse->nTab = i;
+ addrTop = sqlite3VdbeAddOp1(v, OP_Rewind, 0); VdbeCoverage(v);
+ for(i=1, pFK=pTab->pFKey; pFK; i++, pFK=pFK->pNextFrom){
+ pParent = sqlite3FindTable(db, pFK->zTo, zDb);
+ pIdx = 0;
+ aiCols = 0;
+ if( pParent ){
+ x = sqlite3FkLocateIndex(pParse, pParent, pFK, &pIdx, &aiCols);
+ assert( x==0 );
+ }
+ addrOk = sqlite3VdbeMakeLabel(v);
+ if( pParent && pIdx==0 ){
+ int iKey = pFK->aCol[0].iFrom;
+ assert( iKey>=0 && iKey<pTab->nCol );
+ if( iKey!=pTab->iPKey ){
+ sqlite3VdbeAddOp3(v, OP_Column, 0, iKey, regRow);
+ sqlite3ColumnDefault(v, pTab, iKey, regRow);
+ sqlite3VdbeAddOp2(v, OP_IsNull, regRow, addrOk); VdbeCoverage(v);
+ sqlite3VdbeAddOp2(v, OP_MustBeInt, regRow,
+ sqlite3VdbeCurrentAddr(v)+3); VdbeCoverage(v);
+ }else{
+ sqlite3VdbeAddOp2(v, OP_Rowid, 0, regRow);
+ }
+ sqlite3VdbeAddOp3(v, OP_NotExists, i, 0, regRow); VdbeCoverage(v);
+ sqlite3VdbeGoto(v, addrOk);
+ sqlite3VdbeJumpHere(v, sqlite3VdbeCurrentAddr(v)-2);
+ }else{
+ for(j=0; j<pFK->nCol; j++){
+ sqlite3ExprCodeGetColumnOfTable(v, pTab, 0,
+ aiCols ? aiCols[j] : pFK->aCol[j].iFrom, regRow+j);
+ sqlite3VdbeAddOp2(v, OP_IsNull, regRow+j, addrOk); VdbeCoverage(v);
+ }
+ if( pParent ){
+ sqlite3VdbeAddOp4(v, OP_MakeRecord, regRow, pFK->nCol, regKey,
+ sqlite3IndexAffinityStr(db,pIdx), pFK->nCol);
+ sqlite3VdbeAddOp4Int(v, OP_Found, i, addrOk, regKey, 0);
+ VdbeCoverage(v);
+ }
+ }
+ sqlite3VdbeAddOp2(v, OP_Rowid, 0, regResult+1);
+ sqlite3VdbeMultiLoad(v, regResult+2, "si", pFK->zTo, i-1);
+ sqlite3VdbeAddOp2(v, OP_ResultRow, regResult, 4);
+ sqlite3VdbeResolveLabel(v, addrOk);
+ sqlite3DbFree(db, aiCols);
+ }
+ sqlite3VdbeAddOp2(v, OP_Next, 0, addrTop+1); VdbeCoverage(v);
+ sqlite3VdbeJumpHere(v, addrTop);
+ }
+ }
+ break;
+#endif /* !defined(SQLITE_OMIT_TRIGGER) */
#endif /* !defined(SQLITE_OMIT_FOREIGN_KEY) */
#ifndef NDEBUG
- if( sqlite3StrICmp(zLeft, "parser_trace")==0 ){
+ case PragTyp_PARSER_TRACE: {
if( zRight ){
if( sqlite3GetBoolean(zRight, 0) ){
- sqlite3ParserTrace(stderr, "parser: ");
+ sqlite3ParserTrace(stdout, "parser: ");
}else{
sqlite3ParserTrace(0, 0);
}
}
- }else
+ }
+ break;
#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 ){
+ case PragTyp_CASE_SENSITIVE_LIKE: {
if( zRight ){
sqlite3RegisterLikeFunctions(db, sqlite3GetBoolean(zRight, 0));
}
- }else
+ }
+ break;
#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
+ /* Pragma "quick_check" is 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
- ){
+ case PragTyp_INTEGRITY_CHECK: {
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 int iLn = VDBE_OFFSET_LINENO(2);
static const VdbeOpList endCode[] = {
{ OP_AddImm, 1, 0, 0}, /* 0 */
- { OP_IfNeg, 1, 0, 0}, /* 1 */
+ { OP_If, 1, 0, 0}, /* 1 */
{ OP_String8, 0, 3, 0}, /* 2 */
{ OP_ResultRow, 3, 1, 0},
};
@@ -92948,10 +108224,8 @@ SQLITE_PRIVATE void sqlite3Pragma(
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);
+ setOneColumnName(v, "integrity_check");
/* Set the maximum error count */
mxErr = SQLITE_INTEGRITY_CHECK_ERROR_MAX;
@@ -92974,6 +108248,7 @@ SQLITE_PRIVATE void sqlite3Pragma(
sqlite3CodeVerifySchema(pParse, i);
addr = sqlite3VdbeAddOp1(v, OP_IfPos, 1); /* Halt if out of errors */
+ VdbeCoverage(v);
sqlite3VdbeAddOp2(v, OP_Halt, 0, 0);
sqlite3VdbeJumpHere(v, addr);
@@ -92987,27 +108262,29 @@ SQLITE_PRIVATE void sqlite3Pragma(
for(x=sqliteHashFirst(pTbls); x; x=sqliteHashNext(x)){
Table *pTab = sqliteHashData(x);
Index *pIdx;
- sqlite3VdbeAddOp2(v, OP_Integer, pTab->tnum, 2+cnt);
- cnt++;
+ if( HasRowid(pTab) ){
+ sqlite3VdbeAddOp2(v, OP_Integer, pTab->tnum, 2+cnt);
+ VdbeComment((v, "%s", pTab->zName));
+ cnt++;
+ }
for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){
sqlite3VdbeAddOp2(v, OP_Integer, pIdx->tnum, 2+cnt);
+ VdbeComment((v, "%s", pIdx->zName));
cnt++;
}
}
/* Make sure sufficient number of registers have been allocated */
- if( pParse->nMem < cnt+4 ){
- pParse->nMem = cnt+4;
- }
+ pParse->nMem = MAX( pParse->nMem, cnt+8 );
/* Do the b-tree integrity checks */
sqlite3VdbeAddOp3(v, OP_IntegrityCk, 2, cnt, 1);
sqlite3VdbeChangeP5(v, (u8)i);
- addr = sqlite3VdbeAddOp1(v, OP_IsNull, 2);
+ addr = sqlite3VdbeAddOp1(v, OP_IsNull, 2); VdbeCoverage(v);
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_Move, 2, 4, 1);
sqlite3VdbeAddOp3(v, OP_Concat, 4, 3, 2);
sqlite3VdbeAddOp2(v, OP_ResultRow, 2, 1);
sqlite3VdbeJumpHere(v, addr);
@@ -93016,77 +108293,123 @@ SQLITE_PRIVATE void sqlite3Pragma(
*/
for(x=sqliteHashFirst(pTbls); x && !isQuick; x=sqliteHashNext(x)){
Table *pTab = sqliteHashData(x);
- Index *pIdx;
+ Index *pIdx, *pPk;
+ Index *pPrior = 0;
int loopTop;
+ int iDataCur, iIdxCur;
+ int r1 = -1;
if( pTab->pIndex==0 ) continue;
+ pPk = HasRowid(pTab) ? 0 : sqlite3PrimaryKeyIndex(pTab);
addr = sqlite3VdbeAddOp1(v, OP_IfPos, 1); /* Stop if out of errors */
+ VdbeCoverage(v);
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 */
+ sqlite3ExprCacheClear(pParse);
+ sqlite3OpenTableAndIndices(pParse, pTab, OP_OpenRead, 0,
+ 1, 0, &iDataCur, &iIdxCur);
+ sqlite3VdbeAddOp2(v, OP_Integer, 0, 7);
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);
+ sqlite3VdbeAddOp2(v, OP_Integer, 0, 8+j); /* index entries counter */
+ }
+ pParse->nMem = MAX(pParse->nMem, 8+j);
+ sqlite3VdbeAddOp2(v, OP_Rewind, iDataCur, 0); VdbeCoverage(v);
+ loopTop = sqlite3VdbeAddOp2(v, OP_AddImm, 7, 1);
+ /* Verify that all NOT NULL columns really are NOT NULL */
+ for(j=0; j<pTab->nCol; j++){
+ char *zErr;
+ int jmp2, jmp3;
+ if( j==pTab->iPKey ) continue;
+ if( pTab->aCol[j].notNull==0 ) continue;
+ sqlite3ExprCodeGetColumnOfTable(v, pTab, iDataCur, j, 3);
+ sqlite3VdbeChangeP5(v, OPFLAG_TYPEOFARG);
+ jmp2 = sqlite3VdbeAddOp1(v, OP_NotNull, 3); VdbeCoverage(v);
+ sqlite3VdbeAddOp2(v, OP_AddImm, 1, -1); /* Decrement error limit */
+ zErr = sqlite3MPrintf(db, "NULL value in %s.%s", pTab->zName,
+ pTab->aCol[j].zName);
+ sqlite3VdbeAddOp4(v, OP_String8, 0, 3, 0, zErr, P4_DYNAMIC);
+ sqlite3VdbeAddOp2(v, OP_ResultRow, 3, 1);
+ jmp3 = sqlite3VdbeAddOp1(v, OP_IfPos, 1); VdbeCoverage(v);
+ sqlite3VdbeAddOp0(v, OP_Halt);
sqlite3VdbeJumpHere(v, jmp2);
+ sqlite3VdbeJumpHere(v, jmp3);
}
- sqlite3VdbeAddOp2(v, OP_Next, 1, loopTop+1);
- sqlite3VdbeJumpHere(v, loopTop);
+ /* Validate index entries for the current row */
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);
+ int jmp2, jmp3, jmp4, jmp5;
+ int ckUniq = sqlite3VdbeMakeLabel(v);
+ if( pPk==pIdx ) continue;
+ r1 = sqlite3GenerateIndexKey(pParse, pIdx, iDataCur, 0, 0, &jmp3,
+ pPrior, r1);
+ pPrior = pIdx;
+ sqlite3VdbeAddOp2(v, OP_AddImm, 8+j, 1); /* increment entry count */
+ /* Verify that an index entry exists for the current table row */
+ jmp2 = sqlite3VdbeAddOp4Int(v, OP_Found, iIdxCur+j, ckUniq, r1,
+ pIdx->nColumn); VdbeCoverage(v);
+ sqlite3VdbeAddOp2(v, OP_AddImm, 1, -1); /* Decrement error limit */
+ sqlite3VdbeLoadString(v, 3, "row ");
+ sqlite3VdbeAddOp3(v, OP_Concat, 7, 3, 3);
+ sqlite3VdbeLoadString(v, 4, " missing from index ");
+ sqlite3VdbeAddOp3(v, OP_Concat, 4, 3, 3);
+ jmp5 = sqlite3VdbeLoadString(v, 4, pIdx->zName);
+ sqlite3VdbeAddOp3(v, OP_Concat, 4, 3, 3);
+ sqlite3VdbeAddOp2(v, OP_ResultRow, 3, 1);
+ jmp4 = sqlite3VdbeAddOp1(v, OP_IfPos, 1); VdbeCoverage(v);
+ sqlite3VdbeAddOp0(v, OP_Halt);
+ sqlite3VdbeJumpHere(v, jmp2);
+ /* For UNIQUE indexes, verify that only one entry exists with the
+ ** current key. The entry is unique if (1) any column is NULL
+ ** or (2) the next entry has a different key */
+ if( IsUniqueIndex(pIdx) ){
+ int uniqOk = sqlite3VdbeMakeLabel(v);
+ int jmp6;
+ int kk;
+ for(kk=0; kk<pIdx->nKeyCol; kk++){
+ int iCol = pIdx->aiColumn[kk];
+ assert( iCol!=XN_ROWID && iCol<pTab->nCol );
+ if( iCol>=0 && pTab->aCol[iCol].notNull ) continue;
+ sqlite3VdbeAddOp2(v, OP_IsNull, r1+kk, uniqOk);
+ VdbeCoverage(v);
+ }
+ jmp6 = sqlite3VdbeAddOp1(v, OP_Next, iIdxCur+j); VdbeCoverage(v);
+ sqlite3VdbeGoto(v, uniqOk);
+ sqlite3VdbeJumpHere(v, jmp6);
+ sqlite3VdbeAddOp4Int(v, OP_IdxGT, iIdxCur+j, uniqOk, r1,
+ pIdx->nKeyCol); VdbeCoverage(v);
+ sqlite3VdbeAddOp2(v, OP_AddImm, 1, -1); /* Decrement error limit */
+ sqlite3VdbeLoadString(v, 3, "non-unique entry in index ");
+ sqlite3VdbeGoto(v, jmp5);
+ sqlite3VdbeResolveLabel(v, uniqOk);
+ }
+ sqlite3VdbeJumpHere(v, jmp4);
+ sqlite3ResolvePartIdxLabel(pParse, jmp3);
+ }
+ sqlite3VdbeAddOp2(v, OP_Next, iDataCur, loopTop); VdbeCoverage(v);
+ sqlite3VdbeJumpHere(v, loopTop-1);
+#ifndef SQLITE_OMIT_BTREECOUNT
+ sqlite3VdbeLoadString(v, 2, "wrong # of entries in index ");
+ for(j=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, j++){
+ if( pPk==pIdx ) continue;
+ addr = sqlite3VdbeCurrentAddr(v);
+ sqlite3VdbeAddOp2(v, OP_IfPos, 1, addr+2); VdbeCoverage(v);
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);
+ sqlite3VdbeAddOp2(v, OP_Count, iIdxCur+j, 3);
+ sqlite3VdbeAddOp3(v, OP_Eq, 8+j, addr+8, 3); VdbeCoverage(v);
+ sqlite3VdbeChangeP5(v, SQLITE_NOTNULL);
+ sqlite3VdbeAddOp2(v, OP_AddImm, 1, -1);
+ sqlite3VdbeLoadString(v, 3, pIdx->zName);
+ sqlite3VdbeAddOp3(v, OP_Concat, 3, 2, 7);
+ sqlite3VdbeAddOp2(v, OP_ResultRow, 7, 1);
}
+#endif /* SQLITE_OMIT_BTREECOUNT */
}
}
- addr = sqlite3VdbeAddOpList(v, ArraySize(endCode), endCode);
+ addr = sqlite3VdbeAddOpList(v, ArraySize(endCode), endCode, iLn);
sqlite3VdbeChangeP2(v, addr, -mxErr);
sqlite3VdbeJumpHere(v, addr+1);
sqlite3VdbeChangeP4(v, addr+2, "ok", P4_STATIC);
- }else
+ }
+ break;
#endif /* SQLITE_OMIT_INTEGRITY_CHECK */
#ifndef SQLITE_OMIT_UTF16
@@ -93112,7 +108435,7 @@ SQLITE_PRIVATE void sqlite3Pragma(
** 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 ){
+ case PragTyp_ENCODING: {
static const struct EncName {
char *zName;
u8 enc;
@@ -93130,14 +108453,10 @@ SQLITE_PRIVATE void sqlite3Pragma(
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);
+ returnSingleText(v, "encoding", encnames[ENC(pParse->db)].zName);
}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
@@ -93150,7 +108469,8 @@ SQLITE_PRIVATE void sqlite3Pragma(
){
for(pEnc=&encnames[0]; pEnc->zName; pEnc++){
if( 0==sqlite3StrICmp(zRight, pEnc->zName) ){
- ENC(pParse->db) = pEnc->enc ? pEnc->enc : SQLITE_UTF16NATIVE;
+ SCHEMA_ENC(db) = ENC(db) =
+ pEnc->enc ? pEnc->enc : SQLITE_UTF16NATIVE;
break;
}
}
@@ -93159,16 +108479,22 @@ SQLITE_PRIVATE void sqlite3Pragma(
}
}
}
- }else
+ }
+ break;
#endif /* SQLITE_OMIT_UTF16 */
#ifndef SQLITE_OMIT_SCHEMA_VERSION_PRAGMAS
/*
- ** PRAGMA [database.]schema_version
- ** PRAGMA [database.]schema_version = <integer>
+ ** PRAGMA [schema.]schema_version
+ ** PRAGMA [schema.]schema_version = <integer>
+ **
+ ** PRAGMA [schema.]user_version
+ ** PRAGMA [schema.]user_version = <integer>
**
- ** PRAGMA [database.]user_version
- ** PRAGMA [database.]user_version = <integer>
+ ** PRAGMA [schema.]freelist_count = <integer>
+ **
+ ** PRAGMA [schema.]application_id
+ ** PRAGMA [schema.]application_id = <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
@@ -93188,32 +108514,17 @@ SQLITE_PRIVATE void sqlite3Pragma(
** 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. */
+ case PragTyp_HEADER_VALUE: {
+ int iCookie = pPragma->iArg; /* Which cookie to read or write */
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 ){
+ if( zRight && (pPragma->mPragFlag & PragFlag_ReadOnly)==0 ){
/* 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);
+ int addr = sqlite3VdbeAddOpList(v, ArraySize(setCookie), setCookie, 0);
sqlite3VdbeChangeP1(v, addr, iDb);
sqlite3VdbeChangeP1(v, addr+1, sqlite3Atoi(zRight));
sqlite3VdbeChangeP1(v, addr+2, iDb);
@@ -93225,14 +108536,15 @@ SQLITE_PRIVATE void sqlite3Pragma(
{ OP_ReadCookie, 0, 1, 0}, /* 1 */
{ OP_ResultRow, 1, 1, 0}
};
- int addr = sqlite3VdbeAddOpList(v, ArraySize(readCookie), readCookie);
+ int addr = sqlite3VdbeAddOpList(v, ArraySize(readCookie), readCookie, 0);
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
+ }
+ break;
#endif /* SQLITE_OMIT_SCHEMA_VERSION_PRAGMAS */
#ifndef SQLITE_OMIT_COMPILEOPTION_DIAGS
@@ -93242,26 +108554,27 @@ SQLITE_PRIVATE void sqlite3Pragma(
** Return the names of all compile-time options used in this build,
** one option per row.
*/
- if( sqlite3StrICmp(zLeft, "compile_options")==0 ){
+ case PragTyp_COMPILE_OPTIONS: {
int i = 0;
const char *zOpt;
- sqlite3VdbeSetNumCols(v, 1);
pParse->nMem = 1;
- sqlite3VdbeSetColName(v, 0, COLNAME_NAME, "compile_option", SQLITE_STATIC);
+ setOneColumnName(v, "compile_option");
while( (zOpt = sqlite3_compileoption_get(i++))!=0 ){
- sqlite3VdbeAddOp4(v, OP_String8, 0, 1, 0, zOpt, 0);
+ sqlite3VdbeLoadString(v, 1, zOpt);
sqlite3VdbeAddOp2(v, OP_ResultRow, 1, 1);
}
- }else
+ }
+ break;
#endif /* SQLITE_OMIT_COMPILEOPTION_DIAGS */
#ifndef SQLITE_OMIT_WAL
/*
- ** PRAGMA [database.]wal_checkpoint = passive|full|restart
+ ** PRAGMA [schema.]wal_checkpoint = passive|full|restart|truncate
**
** Checkpoint the database.
*/
- if( sqlite3StrICmp(zLeft, "wal_checkpoint")==0 ){
+ case PragTyp_WAL_CHECKPOINT: {
+ static const char *azCol[] = { "busy", "log", "checkpointed" };
int iBt = (pId2->z?iDb:SQLITE_MAX_ATTACHED);
int eMode = SQLITE_CHECKPOINT_PASSIVE;
if( zRight ){
@@ -93269,18 +108582,16 @@ SQLITE_PRIVATE void sqlite3Pragma(
eMode = SQLITE_CHECKPOINT_FULL;
}else if( sqlite3StrICmp(zRight, "restart")==0 ){
eMode = SQLITE_CHECKPOINT_RESTART;
+ }else if( sqlite3StrICmp(zRight, "truncate")==0 ){
+ eMode = SQLITE_CHECKPOINT_TRUNCATE;
}
}
- if( sqlite3ReadSchema(pParse) ) goto pragma_out;
- sqlite3VdbeSetNumCols(v, 3);
+ setAllColumnNames(v, 3, azCol); assert( 3==ArraySize(azCol) );
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
+ }
+ break;
/*
** PRAGMA wal_autocheckpoint
@@ -93290,25 +108601,28 @@ SQLITE_PRIVATE void sqlite3Pragma(
** after accumulating N frames in the log. Or query for the current value
** of N.
*/
- if( sqlite3StrICmp(zLeft, "wal_autocheckpoint")==0 ){
+ case PragTyp_WAL_AUTOCHECKPOINT: {
if( zRight ){
sqlite3_wal_autocheckpoint(db, sqlite3Atoi(zRight));
}
- returnSingleInt(pParse, "wal_autocheckpoint",
+ returnSingleInt(v, "wal_autocheckpoint",
db->xWalCallback==sqlite3WalDefaultHook ?
SQLITE_PTR_TO_INT(db->pWalArg) : 0);
- }else
+ }
+ break;
#endif
/*
** PRAGMA shrink_memory
**
- ** This pragma attempts to free as much memory as possible from the
- ** current database connection.
+ ** IMPLEMENTATION-OF: R-23445-46109 This pragma causes the database
+ ** connection on which it is invoked to free up as much memory as it
+ ** can, by calling sqlite3_db_release_memory().
*/
- if( sqlite3StrICmp(zLeft, "shrink_memory")==0 ){
+ case PragTyp_SHRINK_MEMORY: {
sqlite3_db_release_memory(db);
- }else
+ break;
+ }
/*
** PRAGMA busy_timeout
@@ -93319,32 +108633,72 @@ SQLITE_PRIVATE void sqlite3Pragma(
** then 0 is returned. Setting the busy_timeout to 0 or negative
** disables the timeout.
*/
- if( sqlite3StrICmp(zLeft, "busy_timeout")==0 ){
+ /*case PragTyp_BUSY_TIMEOUT*/ default: {
+ assert( pPragma->ePragTyp==PragTyp_BUSY_TIMEOUT );
if( zRight ){
sqlite3_busy_timeout(db, sqlite3Atoi(zRight));
}
- returnSingleInt(pParse, "timeout", db->busyTimeout);
- }else
+ returnSingleInt(v, "timeout", db->busyTimeout);
+ break;
+ }
+
+ /*
+ ** PRAGMA soft_heap_limit
+ ** PRAGMA soft_heap_limit = N
+ **
+ ** IMPLEMENTATION-OF: R-26343-45930 This pragma invokes the
+ ** sqlite3_soft_heap_limit64() interface with the argument N, if N is
+ ** specified and is a non-negative integer.
+ ** IMPLEMENTATION-OF: R-64451-07163 The soft_heap_limit pragma always
+ ** returns the same integer that would be returned by the
+ ** sqlite3_soft_heap_limit64(-1) C-language function.
+ */
+ case PragTyp_SOFT_HEAP_LIMIT: {
+ sqlite3_int64 N;
+ if( zRight && sqlite3DecOrHexToI64(zRight, &N)==SQLITE_OK ){
+ sqlite3_soft_heap_limit64(N);
+ }
+ returnSingleInt(v, "soft_heap_limit", sqlite3_soft_heap_limit64(-1));
+ break;
+ }
+
+ /*
+ ** PRAGMA threads
+ ** PRAGMA threads = N
+ **
+ ** Configure the maximum number of worker threads. Return the new
+ ** maximum, which might be less than requested.
+ */
+ case PragTyp_THREADS: {
+ sqlite3_int64 N;
+ if( zRight
+ && sqlite3DecOrHexToI64(zRight, &N)==SQLITE_OK
+ && N>=0
+ ){
+ sqlite3_limit(db, SQLITE_LIMIT_WORKER_THREADS, (int)(N&0x7fffffff));
+ }
+ returnSingleInt(v, "threads",
+ sqlite3_limit(db, SQLITE_LIMIT_WORKER_THREADS, -1));
+ break;
+ }
#if defined(SQLITE_DEBUG) || defined(SQLITE_TEST)
/*
** Report the current state of file logs for all databases
*/
- if( sqlite3StrICmp(zLeft, "lock_status")==0 ){
+ case PragTyp_LOCK_STATUS: {
static const char *const azLockName[] = {
"unlocked", "shared", "reserved", "pending", "exclusive"
};
+ static const char *azCol[] = { "database", "status" };
int i;
- sqlite3VdbeSetNumCols(v, 2);
+ setAllColumnNames(v, 2, azCol); assert( 2==ArraySize(azCol) );
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";
@@ -93352,38 +108706,42 @@ SQLITE_PRIVATE void sqlite3Pragma(
SQLITE_FCNTL_LOCKSTATE, &j)==SQLITE_OK ){
zState = azLockName[j];
}
- sqlite3VdbeAddOp4(v, OP_String8, 0, 2, 0, zState, P4_STATIC);
+ sqlite3VdbeMultiLoad(v, 1, "ss", db->aDb[i].zName, zState);
sqlite3VdbeAddOp2(v, OP_ResultRow, 1, 2);
}
-
- }else
+ break;
+ }
#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);
+ case PragTyp_KEY: {
+ if( zRight ) sqlite3_key_v2(db, zDb, zRight, sqlite3Strlen30(zRight));
+ break;
+ }
+ case PragTyp_REKEY: {
+ if( zRight ) sqlite3_rekey_v2(db, zDb, zRight, sqlite3Strlen30(zRight));
+ break;
+ }
+ case PragTyp_HEXKEY: {
+ if( zRight ){
+ u8 iByte;
+ int i;
+ char zKey[40];
+ for(i=0, iByte=0; i<sizeof(zKey)*2 && sqlite3Isxdigit(zRight[i]); i++){
+ iByte = (iByte<<4) + sqlite3HexToInt(zRight[i]);
+ if( (i&1)!=0 ) zKey[i/2] = iByte;
+ }
+ if( (zLeft[3] & 0xf)==0xb ){
+ sqlite3_key_v2(db, zDb, zKey, i/2);
+ }else{
+ sqlite3_rekey_v2(db, zDb, zKey, i/2);
+ }
}
- }else
+ break;
+ }
#endif
#if defined(SQLITE_HAS_CODEC) || defined(SQLITE_ENABLE_CEROD)
- if( sqlite3StrICmp(zLeft, "activate_extensions")==0 ){
+ case PragTyp_ACTIVATE_EXTENSIONS: if( zRight ){
#ifdef SQLITE_HAS_CODEC
if( sqlite3StrNICmp(zRight, "see-", 4)==0 ){
sqlite3_activate_see(&zRight[4]);
@@ -93394,23 +108752,12 @@ SQLITE_PRIVATE void sqlite3Pragma(
sqlite3_activate_cerod(&zRight[6]);
}
#endif
- }else
+ }
+ break;
#endif
-
- {/* Empty ELSE clause */}
+ } /* End of the PRAGMA switch */
- /*
- ** 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);
@@ -93435,6 +108782,7 @@ pragma_out:
** interface, and routines that contribute to loading the database schema
** from disk.
*/
+/* #include "sqliteInt.h" */
/*
** Fill the InitData structure with an error message that indicates
@@ -93447,13 +108795,13 @@ static void corruptSchema(
){
sqlite3 *db = pData->db;
if( !db->mallocFailed && (db->flags & SQLITE_RecoveryMode)==0 ){
+ char *z;
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);
- }
+ z = sqlite3_mprintf("malformed database schema (%s)", zObj);
+ if( z && zExtra ) z = sqlite3_mprintf("%z - %s", z, zExtra);
+ sqlite3DbFree(db, *pData->pzErrMsg);
+ *pData->pzErrMsg = z;
+ if( z==0 ) db->mallocFailed = 1;
}
pData->rc = db->mallocFailed ? SQLITE_NOMEM : SQLITE_CORRUPT_BKPT;
}
@@ -93488,7 +108836,7 @@ SQLITE_PRIVATE int sqlite3InitCallback(void *pInit, int argc, char **argv, char
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] ){
+ }else if( sqlite3_strnicmp(argv[2],"create ",7)==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
@@ -93519,8 +108867,8 @@ SQLITE_PRIVATE int sqlite3InitCallback(void *pInit, int argc, char **argv, char
}
}
sqlite3_finalize(pStmt);
- }else if( argv[0]==0 ){
- corruptSchema(pData, 0, 0);
+ }else if( argv[0]==0 || (argv[2]!=0 && argv[2][0]!=0) ){
+ corruptSchema(pData, argv[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
@@ -93600,7 +108948,7 @@ static int sqlite3InitOne(sqlite3 *db, int iDb, char **pzErrMsg){
/* 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.
+ ** initialized. zMasterName is the name of the master table.
*/
if( !OMIT_TEMPDB && iDb==1 ){
zMasterSchema = temp_master_schema;
@@ -93645,7 +108993,7 @@ static int sqlite3InitOne(sqlite3 *db, int iDb, char **pzErrMsg){
if( !sqlite3BtreeIsInReadTrans(pDb->pBt) ){
rc = sqlite3BtreeBeginTrans(pDb->pBt, 0);
if( rc!=SQLITE_OK ){
- sqlite3SetString(pzErrMsg, db, "%s", sqlite3ErrStr(rc));
+ sqlite3SetString(pzErrMsg, db, sqlite3ErrStr(rc));
goto initone_error_out;
}
openedTransaction = 1;
@@ -93680,11 +109028,15 @@ static int sqlite3InitOne(sqlite3 *db, int iDb, char **pzErrMsg){
*/
if( meta[BTREE_TEXT_ENCODING-1] ){ /* text encoding */
if( iDb==0 ){
+#ifndef SQLITE_OMIT_UTF16
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
+ ENC(db) = SQLITE_UTF8;
+#endif
}else{
/* If opening an attached database, the encoding much match ENC(db) */
if( meta[BTREE_TEXT_ENCODING-1]!=ENC(db) ){
@@ -93745,7 +109097,7 @@ static int sqlite3InitOne(sqlite3 *db, int iDb, char **pzErrMsg){
db->aDb[iDb].zName, zMasterName);
#ifndef SQLITE_OMIT_AUTHORIZATION
{
- int (*xAuth)(void*,int,const char*,const char*,const char*,const char*);
+ sqlite3_xauth xAuth;
xAuth = db->xAuth;
db->xAuth = 0;
#endif
@@ -93811,8 +109163,11 @@ SQLITE_PRIVATE int sqlite3Init(sqlite3 *db, char **pzErrMsg){
int commit_internal = !(db->flags&SQLITE_InternChanges);
assert( sqlite3_mutex_held(db->mutex) );
+ assert( sqlite3BtreeHoldsMutex(db->aDb[0].pBt) );
+ assert( db->init.busy==0 );
rc = SQLITE_OK;
db->init.busy = 1;
+ ENC(db) = SCHEMA_ENC(db);
for(i=0; rc==SQLITE_OK && i<db->nDb; i++){
if( DbHasProperty(db, i, DB_SchemaLoaded) || i==1 ) continue;
rc = sqlite3InitOne(db, i, pzErrMsg);
@@ -93821,13 +109176,13 @@ SQLITE_PRIVATE int sqlite3Init(sqlite3 *db, char **pzErrMsg){
}
}
- /* Once all the other databases have been initialised, load the schema
+ /* Once all the other databases have been initialized, 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) ){
+ assert( db->nDb>1 );
+ if( rc==SQLITE_OK && !DbHasProperty(db, 1, DB_SchemaLoaded) ){
rc = sqlite3InitOne(db, 1, pzErrMsg);
if( rc ){
sqlite3ResetOneSchema(db, 1);
@@ -93844,7 +109199,7 @@ SQLITE_PRIVATE int sqlite3Init(sqlite3 *db, char **pzErrMsg){
}
/*
-** This routine is a no-op if the database schema is already initialised.
+** This routine is a no-op if the database schema is already initialized.
** Otherwise, the schema is loaded. An error code is returned.
*/
SQLITE_PRIVATE int sqlite3ReadSchema(Parse *pParse){
@@ -93942,6 +109297,17 @@ SQLITE_PRIVATE int sqlite3SchemaToIndex(sqlite3 *db, Schema *pSchema){
}
/*
+** Free all memory allocations in the pParse object
+*/
+SQLITE_PRIVATE void sqlite3ParserReset(Parse *pParse){
+ if( pParse ){
+ sqlite3 *db = pParse->db;
+ sqlite3DbFree(db, pParse->aLabel);
+ sqlite3ExprListDelete(db, pParse->pConstExpr);
+ }
+}
+
+/*
** Compile the UTF-8 encoded SQL statement zSql into a statement handle.
*/
static int sqlite3Prepare(
@@ -93999,7 +109365,7 @@ static int sqlite3Prepare(
rc = sqlite3BtreeSchemaLocked(pBt);
if( rc ){
const char *zDb = db->aDb[i].zName;
- sqlite3Error(db, rc, "database schema is locked: %s", zDb);
+ sqlite3ErrorWithMsg(db, rc, "database schema is locked: %s", zDb);
testcase( db->flags & SQLITE_ReadUncommitted );
goto end_prepare;
}
@@ -94009,14 +109375,14 @@ static int sqlite3Prepare(
sqlite3VtabUnlockList(db);
pParse->db = db;
- pParse->nQueryLoop = (double)1;
+ pParse->nQueryLoop = 0; /* Logarithmic, so 0 really means 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");
+ sqlite3ErrorWithMsg(db, SQLITE_TOOBIG, "statement too long");
rc = sqlite3ApiExit(db, SQLITE_TOOBIG);
goto end_prepare;
}
@@ -94031,7 +109397,7 @@ static int sqlite3Prepare(
}else{
sqlite3RunParser(pParse, zSql, &zErrMsg);
}
- assert( 1==(int)pParse->nQueryLoop );
+ assert( 0==pParse->nQueryLoop );
if( db->mallocFailed ){
pParse->rc = SQLITE_NOMEM;
@@ -94071,7 +109437,6 @@ static int sqlite3Prepare(
}
#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);
@@ -94084,10 +109449,10 @@ static int sqlite3Prepare(
}
if( zErrMsg ){
- sqlite3Error(db, rc, "%s", zErrMsg);
+ sqlite3ErrorWithMsg(db, rc, "%s", zErrMsg);
sqlite3DbFree(db, zErrMsg);
}else{
- sqlite3Error(db, rc, 0);
+ sqlite3Error(db, rc);
}
/* Delete any TriggerPrg structures allocated while parsing this statement. */
@@ -94099,6 +109464,7 @@ static int sqlite3Prepare(
end_prepare:
+ sqlite3ParserReset(pParse);
sqlite3StackFree(db, pParse);
rc = sqlite3ApiExit(db, rc);
assert( (rc&db->errMask)==rc );
@@ -94114,9 +109480,12 @@ static int sqlite3LockAndPrepare(
const char **pzTail /* OUT: End of parsed string */
){
int rc;
- assert( ppStmt!=0 );
+
+#ifdef SQLITE_ENABLE_API_ARMOR
+ if( ppStmt==0 ) return SQLITE_MISUSE_BKPT;
+#endif
*ppStmt = 0;
- if( !sqlite3SafetyCheckOk(db) ){
+ if( !sqlite3SafetyCheckOk(db)||zSql==0 ){
return SQLITE_MISUSE_BKPT;
}
sqlite3_mutex_enter(db->mutex);
@@ -94177,7 +109546,7 @@ SQLITE_PRIVATE int sqlite3Reprepare(Vdbe *p){
** and the statement is automatically recompiled if an schema change
** occurs.
*/
-SQLITE_API int sqlite3_prepare(
+SQLITE_API int SQLITE_STDCALL sqlite3_prepare(
sqlite3 *db, /* Database handle. */
const char *zSql, /* UTF-8 encoded SQL statement. */
int nBytes, /* Length of zSql in bytes. */
@@ -94189,7 +109558,7 @@ SQLITE_API int sqlite3_prepare(
assert( rc==SQLITE_OK || ppStmt==0 || *ppStmt==0 ); /* VERIFY: F13021 */
return rc;
}
-SQLITE_API int sqlite3_prepare_v2(
+SQLITE_API int SQLITE_STDCALL sqlite3_prepare_v2(
sqlite3 *db, /* Database handle. */
const char *zSql, /* UTF-8 encoded SQL statement. */
int nBytes, /* Length of zSql in bytes. */
@@ -94223,11 +109592,19 @@ static int sqlite3Prepare16(
const char *zTail8 = 0;
int rc = SQLITE_OK;
- assert( ppStmt );
+#ifdef SQLITE_ENABLE_API_ARMOR
+ if( ppStmt==0 ) return SQLITE_MISUSE_BKPT;
+#endif
*ppStmt = 0;
- if( !sqlite3SafetyCheckOk(db) ){
+ if( !sqlite3SafetyCheckOk(db)||zSql==0 ){
return SQLITE_MISUSE_BKPT;
}
+ if( nBytes>=0 ){
+ int sz;
+ const char *z = (const char*)zSql;
+ for(sz=0; sz<nBytes && (z[sz]!=0 || z[sz+1]!=0); sz += 2){}
+ nBytes = sz;
+ }
sqlite3_mutex_enter(db->mutex);
zSql8 = sqlite3Utf16to8(db, zSql, nBytes, SQLITE_UTF16NATIVE);
if( zSql8 ){
@@ -94257,7 +109634,7 @@ static int sqlite3Prepare16(
** and the statement is automatically recompiled if an schema change
** occurs.
*/
-SQLITE_API int sqlite3_prepare16(
+SQLITE_API int SQLITE_STDCALL sqlite3_prepare16(
sqlite3 *db, /* Database handle. */
const void *zSql, /* UTF-16 encoded SQL statement. */
int nBytes, /* Length of zSql in bytes. */
@@ -94269,7 +109646,7 @@ SQLITE_API int sqlite3_prepare16(
assert( rc==SQLITE_OK || ppStmt==0 || *ppStmt==0 ); /* VERIFY: F13021 */
return rc;
}
-SQLITE_API int sqlite3_prepare16_v2(
+SQLITE_API int SQLITE_STDCALL sqlite3_prepare16_v2(
sqlite3 *db, /* Database handle. */
const void *zSql, /* UTF-16 encoded SQL statement. */
int nBytes, /* Length of zSql in bytes. */
@@ -94300,22 +109677,73 @@ SQLITE_API int sqlite3_prepare16_v2(
** This file contains C code routines that are called by the parser
** to handle SELECT statements in SQLite.
*/
+/* #include "sqliteInt.h" */
+
+/*
+** Trace output macros
+*/
+#if SELECTTRACE_ENABLED
+/***/ int sqlite3SelectTrace = 0;
+# define SELECTTRACE(K,P,S,X) \
+ if(sqlite3SelectTrace&(K)) \
+ sqlite3DebugPrintf("%*s%s.%p: ",(P)->nSelectIndent*2-2,"",\
+ (S)->zSelName,(S)),\
+ sqlite3DebugPrintf X
+#else
+# define SELECTTRACE(K,P,S,X)
+#endif
/*
-** Delete all the content of a Select structure but do not deallocate
-** the select structure itself.
+** 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.
*/
-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);
+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 */
+};
+
+/*
+** An instance of the following object is used to record information about
+** the ORDER BY (or GROUP BY) clause of query is being coded.
+*/
+typedef struct SortCtx SortCtx;
+struct SortCtx {
+ ExprList *pOrderBy; /* The ORDER BY (or GROUP BY clause) */
+ int nOBSat; /* Number of ORDER BY terms satisfied by indices */
+ int iECursor; /* Cursor number for the sorter */
+ int regReturn; /* Register holding block-output return address */
+ int labelBkOut; /* Start label for the block-output subroutine */
+ int addrSortIndex; /* Address of the OP_SorterOpen or OP_OpenEphemeral */
+ int labelDone; /* Jump here when done, ex: LIMIT reached */
+ u8 sortFlags; /* Zero or more SORTFLAG_* bits */
+};
+#define SORTFLAG_UseSorter 0x01 /* Use SorterOpen instead of OpenEphemeral */
+
+/*
+** Delete all the content of a Select structure. Deallocate the structure
+** itself only if bFree is true.
+*/
+static void clearSelect(sqlite3 *db, Select *p, int bFree){
+ while( p ){
+ Select *pPrior = p->pPrior;
+ sqlite3ExprListDelete(db, p->pEList);
+ sqlite3SrcListDelete(db, p->pSrc);
+ sqlite3ExprDelete(db, p->pWhere);
+ sqlite3ExprListDelete(db, p->pGroupBy);
+ sqlite3ExprDelete(db, p->pHaving);
+ sqlite3ExprListDelete(db, p->pOrderBy);
+ sqlite3ExprDelete(db, p->pLimit);
+ sqlite3ExprDelete(db, p->pOffset);
+ sqlite3WithDelete(db, p->pWith);
+ if( bFree ) sqlite3DbFree(db, p);
+ p = pPrior;
+ bFree = 1;
+ }
}
/*
@@ -94342,7 +109770,7 @@ SQLITE_PRIVATE Select *sqlite3SelectNew(
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 */
+ u16 selFlags, /* Flag parameters, such as SF_Distinct */
Expr *pLimit, /* LIMIT value. NULL means not used */
Expr *pOffset /* OFFSET value. NULL means no offset */
){
@@ -94350,14 +109778,13 @@ SQLITE_PRIVATE Select *sqlite3SelectNew(
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));
+ pEList = sqlite3ExprListAppend(pParse, 0, sqlite3Expr(db,TK_ASTERISK,0));
}
pNew->pEList = pEList;
if( pSrc==0 ) pSrc = sqlite3DbMallocZero(db, sizeof(*pSrc));
@@ -94366,17 +109793,15 @@ SQLITE_PRIVATE Select *sqlite3SelectNew(
pNew->pGroupBy = pGroupBy;
pNew->pHaving = pHaving;
pNew->pOrderBy = pOrderBy;
- pNew->selFlags = isDistinct ? SF_Distinct : 0;
+ pNew->selFlags = selFlags;
pNew->op = TK_SELECT;
pNew->pLimit = pLimit;
pNew->pOffset = pOffset;
- assert( pOffset==0 || pLimit!=0 );
+ assert( pOffset==0 || pLimit!=0 || pParse->nErr>0 || db->mallocFailed!=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);
+ clearSelect(db, pNew, pNew!=&standin);
pNew = 0;
}else{
assert( pNew->pSrc!=0 || pParse->nErr>0 );
@@ -94385,18 +109810,35 @@ SQLITE_PRIVATE Select *sqlite3SelectNew(
return pNew;
}
+#if SELECTTRACE_ENABLED
+/*
+** Set the name of a Select object
+*/
+SQLITE_PRIVATE void sqlite3SelectSetName(Select *p, const char *zName){
+ if( p && zName ){
+ sqlite3_snprintf(sizeof(p->zSelName), p->zSelName, "%s", zName);
+ }
+}
+#endif
+
+
/*
** 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);
- }
+ clearSelect(db, p, 1);
}
/*
-** Given 1 to 3 identifiers preceeding the JOIN keyword, determine the
+** Return a pointer to the right-most SELECT statement in a compound.
+*/
+static Select *findRightmost(Select *p){
+ while( p->pNext ) p = p->pNext;
+ return p;
+}
+
+/*
+** Given 1 to 3 identifiers preceding the JOIN keyword, determine the
** type of join. Return an integer constant that expresses that type
** in terms of the following bit values:
**
@@ -94551,8 +109993,8 @@ static void addWhereTerm(
pEq = sqlite3PExpr(pParse, TK_EQ, pE1, pE2, 0);
if( pEq && isOuterJoin ){
ExprSetProperty(pEq, EP_FromJoin);
- assert( !ExprHasAnyProperty(pEq, EP_TokenOnly|EP_Reduced) );
- ExprSetIrreducible(pEq);
+ assert( !ExprHasProperty(pEq, EP_TokenOnly|EP_Reduced) );
+ ExprSetVVAProperty(pEq, EP_NoReduce);
pEq->iRightJoinTable = (i16)pE2->iTable;
}
*ppWhere = sqlite3ExprAnd(db, *ppWhere, pEq);
@@ -94587,9 +110029,15 @@ static void addWhereTerm(
static void setJoinExpr(Expr *p, int iTable){
while( p ){
ExprSetProperty(p, EP_FromJoin);
- assert( !ExprHasAnyProperty(p, EP_TokenOnly|EP_Reduced) );
- ExprSetIrreducible(p);
+ assert( !ExprHasProperty(p, EP_TokenOnly|EP_Reduced) );
+ ExprSetVVAProperty(p, EP_NoReduce);
p->iRightJoinTable = (i16)iTable;
+ if( p->op==TK_FUNCTION && p->x.pList ){
+ int i;
+ for(i=0; i<p->x.pList->nExpr; i++){
+ setJoinExpr(p->x.pList->a[i].pExpr, iTable);
+ }
+ }
setJoinExpr(p->pLeft, iTable);
p = p->pRight;
}
@@ -94624,12 +110072,12 @@ static int sqliteProcessJoin(Parse *pParse, Select *p){
int isOuter;
if( NEVER(pLeftTab==0 || pRightTab==0) ) continue;
- isOuter = (pRight->jointype & JT_OUTER)!=0;
+ isOuter = (pRight->fg.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->fg.jointype & JT_NATURAL ){
if( pRight->pOn || pRight->pUsing ){
sqlite3ErrorMsg(pParse, "a NATURAL join may not have "
"an ON or USING clause", 0);
@@ -94697,49 +110145,111 @@ static int sqliteProcessJoin(Parse *pParse, Select *p){
return 0;
}
+/* Forward reference */
+static KeyInfo *keyInfoFromExprList(
+ Parse *pParse, /* Parsing context */
+ ExprList *pList, /* Form the KeyInfo object from this ExprList */
+ int iStart, /* Begin with this column of pList */
+ int nExtra /* Add this many extra columns to the end */
+);
+
/*
-** Insert code into "v" that will push the record on the top of the
-** stack into the sorter.
+** Generate code that will push the record in registers regData
+** through regData+nData-1 onto the sorter.
*/
static void pushOntoSorter(
Parse *pParse, /* Parser context */
- ExprList *pOrderBy, /* The ORDER BY clause */
+ SortCtx *pSort, /* Information about 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 ){
+ int regData, /* First register holding data to be sorted */
+ int regOrigData, /* First register holding data before packing */
+ int nData, /* Number of elements in the data array */
+ int nPrefixReg /* No. of reg prior to regData available for use */
+){
+ Vdbe *v = pParse->pVdbe; /* Stmt under construction */
+ int bSeq = ((pSort->sortFlags & SORTFLAG_UseSorter)==0);
+ int nExpr = pSort->pOrderBy->nExpr; /* No. of ORDER BY terms */
+ int nBase = nExpr + bSeq + nData; /* Fields in sorter record */
+ int regBase; /* Regs for sorter record */
+ int regRecord = ++pParse->nMem; /* Assembled sorter record */
+ int nOBSat = pSort->nOBSat; /* ORDER BY terms to skip */
+ int op; /* Opcode to add sorter record to sorter */
+ int iLimit; /* LIMIT counter */
+
+ assert( bSeq==0 || bSeq==1 );
+ assert( nData==1 || regData==regOrigData );
+ if( nPrefixReg ){
+ assert( nPrefixReg==nExpr+bSeq );
+ regBase = regData - nExpr - bSeq;
+ }else{
+ regBase = pParse->nMem + 1;
+ pParse->nMem += nBase;
+ }
+ assert( pSelect->iOffset==0 || pSelect->iLimit!=0 );
+ iLimit = pSelect->iOffset ? pSelect->iOffset+1 : pSelect->iLimit;
+ pSort->labelDone = sqlite3VdbeMakeLabel(v);
+ sqlite3ExprCodeExprList(pParse, pSort->pOrderBy, regBase, regOrigData,
+ SQLITE_ECEL_DUP|SQLITE_ECEL_REF);
+ if( bSeq ){
+ sqlite3VdbeAddOp2(v, OP_Sequence, pSort->iECursor, regBase+nExpr);
+ }
+ if( nPrefixReg==0 ){
+ sqlite3ExprCodeMove(pParse, regData, regBase+nExpr+bSeq, nData);
+ }
+ sqlite3VdbeAddOp3(v, OP_MakeRecord, regBase+nOBSat, nBase-nOBSat, regRecord);
+ if( nOBSat>0 ){
+ int regPrevKey; /* The first nOBSat columns of the previous row */
+ int addrFirst; /* Address of the OP_IfNot opcode */
+ int addrJmp; /* Address of the OP_Jump opcode */
+ VdbeOp *pOp; /* Opcode that opens the sorter */
+ int nKey; /* Number of sorting key columns, including OP_Sequence */
+ KeyInfo *pKI; /* Original KeyInfo on the sorter table */
+
+ regPrevKey = pParse->nMem+1;
+ pParse->nMem += pSort->nOBSat;
+ nKey = nExpr - pSort->nOBSat + bSeq;
+ if( bSeq ){
+ addrFirst = sqlite3VdbeAddOp1(v, OP_IfNot, regBase+nExpr);
+ }else{
+ addrFirst = sqlite3VdbeAddOp1(v, OP_SequenceTest, pSort->iECursor);
+ }
+ VdbeCoverage(v);
+ sqlite3VdbeAddOp3(v, OP_Compare, regPrevKey, regBase, pSort->nOBSat);
+ pOp = sqlite3VdbeGetOp(v, pSort->addrSortIndex);
+ if( pParse->db->mallocFailed ) return;
+ pOp->p2 = nKey + nData;
+ pKI = pOp->p4.pKeyInfo;
+ memset(pKI->aSortOrder, 0, pKI->nField); /* Makes OP_Jump below testable */
+ sqlite3VdbeChangeP4(v, -1, (char*)pKI, P4_KEYINFO);
+ testcase( pKI->nXField>2 );
+ pOp->p4.pKeyInfo = keyInfoFromExprList(pParse, pSort->pOrderBy, nOBSat,
+ pKI->nXField-1);
+ addrJmp = sqlite3VdbeCurrentAddr(v);
+ sqlite3VdbeAddOp3(v, OP_Jump, addrJmp+1, 0, addrJmp+1); VdbeCoverage(v);
+ pSort->labelBkOut = sqlite3VdbeMakeLabel(v);
+ pSort->regReturn = ++pParse->nMem;
+ sqlite3VdbeAddOp2(v, OP_Gosub, pSort->regReturn, pSort->labelBkOut);
+ sqlite3VdbeAddOp1(v, OP_ResetSorter, pSort->iECursor);
+ if( iLimit ){
+ sqlite3VdbeAddOp2(v, OP_IfNot, iLimit, pSort->labelDone);
+ VdbeCoverage(v);
+ }
+ sqlite3VdbeJumpHere(v, addrFirst);
+ sqlite3ExprCodeMove(pParse, regBase, regPrevKey, pSort->nOBSat);
+ sqlite3VdbeJumpHere(v, addrJmp);
+ }
+ if( pSort->sortFlags & SORTFLAG_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);
+ sqlite3VdbeAddOp2(v, op, pSort->iECursor, regRecord);
+ if( iLimit ){
+ int addr;
+ addr = sqlite3VdbeAddOp3(v, OP_IfNotZero, iLimit, 0, 1); VdbeCoverage(v);
+ sqlite3VdbeAddOp1(v, OP_Last, pSort->iECursor);
+ sqlite3VdbeAddOp1(v, OP_Delete, pSort->iECursor);
+ sqlite3VdbeJumpHere(v, addr);
}
}
@@ -94748,16 +110258,12 @@ static void pushOntoSorter(
*/
static void codeOffset(
Vdbe *v, /* Generate code into this VM */
- Select *p, /* The SELECT statement being coded */
+ int iOffset, /* Register holding the offset counter */
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);
+ if( iOffset>0 ){
+ sqlite3VdbeAddOp3(v, OP_IfPos, iOffset, iContinue, 1); VdbeCoverage(v);
+ VdbeComment((v, "OFFSET"));
}
}
@@ -94782,7 +110288,7 @@ static void codeDistinct(
v = pParse->pVdbe;
r1 = sqlite3GetTempReg(pParse);
- sqlite3VdbeAddOp4Int(v, OP_Found, iTab, addrRepeat, iMem, N);
+ sqlite3VdbeAddOp4Int(v, OP_Found, iTab, addrRepeat, iMem, N); VdbeCoverage(v);
sqlite3VdbeAddOp3(v, OP_MakeRecord, iMem, N, r1);
sqlite3VdbeAddOp2(v, OP_IdxInsert, iTab, r1);
sqlite3ReleaseTempReg(pParse, r1);
@@ -94813,34 +110319,20 @@ static int checkForMultiColumnSelectError(
#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.
+** If srcTab is negative, then the pEList expressions
+** are evaluated in order to get the data for this row. If srcTab is
+** zero or more, then data is pulled from srcTab and pEList is used only
+** to get number columns and the datatype 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 */
+ SortCtx *pSort, /* If not NULL, info on how to process ORDER BY */
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 */
@@ -94853,50 +110345,62 @@ static void selectInnerLoop(
int eDest = pDest->eDest; /* How to dispose of results */
int iParm = pDest->iSDParm; /* First argument to disposal method */
int nResultCol; /* Number of result columns */
+ int nPrefixReg = 0; /* Number of extra registers before regResult */
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);
+ if( pSort && pSort->pOrderBy==0 ) pSort = 0;
+ if( pSort==0 && !hasDistinct ){
+ assert( iContinue!=0 );
+ codeOffset(v, p->iOffset, iContinue);
}
/* Pull the requested columns.
*/
- if( nColumn>0 ){
- nResultCol = nColumn;
- }else{
- nResultCol = pEList->nExpr;
- }
+ nResultCol = pEList->nExpr;
+
if( pDest->iSdst==0 ){
+ if( pSort ){
+ nPrefixReg = pSort->pOrderBy->nExpr;
+ if( !(pSort->sortFlags & SORTFLAG_UseSorter) ) nPrefixReg++;
+ pParse->nMem += nPrefixReg;
+ }
pDest->iSdst = pParse->nMem+1;
- pDest->nSdst = nResultCol;
pParse->nMem += nResultCol;
- }else{
- assert( pDest->nSdst==nResultCol );
+ }else if( pDest->iSdst+nResultCol > pParse->nMem ){
+ /* This is an error condition that can result, for example, when a SELECT
+ ** on the right-hand side of an INSERT contains more result columns than
+ ** there are columns in the table on the left. The error will be caught
+ ** and reported later. But we need to make sure enough memory is allocated
+ ** to avoid other spurious errors in the meantime. */
+ pParse->nMem += nResultCol;
}
+ pDest->nSdst = nResultCol;
regResult = pDest->iSdst;
- if( nColumn>0 ){
- for(i=0; i<nColumn; i++){
+ if( srcTab>=0 ){
+ for(i=0; i<nResultCol; i++){
sqlite3VdbeAddOp3(v, OP_Column, srcTab, i, regResult+i);
+ VdbeComment((v, "%s", pEList->a[i].zName));
}
}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);
+ u8 ecelFlags;
+ if( eDest==SRT_Mem || eDest==SRT_Output || eDest==SRT_Coroutine ){
+ ecelFlags = SQLITE_ECEL_DUP;
+ }else{
+ ecelFlags = 0;
+ }
+ sqlite3ExprCodeExprList(pParse, pEList, regResult, 0, ecelFlags);
}
- 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. */
@@ -94905,7 +110409,7 @@ static void selectInnerLoop(
/* Allocate space for the previous row */
regPrev = pParse->nMem+1;
- pParse->nMem += nColumn;
+ pParse->nMem += nResultCol;
/* Change the OP_OpenEphemeral coded earlier to an OP_Null
** sets the MEM_Cleared bit on the first register of the
@@ -94919,19 +110423,21 @@ static void selectInnerLoop(
pOp->p1 = 1;
pOp->p2 = regPrev;
- iJump = sqlite3VdbeCurrentAddr(v) + nColumn;
- for(i=0; i<nColumn; i++){
+ iJump = sqlite3VdbeCurrentAddr(v) + nResultCol;
+ for(i=0; i<nResultCol; i++){
CollSeq *pColl = sqlite3ExprCollSeq(pParse, pEList->a[i].pExpr);
- if( i<nColumn-1 ){
+ if( i<nResultCol-1 ){
sqlite3VdbeAddOp3(v, OP_Ne, regResult+i, iJump, regPrev+i);
+ VdbeCoverage(v);
}else{
sqlite3VdbeAddOp3(v, OP_Eq, regResult+i, iContinue, regPrev+i);
- }
+ VdbeCoverage(v);
+ }
sqlite3VdbeChangeP4(v, -1, (const char *)pColl, P4_COLLSEQ);
sqlite3VdbeChangeP5(v, SQLITE_NULLEQ);
}
- assert( sqlite3VdbeCurrentAddr(v)==iJump );
- sqlite3VdbeAddOp3(v, OP_Copy, regResult, regPrev, nColumn-1);
+ assert( sqlite3VdbeCurrentAddr(v)==iJump || pParse->db->mallocFailed );
+ sqlite3VdbeAddOp3(v, OP_Copy, regResult, regPrev, nResultCol-1);
break;
}
@@ -94942,12 +110448,13 @@ static void selectInnerLoop(
default: {
assert( pDistinct->eTnctType==WHERE_DISTINCT_UNORDERED );
- codeDistinct(pParse, pDistinct->tabTnct, iContinue, nColumn, regResult);
+ codeDistinct(pParse, pDistinct->tabTnct, iContinue, nResultCol,
+ regResult);
break;
}
}
- if( pOrderBy==0 ){
- codeOffset(v, p, iContinue);
+ if( pSort==0 ){
+ codeOffset(v, p->iOffset, iContinue);
}
}
@@ -94959,7 +110466,7 @@ static void selectInnerLoop(
case SRT_Union: {
int r1;
r1 = sqlite3GetTempReg(pParse);
- sqlite3VdbeAddOp3(v, OP_MakeRecord, regResult, nColumn, r1);
+ sqlite3VdbeAddOp3(v, OP_MakeRecord, regResult, nResultCol, r1);
sqlite3VdbeAddOp2(v, OP_IdxInsert, iParm, r1);
sqlite3ReleaseTempReg(pParse, r1);
break;
@@ -94970,21 +110477,39 @@ static void selectInnerLoop(
** the temporary table iParm.
*/
case SRT_Except: {
- sqlite3VdbeAddOp3(v, OP_IdxDelete, iParm, regResult, nColumn);
+ sqlite3VdbeAddOp3(v, OP_IdxDelete, iParm, regResult, nResultCol);
break;
}
-#endif
+#endif /* SQLITE_OMIT_COMPOUND_SELECT */
/* Store the result as data using a unique key.
*/
+ case SRT_Fifo:
+ case SRT_DistFifo:
case SRT_Table:
case SRT_EphemTab: {
- int r1 = sqlite3GetTempReg(pParse);
+ int r1 = sqlite3GetTempRange(pParse, nPrefixReg+1);
testcase( eDest==SRT_Table );
testcase( eDest==SRT_EphemTab );
- sqlite3VdbeAddOp3(v, OP_MakeRecord, regResult, nColumn, r1);
- if( pOrderBy ){
- pushOntoSorter(pParse, pOrderBy, p, r1);
+ testcase( eDest==SRT_Fifo );
+ testcase( eDest==SRT_DistFifo );
+ sqlite3VdbeAddOp3(v, OP_MakeRecord, regResult, nResultCol, r1+nPrefixReg);
+#ifndef SQLITE_OMIT_CTE
+ if( eDest==SRT_DistFifo ){
+ /* If the destination is DistFifo, then cursor (iParm+1) is open
+ ** on an ephemeral index. If the current row is already present
+ ** in the index, do not write it to the output. If not, add the
+ ** current row to the index and proceed with writing it to the
+ ** output table as well. */
+ int addr = sqlite3VdbeCurrentAddr(v) + 4;
+ sqlite3VdbeAddOp4Int(v, OP_Found, iParm+1, addr, r1, 0);
+ VdbeCoverage(v);
+ sqlite3VdbeAddOp2(v, OP_IdxInsert, iParm+1, r1);
+ assert( pSort==0 );
+ }
+#endif
+ if( pSort ){
+ pushOntoSorter(pParse, pSort, p, r1+nPrefixReg,regResult,1,nPrefixReg);
}else{
int r2 = sqlite3GetTempReg(pParse);
sqlite3VdbeAddOp2(v, OP_NewRowid, iParm, r2);
@@ -94992,7 +110517,7 @@ static void selectInnerLoop(
sqlite3VdbeChangeP5(v, OPFLAG_APPEND);
sqlite3ReleaseTempReg(pParse, r2);
}
- sqlite3ReleaseTempReg(pParse, r1);
+ sqlite3ReleaseTempRange(pParse, r1, nPrefixReg+1);
break;
}
@@ -95002,15 +110527,15 @@ static void selectInnerLoop(
** item into the set table with bogus data.
*/
case SRT_Set: {
- assert( nColumn==1 );
+ assert( nResultCol==1 );
pDest->affSdst =
sqlite3CompareAffinity(pEList->a[0].pExpr, pDest->affSdst);
- if( pOrderBy ){
+ if( pSort ){
/* 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);
+ pushOntoSorter(pParse, pSort, p, regResult, regResult, 1, nPrefixReg);
}else{
int r1 = sqlite3GetTempReg(pParse);
sqlite3VdbeAddOp4(v, OP_MakeRecord, regResult,1,r1, &pDest->affSdst, 1);
@@ -95034,39 +110559,82 @@ static void selectInnerLoop(
** of the scan loop.
*/
case SRT_Mem: {
- assert( nColumn==1 );
- if( pOrderBy ){
- pushOntoSorter(pParse, pOrderBy, p, regResult);
+ assert( nResultCol==1 );
+ if( pSort ){
+ pushOntoSorter(pParse, pSort, p, regResult, regResult, 1, nPrefixReg);
}else{
- sqlite3ExprCodeMove(pParse, regResult, iParm, 1);
+ assert( regResult==iParm );
/* 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: {
+ case SRT_Coroutine: /* Send data to a co-routine */
+ case SRT_Output: { /* Return the results */
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);
+ if( pSort ){
+ pushOntoSorter(pParse, pSort, p, regResult, regResult, nResultCol,
+ nPrefixReg);
}else if( eDest==SRT_Coroutine ){
sqlite3VdbeAddOp1(v, OP_Yield, pDest->iSDParm);
}else{
- sqlite3VdbeAddOp2(v, OP_ResultRow, regResult, nColumn);
- sqlite3ExprCacheAffinityChange(pParse, regResult, nColumn);
+ sqlite3VdbeAddOp2(v, OP_ResultRow, regResult, nResultCol);
+ sqlite3ExprCacheAffinityChange(pParse, regResult, nResultCol);
}
break;
}
+#ifndef SQLITE_OMIT_CTE
+ /* Write the results into a priority queue that is order according to
+ ** pDest->pOrderBy (in pSO). pDest->iSDParm (in iParm) is the cursor for an
+ ** index with pSO->nExpr+2 columns. Build a key using pSO for the first
+ ** pSO->nExpr columns, then make sure all keys are unique by adding a
+ ** final OP_Sequence column. The last column is the record as a blob.
+ */
+ case SRT_DistQueue:
+ case SRT_Queue: {
+ int nKey;
+ int r1, r2, r3;
+ int addrTest = 0;
+ ExprList *pSO;
+ pSO = pDest->pOrderBy;
+ assert( pSO );
+ nKey = pSO->nExpr;
+ r1 = sqlite3GetTempReg(pParse);
+ r2 = sqlite3GetTempRange(pParse, nKey+2);
+ r3 = r2+nKey+1;
+ if( eDest==SRT_DistQueue ){
+ /* If the destination is DistQueue, then cursor (iParm+1) is open
+ ** on a second ephemeral index that holds all values every previously
+ ** added to the queue. */
+ addrTest = sqlite3VdbeAddOp4Int(v, OP_Found, iParm+1, 0,
+ regResult, nResultCol);
+ VdbeCoverage(v);
+ }
+ sqlite3VdbeAddOp3(v, OP_MakeRecord, regResult, nResultCol, r3);
+ if( eDest==SRT_DistQueue ){
+ sqlite3VdbeAddOp2(v, OP_IdxInsert, iParm+1, r3);
+ sqlite3VdbeChangeP5(v, OPFLAG_USESEEKRESULT);
+ }
+ for(i=0; i<nKey; i++){
+ sqlite3VdbeAddOp2(v, OP_SCopy,
+ regResult + pSO->a[i].u.x.iOrderByCol - 1,
+ r2+i);
+ }
+ sqlite3VdbeAddOp2(v, OP_Sequence, iParm, r2+nKey);
+ sqlite3VdbeAddOp3(v, OP_MakeRecord, r2, nKey+2, r1);
+ sqlite3VdbeAddOp2(v, OP_IdxInsert, iParm, r1);
+ if( addrTest ) sqlite3VdbeJumpHere(v, addrTest);
+ sqlite3ReleaseTempReg(pParse, r1);
+ sqlite3ReleaseTempRange(pParse, r2, nKey+2);
+ break;
+ }
+#endif /* SQLITE_OMIT_CTE */
+
+
+
#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
@@ -95084,12 +110652,64 @@ static void selectInnerLoop(
** 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);
+ if( pSort==0 && p->iLimit ){
+ sqlite3VdbeAddOp2(v, OP_DecrJumpZero, p->iLimit, iBreak); VdbeCoverage(v);
}
}
/*
+** Allocate a KeyInfo object sufficient for an index of N key columns and
+** X extra columns.
+*/
+SQLITE_PRIVATE KeyInfo *sqlite3KeyInfoAlloc(sqlite3 *db, int N, int X){
+ KeyInfo *p = sqlite3DbMallocZero(0,
+ sizeof(KeyInfo) + (N+X)*(sizeof(CollSeq*)+1));
+ if( p ){
+ p->aSortOrder = (u8*)&p->aColl[N+X];
+ p->nField = (u16)N;
+ p->nXField = (u16)X;
+ p->enc = ENC(db);
+ p->db = db;
+ p->nRef = 1;
+ }else{
+ db->mallocFailed = 1;
+ }
+ return p;
+}
+
+/*
+** Deallocate a KeyInfo object
+*/
+SQLITE_PRIVATE void sqlite3KeyInfoUnref(KeyInfo *p){
+ if( p ){
+ assert( p->nRef>0 );
+ p->nRef--;
+ if( p->nRef==0 ) sqlite3DbFree(0, p);
+ }
+}
+
+/*
+** Make a new pointer to a KeyInfo object
+*/
+SQLITE_PRIVATE KeyInfo *sqlite3KeyInfoRef(KeyInfo *p){
+ if( p ){
+ assert( p->nRef>0 );
+ p->nRef++;
+ }
+ return p;
+}
+
+#ifdef SQLITE_DEBUG
+/*
+** Return TRUE if a KeyInfo object can be change. The KeyInfo object
+** can only be changed if this is just a single reference to the object.
+**
+** This routine is used only inside of assert() statements.
+*/
+SQLITE_PRIVATE int sqlite3KeyInfoIsWriteable(KeyInfo *p){ return p->nRef==1; }
+#endif /* SQLITE_DEBUG */
+
+/*
** Given an expression list, generate a KeyInfo structure that records
** the collating sequence for each expression in that expression list.
**
@@ -95099,39 +110719,37 @@ static void selectInnerLoop(
** 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
+** Space to hold the KeyInfo structure is obtained 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.
+** freed.
*/
-static KeyInfo *keyInfoFromExprList(Parse *pParse, ExprList *pList){
- sqlite3 *db = pParse->db;
+static KeyInfo *keyInfoFromExprList(
+ Parse *pParse, /* Parsing context */
+ ExprList *pList, /* Form the KeyInfo object from this ExprList */
+ int iStart, /* Begin with this column of pList */
+ int nExtra /* Add this many extra columns to the end */
+){
int nExpr;
KeyInfo *pInfo;
struct ExprList_item *pItem;
+ sqlite3 *db = pParse->db;
int i;
nExpr = pList->nExpr;
- pInfo = sqlite3DbMallocZero(db, sizeof(*pInfo) + nExpr*(sizeof(CollSeq*)+1) );
+ pInfo = sqlite3KeyInfoAlloc(db, nExpr-iStart, nExtra+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++){
+ assert( sqlite3KeyInfoIsWriteable(pInfo) );
+ for(i=iStart, pItem=pList->a+iStart; 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;
+ if( !pColl ) pColl = db->pDfltColl;
+ pInfo->aColl[i-iStart] = pColl;
+ pInfo->aSortOrder[i-iStart] = pItem->sortOrder;
}
}
return pInfo;
}
-#ifndef SQLITE_OMIT_COMPOUND_SELECT
/*
** Name of the connection operator, used for error messages.
*/
@@ -95145,7 +110763,6 @@ static const char *selectOpName(int id){
}
return z;
}
-#endif /* SQLITE_OMIT_COMPOUND_SELECT */
#ifndef SQLITE_OMIT_EXPLAIN
/*
@@ -95227,51 +110844,72 @@ static void explainComposite(
static void generateSortTail(
Parse *pParse, /* Parsing context */
Select *p, /* The SELECT statement */
- Vdbe *v, /* Generate code into this VDBE */
+ SortCtx *pSort, /* Information on the ORDER BY clause */
int nColumn, /* Number of columns of data */
SelectDest *pDest /* Write the sorted results here */
){
- int addrBreak = sqlite3VdbeMakeLabel(v); /* Jump here to exit loop */
+ Vdbe *v = pParse->pVdbe; /* The prepared statement */
+ int addrBreak = pSort->labelDone; /* Jump here to exit loop */
int addrContinue = sqlite3VdbeMakeLabel(v); /* Jump here for next cycle */
int addr;
+ int addrOnce = 0;
int iTab;
- int pseudoTab = 0;
- ExprList *pOrderBy = p->pOrderBy;
-
+ ExprList *pOrderBy = pSort->pOrderBy;
int eDest = pDest->eDest;
int iParm = pDest->iSDParm;
-
int regRow;
int regRowid;
+ int nKey;
+ int iSortTab; /* Sorter cursor to read from */
+ int nSortData; /* Trailing values to read from sorter */
+ int i;
+ int bSeq; /* True if sorter record includes seq. no. */
+#ifdef SQLITE_ENABLE_EXPLAIN_COMMENTS
+ struct ExprList_item *aOutEx = p->pEList->a;
+#endif
- iTab = pOrderBy->iECursor;
- regRow = sqlite3GetTempReg(pParse);
+ assert( addrBreak<0 );
+ if( pSort->labelBkOut ){
+ sqlite3VdbeAddOp2(v, OP_Gosub, pSort->regReturn, pSort->labelBkOut);
+ sqlite3VdbeGoto(v, addrBreak);
+ sqlite3VdbeResolveLabel(v, pSort->labelBkOut);
+ }
+ iTab = pSort->iECursor;
if( eDest==SRT_Output || eDest==SRT_Coroutine ){
- pseudoTab = pParse->nTab++;
- sqlite3VdbeAddOp3(v, OP_OpenPseudo, pseudoTab, regRow, nColumn);
regRowid = 0;
+ regRow = pDest->iSdst;
+ nSortData = nColumn;
}else{
regRowid = sqlite3GetTempReg(pParse);
+ regRow = sqlite3GetTempReg(pParse);
+ nSortData = 1;
}
- if( p->selFlags & SF_UseSorter ){
+ nKey = pOrderBy->nExpr - pSort->nOBSat;
+ if( pSort->sortFlags & SORTFLAG_UseSorter ){
int regSortOut = ++pParse->nMem;
- int ptab2 = pParse->nTab++;
- sqlite3VdbeAddOp3(v, OP_OpenPseudo, ptab2, regSortOut, pOrderBy->nExpr+2);
+ iSortTab = pParse->nTab++;
+ if( pSort->labelBkOut ){
+ addrOnce = sqlite3CodeOnce(pParse); VdbeCoverage(v);
+ }
+ sqlite3VdbeAddOp3(v, OP_OpenPseudo, iSortTab, regSortOut, nKey+1+nSortData);
+ if( addrOnce ) sqlite3VdbeJumpHere(v, addrOnce);
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);
+ VdbeCoverage(v);
+ codeOffset(v, p->iOffset, addrContinue);
+ sqlite3VdbeAddOp3(v, OP_SorterData, iTab, regSortOut, iSortTab);
+ bSeq = 0;
}else{
- addr = 1 + sqlite3VdbeAddOp2(v, OP_Sort, iTab, addrBreak);
- codeOffset(v, p, addrContinue);
- sqlite3VdbeAddOp3(v, OP_Column, iTab, pOrderBy->nExpr+1, regRow);
+ addr = 1 + sqlite3VdbeAddOp2(v, OP_Sort, iTab, addrBreak); VdbeCoverage(v);
+ codeOffset(v, p->iOffset, addrContinue);
+ iSortTab = iTab;
+ bSeq = 1;
+ }
+ for(i=0; i<nSortData; i++){
+ sqlite3VdbeAddOp3(v, OP_Column, iSortTab, nKey+bSeq+i, regRow+i);
+ VdbeComment((v, "%s", aOutEx[i].zName ? aOutEx[i].zName : aOutEx[i].zSpan));
}
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);
@@ -95294,17 +110932,9 @@ static void generateSortTail(
}
#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);
@@ -95314,27 +110944,29 @@ static void generateSortTail(
break;
}
}
- sqlite3ReleaseTempReg(pParse, regRow);
- sqlite3ReleaseTempReg(pParse, regRowid);
-
+ if( regRowid ){
+ 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);
+ if( pSort->sortFlags & SORTFLAG_UseSorter ){
+ sqlite3VdbeAddOp2(v, OP_SorterNext, iTab, addr); VdbeCoverage(v);
}else{
- sqlite3VdbeAddOp2(v, OP_Next, iTab, addr);
+ sqlite3VdbeAddOp2(v, OP_Next, iTab, addr); VdbeCoverage(v);
}
+ if( pSort->regReturn ) sqlite3VdbeAddOp1(v, OP_Return, pSort->regReturn);
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.
**
+** Also try to estimate the size of the returned value and return that
+** result in *pEstWidth.
+**
** 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
@@ -95348,21 +110980,36 @@ static void generateSortTail(
** SELECT abc FROM (SELECT col AS abc FROM tbl);
**
** The declaration type for any expression other than a column is NULL.
+**
+** This routine has either 3 or 6 parameters depending on whether or not
+** the SQLITE_ENABLE_COLUMN_METADATA compile-time option is used.
*/
-static const char *columnType(
+#ifdef SQLITE_ENABLE_COLUMN_METADATA
+# define columnType(A,B,C,D,E,F) columnTypeImpl(A,B,C,D,E,F)
+#else /* if !defined(SQLITE_ENABLE_COLUMN_METADATA) */
+# define columnType(A,B,C,D,E,F) columnTypeImpl(A,B,F)
+#endif
+static const char *columnTypeImpl(
NameContext *pNC,
Expr *pExpr,
- const char **pzOriginDb,
- const char **pzOriginTab,
- const char **pzOriginCol
+#ifdef SQLITE_ENABLE_COLUMN_METADATA
+ const char **pzOrigDb,
+ const char **pzOrigTab,
+ const char **pzOrigCol,
+#endif
+ u8 *pEstWidth
){
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;
+ u8 estWidth = 1;
+#ifdef SQLITE_ENABLE_COLUMN_METADATA
+ char const *zOrigDb = 0;
+ char const *zOrigTab = 0;
+ char const *zOrigCol = 0;
+#endif
+ assert( pExpr!=0 );
+ assert( pNC->pSrcList!=0 );
switch( pExpr->op ){
case TK_AGG_COLUMN:
case TK_COLUMN: {
@@ -95417,31 +111064,44 @@ static const char *columnType(
/* 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.
+ **
+ ** The ALWAYS() is because iCol>=pS->pEList->nExpr will have been
+ ** caught already by name resolution.
*/
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);
+ zType = columnType(&sNC, p,&zOrigDb,&zOrigTab,&zOrigCol, &estWidth);
}
- }else if( ALWAYS(pTab->pSchema) ){
+ }else if( pTab->pSchema ){
/* A real table */
assert( !pS );
if( iCol<0 ) iCol = pTab->iPKey;
assert( iCol==-1 || (iCol>=0 && iCol<pTab->nCol) );
+#ifdef SQLITE_ENABLE_COLUMN_METADATA
if( iCol<0 ){
zType = "INTEGER";
- zOriginCol = "rowid";
+ zOrigCol = "rowid";
}else{
zType = pTab->aCol[iCol].zType;
- zOriginCol = pTab->aCol[iCol].zName;
+ zOrigCol = pTab->aCol[iCol].zName;
+ estWidth = pTab->aCol[iCol].szEst;
}
- zOriginTab = pTab->zName;
+ zOrigTab = pTab->zName;
if( pNC->pParse ){
int iDb = sqlite3SchemaToIndex(pNC->pParse->db, pTab->pSchema);
- zOriginDb = pNC->pParse->db->aDb[iDb].zName;
+ zOrigDb = pNC->pParse->db->aDb[iDb].zName;
}
+#else
+ if( iCol<0 ){
+ zType = "INTEGER";
+ }else{
+ zType = pTab->aCol[iCol].zType;
+ estWidth = pTab->aCol[iCol].szEst;
+ }
+#endif
}
break;
}
@@ -95458,18 +111118,21 @@ static const char *columnType(
sNC.pSrcList = pS->pSrc;
sNC.pNext = pNC;
sNC.pParse = pNC->pParse;
- zType = columnType(&sNC, p, &zOriginDb, &zOriginTab, &zOriginCol);
+ zType = columnType(&sNC, p, &zOrigDb, &zOrigTab, &zOrigCol, &estWidth);
break;
}
#endif
}
-
- if( pzOriginDb ){
- assert( pzOriginTab && pzOriginCol );
- *pzOriginDb = zOriginDb;
- *pzOriginTab = zOriginTab;
- *pzOriginCol = zOriginCol;
+
+#ifdef SQLITE_ENABLE_COLUMN_METADATA
+ if( pzOrigDb ){
+ assert( pzOrigTab && pzOrigCol );
+ *pzOrigDb = zOrigDb;
+ *pzOrigTab = zOrigTab;
+ *pzOrigCol = zOrigCol;
}
+#endif
+ if( pEstWidth ) *pEstWidth = estWidth;
return zType;
}
@@ -95495,7 +111158,7 @@ static void generateColumnTypes(
const char *zOrigDb = 0;
const char *zOrigTab = 0;
const char *zOrigCol = 0;
- zType = columnType(&sNC, p, &zOrigDb, &zOrigTab, &zOrigCol);
+ zType = columnType(&sNC, p, &zOrigDb, &zOrigTab, &zOrigCol, 0);
/* The vdbe must make its own copy of the column-type and other
** column specific strings, in case the schema is reset before this
@@ -95505,11 +111168,11 @@ static void generateColumnTypes(
sqlite3VdbeSetColName(v, i, COLNAME_TABLE, zOrigTab, SQLITE_TRANSIENT);
sqlite3VdbeSetColName(v, i, COLNAME_COLUMN, zOrigCol, SQLITE_TRANSIENT);
#else
- zType = columnType(&sNC, p, 0, 0, 0);
+ zType = columnType(&sNC, p, 0, 0, 0, 0);
#endif
sqlite3VdbeSetColName(v, i, COLNAME_DECLTYPE, zType, SQLITE_TRANSIENT);
}
-#endif /* SQLITE_OMIT_DECLTYPE */
+#endif /* !defined(SQLITE_OMIT_DECLTYPE) */
}
/*
@@ -95534,7 +111197,9 @@ static void generateColumnNames(
}
#endif
- if( pParse->colNamesSet || NEVER(v==0) || db->mallocFailed ) return;
+ if( pParse->colNamesSet || db->mallocFailed ) return;
+ assert( v!=0 );
+ assert( pTabList!=0 );
pParse->colNamesSet = 1;
fullNames = (db->flags & SQLITE_FullColNames)!=0;
shortNames = (db->flags & SQLITE_ShortColNames)!=0;
@@ -95546,7 +111211,7 @@ static void generateColumnNames(
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 ){
+ }else if( p->op==TK_COLUMN || p->op==TK_AGG_COLUMN ){
Table *pTab;
char *zCol;
int iCol = p->iColumn;
@@ -95573,15 +111238,16 @@ static void generateColumnNames(
sqlite3VdbeSetColName(v, i, COLNAME_NAME, zCol, SQLITE_TRANSIENT);
}
}else{
- sqlite3VdbeSetColName(v, i, COLNAME_NAME,
- sqlite3DbStrDup(db, pEList->a[i].zSpan), SQLITE_DYNAMIC);
+ const char *z = pEList->a[i].zSpan;
+ z = z==0 ? sqlite3MPrintf(db, "column%d", i+1) : sqlite3DbStrDup(db, z);
+ sqlite3VdbeSetColName(v, i, COLNAME_NAME, z, SQLITE_DYNAMIC);
}
}
generateColumnTypes(pParse, pTabList, pEList);
}
/*
-** Given a an expression list (which is really the list of expressions
+** Given 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.
**
@@ -95593,7 +111259,7 @@ static void generateColumnNames(
** 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(
+SQLITE_PRIVATE int sqlite3ColumnsFromExprList(
Parse *pParse, /* Parsing context */
ExprList *pEList, /* Expr list from which to derive column names */
i16 *pnCol, /* Write the number of columns here */
@@ -95601,13 +111267,15 @@ static int selectColumnsFromExprList(
){
sqlite3 *db = pParse->db; /* Database connection */
int i, j; /* Loop counters */
- int cnt; /* Index added to make the name unique */
+ u32 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[] */
+ Hash ht; /* Hash table of column names */
+ sqlite3HashInit(&ht);
if( pEList ){
nCol = pEList->nExpr;
aCol = sqlite3DbMallocZero(db, sizeof(aCol[0])*nCol);
@@ -95616,18 +111284,16 @@ static int selectColumnsFromExprList(
nCol = 0;
aCol = 0;
}
+ assert( nCol==(i16)nCol );
*pnCol = nCol;
*paCol = aCol;
- for(i=0, pCol=aCol; i<nCol; i++, pCol++){
+ for(i=0, pCol=aCol; i<nCol && !db->mallocFailed; 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 */
@@ -95640,38 +111306,37 @@ static int selectColumnsFromExprList(
int iCol = pColExpr->iColumn;
pTab = pColExpr->pTab;
if( iCol<0 ) iCol = pTab->iPKey;
- zName = sqlite3MPrintf(db, "%s",
- iCol>=0 ? pTab->aCol[iCol].zName : "rowid");
+ zName = 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);
+ zName = pColExpr->u.zToken;
}else{
/* Use the original text of the column expression as its name */
- zName = sqlite3MPrintf(db, "%s", pEList->a[i].zSpan);
+ zName = pEList->a[i].zSpan;
}
}
- if( db->mallocFailed ){
- sqlite3DbFree(db, zName);
- break;
- }
+ zName = sqlite3MPrintf(db, "%s", zName);
/* Make sure the column name is unique. If the name is not unique,
- ** append a integer to the name so that it becomes unique.
+ ** append an 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;
+ cnt = 0;
+ while( zName && sqlite3HashFind(&ht, zName)!=0 ){
+ nName = sqlite3Strlen30(zName);
+ if( nName>0 ){
+ for(j=nName-1; j>0 && sqlite3Isdigit(zName[j]); j--){}
+ if( zName[j]==':' ) nName = j;
}
+ zName = sqlite3MPrintf(db, "%.*z:%u", nName, zName, ++cnt);
+ if( cnt>3 ) sqlite3_randomness(sizeof(cnt), &cnt);
}
pCol->zName = zName;
+ sqlite3ColumnPropertiesFromName(0, pCol);
+ if( zName && sqlite3HashInsert(&ht, zName, pCol)==pCol ){
+ db->mallocFailed = 1;
+ }
}
+ sqlite3HashClear(&ht);
if( db->mallocFailed ){
for(j=0; j<i; j++){
sqlite3DbFree(db, aCol[j].zName);
@@ -95697,8 +111362,7 @@ static int selectColumnsFromExprList(
*/
static void selectAddColumnTypeAndCollation(
Parse *pParse, /* Parsing contexts */
- int nCol, /* Number of columns */
- Column *aCol, /* List of columns */
+ Table *pTab, /* Add column type information to this table */
Select *pSelect /* SELECT used to determine types and collations */
){
sqlite3 *db = pParse->db;
@@ -95708,24 +111372,30 @@ static void selectAddColumnTypeAndCollation(
int i;
Expr *p;
struct ExprList_item *a;
+ u64 szAll = 0;
assert( pSelect!=0 );
assert( (pSelect->selFlags & SF_Resolved)!=0 );
- assert( nCol==pSelect->pEList->nExpr || db->mallocFailed );
+ assert( pTab->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++){
+ for(i=0, pCol=pTab->aCol; i<pTab->nCol; i++, pCol++){
p = a[i].pExpr;
- pCol->zType = sqlite3DbStrDup(db, columnType(&sNC, p, 0, 0, 0));
+ if( pCol->zType==0 ){
+ pCol->zType = sqlite3DbStrDup(db,
+ columnType(&sNC, p,0,0,0, &pCol->szEst));
+ }
+ szAll += pCol->szEst;
pCol->affinity = sqlite3ExprAffinity(p);
- if( pCol->affinity==0 ) pCol->affinity = SQLITE_AFF_NONE;
+ if( pCol->affinity==0 ) pCol->affinity = SQLITE_AFF_BLOB;
pColl = sqlite3ExprCollSeq(pParse, p);
- if( pColl ){
+ if( pColl && pCol->zColl==0 ){
pCol->zColl = sqlite3DbStrDup(db, pColl->zName);
}
}
+ pTab->szTabRow = sqlite3LogEst(szAll*4);
}
/*
@@ -95753,9 +111423,9 @@ SQLITE_PRIVATE Table *sqlite3ResultSetOfSelect(Parse *pParse, Select *pSelect){
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->nRowLogEst = 200; assert( 200==sqlite3LogEst(1048576) );
+ sqlite3ColumnsFromExprList(pParse, pSelect->pEList, &pTab->nCol, &pTab->aCol);
+ selectAddColumnTypeAndCollation(pParse, pTab, pSelect);
pTab->iPKey = -1;
if( db->mallocFailed ){
sqlite3DeleteTable(db, pTab);
@@ -95771,12 +111441,14 @@ SQLITE_PRIVATE Table *sqlite3ResultSetOfSelect(Parse *pParse, Select *pSelect){
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);
+ v = pParse->pVdbe = sqlite3VdbeCreate(pParse);
+ if( v ) sqlite3VdbeAddOp0(v, OP_Init);
+ if( pParse->pToplevel==0
+ && OptimizationEnabled(pParse->db,SQLITE_FactorOutConst)
+ ){
+ pParse->okConstFactor = 1;
}
-#endif
+
}
return v;
}
@@ -95793,8 +111465,13 @@ SQLITE_PRIVATE Vdbe *sqlite3GetVdbe(Parse *pParse){
**
** 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.
+** iOffset should have been preset to appropriate default values (zero)
+** prior to calling this routine.
+**
+** The iOffset register (if it exists) is initialized to the value
+** of the OFFSET. The iLimit register is initialized to LIMIT. Register
+** iOffset+1 is initialized to LIMIT+OFFSET.
+**
** 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
@@ -95804,12 +111481,12 @@ static void computeLimitRegisters(Parse *pParse, Select *p, int iBreak){
Vdbe *v = 0;
int iLimit = 0;
int iOffset;
- int addr1, n;
+ int n;
if( p->iLimit ) return;
/*
** "LIMIT -1" always shows all rows. There is some
- ** contraversy about what the correct behavior should be.
+ ** controversy about what the correct behavior should be.
** The current implementation interprets "LIMIT 0" to mean
** no rows.
*/
@@ -95818,35 +111495,31 @@ static void computeLimitRegisters(Parse *pParse, Select *p, int iBreak){
if( p->pLimit ){
p->iLimit = iLimit = ++pParse->nMem;
v = sqlite3GetVdbe(pParse);
- if( NEVER(v==0) ) return; /* VDBE should have already been allocated */
+ assert( v!=0 );
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;
+ sqlite3VdbeGoto(v, iBreak);
+ }else if( n>=0 && p->nSelectRow>(u64)n ){
+ p->nSelectRow = n;
}
}else{
sqlite3ExprCode(pParse, p->pLimit, iLimit);
- sqlite3VdbeAddOp1(v, OP_MustBeInt, iLimit);
+ sqlite3VdbeAddOp1(v, OP_MustBeInt, iLimit); VdbeCoverage(v);
VdbeComment((v, "LIMIT counter"));
- sqlite3VdbeAddOp2(v, OP_IfZero, iLimit, iBreak);
+ sqlite3VdbeAddOp2(v, OP_IfNot, iLimit, iBreak); VdbeCoverage(v);
}
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);
+ sqlite3VdbeAddOp1(v, OP_MustBeInt, iOffset); VdbeCoverage(v);
VdbeComment((v, "OFFSET counter"));
- addr1 = sqlite3VdbeAddOp1(v, OP_IfPos, iOffset);
- sqlite3VdbeAddOp2(v, OP_Integer, 0, iOffset);
- sqlite3VdbeJumpHere(v, addr1);
+ sqlite3VdbeAddOp3(v, OP_SetIfNotPos, iOffset, iOffset, 0);
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);
+ sqlite3VdbeAddOp3(v, OP_SetIfNotPos, iLimit, iOffset+1, -1);
}
}
}
@@ -95868,22 +111541,271 @@ static CollSeq *multiSelectCollSeq(Parse *pParse, Select *p, int iCol){
pRet = 0;
}
assert( iCol>=0 );
- if( pRet==0 && iCol<p->pEList->nExpr ){
+ /* iCol must be less than p->pEList->nExpr. Otherwise an error would
+ ** have been thrown during name resolution and we would not have gotten
+ ** this far */
+ if( pRet==0 && ALWAYS(iCol<p->pEList->nExpr) ){
pRet = sqlite3ExprCollSeq(pParse, p->pEList->a[iCol].pExpr);
}
return pRet;
}
-#endif /* SQLITE_OMIT_COMPOUND_SELECT */
-/* Forward reference */
+/*
+** The select statement passed as the second parameter is a compound SELECT
+** with an ORDER BY clause. This function allocates and returns a KeyInfo
+** structure suitable for implementing the ORDER BY.
+**
+** Space to hold the KeyInfo structure is obtained from malloc. The calling
+** function is responsible for ensuring that this structure is eventually
+** freed.
+*/
+static KeyInfo *multiSelectOrderByKeyInfo(Parse *pParse, Select *p, int nExtra){
+ ExprList *pOrderBy = p->pOrderBy;
+ int nOrderBy = p->pOrderBy->nExpr;
+ sqlite3 *db = pParse->db;
+ KeyInfo *pRet = sqlite3KeyInfoAlloc(db, nOrderBy+nExtra, 1);
+ if( pRet ){
+ int i;
+ for(i=0; i<nOrderBy; i++){
+ struct ExprList_item *pItem = &pOrderBy->a[i];
+ Expr *pTerm = pItem->pExpr;
+ CollSeq *pColl;
+
+ if( pTerm->flags & EP_Collate ){
+ pColl = sqlite3ExprCollSeq(pParse, pTerm);
+ }else{
+ pColl = multiSelectCollSeq(pParse, p, pItem->u.x.iOrderByCol-1);
+ if( pColl==0 ) pColl = db->pDfltColl;
+ pOrderBy->a[i].pExpr =
+ sqlite3ExprAddCollateString(pParse, pTerm, pColl->zName);
+ }
+ assert( sqlite3KeyInfoIsWriteable(pRet) );
+ pRet->aColl[i] = pColl;
+ pRet->aSortOrder[i] = pOrderBy->a[i].sortOrder;
+ }
+ }
+
+ return pRet;
+}
+
+#ifndef SQLITE_OMIT_CTE
+/*
+** This routine generates VDBE code to compute the content of a WITH RECURSIVE
+** query of the form:
+**
+** <recursive-table> AS (<setup-query> UNION [ALL] <recursive-query>)
+** \___________/ \_______________/
+** p->pPrior p
+**
+**
+** There is exactly one reference to the recursive-table in the FROM clause
+** of recursive-query, marked with the SrcList->a[].fg.isRecursive flag.
+**
+** The setup-query runs once to generate an initial set of rows that go
+** into a Queue table. Rows are extracted from the Queue table one by
+** one. Each row extracted from Queue is output to pDest. Then the single
+** extracted row (now in the iCurrent table) becomes the content of the
+** recursive-table for a recursive-query run. The output of the recursive-query
+** is added back into the Queue table. Then another row is extracted from Queue
+** and the iteration continues until the Queue table is empty.
+**
+** If the compound query operator is UNION then no duplicate rows are ever
+** inserted into the Queue table. The iDistinct table keeps a copy of all rows
+** that have ever been inserted into Queue and causes duplicates to be
+** discarded. If the operator is UNION ALL, then duplicates are allowed.
+**
+** If the query has an ORDER BY, then entries in the Queue table are kept in
+** ORDER BY order and the first entry is extracted for each cycle. Without
+** an ORDER BY, the Queue table is just a FIFO.
+**
+** If a LIMIT clause is provided, then the iteration stops after LIMIT rows
+** have been output to pDest. A LIMIT of zero means to output no rows and a
+** negative LIMIT means to output all rows. If there is also an OFFSET clause
+** with a positive value, then the first OFFSET outputs are discarded rather
+** than being sent to pDest. The LIMIT count does not begin until after OFFSET
+** rows have been skipped.
+*/
+static void generateWithRecursiveQuery(
+ Parse *pParse, /* Parsing context */
+ Select *p, /* The recursive SELECT to be coded */
+ SelectDest *pDest /* What to do with query results */
+){
+ SrcList *pSrc = p->pSrc; /* The FROM clause of the recursive query */
+ int nCol = p->pEList->nExpr; /* Number of columns in the recursive table */
+ Vdbe *v = pParse->pVdbe; /* The prepared statement under construction */
+ Select *pSetup = p->pPrior; /* The setup query */
+ int addrTop; /* Top of the loop */
+ int addrCont, addrBreak; /* CONTINUE and BREAK addresses */
+ int iCurrent = 0; /* The Current table */
+ int regCurrent; /* Register holding Current table */
+ int iQueue; /* The Queue table */
+ int iDistinct = 0; /* To ensure unique results if UNION */
+ int eDest = SRT_Fifo; /* How to write to Queue */
+ SelectDest destQueue; /* SelectDest targetting the Queue table */
+ int i; /* Loop counter */
+ int rc; /* Result code */
+ ExprList *pOrderBy; /* The ORDER BY clause */
+ Expr *pLimit, *pOffset; /* Saved LIMIT and OFFSET */
+ int regLimit, regOffset; /* Registers used by LIMIT and OFFSET */
+
+ /* Obtain authorization to do a recursive query */
+ if( sqlite3AuthCheck(pParse, SQLITE_RECURSIVE, 0, 0, 0) ) return;
+
+ /* Process the LIMIT and OFFSET clauses, if they exist */
+ addrBreak = sqlite3VdbeMakeLabel(v);
+ computeLimitRegisters(pParse, p, addrBreak);
+ pLimit = p->pLimit;
+ pOffset = p->pOffset;
+ regLimit = p->iLimit;
+ regOffset = p->iOffset;
+ p->pLimit = p->pOffset = 0;
+ p->iLimit = p->iOffset = 0;
+ pOrderBy = p->pOrderBy;
+
+ /* Locate the cursor number of the Current table */
+ for(i=0; ALWAYS(i<pSrc->nSrc); i++){
+ if( pSrc->a[i].fg.isRecursive ){
+ iCurrent = pSrc->a[i].iCursor;
+ break;
+ }
+ }
+
+ /* Allocate cursors numbers for Queue and Distinct. The cursor number for
+ ** the Distinct table must be exactly one greater than Queue in order
+ ** for the SRT_DistFifo and SRT_DistQueue destinations to work. */
+ iQueue = pParse->nTab++;
+ if( p->op==TK_UNION ){
+ eDest = pOrderBy ? SRT_DistQueue : SRT_DistFifo;
+ iDistinct = pParse->nTab++;
+ }else{
+ eDest = pOrderBy ? SRT_Queue : SRT_Fifo;
+ }
+ sqlite3SelectDestInit(&destQueue, eDest, iQueue);
+
+ /* Allocate cursors for Current, Queue, and Distinct. */
+ regCurrent = ++pParse->nMem;
+ sqlite3VdbeAddOp3(v, OP_OpenPseudo, iCurrent, regCurrent, nCol);
+ if( pOrderBy ){
+ KeyInfo *pKeyInfo = multiSelectOrderByKeyInfo(pParse, p, 1);
+ sqlite3VdbeAddOp4(v, OP_OpenEphemeral, iQueue, pOrderBy->nExpr+2, 0,
+ (char*)pKeyInfo, P4_KEYINFO);
+ destQueue.pOrderBy = pOrderBy;
+ }else{
+ sqlite3VdbeAddOp2(v, OP_OpenEphemeral, iQueue, nCol);
+ }
+ VdbeComment((v, "Queue table"));
+ if( iDistinct ){
+ p->addrOpenEphm[0] = sqlite3VdbeAddOp2(v, OP_OpenEphemeral, iDistinct, 0);
+ p->selFlags |= SF_UsesEphemeral;
+ }
+
+ /* Detach the ORDER BY clause from the compound SELECT */
+ p->pOrderBy = 0;
+
+ /* Store the results of the setup-query in Queue. */
+ pSetup->pNext = 0;
+ rc = sqlite3Select(pParse, pSetup, &destQueue);
+ pSetup->pNext = p;
+ if( rc ) goto end_of_recursive_query;
+
+ /* Find the next row in the Queue and output that row */
+ addrTop = sqlite3VdbeAddOp2(v, OP_Rewind, iQueue, addrBreak); VdbeCoverage(v);
+
+ /* Transfer the next row in Queue over to Current */
+ sqlite3VdbeAddOp1(v, OP_NullRow, iCurrent); /* To reset column cache */
+ if( pOrderBy ){
+ sqlite3VdbeAddOp3(v, OP_Column, iQueue, pOrderBy->nExpr+1, regCurrent);
+ }else{
+ sqlite3VdbeAddOp2(v, OP_RowData, iQueue, regCurrent);
+ }
+ sqlite3VdbeAddOp1(v, OP_Delete, iQueue);
+
+ /* Output the single row in Current */
+ addrCont = sqlite3VdbeMakeLabel(v);
+ codeOffset(v, regOffset, addrCont);
+ selectInnerLoop(pParse, p, p->pEList, iCurrent,
+ 0, 0, pDest, addrCont, addrBreak);
+ if( regLimit ){
+ sqlite3VdbeAddOp2(v, OP_DecrJumpZero, regLimit, addrBreak);
+ VdbeCoverage(v);
+ }
+ sqlite3VdbeResolveLabel(v, addrCont);
+
+ /* Execute the recursive SELECT taking the single row in Current as
+ ** the value for the recursive-table. Store the results in the Queue.
+ */
+ if( p->selFlags & SF_Aggregate ){
+ sqlite3ErrorMsg(pParse, "recursive aggregate queries not supported");
+ }else{
+ p->pPrior = 0;
+ sqlite3Select(pParse, p, &destQueue);
+ assert( p->pPrior==0 );
+ p->pPrior = pSetup;
+ }
+
+ /* Keep running the loop until the Queue is empty */
+ sqlite3VdbeGoto(v, addrTop);
+ sqlite3VdbeResolveLabel(v, addrBreak);
+
+end_of_recursive_query:
+ sqlite3ExprListDelete(pParse->db, p->pOrderBy);
+ p->pOrderBy = pOrderBy;
+ p->pLimit = pLimit;
+ p->pOffset = pOffset;
+ return;
+}
+#endif /* SQLITE_OMIT_CTE */
+
+/* Forward references */
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 */
);
+/*
+** Handle the special case of a compound-select that originates from a
+** VALUES clause. By handling this as a special case, we avoid deep
+** recursion, and thus do not need to enforce the SQLITE_LIMIT_COMPOUND_SELECT
+** on a VALUES clause.
+**
+** Because the Select object originates from a VALUES clause:
+** (1) It has no LIMIT or OFFSET
+** (2) All terms are UNION ALL
+** (3) There is no ORDER BY clause
+*/
+static int multiSelectValues(
+ Parse *pParse, /* Parsing context */
+ Select *p, /* The right-most of SELECTs to be coded */
+ SelectDest *pDest /* What to do with query results */
+){
+ Select *pPrior;
+ int nRow = 1;
+ int rc = 0;
+ assert( p->selFlags & SF_MultiValue );
+ do{
+ assert( p->selFlags & SF_Values );
+ assert( p->op==TK_ALL || (p->op==TK_SELECT && p->pPrior==0) );
+ assert( p->pLimit==0 );
+ assert( p->pOffset==0 );
+ assert( p->pNext==0 || p->pEList->nExpr==p->pNext->pEList->nExpr );
+ if( p->pPrior==0 ) break;
+ assert( p->pPrior->pNext==p );
+ p = p->pPrior;
+ nRow++;
+ }while(1);
+ while( p ){
+ pPrior = p->pPrior;
+ p->pPrior = 0;
+ rc = sqlite3Select(pParse, p, pDest);
+ p->pPrior = pPrior;
+ if( rc ) break;
+ p->nSelectRow = nRow;
+ p = p->pNext;
+ }
+ return rc;
+}
-#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
@@ -95927,18 +111849,17 @@ static int multiSelect(
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 */
+ int iSub1 = 0; /* EQP id of left-hand query */
+ int iSub2 = 0; /* 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 */
+ assert( (p->selFlags & SF_Recursive)==0 || p->op==TK_ALL || p->op==TK_UNION );
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",
@@ -95965,26 +111886,30 @@ static int multiSelect(
dest.eDest = SRT_Table;
}
+ /* Special handling for a compound-select that originates as a VALUES clause.
+ */
+ if( p->selFlags & SF_MultiValue ){
+ rc = multiSelectValues(pParse, p, &dest);
+ goto multi_select_end;
+ }
+
/* 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;
- }
+ assert( p->pEList->nExpr==pPrior->pEList->nExpr );
+
+#ifndef SQLITE_OMIT_CTE
+ if( p->selFlags & SF_Recursive ){
+ generateWithRecursiveQuery(pParse, p, &dest);
+ }else
+#endif
/* Compound SELECTs that have an ORDER BY clause are handled separately.
*/
if( p->pOrderBy ){
return multiSelectOrderBy(pParse, p, pDest);
- }
+ }else
/* Generate code for the left and right SELECT statements.
*/
@@ -95993,6 +111918,8 @@ static int multiSelect(
int addr = 0;
int nLimit;
assert( !pPrior->pLimit );
+ pPrior->iLimit = p->iLimit;
+ pPrior->iOffset = p->iOffset;
pPrior->pLimit = p->pLimit;
pPrior->pOffset = p->pOffset;
explainSetInteger(iSub1, pParse->iNextSelectId);
@@ -96006,8 +111933,13 @@ static int multiSelect(
p->iLimit = pPrior->iLimit;
p->iOffset = pPrior->iOffset;
if( p->iLimit ){
- addr = sqlite3VdbeAddOp1(v, OP_IfZero, p->iLimit);
+ addr = sqlite3VdbeAddOp1(v, OP_IfNot, p->iLimit); VdbeCoverage(v);
VdbeComment((v, "Jump ahead if LIMIT reached"));
+ if( p->iOffset ){
+ sqlite3VdbeAddOp3(v, OP_SetIfNotPos, p->iOffset, p->iOffset, 0);
+ sqlite3VdbeAddOp3(v, OP_Add, p->iLimit, p->iOffset, p->iOffset+1);
+ sqlite3VdbeAddOp3(v, OP_SetIfNotPos, p->iLimit, p->iOffset+1, -1);
+ }
}
explainSetInteger(iSub2, pParse->iNextSelectId);
rc = sqlite3Select(pParse, p, &dest);
@@ -96017,9 +111949,9 @@ static int multiSelect(
p->nSelectRow += pPrior->nSelectRow;
if( pPrior->pLimit
&& sqlite3ExprIsInteger(pPrior->pLimit, &nLimit)
- && p->nSelectRow > (double)nLimit
+ && nLimit>0 && p->nSelectRow > (u64)nLimit
){
- p->nSelectRow = (double)nLimit;
+ p->nSelectRow = nLimit;
}
if( addr ){
sqlite3VdbeJumpHere(v, addr);
@@ -96038,12 +111970,10 @@ static int multiSelect(
testcase( p->op==TK_EXCEPT );
testcase( p->op==TK_UNION );
priorOp = SRT_Union;
- if( dest.eDest==priorOp && ALWAYS(!p->pLimit &&!p->pOffset) ){
+ if( dest.eDest==priorOp ){
/* 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;
@@ -96056,7 +111986,7 @@ static int multiSelect(
addr = sqlite3VdbeAddOp2(v, OP_OpenEphemeral, unionTab, 0);
assert( p->addrOpenEphm[0] == -1 );
p->addrOpenEphm[0] = addr;
- p->pRightmost->selFlags |= SF_UsesEphemeral;
+ findRightmost(p)->selFlags |= SF_UsesEphemeral;
assert( p->pEList );
}
@@ -96110,17 +112040,17 @@ static int multiSelect(
if( dest.eDest==SRT_Output ){
Select *pFirst = p;
while( pFirst->pPrior ) pFirst = pFirst->pPrior;
- generateColumnNames(pParse, 0, pFirst->pEList);
+ generateColumnNames(pParse, pFirst->pSrc, pFirst->pEList);
}
iBreak = sqlite3VdbeMakeLabel(v);
iCont = sqlite3VdbeMakeLabel(v);
computeLimitRegisters(pParse, p, iBreak);
- sqlite3VdbeAddOp2(v, OP_Rewind, unionTab, iBreak);
+ sqlite3VdbeAddOp2(v, OP_Rewind, unionTab, iBreak); VdbeCoverage(v);
iStart = sqlite3VdbeCurrentAddr(v);
- selectInnerLoop(pParse, p, p->pEList, unionTab, p->pEList->nExpr,
+ selectInnerLoop(pParse, p, p->pEList, unionTab,
0, 0, &dest, iCont, iBreak);
sqlite3VdbeResolveLabel(v, iCont);
- sqlite3VdbeAddOp2(v, OP_Next, unionTab, iStart);
+ sqlite3VdbeAddOp2(v, OP_Next, unionTab, iStart); VdbeCoverage(v);
sqlite3VdbeResolveLabel(v, iBreak);
sqlite3VdbeAddOp2(v, OP_Close, unionTab, 0);
}
@@ -96145,7 +112075,7 @@ static int multiSelect(
addr = sqlite3VdbeAddOp2(v, OP_OpenEphemeral, tab1, 0);
assert( p->addrOpenEphm[0] == -1 );
p->addrOpenEphm[0] = addr;
- p->pRightmost->selFlags |= SF_UsesEphemeral;
+ findRightmost(p)->selFlags |= SF_UsesEphemeral;
assert( p->pEList );
/* Code the SELECTs to our left into temporary table "tab1".
@@ -96185,20 +112115,20 @@ static int multiSelect(
if( dest.eDest==SRT_Output ){
Select *pFirst = p;
while( pFirst->pPrior ) pFirst = pFirst->pPrior;
- generateColumnNames(pParse, 0, pFirst->pEList);
+ generateColumnNames(pParse, pFirst->pSrc, pFirst->pEList);
}
iBreak = sqlite3VdbeMakeLabel(v);
iCont = sqlite3VdbeMakeLabel(v);
computeLimitRegisters(pParse, p, iBreak);
- sqlite3VdbeAddOp2(v, OP_Rewind, tab1, iBreak);
+ sqlite3VdbeAddOp2(v, OP_Rewind, tab1, iBreak); VdbeCoverage(v);
r1 = sqlite3GetTempReg(pParse);
iStart = sqlite3VdbeAddOp2(v, OP_RowKey, tab1, r1);
- sqlite3VdbeAddOp4Int(v, OP_NotFound, tab2, iCont, r1, 0);
+ sqlite3VdbeAddOp4Int(v, OP_NotFound, tab2, iCont, r1, 0); VdbeCoverage(v);
sqlite3ReleaseTempReg(pParse, r1);
- selectInnerLoop(pParse, p, p->pEList, tab1, p->pEList->nExpr,
+ selectInnerLoop(pParse, p, p->pEList, tab1,
0, 0, &dest, iCont, iBreak);
sqlite3VdbeResolveLabel(v, iCont);
- sqlite3VdbeAddOp2(v, OP_Next, tab1, iStart);
+ sqlite3VdbeAddOp2(v, OP_Next, tab1, iStart); VdbeCoverage(v);
sqlite3VdbeResolveLabel(v, iBreak);
sqlite3VdbeAddOp2(v, OP_Close, tab2, 0);
sqlite3VdbeAddOp2(v, OP_Close, tab1, 0);
@@ -96224,25 +112154,19 @@ static int multiSelect(
CollSeq **apColl; /* For looping through pKeyInfo->aColl[] */
int nCol; /* Number of columns in result set */
- assert( p->pRightmost==p );
+ assert( p->pNext==0 );
nCol = p->pEList->nExpr;
- pKeyInfo = sqlite3DbMallocZero(db,
- sizeof(*pKeyInfo)+nCol*(sizeof(CollSeq*) + 1));
+ pKeyInfo = sqlite3KeyInfoAlloc(db, nCol, 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++){
@@ -96254,11 +112178,12 @@ static int multiSelect(
break;
}
sqlite3VdbeChangeP2(v, addr, nCol);
- sqlite3VdbeChangeP4(v, addr, (char*)pKeyInfo, P4_KEYINFO);
+ sqlite3VdbeChangeP4(v, addr, (char*)sqlite3KeyInfoRef(pKeyInfo),
+ P4_KEYINFO);
pLoop->addrOpenEphm[i] = -1;
}
}
- sqlite3DbFree(db, pKeyInfo);
+ sqlite3KeyInfoUnref(pKeyInfo);
}
multi_select_end:
@@ -96270,6 +112195,19 @@ multi_select_end:
#endif /* SQLITE_OMIT_COMPOUND_SELECT */
/*
+** Error message for when two or more terms of a compound select have different
+** size result sets.
+*/
+SQLITE_PRIVATE void sqlite3SelectWrongNumTermsError(Parse *pParse, Select *p){
+ 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));
+ }
+}
+
+/*
** Code an output subroutine for a coroutine implementation of a
** SELECT statment.
**
@@ -96297,7 +112235,6 @@ static int generateOutputSubroutine(
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;
@@ -96310,12 +112247,12 @@ static int generateOutputSubroutine(
/* 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);
+ int addr1, addr2;
+ addr1 = sqlite3VdbeAddOp1(v, OP_IfNot, regPrev); VdbeCoverage(v);
+ addr2 = sqlite3VdbeAddOp4(v, OP_Compare, pIn->iSdst, regPrev+1, pIn->nSdst,
+ (char*)sqlite3KeyInfoRef(pKeyInfo), P4_KEYINFO);
+ sqlite3VdbeAddOp3(v, OP_Jump, addr2+2, iContinue, addr2+2); VdbeCoverage(v);
+ sqlite3VdbeJumpHere(v, addr1);
sqlite3VdbeAddOp3(v, OP_Copy, pIn->iSdst, regPrev+1, pIn->nSdst-1);
sqlite3VdbeAddOp2(v, OP_Integer, 1, regPrev);
}
@@ -96323,17 +112260,16 @@ static int generateOutputSubroutine(
/* Suppress the first OFFSET entries if there is an OFFSET clause
*/
- codeOffset(v, p, iContinue);
+ codeOffset(v, p->iOffset, iContinue);
+ assert( pDest->eDest!=SRT_Exists );
+ assert( pDest->eDest!=SRT_Table );
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);
@@ -96350,7 +112286,7 @@ static int generateOutputSubroutine(
*/
case SRT_Set: {
int r1;
- assert( pIn->nSdst==1 );
+ assert( pIn->nSdst==1 || pParse->nErr>0 );
pDest->affSdst =
sqlite3CompareAffinity(p->pEList->a[0].pExpr, pDest->affSdst);
r1 = sqlite3GetTempReg(pParse);
@@ -96361,22 +112297,12 @@ static int generateOutputSubroutine(
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 );
+ assert( pIn->nSdst==1 || pParse->nErr>0 ); testcase( pIn->nSdst!=1 );
sqlite3ExprCodeMove(pParse, pIn->iSdst, pDest->iSDParm, 1);
/* The LIMIT clause will jump out of the loop for us */
break;
@@ -96391,7 +112317,7 @@ static int generateOutputSubroutine(
pDest->iSdst = sqlite3GetTempRange(pParse, pIn->nSdst);
pDest->nSdst = pIn->nSdst;
}
- sqlite3ExprCodeMove(pParse, pIn->iSdst, pDest->iSdst, pDest->nSdst);
+ sqlite3ExprCodeMove(pParse, pIn->iSdst, pDest->iSdst, pIn->nSdst);
sqlite3VdbeAddOp1(v, OP_Yield, pDest->iSDParm);
break;
}
@@ -96415,7 +112341,7 @@ static int generateOutputSubroutine(
/* Jump to the end of the loop if the LIMIT is reached.
*/
if( p->iLimit ){
- sqlite3VdbeAddOp3(v, OP_IfZero, p->iLimit, iBreak, -1);
+ sqlite3VdbeAddOp2(v, OP_DecrJumpZero, p->iLimit, iBreak); VdbeCoverage(v);
}
/* Generate the subroutine return
@@ -96523,9 +112449,7 @@ static int multiSelectOrderBy(
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 */
@@ -96533,6 +112457,7 @@ static int multiSelectOrderBy(
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 addrEofA_noB; /* Alternate addrEofA if B is uninitialized */
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 */
@@ -96544,7 +112469,7 @@ static int multiSelectOrderBy(
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 addr1; /* 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 */
@@ -96583,8 +112508,8 @@ static int multiSelectOrderBy(
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;
+ assert( pItem->u.x.iOrderByCol>0 );
+ if( pItem->u.x.iOrderByCol==i ) break;
}
if( j==nOrderBy ){
Expr *pNew = sqlite3Expr(db, TK_INTEGER, 0);
@@ -96592,7 +112517,7 @@ static int multiSelectOrderBy(
pNew->flags |= EP_IntValue;
pNew->u.iValue = i;
pOrderBy = sqlite3ExprListAppend(pParse, pOrderBy, pNew);
- if( pOrderBy ) pOrderBy->a[nOrderBy++].iOrderByCol = (u16)i;
+ if( pOrderBy ) pOrderBy->a[nOrderBy++].u.x.iOrderByCol = (u16)i;
}
}
}
@@ -96608,30 +112533,11 @@ static int multiSelectOrderBy(
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;
- }
+ assert( pItem->u.x.iOrderByCol>0 );
+ assert( pItem->u.x.iOrderByCol<=p->pEList->nExpr );
+ aPermute[i] = pItem->u.x.iOrderByCol - 1;
}
+ pKeyMerge = multiSelectOrderByKeyInfo(pParse, p, 1);
}else{
pKeyMerge = 0;
}
@@ -96650,14 +112556,12 @@ static int multiSelectOrderBy(
}else{
int nExpr = p->pEList->nExpr;
assert( nOrderBy>=nExpr || db->mallocFailed );
- regPrev = sqlite3GetTempRange(pParse, nExpr+1);
+ regPrev = pParse->nMem+1;
+ pParse->nMem += nExpr+1;
sqlite3VdbeAddOp2(v, OP_Integer, 0, regPrev);
- pKeyDup = sqlite3DbMallocZero(db,
- sizeof(*pKeyDup) + nExpr*(sizeof(CollSeq*)+1) );
+ pKeyDup = sqlite3KeyInfoAlloc(db, nExpr, 1);
if( pKeyDup ){
- pKeyDup->aSortOrder = (u8*)&pKeyDup->aColl[nExpr];
- pKeyDup->nField = (u16)nExpr;
- pKeyDup->enc = ENC(db);
+ assert( sqlite3KeyInfoIsWriteable(pKeyDup) );
for(i=0; i<nExpr; i++){
pKeyDup->aColl[i] = multiSelectCollSeq(pParse, p, i);
pKeyDup->aSortOrder[i] = 0;
@@ -96668,6 +112572,7 @@ static int multiSelectOrderBy(
/* Separate the left and the right query from one another
*/
p->pPrior = 0;
+ pPrior->pNext = 0;
sqlite3ResolveOrderGroupBy(pParse, p, p->pOrderBy, "ORDER");
if( pPrior->pPrior==0 ){
sqlite3ResolveOrderGroupBy(pParse, pPrior, pPrior->pOrderBy, "ORDER");
@@ -96690,37 +112595,30 @@ static int multiSelectOrderBy(
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"));
+ addrSelectA = sqlite3VdbeCurrentAddr(v) + 1;
+ addr1 = sqlite3VdbeAddOp3(v, OP_InitCoroutine, regAddrA, 0, addrSelectA);
+ VdbeComment((v, "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"));
+ sqlite3VdbeAddOp1(v, OP_EndCoroutine, regAddrA);
+ sqlite3VdbeJumpHere(v, addr1);
/* Generate a coroutine to evaluate the SELECT statement on
** the right - the "B" select
*/
- addrSelectB = sqlite3VdbeCurrentAddr(v);
- VdbeNoopComment((v, "Begin coroutine for right SELECT"));
+ addrSelectB = sqlite3VdbeCurrentAddr(v) + 1;
+ addr1 = sqlite3VdbeAddOp3(v, OP_InitCoroutine, regAddrB, 0, addrSelectB);
+ VdbeComment((v, "right SELECT"));
savedLimit = p->iLimit;
savedOffset = p->iOffset;
p->iLimit = regLimitB;
@@ -96729,9 +112627,7 @@ static int multiSelectOrderBy(
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"));
+ sqlite3VdbeAddOp1(v, OP_EndCoroutine, regAddrB);
/* Generate a subroutine that outputs the current row of the A
** select as the next output row of the compound select.
@@ -96739,7 +112635,7 @@ static int multiSelectOrderBy(
VdbeNoopComment((v, "Output routine for A"));
addrOutA = generateOutputSubroutine(pParse,
p, &destA, pDest, regOutA,
- regPrev, pKeyDup, P4_KEYINFO_HANDOFF, labelEnd);
+ regPrev, pKeyDup, labelEnd);
/* Generate a subroutine that outputs the current row of the B
** select as the next output row of the compound select.
@@ -96748,20 +112644,21 @@ static int multiSelectOrderBy(
VdbeNoopComment((v, "Output routine for B"));
addrOutB = generateOutputSubroutine(pParse,
p, &destB, pDest, regOutB,
- regPrev, pKeyDup, P4_KEYINFO_STATIC, labelEnd);
+ regPrev, pKeyDup, labelEnd);
}
+ sqlite3KeyInfoUnref(pKeyDup);
/* 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);
+ addrEofA_noB = addrEofA = 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);
+ VdbeNoopComment((v, "eof-A subroutine"));
+ addrEofA = sqlite3VdbeAddOp2(v, OP_Gosub, regOutB, addrOutB);
+ addrEofA_noB = sqlite3VdbeAddOp2(v, OP_Yield, regAddrB, labelEnd);
+ VdbeCoverage(v);
+ sqlite3VdbeGoto(v, addrEofA);
p->nSelectRow += pPrior->nSelectRow;
}
@@ -96773,19 +112670,17 @@ static int multiSelectOrderBy(
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);
+ addrEofB = sqlite3VdbeAddOp2(v, OP_Gosub, regOutA, addrOutA);
+ sqlite3VdbeAddOp2(v, OP_Yield, regAddrA, labelEnd); VdbeCoverage(v);
+ sqlite3VdbeGoto(v, 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);
+ sqlite3VdbeAddOp2(v, OP_Yield, regAddrA, addrEofA); VdbeCoverage(v);
+ sqlite3VdbeGoto(v, labelCmpr);
/* Generate code to handle the case of A==B
*/
@@ -96797,9 +112692,8 @@ static int multiSelectOrderBy(
}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);
+ sqlite3VdbeAddOp2(v, OP_Yield, regAddrA, addrEofA); VdbeCoverage(v);
+ sqlite3VdbeGoto(v, labelCmpr);
}
/* Generate code to handle the case of A>B
@@ -96809,34 +112703,23 @@ static int multiSelectOrderBy(
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);
+ sqlite3VdbeAddOp2(v, OP_Yield, regAddrB, addrEofB); VdbeCoverage(v);
+ sqlite3VdbeGoto(v, 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);
+ sqlite3VdbeJumpHere(v, addr1);
+ sqlite3VdbeAddOp2(v, OP_Yield, regAddrA, addrEofA_noB); VdbeCoverage(v);
+ sqlite3VdbeAddOp2(v, OP_Yield, regAddrB, addrEofB); VdbeCoverage(v);
/* 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);
+ (char*)pKeyMerge, P4_KEYINFO);
sqlite3VdbeChangeP5(v, OPFLAG_PERMUTE);
- sqlite3VdbeAddOp3(v, OP_Jump, addrAltB, addrAeqB, addrAgtB);
-
- /* Release temporary registers
- */
- if( regPrev ){
- sqlite3ReleaseTempRange(pParse, regPrev, nOrderBy+1);
- }
+ sqlite3VdbeAddOp3(v, OP_Jump, addrAltB, addrAeqB, addrAgtB); VdbeCoverage(v);
/* Jump to the this point in order to terminate the query.
*/
@@ -96847,7 +112730,7 @@ static int multiSelectOrderBy(
if( pDest->eDest==SRT_Output ){
Select *pFirst = pPrior;
while( pFirst->pPrior ) pFirst = pFirst->pPrior;
- generateColumnNames(pParse, 0, pFirst->pEList);
+ generateColumnNames(pParse, pFirst->pSrc, pFirst->pEList);
}
/* Reassembly the compound query so that it will be freed correctly
@@ -96856,18 +112739,19 @@ static int multiSelectOrderBy(
sqlite3SelectDelete(db, p->pPrior);
}
p->pPrior = pPrior;
+ pPrior->pNext = p;
/*** TBD: Insert subroutine calls to close cursors on incomplete
**** subqueries ****/
explainComposite(pParse, p->op, iSub1, iSub2, 0);
- return SQLITE_OK;
+ return pParse->nErr!=0;
}
#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 *);
+static void substSelect(sqlite3*, Select *, int, ExprList*, int);
/*
** Scan through the expression pExpr. Replace every reference to
@@ -96904,7 +112788,7 @@ static Expr *substExpr(
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);
+ substSelect(db, pExpr->x.pSelect, iTable, pEList, 1);
}else{
substExprList(db, pExpr->x.pList, iTable, pEList);
}
@@ -96927,25 +112811,28 @@ 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 */
+ ExprList *pEList, /* Substitute values */
+ int doPrior /* Do substitutes on p->pPrior too */
){
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) ){
+ do{
+ 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);
+ pSrc = p->pSrc;
+ assert( pSrc!=0 );
for(i=pSrc->nSrc, pItem=pSrc->a; i>0; i--, pItem++){
- substSelect(db, pItem->pSelect, iTable, pEList);
+ substSelect(db, pItem->pSelect, iTable, pEList, 1);
+ if( pItem->fg.isTabFunc ){
+ substExprList(db, pItem->u1.pFuncArg, iTable, pEList);
+ }
}
- }
+ }while( doPrior && (p = p->pPrior)!=0 );
}
#endif /* !defined(SQLITE_OMIT_SUBQUERY) || !defined(SQLITE_OMIT_VIEW) */
@@ -96971,7 +112858,7 @@ static void substSelect(
**
** SELECT x+y AS a FROM t1 WHERE z<100 AND a>5
**
-** The code generated for this simpification gives the same result
+** The code generated for this simplification 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.
@@ -96980,7 +112867,10 @@ static void substSelect(
**
** (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.
+** (2) The subquery is not an aggregate or (2a) the outer query is not a join
+** and (2b) the outer query does not use subqueries other than the one
+** FROM-clause subquery that is a candidate for flattening. (2b is
+** due to ticket [2f7170d73bf9abf80] from 2015-02-09.)
**
** (3) The subquery is not the right operand of a left outer join
** (Originally ticket #306. Strengthened by ticket #3300)
@@ -97004,8 +112894,10 @@ static void substSelect(
** (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.
+** (**) Restriction (10) was removed from the code on 2005-02-05 but we
+** accidently carried the comment forward until 2014-09-15. Original
+** text: "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.
**
@@ -97061,6 +112953,19 @@ static void substSelect(
** (21) The subquery does not use LIMIT or the outer query is not
** DISTINCT. (See ticket [752e1646fc]).
**
+** (22) The subquery is not a recursive CTE.
+**
+** (23) The parent is not a recursive CTE, or the sub-query is not a
+** compound query. This restriction is because transforming the
+** parent to a compound query confuses the code that handles
+** recursive queries in multiSelect().
+**
+** (24) The subquery is not an aggregate that uses the built-in min() or
+** or max() functions. (Without this restriction, a query like:
+** "SELECT x FROM (SELECT max(y), x FROM t1)" would not necessarily
+** return the value X for which Y was maximal.)
+**
+**
** 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.
@@ -97079,7 +112984,7 @@ static int flattenSubquery(
int subqueryIsAgg /* True if the subquery uses aggregate functions */
){
const char *zSavedAuthContext = pParse->zAuthContext;
- Select *pParent;
+ Select *pParent; /* Current UNION ALL term of the other query */
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 */
@@ -97102,18 +113007,27 @@ static int flattenSubquery(
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) */
+ if( subqueryIsAgg ){
+ if( isAgg ) return 0; /* Restriction (1) */
+ if( pSrc->nSrc>1 ) return 0; /* Restriction (2a) */
+ if( (p->pWhere && ExprHasProperty(p->pWhere,EP_Subquery))
+ || (sqlite3ExprListFlags(p->pEList) & EP_Subquery)!=0
+ || (sqlite3ExprListFlags(p->pOrderBy) & EP_Subquery)!=0
+ ){
+ return 0; /* Restriction (2b) */
+ }
+ }
+
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
+ ** not arbitrary expressions, 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 ){
+ if( (p->selFlags & SF_Compound)!=0 && pSub->pLimit ){
return 0; /* Restriction (15) */
}
if( pSubSrc->nSrc==0 ) return 0; /* Restriction (7) */
@@ -97132,6 +113046,14 @@ static int flattenSubquery(
if( pSub->pLimit && (p->selFlags & SF_Distinct)!=0 ){
return 0; /* Restriction (21) */
}
+ testcase( pSub->selFlags & SF_Recursive );
+ testcase( pSub->selFlags & SF_MinMaxAgg );
+ if( pSub->selFlags & (SF_Recursive|SF_MinMaxAgg) ){
+ return 0; /* Restrictions (22) and (24) */
+ }
+ if( (p->selFlags & SF_Recursive) && pSub->pPrior ){
+ return 0; /* Restriction (23) */
+ }
/* OBSOLETE COMMENT 1:
** Restriction 3: If the subquery is a join, make sure the subquery is
@@ -97165,7 +113087,7 @@ static int flattenSubquery(
** 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 ){
+ if( (pSubitem->fg.jointype & JT_OUTER)!=0 ){
return 0;
}
@@ -97185,10 +113107,10 @@ static int flattenSubquery(
testcase( (pSub1->selFlags & (SF_Distinct|SF_Aggregate))==SF_Distinct );
testcase( (pSub1->selFlags & (SF_Distinct|SF_Aggregate))==SF_Aggregate );
assert( pSub->pSrc!=0 );
+ assert( pSub->pEList->nExpr==pSub1->pEList->nExpr );
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;
}
@@ -97199,12 +113121,14 @@ static int flattenSubquery(
if( p->pOrderBy ){
int ii;
for(ii=0; ii<p->pOrderBy->nExpr; ii++){
- if( p->pOrderBy->a[ii].iOrderByCol==0 ) return 0;
+ if( p->pOrderBy->a[ii].u.x.iOrderByCol==0 ) return 0;
}
}
}
/***** If we reach this point, flattening is permitted. *****/
+ SELECTTRACE(1,pParse,p,("flatten %s.%p from term %d\n",
+ pSub->zSelName, pSub, iFrom));
/* Authorize the subquery */
pParse->zAuthContext = pSubitem->zName;
@@ -97249,24 +113173,31 @@ static int flattenSubquery(
Select *pNew;
ExprList *pOrderBy = p->pOrderBy;
Expr *pLimit = p->pLimit;
+ Expr *pOffset = p->pOffset;
Select *pPrior = p->pPrior;
p->pOrderBy = 0;
p->pSrc = 0;
p->pPrior = 0;
p->pLimit = 0;
+ p->pOffset = 0;
pNew = sqlite3SelectDup(db, p, 0);
+ sqlite3SelectSetName(pNew, pSub->zSelName);
+ p->pOffset = pOffset;
p->pLimit = pLimit;
p->pOrderBy = pOrderBy;
p->pSrc = pSrc;
p->op = TK_ALL;
- p->pRightmost = 0;
if( pNew==0 ){
- pNew = pPrior;
+ p->pPrior = pPrior;
}else{
pNew->pPrior = pPrior;
- pNew->pRightmost = 0;
+ if( pPrior ) pPrior->pNext = pNew;
+ pNew->pNext = p;
+ p->pPrior = pNew;
+ SELECTTRACE(2,pParse,p,
+ ("compound-subquery flattener creates %s.%p as peer\n",
+ pNew->zSelName, pNew));
}
- p->pPrior = pNew;
if( db->mallocFailed ) return 1;
}
@@ -97327,7 +113258,7 @@ static int flattenSubquery(
if( pSrc ){
assert( pParent==p ); /* First time through the loop */
- jointype = pSubitem->jointype;
+ jointype = pSubitem->fg.jointype;
}else{
assert( pParent!=p ); /* 2nd and subsequent times through the loop */
pSrc = pParent->pSrc = sqlite3SrcListAppend(db, 0, 0, 0);
@@ -97348,9 +113279,9 @@ static int flattenSubquery(
**
** 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.
+ ** block of code will expand the outer query FROM clause 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);
@@ -97364,10 +113295,11 @@ static int flattenSubquery(
*/
for(i=0; i<nSubSrc; i++){
sqlite3IdListDelete(db, pSrc->a[i+iFrom].pUsing);
+ assert( pSrc->a[i+iFrom].fg.isTabFunc==0 );
pSrc->a[i+iFrom] = pSubSrc->a[i];
memset(&pSubSrc->a[i], 0, sizeof(pSubSrc->a[i]));
}
- pSrc->a[iFrom].jointype = jointype;
+ pSrc->a[iFrom].fg.jointype = jointype;
/* Now begin substituting subquery result set expressions for
** references to the iParent in the outer query.
@@ -97389,36 +113321,39 @@ static int flattenSubquery(
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 ){
+ /* At this point, any non-zero iOrderByCol values indicate that the
+ ** ORDER BY column expression is identical to the iOrderByCol'th
+ ** expression returned by SELECT statement pSub. Since these values
+ ** do not necessarily correspond to columns in SELECT statement pParent,
+ ** zero them before transfering the ORDER BY clause.
+ **
+ ** Not doing this may cause an error if a subsequent call to this
+ ** function attempts to flatten a compound sub-query into pParent
+ ** (the only way this can happen is if the compound sub-query is
+ ** currently part of pSub->pSrc). See ticket [d11a6e908f]. */
+ ExprList *pOrderBy = pSub->pOrderBy;
+ for(i=0; i<pOrderBy->nExpr; i++){
+ pOrderBy->a[i].u.x.iOrderByCol = 0;
+ }
assert( pParent->pOrderBy==0 );
- pParent->pOrderBy = pSub->pOrderBy;
+ assert( pSub->pPrior==0 );
+ pParent->pOrderBy = 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;
}
+ pWhere = sqlite3ExprDup(db, pSub->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);
}
+ substSelect(db, pParent, iParent, pSub->pEList, 0);
/* The flattened query is distinct if either the inner or the
** outer query is distinct.
@@ -97442,44 +113377,131 @@ static int flattenSubquery(
*/
sqlite3SelectDelete(db, pSub1);
+#if SELECTTRACE_ENABLED
+ if( sqlite3SelectTrace & 0x100 ){
+ SELECTTRACE(0x100,pParse,p,("After flattening:\n"));
+ sqlite3TreeViewSelect(0, p, 0);
+ }
+#endif
+
return 1;
}
#endif /* !defined(SQLITE_OMIT_SUBQUERY) || !defined(SQLITE_OMIT_VIEW) */
+
+
+#if !defined(SQLITE_OMIT_SUBQUERY) || !defined(SQLITE_OMIT_VIEW)
+/*
+** Make copies of relevant WHERE clause terms of the outer query into
+** the WHERE clause of subquery. Example:
+**
+** SELECT * FROM (SELECT a AS x, c-d AS y FROM t1) WHERE x=5 AND y=10;
+**
+** Transformed into:
+**
+** SELECT * FROM (SELECT a AS x, c-d AS y FROM t1 WHERE a=5 AND c-d=10)
+** WHERE x=5 AND y=10;
+**
+** The hope is that the terms added to the inner query will make it more
+** efficient.
+**
+** Do not attempt this optimization if:
+**
+** (1) The inner query is an aggregate. (In that case, we'd really want
+** to copy the outer WHERE-clause terms onto the HAVING clause of the
+** inner query. But they probably won't help there so do not bother.)
+**
+** (2) The inner query is the recursive part of a common table expression.
+**
+** (3) The inner query has a LIMIT clause (since the changes to the WHERE
+** close would change the meaning of the LIMIT).
+**
+** (4) The inner query is the right operand of a LEFT JOIN. (The caller
+** enforces this restriction since this routine does not have enough
+** information to know.)
+**
+** (5) The WHERE clause expression originates in the ON or USING clause
+** of a LEFT JOIN.
+**
+** Return 0 if no changes are made and non-zero if one or more WHERE clause
+** terms are duplicated into the subquery.
+*/
+static int pushDownWhereTerms(
+ sqlite3 *db, /* The database connection (for malloc()) */
+ Select *pSubq, /* The subquery whose WHERE clause is to be augmented */
+ Expr *pWhere, /* The WHERE clause of the outer query */
+ int iCursor /* Cursor number of the subquery */
+){
+ Expr *pNew;
+ int nChng = 0;
+ if( pWhere==0 ) return 0;
+ if( (pSubq->selFlags & (SF_Aggregate|SF_Recursive))!=0 ){
+ return 0; /* restrictions (1) and (2) */
+ }
+ if( pSubq->pLimit!=0 ){
+ return 0; /* restriction (3) */
+ }
+ while( pWhere->op==TK_AND ){
+ nChng += pushDownWhereTerms(db, pSubq, pWhere->pRight, iCursor);
+ pWhere = pWhere->pLeft;
+ }
+ if( ExprHasProperty(pWhere,EP_FromJoin) ) return 0; /* restriction 5 */
+ if( sqlite3ExprIsTableConstant(pWhere, iCursor) ){
+ nChng++;
+ while( pSubq ){
+ pNew = sqlite3ExprDup(db, pWhere, 0);
+ pNew = substExpr(db, pNew, iCursor, pSubq->pEList);
+ pSubq->pWhere = sqlite3ExprAnd(db, pSubq->pWhere, pNew);
+ pSubq = pSubq->pPrior;
+ }
+ }
+ return nChng;
+}
+#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:
+** Based on the contents of the AggInfo structure indicated by the first
+** argument, this function checks if the following are true:
**
-** 1. There is a single object in the FROM clause.
+** * the query contains just a single aggregate function,
+** * the aggregate function is either min() or max(), and
+** * the argument to the aggregate function is a column value.
**
-** 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.
+** If all of the above are true, then WHERE_ORDERBY_MIN or WHERE_ORDERBY_MAX
+** is returned as appropriate. Also, *ppMinMax is set to point to the
+** list of arguments passed to the aggregate before returning.
+**
+** Or, if the conditions above are not met, *ppMinMax is set to 0 and
+** WHERE_ORDERBY_NORMAL is returned.
*/
-static u8 minMaxQuery(Select *p){
- Expr *pExpr;
- ExprList *pEList = p->pEList;
+static u8 minMaxQuery(AggInfo *pAggInfo, ExprList **ppMinMax){
+ int eRet = WHERE_ORDERBY_NORMAL; /* Return value */
- 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;
+ *ppMinMax = 0;
+ if( pAggInfo->nFunc==1 ){
+ Expr *pExpr = pAggInfo->aFunc[0].pExpr; /* Aggregate function */
+ ExprList *pEList = pExpr->x.pList; /* Arguments to agg function */
+
+ assert( pExpr->op==TK_AGG_FUNCTION );
+ if( pEList && pEList->nExpr==1 && pEList->a[0].pExpr->op==TK_AGG_COLUMN ){
+ const char *zFunc = pExpr->u.zToken;
+ if( sqlite3StrICmp(zFunc, "min")==0 ){
+ eRet = WHERE_ORDERBY_MIN;
+ *ppMinMax = pEList;
+ }else if( sqlite3StrICmp(zFunc, "max")==0 ){
+ eRet = WHERE_ORDERBY_MAX;
+ *ppMinMax = pEList;
+ }
+ }
}
- return WHERE_ORDERBY_NORMAL;
+
+ assert( *ppMinMax==0 || (*ppMinMax)->nExpr==1 );
+ return eRet;
}
/*
** The select statement passed as the first argument is an aggregate query.
-** The second argment is the associated aggregate-info object. This
+** The second argument is the associated aggregate-info object. This
** function tests if the SELECT is of the form:
**
** SELECT count(*) FROM <tbl>
@@ -97506,7 +113528,7 @@ static Table *isSimpleCount(Select *p, AggInfo *pAggInfo){
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( (pAggInfo->aFunc[0].pFunc->funcFlags&SQLITE_FUNC_COUNT)==0 ) return 0;
if( pExpr->flags&EP_Distinct ) return 0;
return pTab;
@@ -97520,23 +113542,301 @@ static Table *isSimpleCount(Select *p, AggInfo *pAggInfo){
** pFrom->pIndex and return SQLITE_OK.
*/
SQLITE_PRIVATE int sqlite3IndexedByLookup(Parse *pParse, struct SrcList_item *pFrom){
- if( pFrom->pTab && pFrom->zIndex ){
+ if( pFrom->pTab && pFrom->fg.isIndexedBy ){
Table *pTab = pFrom->pTab;
- char *zIndex = pFrom->zIndex;
+ char *zIndexedBy = pFrom->u1.zIndexedBy;
Index *pIdx;
for(pIdx=pTab->pIndex;
- pIdx && sqlite3StrICmp(pIdx->zName, zIndex);
+ pIdx && sqlite3StrICmp(pIdx->zName, zIndexedBy);
pIdx=pIdx->pNext
);
if( !pIdx ){
- sqlite3ErrorMsg(pParse, "no such index: %s", zIndex, 0);
+ sqlite3ErrorMsg(pParse, "no such index: %s", zIndexedBy, 0);
pParse->checkSchema = 1;
return SQLITE_ERROR;
}
- pFrom->pIndex = pIdx;
+ pFrom->pIBIndex = pIdx;
}
return SQLITE_OK;
}
+/*
+** Detect compound SELECT statements that use an ORDER BY clause with
+** an alternative collating sequence.
+**
+** SELECT ... FROM t1 EXCEPT SELECT ... FROM t2 ORDER BY .. COLLATE ...
+**
+** These are rewritten as a subquery:
+**
+** SELECT * FROM (SELECT ... FROM t1 EXCEPT SELECT ... FROM t2)
+** ORDER BY ... COLLATE ...
+**
+** This transformation is necessary because the multiSelectOrderBy() routine
+** above that generates the code for a compound SELECT with an ORDER BY clause
+** uses a merge algorithm that requires the same collating sequence on the
+** result columns as on the ORDER BY clause. See ticket
+** http://www.sqlite.org/src/info/6709574d2a
+**
+** This transformation is only needed for EXCEPT, INTERSECT, and UNION.
+** The UNION ALL operator works fine with multiSelectOrderBy() even when
+** there are COLLATE terms in the ORDER BY.
+*/
+static int convertCompoundSelectToSubquery(Walker *pWalker, Select *p){
+ int i;
+ Select *pNew;
+ Select *pX;
+ sqlite3 *db;
+ struct ExprList_item *a;
+ SrcList *pNewSrc;
+ Parse *pParse;
+ Token dummy;
+
+ if( p->pPrior==0 ) return WRC_Continue;
+ if( p->pOrderBy==0 ) return WRC_Continue;
+ for(pX=p; pX && (pX->op==TK_ALL || pX->op==TK_SELECT); pX=pX->pPrior){}
+ if( pX==0 ) return WRC_Continue;
+ a = p->pOrderBy->a;
+ for(i=p->pOrderBy->nExpr-1; i>=0; i--){
+ if( a[i].pExpr->flags & EP_Collate ) break;
+ }
+ if( i<0 ) return WRC_Continue;
+
+ /* If we reach this point, that means the transformation is required. */
+
+ pParse = pWalker->pParse;
+ db = pParse->db;
+ pNew = sqlite3DbMallocZero(db, sizeof(*pNew) );
+ if( pNew==0 ) return WRC_Abort;
+ memset(&dummy, 0, sizeof(dummy));
+ pNewSrc = sqlite3SrcListAppendFromTerm(pParse,0,0,0,&dummy,pNew,0,0);
+ if( pNewSrc==0 ) return WRC_Abort;
+ *pNew = *p;
+ p->pSrc = pNewSrc;
+ p->pEList = sqlite3ExprListAppend(pParse, 0, sqlite3Expr(db, TK_ASTERISK, 0));
+ p->op = TK_SELECT;
+ p->pWhere = 0;
+ pNew->pGroupBy = 0;
+ pNew->pHaving = 0;
+ pNew->pOrderBy = 0;
+ p->pPrior = 0;
+ p->pNext = 0;
+ p->pWith = 0;
+ p->selFlags &= ~SF_Compound;
+ assert( (p->selFlags & SF_Converted)==0 );
+ p->selFlags |= SF_Converted;
+ assert( pNew->pPrior!=0 );
+ pNew->pPrior->pNext = pNew;
+ pNew->pLimit = 0;
+ pNew->pOffset = 0;
+ return WRC_Continue;
+}
+
+/*
+** Check to see if the FROM clause term pFrom has table-valued function
+** arguments. If it does, leave an error message in pParse and return
+** non-zero, since pFrom is not allowed to be a table-valued function.
+*/
+static int cannotBeFunction(Parse *pParse, struct SrcList_item *pFrom){
+ if( pFrom->fg.isTabFunc ){
+ sqlite3ErrorMsg(pParse, "'%s' is not a function", pFrom->zName);
+ return 1;
+ }
+ return 0;
+}
+
+#ifndef SQLITE_OMIT_CTE
+/*
+** Argument pWith (which may be NULL) points to a linked list of nested
+** WITH contexts, from inner to outermost. If the table identified by
+** FROM clause element pItem is really a common-table-expression (CTE)
+** then return a pointer to the CTE definition for that table. Otherwise
+** return NULL.
+**
+** If a non-NULL value is returned, set *ppContext to point to the With
+** object that the returned CTE belongs to.
+*/
+static struct Cte *searchWith(
+ With *pWith, /* Current innermost WITH clause */
+ struct SrcList_item *pItem, /* FROM clause element to resolve */
+ With **ppContext /* OUT: WITH clause return value belongs to */
+){
+ const char *zName;
+ if( pItem->zDatabase==0 && (zName = pItem->zName)!=0 ){
+ With *p;
+ for(p=pWith; p; p=p->pOuter){
+ int i;
+ for(i=0; i<p->nCte; i++){
+ if( sqlite3StrICmp(zName, p->a[i].zName)==0 ){
+ *ppContext = p;
+ return &p->a[i];
+ }
+ }
+ }
+ }
+ return 0;
+}
+
+/* The code generator maintains a stack of active WITH clauses
+** with the inner-most WITH clause being at the top of the stack.
+**
+** This routine pushes the WITH clause passed as the second argument
+** onto the top of the stack. If argument bFree is true, then this
+** WITH clause will never be popped from the stack. In this case it
+** should be freed along with the Parse object. In other cases, when
+** bFree==0, the With object will be freed along with the SELECT
+** statement with which it is associated.
+*/
+SQLITE_PRIVATE void sqlite3WithPush(Parse *pParse, With *pWith, u8 bFree){
+ assert( bFree==0 || (pParse->pWith==0 && pParse->pWithToFree==0) );
+ if( pWith ){
+ assert( pParse->pWith!=pWith );
+ pWith->pOuter = pParse->pWith;
+ pParse->pWith = pWith;
+ if( bFree ) pParse->pWithToFree = pWith;
+ }
+}
+
+/*
+** This function checks if argument pFrom refers to a CTE declared by
+** a WITH clause on the stack currently maintained by the parser. And,
+** if currently processing a CTE expression, if it is a recursive
+** reference to the current CTE.
+**
+** If pFrom falls into either of the two categories above, pFrom->pTab
+** and other fields are populated accordingly. The caller should check
+** (pFrom->pTab!=0) to determine whether or not a successful match
+** was found.
+**
+** Whether or not a match is found, SQLITE_OK is returned if no error
+** occurs. If an error does occur, an error message is stored in the
+** parser and some error code other than SQLITE_OK returned.
+*/
+static int withExpand(
+ Walker *pWalker,
+ struct SrcList_item *pFrom
+){
+ Parse *pParse = pWalker->pParse;
+ sqlite3 *db = pParse->db;
+ struct Cte *pCte; /* Matched CTE (or NULL if no match) */
+ With *pWith; /* WITH clause that pCte belongs to */
+
+ assert( pFrom->pTab==0 );
+
+ pCte = searchWith(pParse->pWith, pFrom, &pWith);
+ if( pCte ){
+ Table *pTab;
+ ExprList *pEList;
+ Select *pSel;
+ Select *pLeft; /* Left-most SELECT statement */
+ int bMayRecursive; /* True if compound joined by UNION [ALL] */
+ With *pSavedWith; /* Initial value of pParse->pWith */
+
+ /* If pCte->zCteErr is non-NULL at this point, then this is an illegal
+ ** recursive reference to CTE pCte. Leave an error in pParse and return
+ ** early. If pCte->zCteErr is NULL, then this is not a recursive reference.
+ ** In this case, proceed. */
+ if( pCte->zCteErr ){
+ sqlite3ErrorMsg(pParse, pCte->zCteErr, pCte->zName);
+ return SQLITE_ERROR;
+ }
+ if( cannotBeFunction(pParse, pFrom) ) return SQLITE_ERROR;
+
+ assert( pFrom->pTab==0 );
+ pFrom->pTab = pTab = sqlite3DbMallocZero(db, sizeof(Table));
+ if( pTab==0 ) return WRC_Abort;
+ pTab->nRef = 1;
+ pTab->zName = sqlite3DbStrDup(db, pCte->zName);
+ pTab->iPKey = -1;
+ pTab->nRowLogEst = 200; assert( 200==sqlite3LogEst(1048576) );
+ pTab->tabFlags |= TF_Ephemeral | TF_NoVisibleRowid;
+ pFrom->pSelect = sqlite3SelectDup(db, pCte->pSelect, 0);
+ if( db->mallocFailed ) return SQLITE_NOMEM;
+ assert( pFrom->pSelect );
+
+ /* Check if this is a recursive CTE. */
+ pSel = pFrom->pSelect;
+ bMayRecursive = ( pSel->op==TK_ALL || pSel->op==TK_UNION );
+ if( bMayRecursive ){
+ int i;
+ SrcList *pSrc = pFrom->pSelect->pSrc;
+ for(i=0; i<pSrc->nSrc; i++){
+ struct SrcList_item *pItem = &pSrc->a[i];
+ if( pItem->zDatabase==0
+ && pItem->zName!=0
+ && 0==sqlite3StrICmp(pItem->zName, pCte->zName)
+ ){
+ pItem->pTab = pTab;
+ pItem->fg.isRecursive = 1;
+ pTab->nRef++;
+ pSel->selFlags |= SF_Recursive;
+ }
+ }
+ }
+
+ /* Only one recursive reference is permitted. */
+ if( pTab->nRef>2 ){
+ sqlite3ErrorMsg(
+ pParse, "multiple references to recursive table: %s", pCte->zName
+ );
+ return SQLITE_ERROR;
+ }
+ assert( pTab->nRef==1 || ((pSel->selFlags&SF_Recursive) && pTab->nRef==2 ));
+
+ pCte->zCteErr = "circular reference: %s";
+ pSavedWith = pParse->pWith;
+ pParse->pWith = pWith;
+ sqlite3WalkSelect(pWalker, bMayRecursive ? pSel->pPrior : pSel);
+ pParse->pWith = pWith;
+
+ for(pLeft=pSel; pLeft->pPrior; pLeft=pLeft->pPrior);
+ pEList = pLeft->pEList;
+ if( pCte->pCols ){
+ if( pEList && pEList->nExpr!=pCte->pCols->nExpr ){
+ sqlite3ErrorMsg(pParse, "table %s has %d values for %d columns",
+ pCte->zName, pEList->nExpr, pCte->pCols->nExpr
+ );
+ pParse->pWith = pSavedWith;
+ return SQLITE_ERROR;
+ }
+ pEList = pCte->pCols;
+ }
+
+ sqlite3ColumnsFromExprList(pParse, pEList, &pTab->nCol, &pTab->aCol);
+ if( bMayRecursive ){
+ if( pSel->selFlags & SF_Recursive ){
+ pCte->zCteErr = "multiple recursive references: %s";
+ }else{
+ pCte->zCteErr = "recursive reference in a subquery: %s";
+ }
+ sqlite3WalkSelect(pWalker, pSel);
+ }
+ pCte->zCteErr = 0;
+ pParse->pWith = pSavedWith;
+ }
+
+ return SQLITE_OK;
+}
+#endif
+
+#ifndef SQLITE_OMIT_CTE
+/*
+** If the SELECT passed as the second argument has an associated WITH
+** clause, pop it from the stack stored as part of the Parse object.
+**
+** This function is used as the xSelectCallback2() callback by
+** sqlite3SelectExpand() when walking a SELECT tree to resolve table
+** names and other FROM clause elements.
+*/
+static void selectPopWith(Walker *pWalker, Select *p){
+ Parse *pParse = pWalker->pParse;
+ With *pWith = findRightmost(p)->pWith;
+ if( pWith!=0 ){
+ assert( pParse->pWith==pWith );
+ pParse->pWith = pWith->pOuter;
+ }
+}
+#else
+#define selectPopWith 0
+#endif
/*
** This routine is a Walker callback for "expanding" a SELECT statement.
@@ -97550,10 +113850,10 @@ SQLITE_PRIVATE int sqlite3IndexedByLookup(Parse *pParse, struct SrcList_item *pF
** 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
+** without worrying about messing up the persistent representation
** of the view.
**
-** (3) Add terms to the WHERE clause to accomodate the NATURAL keyword
+** (3) Add terms to the WHERE clause to accommodate 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
@@ -97569,16 +113869,21 @@ static int selectExpander(Walker *pWalker, Select *p){
ExprList *pEList;
struct SrcList_item *pFrom;
sqlite3 *db = pParse->db;
+ Expr *pE, *pRight, *pExpr;
+ u16 selFlags = p->selFlags;
+ p->selFlags |= SF_Expanded;
if( db->mallocFailed ){
return WRC_Abort;
}
- if( NEVER(p->pSrc==0) || (p->selFlags & SF_Expanded)!=0 ){
+ if( NEVER(p->pSrc==0) || (selFlags & SF_Expanded)!=0 ){
return WRC_Prune;
}
- p->selFlags |= SF_Expanded;
pTabList = p->pSrc;
pEList = p->pEList;
+ if( pWalker->xSelectCallback2==selectPopWith ){
+ sqlite3WithPush(pParse, findRightmost(p)->pWith, 0);
+ }
/* Make sure cursor numbers have been assigned to all entries in
** the FROM clause of the SELECT statement.
@@ -97591,27 +113896,28 @@ static int selectExpander(Walker *pWalker, Select *p){
*/
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;
- }
+ assert( pFrom->fg.isRecursive==0 || pFrom->pTab!=0 );
+ if( pFrom->fg.isRecursive ) continue;
+ assert( pFrom->pTab==0 );
+#ifndef SQLITE_OMIT_CTE
+ if( withExpand(pWalker, pFrom) ) return WRC_Abort;
+ if( pFrom->pTab ) {} else
+#endif
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);
+ if( sqlite3WalkSelect(pWalker, pSel) ) return WRC_Abort;
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);
+ pTab->zName = sqlite3MPrintf(db, "sqlite_sq_%p", (void*)pTab);
while( pSel->pPrior ){ pSel = pSel->pPrior; }
- selectColumnsFromExprList(pParse, pSel->pEList, &pTab->nCol, &pTab->aCol);
+ sqlite3ColumnsFromExprList(pParse, pSel->pEList,&pTab->nCol,&pTab->aCol);
pTab->iPKey = -1;
- pTab->nRowEst = 1000000;
+ pTab->nRowLogEst = 200; assert( 200==sqlite3LogEst(1048576) );
pTab->tabFlags |= TF_Ephemeral;
#endif
}else{
@@ -97619,14 +113925,27 @@ static int selectExpander(Walker *pWalker, Select *p){
assert( pFrom->pTab==0 );
pFrom->pTab = pTab = sqlite3LocateTableItem(pParse, 0, pFrom);
if( pTab==0 ) return WRC_Abort;
+ if( pTab->nRef==0xffff ){
+ sqlite3ErrorMsg(pParse, "too many references to \"%s\": max 65535",
+ pTab->zName);
+ pFrom->pTab = 0;
+ return WRC_Abort;
+ }
pTab->nRef++;
+ if( !IsVirtual(pTab) && cannotBeFunction(pParse, pFrom) ){
+ return WRC_Abort;
+ }
#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( IsVirtual(pTab) || pTab->pSelect ){
+ i16 nCol;
if( sqlite3ViewGetColumnNames(pParse, pTab) ) return WRC_Abort;
assert( pFrom->pSelect==0 );
pFrom->pSelect = sqlite3SelectDup(db, pTab->pSelect, 0);
+ sqlite3SelectSetName(pFrom->pSelect, pTab->zName);
+ nCol = pTab->nCol;
+ pTab->nCol = -1;
sqlite3WalkSelect(pWalker, pFrom->pSelect);
+ pTab->nCol = nCol;
}
#endif
}
@@ -97646,19 +113965,20 @@ static int selectExpander(Walker *pWalker, Select *p){
/* 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.
+ ** with the TK_ASTERISK operator for each "*" that it found in the column
+ ** list. The following code just has to locate the TK_ASTERISK
+ ** 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;
+ pE = pEList->a[k].pExpr;
+ if( pE->op==TK_ASTERISK ) 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( pE->op==TK_DOT && pE->pRight->op==TK_ASTERISK ) break;
}
if( k<pEList->nExpr ){
/*
@@ -97673,9 +113993,12 @@ static int selectExpander(Walker *pWalker, Select *p){
&& (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) ){
+ pE = a[k].pExpr;
+ pRight = pE->pRight;
+ assert( pE->op!=TK_DOT || pRight!=0 );
+ if( pE->op!=TK_ASTERISK
+ && (pE->op!=TK_DOT || pRight->op!=TK_ASTERISK)
+ ){
/* This particular expression does not need to be expanded.
*/
pNew = sqlite3ExprListAppend(pParse, pNew, a[k].pExpr);
@@ -97690,43 +114013,56 @@ static int selectExpander(Walker *pWalker, Select *p){
/* 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 */
+ char *zTName = 0; /* 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;
+ Select *pSub = pFrom->pSelect;
char *zTabName = pFrom->zAlias;
+ const char *zSchemaName = 0;
+ int iDb;
if( zTabName==0 ){
zTabName = pTab->zName;
}
if( db->mallocFailed ) break;
- if( zTName && sqlite3StrICmp(zTName, zTabName)!=0 ){
- continue;
+ if( pSub==0 || (pSub->selFlags & SF_NestedFrom)==0 ){
+ pSub = 0;
+ if( zTName && sqlite3StrICmp(zTName, zTabName)!=0 ){
+ continue;
+ }
+ iDb = sqlite3SchemaToIndex(db, pTab->pSchema);
+ zSchemaName = iDb>=0 ? db->aDb[iDb].zName : "*";
}
- 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.
+ assert( zName );
+ if( zTName && pSub
+ && sqlite3MatchSpanName(pSub->pEList->a[j].zSpan, 0, zTName, 0)==0
+ ){
+ continue;
+ }
+
+ /* If a column is marked as 'hidden', omit it from the expanded
+ ** result-set list unless the SELECT has the SF_IncludeHidden
+ ** bit set.
*/
- if( IsHiddenColumn(&pTab->aCol[j]) ){
- assert(IsVirtual(pTab));
+ if( (p->selFlags & SF_IncludeHidden)==0
+ && IsHiddenColumn(&pTab->aCol[j])
+ ){
continue;
}
+ tableSeen = 1;
if( i>0 && zTName==0 ){
- if( (pFrom->jointype & JT_NATURAL)!=0
+ if( (pFrom->fg.jointype & JT_NATURAL)!=0
&& tableAndColumnIndex(pTabList, i, zName, 0, 0)
){
/* In a NATURAL join, omit the join columns from the
@@ -97746,6 +114082,10 @@ static int selectExpander(Walker *pWalker, Select *p){
Expr *pLeft;
pLeft = sqlite3Expr(db, TK_ID, zTabName);
pExpr = sqlite3PExpr(pParse, TK_DOT, pLeft, pRight, 0);
+ if( zSchemaName ){
+ pLeft = sqlite3Expr(db, TK_ID, zSchemaName);
+ pExpr = sqlite3PExpr(pParse, TK_DOT, pLeft, pExpr, 0);
+ }
if( longNames ){
zColname = sqlite3MPrintf(db, "%s.%s", zTabName, zName);
zToFree = zColname;
@@ -97757,6 +114097,18 @@ static int selectExpander(Walker *pWalker, Select *p){
sColname.z = zColname;
sColname.n = sqlite3Strlen30(zColname);
sqlite3ExprListSetName(pParse, pNew, &sColname, 0);
+ if( pNew && (p->selFlags & SF_NestedFrom)!=0 ){
+ struct ExprList_item *pX = &pNew->a[pNew->nExpr-1];
+ if( pSub ){
+ pX->zSpan = sqlite3DbStrDup(db, pSub->pEList->a[j].zSpan);
+ testcase( pX->zSpan==0 );
+ }else{
+ pX->zSpan = sqlite3MPrintf(db, "%s.%s.%s",
+ zSchemaName, zTabName, zColname);
+ testcase( pX->zSpan==0 );
+ }
+ pX->bSpanIsTab = 1;
+ }
sqlite3DbFree(db, zToFree);
}
}
@@ -97775,6 +114127,7 @@ static int selectExpander(Walker *pWalker, Select *p){
#if SQLITE_MAX_COLUMN
if( p->pEList && p->pEList->nExpr>db->aLimit[SQLITE_LIMIT_COLUMN] ){
sqlite3ErrorMsg(pParse, "too many columns in result set");
+ return WRC_Abort;
}
#endif
return WRC_Continue;
@@ -97789,7 +114142,7 @@ static int selectExpander(Walker *pWalker, Select *p){
** Walker.xSelectCallback is set to do something useful for every
** subquery in the parser tree.
*/
-static int exprWalkNoop(Walker *NotUsed, Expr *NotUsed2){
+SQLITE_PRIVATE int sqlite3ExprWalkNoop(Walker *NotUsed, Expr *NotUsed2){
UNUSED_PARAMETER2(NotUsed, NotUsed2);
return WRC_Continue;
}
@@ -97809,9 +114162,17 @@ static int exprWalkNoop(Walker *NotUsed, Expr *NotUsed2){
*/
static void sqlite3SelectExpand(Parse *pParse, Select *pSelect){
Walker w;
- w.xSelectCallback = selectExpander;
- w.xExprCallback = exprWalkNoop;
+ memset(&w, 0, sizeof(w));
+ w.xExprCallback = sqlite3ExprWalkNoop;
w.pParse = pParse;
+ if( pParse->hasCompound ){
+ w.xSelectCallback = convertCompoundSelectToSubquery;
+ sqlite3WalkSelect(&w, pSelect);
+ }
+ w.xSelectCallback = selectExpander;
+ if( (pSelect->selFlags & SF_MultiValue)==0 ){
+ w.xSelectCallback2 = selectPopWith;
+ }
sqlite3WalkSelect(&w, pSelect);
}
@@ -97830,29 +114191,29 @@ static void sqlite3SelectExpand(Parse *pParse, Select *pSelect){
** at that point because identifiers had not yet been resolved. This
** routine is called after identifier resolution.
*/
-static int selectAddSubqueryTypeInfo(Walker *pWalker, Select *p){
+static void 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 );
+ assert( (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;
+ assert( pTab!=0 );
+ if( (pTab->tabFlags & TF_Ephemeral)!=0 ){
+ /* A sub-query in the FROM clause of a SELECT */
+ Select *pSel = pFrom->pSelect;
+ if( pSel ){
while( pSel->pPrior ) pSel = pSel->pPrior;
- selectAddColumnTypeAndCollation(pParse, pTab->nCol, pTab->aCol, pSel);
+ selectAddColumnTypeAndCollation(pParse, pTab, pSel);
}
}
}
- return WRC_Continue;
}
#endif
@@ -97867,8 +114228,9 @@ static int selectAddSubqueryTypeInfo(Walker *pWalker, Select *p){
static void sqlite3SelectAddTypeInfo(Parse *pParse, Select *pSelect){
#ifndef SQLITE_OMIT_SUBQUERY
Walker w;
- w.xSelectCallback = selectAddSubqueryTypeInfo;
- w.xExprCallback = exprWalkNoop;
+ memset(&w, 0, sizeof(w));
+ w.xSelectCallback2 = selectAddSubqueryTypeInfo;
+ w.xExprCallback = sqlite3ExprWalkNoop;
w.pParse = pParse;
sqlite3WalkSelect(&w, pSelect);
#endif
@@ -97895,6 +114257,7 @@ SQLITE_PRIVATE void sqlite3SelectPrep(
sqlite3 *db;
if( NEVER(p==0) ) return;
db = pParse->db;
+ if( db->mallocFailed ) return;
if( p->selFlags & SF_HasTypeInfo ) return;
sqlite3SelectExpand(pParse, p);
if( pParse->nErr || db->mallocFailed ) return;
@@ -97915,14 +114278,23 @@ static void resetAccumulator(Parse *pParse, AggInfo *pAggInfo){
Vdbe *v = pParse->pVdbe;
int i;
struct AggInfo_func *pFunc;
- if( pAggInfo->nFunc+pAggInfo->nColumn==0 ){
- return;
- }
+ int nReg = pAggInfo->nFunc + pAggInfo->nColumn;
+ if( nReg==0 ) return;
+#ifdef SQLITE_DEBUG
+ /* Verify that all AggInfo registers are within the range specified by
+ ** AggInfo.mnReg..AggInfo.mxReg */
+ assert( nReg==pAggInfo->mxReg-pAggInfo->mnReg+1 );
for(i=0; i<pAggInfo->nColumn; i++){
- sqlite3VdbeAddOp2(v, OP_Null, 0, pAggInfo->aCol[i].iMem);
+ assert( pAggInfo->aCol[i].iMem>=pAggInfo->mnReg
+ && pAggInfo->aCol[i].iMem<=pAggInfo->mxReg );
}
+ for(i=0; i<pAggInfo->nFunc; i++){
+ assert( pAggInfo->aFunc[i].iMem>=pAggInfo->mnReg
+ && pAggInfo->aFunc[i].iMem<=pAggInfo->mxReg );
+ }
+#endif
+ sqlite3VdbeAddOp3(v, OP_Null, 0, pAggInfo->mnReg, pAggInfo->mxReg);
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) );
@@ -97931,9 +114303,9 @@ static void resetAccumulator(Parse *pParse, AggInfo *pAggInfo){
"argument");
pFunc->iDistinct = -1;
}else{
- KeyInfo *pKeyInfo = keyInfoFromExprList(pParse, pE->x.pList);
+ KeyInfo *pKeyInfo = keyInfoFromExprList(pParse, pE->x.pList, 0, 0);
sqlite3VdbeAddOp4(v, OP_OpenEphemeral, pFunc->iDistinct, 0, 0,
- (char*)pKeyInfo, P4_KEYINFO_HANDOFF);
+ (char*)pKeyInfo, P4_KEYINFO);
}
}
}
@@ -97968,7 +114340,6 @@ static void updateAccumulator(Parse *pParse, AggInfo *pAggInfo){
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;
@@ -97978,17 +114349,18 @@ static void updateAccumulator(Parse *pParse, AggInfo *pAggInfo){
if( pList ){
nArg = pList->nExpr;
regAgg = sqlite3GetTempRange(pParse, nArg);
- sqlite3ExprCodeExprList(pParse, pList, regAgg, 1);
+ sqlite3ExprCodeExprList(pParse, pList, regAgg, 0, SQLITE_ECEL_DUP);
}else{
nArg = 0;
regAgg = 0;
}
if( pF->iDistinct>=0 ){
addrNext = sqlite3VdbeMakeLabel(v);
- assert( nArg==1 );
+ testcase( nArg==0 ); /* Error condition */
+ testcase( nArg>1 ); /* Also an error */
codeDistinct(pParse, pF->iDistinct, addrNext, 1, regAgg);
}
- if( pF->pFunc->flags & SQLITE_FUNC_NEEDCOLL ){
+ if( pF->pFunc->funcFlags & SQLITE_FUNC_NEEDCOLL ){
CollSeq *pColl = 0;
struct ExprList_item *pItem;
int j;
@@ -98002,7 +114374,7 @@ static void updateAccumulator(Parse *pParse, AggInfo *pAggInfo){
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,
+ sqlite3VdbeAddOp4(v, OP_AggStep0, 0, regAgg, pF->iMem,
(void*)pF->pFunc, P4_FUNCDEF);
sqlite3VdbeChangeP5(v, (u8)nArg);
sqlite3ExprCacheAffinityChange(pParse, regAgg, nArg);
@@ -98024,7 +114396,7 @@ static void updateAccumulator(Parse *pParse, AggInfo *pAggInfo){
** values to an OP_Copy.
*/
if( regHit ){
- addrHitTest = sqlite3VdbeAddOp1(v, OP_If, regHit);
+ addrHitTest = sqlite3VdbeAddOp1(v, OP_If, regHit); VdbeCoverage(v);
}
sqlite3ExprCacheClear(pParse);
for(i=0, pC=pAggInfo->aCol; i<pAggInfo->nAccumulator; i++, pC++){
@@ -98048,11 +114420,11 @@ static void explainSimpleCount(
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
+ int bCover = (pIdx!=0 && (HasRowid(pTab) || !IsPrimaryKeyIndex(pIdx)));
+ char *zEqp = sqlite3MPrintf(pParse->db, "SCAN TABLE %s%s%s",
+ pTab->zName,
+ bCover ? " USING COVERING INDEX " : "",
+ bCover ? pIdx->zName : ""
);
sqlite3VdbeAddOp4(
pParse->pVdbe, OP_Explain, pParse->iSelectId, 0, 0, zEqp, P4_DYNAMIC
@@ -98066,50 +114438,8 @@ static void explainSimpleCount(
/*
** 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.
+** The results are returned according to the SelectDest structure.
+** See comments in sqliteInt.h for further information.
**
** This routine returns the number of errors. If any errors are
** encountered, then an appropriate error message is left in
@@ -98127,15 +114457,14 @@ SQLITE_PRIVATE int sqlite3Select(
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. */
+ ExprList *pEList = 0; /* 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 */
+ SortCtx sSort; /* Info on how to code the ORDER BY clause */
AggInfo sAggInfo; /* Information used by aggregate queries */
int iEnd; /* Address of the end of the query */
sqlite3 *db; /* The database connection */
@@ -98151,10 +114480,23 @@ SQLITE_PRIVATE int sqlite3Select(
}
if( sqlite3AuthCheck(pParse, SQLITE_SELECT, 0, 0, 0) ) return 1;
memset(&sAggInfo, 0, sizeof(sAggInfo));
+#if SELECTTRACE_ENABLED
+ pParse->nSelectIndent++;
+ SELECTTRACE(1,pParse,p, ("begin processing:\n"));
+ if( sqlite3SelectTrace & 0x100 ){
+ sqlite3TreeViewSelect(0, p, 0);
+ }
+#endif
+ assert( p->pOrderBy==0 || pDest->eDest!=SRT_DistFifo );
+ assert( p->pOrderBy==0 || pDest->eDest!=SRT_Fifo );
+ assert( p->pOrderBy==0 || pDest->eDest!=SRT_DistQueue );
+ assert( p->pOrderBy==0 || pDest->eDest!=SRT_Queue );
if( IgnorableOrderby(pDest) ){
assert(pDest->eDest==SRT_Exists || pDest->eDest==SRT_Union ||
- pDest->eDest==SRT_Except || pDest->eDest==SRT_Discard);
+ pDest->eDest==SRT_Except || pDest->eDest==SRT_Discard ||
+ pDest->eDest==SRT_Queue || pDest->eDest==SRT_DistFifo ||
+ pDest->eDest==SRT_DistQueue || pDest->eDest==SRT_Fifo);
/* If ORDER BY makes no difference in the output then neither does
** DISTINCT so it can be removed too. */
sqlite3ExprListDelete(db, p->pOrderBy);
@@ -98162,38 +114504,93 @@ SQLITE_PRIVATE int sqlite3Select(
p->selFlags &= ~SF_Distinct;
}
sqlite3SelectPrep(pParse, p, 0);
- pOrderBy = p->pOrderBy;
+ memset(&sSort, 0, sizeof(sSort));
+ sSort.pOrderBy = p->pOrderBy;
pTabList = p->pSrc;
- pEList = p->pEList;
if( pParse->nErr || db->mallocFailed ){
goto select_end;
}
+ assert( p->pEList!=0 );
isAgg = (p->selFlags & SF_Aggregate)!=0;
- assert( pEList!=0 );
+#if SELECTTRACE_ENABLED
+ if( sqlite3SelectTrace & 0x100 ){
+ SELECTTRACE(0x100,pParse,p, ("after name resolution:\n"));
+ sqlite3TreeViewSelect(0, p, 0);
+ }
+#endif
- /* 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) ){
+ if( checkForMultiColumnSelectError(pParse, pDest, p->pEList->nExpr) ){
goto select_end;
}
#endif
- /* Generate code for all sub-queries in the FROM clause
+ /* Try to flatten subqueries in the FROM clause up into the main query
*/
#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;
+ Table *pTab = pItem->pTab;
+ if( pSub==0 ) continue;
+
+ /* Catch mismatch in the declared columns of a view and the number of
+ ** columns in the SELECT on the RHS */
+ if( pTab->nCol!=pSub->pEList->nExpr ){
+ sqlite3ErrorMsg(pParse, "expected %d columns for '%s' but got %d",
+ pTab->nCol, pTab->zName, pSub->pEList->nExpr);
+ goto select_end;
+ }
+
+ 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;
+ }
+ pTabList = p->pSrc;
+ if( db->mallocFailed ) goto select_end;
+ if( !IgnorableOrderby(pDest) ){
+ sSort.pOrderBy = p->pOrderBy;
+ }
+ }
+#endif
+
+ /* Get a pointer the VDBE under construction, allocating a new VDBE if one
+ ** does not already exist */
+ v = sqlite3GetVdbe(pParse);
+ if( v==0 ) goto select_end;
+
+#ifndef SQLITE_OMIT_COMPOUND_SELECT
+ /* Handle compound SELECT statements using the separate multiSelect()
+ ** procedure.
+ */
+ if( p->pPrior ){
+ rc = multiSelect(pParse, p, pDest);
+ explainSetInteger(pParse->iSelectId, iRestoreSelectId);
+#if SELECTTRACE_ENABLED
+ SELECTTRACE(1,pParse,p,("end compound-select processing\n"));
+ pParse->nSelectIndent--;
+#endif
+ return rc;
+ }
+#endif
+ /* Generate code for all sub-queries in the FROM clause
+ */
+#if !defined(SQLITE_OMIT_SUBQUERY) || !defined(SQLITE_OMIT_VIEW)
+ for(i=0; i<pTabList->nSrc; i++){
+ struct SrcList_item *pItem = &pTabList->a[i];
+ SelectDest dest;
+ Select *pSub = pItem->pSelect;
if( pSub==0 ) continue;
/* Sometimes the code for a subquery will be generated more than
@@ -98203,14 +114600,14 @@ SQLITE_PRIVATE int sqlite3Select(
** is sufficient, though the subroutine to manifest the view does need
** to be invoked again. */
if( pItem->addrFillSub ){
- if( pItem->viaCoroutine==0 ){
+ if( pItem->fg.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
+ ** tree referred 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
@@ -98218,50 +114615,41 @@ SQLITE_PRIVATE int sqlite3Select(
*/
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;
+ /* Make copies of constant WHERE-clause terms in the outer query down
+ ** inside the subquery. This can help the subquery to run more efficiently.
+ */
+ if( (pItem->fg.jointype & JT_OUTER)==0
+ && pushDownWhereTerms(db, pSub, p->pWhere, pItem->iCursor)
+ ){
+#if SELECTTRACE_ENABLED
+ if( sqlite3SelectTrace & 0x100 ){
+ SELECTTRACE(0x100,pParse,p,("After WHERE-clause push-down:\n"));
+ sqlite3TreeViewSelect(0, p, 0);
}
- i = -1;
- }else if( pTabList->nSrc==1 && (p->selFlags & SF_Materialize)==0
- && OptimizationEnabled(db, SQLITE_SubqCoroutine)
+#endif
+ }
+
+ /* Generate code to implement the subquery
+ */
+ if( pTabList->nSrc==1
+ && (p->selFlags & SF_All)==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;
+ int addrTop = sqlite3VdbeCurrentAddr(v)+1;
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));
+ sqlite3VdbeAddOp3(v, OP_InitCoroutine, pItem->regReturn, 0, addrTop);
+ VdbeComment((v, "%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));
+ pItem->pTab->nRowLogEst = sqlite3LogEst(pSub->nSelectRow);
+ pItem->fg.viaCoroutine = 1;
+ pItem->regResult = dest.iSdst;
+ sqlite3VdbeAddOp1(v, OP_EndCoroutine, pItem->regReturn);
sqlite3VdbeJumpHere(v, addrTop-1);
sqlite3ClearTempRegCache(pParse);
}else{
@@ -98277,76 +114665,45 @@ SQLITE_PRIVATE int sqlite3Select(
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
+ if( pItem->fg.isCorrelated==0 ){
+ /* If the subquery is not 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);
+ onceAddr = sqlite3CodeOnce(pParse); VdbeCoverage(v);
+ VdbeComment((v, "materialize \"%s\"", pItem->pTab->zName));
+ }else{
+ VdbeNoopComment((v, "materialize \"%s\"", pItem->pTab->zName));
}
sqlite3SelectDestInit(&dest, SRT_EphemTab, pItem->iCursor);
explainSetInteger(pItem->iSelectId, (u8)pParse->iNextSelectId);
sqlite3Select(pParse, pSub, &dest);
- pItem->pTab->nRowEst = (unsigned)pSub->nSelectRow;
+ pItem->pTab->nRowLogEst = sqlite3LogEst(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;
- }
+ if( db->mallocFailed ) goto select_end;
pParse->nHeight -= sqlite3SelectExprHeight(p);
- pTabList = p->pSrc;
- if( !IgnorableOrderby(pDest) ){
- pOrderBy = p->pOrderBy;
- }
}
- pEList = p->pEList;
#endif
+
+ /* Various elements of the SELECT copied into local variables for
+ ** convenience */
+ pEList = p->pEList;
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;
+#if SELECTTRACE_ENABLED
+ if( sqlite3SelectTrace & 0x400 ){
+ SELECTTRACE(0x400,pParse,p,("After all FROM-clause analysis:\n"));
+ sqlite3TreeViewSelect(0, p, 0);
}
#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:
@@ -98355,7 +114712,7 @@ SQLITE_PRIVATE int sqlite3Select(
**
** is transformed to:
**
- ** SELECT xyz FROM ... GROUP BY xyz
+ ** SELECT xyz FROM ... GROUP BY xyz ORDER 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
@@ -98363,35 +114720,35 @@ SQLITE_PRIVATE int sqlite3Select(
** 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
+ && sqlite3ExprListCompare(sSort.pOrderBy, pEList, -1)==0
){
p->selFlags &= ~SF_Distinct;
- p->pGroupBy = sqlite3ExprListDup(db, p->pEList, 0);
- pGroupBy = p->pGroupBy;
- pOrderBy = 0;
+ pGroupBy = p->pGroupBy = sqlite3ExprListDup(db, pEList, 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 there is an ORDER BY clause, then create an ephemeral index to
+ ** do the sorting. But this sorting ephemeral 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 sSort.addrSortIndex variable is used to facilitate
+ ** that change.
*/
- if( pOrderBy ){
+ if( sSort.pOrderBy ){
KeyInfo *pKeyInfo;
- pKeyInfo = keyInfoFromExprList(pParse, pOrderBy);
- pOrderBy->iECursor = pParse->nTab++;
- p->addrOpenEphm[2] = addrSortIndex =
+ pKeyInfo = keyInfoFromExprList(pParse, sSort.pOrderBy, 0, pEList->nExpr);
+ sSort.iECursor = pParse->nTab++;
+ sSort.addrSortIndex =
sqlite3VdbeAddOp4(v, OP_OpenEphemeral,
- pOrderBy->iECursor, pOrderBy->nExpr+2, 0,
- (char*)pKeyInfo, P4_KEYINFO_HANDOFF);
+ sSort.iECursor, sSort.pOrderBy->nExpr+1+pEList->nExpr, 0,
+ (char*)pKeyInfo, P4_KEYINFO
+ );
}else{
- addrSortIndex = -1;
+ sSort.addrSortIndex = -1;
}
/* If the output is destined for a temporary table, open that table.
@@ -98403,21 +114760,21 @@ SQLITE_PRIVATE int sqlite3Select(
/* Set the limiter.
*/
iEnd = sqlite3VdbeMakeLabel(v);
- p->nSelectRow = (double)LARGEST_INT64;
+ p->nSelectRow = LARGEST_INT64;
computeLimitRegisters(pParse, p, iEnd);
- if( p->iLimit==0 && addrSortIndex>=0 ){
- sqlite3VdbeGetOp(v, addrSortIndex)->opcode = OP_SorterOpen;
- p->selFlags |= SF_UseSorter;
+ if( p->iLimit==0 && sSort.addrSortIndex>=0 ){
+ sqlite3VdbeChangeOpcode(v, sSort.addrSortIndex, OP_SorterOpen);
+ sSort.sortFlags |= SORTFLAG_UseSorter;
}
- /* Open a virtual index to use for the distinct set.
+ /* Open an ephemeral 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);
+ sDistinct.tabTnct, 0, 0,
+ (char*)keyInfoFromExprList(pParse, p->pEList,0,0),
+ P4_KEYINFO);
sqlite3VdbeChangeP5(v, BTREE_UNORDERED);
sDistinct.eTnctType = WHERE_DISTINCT_UNORDERED;
}else{
@@ -98426,27 +114783,37 @@ SQLITE_PRIVATE int sqlite3Select(
if( !isAgg && pGroupBy==0 ){
/* No aggregate functions and no GROUP BY clause */
- ExprList *pDist = (sDistinct.isTnct ? p->pEList : 0);
+ u16 wctrlFlags = (sDistinct.isTnct ? WHERE_WANT_DISTINCT : 0);
/* Begin the database scan. */
- pWInfo = sqlite3WhereBegin(pParse, pTabList, pWhere, pOrderBy, pDist, 0,0);
+ pWInfo = sqlite3WhereBegin(pParse, pTabList, pWhere, sSort.pOrderBy,
+ p->pEList, wctrlFlags, 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( sqlite3WhereOutputRowCount(pWInfo) < p->nSelectRow ){
+ p->nSelectRow = sqlite3WhereOutputRowCount(pWInfo);
+ }
+ if( sDistinct.isTnct && sqlite3WhereIsDistinct(pWInfo) ){
+ sDistinct.eTnctType = sqlite3WhereIsDistinct(pWInfo);
+ }
+ if( sSort.pOrderBy ){
+ sSort.nOBSat = sqlite3WhereIsOrdered(pWInfo);
+ if( sSort.nOBSat==sSort.pOrderBy->nExpr ){
+ sSort.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;
+ if( sSort.addrSortIndex>=0 && sSort.pOrderBy==0 ){
+ sqlite3VdbeChangeToNoop(v, sSort.addrSortIndex);
}
/* Use the standard inner loop. */
- selectInnerLoop(pParse, p, pEList, 0, 0, pOrderBy, &sDistinct, pDest,
- pWInfo->iContinue, pWInfo->iBreak);
+ selectInnerLoop(pParse, p, pEList, -1, &sSort, &sDistinct, pDest,
+ sqlite3WhereContinueLabel(pWInfo),
+ sqlite3WhereBreakLabel(pWInfo));
/* End the database scan loop.
*/
@@ -98465,6 +114832,7 @@ SQLITE_PRIVATE int sqlite3Select(
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 */
+ int orderByGrp = 0; /* True if the GROUP BY and ORDER BY are the same */
/* Remove any and all aliases between the result set and the
** GROUP BY clause.
@@ -98474,16 +114842,27 @@ SQLITE_PRIVATE int sqlite3Select(
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;
+ pItem->u.x.iAlias = 0;
}
for(k=pGroupBy->nExpr, pItem=pGroupBy->a; k>0; k--, pItem++){
- pItem->iAlias = 0;
+ pItem->u.x.iAlias = 0;
}
- if( p->nSelectRow>(double)100 ) p->nSelectRow = (double)100;
+ if( p->nSelectRow>100 ) p->nSelectRow = 100;
}else{
- p->nSelectRow = (double)1;
+ p->nSelectRow = 1;
}
+ /* If there is both a GROUP BY and an ORDER BY clause and they are
+ ** identical, then it may be possible to disable the ORDER BY clause
+ ** on the grounds that the GROUP BY will cause elements to come out
+ ** in the correct order. It also may not - the GROUP BY might use a
+ ** database index that causes rows to be grouped together as required
+ ** but not actually sorted. Either way, record the fact that the
+ ** ORDER BY and GROUP BY clauses are the same by setting the orderByGrp
+ ** variable. */
+ if( sqlite3ExprListCompare(pGroupBy, sSort.pOrderBy, -1)==0 ){
+ orderByGrp = 1;
+ }
/* Create a label to jump to when we want to abort the query */
addrEnd = sqlite3VdbeMakeLabel(v);
@@ -98496,10 +114875,11 @@ SQLITE_PRIVATE int sqlite3Select(
sNC.pParse = pParse;
sNC.pSrcList = pTabList;
sNC.pAggInfo = &sAggInfo;
- sAggInfo.nSortingColumn = pGroupBy ? pGroupBy->nExpr+1 : 0;
+ sAggInfo.mnReg = pParse->nMem+1;
+ sAggInfo.nSortingColumn = pGroupBy ? pGroupBy->nExpr : 0;
sAggInfo.pGroupBy = pGroupBy;
sqlite3ExprAnalyzeAggList(&sNC, pEList);
- sqlite3ExprAnalyzeAggList(&sNC, pOrderBy);
+ sqlite3ExprAnalyzeAggList(&sNC, sSort.pOrderBy);
if( pHaving ){
sqlite3ExprAnalyzeAggregates(&sNC, pHaving);
}
@@ -98510,6 +114890,7 @@ SQLITE_PRIVATE int sqlite3Select(
sqlite3ExprAnalyzeAggList(&sNC, sAggInfo.aFunc[i].pExpr->x.pList);
sNC.ncFlags &= ~NC_InAggFunc;
}
+ sAggInfo.mxReg = pParse->nMem;
if( db->mallocFailed ) goto select_end;
/* Processing for aggregates with GROUP BY is very different and
@@ -98517,7 +114898,7 @@ SQLITE_PRIVATE int sqlite3Select(
*/
if( pGroupBy ){
KeyInfo *pKeyInfo; /* Keying information for the group by clause */
- int j1; /* A-vs-B comparision jump */
+ int addr1; /* 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 */
@@ -98532,10 +114913,10 @@ SQLITE_PRIVATE int sqlite3Select(
** will be converted into a Noop.
*/
sAggInfo.sortingIdx = pParse->nTab++;
- pKeyInfo = keyInfoFromExprList(pParse, pGroupBy);
+ pKeyInfo = keyInfoFromExprList(pParse, pGroupBy, 0, sAggInfo.nColumn);
addrSortingIdx = sqlite3VdbeAddOp4(v, OP_SorterOpen,
sAggInfo.sortingIdx, sAggInfo.nSortingColumn,
- 0, (char*)pKeyInfo, P4_KEYINFO_HANDOFF);
+ 0, (char*)pKeyInfo, P4_KEYINFO);
/* Initialize memory locations used by GROUP BY aggregate processing
*/
@@ -98561,9 +114942,11 @@ SQLITE_PRIVATE int sqlite3Select(
** in the right order to begin with.
*/
sqlite3VdbeAddOp2(v, OP_Gosub, regReset, addrReset);
- pWInfo = sqlite3WhereBegin(pParse, pTabList, pWhere, pGroupBy, 0, 0, 0);
+ pWInfo = sqlite3WhereBegin(pParse, pTabList, pWhere, pGroupBy, 0,
+ WHERE_GROUPBY | (orderByGrp ? WHERE_SORTBYGROUP : 0), 0
+ );
if( pWInfo==0 ) goto select_end;
- if( pWInfo->nOBSat==pGroupBy->nExpr ){
+ if( sqlite3WhereIsOrdered(pWInfo)==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
@@ -98586,8 +114969,8 @@ SQLITE_PRIVATE int sqlite3Select(
groupBySort = 1;
nGroupBy = pGroupBy->nExpr;
- nCol = nGroupBy + 1;
- j = nGroupBy+1;
+ nCol = nGroupBy;
+ j = nGroupBy;
for(i=0; i<sAggInfo.nColumn; i++){
if( sAggInfo.aCol[i].iSorterColumn>=j ){
nCol++;
@@ -98596,20 +114979,14 @@ SQLITE_PRIVATE int sqlite3Select(
}
regBase = sqlite3GetTempRange(pParse, nCol);
sqlite3ExprCacheClear(pParse);
- sqlite3ExprCodeExprList(pParse, pGroupBy, regBase, 0);
- sqlite3VdbeAddOp2(v, OP_Sequence, sAggInfo.sortingIdx,regBase+nGroupBy);
- j = nGroupBy+1;
+ sqlite3ExprCodeExprList(pParse, pGroupBy, regBase, 0, 0);
+ j = nGroupBy;
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);
- }
+ sqlite3ExprCodeGetColumnToReg(pParse,
+ pCol->pTab, pCol->iColumn, pCol->iTable, r1);
j++;
}
}
@@ -98623,9 +115000,24 @@ SQLITE_PRIVATE int sqlite3Select(
sortOut = sqlite3GetTempReg(pParse);
sqlite3VdbeAddOp3(v, OP_OpenPseudo, sortPTab, sortOut, nCol);
sqlite3VdbeAddOp2(v, OP_SorterSort, sAggInfo.sortingIdx, addrEnd);
- VdbeComment((v, "GROUP BY sort"));
+ VdbeComment((v, "GROUP BY sort")); VdbeCoverage(v);
sAggInfo.useSortingIdx = 1;
sqlite3ExprCacheClear(pParse);
+
+ }
+
+ /* If the index or temporary table used by the GROUP BY sort
+ ** will naturally deliver rows in the order required by the ORDER BY
+ ** clause, cancel the ephemeral table open coded earlier.
+ **
+ ** 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( orderByGrp && OptimizationEnabled(db, SQLITE_GroupByOrder)
+ && (groupBySort || sqlite3WhereIsSorted(pWInfo))
+ ){
+ sSort.pOrderBy = 0;
+ sqlite3VdbeChangeToNoop(v, sSort.addrSortIndex);
}
/* Evaluate the current GROUP BY terms and store in b0, b1, b2...
@@ -98636,21 +115028,21 @@ SQLITE_PRIVATE int sqlite3Select(
addrTopOfLoop = sqlite3VdbeCurrentAddr(v);
sqlite3ExprCacheClear(pParse);
if( groupBySort ){
- sqlite3VdbeAddOp2(v, OP_SorterData, sAggInfo.sortingIdx, sortOut);
+ sqlite3VdbeAddOp3(v, OP_SorterData, sAggInfo.sortingIdx,
+ sortOut, sortPTab);
}
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);
+ (char*)sqlite3KeyInfoRef(pKeyInfo), P4_KEYINFO);
+ addr1 = sqlite3VdbeCurrentAddr(v);
+ sqlite3VdbeAddOp3(v, OP_Jump, addr1+1, 0, addr1+1); VdbeCoverage(v);
/* Generate code that runs whenever the GROUP BY changes.
** Changes in the GROUP BY are detected by the previous code
@@ -98664,7 +115056,7 @@ SQLITE_PRIVATE int sqlite3Select(
sqlite3ExprCodeMove(pParse, iBMem, iAMem, pGroupBy->nExpr);
sqlite3VdbeAddOp2(v, OP_Gosub, regOutputRow, addrOutputRow);
VdbeComment((v, "output one row"));
- sqlite3VdbeAddOp2(v, OP_IfPos, iAbortFlag, addrEnd);
+ sqlite3VdbeAddOp2(v, OP_IfPos, iAbortFlag, addrEnd); VdbeCoverage(v);
VdbeComment((v, "check abort flag"));
sqlite3VdbeAddOp2(v, OP_Gosub, regReset, addrReset);
VdbeComment((v, "reset accumulator"));
@@ -98672,7 +115064,7 @@ SQLITE_PRIVATE int sqlite3Select(
/* Update the aggregate accumulators based on the content of
** the current row
*/
- sqlite3VdbeJumpHere(v, j1);
+ sqlite3VdbeJumpHere(v, addr1);
updateAccumulator(pParse, &sAggInfo);
sqlite3VdbeAddOp2(v, OP_Integer, 1, iUseFlag);
VdbeComment((v, "indicate data in accumulator"));
@@ -98681,6 +115073,7 @@ SQLITE_PRIVATE int sqlite3Select(
*/
if( groupBySort ){
sqlite3VdbeAddOp2(v, OP_SorterNext, sAggInfo.sortingIdx, addrTopOfLoop);
+ VdbeCoverage(v);
}else{
sqlite3WhereEnd(pWInfo);
sqlite3VdbeChangeToNoop(v, addrSortingIdx);
@@ -98693,7 +115086,7 @@ SQLITE_PRIVATE int sqlite3Select(
/* Jump over the subroutines
*/
- sqlite3VdbeAddOp2(v, OP_Goto, 0, addrEnd);
+ sqlite3VdbeGoto(v, addrEnd);
/* Generate a subroutine that outputs a single row of the result
** set. This subroutine first looks at the iUseFlag. If iUseFlag
@@ -98709,11 +115102,12 @@ SQLITE_PRIVATE int sqlite3Select(
sqlite3VdbeResolveLabel(v, addrOutputRow);
addrOutputRow = sqlite3VdbeCurrentAddr(v);
sqlite3VdbeAddOp2(v, OP_IfPos, iUseFlag, addrOutputRow+2);
+ VdbeCoverage(v);
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,
+ selectInnerLoop(pParse, p, p->pEList, -1, &sSort,
&sDistinct, pDest,
addrOutputRow+1, addrSetAbort);
sqlite3VdbeAddOp1(v, OP_Return, regOutputRow);
@@ -98754,33 +115148,34 @@ SQLITE_PRIVATE int sqlite3Select(
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.
+ /* Search for the index that has the lowest scan cost.
**
** (2011-04-15) Do not do a full scan of an unordered index.
**
+ ** (2013-10-03) Do not count the entries in a partial index.
+ **
** In practice the KeyInfo structure will not be used. It is only
** passed to keep OP_OpenRead happy.
*/
+ if( !HasRowid(pTab) ) pBest = sqlite3PrimaryKeyIndex(pTab);
for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){
- if( pIdx->bUnordered==0 && (!pBest || pIdx->nColumn<pBest->nColumn) ){
+ if( pIdx->bUnordered==0
+ && pIdx->szIdxRow<pTab->szTabRow
+ && pIdx->pPartIdxWhere==0
+ && (!pBest || pIdx->szIdxRow<pBest->szIdxRow)
+ ){
pBest = pIdx;
}
}
- if( pBest && pBest->nColumn<pTab->nCol ){
+ if( pBest ){
iRoot = pBest->tnum;
- pKeyInfo = sqlite3IndexKeyinfo(pParse, pBest);
+ pKeyInfo = sqlite3KeyInfoOfIndex(pParse, pBest);
}
/* Open a read-only cursor, execute the OP_Count, close the cursor. */
- sqlite3VdbeAddOp3(v, OP_OpenRead, iCsr, iRoot, iDb);
+ sqlite3VdbeAddOp4Int(v, OP_OpenRead, iCsr, iRoot, iDb, 1);
if( pKeyInfo ){
- sqlite3VdbeChangeP4(v, -1, (char *)pKeyInfo, P4_KEYINFO_HANDOFF);
+ sqlite3VdbeChangeP4(v, -1, (char *)pKeyInfo, P4_KEYINFO);
}
sqlite3VdbeAddOp2(v, OP_Count, iCsr, sAggInfo.aFunc[0].iMem);
sqlite3VdbeAddOp1(v, OP_Close, iCsr);
@@ -98802,7 +115197,7 @@ SQLITE_PRIVATE int sqlite3Select(
** value of x, the only row required).
**
** A special flag must be passed to sqlite3WhereBegin() to slightly
- ** modify behaviour as follows:
+ ** modify behavior 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
@@ -98814,11 +115209,17 @@ SQLITE_PRIVATE int sqlite3Select(
** Refer to code and comments in where.c for details.
*/
ExprList *pMinMax = 0;
- u8 flag = minMaxQuery(p);
+ u8 flag = WHERE_ORDERBY_NORMAL;
+
+ assert( p->pGroupBy==0 );
+ assert( flag==0 );
+ if( p->pHaving==0 ){
+ flag = minMaxQuery(&sAggInfo, &pMinMax);
+ }
+ assert( flag==0 || (pMinMax!=0 && pMinMax->nExpr==1) );
+
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);
+ pMinMax = sqlite3ExprListDup(db, pMinMax, 0);
pDel = pMinMax;
if( pMinMax && !db->mallocFailed ){
pMinMax->a[0].sortOrder = flag!=WHERE_ORDERBY_MIN ?1:0;
@@ -98838,8 +115239,8 @@ SQLITE_PRIVATE int sqlite3Select(
}
updateAccumulator(pParse, &sAggInfo);
assert( pMinMax==0 || pMinMax->nExpr==1 );
- if( pWInfo->nOBSat>0 ){
- sqlite3VdbeAddOp2(v, OP_Goto, 0, pWInfo->iBreak);
+ if( sqlite3WhereIsOrdered(pWInfo)>0 ){
+ sqlite3VdbeGoto(v, sqlite3WhereBreakLabel(pWInfo));
VdbeComment((v, "%s() by index",
(flag==WHERE_ORDERBY_MIN?"min":"max")));
}
@@ -98847,9 +115248,9 @@ SQLITE_PRIVATE int sqlite3Select(
finalizeAggFunctions(pParse, &sAggInfo);
}
- pOrderBy = 0;
+ sSort.pOrderBy = 0;
sqlite3ExprIfFalse(pParse, pHaving, addrEnd, SQLITE_JUMPIFNULL);
- selectInnerLoop(pParse, p, p->pEList, 0, 0, 0, 0,
+ selectInnerLoop(pParse, p, p->pEList, -1, 0, 0,
pDest, addrEnd, addrEnd);
sqlite3ExprListDelete(db, pDel);
}
@@ -98864,19 +115265,19 @@ SQLITE_PRIVATE int sqlite3Select(
/* 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);
+ if( sSort.pOrderBy ){
+ explainTempTable(pParse,
+ sSort.nOBSat>0 ? "RIGHT PART OF ORDER BY":"ORDER BY");
+ generateSortTail(pParse, p, &sSort, 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;
+ /* The SELECT has been coded. If there is an error in the Parse structure,
+ ** set the return code to 1. Otherwise 0. */
+ rc = (pParse->nErr>0);
/* Control jumps to here if an error is encountered above, or upon
** successful coding of the SELECT.
@@ -98892,105 +115293,13 @@ select_end:
sqlite3DbFree(db, sAggInfo.aCol);
sqlite3DbFree(db, sAggInfo.aFunc);
+#if SELECTTRACE_ENABLED
+ SELECTTRACE(1,pParse,p,("end processing\n"));
+ pParse->nSelectIndent--;
+#endif
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 *******************************************/
/*
@@ -99011,6 +115320,7 @@ SQLITE_PRIVATE void sqlite3ExplainSelect(Vdbe *pVdbe, Select *p){
** These routines are in a separate files so that they will not be linked
** if they are not used.
*/
+/* #include "sqliteInt.h" */
/* #include <stdlib.h> */
/* #include <string.h> */
@@ -99023,10 +115333,10 @@ SQLITE_PRIVATE void sqlite3ExplainSelect(Vdbe *pVdbe, Select *p){
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 */
+ u32 nAlloc; /* Slots allocated for azResult[] */
+ u32 nRow; /* Number of rows in the result */
+ u32 nColumn; /* Number of columns in the result */
+ u32 nData; /* Slots used in azResult[]. (nRow+1)*nColumn */
int rc; /* Return code from sqlite3_exec() */
} TabResult;
@@ -99052,7 +115362,7 @@ static int sqlite3_get_table_cb(void *pArg, int nCol, char **argv, char **colv){
if( p->nData + need > p->nAlloc ){
char **azNew;
p->nAlloc = p->nAlloc*2 + need;
- azNew = sqlite3_realloc( p->azResult, sizeof(char*)*p->nAlloc );
+ azNew = sqlite3_realloc64( p->azResult, sizeof(char*)*p->nAlloc );
if( azNew==0 ) goto malloc_failed;
p->azResult = azNew;
}
@@ -99067,7 +115377,7 @@ static int sqlite3_get_table_cb(void *pArg, int nCol, char **argv, char **colv){
if( z==0 ) goto malloc_failed;
p->azResult[p->nData++] = z;
}
- }else if( p->nColumn!=nCol ){
+ }else if( (int)p->nColumn!=nCol ){
sqlite3_free(p->zErrMsg);
p->zErrMsg = sqlite3_mprintf(
"sqlite3_get_table() called with two or more incompatible queries"
@@ -99084,7 +115394,7 @@ static int sqlite3_get_table_cb(void *pArg, int nCol, char **argv, char **colv){
z = 0;
}else{
int n = sqlite3Strlen30(argv[i])+1;
- z = sqlite3_malloc( n );
+ z = sqlite3_malloc64( n );
if( z==0 ) goto malloc_failed;
memcpy(z, argv[i], n);
}
@@ -99109,7 +115419,7 @@ malloc_failed:
** 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(
+SQLITE_API int SQLITE_STDCALL 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 */
@@ -99120,6 +115430,9 @@ SQLITE_API int sqlite3_get_table(
int rc;
TabResult res;
+#ifdef SQLITE_ENABLE_API_ARMOR
+ if( !sqlite3SafetyCheckOk(db) || pazResult==0 ) return SQLITE_MISUSE_BKPT;
+#endif
*pazResult = 0;
if( pnColumn ) *pnColumn = 0;
if( pnRow ) *pnRow = 0;
@@ -99130,7 +115443,7 @@ SQLITE_API int sqlite3_get_table(
res.nData = 1;
res.nAlloc = 20;
res.rc = SQLITE_OK;
- res.azResult = sqlite3_malloc(sizeof(char*)*res.nAlloc );
+ res.azResult = sqlite3_malloc64(sizeof(char*)*res.nAlloc );
if( res.azResult==0 ){
db->errCode = SQLITE_NOMEM;
return SQLITE_NOMEM;
@@ -99158,7 +115471,7 @@ SQLITE_API int sqlite3_get_table(
}
if( res.nAlloc>res.nData ){
char **azNew;
- azNew = sqlite3_realloc( res.azResult, sizeof(char*)*res.nData );
+ azNew = sqlite3_realloc64( res.azResult, sizeof(char*)*res.nData );
if( azNew==0 ){
sqlite3_free_table(&res.azResult[1]);
db->errCode = SQLITE_NOMEM;
@@ -99175,8 +115488,8 @@ SQLITE_API int sqlite3_get_table(
/*
** 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() */
+SQLITE_API void SQLITE_STDCALL sqlite3_free_table(
+ char **azResult /* Result returned from sqlite3_get_table() */
){
if( azResult ){
int i, n;
@@ -99204,6 +115517,7 @@ SQLITE_API void sqlite3_free_table(
*************************************************************************
** This file contains the implementation for TRIGGERs
*/
+/* #include "sqliteInt.h" */
#ifndef SQLITE_OMIT_TRIGGER
/*
@@ -99320,7 +115634,7 @@ SQLITE_PRIVATE void sqlite3BeginTrigger(
** ^^^^^^^^
**
** To maintain backwards compatibility, ignore the database
- ** name on pTableName if we are reparsing our of SQLITE_MASTER.
+ ** name on pTableName if we are reparsing out of SQLITE_MASTER.
*/
if( db->init.busy && iDb!=1 ){
sqlite3DbFree(db, pTableName->a[0].zDatabase);
@@ -99341,8 +115655,8 @@ SQLITE_PRIVATE void sqlite3BeginTrigger(
/* 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) ){
+ sqlite3FixInit(&sFix, pParse, iDb, "trigger", pName);
+ if( sqlite3FixSrcList(&sFix, pTableName) ){
goto trigger_cleanup;
}
pTab = sqlite3SrcListLookup(pParse, pTableName);
@@ -99373,8 +115687,7 @@ SQLITE_PRIVATE void sqlite3BeginTrigger(
goto trigger_cleanup;
}
assert( sqlite3SchemaMutexHeld(db, iDb, 0) );
- if( sqlite3HashFind(&(db->aDb[iDb].pSchema->trigHash),
- zName, sqlite3Strlen30(zName)) ){
+ if( sqlite3HashFind(&(db->aDb[iDb].pSchema->trigHash),zName) ){
if( !noErr ){
sqlite3ErrorMsg(pParse, "trigger %T already exists", pName);
}else{
@@ -99387,7 +115700,6 @@ SQLITE_PRIVATE void sqlite3BeginTrigger(
/* 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;
}
@@ -99484,8 +115796,10 @@ SQLITE_PRIVATE void sqlite3FinishTrigger(
}
nameToken.z = pTrig->zName;
nameToken.n = sqlite3Strlen30(nameToken.z);
- if( sqlite3FixInit(&sFix, pParse, iDb, "trigger", &nameToken)
- && sqlite3FixTriggerStep(&sFix, pTrig->step_list) ){
+ sqlite3FixInit(&sFix, pParse, iDb, "trigger", &nameToken);
+ if( sqlite3FixTriggerStep(&sFix, pTrig->step_list)
+ || sqlite3FixExpr(&sFix, pTrig->pWhen)
+ ){
goto triggerfinish_cleanup;
}
@@ -99515,13 +115829,12 @@ SQLITE_PRIVATE void sqlite3FinishTrigger(
Trigger *pLink = pTrig;
Hash *pHash = &db->aDb[iDb].pSchema->trigHash;
assert( sqlite3SchemaMutexHeld(db, iDb, 0) );
- pTrig = sqlite3HashInsert(pHash, zName, sqlite3Strlen30(zName), pTrig);
+ pTrig = sqlite3HashInsert(pHash, 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);
+ pTab = sqlite3HashFind(&pLink->pTabSchema->tblHash, pLink->table);
assert( pTab!=0 );
pLink->pNext = pTab->pTrigger;
pTab->pTrigger = pLink;
@@ -99566,12 +115879,12 @@ static TriggerStep *triggerStepAllocate(
){
TriggerStep *pTriggerStep;
- pTriggerStep = sqlite3DbMallocZero(db, sizeof(TriggerStep) + pName->n);
+ pTriggerStep = sqlite3DbMallocZero(db, sizeof(TriggerStep) + pName->n + 1);
if( pTriggerStep ){
char *z = (char*)&pTriggerStep[1];
memcpy(z, pName->z, pName->n);
- pTriggerStep->target.z = z;
- pTriggerStep->target.n = pName->n;
+ sqlite3Dequote(z);
+ pTriggerStep->zTarget = z;
pTriggerStep->op = op;
}
return pTriggerStep;
@@ -99588,25 +115901,21 @@ 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);
+ assert(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;
@@ -99684,7 +115993,6 @@ SQLITE_PRIVATE void sqlite3DropTrigger(Parse *pParse, SrcList *pName, int noErr)
int i;
const char *zDb;
const char *zName;
- int nName;
sqlite3 *db = pParse->db;
if( db->mallocFailed ) goto drop_trigger_cleanup;
@@ -99695,13 +116003,12 @@ SQLITE_PRIVATE void sqlite3DropTrigger(Parse *pParse, SrcList *pName, int noErr)
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);
+ pTrigger = sqlite3HashFind(&(db->aDb[j].pSchema->trigHash), zName);
if( pTrigger ) break;
}
if( !pTrigger ){
@@ -99724,8 +116031,7 @@ drop_trigger_cleanup:
** is set on.
*/
static Table *tableOfTrigger(Trigger *pTrigger){
- int n = sqlite3Strlen30(pTrigger->table);
- return sqlite3HashFind(&pTrigger->pTabSchema->tblHash, pTrigger->table, n);
+ return sqlite3HashFind(&pTrigger->pTabSchema->tblHash, pTrigger->table);
}
@@ -99760,30 +116066,12 @@ SQLITE_PRIVATE void sqlite3DropTriggerPtr(Parse *pParse, Trigger *pTrigger){
*/
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);
+ sqlite3NestedParse(pParse,
+ "DELETE FROM %Q.%s WHERE name=%Q AND type='trigger'",
+ db->aDb[iDb].zName, SCHEMA_TABLE(iDb), pTrigger->zName
+ );
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;
- }
}
}
@@ -99796,7 +116084,7 @@ SQLITE_PRIVATE void sqlite3UnlinkAndDeleteTrigger(sqlite3 *db, int iDb, const ch
assert( sqlite3SchemaMutexHeld(db, iDb, 0) );
pHash = &(db->aDb[iDb].pSchema->trigHash);
- pTrigger = sqlite3HashInsert(pHash, zName, sqlite3Strlen30(zName), 0);
+ pTrigger = sqlite3HashInsert(pHash, zName, 0);
if( ALWAYS(pTrigger) ){
if( pTrigger->pSchema==pTrigger->pTabSchema ){
Table *pTab = tableOfTrigger(pTrigger);
@@ -99860,7 +116148,7 @@ SQLITE_PRIVATE Trigger *sqlite3TriggersExist(
}
/*
-** Convert the pStep->target token into a SrcList and return a pointer
+** Convert the pStep->zTarget string into a SrcList and return a pointer
** to that SrcList.
**
** This routine adds a specific database name, if needed, to the target when
@@ -99873,17 +116161,17 @@ static SrcList *targetSrcList(
Parse *pParse, /* The parsing context */
TriggerStep *pStep /* The trigger containing the target token */
){
+ sqlite3 *db = pParse->db;
int iDb; /* Index of the database to use */
SrcList *pSrc; /* SrcList to be returned */
- pSrc = sqlite3SrcListAppend(pParse->db, 0, &pStep->target, 0);
+ pSrc = sqlite3SrcListAppend(db, 0, 0, 0);
if( pSrc ){
assert( pSrc->nSrc>0 );
- assert( pSrc->a!=0 );
- iDb = sqlite3SchemaToIndex(pParse->db, pStep->pTrig->pSchema);
+ pSrc->a[pSrc->nSrc-1].zName = sqlite3DbStrDup(db, pStep->zTarget);
+ iDb = sqlite3SchemaToIndex(db, pStep->pTrig->pSchema);
if( iDb==0 || iDb>=2 ){
- sqlite3 *db = pParse->db;
- assert( iDb<pParse->db->nDb );
+ assert( iDb<db->nDb );
pSrc->a[pSrc->nSrc-1].zDatabase = sqlite3DbStrDup(db, db->aDb[iDb].zName);
}
}
@@ -99921,15 +116209,7 @@ static int codeTriggerProgram(
** 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;
+ assert( pParse->okConstFactor==0 );
switch( pStep->op ){
case TK_UPDATE: {
@@ -99944,7 +116224,6 @@ static int codeTriggerProgram(
case TK_INSERT: {
sqlite3Insert(pParse,
targetSrcList(pParse, pStep),
- sqlite3ExprListDup(db, pStep->pExprList, 0),
sqlite3SelectDup(db, pStep->pSelect, 0),
sqlite3IdListDup(db, pStep->pIdList),
pParse->eOrconf
@@ -99975,7 +116254,7 @@ static int codeTriggerProgram(
return 0;
}
-#ifdef SQLITE_DEBUG
+#ifdef SQLITE_ENABLE_EXPLAIN_COMMENTS
/*
** This function is used to add VdbeComment() annotations to a VDBE
** program. It is not used in production code, only for debugging.
@@ -100004,6 +116283,7 @@ static void transferParseError(Parse *pTo, Parse *pFrom){
if( pTo->nErr==0 ){
pTo->zErrMsg = pFrom->zErrMsg;
pTo->nErr = pFrom->nErr;
+ pTo->rc = pFrom->rc;
}else{
sqlite3DbFree(pFrom->db, pFrom->zErrMsg);
}
@@ -100115,6 +116395,7 @@ static TriggerPrg *codeRowTrigger(
assert( !pSubParse->pAinc && !pSubParse->pZombieTab );
assert( !pSubParse->pTriggerPrg && !pSubParse->nMaxArg );
+ sqlite3ParserReset(pSubParse);
sqlite3StackFree(db, pSubParse);
return pPrg;
@@ -100195,7 +116476,7 @@ SQLITE_PRIVATE void sqlite3CodeRowTriggerDirect(
/*
** 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
+** is given by the op parameter. 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.
**
@@ -100341,6 +116622,7 @@ SQLITE_PRIVATE u32 sqlite3TriggerColmask(
** This file contains C code routines that are called by the parser
** to handle UPDATE statements.
*/
+/* #include "sqliteInt.h" */
#ifndef SQLITE_OMIT_VIRTUALTABLE
/* Forward declaration */
@@ -100389,7 +116671,7 @@ static void updateVirtualTable(
SQLITE_PRIVATE void sqlite3ColumnDefault(Vdbe *v, Table *pTab, int i, int iReg){
assert( pTab!=0 );
if( !pTab->pSelect ){
- sqlite3_value *pValue;
+ sqlite3_value *pValue = 0;
u8 enc = ENC(sqlite3VdbeDb(v));
Column *pCol = &pTab->aCol[i];
VdbeComment((v, "%s.%s", pTab->zName, pCol->zName));
@@ -100400,7 +116682,7 @@ SQLITE_PRIVATE void sqlite3ColumnDefault(Vdbe *v, Table *pTab, int i, int iReg){
sqlite3VdbeChangeP4(v, -1, (const char *)pValue, P4_MEM);
}
#ifndef SQLITE_OMIT_FLOATING_POINT
- if( iReg>=0 && pTab->aCol[i].affinity==SQLITE_AFF_REAL ){
+ if( pTab->aCol[i].affinity==SQLITE_AFF_REAL ){
sqlite3VdbeAddOp1(v, OP_RealAffinity, iReg);
}
#endif
@@ -100423,25 +116705,32 @@ SQLITE_PRIVATE void sqlite3Update(
){
int i, j; /* Loop counters */
Table *pTab; /* The table to be updated */
- int addr = 0; /* VDBE instruction address of the start of the loop */
+ int addrTop = 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 */
+ Index *pPk; /* The PRIMARY KEY index for WITHOUT ROWID tables */
int nIdx; /* Number of indices that need updating */
- int iCur; /* VDBE Cursor number of pTab */
+ int iBaseCur; /* Base cursor number */
+ int iDataCur; /* Cursor for the canonical data btree */
+ int iIdxCur; /* Cursor for the first index */
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 */
+ u8 *aToOpen; /* 1 for tables and indices to be opened */
+ u8 chngPk; /* PRIMARY KEY changed in a WITHOUT ROWID table */
+ u8 chngRowid; /* Rowid changed in a normal table */
+ u8 chngKey; /* Either chngPk or chngRowid */
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 */
+ int labelBreak; /* Jump here to break out of UPDATE loop */
+ int labelContinue; /* Jump here to continue next step of UPDATE loop */
#ifndef SQLITE_OMIT_TRIGGER
int isView; /* True when updating a view (INSTEAD OF trigger) */
@@ -100449,14 +116738,18 @@ SQLITE_PRIVATE void sqlite3Update(
int tmask; /* Mask of TRIGGER_BEFORE|TRIGGER_AFTER */
#endif
int newmask; /* Mask of NEW.* columns accessed by BEFORE triggers */
+ int iEph = 0; /* Ephemeral table holding all primary key values */
+ int nKey = 0; /* Number of elements in regKey for WITHOUT ROWID */
+ int aiCurOnePass[2]; /* The write cursors opened by WHERE_ONEPASS */
/* 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 regOldRowid = 0; /* The old rowid */
+ int regNewRowid = 0; /* The new rowid */
+ int regNew = 0; /* 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 */
+ int regKey = 0; /* composite PRIMARY KEY value */
memset(&sContext, 0, sizeof(sContext));
db = pParse->db;
@@ -100494,20 +116787,34 @@ SQLITE_PRIVATE void sqlite3Update(
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){
+ pTabList->a[0].iCursor = iBaseCur = iDataCur = pParse->nTab++;
+ iIdxCur = iDataCur+1;
+ pPk = HasRowid(pTab) ? 0 : sqlite3PrimaryKeyIndex(pTab);
+ for(nIdx=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, nIdx++){
+ if( IsPrimaryKeyIndex(pIdx) && pPk!=0 ){
+ iDataCur = pParse->nTab;
+ pTabList->a[0].iCursor = iDataCur;
+ }
pParse->nTab++;
}
+ /* Allocate space for aXRef[], aRegIdx[], and aToOpen[].
+ ** Initialize aXRef[] and aToOpen[] to their default values.
+ */
+ aXRef = sqlite3DbMallocRaw(db, sizeof(int) * (pTab->nCol+nIdx) + nIdx+2 );
+ if( aXRef==0 ) goto update_cleanup;
+ aRegIdx = aXRef+pTab->nCol;
+ aToOpen = (u8*)(aRegIdx+nIdx);
+ memset(aToOpen, 1, nIdx+1);
+ aToOpen[nIdx+1] = 0;
+ for(i=0; i<pTab->nCol; i++) aXRef[i] = -1;
+
/* Initialize the name-context */
memset(&sNC, 0, sizeof(sNC));
sNC.pParse = pParse;
@@ -100519,7 +116826,7 @@ SQLITE_PRIVATE void sqlite3Update(
** column to be updated, make sure we have authorization to change
** that column.
*/
- chngRowid = 0;
+ chngRowid = chngPk = 0;
for(i=0; i<pChanges->nExpr; i++){
if( sqlite3ResolveExprNames(&sNC, pChanges->a[i].pExpr) ){
goto update_cleanup;
@@ -100529,13 +116836,16 @@ SQLITE_PRIVATE void sqlite3Update(
if( j==pTab->iPKey ){
chngRowid = 1;
pRowidExpr = pChanges->a[i].pExpr;
+ }else if( pPk && (pTab->aCol[j].colFlags & COLFLAG_PRIMKEY)!=0 ){
+ chngPk = 1;
}
aXRef[j] = i;
break;
}
}
if( j>=pTab->nCol ){
- if( sqlite3IsRowid(pChanges->a[i].zName) ){
+ if( pPk==0 && sqlite3IsRowid(pChanges->a[i].zName) ){
+ j = -1;
chngRowid = 1;
pRowidExpr = pChanges->a[i].pExpr;
}else{
@@ -100548,7 +116858,8 @@ SQLITE_PRIVATE void sqlite3Update(
{
int rc;
rc = sqlite3AuthCheck(pParse, SQLITE_UPDATE, pTab->zName,
- pTab->aCol[j].zName, db->aDb[iDb].zName);
+ j<0 ? "ROWID" : pTab->aCol[j].zName,
+ db->aDb[iDb].zName);
if( rc==SQLITE_DENY ){
goto update_cleanup;
}else if( rc==SQLITE_IGNORE ){
@@ -100557,32 +116868,41 @@ SQLITE_PRIVATE void sqlite3Update(
}
#endif
}
+ assert( (chngRowid & chngPk)==0 );
+ assert( chngRowid==0 || chngRowid==1 );
+ assert( chngPk==0 || chngPk==1 );
+ chngKey = chngRowid + chngPk;
- hasFK = sqlite3FkRequired(pParse, pTab, aXRef, chngRowid);
+ /* The SET expressions are not actually used inside the WHERE loop.
+ ** So reset the colUsed mask. Unless this is a virtual table. In that
+ ** case, set all bits of the colUsed mask (to ensure that the virtual
+ ** table implementation makes all columns available).
+ */
+ pTabList->a[0].colUsed = IsVirtual(pTab) ? (Bitmask)-1 : 0;
+
+ hasFK = sqlite3FkRequired(pParse, pTab, aXRef, chngKey);
- /* 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.
+ /* There is one entry in the aRegIdx[] array for each index on the table
+ ** being updated. Fill in aRegIdx[] with a register number that will hold
+ ** the key for accessing each index.
+ **
+ ** FIXME: Be smarter about omitting indexes that use expressions.
*/
- 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 ){
+ if( chngKey || hasFK || pIdx->pPartIdxWhere || pIdx==pPk ){
reg = ++pParse->nMem;
}else{
reg = 0;
- for(i=0; i<pIdx->nColumn; i++){
- if( aXRef[pIdx->aiColumn[i]]>=0 ){
+ for(i=0; i<pIdx->nKeyCol; i++){
+ i16 iIdxCol = pIdx->aiColumn[i];
+ if( iIdxCol<0 || aXRef[iIdxCol]>=0 ){
reg = ++pParse->nMem;
break;
}
}
}
+ if( reg==0 ) aToOpen[j+1] = 0;
aRegIdx[j] = reg;
}
@@ -100592,29 +116912,20 @@ SQLITE_PRIVATE void sqlite3Update(
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;
+ if( !IsVirtual(pTab) ){
+ regRowSet = ++pParse->nMem;
+ regOldRowid = regNewRowid = ++pParse->nMem;
+ if( chngPk || pTrigger || hasFK ){
+ regOld = pParse->nMem + 1;
+ pParse->nMem += pTab->nCol;
+ }
+ if( chngKey || pTrigger || hasFK ){
+ regNewRowid = ++pParse->nMem;
+ }
+ regNew = 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 ){
@@ -100622,11 +116933,11 @@ SQLITE_PRIVATE void sqlite3Update(
}
/* If we are trying to update a view, realize that view into
- ** a ephemeral table.
+ ** an ephemeral table.
*/
#if !defined(SQLITE_OMIT_VIEW) && !defined(SQLITE_OMIT_TRIGGER)
if( isView ){
- sqlite3MaterializeView(pParse, pTab, pWhere, iCur);
+ sqlite3MaterializeView(pParse, pTab, pWhere, iDataCur);
}
#endif
@@ -100637,25 +116948,69 @@ SQLITE_PRIVATE void sqlite3Update(
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);
+#ifndef SQLITE_OMIT_VIRTUALTABLE
+ /* Virtual tables must be handled separately */
+ if( IsVirtual(pTab) ){
+ updateVirtualTable(pParse, pTabList, pTab, pChanges, pRowidExpr, aXRef,
+ pWhere, onError);
+ goto update_cleanup;
}
+#endif
- /* End the database scan loop.
+ /* Begin the database scan
*/
- sqlite3WhereEnd(pWInfo);
+ if( HasRowid(pTab) ){
+ sqlite3VdbeAddOp3(v, OP_Null, 0, regRowSet, regOldRowid);
+ pWInfo = sqlite3WhereBegin(
+ pParse, pTabList, pWhere, 0, 0, WHERE_ONEPASS_DESIRED, iIdxCur
+ );
+ if( pWInfo==0 ) goto update_cleanup;
+ okOnePass = sqlite3WhereOkOnePass(pWInfo, aiCurOnePass);
+
+ /* Remember the rowid of every item to be updated.
+ */
+ sqlite3VdbeAddOp2(v, OP_Rowid, iDataCur, regOldRowid);
+ if( !okOnePass ){
+ sqlite3VdbeAddOp2(v, OP_RowSetAdd, regRowSet, regOldRowid);
+ }
+
+ /* End the database scan loop.
+ */
+ sqlite3WhereEnd(pWInfo);
+ }else{
+ int iPk; /* First of nPk memory cells holding PRIMARY KEY value */
+ i16 nPk; /* Number of components of the PRIMARY KEY */
+ int addrOpen; /* Address of the OpenEphemeral instruction */
+
+ assert( pPk!=0 );
+ nPk = pPk->nKeyCol;
+ iPk = pParse->nMem+1;
+ pParse->nMem += nPk;
+ regKey = ++pParse->nMem;
+ iEph = pParse->nTab++;
+ sqlite3VdbeAddOp2(v, OP_Null, 0, iPk);
+ addrOpen = sqlite3VdbeAddOp2(v, OP_OpenEphemeral, iEph, nPk);
+ sqlite3VdbeSetP4KeyInfo(pParse, pPk);
+ pWInfo = sqlite3WhereBegin(pParse, pTabList, pWhere, 0, 0,
+ WHERE_ONEPASS_DESIRED, iIdxCur);
+ if( pWInfo==0 ) goto update_cleanup;
+ okOnePass = sqlite3WhereOkOnePass(pWInfo, aiCurOnePass);
+ for(i=0; i<nPk; i++){
+ assert( pPk->aiColumn[i]>=0 );
+ sqlite3ExprCodeGetColumnOfTable(v, pTab, iDataCur, pPk->aiColumn[i],
+ iPk+i);
+ }
+ if( okOnePass ){
+ sqlite3VdbeChangeToNoop(v, addrOpen);
+ nKey = nPk;
+ regKey = iPk;
+ }else{
+ sqlite3VdbeAddOp4(v, OP_MakeRecord, iPk, nPk, regKey,
+ sqlite3IndexAffinityStr(db, pPk), nPk);
+ sqlite3VdbeAddOp2(v, OP_IdxInsert, iEph, regKey);
+ }
+ sqlite3WhereEnd(pWInfo);
+ }
/* Initialize the count of updated rows
*/
@@ -100664,6 +117019,7 @@ SQLITE_PRIVATE void sqlite3Update(
sqlite3VdbeAddOp2(v, OP_Integer, 0, regRowCount);
}
+ labelBreak = sqlite3VdbeMakeLabel(v);
if( !isView ){
/*
** Open every index that needs updating. Note that if any
@@ -100671,74 +117027,84 @@ SQLITE_PRIVATE void sqlite3Update(
** 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;
+ memset(aToOpen, 1, nIdx+1);
}else{
- openAll = 0;
for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){
if( pIdx->onError==OE_Replace ){
- openAll = 1;
+ memset(aToOpen, 1, nIdx+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 );
- }
+ if( okOnePass ){
+ if( aiCurOnePass[0]>=0 ) aToOpen[aiCurOnePass[0]-iBaseCur] = 0;
+ if( aiCurOnePass[1]>=0 ) aToOpen[aiCurOnePass[1]-iBaseCur] = 0;
}
+ sqlite3OpenTableAndIndices(pParse, pTab, OP_OpenWrite, 0, iBaseCur, aToOpen,
+ 0, 0);
}
/* 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);
+ if( aToOpen[iDataCur-iBaseCur] && !isView ){
+ assert( pPk );
+ sqlite3VdbeAddOp4Int(v, OP_NotFound, iDataCur, labelBreak, regKey, nKey);
+ VdbeCoverageNeverTaken(v);
+ }
+ labelContinue = labelBreak;
+ sqlite3VdbeAddOp2(v, OP_IsNull, pPk ? regKey : regOldRowid, labelBreak);
+ VdbeCoverageIf(v, pPk==0);
+ VdbeCoverageIf(v, pPk!=0);
+ }else if( pPk ){
+ labelContinue = sqlite3VdbeMakeLabel(v);
+ sqlite3VdbeAddOp2(v, OP_Rewind, iEph, labelBreak); VdbeCoverage(v);
+ addrTop = sqlite3VdbeAddOp2(v, OP_RowKey, iEph, regKey);
+ sqlite3VdbeAddOp4Int(v, OP_NotFound, iDataCur, labelContinue, regKey, 0);
+ VdbeCoverage(v);
+ }else{
+ labelContinue = sqlite3VdbeAddOp3(v, OP_RowSetRead, regRowSet, labelBreak,
+ regOldRowid);
+ VdbeCoverage(v);
+ sqlite3VdbeAddOp3(v, OP_NotExists, iDataCur, labelContinue, regOldRowid);
+ VdbeCoverage(v);
}
- /* 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 );
+ assert( chngKey || pTrigger || hasFK || regOldRowid==regNewRowid );
if( chngRowid ){
sqlite3ExprCode(pParse, pRowidExpr, regNewRowid);
- sqlite3VdbeAddOp1(v, OP_MustBeInt, regNewRowid);
+ sqlite3VdbeAddOp1(v, OP_MustBeInt, regNewRowid); VdbeCoverage(v);
}
- /* If there are triggers on this table, populate an array of registers
- ** with the required old.* column data. */
- if( hasFK || pTrigger ){
+ /* Compute the old pre-UPDATE content of the row being changed, if that
+ ** information is needed */
+ if( chngPk || 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);
+ if( oldmask==0xffffffff
+ || (i<32 && (oldmask & MASKBIT32(i))!=0)
+ || (pTab->aCol[i].colFlags & COLFLAG_PRIMKEY)!=0
+ ){
+ testcase( oldmask!=0xffffffff && i==31 );
+ sqlite3ExprCodeGetColumnOfTable(v, pTab, iDataCur, i, regOld+i);
}else{
sqlite3VdbeAddOp2(v, OP_Null, 0, regOld+i);
}
}
- if( chngRowid==0 ){
+ if( chngRowid==0 && pPk==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
+ ** row data. This array is used to check constants, create the new
** table and index records, and as the values for any new.* references
** made by triggers.
**
@@ -100753,15 +117119,14 @@ SQLITE_PRIVATE void sqlite3Update(
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);*/
+ 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)) ){
+ }else if( 0==(tmask&TRIGGER_BEFORE) || i>31 || (newmask & MASKBIT32(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
@@ -100769,8 +117134,9 @@ SQLITE_PRIVATE void sqlite3Update(
*/
testcase( i==31 );
testcase( i==32 );
- sqlite3VdbeAddOp3(v, OP_Column, iCur, i, regNew+i);
- sqlite3ColumnDefault(v, pTab, i, regNew+i);
+ sqlite3ExprCodeGetColumnToReg(pParse, pTab, i, iDataCur, regNew+i);
+ }else{
+ sqlite3VdbeAddOp2(v, OP_Null, 0, regNew+i);
}
}
}
@@ -100779,18 +117145,23 @@ SQLITE_PRIVATE void sqlite3Update(
** verified. One could argue that this is wrong.
*/
if( tmask&TRIGGER_BEFORE ){
- sqlite3VdbeAddOp2(v, OP_Affinity, regNew, pTab->nCol);
- sqlite3TableAffinityStr(v, pTab);
+ sqlite3TableAffinity(v, pTab, regNew);
sqlite3CodeRowTrigger(pParse, pTrigger, TK_UPDATE, pChanges,
- TRIGGER_BEFORE, pTab, regOldRowid, onError, addr);
+ TRIGGER_BEFORE, pTab, regOldRowid, onError, labelContinue);
/* 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
+ ** required. This behavior - 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( pPk ){
+ sqlite3VdbeAddOp4Int(v, OP_NotFound, iDataCur, labelContinue,regKey,nKey);
+ VdbeCoverage(v);
+ }else{
+ sqlite3VdbeAddOp3(v, OP_NotExists, iDataCur, labelContinue, regOldRowid);
+ VdbeCoverage(v);
+ }
/* 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
@@ -100799,46 +117170,57 @@ SQLITE_PRIVATE void sqlite3Update(
*/
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);
+ sqlite3ExprCodeGetColumnOfTable(v, pTab, iDataCur, i, regNew+i);
}
}
}
if( !isView ){
- int j1; /* Address of jump instruction */
+ int addr1 = 0; /* Address of jump instruction */
+ int bReplace = 0; /* True if REPLACE conflict resolution might happen */
/* Do constraint checks. */
- sqlite3GenerateConstraintChecks(pParse, pTab, iCur, regNewRowid,
- aRegIdx, (chngRowid?regOldRowid:0), 1, onError, addr, 0);
+ assert( regOldRowid>0 );
+ sqlite3GenerateConstraintChecks(pParse, pTab, aRegIdx, iDataCur, iIdxCur,
+ regNewRowid, regOldRowid, chngKey, onError, labelContinue, &bReplace);
/* Do FK constraint checks. */
if( hasFK ){
- sqlite3FkCheck(pParse, pTab, regOldRowid, 0);
+ sqlite3FkCheck(pParse, pTab, regOldRowid, 0, aXRef, chngKey);
}
/* Delete the index entries associated with the current record. */
- j1 = sqlite3VdbeAddOp3(v, OP_NotExists, iCur, 0, regOldRowid);
- sqlite3GenerateRowIndexDelete(pParse, pTab, iCur, aRegIdx);
+ if( bReplace || chngKey ){
+ if( pPk ){
+ addr1 = sqlite3VdbeAddOp4Int(v, OP_NotFound, iDataCur, 0, regKey, nKey);
+ }else{
+ addr1 = sqlite3VdbeAddOp3(v, OP_NotExists, iDataCur, 0, regOldRowid);
+ }
+ VdbeCoverageNeverTaken(v);
+ }
+ sqlite3GenerateRowIndexDelete(pParse, pTab, iDataCur, iIdxCur, aRegIdx, -1);
/* If changing the record number, delete the old record. */
- if( hasFK || chngRowid ){
- sqlite3VdbeAddOp2(v, OP_Delete, iCur, 0);
+ if( hasFK || chngKey || pPk!=0 ){
+ sqlite3VdbeAddOp2(v, OP_Delete, iDataCur, 0);
+ }
+ if( bReplace || chngKey ){
+ sqlite3VdbeJumpHere(v, addr1);
}
- sqlite3VdbeJumpHere(v, j1);
if( hasFK ){
- sqlite3FkCheck(pParse, pTab, 0, regNewRowid);
+ sqlite3FkCheck(pParse, pTab, 0, regNewRowid, aXRef, chngKey);
}
/* Insert the new index entries and the new record. */
- sqlite3CompleteInsertion(pParse, pTab, iCur, regNewRowid, aRegIdx, 1, 0, 0);
+ sqlite3CompleteInsertion(pParse, pTab, iDataCur, iIdxCur,
+ 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);
+ sqlite3FkActions(pParse, pTab, pChanges, regOldRowid, aXRef, chngKey);
}
}
@@ -100849,22 +117231,29 @@ SQLITE_PRIVATE void sqlite3Update(
}
sqlite3CodeRowTrigger(pParse, pTrigger, TK_UPDATE, pChanges,
- TRIGGER_AFTER, pTab, regOldRowid, onError, addr);
+ TRIGGER_AFTER, pTab, regOldRowid, onError, labelContinue);
/* 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);
+ if( okOnePass ){
+ /* Nothing to do at end-of-loop for a single-pass */
+ }else if( pPk ){
+ sqlite3VdbeResolveLabel(v, labelContinue);
+ sqlite3VdbeAddOp2(v, OP_Next, iEph, addrTop); VdbeCoverage(v);
+ }else{
+ sqlite3VdbeGoto(v, labelContinue);
+ }
+ sqlite3VdbeResolveLabel(v, labelBreak);
/* 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);
+ if( aToOpen[i+1] ){
+ sqlite3VdbeAddOp2(v, OP_Close, iIdxCur+i, 0);
}
}
- sqlite3VdbeAddOp2(v, OP_Close, iCur, 0);
+ if( iDataCur<iIdxCur ) sqlite3VdbeAddOp2(v, OP_Close, iDataCur, 0);
/* Update the sqlite_sequence table by storing the content of the
** maximum rowid counter values recorded while inserting into
@@ -100887,15 +117276,14 @@ SQLITE_PRIVATE void sqlite3Update(
update_cleanup:
sqlite3AuthContextPop(&sContext);
- sqlite3DbFree(db, aRegIdx);
- sqlite3DbFree(db, aXRef);
+ sqlite3DbFree(db, aXRef); /* Also frees aRegIdx[] and aToOpen[] */
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
+** they 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
@@ -100908,21 +117296,23 @@ update_cleanup:
/*
** Generate code for an UPDATE of a virtual table.
**
-** The strategy is that we create an ephemerial table that contains
+** There are two possible strategies - the default and the special
+** "onepass" strategy. Onepass is only used if the virtual table
+** implementation indicates that pWhere may match at most one row.
+**
+** The default strategy is to create an ephemeral table that contains
** for each row to be changed:
**
** (A) The original rowid of that row.
-** (B) The revised rowid for the row. (note1)
+** (B) The revised rowid for the row.
** (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.
+** Then loop through the contents of this ephemeral table executing a
+** VUpdate for each row. When finished, drop the ephemeral table.
**
-** 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.
+** The "onepass" strategy does not use an ephemeral table. Instead, it
+** stores the same values (A, B and C above) in a register array and
+** makes a single invocation of VUpdate.
*/
static void updateVirtualTable(
Parse *pParse, /* The parsing context */
@@ -100935,68 +117325,96 @@ static void updateVirtualTable(
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_"));
+ WhereInfo *pWInfo;
+ int nArg = 2 + pTab->nCol; /* Number of arguments to VUpdate */
+ int regArg; /* First register in VUpdate arg array */
+ int regRec; /* Register in which to assemble record */
+ int regRowid; /* Register for ephem table rowid */
+ int iCsr = pSrc->a[0].iCursor; /* Cursor used for virtual table scan */
+ int aDummy[2]; /* Unused arg for sqlite3WhereOkOnePass() */
+ int bOnePass; /* True to use onepass strategy */
+ int addr; /* Address of OP_OpenEphemeral */
+
+ /* Allocate nArg registers to martial the arguments to VUpdate. Then
+ ** create and open the ephemeral table in which the records created from
+ ** these arguments will be temporarily stored. */
+ assert( v );
+ ephemTab = pParse->nTab++;
+ addr= sqlite3VdbeAddOp2(v, OP_OpenEphemeral, ephemTab, nArg);
+ regArg = pParse->nMem + 1;
+ pParse->nMem += nArg;
+ regRec = ++pParse->nMem;
+ regRowid = ++pParse->nMem;
+
+ /* Start scanning the virtual table */
+ pWInfo = sqlite3WhereBegin(pParse, pSrc, pWhere, 0,0,WHERE_ONEPASS_DESIRED,0);
+ if( pWInfo==0 ) return;
+
+ /* Populate the argument registers. */
+ sqlite3VdbeAddOp2(v, OP_Rowid, iCsr, regArg);
if( pRowid ){
- pEList = sqlite3ExprListAppend(pParse, pEList,
- sqlite3ExprDup(db, pRowid, 0));
+ sqlite3ExprCode(pParse, pRowid, regArg+1);
+ }else{
+ sqlite3VdbeAddOp2(v, OP_Rowid, iCsr, regArg+1);
}
- assert( pTab->iPKey<0 );
for(i=0; i<pTab->nCol; i++){
if( aXRef[i]>=0 ){
- pExpr = sqlite3ExprDup(db, pChanges->a[aXRef[i]].pExpr, 0);
+ sqlite3ExprCode(pParse, pChanges->a[aXRef[i]].pExpr, regArg+2+i);
}else{
- pExpr = sqlite3Expr(db, TK_ID, pTab->aCol[i].zName);
+ sqlite3VdbeAddOp3(v, OP_VColumn, iCsr, i, regArg+2+i);
}
- 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);
+ bOnePass = sqlite3WhereOkOnePass(pWInfo, aDummy);
- /* 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);
+ if( bOnePass ){
+ /* If using the onepass strategy, no-op out the OP_OpenEphemeral coded
+ ** above. Also, if this is a top-level parse (not a trigger), clear the
+ ** multi-write flag so that the VM does not open a statement journal */
+ sqlite3VdbeChangeToNoop(v, addr);
+ if( sqlite3IsToplevel(pParse) ){
+ pParse->isMultiWrite = 0;
+ }
+ }else{
+ /* Create a record from the argument register contents and insert it into
+ ** the ephemeral table. */
+ sqlite3VdbeAddOp3(v, OP_MakeRecord, regArg, nArg, regRec);
+ sqlite3VdbeAddOp2(v, OP_NewRowid, ephemTab, regRowid);
+ sqlite3VdbeAddOp3(v, OP_Insert, ephemTab, regRec, regRowid);
+ }
+
+
+ if( bOnePass==0 ){
+ /* End the virtual table scan */
+ sqlite3WhereEnd(pWInfo);
+
+ /* Begin scannning through the ephemeral table. */
+ addr = sqlite3VdbeAddOp1(v, OP_Rewind, ephemTab); VdbeCoverage(v);
+
+ /* Extract arguments from the current row of the ephemeral table and
+ ** invoke the VUpdate method. */
+ for(i=0; i<nArg; i++){
+ sqlite3VdbeAddOp3(v, OP_Column, ephemTab, i, regArg+i);
+ }
}
sqlite3VtabMakeWritable(pParse, pTab);
- sqlite3VdbeAddOp4(v, OP_VUpdate, 0, pTab->nCol+2, iReg, pVTab, P4_VTAB);
+ sqlite3VdbeAddOp4(v, OP_VUpdate, 0, nArg, regArg, 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);
+ /* End of the ephemeral table scan. Or, if using the onepass strategy,
+ ** jump to here if the scan visited zero rows. */
+ if( bOnePass==0 ){
+ sqlite3VdbeAddOp2(v, OP_Next, ephemTab, addr+1); VdbeCoverage(v);
+ sqlite3VdbeJumpHere(v, addr);
+ sqlite3VdbeAddOp2(v, OP_Close, ephemTab, 0);
+ }else{
+ sqlite3WhereEnd(pWInfo);
+ }
}
#endif /* SQLITE_OMIT_VIRTUALTABLE */
@@ -101018,6 +117436,8 @@ static void updateVirtualTable(
** Most of the code in this file may be omitted by defining the
** SQLITE_OMIT_VACUUM macro.
*/
+/* #include "sqliteInt.h" */
+/* #include "vdbeInt.h" */
#if !defined(SQLITE_OMIT_VACUUM) && !defined(SQLITE_OMIT_ATTACH)
/*
@@ -101074,14 +117494,34 @@ static int execExecSql(sqlite3 *db, char **pzErrMsg, const char *zSql){
}
/*
-** The non-standard VACUUM command is used to clean up the database,
+** The 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.
+** in PostgreSQL. The VACUUM command works as follows:
+**
+** (1) Create a new transient database file
+** (2) Copy all content from the database being vacuumed into
+** the new transient database file
+** (3) Copy content from the transient database back into the
+** original database.
+**
+** The transient database requires temporary disk space approximately
+** equal to the size of the original database. The copy operation of
+** step (3) requires additional temporary disk space approximately equal
+** to the size of the original database for the rollback journal.
+** Hence, temporary disk space that is approximately 2x the size of the
+** original database is required. Every page of the database is written
+** approximately 3 times: Once for step (2) and twice for step (3).
+** Two writes per page are required in step (3) because the original
+** database content must be written into the rollback journal prior to
+** overwriting the database with the vacuumed content.
+**
+** Only 1x temporary space and only 1x writes would be required if
+** the copy of step (3) were replaced by deleting the original database
+** and renaming the transient database as the original. But that will
+** not work if other processes are attached to the original database.
+** And a power loss in between deleting the original and renaming the
+** transient would cause the database file to appear to be deleted
+** following reboot.
*/
SQLITE_PRIVATE void sqlite3Vacuum(Parse *pParse){
Vdbe *v = sqlite3GetVdbe(pParse);
@@ -101113,7 +117553,7 @@ SQLITE_PRIVATE int sqlite3RunVacuum(char **pzErrMsg, sqlite3 *db){
sqlite3SetString(pzErrMsg, db, "cannot VACUUM from within a transaction");
return SQLITE_ERROR;
}
- if( db->activeVdbeCnt>1 ){
+ if( db->nVdbeActive>1 ){
sqlite3SetString(pzErrMsg, db,"cannot VACUUM - SQL statements in progress");
return SQLITE_ERROR;
}
@@ -101166,7 +117606,7 @@ SQLITE_PRIVATE int sqlite3RunVacuum(char **pzErrMsg, sqlite3 *db){
** cause problems for the call to BtreeSetPageSize() below. */
sqlite3BtreeCommit(pTemp);
- nRes = sqlite3BtreeGetReserve(pMain);
+ nRes = sqlite3BtreeGetOptimalReserve(pMain);
/* A VACUUM cannot change the pagesize of an encrypted database. */
#ifdef SQLITE_HAS_CODEC
@@ -101216,7 +117656,7 @@ SQLITE_PRIVATE int sqlite3RunVacuum(char **pzErrMsg, sqlite3 *db){
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"
+ " AND coalesce(rootpage,1)>0"
);
if( rc!=SQLITE_OK ) goto end_of_vacuum;
rc = execExecSql(db, pzErrMsg,
@@ -101232,13 +117672,17 @@ SQLITE_PRIVATE int sqlite3RunVacuum(char **pzErrMsg, sqlite3 *db){
** an "INSERT INTO vacuum_db.xxx SELECT * FROM main.xxx;" to copy
** the contents to the temporary database.
*/
+ assert( (db->flags & SQLITE_Vacuum)==0 );
+ db->flags |= SQLITE_Vacuum;
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"
+ " AND coalesce(rootpage,1)>0"
);
+ assert( (db->flags & SQLITE_Vacuum)!=0 );
+ db->flags &= ~SQLITE_Vacuum;
if( rc!=SQLITE_OK ) goto end_of_vacuum;
/* Copy over the sequence table
@@ -101291,6 +117735,7 @@ SQLITE_PRIVATE int sqlite3RunVacuum(char **pzErrMsg, sqlite3 *db){
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 */
+ BTREE_APPLICATION_ID, 0, /* Preserve the application id */
};
assert( 1==sqlite3BtreeIsInTrans(pTemp) );
@@ -101365,6 +117810,7 @@ end_of_vacuum:
** This file contains code used to help implement virtual tables.
*/
#ifndef SQLITE_OMIT_VIRTUALTABLE
+/* #include "sqliteInt.h" */
/*
** Before a virtual table xCreate() or xConnect() method is invoked, the
@@ -101376,6 +117822,8 @@ end_of_vacuum:
struct VtabCtx {
VTable *pVTable; /* The virtual table being constructed */
Table *pTab; /* The Table object to which the virtual table belongs */
+ VtabCtx *pPrior; /* Parent context (if any) */
+ int bDeclared; /* True after sqlite3_declare_vtab() is called */
};
/*
@@ -101395,7 +117843,7 @@ static int createModule(
sqlite3_mutex_enter(db->mutex);
nName = sqlite3Strlen30(zName);
- if( sqlite3HashFind(&db->aModule, zName, nName) ){
+ if( sqlite3HashFind(&db->aModule, zName) ){
rc = SQLITE_MISUSE_BKPT;
}else{
Module *pMod;
@@ -101408,7 +117856,8 @@ static int createModule(
pMod->pModule = pModule;
pMod->pAux = pAux;
pMod->xDestroy = xDestroy;
- pDel = (Module *)sqlite3HashInsert(&db->aModule,zCopy,nName,(void*)pMod);
+ pMod->pEpoTab = 0;
+ pDel = (Module *)sqlite3HashInsert(&db->aModule,zCopy,(void*)pMod);
assert( pDel==0 || pDel==pMod );
if( pDel ){
db->mallocFailed = 1;
@@ -101427,25 +117876,31 @@ static int createModule(
/*
** External API function used to create a new virtual-table module.
*/
-SQLITE_API int sqlite3_create_module(
+SQLITE_API int SQLITE_STDCALL 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 */
){
+#ifdef SQLITE_ENABLE_API_ARMOR
+ if( !sqlite3SafetyCheckOk(db) || zName==0 ) return SQLITE_MISUSE_BKPT;
+#endif
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(
+SQLITE_API int SQLITE_STDCALL 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 */
){
+#ifdef SQLITE_ENABLE_API_ARMOR
+ if( !sqlite3SafetyCheckOk(db) || zName==0 ) return SQLITE_MISUSE_BKPT;
+#endif
return createModule(db, zName, pModule, pAux, xDestroy);
}
@@ -101629,23 +118084,17 @@ SQLITE_PRIVATE void sqlite3VtabClear(sqlite3 *db, Table *p){
** deleted.
*/
static void addModuleArgument(sqlite3 *db, Table *pTable, char *zArg){
- int i = pTable->nModuleArg++;
- int nBytes = sizeof(char *)*(1+pTable->nModuleArg);
+ int nBytes = sizeof(char *)*(2+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{
+ int i = pTable->nModuleArg++;
azModuleArg[i] = zArg;
azModuleArg[i+1] = 0;
+ pTable->azModuleArg = azModuleArg;
}
- pTable->azModuleArg = azModuleArg;
}
/*
@@ -101678,7 +118127,12 @@ SQLITE_PRIVATE void sqlite3VtabBeginParse(
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);
+ assert( (pParse->sNameToken.z==pName2->z && pName2->z!=0)
+ || (pParse->sNameToken.z==pName1->z && pName2->z==0)
+ );
+ pParse->sNameToken.n = (int)(
+ &pModuleName->z[pModuleName->n] - pParse->sNameToken.z
+ );
#ifndef SQLITE_OMIT_AUTHORIZATION
/* Creating a virtual table invokes the authorization callback twice.
@@ -101730,6 +118184,7 @@ SQLITE_PRIVATE void sqlite3VtabFinishParse(Parse *pParse, Token *pEnd){
char *zStmt;
char *zWhere;
int iDb;
+ int iReg;
Vdbe *v;
/* Compute the complete text of the CREATE VIRTUAL TABLE statement */
@@ -101764,8 +118219,10 @@ SQLITE_PRIVATE void sqlite3VtabFinishParse(Parse *pParse, Token *pEnd){
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);
+
+ iReg = ++pParse->nMem;
+ sqlite3VdbeLoadString(v, iReg, pTab->zName);
+ sqlite3VdbeAddOp2(v, OP_VCreate, iDb, iReg);
}
/* If we are rereading the sqlite_master table create the in-memory
@@ -101777,9 +118234,8 @@ SQLITE_PRIVATE void sqlite3VtabFinishParse(Parse *pParse, Token *pEnd){
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);
+ pOld = sqlite3HashInsert(&pSchema->tblHash, zName, pTab);
if( pOld ){
db->mallocFailed = 1;
assert( pTab==pOld ); /* Malloc must have failed inside HashInsert() */
@@ -101809,7 +118265,7 @@ SQLITE_PRIVATE void sqlite3VtabArgExtend(Parse *pParse, Token *p){
pArg->z = p->z;
pArg->n = p->n;
}else{
- assert(pArg->z < p->z);
+ assert(pArg->z <= p->z);
pArg->n = (int)(&p->z[p->n] - pArg->z);
}
}
@@ -101826,15 +118282,27 @@ static int vtabCallConstructor(
int (*xConstruct)(sqlite3*,void*,int,const char*const*,sqlite3_vtab**,char**),
char **pzErr
){
- VtabCtx sCtx, *pPriorCtx;
+ VtabCtx sCtx;
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);
+ char *zModuleName;
int iDb;
+ VtabCtx *pCtx;
+ /* Check that the virtual-table is not already being initialized */
+ for(pCtx=db->pVtabCtx; pCtx; pCtx=pCtx->pPrior){
+ if( pCtx->pTab==pTab ){
+ *pzErr = sqlite3MPrintf(db,
+ "vtable constructor called recursively: %s", pTab->zName
+ );
+ return SQLITE_LOCKED;
+ }
+ }
+
+ zModuleName = sqlite3MPrintf(db, "%s", pTab->zName);
if( !zModuleName ){
return SQLITE_NOMEM;
}
@@ -101855,11 +118323,13 @@ static int vtabCallConstructor(
assert( xConstruct );
sCtx.pTab = pTab;
sCtx.pVTable = pVTable;
- pPriorCtx = db->pVtabCtx;
+ sCtx.pPrior = db->pVtabCtx;
+ sCtx.bDeclared = 0;
db->pVtabCtx = &sCtx;
rc = xConstruct(db, pMod->pAux, nArg, azArg, &pVTable->pVtab, &zErr);
- db->pVtabCtx = pPriorCtx;
+ db->pVtabCtx = sCtx.pPrior;
if( rc==SQLITE_NOMEM ) db->mallocFailed = 1;
+ assert( sCtx.pTab==pTab );
if( SQLITE_OK!=rc ){
if( zErr==0 ){
@@ -101872,15 +118342,17 @@ static int vtabCallConstructor(
}else if( ALWAYS(pVTable->pVtab) ){
/* Justification of ALWAYS(): A correct vtab constructor must allocate
** the sqlite3_vtab object if successful. */
+ memset(pVTable->pVtab, 0, sizeof(pVTable->pVtab[0]));
pVTable->pVtab->pModule = pMod->pModule;
pVTable->nRef = 1;
- if( sCtx.pTab ){
+ if( sCtx.bDeclared==0 ){
const char *zFormat = "vtable constructor did not declare schema: %s";
*pzErr = sqlite3MPrintf(db, zFormat, pTab->zName);
sqlite3VtabUnlock(pVTable);
rc = SQLITE_ERROR;
}else{
int iCol;
+ u8 oooHidden = 0;
/* 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".
@@ -101893,7 +118365,10 @@ static int vtabCallConstructor(
char *zType = pTab->aCol[iCol].zType;
int nType;
int i = 0;
- if( !zType ) continue;
+ if( !zType ){
+ pTab->tabFlags |= oooHidden;
+ continue;
+ }
nType = sqlite3Strlen30(zType);
if( sqlite3StrNICmp("hidden", zType, 6)||(zType[6] && zType[6]!=' ') ){
for(i=0; i<nType; i++){
@@ -101916,6 +118391,9 @@ static int vtabCallConstructor(
zType[i-1] = '\0';
}
pTab->aCol[iCol].colFlags |= COLFLAG_HIDDEN;
+ oooHidden = TF_OOOHidden;
+ }else{
+ pTab->tabFlags |= oooHidden;
}
}
}
@@ -101945,7 +118423,7 @@ SQLITE_PRIVATE int sqlite3VtabCallConnect(Parse *pParse, Table *pTab){
/* Locate the required virtual table module */
zMod = pTab->azModuleArg[0];
- pMod = (Module*)sqlite3HashFind(&db->aModule, zMod, sqlite3Strlen30(zMod));
+ pMod = (Module*)sqlite3HashFind(&db->aModule, zMod);
if( !pMod ){
const char *zModule = pTab->azModuleArg[0];
@@ -102013,13 +118491,13 @@ SQLITE_PRIVATE int sqlite3VtabCallCreate(sqlite3 *db, int iDb, const char *zTab,
/* Locate the required virtual table module */
zMod = pTab->azModuleArg[0];
- pMod = (Module*)sqlite3HashFind(&db->aModule, zMod, sqlite3Strlen30(zMod));
+ pMod = (Module*)sqlite3HashFind(&db->aModule, 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 ){
+ if( pMod==0 || pMod->pModule->xCreate==0 || pMod->pModule->xDestroy==0 ){
*pzErr = sqlite3MPrintf(db, "no such module: %s", zMod);
rc = SQLITE_ERROR;
}else{
@@ -102043,19 +118521,26 @@ SQLITE_PRIVATE int sqlite3VtabCallCreate(sqlite3 *db, int iDb, const char *zTab,
** 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){
+SQLITE_API int SQLITE_STDCALL sqlite3_declare_vtab(sqlite3 *db, const char *zCreateTable){
+ VtabCtx *pCtx;
Parse *pParse;
-
int rc = SQLITE_OK;
Table *pTab;
char *zErr = 0;
+#ifdef SQLITE_ENABLE_API_ARMOR
+ if( !sqlite3SafetyCheckOk(db) || zCreateTable==0 ){
+ return SQLITE_MISUSE_BKPT;
+ }
+#endif
sqlite3_mutex_enter(db->mutex);
- if( !db->pVtabCtx || !(pTab = db->pVtabCtx->pTab) ){
- sqlite3Error(db, SQLITE_MISUSE, 0);
+ pCtx = db->pVtabCtx;
+ if( !pCtx || pCtx->bDeclared ){
+ sqlite3Error(db, SQLITE_MISUSE);
sqlite3_mutex_leave(db->mutex);
return SQLITE_MISUSE_BKPT;
}
+ pTab = pCtx->pTab;
assert( (pTab->tabFlags & TF_Virtual)!=0 );
pParse = sqlite3StackAllocZero(db, sizeof(*pParse));
@@ -102078,9 +118563,9 @@ SQLITE_API int sqlite3_declare_vtab(sqlite3 *db, const char *zCreateTable){
pParse->pNewTable->nCol = 0;
pParse->pNewTable->aCol = 0;
}
- db->pVtabCtx->pTab = 0;
+ pCtx->bDeclared = 1;
}else{
- sqlite3Error(db, SQLITE_ERROR, (zErr ? "%s" : 0), zErr);
+ sqlite3ErrorWithMsg(db, SQLITE_ERROR, (zErr ? "%s" : 0), zErr);
sqlite3DbFree(db, zErr);
rc = SQLITE_ERROR;
}
@@ -102090,6 +118575,7 @@ SQLITE_API int sqlite3_declare_vtab(sqlite3 *db, const char *zCreateTable){
sqlite3VdbeFinalize(pParse->pVdbe);
}
sqlite3DeleteTable(db, pParse->pNewTable);
+ sqlite3ParserReset(pParse);
sqlite3StackFree(db, pParse);
}
@@ -102112,11 +118598,18 @@ SQLITE_PRIVATE int sqlite3VtabCallDestroy(sqlite3 *db, int iDb, const char *zTab
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);
-
+ VTable *p;
+ int (*xDestroy)(sqlite3_vtab *);
+ for(p=pTab->pVTable; p; p=p->pNext){
+ assert( p->pVtab );
+ if( p->pVtab->nRef>0 ){
+ return SQLITE_LOCKED;
+ }
+ }
+ p = vtabDisconnectAll(db, pTab);
+ xDestroy = p->pMod->pModule->xDestroy;
+ assert( xDestroy!=0 ); /* Checked before the virtual table is created */
+ rc = xDestroy(p->pVtab);
/* Remove the sqlite3_vtab* from the aVTrans[] array, if applicable */
if( rc==SQLITE_OK ){
assert( pTab->pVTable==p && p->pNext==0 );
@@ -102140,8 +118633,10 @@ SQLITE_PRIVATE int sqlite3VtabCallDestroy(sqlite3 *db, int iDb, const char *zTab
static void callFinaliser(sqlite3 *db, int offset){
int i;
if( db->aVTrans ){
+ VTable **aVTrans = db->aVTrans;
+ db->aVTrans = 0;
for(i=0; i<db->nVTrans; i++){
- VTable *pVTab = db->aVTrans[i];
+ VTable *pVTab = aVTrans[i];
sqlite3_vtab *p = pVTab->pVtab;
if( p ){
int (*x)(sqlite3_vtab *);
@@ -102151,9 +118646,8 @@ static void callFinaliser(sqlite3 *db, int offset){
pVTab->iSavepoint = 0;
sqlite3VtabUnlock(pVTab);
}
- sqlite3DbFree(db, db->aVTrans);
+ sqlite3DbFree(db, aVTrans);
db->nVTrans = 0;
- db->aVTrans = 0;
}
}
@@ -102162,10 +118656,9 @@ static void callFinaliser(sqlite3 *db, int offset){
** 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.
+** If an error message is available, leave it in p->zErrMsg.
*/
-SQLITE_PRIVATE int sqlite3VtabSync(sqlite3 *db, char **pzErrmsg){
+SQLITE_PRIVATE int sqlite3VtabSync(sqlite3 *db, Vdbe *p){
int i;
int rc = SQLITE_OK;
VTable **aVTrans = db->aVTrans;
@@ -102176,9 +118669,7 @@ SQLITE_PRIVATE int sqlite3VtabSync(sqlite3 *db, char **pzErrmsg){
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);
+ sqlite3VtabImportErrmsg(p, pVtab);
}
}
db->aVTrans = aVTrans;
@@ -102244,7 +118735,9 @@ SQLITE_PRIVATE int sqlite3VtabBegin(sqlite3 *db, VTable *pVTab){
if( rc==SQLITE_OK ){
rc = pModule->xBegin(pVTab->pVtab);
if( rc==SQLITE_OK ){
+ int iSvpt = db->nStatement + db->nSavepoint;
addToVTrans(db, pVTab);
+ if( iSvpt ) rc = sqlite3VtabSavepoint(db, SAVEPOINT_BEGIN, iSvpt-1);
}
}
}
@@ -102270,7 +118763,7 @@ 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 );
+ assert( iSavepoint>=-1 );
if( db->aVTrans ){
int i;
for(i=0; rc==SQLITE_OK && i<db->nVTrans; i++){
@@ -102368,7 +118861,7 @@ SQLITE_PRIVATE FuncDef *sqlite3VtabOverloadFunction(
memcpy(pNew->zName, pDef->zName, sqlite3Strlen30(pDef->zName)+1);
pNew->xFunc = xFunc;
pNew->pUserData = pArg;
- pNew->flags |= SQLITE_FUNC_EPHEM;
+ pNew->funcFlags |= SQLITE_FUNC_EPHEM;
return pNew;
}
@@ -102388,7 +118881,7 @@ SQLITE_PRIVATE void sqlite3VtabMakeWritable(Parse *pParse, Table *pTab){
if( pTab==pToplevel->apVtabLock[i] ) return;
}
n = (pToplevel->nVtabLock+1)*sizeof(pToplevel->apVtabLock[0]);
- apVtabLock = sqlite3_realloc(pToplevel->apVtabLock, n);
+ apVtabLock = sqlite3_realloc64(pToplevel->apVtabLock, n);
if( apVtabLock ){
pToplevel->apVtabLock = apVtabLock;
pToplevel->apVtabLock[pToplevel->nVtabLock++] = pTab;
@@ -102398,16 +118891,80 @@ SQLITE_PRIVATE void sqlite3VtabMakeWritable(Parse *pParse, Table *pTab){
}
/*
+** Check to see if virtual tale module pMod can be have an eponymous
+** virtual table instance. If it can, create one if one does not already
+** exist. Return non-zero if the eponymous virtual table instance exists
+** when this routine returns, and return zero if it does not exist.
+**
+** An eponymous virtual table instance is one that is named after its
+** module, and more importantly, does not require a CREATE VIRTUAL TABLE
+** statement in order to come into existance. Eponymous virtual table
+** instances always exist. They cannot be DROP-ed.
+**
+** Any virtual table module for which xConnect and xCreate are the same
+** method can have an eponymous virtual table instance.
+*/
+SQLITE_PRIVATE int sqlite3VtabEponymousTableInit(Parse *pParse, Module *pMod){
+ const sqlite3_module *pModule = pMod->pModule;
+ Table *pTab;
+ char *zErr = 0;
+ int nName;
+ int rc;
+ sqlite3 *db = pParse->db;
+ if( pMod->pEpoTab ) return 1;
+ if( pModule->xCreate!=0 && pModule->xCreate!=pModule->xConnect ) return 0;
+ nName = sqlite3Strlen30(pMod->zName) + 1;
+ pTab = sqlite3DbMallocZero(db, sizeof(Table) + nName);
+ if( pTab==0 ) return 0;
+ pMod->pEpoTab = pTab;
+ pTab->zName = (char*)&pTab[1];
+ memcpy(pTab->zName, pMod->zName, nName);
+ pTab->nRef = 1;
+ pTab->pSchema = db->aDb[0].pSchema;
+ pTab->tabFlags |= TF_Virtual;
+ pTab->nModuleArg = 0;
+ pTab->iPKey = -1;
+ addModuleArgument(db, pTab, sqlite3DbStrDup(db, pTab->zName));
+ addModuleArgument(db, pTab, 0);
+ addModuleArgument(db, pTab, sqlite3DbStrDup(db, pTab->zName));
+ rc = vtabCallConstructor(db, pTab, pMod, pModule->xConnect, &zErr);
+ if( rc ){
+ sqlite3ErrorMsg(pParse, "%s", zErr);
+ sqlite3DbFree(db, zErr);
+ sqlite3VtabEponymousTableClear(db, pMod);
+ return 0;
+ }
+ return 1;
+}
+
+/*
+** Erase the eponymous virtual table instance associated with
+** virtual table module pMod, if it exists.
+*/
+SQLITE_PRIVATE void sqlite3VtabEponymousTableClear(sqlite3 *db, Module *pMod){
+ Table *pTab = pMod->pEpoTab;
+ if( pTab!=0 ){
+ sqlite3DeleteColumnNames(db, pTab);
+ sqlite3VtabClear(db, pTab);
+ sqlite3DbFree(db, pTab);
+ pMod->pEpoTab = 0;
+ }
+}
+
+/*
** 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){
+SQLITE_API int SQLITE_STDCALL sqlite3_vtab_on_conflict(sqlite3 *db){
static const unsigned char aMap[] = {
SQLITE_ROLLBACK, SQLITE_ABORT, SQLITE_FAIL, SQLITE_IGNORE, SQLITE_REPLACE
};
+#ifdef SQLITE_ENABLE_API_ARMOR
+ if( !sqlite3SafetyCheckOk(db) ) return SQLITE_MISUSE_BKPT;
+#endif
assert( OE_Rollback==1 && OE_Abort==2 && OE_Fail==3 );
assert( OE_Ignore==4 && OE_Replace==5 );
assert( db->vtabOnConflict>=1 && db->vtabOnConflict<=5 );
@@ -102419,12 +118976,14 @@ SQLITE_API int sqlite3_vtab_on_conflict(sqlite3 *db){
** 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, ...){
+SQLITE_API int SQLITE_CDECL sqlite3_vtab_config(sqlite3 *db, int op, ...){
va_list ap;
int rc = SQLITE_OK;
+#ifdef SQLITE_ENABLE_API_ARMOR
+ if( !sqlite3SafetyCheckOk(db) ) return SQLITE_MISUSE_BKPT;
+#endif
sqlite3_mutex_enter(db->mutex);
-
va_start(ap, op);
switch( op ){
case SQLITE_VTAB_CONSTRAINT_SUPPORT: {
@@ -102443,7 +119002,7 @@ SQLITE_API int sqlite3_vtab_config(sqlite3 *db, int op, ...){
}
va_end(ap);
- if( rc!=SQLITE_OK ) sqlite3Error(db, rc, 0);
+ if( rc!=SQLITE_OK ) sqlite3Error(db, rc);
sqlite3_mutex_leave(db->mutex);
return rc;
}
@@ -102451,9 +119010,9 @@ SQLITE_API int sqlite3_vtab_config(sqlite3 *db, int op, ...){
#endif /* SQLITE_OMIT_VIRTUALTABLE */
/************** End of vtab.c ************************************************/
-/************** Begin file where.c *******************************************/
+/************** Begin file wherecode.c ***************************************/
/*
-** 2001 September 15
+** 2015-06-06
**
** The author disclaims copyright to this source code. In place of
** a legal notice, here is a blessing:
@@ -102464,34 +119023,208 @@ SQLITE_API int sqlite3_vtab_config(sqlite3 *db, int op, ...){
**
*************************************************************************
** 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".
+** the WHERE clause of SQL statements.
+**
+** This file was split off from where.c on 2015-06-06 in order to reduce the
+** size of where.c and make it easier to edit. This file contains the routines
+** that actually generate the bulk of the WHERE loop code. The original where.c
+** file retains the code that does query planning and analysis.
+*/
+/* #include "sqliteInt.h" */
+/************** Include whereInt.h in the middle of wherecode.c **************/
+/************** Begin file whereInt.h ****************************************/
+/*
+** 2013-11-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.
+**
+*************************************************************************
+**
+** This file contains structure and macro definitions for the query
+** planner logic in "where.c". These definitions are broken out into
+** a separate source file for easier editing.
*/
-
/*
** Trace output macros
*/
#if defined(SQLITE_TEST) || defined(SQLITE_DEBUG)
-/***/ int sqlite3WhereTrace = 0;
+/***/ int sqlite3WhereTrace;
#endif
#if defined(SQLITE_DEBUG) \
&& (defined(SQLITE_TEST) || defined(SQLITE_ENABLE_WHERETRACE))
-# define WHERETRACE(X) if(sqlite3WhereTrace) sqlite3DebugPrintf X
+# define WHERETRACE(K,X) if(sqlite3WhereTrace&(K)) sqlite3DebugPrintf X
+# define WHERETRACE_ENABLED 1
#else
-# define WHERETRACE(X)
+# define WHERETRACE(K,X)
#endif
-/* Forward reference
+/* Forward references
*/
typedef struct WhereClause WhereClause;
typedef struct WhereMaskSet WhereMaskSet;
typedef struct WhereOrInfo WhereOrInfo;
typedef struct WhereAndInfo WhereAndInfo;
-typedef struct WhereCost WhereCost;
+typedef struct WhereLevel WhereLevel;
+typedef struct WhereLoop WhereLoop;
+typedef struct WherePath WherePath;
+typedef struct WhereTerm WhereTerm;
+typedef struct WhereLoopBuilder WhereLoopBuilder;
+typedef struct WhereScan WhereScan;
+typedef struct WhereOrCost WhereOrCost;
+typedef struct WhereOrSet WhereOrSet;
+
+/*
+** This object contains information needed to implement a single nested
+** loop in WHERE clause.
+**
+** Contrast this object with WhereLoop. This object describes the
+** implementation of the loop. WhereLoop describes the algorithm.
+** This object contains a pointer to the WhereLoop algorithm as one of
+** its elements.
+**
+** The WhereInfo object contains a single instance of this object for
+** each term in the FROM clause (which is to say, for each of the
+** nested loops as implemented). The order of WhereLevel objects determines
+** the loop nested order, with WhereInfo.a[0] being the outer loop and
+** WhereInfo.a[WhereInfo.nLevel-1] being the inner loop.
+*/
+struct WhereLevel {
+ 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 addrSkip; /* Jump here for next iteration of skip-scan */
+ int addrCont; /* Jump here to continue with the next loop cycle */
+ int addrFirst; /* First instruction of interior of the loop */
+ int addrBody; /* Beginning of the body of this loop */
+#ifndef SQLITE_LIKE_DOESNT_MATCH_BLOBS
+ int iLikeRepCntr; /* LIKE range processing counter register */
+ int addrLikeRep; /* LIKE range processing address */
+#endif
+ u8 iFrom; /* Which entry in the FROM clause */
+ u8 op, p3, p5; /* Opcode, P3 & 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 pWLoop->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 */
+ u8 eEndLoopOp; /* IN Loop terminator. OP_Next or OP_Prev */
+ } *aInLoop; /* Information about each nested IN operator */
+ } in; /* Used when pWLoop->wsFlags&WHERE_IN_ABLE */
+ Index *pCovidx; /* Possible covering index for WHERE_MULTI_OR */
+ } u;
+ struct WhereLoop *pWLoop; /* The selected WhereLoop object */
+ Bitmask notReady; /* FROM entries not usable at this level */
+#ifdef SQLITE_ENABLE_STMT_SCANSTATUS
+ int addrVisit; /* Address at which row is visited */
+#endif
+};
+
+/*
+** Each instance of this object represents an algorithm for evaluating one
+** term of a join. Every term of the FROM clause will have at least
+** one corresponding WhereLoop object (unless INDEXED BY constraints
+** prevent a query solution - which is an error) and many terms of the
+** FROM clause will have multiple WhereLoop objects, each describing a
+** potential way of implementing that FROM-clause term, together with
+** dependencies and cost estimates for using the chosen algorithm.
+**
+** Query planning consists of building up a collection of these WhereLoop
+** objects, then computing a particular sequence of WhereLoop objects, with
+** one WhereLoop object per FROM clause term, that satisfy all dependencies
+** and that minimize the overall cost.
+*/
+struct WhereLoop {
+ Bitmask prereq; /* Bitmask of other loops that must run first */
+ Bitmask maskSelf; /* Bitmask identifying table iTab */
+#ifdef SQLITE_DEBUG
+ char cId; /* Symbolic ID of this loop for debugging use */
+#endif
+ u8 iTab; /* Position in FROM clause of table for this loop */
+ u8 iSortIdx; /* Sorting index number. 0==None */
+ LogEst rSetup; /* One-time setup cost (ex: create transient index) */
+ LogEst rRun; /* Cost of running each loop */
+ LogEst nOut; /* Estimated number of output rows */
+ union {
+ struct { /* Information for internal btree tables */
+ u16 nEq; /* Number of equality constraints */
+ Index *pIndex; /* Index used, or NULL */
+ } btree;
+ struct { /* Information for virtual tables */
+ int idxNum; /* Index number */
+ u8 needFree; /* True if sqlite3_free(idxStr) is needed */
+ i8 isOrdered; /* True if satisfies ORDER BY */
+ u16 omitMask; /* Terms that may be omitted */
+ char *idxStr; /* Index identifier string */
+ } vtab;
+ } u;
+ u32 wsFlags; /* WHERE_* flags describing the plan */
+ u16 nLTerm; /* Number of entries in aLTerm[] */
+ u16 nSkip; /* Number of NULL aLTerm[] entries */
+ /**** whereLoopXfer() copies fields above ***********************/
+# define WHERE_LOOP_XFER_SZ offsetof(WhereLoop,nLSlot)
+ u16 nLSlot; /* Number of slots allocated for aLTerm[] */
+ WhereTerm **aLTerm; /* WhereTerms used */
+ WhereLoop *pNextLoop; /* Next WhereLoop object in the WhereClause */
+ WhereTerm *aLTermSpace[3]; /* Initial aLTerm[] space */
+};
+
+/* This object holds the prerequisites and the cost of running a
+** subquery on one operand of an OR operator in the WHERE clause.
+** See WhereOrSet for additional information
+*/
+struct WhereOrCost {
+ Bitmask prereq; /* Prerequisites */
+ LogEst rRun; /* Cost of running this subquery */
+ LogEst nOut; /* Number of outputs for this subquery */
+};
+
+/* The WhereOrSet object holds a set of possible WhereOrCosts that
+** correspond to the subquery(s) of OR-clause processing. Only the
+** best N_OR_COST elements are retained.
+*/
+#define N_OR_COST 3
+struct WhereOrSet {
+ u16 n; /* Number of valid a[] entries */
+ WhereOrCost a[N_OR_COST]; /* Set of best costs */
+};
+
+/*
+** Each instance of this object holds a sequence of WhereLoop objects
+** that implement some or all of a query plan.
+**
+** Think of each WhereLoop object as a node in a graph with arcs
+** showing dependencies and costs for travelling between nodes. (That is
+** not a completely accurate description because WhereLoop costs are a
+** vector, not a scalar, and because dependencies are many-to-one, not
+** one-to-one as are graph nodes. But it is a useful visualization aid.)
+** Then a WherePath object is a path through the graph that visits some
+** or all of the WhereLoop objects once.
+**
+** The "solver" works by creating the N best WherePath objects of length
+** 1. Then using those as a basis to compute the N best WherePath objects
+** of length 2. And so forth until the length of WherePaths equals the
+** number of nodes in the FROM clause. The best (lowest cost) WherePath
+** at the end is the chosen query plan.
+*/
+struct WherePath {
+ Bitmask maskLoop; /* Bitmask of all WhereLoop objects in this path */
+ Bitmask revLoop; /* aLoop[]s that should be reversed for ORDER BY */
+ LogEst nRow; /* Estimated number of rows generated by this path */
+ LogEst rCost; /* Total cost of this path */
+ LogEst rUnsorted; /* Total cost of this path ignoring sorting costs */
+ i8 isOrdered; /* No. of ORDER BY terms satisfied. -1 for unknown */
+ WhereLoop **aLoop; /* Array of WhereLoop objects implementing this path */
+};
/*
** The query generator uses an array of instances of this structure to
@@ -102519,9 +119252,9 @@ typedef struct WhereCost WhereCost;
**
** (t1.X <op> <expr>) OR (t1.Y <op> <expr>) OR ....
**
-** In this second case, wtFlag as the TERM_ORINFO set and eOperator==WO_OR
+** In this second case, wtFlag has the TERM_ORINFO bit set and eOperator==WO_OR
** and the WhereTerm.u.pOrInfo field points to auxiliary information that
-** is collected about the
+** is collected about the OR clause.
**
** 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
@@ -102544,19 +119277,20 @@ typedef struct WhereCost WhereCost;
** 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 */
+ WhereOrInfo *pOrInfo; /* Extra information if (eOperator & WO_OR)!=0 */
+ WhereAndInfo *pAndInfo; /* Extra information if (eOperator& WO_AND)!=0 */
} u;
+ LogEst truthProb; /* Probability of truth for this expression */
u16 eOperator; /* A WO_xx value describing <op> */
- u8 wtFlags; /* TERM_xxx bit flags. See below */
+ u16 wtFlags; /* TERM_xxx bit flags. See below */
u8 nChild; /* Number of children that must disable us */
+ u8 eMatchOp; /* Op for vtab MATCH/LIKE/GLOB/REGEXP terms */
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 */
@@ -102572,11 +119306,33 @@ struct WhereTerm {
#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
+#ifdef SQLITE_ENABLE_STAT3_OR_STAT4
# define TERM_VNULL 0x80 /* Manufactured x>NULL or x<=NULL term */
#else
# define TERM_VNULL 0x00 /* Disabled if not using stat3 */
#endif
+#define TERM_LIKEOPT 0x100 /* Virtual terms from the LIKE optimization */
+#define TERM_LIKECOND 0x200 /* Conditionally this LIKE operator term */
+#define TERM_LIKE 0x400 /* The original LIKE operator */
+#define TERM_IS 0x800 /* Term.pExpr is an IS operator */
+
+/*
+** An instance of the WhereScan object is used as an iterator for locating
+** terms in the WHERE clause that are useful to the query planner.
+*/
+struct WhereScan {
+ WhereClause *pOrigWC; /* Original, innermost WhereClause */
+ WhereClause *pWC; /* WhereClause currently being scanned */
+ const char *zCollName; /* Required collating sequence, if not NULL */
+ Expr *pIdxExpr; /* Search for this index expression */
+ char idxaff; /* Must match this affinity, if zCollName!=NULL */
+ unsigned char nEquiv; /* Number of entries in aEquiv[] */
+ unsigned char iEquiv; /* Next unused slot in aEquiv[] */
+ u32 opMask; /* Acceptable operators */
+ int k; /* Resume scanning at this->pWC->a[this->k] */
+ int aiCur[11]; /* Cursors in the equivalence class */
+ i16 aiColumn[11]; /* Corresponding column number in the eq-class */
+};
/*
** An instance of the following structure holds all information about a
@@ -102591,12 +119347,9 @@ struct WhereTerm {
** 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 */
+ WhereInfo *pWInfo; /* WHERE clause processing context */
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 */
@@ -102656,163 +119409,1863 @@ struct WhereMaskSet {
};
/*
-** A WhereCost object records a lookup strategy and the estimated
-** cost of pursuing that strategy.
+** Initialize a WhereMaskSet object
*/
-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 */
+#define initMaskSet(P) (P)->n=0
+
+/*
+** This object is a convenience wrapper holding all information needed
+** to construct WhereLoop objects for a particular query.
+*/
+struct WhereLoopBuilder {
+ WhereInfo *pWInfo; /* Information about this WHERE */
+ WhereClause *pWC; /* WHERE clause terms */
+ ExprList *pOrderBy; /* ORDER BY clause */
+ WhereLoop *pNew; /* Template WhereLoop */
+ WhereOrSet *pOrSet; /* Record best loops here, if not NULL */
+#ifdef SQLITE_ENABLE_STAT3_OR_STAT4
+ UnpackedRecord *pRec; /* Probe for stat4 (if required) */
+ int nRecValid; /* Number of valid fields currently in pRec */
+#endif
+};
+
+/*
+** 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.
+**
+** An instance of this object holds the complete state of the query
+** planner.
+*/
+struct WhereInfo {
+ Parse *pParse; /* Parsing and code generating context */
+ SrcList *pTabList; /* List of tables in the join */
+ ExprList *pOrderBy; /* The ORDER BY clause or NULL */
+ ExprList *pResultSet; /* Result set. DISTINCT operates on these */
+ WhereLoop *pLoops; /* List of all WhereLoop objects */
+ Bitmask revMask; /* Mask of ORDER BY terms that need reversing */
+ LogEst nRowOut; /* Estimated number of output rows */
+ u16 wctrlFlags; /* Flags originally passed to sqlite3WhereBegin() */
+ i8 nOBSat; /* Number of ORDER BY terms satisfied by indices */
+ u8 sorted; /* True if really sorted (not just grouped) */
+ u8 eOnePass; /* ONEPASS_OFF, or _SINGLE, or _MULTI */
+ u8 untestedTerms; /* Not all WHERE terms resolved by outer loop */
+ u8 eDistinct; /* One of the WHERE_DISTINCT_* values below */
+ u8 nLevel; /* Number of nested loop */
+ 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 savedNQueryLoop; /* pParse->nQueryLoop outside the WHERE loop */
+ int aiCurOnePass[2]; /* OP_OpenWrite cursors for the ONEPASS opt */
+ WhereMaskSet sMaskSet; /* Map cursor numbers to bitmasks */
+ WhereClause sWC; /* Decomposition of the WHERE clause */
+ WhereLevel a[1]; /* Information about each nest loop in WHERE */
};
/*
-** Bitmasks for the operators that indices are able to exploit. An
+** Private interfaces - callable only by other where.c routines.
+**
+** where.c:
+*/
+SQLITE_PRIVATE Bitmask sqlite3WhereGetMask(WhereMaskSet*,int);
+SQLITE_PRIVATE WhereTerm *sqlite3WhereFindTerm(
+ 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 */
+);
+
+/* wherecode.c: */
+#ifndef SQLITE_OMIT_EXPLAIN
+SQLITE_PRIVATE int sqlite3WhereExplainOneScan(
+ 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() */
+);
+#else
+# define sqlite3WhereExplainOneScan(u,v,w,x,y,z) 0
+#endif /* SQLITE_OMIT_EXPLAIN */
+#ifdef SQLITE_ENABLE_STMT_SCANSTATUS
+SQLITE_PRIVATE void sqlite3WhereAddScanStatus(
+ Vdbe *v, /* Vdbe to add scanstatus entry to */
+ SrcList *pSrclist, /* FROM clause pLvl reads data from */
+ WhereLevel *pLvl, /* Level to add scanstatus() entry for */
+ int addrExplain /* Address of OP_Explain (or 0) */
+);
+#else
+# define sqlite3WhereAddScanStatus(a, b, c, d) ((void)d)
+#endif
+SQLITE_PRIVATE Bitmask sqlite3WhereCodeOneLoopStart(
+ WhereInfo *pWInfo, /* Complete information about the WHERE clause */
+ int iLevel, /* Which level of pWInfo->a[] should be coded */
+ Bitmask notReady /* Which tables are currently available */
+);
+
+/* whereexpr.c: */
+SQLITE_PRIVATE void sqlite3WhereClauseInit(WhereClause*,WhereInfo*);
+SQLITE_PRIVATE void sqlite3WhereClauseClear(WhereClause*);
+SQLITE_PRIVATE void sqlite3WhereSplit(WhereClause*,Expr*,u8);
+SQLITE_PRIVATE Bitmask sqlite3WhereExprUsage(WhereMaskSet*, Expr*);
+SQLITE_PRIVATE Bitmask sqlite3WhereExprListUsage(WhereMaskSet*, ExprList*);
+SQLITE_PRIVATE void sqlite3WhereExprAnalyze(SrcList*, WhereClause*);
+SQLITE_PRIVATE void sqlite3WhereTabFuncArgs(Parse*, struct SrcList_item*, WhereClause*);
+
+
+
+
+
+/*
+** Bitmasks for the operators on WhereTerm objects. These are all
+** operators that are of interest to the query planner. An
** OR-ed combination of these values can be used when searching for
-** terms in the where clause.
+** particular WhereTerms within a WhereClause.
*/
-#define WO_IN 0x001
-#define WO_EQ 0x002
+#define WO_IN 0x0001
+#define WO_EQ 0x0002
#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.
+#define WO_MATCH 0x0040
+#define WO_IS 0x0080
+#define WO_ISNULL 0x0100
+#define WO_OR 0x0200 /* Two or more OR-connected terms */
+#define WO_AND 0x0400 /* Two or more AND-connected terms */
+#define WO_EQUIV 0x0800 /* Of the form A==B, both columns */
+#define WO_NOOP 0x1000 /* This term does not restrict search space */
+
+#define WO_ALL 0x1fff /* Mask of all possible WO_* values */
+#define WO_SINGLE 0x01ff /* Mask of all non-compound WO_* values */
+
+/*
+** These are definitions of bits in the WhereLoop.wsFlags field.
+** The particular combination of bits in each WhereLoop help to
+** determine the algorithm that WhereLoop represents.
+*/
+#define WHERE_COLUMN_EQ 0x00000001 /* x=EXPR */
+#define WHERE_COLUMN_RANGE 0x00000002 /* x<EXPR and/or x>EXPR */
+#define WHERE_COLUMN_IN 0x00000004 /* x IN (...) */
+#define WHERE_COLUMN_NULL 0x00000008 /* x IS NULL */
+#define WHERE_CONSTRAINT 0x0000000f /* Any of the WHERE_COLUMN_xxx values */
+#define WHERE_TOP_LIMIT 0x00000010 /* x<EXPR or x<=EXPR constraint */
+#define WHERE_BTM_LIMIT 0x00000020 /* x>EXPR or x>=EXPR constraint */
+#define WHERE_BOTH_LIMIT 0x00000030 /* Both x>EXPR and x<EXPR */
+#define WHERE_IDX_ONLY 0x00000040 /* Use index only - omit table */
+#define WHERE_IPK 0x00000100 /* x is the INTEGER PRIMARY KEY */
+#define WHERE_INDEXED 0x00000200 /* WhereLoop.u.btree.pIndex is valid */
+#define WHERE_VIRTUALTABLE 0x00000400 /* WhereLoop.u.vtab is valid */
+#define WHERE_IN_ABLE 0x00000800 /* Able to support an IN operator */
+#define WHERE_ONEROW 0x00001000 /* Selects no more than one row */
+#define WHERE_MULTI_OR 0x00002000 /* OR using multiple indices */
+#define WHERE_AUTO_INDEX 0x00004000 /* Uses an ephemeral index */
+#define WHERE_SKIPSCAN 0x00008000 /* Uses the skip-scan algorithm */
+#define WHERE_UNQ_WANTED 0x00010000 /* WHERE_ONEROW would have been helpful*/
+#define WHERE_PARTIALIDX 0x00020000 /* The automatic index is partial */
+
+/************** End of whereInt.h ********************************************/
+/************** Continuing where we left off in wherecode.c ******************/
+
+#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.
*/
-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 */
-};
+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);
+ sqlite3StrAccumAppendAll(pStr, zColumn);
+ sqlite3StrAccumAppend(pStr, zOp, 1);
+ sqlite3StrAccumAppend(pStr, "?", 1);
+}
/*
-** Return TRUE if the probe cost is less than the baseline cost
+** Return the name of the i-th column of the pIdx index.
*/
-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;
+static const char *explainIndexColumnName(Index *pIdx, int i){
+ i = pIdx->aiColumn[i];
+ if( i==XN_EXPR ) return "<expr>";
+ if( i==XN_ROWID ) return "rowid";
+ return pIdx->pTable->aCol[i].zName;
}
/*
-** Initialize a preallocated WhereClause structure.
+** Argument pLevel describes a strategy for scanning table pTab. This
+** function appends text to pStr that describes the subset of table
+** rows scanned by the strategy in the form of an SQL expression.
+**
+** 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>?"
*/
-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 */
+static void explainIndexRange(StrAccum *pStr, WhereLoop *pLoop){
+ Index *pIndex = pLoop->u.btree.pIndex;
+ u16 nEq = pLoop->u.btree.nEq;
+ u16 nSkip = pLoop->nSkip;
+ int i, j;
+
+ if( nEq==0 && (pLoop->wsFlags&(WHERE_BTM_LIMIT|WHERE_TOP_LIMIT))==0 ) return;
+ sqlite3StrAccumAppend(pStr, " (", 2);
+ for(i=0; i<nEq; i++){
+ const char *z = explainIndexColumnName(pIndex, i);
+ if( i ) sqlite3StrAccumAppend(pStr, " AND ", 5);
+ sqlite3XPrintf(pStr, 0, i>=nSkip ? "%s=?" : "ANY(%s)", z);
+ }
+
+ j = i;
+ if( pLoop->wsFlags&WHERE_BTM_LIMIT ){
+ const char *z = explainIndexColumnName(pIndex, i);
+ explainAppendTerm(pStr, i++, z, ">");
+ }
+ if( pLoop->wsFlags&WHERE_TOP_LIMIT ){
+ const char *z = explainIndexColumnName(pIndex, j);
+ explainAppendTerm(pStr, i, z, "<");
+ }
+ sqlite3StrAccumAppend(pStr, ")", 1);
+}
+
+/*
+** This function is a no-op unless currently processing an EXPLAIN QUERY PLAN
+** command, or if either SQLITE_DEBUG or SQLITE_ENABLE_STMT_SCANSTATUS was
+** defined at compile-time. If it is not a no-op, a single OP_Explain opcode
+** is added to the output to describe the table scan strategy in pLevel.
+**
+** If an OP_Explain opcode is added to the VM, its address is returned.
+** Otherwise, if no OP_Explain is coded, zero is returned.
+*/
+SQLITE_PRIVATE int sqlite3WhereExplainOneScan(
+ 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() */
){
- 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;
+ int ret = 0;
+#if !defined(SQLITE_DEBUG) && !defined(SQLITE_ENABLE_STMT_SCANSTATUS)
+ if( pParse->explain==2 )
+#endif
+ {
+ struct SrcList_item *pItem = &pTabList->a[pLevel->iFrom];
+ Vdbe *v = pParse->pVdbe; /* VM being constructed */
+ sqlite3 *db = pParse->db; /* Database handle */
+ int iId = pParse->iSelectId; /* Select id (left-most output column) */
+ int isSearch; /* True for a SEARCH. False for SCAN. */
+ WhereLoop *pLoop; /* The controlling WhereLoop object */
+ u32 flags; /* Flags that describe this loop */
+ char *zMsg; /* Text to add to EQP output */
+ StrAccum str; /* EQP output string */
+ char zBuf[100]; /* Initial space for EQP output string */
+
+ pLoop = pLevel->pWLoop;
+ flags = pLoop->wsFlags;
+ if( (flags&WHERE_MULTI_OR) || (wctrlFlags&WHERE_ONETABLE_ONLY) ) return 0;
+
+ isSearch = (flags&(WHERE_BTM_LIMIT|WHERE_TOP_LIMIT))!=0
+ || ((flags&WHERE_VIRTUALTABLE)==0 && (pLoop->u.btree.nEq>0))
+ || (wctrlFlags&(WHERE_ORDERBY_MIN|WHERE_ORDERBY_MAX));
+
+ sqlite3StrAccumInit(&str, db, zBuf, sizeof(zBuf), SQLITE_MAX_LENGTH);
+ sqlite3StrAccumAppendAll(&str, isSearch ? "SEARCH" : "SCAN");
+ if( pItem->pSelect ){
+ sqlite3XPrintf(&str, 0, " SUBQUERY %d", pItem->iSelectId);
+ }else{
+ sqlite3XPrintf(&str, 0, " TABLE %s", pItem->zName);
+ }
+
+ if( pItem->zAlias ){
+ sqlite3XPrintf(&str, 0, " AS %s", pItem->zAlias);
+ }
+ if( (flags & (WHERE_IPK|WHERE_VIRTUALTABLE))==0 ){
+ const char *zFmt = 0;
+ Index *pIdx;
+
+ assert( pLoop->u.btree.pIndex!=0 );
+ pIdx = pLoop->u.btree.pIndex;
+ assert( !(flags&WHERE_AUTO_INDEX) || (flags&WHERE_IDX_ONLY) );
+ if( !HasRowid(pItem->pTab) && IsPrimaryKeyIndex(pIdx) ){
+ if( isSearch ){
+ zFmt = "PRIMARY KEY";
+ }
+ }else if( flags & WHERE_PARTIALIDX ){
+ zFmt = "AUTOMATIC PARTIAL COVERING INDEX";
+ }else if( flags & WHERE_AUTO_INDEX ){
+ zFmt = "AUTOMATIC COVERING INDEX";
+ }else if( flags & WHERE_IDX_ONLY ){
+ zFmt = "COVERING INDEX %s";
+ }else{
+ zFmt = "INDEX %s";
+ }
+ if( zFmt ){
+ sqlite3StrAccumAppend(&str, " USING ", 7);
+ sqlite3XPrintf(&str, 0, zFmt, pIdx->zName);
+ explainIndexRange(&str, pLoop);
+ }
+ }else if( (flags & WHERE_IPK)!=0 && (flags & WHERE_CONSTRAINT)!=0 ){
+ const char *zRangeOp;
+ if( flags&(WHERE_COLUMN_EQ|WHERE_COLUMN_IN) ){
+ zRangeOp = "=";
+ }else if( (flags&WHERE_BOTH_LIMIT)==WHERE_BOTH_LIMIT ){
+ zRangeOp = ">? AND rowid<";
+ }else if( flags&WHERE_BTM_LIMIT ){
+ zRangeOp = ">";
+ }else{
+ assert( flags&WHERE_TOP_LIMIT);
+ zRangeOp = "<";
+ }
+ sqlite3XPrintf(&str, 0, " USING INTEGER PRIMARY KEY (rowid%s?)",zRangeOp);
+ }
+#ifndef SQLITE_OMIT_VIRTUALTABLE
+ else if( (flags & WHERE_VIRTUALTABLE)!=0 ){
+ sqlite3XPrintf(&str, 0, " VIRTUAL TABLE INDEX %d:%s",
+ pLoop->u.vtab.idxNum, pLoop->u.vtab.idxStr);
+ }
+#endif
+#ifdef SQLITE_EXPLAIN_ESTIMATED_ROWS
+ if( pLoop->nOut>=10 ){
+ sqlite3XPrintf(&str, 0, " (~%llu rows)", sqlite3LogEstToInt(pLoop->nOut));
+ }else{
+ sqlite3StrAccumAppend(&str, " (~1 row)", 9);
+ }
+#endif
+ zMsg = sqlite3StrAccumFinish(&str);
+ ret = sqlite3VdbeAddOp4(v, OP_Explain, iId, iLevel, iFrom, zMsg,P4_DYNAMIC);
+ }
+ return ret;
}
+#endif /* SQLITE_OMIT_EXPLAIN */
+
+#ifdef SQLITE_ENABLE_STMT_SCANSTATUS
+/*
+** Configure the VM passed as the first argument with an
+** sqlite3_stmt_scanstatus() entry corresponding to the scan used to
+** implement level pLvl. Argument pSrclist is a pointer to the FROM
+** clause that the scan reads data from.
+**
+** If argument addrExplain is not 0, it must be the address of an
+** OP_Explain instruction that describes the same loop.
+*/
+SQLITE_PRIVATE void sqlite3WhereAddScanStatus(
+ Vdbe *v, /* Vdbe to add scanstatus entry to */
+ SrcList *pSrclist, /* FROM clause pLvl reads data from */
+ WhereLevel *pLvl, /* Level to add scanstatus() entry for */
+ int addrExplain /* Address of OP_Explain (or 0) */
+){
+ const char *zObj = 0;
+ WhereLoop *pLoop = pLvl->pWLoop;
+ if( (pLoop->wsFlags & WHERE_VIRTUALTABLE)==0 && pLoop->u.btree.pIndex!=0 ){
+ zObj = pLoop->u.btree.pIndex->zName;
+ }else{
+ zObj = pSrclist->a[pLvl->iFrom].zName;
+ }
+ sqlite3VdbeScanStatus(
+ v, addrExplain, pLvl->addrBody, pLvl->addrVisit, pLoop->nOut, zObj
+ );
+}
+#endif
-/* Forward reference */
-static void whereClauseClear(WhereClause*);
/*
-** Deallocate all memory associated with a WhereOrInfo object.
+** 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.
+**
+** 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.
+**
+** If all the children of a term are disabled, then that term is also
+** automatically disabled. In this way, terms get disabled if derived
+** virtual terms are tested first. For example:
+**
+** x GLOB 'abc*' AND x>='abc' AND x<'acd'
+** \___________/ \______/ \_____/
+** parent child1 child2
+**
+** Only the parent term was in the original WHERE clause. The child1
+** and child2 terms were added by the LIKE optimization. If both of
+** the virtual child terms are valid, then testing of the parent can be
+** skipped.
+**
+** Usually the parent term is marked as TERM_CODED. But if the parent
+** term was originally TERM_LIKE, then the parent gets TERM_LIKECOND instead.
+** The TERM_LIKECOND marking indicates that the term should be coded inside
+** a conditional such that is only evaluated on the second pass of a
+** LIKE-optimization loop, when scanning BLOBs instead of strings.
*/
-static void whereOrInfoDelete(sqlite3 *db, WhereOrInfo *p){
- whereClauseClear(&p->wc);
- sqlite3DbFree(db, p);
+static void disableTerm(WhereLevel *pLevel, WhereTerm *pTerm){
+ int nLoop = 0;
+ while( pTerm
+ && (pTerm->wtFlags & TERM_CODED)==0
+ && (pLevel->iLeftJoin==0 || ExprHasProperty(pTerm->pExpr, EP_FromJoin))
+ && (pLevel->notReady & pTerm->prereqAll)==0
+ ){
+ if( nLoop && (pTerm->wtFlags & TERM_LIKE)!=0 ){
+ pTerm->wtFlags |= TERM_LIKECOND;
+ }else{
+ pTerm->wtFlags |= TERM_CODED;
+ }
+ if( pTerm->iParent<0 ) break;
+ pTerm = &pTerm->pWC->a[pTerm->iParent];
+ pTerm->nChild--;
+ if( pTerm->nChild!=0 ) break;
+ nLoop++;
+ }
}
/*
-** Deallocate all memory associated with a WhereAndInfo object.
+** Code an OP_Affinity opcode to apply the column affinity string zAff
+** to the n registers starting at base.
+**
+** As an optimization, SQLITE_AFF_BLOB entries (which are no-ops) at the
+** beginning and end of zAff are ignored. If all entries in zAff are
+** SQLITE_AFF_BLOB, 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 whereAndInfoDelete(sqlite3 *db, WhereAndInfo *p){
- whereClauseClear(&p->wc);
- sqlite3DbFree(db, p);
+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_BLOB entries at the beginning
+ ** and end of the affinity string.
+ */
+ while( n>0 && zAff[0]==SQLITE_AFF_BLOB ){
+ n--;
+ base++;
+ zAff++;
+ }
+ while( n>1 && zAff[n-1]==SQLITE_AFF_BLOB ){
+ 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);
+ }
}
+
/*
-** Deallocate a WhereClause structure. The WhereClause structure
-** itself is not freed. This routine is the inverse of whereClauseInit().
+** 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 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);
+static int codeEqualityTerm(
+ Parse *pParse, /* The parsing context */
+ WhereTerm *pTerm, /* The term of the WHERE clause to be coded */
+ WhereLevel *pLevel, /* The level of the FROM clause we are working on */
+ int iEq, /* Index of the equality term within this level */
+ int bRev, /* True for reverse-order IN operations */
+ 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 || pX->op==TK_IS ){
+ 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;
+ WhereLoop *pLoop = pLevel->pWLoop;
+
+ if( (pLoop->wsFlags & WHERE_VIRTUALTABLE)==0
+ && pLoop->u.btree.pIndex!=0
+ && pLoop->u.btree.pIndex->aSortOrder[iEq]
+ ){
+ testcase( iEq==0 );
+ testcase( bRev );
+ bRev = !bRev;
}
- if( a->wtFlags & TERM_ORINFO ){
- whereOrInfoDelete(db, a->u.pOrInfo);
- }else if( a->wtFlags & TERM_ANDINFO ){
- whereAndInfoDelete(db, a->u.pAndInfo);
+ assert( pX->op==TK_IN );
+ iReg = iTarget;
+ eType = sqlite3FindInIndex(pParse, pX, IN_INDEX_LOOP, 0);
+ if( eType==IN_INDEX_INDEX_DESC ){
+ testcase( bRev );
+ bRev = !bRev;
}
+ iTab = pX->iTable;
+ sqlite3VdbeAddOp2(v, bRev ? OP_Last : OP_Rewind, iTab, 0);
+ VdbeCoverageIf(v, bRev);
+ VdbeCoverageIf(v, !bRev);
+ assert( (pLoop->wsFlags & WHERE_MULTI_OR)==0 );
+ pLoop->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);
+ }
+ pIn->eEndLoopOp = bRev ? OP_PrevIfOpen : OP_NextIfOpen;
+ sqlite3VdbeAddOp1(v, OP_IsNull, iReg); VdbeCoverage(v);
+ }else{
+ pLevel->u.in.nIn = 0;
+ }
+#endif
}
- if( pWC->a!=pWC->aStatic ){
- sqlite3DbFree(db, pWC->a);
+ disableTerm(pLevel, pTerm);
+ return iReg;
+}
+
+/*
+** Generate code that will evaluate all == and IN constraints for an
+** index scan.
+**
+** 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.
+**
+** The nExtraReg parameter is 0 or 1. It is 0 if all WHERE clause constraints
+** are == or IN and are covered by the nEq. nExtraReg is 1 if there is
+** an inequality constraint (such as the "c>=5 AND c<10" in the example) that
+** occurs after the nEq quality constraints.
+**
+** This routine allocates a range of nEq+nExtraReg memory cells and returns
+** the index of the first memory cell in that range. The code that
+** calls this routine will use that memory range to store keys for
+** start and termination conditions of the loop.
+** 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 BLOB or NONE affinity are set to
+** SQLITE_AFF_BLOB. 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 BLOB/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_BLOB.
+*/
+static int codeAllEqualityTerms(
+ Parse *pParse, /* Parsing context */
+ WhereLevel *pLevel, /* Which nested loop of the FROM we are coding */
+ int bRev, /* Reverse the order of IN operators */
+ int nExtraReg, /* Number of extra registers to allocate */
+ char **pzAff /* OUT: Set to point to affinity string */
+){
+ u16 nEq; /* The number of == or IN constraints to code */
+ u16 nSkip; /* Number of left-most columns to skip */
+ Vdbe *v = pParse->pVdbe; /* The vm under construction */
+ Index *pIdx; /* The index being used for this loop */
+ WhereTerm *pTerm; /* A single constraint term */
+ WhereLoop *pLoop; /* The WhereLoop object */
+ 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. */
+ pLoop = pLevel->pWLoop;
+ assert( (pLoop->wsFlags & WHERE_VIRTUALTABLE)==0 );
+ nEq = pLoop->u.btree.nEq;
+ nSkip = pLoop->nSkip;
+ pIdx = pLoop->u.btree.pIndex;
+ assert( pIdx!=0 );
+
+ /* Figure out how many memory cells we will need then allocate them.
+ */
+ regBase = pParse->nMem + 1;
+ nReg = pLoop->u.btree.nEq + nExtraReg;
+ pParse->nMem += nReg;
+
+ zAff = sqlite3DbStrDup(pParse->db,sqlite3IndexAffinityStr(pParse->db,pIdx));
+ if( !zAff ){
+ pParse->db->mallocFailed = 1;
+ }
+
+ if( nSkip ){
+ int iIdxCur = pLevel->iIdxCur;
+ sqlite3VdbeAddOp1(v, (bRev?OP_Last:OP_Rewind), iIdxCur);
+ VdbeCoverageIf(v, bRev==0);
+ VdbeCoverageIf(v, bRev!=0);
+ VdbeComment((v, "begin skip-scan on %s", pIdx->zName));
+ j = sqlite3VdbeAddOp0(v, OP_Goto);
+ pLevel->addrSkip = sqlite3VdbeAddOp4Int(v, (bRev?OP_SeekLT:OP_SeekGT),
+ iIdxCur, 0, regBase, nSkip);
+ VdbeCoverageIf(v, bRev==0);
+ VdbeCoverageIf(v, bRev!=0);
+ sqlite3VdbeJumpHere(v, j);
+ for(j=0; j<nSkip; j++){
+ sqlite3VdbeAddOp3(v, OP_Column, iIdxCur, j, regBase+j);
+ testcase( pIdx->aiColumn[j]==XN_EXPR );
+ VdbeComment((v, "%s", explainIndexColumnName(pIdx, j)));
+ }
+ }
+
+ /* Evaluate the equality constraints
+ */
+ assert( zAff==0 || (int)strlen(zAff)>=nEq );
+ for(j=nSkip; j<nEq; j++){
+ int r1;
+ pTerm = pLoop->aLTerm[j];
+ assert( pTerm!=0 );
+ /* The following testcase is 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 );
+ r1 = codeEqualityTerm(pParse, pTerm, pLevel, j, bRev, 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;
+ if( (pTerm->wtFlags & TERM_IS)==0 && sqlite3ExprCanBeNull(pRight) ){
+ sqlite3VdbeAddOp2(v, OP_IsNull, regBase+j, pLevel->addrBrk);
+ VdbeCoverage(v);
+ }
+ if( zAff ){
+ if( sqlite3CompareAffinity(pRight, zAff[j])==SQLITE_AFF_BLOB ){
+ zAff[j] = SQLITE_AFF_BLOB;
+ }
+ if( sqlite3ExprNeedsNoAffinityChange(pRight, zAff[j]) ){
+ zAff[j] = SQLITE_AFF_BLOB;
+ }
+ }
+ }
+ }
+ *pzAff = zAff;
+ return regBase;
+}
+
+#ifndef SQLITE_LIKE_DOESNT_MATCH_BLOBS
+/*
+** If the most recently coded instruction is a constant range contraint
+** that originated from the LIKE optimization, then change the P3 to be
+** pLoop->iLikeRepCntr and set P5.
+**
+** The LIKE optimization trys to evaluate "x LIKE 'abc%'" as a range
+** expression: "x>='ABC' AND x<'abd'". But this requires that the range
+** scan loop run twice, once for strings and a second time for BLOBs.
+** The OP_String opcodes on the second pass convert the upper and lower
+** bound string contants to blobs. This routine makes the necessary changes
+** to the OP_String opcodes for that to happen.
+**
+** Except, of course, if SQLITE_LIKE_DOESNT_MATCH_BLOBS is defined, then
+** only the one pass through the string space is required, so this routine
+** becomes a no-op.
+*/
+static void whereLikeOptimizationStringFixup(
+ Vdbe *v, /* prepared statement under construction */
+ WhereLevel *pLevel, /* The loop that contains the LIKE operator */
+ WhereTerm *pTerm /* The upper or lower bound just coded */
+){
+ if( pTerm->wtFlags & TERM_LIKEOPT ){
+ VdbeOp *pOp;
+ assert( pLevel->iLikeRepCntr>0 );
+ pOp = sqlite3VdbeGetOp(v, -1);
+ assert( pOp!=0 );
+ assert( pOp->opcode==OP_String8
+ || pTerm->pWC->pWInfo->pParse->db->mallocFailed );
+ pOp->p3 = pLevel->iLikeRepCntr;
+ pOp->p5 = 1;
+ }
+}
+#else
+# define whereLikeOptimizationStringFixup(A,B,C)
+#endif
+
+#ifdef SQLITE_ENABLE_CURSOR_HINTS
+/*
+** Information is passed from codeCursorHint() down to individual nodes of
+** the expression tree (by sqlite3WalkExpr()) using an instance of this
+** structure.
+*/
+struct CCurHint {
+ int iTabCur; /* Cursor for the main table */
+ int iIdxCur; /* Cursor for the index, if pIdx!=0. Unused otherwise */
+ Index *pIdx; /* The index used to access the table */
+};
+
+/*
+** This function is called for every node of an expression that is a candidate
+** for a cursor hint on an index cursor. For TK_COLUMN nodes that reference
+** the table CCurHint.iTabCur, verify that the same column can be
+** accessed through the index. If it cannot, then set pWalker->eCode to 1.
+*/
+static int codeCursorHintCheckExpr(Walker *pWalker, Expr *pExpr){
+ struct CCurHint *pHint = pWalker->u.pCCurHint;
+ assert( pHint->pIdx!=0 );
+ if( pExpr->op==TK_COLUMN
+ && pExpr->iTable==pHint->iTabCur
+ && sqlite3ColumnOfIndex(pHint->pIdx, pExpr->iColumn)<0
+ ){
+ pWalker->eCode = 1;
+ }
+ return WRC_Continue;
+}
+
+
+/*
+** This function is called on every node of an expression tree used as an
+** argument to the OP_CursorHint instruction. If the node is a TK_COLUMN
+** that accesses any table other than the one identified by
+** CCurHint.iTabCur, then do the following:
+**
+** 1) allocate a register and code an OP_Column instruction to read
+** the specified column into the new register, and
+**
+** 2) transform the expression node to a TK_REGISTER node that reads
+** from the newly populated register.
+**
+** Also, if the node is a TK_COLUMN that does access the table idenified
+** by pCCurHint.iTabCur, and an index is being used (which we will
+** know because CCurHint.pIdx!=0) then transform the TK_COLUMN into
+** an access of the index rather than the original table.
+*/
+static int codeCursorHintFixExpr(Walker *pWalker, Expr *pExpr){
+ int rc = WRC_Continue;
+ struct CCurHint *pHint = pWalker->u.pCCurHint;
+ if( pExpr->op==TK_COLUMN ){
+ if( pExpr->iTable!=pHint->iTabCur ){
+ Vdbe *v = pWalker->pParse->pVdbe;
+ int reg = ++pWalker->pParse->nMem; /* Register for column value */
+ sqlite3ExprCodeGetColumnOfTable(
+ v, pExpr->pTab, pExpr->iTable, pExpr->iColumn, reg
+ );
+ pExpr->op = TK_REGISTER;
+ pExpr->iTable = reg;
+ }else if( pHint->pIdx!=0 ){
+ pExpr->iTable = pHint->iIdxCur;
+ pExpr->iColumn = sqlite3ColumnOfIndex(pHint->pIdx, pExpr->iColumn);
+ assert( pExpr->iColumn>=0 );
+ }
+ }else if( pExpr->op==TK_AGG_FUNCTION ){
+ /* An aggregate function in the WHERE clause of a query means this must
+ ** be a correlated sub-query, and expression pExpr is an aggregate from
+ ** the parent context. Do not walk the function arguments in this case.
+ **
+ ** todo: It should be possible to replace this node with a TK_REGISTER
+ ** expression, as the result of the expression must be stored in a
+ ** register at this point. The same holds for TK_AGG_COLUMN nodes. */
+ rc = WRC_Prune;
+ }
+ return rc;
+}
+
+/*
+** Insert an OP_CursorHint instruction if it is appropriate to do so.
+*/
+static void codeCursorHint(
+ WhereInfo *pWInfo, /* The where clause */
+ WhereLevel *pLevel, /* Which loop to provide hints for */
+ WhereTerm *pEndRange /* Hint this end-of-scan boundary term if not NULL */
+){
+ Parse *pParse = pWInfo->pParse;
+ sqlite3 *db = pParse->db;
+ Vdbe *v = pParse->pVdbe;
+ Expr *pExpr = 0;
+ WhereLoop *pLoop = pLevel->pWLoop;
+ int iCur;
+ WhereClause *pWC;
+ WhereTerm *pTerm;
+ int i, j;
+ struct CCurHint sHint;
+ Walker sWalker;
+
+ if( OptimizationDisabled(db, SQLITE_CursorHints) ) return;
+ iCur = pLevel->iTabCur;
+ assert( iCur==pWInfo->pTabList->a[pLevel->iFrom].iCursor );
+ sHint.iTabCur = iCur;
+ sHint.iIdxCur = pLevel->iIdxCur;
+ sHint.pIdx = pLoop->u.btree.pIndex;
+ memset(&sWalker, 0, sizeof(sWalker));
+ sWalker.pParse = pParse;
+ sWalker.u.pCCurHint = &sHint;
+ pWC = &pWInfo->sWC;
+ for(i=0; i<pWC->nTerm; i++){
+ pTerm = &pWC->a[i];
+ if( pTerm->wtFlags & (TERM_VIRTUAL|TERM_CODED) ) continue;
+ if( pTerm->prereqAll & pLevel->notReady ) continue;
+ if( ExprHasProperty(pTerm->pExpr, EP_FromJoin) ) continue;
+
+ /* All terms in pWLoop->aLTerm[] except pEndRange are used to initialize
+ ** the cursor. These terms are not needed as hints for a pure range
+ ** scan (that has no == terms) so omit them. */
+ if( pLoop->u.btree.nEq==0 && pTerm!=pEndRange ){
+ for(j=0; j<pLoop->nLTerm && pLoop->aLTerm[j]!=pTerm; j++){}
+ if( j<pLoop->nLTerm ) continue;
+ }
+
+ /* No subqueries or non-deterministic functions allowed */
+ if( sqlite3ExprContainsSubquery(pTerm->pExpr) ) continue;
+
+ /* For an index scan, make sure referenced columns are actually in
+ ** the index. */
+ if( sHint.pIdx!=0 ){
+ sWalker.eCode = 0;
+ sWalker.xExprCallback = codeCursorHintCheckExpr;
+ sqlite3WalkExpr(&sWalker, pTerm->pExpr);
+ if( sWalker.eCode ) continue;
+ }
+
+ /* If we survive all prior tests, that means this term is worth hinting */
+ pExpr = sqlite3ExprAnd(db, pExpr, sqlite3ExprDup(db, pTerm->pExpr, 0));
+ }
+ if( pExpr!=0 ){
+ sWalker.xExprCallback = codeCursorHintFixExpr;
+ sqlite3WalkExpr(&sWalker, pExpr);
+ sqlite3VdbeAddOp4(v, OP_CursorHint,
+ (sHint.pIdx ? sHint.iIdxCur : sHint.iTabCur), 0, 0,
+ (const char*)pExpr, P4_EXPR);
+ }
+}
+#else
+# define codeCursorHint(A,B,C) /* No-op */
+#endif /* SQLITE_ENABLE_CURSOR_HINTS */
+
+/*
+** Generate code for the start of the iLevel-th loop in the WHERE clause
+** implementation described by pWInfo.
+*/
+SQLITE_PRIVATE Bitmask sqlite3WhereCodeOneLoopStart(
+ WhereInfo *pWInfo, /* Complete information about the WHERE clause */
+ int iLevel, /* Which level of pWInfo->a[] should be coded */
+ 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 */
+ WhereLoop *pLoop; /* The WhereLoop object being coded */
+ WhereClause *pWC; /* Decomposition of the entire WHERE clause */
+ WhereTerm *pTerm; /* A WHERE clause term */
+ Parse *pParse; /* Parsing context */
+ sqlite3 *db; /* Database connection */
+ 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->sWC;
+ db = pParse->db;
+ pLevel = &pWInfo->a[iLevel];
+ pLoop = pLevel->pWLoop;
+ pTabItem = &pWInfo->pTabList->a[pLevel->iFrom];
+ iCur = pTabItem->iCursor;
+ pLevel->notReady = notReady & ~sqlite3WhereGetMask(&pWInfo->sMaskSet, iCur);
+ bRev = (pWInfo->revMask>>iLevel)&1;
+ omitTable = (pLoop->wsFlags & WHERE_IDX_ONLY)!=0
+ && (pWInfo->wctrlFlags & WHERE_FORCE_TABLE)==0;
+ VdbeModuleComment((v, "Begin WHERE-loop%d: %s",iLevel,pTabItem->pTab->zName));
+
+ /* 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].fg.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->fg.viaCoroutine ){
+ int regYield = pTabItem->regReturn;
+ sqlite3VdbeAddOp3(v, OP_InitCoroutine, regYield, 0, pTabItem->addrFillSub);
+ pLevel->p2 = sqlite3VdbeAddOp2(v, OP_Yield, regYield, addrBrk);
+ VdbeCoverage(v);
+ VdbeComment((v, "next row of \"%s\"", pTabItem->pTab->zName));
+ pLevel->op = OP_Goto;
+ }else
+
+#ifndef SQLITE_OMIT_VIRTUALTABLE
+ if( (pLoop->wsFlags & WHERE_VIRTUALTABLE)!=0 ){
+ /* Case 1: The table is a virtual-table. Use the VFilter and VNext
+ ** to access the data.
+ */
+ int iReg; /* P3 Value for OP_VFilter */
+ int addrNotFound;
+ int nConstraint = pLoop->nLTerm;
+
+ sqlite3ExprCachePush(pParse);
+ iReg = sqlite3GetTempRange(pParse, nConstraint+2);
+ addrNotFound = pLevel->addrBrk;
+ for(j=0; j<nConstraint; j++){
+ int iTarget = iReg+j+2;
+ pTerm = pLoop->aLTerm[j];
+ if( pTerm==0 ) continue;
+ if( pTerm->eOperator & WO_IN ){
+ codeEqualityTerm(pParse, pTerm, pLevel, j, bRev, iTarget);
+ addrNotFound = pLevel->addrNxt;
+ }else{
+ sqlite3ExprCode(pParse, pTerm->pExpr->pRight, iTarget);
+ }
+ }
+ sqlite3VdbeAddOp2(v, OP_Integer, pLoop->u.vtab.idxNum, iReg);
+ sqlite3VdbeAddOp2(v, OP_Integer, nConstraint, iReg+1);
+ sqlite3VdbeAddOp4(v, OP_VFilter, iCur, addrNotFound, iReg,
+ pLoop->u.vtab.idxStr,
+ pLoop->u.vtab.needFree ? P4_MPRINTF : P4_STATIC);
+ VdbeCoverage(v);
+ pLoop->u.vtab.needFree = 0;
+ for(j=0; j<nConstraint && j<16; j++){
+ if( (pLoop->u.vtab.omitMask>>j)&1 ){
+ disableTerm(pLevel, pLoop->aLTerm[j]);
+ }
+ }
+ pLevel->p1 = iCur;
+ pLevel->op = pWInfo->eOnePass ? OP_Noop : OP_VNext;
+ pLevel->p2 = sqlite3VdbeCurrentAddr(v);
+ sqlite3ReleaseTempRange(pParse, iReg, nConstraint+2);
+ sqlite3ExprCachePop(pParse);
+ }else
+#endif /* SQLITE_OMIT_VIRTUALTABLE */
+
+ if( (pLoop->wsFlags & WHERE_IPK)!=0
+ && (pLoop->wsFlags & (WHERE_COLUMN_IN|WHERE_COLUMN_EQ))!=0
+ ){
+ /* Case 2: 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.
+ */
+ assert( pLoop->u.btree.nEq==1 );
+ pTerm = pLoop->aLTerm[0];
+ assert( pTerm!=0 );
+ assert( pTerm->pExpr!=0 );
+ assert( omitTable==0 );
+ testcase( pTerm->wtFlags & TERM_VIRTUAL );
+ iReleaseReg = ++pParse->nMem;
+ iRowidReg = codeEqualityTerm(pParse, pTerm, pLevel, 0, bRev, iReleaseReg);
+ if( iRowidReg!=iReleaseReg ) sqlite3ReleaseTempReg(pParse, iReleaseReg);
+ addrNxt = pLevel->addrNxt;
+ sqlite3VdbeAddOp2(v, OP_MustBeInt, iRowidReg, addrNxt); VdbeCoverage(v);
+ sqlite3VdbeAddOp3(v, OP_NotExists, iCur, addrNxt, iRowidReg);
+ VdbeCoverage(v);
+ sqlite3ExprCacheAffinityChange(pParse, iRowidReg, 1);
+ sqlite3ExprCacheStore(pParse, iCur, -1, iRowidReg);
+ VdbeComment((v, "pk"));
+ pLevel->op = OP_Noop;
+ }else if( (pLoop->wsFlags & WHERE_IPK)!=0
+ && (pLoop->wsFlags & WHERE_COLUMN_RANGE)!=0
+ ){
+ /* Case 3: We have an inequality comparison against the ROWID field.
+ */
+ int testOp = OP_Noop;
+ int start;
+ int memEndValue = 0;
+ WhereTerm *pStart, *pEnd;
+
+ assert( omitTable==0 );
+ j = 0;
+ pStart = pEnd = 0;
+ if( pLoop->wsFlags & WHERE_BTM_LIMIT ) pStart = pLoop->aLTerm[j++];
+ if( pLoop->wsFlags & WHERE_TOP_LIMIT ) pEnd = pLoop->aLTerm[j++];
+ assert( pStart!=0 || pEnd!=0 );
+ if( bRev ){
+ pTerm = pStart;
+ pStart = pEnd;
+ pEnd = pTerm;
+ }
+ codeCursorHint(pWInfo, pLevel, pEnd);
+ 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. */
+
+ assert( (pStart->wtFlags & TERM_VNULL)==0 );
+ testcase( pStart->wtFlags & TERM_VIRTUAL );
+ pX = pStart->pExpr;
+ assert( pX!=0 );
+ testcase( pStart->leftCursor!=iCur ); /* transitive constraints */
+ r1 = sqlite3ExprCodeTemp(pParse, pX->pRight, &rTemp);
+ sqlite3VdbeAddOp3(v, aMoveOp[pX->op-TK_GT], iCur, addrBrk, r1);
+ VdbeComment((v, "pk"));
+ VdbeCoverageIf(v, pX->op==TK_GT);
+ VdbeCoverageIf(v, pX->op==TK_LE);
+ VdbeCoverageIf(v, pX->op==TK_LT);
+ VdbeCoverageIf(v, pX->op==TK_GE);
+ sqlite3ExprCacheAffinityChange(pParse, r1, 1);
+ sqlite3ReleaseTempReg(pParse, rTemp);
+ disableTerm(pLevel, pStart);
+ }else{
+ sqlite3VdbeAddOp2(v, bRev ? OP_Last : OP_Rewind, iCur, addrBrk);
+ VdbeCoverageIf(v, bRev==0);
+ VdbeCoverageIf(v, bRev!=0);
+ }
+ if( pEnd ){
+ Expr *pX;
+ pX = pEnd->pExpr;
+ assert( pX!=0 );
+ assert( (pEnd->wtFlags & TERM_VNULL)==0 );
+ testcase( pEnd->leftCursor!=iCur ); /* Transitive constraints */
+ testcase( pEnd->wtFlags & TERM_VIRTUAL );
+ 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;
+ assert( pLevel->p5==0 );
+ if( testOp!=OP_Noop ){
+ iRowidReg = ++pParse->nMem;
+ sqlite3VdbeAddOp2(v, OP_Rowid, iCur, iRowidReg);
+ sqlite3ExprCacheStore(pParse, iCur, -1, iRowidReg);
+ sqlite3VdbeAddOp3(v, testOp, memEndValue, addrBrk, iRowidReg);
+ VdbeCoverageIf(v, testOp==OP_Le);
+ VdbeCoverageIf(v, testOp==OP_Lt);
+ VdbeCoverageIf(v, testOp==OP_Ge);
+ VdbeCoverageIf(v, testOp==OP_Gt);
+ sqlite3VdbeChangeP5(v, SQLITE_AFF_NUMERIC | SQLITE_JUMPIFNULL);
+ }
+ }else if( pLoop->wsFlags & WHERE_INDEXED ){
+ /* Case 4: 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_IdxGE, /* 0: (end_constraints && !bRev && !endEq) */
+ OP_IdxGT, /* 1: (end_constraints && !bRev && endEq) */
+ OP_IdxLE, /* 2: (end_constraints && bRev && !endEq) */
+ OP_IdxLT, /* 3: (end_constraints && bRev && endEq) */
+ };
+ u16 nEq = pLoop->u.btree.nEq; /* Number of == or IN terms */
+ int regBase; /* Base register holding constraint values */
+ 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 cEndAff = 0; /* Affinity for end of range constraint */
+ u8 bSeekPastNull = 0; /* True to seek past initial nulls */
+ u8 bStopAtNull = 0; /* Add condition to terminate at NULLs */
+
+ pIdx = pLoop->u.btree.pIndex;
+ iIdxCur = pLevel->iIdxCur;
+ assert( nEq>=pLoop->nSkip );
+
+ /* 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.
+ */
+ assert( pWInfo->pOrderBy==0
+ || pWInfo->pOrderBy->nExpr==1
+ || (pWInfo->wctrlFlags&WHERE_ORDERBY_MIN)==0 );
+ if( (pWInfo->wctrlFlags&WHERE_ORDERBY_MIN)!=0
+ && pWInfo->nOBSat>0
+ && (pIdx->nKeyCol>nEq)
+ ){
+ assert( pLoop->nSkip==0 );
+ bSeekPastNull = 1;
+ nExtraReg = 1;
+ }
+
+ /* Find any inequality constraint terms for the start and end
+ ** of the range.
+ */
+ j = nEq;
+ if( pLoop->wsFlags & WHERE_BTM_LIMIT ){
+ pRangeStart = pLoop->aLTerm[j++];
+ nExtraReg = 1;
+ /* Like optimization range constraints always occur in pairs */
+ assert( (pRangeStart->wtFlags & TERM_LIKEOPT)==0 ||
+ (pLoop->wsFlags & WHERE_TOP_LIMIT)!=0 );
+ }
+ if( pLoop->wsFlags & WHERE_TOP_LIMIT ){
+ pRangeEnd = pLoop->aLTerm[j++];
+ nExtraReg = 1;
+#ifndef SQLITE_LIKE_DOESNT_MATCH_BLOBS
+ if( (pRangeEnd->wtFlags & TERM_LIKEOPT)!=0 ){
+ assert( pRangeStart!=0 ); /* LIKE opt constraints */
+ assert( pRangeStart->wtFlags & TERM_LIKEOPT ); /* occur in pairs */
+ pLevel->iLikeRepCntr = ++pParse->nMem;
+ testcase( bRev );
+ testcase( pIdx->aSortOrder[nEq]==SQLITE_SO_DESC );
+ sqlite3VdbeAddOp2(v, OP_Integer,
+ bRev ^ (pIdx->aSortOrder[nEq]==SQLITE_SO_DESC),
+ pLevel->iLikeRepCntr);
+ VdbeComment((v, "LIKE loop counter"));
+ pLevel->addrLikeRep = sqlite3VdbeCurrentAddr(v);
+ }
+#endif
+ if( pRangeStart==0
+ && (j = pIdx->aiColumn[nEq])>=0
+ && pIdx->pTable->aCol[j].notNull==0
+ ){
+ bSeekPastNull = 1;
+ }
+ }
+ assert( pRangeEnd==0 || (pRangeEnd->wtFlags & TERM_VNULL)==0 );
+
+ /* 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->nKeyCol && bRev==(pIdx->aSortOrder[nEq]==SQLITE_SO_ASC))
+ || (bRev && pIdx->nKeyCol==nEq)
+ ){
+ SWAP(WhereTerm *, pRangeEnd, pRangeStart);
+ SWAP(u8, bSeekPastNull, bStopAtNull);
+ }
+
+ /* 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.
+ */
+ codeCursorHint(pWInfo, pLevel, pRangeEnd);
+ regBase = codeAllEqualityTerms(pParse,pLevel,bRev,nExtraReg,&zStartAff);
+ assert( zStartAff==0 || sqlite3Strlen30(zStartAff)>=nEq );
+ if( zStartAff ) cEndAff = zStartAff[nEq];
+ addrNxt = pLevel->addrNxt;
+
+ testcase( pRangeStart && (pRangeStart->eOperator & WO_LE)!=0 );
+ testcase( pRangeStart && (pRangeStart->eOperator & WO_GE)!=0 );
+ testcase( pRangeEnd && (pRangeEnd->eOperator & WO_LE)!=0 );
+ testcase( pRangeEnd && (pRangeEnd->eOperator & WO_GE)!=0 );
+ 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);
+ whereLikeOptimizationStringFixup(v, pLevel, pRangeStart);
+ if( (pRangeStart->wtFlags & TERM_VNULL)==0
+ && sqlite3ExprCanBeNull(pRight)
+ ){
+ sqlite3VdbeAddOp2(v, OP_IsNull, regBase+nEq, addrNxt);
+ VdbeCoverage(v);
+ }
+ if( zStartAff ){
+ if( sqlite3CompareAffinity(pRight, zStartAff[nEq])==SQLITE_AFF_BLOB){
+ /* Since the comparison is to be performed with no conversions
+ ** applied to the operands, set the affinity to apply to pRight to
+ ** SQLITE_AFF_BLOB. */
+ zStartAff[nEq] = SQLITE_AFF_BLOB;
+ }
+ if( sqlite3ExprNeedsNoAffinityChange(pRight, zStartAff[nEq]) ){
+ zStartAff[nEq] = SQLITE_AFF_BLOB;
+ }
+ }
+ nConstraint++;
+ testcase( pRangeStart->wtFlags & TERM_VIRTUAL );
+ }else if( bSeekPastNull ){
+ sqlite3VdbeAddOp2(v, OP_Null, 0, regBase+nEq);
+ nConstraint++;
+ startEq = 0;
+ start_constraints = 1;
+ }
+ codeApplyAffinity(pParse, regBase, nConstraint - bSeekPastNull, zStartAff);
+ op = aStartOp[(start_constraints<<2) + (startEq<<1) + bRev];
+ assert( op!=0 );
+ sqlite3VdbeAddOp4Int(v, op, iIdxCur, addrNxt, regBase, nConstraint);
+ VdbeCoverage(v);
+ VdbeCoverageIf(v, op==OP_Rewind); testcase( op==OP_Rewind );
+ VdbeCoverageIf(v, op==OP_Last); testcase( op==OP_Last );
+ VdbeCoverageIf(v, op==OP_SeekGT); testcase( op==OP_SeekGT );
+ VdbeCoverageIf(v, op==OP_SeekGE); testcase( op==OP_SeekGE );
+ VdbeCoverageIf(v, op==OP_SeekLE); testcase( op==OP_SeekLE );
+ VdbeCoverageIf(v, op==OP_SeekLT); testcase( op==OP_SeekLT );
+
+ /* 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);
+ whereLikeOptimizationStringFixup(v, pLevel, pRangeEnd);
+ if( (pRangeEnd->wtFlags & TERM_VNULL)==0
+ && sqlite3ExprCanBeNull(pRight)
+ ){
+ sqlite3VdbeAddOp2(v, OP_IsNull, regBase+nEq, addrNxt);
+ VdbeCoverage(v);
+ }
+ if( sqlite3CompareAffinity(pRight, cEndAff)!=SQLITE_AFF_BLOB
+ && !sqlite3ExprNeedsNoAffinityChange(pRight, cEndAff)
+ ){
+ codeApplyAffinity(pParse, regBase+nEq, 1, &cEndAff);
+ }
+ nConstraint++;
+ testcase( pRangeEnd->wtFlags & TERM_VIRTUAL );
+ }else if( bStopAtNull ){
+ sqlite3VdbeAddOp2(v, OP_Null, 0, regBase+nEq);
+ endEq = 0;
+ nConstraint++;
+ }
+ sqlite3DbFree(db, zStartAff);
+
+ /* Top of the loop body */
+ pLevel->p2 = sqlite3VdbeCurrentAddr(v);
+
+ /* Check if the index cursor is past the end of the range. */
+ if( nConstraint ){
+ op = aEndOp[bRev*2 + endEq];
+ sqlite3VdbeAddOp4Int(v, op, iIdxCur, addrNxt, regBase, nConstraint);
+ testcase( op==OP_IdxGT ); VdbeCoverageIf(v, op==OP_IdxGT );
+ testcase( op==OP_IdxGE ); VdbeCoverageIf(v, op==OP_IdxGE );
+ testcase( op==OP_IdxLT ); VdbeCoverageIf(v, op==OP_IdxLT );
+ testcase( op==OP_IdxLE ); VdbeCoverageIf(v, op==OP_IdxLE );
+ }
+
+ /* Seek the table cursor, if required */
+ disableTerm(pLevel, pRangeStart);
+ disableTerm(pLevel, pRangeEnd);
+ if( omitTable ){
+ /* pIdx is a covering index. No need to access the main table. */
+ }else if( HasRowid(pIdx->pTable) ){
+ iRowidReg = ++pParse->nMem;
+ sqlite3VdbeAddOp2(v, OP_IdxRowid, iIdxCur, iRowidReg);
+ sqlite3ExprCacheStore(pParse, iCur, -1, iRowidReg);
+ if( pWInfo->eOnePass!=ONEPASS_OFF ){
+ sqlite3VdbeAddOp3(v, OP_NotExists, iCur, 0, iRowidReg);
+ VdbeCoverage(v);
+ }else{
+ sqlite3VdbeAddOp2(v, OP_Seek, iCur, iRowidReg); /* Deferred seek */
+ }
+ }else if( iCur!=iIdxCur ){
+ Index *pPk = sqlite3PrimaryKeyIndex(pIdx->pTable);
+ iRowidReg = sqlite3GetTempRange(pParse, pPk->nKeyCol);
+ for(j=0; j<pPk->nKeyCol; j++){
+ k = sqlite3ColumnOfIndex(pIdx, pPk->aiColumn[j]);
+ sqlite3VdbeAddOp3(v, OP_Column, iIdxCur, k, iRowidReg+j);
+ }
+ sqlite3VdbeAddOp4Int(v, OP_NotFound, iCur, addrCont,
+ iRowidReg, pPk->nKeyCol); VdbeCoverage(v);
+ }
+
+ /* Record the instruction used to terminate the loop. Disable
+ ** WHERE clause terms made redundant by the index range scan.
+ */
+ if( pLoop->wsFlags & WHERE_ONEROW ){
+ pLevel->op = OP_Noop;
+ }else if( bRev ){
+ pLevel->op = OP_Prev;
+ }else{
+ pLevel->op = OP_Next;
+ }
+ pLevel->p1 = iIdxCur;
+ pLevel->p3 = (pLoop->wsFlags&WHERE_UNQ_WANTED)!=0 ? 1:0;
+ if( (pLoop->wsFlags & WHERE_CONSTRAINT)==0 ){
+ pLevel->p5 = SQLITE_STMTSTATUS_FULLSCAN_STEP;
+ }else{
+ assert( pLevel->p5==0 );
+ }
+ }else
+
+#ifndef SQLITE_OMIT_OR_OPTIMIZATION
+ if( pLoop->wsFlags & WHERE_MULTI_OR ){
+ /* Case 5: 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>
+ **
+ ** Added 2014-05-26: If the table is a WITHOUT ROWID table, then
+ ** use an ephemeral index instead of a RowSet to record the primary
+ ** keys of the rows we have already seen.
+ **
+ */
+ 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 */
+ u16 wctrlFlags; /* Flags for sub-WHERE clause */
+ Expr *pAndExpr = 0; /* An ".. AND (...)" expression */
+ Table *pTab = pTabItem->pTab;
+
+ pTerm = pLoop->aLTerm[0];
+ 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(db,
+ sizeof(*pOrTab)+ nNotReady*sizeof(pOrTab->a[0]));
+ if( pOrTab==0 ) return notReady;
+ pOrTab->nAlloc = (u8)(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. Or, create an ephemeral index
+ ** capable of holding primary keys in the case of a WITHOUT ROWID.
+ **
+ ** 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( (pWInfo->wctrlFlags & WHERE_DUPLICATES_OK)==0 ){
+ if( HasRowid(pTab) ){
+ regRowset = ++pParse->nMem;
+ sqlite3VdbeAddOp2(v, OP_Null, 0, regRowset);
+ }else{
+ Index *pPk = sqlite3PrimaryKeyIndex(pTab);
+ regRowset = pParse->nTab++;
+ sqlite3VdbeAddOp2(v, OP_OpenEphemeral, regRowset, pPk->nKeyCol);
+ sqlite3VdbeSetP4KeyInfo(pParse, pPk);
+ }
+ regRowid = ++pParse->nMem;
+ }
+ 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.
+ **
+ ** This optimization also only applies if the (x1 OR x2 OR ...) term
+ ** is not contained in the ON clause of a LEFT JOIN.
+ ** See ticket http://www.sqlite.org/src/info/f2369304e4
+ */
+ if( pWC->nTerm>1 ){
+ int iTerm;
+ for(iTerm=0; iTerm<pWC->nTerm; iTerm++){
+ Expr *pExpr = pWC->a[iTerm].pExpr;
+ if( &pWC->a[iTerm] == pTerm ) continue;
+ if( ExprHasProperty(pExpr, EP_FromJoin) ) continue;
+ if( (pWC->a[iTerm].wtFlags & TERM_VIRTUAL)!=0 ) continue;
+ if( (pWC->a[iTerm].eOperator & WO_ALL)==0 ) continue;
+ testcase( pWC->a[iTerm].wtFlags & TERM_ORINFO );
+ pExpr = sqlite3ExprDup(db, pExpr, 0);
+ pAndExpr = sqlite3ExprAnd(db, pAndExpr, pExpr);
+ }
+ if( pAndExpr ){
+ pAndExpr = sqlite3PExpr(pParse, TK_AND|TKFLG_DONTFOLD, 0, pAndExpr, 0);
+ }
+ }
+
+ /* Run a separate WHERE clause for each term of the OR clause. After
+ ** eliminating duplicates from other WHERE clauses, the action for each
+ ** sub-WHERE clause is to to invoke the main loop body as a subroutine.
+ */
+ wctrlFlags = WHERE_OMIT_OPEN_CLOSE
+ | WHERE_FORCE_TABLE
+ | WHERE_ONETABLE_ONLY
+ | WHERE_NO_AUTOINDEX;
+ for(ii=0; ii<pOrWc->nTerm; ii++){
+ WhereTerm *pOrTerm = &pOrWc->a[ii];
+ if( pOrTerm->leftCursor==iCur || (pOrTerm->eOperator & WO_AND)!=0 ){
+ WhereInfo *pSubWInfo; /* Info for single OR-term scan */
+ Expr *pOrExpr = pOrTerm->pExpr; /* Current OR clause term */
+ int jmp1 = 0; /* Address of jump operation */
+ if( pAndExpr && !ExprHasProperty(pOrExpr, EP_FromJoin) ){
+ pAndExpr->pLeft = pOrExpr;
+ pOrExpr = pAndExpr;
+ }
+ /* Loop through table entries that match term pOrTerm. */
+ WHERETRACE(0xffff, ("Subplan for OR-clause:\n"));
+ pSubWInfo = sqlite3WhereBegin(pParse, pOrTab, pOrExpr, 0, 0,
+ wctrlFlags, iCovCur);
+ assert( pSubWInfo || pParse->nErr || db->mallocFailed );
+ if( pSubWInfo ){
+ WhereLoop *pSubLoop;
+ int addrExplain = sqlite3WhereExplainOneScan(
+ pParse, pOrTab, &pSubWInfo->a[0], iLevel, pLevel->iFrom, 0
+ );
+ sqlite3WhereAddScanStatus(v, pOrTab, &pSubWInfo->a[0], addrExplain);
+
+ /* This is the sub-WHERE clause body. First skip over
+ ** duplicate rows from prior sub-WHERE clauses, and record the
+ ** rowid (or PRIMARY KEY) for the current row so that the same
+ ** row will be skipped in subsequent sub-WHERE clauses.
+ */
+ if( (pWInfo->wctrlFlags & WHERE_DUPLICATES_OK)==0 ){
+ int r;
+ int iSet = ((ii==pOrWc->nTerm-1)?-1:ii);
+ if( HasRowid(pTab) ){
+ r = sqlite3ExprCodeGetColumn(pParse, pTab, -1, iCur, regRowid, 0);
+ jmp1 = sqlite3VdbeAddOp4Int(v, OP_RowSetTest, regRowset, 0,
+ r,iSet);
+ VdbeCoverage(v);
+ }else{
+ Index *pPk = sqlite3PrimaryKeyIndex(pTab);
+ int nPk = pPk->nKeyCol;
+ int iPk;
+
+ /* Read the PK into an array of temp registers. */
+ r = sqlite3GetTempRange(pParse, nPk);
+ for(iPk=0; iPk<nPk; iPk++){
+ int iCol = pPk->aiColumn[iPk];
+ sqlite3ExprCodeGetColumnToReg(pParse, pTab, iCol, iCur, r+iPk);
+ }
+
+ /* Check if the temp table already contains this key. If so,
+ ** the row has already been included in the result set and
+ ** can be ignored (by jumping past the Gosub below). Otherwise,
+ ** insert the key into the temp table and proceed with processing
+ ** the row.
+ **
+ ** Use some of the same optimizations as OP_RowSetTest: If iSet
+ ** is zero, assume that the key cannot already be present in
+ ** the temp table. And if iSet is -1, assume that there is no
+ ** need to insert the key into the temp table, as it will never
+ ** be tested for. */
+ if( iSet ){
+ jmp1 = sqlite3VdbeAddOp4Int(v, OP_Found, regRowset, 0, r, nPk);
+ VdbeCoverage(v);
+ }
+ if( iSet>=0 ){
+ sqlite3VdbeAddOp3(v, OP_MakeRecord, r, nPk, regRowid);
+ sqlite3VdbeAddOp3(v, OP_IdxInsert, regRowset, regRowid, 0);
+ if( iSet ) sqlite3VdbeChangeP5(v, OPFLAG_USESEEKRESULT);
+ }
+
+ /* Release the array of temp registers */
+ sqlite3ReleaseTempRange(pParse, r, nPk);
+ }
+ }
+
+ /* Invoke the main loop body as a subroutine */
+ sqlite3VdbeAddOp2(v, OP_Gosub, regReturn, iLoopBody);
+
+ /* Jump here (skipping the main loop body subroutine) if the
+ ** current sub-WHERE row is a duplicate from prior sub-WHEREs. */
+ if( jmp1 ) sqlite3VdbeJumpHere(v, jmp1);
+
+ /* 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.
+ */
+ pSubLoop = pSubWInfo->a[0].pWLoop;
+ assert( (pSubLoop->wsFlags & WHERE_AUTO_INDEX)==0 );
+ if( (pSubLoop->wsFlags & WHERE_INDEXED)!=0
+ && (ii==0 || pSubLoop->u.btree.pIndex==pCov)
+ && (HasRowid(pTab) || !IsPrimaryKeyIndex(pSubLoop->u.btree.pIndex))
+ ){
+ assert( pSubWInfo->a[0].iIdxCur==iCovCur );
+ pCov = pSubLoop->u.btree.pIndex;
+ wctrlFlags |= WHERE_REOPEN_IDX;
+ }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(db, pAndExpr);
+ }
+ sqlite3VdbeChangeP1(v, iRetInit, sqlite3VdbeCurrentAddr(v));
+ sqlite3VdbeGoto(v, pLevel->addrBrk);
+ sqlite3VdbeResolveLabel(v, iLoopBody);
+
+ if( pWInfo->nLevel>1 ) sqlite3StackFree(db, pOrTab);
+ if( !untestedTerms ) disableTerm(pLevel, pTerm);
+ }else
+#endif /* SQLITE_OMIT_OR_OPTIMIZATION */
+
+ {
+ /* Case 6: 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 );
+ if( pTabItem->fg.isRecursive ){
+ /* Tables marked isRecursive have only a single row that is stored in
+ ** a pseudo-cursor. No need to Rewind or Next such cursors. */
+ pLevel->op = OP_Noop;
+ }else{
+ codeCursorHint(pWInfo, pLevel, 0);
+ pLevel->op = aStep[bRev];
+ pLevel->p1 = iCur;
+ pLevel->p2 = 1 + sqlite3VdbeAddOp2(v, aStart[bRev], iCur, addrBrk);
+ VdbeCoverageIf(v, bRev==0);
+ VdbeCoverageIf(v, bRev!=0);
+ pLevel->p5 = SQLITE_STMTSTATUS_FULLSCAN_STEP;
+ }
}
+
+#ifdef SQLITE_ENABLE_STMT_SCANSTATUS
+ pLevel->addrVisit = sqlite3VdbeCurrentAddr(v);
+#endif
+
+ /* Insert code to test every subexpression that can be completely
+ ** computed using the current set of tables.
+ */
+ for(pTerm=pWC->a, j=pWC->nTerm; j>0; j--, pTerm++){
+ Expr *pE;
+ int skipLikeAddr = 0;
+ testcase( pTerm->wtFlags & TERM_VIRTUAL );
+ testcase( pTerm->wtFlags & TERM_CODED );
+ if( pTerm->wtFlags & (TERM_VIRTUAL|TERM_CODED) ) continue;
+ if( (pTerm->prereqAll & pLevel->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;
+ }
+ if( pTerm->wtFlags & TERM_LIKECOND ){
+#ifdef SQLITE_LIKE_DOESNT_MATCH_BLOBS
+ continue;
+#else
+ assert( pLevel->iLikeRepCntr>0 );
+ skipLikeAddr = sqlite3VdbeAddOp1(v, OP_IfNot, pLevel->iLikeRepCntr);
+ VdbeCoverage(v);
+#endif
+ }
+ sqlite3ExprIfFalse(pParse, pE, addrCont, SQLITE_JUMPIFNULL);
+ if( skipLikeAddr ) sqlite3VdbeJumpHere(v, skipLikeAddr);
+ pTerm->wtFlags |= TERM_CODED;
+ }
+
+ /* Insert code to test for implied constraints based on transitivity
+ ** of the "==" operator.
+ **
+ ** Example: If the WHERE clause contains "t1.a=t2.b" and "t2.b=123"
+ ** and we are coding the t1 loop and the t2 loop has not yet coded,
+ ** then we cannot use the "t1.a=t2.b" constraint, but we can code
+ ** the implied "t1.a=123" constraint.
+ */
+ for(pTerm=pWC->a, j=pWC->nTerm; j>0; j--, pTerm++){
+ Expr *pE, *pEAlt;
+ WhereTerm *pAlt;
+ if( pTerm->wtFlags & (TERM_VIRTUAL|TERM_CODED) ) continue;
+ if( (pTerm->eOperator & (WO_EQ|WO_IS))==0 ) continue;
+ if( (pTerm->eOperator & WO_EQUIV)==0 ) continue;
+ if( pTerm->leftCursor!=iCur ) continue;
+ if( pLevel->iLeftJoin ) continue;
+ pE = pTerm->pExpr;
+ assert( !ExprHasProperty(pE, EP_FromJoin) );
+ assert( (pTerm->prereqRight & pLevel->notReady)!=0 );
+ pAlt = sqlite3WhereFindTerm(pWC, iCur, pTerm->u.leftColumn, notReady,
+ WO_EQ|WO_IN|WO_IS, 0);
+ if( pAlt==0 ) continue;
+ if( pAlt->wtFlags & (TERM_CODED) ) continue;
+ testcase( pAlt->eOperator & WO_EQ );
+ testcase( pAlt->eOperator & WO_IS );
+ testcase( pAlt->eOperator & WO_IN );
+ VdbeModuleComment((v, "begin transitive constraint"));
+ pEAlt = sqlite3StackAllocRaw(db, sizeof(*pEAlt));
+ if( pEAlt ){
+ *pEAlt = *pAlt->pExpr;
+ pEAlt->pLeft = pE->pLeft;
+ sqlite3ExprIfFalse(pParse, pEAlt, addrCont, SQLITE_JUMPIFNULL);
+ sqlite3StackFree(db, pEAlt);
+ }
+ }
+
+ /* 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 );
+ testcase( pTerm->wtFlags & TERM_CODED );
+ if( pTerm->wtFlags & (TERM_VIRTUAL|TERM_CODED) ) continue;
+ if( (pTerm->prereqAll & pLevel->notReady)!=0 ){
+ assert( pWInfo->untestedTerms );
+ continue;
+ }
+ assert( pTerm->pExpr );
+ sqlite3ExprIfFalse(pParse, pTerm->pExpr, addrCont, SQLITE_JUMPIFNULL);
+ pTerm->wtFlags |= TERM_CODED;
+ }
+ }
+
+ return pLevel->notReady;
+}
+
+/************** End of wherecode.c *******************************************/
+/************** Begin file whereexpr.c ***************************************/
+/*
+** 2015-06-08
+**
+** 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 file was originally part of where.c but was split out to improve
+** readability and editabiliity. This file contains utility routines for
+** analyzing Expr objects in the WHERE clause.
+*/
+/* #include "sqliteInt.h" */
+/* #include "whereInt.h" */
+
+/* Forward declarations */
+static void exprAnalyze(SrcList*, WhereClause*, int);
+
+/*
+** Deallocate all memory associated with a WhereOrInfo object.
+*/
+static void whereOrInfoDelete(sqlite3 *db, WhereOrInfo *p){
+ sqlite3WhereClauseClear(&p->wc);
+ sqlite3DbFree(db, p);
+}
+
+/*
+** Deallocate all memory associated with a WhereAndInfo object.
+*/
+static void whereAndInfoDelete(sqlite3 *db, WhereAndInfo *p){
+ sqlite3WhereClauseClear(&p->wc);
+ sqlite3DbFree(db, p);
}
/*
@@ -102834,13 +121287,13 @@ static void whereClauseClear(WhereClause *pWC){
** calling this routine. Such pointers may be reinitialized by referencing
** the pWC->a[] array.
*/
-static int whereClauseInsert(WhereClause *pWC, Expr *p, u8 wtFlags){
+static int whereClauseInsert(WhereClause *pWC, Expr *p, u16 wtFlags){
WhereTerm *pTerm;
int idx;
- testcase( wtFlags & TERM_VIRTUAL ); /* EV: R-00211-15100 */
+ testcase( wtFlags & TERM_VIRTUAL );
if( pWC->nTerm>=pWC->nSlot ){
WhereTerm *pOld = pWC->a;
- sqlite3 *db = pWC->pParse->db;
+ sqlite3 *db = pWC->pWInfo->pParse->db;
pWC->a = sqlite3DbMallocRaw(db, sizeof(pWC->a[0])*pWC->nSlot*2 );
if( pWC->a==0 ){
if( wtFlags & TERM_DYNAMIC ){
@@ -102854,9 +121307,15 @@ static int whereClauseInsert(WhereClause *pWC, Expr *p, u8 wtFlags){
sqlite3DbFree(db, pOld);
}
pWC->nSlot = sqlite3DbMallocSize(db, pWC->a)/sizeof(pWC->a[0]);
+ memset(&pWC->a[pWC->nTerm], 0, sizeof(pWC->a[0])*(pWC->nSlot-pWC->nTerm));
}
pTerm = &pWC->a[idx = pWC->nTerm++];
- pTerm->pExpr = p;
+ if( p && ExprHasProperty(p, EP_Unlikely) ){
+ pTerm->truthProb = sqlite3LogEst(p->iTable) - 270;
+ }else{
+ pTerm->truthProb = 1;
+ }
+ pTerm->pExpr = sqlite3ExprSkipCollate(p);
pTerm->wtFlags = wtFlags;
pTerm->pWC = pWC;
pTerm->iParent = -1;
@@ -102864,163 +121323,26 @@ static int whereClauseInsert(WhereClause *pWC, Expr *p, u8 wtFlags){
}
/*
-** 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
+** "=", "<", ">", "<=", ">=", "IN", and "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;
+ return op==TK_IN || (op>=TK_EQ && op<=TK_GE) || op==TK_ISNULL || op==TK_IS;
}
/*
-** 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
+** If left/right precedence rules come into play when determining the
+** collating sequence, then COLLATE operators are adjusted to ensure
+** that the collating sequence does not change. For example:
+** "Y collate NOCASE op X" becomes "X op Y" 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.
@@ -103063,6 +121385,8 @@ static u16 operatorMask(int op){
c = WO_IN;
}else if( op==TK_ISNULL ){
c = WO_ISNULL;
+ }else if( op==TK_IS ){
+ c = WO_IS;
}else{
assert( (WO_EQ<<(op-TK_EQ)) < 0x7fff );
c = (u16)(WO_EQ<<(op-TK_EQ));
@@ -103074,81 +121398,10 @@ static u16 operatorMask(int op){
assert( op!=TK_LE || c==WO_LE );
assert( op!=TK_GT || c==WO_GT );
assert( op!=TK_GE || c==WO_GE );
+ assert( op!=TK_IS || c==WO_IS );
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
/*
@@ -103157,7 +121410,11 @@ static void exprAnalyzeAll(
** 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.
+** literal that does not begin with a wildcard. The LHS must be a column
+** that may only be NULL, a string, or a BLOB, never a number. (This means
+** that virtual tables cannot participate in the LIKE optimization.) The
+** collating sequence for the column on the LHS must be appropriate for
+** the operator.
*/
static int isLikeOrGlob(
Parse *pParse, /* Parsing and code generating context */
@@ -103186,7 +121443,7 @@ static int isLikeOrGlob(
pLeft = pList->a[1].pExpr;
if( pLeft->op!=TK_COLUMN
|| sqlite3ExprAffinity(pLeft)!=SQLITE_AFF_TEXT
- || IsVirtual(pLeft->pTab)
+ || IsVirtual(pLeft->pTab) /* Value might be numeric */
){
/* 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. */
@@ -103194,15 +121451,12 @@ static int isLikeOrGlob(
}
assert( pLeft->iColumn!=(-1) ); /* Because IPK never has AFF_TEXT */
- pRight = pList->a[0].pExpr;
+ pRight = sqlite3ExprSkipCollate(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);
+ pVal = sqlite3VdbeGetBoundValue(pReprepare, iCol, SQLITE_AFF_BLOB);
if( pVal && sqlite3_value_type(pVal)==SQLITE_TEXT ){
z = (char *)sqlite3_value_text(pVal);
}
@@ -103230,7 +121484,7 @@ static int isLikeOrGlob(
** 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.
+ ** API. To work around them, add a dummy OP_Variable here.
*/
int r1 = sqlite3GetTempReg(pParse);
sqlite3ExprCodeTarget(pParse, pRight, r1);
@@ -103253,29 +121507,48 @@ static int isLikeOrGlob(
/*
** Check to see if the given expression is of the form
**
-** column MATCH expr
+** column OP expr
+**
+** where OP is one of MATCH, GLOB, LIKE or REGEXP and "column" is a
+** column of a virtual table.
**
** If it is then return TRUE. If not, return FALSE.
*/
static int isMatchOfColumn(
- Expr *pExpr /* Test this expression */
-){
+ Expr *pExpr, /* Test this expression */
+ unsigned char *peOp2 /* OUT: 0 for MATCH, or else an op2 value */
+){
+ struct Op2 {
+ const char *zOp;
+ unsigned char eOp2;
+ } aOp[] = {
+ { "match", SQLITE_INDEX_CONSTRAINT_MATCH },
+ { "glob", SQLITE_INDEX_CONSTRAINT_GLOB },
+ { "like", SQLITE_INDEX_CONSTRAINT_LIKE },
+ { "regexp", SQLITE_INDEX_CONSTRAINT_REGEXP }
+ };
ExprList *pList;
+ Expr *pCol; /* Column reference */
+ int i;
if( pExpr->op!=TK_FUNCTION ){
return 0;
}
- if( sqlite3StrICmp(pExpr->u.zToken,"match")!=0 ){
- return 0;
- }
pList = pExpr->x.pList;
- if( pList->nExpr!=2 ){
+ if( pList==0 || pList->nExpr!=2 ){
return 0;
}
- if( pList->a[1].pExpr->op != TK_COLUMN ){
+ pCol = pList->a[1].pExpr;
+ if( pCol->op!=TK_COLUMN || !IsVirtual(pCol->pTab) ){
return 0;
}
- return 1;
+ for(i=0; i<ArraySize(aOp); i++){
+ if( sqlite3StrICmp(pExpr->u.zToken, aOp[i].zOp)==0 ){
+ *peOp2 = aOp[i].eOp2;
+ return 1;
+ }
+ }
+ return 0;
}
#endif /* SQLITE_OMIT_VIRTUALTABLE */
@@ -103284,8 +121557,92 @@ static int isMatchOfColumn(
** 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( pDerived ){
+ pDerived->flags |= pBase->flags & EP_FromJoin;
+ pDerived->iRightJoinTable = pBase->iRightJoinTable;
+ }
+}
+
+/*
+** Mark term iChild as being a child of term iParent
+*/
+static void markTermAsChild(WhereClause *pWC, int iChild, int iParent){
+ pWC->a[iChild].iParent = iParent;
+ pWC->a[iChild].truthProb = pWC->a[iParent].truthProb;
+ pWC->a[iParent].nChild++;
+}
+
+/*
+** Return the N-th AND-connected subterm of pTerm. Or if pTerm is not
+** a conjunction, then return just pTerm when N==0. If N is exceeds
+** the number of available subterms, return NULL.
+*/
+static WhereTerm *whereNthSubterm(WhereTerm *pTerm, int N){
+ if( pTerm->eOperator!=WO_AND ){
+ return N==0 ? pTerm : 0;
+ }
+ if( N<pTerm->u.pAndInfo->wc.nTerm ){
+ return &pTerm->u.pAndInfo->wc.a[N];
+ }
+ return 0;
+}
+
+/*
+** Subterms pOne and pTwo are contained within WHERE clause pWC. The
+** two subterms are in disjunction - they are OR-ed together.
+**
+** If these two terms are both of the form: "A op B" with the same
+** A and B values but different operators and if the operators are
+** compatible (if one is = and the other is <, for example) then
+** add a new virtual AND term to pWC that is the combination of the
+** two.
+**
+** Some examples:
+**
+** x<y OR x=y --> x<=y
+** x=y OR x=y --> x=y
+** x<=y OR x<y --> x<=y
+**
+** The following is NOT generated:
+**
+** x<y OR x>y --> x!=y
+*/
+static void whereCombineDisjuncts(
+ SrcList *pSrc, /* the FROM clause */
+ WhereClause *pWC, /* The complete WHERE clause */
+ WhereTerm *pOne, /* First disjunct */
+ WhereTerm *pTwo /* Second disjunct */
+){
+ u16 eOp = pOne->eOperator | pTwo->eOperator;
+ sqlite3 *db; /* Database connection (for malloc) */
+ Expr *pNew; /* New virtual expression */
+ int op; /* Operator for the combined expression */
+ int idxNew; /* Index in pWC of the next virtual term */
+
+ if( (pOne->eOperator & (WO_EQ|WO_LT|WO_LE|WO_GT|WO_GE))==0 ) return;
+ if( (pTwo->eOperator & (WO_EQ|WO_LT|WO_LE|WO_GT|WO_GE))==0 ) return;
+ if( (eOp & (WO_EQ|WO_LT|WO_LE))!=eOp
+ && (eOp & (WO_EQ|WO_GT|WO_GE))!=eOp ) return;
+ assert( pOne->pExpr->pLeft!=0 && pOne->pExpr->pRight!=0 );
+ assert( pTwo->pExpr->pLeft!=0 && pTwo->pExpr->pRight!=0 );
+ if( sqlite3ExprCompare(pOne->pExpr->pLeft, pTwo->pExpr->pLeft, -1) ) return;
+ if( sqlite3ExprCompare(pOne->pExpr->pRight, pTwo->pExpr->pRight, -1) )return;
+ /* If we reach this point, it means the two subterms can be combined */
+ if( (eOp & (eOp-1))!=0 ){
+ if( eOp & (WO_LT|WO_LE) ){
+ eOp = WO_LE;
+ }else{
+ assert( eOp & (WO_GT|WO_GE) );
+ eOp = WO_GE;
+ }
+ }
+ db = pWC->pWInfo->pParse->db;
+ pNew = sqlite3ExprDup(db, pOne->pExpr, 0);
+ if( pNew==0 ) return;
+ for(op=TK_EQ; eOp!=(WO_EQ<<(op-TK_EQ)); op++){ assert( op<TK_GE ); }
+ pNew->op = op;
+ idxNew = whereClauseInsert(pWC, pNew, TERM_VIRTUAL|TERM_DYNAMIC);
+ exprAnalyze(pSrc, pWC, idxNew);
}
#if !defined(SQLITE_OMIT_OR_OPTIMIZATION) && !defined(SQLITE_OMIT_SUBQUERY)
@@ -103312,10 +121669,11 @@ static void transferJoinMarkings(Expr *pDerived, Expr *pBase){
** (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)
+** (F) x>A OR (x=A AND y>=B)
**
** CASE 1:
**
-** If all subterms are of the form T.C=expr for some single column of C
+** If all subterms are of the form T.C=expr for some single column of C and
** 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:
@@ -103328,6 +121686,16 @@ static void transferJoinMarkings(Expr *pDerived, Expr *pBase){
**
** CASE 2:
**
+** If there are exactly two disjuncts and one side has x>A and the other side
+** has x=A (for the same x and A) then add a new virtual conjunct term to the
+** WHERE clause of the form "x>=A". Example:
+**
+** x>A OR (x=A AND y>B) adds: x>=A
+**
+** The added conjunct can sometimes be helpful in query planning.
+**
+** CASE 3:
+**
** If all subterms are indexable by a single table T, then set
**
** WhereTerm.eOperator = WO_OR
@@ -103344,25 +121712,25 @@ static void transferJoinMarkings(Expr *pDerived, Expr *pBase){
** 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.
+** is decided elsewhere. 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
+** All examples A through E above satisfy case 3. But if a term
+** also satisfies case 1 (such as B) we know that the optimizer will
+** always prefer case 1, so in that case we pretend that case 3 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
+** Terms that satisfy case 3 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
+** If none of cases 1, 2, or 3 apply, then leave the eOperator set to
** zero. This term is not useful for search.
*/
static void exprAnalyzeOrTerm(
@@ -103370,11 +121738,11 @@ static void exprAnalyzeOrTerm(
WhereClause *pWC, /* the complete WHERE clause */
int idxTerm /* Index of the OR-term to be analyzed */
){
- Parse *pParse = pWC->pParse; /* Parser context */
+ WhereInfo *pWInfo = pWC->pWInfo; /* WHERE clause processing context */
+ Parse *pParse = pWInfo->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 */
@@ -103393,21 +121761,20 @@ static void exprAnalyzeOrTerm(
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);
+ sqlite3WhereClauseInit(pOrWc, pWInfo);
+ sqlite3WhereSplit(pOrWc, pExpr, TK_OR);
+ sqlite3WhereExprAnalyze(pSrc, pOrWc);
if( db->mallocFailed ) return;
assert( pOrWc->nTerm>=2 );
/*
- ** Compute the set of tables that might satisfy cases 1 or 2.
+ ** Compute the set of tables that might satisfy cases 1 or 3.
*/
indexable = ~(Bitmask)0;
- chngToIN = ~(pWC->vmask);
+ chngToIN = ~(Bitmask)0;
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));
@@ -103420,16 +121787,16 @@ static void exprAnalyzeOrTerm(
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);
+ sqlite3WhereClauseInit(pAndWC, pWC->pWInfo);
+ sqlite3WhereSplit(pAndWC, pOrTerm->pExpr, TK_AND);
+ sqlite3WhereExprAnalyze(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);
+ b |= sqlite3WhereGetMask(&pWInfo->sMaskSet, pAndTerm->leftCursor);
}
}
}
@@ -103440,13 +121807,13 @@ static void exprAnalyzeOrTerm(
** corresponding TERM_VIRTUAL term */
}else{
Bitmask b;
- b = getMask(pMaskSet, pOrTerm->leftCursor);
+ b = sqlite3WhereGetMask(&pWInfo->sMaskSet, pOrTerm->leftCursor);
if( pOrTerm->wtFlags & TERM_VIRTUAL ){
WhereTerm *pOther = &pOrWc->a[pOrTerm->iParent];
- b |= getMask(pMaskSet, pOther->leftCursor);
+ b |= sqlite3WhereGetMask(&pWInfo->sMaskSet, pOther->leftCursor);
}
indexable &= b;
- if( pOrTerm->eOperator!=WO_EQ ){
+ if( (pOrTerm->eOperator & WO_EQ)==0 ){
chngToIN = 0;
}else{
chngToIN &= b;
@@ -103455,12 +121822,26 @@ static void exprAnalyzeOrTerm(
}
/*
- ** Record the set of tables that satisfy case 2. The set might be
+ ** Record the set of tables that satisfy case 3. The set might be
** empty.
*/
pOrInfo->indexable = indexable;
pTerm->eOperator = indexable==0 ? 0 : WO_OR;
+ /* For a two-way OR, attempt to implementation case 2.
+ */
+ if( indexable && pOrWc->nTerm==2 ){
+ int iOne = 0;
+ WhereTerm *pOne;
+ while( (pOne = whereNthSubterm(&pOrWc->a[0],iOne++))!=0 ){
+ int iTwo = 0;
+ WhereTerm *pTwo;
+ while( (pTwo = whereNthSubterm(&pOrWc->a[1],iTwo++))!=0 ){
+ whereCombineDisjuncts(pSrc, pWC, pOne, pTwo);
+ }
+ }
+ }
+
/*
** 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
@@ -103497,7 +121878,7 @@ static void exprAnalyzeOrTerm(
for(j=0; j<2 && !okToChngToIN; j++){
pOrTerm = pOrWc->a;
for(i=pOrWc->nTerm-1; i>=0; i--, pOrTerm++){
- assert( pOrTerm->eOperator==WO_EQ );
+ 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
@@ -103505,9 +121886,10 @@ static void exprAnalyzeOrTerm(
assert( j==1 );
continue;
}
- if( (chngToIN & getMask(pMaskSet, pOrTerm->leftCursor))==0 ){
+ if( (chngToIN & sqlite3WhereGetMask(&pWInfo->sMaskSet,
+ 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
+ ** chngToIN set but t1 is not. This term will be either preceded
** or follwed by an inverted copy (t2.b==t1.a). Skip this term
** and use its inversion. */
testcase( pOrTerm->wtFlags & TERM_COPIED );
@@ -103523,8 +121905,8 @@ static void exprAnalyzeOrTerm(
/* 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) );
+ assert( IsPowerOfTwo(chngToIN) );
+ assert( chngToIN==sqlite3WhereGetMask(&pWInfo->sMaskSet, iCursor) );
break;
}
testcase( j==1 );
@@ -103533,7 +121915,7 @@ static void exprAnalyzeOrTerm(
** 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 );
+ assert( pOrTerm->eOperator & WO_EQ );
if( pOrTerm->leftCursor!=iCursor ){
pOrTerm->wtFlags &= ~TERM_OR_OK;
}else if( pOrTerm->u.leftColumn!=iColumn ){
@@ -103558,8 +121940,6 @@ static void exprAnalyzeOrTerm(
/* 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 */
@@ -103569,11 +121949,11 @@ static void exprAnalyzeOrTerm(
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->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);
+ pList = sqlite3ExprListAppend(pWInfo->pParse, pList, pDup);
pLeft = pOrTerm->pExpr->pLeft;
}
assert( pLeft!=0 );
@@ -103588,17 +121968,126 @@ static void exprAnalyzeOrTerm(
testcase( idxNew==0 );
exprAnalyze(pSrc, pWC, idxNew);
pTerm = &pWC->a[idxTerm];
- pWC->a[idxNew].iParent = idxTerm;
- pTerm->nChild = 1;
+ markTermAsChild(pWC, idxNew, idxTerm);
}else{
sqlite3ExprListDelete(db, pList);
}
- pTerm->eOperator = WO_NOOP; /* case 1 trumps case 2 */
+ pTerm->eOperator = WO_NOOP; /* case 1 trumps case 3 */
}
}
}
#endif /* !SQLITE_OMIT_OR_OPTIMIZATION && !SQLITE_OMIT_SUBQUERY */
+/*
+** We already know that pExpr is a binary operator where both operands are
+** column references. This routine checks to see if pExpr is an equivalence
+** relation:
+** 1. The SQLITE_Transitive optimization must be enabled
+** 2. Must be either an == or an IS operator
+** 3. Not originating in the ON clause of an OUTER JOIN
+** 4. The affinities of A and B must be compatible
+** 5a. Both operands use the same collating sequence OR
+** 5b. The overall collating sequence is BINARY
+** If this routine returns TRUE, that means that the RHS can be substituted
+** for the LHS anyplace else in the WHERE clause where the LHS column occurs.
+** This is an optimization. No harm comes from returning 0. But if 1 is
+** returned when it should not be, then incorrect answers might result.
+*/
+static int termIsEquivalence(Parse *pParse, Expr *pExpr){
+ char aff1, aff2;
+ CollSeq *pColl;
+ const char *zColl1, *zColl2;
+ if( !OptimizationEnabled(pParse->db, SQLITE_Transitive) ) return 0;
+ if( pExpr->op!=TK_EQ && pExpr->op!=TK_IS ) return 0;
+ if( ExprHasProperty(pExpr, EP_FromJoin) ) return 0;
+ aff1 = sqlite3ExprAffinity(pExpr->pLeft);
+ aff2 = sqlite3ExprAffinity(pExpr->pRight);
+ if( aff1!=aff2
+ && (!sqlite3IsNumericAffinity(aff1) || !sqlite3IsNumericAffinity(aff2))
+ ){
+ return 0;
+ }
+ pColl = sqlite3BinaryCompareCollSeq(pParse, pExpr->pLeft, pExpr->pRight);
+ if( pColl==0 || sqlite3StrICmp(pColl->zName, "BINARY")==0 ) return 1;
+ pColl = sqlite3ExprCollSeq(pParse, pExpr->pLeft);
+ /* Since pLeft and pRight are both a column references, their collating
+ ** sequence should always be defined. */
+ zColl1 = ALWAYS(pColl) ? pColl->zName : 0;
+ pColl = sqlite3ExprCollSeq(pParse, pExpr->pRight);
+ zColl2 = ALWAYS(pColl) ? pColl->zName : 0;
+ return sqlite3StrICmp(zColl1, zColl2)==0;
+}
+
+/*
+** Recursively walk the expressions of a SELECT statement and generate
+** a bitmask indicating which tables are used in that expression
+** tree.
+*/
+static Bitmask exprSelectUsage(WhereMaskSet *pMaskSet, Select *pS){
+ Bitmask mask = 0;
+ while( pS ){
+ SrcList *pSrc = pS->pSrc;
+ mask |= sqlite3WhereExprListUsage(pMaskSet, pS->pEList);
+ mask |= sqlite3WhereExprListUsage(pMaskSet, pS->pGroupBy);
+ mask |= sqlite3WhereExprListUsage(pMaskSet, pS->pOrderBy);
+ mask |= sqlite3WhereExprUsage(pMaskSet, pS->pWhere);
+ mask |= sqlite3WhereExprUsage(pMaskSet, pS->pHaving);
+ if( ALWAYS(pSrc!=0) ){
+ int i;
+ for(i=0; i<pSrc->nSrc; i++){
+ mask |= exprSelectUsage(pMaskSet, pSrc->a[i].pSelect);
+ mask |= sqlite3WhereExprUsage(pMaskSet, pSrc->a[i].pOn);
+ }
+ }
+ pS = pS->pPrior;
+ }
+ return mask;
+}
+
+/*
+** Expression pExpr is one operand of a comparison operator that might
+** be useful for indexing. This routine checks to see if pExpr appears
+** in any index. Return TRUE (1) if pExpr is an indexed term and return
+** FALSE (0) if not. If TRUE is returned, also set *piCur to the cursor
+** number of the table that is indexed and *piColumn to the column number
+** of the column that is indexed, or -2 if an expression is being indexed.
+**
+** If pExpr is a TK_COLUMN column reference, then this routine always returns
+** true even if that particular column is not indexed, because the column
+** might be added to an automatic index later.
+*/
+static int exprMightBeIndexed(
+ SrcList *pFrom, /* The FROM clause */
+ Bitmask mPrereq, /* Bitmask of FROM clause terms referenced by pExpr */
+ Expr *pExpr, /* An operand of a comparison operator */
+ int *piCur, /* Write the referenced table cursor number here */
+ int *piColumn /* Write the referenced table column number here */
+){
+ Index *pIdx;
+ int i;
+ int iCur;
+ if( pExpr->op==TK_COLUMN ){
+ *piCur = pExpr->iTable;
+ *piColumn = pExpr->iColumn;
+ return 1;
+ }
+ if( mPrereq==0 ) return 0; /* No table references */
+ if( (mPrereq&(mPrereq-1))!=0 ) return 0; /* Refs more than one table */
+ for(i=0; mPrereq>1; i++, mPrereq>>=1){}
+ iCur = pFrom->a[i].iCursor;
+ for(pIdx=pFrom->a[i].pTab->pIndex; pIdx; pIdx=pIdx->pNext){
+ if( pIdx->aColExpr==0 ) continue;
+ for(i=0; i<pIdx->nKeyCol; i++){
+ if( pIdx->aiColumn[i]!=(-2) ) continue;
+ if( sqlite3ExprCompare(pExpr, pIdx->aColExpr->a[i].pExpr, iCur)==0 ){
+ *piCur = iCur;
+ *piColumn = -2;
+ return 1;
+ }
+ }
+ }
+ return 0;
+}
/*
** The input to this routine is an WhereTerm structure with only the
@@ -103623,6 +122112,7 @@ static void exprAnalyze(
WhereClause *pWC, /* the WHERE clause */
int idxTerm /* Index of the term to be analyzed */
){
+ WhereInfo *pWInfo = pWC->pWInfo; /* WHERE clause processing context */
WhereTerm *pTerm; /* The term to be analyzed */
WhereMaskSet *pMaskSet; /* Set of table index masks */
Expr *pExpr; /* The expression to be analyzed */
@@ -103631,34 +122121,36 @@ static void exprAnalyze(
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 noCase = 0; /* uppercase equivalent to lowercase */
int op; /* Top-level operator. pExpr->op */
- Parse *pParse = pWC->pParse; /* Parsing context */
+ Parse *pParse = pWInfo->pParse; /* Parsing context */
sqlite3 *db = pParse->db; /* Database connection */
+ unsigned char eOp2; /* op2 value for LIKE/REGEXP/GLOB */
if( db->mallocFailed ){
return;
}
pTerm = &pWC->a[idxTerm];
- pMaskSet = pWC->pMaskSet;
- pExpr = sqlite3ExprSkipCollate(pTerm->pExpr);
- prereqLeft = exprTableUsage(pMaskSet, pExpr->pLeft);
+ pMaskSet = &pWInfo->sMaskSet;
+ pExpr = pTerm->pExpr;
+ assert( pExpr->op!=TK_AS && pExpr->op!=TK_COLLATE );
+ prereqLeft = sqlite3WhereExprUsage(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);
+ pTerm->prereqRight = exprSelectUsage(pMaskSet, pExpr->x.pSelect);
}else{
- pTerm->prereqRight = exprListTableUsage(pMaskSet, pExpr->x.pList);
+ pTerm->prereqRight = sqlite3WhereExprListUsage(pMaskSet, pExpr->x.pList);
}
}else if( op==TK_ISNULL ){
pTerm->prereqRight = 0;
}else{
- pTerm->prereqRight = exprTableUsage(pMaskSet, pExpr->pRight);
+ pTerm->prereqRight = sqlite3WhereExprUsage(pMaskSet, pExpr->pRight);
}
- prereqAll = exprTableUsage(pMaskSet, pExpr);
+ prereqAll = sqlite3WhereExprUsage(pMaskSet, pExpr);
if( ExprHasProperty(pExpr, EP_FromJoin) ){
- Bitmask x = getMask(pMaskSet, pExpr->iRightJoinTable);
+ Bitmask x = sqlite3WhereGetMask(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 */
@@ -103667,17 +122159,23 @@ static void exprAnalyze(
pTerm->leftCursor = -1;
pTerm->iParent = -1;
pTerm->eOperator = 0;
- if( allowedOp(op) && (pTerm->prereqRight & prereqLeft)==0 ){
+ if( allowedOp(op) ){
+ int iCur, iColumn;
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 ){
+ u16 opMask = (pTerm->prereqRight & prereqLeft)==0 ? WO_ALL : WO_EQUIV;
+ if( exprMightBeIndexed(pSrc, prereqLeft, pLeft, &iCur, &iColumn) ){
+ pTerm->leftCursor = iCur;
+ pTerm->u.leftColumn = iColumn;
+ pTerm->eOperator = operatorMask(op) & opMask;
+ }
+ if( op==TK_IS ) pTerm->wtFlags |= TERM_IS;
+ if( pRight
+ && exprMightBeIndexed(pSrc, pTerm->prereqRight, pRight, &iCur, &iColumn)
+ ){
WhereTerm *pNew;
Expr *pDup;
+ u16 eExtraOp = 0; /* Extra bits for pNew->eOperator */
if( pTerm->leftCursor>=0 ){
int idxNew;
pDup = sqlite3ExprDup(db, pExpr, 0);
@@ -103688,22 +122186,26 @@ static void exprAnalyze(
idxNew = whereClauseInsert(pWC, pDup, TERM_VIRTUAL|TERM_DYNAMIC);
if( idxNew==0 ) return;
pNew = &pWC->a[idxNew];
- pNew->iParent = idxTerm;
+ markTermAsChild(pWC, idxNew, idxTerm);
+ if( op==TK_IS ) pNew->wtFlags |= TERM_IS;
pTerm = &pWC->a[idxTerm];
- pTerm->nChild = 1;
pTerm->wtFlags |= TERM_COPIED;
+
+ if( termIsEquivalence(pParse, pDup) ){
+ pTerm->eOperator |= WO_EQUIV;
+ eExtraOp = WO_EQUIV;
+ }
}else{
pDup = pExpr;
pNew = pTerm;
}
exprCommute(pParse, pDup);
- pLeft = sqlite3ExprSkipCollate(pDup->pLeft);
- pNew->leftCursor = pLeft->iTable;
- pNew->u.leftColumn = pLeft->iColumn;
+ pNew->leftCursor = iCur;
+ pNew->u.leftColumn = iColumn;
testcase( (prereqLeft | extraRight) != prereqLeft );
pNew->prereqRight = prereqLeft | extraRight;
pNew->prereqAll = prereqAll;
- pNew->eOperator = operatorMask(pDup->op);
+ pNew->eOperator = (operatorMask(pDup->op) + eExtraOp) & opMask;
}
}
@@ -103735,13 +122237,13 @@ static void exprAnalyze(
pNewExpr = sqlite3PExpr(pParse, ops[i],
sqlite3ExprDup(db, pExpr->pLeft, 0),
sqlite3ExprDup(db, pList->a[i].pExpr, 0), 0);
+ transferJoinMarkings(pNewExpr, pExpr);
idxNew = whereClauseInsert(pWC, pNewExpr, TERM_VIRTUAL|TERM_DYNAMIC);
testcase( idxNew==0 );
exprAnalyze(pSrc, pWC, idxNew);
pTerm = &pWC->a[idxTerm];
- pWC->a[idxNew].iParent = idxTerm;
+ markTermAsChild(pWC, idxNew, idxTerm);
}
- pTerm->nChild = 2;
}
#endif /* SQLITE_OMIT_BETWEEN_OPTIMIZATION */
@@ -103760,12 +122262,15 @@ static void exprAnalyze(
/* 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
+ ** A like pattern of the form "x LIKE 'aBc%'" is changed into constraints
**
- ** x>='abc' AND x<'abd' AND x LIKE 'abc%'
+ ** x>='ABC' AND x<'abd' AND x LIKE 'aBc%'
**
** The last character of the prefix "abc" is incremented to form the
- ** termination condition "abd".
+ ** termination condition "abd". If case is not significant (the default
+ ** for LIKE) then the lower-bound is made all uppercase and the upper-
+ ** bound is made all lowercase so that the bounds also work when comparing
+ ** BLOBs.
*/
if( pWC->op==TK_AND
&& isLikeOrGlob(pParse, pExpr, &pStr1, &isComplete, &noCase)
@@ -103776,10 +122281,26 @@ static void exprAnalyze(
Expr *pNewExpr2;
int idxNew1;
int idxNew2;
- Token sCollSeqName; /* Name of collating sequence */
+ const char *zCollSeqName; /* Name of collating sequence */
+ const u16 wtFlags = TERM_LIKEOPT | TERM_VIRTUAL | TERM_DYNAMIC;
pLeft = pExpr->x.pList->a[1].pExpr;
pStr2 = sqlite3ExprDup(db, pStr1, 0);
+
+ /* Convert the lower bound to upper-case and the upper bound to
+ ** lower-case (upper-case is less than lower-case in ASCII) so that
+ ** the range constraints also work for BLOBs
+ */
+ if( noCase && !pParse->db->mallocFailed ){
+ int i;
+ char c;
+ pTerm->wtFlags |= TERM_LIKE;
+ for(i=0; (c = pStr1->u.zToken[i])!=0; i++){
+ pStr1->u.zToken[i] = sqlite3Toupper(c);
+ pStr2->u.zToken[i] = sqlite3Tolower(c);
+ }
+ }
+
if( !db->mallocFailed ){
u8 c, *pC; /* Last character before the first wildcard */
pC = (u8*)&pStr2->u.zToken[sqlite3Strlen30(pStr2->u.zToken)-1];
@@ -103791,34 +122312,32 @@ static void exprAnalyze(
** 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 */
-
-
+ if( c=='A'-1 ) isComplete = 0;
c = sqlite3UpperToLower[c];
}
*pC = c + 1;
}
- sCollSeqName.z = noCase ? "NOCASE" : "BINARY";
- sCollSeqName.n = 6;
+ zCollSeqName = noCase ? "NOCASE" : "BINARY";
pNewExpr1 = sqlite3ExprDup(db, pLeft, 0);
- pNewExpr1 = sqlite3PExpr(pParse, TK_GE,
- sqlite3ExprAddCollateToken(pParse,pNewExpr1,&sCollSeqName),
+ pNewExpr1 = sqlite3PExpr(pParse, TK_GE,
+ sqlite3ExprAddCollateString(pParse,pNewExpr1,zCollSeqName),
pStr1, 0);
- idxNew1 = whereClauseInsert(pWC, pNewExpr1, TERM_VIRTUAL|TERM_DYNAMIC);
+ transferJoinMarkings(pNewExpr1, pExpr);
+ idxNew1 = whereClauseInsert(pWC, pNewExpr1, wtFlags);
testcase( idxNew1==0 );
exprAnalyze(pSrc, pWC, idxNew1);
pNewExpr2 = sqlite3ExprDup(db, pLeft, 0);
pNewExpr2 = sqlite3PExpr(pParse, TK_LT,
- sqlite3ExprAddCollateToken(pParse,pNewExpr2,&sCollSeqName),
+ sqlite3ExprAddCollateString(pParse,pNewExpr2,zCollSeqName),
pStr2, 0);
- idxNew2 = whereClauseInsert(pWC, pNewExpr2, TERM_VIRTUAL|TERM_DYNAMIC);
+ transferJoinMarkings(pNewExpr2, pExpr);
+ idxNew2 = whereClauseInsert(pWC, pNewExpr2, wtFlags);
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;
+ markTermAsChild(pWC, idxNew1, idxTerm);
+ markTermAsChild(pWC, idxNew2, idxTerm);
}
}
#endif /* SQLITE_OMIT_LIKE_OPTIMIZATION */
@@ -103830,7 +122349,7 @@ static void exprAnalyze(
** virtual tables. The native query optimizer does not attempt
** to do anything with MATCH functions.
*/
- if( isMatchOfColumn(pExpr) ){
+ if( isMatchOfColumn(pExpr, &eOp2) ){
int idxNew;
Expr *pRight, *pLeft;
WhereTerm *pNewTerm;
@@ -103838,8 +122357,8 @@ static void exprAnalyze(
pRight = pExpr->x.pList->a[0].pExpr;
pLeft = pExpr->x.pList->a[1].pExpr;
- prereqExpr = exprTableUsage(pMaskSet, pRight);
- prereqColumn = exprTableUsage(pMaskSet, pLeft);
+ prereqExpr = sqlite3WhereExprUsage(pMaskSet, pRight);
+ prereqColumn = sqlite3WhereExprUsage(pMaskSet, pLeft);
if( (prereqExpr & prereqColumn)==0 ){
Expr *pNewExpr;
pNewExpr = sqlite3PExpr(pParse, TK_MATCH,
@@ -103851,29 +122370,27 @@ static void exprAnalyze(
pNewTerm->leftCursor = pLeft->iTable;
pNewTerm->u.leftColumn = pLeft->iColumn;
pNewTerm->eOperator = WO_MATCH;
- pNewTerm->iParent = idxTerm;
+ pNewTerm->eMatchOp = eOp2;
+ markTermAsChild(pWC, idxNew, idxTerm);
pTerm = &pWC->a[idxTerm];
- pTerm->nChild = 1;
pTerm->wtFlags |= TERM_COPIED;
pNewTerm->prereqAll = pTerm->prereqAll;
}
}
#endif /* SQLITE_OMIT_VIRTUALTABLE */
-#ifdef SQLITE_ENABLE_STAT3
+#ifdef SQLITE_ENABLE_STAT3_OR_STAT4
/* 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.
+ ** Note that the virtual term must be tagged with TERM_VNULL.
*/
if( pExpr->op==TK_NOTNULL
&& pExpr->pLeft->op==TK_COLUMN
&& pExpr->pLeft->iColumn>=0
+ && OptimizationEnabled(db, SQLITE_Stat34)
){
Expr *pNewExpr;
Expr *pLeft = pExpr->pLeft;
@@ -103892,14 +122409,13 @@ static void exprAnalyze(
pNewTerm->leftCursor = pLeft->iTable;
pNewTerm->u.leftColumn = pLeft->iColumn;
pNewTerm->eOperator = WO_GT;
- pNewTerm->iParent = idxTerm;
+ markTermAsChild(pWC, idxNew, idxTerm);
pTerm = &pWC->a[idxTerm];
- pTerm->nChild = 1;
pTerm->wtFlags |= TERM_COPIED;
pNewTerm->prereqAll = pTerm->prereqAll;
}
}
-#endif /* SQLITE_ENABLE_STAT */
+#endif /* SQLITE_ENABLE_STAT3_OR_STAT4 */
/* Prevent ON clause terms of a LEFT JOIN from being used to drive
** an index for tables to the left of the join.
@@ -103907,12 +122423,534 @@ static void exprAnalyze(
pTerm->prereqRight |= extraRight;
}
+/***************************************************************************
+** Routines with file scope above. Interface to the rest of the where.c
+** subsystem follows.
+***************************************************************************/
+
+/*
+** 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.
+*/
+SQLITE_PRIVATE void sqlite3WhereSplit(WhereClause *pWC, Expr *pExpr, u8 op){
+ Expr *pE2 = sqlite3ExprSkipCollate(pExpr);
+ pWC->op = op;
+ if( pE2==0 ) return;
+ if( pE2->op!=op ){
+ whereClauseInsert(pWC, pExpr, 0);
+ }else{
+ sqlite3WhereSplit(pWC, pE2->pLeft, op);
+ sqlite3WhereSplit(pWC, pE2->pRight, op);
+ }
+}
+
+/*
+** Initialize a preallocated WhereClause structure.
+*/
+SQLITE_PRIVATE void sqlite3WhereClauseInit(
+ WhereClause *pWC, /* The WhereClause to be initialized */
+ WhereInfo *pWInfo /* The WHERE processing context */
+){
+ pWC->pWInfo = pWInfo;
+ pWC->pOuter = 0;
+ pWC->nTerm = 0;
+ pWC->nSlot = ArraySize(pWC->aStatic);
+ pWC->a = pWC->aStatic;
+}
+
+/*
+** Deallocate a WhereClause structure. The WhereClause structure
+** itself is not freed. This routine is the inverse of
+** sqlite3WhereClauseInit().
+*/
+SQLITE_PRIVATE void sqlite3WhereClauseClear(WhereClause *pWC){
+ int i;
+ WhereTerm *a;
+ sqlite3 *db = pWC->pWInfo->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);
+ }
+}
+
+
+/*
+** These routines walk (recursively) an expression tree and generate
+** a bitmask indicating which tables are used in that expression
+** tree.
+*/
+SQLITE_PRIVATE Bitmask sqlite3WhereExprUsage(WhereMaskSet *pMaskSet, Expr *p){
+ Bitmask mask = 0;
+ if( p==0 ) return 0;
+ if( p->op==TK_COLUMN ){
+ mask = sqlite3WhereGetMask(pMaskSet, p->iTable);
+ return mask;
+ }
+ mask = sqlite3WhereExprUsage(pMaskSet, p->pRight);
+ mask |= sqlite3WhereExprUsage(pMaskSet, p->pLeft);
+ if( ExprHasProperty(p, EP_xIsSelect) ){
+ mask |= exprSelectUsage(pMaskSet, p->x.pSelect);
+ }else{
+ mask |= sqlite3WhereExprListUsage(pMaskSet, p->x.pList);
+ }
+ return mask;
+}
+SQLITE_PRIVATE Bitmask sqlite3WhereExprListUsage(WhereMaskSet *pMaskSet, ExprList *pList){
+ int i;
+ Bitmask mask = 0;
+ if( pList ){
+ for(i=0; i<pList->nExpr; i++){
+ mask |= sqlite3WhereExprUsage(pMaskSet, pList->a[i].pExpr);
+ }
+ }
+ return mask;
+}
+
+
+/*
+** Call exprAnalyze on all terms in a WHERE clause.
+**
+** Note that exprAnalyze() might add new virtual terms onto the
+** end of the WHERE clause. We do not want to analyze these new
+** virtual terms, so start analyzing at the end and work forward
+** so that the added virtual terms are never processed.
+*/
+SQLITE_PRIVATE void sqlite3WhereExprAnalyze(
+ 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);
+ }
+}
+
+/*
+** For table-valued-functions, transform the function arguments into
+** new WHERE clause terms.
+**
+** Each function argument translates into an equality constraint against
+** a HIDDEN column in the table.
+*/
+SQLITE_PRIVATE void sqlite3WhereTabFuncArgs(
+ Parse *pParse, /* Parsing context */
+ struct SrcList_item *pItem, /* The FROM clause term to process */
+ WhereClause *pWC /* Xfer function arguments to here */
+){
+ Table *pTab;
+ int j, k;
+ ExprList *pArgs;
+ Expr *pColRef;
+ Expr *pTerm;
+ if( pItem->fg.isTabFunc==0 ) return;
+ pTab = pItem->pTab;
+ assert( pTab!=0 );
+ pArgs = pItem->u1.pFuncArg;
+ if( pArgs==0 ) return;
+ for(j=k=0; j<pArgs->nExpr; j++){
+ while( k<pTab->nCol && (pTab->aCol[k].colFlags & COLFLAG_HIDDEN)==0 ){k++;}
+ if( k>=pTab->nCol ){
+ sqlite3ErrorMsg(pParse, "too many arguments on %s() - max %d",
+ pTab->zName, j);
+ return;
+ }
+ pColRef = sqlite3PExpr(pParse, TK_COLUMN, 0, 0, 0);
+ if( pColRef==0 ) return;
+ pColRef->iTable = pItem->iCursor;
+ pColRef->iColumn = k++;
+ pColRef->pTab = pTab;
+ pTerm = sqlite3PExpr(pParse, TK_EQ, pColRef,
+ sqlite3ExprDup(pParse->db, pArgs->a[j].pExpr, 0), 0);
+ whereClauseInsert(pWC, pTerm, TERM_DYNAMIC);
+ }
+}
+
+/************** End of whereexpr.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".
+*/
+/* #include "sqliteInt.h" */
+/* #include "whereInt.h" */
+
+/* Forward declaration of methods */
+static int whereLoopResize(sqlite3*, WhereLoop*, int);
+
+/* Test variable that can be set to enable WHERE tracing */
+#if defined(SQLITE_TEST) || defined(SQLITE_DEBUG)
+/***/ int sqlite3WhereTrace = 0;
+#endif
+
+
+/*
+** Return the estimated number of output rows from a WHERE clause
+*/
+SQLITE_PRIVATE u64 sqlite3WhereOutputRowCount(WhereInfo *pWInfo){
+ return sqlite3LogEstToInt(pWInfo->nRowOut);
+}
+
+/*
+** Return one of the WHERE_DISTINCT_xxxxx values to indicate how this
+** WHERE clause returns outputs for DISTINCT processing.
+*/
+SQLITE_PRIVATE int sqlite3WhereIsDistinct(WhereInfo *pWInfo){
+ return pWInfo->eDistinct;
+}
+
+/*
+** Return TRUE if the WHERE clause returns rows in ORDER BY order.
+** Return FALSE if the output needs to be sorted.
+*/
+SQLITE_PRIVATE int sqlite3WhereIsOrdered(WhereInfo *pWInfo){
+ return pWInfo->nOBSat;
+}
+
+/*
+** Return the VDBE address or label to jump to in order to continue
+** immediately with the next row of a WHERE clause.
+*/
+SQLITE_PRIVATE int sqlite3WhereContinueLabel(WhereInfo *pWInfo){
+ assert( pWInfo->iContinue!=0 );
+ return pWInfo->iContinue;
+}
+
+/*
+** Return the VDBE address or label to jump to in order to break
+** out of a WHERE loop.
+*/
+SQLITE_PRIVATE int sqlite3WhereBreakLabel(WhereInfo *pWInfo){
+ return pWInfo->iBreak;
+}
+
/*
-** 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.
+** Return ONEPASS_OFF (0) if an UPDATE or DELETE statement is unable to
+** operate directly on the rowis returned by a WHERE clause. Return
+** ONEPASS_SINGLE (1) if the statement can operation directly because only
+** a single row is to be changed. Return ONEPASS_MULTI (2) if the one-pass
+** optimization can be used on multiple
+**
+** If the ONEPASS optimization is used (if this routine returns true)
+** then also write the indices of open cursors used by ONEPASS
+** into aiCur[0] and aiCur[1]. iaCur[0] gets the cursor of the data
+** table and iaCur[1] gets the cursor used by an auxiliary index.
+** Either value may be -1, indicating that cursor is not used.
+** Any cursors returned will have been opened for writing.
+**
+** aiCur[0] and aiCur[1] both get -1 if the where-clause logic is
+** unable to use the ONEPASS optimization.
+*/
+SQLITE_PRIVATE int sqlite3WhereOkOnePass(WhereInfo *pWInfo, int *aiCur){
+ memcpy(aiCur, pWInfo->aiCurOnePass, sizeof(int)*2);
+#ifdef WHERETRACE_ENABLED
+ if( sqlite3WhereTrace && pWInfo->eOnePass!=ONEPASS_OFF ){
+ sqlite3DebugPrintf("%s cursors: %d %d\n",
+ pWInfo->eOnePass==ONEPASS_SINGLE ? "ONEPASS_SINGLE" : "ONEPASS_MULTI",
+ aiCur[0], aiCur[1]);
+ }
+#endif
+ return pWInfo->eOnePass;
+}
+
+/*
+** Move the content of pSrc into pDest
+*/
+static void whereOrMove(WhereOrSet *pDest, WhereOrSet *pSrc){
+ pDest->n = pSrc->n;
+ memcpy(pDest->a, pSrc->a, pDest->n*sizeof(pDest->a[0]));
+}
+
+/*
+** Try to insert a new prerequisite/cost entry into the WhereOrSet pSet.
+**
+** The new entry might overwrite an existing entry, or it might be
+** appended, or it might be discarded. Do whatever is the right thing
+** so that pSet keeps the N_OR_COST best entries seen so far.
+*/
+static int whereOrInsert(
+ WhereOrSet *pSet, /* The WhereOrSet to be updated */
+ Bitmask prereq, /* Prerequisites of the new entry */
+ LogEst rRun, /* Run-cost of the new entry */
+ LogEst nOut /* Number of outputs for the new entry */
+){
+ u16 i;
+ WhereOrCost *p;
+ for(i=pSet->n, p=pSet->a; i>0; i--, p++){
+ if( rRun<=p->rRun && (prereq & p->prereq)==prereq ){
+ goto whereOrInsert_done;
+ }
+ if( p->rRun<=rRun && (p->prereq & prereq)==p->prereq ){
+ return 0;
+ }
+ }
+ if( pSet->n<N_OR_COST ){
+ p = &pSet->a[pSet->n++];
+ p->nOut = nOut;
+ }else{
+ p = pSet->a;
+ for(i=1; i<pSet->n; i++){
+ if( p->rRun>pSet->a[i].rRun ) p = pSet->a + i;
+ }
+ if( p->rRun<=rRun ) return 0;
+ }
+whereOrInsert_done:
+ p->prereq = prereq;
+ p->rRun = rRun;
+ if( p->nOut>nOut ) p->nOut = nOut;
+ return 1;
+}
+
+/*
+** Return the bitmask for the given cursor number. Return 0 if
+** iCursor is not in the set.
+*/
+SQLITE_PRIVATE Bitmask sqlite3WhereGetMask(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 MASKBIT(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;
+}
+
+/*
+** Advance to the next WhereTerm that matches according to the criteria
+** established when the pScan object was initialized by whereScanInit().
+** Return NULL if there are no more matching WhereTerms.
+*/
+static WhereTerm *whereScanNext(WhereScan *pScan){
+ int iCur; /* The cursor on the LHS of the term */
+ i16 iColumn; /* The column on the LHS of the term. -1 for IPK */
+ Expr *pX; /* An expression being tested */
+ WhereClause *pWC; /* Shorthand for pScan->pWC */
+ WhereTerm *pTerm; /* The term being tested */
+ int k = pScan->k; /* Where to start scanning */
+
+ while( pScan->iEquiv<=pScan->nEquiv ){
+ iCur = pScan->aiCur[pScan->iEquiv-1];
+ iColumn = pScan->aiColumn[pScan->iEquiv-1];
+ if( iColumn==XN_EXPR && pScan->pIdxExpr==0 ) return 0;
+ while( (pWC = pScan->pWC)!=0 ){
+ for(pTerm=pWC->a+k; k<pWC->nTerm; k++, pTerm++){
+ if( pTerm->leftCursor==iCur
+ && pTerm->u.leftColumn==iColumn
+ && (iColumn!=XN_EXPR
+ || sqlite3ExprCompare(pTerm->pExpr->pLeft,pScan->pIdxExpr,iCur)==0)
+ && (pScan->iEquiv<=1 || !ExprHasProperty(pTerm->pExpr, EP_FromJoin))
+ ){
+ if( (pTerm->eOperator & WO_EQUIV)!=0
+ && pScan->nEquiv<ArraySize(pScan->aiCur)
+ && (pX = sqlite3ExprSkipCollate(pTerm->pExpr->pRight))->op==TK_COLUMN
+ ){
+ int j;
+ for(j=0; j<pScan->nEquiv; j++){
+ if( pScan->aiCur[j]==pX->iTable
+ && pScan->aiColumn[j]==pX->iColumn ){
+ break;
+ }
+ }
+ if( j==pScan->nEquiv ){
+ pScan->aiCur[j] = pX->iTable;
+ pScan->aiColumn[j] = pX->iColumn;
+ pScan->nEquiv++;
+ }
+ }
+ if( (pTerm->eOperator & pScan->opMask)!=0 ){
+ /* Verify the affinity and collating sequence match */
+ if( pScan->zCollName && (pTerm->eOperator & WO_ISNULL)==0 ){
+ CollSeq *pColl;
+ Parse *pParse = pWC->pWInfo->pParse;
+ pX = pTerm->pExpr;
+ if( !sqlite3IndexAffinityOk(pX, pScan->idxaff) ){
+ continue;
+ }
+ assert(pX->pLeft);
+ pColl = sqlite3BinaryCompareCollSeq(pParse,
+ pX->pLeft, pX->pRight);
+ if( pColl==0 ) pColl = pParse->db->pDfltColl;
+ if( sqlite3StrICmp(pColl->zName, pScan->zCollName) ){
+ continue;
+ }
+ }
+ if( (pTerm->eOperator & (WO_EQ|WO_IS))!=0
+ && (pX = pTerm->pExpr->pRight)->op==TK_COLUMN
+ && pX->iTable==pScan->aiCur[0]
+ && pX->iColumn==pScan->aiColumn[0]
+ ){
+ testcase( pTerm->eOperator & WO_IS );
+ continue;
+ }
+ pScan->k = k+1;
+ return pTerm;
+ }
+ }
+ }
+ pScan->pWC = pScan->pWC->pOuter;
+ k = 0;
+ }
+ pScan->pWC = pScan->pOrigWC;
+ k = 0;
+ pScan->iEquiv++;
+ }
+ return 0;
+}
+
+/*
+** Initialize a WHERE clause scanner object. Return a pointer to the
+** first match. Return NULL if there are no matches.
+**
+** The scanner will be searching the WHERE clause pWC. It will look
+** for terms of the form "X <op> <expr>" where X is column iColumn of table
+** iCur. The <op> must be one of the operators described by opMask.
+**
+** If the search is for X and the WHERE clause contains terms of the
+** form X=Y then this routine might also return terms of the form
+** "Y <op> <expr>". The number of levels of transitivity is limited,
+** but is enough to handle most commonly occurring SQL statements.
+**
+** If X is not the INTEGER PRIMARY KEY then X must be compatible with
+** index pIdx.
+*/
+static WhereTerm *whereScanInit(
+ WhereScan *pScan, /* The WhereScan object being initialized */
+ WhereClause *pWC, /* The WHERE clause to be scanned */
+ int iCur, /* Cursor to scan for */
+ int iColumn, /* Column to scan for */
+ u32 opMask, /* Operator(s) to scan for */
+ Index *pIdx /* Must be compatible with this index */
+){
+ int j = 0;
+
+ /* memset(pScan, 0, sizeof(*pScan)); */
+ pScan->pOrigWC = pWC;
+ pScan->pWC = pWC;
+ pScan->pIdxExpr = 0;
+ if( pIdx ){
+ j = iColumn;
+ iColumn = pIdx->aiColumn[j];
+ if( iColumn==XN_EXPR ) pScan->pIdxExpr = pIdx->aColExpr->a[j].pExpr;
+ }
+ if( pIdx && iColumn>=0 ){
+ pScan->idxaff = pIdx->pTable->aCol[iColumn].affinity;
+ pScan->zCollName = pIdx->azColl[j];
+ }else{
+ pScan->idxaff = 0;
+ pScan->zCollName = 0;
+ }
+ pScan->opMask = opMask;
+ pScan->k = 0;
+ pScan->aiCur[0] = iCur;
+ pScan->aiColumn[0] = iColumn;
+ pScan->nEquiv = 1;
+ pScan->iEquiv = 1;
+ return whereScanNext(pScan);
+}
+
+/*
+** 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.
+**
+** If pIdx!=0 then search for terms matching the iColumn-th column of pIdx
+** rather than the iColumn-th column of table iCur.
+**
+** The term returned might by Y=<expr> if there is another constraint in
+** the WHERE clause that specifies that X=Y. Any such constraints will be
+** identified by the WO_EQUIV bit in the pTerm->eOperator field. The
+** aiCur[]/iaColumn[] arrays hold X and all its equivalents. There are 11
+** slots in aiCur[]/aiColumn[] so that means we can look for X plus up to 10
+** other equivalent values. Hence a search for X will return <expr> if X=A1
+** and A1=A2 and A2=A3 and ... and A9=A10 and A10=<expr>.
+**
+** If there are multiple terms in the WHERE clause of the form "X <op> <expr>"
+** then try for the one with no dependencies on <expr> - in other words where
+** <expr> is a constant expression of some kind. Only return entries of
+** the form "X <op> Y" where Y is a column in another table if no terms of
+** the form "X <op> <const-expr>" exist. If no terms with a constant RHS
+** exist, try to return a term that does not use WO_EQUIV.
+*/
+SQLITE_PRIVATE WhereTerm *sqlite3WhereFindTerm(
+ 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 *pResult = 0;
+ WhereTerm *p;
+ WhereScan scan;
+
+ p = whereScanInit(&scan, pWC, iCur, iColumn, op, pIdx);
+ op &= WO_EQ|WO_IS;
+ while( p ){
+ if( (p->prereqRight & notReady)==0 ){
+ if( p->prereqRight==0 && (p->eOperator&op)!=0 ){
+ testcase( p->eOperator & WO_IS );
+ return p;
+ }
+ if( pResult==0 ) pResult = p;
+ }
+ p = whereScanNext(&scan);
+ }
+ return pResult;
+}
+
+/*
+** This function searches pList for an entry that matches the iCol-th column
+** of index pIdx.
**
** If such an expression is found, its index in pList->a[] is returned. If
** no expression is found, -1 is returned.
@@ -103934,7 +122972,7 @@ static int findIndexCol(
&& p->iTable==iBase
){
CollSeq *pColl = sqlite3ExprCollSeq(pParse, pList->a[i].pExpr);
- if( ALWAYS(pColl) && 0==sqlite3StrICmp(pColl->zName, zColl) ){
+ if( pColl && 0==sqlite3StrICmp(pColl->zName, zColl) ){
return i;
}
}
@@ -103944,76 +122982,36 @@ static int findIndexCol(
}
/*
-** 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".
+** Return TRUE if the iCol-th column of index pIdx is NOT NULL
*/
-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);
- }
+static int indexColumnNotNull(Index *pIdx, int iCol){
+ int j;
+ assert( pIdx!=0 );
+ assert( iCol>=0 && iCol<pIdx->nColumn );
+ j = pIdx->aiColumn[iCol];
+ if( j>=0 ){
+ return pIdx->pTable->aCol[j].notNull;
+ }else if( j==(-1) ){
+ return 1;
+ }else{
+ assert( j==(-2) );
+ return 0; /* Assume an indexed expression can always yield a NULL */
- 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.
+** is redundant.
+**
+** A DISTINCT list is redundant if any subset of the columns in the
+** DISTINCT list are collectively unique and individually non-null.
*/
static int isDistinctRedundant(
- Parse *pParse,
- SrcList *pTabList,
- WhereClause *pWC,
- ExprList *pDistinct
+ Parse *pParse, /* Parsing context */
+ SrcList *pTabList, /* The FROM clause */
+ WhereClause *pWC, /* The WHERE clause */
+ ExprList *pDistinct /* The result set that needs to be DISTINCT */
){
Table *pTab;
Index *pIdx;
@@ -104050,17 +123048,14 @@ static int isDistinctRedundant(
** 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( !IsUniqueIndex(pIdx) ) continue;
+ for(i=0; i<pIdx->nKeyCol; i++){
+ if( 0==sqlite3WhereFindTerm(pWC, iBase, i, ~(Bitmask)0, WO_EQ, pIdx) ){
+ if( findIndexCol(pParse, pDistinct, iBase, pIdx, i)<0 ) break;
+ if( indexColumnNotNull(pIdx, i)==0 ) break;
}
}
- if( i==pIdx->nColumn ){
+ if( i==pIdx->nKeyCol ){
/* This index implies that the DISTINCT qualifier is redundant. */
return 1;
}
@@ -104069,21 +123064,55 @@ static int isDistinctRedundant(
return 0;
}
+
+/*
+** Estimate the logarithm of the input value to base 2.
+*/
+static LogEst estLog(LogEst N){
+ return N<=10 ? 0 : sqlite3LogEst(N) - 33;
+}
+
/*
-** 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.
+** Convert OP_Column opcodes to OP_Copy in previously generated code.
+**
+** This routine runs over generated VDBE code and translates OP_Column
+** opcodes into OP_Copy when the table is being accessed via co-routine
+** instead of via table lookup.
+**
+** If the bIncrRowid parameter is 0, then any OP_Rowid instructions on
+** cursor iTabCur are transformed into OP_Null. Or, if bIncrRowid is non-zero,
+** then each OP_Rowid is transformed into an instruction to increment the
+** value stored in its output register.
*/
-static double estLog(double N){
- double logN = 1;
- double x = 10;
- while( N>x ){
- logN += 1;
- x *= 10;
+static void translateColumnToCopy(
+ Vdbe *v, /* The VDBE containing code to translate */
+ int iStart, /* Translate from this opcode to the end */
+ int iTabCur, /* OP_Column/OP_Rowid references to this table */
+ int iRegister, /* The first column is in this register */
+ int bIncrRowid /* If non-zero, transform OP_rowid to OP_AddImm(1) */
+){
+ VdbeOp *pOp = sqlite3VdbeGetOp(v, iStart);
+ int iEnd = sqlite3VdbeCurrentAddr(v);
+ for(; iStart<iEnd; iStart++, pOp++){
+ if( pOp->p1!=iTabCur ) continue;
+ if( pOp->opcode==OP_Column ){
+ pOp->opcode = OP_Copy;
+ pOp->p1 = pOp->p2 + iRegister;
+ pOp->p2 = pOp->p3;
+ pOp->p3 = 0;
+ }else if( pOp->opcode==OP_Rowid ){
+ if( bIncrRowid ){
+ /* Increment the value stored in the P2 operand of the OP_Rowid. */
+ pOp->opcode = OP_AddImm;
+ pOp->p1 = pOp->p2;
+ pOp->p2 = 1;
+ }else{
+ pOp->opcode = OP_Null;
+ pOp->p1 = 0;
+ pOp->p3 = 0;
+ }
+ }
}
- return logN;
}
/*
@@ -104092,7 +123121,7 @@ static double estLog(double N){
** SQLITE_TEST or SQLITE_DEBUG are defined, then these routines
** are no-ops.
*/
-#if !defined(SQLITE_OMIT_VIRTUALTABLE) && defined(SQLITE_DEBUG)
+#if !defined(SQLITE_OMIT_VIRTUALTABLE) && defined(WHERETRACE_ENABLED)
static void TRACE_IDX_INPUTS(sqlite3_index_info *p){
int i;
if( !sqlite3WhereTrace ) return;
@@ -104124,113 +123153,13 @@ static void TRACE_IDX_OUTPUTS(sqlite3_index_info *p){
sqlite3DebugPrintf(" idxStr=%s\n", p->idxStr);
sqlite3DebugPrintf(" orderByConsumed=%d\n", p->orderByConsumed);
sqlite3DebugPrintf(" estimatedCost=%g\n", p->estimatedCost);
+ sqlite3DebugPrintf(" estimatedRows=%lld\n", p->estimatedRows);
}
#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
@@ -104244,90 +123173,16 @@ static int termCanDriveIndex(
){
char aff;
if( pTerm->leftCursor!=pSrc->iCursor ) return 0;
- if( pTerm->eOperator!=WO_EQ ) return 0;
+ if( (pTerm->eOperator & (WO_EQ|WO_IS))==0 ) return 0;
if( (pTerm->prereqRight & notReady)!=0 ) return 0;
+ if( pTerm->u.leftColumn<0 ) return 0;
aff = pSrc->pTab->aCol[pTerm->u.leftColumn].affinity;
if( !sqlite3IndexAffinityOk(pTerm->pExpr, aff) ) return 0;
+ testcase( pTerm->pExpr->op==TK_IS );
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
/*
@@ -104342,50 +123197,79 @@ static void constructAutomaticIndex(
Bitmask notReady, /* Mask of cursors that are not available */
WhereLevel *pLevel /* Write new index here */
){
- int nColumn; /* Number of columns in the constructed index */
+ int nKeyCol; /* 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 */
+ WhereLoop *pLoop; /* The Loop object */
+ char *zNotUsed; /* Extra space on the end of pIdx */
Bitmask idxCols; /* Bitmap of columns used for indexing */
Bitmask extraCols; /* Bitmap of additional columns */
+ u8 sentWarning = 0; /* True if a warnning has been issued */
+ Expr *pPartial = 0; /* Partial Index Expression */
+ int iContinue = 0; /* Jump here to skip excluded rows */
+ struct SrcList_item *pTabItem; /* FROM clause term being indexed */
+ int addrCounter = 0; /* Address where integer counter is initialized */
+ int regBase; /* Array of registers where record is assembled */
/* 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);
+ addrInit = sqlite3CodeOnce(pParse); VdbeCoverage(v);
/* Count the number of columns that will be added to the index
** and used to match WHERE clause constraints */
- nColumn = 0;
+ nKeyCol = 0;
pTable = pSrc->pTab;
pWCEnd = &pWC->a[pWC->nTerm];
+ pLoop = pLevel->pWLoop;
idxCols = 0;
for(pTerm=pWC->a; pTerm<pWCEnd; pTerm++){
+ Expr *pExpr = pTerm->pExpr;
+ assert( !ExprHasProperty(pExpr, EP_FromJoin) /* prereq always non-zero */
+ || pExpr->iRightJoinTable!=pSrc->iCursor /* for the right-hand */
+ || pLoop->prereq!=0 ); /* table of a LEFT JOIN */
+ if( pLoop->prereq==0
+ && (pTerm->wtFlags & TERM_VIRTUAL)==0
+ && !ExprHasProperty(pExpr, EP_FromJoin)
+ && sqlite3ExprIsTableConstant(pExpr, pSrc->iCursor) ){
+ pPartial = sqlite3ExprAnd(pParse->db, pPartial,
+ sqlite3ExprDup(pParse->db, pExpr, 0));
+ }
if( termCanDriveIndex(pTerm, pSrc, notReady) ){
int iCol = pTerm->u.leftColumn;
- Bitmask cMask = iCol>=BMS ? ((Bitmask)1)<<(BMS-1) : ((Bitmask)1)<<iCol;
+ Bitmask cMask = iCol>=BMS ? MASKBIT(BMS-1) : MASKBIT(iCol);
testcase( iCol==BMS );
testcase( iCol==BMS-1 );
+ if( !sentWarning ){
+ sqlite3_log(SQLITE_WARNING_AUTOINDEX,
+ "automatic index on %s(%s)", pTable->zName,
+ pTable->aCol[iCol].zName);
+ sentWarning = 1;
+ }
if( (idxCols & cMask)==0 ){
- nColumn++;
+ if( whereLoopResize(pParse->db, pLoop, nKeyCol+1) ){
+ goto end_auto_index_create;
+ }
+ pLoop->aLTerm[nKeyCol++] = pTerm;
idxCols |= cMask;
}
}
}
- assert( nColumn>0 );
- pLevel->plan.nEq = nColumn;
+ assert( nKeyCol>0 );
+ pLoop->u.btree.nEq = pLoop->nLTerm = nKeyCol;
+ pLoop->wsFlags = WHERE_COLUMN_EQ | WHERE_IDX_ONLY | WHERE_INDEXED
+ | WHERE_AUTO_INDEX;
/* Count the number of additional columns needed to create a
** covering index. A "covering index" is an index that contains all
@@ -104395,88 +123279,113 @@ static void constructAutomaticIndex(
** 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;
+ extraCols = pSrc->colUsed & (~idxCols | MASKBIT(BMS-1));
+ mxBitCol = MIN(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( extraCols & MASKBIT(i) ) nKeyCol++;
}
- if( pSrc->colUsed & (((Bitmask)1)<<(BMS-1)) ){
- nColumn += pTable->nCol - BMS + 1;
+ if( pSrc->colUsed & MASKBIT(BMS-1) ){
+ nKeyCol += 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 = sqlite3AllocateIndexObject(pParse->db, nKeyCol+1, 0, &zNotUsed);
+ if( pIdx==0 ) goto end_auto_index_create;
+ pLoop->u.btree.pIndex = pIdx;
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;
+ Bitmask cMask = iCol>=BMS ? MASKBIT(BMS-1) : MASKBIT(iCol);
+ testcase( iCol==BMS-1 );
+ testcase( iCol==BMS );
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";
+ pIdx->azColl[n] = pColl ? pColl->zName : sqlite3StrBINARY;
n++;
}
}
}
- assert( (u32)n==pLevel->plan.nEq );
+ assert( (u32)n==pLoop->u.btree.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) ){
+ if( extraCols & MASKBIT(i) ){
pIdx->aiColumn[n] = i;
- pIdx->azColl[n] = "BINARY";
+ pIdx->azColl[n] = sqlite3StrBINARY;
n++;
}
}
- if( pSrc->colUsed & (((Bitmask)1)<<(BMS-1)) ){
+ if( pSrc->colUsed & MASKBIT(BMS-1) ){
for(i=BMS-1; i<pTable->nCol; i++){
pIdx->aiColumn[n] = i;
- pIdx->azColl[n] = "BINARY";
+ pIdx->azColl[n] = sqlite3StrBINARY;
n++;
}
}
- assert( n==nColumn );
+ assert( n==nKeyCol );
+ pIdx->aiColumn[n] = XN_ROWID;
+ pIdx->azColl[n] = sqlite3StrBINARY;
/* 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);
+ pLevel->iIdxCur = pParse->nTab++;
+ sqlite3VdbeAddOp2(v, OP_OpenAutoindex, pLevel->iIdxCur, nKeyCol+1);
+ sqlite3VdbeSetP4KeyInfo(pParse, pIdx);
VdbeComment((v, "for %s", pTable->zName));
/* Fill the automatic index with content */
- addrTop = sqlite3VdbeAddOp1(v, OP_Rewind, pLevel->iTabCur);
+ sqlite3ExprCachePush(pParse);
+ pTabItem = &pWC->pWInfo->pTabList->a[pLevel->iFrom];
+ if( pTabItem->fg.viaCoroutine ){
+ int regYield = pTabItem->regReturn;
+ addrCounter = sqlite3VdbeAddOp2(v, OP_Integer, 0, 0);
+ sqlite3VdbeAddOp3(v, OP_InitCoroutine, regYield, 0, pTabItem->addrFillSub);
+ addrTop = sqlite3VdbeAddOp1(v, OP_Yield, regYield);
+ VdbeCoverage(v);
+ VdbeComment((v, "next row of \"%s\"", pTabItem->pTab->zName));
+ }else{
+ addrTop = sqlite3VdbeAddOp1(v, OP_Rewind, pLevel->iTabCur); VdbeCoverage(v);
+ }
+ if( pPartial ){
+ iContinue = sqlite3VdbeMakeLabel(v);
+ sqlite3ExprIfFalse(pParse, pPartial, iContinue, SQLITE_JUMPIFNULL);
+ pLoop->wsFlags |= WHERE_PARTIALIDX;
+ }
regRecord = sqlite3GetTempReg(pParse);
- sqlite3GenerateIndexKey(pParse, pIdx, pLevel->iTabCur, regRecord, 1);
+ regBase = sqlite3GenerateIndexKey(
+ pParse, pIdx, pLevel->iTabCur, regRecord, 0, 0, 0, 0
+ );
sqlite3VdbeAddOp2(v, OP_IdxInsert, pLevel->iIdxCur, regRecord);
sqlite3VdbeChangeP5(v, OPFLAG_USESEEKRESULT);
- sqlite3VdbeAddOp2(v, OP_Next, pLevel->iTabCur, addrTop+1);
+ if( pPartial ) sqlite3VdbeResolveLabel(v, iContinue);
+ if( pTabItem->fg.viaCoroutine ){
+ sqlite3VdbeChangeP2(v, addrCounter, regBase+n);
+ translateColumnToCopy(v, addrTop, pLevel->iTabCur, pTabItem->regResult, 1);
+ sqlite3VdbeGoto(v, addrTop);
+ pTabItem->fg.viaCoroutine = 0;
+ }else{
+ sqlite3VdbeAddOp2(v, OP_Next, pLevel->iTabCur, addrTop+1); VdbeCoverage(v);
+ }
sqlite3VdbeChangeP5(v, SQLITE_STMTSTATUS_AUTOINDEX);
sqlite3VdbeJumpHere(v, addrTop);
sqlite3ReleaseTempReg(pParse, regRecord);
+ sqlite3ExprCachePop(pParse);
/* Jump here when skipping the initialization */
sqlite3VdbeJumpHere(v, addrInit);
+
+end_auto_index_create:
+ sqlite3ExprDelete(pParse->db, pPartial);
}
#endif /* SQLITE_OMIT_AUTOMATIC_INDEX */
@@ -104486,11 +123395,13 @@ static void constructAutomaticIndex(
** 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;
+static sqlite3_index_info *allocateIndexInfo(
+ Parse *pParse,
+ WhereClause *pWC,
+ Bitmask mUnusable, /* Ignore terms with these prereqs */
+ struct SrcList_item *pSrc,
+ ExprList *pOrderBy
+){
int i, j;
int nTerm;
struct sqlite3_index_constraint *pIdxCons;
@@ -104500,17 +123411,19 @@ static sqlite3_index_info *allocateIndexInfo(WhereBestIdx *p){
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->prereqRight & mUnusable ) continue;
+ assert( IsPowerOfTwo(pTerm->eOperator & ~WO_EQUIV) );
+ testcase( pTerm->eOperator & WO_IN );
+ testcase( pTerm->eOperator & WO_ISNULL );
+ testcase( pTerm->eOperator & WO_IS );
+ testcase( pTerm->eOperator & WO_ALL );
+ if( (pTerm->eOperator & ~(WO_ISNULL|WO_EQUIV|WO_IS))==0 ) continue;
if( pTerm->wtFlags & TERM_VNULL ) continue;
+ assert( pTerm->u.leftColumn>=(-1) );
nTerm++;
}
@@ -104537,7 +123450,6 @@ static sqlite3_index_info *allocateIndexInfo(WhereBestIdx *p){
+ sizeof(*pIdxOrderBy)*nOrderBy );
if( pIdxInfo==0 ){
sqlite3ErrorMsg(pParse, "out of memory");
- /* (double)0 In case of SQLITE_OMIT_FLOATING_POINT... */
return 0;
}
@@ -104557,15 +123469,25 @@ static sqlite3_index_info *allocateIndexInfo(WhereBestIdx *p){
pUsage;
for(i=j=0, pTerm=pWC->a; i<pWC->nTerm; i++, pTerm++){
+ u8 op;
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->prereqRight & mUnusable ) continue;
+ assert( IsPowerOfTwo(pTerm->eOperator & ~WO_EQUIV) );
+ testcase( pTerm->eOperator & WO_IN );
+ testcase( pTerm->eOperator & WO_IS );
+ testcase( pTerm->eOperator & WO_ISNULL );
+ testcase( pTerm->eOperator & WO_ALL );
+ if( (pTerm->eOperator & ~(WO_ISNULL|WO_EQUIV|WO_IS))==0 ) continue;
if( pTerm->wtFlags & TERM_VNULL ) continue;
+ assert( pTerm->u.leftColumn>=(-1) );
pIdxCons[j].iColumn = pTerm->u.leftColumn;
pIdxCons[j].iTermOffset = i;
- pIdxCons[j].op = (u8)pTerm->eOperator;
+ op = (u8)pTerm->eOperator & WO_ALL;
+ if( op==WO_IN ) op = WO_EQ;
+ if( op==WO_MATCH ){
+ op = pTerm->eMatchOp;
+ }
+ pIdxCons[j].op = op;
/* 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. */
@@ -104575,7 +123497,7 @@ static sqlite3_index_info *allocateIndexInfo(WhereBestIdx *p){
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) );
+ assert( pTerm->eOperator & (WO_IN|WO_EQ|WO_LT|WO_LE|WO_GT|WO_GE|WO_MATCH) );
j++;
}
for(i=0; i<nOrderBy; i++){
@@ -104590,8 +123512,8 @@ static sqlite3_index_info *allocateIndexInfo(WhereBestIdx *p){
/*
** 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.
+** method of the virtual table with the sqlite3_index_info object that
+** comes in as the 3rd argument to this function.
**
** 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
@@ -104606,7 +123528,6 @@ static int vtabBestIndex(Parse *pParse, Table *pTab, sqlite3_index_info *p){
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);
@@ -104632,304 +123553,183 @@ static int vtabBestIndex(Parse *pParse, Table *pTab, sqlite3_index_info *p){
return pParse->nErr;
}
+#endif /* !defined(SQLITE_OMIT_VIRTUALTABLE) */
-
-/*
-** 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
+#ifdef SQLITE_ENABLE_STAT3_OR_STAT4
/*
** 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
+** aStat[0] Est. number of rows less than pRec
+** aStat[1] Est. number of rows equal to pRec
**
-** Return SQLITE_OK on success.
+** Return the index of the sample that is the smallest sample that
+** is greater than or equal to pRec. Note that this index is not an index
+** into the aSample[] array - it is an index into a virtual set of samples
+** based on the contents of aSample[] and the number of fields in record
+** pRec.
*/
static int whereKeyStats(
Parse *pParse, /* Database connection */
Index *pIdx, /* Index to consider domain of */
- sqlite3_value *pVal, /* Value to consider */
+ UnpackedRecord *pRec, /* Vector of values 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;
+ IndexSample *aSample = pIdx->aSample;
+ int iCol; /* Index of required stats in anEq[] etc. */
+ int i; /* Index of first sample >= pRec */
+ int iSample; /* Smallest sample larger than or equal to pRec */
+ int iMin = 0; /* Smallest sample not yet tested */
+ int iTest; /* Next sample to test */
+ int res; /* Result of comparison operation */
+ int nField; /* Number of fields in pRec */
+ tRowcnt iLower = 0; /* anLt[] + anEq[] of largest sample pRec is > */
- assert( roundUp==0 || roundUp==1 );
+#ifndef SQLITE_DEBUG
+ UNUSED_PARAMETER( pParse );
+#endif
+ assert( pRec!=0 );
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;
+ assert( pRec->nField>0 && pRec->nField<=pIdx->nSampleCol );
+
+ /* Do a binary search to find the first sample greater than or equal
+ ** to pRec. If pRec contains a single field, the set of samples to search
+ ** is simply the aSample[] array. If the samples in aSample[] contain more
+ ** than one fields, all fields following the first are ignored.
+ **
+ ** If pRec contains N fields, where N is more than one, then as well as the
+ ** samples in aSample[] (truncated to N fields), the search also has to
+ ** consider prefixes of those samples. For example, if the set of samples
+ ** in aSample is:
+ **
+ ** aSample[0] = (a, 5)
+ ** aSample[1] = (a, 10)
+ ** aSample[2] = (b, 5)
+ ** aSample[3] = (c, 100)
+ ** aSample[4] = (c, 105)
+ **
+ ** Then the search space should ideally be the samples above and the
+ ** unique prefixes [a], [b] and [c]. But since that is hard to organize,
+ ** the code actually searches this set:
+ **
+ ** 0: (a)
+ ** 1: (a, 5)
+ ** 2: (a, 10)
+ ** 3: (a, 10)
+ ** 4: (b)
+ ** 5: (b, 5)
+ ** 6: (c)
+ ** 7: (c, 100)
+ ** 8: (c, 105)
+ ** 9: (c, 105)
+ **
+ ** For each sample in the aSample[] array, N samples are present in the
+ ** effective sample array. In the above, samples 0 and 1 are based on
+ ** sample aSample[0]. Samples 2 and 3 on aSample[1] etc.
+ **
+ ** Often, sample i of each block of N effective samples has (i+1) fields.
+ ** Except, each sample may be extended to ensure that it is greater than or
+ ** equal to the previous sample in the array. For example, in the above,
+ ** sample 2 is the first sample of a block of N samples, so at first it
+ ** appears that it should be 1 field in size. However, that would make it
+ ** smaller than sample 1, so the binary search would not work. As a result,
+ ** it is extended to two fields. The duplicates that this creates do not
+ ** cause any problems.
+ */
+ nField = pRec->nField;
+ iCol = 0;
+ iSample = pIdx->nSample * nField;
+ do{
+ int iSamp; /* Index in aSample[] of test sample */
+ int n; /* Number of fields in test sample */
+
+ iTest = (iMin+iSample)/2;
+ iSamp = iTest / nField;
+ if( iSamp>0 ){
+ /* The proposed effective sample is a prefix of sample aSample[iSamp].
+ ** Specifically, the shortest prefix of at least (1 + iTest%nField)
+ ** fields that is greater than the previous effective sample. */
+ for(n=(iTest % nField) + 1; n<nField; n++){
+ if( aSample[iSamp-1].anLt[n-1]!=aSample[iSamp].anLt[n-1] ) break;
}
+ }else{
+ n = iTest + 1;
+ }
+
+ pRec->nField = n;
+ res = sqlite3VdbeRecordCompare(aSample[iSamp].n, aSample[iSamp].p, pRec);
+ if( res<0 ){
+ iLower = aSample[iSamp].anLt[n-1] + aSample[iSamp].anEq[n-1];
+ iMin = iTest+1;
+ }else if( res==0 && n<nField ){
+ iLower = aSample[iSamp].anLt[n-1];
+ iMin = iTest+1;
+ res = -1;
+ }else{
+ iSample = iTest;
+ iCol = n-1;
}
- 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 );
+ }while( res && iMin<iSample );
+ i = iSample / nField;
+
+#ifdef SQLITE_DEBUG
+ /* The following assert statements check that the binary search code
+ ** above found the right answer. This block serves no purpose other
+ ** than to invoke the asserts. */
+ if( pParse->db->mallocFailed==0 ){
+ if( res==0 ){
+ /* If (res==0) is true, then pRec must be equal to sample i. */
+ assert( i<pIdx->nSample );
+ assert( iCol==nField-1 );
+ pRec->nField = nField;
+ assert( 0==sqlite3VdbeRecordCompare(aSample[i].n, aSample[i].p, pRec)
+ || pParse->db->mallocFailed
+ );
+ }else{
+ /* Unless i==pIdx->nSample, indicating that pRec is larger than
+ ** all samples in the aSample[] array, pRec must be smaller than the
+ ** (iCol+1) field prefix of sample i. */
+ assert( i<=pIdx->nSample && i>=0 );
+ pRec->nField = iCol+1;
+ assert( i==pIdx->nSample
+ || sqlite3VdbeRecordCompare(aSample[i].n, aSample[i].p, pRec)>0
+ || pParse->db->mallocFailed );
+
+ /* if i==0 and iCol==0, then record pRec is smaller than all samples
+ ** in the aSample[] array. Otherwise, if (iCol>0) then pRec must
+ ** be greater than or equal to the (iCol) field prefix of sample i.
+ ** If (i>0), then pRec must also be greater than sample (i-1). */
+ if( iCol>0 ){
+ pRec->nField = iCol;
+ assert( sqlite3VdbeRecordCompare(aSample[i].n, aSample[i].p, pRec)<=0
+ || pParse->db->mallocFailed );
}
- 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;
- }
+ if( i>0 ){
+ pRec->nField = nField;
+ assert( sqlite3VdbeRecordCompare(aSample[i-1].n, aSample[i-1].p, pRec)<0
+ || pParse->db->mallocFailed );
}
}
}
+#endif /* ifdef SQLITE_DEBUG */
- /* 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;
+ if( res==0 ){
+ /* Record pRec is equal to sample i */
+ assert( iCol==nField-1 );
+ aStat[0] = aSample[i].anLt[iCol];
+ aStat[1] = aSample[i].anEq[iCol];
}else{
- tRowcnt iLower, iUpper, iGap;
- if( i==0 ){
- iLower = 0;
- iUpper = aSample[0].nLt;
+ /* At this point, the (iCol+1) field prefix of aSample[i] is the first
+ ** sample that is greater than pRec. Or, if i==pIdx->nSample then pRec
+ ** is larger than all samples in the array. */
+ tRowcnt iUpper, iGap;
+ if( i>=pIdx->nSample ){
+ iUpper = sqlite3LogEstToInt(pIdx->aiRowLogEst[0]);
}else{
- iUpper = i>=pIdx->nSample ? n : aSample[i].nLt;
- iLower = aSample[i-1].nEq + aSample[i-1].nLt;
+ iUpper = aSample[i].anLt[iCol];
}
- aStat[1] = pIdx->avgEq;
+
if( iLower>=iUpper ){
iGap = 0;
}else{
@@ -104941,45 +123741,160 @@ static int whereKeyStats(
iGap = iGap/3;
}
aStat[0] = iLower + iGap;
+ aStat[1] = pIdx->aAvgEq[iCol];
}
- return SQLITE_OK;
+
+ /* Restore the pRec->nField value before returning. */
+ pRec->nField = nField;
+ return i;
}
-#endif /* SQLITE_ENABLE_STAT3 */
+#endif /* SQLITE_ENABLE_STAT3_OR_STAT4 */
/*
-** 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 it is not NULL, pTerm is a term that provides an upper or lower
+** bound on a range scan. Without considering pTerm, it is estimated
+** that the scan will visit nNew rows. This function returns the number
+** estimated to be visited after taking pTerm into account.
**
-** 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 the user explicitly specified a likelihood() value for this term,
+** then the return value is the likelihood multiplied by the number of
+** input rows. Otherwise, this function assumes that an "IS NOT NULL" term
+** has a likelihood of 0.50, and any other term a likelihood of 0.25.
+*/
+static LogEst whereRangeAdjust(WhereTerm *pTerm, LogEst nNew){
+ LogEst nRet = nNew;
+ if( pTerm ){
+ if( pTerm->truthProb<=0 ){
+ nRet += pTerm->truthProb;
+ }else if( (pTerm->wtFlags & TERM_VNULL)==0 ){
+ nRet -= 20; assert( 20==sqlite3LogEst(4) );
+ }
+ }
+ return nRet;
+}
+
+
+#ifdef SQLITE_ENABLE_STAT3_OR_STAT4
+/*
+** Return the affinity for a single column of an index.
+*/
+static char sqlite3IndexColumnAffinity(sqlite3 *db, Index *pIdx, int iCol){
+ assert( iCol>=0 && iCol<pIdx->nColumn );
+ if( !pIdx->zColAff ){
+ if( sqlite3IndexAffinityStr(db, pIdx)==0 ) return SQLITE_AFF_BLOB;
+ }
+ return pIdx->zColAff[iCol];
+}
+#endif
+
+
+#ifdef SQLITE_ENABLE_STAT3_OR_STAT4
+/*
+** This function is called to estimate the number of rows visited by a
+** range-scan on a skip-scan index. For example:
+**
+** CREATE INDEX i1 ON t1(a, b, c);
+** SELECT * FROM t1 WHERE a=? AND c BETWEEN ? AND ?;
+**
+** Value pLoop->nOut is currently set to the estimated number of rows
+** visited for scanning (a=? AND b=?). This function reduces that estimate
+** by some factor to account for the (c BETWEEN ? AND ?) expression based
+** on the stat4 data for the index. this scan will be peformed multiple
+** times (once for each (a,b) combination that matches a=?) is dealt with
+** by the caller.
+**
+** It does this by scanning through all stat4 samples, comparing values
+** extracted from pLower and pUpper with the corresponding column in each
+** sample. If L and U are the number of samples found to be less than or
+** equal to the values extracted from pLower and pUpper respectively, and
+** N is the total number of samples, the pLoop->nOut value is adjusted
+** as follows:
+**
+** nOut = nOut * ( min(U - L, 1) / N )
**
-** If neither of the above apply, set *pp to NULL.
+** If pLower is NULL, or a value cannot be extracted from the term, L is
+** set to zero. If pUpper is NULL, or a value cannot be extracted from it,
+** U is set to N.
**
-** If an error occurs, return an error code. Otherwise, SQLITE_OK.
+** Normally, this function sets *pbDone to 1 before returning. However,
+** if no value can be extracted from either pLower or pUpper (and so the
+** estimate of the number of rows delivered remains unchanged), *pbDone
+** is left as is.
+**
+** If an error occurs, an SQLite error code is returned. Otherwise,
+** SQLITE_OK.
*/
-#ifdef SQLITE_ENABLE_STAT3
-static int valueFromExpr(
- Parse *pParse,
- Expr *pExpr,
- u8 aff,
- sqlite3_value **pp
+static int whereRangeSkipScanEst(
+ Parse *pParse, /* Parsing & code generating context */
+ 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 */
+ WhereLoop *pLoop, /* Update the .nOut value of this loop */
+ int *pbDone /* Set to true if at least one expr. value extracted */
){
- 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;
+ Index *p = pLoop->u.btree.pIndex;
+ int nEq = pLoop->u.btree.nEq;
+ sqlite3 *db = pParse->db;
+ int nLower = -1;
+ int nUpper = p->nSample+1;
+ int rc = SQLITE_OK;
+ u8 aff = sqlite3IndexColumnAffinity(db, p, nEq);
+ CollSeq *pColl;
+
+ sqlite3_value *p1 = 0; /* Value extracted from pLower */
+ sqlite3_value *p2 = 0; /* Value extracted from pUpper */
+ sqlite3_value *pVal = 0; /* Value extracted from record */
+
+ pColl = sqlite3LocateCollSeq(pParse, p->azColl[nEq]);
+ if( pLower ){
+ rc = sqlite3Stat4ValueFromExpr(pParse, pLower->pExpr->pRight, aff, &p1);
+ nLower = 0;
+ }
+ if( pUpper && rc==SQLITE_OK ){
+ rc = sqlite3Stat4ValueFromExpr(pParse, pUpper->pExpr->pRight, aff, &p2);
+ nUpper = p2 ? 0 : p->nSample;
}
- return sqlite3ValueFromExpr(pParse->db, pExpr, SQLITE_UTF8, aff, pp);
+
+ if( p1 || p2 ){
+ int i;
+ int nDiff;
+ for(i=0; rc==SQLITE_OK && i<p->nSample; i++){
+ rc = sqlite3Stat4Column(db, p->aSample[i].p, p->aSample[i].n, nEq, &pVal);
+ if( rc==SQLITE_OK && p1 ){
+ int res = sqlite3MemCompare(p1, pVal, pColl);
+ if( res>=0 ) nLower++;
+ }
+ if( rc==SQLITE_OK && p2 ){
+ int res = sqlite3MemCompare(p2, pVal, pColl);
+ if( res>=0 ) nUpper++;
+ }
+ }
+ nDiff = (nUpper - nLower);
+ if( nDiff<=0 ) nDiff = 1;
+
+ /* If there is both an upper and lower bound specified, and the
+ ** comparisons indicate that they are close together, use the fallback
+ ** method (assume that the scan visits 1/64 of the rows) for estimating
+ ** the number of rows visited. Otherwise, estimate the number of rows
+ ** using the method described in the header comment for this function. */
+ if( nDiff!=1 || pUpper==0 || pLower==0 ){
+ int nAdjust = (sqlite3LogEst(p->nSample) - sqlite3LogEst(nDiff));
+ pLoop->nOut -= nAdjust;
+ *pbDone = 1;
+ WHERETRACE(0x10, ("range skip-scan regions: %u..%u adjust=%d est=%d\n",
+ nLower, nUpper, nAdjust*-1, pLoop->nOut));
+ }
+
+ }else{
+ assert( *pbDone==0 );
+ }
+
+ sqlite3ValueFree(p1);
+ sqlite3ValueFree(p2);
+ sqlite3ValueFree(pVal);
+
+ return rc;
}
-#endif
+#endif /* SQLITE_ENABLE_STAT3_OR_STAT4 */
/*
** This function is used to estimate the number of rows that will be visited
@@ -104996,97 +123911,189 @@ static int valueFromExpr(
** 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:
+** The value in (pBuilder->pNew->u.btree.nEq) is the number 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:
+** then nEq is set to 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.
+** then nEq is set to 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.
+** When this function is called, *pnOut is set to the sqlite3LogEst() of the
+** number of rows that the index scan is expected to visit without
+** considering the range constraints. If nEq is 0, then *pnOut is the number of
+** rows in the index. Assuming no error occurs, *pnOut is adjusted (reduced)
+** to account for the range constraints pLower and pUpper.
+**
+** In the absence of sqlite_stat4 ANALYZE data, or if such data cannot be
+** used, a single range inequality reduces the search space by a factor of 4.
+** and a pair of constraints (x>? AND x<?) reduces the expected number of
+** rows visited by a factor of 64.
*/
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 */
+ WhereLoopBuilder *pBuilder,
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 */
+ WhereLoop *pLoop /* Modify the .nOut and maybe .rRun fields */
){
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
- ){
+ int nOut = pLoop->nOut;
+ LogEst nNew;
+
+#ifdef SQLITE_ENABLE_STAT3_OR_STAT4
+ Index *p = pLoop->u.btree.pIndex;
+ int nEq = pLoop->u.btree.nEq;
+
+ if( p->nSample>0 && nEq<p->nSampleCol ){
+ if( nEq==pBuilder->nRecValid ){
+ UnpackedRecord *pRec = pBuilder->pRec;
+ tRowcnt a[2];
+ u8 aff;
+
+ /* Variable iLower will be set to the estimate of the number of rows in
+ ** the index that are less than the lower bound of the range query. The
+ ** lower bound being the concatenation of $P and $L, where $P is the
+ ** key-prefix formed by the nEq values matched against the nEq left-most
+ ** columns of the index, and $L is the value in pLower.
+ **
+ ** Or, if pLower is NULL or $L cannot be extracted from it (because it
+ ** is not a simple variable or literal value), the lower bound of the
+ ** range is $P. Due to a quirk in the way whereKeyStats() works, even
+ ** if $L is available, whereKeyStats() is called for both ($P) and
+ ** ($P:$L) and the larger of the two returned values is used.
+ **
+ ** Similarly, iUpper is to be set to the estimate of the number of rows
+ ** less than the upper bound of the range query. Where the upper bound
+ ** is either ($P) or ($P:$U). Again, even if $U is available, both values
+ ** of iUpper are requested of whereKeyStats() and the smaller used.
+ **
+ ** The number of rows between the two bounds is then just iUpper-iLower.
+ */
+ tRowcnt iLower; /* Rows less than the lower bound */
+ tRowcnt iUpper; /* Rows less than the upper bound */
+ int iLwrIdx = -2; /* aSample[] for the lower bound */
+ int iUprIdx = -1; /* aSample[] for the upper bound */
+
+ if( pRec ){
+ testcase( pRec->nField!=pBuilder->nRecValid );
+ pRec->nField = pBuilder->nRecValid;
+ }
+ aff = sqlite3IndexColumnAffinity(pParse->db, p, nEq);
+ assert( nEq!=p->nKeyCol || aff==SQLITE_AFF_INTEGER );
+ /* Determine iLower and iUpper using ($P) only. */
+ if( nEq==0 ){
+ iLower = 0;
+ iUpper = p->nRowEst0;
+ }else{
+ /* Note: this call could be optimized away - since the same values must
+ ** have been requested when testing key $P in whereEqualScanEst(). */
+ whereKeyStats(pParse, p, pRec, 0, a);
iLower = a[0];
- if( pLower->eOperator==WO_GT ) iLower += a[1];
+ iUpper = a[0] + a[1];
+ }
+
+ assert( pLower==0 || (pLower->eOperator & (WO_GT|WO_GE))!=0 );
+ assert( pUpper==0 || (pUpper->eOperator & (WO_LT|WO_LE))!=0 );
+ assert( p->aSortOrder!=0 );
+ if( p->aSortOrder[nEq] ){
+ /* The roles of pLower and pUpper are swapped for a DESC index */
+ SWAP(WhereTerm*, pLower, pUpper);
+ }
+
+ /* If possible, improve on the iLower estimate using ($P:$L). */
+ if( pLower ){
+ int bOk; /* True if value is extracted from pExpr */
+ Expr *pExpr = pLower->pExpr->pRight;
+ rc = sqlite3Stat4ProbeSetValue(pParse, p, &pRec, pExpr, aff, nEq, &bOk);
+ if( rc==SQLITE_OK && bOk ){
+ tRowcnt iNew;
+ iLwrIdx = whereKeyStats(pParse, p, pRec, 0, a);
+ iNew = a[0] + ((pLower->eOperator & (WO_GT|WO_LE)) ? a[1] : 0);
+ if( iNew>iLower ) iLower = iNew;
+ nOut--;
+ pLower = 0;
+ }
}
- 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];
+
+ /* If possible, improve on the iUpper estimate using ($P:$U). */
+ if( pUpper ){
+ int bOk; /* True if value is extracted from pExpr */
+ Expr *pExpr = pUpper->pExpr->pRight;
+ rc = sqlite3Stat4ProbeSetValue(pParse, p, &pRec, pExpr, aff, nEq, &bOk);
+ if( rc==SQLITE_OK && bOk ){
+ tRowcnt iNew;
+ iUprIdx = whereKeyStats(pParse, p, pRec, 1, a);
+ iNew = a[0] + ((pUpper->eOperator & (WO_GT|WO_LE)) ? a[1] : 0);
+ if( iNew<iUpper ) iUpper = iNew;
+ nOut--;
+ pUpper = 0;
+ }
}
- sqlite3ValueFree(pRangeVal);
- }
- if( rc==SQLITE_OK ){
- if( iUpper<=iLower ){
- *pRangeDiv = (double)p->aiRowEst[0];
- }else{
- *pRangeDiv = (double)p->aiRowEst[0]/(double)(iUpper - iLower);
+
+ pBuilder->pRec = pRec;
+ if( rc==SQLITE_OK ){
+ if( iUpper>iLower ){
+ nNew = sqlite3LogEst(iUpper - iLower);
+ /* TUNING: If both iUpper and iLower are derived from the same
+ ** sample, then assume they are 4x more selective. This brings
+ ** the estimated selectivity more in line with what it would be
+ ** if estimated without the use of STAT3/4 tables. */
+ if( iLwrIdx==iUprIdx ) nNew -= 20; assert( 20==sqlite3LogEst(4) );
+ }else{
+ nNew = 10; assert( 10==sqlite3LogEst(2) );
+ }
+ if( nNew<nOut ){
+ nOut = nNew;
+ }
+ WHERETRACE(0x10, ("STAT4 range scan: %u..%u est=%d\n",
+ (u32)iLower, (u32)iUpper, nOut));
}
- WHERETRACE(("range scan regions: %u..%u div=%g\n",
- (u32)iLower, (u32)iUpper, *pRangeDiv));
- return SQLITE_OK;
+ }else{
+ int bDone = 0;
+ rc = whereRangeSkipScanEst(pParse, pLower, pUpper, pLoop, &bDone);
+ if( bDone ) return rc;
}
}
#else
UNUSED_PARAMETER(pParse);
- UNUSED_PARAMETER(p);
- UNUSED_PARAMETER(nEq);
-#endif
+ UNUSED_PARAMETER(pBuilder);
assert( pLower || pUpper );
- *pRangeDiv = (double)1;
- if( pLower && (pLower->wtFlags & TERM_VNULL)==0 ) *pRangeDiv *= (double)4;
- if( pUpper ) *pRangeDiv *= (double)4;
+#endif
+ assert( pUpper==0 || (pUpper->wtFlags & TERM_VNULL)==0 );
+ nNew = whereRangeAdjust(pLower, nOut);
+ nNew = whereRangeAdjust(pUpper, nNew);
+
+ /* TUNING: If there is both an upper and lower limit and neither limit
+ ** has an application-defined likelihood(), assume the range is
+ ** reduced by an additional 75%. This means that, by default, an open-ended
+ ** range query (e.g. col > ?) is assumed to match 1/4 of the rows in the
+ ** index. While a closed range (e.g. col BETWEEN ? AND ?) is estimated to
+ ** match 1/64 of the index. */
+ if( pLower && pLower->truthProb>0 && pUpper && pUpper->truthProb>0 ){
+ nNew -= 20;
+ }
+
+ nOut -= (pLower!=0) + (pUpper!=0);
+ if( nNew<10 ) nNew = 10;
+ if( nNew<nOut ) nOut = nNew;
+#if defined(WHERETRACE_ENABLED)
+ if( pLoop->nOut>nOut ){
+ WHERETRACE(0x10,("Range scan lowers nOut from %d to %d\n",
+ pLoop->nOut, nOut));
+ }
+#endif
+ pLoop->nOut = (LogEst)nOut;
return rc;
}
-#ifdef SQLITE_ENABLE_STAT3
+#ifdef SQLITE_ENABLE_STAT3_OR_STAT4
/*
** Estimate the number of rows that will be returned based on
** an equality constraint x=VALUE and where that VALUE occurs in
@@ -105106,37 +124113,53 @@ static int whereRangeScanEst(
*/
static int whereEqualScanEst(
Parse *pParse, /* Parsing & code generating context */
- Index *p, /* The index whose left-most column is pTerm */
+ WhereLoopBuilder *pBuilder,
Expr *pExpr, /* Expression for VALUE in the x=VALUE constraint */
- double *pnRow /* Write the revised row estimate here */
+ tRowcnt *pnRow /* Write the revised row estimate here */
){
- sqlite3_value *pRhs = 0; /* VALUE on right-hand side of pTerm */
+ Index *p = pBuilder->pNew->u.btree.pIndex;
+ int nEq = pBuilder->pNew->u.btree.nEq;
+ UnpackedRecord *pRec = pBuilder->pRec;
u8 aff; /* Column affinity */
int rc; /* Subfunction return code */
tRowcnt a[2]; /* Statistics */
+ int bOk;
+ assert( nEq>=1 );
+ assert( nEq<=p->nColumn );
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);
+ assert( pBuilder->nRecValid<nEq );
+
+ /* If values are not available for all fields of the index to the left
+ ** of this one, no estimate can be made. Return SQLITE_NOTFOUND. */
+ if( pBuilder->nRecValid<(nEq-1) ){
+ return SQLITE_NOTFOUND;
}
- 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];
+
+ /* This is an optimization only. The call to sqlite3Stat4ProbeSetValue()
+ ** below would return the same value. */
+ if( nEq>=p->nColumn ){
+ *pnRow = 1;
+ return SQLITE_OK;
}
-whereEqualScanEst_cancel:
- sqlite3ValueFree(pRhs);
+
+ aff = sqlite3IndexColumnAffinity(pParse->db, p, nEq-1);
+ rc = sqlite3Stat4ProbeSetValue(pParse, p, &pRec, pExpr, aff, nEq-1, &bOk);
+ pBuilder->pRec = pRec;
+ if( rc!=SQLITE_OK ) return rc;
+ if( bOk==0 ) return SQLITE_NOTFOUND;
+ pBuilder->nRecValid = nEq;
+
+ whereKeyStats(pParse, p, pRec, 0, a);
+ WHERETRACE(0x10,("equality scan regions: %d\n", (int)a[1]));
+ *pnRow = a[1];
+
return rc;
}
-#endif /* defined(SQLITE_ENABLE_STAT3) */
+#endif /* SQLITE_ENABLE_STAT3_OR_STAT4 */
-#ifdef SQLITE_ENABLE_STAT3
+#ifdef SQLITE_ENABLE_STAT3_OR_STAT4
/*
** Estimate the number of rows that will be returned based on
** an IN constraint where the right-hand side of the IN operator
@@ -105155,2066 +124178,2324 @@ whereEqualScanEst_cancel:
*/
static int whereInScanEst(
Parse *pParse, /* Parsing & code generating context */
- Index *p, /* The index whose left-most column is pTerm */
+ WhereLoopBuilder *pBuilder,
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 */
+ tRowcnt *pnRow /* Write the revised row estimate here */
+){
+ Index *p = pBuilder->pNew->u.btree.pIndex;
+ i64 nRow0 = sqlite3LogEstToInt(p->aiRowLogEst[0]);
+ int nRecValid = pBuilder->nRecValid;
+ int rc = SQLITE_OK; /* Subfunction return code */
+ tRowcnt nEst; /* Number of rows for a single term */
+ tRowcnt nRowEst = 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);
+ nEst = nRow0;
+ rc = whereEqualScanEst(pParse, pBuilder, pList->a[i].pExpr, &nEst);
nRowEst += nEst;
+ pBuilder->nRecValid = nRecValid;
}
+
if( rc==SQLITE_OK ){
- if( nRowEst > p->aiRowEst[0] ) nRowEst = p->aiRowEst[0];
+ if( nRowEst > nRow0 ) nRowEst = nRow0;
*pnRow = nRowEst;
- WHERETRACE(("IN row estimate: est=%g\n", nRowEst));
+ WHERETRACE(0x10,("IN row estimate: est=%d\n", nRowEst));
}
+ assert( pBuilder->nRecValid==nRecValid );
return rc;
}
-#endif /* defined(SQLITE_ENABLE_STAT3) */
+#endif /* SQLITE_ENABLE_STAT3_OR_STAT4 */
+
+#ifdef WHERETRACE_ENABLED
/*
-** 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
+** Print the content of a WhereTerm object
*/
-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 );
+static void whereTermPrint(WhereTerm *pTerm, int iTerm){
+ if( pTerm==0 ){
+ sqlite3DebugPrintf("TERM-%-3d NULL\n", iTerm);
+ }else{
+ char zType[4];
+ memcpy(zType, "...", 4);
+ if( pTerm->wtFlags & TERM_VIRTUAL ) zType[0] = 'V';
+ if( pTerm->eOperator & WO_EQUIV ) zType[1] = 'E';
+ if( ExprHasProperty(pTerm->pExpr, EP_FromJoin) ) zType[2] = 'L';
+ sqlite3DebugPrintf(
+ "TERM-%-3d %p %s cursor=%-3d prob=%-3d op=0x%03x wtFlags=0x%04x\n",
+ iTerm, pTerm, zType, pTerm->leftCursor, pTerm->truthProb,
+ pTerm->eOperator, pTerm->wtFlags);
+ sqlite3TreeViewExpr(0, pTerm->pExpr, 0);
+ }
+}
+#endif
+
+#ifdef WHERETRACE_ENABLED
+/*
+** Print a WhereLoop object for debugging purposes
+*/
+static void whereLoopPrint(WhereLoop *p, WhereClause *pWC){
+ WhereInfo *pWInfo = pWC->pWInfo;
+ int nb = 1+(pWInfo->pTabList->nSrc+7)/8;
+ struct SrcList_item *pItem = pWInfo->pTabList->a + p->iTab;
+ Table *pTab = pItem->pTab;
+ sqlite3DebugPrintf("%c%2d.%0*llx.%0*llx", p->cId,
+ p->iTab, nb, p->maskSelf, nb, p->prereq);
+ sqlite3DebugPrintf(" %12s",
+ pItem->zAlias ? pItem->zAlias : pTab->zName);
+ if( (p->wsFlags & WHERE_VIRTUALTABLE)==0 ){
+ const char *zName;
+ if( p->u.btree.pIndex && (zName = p->u.btree.pIndex->zName)!=0 ){
+ if( strncmp(zName, "sqlite_autoindex_", 17)==0 ){
+ int i = sqlite3Strlen30(zName) - 1;
+ while( zName[i]!='_' ) i--;
+ zName += i;
}
+ sqlite3DebugPrintf(".%-16s %2d", zName, p->u.btree.nEq);
}else{
- if( iCol!=(-1) ) return 0;
- sortOrder = 0;
- testcase( (pLevel->plan.wsFlags & WHERE_REVERSE)!=0 );
+ sqlite3DebugPrintf("%20s","");
}
- if( (pLevel->plan.wsFlags & WHERE_REVERSE)!=0 ){
- assert( sortOrder==0 || sortOrder==1 );
- testcase( sortOrder==1 );
- sortOrder = 1 - sortOrder;
+ }else{
+ char *z;
+ if( p->u.vtab.idxStr ){
+ z = sqlite3_mprintf("(%d,\"%s\",%x)",
+ p->u.vtab.idxNum, p->u.vtab.idxStr, p->u.vtab.omitMask);
+ }else{
+ z = sqlite3_mprintf("(%d,%x)", p->u.vtab.idxNum, p->u.vtab.omitMask);
+ }
+ sqlite3DebugPrintf(" %-19s", z);
+ sqlite3_free(z);
+ }
+ if( p->wsFlags & WHERE_SKIPSCAN ){
+ sqlite3DebugPrintf(" f %05x %d-%d", p->wsFlags, p->nLTerm,p->nSkip);
+ }else{
+ sqlite3DebugPrintf(" f %05x N %d", p->wsFlags, p->nLTerm);
+ }
+ sqlite3DebugPrintf(" cost %d,%d,%d\n", p->rSetup, p->rRun, p->nOut);
+ if( p->nLTerm && (sqlite3WhereTrace & 0x100)!=0 ){
+ int i;
+ for(i=0; i<p->nLTerm; i++){
+ whereTermPrint(p->aLTerm[i], i);
}
- return sortOrder+2;
}
- return 0;
}
+#endif
/*
-** 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.
+** Convert bulk memory into a valid WhereLoop that can be passed
+** to whereLoopClear harmlessly.
*/
-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 */
+static void whereLoopInit(WhereLoop *p){
+ p->aLTerm = p->aLTermSpace;
+ p->nLTerm = 0;
+ p->nLSlot = ArraySize(p->aLTermSpace);
+ p->wsFlags = 0;
+}
- 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;
+/*
+** Clear the WhereLoop.u union. Leave WhereLoop.pLTerm intact.
+*/
+static void whereLoopClearUnion(sqlite3 *db, WhereLoop *p){
+ if( p->wsFlags & (WHERE_VIRTUALTABLE|WHERE_AUTO_INDEX) ){
+ if( (p->wsFlags & WHERE_VIRTUALTABLE)!=0 && p->u.vtab.needFree ){
+ sqlite3_free(p->u.vtab.idxStr);
+ p->u.vtab.needFree = 0;
+ p->u.vtab.idxStr = 0;
+ }else if( (p->wsFlags & WHERE_AUTO_INDEX)!=0 && p->u.btree.pIndex!=0 ){
+ sqlite3DbFree(db, p->u.btree.pIndex->zColAff);
+ sqlite3DbFree(db, p->u.btree.pIndex);
+ p->u.btree.pIndex = 0;
}
}
- 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;
- }
+/*
+** Deallocate internal memory used by a WhereLoop object
+*/
+static void whereLoopClear(sqlite3 *db, WhereLoop *p){
+ if( p->aLTerm!=p->aLTermSpace ) sqlite3DbFree(db, p->aLTerm);
+ whereLoopClearUnion(db, p);
+ whereLoopInit(p);
+}
- /* 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;
- }
+/*
+** Increase the memory allocation for pLoop->aLTerm[] to be at least n.
+*/
+static int whereLoopResize(sqlite3 *db, WhereLoop *p, int n){
+ WhereTerm **paNew;
+ if( p->nLSlot>=n ) return SQLITE_OK;
+ n = (n+7)&~7;
+ paNew = sqlite3DbMallocRaw(db, sizeof(p->aLTerm[0])*n);
+ if( paNew==0 ) return SQLITE_NOMEM;
+ memcpy(paNew, p->aLTerm, sizeof(p->aLTerm[0])*p->nLSlot);
+ if( p->aLTerm!=p->aLTermSpace ) sqlite3DbFree(db, p->aLTerm);
+ p->aLTerm = paNew;
+ p->nLSlot = n;
+ return SQLITE_OK;
+}
- /* 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;
- }
+/*
+** Transfer content from the second pLoop into the first.
+*/
+static int whereLoopXfer(sqlite3 *db, WhereLoop *pTo, WhereLoop *pFrom){
+ whereLoopClearUnion(db, pTo);
+ if( whereLoopResize(db, pTo, pFrom->nLTerm) ){
+ memset(&pTo->u, 0, sizeof(pTo->u));
+ return SQLITE_NOMEM;
+ }
+ memcpy(pTo, pFrom, WHERE_LOOP_XFER_SZ);
+ memcpy(pTo->aLTerm, pFrom->aLTerm, pTo->nLTerm*sizeof(pTo->aLTerm[0]));
+ if( pFrom->wsFlags & WHERE_VIRTUALTABLE ){
+ pFrom->u.vtab.needFree = 0;
+ }else if( (pFrom->wsFlags & WHERE_AUTO_INDEX)!=0 ){
+ pFrom->u.btree.pIndex = 0;
+ }
+ return SQLITE_OK;
+}
- /* 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;
+/*
+** Delete a WhereLoop object
+*/
+static void whereLoopDelete(sqlite3 *db, WhereLoop *p){
+ whereLoopClear(db, p);
+ sqlite3DbFree(db, p);
+}
- /* 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;
+/*
+** Free a WhereInfo structure
+*/
+static void whereInfoFree(sqlite3 *db, WhereInfo *pWInfo){
+ if( ALWAYS(pWInfo) ){
+ int i;
+ for(i=0; i<pWInfo->nLevel; i++){
+ WhereLevel *pLevel = &pWInfo->a[i];
+ if( pLevel->pWLoop && (pLevel->pWLoop->wsFlags & WHERE_IN_ABLE) ){
+ sqlite3DbFree(db, pLevel->u.in.aInLoop);
}
}
- 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;
+ sqlite3WhereClauseClear(&pWInfo->sWC);
+ while( pWInfo->pLoops ){
+ WhereLoop *p = pWInfo->pLoops;
+ pWInfo->pLoops = p->pNextLoop;
+ whereLoopDelete(db, p);
}
+ sqlite3DbFree(db, pWInfo);
}
+}
- /* 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 TRUE if all of the following are true:
+**
+** (1) X has the same or lower cost that Y
+** (2) X is a proper subset of Y
+** (3) X skips at least as many columns as Y
+**
+** By "proper subset" we mean that X uses fewer WHERE clause terms
+** than Y and that every WHERE clause term used by X is also used
+** by Y.
+**
+** If X is a proper subset of Y then Y is a better choice and ought
+** to have a lower cost. This routine returns TRUE when that cost
+** relationship is inverted and needs to be adjusted. The third rule
+** was added because if X uses skip-scan less than Y it still might
+** deserve a lower cost even if it is a proper subset of Y.
+*/
+static int whereLoopCheaperProperSubset(
+ const WhereLoop *pX, /* First WhereLoop to compare */
+ const WhereLoop *pY /* Compare against this WhereLoop */
+){
+ int i, j;
+ if( pX->nLTerm-pX->nSkip >= pY->nLTerm-pY->nSkip ){
+ return 0; /* X is not a subset of Y */
+ }
+ if( pY->nSkip > pX->nSkip ) return 0;
+ if( pX->rRun >= pY->rRun ){
+ if( pX->rRun > pY->rRun ) return 0; /* X costs more than Y */
+ if( pX->nOut > pY->nOut ) return 0; /* X costs more than Y */
+ }
+ for(i=pX->nLTerm-1; i>=0; i--){
+ if( pX->aLTerm[i]==0 ) continue;
+ for(j=pY->nLTerm-1; j>=0; j--){
+ if( pY->aLTerm[j]==pX->aLTerm[i] ) break;
}
+ if( j<0 ) return 0; /* X not a subset of Y since term X[i] not used by Y */
}
- return j;
+ return 1; /* All conditions meet */
}
/*
-** Find the best query plan for accessing a particular table. Write the
-** best query plan and its cost into the p->cost.
+** Try to adjust the cost of WhereLoop pTemplate upwards or downwards so
+** that:
**
-** 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:
+** (1) pTemplate costs less than any other WhereLoops that are a proper
+** subset of pTemplate
**
-** * The estimated number of rows that will be retrieved. (The
-** fewer the better.)
+** (2) pTemplate costs more than any other WhereLoops for which pTemplate
+** is a proper subset.
**
-** * Whether or not sorting must occur.
+** To say "WhereLoop X is a proper subset of Y" means that X uses fewer
+** WHERE clause terms than Y and that every WHERE clause term used by X is
+** also used by Y.
+*/
+static void whereLoopAdjustCost(const WhereLoop *p, WhereLoop *pTemplate){
+ if( (pTemplate->wsFlags & WHERE_INDEXED)==0 ) return;
+ for(; p; p=p->pNextLoop){
+ if( p->iTab!=pTemplate->iTab ) continue;
+ if( (p->wsFlags & WHERE_INDEXED)==0 ) continue;
+ if( whereLoopCheaperProperSubset(p, pTemplate) ){
+ /* Adjust pTemplate cost downward so that it is cheaper than its
+ ** subset p. */
+ WHERETRACE(0x80,("subset cost adjustment %d,%d to %d,%d\n",
+ pTemplate->rRun, pTemplate->nOut, p->rRun, p->nOut-1));
+ pTemplate->rRun = p->rRun;
+ pTemplate->nOut = p->nOut - 1;
+ }else if( whereLoopCheaperProperSubset(pTemplate, p) ){
+ /* Adjust pTemplate cost upward so that it is costlier than p since
+ ** pTemplate is a proper subset of p */
+ WHERETRACE(0x80,("subset cost adjustment %d,%d to %d,%d\n",
+ pTemplate->rRun, pTemplate->nOut, p->rRun, p->nOut+1));
+ pTemplate->rRun = p->rRun;
+ pTemplate->nOut = p->nOut + 1;
+ }
+ }
+}
+
+/*
+** Search the list of WhereLoops in *ppPrev looking for one that can be
+** supplanted by pTemplate.
**
-** * Whether or not there must be separate lookups in the
-** index and in the main table.
+** Return NULL if the WhereLoop list contains an entry that can supplant
+** pTemplate, in other words if pTemplate does not belong on the list.
**
-** 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 pX is a WhereLoop that pTemplate can supplant, then return the
+** link that points to pX.
**
-** 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.
+** If pTemplate cannot supplant any existing element of the list but needs
+** to be added to the list, then return a pointer to the tail of the list.
*/
-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;
+static WhereLoop **whereLoopFindLesser(
+ WhereLoop **ppPrev,
+ const WhereLoop *pTemplate
+){
+ WhereLoop *p;
+ for(p=(*ppPrev); p; ppPrev=&p->pNextLoop, p=*ppPrev){
+ if( p->iTab!=pTemplate->iTab || p->iSortIdx!=pTemplate->iSortIdx ){
+ /* If either the iTab or iSortIdx values for two WhereLoop are different
+ ** then those WhereLoops need to be considered separately. Neither is
+ ** a candidate to replace the other. */
+ continue;
+ }
+ /* In the current implementation, the rSetup value is either zero
+ ** or the cost of building an automatic index (NlogN) and the NlogN
+ ** is the same for compatible WhereLoops. */
+ assert( p->rSetup==0 || pTemplate->rSetup==0
+ || p->rSetup==pTemplate->rSetup );
+
+ /* whereLoopAddBtree() always generates and inserts the automatic index
+ ** case first. Hence compatible candidate WhereLoops never have a larger
+ ** rSetup. Call this SETUP-INVARIANT */
+ assert( p->rSetup>=pTemplate->rSetup );
+
+ /* Any loop using an appliation-defined index (or PRIMARY KEY or
+ ** UNIQUE constraint) with one or more == constraints is better
+ ** than an automatic index. Unless it is a skip-scan. */
+ if( (p->wsFlags & WHERE_AUTO_INDEX)!=0
+ && (pTemplate->nSkip)==0
+ && (pTemplate->wsFlags & WHERE_INDEXED)!=0
+ && (pTemplate->wsFlags & WHERE_COLUMN_EQ)!=0
+ && (p->prereq & pTemplate->prereq)==pTemplate->prereq
+ ){
+ break;
+ }
- /* 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 existing WhereLoop p is better than pTemplate, pTemplate can be
+ ** discarded. WhereLoop p is better if:
+ ** (1) p has no more dependencies than pTemplate, and
+ ** (2) p has an equal or lower cost than pTemplate
+ */
+ if( (p->prereq & pTemplate->prereq)==p->prereq /* (1) */
+ && p->rSetup<=pTemplate->rSetup /* (2a) */
+ && p->rRun<=pTemplate->rRun /* (2b) */
+ && p->nOut<=pTemplate->nOut /* (2c) */
+ ){
+ return 0; /* Discard pTemplate */
+ }
- 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;
+ /* If pTemplate is always better than p, then cause p to be overwritten
+ ** with pTemplate. pTemplate is better than p if:
+ ** (1) pTemplate has no more dependences than p, and
+ ** (2) pTemplate has an equal or lower cost than p.
+ */
+ if( (p->prereq & pTemplate->prereq)==pTemplate->prereq /* (1) */
+ && p->rRun>=pTemplate->rRun /* (2a) */
+ && p->nOut>=pTemplate->nOut /* (2b) */
+ ){
+ assert( p->rSetup>=pTemplate->rSetup ); /* SETUP-INVARIANT above */
+ break; /* Cause p to be overwritten by pTemplate */
}
- pProbe = &sPk;
- wsFlagMask = ~(
- WHERE_COLUMN_IN|WHERE_COLUMN_EQ|WHERE_COLUMN_NULL|WHERE_COLUMN_RANGE
- );
- eqTermMask = WO_EQ|WO_IN;
- pIdx = 0;
}
+ return ppPrev;
+}
- 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;
+/*
+** Insert or replace a WhereLoop entry using the template supplied.
+**
+** An existing WhereLoop entry might be overwritten if the new template
+** is better and has fewer dependencies. Or the template will be ignored
+** and no insert will occur if an existing WhereLoop is faster and has
+** fewer dependencies than the template. Otherwise a new WhereLoop is
+** added based on the template.
+**
+** If pBuilder->pOrSet is not NULL then we care about only the
+** prerequisites and rRun and nOut costs of the N best loops. That
+** information is gathered in the pBuilder->pOrSet object. This special
+** processing mode is used only for OR clause processing.
+**
+** When accumulating multiple loops (when pBuilder->pOrSet is NULL) we
+** still might overwrite similar loops with the new template if the
+** new template is better. Loops may be overwritten if the following
+** conditions are met:
+**
+** (1) They have the same iTab.
+** (2) They have the same iSortIdx.
+** (3) The template has same or fewer dependencies than the current loop
+** (4) The template has the same or lower cost than the current loop
+*/
+static int whereLoopInsert(WhereLoopBuilder *pBuilder, WhereLoop *pTemplate){
+ WhereLoop **ppPrev, *p;
+ WhereInfo *pWInfo = pBuilder->pWInfo;
+ sqlite3 *db = pWInfo->pParse->db;
+
+ /* If pBuilder->pOrSet is defined, then only keep track of the costs
+ ** and prereqs.
+ */
+ if( pBuilder->pOrSet!=0 ){
+ if( pTemplate->nLTerm ){
+#if WHERETRACE_ENABLED
+ u16 n = pBuilder->pOrSet->n;
+ int x =
+#endif
+ whereOrInsert(pBuilder->pOrSet, pTemplate->prereq, pTemplate->rRun,
+ pTemplate->nOut);
+#if WHERETRACE_ENABLED /* 0x8 */
+ if( sqlite3WhereTrace & 0x8 ){
+ sqlite3DebugPrintf(x?" or-%d: ":" or-X: ", n);
+ whereLoopPrint(pTemplate, pBuilder->pWC);
+ }
+#endif
+ }
+ return SQLITE_OK;
}
- /* Loop over all indices looking for the best one to use
+ /* Look for an existing WhereLoop to replace with pTemplate
*/
- 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) */
+ whereLoopAdjustCost(pWInfo->pLoops, pTemplate);
+ ppPrev = whereLoopFindLesser(&pWInfo->pLoops, pTemplate);
- /* 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 */
+ if( ppPrev==0 ){
+ /* There already exists a WhereLoop on the list that is better
+ ** than pTemplate, so just ignore pTemplate */
+#if WHERETRACE_ENABLED /* 0x8 */
+ if( sqlite3WhereTrace & 0x8 ){
+ sqlite3DebugPrintf(" skip: ");
+ whereLoopPrint(pTemplate, pBuilder->pWC);
+ }
#endif
+ return SQLITE_OK;
+ }else{
+ p = *ppPrev;
+ }
- 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 we reach this point it means that either p[] should be overwritten
+ ** with pTemplate[] if p[] exists, or if p==NULL then allocate a new
+ ** WhereLoop and insert it.
+ */
+#if WHERETRACE_ENABLED /* 0x8 */
+ if( sqlite3WhereTrace & 0x8 ){
+ if( p!=0 ){
+ sqlite3DebugPrintf("replace: ");
+ whereLoopPrint(p, pBuilder->pWC);
}
-
- /* 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;
+ sqlite3DebugPrintf(" add: ");
+ whereLoopPrint(pTemplate, pBuilder->pWC);
+ }
+#endif
+ if( p==0 ){
+ /* Allocate a new WhereLoop to add to the end of the list */
+ *ppPrev = p = sqlite3DbMallocRaw(db, sizeof(WhereLoop));
+ if( p==0 ) return SQLITE_NOMEM;
+ whereLoopInit(p);
+ p->pNextLoop = 0;
+ }else{
+ /* We will be overwriting WhereLoop p[]. But before we do, first
+ ** go through the rest of the list and delete any other entries besides
+ ** p[] that are also supplated by pTemplate */
+ WhereLoop **ppTail = &p->pNextLoop;
+ WhereLoop *pToDel;
+ while( *ppTail ){
+ ppTail = whereLoopFindLesser(ppTail, pTemplate);
+ if( ppTail==0 ) break;
+ pToDel = *ppTail;
+ if( pToDel==0 ) break;
+ *ppTail = pToDel->pNextLoop;
+#if WHERETRACE_ENABLED /* 0x8 */
+ if( sqlite3WhereTrace & 0x8 ){
+ sqlite3DebugPrintf(" delete: ");
+ whereLoopPrint(pToDel, pBuilder->pWC);
+ }
+#endif
+ whereLoopDelete(db, pToDel);
+ }
+ }
+ whereLoopXfer(db, p, pTemplate);
+ if( (p->wsFlags & WHERE_VIRTUALTABLE)==0 ){
+ Index *pIndex = p->u.btree.pIndex;
+ if( pIndex && pIndex->tnum==0 ){
+ p->u.btree.pIndex = 0;
}
+ }
+ return SQLITE_OK;
+}
- /* 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;
+/*
+** Adjust the WhereLoop.nOut value downward to account for terms of the
+** WHERE clause that reference the loop but which are not used by an
+** index.
+*
+** For every WHERE clause term that is not used by the index
+** and which has a truth probability assigned by one of the likelihood(),
+** likely(), or unlikely() SQL functions, reduce the estimated number
+** of output rows by the probability specified.
+**
+** TUNING: For every WHERE clause term that is not used by the index
+** and which does not have an assigned truth probability, heuristics
+** described below are used to try to estimate the truth probability.
+** TODO --> Perhaps this is something that could be improved by better
+** table statistics.
+**
+** Heuristic 1: Estimate the truth probability as 93.75%. The 93.75%
+** value corresponds to -1 in LogEst notation, so this means decrement
+** the WhereLoop.nOut field for every such WHERE clause term.
+**
+** Heuristic 2: If there exists one or more WHERE clause terms of the
+** form "x==EXPR" and EXPR is not a constant 0 or 1, then make sure the
+** final output row estimate is no greater than 1/4 of the total number
+** of rows in the table. In other words, assume that x==EXPR will filter
+** out at least 3 out of 4 rows. If EXPR is -1 or 0 or 1, then maybe the
+** "x" column is boolean or else -1 or 0 or 1 is a common default value
+** on the "x" column and so in that case only cap the output row estimate
+** at 1/2 instead of 1/4.
+*/
+static void whereLoopOutputAdjust(
+ WhereClause *pWC, /* The WHERE clause */
+ WhereLoop *pLoop, /* The loop to adjust downward */
+ LogEst nRow /* Number of rows in the entire table */
+){
+ WhereTerm *pTerm, *pX;
+ Bitmask notAllowed = ~(pLoop->prereq|pLoop->maskSelf);
+ int i, j, k;
+ LogEst iReduce = 0; /* pLoop->nOut should not exceed nRow-iReduce */
+
+ assert( (pLoop->wsFlags & WHERE_AUTO_INDEX)==0 );
+ for(i=pWC->nTerm, pTerm=pWC->a; i>0; i--, pTerm++){
+ if( (pTerm->wtFlags & TERM_VIRTUAL)!=0 ) break;
+ if( (pTerm->prereqAll & pLoop->maskSelf)==0 ) continue;
+ if( (pTerm->prereqAll & notAllowed)!=0 ) continue;
+ for(j=pLoop->nLTerm-1; j>=0; j--){
+ pX = pLoop->aLTerm[j];
+ if( pX==0 ) continue;
+ if( pX==pTerm ) break;
+ if( pX->iParent>=0 && (&pWC->a[pX->iParent])==pTerm ) break;
+ }
+ if( j<0 ){
+ if( pTerm->truthProb<=0 ){
+ /* If a truth probability is specified using the likelihood() hints,
+ ** then use the probability provided by the application. */
+ pLoop->nOut += pTerm->truthProb;
}else{
- bLookup = 1;
+ /* In the absence of explicit truth probabilities, use heuristics to
+ ** guess a reasonable truth probability. */
+ pLoop->nOut--;
+ if( pTerm->eOperator&(WO_EQ|WO_IS) ){
+ Expr *pRight = pTerm->pExpr->pRight;
+ testcase( pTerm->pExpr->op==TK_IS );
+ if( sqlite3ExprIsInteger(pRight, &k) && k>=(-1) && k<=1 ){
+ k = 10;
+ }else{
+ k = 20;
+ }
+ if( iReduce<k ) iReduce = k;
+ }
}
}
+ }
+ if( pLoop->nOut > nRow-iReduce ) pLoop->nOut = nRow - iReduce;
+}
- /*
- ** 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]);
- }
+/*
+** Adjust the cost C by the costMult facter T. This only occurs if
+** compiled with -DSQLITE_ENABLE_COSTMULT
+*/
+#ifdef SQLITE_ENABLE_COSTMULT
+# define ApplyCostMultiplier(C,T) C += T
+#else
+# define ApplyCostMultiplier(C,T)
+#endif
-#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)
+/*
+** We have so far matched pBuilder->pNew->u.btree.nEq terms of the
+** index pIndex. Try to match one more.
+**
+** When this function is called, pBuilder->pNew->nOut contains the
+** number of rows expected to be visited by filtering using the nEq
+** terms only. If it is modified, this value is restored before this
+** function returns.
+**
+** If pProbe->tnum==0, that means pIndex is a fake index used for the
+** INTEGER PRIMARY KEY.
+*/
+static int whereLoopAddBtreeIndex(
+ WhereLoopBuilder *pBuilder, /* The WhereLoop factory */
+ struct SrcList_item *pSrc, /* FROM clause term being analyzed */
+ Index *pProbe, /* An index on pSrc */
+ LogEst nInMul /* log(Number of iterations due to IN) */
+){
+ WhereInfo *pWInfo = pBuilder->pWInfo; /* WHERE analyse context */
+ Parse *pParse = pWInfo->pParse; /* Parsing context */
+ sqlite3 *db = pParse->db; /* Database connection malloc context */
+ WhereLoop *pNew; /* Template WhereLoop under construction */
+ WhereTerm *pTerm; /* A WhereTerm under consideration */
+ int opMask; /* Valid operators for constraints */
+ WhereScan scan; /* Iterator for WHERE terms */
+ Bitmask saved_prereq; /* Original value of pNew->prereq */
+ u16 saved_nLTerm; /* Original value of pNew->nLTerm */
+ u16 saved_nEq; /* Original value of pNew->u.btree.nEq */
+ u16 saved_nSkip; /* Original value of pNew->nSkip */
+ u32 saved_wsFlags; /* Original value of pNew->wsFlags */
+ LogEst saved_nOut; /* Original value of pNew->nOut */
+ int rc = SQLITE_OK; /* Return code */
+ LogEst rSize; /* Number of rows in the table */
+ LogEst rLogSize; /* Logarithm of table size */
+ WhereTerm *pTop = 0, *pBtm = 0; /* Top and bottom range constraints */
+
+ pNew = pBuilder->pNew;
+ if( db->mallocFailed ) return SQLITE_NOMEM;
+
+ assert( (pNew->wsFlags & WHERE_VIRTUALTABLE)==0 );
+ assert( (pNew->wsFlags & WHERE_TOP_LIMIT)==0 );
+ if( pNew->wsFlags & WHERE_BTM_LIMIT ){
+ opMask = WO_LT|WO_LE;
+ }else if( /*pProbe->tnum<=0 ||*/ (pSrc->fg.jointype & JT_LEFT)!=0 ){
+ opMask = WO_EQ|WO_IN|WO_GT|WO_GE|WO_LT|WO_LE;
+ }else{
+ opMask = WO_EQ|WO_IN|WO_GT|WO_GE|WO_LT|WO_LE|WO_ISNULL|WO_IS;
+ }
+ if( pProbe->bUnordered ) opMask &= ~(WO_GT|WO_GE|WO_LT|WO_LE);
+
+ assert( pNew->u.btree.nEq<pProbe->nColumn );
+
+ saved_nEq = pNew->u.btree.nEq;
+ saved_nSkip = pNew->nSkip;
+ saved_nLTerm = pNew->nLTerm;
+ saved_wsFlags = pNew->wsFlags;
+ saved_prereq = pNew->prereq;
+ saved_nOut = pNew->nOut;
+ pTerm = whereScanInit(&scan, pBuilder->pWC, pSrc->iCursor, saved_nEq,
+ opMask, pProbe);
+ pNew->rSetup = 0;
+ rSize = pProbe->aiRowLogEst[0];
+ rLogSize = estLog(rSize);
+ for(; rc==SQLITE_OK && pTerm!=0; pTerm = whereScanNext(&scan)){
+ u16 eOp = pTerm->eOperator; /* Shorthand for pTerm->eOperator */
+ LogEst rCostIdx;
+ LogEst nOutUnadjusted; /* nOut before IN() and WHERE adjustments */
+ int nIn = 0;
+#ifdef SQLITE_ENABLE_STAT3_OR_STAT4
+ int nRecValid = pBuilder->nRecValid;
+#endif
+ if( (eOp==WO_ISNULL || (pTerm->wtFlags&TERM_VNULL)!=0)
+ && indexColumnNotNull(pProbe, saved_nEq)
){
- /* 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;
- }
+ continue; /* ignore IS [NOT] NULL constraints on NOT NULL columns */
}
+ if( pTerm->prereqRight & pNew->maskSelf ) continue;
- /* 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;
- }
+ /* Do not allow the upper bound of a LIKE optimization range constraint
+ ** to mix with a lower range bound from some other source */
+ if( pTerm->wtFlags & TERM_LIKEOPT && pTerm->eOperator==WO_LT ) continue;
- /**** Cost of using this index has now been computed ****/
+ pNew->wsFlags = saved_wsFlags;
+ pNew->u.btree.nEq = saved_nEq;
+ pNew->nLTerm = saved_nLTerm;
+ if( whereLoopResize(db, pNew, pNew->nLTerm+1) ) break; /* OOM */
+ pNew->aLTerm[pNew->nLTerm++] = pTerm;
+ pNew->prereq = (saved_prereq | pTerm->prereqRight) & ~pNew->maskSelf;
- /* 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--;
+ assert( nInMul==0
+ || (pNew->wsFlags & WHERE_COLUMN_NULL)!=0
+ || (pNew->wsFlags & WHERE_COLUMN_IN)!=0
+ || (pNew->wsFlags & WHERE_SKIPSCAN)!=0
+ );
+
+ if( eOp & WO_IN ){
+ Expr *pExpr = pTerm->pExpr;
+ pNew->wsFlags |= WHERE_COLUMN_IN;
+ if( ExprHasProperty(pExpr, EP_xIsSelect) ){
+ /* "x IN (SELECT ...)": TUNING: the SELECT returns 25 rows */
+ nIn = 46; assert( 46==sqlite3LogEst(25) );
+ }else if( ALWAYS(pExpr->x.pList && pExpr->x.pList->nExpr) ){
+ /* "x IN (value, value, ...)" */
+ nIn = sqlite3LogEst(pExpr->x.pList->nExpr);
+ }
+ assert( nIn>0 ); /* RHS always has 2 or more terms... The parser
+ ** changes "x IN (?)" into "x=?". */
+
+ }else if( eOp & (WO_EQ|WO_IS) ){
+ int iCol = pProbe->aiColumn[saved_nEq];
+ pNew->wsFlags |= WHERE_COLUMN_EQ;
+ assert( saved_nEq==pNew->u.btree.nEq );
+ if( iCol==XN_ROWID
+ || (iCol>0 && nInMul==0 && saved_nEq==pProbe->nKeyCol-1)
+ ){
+ if( iCol>=0 && pProbe->uniqNotNull==0 ){
+ pNew->wsFlags |= WHERE_UNQ_WANTED;
+ }else{
+ pNew->wsFlags |= WHERE_ONEROW;
+ }
+ }
+ }else if( eOp & WO_ISNULL ){
+ pNew->wsFlags |= WHERE_COLUMN_NULL;
+ }else if( eOp & (WO_GT|WO_GE) ){
+ testcase( eOp & WO_GT );
+ testcase( eOp & WO_GE );
+ pNew->wsFlags |= WHERE_COLUMN_RANGE|WHERE_BTM_LIMIT;
+ pBtm = pTerm;
+ pTop = 0;
+ if( pTerm->wtFlags & TERM_LIKEOPT ){
+ /* Range contraints that come from the LIKE optimization are
+ ** always used in pairs. */
+ pTop = &pTerm[1];
+ assert( (pTop-(pTerm->pWC->a))<pTerm->pWC->nTerm );
+ assert( pTop->wtFlags & TERM_LIKEOPT );
+ assert( pTop->eOperator==WO_LT );
+ if( whereLoopResize(db, pNew, pNew->nLTerm+1) ) break; /* OOM */
+ pNew->aLTerm[pNew->nLTerm++] = pTop;
+ pNew->wsFlags |= WHERE_TOP_LIMIT;
+ }
+ }else{
+ assert( eOp & (WO_LT|WO_LE) );
+ testcase( eOp & WO_LT );
+ testcase( eOp & WO_LE );
+ pNew->wsFlags |= WHERE_COLUMN_RANGE|WHERE_TOP_LIMIT;
+ pTop = pTerm;
+ pBtm = (pNew->wsFlags & WHERE_BTM_LIMIT)!=0 ?
+ pNew->aLTerm[pNew->nLTerm-2] : 0;
+ }
+
+ /* At this point pNew->nOut is set to the number of rows expected to
+ ** be visited by the index scan before considering term pTerm, or the
+ ** values of nIn and nInMul. In other words, assuming that all
+ ** "x IN(...)" terms are replaced with "x = ?". This block updates
+ ** the value of pNew->nOut to account for pTerm (but not nIn/nInMul). */
+ assert( pNew->nOut==saved_nOut );
+ if( pNew->wsFlags & WHERE_COLUMN_RANGE ){
+ /* Adjust nOut using stat3/stat4 data. Or, if there is no stat3/stat4
+ ** data, using some other estimate. */
+ whereRangeScanEst(pParse, pBuilder, pBtm, pTop, pNew);
+ }else{
+ int nEq = ++pNew->u.btree.nEq;
+ assert( eOp & (WO_ISNULL|WO_EQ|WO_IN|WO_IS) );
+
+ assert( pNew->nOut==saved_nOut );
+ if( pTerm->truthProb<=0 && pProbe->aiColumn[saved_nEq]>=0 ){
+ assert( (eOp & WO_IN) || nIn==0 );
+ testcase( eOp & WO_IN );
+ pNew->nOut += pTerm->truthProb;
+ pNew->nOut -= nIn;
+ }else{
+#ifdef SQLITE_ENABLE_STAT3_OR_STAT4
+ tRowcnt nOut = 0;
+ if( nInMul==0
+ && pProbe->nSample
+ && pNew->u.btree.nEq<=pProbe->nSampleCol
+ && ((eOp & WO_IN)==0 || !ExprHasProperty(pTerm->pExpr, EP_xIsSelect))
+ ){
+ Expr *pExpr = pTerm->pExpr;
+ if( (eOp & (WO_EQ|WO_ISNULL|WO_IS))!=0 ){
+ testcase( eOp & WO_EQ );
+ testcase( eOp & WO_IS );
+ testcase( eOp & WO_ISNULL );
+ rc = whereEqualScanEst(pParse, pBuilder, pExpr->pRight, &nOut);
}else{
- /* Assume each additional equality match reduces the result
- ** set size by a factor of 10 */
- pc.plan.nRow /= 10;
+ rc = whereInScanEst(pParse, pBuilder, pExpr->x.pList, &nOut);
}
- }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;
+ if( rc==SQLITE_NOTFOUND ) rc = SQLITE_OK;
+ if( rc!=SQLITE_OK ) break; /* Jump out of the pTerm loop */
+ if( nOut ){
+ pNew->nOut = sqlite3LogEst(nOut);
+ if( pNew->nOut>saved_nOut ) pNew->nOut = saved_nOut;
+ pNew->nOut -= nIn;
+ }
+ }
+ if( nOut==0 )
+#endif
+ {
+ pNew->nOut += (pProbe->aiRowLogEst[nEq] - pProbe->aiRowLogEst[nEq-1]);
+ if( eOp & WO_ISNULL ){
+ /* TUNING: If there is no likelihood() value, assume that a
+ ** "col IS NULL" expression matches twice as many rows
+ ** as (col=?). */
+ pNew->nOut += 10;
}
- }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;
}
+ /* Set rCostIdx to the cost of visiting selected rows in index. Add
+ ** it to pNew->rRun, which is currently set to the cost of the index
+ ** seek only. Then, if this is a non-covering index, add the cost of
+ ** visiting the rows in the main table. */
+ rCostIdx = pNew->nOut + 1 + (15*pProbe->szIdxRow)/pSrc->pTab->szTabRow;
+ pNew->rRun = sqlite3LogEstAdd(rLogSize, rCostIdx);
+ if( (pNew->wsFlags & (WHERE_IDX_ONLY|WHERE_IPK))==0 ){
+ pNew->rRun = sqlite3LogEstAdd(pNew->rRun, pNew->nOut + 16);
+ }
+ ApplyCostMultiplier(pNew->rRun, pProbe->pTable->costMult);
- 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
- ));
+ nOutUnadjusted = pNew->nOut;
+ pNew->rRun += nInMul + nIn;
+ pNew->nOut += nInMul + nIn;
+ whereLoopOutputAdjust(pBuilder->pWC, pNew, rSize);
+ rc = whereLoopInsert(pBuilder, pNew);
- /* 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( pNew->wsFlags & WHERE_COLUMN_RANGE ){
+ pNew->nOut = saved_nOut;
+ }else{
+ pNew->nOut = nOutUnadjusted;
}
- /* 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( (pNew->wsFlags & WHERE_TOP_LIMIT)==0
+ && pNew->u.btree.nEq<pProbe->nColumn
+ ){
+ whereLoopAddBtreeIndex(pBuilder, pSrc, pProbe, nInMul+nIn);
+ }
+ pNew->nOut = saved_nOut;
+#ifdef SQLITE_ENABLE_STAT3_OR_STAT4
+ pBuilder->nRecValid = nRecValid;
+#endif
}
+ pNew->prereq = saved_prereq;
+ pNew->u.btree.nEq = saved_nEq;
+ pNew->nSkip = saved_nSkip;
+ pNew->wsFlags = saved_wsFlags;
+ pNew->nOut = saved_nOut;
+ pNew->nLTerm = saved_nLTerm;
- /* 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;
+ /* Consider using a skip-scan if there are no WHERE clause constraints
+ ** available for the left-most terms of the index, and if the average
+ ** number of repeats in the left-most terms is at least 18.
+ **
+ ** The magic number 18 is selected on the basis that scanning 17 rows
+ ** is almost always quicker than an index seek (even though if the index
+ ** contains fewer than 2^17 rows we assume otherwise in other parts of
+ ** the code). And, even if it is not, it should not be too much slower.
+ ** On the other hand, the extra seeks could end up being significantly
+ ** more expensive. */
+ assert( 42==sqlite3LogEst(18) );
+ if( saved_nEq==saved_nSkip
+ && saved_nEq+1<pProbe->nKeyCol
+ && pProbe->noSkipScan==0
+ && pProbe->aiRowLogEst[saved_nEq+1]>=42 /* TUNING: Minimum for skip-scan */
+ && (rc = whereLoopResize(db, pNew, pNew->nLTerm+1))==SQLITE_OK
+ ){
+ LogEst nIter;
+ pNew->u.btree.nEq++;
+ pNew->nSkip++;
+ pNew->aLTerm[pNew->nLTerm++] = 0;
+ pNew->wsFlags |= WHERE_SKIPSCAN;
+ nIter = pProbe->aiRowLogEst[saved_nEq] - pProbe->aiRowLogEst[saved_nEq+1];
+ pNew->nOut -= nIter;
+ /* TUNING: Because uncertainties in the estimates for skip-scan queries,
+ ** add a 1.375 fudge factor to make skip-scan slightly less likely. */
+ nIter += 5;
+ whereLoopAddBtreeIndex(pBuilder, pSrc, pProbe, nIter + nInMul);
+ pNew->nOut = saved_nOut;
+ pNew->u.btree.nEq = saved_nEq;
+ pNew->nSkip = saved_nSkip;
+ pNew->wsFlags = saved_wsFlags;
}
- 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;
+ return rc;
}
/*
-** 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.
+** Return True if it is possible that pIndex might be useful in
+** implementing the ORDER BY clause in pBuilder.
**
-** 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.
+** Return False if pBuilder does not contain an ORDER BY clause or
+** if there is no way for pIndex to be useful in implementing that
+** ORDER BY clause.
*/
-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);
- }
-}
+static int indexMightHelpWithOrderBy(
+ WhereLoopBuilder *pBuilder,
+ Index *pIndex,
+ int iCursor
+){
+ ExprList *pOB;
+ ExprList *aColExpr;
+ int ii, jj;
-/*
-** 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);
+ if( pIndex->bUnordered ) return 0;
+ if( (pOB = pBuilder->pWInfo->pOrderBy)==0 ) return 0;
+ for(ii=0; ii<pOB->nExpr; ii++){
+ Expr *pExpr = sqlite3ExprSkipCollate(pOB->a[ii].pExpr);
+ if( pExpr->op==TK_COLUMN && pExpr->iTable==iCursor ){
+ if( pExpr->iColumn<0 ) return 1;
+ for(jj=0; jj<pIndex->nKeyCol; jj++){
+ if( pExpr->iColumn==pIndex->aiColumn[jj] ) return 1;
+ }
+ }else if( (aColExpr = pIndex->aColExpr)!=0 ){
+ for(jj=0; jj<pIndex->nKeyCol; jj++){
+ if( pIndex->aiColumn[jj]!=XN_EXPR ) continue;
+ if( sqlite3ExprCompare(pExpr,aColExpr->a[jj].pExpr,iCursor)==0 ){
+ return 1;
+ }
}
}
}
+ return 0;
}
/*
-** 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.
+** Return a bitmask where 1s indicate that the corresponding column of
+** the table is used by an index. Only the first 63 columns are considered.
*/
-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--;
+static Bitmask columnsInIndex(Index *pIdx){
+ Bitmask m = 0;
+ int j;
+ for(j=pIdx->nColumn-1; j>=0; j--){
+ int x = pIdx->aiColumn[j];
+ if( x>=0 ){
+ testcase( x==BMS-1 );
+ testcase( x==BMS-2 );
+ if( x<BMS-1 ) m |= MASKBIT(x);
+ }
}
+ return m;
+}
- /* 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);
+/* Check to see if a partial index with pPartIndexWhere can be used
+** in the current query. Return true if it can be and false if not.
+*/
+static int whereUsablePartialIndex(int iTab, WhereClause *pWC, Expr *pWhere){
+ int i;
+ WhereTerm *pTerm;
+ while( pWhere->op==TK_AND ){
+ if( !whereUsablePartialIndex(iTab,pWC,pWhere->pLeft) ) return 0;
+ pWhere = pWhere->pRight;
+ }
+ for(i=0, pTerm=pWC->a; i<pWC->nTerm; i++, pTerm++){
+ Expr *pExpr = pTerm->pExpr;
+ if( sqlite3ExprImpliesExpr(pExpr, pWhere, iTab)
+ && (!ExprHasProperty(pExpr, EP_FromJoin) || pExpr->iRightJoinTable==iTab)
+ ){
+ return 1;
+ }
}
+ return 0;
}
-
/*
-** 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.
+** Add all WhereLoop objects for a single table of the join where the table
+** is idenfied by pBuilder->pNew->iTab. That table is guaranteed to be
+** a b-tree table, not a virtual table.
**
-** The current value for the constraint is left in register iReg.
+** The costs (WhereLoop.rRun) of the b-tree loops added by this function
+** are calculated as follows:
**
-** 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.
+** For a full scan, assuming the table (or index) contains nRow rows:
+**
+** cost = nRow * 3.0 // full-table scan
+** cost = nRow * K // scan of covering index
+** cost = nRow * (K+3.0) // scan of non-covering index
+**
+** where K is a value between 1.1 and 3.0 set based on the relative
+** estimated average size of the index and table records.
+**
+** For an index scan, where nVisit is the number of index rows visited
+** by the scan, and nSeek is the number of seek operations required on
+** the index b-tree:
+**
+** cost = nSeek * (log(nRow) + K * nVisit) // covering index
+** cost = nSeek * (log(nRow) + (K+3.0) * nVisit) // non-covering index
+**
+** Normally, nSeek is 1. nSeek values greater than 1 come about if the
+** WHERE clause includes "x IN (....)" terms used in place of "x=?". Or when
+** implicit "x IN (SELECT x FROM tbl)" terms are added for skip-scans.
+**
+** The estimated values (nRow, nVisit, nSeek) often contain a large amount
+** of uncertainty. For this reason, scoring is designed to pick plans that
+** "do the least harm" if the estimates are inaccurate. For example, a
+** log(nRow) factor is omitted from a non-covering index scan in order to
+** bias the scoring in favor of using an index, since the worst-case
+** performance of using an index is far better than the worst-case performance
+** of a full table scan.
*/
-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 */
+static int whereLoopAddBtree(
+ WhereLoopBuilder *pBuilder, /* WHERE clause information */
+ Bitmask mExtra /* Extra prerequesites for using this table */
){
- 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
+ WhereInfo *pWInfo; /* WHERE analysis context */
+ Index *pProbe; /* An index we are evaluating */
+ Index sPk; /* A fake index object for the primary key */
+ LogEst aiRowEstPk[2]; /* The aiRowLogEst[] value for the sPk index */
+ i16 aiColumnPk = -1; /* The aColumn[] value for the sPk index */
+ SrcList *pTabList; /* The FROM clause */
+ struct SrcList_item *pSrc; /* The FROM clause btree term to add */
+ WhereLoop *pNew; /* Template WhereLoop object */
+ int rc = SQLITE_OK; /* Return code */
+ int iSortIdx = 1; /* Index number */
+ int b; /* A boolean value */
+ LogEst rSize; /* number of rows in the table */
+ LogEst rLogSize; /* Logarithm of the number of rows in the table */
+ WhereClause *pWC; /* The parsed WHERE clause */
+ Table *pTab; /* Table being queried */
+
+ pNew = pBuilder->pNew;
+ pWInfo = pBuilder->pWInfo;
+ pTabList = pWInfo->pTabList;
+ pSrc = pTabList->a + pNew->iTab;
+ pTab = pSrc->pTab;
+ pWC = pBuilder->pWC;
+ assert( !IsVirtual(pSrc->pTab) );
+
+ if( pSrc->pIBIndex ){
+ /* An INDEXED BY clause specifies a particular index to use */
+ pProbe = pSrc->pIBIndex;
+ }else if( !HasRowid(pTab) ){
+ pProbe = pTab->pIndex;
}else{
- int eType;
- int iTab;
- struct InLoop *pIn;
+ /* 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.nKeyCol = 1;
+ sPk.nColumn = 1;
+ sPk.aiColumn = &aiColumnPk;
+ sPk.aiRowLogEst = aiRowEstPk;
+ sPk.onError = OE_Replace;
+ sPk.pTable = pTab;
+ sPk.szIdxRow = pTab->szTabRow;
+ aiRowEstPk[0] = pTab->nRowLogEst;
+ aiRowEstPk[1] = 0;
+ pFirst = pSrc->pTab->pIndex;
+ if( pSrc->fg.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;
+ }
+ rSize = pTab->nRowLogEst;
+ rLogSize = estLog(rSize);
- 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);
+#ifndef SQLITE_OMIT_AUTOMATIC_INDEX
+ /* Automatic indexes */
+ if( !pBuilder->pOrSet /* Not part of an OR optimization */
+ && (pWInfo->wctrlFlags & WHERE_NO_AUTOINDEX)==0
+ && (pWInfo->pParse->db->flags & SQLITE_AutoIndex)!=0
+ && pSrc->pIBIndex==0 /* Has no INDEXED BY clause */
+ && !pSrc->fg.notIndexed /* Has no NOT INDEXED clause */
+ && HasRowid(pTab) /* Not WITHOUT ROWID table. (FIXME: Why not?) */
+ && !pSrc->fg.isCorrelated /* Not a correlated subquery */
+ && !pSrc->fg.isRecursive /* Not a recursive common table expression. */
+ ){
+ /* Generate auto-index WhereLoops */
+ WhereTerm *pTerm;
+ WhereTerm *pWCEnd = pWC->a + pWC->nTerm;
+ for(pTerm=pWC->a; rc==SQLITE_OK && pTerm<pWCEnd; pTerm++){
+ if( pTerm->prereqRight & pNew->maskSelf ) continue;
+ if( termCanDriveIndex(pTerm, pSrc, 0) ){
+ pNew->u.btree.nEq = 1;
+ pNew->nSkip = 0;
+ pNew->u.btree.pIndex = 0;
+ pNew->nLTerm = 1;
+ pNew->aLTerm[0] = pTerm;
+ /* TUNING: One-time cost for computing the automatic index is
+ ** estimated to be X*N*log2(N) where N is the number of rows in
+ ** the table being indexed and where X is 7 (LogEst=28) for normal
+ ** tables or 1.375 (LogEst=4) for views and subqueries. The value
+ ** of X is smaller for views and subqueries so that the query planner
+ ** will be more aggressive about generating automatic indexes for
+ ** those objects, since there is no opportunity to add schema
+ ** indexes on subqueries and views. */
+ pNew->rSetup = rLogSize + rSize + 4;
+ if( pTab->pSelect==0 && (pTab->tabFlags & TF_Ephemeral)==0 ){
+ pNew->rSetup += 24;
+ }
+ ApplyCostMultiplier(pNew->rSetup, pTab->costMult);
+ /* TUNING: Each index lookup yields 20 rows in the table. This
+ ** is more than the usual guess of 10 rows, since we have no way
+ ** of knowing how selective the index will ultimately be. It would
+ ** not be unreasonable to make this value much larger. */
+ pNew->nOut = 43; assert( 43==sqlite3LogEst(20) );
+ pNew->rRun = sqlite3LogEstAdd(rLogSize,pNew->nOut);
+ pNew->wsFlags = WHERE_AUTO_INDEX;
+ pNew->prereq = mExtra | pTerm->prereqRight;
+ rc = whereLoopInsert(pBuilder, pNew);
+ }
}
- 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);
+ }
+#endif /* SQLITE_OMIT_AUTOMATIC_INDEX */
+
+ /* Loop over all indices
+ */
+ for(; rc==SQLITE_OK && pProbe; pProbe=pProbe->pNext, iSortIdx++){
+ if( pProbe->pPartIdxWhere!=0
+ && !whereUsablePartialIndex(pSrc->iCursor, pWC, pProbe->pPartIdxWhere) ){
+ testcase( pNew->iTab!=pSrc->iCursor ); /* See ticket [98d973b8f5] */
+ continue; /* Partial index inappropriate for this query */
+ }
+ rSize = pProbe->aiRowLogEst[0];
+ pNew->u.btree.nEq = 0;
+ pNew->nSkip = 0;
+ pNew->nLTerm = 0;
+ pNew->iSortIdx = 0;
+ pNew->rSetup = 0;
+ pNew->prereq = mExtra;
+ pNew->nOut = rSize;
+ pNew->u.btree.pIndex = pProbe;
+ b = indexMightHelpWithOrderBy(pBuilder, pProbe, pSrc->iCursor);
+ /* The ONEPASS_DESIRED flags never occurs together with ORDER BY */
+ assert( (pWInfo->wctrlFlags & WHERE_ONEPASS_DESIRED)==0 || b==0 );
+ if( pProbe->tnum<=0 ){
+ /* Integer primary key index */
+ pNew->wsFlags = WHERE_IPK;
+
+ /* Full table scan */
+ pNew->iSortIdx = b ? iSortIdx : 0;
+ /* TUNING: Cost of full table scan is (N*3.0). */
+ pNew->rRun = rSize + 16;
+ ApplyCostMultiplier(pNew->rRun, pTab->costMult);
+ whereLoopOutputAdjust(pWC, pNew, rSize);
+ rc = whereLoopInsert(pBuilder, pNew);
+ pNew->nOut = rSize;
+ if( rc ) break;
+ }else{
+ Bitmask m;
+ if( pProbe->isCovering ){
+ pNew->wsFlags = WHERE_IDX_ONLY | WHERE_INDEXED;
+ m = 0;
}else{
- pIn->addrInTop = sqlite3VdbeAddOp3(v, OP_Column, iTab, 0, iReg);
+ m = pSrc->colUsed & ~columnsInIndex(pProbe);
+ pNew->wsFlags = (m==0) ? (WHERE_IDX_ONLY|WHERE_INDEXED) : WHERE_INDEXED;
+ }
+
+ /* Full scan via index */
+ if( b
+ || !HasRowid(pTab)
+ || ( m==0
+ && pProbe->bUnordered==0
+ && (pProbe->szIdxRow<pTab->szTabRow)
+ && (pWInfo->wctrlFlags & WHERE_ONEPASS_DESIRED)==0
+ && sqlite3GlobalConfig.bUseCis
+ && OptimizationEnabled(pWInfo->pParse->db, SQLITE_CoverIdxScan)
+ )
+ ){
+ pNew->iSortIdx = b ? iSortIdx : 0;
+
+ /* The cost of visiting the index rows is N*K, where K is
+ ** between 1.1 and 3.0, depending on the relative sizes of the
+ ** index and table rows. If this is a non-covering index scan,
+ ** also add the cost of visiting table rows (N*3.0). */
+ pNew->rRun = rSize + 1 + (15*pProbe->szIdxRow)/pTab->szTabRow;
+ if( m!=0 ){
+ pNew->rRun = sqlite3LogEstAdd(pNew->rRun, rSize+16);
+ }
+ ApplyCostMultiplier(pNew->rRun, pTab->costMult);
+ whereLoopOutputAdjust(pWC, pNew, rSize);
+ rc = whereLoopInsert(pBuilder, pNew);
+ pNew->nOut = rSize;
+ if( rc ) break;
}
- sqlite3VdbeAddOp1(v, OP_IsNull, iReg);
- }else{
- pLevel->u.in.nIn = 0;
}
+
+ rc = whereLoopAddBtreeIndex(pBuilder, pSrc, pProbe, 0);
+#ifdef SQLITE_ENABLE_STAT3_OR_STAT4
+ sqlite3Stat4ProbeFree(pBuilder->pRec);
+ pBuilder->nRecValid = 0;
+ pBuilder->pRec = 0;
#endif
+
+ /* If there was an INDEXED BY clause, then only that one index is
+ ** considered. */
+ if( pSrc->pIBIndex ) break;
}
- disableTerm(pLevel, pTerm);
- return iReg;
+ return rc;
}
+#ifndef SQLITE_OMIT_VIRTUALTABLE
/*
-** Generate code that will evaluate all == and IN constraints for an
-** index.
+** Add all WhereLoop objects for a table of the join identified by
+** pBuilder->pNew->iTab. That table is guaranteed to be a virtual table.
**
-** 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.
+** If there are no LEFT or CROSS JOIN joins in the query, both mExtra and
+** mUnusable are set to 0. Otherwise, mExtra is a mask of all FROM clause
+** entries that occur before the virtual table in the FROM clause and are
+** separated from it by at least one LEFT or CROSS JOIN. Similarly, the
+** mUnusable mask contains all FROM clause entries that occur after the
+** virtual table and are separated from it by at least one LEFT or
+** CROSS JOIN.
**
-** 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.
+** For example, if the query were:
**
-** 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.
+** ... FROM t1, t2 LEFT JOIN t3, t4, vt CROSS JOIN t5, t6;
**
-** 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;
+** then mExtra corresponds to (t1, t2) and mUnusable to (t5, t6).
**
-** 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.
+** All the tables in mExtra must be scanned before the current virtual
+** table. So any terms for which all prerequisites are satisfied by
+** mExtra may be specified as "usable" in all calls to xBestIndex.
+** Conversely, all tables in mUnusable must be scanned after the current
+** virtual table, so any terms for which the prerequisites overlap with
+** mUnusable should always be configured as "not-usable" for xBestIndex.
*/
-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 */
+static int whereLoopAddVirtual(
+ WhereLoopBuilder *pBuilder, /* WHERE clause information */
+ Bitmask mExtra, /* Tables that must be scanned before this one */
+ Bitmask mUnusable /* Tables that must be scanned after this one */
){
- 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;
+ WhereInfo *pWInfo; /* WHERE analysis context */
+ Parse *pParse; /* The parsing context */
+ WhereClause *pWC; /* The WHERE clause */
+ struct SrcList_item *pSrc; /* The FROM clause term to search */
+ Table *pTab;
+ sqlite3 *db;
+ sqlite3_index_info *pIdxInfo;
+ struct sqlite3_index_constraint *pIdxCons;
+ struct sqlite3_index_constraint_usage *pUsage;
+ WhereTerm *pTerm;
+ int i, j;
+ int iTerm, mxTerm;
+ int nConstraint;
+ int seenIn = 0; /* True if an IN operator is seen */
+ int seenVar = 0; /* True if a non-constant constraint is seen */
+ int iPhase; /* 0: const w/o IN, 1: const, 2: no IN, 2: IN */
+ WhereLoop *pNew;
+ int rc = SQLITE_OK;
- zAff = sqlite3DbStrDup(pParse->db, sqlite3IndexAffinityStr(v, pIdx));
- if( !zAff ){
- pParse->db->mallocFailed = 1;
+ assert( (mExtra & mUnusable)==0 );
+ pWInfo = pBuilder->pWInfo;
+ pParse = pWInfo->pParse;
+ db = pParse->db;
+ pWC = pBuilder->pWC;
+ pNew = pBuilder->pNew;
+ pSrc = &pWInfo->pTabList->a[pNew->iTab];
+ pTab = pSrc->pTab;
+ assert( IsVirtual(pTab) );
+ pIdxInfo = allocateIndexInfo(pParse, pWC, mUnusable, pSrc,pBuilder->pOrderBy);
+ if( pIdxInfo==0 ) return SQLITE_NOMEM;
+ pNew->prereq = 0;
+ pNew->rSetup = 0;
+ pNew->wsFlags = WHERE_VIRTUALTABLE;
+ pNew->nLTerm = 0;
+ pNew->u.vtab.needFree = 0;
+ pUsage = pIdxInfo->aConstraintUsage;
+ nConstraint = pIdxInfo->nConstraint;
+ if( whereLoopResize(db, pNew, nConstraint) ){
+ sqlite3DbFree(db, pIdxInfo);
+ return SQLITE_NOMEM;
}
- /* 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);
+ for(iPhase=0; iPhase<=3; iPhase++){
+ if( !seenIn && (iPhase&1)!=0 ){
+ iPhase++;
+ if( iPhase>3 ) break;
+ }
+ if( !seenVar && iPhase>1 ) break;
+ pIdxCons = *(struct sqlite3_index_constraint**)&pIdxInfo->aConstraint;
+ for(i=0; i<pIdxInfo->nConstraint; i++, pIdxCons++){
+ j = pIdxCons->iTermOffset;
+ pTerm = &pWC->a[j];
+ switch( iPhase ){
+ case 0: /* Constants without IN operator */
+ pIdxCons->usable = 0;
+ if( (pTerm->eOperator & WO_IN)!=0 ){
+ seenIn = 1;
+ }
+ if( (pTerm->prereqRight & ~mExtra)!=0 ){
+ seenVar = 1;
+ }else if( (pTerm->eOperator & WO_IN)==0 ){
+ pIdxCons->usable = 1;
+ }
+ break;
+ case 1: /* Constants with IN operators */
+ assert( seenIn );
+ pIdxCons->usable = (pTerm->prereqRight & ~mExtra)==0;
+ break;
+ case 2: /* Variables without IN */
+ assert( seenVar );
+ pIdxCons->usable = (pTerm->eOperator & WO_IN)==0;
+ break;
+ default: /* Variables with IN */
+ assert( seenVar && seenIn );
+ pIdxCons->usable = 1;
+ break;
}
}
- 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;
+ 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;
+ pIdxInfo->estimatedCost = SQLITE_BIG_DBL / (double)2;
+ pIdxInfo->estimatedRows = 25;
+ pIdxInfo->idxFlags = 0;
+ pIdxInfo->colUsed = (sqlite3_int64)pSrc->colUsed;
+ rc = vtabBestIndex(pParse, pTab, pIdxInfo);
+ if( rc ) goto whereLoopAddVtab_exit;
+ pIdxCons = *(struct sqlite3_index_constraint**)&pIdxInfo->aConstraint;
+ pNew->prereq = mExtra;
+ mxTerm = -1;
+ assert( pNew->nLSlot>=nConstraint );
+ for(i=0; i<nConstraint; i++) pNew->aLTerm[i] = 0;
+ pNew->u.vtab.omitMask = 0;
+ for(i=0; i<nConstraint; i++, pIdxCons++){
+ if( (iTerm = pUsage[i].argvIndex - 1)>=0 ){
+ j = pIdxCons->iTermOffset;
+ if( iTerm>=nConstraint
+ || j<0
+ || j>=pWC->nTerm
+ || pNew->aLTerm[iTerm]!=0
+ ){
+ rc = SQLITE_ERROR;
+ sqlite3ErrorMsg(pParse, "%s.xBestIndex() malfunction", pTab->zName);
+ goto whereLoopAddVtab_exit;
}
- if( sqlite3ExprNeedsNoAffinityChange(pRight, zAff[j]) ){
- zAff[j] = SQLITE_AFF_NONE;
+ testcase( iTerm==nConstraint-1 );
+ testcase( j==0 );
+ testcase( j==pWC->nTerm-1 );
+ pTerm = &pWC->a[j];
+ pNew->prereq |= pTerm->prereqRight;
+ assert( iTerm<pNew->nLSlot );
+ pNew->aLTerm[iTerm] = pTerm;
+ if( iTerm>mxTerm ) mxTerm = iTerm;
+ testcase( iTerm==15 );
+ testcase( iTerm==16 );
+ if( iTerm<16 && pUsage[i].omit ) pNew->u.vtab.omitMask |= 1<<iTerm;
+ if( (pTerm->eOperator & WO_IN)!=0 ){
+ if( pUsage[i].omit==0 ){
+ /* Do not attempt to use an IN constraint if the virtual table
+ ** says that the equivalent EQ constraint cannot be safely omitted.
+ ** If we do attempt to use such a constraint, some rows might be
+ ** repeated in the output. */
+ break;
+ }
+ /* A virtual table that is constrained by an IN clause may not
+ ** consume the ORDER BY clause because (1) the order of IN terms
+ ** is not necessarily related to the order of output terms and
+ ** (2) Multiple outputs from a single IN value will not merge
+ ** together. */
+ pIdxInfo->orderByConsumed = 0;
+ pIdxInfo->idxFlags &= ~SQLITE_INDEX_SCAN_UNIQUE;
}
}
}
- }
- *pzAff = zAff;
- return regBase;
-}
+ if( i>=nConstraint ){
+ pNew->nLTerm = mxTerm+1;
+ assert( pNew->nLTerm<=pNew->nLSlot );
+ pNew->u.vtab.idxNum = pIdxInfo->idxNum;
+ pNew->u.vtab.needFree = pIdxInfo->needToFreeIdxStr;
+ pIdxInfo->needToFreeIdxStr = 0;
+ pNew->u.vtab.idxStr = pIdxInfo->idxStr;
+ pNew->u.vtab.isOrdered = (i8)(pIdxInfo->orderByConsumed ?
+ pIdxInfo->nOrderBy : 0);
+ pNew->rSetup = 0;
+ pNew->rRun = sqlite3LogEstFromDouble(pIdxInfo->estimatedCost);
+ pNew->nOut = sqlite3LogEst(pIdxInfo->estimatedRows);
+
+ /* Set the WHERE_ONEROW flag if the xBestIndex() method indicated
+ ** that the scan will visit at most one row. Clear it otherwise. */
+ if( pIdxInfo->idxFlags & SQLITE_INDEX_SCAN_UNIQUE ){
+ pNew->wsFlags |= WHERE_ONEROW;
+ }else{
+ pNew->wsFlags &= ~WHERE_ONEROW;
+ }
+ whereLoopInsert(pBuilder, pNew);
+ if( pNew->u.vtab.needFree ){
+ sqlite3_free(pNew->u.vtab.idxStr);
+ pNew->u.vtab.needFree = 0;
+ }
+ }
+ }
-#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);
+whereLoopAddVtab_exit:
+ if( pIdxInfo->needToFreeIdxStr ) sqlite3_free(pIdxInfo->idxStr);
+ sqlite3DbFree(db, pIdxInfo);
+ return rc;
}
+#endif /* SQLITE_OMIT_VIRTUALTABLE */
/*
-** 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.
+** Add WhereLoop entries to handle OR terms. This works for either
+** btrees or virtual tables.
*/
-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, "=");
- }
+static int whereLoopAddOr(
+ WhereLoopBuilder *pBuilder,
+ Bitmask mExtra,
+ Bitmask mUnusable
+){
+ WhereInfo *pWInfo = pBuilder->pWInfo;
+ WhereClause *pWC;
+ WhereLoop *pNew;
+ WhereTerm *pTerm, *pWCEnd;
+ int rc = SQLITE_OK;
+ int iCur;
+ WhereClause tempWC;
+ WhereLoopBuilder sSubBuild;
+ WhereOrSet sSum, sCur;
+ struct SrcList_item *pItem;
+
+ pWC = pBuilder->pWC;
+ pWCEnd = pWC->a + pWC->nTerm;
+ pNew = pBuilder->pNew;
+ memset(&sSum, 0, sizeof(sSum));
+ pItem = pWInfo->pTabList->a + pNew->iTab;
+ iCur = pItem->iCursor;
+
+ for(pTerm=pWC->a; pTerm<pWCEnd && rc==SQLITE_OK; pTerm++){
+ if( (pTerm->eOperator & WO_OR)!=0
+ && (pTerm->u.pOrInfo->indexable & pNew->maskSelf)!=0
+ ){
+ WhereClause * const pOrWC = &pTerm->u.pOrInfo->wc;
+ WhereTerm * const pOrWCEnd = &pOrWC->a[pOrWC->nTerm];
+ WhereTerm *pOrTerm;
+ int once = 1;
+ int i, j;
+
+ sSubBuild = *pBuilder;
+ sSubBuild.pOrderBy = 0;
+ sSubBuild.pOrSet = &sCur;
- 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, "<");
+ WHERETRACE(0x200, ("Begin processing OR-clause %p\n", pTerm));
+ for(pOrTerm=pOrWC->a; pOrTerm<pOrWCEnd; pOrTerm++){
+ if( (pOrTerm->eOperator & WO_AND)!=0 ){
+ sSubBuild.pWC = &pOrTerm->u.pAndInfo->wc;
+ }else if( pOrTerm->leftCursor==iCur ){
+ tempWC.pWInfo = pWC->pWInfo;
+ tempWC.pOuter = pWC;
+ tempWC.op = TK_AND;
+ tempWC.nTerm = 1;
+ tempWC.a = pOrTerm;
+ sSubBuild.pWC = &tempWC;
+ }else{
+ continue;
+ }
+ sCur.n = 0;
+#ifdef WHERETRACE_ENABLED
+ WHERETRACE(0x200, ("OR-term %d of %p has %d subterms:\n",
+ (int)(pOrTerm-pOrWC->a), pTerm, sSubBuild.pWC->nTerm));
+ if( sqlite3WhereTrace & 0x400 ){
+ for(i=0; i<sSubBuild.pWC->nTerm; i++){
+ whereTermPrint(&sSubBuild.pWC->a[i], i);
+ }
+ }
+#endif
+#ifndef SQLITE_OMIT_VIRTUALTABLE
+ if( IsVirtual(pItem->pTab) ){
+ rc = whereLoopAddVirtual(&sSubBuild, mExtra, mUnusable);
+ }else
+#endif
+ {
+ rc = whereLoopAddBtree(&sSubBuild, mExtra);
+ }
+ if( rc==SQLITE_OK ){
+ rc = whereLoopAddOr(&sSubBuild, mExtra, mUnusable);
+ }
+ assert( rc==SQLITE_OK || sCur.n==0 );
+ if( sCur.n==0 ){
+ sSum.n = 0;
+ break;
+ }else if( once ){
+ whereOrMove(&sSum, &sCur);
+ once = 0;
+ }else{
+ WhereOrSet sPrev;
+ whereOrMove(&sPrev, &sSum);
+ sSum.n = 0;
+ for(i=0; i<sPrev.n; i++){
+ for(j=0; j<sCur.n; j++){
+ whereOrInsert(&sSum, sPrev.a[i].prereq | sCur.a[j].prereq,
+ sqlite3LogEstAdd(sPrev.a[i].rRun, sCur.a[j].rRun),
+ sqlite3LogEstAdd(sPrev.a[i].nOut, sCur.a[j].nOut));
+ }
+ }
+ }
+ }
+ pNew->nLTerm = 1;
+ pNew->aLTerm[0] = pTerm;
+ pNew->wsFlags = WHERE_MULTI_OR;
+ pNew->rSetup = 0;
+ pNew->iSortIdx = 0;
+ memset(&pNew->u, 0, sizeof(pNew->u));
+ for(i=0; rc==SQLITE_OK && i<sSum.n; i++){
+ /* TUNING: Currently sSum.a[i].rRun is set to the sum of the costs
+ ** of all sub-scans required by the OR-scan. However, due to rounding
+ ** errors, it may be that the cost of the OR-scan is equal to its
+ ** most expensive sub-scan. Add the smallest possible penalty
+ ** (equivalent to multiplying the cost by 1.07) to ensure that
+ ** this does not happen. Otherwise, for WHERE clauses such as the
+ ** following where there is an index on "y":
+ **
+ ** WHERE likelihood(x=?, 0.99) OR y=?
+ **
+ ** the planner may elect to "OR" together a full-table scan and an
+ ** index lookup. And other similarly odd results. */
+ pNew->rRun = sSum.a[i].rRun + 1;
+ pNew->nOut = sSum.a[i].nOut;
+ pNew->prereq = sSum.a[i].prereq;
+ rc = whereLoopInsert(pBuilder, pNew);
+ }
+ WHERETRACE(0x200, ("End processing OR-clause %p\n", pTerm));
+ }
}
- sqlite3StrAccumAppend(&txt, ")", 1);
- return sqlite3StrAccumFinish(&txt);
+ return rc;
}
/*
-** 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.
+** Add all WhereLoop objects for all tables
*/
-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);
+static int whereLoopAddAll(WhereLoopBuilder *pBuilder){
+ WhereInfo *pWInfo = pBuilder->pWInfo;
+ Bitmask mExtra = 0;
+ Bitmask mPrior = 0;
+ int iTab;
+ SrcList *pTabList = pWInfo->pTabList;
+ struct SrcList_item *pItem;
+ struct SrcList_item *pEnd = &pTabList->a[pWInfo->nLevel];
+ sqlite3 *db = pWInfo->pParse->db;
+ int rc = SQLITE_OK;
+ WhereLoop *pNew;
+ u8 priorJointype = 0;
+
+ /* Loop over the tables in the join, from left to right */
+ pNew = pBuilder->pNew;
+ whereLoopInit(pNew);
+ for(iTab=0, pItem=pTabList->a; pItem<pEnd; iTab++, pItem++){
+ Bitmask mUnusable = 0;
+ pNew->iTab = iTab;
+ pNew->maskSelf = sqlite3WhereGetMask(&pWInfo->sMaskSet, pItem->iCursor);
+ if( ((pItem->fg.jointype|priorJointype) & (JT_LEFT|JT_CROSS))!=0 ){
+ /* This condition is true when pItem is the FROM clause term on the
+ ** right-hand-side of a LEFT or CROSS JOIN. */
+ mExtra = mPrior;
+ }
+ priorJointype = pItem->fg.jointype;
+ if( IsVirtual(pItem->pTab) ){
+ struct SrcList_item *p;
+ for(p=&pItem[1]; p<pEnd; p++){
+ if( mUnusable || (p->fg.jointype & (JT_LEFT|JT_CROSS)) ){
+ mUnusable |= sqlite3WhereGetMask(&pWInfo->sMaskSet, p->iCursor);
+ }
}
- }
-#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;
+ rc = whereLoopAddVirtual(pBuilder, mExtra, mUnusable);
}else{
- nRow = (sqlite3_int64)pLevel->plan.nRow;
+ rc = whereLoopAddBtree(pBuilder, mExtra);
+ }
+ if( rc==SQLITE_OK ){
+ rc = whereLoopAddOr(pBuilder, mExtra, mUnusable);
}
- zMsg = sqlite3MAppendf(db, zMsg, "%s (~%lld rows)", zMsg, nRow);
- sqlite3VdbeAddOp4(v, OP_Explain, iId, iLevel, iFrom, zMsg, P4_DYNAMIC);
+ mPrior |= pNew->maskSelf;
+ if( rc || db->mallocFailed ) break;
}
-}
-#else
-# define explainOneScan(u,v,w,x,y,z)
-#endif /* SQLITE_OMIT_EXPLAIN */
+ whereLoopClear(db, pNew);
+ return rc;
+}
/*
-** 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;
+** Examine a WherePath (with the addition of the extra WhereLoop of the 5th
+** parameters) to see if it outputs rows in the requested ORDER BY
+** (or GROUP BY) without requiring a separate sort operation. Return N:
+**
+** N>0: N terms of the ORDER BY clause are satisfied
+** N==0: No terms of the ORDER BY clause are satisfied
+** N<0: Unknown yet how many terms of ORDER BY might be satisfied.
+**
+** Note that processing for WHERE_GROUPBY and WHERE_DISTINCTBY is not as
+** strict. With GROUP BY and DISTINCT the only requirement is that
+** equivalent rows appear immediately adjacent to one another. GROUP BY
+** and DISTINCT do not require rows to appear in any particular order as long
+** as equivalent rows are grouped together. Thus for GROUP BY and DISTINCT
+** the pOrderBy terms can be matched in any order. With ORDER BY, the
+** pOrderBy terms must be matched in strict left-to-right order.
+*/
+static i8 wherePathSatisfiesOrderBy(
+ WhereInfo *pWInfo, /* The WHERE clause */
+ ExprList *pOrderBy, /* ORDER BY or GROUP BY or DISTINCT clause to check */
+ WherePath *pPath, /* The WherePath to check */
+ u16 wctrlFlags, /* Might contain WHERE_GROUPBY or WHERE_DISTINCTBY */
+ u16 nLoop, /* Number of entries in pPath->aLoop[] */
+ WhereLoop *pLast, /* Add this WhereLoop to the end of pPath->aLoop[] */
+ Bitmask *pRevMask /* OUT: Mask of WhereLoops to run in reverse order */
+){
+ u8 revSet; /* True if rev is known */
+ u8 rev; /* Composite sort order */
+ u8 revIdx; /* Index sort order */
+ u8 isOrderDistinct; /* All prior WhereLoops are order-distinct */
+ u8 distinctColumns; /* True if the loop has UNIQUE NOT NULL columns */
+ u8 isMatch; /* iColumn matches a term of the ORDER BY clause */
+ u16 nKeyCol; /* Number of key columns in pIndex */
+ u16 nColumn; /* Total number of ordered columns in the index */
+ u16 nOrderBy; /* Number terms in the ORDER BY clause */
+ int iLoop; /* Index of WhereLoop in pPath being processed */
+ int i, j; /* Loop counters */
+ int iCur; /* Cursor number for current WhereLoop */
+ int iColumn; /* A column number within table iCur */
+ WhereLoop *pLoop = 0; /* Current WhereLoop being processed. */
+ WhereTerm *pTerm; /* A single term of the WHERE clause */
+ Expr *pOBExpr; /* An expression from the ORDER BY clause */
+ CollSeq *pColl; /* COLLATE function from an ORDER BY clause term */
+ Index *pIndex; /* The index associated with pLoop */
+ sqlite3 *db = pWInfo->pParse->db; /* Database connection */
+ Bitmask obSat = 0; /* Mask of ORDER BY terms satisfied so far */
+ Bitmask obDone; /* Mask of all ORDER BY terms */
+ Bitmask orderDistinctMask; /* Mask of all well-ordered loops */
+ Bitmask ready; /* Mask of inner loops */
- /* 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.
+ /*
+ ** We say the WhereLoop is "one-row" if it generates no more than one
+ ** row of output. A WhereLoop is one-row if all of the following are true:
+ ** (a) All index columns match with WHERE_COLUMN_EQ.
+ ** (b) The index is unique
+ ** Any WhereLoop with an WHERE_COLUMN_EQ constraint on the rowid is one-row.
+ ** Every one-row WhereLoop will have the WHERE_ONEROW bit set in wsFlags.
**
- ** 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.
+ ** We say the WhereLoop is "order-distinct" if the set of columns from
+ ** that WhereLoop that are in the ORDER BY clause are different for every
+ ** row of the WhereLoop. Every one-row WhereLoop is automatically
+ ** order-distinct. A WhereLoop that has no columns in the ORDER BY clause
+ ** is not order-distinct. To be order-distinct is not quite the same as being
+ ** UNIQUE since a UNIQUE column or index can have multiple rows that
+ ** are NULL and NULL values are equivalent for the purpose of order-distinct.
+ ** To be order-distinct, the columns must be UNIQUE and NOT NULL.
+ **
+ ** The rowid for a table is always UNIQUE and NOT NULL so whenever the
+ ** rowid appears in the ORDER BY clause, the corresponding WhereLoop is
+ ** automatically order-distinct.
*/
- 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;
+ assert( pOrderBy!=0 );
+ if( nLoop && OptimizationDisabled(db, SQLITE_OrderByIdxJoin) ) return 0;
- 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]);
- }
+ nOrderBy = pOrderBy->nExpr;
+ testcase( nOrderBy==BMS-1 );
+ if( nOrderBy>BMS-1 ) return 0; /* Cannot optimize overly large ORDER BYs */
+ isOrderDistinct = 1;
+ obDone = MASKBIT(nOrderBy)-1;
+ orderDistinctMask = 0;
+ ready = 0;
+ for(iLoop=0; isOrderDistinct && obSat<obDone && iLoop<=nLoop; iLoop++){
+ if( iLoop>0 ) ready |= pLoop->maskSelf;
+ pLoop = iLoop<nLoop ? pPath->aLoop[iLoop] : pLast;
+ if( pLoop->wsFlags & WHERE_VIRTUALTABLE ){
+ if( pLoop->u.vtab.isOrdered ) obSat = obDone;
+ break;
}
- pLevel->op = OP_VNext;
- pLevel->p1 = iCur;
- pLevel->p2 = sqlite3VdbeCurrentAddr(v);
- sqlite3ReleaseTempRange(pParse, iReg, nConstraint+2);
- sqlite3ExprCachePop(pParse, 1);
- }else
-#endif /* SQLITE_OMIT_VIRTUALTABLE */
+ iCur = pWInfo->pTabList->a[pLoop->iTab].iCursor;
- 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.
+ /* Mark off any ORDER BY term X that is a column in the table of
+ ** the current loop for which there is term in the WHERE
+ ** clause of the form X IS NULL or X=? that reference only outer
+ ** loops.
*/
- 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;
+ for(i=0; i<nOrderBy; i++){
+ if( MASKBIT(i) & obSat ) continue;
+ pOBExpr = sqlite3ExprSkipCollate(pOrderBy->a[i].pExpr);
+ if( pOBExpr->op!=TK_COLUMN ) continue;
+ if( pOBExpr->iTable!=iCur ) continue;
+ pTerm = sqlite3WhereFindTerm(&pWInfo->sWC, iCur, pOBExpr->iColumn,
+ ~ready, WO_EQ|WO_ISNULL|WO_IS, 0);
+ if( pTerm==0 ) continue;
+ if( (pTerm->eOperator&(WO_EQ|WO_IS))!=0 && pOBExpr->iColumn>=0 ){
+ const char *z1, *z2;
+ pColl = sqlite3ExprCollSeq(pWInfo->pParse, pOrderBy->a[i].pExpr);
+ if( !pColl ) pColl = db->pDfltColl;
+ z1 = pColl->zName;
+ pColl = sqlite3ExprCollSeq(pWInfo->pParse, pTerm->pExpr);
+ if( !pColl ) pColl = db->pDfltColl;
+ z2 = pColl->zName;
+ if( sqlite3StrICmp(z1, z2)!=0 ) continue;
+ testcase( pTerm->pExpr->op==TK_IS );
+ }
+ obSat |= MASKBIT(i);
}
- 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;
+ if( (pLoop->wsFlags & WHERE_ONEROW)==0 ){
+ if( pLoop->wsFlags & WHERE_IPK ){
+ pIndex = 0;
+ nKeyCol = 0;
+ nColumn = 1;
+ }else if( (pIndex = pLoop->u.btree.pIndex)==0 || pIndex->bUnordered ){
+ return 0;
}else{
- testOp = bRev ? OP_Lt : OP_Gt;
+ nKeyCol = pIndex->nKeyCol;
+ nColumn = pIndex->nColumn;
+ assert( nColumn==nKeyCol+1 || !HasRowid(pIndex->pTable) );
+ assert( pIndex->aiColumn[nColumn-1]==XN_ROWID
+ || !HasRowid(pIndex->pTable));
+ isOrderDistinct = IsUniqueIndex(pIndex);
}
- 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;
+ /* Loop through all columns of the index and deal with the ones
+ ** that are not constrained by == or IN.
+ */
+ rev = revSet = 0;
+ distinctColumns = 0;
+ for(j=0; j<nColumn; j++){
+ u8 bOnce; /* True to run the ORDER BY search loop */
+
+ /* Skip over == and IS NULL terms */
+ if( j<pLoop->u.btree.nEq
+ && pLoop->nSkip==0
+ && ((i = pLoop->aLTerm[j]->eOperator) & (WO_EQ|WO_ISNULL|WO_IS))!=0
+ ){
+ if( i & WO_ISNULL ){
+ testcase( isOrderDistinct );
+ isOrderDistinct = 0;
+ }
+ continue;
+ }
- /* 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;
+ /* Get the column number in the table (iColumn) and sort order
+ ** (revIdx) for the j-th column of the index.
+ */
+ if( pIndex ){
+ iColumn = pIndex->aiColumn[j];
+ revIdx = pIndex->aSortOrder[j];
+ if( iColumn==pIndex->pTable->iPKey ) iColumn = -1;
+ }else{
+ iColumn = XN_ROWID;
+ revIdx = 0;
}
- if( sqlite3ExprNeedsNoAffinityChange(pRight, zStartAff[nEq]) ){
- zStartAff[nEq] = SQLITE_AFF_NONE;
+
+ /* An unconstrained column that might be NULL means that this
+ ** WhereLoop is not well-ordered
+ */
+ if( isOrderDistinct
+ && iColumn>=0
+ && j>=pLoop->u.btree.nEq
+ && pIndex->pTable->aCol[iColumn].notNull==0
+ ){
+ isOrderDistinct = 0;
}
- }
- 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;
+ /* Find the ORDER BY term that corresponds to the j-th column
+ ** of the index and mark that ORDER BY term off
+ */
+ bOnce = 1;
+ isMatch = 0;
+ for(i=0; bOnce && i<nOrderBy; i++){
+ if( MASKBIT(i) & obSat ) continue;
+ pOBExpr = sqlite3ExprSkipCollate(pOrderBy->a[i].pExpr);
+ testcase( wctrlFlags & WHERE_GROUPBY );
+ testcase( wctrlFlags & WHERE_DISTINCTBY );
+ if( (wctrlFlags & (WHERE_GROUPBY|WHERE_DISTINCTBY))==0 ) bOnce = 0;
+ if( iColumn>=(-1) ){
+ if( pOBExpr->op!=TK_COLUMN ) continue;
+ if( pOBExpr->iTable!=iCur ) continue;
+ if( pOBExpr->iColumn!=iColumn ) continue;
+ }else{
+ if( sqlite3ExprCompare(pOBExpr,pIndex->aColExpr->a[j].pExpr,iCur) ){
+ continue;
+ }
+ }
+ if( iColumn>=0 ){
+ pColl = sqlite3ExprCollSeq(pWInfo->pParse, pOrderBy->a[i].pExpr);
+ if( !pColl ) pColl = db->pDfltColl;
+ if( sqlite3StrICmp(pColl->zName, pIndex->azColl[j])!=0 ) continue;
+ }
+ isMatch = 1;
+ break;
}
- if( sqlite3ExprNeedsNoAffinityChange(pRight, zEndAff[nEq]) ){
- zEndAff[nEq] = SQLITE_AFF_NONE;
+ if( isMatch && (wctrlFlags & WHERE_GROUPBY)==0 ){
+ /* Make sure the sort order is compatible in an ORDER BY clause.
+ ** Sort order is irrelevant for a GROUP BY clause. */
+ if( revSet ){
+ if( (rev ^ revIdx)!=pOrderBy->a[i].sortOrder ) isMatch = 0;
+ }else{
+ rev = revIdx ^ pOrderBy->a[i].sortOrder;
+ if( rev ) *pRevMask |= MASKBIT(iLoop);
+ revSet = 1;
+ }
}
- }
- 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);
+ if( isMatch ){
+ if( iColumn<0 ){
+ testcase( distinctColumns==0 );
+ distinctColumns = 1;
+ }
+ obSat |= MASKBIT(i);
+ }else{
+ /* No match found */
+ if( j==0 || j<nKeyCol ){
+ testcase( isOrderDistinct!=0 );
+ isOrderDistinct = 0;
+ }
+ break;
+ }
+ } /* end Loop over all index columns */
+ if( distinctColumns ){
+ testcase( isOrderDistinct==0 );
+ isOrderDistinct = 1;
+ }
+ } /* end-if not one-row */
- /* 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);
+ /* Mark off any other ORDER BY terms that reference pLoop */
+ if( isOrderDistinct ){
+ orderDistinctMask |= pLoop->maskSelf;
+ for(i=0; i<nOrderBy; i++){
+ Expr *p;
+ Bitmask mTerm;
+ if( MASKBIT(i) & obSat ) continue;
+ p = pOrderBy->a[i].pExpr;
+ mTerm = sqlite3WhereExprUsage(&pWInfo->sMaskSet,p);
+ if( mTerm==0 && !sqlite3ExprIsConstant(p) ) continue;
+ if( (mTerm&~orderDistinctMask)==0 ){
+ obSat |= MASKBIT(i);
+ }
+ }
}
-
- /* 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);
+ } /* End the loop over all WhereLoops from outer-most down to inner-most */
+ if( obSat==obDone ) return (i8)nOrderBy;
+ if( !isOrderDistinct ){
+ for(i=nOrderBy-1; i>0; i--){
+ Bitmask m = MASKBIT(i) - 1;
+ if( (obSat&m)==m ) return i;
}
- sqlite3ReleaseTempReg(pParse, r1);
+ return 0;
+ }
+ return -1;
+}
- /* 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
+/*
+** If the WHERE_GROUPBY flag is set in the mask passed to sqlite3WhereBegin(),
+** the planner assumes that the specified pOrderBy list is actually a GROUP
+** BY clause - and so any order that groups rows as required satisfies the
+** request.
+**
+** Normally, in this case it is not possible for the caller to determine
+** whether or not the rows are really being delivered in sorted order, or
+** just in some other order that provides the required grouping. However,
+** if the WHERE_SORTBYGROUP flag is also passed to sqlite3WhereBegin(), then
+** this function may be called on the returned WhereInfo object. It returns
+** true if the rows really will be sorted in the specified order, or false
+** otherwise.
+**
+** For example, assuming:
+**
+** CREATE INDEX i1 ON t1(x, Y);
+**
+** then
+**
+** SELECT * FROM t1 GROUP BY x,y ORDER BY x,y; -- IsSorted()==1
+** SELECT * FROM t1 GROUP BY y,x ORDER BY y,x; -- IsSorted()==0
+*/
+SQLITE_PRIVATE int sqlite3WhereIsSorted(WhereInfo *pWInfo){
+ assert( pWInfo->wctrlFlags & WHERE_GROUPBY );
+ assert( pWInfo->wctrlFlags & WHERE_SORTBYGROUP );
+ return pWInfo->sorted;
+}
-#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) */
+#ifdef WHERETRACE_ENABLED
+/* For debugging use only: */
+static const char *wherePathName(WherePath *pPath, int nLoop, WhereLoop *pLast){
+ static char zName[65];
+ int i;
+ for(i=0; i<nLoop; i++){ zName[i] = pPath->aLoop[i]->cId; }
+ if( pLast ) zName[i++] = pLast->cId;
+ zName[i] = 0;
+ return zName;
+}
+#endif
- 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;
+/*
+** Return the cost of sorting nRow rows, assuming that the keys have
+** nOrderby columns and that the first nSorted columns are already in
+** order.
+*/
+static LogEst whereSortingCost(
+ WhereInfo *pWInfo,
+ LogEst nRow,
+ int nOrderBy,
+ int nSorted
+){
+ /* TUNING: Estimated cost of a full external sort, where N is
+ ** the number of rows to sort is:
+ **
+ ** cost = (3.0 * N * log(N)).
+ **
+ ** Or, if the order-by clause has X terms but only the last Y
+ ** terms are out of order, then block-sorting will reduce the
+ ** sorting cost to:
+ **
+ ** cost = (3.0 * N * log(N)) * (Y/X)
+ **
+ ** The (Y/X) term is implemented using stack variable rScale
+ ** below. */
+ LogEst rScale, rSortCost;
+ assert( nOrderBy>0 && 66==sqlite3LogEst(100) );
+ rScale = sqlite3LogEst((nOrderBy-nSorted)*100/nOrderBy) - 66;
+ rSortCost = nRow + estLog(nRow) + rScale + 16;
- /* 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;
- }
+ /* TUNING: The cost of implementing DISTINCT using a B-TREE is
+ ** similar but with a larger constant of proportionality.
+ ** Multiply by an additional factor of 3.0. */
+ if( pWInfo->wctrlFlags & WHERE_WANT_DISTINCT ){
+ rSortCost += 16;
+ }
- /* 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);
+ return rSortCost;
+}
- /* 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);
- }
- }
+/*
+** Given the list of WhereLoop objects at pWInfo->pLoops, this routine
+** attempts to find the lowest cost path that visits each WhereLoop
+** once. This path is then loaded into the pWInfo->a[].pWLoop fields.
+**
+** Assume that the total number of output rows that will need to be sorted
+** will be nRowEst (in the 10*log2 representation). Or, ignore sorting
+** costs if nRowEst==0.
+**
+** Return SQLITE_OK on success or SQLITE_NOMEM of a memory allocation
+** error occurs.
+*/
+static int wherePathSolver(WhereInfo *pWInfo, LogEst nRowEst){
+ int mxChoice; /* Maximum number of simultaneous paths tracked */
+ int nLoop; /* Number of terms in the join */
+ Parse *pParse; /* Parsing context */
+ sqlite3 *db; /* The database connection */
+ int iLoop; /* Loop counter over the terms of the join */
+ int ii, jj; /* Loop counters */
+ int mxI = 0; /* Index of next entry to replace */
+ int nOrderBy; /* Number of ORDER BY clause terms */
+ LogEst mxCost = 0; /* Maximum cost of a set of paths */
+ LogEst mxUnsorted = 0; /* Maximum unsorted cost of a set of path */
+ int nTo, nFrom; /* Number of valid entries in aTo[] and aFrom[] */
+ WherePath *aFrom; /* All nFrom paths at the previous level */
+ WherePath *aTo; /* The nTo best paths at the current level */
+ WherePath *pFrom; /* An element of aFrom[] that we are working on */
+ WherePath *pTo; /* An element of aTo[] that we are working on */
+ WhereLoop *pWLoop; /* One of the WhereLoop objects */
+ WhereLoop **pX; /* Used to divy up the pSpace memory */
+ LogEst *aSortCost = 0; /* Sorting and partial sorting costs */
+ char *pSpace; /* Temporary memory used by this routine */
+ int nSpace; /* Bytes of space allocated at pSpace */
- 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;
+ pParse = pWInfo->pParse;
+ db = pParse->db;
+ nLoop = pWInfo->nLevel;
+ /* TUNING: For simple queries, only the best path is tracked.
+ ** For 2-way joins, the 5 best paths are followed.
+ ** For joins of 3 or more tables, track the 10 best paths */
+ mxChoice = (nLoop<=1) ? 1 : (nLoop==2 ? 5 : 10);
+ assert( nLoop<=pWInfo->pTabList->nSrc );
+ WHERETRACE(0x002, ("---- begin solver. (nRowEst=%d)\n", nRowEst));
+
+ /* If nRowEst is zero and there is an ORDER BY clause, ignore it. In this
+ ** case the purpose of this call is to estimate the number of rows returned
+ ** by the overall query. Once this estimate has been obtained, the caller
+ ** will invoke this function a second time, passing the estimate as the
+ ** nRowEst parameter. */
+ if( pWInfo->pOrderBy==0 || nRowEst==0 ){
+ nOrderBy = 0;
+ }else{
+ nOrderBy = pWInfo->pOrderBy->nExpr;
+ }
+
+ /* Allocate and initialize space for aTo, aFrom and aSortCost[] */
+ nSpace = (sizeof(WherePath)+sizeof(WhereLoop*)*nLoop)*mxChoice*2;
+ nSpace += sizeof(LogEst) * nOrderBy;
+ pSpace = sqlite3DbMallocRaw(db, nSpace);
+ if( pSpace==0 ) return SQLITE_NOMEM;
+ aTo = (WherePath*)pSpace;
+ aFrom = aTo+mxChoice;
+ memset(aFrom, 0, sizeof(aFrom[0]));
+ pX = (WhereLoop**)(aFrom+mxChoice);
+ for(ii=mxChoice*2, pFrom=aTo; ii>0; ii--, pFrom++, pX += nLoop){
+ pFrom->aLoop = pX;
+ }
+ if( nOrderBy ){
+ /* If there is an ORDER BY clause and it is not being ignored, set up
+ ** space for the aSortCost[] array. Each element of the aSortCost array
+ ** is either zero - meaning it has not yet been initialized - or the
+ ** cost of sorting nRowEst rows of data where the first X terms of
+ ** the ORDER BY clause are already in order, where X is the array
+ ** index. */
+ aSortCost = (LogEst*)pX;
+ memset(aSortCost, 0, sizeof(LogEst) * nOrderBy);
+ }
+ assert( aSortCost==0 || &pSpace[nSpace]==(char*)&aSortCost[nOrderBy] );
+ assert( aSortCost!=0 || &pSpace[nSpace]==(char*)pX );
+
+ /* Seed the search with a single WherePath containing zero WhereLoops.
+ **
+ ** TUNING: Do not let the number of iterations go above 28. If the cost
+ ** of computing an automatic index is not paid back within the first 28
+ ** rows, then do not use the automatic index. */
+ aFrom[0].nRow = MIN(pParse->nQueryLoop, 48); assert( 48==sqlite3LogEst(28) );
+ nFrom = 1;
+ assert( aFrom[0].isOrdered==0 );
+ if( nOrderBy ){
+ /* If nLoop is zero, then there are no FROM terms in the query. Since
+ ** in this case the query may return a maximum of one row, the results
+ ** are already in the requested order. Set isOrdered to nOrderBy to
+ ** indicate this. Or, if nLoop is greater than zero, set isOrdered to
+ ** -1, indicating that the result set may or may not be ordered,
+ ** depending on the loops added to the current plan. */
+ aFrom[0].isOrdered = nLoop>0 ? -1 : nOrderBy;
+ }
+
+ /* Compute successively longer WherePaths using the previous generation
+ ** of WherePaths as the basis for the next. Keep track of the mxChoice
+ ** best paths at each generation */
+ for(iLoop=0; iLoop<nLoop; iLoop++){
+ nTo = 0;
+ for(ii=0, pFrom=aFrom; ii<nFrom; ii++, pFrom++){
+ for(pWLoop=pWInfo->pLoops; pWLoop; pWLoop=pWLoop->pNextLoop){
+ LogEst nOut; /* Rows visited by (pFrom+pWLoop) */
+ LogEst rCost; /* Cost of path (pFrom+pWLoop) */
+ LogEst rUnsorted; /* Unsorted cost of (pFrom+pWLoop) */
+ i8 isOrdered = pFrom->isOrdered; /* isOrdered for (pFrom+pWLoop) */
+ Bitmask maskNew; /* Mask of src visited by (..) */
+ Bitmask revMask = 0; /* Mask of rev-order loops for (..) */
+
+ if( (pWLoop->prereq & ~pFrom->maskLoop)!=0 ) continue;
+ if( (pWLoop->maskSelf & pFrom->maskLoop)!=0 ) continue;
+ /* At this point, pWLoop is a candidate to be the next loop.
+ ** Compute its cost */
+ rUnsorted = sqlite3LogEstAdd(pWLoop->rSetup,pWLoop->rRun + pFrom->nRow);
+ rUnsorted = sqlite3LogEstAdd(rUnsorted, pFrom->rUnsorted);
+ nOut = pFrom->nRow + pWLoop->nOut;
+ maskNew = pFrom->maskLoop | pWLoop->maskSelf;
+ if( isOrdered<0 ){
+ isOrdered = wherePathSatisfiesOrderBy(pWInfo,
+ pWInfo->pOrderBy, pFrom, pWInfo->wctrlFlags,
+ iLoop, pWLoop, &revMask);
+ }else{
+ revMask = pFrom->revLoop;
}
- /* 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);
+ if( isOrdered>=0 && isOrdered<nOrderBy ){
+ if( aSortCost[isOrdered]==0 ){
+ aSortCost[isOrdered] = whereSortingCost(
+ pWInfo, nRowEst, nOrderBy, isOrdered
+ );
}
- sqlite3VdbeAddOp2(v, OP_Gosub, regReturn, iLoopBody);
+ rCost = sqlite3LogEstAdd(rUnsorted, aSortCost[isOrdered]);
- /* 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;
+ WHERETRACE(0x002,
+ ("---- sort cost=%-3d (%d/%d) increases cost %3d to %-3d\n",
+ aSortCost[isOrdered], (nOrderBy-isOrdered), nOrderBy,
+ rUnsorted, rCost));
+ }else{
+ rCost = rUnsorted;
+ }
- /* 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)
+ /* Check to see if pWLoop should be added to the set of
+ ** mxChoice best-so-far paths.
+ **
+ ** First look for an existing path among best-so-far paths
+ ** that covers the same set of loops and has the same isOrdered
+ ** setting as the current path candidate.
+ **
+ ** The term "((pTo->isOrdered^isOrdered)&0x80)==0" is equivalent
+ ** to (pTo->isOrdered==(-1))==(isOrdered==(-1))" for the range
+ ** of legal values for isOrdered, -1..64.
+ */
+ for(jj=0, pTo=aTo; jj<nTo; jj++, pTo++){
+ if( pTo->maskLoop==maskNew
+ && ((pTo->isOrdered^isOrdered)&0x80)==0
){
- assert( pLvl->iIdxCur==iCovCur );
- pCov = pLvl->plan.u.pIdx;
+ testcase( jj==nTo-1 );
+ break;
+ }
+ }
+ if( jj>=nTo ){
+ /* None of the existing best-so-far paths match the candidate. */
+ if( nTo>=mxChoice
+ && (rCost>mxCost || (rCost==mxCost && rUnsorted>=mxUnsorted))
+ ){
+ /* The current candidate is no better than any of the mxChoice
+ ** paths currently in the best-so-far buffer. So discard
+ ** this candidate as not viable. */
+#ifdef WHERETRACE_ENABLED /* 0x4 */
+ if( sqlite3WhereTrace&0x4 ){
+ sqlite3DebugPrintf("Skip %s cost=%-3d,%3d order=%c\n",
+ wherePathName(pFrom, iLoop, pWLoop), rCost, nOut,
+ isOrdered>=0 ? isOrdered+'0' : '?');
+ }
+#endif
+ continue;
+ }
+ /* If we reach this points it means that the new candidate path
+ ** needs to be added to the set of best-so-far paths. */
+ if( nTo<mxChoice ){
+ /* Increase the size of the aTo set by one */
+ jj = nTo++;
}else{
- pCov = 0;
+ /* New path replaces the prior worst to keep count below mxChoice */
+ jj = mxI;
+ }
+ pTo = &aTo[jj];
+#ifdef WHERETRACE_ENABLED /* 0x4 */
+ if( sqlite3WhereTrace&0x4 ){
+ sqlite3DebugPrintf("New %s cost=%-3d,%3d order=%c\n",
+ wherePathName(pFrom, iLoop, pWLoop), rCost, nOut,
+ isOrdered>=0 ? isOrdered+'0' : '?');
+ }
+#endif
+ }else{
+ /* Control reaches here if best-so-far path pTo=aTo[jj] covers the
+ ** same set of loops and has the sam isOrdered setting as the
+ ** candidate path. Check to see if the candidate should replace
+ ** pTo or if the candidate should be skipped */
+ if( pTo->rCost<rCost || (pTo->rCost==rCost && pTo->nRow<=nOut) ){
+#ifdef WHERETRACE_ENABLED /* 0x4 */
+ if( sqlite3WhereTrace&0x4 ){
+ sqlite3DebugPrintf(
+ "Skip %s cost=%-3d,%3d order=%c",
+ wherePathName(pFrom, iLoop, pWLoop), rCost, nOut,
+ isOrdered>=0 ? isOrdered+'0' : '?');
+ sqlite3DebugPrintf(" vs %s cost=%-3d,%d order=%c\n",
+ wherePathName(pTo, iLoop+1, 0), pTo->rCost, pTo->nRow,
+ pTo->isOrdered>=0 ? pTo->isOrdered+'0' : '?');
+ }
+#endif
+ /* Discard the candidate path from further consideration */
+ testcase( pTo->rCost==rCost );
+ continue;
+ }
+ testcase( pTo->rCost==rCost+1 );
+ /* Control reaches here if the candidate path is better than the
+ ** pTo path. Replace pTo with the candidate. */
+#ifdef WHERETRACE_ENABLED /* 0x4 */
+ if( sqlite3WhereTrace&0x4 ){
+ sqlite3DebugPrintf(
+ "Update %s cost=%-3d,%3d order=%c",
+ wherePathName(pFrom, iLoop, pWLoop), rCost, nOut,
+ isOrdered>=0 ? isOrdered+'0' : '?');
+ sqlite3DebugPrintf(" was %s cost=%-3d,%3d order=%c\n",
+ wherePathName(pTo, iLoop+1, 0), pTo->rCost, pTo->nRow,
+ pTo->isOrdered>=0 ? pTo->isOrdered+'0' : '?');
+ }
+#endif
+ }
+ /* pWLoop is a winner. Add it to the set of best so far */
+ pTo->maskLoop = pFrom->maskLoop | pWLoop->maskSelf;
+ pTo->revLoop = revMask;
+ pTo->nRow = nOut;
+ pTo->rCost = rCost;
+ pTo->rUnsorted = rUnsorted;
+ pTo->isOrdered = isOrdered;
+ memcpy(pTo->aLoop, pFrom->aLoop, sizeof(WhereLoop*)*iLoop);
+ pTo->aLoop[iLoop] = pWLoop;
+ if( nTo>=mxChoice ){
+ mxI = 0;
+ mxCost = aTo[0].rCost;
+ mxUnsorted = aTo[0].nRow;
+ for(jj=1, pTo=&aTo[1]; jj<mxChoice; jj++, pTo++){
+ if( pTo->rCost>mxCost
+ || (pTo->rCost==mxCost && pTo->rUnsorted>mxUnsorted)
+ ){
+ mxCost = pTo->rCost;
+ mxUnsorted = pTo->rUnsorted;
+ mxI = jj;
+ }
}
-
- /* 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 */
+#ifdef WHERETRACE_ENABLED /* >=2 */
+ if( sqlite3WhereTrace & 0x02 ){
+ sqlite3DebugPrintf("---- after round %d ----\n", iLoop);
+ for(ii=0, pTo=aTo; ii<nTo; ii++, pTo++){
+ sqlite3DebugPrintf(" %s cost=%-3d nrow=%-3d order=%c",
+ wherePathName(pTo, iLoop+1, 0), pTo->rCost, pTo->nRow,
+ pTo->isOrdered>=0 ? (pTo->isOrdered+'0') : '?');
+ if( pTo->isOrdered>0 ){
+ sqlite3DebugPrintf(" rev=0x%llx\n", pTo->revLoop);
+ }else{
+ sqlite3DebugPrintf("\n");
+ }
+ }
+ }
+#endif
- {
- /* 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;
+ /* Swap the roles of aFrom and aTo for the next generation */
+ pFrom = aTo;
+ aTo = aFrom;
+ aFrom = pFrom;
+ nFrom = nTo;
}
- 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;
+ if( nFrom==0 ){
+ sqlite3ErrorMsg(pParse, "no query solution");
+ sqlite3DbFree(db, pSpace);
+ return SQLITE_ERROR;
+ }
+
+ /* Find the lowest cost path. pFrom will be left pointing to that path */
+ pFrom = aFrom;
+ for(ii=1; ii<nFrom; ii++){
+ if( pFrom->rCost>aFrom[ii].rCost ) pFrom = &aFrom[ii];
+ }
+ assert( pWInfo->nLevel==nLoop );
+ /* Load the lowest cost path into pWInfo */
+ for(iLoop=0; iLoop<nLoop; iLoop++){
+ WhereLevel *pLevel = pWInfo->a + iLoop;
+ pLevel->pWLoop = pWLoop = pFrom->aLoop[iLoop];
+ pLevel->iFrom = pWLoop->iTab;
+ pLevel->iTabCur = pWInfo->pTabList->a[pLevel->iFrom].iCursor;
+ }
+ if( (pWInfo->wctrlFlags & WHERE_WANT_DISTINCT)!=0
+ && (pWInfo->wctrlFlags & WHERE_DISTINCTBY)==0
+ && pWInfo->eDistinct==WHERE_DISTINCT_NOOP
+ && nRowEst
+ ){
+ Bitmask notUsed;
+ int rc = wherePathSatisfiesOrderBy(pWInfo, pWInfo->pResultSet, pFrom,
+ WHERE_DISTINCTBY, nLoop-1, pFrom->aLoop[nLoop-1], &notUsed);
+ if( rc==pWInfo->pResultSet->nExpr ){
+ pWInfo->eDistinct = WHERE_DISTINCT_ORDERED;
}
- 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;
+ if( pWInfo->pOrderBy ){
+ if( pWInfo->wctrlFlags & WHERE_DISTINCTBY ){
+ if( pFrom->isOrdered==pWInfo->pOrderBy->nExpr ){
+ pWInfo->eDistinct = WHERE_DISTINCT_ORDERED;
+ }
+ }else{
+ pWInfo->nOBSat = pFrom->isOrdered;
+ if( pWInfo->nOBSat<0 ) pWInfo->nOBSat = 0;
+ pWInfo->revMask = pFrom->revLoop;
+ }
+ if( (pWInfo->wctrlFlags & WHERE_SORTBYGROUP)
+ && pWInfo->nOBSat==pWInfo->pOrderBy->nExpr && nLoop>0
+ ){
+ Bitmask revMask = 0;
+ int nOrder = wherePathSatisfiesOrderBy(pWInfo, pWInfo->pOrderBy,
+ pFrom, 0, nLoop-1, pFrom->aLoop[nLoop-1], &revMask
+ );
+ assert( pWInfo->sorted==0 );
+ if( nOrder==pWInfo->pOrderBy->nExpr ){
+ pWInfo->sorted = 1;
+ pWInfo->revMask = revMask;
}
- 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 */
+ pWInfo->nRowOut = pFrom->nRow;
+ /* Free temporary memory and return success */
+ sqlite3DbFree(db, pSpace);
+ return SQLITE_OK;
+}
/*
-** Free a WhereInfo structure
+** Most queries use only a single table (they are not joins) and have
+** simple == constraints against indexed fields. This routine attempts
+** to plan those simple cases using much less ceremony than the
+** general-purpose query planner, and thereby yield faster sqlite3_prepare()
+** times for the common case.
+**
+** Return non-zero on success, if this query can be handled by this
+** no-frills query planner. Return zero if this query needs the
+** general-purpose query planner.
*/
-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);
- }
- }
+static int whereShortCut(WhereLoopBuilder *pBuilder){
+ WhereInfo *pWInfo;
+ struct SrcList_item *pItem;
+ WhereClause *pWC;
+ WhereTerm *pTerm;
+ WhereLoop *pLoop;
+ int iCur;
+ int j;
+ Table *pTab;
+ Index *pIdx;
+
+ pWInfo = pBuilder->pWInfo;
+ if( pWInfo->wctrlFlags & WHERE_FORCE_TABLE ) return 0;
+ assert( pWInfo->pTabList->nSrc>=1 );
+ pItem = pWInfo->pTabList->a;
+ pTab = pItem->pTab;
+ if( IsVirtual(pTab) ) return 0;
+ if( pItem->fg.isIndexedBy ) return 0;
+ iCur = pItem->iCursor;
+ pWC = &pWInfo->sWC;
+ pLoop = pBuilder->pNew;
+ pLoop->wsFlags = 0;
+ pLoop->nSkip = 0;
+ pTerm = sqlite3WhereFindTerm(pWC, iCur, -1, 0, WO_EQ|WO_IS, 0);
+ if( pTerm ){
+ testcase( pTerm->eOperator & WO_IS );
+ pLoop->wsFlags = WHERE_COLUMN_EQ|WHERE_IPK|WHERE_ONEROW;
+ pLoop->aLTerm[0] = pTerm;
+ pLoop->nLTerm = 1;
+ pLoop->u.btree.nEq = 1;
+ /* TUNING: Cost of a rowid lookup is 10 */
+ pLoop->rRun = 33; /* 33==sqlite3LogEst(10) */
+ }else{
+ for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){
+ int opMask;
+ assert( pLoop->aLTermSpace==pLoop->aLTerm );
+ if( !IsUniqueIndex(pIdx)
+ || pIdx->pPartIdxWhere!=0
+ || pIdx->nKeyCol>ArraySize(pLoop->aLTermSpace)
+ ) continue;
+ opMask = pIdx->uniqNotNull ? (WO_EQ|WO_IS) : WO_EQ;
+ for(j=0; j<pIdx->nKeyCol; j++){
+ pTerm = sqlite3WhereFindTerm(pWC, iCur, j, 0, opMask, pIdx);
+ if( pTerm==0 ) break;
+ testcase( pTerm->eOperator & WO_IS );
+ pLoop->aLTerm[j] = pTerm;
+ }
+ if( j!=pIdx->nKeyCol ) continue;
+ pLoop->wsFlags = WHERE_COLUMN_EQ|WHERE_ONEROW|WHERE_INDEXED;
+ if( pIdx->isCovering || (pItem->colUsed & ~columnsInIndex(pIdx))==0 ){
+ pLoop->wsFlags |= WHERE_IDX_ONLY;
+ }
+ pLoop->nLTerm = j;
+ pLoop->u.btree.nEq = j;
+ pLoop->u.btree.pIndex = pIdx;
+ /* TUNING: Cost of a unique index lookup is 15 */
+ pLoop->rRun = 39; /* 39==sqlite3LogEst(15) */
+ break;
}
- whereClauseClear(pWInfo->pWC);
- sqlite3DbFree(db, pWInfo);
}
+ if( pLoop->wsFlags ){
+ pLoop->nOut = (LogEst)1;
+ pWInfo->a[0].pWLoop = pLoop;
+ pLoop->maskSelf = sqlite3WhereGetMask(&pWInfo->sMaskSet, iCur);
+ pWInfo->a[0].iTabCur = iCur;
+ pWInfo->nRowOut = 1;
+ if( pWInfo->pOrderBy ) pWInfo->nOBSat = pWInfo->pOrderBy->nExpr;
+ if( pWInfo->wctrlFlags & WHERE_WANT_DISTINCT ){
+ pWInfo->eDistinct = WHERE_DISTINCT_UNIQUE;
+ }
+#ifdef SQLITE_DEBUG
+ pLoop->cId = '0';
+#endif
+ return 1;
+ }
+ return 0;
}
-
/*
** Generate the beginning of the loop used for WHERE clause processing.
** The return value is a pointer to an opaque structure that contains
@@ -107290,25 +126571,25 @@ static void whereInfoFree(sqlite3 *db, WhereInfo *pWInfo){
**
** ORDER BY CLAUSE PROCESSING
**
-** pOrderBy is a pointer to the ORDER BY clause of a SELECT statement,
+** pOrderBy is a pointer to the ORDER BY clause (or the GROUP BY clause
+** if the WHERE_GROUPBY flag is set in wctrlFlags) 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.
+** The iIdxCur parameter is the cursor number of an index. If
+** WHERE_ONETABLE_ONLY is set, iIdxCur is the cursor number of an index
+** to use for OR clause processing. The WHERE clause should use this
+** specific cursor. If WHERE_ONEPASS_DESIRED is set, then iIdxCur is
+** the first cursor in an array of cursors for all indices. iIdxCur should
+** be used to compute the appropriate cursor depending on which index is
+** used.
*/
SQLITE_PRIVATE WhereInfo *sqlite3WhereBegin(
Parse *pParse, /* The parser context */
- SrcList *pTabList, /* A list of all tables to be scanned */
+ SrcList *pTabList, /* FROM clause: 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 */
+ ExprList *pOrderBy, /* An ORDER BY (or GROUP BY) clause, or NULL */
+ ExprList *pResultSet, /* Result set of the query */
u16 wctrlFlags, /* One of the WHERE_* flags defined in sqliteInt.h */
int iIdxCur /* If WHERE_ONETABLE_ONLY is set, index cursor number */
){
@@ -107317,18 +126598,34 @@ SQLITE_PRIVATE WhereInfo *sqlite3WhereBegin(
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 */
+ WhereLoopBuilder sWLB; /* The WhereLoop builder */
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 */
+ WhereLoop *pLoop; /* Pointer to a single WhereLoop object */
int ii; /* Loop counter */
sqlite3 *db; /* Database connection */
+ int rc; /* Return code */
+ u8 bFordelete = 0;
+ assert( (wctrlFlags & WHERE_ONEPASS_MULTIROW)==0 || (
+ (wctrlFlags & WHERE_ONEPASS_DESIRED)!=0
+ && (wctrlFlags & WHERE_OMIT_OPEN_CLOSE)==0
+ ));
/* Variable initialization */
- memset(&sWBI, 0, sizeof(sWBI));
- sWBI.pParse = pParse;
+ db = pParse->db;
+ memset(&sWLB, 0, sizeof(sWLB));
+
+ /* An ORDER/GROUP BY clause of more than 63 terms cannot be optimized */
+ testcase( pOrderBy && pOrderBy->nExpr==BMS-1 );
+ if( pOrderBy && pOrderBy->nExpr>=BMS ) pOrderBy = 0;
+ sWLB.pOrderBy = pOrderBy;
+
+ /* Disable the DISTINCT optimization if SQLITE_DistinctOpt is set via
+ ** sqlite3_test_ctrl(SQLITE_TESTCTRL_OPTIMIZATIONS,...) */
+ if( OptimizationDisabled(db, SQLITE_DistinctOpt) ){
+ wctrlFlags &= ~WHERE_WANT_DISTINCT;
+ }
/* The number of tables in the FROM clause is limited by the number of
** bits in a Bitmask
@@ -107353,363 +126650,229 @@ SQLITE_PRIVATE WhereInfo *sqlite3WhereBegin(
** 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)
- );
+ pWInfo = sqlite3DbMallocZero(db, nByteWInfo + sizeof(WhereLoop));
if( db->mallocFailed ){
sqlite3DbFree(db, pWInfo);
pWInfo = 0;
goto whereBeginError;
}
+ pWInfo->aiCurOnePass[0] = pWInfo->aiCurOnePass[1] = -1;
pWInfo->nLevel = nTabList;
pWInfo->pParse = pParse;
pWInfo->pTabList = pTabList;
- pWInfo->iBreak = sqlite3VdbeMakeLabel(v);
- pWInfo->pWC = sWBI.pWC = (WhereClause *)&((u8 *)pWInfo)[nByteWInfo];
+ pWInfo->pOrderBy = pOrderBy;
+ pWInfo->pResultSet = pResultSet;
+ pWInfo->iBreak = pWInfo->iContinue = sqlite3VdbeMakeLabel(v);
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;
+ assert( pWInfo->eOnePass==ONEPASS_OFF ); /* ONEPASS defaults to OFF */
+ pMaskSet = &pWInfo->sMaskSet;
+ sWLB.pWInfo = pWInfo;
+ sWLB.pWC = &pWInfo->sWC;
+ sWLB.pNew = (WhereLoop*)(((char*)pWInfo)+nByteWInfo);
+ assert( EIGHT_BYTE_ALIGNMENT(sWLB.pNew) );
+ whereLoopInit(sWLB.pNew);
+#ifdef SQLITE_DEBUG
+ sWLB.pNew->cId = '*';
+#endif
/* 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 */
+ sqlite3WhereClauseInit(&pWInfo->sWC, pWInfo);
+ sqlite3WhereSplit(&pWInfo->sWC, pWhere, TK_AND);
/* 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;
+ for(ii=0; ii<sWLB.pWC->nTerm; ii++){
+ if( nTabList==0 || sqlite3ExprIsConstantNotJoin(sWLB.pWC->a[ii].pExpr) ){
+ sqlite3ExprIfFalse(pParse, sWLB.pWC->a[ii].pExpr, pWInfo->iBreak,
+ SQLITE_JUMPIFNULL);
+ sWLB.pWC->a[ii].wtFlags |= TERM_CODED;
+ }
+ }
+
+ /* Special case: No FROM clause
+ */
+ if( nTabList==0 ){
+ if( pOrderBy ) pWInfo->nOBSat = pOrderBy->nExpr;
+ if( wctrlFlags & WHERE_WANT_DISTINCT ){
+ pWInfo->eDistinct = WHERE_DISTINCT_UNIQUE;
+ }
}
/* 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.
+ ** The N-th term of the FROM clause is assigned a bitmask of 1<<N.
**
- ** 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.
+ ** The rule of the previous sentence ensures thta if X is the bitmask for
+ ** a table T, then X-1 is the bitmask for all other tables to the left of T.
+ ** Knowing the bitmask for all tables to the left of a left join is
+ ** important. Ticket #3015.
**
** 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
+ sqlite3WhereTabFuncArgs(pParse, &pTabList->a[ii], &pWInfo->sWC);
}
-#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;
- }
+#ifdef SQLITE_DEBUG
+ for(ii=0; ii<pTabList->nSrc; ii++){
+ Bitmask m = sqlite3WhereGetMask(pMaskSet, pTabList->a[ii].iCursor);
+ assert( m==MASKBIT(ii) );
}
#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;
+ /* Analyze all of the subexpressions. */
+ sqlite3WhereExprAnalyze(pTabList, &pWInfo->sWC);
+ if( db->mallocFailed ) goto whereBeginError;
+
+ if( wctrlFlags & WHERE_WANT_DISTINCT ){
+ if( isDistinctRedundant(pParse, pTabList, &pWInfo->sWC, pResultSet) ){
+ /* The DISTINCT marking is pointless. Ignore it. */
+ pWInfo->eDistinct = WHERE_DISTINCT_UNIQUE;
+ }else if( pOrderBy==0 ){
+ /* Try to ORDER BY the result set to make distinct processing easier */
+ pWInfo->wctrlFlags |= WHERE_DISTINCTBY;
+ pWInfo->pOrderBy = pResultSet;
+ }
}
- /* 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;
+ /* Construct the WhereLoop objects */
+ WHERETRACE(0xffff,("*** Optimizer Start *** (wctrlFlags: 0x%x)\n",
+ wctrlFlags));
+#if defined(WHERETRACE_ENABLED)
+ if( sqlite3WhereTrace & 0x100 ){ /* Display all terms of the WHERE clause */
+ int i;
+ for(i=0; i<sWLB.pWC->nTerm; i++){
+ whereTermPrint(&sWLB.pWC->a[i], i);
+ }
}
+#endif
- /* 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++;
+ if( nTabList!=1 || whereShortCut(&sWLB)==0 ){
+ rc = whereLoopAddAll(&sWLB);
+ if( rc ) goto whereBeginError;
- 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++;
+#ifdef WHERETRACE_ENABLED
+ if( sqlite3WhereTrace ){ /* Display all of the WhereLoop objects */
+ WhereLoop *p;
+ int i;
+ static const char zLabel[] = "0123456789abcdefghijklmnopqrstuvwyxz"
+ "ABCDEFGHIJKLMNOPQRSTUVWYXZ";
+ for(p=pWInfo->pLoops, i=0; p; p=p->pNextLoop, i++){
+ p->cId = zLabel[i%sizeof(zLabel)];
+ whereLoopPrint(p, sWLB.pWC);
}
- }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 );
- }
+#endif
+
+ wherePathSolver(pWInfo, 0);
+ if( db->mallocFailed ) goto whereBeginError;
+ if( pWInfo->pOrderBy ){
+ wherePathSolver(pWInfo, pWInfo->nRowOut+1);
+ if( db->mallocFailed ) goto whereBeginError;
}
}
- WHERETRACE(("*** Optimizer Finished ***\n"));
- if( pParse->nErr || db->mallocFailed ){
+ if( pWInfo->pOrderBy==0 && (db->flags & SQLITE_ReverseOrder)!=0 ){
+ pWInfo->revMask = (Bitmask)(-1);
+ }
+ if( pParse->nErr || NEVER(db->mallocFailed) ){
goto whereBeginError;
}
- if( nTabList ){
- pLevel--;
- pWInfo->nOBSat = pLevel->plan.nOBSat;
- }else{
- pWInfo->nOBSat = 0;
+#ifdef WHERETRACE_ENABLED
+ if( sqlite3WhereTrace ){
+ sqlite3DebugPrintf("---- Solution nRow=%d", pWInfo->nRowOut);
+ if( pWInfo->nOBSat>0 ){
+ sqlite3DebugPrintf(" ORDERBY=%d,0x%llx", pWInfo->nOBSat, pWInfo->revMask);
+ }
+ switch( pWInfo->eDistinct ){
+ case WHERE_DISTINCT_UNIQUE: {
+ sqlite3DebugPrintf(" DISTINCT=unique");
+ break;
+ }
+ case WHERE_DISTINCT_ORDERED: {
+ sqlite3DebugPrintf(" DISTINCT=ordered");
+ break;
+ }
+ case WHERE_DISTINCT_UNORDERED: {
+ sqlite3DebugPrintf(" DISTINCT=unordered");
+ break;
+ }
+ }
+ sqlite3DebugPrintf("\n");
+ for(ii=0; ii<pWInfo->nLevel; ii++){
+ whereLoopPrint(pWInfo->a[ii].pWLoop, sWLB.pWC);
+ }
}
-
- /* 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;
+#endif
+ /* Attempt to omit tables from the join that do not effect the result */
+ if( pWInfo->nLevel>=2
+ && pResultSet!=0
+ && OptimizationEnabled(db, SQLITE_OmitNoopJoin)
+ ){
+ Bitmask tabUsed = sqlite3WhereExprListUsage(pMaskSet, pResultSet);
+ if( sWLB.pOrderBy ){
+ tabUsed |= sqlite3WhereExprListUsage(pMaskSet, sWLB.pOrderBy);
+ }
+ while( pWInfo->nLevel>=2 ){
+ WhereTerm *pTerm, *pEnd;
+ pLoop = pWInfo->a[pWInfo->nLevel-1].pWLoop;
+ if( (pWInfo->pTabList->a[pLoop->iTab].fg.jointype & JT_LEFT)==0 ) break;
+ if( (wctrlFlags & WHERE_WANT_DISTINCT)==0
+ && (pLoop->wsFlags & WHERE_ONEROW)==0
+ ){
+ break;
+ }
+ if( (tabUsed & pLoop->maskSelf)!=0 ) break;
+ pEnd = sWLB.pWC->a + sWLB.pWC->nTerm;
+ for(pTerm=sWLB.pWC->a; pTerm<pEnd; pTerm++){
+ if( (pTerm->prereqAll & pLoop->maskSelf)!=0
+ && !ExprHasProperty(pTerm->pExpr, EP_FromJoin)
+ ){
+ break;
+ }
+ }
+ if( pTerm<pEnd ) break;
+ WHERETRACE(0xffff, ("-> drop loop %c not used\n", pLoop->cId));
+ pWInfo->nLevel--;
+ nTabList--;
+ }
}
+ WHERETRACE(0xffff,("*** Optimizer Finished ***\n"));
+ pWInfo->pParse->nQueryLoop += pWInfo->nRowOut;
/* 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.
+ ** The one-pass algorithm only works if the WHERE clause constrains
+ ** the statement to update or delete 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;
+ if( (wctrlFlags & WHERE_ONEPASS_DESIRED)!=0 ){
+ int wsFlags = pWInfo->a[0].pWLoop->wsFlags;
+ int bOnerow = (wsFlags & WHERE_ONEROW)!=0;
+ if( bOnerow || ( (wctrlFlags & WHERE_ONEPASS_MULTIROW)
+ && 0==(wsFlags & WHERE_VIRTUALTABLE)
+ )){
+ pWInfo->eOnePass = bOnerow ? ONEPASS_SINGLE : ONEPASS_MULTI;
+ if( HasRowid(pTabList->a[0].pTab) && (wsFlags & WHERE_IDX_ONLY) ){
+ if( wctrlFlags & WHERE_ONEPASS_MULTIROW ){
+ bFordelete = OPFLAG_FORDELETE;
+ }
+ pWInfo->a[0].pWLoop->wsFlags = (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 */
@@ -107717,13 +126880,13 @@ SQLITE_PRIVATE WhereInfo *sqlite3WhereBegin(
pTabItem = &pTabList->a[pLevel->iFrom];
pTab = pTabItem->pTab;
- pWInfo->nRowOut *= pLevel->plan.nRow;
iDb = sqlite3SchemaToIndex(db, pTab->pSchema);
+ pLoop = pLevel->pWLoop;
if( (pTab->tabFlags & TF_Ephemeral)!=0 || pTab->pSelect ){
/* Do nothing */
}else
#ifndef SQLITE_OMIT_VIRTUALTABLE
- if( (pLevel->plan.wsFlags & WHERE_VIRTUALTABLE)!=0 ){
+ if( (pLoop->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);
@@ -107731,13 +126894,18 @@ SQLITE_PRIVATE WhereInfo *sqlite3WhereBegin(
/* noop */
}else
#endif
- if( (pLevel->plan.wsFlags & WHERE_IDX_ONLY)==0
+ if( (pLoop->wsFlags & WHERE_IDX_ONLY)==0
&& (wctrlFlags & WHERE_OMIT_OPEN_CLOSE)==0 ){
- int op = pWInfo->okOnePass ? OP_OpenWrite : OP_OpenRead;
+ int op = OP_OpenRead;
+ if( pWInfo->eOnePass!=ONEPASS_OFF ){
+ op = OP_OpenWrite;
+ pWInfo->aiCurOnePass[0] = pTabItem->iCursor;
+ };
sqlite3OpenTable(pParse, pTabItem->iCursor, iDb, pTab, op);
- testcase( pTab->nCol==BMS-1 );
- testcase( pTab->nCol==BMS );
- if( !pWInfo->okOnePass && pTab->nCol<BMS ){
+ assert( pTabItem->iCursor==pLevel->iTabCur );
+ testcase( pWInfo->eOnePass==ONEPASS_OFF && pTab->nCol==BMS-1 );
+ testcase( pWInfo->eOnePass==ONEPASS_OFF && pTab->nCol==BMS );
+ if( pWInfo->eOnePass==ONEPASS_OFF && pTab->nCol<BMS && HasRowid(pTab) ){
Bitmask b = pTabItem->colUsed;
int n = 0;
for(; b; b=b>>1, n++){}
@@ -107745,26 +126913,81 @@ SQLITE_PRIVATE WhereInfo *sqlite3WhereBegin(
SQLITE_INT_TO_PTR(n), P4_INT32);
assert( n<=pTab->nCol );
}
+#ifdef SQLITE_ENABLE_CURSOR_HINTS
+ if( pLoop->u.btree.pIndex!=0 ){
+ sqlite3VdbeChangeP5(v, OPFLAG_SEEKEQ|bFordelete);
+ }else
+#endif
+ {
+ sqlite3VdbeChangeP5(v, bFordelete);
+ }
+#ifdef SQLITE_ENABLE_COLUMN_USED_MASK
+ sqlite3VdbeAddOp4Dup8(v, OP_ColumnsUsed, pTabItem->iCursor, 0, 0,
+ (const u8*)&pTabItem->colUsed, P4_INT64);
+#endif
}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;
+ if( pLoop->wsFlags & WHERE_INDEXED ){
+ Index *pIx = pLoop->u.btree.pIndex;
+ int iIndexCur;
+ int op = OP_OpenRead;
+ /* iIdxCur is always set if to a positive value if ONEPASS is possible */
+ assert( iIdxCur!=0 || (pWInfo->wctrlFlags & WHERE_ONEPASS_DESIRED)==0 );
+ if( !HasRowid(pTab) && IsPrimaryKeyIndex(pIx)
+ && (wctrlFlags & WHERE_ONETABLE_ONLY)!=0
+ ){
+ /* This is one term of an OR-optimization using the PRIMARY KEY of a
+ ** WITHOUT ROWID table. No need for a separate index */
+ iIndexCur = pLevel->iTabCur;
+ op = 0;
+ }else if( pWInfo->eOnePass!=ONEPASS_OFF ){
+ Index *pJ = pTabItem->pTab->pIndex;
+ iIndexCur = iIdxCur;
+ assert( wctrlFlags & WHERE_ONEPASS_DESIRED );
+ while( ALWAYS(pJ) && pJ!=pIx ){
+ iIndexCur++;
+ pJ = pJ->pNext;
+ }
+ op = OP_OpenWrite;
+ pWInfo->aiCurOnePass[1] = iIndexCur;
+ }else if( iIdxCur && (wctrlFlags & WHERE_ONETABLE_ONLY)!=0 ){
+ iIndexCur = iIdxCur;
+ if( wctrlFlags & WHERE_REOPEN_IDX ) op = OP_ReopenIdx;
+ }else{
+ iIndexCur = pParse->nTab++;
+ }
+ pLevel->iIdxCur = iIndexCur;
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));
+ if( op ){
+ sqlite3VdbeAddOp3(v, op, iIndexCur, pIx->tnum, iDb);
+ sqlite3VdbeSetP4KeyInfo(pParse, pIx);
+ if( (pLoop->wsFlags & WHERE_CONSTRAINT)!=0
+ && (pLoop->wsFlags & (WHERE_COLUMN_RANGE|WHERE_SKIPSCAN))==0
+ && (pWInfo->wctrlFlags&WHERE_ORDERBY_MIN)==0
+ ){
+ sqlite3VdbeChangeP5(v, OPFLAG_SEEKEQ); /* Hint to COMDB2 */
+ }
+ VdbeComment((v, "%s", pIx->zName));
+#ifdef SQLITE_ENABLE_COLUMN_USED_MASK
+ {
+ u64 colUsed = 0;
+ int ii, jj;
+ for(ii=0; ii<pIx->nColumn; ii++){
+ jj = pIx->aiColumn[ii];
+ if( jj<0 ) continue;
+ if( jj>63 ) jj = 63;
+ if( (pTabItem->colUsed & MASKBIT(jj))==0 ) continue;
+ colUsed |= ((u64)1)<<(ii<63 ? ii : 63);
+ }
+ sqlite3VdbeAddOp4Dup8(v, OP_ColumnsUsed, iIndexCur, 0, 0,
+ (u8*)&colUsed, P4_INT64);
+ }
+#endif /* SQLITE_ENABLE_COLUMN_USED_MASK */
+ }
}
- sqlite3CodeVerifySchema(pParse, iDb);
- notReady &= ~getMask(sWBI.pWC->pMaskSet, pTabItem->iCursor);
+ if( iDb>=0 ) sqlite3CodeVerifySchema(pParse, iDb);
}
pWInfo->iTop = sqlite3VdbeCurrentAddr(v);
if( db->mallocFailed ) goto whereBeginError;
@@ -107775,68 +126998,30 @@ SQLITE_PRIVATE WhereInfo *sqlite3WhereBegin(
*/
notReady = ~(Bitmask)0;
for(ii=0; ii<nTabList; ii++){
+ int addrExplain;
+ int wsFlags;
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++] = ' ';
+ wsFlags = pLevel->pWLoop->wsFlags;
+#ifndef SQLITE_OMIT_AUTOMATIC_INDEX
+ if( (pLevel->pWLoop->wsFlags & WHERE_AUTO_INDEX)!=0 ){
+ constructAutomaticIndex(pParse, &pWInfo->sWC,
+ &pTabList->a[pLevel->iFrom], notReady, pLevel);
+ if( db->mallocFailed ) goto whereBeginError;
}
- 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;
+#endif
+ addrExplain = sqlite3WhereExplainOneScan(
+ pParse, pTabList, pLevel, ii, pLevel->iFrom, wctrlFlags
+ );
+ pLevel->addrBody = sqlite3VdbeCurrentAddr(v);
+ notReady = sqlite3WhereCodeOneLoopStart(pWInfo, ii, notReady);
+ pWInfo->iContinue = pLevel->addrCont;
+ if( (wsFlags&WHERE_MULTI_OR)==0 && (wctrlFlags&WHERE_ONETABLE_ONLY)==0 ){
+ sqlite3WhereAddScanStatus(v, pTabList, pLevel, addrExplain);
}
}
- 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.
- */
+ /* Done. */
+ VdbeModuleComment((v, "Begin WHERE-core"));
return pWInfo;
/* Jump here if malloc fails */
@@ -107857,49 +127042,78 @@ SQLITE_PRIVATE void sqlite3WhereEnd(WhereInfo *pWInfo){
Vdbe *v = pParse->pVdbe;
int i;
WhereLevel *pLevel;
+ WhereLoop *pLoop;
SrcList *pTabList = pWInfo->pTabList;
sqlite3 *db = pParse->db;
/* Generate loop termination code.
*/
+ VdbeModuleComment((v, "End WHERE-core"));
sqlite3ExprCacheClear(pParse);
for(i=pWInfo->nLevel-1; i>=0; i--){
+ int addr;
pLevel = &pWInfo->a[i];
+ pLoop = pLevel->pWLoop;
sqlite3VdbeResolveLabel(v, pLevel->addrCont);
if( pLevel->op!=OP_Noop ){
- sqlite3VdbeAddOp2(v, pLevel->op, pLevel->p1, pLevel->p2);
+ sqlite3VdbeAddOp3(v, pLevel->op, pLevel->p1, pLevel->p2, pLevel->p3);
sqlite3VdbeChangeP5(v, pLevel->p5);
+ VdbeCoverage(v);
+ VdbeCoverageIf(v, pLevel->op==OP_Next);
+ VdbeCoverageIf(v, pLevel->op==OP_Prev);
+ VdbeCoverageIf(v, pLevel->op==OP_VNext);
}
- if( pLevel->plan.wsFlags & WHERE_IN_ABLE && pLevel->u.in.nIn>0 ){
+ if( pLoop->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);
+ sqlite3VdbeAddOp2(v, pIn->eEndLoopOp, pIn->iCur, pIn->addrInTop);
+ VdbeCoverage(v);
+ VdbeCoverageIf(v, pIn->eEndLoopOp==OP_PrevIfOpen);
+ VdbeCoverageIf(v, pIn->eEndLoopOp==OP_NextIfOpen);
sqlite3VdbeJumpHere(v, pIn->addrInTop-1);
}
- sqlite3DbFree(db, pLevel->u.in.aInLoop);
}
sqlite3VdbeResolveLabel(v, pLevel->addrBrk);
+ if( pLevel->addrSkip ){
+ sqlite3VdbeGoto(v, pLevel->addrSkip);
+ VdbeComment((v, "next skip-scan on %s", pLoop->u.btree.pIndex->zName));
+ sqlite3VdbeJumpHere(v, pLevel->addrSkip);
+ sqlite3VdbeJumpHere(v, pLevel->addrSkip-2);
+ }
+#ifndef SQLITE_LIKE_DOESNT_MATCH_BLOBS
+ if( pLevel->addrLikeRep ){
+ int op;
+ if( sqlite3VdbeGetOp(v, pLevel->addrLikeRep-1)->p1 ){
+ op = OP_DecrJumpZero;
+ }else{
+ op = OP_JumpZeroIncr;
+ }
+ sqlite3VdbeAddOp2(v, op, pLevel->iLikeRepCntr, pLevel->addrLikeRep);
+ VdbeCoverage(v);
+ }
+#endif
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 ){
+ addr = sqlite3VdbeAddOp1(v, OP_IfPos, pLevel->iLeftJoin); VdbeCoverage(v);
+ assert( (pLoop->wsFlags & WHERE_IDX_ONLY)==0
+ || (pLoop->wsFlags & WHERE_INDEXED)!=0 );
+ if( (pLoop->wsFlags & WHERE_IDX_ONLY)==0 ){
sqlite3VdbeAddOp1(v, OP_NullRow, pTabList->a[i].iCursor);
}
- if( pLevel->iIdxCur>=0 ){
+ if( pLoop->wsFlags & WHERE_INDEXED ){
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);
+ sqlite3VdbeGoto(v, pLevel->addrFirst);
}
sqlite3VdbeJumpHere(v, addr);
}
+ VdbeModuleComment((v, "End WHERE-loop%d: %s", i,
+ pWInfo->pTabList->a[pLevel->iFrom].pTab->zName));
}
/* The "break" point is here, just past the end of the outer loop.
@@ -107907,33 +127121,51 @@ SQLITE_PRIVATE void sqlite3WhereEnd(WhereInfo *pWInfo){
*/
sqlite3VdbeResolveLabel(v, pWInfo->iBreak);
- /* Close all of the cursors that were opened by sqlite3WhereBegin.
- */
- assert( pWInfo->nLevel==1 || pWInfo->nLevel==pTabList->nSrc );
+ assert( pWInfo->nLevel<=pTabList->nSrc );
for(i=0, pLevel=pWInfo->a; i<pWInfo->nLevel; i++, pLevel++){
+ int k, last;
+ VdbeOp *pOp;
Index *pIdx = 0;
struct SrcList_item *pTabItem = &pTabList->a[pLevel->iFrom];
Table *pTab = pTabItem->pTab;
assert( pTab!=0 );
+ pLoop = pLevel->pWLoop;
+
+ /* For a co-routine, change all OP_Column references to the table of
+ ** the co-routine into OP_Copy of result contained in a register.
+ ** OP_Rowid becomes OP_Null.
+ */
+ if( pTabItem->fg.viaCoroutine && !db->mallocFailed ){
+ translateColumnToCopy(v, pLevel->addrBody, pLevel->iTabCur,
+ pTabItem->regResult, 0);
+ continue;
+ }
+
+ /* Close all of the cursors that were opened by sqlite3WhereBegin.
+ ** Except, do not close cursors that will be reused by the OR optimization
+ ** (WHERE_OMIT_OPEN_CLOSE). And do not close the OP_OpenWrite cursors
+ ** created for the ONEPASS optimization.
+ */
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 ){
+ int ws = pLoop->wsFlags;
+ if( pWInfo->eOnePass==ONEPASS_OFF && (ws & WHERE_IDX_ONLY)==0 ){
sqlite3VdbeAddOp1(v, OP_Close, pTabItem->iCursor);
}
- if( (ws & WHERE_INDEXED)!=0 && (ws & WHERE_TEMP_INDEX)==0 ){
+ if( (ws & WHERE_INDEXED)!=0
+ && (ws & (WHERE_IPK|WHERE_AUTO_INDEX))==0
+ && pLevel->iIdxCur!=pWInfo->aiCurOnePass[1]
+ ){
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.
+ /* If this scan uses an index, make VDBE code substitutions to read data
+ ** from the index instead of from the table where possible. In some cases
+ ** this optimization prevents the table from ever being read, which can
+ ** yield a significant performance boost.
**
** Calls to the code generator in between sqlite3WhereBegin and
** sqlite3WhereEnd will have created code that references the table
@@ -107941,29 +127173,34 @@ SQLITE_PRIVATE void sqlite3WhereEnd(WhereInfo *pWInfo){
** 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 ){
+ if( pLoop->wsFlags & (WHERE_INDEXED|WHERE_IDX_ONLY) ){
+ pIdx = pLoop->u.btree.pIndex;
+ }else if( pLoop->wsFlags & WHERE_MULTI_OR ){
pIdx = pLevel->u.pCovidx;
}
- if( pIdx && !db->mallocFailed){
- int k, j, last;
- VdbeOp *pOp;
-
- pOp = sqlite3VdbeGetOp(v, pWInfo->iTop);
+ if( pIdx
+ && (pWInfo->eOnePass==ONEPASS_OFF || !HasRowid(pIdx->pTable))
+ && !db->mallocFailed
+ ){
last = sqlite3VdbeCurrentAddr(v);
- for(k=pWInfo->iTop; k<last; k++, pOp++){
+ k = pLevel->addrBody;
+ pOp = sqlite3VdbeGetOp(v, k);
+ for(; 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;
- }
+ int x = pOp->p2;
+ assert( pIdx->pTable==pTab );
+ if( !HasRowid(pTab) ){
+ Index *pPk = sqlite3PrimaryKeyIndex(pTab);
+ x = pPk->aiColumn[x];
+ assert( x>=0 );
+ }
+ x = sqlite3ColumnOfIndex(pIdx, x);
+ if( x>=0 ){
+ pOp->p2 = x;
+ pOp->p1 = pLevel->iIdxCur;
}
- assert( (pLevel->plan.wsFlags & WHERE_IDX_ONLY)==0
- || j<pIdx->nColumn );
+ assert( (pLoop->wsFlags & WHERE_IDX_ONLY)==0 || x>=0 );
}else if( pOp->opcode==OP_Rowid ){
pOp->p1 = pLevel->iIdxCur;
pOp->opcode = OP_IdxRowid;
@@ -107981,19 +127218,34 @@ SQLITE_PRIVATE void sqlite3WhereEnd(WhereInfo *pWInfo){
/************** End of where.c ***********************************************/
/************** Begin file parse.c *******************************************/
-/* Driver template for the LEMON parser generator.
-** The author disclaims copyright to this source code.
+/*
+** 2000-05-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.
+**
+*************************************************************************
+** Driver template for the LEMON parser generator.
**
-** 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.
+** The "lemon" program processes an LALR(1) input grammar file, then uses
+** this template to construct a parser. The "lemon" program inserts text
+** at each "%%" line. Also, any "P-a-r-s-e" identifer prefix (without the
+** interstitial "-" characters) contained in this template is changed into
+** the value of the %name directive from the grammar. Otherwise, the content
+** of this template is copied straight through into the generate parser
+** source file.
+**
+** The following is the concatenation of all %include directives from the
+** input grammar file:
*/
-/* First off, code is included that follows the "include" declaration
-** in the input grammar file. */
/* #include <stdio.h> */
+/************ Begin %include sections from the grammar ************************/
+/* #include "sqliteInt.h" */
/*
** Disable all error recovery processing in the parser push-down
@@ -108007,6 +127259,18 @@ SQLITE_PRIVATE void sqlite3WhereEnd(WhereInfo *pWInfo){
#define yytestcase(X) testcase(X)
/*
+** Indicate that sqlite3ParserFree() will never be called with a null
+** pointer.
+*/
+#define YYPARSEFREENEVERNULL 1
+
+/*
+** Alternative datatype for the argument to the malloc() routine passed
+** into sqlite3ParserAlloc(). The default is size_t.
+*/
+#define YYMALLOCARGTYPE u64
+
+/*
** An instance of this structure holds information about the
** LIMIT clause of a SELECT statement.
*/
@@ -108040,14 +127304,28 @@ struct TrigEvent { int a; IdList * b; };
*/
struct AttachKey { int type; Token key; };
-/*
-** One or more VALUES claues
-*/
-struct ValueList {
- ExprList *pList;
- Select *pSelect;
-};
+ /*
+ ** For a compound SELECT statement, make sure p->pPrior->pNext==p for
+ ** all elements in the list. And make sure list length does not exceed
+ ** SQLITE_LIMIT_COMPOUND_SELECT.
+ */
+ static void parserDoubleLinkSelect(Parse *pParse, Select *p){
+ if( p->pPrior ){
+ Select *pNext = 0, *pLoop;
+ int mxSelect, cnt = 0;
+ for(pLoop=p; pLoop; pNext=pLoop, pLoop=pLoop->pPrior, cnt++){
+ pLoop->pNext = pNext;
+ pLoop->selFlags |= SF_Compound;
+ }
+ if( (p->selFlags & SF_MultiValue)==0 &&
+ (mxSelect = pParse->db->aLimit[SQLITE_LIMIT_COMPOUND_SELECT])>0 &&
+ cnt>mxSelect
+ ){
+ sqlite3ErrorMsg(pParse, "too many terms in compound SELECT");
+ }
+ }
+ }
/* This is a utility routine used to set the ExprSpan.zStart and
** ExprSpan.zEnd values of pOut so that the span covers the complete
@@ -108083,6 +127361,13 @@ struct ValueList {
pOut->zEnd = pRight->zEnd;
}
+ /* If doNot is true, then add a TK_NOT Expr-node wrapper around the
+ ** outside of *ppExpr.
+ */
+ static void exprNot(Parse *pParse, int doNot, Expr **ppExpr){
+ if( doNot ) *ppExpr = sqlite3PExpr(pParse, TK_NOT, *ppExpr, 0, 0);
+ }
+
/* Construct an expression node for a unary postfix operator
*/
static void spanUnaryPostfix(
@@ -108101,7 +127386,7 @@ struct ValueList {
** 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 ){
+ if( pY && pA && pY->op==TK_NULL ){
pA->op = (u8)op;
sqlite3ExprDelete(db, pA->pRight);
pA->pRight = 0;
@@ -108121,77 +127406,108 @@ struct ValueList {
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
+
+ /* Add a single new term to an ExprList that is used to store a
+ ** list of identifiers. Report an error if the ID list contains
+ ** a COLLATE clause or an ASC or DESC keyword, except ignore the
+ ** error while parsing a legacy schema.
+ */
+ static ExprList *parserAddExprIdListTerm(
+ Parse *pParse,
+ ExprList *pPrior,
+ Token *pIdToken,
+ int hasCollate,
+ int sortOrder
+ ){
+ ExprList *p = sqlite3ExprListAppend(pParse, pPrior, 0);
+ if( (hasCollate || sortOrder!=SQLITE_SO_UNDEFINED)
+ && pParse->db->init.busy==0
+ ){
+ sqlite3ErrorMsg(pParse, "syntax error after column name \"%.*s\"",
+ pIdToken->n, pIdToken->z);
+ }
+ sqlite3ExprListSetName(pParse, p, pIdToken, 1);
+ return p;
+ }
+/**************** End of %include directives **********************************/
+/* These constants specify the various numeric values for terminal symbols
+** in a format understandable to "makeheaders". This section is blank unless
+** "lemon" is run with the "-m" command-line option.
+***************** Begin makeheaders token definitions *************************/
+/**************** End makeheaders token definitions ***************************/
+
+/* The next sections is a series of control #defines.
** 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.
+** YYCODETYPE is the data type used to store the integer codes
+** that represent terminal and non-terminal symbols.
+** "unsigned char" is used if there are fewer than
+** 256 symbols. Larger types otherwise.
+** YYNOCODE is a number of type YYCODETYPE that is not used for
+** any terminal or nonterminal symbol.
** 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.
+** (also known as: "terminal symbols") have fall-back
+** values which should be used if the original symbol
+** would not parse. This permits keywords to sometimes
+** be used as identifiers, for example.
+** YYACTIONTYPE is the data type used for "action codes" - numbers
+** that indicate what to do in response to the next
+** token.
+** sqlite3ParserTOKENTYPE is the data type used for minor type for terminal
+** symbols. Background: A "minor type" is a semantic
+** value associated with a terminal or non-terminal
+** symbols. For example, for an "ID" terminal symbol,
+** the minor type might be the name of the identifier.
+** Each non-terminal can have a different minor type.
+** Terminal symbols all have the same minor type, though.
+** This macros defines the minor type for terminal
+** symbols.
+** YYMINORTYPE is the data type used for all minor types.
** This is typically a union of many types, one of
** which is sqlite3ParserTOKENTYPE. The entry in the union
-** for base tokens is called "yy0".
+** for terminal symbols 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.
+** YYNSTATE the combined number of states.
+** YYNRULE the number of rules in the grammar
+** YY_MAX_SHIFT Maximum value for shift actions
+** YY_MIN_SHIFTREDUCE Minimum value for shift-reduce actions
+** YY_MAX_SHIFTREDUCE Maximum value for shift-reduce actions
+** YY_MIN_REDUCE Maximum value for reduce actions
+** YY_ERROR_ACTION The yy_action[] code for syntax error
+** YY_ACCEPT_ACTION The yy_action[] code for accept
+** YY_NO_ACTION The yy_action[] code for no-op
*/
+#ifndef INTERFACE
+# define INTERFACE 1
+#endif
+/************* Begin control #defines *****************************************/
#define YYCODETYPE unsigned char
-#define YYNOCODE 251
+#define YYNOCODE 253
#define YYACTIONTYPE unsigned short int
-#define YYWILDCARD 67
+#define YYWILDCARD 70
#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;
+ int yy4;
+ struct TrigEvent yy90;
+ ExprSpan yy118;
+ TriggerStep* yy203;
+ struct {int value; int mask;} yy215;
+ SrcList* yy259;
+ struct LimitVal yy292;
+ Expr* yy314;
+ ExprList* yy322;
+ struct LikeOp yy342;
+ IdList* yy384;
+ Select* yy387;
+ With* yy451;
} YYMINORTYPE;
#ifndef YYSTACKDEPTH
#define YYSTACKDEPTH 100
@@ -108200,12 +127516,18 @@ typedef union {
#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)
+#define YYNSTATE 436
+#define YYNRULE 328
+#define YY_MAX_SHIFT 435
+#define YY_MIN_SHIFTREDUCE 649
+#define YY_MAX_SHIFTREDUCE 976
+#define YY_MIN_REDUCE 977
+#define YY_MAX_REDUCE 1304
+#define YY_ERROR_ACTION 1305
+#define YY_ACCEPT_ACTION 1306
+#define YY_NO_ACTION 1307
+/************* End control #defines *******************************************/
/* The yyzerominor constant is used to initialize instances of
** YYMINORTYPE objects to zero. */
@@ -108232,16 +127554,20 @@ static const YYMINORTYPE yyzerominor = { 0 };
** Suppose the action integer is N. Then the action is determined as
** follows
**
-** 0 <= N < YYNSTATE Shift N. That is, push the lookahead
+** 0 <= N <= YY_MAX_SHIFT 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 between YY_MIN_SHIFTREDUCE Shift to an arbitrary state then
+** and YY_MAX_SHIFTREDUCE reduce by rule N-YY_MIN_SHIFTREDUCE.
**
-** N == YYNSTATE+YYNRULE A syntax error has occurred.
+** N between YY_MIN_REDUCE Reduce by rule N-YY_MIN_REDUCE
+** and YY_MAX_REDUCE
+
+** N == YY_ERROR_ACTION A syntax error has occurred.
**
-** N == YYNSTATE+YYNRULE+1 The parser accepts its input.
+** N == YY_ACCEPT_ACTION The parser accepts its input.
**
-** N == YYNSTATE+YYNRULE+2 No such action. Denotes unused
+** N == YY_NO_ACTION No such action. Denotes unused
** slots in the yy_action[] table.
**
** The action table is constructed as a single large table named yy_action[].
@@ -108270,479 +127596,453 @@ static const YYMINORTYPE yyzerominor = { 0 };
** 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)
+**
+*********** Begin parsing tables **********************************************/
+#define YY_ACTTAB_COUNT (1501)
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,
+ /* 0 */ 311, 1306, 145, 651, 2, 192, 652, 338, 780, 92,
+ /* 10 */ 92, 92, 92, 85, 90, 90, 90, 90, 89, 89,
+ /* 20 */ 88, 88, 88, 87, 335, 88, 88, 88, 87, 335,
+ /* 30 */ 327, 856, 856, 92, 92, 92, 92, 697, 90, 90,
+ /* 40 */ 90, 90, 89, 89, 88, 88, 88, 87, 335, 76,
+ /* 50 */ 807, 74, 93, 94, 84, 868, 871, 860, 860, 91,
+ /* 60 */ 91, 92, 92, 92, 92, 335, 90, 90, 90, 90,
+ /* 70 */ 89, 89, 88, 88, 88, 87, 335, 311, 780, 90,
+ /* 80 */ 90, 90, 90, 89, 89, 88, 88, 88, 87, 335,
+ /* 90 */ 356, 808, 776, 701, 689, 689, 86, 83, 166, 257,
+ /* 100 */ 809, 715, 430, 86, 83, 166, 324, 697, 856, 856,
+ /* 110 */ 201, 158, 276, 387, 271, 386, 188, 689, 689, 828,
+ /* 120 */ 86, 83, 166, 269, 833, 49, 123, 87, 335, 93,
+ /* 130 */ 94, 84, 868, 871, 860, 860, 91, 91, 92, 92,
+ /* 140 */ 92, 92, 239, 90, 90, 90, 90, 89, 89, 88,
+ /* 150 */ 88, 88, 87, 335, 311, 763, 333, 332, 216, 408,
+ /* 160 */ 394, 69, 231, 393, 690, 691, 396, 910, 251, 354,
+ /* 170 */ 250, 288, 315, 430, 908, 430, 909, 89, 89, 88,
+ /* 180 */ 88, 88, 87, 335, 391, 856, 856, 690, 691, 183,
+ /* 190 */ 95, 123, 384, 381, 380, 833, 31, 833, 49, 912,
+ /* 200 */ 912, 751, 752, 379, 123, 311, 93, 94, 84, 868,
+ /* 210 */ 871, 860, 860, 91, 91, 92, 92, 92, 92, 114,
+ /* 220 */ 90, 90, 90, 90, 89, 89, 88, 88, 88, 87,
+ /* 230 */ 335, 430, 408, 399, 435, 657, 856, 856, 346, 57,
+ /* 240 */ 232, 828, 109, 704, 366, 689, 689, 363, 825, 760,
+ /* 250 */ 97, 749, 752, 833, 49, 708, 708, 93, 94, 84,
+ /* 260 */ 868, 871, 860, 860, 91, 91, 92, 92, 92, 92,
+ /* 270 */ 423, 90, 90, 90, 90, 89, 89, 88, 88, 88,
+ /* 280 */ 87, 335, 311, 114, 22, 361, 688, 58, 408, 390,
+ /* 290 */ 251, 349, 240, 213, 762, 689, 689, 847, 685, 115,
+ /* 300 */ 361, 231, 393, 689, 689, 396, 183, 689, 689, 384,
+ /* 310 */ 381, 380, 361, 856, 856, 690, 691, 160, 159, 223,
+ /* 320 */ 379, 738, 25, 806, 707, 841, 143, 689, 689, 835,
+ /* 330 */ 392, 339, 766, 766, 93, 94, 84, 868, 871, 860,
+ /* 340 */ 860, 91, 91, 92, 92, 92, 92, 914, 90, 90,
+ /* 350 */ 90, 90, 89, 89, 88, 88, 88, 87, 335, 311,
+ /* 360 */ 840, 840, 840, 266, 257, 690, 691, 778, 706, 86,
+ /* 370 */ 83, 166, 219, 690, 691, 737, 1, 690, 691, 689,
+ /* 380 */ 689, 689, 689, 430, 86, 83, 166, 249, 688, 937,
+ /* 390 */ 856, 856, 427, 699, 700, 828, 298, 690, 691, 221,
+ /* 400 */ 686, 115, 123, 944, 795, 833, 48, 342, 305, 970,
+ /* 410 */ 847, 93, 94, 84, 868, 871, 860, 860, 91, 91,
+ /* 420 */ 92, 92, 92, 92, 114, 90, 90, 90, 90, 89,
+ /* 430 */ 89, 88, 88, 88, 87, 335, 311, 940, 841, 679,
+ /* 440 */ 713, 429, 835, 430, 251, 354, 250, 355, 288, 690,
+ /* 450 */ 691, 690, 691, 285, 941, 340, 971, 287, 210, 23,
+ /* 460 */ 174, 793, 832, 430, 353, 833, 10, 856, 856, 24,
+ /* 470 */ 942, 151, 753, 840, 840, 840, 794, 968, 1290, 321,
+ /* 480 */ 398, 1290, 356, 352, 754, 833, 49, 935, 93, 94,
+ /* 490 */ 84, 868, 871, 860, 860, 91, 91, 92, 92, 92,
+ /* 500 */ 92, 430, 90, 90, 90, 90, 89, 89, 88, 88,
+ /* 510 */ 88, 87, 335, 311, 376, 114, 907, 705, 430, 907,
+ /* 520 */ 328, 890, 114, 833, 10, 966, 430, 857, 857, 320,
+ /* 530 */ 189, 163, 832, 165, 430, 906, 344, 323, 906, 904,
+ /* 540 */ 833, 10, 965, 306, 856, 856, 187, 419, 833, 10,
+ /* 550 */ 220, 869, 872, 832, 222, 403, 833, 49, 1219, 793,
+ /* 560 */ 68, 937, 406, 245, 66, 93, 94, 84, 868, 871,
+ /* 570 */ 860, 860, 91, 91, 92, 92, 92, 92, 861, 90,
+ /* 580 */ 90, 90, 90, 89, 89, 88, 88, 88, 87, 335,
+ /* 590 */ 311, 404, 213, 762, 834, 345, 114, 940, 902, 368,
+ /* 600 */ 727, 5, 316, 192, 396, 772, 780, 269, 230, 242,
+ /* 610 */ 771, 244, 397, 164, 941, 385, 123, 347, 55, 355,
+ /* 620 */ 329, 856, 856, 728, 333, 332, 688, 968, 1291, 724,
+ /* 630 */ 942, 1291, 413, 214, 833, 9, 362, 286, 955, 115,
+ /* 640 */ 718, 311, 93, 94, 84, 868, 871, 860, 860, 91,
+ /* 650 */ 91, 92, 92, 92, 92, 430, 90, 90, 90, 90,
+ /* 660 */ 89, 89, 88, 88, 88, 87, 335, 912, 912, 1300,
+ /* 670 */ 1300, 758, 856, 856, 325, 966, 780, 833, 35, 747,
+ /* 680 */ 720, 334, 699, 700, 977, 652, 338, 243, 745, 920,
+ /* 690 */ 920, 369, 187, 93, 94, 84, 868, 871, 860, 860,
+ /* 700 */ 91, 91, 92, 92, 92, 92, 114, 90, 90, 90,
+ /* 710 */ 90, 89, 89, 88, 88, 88, 87, 335, 311, 430,
+ /* 720 */ 954, 430, 112, 310, 430, 693, 317, 698, 400, 430,
+ /* 730 */ 793, 359, 430, 1017, 430, 192, 430, 401, 780, 430,
+ /* 740 */ 360, 833, 36, 833, 12, 430, 833, 27, 316, 856,
+ /* 750 */ 856, 833, 37, 20, 833, 38, 833, 39, 833, 28,
+ /* 760 */ 72, 833, 29, 663, 664, 665, 264, 833, 40, 234,
+ /* 770 */ 93, 94, 84, 868, 871, 860, 860, 91, 91, 92,
+ /* 780 */ 92, 92, 92, 430, 90, 90, 90, 90, 89, 89,
+ /* 790 */ 88, 88, 88, 87, 335, 311, 430, 698, 430, 917,
+ /* 800 */ 147, 430, 165, 916, 275, 833, 41, 430, 780, 430,
+ /* 810 */ 21, 430, 259, 430, 262, 274, 430, 367, 833, 42,
+ /* 820 */ 833, 11, 430, 833, 43, 235, 856, 856, 793, 833,
+ /* 830 */ 99, 833, 44, 833, 45, 833, 32, 75, 833, 46,
+ /* 840 */ 305, 967, 257, 257, 833, 47, 311, 93, 94, 84,
+ /* 850 */ 868, 871, 860, 860, 91, 91, 92, 92, 92, 92,
+ /* 860 */ 430, 90, 90, 90, 90, 89, 89, 88, 88, 88,
+ /* 870 */ 87, 335, 430, 186, 185, 184, 238, 856, 856, 650,
+ /* 880 */ 2, 1064, 833, 33, 739, 217, 218, 257, 971, 257,
+ /* 890 */ 426, 317, 257, 774, 833, 117, 257, 311, 93, 94,
+ /* 900 */ 84, 868, 871, 860, 860, 91, 91, 92, 92, 92,
+ /* 910 */ 92, 430, 90, 90, 90, 90, 89, 89, 88, 88,
+ /* 920 */ 88, 87, 335, 430, 318, 124, 212, 163, 856, 856,
+ /* 930 */ 943, 900, 898, 833, 118, 759, 726, 725, 257, 755,
+ /* 940 */ 289, 289, 733, 734, 961, 833, 119, 682, 311, 93,
+ /* 950 */ 82, 84, 868, 871, 860, 860, 91, 91, 92, 92,
+ /* 960 */ 92, 92, 430, 90, 90, 90, 90, 89, 89, 88,
+ /* 970 */ 88, 88, 87, 335, 430, 716, 246, 322, 331, 856,
+ /* 980 */ 856, 256, 114, 357, 833, 53, 808, 913, 913, 932,
+ /* 990 */ 156, 416, 420, 424, 930, 809, 833, 34, 364, 311,
+ /* 1000 */ 253, 94, 84, 868, 871, 860, 860, 91, 91, 92,
+ /* 1010 */ 92, 92, 92, 430, 90, 90, 90, 90, 89, 89,
+ /* 1020 */ 88, 88, 88, 87, 335, 430, 114, 114, 114, 960,
+ /* 1030 */ 856, 856, 307, 258, 830, 833, 100, 191, 252, 377,
+ /* 1040 */ 267, 68, 197, 68, 261, 716, 769, 833, 50, 71,
+ /* 1050 */ 911, 911, 263, 84, 868, 871, 860, 860, 91, 91,
+ /* 1060 */ 92, 92, 92, 92, 430, 90, 90, 90, 90, 89,
+ /* 1070 */ 89, 88, 88, 88, 87, 335, 80, 425, 802, 3,
+ /* 1080 */ 1214, 191, 430, 265, 336, 336, 833, 101, 741, 80,
+ /* 1090 */ 425, 897, 3, 723, 722, 428, 721, 336, 336, 430,
+ /* 1100 */ 893, 270, 430, 197, 833, 102, 430, 800, 428, 430,
+ /* 1110 */ 695, 430, 843, 111, 414, 430, 784, 409, 430, 831,
+ /* 1120 */ 430, 833, 98, 123, 833, 116, 847, 414, 833, 49,
+ /* 1130 */ 779, 833, 113, 833, 106, 226, 123, 833, 105, 847,
+ /* 1140 */ 833, 103, 833, 104, 791, 411, 77, 78, 290, 412,
+ /* 1150 */ 430, 291, 114, 79, 432, 431, 389, 430, 835, 77,
+ /* 1160 */ 78, 897, 839, 408, 410, 430, 79, 432, 431, 372,
+ /* 1170 */ 703, 835, 833, 52, 430, 80, 425, 430, 3, 833,
+ /* 1180 */ 54, 772, 843, 336, 336, 684, 771, 833, 51, 840,
+ /* 1190 */ 840, 840, 842, 19, 428, 672, 833, 26, 671, 833,
+ /* 1200 */ 30, 673, 840, 840, 840, 842, 19, 207, 661, 278,
+ /* 1210 */ 304, 148, 280, 414, 282, 248, 358, 822, 382, 6,
+ /* 1220 */ 348, 161, 273, 80, 425, 847, 3, 934, 895, 720,
+ /* 1230 */ 894, 336, 336, 296, 157, 415, 241, 284, 674, 958,
+ /* 1240 */ 194, 953, 428, 951, 948, 77, 78, 777, 319, 56,
+ /* 1250 */ 59, 135, 79, 432, 431, 121, 66, 835, 146, 128,
+ /* 1260 */ 350, 414, 819, 130, 351, 131, 132, 133, 375, 173,
+ /* 1270 */ 107, 138, 149, 847, 365, 178, 62, 70, 425, 936,
+ /* 1280 */ 3, 827, 889, 371, 255, 336, 336, 792, 840, 840,
+ /* 1290 */ 840, 842, 19, 77, 78, 915, 428, 208, 179, 144,
+ /* 1300 */ 79, 432, 431, 373, 260, 835, 180, 326, 675, 181,
+ /* 1310 */ 308, 744, 388, 743, 731, 414, 718, 742, 730, 712,
+ /* 1320 */ 402, 309, 711, 272, 788, 65, 710, 847, 709, 277,
+ /* 1330 */ 193, 789, 787, 279, 876, 73, 840, 840, 840, 842,
+ /* 1340 */ 19, 786, 281, 418, 283, 422, 227, 77, 78, 330,
+ /* 1350 */ 228, 229, 96, 767, 79, 432, 431, 407, 67, 835,
+ /* 1360 */ 215, 292, 293, 405, 294, 303, 302, 301, 204, 299,
+ /* 1370 */ 295, 202, 676, 681, 7, 433, 669, 203, 205, 206,
+ /* 1380 */ 125, 110, 313, 434, 667, 666, 658, 168, 224, 237,
+ /* 1390 */ 840, 840, 840, 842, 19, 120, 656, 337, 236, 155,
+ /* 1400 */ 167, 341, 233, 314, 108, 905, 903, 826, 127, 126,
+ /* 1410 */ 756, 170, 129, 172, 247, 928, 134, 136, 171, 60,
+ /* 1420 */ 61, 123, 169, 137, 933, 175, 176, 927, 8, 13,
+ /* 1430 */ 177, 254, 918, 139, 191, 924, 140, 370, 678, 150,
+ /* 1440 */ 374, 182, 274, 268, 141, 122, 63, 14, 378, 15,
+ /* 1450 */ 383, 64, 225, 846, 845, 874, 16, 4, 729, 765,
+ /* 1460 */ 770, 162, 395, 209, 211, 142, 801, 878, 796, 312,
+ /* 1470 */ 71, 68, 875, 873, 939, 190, 417, 938, 17, 195,
+ /* 1480 */ 196, 152, 18, 975, 199, 976, 153, 198, 154, 421,
+ /* 1490 */ 877, 844, 696, 81, 200, 297, 343, 1019, 1018, 300,
+ /* 1500 */ 653,
};
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,
+ /* 0 */ 19, 144, 145, 146, 147, 24, 1, 2, 27, 80,
+ /* 10 */ 81, 82, 83, 84, 85, 86, 87, 88, 89, 90,
+ /* 20 */ 91, 92, 93, 94, 95, 91, 92, 93, 94, 95,
+ /* 30 */ 19, 50, 51, 80, 81, 82, 83, 27, 85, 86,
+ /* 40 */ 87, 88, 89, 90, 91, 92, 93, 94, 95, 137,
+ /* 50 */ 177, 139, 71, 72, 73, 74, 75, 76, 77, 78,
+ /* 60 */ 79, 80, 81, 82, 83, 95, 85, 86, 87, 88,
+ /* 70 */ 89, 90, 91, 92, 93, 94, 95, 19, 97, 85,
+ /* 80 */ 86, 87, 88, 89, 90, 91, 92, 93, 94, 95,
+ /* 90 */ 152, 33, 212, 173, 27, 28, 223, 224, 225, 152,
+ /* 100 */ 42, 181, 152, 223, 224, 225, 95, 97, 50, 51,
+ /* 110 */ 99, 100, 101, 102, 103, 104, 105, 27, 28, 59,
+ /* 120 */ 223, 224, 225, 112, 174, 175, 66, 94, 95, 71,
+ /* 130 */ 72, 73, 74, 75, 76, 77, 78, 79, 80, 81,
+ /* 140 */ 82, 83, 195, 85, 86, 87, 88, 89, 90, 91,
+ /* 150 */ 92, 93, 94, 95, 19, 197, 89, 90, 220, 209,
+ /* 160 */ 210, 26, 119, 120, 97, 98, 208, 100, 108, 109,
+ /* 170 */ 110, 152, 157, 152, 107, 152, 109, 89, 90, 91,
+ /* 180 */ 92, 93, 94, 95, 163, 50, 51, 97, 98, 99,
+ /* 190 */ 55, 66, 102, 103, 104, 174, 175, 174, 175, 132,
+ /* 200 */ 133, 192, 193, 113, 66, 19, 71, 72, 73, 74,
+ /* 210 */ 75, 76, 77, 78, 79, 80, 81, 82, 83, 198,
+ /* 220 */ 85, 86, 87, 88, 89, 90, 91, 92, 93, 94,
+ /* 230 */ 95, 152, 209, 210, 148, 149, 50, 51, 100, 53,
+ /* 240 */ 154, 59, 156, 174, 229, 27, 28, 232, 163, 163,
+ /* 250 */ 22, 192, 193, 174, 175, 27, 28, 71, 72, 73,
+ /* 260 */ 74, 75, 76, 77, 78, 79, 80, 81, 82, 83,
+ /* 270 */ 251, 85, 86, 87, 88, 89, 90, 91, 92, 93,
+ /* 280 */ 94, 95, 19, 198, 198, 152, 152, 24, 209, 210,
+ /* 290 */ 108, 109, 110, 196, 197, 27, 28, 69, 164, 165,
+ /* 300 */ 152, 119, 120, 27, 28, 208, 99, 27, 28, 102,
+ /* 310 */ 103, 104, 152, 50, 51, 97, 98, 89, 90, 185,
+ /* 320 */ 113, 187, 22, 177, 174, 97, 58, 27, 28, 101,
+ /* 330 */ 115, 245, 117, 118, 71, 72, 73, 74, 75, 76,
+ /* 340 */ 77, 78, 79, 80, 81, 82, 83, 11, 85, 86,
+ /* 350 */ 87, 88, 89, 90, 91, 92, 93, 94, 95, 19,
+ /* 360 */ 132, 133, 134, 23, 152, 97, 98, 91, 174, 223,
+ /* 370 */ 224, 225, 239, 97, 98, 187, 22, 97, 98, 27,
+ /* 380 */ 28, 27, 28, 152, 223, 224, 225, 239, 152, 163,
+ /* 390 */ 50, 51, 170, 171, 172, 59, 160, 97, 98, 239,
+ /* 400 */ 164, 165, 66, 242, 124, 174, 175, 195, 22, 23,
+ /* 410 */ 69, 71, 72, 73, 74, 75, 76, 77, 78, 79,
+ /* 420 */ 80, 81, 82, 83, 198, 85, 86, 87, 88, 89,
+ /* 430 */ 90, 91, 92, 93, 94, 95, 19, 12, 97, 21,
+ /* 440 */ 23, 152, 101, 152, 108, 109, 110, 221, 152, 97,
+ /* 450 */ 98, 97, 98, 152, 29, 243, 70, 226, 23, 233,
+ /* 460 */ 26, 26, 152, 152, 238, 174, 175, 50, 51, 22,
+ /* 470 */ 45, 24, 47, 132, 133, 134, 124, 22, 23, 188,
+ /* 480 */ 163, 26, 152, 65, 59, 174, 175, 163, 71, 72,
+ /* 490 */ 73, 74, 75, 76, 77, 78, 79, 80, 81, 82,
+ /* 500 */ 83, 152, 85, 86, 87, 88, 89, 90, 91, 92,
+ /* 510 */ 93, 94, 95, 19, 19, 198, 152, 23, 152, 152,
+ /* 520 */ 209, 103, 198, 174, 175, 70, 152, 50, 51, 219,
+ /* 530 */ 213, 214, 152, 98, 152, 171, 172, 188, 171, 172,
+ /* 540 */ 174, 175, 248, 249, 50, 51, 51, 251, 174, 175,
+ /* 550 */ 220, 74, 75, 152, 188, 152, 174, 175, 140, 124,
+ /* 560 */ 26, 163, 188, 16, 130, 71, 72, 73, 74, 75,
+ /* 570 */ 76, 77, 78, 79, 80, 81, 82, 83, 101, 85,
+ /* 580 */ 86, 87, 88, 89, 90, 91, 92, 93, 94, 95,
+ /* 590 */ 19, 209, 196, 197, 23, 231, 198, 12, 231, 219,
+ /* 600 */ 37, 22, 107, 24, 208, 116, 27, 112, 201, 62,
+ /* 610 */ 121, 64, 152, 152, 29, 52, 66, 221, 211, 221,
+ /* 620 */ 219, 50, 51, 60, 89, 90, 152, 22, 23, 183,
+ /* 630 */ 45, 26, 47, 22, 174, 175, 238, 152, 164, 165,
+ /* 640 */ 106, 19, 71, 72, 73, 74, 75, 76, 77, 78,
+ /* 650 */ 79, 80, 81, 82, 83, 152, 85, 86, 87, 88,
+ /* 660 */ 89, 90, 91, 92, 93, 94, 95, 132, 133, 119,
+ /* 670 */ 120, 163, 50, 51, 111, 70, 97, 174, 175, 181,
+ /* 680 */ 182, 170, 171, 172, 0, 1, 2, 140, 190, 108,
+ /* 690 */ 109, 110, 51, 71, 72, 73, 74, 75, 76, 77,
+ /* 700 */ 78, 79, 80, 81, 82, 83, 198, 85, 86, 87,
+ /* 710 */ 88, 89, 90, 91, 92, 93, 94, 95, 19, 152,
+ /* 720 */ 152, 152, 22, 166, 152, 168, 169, 27, 19, 152,
+ /* 730 */ 26, 19, 152, 122, 152, 24, 152, 28, 27, 152,
+ /* 740 */ 28, 174, 175, 174, 175, 152, 174, 175, 107, 50,
+ /* 750 */ 51, 174, 175, 22, 174, 175, 174, 175, 174, 175,
+ /* 760 */ 138, 174, 175, 7, 8, 9, 16, 174, 175, 152,
+ /* 770 */ 71, 72, 73, 74, 75, 76, 77, 78, 79, 80,
+ /* 780 */ 81, 82, 83, 152, 85, 86, 87, 88, 89, 90,
+ /* 790 */ 91, 92, 93, 94, 95, 19, 152, 97, 152, 31,
+ /* 800 */ 24, 152, 98, 35, 101, 174, 175, 152, 97, 152,
+ /* 810 */ 79, 152, 62, 152, 64, 112, 152, 49, 174, 175,
+ /* 820 */ 174, 175, 152, 174, 175, 152, 50, 51, 124, 174,
+ /* 830 */ 175, 174, 175, 174, 175, 174, 175, 138, 174, 175,
+ /* 840 */ 22, 23, 152, 152, 174, 175, 19, 71, 72, 73,
+ /* 850 */ 74, 75, 76, 77, 78, 79, 80, 81, 82, 83,
+ /* 860 */ 152, 85, 86, 87, 88, 89, 90, 91, 92, 93,
+ /* 870 */ 94, 95, 152, 108, 109, 110, 152, 50, 51, 146,
+ /* 880 */ 147, 23, 174, 175, 26, 195, 195, 152, 70, 152,
+ /* 890 */ 168, 169, 152, 26, 174, 175, 152, 19, 71, 72,
+ /* 900 */ 73, 74, 75, 76, 77, 78, 79, 80, 81, 82,
+ /* 910 */ 83, 152, 85, 86, 87, 88, 89, 90, 91, 92,
+ /* 920 */ 93, 94, 95, 152, 246, 247, 213, 214, 50, 51,
+ /* 930 */ 195, 152, 195, 174, 175, 195, 100, 101, 152, 195,
+ /* 940 */ 152, 152, 7, 8, 152, 174, 175, 163, 19, 71,
+ /* 950 */ 72, 73, 74, 75, 76, 77, 78, 79, 80, 81,
+ /* 960 */ 82, 83, 152, 85, 86, 87, 88, 89, 90, 91,
+ /* 970 */ 92, 93, 94, 95, 152, 27, 152, 189, 189, 50,
+ /* 980 */ 51, 195, 198, 152, 174, 175, 33, 132, 133, 152,
+ /* 990 */ 123, 163, 163, 163, 152, 42, 174, 175, 152, 19,
+ /* 1000 */ 152, 72, 73, 74, 75, 76, 77, 78, 79, 80,
+ /* 1010 */ 81, 82, 83, 152, 85, 86, 87, 88, 89, 90,
+ /* 1020 */ 91, 92, 93, 94, 95, 152, 198, 198, 198, 23,
+ /* 1030 */ 50, 51, 26, 152, 23, 174, 175, 26, 23, 23,
+ /* 1040 */ 23, 26, 26, 26, 152, 97, 23, 174, 175, 26,
+ /* 1050 */ 132, 133, 152, 73, 74, 75, 76, 77, 78, 79,
+ /* 1060 */ 80, 81, 82, 83, 152, 85, 86, 87, 88, 89,
+ /* 1070 */ 90, 91, 92, 93, 94, 95, 19, 20, 23, 22,
+ /* 1080 */ 23, 26, 152, 152, 27, 28, 174, 175, 152, 19,
+ /* 1090 */ 20, 27, 22, 183, 183, 38, 152, 27, 28, 152,
+ /* 1100 */ 23, 152, 152, 26, 174, 175, 152, 152, 38, 152,
+ /* 1110 */ 23, 152, 27, 26, 57, 152, 215, 163, 152, 152,
+ /* 1120 */ 152, 174, 175, 66, 174, 175, 69, 57, 174, 175,
+ /* 1130 */ 152, 174, 175, 174, 175, 212, 66, 174, 175, 69,
+ /* 1140 */ 174, 175, 174, 175, 152, 152, 89, 90, 152, 193,
+ /* 1150 */ 152, 152, 198, 96, 97, 98, 91, 152, 101, 89,
+ /* 1160 */ 90, 97, 152, 209, 210, 152, 96, 97, 98, 235,
+ /* 1170 */ 152, 101, 174, 175, 152, 19, 20, 152, 22, 174,
+ /* 1180 */ 175, 116, 97, 27, 28, 152, 121, 174, 175, 132,
+ /* 1190 */ 133, 134, 135, 136, 38, 152, 174, 175, 152, 174,
+ /* 1200 */ 175, 152, 132, 133, 134, 135, 136, 234, 152, 212,
+ /* 1210 */ 150, 199, 212, 57, 212, 240, 240, 203, 178, 200,
+ /* 1220 */ 216, 186, 177, 19, 20, 69, 22, 203, 177, 182,
+ /* 1230 */ 177, 27, 28, 202, 200, 228, 216, 216, 155, 39,
+ /* 1240 */ 122, 159, 38, 159, 41, 89, 90, 91, 159, 241,
+ /* 1250 */ 241, 22, 96, 97, 98, 71, 130, 101, 222, 191,
+ /* 1260 */ 18, 57, 203, 194, 159, 194, 194, 194, 18, 158,
+ /* 1270 */ 244, 191, 222, 69, 159, 158, 137, 19, 20, 203,
+ /* 1280 */ 22, 191, 203, 46, 236, 27, 28, 159, 132, 133,
+ /* 1290 */ 134, 135, 136, 89, 90, 237, 38, 159, 158, 22,
+ /* 1300 */ 96, 97, 98, 179, 159, 101, 158, 48, 159, 158,
+ /* 1310 */ 179, 176, 107, 176, 184, 57, 106, 176, 184, 176,
+ /* 1320 */ 125, 179, 178, 176, 218, 107, 176, 69, 176, 217,
+ /* 1330 */ 159, 218, 218, 217, 159, 137, 132, 133, 134, 135,
+ /* 1340 */ 136, 218, 217, 179, 217, 179, 227, 89, 90, 95,
+ /* 1350 */ 230, 230, 129, 207, 96, 97, 98, 126, 128, 101,
+ /* 1360 */ 5, 206, 205, 127, 204, 10, 11, 12, 13, 14,
+ /* 1370 */ 203, 25, 17, 162, 26, 161, 13, 153, 153, 6,
+ /* 1380 */ 247, 180, 250, 151, 151, 151, 151, 32, 180, 34,
+ /* 1390 */ 132, 133, 134, 135, 136, 167, 4, 3, 43, 22,
+ /* 1400 */ 15, 68, 142, 250, 16, 23, 23, 120, 111, 131,
+ /* 1410 */ 20, 56, 123, 125, 16, 1, 123, 131, 63, 79,
+ /* 1420 */ 79, 66, 67, 111, 28, 36, 122, 1, 5, 22,
+ /* 1430 */ 107, 140, 54, 54, 26, 61, 107, 44, 20, 24,
+ /* 1440 */ 19, 105, 112, 23, 22, 40, 22, 22, 53, 22,
+ /* 1450 */ 53, 22, 53, 23, 23, 23, 22, 22, 30, 116,
+ /* 1460 */ 23, 122, 26, 23, 23, 22, 28, 11, 124, 114,
+ /* 1470 */ 26, 26, 23, 23, 23, 36, 24, 23, 36, 26,
+ /* 1480 */ 22, 22, 36, 23, 122, 23, 22, 26, 22, 24,
+ /* 1490 */ 23, 23, 23, 22, 122, 23, 141, 122, 122, 15,
+ /* 1500 */ 1,
};
-#define YY_SHIFT_USE_DFLT (-70)
-#define YY_SHIFT_COUNT (416)
-#define YY_SHIFT_MIN (-69)
-#define YY_SHIFT_MAX (1487)
+#define YY_SHIFT_USE_DFLT (-89)
+#define YY_SHIFT_COUNT (435)
+#define YY_SHIFT_MIN (-88)
+#define YY_SHIFT_MAX (1499)
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,
+ /* 0 */ 5, 1057, 1355, 1070, 1204, 1204, 1204, 90, 60, -19,
+ /* 10 */ 58, 58, 186, 1204, 1204, 1204, 1204, 1204, 1204, 1204,
+ /* 20 */ 67, 67, 182, 336, 218, 550, 135, 263, 340, 417,
+ /* 30 */ 494, 571, 622, 699, 776, 827, 827, 827, 827, 827,
+ /* 40 */ 827, 827, 827, 827, 827, 827, 827, 827, 827, 827,
+ /* 50 */ 878, 827, 929, 980, 980, 1156, 1204, 1204, 1204, 1204,
+ /* 60 */ 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204,
+ /* 70 */ 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204,
+ /* 80 */ 1204, 1204, 1204, 1204, 1258, 1204, 1204, 1204, 1204, 1204,
+ /* 90 */ 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, -71, -47,
+ /* 100 */ -47, -47, -47, -47, -6, 88, -66, 218, 218, 418,
+ /* 110 */ 495, 535, 535, 33, 43, 10, -30, -89, -89, -89,
+ /* 120 */ 11, 425, 425, 268, 455, 605, 218, 218, 218, 218,
+ /* 130 */ 218, 218, 218, 218, 218, 218, 218, 218, 218, 218,
+ /* 140 */ 218, 218, 218, 218, 218, 684, 138, 10, 43, 125,
+ /* 150 */ 125, 125, 125, 125, 125, -89, -89, -89, 228, 341,
+ /* 160 */ 341, 207, 276, 300, 280, 352, 354, 218, 218, 218,
+ /* 170 */ 218, 218, 218, 218, 218, 218, 218, 218, 218, 218,
+ /* 180 */ 218, 218, 218, 218, 563, 563, 563, 218, 218, 435,
+ /* 190 */ 218, 218, 218, 579, 218, 218, 585, 218, 218, 218,
+ /* 200 */ 218, 218, 218, 218, 218, 218, 218, 581, 768, 711,
+ /* 210 */ 711, 711, 704, 215, 1065, 756, 434, 709, 709, 712,
+ /* 220 */ 434, 712, 534, 858, 641, 953, 709, -88, 953, 953,
+ /* 230 */ 867, 489, 447, 1200, 1118, 1118, 1203, 1203, 1118, 1229,
+ /* 240 */ 1184, 1126, 1242, 1242, 1242, 1242, 1118, 1250, 1126, 1229,
+ /* 250 */ 1184, 1184, 1126, 1118, 1250, 1139, 1237, 1118, 1118, 1250,
+ /* 260 */ 1277, 1118, 1250, 1118, 1250, 1277, 1205, 1205, 1205, 1259,
+ /* 270 */ 1277, 1205, 1210, 1205, 1259, 1205, 1205, 1195, 1218, 1195,
+ /* 280 */ 1218, 1195, 1218, 1195, 1218, 1118, 1118, 1198, 1277, 1254,
+ /* 290 */ 1254, 1277, 1223, 1231, 1230, 1236, 1126, 1346, 1348, 1363,
+ /* 300 */ 1363, 1373, 1373, 1373, 1373, -89, -89, -89, -89, -89,
+ /* 310 */ -89, 477, 547, 386, 818, 750, 765, 700, 1006, 731,
+ /* 320 */ 1011, 1015, 1016, 1017, 948, 836, 935, 703, 1023, 1055,
+ /* 330 */ 1064, 1077, 855, 918, 1087, 1085, 611, 1392, 1394, 1377,
+ /* 340 */ 1260, 1385, 1333, 1388, 1382, 1383, 1287, 1278, 1297, 1289,
+ /* 350 */ 1390, 1288, 1398, 1414, 1293, 1286, 1340, 1341, 1312, 1396,
+ /* 360 */ 1389, 1304, 1426, 1423, 1407, 1323, 1291, 1378, 1408, 1379,
+ /* 370 */ 1374, 1393, 1329, 1415, 1418, 1421, 1330, 1336, 1422, 1395,
+ /* 380 */ 1424, 1425, 1420, 1427, 1397, 1428, 1429, 1399, 1405, 1430,
+ /* 390 */ 1431, 1432, 1343, 1434, 1437, 1435, 1436, 1339, 1440, 1441,
+ /* 400 */ 1438, 1439, 1443, 1344, 1444, 1442, 1445, 1446, 1444, 1449,
+ /* 410 */ 1450, 1451, 1453, 1454, 1458, 1456, 1460, 1459, 1452, 1461,
+ /* 420 */ 1462, 1464, 1465, 1461, 1467, 1466, 1468, 1469, 1471, 1362,
+ /* 430 */ 1372, 1375, 1376, 1472, 1484, 1499,
};
-#define YY_REDUCE_USE_DFLT (-169)
-#define YY_REDUCE_COUNT (308)
-#define YY_REDUCE_MIN (-168)
-#define YY_REDUCE_MAX (1391)
+#define YY_REDUCE_USE_DFLT (-144)
+#define YY_REDUCE_COUNT (310)
+#define YY_REDUCE_MIN (-143)
+#define YY_REDUCE_MAX (1235)
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,
+ /* 0 */ -143, 954, 86, 21, -50, 23, 79, 134, 226, -120,
+ /* 10 */ -127, 146, 161, 291, 349, 366, 311, 382, 374, 231,
+ /* 20 */ 364, 367, 396, 398, 236, 317, -103, -103, -103, -103,
+ /* 30 */ -103, -103, -103, -103, -103, -103, -103, -103, -103, -103,
+ /* 40 */ -103, -103, -103, -103, -103, -103, -103, -103, -103, -103,
+ /* 50 */ -103, -103, -103, -103, -103, 460, 503, 567, 569, 572,
+ /* 60 */ 577, 580, 582, 584, 587, 593, 631, 644, 646, 649,
+ /* 70 */ 655, 657, 659, 661, 664, 670, 708, 720, 759, 771,
+ /* 80 */ 810, 822, 861, 873, 912, 930, 947, 950, 957, 959,
+ /* 90 */ 963, 966, 968, 998, 1005, 1013, 1022, 1025, -103, -103,
+ /* 100 */ -103, -103, -103, -103, -103, -103, -103, 474, 212, 15,
+ /* 110 */ 498, 222, 511, -103, 97, 557, -103, -103, -103, -103,
+ /* 120 */ -80, 9, 59, 19, 294, 294, -53, -62, 690, 691,
+ /* 130 */ 735, 737, 740, 744, 133, 310, 148, 330, 160, 380,
+ /* 140 */ 786, 788, 401, 296, 789, 733, 85, 722, -42, 324,
+ /* 150 */ 508, 784, 828, 829, 830, 678, 713, 407, 69, 150,
+ /* 160 */ 194, 188, 289, 301, 403, 461, 485, 568, 617, 673,
+ /* 170 */ 724, 779, 792, 824, 831, 837, 842, 846, 848, 881,
+ /* 180 */ 892, 900, 931, 936, 446, 910, 911, 944, 949, 901,
+ /* 190 */ 955, 967, 978, 923, 992, 993, 956, 996, 999, 1010,
+ /* 200 */ 289, 1018, 1033, 1043, 1046, 1049, 1056, 934, 973, 997,
+ /* 210 */ 1000, 1002, 901, 1012, 1019, 1060, 1014, 1004, 1020, 975,
+ /* 220 */ 1024, 976, 1040, 1035, 1047, 1045, 1021, 1007, 1051, 1053,
+ /* 230 */ 1031, 1034, 1083, 1026, 1082, 1084, 1008, 1009, 1089, 1036,
+ /* 240 */ 1068, 1059, 1069, 1071, 1072, 1073, 1105, 1111, 1076, 1050,
+ /* 250 */ 1080, 1090, 1079, 1115, 1117, 1058, 1048, 1128, 1138, 1140,
+ /* 260 */ 1124, 1145, 1148, 1149, 1151, 1131, 1135, 1137, 1141, 1130,
+ /* 270 */ 1142, 1143, 1144, 1147, 1134, 1150, 1152, 1106, 1112, 1113,
+ /* 280 */ 1116, 1114, 1125, 1123, 1127, 1171, 1175, 1119, 1164, 1120,
+ /* 290 */ 1121, 1166, 1146, 1155, 1157, 1160, 1167, 1211, 1214, 1224,
+ /* 300 */ 1225, 1232, 1233, 1234, 1235, 1132, 1153, 1133, 1201, 1208,
+ /* 310 */ 1228,
};
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,
+ /* 0 */ 982, 1300, 1300, 1300, 1214, 1214, 1214, 1305, 1300, 1109,
+ /* 10 */ 1138, 1138, 1274, 1305, 1305, 1305, 1305, 1305, 1305, 1212,
+ /* 20 */ 1305, 1305, 1305, 1300, 1305, 1113, 1144, 1305, 1305, 1305,
+ /* 30 */ 1305, 1305, 1305, 1305, 1305, 1273, 1275, 1152, 1151, 1254,
+ /* 40 */ 1125, 1149, 1142, 1146, 1215, 1208, 1209, 1207, 1211, 1216,
+ /* 50 */ 1305, 1145, 1177, 1192, 1176, 1305, 1305, 1305, 1305, 1305,
+ /* 60 */ 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305,
+ /* 70 */ 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305,
+ /* 80 */ 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305,
+ /* 90 */ 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1186, 1191,
+ /* 100 */ 1198, 1190, 1187, 1179, 1178, 1180, 1181, 1305, 1305, 1008,
+ /* 110 */ 1074, 1305, 1305, 1182, 1305, 1020, 1183, 1195, 1194, 1193,
+ /* 120 */ 1015, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305,
+ /* 130 */ 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305,
+ /* 140 */ 1305, 1305, 1305, 1305, 1305, 982, 1300, 1305, 1305, 1300,
+ /* 150 */ 1300, 1300, 1300, 1300, 1300, 1292, 1113, 1103, 1305, 1305,
+ /* 160 */ 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1280, 1278,
+ /* 170 */ 1305, 1227, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305,
+ /* 180 */ 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305,
+ /* 190 */ 1305, 1305, 1305, 1109, 1305, 1305, 1305, 1305, 1305, 1305,
+ /* 200 */ 1305, 1305, 1305, 1305, 1305, 1305, 988, 1305, 1247, 1109,
+ /* 210 */ 1109, 1109, 1111, 1089, 1101, 990, 1148, 1127, 1127, 1259,
+ /* 220 */ 1148, 1259, 1045, 1068, 1042, 1138, 1127, 1210, 1138, 1138,
+ /* 230 */ 1110, 1101, 1305, 1285, 1118, 1118, 1277, 1277, 1118, 1157,
+ /* 240 */ 1078, 1148, 1085, 1085, 1085, 1085, 1118, 1005, 1148, 1157,
+ /* 250 */ 1078, 1078, 1148, 1118, 1005, 1253, 1251, 1118, 1118, 1005,
+ /* 260 */ 1220, 1118, 1005, 1118, 1005, 1220, 1076, 1076, 1076, 1060,
+ /* 270 */ 1220, 1076, 1045, 1076, 1060, 1076, 1076, 1131, 1126, 1131,
+ /* 280 */ 1126, 1131, 1126, 1131, 1126, 1118, 1118, 1305, 1220, 1224,
+ /* 290 */ 1224, 1220, 1143, 1132, 1141, 1139, 1148, 1011, 1063, 998,
+ /* 300 */ 998, 987, 987, 987, 987, 1297, 1297, 1292, 1047, 1047,
+ /* 310 */ 1030, 1305, 1305, 1305, 1305, 1305, 1305, 1022, 1305, 1229,
+ /* 320 */ 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305,
+ /* 330 */ 1305, 1305, 1305, 1305, 1305, 1305, 1164, 1305, 983, 1287,
+ /* 340 */ 1305, 1305, 1284, 1305, 1305, 1305, 1305, 1305, 1305, 1305,
+ /* 350 */ 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305,
+ /* 360 */ 1305, 1257, 1305, 1305, 1305, 1305, 1305, 1305, 1250, 1249,
+ /* 370 */ 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305,
+ /* 380 */ 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305,
+ /* 390 */ 1305, 1305, 1092, 1305, 1305, 1305, 1096, 1305, 1305, 1305,
+ /* 400 */ 1305, 1305, 1305, 1305, 1140, 1305, 1133, 1305, 1213, 1305,
+ /* 410 */ 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1302,
+ /* 420 */ 1305, 1305, 1305, 1301, 1305, 1305, 1305, 1305, 1305, 1166,
+ /* 430 */ 1305, 1165, 1169, 1305, 996, 1305,
};
+/********** End of lemon-generated parsing tables *****************************/
-/* The next table maps tokens into fallback tokens. If a construct
-** like the following:
+/* The next table maps tokens (terminal symbols) into fallback tokens.
+** If a construct like the following:
**
** %fallback ID X Y Z.
**
@@ -108750,76 +128050,83 @@ static const YYACTIONTYPE yy_default[] = {
** 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.
+**
+** This feature can be used, for example, to cause some keywords in a language
+** to revert to identifiers if they keyword does not apply in the context where
+** it appears.
*/
#ifdef YYFALLBACK
static const YYCODETYPE yyFallback[] = {
0, /* $ => nothing */
0, /* SEMI => nothing */
- 26, /* EXPLAIN => ID */
- 26, /* QUERY => ID */
- 26, /* PLAN => ID */
- 26, /* BEGIN => ID */
+ 27, /* EXPLAIN => ID */
+ 27, /* QUERY => ID */
+ 27, /* PLAN => ID */
+ 27, /* BEGIN => ID */
0, /* TRANSACTION => nothing */
- 26, /* DEFERRED => ID */
- 26, /* IMMEDIATE => ID */
- 26, /* EXCLUSIVE => ID */
+ 27, /* DEFERRED => ID */
+ 27, /* IMMEDIATE => ID */
+ 27, /* EXCLUSIVE => ID */
0, /* COMMIT => nothing */
- 26, /* END => ID */
- 26, /* ROLLBACK => ID */
- 26, /* SAVEPOINT => ID */
- 26, /* RELEASE => ID */
+ 27, /* END => ID */
+ 27, /* ROLLBACK => ID */
+ 27, /* SAVEPOINT => ID */
+ 27, /* RELEASE => ID */
0, /* TO => nothing */
0, /* TABLE => nothing */
0, /* CREATE => nothing */
- 26, /* IF => ID */
+ 27, /* IF => ID */
0, /* NOT => nothing */
0, /* EXISTS => nothing */
- 26, /* TEMP => ID */
+ 27, /* TEMP => ID */
0, /* LP => nothing */
0, /* RP => nothing */
0, /* AS => nothing */
+ 27, /* WITHOUT => ID */
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 */
+ 27, /* ABORT => ID */
+ 27, /* ACTION => ID */
+ 27, /* AFTER => ID */
+ 27, /* ANALYZE => ID */
+ 27, /* ASC => ID */
+ 27, /* ATTACH => ID */
+ 27, /* BEFORE => ID */
+ 27, /* BY => ID */
+ 27, /* CASCADE => ID */
+ 27, /* CAST => ID */
+ 27, /* COLUMNKW => ID */
+ 27, /* CONFLICT => ID */
+ 27, /* DATABASE => ID */
+ 27, /* DESC => ID */
+ 27, /* DETACH => ID */
+ 27, /* EACH => ID */
+ 27, /* FAIL => ID */
+ 27, /* FOR => ID */
+ 27, /* IGNORE => ID */
+ 27, /* INITIALLY => ID */
+ 27, /* INSTEAD => ID */
+ 27, /* LIKE_KW => ID */
+ 27, /* MATCH => ID */
+ 27, /* NO => ID */
+ 27, /* KEY => ID */
+ 27, /* OF => ID */
+ 27, /* OFFSET => ID */
+ 27, /* PRAGMA => ID */
+ 27, /* RAISE => ID */
+ 27, /* RECURSIVE => ID */
+ 27, /* REPLACE => ID */
+ 27, /* RESTRICT => ID */
+ 27, /* ROW => ID */
+ 27, /* TRIGGER => ID */
+ 27, /* VACUUM => ID */
+ 27, /* VIEW => ID */
+ 27, /* VIRTUAL => ID */
+ 27, /* WITH => ID */
+ 27, /* REINDEX => ID */
+ 27, /* RENAME => ID */
+ 27, /* CTIME_KW => ID */
};
#endif /* YYFALLBACK */
@@ -108834,9 +128141,13 @@ static const YYCODETYPE yyFallback[] = {
** + 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.
+**
+** After the "shift" half of a SHIFTREDUCE action, the stateno field
+** actually contains the reduce action for the second half of the
+** SHIFTREDUCE.
*/
struct yyStackEntry {
- YYACTIONTYPE stateno; /* The state-number */
+ YYACTIONTYPE stateno; /* The state-number, or reduce action in SHIFTREDUCE */
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
@@ -108904,63 +128215,63 @@ static const char *const yyTokenName[] = {
"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",
+ "AS", "WITHOUT", "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", "RECURSIVE", "REPLACE",
+ "RESTRICT", "ROW", "TRIGGER", "VACUUM",
+ "VIEW", "VIRTUAL", "WITH", "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",
+ "VALUES", "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",
+ "INTEGER", "FLOAT", "BLOB", "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", "table_options", "select",
+ "column", "columnid", "type", "carglist",
+ "typetoken", "typename", "signed", "plus_num",
+ "minus_num", "ccons", "term", "expr",
+ "onconf", "sortorder", "autoinc", "eidlist_opt",
+ "refargs", "defer_subclause", "refarg", "refact",
+ "init_deferred_pred_opt", "conslist", "tconscomma", "tcons",
+ "sortlist", "eidlist", "defer_subclause_opt", "orconf",
+ "resolvetype", "raisetype", "ifexists", "fullname",
+ "selectnowith", "oneselect", "with", "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",
+ "values", "nexprlist", "exprlist", "sclp",
+ "as", "seltablist", "stl_prefix", "joinop",
+ "indexed_opt", "on_opt", "using_opt", "idlist",
+ "setlist", "insert_cmd", "idlist_opt", "likeop",
+ "between_op", "in_op", "case_operand", "case_exprlist",
+ "case_else", "uniqueflag", "collate", "nmnum",
+ "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", "wqlist",
};
#endif /* NDEBUG */
@@ -109000,172 +128311,172 @@ static const char *const yyRuleName[] = {
/* 29 */ "ifnotexists ::= IF NOT EXISTS",
/* 30 */ "temp ::= TEMP",
/* 31 */ "temp ::=",
- /* 32 */ "create_table_args ::= LP columnlist conslist_opt RP",
+ /* 32 */ "create_table_args ::= LP columnlist conslist_opt RP table_options",
/* 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",
+ /* 34 */ "table_options ::=",
+ /* 35 */ "table_options ::= WITHOUT nm",
+ /* 36 */ "columnlist ::= columnlist COMMA column",
+ /* 37 */ "columnlist ::= column",
+ /* 38 */ "column ::= columnid type carglist",
+ /* 39 */ "columnid ::= nm",
+ /* 40 */ "nm ::= ID|INDEXED",
+ /* 41 */ "nm ::= STRING",
+ /* 42 */ "nm ::= JOIN_KW",
+ /* 43 */ "type ::=",
+ /* 44 */ "type ::= typetoken",
+ /* 45 */ "typetoken ::= typename",
+ /* 46 */ "typetoken ::= typename LP signed RP",
+ /* 47 */ "typetoken ::= typename LP signed COMMA signed RP",
+ /* 48 */ "typename ::= ID|STRING",
+ /* 49 */ "typename ::= typename ID|STRING",
+ /* 50 */ "signed ::= plus_num",
+ /* 51 */ "signed ::= minus_num",
+ /* 52 */ "carglist ::= carglist ccons",
+ /* 53 */ "carglist ::=",
+ /* 54 */ "ccons ::= CONSTRAINT nm",
+ /* 55 */ "ccons ::= DEFAULT term",
+ /* 56 */ "ccons ::= DEFAULT LP expr RP",
+ /* 57 */ "ccons ::= DEFAULT PLUS term",
+ /* 58 */ "ccons ::= DEFAULT MINUS term",
+ /* 59 */ "ccons ::= DEFAULT ID|INDEXED",
+ /* 60 */ "ccons ::= NULL onconf",
+ /* 61 */ "ccons ::= NOT NULL onconf",
+ /* 62 */ "ccons ::= PRIMARY KEY sortorder onconf autoinc",
+ /* 63 */ "ccons ::= UNIQUE onconf",
+ /* 64 */ "ccons ::= CHECK LP expr RP",
+ /* 65 */ "ccons ::= REFERENCES nm eidlist_opt refargs",
+ /* 66 */ "ccons ::= defer_subclause",
+ /* 67 */ "ccons ::= COLLATE ID|STRING",
+ /* 68 */ "autoinc ::=",
+ /* 69 */ "autoinc ::= AUTOINCR",
+ /* 70 */ "refargs ::=",
+ /* 71 */ "refargs ::= refargs refarg",
+ /* 72 */ "refarg ::= MATCH nm",
+ /* 73 */ "refarg ::= ON INSERT refact",
+ /* 74 */ "refarg ::= ON DELETE refact",
+ /* 75 */ "refarg ::= ON UPDATE refact",
+ /* 76 */ "refact ::= SET NULL",
+ /* 77 */ "refact ::= SET DEFAULT",
+ /* 78 */ "refact ::= CASCADE",
+ /* 79 */ "refact ::= RESTRICT",
+ /* 80 */ "refact ::= NO ACTION",
+ /* 81 */ "defer_subclause ::= NOT DEFERRABLE init_deferred_pred_opt",
+ /* 82 */ "defer_subclause ::= DEFERRABLE init_deferred_pred_opt",
+ /* 83 */ "init_deferred_pred_opt ::=",
+ /* 84 */ "init_deferred_pred_opt ::= INITIALLY DEFERRED",
+ /* 85 */ "init_deferred_pred_opt ::= INITIALLY IMMEDIATE",
+ /* 86 */ "conslist_opt ::=",
+ /* 87 */ "conslist_opt ::= COMMA conslist",
+ /* 88 */ "conslist ::= conslist tconscomma tcons",
+ /* 89 */ "conslist ::= tcons",
+ /* 90 */ "tconscomma ::= COMMA",
+ /* 91 */ "tconscomma ::=",
+ /* 92 */ "tcons ::= CONSTRAINT nm",
+ /* 93 */ "tcons ::= PRIMARY KEY LP sortlist autoinc RP onconf",
+ /* 94 */ "tcons ::= UNIQUE LP sortlist RP onconf",
+ /* 95 */ "tcons ::= CHECK LP expr RP onconf",
+ /* 96 */ "tcons ::= FOREIGN KEY LP eidlist RP REFERENCES nm eidlist_opt refargs defer_subclause_opt",
+ /* 97 */ "defer_subclause_opt ::=",
+ /* 98 */ "defer_subclause_opt ::= defer_subclause",
+ /* 99 */ "onconf ::=",
+ /* 100 */ "onconf ::= ON CONFLICT resolvetype",
+ /* 101 */ "orconf ::=",
+ /* 102 */ "orconf ::= OR resolvetype",
+ /* 103 */ "resolvetype ::= raisetype",
+ /* 104 */ "resolvetype ::= IGNORE",
+ /* 105 */ "resolvetype ::= REPLACE",
+ /* 106 */ "cmd ::= DROP TABLE ifexists fullname",
+ /* 107 */ "ifexists ::= IF EXISTS",
+ /* 108 */ "ifexists ::=",
+ /* 109 */ "cmd ::= createkw temp VIEW ifnotexists nm dbnm eidlist_opt AS select",
+ /* 110 */ "cmd ::= DROP VIEW ifexists fullname",
+ /* 111 */ "cmd ::= select",
+ /* 112 */ "select ::= with selectnowith",
+ /* 113 */ "selectnowith ::= oneselect",
+ /* 114 */ "selectnowith ::= selectnowith 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",
+ /* 119 */ "oneselect ::= values",
+ /* 120 */ "values ::= VALUES LP nexprlist RP",
+ /* 121 */ "values ::= values COMMA LP exprlist RP",
+ /* 122 */ "distinct ::= DISTINCT",
+ /* 123 */ "distinct ::= ALL",
+ /* 124 */ "distinct ::=",
+ /* 125 */ "sclp ::= selcollist COMMA",
+ /* 126 */ "sclp ::=",
+ /* 127 */ "selcollist ::= sclp expr as",
+ /* 128 */ "selcollist ::= sclp STAR",
+ /* 129 */ "selcollist ::= sclp nm DOT STAR",
+ /* 130 */ "as ::= AS nm",
+ /* 131 */ "as ::= ID|STRING",
+ /* 132 */ "as ::=",
+ /* 133 */ "from ::=",
+ /* 134 */ "from ::= FROM seltablist",
+ /* 135 */ "stl_prefix ::= seltablist joinop",
+ /* 136 */ "stl_prefix ::=",
+ /* 137 */ "seltablist ::= stl_prefix nm dbnm as indexed_opt on_opt using_opt",
+ /* 138 */ "seltablist ::= stl_prefix nm dbnm LP exprlist RP as on_opt using_opt",
+ /* 139 */ "seltablist ::= stl_prefix LP select RP as on_opt using_opt",
+ /* 140 */ "seltablist ::= stl_prefix LP seltablist RP as on_opt using_opt",
+ /* 141 */ "dbnm ::=",
+ /* 142 */ "dbnm ::= DOT nm",
+ /* 143 */ "fullname ::= nm dbnm",
+ /* 144 */ "joinop ::= COMMA|JOIN",
+ /* 145 */ "joinop ::= JOIN_KW JOIN",
+ /* 146 */ "joinop ::= JOIN_KW nm JOIN",
+ /* 147 */ "joinop ::= JOIN_KW nm nm JOIN",
+ /* 148 */ "on_opt ::= ON expr",
+ /* 149 */ "on_opt ::=",
+ /* 150 */ "indexed_opt ::=",
+ /* 151 */ "indexed_opt ::= INDEXED BY nm",
+ /* 152 */ "indexed_opt ::= NOT INDEXED",
+ /* 153 */ "using_opt ::= USING LP idlist RP",
+ /* 154 */ "using_opt ::=",
+ /* 155 */ "orderby_opt ::=",
+ /* 156 */ "orderby_opt ::= ORDER BY sortlist",
+ /* 157 */ "sortlist ::= sortlist COMMA expr sortorder",
+ /* 158 */ "sortlist ::= expr sortorder",
+ /* 159 */ "sortorder ::= ASC",
+ /* 160 */ "sortorder ::= DESC",
+ /* 161 */ "sortorder ::=",
+ /* 162 */ "groupby_opt ::=",
+ /* 163 */ "groupby_opt ::= GROUP BY nexprlist",
+ /* 164 */ "having_opt ::=",
+ /* 165 */ "having_opt ::= HAVING expr",
+ /* 166 */ "limit_opt ::=",
+ /* 167 */ "limit_opt ::= LIMIT expr",
+ /* 168 */ "limit_opt ::= LIMIT expr OFFSET expr",
+ /* 169 */ "limit_opt ::= LIMIT expr COMMA expr",
+ /* 170 */ "cmd ::= with DELETE FROM fullname indexed_opt where_opt",
+ /* 171 */ "where_opt ::=",
+ /* 172 */ "where_opt ::= WHERE expr",
+ /* 173 */ "cmd ::= with UPDATE orconf fullname indexed_opt SET setlist where_opt",
+ /* 174 */ "setlist ::= setlist COMMA nm EQ expr",
+ /* 175 */ "setlist ::= nm EQ expr",
+ /* 176 */ "cmd ::= with insert_cmd INTO fullname idlist_opt select",
+ /* 177 */ "cmd ::= with insert_cmd INTO fullname idlist_opt DEFAULT VALUES",
+ /* 178 */ "insert_cmd ::= INSERT orconf",
+ /* 179 */ "insert_cmd ::= REPLACE",
+ /* 180 */ "idlist_opt ::=",
+ /* 181 */ "idlist_opt ::= LP idlist RP",
+ /* 182 */ "idlist ::= idlist COMMA nm",
+ /* 183 */ "idlist ::= nm",
+ /* 184 */ "expr ::= term",
+ /* 185 */ "expr ::= LP expr RP",
+ /* 186 */ "term ::= NULL",
+ /* 187 */ "expr ::= ID|INDEXED",
+ /* 188 */ "expr ::= JOIN_KW",
+ /* 189 */ "expr ::= nm DOT nm",
+ /* 190 */ "expr ::= nm DOT nm DOT nm",
+ /* 191 */ "term ::= INTEGER|FLOAT|BLOB",
+ /* 192 */ "term ::= STRING",
/* 193 */ "expr ::= VARIABLE",
- /* 194 */ "expr ::= expr COLLATE ids",
+ /* 194 */ "expr ::= expr COLLATE ID|STRING",
/* 195 */ "expr ::= CAST LP expr AS typetoken RP",
- /* 196 */ "expr ::= ID LP distinct exprlist RP",
- /* 197 */ "expr ::= ID LP STAR RP",
+ /* 196 */ "expr ::= ID|INDEXED LP distinct exprlist RP",
+ /* 197 */ "expr ::= ID|INDEXED LP STAR RP",
/* 198 */ "term ::= CTIME_KW",
/* 199 */ "expr ::= expr AND expr",
/* 200 */ "expr ::= expr OR expr",
@@ -109175,126 +128486,127 @@ static const char *const yyRuleName[] = {
/* 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",
+ /* 207 */ "likeop ::= LIKE_KW|MATCH",
+ /* 208 */ "likeop ::= NOT LIKE_KW|MATCH",
+ /* 209 */ "expr ::= expr likeop expr",
+ /* 210 */ "expr ::= expr likeop expr ESCAPE expr",
+ /* 211 */ "expr ::= expr ISNULL|NOTNULL",
+ /* 212 */ "expr ::= expr NOT NULL",
+ /* 213 */ "expr ::= expr IS expr",
+ /* 214 */ "expr ::= expr IS NOT expr",
+ /* 215 */ "expr ::= NOT expr",
+ /* 216 */ "expr ::= BITNOT expr",
+ /* 217 */ "expr ::= MINUS expr",
+ /* 218 */ "expr ::= PLUS expr",
+ /* 219 */ "between_op ::= BETWEEN",
+ /* 220 */ "between_op ::= NOT BETWEEN",
+ /* 221 */ "expr ::= expr between_op expr AND expr",
+ /* 222 */ "in_op ::= IN",
+ /* 223 */ "in_op ::= NOT IN",
+ /* 224 */ "expr ::= expr in_op LP exprlist RP",
+ /* 225 */ "expr ::= LP select RP",
+ /* 226 */ "expr ::= expr in_op LP select RP",
+ /* 227 */ "expr ::= expr in_op nm dbnm",
+ /* 228 */ "expr ::= EXISTS LP select RP",
+ /* 229 */ "expr ::= CASE case_operand case_exprlist case_else END",
+ /* 230 */ "case_exprlist ::= case_exprlist WHEN expr THEN expr",
+ /* 231 */ "case_exprlist ::= WHEN expr THEN expr",
+ /* 232 */ "case_else ::= ELSE expr",
+ /* 233 */ "case_else ::=",
+ /* 234 */ "case_operand ::= expr",
+ /* 235 */ "case_operand ::=",
+ /* 236 */ "exprlist ::= nexprlist",
+ /* 237 */ "exprlist ::=",
+ /* 238 */ "nexprlist ::= nexprlist COMMA expr",
+ /* 239 */ "nexprlist ::= expr",
+ /* 240 */ "cmd ::= createkw uniqueflag INDEX ifnotexists nm dbnm ON nm LP sortlist RP where_opt",
+ /* 241 */ "uniqueflag ::= UNIQUE",
+ /* 242 */ "uniqueflag ::=",
+ /* 243 */ "eidlist_opt ::=",
+ /* 244 */ "eidlist_opt ::= LP eidlist RP",
+ /* 245 */ "eidlist ::= eidlist COMMA nm collate sortorder",
+ /* 246 */ "eidlist ::= nm collate sortorder",
+ /* 247 */ "collate ::=",
+ /* 248 */ "collate ::= COLLATE ID|STRING",
+ /* 249 */ "cmd ::= DROP INDEX ifexists fullname",
+ /* 250 */ "cmd ::= VACUUM",
+ /* 251 */ "cmd ::= VACUUM nm",
+ /* 252 */ "cmd ::= PRAGMA nm dbnm",
+ /* 253 */ "cmd ::= PRAGMA nm dbnm EQ nmnum",
+ /* 254 */ "cmd ::= PRAGMA nm dbnm LP nmnum RP",
+ /* 255 */ "cmd ::= PRAGMA nm dbnm EQ minus_num",
+ /* 256 */ "cmd ::= PRAGMA nm dbnm LP minus_num RP",
+ /* 257 */ "nmnum ::= plus_num",
+ /* 258 */ "nmnum ::= nm",
+ /* 259 */ "nmnum ::= ON",
+ /* 260 */ "nmnum ::= DELETE",
+ /* 261 */ "nmnum ::= DEFAULT",
+ /* 262 */ "plus_num ::= PLUS INTEGER|FLOAT",
+ /* 263 */ "plus_num ::= INTEGER|FLOAT",
+ /* 264 */ "minus_num ::= MINUS INTEGER|FLOAT",
+ /* 265 */ "cmd ::= createkw trigger_decl BEGIN trigger_cmd_list END",
+ /* 266 */ "trigger_decl ::= temp TRIGGER ifnotexists nm dbnm trigger_time trigger_event ON fullname foreach_clause when_clause",
+ /* 267 */ "trigger_time ::= BEFORE",
+ /* 268 */ "trigger_time ::= AFTER",
+ /* 269 */ "trigger_time ::= INSTEAD OF",
+ /* 270 */ "trigger_time ::=",
+ /* 271 */ "trigger_event ::= DELETE|INSERT",
+ /* 272 */ "trigger_event ::= UPDATE",
+ /* 273 */ "trigger_event ::= UPDATE OF idlist",
+ /* 274 */ "foreach_clause ::=",
+ /* 275 */ "foreach_clause ::= FOR EACH ROW",
+ /* 276 */ "when_clause ::=",
+ /* 277 */ "when_clause ::= WHEN expr",
+ /* 278 */ "trigger_cmd_list ::= trigger_cmd_list trigger_cmd SEMI",
+ /* 279 */ "trigger_cmd_list ::= trigger_cmd SEMI",
+ /* 280 */ "trnm ::= nm",
+ /* 281 */ "trnm ::= nm DOT nm",
+ /* 282 */ "tridxby ::=",
+ /* 283 */ "tridxby ::= INDEXED BY nm",
+ /* 284 */ "tridxby ::= NOT INDEXED",
+ /* 285 */ "trigger_cmd ::= UPDATE orconf trnm tridxby SET setlist where_opt",
+ /* 286 */ "trigger_cmd ::= insert_cmd INTO trnm idlist_opt select",
+ /* 287 */ "trigger_cmd ::= DELETE FROM trnm tridxby where_opt",
+ /* 288 */ "trigger_cmd ::= select",
+ /* 289 */ "expr ::= RAISE LP IGNORE RP",
+ /* 290 */ "expr ::= RAISE LP raisetype COMMA nm RP",
+ /* 291 */ "raisetype ::= ROLLBACK",
+ /* 292 */ "raisetype ::= ABORT",
+ /* 293 */ "raisetype ::= FAIL",
+ /* 294 */ "cmd ::= DROP TRIGGER ifexists fullname",
+ /* 295 */ "cmd ::= ATTACH database_kw_opt expr AS expr key_opt",
+ /* 296 */ "cmd ::= DETACH database_kw_opt expr",
+ /* 297 */ "key_opt ::=",
+ /* 298 */ "key_opt ::= KEY expr",
+ /* 299 */ "database_kw_opt ::= DATABASE",
+ /* 300 */ "database_kw_opt ::=",
+ /* 301 */ "cmd ::= REINDEX",
+ /* 302 */ "cmd ::= REINDEX nm dbnm",
+ /* 303 */ "cmd ::= ANALYZE",
+ /* 304 */ "cmd ::= ANALYZE nm dbnm",
+ /* 305 */ "cmd ::= ALTER TABLE fullname RENAME TO nm",
+ /* 306 */ "cmd ::= ALTER TABLE add_column_fullname ADD kwcolumn_opt column",
+ /* 307 */ "add_column_fullname ::= fullname",
+ /* 308 */ "kwcolumn_opt ::=",
+ /* 309 */ "kwcolumn_opt ::= COLUMNKW",
+ /* 310 */ "cmd ::= create_vtab",
+ /* 311 */ "cmd ::= create_vtab LP vtabarglist RP",
+ /* 312 */ "create_vtab ::= createkw VIRTUAL TABLE ifnotexists nm dbnm USING nm",
+ /* 313 */ "vtabarglist ::= vtabarg",
+ /* 314 */ "vtabarglist ::= vtabarglist COMMA vtabarg",
+ /* 315 */ "vtabarg ::=",
+ /* 316 */ "vtabarg ::= vtabarg vtabargtoken",
+ /* 317 */ "vtabargtoken ::= ANY",
+ /* 318 */ "vtabargtoken ::= lp anylist RP",
+ /* 319 */ "lp ::= LP",
+ /* 320 */ "anylist ::=",
+ /* 321 */ "anylist ::= anylist LP anylist RP",
+ /* 322 */ "anylist ::= anylist ANY",
+ /* 323 */ "with ::=",
+ /* 324 */ "with ::= WITH wqlist",
+ /* 325 */ "with ::= WITH RECURSIVE wqlist",
+ /* 326 */ "wqlist ::= nm eidlist_opt AS LP select RP",
+ /* 327 */ "wqlist ::= wqlist COMMA nm eidlist_opt AS LP select RP",
};
#endif /* NDEBUG */
@@ -109322,6 +128634,15 @@ static void yyGrowStack(yyParser *p){
}
#endif
+/* Datatype of the argument to the memory allocated passed as the
+** second argument to sqlite3ParserAlloc() below. This can be changed by
+** putting an appropriate #define in the %include section of the input
+** grammar.
+*/
+#ifndef YYMALLOCARGTYPE
+# define YYMALLOCARGTYPE size_t
+#endif
+
/*
** This function allocates a new parser.
** The only argument is a pointer to a function which works like
@@ -109334,9 +128655,9 @@ static void yyGrowStack(yyParser *p){
** A pointer to a parser. This pointer is used in subsequent calls
** to sqlite3Parser and sqlite3ParserFree.
*/
-SQLITE_PRIVATE void *sqlite3ParserAlloc(void *(*mallocProc)(size_t)){
+SQLITE_PRIVATE void *sqlite3ParserAlloc(void *(*mallocProc)(YYMALLOCARGTYPE)){
yyParser *pParser;
- pParser = (yyParser*)(*mallocProc)( (size_t)sizeof(yyParser) );
+ pParser = (yyParser*)(*mallocProc)( (YYMALLOCARGTYPE)sizeof(yyParser) );
if( pParser ){
pParser->yyidx = -1;
#ifdef YYTRACKMAXSTACKDEPTH
@@ -109351,10 +128672,12 @@ SQLITE_PRIVATE void *sqlite3ParserAlloc(void *(*mallocProc)(size_t)){
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.
+/* The following function deletes the "minor type" or semantic 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 to be deleted. The code used to do the
+** deletions is derived from the %destructor and/or %token_destructor
+** directives of the input grammar.
*/
static void yy_destructor(
yyParser *yypParser, /* The parser */
@@ -109370,81 +128693,83 @@ static void yy_destructor(
** 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
+ ** which appear on the RHS of the rule, but which are *not* used
** inside the C code.
*/
- case 160: /* select */
- case 194: /* oneselect */
+/********* Begin destructor definitions ***************************************/
+ case 163: /* select */
+ case 196: /* selectnowith */
+ case 197: /* oneselect */
+ case 208: /* values */
{
-sqlite3SelectDelete(pParse->db, (yypminor->yy159));
+sqlite3SelectDelete(pParse->db, (yypminor->yy387));
}
break;
- case 173: /* term */
- case 174: /* expr */
+ case 174: /* term */
+ case 175: /* expr */
{
-sqlite3ExprDelete(pParse->db, (yypminor->yy342).pExpr);
+sqlite3ExprDelete(pParse->db, (yypminor->yy118).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 */
+ case 179: /* eidlist_opt */
+ case 188: /* sortlist */
+ case 189: /* eidlist */
+ case 201: /* selcollist */
+ case 204: /* groupby_opt */
+ case 206: /* orderby_opt */
+ case 209: /* nexprlist */
+ case 210: /* exprlist */
+ case 211: /* sclp */
+ case 220: /* setlist */
+ case 227: /* case_exprlist */
{
-sqlite3ExprListDelete(pParse->db, (yypminor->yy442));
+sqlite3ExprListDelete(pParse->db, (yypminor->yy322));
}
break;
- case 193: /* fullname */
- case 198: /* from */
- case 206: /* seltablist */
- case 207: /* stl_prefix */
+ case 195: /* fullname */
+ case 202: /* from */
+ case 213: /* seltablist */
+ case 214: /* stl_prefix */
{
-sqlite3SrcListDelete(pParse->db, (yypminor->yy347));
+sqlite3SrcListDelete(pParse->db, (yypminor->yy259));
}
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 */
+ case 198: /* with */
+ case 251: /* wqlist */
{
-sqlite3ExprDelete(pParse->db, (yypminor->yy122));
+sqlite3WithDelete(pParse->db, (yypminor->yy451));
}
break;
- case 211: /* using_opt */
- case 213: /* inscollist */
- case 218: /* inscollist_opt */
+ case 203: /* where_opt */
+ case 205: /* having_opt */
+ case 217: /* on_opt */
+ case 226: /* case_operand */
+ case 228: /* case_else */
+ case 237: /* when_clause */
+ case 242: /* key_opt */
{
-sqlite3IdListDelete(pParse->db, (yypminor->yy180));
+sqlite3ExprDelete(pParse->db, (yypminor->yy314));
}
break;
- case 219: /* valuelist */
+ case 218: /* using_opt */
+ case 219: /* idlist */
+ case 222: /* idlist_opt */
{
-
- sqlite3ExprListDelete(pParse->db, (yypminor->yy487).pList);
- sqlite3SelectDelete(pParse->db, (yypminor->yy487).pSelect);
-
+sqlite3IdListDelete(pParse->db, (yypminor->yy384));
}
break;
- case 232: /* trigger_cmd_list */
- case 237: /* trigger_cmd */
+ case 233: /* trigger_cmd_list */
+ case 238: /* trigger_cmd */
{
-sqlite3DeleteTriggerStep(pParse->db, (yypminor->yy327));
+sqlite3DeleteTriggerStep(pParse->db, (yypminor->yy203));
}
break;
- case 234: /* trigger_event */
+ case 235: /* trigger_event */
{
-sqlite3IdListDelete(pParse->db, (yypminor->yy410).b);
+sqlite3IdListDelete(pParse->db, (yypminor->yy90).b);
}
break;
+/********* End destructor definitions *****************************************/
default: break; /* If no destructor action specified: do nothing */
}
}
@@ -109454,49 +128779,37 @@ sqlite3IdListDelete(pParse->db, (yypminor->yy410).b);
**
** 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;
+static void yy_pop_parser_stack(yyParser *pParser){
+ yyStackEntry *yytos;
+ assert( pParser->yyidx>=0 );
+ yytos = &pParser->yystack[pParser->yyidx--];
#ifndef NDEBUG
- if( yyTraceFILE && pParser->yyidx>=0 ){
+ if( yyTraceFILE ){
fprintf(yyTraceFILE,"%sPopping %s\n",
yyTracePrompt,
yyTokenName[yytos->major]);
}
#endif
- yymajor = yytos->major;
- yy_destructor(pParser, yymajor, &yytos->minor);
- pParser->yyidx--;
- return yymajor;
+ yy_destructor(pParser, yytos->major, &yytos->minor);
}
/*
-** Deallocate and destroy a parser. Destructors are all called for
+** Deallocate and destroy a parser. Destructors are 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>
+** If the YYPARSEFREENEVERNULL macro exists (for example because it
+** is defined in a %include section of the input grammar) then it is
+** assumed that the input pointer is never NULL.
*/
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;
+#ifndef YYPARSEFREENEVERNULL
+ if( pParser==0 ) return;
+#endif
while( pParser->yyidx>=0 ) yy_pop_parser_stack(pParser);
#if YYSTACKDEPTH<=0
free(pParser->yystack);
@@ -109517,10 +128830,6 @@ SQLITE_PRIVATE int sqlite3ParserStackPeak(void *p){
/*
** 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 */
@@ -109529,63 +128838,64 @@ static int yy_find_shift_action(
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 ){
+ if( stateno>=YY_MIN_REDUCE ) return stateno;
+ assert( stateno <= YY_SHIFT_COUNT );
+ do{
+ i = yy_shift_ofst[stateno];
+ if( i==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 ){
+ 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]);
- }
+ if( yyTraceFILE ){
+ fprintf(yyTraceFILE, "%sFALLBACK %s => %s\n",
+ yyTracePrompt, yyTokenName[iLookAhead], yyTokenName[iFallback]);
+ }
#endif
- return yy_find_shift_action(pParser, iFallback);
- }
+ assert( yyFallback[iFallback]==0 ); /* Fallback loop must terminate */
+ iLookAhead = iFallback;
+ continue;
+ }
#endif
#ifdef YYWILDCARD
- {
- int j = i - iLookAhead + YYWILDCARD;
- if(
+ {
+ int j = i - iLookAhead + YYWILDCARD;
+ if(
#if YY_SHIFT_MIN+YYWILDCARD<0
- j>=0 &&
+ j>=0 &&
#endif
#if YY_SHIFT_MAX+YYWILDCARD>=YY_ACTTAB_COUNT
- j<YY_ACTTAB_COUNT &&
+ j<YY_ACTTAB_COUNT &&
#endif
- yy_lookahead[j]==YYWILDCARD
- ){
+ yy_lookahead[j]==YYWILDCARD
+ ){
#ifndef NDEBUG
- if( yyTraceFILE ){
- fprintf(yyTraceFILE, "%sWILDCARD %s => %s\n",
- yyTracePrompt, yyTokenName[iLookAhead], yyTokenName[YYWILDCARD]);
- }
+ if( yyTraceFILE ){
+ fprintf(yyTraceFILE, "%sWILDCARD %s => %s\n",
+ yyTracePrompt, yyTokenName[iLookAhead],
+ yyTokenName[YYWILDCARD]);
+ }
#endif /* NDEBUG */
- return yy_action[j];
+ return yy_action[j];
+ }
}
- }
#endif /* YYWILDCARD */
+ }
+ return yy_default[stateno];
+ }else{
+ return yy_action[i];
}
- return yy_default[stateno];
- }else{
- return yy_action[i];
- }
+ }while(1);
}
/*
** 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 */
@@ -109628,13 +128938,35 @@ static void yyStackOverflow(yyParser *yypParser, YYMINORTYPE *yypMinor){
while( yypParser->yyidx>=0 ) yy_pop_parser_stack(yypParser);
/* Here code is inserted which will execute if the parser
** stack every overflows */
+/******** Begin %stack_overflow code ******************************************/
UNUSED_PARAMETER(yypMinor); /* Silence some compiler warnings */
sqlite3ErrorMsg(pParse, "parser stack overflow");
+/******** End %stack_overflow code ********************************************/
sqlite3ParserARG_STORE; /* Suppress warning about unused %extra_argument var */
}
/*
+** Print tracing information for a SHIFT action
+*/
+#ifndef NDEBUG
+static void yyTraceShift(yyParser *yypParser, int yyNewState){
+ if( yyTraceFILE ){
+ if( yyNewState<YYNSTATE ){
+ fprintf(yyTraceFILE,"%sShift '%s', go to state %d\n",
+ yyTracePrompt,yyTokenName[yypParser->yystack[yypParser->yyidx].major],
+ yyNewState);
+ }else{
+ fprintf(yyTraceFILE,"%sShift '%s'\n",
+ yyTracePrompt,yyTokenName[yypParser->yystack[yypParser->yyidx].major]);
+ }
+ }
+}
+#else
+# define yyTraceShift(X,Y)
+#endif
+
+/*
** Perform a shift action.
*/
static void yy_shift(
@@ -109668,16 +129000,7 @@ static void yy_shift(
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
+ yyTraceShift(yypParser, yyNewState);
}
/* The following table contains information about every rule that
@@ -109687,333 +129010,334 @@ 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, 2 },
{ 145, 1 },
- { 145, 3 },
{ 146, 1 },
+ { 146, 3 },
+ { 147, 0 },
+ { 147, 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 },
+ { 149, 3 },
{ 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 },
+ { 151, 1 },
+ { 151, 2 },
+ { 150, 0 },
{ 150, 1 },
{ 150, 1 },
{ 150, 1 },
- { 163, 0 },
- { 163, 1 },
- { 167, 1 },
- { 167, 4 },
- { 167, 6 },
+ { 149, 2 },
+ { 149, 2 },
+ { 149, 2 },
+ { 153, 1 },
+ { 153, 0 },
+ { 149, 2 },
+ { 149, 3 },
+ { 149, 5 },
+ { 149, 2 },
+ { 154, 6 },
+ { 156, 1 },
+ { 158, 0 },
+ { 158, 3 },
+ { 157, 1 },
+ { 157, 0 },
+ { 155, 5 },
+ { 155, 2 },
+ { 162, 0 },
+ { 162, 2 },
+ { 160, 3 },
+ { 160, 1 },
+ { 164, 3 },
+ { 165, 1 },
+ { 152, 1 },
+ { 152, 1 },
+ { 152, 1 },
+ { 166, 0 },
+ { 166, 1 },
{ 168, 1 },
- { 168, 2 },
+ { 168, 4 },
+ { 168, 6 },
{ 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 },
+ { 169, 2 },
+ { 170, 1 },
+ { 170, 1 },
+ { 167, 2 },
+ { 167, 0 },
+ { 173, 2 },
+ { 173, 2 },
+ { 173, 4 },
+ { 173, 3 },
+ { 173, 3 },
+ { 173, 2 },
+ { 173, 2 },
+ { 173, 3 },
+ { 173, 5 },
+ { 173, 2 },
+ { 173, 4 },
+ { 173, 4 },
+ { 173, 1 },
+ { 173, 2 },
+ { 178, 0 },
+ { 178, 1 },
+ { 180, 0 },
{ 180, 2 },
- { 183, 0 },
+ { 182, 2 },
+ { 182, 3 },
+ { 182, 3 },
+ { 182, 3 },
{ 183, 2 },
{ 183, 2 },
- { 159, 0 },
- { 159, 2 },
- { 184, 3 },
- { 184, 1 },
+ { 183, 1 },
+ { 183, 1 },
+ { 183, 2 },
+ { 181, 3 },
+ { 181, 2 },
+ { 184, 0 },
+ { 184, 2 },
+ { 184, 2 },
+ { 161, 0 },
+ { 161, 2 },
+ { 185, 3 },
{ 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 },
+ { 186, 1 },
+ { 186, 0 },
+ { 187, 2 },
+ { 187, 7 },
+ { 187, 5 },
+ { 187, 5 },
+ { 187, 10 },
+ { 190, 0 },
{ 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 },
+ { 176, 0 },
+ { 176, 3 },
+ { 191, 0 },
+ { 191, 2 },
+ { 192, 1 },
+ { 192, 1 },
+ { 192, 1 },
+ { 149, 4 },
+ { 194, 2 },
+ { 194, 0 },
+ { 149, 9 },
+ { 149, 4 },
+ { 149, 1 },
+ { 163, 2 },
{ 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 },
+ { 196, 3 },
+ { 199, 1 },
+ { 199, 2 },
+ { 199, 1 },
+ { 197, 9 },
+ { 197, 1 },
{ 208, 4 },
- { 210, 2 },
- { 210, 0 },
- { 209, 0 },
- { 209, 3 },
- { 209, 2 },
- { 211, 4 },
+ { 208, 5 },
+ { 200, 1 },
+ { 200, 1 },
+ { 200, 0 },
+ { 211, 2 },
{ 211, 0 },
+ { 201, 3 },
+ { 201, 2 },
+ { 201, 4 },
+ { 212, 2 },
+ { 212, 1 },
+ { 212, 0 },
{ 202, 0 },
- { 202, 3 },
- { 214, 4 },
+ { 202, 2 },
{ 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 },
+ { 214, 0 },
+ { 213, 7 },
+ { 213, 9 },
+ { 213, 7 },
+ { 213, 7 },
+ { 159, 0 },
+ { 159, 2 },
+ { 195, 2 },
+ { 215, 1 },
+ { 215, 2 },
+ { 215, 3 },
+ { 215, 4 },
{ 217, 2 },
- { 217, 1 },
- { 219, 4 },
- { 219, 5 },
+ { 217, 0 },
+ { 216, 0 },
+ { 216, 3 },
+ { 216, 2 },
+ { 218, 4 },
{ 218, 0 },
- { 218, 3 },
- { 213, 3 },
- { 213, 1 },
- { 174, 1 },
- { 174, 3 },
- { 173, 1 },
+ { 206, 0 },
+ { 206, 3 },
+ { 188, 4 },
+ { 188, 2 },
+ { 177, 1 },
+ { 177, 1 },
+ { 177, 0 },
+ { 204, 0 },
+ { 204, 3 },
+ { 205, 0 },
+ { 205, 2 },
+ { 207, 0 },
+ { 207, 2 },
+ { 207, 4 },
+ { 207, 4 },
+ { 149, 6 },
+ { 203, 0 },
+ { 203, 2 },
+ { 149, 8 },
+ { 220, 5 },
+ { 220, 3 },
+ { 149, 6 },
+ { 149, 7 },
+ { 221, 2 },
+ { 221, 1 },
+ { 222, 0 },
+ { 222, 3 },
+ { 219, 3 },
+ { 219, 1 },
+ { 175, 1 },
+ { 175, 3 },
{ 174, 1 },
+ { 175, 1 },
+ { 175, 1 },
+ { 175, 3 },
+ { 175, 5 },
{ 174, 1 },
- { 174, 3 },
- { 174, 5 },
- { 173, 1 },
- { 173, 1 },
{ 174, 1 },
+ { 175, 1 },
+ { 175, 3 },
+ { 175, 6 },
+ { 175, 5 },
+ { 175, 4 },
{ 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 },
+ { 175, 3 },
+ { 175, 3 },
+ { 175, 3 },
+ { 175, 3 },
+ { 175, 3 },
+ { 175, 3 },
+ { 175, 3 },
+ { 175, 3 },
{ 223, 1 },
{ 223, 2 },
- { 174, 5 },
- { 174, 3 },
- { 174, 5 },
- { 174, 4 },
- { 174, 4 },
- { 174, 5 },
- { 225, 5 },
- { 225, 4 },
- { 226, 2 },
- { 226, 0 },
+ { 175, 3 },
+ { 175, 5 },
+ { 175, 2 },
+ { 175, 3 },
+ { 175, 3 },
+ { 175, 4 },
+ { 175, 2 },
+ { 175, 2 },
+ { 175, 2 },
+ { 175, 2 },
{ 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 },
+ { 224, 2 },
+ { 175, 5 },
+ { 225, 1 },
+ { 225, 2 },
+ { 175, 5 },
+ { 175, 3 },
+ { 175, 5 },
+ { 175, 4 },
+ { 175, 4 },
+ { 175, 5 },
+ { 227, 5 },
+ { 227, 4 },
{ 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 },
+ { 228, 0 },
+ { 226, 1 },
+ { 226, 0 },
+ { 210, 1 },
+ { 210, 0 },
+ { 209, 3 },
+ { 209, 1 },
+ { 149, 12 },
{ 229, 1 },
- { 170, 2 },
- { 170, 1 },
+ { 229, 0 },
+ { 179, 0 },
+ { 179, 3 },
+ { 189, 5 },
+ { 189, 3 },
+ { 230, 0 },
+ { 230, 2 },
+ { 149, 4 },
+ { 149, 1 },
+ { 149, 2 },
+ { 149, 3 },
+ { 149, 5 },
+ { 149, 6 },
+ { 149, 5 },
+ { 149, 6 },
+ { 231, 1 },
+ { 231, 1 },
+ { 231, 1 },
+ { 231, 1 },
+ { 231, 1 },
{ 171, 2 },
- { 230, 1 },
- { 147, 5 },
- { 231, 11 },
- { 233, 1 },
- { 233, 1 },
- { 233, 2 },
- { 233, 0 },
+ { 171, 1 },
+ { 172, 2 },
+ { 149, 5 },
+ { 232, 11 },
{ 234, 1 },
{ 234, 1 },
- { 234, 3 },
- { 235, 0 },
+ { 234, 2 },
+ { 234, 0 },
+ { 235, 1 },
+ { 235, 1 },
{ 235, 3 },
{ 236, 0 },
- { 236, 2 },
- { 232, 3 },
- { 232, 2 },
- { 238, 1 },
- { 238, 3 },
- { 239, 0 },
+ { 236, 3 },
+ { 237, 0 },
+ { 237, 2 },
+ { 233, 3 },
+ { 233, 2 },
+ { 239, 1 },
{ 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 },
+ { 240, 3 },
+ { 240, 2 },
+ { 238, 7 },
+ { 238, 5 },
+ { 238, 5 },
+ { 238, 1 },
+ { 175, 4 },
+ { 175, 6 },
+ { 193, 1 },
+ { 193, 1 },
+ { 193, 1 },
+ { 149, 4 },
+ { 149, 6 },
+ { 149, 3 },
+ { 242, 0 },
+ { 242, 2 },
+ { 241, 1 },
+ { 241, 0 },
+ { 149, 1 },
+ { 149, 3 },
+ { 149, 1 },
+ { 149, 3 },
+ { 149, 6 },
+ { 149, 6 },
{ 243, 1 },
- { 147, 1 },
- { 147, 4 },
- { 244, 8 },
- { 245, 1 },
- { 245, 3 },
- { 246, 0 },
- { 246, 2 },
- { 247, 1 },
- { 247, 3 },
+ { 244, 0 },
+ { 244, 1 },
+ { 149, 1 },
+ { 149, 4 },
+ { 245, 8 },
+ { 246, 1 },
+ { 246, 3 },
+ { 247, 0 },
+ { 247, 2 },
{ 248, 1 },
- { 249, 0 },
- { 249, 4 },
- { 249, 2 },
+ { 248, 3 },
+ { 249, 1 },
+ { 250, 0 },
+ { 250, 4 },
+ { 250, 2 },
+ { 198, 0 },
+ { 198, 2 },
+ { 198, 3 },
+ { 251, 6 },
+ { 251, 8 },
};
static void yy_accept(yyParser*); /* Forward Declaration */
@@ -110036,29 +129360,13 @@ static void yy_reduce(
#ifndef NDEBUG
if( yyTraceFILE && yyruleno>=0
&& yyruleno<(int)(sizeof(yyRuleName)/sizeof(yyRuleName[0])) ){
- fprintf(yyTraceFILE, "%sReduce [%s].\n", yyTracePrompt,
- yyRuleName[yyruleno]);
+ yysize = yyRuleInfo[yyruleno].nrhs;
+ fprintf(yyTraceFILE, "%sReduce [%s], go to state %d.\n", yyTracePrompt,
+ yyRuleName[yyruleno], yymsp[-yysize].stateno);
}
#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:
@@ -110068,6 +129376,7 @@ static void yy_reduce(
** #line <lineno> <thisfile>
** break;
*/
+/********** Begin reduce actions **********************************************/
case 5: /* explain ::= */
{ sqlite3BeginParse(pParse, 0); }
break;
@@ -110081,17 +129390,17 @@ static void yy_reduce(
{ sqlite3FinishCoding(pParse); }
break;
case 9: /* cmd ::= BEGIN transtype trans_opt */
-{sqlite3BeginTransaction(pParse, yymsp[-1].minor.yy392);}
+{sqlite3BeginTransaction(pParse, yymsp[-1].minor.yy4);}
break;
case 13: /* transtype ::= */
-{yygotominor.yy392 = TK_DEFERRED;}
+{yygotominor.yy4 = 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;}
+{yygotominor.yy4 = yymsp[0].major;}
break;
case 17: /* cmd ::= COMMIT trans_opt */
case 18: /* cmd ::= END trans_opt */ yytestcase(yyruleno==18);
@@ -110117,7 +129426,7 @@ static void yy_reduce(
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);
+ sqlite3StartTable(pParse,&yymsp[-1].minor.yy0,&yymsp[0].minor.yy0,yymsp[-4].minor.yy4,0,0,yymsp[-2].minor.yy4);
}
break;
case 27: /* createkw ::= CREATE */
@@ -110128,590 +129437,652 @@ static void yy_reduce(
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;}
+ case 34: /* table_options ::= */ yytestcase(yyruleno==34);
+ case 68: /* autoinc ::= */ yytestcase(yyruleno==68);
+ case 81: /* defer_subclause ::= NOT DEFERRABLE init_deferred_pred_opt */ yytestcase(yyruleno==81);
+ case 83: /* init_deferred_pred_opt ::= */ yytestcase(yyruleno==83);
+ case 85: /* init_deferred_pred_opt ::= INITIALLY IMMEDIATE */ yytestcase(yyruleno==85);
+ case 97: /* defer_subclause_opt ::= */ yytestcase(yyruleno==97);
+ case 108: /* ifexists ::= */ yytestcase(yyruleno==108);
+ case 124: /* distinct ::= */ yytestcase(yyruleno==124);
+ case 219: /* between_op ::= BETWEEN */ yytestcase(yyruleno==219);
+ case 222: /* in_op ::= IN */ yytestcase(yyruleno==222);
+ case 247: /* collate ::= */ yytestcase(yyruleno==247);
+{yygotominor.yy4 = 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;}
+ case 69: /* autoinc ::= AUTOINCR */ yytestcase(yyruleno==69);
+ case 84: /* init_deferred_pred_opt ::= INITIALLY DEFERRED */ yytestcase(yyruleno==84);
+ case 107: /* ifexists ::= IF EXISTS */ yytestcase(yyruleno==107);
+ case 220: /* between_op ::= NOT BETWEEN */ yytestcase(yyruleno==220);
+ case 223: /* in_op ::= NOT IN */ yytestcase(yyruleno==223);
+ case 248: /* collate ::= COLLATE ID|STRING */ yytestcase(yyruleno==248);
+{yygotominor.yy4 = 1;}
break;
- case 32: /* create_table_args ::= LP columnlist conslist_opt RP */
+ case 32: /* create_table_args ::= LP columnlist conslist_opt RP table_options */
{
- sqlite3EndTable(pParse,&yymsp[-1].minor.yy0,&yymsp[0].minor.yy0,0);
+ sqlite3EndTable(pParse,&yymsp[-2].minor.yy0,&yymsp[-1].minor.yy0,yymsp[0].minor.yy4,0);
}
break;
case 33: /* create_table_args ::= AS select */
{
- sqlite3EndTable(pParse,0,0,yymsp[0].minor.yy159);
- sqlite3SelectDelete(pParse->db, yymsp[0].minor.yy159);
+ sqlite3EndTable(pParse,0,0,0,yymsp[0].minor.yy387);
+ sqlite3SelectDelete(pParse->db, yymsp[0].minor.yy387);
}
break;
- case 36: /* column ::= columnid type carglist */
+ case 35: /* table_options ::= WITHOUT nm */
+{
+ if( yymsp[0].minor.yy0.n==5 && sqlite3_strnicmp(yymsp[0].minor.yy0.z,"rowid",5)==0 ){
+ yygotominor.yy4 = TF_WithoutRowid | TF_NoVisibleRowid;
+ }else{
+ yygotominor.yy4 = 0;
+ sqlite3ErrorMsg(pParse, "unknown table option: %.*s", yymsp[0].minor.yy0.n, yymsp[0].minor.yy0.z);
+ }
+}
+ break;
+ case 38: /* 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 */
+ case 39: /* 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);
+ case 40: /* nm ::= ID|INDEXED */
+ case 41: /* nm ::= STRING */ yytestcase(yyruleno==41);
+ case 42: /* nm ::= JOIN_KW */ yytestcase(yyruleno==42);
+ case 45: /* typetoken ::= typename */ yytestcase(yyruleno==45);
+ case 48: /* typename ::= ID|STRING */ yytestcase(yyruleno==48);
+ case 130: /* as ::= AS nm */ yytestcase(yyruleno==130);
+ case 131: /* as ::= ID|STRING */ yytestcase(yyruleno==131);
+ case 142: /* dbnm ::= DOT nm */ yytestcase(yyruleno==142);
+ case 151: /* indexed_opt ::= INDEXED BY nm */ yytestcase(yyruleno==151);
+ case 257: /* nmnum ::= plus_num */ yytestcase(yyruleno==257);
+ case 258: /* nmnum ::= nm */ yytestcase(yyruleno==258);
+ case 259: /* nmnum ::= ON */ yytestcase(yyruleno==259);
+ case 260: /* nmnum ::= DELETE */ yytestcase(yyruleno==260);
+ case 261: /* nmnum ::= DEFAULT */ yytestcase(yyruleno==261);
+ case 262: /* plus_num ::= PLUS INTEGER|FLOAT */ yytestcase(yyruleno==262);
+ case 263: /* plus_num ::= INTEGER|FLOAT */ yytestcase(yyruleno==263);
+ case 264: /* minus_num ::= MINUS INTEGER|FLOAT */ yytestcase(yyruleno==264);
+ case 280: /* trnm ::= nm */ yytestcase(yyruleno==280);
{yygotominor.yy0 = yymsp[0].minor.yy0;}
break;
- case 45: /* type ::= typetoken */
+ case 44: /* type ::= typetoken */
{sqlite3AddColumnType(pParse,&yymsp[0].minor.yy0);}
break;
- case 47: /* typetoken ::= typename LP signed RP */
+ case 46: /* 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 */
+ case 47: /* 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 */
+ case 49: /* typename ::= typename ID|STRING */
{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);
+ case 54: /* ccons ::= CONSTRAINT nm */
+ case 92: /* tcons ::= CONSTRAINT nm */ yytestcase(yyruleno==92);
{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);}
+ case 55: /* ccons ::= DEFAULT term */
+ case 57: /* ccons ::= DEFAULT PLUS term */ yytestcase(yyruleno==57);
+{sqlite3AddDefaultValue(pParse,&yymsp[0].minor.yy118);}
break;
- case 57: /* ccons ::= DEFAULT LP expr RP */
-{sqlite3AddDefaultValue(pParse,&yymsp[-1].minor.yy342);}
+ case 56: /* ccons ::= DEFAULT LP expr RP */
+{sqlite3AddDefaultValue(pParse,&yymsp[-1].minor.yy118);}
break;
- case 59: /* ccons ::= DEFAULT MINUS term */
+ case 58: /* ccons ::= DEFAULT MINUS term */
{
ExprSpan v;
- v.pExpr = sqlite3PExpr(pParse, TK_UMINUS, yymsp[0].minor.yy342.pExpr, 0, 0);
+ v.pExpr = sqlite3PExpr(pParse, TK_UMINUS, yymsp[0].minor.yy118.pExpr, 0, 0);
v.zStart = yymsp[-1].minor.yy0.z;
- v.zEnd = yymsp[0].minor.yy342.zEnd;
+ v.zEnd = yymsp[0].minor.yy118.zEnd;
sqlite3AddDefaultValue(pParse,&v);
}
break;
- case 60: /* ccons ::= DEFAULT id */
+ case 59: /* ccons ::= DEFAULT ID|INDEXED */
{
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);}
+ case 61: /* ccons ::= NOT NULL onconf */
+{sqlite3AddNotNull(pParse, yymsp[0].minor.yy4);}
break;
- case 63: /* ccons ::= PRIMARY KEY sortorder onconf autoinc */
-{sqlite3AddPrimaryKey(pParse,0,yymsp[-1].minor.yy392,yymsp[0].minor.yy392,yymsp[-2].minor.yy392);}
+ case 62: /* ccons ::= PRIMARY KEY sortorder onconf autoinc */
+{sqlite3AddPrimaryKey(pParse,0,yymsp[-1].minor.yy4,yymsp[0].minor.yy4,yymsp[-2].minor.yy4);}
break;
- case 64: /* ccons ::= UNIQUE onconf */
-{sqlite3CreateIndex(pParse,0,0,0,0,yymsp[0].minor.yy392,0,0,0,0);}
+ case 63: /* ccons ::= UNIQUE onconf */
+{sqlite3CreateIndex(pParse,0,0,0,0,yymsp[0].minor.yy4,0,0,0,0);}
break;
- case 65: /* ccons ::= CHECK LP expr RP */
-{sqlite3AddCheckConstraint(pParse,yymsp[-1].minor.yy342.pExpr);}
+ case 64: /* ccons ::= CHECK LP expr RP */
+{sqlite3AddCheckConstraint(pParse,yymsp[-1].minor.yy118.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);}
+ case 65: /* ccons ::= REFERENCES nm eidlist_opt refargs */
+{sqlite3CreateForeignKey(pParse,0,&yymsp[-2].minor.yy0,yymsp[-1].minor.yy322,yymsp[0].minor.yy4);}
break;
- case 67: /* ccons ::= defer_subclause */
-{sqlite3DeferForeignKey(pParse,yymsp[0].minor.yy392);}
+ case 66: /* ccons ::= defer_subclause */
+{sqlite3DeferForeignKey(pParse,yymsp[0].minor.yy4);}
break;
- case 68: /* ccons ::= COLLATE ids */
+ case 67: /* ccons ::= COLLATE ID|STRING */
{sqlite3AddCollateType(pParse, &yymsp[0].minor.yy0);}
break;
- case 71: /* refargs ::= */
-{ yygotominor.yy392 = OE_None*0x0101; /* EV: R-19803-45884 */}
+ case 70: /* refargs ::= */
+{ yygotominor.yy4 = 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; }
+ case 71: /* refargs ::= refargs refarg */
+{ yygotominor.yy4 = (yymsp[-1].minor.yy4 & ~yymsp[0].minor.yy215.mask) | yymsp[0].minor.yy215.value; }
break;
- case 73: /* refarg ::= MATCH nm */
- case 74: /* refarg ::= ON INSERT refact */ yytestcase(yyruleno==74);
-{ yygotominor.yy207.value = 0; yygotominor.yy207.mask = 0x000000; }
+ case 72: /* refarg ::= MATCH nm */
+ case 73: /* refarg ::= ON INSERT refact */ yytestcase(yyruleno==73);
+{ yygotominor.yy215.value = 0; yygotominor.yy215.mask = 0x000000; }
break;
- case 75: /* refarg ::= ON DELETE refact */
-{ yygotominor.yy207.value = yymsp[0].minor.yy392; yygotominor.yy207.mask = 0x0000ff; }
+ case 74: /* refarg ::= ON DELETE refact */
+{ yygotominor.yy215.value = yymsp[0].minor.yy4; yygotominor.yy215.mask = 0x0000ff; }
break;
- case 76: /* refarg ::= ON UPDATE refact */
-{ yygotominor.yy207.value = yymsp[0].minor.yy392<<8; yygotominor.yy207.mask = 0x00ff00; }
+ case 75: /* refarg ::= ON UPDATE refact */
+{ yygotominor.yy215.value = yymsp[0].minor.yy4<<8; yygotominor.yy215.mask = 0x00ff00; }
break;
- case 77: /* refact ::= SET NULL */
-{ yygotominor.yy392 = OE_SetNull; /* EV: R-33326-45252 */}
+ case 76: /* refact ::= SET NULL */
+{ yygotominor.yy4 = OE_SetNull; /* EV: R-33326-45252 */}
break;
- case 78: /* refact ::= SET DEFAULT */
-{ yygotominor.yy392 = OE_SetDflt; /* EV: R-33326-45252 */}
+ case 77: /* refact ::= SET DEFAULT */
+{ yygotominor.yy4 = OE_SetDflt; /* EV: R-33326-45252 */}
break;
- case 79: /* refact ::= CASCADE */
-{ yygotominor.yy392 = OE_Cascade; /* EV: R-33326-45252 */}
+ case 78: /* refact ::= CASCADE */
+{ yygotominor.yy4 = OE_Cascade; /* EV: R-33326-45252 */}
break;
- case 80: /* refact ::= RESTRICT */
-{ yygotominor.yy392 = OE_Restrict; /* EV: R-33326-45252 */}
+ case 79: /* refact ::= RESTRICT */
+{ yygotominor.yy4 = OE_Restrict; /* EV: R-33326-45252 */}
break;
- case 81: /* refact ::= NO ACTION */
-{ yygotominor.yy392 = OE_None; /* EV: R-33326-45252 */}
+ case 80: /* refact ::= NO ACTION */
+{ yygotominor.yy4 = 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;}
+ case 82: /* defer_subclause ::= DEFERRABLE init_deferred_pred_opt */
+ case 98: /* defer_subclause_opt ::= defer_subclause */ yytestcase(yyruleno==98);
+ case 100: /* onconf ::= ON CONFLICT resolvetype */ yytestcase(yyruleno==100);
+ case 102: /* orconf ::= OR resolvetype */ yytestcase(yyruleno==102);
+ case 103: /* resolvetype ::= raisetype */ yytestcase(yyruleno==103);
+ case 178: /* insert_cmd ::= INSERT orconf */ yytestcase(yyruleno==178);
+{yygotominor.yy4 = yymsp[0].minor.yy4;}
break;
- case 87: /* conslist_opt ::= */
+ case 86: /* conslist_opt ::= */
{yygotominor.yy0.n = 0; yygotominor.yy0.z = 0;}
break;
- case 88: /* conslist_opt ::= COMMA conslist */
+ case 87: /* conslist_opt ::= COMMA conslist */
{yygotominor.yy0 = yymsp[-1].minor.yy0;}
break;
- case 91: /* tconscomma ::= COMMA */
+ case 90: /* 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);}
+ case 93: /* tcons ::= PRIMARY KEY LP sortlist autoinc RP onconf */
+{sqlite3AddPrimaryKey(pParse,yymsp[-3].minor.yy322,yymsp[0].minor.yy4,yymsp[-2].minor.yy4,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);}
+ case 94: /* tcons ::= UNIQUE LP sortlist RP onconf */
+{sqlite3CreateIndex(pParse,0,0,0,yymsp[-2].minor.yy322,yymsp[0].minor.yy4,0,0,0,0);}
break;
- case 96: /* tcons ::= CHECK LP expr RP onconf */
-{sqlite3AddCheckConstraint(pParse,yymsp[-2].minor.yy342.pExpr);}
+ case 95: /* tcons ::= CHECK LP expr RP onconf */
+{sqlite3AddCheckConstraint(pParse,yymsp[-2].minor.yy118.pExpr);}
break;
- case 97: /* tcons ::= FOREIGN KEY LP idxlist RP REFERENCES nm idxlist_opt refargs defer_subclause_opt */
+ case 96: /* tcons ::= FOREIGN KEY LP eidlist RP REFERENCES nm eidlist_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);
+ sqlite3CreateForeignKey(pParse, yymsp[-6].minor.yy322, &yymsp[-3].minor.yy0, yymsp[-2].minor.yy322, yymsp[-1].minor.yy4);
+ sqlite3DeferForeignKey(pParse, yymsp[0].minor.yy4);
}
break;
- case 100: /* onconf ::= */
-{yygotominor.yy392 = OE_Default;}
- break;
- case 102: /* orconf ::= */
-{yygotominor.yy258 = OE_Default;}
+ case 99: /* onconf ::= */
+ case 101: /* orconf ::= */ yytestcase(yyruleno==101);
+{yygotominor.yy4 = OE_Default;}
break;
- case 103: /* orconf ::= OR resolvetype */
-{yygotominor.yy258 = (u8)yymsp[0].minor.yy392;}
+ case 104: /* resolvetype ::= IGNORE */
+{yygotominor.yy4 = OE_Ignore;}
break;
- case 105: /* resolvetype ::= IGNORE */
-{yygotominor.yy392 = OE_Ignore;}
+ case 105: /* resolvetype ::= REPLACE */
+ case 179: /* insert_cmd ::= REPLACE */ yytestcase(yyruleno==179);
+{yygotominor.yy4 = OE_Replace;}
break;
- case 106: /* resolvetype ::= REPLACE */
-{yygotominor.yy392 = OE_Replace;}
+ case 106: /* cmd ::= DROP TABLE ifexists fullname */
+{
+ sqlite3DropTable(pParse, yymsp[0].minor.yy259, 0, yymsp[-1].minor.yy4);
+}
break;
- case 107: /* cmd ::= DROP TABLE ifexists fullname */
+ case 109: /* cmd ::= createkw temp VIEW ifnotexists nm dbnm eidlist_opt AS select */
{
- sqlite3DropTable(pParse, yymsp[0].minor.yy347, 0, yymsp[-1].minor.yy392);
+ sqlite3CreateView(pParse, &yymsp[-8].minor.yy0, &yymsp[-4].minor.yy0, &yymsp[-3].minor.yy0, yymsp[-2].minor.yy322, yymsp[0].minor.yy387, yymsp[-7].minor.yy4, yymsp[-5].minor.yy4);
}
break;
- case 110: /* cmd ::= createkw temp VIEW ifnotexists nm dbnm AS select */
+ case 110: /* cmd ::= DROP VIEW ifexists fullname */
{
- 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);
+ sqlite3DropTable(pParse, yymsp[0].minor.yy259, 1, yymsp[-1].minor.yy4);
}
break;
- case 111: /* cmd ::= DROP VIEW ifexists fullname */
+ case 111: /* cmd ::= select */
{
- sqlite3DropTable(pParse, yymsp[0].minor.yy347, 1, yymsp[-1].minor.yy392);
+ SelectDest dest = {SRT_Output, 0, 0, 0, 0, 0};
+ sqlite3Select(pParse, yymsp[0].minor.yy387, &dest);
+ sqlite3SelectDelete(pParse->db, yymsp[0].minor.yy387);
}
break;
- case 112: /* cmd ::= select */
+ case 112: /* select ::= with selectnowith */
{
- 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);
+ Select *p = yymsp[0].minor.yy387;
+ if( p ){
+ p->pWith = yymsp[-1].minor.yy451;
+ parserDoubleLinkSelect(pParse, p);
+ }else{
+ sqlite3WithDelete(pParse->db, yymsp[-1].minor.yy451);
+ }
+ yygotominor.yy387 = p;
}
break;
- case 113: /* select ::= oneselect */
-{yygotominor.yy159 = yymsp[0].minor.yy159;}
+ case 113: /* selectnowith ::= oneselect */
+ case 119: /* oneselect ::= values */ yytestcase(yyruleno==119);
+{yygotominor.yy387 = yymsp[0].minor.yy387;}
break;
- case 114: /* select ::= select multiselect_op oneselect */
+ case 114: /* selectnowith ::= selectnowith 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;
+ Select *pRhs = yymsp[0].minor.yy387;
+ Select *pLhs = yymsp[-2].minor.yy387;
+ if( pRhs && pRhs->pPrior ){
+ SrcList *pFrom;
+ Token x;
+ x.n = 0;
+ parserDoubleLinkSelect(pParse, pRhs);
+ pFrom = sqlite3SrcListAppendFromTerm(pParse,0,0,0,&x,pRhs,0,0);
+ pRhs = sqlite3SelectNew(pParse,0,pFrom,0,0,0,0,0,0,0);
+ }
+ if( pRhs ){
+ pRhs->op = (u8)yymsp[-1].minor.yy4;
+ pRhs->pPrior = pLhs;
+ if( ALWAYS(pLhs) ) pLhs->selFlags &= ~SF_MultiValue;
+ pRhs->selFlags &= ~SF_MultiValue;
+ if( yymsp[-1].minor.yy4!=TK_ALL ) pParse->hasCompound = 1;
}else{
- sqlite3SelectDelete(pParse->db, yymsp[-2].minor.yy159);
+ sqlite3SelectDelete(pParse->db, pLhs);
}
- yygotominor.yy159 = yymsp[0].minor.yy159;
+ yygotominor.yy387 = pRhs;
}
break;
case 116: /* multiselect_op ::= UNION ALL */
-{yygotominor.yy392 = TK_ALL;}
+{yygotominor.yy4 = 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);
+ yygotominor.yy387 = sqlite3SelectNew(pParse,yymsp[-6].minor.yy322,yymsp[-5].minor.yy259,yymsp[-4].minor.yy314,yymsp[-3].minor.yy322,yymsp[-2].minor.yy314,yymsp[-1].minor.yy322,yymsp[-7].minor.yy4,yymsp[0].minor.yy292.pLimit,yymsp[0].minor.yy292.pOffset);
+#if SELECTTRACE_ENABLED
+ /* Populate the Select.zSelName[] string that is used to help with
+ ** query planner debugging, to differentiate between multiple Select
+ ** objects in a complex query.
+ **
+ ** If the SELECT keyword is immediately followed by a C-style comment
+ ** then extract the first few alphanumeric characters from within that
+ ** comment to be the zSelName value. Otherwise, the label is #N where
+ ** is an integer that is incremented with each SELECT statement seen.
+ */
+ if( yygotominor.yy387!=0 ){
+ const char *z = yymsp[-8].minor.yy0.z+6;
+ int i;
+ sqlite3_snprintf(sizeof(yygotominor.yy387->zSelName), yygotominor.yy387->zSelName, "#%d",
+ ++pParse->nSelect);
+ while( z[0]==' ' ) z++;
+ if( z[0]=='/' && z[1]=='*' ){
+ z += 2;
+ while( z[0]==' ' ) z++;
+ for(i=0; sqlite3Isalnum(z[i]); i++){}
+ sqlite3_snprintf(sizeof(yygotominor.yy387->zSelName), yygotominor.yy387->zSelName, "%.*s", i, z);
+ }
+ }
+#endif /* SELECTRACE_ENABLED */
+}
+ break;
+ case 120: /* values ::= VALUES LP nexprlist RP */
+{
+ yygotominor.yy387 = sqlite3SelectNew(pParse,yymsp[-1].minor.yy322,0,0,0,0,0,SF_Values,0,0);
}
break;
- case 122: /* sclp ::= selcollist COMMA */
- case 246: /* idxlist_opt ::= LP idxlist RP */ yytestcase(yyruleno==246);
-{yygotominor.yy442 = yymsp[-1].minor.yy442;}
+ case 121: /* values ::= values COMMA LP exprlist RP */
+{
+ Select *pRight, *pLeft = yymsp[-4].minor.yy387;
+ pRight = sqlite3SelectNew(pParse,yymsp[-1].minor.yy322,0,0,0,0,0,SF_Values|SF_MultiValue,0,0);
+ if( ALWAYS(pLeft) ) pLeft->selFlags &= ~SF_MultiValue;
+ if( pRight ){
+ pRight->op = TK_ALL;
+ pLeft = yymsp[-4].minor.yy387;
+ pRight->pPrior = pLeft;
+ yygotominor.yy387 = pRight;
+ }else{
+ yygotominor.yy387 = pLeft;
+ }
+}
+ break;
+ case 122: /* distinct ::= DISTINCT */
+{yygotominor.yy4 = SF_Distinct;}
+ break;
+ case 123: /* distinct ::= ALL */
+{yygotominor.yy4 = SF_All;}
+ break;
+ case 125: /* sclp ::= selcollist COMMA */
+ case 244: /* eidlist_opt ::= LP eidlist RP */ yytestcase(yyruleno==244);
+{yygotominor.yy322 = yymsp[-1].minor.yy322;}
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;}
+ case 126: /* sclp ::= */
+ case 155: /* orderby_opt ::= */ yytestcase(yyruleno==155);
+ case 162: /* groupby_opt ::= */ yytestcase(yyruleno==162);
+ case 237: /* exprlist ::= */ yytestcase(yyruleno==237);
+ case 243: /* eidlist_opt ::= */ yytestcase(yyruleno==243);
+{yygotominor.yy322 = 0;}
break;
- case 124: /* selcollist ::= sclp expr as */
+ case 127: /* 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);
+ yygotominor.yy322 = sqlite3ExprListAppend(pParse, yymsp[-2].minor.yy322, yymsp[-1].minor.yy118.pExpr);
+ if( yymsp[0].minor.yy0.n>0 ) sqlite3ExprListSetName(pParse, yygotominor.yy322, &yymsp[0].minor.yy0, 1);
+ sqlite3ExprListSetSpan(pParse,yygotominor.yy322,&yymsp[-1].minor.yy118);
}
break;
- case 125: /* selcollist ::= sclp STAR */
+ case 128: /* selcollist ::= sclp STAR */
{
- Expr *p = sqlite3Expr(pParse->db, TK_ALL, 0);
- yygotominor.yy442 = sqlite3ExprListAppend(pParse, yymsp[-1].minor.yy442, p);
+ Expr *p = sqlite3Expr(pParse->db, TK_ASTERISK, 0);
+ yygotominor.yy322 = sqlite3ExprListAppend(pParse, yymsp[-1].minor.yy322, p);
}
break;
- case 126: /* selcollist ::= sclp nm DOT STAR */
+ case 129: /* selcollist ::= sclp nm DOT STAR */
{
- Expr *pRight = sqlite3PExpr(pParse, TK_ALL, 0, 0, &yymsp[0].minor.yy0);
+ Expr *pRight = sqlite3PExpr(pParse, TK_ASTERISK, 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);
+ yygotominor.yy322 = sqlite3ExprListAppend(pParse,yymsp[-3].minor.yy322, pDot);
}
break;
- case 129: /* as ::= */
+ case 132: /* as ::= */
{yygotominor.yy0.n = 0;}
break;
- case 130: /* from ::= */
-{yygotominor.yy347 = sqlite3DbMallocZero(pParse->db, sizeof(*yygotominor.yy347));}
+ case 133: /* from ::= */
+{yygotominor.yy259 = sqlite3DbMallocZero(pParse->db, sizeof(*yygotominor.yy259));}
break;
- case 131: /* from ::= FROM seltablist */
+ case 134: /* from ::= FROM seltablist */
{
- yygotominor.yy347 = yymsp[0].minor.yy347;
- sqlite3SrcListShiftJoinType(yygotominor.yy347);
+ yygotominor.yy259 = yymsp[0].minor.yy259;
+ sqlite3SrcListShiftJoinType(yygotominor.yy259);
}
break;
- case 132: /* stl_prefix ::= seltablist joinop */
+ case 135: /* 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;
+ yygotominor.yy259 = yymsp[-1].minor.yy259;
+ if( ALWAYS(yygotominor.yy259 && yygotominor.yy259->nSrc>0) ) yygotominor.yy259->a[yygotominor.yy259->nSrc-1].fg.jointype = (u8)yymsp[0].minor.yy4;
}
break;
- case 133: /* stl_prefix ::= */
-{yygotominor.yy347 = 0;}
+ case 136: /* stl_prefix ::= */
+{yygotominor.yy259 = 0;}
break;
- case 134: /* seltablist ::= stl_prefix nm dbnm as indexed_opt on_opt using_opt */
+ case 137: /* 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);
+ yygotominor.yy259 = sqlite3SrcListAppendFromTerm(pParse,yymsp[-6].minor.yy259,&yymsp[-5].minor.yy0,&yymsp[-4].minor.yy0,&yymsp[-3].minor.yy0,0,yymsp[-1].minor.yy314,yymsp[0].minor.yy384);
+ sqlite3SrcListIndexedBy(pParse, yygotominor.yy259, &yymsp[-2].minor.yy0);
}
break;
- case 135: /* seltablist ::= stl_prefix LP select RP as on_opt using_opt */
+ case 138: /* seltablist ::= stl_prefix nm dbnm LP exprlist 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);
+ yygotominor.yy259 = sqlite3SrcListAppendFromTerm(pParse,yymsp[-8].minor.yy259,&yymsp[-7].minor.yy0,&yymsp[-6].minor.yy0,&yymsp[-2].minor.yy0,0,yymsp[-1].minor.yy314,yymsp[0].minor.yy384);
+ sqlite3SrcListFuncArgs(pParse, yygotominor.yy259, yymsp[-4].minor.yy322);
+}
+ break;
+ case 139: /* seltablist ::= stl_prefix LP select RP as on_opt using_opt */
+{
+ yygotominor.yy259 = sqlite3SrcListAppendFromTerm(pParse,yymsp[-6].minor.yy259,0,0,&yymsp[-2].minor.yy0,yymsp[-4].minor.yy387,yymsp[-1].minor.yy314,yymsp[0].minor.yy384);
}
break;
- case 136: /* seltablist ::= stl_prefix LP seltablist RP as on_opt using_opt */
+ case 140: /* 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;
+ if( yymsp[-6].minor.yy259==0 && yymsp[-2].minor.yy0.n==0 && yymsp[-1].minor.yy314==0 && yymsp[0].minor.yy384==0 ){
+ yygotominor.yy259 = yymsp[-4].minor.yy259;
+ }else if( yymsp[-4].minor.yy259->nSrc==1 ){
+ yygotominor.yy259 = sqlite3SrcListAppendFromTerm(pParse,yymsp[-6].minor.yy259,0,0,&yymsp[-2].minor.yy0,0,yymsp[-1].minor.yy314,yymsp[0].minor.yy384);
+ if( yygotominor.yy259 ){
+ struct SrcList_item *pNew = &yygotominor.yy259->a[yygotominor.yy259->nSrc-1];
+ struct SrcList_item *pOld = yymsp[-4].minor.yy259->a;
+ pNew->zName = pOld->zName;
+ pNew->zDatabase = pOld->zDatabase;
+ pNew->pSelect = pOld->pSelect;
+ pOld->zName = pOld->zDatabase = 0;
+ pOld->pSelect = 0;
+ }
+ sqlite3SrcListDelete(pParse->db, yymsp[-4].minor.yy259);
}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);
+ sqlite3SrcListShiftJoinType(yymsp[-4].minor.yy259);
+ pSubquery = sqlite3SelectNew(pParse,0,yymsp[-4].minor.yy259,0,0,0,0,SF_NestedFrom,0,0);
+ yygotominor.yy259 = sqlite3SrcListAppendFromTerm(pParse,yymsp[-6].minor.yy259,0,0,&yymsp[-2].minor.yy0,pSubquery,yymsp[-1].minor.yy314,yymsp[0].minor.yy384);
}
}
break;
- case 137: /* dbnm ::= */
- case 146: /* indexed_opt ::= */ yytestcase(yyruleno==146);
+ case 141: /* dbnm ::= */
+ case 150: /* indexed_opt ::= */ yytestcase(yyruleno==150);
{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);}
+ case 143: /* fullname ::= nm dbnm */
+{yygotominor.yy259 = sqlite3SrcListAppend(pParse->db,0,&yymsp[-1].minor.yy0,&yymsp[0].minor.yy0);}
break;
- case 140: /* joinop ::= COMMA|JOIN */
-{ yygotominor.yy392 = JT_INNER; }
+ case 144: /* joinop ::= COMMA|JOIN */
+{ yygotominor.yy4 = JT_INNER; }
break;
- case 141: /* joinop ::= JOIN_KW JOIN */
-{ yygotominor.yy392 = sqlite3JoinType(pParse,&yymsp[-1].minor.yy0,0,0); }
+ case 145: /* joinop ::= JOIN_KW JOIN */
+{ yygotominor.yy4 = 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); }
+ case 146: /* joinop ::= JOIN_KW nm JOIN */
+{ yygotominor.yy4 = 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); }
+ case 147: /* joinop ::= JOIN_KW nm nm JOIN */
+{ yygotominor.yy4 = 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;}
+ case 148: /* on_opt ::= ON expr */
+ case 165: /* having_opt ::= HAVING expr */ yytestcase(yyruleno==165);
+ case 172: /* where_opt ::= WHERE expr */ yytestcase(yyruleno==172);
+ case 232: /* case_else ::= ELSE expr */ yytestcase(yyruleno==232);
+ case 234: /* case_operand ::= expr */ yytestcase(yyruleno==234);
+{yygotominor.yy314 = yymsp[0].minor.yy118.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;}
+ case 149: /* on_opt ::= */
+ case 164: /* having_opt ::= */ yytestcase(yyruleno==164);
+ case 171: /* where_opt ::= */ yytestcase(yyruleno==171);
+ case 233: /* case_else ::= */ yytestcase(yyruleno==233);
+ case 235: /* case_operand ::= */ yytestcase(yyruleno==235);
+{yygotominor.yy314 = 0;}
break;
- case 148: /* indexed_opt ::= NOT INDEXED */
+ case 152: /* 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;}
+ case 153: /* using_opt ::= USING LP idlist RP */
+ case 181: /* idlist_opt ::= LP idlist RP */ yytestcase(yyruleno==181);
+{yygotominor.yy384 = yymsp[-1].minor.yy384;}
break;
- case 150: /* using_opt ::= */
- case 179: /* inscollist_opt ::= */ yytestcase(yyruleno==179);
-{yygotominor.yy180 = 0;}
+ case 154: /* using_opt ::= */
+ case 180: /* idlist_opt ::= */ yytestcase(yyruleno==180);
+{yygotominor.yy384 = 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;}
+ case 156: /* orderby_opt ::= ORDER BY sortlist */
+ case 163: /* groupby_opt ::= GROUP BY nexprlist */ yytestcase(yyruleno==163);
+ case 236: /* exprlist ::= nexprlist */ yytestcase(yyruleno==236);
+{yygotominor.yy322 = yymsp[0].minor.yy322;}
break;
- case 153: /* sortlist ::= sortlist COMMA expr sortorder */
+ case 157: /* 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;
+ yygotominor.yy322 = sqlite3ExprListAppend(pParse,yymsp[-3].minor.yy322,yymsp[-1].minor.yy118.pExpr);
+ sqlite3ExprListSetSortOrder(yygotominor.yy322,yymsp[0].minor.yy4);
}
break;
- case 154: /* sortlist ::= expr sortorder */
+ case 158: /* 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;
+ yygotominor.yy322 = sqlite3ExprListAppend(pParse,0,yymsp[-1].minor.yy118.pExpr);
+ sqlite3ExprListSetSortOrder(yygotominor.yy322,yymsp[0].minor.yy4);
}
break;
- case 155: /* sortorder ::= ASC */
- case 157: /* sortorder ::= */ yytestcase(yyruleno==157);
-{yygotominor.yy392 = SQLITE_SO_ASC;}
+ case 159: /* sortorder ::= ASC */
+{yygotominor.yy4 = SQLITE_SO_ASC;}
+ break;
+ case 160: /* sortorder ::= DESC */
+{yygotominor.yy4 = SQLITE_SO_DESC;}
break;
- case 156: /* sortorder ::= DESC */
-{yygotominor.yy392 = SQLITE_SO_DESC;}
+ case 161: /* sortorder ::= */
+{yygotominor.yy4 = SQLITE_SO_UNDEFINED;}
break;
- case 162: /* limit_opt ::= */
-{yygotominor.yy64.pLimit = 0; yygotominor.yy64.pOffset = 0;}
+ case 166: /* limit_opt ::= */
+{yygotominor.yy292.pLimit = 0; yygotominor.yy292.pOffset = 0;}
break;
- case 163: /* limit_opt ::= LIMIT expr */
-{yygotominor.yy64.pLimit = yymsp[0].minor.yy342.pExpr; yygotominor.yy64.pOffset = 0;}
+ case 167: /* limit_opt ::= LIMIT expr */
+{yygotominor.yy292.pLimit = yymsp[0].minor.yy118.pExpr; yygotominor.yy292.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;}
+ case 168: /* limit_opt ::= LIMIT expr OFFSET expr */
+{yygotominor.yy292.pLimit = yymsp[-2].minor.yy118.pExpr; yygotominor.yy292.pOffset = yymsp[0].minor.yy118.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;}
+ case 169: /* limit_opt ::= LIMIT expr COMMA expr */
+{yygotominor.yy292.pOffset = yymsp[-2].minor.yy118.pExpr; yygotominor.yy292.pLimit = yymsp[0].minor.yy118.pExpr;}
break;
- case 166: /* cmd ::= DELETE FROM fullname indexed_opt where_opt */
+ case 170: /* cmd ::= with 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);
+ sqlite3WithPush(pParse, yymsp[-5].minor.yy451, 1);
+ sqlite3SrcListIndexedBy(pParse, yymsp[-2].minor.yy259, &yymsp[-1].minor.yy0);
+ sqlite3DeleteFrom(pParse,yymsp[-2].minor.yy259,yymsp[0].minor.yy314);
}
break;
- case 169: /* cmd ::= UPDATE orconf fullname indexed_opt SET setlist where_opt */
+ case 173: /* cmd ::= with 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);
+ sqlite3WithPush(pParse, yymsp[-7].minor.yy451, 1);
+ sqlite3SrcListIndexedBy(pParse, yymsp[-4].minor.yy259, &yymsp[-3].minor.yy0);
+ sqlite3ExprListCheckLength(pParse,yymsp[-1].minor.yy322,"set list");
+ sqlite3Update(pParse,yymsp[-4].minor.yy259,yymsp[-1].minor.yy322,yymsp[0].minor.yy314,yymsp[-5].minor.yy4);
}
break;
- case 170: /* setlist ::= setlist COMMA nm EQ expr */
+ case 174: /* 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);
+ yygotominor.yy322 = sqlite3ExprListAppend(pParse, yymsp[-4].minor.yy322, yymsp[0].minor.yy118.pExpr);
+ sqlite3ExprListSetName(pParse, yygotominor.yy322, &yymsp[-2].minor.yy0, 1);
}
break;
- case 171: /* setlist ::= nm EQ expr */
+ case 175: /* setlist ::= nm EQ expr */
{
- yygotominor.yy442 = sqlite3ExprListAppend(pParse, 0, yymsp[0].minor.yy342.pExpr);
- sqlite3ExprListSetName(pParse, yygotominor.yy442, &yymsp[-2].minor.yy0, 1);
+ yygotominor.yy322 = sqlite3ExprListAppend(pParse, 0, yymsp[0].minor.yy118.pExpr);
+ sqlite3ExprListSetName(pParse, yygotominor.yy322, &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 */
+ case 176: /* cmd ::= with insert_cmd INTO fullname idlist_opt select */
{
- yygotominor.yy487.pList = yymsp[-1].minor.yy442;
- yygotominor.yy487.pSelect = 0;
+ sqlite3WithPush(pParse, yymsp[-5].minor.yy451, 1);
+ sqlite3Insert(pParse, yymsp[-2].minor.yy259, yymsp[0].minor.yy387, yymsp[-1].minor.yy384, yymsp[-4].minor.yy4);
}
break;
- case 178: /* valuelist ::= valuelist COMMA LP exprlist RP */
+ case 177: /* cmd ::= with insert_cmd INTO fullname idlist_opt DEFAULT VALUES */
{
- 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;
- }
+ sqlite3WithPush(pParse, yymsp[-6].minor.yy451, 1);
+ sqlite3Insert(pParse, yymsp[-3].minor.yy259, 0, yymsp[-2].minor.yy384, yymsp[-5].minor.yy4);
}
break;
- case 181: /* inscollist ::= inscollist COMMA nm */
-{yygotominor.yy180 = sqlite3IdListAppend(pParse->db,yymsp[-2].minor.yy180,&yymsp[0].minor.yy0);}
+ case 182: /* idlist ::= idlist COMMA nm */
+{yygotominor.yy384 = sqlite3IdListAppend(pParse->db,yymsp[-2].minor.yy384,&yymsp[0].minor.yy0);}
break;
- case 182: /* inscollist ::= nm */
-{yygotominor.yy180 = sqlite3IdListAppend(pParse->db,0,&yymsp[0].minor.yy0);}
+ case 183: /* idlist ::= nm */
+{yygotominor.yy384 = sqlite3IdListAppend(pParse->db,0,&yymsp[0].minor.yy0);}
break;
- case 183: /* expr ::= term */
-{yygotominor.yy342 = yymsp[0].minor.yy342;}
+ case 184: /* expr ::= term */
+{yygotominor.yy118 = yymsp[0].minor.yy118;}
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);}
+ case 185: /* expr ::= LP expr RP */
+{yygotominor.yy118.pExpr = yymsp[-1].minor.yy118.pExpr; spanSet(&yygotominor.yy118,&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);}
+ case 186: /* term ::= NULL */
+ case 191: /* term ::= INTEGER|FLOAT|BLOB */ yytestcase(yyruleno==191);
+ case 192: /* term ::= STRING */ yytestcase(yyruleno==192);
+{spanExpr(&yygotominor.yy118, 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);}
+ case 187: /* expr ::= ID|INDEXED */
+ case 188: /* expr ::= JOIN_KW */ yytestcase(yyruleno==188);
+{spanExpr(&yygotominor.yy118, pParse, TK_ID, &yymsp[0].minor.yy0);}
break;
- case 188: /* expr ::= nm DOT nm */
+ case 189: /* 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);
+ yygotominor.yy118.pExpr = sqlite3PExpr(pParse, TK_DOT, temp1, temp2, 0);
+ spanSet(&yygotominor.yy118,&yymsp[-2].minor.yy0,&yymsp[0].minor.yy0);
}
break;
- case 189: /* expr ::= nm DOT nm DOT nm */
+ case 190: /* 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);
+ yygotominor.yy118.pExpr = sqlite3PExpr(pParse, TK_DOT, temp1, temp4, 0);
+ spanSet(&yygotominor.yy118,&yymsp[-4].minor.yy0,&yymsp[0].minor.yy0);
}
break;
- case 192: /* expr ::= REGISTER */
+ case 193: /* expr ::= VARIABLE */
{
- /* 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;
+ if( yymsp[0].minor.yy0.n>=2 && yymsp[0].minor.yy0.z[0]=='#' && sqlite3Isdigit(yymsp[0].minor.yy0.z[1]) ){
+ /* 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.yy118.pExpr = 0;
+ }else{
+ yygotominor.yy118.pExpr = sqlite3PExpr(pParse, TK_REGISTER, 0, 0, &yymsp[0].minor.yy0);
+ if( yygotominor.yy118.pExpr ) sqlite3GetInt32(&yymsp[0].minor.yy0.z[1], &yygotominor.yy118.pExpr->iTable);
+ }
}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);
+ spanExpr(&yygotominor.yy118, pParse, TK_VARIABLE, &yymsp[0].minor.yy0);
+ sqlite3ExprAssignVarNumber(pParse, yygotominor.yy118.pExpr);
}
- 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);
+ spanSet(&yygotominor.yy118, &yymsp[0].minor.yy0, &yymsp[0].minor.yy0);
}
break;
- case 194: /* expr ::= expr COLLATE ids */
+ case 194: /* expr ::= expr COLLATE ID|STRING */
{
- 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];
+ yygotominor.yy118.pExpr = sqlite3ExprAddCollateToken(pParse, yymsp[-2].minor.yy118.pExpr, &yymsp[0].minor.yy0, 1);
+ yygotominor.yy118.zStart = yymsp[-2].minor.yy118.zStart;
+ yygotominor.yy118.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);
+ yygotominor.yy118.pExpr = sqlite3PExpr(pParse, TK_CAST, yymsp[-3].minor.yy118.pExpr, 0, &yymsp[-1].minor.yy0);
+ spanSet(&yygotominor.yy118,&yymsp[-5].minor.yy0,&yymsp[0].minor.yy0);
}
break;
- case 196: /* expr ::= ID LP distinct exprlist RP */
+ case 196: /* expr ::= ID|INDEXED LP distinct exprlist RP */
{
- if( yymsp[-1].minor.yy442 && yymsp[-1].minor.yy442->nExpr>pParse->db->aLimit[SQLITE_LIMIT_FUNCTION_ARG] ){
+ if( yymsp[-1].minor.yy322 && yymsp[-1].minor.yy322->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;
+ yygotominor.yy118.pExpr = sqlite3ExprFunction(pParse, yymsp[-1].minor.yy322, &yymsp[-4].minor.yy0);
+ spanSet(&yygotominor.yy118,&yymsp[-4].minor.yy0,&yymsp[0].minor.yy0);
+ if( yymsp[-2].minor.yy4==SF_Distinct && yygotominor.yy118.pExpr ){
+ yygotominor.yy118.pExpr->flags |= EP_Distinct;
}
}
break;
- case 197: /* expr ::= ID LP STAR RP */
+ case 197: /* expr ::= ID|INDEXED LP STAR RP */
{
- yygotominor.yy342.pExpr = sqlite3ExprFunction(pParse, 0, &yymsp[-3].minor.yy0);
- spanSet(&yygotominor.yy342,&yymsp[-3].minor.yy0,&yymsp[0].minor.yy0);
+ yygotominor.yy118.pExpr = sqlite3ExprFunction(pParse, 0, &yymsp[-3].minor.yy0);
+ spanSet(&yygotominor.yy118,&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);
+ yygotominor.yy118.pExpr = sqlite3ExprFunction(pParse, 0, &yymsp[0].minor.yy0);
+ spanSet(&yygotominor.yy118, &yymsp[0].minor.yy0, &yymsp[0].minor.yy0);
}
break;
case 199: /* expr ::= expr AND expr */
@@ -110722,87 +130093,85 @@ static void yy_reduce(
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);}
+{spanBinaryExpr(&yygotominor.yy118,pParse,yymsp[-1].major,&yymsp[-2].minor.yy118,&yymsp[0].minor.yy118);}
break;
- case 207: /* likeop ::= LIKE_KW */
- case 209: /* likeop ::= MATCH */ yytestcase(yyruleno==209);
-{yygotominor.yy318.eOperator = yymsp[0].minor.yy0; yygotominor.yy318.bNot = 0;}
+ case 207: /* likeop ::= LIKE_KW|MATCH */
+{yygotominor.yy342.eOperator = yymsp[0].minor.yy0; yygotominor.yy342.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;}
+ case 208: /* likeop ::= NOT LIKE_KW|MATCH */
+{yygotominor.yy342.eOperator = yymsp[0].minor.yy0; yygotominor.yy342.bNot = 1;}
break;
- case 211: /* expr ::= expr likeop expr */
+ case 209: /* 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;
+ pList = sqlite3ExprListAppend(pParse,0, yymsp[0].minor.yy118.pExpr);
+ pList = sqlite3ExprListAppend(pParse,pList, yymsp[-2].minor.yy118.pExpr);
+ yygotominor.yy118.pExpr = sqlite3ExprFunction(pParse, pList, &yymsp[-1].minor.yy342.eOperator);
+ exprNot(pParse, yymsp[-1].minor.yy342.bNot, &yygotominor.yy118.pExpr);
+ yygotominor.yy118.zStart = yymsp[-2].minor.yy118.zStart;
+ yygotominor.yy118.zEnd = yymsp[0].minor.yy118.zEnd;
+ if( yygotominor.yy118.pExpr ) yygotominor.yy118.pExpr->flags |= EP_InfixFunc;
}
break;
- case 212: /* expr ::= expr likeop expr ESCAPE expr */
+ case 210: /* 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;
+ pList = sqlite3ExprListAppend(pParse,0, yymsp[-2].minor.yy118.pExpr);
+ pList = sqlite3ExprListAppend(pParse,pList, yymsp[-4].minor.yy118.pExpr);
+ pList = sqlite3ExprListAppend(pParse,pList, yymsp[0].minor.yy118.pExpr);
+ yygotominor.yy118.pExpr = sqlite3ExprFunction(pParse, pList, &yymsp[-3].minor.yy342.eOperator);
+ exprNot(pParse, yymsp[-3].minor.yy342.bNot, &yygotominor.yy118.pExpr);
+ yygotominor.yy118.zStart = yymsp[-4].minor.yy118.zStart;
+ yygotominor.yy118.zEnd = yymsp[0].minor.yy118.zEnd;
+ if( yygotominor.yy118.pExpr ) yygotominor.yy118.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);}
+ case 211: /* expr ::= expr ISNULL|NOTNULL */
+{spanUnaryPostfix(&yygotominor.yy118,pParse,yymsp[0].major,&yymsp[-1].minor.yy118,&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);}
+ case 212: /* expr ::= expr NOT NULL */
+{spanUnaryPostfix(&yygotominor.yy118,pParse,TK_NOTNULL,&yymsp[-2].minor.yy118,&yymsp[0].minor.yy0);}
break;
- case 215: /* expr ::= expr IS expr */
+ case 213: /* 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);
+ spanBinaryExpr(&yygotominor.yy118,pParse,TK_IS,&yymsp[-2].minor.yy118,&yymsp[0].minor.yy118);
+ binaryToUnaryIfNull(pParse, yymsp[0].minor.yy118.pExpr, yygotominor.yy118.pExpr, TK_ISNULL);
}
break;
- case 216: /* expr ::= expr IS NOT expr */
+ case 214: /* 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);
+ spanBinaryExpr(&yygotominor.yy118,pParse,TK_ISNOT,&yymsp[-3].minor.yy118,&yymsp[0].minor.yy118);
+ binaryToUnaryIfNull(pParse, yymsp[0].minor.yy118.pExpr, yygotominor.yy118.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);}
+ case 215: /* expr ::= NOT expr */
+ case 216: /* expr ::= BITNOT expr */ yytestcase(yyruleno==216);
+{spanUnaryPrefix(&yygotominor.yy118,pParse,yymsp[-1].major,&yymsp[0].minor.yy118,&yymsp[-1].minor.yy0);}
break;
- case 219: /* expr ::= MINUS expr */
-{spanUnaryPrefix(&yygotominor.yy342,pParse,TK_UMINUS,&yymsp[0].minor.yy342,&yymsp[-1].minor.yy0);}
+ case 217: /* expr ::= MINUS expr */
+{spanUnaryPrefix(&yygotominor.yy118,pParse,TK_UMINUS,&yymsp[0].minor.yy118,&yymsp[-1].minor.yy0);}
break;
- case 220: /* expr ::= PLUS expr */
-{spanUnaryPrefix(&yygotominor.yy342,pParse,TK_UPLUS,&yymsp[0].minor.yy342,&yymsp[-1].minor.yy0);}
+ case 218: /* expr ::= PLUS expr */
+{spanUnaryPrefix(&yygotominor.yy118,pParse,TK_UPLUS,&yymsp[0].minor.yy118,&yymsp[-1].minor.yy0);}
break;
- case 223: /* expr ::= expr between_op expr AND expr */
+ case 221: /* 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;
+ ExprList *pList = sqlite3ExprListAppend(pParse,0, yymsp[-2].minor.yy118.pExpr);
+ pList = sqlite3ExprListAppend(pParse,pList, yymsp[0].minor.yy118.pExpr);
+ yygotominor.yy118.pExpr = sqlite3PExpr(pParse, TK_BETWEEN, yymsp[-4].minor.yy118.pExpr, 0, 0);
+ if( yygotominor.yy118.pExpr ){
+ yygotominor.yy118.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;
+ exprNot(pParse, yymsp[-3].minor.yy4, &yygotominor.yy118.pExpr);
+ yygotominor.yy118.zStart = yymsp[-4].minor.yy118.zStart;
+ yygotominor.yy118.zEnd = yymsp[0].minor.yy118.zEnd;
}
break;
- case 226: /* expr ::= expr in_op LP exprlist RP */
+ case 224: /* expr ::= expr in_op LP exprlist RP */
{
- if( yymsp[-1].minor.yy442==0 ){
+ if( yymsp[-1].minor.yy322==0 ){
/* Expressions of the form
**
** expr1 IN ()
@@ -110811,224 +130180,241 @@ static void yy_reduce(
** 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);
+ yygotominor.yy118.pExpr = sqlite3PExpr(pParse, TK_INTEGER, 0, 0, &sqlite3IntTokens[yymsp[-3].minor.yy4]);
+ sqlite3ExprDelete(pParse->db, yymsp[-4].minor.yy118.pExpr);
+ }else if( yymsp[-1].minor.yy322->nExpr==1 ){
+ /* Expressions of the form:
+ **
+ ** expr1 IN (?1)
+ ** expr1 NOT IN (?2)
+ **
+ ** with exactly one value on the RHS can be simplified to something
+ ** like this:
+ **
+ ** expr1 == ?1
+ ** expr1 <> ?2
+ **
+ ** But, the RHS of the == or <> is marked with the EP_Generic flag
+ ** so that it may not contribute to the computation of comparison
+ ** affinity or the collating sequence to use for comparison. Otherwise,
+ ** the semantics would be subtly different from IN or NOT IN.
+ */
+ Expr *pRHS = yymsp[-1].minor.yy322->a[0].pExpr;
+ yymsp[-1].minor.yy322->a[0].pExpr = 0;
+ sqlite3ExprListDelete(pParse->db, yymsp[-1].minor.yy322);
+ /* pRHS cannot be NULL because a malloc error would have been detected
+ ** before now and control would have never reached this point */
+ if( ALWAYS(pRHS) ){
+ pRHS->flags &= ~EP_Collate;
+ pRHS->flags |= EP_Generic;
+ }
+ yygotominor.yy118.pExpr = sqlite3PExpr(pParse, yymsp[-3].minor.yy4 ? TK_NE : TK_EQ, yymsp[-4].minor.yy118.pExpr, pRHS, 0);
}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);
+ yygotominor.yy118.pExpr = sqlite3PExpr(pParse, TK_IN, yymsp[-4].minor.yy118.pExpr, 0, 0);
+ if( yygotominor.yy118.pExpr ){
+ yygotominor.yy118.pExpr->x.pList = yymsp[-1].minor.yy322;
+ sqlite3ExprSetHeightAndFlags(pParse, yygotominor.yy118.pExpr);
}else{
- sqlite3ExprListDelete(pParse->db, yymsp[-1].minor.yy442);
+ sqlite3ExprListDelete(pParse->db, yymsp[-1].minor.yy322);
}
- if( yymsp[-3].minor.yy392 ) yygotominor.yy342.pExpr = sqlite3PExpr(pParse, TK_NOT, yygotominor.yy342.pExpr, 0, 0);
+ exprNot(pParse, yymsp[-3].minor.yy4, &yygotominor.yy118.pExpr);
}
- yygotominor.yy342.zStart = yymsp[-4].minor.yy342.zStart;
- yygotominor.yy342.zEnd = &yymsp[0].minor.yy0.z[yymsp[0].minor.yy0.n];
+ yygotominor.yy118.zStart = yymsp[-4].minor.yy118.zStart;
+ yygotominor.yy118.zEnd = &yymsp[0].minor.yy0.z[yymsp[0].minor.yy0.n];
}
break;
- case 227: /* expr ::= LP select RP */
+ case 225: /* 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);
+ yygotominor.yy118.pExpr = sqlite3PExpr(pParse, TK_SELECT, 0, 0, 0);
+ if( yygotominor.yy118.pExpr ){
+ yygotominor.yy118.pExpr->x.pSelect = yymsp[-1].minor.yy387;
+ ExprSetProperty(yygotominor.yy118.pExpr, EP_xIsSelect|EP_Subquery);
+ sqlite3ExprSetHeightAndFlags(pParse, yygotominor.yy118.pExpr);
}else{
- sqlite3SelectDelete(pParse->db, yymsp[-1].minor.yy159);
+ sqlite3SelectDelete(pParse->db, yymsp[-1].minor.yy387);
}
- yygotominor.yy342.zStart = yymsp[-2].minor.yy0.z;
- yygotominor.yy342.zEnd = &yymsp[0].minor.yy0.z[yymsp[0].minor.yy0.n];
+ yygotominor.yy118.zStart = yymsp[-2].minor.yy0.z;
+ yygotominor.yy118.zEnd = &yymsp[0].minor.yy0.z[yymsp[0].minor.yy0.n];
}
break;
- case 228: /* expr ::= expr in_op LP select RP */
+ case 226: /* 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);
+ yygotominor.yy118.pExpr = sqlite3PExpr(pParse, TK_IN, yymsp[-4].minor.yy118.pExpr, 0, 0);
+ if( yygotominor.yy118.pExpr ){
+ yygotominor.yy118.pExpr->x.pSelect = yymsp[-1].minor.yy387;
+ ExprSetProperty(yygotominor.yy118.pExpr, EP_xIsSelect|EP_Subquery);
+ sqlite3ExprSetHeightAndFlags(pParse, yygotominor.yy118.pExpr);
}else{
- sqlite3SelectDelete(pParse->db, yymsp[-1].minor.yy159);
+ sqlite3SelectDelete(pParse->db, yymsp[-1].minor.yy387);
}
- 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];
+ exprNot(pParse, yymsp[-3].minor.yy4, &yygotominor.yy118.pExpr);
+ yygotominor.yy118.zStart = yymsp[-4].minor.yy118.zStart;
+ yygotominor.yy118.zEnd = &yymsp[0].minor.yy0.z[yymsp[0].minor.yy0.n];
}
break;
- case 229: /* expr ::= expr in_op nm dbnm */
+ case 227: /* 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);
+ yygotominor.yy118.pExpr = sqlite3PExpr(pParse, TK_IN, yymsp[-3].minor.yy118.pExpr, 0, 0);
+ if( yygotominor.yy118.pExpr ){
+ yygotominor.yy118.pExpr->x.pSelect = sqlite3SelectNew(pParse, 0,pSrc,0,0,0,0,0,0,0);
+ ExprSetProperty(yygotominor.yy118.pExpr, EP_xIsSelect|EP_Subquery);
+ sqlite3ExprSetHeightAndFlags(pParse, yygotominor.yy118.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];
+ exprNot(pParse, yymsp[-2].minor.yy4, &yygotominor.yy118.pExpr);
+ yygotominor.yy118.zStart = yymsp[-3].minor.yy118.zStart;
+ yygotominor.yy118.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 */
+ case 228: /* expr ::= EXISTS LP select RP */
{
- Expr *p = yygotominor.yy342.pExpr = sqlite3PExpr(pParse, TK_EXISTS, 0, 0, 0);
+ Expr *p = yygotominor.yy118.pExpr = sqlite3PExpr(pParse, TK_EXISTS, 0, 0, 0);
if( p ){
- p->x.pSelect = yymsp[-1].minor.yy159;
- ExprSetProperty(p, EP_xIsSelect);
- sqlite3ExprSetHeight(pParse, p);
+ p->x.pSelect = yymsp[-1].minor.yy387;
+ ExprSetProperty(p, EP_xIsSelect|EP_Subquery);
+ sqlite3ExprSetHeightAndFlags(pParse, p);
}else{
- sqlite3SelectDelete(pParse->db, yymsp[-1].minor.yy159);
+ sqlite3SelectDelete(pParse->db, yymsp[-1].minor.yy387);
}
- yygotominor.yy342.zStart = yymsp[-3].minor.yy0.z;
- yygotominor.yy342.zEnd = &yymsp[0].minor.yy0.z[yymsp[0].minor.yy0.n];
+ yygotominor.yy118.zStart = yymsp[-3].minor.yy0.z;
+ yygotominor.yy118.zEnd = &yymsp[0].minor.yy0.z[yymsp[0].minor.yy0.n];
}
break;
- case 231: /* expr ::= CASE case_operand case_exprlist case_else END */
+ case 229: /* 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);
+ yygotominor.yy118.pExpr = sqlite3PExpr(pParse, TK_CASE, yymsp[-3].minor.yy314, 0, 0);
+ if( yygotominor.yy118.pExpr ){
+ yygotominor.yy118.pExpr->x.pList = yymsp[-1].minor.yy314 ? sqlite3ExprListAppend(pParse,yymsp[-2].minor.yy322,yymsp[-1].minor.yy314) : yymsp[-2].minor.yy322;
+ sqlite3ExprSetHeightAndFlags(pParse, yygotominor.yy118.pExpr);
}else{
- sqlite3ExprListDelete(pParse->db, yymsp[-2].minor.yy442);
+ sqlite3ExprListDelete(pParse->db, yymsp[-2].minor.yy322);
+ sqlite3ExprDelete(pParse->db, yymsp[-1].minor.yy314);
}
- yygotominor.yy342.zStart = yymsp[-4].minor.yy0.z;
- yygotominor.yy342.zEnd = &yymsp[0].minor.yy0.z[yymsp[0].minor.yy0.n];
+ yygotominor.yy118.zStart = yymsp[-4].minor.yy0.z;
+ yygotominor.yy118.zEnd = &yymsp[0].minor.yy0.z[yymsp[0].minor.yy0.n];
}
break;
- case 232: /* case_exprlist ::= case_exprlist WHEN expr THEN expr */
+ case 230: /* 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);
+ yygotominor.yy322 = sqlite3ExprListAppend(pParse,yymsp[-4].minor.yy322, yymsp[-2].minor.yy118.pExpr);
+ yygotominor.yy322 = sqlite3ExprListAppend(pParse,yygotominor.yy322, yymsp[0].minor.yy118.pExpr);
}
break;
- case 233: /* case_exprlist ::= WHEN expr THEN expr */
+ case 231: /* 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);
+ yygotominor.yy322 = sqlite3ExprListAppend(pParse,0, yymsp[-2].minor.yy118.pExpr);
+ yygotominor.yy322 = sqlite3ExprListAppend(pParse,yygotominor.yy322, yymsp[0].minor.yy118.pExpr);
}
break;
- case 240: /* nexprlist ::= nexprlist COMMA expr */
-{yygotominor.yy442 = sqlite3ExprListAppend(pParse,yymsp[-2].minor.yy442,yymsp[0].minor.yy342.pExpr);}
+ case 238: /* nexprlist ::= nexprlist COMMA expr */
+{yygotominor.yy322 = sqlite3ExprListAppend(pParse,yymsp[-2].minor.yy322,yymsp[0].minor.yy118.pExpr);}
break;
- case 241: /* nexprlist ::= expr */
-{yygotominor.yy442 = sqlite3ExprListAppend(pParse,0,yymsp[0].minor.yy342.pExpr);}
+ case 239: /* nexprlist ::= expr */
+{yygotominor.yy322 = sqlite3ExprListAppend(pParse,0,yymsp[0].minor.yy118.pExpr);}
break;
- case 242: /* cmd ::= createkw uniqueflag INDEX ifnotexists nm dbnm ON nm LP idxlist RP */
+ case 240: /* cmd ::= createkw uniqueflag INDEX ifnotexists nm dbnm ON nm LP sortlist RP where_opt */
{
- 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);
+ sqlite3CreateIndex(pParse, &yymsp[-7].minor.yy0, &yymsp[-6].minor.yy0,
+ sqlite3SrcListAppend(pParse->db,0,&yymsp[-4].minor.yy0,0), yymsp[-2].minor.yy322, yymsp[-10].minor.yy4,
+ &yymsp[-11].minor.yy0, yymsp[0].minor.yy314, SQLITE_SO_ASC, yymsp[-8].minor.yy4);
}
break;
- case 243: /* uniqueflag ::= UNIQUE */
- case 296: /* raisetype ::= ABORT */ yytestcase(yyruleno==296);
-{yygotominor.yy392 = OE_Abort;}
+ case 241: /* uniqueflag ::= UNIQUE */
+ case 292: /* raisetype ::= ABORT */ yytestcase(yyruleno==292);
+{yygotominor.yy4 = OE_Abort;}
break;
- case 244: /* uniqueflag ::= */
-{yygotominor.yy392 = OE_None;}
+ case 242: /* uniqueflag ::= */
+{yygotominor.yy4 = OE_None;}
break;
- case 247: /* idxlist ::= idxlist COMMA nm collate sortorder */
+ case 245: /* eidlist ::= eidlist 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;
+ yygotominor.yy322 = parserAddExprIdListTerm(pParse, yymsp[-4].minor.yy322, &yymsp[-2].minor.yy0, yymsp[-1].minor.yy4, yymsp[0].minor.yy4);
}
break;
- case 248: /* idxlist ::= nm collate sortorder */
+ case 246: /* eidlist ::= 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;
+ yygotominor.yy322 = parserAddExprIdListTerm(pParse, 0, &yymsp[-2].minor.yy0, yymsp[-1].minor.yy4, yymsp[0].minor.yy4);
}
break;
- case 249: /* collate ::= */
-{yygotominor.yy0.z = 0; yygotominor.yy0.n = 0;}
+ case 249: /* cmd ::= DROP INDEX ifexists fullname */
+{sqlite3DropIndex(pParse, yymsp[0].minor.yy259, yymsp[-1].minor.yy4);}
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);
+ case 250: /* cmd ::= VACUUM */
+ case 251: /* cmd ::= VACUUM nm */ yytestcase(yyruleno==251);
{sqlite3Vacuum(pParse);}
break;
- case 254: /* cmd ::= PRAGMA nm dbnm */
+ case 252: /* 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 */
+ case 253: /* 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 */
+ case 254: /* 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 */
+ case 255: /* 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 */
+ case 256: /* 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 */
+ case 265: /* 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);
+ sqlite3FinishTrigger(pParse, yymsp[-1].minor.yy203, &all);
}
break;
- case 269: /* trigger_decl ::= temp TRIGGER ifnotexists nm dbnm trigger_time trigger_event ON fullname foreach_clause when_clause */
+ case 266: /* 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);
+ sqlite3BeginTrigger(pParse, &yymsp[-7].minor.yy0, &yymsp[-6].minor.yy0, yymsp[-5].minor.yy4, yymsp[-4].minor.yy90.a, yymsp[-4].minor.yy90.b, yymsp[-2].minor.yy259, yymsp[0].minor.yy314, yymsp[-10].minor.yy4, yymsp[-8].minor.yy4);
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; }
+ case 267: /* trigger_time ::= BEFORE */
+ case 270: /* trigger_time ::= */ yytestcase(yyruleno==270);
+{ yygotominor.yy4 = TK_BEFORE; }
break;
- case 271: /* trigger_time ::= AFTER */
-{ yygotominor.yy392 = TK_AFTER; }
+ case 268: /* trigger_time ::= AFTER */
+{ yygotominor.yy4 = TK_AFTER; }
break;
- case 272: /* trigger_time ::= INSTEAD OF */
-{ yygotominor.yy392 = TK_INSTEAD;}
+ case 269: /* trigger_time ::= INSTEAD OF */
+{ yygotominor.yy4 = 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;}
+ case 271: /* trigger_event ::= DELETE|INSERT */
+ case 272: /* trigger_event ::= UPDATE */ yytestcase(yyruleno==272);
+{yygotominor.yy90.a = yymsp[0].major; yygotominor.yy90.b = 0;}
break;
- case 276: /* trigger_event ::= UPDATE OF inscollist */
-{yygotominor.yy410.a = TK_UPDATE; yygotominor.yy410.b = yymsp[0].minor.yy180;}
+ case 273: /* trigger_event ::= UPDATE OF idlist */
+{yygotominor.yy90.a = TK_UPDATE; yygotominor.yy90.b = yymsp[0].minor.yy384;}
break;
- case 279: /* when_clause ::= */
- case 301: /* key_opt ::= */ yytestcase(yyruleno==301);
-{ yygotominor.yy122 = 0; }
+ case 276: /* when_clause ::= */
+ case 297: /* key_opt ::= */ yytestcase(yyruleno==297);
+{ yygotominor.yy314 = 0; }
break;
- case 280: /* when_clause ::= WHEN expr */
- case 302: /* key_opt ::= KEY expr */ yytestcase(yyruleno==302);
-{ yygotominor.yy122 = yymsp[0].minor.yy342.pExpr; }
+ case 277: /* when_clause ::= WHEN expr */
+ case 298: /* key_opt ::= KEY expr */ yytestcase(yyruleno==298);
+{ yygotominor.yy314 = yymsp[0].minor.yy118.pExpr; }
break;
- case 281: /* trigger_cmd_list ::= trigger_cmd_list trigger_cmd SEMI */
+ case 278: /* 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;
+ assert( yymsp[-2].minor.yy203!=0 );
+ yymsp[-2].minor.yy203->pLast->pNext = yymsp[-1].minor.yy203;
+ yymsp[-2].minor.yy203->pLast = yymsp[-1].minor.yy203;
+ yygotominor.yy203 = yymsp[-2].minor.yy203;
}
break;
- case 282: /* trigger_cmd_list ::= trigger_cmd SEMI */
+ case 279: /* 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;
+ assert( yymsp[-1].minor.yy203!=0 );
+ yymsp[-1].minor.yy203->pLast = yymsp[-1].minor.yy203;
+ yygotominor.yy203 = yymsp[-1].minor.yy203;
}
break;
- case 284: /* trnm ::= nm DOT nm */
+ case 281: /* trnm ::= nm DOT nm */
{
yygotominor.yy0 = yymsp[0].minor.yy0;
sqlite3ErrorMsg(pParse,
@@ -111036,123 +130422,137 @@ static void yy_reduce(
"statements within triggers");
}
break;
- case 286: /* tridxby ::= INDEXED BY nm */
+ case 283: /* 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 */
+ case 284: /* 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);}
+ case 285: /* trigger_cmd ::= UPDATE orconf trnm tridxby SET setlist where_opt */
+{ yygotominor.yy203 = sqlite3TriggerUpdateStep(pParse->db, &yymsp[-4].minor.yy0, yymsp[-1].minor.yy322, yymsp[0].minor.yy314, yymsp[-5].minor.yy4); }
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);}
+ case 286: /* trigger_cmd ::= insert_cmd INTO trnm idlist_opt select */
+{yygotominor.yy203 = sqlite3TriggerInsertStep(pParse->db, &yymsp[-2].minor.yy0, yymsp[-1].minor.yy384, yymsp[0].minor.yy387, yymsp[-4].minor.yy4);}
break;
- case 291: /* trigger_cmd ::= DELETE FROM trnm tridxby where_opt */
-{yygotominor.yy327 = sqlite3TriggerDeleteStep(pParse->db, &yymsp[-2].minor.yy0, yymsp[0].minor.yy122);}
+ case 287: /* trigger_cmd ::= DELETE FROM trnm tridxby where_opt */
+{yygotominor.yy203 = sqlite3TriggerDeleteStep(pParse->db, &yymsp[-2].minor.yy0, yymsp[0].minor.yy314);}
break;
- case 292: /* trigger_cmd ::= select */
-{yygotominor.yy327 = sqlite3TriggerSelectStep(pParse->db, yymsp[0].minor.yy159); }
+ case 288: /* trigger_cmd ::= select */
+{yygotominor.yy203 = sqlite3TriggerSelectStep(pParse->db, yymsp[0].minor.yy387); }
break;
- case 293: /* expr ::= RAISE LP IGNORE RP */
+ case 289: /* 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.yy118.pExpr = sqlite3PExpr(pParse, TK_RAISE, 0, 0, 0);
+ if( yygotominor.yy118.pExpr ){
+ yygotominor.yy118.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];
+ yygotominor.yy118.zStart = yymsp[-3].minor.yy0.z;
+ yygotominor.yy118.zEnd = &yymsp[0].minor.yy0.z[yymsp[0].minor.yy0.n];
}
break;
- case 294: /* expr ::= RAISE LP raisetype COMMA nm RP */
+ case 290: /* 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.yy118.pExpr = sqlite3PExpr(pParse, TK_RAISE, 0, 0, &yymsp[-1].minor.yy0);
+ if( yygotominor.yy118.pExpr ) {
+ yygotominor.yy118.pExpr->affinity = (char)yymsp[-3].minor.yy4;
}
- yygotominor.yy342.zStart = yymsp[-5].minor.yy0.z;
- yygotominor.yy342.zEnd = &yymsp[0].minor.yy0.z[yymsp[0].minor.yy0.n];
+ yygotominor.yy118.zStart = yymsp[-5].minor.yy0.z;
+ yygotominor.yy118.zEnd = &yymsp[0].minor.yy0.z[yymsp[0].minor.yy0.n];
}
break;
- case 295: /* raisetype ::= ROLLBACK */
-{yygotominor.yy392 = OE_Rollback;}
+ case 291: /* raisetype ::= ROLLBACK */
+{yygotominor.yy4 = OE_Rollback;}
break;
- case 297: /* raisetype ::= FAIL */
-{yygotominor.yy392 = OE_Fail;}
+ case 293: /* raisetype ::= FAIL */
+{yygotominor.yy4 = OE_Fail;}
break;
- case 298: /* cmd ::= DROP TRIGGER ifexists fullname */
+ case 294: /* cmd ::= DROP TRIGGER ifexists fullname */
{
- sqlite3DropTrigger(pParse,yymsp[0].minor.yy347,yymsp[-1].minor.yy392);
+ sqlite3DropTrigger(pParse,yymsp[0].minor.yy259,yymsp[-1].minor.yy4);
}
break;
- case 299: /* cmd ::= ATTACH database_kw_opt expr AS expr key_opt */
+ case 295: /* 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);
+ sqlite3Attach(pParse, yymsp[-3].minor.yy118.pExpr, yymsp[-1].minor.yy118.pExpr, yymsp[0].minor.yy314);
}
break;
- case 300: /* cmd ::= DETACH database_kw_opt expr */
+ case 296: /* cmd ::= DETACH database_kw_opt expr */
{
- sqlite3Detach(pParse, yymsp[0].minor.yy342.pExpr);
+ sqlite3Detach(pParse, yymsp[0].minor.yy118.pExpr);
}
break;
- case 305: /* cmd ::= REINDEX */
+ case 301: /* cmd ::= REINDEX */
{sqlite3Reindex(pParse, 0, 0);}
break;
- case 306: /* cmd ::= REINDEX nm dbnm */
+ case 302: /* cmd ::= REINDEX nm dbnm */
{sqlite3Reindex(pParse, &yymsp[-1].minor.yy0, &yymsp[0].minor.yy0);}
break;
- case 307: /* cmd ::= ANALYZE */
+ case 303: /* cmd ::= ANALYZE */
{sqlite3Analyze(pParse, 0, 0);}
break;
- case 308: /* cmd ::= ANALYZE nm dbnm */
+ case 304: /* cmd ::= ANALYZE nm dbnm */
{sqlite3Analyze(pParse, &yymsp[-1].minor.yy0, &yymsp[0].minor.yy0);}
break;
- case 309: /* cmd ::= ALTER TABLE fullname RENAME TO nm */
+ case 305: /* cmd ::= ALTER TABLE fullname RENAME TO nm */
{
- sqlite3AlterRenameTable(pParse,yymsp[-3].minor.yy347,&yymsp[0].minor.yy0);
+ sqlite3AlterRenameTable(pParse,yymsp[-3].minor.yy259,&yymsp[0].minor.yy0);
}
break;
- case 310: /* cmd ::= ALTER TABLE add_column_fullname ADD kwcolumn_opt column */
+ case 306: /* cmd ::= ALTER TABLE add_column_fullname ADD kwcolumn_opt column */
{
sqlite3AlterFinishAddColumn(pParse, &yymsp[0].minor.yy0);
}
break;
- case 311: /* add_column_fullname ::= fullname */
+ case 307: /* add_column_fullname ::= fullname */
{
pParse->db->lookaside.bEnabled = 0;
- sqlite3AlterBeginAddColumn(pParse, yymsp[0].minor.yy347);
+ sqlite3AlterBeginAddColumn(pParse, yymsp[0].minor.yy259);
}
break;
- case 314: /* cmd ::= create_vtab */
+ case 310: /* cmd ::= create_vtab */
{sqlite3VtabFinishParse(pParse,0);}
break;
- case 315: /* cmd ::= create_vtab LP vtabarglist RP */
+ case 311: /* 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 */
+ case 312: /* 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);
+ sqlite3VtabBeginParse(pParse, &yymsp[-3].minor.yy0, &yymsp[-2].minor.yy0, &yymsp[0].minor.yy0, yymsp[-4].minor.yy4);
}
break;
- case 319: /* vtabarg ::= */
+ case 315: /* vtabarg ::= */
{sqlite3VtabArgInit(pParse);}
break;
- case 321: /* vtabargtoken ::= ANY */
- case 322: /* vtabargtoken ::= lp anylist RP */ yytestcase(yyruleno==322);
- case 323: /* lp ::= LP */ yytestcase(yyruleno==323);
+ case 317: /* vtabargtoken ::= ANY */
+ case 318: /* vtabargtoken ::= lp anylist RP */ yytestcase(yyruleno==318);
+ case 319: /* lp ::= LP */ yytestcase(yyruleno==319);
{sqlite3VtabArgExtend(pParse,&yymsp[0].minor.yy0);}
break;
+ case 323: /* with ::= */
+{yygotominor.yy451 = 0;}
+ break;
+ case 324: /* with ::= WITH wqlist */
+ case 325: /* with ::= WITH RECURSIVE wqlist */ yytestcase(yyruleno==325);
+{ yygotominor.yy451 = yymsp[0].minor.yy451; }
+ break;
+ case 326: /* wqlist ::= nm eidlist_opt AS LP select RP */
+{
+ yygotominor.yy451 = sqlite3WithAdd(pParse, 0, &yymsp[-5].minor.yy0, yymsp[-4].minor.yy322, yymsp[-1].minor.yy387);
+}
+ break;
+ case 327: /* wqlist ::= wqlist COMMA nm eidlist_opt AS LP select RP */
+{
+ yygotominor.yy451 = sqlite3WithAdd(pParse, yymsp[-7].minor.yy451, &yymsp[-5].minor.yy0, yymsp[-4].minor.yy322, yymsp[-1].minor.yy387);
+}
+ break;
default:
/* (0) input ::= cmdlist */ yytestcase(yyruleno==0);
/* (1) cmdlist ::= cmdlist ecmd */ yytestcase(yyruleno==1);
@@ -111165,40 +130565,41 @@ static void yy_reduce(
/* (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);
+ /* (36) columnlist ::= columnlist COMMA column */ yytestcase(yyruleno==36);
+ /* (37) columnlist ::= column */ yytestcase(yyruleno==37);
+ /* (43) type ::= */ yytestcase(yyruleno==43);
+ /* (50) signed ::= plus_num */ yytestcase(yyruleno==50);
+ /* (51) signed ::= minus_num */ yytestcase(yyruleno==51);
+ /* (52) carglist ::= carglist ccons */ yytestcase(yyruleno==52);
+ /* (53) carglist ::= */ yytestcase(yyruleno==53);
+ /* (60) ccons ::= NULL onconf */ yytestcase(yyruleno==60);
+ /* (88) conslist ::= conslist tconscomma tcons */ yytestcase(yyruleno==88);
+ /* (89) conslist ::= tcons */ yytestcase(yyruleno==89);
+ /* (91) tconscomma ::= */ yytestcase(yyruleno==91);
+ /* (274) foreach_clause ::= */ yytestcase(yyruleno==274);
+ /* (275) foreach_clause ::= FOR EACH ROW */ yytestcase(yyruleno==275);
+ /* (282) tridxby ::= */ yytestcase(yyruleno==282);
+ /* (299) database_kw_opt ::= DATABASE */ yytestcase(yyruleno==299);
+ /* (300) database_kw_opt ::= */ yytestcase(yyruleno==300);
+ /* (308) kwcolumn_opt ::= */ yytestcase(yyruleno==308);
+ /* (309) kwcolumn_opt ::= COLUMNKW */ yytestcase(yyruleno==309);
+ /* (313) vtabarglist ::= vtabarg */ yytestcase(yyruleno==313);
+ /* (314) vtabarglist ::= vtabarglist COMMA vtabarg */ yytestcase(yyruleno==314);
+ /* (316) vtabarg ::= vtabarg vtabargtoken */ yytestcase(yyruleno==316);
+ /* (320) anylist ::= */ yytestcase(yyruleno==320);
+ /* (321) anylist ::= anylist LP anylist RP */ yytestcase(yyruleno==321);
+ /* (322) anylist ::= anylist ANY */ yytestcase(yyruleno==322);
break;
+/********** End reduce actions ************************************************/
};
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
+ if( yyact <= YY_MAX_SHIFTREDUCE ){
+ if( yyact>YY_MAX_SHIFT ) yyact += YY_MIN_REDUCE - YY_MIN_SHIFTREDUCE;
+ /* If 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. */
@@ -111208,13 +130609,12 @@ static void yy_reduce(
yymsp->stateno = (YYACTIONTYPE)yyact;
yymsp->major = (YYCODETYPE)yygoto;
yymsp->minor = yygotominor;
- }else
-#endif
- {
+ yyTraceShift(yypParser, yyact);
+ }else{
yy_shift(yypParser,yyact,yygoto,&yygotominor);
}
}else{
- assert( yyact == YYNSTATE + YYNRULE + 1 );
+ assert( yyact == YY_ACCEPT_ACTION );
yy_accept(yypParser);
}
}
@@ -111235,6 +130635,8 @@ static void yy_parse_failed(
while( yypParser->yyidx>=0 ) yy_pop_parser_stack(yypParser);
/* Here code is inserted which will be executed whenever the
** parser fails */
+/************ Begin %parse_failure code ***************************************/
+/************ End %parse_failure code *****************************************/
sqlite3ParserARG_STORE; /* Suppress warning about unused %extra_argument variable */
}
#endif /* YYNOERRORRECOVERY */
@@ -111249,10 +130651,12 @@ static void yy_syntax_error(
){
sqlite3ParserARG_FETCH;
#define TOKEN (yyminor.yy0)
+/************ Begin %syntax_error code ****************************************/
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);
+/************ End %syntax_error code ******************************************/
sqlite3ParserARG_STORE; /* Suppress warning about unused %extra_argument variable */
}
@@ -111271,6 +130675,8 @@ static void yy_accept(
while( yypParser->yyidx>=0 ) yy_pop_parser_stack(yypParser);
/* Here code is inserted which will be executed whenever the
** parser accepts */
+/*********** Begin %parse_accept code *****************************************/
+/*********** End %parse_accept code *******************************************/
sqlite3ParserARG_STORE; /* Suppress warning about unused %extra_argument variable */
}
@@ -111324,6 +130730,12 @@ SQLITE_PRIVATE void sqlite3Parser(
yypParser->yyerrcnt = -1;
yypParser->yystack[0].stateno = 0;
yypParser->yystack[0].major = 0;
+#ifndef NDEBUG
+ if( yyTraceFILE ){
+ fprintf(yyTraceFILE,"%sInitialize. Empty stack. State 0\n",
+ yyTracePrompt);
+ }
+#endif
}
yyminorunion.yy0 = yyminor;
#if !defined(YYERRORSYMBOL) && !defined(YYNOERRORRECOVERY)
@@ -111333,18 +130745,19 @@ SQLITE_PRIVATE void sqlite3Parser(
#ifndef NDEBUG
if( yyTraceFILE ){
- fprintf(yyTraceFILE,"%sInput %s\n",yyTracePrompt,yyTokenName[yymajor]);
+ fprintf(yyTraceFILE,"%sInput '%s'\n",yyTracePrompt,yyTokenName[yymajor]);
}
#endif
do{
yyact = yy_find_shift_action(yypParser,(YYCODETYPE)yymajor);
- if( yyact<YYNSTATE ){
+ if( yyact <= YY_MAX_SHIFTREDUCE ){
+ if( yyact > YY_MAX_SHIFT ) yyact += YY_MIN_REDUCE - YY_MIN_SHIFTREDUCE;
yy_shift(yypParser,yyact,yymajor,&yyminorunion);
yypParser->yyerrcnt--;
yymajor = YYNOCODE;
- }else if( yyact < YYNSTATE + YYNRULE ){
- yy_reduce(yypParser,yyact-YYNSTATE);
+ }else if( yyact <= YY_MAX_REDUCE ){
+ yy_reduce(yypParser,yyact-YY_MIN_REDUCE);
}else{
assert( yyact == YY_ERROR_ACTION );
#ifdef YYERRORSYMBOL
@@ -111394,7 +130807,7 @@ SQLITE_PRIVATE void sqlite3Parser(
yymx != YYERRORSYMBOL &&
(yyact = yy_find_reduce_action(
yypParser->yystack[yypParser->yyidx].stateno,
- YYERRORSYMBOL)) >= YYNSTATE
+ YYERRORSYMBOL)) >= YY_MIN_REDUCE
){
yy_pop_parser_stack(yypParser);
}
@@ -111444,6 +130857,16 @@ SQLITE_PRIVATE void sqlite3Parser(
#endif
}
}while( yymajor!=YYNOCODE && yypParser->yyidx>=0 );
+#ifndef NDEBUG
+ if( yyTraceFILE ){
+ int i;
+ fprintf(yyTraceFILE,"%sReturn. Stack=",yyTracePrompt);
+ for(i=1; i<=yypParser->yyidx; i++)
+ fprintf(yyTraceFILE,"%c%s", i==1 ? '[' : ' ',
+ yyTokenName[yypParser->yystack[i].major]);
+ fprintf(yyTraceFILE,"]\n");
+ }
+#endif
return;
}
@@ -111466,6 +130889,7 @@ SQLITE_PRIVATE void sqlite3Parser(
** individual tokens and sends those tokens one-by-one over to the
** parser for analysis.
*/
+/* #include "sqliteInt.h" */
/* #include <stdlib.h> */
/*
@@ -111527,20 +130951,20 @@ const unsigned char ebcdicToAscii[] = {
** 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 */
+/* Hash score: 182 */
+static int keywordCode(const char *z, int n, int *pType){
+ /* zText[] encodes 834 bytes of keywords in 554 bytes */
/* REINDEXEDESCAPEACHECKEYBEFOREIGNOREGEXPLAINSTEADDATABASELECT */
/* ABLEFTHENDEFERRABLELSEXCEPTRANSACTIONATURALTERAISEXCLUSIVE */
/* XISTSAVEPOINTERSECTRIGGEREFERENCESCONSTRAINTOFFSETEMPORARY */
- /* UNIQUERYATTACHAVINGROUPDATEBEGINNERELEASEBETWEENOTNULLIKE */
- /* CASCADELETECASECOLLATECREATECURRENT_DATEDETACHIMMEDIATEJOIN */
- /* SERTMATCHPLANALYZEPRAGMABORTVALUESVIRTUALIMITWHENWHERENAME */
- /* AFTEREPLACEANDEFAULTAUTOINCREMENTCASTCOLUMNCOMMITCONFLICTCROSS */
- /* CURRENT_TIMESTAMPRIMARYDEFERREDISTINCTDROPFAILFROMFULLGLOBYIF */
- /* ISNULLORDERESTRICTOUTERIGHTROLLBACKROWUNIONUSINGVACUUMVIEW */
- /* INITIALLY */
- static const char zText[540] = {
+ /* UNIQUERYWITHOUTERELEASEATTACHAVINGROUPDATEBEGINNERECURSIVE */
+ /* BETWEENOTNULLIKECASCADELETECASECOLLATECREATECURRENT_DATEDETACH */
+ /* IMMEDIATEJOINSERTMATCHPLANALYZEPRAGMABORTVALUESVIRTUALIMITWHEN */
+ /* WHERENAMEAFTEREPLACEANDEFAULTAUTOINCREMENTCASTCOLUMNCOMMIT */
+ /* CONFLICTCROSSCURRENT_TIMESTAMPRIMARYDEFERREDISTINCTDROPFAIL */
+ /* FROMFULLGLOBYIFISNULLORDERESTRICTRIGHTROLLBACKROWUNIONUSING */
+ /* VACUUMVIEWINITIALLY */
+ static const char zText[553] = {
'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',
@@ -111551,76 +130975,77 @@ static int keywordCode(const char *z, int n){
'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',
+ 'U','E','R','Y','W','I','T','H','O','U','T','E','R','E','L','E','A','S',
+ 'E','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','C','U','R','S','I','V','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','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,
+ 76, 105, 117, 74, 0, 45, 0, 0, 82, 0, 77, 0, 0,
+ 42, 12, 78, 15, 0, 116, 85, 54, 112, 0, 19, 0, 0,
+ 121, 0, 119, 115, 0, 22, 93, 0, 9, 0, 0, 70, 71,
+ 0, 69, 6, 0, 48, 90, 102, 0, 118, 101, 0, 0, 44,
+ 0, 103, 24, 0, 17, 0, 122, 53, 23, 0, 5, 110, 25,
+ 96, 0, 0, 124, 106, 60, 123, 57, 28, 55, 0, 91, 0,
+ 100, 26, 0, 99, 0, 0, 0, 95, 92, 97, 88, 109, 14,
+ 39, 108, 0, 81, 0, 18, 89, 111, 32, 0, 120, 80, 113,
+ 62, 46, 84, 0, 0, 94, 40, 59, 114, 0, 36, 0, 0,
+ 29, 0, 86, 63, 64, 0, 20, 61, 0, 56,
};
- static const unsigned char aNext[121] = {
+ static const unsigned char aNext[124] = {
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,
+ 0, 0, 0, 0, 33, 0, 21, 0, 0, 0, 0, 0, 50,
+ 0, 43, 3, 47, 0, 0, 0, 0, 30, 0, 58, 0, 38,
+ 0, 0, 0, 1, 66, 0, 0, 67, 0, 41, 0, 0, 0,
+ 0, 0, 0, 49, 65, 0, 0, 0, 0, 31, 52, 16, 34,
+ 10, 0, 0, 0, 0, 0, 0, 0, 11, 72, 79, 0, 8,
+ 0, 104, 98, 0, 107, 0, 87, 0, 75, 51, 0, 27, 37,
+ 73, 83, 0, 35, 68, 0, 0,
};
- static const unsigned char aLen[121] = {
+ static const unsigned char aLen[124] = {
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,
+ 4, 6, 2, 3, 9, 4, 2, 6, 5, 7, 4, 5, 7,
+ 6, 6, 5, 6, 5, 5, 9, 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, 8,
+ 3, 5, 5, 6, 4, 9, 3,
};
- static const unsigned short int aOffset[121] = {
+ static const unsigned short int aOffset[124] = {
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,
+ 159, 162, 162, 165, 167, 167, 171, 176, 179, 184, 184, 188, 192,
+ 199, 204, 209, 212, 218, 221, 225, 234, 240, 240, 240, 243, 246,
+ 250, 251, 255, 261, 265, 272, 278, 290, 296, 305, 307, 313, 318,
+ 320, 327, 332, 337, 343, 349, 354, 358, 361, 367, 371, 378, 380,
+ 387, 389, 391, 400, 404, 410, 416, 424, 429, 429, 445, 452, 459,
+ 460, 467, 471, 475, 479, 483, 486, 488, 490, 496, 500, 508, 513,
+ 521, 524, 529, 534, 540, 544, 549,
};
- static const unsigned char aCode[121] = {
+ static const unsigned char aCode[124] = {
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,
@@ -111630,160 +131055,165 @@ static int keywordCode(const char *z, int n){
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,
+ TK_OR, TK_UNIQUE, TK_QUERY, TK_WITHOUT, TK_WITH,
+ TK_JOIN_KW, TK_RELEASE, TK_ATTACH, TK_HAVING, TK_GROUP,
+ TK_UPDATE, TK_BEGIN, TK_JOIN_KW, TK_RECURSIVE, 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_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;
+ if( n>=2 ){
+ 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 ); /* WITHOUT */
+ testcase( i==49 ); /* WITH */
+ testcase( i==50 ); /* OUTER */
+ testcase( i==51 ); /* RELEASE */
+ testcase( i==52 ); /* ATTACH */
+ testcase( i==53 ); /* HAVING */
+ testcase( i==54 ); /* GROUP */
+ testcase( i==55 ); /* UPDATE */
+ testcase( i==56 ); /* BEGIN */
+ testcase( i==57 ); /* INNER */
+ testcase( i==58 ); /* RECURSIVE */
+ testcase( i==59 ); /* BETWEEN */
+ testcase( i==60 ); /* NOTNULL */
+ testcase( i==61 ); /* NOT */
+ testcase( i==62 ); /* NO */
+ testcase( i==63 ); /* NULL */
+ testcase( i==64 ); /* LIKE */
+ testcase( i==65 ); /* CASCADE */
+ testcase( i==66 ); /* ASC */
+ testcase( i==67 ); /* DELETE */
+ testcase( i==68 ); /* CASE */
+ testcase( i==69 ); /* COLLATE */
+ testcase( i==70 ); /* CREATE */
+ testcase( i==71 ); /* CURRENT_DATE */
+ testcase( i==72 ); /* DETACH */
+ testcase( i==73 ); /* IMMEDIATE */
+ testcase( i==74 ); /* JOIN */
+ testcase( i==75 ); /* INSERT */
+ testcase( i==76 ); /* MATCH */
+ testcase( i==77 ); /* PLAN */
+ testcase( i==78 ); /* ANALYZE */
+ testcase( i==79 ); /* PRAGMA */
+ testcase( i==80 ); /* ABORT */
+ testcase( i==81 ); /* VALUES */
+ testcase( i==82 ); /* VIRTUAL */
+ testcase( i==83 ); /* LIMIT */
+ testcase( i==84 ); /* WHEN */
+ testcase( i==85 ); /* WHERE */
+ testcase( i==86 ); /* RENAME */
+ testcase( i==87 ); /* AFTER */
+ testcase( i==88 ); /* REPLACE */
+ testcase( i==89 ); /* AND */
+ testcase( i==90 ); /* DEFAULT */
+ testcase( i==91 ); /* AUTOINCREMENT */
+ testcase( i==92 ); /* TO */
+ testcase( i==93 ); /* IN */
+ testcase( i==94 ); /* CAST */
+ testcase( i==95 ); /* COLUMN */
+ testcase( i==96 ); /* COMMIT */
+ testcase( i==97 ); /* CONFLICT */
+ testcase( i==98 ); /* CROSS */
+ testcase( i==99 ); /* CURRENT_TIMESTAMP */
+ testcase( i==100 ); /* CURRENT_TIME */
+ testcase( i==101 ); /* PRIMARY */
+ testcase( i==102 ); /* DEFERRED */
+ testcase( i==103 ); /* DISTINCT */
+ testcase( i==104 ); /* IS */
+ testcase( i==105 ); /* DROP */
+ testcase( i==106 ); /* FAIL */
+ testcase( i==107 ); /* FROM */
+ testcase( i==108 ); /* FULL */
+ testcase( i==109 ); /* GLOB */
+ testcase( i==110 ); /* BY */
+ testcase( i==111 ); /* IF */
+ testcase( i==112 ); /* ISNULL */
+ testcase( i==113 ); /* ORDER */
+ testcase( i==114 ); /* RESTRICT */
+ testcase( i==115 ); /* RIGHT */
+ testcase( i==116 ); /* ROLLBACK */
+ testcase( i==117 ); /* ROW */
+ testcase( i==118 ); /* UNION */
+ testcase( i==119 ); /* USING */
+ testcase( i==120 ); /* VACUUM */
+ testcase( i==121 ); /* VIEW */
+ testcase( i==122 ); /* INITIALLY */
+ testcase( i==123 ); /* ALL */
+ *pType = aCode[i];
+ break;
+ }
+ }
+ }
+ return n;
}
SQLITE_PRIVATE int sqlite3KeywordCode(const unsigned char *z, int n){
- return keywordCode((char*)z, n);
+ int id = TK_ID;
+ keywordCode((char*)z, n, &id);
+ return id;
}
-#define SQLITE_N_KEYWORD 121
+#define SQLITE_N_KEYWORD 124
/************** End of keywordhash.h *****************************************/
/************** Continuing where we left off in tokenize.c *******************/
@@ -111801,7 +131231,7 @@ SQLITE_PRIVATE int sqlite3KeywordCode(const unsigned char *z, int n){
** end result.
**
** Ticket #1066. the SQL standard does not allow '$' in the
-** middle of identfiers. But many SQL implementations do.
+** middle of identifiers. But many SQL implementations do.
** SQLite will allow '$' in identifiers for compatibility.
** But the feature is undocumented.
*/
@@ -111827,6 +131257,11 @@ SQLITE_PRIVATE const char sqlite3IsEbcdicIdChar[] = {
#define IdChar(C) (((c=C)>=0x42 && sqlite3IsEbcdicIdChar[c-0x40]))
#endif
+/* Make the IdChar function accessible from ctime.c */
+#ifndef SQLITE_OMIT_COMPILEOPTION_DIAGS
+SQLITE_PRIVATE int sqlite3IsIdChar(u8 c){ return IdChar(c); }
+#endif
+
/*
** Return the length of the token that begins at z[0].
@@ -111847,7 +131282,6 @@ SQLITE_PRIVATE int sqlite3GetToken(const unsigned char *z, int *tokenType){
}
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;
@@ -111880,7 +131314,6 @@ SQLITE_PRIVATE int sqlite3GetToken(const unsigned char *z, int *tokenType){
*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 */
@@ -111996,6 +131429,12 @@ SQLITE_PRIVATE int sqlite3GetToken(const unsigned char *z, int *tokenType){
testcase( z[0]=='6' ); testcase( z[0]=='7' ); testcase( z[0]=='8' );
testcase( z[0]=='9' );
*tokenType = TK_INTEGER;
+#ifndef SQLITE_OMIT_HEX_INTEGER
+ if( z[0]=='0' && (z[1]=='x' || z[1]=='X') && sqlite3Isxdigit(z[2]) ){
+ for(i=3; sqlite3Isxdigit(z[i]); i++){}
+ return i;
+ }
+#endif
for(i=0; sqlite3Isdigit(z[i]); i++){}
#ifndef SQLITE_OMIT_FLOATING_POINT
if( z[i]=='.' ){
@@ -112029,24 +131468,15 @@ SQLITE_PRIVATE int sqlite3GetToken(const unsigned char *z, int *tokenType){
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 '#':
case ':': {
int n = 0;
- testcase( z[0]=='$' ); testcase( z[0]=='@' ); testcase( z[0]==':' );
+ testcase( z[0]=='$' ); testcase( z[0]=='@' );
+ testcase( z[0]==':' ); testcase( z[0]=='#' );
*tokenType = TK_VARIABLE;
for(i=1; (c=z[i])!=0; i++){
if( IdChar(c) ){
@@ -112093,8 +131523,8 @@ SQLITE_PRIVATE int sqlite3GetToken(const unsigned char *z, int *tokenType){
break;
}
for(i=1; IdChar(z[i]); i++){}
- *tokenType = keywordCode((char*)z, i);
- return i;
+ *tokenType = TK_ID;
+ return keywordCode((char*)z, i, tokenType);
}
}
*tokenType = TK_ILLEGAL;
@@ -112118,16 +131548,17 @@ SQLITE_PRIVATE int sqlite3RunParser(Parse *pParse, const char *zSql, char **pzEr
sqlite3 *db = pParse->db; /* The database connection */
int mxSqlLen; /* Max length of an SQL string */
-
+ assert( zSql!=0 );
mxSqlLen = db->aLimit[SQLITE_LIMIT_SQL_LENGTH];
- if( db->activeVdbeCnt==0 ){
+ if( db->nVdbeActive==0 ){
db->u1.isInterrupted = 0;
}
pParse->rc = SQLITE_OK;
pParse->zTail = zSql;
i = 0;
assert( pzErrMsg!=0 );
- pEngine = sqlite3ParserAlloc((void*(*)(size_t))sqlite3Malloc);
+ /* sqlite3ParserTrace(stdout, "parser: "); */
+ pEngine = sqlite3ParserAlloc(sqlite3Malloc);
if( pEngine==0 ){
db->mallocFailed = 1;
return SQLITE_NOMEM;
@@ -112139,7 +131570,7 @@ SQLITE_PRIVATE int sqlite3RunParser(Parse *pParse, const char *zSql, char **pzEr
assert( pParse->azVar==0 );
enableLookaside = db->lookaside.bEnabled;
if( db->lookaside.pStart ) db->lookaside.bEnabled = 1;
- while( !db->mallocFailed && zSql[i]!=0 ){
+ while( zSql[i]!=0 ){
assert( i>=0 );
pParse->sLastToken.z = &zSql[i];
pParse->sLastToken.n = sqlite3GetToken((unsigned char*)&zSql[i],&tokenType);
@@ -112148,48 +131579,42 @@ SQLITE_PRIVATE int sqlite3RunParser(Parse *pParse, const char *zSql, char **pzEr
pParse->rc = SQLITE_TOOBIG;
break;
}
- switch( tokenType ){
- case TK_SPACE: {
- if( db->u1.isInterrupted ){
- sqlite3ErrorMsg(pParse, "interrupt");
- pParse->rc = SQLITE_INTERRUPT;
- goto abort_parse;
- }
+ if( tokenType>=TK_SPACE ){
+ assert( tokenType==TK_SPACE || tokenType==TK_ILLEGAL );
+ if( db->u1.isInterrupted ){
+ sqlite3ErrorMsg(pParse, "interrupt");
+ pParse->rc = SQLITE_INTERRUPT;
break;
}
- case TK_ILLEGAL: {
- sqlite3DbFree(db, *pzErrMsg);
- *pzErrMsg = sqlite3MPrintf(db, "unrecognized token: \"%T\"",
+ if( tokenType==TK_ILLEGAL ){
+ sqlite3ErrorMsg(pParse, "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;
}
+ }else{
+ if( tokenType==TK_SEMI ) pParse->zTail = &zSql[i];
+ sqlite3Parser(pEngine, tokenType, pParse->sLastToken, pParse);
+ lastTokenParsed = tokenType;
+ if( pParse->rc!=SQLITE_OK || db->mallocFailed ) break;
}
}
-abort_parse:
- if( zSql[i]==0 && nErr==0 && pParse->rc==SQLITE_OK ){
+ assert( nErr==0 );
+ if( pParse->rc==SQLITE_OK && db->mallocFailed==0 ){
+ assert( zSql[i]==0 );
if( lastTokenParsed!=TK_SEMI ){
sqlite3Parser(pEngine, TK_SEMI, pParse->sLastToken, pParse);
pParse->zTail = &zSql[i];
}
- sqlite3Parser(pEngine, 0, pParse->sLastToken, pParse);
+ if( pParse->rc==SQLITE_OK && db->mallocFailed==0 ){
+ sqlite3Parser(pEngine, 0, pParse->sLastToken, pParse);
+ }
}
#ifdef YYTRACKMAXSTACKDEPTH
- sqlite3StatusSet(SQLITE_STATUS_PARSER_STACK,
+ sqlite3_mutex_enter(sqlite3MallocMutex());
+ sqlite3StatusHighwater(SQLITE_STATUS_PARSER_STACK,
sqlite3ParserStackPeak(pEngine)
);
+ sqlite3_mutex_leave(sqlite3MallocMutex());
#endif /* YYDEBUG */
sqlite3ParserFree(pEngine, sqlite3_free);
db->lookaside.bEnabled = enableLookaside;
@@ -112197,7 +131622,7 @@ abort_parse:
pParse->rc = SQLITE_NOMEM;
}
if( pParse->rc!=SQLITE_OK && pParse->rc!=SQLITE_DONE && pParse->zErrMsg==0 ){
- sqlite3SetString(&pParse->zErrMsg, db, "%s", sqlite3ErrStr(pParse->rc));
+ pParse->zErrMsg = sqlite3MPrintf(db, "%s", sqlite3ErrStr(pParse->rc));
}
assert( pzErrMsg!=0 );
if( pParse->zErrMsg ){
@@ -112229,10 +131654,10 @@ abort_parse:
sqlite3DeleteTable(db, pParse->pNewTable);
}
+ sqlite3WithDelete(db, pParse->pWithToFree);
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;
@@ -112243,9 +131668,7 @@ abort_parse:
pParse->pZombieTab = p->pNextZombie;
sqlite3DeleteTable(db, p);
}
- if( nErr>0 && pParse->rc==SQLITE_OK ){
- pParse->rc = SQLITE_ERROR;
- }
+ assert( nErr==0 || pParse->rc!=SQLITE_OK );
return nErr;
}
@@ -112269,6 +131692,7 @@ abort_parse:
** separating it out, the code will be automatically omitted from
** static links that do not use it.
*/
+/* #include "sqliteInt.h" */
#ifndef SQLITE_OMIT_COMPLETE
/*
@@ -112322,7 +131746,7 @@ SQLITE_PRIVATE const char sqlite3IsEbcdicIdChar[];
** a statement.
**
** (4) CREATE The keyword CREATE has been seen at the beginning of a
-** statement, possibly preceeded by EXPLAIN and/or followed by
+** statement, possibly preceded by EXPLAIN and/or followed by
** TEMP or TEMPORARY
**
** (5) TRIGGER We are in the middle of a trigger definition that must be
@@ -112332,7 +131756,7 @@ SQLITE_PRIVATE const char sqlite3IsEbcdicIdChar[];
** 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.
+** of a trigger definition.
**
** Transitions between states above are determined by tokens extracted
** from the input. The following tokens are significant:
@@ -112353,7 +131777,7 @@ SQLITE_PRIVATE const char sqlite3IsEbcdicIdChar[];
** 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){
+SQLITE_API int SQLITE_STDCALL sqlite3_complete(const char *zSql){
u8 state = 0; /* Current state, using numbers defined in header comment */
u8 token; /* Value of the next token */
@@ -112375,7 +131799,7 @@ SQLITE_API int sqlite3_complete(const char *zSql){
};
#else
/* If triggers are not supported by this compile then the statement machine
- ** used to detect the end of a statement is much simplier
+ ** used to detect the end of a statement is much simpler
*/
static const u8 trans[3][3] = {
/* Token: */
@@ -112386,6 +131810,13 @@ SQLITE_API int sqlite3_complete(const char *zSql){
};
#endif /* SQLITE_OMIT_TRIGGER */
+#ifdef SQLITE_ENABLE_API_ARMOR
+ if( zSql==0 ){
+ (void)SQLITE_MISUSE_BKPT;
+ return 0;
+ }
+#endif
+
while( *zSql ){
switch( *zSql ){
case ';': { /* A semicolon */
@@ -112511,10 +131942,10 @@ SQLITE_API int sqlite3_complete(const char *zSql){
** above, except that the parameter is required to be UTF-16 encoded, not
** UTF-8.
*/
-SQLITE_API int sqlite3_complete16(const void *zSql){
+SQLITE_API int SQLITE_STDCALL sqlite3_complete16(const void *zSql){
sqlite3_value *pVal;
char const *zSql8;
- int rc = SQLITE_NOMEM;
+ int rc;
#ifndef SQLITE_OMIT_AUTOINIT
rc = sqlite3_initialize();
@@ -112529,7 +131960,7 @@ SQLITE_API int sqlite3_complete16(const void *zSql){
rc = SQLITE_NOMEM;
}
sqlite3ValueFree(pVal);
- return sqlite3ApiExit(0, rc);
+ return rc & 0xff;
}
#endif /* SQLITE_OMIT_UTF16 */
#endif /* SQLITE_OMIT_COMPLETE */
@@ -112552,6 +131983,7 @@ SQLITE_API int sqlite3_complete16(const void *zSql){
** other files are for internal use by SQLite and should not be
** accessed by users of the library.
*/
+/* #include "sqliteInt.h" */
#ifdef SQLITE_ENABLE_FTS3
/************** Include fts3.h in the middle of main.c ***********************/
@@ -112571,6 +132003,7 @@ SQLITE_API int sqlite3_complete16(const void *zSql){
** This header file is used by programs that want to link against the
** FTS3 library. All it does is declare the sqlite3Fts3Init() interface.
*/
+/* #include "sqlite3.h" */
#if 0
extern "C" {
@@ -112603,6 +132036,7 @@ SQLITE_PRIVATE int sqlite3Fts3Init(sqlite3 *db);
** This header file is used by programs that want to link against the
** RTREE library. All it does is declare the sqlite3RtreeInit() interface.
*/
+/* #include "sqlite3.h" */
#if 0
extern "C" {
@@ -112635,6 +132069,7 @@ SQLITE_PRIVATE int sqlite3RtreeInit(sqlite3 *db);
** This header file is used by programs that want to link against the
** ICU extension. All it does is declare the sqlite3IcuInit() interface.
*/
+/* #include "sqlite3.h" */
#if 0
extern "C" {
@@ -112650,6 +132085,12 @@ SQLITE_PRIVATE int sqlite3IcuInit(sqlite3 *db);
/************** End of sqliteicu.h *******************************************/
/************** Continuing where we left off in main.c ***********************/
#endif
+#ifdef SQLITE_ENABLE_JSON1
+SQLITE_PRIVATE int sqlite3Json1Init(sqlite3*);
+#endif
+#ifdef SQLITE_ENABLE_FTS5
+SQLITE_PRIVATE int sqlite3Fts5Init(sqlite3*);
+#endif
#ifndef SQLITE_AMALGAMATION
/* IMPLEMENTATION-OF: R-46656-45156 The sqlite3_version[] string constant
@@ -112661,24 +132102,36 @@ SQLITE_API const char sqlite3_version[] = SQLITE_VERSION;
/* 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; }
+SQLITE_API const char *SQLITE_STDCALL 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; }
+SQLITE_API const char *SQLITE_STDCALL 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; }
+SQLITE_API int SQLITE_STDCALL 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; }
+SQLITE_API int SQLITE_STDCALL sqlite3_threadsafe(void){ return SQLITE_THREADSAFE; }
+
+/*
+** When compiling the test fixture or with debugging enabled (on Win32),
+** this variable being set to non-zero will cause OSTRACE macros to emit
+** extra diagnostic information.
+*/
+#ifdef SQLITE_HAVE_OS_TRACE
+# ifndef SQLITE_DEBUG_OS_TRACE
+# define SQLITE_DEBUG_OS_TRACE 0
+# endif
+ int sqlite3OSTrace = SQLITE_DEBUG_OS_TRACE;
+#endif
#if !defined(SQLITE_OMIT_TRACE) && defined(SQLITE_ENABLE_IOTRACE)
/*
@@ -112687,7 +132140,7 @@ SQLITE_API int sqlite3_threadsafe(void){ return SQLITE_THREADSAFE; }
** I/O active are written using this function. These messages
** are intended for debugging activity only.
*/
-SQLITE_PRIVATE void (*sqlite3IoTrace)(const char*, ...) = 0;
+SQLITE_API void (SQLITE_CDECL *sqlite3IoTrace)(const char*, ...) = 0;
#endif
/*
@@ -112739,9 +132192,12 @@ SQLITE_API char *sqlite3_data_directory = 0;
** * Recursive calls to this routine from thread X return immediately
** without blocking.
*/
-SQLITE_API int sqlite3_initialize(void){
+SQLITE_API int SQLITE_STDCALL sqlite3_initialize(void){
MUTEX_LOGIC( sqlite3_mutex *pMaster; ) /* The main static mutex */
int rc; /* Result code */
+#ifdef SQLITE_EXTRA_INIT
+ int bRunExtraInit = 0; /* Extra initialization needed */
+#endif
#ifdef SQLITE_OMIT_WSD
rc = sqlite3_wsd_init(4096, 24);
@@ -112750,6 +132206,11 @@ SQLITE_API int sqlite3_initialize(void){
}
#endif
+ /* If the following assert() fails on some obscure processor/compiler
+ ** combination, the work-around is to set the correct pointer
+ ** size at compile-time using -DSQLITE_PTRSIZE=n compile-time option */
+ assert( SQLITE_PTRSIZE==sizeof(char*) );
+
/* 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
@@ -112757,13 +132218,6 @@ SQLITE_API int sqlite3_initialize(void){
*/
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,
@@ -112826,6 +132280,12 @@ SQLITE_API int sqlite3_initialize(void){
if( sqlite3GlobalConfig.isInit==0 && sqlite3GlobalConfig.inProgress==0 ){
FuncDefHash *pHash = &GLOBAL(FuncDefHash, sqlite3GlobalFunctions);
sqlite3GlobalConfig.inProgress = 1;
+#ifdef SQLITE_ENABLE_SQLLOG
+ {
+ extern void sqlite3_init_sqllog(void);
+ sqlite3_init_sqllog();
+ }
+#endif
memset(pHash, 0, sizeof(sqlite3GlobalFunctions));
sqlite3RegisterGlobalFunctions();
if( sqlite3GlobalConfig.isPCacheInit==0 ){
@@ -112839,6 +132299,9 @@ SQLITE_API int sqlite3_initialize(void){
sqlite3PCacheBufferSetup( sqlite3GlobalConfig.pPage,
sqlite3GlobalConfig.szPage, sqlite3GlobalConfig.nPage);
sqlite3GlobalConfig.isInit = 1;
+#ifdef SQLITE_EXTRA_INIT
+ bRunExtraInit = 1;
+#endif
}
sqlite3GlobalConfig.inProgress = 0;
}
@@ -112879,7 +132342,7 @@ SQLITE_API int sqlite3_initialize(void){
** compile-time option.
*/
#ifdef SQLITE_EXTRA_INIT
- if( rc==SQLITE_OK && sqlite3GlobalConfig.isInit ){
+ if( bRunExtraInit ){
int SQLITE_EXTRA_INIT(const char*);
rc = SQLITE_EXTRA_INIT(0);
}
@@ -112896,7 +132359,14 @@ SQLITE_API int sqlite3_initialize(void){
** 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){
+SQLITE_API int SQLITE_STDCALL sqlite3_shutdown(void){
+#ifdef SQLITE_OMIT_WSD
+ int rc = sqlite3_wsd_init(4096, 24);
+ if( rc!=SQLITE_OK ){
+ return rc;
+ }
+#endif
+
if( sqlite3GlobalConfig.isInit ){
#ifdef SQLITE_EXTRA_SHUTDOWN
void SQLITE_EXTRA_SHUTDOWN(void);
@@ -112943,7 +132413,7 @@ SQLITE_API int sqlite3_shutdown(void){
** threadsafe. Failure to heed these warnings can lead to unpredictable
** behavior.
*/
-SQLITE_API int sqlite3_config(int op, ...){
+SQLITE_API int SQLITE_CDECL sqlite3_config(int op, ...){
va_list ap;
int rc = SQLITE_OK;
@@ -112955,33 +132425,43 @@ SQLITE_API int sqlite3_config(int op, ...){
switch( op ){
/* Mutex configuration options are only available in a threadsafe
- ** compile.
+ ** compile.
*/
-#if defined(SQLITE_THREADSAFE) && SQLITE_THREADSAFE>0
+#if defined(SQLITE_THREADSAFE) && SQLITE_THREADSAFE>0 /* IMP: R-54466-46756 */
case SQLITE_CONFIG_SINGLETHREAD: {
- /* Disable all mutexing */
- sqlite3GlobalConfig.bCoreMutex = 0;
- sqlite3GlobalConfig.bFullMutex = 0;
+ /* EVIDENCE-OF: R-02748-19096 This option sets the threading mode to
+ ** Single-thread. */
+ sqlite3GlobalConfig.bCoreMutex = 0; /* Disable mutex on core */
+ sqlite3GlobalConfig.bFullMutex = 0; /* Disable mutex on connections */
break;
}
+#endif
+#if defined(SQLITE_THREADSAFE) && SQLITE_THREADSAFE>0 /* IMP: R-20520-54086 */
case SQLITE_CONFIG_MULTITHREAD: {
- /* Disable mutexing of database connections */
- /* Enable mutexing of core data structures */
- sqlite3GlobalConfig.bCoreMutex = 1;
- sqlite3GlobalConfig.bFullMutex = 0;
+ /* EVIDENCE-OF: R-14374-42468 This option sets the threading mode to
+ ** Multi-thread. */
+ sqlite3GlobalConfig.bCoreMutex = 1; /* Enable mutex on core */
+ sqlite3GlobalConfig.bFullMutex = 0; /* Disable mutex on connections */
break;
}
+#endif
+#if defined(SQLITE_THREADSAFE) && SQLITE_THREADSAFE>0 /* IMP: R-59593-21810 */
case SQLITE_CONFIG_SERIALIZED: {
- /* Enable all mutexing */
- sqlite3GlobalConfig.bCoreMutex = 1;
- sqlite3GlobalConfig.bFullMutex = 1;
+ /* EVIDENCE-OF: R-41220-51800 This option sets the threading mode to
+ ** Serialized. */
+ sqlite3GlobalConfig.bCoreMutex = 1; /* Enable mutex on core */
+ sqlite3GlobalConfig.bFullMutex = 1; /* Enable mutex on connections */
break;
}
+#endif
+#if defined(SQLITE_THREADSAFE) && SQLITE_THREADSAFE>0 /* IMP: R-63666-48755 */
case SQLITE_CONFIG_MUTEX: {
/* Specify an alternative mutex implementation */
sqlite3GlobalConfig.mutex = *va_arg(ap, sqlite3_mutex_methods*);
break;
}
+#endif
+#if defined(SQLITE_THREADSAFE) && SQLITE_THREADSAFE>0 /* IMP: R-14450-37597 */
case SQLITE_CONFIG_GETMUTEX: {
/* Retrieve the current mutex implementation */
*va_arg(ap, sqlite3_mutex_methods*) = sqlite3GlobalConfig.mutex;
@@ -112989,37 +132469,62 @@ SQLITE_API int sqlite3_config(int op, ...){
}
#endif
-
case SQLITE_CONFIG_MALLOC: {
- /* Specify an alternative malloc implementation */
+ /* EVIDENCE-OF: R-55594-21030 The SQLITE_CONFIG_MALLOC 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. */
sqlite3GlobalConfig.m = *va_arg(ap, sqlite3_mem_methods*);
break;
}
case SQLITE_CONFIG_GETMALLOC: {
- /* Retrieve the current malloc() implementation */
+ /* EVIDENCE-OF: R-51213-46414 The SQLITE_CONFIG_GETMALLOC 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. */
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 */
+ /* EVIDENCE-OF: R-61275-35157 The SQLITE_CONFIG_MEMSTATUS option takes
+ ** single argument of type int, interpreted as a boolean, which enables
+ ** or disables the collection of memory allocation statistics. */
sqlite3GlobalConfig.bMemstat = va_arg(ap, int);
break;
}
case SQLITE_CONFIG_SCRATCH: {
- /* Designate a buffer for scratch memory space */
+ /* EVIDENCE-OF: R-08404-60887 There are three arguments to
+ ** SQLITE_CONFIG_SCRATCH: 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). */
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 */
+ /* EVIDENCE-OF: R-18761-36601 There are three arguments to
+ ** SQLITE_CONFIG_PAGECACHE: A pointer to 8-byte aligned memory (pMem),
+ ** the size of each page cache line (sz), and the number of cache lines
+ ** (N). */
sqlite3GlobalConfig.pPage = va_arg(ap, void*);
sqlite3GlobalConfig.szPage = va_arg(ap, int);
sqlite3GlobalConfig.nPage = va_arg(ap, int);
break;
}
+ case SQLITE_CONFIG_PCACHE_HDRSZ: {
+ /* EVIDENCE-OF: R-39100-27317 The SQLITE_CONFIG_PCACHE_HDRSZ option takes
+ ** a single parameter which is a pointer to an integer and writes into
+ ** that integer the number of extra bytes per page required for each page
+ ** in SQLITE_CONFIG_PAGECACHE. */
+ *va_arg(ap, int*) =
+ sqlite3HeaderSizeBtree() +
+ sqlite3HeaderSizePcache() +
+ sqlite3HeaderSizePcache1();
+ break;
+ }
case SQLITE_CONFIG_PCACHE: {
/* no-op */
@@ -113032,11 +132537,18 @@ SQLITE_API int sqlite3_config(int op, ...){
}
case SQLITE_CONFIG_PCACHE2: {
- /* Specify an alternative page cache implementation */
+ /* EVIDENCE-OF: R-63325-48378 The SQLITE_CONFIG_PCACHE2 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. */
sqlite3GlobalConfig.pcache2 = *va_arg(ap, sqlite3_pcache_methods2*);
break;
}
case SQLITE_CONFIG_GETPCACHE2: {
+ /* EVIDENCE-OF: R-22035-46182 The SQLITE_CONFIG_GETPCACHE2 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. */
if( sqlite3GlobalConfig.pcache2.xInit==0 ){
sqlite3PCacheSetDefault();
}
@@ -113044,9 +132556,15 @@ SQLITE_API int sqlite3_config(int op, ...){
break;
}
+/* EVIDENCE-OF: R-06626-12911 The SQLITE_CONFIG_HEAP option is only
+** available if SQLite is compiled with either SQLITE_ENABLE_MEMSYS3 or
+** SQLITE_ENABLE_MEMSYS5 and returns SQLITE_ERROR if invoked otherwise. */
#if defined(SQLITE_ENABLE_MEMSYS3) || defined(SQLITE_ENABLE_MEMSYS5)
case SQLITE_CONFIG_HEAP: {
- /* Designate a buffer for heap memory space */
+ /* EVIDENCE-OF: R-19854-42126 There are three arguments to
+ ** SQLITE_CONFIG_HEAP: An 8-byte aligned pointer to the memory, the
+ ** number of bytes in the memory buffer, and the minimum allocation size.
+ */
sqlite3GlobalConfig.pHeap = va_arg(ap, void*);
sqlite3GlobalConfig.nHeap = va_arg(ap, int);
sqlite3GlobalConfig.mnReq = va_arg(ap, int);
@@ -113059,17 +132577,19 @@ SQLITE_API int sqlite3_config(int op, ...){
}
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.
+ /* EVIDENCE-OF: R-49920-60189 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.
+ **
+ ** Setting sqlite3GlobalConfig.m to all zeros will cause malloc to
+ ** revert 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.
- */
+ /* EVIDENCE-OF: R-61006-08918 If the memory pointer is not NULL then the
+ ** alternative memory allocator is engaged to handle all of SQLites
+ ** memory allocation needs. */
#ifdef SQLITE_ENABLE_MEMSYS3
sqlite3GlobalConfig.m = *sqlite3MemGetMemsys3();
#endif
@@ -113087,7 +132607,7 @@ SQLITE_API int sqlite3_config(int op, ...){
break;
}
- /* Record a pointer to the logger funcction and its first argument.
+ /* Record a pointer to the logger function and its first argument.
** The default is NULL. Logging is disabled if the function pointer is
** NULL.
*/
@@ -113102,12 +132622,25 @@ SQLITE_API int sqlite3_config(int op, ...){
break;
}
+ /* EVIDENCE-OF: R-55548-33817 The compile-time setting for URI filenames
+ ** can be changed at start-time using the
+ ** sqlite3_config(SQLITE_CONFIG_URI,1) or
+ ** sqlite3_config(SQLITE_CONFIG_URI,0) configuration calls.
+ */
case SQLITE_CONFIG_URI: {
+ /* EVIDENCE-OF: R-25451-61125 The SQLITE_CONFIG_URI 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. */
sqlite3GlobalConfig.bOpenUri = va_arg(ap, int);
break;
}
case SQLITE_CONFIG_COVERING_INDEX_SCAN: {
+ /* EVIDENCE-OF: R-36592-02772 The SQLITE_CONFIG_COVERING_INDEX_SCAN
+ ** 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. */
sqlite3GlobalConfig.bUseCis = va_arg(ap, int);
break;
}
@@ -113121,6 +132654,46 @@ SQLITE_API int sqlite3_config(int op, ...){
}
#endif
+ case SQLITE_CONFIG_MMAP_SIZE: {
+ /* EVIDENCE-OF: R-58063-38258 SQLITE_CONFIG_MMAP_SIZE takes two 64-bit
+ ** integer (sqlite3_int64) values that are the default mmap size limit
+ ** (the default setting for PRAGMA mmap_size) and the maximum allowed
+ ** mmap size limit. */
+ sqlite3_int64 szMmap = va_arg(ap, sqlite3_int64);
+ sqlite3_int64 mxMmap = va_arg(ap, sqlite3_int64);
+ /* EVIDENCE-OF: R-53367-43190 If either argument to this option is
+ ** negative, then that argument is changed to its compile-time default.
+ **
+ ** EVIDENCE-OF: R-34993-45031 The maximum allowed mmap size will be
+ ** silently truncated if necessary so that it does not exceed the
+ ** compile-time maximum mmap size set by the SQLITE_MAX_MMAP_SIZE
+ ** compile-time option.
+ */
+ if( mxMmap<0 || mxMmap>SQLITE_MAX_MMAP_SIZE ){
+ mxMmap = SQLITE_MAX_MMAP_SIZE;
+ }
+ if( szMmap<0 ) szMmap = SQLITE_DEFAULT_MMAP_SIZE;
+ if( szMmap>mxMmap) szMmap = mxMmap;
+ sqlite3GlobalConfig.mxMmap = mxMmap;
+ sqlite3GlobalConfig.szMmap = szMmap;
+ break;
+ }
+
+#if SQLITE_OS_WIN && defined(SQLITE_WIN32_MALLOC) /* IMP: R-04780-55815 */
+ case SQLITE_CONFIG_WIN32_HEAPSIZE: {
+ /* EVIDENCE-OF: R-34926-03360 SQLITE_CONFIG_WIN32_HEAPSIZE takes a 32-bit
+ ** unsigned integer value that specifies the maximum size of the created
+ ** heap. */
+ sqlite3GlobalConfig.nHeap = va_arg(ap, int);
+ break;
+ }
+#endif
+
+ case SQLITE_CONFIG_PMASZ: {
+ sqlite3GlobalConfig.szPma = va_arg(ap, unsigned int);
+ break;
+ }
+
default: {
rc = SQLITE_ERROR;
break;
@@ -113142,6 +132715,7 @@ SQLITE_API int sqlite3_config(int op, ...){
** the lookaside memory.
*/
static int setupLookaside(sqlite3 *db, void *pBuf, int sz, int cnt){
+#ifndef SQLITE_OMIT_LOOKASIDE
void *pStart;
if( db->lookaside.nOut ){
return SQLITE_BUSY;
@@ -113187,17 +132761,25 @@ static int setupLookaside(sqlite3 *db, void *pBuf, int sz, int cnt){
db->lookaside.bEnabled = 1;
db->lookaside.bMalloced = pBuf==0 ?1:0;
}else{
- db->lookaside.pEnd = 0;
+ db->lookaside.pStart = db;
+ db->lookaside.pEnd = db;
db->lookaside.bEnabled = 0;
db->lookaside.bMalloced = 0;
}
+#endif /* SQLITE_OMIT_LOOKASIDE */
return SQLITE_OK;
}
/*
** Return the mutex associated with a database connection.
*/
-SQLITE_API sqlite3_mutex *sqlite3_db_mutex(sqlite3 *db){
+SQLITE_API sqlite3_mutex *SQLITE_STDCALL sqlite3_db_mutex(sqlite3 *db){
+#ifdef SQLITE_ENABLE_API_ARMOR
+ if( !sqlite3SafetyCheckOk(db) ){
+ (void)SQLITE_MISUSE_BKPT;
+ return 0;
+ }
+#endif
return db->mutex;
}
@@ -113205,8 +132787,12 @@ SQLITE_API sqlite3_mutex *sqlite3_db_mutex(sqlite3 *db){
** Free up as much memory as we can from the given database
** connection.
*/
-SQLITE_API int sqlite3_db_release_memory(sqlite3 *db){
+SQLITE_API int SQLITE_STDCALL sqlite3_db_release_memory(sqlite3 *db){
int i;
+
+#ifdef SQLITE_ENABLE_API_ARMOR
+ if( !sqlite3SafetyCheckOk(db) ) return SQLITE_MISUSE_BKPT;
+#endif
sqlite3_mutex_enter(db->mutex);
sqlite3BtreeEnterAll(db);
for(i=0; i<db->nDb; i++){
@@ -113222,9 +132808,39 @@ SQLITE_API int sqlite3_db_release_memory(sqlite3 *db){
}
/*
+** Flush any dirty pages in the pager-cache for any attached database
+** to disk.
+*/
+SQLITE_API int SQLITE_STDCALL sqlite3_db_cacheflush(sqlite3 *db){
+ int i;
+ int rc = SQLITE_OK;
+ int bSeenBusy = 0;
+
+#ifdef SQLITE_ENABLE_API_ARMOR
+ if( !sqlite3SafetyCheckOk(db) ) return SQLITE_MISUSE_BKPT;
+#endif
+ sqlite3_mutex_enter(db->mutex);
+ sqlite3BtreeEnterAll(db);
+ for(i=0; rc==SQLITE_OK && i<db->nDb; i++){
+ Btree *pBt = db->aDb[i].pBt;
+ if( pBt && sqlite3BtreeIsInTrans(pBt) ){
+ Pager *pPager = sqlite3BtreePager(pBt);
+ rc = sqlite3PagerFlush(pPager);
+ if( rc==SQLITE_BUSY ){
+ bSeenBusy = 1;
+ rc = SQLITE_OK;
+ }
+ }
+ }
+ sqlite3BtreeLeaveAll(db);
+ sqlite3_mutex_leave(db->mutex);
+ return ((rc==SQLITE_OK && bSeenBusy) ? SQLITE_BUSY : rc);
+}
+
+/*
** Configuration settings for an individual database connection
*/
-SQLITE_API int sqlite3_db_config(sqlite3 *db, int op, ...){
+SQLITE_API int SQLITE_CDECL sqlite3_db_config(sqlite3 *db, int op, ...){
va_list ap;
int rc;
va_start(ap, op);
@@ -113296,13 +132912,20 @@ static int binCollFunc(
){
int rc, n;
n = nKey1<nKey2 ? nKey1 : nKey2;
+ /* EVIDENCE-OF: R-65033-28449 The built-in BINARY collation compares
+ ** strings byte by byte using the memcmp() function from the standard C
+ ** library. */
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 */
+ /* EVIDENCE-OF: R-31624-24737 RTRIM is like BINARY except that extra
+ ** spaces at the end of either string do not change the result. In other
+ ** words, strings will compare equal to one another as long as they
+ ** differ only in the number of spaces at the end.
+ */
}else{
rc = nKey1 - nKey2;
}
@@ -113313,7 +132936,7 @@ static int binCollFunc(
/*
** Another built-in collating sequence: NOCASE.
**
-** This collating sequence is intended to be used for "case independant
+** This collating sequence is intended to be used for "case independent
** comparison". SQLite's knowledge of upper and lower case equivalents
** extends only to the 26 characters used in the English language.
**
@@ -113336,21 +132959,39 @@ static int nocaseCollatingFunc(
/*
** Return the ROWID of the most recent insert
*/
-SQLITE_API sqlite_int64 sqlite3_last_insert_rowid(sqlite3 *db){
+SQLITE_API sqlite_int64 SQLITE_STDCALL sqlite3_last_insert_rowid(sqlite3 *db){
+#ifdef SQLITE_ENABLE_API_ARMOR
+ if( !sqlite3SafetyCheckOk(db) ){
+ (void)SQLITE_MISUSE_BKPT;
+ return 0;
+ }
+#endif
return db->lastRowid;
}
/*
** Return the number of changes in the most recent call to sqlite3_exec().
*/
-SQLITE_API int sqlite3_changes(sqlite3 *db){
+SQLITE_API int SQLITE_STDCALL sqlite3_changes(sqlite3 *db){
+#ifdef SQLITE_ENABLE_API_ARMOR
+ if( !sqlite3SafetyCheckOk(db) ){
+ (void)SQLITE_MISUSE_BKPT;
+ return 0;
+ }
+#endif
return db->nChange;
}
/*
** Return the number of changes since the database handle was opened.
*/
-SQLITE_API int sqlite3_total_changes(sqlite3 *db){
+SQLITE_API int SQLITE_STDCALL sqlite3_total_changes(sqlite3 *db){
+#ifdef SQLITE_ENABLE_API_ARMOR
+ if( !sqlite3SafetyCheckOk(db) ){
+ (void)SQLITE_MISUSE_BKPT;
+ return 0;
+ }
+#endif
return db->nTotalChange;
}
@@ -113394,17 +133035,24 @@ static void functionDestroy(sqlite3 *db, FuncDef *p){
static void disconnectAllVtab(sqlite3 *db){
#ifndef SQLITE_OMIT_VIRTUALTABLE
int i;
+ HashElem *p;
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);
}
}
}
+ for(p=sqliteHashFirst(&db->aModule); p; p=sqliteHashNext(p)){
+ Module *pMod = (Module *)sqliteHashData(p);
+ if( pMod->pEpoTab ){
+ sqlite3VtabDisconnect(db, pMod->pEpoTab);
+ }
+ }
+ sqlite3VtabUnlockList(db);
sqlite3BtreeLeaveAll(db);
#else
UNUSED_PARAMETER(db);
@@ -113431,6 +133079,8 @@ static int connectionIsBusy(sqlite3 *db){
*/
static int sqlite3Close(sqlite3 *db, int forceZombie){
if( !db ){
+ /* EVIDENCE-OF: R-63257-11740 Calling sqlite3_close() or
+ ** sqlite3_close_v2() with a NULL pointer argument is a harmless no-op. */
return SQLITE_OK;
}
if( !sqlite3SafetyCheckSickOrOk(db) ){
@@ -113454,7 +133104,7 @@ static int sqlite3Close(sqlite3 *db, int forceZombie){
** SQLITE_BUSY if the connection can not be closed immediately.
*/
if( !forceZombie && connectionIsBusy(db) ){
- sqlite3Error(db, SQLITE_BUSY, "unable to close due to unfinalized "
+ sqlite3ErrorWithMsg(db, SQLITE_BUSY, "unable to close due to unfinalized "
"statements or unfinished backups");
sqlite3_mutex_leave(db->mutex);
return SQLITE_BUSY;
@@ -113483,8 +133133,8 @@ static int sqlite3Close(sqlite3 *db, int forceZombie){
** 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); }
+SQLITE_API int SQLITE_STDCALL sqlite3_close(sqlite3 *db){ return sqlite3Close(db,0); }
+SQLITE_API int SQLITE_STDCALL sqlite3_close_v2(sqlite3 *db){ return sqlite3Close(db,1); }
/*
@@ -113510,10 +133160,16 @@ SQLITE_PRIVATE void sqlite3LeaveMutexAndCloseZombie(sqlite3 *db){
/* 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,
+ ** passed to sqlite3_close (meaning that it is a zombie). Therefore,
** go ahead and free all resources.
*/
+ /* If a transaction is open, roll it back. This also ensures that if
+ ** any database schemas have been modified by an uncommitted transaction
+ ** they are reset. And that the required b-tree mutex is held to make
+ ** the pager rollback and schema reset an atomic operation. */
+ sqlite3RollbackAll(db, SQLITE_OK);
+
/* Free any outstanding Savepoint structures. */
sqlite3CloseSavepoints(db);
@@ -113573,16 +133229,19 @@ SQLITE_PRIVATE void sqlite3LeaveMutexAndCloseZombie(sqlite3 *db){
if( pMod->xDestroy ){
pMod->xDestroy(pMod->pAux);
}
+ sqlite3VtabEponymousTableClear(db, pMod);
sqlite3DbFree(db, pMod);
}
sqlite3HashClear(&db->aModule);
#endif
- sqlite3Error(db, SQLITE_OK, 0); /* Deallocates any cached error strings. */
- if( db->pErr ){
- sqlite3ValueFree(db->pErr);
- }
+ sqlite3Error(db, SQLITE_OK); /* Deallocates any cached error strings. */
+ sqlite3ValueFree(db->pErr);
sqlite3CloseExtensions(db);
+#if SQLITE_USER_AUTHENTICATION
+ sqlite3_free(db->auth.zAuthUser);
+ sqlite3_free(db->auth.zAuthPW);
+#endif
db->magic = SQLITE_MAGIC_ERROR;
@@ -113605,35 +133264,49 @@ SQLITE_PRIVATE void sqlite3LeaveMutexAndCloseZombie(sqlite3 *db){
/*
** Rollback all database files. If tripCode is not SQLITE_OK, then
-** any open cursors are invalidated ("tripped" - as in "tripping a circuit
+** any write 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.
+** attempts to use that cursor. Read cursors remain open and valid
+** but are "saved" in case the table pages are moved around.
*/
SQLITE_PRIVATE void sqlite3RollbackAll(sqlite3 *db, int tripCode){
int i;
int inTrans = 0;
+ int schemaChange;
assert( sqlite3_mutex_held(db->mutex) );
sqlite3BeginBenignMalloc();
+
+ /* Obtain all b-tree mutexes before making any calls to BtreeRollback().
+ ** This is important in case the transaction being rolled back has
+ ** modified the database schema. If the b-tree mutexes are not taken
+ ** here, then another shared-cache connection might sneak in between
+ ** the database rollback and schema reset, which can cause false
+ ** corruption reports in some cases. */
+ sqlite3BtreeEnterAll(db);
+ schemaChange = (db->flags & SQLITE_InternChanges)!=0 && db->init.busy==0;
+
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;
+ sqlite3BtreeRollback(p, tripCode, !schemaChange);
}
}
sqlite3VtabRollback(db);
sqlite3EndBenignMalloc();
- if( db->flags&SQLITE_InternChanges ){
+ if( (db->flags&SQLITE_InternChanges)!=0 && db->init.busy==0 ){
sqlite3ExpirePreparedStatements(db);
sqlite3ResetAllSchemasOfConnection(db);
}
+ sqlite3BtreeLeaveAll(db);
/* Any deferred constraint violations have now been resolved. */
db->nDeferredCons = 0;
+ db->nDeferredImmCons = 0;
+ db->flags &= ~SQLITE_DeferFKs;
/* If one has been configured, invoke the rollback-hook callback */
if( db->xRollbackCallback && (inTrans || !db->autoCommit) ){
@@ -113642,6 +133315,115 @@ SQLITE_PRIVATE void sqlite3RollbackAll(sqlite3 *db, int tripCode){
}
/*
+** Return a static string containing the name corresponding to the error code
+** specified in the argument.
+*/
+#if defined(SQLITE_NEED_ERR_NAME)
+SQLITE_PRIVATE const char *sqlite3ErrName(int rc){
+ const char *zName = 0;
+ int i, origRc = rc;
+ for(i=0; i<2 && zName==0; i++, rc &= 0xff){
+ switch( rc ){
+ case SQLITE_OK: zName = "SQLITE_OK"; break;
+ case SQLITE_ERROR: zName = "SQLITE_ERROR"; break;
+ case SQLITE_INTERNAL: zName = "SQLITE_INTERNAL"; break;
+ case SQLITE_PERM: zName = "SQLITE_PERM"; break;
+ case SQLITE_ABORT: zName = "SQLITE_ABORT"; break;
+ case SQLITE_ABORT_ROLLBACK: zName = "SQLITE_ABORT_ROLLBACK"; break;
+ case SQLITE_BUSY: zName = "SQLITE_BUSY"; break;
+ case SQLITE_BUSY_RECOVERY: zName = "SQLITE_BUSY_RECOVERY"; break;
+ case SQLITE_BUSY_SNAPSHOT: zName = "SQLITE_BUSY_SNAPSHOT"; break;
+ case SQLITE_LOCKED: zName = "SQLITE_LOCKED"; break;
+ case SQLITE_LOCKED_SHAREDCACHE: zName = "SQLITE_LOCKED_SHAREDCACHE";break;
+ case SQLITE_NOMEM: zName = "SQLITE_NOMEM"; break;
+ case SQLITE_READONLY: zName = "SQLITE_READONLY"; break;
+ case SQLITE_READONLY_RECOVERY: zName = "SQLITE_READONLY_RECOVERY"; break;
+ case SQLITE_READONLY_CANTLOCK: zName = "SQLITE_READONLY_CANTLOCK"; break;
+ case SQLITE_READONLY_ROLLBACK: zName = "SQLITE_READONLY_ROLLBACK"; break;
+ case SQLITE_READONLY_DBMOVED: zName = "SQLITE_READONLY_DBMOVED"; break;
+ case SQLITE_INTERRUPT: zName = "SQLITE_INTERRUPT"; break;
+ case SQLITE_IOERR: zName = "SQLITE_IOERR"; break;
+ case SQLITE_IOERR_READ: zName = "SQLITE_IOERR_READ"; break;
+ case SQLITE_IOERR_SHORT_READ: zName = "SQLITE_IOERR_SHORT_READ"; break;
+ case SQLITE_IOERR_WRITE: zName = "SQLITE_IOERR_WRITE"; break;
+ case SQLITE_IOERR_FSYNC: zName = "SQLITE_IOERR_FSYNC"; break;
+ case SQLITE_IOERR_DIR_FSYNC: zName = "SQLITE_IOERR_DIR_FSYNC"; break;
+ case SQLITE_IOERR_TRUNCATE: zName = "SQLITE_IOERR_TRUNCATE"; break;
+ case SQLITE_IOERR_FSTAT: zName = "SQLITE_IOERR_FSTAT"; break;
+ case SQLITE_IOERR_UNLOCK: zName = "SQLITE_IOERR_UNLOCK"; break;
+ case SQLITE_IOERR_RDLOCK: zName = "SQLITE_IOERR_RDLOCK"; break;
+ case SQLITE_IOERR_DELETE: zName = "SQLITE_IOERR_DELETE"; break;
+ case SQLITE_IOERR_NOMEM: zName = "SQLITE_IOERR_NOMEM"; break;
+ case SQLITE_IOERR_ACCESS: zName = "SQLITE_IOERR_ACCESS"; break;
+ case SQLITE_IOERR_CHECKRESERVEDLOCK:
+ zName = "SQLITE_IOERR_CHECKRESERVEDLOCK"; break;
+ case SQLITE_IOERR_LOCK: zName = "SQLITE_IOERR_LOCK"; break;
+ case SQLITE_IOERR_CLOSE: zName = "SQLITE_IOERR_CLOSE"; break;
+ case SQLITE_IOERR_DIR_CLOSE: zName = "SQLITE_IOERR_DIR_CLOSE"; break;
+ case SQLITE_IOERR_SHMOPEN: zName = "SQLITE_IOERR_SHMOPEN"; break;
+ case SQLITE_IOERR_SHMSIZE: zName = "SQLITE_IOERR_SHMSIZE"; break;
+ case SQLITE_IOERR_SHMLOCK: zName = "SQLITE_IOERR_SHMLOCK"; break;
+ case SQLITE_IOERR_SHMMAP: zName = "SQLITE_IOERR_SHMMAP"; break;
+ case SQLITE_IOERR_SEEK: zName = "SQLITE_IOERR_SEEK"; break;
+ case SQLITE_IOERR_DELETE_NOENT: zName = "SQLITE_IOERR_DELETE_NOENT";break;
+ case SQLITE_IOERR_MMAP: zName = "SQLITE_IOERR_MMAP"; break;
+ case SQLITE_IOERR_GETTEMPPATH: zName = "SQLITE_IOERR_GETTEMPPATH"; break;
+ case SQLITE_IOERR_CONVPATH: zName = "SQLITE_IOERR_CONVPATH"; break;
+ case SQLITE_CORRUPT: zName = "SQLITE_CORRUPT"; break;
+ case SQLITE_CORRUPT_VTAB: zName = "SQLITE_CORRUPT_VTAB"; break;
+ case SQLITE_NOTFOUND: zName = "SQLITE_NOTFOUND"; break;
+ case SQLITE_FULL: zName = "SQLITE_FULL"; break;
+ case SQLITE_CANTOPEN: zName = "SQLITE_CANTOPEN"; break;
+ case SQLITE_CANTOPEN_NOTEMPDIR: zName = "SQLITE_CANTOPEN_NOTEMPDIR";break;
+ case SQLITE_CANTOPEN_ISDIR: zName = "SQLITE_CANTOPEN_ISDIR"; break;
+ case SQLITE_CANTOPEN_FULLPATH: zName = "SQLITE_CANTOPEN_FULLPATH"; break;
+ case SQLITE_CANTOPEN_CONVPATH: zName = "SQLITE_CANTOPEN_CONVPATH"; break;
+ case SQLITE_PROTOCOL: zName = "SQLITE_PROTOCOL"; break;
+ case SQLITE_EMPTY: zName = "SQLITE_EMPTY"; break;
+ case SQLITE_SCHEMA: zName = "SQLITE_SCHEMA"; break;
+ case SQLITE_TOOBIG: zName = "SQLITE_TOOBIG"; break;
+ case SQLITE_CONSTRAINT: zName = "SQLITE_CONSTRAINT"; break;
+ case SQLITE_CONSTRAINT_UNIQUE: zName = "SQLITE_CONSTRAINT_UNIQUE"; break;
+ case SQLITE_CONSTRAINT_TRIGGER: zName = "SQLITE_CONSTRAINT_TRIGGER";break;
+ case SQLITE_CONSTRAINT_FOREIGNKEY:
+ zName = "SQLITE_CONSTRAINT_FOREIGNKEY"; break;
+ case SQLITE_CONSTRAINT_CHECK: zName = "SQLITE_CONSTRAINT_CHECK"; break;
+ case SQLITE_CONSTRAINT_PRIMARYKEY:
+ zName = "SQLITE_CONSTRAINT_PRIMARYKEY"; break;
+ case SQLITE_CONSTRAINT_NOTNULL: zName = "SQLITE_CONSTRAINT_NOTNULL";break;
+ case SQLITE_CONSTRAINT_COMMITHOOK:
+ zName = "SQLITE_CONSTRAINT_COMMITHOOK"; break;
+ case SQLITE_CONSTRAINT_VTAB: zName = "SQLITE_CONSTRAINT_VTAB"; break;
+ case SQLITE_CONSTRAINT_FUNCTION:
+ zName = "SQLITE_CONSTRAINT_FUNCTION"; break;
+ case SQLITE_CONSTRAINT_ROWID: zName = "SQLITE_CONSTRAINT_ROWID"; break;
+ case SQLITE_MISMATCH: zName = "SQLITE_MISMATCH"; break;
+ case SQLITE_MISUSE: zName = "SQLITE_MISUSE"; break;
+ case SQLITE_NOLFS: zName = "SQLITE_NOLFS"; break;
+ case SQLITE_AUTH: zName = "SQLITE_AUTH"; break;
+ case SQLITE_FORMAT: zName = "SQLITE_FORMAT"; break;
+ case SQLITE_RANGE: zName = "SQLITE_RANGE"; break;
+ case SQLITE_NOTADB: zName = "SQLITE_NOTADB"; break;
+ case SQLITE_ROW: zName = "SQLITE_ROW"; break;
+ case SQLITE_NOTICE: zName = "SQLITE_NOTICE"; break;
+ case SQLITE_NOTICE_RECOVER_WAL: zName = "SQLITE_NOTICE_RECOVER_WAL";break;
+ case SQLITE_NOTICE_RECOVER_ROLLBACK:
+ zName = "SQLITE_NOTICE_RECOVER_ROLLBACK"; break;
+ case SQLITE_WARNING: zName = "SQLITE_WARNING"; break;
+ case SQLITE_WARNING_AUTOINDEX: zName = "SQLITE_WARNING_AUTOINDEX"; break;
+ case SQLITE_DONE: zName = "SQLITE_DONE"; break;
+ }
+ }
+ if( zName==0 ){
+ static char zBuf[50];
+ sqlite3_snprintf(sizeof(zBuf), zBuf, "SQLITE_UNKNOWN(%d)", origRc);
+ zName = zBuf;
+ }
+ return zName;
+}
+#endif
+
+/*
** Return a static string that describes the kind of error specified in the
** argument.
*/
@@ -113702,7 +133484,7 @@ 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)
+#if SQLITE_OS_WIN || HAVE_USLEEP
static const u8 delays[] =
{ 1, 2, 5, 10, 15, 20, 25, 25, 25, 50, 50, 100 };
static const u8 totals[] =
@@ -113760,11 +133542,14 @@ SQLITE_PRIVATE int sqlite3InvokeBusyHandler(BusyHandler *p){
** 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(
+SQLITE_API int SQLITE_STDCALL sqlite3_busy_handler(
sqlite3 *db,
int (*xBusy)(void*,int),
void *pArg
){
+#ifdef SQLITE_ENABLE_API_ARMOR
+ if( !sqlite3SafetyCheckOk(db) ) return SQLITE_MISUSE_BKPT;
+#endif
sqlite3_mutex_enter(db->mutex);
db->busyHandler.xFunc = xBusy;
db->busyHandler.pArg = pArg;
@@ -113780,16 +133565,22 @@ SQLITE_API int sqlite3_busy_handler(
** given callback function with the given argument. The progress callback will
** be invoked every nOps opcodes.
*/
-SQLITE_API void sqlite3_progress_handler(
+SQLITE_API void SQLITE_STDCALL sqlite3_progress_handler(
sqlite3 *db,
int nOps,
int (*xProgress)(void*),
void *pArg
){
+#ifdef SQLITE_ENABLE_API_ARMOR
+ if( !sqlite3SafetyCheckOk(db) ){
+ (void)SQLITE_MISUSE_BKPT;
+ return;
+ }
+#endif
sqlite3_mutex_enter(db->mutex);
if( nOps>0 ){
db->xProgress = xProgress;
- db->nProgressOps = nOps;
+ db->nProgressOps = (unsigned)nOps;
db->pProgressArg = pArg;
}else{
db->xProgress = 0;
@@ -113805,7 +133596,10 @@ SQLITE_API void sqlite3_progress_handler(
** 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){
+SQLITE_API int SQLITE_STDCALL sqlite3_busy_timeout(sqlite3 *db, int ms){
+#ifdef SQLITE_ENABLE_API_ARMOR
+ if( !sqlite3SafetyCheckOk(db) ) return SQLITE_MISUSE_BKPT;
+#endif
if( ms>0 ){
sqlite3_busy_handler(db, sqliteDefaultBusyCallback, (void*)db);
db->busyTimeout = ms;
@@ -113818,7 +133612,13 @@ SQLITE_API int sqlite3_busy_timeout(sqlite3 *db, int ms){
/*
** Cause any pending operation to stop at its earliest opportunity.
*/
-SQLITE_API void sqlite3_interrupt(sqlite3 *db){
+SQLITE_API void SQLITE_STDCALL sqlite3_interrupt(sqlite3 *db){
+#ifdef SQLITE_ENABLE_API_ARMOR
+ if( !sqlite3SafetyCheckOk(db) ){
+ (void)SQLITE_MISUSE_BKPT;
+ return;
+ }
+#endif
db->u1.isInterrupted = 1;
}
@@ -113842,6 +133642,7 @@ SQLITE_PRIVATE int sqlite3CreateFunc(
){
FuncDef *p;
int nName;
+ int extraFlags;
assert( sqlite3_mutex_held(db->mutex) );
if( zFunctionName==0 ||
@@ -113852,6 +133653,10 @@ SQLITE_PRIVATE int sqlite3CreateFunc(
(255<(nName = sqlite3Strlen30( zFunctionName))) ){
return SQLITE_MISUSE_BKPT;
}
+
+ assert( SQLITE_FUNC_CONSTANT==SQLITE_DETERMINISTIC );
+ extraFlags = enc & SQLITE_DETERMINISTIC;
+ enc &= (SQLITE_FUNC_ENCMASK|SQLITE_ANY);
#ifndef SQLITE_OMIT_UTF16
/* If SQLITE_UTF16 is specified as the encoding type, transform this
@@ -113865,10 +133670,10 @@ SQLITE_PRIVATE int sqlite3CreateFunc(
enc = SQLITE_UTF16NATIVE;
}else if( enc==SQLITE_ANY ){
int rc;
- rc = sqlite3CreateFunc(db, zFunctionName, nArg, SQLITE_UTF8,
+ rc = sqlite3CreateFunc(db, zFunctionName, nArg, SQLITE_UTF8|extraFlags,
pUserData, xFunc, xStep, xFinal, pDestructor);
if( rc==SQLITE_OK ){
- rc = sqlite3CreateFunc(db, zFunctionName, nArg, SQLITE_UTF16LE,
+ rc = sqlite3CreateFunc(db, zFunctionName, nArg, SQLITE_UTF16LE|extraFlags,
pUserData, xFunc, xStep, xFinal, pDestructor);
}
if( rc!=SQLITE_OK ){
@@ -113886,9 +133691,9 @@ SQLITE_PRIVATE int sqlite3CreateFunc(
** 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,
+ if( p && (p->funcFlags & SQLITE_FUNC_ENCMASK)==enc && p->nArg==nArg ){
+ if( db->nVdbeActive ){
+ sqlite3ErrorWithMsg(db, SQLITE_BUSY,
"unable to delete/modify user-function due to active statements");
assert( !db->mallocFailed );
return SQLITE_BUSY;
@@ -113911,7 +133716,8 @@ SQLITE_PRIVATE int sqlite3CreateFunc(
pDestructor->nRef++;
}
p->pDestructor = pDestructor;
- p->flags = 0;
+ p->funcFlags = (p->funcFlags & SQLITE_FUNC_ENCMASK) | extraFlags;
+ testcase( p->funcFlags & SQLITE_DETERMINISTIC );
p->xFunc = xFunc;
p->xStep = xStep;
p->xFinalize = xFinal;
@@ -113923,7 +133729,7 @@ SQLITE_PRIVATE int sqlite3CreateFunc(
/*
** Create new user functions.
*/
-SQLITE_API int sqlite3_create_function(
+SQLITE_API int SQLITE_STDCALL sqlite3_create_function(
sqlite3 *db,
const char *zFunc,
int nArg,
@@ -113937,7 +133743,7 @@ SQLITE_API int sqlite3_create_function(
xFinal, 0);
}
-SQLITE_API int sqlite3_create_function_v2(
+SQLITE_API int SQLITE_STDCALL sqlite3_create_function_v2(
sqlite3 *db,
const char *zFunc,
int nArg,
@@ -113950,6 +133756,12 @@ SQLITE_API int sqlite3_create_function_v2(
){
int rc = SQLITE_ERROR;
FuncDestructor *pArg = 0;
+
+#ifdef SQLITE_ENABLE_API_ARMOR
+ if( !sqlite3SafetyCheckOk(db) ){
+ return SQLITE_MISUSE_BKPT;
+ }
+#endif
sqlite3_mutex_enter(db->mutex);
if( xDestroy ){
pArg = (FuncDestructor *)sqlite3DbMallocZero(db, sizeof(FuncDestructor));
@@ -113974,7 +133786,7 @@ SQLITE_API int sqlite3_create_function_v2(
}
#ifndef SQLITE_OMIT_UTF16
-SQLITE_API int sqlite3_create_function16(
+SQLITE_API int SQLITE_STDCALL sqlite3_create_function16(
sqlite3 *db,
const void *zFunctionName,
int nArg,
@@ -113986,6 +133798,10 @@ SQLITE_API int sqlite3_create_function16(
){
int rc;
char *zFunc8;
+
+#ifdef SQLITE_ENABLE_API_ARMOR
+ if( !sqlite3SafetyCheckOk(db) || zFunctionName==0 ) return SQLITE_MISUSE_BKPT;
+#endif
sqlite3_mutex_enter(db->mutex);
assert( !db->mallocFailed );
zFunc8 = sqlite3Utf16to8(db, zFunctionName, -1, SQLITE_UTF16NATIVE);
@@ -114010,13 +133826,19 @@ SQLITE_API int sqlite3_create_function16(
** A global function must exist in order for name resolution to work
** properly.
*/
-SQLITE_API int sqlite3_overload_function(
+SQLITE_API int SQLITE_STDCALL sqlite3_overload_function(
sqlite3 *db,
const char *zName,
int nArg
){
int nName = sqlite3Strlen30(zName);
int rc = SQLITE_OK;
+
+#ifdef SQLITE_ENABLE_API_ARMOR
+ if( !sqlite3SafetyCheckOk(db) || zName==0 || nArg<-2 ){
+ return SQLITE_MISUSE_BKPT;
+ }
+#endif
sqlite3_mutex_enter(db->mutex);
if( sqlite3FindFunction(db, zName, nName, nArg, SQLITE_UTF8, 0)==0 ){
rc = sqlite3CreateFunc(db, zName, nArg, SQLITE_UTF8,
@@ -114036,8 +133858,15 @@ SQLITE_API int sqlite3_overload_function(
** 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){
+SQLITE_API void *SQLITE_STDCALL sqlite3_trace(sqlite3 *db, void (*xTrace)(void*,const char*), void *pArg){
void *pOld;
+
+#ifdef SQLITE_ENABLE_API_ARMOR
+ if( !sqlite3SafetyCheckOk(db) ){
+ (void)SQLITE_MISUSE_BKPT;
+ return 0;
+ }
+#endif
sqlite3_mutex_enter(db->mutex);
pOld = db->pTraceArg;
db->xTrace = xTrace;
@@ -114053,12 +133882,19 @@ SQLITE_API void *sqlite3_trace(sqlite3 *db, void (*xTrace)(void*,const char*), v
** 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(
+SQLITE_API void *SQLITE_STDCALL sqlite3_profile(
sqlite3 *db,
void (*xProfile)(void*,const char*,sqlite_uint64),
void *pArg
){
void *pOld;
+
+#ifdef SQLITE_ENABLE_API_ARMOR
+ if( !sqlite3SafetyCheckOk(db) ){
+ (void)SQLITE_MISUSE_BKPT;
+ return 0;
+ }
+#endif
sqlite3_mutex_enter(db->mutex);
pOld = db->pProfileArg;
db->xProfile = xProfile;
@@ -114073,12 +133909,19 @@ SQLITE_API void *sqlite3_profile(
** If the invoked function returns non-zero, then the commit becomes a
** rollback.
*/
-SQLITE_API void *sqlite3_commit_hook(
+SQLITE_API void *SQLITE_STDCALL 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;
+
+#ifdef SQLITE_ENABLE_API_ARMOR
+ if( !sqlite3SafetyCheckOk(db) ){
+ (void)SQLITE_MISUSE_BKPT;
+ return 0;
+ }
+#endif
sqlite3_mutex_enter(db->mutex);
pOld = db->pCommitArg;
db->xCommitCallback = xCallback;
@@ -114091,12 +133934,19 @@ SQLITE_API void *sqlite3_commit_hook(
** 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(
+SQLITE_API void *SQLITE_STDCALL 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;
+
+#ifdef SQLITE_ENABLE_API_ARMOR
+ if( !sqlite3SafetyCheckOk(db) ){
+ (void)SQLITE_MISUSE_BKPT;
+ return 0;
+ }
+#endif
sqlite3_mutex_enter(db->mutex);
pRet = db->pUpdateArg;
db->xUpdateCallback = xCallback;
@@ -114109,12 +133959,19 @@ SQLITE_API void *sqlite3_update_hook(
** Register a callback to be invoked each time a transaction is rolled
** back by this database connection.
*/
-SQLITE_API void *sqlite3_rollback_hook(
+SQLITE_API void *SQLITE_STDCALL sqlite3_rollback_hook(
sqlite3 *db, /* Attach the hook to this database */
void (*xCallback)(void*), /* Callback function */
void *pArg /* Argument to the function */
){
void *pRet;
+
+#ifdef SQLITE_ENABLE_API_ARMOR
+ if( !sqlite3SafetyCheckOk(db) ){
+ (void)SQLITE_MISUSE_BKPT;
+ return 0;
+ }
+#endif
sqlite3_mutex_enter(db->mutex);
pRet = db->pRollbackArg;
db->xRollbackCallback = xCallback;
@@ -114156,11 +134013,14 @@ SQLITE_PRIVATE int sqlite3WalDefaultHook(
** using sqlite3_wal_hook() disables the automatic checkpoint mechanism
** configured by this function.
*/
-SQLITE_API int sqlite3_wal_autocheckpoint(sqlite3 *db, int nFrame){
+SQLITE_API int SQLITE_STDCALL sqlite3_wal_autocheckpoint(sqlite3 *db, int nFrame){
#ifdef SQLITE_OMIT_WAL
UNUSED_PARAMETER(db);
UNUSED_PARAMETER(nFrame);
#else
+#ifdef SQLITE_ENABLE_API_ARMOR
+ if( !sqlite3SafetyCheckOk(db) ) return SQLITE_MISUSE_BKPT;
+#endif
if( nFrame>0 ){
sqlite3_wal_hook(db, sqlite3WalDefaultHook, SQLITE_INT_TO_PTR(nFrame));
}else{
@@ -114174,13 +134034,19 @@ SQLITE_API int sqlite3_wal_autocheckpoint(sqlite3 *db, int nFrame){
** 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(
+SQLITE_API void *SQLITE_STDCALL 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;
+#ifdef SQLITE_ENABLE_API_ARMOR
+ if( !sqlite3SafetyCheckOk(db) ){
+ (void)SQLITE_MISUSE_BKPT;
+ return 0;
+ }
+#endif
sqlite3_mutex_enter(db->mutex);
pRet = db->pWalArg;
db->xWalCallback = xCallback;
@@ -114195,7 +134061,7 @@ SQLITE_API void *sqlite3_wal_hook(
/*
** Checkpoint database zDb.
*/
-SQLITE_API int sqlite3_wal_checkpoint_v2(
+SQLITE_API int SQLITE_STDCALL sqlite3_wal_checkpoint_v2(
sqlite3 *db, /* Database handle */
const char *zDb, /* Name of attached database (or NULL) */
int eMode, /* SQLITE_CHECKPOINT_* value */
@@ -114208,14 +134074,21 @@ SQLITE_API int sqlite3_wal_checkpoint_v2(
int rc; /* Return code */
int iDb = SQLITE_MAX_ATTACHED; /* sqlite3.aDb[] index of db to checkpoint */
+#ifdef SQLITE_ENABLE_API_ARMOR
+ if( !sqlite3SafetyCheckOk(db) ) return SQLITE_MISUSE_BKPT;
+#endif
+
/* 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 ){
+ assert( SQLITE_CHECKPOINT_PASSIVE==0 );
+ assert( SQLITE_CHECKPOINT_FULL==1 );
+ assert( SQLITE_CHECKPOINT_RESTART==2 );
+ assert( SQLITE_CHECKPOINT_TRUNCATE==3 );
+ if( eMode<SQLITE_CHECKPOINT_PASSIVE || eMode>SQLITE_CHECKPOINT_TRUNCATE ){
+ /* EVIDENCE-OF: R-03996-12088 The M parameter must be a valid checkpoint
+ ** mode: */
return SQLITE_MISUSE;
}
@@ -114225,10 +134098,11 @@ SQLITE_API int sqlite3_wal_checkpoint_v2(
}
if( iDb<0 ){
rc = SQLITE_ERROR;
- sqlite3Error(db, SQLITE_ERROR, "unknown database: %s", zDb);
+ sqlite3ErrorWithMsg(db, SQLITE_ERROR, "unknown database: %s", zDb);
}else{
+ db->busyHandler.nBusy = 0;
rc = sqlite3Checkpoint(db, iDb, eMode, pnLog, pnCkpt);
- sqlite3Error(db, rc, 0);
+ sqlite3Error(db, rc);
}
rc = sqlite3ApiExit(db, rc);
sqlite3_mutex_leave(db->mutex);
@@ -114242,8 +134116,10 @@ SQLITE_API int sqlite3_wal_checkpoint_v2(
** 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);
+SQLITE_API int SQLITE_STDCALL sqlite3_wal_checkpoint(sqlite3 *db, const char *zDb){
+ /* EVIDENCE-OF: R-41613-20553 The sqlite3_wal_checkpoint(D,X) is equivalent to
+ ** sqlite3_wal_checkpoint_v2(D,X,SQLITE_CHECKPOINT_PASSIVE,0,0). */
+ return sqlite3_wal_checkpoint_v2(db,zDb,SQLITE_CHECKPOINT_PASSIVE,0,0);
}
#ifndef SQLITE_OMIT_WAL
@@ -114318,9 +134194,11 @@ SQLITE_PRIVATE int sqlite3TempInMemory(const sqlite3 *db){
return ( db->temp_store!=1 );
#endif
#if SQLITE_TEMP_STORE==3
+ UNUSED_PARAMETER(db);
return 1;
#endif
#if SQLITE_TEMP_STORE<1 || SQLITE_TEMP_STORE>3
+ UNUSED_PARAMETER(db);
return 0;
#endif
}
@@ -114329,7 +134207,7 @@ SQLITE_PRIVATE int sqlite3TempInMemory(const sqlite3 *db){
** Return UTF-8 encoded English language explanation of the most recent
** error.
*/
-SQLITE_API const char *sqlite3_errmsg(sqlite3 *db){
+SQLITE_API const char *SQLITE_STDCALL sqlite3_errmsg(sqlite3 *db){
const char *z;
if( !db ){
return sqlite3ErrStr(SQLITE_NOMEM);
@@ -114341,6 +134219,7 @@ SQLITE_API const char *sqlite3_errmsg(sqlite3 *db){
if( db->mallocFailed ){
z = sqlite3ErrStr(SQLITE_NOMEM);
}else{
+ testcase( db->pErr==0 );
z = (char*)sqlite3_value_text(db->pErr);
assert( !db->mallocFailed );
if( z==0 ){
@@ -114356,7 +134235,7 @@ SQLITE_API const char *sqlite3_errmsg(sqlite3 *db){
** Return UTF-16 encoded English language explanation of the most recent
** error.
*/
-SQLITE_API const void *sqlite3_errmsg16(sqlite3 *db){
+SQLITE_API const void *SQLITE_STDCALL sqlite3_errmsg16(sqlite3 *db){
static const u16 outOfMem[] = {
'o', 'u', 't', ' ', 'o', 'f', ' ', 'm', 'e', 'm', 'o', 'r', 'y', 0
};
@@ -114382,8 +134261,7 @@ SQLITE_API const void *sqlite3_errmsg16(sqlite3 *db){
}else{
z = sqlite3_value_text16(db->pErr);
if( z==0 ){
- sqlite3ValueSetStr(db->pErr, -1, sqlite3ErrStr(db->errCode),
- SQLITE_UTF8, SQLITE_STATIC);
+ sqlite3ErrorWithMsg(db, db->errCode, sqlite3ErrStr(db->errCode));
z = sqlite3_value_text16(db->pErr);
}
/* A malloc() may have failed within the call to sqlite3_value_text16()
@@ -114402,7 +134280,7 @@ SQLITE_API const void *sqlite3_errmsg16(sqlite3 *db){
** 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){
+SQLITE_API int SQLITE_STDCALL sqlite3_errcode(sqlite3 *db){
if( db && !sqlite3SafetyCheckSickOrOk(db) ){
return SQLITE_MISUSE_BKPT;
}
@@ -114411,7 +134289,7 @@ SQLITE_API int sqlite3_errcode(sqlite3 *db){
}
return db->errCode & db->errMask;
}
-SQLITE_API int sqlite3_extended_errcode(sqlite3 *db){
+SQLITE_API int SQLITE_STDCALL sqlite3_extended_errcode(sqlite3 *db){
if( db && !sqlite3SafetyCheckSickOrOk(db) ){
return SQLITE_MISUSE_BKPT;
}
@@ -114426,7 +134304,7 @@ SQLITE_API int sqlite3_extended_errcode(sqlite3 *db){
** argument. For now, this simply calls the internal sqlite3ErrStr()
** function.
*/
-SQLITE_API const char *sqlite3_errstr(int rc){
+SQLITE_API const char *SQLITE_STDCALL sqlite3_errstr(int rc){
return sqlite3ErrStr(rc);
}
@@ -114444,7 +134322,6 @@ static int createCollation(
){
CollSeq *pColl;
int enc2;
- int nName = sqlite3Strlen30(zName);
assert( sqlite3_mutex_held(db->mutex) );
@@ -114468,8 +134345,8 @@ static int createCollation(
*/
pColl = sqlite3FindCollSeq(db, (u8)enc2, zName, 0);
if( pColl && pColl->xCmp ){
- if( db->activeVdbeCnt ){
- sqlite3Error(db, SQLITE_BUSY,
+ if( db->nVdbeActive ){
+ sqlite3ErrorWithMsg(db, SQLITE_BUSY,
"unable to delete/modify collation sequence due to active statements");
return SQLITE_BUSY;
}
@@ -114482,7 +134359,7 @@ static int createCollation(
** to be called.
*/
if( (pColl->enc & ~SQLITE_UTF16_ALIGNED)==enc2 ){
- CollSeq *aColl = sqlite3HashFind(&db->aCollSeq, zName, nName);
+ CollSeq *aColl = sqlite3HashFind(&db->aCollSeq, zName);
int j;
for(j=0; j<3; j++){
CollSeq *p = &aColl[j];
@@ -114502,7 +134379,7 @@ static int createCollation(
pColl->pUser = pCtx;
pColl->xDel = xDel;
pColl->enc = (u8)(enc2 | (enc & SQLITE_UTF16_ALIGNED));
- sqlite3Error(db, SQLITE_OK, 0);
+ sqlite3Error(db, SQLITE_OK);
return SQLITE_OK;
}
@@ -114522,8 +134399,9 @@ static const int aHardLimit[] = {
SQLITE_MAX_FUNCTION_ARG,
SQLITE_MAX_ATTACHED,
SQLITE_MAX_LIKE_PATTERN_LENGTH,
- SQLITE_MAX_VARIABLE_NUMBER,
+ SQLITE_MAX_VARIABLE_NUMBER, /* IMP: R-38091-32352 */
SQLITE_MAX_TRIGGER_DEPTH,
+ SQLITE_MAX_WORKER_THREADS,
};
/*
@@ -114547,8 +134425,8 @@ static const int aHardLimit[] = {
#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
+#if SQLITE_MAX_ATTACHED<0 || SQLITE_MAX_ATTACHED>125
+# error SQLITE_MAX_ATTACHED must be between 0 and 125
#endif
#if SQLITE_MAX_LIKE_PATTERN_LENGTH<1
# error SQLITE_MAX_LIKE_PATTERN_LENGTH must be at least 1
@@ -114559,6 +134437,9 @@ static const int aHardLimit[] = {
#if SQLITE_MAX_TRIGGER_DEPTH<1
# error SQLITE_MAX_TRIGGER_DEPTH must be at least 1
#endif
+#if SQLITE_MAX_WORKER_THREADS<0 || SQLITE_MAX_WORKER_THREADS>50
+# error SQLITE_MAX_WORKER_THREADS must be between 0 and 50
+#endif
/*
@@ -114571,9 +134452,15 @@ static const int aHardLimit[] = {
** It merely prevents new constructs that exceed the limit
** from forming.
*/
-SQLITE_API int sqlite3_limit(sqlite3 *db, int limitId, int newLimit){
+SQLITE_API int SQLITE_STDCALL sqlite3_limit(sqlite3 *db, int limitId, int newLimit){
int oldLimit;
+#ifdef SQLITE_ENABLE_API_ARMOR
+ if( !sqlite3SafetyCheckOk(db) ){
+ (void)SQLITE_MISUSE_BKPT;
+ return -1;
+ }
+#endif
/* 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
@@ -114592,7 +134479,8 @@ SQLITE_API int sqlite3_limit(sqlite3 *db, int limitId, int newLimit){
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) );
+ assert( aHardLimit[SQLITE_LIMIT_WORKER_THREADS]==SQLITE_MAX_WORKER_THREADS );
+ assert( SQLITE_LIMIT_WORKER_THREADS==(SQLITE_N_LIMIT-1) );
if( limitId<0 || limitId>=SQLITE_N_LIMIT ){
@@ -114649,37 +134537,50 @@ SQLITE_PRIVATE int sqlite3ParseUri(
assert( *pzErrMsg==0 );
- if( ((flags & SQLITE_OPEN_URI) || sqlite3GlobalConfig.bOpenUri)
- && nUri>=5 && memcmp(zUri, "file:", 5)==0
+ if( ((flags & SQLITE_OPEN_URI) /* IMP: R-48725-32206 */
+ || sqlite3GlobalConfig.bOpenUri) /* IMP: R-51689-46548 */
+ && nUri>=5 && memcmp(zUri, "file:", 5)==0 /* IMP: R-57884-37496 */
){
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 */
+ u64 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);
+ zFile = sqlite3_malloc64(nByte);
if( !zFile ) return SQLITE_NOMEM;
+ iIn = 5;
+#ifdef SQLITE_ALLOW_URI_AUTHORITY
+ if( strncmp(zUri+5, "///", 3)==0 ){
+ iIn = 7;
+ /* The following condition causes URIs with five leading / characters
+ ** like file://///host/path to be converted into UNCs like //host/path.
+ ** The correct URI for that UNC has only two or four leading / characters
+ ** file://host/path or file:////host/path. But 5 leading slashes is a
+ ** common error, we are told, so we handle it as a special case. */
+ if( strncmp(zUri+7, "///", 3)==0 ){ iIn++; }
+ }else if( strncmp(zUri+5, "//localhost/", 12)==0 ){
+ iIn = 16;
+ }
+#else
/* 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;
}
+#endif
/* Copy the filename and any query parameters into the zFile buffer.
** Decode %HH escape codes along the way.
@@ -114817,7 +134718,7 @@ SQLITE_PRIVATE int sqlite3ParseUri(
}
}else{
- zFile = sqlite3_malloc(nUri+2);
+ zFile = sqlite3_malloc64(nUri+2);
if( !zFile ) return SQLITE_NOMEM;
memcpy(zFile, zUri, nUri);
zFile[nUri] = '\0';
@@ -114858,6 +134759,9 @@ static int openDatabase(
char *zOpen = 0; /* Filename argument to pass to BtreeOpen() */
char *zErrMsg = 0; /* Error message from sqlite3ParseUri() */
+#ifdef SQLITE_ENABLE_API_ARMOR
+ if( ppDb==0 ) return SQLITE_MISUSE_BKPT;
+#endif
*ppDb = 0;
#ifndef SQLITE_OMIT_AUTOINIT
rc = sqlite3_initialize();
@@ -114880,7 +134784,9 @@ static int openDatabase(
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( ((1<<(flags&7)) & 0x46)==0 ){
+ return SQLITE_MISUSE_BKPT; /* IMP: R-65497-44594 */
+ }
if( sqlite3GlobalConfig.bCoreMutex==0 ){
isThreadsafe = 0;
@@ -114939,10 +134845,19 @@ static int openDatabase(
assert( sizeof(db->aLimit)==sizeof(aHardLimit) );
memcpy(db->aLimit, aHardLimit, sizeof(db->aLimit));
+ db->aLimit[SQLITE_LIMIT_WORKER_THREADS] = SQLITE_DEFAULT_WORKER_THREADS;
db->autoCommit = 1;
db->nextAutovac = -1;
+ db->szMmap = sqlite3GlobalConfig.szMmap;
db->nextPagesize = 0;
- db->flags |= SQLITE_ShortColNames | SQLITE_AutoIndex | SQLITE_EnableTrigger
+ db->nMaxSorterMmap = 0x7FFFFFFF;
+ db->flags |= SQLITE_ShortColNames | SQLITE_EnableTrigger | SQLITE_CacheSpill
+#if !defined(SQLITE_DEFAULT_AUTOMATIC_INDEX) || SQLITE_DEFAULT_AUTOMATIC_INDEX
+ | SQLITE_AutoIndex
+#endif
+#if SQLITE_DEFAULT_CKPTFULLFSYNC
+ | SQLITE_CkptFullFSync
+#endif
#if SQLITE_DEFAULT_FILE_FORMAT<4
| SQLITE_LegacyFileFmt
#endif
@@ -114955,6 +134870,12 @@ static int openDatabase(
#if defined(SQLITE_DEFAULT_FOREIGN_KEYS) && SQLITE_DEFAULT_FOREIGN_KEYS
| SQLITE_ForeignKeys
#endif
+#if defined(SQLITE_REVERSE_UNORDERED_SELECTS)
+ | SQLITE_ReverseOrder
+#endif
+#if defined(SQLITE_ENABLE_OVERSIZE_CELL_CHECK)
+ | SQLITE_CellSizeCk
+#endif
;
sqlite3HashInit(&db->aCollSeq);
#ifndef SQLITE_OMIT_VIRTUALTABLE
@@ -114964,26 +134885,30 @@ static int openDatabase(
/* 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.
+ **
+ ** EVIDENCE-OF: R-52786-44878 SQLite defines three built-in collating
+ ** functions:
*/
- 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, sqlite3StrBINARY, SQLITE_UTF8, 0, binCollFunc, 0);
+ createCollation(db, sqlite3StrBINARY, SQLITE_UTF16BE, 0, binCollFunc, 0);
+ createCollation(db, sqlite3StrBINARY, SQLITE_UTF16LE, 0, binCollFunc, 0);
+ createCollation(db, "NOCASE", SQLITE_UTF8, 0, nocaseCollatingFunc, 0);
createCollation(db, "RTRIM", SQLITE_UTF8, (void*)1, binCollFunc, 0);
if( db->mallocFailed ){
goto opendb_out;
}
- db->pDfltColl = sqlite3FindCollSeq(db, SQLITE_UTF8, "BINARY", 0);
+ /* EVIDENCE-OF: R-08308-17224 The default collating function for all
+ ** strings is BINARY.
+ */
+ db->pDfltColl = sqlite3FindCollSeq(db, SQLITE_UTF8, sqlite3StrBINARY, 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);
+ sqlite3ErrorWithMsg(db, rc, zErrMsg ? "%s" : 0, zErrMsg);
sqlite3_free(zErrMsg);
goto opendb_out;
}
@@ -114995,13 +134920,15 @@ static int openDatabase(
if( rc==SQLITE_IOERR_NOMEM ){
rc = SQLITE_NOMEM;
}
- sqlite3Error(db, rc, 0);
+ sqlite3Error(db, rc);
goto opendb_out;
}
+ sqlite3BtreeEnter(db->aDb[0].pBt);
db->aDb[0].pSchema = sqlite3SchemaGet(db, db->aDb[0].pBt);
+ if( !db->mallocFailed ) ENC(db) = SCHEMA_ENC(db);
+ sqlite3BtreeLeave(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.
*/
@@ -115019,7 +134946,7 @@ static int openDatabase(
** database schema yet. This is delayed until the first time the database
** is accessed.
*/
- sqlite3Error(db, SQLITE_OK, 0);
+ sqlite3Error(db, SQLITE_OK);
sqlite3RegisterBuiltinFunctions(db);
/* Load automatic extensions - extensions that have been registered
@@ -115048,12 +134975,18 @@ static int openDatabase(
}
#endif
-#ifdef SQLITE_ENABLE_FTS3
+#ifdef SQLITE_ENABLE_FTS3 /* automatically defined by SQLITE_ENABLE_FTS4 */
if( !db->mallocFailed && rc==SQLITE_OK ){
rc = sqlite3Fts3Init(db);
}
#endif
+#ifdef SQLITE_ENABLE_FTS5
+ if( !db->mallocFailed && rc==SQLITE_OK ){
+ rc = sqlite3Fts5Init(db);
+ }
+#endif
+
#ifdef SQLITE_ENABLE_ICU
if( !db->mallocFailed && rc==SQLITE_OK ){
rc = sqlite3IcuInit(db);
@@ -115066,7 +134999,17 @@ static int openDatabase(
}
#endif
- sqlite3Error(db, rc, 0);
+#ifdef SQLITE_ENABLE_DBSTAT_VTAB
+ if( !db->mallocFailed && rc==SQLITE_OK){
+ rc = sqlite3DbstatRegister(db);
+ }
+#endif
+
+#ifdef SQLITE_ENABLE_JSON1
+ if( !db->mallocFailed && rc==SQLITE_OK){
+ rc = sqlite3Json1Init(db);
+ }
+#endif
/* -DSQLITE_DEFAULT_LOCKING_MODE=1 makes EXCLUSIVE the default locking
** mode. -DSQLITE_DEFAULT_LOCKING_MODE=0 make NORMAL the default locking
@@ -115078,6 +135021,8 @@ static int openDatabase(
SQLITE_DEFAULT_LOCKING_MODE);
#endif
+ if( rc ) sqlite3Error(db, rc);
+
/* Enable the lookaside-malloc subsystem */
setupLookaside(db, 0, sqlite3GlobalConfig.szLookaside,
sqlite3GlobalConfig.nLookaside);
@@ -115085,9 +135030,9 @@ static int openDatabase(
sqlite3_wal_autocheckpoint(db, SQLITE_DEFAULT_WAL_AUTOCHECKPOINT);
opendb_out:
- sqlite3_free(zOpen);
if( db ){
- assert( db->mutex!=0 || isThreadsafe==0 || sqlite3GlobalConfig.bFullMutex==0 );
+ assert( db->mutex!=0 || isThreadsafe==0
+ || sqlite3GlobalConfig.bFullMutex==0 );
sqlite3_mutex_leave(db->mutex);
}
rc = sqlite3_errcode(db);
@@ -115106,20 +135051,36 @@ opendb_out:
sqlite3GlobalConfig.xSqllog(pArg, db, zFilename, 0);
}
#endif
- return sqlite3ApiExit(0, rc);
+#if defined(SQLITE_HAS_CODEC)
+ if( rc==SQLITE_OK ){
+ const char *zHexKey = sqlite3_uri_parameter(zOpen, "hexkey");
+ if( zHexKey && zHexKey[0] ){
+ u8 iByte;
+ int i;
+ char zKey[40];
+ for(i=0, iByte=0; i<sizeof(zKey)*2 && sqlite3Isxdigit(zHexKey[i]); i++){
+ iByte = (iByte<<4) + sqlite3HexToInt(zHexKey[i]);
+ if( (i&1)!=0 ) zKey[i/2] = iByte;
+ }
+ sqlite3_key_v2(db, 0, zKey, i/2);
+ }
+ }
+#endif
+ sqlite3_free(zOpen);
+ return rc & 0xff;
}
/*
** Open a new database handle.
*/
-SQLITE_API int sqlite3_open(
+SQLITE_API int SQLITE_STDCALL sqlite3_open(
const char *zFilename,
sqlite3 **ppDb
){
return openDatabase(zFilename, ppDb,
SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE, 0);
}
-SQLITE_API int sqlite3_open_v2(
+SQLITE_API int SQLITE_STDCALL sqlite3_open_v2(
const char *filename, /* Database filename (UTF-8) */
sqlite3 **ppDb, /* OUT: SQLite db handle */
int flags, /* Flags */
@@ -115132,7 +135093,7 @@ SQLITE_API int sqlite3_open_v2(
/*
** Open a new database handle.
*/
-SQLITE_API int sqlite3_open16(
+SQLITE_API int SQLITE_STDCALL sqlite3_open16(
const void *zFilename,
sqlite3 **ppDb
){
@@ -115140,13 +135101,15 @@ SQLITE_API int sqlite3_open16(
sqlite3_value *pVal;
int rc;
- assert( zFilename );
- assert( ppDb );
+#ifdef SQLITE_ENABLE_API_ARMOR
+ if( ppDb==0 ) return SQLITE_MISUSE_BKPT;
+#endif
*ppDb = 0;
#ifndef SQLITE_OMIT_AUTOINIT
rc = sqlite3_initialize();
if( rc ) return rc;
#endif
+ if( zFilename==0 ) zFilename = "\000\000";
pVal = sqlite3ValueNew(0);
sqlite3ValueSetStr(pVal, -1, zFilename, SQLITE_UTF16NATIVE, SQLITE_STATIC);
zFilename8 = sqlite3ValueText(pVal, SQLITE_UTF8);
@@ -115155,40 +135118,34 @@ SQLITE_API int sqlite3_open16(
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;
+ SCHEMA_ENC(*ppDb) = ENC(*ppDb) = SQLITE_UTF16NATIVE;
}
}else{
rc = SQLITE_NOMEM;
}
sqlite3ValueFree(pVal);
- return sqlite3ApiExit(0, rc);
+ return rc & 0xff;
}
#endif /* SQLITE_OMIT_UTF16 */
/*
** Register a new collation sequence with the database handle db.
*/
-SQLITE_API int sqlite3_create_collation(
+SQLITE_API int SQLITE_STDCALL 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;
+ return sqlite3_create_collation_v2(db, zName, enc, pCtx, xCompare, 0);
}
/*
** Register a new collation sequence with the database handle db.
*/
-SQLITE_API int sqlite3_create_collation_v2(
+SQLITE_API int SQLITE_STDCALL sqlite3_create_collation_v2(
sqlite3* db,
const char *zName,
int enc,
@@ -115197,6 +135154,10 @@ SQLITE_API int sqlite3_create_collation_v2(
void(*xDel)(void*)
){
int rc;
+
+#ifdef SQLITE_ENABLE_API_ARMOR
+ if( !sqlite3SafetyCheckOk(db) || zName==0 ) return SQLITE_MISUSE_BKPT;
+#endif
sqlite3_mutex_enter(db->mutex);
assert( !db->mallocFailed );
rc = createCollation(db, zName, (u8)enc, pCtx, xCompare, xDel);
@@ -115209,7 +135170,7 @@ SQLITE_API int sqlite3_create_collation_v2(
/*
** Register a new collation sequence with the database handle db.
*/
-SQLITE_API int sqlite3_create_collation16(
+SQLITE_API int SQLITE_STDCALL sqlite3_create_collation16(
sqlite3* db,
const void *zName,
int enc,
@@ -115218,6 +135179,10 @@ SQLITE_API int sqlite3_create_collation16(
){
int rc = SQLITE_OK;
char *zName8;
+
+#ifdef SQLITE_ENABLE_API_ARMOR
+ if( !sqlite3SafetyCheckOk(db) || zName==0 ) return SQLITE_MISUSE_BKPT;
+#endif
sqlite3_mutex_enter(db->mutex);
assert( !db->mallocFailed );
zName8 = sqlite3Utf16to8(db, zName, -1, SQLITE_UTF16NATIVE);
@@ -115235,11 +135200,14 @@ SQLITE_API int sqlite3_create_collation16(
** Register a collation sequence factory callback with the database handle
** db. Replace any previously installed collation sequence factory.
*/
-SQLITE_API int sqlite3_collation_needed(
+SQLITE_API int SQLITE_STDCALL sqlite3_collation_needed(
sqlite3 *db,
void *pCollNeededArg,
void(*xCollNeeded)(void*,sqlite3*,int eTextRep,const char*)
){
+#ifdef SQLITE_ENABLE_API_ARMOR
+ if( !sqlite3SafetyCheckOk(db) ) return SQLITE_MISUSE_BKPT;
+#endif
sqlite3_mutex_enter(db->mutex);
db->xCollNeeded = xCollNeeded;
db->xCollNeeded16 = 0;
@@ -115253,11 +135221,14 @@ SQLITE_API int sqlite3_collation_needed(
** Register a collation sequence factory callback with the database handle
** db. Replace any previously installed collation sequence factory.
*/
-SQLITE_API int sqlite3_collation_needed16(
+SQLITE_API int SQLITE_STDCALL sqlite3_collation_needed16(
sqlite3 *db,
void *pCollNeededArg,
void(*xCollNeeded16)(void*,sqlite3*,int eTextRep,const void*)
){
+#ifdef SQLITE_ENABLE_API_ARMOR
+ if( !sqlite3SafetyCheckOk(db) ) return SQLITE_MISUSE_BKPT;
+#endif
sqlite3_mutex_enter(db->mutex);
db->xCollNeeded = 0;
db->xCollNeeded16 = xCollNeeded16;
@@ -115272,7 +135243,7 @@ SQLITE_API int sqlite3_collation_needed16(
** 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){
+SQLITE_API int SQLITE_STDCALL sqlite3_global_recover(void){
return SQLITE_OK;
}
#endif
@@ -115282,17 +135253,21 @@ SQLITE_API int sqlite3_global_recover(void){
** 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){
+SQLITE_API int SQLITE_STDCALL sqlite3_get_autocommit(sqlite3 *db){
+#ifdef SQLITE_ENABLE_API_ARMOR
+ if( !sqlite3SafetyCheckOk(db) ){
+ (void)SQLITE_MISUSE_BKPT;
+ return 0;
+ }
+#endif
return db->autoCommit;
}
/*
-** The following routines are subtitutes for constants SQLITE_CORRUPT,
+** The following routines are substitutes for constants SQLITE_CORRUPT,
** SQLITE_MISUSE, SQLITE_CANTOPEN, SQLITE_IOERR and possibly other error
-** constants. They server two purposes:
+** constants. They serve two purposes:
**
** 1. Serve as a convenient place to set a breakpoint in a debugger
** to detect when version error conditions occurs.
@@ -115331,7 +135306,7 @@ SQLITE_PRIVATE int sqlite3CantopenError(int lineno){
** 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){
+SQLITE_API void SQLITE_STDCALL sqlite3_thread_cleanup(void){
}
#endif
@@ -115339,8 +135314,7 @@ SQLITE_API void sqlite3_thread_cleanup(void){
** 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(
+SQLITE_API int SQLITE_STDCALL sqlite3_table_column_metadata(
sqlite3 *db, /* Connection handle */
const char *zDbName, /* Database name or NULL */
const char *zTableName, /* Table name */
@@ -115355,14 +135329,20 @@ SQLITE_API int sqlite3_table_column_metadata(
char *zErrMsg = 0;
Table *pTab = 0;
Column *pCol = 0;
- int iCol;
-
+ int iCol = 0;
char const *zDataType = 0;
char const *zCollSeq = 0;
int notnull = 0;
int primarykey = 0;
int autoinc = 0;
+
+#ifdef SQLITE_ENABLE_API_ARMOR
+ if( !sqlite3SafetyCheckOk(db) || zTableName==0 ){
+ return SQLITE_MISUSE_BKPT;
+ }
+#endif
+
/* Ensure the database schema has been loaded */
sqlite3_mutex_enter(db->mutex);
sqlite3BtreeEnterAll(db);
@@ -115379,11 +135359,8 @@ SQLITE_API int sqlite3_table_column_metadata(
}
/* Find the column for which info is requested */
- if( sqlite3IsRowid(zColumnName) ){
- iCol = pTab->iPKey;
- if( iCol>=0 ){
- pCol = &pTab->aCol[iCol];
- }
+ if( zColumnName==0 ){
+ /* Query for existance of table only */
}else{
for(iCol=0; iCol<pTab->nCol; iCol++){
pCol = &pTab->aCol[iCol];
@@ -115392,8 +135369,13 @@ SQLITE_API int sqlite3_table_column_metadata(
}
}
if( iCol==pTab->nCol ){
- pTab = 0;
- goto error_out;
+ if( HasRowid(pTab) && sqlite3IsRowid(zColumnName) ){
+ iCol = pTab->iPKey;
+ pCol = iCol>=0 ? &pTab->aCol[iCol] : 0;
+ }else{
+ pTab = 0;
+ goto error_out;
+ }
}
}
@@ -115418,7 +135400,7 @@ SQLITE_API int sqlite3_table_column_metadata(
primarykey = 1;
}
if( !zCollSeq ){
- zCollSeq = "BINARY";
+ zCollSeq = sqlite3StrBINARY;
}
error_out:
@@ -115440,18 +135422,17 @@ error_out:
zColumnName);
rc = SQLITE_ERROR;
}
- sqlite3Error(db, rc, (zErrMsg?"%s":0), zErrMsg);
+ sqlite3ErrorWithMsg(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){
+SQLITE_API int SQLITE_STDCALL sqlite3_sleep(int ms){
sqlite3_vfs *pVfs;
int rc;
pVfs = sqlite3_vfs_find(0);
@@ -115467,7 +135448,10 @@ SQLITE_API int sqlite3_sleep(int ms){
/*
** Enable or disable the extended result codes.
*/
-SQLITE_API int sqlite3_extended_result_codes(sqlite3 *db, int onoff){
+SQLITE_API int SQLITE_STDCALL sqlite3_extended_result_codes(sqlite3 *db, int onoff){
+#ifdef SQLITE_ENABLE_API_ARMOR
+ if( !sqlite3SafetyCheckOk(db) ) return SQLITE_MISUSE_BKPT;
+#endif
sqlite3_mutex_enter(db->mutex);
db->errMask = onoff ? 0xffffffff : 0xff;
sqlite3_mutex_leave(db->mutex);
@@ -115477,10 +135461,13 @@ SQLITE_API int sqlite3_extended_result_codes(sqlite3 *db, int onoff){
/*
** Invoke the xFileControl method on a particular database.
*/
-SQLITE_API int sqlite3_file_control(sqlite3 *db, const char *zDbName, int op, void *pArg){
+SQLITE_API int SQLITE_STDCALL sqlite3_file_control(sqlite3 *db, const char *zDbName, int op, void *pArg){
int rc = SQLITE_ERROR;
Btree *pBtree;
+#ifdef SQLITE_ENABLE_API_ARMOR
+ if( !sqlite3SafetyCheckOk(db) ) return SQLITE_MISUSE_BKPT;
+#endif
sqlite3_mutex_enter(db->mutex);
pBtree = sqlite3DbNameToBtree(db, zDbName);
if( pBtree ){
@@ -115494,6 +135481,12 @@ SQLITE_API int sqlite3_file_control(sqlite3 *db, const char *zDbName, int op, vo
if( op==SQLITE_FCNTL_FILE_POINTER ){
*(sqlite3_file**)pArg = fd;
rc = SQLITE_OK;
+ }else if( op==SQLITE_FCNTL_VFS_POINTER ){
+ *(sqlite3_vfs**)pArg = sqlite3PagerVfs(pPager);
+ rc = SQLITE_OK;
+ }else if( op==SQLITE_FCNTL_JOURNAL_POINTER ){
+ *(sqlite3_file**)pArg = sqlite3PagerJrnlFile(pPager);
+ rc = SQLITE_OK;
}else if( fd->pMethods ){
rc = sqlite3OsFileControl(fd, op, pArg);
}else{
@@ -115502,15 +135495,17 @@ SQLITE_API int sqlite3_file_control(sqlite3 *db, const char *zDbName, int op, vo
sqlite3BtreeLeave(pBtree);
}
sqlite3_mutex_leave(db->mutex);
- return rc;
+ return rc;
}
/*
** Interface to the testing logic.
*/
-SQLITE_API int sqlite3_test_control(int op, ...){
+SQLITE_API int SQLITE_CDECL sqlite3_test_control(int op, ...){
int rc = 0;
-#ifndef SQLITE_OMIT_BUILTIN_TEST
+#ifdef SQLITE_OMIT_BUILTIN_TEST
+ UNUSED_PARAMETER(op);
+#else
va_list ap;
va_start(ap, op);
switch( op ){
@@ -115539,7 +135534,7 @@ SQLITE_API int sqlite3_test_control(int op, ...){
** to the xRandomness method of the default VFS.
*/
case SQLITE_TESTCTRL_PRNG_RESET: {
- sqlite3PrngResetState();
+ sqlite3_randomness(0,0);
break;
}
@@ -115559,6 +135554,28 @@ SQLITE_API int sqlite3_test_control(int op, ...){
}
/*
+ ** sqlite3_test_control(FAULT_INSTALL, xCallback)
+ **
+ ** Arrange to invoke xCallback() whenever sqlite3FaultSim() is called,
+ ** if xCallback is not NULL.
+ **
+ ** As a test of the fault simulator mechanism itself, sqlite3FaultSim(0)
+ ** is called immediately after installing the new callback and the return
+ ** value from sqlite3FaultSim(0) becomes the return from
+ ** sqlite3_test_control().
+ */
+ case SQLITE_TESTCTRL_FAULT_INSTALL: {
+ /* MSVC is picky about pulling func ptrs from va lists.
+ ** http://support.microsoft.com/kb/47961
+ ** sqlite3GlobalConfig.xTestCallback = va_arg(ap, int(*)(int));
+ */
+ typedef int(*TESTCALLBACKFUNC_t)(int);
+ sqlite3GlobalConfig.xTestCallback = va_arg(ap, TESTCALLBACKFUNC_t);
+ rc = sqlite3FaultSim(0);
+ break;
+ }
+
+ /*
** sqlite3_test_control(BENIGN_MALLOC_HOOKS, xBegin, xEnd)
**
** Register hooks to call to indicate which malloc() failures
@@ -115584,7 +135601,7 @@ SQLITE_API int sqlite3_test_control(int op, ...){
** 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.
+ ** deleterious behavior.
*/
case SQLITE_TESTCTRL_PENDING_BYTE: {
rc = PENDING_BYTE;
@@ -115649,6 +135666,22 @@ SQLITE_API int sqlite3_test_control(int op, ...){
break;
}
+ /*
+ ** sqlite3_test_control(SQLITE_TESTCTRL_BYTEORDER);
+ **
+ ** The integer returned reveals the byte-order of the computer on which
+ ** SQLite is running:
+ **
+ ** 1 big-endian, determined at run-time
+ ** 10 little-endian, determined at run-time
+ ** 432101 big-endian, determined at compile-time
+ ** 123410 little-endian, determined at compile-time
+ */
+ case SQLITE_TESTCTRL_BYTEORDER: {
+ rc = SQLITE_BYTEORDER*100 + SQLITE_LITTLEENDIAN*10 + SQLITE_BIGENDIAN;
+ break;
+ }
+
/* sqlite3_test_control(SQLITE_TESTCTRL_RESERVE, sqlite3 *db, int N)
**
** Set the nReserve size to N for the main database on the database
@@ -115723,22 +135756,79 @@ SQLITE_API int sqlite3_test_control(int op, ...){
break;
}
-#if defined(SQLITE_ENABLE_TREE_EXPLAIN)
- /* sqlite3_test_control(SQLITE_TESTCTRL_EXPLAIN_STMT,
- ** sqlite3_stmt*,const char**);
+ /* sqlite3_test_control(SQLITE_TESTCTRL_NEVER_CORRUPT, int);
**
- ** 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.
+ ** Set or clear a flag that indicates that the database file is always well-
+ ** formed and never corrupt. This flag is clear by default, indicating that
+ ** database files might have arbitrary corruption. Setting the flag during
+ ** testing causes certain assert() statements in the code to be activated
+ ** that demonstrat invariants on well-formed database files.
*/
- 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);
+ case SQLITE_TESTCTRL_NEVER_CORRUPT: {
+ sqlite3GlobalConfig.neverCorrupt = va_arg(ap, int);
break;
}
+
+
+ /* sqlite3_test_control(SQLITE_TESTCTRL_VDBE_COVERAGE, xCallback, ptr);
+ **
+ ** Set the VDBE coverage callback function to xCallback with context
+ ** pointer ptr.
+ */
+ case SQLITE_TESTCTRL_VDBE_COVERAGE: {
+#ifdef SQLITE_VDBE_COVERAGE
+ typedef void (*branch_callback)(void*,int,u8,u8);
+ sqlite3GlobalConfig.xVdbeBranch = va_arg(ap,branch_callback);
+ sqlite3GlobalConfig.pVdbeBranchArg = va_arg(ap,void*);
#endif
+ break;
+ }
+ /* sqlite3_test_control(SQLITE_TESTCTRL_SORTER_MMAP, db, nMax); */
+ case SQLITE_TESTCTRL_SORTER_MMAP: {
+ sqlite3 *db = va_arg(ap, sqlite3*);
+ db->nMaxSorterMmap = va_arg(ap, int);
+ break;
+ }
+
+ /* sqlite3_test_control(SQLITE_TESTCTRL_ISINIT);
+ **
+ ** Return SQLITE_OK if SQLite has been initialized and SQLITE_ERROR if
+ ** not.
+ */
+ case SQLITE_TESTCTRL_ISINIT: {
+ if( sqlite3GlobalConfig.isInit==0 ) rc = SQLITE_ERROR;
+ break;
+ }
+
+ /* sqlite3_test_control(SQLITE_TESTCTRL_IMPOSTER, db, dbName, onOff, tnum);
+ **
+ ** This test control is used to create imposter tables. "db" is a pointer
+ ** to the database connection. dbName is the database name (ex: "main" or
+ ** "temp") which will receive the imposter. "onOff" turns imposter mode on
+ ** or off. "tnum" is the root page of the b-tree to which the imposter
+ ** table should connect.
+ **
+ ** Enable imposter mode only when the schema has already been parsed. Then
+ ** run a single CREATE TABLE statement to construct the imposter table in
+ ** the parsed schema. Then turn imposter mode back off again.
+ **
+ ** If onOff==0 and tnum>0 then reset the schema for all databases, causing
+ ** the schema to be reparsed the next time it is needed. This has the
+ ** effect of erasing all imposter tables.
+ */
+ case SQLITE_TESTCTRL_IMPOSTER: {
+ sqlite3 *db = va_arg(ap, sqlite3*);
+ sqlite3_mutex_enter(db->mutex);
+ db->init.iDb = sqlite3FindDbName(db, va_arg(ap,const char*));
+ db->init.busy = db->init.imposterTable = va_arg(ap,int);
+ db->init.newTnum = va_arg(ap,int);
+ if( db->init.busy==0 && db->init.newTnum>0 ){
+ sqlite3ResetAllSchemasOfConnection(db);
+ }
+ sqlite3_mutex_leave(db->mutex);
+ break;
+ }
}
va_end(ap);
#endif /* SQLITE_OMIT_BUILTIN_TEST */
@@ -115756,8 +135846,8 @@ SQLITE_API int sqlite3_test_control(int op, ...){
** 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;
+SQLITE_API const char *SQLITE_STDCALL sqlite3_uri_parameter(const char *zFilename, const char *zParam){
+ if( zFilename==0 || zParam==0 ) return 0;
zFilename += sqlite3Strlen30(zFilename) + 1;
while( zFilename[0] ){
int x = strcmp(zFilename, zParam);
@@ -115771,7 +135861,7 @@ SQLITE_API const char *sqlite3_uri_parameter(const char *zFilename, const char *
/*
** Return a boolean value for a query parameter.
*/
-SQLITE_API int sqlite3_uri_boolean(const char *zFilename, const char *zParam, int bDflt){
+SQLITE_API int SQLITE_STDCALL 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;
@@ -115780,14 +135870,14 @@ SQLITE_API int sqlite3_uri_boolean(const char *zFilename, const char *zParam, in
/*
** Return a 64-bit integer value for a query parameter.
*/
-SQLITE_API sqlite3_int64 sqlite3_uri_int64(
+SQLITE_API sqlite3_int64 SQLITE_STDCALL 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 ){
+ if( z && sqlite3DecOrHexToI64(z, &v)==SQLITE_OK ){
bDflt = v;
}
return bDflt;
@@ -115812,8 +135902,15 @@ SQLITE_PRIVATE Btree *sqlite3DbNameToBtree(sqlite3 *db, const char *zDbName){
** 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);
+SQLITE_API const char *SQLITE_STDCALL sqlite3_db_filename(sqlite3 *db, const char *zDbName){
+ Btree *pBt;
+#ifdef SQLITE_ENABLE_API_ARMOR
+ if( !sqlite3SafetyCheckOk(db) ){
+ (void)SQLITE_MISUSE_BKPT;
+ return 0;
+ }
+#endif
+ pBt = sqlite3DbNameToBtree(db, zDbName);
return pBt ? sqlite3BtreeGetFilename(pBt) : 0;
}
@@ -115821,11 +135918,100 @@ SQLITE_API const char *sqlite3_db_filename(sqlite3 *db, const char *zDbName){
** 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;
+SQLITE_API int SQLITE_STDCALL sqlite3_db_readonly(sqlite3 *db, const char *zDbName){
+ Btree *pBt;
+#ifdef SQLITE_ENABLE_API_ARMOR
+ if( !sqlite3SafetyCheckOk(db) ){
+ (void)SQLITE_MISUSE_BKPT;
+ return -1;
+ }
+#endif
+ pBt = sqlite3DbNameToBtree(db, zDbName);
+ return pBt ? sqlite3BtreeIsReadonly(pBt) : -1;
}
+#ifdef SQLITE_ENABLE_SNAPSHOT
+/*
+** Obtain a snapshot handle for the snapshot of database zDb currently
+** being read by handle db.
+*/
+SQLITE_API int SQLITE_STDCALL sqlite3_snapshot_get(
+ sqlite3 *db,
+ const char *zDb,
+ sqlite3_snapshot **ppSnapshot
+){
+ int rc = SQLITE_ERROR;
+#ifndef SQLITE_OMIT_WAL
+ int iDb;
+
+#ifdef SQLITE_ENABLE_API_ARMOR
+ if( !sqlite3SafetyCheckOk(db) ){
+ return SQLITE_MISUSE_BKPT;
+ }
+#endif
+ sqlite3_mutex_enter(db->mutex);
+
+ iDb = sqlite3FindDbName(db, zDb);
+ if( iDb==0 || iDb>1 ){
+ Btree *pBt = db->aDb[iDb].pBt;
+ if( 0==sqlite3BtreeIsInTrans(pBt) ){
+ rc = sqlite3BtreeBeginTrans(pBt, 0);
+ if( rc==SQLITE_OK ){
+ rc = sqlite3PagerSnapshotGet(sqlite3BtreePager(pBt), ppSnapshot);
+ }
+ }
+ }
+
+ sqlite3_mutex_leave(db->mutex);
+#endif /* SQLITE_OMIT_WAL */
+ return rc;
+}
+
+/*
+** Open a read-transaction on the snapshot idendified by pSnapshot.
+*/
+SQLITE_API int SQLITE_STDCALL sqlite3_snapshot_open(
+ sqlite3 *db,
+ const char *zDb,
+ sqlite3_snapshot *pSnapshot
+){
+ int rc = SQLITE_ERROR;
+#ifndef SQLITE_OMIT_WAL
+
+#ifdef SQLITE_ENABLE_API_ARMOR
+ if( !sqlite3SafetyCheckOk(db) ){
+ return SQLITE_MISUSE_BKPT;
+ }
+#endif
+ sqlite3_mutex_enter(db->mutex);
+ if( db->autoCommit==0 ){
+ int iDb;
+ iDb = sqlite3FindDbName(db, zDb);
+ if( iDb==0 || iDb>1 ){
+ Btree *pBt = db->aDb[iDb].pBt;
+ if( 0==sqlite3BtreeIsInReadTrans(pBt) ){
+ rc = sqlite3PagerSnapshotOpen(sqlite3BtreePager(pBt), pSnapshot);
+ if( rc==SQLITE_OK ){
+ rc = sqlite3BtreeBeginTrans(pBt, 0);
+ sqlite3PagerSnapshotOpen(sqlite3BtreePager(pBt), 0);
+ }
+ }
+ }
+ }
+
+ sqlite3_mutex_leave(db->mutex);
+#endif /* SQLITE_OMIT_WAL */
+ return rc;
+}
+
+/*
+** Free a snapshot handle obtained from sqlite3_snapshot_get().
+*/
+SQLITE_API void SQLITE_STDCALL sqlite3_snapshot_free(sqlite3_snapshot *pSnapshot){
+ sqlite3_free(pSnapshot);
+}
+#endif /* SQLITE_ENABLE_SNAPSHOT */
+
/************** End of main.c ************************************************/
/************** Begin file notify.c ******************************************/
/*
@@ -115843,6 +136029,8 @@ SQLITE_API int sqlite3_db_readonly(sqlite3 *db, const char *zDbName){
** This file contains the implementation of the sqlite3_unlock_notify()
** API method and its associated functionality.
*/
+/* #include "sqliteInt.h" */
+/* #include "btreeInt.h" */
/* Omit this entire file if SQLITE_ENABLE_UNLOCK_NOTIFY is not defined. */
#ifdef SQLITE_ENABLE_UNLOCK_NOTIFY
@@ -115973,7 +136161,7 @@ static void leaveMutex(void){
** on the same "db". If xNotify==0 then any prior callbacks are immediately
** cancelled.
*/
-SQLITE_API int sqlite3_unlock_notify(
+SQLITE_API int SQLITE_STDCALL sqlite3_unlock_notify(
sqlite3 *db,
void (*xNotify)(void **, int),
void *pArg
@@ -116012,7 +136200,7 @@ SQLITE_API int sqlite3_unlock_notify(
leaveMutex();
assert( !db->mallocFailed );
- sqlite3Error(db, rc, (rc?"database is deadlocked":0));
+ sqlite3ErrorWithMsg(db, rc, (rc?"database is deadlocked":0));
sqlite3_mutex_leave(db->mutex);
return rc;
}
@@ -116486,9 +136674,11 @@ SQLITE_PRIVATE void sqlite3ConnectionClosed(sqlite3 *db){
/* If not building as part of the core, include sqlite3ext.h. */
#ifndef SQLITE_CORE
-SQLITE_API extern const sqlite3_api_routines *sqlite3_api;
+/* # include "sqlite3ext.h" */
+SQLITE_EXTENSION_INIT3
#endif
+/* #include "sqlite3.h" */
/************** Include fts3_tokenizer.h in the middle of fts3Int.h **********/
/************** Begin file fts3_tokenizer.h **********************************/
/*
@@ -116517,6 +136707,7 @@ SQLITE_API extern const sqlite3_api_routines *sqlite3_api;
** If tokenizers are to be allowed to call sqlite3_*() functions, then
** we will need a way to register the API consistently.
*/
+/* #include "sqlite3.h" */
/*
** Structures used by the tokenizer interface. When a new tokenizer
@@ -116562,7 +136753,7 @@ struct sqlite3_tokenizer_module {
** 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
+ ** sqlite3_tokenizer.pModule variable should not be initialized by
** this callback. The caller will do so.
*/
int (*xCreate)(
@@ -116667,7 +136858,7 @@ int fts3_term_cnt(int iTerm, int iCol);
** May you share freely, never taking more than you give.
**
*************************************************************************
-** This is the header file for the generic hash-table implemenation
+** This is the header file for the generic hash-table implementation
** used in SQLite. We've modified it slightly to serve as a standalone
** hash table implementation for the full-text indexing module.
**
@@ -116773,6 +136964,18 @@ SQLITE_PRIVATE Fts3HashElem *sqlite3Fts3HashFindElem(const Fts3Hash *, const voi
/************** Continuing where we left off in fts3Int.h ********************/
/*
+** This constant determines the maximum depth of an FTS expression tree
+** that the library will create and use. FTS uses recursion to perform
+** various operations on the query tree, so the disadvantage of a large
+** limit is that it may allow very large queries to use large amounts
+** of stack space (perhaps causing a stack overflow).
+*/
+#ifndef SQLITE_FTS3_MAX_EXPR_DEPTH
+# define SQLITE_FTS3_MAX_EXPR_DEPTH 12
+#endif
+
+
+/*
** 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.
@@ -116855,6 +137058,11 @@ SQLITE_PRIVATE Fts3HashElem *sqlite3Fts3HashFindElem(const Fts3Hash *, const voi
#ifdef SQLITE_COVERAGE_TEST
# define ALWAYS(x) (1)
# define NEVER(X) (0)
+#elif defined(SQLITE_DEBUG)
+# define ALWAYS(x) sqlite3Fts3Always((x)!=0)
+# define NEVER(x) sqlite3Fts3Never((x)!=0)
+SQLITE_PRIVATE int sqlite3Fts3Always(int b);
+SQLITE_PRIVATE int sqlite3Fts3Never(int b);
#else
# define ALWAYS(x) (x)
# define NEVER(x) (x)
@@ -116913,6 +137121,8 @@ typedef struct Fts3DeferredToken Fts3DeferredToken;
typedef struct Fts3SegReader Fts3SegReader;
typedef struct Fts3MultiSegReader Fts3MultiSegReader;
+typedef struct MatchinfoBuffer MatchinfoBuffer;
+
/*
** A connection to a fulltext index is an instance of the following
** structure. The xCreate and xConnect methods create an instance
@@ -116927,23 +137137,24 @@ struct Fts3Table {
const char *zName; /* virtual table name */
int nColumn; /* number of named columns in virtual table */
char **azColumn; /* column names. malloced */
+ u8 *abNotindexed; /* True for 'notindexed' columns */
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 */
+ int nAutoincrmerge; /* Value configured by 'automerge' */
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];
+ sqlite3_stmt *aStmt[40];
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 bHasStat; /* True if %_stat table exists (2==unknown) */
u8 bHasDocsize; /* True if %_docsize table exists */
u8 bDescIdx; /* True if doclists are in reverse order */
u8 bIgnoreSavepoint; /* True to ignore xSavepoint invocations */
@@ -116977,6 +137188,7 @@ struct Fts3Table {
int nPendingData; /* Current bytes of pending data */
sqlite_int64 iPrevDocid; /* Docid of most recently inserted document */
int iPrevLangid; /* Langid of recently inserted document */
+ int bPrevDelete; /* True if last operation was a delete */
#if defined(SQLITE_DEBUG) || defined(SQLITE_COVERAGE_TEST)
/* State variables used for validating that the transaction control
@@ -116987,6 +137199,12 @@ struct Fts3Table {
int inTransaction; /* True after xBegin but before xCommit/xRollback */
int mxSavepoint; /* Largest valid xSavepoint integer */
#endif
+
+#ifdef SQLITE_TEST
+ /* True to disable the incremental doclist optimization. This is controled
+ ** by special insert command 'test-no-incr-doclist'. */
+ int bNoIncrDoclist;
+#endif
};
/*
@@ -117012,11 +137230,10 @@ struct Fts3Cursor {
int eEvalmode; /* An FTS3_EVAL_XX constant */
int nRowAvg; /* Average size of database rows, in pages */
sqlite3_int64 nDoc; /* Documents in table */
-
+ i64 iMinDocid; /* Minimum docid to return */
+ i64 iMaxDocid; /* Maximum docid to return */
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 */
+ MatchinfoBuffer *pMIBuffer; /* Buffer for matchinfo data */
};
#define FTS3_EVAL_FILTER 0
@@ -117042,6 +137259,15 @@ struct Fts3Cursor {
#define FTS3_DOCID_SEARCH 1 /* Lookup by rowid on %_content table */
#define FTS3_FULLTEXT_SEARCH 2 /* Full-text index search */
+/*
+** The lower 16-bits of the sqlite3_index_info.idxNum value set by
+** the xBestIndex() method contains the Fts3Cursor.eSearch value described
+** above. The upper 16-bits contain a combination of the following
+** bits, used to describe extra constraints on full-text searches.
+*/
+#define FTS3_HAVE_LANGID 0x00010000 /* languageid=? */
+#define FTS3_HAVE_DOCID_GE 0x00020000 /* docid>=? */
+#define FTS3_HAVE_DOCID_LE 0x00040000 /* docid<=? */
struct Fts3Doclist {
char *aAll; /* Array containing doclist (or NULL) */
@@ -117079,6 +137305,11 @@ struct Fts3Phrase {
int bIncr; /* True if doclist is loaded incrementally */
int iDoclistToken;
+ /* Used by sqlite3Fts3EvalPhrasePoslist() if this is a descendent of an
+ ** OR condition. */
+ char *pOrPoslist;
+ i64 iOrDocid;
+
/* Variables below this point are populated by fts3_expr.c when parsing
** a MATCH expression. Everything above is part of the evaluation phase.
*/
@@ -117122,7 +137353,9 @@ struct Fts3Expr {
u8 bStart; /* True if iDocid is valid */
u8 bDeferred; /* True if this expression is entirely deferred */
- u32 *aMI;
+ /* The following are used by the fts3_snippet.c module. */
+ int iPhrase; /* Index of this phrase in matchinfo() results */
+ u32 *aMI; /* See above */
};
/*
@@ -117154,7 +137387,6 @@ 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 **);
@@ -117229,7 +137461,12 @@ struct Fts3MultiSegReader {
SQLITE_PRIVATE int sqlite3Fts3Incrmerge(Fts3Table*,int,int);
+#define fts3GetVarint32(p, piVal) ( \
+ (*(u8*)(p)&0x80) ? sqlite3Fts3GetVarint32(p, piVal) : (*piVal=*(u8*)(p), 1) \
+)
+
/* fts3.c */
+SQLITE_PRIVATE void sqlite3Fts3ErrMsg(char**,const char*,...);
SQLITE_PRIVATE int sqlite3Fts3PutVarint(char *, sqlite3_int64);
SQLITE_PRIVATE int sqlite3Fts3GetVarint(const char *, sqlite_int64 *);
SQLITE_PRIVATE int sqlite3Fts3GetVarint32(const char *, int *);
@@ -117239,6 +137476,7 @@ SQLITE_PRIVATE void sqlite3Fts3DoclistPrev(int,char*,int,char**,sqlite3_int64*,i
SQLITE_PRIVATE int sqlite3Fts3EvalPhraseStats(Fts3Cursor *, Fts3Expr *, u32 *);
SQLITE_PRIVATE int sqlite3Fts3FirstFilter(sqlite3_int64, char *, int, char *);
SQLITE_PRIVATE void sqlite3Fts3CreateStatTable(int*, Fts3Table*);
+SQLITE_PRIVATE int sqlite3Fts3EvalTestDeferred(Fts3Cursor *pCsr, int *pRc);
/* fts3_tokenizer.c */
SQLITE_PRIVATE const char *sqlite3Fts3NextToken(const char *, int *);
@@ -117254,10 +137492,11 @@ SQLITE_PRIVATE void sqlite3Fts3Snippet(sqlite3_context *, Fts3Cursor *, const ch
const char *, const char *, int, int
);
SQLITE_PRIVATE void sqlite3Fts3Matchinfo(sqlite3_context *, Fts3Cursor *, const char *);
+SQLITE_PRIVATE void sqlite3Fts3MIBufferFree(MatchinfoBuffer *p);
/* fts3_expr.c */
SQLITE_PRIVATE int sqlite3Fts3ExprParse(sqlite3_tokenizer *, int,
- char **, int, int, int, const char *, int, Fts3Expr **
+ char **, int, int, int, const char *, int, Fts3Expr **, char **
);
SQLITE_PRIVATE void sqlite3Fts3ExprFree(Fts3Expr *);
#ifdef SQLITE_TEST
@@ -117282,8 +137521,11 @@ SQLITE_PRIVATE int sqlite3Fts3EvalPhrasePoslist(Fts3Cursor *, Fts3Expr *, int iC
SQLITE_PRIVATE int sqlite3Fts3MsrOvfl(Fts3Cursor *, Fts3MultiSegReader *, int *);
SQLITE_PRIVATE int sqlite3Fts3MsrIncrRestart(Fts3MultiSegReader *pCsr);
+/* fts3_tokenize_vtab.c */
+SQLITE_PRIVATE int sqlite3Fts3InitTok(sqlite3*, Fts3Hash *);
+
/* fts3_unicode2.c (functions generated by parsing unicode text files) */
-#ifdef SQLITE_ENABLE_FTS4_UNICODE61
+#ifndef SQLITE_DISABLE_FTS3_UNICODE
SQLITE_PRIVATE int sqlite3FtsUnicodeFold(int, int);
SQLITE_PRIVATE int sqlite3FtsUnicodeIsalnum(int);
SQLITE_PRIVATE int sqlite3FtsUnicodeIsdiacritic(int);
@@ -117307,7 +137549,9 @@ SQLITE_PRIVATE int sqlite3FtsUnicodeIsdiacritic(int);
/* #include <string.h> */
/* #include <stdarg.h> */
+/* #include "fts3.h" */
#ifndef SQLITE_CORE
+/* # include "sqlite3ext.h" */
SQLITE_EXTENSION_INIT1
#endif
@@ -117316,6 +137560,13 @@ static int fts3EvalStart(Fts3Cursor *pCsr);
static int fts3TermSegReaderCursor(
Fts3Cursor *, const char *, int, int, Fts3MultiSegReader **);
+#ifndef SQLITE_AMALGAMATION
+# if defined(SQLITE_DEBUG)
+SQLITE_PRIVATE int sqlite3Fts3Always(int b) { assert( b ); return b; }
+SQLITE_PRIVATE int sqlite3Fts3Never(int b) { assert( !b ); return b; }
+# endif
+#endif
+
/*
** 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.
@@ -117333,21 +137584,37 @@ SQLITE_PRIVATE int sqlite3Fts3PutVarint(char *p, sqlite_int64 v){
return (int) (q - (unsigned char *)p);
}
+#define GETVARINT_STEP(v, ptr, shift, mask1, mask2, var, ret) \
+ v = (v & mask1) | ( (*ptr++) << shift ); \
+ if( (v & mask2)==0 ){ var = v; return ret; }
+#define GETVARINT_INIT(v, ptr, shift, mask1, mask2, var, ret) \
+ v = (*ptr++); \
+ if( (v & mask2)==0 ){ var = v; return ret; }
+
/*
** 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);
+ const char *pStart = p;
+ u32 a;
+ u64 b;
+ int shift;
+
+ GETVARINT_INIT(a, p, 0, 0x00, 0x80, *v, 1);
+ GETVARINT_STEP(a, p, 7, 0x7F, 0x4000, *v, 2);
+ GETVARINT_STEP(a, p, 14, 0x3FFF, 0x200000, *v, 3);
+ GETVARINT_STEP(a, p, 21, 0x1FFFFF, 0x10000000, *v, 4);
+ b = (a & 0x0FFFFFFF );
+
+ for(shift=28; shift<=63; shift+=7){
+ u64 c = *p++;
+ b += (c&0x7F) << shift;
+ if( (c & 0x80)==0 ) break;
+ }
+ *v = b;
+ return (int)(p - pStart);
}
/*
@@ -117355,10 +137622,21 @@ SQLITE_PRIVATE int sqlite3Fts3GetVarint(const char *p, sqlite_int64 *v){
** 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;
+ u32 a;
+
+#ifndef fts3GetVarint32
+ GETVARINT_INIT(a, p, 0, 0x00, 0x80, *pi, 1);
+#else
+ a = (*p++);
+ assert( a & 0x80 );
+#endif
+
+ GETVARINT_STEP(a, p, 7, 0x7F, 0x4000, *pi, 2);
+ GETVARINT_STEP(a, p, 14, 0x3FFF, 0x200000, *pi, 3);
+ GETVARINT_STEP(a, p, 21, 0x1FFFFF, 0x10000000, *pi, 4);
+ a = (a & 0x0FFFFFFF );
+ *pi = (int)(a | ((u32)(*p & 0x0F) << 28));
+ return 5;
}
/*
@@ -117398,7 +137676,7 @@ SQLITE_PRIVATE void sqlite3Fts3Dequote(char *z){
/* If the first byte was a '[', then the close-quote character is a ']' */
if( quote=='[' ) quote = ']';
- while( ALWAYS(z[iIn]) ){
+ while( z[iIn] ){
if( z[iIn]==quote ){
if( z[iIn+1]!=quote ) break;
z[iOut++] = quote;
@@ -117478,6 +137756,17 @@ static int fts3DisconnectMethod(sqlite3_vtab *pVtab){
}
/*
+** Write an error message into *pzErr
+*/
+SQLITE_PRIVATE void sqlite3Fts3ErrMsg(char **pzErr, const char *zFormat, ...){
+ va_list ap;
+ sqlite3_free(*pzErr);
+ va_start(ap, zFormat);
+ *pzErr = sqlite3_vmprintf(zFormat, ap);
+ va_end(ap);
+}
+
+/*
** Construct one or more SQL statements from the format string given
** and then evaluate those statements. The success code is written
** into *pRc.
@@ -117886,11 +138175,16 @@ static char *fts3WriteExprList(Fts3Table *p, const char *zFunc, int *pRc){
** This function is used when parsing the "prefix=" FTS4 parameter.
*/
static int fts3GobbleInt(const char **pp, int *pnOut){
+ const int MAX_NPREFIX = 10000000;
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( nInt>MAX_NPREFIX ){
+ nInt = 0;
+ break;
+ }
}
if( p==*pp ) return SQLITE_ERROR;
*pnOut = nInt;
@@ -117933,7 +138227,6 @@ static int fts3PrefixParameter(
aIndex = sqlite3_malloc(sizeof(struct Fts3Index) * nIndex);
*apIndex = aIndex;
- *pnIndex = nIndex;
if( !aIndex ){
return SQLITE_NOMEM;
}
@@ -117943,13 +138236,20 @@ static int fts3PrefixParameter(
const char *p = zParam;
int i;
for(i=1; i<nIndex; i++){
- int nPrefix;
+ int nPrefix = 0;
if( fts3GobbleInt(&p, &nPrefix) ) return SQLITE_ERROR;
- aIndex[i].nPrefix = nPrefix;
+ assert( nPrefix>=0 );
+ if( nPrefix==0 ){
+ nIndex--;
+ i--;
+ }else{
+ aIndex[i].nPrefix = nPrefix;
+ }
p++;
}
}
+ *pnIndex = nIndex;
return SQLITE_OK;
}
@@ -117984,7 +138284,8 @@ static int fts3ContentColumns(
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 *pnStr, /* OUT: Bytes of string content */
+ char **pzErr /* OUT: error message */
){
int rc = SQLITE_OK; /* Return code */
char *zSql; /* "SELECT *" statement on zTbl */
@@ -117995,6 +138296,9 @@ static int fts3ContentColumns(
rc = SQLITE_NOMEM;
}else{
rc = sqlite3_prepare(db, zSql, -1, &pStmt, 0);
+ if( rc!=SQLITE_OK ){
+ sqlite3Fts3ErrMsg(pzErr, "%s", sqlite3_errmsg(db));
+ }
}
sqlite3_free(zSql);
@@ -118073,7 +138377,7 @@ static int fts3InitVtab(
const char **aCol; /* Array of column names */
sqlite3_tokenizer *pTokenizer = 0; /* Tokenizer for this table */
- int nIndex; /* Size of aIndex[] array */
+ int nIndex = 0; /* Size of aIndex[] array */
struct Fts3Index *aIndex = 0; /* Array of indexes for this table */
/* The results of parsing supported FTS4 key=value options: */
@@ -118084,6 +138388,8 @@ static int fts3InitVtab(
char *zUncompress = 0; /* uncompress=? parameter (or NULL) */
char *zContent = 0; /* content=? parameter (or NULL) */
char *zLanguageid = 0; /* languageid=? parameter (or NULL) */
+ char **azNotindexed = 0; /* The set of notindexed= columns */
+ int nNotindexed = 0; /* Size of azNotindexed[] array */
assert( strlen(argv[0])==4 );
assert( (sqlite3_strnicmp(argv[0], "fts4", 4)==0 && isFts4)
@@ -118093,9 +138399,19 @@ static int fts3InitVtab(
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));
+ nByte = sizeof(const char *) * (argc-2);
+ aCol = (const char **)sqlite3_malloc(nByte);
+ if( aCol ){
+ memset((void*)aCol, 0, nByte);
+ azNotindexed = (char **)sqlite3_malloc(nByte);
+ }
+ if( azNotindexed ){
+ memset(azNotindexed, 0, nByte);
+ }
+ if( !aCol || !azNotindexed ){
+ rc = SQLITE_NOMEM;
+ goto fts3_init_out;
+ }
/* 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
@@ -118134,7 +138450,8 @@ static int fts3InitVtab(
{ "uncompress", 10 }, /* 3 -> UNCOMPRESS */
{ "order", 5 }, /* 4 -> ORDER */
{ "content", 7 }, /* 5 -> CONTENT */
- { "languageid", 10 } /* 6 -> LANGUAGEID */
+ { "languageid", 10 }, /* 6 -> LANGUAGEID */
+ { "notindexed", 10 } /* 7 -> NOTINDEXED */
};
int iOpt;
@@ -118148,13 +138465,13 @@ static int fts3InitVtab(
}
}
if( iOpt==SizeofArray(aFts4Opt) ){
- *pzErr = sqlite3_mprintf("unrecognized parameter: %s", z);
+ sqlite3Fts3ErrMsg(pzErr, "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);
+ sqlite3Fts3ErrMsg(pzErr, "unrecognized matchinfo: %s", zVal);
rc = SQLITE_ERROR;
}
bNoDocsize = 1;
@@ -118182,7 +138499,7 @@ static int fts3InitVtab(
if( (strlen(zVal)!=3 || sqlite3_strnicmp(zVal, "asc", 3))
&& (strlen(zVal)!=4 || sqlite3_strnicmp(zVal, "desc", 4))
){
- *pzErr = sqlite3_mprintf("unrecognized order: %s", zVal);
+ sqlite3Fts3ErrMsg(pzErr, "unrecognized order: %s", zVal);
rc = SQLITE_ERROR;
}
bDescIdx = (zVal[0]=='d' || zVal[0]=='D');
@@ -118200,6 +138517,11 @@ static int fts3InitVtab(
zLanguageid = zVal;
zVal = 0;
break;
+
+ case 7: /* NOTINDEXED */
+ azNotindexed[nNotindexed++] = zVal;
+ zVal = 0;
+ break;
}
}
sqlite3_free(zVal);
@@ -118228,7 +138550,7 @@ static int fts3InitVtab(
if( nCol==0 ){
sqlite3_free((void*)aCol);
aCol = 0;
- rc = fts3ContentColumns(db, argv[1], zContent, &aCol, &nCol, &nString);
+ rc = fts3ContentColumns(db, argv[1], zContent,&aCol,&nCol,&nString,pzErr);
/* If a languageid= option was specified, remove the language id
** column from the aCol[] array. */
@@ -118263,7 +138585,7 @@ static int fts3InitVtab(
rc = fts3PrefixParameter(zPrefix, &nIndex, &aIndex);
if( rc==SQLITE_ERROR ){
assert( zPrefix );
- *pzErr = sqlite3_mprintf("error parsing prefix parameter: %s", zPrefix);
+ sqlite3Fts3ErrMsg(pzErr, "error parsing prefix parameter: %s", zPrefix);
}
if( rc!=SQLITE_OK ) goto fts3_init_out;
@@ -118271,6 +138593,7 @@ static int fts3InitVtab(
nByte = sizeof(Fts3Table) + /* Fts3Table */
nCol * sizeof(char *) + /* azColumn */
nIndex * sizeof(struct Fts3Index) + /* aIndex */
+ nCol * sizeof(u8) + /* abNotindexed */
nName + /* zName */
nDb + /* zDb */
nString; /* Space for azColumn strings */
@@ -118290,7 +138613,7 @@ static int fts3InitVtab(
p->bHasStat = isFts4;
p->bFts4 = isFts4;
p->bDescIdx = bDescIdx;
- p->bAutoincrmerge = 0xff; /* 0xff means setting unknown */
+ p->nAutoincrmerge = 0xff; /* 0xff means setting unknown */
p->zContentTbl = zContent;
p->zLanguageid = zLanguageid;
zContent = 0;
@@ -118304,9 +138627,10 @@ static int fts3InitVtab(
for(i=0; i<nIndex; i++){
fts3HashInit(&p->aIndex[i].hPending, FTS3_HASH_STRING, 1);
}
+ p->abNotindexed = (u8 *)&p->aIndex[nIndex];
/* Fill in the zName and zDb fields of the vtab structure. */
- zCsr = (char *)&p->aIndex[nIndex];
+ zCsr = (char *)&p->abNotindexed[nCol];
p->zName = zCsr;
memcpy(zCsr, argv[2], nName);
zCsr += nName;
@@ -118327,10 +138651,31 @@ static int fts3InitVtab(
assert( zCsr <= &((char *)p)[nByte] );
}
- if( (zCompress==0)!=(zUncompress==0) ){
+ /* Fill in the abNotindexed array */
+ for(iCol=0; iCol<nCol; iCol++){
+ int n = (int)strlen(p->azColumn[iCol]);
+ for(i=0; i<nNotindexed; i++){
+ char *zNot = azNotindexed[i];
+ if( zNot && n==(int)strlen(zNot)
+ && 0==sqlite3_strnicmp(p->azColumn[iCol], zNot, n)
+ ){
+ p->abNotindexed[iCol] = 1;
+ sqlite3_free(zNot);
+ azNotindexed[i] = 0;
+ }
+ }
+ }
+ for(i=0; i<nNotindexed; i++){
+ if( azNotindexed[i] ){
+ sqlite3Fts3ErrMsg(pzErr, "no such column: %s", azNotindexed[i]);
+ rc = SQLITE_ERROR;
+ }
+ }
+
+ if( rc==SQLITE_OK && (zCompress==0)!=(zUncompress==0) ){
char const *zMiss = (zCompress==0 ? "compress" : "uncompress");
rc = SQLITE_ERROR;
- *pzErr = sqlite3_mprintf("missing %s parameter in fts4 constructor", zMiss);
+ sqlite3Fts3ErrMsg(pzErr, "missing %s parameter in fts4 constructor", zMiss);
}
p->zReadExprlist = fts3ReadExprList(p, zUncompress, &rc);
p->zWriteExprlist = fts3WriteExprList(p, zCompress, &rc);
@@ -118347,10 +138692,7 @@ static int fts3InitVtab(
** 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;
+ p->bHasStat = 2;
}
/* Figure out the page-size for the database. This is required in order to
@@ -118368,7 +138710,9 @@ fts3_init_out:
sqlite3_free(zUncompress);
sqlite3_free(zContent);
sqlite3_free(zLanguageid);
+ for(i=0; i<nNotindexed; i++) sqlite3_free(azNotindexed[i]);
sqlite3_free((void *)aCol);
+ sqlite3_free((void *)azNotindexed);
if( rc!=SQLITE_OK ){
if( p ){
fts3DisconnectMethod((sqlite3_vtab *)p);
@@ -118407,6 +138751,32 @@ static int fts3CreateMethod(
return fts3InitVtab(1, db, pAux, argc, argv, ppVtab, pzErr);
}
+/*
+** Set the pIdxInfo->estimatedRows variable to nRow. Unless this
+** extension is currently being used by a version of SQLite too old to
+** support estimatedRows. In that case this function is a no-op.
+*/
+static void fts3SetEstimatedRows(sqlite3_index_info *pIdxInfo, i64 nRow){
+#if SQLITE_VERSION_NUMBER>=3008002
+ if( sqlite3_libversion_number()>=3008002 ){
+ pIdxInfo->estimatedRows = nRow;
+ }
+#endif
+}
+
+/*
+** Set the SQLITE_INDEX_SCAN_UNIQUE flag in pIdxInfo->flags. Unless this
+** extension is currently being used by a version of SQLite too old to
+** support index-info flags. In that case this function is a no-op.
+*/
+static void fts3SetUniqueFlag(sqlite3_index_info *pIdxInfo){
+#if SQLITE_VERSION_NUMBER>=3008012
+ if( sqlite3_libversion_number()>=3008012 ){
+ pIdxInfo->idxFlags |= SQLITE_INDEX_SCAN_UNIQUE;
+ }
+#endif
+}
+
/*
** Implementation of the xBestIndex method for FTS3 tables. There
** are three possible strategies, in order of preference:
@@ -118419,23 +138789,40 @@ 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 */
+ int iDocidGe = -1; /* Index of docid>=x constraint, if present */
+ int iDocidLe = -1; /* Index of docid<=x constraint, if present */
+ int iIdx;
/* 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;
+ pInfo->estimatedCost = 5000000;
for(i=0; i<pInfo->nConstraint; i++){
+ int bDocid; /* True if this constraint is on docid */
struct sqlite3_index_constraint *pCons = &pInfo->aConstraint[i];
- if( pCons->usable==0 ) continue;
+ if( pCons->usable==0 ){
+ if( pCons->op==SQLITE_INDEX_CONSTRAINT_MATCH ){
+ /* There exists an unusable MATCH constraint. This means that if
+ ** the planner does elect to use the results of this call as part
+ ** of the overall query plan the user will see an "unable to use
+ ** function MATCH in the requested context" error. To discourage
+ ** this, return a very high cost here. */
+ pInfo->idxNum = FTS3_FULLSCAN_SEARCH;
+ pInfo->estimatedCost = 1e50;
+ fts3SetEstimatedRows(pInfo, ((sqlite3_int64)1) << 50);
+ return SQLITE_OK;
+ }
+ continue;
+ }
+
+ bDocid = (pCons->iColumn<0 || pCons->iColumn==p->nColumn+1);
/* 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 )
- ){
+ if( iCons<0 && pCons->op==SQLITE_INDEX_CONSTRAINT_EQ && bDocid ){
pInfo->idxNum = FTS3_DOCID_SEARCH;
pInfo->estimatedCost = 1.0;
iCons = i;
@@ -118464,14 +138851,41 @@ static int fts3BestIndexMethod(sqlite3_vtab *pVTab, sqlite3_index_info *pInfo){
){
iLangidCons = i;
}
+
+ if( bDocid ){
+ switch( pCons->op ){
+ case SQLITE_INDEX_CONSTRAINT_GE:
+ case SQLITE_INDEX_CONSTRAINT_GT:
+ iDocidGe = i;
+ break;
+
+ case SQLITE_INDEX_CONSTRAINT_LE:
+ case SQLITE_INDEX_CONSTRAINT_LT:
+ iDocidLe = i;
+ break;
+ }
+ }
}
+ /* If using a docid=? or rowid=? strategy, set the UNIQUE flag. */
+ if( pInfo->idxNum==FTS3_DOCID_SEARCH ) fts3SetUniqueFlag(pInfo);
+
+ iIdx = 1;
if( iCons>=0 ){
- pInfo->aConstraintUsage[iCons].argvIndex = 1;
+ pInfo->aConstraintUsage[iCons].argvIndex = iIdx++;
pInfo->aConstraintUsage[iCons].omit = 1;
}
if( iLangidCons>=0 ){
- pInfo->aConstraintUsage[iLangidCons].argvIndex = 2;
+ pInfo->idxNum |= FTS3_HAVE_LANGID;
+ pInfo->aConstraintUsage[iLangidCons].argvIndex = iIdx++;
+ }
+ if( iDocidGe>=0 ){
+ pInfo->idxNum |= FTS3_HAVE_DOCID_GE;
+ pInfo->aConstraintUsage[iDocidGe].argvIndex = iIdx++;
+ }
+ if( iDocidLe>=0 ){
+ pInfo->idxNum |= FTS3_HAVE_DOCID_LE;
+ pInfo->aConstraintUsage[iDocidLe].argvIndex = iIdx++;
}
/* Regardless of the strategy selected, FTS can deliver rows in rowid (or
@@ -118524,7 +138938,7 @@ static int fts3CloseMethod(sqlite3_vtab_cursor *pCursor){
sqlite3Fts3ExprFree(pCsr->pExpr);
sqlite3Fts3FreeDeferredTokens(pCsr);
sqlite3_free(pCsr->aDoclist);
- sqlite3_free(pCsr->aMatchinfo);
+ sqlite3Fts3MIBufferFree(pCsr->pMIBuffer);
assert( ((Fts3Table *)pCsr->base.pVtab)->pSegments==0 );
sqlite3_free(pCsr);
return SQLITE_OK;
@@ -118574,7 +138988,7 @@ static int fts3CursorSeek(sqlite3_context *pContext, Fts3Cursor *pCsr){
}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
+ /* If no row was found and no error has occurred, 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;
@@ -118649,10 +139063,10 @@ static int fts3ScanInteriorNode(
/* 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);
+ zCsr += fts3GetVarint32(zCsr, &nPrefix);
}
isFirstTerm = 0;
- zCsr += sqlite3Fts3GetVarint32(zCsr, &nSuffix);
+ zCsr += fts3GetVarint32(zCsr, &nSuffix);
if( nPrefix<0 || nSuffix<0 || &zCsr[nSuffix]>zEnd ){
rc = FTS_CORRUPT_VTAB;
@@ -118735,18 +139149,18 @@ static int fts3SelectLeaf(
sqlite3_int64 *piLeaf, /* Selected leaf node */
sqlite3_int64 *piLeaf2 /* Selected leaf node */
){
- int rc; /* Return code */
+ int rc = SQLITE_OK; /* Return code */
int iHeight; /* Height of this node in tree */
assert( piLeaf || piLeaf2 );
- sqlite3Fts3GetVarint32(zNode, &iHeight);
+ fts3GetVarint32(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 */
+ int nBlob = 0; /* Size of zBlob in bytes */
if( piLeaf && piLeaf2 && (*piLeaf!=*piLeaf2) ){
rc = sqlite3Fts3ReadBlock(p, *piLeaf, &zBlob, &nBlob, 0);
@@ -118942,11 +139356,11 @@ static void fts3PoslistMerge(
int iCol1; /* The current column index in pp1 */
int iCol2; /* The current column index in pp2 */
- if( *p1==POS_COLUMN ) sqlite3Fts3GetVarint32(&p1[1], &iCol1);
+ if( *p1==POS_COLUMN ) fts3GetVarint32(&p1[1], &iCol1);
else if( *p1==POS_END ) iCol1 = POSITION_LIST_END;
else iCol1 = 0;
- if( *p2==POS_COLUMN ) sqlite3Fts3GetVarint32(&p2[1], &iCol2);
+ if( *p2==POS_COLUMN ) fts3GetVarint32(&p2[1], &iCol2);
else if( *p2==POS_END ) iCol2 = POSITION_LIST_END;
else iCol2 = 0;
@@ -119039,11 +139453,11 @@ static int fts3PoslistPhraseMerge(
assert( p!=0 && *p1!=0 && *p2!=0 );
if( *p1==POS_COLUMN ){
p1++;
- p1 += sqlite3Fts3GetVarint32(p1, &iCol1);
+ p1 += fts3GetVarint32(p1, &iCol1);
}
if( *p2==POS_COLUMN ){
p2++;
- p2 += sqlite3Fts3GetVarint32(p2, &iCol2);
+ p2 += fts3GetVarint32(p2, &iCol2);
}
while( 1 ){
@@ -119093,9 +139507,9 @@ static int fts3PoslistPhraseMerge(
if( 0==*p1 || 0==*p2 ) break;
p1++;
- p1 += sqlite3Fts3GetVarint32(p1, &iCol1);
+ p1 += fts3GetVarint32(p1, &iCol1);
p2++;
- p2 += sqlite3Fts3GetVarint32(p2, &iCol2);
+ p2 += fts3GetVarint32(p2, &iCol2);
}
/* Advance pointer p1 or p2 (whichever corresponds to the smaller of
@@ -119107,12 +139521,12 @@ static int fts3PoslistPhraseMerge(
fts3ColumnlistCopy(0, &p1);
if( 0==*p1 ) break;
p1++;
- p1 += sqlite3Fts3GetVarint32(p1, &iCol1);
+ p1 += fts3GetVarint32(p1, &iCol1);
}else{
fts3ColumnlistCopy(0, &p2);
if( 0==*p2 ) break;
p2++;
- p2 += sqlite3Fts3GetVarint32(p2, &iCol2);
+ p2 += fts3GetVarint32(p2, &iCol2);
}
}
@@ -119373,26 +139787,33 @@ static int fts3DoclistOrMerge(
**
** The right-hand input doclist is overwritten by this function.
*/
-static void fts3DoclistPhraseMerge(
+static int 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 */
+ char **paRight, int *pnRight /* IN/OUT: Right/output doclist */
){
sqlite3_int64 i1 = 0;
sqlite3_int64 i2 = 0;
sqlite3_int64 iPrev = 0;
+ char *aRight = *paRight;
char *pEnd1 = &aLeft[nLeft];
char *pEnd2 = &aRight[*pnRight];
char *p1 = aLeft;
char *p2 = aRight;
char *p;
int bFirstOut = 0;
- char *aOut = aRight;
+ char *aOut;
assert( nDist>0 );
-
+ if( bDescDoclist ){
+ aOut = sqlite3_malloc(*pnRight + FTS3_VARINT_MAX);
+ if( aOut==0 ) return SQLITE_NOMEM;
+ }else{
+ aOut = aRight;
+ }
p = aOut;
+
fts3GetDeltaVarint3(&p1, pEnd1, 0, &i1);
fts3GetDeltaVarint3(&p2, pEnd2, 0, &i2);
@@ -119421,6 +139842,12 @@ static void fts3DoclistPhraseMerge(
}
*pnRight = (int)(p - aOut);
+ if( bDescDoclist ){
+ sqlite3_free(aRight);
+ *paRight = aOut;
+ }
+
+ return SQLITE_OK;
}
/*
@@ -119545,8 +139972,22 @@ static int fts3TermSelectMerge(
){
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);
+ ** buffer using memcpy().
+ **
+ ** Add FTS3_VARINT_MAX bytes of unused space to the end of the
+ ** allocation. This is so as to ensure that the buffer is big enough
+ ** to hold the current doclist AND'd with any other doclist. If the
+ ** doclists are stored in order=ASC order, this padding would not be
+ ** required (since the size of [doclistA AND doclistB] is always less
+ ** than or equal to the size of [doclistA] in that case). But this is
+ ** not true for order=DESC. For example, a doclist containing (1, -1)
+ ** may be smaller than (-1), as in the first example the -1 may be stored
+ ** as a single-byte delta, whereas in the second it must be stored as a
+ ** FTS3_VARINT_MAX byte varint.
+ **
+ ** Similar padding is added in the fts3DoclistOrMerge() function.
+ */
+ pTS->aaOutput[0] = sqlite3_malloc(nDoclist + FTS3_VARINT_MAX + 1);
pTS->anOutput[0] = nDoclist;
if( pTS->aaOutput[0] ){
memcpy(pTS->aaOutput[0], aDoclist, nDoclist);
@@ -119643,7 +140084,7 @@ static int fts3SegReaderCursor(
** calls out here. */
if( iLevel<0 && p->aIndex ){
Fts3SegReader *pSeg = 0;
- rc = sqlite3Fts3SegReaderPending(p, iIndex, zTerm, nTerm, isPrefix, &pSeg);
+ rc = sqlite3Fts3SegReaderPending(p, iIndex, zTerm, nTerm, isPrefix||isScan, &pSeg);
if( rc==SQLITE_OK && pSeg ){
rc = fts3SegReaderCursorAppend(pCsr, pSeg);
}
@@ -119814,7 +140255,7 @@ static void fts3SegReaderCursorFree(Fts3MultiSegReader *pSegcsr){
}
/*
-** This function retreives the doclist for the specified term (or term
+** This function retrieves the doclist for the specified term (or term
** prefix) from the database.
*/
static int fts3TermSelect(
@@ -119919,6 +140360,33 @@ static int fts3NextMethod(sqlite3_vtab_cursor *pCursor){
}
/*
+** The following are copied from sqliteInt.h.
+**
+** 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.
+*/
+#ifndef SQLITE_AMALGAMATION
+# define LARGEST_INT64 (0xffffffff|(((sqlite3_int64)0x7fffffff)<<32))
+# define SMALLEST_INT64 (((sqlite3_int64)-1) - LARGEST_INT64)
+#endif
+
+/*
+** If the numeric type of argument pVal is "integer", then return it
+** converted to a 64-bit signed integer. Otherwise, return a copy of
+** the second parameter, iDefault.
+*/
+static sqlite3_int64 fts3DocidRange(sqlite3_value *pVal, i64 iDefault){
+ if( pVal ){
+ int eType = sqlite3_value_numeric_type(pVal);
+ if( eType==SQLITE_INTEGER ){
+ return sqlite3_value_int64(pVal);
+ }
+ }
+ return iDefault;
+}
+
+/*
** This is the xFilter interface for the virtual table. See
** the virtual table xFilter method documentation for additional
** information.
@@ -119941,59 +140409,72 @@ static int fts3FilterMethod(
int nVal, /* Number of elements in apVal */
sqlite3_value **apVal /* Arguments for the indexing scheme */
){
- int rc;
+ int rc = SQLITE_OK;
char *zSql; /* SQL statement used to access %_content */
+ int eSearch;
Fts3Table *p = (Fts3Table *)pCursor->pVtab;
Fts3Cursor *pCsr = (Fts3Cursor *)pCursor;
+ sqlite3_value *pCons = 0; /* The MATCH or rowid constraint, if any */
+ sqlite3_value *pLangid = 0; /* The "langid = ?" constraint, if any */
+ sqlite3_value *pDocidGe = 0; /* The "docid >= ?" constraint, if any */
+ sqlite3_value *pDocidLe = 0; /* The "docid <= ?" constraint, if any */
+ int iIdx;
+
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) );
+ eSearch = (idxNum & 0x0000FFFF);
+ assert( eSearch>=0 && eSearch<=(FTS3_FULLTEXT_SEARCH+p->nColumn) );
assert( p->pSegments==0 );
+ /* Collect arguments into local variables */
+ iIdx = 0;
+ if( eSearch!=FTS3_FULLSCAN_SEARCH ) pCons = apVal[iIdx++];
+ if( idxNum & FTS3_HAVE_LANGID ) pLangid = apVal[iIdx++];
+ if( idxNum & FTS3_HAVE_DOCID_GE ) pDocidGe = apVal[iIdx++];
+ if( idxNum & FTS3_HAVE_DOCID_LE ) pDocidLe = apVal[iIdx++];
+ assert( iIdx==nVal );
+
/* In case the cursor has been used before, clear it now. */
sqlite3_finalize(pCsr->pStmt);
sqlite3_free(pCsr->aDoclist);
+ sqlite3Fts3MIBufferFree(pCsr->pMIBuffer);
sqlite3Fts3ExprFree(pCsr->pExpr);
memset(&pCursor[1], 0, sizeof(Fts3Cursor)-sizeof(sqlite3_vtab_cursor));
+ /* Set the lower and upper bounds on docids to return */
+ pCsr->iMinDocid = fts3DocidRange(pDocidGe, SMALLEST_INT64);
+ pCsr->iMaxDocid = fts3DocidRange(pDocidLe, LARGEST_INT64);
+
if( idxStr ){
pCsr->bDesc = (idxStr[0]=='D');
}else{
pCsr->bDesc = p->bDescIdx;
}
- pCsr->eSearch = (i16)idxNum;
+ pCsr->eSearch = (i16)eSearch;
- 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( eSearch!=FTS3_DOCID_SEARCH && eSearch!=FTS3_FULLSCAN_SEARCH ){
+ int iCol = eSearch-FTS3_FULLTEXT_SEARCH;
+ const char *zQuery = (const char *)sqlite3_value_text(pCons);
- if( zQuery==0 && sqlite3_value_type(apVal[0])!=SQLITE_NULL ){
+ if( zQuery==0 && sqlite3_value_type(pCons)!=SQLITE_NULL ){
return SQLITE_NOMEM;
}
pCsr->iLangid = 0;
- if( nVal==2 ) pCsr->iLangid = sqlite3_value_int(apVal[1]);
+ if( pLangid ) pCsr->iLangid = sqlite3_value_int(pLangid);
+ assert( p->base.zErrMsg==0 );
rc = sqlite3Fts3ExprParse(p->pTokenizer, pCsr->iLangid,
- p->azColumn, p->bFts4, p->nColumn, iCol, zQuery, -1, &pCsr->pExpr
+ p->azColumn, p->bFts4, p->nColumn, iCol, zQuery, -1, &pCsr->pExpr,
+ &p->base.zErrMsg
);
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;
@@ -120005,21 +140486,28 @@ static int fts3FilterMethod(
** 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( eSearch==FTS3_FULLSCAN_SEARCH ){
+ if( pDocidGe || pDocidLe ){
+ zSql = sqlite3_mprintf(
+ "SELECT %s WHERE rowid BETWEEN %lld AND %lld ORDER BY rowid %s",
+ p->zReadExprlist, pCsr->iMinDocid, pCsr->iMaxDocid,
+ (pCsr->bDesc ? "DESC" : "ASC")
+ );
+ }else{
+ 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 ){
+ }else if( eSearch==FTS3_DOCID_SEARCH ){
rc = fts3CursorSeekStmt(pCsr, &pCsr->pStmt);
if( rc==SQLITE_OK ){
- rc = sqlite3_bind_value(pCsr->pStmt, 1, apVal[0]);
+ rc = sqlite3_bind_value(pCsr->pStmt, 1, pCons);
}
}
if( rc!=SQLITE_OK ) return rc;
@@ -120147,7 +140635,10 @@ static int fts3SyncMethod(sqlite3_vtab *pVtab){
Fts3Table *p = (Fts3Table*)pVtab;
int rc = sqlite3Fts3PendingTermsFlush(p);
- if( rc==SQLITE_OK && p->bAutoincrmerge==1 && p->nLeafAdd>(nMinMerge/16) ){
+ if( rc==SQLITE_OK
+ && p->nLeafAdd>(nMinMerge/16)
+ && p->nAutoincrmerge && p->nAutoincrmerge!=0xff
+ ){
int mxLevel = 0; /* Maximum relative level value in db */
int A; /* Incr-merge parameter A */
@@ -120155,14 +140646,41 @@ static int fts3SyncMethod(sqlite3_vtab *pVtab){
assert( rc==SQLITE_OK || mxLevel==0 );
A = p->nLeafAdd * mxLevel;
A += (A/2);
- if( A>(int)nMinMerge ) rc = sqlite3Fts3Incrmerge(p, A, 8);
+ if( A>(int)nMinMerge ) rc = sqlite3Fts3Incrmerge(p, A, p->nAutoincrmerge);
}
sqlite3Fts3SegmentsClose(p);
return rc;
}
/*
-** Implementation of xBegin() method. This is a no-op.
+** If it is currently unknown whether or not the FTS table has an %_stat
+** table (if p->bHasStat==2), attempt to determine this (set p->bHasStat
+** to 0 or 1). Return SQLITE_OK if successful, or an SQLite error code
+** if an error occurs.
+*/
+static int fts3SetHasStat(Fts3Table *p){
+ int rc = SQLITE_OK;
+ if( p->bHasStat==2 ){
+ const char *zFmt ="SELECT 1 FROM %Q.sqlite_master WHERE tbl_name='%q_stat'";
+ char *zSql = sqlite3_mprintf(zFmt, p->zDb, p->zName);
+ if( zSql ){
+ sqlite3_stmt *pStmt = 0;
+ rc = sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0);
+ if( rc==SQLITE_OK ){
+ int bHasStat = (sqlite3_step(pStmt)==SQLITE_ROW);
+ rc = sqlite3_finalize(pStmt);
+ if( rc==SQLITE_OK ) p->bHasStat = bHasStat;
+ }
+ sqlite3_free(zSql);
+ }else{
+ rc = SQLITE_NOMEM;
+ }
+ }
+ return rc;
+}
+
+/*
+** Implementation of xBegin() method.
*/
static int fts3BeginMethod(sqlite3_vtab *pVtab){
Fts3Table *p = (Fts3Table*)pVtab;
@@ -120173,7 +140691,7 @@ static int fts3BeginMethod(sqlite3_vtab *pVtab){
TESTONLY( p->inTransaction = 1 );
TESTONLY( p->mxSavepoint = -1; );
p->nLeafAdd = 0;
- return SQLITE_OK;
+ return fts3SetHasStat(p);
}
/*
@@ -120215,11 +140733,31 @@ static void fts3ReversePoslist(char *pStart, char **ppPoslist){
char *p = &(*ppPoslist)[-2];
char c = 0;
+ /* Skip backwards passed any trailing 0x00 bytes added by NearTrim() */
while( p>pStart && (c=*p--)==0 );
+
+ /* Search backwards for a varint with value zero (the end of the previous
+ ** poslist). This is an 0x00 byte preceded by some byte that does not
+ ** have the 0x80 bit set. */
while( p>pStart && (*p & 0x80) | c ){
c = *p--;
}
- if( p>pStart ){ p = &p[2]; }
+ assert( p==pStart || c==0 );
+
+ /* At this point p points to that preceding byte without the 0x80 bit
+ ** set. So to find the start of the poslist, skip forward 2 bytes then
+ ** over a varint.
+ **
+ ** Normally. The other case is that p==pStart and the poslist to return
+ ** is the first in the doclist. In this case do not skip forward 2 bytes.
+ ** The second part of the if condition (c==0 && *ppPoslist>&p[2])
+ ** is required for cases where the first byte of a doclist and the
+ ** doclist is empty. For example, if the first docid is 10, a doclist
+ ** that begins with:
+ **
+ ** 0x0A 0x00 <next docid delta varint>
+ */
+ if( p>pStart || (c==0 && *ppPoslist>&p[2]) ){ p = &p[2]; }
while( *p++&0x80 );
*ppPoslist = p;
}
@@ -120290,6 +140828,8 @@ static void fts3SnippetFunc(
}
if( !zEllipsis || !zEnd || !zStart ){
sqlite3_result_error_nomem(pContext);
+ }else if( nToken==0 ){
+ sqlite3_result_text(pContext, "", -1, SQLITE_STATIC);
}else if( SQLITE_OK==fts3CursorSeek(pContext, pCsr) ){
sqlite3Fts3Snippet(pContext, pCsr, zStart, zEnd, zEllipsis, iCol, nToken);
}
@@ -120422,6 +140962,10 @@ static int fts3RenameMethod(
sqlite3 *db = p->db; /* Database connection */
int rc; /* Return Code */
+ /* At this point it must be known if the %_stat table exists or not.
+ ** So bHasStat may not be 2. */
+ rc = fts3SetHasStat(p);
+
/* 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
@@ -120429,7 +140973,9 @@ static int fts3RenameMethod(
** PendingTermsFlush() in in case that changes.
*/
assert( p->nPendingData==0 );
- rc = sqlite3Fts3PendingTermsFlush(p);
+ if( rc==SQLITE_OK ){
+ rc = sqlite3Fts3PendingTermsFlush(p);
+ }
if( p->zContentTbl==0 ){
fts3DbExec(&rc, db,
@@ -120557,7 +141103,7 @@ static void hashDestroy(void *p){
*/
SQLITE_PRIVATE void sqlite3Fts3SimpleTokenizerModule(sqlite3_tokenizer_module const**ppModule);
SQLITE_PRIVATE void sqlite3Fts3PorterTokenizerModule(sqlite3_tokenizer_module const**ppModule);
-#ifdef SQLITE_ENABLE_FTS4_UNICODE61
+#ifndef SQLITE_DISABLE_FTS3_UNICODE
SQLITE_PRIVATE void sqlite3Fts3UnicodeTokenizer(sqlite3_tokenizer_module const**ppModule);
#endif
#ifdef SQLITE_ENABLE_ICU
@@ -120565,7 +141111,7 @@ SQLITE_PRIVATE void sqlite3Fts3IcuTokenizerModule(sqlite3_tokenizer_module const
#endif
/*
-** Initialise the fts3 extension. If this extension is built as part
+** Initialize 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.
@@ -120575,7 +141121,7 @@ SQLITE_PRIVATE int sqlite3Fts3Init(sqlite3 *db){
Fts3Hash *pHash = 0;
const sqlite3_tokenizer_module *pSimple = 0;
const sqlite3_tokenizer_module *pPorter = 0;
-#ifdef SQLITE_ENABLE_FTS4_UNICODE61
+#ifndef SQLITE_DISABLE_FTS3_UNICODE
const sqlite3_tokenizer_module *pUnicode = 0;
#endif
@@ -120584,7 +141130,7 @@ SQLITE_PRIVATE int sqlite3Fts3Init(sqlite3 *db){
sqlite3Fts3IcuTokenizerModule(&pIcu);
#endif
-#ifdef SQLITE_ENABLE_FTS4_UNICODE61
+#ifndef SQLITE_DISABLE_FTS3_UNICODE
sqlite3Fts3UnicodeTokenizer(&pUnicode);
#endif
@@ -120599,7 +141145,7 @@ SQLITE_PRIVATE int sqlite3Fts3Init(sqlite3 *db){
sqlite3Fts3SimpleTokenizerModule(&pSimple);
sqlite3Fts3PorterTokenizerModule(&pPorter);
- /* Allocate and initialise the hash-table used to store tokenizers. */
+ /* Allocate and initialize the hash-table used to store tokenizers. */
pHash = sqlite3_malloc(sizeof(Fts3Hash));
if( !pHash ){
rc = SQLITE_NOMEM;
@@ -120612,7 +141158,7 @@ SQLITE_PRIVATE int sqlite3Fts3Init(sqlite3 *db){
if( sqlite3Fts3HashInsert(pHash, "simple", 7, (void *)pSimple)
|| sqlite3Fts3HashInsert(pHash, "porter", 7, (void *)pPorter)
-#ifdef SQLITE_ENABLE_FTS4_UNICODE61
+#ifndef SQLITE_DISABLE_FTS3_UNICODE
|| sqlite3Fts3HashInsert(pHash, "unicode61", 10, (void *)pUnicode)
#endif
#ifdef SQLITE_ENABLE_ICU
@@ -120649,9 +141195,13 @@ SQLITE_PRIVATE int sqlite3Fts3Init(sqlite3 *db){
db, "fts4", &fts3Module, (void *)pHash, 0
);
}
+ if( rc==SQLITE_OK ){
+ rc = sqlite3Fts3InitTok(db, (void *)pHash);
+ }
return rc;
}
+
/* An error has occurred. Delete the hash table and return the error code. */
assert( rc!=SQLITE_OK );
if( pHash ){
@@ -120715,14 +141265,17 @@ static void fts3EvalAllocateReaders(
** This function assumes that pList points to a buffer allocated using
** sqlite3_malloc(). This function takes responsibility for eventually
** freeing the buffer.
+**
+** SQLITE_OK is returned if successful, or SQLITE_NOMEM if an error occurs.
*/
-static void fts3EvalPhraseMergeToken(
+static int 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 */
){
+ int rc = SQLITE_OK;
assert( iToken!=p->iDoclistToken );
if( pList==0 ){
@@ -120761,13 +141314,16 @@ static void fts3EvalPhraseMergeToken(
nDiff = p->iDoclistToken - iToken;
}
- fts3DoclistPhraseMerge(pTab->bDescIdx, nDiff, pLeft, nLeft, pRight,&nRight);
+ rc = 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;
+ return rc;
}
/*
@@ -120793,7 +141349,7 @@ static int fts3EvalPhraseLoad(
char *pThis = 0;
rc = fts3TermSelect(pTab, pToken, p->iColumn, &nThis, &pThis);
if( rc==SQLITE_OK ){
- fts3EvalPhraseMergeToken(pTab, p, iToken, pThis, nThis);
+ rc = fts3EvalPhraseMergeToken(pTab, p, iToken, pThis, nThis);
}
}
assert( pToken->pSegcsr==0 );
@@ -120907,6 +141463,12 @@ static int fts3EvalDeferredPhrase(Fts3Cursor *pCsr, Fts3Phrase *pPhrase){
}
/*
+** Maximum number of tokens a phrase may have to be considered for the
+** incremental doclists strategy.
+*/
+#define MAX_INCR_PHRASE_TOKENS 4
+
+/*
** 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
@@ -120919,23 +141481,42 @@ static int fts3EvalDeferredPhrase(Fts3Cursor *pCsr, Fts3Phrase *pPhrase){
** 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;
+ int rc = SQLITE_OK; /* Error code */
+ int i;
- if( pCsr->bDesc==pTab->bDescIdx
- && bOptOk==1
- && p->nToken==1
- && pFirst->pSegcsr
- && pFirst->pSegcsr->bLookup
- && pFirst->bFirst==0
- ){
+ /* Determine if doclists may be loaded from disk incrementally. This is
+ ** possible if the bOptOk argument is true, the FTS doclists will be
+ ** scanned in forward order, and the phrase consists of
+ ** MAX_INCR_PHRASE_TOKENS or fewer tokens, none of which are are "^first"
+ ** tokens or prefix tokens that cannot use a prefix-index. */
+ int bHaveIncr = 0;
+ int bIncrOk = (bOptOk
+ && pCsr->bDesc==pTab->bDescIdx
+ && p->nToken<=MAX_INCR_PHRASE_TOKENS && p->nToken>0
+#ifdef SQLITE_TEST
+ && pTab->bNoIncrDoclist==0
+#endif
+ );
+ for(i=0; bIncrOk==1 && i<p->nToken; i++){
+ Fts3PhraseToken *pToken = &p->aToken[i];
+ if( pToken->bFirst || (pToken->pSegcsr!=0 && !pToken->pSegcsr->bLookup) ){
+ bIncrOk = 0;
+ }
+ if( pToken->pSegcsr ) bHaveIncr = 1;
+ }
+
+ if( bIncrOk && bHaveIncr ){
/* Use the incremental approach. */
int iCol = (p->iColumn >= pTab->nColumn ? -1 : p->iColumn);
- rc = sqlite3Fts3MsrIncrStart(
- pTab, pFirst->pSegcsr, iCol, pFirst->z, pFirst->n);
+ for(i=0; rc==SQLITE_OK && i<p->nToken; i++){
+ Fts3PhraseToken *pToken = &p->aToken[i];
+ Fts3MultiSegReader *pSegcsr = pToken->pSegcsr;
+ if( pSegcsr ){
+ rc = sqlite3Fts3MsrIncrStart(pTab, pSegcsr, iCol, pToken->z, pToken->n);
+ }
+ }
p->bIncr = 1;
-
}else{
/* Load the full doclist for the phrase into memory. */
rc = fts3EvalPhraseLoad(pCsr, p);
@@ -121032,6 +141613,7 @@ SQLITE_PRIVATE void sqlite3Fts3DoclistNext(
p += sqlite3Fts3GetVarint(p, piDocid);
}else{
fts3PoslistCopy(0, &p);
+ while( p<&aDoclist[nDoclist] && *p==0 ) p++;
if( p>=&aDoclist[nDoclist] ){
*pbEof = 1;
}else{
@@ -121045,15 +141627,125 @@ SQLITE_PRIVATE void sqlite3Fts3DoclistNext(
}
/*
-** Attempt to move the phrase iterator to point to the next matching docid.
+** Advance the iterator pDL to the next entry in pDL->aAll/nAll. Set *pbEof
+** to true if EOF is reached.
+*/
+static void fts3EvalDlPhraseNext(
+ Fts3Table *pTab,
+ Fts3Doclist *pDL,
+ u8 *pbEof
+){
+ 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;
+ }
+}
+
+/*
+** Helper type used by fts3EvalIncrPhraseNext() and incrPhraseTokenNext().
+*/
+typedef struct TokenDoclist TokenDoclist;
+struct TokenDoclist {
+ int bIgnore;
+ sqlite3_int64 iDocid;
+ char *pList;
+ int nList;
+};
+
+/*
+** Token pToken is an incrementally loaded token that is part of a
+** multi-token phrase. Advance it to the next matching document in the
+** database and populate output variable *p with the details of the new
+** entry. Or, if the iterator has reached EOF, set *pbEof to true.
+**
** If an error occurs, return an SQLite error code. Otherwise, return
** SQLITE_OK.
+*/
+static int incrPhraseTokenNext(
+ Fts3Table *pTab, /* Virtual table handle */
+ Fts3Phrase *pPhrase, /* Phrase to advance token of */
+ int iToken, /* Specific token to advance */
+ TokenDoclist *p, /* OUT: Docid and doclist for new entry */
+ u8 *pbEof /* OUT: True if iterator is at EOF */
+){
+ int rc = SQLITE_OK;
+
+ if( pPhrase->iDoclistToken==iToken ){
+ assert( p->bIgnore==0 );
+ assert( pPhrase->aToken[iToken].pSegcsr==0 );
+ fts3EvalDlPhraseNext(pTab, &pPhrase->doclist, pbEof);
+ p->pList = pPhrase->doclist.pList;
+ p->nList = pPhrase->doclist.nList;
+ p->iDocid = pPhrase->doclist.iDocid;
+ }else{
+ Fts3PhraseToken *pToken = &pPhrase->aToken[iToken];
+ assert( pToken->pDeferred==0 );
+ assert( pToken->pSegcsr || pPhrase->iDoclistToken>=0 );
+ if( pToken->pSegcsr ){
+ assert( p->bIgnore==0 );
+ rc = sqlite3Fts3MsrIncrNext(
+ pTab, pToken->pSegcsr, &p->iDocid, &p->pList, &p->nList
+ );
+ if( p->pList==0 ) *pbEof = 1;
+ }else{
+ p->bIgnore = 1;
+ }
+ }
+
+ return rc;
+}
+
+
+/*
+** The phrase iterator passed as the second argument:
+**
+** * features at least one token that uses an incremental doclist, and
+**
+** * does not contain any deferred tokens.
+**
+** Advance it to the next matching documnent in the database and populate
+** the Fts3Doclist.pList and nList fields.
**
** 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.
+**
+** If an error occurs, return an SQLite error code. Otherwise, return
+** SQLITE_OK.
*/
-static int fts3EvalPhraseNext(
+static int fts3EvalIncrPhraseNext(
Fts3Cursor *pCsr, /* FTS Cursor handle */
Fts3Phrase *p, /* Phrase object to advance to next docid */
u8 *pbEof /* OUT: Set to 1 if EOF */
@@ -121061,57 +141753,116 @@ static int fts3EvalPhraseNext(
int rc = SQLITE_OK;
Fts3Doclist *pDL = &p->doclist;
Fts3Table *pTab = (Fts3Table *)pCsr->base.pVtab;
+ u8 bEof = 0;
- if( p->bIncr ){
- assert( p->nToken==1 );
- assert( pDL->pNextDocid==0 );
+ /* This is only called if it is guaranteed that the phrase has at least
+ ** one incremental token. In which case the bIncr flag is set. */
+ assert( p->bIncr==1 );
+
+ if( p->nToken==1 && p->bIncr ){
rc = sqlite3Fts3MsrIncrNext(pTab, p->aToken[0].pSegcsr,
&pDL->iDocid, &pDL->pList, &pDL->nList
);
- if( rc==SQLITE_OK && !pDL->pList ){
- *pbEof = 1;
+ if( pDL->pList==0 ) bEof = 1;
+ }else{
+ int bDescDoclist = pCsr->bDesc;
+ struct TokenDoclist a[MAX_INCR_PHRASE_TOKENS];
+
+ memset(a, 0, sizeof(a));
+ assert( p->nToken<=MAX_INCR_PHRASE_TOKENS );
+ assert( p->iDoclistToken<MAX_INCR_PHRASE_TOKENS );
+
+ while( bEof==0 ){
+ int bMaxSet = 0;
+ sqlite3_int64 iMax = 0; /* Largest docid for all iterators */
+ int i; /* Used to iterate through tokens */
+
+ /* Advance the iterator for each token in the phrase once. */
+ for(i=0; rc==SQLITE_OK && i<p->nToken && bEof==0; i++){
+ rc = incrPhraseTokenNext(pTab, p, i, &a[i], &bEof);
+ if( a[i].bIgnore==0 && (bMaxSet==0 || DOCID_CMP(iMax, a[i].iDocid)<0) ){
+ iMax = a[i].iDocid;
+ bMaxSet = 1;
+ }
+ }
+ assert( rc!=SQLITE_OK || (p->nToken>=1 && a[p->nToken-1].bIgnore==0) );
+ assert( rc!=SQLITE_OK || bMaxSet );
+
+ /* Keep advancing iterators until they all point to the same document */
+ for(i=0; i<p->nToken; i++){
+ while( rc==SQLITE_OK && bEof==0
+ && a[i].bIgnore==0 && DOCID_CMP(a[i].iDocid, iMax)<0
+ ){
+ rc = incrPhraseTokenNext(pTab, p, i, &a[i], &bEof);
+ if( DOCID_CMP(a[i].iDocid, iMax)>0 ){
+ iMax = a[i].iDocid;
+ i = 0;
+ }
+ }
+ }
+
+ /* Check if the current entries really are a phrase match */
+ if( bEof==0 ){
+ int nList = 0;
+ int nByte = a[p->nToken-1].nList;
+ char *aDoclist = sqlite3_malloc(nByte+1);
+ if( !aDoclist ) return SQLITE_NOMEM;
+ memcpy(aDoclist, a[p->nToken-1].pList, nByte+1);
+
+ for(i=0; i<(p->nToken-1); i++){
+ if( a[i].bIgnore==0 ){
+ char *pL = a[i].pList;
+ char *pR = aDoclist;
+ char *pOut = aDoclist;
+ int nDist = p->nToken-1-i;
+ int res = fts3PoslistPhraseMerge(&pOut, nDist, 0, 1, &pL, &pR);
+ if( res==0 ) break;
+ nList = (int)(pOut - aDoclist);
+ }
+ }
+ if( i==(p->nToken-1) ){
+ pDL->iDocid = iMax;
+ pDL->pList = aDoclist;
+ pDL->nList = nList;
+ pDL->bFreeList = 1;
+ break;
+ }
+ sqlite3_free(aDoclist);
+ }
}
+ }
+
+ *pbEof = bEof;
+ return rc;
+}
+
+/*
+** 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 ){
+ rc = fts3EvalIncrPhraseNext(pCsr, p, pbEof);
}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;
- }
+ fts3EvalDlPhraseNext(pTab, pDL, pbEof);
}
return rc;
@@ -121136,21 +141887,22 @@ static int fts3EvalPhraseNext(
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;
+ if( nToken ){
+ int i;
+ for(i=0; i<nToken; i++){
+ if( pExpr->pPhrase->aToken[i].pDeferred==0 ) break;
+ }
+ pExpr->bDeferred = (i==nToken);
}
- pExpr->bDeferred = (i==nToken);
- *pRc = fts3EvalPhraseStart(pCsr, bOptOk, pExpr->pPhrase);
+ *pRc = fts3EvalPhraseStart(pCsr, 1, pExpr->pPhrase);
}else{
- fts3EvalStartReaders(pCsr, pExpr->pLeft, bOptOk, pRc);
- fts3EvalStartReaders(pCsr, pExpr->pRight, bOptOk, pRc);
+ fts3EvalStartReaders(pCsr, pExpr->pLeft, pRc);
+ fts3EvalStartReaders(pCsr, pExpr->pRight, pRc);
pExpr->bDeferred = (pExpr->pLeft->bDeferred && pExpr->pRight->bDeferred);
}
}
@@ -121392,7 +142144,7 @@ static int fts3EvalSelectDeferred(
** overflowing the 32-bit integer it is stored in. */
if( ii<12 ) nLoad4 = nLoad4*4;
- if( ii==0 || pTC->pPhrase->nToken>1 ){
+ if( ii==0 || (pTC->pPhrase->nToken>1 && ii!=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. */
@@ -121402,8 +142154,12 @@ static int fts3EvalSelectDeferred(
rc = fts3TermSelect(pTab, pToken, pTC->iCol, &nList, &pList);
assert( rc==SQLITE_OK || pList==0 );
if( rc==SQLITE_OK ){
+ rc = fts3EvalPhraseMergeToken(
+ pTab, pTC->pPhrase, pTC->iToken,pList,nList
+ );
+ }
+ if( rc==SQLITE_OK ){
int nCount;
- fts3EvalPhraseMergeToken(pTab, pTC->pPhrase, pTC->iToken,pList,nList);
nCount = fts3DoclistCountDocids(
pTC->pPhrase->doclist.aAll, pTC->pPhrase->doclist.nAll
);
@@ -121472,7 +142228,7 @@ static int fts3EvalStart(Fts3Cursor *pCsr){
}
#endif
- fts3EvalStartReaders(pCsr, pCsr->pExpr, 1, &rc);
+ fts3EvalStartReaders(pCsr, pCsr->pExpr, &rc);
return rc;
}
@@ -121581,7 +142337,7 @@ static int fts3EvalNearTrim(
** 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
+** See sqlite3Fts3EvalTestDeferred() for details on testing if a row is
** really a match, taking into account deferred tokens and NEAR operators.
*/
static void fts3EvalNextRow(
@@ -121628,6 +142384,22 @@ static void fts3EvalNextRow(
}
pExpr->iDocid = pLeft->iDocid;
pExpr->bEof = (pLeft->bEof || pRight->bEof);
+ if( pExpr->eType==FTSQUERY_NEAR && pExpr->bEof ){
+ if( pRight->pPhrase && pRight->pPhrase->doclist.aAll ){
+ Fts3Doclist *pDl = &pRight->pPhrase->doclist;
+ while( *pRc==SQLITE_OK && pRight->bEof==0 ){
+ memset(pDl->pList, 0, pDl->nList);
+ fts3EvalNextRow(pCsr, pRight, pRc);
+ }
+ }
+ if( pLeft->pPhrase && pLeft->pPhrase->doclist.aAll ){
+ Fts3Doclist *pDl = &pLeft->pPhrase->doclist;
+ while( *pRc==SQLITE_OK && pLeft->bEof==0 ){
+ memset(pDl->pList, 0, pDl->nList);
+ fts3EvalNextRow(pCsr, pLeft, pRc);
+ }
+ }
+ }
}
break;
}
@@ -121785,7 +142557,7 @@ static int fts3EvalNearTest(Fts3Expr *pExpr, int *pRc){
}
/*
-** This function is a helper function for fts3EvalTestDeferredAndNear().
+** This function is a helper function for sqlite3Fts3EvalTestDeferred().
** 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.
@@ -121906,7 +142678,7 @@ static int fts3EvalTestExpr(
** 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){
+SQLITE_PRIVATE int sqlite3Fts3EvalTestDeferred(Fts3Cursor *pCsr, int *pRc){
int rc = *pRc;
int bMiss = 0;
if( rc==SQLITE_OK ){
@@ -121953,8 +142725,18 @@ static int fts3EvalNext(Fts3Cursor *pCsr){
pCsr->isRequireSeek = 1;
pCsr->isMatchinfoNeeded = 1;
pCsr->iPrevId = pExpr->iDocid;
- }while( pCsr->isEof==0 && fts3EvalTestDeferredAndNear(pCsr, &rc) );
+ }while( pCsr->isEof==0 && sqlite3Fts3EvalTestDeferred(pCsr, &rc) );
}
+
+ /* Check if the cursor is past the end of the docid range specified
+ ** by Fts3Cursor.iMinDocid/iMaxDocid. If so, set the EOF flag. */
+ if( rc==SQLITE_OK && (
+ (pCsr->bDesc==0 && pCsr->iPrevId>pCsr->iMaxDocid)
+ || (pCsr->bDesc!=0 && pCsr->iPrevId<pCsr->iMinDocid)
+ )){
+ pCsr->isEof = 1;
+ }
+
return rc;
}
@@ -121978,14 +142760,19 @@ static void fts3EvalRestart(
if( pPhrase ){
fts3EvalInvalidatePoslist(pPhrase);
if( pPhrase->bIncr ){
- assert( pPhrase->nToken==1 );
- assert( pPhrase->aToken[0].pSegcsr );
- sqlite3Fts3MsrIncrRestart(pPhrase->aToken[0].pSegcsr);
+ int i;
+ for(i=0; i<pPhrase->nToken; i++){
+ Fts3PhraseToken *pToken = &pPhrase->aToken[i];
+ assert( pToken->pDeferred==0 );
+ if( pToken->pSegcsr ){
+ sqlite3Fts3MsrIncrRestart(pToken->pSegcsr);
+ }
+ }
*pRc = fts3EvalPhraseStart(pCsr, 0, pPhrase);
}
-
pPhrase->doclist.pNextDocid = 0;
pPhrase->doclist.iDocid = 0;
+ pPhrase->pOrPoslist = 0;
}
pExpr->iDocid = 0;
@@ -122028,7 +142815,7 @@ static void fts3EvalUpdateCounts(Fts3Expr *pExpr){
pExpr->aMI[iCol*3 + 2] += (iCnt>0);
if( *p==0x00 ) break;
p++;
- p += sqlite3Fts3GetVarint32(p, &iCol);
+ p += fts3GetVarint32(p, &iCol);
}
}
@@ -122099,7 +142886,7 @@ static int fts3EvalGatherStats(
pCsr->iPrevId = pRoot->iDocid;
}while( pCsr->isEof==0
&& pRoot->eType==FTSQUERY_NEAR
- && fts3EvalTestDeferredAndNear(pCsr, &rc)
+ && sqlite3Fts3EvalTestDeferred(pCsr, &rc)
);
if( rc==SQLITE_OK && pCsr->isEof==0 ){
@@ -122124,7 +142911,6 @@ static int fts3EvalGatherStats(
fts3EvalNextRow(pCsr, pRoot, &rc);
assert( pRoot->bEof==0 );
}while( pRoot->iDocid!=iDocid && rc==SQLITE_OK );
- fts3EvalTestDeferredAndNear(pCsr, &rc);
}
}
return rc;
@@ -122198,7 +142984,7 @@ SQLITE_PRIVATE int sqlite3Fts3EvalPhraseStats(
** 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)
+** occurrence 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:
@@ -122231,16 +143017,24 @@ SQLITE_PRIVATE int sqlite3Fts3EvalPhrasePoslist(
iDocid = pExpr->iDocid;
pIter = pPhrase->doclist.pList;
if( iDocid!=pCsr->iPrevId || pExpr->bEof ){
+ int rc = SQLITE_OK;
int bDescDoclist = pTab->bDescIdx; /* For DOCID_CMP macro */
int bOr = 0;
- u8 bEof = 0;
- Fts3Expr *p;
+ u8 bTreeEof = 0;
+ Fts3Expr *p; /* Used to iterate from pExpr to root */
+ Fts3Expr *pNear; /* Most senior NEAR ancestor (or pExpr) */
+ int bMatch;
/* 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. */
+ ** pCsr->iPrevId may lie earlier in the doclist buffer. Or, if the
+ ** tree that the node is part of has been marked as EOF, but the node
+ ** itself is not EOF, then it may point to an earlier entry. */
+ pNear = pExpr;
for(p=pExpr->pParent; p; p=p->pParent){
if( p->eType==FTSQUERY_OR ) bOr = 1;
+ if( p->eType==FTSQUERY_NEAR ) pNear = p;
+ if( p->bEof ) bTreeEof = 1;
}
if( bOr==0 ) return SQLITE_OK;
@@ -122248,58 +143042,79 @@ SQLITE_PRIVATE int sqlite3Fts3EvalPhrasePoslist(
** 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;
+ int bEofSave = pNear->bEof;
+ fts3EvalRestart(pCsr, pNear, &rc);
+ while( rc==SQLITE_OK && !pNear->bEof ){
+ fts3EvalNextRow(pCsr, pNear, &rc);
+ if( bEofSave==0 && pNear->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
- );
+ if( bTreeEof ){
+ while( rc==SQLITE_OK && !pNear->bEof ){
+ fts3EvalNextRow(pCsr, pNear, &rc);
}
- }else{
- while( (pIter==0 || DOCID_CMP(iDocid, pCsr->iPrevId)<0 ) && bEof==0 ){
- sqlite3Fts3DoclistNext(
- bDescDoclist, pPhrase->doclist.aAll, pPhrase->doclist.nAll,
- &pIter, &iDocid, &bEof
- );
+ }
+ if( rc!=SQLITE_OK ) return rc;
+
+ bMatch = 1;
+ for(p=pNear; p; p=p->pLeft){
+ u8 bEof = 0;
+ Fts3Expr *pTest = p;
+ Fts3Phrase *pPh;
+ assert( pTest->eType==FTSQUERY_NEAR || pTest->eType==FTSQUERY_PHRASE );
+ if( pTest->eType==FTSQUERY_NEAR ) pTest = pTest->pRight;
+ assert( pTest->eType==FTSQUERY_PHRASE );
+ pPh = pTest->pPhrase;
+
+ pIter = pPh->pOrPoslist;
+ iDocid = pPh->iOrDocid;
+ if( pCsr->bDesc==bDescDoclist ){
+ bEof = !pPh->doclist.nAll ||
+ (pIter >= (pPh->doclist.aAll + pPh->doclist.nAll));
+ while( (pIter==0 || DOCID_CMP(iDocid, pCsr->iPrevId)<0 ) && bEof==0 ){
+ sqlite3Fts3DoclistNext(
+ bDescDoclist, pPh->doclist.aAll, pPh->doclist.nAll,
+ &pIter, &iDocid, &bEof
+ );
+ }
+ }else{
+ bEof = !pPh->doclist.nAll || (pIter && pIter<=pPh->doclist.aAll);
+ while( (pIter==0 || DOCID_CMP(iDocid, pCsr->iPrevId)>0 ) && bEof==0 ){
+ int dummy;
+ sqlite3Fts3DoclistPrev(
+ bDescDoclist, pPh->doclist.aAll, pPh->doclist.nAll,
+ &pIter, &iDocid, &dummy, &bEof
+ );
+ }
}
+ pPh->pOrPoslist = pIter;
+ pPh->iOrDocid = iDocid;
+ if( bEof || iDocid!=pCsr->iPrevId ) bMatch = 0;
}
- if( bEof || iDocid!=pCsr->iPrevId ) pIter = 0;
+ if( bMatch ){
+ pIter = pPhrase->pOrPoslist;
+ }else{
+ pIter = 0;
+ }
}
if( pIter==0 ) return SQLITE_OK;
if( *pIter==0x01 ){
pIter++;
- pIter += sqlite3Fts3GetVarint32(pIter, &iThis);
+ pIter += fts3GetVarint32(pIter, &iThis);
}else{
iThis = 0;
}
while( iThis<iCol ){
fts3ColumnlistCopy(0, &pIter);
- if( *pIter==0x00 ) return 0;
+ if( *pIter==0x00 ) return SQLITE_OK;
pIter++;
- pIter += sqlite3Fts3GetVarint32(pIter, &iThis);
+ pIter += fts3GetVarint32(pIter, &iThis);
+ }
+ if( *pIter==0x00 ){
+ pIter = 0;
}
*ppOut = ((iCol==iThis)?pIter:0);
@@ -122340,7 +143155,10 @@ SQLITE_PRIVATE int sqlite3Fts3Corrupt(){
/*
** Initialize API pointer table, if required.
*/
-SQLITE_API int sqlite3_extension_init(
+#ifdef _WIN32
+__declspec(dllexport)
+#endif
+SQLITE_API int SQLITE_STDCALL sqlite3_fts3_init(
sqlite3 *db,
char **pzErrMsg,
const sqlite3_api_routines *pApi
@@ -122367,6 +143185,7 @@ SQLITE_API int sqlite3_extension_init(
******************************************************************************
**
*/
+/* #include "fts3Int.h" */
#if !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_FTS3)
/* #include <string.h> */
@@ -122386,6 +143205,7 @@ struct Fts3auxCursor {
Fts3SegFilter filter;
char *zStop;
int nStop; /* Byte-length of string zStop */
+ int iLangid; /* Language id to query */
int isEof; /* True if cursor is at EOF */
sqlite3_int64 iRowid; /* Current rowid */
@@ -122400,7 +143220,8 @@ struct Fts3auxCursor {
/*
** Schema of the terms table.
*/
-#define FTS3_TERMS_SCHEMA "CREATE TABLE x(term, col, documents, occurrences)"
+#define FTS3_AUX_SCHEMA \
+ "CREATE TABLE x(term, col, documents, occurrences, languageid HIDDEN)"
/*
** This function does all the work for both the xConnect and xCreate methods.
@@ -122425,20 +143246,29 @@ static int fts3auxConnectMethod(
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;
- }
+ /* The user should invoke this in one of two forms:
+ **
+ ** CREATE VIRTUAL TABLE xxx USING fts4aux(fts4-table);
+ ** CREATE VIRTUAL TABLE xxx USING fts4aux(fts4-table-db, fts4-table);
+ */
+ if( argc!=4 && argc!=5 ) goto bad_args;
zDb = argv[1];
nDb = (int)strlen(zDb);
- zFts3 = argv[3];
+ if( argc==5 ){
+ if( nDb==4 && 0==sqlite3_strnicmp("temp", zDb, 4) ){
+ zDb = argv[3];
+ nDb = (int)strlen(zDb);
+ zFts3 = argv[4];
+ }else{
+ goto bad_args;
+ }
+ }else{
+ zFts3 = argv[3];
+ }
nFts3 = (int)strlen(zFts3);
- rc = sqlite3_declare_vtab(db, FTS3_TERMS_SCHEMA);
+ rc = sqlite3_declare_vtab(db, FTS3_AUX_SCHEMA);
if( rc!=SQLITE_OK ) return rc;
nByte = sizeof(Fts3auxTable) + sizeof(Fts3Table) + nDb + nFts3 + 2;
@@ -122458,6 +143288,10 @@ static int fts3auxConnectMethod(
*ppVtab = (sqlite3_vtab *)p;
return SQLITE_OK;
+
+ bad_args:
+ sqlite3Fts3ErrMsg(pzErr, "invalid arguments to fts4aux constructor");
+ return SQLITE_ERROR;
}
/*
@@ -122494,6 +143328,8 @@ static int fts3auxBestIndexMethod(
int iEq = -1;
int iGe = -1;
int iLe = -1;
+ int iLangid = -1;
+ int iNext = 1; /* Next free argvIndex value */
UNUSED_PARAMETER(pVTab);
@@ -122505,36 +143341,48 @@ static int fts3auxBestIndexMethod(
pInfo->orderByConsumed = 1;
}
- /* Search for equality and range constraints on the "term" column. */
+ /* Search for equality and range constraints on the "term" column.
+ ** And equality constraints on the hidden "languageid" column. */
for(i=0; i<pInfo->nConstraint; i++){
- if( pInfo->aConstraint[i].usable && pInfo->aConstraint[i].iColumn==0 ){
+ if( pInfo->aConstraint[i].usable ){
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;
+ int iCol = pInfo->aConstraint[i].iColumn;
+
+ if( iCol==0 ){
+ 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( iCol==4 ){
+ if( op==SQLITE_INDEX_CONSTRAINT_EQ ) iLangid = i;
+ }
}
}
if( iEq>=0 ){
pInfo->idxNum = FTS4AUX_EQ_CONSTRAINT;
- pInfo->aConstraintUsage[iEq].argvIndex = 1;
+ pInfo->aConstraintUsage[iEq].argvIndex = iNext++;
pInfo->estimatedCost = 5;
}else{
pInfo->idxNum = 0;
pInfo->estimatedCost = 20000;
if( iGe>=0 ){
pInfo->idxNum += FTS4AUX_GE_CONSTRAINT;
- pInfo->aConstraintUsage[iGe].argvIndex = 1;
+ pInfo->aConstraintUsage[iGe].argvIndex = iNext++;
pInfo->estimatedCost /= 2;
}
if( iLe>=0 ){
pInfo->idxNum += FTS4AUX_LE_CONSTRAINT;
- pInfo->aConstraintUsage[iLe].argvIndex = 1 + (iGe>=0);
+ pInfo->aConstraintUsage[iLe].argvIndex = iNext++;
pInfo->estimatedCost /= 2;
}
}
+ if( iLangid>=0 ){
+ pInfo->aConstraintUsage[iLangid].argvIndex = iNext++;
+ pInfo->estimatedCost--;
+ }
return SQLITE_OK;
}
@@ -122694,7 +143542,14 @@ static int fts3auxFilterMethod(
Fts3auxCursor *pCsr = (Fts3auxCursor *)pCursor;
Fts3Table *pFts3 = ((Fts3auxTable *)pCursor->pVtab)->pFts3Tab;
int rc;
- int isScan;
+ int isScan = 0;
+ int iLangVal = 0; /* Language id to query */
+
+ int iEq = -1; /* Index of term=? value in apVal */
+ int iGe = -1; /* Index of term>=? value in apVal */
+ int iLe = -1; /* Index of term<=? value in apVal */
+ int iLangid = -1; /* Index of languageid=? value in apVal */
+ int iNext = 0;
UNUSED_PARAMETER(nVal);
UNUSED_PARAMETER(idxStr);
@@ -122704,7 +143559,21 @@ static int fts3auxFilterMethod(
|| idxNum==FTS4AUX_LE_CONSTRAINT || idxNum==FTS4AUX_GE_CONSTRAINT
|| idxNum==(FTS4AUX_LE_CONSTRAINT|FTS4AUX_GE_CONSTRAINT)
);
- isScan = (idxNum!=FTS4AUX_EQ_CONSTRAINT);
+
+ if( idxNum==FTS4AUX_EQ_CONSTRAINT ){
+ iEq = iNext++;
+ }else{
+ isScan = 1;
+ if( idxNum & FTS4AUX_GE_CONSTRAINT ){
+ iGe = iNext++;
+ }
+ if( idxNum & FTS4AUX_LE_CONSTRAINT ){
+ iLe = iNext++;
+ }
+ }
+ if( iNext<nVal ){
+ iLangid = iNext++;
+ }
/* In case this cursor is being reused, close and zero it. */
testcase(pCsr->filter.zTerm);
@@ -122716,22 +143585,35 @@ static int fts3auxFilterMethod(
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) ){
+ if( iEq>=0 || iGe>=0 ){
const unsigned char *zStr = sqlite3_value_text(apVal[0]);
+ assert( (iEq==0 && iGe==-1) || (iEq==-1 && iGe==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( iLe>=0 ){
+ pCsr->zStop = sqlite3_mprintf("%s", sqlite3_value_text(apVal[iLe]));
+ pCsr->nStop = sqlite3_value_bytes(apVal[iLe]);
if( pCsr->zStop==0 ) return SQLITE_NOMEM;
}
+
+ if( iLangid>=0 ){
+ iLangVal = sqlite3_value_int(apVal[iLangid]);
+
+ /* If the user specified a negative value for the languageid, use zero
+ ** instead. This works, as the "languageid=?" constraint will also
+ ** be tested by the VDBE layer. The test will always be false (since
+ ** this module will not return a row with a negative languageid), and
+ ** so the overall query will return zero rows. */
+ if( iLangVal<0 ) iLangVal = 0;
+ }
+ pCsr->iLangid = iLangVal;
- rc = sqlite3Fts3SegReaderCursor(pFts3, 0, 0, FTS3_SEGCURSOR_ALL,
+ rc = sqlite3Fts3SegReaderCursor(pFts3, iLangVal, 0, FTS3_SEGCURSOR_ALL,
pCsr->filter.zTerm, pCsr->filter.nTerm, 0, isScan, &pCsr->csr
);
if( rc==SQLITE_OK ){
@@ -122755,24 +143637,37 @@ static int fts3auxEofMethod(sqlite3_vtab_cursor *pCursor){
*/
static int fts3auxColumnMethod(
sqlite3_vtab_cursor *pCursor, /* Cursor to retrieve value from */
- sqlite3_context *pContext, /* Context for sqlite3_result_xxx() calls */
+ sqlite3_context *pCtx, /* 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);
+ switch( iCol ){
+ case 0: /* term */
+ sqlite3_result_text(pCtx, p->csr.zTerm, p->csr.nTerm, SQLITE_TRANSIENT);
+ break;
+
+ case 1: /* col */
+ if( p->iCol ){
+ sqlite3_result_int(pCtx, p->iCol-1);
+ }else{
+ sqlite3_result_text(pCtx, "*", -1, SQLITE_STATIC);
+ }
+ break;
+
+ case 2: /* documents */
+ sqlite3_result_int64(pCtx, p->aStat[p->iCol].nDoc);
+ break;
+
+ case 3: /* occurrences */
+ sqlite3_result_int64(pCtx, p->aStat[p->iCol].nOcc);
+ break;
+
+ default: /* languageid */
+ assert( iCol==4 );
+ sqlite3_result_int(pCtx, p->iLangid);
+ break;
}
return SQLITE_OK;
@@ -122847,6 +143742,7 @@ SQLITE_PRIVATE int sqlite3Fts3InitAux(sqlite3 *db){
** syntax is relatively simple, the whole tokenizer/parser system is
** hand-coded.
*/
+/* #include "fts3Int.h" */
#if !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_FTS3)
/*
@@ -122937,7 +143833,7 @@ struct ParseContext {
** 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
+** is defined to accept an argument of type int, its behavior 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
@@ -122986,6 +143882,11 @@ SQLITE_PRIVATE int sqlite3Fts3OpenTokenizer(
return rc;
}
+/*
+** 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 *);
/*
** Extract the next token from buffer z (length n) using the tokenizer
@@ -123011,9 +143912,16 @@ static int getNextToken(
int rc;
sqlite3_tokenizer_cursor *pCursor;
Fts3Expr *pRet = 0;
- int nConsumed = 0;
+ int i = 0;
+
+ /* Set variable i to the maximum number of bytes of input to tokenize. */
+ for(i=0; i<n; i++){
+ if( sqlite3_fts3_enable_parentheses && (z[i]=='(' || z[i]==')') ) break;
+ if( z[i]=='"' ) break;
+ }
- rc = sqlite3Fts3OpenTokenizer(pTokenizer, pParse->iLangid, z, n, &pCursor);
+ *pnConsumed = i;
+ rc = sqlite3Fts3OpenTokenizer(pTokenizer, pParse->iLangid, z, i, &pCursor);
if( rc==SQLITE_OK ){
const char *zToken;
int nToken = 0, iStart = 0, iEnd = 0, iPosition = 0;
@@ -123054,13 +143962,14 @@ static int getNextToken(
}
}
- nConsumed = iEnd;
+ *pnConsumed = iEnd;
+ }else if( i && rc==SQLITE_DONE ){
+ rc = SQLITE_OK;
}
pModule->xClose(pCursor);
}
- *pnConsumed = nConsumed;
*ppExpr = pRet;
return rc;
}
@@ -123201,12 +144110,6 @@ no_mem:
}
/*
-** 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.
**
@@ -123302,27 +144205,6 @@ static int getNextNode(
}
}
- /* 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
@@ -123337,6 +144219,21 @@ static int getNextNode(
return getNextString(pParse, &zInput[1], ii-1, ppExpr);
}
+ if( sqlite3_fts3_enable_parentheses ){
+ if( *zInput=='(' ){
+ int nConsumed = 0;
+ 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;
+ }else if( *zInput==')' ){
+ pParse->nNest--;
+ *pnConsumed = (int)((zInput - z) + 1);
+ *ppExpr = 0;
+ return SQLITE_DONE;
+ }
+ }
/* 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
@@ -123455,94 +144352,100 @@ static int fts3ExprParse(
while( rc==SQLITE_OK ){
Fts3Expr *p = 0;
int nByte = 0;
+
rc = getNextNode(pParse, zIn, nIn, &p, &nByte);
+ assert( nByte>0 || (rc!=SQLITE_OK && p==0) );
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);
+ if( p ){
+ int isPhrase;
- /* 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 ){
+ 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;
}
- pAnd->eType = FTSQUERY_AND;
- insertBinaryOperator(&pRet, pPrev, pAnd);
- pPrev = pAnd;
- }
+ pNot->eType = FTSQUERY_NOT;
+ pNot->pRight = p;
+ p->pParent = pNot;
+ if( pNotBranch ){
+ pNot->pLeft = pNotBranch;
+ pNotBranch->pParent = pNot;
+ }
+ pNotBranch = pNot;
+ p = pPrev;
+ }else{
+ int eType = p->eType;
+ isPhrase = (eType==FTSQUERY_PHRASE || p->pLeft);
- /* 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 && (
+ /* 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;
+ )){
+ 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{
- pRet = p;
+ insertBinaryOperator(&pRet, pPrev, p);
}
- }else{
- insertBinaryOperator(&pRet, pPrev, p);
+ isRequirePhrase = !isPhrase;
}
- isRequirePhrase = !isPhrase;
+ pPrev = p;
}
assert( nByte>0 );
}
assert( rc!=SQLITE_OK || (nByte>0 && nByte<=nIn) );
nIn -= nByte;
zIn += nByte;
- pPrev = p;
}
if( rc==SQLITE_DONE && pRet && isRequirePhrase ){
@@ -123560,6 +144463,7 @@ static int fts3ExprParse(
pIter = pIter->pLeft;
}
pIter->pLeft = pRet;
+ pRet->pParent = pIter;
pRet = pNotBranch;
}
}
@@ -123577,30 +144481,210 @@ exprparse_out:
}
/*
-** 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.
+** Return SQLITE_ERROR if the maximum depth of the expression tree passed
+** as the only argument is more than nMaxDepth.
+*/
+static int fts3ExprCheckDepth(Fts3Expr *p, int nMaxDepth){
+ int rc = SQLITE_OK;
+ if( p ){
+ if( nMaxDepth<0 ){
+ rc = SQLITE_TOOBIG;
+ }else{
+ rc = fts3ExprCheckDepth(p->pLeft, nMaxDepth-1);
+ if( rc==SQLITE_OK ){
+ rc = fts3ExprCheckDepth(p->pRight, nMaxDepth-1);
+ }
+ }
+ }
+ return rc;
+}
+
+/*
+** This function attempts to transform the expression tree at (*pp) to
+** an equivalent but more balanced form. The tree is modified in place.
+** If successful, SQLITE_OK is returned and (*pp) set to point to the
+** new root expression node.
**
-** 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().
+** nMaxDepth is the maximum allowable depth of the balanced sub-tree.
**
-** 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.
+** Otherwise, if an error occurs, an SQLite error code is returned and
+** expression (*pp) freed.
+*/
+static int fts3ExprBalance(Fts3Expr **pp, int nMaxDepth){
+ int rc = SQLITE_OK; /* Return code */
+ Fts3Expr *pRoot = *pp; /* Initial root node */
+ Fts3Expr *pFree = 0; /* List of free nodes. Linked by pParent. */
+ int eType = pRoot->eType; /* Type of node in this tree */
+
+ if( nMaxDepth==0 ){
+ rc = SQLITE_ERROR;
+ }
+
+ if( rc==SQLITE_OK ){
+ if( (eType==FTSQUERY_AND || eType==FTSQUERY_OR) ){
+ Fts3Expr **apLeaf;
+ apLeaf = (Fts3Expr **)sqlite3_malloc(sizeof(Fts3Expr *) * nMaxDepth);
+ if( 0==apLeaf ){
+ rc = SQLITE_NOMEM;
+ }else{
+ memset(apLeaf, 0, sizeof(Fts3Expr *) * nMaxDepth);
+ }
+
+ if( rc==SQLITE_OK ){
+ int i;
+ Fts3Expr *p;
+
+ /* Set $p to point to the left-most leaf in the tree of eType nodes. */
+ for(p=pRoot; p->eType==eType; p=p->pLeft){
+ assert( p->pParent==0 || p->pParent->pLeft==p );
+ assert( p->pLeft && p->pRight );
+ }
+
+ /* This loop runs once for each leaf in the tree of eType nodes. */
+ while( 1 ){
+ int iLvl;
+ Fts3Expr *pParent = p->pParent; /* Current parent of p */
+
+ assert( pParent==0 || pParent->pLeft==p );
+ p->pParent = 0;
+ if( pParent ){
+ pParent->pLeft = 0;
+ }else{
+ pRoot = 0;
+ }
+ rc = fts3ExprBalance(&p, nMaxDepth-1);
+ if( rc!=SQLITE_OK ) break;
+
+ for(iLvl=0; p && iLvl<nMaxDepth; iLvl++){
+ if( apLeaf[iLvl]==0 ){
+ apLeaf[iLvl] = p;
+ p = 0;
+ }else{
+ assert( pFree );
+ pFree->pLeft = apLeaf[iLvl];
+ pFree->pRight = p;
+ pFree->pLeft->pParent = pFree;
+ pFree->pRight->pParent = pFree;
+
+ p = pFree;
+ pFree = pFree->pParent;
+ p->pParent = 0;
+ apLeaf[iLvl] = 0;
+ }
+ }
+ if( p ){
+ sqlite3Fts3ExprFree(p);
+ rc = SQLITE_TOOBIG;
+ break;
+ }
+
+ /* If that was the last leaf node, break out of the loop */
+ if( pParent==0 ) break;
+
+ /* Set $p to point to the next leaf in the tree of eType nodes */
+ for(p=pParent->pRight; p->eType==eType; p=p->pLeft);
+
+ /* Remove pParent from the original tree. */
+ assert( pParent->pParent==0 || pParent->pParent->pLeft==pParent );
+ pParent->pRight->pParent = pParent->pParent;
+ if( pParent->pParent ){
+ pParent->pParent->pLeft = pParent->pRight;
+ }else{
+ assert( pParent==pRoot );
+ pRoot = pParent->pRight;
+ }
+
+ /* Link pParent into the free node list. It will be used as an
+ ** internal node of the new tree. */
+ pParent->pParent = pFree;
+ pFree = pParent;
+ }
+
+ if( rc==SQLITE_OK ){
+ p = 0;
+ for(i=0; i<nMaxDepth; i++){
+ if( apLeaf[i] ){
+ if( p==0 ){
+ p = apLeaf[i];
+ p->pParent = 0;
+ }else{
+ assert( pFree!=0 );
+ pFree->pRight = p;
+ pFree->pLeft = apLeaf[i];
+ pFree->pLeft->pParent = pFree;
+ pFree->pRight->pParent = pFree;
+
+ p = pFree;
+ pFree = pFree->pParent;
+ p->pParent = 0;
+ }
+ }
+ }
+ pRoot = p;
+ }else{
+ /* An error occurred. Delete the contents of the apLeaf[] array
+ ** and pFree list. Everything else is cleaned up by the call to
+ ** sqlite3Fts3ExprFree(pRoot) below. */
+ Fts3Expr *pDel;
+ for(i=0; i<nMaxDepth; i++){
+ sqlite3Fts3ExprFree(apLeaf[i]);
+ }
+ while( (pDel=pFree)!=0 ){
+ pFree = pDel->pParent;
+ sqlite3_free(pDel);
+ }
+ }
+
+ assert( pFree==0 );
+ sqlite3_free( apLeaf );
+ }
+ }else if( eType==FTSQUERY_NOT ){
+ Fts3Expr *pLeft = pRoot->pLeft;
+ Fts3Expr *pRight = pRoot->pRight;
+
+ pRoot->pLeft = 0;
+ pRoot->pRight = 0;
+ pLeft->pParent = 0;
+ pRight->pParent = 0;
+
+ rc = fts3ExprBalance(&pLeft, nMaxDepth-1);
+ if( rc==SQLITE_OK ){
+ rc = fts3ExprBalance(&pRight, nMaxDepth-1);
+ }
+
+ if( rc!=SQLITE_OK ){
+ sqlite3Fts3ExprFree(pRight);
+ sqlite3Fts3ExprFree(pLeft);
+ }else{
+ assert( pLeft && pRight );
+ pRoot->pLeft = pLeft;
+ pLeft->pParent = pRoot;
+ pRoot->pRight = pRight;
+ pRight->pParent = pRoot;
+ }
+ }
+ }
+
+ if( rc!=SQLITE_OK ){
+ sqlite3Fts3ExprFree(pRoot);
+ pRoot = 0;
+ }
+ *pp = pRoot;
+ return rc;
+}
+
+/*
+** This function is similar to sqlite3Fts3ExprParse(), with the following
+** differences:
**
-** 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.
+** 1. It does not do expression rebalancing.
+** 2. It does not check that the expression does not exceed the
+** maximum allowable depth.
+** 3. Even if it fails, *ppExpr may still be set to point to an
+** expression tree. It should be deleted using sqlite3Fts3ExprFree()
+** in this case.
*/
-SQLITE_PRIVATE int sqlite3Fts3ExprParse(
+static int fts3ExprParseUnbalanced(
sqlite3_tokenizer *pTokenizer, /* Tokenizer module */
int iLangid, /* Language id for tokenizer */
char **azCol, /* Array of column names for fts3 table */
@@ -123629,28 +144713,116 @@ SQLITE_PRIVATE int sqlite3Fts3ExprParse(
n = (int)strlen(z);
}
rc = fts3ExprParse(&sParse, z, n, ppExpr, &nParsed);
+ assert( rc==SQLITE_OK || *ppExpr==0 );
/* Check for mismatched parenthesis */
if( rc==SQLITE_OK && sParse.nNest ){
rc = SQLITE_ERROR;
+ }
+
+ 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 */
+ char **pzErr /* OUT: Error message (sqlite3_malloc) */
+){
+ int rc = fts3ExprParseUnbalanced(
+ pTokenizer, iLangid, azCol, bFts4, nCol, iDefaultCol, z, n, ppExpr
+ );
+
+ /* Rebalance the expression. And check that its depth does not exceed
+ ** SQLITE_FTS3_MAX_EXPR_DEPTH. */
+ if( rc==SQLITE_OK && *ppExpr ){
+ rc = fts3ExprBalance(ppExpr, SQLITE_FTS3_MAX_EXPR_DEPTH);
+ if( rc==SQLITE_OK ){
+ rc = fts3ExprCheckDepth(*ppExpr, SQLITE_FTS3_MAX_EXPR_DEPTH);
+ }
+ }
+
+ if( rc!=SQLITE_OK ){
sqlite3Fts3ExprFree(*ppExpr);
*ppExpr = 0;
+ if( rc==SQLITE_TOOBIG ){
+ sqlite3Fts3ErrMsg(pzErr,
+ "FTS expression tree is too large (maximum depth %d)",
+ SQLITE_FTS3_MAX_EXPR_DEPTH
+ );
+ rc = SQLITE_ERROR;
+ }else if( rc==SQLITE_ERROR ){
+ sqlite3Fts3ErrMsg(pzErr, "malformed MATCH expression: [%s]", z);
+ }
}
return rc;
}
/*
+** Free a single node of an expression tree.
+*/
+static void fts3FreeExprNode(Fts3Expr *p){
+ assert( p->eType==FTSQUERY_PHRASE || p->pPhrase==0 );
+ sqlite3Fts3EvalPhraseCleanup(p->pPhrase);
+ sqlite3_free(p->aMI);
+ sqlite3_free(p);
+}
+
+/*
** Free a parsed fts3 query expression allocated by sqlite3Fts3ExprParse().
+**
+** This function would be simpler if it recursively called itself. But
+** that would mean passing a sufficiently large expression to ExprParse()
+** could cause a stack overflow.
*/
-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);
+SQLITE_PRIVATE void sqlite3Fts3ExprFree(Fts3Expr *pDel){
+ Fts3Expr *p;
+ assert( pDel==0 || pDel->pParent==0 );
+ for(p=pDel; p && (p->pLeft||p->pRight); p=(p->pLeft ? p->pLeft : p->pRight)){
+ assert( p->pParent==0 || p==p->pParent->pRight || p==p->pParent->pLeft );
+ }
+ while( p ){
+ Fts3Expr *pParent = p->pParent;
+ fts3FreeExprNode(p);
+ if( pParent && p==pParent->pLeft && pParent->pRight ){
+ p = pParent->pRight;
+ while( p && (p->pLeft || p->pRight) ){
+ assert( p==p->pParent->pRight || p==p->pParent->pLeft );
+ p = (p->pLeft ? p->pLeft : p->pRight);
+ }
+ }else{
+ p = pParent;
+ }
}
}
@@ -123702,6 +144874,9 @@ static int queryTestTokenizer(
** the returned expression text and then freed using sqlite3_free().
*/
static char *exprToString(Fts3Expr *pExpr, char *zBuf){
+ if( pExpr==0 ){
+ return sqlite3_mprintf("");
+ }
switch( pExpr->eType ){
case FTSQUERY_PHRASE: {
Fts3Phrase *pPhrase = pExpr->pPhrase;
@@ -123809,10 +144984,21 @@ static void fts3ExprTest(
azCol[ii] = (char *)sqlite3_value_text(argv[ii+2]);
}
- rc = sqlite3Fts3ExprParse(
- pTokenizer, 0, azCol, 0, nCol, nCol, zExpr, nExpr, &pExpr
- );
+ if( sqlite3_user_data(context) ){
+ char *zDummy = 0;
+ rc = sqlite3Fts3ExprParse(
+ pTokenizer, 0, azCol, 0, nCol, nCol, zExpr, nExpr, &pExpr, &zDummy
+ );
+ assert( rc==SQLITE_OK || pExpr==0 );
+ sqlite3_free(zDummy);
+ }else{
+ rc = fts3ExprParseUnbalanced(
+ pTokenizer, 0, azCol, 0, nCol, nCol, zExpr, nExpr, &pExpr
+ );
+ }
+
if( rc!=SQLITE_OK && rc!=SQLITE_NOMEM ){
+ sqlite3Fts3ExprFree(pExpr);
sqlite3_result_error(context, "Error parsing expression", -1);
}else if( rc==SQLITE_NOMEM || !(zBuf = exprToString(pExpr, 0)) ){
sqlite3_result_error_nomem(context);
@@ -123835,9 +145021,15 @@ exprtest_out:
** with database connection db.
*/
SQLITE_PRIVATE int sqlite3Fts3ExprInitTestInterface(sqlite3* db){
- return sqlite3_create_function(
+ int rc = sqlite3_create_function(
db, "fts3_exprtest", -1, SQLITE_UTF8, 0, fts3ExprTest, 0, 0
);
+ if( rc==SQLITE_OK ){
+ rc = sqlite3_create_function(db, "fts3_exprtest_rebalance",
+ -1, SQLITE_UTF8, (void *)1, fts3ExprTest, 0, 0
+ );
+ }
+ return rc;
}
#endif
@@ -123870,12 +145062,14 @@ SQLITE_PRIVATE int sqlite3Fts3ExprInitTestInterface(sqlite3* db){
** * The FTS3 module is being built into the core of
** SQLite (in which case SQLITE_ENABLE_FTS3 is defined).
*/
+/* #include "fts3Int.h" */
#if !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_FTS3)
/* #include <assert.h> */
/* #include <stdlib.h> */
/* #include <string.h> */
+/* #include "fts3_hash.h" */
/*
** Malloc and Free functions
@@ -123941,13 +145135,13 @@ SQLITE_PRIVATE void sqlite3Fts3HashClear(Fts3Hash *pH){
*/
static int fts3StrHash(const void *pKey, int nKey){
const char *z = (const char *)pKey;
- int h = 0;
+ unsigned h = 0;
if( nKey<=0 ) nKey = (int) strlen(z);
while( nKey > 0 ){
h = (h<<3) ^ h ^ *z++;
nKey--;
}
- return h & 0x7fffffff;
+ return (int)(h & 0x7fffffff);
}
static int fts3StrCompare(const void *pKey1, int n1, const void *pKey2, int n2){
if( n1!=n2 ) return 1;
@@ -124253,6 +145447,7 @@ SQLITE_PRIVATE void *sqlite3Fts3HashInsert(
** * The FTS3 module is being built into the core of
** SQLite (in which case SQLITE_ENABLE_FTS3 is defined).
*/
+/* #include "fts3Int.h" */
#if !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_FTS3)
/* #include <assert.h> */
@@ -124260,6 +145455,7 @@ SQLITE_PRIVATE void *sqlite3Fts3HashInsert(
/* #include <stdio.h> */
/* #include <string.h> */
+/* #include "fts3_tokenizer.h" */
/*
** Class derived from sqlite3_tokenizer
@@ -124412,7 +145608,7 @@ static int isVowel(const char *z){
** 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.
+** for an instance of a consonant followed by a vowel.
*/
static int m_gt_0(const char *z){
while( isVowel(z) ){ z++; }
@@ -124632,12 +145828,14 @@ static void porter_stemmer(const char *zIn, int nIn, char *zOut, int *pnOut){
/* Step 2 */
switch( z[1] ){
case 'a':
- stem(&z, "lanoita", "ate", m_gt_0) ||
- stem(&z, "lanoit", "tion", m_gt_0);
+ if( !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);
+ if( !stem(&z, "icne", "ence", m_gt_0) ){
+ stem(&z, "icna", "ance", m_gt_0);
+ }
break;
case 'e':
stem(&z, "rezi", "ize", m_gt_0);
@@ -124646,43 +145844,54 @@ static void porter_stemmer(const char *zIn, int nIn, char *zOut, int *pnOut){
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);
+ if( !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);
+ if( !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);
+ if( !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);
+ if( !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);
+ if( !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);
+ if( !stem(&z, "laci", "ic", m_gt_0) ){
+ stem(&z, "luf", "", m_gt_0);
+ }
break;
case 's':
stem(&z, "ssen", "", m_gt_0);
@@ -124723,9 +145932,11 @@ static void porter_stemmer(const char *zIn, int nIn, char *zOut, int *pnOut){
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);
+ if( !stem(&z, "tneme", "", m_gt_1)
+ && !stem(&z, "tnem", "", m_gt_1)
+ ){
+ stem(&z, "tne", "", m_gt_1);
+ }
}
}
break;
@@ -124744,8 +145955,9 @@ static void porter_stemmer(const char *zIn, int nIn, char *zOut, int *pnOut){
}
break;
case 't':
- stem(&z, "eta", "", m_gt_1) ||
- stem(&z, "iti", "", m_gt_1);
+ if( !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) ){
@@ -124901,6 +146113,7 @@ SQLITE_PRIVATE void sqlite3Fts3PorterTokenizerModule(
** * The FTS3 module is being built into the core of
** SQLite (in which case SQLITE_ENABLE_FTS3 is defined).
*/
+/* #include "fts3Int.h" */
#if !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_FTS3)
/* #include <assert.h> */
@@ -124946,7 +146159,7 @@ static void scalarFunc(
if( argc==2 ){
void *pOld;
int n = sqlite3_value_bytes(argv[1]);
- if( n!=sizeof(pPtr) ){
+ if( zName==0 || n!=sizeof(pPtr) ){
sqlite3_result_error(context, "argument type mismatch", -1);
return;
}
@@ -124957,7 +146170,9 @@ static void scalarFunc(
return;
}
}else{
- pPtr = sqlite3Fts3HashFind(pHash, zName, nName);
+ if( zName ){
+ pPtr = sqlite3Fts3HashFind(pHash, zName, nName);
+ }
if( !pPtr ){
char *zErr = sqlite3_mprintf("unknown tokenizer: %s", zName);
sqlite3_result_error(context, zErr, -1);
@@ -125038,12 +146253,16 @@ SQLITE_PRIVATE int sqlite3Fts3InitTokenizer(
zEnd = &zCopy[strlen(zCopy)];
z = (char *)sqlite3Fts3NextToken(zCopy, &n);
+ if( z==0 ){
+ assert( n==0 );
+ z = zCopy;
+ }
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);
+ sqlite3Fts3ErrMsg(pzErr, "unknown tokenizer: %s", z);
rc = SQLITE_ERROR;
}else{
char const **aArg = 0;
@@ -125066,7 +146285,7 @@ SQLITE_PRIVATE int sqlite3Fts3InitTokenizer(
rc = m->xCreate(iArg, aArg, ppTok);
assert( rc!=SQLITE_OK || *ppTok );
if( rc!=SQLITE_OK ){
- *pzErr = sqlite3_mprintf("unknown tokenizer");
+ sqlite3Fts3ErrMsg(pzErr, "unknown tokenizer");
}else{
(*ppTok)->pModule = m;
}
@@ -125080,7 +146299,7 @@ SQLITE_PRIVATE int sqlite3Fts3InitTokenizer(
#ifdef SQLITE_TEST
-/* #include <tcl.h> */
+#include <tcl.h>
/* #include <string.h> */
/*
@@ -125150,9 +146369,9 @@ static void testFunc(
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);
+ char *zErr2 = sqlite3_mprintf("unknown tokenizer: %s", zName);
+ sqlite3_result_error(context, zErr2, -1);
+ sqlite3_free(zErr2);
return;
}
@@ -125305,7 +146524,7 @@ static void intTestFunc(
/*
** 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
+** been initialized 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);
@@ -125390,6 +146609,7 @@ SQLITE_PRIVATE int sqlite3Fts3InitHashTable(
** * The FTS3 module is being built into the core of
** SQLite (in which case SQLITE_ENABLE_FTS3 is defined).
*/
+/* #include "fts3Int.h" */
#if !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_FTS3)
/* #include <assert.h> */
@@ -125397,6 +146617,7 @@ SQLITE_PRIVATE int sqlite3Fts3InitHashTable(
/* #include <stdio.h> */
/* #include <string.h> */
+/* #include "fts3_tokenizer.h" */
typedef struct simple_tokenizer {
sqlite3_tokenizer base;
@@ -125600,6 +146821,463 @@ SQLITE_PRIVATE void sqlite3Fts3SimpleTokenizerModule(
#endif /* !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_FTS3) */
/************** End of fts3_tokenizer1.c *************************************/
+/************** Begin file fts3_tokenize_vtab.c ******************************/
+/*
+** 2013 Apr 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 for the "fts3tokenize" virtual table module.
+** An fts3tokenize virtual table is created as follows:
+**
+** CREATE VIRTUAL TABLE <tbl> USING fts3tokenize(
+** <tokenizer-name>, <arg-1>, ...
+** );
+**
+** The table created has the following schema:
+**
+** CREATE TABLE <tbl>(input, token, start, end, position)
+**
+** When queried, the query must include a WHERE clause of type:
+**
+** input = <string>
+**
+** The virtual table module tokenizes this <string>, using the FTS3
+** tokenizer specified by the arguments to the CREATE VIRTUAL TABLE
+** statement and returns one row for each token in the result. With
+** fields set as follows:
+**
+** input: Always set to a copy of <string>
+** token: A token from the input.
+** start: Byte offset of the token within the input <string>.
+** end: Byte offset of the byte immediately following the end of the
+** token within the input string.
+** pos: Token offset of token within input.
+**
+*/
+/* #include "fts3Int.h" */
+#if !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_FTS3)
+
+/* #include <string.h> */
+/* #include <assert.h> */
+
+typedef struct Fts3tokTable Fts3tokTable;
+typedef struct Fts3tokCursor Fts3tokCursor;
+
+/*
+** Virtual table structure.
+*/
+struct Fts3tokTable {
+ sqlite3_vtab base; /* Base class used by SQLite core */
+ const sqlite3_tokenizer_module *pMod;
+ sqlite3_tokenizer *pTok;
+};
+
+/*
+** Virtual table cursor structure.
+*/
+struct Fts3tokCursor {
+ sqlite3_vtab_cursor base; /* Base class used by SQLite core */
+ char *zInput; /* Input string */
+ sqlite3_tokenizer_cursor *pCsr; /* Cursor to iterate through zInput */
+ int iRowid; /* Current 'rowid' value */
+ const char *zToken; /* Current 'token' value */
+ int nToken; /* Size of zToken in bytes */
+ int iStart; /* Current 'start' value */
+ int iEnd; /* Current 'end' value */
+ int iPos; /* Current 'pos' value */
+};
+
+/*
+** Query FTS for the tokenizer implementation named zName.
+*/
+static int fts3tokQueryTokenizer(
+ Fts3Hash *pHash,
+ const char *zName,
+ const sqlite3_tokenizer_module **pp,
+ char **pzErr
+){
+ sqlite3_tokenizer_module *p;
+ int nName = (int)strlen(zName);
+
+ p = (sqlite3_tokenizer_module *)sqlite3Fts3HashFind(pHash, zName, nName+1);
+ if( !p ){
+ sqlite3Fts3ErrMsg(pzErr, "unknown tokenizer: %s", zName);
+ return SQLITE_ERROR;
+ }
+
+ *pp = p;
+ return SQLITE_OK;
+}
+
+/*
+** The second argument, argv[], is an array of pointers to nul-terminated
+** strings. This function makes a copy of the array and strings into a
+** single block of memory. It then dequotes any of the strings that appear
+** to be quoted.
+**
+** If successful, output parameter *pazDequote is set to point at the
+** array of dequoted strings and SQLITE_OK is returned. The caller is
+** responsible for eventually calling sqlite3_free() to free the array
+** in this case. Or, if an error occurs, an SQLite error code is returned.
+** The final value of *pazDequote is undefined in this case.
+*/
+static int fts3tokDequoteArray(
+ int argc, /* Number of elements in argv[] */
+ const char * const *argv, /* Input array */
+ char ***pazDequote /* Output array */
+){
+ int rc = SQLITE_OK; /* Return code */
+ if( argc==0 ){
+ *pazDequote = 0;
+ }else{
+ int i;
+ int nByte = 0;
+ char **azDequote;
+
+ for(i=0; i<argc; i++){
+ nByte += (int)(strlen(argv[i]) + 1);
+ }
+
+ *pazDequote = azDequote = sqlite3_malloc(sizeof(char *)*argc + nByte);
+ if( azDequote==0 ){
+ rc = SQLITE_NOMEM;
+ }else{
+ char *pSpace = (char *)&azDequote[argc];
+ for(i=0; i<argc; i++){
+ int n = (int)strlen(argv[i]);
+ azDequote[i] = pSpace;
+ memcpy(pSpace, argv[i], n+1);
+ sqlite3Fts3Dequote(pSpace);
+ pSpace += (n+1);
+ }
+ }
+ }
+
+ return rc;
+}
+
+/*
+** Schema of the tokenizer table.
+*/
+#define FTS3_TOK_SCHEMA "CREATE TABLE x(input, token, start, end, position)"
+
+/*
+** 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.
+**
+** argv[0]: module name
+** argv[1]: database name
+** argv[2]: table name
+** argv[3]: first argument (tokenizer name)
+*/
+static int fts3tokConnectMethod(
+ sqlite3 *db, /* Database connection */
+ void *pHash, /* Hash table of tokenizers */
+ 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 */
+){
+ Fts3tokTable *pTab = 0;
+ const sqlite3_tokenizer_module *pMod = 0;
+ sqlite3_tokenizer *pTok = 0;
+ int rc;
+ char **azDequote = 0;
+ int nDequote;
+
+ rc = sqlite3_declare_vtab(db, FTS3_TOK_SCHEMA);
+ if( rc!=SQLITE_OK ) return rc;
+
+ nDequote = argc-3;
+ rc = fts3tokDequoteArray(nDequote, &argv[3], &azDequote);
+
+ if( rc==SQLITE_OK ){
+ const char *zModule;
+ if( nDequote<1 ){
+ zModule = "simple";
+ }else{
+ zModule = azDequote[0];
+ }
+ rc = fts3tokQueryTokenizer((Fts3Hash*)pHash, zModule, &pMod, pzErr);
+ }
+
+ assert( (rc==SQLITE_OK)==(pMod!=0) );
+ if( rc==SQLITE_OK ){
+ const char * const *azArg = (const char * const *)&azDequote[1];
+ rc = pMod->xCreate((nDequote>1 ? nDequote-1 : 0), azArg, &pTok);
+ }
+
+ if( rc==SQLITE_OK ){
+ pTab = (Fts3tokTable *)sqlite3_malloc(sizeof(Fts3tokTable));
+ if( pTab==0 ){
+ rc = SQLITE_NOMEM;
+ }
+ }
+
+ if( rc==SQLITE_OK ){
+ memset(pTab, 0, sizeof(Fts3tokTable));
+ pTab->pMod = pMod;
+ pTab->pTok = pTok;
+ *ppVtab = &pTab->base;
+ }else{
+ if( pTok ){
+ pMod->xDestroy(pTok);
+ }
+ }
+
+ sqlite3_free(azDequote);
+ return rc;
+}
+
+/*
+** 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 fts3tokDisconnectMethod(sqlite3_vtab *pVtab){
+ Fts3tokTable *pTab = (Fts3tokTable *)pVtab;
+
+ pTab->pMod->xDestroy(pTab->pTok);
+ sqlite3_free(pTab);
+ return SQLITE_OK;
+}
+
+/*
+** xBestIndex - Analyze a WHERE and ORDER BY clause.
+*/
+static int fts3tokBestIndexMethod(
+ sqlite3_vtab *pVTab,
+ sqlite3_index_info *pInfo
+){
+ int i;
+ UNUSED_PARAMETER(pVTab);
+
+ for(i=0; i<pInfo->nConstraint; i++){
+ if( pInfo->aConstraint[i].usable
+ && pInfo->aConstraint[i].iColumn==0
+ && pInfo->aConstraint[i].op==SQLITE_INDEX_CONSTRAINT_EQ
+ ){
+ pInfo->idxNum = 1;
+ pInfo->aConstraintUsage[i].argvIndex = 1;
+ pInfo->aConstraintUsage[i].omit = 1;
+ pInfo->estimatedCost = 1;
+ return SQLITE_OK;
+ }
+ }
+
+ pInfo->idxNum = 0;
+ assert( pInfo->estimatedCost>1000000.0 );
+
+ return SQLITE_OK;
+}
+
+/*
+** xOpen - Open a cursor.
+*/
+static int fts3tokOpenMethod(sqlite3_vtab *pVTab, sqlite3_vtab_cursor **ppCsr){
+ Fts3tokCursor *pCsr;
+ UNUSED_PARAMETER(pVTab);
+
+ pCsr = (Fts3tokCursor *)sqlite3_malloc(sizeof(Fts3tokCursor));
+ if( pCsr==0 ){
+ return SQLITE_NOMEM;
+ }
+ memset(pCsr, 0, sizeof(Fts3tokCursor));
+
+ *ppCsr = (sqlite3_vtab_cursor *)pCsr;
+ return SQLITE_OK;
+}
+
+/*
+** Reset the tokenizer cursor passed as the only argument. As if it had
+** just been returned by fts3tokOpenMethod().
+*/
+static void fts3tokResetCursor(Fts3tokCursor *pCsr){
+ if( pCsr->pCsr ){
+ Fts3tokTable *pTab = (Fts3tokTable *)(pCsr->base.pVtab);
+ pTab->pMod->xClose(pCsr->pCsr);
+ pCsr->pCsr = 0;
+ }
+ sqlite3_free(pCsr->zInput);
+ pCsr->zInput = 0;
+ pCsr->zToken = 0;
+ pCsr->nToken = 0;
+ pCsr->iStart = 0;
+ pCsr->iEnd = 0;
+ pCsr->iPos = 0;
+ pCsr->iRowid = 0;
+}
+
+/*
+** xClose - Close a cursor.
+*/
+static int fts3tokCloseMethod(sqlite3_vtab_cursor *pCursor){
+ Fts3tokCursor *pCsr = (Fts3tokCursor *)pCursor;
+
+ fts3tokResetCursor(pCsr);
+ sqlite3_free(pCsr);
+ return SQLITE_OK;
+}
+
+/*
+** xNext - Advance the cursor to the next row, if any.
+*/
+static int fts3tokNextMethod(sqlite3_vtab_cursor *pCursor){
+ Fts3tokCursor *pCsr = (Fts3tokCursor *)pCursor;
+ Fts3tokTable *pTab = (Fts3tokTable *)(pCursor->pVtab);
+ int rc; /* Return code */
+
+ pCsr->iRowid++;
+ rc = pTab->pMod->xNext(pCsr->pCsr,
+ &pCsr->zToken, &pCsr->nToken,
+ &pCsr->iStart, &pCsr->iEnd, &pCsr->iPos
+ );
+
+ if( rc!=SQLITE_OK ){
+ fts3tokResetCursor(pCsr);
+ if( rc==SQLITE_DONE ) rc = SQLITE_OK;
+ }
+
+ return rc;
+}
+
+/*
+** xFilter - Initialize a cursor to point at the start of its data.
+*/
+static int fts3tokFilterMethod(
+ 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 = SQLITE_ERROR;
+ Fts3tokCursor *pCsr = (Fts3tokCursor *)pCursor;
+ Fts3tokTable *pTab = (Fts3tokTable *)(pCursor->pVtab);
+ UNUSED_PARAMETER(idxStr);
+ UNUSED_PARAMETER(nVal);
+
+ fts3tokResetCursor(pCsr);
+ if( idxNum==1 ){
+ const char *zByte = (const char *)sqlite3_value_text(apVal[0]);
+ int nByte = sqlite3_value_bytes(apVal[0]);
+ pCsr->zInput = sqlite3_malloc(nByte+1);
+ if( pCsr->zInput==0 ){
+ rc = SQLITE_NOMEM;
+ }else{
+ memcpy(pCsr->zInput, zByte, nByte);
+ pCsr->zInput[nByte] = 0;
+ rc = pTab->pMod->xOpen(pTab->pTok, pCsr->zInput, nByte, &pCsr->pCsr);
+ if( rc==SQLITE_OK ){
+ pCsr->pCsr->pTokenizer = pTab->pTok;
+ }
+ }
+ }
+
+ if( rc!=SQLITE_OK ) return rc;
+ return fts3tokNextMethod(pCursor);
+}
+
+/*
+** xEof - Return true if the cursor is at EOF, or false otherwise.
+*/
+static int fts3tokEofMethod(sqlite3_vtab_cursor *pCursor){
+ Fts3tokCursor *pCsr = (Fts3tokCursor *)pCursor;
+ return (pCsr->zToken==0);
+}
+
+/*
+** xColumn - Return a column value.
+*/
+static int fts3tokColumnMethod(
+ 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 */
+){
+ Fts3tokCursor *pCsr = (Fts3tokCursor *)pCursor;
+
+ /* CREATE TABLE x(input, token, start, end, position) */
+ switch( iCol ){
+ case 0:
+ sqlite3_result_text(pCtx, pCsr->zInput, -1, SQLITE_TRANSIENT);
+ break;
+ case 1:
+ sqlite3_result_text(pCtx, pCsr->zToken, pCsr->nToken, SQLITE_TRANSIENT);
+ break;
+ case 2:
+ sqlite3_result_int(pCtx, pCsr->iStart);
+ break;
+ case 3:
+ sqlite3_result_int(pCtx, pCsr->iEnd);
+ break;
+ default:
+ assert( iCol==4 );
+ sqlite3_result_int(pCtx, pCsr->iPos);
+ break;
+ }
+ return SQLITE_OK;
+}
+
+/*
+** xRowid - Return the current rowid for the cursor.
+*/
+static int fts3tokRowidMethod(
+ sqlite3_vtab_cursor *pCursor, /* Cursor to retrieve value from */
+ sqlite_int64 *pRowid /* OUT: Rowid value */
+){
+ Fts3tokCursor *pCsr = (Fts3tokCursor *)pCursor;
+ *pRowid = (sqlite3_int64)pCsr->iRowid;
+ return SQLITE_OK;
+}
+
+/*
+** Register the fts3tok module with database connection db. Return SQLITE_OK
+** if successful or an error code if sqlite3_create_module() fails.
+*/
+SQLITE_PRIVATE int sqlite3Fts3InitTok(sqlite3 *db, Fts3Hash *pHash){
+ static const sqlite3_module fts3tok_module = {
+ 0, /* iVersion */
+ fts3tokConnectMethod, /* xCreate */
+ fts3tokConnectMethod, /* xConnect */
+ fts3tokBestIndexMethod, /* xBestIndex */
+ fts3tokDisconnectMethod, /* xDisconnect */
+ fts3tokDisconnectMethod, /* xDestroy */
+ fts3tokOpenMethod, /* xOpen */
+ fts3tokCloseMethod, /* xClose */
+ fts3tokFilterMethod, /* xFilter */
+ fts3tokNextMethod, /* xNext */
+ fts3tokEofMethod, /* xEof */
+ fts3tokColumnMethod, /* xColumn */
+ fts3tokRowidMethod, /* 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, "fts3tokenize", &fts3tok_module, (void*)pHash);
+ return rc;
+}
+
+#endif /* !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_FTS3) */
+
+/************** End of fts3_tokenize_vtab.c **********************************/
/************** Begin file fts3_write.c **************************************/
/*
** 2009 Oct 23
@@ -125620,6 +147298,7 @@ SQLITE_PRIVATE void sqlite3Fts3SimpleTokenizerModule(
** code in fts3.c.
*/
+/* #include "fts3Int.h" */
#if !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_FTS3)
/* #include <string.h> */
@@ -125795,6 +147474,7 @@ struct SegmentWriter {
int nSize; /* Size of allocation at aData */
int nData; /* Bytes of data in aData */
char *aData; /* Pointer to block from malloc() */
+ i64 nLeafData; /* Number of bytes of leaf data written */
};
/*
@@ -125870,6 +147550,10 @@ struct SegmentNode {
#define SQL_SELECT_INDEXES 35
#define SQL_SELECT_MXLEVEL 36
+#define SQL_SELECT_LEVEL_RANGE2 37
+#define SQL_UPDATE_LEVEL_IDX 38
+#define SQL_UPDATE_LEVEL 39
+
/*
** This function is used to obtain an SQLite prepared statement handle
** for the statement identified by the second argument. If successful,
@@ -125923,7 +147607,7 @@ static int fts3SqlStmt(
/* 25 */ "",
/* 26 */ "DELETE FROM %Q.'%q_segdir' WHERE level BETWEEN ? AND ?",
-/* 27 */ "SELECT DISTINCT level / (1024 * ?) FROM %Q.'%q_segdir'",
+/* 27 */ "SELECT ? UNION SELECT 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
@@ -125971,7 +147655,18 @@ static int fts3SqlStmt(
/* SQL_SELECT_MXLEVEL
** Return the largest relative level in the FTS index or indexes. */
-/* 36 */ "SELECT max( level %% 1024 ) FROM %Q.'%q_segdir'"
+/* 36 */ "SELECT max( level %% 1024 ) FROM %Q.'%q_segdir'",
+
+ /* Return segments in order from oldest to newest.*/
+/* 37 */ "SELECT level, idx, end_block "
+ "FROM %Q.'%q_segdir' WHERE level BETWEEN ? AND ? "
+ "ORDER BY level DESC, idx ASC",
+
+ /* Update statements used while promoting segments */
+/* 38 */ "UPDATE OR FAIL %Q.'%q_segdir' SET level=-1,idx=? "
+ "WHERE level=? AND idx=?",
+/* 39 */ "UPDATE OR FAIL %Q.'%q_segdir' SET level=? WHERE level=-1"
+
};
int rc = SQLITE_OK;
sqlite3_stmt *pStmt;
@@ -126091,37 +147786,30 @@ static void fts3SqlExec(
/*
-** 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).
+** This function ensures that the caller has obtained an exclusive
+** shared-cache table-lock on the %_segdir table. This is required before
+** writing data to the fts3 table. If this lock is not acquired first, then
+** the caller may end up attempting to take this lock as part of committing
+** a transaction, causing SQLite to return SQLITE_LOCKED or
+** LOCKED_SHAREDCACHEto a COMMIT command.
**
-** 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.
+** It is best 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 locks the underlying tables directly
+** instead of accessing them via FTS.
*/
-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);
+static int fts3Writelock(Fts3Table *p){
+ int rc = SQLITE_OK;
+
+ if( p->nPendingData==0 ){
+ sqlite3_stmt *pStmt;
+ rc = fts3SqlStmt(p, SQL_DELETE_SEGDIR_LEVEL, &pStmt, 0);
if( rc==SQLITE_OK ){
sqlite3_bind_null(pStmt, 1);
sqlite3_step(pStmt);
rc = sqlite3_reset(pStmt);
}
- }else{
- rc = SQLITE_OK;
}
return rc;
@@ -126453,10 +148141,12 @@ static int fts3PendingTermsAdd(
*/
static int fts3PendingTermsDocid(
Fts3Table *p, /* Full-text table handle */
+ int bDelete, /* True if this op is a delete */
int iLangid, /* Language id of row being written */
sqlite_int64 iDocid /* Docid of row being written */
){
assert( iLangid>=0 );
+ assert( bDelete==1 || bDelete==0 );
/* TODO(shess) Explore whether partially flushing the buffer on
** forced-flush would provide better performance. I suspect that if
@@ -126464,7 +148154,8 @@ static int fts3PendingTermsDocid(
** buffer was half empty, that would let the less frequent terms
** generate longer doclists.
*/
- if( iDocid<=p->iPrevDocid
+ if( iDocid<p->iPrevDocid
+ || (iDocid==p->iPrevDocid && p->bPrevDelete==0)
|| p->iPrevLangid!=iLangid
|| p->nPendingData>p->nMaxPendingData
){
@@ -126473,6 +148164,7 @@ static int fts3PendingTermsDocid(
}
p->iPrevDocid = iDocid;
p->iPrevLangid = iLangid;
+ p->bPrevDelete = bDelete;
return SQLITE_OK;
}
@@ -126509,12 +148201,15 @@ static int fts3InsertTerms(
){
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;
+ int iCol = i-2;
+ if( p->abNotindexed[iCol]==0 ){
+ const char *zText = (const char *)sqlite3_value_text(apVal[i]);
+ int rc = fts3PendingTermsAdd(p, iLangid, zText, iCol, &aSz[iCol]);
+ if( rc!=SQLITE_OK ){
+ return rc;
+ }
+ aSz[p->nColumn] += sqlite3_value_bytes(apVal[i]);
}
- aSz[p->nColumn] += sqlite3_value_bytes(apVal[i]);
}
return SQLITE_OK;
}
@@ -126659,11 +148354,15 @@ static void fts3DeleteTerms(
if( SQLITE_ROW==sqlite3_step(pSelect) ){
int i;
int iLangid = langidFromSelect(p, pSelect);
- rc = fts3PendingTermsDocid(p, iLangid, sqlite3_column_int64(pSelect, 0));
+ i64 iDocid = sqlite3_column_int64(pSelect, 0);
+ rc = fts3PendingTermsDocid(p, 1, iLangid, iDocid);
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);
+ int iCol = i-1;
+ if( p->abNotindexed[iCol]==0 ){
+ const char *zText = (const char *)sqlite3_column_text(pSelect, i);
+ rc = fts3PendingTermsAdd(p, iLangid, zText, -1, &aSz[iCol]);
+ aSz[p->nColumn] += sqlite3_column_bytes(pSelect, i);
+ }
}
if( rc!=SQLITE_OK ){
sqlite3_reset(pSelect);
@@ -126904,14 +148603,19 @@ static int fts3SegReaderNext(
if( fts3SegReaderIsPending(pReader) ){
Fts3HashElem *pElem = *(pReader->ppNextElem);
- if( pElem==0 ){
- pReader->aNode = 0;
- }else{
+ sqlite3_free(pReader->aNode);
+ pReader->aNode = 0;
+ if( pElem ){
+ char *aCopy;
PendingList *pList = (PendingList *)fts3HashData(pElem);
+ int nCopy = pList->nData+1;
pReader->zTerm = (char *)fts3HashKey(pElem);
pReader->nTerm = fts3HashKeysize(pElem);
- pReader->nNode = pReader->nDoclist = pList->nData + 1;
- pReader->aNode = pReader->aDoclist = pList->aData;
+ aCopy = (char*)sqlite3_malloc(nCopy);
+ if( !aCopy ) return SQLITE_NOMEM;
+ memcpy(aCopy, pList->aData, nCopy);
+ pReader->nNode = pReader->nDoclist = nCopy;
+ pReader->aNode = pReader->aDoclist = aCopy;
pReader->ppNextElem++;
assert( pReader->aNode );
}
@@ -126947,8 +148651,8 @@ static int fts3SegReaderNext(
/* 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);
+ pNext += fts3GetVarint32(pNext, &nPrefix);
+ pNext += fts3GetVarint32(pNext, &nSuffix);
if( nPrefix<0 || nSuffix<=0
|| &pNext[nSuffix]>&pReader->aNode[pReader->nNode]
){
@@ -126971,7 +148675,7 @@ static int fts3SegReaderNext(
memcpy(&pReader->zTerm[nPrefix], pNext, nSuffix);
pReader->nTerm = nPrefix+nSuffix;
pNext += nSuffix;
- pNext += sqlite3Fts3GetVarint32(pNext, &pReader->nDoclist);
+ pNext += fts3GetVarint32(pNext, &pReader->nDoclist);
pReader->aDoclist = pNext;
pReader->pOffsetList = 0;
@@ -127064,7 +148768,7 @@ static int fts3SegReaderNextDocid(
/* 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
+ ** incrementally and pointer "p" now points to the first byte past
** the populated part of pReader->aNode[].
*/
while( *p | c ) c = *p++ & 0x80;
@@ -127084,6 +148788,7 @@ static int fts3SegReaderNextDocid(
*pnOffsetList = (int)(p - pReader->pOffsetList - 1);
}
+ /* List may have been edited in place by fts3EvalNearTrim() */
while( p<pEnd && *p==0 ) p++;
/* If there are no more entries in the doclist, set pOffsetList to
@@ -127150,12 +148855,14 @@ SQLITE_PRIVATE int sqlite3Fts3MsrOvfl(
** second argument.
*/
SQLITE_PRIVATE void sqlite3Fts3SegReaderFree(Fts3SegReader *pReader){
- if( pReader && !fts3SegReaderIsPending(pReader) ){
- sqlite3_free(pReader->zTerm);
+ if( pReader ){
+ if( !fts3SegReaderIsPending(pReader) ){
+ sqlite3_free(pReader->zTerm);
+ }
if( !fts3SegReaderIsRootOnly(pReader) ){
sqlite3_free(pReader->aNode);
- sqlite3_blob_close(pReader->pBlob);
}
+ sqlite3_blob_close(pReader->pBlob);
}
sqlite3_free(pReader);
}
@@ -127211,7 +148918,10 @@ SQLITE_PRIVATE int sqlite3Fts3SegReaderNew(
** 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){
+static int SQLITE_CDECL fts3CompareElemByTerm(
+ const void *lhs,
+ const void *rhs
+){
char *z1 = fts3HashKey(*(Fts3HashElem **)lhs);
char *z2 = fts3HashKey(*(Fts3HashElem **)rhs);
int n1 = fts3HashKeysize(*(Fts3HashElem **)lhs);
@@ -127512,6 +149222,7 @@ static int fts3WriteSegdir(
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 */
+ sqlite3_int64 nLeafData, /* Bytes of leaf data in segment */
char *zRoot, /* Blob value for "root" field */
int nRoot /* Number of bytes in buffer zRoot */
){
@@ -127522,7 +149233,13 @@ static int fts3WriteSegdir(
sqlite3_bind_int(pStmt, 2, iIdx);
sqlite3_bind_int64(pStmt, 3, iStartBlock);
sqlite3_bind_int64(pStmt, 4, iLeafEndBlock);
- sqlite3_bind_int64(pStmt, 5, iEndBlock);
+ if( nLeafData==0 ){
+ sqlite3_bind_int64(pStmt, 5, iEndBlock);
+ }else{
+ char *zEnd = sqlite3_mprintf("%lld %lld", iEndBlock, nLeafData);
+ if( !zEnd ) return SQLITE_NOMEM;
+ sqlite3_bind_text(pStmt, 5, zEnd, -1, sqlite3_free);
+ }
sqlite3_bind_blob(pStmt, 6, zRoot, nRoot, SQLITE_STATIC);
sqlite3_step(pStmt);
rc = sqlite3_reset(pStmt);
@@ -127848,6 +149565,9 @@ static int fts3SegWriterAdd(
nDoclist; /* Doclist data */
}
+ /* Increase the total number of bytes written to account for the new entry. */
+ pWriter->nLeafData += nReq;
+
/* If the buffer currently allocated is too small for this entry, realloc
** the buffer to make it large enough.
*/
@@ -127919,13 +149639,13 @@ static int fts3SegWriterFlush(
pWriter->iFirst, pWriter->iFree, &iLast, &zRoot, &nRoot);
}
if( rc==SQLITE_OK ){
- rc = fts3WriteSegdir(
- p, iLevel, iIdx, pWriter->iFirst, iLastLeaf, iLast, zRoot, nRoot);
+ rc = fts3WriteSegdir(p, iLevel, iIdx,
+ pWriter->iFirst, iLastLeaf, iLast, pWriter->nLeafData, 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);
+ rc = fts3WriteSegdir(p, iLevel, iIdx,
+ 0, 0, 0, pWriter->nLeafData, pWriter->aData, pWriter->nData);
}
p->nLeafAdd++;
return rc;
@@ -128010,6 +149730,37 @@ static int fts3SegmentMaxLevel(
}
/*
+** iAbsLevel is an absolute level that may be assumed to exist within
+** the database. This function checks if it is the largest level number
+** within its index. Assuming no error occurs, *pbMax is set to 1 if
+** iAbsLevel is indeed the largest level, or 0 otherwise, and SQLITE_OK
+** is returned. If an error occurs, an error code is returned and the
+** final value of *pbMax is undefined.
+*/
+static int fts3SegmentIsMaxLevel(Fts3Table *p, i64 iAbsLevel, int *pbMax){
+
+ /* 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).
+ */
+ sqlite3_stmt *pStmt;
+ int rc = fts3SqlStmt(p, SQL_SELECT_SEGDIR_MAX_LEVEL, &pStmt, 0);
+ if( rc!=SQLITE_OK ) return rc;
+ sqlite3_bind_int64(pStmt, 1, iAbsLevel+1);
+ sqlite3_bind_int64(pStmt, 2,
+ ((iAbsLevel/FTS3_SEGDIR_MAXLEVEL)+1) * FTS3_SEGDIR_MAXLEVEL
+ );
+
+ *pbMax = 0;
+ if( SQLITE_ROW==sqlite3_step(pStmt) ){
+ *pbMax = sqlite3_column_type(pStmt, 0)==SQLITE_NULL;
+ }
+ 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.
@@ -128099,9 +149850,13 @@ static int fts3DeleteSegdir(
**
** If there are no entries in the input position list for column iCol, then
** *pnList is set to zero before returning.
+**
+** If parameter bZero is non-zero, then any part of the input list following
+** the end of the output list is zeroed before returning.
*/
static void fts3ColumnFilter(
int iCol, /* Column to filter on */
+ int bZero, /* Zero out anything following *ppList */
char **ppList, /* IN/OUT: Pointer to position list */
int *pnList /* IN/OUT: Size of buffer *ppList in bytes */
){
@@ -128127,9 +149882,12 @@ static void fts3ColumnFilter(
break;
}
p = &pList[1];
- p += sqlite3Fts3GetVarint32(p, &iCurrent);
+ p += fts3GetVarint32(p, &iCurrent);
}
+ if( bZero && &pList[nList]!=pEnd ){
+ memset(&pList[nList], 0, pEnd - &pList[nList]);
+ }
*ppList = pList;
*pnList = nList;
}
@@ -128203,19 +149961,19 @@ SQLITE_PRIVATE int sqlite3Fts3MsrIncrNext(
if( rc!=SQLITE_OK ) return rc;
fts3SegReaderSort(pMsr->apSegment, nMerge, j, xCmp);
+ if( nList>0 && fts3SegReaderIsPending(apSegment[0]) ){
+ rc = fts3MsrBufferData(pMsr, pList, nList+1);
+ if( rc!=SQLITE_OK ) return rc;
+ assert( (pMsr->aBuffer[nList] & 0xFE)==0x00 );
+ pList = pMsr->aBuffer;
+ }
+
if( pMsr->iColFilter>=0 ){
- fts3ColumnFilter(pMsr->iColFilter, &pList, &nList);
+ fts3ColumnFilter(pMsr->iColFilter, 1, &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;
- }
+ *paPoslist = pList;
*piDocid = iDocid;
*pnPoslist = nList;
break;
@@ -128443,8 +150201,8 @@ SQLITE_PRIVATE int sqlite3Fts3SegReaderStep(
fts3SegReaderSort(apSegment, nMerge, nMerge, xCmp);
while( apSegment[0]->pOffsetList ){
int j; /* Number of segments that share a docid */
- char *pList;
- int nList;
+ char *pList = 0;
+ int nList = 0;
int nByte;
sqlite3_int64 iDocid = apSegment[0]->iDocid;
fts3SegReaderNextDocid(p, apSegment[0], &pList, &nList);
@@ -128458,7 +150216,7 @@ SQLITE_PRIVATE int sqlite3Fts3SegReaderStep(
}
if( isColFilter ){
- fts3ColumnFilter(pFilter->iCol, &pList, &nList);
+ fts3ColumnFilter(pFilter->iCol, 0, &pList, &nList);
}
if( !isIgnoreEmpty || nList>0 ){
@@ -128538,6 +150296,140 @@ SQLITE_PRIVATE void sqlite3Fts3SegReaderFinish(
}
/*
+** Decode the "end_block" field, selected by column iCol of the SELECT
+** statement passed as the first argument.
+**
+** The "end_block" field may contain either an integer, or a text field
+** containing the text representation of two non-negative integers separated
+** by one or more space (0x20) characters. In the first case, set *piEndBlock
+** to the integer value and *pnByte to zero before returning. In the second,
+** set *piEndBlock to the first value and *pnByte to the second.
+*/
+static void fts3ReadEndBlockField(
+ sqlite3_stmt *pStmt,
+ int iCol,
+ i64 *piEndBlock,
+ i64 *pnByte
+){
+ const unsigned char *zText = sqlite3_column_text(pStmt, iCol);
+ if( zText ){
+ int i;
+ int iMul = 1;
+ i64 iVal = 0;
+ for(i=0; zText[i]>='0' && zText[i]<='9'; i++){
+ iVal = iVal*10 + (zText[i] - '0');
+ }
+ *piEndBlock = iVal;
+ while( zText[i]==' ' ) i++;
+ iVal = 0;
+ if( zText[i]=='-' ){
+ i++;
+ iMul = -1;
+ }
+ for(/* no-op */; zText[i]>='0' && zText[i]<='9'; i++){
+ iVal = iVal*10 + (zText[i] - '0');
+ }
+ *pnByte = (iVal * (i64)iMul);
+ }
+}
+
+
+/*
+** A segment of size nByte bytes has just been written to absolute level
+** iAbsLevel. Promote any segments that should be promoted as a result.
+*/
+static int fts3PromoteSegments(
+ Fts3Table *p, /* FTS table handle */
+ sqlite3_int64 iAbsLevel, /* Absolute level just updated */
+ sqlite3_int64 nByte /* Size of new segment at iAbsLevel */
+){
+ int rc = SQLITE_OK;
+ sqlite3_stmt *pRange;
+
+ rc = fts3SqlStmt(p, SQL_SELECT_LEVEL_RANGE2, &pRange, 0);
+
+ if( rc==SQLITE_OK ){
+ int bOk = 0;
+ i64 iLast = (iAbsLevel/FTS3_SEGDIR_MAXLEVEL + 1) * FTS3_SEGDIR_MAXLEVEL - 1;
+ i64 nLimit = (nByte*3)/2;
+
+ /* Loop through all entries in the %_segdir table corresponding to
+ ** segments in this index on levels greater than iAbsLevel. If there is
+ ** at least one such segment, and it is possible to determine that all
+ ** such segments are smaller than nLimit bytes in size, they will be
+ ** promoted to level iAbsLevel. */
+ sqlite3_bind_int64(pRange, 1, iAbsLevel+1);
+ sqlite3_bind_int64(pRange, 2, iLast);
+ while( SQLITE_ROW==sqlite3_step(pRange) ){
+ i64 nSize = 0, dummy;
+ fts3ReadEndBlockField(pRange, 2, &dummy, &nSize);
+ if( nSize<=0 || nSize>nLimit ){
+ /* If nSize==0, then the %_segdir.end_block field does not not
+ ** contain a size value. This happens if it was written by an
+ ** old version of FTS. In this case it is not possible to determine
+ ** the size of the segment, and so segment promotion does not
+ ** take place. */
+ bOk = 0;
+ break;
+ }
+ bOk = 1;
+ }
+ rc = sqlite3_reset(pRange);
+
+ if( bOk ){
+ int iIdx = 0;
+ sqlite3_stmt *pUpdate1 = 0;
+ sqlite3_stmt *pUpdate2 = 0;
+
+ if( rc==SQLITE_OK ){
+ rc = fts3SqlStmt(p, SQL_UPDATE_LEVEL_IDX, &pUpdate1, 0);
+ }
+ if( rc==SQLITE_OK ){
+ rc = fts3SqlStmt(p, SQL_UPDATE_LEVEL, &pUpdate2, 0);
+ }
+
+ if( rc==SQLITE_OK ){
+
+ /* Loop through all %_segdir entries for segments in this index with
+ ** levels equal to or greater than iAbsLevel. As each entry is visited,
+ ** updated it to set (level = -1) and (idx = N), where N is 0 for the
+ ** oldest segment in the range, 1 for the next oldest, and so on.
+ **
+ ** In other words, move all segments being promoted to level -1,
+ ** setting the "idx" fields as appropriate to keep them in the same
+ ** order. The contents of level -1 (which is never used, except
+ ** transiently here), will be moved back to level iAbsLevel below. */
+ sqlite3_bind_int64(pRange, 1, iAbsLevel);
+ while( SQLITE_ROW==sqlite3_step(pRange) ){
+ sqlite3_bind_int(pUpdate1, 1, iIdx++);
+ sqlite3_bind_int(pUpdate1, 2, sqlite3_column_int(pRange, 0));
+ sqlite3_bind_int(pUpdate1, 3, sqlite3_column_int(pRange, 1));
+ sqlite3_step(pUpdate1);
+ rc = sqlite3_reset(pUpdate1);
+ if( rc!=SQLITE_OK ){
+ sqlite3_reset(pRange);
+ break;
+ }
+ }
+ }
+ if( rc==SQLITE_OK ){
+ rc = sqlite3_reset(pRange);
+ }
+
+ /* Move level -1 to level iAbsLevel */
+ if( rc==SQLITE_OK ){
+ sqlite3_bind_int64(pUpdate2, 1, iAbsLevel);
+ sqlite3_step(pUpdate2);
+ rc = sqlite3_reset(pUpdate2);
+ }
+ }
+ }
+
+
+ return rc;
+}
+
+/*
** 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
@@ -128561,6 +150453,7 @@ static int fts3SegmentMerge(
Fts3SegFilter filter; /* Segment term filter condition */
Fts3MultiSegReader csr; /* Cursor to iterate through level(s) */
int bIgnoreEmpty = 0; /* True to ignore empty segments */
+ i64 iMaxLevel = 0; /* Max level number for this index/langid */
assert( iLevel==FTS3_SEGCURSOR_ALL
|| iLevel==FTS3_SEGCURSOR_PENDING
@@ -128572,6 +150465,11 @@ static int fts3SegmentMerge(
rc = sqlite3Fts3SegReaderCursor(p, iLangid, iIndex, iLevel, 0, 0, 1, 0, &csr);
if( rc!=SQLITE_OK || csr.nSegment==0 ) goto finished;
+ if( iLevel!=FTS3_SEGCURSOR_PENDING ){
+ rc = fts3SegmentMaxLevel(p, iLangid, iIndex, &iMaxLevel);
+ if( rc!=SQLITE_OK ) 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
@@ -128581,21 +150479,21 @@ static int fts3SegmentMerge(
rc = SQLITE_DONE;
goto finished;
}
- rc = fts3SegmentMaxLevel(p, iLangid, iIndex, &iNewLevel);
+ iNewLevel = iMaxLevel;
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);
+ assert( FTS3_SEGCURSOR_PENDING==-1 );
iNewLevel = getAbsoluteLevel(p, iLangid, iIndex, iLevel+1);
+ rc = fts3AllocateSegdirIdx(p, iLangid, iIndex, iLevel+1, &iIdx);
+ bIgnoreEmpty = (iLevel!=FTS3_SEGCURSOR_PENDING) && (iNewLevel>iMaxLevel);
}
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) );
@@ -128612,7 +150510,7 @@ static int fts3SegmentMerge(
csr.zTerm, csr.nTerm, csr.aDoclist, csr.nDoclist);
}
if( rc!=SQLITE_OK ) goto finished;
- assert( pWriter );
+ assert( pWriter || bIgnoreEmpty );
if( iLevel!=FTS3_SEGCURSOR_PENDING ){
rc = fts3DeleteSegdir(
@@ -128620,7 +150518,14 @@ static int fts3SegmentMerge(
);
if( rc!=SQLITE_OK ) goto finished;
}
- rc = fts3SegWriterFlush(p, pWriter, iNewLevel, iIdx);
+ if( pWriter ){
+ rc = fts3SegWriterFlush(p, pWriter, iNewLevel, iIdx);
+ if( rc==SQLITE_OK ){
+ if( iLevel==FTS3_SEGCURSOR_PENDING || iNewLevel<iMaxLevel ){
+ rc = fts3PromoteSegments(p, iNewLevel, pWriter->nLeafData);
+ }
+ }
+ }
finished:
fts3SegWriterFree(pWriter);
@@ -128630,7 +150535,7 @@ static int fts3SegmentMerge(
/*
-** Flush the contents of pendingTerms to level 0 segments.
+** Flush the contents of pendingTerms to level 0 segments.
*/
SQLITE_PRIVATE int sqlite3Fts3PendingTermsFlush(Fts3Table *p){
int rc = SQLITE_OK;
@@ -128646,14 +150551,19 @@ SQLITE_PRIVATE int sqlite3Fts3PendingTermsFlush(Fts3Table *p){
** estimate the number of leaf blocks of content to be written
*/
if( rc==SQLITE_OK && p->bHasStat
- && p->bAutoincrmerge==0xff && p->nLeafAdd>0
+ && p->nAutoincrmerge==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));
+ if( rc==SQLITE_ROW ){
+ p->nAutoincrmerge = sqlite3_column_int(pStmt, 0);
+ if( p->nAutoincrmerge==1 ) p->nAutoincrmerge = 8;
+ }else if( rc==SQLITE_DONE ){
+ p->nAutoincrmerge = 0;
+ }
rc = sqlite3_reset(pStmt);
}
}
@@ -128827,7 +150737,8 @@ static int fts3DoOptimize(Fts3Table *p, int bReturnDone){
rc = fts3SqlStmt(p, SQL_SELECT_ALL_LANGID, &pAllLangid, 0);
if( rc==SQLITE_OK ){
int rc2;
- sqlite3_bind_int(pAllLangid, 1, p->nIndex);
+ sqlite3_bind_int(pAllLangid, 1, p->iPrevLangid);
+ sqlite3_bind_int(pAllLangid, 2, p->nIndex);
while( sqlite3_step(pAllLangid)==SQLITE_ROW ){
int i;
int iLangid = sqlite3_column_int(pAllLangid, 0);
@@ -128894,12 +150805,14 @@ static int fts3DoRebuild(Fts3Table *p){
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));
+ rc = fts3PendingTermsDocid(p, 0, 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->abNotindexed[iCol]==0 ){
+ 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);
@@ -129019,6 +150932,8 @@ struct IncrmergeWriter {
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 */
+ sqlite3_int64 nLeafData; /* Bytes of leaf page data so far */
+ u8 bNoLeafData; /* If true, store 0 for segment size */
NodeWriter aNodeWriter[FTS_MAX_APPENDABLE_HEIGHT];
};
@@ -129087,9 +151002,9 @@ static int nodeReaderNext(NodeReader *p){
p->aNode = 0;
}else{
if( bFirst==0 ){
- p->iOff += sqlite3Fts3GetVarint32(&p->aNode[p->iOff], &nPrefix);
+ p->iOff += fts3GetVarint32(&p->aNode[p->iOff], &nPrefix);
}
- p->iOff += sqlite3Fts3GetVarint32(&p->aNode[p->iOff], &nSuffix);
+ p->iOff += fts3GetVarint32(&p->aNode[p->iOff], &nSuffix);
blobGrowBuffer(&p->term, nPrefix+nSuffix, &rc);
if( rc==SQLITE_OK ){
@@ -129097,7 +151012,7 @@ static int nodeReaderNext(NodeReader *p){
p->term.n = nPrefix+nSuffix;
p->iOff += nSuffix;
if( p->iChild==0 ){
- p->iOff += sqlite3Fts3GetVarint32(&p->aNode[p->iOff], &p->nDoclist);
+ p->iOff += fts3GetVarint32(&p->aNode[p->iOff], &p->nDoclist);
p->aDoclist = &p->aNode[p->iOff];
p->iOff += p->nDoclist;
}
@@ -129357,8 +151272,8 @@ static int fts3IncrmergeAppend(
nSpace += sqlite3Fts3VarintLen(nDoclist) + nDoclist;
}
+ pWriter->nLeafData += nSpace;
blobGrowBuffer(&pLeaf->block, pLeaf->block.n + nSpace, &rc);
-
if( rc==SQLITE_OK ){
if( pLeaf->block.n==0 ){
pLeaf->block.n = 1;
@@ -129457,6 +151372,7 @@ static void fts3IncrmergeRelease(
pWriter->iStart, /* start_block */
pWriter->aNodeWriter[0].iBlock, /* leaves_end_block */
pWriter->iEnd, /* end_block */
+ (pWriter->bNoLeafData==0 ? pWriter->nLeafData : 0), /* end_block */
pRoot->block.a, pRoot->block.n /* root */
);
}
@@ -129558,7 +151474,11 @@ static int fts3IncrmergeLoad(
if( sqlite3_step(pSelect)==SQLITE_ROW ){
iStart = sqlite3_column_int64(pSelect, 1);
iLeafEnd = sqlite3_column_int64(pSelect, 2);
- iEnd = sqlite3_column_int64(pSelect, 3);
+ fts3ReadEndBlockField(pSelect, 3, &iEnd, &pWriter->nLeafData);
+ if( pWriter->nLeafData<0 ){
+ pWriter->nLeafData = pWriter->nLeafData * -1;
+ }
+ pWriter->bNoLeafData = (pWriter->nLeafData==0);
nRoot = sqlite3_column_bytes(pSelect, 4);
aRoot = sqlite3_column_blob(pSelect, 4);
}else{
@@ -130149,8 +152069,8 @@ static int fts3IncrmergeHintPop(Blob *pHint, i64 *piAbsLevel, int *pnInput){
pHint->n = i;
i += sqlite3Fts3GetVarint(&pHint->a[i], piAbsLevel);
- i += sqlite3Fts3GetVarint32(&pHint->a[i], pnInput);
- if( i!=nHint ) return SQLITE_CORRUPT_VTAB;
+ i += fts3GetVarint32(&pHint->a[i], pnInput);
+ if( i!=nHint ) return FTS_CORRUPT_VTAB;
return SQLITE_OK;
}
@@ -130159,11 +152079,11 @@ static int fts3IncrmergeHintPop(Blob *pHint, i64 *piAbsLevel, int *pnInput){
/*
** 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.
+** Incremental merges happen nMin segments at a time. The segments
+** to be merged are the nMin oldest segments (the ones with the smallest
+** values for the _segdir.idx field) 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 */
@@ -130188,6 +152108,7 @@ SQLITE_PRIVATE int sqlite3Fts3Incrmerge(Fts3Table *p, int nMerge, int nMin){
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 */
+ int iIdx = 0; /* Largest idx in level (iAbsLevel+1) */
/* Search the %_segdir table for the absolute level with the smallest
** relative level number that contains at least nMin segments, if any.
@@ -130241,6 +152162,19 @@ SQLITE_PRIVATE int sqlite3Fts3Incrmerge(Fts3Table *p, int nMerge, int nMin){
** to start work on some other level. */
memset(pWriter, 0, nAlloc);
pFilter->flags = FTS3_SEGMENT_REQUIRE_POS;
+
+ if( rc==SQLITE_OK ){
+ rc = fts3IncrmergeOutputIdx(p, iAbsLevel, &iIdx);
+ assert( bUseHint==1 || bUseHint==0 );
+ if( iIdx==0 || (bUseHint && iIdx==1) ){
+ int bIgnore = 0;
+ rc = fts3SegmentIsMaxLevel(p, iAbsLevel+1, &bIgnore);
+ if( bIgnore ){
+ pFilter->flags |= FTS3_SEGMENT_IGNORE_EMPTY;
+ }
+ }
+ }
+
if( rc==SQLITE_OK ){
rc = fts3IncrmergeCsr(p, iAbsLevel, nSeg, pCsr);
}
@@ -130248,16 +152182,12 @@ SQLITE_PRIVATE int sqlite3Fts3Incrmerge(Fts3Table *p, int nMerge, int nMin){
&& 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( 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 ){
@@ -130279,7 +152209,13 @@ SQLITE_PRIVATE int sqlite3Fts3Incrmerge(Fts3Table *p, int nMerge, int nMin){
}
}
+ if( nSeg!=0 ){
+ pWriter->nLeafData = pWriter->nLeafData * -1;
+ }
fts3IncrmergeRelease(p, pWriter, &rc);
+ if( nSeg==0 && pWriter->bNoLeafData==0 ){
+ fts3PromoteSegments(p, iAbsLevel+1, pWriter->nLeafData);
+ }
}
sqlite3Fts3SegReaderFinish(pCsr);
@@ -130366,16 +152302,19 @@ static int fts3DoAutoincrmerge(
){
int rc = SQLITE_OK;
sqlite3_stmt *pStmt = 0;
- p->bAutoincrmerge = fts3Getint(&zParam)!=0;
+ p->nAutoincrmerge = fts3Getint(&zParam);
+ if( p->nAutoincrmerge==1 || p->nAutoincrmerge>FTS3_MERGE_COUNT ){
+ p->nAutoincrmerge = 8;
+ }
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;;
+ if( rc ) return rc;
sqlite3_bind_int(pStmt, 1, FTS_STAT_AUTOINCRMERGE);
- sqlite3_bind_int(pStmt, 2, p->bAutoincrmerge);
+ sqlite3_bind_int(pStmt, 2, p->nAutoincrmerge);
sqlite3_step(pStmt);
rc = sqlite3_reset(pStmt);
return rc;
@@ -130499,7 +152438,8 @@ static int fts3IntegrityCheck(Fts3Table *p, int *pbOk){
rc = fts3SqlStmt(p, SQL_SELECT_ALL_LANGID, &pAllLangid, 0);
if( rc==SQLITE_OK ){
int rc2;
- sqlite3_bind_int(pAllLangid, 1, p->nIndex);
+ sqlite3_bind_int(pAllLangid, 1, p->iPrevLangid);
+ sqlite3_bind_int(pAllLangid, 2, p->nIndex);
while( rc==SQLITE_OK && sqlite3_step(pAllLangid)==SQLITE_ROW ){
int iLangid = sqlite3_column_int(pAllLangid, 0);
int i;
@@ -130512,7 +152452,6 @@ static int fts3IntegrityCheck(Fts3Table *p, int *pbOk){
}
/* 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;
@@ -130532,34 +152471,36 @@ static int fts3IntegrityCheck(Fts3Table *p, int *pbOk){
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( p->abNotindexed[iCol]==0 ){
+ 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;
}
- if( pT ) pModule->xClose(pT);
- if( rc==SQLITE_DONE ) rc = SQLITE_OK;
}
}
@@ -130607,7 +152548,7 @@ static int fts3DoIntegrityCheck(
int rc;
int bOk = 0;
rc = fts3IntegrityCheck(p, &bOk);
- if( rc==SQLITE_OK && bOk==0 ) rc = SQLITE_CORRUPT_VTAB;
+ if( rc==SQLITE_OK && bOk==0 ) rc = FTS_CORRUPT_VTAB;
return rc;
}
@@ -130643,6 +152584,9 @@ static int fts3SpecialInsert(Fts3Table *p, sqlite3_value *pVal){
}else if( nVal>11 && 0==sqlite3_strnicmp(zVal, "maxpending=", 9) ){
p->nMaxPendingData = atoi(&zVal[11]);
rc = SQLITE_OK;
+ }else if( nVal>21 && 0==sqlite3_strnicmp(zVal, "test-no-incr-doclist=", 21) ){
+ p->bNoIncrDoclist = atoi(&zVal[21]);
+ rc = SQLITE_OK;
#endif
}else{
rc = SQLITE_ERROR;
@@ -130702,32 +152646,34 @@ SQLITE_PRIVATE int sqlite3Fts3CacheDeferredDoclists(Fts3Cursor *pCsr){
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( p->abNotindexed[i]==0 ){
+ 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;
}
- 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);
@@ -130859,6 +152805,10 @@ SQLITE_PRIVATE int sqlite3Fts3UpdateMethod(
int nChng = 0; /* Net change in number of documents */
int bInsertDone = 0;
+ /* At this point it must be known if the %_stat table exists or not.
+ ** So bHasStat may not be 2. */
+ assert( p->bHasStat==0 || p->bHasStat==1 );
+
assert( p->pSegments==0 );
assert(
nArg==1 /* DELETE operations */
@@ -130891,6 +152841,9 @@ SQLITE_PRIVATE int sqlite3Fts3UpdateMethod(
aSzIns = &aSzDel[p->nColumn+1];
memset(aSzDel, 0, sizeof(aSzDel[0])*(p->nColumn+1)*2);
+ rc = fts3Writelock(p);
+ if( rc!=SQLITE_OK ) goto update_out;
+
/* If this is an INSERT operation, or an UPDATE that modifies the rowid
** value, then this operation requires constraint handling.
**
@@ -130957,7 +152910,7 @@ SQLITE_PRIVATE int sqlite3Fts3UpdateMethod(
}
}
if( rc==SQLITE_OK && (!isRemove || *pRowid!=p->iPrevDocid ) ){
- rc = fts3PendingTermsDocid(p, iLangid, *pRowid);
+ rc = fts3PendingTermsDocid(p, 0, iLangid, *pRowid);
}
if( rc==SQLITE_OK ){
assert( p->iPrevDocid==*pRowid );
@@ -131018,6 +152971,7 @@ SQLITE_PRIVATE int sqlite3Fts3Optimize(Fts3Table *p){
******************************************************************************
*/
+/* #include "fts3Int.h" */
#if !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_FTS3)
/* #include <string.h> */
@@ -131033,6 +152987,8 @@ SQLITE_PRIVATE int sqlite3Fts3Optimize(Fts3Table *p){
#define FTS3_MATCHINFO_LENGTH 'l' /* nCol values */
#define FTS3_MATCHINFO_LCS 's' /* nCol values */
#define FTS3_MATCHINFO_HITS 'x' /* 3*nCol*nPhrase values */
+#define FTS3_MATCHINFO_LHITS 'y' /* nCol*nPhrase values */
+#define FTS3_MATCHINFO_LHITS_BM 'b' /* nCol*nPhrase values */
/*
** The default value for the second argument to matchinfo().
@@ -131094,9 +153050,22 @@ struct MatchInfo {
int nCol; /* Number of columns in table */
int nPhrase; /* Number of matchable phrases in query */
sqlite3_int64 nDoc; /* Number of docs in database */
+ char flag;
u32 *aMatchinfo; /* Pre-allocated buffer */
};
+/*
+** An instance of this structure is used to manage a pair of buffers, each
+** (nElem * sizeof(u32)) bytes in size. See the MatchinfoBuffer code below
+** for details.
+*/
+struct MatchinfoBuffer {
+ u8 aRef[3];
+ int nElem;
+ int bGlobal; /* Set if global data is loaded */
+ char *zMatchinfo;
+ u32 aMatchinfo[1];
+};
/*
@@ -131112,6 +153081,97 @@ struct StrBuffer {
};
+/*************************************************************************
+** Start of MatchinfoBuffer code.
+*/
+
+/*
+** Allocate a two-slot MatchinfoBuffer object.
+*/
+static MatchinfoBuffer *fts3MIBufferNew(int nElem, const char *zMatchinfo){
+ MatchinfoBuffer *pRet;
+ int nByte = sizeof(u32) * (2*nElem + 1) + sizeof(MatchinfoBuffer);
+ int nStr = (int)strlen(zMatchinfo);
+
+ pRet = sqlite3_malloc(nByte + nStr+1);
+ if( pRet ){
+ memset(pRet, 0, nByte);
+ pRet->aMatchinfo[0] = (u8*)(&pRet->aMatchinfo[1]) - (u8*)pRet;
+ pRet->aMatchinfo[1+nElem] = pRet->aMatchinfo[0] + sizeof(u32)*(nElem+1);
+ pRet->nElem = nElem;
+ pRet->zMatchinfo = ((char*)pRet) + nByte;
+ memcpy(pRet->zMatchinfo, zMatchinfo, nStr+1);
+ pRet->aRef[0] = 1;
+ }
+
+ return pRet;
+}
+
+static void fts3MIBufferFree(void *p){
+ MatchinfoBuffer *pBuf = (MatchinfoBuffer*)((u8*)p - ((u32*)p)[-1]);
+
+ assert( (u32*)p==&pBuf->aMatchinfo[1]
+ || (u32*)p==&pBuf->aMatchinfo[pBuf->nElem+2]
+ );
+ if( (u32*)p==&pBuf->aMatchinfo[1] ){
+ pBuf->aRef[1] = 0;
+ }else{
+ pBuf->aRef[2] = 0;
+ }
+
+ if( pBuf->aRef[0]==0 && pBuf->aRef[1]==0 && pBuf->aRef[2]==0 ){
+ sqlite3_free(pBuf);
+ }
+}
+
+static void (*fts3MIBufferAlloc(MatchinfoBuffer *p, u32 **paOut))(void*){
+ void (*xRet)(void*) = 0;
+ u32 *aOut = 0;
+
+ if( p->aRef[1]==0 ){
+ p->aRef[1] = 1;
+ aOut = &p->aMatchinfo[1];
+ xRet = fts3MIBufferFree;
+ }
+ else if( p->aRef[2]==0 ){
+ p->aRef[2] = 1;
+ aOut = &p->aMatchinfo[p->nElem+2];
+ xRet = fts3MIBufferFree;
+ }else{
+ aOut = (u32*)sqlite3_malloc(p->nElem * sizeof(u32));
+ if( aOut ){
+ xRet = sqlite3_free;
+ if( p->bGlobal ) memcpy(aOut, &p->aMatchinfo[1], p->nElem*sizeof(u32));
+ }
+ }
+
+ *paOut = aOut;
+ return xRet;
+}
+
+static void fts3MIBufferSetGlobal(MatchinfoBuffer *p){
+ p->bGlobal = 1;
+ memcpy(&p->aMatchinfo[2+p->nElem], &p->aMatchinfo[1], p->nElem*sizeof(u32));
+}
+
+/*
+** Free a MatchinfoBuffer object allocated using fts3MIBufferNew()
+*/
+SQLITE_PRIVATE void sqlite3Fts3MIBufferFree(MatchinfoBuffer *p){
+ if( p ){
+ assert( p->aRef[0]==1 );
+ p->aRef[0] = 0;
+ if( p->aRef[0]==0 && p->aRef[1]==0 && p->aRef[2]==0 ){
+ sqlite3_free(p);
+ }
+ }
+}
+
+/*
+** End of MatchinfoBuffer code.
+*************************************************************************/
+
+
/*
** 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
@@ -131134,7 +153194,7 @@ struct StrBuffer {
*/
static void fts3GetDeltaPosition(char **pp, int *piPos){
int iVal;
- *pp += sqlite3Fts3GetVarint32(*pp, &iVal);
+ *pp += fts3GetVarint32(*pp, &iVal);
*piPos += (iVal-2);
}
@@ -131148,7 +153208,7 @@ static int fts3ExprIterate2(
void *pCtx /* Second argument to pass to callback */
){
int rc; /* Return code */
- int eType = pExpr->eType; /* Type of expression node pExpr */
+ int eType = pExpr->eType; /* Type of expression node pExpr */
if( eType!=FTSQUERY_PHRASE ){
assert( pExpr->pLeft && pExpr->pRight );
@@ -131182,6 +153242,7 @@ static int fts3ExprIterate(
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
@@ -131226,8 +153287,7 @@ static int fts3ExprLoadDoclists(
static int fts3ExprPhraseCountCb(Fts3Expr *pExpr, int iPhrase, void *ctx){
(*(int *)ctx)++;
- UNUSED_PARAMETER(pExpr);
- UNUSED_PARAMETER(iPhrase);
+ pExpr->iPhrase = iPhrase;
return SQLITE_OK;
}
static int fts3ExprPhraseCount(Fts3Expr *pExpr){
@@ -131395,9 +153455,9 @@ static int fts3SnippetFindPositions(Fts3Expr *pExpr, int iPhrase, void *ctx){
** 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.
+** (a) +1 point for each occurrence of a matchable phrase in the snippet.
**
-** (b) +1000 points for the first occurence of each matchable phrase in
+** (b) +1000 points for the first occurrence 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
@@ -131448,37 +153508,39 @@ static int fts3BestSnippet(
sIter.nSnippet = nSnippet;
sIter.nPhrase = nList;
sIter.iCurrent = -1;
- (void)fts3ExprIterate(pCsr->pExpr, fts3SnippetFindPositions, (void *)&sIter);
+ rc = fts3ExprIterate(pCsr->pExpr, fts3SnippetFindPositions, (void*)&sIter);
+ if( rc==SQLITE_OK ){
- /* Set the *pmSeen output variable. */
- for(i=0; i<nList; i++){
- if( sIter.aPhrase[i].pHead ){
- *pmSeen |= (u64)1 << i;
+ /* 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;
+ /* 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 mHighlite;
+ fts3SnippetDetails(&sIter, mCovered, &iPos, &iScore, &mCover,&mHighlite);
+ assert( iScore>=0 );
+ if( iScore>iBestScore ){
+ pFragment->iPos = iPos;
+ pFragment->hlmask = mHighlite;
+ pFragment->covered = mCover;
+ iBestScore = iScore;
+ }
}
- }
+ *piScore = iBestScore;
+ }
sqlite3_free(sIter.aPhrase);
- *piScore = iBestScore;
- return SQLITE_OK;
+ return rc;
}
@@ -131510,6 +153572,7 @@ static int fts3StringAppend(
pStr->z = zNew;
pStr->nAlloc = nAlloc;
}
+ assert( pStr->z!=0 && (pStr->nAlloc >= pStr->n+nAppend+1) );
/* Append the data to the string buffer. */
memcpy(&pStr->z[pStr->n], zAppend, nAppend);
@@ -131685,8 +153748,12 @@ static int fts3SnippetText(
** 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 ){
+ if( iPos>0 || iFragment>0 ){
+ rc = fts3StringAppend(pOut, zEllipsis, -1);
+ }else if( iBegin ){
+ rc = fts3StringAppend(pOut, zDoc, iBegin);
+ }
}
if( rc!=SQLITE_OK || iCurrent<iPos ) continue;
}
@@ -131743,6 +153810,60 @@ static int fts3ColumnlistCount(char **ppCollist){
}
/*
+** This function gathers 'y' or 'b' data for a single phrase.
+*/
+static void fts3ExprLHits(
+ Fts3Expr *pExpr, /* Phrase expression node */
+ MatchInfo *p /* Matchinfo context */
+){
+ Fts3Table *pTab = (Fts3Table *)p->pCursor->base.pVtab;
+ int iStart;
+ Fts3Phrase *pPhrase = pExpr->pPhrase;
+ char *pIter = pPhrase->doclist.pList;
+ int iCol = 0;
+
+ assert( p->flag==FTS3_MATCHINFO_LHITS_BM || p->flag==FTS3_MATCHINFO_LHITS );
+ if( p->flag==FTS3_MATCHINFO_LHITS ){
+ iStart = pExpr->iPhrase * p->nCol;
+ }else{
+ iStart = pExpr->iPhrase * ((p->nCol + 31) / 32);
+ }
+
+ while( 1 ){
+ int nHit = fts3ColumnlistCount(&pIter);
+ if( (pPhrase->iColumn>=pTab->nColumn || pPhrase->iColumn==iCol) ){
+ if( p->flag==FTS3_MATCHINFO_LHITS ){
+ p->aMatchinfo[iStart + iCol] = (u32)nHit;
+ }else if( nHit ){
+ p->aMatchinfo[iStart + (iCol+1)/32] |= (1 << (iCol&0x1F));
+ }
+ }
+ assert( *pIter==0x00 || *pIter==0x01 );
+ if( *pIter!=0x01 ) break;
+ pIter++;
+ pIter += fts3GetVarint32(pIter, &iCol);
+ }
+}
+
+/*
+** Gather the results for matchinfo directives 'y' and 'b'.
+*/
+static void fts3ExprLHitGather(
+ Fts3Expr *pExpr,
+ MatchInfo *p
+){
+ assert( (pExpr->pLeft==0)==(pExpr->pRight==0) );
+ if( pExpr->bEof==0 && pExpr->iDocid==p->pCursor->iPrevId ){
+ if( pExpr->pLeft ){
+ fts3ExprLHitGather(pExpr->pLeft, p);
+ fts3ExprLHitGather(pExpr->pRight, p);
+ }else{
+ fts3ExprLHits(pExpr, p);
+ }
+ }
+}
+
+/*
** fts3ExprIterate() callback used to collect the "global" matchinfo stats
** for a single query.
**
@@ -131820,10 +153941,12 @@ static int fts3MatchinfoCheck(
|| (cArg==FTS3_MATCHINFO_LENGTH && pTab->bHasDocsize)
|| (cArg==FTS3_MATCHINFO_LCS)
|| (cArg==FTS3_MATCHINFO_HITS)
+ || (cArg==FTS3_MATCHINFO_LHITS)
+ || (cArg==FTS3_MATCHINFO_LHITS_BM)
){
return SQLITE_OK;
}
- *pzErr = sqlite3_mprintf("unrecognized matchinfo request: %c", cArg);
+ sqlite3Fts3ErrMsg(pzErr, "unrecognized matchinfo request: %c", cArg);
return SQLITE_ERROR;
}
@@ -131843,6 +153966,14 @@ static int fts3MatchinfoSize(MatchInfo *pInfo, char cArg){
nVal = pInfo->nCol;
break;
+ case FTS3_MATCHINFO_LHITS:
+ nVal = pInfo->nCol * pInfo->nPhrase;
+ break;
+
+ case FTS3_MATCHINFO_LHITS_BM:
+ nVal = pInfo->nPhrase * ((pInfo->nCol + 31) / 32);
+ break;
+
default:
assert( cArg==FTS3_MATCHINFO_HITS );
nVal = pInfo->nCol * pInfo->nPhrase * 3;
@@ -132037,7 +154168,7 @@ static int fts3MatchinfoValues(
sqlite3_stmt *pSelect = 0;
for(i=0; rc==SQLITE_OK && zArg[i]; i++){
-
+ pInfo->flag = zArg[i];
switch( zArg[i] ){
case FTS3_MATCHINFO_NPHRASE:
if( bGlobal ) pInfo->aMatchinfo[0] = pInfo->nPhrase;
@@ -132097,6 +154228,14 @@ static int fts3MatchinfoValues(
}
break;
+ case FTS3_MATCHINFO_LHITS_BM:
+ case FTS3_MATCHINFO_LHITS: {
+ int nZero = fts3MatchinfoSize(pInfo, zArg[i]) * sizeof(u32);
+ memset(pInfo->aMatchinfo, 0, nZero);
+ fts3ExprLHitGather(pCsr->pExpr, pInfo);
+ break;
+ }
+
default: {
Fts3Expr *pExpr;
assert( zArg[i]==FTS3_MATCHINFO_HITS );
@@ -132109,6 +154248,7 @@ static int fts3MatchinfoValues(
if( rc!=SQLITE_OK ) break;
}
rc = fts3ExprIterate(pExpr, fts3ExprGlobalHitsCb,(void*)pInfo);
+ sqlite3Fts3EvalTestDeferred(pCsr, &rc);
if( rc!=SQLITE_OK ) break;
}
(void)fts3ExprIterate(pExpr, fts3ExprLocalHitsCb,(void*)pInfo);
@@ -132128,7 +154268,8 @@ static int fts3MatchinfoValues(
** 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(
+static void fts3GetMatchinfo(
+ sqlite3_context *pCtx, /* Return results here */
Fts3Cursor *pCsr, /* FTS3 Cursor object */
const char *zArg /* Second argument to matchinfo() function */
){
@@ -132137,6 +154278,9 @@ static int fts3GetMatchinfo(
int rc = SQLITE_OK;
int bGlobal = 0; /* Collect 'global' stats as well as local */
+ u32 *aOut = 0;
+ void (*xDestroyOut)(void*) = 0;
+
memset(&sInfo, 0, sizeof(MatchInfo));
sInfo.pCursor = pCsr;
sInfo.nCol = pTab->nColumn;
@@ -132144,21 +154288,18 @@ static int fts3GetMatchinfo(
/* 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( pCsr->pMIBuffer && strcmp(pCsr->pMIBuffer->zMatchinfo, zArg) ){
+ sqlite3Fts3MIBufferFree(pCsr->pMIBuffer);
+ pCsr->pMIBuffer = 0;
}
- /* If Fts3Cursor.aMatchinfo[] is NULL, then this is the first time the
+ /* If Fts3Cursor.pMIBuffer 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 ){
+ if( pCsr->pMIBuffer==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 */
@@ -132167,30 +154308,46 @@ static int fts3GetMatchinfo(
/* Determine the number of integers in the buffer returned by this call. */
for(i=0; zArg[i]; i++){
+ char *zErr = 0;
+ if( fts3MatchinfoCheck(pTab, zArg[i], &zErr) ){
+ sqlite3_result_error(pCtx, zErr, -1);
+ sqlite3_free(zErr);
+ return;
+ }
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->pMIBuffer = fts3MIBufferNew(nMatchinfo, zArg);
+ if( !pCsr->pMIBuffer ) rc = SQLITE_NOMEM;
+
pCsr->isMatchinfoNeeded = 1;
bGlobal = 1;
}
- sInfo.aMatchinfo = pCsr->aMatchinfo;
- sInfo.nPhrase = pCsr->nPhrase;
- if( pCsr->isMatchinfoNeeded ){
+ if( rc==SQLITE_OK ){
+ xDestroyOut = fts3MIBufferAlloc(pCsr->pMIBuffer, &aOut);
+ if( xDestroyOut==0 ){
+ rc = SQLITE_NOMEM;
+ }
+ }
+
+ if( rc==SQLITE_OK ){
+ sInfo.aMatchinfo = aOut;
+ sInfo.nPhrase = pCsr->nPhrase;
rc = fts3MatchinfoValues(pCsr, bGlobal, &sInfo, zArg);
- pCsr->isMatchinfoNeeded = 0;
+ if( bGlobal ){
+ fts3MIBufferSetGlobal(pCsr->pMIBuffer);
+ }
}
- return rc;
+ if( rc!=SQLITE_OK ){
+ sqlite3_result_error_code(pCtx, rc);
+ if( xDestroyOut ) xDestroyOut(aOut);
+ }else{
+ int n = pCsr->pMIBuffer->nElem * sizeof(u32);
+ sqlite3_result_blob(pCtx, aOut, n, xDestroyOut);
+ }
}
/*
@@ -132252,7 +154409,7 @@ SQLITE_PRIVATE void sqlite3Fts3Snippet(
*/
for(iRead=0; iRead<pTab->nColumn; iRead++){
SnippetFragment sF = {0, 0, 0, 0};
- int iS;
+ int iS = 0;
if( iCol>=0 && iRead!=iCol ) continue;
/* Find the best snippet of nFToken tokens in column iRead. */
@@ -132396,7 +154553,7 @@ SQLITE_PRIVATE void sqlite3Fts3Offsets(
*/
sCtx.iCol = iCol;
sCtx.iTerm = 0;
- (void)fts3ExprIterate(pCsr->pExpr, fts3ExprTermOffsetInit, (void *)&sCtx);
+ (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.
@@ -132488,19 +154645,9 @@ SQLITE_PRIVATE void sqlite3Fts3Matchinfo(
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;
@@ -132509,17 +154656,10 @@ SQLITE_PRIVATE void sqlite3Fts3Matchinfo(
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);
+ /* Retrieve matchinfo() data. */
+ fts3GetMatchinfo(pContext, pCsr, zFormat);
+ sqlite3Fts3SegmentsClose(pTab);
}
}
@@ -132542,8 +154682,9 @@ SQLITE_PRIVATE void sqlite3Fts3Matchinfo(
** Implementation of the "unicode" full-text-search tokenizer.
*/
-#ifdef SQLITE_ENABLE_FTS4_UNICODE61
+#ifndef SQLITE_DISABLE_FTS3_UNICODE
+/* #include "fts3Int.h" */
#if !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_FTS3)
/* #include <assert.h> */
@@ -132551,6 +154692,7 @@ SQLITE_PRIVATE void sqlite3Fts3Matchinfo(
/* #include <stdio.h> */
/* #include <string.h> */
+/* #include "fts3_tokenizer.h" */
/*
** The following two macros - READ_UTF8 and WRITE_UTF8 - have been copied
@@ -132652,7 +154794,7 @@ static int unicodeDestroy(sqlite3_tokenizer *pTokenizer){
**
** 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
+** It is not possible to change the behavior of the tokenizer with respect
** to these codepoints.
*/
static int unicodeAddExceptions(
@@ -132758,7 +154900,7 @@ static int unicodeCreate(
for(i=0; rc==SQLITE_OK && i<nArg; i++){
const char *z = azArg[i];
- int n = strlen(z);
+ int n = (int)strlen(z);
if( n==19 && memcmp("remove_diacritics=1", z, 19)==0 ){
pNew->bRemoveDiacritic = 1;
@@ -132845,7 +154987,7 @@ static int unicodeNext(
){
unicode_cursor *pCsr = (unicode_cursor *)pC;
unicode_tokenizer *p = ((unicode_tokenizer *)pCsr->base.pTokenizer);
- int iCode;
+ int iCode = 0;
char *zOut;
const unsigned char *z = &pCsr->aInput[pCsr->iOff];
const unsigned char *zStart = z;
@@ -132890,11 +155032,11 @@ static int unicodeNext(
);
/* Set the output variables and return. */
- pCsr->iOff = (z - pCsr->aInput);
+ pCsr->iOff = (int)(z - pCsr->aInput);
*paToken = pCsr->zToken;
- *pnToken = zOut - pCsr->zToken;
- *piStart = (zStart - pCsr->aInput);
- *piEnd = (zEnd - pCsr->aInput);
+ *pnToken = (int)(zOut - pCsr->zToken);
+ *piStart = (int)(zStart - pCsr->aInput);
+ *piEnd = (int)(zEnd - pCsr->aInput);
*piPos = pCsr->iToken++;
return SQLITE_OK;
}
@@ -132917,7 +155059,7 @@ SQLITE_PRIVATE void sqlite3Fts3UnicodeTokenizer(sqlite3_tokenizer_module const *
}
#endif /* !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_FTS3) */
-#endif /* ifndef SQLITE_ENABLE_FTS4_UNICODE61 */
+#endif /* ifndef SQLITE_DISABLE_FTS3_UNICODE */
/************** End of fts3_unicode.c ****************************************/
/************** Begin file fts3_unicode2.c ***********************************/
@@ -132938,7 +155080,7 @@ SQLITE_PRIVATE void sqlite3Fts3UnicodeTokenizer(sqlite3_tokenizer_module const *
** DO NOT EDIT THIS MACHINE GENERATED FILE.
*/
-#if defined(SQLITE_ENABLE_FTS4_UNICODE61)
+#ifndef SQLITE_DISABLE_FTS3_UNICODE
#if defined(SQLITE_ENABLE_FTS3) || defined(SQLITE_ENABLE_FTS4)
/* #include <assert.h> */
@@ -132962,7 +155104,7 @@ SQLITE_PRIVATE int sqlite3FtsUnicodeIsalnum(int c){
** C. It is not possible to represent a range larger than 1023 codepoints
** using this format.
*/
- const static unsigned int aEntry[] = {
+ static const unsigned int aEntry[] = {
0x00000030, 0x0000E807, 0x00016C06, 0x0001EC2F, 0x0002AC07,
0x0002D001, 0x0002D803, 0x0002EC01, 0x0002FC01, 0x00035C01,
0x0003DC01, 0x000B0804, 0x000B480E, 0x000B9407, 0x000BB401,
@@ -133024,28 +155166,27 @@ SQLITE_PRIVATE int sqlite3FtsUnicodeIsalnum(int c){
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,
+ 0x037FFC01, 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,
};
static const unsigned int aAscii[4] = {
0xFFFFFFFF, 0xFC00FFFF, 0xF8000001, 0xF8000001,
@@ -133055,7 +155196,7 @@ SQLITE_PRIVATE int sqlite3FtsUnicodeIsalnum(int c){
return ( (aAscii[c >> 5] & (1 << (c & 0x001F)))==0 );
}else if( c<(1<<22) ){
unsigned int key = (((unsigned int)c)<<10) | 0x000003FF;
- int iRes;
+ int iRes = 0;
int iHi = sizeof(aEntry)/sizeof(aEntry[0]) - 1;
int iLo = 0;
while( iHi>=iLo ){
@@ -133126,7 +155267,7 @@ static int remove_diacritic(int c){
}
assert( key>=aDia[iRes] );
return ((c > (aDia[iRes]>>3) + (aDia[iRes]&0x07)) ? c : (int)aChar[iRes]);
-};
+}
/*
@@ -133286,7 +155427,7 @@ SQLITE_PRIVATE int sqlite3FtsUnicodeFold(int c, int bRemoveDiacritic){
return ret;
}
#endif /* defined(SQLITE_ENABLE_FTS3) || defined(SQLITE_ENABLE_FTS4) */
-#endif /* !defined(SQLITE_ENABLE_FTS4_UNICODE61) */
+#endif /* !defined(SQLITE_DISABLE_FTS3_UNICODE) */
/************** End of fts3_unicode2.c ***************************************/
/************** Begin file rtree.c *******************************************/
@@ -133346,60 +155487,22 @@ SQLITE_PRIVATE int sqlite3FtsUnicodeFold(int c, int bRemoveDiacritic){
#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
+/* #include "sqlite3ext.h" */
SQLITE_EXTENSION_INIT1
#else
+/* #include "sqlite3.h" */
#endif
/* #include <string.h> */
/* #include <assert.h> */
+/* #include <stdio.h> */
#ifndef SQLITE_AMALGAMATION
#include "sqlite3rtree.h"
typedef sqlite3_int64 i64;
typedef unsigned char u8;
+typedef unsigned short u16;
typedef unsigned int u32;
#endif
@@ -133417,6 +155520,7 @@ typedef struct RtreeConstraint RtreeConstraint;
typedef struct RtreeMatchArg RtreeMatchArg;
typedef struct RtreeGeomCallback RtreeGeomCallback;
typedef union RtreeCoord RtreeCoord;
+typedef struct RtreeSearchPoint RtreeSearchPoint;
/* The rtree may have between 1 and RTREE_MAX_DIMENSIONS dimensions. */
#define RTREE_MAX_DIMENSIONS 5
@@ -133425,22 +155529,33 @@ typedef union RtreeCoord RtreeCoord;
** ever contain very many entries, so a fixed number of buckets is
** used.
*/
-#define HASHSIZE 128
+#define HASHSIZE 97
+
+/* The xBestIndex method of this virtual table requires an estimate of
+** the number of rows in the virtual table to calculate the costs of
+** various strategies. If possible, this estimate is loaded from the
+** sqlite_stat1 table (with RTREE_MIN_ROWEST as a hard-coded minimum).
+** Otherwise, if no sqlite_stat1 entry is available, use
+** RTREE_DEFAULT_ROWEST.
+*/
+#define RTREE_DEFAULT_ROWEST 1048576
+#define RTREE_MIN_ROWEST 100
/*
** An rtree virtual-table object.
*/
struct Rtree {
- sqlite3_vtab base;
+ sqlite3_vtab base; /* Base class. Must be first */
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 */
+ u8 nDim; /* Number of dimensions */
+ u8 eCoordType; /* RTREE_COORD_REAL32 or RTREE_COORD_INT32 */
+ u8 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 */
+ i64 nRowEst; /* Estimated number of rows in this table */
/* List of nodes removed during a CondenseTree operation. List is
** linked together via the pointer normally used for hash chains -
@@ -133465,10 +155580,10 @@ struct Rtree {
sqlite3_stmt *pWriteParent;
sqlite3_stmt *pDeleteParent;
- int eCoordType;
+ RtreeNode *aHash[HASHSIZE]; /* Hash table of in-memory nodes. */
};
-/* Possible values for eCoordType: */
+/* Possible values for Rtree.eCoordType: */
#define RTREE_COORD_REAL32 0
#define RTREE_COORD_INT32 1
@@ -133480,12 +155595,31 @@ struct Rtree {
#ifdef SQLITE_RTREE_INT_ONLY
typedef sqlite3_int64 RtreeDValue; /* High accuracy coordinate */
typedef int RtreeValue; /* Low accuracy coordinate */
+# define RTREE_ZERO 0
#else
typedef double RtreeDValue; /* High accuracy coordinate */
typedef float RtreeValue; /* Low accuracy coordinate */
+# define RTREE_ZERO 0.0
#endif
/*
+** When doing a search of an r-tree, instances of the following structure
+** record intermediate results from the tree walk.
+**
+** The id is always a node-id. For iLevel>=1 the id is the node-id of
+** the node that the RtreeSearchPoint represents. When iLevel==0, however,
+** the id is of the parent node and the cell that RtreeSearchPoint
+** represents is the iCell-th entry in the parent node.
+*/
+struct RtreeSearchPoint {
+ RtreeDValue rScore; /* The score for this node. Smallest goes first. */
+ sqlite3_int64 id; /* Node ID */
+ u8 iLevel; /* 0=entries. 1=leaf node. 2+ for higher */
+ u8 eWithin; /* PARTLY_WITHIN or FULLY_WITHIN */
+ u8 iCell; /* Cell index within the node */
+};
+
+/*
** The minimum number of cells allowed for a node is a third of the
** maximum. In Gutman's notation:
**
@@ -133507,21 +155641,44 @@ struct Rtree {
*/
#define RTREE_MAX_DEPTH 40
+
+/*
+** Number of entries in the cursor RtreeNode cache. The first entry is
+** used to cache the RtreeNode for RtreeCursor.sPoint. The remaining
+** entries cache the RtreeNode for the first elements of the priority queue.
+*/
+#define RTREE_CACHE_SZ 5
+
/*
** 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 */
+ sqlite3_vtab_cursor base; /* Base class. Must be first */
+ u8 atEOF; /* True if at end of search */
+ u8 bPoint; /* True if sPoint is valid */
int iStrategy; /* Copy of idxNum search parameter */
int nConstraint; /* Number of entries in aConstraint */
RtreeConstraint *aConstraint; /* Search constraints. */
+ int nPointAlloc; /* Number of slots allocated for aPoint[] */
+ int nPoint; /* Number of slots used in aPoint[] */
+ int mxLevel; /* iLevel value for root of the tree */
+ RtreeSearchPoint *aPoint; /* Priority queue for search points */
+ RtreeSearchPoint sPoint; /* Cached next search point */
+ RtreeNode *aNode[RTREE_CACHE_SZ]; /* Rtree node cache */
+ u32 anQueue[RTREE_MAX_DEPTH+1]; /* Number of queued entries by iLevel */
};
+/* Return the Rtree of a RtreeCursor */
+#define RTREE_OF_CURSOR(X) ((Rtree*)((X)->base.pVtab))
+
+/*
+** A coordinate can be either a floating point number or a integer. All
+** coordinates within a single R-Tree are always of the same time.
+*/
union RtreeCoord {
- RtreeValue f;
- int i;
+ RtreeValue f; /* Floating point value */
+ int i; /* Integer value */
+ u32 u; /* Unsigned for byte-order conversions */
};
/*
@@ -133546,38 +155703,67 @@ union RtreeCoord {
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 */
+ union {
+ RtreeDValue rValue; /* Constraint value. */
+ int (*xGeom)(sqlite3_rtree_geometry*,int,RtreeDValue*,int*);
+ int (*xQueryFunc)(sqlite3_rtree_query_info*);
+ } u;
+ sqlite3_rtree_query_info *pInfo; /* xGeom and xQueryFunc argument */
};
/* 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
+#define RTREE_EQ 0x41 /* A */
+#define RTREE_LE 0x42 /* B */
+#define RTREE_LT 0x43 /* C */
+#define RTREE_GE 0x44 /* D */
+#define RTREE_GT 0x45 /* E */
+#define RTREE_MATCH 0x46 /* F: Old-style sqlite3_rtree_geometry_callback() */
+#define RTREE_QUERY 0x47 /* G: New-style sqlite3_rtree_query_callback() */
+
/*
** 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 */
+ RtreeNode *pParent; /* Parent node */
+ i64 iNode; /* The node number */
+ int nRef; /* Number of references to this node */
+ int isDirty; /* True if the node needs to be written to disk */
+ u8 *zData; /* Content of the node, as should be on disk */
+ RtreeNode *pNext; /* Next node in this hash collision chain */
};
+
+/* Return the number of cells in a node */
#define NCELL(pNode) readInt16(&(pNode)->zData[2])
/*
-** Structure to store a deserialized rtree record.
+** A single cell from a node, deserialized
*/
struct RtreeCell {
- i64 iRowid;
- RtreeCoord aCoord[RTREE_MAX_DIMENSIONS*2];
+ i64 iRowid; /* Node or entry ID */
+ RtreeCoord aCoord[RTREE_MAX_DIMENSIONS*2]; /* Bounding box coordinates */
+};
+
+
+/*
+** This object becomes the sqlite3_user_data() for the SQL functions
+** that are created by sqlite3_rtree_geometry_callback() and
+** sqlite3_rtree_query_callback() and which appear on the right of MATCH
+** operators in order to constrain a search.
+**
+** xGeom and xQueryFunc are the callback functions. Exactly one of
+** xGeom and xQueryFunc fields is non-NULL, depending on whether the
+** SQL function was created using sqlite3_rtree_geometry_callback() or
+** sqlite3_rtree_query_callback().
+**
+** This object is deleted automatically by the destructor mechanism in
+** sqlite3_create_function_v2().
+*/
+struct RtreeGeomCallback {
+ int (*xGeom)(sqlite3_rtree_geometry*, int, RtreeDValue*, int*);
+ int (*xQueryFunc)(sqlite3_rtree_query_info*);
+ void (*xDestructor)(void*);
+ void *pContext;
};
@@ -133589,29 +155775,17 @@ struct RtreeCell {
#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.
+** An instance of this structure (in the form of a BLOB) is returned by
+** the SQL functions that sqlite3_rtree_geometry_callback() and
+** sqlite3_rtree_query_callback() create, and is read as the right-hand
+** operand to the MATCH operator of an R-Tree.
*/
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;
+ u32 magic; /* Always RTREE_GEOMETRY_MAGIC */
+ RtreeGeomCallback cb; /* Info about the callback functions */
+ int nParam; /* Number of parameters to the SQL function */
+ sqlite3_value **apSqlParam; /* Original SQL parameter values */
+ RtreeDValue aParam[1]; /* Values for parameters to the SQL function */
};
#ifndef MAX
@@ -133629,13 +155803,12 @@ static int readInt16(u8 *p){
return (p[0]<<8) + p[1];
}
static void readCoord(u8 *p, RtreeCoord *pCoord){
- u32 i = (
+ pCoord->u = (
(((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 (
@@ -133664,7 +155837,7 @@ static int writeCoord(u8 *p, RtreeCoord *pCoord){
u32 i;
assert( sizeof(RtreeCoord)==4 );
assert( sizeof(u32)==4 );
- i = *(u32 *)pCoord;
+ i = pCoord->u;
p[0] = (i>>24)&0xFF;
p[1] = (i>>16)&0xFF;
p[2] = (i>> 8)&0xFF;
@@ -133705,10 +155878,7 @@ static void nodeZero(Rtree *pRtree, RtreeNode *p){
** 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;
+ return iNode % HASHSIZE;
}
/*
@@ -133768,8 +155938,7 @@ static RtreeNode *nodeNew(Rtree *pRtree, RtreeNode *pParent){
/*
** Obtain a reference to an r-tree node.
*/
-static int
-nodeAcquire(
+static int nodeAcquire(
Rtree *pRtree, /* R-tree structure */
i64 iNode, /* Node number to load */
RtreeNode *pParent, /* Either the parent node or NULL */
@@ -133858,10 +156027,10 @@ nodeAcquire(
** Overwrite cell iCell of node pNode with the contents of pCell.
*/
static void nodeOverwriteCell(
- Rtree *pRtree,
- RtreeNode *pNode,
- RtreeCell *pCell,
- int iCell
+ Rtree *pRtree, /* The overall R-Tree */
+ RtreeNode *pNode, /* The node into which the cell is to be written */
+ RtreeCell *pCell, /* The cell to write */
+ int iCell /* Index into pNode into which pCell is written */
){
int ii;
u8 *p = &pNode->zData[4 + pRtree->nBytesPerCell*iCell];
@@ -133873,7 +156042,7 @@ static void nodeOverwriteCell(
}
/*
-** Remove cell the cell with index iCell from node pNode.
+** Remove 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];
@@ -133890,11 +156059,10 @@ static void nodeDeleteCell(Rtree *pRtree, RtreeNode *pNode, int iCell){
**
** If there is not enough free space in pNode, return SQLITE_FULL.
*/
-static int
-nodeInsertCell(
- Rtree *pRtree,
- RtreeNode *pNode,
- RtreeCell *pCell
+static int nodeInsertCell(
+ Rtree *pRtree, /* The overall R-Tree */
+ RtreeNode *pNode, /* Write new cell into this node */
+ RtreeCell *pCell /* The cell to be inserted */
){
int nCell; /* Current number of cells in pNode */
int nMaxCell; /* Maximum number of cells for pNode */
@@ -133915,8 +156083,7 @@ nodeInsertCell(
/*
** If the node is dirty, write it out to the database.
*/
-static int
-nodeWrite(Rtree *pRtree, RtreeNode *pNode){
+static int nodeWrite(Rtree *pRtree, RtreeNode *pNode){
int rc = SQLITE_OK;
if( pNode->isDirty ){
sqlite3_stmt *p = pRtree->pWriteNode;
@@ -133941,8 +156108,7 @@ nodeWrite(Rtree *pRtree, RtreeNode *pNode){
** 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){
+static int nodeRelease(Rtree *pRtree, RtreeNode *pNode){
int rc = SQLITE_OK;
if( pNode ){
assert( pNode->nRef>0 );
@@ -133970,9 +156136,9 @@ nodeRelease(Rtree *pRtree, RtreeNode *pNode){
** an internal node, then the 64-bit integer is a child page number.
*/
static i64 nodeGetRowid(
- Rtree *pRtree,
- RtreeNode *pNode,
- int iCell
+ Rtree *pRtree, /* The overall R-Tree */
+ RtreeNode *pNode, /* The node from which to extract the ID */
+ int iCell /* The cell index from which to extract the ID */
){
assert( iCell<NCELL(pNode) );
return readInt64(&pNode->zData[4 + pRtree->nBytesPerCell*iCell]);
@@ -133982,11 +156148,11 @@ static i64 nodeGetRowid(
** 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 */
+ Rtree *pRtree, /* The overall R-Tree */
+ RtreeNode *pNode, /* The node from which to extract a coordinate */
+ int iCell, /* The index of the cell within the node */
+ int iCoord, /* Which coordinate to extract */
+ RtreeCoord *pCoord /* OUT: Space to write result to */
){
readCoord(&pNode->zData[12 + pRtree->nBytesPerCell*iCell + 4*iCoord], pCoord);
}
@@ -133996,15 +156162,19 @@ static void nodeGetCoord(
** to by pCell with the results.
*/
static void nodeGetCell(
- Rtree *pRtree,
- RtreeNode *pNode,
- int iCell,
- RtreeCell *pCell
+ Rtree *pRtree, /* The overall R-Tree */
+ RtreeNode *pNode, /* The node containing the cell to be read */
+ int iCell, /* Index of the cell within the node */
+ RtreeCell *pCell /* OUT: Write the cell contents here */
){
+ u8 *pData;
+ RtreeCoord *pCoord;
int ii;
pCell->iRowid = nodeGetRowid(pRtree, pNode, iCell);
+ pData = pNode->zData + (12 + pRtree->nBytesPerCell*iCell);
+ pCoord = pCell->aCoord;
for(ii=0; ii<pRtree->nDim*2; ii++){
- nodeGetCoord(pRtree, pNode, iCell, ii, &pCell->aCoord[ii]);
+ readCoord(&pData[ii*4], &pCoord[ii]);
}
}
@@ -134130,10 +156300,10 @@ 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_rtree_query_info *pInfo = pCsr->aConstraint[i].pInfo;
+ if( pInfo ){
+ if( pInfo->xDelUser ) pInfo->xDelUser(pInfo->pUser);
+ sqlite3_free(pInfo);
}
}
sqlite3_free(pCsr->aConstraint);
@@ -134146,12 +156316,13 @@ static void freeCursorConstraints(RtreeCursor *pCsr){
*/
static int rtreeClose(sqlite3_vtab_cursor *cur){
Rtree *pRtree = (Rtree *)(cur->pVtab);
- int rc;
+ int ii;
RtreeCursor *pCsr = (RtreeCursor *)cur;
freeCursorConstraints(pCsr);
- rc = nodeRelease(pRtree, pCsr->pNode);
+ sqlite3_free(pCsr->aPoint);
+ for(ii=0; ii<RTREE_CACHE_SZ; ii++) nodeRelease(pRtree, pCsr->aNode[ii]);
sqlite3_free(pCsr);
- return rc;
+ return SQLITE_OK;
}
/*
@@ -134162,194 +156333,164 @@ static int rtreeClose(sqlite3_vtab_cursor *cur){
*/
static int rtreeEof(sqlite3_vtab_cursor *cur){
RtreeCursor *pCsr = (RtreeCursor *)cur;
- return (pCsr->pNode==0);
+ return pCsr->atEOF;
+}
+
+/*
+** Convert raw bits from the on-disk RTree record into a coordinate value.
+** The on-disk format is big-endian and needs to be converted for little-
+** endian platforms. The on-disk record stores integer coordinates if
+** eInt is true and it stores 32-bit floating point records if eInt is
+** false. a[] is the four bytes of the on-disk record to be decoded.
+** Store the results in "r".
+**
+** There are three versions of this macro, one each for little-endian and
+** big-endian processors and a third generic implementation. The endian-
+** specific implementations are much faster and are preferred if the
+** processor endianness is known at compile-time. The SQLITE_BYTEORDER
+** macro is part of sqliteInt.h and hence the endian-specific
+** implementation will only be used if this module is compiled as part
+** of the amalgamation.
+*/
+#if defined(SQLITE_BYTEORDER) && SQLITE_BYTEORDER==1234
+#define RTREE_DECODE_COORD(eInt, a, r) { \
+ RtreeCoord c; /* Coordinate decoded */ \
+ memcpy(&c.u,a,4); \
+ c.u = ((c.u>>24)&0xff)|((c.u>>8)&0xff00)| \
+ ((c.u&0xff)<<24)|((c.u&0xff00)<<8); \
+ r = eInt ? (sqlite3_rtree_dbl)c.i : (sqlite3_rtree_dbl)c.f; \
+}
+#elif defined(SQLITE_BYTEORDER) && SQLITE_BYTEORDER==4321
+#define RTREE_DECODE_COORD(eInt, a, r) { \
+ RtreeCoord c; /* Coordinate decoded */ \
+ memcpy(&c.u,a,4); \
+ r = eInt ? (sqlite3_rtree_dbl)c.i : (sqlite3_rtree_dbl)c.f; \
}
+#else
+#define RTREE_DECODE_COORD(eInt, a, r) { \
+ RtreeCoord c; /* Coordinate decoded */ \
+ c.u = ((u32)a[0]<<24) + ((u32)a[1]<<16) \
+ +((u32)a[2]<<8) + a[3]; \
+ r = eInt ? (sqlite3_rtree_dbl)c.i : (sqlite3_rtree_dbl)c.f; \
+}
+#endif
/*
-** The r-tree constraint passed as the second argument to this function is
-** guaranteed to be a MATCH constraint.
+** Check the RTree node or entry given by pCellData and p against the MATCH
+** constraint pConstraint.
*/
-static int testRtreeGeom(
- Rtree *pRtree, /* R-Tree object */
- RtreeConstraint *pConstraint, /* MATCH constraint to test */
- RtreeCell *pCell, /* Cell to test */
- int *pbRes /* OUT: Test result */
+static int rtreeCallbackConstraint(
+ RtreeConstraint *pConstraint, /* The constraint to test */
+ int eInt, /* True if RTree holding integer coordinates */
+ u8 *pCellData, /* Raw cell content */
+ RtreeSearchPoint *pSearch, /* Container of this cell */
+ sqlite3_rtree_dbl *prScore, /* OUT: score for the cell */
+ int *peWithin /* OUT: visibility of the cell */
){
- int i;
- RtreeDValue aCoord[RTREE_MAX_DIMENSIONS*2];
- int nCoord = pRtree->nDim*2;
+ int i; /* Loop counter */
+ sqlite3_rtree_query_info *pInfo = pConstraint->pInfo; /* Callback info */
+ int nCoord = pInfo->nCoord; /* No. of coordinates */
+ int rc; /* Callback return code */
+ sqlite3_rtree_dbl aCoord[RTREE_MAX_DIMENSIONS*2]; /* Decoded coordinates */
- assert( pConstraint->op==RTREE_MATCH );
- assert( pConstraint->pGeom );
+ assert( pConstraint->op==RTREE_MATCH || pConstraint->op==RTREE_QUERY );
+ assert( nCoord==2 || nCoord==4 || nCoord==6 || nCoord==8 || nCoord==10 );
- for(i=0; i<nCoord; i++){
- aCoord[i] = DCOORD(pCell->aCoord[i]);
+ if( pConstraint->op==RTREE_QUERY && pSearch->iLevel==1 ){
+ pInfo->iRowid = readInt64(pCellData);
}
- 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;
- }
+ pCellData += 8;
+ for(i=0; i<nCoord; i++, pCellData += 4){
+ RTREE_DECODE_COORD(eInt, pCellData, aCoord[i]);
+ }
+ if( pConstraint->op==RTREE_MATCH ){
+ rc = pConstraint->u.xGeom((sqlite3_rtree_geometry*)pInfo,
+ nCoord, aCoord, &i);
+ if( i==0 ) *peWithin = NOT_WITHIN;
+ *prScore = RTREE_ZERO;
+ }else{
+ pInfo->aCoord = aCoord;
+ pInfo->iLevel = pSearch->iLevel - 1;
+ pInfo->rScore = pInfo->rParentScore = pSearch->rScore;
+ pInfo->eWithin = pInfo->eParentWithin = pSearch->eWithin;
+ rc = pConstraint->u.xQueryFunc(pInfo);
+ if( pInfo->eWithin<*peWithin ) *peWithin = pInfo->eWithin;
+ if( pInfo->rScore<*prScore || *prScore<RTREE_ZERO ){
+ *prScore = pInfo->rScore;
}
}
-
- *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.
+** Check the internal RTree node given by pCellData against constraint p.
+** If this constraint cannot be satisfied by any child within the node,
+** set *peWithin to NOT_WITHIN.
*/
-static int testRtreeEntry(Rtree *pRtree, RtreeCursor *pCursor, int *pbEof){
- RtreeCell cell;
- int ii;
- *pbEof = 0;
+static void rtreeNonleafConstraint(
+ RtreeConstraint *p, /* The constraint to test */
+ int eInt, /* True if RTree holds integer coordinates */
+ u8 *pCellData, /* Raw cell content as appears on disk */
+ int *peWithin /* Adjust downward, as appropriate */
+){
+ sqlite3_rtree_dbl val; /* Coordinate value convert to a double */
- 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;
- }
- }
+ /* p->iCoord might point to either a lower or upper bound coordinate
+ ** in a coordinate pair. But make pCellData point to the lower bound.
+ */
+ pCellData += 8 + 4*(p->iCoord&0xfe);
- if( !res ){
- *pbEof = 1;
- return SQLITE_OK;
- }
- }
+ assert(p->op==RTREE_LE || p->op==RTREE_LT || p->op==RTREE_GE
+ || p->op==RTREE_GT || p->op==RTREE_EQ );
+ switch( p->op ){
+ case RTREE_LE:
+ case RTREE_LT:
+ case RTREE_EQ:
+ RTREE_DECODE_COORD(eInt, pCellData, val);
+ /* val now holds the lower bound of the coordinate pair */
+ if( p->u.rValue>=val ) return;
+ if( p->op!=RTREE_EQ ) break; /* RTREE_LE and RTREE_LT end here */
+ /* Fall through for the RTREE_EQ case */
- return SQLITE_OK;
+ default: /* RTREE_GT or RTREE_GE, or fallthrough of RTREE_EQ */
+ pCellData += 4;
+ RTREE_DECODE_COORD(eInt, pCellData, val);
+ /* val now holds the upper bound of the coordinate pair */
+ if( p->u.rValue<=val ) return;
+ }
+ *peWithin = NOT_WITHIN;
}
/*
-** 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.
+** Check the leaf RTree cell given by pCellData against constraint p.
+** If this constraint is not satisfied, set *peWithin to NOT_WITHIN.
+** If the constraint is satisfied, leave *peWithin unchanged.
+**
+** The constraint is of the form: xN op $val
+**
+** The op is given by p->op. The xN is p->iCoord-th coordinate in
+** pCellData. $val is given by p->u.rValue.
*/
-static int descendToCell(
- Rtree *pRtree,
- RtreeCursor *pCursor,
- int iHeight,
- int *pEof /* OUT: Set to true if cannot descend */
+static void rtreeLeafConstraint(
+ RtreeConstraint *p, /* The constraint to test */
+ int eInt, /* True if RTree holds integer coordinates */
+ u8 *pCellData, /* Raw cell content as appears on disk */
+ int *peWithin /* Adjust downward, as appropriate */
){
- 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;
- }
+ RtreeDValue xN; /* Coordinate value converted to a double */
- 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;
+ assert(p->op==RTREE_LE || p->op==RTREE_LT || p->op==RTREE_GE
+ || p->op==RTREE_GT || p->op==RTREE_EQ );
+ pCellData += 8 + p->iCoord*4;
+ RTREE_DECODE_COORD(eInt, pCellData, xN);
+ switch( p->op ){
+ case RTREE_LE: if( xN <= p->u.rValue ) return; break;
+ case RTREE_LT: if( xN < p->u.rValue ) return; break;
+ case RTREE_GE: if( xN >= p->u.rValue ) return; break;
+ case RTREE_GT: if( xN > p->u.rValue ) return; break;
+ default: if( xN == p->u.rValue ) return; break;
}
-
-descend_to_cell_out:
- *pEof = isEof;
- return rc;
+ *peWithin = NOT_WITHIN;
}
/*
@@ -134364,6 +156505,7 @@ static int nodeRowidIndex(
){
int ii;
int nCell = NCELL(pNode);
+ assert( nCell<200 );
for(ii=0; ii<nCell; ii++){
if( nodeGetRowid(pRtree, pNode, ii)==iRowid ){
*piIndex = ii;
@@ -134386,48 +156528,302 @@ static int nodeParentIndex(Rtree *pRtree, RtreeNode *pNode, int *piIndex){
return SQLITE_OK;
}
-/*
-** Rtree virtual table module xNext method.
+/*
+** Compare two search points. Return negative, zero, or positive if the first
+** is less than, equal to, or greater than the second.
+**
+** The rScore is the primary key. Smaller rScore values come first.
+** If the rScore is a tie, then use iLevel as the tie breaker with smaller
+** iLevel values coming first. In this way, if rScore is the same for all
+** SearchPoints, then iLevel becomes the deciding factor and the result
+** is a depth-first search, which is the desired default behavior.
*/
-static int rtreeNext(sqlite3_vtab_cursor *pVtabCursor){
- Rtree *pRtree = (Rtree *)(pVtabCursor->pVtab);
- RtreeCursor *pCsr = (RtreeCursor *)pVtabCursor;
- int rc = SQLITE_OK;
+static int rtreeSearchPointCompare(
+ const RtreeSearchPoint *pA,
+ const RtreeSearchPoint *pB
+){
+ if( pA->rScore<pB->rScore ) return -1;
+ if( pA->rScore>pB->rScore ) return +1;
+ if( pA->iLevel<pB->iLevel ) return -1;
+ if( pA->iLevel>pB->iLevel ) return +1;
+ return 0;
+}
- /* 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;
- }
+/*
+** Interchange to search points in a cursor.
+*/
+static void rtreeSearchPointSwap(RtreeCursor *p, int i, int j){
+ RtreeSearchPoint t = p->aPoint[i];
+ assert( i<j );
+ p->aPoint[i] = p->aPoint[j];
+ p->aPoint[j] = t;
+ i++; j++;
+ if( i<RTREE_CACHE_SZ ){
+ if( j>=RTREE_CACHE_SZ ){
+ nodeRelease(RTREE_OF_CURSOR(p), p->aNode[i]);
+ p->aNode[i] = 0;
+ }else{
+ RtreeNode *pTemp = p->aNode[i];
+ p->aNode[i] = p->aNode[j];
+ p->aNode[j] = pTemp;
+ }
+ }
+}
+
+/*
+** Return the search point with the lowest current score.
+*/
+static RtreeSearchPoint *rtreeSearchPointFirst(RtreeCursor *pCur){
+ return pCur->bPoint ? &pCur->sPoint : pCur->nPoint ? pCur->aPoint : 0;
+}
+
+/*
+** Get the RtreeNode for the search point with the lowest score.
+*/
+static RtreeNode *rtreeNodeOfFirstSearchPoint(RtreeCursor *pCur, int *pRC){
+ sqlite3_int64 id;
+ int ii = 1 - pCur->bPoint;
+ assert( ii==0 || ii==1 );
+ assert( pCur->bPoint || pCur->nPoint );
+ if( pCur->aNode[ii]==0 ){
+ assert( pRC!=0 );
+ id = ii ? pCur->aPoint[0].id : pCur->sPoint.id;
+ *pRC = nodeAcquire(RTREE_OF_CURSOR(pCur), id, 0, &pCur->aNode[ii]);
+ }
+ return pCur->aNode[ii];
+}
+
+/*
+** Push a new element onto the priority queue
+*/
+static RtreeSearchPoint *rtreeEnqueue(
+ RtreeCursor *pCur, /* The cursor */
+ RtreeDValue rScore, /* Score for the new search point */
+ u8 iLevel /* Level for the new search point */
+){
+ int i, j;
+ RtreeSearchPoint *pNew;
+ if( pCur->nPoint>=pCur->nPointAlloc ){
+ int nNew = pCur->nPointAlloc*2 + 8;
+ pNew = sqlite3_realloc(pCur->aPoint, nNew*sizeof(pCur->aPoint[0]));
+ if( pNew==0 ) return 0;
+ pCur->aPoint = pNew;
+ pCur->nPointAlloc = nNew;
+ }
+ i = pCur->nPoint++;
+ pNew = pCur->aPoint + i;
+ pNew->rScore = rScore;
+ pNew->iLevel = iLevel;
+ assert( iLevel<=RTREE_MAX_DEPTH );
+ while( i>0 ){
+ RtreeSearchPoint *pParent;
+ j = (i-1)/2;
+ pParent = pCur->aPoint + j;
+ if( rtreeSearchPointCompare(pNew, pParent)>=0 ) break;
+ rtreeSearchPointSwap(pCur, j, i);
+ i = j;
+ pNew = pParent;
+ }
+ return pNew;
+}
+
+/*
+** Allocate a new RtreeSearchPoint and return a pointer to it. Return
+** NULL if malloc fails.
+*/
+static RtreeSearchPoint *rtreeSearchPointNew(
+ RtreeCursor *pCur, /* The cursor */
+ RtreeDValue rScore, /* Score for the new search point */
+ u8 iLevel /* Level for the new search point */
+){
+ RtreeSearchPoint *pNew, *pFirst;
+ pFirst = rtreeSearchPointFirst(pCur);
+ pCur->anQueue[iLevel]++;
+ if( pFirst==0
+ || pFirst->rScore>rScore
+ || (pFirst->rScore==rScore && pFirst->iLevel>iLevel)
+ ){
+ if( pCur->bPoint ){
+ int ii;
+ pNew = rtreeEnqueue(pCur, rScore, iLevel);
+ if( pNew==0 ) return 0;
+ ii = (int)(pNew - pCur->aPoint) + 1;
+ if( ii<RTREE_CACHE_SZ ){
+ assert( pCur->aNode[ii]==0 );
+ pCur->aNode[ii] = pCur->aNode[0];
+ }else{
+ nodeRelease(RTREE_OF_CURSOR(pCur), pCur->aNode[0]);
}
- pCsr->pNode = pNode->pParent;
- rc = nodeParentIndex(pRtree, pNode, &pCsr->iCell);
- if( rc!=SQLITE_OK ){
- return rc;
+ pCur->aNode[0] = 0;
+ *pNew = pCur->sPoint;
+ }
+ pCur->sPoint.rScore = rScore;
+ pCur->sPoint.iLevel = iLevel;
+ pCur->bPoint = 1;
+ return &pCur->sPoint;
+ }else{
+ return rtreeEnqueue(pCur, rScore, iLevel);
+ }
+}
+
+#if 0
+/* Tracing routines for the RtreeSearchPoint queue */
+static void tracePoint(RtreeSearchPoint *p, int idx, RtreeCursor *pCur){
+ if( idx<0 ){ printf(" s"); }else{ printf("%2d", idx); }
+ printf(" %d.%05lld.%02d %g %d",
+ p->iLevel, p->id, p->iCell, p->rScore, p->eWithin
+ );
+ idx++;
+ if( idx<RTREE_CACHE_SZ ){
+ printf(" %p\n", pCur->aNode[idx]);
+ }else{
+ printf("\n");
+ }
+}
+static void traceQueue(RtreeCursor *pCur, const char *zPrefix){
+ int ii;
+ printf("=== %9s ", zPrefix);
+ if( pCur->bPoint ){
+ tracePoint(&pCur->sPoint, -1, pCur);
+ }
+ for(ii=0; ii<pCur->nPoint; ii++){
+ if( ii>0 || pCur->bPoint ) printf(" ");
+ tracePoint(&pCur->aPoint[ii], ii, pCur);
+ }
+}
+# define RTREE_QUEUE_TRACE(A,B) traceQueue(A,B)
+#else
+# define RTREE_QUEUE_TRACE(A,B) /* no-op */
+#endif
+
+/* Remove the search point with the lowest current score.
+*/
+static void rtreeSearchPointPop(RtreeCursor *p){
+ int i, j, k, n;
+ i = 1 - p->bPoint;
+ assert( i==0 || i==1 );
+ if( p->aNode[i] ){
+ nodeRelease(RTREE_OF_CURSOR(p), p->aNode[i]);
+ p->aNode[i] = 0;
+ }
+ if( p->bPoint ){
+ p->anQueue[p->sPoint.iLevel]--;
+ p->bPoint = 0;
+ }else if( p->nPoint ){
+ p->anQueue[p->aPoint[0].iLevel]--;
+ n = --p->nPoint;
+ p->aPoint[0] = p->aPoint[n];
+ if( n<RTREE_CACHE_SZ-1 ){
+ p->aNode[1] = p->aNode[n+1];
+ p->aNode[n+1] = 0;
+ }
+ i = 0;
+ while( (j = i*2+1)<n ){
+ k = j+1;
+ if( k<n && rtreeSearchPointCompare(&p->aPoint[k], &p->aPoint[j])<0 ){
+ if( rtreeSearchPointCompare(&p->aPoint[k], &p->aPoint[i])<0 ){
+ rtreeSearchPointSwap(p, i, k);
+ i = k;
+ }else{
+ break;
+ }
+ }else{
+ if( rtreeSearchPointCompare(&p->aPoint[j], &p->aPoint[i])<0 ){
+ rtreeSearchPointSwap(p, i, j);
+ i = j;
+ }else{
+ break;
+ }
}
- nodeReference(pCsr->pNode);
- nodeRelease(pRtree, pNode);
- iHeight++;
}
}
+}
+
+
+/*
+** Continue the search on cursor pCur until the front of the queue
+** contains an entry suitable for returning as a result-set row,
+** or until the RtreeSearchPoint queue is empty, indicating that the
+** query has completed.
+*/
+static int rtreeStepToLeaf(RtreeCursor *pCur){
+ RtreeSearchPoint *p;
+ Rtree *pRtree = RTREE_OF_CURSOR(pCur);
+ RtreeNode *pNode;
+ int eWithin;
+ int rc = SQLITE_OK;
+ int nCell;
+ int nConstraint = pCur->nConstraint;
+ int ii;
+ int eInt;
+ RtreeSearchPoint x;
+
+ eInt = pRtree->eCoordType==RTREE_COORD_INT32;
+ while( (p = rtreeSearchPointFirst(pCur))!=0 && p->iLevel>0 ){
+ pNode = rtreeNodeOfFirstSearchPoint(pCur, &rc);
+ if( rc ) return rc;
+ nCell = NCELL(pNode);
+ assert( nCell<200 );
+ while( p->iCell<nCell ){
+ sqlite3_rtree_dbl rScore = (sqlite3_rtree_dbl)-1;
+ u8 *pCellData = pNode->zData + (4+pRtree->nBytesPerCell*p->iCell);
+ eWithin = FULLY_WITHIN;
+ for(ii=0; ii<nConstraint; ii++){
+ RtreeConstraint *pConstraint = pCur->aConstraint + ii;
+ if( pConstraint->op>=RTREE_MATCH ){
+ rc = rtreeCallbackConstraint(pConstraint, eInt, pCellData, p,
+ &rScore, &eWithin);
+ if( rc ) return rc;
+ }else if( p->iLevel==1 ){
+ rtreeLeafConstraint(pConstraint, eInt, pCellData, &eWithin);
+ }else{
+ rtreeNonleafConstraint(pConstraint, eInt, pCellData, &eWithin);
+ }
+ if( eWithin==NOT_WITHIN ) break;
+ }
+ p->iCell++;
+ if( eWithin==NOT_WITHIN ) continue;
+ x.iLevel = p->iLevel - 1;
+ if( x.iLevel ){
+ x.id = readInt64(pCellData);
+ x.iCell = 0;
+ }else{
+ x.id = p->id;
+ x.iCell = p->iCell - 1;
+ }
+ if( p->iCell>=nCell ){
+ RTREE_QUEUE_TRACE(pCur, "POP-S:");
+ rtreeSearchPointPop(pCur);
+ }
+ if( rScore<RTREE_ZERO ) rScore = RTREE_ZERO;
+ p = rtreeSearchPointNew(pCur, rScore, x.iLevel);
+ if( p==0 ) return SQLITE_NOMEM;
+ p->eWithin = eWithin;
+ p->id = x.id;
+ p->iCell = x.iCell;
+ RTREE_QUEUE_TRACE(pCur, "PUSH-S:");
+ break;
+ }
+ if( p->iCell>=nCell ){
+ RTREE_QUEUE_TRACE(pCur, "POP-Se:");
+ rtreeSearchPointPop(pCur);
+ }
+ }
+ pCur->atEOF = p==0;
+ return SQLITE_OK;
+}
+
+/*
+** Rtree virtual table module xNext method.
+*/
+static int rtreeNext(sqlite3_vtab_cursor *pVtabCursor){
+ RtreeCursor *pCsr = (RtreeCursor *)pVtabCursor;
+ int rc = SQLITE_OK;
+ /* Move to the next entry that matches the configured constraints. */
+ RTREE_QUEUE_TRACE(pCsr, "POP-Nx:");
+ rtreeSearchPointPop(pCsr);
+ rc = rtreeStepToLeaf(pCsr);
return rc;
}
@@ -134435,13 +156831,14 @@ static int rtreeNext(sqlite3_vtab_cursor *pVtabCursor){
** 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;
+ RtreeSearchPoint *p = rtreeSearchPointFirst(pCsr);
+ int rc = SQLITE_OK;
+ RtreeNode *pNode = rtreeNodeOfFirstSearchPoint(pCsr, &rc);
+ if( rc==SQLITE_OK && p ){
+ *pRowid = nodeGetRowid(RTREE_OF_CURSOR(pCsr), pNode, p->iCell);
+ }
+ return rc;
}
/*
@@ -134450,13 +156847,18 @@ static int rtreeRowid(sqlite3_vtab_cursor *pVtabCursor, sqlite_int64 *pRowid){
static int rtreeColumn(sqlite3_vtab_cursor *cur, sqlite3_context *ctx, int i){
Rtree *pRtree = (Rtree *)cur->pVtab;
RtreeCursor *pCsr = (RtreeCursor *)cur;
+ RtreeSearchPoint *p = rtreeSearchPointFirst(pCsr);
+ RtreeCoord c;
+ int rc = SQLITE_OK;
+ RtreeNode *pNode = rtreeNodeOfFirstSearchPoint(pCsr, &rc);
+ if( rc ) return rc;
+ if( p==0 ) return SQLITE_OK;
if( i==0 ){
- i64 iRowid = nodeGetRowid(pRtree, pCsr->pNode, pCsr->iCell);
- sqlite3_result_int64(ctx, iRowid);
+ sqlite3_result_int64(ctx, nodeGetRowid(pRtree, pNode, p->iCell));
}else{
- RtreeCoord c;
- nodeGetCoord(pRtree, pCsr->pNode, pCsr->iCell, i-1, &c);
+ if( rc ) return rc;
+ nodeGetCoord(pRtree, pNode, p->iCell, i-1, &c);
#ifndef SQLITE_RTREE_INT_ONLY
if( pRtree->eCoordType==RTREE_COORD_REAL32 ){
sqlite3_result_double(ctx, c.f);
@@ -134467,7 +156869,6 @@ static int rtreeColumn(sqlite3_vtab_cursor *cur, sqlite3_context *ctx, int i){
sqlite3_result_int(ctx, c.i);
}
}
-
return SQLITE_OK;
}
@@ -134478,12 +156879,18 @@ static int rtreeColumn(sqlite3_vtab_cursor *cur, sqlite3_context *ctx, int i){
** *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){
+static int findLeafNode(
+ Rtree *pRtree, /* RTree to search */
+ i64 iRowid, /* The rowid searching for */
+ RtreeNode **ppLeaf, /* Write the node here */
+ sqlite3_int64 *piNode /* Write the node-id here */
+){
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);
+ if( piNode ) *piNode = iNode;
rc = nodeAcquire(pRtree, iNode, 0, ppLeaf);
sqlite3_reset(pRtree->pReadRowid);
}else{
@@ -134499,42 +156906,45 @@ static int findLeafNode(Rtree *pRtree, i64 iRowid, RtreeNode **ppLeaf){
** operator.
*/
static int deserializeGeometry(sqlite3_value *pValue, RtreeConstraint *pCons){
- RtreeMatchArg *p;
- sqlite3_rtree_geometry *pGeom;
- int nBlob;
+ RtreeMatchArg *pBlob; /* BLOB returned by geometry function */
+ sqlite3_rtree_query_info *pInfo; /* Callback information */
+ int nBlob; /* Size of the geometry function blob */
+ int nExpected; /* Expected size of the BLOB */
/* 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
- ){
+ if( nBlob<(int)sizeof(RtreeMatchArg) ){
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];
+ pInfo = (sqlite3_rtree_query_info*)sqlite3_malloc( sizeof(*pInfo)+nBlob );
+ if( !pInfo ) return SQLITE_NOMEM;
+ memset(pInfo, 0, sizeof(*pInfo));
+ pBlob = (RtreeMatchArg*)&pInfo[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);
+ memcpy(pBlob, sqlite3_value_blob(pValue), nBlob);
+ nExpected = (int)(sizeof(RtreeMatchArg) +
+ pBlob->nParam*sizeof(sqlite3_value*) +
+ (pBlob->nParam-1)*sizeof(RtreeDValue));
+ if( pBlob->magic!=RTREE_GEOMETRY_MAGIC || nBlob!=nExpected ){
+ sqlite3_free(pInfo);
return SQLITE_ERROR;
}
+ pInfo->pContext = pBlob->cb.pContext;
+ pInfo->nParam = pBlob->nParam;
+ pInfo->aParam = pBlob->aParam;
+ pInfo->apSqlParam = pBlob->apSqlParam;
- pGeom->pContext = p->pContext;
- pGeom->nParam = p->nParam;
- pGeom->aParam = p->aParam;
-
- pCons->xGeom = p->xGeom;
- pCons->pGeom = pGeom;
+ if( pBlob->cb.xGeom ){
+ pCons->u.xGeom = pBlob->cb.xGeom;
+ }else{
+ pCons->op = RTREE_QUERY;
+ pCons->u.xQueryFunc = pBlob->cb.xQueryFunc;
+ }
+ pCons->pInfo = pInfo;
return SQLITE_OK;
}
@@ -134548,44 +156958,59 @@ static int rtreeFilter(
){
Rtree *pRtree = (Rtree *)pVtabCursor->pVtab;
RtreeCursor *pCsr = (RtreeCursor *)pVtabCursor;
-
RtreeNode *pRoot = 0;
int ii;
int rc = SQLITE_OK;
+ int iCell = 0;
rtreeReference(pRtree);
+ /* Reset the cursor to the same state as rtreeOpen() leaves it in. */
freeCursorConstraints(pCsr);
- pCsr->iStrategy = idxNum;
+ sqlite3_free(pCsr->aPoint);
+ memset(pCsr, 0, sizeof(RtreeCursor));
+ pCsr->base.pVtab = (sqlite3_vtab*)pRtree;
+ pCsr->iStrategy = idxNum;
if( idxNum==1 ){
/* Special case - lookup by rowid. */
RtreeNode *pLeaf; /* Leaf on which the required cell resides */
+ RtreeSearchPoint *p; /* Search point for the the leaf */
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);
+ i64 iNode = 0;
+ rc = findLeafNode(pRtree, iRowid, &pLeaf, &iNode);
+ if( rc==SQLITE_OK && pLeaf!=0 ){
+ p = rtreeSearchPointNew(pCsr, RTREE_ZERO, 0);
+ assert( p!=0 ); /* Always returns pCsr->sPoint */
+ pCsr->aNode[0] = pLeaf;
+ p->id = iNode;
+ p->eWithin = PARTLY_WITHIN;
+ rc = nodeRowidIndex(pRtree, pLeaf, iRowid, &iCell);
+ p->iCell = iCell;
+ RTREE_QUEUE_TRACE(pCsr, "PUSH-F1:");
+ }else{
+ pCsr->atEOF = 1;
}
}else{
/* Normal case - r-tree scan. Set up the RtreeCursor.aConstraint array
** with the configured constraints.
*/
- if( argc>0 ){
+ rc = nodeAcquire(pRtree, 1, 0, &pRoot);
+ if( rc==SQLITE_OK && 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);
+ memset(pCsr->anQueue, 0, sizeof(u32)*(pRtree->iDepth + 1));
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 ){
+ p->iCoord = idxStr[ii*2+1]-'0';
+ 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.
@@ -134594,46 +157019,53 @@ static int rtreeFilter(
if( rc!=SQLITE_OK ){
break;
}
+ p->pInfo->nCoord = pRtree->nDim*2;
+ p->pInfo->anQueue = pCsr->anQueue;
+ p->pInfo->mxLevel = pRtree->iDepth + 1;
}else{
#ifdef SQLITE_RTREE_INT_ONLY
- p->rValue = sqlite3_value_int64(argv[ii]);
+ p->u.rValue = sqlite3_value_int64(argv[ii]);
#else
- p->rValue = sqlite3_value_double(argv[ii]);
+ p->u.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) );
+ RtreeSearchPoint *pNew;
+ pNew = rtreeSearchPointNew(pCsr, RTREE_ZERO, pRtree->iDepth+1);
+ if( pNew==0 ) return SQLITE_NOMEM;
+ pNew->id = 1;
+ pNew->iCell = 0;
+ pNew->eWithin = PARTLY_WITHIN;
+ assert( pCsr->bPoint==1 );
+ pCsr->aNode[0] = pRoot;
+ pRoot = 0;
+ RTREE_QUEUE_TRACE(pCsr, "PUSH-Fm:");
+ rc = rtreeStepToLeaf(pCsr);
}
}
+ nodeRelease(pRtree, pRoot);
rtreeRelease(pRtree);
return rc;
}
/*
+** Set the pIdxInfo->estimatedRows variable to nRow. Unless this
+** extension is currently being used by a version of SQLite too old to
+** support estimatedRows. In that case this function is a no-op.
+*/
+static void setEstimatedRows(sqlite3_index_info *pIdxInfo, i64 nRow){
+#if SQLITE_VERSION_NUMBER>=3008002
+ if( sqlite3_libversion_number()>=3008002 ){
+ pIdxInfo->estimatedRows = nRow;
+ }
+#endif
+}
+
+/*
** Rtree virtual table module xBestIndex method. There are three
** table scan strategies to choose from (in order from most to
** least desirable):
@@ -134668,19 +157100,33 @@ static int rtreeFilter(
** is 'a', the second from the left 'b' etc.
*/
static int rtreeBestIndex(sqlite3_vtab *tab, sqlite3_index_info *pIdxInfo){
+ Rtree *pRtree = (Rtree*)tab;
int rc = SQLITE_OK;
int ii;
+ int bMatch = 0; /* True if there exists a MATCH constraint */
+ i64 nRow; /* Estimated rows returned by this scan */
int iIdx = 0;
char zIdxStr[RTREE_MAX_DIMENSIONS*8+1];
memset(zIdxStr, 0, sizeof(zIdxStr));
- UNUSED_PARAMETER(tab);
+
+ /* Check if there exists a MATCH constraint - even an unusable one. If there
+ ** is, do not consider the lookup-by-rowid plan as using such a plan would
+ ** require the VDBE to evaluate the MATCH constraint, which is not currently
+ ** possible. */
+ for(ii=0; ii<pIdxInfo->nConstraint; ii++){
+ if( pIdxInfo->aConstraint[ii].op==SQLITE_INDEX_CONSTRAINT_MATCH ){
+ bMatch = 1;
+ }
+ }
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 ){
+ if( bMatch==0 && 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++){
@@ -134694,9 +157140,11 @@ static int rtreeBestIndex(sqlite3_vtab *tab, sqlite3_index_info *pIdxInfo){
/* 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).
+ ** sqlite uses an internal cost of 0.0). It is expected to return
+ ** a single row.
*/
- pIdxInfo->estimatedCost = 10.0;
+ pIdxInfo->estimatedCost = 30.0;
+ setEstimatedRows(pIdxInfo, 1);
return SQLITE_OK;
}
@@ -134714,7 +157162,7 @@ static int rtreeBestIndex(sqlite3_vtab *tab, sqlite3_index_info *pIdxInfo){
break;
}
zIdxStr[iIdx++] = op;
- zIdxStr[iIdx++] = p->iColumn - 1 + 'a';
+ zIdxStr[iIdx++] = p->iColumn - 1 + '0';
pIdxInfo->aConstraintUsage[ii].argvIndex = (iIdx/2);
pIdxInfo->aConstraintUsage[ii].omit = 1;
}
@@ -134725,8 +157173,11 @@ static int rtreeBestIndex(sqlite3_vtab *tab, sqlite3_index_info *pIdxInfo){
if( iIdx>0 && 0==(pIdxInfo->idxStr = sqlite3_mprintf("%s", zIdxStr)) ){
return SQLITE_NOMEM;
}
- assert( iIdx>=0 );
- pIdxInfo->estimatedCost = (2000000.0 / (double)(iIdx + 1));
+
+ nRow = pRtree->nRowEst / (iIdx + 1);
+ pIdxInfo->estimatedCost = (double)6.0 * (double)nRow;
+ setEstimatedRows(pIdxInfo, nRow);
+
return rc;
}
@@ -134804,62 +157255,32 @@ static RtreeDValue cellGrowth(Rtree *pRtree, RtreeCell *p, RtreeCell *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 nCell
){
int ii;
- RtreeDValue overlap = 0.0;
+ RtreeDValue overlap = RTREE_ZERO;
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);
- }
+ 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 = (RtreeDValue)0;
+ break;
+ }else{
+ o = o * (x2-x1);
}
- overlap += o;
}
+ 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
/*
@@ -134881,12 +157302,8 @@ static int ChooseLeaf(
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
+ RtreeDValue fMinGrowth = RTREE_ZERO;
+ RtreeDValue fMinArea = RTREE_ZERO;
int nCell = NCELL(pNode);
RtreeCell cell;
@@ -134894,22 +157311,6 @@ static int ChooseLeaf(
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.
@@ -134921,26 +157322,9 @@ static int ChooseLeaf(
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;
@@ -135011,155 +157395,6 @@ static int parentWrite(Rtree *pRtree, sqlite3_int64 iNode, sqlite3_int64 iPar){
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
@@ -135300,7 +157535,6 @@ static void SortByDimension(
}
}
-#if VARIANT_RSTARTREE_SPLIT
/*
** Implementation of the R*-tree variant of SplitNode from Beckman[1990].
*/
@@ -135319,7 +157553,7 @@ static int splitNodeStartree(
int iBestDim = 0;
int iBestSplit = 0;
- RtreeDValue fBestMargin = 0.0;
+ RtreeDValue fBestMargin = RTREE_ZERO;
int nByte = (pRtree->nDim+1)*(sizeof(int*)+nCell*sizeof(int));
@@ -135340,9 +157574,9 @@ static int splitNodeStartree(
}
for(ii=0; ii<pRtree->nDim; ii++){
- RtreeDValue margin = 0.0;
- RtreeDValue fBestOverlap = 0.0;
- RtreeDValue fBestArea = 0.0;
+ RtreeDValue margin = RTREE_ZERO;
+ RtreeDValue fBestOverlap = RTREE_ZERO;
+ RtreeDValue fBestArea = RTREE_ZERO;
int iBestLeft = 0;
int nLeft;
@@ -135368,7 +157602,7 @@ static int splitNodeStartree(
}
margin += cellMargin(pRtree, &left);
margin += cellMargin(pRtree, &right);
- overlap = cellOverlap(pRtree, &left, &right, 1, -1);
+ overlap = cellOverlap(pRtree, &left, &right, 1);
area = cellArea(pRtree, &left) + cellArea(pRtree, &right);
if( (nLeft==RTREE_MINCELLS(pRtree))
|| (overlap<fBestOverlap)
@@ -135400,63 +157634,7 @@ static int splitNodeStartree(
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,
@@ -135534,7 +157712,8 @@ static int SplitNode(
memset(pLeft->zData, 0, pRtree->iNodeSize);
memset(pRight->zData, 0, pRtree->iNodeSize);
- rc = AssignCells(pRtree, aCell, nCell, pLeft, pRight, &leftbbox, &rightbbox);
+ rc = splitNodeStartree(pRtree, aCell, nCell, pLeft, pRight,
+ &leftbbox, &rightbbox);
if( rc!=SQLITE_OK ){
goto splitnode_out;
}
@@ -135817,7 +157996,7 @@ static int Reinsert(
}
for(ii=0; ii<nCell; ii++){
- aDistance[ii] = 0.0;
+ aDistance[ii] = RTREE_ZERO;
for(iDim=0; iDim<pRtree->nDim; iDim++){
RtreeDValue coord = (DCOORD(aCell[ii].aCoord[iDim*2+1]) -
DCOORD(aCell[ii].aCoord[iDim*2]));
@@ -135883,16 +158062,12 @@ static int rtreeInsertCell(
}
}
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 ){
@@ -135955,14 +158130,14 @@ static int rtreeDeleteRowid(Rtree *pRtree, sqlite3_int64 iDelete){
RtreeNode *pRoot; /* Root node of rtree structure */
- /* Obtain a reference to the root node to initialise Rtree.iDepth */
+ /* Obtain a reference to the root node to initialize 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);
+ rc = findLeafNode(pRtree, iDelete, &pLeaf, 0);
}
/* Delete the cell in question from the leaf node. */
@@ -136076,6 +158251,8 @@ static int rtreeUpdate(
rtreeReference(pRtree);
assert(nData>=1);
+ cell.iRowid = 0; /* Used only to suppress a compiler warning */
+
/* Constraint handling. A write operation on an r-tree table may return
** SQLITE_CONSTRAINT for two reasons:
**
@@ -136090,11 +158267,19 @@ static int rtreeUpdate(
if( nData>1 ){
int ii;
- /* Populate the cell.aCoord[] array. The first coordinate is azData[3]. */
- assert( nData==(pRtree->nDim*2 + 3) );
+ /* Populate the cell.aCoord[] array. The first coordinate is azData[3].
+ **
+ ** NB: nData can only be less than nDim*2+3 if the rtree is mis-declared
+ ** with "column" that are interpreted as table constraints.
+ ** Example: CREATE VIRTUAL TABLE bad USING rtree(x,y,CHECK(y>5));
+ ** This problem was discovered after years of use, so we silently ignore
+ ** these kinds of misdeclared tables to avoid breaking any legacy.
+ */
+ 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){
+ for(ii=0; ii<nData-4; 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 ){
@@ -136105,7 +158290,7 @@ static int rtreeUpdate(
}else
#endif
{
- for(ii=0; ii<(pRtree->nDim*2); ii+=2){
+ for(ii=0; ii<nData-4; 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 ){
@@ -136201,6 +158386,43 @@ static int rtreeRename(sqlite3_vtab *pVtab, const char *zNewName){
return rc;
}
+/*
+** This function populates the pRtree->nRowEst variable with an estimate
+** of the number of rows in the virtual table. If possible, this is based
+** on sqlite_stat1 data. Otherwise, use RTREE_DEFAULT_ROWEST.
+*/
+static int rtreeQueryStat1(sqlite3 *db, Rtree *pRtree){
+ const char *zFmt = "SELECT stat FROM %Q.sqlite_stat1 WHERE tbl = '%q_rowid'";
+ char *zSql;
+ sqlite3_stmt *p;
+ int rc;
+ i64 nRow = 0;
+
+ zSql = sqlite3_mprintf(zFmt, pRtree->zDb, pRtree->zName);
+ if( zSql==0 ){
+ rc = SQLITE_NOMEM;
+ }else{
+ rc = sqlite3_prepare_v2(db, zSql, -1, &p, 0);
+ if( rc==SQLITE_OK ){
+ if( sqlite3_step(p)==SQLITE_ROW ) nRow = sqlite3_column_int64(p, 0);
+ rc = sqlite3_finalize(p);
+ }else if( rc!=SQLITE_NOMEM ){
+ rc = SQLITE_OK;
+ }
+
+ if( rc==SQLITE_OK ){
+ if( nRow==0 ){
+ pRtree->nRowEst = RTREE_DEFAULT_ROWEST;
+ }else{
+ pRtree->nRowEst = MAX(nRow, RTREE_MIN_ROWEST);
+ }
+ }
+ sqlite3_free(zSql);
+ }
+
+ return rc;
+}
+
static sqlite3_module rtreeModule = {
0, /* iVersion */
rtreeCreate, /* xCreate - create a table */
@@ -136262,7 +158484,8 @@ static int rtreeSqlInit(
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);"
+"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
);
@@ -136286,6 +158509,7 @@ static int rtreeSqlInit(
appStmt[7] = &pRtree->pWriteParent;
appStmt[8] = &pRtree->pDeleteParent;
+ rc = rtreeQueryStat1(db, pRtree);
for(i=0; i<N_STATEMENT && rc==SQLITE_OK; i++){
char *zSql = sqlite3_mprintf(azSql[i], zDb, zPrefix);
if( zSql ){
@@ -136339,7 +158563,8 @@ static int getIntFromStmt(sqlite3 *db, const char *zSql, int *piVal){
static int getNodeSize(
sqlite3 *db, /* Database handle */
Rtree *pRtree, /* Rtree handle */
- int isCreate /* True for xCreate, false for xConnect */
+ int isCreate, /* True for xCreate, false for xConnect */
+ char **pzErr /* OUT: Error message, if any */
){
int rc;
char *zSql;
@@ -136352,6 +158577,8 @@ static int getNodeSize(
if( (4+pRtree->nBytesPerCell*RTREE_MAXCELLS)<pRtree->iNodeSize ){
pRtree->iNodeSize = 4+pRtree->nBytesPerCell*RTREE_MAXCELLS;
}
+ }else{
+ *pzErr = sqlite3_mprintf("%s", sqlite3_errmsg(db));
}
}else{
zSql = sqlite3_mprintf(
@@ -136359,6 +158586,9 @@ static int getNodeSize(
pRtree->zDb, pRtree->zName
);
rc = getIntFromStmt(db, zSql, &pRtree->iNodeSize);
+ if( rc!=SQLITE_OK ){
+ *pzErr = sqlite3_mprintf("%s", sqlite3_errmsg(db));
+ }
}
sqlite3_free(zSql);
@@ -136422,7 +158652,7 @@ static int rtreeInit(
memcpy(pRtree->zName, argv[2], nName);
/* Figure out the node size to use. */
- rc = getNodeSize(db, pRtree, isCreate);
+ rc = getNodeSize(db, pRtree, isCreate, pzErr);
/* Create/Connect to the underlying relational database schema. If
** that is successful, call sqlite3_declare_vtab() to configure
@@ -136457,6 +158687,8 @@ static int rtreeInit(
if( rc==SQLITE_OK ){
*ppVtab = (sqlite3_vtab *)pRtree;
}else{
+ assert( *ppVtab==0 );
+ assert( pRtree->nBusy==1 );
rtreeRelease(pRtree);
}
return rc;
@@ -136467,10 +158699,10 @@ static int rtreeInit(
** 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:
+** The scalar function takes two arguments: (1) the number of dimensions
+** to the rtree (between 1 and 5, inclusive) and (2) a blob of data containing
+** an r-tree node. For a two-dimensional r-tree structure called "rt", to
+** deserialize all nodes, a statement like:
**
** SELECT rtreenode(2, data) FROM rt_node;
**
@@ -136503,7 +158735,7 @@ static void rtreenode(sqlite3_context *ctx, int nArg, sqlite3_value **apArg){
nCell = (int)strlen(zCell);
for(jj=0; jj<tree.nDim*2; jj++){
#ifndef SQLITE_RTREE_INT_ONLY
- sqlite3_snprintf(512-nCell,&zCell[nCell], " %f",
+ sqlite3_snprintf(512-nCell,&zCell[nCell], " %g",
(double)cell.aCoord[jj].f);
#else
sqlite3_snprintf(512-nCell,&zCell[nCell], " %d",
@@ -136524,6 +158756,15 @@ static void rtreenode(sqlite3_context *ctx, int nArg, sqlite3_value **apArg){
sqlite3_result_text(ctx, zText, -1, sqlite3_free);
}
+/* This routine implements an SQL function that returns the "depth" parameter
+** from the front of a blob that is an r-tree node. For example:
+**
+** SELECT rtreedepth(data) FROM rt_node WHERE nodeno=1;
+**
+** The depth value is 0 for all nodes other than the root node, and the root
+** node always has nodeno=1, so the example above is the primary use for this
+** routine. This routine is intended for testing and analysis only.
+*/
static void rtreedepth(sqlite3_context *ctx, int nArg, sqlite3_value **apArg){
UNUSED_PARAMETER(nArg);
if( sqlite3_value_type(apArg[0])!=SQLITE_BLOB
@@ -136566,57 +158807,87 @@ SQLITE_PRIVATE int sqlite3RtreeInit(sqlite3 *db){
}
/*
-** 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.
+** This routine deletes the RtreeGeomCallback object that was attached
+** one of the SQL functions create by sqlite3_rtree_geometry_callback()
+** or sqlite3_rtree_query_callback(). In other words, this routine is the
+** destructor for an RtreeGeomCallback objecct. This routine is called when
+** the corresponding SQL function is deleted.
+*/
+static void rtreeFreeCallback(void *p){
+ RtreeGeomCallback *pInfo = (RtreeGeomCallback*)p;
+ if( pInfo->xDestructor ) pInfo->xDestructor(pInfo->pContext);
+ sqlite3_free(p);
+}
+
+/*
+** This routine frees the BLOB that is returned by geomCallback().
*/
-static void doSqlite3Free(void *p){
+static void rtreeMatchArgFree(void *pArg){
+ int i;
+ RtreeMatchArg *p = (RtreeMatchArg*)pArg;
+ for(i=0; i<p->nParam; i++){
+ sqlite3_value_free(p->apSqlParam[i]);
+ }
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.
+** Each call to sqlite3_rtree_geometry_callback() or
+** sqlite3_rtree_query_callback() creates an ordinary SQLite
+** scalar function that is implemented by this routine.
**
-** The scalar user functions return a blob that is interpreted by r-tree
-** table MATCH operators.
+** All this function does is construct an RtreeMatchArg object that
+** contains the geometry-checking callback routines and a list of
+** parameters to this function, then return that RtreeMatchArg object
+** as a BLOB.
+**
+** The R-Tree MATCH operator will read the returned BLOB, deserialize
+** the RtreeMatchArg object, and use the RtreeMatchArg object to figure
+** out which elements of the R-Tree should be returned by the query.
*/
static void geomCallback(sqlite3_context *ctx, int nArg, sqlite3_value **aArg){
RtreeGeomCallback *pGeomCtx = (RtreeGeomCallback *)sqlite3_user_data(ctx);
RtreeMatchArg *pBlob;
int nBlob;
+ int memErr = 0;
- nBlob = sizeof(RtreeMatchArg) + (nArg-1)*sizeof(RtreeDValue);
+ nBlob = sizeof(RtreeMatchArg) + (nArg-1)*sizeof(RtreeDValue)
+ + nArg*sizeof(sqlite3_value*);
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->cb = pGeomCtx[0];
+ pBlob->apSqlParam = (sqlite3_value**)&pBlob->aParam[nArg];
pBlob->nParam = nArg;
for(i=0; i<nArg; i++){
+ pBlob->apSqlParam[i] = sqlite3_value_dup(aArg[i]);
+ if( pBlob->apSqlParam[i]==0 ) memErr = 1;
#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);
+ if( memErr ){
+ sqlite3_result_error_nomem(ctx);
+ rtreeMatchArgFree(pBlob);
+ }else{
+ sqlite3_result_blob(ctx, pBlob, nBlob, rtreeMatchArgFree);
+ }
}
}
/*
** 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
+SQLITE_API int SQLITE_STDCALL sqlite3_rtree_geometry_callback(
+ sqlite3 *db, /* Register SQL function on this connection */
+ const char *zGeom, /* Name of the new SQL function */
+ int (*xGeom)(sqlite3_rtree_geometry*,int,RtreeDValue*,int*), /* Callback */
+ void *pContext /* Extra data associated with the callback */
){
RtreeGeomCallback *pGeomCtx; /* Context object for new user-function */
@@ -136624,17 +158895,44 @@ SQLITE_API int sqlite3_rtree_geometry_callback(
pGeomCtx = (RtreeGeomCallback *)sqlite3_malloc(sizeof(RtreeGeomCallback));
if( !pGeomCtx ) return SQLITE_NOMEM;
pGeomCtx->xGeom = xGeom;
+ pGeomCtx->xQueryFunc = 0;
+ pGeomCtx->xDestructor = 0;
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
+ (void *)pGeomCtx, geomCallback, 0, 0, rtreeFreeCallback
+ );
+}
+
+/*
+** Register a new 2nd-generation geometry function for use with the
+** r-tree MATCH operator.
+*/
+SQLITE_API int SQLITE_STDCALL sqlite3_rtree_query_callback(
+ sqlite3 *db, /* Register SQL function on this connection */
+ const char *zQueryFunc, /* Name of new SQL function */
+ int (*xQueryFunc)(sqlite3_rtree_query_info*), /* Callback */
+ void *pContext, /* Extra data passed into the callback */
+ void (*xDestructor)(void*) /* Destructor for the extra data */
+){
+ 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 = 0;
+ pGeomCtx->xQueryFunc = xQueryFunc;
+ pGeomCtx->xDestructor = xDestructor;
+ pGeomCtx->pContext = pContext;
+ return sqlite3_create_function_v2(db, zQueryFunc, -1, SQLITE_ANY,
+ (void *)pGeomCtx, geomCallback, 0, 0, rtreeFreeCallback
);
}
#if !SQLITE_CORE
-SQLITE_API int sqlite3_extension_init(
+#ifdef _WIN32
+__declspec(dllexport)
+#endif
+SQLITE_API int SQLITE_STDCALL sqlite3_rtree_init(
sqlite3 *db,
char **pzErrMsg,
const sqlite3_api_routines *pApi
@@ -136659,7 +158957,7 @@ SQLITE_API int sqlite3_extension_init(
** May you share freely, never taking more than you give.
**
*************************************************************************
-** $Id$
+** $Id: icu.c,v 1.7 2007/12/13 21:54:11 drh Exp $
**
** This file implements an integration between the ICU library
** ("International Components for Unicode", an open-source library
@@ -136672,7 +158970,7 @@ SQLITE_API int sqlite3_extension_init(
** * Implementations of the SQL scalar upper() and lower() functions
** for case mapping.
**
-** * Integration of ICU and SQLite collation seqences.
+** * Integration of ICU and SQLite collation sequences.
**
** * An implementation of the LIKE operator that uses ICU to
** provide case-independent matching.
@@ -136689,8 +158987,10 @@ SQLITE_API int sqlite3_extension_init(
/* #include <assert.h> */
#ifndef SQLITE_CORE
+/* #include "sqlite3ext.h" */
SQLITE_EXTENSION_INIT1
#else
+/* #include "sqlite3.h" */
#endif
/*
@@ -136731,7 +159031,6 @@ static int icuLikeCompare(
/* 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:
**
@@ -137070,6 +159369,7 @@ static void icuLoadCollation(
int rc; /* Return code from sqlite3_create_collation_x() */
assert(nArg==2);
+ (void)nArg; /* Unused parameter */
zLocale = (const char *)sqlite3_value_text(apArg[0]);
zName = (const char *)sqlite3_value_text(apArg[1]);
@@ -137136,7 +159436,10 @@ SQLITE_PRIVATE int sqlite3IcuInit(sqlite3 *db){
}
#if !SQLITE_CORE
-SQLITE_API int sqlite3_extension_init(
+#ifdef _WIN32
+__declspec(dllexport)
+#endif
+SQLITE_API int SQLITE_STDCALL sqlite3_icu_init(
sqlite3 *db,
char **pzErrMsg,
const sqlite3_api_routines *pApi
@@ -137163,11 +159466,13 @@ SQLITE_API int sqlite3_extension_init(
*************************************************************************
** This file implements a tokenizer for fts3 based on the ICU library.
*/
+/* #include "fts3Int.h" */
#if !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_FTS3)
#ifdef SQLITE_ENABLE_ICU
/* #include <assert.h> */
/* #include <string.h> */
+/* #include "fts3_tokenizer.h" */
#include <unicode/ubrk.h>
/* #include <unicode/ucol.h> */
@@ -137390,12 +159695,13 @@ static int icuNext(
** 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 */
+ 0, /* iVersion */
+ icuCreate, /* xCreate */
+ icuDestroy, /* xCreate */
+ icuOpen, /* xOpen */
+ icuClose, /* xClose */
+ icuNext, /* xNext */
+ 0, /* xLanguageid */
};
/*
@@ -137411,3 +159717,26325 @@ SQLITE_PRIVATE void sqlite3Fts3IcuTokenizerModule(
#endif /* !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_FTS3) */
/************** End of fts3_icu.c ********************************************/
+/************** Begin file sqlite3rbu.c **************************************/
+/*
+** 2014 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.
+**
+*************************************************************************
+**
+**
+** OVERVIEW
+**
+** The RBU extension requires that the RBU update be packaged as an
+** SQLite database. The tables it expects to find are described in
+** sqlite3rbu.h. Essentially, for each table xyz in the target database
+** that the user wishes to write to, a corresponding data_xyz table is
+** created in the RBU database and populated with one row for each row to
+** update, insert or delete from the target table.
+**
+** The update proceeds in three stages:
+**
+** 1) The database is updated. The modified database pages are written
+** to a *-oal file. A *-oal file is just like a *-wal file, except
+** that it is named "<database>-oal" instead of "<database>-wal".
+** Because regular SQLite clients do not look for file named
+** "<database>-oal", they go on using the original database in
+** rollback mode while the *-oal file is being generated.
+**
+** During this stage RBU does not update the database by writing
+** directly to the target tables. Instead it creates "imposter"
+** tables using the SQLITE_TESTCTRL_IMPOSTER interface that it uses
+** to update each b-tree individually. All updates required by each
+** b-tree are completed before moving on to the next, and all
+** updates are done in sorted key order.
+**
+** 2) The "<database>-oal" file is moved to the equivalent "<database>-wal"
+** location using a call to rename(2). Before doing this the RBU
+** module takes an EXCLUSIVE lock on the database file, ensuring
+** that there are no other active readers.
+**
+** Once the EXCLUSIVE lock is released, any other database readers
+** detect the new *-wal file and read the database in wal mode. At
+** this point they see the new version of the database - including
+** the updates made as part of the RBU update.
+**
+** 3) The new *-wal file is checkpointed. This proceeds in the same way
+** as a regular database checkpoint, except that a single frame is
+** checkpointed each time sqlite3rbu_step() is called. If the RBU
+** handle is closed before the entire *-wal file is checkpointed,
+** the checkpoint progress is saved in the RBU database and the
+** checkpoint can be resumed by another RBU client at some point in
+** the future.
+**
+** POTENTIAL PROBLEMS
+**
+** The rename() call might not be portable. And RBU is not currently
+** syncing the directory after renaming the file.
+**
+** When state is saved, any commit to the *-oal file and the commit to
+** the RBU update database are not atomic. So if the power fails at the
+** wrong moment they might get out of sync. As the main database will be
+** committed before the RBU update database this will likely either just
+** pass unnoticed, or result in SQLITE_CONSTRAINT errors (due to UNIQUE
+** constraint violations).
+**
+** If some client does modify the target database mid RBU update, or some
+** other error occurs, the RBU extension will keep throwing errors. It's
+** not really clear how to get out of this state. The system could just
+** by delete the RBU update database and *-oal file and have the device
+** download the update again and start over.
+**
+** At present, for an UPDATE, both the new.* and old.* records are
+** collected in the rbu_xyz table. And for both UPDATEs and DELETEs all
+** fields are collected. This means we're probably writing a lot more
+** data to disk when saving the state of an ongoing update to the RBU
+** update database than is strictly necessary.
+**
+*/
+
+/* #include <assert.h> */
+/* #include <string.h> */
+/* #include <stdio.h> */
+
+/* #include "sqlite3.h" */
+
+#if !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_RBU)
+/************** Include sqlite3rbu.h in the middle of sqlite3rbu.c ***********/
+/************** Begin file sqlite3rbu.h **************************************/
+/*
+** 2014 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.
+**
+*************************************************************************
+**
+** This file contains the public interface for the RBU extension.
+*/
+
+/*
+** SUMMARY
+**
+** Writing a transaction containing a large number of operations on
+** b-tree indexes that are collectively larger than the available cache
+** memory can be very inefficient.
+**
+** The problem is that in order to update a b-tree, the leaf page (at least)
+** containing the entry being inserted or deleted must be modified. If the
+** working set of leaves is larger than the available cache memory, then a
+** single leaf that is modified more than once as part of the transaction
+** may be loaded from or written to the persistent media multiple times.
+** Additionally, because the index updates are likely to be applied in
+** random order, access to pages within the database is also likely to be in
+** random order, which is itself quite inefficient.
+**
+** One way to improve the situation is to sort the operations on each index
+** by index key before applying them to the b-tree. This leads to an IO
+** pattern that resembles a single linear scan through the index b-tree,
+** and all but guarantees each modified leaf page is loaded and stored
+** exactly once. SQLite uses this trick to improve the performance of
+** CREATE INDEX commands. This extension allows it to be used to improve
+** the performance of large transactions on existing databases.
+**
+** Additionally, this extension allows the work involved in writing the
+** large transaction to be broken down into sub-transactions performed
+** sequentially by separate processes. This is useful if the system cannot
+** guarantee that a single update process will run for long enough to apply
+** the entire update, for example because the update is being applied on a
+** mobile device that is frequently rebooted. Even after the writer process
+** has committed one or more sub-transactions, other database clients continue
+** to read from the original database snapshot. In other words, partially
+** applied transactions are not visible to other clients.
+**
+** "RBU" stands for "Resumable Bulk Update". As in a large database update
+** transmitted via a wireless network to a mobile device. A transaction
+** applied using this extension is hence refered to as an "RBU update".
+**
+**
+** LIMITATIONS
+**
+** An "RBU update" transaction is subject to the following limitations:
+**
+** * The transaction must consist of INSERT, UPDATE and DELETE operations
+** only.
+**
+** * INSERT statements may not use any default values.
+**
+** * UPDATE and DELETE statements must identify their target rows by
+** non-NULL PRIMARY KEY values. Rows with NULL values stored in PRIMARY
+** KEY fields may not be updated or deleted. If the table being written
+** has no PRIMARY KEY, affected rows must be identified by rowid.
+**
+** * UPDATE statements may not modify PRIMARY KEY columns.
+**
+** * No triggers will be fired.
+**
+** * No foreign key violations are detected or reported.
+**
+** * CHECK constraints are not enforced.
+**
+** * No constraint handling mode except for "OR ROLLBACK" is supported.
+**
+**
+** PREPARATION
+**
+** An "RBU update" is stored as a separate SQLite database. A database
+** containing an RBU update is an "RBU database". For each table in the
+** target database to be updated, the RBU database should contain a table
+** named "data_<target name>" containing the same set of columns as the
+** target table, and one more - "rbu_control". The data_% table should
+** have no PRIMARY KEY or UNIQUE constraints, but each column should have
+** the same type as the corresponding column in the target database.
+** The "rbu_control" column should have no type at all. For example, if
+** the target database contains:
+**
+** CREATE TABLE t1(a INTEGER PRIMARY KEY, b TEXT, c UNIQUE);
+**
+** Then the RBU database should contain:
+**
+** CREATE TABLE data_t1(a INTEGER, b TEXT, c, rbu_control);
+**
+** The order of the columns in the data_% table does not matter.
+**
+** Instead of a regular table, the RBU database may also contain virtual
+** tables or view named using the data_<target> naming scheme.
+**
+** Instead of the plain data_<target> naming scheme, RBU database tables
+** may also be named data<integer>_<target>, where <integer> is any sequence
+** of zero or more numeric characters (0-9). This can be significant because
+** tables within the RBU database are always processed in order sorted by
+** name. By judicious selection of the the <integer> portion of the names
+** of the RBU tables the user can therefore control the order in which they
+** are processed. This can be useful, for example, to ensure that "external
+** content" FTS4 tables are updated before their underlying content tables.
+**
+** If the target database table is a virtual table or a table that has no
+** PRIMARY KEY declaration, the data_% table must also contain a column
+** named "rbu_rowid". This column is mapped to the tables implicit primary
+** key column - "rowid". Virtual tables for which the "rowid" column does
+** not function like a primary key value cannot be updated using RBU. For
+** example, if the target db contains either of the following:
+**
+** CREATE VIRTUAL TABLE x1 USING fts3(a, b);
+** CREATE TABLE x1(a, b)
+**
+** then the RBU database should contain:
+**
+** CREATE TABLE data_x1(a, b, rbu_rowid, rbu_control);
+**
+** All non-hidden columns (i.e. all columns matched by "SELECT *") of the
+** target table must be present in the input table. For virtual tables,
+** hidden columns are optional - they are updated by RBU if present in
+** the input table, or not otherwise. For example, to write to an fts4
+** table with a hidden languageid column such as:
+**
+** CREATE VIRTUAL TABLE ft1 USING fts4(a, b, languageid='langid');
+**
+** Either of the following input table schemas may be used:
+**
+** CREATE TABLE data_ft1(a, b, langid, rbu_rowid, rbu_control);
+** CREATE TABLE data_ft1(a, b, rbu_rowid, rbu_control);
+**
+** For each row to INSERT into the target database as part of the RBU
+** update, the corresponding data_% table should contain a single record
+** with the "rbu_control" column set to contain integer value 0. The
+** other columns should be set to the values that make up the new record
+** to insert.
+**
+** If the target database table has an INTEGER PRIMARY KEY, it is not
+** possible to insert a NULL value into the IPK column. Attempting to
+** do so results in an SQLITE_MISMATCH error.
+**
+** For each row to DELETE from the target database as part of the RBU
+** update, the corresponding data_% table should contain a single record
+** with the "rbu_control" column set to contain integer value 1. The
+** real primary key values of the row to delete should be stored in the
+** corresponding columns of the data_% table. The values stored in the
+** other columns are not used.
+**
+** For each row to UPDATE from the target database as part of the RBU
+** update, the corresponding data_% table should contain a single record
+** with the "rbu_control" column set to contain a value of type text.
+** The real primary key values identifying the row to update should be
+** stored in the corresponding columns of the data_% table row, as should
+** the new values of all columns being update. The text value in the
+** "rbu_control" column must contain the same number of characters as
+** there are columns in the target database table, and must consist entirely
+** of 'x' and '.' characters (or in some special cases 'd' - see below). For
+** each column that is being updated, the corresponding character is set to
+** 'x'. For those that remain as they are, the corresponding character of the
+** rbu_control value should be set to '.'. For example, given the tables
+** above, the update statement:
+**
+** UPDATE t1 SET c = 'usa' WHERE a = 4;
+**
+** is represented by the data_t1 row created by:
+**
+** INSERT INTO data_t1(a, b, c, rbu_control) VALUES(4, NULL, 'usa', '..x');
+**
+** Instead of an 'x' character, characters of the rbu_control value specified
+** for UPDATEs may also be set to 'd'. In this case, instead of updating the
+** target table with the value stored in the corresponding data_% column, the
+** user-defined SQL function "rbu_delta()" is invoked and the result stored in
+** the target table column. rbu_delta() is invoked with two arguments - the
+** original value currently stored in the target table column and the
+** value specified in the data_xxx table.
+**
+** For example, this row:
+**
+** INSERT INTO data_t1(a, b, c, rbu_control) VALUES(4, NULL, 'usa', '..d');
+**
+** is similar to an UPDATE statement such as:
+**
+** UPDATE t1 SET c = rbu_delta(c, 'usa') WHERE a = 4;
+**
+** Finally, if an 'f' character appears in place of a 'd' or 's' in an
+** ota_control string, the contents of the data_xxx table column is assumed
+** to be a "fossil delta" - a patch to be applied to a blob value in the
+** format used by the fossil source-code management system. In this case
+** the existing value within the target database table must be of type BLOB.
+** It is replaced by the result of applying the specified fossil delta to
+** itself.
+**
+** If the target database table is a virtual table or a table with no PRIMARY
+** KEY, the rbu_control value should not include a character corresponding
+** to the rbu_rowid value. For example, this:
+**
+** INSERT INTO data_ft1(a, b, rbu_rowid, rbu_control)
+** VALUES(NULL, 'usa', 12, '.x');
+**
+** causes a result similar to:
+**
+** UPDATE ft1 SET b = 'usa' WHERE rowid = 12;
+**
+** The data_xxx tables themselves should have no PRIMARY KEY declarations.
+** However, RBU is more efficient if reading the rows in from each data_xxx
+** table in "rowid" order is roughly the same as reading them sorted by
+** the PRIMARY KEY of the corresponding target database table. In other
+** words, rows should be sorted using the destination table PRIMARY KEY
+** fields before they are inserted into the data_xxx tables.
+**
+** USAGE
+**
+** The API declared below allows an application to apply an RBU update
+** stored on disk to an existing target database. Essentially, the
+** application:
+**
+** 1) Opens an RBU handle using the sqlite3rbu_open() function.
+**
+** 2) Registers any required virtual table modules with the database
+** handle returned by sqlite3rbu_db(). Also, if required, register
+** the rbu_delta() implementation.
+**
+** 3) Calls the sqlite3rbu_step() function one or more times on
+** the new handle. Each call to sqlite3rbu_step() performs a single
+** b-tree operation, so thousands of calls may be required to apply
+** a complete update.
+**
+** 4) Calls sqlite3rbu_close() to close the RBU update handle. If
+** sqlite3rbu_step() has been called enough times to completely
+** apply the update to the target database, then the RBU database
+** is marked as fully applied. Otherwise, the state of the RBU
+** update application is saved in the RBU database for later
+** resumption.
+**
+** See comments below for more detail on APIs.
+**
+** If an update is only partially applied to the target database by the
+** time sqlite3rbu_close() is called, various state information is saved
+** within the RBU database. This allows subsequent processes to automatically
+** resume the RBU update from where it left off.
+**
+** To remove all RBU extension state information, returning an RBU database
+** to its original contents, it is sufficient to drop all tables that begin
+** with the prefix "rbu_"
+**
+** DATABASE LOCKING
+**
+** An RBU update may not be applied to a database in WAL mode. Attempting
+** to do so is an error (SQLITE_ERROR).
+**
+** While an RBU handle is open, a SHARED lock may be held on the target
+** database file. This means it is possible for other clients to read the
+** database, but not to write it.
+**
+** If an RBU update is started and then suspended before it is completed,
+** then an external client writes to the database, then attempting to resume
+** the suspended RBU update is also an error (SQLITE_BUSY).
+*/
+
+#ifndef _SQLITE3RBU_H
+#define _SQLITE3RBU_H
+
+/* #include "sqlite3.h" ** Required for error code definitions ** */
+
+#if 0
+extern "C" {
+#endif
+
+typedef struct sqlite3rbu sqlite3rbu;
+
+/*
+** Open an RBU handle.
+**
+** Argument zTarget is the path to the target database. Argument zRbu is
+** the path to the RBU database. Each call to this function must be matched
+** by a call to sqlite3rbu_close(). When opening the databases, RBU passes
+** the SQLITE_CONFIG_URI flag to sqlite3_open_v2(). So if either zTarget
+** or zRbu begin with "file:", it will be interpreted as an SQLite
+** database URI, not a regular file name.
+**
+** If the zState argument is passed a NULL value, the RBU extension stores
+** the current state of the update (how many rows have been updated, which
+** indexes are yet to be updated etc.) within the RBU database itself. This
+** can be convenient, as it means that the RBU application does not need to
+** organize removing a separate state file after the update is concluded.
+** Or, if zState is non-NULL, it must be a path to a database file in which
+** the RBU extension can store the state of the update.
+**
+** When resuming an RBU update, the zState argument must be passed the same
+** value as when the RBU update was started.
+**
+** Once the RBU update is finished, the RBU extension does not
+** automatically remove any zState database file, even if it created it.
+**
+** By default, RBU uses the default VFS to access the files on disk. To
+** use a VFS other than the default, an SQLite "file:" URI containing a
+** "vfs=..." option may be passed as the zTarget option.
+**
+** IMPORTANT NOTE FOR ZIPVFS USERS: The RBU extension works with all of
+** SQLite's built-in VFSs, including the multiplexor VFS. However it does
+** not work out of the box with zipvfs. Refer to the comment describing
+** the zipvfs_create_vfs() API below for details on using RBU with zipvfs.
+*/
+SQLITE_API sqlite3rbu *SQLITE_STDCALL sqlite3rbu_open(
+ const char *zTarget,
+ const char *zRbu,
+ const char *zState
+);
+
+/*
+** Internally, each RBU connection uses a separate SQLite database
+** connection to access the target and rbu update databases. This
+** API allows the application direct access to these database handles.
+**
+** The first argument passed to this function must be a valid, open, RBU
+** handle. The second argument should be passed zero to access the target
+** database handle, or non-zero to access the rbu update database handle.
+** Accessing the underlying database handles may be useful in the
+** following scenarios:
+**
+** * If any target tables are virtual tables, it may be necessary to
+** call sqlite3_create_module() on the target database handle to
+** register the required virtual table implementations.
+**
+** * If the data_xxx tables in the RBU source database are virtual
+** tables, the application may need to call sqlite3_create_module() on
+** the rbu update db handle to any required virtual table
+** implementations.
+**
+** * If the application uses the "rbu_delta()" feature described above,
+** it must use sqlite3_create_function() or similar to register the
+** rbu_delta() implementation with the target database handle.
+**
+** If an error has occurred, either while opening or stepping the RBU object,
+** this function may return NULL. The error code and message may be collected
+** when sqlite3rbu_close() is called.
+**
+** Database handles returned by this function remain valid until the next
+** call to any sqlite3rbu_xxx() function other than sqlite3rbu_db().
+*/
+SQLITE_API sqlite3 *SQLITE_STDCALL sqlite3rbu_db(sqlite3rbu*, int bRbu);
+
+/*
+** Do some work towards applying the RBU update to the target db.
+**
+** Return SQLITE_DONE if the update has been completely applied, or
+** SQLITE_OK if no error occurs but there remains work to do to apply
+** the RBU update. If an error does occur, some other error code is
+** returned.
+**
+** Once a call to sqlite3rbu_step() has returned a value other than
+** SQLITE_OK, all subsequent calls on the same RBU handle are no-ops
+** that immediately return the same value.
+*/
+SQLITE_API int SQLITE_STDCALL sqlite3rbu_step(sqlite3rbu *pRbu);
+
+/*
+** Force RBU to save its state to disk.
+**
+** If a power failure or application crash occurs during an update, following
+** system recovery RBU may resume the update from the point at which the state
+** was last saved. In other words, from the most recent successful call to
+** sqlite3rbu_close() or this function.
+**
+** SQLITE_OK is returned if successful, or an SQLite error code otherwise.
+*/
+SQLITE_API int SQLITE_STDCALL sqlite3rbu_savestate(sqlite3rbu *pRbu);
+
+/*
+** Close an RBU handle.
+**
+** If the RBU update has been completely applied, mark the RBU database
+** as fully applied. Otherwise, assuming no error has occurred, save the
+** current state of the RBU update appliation to the RBU database.
+**
+** If an error has already occurred as part of an sqlite3rbu_step()
+** or sqlite3rbu_open() call, or if one occurs within this function, an
+** SQLite error code is returned. Additionally, *pzErrmsg may be set to
+** point to a buffer containing a utf-8 formatted English language error
+** message. It is the responsibility of the caller to eventually free any
+** such buffer using sqlite3_free().
+**
+** Otherwise, if no error occurs, this function returns SQLITE_OK if the
+** update has been partially applied, or SQLITE_DONE if it has been
+** completely applied.
+*/
+SQLITE_API int SQLITE_STDCALL sqlite3rbu_close(sqlite3rbu *pRbu, char **pzErrmsg);
+
+/*
+** Return the total number of key-value operations (inserts, deletes or
+** updates) that have been performed on the target database since the
+** current RBU update was started.
+*/
+SQLITE_API sqlite3_int64 SQLITE_STDCALL sqlite3rbu_progress(sqlite3rbu *pRbu);
+
+/*
+** Create an RBU VFS named zName that accesses the underlying file-system
+** via existing VFS zParent. Or, if the zParent parameter is passed NULL,
+** then the new RBU VFS uses the default system VFS to access the file-system.
+** The new object is registered as a non-default VFS with SQLite before
+** returning.
+**
+** Part of the RBU implementation uses a custom VFS object. Usually, this
+** object is created and deleted automatically by RBU.
+**
+** The exception is for applications that also use zipvfs. In this case,
+** the custom VFS must be explicitly created by the user before the RBU
+** handle is opened. The RBU VFS should be installed so that the zipvfs
+** VFS uses the RBU VFS, which in turn uses any other VFS layers in use
+** (for example multiplexor) to access the file-system. For example,
+** to assemble an RBU enabled VFS stack that uses both zipvfs and
+** multiplexor (error checking omitted):
+**
+** // Create a VFS named "multiplex" (not the default).
+** sqlite3_multiplex_initialize(0, 0);
+**
+** // Create an rbu VFS named "rbu" that uses multiplexor. If the
+** // second argument were replaced with NULL, the "rbu" VFS would
+** // access the file-system via the system default VFS, bypassing the
+** // multiplexor.
+** sqlite3rbu_create_vfs("rbu", "multiplex");
+**
+** // Create a zipvfs VFS named "zipvfs" that uses rbu.
+** zipvfs_create_vfs_v3("zipvfs", "rbu", 0, xCompressorAlgorithmDetector);
+**
+** // Make zipvfs the default VFS.
+** sqlite3_vfs_register(sqlite3_vfs_find("zipvfs"), 1);
+**
+** Because the default VFS created above includes a RBU functionality, it
+** may be used by RBU clients. Attempting to use RBU with a zipvfs VFS stack
+** that does not include the RBU layer results in an error.
+**
+** The overhead of adding the "rbu" VFS to the system is negligible for
+** non-RBU users. There is no harm in an application accessing the
+** file-system via "rbu" all the time, even if it only uses RBU functionality
+** occasionally.
+*/
+SQLITE_API int SQLITE_STDCALL sqlite3rbu_create_vfs(const char *zName, const char *zParent);
+
+/*
+** Deregister and destroy an RBU vfs created by an earlier call to
+** sqlite3rbu_create_vfs().
+**
+** VFS objects are not reference counted. If a VFS object is destroyed
+** before all database handles that use it have been closed, the results
+** are undefined.
+*/
+SQLITE_API void SQLITE_STDCALL sqlite3rbu_destroy_vfs(const char *zName);
+
+#if 0
+} /* end of the 'extern "C"' block */
+#endif
+
+#endif /* _SQLITE3RBU_H */
+
+/************** End of sqlite3rbu.h ******************************************/
+/************** Continuing where we left off in sqlite3rbu.c *****************/
+
+#if defined(_WIN32_WCE)
+/* #include "windows.h" */
+#endif
+
+/* Maximum number of prepared UPDATE statements held by this module */
+#define SQLITE_RBU_UPDATE_CACHESIZE 16
+
+/*
+** Swap two objects of type TYPE.
+*/
+#if !defined(SQLITE_AMALGAMATION)
+# define SWAP(TYPE,A,B) {TYPE t=A; A=B; B=t;}
+#endif
+
+/*
+** The rbu_state table is used to save the state of a partially applied
+** update so that it can be resumed later. The table consists of integer
+** keys mapped to values as follows:
+**
+** RBU_STATE_STAGE:
+** May be set to integer values 1, 2, 4 or 5. As follows:
+** 1: the *-rbu file is currently under construction.
+** 2: the *-rbu file has been constructed, but not yet moved
+** to the *-wal path.
+** 4: the checkpoint is underway.
+** 5: the rbu update has been checkpointed.
+**
+** RBU_STATE_TBL:
+** Only valid if STAGE==1. The target database name of the table
+** currently being written.
+**
+** RBU_STATE_IDX:
+** Only valid if STAGE==1. The target database name of the index
+** currently being written, or NULL if the main table is currently being
+** updated.
+**
+** RBU_STATE_ROW:
+** Only valid if STAGE==1. Number of rows already processed for the current
+** table/index.
+**
+** RBU_STATE_PROGRESS:
+** Trbul number of sqlite3rbu_step() calls made so far as part of this
+** rbu update.
+**
+** RBU_STATE_CKPT:
+** Valid if STAGE==4. The 64-bit checksum associated with the wal-index
+** header created by recovering the *-wal file. This is used to detect
+** cases when another client appends frames to the *-wal file in the
+** middle of an incremental checkpoint (an incremental checkpoint cannot
+** be continued if this happens).
+**
+** RBU_STATE_COOKIE:
+** Valid if STAGE==1. The current change-counter cookie value in the
+** target db file.
+**
+** RBU_STATE_OALSZ:
+** Valid if STAGE==1. The size in bytes of the *-oal file.
+*/
+#define RBU_STATE_STAGE 1
+#define RBU_STATE_TBL 2
+#define RBU_STATE_IDX 3
+#define RBU_STATE_ROW 4
+#define RBU_STATE_PROGRESS 5
+#define RBU_STATE_CKPT 6
+#define RBU_STATE_COOKIE 7
+#define RBU_STATE_OALSZ 8
+
+#define RBU_STAGE_OAL 1
+#define RBU_STAGE_MOVE 2
+#define RBU_STAGE_CAPTURE 3
+#define RBU_STAGE_CKPT 4
+#define RBU_STAGE_DONE 5
+
+
+#define RBU_CREATE_STATE \
+ "CREATE TABLE IF NOT EXISTS %s.rbu_state(k INTEGER PRIMARY KEY, v)"
+
+typedef struct RbuFrame RbuFrame;
+typedef struct RbuObjIter RbuObjIter;
+typedef struct RbuState RbuState;
+typedef struct rbu_vfs rbu_vfs;
+typedef struct rbu_file rbu_file;
+typedef struct RbuUpdateStmt RbuUpdateStmt;
+
+#if !defined(SQLITE_AMALGAMATION)
+typedef unsigned int u32;
+typedef unsigned char u8;
+typedef sqlite3_int64 i64;
+#endif
+
+/*
+** These values must match the values defined in wal.c for the equivalent
+** locks. These are not magic numbers as they are part of the SQLite file
+** format.
+*/
+#define WAL_LOCK_WRITE 0
+#define WAL_LOCK_CKPT 1
+#define WAL_LOCK_READ0 3
+
+/*
+** A structure to store values read from the rbu_state table in memory.
+*/
+struct RbuState {
+ int eStage;
+ char *zTbl;
+ char *zIdx;
+ i64 iWalCksum;
+ int nRow;
+ i64 nProgress;
+ u32 iCookie;
+ i64 iOalSz;
+};
+
+struct RbuUpdateStmt {
+ char *zMask; /* Copy of update mask used with pUpdate */
+ sqlite3_stmt *pUpdate; /* Last update statement (or NULL) */
+ RbuUpdateStmt *pNext;
+};
+
+/*
+** An iterator of this type is used to iterate through all objects in
+** the target database that require updating. For each such table, the
+** iterator visits, in order:
+**
+** * the table itself,
+** * each index of the table (zero or more points to visit), and
+** * a special "cleanup table" state.
+**
+** abIndexed:
+** If the table has no indexes on it, abIndexed is set to NULL. Otherwise,
+** it points to an array of flags nTblCol elements in size. The flag is
+** set for each column that is either a part of the PK or a part of an
+** index. Or clear otherwise.
+**
+*/
+struct RbuObjIter {
+ sqlite3_stmt *pTblIter; /* Iterate through tables */
+ sqlite3_stmt *pIdxIter; /* Index iterator */
+ int nTblCol; /* Size of azTblCol[] array */
+ char **azTblCol; /* Array of unquoted target column names */
+ char **azTblType; /* Array of target column types */
+ int *aiSrcOrder; /* src table col -> target table col */
+ u8 *abTblPk; /* Array of flags, set on target PK columns */
+ u8 *abNotNull; /* Array of flags, set on NOT NULL columns */
+ u8 *abIndexed; /* Array of flags, set on indexed & PK cols */
+ int eType; /* Table type - an RBU_PK_XXX value */
+
+ /* Output variables. zTbl==0 implies EOF. */
+ int bCleanup; /* True in "cleanup" state */
+ const char *zTbl; /* Name of target db table */
+ const char *zDataTbl; /* Name of rbu db table (or null) */
+ const char *zIdx; /* Name of target db index (or null) */
+ int iTnum; /* Root page of current object */
+ int iPkTnum; /* If eType==EXTERNAL, root of PK index */
+ int bUnique; /* Current index is unique */
+
+ /* Statements created by rbuObjIterPrepareAll() */
+ int nCol; /* Number of columns in current object */
+ sqlite3_stmt *pSelect; /* Source data */
+ sqlite3_stmt *pInsert; /* Statement for INSERT operations */
+ sqlite3_stmt *pDelete; /* Statement for DELETE ops */
+ sqlite3_stmt *pTmpInsert; /* Insert into rbu_tmp_$zDataTbl */
+
+ /* Last UPDATE used (for PK b-tree updates only), or NULL. */
+ RbuUpdateStmt *pRbuUpdate;
+};
+
+/*
+** Values for RbuObjIter.eType
+**
+** 0: Table does not exist (error)
+** 1: Table has an implicit rowid.
+** 2: Table has an explicit IPK column.
+** 3: Table has an external PK index.
+** 4: Table is WITHOUT ROWID.
+** 5: Table is a virtual table.
+*/
+#define RBU_PK_NOTABLE 0
+#define RBU_PK_NONE 1
+#define RBU_PK_IPK 2
+#define RBU_PK_EXTERNAL 3
+#define RBU_PK_WITHOUT_ROWID 4
+#define RBU_PK_VTAB 5
+
+
+/*
+** Within the RBU_STAGE_OAL stage, each call to sqlite3rbu_step() performs
+** one of the following operations.
+*/
+#define RBU_INSERT 1 /* Insert on a main table b-tree */
+#define RBU_DELETE 2 /* Delete a row from a main table b-tree */
+#define RBU_IDX_DELETE 3 /* Delete a row from an aux. index b-tree */
+#define RBU_IDX_INSERT 4 /* Insert on an aux. index b-tree */
+#define RBU_UPDATE 5 /* Update a row in a main table b-tree */
+
+
+/*
+** A single step of an incremental checkpoint - frame iWalFrame of the wal
+** file should be copied to page iDbPage of the database file.
+*/
+struct RbuFrame {
+ u32 iDbPage;
+ u32 iWalFrame;
+};
+
+/*
+** RBU handle.
+*/
+struct sqlite3rbu {
+ int eStage; /* Value of RBU_STATE_STAGE field */
+ sqlite3 *dbMain; /* target database handle */
+ sqlite3 *dbRbu; /* rbu database handle */
+ char *zTarget; /* Path to target db */
+ char *zRbu; /* Path to rbu db */
+ char *zState; /* Path to state db (or NULL if zRbu) */
+ char zStateDb[5]; /* Db name for state ("stat" or "main") */
+ int rc; /* Value returned by last rbu_step() call */
+ char *zErrmsg; /* Error message if rc!=SQLITE_OK */
+ int nStep; /* Rows processed for current object */
+ int nProgress; /* Rows processed for all objects */
+ RbuObjIter objiter; /* Iterator for skipping through tbl/idx */
+ const char *zVfsName; /* Name of automatically created rbu vfs */
+ rbu_file *pTargetFd; /* File handle open on target db */
+ i64 iOalSz;
+
+ /* The following state variables are used as part of the incremental
+ ** checkpoint stage (eStage==RBU_STAGE_CKPT). See comments surrounding
+ ** function rbuSetupCheckpoint() for details. */
+ u32 iMaxFrame; /* Largest iWalFrame value in aFrame[] */
+ u32 mLock;
+ int nFrame; /* Entries in aFrame[] array */
+ int nFrameAlloc; /* Allocated size of aFrame[] array */
+ RbuFrame *aFrame;
+ int pgsz;
+ u8 *aBuf;
+ i64 iWalCksum;
+};
+
+/*
+** An rbu VFS is implemented using an instance of this structure.
+*/
+struct rbu_vfs {
+ sqlite3_vfs base; /* rbu VFS shim methods */
+ sqlite3_vfs *pRealVfs; /* Underlying VFS */
+ sqlite3_mutex *mutex; /* Mutex to protect pMain */
+ rbu_file *pMain; /* Linked list of main db files */
+};
+
+/*
+** Each file opened by an rbu VFS is represented by an instance of
+** the following structure.
+*/
+struct rbu_file {
+ sqlite3_file base; /* sqlite3_file methods */
+ sqlite3_file *pReal; /* Underlying file handle */
+ rbu_vfs *pRbuVfs; /* Pointer to the rbu_vfs object */
+ sqlite3rbu *pRbu; /* Pointer to rbu object (rbu target only) */
+
+ int openFlags; /* Flags this file was opened with */
+ u32 iCookie; /* Cookie value for main db files */
+ u8 iWriteVer; /* "write-version" value for main db files */
+
+ int nShm; /* Number of entries in apShm[] array */
+ char **apShm; /* Array of mmap'd *-shm regions */
+ char *zDel; /* Delete this when closing file */
+
+ const char *zWal; /* Wal filename for this main db file */
+ rbu_file *pWalFd; /* Wal file descriptor for this main db */
+ rbu_file *pMainNext; /* Next MAIN_DB file */
+};
+
+
+/*************************************************************************
+** The following three functions, found below:
+**
+** rbuDeltaGetInt()
+** rbuDeltaChecksum()
+** rbuDeltaApply()
+**
+** are lifted from the fossil source code (http://fossil-scm.org). They
+** are used to implement the scalar SQL function rbu_fossil_delta().
+*/
+
+/*
+** Read bytes from *pz and convert them into a positive integer. When
+** finished, leave *pz pointing to the first character past the end of
+** the integer. The *pLen parameter holds the length of the string
+** in *pz and is decremented once for each character in the integer.
+*/
+static unsigned int rbuDeltaGetInt(const char **pz, int *pLen){
+ static const signed char zValue[] = {
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -1, -1, -1, -1, -1, -1,
+ -1, 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, -1, -1, -1, -1, 36,
+ -1, 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, -1, -1, -1, 63, -1,
+ };
+ unsigned int v = 0;
+ int c;
+ unsigned char *z = (unsigned char*)*pz;
+ unsigned char *zStart = z;
+ while( (c = zValue[0x7f&*(z++)])>=0 ){
+ v = (v<<6) + c;
+ }
+ z--;
+ *pLen -= z - zStart;
+ *pz = (char*)z;
+ return v;
+}
+
+/*
+** Compute a 32-bit checksum on the N-byte buffer. Return the result.
+*/
+static unsigned int rbuDeltaChecksum(const char *zIn, size_t N){
+ const unsigned char *z = (const unsigned char *)zIn;
+ unsigned sum0 = 0;
+ unsigned sum1 = 0;
+ unsigned sum2 = 0;
+ unsigned sum3 = 0;
+ while(N >= 16){
+ sum0 += ((unsigned)z[0] + z[4] + z[8] + z[12]);
+ sum1 += ((unsigned)z[1] + z[5] + z[9] + z[13]);
+ sum2 += ((unsigned)z[2] + z[6] + z[10]+ z[14]);
+ sum3 += ((unsigned)z[3] + z[7] + z[11]+ z[15]);
+ z += 16;
+ N -= 16;
+ }
+ while(N >= 4){
+ sum0 += z[0];
+ sum1 += z[1];
+ sum2 += z[2];
+ sum3 += z[3];
+ z += 4;
+ N -= 4;
+ }
+ sum3 += (sum2 << 8) + (sum1 << 16) + (sum0 << 24);
+ switch(N){
+ case 3: sum3 += (z[2] << 8);
+ case 2: sum3 += (z[1] << 16);
+ case 1: sum3 += (z[0] << 24);
+ default: ;
+ }
+ return sum3;
+}
+
+/*
+** Apply a delta.
+**
+** The output buffer should be big enough to hold the whole output
+** file and a NUL terminator at the end. The delta_output_size()
+** routine will determine this size for you.
+**
+** The delta string should be null-terminated. But the delta string
+** may contain embedded NUL characters (if the input and output are
+** binary files) so we also have to pass in the length of the delta in
+** the lenDelta parameter.
+**
+** This function returns the size of the output file in bytes (excluding
+** the final NUL terminator character). Except, if the delta string is
+** malformed or intended for use with a source file other than zSrc,
+** then this routine returns -1.
+**
+** Refer to the delta_create() documentation above for a description
+** of the delta file format.
+*/
+static int rbuDeltaApply(
+ const char *zSrc, /* The source or pattern file */
+ int lenSrc, /* Length of the source file */
+ const char *zDelta, /* Delta to apply to the pattern */
+ int lenDelta, /* Length of the delta */
+ char *zOut /* Write the output into this preallocated buffer */
+){
+ unsigned int limit;
+ unsigned int total = 0;
+#ifndef FOSSIL_OMIT_DELTA_CKSUM_TEST
+ char *zOrigOut = zOut;
+#endif
+
+ limit = rbuDeltaGetInt(&zDelta, &lenDelta);
+ if( *zDelta!='\n' ){
+ /* ERROR: size integer not terminated by "\n" */
+ return -1;
+ }
+ zDelta++; lenDelta--;
+ while( *zDelta && lenDelta>0 ){
+ unsigned int cnt, ofst;
+ cnt = rbuDeltaGetInt(&zDelta, &lenDelta);
+ switch( zDelta[0] ){
+ case '@': {
+ zDelta++; lenDelta--;
+ ofst = rbuDeltaGetInt(&zDelta, &lenDelta);
+ if( lenDelta>0 && zDelta[0]!=',' ){
+ /* ERROR: copy command not terminated by ',' */
+ return -1;
+ }
+ zDelta++; lenDelta--;
+ total += cnt;
+ if( total>limit ){
+ /* ERROR: copy exceeds output file size */
+ return -1;
+ }
+ if( (int)(ofst+cnt) > lenSrc ){
+ /* ERROR: copy extends past end of input */
+ return -1;
+ }
+ memcpy(zOut, &zSrc[ofst], cnt);
+ zOut += cnt;
+ break;
+ }
+ case ':': {
+ zDelta++; lenDelta--;
+ total += cnt;
+ if( total>limit ){
+ /* ERROR: insert command gives an output larger than predicted */
+ return -1;
+ }
+ if( (int)cnt>lenDelta ){
+ /* ERROR: insert count exceeds size of delta */
+ return -1;
+ }
+ memcpy(zOut, zDelta, cnt);
+ zOut += cnt;
+ zDelta += cnt;
+ lenDelta -= cnt;
+ break;
+ }
+ case ';': {
+ zDelta++; lenDelta--;
+ zOut[0] = 0;
+#ifndef FOSSIL_OMIT_DELTA_CKSUM_TEST
+ if( cnt!=rbuDeltaChecksum(zOrigOut, total) ){
+ /* ERROR: bad checksum */
+ return -1;
+ }
+#endif
+ if( total!=limit ){
+ /* ERROR: generated size does not match predicted size */
+ return -1;
+ }
+ return total;
+ }
+ default: {
+ /* ERROR: unknown delta operator */
+ return -1;
+ }
+ }
+ }
+ /* ERROR: unterminated delta */
+ return -1;
+}
+
+static int rbuDeltaOutputSize(const char *zDelta, int lenDelta){
+ int size;
+ size = rbuDeltaGetInt(&zDelta, &lenDelta);
+ if( *zDelta!='\n' ){
+ /* ERROR: size integer not terminated by "\n" */
+ return -1;
+ }
+ return size;
+}
+
+/*
+** End of code taken from fossil.
+*************************************************************************/
+
+/*
+** Implementation of SQL scalar function rbu_fossil_delta().
+**
+** This function applies a fossil delta patch to a blob. Exactly two
+** arguments must be passed to this function. The first is the blob to
+** patch and the second the patch to apply. If no error occurs, this
+** function returns the patched blob.
+*/
+static void rbuFossilDeltaFunc(
+ sqlite3_context *context,
+ int argc,
+ sqlite3_value **argv
+){
+ const char *aDelta;
+ int nDelta;
+ const char *aOrig;
+ int nOrig;
+
+ int nOut;
+ int nOut2;
+ char *aOut;
+
+ assert( argc==2 );
+
+ nOrig = sqlite3_value_bytes(argv[0]);
+ aOrig = (const char*)sqlite3_value_blob(argv[0]);
+ nDelta = sqlite3_value_bytes(argv[1]);
+ aDelta = (const char*)sqlite3_value_blob(argv[1]);
+
+ /* Figure out the size of the output */
+ nOut = rbuDeltaOutputSize(aDelta, nDelta);
+ if( nOut<0 ){
+ sqlite3_result_error(context, "corrupt fossil delta", -1);
+ return;
+ }
+
+ aOut = sqlite3_malloc(nOut+1);
+ if( aOut==0 ){
+ sqlite3_result_error_nomem(context);
+ }else{
+ nOut2 = rbuDeltaApply(aOrig, nOrig, aDelta, nDelta, aOut);
+ if( nOut2!=nOut ){
+ sqlite3_result_error(context, "corrupt fossil delta", -1);
+ }else{
+ sqlite3_result_blob(context, aOut, nOut, sqlite3_free);
+ }
+ }
+}
+
+
+/*
+** Prepare the SQL statement in buffer zSql against database handle db.
+** If successful, set *ppStmt to point to the new statement and return
+** SQLITE_OK.
+**
+** Otherwise, if an error does occur, set *ppStmt to NULL and return
+** an SQLite error code. Additionally, set output variable *pzErrmsg to
+** point to a buffer containing an error message. It is the responsibility
+** of the caller to (eventually) free this buffer using sqlite3_free().
+*/
+static int prepareAndCollectError(
+ sqlite3 *db,
+ sqlite3_stmt **ppStmt,
+ char **pzErrmsg,
+ const char *zSql
+){
+ int rc = sqlite3_prepare_v2(db, zSql, -1, ppStmt, 0);
+ if( rc!=SQLITE_OK ){
+ *pzErrmsg = sqlite3_mprintf("%s", sqlite3_errmsg(db));
+ *ppStmt = 0;
+ }
+ return rc;
+}
+
+/*
+** Reset the SQL statement passed as the first argument. Return a copy
+** of the value returned by sqlite3_reset().
+**
+** If an error has occurred, then set *pzErrmsg to point to a buffer
+** containing an error message. It is the responsibility of the caller
+** to eventually free this buffer using sqlite3_free().
+*/
+static int resetAndCollectError(sqlite3_stmt *pStmt, char **pzErrmsg){
+ int rc = sqlite3_reset(pStmt);
+ if( rc!=SQLITE_OK ){
+ *pzErrmsg = sqlite3_mprintf("%s", sqlite3_errmsg(sqlite3_db_handle(pStmt)));
+ }
+ return rc;
+}
+
+/*
+** Unless it is NULL, argument zSql points to a buffer allocated using
+** sqlite3_malloc containing an SQL statement. This function prepares the SQL
+** statement against database db and frees the buffer. If statement
+** compilation is successful, *ppStmt is set to point to the new statement
+** handle and SQLITE_OK is returned.
+**
+** Otherwise, if an error occurs, *ppStmt is set to NULL and an error code
+** returned. In this case, *pzErrmsg may also be set to point to an error
+** message. It is the responsibility of the caller to free this error message
+** buffer using sqlite3_free().
+**
+** If argument zSql is NULL, this function assumes that an OOM has occurred.
+** In this case SQLITE_NOMEM is returned and *ppStmt set to NULL.
+*/
+static int prepareFreeAndCollectError(
+ sqlite3 *db,
+ sqlite3_stmt **ppStmt,
+ char **pzErrmsg,
+ char *zSql
+){
+ int rc;
+ assert( *pzErrmsg==0 );
+ if( zSql==0 ){
+ rc = SQLITE_NOMEM;
+ *ppStmt = 0;
+ }else{
+ rc = prepareAndCollectError(db, ppStmt, pzErrmsg, zSql);
+ sqlite3_free(zSql);
+ }
+ return rc;
+}
+
+/*
+** Free the RbuObjIter.azTblCol[] and RbuObjIter.abTblPk[] arrays allocated
+** by an earlier call to rbuObjIterCacheTableInfo().
+*/
+static void rbuObjIterFreeCols(RbuObjIter *pIter){
+ int i;
+ for(i=0; i<pIter->nTblCol; i++){
+ sqlite3_free(pIter->azTblCol[i]);
+ sqlite3_free(pIter->azTblType[i]);
+ }
+ sqlite3_free(pIter->azTblCol);
+ pIter->azTblCol = 0;
+ pIter->azTblType = 0;
+ pIter->aiSrcOrder = 0;
+ pIter->abTblPk = 0;
+ pIter->abNotNull = 0;
+ pIter->nTblCol = 0;
+ pIter->eType = 0; /* Invalid value */
+}
+
+/*
+** Finalize all statements and free all allocations that are specific to
+** the current object (table/index pair).
+*/
+static void rbuObjIterClearStatements(RbuObjIter *pIter){
+ RbuUpdateStmt *pUp;
+
+ sqlite3_finalize(pIter->pSelect);
+ sqlite3_finalize(pIter->pInsert);
+ sqlite3_finalize(pIter->pDelete);
+ sqlite3_finalize(pIter->pTmpInsert);
+ pUp = pIter->pRbuUpdate;
+ while( pUp ){
+ RbuUpdateStmt *pTmp = pUp->pNext;
+ sqlite3_finalize(pUp->pUpdate);
+ sqlite3_free(pUp);
+ pUp = pTmp;
+ }
+
+ pIter->pSelect = 0;
+ pIter->pInsert = 0;
+ pIter->pDelete = 0;
+ pIter->pRbuUpdate = 0;
+ pIter->pTmpInsert = 0;
+ pIter->nCol = 0;
+}
+
+/*
+** Clean up any resources allocated as part of the iterator object passed
+** as the only argument.
+*/
+static void rbuObjIterFinalize(RbuObjIter *pIter){
+ rbuObjIterClearStatements(pIter);
+ sqlite3_finalize(pIter->pTblIter);
+ sqlite3_finalize(pIter->pIdxIter);
+ rbuObjIterFreeCols(pIter);
+ memset(pIter, 0, sizeof(RbuObjIter));
+}
+
+/*
+** Advance the iterator to the next position.
+**
+** If no error occurs, SQLITE_OK is returned and the iterator is left
+** pointing to the next entry. Otherwise, an error code and message is
+** left in the RBU handle passed as the first argument. A copy of the
+** error code is returned.
+*/
+static int rbuObjIterNext(sqlite3rbu *p, RbuObjIter *pIter){
+ int rc = p->rc;
+ if( rc==SQLITE_OK ){
+
+ /* Free any SQLite statements used while processing the previous object */
+ rbuObjIterClearStatements(pIter);
+ if( pIter->zIdx==0 ){
+ rc = sqlite3_exec(p->dbMain,
+ "DROP TRIGGER IF EXISTS temp.rbu_insert_tr;"
+ "DROP TRIGGER IF EXISTS temp.rbu_update1_tr;"
+ "DROP TRIGGER IF EXISTS temp.rbu_update2_tr;"
+ "DROP TRIGGER IF EXISTS temp.rbu_delete_tr;"
+ , 0, 0, &p->zErrmsg
+ );
+ }
+
+ if( rc==SQLITE_OK ){
+ if( pIter->bCleanup ){
+ rbuObjIterFreeCols(pIter);
+ pIter->bCleanup = 0;
+ rc = sqlite3_step(pIter->pTblIter);
+ if( rc!=SQLITE_ROW ){
+ rc = resetAndCollectError(pIter->pTblIter, &p->zErrmsg);
+ pIter->zTbl = 0;
+ }else{
+ pIter->zTbl = (const char*)sqlite3_column_text(pIter->pTblIter, 0);
+ pIter->zDataTbl = (const char*)sqlite3_column_text(pIter->pTblIter,1);
+ rc = (pIter->zDataTbl && pIter->zTbl) ? SQLITE_OK : SQLITE_NOMEM;
+ }
+ }else{
+ if( pIter->zIdx==0 ){
+ sqlite3_stmt *pIdx = pIter->pIdxIter;
+ rc = sqlite3_bind_text(pIdx, 1, pIter->zTbl, -1, SQLITE_STATIC);
+ }
+ if( rc==SQLITE_OK ){
+ rc = sqlite3_step(pIter->pIdxIter);
+ if( rc!=SQLITE_ROW ){
+ rc = resetAndCollectError(pIter->pIdxIter, &p->zErrmsg);
+ pIter->bCleanup = 1;
+ pIter->zIdx = 0;
+ }else{
+ pIter->zIdx = (const char*)sqlite3_column_text(pIter->pIdxIter, 0);
+ pIter->iTnum = sqlite3_column_int(pIter->pIdxIter, 1);
+ pIter->bUnique = sqlite3_column_int(pIter->pIdxIter, 2);
+ rc = pIter->zIdx ? SQLITE_OK : SQLITE_NOMEM;
+ }
+ }
+ }
+ }
+ }
+
+ if( rc!=SQLITE_OK ){
+ rbuObjIterFinalize(pIter);
+ p->rc = rc;
+ }
+ return rc;
+}
+
+
+/*
+** The implementation of the rbu_target_name() SQL function. This function
+** accepts one argument - the name of a table in the RBU database. If the
+** table name matches the pattern:
+**
+** data[0-9]_<name>
+**
+** where <name> is any sequence of 1 or more characters, <name> is returned.
+** Otherwise, if the only argument does not match the above pattern, an SQL
+** NULL is returned.
+**
+** "data_t1" -> "t1"
+** "data0123_t2" -> "t2"
+** "dataAB_t3" -> NULL
+*/
+static void rbuTargetNameFunc(
+ sqlite3_context *context,
+ int argc,
+ sqlite3_value **argv
+){
+ const char *zIn;
+ assert( argc==1 );
+
+ zIn = (const char*)sqlite3_value_text(argv[0]);
+ if( zIn && strlen(zIn)>4 && memcmp("data", zIn, 4)==0 ){
+ int i;
+ for(i=4; zIn[i]>='0' && zIn[i]<='9'; i++);
+ if( zIn[i]=='_' && zIn[i+1] ){
+ sqlite3_result_text(context, &zIn[i+1], -1, SQLITE_STATIC);
+ }
+ }
+}
+
+/*
+** Initialize the iterator structure passed as the second argument.
+**
+** If no error occurs, SQLITE_OK is returned and the iterator is left
+** pointing to the first entry. Otherwise, an error code and message is
+** left in the RBU handle passed as the first argument. A copy of the
+** error code is returned.
+*/
+static int rbuObjIterFirst(sqlite3rbu *p, RbuObjIter *pIter){
+ int rc;
+ memset(pIter, 0, sizeof(RbuObjIter));
+
+ rc = prepareAndCollectError(p->dbRbu, &pIter->pTblIter, &p->zErrmsg,
+ "SELECT rbu_target_name(name) AS target, name FROM sqlite_master "
+ "WHERE type IN ('table', 'view') AND target IS NOT NULL "
+ "ORDER BY name"
+ );
+
+ if( rc==SQLITE_OK ){
+ rc = prepareAndCollectError(p->dbMain, &pIter->pIdxIter, &p->zErrmsg,
+ "SELECT name, rootpage, sql IS NULL OR substr(8, 6)=='UNIQUE' "
+ " FROM main.sqlite_master "
+ " WHERE type='index' AND tbl_name = ?"
+ );
+ }
+
+ pIter->bCleanup = 1;
+ p->rc = rc;
+ return rbuObjIterNext(p, pIter);
+}
+
+/*
+** This is a wrapper around "sqlite3_mprintf(zFmt, ...)". If an OOM occurs,
+** an error code is stored in the RBU handle passed as the first argument.
+**
+** If an error has already occurred (p->rc is already set to something other
+** than SQLITE_OK), then this function returns NULL without modifying the
+** stored error code. In this case it still calls sqlite3_free() on any
+** printf() parameters associated with %z conversions.
+*/
+static char *rbuMPrintf(sqlite3rbu *p, const char *zFmt, ...){
+ char *zSql = 0;
+ va_list ap;
+ va_start(ap, zFmt);
+ zSql = sqlite3_vmprintf(zFmt, ap);
+ if( p->rc==SQLITE_OK ){
+ if( zSql==0 ) p->rc = SQLITE_NOMEM;
+ }else{
+ sqlite3_free(zSql);
+ zSql = 0;
+ }
+ va_end(ap);
+ return zSql;
+}
+
+/*
+** Argument zFmt is a sqlite3_mprintf() style format string. The trailing
+** arguments are the usual subsitution values. This function performs
+** the printf() style substitutions and executes the result as an SQL
+** statement on the RBU handles database.
+**
+** If an error occurs, an error code and error message is stored in the
+** RBU handle. If an error has already occurred when this function is
+** called, it is a no-op.
+*/
+static int rbuMPrintfExec(sqlite3rbu *p, sqlite3 *db, const char *zFmt, ...){
+ va_list ap;
+ char *zSql;
+ va_start(ap, zFmt);
+ zSql = sqlite3_vmprintf(zFmt, ap);
+ if( p->rc==SQLITE_OK ){
+ if( zSql==0 ){
+ p->rc = SQLITE_NOMEM;
+ }else{
+ p->rc = sqlite3_exec(db, zSql, 0, 0, &p->zErrmsg);
+ }
+ }
+ sqlite3_free(zSql);
+ va_end(ap);
+ return p->rc;
+}
+
+/*
+** Attempt to allocate and return a pointer to a zeroed block of nByte
+** bytes.
+**
+** If an error (i.e. an OOM condition) occurs, return NULL and leave an
+** error code in the rbu handle passed as the first argument. Or, if an
+** error has already occurred when this function is called, return NULL
+** immediately without attempting the allocation or modifying the stored
+** error code.
+*/
+static void *rbuMalloc(sqlite3rbu *p, int nByte){
+ void *pRet = 0;
+ if( p->rc==SQLITE_OK ){
+ assert( nByte>0 );
+ pRet = sqlite3_malloc(nByte);
+ if( pRet==0 ){
+ p->rc = SQLITE_NOMEM;
+ }else{
+ memset(pRet, 0, nByte);
+ }
+ }
+ return pRet;
+}
+
+
+/*
+** Allocate and zero the pIter->azTblCol[] and abTblPk[] arrays so that
+** there is room for at least nCol elements. If an OOM occurs, store an
+** error code in the RBU handle passed as the first argument.
+*/
+static void rbuAllocateIterArrays(sqlite3rbu *p, RbuObjIter *pIter, int nCol){
+ int nByte = (2*sizeof(char*) + sizeof(int) + 3*sizeof(u8)) * nCol;
+ char **azNew;
+
+ azNew = (char**)rbuMalloc(p, nByte);
+ if( azNew ){
+ pIter->azTblCol = azNew;
+ pIter->azTblType = &azNew[nCol];
+ pIter->aiSrcOrder = (int*)&pIter->azTblType[nCol];
+ pIter->abTblPk = (u8*)&pIter->aiSrcOrder[nCol];
+ pIter->abNotNull = (u8*)&pIter->abTblPk[nCol];
+ pIter->abIndexed = (u8*)&pIter->abNotNull[nCol];
+ }
+}
+
+/*
+** The first argument must be a nul-terminated string. This function
+** returns a copy of the string in memory obtained from sqlite3_malloc().
+** It is the responsibility of the caller to eventually free this memory
+** using sqlite3_free().
+**
+** If an OOM condition is encountered when attempting to allocate memory,
+** output variable (*pRc) is set to SQLITE_NOMEM before returning. Otherwise,
+** if the allocation succeeds, (*pRc) is left unchanged.
+*/
+static char *rbuStrndup(const char *zStr, int *pRc){
+ char *zRet = 0;
+
+ assert( *pRc==SQLITE_OK );
+ if( zStr ){
+ int nCopy = strlen(zStr) + 1;
+ zRet = (char*)sqlite3_malloc(nCopy);
+ if( zRet ){
+ memcpy(zRet, zStr, nCopy);
+ }else{
+ *pRc = SQLITE_NOMEM;
+ }
+ }
+
+ return zRet;
+}
+
+/*
+** Finalize the statement passed as the second argument.
+**
+** If the sqlite3_finalize() call indicates that an error occurs, and the
+** rbu handle error code is not already set, set the error code and error
+** message accordingly.
+*/
+static void rbuFinalize(sqlite3rbu *p, sqlite3_stmt *pStmt){
+ sqlite3 *db = sqlite3_db_handle(pStmt);
+ int rc = sqlite3_finalize(pStmt);
+ if( p->rc==SQLITE_OK && rc!=SQLITE_OK ){
+ p->rc = rc;
+ p->zErrmsg = sqlite3_mprintf("%s", sqlite3_errmsg(db));
+ }
+}
+
+/* Determine the type of a table.
+**
+** peType is of type (int*), a pointer to an output parameter of type
+** (int). This call sets the output parameter as follows, depending
+** on the type of the table specified by parameters dbName and zTbl.
+**
+** RBU_PK_NOTABLE: No such table.
+** RBU_PK_NONE: Table has an implicit rowid.
+** RBU_PK_IPK: Table has an explicit IPK column.
+** RBU_PK_EXTERNAL: Table has an external PK index.
+** RBU_PK_WITHOUT_ROWID: Table is WITHOUT ROWID.
+** RBU_PK_VTAB: Table is a virtual table.
+**
+** Argument *piPk is also of type (int*), and also points to an output
+** parameter. Unless the table has an external primary key index
+** (i.e. unless *peType is set to 3), then *piPk is set to zero. Or,
+** if the table does have an external primary key index, then *piPk
+** is set to the root page number of the primary key index before
+** returning.
+**
+** ALGORITHM:
+**
+** if( no entry exists in sqlite_master ){
+** return RBU_PK_NOTABLE
+** }else if( sql for the entry starts with "CREATE VIRTUAL" ){
+** return RBU_PK_VTAB
+** }else if( "PRAGMA index_list()" for the table contains a "pk" index ){
+** if( the index that is the pk exists in sqlite_master ){
+** *piPK = rootpage of that index.
+** return RBU_PK_EXTERNAL
+** }else{
+** return RBU_PK_WITHOUT_ROWID
+** }
+** }else if( "PRAGMA table_info()" lists one or more "pk" columns ){
+** return RBU_PK_IPK
+** }else{
+** return RBU_PK_NONE
+** }
+*/
+static void rbuTableType(
+ sqlite3rbu *p,
+ const char *zTab,
+ int *peType,
+ int *piTnum,
+ int *piPk
+){
+ /*
+ ** 0) SELECT count(*) FROM sqlite_master where name=%Q AND IsVirtual(%Q)
+ ** 1) PRAGMA index_list = ?
+ ** 2) SELECT count(*) FROM sqlite_master where name=%Q
+ ** 3) PRAGMA table_info = ?
+ */
+ sqlite3_stmt *aStmt[4] = {0, 0, 0, 0};
+
+ *peType = RBU_PK_NOTABLE;
+ *piPk = 0;
+
+ assert( p->rc==SQLITE_OK );
+ p->rc = prepareFreeAndCollectError(p->dbMain, &aStmt[0], &p->zErrmsg,
+ sqlite3_mprintf(
+ "SELECT (sql LIKE 'create virtual%%'), rootpage"
+ " FROM sqlite_master"
+ " WHERE name=%Q", zTab
+ ));
+ if( p->rc!=SQLITE_OK || sqlite3_step(aStmt[0])!=SQLITE_ROW ){
+ /* Either an error, or no such table. */
+ goto rbuTableType_end;
+ }
+ if( sqlite3_column_int(aStmt[0], 0) ){
+ *peType = RBU_PK_VTAB; /* virtual table */
+ goto rbuTableType_end;
+ }
+ *piTnum = sqlite3_column_int(aStmt[0], 1);
+
+ p->rc = prepareFreeAndCollectError(p->dbMain, &aStmt[1], &p->zErrmsg,
+ sqlite3_mprintf("PRAGMA index_list=%Q",zTab)
+ );
+ if( p->rc ) goto rbuTableType_end;
+ while( sqlite3_step(aStmt[1])==SQLITE_ROW ){
+ const u8 *zOrig = sqlite3_column_text(aStmt[1], 3);
+ const u8 *zIdx = sqlite3_column_text(aStmt[1], 1);
+ if( zOrig && zIdx && zOrig[0]=='p' ){
+ p->rc = prepareFreeAndCollectError(p->dbMain, &aStmt[2], &p->zErrmsg,
+ sqlite3_mprintf(
+ "SELECT rootpage FROM sqlite_master WHERE name = %Q", zIdx
+ ));
+ if( p->rc==SQLITE_OK ){
+ if( sqlite3_step(aStmt[2])==SQLITE_ROW ){
+ *piPk = sqlite3_column_int(aStmt[2], 0);
+ *peType = RBU_PK_EXTERNAL;
+ }else{
+ *peType = RBU_PK_WITHOUT_ROWID;
+ }
+ }
+ goto rbuTableType_end;
+ }
+ }
+
+ p->rc = prepareFreeAndCollectError(p->dbMain, &aStmt[3], &p->zErrmsg,
+ sqlite3_mprintf("PRAGMA table_info=%Q",zTab)
+ );
+ if( p->rc==SQLITE_OK ){
+ while( sqlite3_step(aStmt[3])==SQLITE_ROW ){
+ if( sqlite3_column_int(aStmt[3],5)>0 ){
+ *peType = RBU_PK_IPK; /* explicit IPK column */
+ goto rbuTableType_end;
+ }
+ }
+ *peType = RBU_PK_NONE;
+ }
+
+rbuTableType_end: {
+ unsigned int i;
+ for(i=0; i<sizeof(aStmt)/sizeof(aStmt[0]); i++){
+ rbuFinalize(p, aStmt[i]);
+ }
+ }
+}
+
+/*
+** This is a helper function for rbuObjIterCacheTableInfo(). It populates
+** the pIter->abIndexed[] array.
+*/
+static void rbuObjIterCacheIndexedCols(sqlite3rbu *p, RbuObjIter *pIter){
+ sqlite3_stmt *pList = 0;
+ int bIndex = 0;
+
+ if( p->rc==SQLITE_OK ){
+ memcpy(pIter->abIndexed, pIter->abTblPk, sizeof(u8)*pIter->nTblCol);
+ p->rc = prepareFreeAndCollectError(p->dbMain, &pList, &p->zErrmsg,
+ sqlite3_mprintf("PRAGMA main.index_list = %Q", pIter->zTbl)
+ );
+ }
+
+ while( p->rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pList) ){
+ const char *zIdx = (const char*)sqlite3_column_text(pList, 1);
+ sqlite3_stmt *pXInfo = 0;
+ if( zIdx==0 ) break;
+ p->rc = prepareFreeAndCollectError(p->dbMain, &pXInfo, &p->zErrmsg,
+ sqlite3_mprintf("PRAGMA main.index_xinfo = %Q", zIdx)
+ );
+ while( p->rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pXInfo) ){
+ int iCid = sqlite3_column_int(pXInfo, 1);
+ if( iCid>=0 ) pIter->abIndexed[iCid] = 1;
+ }
+ rbuFinalize(p, pXInfo);
+ bIndex = 1;
+ }
+
+ rbuFinalize(p, pList);
+ if( bIndex==0 ) pIter->abIndexed = 0;
+}
+
+
+/*
+** If they are not already populated, populate the pIter->azTblCol[],
+** pIter->abTblPk[], pIter->nTblCol and pIter->bRowid variables according to
+** the table (not index) that the iterator currently points to.
+**
+** Return SQLITE_OK if successful, or an SQLite error code otherwise. If
+** an error does occur, an error code and error message are also left in
+** the RBU handle.
+*/
+static int rbuObjIterCacheTableInfo(sqlite3rbu *p, RbuObjIter *pIter){
+ if( pIter->azTblCol==0 ){
+ sqlite3_stmt *pStmt = 0;
+ int nCol = 0;
+ int i; /* for() loop iterator variable */
+ int bRbuRowid = 0; /* If input table has column "rbu_rowid" */
+ int iOrder = 0;
+ int iTnum = 0;
+
+ /* Figure out the type of table this step will deal with. */
+ assert( pIter->eType==0 );
+ rbuTableType(p, pIter->zTbl, &pIter->eType, &iTnum, &pIter->iPkTnum);
+ if( p->rc==SQLITE_OK && pIter->eType==RBU_PK_NOTABLE ){
+ p->rc = SQLITE_ERROR;
+ p->zErrmsg = sqlite3_mprintf("no such table: %s", pIter->zTbl);
+ }
+ if( p->rc ) return p->rc;
+ if( pIter->zIdx==0 ) pIter->iTnum = iTnum;
+
+ assert( pIter->eType==RBU_PK_NONE || pIter->eType==RBU_PK_IPK
+ || pIter->eType==RBU_PK_EXTERNAL || pIter->eType==RBU_PK_WITHOUT_ROWID
+ || pIter->eType==RBU_PK_VTAB
+ );
+
+ /* Populate the azTblCol[] and nTblCol variables based on the columns
+ ** of the input table. Ignore any input table columns that begin with
+ ** "rbu_". */
+ p->rc = prepareFreeAndCollectError(p->dbRbu, &pStmt, &p->zErrmsg,
+ sqlite3_mprintf("SELECT * FROM '%q'", pIter->zDataTbl)
+ );
+ if( p->rc==SQLITE_OK ){
+ nCol = sqlite3_column_count(pStmt);
+ rbuAllocateIterArrays(p, pIter, nCol);
+ }
+ for(i=0; p->rc==SQLITE_OK && i<nCol; i++){
+ const char *zName = (const char*)sqlite3_column_name(pStmt, i);
+ if( sqlite3_strnicmp("rbu_", zName, 4) ){
+ char *zCopy = rbuStrndup(zName, &p->rc);
+ pIter->aiSrcOrder[pIter->nTblCol] = pIter->nTblCol;
+ pIter->azTblCol[pIter->nTblCol++] = zCopy;
+ }
+ else if( 0==sqlite3_stricmp("rbu_rowid", zName) ){
+ bRbuRowid = 1;
+ }
+ }
+ sqlite3_finalize(pStmt);
+ pStmt = 0;
+
+ if( p->rc==SQLITE_OK
+ && bRbuRowid!=(pIter->eType==RBU_PK_VTAB || pIter->eType==RBU_PK_NONE)
+ ){
+ p->rc = SQLITE_ERROR;
+ p->zErrmsg = sqlite3_mprintf(
+ "table %q %s rbu_rowid column", pIter->zDataTbl,
+ (bRbuRowid ? "may not have" : "requires")
+ );
+ }
+
+ /* Check that all non-HIDDEN columns in the destination table are also
+ ** present in the input table. Populate the abTblPk[], azTblType[] and
+ ** aiTblOrder[] arrays at the same time. */
+ if( p->rc==SQLITE_OK ){
+ p->rc = prepareFreeAndCollectError(p->dbMain, &pStmt, &p->zErrmsg,
+ sqlite3_mprintf("PRAGMA table_info(%Q)", pIter->zTbl)
+ );
+ }
+ while( p->rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pStmt) ){
+ const char *zName = (const char*)sqlite3_column_text(pStmt, 1);
+ if( zName==0 ) break; /* An OOM - finalize() below returns S_NOMEM */
+ for(i=iOrder; i<pIter->nTblCol; i++){
+ if( 0==strcmp(zName, pIter->azTblCol[i]) ) break;
+ }
+ if( i==pIter->nTblCol ){
+ p->rc = SQLITE_ERROR;
+ p->zErrmsg = sqlite3_mprintf("column missing from %q: %s",
+ pIter->zDataTbl, zName
+ );
+ }else{
+ int iPk = sqlite3_column_int(pStmt, 5);
+ int bNotNull = sqlite3_column_int(pStmt, 3);
+ const char *zType = (const char*)sqlite3_column_text(pStmt, 2);
+
+ if( i!=iOrder ){
+ SWAP(int, pIter->aiSrcOrder[i], pIter->aiSrcOrder[iOrder]);
+ SWAP(char*, pIter->azTblCol[i], pIter->azTblCol[iOrder]);
+ }
+
+ pIter->azTblType[iOrder] = rbuStrndup(zType, &p->rc);
+ pIter->abTblPk[iOrder] = (iPk!=0);
+ pIter->abNotNull[iOrder] = (u8)bNotNull || (iPk!=0);
+ iOrder++;
+ }
+ }
+
+ rbuFinalize(p, pStmt);
+ rbuObjIterCacheIndexedCols(p, pIter);
+ assert( pIter->eType!=RBU_PK_VTAB || pIter->abIndexed==0 );
+ }
+
+ return p->rc;
+}
+
+/*
+** This function constructs and returns a pointer to a nul-terminated
+** string containing some SQL clause or list based on one or more of the
+** column names currently stored in the pIter->azTblCol[] array.
+*/
+static char *rbuObjIterGetCollist(
+ sqlite3rbu *p, /* RBU object */
+ RbuObjIter *pIter /* Object iterator for column names */
+){
+ char *zList = 0;
+ const char *zSep = "";
+ int i;
+ for(i=0; i<pIter->nTblCol; i++){
+ const char *z = pIter->azTblCol[i];
+ zList = rbuMPrintf(p, "%z%s\"%w\"", zList, zSep, z);
+ zSep = ", ";
+ }
+ return zList;
+}
+
+/*
+** This function is used to create a SELECT list (the list of SQL
+** expressions that follows a SELECT keyword) for a SELECT statement
+** used to read from an data_xxx or rbu_tmp_xxx table while updating the
+** index object currently indicated by the iterator object passed as the
+** second argument. A "PRAGMA index_xinfo = <idxname>" statement is used
+** to obtain the required information.
+**
+** If the index is of the following form:
+**
+** CREATE INDEX i1 ON t1(c, b COLLATE nocase);
+**
+** and "t1" is a table with an explicit INTEGER PRIMARY KEY column
+** "ipk", the returned string is:
+**
+** "`c` COLLATE 'BINARY', `b` COLLATE 'NOCASE', `ipk` COLLATE 'BINARY'"
+**
+** As well as the returned string, three other malloc'd strings are
+** returned via output parameters. As follows:
+**
+** pzImposterCols: ...
+** pzImposterPk: ...
+** pzWhere: ...
+*/
+static char *rbuObjIterGetIndexCols(
+ sqlite3rbu *p, /* RBU object */
+ RbuObjIter *pIter, /* Object iterator for column names */
+ char **pzImposterCols, /* OUT: Columns for imposter table */
+ char **pzImposterPk, /* OUT: Imposter PK clause */
+ char **pzWhere, /* OUT: WHERE clause */
+ int *pnBind /* OUT: Trbul number of columns */
+){
+ int rc = p->rc; /* Error code */
+ int rc2; /* sqlite3_finalize() return code */
+ char *zRet = 0; /* String to return */
+ char *zImpCols = 0; /* String to return via *pzImposterCols */
+ char *zImpPK = 0; /* String to return via *pzImposterPK */
+ char *zWhere = 0; /* String to return via *pzWhere */
+ int nBind = 0; /* Value to return via *pnBind */
+ const char *zCom = ""; /* Set to ", " later on */
+ const char *zAnd = ""; /* Set to " AND " later on */
+ sqlite3_stmt *pXInfo = 0; /* PRAGMA index_xinfo = ? */
+
+ if( rc==SQLITE_OK ){
+ assert( p->zErrmsg==0 );
+ rc = prepareFreeAndCollectError(p->dbMain, &pXInfo, &p->zErrmsg,
+ sqlite3_mprintf("PRAGMA main.index_xinfo = %Q", pIter->zIdx)
+ );
+ }
+
+ while( rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pXInfo) ){
+ int iCid = sqlite3_column_int(pXInfo, 1);
+ int bDesc = sqlite3_column_int(pXInfo, 3);
+ const char *zCollate = (const char*)sqlite3_column_text(pXInfo, 4);
+ const char *zCol;
+ const char *zType;
+
+ if( iCid<0 ){
+ /* An integer primary key. If the table has an explicit IPK, use
+ ** its name. Otherwise, use "rbu_rowid". */
+ if( pIter->eType==RBU_PK_IPK ){
+ int i;
+ for(i=0; pIter->abTblPk[i]==0; i++);
+ assert( i<pIter->nTblCol );
+ zCol = pIter->azTblCol[i];
+ }else{
+ zCol = "rbu_rowid";
+ }
+ zType = "INTEGER";
+ }else{
+ zCol = pIter->azTblCol[iCid];
+ zType = pIter->azTblType[iCid];
+ }
+
+ zRet = sqlite3_mprintf("%z%s\"%w\" COLLATE %Q", zRet, zCom, zCol, zCollate);
+ if( pIter->bUnique==0 || sqlite3_column_int(pXInfo, 5) ){
+ const char *zOrder = (bDesc ? " DESC" : "");
+ zImpPK = sqlite3_mprintf("%z%s\"rbu_imp_%d%w\"%s",
+ zImpPK, zCom, nBind, zCol, zOrder
+ );
+ }
+ zImpCols = sqlite3_mprintf("%z%s\"rbu_imp_%d%w\" %s COLLATE %Q",
+ zImpCols, zCom, nBind, zCol, zType, zCollate
+ );
+ zWhere = sqlite3_mprintf(
+ "%z%s\"rbu_imp_%d%w\" IS ?", zWhere, zAnd, nBind, zCol
+ );
+ if( zRet==0 || zImpPK==0 || zImpCols==0 || zWhere==0 ) rc = SQLITE_NOMEM;
+ zCom = ", ";
+ zAnd = " AND ";
+ nBind++;
+ }
+
+ rc2 = sqlite3_finalize(pXInfo);
+ if( rc==SQLITE_OK ) rc = rc2;
+
+ if( rc!=SQLITE_OK ){
+ sqlite3_free(zRet);
+ sqlite3_free(zImpCols);
+ sqlite3_free(zImpPK);
+ sqlite3_free(zWhere);
+ zRet = 0;
+ zImpCols = 0;
+ zImpPK = 0;
+ zWhere = 0;
+ p->rc = rc;
+ }
+
+ *pzImposterCols = zImpCols;
+ *pzImposterPk = zImpPK;
+ *pzWhere = zWhere;
+ *pnBind = nBind;
+ return zRet;
+}
+
+/*
+** Assuming the current table columns are "a", "b" and "c", and the zObj
+** paramter is passed "old", return a string of the form:
+**
+** "old.a, old.b, old.b"
+**
+** With the column names escaped.
+**
+** For tables with implicit rowids - RBU_PK_EXTERNAL and RBU_PK_NONE, append
+** the text ", old._rowid_" to the returned value.
+*/
+static char *rbuObjIterGetOldlist(
+ sqlite3rbu *p,
+ RbuObjIter *pIter,
+ const char *zObj
+){
+ char *zList = 0;
+ if( p->rc==SQLITE_OK && pIter->abIndexed ){
+ const char *zS = "";
+ int i;
+ for(i=0; i<pIter->nTblCol; i++){
+ if( pIter->abIndexed[i] ){
+ const char *zCol = pIter->azTblCol[i];
+ zList = sqlite3_mprintf("%z%s%s.\"%w\"", zList, zS, zObj, zCol);
+ }else{
+ zList = sqlite3_mprintf("%z%sNULL", zList, zS);
+ }
+ zS = ", ";
+ if( zList==0 ){
+ p->rc = SQLITE_NOMEM;
+ break;
+ }
+ }
+
+ /* For a table with implicit rowids, append "old._rowid_" to the list. */
+ if( pIter->eType==RBU_PK_EXTERNAL || pIter->eType==RBU_PK_NONE ){
+ zList = rbuMPrintf(p, "%z, %s._rowid_", zList, zObj);
+ }
+ }
+ return zList;
+}
+
+/*
+** Return an expression that can be used in a WHERE clause to match the
+** primary key of the current table. For example, if the table is:
+**
+** CREATE TABLE t1(a, b, c, PRIMARY KEY(b, c));
+**
+** Return the string:
+**
+** "b = ?1 AND c = ?2"
+*/
+static char *rbuObjIterGetWhere(
+ sqlite3rbu *p,
+ RbuObjIter *pIter
+){
+ char *zList = 0;
+ if( pIter->eType==RBU_PK_VTAB || pIter->eType==RBU_PK_NONE ){
+ zList = rbuMPrintf(p, "_rowid_ = ?%d", pIter->nTblCol+1);
+ }else if( pIter->eType==RBU_PK_EXTERNAL ){
+ const char *zSep = "";
+ int i;
+ for(i=0; i<pIter->nTblCol; i++){
+ if( pIter->abTblPk[i] ){
+ zList = rbuMPrintf(p, "%z%sc%d=?%d", zList, zSep, i, i+1);
+ zSep = " AND ";
+ }
+ }
+ zList = rbuMPrintf(p,
+ "_rowid_ = (SELECT id FROM rbu_imposter2 WHERE %z)", zList
+ );
+
+ }else{
+ const char *zSep = "";
+ int i;
+ for(i=0; i<pIter->nTblCol; i++){
+ if( pIter->abTblPk[i] ){
+ const char *zCol = pIter->azTblCol[i];
+ zList = rbuMPrintf(p, "%z%s\"%w\"=?%d", zList, zSep, zCol, i+1);
+ zSep = " AND ";
+ }
+ }
+ }
+ return zList;
+}
+
+/*
+** The SELECT statement iterating through the keys for the current object
+** (p->objiter.pSelect) currently points to a valid row. However, there
+** is something wrong with the rbu_control value in the rbu_control value
+** stored in the (p->nCol+1)'th column. Set the error code and error message
+** of the RBU handle to something reflecting this.
+*/
+static void rbuBadControlError(sqlite3rbu *p){
+ p->rc = SQLITE_ERROR;
+ p->zErrmsg = sqlite3_mprintf("invalid rbu_control value");
+}
+
+
+/*
+** Return a nul-terminated string containing the comma separated list of
+** assignments that should be included following the "SET" keyword of
+** an UPDATE statement used to update the table object that the iterator
+** passed as the second argument currently points to if the rbu_control
+** column of the data_xxx table entry is set to zMask.
+**
+** The memory for the returned string is obtained from sqlite3_malloc().
+** It is the responsibility of the caller to eventually free it using
+** sqlite3_free().
+**
+** If an OOM error is encountered when allocating space for the new
+** string, an error code is left in the rbu handle passed as the first
+** argument and NULL is returned. Or, if an error has already occurred
+** when this function is called, NULL is returned immediately, without
+** attempting the allocation or modifying the stored error code.
+*/
+static char *rbuObjIterGetSetlist(
+ sqlite3rbu *p,
+ RbuObjIter *pIter,
+ const char *zMask
+){
+ char *zList = 0;
+ if( p->rc==SQLITE_OK ){
+ int i;
+
+ if( (int)strlen(zMask)!=pIter->nTblCol ){
+ rbuBadControlError(p);
+ }else{
+ const char *zSep = "";
+ for(i=0; i<pIter->nTblCol; i++){
+ char c = zMask[pIter->aiSrcOrder[i]];
+ if( c=='x' ){
+ zList = rbuMPrintf(p, "%z%s\"%w\"=?%d",
+ zList, zSep, pIter->azTblCol[i], i+1
+ );
+ zSep = ", ";
+ }
+ else if( c=='d' ){
+ zList = rbuMPrintf(p, "%z%s\"%w\"=rbu_delta(\"%w\", ?%d)",
+ zList, zSep, pIter->azTblCol[i], pIter->azTblCol[i], i+1
+ );
+ zSep = ", ";
+ }
+ else if( c=='f' ){
+ zList = rbuMPrintf(p, "%z%s\"%w\"=rbu_fossil_delta(\"%w\", ?%d)",
+ zList, zSep, pIter->azTblCol[i], pIter->azTblCol[i], i+1
+ );
+ zSep = ", ";
+ }
+ }
+ }
+ }
+ return zList;
+}
+
+/*
+** Return a nul-terminated string consisting of nByte comma separated
+** "?" expressions. For example, if nByte is 3, return a pointer to
+** a buffer containing the string "?,?,?".
+**
+** The memory for the returned string is obtained from sqlite3_malloc().
+** It is the responsibility of the caller to eventually free it using
+** sqlite3_free().
+**
+** If an OOM error is encountered when allocating space for the new
+** string, an error code is left in the rbu handle passed as the first
+** argument and NULL is returned. Or, if an error has already occurred
+** when this function is called, NULL is returned immediately, without
+** attempting the allocation or modifying the stored error code.
+*/
+static char *rbuObjIterGetBindlist(sqlite3rbu *p, int nBind){
+ char *zRet = 0;
+ int nByte = nBind*2 + 1;
+
+ zRet = (char*)rbuMalloc(p, nByte);
+ if( zRet ){
+ int i;
+ for(i=0; i<nBind; i++){
+ zRet[i*2] = '?';
+ zRet[i*2+1] = (i+1==nBind) ? '\0' : ',';
+ }
+ }
+ return zRet;
+}
+
+/*
+** The iterator currently points to a table (not index) of type
+** RBU_PK_WITHOUT_ROWID. This function creates the PRIMARY KEY
+** declaration for the corresponding imposter table. For example,
+** if the iterator points to a table created as:
+**
+** CREATE TABLE t1(a, b, c, PRIMARY KEY(b, a DESC)) WITHOUT ROWID
+**
+** this function returns:
+**
+** PRIMARY KEY("b", "a" DESC)
+*/
+static char *rbuWithoutRowidPK(sqlite3rbu *p, RbuObjIter *pIter){
+ char *z = 0;
+ assert( pIter->zIdx==0 );
+ if( p->rc==SQLITE_OK ){
+ const char *zSep = "PRIMARY KEY(";
+ sqlite3_stmt *pXList = 0; /* PRAGMA index_list = (pIter->zTbl) */
+ sqlite3_stmt *pXInfo = 0; /* PRAGMA index_xinfo = <pk-index> */
+
+ p->rc = prepareFreeAndCollectError(p->dbMain, &pXList, &p->zErrmsg,
+ sqlite3_mprintf("PRAGMA main.index_list = %Q", pIter->zTbl)
+ );
+ while( p->rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pXList) ){
+ const char *zOrig = (const char*)sqlite3_column_text(pXList,3);
+ if( zOrig && strcmp(zOrig, "pk")==0 ){
+ const char *zIdx = (const char*)sqlite3_column_text(pXList,1);
+ if( zIdx ){
+ p->rc = prepareFreeAndCollectError(p->dbMain, &pXInfo, &p->zErrmsg,
+ sqlite3_mprintf("PRAGMA main.index_xinfo = %Q", zIdx)
+ );
+ }
+ break;
+ }
+ }
+ rbuFinalize(p, pXList);
+
+ while( p->rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pXInfo) ){
+ if( sqlite3_column_int(pXInfo, 5) ){
+ /* int iCid = sqlite3_column_int(pXInfo, 0); */
+ const char *zCol = (const char*)sqlite3_column_text(pXInfo, 2);
+ const char *zDesc = sqlite3_column_int(pXInfo, 3) ? " DESC" : "";
+ z = rbuMPrintf(p, "%z%s\"%w\"%s", z, zSep, zCol, zDesc);
+ zSep = ", ";
+ }
+ }
+ z = rbuMPrintf(p, "%z)", z);
+ rbuFinalize(p, pXInfo);
+ }
+ return z;
+}
+
+/*
+** This function creates the second imposter table used when writing to
+** a table b-tree where the table has an external primary key. If the
+** iterator passed as the second argument does not currently point to
+** a table (not index) with an external primary key, this function is a
+** no-op.
+**
+** Assuming the iterator does point to a table with an external PK, this
+** function creates a WITHOUT ROWID imposter table named "rbu_imposter2"
+** used to access that PK index. For example, if the target table is
+** declared as follows:
+**
+** CREATE TABLE t1(a, b TEXT, c REAL, PRIMARY KEY(b, c));
+**
+** then the imposter table schema is:
+**
+** CREATE TABLE rbu_imposter2(c1 TEXT, c2 REAL, id INTEGER) WITHOUT ROWID;
+**
+*/
+static void rbuCreateImposterTable2(sqlite3rbu *p, RbuObjIter *pIter){
+ if( p->rc==SQLITE_OK && pIter->eType==RBU_PK_EXTERNAL ){
+ int tnum = pIter->iPkTnum; /* Root page of PK index */
+ sqlite3_stmt *pQuery = 0; /* SELECT name ... WHERE rootpage = $tnum */
+ const char *zIdx = 0; /* Name of PK index */
+ sqlite3_stmt *pXInfo = 0; /* PRAGMA main.index_xinfo = $zIdx */
+ const char *zComma = "";
+ char *zCols = 0; /* Used to build up list of table cols */
+ char *zPk = 0; /* Used to build up table PK declaration */
+
+ /* Figure out the name of the primary key index for the current table.
+ ** This is needed for the argument to "PRAGMA index_xinfo". Set
+ ** zIdx to point to a nul-terminated string containing this name. */
+ p->rc = prepareAndCollectError(p->dbMain, &pQuery, &p->zErrmsg,
+ "SELECT name FROM sqlite_master WHERE rootpage = ?"
+ );
+ if( p->rc==SQLITE_OK ){
+ sqlite3_bind_int(pQuery, 1, tnum);
+ if( SQLITE_ROW==sqlite3_step(pQuery) ){
+ zIdx = (const char*)sqlite3_column_text(pQuery, 0);
+ }
+ }
+ if( zIdx ){
+ p->rc = prepareFreeAndCollectError(p->dbMain, &pXInfo, &p->zErrmsg,
+ sqlite3_mprintf("PRAGMA main.index_xinfo = %Q", zIdx)
+ );
+ }
+ rbuFinalize(p, pQuery);
+
+ while( p->rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pXInfo) ){
+ int bKey = sqlite3_column_int(pXInfo, 5);
+ if( bKey ){
+ int iCid = sqlite3_column_int(pXInfo, 1);
+ int bDesc = sqlite3_column_int(pXInfo, 3);
+ const char *zCollate = (const char*)sqlite3_column_text(pXInfo, 4);
+ zCols = rbuMPrintf(p, "%z%sc%d %s COLLATE %s", zCols, zComma,
+ iCid, pIter->azTblType[iCid], zCollate
+ );
+ zPk = rbuMPrintf(p, "%z%sc%d%s", zPk, zComma, iCid, bDesc?" DESC":"");
+ zComma = ", ";
+ }
+ }
+ zCols = rbuMPrintf(p, "%z, id INTEGER", zCols);
+ rbuFinalize(p, pXInfo);
+
+ sqlite3_test_control(SQLITE_TESTCTRL_IMPOSTER, p->dbMain, "main", 1, tnum);
+ rbuMPrintfExec(p, p->dbMain,
+ "CREATE TABLE rbu_imposter2(%z, PRIMARY KEY(%z)) WITHOUT ROWID",
+ zCols, zPk
+ );
+ sqlite3_test_control(SQLITE_TESTCTRL_IMPOSTER, p->dbMain, "main", 0, 0);
+ }
+}
+
+/*
+** If an error has already occurred when this function is called, it
+** immediately returns zero (without doing any work). Or, if an error
+** occurs during the execution of this function, it sets the error code
+** in the sqlite3rbu object indicated by the first argument and returns
+** zero.
+**
+** The iterator passed as the second argument is guaranteed to point to
+** a table (not an index) when this function is called. This function
+** attempts to create any imposter table required to write to the main
+** table b-tree of the table before returning. Non-zero is returned if
+** an imposter table are created, or zero otherwise.
+**
+** An imposter table is required in all cases except RBU_PK_VTAB. Only
+** virtual tables are written to directly. The imposter table has the
+** same schema as the actual target table (less any UNIQUE constraints).
+** More precisely, the "same schema" means the same columns, types,
+** collation sequences. For tables that do not have an external PRIMARY
+** KEY, it also means the same PRIMARY KEY declaration.
+*/
+static void rbuCreateImposterTable(sqlite3rbu *p, RbuObjIter *pIter){
+ if( p->rc==SQLITE_OK && pIter->eType!=RBU_PK_VTAB ){
+ int tnum = pIter->iTnum;
+ const char *zComma = "";
+ char *zSql = 0;
+ int iCol;
+ sqlite3_test_control(SQLITE_TESTCTRL_IMPOSTER, p->dbMain, "main", 0, 1);
+
+ for(iCol=0; p->rc==SQLITE_OK && iCol<pIter->nTblCol; iCol++){
+ const char *zPk = "";
+ const char *zCol = pIter->azTblCol[iCol];
+ const char *zColl = 0;
+
+ p->rc = sqlite3_table_column_metadata(
+ p->dbMain, "main", pIter->zTbl, zCol, 0, &zColl, 0, 0, 0
+ );
+
+ if( pIter->eType==RBU_PK_IPK && pIter->abTblPk[iCol] ){
+ /* If the target table column is an "INTEGER PRIMARY KEY", add
+ ** "PRIMARY KEY" to the imposter table column declaration. */
+ zPk = "PRIMARY KEY ";
+ }
+ zSql = rbuMPrintf(p, "%z%s\"%w\" %s %sCOLLATE %s%s",
+ zSql, zComma, zCol, pIter->azTblType[iCol], zPk, zColl,
+ (pIter->abNotNull[iCol] ? " NOT NULL" : "")
+ );
+ zComma = ", ";
+ }
+
+ if( pIter->eType==RBU_PK_WITHOUT_ROWID ){
+ char *zPk = rbuWithoutRowidPK(p, pIter);
+ if( zPk ){
+ zSql = rbuMPrintf(p, "%z, %z", zSql, zPk);
+ }
+ }
+
+ sqlite3_test_control(SQLITE_TESTCTRL_IMPOSTER, p->dbMain, "main", 1, tnum);
+ rbuMPrintfExec(p, p->dbMain, "CREATE TABLE \"rbu_imp_%w\"(%z)%s",
+ pIter->zTbl, zSql,
+ (pIter->eType==RBU_PK_WITHOUT_ROWID ? " WITHOUT ROWID" : "")
+ );
+ sqlite3_test_control(SQLITE_TESTCTRL_IMPOSTER, p->dbMain, "main", 0, 0);
+ }
+}
+
+/*
+** Prepare a statement used to insert rows into the "rbu_tmp_xxx" table.
+** Specifically a statement of the form:
+**
+** INSERT INTO rbu_tmp_xxx VALUES(?, ?, ? ...);
+**
+** The number of bound variables is equal to the number of columns in
+** the target table, plus one (for the rbu_control column), plus one more
+** (for the rbu_rowid column) if the target table is an implicit IPK or
+** virtual table.
+*/
+static void rbuObjIterPrepareTmpInsert(
+ sqlite3rbu *p,
+ RbuObjIter *pIter,
+ const char *zCollist,
+ const char *zRbuRowid
+){
+ int bRbuRowid = (pIter->eType==RBU_PK_EXTERNAL || pIter->eType==RBU_PK_NONE);
+ char *zBind = rbuObjIterGetBindlist(p, pIter->nTblCol + 1 + bRbuRowid);
+ if( zBind ){
+ assert( pIter->pTmpInsert==0 );
+ p->rc = prepareFreeAndCollectError(
+ p->dbRbu, &pIter->pTmpInsert, &p->zErrmsg, sqlite3_mprintf(
+ "INSERT INTO %s.'rbu_tmp_%q'(rbu_control,%s%s) VALUES(%z)",
+ p->zStateDb, pIter->zDataTbl, zCollist, zRbuRowid, zBind
+ ));
+ }
+}
+
+static void rbuTmpInsertFunc(
+ sqlite3_context *pCtx,
+ int nVal,
+ sqlite3_value **apVal
+){
+ sqlite3rbu *p = sqlite3_user_data(pCtx);
+ int rc = SQLITE_OK;
+ int i;
+
+ for(i=0; rc==SQLITE_OK && i<nVal; i++){
+ rc = sqlite3_bind_value(p->objiter.pTmpInsert, i+1, apVal[i]);
+ }
+ if( rc==SQLITE_OK ){
+ sqlite3_step(p->objiter.pTmpInsert);
+ rc = sqlite3_reset(p->objiter.pTmpInsert);
+ }
+
+ if( rc!=SQLITE_OK ){
+ sqlite3_result_error_code(pCtx, rc);
+ }
+}
+
+/*
+** Ensure that the SQLite statement handles required to update the
+** target database object currently indicated by the iterator passed
+** as the second argument are available.
+*/
+static int rbuObjIterPrepareAll(
+ sqlite3rbu *p,
+ RbuObjIter *pIter,
+ int nOffset /* Add "LIMIT -1 OFFSET $nOffset" to SELECT */
+){
+ assert( pIter->bCleanup==0 );
+ if( pIter->pSelect==0 && rbuObjIterCacheTableInfo(p, pIter)==SQLITE_OK ){
+ const int tnum = pIter->iTnum;
+ char *zCollist = 0; /* List of indexed columns */
+ char **pz = &p->zErrmsg;
+ const char *zIdx = pIter->zIdx;
+ char *zLimit = 0;
+
+ if( nOffset ){
+ zLimit = sqlite3_mprintf(" LIMIT -1 OFFSET %d", nOffset);
+ if( !zLimit ) p->rc = SQLITE_NOMEM;
+ }
+
+ if( zIdx ){
+ const char *zTbl = pIter->zTbl;
+ char *zImposterCols = 0; /* Columns for imposter table */
+ char *zImposterPK = 0; /* Primary key declaration for imposter */
+ char *zWhere = 0; /* WHERE clause on PK columns */
+ char *zBind = 0;
+ int nBind = 0;
+
+ assert( pIter->eType!=RBU_PK_VTAB );
+ zCollist = rbuObjIterGetIndexCols(
+ p, pIter, &zImposterCols, &zImposterPK, &zWhere, &nBind
+ );
+ zBind = rbuObjIterGetBindlist(p, nBind);
+
+ /* Create the imposter table used to write to this index. */
+ sqlite3_test_control(SQLITE_TESTCTRL_IMPOSTER, p->dbMain, "main", 0, 1);
+ sqlite3_test_control(SQLITE_TESTCTRL_IMPOSTER, p->dbMain, "main", 1,tnum);
+ rbuMPrintfExec(p, p->dbMain,
+ "CREATE TABLE \"rbu_imp_%w\"( %s, PRIMARY KEY( %s ) ) WITHOUT ROWID",
+ zTbl, zImposterCols, zImposterPK
+ );
+ sqlite3_test_control(SQLITE_TESTCTRL_IMPOSTER, p->dbMain, "main", 0, 0);
+
+ /* Create the statement to insert index entries */
+ pIter->nCol = nBind;
+ if( p->rc==SQLITE_OK ){
+ p->rc = prepareFreeAndCollectError(
+ p->dbMain, &pIter->pInsert, &p->zErrmsg,
+ sqlite3_mprintf("INSERT INTO \"rbu_imp_%w\" VALUES(%s)", zTbl, zBind)
+ );
+ }
+
+ /* And to delete index entries */
+ if( p->rc==SQLITE_OK ){
+ p->rc = prepareFreeAndCollectError(
+ p->dbMain, &pIter->pDelete, &p->zErrmsg,
+ sqlite3_mprintf("DELETE FROM \"rbu_imp_%w\" WHERE %s", zTbl, zWhere)
+ );
+ }
+
+ /* Create the SELECT statement to read keys in sorted order */
+ if( p->rc==SQLITE_OK ){
+ char *zSql;
+ if( pIter->eType==RBU_PK_EXTERNAL || pIter->eType==RBU_PK_NONE ){
+ zSql = sqlite3_mprintf(
+ "SELECT %s, rbu_control FROM %s.'rbu_tmp_%q' ORDER BY %s%s",
+ zCollist, p->zStateDb, pIter->zDataTbl,
+ zCollist, zLimit
+ );
+ }else{
+ zSql = sqlite3_mprintf(
+ "SELECT %s, rbu_control FROM '%q' "
+ "WHERE typeof(rbu_control)='integer' AND rbu_control!=1 "
+ "UNION ALL "
+ "SELECT %s, rbu_control FROM %s.'rbu_tmp_%q' "
+ "ORDER BY %s%s",
+ zCollist, pIter->zDataTbl,
+ zCollist, p->zStateDb, pIter->zDataTbl,
+ zCollist, zLimit
+ );
+ }
+ p->rc = prepareFreeAndCollectError(p->dbRbu, &pIter->pSelect, pz, zSql);
+ }
+
+ sqlite3_free(zImposterCols);
+ sqlite3_free(zImposterPK);
+ sqlite3_free(zWhere);
+ sqlite3_free(zBind);
+ }else{
+ int bRbuRowid = (pIter->eType==RBU_PK_VTAB || pIter->eType==RBU_PK_NONE);
+ const char *zTbl = pIter->zTbl; /* Table this step applies to */
+ const char *zWrite; /* Imposter table name */
+
+ char *zBindings = rbuObjIterGetBindlist(p, pIter->nTblCol + bRbuRowid);
+ char *zWhere = rbuObjIterGetWhere(p, pIter);
+ char *zOldlist = rbuObjIterGetOldlist(p, pIter, "old");
+ char *zNewlist = rbuObjIterGetOldlist(p, pIter, "new");
+
+ zCollist = rbuObjIterGetCollist(p, pIter);
+ pIter->nCol = pIter->nTblCol;
+
+ /* Create the imposter table or tables (if required). */
+ rbuCreateImposterTable(p, pIter);
+ rbuCreateImposterTable2(p, pIter);
+ zWrite = (pIter->eType==RBU_PK_VTAB ? "" : "rbu_imp_");
+
+ /* Create the INSERT statement to write to the target PK b-tree */
+ if( p->rc==SQLITE_OK ){
+ p->rc = prepareFreeAndCollectError(p->dbMain, &pIter->pInsert, pz,
+ sqlite3_mprintf(
+ "INSERT INTO \"%s%w\"(%s%s) VALUES(%s)",
+ zWrite, zTbl, zCollist, (bRbuRowid ? ", _rowid_" : ""), zBindings
+ )
+ );
+ }
+
+ /* Create the DELETE statement to write to the target PK b-tree */
+ if( p->rc==SQLITE_OK ){
+ p->rc = prepareFreeAndCollectError(p->dbMain, &pIter->pDelete, pz,
+ sqlite3_mprintf(
+ "DELETE FROM \"%s%w\" WHERE %s", zWrite, zTbl, zWhere
+ )
+ );
+ }
+
+ if( pIter->abIndexed ){
+ const char *zRbuRowid = "";
+ if( pIter->eType==RBU_PK_EXTERNAL || pIter->eType==RBU_PK_NONE ){
+ zRbuRowid = ", rbu_rowid";
+ }
+
+ /* Create the rbu_tmp_xxx table and the triggers to populate it. */
+ rbuMPrintfExec(p, p->dbRbu,
+ "CREATE TABLE IF NOT EXISTS %s.'rbu_tmp_%q' AS "
+ "SELECT *%s FROM '%q' WHERE 0;"
+ , p->zStateDb, pIter->zDataTbl
+ , (pIter->eType==RBU_PK_EXTERNAL ? ", 0 AS rbu_rowid" : "")
+ , pIter->zDataTbl
+ );
+
+ rbuMPrintfExec(p, p->dbMain,
+ "CREATE TEMP TRIGGER rbu_delete_tr BEFORE DELETE ON \"%s%w\" "
+ "BEGIN "
+ " SELECT rbu_tmp_insert(2, %s);"
+ "END;"
+
+ "CREATE TEMP TRIGGER rbu_update1_tr BEFORE UPDATE ON \"%s%w\" "
+ "BEGIN "
+ " SELECT rbu_tmp_insert(2, %s);"
+ "END;"
+
+ "CREATE TEMP TRIGGER rbu_update2_tr AFTER UPDATE ON \"%s%w\" "
+ "BEGIN "
+ " SELECT rbu_tmp_insert(3, %s);"
+ "END;",
+ zWrite, zTbl, zOldlist,
+ zWrite, zTbl, zOldlist,
+ zWrite, zTbl, zNewlist
+ );
+
+ if( pIter->eType==RBU_PK_EXTERNAL || pIter->eType==RBU_PK_NONE ){
+ rbuMPrintfExec(p, p->dbMain,
+ "CREATE TEMP TRIGGER rbu_insert_tr AFTER INSERT ON \"%s%w\" "
+ "BEGIN "
+ " SELECT rbu_tmp_insert(0, %s);"
+ "END;",
+ zWrite, zTbl, zNewlist
+ );
+ }
+
+ rbuObjIterPrepareTmpInsert(p, pIter, zCollist, zRbuRowid);
+ }
+
+ /* Create the SELECT statement to read keys from data_xxx */
+ if( p->rc==SQLITE_OK ){
+ p->rc = prepareFreeAndCollectError(p->dbRbu, &pIter->pSelect, pz,
+ sqlite3_mprintf(
+ "SELECT %s, rbu_control%s FROM '%q'%s",
+ zCollist, (bRbuRowid ? ", rbu_rowid" : ""),
+ pIter->zDataTbl, zLimit
+ )
+ );
+ }
+
+ sqlite3_free(zWhere);
+ sqlite3_free(zOldlist);
+ sqlite3_free(zNewlist);
+ sqlite3_free(zBindings);
+ }
+ sqlite3_free(zCollist);
+ sqlite3_free(zLimit);
+ }
+
+ return p->rc;
+}
+
+/*
+** Set output variable *ppStmt to point to an UPDATE statement that may
+** be used to update the imposter table for the main table b-tree of the
+** table object that pIter currently points to, assuming that the
+** rbu_control column of the data_xyz table contains zMask.
+**
+** If the zMask string does not specify any columns to update, then this
+** is not an error. Output variable *ppStmt is set to NULL in this case.
+*/
+static int rbuGetUpdateStmt(
+ sqlite3rbu *p, /* RBU handle */
+ RbuObjIter *pIter, /* Object iterator */
+ const char *zMask, /* rbu_control value ('x.x.') */
+ sqlite3_stmt **ppStmt /* OUT: UPDATE statement handle */
+){
+ RbuUpdateStmt **pp;
+ RbuUpdateStmt *pUp = 0;
+ int nUp = 0;
+
+ /* In case an error occurs */
+ *ppStmt = 0;
+
+ /* Search for an existing statement. If one is found, shift it to the front
+ ** of the LRU queue and return immediately. Otherwise, leave nUp pointing
+ ** to the number of statements currently in the cache and pUp to the
+ ** last object in the list. */
+ for(pp=&pIter->pRbuUpdate; *pp; pp=&((*pp)->pNext)){
+ pUp = *pp;
+ if( strcmp(pUp->zMask, zMask)==0 ){
+ *pp = pUp->pNext;
+ pUp->pNext = pIter->pRbuUpdate;
+ pIter->pRbuUpdate = pUp;
+ *ppStmt = pUp->pUpdate;
+ return SQLITE_OK;
+ }
+ nUp++;
+ }
+ assert( pUp==0 || pUp->pNext==0 );
+
+ if( nUp>=SQLITE_RBU_UPDATE_CACHESIZE ){
+ for(pp=&pIter->pRbuUpdate; *pp!=pUp; pp=&((*pp)->pNext));
+ *pp = 0;
+ sqlite3_finalize(pUp->pUpdate);
+ pUp->pUpdate = 0;
+ }else{
+ pUp = (RbuUpdateStmt*)rbuMalloc(p, sizeof(RbuUpdateStmt)+pIter->nTblCol+1);
+ }
+
+ if( pUp ){
+ char *zWhere = rbuObjIterGetWhere(p, pIter);
+ char *zSet = rbuObjIterGetSetlist(p, pIter, zMask);
+ char *zUpdate = 0;
+
+ pUp->zMask = (char*)&pUp[1];
+ memcpy(pUp->zMask, zMask, pIter->nTblCol);
+ pUp->pNext = pIter->pRbuUpdate;
+ pIter->pRbuUpdate = pUp;
+
+ if( zSet ){
+ const char *zPrefix = "";
+
+ if( pIter->eType!=RBU_PK_VTAB ) zPrefix = "rbu_imp_";
+ zUpdate = sqlite3_mprintf("UPDATE \"%s%w\" SET %s WHERE %s",
+ zPrefix, pIter->zTbl, zSet, zWhere
+ );
+ p->rc = prepareFreeAndCollectError(
+ p->dbMain, &pUp->pUpdate, &p->zErrmsg, zUpdate
+ );
+ *ppStmt = pUp->pUpdate;
+ }
+ sqlite3_free(zWhere);
+ sqlite3_free(zSet);
+ }
+
+ return p->rc;
+}
+
+static sqlite3 *rbuOpenDbhandle(sqlite3rbu *p, const char *zName){
+ sqlite3 *db = 0;
+ if( p->rc==SQLITE_OK ){
+ const int flags = SQLITE_OPEN_READWRITE|SQLITE_OPEN_CREATE|SQLITE_OPEN_URI;
+ p->rc = sqlite3_open_v2(zName, &db, flags, p->zVfsName);
+ if( p->rc ){
+ p->zErrmsg = sqlite3_mprintf("%s", sqlite3_errmsg(db));
+ sqlite3_close(db);
+ db = 0;
+ }
+ }
+ return db;
+}
+
+/*
+** Open the database handle and attach the RBU database as "rbu". If an
+** error occurs, leave an error code and message in the RBU handle.
+*/
+static void rbuOpenDatabase(sqlite3rbu *p){
+ assert( p->rc==SQLITE_OK );
+ assert( p->dbMain==0 && p->dbRbu==0 );
+
+ p->eStage = 0;
+ p->dbMain = rbuOpenDbhandle(p, p->zTarget);
+ p->dbRbu = rbuOpenDbhandle(p, p->zRbu);
+
+ /* If using separate RBU and state databases, attach the state database to
+ ** the RBU db handle now. */
+ if( p->zState ){
+ rbuMPrintfExec(p, p->dbRbu, "ATTACH %Q AS stat", p->zState);
+ memcpy(p->zStateDb, "stat", 4);
+ }else{
+ memcpy(p->zStateDb, "main", 4);
+ }
+
+ if( p->rc==SQLITE_OK ){
+ p->rc = sqlite3_create_function(p->dbMain,
+ "rbu_tmp_insert", -1, SQLITE_UTF8, (void*)p, rbuTmpInsertFunc, 0, 0
+ );
+ }
+
+ if( p->rc==SQLITE_OK ){
+ p->rc = sqlite3_create_function(p->dbMain,
+ "rbu_fossil_delta", 2, SQLITE_UTF8, 0, rbuFossilDeltaFunc, 0, 0
+ );
+ }
+
+ if( p->rc==SQLITE_OK ){
+ p->rc = sqlite3_create_function(p->dbRbu,
+ "rbu_target_name", 1, SQLITE_UTF8, (void*)p, rbuTargetNameFunc, 0, 0
+ );
+ }
+
+ if( p->rc==SQLITE_OK ){
+ p->rc = sqlite3_file_control(p->dbMain, "main", SQLITE_FCNTL_RBU, (void*)p);
+ }
+ rbuMPrintfExec(p, p->dbMain, "SELECT * FROM sqlite_master");
+
+ /* Mark the database file just opened as an RBU target database. If
+ ** this call returns SQLITE_NOTFOUND, then the RBU vfs is not in use.
+ ** This is an error. */
+ if( p->rc==SQLITE_OK ){
+ p->rc = sqlite3_file_control(p->dbMain, "main", SQLITE_FCNTL_RBU, (void*)p);
+ }
+
+ if( p->rc==SQLITE_NOTFOUND ){
+ p->rc = SQLITE_ERROR;
+ p->zErrmsg = sqlite3_mprintf("rbu vfs not found");
+ }
+}
+
+/*
+** This routine is a copy of the sqlite3FileSuffix3() routine from the core.
+** It is a no-op unless SQLITE_ENABLE_8_3_NAMES is defined.
+**
+** 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
+*/
+static void rbuFileSuffix3(const char *zBase, char *z){
+#ifdef SQLITE_ENABLE_8_3_NAMES
+#if SQLITE_ENABLE_8_3_NAMES<2
+ if( sqlite3_uri_boolean(zBase, "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
+}
+
+/*
+** Return the current wal-index header checksum for the target database
+** as a 64-bit integer.
+**
+** The checksum is store in the first page of xShmMap memory as an 8-byte
+** blob starting at byte offset 40.
+*/
+static i64 rbuShmChecksum(sqlite3rbu *p){
+ i64 iRet = 0;
+ if( p->rc==SQLITE_OK ){
+ sqlite3_file *pDb = p->pTargetFd->pReal;
+ u32 volatile *ptr;
+ p->rc = pDb->pMethods->xShmMap(pDb, 0, 32*1024, 0, (void volatile**)&ptr);
+ if( p->rc==SQLITE_OK ){
+ iRet = ((i64)ptr[10] << 32) + ptr[11];
+ }
+ }
+ return iRet;
+}
+
+/*
+** This function is called as part of initializing or reinitializing an
+** incremental checkpoint.
+**
+** It populates the sqlite3rbu.aFrame[] array with the set of
+** (wal frame -> db page) copy operations required to checkpoint the
+** current wal file, and obtains the set of shm locks required to safely
+** perform the copy operations directly on the file-system.
+**
+** If argument pState is not NULL, then the incremental checkpoint is
+** being resumed. In this case, if the checksum of the wal-index-header
+** following recovery is not the same as the checksum saved in the RbuState
+** object, then the rbu handle is set to DONE state. This occurs if some
+** other client appends a transaction to the wal file in the middle of
+** an incremental checkpoint.
+*/
+static void rbuSetupCheckpoint(sqlite3rbu *p, RbuState *pState){
+
+ /* If pState is NULL, then the wal file may not have been opened and
+ ** recovered. Running a read-statement here to ensure that doing so
+ ** does not interfere with the "capture" process below. */
+ if( pState==0 ){
+ p->eStage = 0;
+ if( p->rc==SQLITE_OK ){
+ p->rc = sqlite3_exec(p->dbMain, "SELECT * FROM sqlite_master", 0, 0, 0);
+ }
+ }
+
+ /* Assuming no error has occurred, run a "restart" checkpoint with the
+ ** sqlite3rbu.eStage variable set to CAPTURE. This turns on the following
+ ** special behaviour in the rbu VFS:
+ **
+ ** * If the exclusive shm WRITER or READ0 lock cannot be obtained,
+ ** the checkpoint fails with SQLITE_BUSY (normally SQLite would
+ ** proceed with running a passive checkpoint instead of failing).
+ **
+ ** * Attempts to read from the *-wal file or write to the database file
+ ** do not perform any IO. Instead, the frame/page combinations that
+ ** would be read/written are recorded in the sqlite3rbu.aFrame[]
+ ** array.
+ **
+ ** * Calls to xShmLock(UNLOCK) to release the exclusive shm WRITER,
+ ** READ0 and CHECKPOINT locks taken as part of the checkpoint are
+ ** no-ops. These locks will not be released until the connection
+ ** is closed.
+ **
+ ** * Attempting to xSync() the database file causes an SQLITE_INTERNAL
+ ** error.
+ **
+ ** As a result, unless an error (i.e. OOM or SQLITE_BUSY) occurs, the
+ ** checkpoint below fails with SQLITE_INTERNAL, and leaves the aFrame[]
+ ** array populated with a set of (frame -> page) mappings. Because the
+ ** WRITER, CHECKPOINT and READ0 locks are still held, it is safe to copy
+ ** data from the wal file into the database file according to the
+ ** contents of aFrame[].
+ */
+ if( p->rc==SQLITE_OK ){
+ int rc2;
+ p->eStage = RBU_STAGE_CAPTURE;
+ rc2 = sqlite3_exec(p->dbMain, "PRAGMA main.wal_checkpoint=restart", 0, 0,0);
+ if( rc2!=SQLITE_INTERNAL ) p->rc = rc2;
+ }
+
+ if( p->rc==SQLITE_OK ){
+ p->eStage = RBU_STAGE_CKPT;
+ p->nStep = (pState ? pState->nRow : 0);
+ p->aBuf = rbuMalloc(p, p->pgsz);
+ p->iWalCksum = rbuShmChecksum(p);
+ }
+
+ if( p->rc==SQLITE_OK && pState && pState->iWalCksum!=p->iWalCksum ){
+ p->rc = SQLITE_DONE;
+ p->eStage = RBU_STAGE_DONE;
+ }
+}
+
+/*
+** Called when iAmt bytes are read from offset iOff of the wal file while
+** the rbu object is in capture mode. Record the frame number of the frame
+** being read in the aFrame[] array.
+*/
+static int rbuCaptureWalRead(sqlite3rbu *pRbu, i64 iOff, int iAmt){
+ const u32 mReq = (1<<WAL_LOCK_WRITE)|(1<<WAL_LOCK_CKPT)|(1<<WAL_LOCK_READ0);
+ u32 iFrame;
+
+ if( pRbu->mLock!=mReq ){
+ pRbu->rc = SQLITE_BUSY;
+ return SQLITE_INTERNAL;
+ }
+
+ pRbu->pgsz = iAmt;
+ if( pRbu->nFrame==pRbu->nFrameAlloc ){
+ int nNew = (pRbu->nFrameAlloc ? pRbu->nFrameAlloc : 64) * 2;
+ RbuFrame *aNew;
+ aNew = (RbuFrame*)sqlite3_realloc(pRbu->aFrame, nNew * sizeof(RbuFrame));
+ if( aNew==0 ) return SQLITE_NOMEM;
+ pRbu->aFrame = aNew;
+ pRbu->nFrameAlloc = nNew;
+ }
+
+ iFrame = (u32)((iOff-32) / (i64)(iAmt+24)) + 1;
+ if( pRbu->iMaxFrame<iFrame ) pRbu->iMaxFrame = iFrame;
+ pRbu->aFrame[pRbu->nFrame].iWalFrame = iFrame;
+ pRbu->aFrame[pRbu->nFrame].iDbPage = 0;
+ pRbu->nFrame++;
+ return SQLITE_OK;
+}
+
+/*
+** Called when a page of data is written to offset iOff of the database
+** file while the rbu handle is in capture mode. Record the page number
+** of the page being written in the aFrame[] array.
+*/
+static int rbuCaptureDbWrite(sqlite3rbu *pRbu, i64 iOff){
+ pRbu->aFrame[pRbu->nFrame-1].iDbPage = (u32)(iOff / pRbu->pgsz) + 1;
+ return SQLITE_OK;
+}
+
+/*
+** This is called as part of an incremental checkpoint operation. Copy
+** a single frame of data from the wal file into the database file, as
+** indicated by the RbuFrame object.
+*/
+static void rbuCheckpointFrame(sqlite3rbu *p, RbuFrame *pFrame){
+ sqlite3_file *pWal = p->pTargetFd->pWalFd->pReal;
+ sqlite3_file *pDb = p->pTargetFd->pReal;
+ i64 iOff;
+
+ assert( p->rc==SQLITE_OK );
+ iOff = (i64)(pFrame->iWalFrame-1) * (p->pgsz + 24) + 32 + 24;
+ p->rc = pWal->pMethods->xRead(pWal, p->aBuf, p->pgsz, iOff);
+ if( p->rc ) return;
+
+ iOff = (i64)(pFrame->iDbPage-1) * p->pgsz;
+ p->rc = pDb->pMethods->xWrite(pDb, p->aBuf, p->pgsz, iOff);
+}
+
+
+/*
+** Take an EXCLUSIVE lock on the database file.
+*/
+static void rbuLockDatabase(sqlite3rbu *p){
+ sqlite3_file *pReal = p->pTargetFd->pReal;
+ assert( p->rc==SQLITE_OK );
+ p->rc = pReal->pMethods->xLock(pReal, SQLITE_LOCK_SHARED);
+ if( p->rc==SQLITE_OK ){
+ p->rc = pReal->pMethods->xLock(pReal, SQLITE_LOCK_EXCLUSIVE);
+ }
+}
+
+#if defined(_WIN32_WCE)
+static LPWSTR rbuWinUtf8ToUnicode(const char *zFilename){
+ int nChar;
+ LPWSTR zWideFilename;
+
+ nChar = MultiByteToWideChar(CP_UTF8, 0, zFilename, -1, NULL, 0);
+ if( nChar==0 ){
+ return 0;
+ }
+ zWideFilename = sqlite3_malloc( nChar*sizeof(zWideFilename[0]) );
+ if( zWideFilename==0 ){
+ return 0;
+ }
+ memset(zWideFilename, 0, nChar*sizeof(zWideFilename[0]));
+ nChar = MultiByteToWideChar(CP_UTF8, 0, zFilename, -1, zWideFilename,
+ nChar);
+ if( nChar==0 ){
+ sqlite3_free(zWideFilename);
+ zWideFilename = 0;
+ }
+ return zWideFilename;
+}
+#endif
+
+/*
+** The RBU handle is currently in RBU_STAGE_OAL state, with a SHARED lock
+** on the database file. This proc moves the *-oal file to the *-wal path,
+** then reopens the database file (this time in vanilla, non-oal, WAL mode).
+** If an error occurs, leave an error code and error message in the rbu
+** handle.
+*/
+static void rbuMoveOalFile(sqlite3rbu *p){
+ const char *zBase = sqlite3_db_filename(p->dbMain, "main");
+
+ char *zWal = sqlite3_mprintf("%s-wal", zBase);
+ char *zOal = sqlite3_mprintf("%s-oal", zBase);
+
+ assert( p->eStage==RBU_STAGE_MOVE );
+ assert( p->rc==SQLITE_OK && p->zErrmsg==0 );
+ if( zWal==0 || zOal==0 ){
+ p->rc = SQLITE_NOMEM;
+ }else{
+ /* Move the *-oal file to *-wal. At this point connection p->db is
+ ** holding a SHARED lock on the target database file (because it is
+ ** in WAL mode). So no other connection may be writing the db.
+ **
+ ** In order to ensure that there are no database readers, an EXCLUSIVE
+ ** lock is obtained here before the *-oal is moved to *-wal.
+ */
+ rbuLockDatabase(p);
+ if( p->rc==SQLITE_OK ){
+ rbuFileSuffix3(zBase, zWal);
+ rbuFileSuffix3(zBase, zOal);
+
+ /* Re-open the databases. */
+ rbuObjIterFinalize(&p->objiter);
+ sqlite3_close(p->dbMain);
+ sqlite3_close(p->dbRbu);
+ p->dbMain = 0;
+ p->dbRbu = 0;
+
+#if defined(_WIN32_WCE)
+ {
+ LPWSTR zWideOal;
+ LPWSTR zWideWal;
+
+ zWideOal = rbuWinUtf8ToUnicode(zOal);
+ if( zWideOal ){
+ zWideWal = rbuWinUtf8ToUnicode(zWal);
+ if( zWideWal ){
+ if( MoveFileW(zWideOal, zWideWal) ){
+ p->rc = SQLITE_OK;
+ }else{
+ p->rc = SQLITE_IOERR;
+ }
+ sqlite3_free(zWideWal);
+ }else{
+ p->rc = SQLITE_IOERR_NOMEM;
+ }
+ sqlite3_free(zWideOal);
+ }else{
+ p->rc = SQLITE_IOERR_NOMEM;
+ }
+ }
+#else
+ p->rc = rename(zOal, zWal) ? SQLITE_IOERR : SQLITE_OK;
+#endif
+
+ if( p->rc==SQLITE_OK ){
+ rbuOpenDatabase(p);
+ rbuSetupCheckpoint(p, 0);
+ }
+ }
+ }
+
+ sqlite3_free(zWal);
+ sqlite3_free(zOal);
+}
+
+/*
+** The SELECT statement iterating through the keys for the current object
+** (p->objiter.pSelect) currently points to a valid row. This function
+** determines the type of operation requested by this row and returns
+** one of the following values to indicate the result:
+**
+** * RBU_INSERT
+** * RBU_DELETE
+** * RBU_IDX_DELETE
+** * RBU_UPDATE
+**
+** If RBU_UPDATE is returned, then output variable *pzMask is set to
+** point to the text value indicating the columns to update.
+**
+** If the rbu_control field contains an invalid value, an error code and
+** message are left in the RBU handle and zero returned.
+*/
+static int rbuStepType(sqlite3rbu *p, const char **pzMask){
+ int iCol = p->objiter.nCol; /* Index of rbu_control column */
+ int res = 0; /* Return value */
+
+ switch( sqlite3_column_type(p->objiter.pSelect, iCol) ){
+ case SQLITE_INTEGER: {
+ int iVal = sqlite3_column_int(p->objiter.pSelect, iCol);
+ if( iVal==0 ){
+ res = RBU_INSERT;
+ }else if( iVal==1 ){
+ res = RBU_DELETE;
+ }else if( iVal==2 ){
+ res = RBU_IDX_DELETE;
+ }else if( iVal==3 ){
+ res = RBU_IDX_INSERT;
+ }
+ break;
+ }
+
+ case SQLITE_TEXT: {
+ const unsigned char *z = sqlite3_column_text(p->objiter.pSelect, iCol);
+ if( z==0 ){
+ p->rc = SQLITE_NOMEM;
+ }else{
+ *pzMask = (const char*)z;
+ }
+ res = RBU_UPDATE;
+
+ break;
+ }
+
+ default:
+ break;
+ }
+
+ if( res==0 ){
+ rbuBadControlError(p);
+ }
+ return res;
+}
+
+#ifdef SQLITE_DEBUG
+/*
+** Assert that column iCol of statement pStmt is named zName.
+*/
+static void assertColumnName(sqlite3_stmt *pStmt, int iCol, const char *zName){
+ const char *zCol = sqlite3_column_name(pStmt, iCol);
+ assert( 0==sqlite3_stricmp(zName, zCol) );
+}
+#else
+# define assertColumnName(x,y,z)
+#endif
+
+/*
+** This function does the work for an sqlite3rbu_step() call.
+**
+** The object-iterator (p->objiter) currently points to a valid object,
+** and the input cursor (p->objiter.pSelect) currently points to a valid
+** input row. Perform whatever processing is required and return.
+**
+** If no error occurs, SQLITE_OK is returned. Otherwise, an error code
+** and message is left in the RBU handle and a copy of the error code
+** returned.
+*/
+static int rbuStep(sqlite3rbu *p){
+ RbuObjIter *pIter = &p->objiter;
+ const char *zMask = 0;
+ int i;
+ int eType = rbuStepType(p, &zMask);
+
+ if( eType ){
+ assert( eType!=RBU_UPDATE || pIter->zIdx==0 );
+
+ if( pIter->zIdx==0 && eType==RBU_IDX_DELETE ){
+ rbuBadControlError(p);
+ }
+ else if(
+ eType==RBU_INSERT
+ || eType==RBU_DELETE
+ || eType==RBU_IDX_DELETE
+ || eType==RBU_IDX_INSERT
+ ){
+ sqlite3_value *pVal;
+ sqlite3_stmt *pWriter;
+
+ assert( eType!=RBU_UPDATE );
+ assert( eType!=RBU_DELETE || pIter->zIdx==0 );
+
+ if( eType==RBU_IDX_DELETE || eType==RBU_DELETE ){
+ pWriter = pIter->pDelete;
+ }else{
+ pWriter = pIter->pInsert;
+ }
+
+ for(i=0; i<pIter->nCol; i++){
+ /* If this is an INSERT into a table b-tree and the table has an
+ ** explicit INTEGER PRIMARY KEY, check that this is not an attempt
+ ** to write a NULL into the IPK column. That is not permitted. */
+ if( eType==RBU_INSERT
+ && pIter->zIdx==0 && pIter->eType==RBU_PK_IPK && pIter->abTblPk[i]
+ && sqlite3_column_type(pIter->pSelect, i)==SQLITE_NULL
+ ){
+ p->rc = SQLITE_MISMATCH;
+ p->zErrmsg = sqlite3_mprintf("datatype mismatch");
+ goto step_out;
+ }
+
+ if( eType==RBU_DELETE && pIter->abTblPk[i]==0 ){
+ continue;
+ }
+
+ pVal = sqlite3_column_value(pIter->pSelect, i);
+ p->rc = sqlite3_bind_value(pWriter, i+1, pVal);
+ if( p->rc ) goto step_out;
+ }
+ if( pIter->zIdx==0
+ && (pIter->eType==RBU_PK_VTAB || pIter->eType==RBU_PK_NONE)
+ ){
+ /* For a virtual table, or a table with no primary key, the
+ ** SELECT statement is:
+ **
+ ** SELECT <cols>, rbu_control, rbu_rowid FROM ....
+ **
+ ** Hence column_value(pIter->nCol+1).
+ */
+ assertColumnName(pIter->pSelect, pIter->nCol+1, "rbu_rowid");
+ pVal = sqlite3_column_value(pIter->pSelect, pIter->nCol+1);
+ p->rc = sqlite3_bind_value(pWriter, pIter->nCol+1, pVal);
+ }
+ if( p->rc==SQLITE_OK ){
+ sqlite3_step(pWriter);
+ p->rc = resetAndCollectError(pWriter, &p->zErrmsg);
+ }
+ }else{
+ sqlite3_value *pVal;
+ sqlite3_stmt *pUpdate = 0;
+ assert( eType==RBU_UPDATE );
+ rbuGetUpdateStmt(p, pIter, zMask, &pUpdate);
+ if( pUpdate ){
+ for(i=0; p->rc==SQLITE_OK && i<pIter->nCol; i++){
+ char c = zMask[pIter->aiSrcOrder[i]];
+ pVal = sqlite3_column_value(pIter->pSelect, i);
+ if( pIter->abTblPk[i] || c!='.' ){
+ p->rc = sqlite3_bind_value(pUpdate, i+1, pVal);
+ }
+ }
+ if( p->rc==SQLITE_OK
+ && (pIter->eType==RBU_PK_VTAB || pIter->eType==RBU_PK_NONE)
+ ){
+ /* Bind the rbu_rowid value to column _rowid_ */
+ assertColumnName(pIter->pSelect, pIter->nCol+1, "rbu_rowid");
+ pVal = sqlite3_column_value(pIter->pSelect, pIter->nCol+1);
+ p->rc = sqlite3_bind_value(pUpdate, pIter->nCol+1, pVal);
+ }
+ if( p->rc==SQLITE_OK ){
+ sqlite3_step(pUpdate);
+ p->rc = resetAndCollectError(pUpdate, &p->zErrmsg);
+ }
+ }
+ }
+ }
+
+ step_out:
+ return p->rc;
+}
+
+/*
+** Increment the schema cookie of the main database opened by p->dbMain.
+*/
+static void rbuIncrSchemaCookie(sqlite3rbu *p){
+ if( p->rc==SQLITE_OK ){
+ int iCookie = 1000000;
+ sqlite3_stmt *pStmt;
+
+ p->rc = prepareAndCollectError(p->dbMain, &pStmt, &p->zErrmsg,
+ "PRAGMA schema_version"
+ );
+ if( p->rc==SQLITE_OK ){
+ /* Coverage: it may be that this sqlite3_step() cannot fail. There
+ ** is already a transaction open, so the prepared statement cannot
+ ** throw an SQLITE_SCHEMA exception. The only database page the
+ ** statement reads is page 1, which is guaranteed to be in the cache.
+ ** And no memory allocations are required. */
+ if( SQLITE_ROW==sqlite3_step(pStmt) ){
+ iCookie = sqlite3_column_int(pStmt, 0);
+ }
+ rbuFinalize(p, pStmt);
+ }
+ if( p->rc==SQLITE_OK ){
+ rbuMPrintfExec(p, p->dbMain, "PRAGMA schema_version = %d", iCookie+1);
+ }
+ }
+}
+
+/*
+** Update the contents of the rbu_state table within the rbu database. The
+** value stored in the RBU_STATE_STAGE column is eStage. All other values
+** are determined by inspecting the rbu handle passed as the first argument.
+*/
+static void rbuSaveState(sqlite3rbu *p, int eStage){
+ if( p->rc==SQLITE_OK || p->rc==SQLITE_DONE ){
+ sqlite3_stmt *pInsert = 0;
+ int rc;
+
+ assert( p->zErrmsg==0 );
+ rc = prepareFreeAndCollectError(p->dbRbu, &pInsert, &p->zErrmsg,
+ sqlite3_mprintf(
+ "INSERT OR REPLACE INTO %s.rbu_state(k, v) VALUES "
+ "(%d, %d), "
+ "(%d, %Q), "
+ "(%d, %Q), "
+ "(%d, %d), "
+ "(%d, %d), "
+ "(%d, %lld), "
+ "(%d, %lld), "
+ "(%d, %lld) ",
+ p->zStateDb,
+ RBU_STATE_STAGE, eStage,
+ RBU_STATE_TBL, p->objiter.zTbl,
+ RBU_STATE_IDX, p->objiter.zIdx,
+ RBU_STATE_ROW, p->nStep,
+ RBU_STATE_PROGRESS, p->nProgress,
+ RBU_STATE_CKPT, p->iWalCksum,
+ RBU_STATE_COOKIE, (i64)p->pTargetFd->iCookie,
+ RBU_STATE_OALSZ, p->iOalSz
+ )
+ );
+ assert( pInsert==0 || rc==SQLITE_OK );
+
+ if( rc==SQLITE_OK ){
+ sqlite3_step(pInsert);
+ rc = sqlite3_finalize(pInsert);
+ }
+ if( rc!=SQLITE_OK ) p->rc = rc;
+ }
+}
+
+
+/*
+** Step the RBU object.
+*/
+SQLITE_API int SQLITE_STDCALL sqlite3rbu_step(sqlite3rbu *p){
+ if( p ){
+ switch( p->eStage ){
+ case RBU_STAGE_OAL: {
+ RbuObjIter *pIter = &p->objiter;
+ while( p->rc==SQLITE_OK && pIter->zTbl ){
+
+ if( pIter->bCleanup ){
+ /* Clean up the rbu_tmp_xxx table for the previous table. It
+ ** cannot be dropped as there are currently active SQL statements.
+ ** But the contents can be deleted. */
+ if( pIter->abIndexed ){
+ rbuMPrintfExec(p, p->dbRbu,
+ "DELETE FROM %s.'rbu_tmp_%q'", p->zStateDb, pIter->zDataTbl
+ );
+ }
+ }else{
+ rbuObjIterPrepareAll(p, pIter, 0);
+
+ /* Advance to the next row to process. */
+ if( p->rc==SQLITE_OK ){
+ int rc = sqlite3_step(pIter->pSelect);
+ if( rc==SQLITE_ROW ){
+ p->nProgress++;
+ p->nStep++;
+ return rbuStep(p);
+ }
+ p->rc = sqlite3_reset(pIter->pSelect);
+ p->nStep = 0;
+ }
+ }
+
+ rbuObjIterNext(p, pIter);
+ }
+
+ if( p->rc==SQLITE_OK ){
+ assert( pIter->zTbl==0 );
+ rbuSaveState(p, RBU_STAGE_MOVE);
+ rbuIncrSchemaCookie(p);
+ if( p->rc==SQLITE_OK ){
+ p->rc = sqlite3_exec(p->dbMain, "COMMIT", 0, 0, &p->zErrmsg);
+ }
+ if( p->rc==SQLITE_OK ){
+ p->rc = sqlite3_exec(p->dbRbu, "COMMIT", 0, 0, &p->zErrmsg);
+ }
+ p->eStage = RBU_STAGE_MOVE;
+ }
+ break;
+ }
+
+ case RBU_STAGE_MOVE: {
+ if( p->rc==SQLITE_OK ){
+ rbuMoveOalFile(p);
+ p->nProgress++;
+ }
+ break;
+ }
+
+ case RBU_STAGE_CKPT: {
+ if( p->rc==SQLITE_OK ){
+ if( p->nStep>=p->nFrame ){
+ sqlite3_file *pDb = p->pTargetFd->pReal;
+
+ /* Sync the db file */
+ p->rc = pDb->pMethods->xSync(pDb, SQLITE_SYNC_NORMAL);
+
+ /* Update nBackfill */
+ if( p->rc==SQLITE_OK ){
+ void volatile *ptr;
+ p->rc = pDb->pMethods->xShmMap(pDb, 0, 32*1024, 0, &ptr);
+ if( p->rc==SQLITE_OK ){
+ ((u32 volatile*)ptr)[24] = p->iMaxFrame;
+ }
+ }
+
+ if( p->rc==SQLITE_OK ){
+ p->eStage = RBU_STAGE_DONE;
+ p->rc = SQLITE_DONE;
+ }
+ }else{
+ RbuFrame *pFrame = &p->aFrame[p->nStep];
+ rbuCheckpointFrame(p, pFrame);
+ p->nStep++;
+ }
+ p->nProgress++;
+ }
+ break;
+ }
+
+ default:
+ break;
+ }
+ return p->rc;
+ }else{
+ return SQLITE_NOMEM;
+ }
+}
+
+/*
+** Free an RbuState object allocated by rbuLoadState().
+*/
+static void rbuFreeState(RbuState *p){
+ if( p ){
+ sqlite3_free(p->zTbl);
+ sqlite3_free(p->zIdx);
+ sqlite3_free(p);
+ }
+}
+
+/*
+** Allocate an RbuState object and load the contents of the rbu_state
+** table into it. Return a pointer to the new object. It is the
+** responsibility of the caller to eventually free the object using
+** sqlite3_free().
+**
+** If an error occurs, leave an error code and message in the rbu handle
+** and return NULL.
+*/
+static RbuState *rbuLoadState(sqlite3rbu *p){
+ RbuState *pRet = 0;
+ sqlite3_stmt *pStmt = 0;
+ int rc;
+ int rc2;
+
+ pRet = (RbuState*)rbuMalloc(p, sizeof(RbuState));
+ if( pRet==0 ) return 0;
+
+ rc = prepareFreeAndCollectError(p->dbRbu, &pStmt, &p->zErrmsg,
+ sqlite3_mprintf("SELECT k, v FROM %s.rbu_state", p->zStateDb)
+ );
+ while( rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pStmt) ){
+ switch( sqlite3_column_int(pStmt, 0) ){
+ case RBU_STATE_STAGE:
+ pRet->eStage = sqlite3_column_int(pStmt, 1);
+ if( pRet->eStage!=RBU_STAGE_OAL
+ && pRet->eStage!=RBU_STAGE_MOVE
+ && pRet->eStage!=RBU_STAGE_CKPT
+ ){
+ p->rc = SQLITE_CORRUPT;
+ }
+ break;
+
+ case RBU_STATE_TBL:
+ pRet->zTbl = rbuStrndup((char*)sqlite3_column_text(pStmt, 1), &rc);
+ break;
+
+ case RBU_STATE_IDX:
+ pRet->zIdx = rbuStrndup((char*)sqlite3_column_text(pStmt, 1), &rc);
+ break;
+
+ case RBU_STATE_ROW:
+ pRet->nRow = sqlite3_column_int(pStmt, 1);
+ break;
+
+ case RBU_STATE_PROGRESS:
+ pRet->nProgress = sqlite3_column_int64(pStmt, 1);
+ break;
+
+ case RBU_STATE_CKPT:
+ pRet->iWalCksum = sqlite3_column_int64(pStmt, 1);
+ break;
+
+ case RBU_STATE_COOKIE:
+ pRet->iCookie = (u32)sqlite3_column_int64(pStmt, 1);
+ break;
+
+ case RBU_STATE_OALSZ:
+ pRet->iOalSz = (u32)sqlite3_column_int64(pStmt, 1);
+ break;
+
+ default:
+ rc = SQLITE_CORRUPT;
+ break;
+ }
+ }
+ rc2 = sqlite3_finalize(pStmt);
+ if( rc==SQLITE_OK ) rc = rc2;
+
+ p->rc = rc;
+ return pRet;
+}
+
+/*
+** Compare strings z1 and z2, returning 0 if they are identical, or non-zero
+** otherwise. Either or both argument may be NULL. Two NULL values are
+** considered equal, and NULL is considered distinct from all other values.
+*/
+static int rbuStrCompare(const char *z1, const char *z2){
+ if( z1==0 && z2==0 ) return 0;
+ if( z1==0 || z2==0 ) return 1;
+ return (sqlite3_stricmp(z1, z2)!=0);
+}
+
+/*
+** This function is called as part of sqlite3rbu_open() when initializing
+** an rbu handle in OAL stage. If the rbu update has not started (i.e.
+** the rbu_state table was empty) it is a no-op. Otherwise, it arranges
+** things so that the next call to sqlite3rbu_step() continues on from
+** where the previous rbu handle left off.
+**
+** If an error occurs, an error code and error message are left in the
+** rbu handle passed as the first argument.
+*/
+static void rbuSetupOal(sqlite3rbu *p, RbuState *pState){
+ assert( p->rc==SQLITE_OK );
+ if( pState->zTbl ){
+ RbuObjIter *pIter = &p->objiter;
+ int rc = SQLITE_OK;
+
+ while( rc==SQLITE_OK && pIter->zTbl && (pIter->bCleanup
+ || rbuStrCompare(pIter->zIdx, pState->zIdx)
+ || rbuStrCompare(pIter->zTbl, pState->zTbl)
+ )){
+ rc = rbuObjIterNext(p, pIter);
+ }
+
+ if( rc==SQLITE_OK && !pIter->zTbl ){
+ rc = SQLITE_ERROR;
+ p->zErrmsg = sqlite3_mprintf("rbu_state mismatch error");
+ }
+
+ if( rc==SQLITE_OK ){
+ p->nStep = pState->nRow;
+ rc = rbuObjIterPrepareAll(p, &p->objiter, p->nStep);
+ }
+
+ p->rc = rc;
+ }
+}
+
+/*
+** If there is a "*-oal" file in the file-system corresponding to the
+** target database in the file-system, delete it. If an error occurs,
+** leave an error code and error message in the rbu handle.
+*/
+static void rbuDeleteOalFile(sqlite3rbu *p){
+ char *zOal = rbuMPrintf(p, "%s-oal", p->zTarget);
+ if( zOal ){
+ sqlite3_vfs *pVfs = sqlite3_vfs_find(0);
+ assert( pVfs && p->rc==SQLITE_OK && p->zErrmsg==0 );
+ pVfs->xDelete(pVfs, zOal, 0);
+ sqlite3_free(zOal);
+ }
+}
+
+/*
+** Allocate a private rbu VFS for the rbu handle passed as the only
+** argument. This VFS will be used unless the call to sqlite3rbu_open()
+** specified a URI with a vfs=? option in place of a target database
+** file name.
+*/
+static void rbuCreateVfs(sqlite3rbu *p){
+ int rnd;
+ char zRnd[64];
+
+ assert( p->rc==SQLITE_OK );
+ sqlite3_randomness(sizeof(int), (void*)&rnd);
+ sqlite3_snprintf(sizeof(zRnd), zRnd, "rbu_vfs_%d", rnd);
+ p->rc = sqlite3rbu_create_vfs(zRnd, 0);
+ if( p->rc==SQLITE_OK ){
+ sqlite3_vfs *pVfs = sqlite3_vfs_find(zRnd);
+ assert( pVfs );
+ p->zVfsName = pVfs->zName;
+ }
+}
+
+/*
+** Destroy the private VFS created for the rbu handle passed as the only
+** argument by an earlier call to rbuCreateVfs().
+*/
+static void rbuDeleteVfs(sqlite3rbu *p){
+ if( p->zVfsName ){
+ sqlite3rbu_destroy_vfs(p->zVfsName);
+ p->zVfsName = 0;
+ }
+}
+
+/*
+** Open and return a new RBU handle.
+*/
+SQLITE_API sqlite3rbu *SQLITE_STDCALL sqlite3rbu_open(
+ const char *zTarget,
+ const char *zRbu,
+ const char *zState
+){
+ sqlite3rbu *p;
+ int nTarget = strlen(zTarget);
+ int nRbu = strlen(zRbu);
+ int nState = zState ? strlen(zState) : 0;
+
+ p = (sqlite3rbu*)sqlite3_malloc(sizeof(sqlite3rbu)+nTarget+1+nRbu+1+nState+1);
+ if( p ){
+ RbuState *pState = 0;
+
+ /* Create the custom VFS. */
+ memset(p, 0, sizeof(sqlite3rbu));
+ rbuCreateVfs(p);
+
+ /* Open the target database */
+ if( p->rc==SQLITE_OK ){
+ p->zTarget = (char*)&p[1];
+ memcpy(p->zTarget, zTarget, nTarget+1);
+ p->zRbu = &p->zTarget[nTarget+1];
+ memcpy(p->zRbu, zRbu, nRbu+1);
+ if( zState ){
+ p->zState = &p->zRbu[nRbu+1];
+ memcpy(p->zState, zState, nState+1);
+ }
+ rbuOpenDatabase(p);
+ }
+
+ /* If it has not already been created, create the rbu_state table */
+ rbuMPrintfExec(p, p->dbRbu, RBU_CREATE_STATE, p->zStateDb);
+
+ if( p->rc==SQLITE_OK ){
+ pState = rbuLoadState(p);
+ assert( pState || p->rc!=SQLITE_OK );
+ if( p->rc==SQLITE_OK ){
+
+ if( pState->eStage==0 ){
+ rbuDeleteOalFile(p);
+ p->eStage = RBU_STAGE_OAL;
+ }else{
+ p->eStage = pState->eStage;
+ }
+ p->nProgress = pState->nProgress;
+ p->iOalSz = pState->iOalSz;
+ }
+ }
+ assert( p->rc!=SQLITE_OK || p->eStage!=0 );
+
+ if( p->rc==SQLITE_OK && p->pTargetFd->pWalFd ){
+ if( p->eStage==RBU_STAGE_OAL ){
+ p->rc = SQLITE_ERROR;
+ p->zErrmsg = sqlite3_mprintf("cannot update wal mode database");
+ }else if( p->eStage==RBU_STAGE_MOVE ){
+ p->eStage = RBU_STAGE_CKPT;
+ p->nStep = 0;
+ }
+ }
+
+ if( p->rc==SQLITE_OK
+ && (p->eStage==RBU_STAGE_OAL || p->eStage==RBU_STAGE_MOVE)
+ && pState->eStage!=0 && p->pTargetFd->iCookie!=pState->iCookie
+ ){
+ /* At this point (pTargetFd->iCookie) contains the value of the
+ ** change-counter cookie (the thing that gets incremented when a
+ ** transaction is committed in rollback mode) currently stored on
+ ** page 1 of the database file. */
+ p->rc = SQLITE_BUSY;
+ p->zErrmsg = sqlite3_mprintf("database modified during rbu update");
+ }
+
+ if( p->rc==SQLITE_OK ){
+ if( p->eStage==RBU_STAGE_OAL ){
+ sqlite3 *db = p->dbMain;
+
+ /* Open transactions both databases. The *-oal file is opened or
+ ** created at this point. */
+ p->rc = sqlite3_exec(db, "BEGIN IMMEDIATE", 0, 0, &p->zErrmsg);
+ if( p->rc==SQLITE_OK ){
+ p->rc = sqlite3_exec(p->dbRbu, "BEGIN IMMEDIATE", 0, 0, &p->zErrmsg);
+ }
+
+ /* Check if the main database is a zipvfs db. If it is, set the upper
+ ** level pager to use "journal_mode=off". This prevents it from
+ ** generating a large journal using a temp file. */
+ if( p->rc==SQLITE_OK ){
+ int frc = sqlite3_file_control(db, "main", SQLITE_FCNTL_ZIPVFS, 0);
+ if( frc==SQLITE_OK ){
+ p->rc = sqlite3_exec(db, "PRAGMA journal_mode=off",0,0,&p->zErrmsg);
+ }
+ }
+
+ /* Point the object iterator at the first object */
+ if( p->rc==SQLITE_OK ){
+ p->rc = rbuObjIterFirst(p, &p->objiter);
+ }
+
+ /* If the RBU database contains no data_xxx tables, declare the RBU
+ ** update finished. */
+ if( p->rc==SQLITE_OK && p->objiter.zTbl==0 ){
+ p->rc = SQLITE_DONE;
+ }
+
+ if( p->rc==SQLITE_OK ){
+ rbuSetupOal(p, pState);
+ }
+
+ }else if( p->eStage==RBU_STAGE_MOVE ){
+ /* no-op */
+ }else if( p->eStage==RBU_STAGE_CKPT ){
+ rbuSetupCheckpoint(p, pState);
+ }else if( p->eStage==RBU_STAGE_DONE ){
+ p->rc = SQLITE_DONE;
+ }else{
+ p->rc = SQLITE_CORRUPT;
+ }
+ }
+
+ rbuFreeState(pState);
+ }
+
+ return p;
+}
+
+
+/*
+** Return the database handle used by pRbu.
+*/
+SQLITE_API sqlite3 *SQLITE_STDCALL sqlite3rbu_db(sqlite3rbu *pRbu, int bRbu){
+ sqlite3 *db = 0;
+ if( pRbu ){
+ db = (bRbu ? pRbu->dbRbu : pRbu->dbMain);
+ }
+ return db;
+}
+
+
+/*
+** If the error code currently stored in the RBU handle is SQLITE_CONSTRAINT,
+** then edit any error message string so as to remove all occurrences of
+** the pattern "rbu_imp_[0-9]*".
+*/
+static void rbuEditErrmsg(sqlite3rbu *p){
+ if( p->rc==SQLITE_CONSTRAINT && p->zErrmsg ){
+ int i;
+ int nErrmsg = strlen(p->zErrmsg);
+ for(i=0; i<(nErrmsg-8); i++){
+ if( memcmp(&p->zErrmsg[i], "rbu_imp_", 8)==0 ){
+ int nDel = 8;
+ while( p->zErrmsg[i+nDel]>='0' && p->zErrmsg[i+nDel]<='9' ) nDel++;
+ memmove(&p->zErrmsg[i], &p->zErrmsg[i+nDel], nErrmsg + 1 - i - nDel);
+ nErrmsg -= nDel;
+ }
+ }
+ }
+}
+
+/*
+** Close the RBU handle.
+*/
+SQLITE_API int SQLITE_STDCALL sqlite3rbu_close(sqlite3rbu *p, char **pzErrmsg){
+ int rc;
+ if( p ){
+
+ /* Commit the transaction to the *-oal file. */
+ if( p->rc==SQLITE_OK && p->eStage==RBU_STAGE_OAL ){
+ p->rc = sqlite3_exec(p->dbMain, "COMMIT", 0, 0, &p->zErrmsg);
+ }
+
+ rbuSaveState(p, p->eStage);
+
+ if( p->rc==SQLITE_OK && p->eStage==RBU_STAGE_OAL ){
+ p->rc = sqlite3_exec(p->dbRbu, "COMMIT", 0, 0, &p->zErrmsg);
+ }
+
+ /* Close any open statement handles. */
+ rbuObjIterFinalize(&p->objiter);
+
+ /* Close the open database handle and VFS object. */
+ sqlite3_close(p->dbMain);
+ sqlite3_close(p->dbRbu);
+ rbuDeleteVfs(p);
+ sqlite3_free(p->aBuf);
+ sqlite3_free(p->aFrame);
+
+ rbuEditErrmsg(p);
+ rc = p->rc;
+ *pzErrmsg = p->zErrmsg;
+ sqlite3_free(p);
+ }else{
+ rc = SQLITE_NOMEM;
+ *pzErrmsg = 0;
+ }
+ return rc;
+}
+
+/*
+** Return the total number of key-value operations (inserts, deletes or
+** updates) that have been performed on the target database since the
+** current RBU update was started.
+*/
+SQLITE_API sqlite3_int64 SQLITE_STDCALL sqlite3rbu_progress(sqlite3rbu *pRbu){
+ return pRbu->nProgress;
+}
+
+SQLITE_API int SQLITE_STDCALL sqlite3rbu_savestate(sqlite3rbu *p){
+ int rc = p->rc;
+
+ if( rc==SQLITE_DONE ) return SQLITE_OK;
+
+ assert( p->eStage>=RBU_STAGE_OAL && p->eStage<=RBU_STAGE_DONE );
+ if( p->eStage==RBU_STAGE_OAL ){
+ assert( rc!=SQLITE_DONE );
+ if( rc==SQLITE_OK ) rc = sqlite3_exec(p->dbMain, "COMMIT", 0, 0, 0);
+ }
+
+ p->rc = rc;
+ rbuSaveState(p, p->eStage);
+ rc = p->rc;
+
+ if( p->eStage==RBU_STAGE_OAL ){
+ assert( rc!=SQLITE_DONE );
+ if( rc==SQLITE_OK ) rc = sqlite3_exec(p->dbRbu, "COMMIT", 0, 0, 0);
+ if( rc==SQLITE_OK ) rc = sqlite3_exec(p->dbRbu, "BEGIN IMMEDIATE", 0, 0, 0);
+ if( rc==SQLITE_OK ) rc = sqlite3_exec(p->dbMain, "BEGIN IMMEDIATE", 0, 0,0);
+ }
+
+ p->rc = rc;
+ return rc;
+}
+
+/**************************************************************************
+** Beginning of RBU VFS shim methods. The VFS shim modifies the behaviour
+** of a standard VFS in the following ways:
+**
+** 1. Whenever the first page of a main database file is read or
+** written, the value of the change-counter cookie is stored in
+** rbu_file.iCookie. Similarly, the value of the "write-version"
+** database header field is stored in rbu_file.iWriteVer. This ensures
+** that the values are always trustworthy within an open transaction.
+**
+** 2. Whenever an SQLITE_OPEN_WAL file is opened, the (rbu_file.pWalFd)
+** member variable of the associated database file descriptor is set
+** to point to the new file. A mutex protected linked list of all main
+** db fds opened using a particular RBU VFS is maintained at
+** rbu_vfs.pMain to facilitate this.
+**
+** 3. Using a new file-control "SQLITE_FCNTL_RBU", a main db rbu_file
+** object can be marked as the target database of an RBU update. This
+** turns on the following extra special behaviour:
+**
+** 3a. If xAccess() is called to check if there exists a *-wal file
+** associated with an RBU target database currently in RBU_STAGE_OAL
+** stage (preparing the *-oal file), the following special handling
+** applies:
+**
+** * if the *-wal file does exist, return SQLITE_CANTOPEN. An RBU
+** target database may not be in wal mode already.
+**
+** * if the *-wal file does not exist, set the output parameter to
+** non-zero (to tell SQLite that it does exist) anyway.
+**
+** Then, when xOpen() is called to open the *-wal file associated with
+** the RBU target in RBU_STAGE_OAL stage, instead of opening the *-wal
+** file, the rbu vfs opens the corresponding *-oal file instead.
+**
+** 3b. The *-shm pages returned by xShmMap() for a target db file in
+** RBU_STAGE_OAL mode are actually stored in heap memory. This is to
+** avoid creating a *-shm file on disk. Additionally, xShmLock() calls
+** are no-ops on target database files in RBU_STAGE_OAL mode. This is
+** because assert() statements in some VFS implementations fail if
+** xShmLock() is called before xShmMap().
+**
+** 3c. If an EXCLUSIVE lock is attempted on a target database file in any
+** mode except RBU_STAGE_DONE (all work completed and checkpointed), it
+** fails with an SQLITE_BUSY error. This is to stop RBU connections
+** from automatically checkpointing a *-wal (or *-oal) file from within
+** sqlite3_close().
+**
+** 3d. In RBU_STAGE_CAPTURE mode, all xRead() calls on the wal file, and
+** all xWrite() calls on the target database file perform no IO.
+** Instead the frame and page numbers that would be read and written
+** are recorded. Additionally, successful attempts to obtain exclusive
+** xShmLock() WRITER, CHECKPOINTER and READ0 locks on the target
+** database file are recorded. xShmLock() calls to unlock the same
+** locks are no-ops (so that once obtained, these locks are never
+** relinquished). Finally, calls to xSync() on the target database
+** file fail with SQLITE_INTERNAL errors.
+*/
+
+static void rbuUnlockShm(rbu_file *p){
+ if( p->pRbu ){
+ int (*xShmLock)(sqlite3_file*,int,int,int) = p->pReal->pMethods->xShmLock;
+ int i;
+ for(i=0; i<SQLITE_SHM_NLOCK;i++){
+ if( (1<<i) & p->pRbu->mLock ){
+ xShmLock(p->pReal, i, 1, SQLITE_SHM_UNLOCK|SQLITE_SHM_EXCLUSIVE);
+ }
+ }
+ p->pRbu->mLock = 0;
+ }
+}
+
+/*
+** Close an rbu file.
+*/
+static int rbuVfsClose(sqlite3_file *pFile){
+ rbu_file *p = (rbu_file*)pFile;
+ int rc;
+ int i;
+
+ /* Free the contents of the apShm[] array. And the array itself. */
+ for(i=0; i<p->nShm; i++){
+ sqlite3_free(p->apShm[i]);
+ }
+ sqlite3_free(p->apShm);
+ p->apShm = 0;
+ sqlite3_free(p->zDel);
+
+ if( p->openFlags & SQLITE_OPEN_MAIN_DB ){
+ rbu_file **pp;
+ sqlite3_mutex_enter(p->pRbuVfs->mutex);
+ for(pp=&p->pRbuVfs->pMain; *pp!=p; pp=&((*pp)->pMainNext));
+ *pp = p->pMainNext;
+ sqlite3_mutex_leave(p->pRbuVfs->mutex);
+ rbuUnlockShm(p);
+ p->pReal->pMethods->xShmUnmap(p->pReal, 0);
+ }
+
+ /* Close the underlying file handle */
+ rc = p->pReal->pMethods->xClose(p->pReal);
+ return rc;
+}
+
+
+/*
+** Read and return an unsigned 32-bit big-endian integer from the buffer
+** passed as the only argument.
+*/
+static u32 rbuGetU32(u8 *aBuf){
+ return ((u32)aBuf[0] << 24)
+ + ((u32)aBuf[1] << 16)
+ + ((u32)aBuf[2] << 8)
+ + ((u32)aBuf[3]);
+}
+
+/*
+** Read data from an rbuVfs-file.
+*/
+static int rbuVfsRead(
+ sqlite3_file *pFile,
+ void *zBuf,
+ int iAmt,
+ sqlite_int64 iOfst
+){
+ rbu_file *p = (rbu_file*)pFile;
+ sqlite3rbu *pRbu = p->pRbu;
+ int rc;
+
+ if( pRbu && pRbu->eStage==RBU_STAGE_CAPTURE ){
+ assert( p->openFlags & SQLITE_OPEN_WAL );
+ rc = rbuCaptureWalRead(p->pRbu, iOfst, iAmt);
+ }else{
+ if( pRbu && pRbu->eStage==RBU_STAGE_OAL
+ && (p->openFlags & SQLITE_OPEN_WAL)
+ && iOfst>=pRbu->iOalSz
+ ){
+ rc = SQLITE_OK;
+ memset(zBuf, 0, iAmt);
+ }else{
+ rc = p->pReal->pMethods->xRead(p->pReal, zBuf, iAmt, iOfst);
+ }
+ if( rc==SQLITE_OK && iOfst==0 && (p->openFlags & SQLITE_OPEN_MAIN_DB) ){
+ /* These look like magic numbers. But they are stable, as they are part
+ ** of the definition of the SQLite file format, which may not change. */
+ u8 *pBuf = (u8*)zBuf;
+ p->iCookie = rbuGetU32(&pBuf[24]);
+ p->iWriteVer = pBuf[19];
+ }
+ }
+ return rc;
+}
+
+/*
+** Write data to an rbuVfs-file.
+*/
+static int rbuVfsWrite(
+ sqlite3_file *pFile,
+ const void *zBuf,
+ int iAmt,
+ sqlite_int64 iOfst
+){
+ rbu_file *p = (rbu_file*)pFile;
+ sqlite3rbu *pRbu = p->pRbu;
+ int rc;
+
+ if( pRbu && pRbu->eStage==RBU_STAGE_CAPTURE ){
+ assert( p->openFlags & SQLITE_OPEN_MAIN_DB );
+ rc = rbuCaptureDbWrite(p->pRbu, iOfst);
+ }else{
+ if( pRbu && pRbu->eStage==RBU_STAGE_OAL
+ && (p->openFlags & SQLITE_OPEN_WAL)
+ && iOfst>=pRbu->iOalSz
+ ){
+ pRbu->iOalSz = iAmt + iOfst;
+ }
+ rc = p->pReal->pMethods->xWrite(p->pReal, zBuf, iAmt, iOfst);
+ if( rc==SQLITE_OK && iOfst==0 && (p->openFlags & SQLITE_OPEN_MAIN_DB) ){
+ /* These look like magic numbers. But they are stable, as they are part
+ ** of the definition of the SQLite file format, which may not change. */
+ u8 *pBuf = (u8*)zBuf;
+ p->iCookie = rbuGetU32(&pBuf[24]);
+ p->iWriteVer = pBuf[19];
+ }
+ }
+ return rc;
+}
+
+/*
+** Truncate an rbuVfs-file.
+*/
+static int rbuVfsTruncate(sqlite3_file *pFile, sqlite_int64 size){
+ rbu_file *p = (rbu_file*)pFile;
+ return p->pReal->pMethods->xTruncate(p->pReal, size);
+}
+
+/*
+** Sync an rbuVfs-file.
+*/
+static int rbuVfsSync(sqlite3_file *pFile, int flags){
+ rbu_file *p = (rbu_file *)pFile;
+ if( p->pRbu && p->pRbu->eStage==RBU_STAGE_CAPTURE ){
+ if( p->openFlags & SQLITE_OPEN_MAIN_DB ){
+ return SQLITE_INTERNAL;
+ }
+ return SQLITE_OK;
+ }
+ return p->pReal->pMethods->xSync(p->pReal, flags);
+}
+
+/*
+** Return the current file-size of an rbuVfs-file.
+*/
+static int rbuVfsFileSize(sqlite3_file *pFile, sqlite_int64 *pSize){
+ rbu_file *p = (rbu_file *)pFile;
+ return p->pReal->pMethods->xFileSize(p->pReal, pSize);
+}
+
+/*
+** Lock an rbuVfs-file.
+*/
+static int rbuVfsLock(sqlite3_file *pFile, int eLock){
+ rbu_file *p = (rbu_file*)pFile;
+ sqlite3rbu *pRbu = p->pRbu;
+ int rc = SQLITE_OK;
+
+ assert( p->openFlags & (SQLITE_OPEN_MAIN_DB|SQLITE_OPEN_TEMP_DB) );
+ if( pRbu && eLock==SQLITE_LOCK_EXCLUSIVE && pRbu->eStage!=RBU_STAGE_DONE ){
+ /* Do not allow EXCLUSIVE locks. Preventing SQLite from taking this
+ ** prevents it from checkpointing the database from sqlite3_close(). */
+ rc = SQLITE_BUSY;
+ }else{
+ rc = p->pReal->pMethods->xLock(p->pReal, eLock);
+ }
+
+ return rc;
+}
+
+/*
+** Unlock an rbuVfs-file.
+*/
+static int rbuVfsUnlock(sqlite3_file *pFile, int eLock){
+ rbu_file *p = (rbu_file *)pFile;
+ return p->pReal->pMethods->xUnlock(p->pReal, eLock);
+}
+
+/*
+** Check if another file-handle holds a RESERVED lock on an rbuVfs-file.
+*/
+static int rbuVfsCheckReservedLock(sqlite3_file *pFile, int *pResOut){
+ rbu_file *p = (rbu_file *)pFile;
+ return p->pReal->pMethods->xCheckReservedLock(p->pReal, pResOut);
+}
+
+/*
+** File control method. For custom operations on an rbuVfs-file.
+*/
+static int rbuVfsFileControl(sqlite3_file *pFile, int op, void *pArg){
+ rbu_file *p = (rbu_file *)pFile;
+ int (*xControl)(sqlite3_file*,int,void*) = p->pReal->pMethods->xFileControl;
+ int rc;
+
+ assert( p->openFlags & (SQLITE_OPEN_MAIN_DB|SQLITE_OPEN_TEMP_DB)
+ || p->openFlags & (SQLITE_OPEN_TRANSIENT_DB|SQLITE_OPEN_TEMP_JOURNAL)
+ );
+ if( op==SQLITE_FCNTL_RBU ){
+ sqlite3rbu *pRbu = (sqlite3rbu*)pArg;
+
+ /* First try to find another RBU vfs lower down in the vfs stack. If
+ ** one is found, this vfs will operate in pass-through mode. The lower
+ ** level vfs will do the special RBU handling. */
+ rc = xControl(p->pReal, op, pArg);
+
+ if( rc==SQLITE_NOTFOUND ){
+ /* Now search for a zipvfs instance lower down in the VFS stack. If
+ ** one is found, this is an error. */
+ void *dummy = 0;
+ rc = xControl(p->pReal, SQLITE_FCNTL_ZIPVFS, &dummy);
+ if( rc==SQLITE_OK ){
+ rc = SQLITE_ERROR;
+ pRbu->zErrmsg = sqlite3_mprintf("rbu/zipvfs setup error");
+ }else if( rc==SQLITE_NOTFOUND ){
+ pRbu->pTargetFd = p;
+ p->pRbu = pRbu;
+ if( p->pWalFd ) p->pWalFd->pRbu = pRbu;
+ rc = SQLITE_OK;
+ }
+ }
+ return rc;
+ }
+
+ rc = xControl(p->pReal, op, pArg);
+ if( rc==SQLITE_OK && op==SQLITE_FCNTL_VFSNAME ){
+ rbu_vfs *pRbuVfs = p->pRbuVfs;
+ char *zIn = *(char**)pArg;
+ char *zOut = sqlite3_mprintf("rbu(%s)/%z", pRbuVfs->base.zName, zIn);
+ *(char**)pArg = zOut;
+ if( zOut==0 ) rc = SQLITE_NOMEM;
+ }
+
+ return rc;
+}
+
+/*
+** Return the sector-size in bytes for an rbuVfs-file.
+*/
+static int rbuVfsSectorSize(sqlite3_file *pFile){
+ rbu_file *p = (rbu_file *)pFile;
+ return p->pReal->pMethods->xSectorSize(p->pReal);
+}
+
+/*
+** Return the device characteristic flags supported by an rbuVfs-file.
+*/
+static int rbuVfsDeviceCharacteristics(sqlite3_file *pFile){
+ rbu_file *p = (rbu_file *)pFile;
+ return p->pReal->pMethods->xDeviceCharacteristics(p->pReal);
+}
+
+/*
+** Take or release a shared-memory lock.
+*/
+static int rbuVfsShmLock(sqlite3_file *pFile, int ofst, int n, int flags){
+ rbu_file *p = (rbu_file*)pFile;
+ sqlite3rbu *pRbu = p->pRbu;
+ int rc = SQLITE_OK;
+
+#ifdef SQLITE_AMALGAMATION
+ assert( WAL_CKPT_LOCK==1 );
+#endif
+
+ assert( p->openFlags & (SQLITE_OPEN_MAIN_DB|SQLITE_OPEN_TEMP_DB) );
+ if( pRbu && (pRbu->eStage==RBU_STAGE_OAL || pRbu->eStage==RBU_STAGE_MOVE) ){
+ /* Magic number 1 is the WAL_CKPT_LOCK lock. Preventing SQLite from
+ ** taking this lock also prevents any checkpoints from occurring.
+ ** todo: really, it's not clear why this might occur, as
+ ** wal_autocheckpoint ought to be turned off. */
+ if( ofst==WAL_LOCK_CKPT && n==1 ) rc = SQLITE_BUSY;
+ }else{
+ int bCapture = 0;
+ if( n==1 && (flags & SQLITE_SHM_EXCLUSIVE)
+ && pRbu && pRbu->eStage==RBU_STAGE_CAPTURE
+ && (ofst==WAL_LOCK_WRITE || ofst==WAL_LOCK_CKPT || ofst==WAL_LOCK_READ0)
+ ){
+ bCapture = 1;
+ }
+
+ if( bCapture==0 || 0==(flags & SQLITE_SHM_UNLOCK) ){
+ rc = p->pReal->pMethods->xShmLock(p->pReal, ofst, n, flags);
+ if( bCapture && rc==SQLITE_OK ){
+ pRbu->mLock |= (1 << ofst);
+ }
+ }
+ }
+
+ return rc;
+}
+
+/*
+** Obtain a pointer to a mapping of a single 32KiB page of the *-shm file.
+*/
+static int rbuVfsShmMap(
+ sqlite3_file *pFile,
+ int iRegion,
+ int szRegion,
+ int isWrite,
+ void volatile **pp
+){
+ rbu_file *p = (rbu_file*)pFile;
+ int rc = SQLITE_OK;
+ int eStage = (p->pRbu ? p->pRbu->eStage : 0);
+
+ /* If not in RBU_STAGE_OAL, allow this call to pass through. Or, if this
+ ** rbu is in the RBU_STAGE_OAL state, use heap memory for *-shm space
+ ** instead of a file on disk. */
+ assert( p->openFlags & (SQLITE_OPEN_MAIN_DB|SQLITE_OPEN_TEMP_DB) );
+ if( eStage==RBU_STAGE_OAL || eStage==RBU_STAGE_MOVE ){
+ if( iRegion<=p->nShm ){
+ int nByte = (iRegion+1) * sizeof(char*);
+ char **apNew = (char**)sqlite3_realloc(p->apShm, nByte);
+ if( apNew==0 ){
+ rc = SQLITE_NOMEM;
+ }else{
+ memset(&apNew[p->nShm], 0, sizeof(char*) * (1 + iRegion - p->nShm));
+ p->apShm = apNew;
+ p->nShm = iRegion+1;
+ }
+ }
+
+ if( rc==SQLITE_OK && p->apShm[iRegion]==0 ){
+ char *pNew = (char*)sqlite3_malloc(szRegion);
+ if( pNew==0 ){
+ rc = SQLITE_NOMEM;
+ }else{
+ memset(pNew, 0, szRegion);
+ p->apShm[iRegion] = pNew;
+ }
+ }
+
+ if( rc==SQLITE_OK ){
+ *pp = p->apShm[iRegion];
+ }else{
+ *pp = 0;
+ }
+ }else{
+ assert( p->apShm==0 );
+ rc = p->pReal->pMethods->xShmMap(p->pReal, iRegion, szRegion, isWrite, pp);
+ }
+
+ return rc;
+}
+
+/*
+** Memory barrier.
+*/
+static void rbuVfsShmBarrier(sqlite3_file *pFile){
+ rbu_file *p = (rbu_file *)pFile;
+ p->pReal->pMethods->xShmBarrier(p->pReal);
+}
+
+/*
+** The xShmUnmap method.
+*/
+static int rbuVfsShmUnmap(sqlite3_file *pFile, int delFlag){
+ rbu_file *p = (rbu_file*)pFile;
+ int rc = SQLITE_OK;
+ int eStage = (p->pRbu ? p->pRbu->eStage : 0);
+
+ assert( p->openFlags & (SQLITE_OPEN_MAIN_DB|SQLITE_OPEN_TEMP_DB) );
+ if( eStage==RBU_STAGE_OAL || eStage==RBU_STAGE_MOVE ){
+ /* no-op */
+ }else{
+ /* Release the checkpointer and writer locks */
+ rbuUnlockShm(p);
+ rc = p->pReal->pMethods->xShmUnmap(p->pReal, delFlag);
+ }
+ return rc;
+}
+
+/*
+** Given that zWal points to a buffer containing a wal file name passed to
+** either the xOpen() or xAccess() VFS method, return a pointer to the
+** file-handle opened by the same database connection on the corresponding
+** database file.
+*/
+static rbu_file *rbuFindMaindb(rbu_vfs *pRbuVfs, const char *zWal){
+ rbu_file *pDb;
+ sqlite3_mutex_enter(pRbuVfs->mutex);
+ for(pDb=pRbuVfs->pMain; pDb && pDb->zWal!=zWal; pDb=pDb->pMainNext);
+ sqlite3_mutex_leave(pRbuVfs->mutex);
+ return pDb;
+}
+
+/*
+** Open an rbu file handle.
+*/
+static int rbuVfsOpen(
+ sqlite3_vfs *pVfs,
+ const char *zName,
+ sqlite3_file *pFile,
+ int flags,
+ int *pOutFlags
+){
+ static sqlite3_io_methods rbuvfs_io_methods = {
+ 2, /* iVersion */
+ rbuVfsClose, /* xClose */
+ rbuVfsRead, /* xRead */
+ rbuVfsWrite, /* xWrite */
+ rbuVfsTruncate, /* xTruncate */
+ rbuVfsSync, /* xSync */
+ rbuVfsFileSize, /* xFileSize */
+ rbuVfsLock, /* xLock */
+ rbuVfsUnlock, /* xUnlock */
+ rbuVfsCheckReservedLock, /* xCheckReservedLock */
+ rbuVfsFileControl, /* xFileControl */
+ rbuVfsSectorSize, /* xSectorSize */
+ rbuVfsDeviceCharacteristics, /* xDeviceCharacteristics */
+ rbuVfsShmMap, /* xShmMap */
+ rbuVfsShmLock, /* xShmLock */
+ rbuVfsShmBarrier, /* xShmBarrier */
+ rbuVfsShmUnmap, /* xShmUnmap */
+ 0, 0 /* xFetch, xUnfetch */
+ };
+ rbu_vfs *pRbuVfs = (rbu_vfs*)pVfs;
+ sqlite3_vfs *pRealVfs = pRbuVfs->pRealVfs;
+ rbu_file *pFd = (rbu_file *)pFile;
+ int rc = SQLITE_OK;
+ const char *zOpen = zName;
+
+ memset(pFd, 0, sizeof(rbu_file));
+ pFd->pReal = (sqlite3_file*)&pFd[1];
+ pFd->pRbuVfs = pRbuVfs;
+ pFd->openFlags = flags;
+ if( zName ){
+ if( flags & SQLITE_OPEN_MAIN_DB ){
+ /* A main database has just been opened. The following block sets
+ ** (pFd->zWal) to point to a buffer owned by SQLite that contains
+ ** the name of the *-wal file this db connection will use. SQLite
+ ** happens to pass a pointer to this buffer when using xAccess()
+ ** or xOpen() to operate on the *-wal file. */
+ int n = strlen(zName);
+ const char *z = &zName[n];
+ if( flags & SQLITE_OPEN_URI ){
+ int odd = 0;
+ while( 1 ){
+ if( z[0]==0 ){
+ odd = 1 - odd;
+ if( odd && z[1]==0 ) break;
+ }
+ z++;
+ }
+ z += 2;
+ }else{
+ while( *z==0 ) z++;
+ }
+ z += (n + 8 + 1);
+ pFd->zWal = z;
+ }
+ else if( flags & SQLITE_OPEN_WAL ){
+ rbu_file *pDb = rbuFindMaindb(pRbuVfs, zName);
+ if( pDb ){
+ if( pDb->pRbu && pDb->pRbu->eStage==RBU_STAGE_OAL ){
+ /* This call is to open a *-wal file. Intead, open the *-oal. This
+ ** code ensures that the string passed to xOpen() is terminated by a
+ ** pair of '\0' bytes in case the VFS attempts to extract a URI
+ ** parameter from it. */
+ int nCopy = strlen(zName);
+ char *zCopy = sqlite3_malloc(nCopy+2);
+ if( zCopy ){
+ memcpy(zCopy, zName, nCopy);
+ zCopy[nCopy-3] = 'o';
+ zCopy[nCopy] = '\0';
+ zCopy[nCopy+1] = '\0';
+ zOpen = (const char*)(pFd->zDel = zCopy);
+ }else{
+ rc = SQLITE_NOMEM;
+ }
+ pFd->pRbu = pDb->pRbu;
+ }
+ pDb->pWalFd = pFd;
+ }
+ }
+ }
+
+ if( rc==SQLITE_OK ){
+ rc = pRealVfs->xOpen(pRealVfs, zOpen, pFd->pReal, flags, pOutFlags);
+ }
+ if( pFd->pReal->pMethods ){
+ /* The xOpen() operation has succeeded. Set the sqlite3_file.pMethods
+ ** pointer and, if the file is a main database file, link it into the
+ ** mutex protected linked list of all such files. */
+ pFile->pMethods = &rbuvfs_io_methods;
+ if( flags & SQLITE_OPEN_MAIN_DB ){
+ sqlite3_mutex_enter(pRbuVfs->mutex);
+ pFd->pMainNext = pRbuVfs->pMain;
+ pRbuVfs->pMain = pFd;
+ sqlite3_mutex_leave(pRbuVfs->mutex);
+ }
+ }else{
+ sqlite3_free(pFd->zDel);
+ }
+
+ return rc;
+}
+
+/*
+** Delete the file located at zPath.
+*/
+static int rbuVfsDelete(sqlite3_vfs *pVfs, const char *zPath, int dirSync){
+ sqlite3_vfs *pRealVfs = ((rbu_vfs*)pVfs)->pRealVfs;
+ return pRealVfs->xDelete(pRealVfs, zPath, dirSync);
+}
+
+/*
+** Test for access permissions. Return true if the requested permission
+** is available, or false otherwise.
+*/
+static int rbuVfsAccess(
+ sqlite3_vfs *pVfs,
+ const char *zPath,
+ int flags,
+ int *pResOut
+){
+ rbu_vfs *pRbuVfs = (rbu_vfs*)pVfs;
+ sqlite3_vfs *pRealVfs = pRbuVfs->pRealVfs;
+ int rc;
+
+ rc = pRealVfs->xAccess(pRealVfs, zPath, flags, pResOut);
+
+ /* If this call is to check if a *-wal file associated with an RBU target
+ ** database connection exists, and the RBU update is in RBU_STAGE_OAL,
+ ** the following special handling is activated:
+ **
+ ** a) if the *-wal file does exist, return SQLITE_CANTOPEN. This
+ ** ensures that the RBU extension never tries to update a database
+ ** in wal mode, even if the first page of the database file has
+ ** been damaged.
+ **
+ ** b) if the *-wal file does not exist, claim that it does anyway,
+ ** causing SQLite to call xOpen() to open it. This call will also
+ ** be intercepted (see the rbuVfsOpen() function) and the *-oal
+ ** file opened instead.
+ */
+ if( rc==SQLITE_OK && flags==SQLITE_ACCESS_EXISTS ){
+ rbu_file *pDb = rbuFindMaindb(pRbuVfs, zPath);
+ if( pDb && pDb->pRbu && pDb->pRbu->eStage==RBU_STAGE_OAL ){
+ if( *pResOut ){
+ rc = SQLITE_CANTOPEN;
+ }else{
+ *pResOut = 1;
+ }
+ }
+ }
+
+ return rc;
+}
+
+/*
+** Populate buffer zOut with the full canonical pathname corresponding
+** to the pathname in zPath. zOut is guaranteed to point to a buffer
+** of at least (DEVSYM_MAX_PATHNAME+1) bytes.
+*/
+static int rbuVfsFullPathname(
+ sqlite3_vfs *pVfs,
+ const char *zPath,
+ int nOut,
+ char *zOut
+){
+ sqlite3_vfs *pRealVfs = ((rbu_vfs*)pVfs)->pRealVfs;
+ return pRealVfs->xFullPathname(pRealVfs, zPath, nOut, zOut);
+}
+
+#ifndef SQLITE_OMIT_LOAD_EXTENSION
+/*
+** Open the dynamic library located at zPath and return a handle.
+*/
+static void *rbuVfsDlOpen(sqlite3_vfs *pVfs, const char *zPath){
+ sqlite3_vfs *pRealVfs = ((rbu_vfs*)pVfs)->pRealVfs;
+ return pRealVfs->xDlOpen(pRealVfs, zPath);
+}
+
+/*
+** Populate the buffer zErrMsg (size nByte bytes) with a human readable
+** utf-8 string describing the most recent error encountered associated
+** with dynamic libraries.
+*/
+static void rbuVfsDlError(sqlite3_vfs *pVfs, int nByte, char *zErrMsg){
+ sqlite3_vfs *pRealVfs = ((rbu_vfs*)pVfs)->pRealVfs;
+ pRealVfs->xDlError(pRealVfs, nByte, zErrMsg);
+}
+
+/*
+** Return a pointer to the symbol zSymbol in the dynamic library pHandle.
+*/
+static void (*rbuVfsDlSym(
+ sqlite3_vfs *pVfs,
+ void *pArg,
+ const char *zSym
+))(void){
+ sqlite3_vfs *pRealVfs = ((rbu_vfs*)pVfs)->pRealVfs;
+ return pRealVfs->xDlSym(pRealVfs, pArg, zSym);
+}
+
+/*
+** Close the dynamic library handle pHandle.
+*/
+static void rbuVfsDlClose(sqlite3_vfs *pVfs, void *pHandle){
+ sqlite3_vfs *pRealVfs = ((rbu_vfs*)pVfs)->pRealVfs;
+ pRealVfs->xDlClose(pRealVfs, pHandle);
+}
+#endif /* SQLITE_OMIT_LOAD_EXTENSION */
+
+/*
+** Populate the buffer pointed to by zBufOut with nByte bytes of
+** random data.
+*/
+static int rbuVfsRandomness(sqlite3_vfs *pVfs, int nByte, char *zBufOut){
+ sqlite3_vfs *pRealVfs = ((rbu_vfs*)pVfs)->pRealVfs;
+ return pRealVfs->xRandomness(pRealVfs, nByte, zBufOut);
+}
+
+/*
+** Sleep for nMicro microseconds. Return the number of microseconds
+** actually slept.
+*/
+static int rbuVfsSleep(sqlite3_vfs *pVfs, int nMicro){
+ sqlite3_vfs *pRealVfs = ((rbu_vfs*)pVfs)->pRealVfs;
+ return pRealVfs->xSleep(pRealVfs, nMicro);
+}
+
+/*
+** Return the current time as a Julian Day number in *pTimeOut.
+*/
+static int rbuVfsCurrentTime(sqlite3_vfs *pVfs, double *pTimeOut){
+ sqlite3_vfs *pRealVfs = ((rbu_vfs*)pVfs)->pRealVfs;
+ return pRealVfs->xCurrentTime(pRealVfs, pTimeOut);
+}
+
+/*
+** No-op.
+*/
+static int rbuVfsGetLastError(sqlite3_vfs *pVfs, int a, char *b){
+ return 0;
+}
+
+/*
+** Deregister and destroy an RBU vfs created by an earlier call to
+** sqlite3rbu_create_vfs().
+*/
+SQLITE_API void SQLITE_STDCALL sqlite3rbu_destroy_vfs(const char *zName){
+ sqlite3_vfs *pVfs = sqlite3_vfs_find(zName);
+ if( pVfs && pVfs->xOpen==rbuVfsOpen ){
+ sqlite3_mutex_free(((rbu_vfs*)pVfs)->mutex);
+ sqlite3_vfs_unregister(pVfs);
+ sqlite3_free(pVfs);
+ }
+}
+
+/*
+** Create an RBU VFS named zName that accesses the underlying file-system
+** via existing VFS zParent. The new object is registered as a non-default
+** VFS with SQLite before returning.
+*/
+SQLITE_API int SQLITE_STDCALL sqlite3rbu_create_vfs(const char *zName, const char *zParent){
+
+ /* Template for VFS */
+ static sqlite3_vfs vfs_template = {
+ 1, /* iVersion */
+ 0, /* szOsFile */
+ 0, /* mxPathname */
+ 0, /* pNext */
+ 0, /* zName */
+ 0, /* pAppData */
+ rbuVfsOpen, /* xOpen */
+ rbuVfsDelete, /* xDelete */
+ rbuVfsAccess, /* xAccess */
+ rbuVfsFullPathname, /* xFullPathname */
+
+#ifndef SQLITE_OMIT_LOAD_EXTENSION
+ rbuVfsDlOpen, /* xDlOpen */
+ rbuVfsDlError, /* xDlError */
+ rbuVfsDlSym, /* xDlSym */
+ rbuVfsDlClose, /* xDlClose */
+#else
+ 0, 0, 0, 0,
+#endif
+
+ rbuVfsRandomness, /* xRandomness */
+ rbuVfsSleep, /* xSleep */
+ rbuVfsCurrentTime, /* xCurrentTime */
+ rbuVfsGetLastError, /* xGetLastError */
+ 0, /* xCurrentTimeInt64 (version 2) */
+ 0, 0, 0 /* Unimplemented version 3 methods */
+ };
+
+ rbu_vfs *pNew = 0; /* Newly allocated VFS */
+ int nName;
+ int rc = SQLITE_OK;
+
+ int nByte;
+ nName = strlen(zName);
+ nByte = sizeof(rbu_vfs) + nName + 1;
+ pNew = (rbu_vfs*)sqlite3_malloc(nByte);
+ if( pNew==0 ){
+ rc = SQLITE_NOMEM;
+ }else{
+ sqlite3_vfs *pParent; /* Parent VFS */
+ memset(pNew, 0, nByte);
+ pParent = sqlite3_vfs_find(zParent);
+ if( pParent==0 ){
+ rc = SQLITE_NOTFOUND;
+ }else{
+ char *zSpace;
+ memcpy(&pNew->base, &vfs_template, sizeof(sqlite3_vfs));
+ pNew->base.mxPathname = pParent->mxPathname;
+ pNew->base.szOsFile = sizeof(rbu_file) + pParent->szOsFile;
+ pNew->pRealVfs = pParent;
+ pNew->base.zName = (const char*)(zSpace = (char*)&pNew[1]);
+ memcpy(zSpace, zName, nName);
+
+ /* Allocate the mutex and register the new VFS (not as the default) */
+ pNew->mutex = sqlite3_mutex_alloc(SQLITE_MUTEX_RECURSIVE);
+ if( pNew->mutex==0 ){
+ rc = SQLITE_NOMEM;
+ }else{
+ rc = sqlite3_vfs_register(&pNew->base, 0);
+ }
+ }
+
+ if( rc!=SQLITE_OK ){
+ sqlite3_mutex_free(pNew->mutex);
+ sqlite3_free(pNew);
+ }
+ }
+
+ return rc;
+}
+
+
+/**************************************************************************/
+
+#endif /* !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_RBU) */
+
+/************** End of sqlite3rbu.c ******************************************/
+/************** Begin file dbstat.c ******************************************/
+/*
+** 2010 July 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.
+**
+******************************************************************************
+**
+** This file contains an implementation of the "dbstat" virtual table.
+**
+** The dbstat virtual table is used to extract low-level formatting
+** information from an SQLite database in order to implement the
+** "sqlite3_analyzer" utility. See the ../tool/spaceanal.tcl script
+** for an example implementation.
+**
+** Additional information is available on the "dbstat.html" page of the
+** official SQLite documentation.
+*/
+
+/* #include "sqliteInt.h" ** Requires access to internal data structures ** */
+#if (defined(SQLITE_ENABLE_DBSTAT_VTAB) || defined(SQLITE_TEST)) \
+ && !defined(SQLITE_OMIT_VIRTUALTABLE)
+
+/*
+** Page paths:
+**
+** The value of the 'path' column describes the path taken from the
+** root-node of the b-tree structure to each page. The value of the
+** root-node path is '/'.
+**
+** The value of the path for the left-most child page of the root of
+** a b-tree is '/000/'. (Btrees store content ordered from left to right
+** so the pages to the left have smaller keys than the pages to the right.)
+** The next to left-most child of the root page is
+** '/001', and so on, each sibling page identified by a 3-digit hex
+** value. The children of the 451st left-most sibling have paths such
+** as '/1c2/000/, '/1c2/001/' etc.
+**
+** Overflow pages are specified by appending a '+' character and a
+** six-digit hexadecimal value to the path to the cell they are linked
+** from. For example, the three overflow pages in a chain linked from
+** the left-most cell of the 450th child of the root page are identified
+** by the paths:
+**
+** '/1c2/000+000000' // First page in overflow chain
+** '/1c2/000+000001' // Second page in overflow chain
+** '/1c2/000+000002' // Third page in overflow chain
+**
+** If the paths are sorted using the BINARY collation sequence, then
+** the overflow pages associated with a cell will appear earlier in the
+** sort-order than its child page:
+**
+** '/1c2/000/' // Left-most child of 451st child of root
+*/
+#define VTAB_SCHEMA \
+ "CREATE TABLE xx( " \
+ " name STRING, /* Name of table or index */" \
+ " path INTEGER, /* Path to page from root */" \
+ " pageno INTEGER, /* Page number */" \
+ " pagetype STRING, /* 'internal', 'leaf' or 'overflow' */" \
+ " ncell INTEGER, /* Cells on page (0 for overflow) */" \
+ " payload INTEGER, /* Bytes of payload on this page */" \
+ " unused INTEGER, /* Bytes of unused space on this page */" \
+ " mx_payload INTEGER, /* Largest payload size of all cells */" \
+ " pgoffset INTEGER, /* Offset of page in file */" \
+ " pgsize INTEGER, /* Size of the page */" \
+ " schema TEXT HIDDEN /* Database schema being analyzed */" \
+ ");"
+
+
+typedef struct StatTable StatTable;
+typedef struct StatCursor StatCursor;
+typedef struct StatPage StatPage;
+typedef struct StatCell StatCell;
+
+struct StatCell {
+ int nLocal; /* Bytes of local payload */
+ u32 iChildPg; /* Child node (or 0 if this is a leaf) */
+ int nOvfl; /* Entries in aOvfl[] */
+ u32 *aOvfl; /* Array of overflow page numbers */
+ int nLastOvfl; /* Bytes of payload on final overflow page */
+ int iOvfl; /* Iterates through aOvfl[] */
+};
+
+struct StatPage {
+ u32 iPgno;
+ DbPage *pPg;
+ int iCell;
+
+ char *zPath; /* Path to this page */
+
+ /* Variables populated by statDecodePage(): */
+ u8 flags; /* Copy of flags byte */
+ int nCell; /* Number of cells on page */
+ int nUnused; /* Number of unused bytes on page */
+ StatCell *aCell; /* Array of parsed cells */
+ u32 iRightChildPg; /* Right-child page number (or 0) */
+ int nMxPayload; /* Largest payload of any cell on this page */
+};
+
+struct StatCursor {
+ sqlite3_vtab_cursor base;
+ sqlite3_stmt *pStmt; /* Iterates through set of root pages */
+ int isEof; /* After pStmt has returned SQLITE_DONE */
+ int iDb; /* Schema used for this query */
+
+ StatPage aPage[32];
+ int iPage; /* Current entry in aPage[] */
+
+ /* Values to return. */
+ char *zName; /* Value of 'name' column */
+ char *zPath; /* Value of 'path' column */
+ u32 iPageno; /* Value of 'pageno' column */
+ char *zPagetype; /* Value of 'pagetype' column */
+ int nCell; /* Value of 'ncell' column */
+ int nPayload; /* Value of 'payload' column */
+ int nUnused; /* Value of 'unused' column */
+ int nMxPayload; /* Value of 'mx_payload' column */
+ i64 iOffset; /* Value of 'pgOffset' column */
+ int szPage; /* Value of 'pgSize' column */
+};
+
+struct StatTable {
+ sqlite3_vtab base;
+ sqlite3 *db;
+ int iDb; /* Index of database to analyze */
+};
+
+#ifndef get2byte
+# define get2byte(x) ((x)[0]<<8 | (x)[1])
+#endif
+
+/*
+** Connect to or create a statvfs virtual table.
+*/
+static int statConnect(
+ sqlite3 *db,
+ void *pAux,
+ int argc, const char *const*argv,
+ sqlite3_vtab **ppVtab,
+ char **pzErr
+){
+ StatTable *pTab = 0;
+ int rc = SQLITE_OK;
+ int iDb;
+
+ if( argc>=4 ){
+ iDb = sqlite3FindDbName(db, argv[3]);
+ if( iDb<0 ){
+ *pzErr = sqlite3_mprintf("no such database: %s", argv[3]);
+ return SQLITE_ERROR;
+ }
+ }else{
+ iDb = 0;
+ }
+ rc = sqlite3_declare_vtab(db, VTAB_SCHEMA);
+ if( rc==SQLITE_OK ){
+ pTab = (StatTable *)sqlite3_malloc64(sizeof(StatTable));
+ if( pTab==0 ) rc = SQLITE_NOMEM;
+ }
+
+ assert( rc==SQLITE_OK || pTab==0 );
+ if( rc==SQLITE_OK ){
+ memset(pTab, 0, sizeof(StatTable));
+ pTab->db = db;
+ pTab->iDb = iDb;
+ }
+
+ *ppVtab = (sqlite3_vtab*)pTab;
+ return rc;
+}
+
+/*
+** Disconnect from or destroy a statvfs virtual table.
+*/
+static int statDisconnect(sqlite3_vtab *pVtab){
+ sqlite3_free(pVtab);
+ return SQLITE_OK;
+}
+
+/*
+** There is no "best-index". This virtual table always does a linear
+** scan. However, a schema=? constraint should cause this table to
+** operate on a different database schema, so check for it.
+**
+** idxNum is normally 0, but will be 1 if a schema=? constraint exists.
+*/
+static int statBestIndex(sqlite3_vtab *tab, sqlite3_index_info *pIdxInfo){
+ int i;
+
+ pIdxInfo->estimatedCost = 1.0e6; /* Initial cost estimate */
+
+ /* Look for a valid schema=? constraint. If found, change the idxNum to
+ ** 1 and request the value of that constraint be sent to xFilter. And
+ ** lower the cost estimate to encourage the constrained version to be
+ ** used.
+ */
+ for(i=0; i<pIdxInfo->nConstraint; i++){
+ if( pIdxInfo->aConstraint[i].usable==0 ) continue;
+ if( pIdxInfo->aConstraint[i].op!=SQLITE_INDEX_CONSTRAINT_EQ ) continue;
+ if( pIdxInfo->aConstraint[i].iColumn!=10 ) continue;
+ pIdxInfo->idxNum = 1;
+ pIdxInfo->estimatedCost = 1.0;
+ pIdxInfo->aConstraintUsage[i].argvIndex = 1;
+ pIdxInfo->aConstraintUsage[i].omit = 1;
+ break;
+ }
+
+
+ /* Records are always returned in ascending order of (name, path).
+ ** If this will satisfy the client, set the orderByConsumed flag so that
+ ** SQLite does not do an external sort.
+ */
+ if( ( pIdxInfo->nOrderBy==1
+ && pIdxInfo->aOrderBy[0].iColumn==0
+ && pIdxInfo->aOrderBy[0].desc==0
+ ) ||
+ ( pIdxInfo->nOrderBy==2
+ && pIdxInfo->aOrderBy[0].iColumn==0
+ && pIdxInfo->aOrderBy[0].desc==0
+ && pIdxInfo->aOrderBy[1].iColumn==1
+ && pIdxInfo->aOrderBy[1].desc==0
+ )
+ ){
+ pIdxInfo->orderByConsumed = 1;
+ }
+
+ return SQLITE_OK;
+}
+
+/*
+** Open a new statvfs cursor.
+*/
+static int statOpen(sqlite3_vtab *pVTab, sqlite3_vtab_cursor **ppCursor){
+ StatTable *pTab = (StatTable *)pVTab;
+ StatCursor *pCsr;
+
+ pCsr = (StatCursor *)sqlite3_malloc64(sizeof(StatCursor));
+ if( pCsr==0 ){
+ return SQLITE_NOMEM;
+ }else{
+ memset(pCsr, 0, sizeof(StatCursor));
+ pCsr->base.pVtab = pVTab;
+ pCsr->iDb = pTab->iDb;
+ }
+
+ *ppCursor = (sqlite3_vtab_cursor *)pCsr;
+ return SQLITE_OK;
+}
+
+static void statClearPage(StatPage *p){
+ int i;
+ if( p->aCell ){
+ for(i=0; i<p->nCell; i++){
+ sqlite3_free(p->aCell[i].aOvfl);
+ }
+ sqlite3_free(p->aCell);
+ }
+ sqlite3PagerUnref(p->pPg);
+ sqlite3_free(p->zPath);
+ memset(p, 0, sizeof(StatPage));
+}
+
+static void statResetCsr(StatCursor *pCsr){
+ int i;
+ sqlite3_reset(pCsr->pStmt);
+ for(i=0; i<ArraySize(pCsr->aPage); i++){
+ statClearPage(&pCsr->aPage[i]);
+ }
+ pCsr->iPage = 0;
+ sqlite3_free(pCsr->zPath);
+ pCsr->zPath = 0;
+ pCsr->isEof = 0;
+}
+
+/*
+** Close a statvfs cursor.
+*/
+static int statClose(sqlite3_vtab_cursor *pCursor){
+ StatCursor *pCsr = (StatCursor *)pCursor;
+ statResetCsr(pCsr);
+ sqlite3_finalize(pCsr->pStmt);
+ sqlite3_free(pCsr);
+ return SQLITE_OK;
+}
+
+static void getLocalPayload(
+ int nUsable, /* Usable bytes per page */
+ u8 flags, /* Page flags */
+ int nTotal, /* Total record (payload) size */
+ int *pnLocal /* OUT: Bytes stored locally */
+){
+ int nLocal;
+ int nMinLocal;
+ int nMaxLocal;
+
+ if( flags==0x0D ){ /* Table leaf node */
+ nMinLocal = (nUsable - 12) * 32 / 255 - 23;
+ nMaxLocal = nUsable - 35;
+ }else{ /* Index interior and leaf nodes */
+ nMinLocal = (nUsable - 12) * 32 / 255 - 23;
+ nMaxLocal = (nUsable - 12) * 64 / 255 - 23;
+ }
+
+ nLocal = nMinLocal + (nTotal - nMinLocal) % (nUsable - 4);
+ if( nLocal>nMaxLocal ) nLocal = nMinLocal;
+ *pnLocal = nLocal;
+}
+
+static int statDecodePage(Btree *pBt, StatPage *p){
+ int nUnused;
+ int iOff;
+ int nHdr;
+ int isLeaf;
+ int szPage;
+
+ u8 *aData = sqlite3PagerGetData(p->pPg);
+ u8 *aHdr = &aData[p->iPgno==1 ? 100 : 0];
+
+ p->flags = aHdr[0];
+ p->nCell = get2byte(&aHdr[3]);
+ p->nMxPayload = 0;
+
+ isLeaf = (p->flags==0x0A || p->flags==0x0D);
+ nHdr = 12 - isLeaf*4 + (p->iPgno==1)*100;
+
+ nUnused = get2byte(&aHdr[5]) - nHdr - 2*p->nCell;
+ nUnused += (int)aHdr[7];
+ iOff = get2byte(&aHdr[1]);
+ while( iOff ){
+ nUnused += get2byte(&aData[iOff+2]);
+ iOff = get2byte(&aData[iOff]);
+ }
+ p->nUnused = nUnused;
+ p->iRightChildPg = isLeaf ? 0 : sqlite3Get4byte(&aHdr[8]);
+ szPage = sqlite3BtreeGetPageSize(pBt);
+
+ if( p->nCell ){
+ int i; /* Used to iterate through cells */
+ int nUsable; /* Usable bytes per page */
+
+ sqlite3BtreeEnter(pBt);
+ nUsable = szPage - sqlite3BtreeGetReserveNoMutex(pBt);
+ sqlite3BtreeLeave(pBt);
+ p->aCell = sqlite3_malloc64((p->nCell+1) * sizeof(StatCell));
+ if( p->aCell==0 ) return SQLITE_NOMEM;
+ memset(p->aCell, 0, (p->nCell+1) * sizeof(StatCell));
+
+ for(i=0; i<p->nCell; i++){
+ StatCell *pCell = &p->aCell[i];
+
+ iOff = get2byte(&aData[nHdr+i*2]);
+ if( !isLeaf ){
+ pCell->iChildPg = sqlite3Get4byte(&aData[iOff]);
+ iOff += 4;
+ }
+ if( p->flags==0x05 ){
+ /* A table interior node. nPayload==0. */
+ }else{
+ u32 nPayload; /* Bytes of payload total (local+overflow) */
+ int nLocal; /* Bytes of payload stored locally */
+ iOff += getVarint32(&aData[iOff], nPayload);
+ if( p->flags==0x0D ){
+ u64 dummy;
+ iOff += sqlite3GetVarint(&aData[iOff], &dummy);
+ }
+ if( nPayload>(u32)p->nMxPayload ) p->nMxPayload = nPayload;
+ getLocalPayload(nUsable, p->flags, nPayload, &nLocal);
+ pCell->nLocal = nLocal;
+ assert( nLocal>=0 );
+ assert( nPayload>=(u32)nLocal );
+ assert( nLocal<=(nUsable-35) );
+ if( nPayload>(u32)nLocal ){
+ int j;
+ int nOvfl = ((nPayload - nLocal) + nUsable-4 - 1) / (nUsable - 4);
+ pCell->nLastOvfl = (nPayload-nLocal) - (nOvfl-1) * (nUsable-4);
+ pCell->nOvfl = nOvfl;
+ pCell->aOvfl = sqlite3_malloc64(sizeof(u32)*nOvfl);
+ if( pCell->aOvfl==0 ) return SQLITE_NOMEM;
+ pCell->aOvfl[0] = sqlite3Get4byte(&aData[iOff+nLocal]);
+ for(j=1; j<nOvfl; j++){
+ int rc;
+ u32 iPrev = pCell->aOvfl[j-1];
+ DbPage *pPg = 0;
+ rc = sqlite3PagerGet(sqlite3BtreePager(pBt), iPrev, &pPg, 0);
+ if( rc!=SQLITE_OK ){
+ assert( pPg==0 );
+ return rc;
+ }
+ pCell->aOvfl[j] = sqlite3Get4byte(sqlite3PagerGetData(pPg));
+ sqlite3PagerUnref(pPg);
+ }
+ }
+ }
+ }
+ }
+
+ return SQLITE_OK;
+}
+
+/*
+** Populate the pCsr->iOffset and pCsr->szPage member variables. Based on
+** the current value of pCsr->iPageno.
+*/
+static void statSizeAndOffset(StatCursor *pCsr){
+ StatTable *pTab = (StatTable *)((sqlite3_vtab_cursor *)pCsr)->pVtab;
+ Btree *pBt = pTab->db->aDb[pTab->iDb].pBt;
+ Pager *pPager = sqlite3BtreePager(pBt);
+ sqlite3_file *fd;
+ sqlite3_int64 x[2];
+
+ /* The default page size and offset */
+ pCsr->szPage = sqlite3BtreeGetPageSize(pBt);
+ pCsr->iOffset = (i64)pCsr->szPage * (pCsr->iPageno - 1);
+
+ /* If connected to a ZIPVFS backend, override the page size and
+ ** offset with actual values obtained from ZIPVFS.
+ */
+ fd = sqlite3PagerFile(pPager);
+ x[0] = pCsr->iPageno;
+ if( fd->pMethods!=0 && sqlite3OsFileControl(fd, 230440, &x)==SQLITE_OK ){
+ pCsr->iOffset = x[0];
+ pCsr->szPage = (int)x[1];
+ }
+}
+
+/*
+** Move a statvfs cursor to the next entry in the file.
+*/
+static int statNext(sqlite3_vtab_cursor *pCursor){
+ int rc;
+ int nPayload;
+ char *z;
+ StatCursor *pCsr = (StatCursor *)pCursor;
+ StatTable *pTab = (StatTable *)pCursor->pVtab;
+ Btree *pBt = pTab->db->aDb[pCsr->iDb].pBt;
+ Pager *pPager = sqlite3BtreePager(pBt);
+
+ sqlite3_free(pCsr->zPath);
+ pCsr->zPath = 0;
+
+statNextRestart:
+ if( pCsr->aPage[0].pPg==0 ){
+ rc = sqlite3_step(pCsr->pStmt);
+ if( rc==SQLITE_ROW ){
+ int nPage;
+ u32 iRoot = (u32)sqlite3_column_int64(pCsr->pStmt, 1);
+ sqlite3PagerPagecount(pPager, &nPage);
+ if( nPage==0 ){
+ pCsr->isEof = 1;
+ return sqlite3_reset(pCsr->pStmt);
+ }
+ rc = sqlite3PagerGet(pPager, iRoot, &pCsr->aPage[0].pPg, 0);
+ pCsr->aPage[0].iPgno = iRoot;
+ pCsr->aPage[0].iCell = 0;
+ pCsr->aPage[0].zPath = z = sqlite3_mprintf("/");
+ pCsr->iPage = 0;
+ if( z==0 ) rc = SQLITE_NOMEM;
+ }else{
+ pCsr->isEof = 1;
+ return sqlite3_reset(pCsr->pStmt);
+ }
+ }else{
+
+ /* Page p itself has already been visited. */
+ StatPage *p = &pCsr->aPage[pCsr->iPage];
+
+ while( p->iCell<p->nCell ){
+ StatCell *pCell = &p->aCell[p->iCell];
+ if( pCell->iOvfl<pCell->nOvfl ){
+ int nUsable;
+ sqlite3BtreeEnter(pBt);
+ nUsable = sqlite3BtreeGetPageSize(pBt) -
+ sqlite3BtreeGetReserveNoMutex(pBt);
+ sqlite3BtreeLeave(pBt);
+ pCsr->zName = (char *)sqlite3_column_text(pCsr->pStmt, 0);
+ pCsr->iPageno = pCell->aOvfl[pCell->iOvfl];
+ pCsr->zPagetype = "overflow";
+ pCsr->nCell = 0;
+ pCsr->nMxPayload = 0;
+ pCsr->zPath = z = sqlite3_mprintf(
+ "%s%.3x+%.6x", p->zPath, p->iCell, pCell->iOvfl
+ );
+ if( pCell->iOvfl<pCell->nOvfl-1 ){
+ pCsr->nUnused = 0;
+ pCsr->nPayload = nUsable - 4;
+ }else{
+ pCsr->nPayload = pCell->nLastOvfl;
+ pCsr->nUnused = nUsable - 4 - pCsr->nPayload;
+ }
+ pCell->iOvfl++;
+ statSizeAndOffset(pCsr);
+ return z==0 ? SQLITE_NOMEM : SQLITE_OK;
+ }
+ if( p->iRightChildPg ) break;
+ p->iCell++;
+ }
+
+ if( !p->iRightChildPg || p->iCell>p->nCell ){
+ statClearPage(p);
+ if( pCsr->iPage==0 ) return statNext(pCursor);
+ pCsr->iPage--;
+ goto statNextRestart; /* Tail recursion */
+ }
+ pCsr->iPage++;
+ assert( p==&pCsr->aPage[pCsr->iPage-1] );
+
+ if( p->iCell==p->nCell ){
+ p[1].iPgno = p->iRightChildPg;
+ }else{
+ p[1].iPgno = p->aCell[p->iCell].iChildPg;
+ }
+ rc = sqlite3PagerGet(pPager, p[1].iPgno, &p[1].pPg, 0);
+ p[1].iCell = 0;
+ p[1].zPath = z = sqlite3_mprintf("%s%.3x/", p->zPath, p->iCell);
+ p->iCell++;
+ if( z==0 ) rc = SQLITE_NOMEM;
+ }
+
+
+ /* Populate the StatCursor fields with the values to be returned
+ ** by the xColumn() and xRowid() methods.
+ */
+ if( rc==SQLITE_OK ){
+ int i;
+ StatPage *p = &pCsr->aPage[pCsr->iPage];
+ pCsr->zName = (char *)sqlite3_column_text(pCsr->pStmt, 0);
+ pCsr->iPageno = p->iPgno;
+
+ rc = statDecodePage(pBt, p);
+ if( rc==SQLITE_OK ){
+ statSizeAndOffset(pCsr);
+
+ switch( p->flags ){
+ case 0x05: /* table internal */
+ case 0x02: /* index internal */
+ pCsr->zPagetype = "internal";
+ break;
+ case 0x0D: /* table leaf */
+ case 0x0A: /* index leaf */
+ pCsr->zPagetype = "leaf";
+ break;
+ default:
+ pCsr->zPagetype = "corrupted";
+ break;
+ }
+ pCsr->nCell = p->nCell;
+ pCsr->nUnused = p->nUnused;
+ pCsr->nMxPayload = p->nMxPayload;
+ pCsr->zPath = z = sqlite3_mprintf("%s", p->zPath);
+ if( z==0 ) rc = SQLITE_NOMEM;
+ nPayload = 0;
+ for(i=0; i<p->nCell; i++){
+ nPayload += p->aCell[i].nLocal;
+ }
+ pCsr->nPayload = nPayload;
+ }
+ }
+
+ return rc;
+}
+
+static int statEof(sqlite3_vtab_cursor *pCursor){
+ StatCursor *pCsr = (StatCursor *)pCursor;
+ return pCsr->isEof;
+}
+
+static int statFilter(
+ sqlite3_vtab_cursor *pCursor,
+ int idxNum, const char *idxStr,
+ int argc, sqlite3_value **argv
+){
+ StatCursor *pCsr = (StatCursor *)pCursor;
+ StatTable *pTab = (StatTable*)(pCursor->pVtab);
+ char *zSql;
+ int rc = SQLITE_OK;
+ char *zMaster;
+
+ if( idxNum==1 ){
+ const char *zDbase = (const char*)sqlite3_value_text(argv[0]);
+ pCsr->iDb = sqlite3FindDbName(pTab->db, zDbase);
+ if( pCsr->iDb<0 ){
+ sqlite3_free(pCursor->pVtab->zErrMsg);
+ pCursor->pVtab->zErrMsg = sqlite3_mprintf("no such schema: %s", zDbase);
+ return pCursor->pVtab->zErrMsg ? SQLITE_ERROR : SQLITE_NOMEM;
+ }
+ }else{
+ pCsr->iDb = pTab->iDb;
+ }
+ statResetCsr(pCsr);
+ sqlite3_finalize(pCsr->pStmt);
+ pCsr->pStmt = 0;
+ zMaster = pCsr->iDb==1 ? "sqlite_temp_master" : "sqlite_master";
+ zSql = sqlite3_mprintf(
+ "SELECT 'sqlite_master' AS name, 1 AS rootpage, 'table' AS type"
+ " UNION ALL "
+ "SELECT name, rootpage, type"
+ " FROM \"%w\".%s WHERE rootpage!=0"
+ " ORDER BY name", pTab->db->aDb[pCsr->iDb].zName, zMaster);
+ if( zSql==0 ){
+ return SQLITE_NOMEM;
+ }else{
+ rc = sqlite3_prepare_v2(pTab->db, zSql, -1, &pCsr->pStmt, 0);
+ sqlite3_free(zSql);
+ }
+
+ if( rc==SQLITE_OK ){
+ rc = statNext(pCursor);
+ }
+ return rc;
+}
+
+static int statColumn(
+ sqlite3_vtab_cursor *pCursor,
+ sqlite3_context *ctx,
+ int i
+){
+ StatCursor *pCsr = (StatCursor *)pCursor;
+ switch( i ){
+ case 0: /* name */
+ sqlite3_result_text(ctx, pCsr->zName, -1, SQLITE_TRANSIENT);
+ break;
+ case 1: /* path */
+ sqlite3_result_text(ctx, pCsr->zPath, -1, SQLITE_TRANSIENT);
+ break;
+ case 2: /* pageno */
+ sqlite3_result_int64(ctx, pCsr->iPageno);
+ break;
+ case 3: /* pagetype */
+ sqlite3_result_text(ctx, pCsr->zPagetype, -1, SQLITE_STATIC);
+ break;
+ case 4: /* ncell */
+ sqlite3_result_int(ctx, pCsr->nCell);
+ break;
+ case 5: /* payload */
+ sqlite3_result_int(ctx, pCsr->nPayload);
+ break;
+ case 6: /* unused */
+ sqlite3_result_int(ctx, pCsr->nUnused);
+ break;
+ case 7: /* mx_payload */
+ sqlite3_result_int(ctx, pCsr->nMxPayload);
+ break;
+ case 8: /* pgoffset */
+ sqlite3_result_int64(ctx, pCsr->iOffset);
+ break;
+ case 9: /* pgsize */
+ sqlite3_result_int(ctx, pCsr->szPage);
+ break;
+ default: { /* schema */
+ sqlite3 *db = sqlite3_context_db_handle(ctx);
+ int iDb = pCsr->iDb;
+ sqlite3_result_text(ctx, db->aDb[iDb].zName, -1, SQLITE_STATIC);
+ break;
+ }
+ }
+ return SQLITE_OK;
+}
+
+static int statRowid(sqlite3_vtab_cursor *pCursor, sqlite_int64 *pRowid){
+ StatCursor *pCsr = (StatCursor *)pCursor;
+ *pRowid = pCsr->iPageno;
+ return SQLITE_OK;
+}
+
+/*
+** Invoke this routine to register the "dbstat" virtual table module
+*/
+SQLITE_PRIVATE int sqlite3DbstatRegister(sqlite3 *db){
+ static sqlite3_module dbstat_module = {
+ 0, /* iVersion */
+ statConnect, /* xCreate */
+ statConnect, /* xConnect */
+ statBestIndex, /* xBestIndex */
+ statDisconnect, /* xDisconnect */
+ statDisconnect, /* xDestroy */
+ statOpen, /* xOpen - open a cursor */
+ statClose, /* xClose - close a cursor */
+ statFilter, /* xFilter - configure scan constraints */
+ statNext, /* xNext - advance a cursor */
+ statEof, /* xEof - check for end of scan */
+ statColumn, /* xColumn - read data */
+ statRowid, /* xRowid - read data */
+ 0, /* xUpdate */
+ 0, /* xBegin */
+ 0, /* xSync */
+ 0, /* xCommit */
+ 0, /* xRollback */
+ 0, /* xFindMethod */
+ 0, /* xRename */
+ };
+ return sqlite3_create_module(db, "dbstat", &dbstat_module, 0);
+}
+#elif defined(SQLITE_ENABLE_DBSTAT_VTAB)
+SQLITE_PRIVATE int sqlite3DbstatRegister(sqlite3 *db){ return SQLITE_OK; }
+#endif /* SQLITE_ENABLE_DBSTAT_VTAB */
+
+/************** End of dbstat.c **********************************************/
+/************** Begin file json1.c *******************************************/
+/*
+** 2015-08-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.
+**
+******************************************************************************
+**
+** This SQLite extension implements JSON functions. The interface is
+** modeled after MySQL JSON functions:
+**
+** https://dev.mysql.com/doc/refman/5.7/en/json.html
+**
+** For the time being, all JSON is stored as pure text. (We might add
+** a JSONB type in the future which stores a binary encoding of JSON in
+** a BLOB, but there is no support for JSONB in the current implementation.
+** This implementation parses JSON text at 250 MB/s, so it is hard to see
+** how JSONB might improve on that.)
+*/
+#if !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_JSON1)
+#if !defined(_SQLITEINT_H_)
+/* #include "sqlite3ext.h" */
+#endif
+SQLITE_EXTENSION_INIT1
+/* #include <assert.h> */
+/* #include <string.h> */
+/* #include <stdlib.h> */
+/* #include <stdarg.h> */
+
+#define UNUSED_PARAM(X) (void)(X)
+
+#ifndef LARGEST_INT64
+# define LARGEST_INT64 (0xffffffff|(((sqlite3_int64)0x7fffffff)<<32))
+# define SMALLEST_INT64 (((sqlite3_int64)-1) - LARGEST_INT64)
+#endif
+
+/*
+** Versions of isspace(), isalnum() and isdigit() to which it is safe
+** to pass signed char values.
+*/
+#ifdef sqlite3Isdigit
+ /* Use the SQLite core versions if this routine is part of the
+ ** SQLite amalgamation */
+# define safe_isdigit(x) sqlite3Isdigit(x)
+# define safe_isalnum(x) sqlite3Isalnum(x)
+#else
+ /* Use the standard library for separate compilation */
+#include <ctype.h> /* amalgamator: keep */
+# define safe_isdigit(x) isdigit((unsigned char)(x))
+# define safe_isalnum(x) isalnum((unsigned char)(x))
+#endif
+
+/*
+** Growing our own isspace() routine this way is twice as fast as
+** the library isspace() function, resulting in a 7% overall performance
+** increase for the parser. (Ubuntu14.10 gcc 4.8.4 x64 with -Os).
+*/
+static const char jsonIsSpace[] = {
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 1, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 1, 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, 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, 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, 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 safe_isspace(x) (jsonIsSpace[(unsigned char)x])
+
+#ifndef SQLITE_AMALGAMATION
+ /* Unsigned integer types. These are already defined in the sqliteInt.h,
+ ** but the definitions need to be repeated for separate compilation. */
+ typedef sqlite3_uint64 u64;
+ typedef unsigned int u32;
+ typedef unsigned char u8;
+#endif
+
+/* Objects */
+typedef struct JsonString JsonString;
+typedef struct JsonNode JsonNode;
+typedef struct JsonParse JsonParse;
+
+/* An instance of this object represents a JSON string
+** under construction. Really, this is a generic string accumulator
+** that can be and is used to create strings other than JSON.
+*/
+struct JsonString {
+ sqlite3_context *pCtx; /* Function context - put error messages here */
+ char *zBuf; /* Append JSON content here */
+ u64 nAlloc; /* Bytes of storage available in zBuf[] */
+ u64 nUsed; /* Bytes of zBuf[] currently used */
+ u8 bStatic; /* True if zBuf is static space */
+ u8 bErr; /* True if an error has been encountered */
+ char zSpace[100]; /* Initial static space */
+};
+
+/* JSON type values
+*/
+#define JSON_NULL 0
+#define JSON_TRUE 1
+#define JSON_FALSE 2
+#define JSON_INT 3
+#define JSON_REAL 4
+#define JSON_STRING 5
+#define JSON_ARRAY 6
+#define JSON_OBJECT 7
+
+/* The "subtype" set for JSON values */
+#define JSON_SUBTYPE 74 /* Ascii for "J" */
+
+/*
+** Names of the various JSON types:
+*/
+static const char * const jsonType[] = {
+ "null", "true", "false", "integer", "real", "text", "array", "object"
+};
+
+/* Bit values for the JsonNode.jnFlag field
+*/
+#define JNODE_RAW 0x01 /* Content is raw, not JSON encoded */
+#define JNODE_ESCAPE 0x02 /* Content is text with \ escapes */
+#define JNODE_REMOVE 0x04 /* Do not output */
+#define JNODE_REPLACE 0x08 /* Replace with JsonNode.iVal */
+#define JNODE_APPEND 0x10 /* More ARRAY/OBJECT entries at u.iAppend */
+#define JNODE_LABEL 0x20 /* Is a label of an object */
+
+
+/* A single node of parsed JSON
+*/
+struct JsonNode {
+ u8 eType; /* One of the JSON_ type values */
+ u8 jnFlags; /* JNODE flags */
+ u8 iVal; /* Replacement value when JNODE_REPLACE */
+ u32 n; /* Bytes of content, or number of sub-nodes */
+ union {
+ const char *zJContent; /* Content for INT, REAL, and STRING */
+ u32 iAppend; /* More terms for ARRAY and OBJECT */
+ u32 iKey; /* Key for ARRAY objects in json_tree() */
+ } u;
+};
+
+/* A completely parsed JSON string
+*/
+struct JsonParse {
+ u32 nNode; /* Number of slots of aNode[] used */
+ u32 nAlloc; /* Number of slots of aNode[] allocated */
+ JsonNode *aNode; /* Array of nodes containing the parse */
+ const char *zJson; /* Original JSON string */
+ u32 *aUp; /* Index of parent of each node */
+ u8 oom; /* Set to true if out of memory */
+ u8 nErr; /* Number of errors seen */
+};
+
+/**************************************************************************
+** Utility routines for dealing with JsonString objects
+**************************************************************************/
+
+/* Set the JsonString object to an empty string
+*/
+static void jsonZero(JsonString *p){
+ p->zBuf = p->zSpace;
+ p->nAlloc = sizeof(p->zSpace);
+ p->nUsed = 0;
+ p->bStatic = 1;
+}
+
+/* Initialize the JsonString object
+*/
+static void jsonInit(JsonString *p, sqlite3_context *pCtx){
+ p->pCtx = pCtx;
+ p->bErr = 0;
+ jsonZero(p);
+}
+
+
+/* Free all allocated memory and reset the JsonString object back to its
+** initial state.
+*/
+static void jsonReset(JsonString *p){
+ if( !p->bStatic ) sqlite3_free(p->zBuf);
+ jsonZero(p);
+}
+
+
+/* Report an out-of-memory (OOM) condition
+*/
+static void jsonOom(JsonString *p){
+ p->bErr = 1;
+ sqlite3_result_error_nomem(p->pCtx);
+ jsonReset(p);
+}
+
+/* Enlarge pJson->zBuf so that it can hold at least N more bytes.
+** Return zero on success. Return non-zero on an OOM error
+*/
+static int jsonGrow(JsonString *p, u32 N){
+ u64 nTotal = N<p->nAlloc ? p->nAlloc*2 : p->nAlloc+N+10;
+ char *zNew;
+ if( p->bStatic ){
+ if( p->bErr ) return 1;
+ zNew = sqlite3_malloc64(nTotal);
+ if( zNew==0 ){
+ jsonOom(p);
+ return SQLITE_NOMEM;
+ }
+ memcpy(zNew, p->zBuf, (size_t)p->nUsed);
+ p->zBuf = zNew;
+ p->bStatic = 0;
+ }else{
+ zNew = sqlite3_realloc64(p->zBuf, nTotal);
+ if( zNew==0 ){
+ jsonOom(p);
+ return SQLITE_NOMEM;
+ }
+ p->zBuf = zNew;
+ }
+ p->nAlloc = nTotal;
+ return SQLITE_OK;
+}
+
+/* Append N bytes from zIn onto the end of the JsonString string.
+*/
+static void jsonAppendRaw(JsonString *p, const char *zIn, u32 N){
+ if( (N+p->nUsed >= p->nAlloc) && jsonGrow(p,N)!=0 ) return;
+ memcpy(p->zBuf+p->nUsed, zIn, N);
+ p->nUsed += N;
+}
+
+/* Append formatted text (not to exceed N bytes) to the JsonString.
+*/
+static void jsonPrintf(int N, JsonString *p, const char *zFormat, ...){
+ va_list ap;
+ if( (p->nUsed + N >= p->nAlloc) && jsonGrow(p, N) ) return;
+ va_start(ap, zFormat);
+ sqlite3_vsnprintf(N, p->zBuf+p->nUsed, zFormat, ap);
+ va_end(ap);
+ p->nUsed += (int)strlen(p->zBuf+p->nUsed);
+}
+
+/* Append a single character
+*/
+static void jsonAppendChar(JsonString *p, char c){
+ if( p->nUsed>=p->nAlloc && jsonGrow(p,1)!=0 ) return;
+ p->zBuf[p->nUsed++] = c;
+}
+
+/* Append a comma separator to the output buffer, if the previous
+** character is not '[' or '{'.
+*/
+static void jsonAppendSeparator(JsonString *p){
+ char c;
+ if( p->nUsed==0 ) return;
+ c = p->zBuf[p->nUsed-1];
+ if( c!='[' && c!='{' ) jsonAppendChar(p, ',');
+}
+
+/* Append the N-byte string in zIn to the end of the JsonString string
+** under construction. Enclose the string in "..." and escape
+** any double-quotes or backslash characters contained within the
+** string.
+*/
+static void jsonAppendString(JsonString *p, const char *zIn, u32 N){
+ u32 i;
+ if( (N+p->nUsed+2 >= p->nAlloc) && jsonGrow(p,N+2)!=0 ) return;
+ p->zBuf[p->nUsed++] = '"';
+ for(i=0; i<N; i++){
+ char c = zIn[i];
+ if( c=='"' || c=='\\' ){
+ if( (p->nUsed+N+3-i > p->nAlloc) && jsonGrow(p,N+3-i)!=0 ) return;
+ p->zBuf[p->nUsed++] = '\\';
+ }
+ p->zBuf[p->nUsed++] = c;
+ }
+ p->zBuf[p->nUsed++] = '"';
+ assert( p->nUsed<p->nAlloc );
+}
+
+/*
+** Append a function parameter value to the JSON string under
+** construction.
+*/
+static void jsonAppendValue(
+ JsonString *p, /* Append to this JSON string */
+ sqlite3_value *pValue /* Value to append */
+){
+ switch( sqlite3_value_type(pValue) ){
+ case SQLITE_NULL: {
+ jsonAppendRaw(p, "null", 4);
+ break;
+ }
+ case SQLITE_INTEGER:
+ case SQLITE_FLOAT: {
+ const char *z = (const char*)sqlite3_value_text(pValue);
+ u32 n = (u32)sqlite3_value_bytes(pValue);
+ jsonAppendRaw(p, z, n);
+ break;
+ }
+ case SQLITE_TEXT: {
+ const char *z = (const char*)sqlite3_value_text(pValue);
+ u32 n = (u32)sqlite3_value_bytes(pValue);
+ if( sqlite3_value_subtype(pValue)==JSON_SUBTYPE ){
+ jsonAppendRaw(p, z, n);
+ }else{
+ jsonAppendString(p, z, n);
+ }
+ break;
+ }
+ default: {
+ if( p->bErr==0 ){
+ sqlite3_result_error(p->pCtx, "JSON cannot hold BLOB values", -1);
+ p->bErr = 1;
+ jsonReset(p);
+ }
+ break;
+ }
+ }
+}
+
+
+/* Make the JSON in p the result of the SQL function.
+*/
+static void jsonResult(JsonString *p){
+ if( p->bErr==0 ){
+ sqlite3_result_text64(p->pCtx, p->zBuf, p->nUsed,
+ p->bStatic ? SQLITE_TRANSIENT : sqlite3_free,
+ SQLITE_UTF8);
+ jsonZero(p);
+ }
+ assert( p->bStatic );
+}
+
+/**************************************************************************
+** Utility routines for dealing with JsonNode and JsonParse objects
+**************************************************************************/
+
+/*
+** Return the number of consecutive JsonNode slots need to represent
+** the parsed JSON at pNode. The minimum answer is 1. For ARRAY and
+** OBJECT types, the number might be larger.
+**
+** Appended elements are not counted. The value returned is the number
+** by which the JsonNode counter should increment in order to go to the
+** next peer value.
+*/
+static u32 jsonNodeSize(JsonNode *pNode){
+ return pNode->eType>=JSON_ARRAY ? pNode->n+1 : 1;
+}
+
+/*
+** Reclaim all memory allocated by a JsonParse object. But do not
+** delete the JsonParse object itself.
+*/
+static void jsonParseReset(JsonParse *pParse){
+ sqlite3_free(pParse->aNode);
+ pParse->aNode = 0;
+ pParse->nNode = 0;
+ pParse->nAlloc = 0;
+ sqlite3_free(pParse->aUp);
+ pParse->aUp = 0;
+}
+
+/*
+** Convert the JsonNode pNode into a pure JSON string and
+** append to pOut. Subsubstructure is also included. Return
+** the number of JsonNode objects that are encoded.
+*/
+static void jsonRenderNode(
+ JsonNode *pNode, /* The node to render */
+ JsonString *pOut, /* Write JSON here */
+ sqlite3_value **aReplace /* Replacement values */
+){
+ switch( pNode->eType ){
+ default: {
+ assert( pNode->eType==JSON_NULL );
+ jsonAppendRaw(pOut, "null", 4);
+ break;
+ }
+ case JSON_TRUE: {
+ jsonAppendRaw(pOut, "true", 4);
+ break;
+ }
+ case JSON_FALSE: {
+ jsonAppendRaw(pOut, "false", 5);
+ break;
+ }
+ case JSON_STRING: {
+ if( pNode->jnFlags & JNODE_RAW ){
+ jsonAppendString(pOut, pNode->u.zJContent, pNode->n);
+ break;
+ }
+ /* Fall through into the next case */
+ }
+ case JSON_REAL:
+ case JSON_INT: {
+ jsonAppendRaw(pOut, pNode->u.zJContent, pNode->n);
+ break;
+ }
+ case JSON_ARRAY: {
+ u32 j = 1;
+ jsonAppendChar(pOut, '[');
+ for(;;){
+ while( j<=pNode->n ){
+ if( pNode[j].jnFlags & (JNODE_REMOVE|JNODE_REPLACE) ){
+ if( pNode[j].jnFlags & JNODE_REPLACE ){
+ jsonAppendSeparator(pOut);
+ jsonAppendValue(pOut, aReplace[pNode[j].iVal]);
+ }
+ }else{
+ jsonAppendSeparator(pOut);
+ jsonRenderNode(&pNode[j], pOut, aReplace);
+ }
+ j += jsonNodeSize(&pNode[j]);
+ }
+ if( (pNode->jnFlags & JNODE_APPEND)==0 ) break;
+ pNode = &pNode[pNode->u.iAppend];
+ j = 1;
+ }
+ jsonAppendChar(pOut, ']');
+ break;
+ }
+ case JSON_OBJECT: {
+ u32 j = 1;
+ jsonAppendChar(pOut, '{');
+ for(;;){
+ while( j<=pNode->n ){
+ if( (pNode[j+1].jnFlags & JNODE_REMOVE)==0 ){
+ jsonAppendSeparator(pOut);
+ jsonRenderNode(&pNode[j], pOut, aReplace);
+ jsonAppendChar(pOut, ':');
+ if( pNode[j+1].jnFlags & JNODE_REPLACE ){
+ jsonAppendValue(pOut, aReplace[pNode[j+1].iVal]);
+ }else{
+ jsonRenderNode(&pNode[j+1], pOut, aReplace);
+ }
+ }
+ j += 1 + jsonNodeSize(&pNode[j+1]);
+ }
+ if( (pNode->jnFlags & JNODE_APPEND)==0 ) break;
+ pNode = &pNode[pNode->u.iAppend];
+ j = 1;
+ }
+ jsonAppendChar(pOut, '}');
+ break;
+ }
+ }
+}
+
+/*
+** Return a JsonNode and all its descendents as a JSON string.
+*/
+static void jsonReturnJson(
+ JsonNode *pNode, /* Node to return */
+ sqlite3_context *pCtx, /* Return value for this function */
+ sqlite3_value **aReplace /* Array of replacement values */
+){
+ JsonString s;
+ jsonInit(&s, pCtx);
+ jsonRenderNode(pNode, &s, aReplace);
+ jsonResult(&s);
+ sqlite3_result_subtype(pCtx, JSON_SUBTYPE);
+}
+
+/*
+** Make the JsonNode the return value of the function.
+*/
+static void jsonReturn(
+ JsonNode *pNode, /* Node to return */
+ sqlite3_context *pCtx, /* Return value for this function */
+ sqlite3_value **aReplace /* Array of replacement values */
+){
+ switch( pNode->eType ){
+ default: {
+ assert( pNode->eType==JSON_NULL );
+ sqlite3_result_null(pCtx);
+ break;
+ }
+ case JSON_TRUE: {
+ sqlite3_result_int(pCtx, 1);
+ break;
+ }
+ case JSON_FALSE: {
+ sqlite3_result_int(pCtx, 0);
+ break;
+ }
+ case JSON_INT: {
+ sqlite3_int64 i = 0;
+ const char *z = pNode->u.zJContent;
+ if( z[0]=='-' ){ z++; }
+ while( z[0]>='0' && z[0]<='9' ){
+ unsigned v = *(z++) - '0';
+ if( i>=LARGEST_INT64/10 ){
+ if( i>LARGEST_INT64/10 ) goto int_as_real;
+ if( z[0]>='0' && z[0]<='9' ) goto int_as_real;
+ if( v==9 ) goto int_as_real;
+ if( v==8 ){
+ if( pNode->u.zJContent[0]=='-' ){
+ sqlite3_result_int64(pCtx, SMALLEST_INT64);
+ goto int_done;
+ }else{
+ goto int_as_real;
+ }
+ }
+ }
+ i = i*10 + v;
+ }
+ if( pNode->u.zJContent[0]=='-' ){ i = -i; }
+ sqlite3_result_int64(pCtx, i);
+ int_done:
+ break;
+ int_as_real: /* fall through to real */;
+ }
+ case JSON_REAL: {
+ double r;
+#ifdef SQLITE_AMALGAMATION
+ const char *z = pNode->u.zJContent;
+ sqlite3AtoF(z, &r, sqlite3Strlen30(z), SQLITE_UTF8);
+#else
+ r = strtod(pNode->u.zJContent, 0);
+#endif
+ sqlite3_result_double(pCtx, r);
+ break;
+ }
+ case JSON_STRING: {
+#if 0 /* Never happens because JNODE_RAW is only set by json_set(),
+ ** json_insert() and json_replace() and those routines do not
+ ** call jsonReturn() */
+ if( pNode->jnFlags & JNODE_RAW ){
+ sqlite3_result_text(pCtx, pNode->u.zJContent, pNode->n,
+ SQLITE_TRANSIENT);
+ }else
+#endif
+ assert( (pNode->jnFlags & JNODE_RAW)==0 );
+ if( (pNode->jnFlags & JNODE_ESCAPE)==0 ){
+ /* JSON formatted without any backslash-escapes */
+ sqlite3_result_text(pCtx, pNode->u.zJContent+1, pNode->n-2,
+ SQLITE_TRANSIENT);
+ }else{
+ /* Translate JSON formatted string into raw text */
+ u32 i;
+ u32 n = pNode->n;
+ const char *z = pNode->u.zJContent;
+ char *zOut;
+ u32 j;
+ zOut = sqlite3_malloc( n+1 );
+ if( zOut==0 ){
+ sqlite3_result_error_nomem(pCtx);
+ break;
+ }
+ for(i=1, j=0; i<n-1; i++){
+ char c = z[i];
+ if( c!='\\' ){
+ zOut[j++] = c;
+ }else{
+ c = z[++i];
+ if( c=='u' ){
+ u32 v = 0, k;
+ for(k=0; k<4 && i<n-2; i++, k++){
+ c = z[i+1];
+ if( c>='0' && c<='9' ) v = v*16 + c - '0';
+ else if( c>='A' && c<='F' ) v = v*16 + c - 'A' + 10;
+ else if( c>='a' && c<='f' ) v = v*16 + c - 'a' + 10;
+ else break;
+ }
+ if( v==0 ) break;
+ if( v<=0x7f ){
+ zOut[j++] = (char)v;
+ }else if( v<=0x7ff ){
+ zOut[j++] = (char)(0xc0 | (v>>6));
+ zOut[j++] = 0x80 | (v&0x3f);
+ }else{
+ zOut[j++] = (char)(0xe0 | (v>>12));
+ zOut[j++] = 0x80 | ((v>>6)&0x3f);
+ zOut[j++] = 0x80 | (v&0x3f);
+ }
+ }else{
+ if( c=='b' ){
+ c = '\b';
+ }else if( c=='f' ){
+ c = '\f';
+ }else if( c=='n' ){
+ c = '\n';
+ }else if( c=='r' ){
+ c = '\r';
+ }else if( c=='t' ){
+ c = '\t';
+ }
+ zOut[j++] = c;
+ }
+ }
+ }
+ zOut[j] = 0;
+ sqlite3_result_text(pCtx, zOut, j, sqlite3_free);
+ }
+ break;
+ }
+ case JSON_ARRAY:
+ case JSON_OBJECT: {
+ jsonReturnJson(pNode, pCtx, aReplace);
+ break;
+ }
+ }
+}
+
+/* Forward reference */
+static int jsonParseAddNode(JsonParse*,u32,u32,const char*);
+
+/*
+** A macro to hint to the compiler that a function should not be
+** inlined.
+*/
+#if defined(__GNUC__)
+# define JSON_NOINLINE __attribute__((noinline))
+#elif defined(_MSC_VER) && _MSC_VER>=1310
+# define JSON_NOINLINE __declspec(noinline)
+#else
+# define JSON_NOINLINE
+#endif
+
+
+static JSON_NOINLINE int jsonParseAddNodeExpand(
+ JsonParse *pParse, /* Append the node to this object */
+ u32 eType, /* Node type */
+ u32 n, /* Content size or sub-node count */
+ const char *zContent /* Content */
+){
+ u32 nNew;
+ JsonNode *pNew;
+ assert( pParse->nNode>=pParse->nAlloc );
+ if( pParse->oom ) return -1;
+ nNew = pParse->nAlloc*2 + 10;
+ pNew = sqlite3_realloc(pParse->aNode, sizeof(JsonNode)*nNew);
+ if( pNew==0 ){
+ pParse->oom = 1;
+ return -1;
+ }
+ pParse->nAlloc = nNew;
+ pParse->aNode = pNew;
+ assert( pParse->nNode<pParse->nAlloc );
+ return jsonParseAddNode(pParse, eType, n, zContent);
+}
+
+/*
+** Create a new JsonNode instance based on the arguments and append that
+** instance to the JsonParse. Return the index in pParse->aNode[] of the
+** new node, or -1 if a memory allocation fails.
+*/
+static int jsonParseAddNode(
+ JsonParse *pParse, /* Append the node to this object */
+ u32 eType, /* Node type */
+ u32 n, /* Content size or sub-node count */
+ const char *zContent /* Content */
+){
+ JsonNode *p;
+ if( pParse->nNode>=pParse->nAlloc ){
+ return jsonParseAddNodeExpand(pParse, eType, n, zContent);
+ }
+ p = &pParse->aNode[pParse->nNode];
+ p->eType = (u8)eType;
+ p->jnFlags = 0;
+ p->iVal = 0;
+ p->n = n;
+ p->u.zJContent = zContent;
+ return pParse->nNode++;
+}
+
+/*
+** Parse a single JSON value which begins at pParse->zJson[i]. Return the
+** index of the first character past the end of the value parsed.
+**
+** Return negative for a syntax error. Special cases: return -2 if the
+** first non-whitespace character is '}' and return -3 if the first
+** non-whitespace character is ']'.
+*/
+static int jsonParseValue(JsonParse *pParse, u32 i){
+ char c;
+ u32 j;
+ int iThis;
+ int x;
+ JsonNode *pNode;
+ while( safe_isspace(pParse->zJson[i]) ){ i++; }
+ if( (c = pParse->zJson[i])=='{' ){
+ /* Parse object */
+ iThis = jsonParseAddNode(pParse, JSON_OBJECT, 0, 0);
+ if( iThis<0 ) return -1;
+ for(j=i+1;;j++){
+ while( safe_isspace(pParse->zJson[j]) ){ j++; }
+ x = jsonParseValue(pParse, j);
+ if( x<0 ){
+ if( x==(-2) && pParse->nNode==(u32)iThis+1 ) return j+1;
+ return -1;
+ }
+ if( pParse->oom ) return -1;
+ pNode = &pParse->aNode[pParse->nNode-1];
+ if( pNode->eType!=JSON_STRING ) return -1;
+ pNode->jnFlags |= JNODE_LABEL;
+ j = x;
+ while( safe_isspace(pParse->zJson[j]) ){ j++; }
+ if( pParse->zJson[j]!=':' ) return -1;
+ j++;
+ x = jsonParseValue(pParse, j);
+ if( x<0 ) return -1;
+ j = x;
+ while( safe_isspace(pParse->zJson[j]) ){ j++; }
+ c = pParse->zJson[j];
+ if( c==',' ) continue;
+ if( c!='}' ) return -1;
+ break;
+ }
+ pParse->aNode[iThis].n = pParse->nNode - (u32)iThis - 1;
+ return j+1;
+ }else if( c=='[' ){
+ /* Parse array */
+ iThis = jsonParseAddNode(pParse, JSON_ARRAY, 0, 0);
+ if( iThis<0 ) return -1;
+ for(j=i+1;;j++){
+ while( safe_isspace(pParse->zJson[j]) ){ j++; }
+ x = jsonParseValue(pParse, j);
+ if( x<0 ){
+ if( x==(-3) && pParse->nNode==(u32)iThis+1 ) return j+1;
+ return -1;
+ }
+ j = x;
+ while( safe_isspace(pParse->zJson[j]) ){ j++; }
+ c = pParse->zJson[j];
+ if( c==',' ) continue;
+ if( c!=']' ) return -1;
+ break;
+ }
+ pParse->aNode[iThis].n = pParse->nNode - (u32)iThis - 1;
+ return j+1;
+ }else if( c=='"' ){
+ /* Parse string */
+ u8 jnFlags = 0;
+ j = i+1;
+ for(;;){
+ c = pParse->zJson[j];
+ if( c==0 ) return -1;
+ if( c=='\\' ){
+ c = pParse->zJson[++j];
+ if( c==0 ) return -1;
+ jnFlags = JNODE_ESCAPE;
+ }else if( c=='"' ){
+ break;
+ }
+ j++;
+ }
+ jsonParseAddNode(pParse, JSON_STRING, j+1-i, &pParse->zJson[i]);
+ if( !pParse->oom ) pParse->aNode[pParse->nNode-1].jnFlags = jnFlags;
+ return j+1;
+ }else if( c=='n'
+ && strncmp(pParse->zJson+i,"null",4)==0
+ && !safe_isalnum(pParse->zJson[i+4]) ){
+ jsonParseAddNode(pParse, JSON_NULL, 0, 0);
+ return i+4;
+ }else if( c=='t'
+ && strncmp(pParse->zJson+i,"true",4)==0
+ && !safe_isalnum(pParse->zJson[i+4]) ){
+ jsonParseAddNode(pParse, JSON_TRUE, 0, 0);
+ return i+4;
+ }else if( c=='f'
+ && strncmp(pParse->zJson+i,"false",5)==0
+ && !safe_isalnum(pParse->zJson[i+5]) ){
+ jsonParseAddNode(pParse, JSON_FALSE, 0, 0);
+ return i+5;
+ }else if( c=='-' || (c>='0' && c<='9') ){
+ /* Parse number */
+ u8 seenDP = 0;
+ u8 seenE = 0;
+ j = i+1;
+ for(;; j++){
+ c = pParse->zJson[j];
+ if( c>='0' && c<='9' ) continue;
+ if( c=='.' ){
+ if( pParse->zJson[j-1]=='-' ) return -1;
+ if( seenDP ) return -1;
+ seenDP = 1;
+ continue;
+ }
+ if( c=='e' || c=='E' ){
+ if( pParse->zJson[j-1]<'0' ) return -1;
+ if( seenE ) return -1;
+ seenDP = seenE = 1;
+ c = pParse->zJson[j+1];
+ if( c=='+' || c=='-' ){
+ j++;
+ c = pParse->zJson[j+1];
+ }
+ if( c<'0' || c>'9' ) return -1;
+ continue;
+ }
+ break;
+ }
+ if( pParse->zJson[j-1]<'0' ) return -1;
+ jsonParseAddNode(pParse, seenDP ? JSON_REAL : JSON_INT,
+ j - i, &pParse->zJson[i]);
+ return j;
+ }else if( c=='}' ){
+ return -2; /* End of {...} */
+ }else if( c==']' ){
+ return -3; /* End of [...] */
+ }else if( c==0 ){
+ return 0; /* End of file */
+ }else{
+ return -1; /* Syntax error */
+ }
+}
+
+/*
+** Parse a complete JSON string. Return 0 on success or non-zero if there
+** are any errors. If an error occurs, free all memory associated with
+** pParse.
+**
+** pParse is uninitialized when this routine is called.
+*/
+static int jsonParse(
+ JsonParse *pParse, /* Initialize and fill this JsonParse object */
+ sqlite3_context *pCtx, /* Report errors here */
+ const char *zJson /* Input JSON text to be parsed */
+){
+ int i;
+ memset(pParse, 0, sizeof(*pParse));
+ if( zJson==0 ) return 1;
+ pParse->zJson = zJson;
+ i = jsonParseValue(pParse, 0);
+ if( pParse->oom ) i = -1;
+ if( i>0 ){
+ while( safe_isspace(zJson[i]) ) i++;
+ if( zJson[i] ) i = -1;
+ }
+ if( i<=0 ){
+ if( pCtx!=0 ){
+ if( pParse->oom ){
+ sqlite3_result_error_nomem(pCtx);
+ }else{
+ sqlite3_result_error(pCtx, "malformed JSON", -1);
+ }
+ }
+ jsonParseReset(pParse);
+ return 1;
+ }
+ return 0;
+}
+
+/* Mark node i of pParse as being a child of iParent. Call recursively
+** to fill in all the descendants of node i.
+*/
+static void jsonParseFillInParentage(JsonParse *pParse, u32 i, u32 iParent){
+ JsonNode *pNode = &pParse->aNode[i];
+ u32 j;
+ pParse->aUp[i] = iParent;
+ switch( pNode->eType ){
+ case JSON_ARRAY: {
+ for(j=1; j<=pNode->n; j += jsonNodeSize(pNode+j)){
+ jsonParseFillInParentage(pParse, i+j, i);
+ }
+ break;
+ }
+ case JSON_OBJECT: {
+ for(j=1; j<=pNode->n; j += jsonNodeSize(pNode+j+1)+1){
+ pParse->aUp[i+j] = i;
+ jsonParseFillInParentage(pParse, i+j+1, i);
+ }
+ break;
+ }
+ default: {
+ break;
+ }
+ }
+}
+
+/*
+** Compute the parentage of all nodes in a completed parse.
+*/
+static int jsonParseFindParents(JsonParse *pParse){
+ u32 *aUp;
+ assert( pParse->aUp==0 );
+ aUp = pParse->aUp = sqlite3_malloc( sizeof(u32)*pParse->nNode );
+ if( aUp==0 ){
+ pParse->oom = 1;
+ return SQLITE_NOMEM;
+ }
+ jsonParseFillInParentage(pParse, 0, 0);
+ return SQLITE_OK;
+}
+
+/*
+** Compare the OBJECT label at pNode against zKey,nKey. Return true on
+** a match.
+*/
+static int jsonLabelCompare(JsonNode *pNode, const char *zKey, u32 nKey){
+ if( pNode->jnFlags & JNODE_RAW ){
+ if( pNode->n!=nKey ) return 0;
+ return strncmp(pNode->u.zJContent, zKey, nKey)==0;
+ }else{
+ if( pNode->n!=nKey+2 ) return 0;
+ return strncmp(pNode->u.zJContent+1, zKey, nKey)==0;
+ }
+}
+
+/* forward declaration */
+static JsonNode *jsonLookupAppend(JsonParse*,const char*,int*,const char**);
+
+/*
+** Search along zPath to find the node specified. Return a pointer
+** to that node, or NULL if zPath is malformed or if there is no such
+** node.
+**
+** If pApnd!=0, then try to append new nodes to complete zPath if it is
+** possible to do so and if no existing node corresponds to zPath. If
+** new nodes are appended *pApnd is set to 1.
+*/
+static JsonNode *jsonLookupStep(
+ JsonParse *pParse, /* The JSON to search */
+ u32 iRoot, /* Begin the search at this node */
+ const char *zPath, /* The path to search */
+ int *pApnd, /* Append nodes to complete path if not NULL */
+ const char **pzErr /* Make *pzErr point to any syntax error in zPath */
+){
+ u32 i, j, nKey;
+ const char *zKey;
+ JsonNode *pRoot = &pParse->aNode[iRoot];
+ if( zPath[0]==0 ) return pRoot;
+ if( zPath[0]=='.' ){
+ if( pRoot->eType!=JSON_OBJECT ) return 0;
+ zPath++;
+ if( zPath[0]=='"' ){
+ zKey = zPath + 1;
+ for(i=1; zPath[i] && zPath[i]!='"'; i++){}
+ nKey = i-1;
+ if( zPath[i] ){
+ i++;
+ }else{
+ *pzErr = zPath;
+ return 0;
+ }
+ }else{
+ zKey = zPath;
+ for(i=0; zPath[i] && zPath[i]!='.' && zPath[i]!='['; i++){}
+ nKey = i;
+ }
+ if( nKey==0 ){
+ *pzErr = zPath;
+ return 0;
+ }
+ j = 1;
+ for(;;){
+ while( j<=pRoot->n ){
+ if( jsonLabelCompare(pRoot+j, zKey, nKey) ){
+ return jsonLookupStep(pParse, iRoot+j+1, &zPath[i], pApnd, pzErr);
+ }
+ j++;
+ j += jsonNodeSize(&pRoot[j]);
+ }
+ if( (pRoot->jnFlags & JNODE_APPEND)==0 ) break;
+ iRoot += pRoot->u.iAppend;
+ pRoot = &pParse->aNode[iRoot];
+ j = 1;
+ }
+ if( pApnd ){
+ u32 iStart, iLabel;
+ JsonNode *pNode;
+ iStart = jsonParseAddNode(pParse, JSON_OBJECT, 2, 0);
+ iLabel = jsonParseAddNode(pParse, JSON_STRING, i, zPath);
+ zPath += i;
+ pNode = jsonLookupAppend(pParse, zPath, pApnd, pzErr);
+ if( pParse->oom ) return 0;
+ if( pNode ){
+ pRoot = &pParse->aNode[iRoot];
+ pRoot->u.iAppend = iStart - iRoot;
+ pRoot->jnFlags |= JNODE_APPEND;
+ pParse->aNode[iLabel].jnFlags |= JNODE_RAW;
+ }
+ return pNode;
+ }
+ }else if( zPath[0]=='[' && safe_isdigit(zPath[1]) ){
+ if( pRoot->eType!=JSON_ARRAY ) return 0;
+ i = 0;
+ j = 1;
+ while( safe_isdigit(zPath[j]) ){
+ i = i*10 + zPath[j] - '0';
+ j++;
+ }
+ if( zPath[j]!=']' ){
+ *pzErr = zPath;
+ return 0;
+ }
+ zPath += j + 1;
+ j = 1;
+ for(;;){
+ while( j<=pRoot->n && (i>0 || (pRoot[j].jnFlags & JNODE_REMOVE)!=0) ){
+ if( (pRoot[j].jnFlags & JNODE_REMOVE)==0 ) i--;
+ j += jsonNodeSize(&pRoot[j]);
+ }
+ if( (pRoot->jnFlags & JNODE_APPEND)==0 ) break;
+ iRoot += pRoot->u.iAppend;
+ pRoot = &pParse->aNode[iRoot];
+ j = 1;
+ }
+ if( j<=pRoot->n ){
+ return jsonLookupStep(pParse, iRoot+j, zPath, pApnd, pzErr);
+ }
+ if( i==0 && pApnd ){
+ u32 iStart;
+ JsonNode *pNode;
+ iStart = jsonParseAddNode(pParse, JSON_ARRAY, 1, 0);
+ pNode = jsonLookupAppend(pParse, zPath, pApnd, pzErr);
+ if( pParse->oom ) return 0;
+ if( pNode ){
+ pRoot = &pParse->aNode[iRoot];
+ pRoot->u.iAppend = iStart - iRoot;
+ pRoot->jnFlags |= JNODE_APPEND;
+ }
+ return pNode;
+ }
+ }else{
+ *pzErr = zPath;
+ }
+ return 0;
+}
+
+/*
+** Append content to pParse that will complete zPath. Return a pointer
+** to the inserted node, or return NULL if the append fails.
+*/
+static JsonNode *jsonLookupAppend(
+ JsonParse *pParse, /* Append content to the JSON parse */
+ const char *zPath, /* Description of content to append */
+ int *pApnd, /* Set this flag to 1 */
+ const char **pzErr /* Make this point to any syntax error */
+){
+ *pApnd = 1;
+ if( zPath[0]==0 ){
+ jsonParseAddNode(pParse, JSON_NULL, 0, 0);
+ return pParse->oom ? 0 : &pParse->aNode[pParse->nNode-1];
+ }
+ if( zPath[0]=='.' ){
+ jsonParseAddNode(pParse, JSON_OBJECT, 0, 0);
+ }else if( strncmp(zPath,"[0]",3)==0 ){
+ jsonParseAddNode(pParse, JSON_ARRAY, 0, 0);
+ }else{
+ return 0;
+ }
+ if( pParse->oom ) return 0;
+ return jsonLookupStep(pParse, pParse->nNode-1, zPath, pApnd, pzErr);
+}
+
+/*
+** Return the text of a syntax error message on a JSON path. Space is
+** obtained from sqlite3_malloc().
+*/
+static char *jsonPathSyntaxError(const char *zErr){
+ return sqlite3_mprintf("JSON path error near '%q'", zErr);
+}
+
+/*
+** Do a node lookup using zPath. Return a pointer to the node on success.
+** Return NULL if not found or if there is an error.
+**
+** On an error, write an error message into pCtx and increment the
+** pParse->nErr counter.
+**
+** If pApnd!=NULL then try to append missing nodes and set *pApnd = 1 if
+** nodes are appended.
+*/
+static JsonNode *jsonLookup(
+ JsonParse *pParse, /* The JSON to search */
+ const char *zPath, /* The path to search */
+ int *pApnd, /* Append nodes to complete path if not NULL */
+ sqlite3_context *pCtx /* Report errors here, if not NULL */
+){
+ const char *zErr = 0;
+ JsonNode *pNode = 0;
+ char *zMsg;
+
+ if( zPath==0 ) return 0;
+ if( zPath[0]!='$' ){
+ zErr = zPath;
+ goto lookup_err;
+ }
+ zPath++;
+ pNode = jsonLookupStep(pParse, 0, zPath, pApnd, &zErr);
+ if( zErr==0 ) return pNode;
+
+lookup_err:
+ pParse->nErr++;
+ assert( zErr!=0 && pCtx!=0 );
+ zMsg = jsonPathSyntaxError(zErr);
+ if( zMsg ){
+ sqlite3_result_error(pCtx, zMsg, -1);
+ sqlite3_free(zMsg);
+ }else{
+ sqlite3_result_error_nomem(pCtx);
+ }
+ return 0;
+}
+
+
+/*
+** Report the wrong number of arguments for json_insert(), json_replace()
+** or json_set().
+*/
+static void jsonWrongNumArgs(
+ sqlite3_context *pCtx,
+ const char *zFuncName
+){
+ char *zMsg = sqlite3_mprintf("json_%s() needs an odd number of arguments",
+ zFuncName);
+ sqlite3_result_error(pCtx, zMsg, -1);
+ sqlite3_free(zMsg);
+}
+
+
+/****************************************************************************
+** SQL functions used for testing and debugging
+****************************************************************************/
+
+#ifdef SQLITE_DEBUG
+/*
+** The json_parse(JSON) function returns a string which describes
+** a parse of the JSON provided. Or it returns NULL if JSON is not
+** well-formed.
+*/
+static void jsonParseFunc(
+ sqlite3_context *ctx,
+ int argc,
+ sqlite3_value **argv
+){
+ JsonString s; /* Output string - not real JSON */
+ JsonParse x; /* The parse */
+ u32 i;
+
+ assert( argc==1 );
+ if( jsonParse(&x, ctx, (const char*)sqlite3_value_text(argv[0])) ) return;
+ jsonParseFindParents(&x);
+ jsonInit(&s, ctx);
+ for(i=0; i<x.nNode; i++){
+ const char *zType;
+ if( x.aNode[i].jnFlags & JNODE_LABEL ){
+ assert( x.aNode[i].eType==JSON_STRING );
+ zType = "label";
+ }else{
+ zType = jsonType[x.aNode[i].eType];
+ }
+ jsonPrintf(100, &s,"node %3u: %7s n=%-4d up=%-4d",
+ i, zType, x.aNode[i].n, x.aUp[i]);
+ if( x.aNode[i].u.zJContent!=0 ){
+ jsonAppendRaw(&s, " ", 1);
+ jsonAppendRaw(&s, x.aNode[i].u.zJContent, x.aNode[i].n);
+ }
+ jsonAppendRaw(&s, "\n", 1);
+ }
+ jsonParseReset(&x);
+ jsonResult(&s);
+}
+
+/*
+** The json_test1(JSON) function return true (1) if the input is JSON
+** text generated by another json function. It returns (0) if the input
+** is not known to be JSON.
+*/
+static void jsonTest1Func(
+ sqlite3_context *ctx,
+ int argc,
+ sqlite3_value **argv
+){
+ UNUSED_PARAM(argc);
+ sqlite3_result_int(ctx, sqlite3_value_subtype(argv[0])==JSON_SUBTYPE);
+}
+#endif /* SQLITE_DEBUG */
+
+/****************************************************************************
+** Scalar SQL function implementations
+****************************************************************************/
+
+/*
+** Implementation of the json_array(VALUE,...) function. Return a JSON
+** array that contains all values given in arguments. Or if any argument
+** is a BLOB, throw an error.
+*/
+static void jsonArrayFunc(
+ sqlite3_context *ctx,
+ int argc,
+ sqlite3_value **argv
+){
+ int i;
+ JsonString jx;
+
+ jsonInit(&jx, ctx);
+ jsonAppendChar(&jx, '[');
+ for(i=0; i<argc; i++){
+ jsonAppendSeparator(&jx);
+ jsonAppendValue(&jx, argv[i]);
+ }
+ jsonAppendChar(&jx, ']');
+ jsonResult(&jx);
+ sqlite3_result_subtype(ctx, JSON_SUBTYPE);
+}
+
+
+/*
+** json_array_length(JSON)
+** json_array_length(JSON, PATH)
+**
+** Return the number of elements in the top-level JSON array.
+** Return 0 if the input is not a well-formed JSON array.
+*/
+static void jsonArrayLengthFunc(
+ sqlite3_context *ctx,
+ int argc,
+ sqlite3_value **argv
+){
+ JsonParse x; /* The parse */
+ sqlite3_int64 n = 0;
+ u32 i;
+ JsonNode *pNode;
+
+ if( jsonParse(&x, ctx, (const char*)sqlite3_value_text(argv[0])) ) return;
+ assert( x.nNode );
+ if( argc==2 ){
+ const char *zPath = (const char*)sqlite3_value_text(argv[1]);
+ pNode = jsonLookup(&x, zPath, 0, ctx);
+ }else{
+ pNode = x.aNode;
+ }
+ if( pNode==0 ){
+ x.nErr = 1;
+ }else if( pNode->eType==JSON_ARRAY ){
+ assert( (pNode->jnFlags & JNODE_APPEND)==0 );
+ for(i=1; i<=pNode->n; n++){
+ i += jsonNodeSize(&pNode[i]);
+ }
+ }
+ if( x.nErr==0 ) sqlite3_result_int64(ctx, n);
+ jsonParseReset(&x);
+}
+
+/*
+** json_extract(JSON, PATH, ...)
+**
+** Return the element described by PATH. Return NULL if there is no
+** PATH element. If there are multiple PATHs, then return a JSON array
+** with the result from each path. Throw an error if the JSON or any PATH
+** is malformed.
+*/
+static void jsonExtractFunc(
+ sqlite3_context *ctx,
+ int argc,
+ sqlite3_value **argv
+){
+ JsonParse x; /* The parse */
+ JsonNode *pNode;
+ const char *zPath;
+ JsonString jx;
+ int i;
+
+ if( argc<2 ) return;
+ if( jsonParse(&x, ctx, (const char*)sqlite3_value_text(argv[0])) ) return;
+ jsonInit(&jx, ctx);
+ jsonAppendChar(&jx, '[');
+ for(i=1; i<argc; i++){
+ zPath = (const char*)sqlite3_value_text(argv[i]);
+ pNode = jsonLookup(&x, zPath, 0, ctx);
+ if( x.nErr ) break;
+ if( argc>2 ){
+ jsonAppendSeparator(&jx);
+ if( pNode ){
+ jsonRenderNode(pNode, &jx, 0);
+ }else{
+ jsonAppendRaw(&jx, "null", 4);
+ }
+ }else if( pNode ){
+ jsonReturn(pNode, ctx, 0);
+ }
+ }
+ if( argc>2 && i==argc ){
+ jsonAppendChar(&jx, ']');
+ jsonResult(&jx);
+ sqlite3_result_subtype(ctx, JSON_SUBTYPE);
+ }
+ jsonReset(&jx);
+ jsonParseReset(&x);
+}
+
+/*
+** Implementation of the json_object(NAME,VALUE,...) function. Return a JSON
+** object that contains all name/value given in arguments. Or if any name
+** is not a string or if any value is a BLOB, throw an error.
+*/
+static void jsonObjectFunc(
+ sqlite3_context *ctx,
+ int argc,
+ sqlite3_value **argv
+){
+ int i;
+ JsonString jx;
+ const char *z;
+ u32 n;
+
+ if( argc&1 ){
+ sqlite3_result_error(ctx, "json_object() requires an even number "
+ "of arguments", -1);
+ return;
+ }
+ jsonInit(&jx, ctx);
+ jsonAppendChar(&jx, '{');
+ for(i=0; i<argc; i+=2){
+ if( sqlite3_value_type(argv[i])!=SQLITE_TEXT ){
+ sqlite3_result_error(ctx, "json_object() labels must be TEXT", -1);
+ jsonReset(&jx);
+ return;
+ }
+ jsonAppendSeparator(&jx);
+ z = (const char*)sqlite3_value_text(argv[i]);
+ n = (u32)sqlite3_value_bytes(argv[i]);
+ jsonAppendString(&jx, z, n);
+ jsonAppendChar(&jx, ':');
+ jsonAppendValue(&jx, argv[i+1]);
+ }
+ jsonAppendChar(&jx, '}');
+ jsonResult(&jx);
+ sqlite3_result_subtype(ctx, JSON_SUBTYPE);
+}
+
+
+/*
+** json_remove(JSON, PATH, ...)
+**
+** Remove the named elements from JSON and return the result. malformed
+** JSON or PATH arguments result in an error.
+*/
+static void jsonRemoveFunc(
+ sqlite3_context *ctx,
+ int argc,
+ sqlite3_value **argv
+){
+ JsonParse x; /* The parse */
+ JsonNode *pNode;
+ const char *zPath;
+ u32 i;
+
+ if( argc<1 ) return;
+ if( jsonParse(&x, ctx, (const char*)sqlite3_value_text(argv[0])) ) return;
+ assert( x.nNode );
+ for(i=1; i<(u32)argc; i++){
+ zPath = (const char*)sqlite3_value_text(argv[i]);
+ if( zPath==0 ) goto remove_done;
+ pNode = jsonLookup(&x, zPath, 0, ctx);
+ if( x.nErr ) goto remove_done;
+ if( pNode ) pNode->jnFlags |= JNODE_REMOVE;
+ }
+ if( (x.aNode[0].jnFlags & JNODE_REMOVE)==0 ){
+ jsonReturnJson(x.aNode, ctx, 0);
+ }
+remove_done:
+ jsonParseReset(&x);
+}
+
+/*
+** json_replace(JSON, PATH, VALUE, ...)
+**
+** Replace the value at PATH with VALUE. If PATH does not already exist,
+** this routine is a no-op. If JSON or PATH is malformed, throw an error.
+*/
+static void jsonReplaceFunc(
+ sqlite3_context *ctx,
+ int argc,
+ sqlite3_value **argv
+){
+ JsonParse x; /* The parse */
+ JsonNode *pNode;
+ const char *zPath;
+ u32 i;
+
+ if( argc<1 ) return;
+ if( (argc&1)==0 ) {
+ jsonWrongNumArgs(ctx, "replace");
+ return;
+ }
+ if( jsonParse(&x, ctx, (const char*)sqlite3_value_text(argv[0])) ) return;
+ assert( x.nNode );
+ for(i=1; i<(u32)argc; i+=2){
+ zPath = (const char*)sqlite3_value_text(argv[i]);
+ pNode = jsonLookup(&x, zPath, 0, ctx);
+ if( x.nErr ) goto replace_err;
+ if( pNode ){
+ pNode->jnFlags |= (u8)JNODE_REPLACE;
+ pNode->iVal = (u8)(i+1);
+ }
+ }
+ if( x.aNode[0].jnFlags & JNODE_REPLACE ){
+ sqlite3_result_value(ctx, argv[x.aNode[0].iVal]);
+ }else{
+ jsonReturnJson(x.aNode, ctx, argv);
+ }
+replace_err:
+ jsonParseReset(&x);
+}
+
+/*
+** json_set(JSON, PATH, VALUE, ...)
+**
+** Set the value at PATH to VALUE. Create the PATH if it does not already
+** exist. Overwrite existing values that do exist.
+** If JSON or PATH is malformed, throw an error.
+**
+** json_insert(JSON, PATH, VALUE, ...)
+**
+** Create PATH and initialize it to VALUE. If PATH already exists, this
+** routine is a no-op. If JSON or PATH is malformed, throw an error.
+*/
+static void jsonSetFunc(
+ sqlite3_context *ctx,
+ int argc,
+ sqlite3_value **argv
+){
+ JsonParse x; /* The parse */
+ JsonNode *pNode;
+ const char *zPath;
+ u32 i;
+ int bApnd;
+ int bIsSet = *(int*)sqlite3_user_data(ctx);
+
+ if( argc<1 ) return;
+ if( (argc&1)==0 ) {
+ jsonWrongNumArgs(ctx, bIsSet ? "set" : "insert");
+ return;
+ }
+ if( jsonParse(&x, ctx, (const char*)sqlite3_value_text(argv[0])) ) return;
+ assert( x.nNode );
+ for(i=1; i<(u32)argc; i+=2){
+ zPath = (const char*)sqlite3_value_text(argv[i]);
+ bApnd = 0;
+ pNode = jsonLookup(&x, zPath, &bApnd, ctx);
+ if( x.oom ){
+ sqlite3_result_error_nomem(ctx);
+ goto jsonSetDone;
+ }else if( x.nErr ){
+ goto jsonSetDone;
+ }else if( pNode && (bApnd || bIsSet) ){
+ pNode->jnFlags |= (u8)JNODE_REPLACE;
+ pNode->iVal = (u8)(i+1);
+ }
+ }
+ if( x.aNode[0].jnFlags & JNODE_REPLACE ){
+ sqlite3_result_value(ctx, argv[x.aNode[0].iVal]);
+ }else{
+ jsonReturnJson(x.aNode, ctx, argv);
+ }
+jsonSetDone:
+ jsonParseReset(&x);
+}
+
+/*
+** json_type(JSON)
+** json_type(JSON, PATH)
+**
+** Return the top-level "type" of a JSON string. Throw an error if
+** either the JSON or PATH inputs are not well-formed.
+*/
+static void jsonTypeFunc(
+ sqlite3_context *ctx,
+ int argc,
+ sqlite3_value **argv
+){
+ JsonParse x; /* The parse */
+ const char *zPath;
+ JsonNode *pNode;
+
+ if( jsonParse(&x, ctx, (const char*)sqlite3_value_text(argv[0])) ) return;
+ assert( x.nNode );
+ if( argc==2 ){
+ zPath = (const char*)sqlite3_value_text(argv[1]);
+ pNode = jsonLookup(&x, zPath, 0, ctx);
+ }else{
+ pNode = x.aNode;
+ }
+ if( pNode ){
+ sqlite3_result_text(ctx, jsonType[pNode->eType], -1, SQLITE_STATIC);
+ }
+ jsonParseReset(&x);
+}
+
+/*
+** json_valid(JSON)
+**
+** Return 1 if JSON is a well-formed JSON string according to RFC-7159.
+** Return 0 otherwise.
+*/
+static void jsonValidFunc(
+ sqlite3_context *ctx,
+ int argc,
+ sqlite3_value **argv
+){
+ JsonParse x; /* The parse */
+ int rc = 0;
+
+ UNUSED_PARAM(argc);
+ if( jsonParse(&x, 0, (const char*)sqlite3_value_text(argv[0]))==0 ){
+ rc = 1;
+ }
+ jsonParseReset(&x);
+ sqlite3_result_int(ctx, rc);
+}
+
+
+/****************************************************************************
+** Aggregate SQL function implementations
+****************************************************************************/
+/*
+** json_group_array(VALUE)
+**
+** Return a JSON array composed of all values in the aggregate.
+*/
+static void jsonArrayStep(
+ sqlite3_context *ctx,
+ int argc,
+ sqlite3_value **argv
+){
+ JsonString *pStr;
+ pStr = (JsonString*)sqlite3_aggregate_context(ctx, sizeof(*pStr));
+ if( pStr ){
+ if( pStr->zBuf==0 ){
+ jsonInit(pStr, ctx);
+ jsonAppendChar(pStr, '[');
+ }else{
+ jsonAppendChar(pStr, ',');
+ pStr->pCtx = ctx;
+ }
+ jsonAppendValue(pStr, argv[0]);
+ }
+}
+static void jsonArrayFinal(sqlite3_context *ctx){
+ JsonString *pStr;
+ pStr = (JsonString*)sqlite3_aggregate_context(ctx, 0);
+ if( pStr ){
+ pStr->pCtx = ctx;
+ jsonAppendChar(pStr, ']');
+ if( pStr->bErr ){
+ sqlite3_result_error_nomem(ctx);
+ assert( pStr->bStatic );
+ }else{
+ sqlite3_result_text(ctx, pStr->zBuf, pStr->nUsed,
+ pStr->bStatic ? SQLITE_TRANSIENT : sqlite3_free);
+ pStr->bStatic = 1;
+ }
+ }else{
+ sqlite3_result_text(ctx, "[]", 2, SQLITE_STATIC);
+ }
+ sqlite3_result_subtype(ctx, JSON_SUBTYPE);
+}
+
+/*
+** json_group_obj(NAME,VALUE)
+**
+** Return a JSON object composed of all names and values in the aggregate.
+*/
+static void jsonObjectStep(
+ sqlite3_context *ctx,
+ int argc,
+ sqlite3_value **argv
+){
+ JsonString *pStr;
+ const char *z;
+ u32 n;
+ pStr = (JsonString*)sqlite3_aggregate_context(ctx, sizeof(*pStr));
+ if( pStr ){
+ if( pStr->zBuf==0 ){
+ jsonInit(pStr, ctx);
+ jsonAppendChar(pStr, '{');
+ }else{
+ jsonAppendChar(pStr, ',');
+ pStr->pCtx = ctx;
+ }
+ z = (const char*)sqlite3_value_text(argv[0]);
+ n = (u32)sqlite3_value_bytes(argv[0]);
+ jsonAppendString(pStr, z, n);
+ jsonAppendChar(pStr, ':');
+ jsonAppendValue(pStr, argv[1]);
+ }
+}
+static void jsonObjectFinal(sqlite3_context *ctx){
+ JsonString *pStr;
+ pStr = (JsonString*)sqlite3_aggregate_context(ctx, 0);
+ if( pStr ){
+ jsonAppendChar(pStr, '}');
+ if( pStr->bErr ){
+ sqlite3_result_error_nomem(ctx);
+ assert( pStr->bStatic );
+ }else{
+ sqlite3_result_text(ctx, pStr->zBuf, pStr->nUsed,
+ pStr->bStatic ? SQLITE_TRANSIENT : sqlite3_free);
+ pStr->bStatic = 1;
+ }
+ }else{
+ sqlite3_result_text(ctx, "{}", 2, SQLITE_STATIC);
+ }
+ sqlite3_result_subtype(ctx, JSON_SUBTYPE);
+}
+
+
+#ifndef SQLITE_OMIT_VIRTUALTABLE
+/****************************************************************************
+** The json_each virtual table
+****************************************************************************/
+typedef struct JsonEachCursor JsonEachCursor;
+struct JsonEachCursor {
+ sqlite3_vtab_cursor base; /* Base class - must be first */
+ u32 iRowid; /* The rowid */
+ u32 iBegin; /* The first node of the scan */
+ u32 i; /* Index in sParse.aNode[] of current row */
+ u32 iEnd; /* EOF when i equals or exceeds this value */
+ u8 eType; /* Type of top-level element */
+ u8 bRecursive; /* True for json_tree(). False for json_each() */
+ char *zJson; /* Input JSON */
+ char *zRoot; /* Path by which to filter zJson */
+ JsonParse sParse; /* Parse of the input JSON */
+};
+
+/* Constructor for the json_each virtual table */
+static int jsonEachConnect(
+ sqlite3 *db,
+ void *pAux,
+ int argc, const char *const*argv,
+ sqlite3_vtab **ppVtab,
+ char **pzErr
+){
+ sqlite3_vtab *pNew;
+ int rc;
+
+/* Column numbers */
+#define JEACH_KEY 0
+#define JEACH_VALUE 1
+#define JEACH_TYPE 2
+#define JEACH_ATOM 3
+#define JEACH_ID 4
+#define JEACH_PARENT 5
+#define JEACH_FULLKEY 6
+#define JEACH_PATH 7
+#define JEACH_JSON 8
+#define JEACH_ROOT 9
+
+ UNUSED_PARAM(pzErr);
+ UNUSED_PARAM(argv);
+ UNUSED_PARAM(argc);
+ UNUSED_PARAM(pAux);
+ rc = sqlite3_declare_vtab(db,
+ "CREATE TABLE x(key,value,type,atom,id,parent,fullkey,path,"
+ "json HIDDEN,root HIDDEN)");
+ if( rc==SQLITE_OK ){
+ pNew = *ppVtab = sqlite3_malloc( sizeof(*pNew) );
+ if( pNew==0 ) return SQLITE_NOMEM;
+ memset(pNew, 0, sizeof(*pNew));
+ }
+ return rc;
+}
+
+/* destructor for json_each virtual table */
+static int jsonEachDisconnect(sqlite3_vtab *pVtab){
+ sqlite3_free(pVtab);
+ return SQLITE_OK;
+}
+
+/* constructor for a JsonEachCursor object for json_each(). */
+static int jsonEachOpenEach(sqlite3_vtab *p, sqlite3_vtab_cursor **ppCursor){
+ JsonEachCursor *pCur;
+
+ UNUSED_PARAM(p);
+ pCur = sqlite3_malloc( sizeof(*pCur) );
+ if( pCur==0 ) return SQLITE_NOMEM;
+ memset(pCur, 0, sizeof(*pCur));
+ *ppCursor = &pCur->base;
+ return SQLITE_OK;
+}
+
+/* constructor for a JsonEachCursor object for json_tree(). */
+static int jsonEachOpenTree(sqlite3_vtab *p, sqlite3_vtab_cursor **ppCursor){
+ int rc = jsonEachOpenEach(p, ppCursor);
+ if( rc==SQLITE_OK ){
+ JsonEachCursor *pCur = (JsonEachCursor*)*ppCursor;
+ pCur->bRecursive = 1;
+ }
+ return rc;
+}
+
+/* Reset a JsonEachCursor back to its original state. Free any memory
+** held. */
+static void jsonEachCursorReset(JsonEachCursor *p){
+ sqlite3_free(p->zJson);
+ sqlite3_free(p->zRoot);
+ jsonParseReset(&p->sParse);
+ p->iRowid = 0;
+ p->i = 0;
+ p->iEnd = 0;
+ p->eType = 0;
+ p->zJson = 0;
+ p->zRoot = 0;
+}
+
+/* Destructor for a jsonEachCursor object */
+static int jsonEachClose(sqlite3_vtab_cursor *cur){
+ JsonEachCursor *p = (JsonEachCursor*)cur;
+ jsonEachCursorReset(p);
+ sqlite3_free(cur);
+ return SQLITE_OK;
+}
+
+/* Return TRUE if the jsonEachCursor object has been advanced off the end
+** of the JSON object */
+static int jsonEachEof(sqlite3_vtab_cursor *cur){
+ JsonEachCursor *p = (JsonEachCursor*)cur;
+ return p->i >= p->iEnd;
+}
+
+/* Advance the cursor to the next element for json_tree() */
+static int jsonEachNext(sqlite3_vtab_cursor *cur){
+ JsonEachCursor *p = (JsonEachCursor*)cur;
+ if( p->bRecursive ){
+ if( p->sParse.aNode[p->i].jnFlags & JNODE_LABEL ) p->i++;
+ p->i++;
+ p->iRowid++;
+ if( p->i<p->iEnd ){
+ u32 iUp = p->sParse.aUp[p->i];
+ JsonNode *pUp = &p->sParse.aNode[iUp];
+ p->eType = pUp->eType;
+ if( pUp->eType==JSON_ARRAY ){
+ if( iUp==p->i-1 ){
+ pUp->u.iKey = 0;
+ }else{
+ pUp->u.iKey++;
+ }
+ }
+ }
+ }else{
+ switch( p->eType ){
+ case JSON_ARRAY: {
+ p->i += jsonNodeSize(&p->sParse.aNode[p->i]);
+ p->iRowid++;
+ break;
+ }
+ case JSON_OBJECT: {
+ p->i += 1 + jsonNodeSize(&p->sParse.aNode[p->i+1]);
+ p->iRowid++;
+ break;
+ }
+ default: {
+ p->i = p->iEnd;
+ break;
+ }
+ }
+ }
+ return SQLITE_OK;
+}
+
+/* Append the name of the path for element i to pStr
+*/
+static void jsonEachComputePath(
+ JsonEachCursor *p, /* The cursor */
+ JsonString *pStr, /* Write the path here */
+ u32 i /* Path to this element */
+){
+ JsonNode *pNode, *pUp;
+ u32 iUp;
+ if( i==0 ){
+ jsonAppendChar(pStr, '$');
+ return;
+ }
+ iUp = p->sParse.aUp[i];
+ jsonEachComputePath(p, pStr, iUp);
+ pNode = &p->sParse.aNode[i];
+ pUp = &p->sParse.aNode[iUp];
+ if( pUp->eType==JSON_ARRAY ){
+ jsonPrintf(30, pStr, "[%d]", pUp->u.iKey);
+ }else{
+ assert( pUp->eType==JSON_OBJECT );
+ if( (pNode->jnFlags & JNODE_LABEL)==0 ) pNode--;
+ assert( pNode->eType==JSON_STRING );
+ assert( pNode->jnFlags & JNODE_LABEL );
+ jsonPrintf(pNode->n+1, pStr, ".%.*s", pNode->n-2, pNode->u.zJContent+1);
+ }
+}
+
+/* Return the value of a column */
+static int jsonEachColumn(
+ sqlite3_vtab_cursor *cur, /* The cursor */
+ sqlite3_context *ctx, /* First argument to sqlite3_result_...() */
+ int i /* Which column to return */
+){
+ JsonEachCursor *p = (JsonEachCursor*)cur;
+ JsonNode *pThis = &p->sParse.aNode[p->i];
+ switch( i ){
+ case JEACH_KEY: {
+ if( p->i==0 ) break;
+ if( p->eType==JSON_OBJECT ){
+ jsonReturn(pThis, ctx, 0);
+ }else if( p->eType==JSON_ARRAY ){
+ u32 iKey;
+ if( p->bRecursive ){
+ if( p->iRowid==0 ) break;
+ iKey = p->sParse.aNode[p->sParse.aUp[p->i]].u.iKey;
+ }else{
+ iKey = p->iRowid;
+ }
+ sqlite3_result_int64(ctx, (sqlite3_int64)iKey);
+ }
+ break;
+ }
+ case JEACH_VALUE: {
+ if( pThis->jnFlags & JNODE_LABEL ) pThis++;
+ jsonReturn(pThis, ctx, 0);
+ break;
+ }
+ case JEACH_TYPE: {
+ if( pThis->jnFlags & JNODE_LABEL ) pThis++;
+ sqlite3_result_text(ctx, jsonType[pThis->eType], -1, SQLITE_STATIC);
+ break;
+ }
+ case JEACH_ATOM: {
+ if( pThis->jnFlags & JNODE_LABEL ) pThis++;
+ if( pThis->eType>=JSON_ARRAY ) break;
+ jsonReturn(pThis, ctx, 0);
+ break;
+ }
+ case JEACH_ID: {
+ sqlite3_result_int64(ctx,
+ (sqlite3_int64)p->i + ((pThis->jnFlags & JNODE_LABEL)!=0));
+ break;
+ }
+ case JEACH_PARENT: {
+ if( p->i>p->iBegin && p->bRecursive ){
+ sqlite3_result_int64(ctx, (sqlite3_int64)p->sParse.aUp[p->i]);
+ }
+ break;
+ }
+ case JEACH_FULLKEY: {
+ JsonString x;
+ jsonInit(&x, ctx);
+ if( p->bRecursive ){
+ jsonEachComputePath(p, &x, p->i);
+ }else{
+ if( p->zRoot ){
+ jsonAppendRaw(&x, p->zRoot, (int)strlen(p->zRoot));
+ }else{
+ jsonAppendChar(&x, '$');
+ }
+ if( p->eType==JSON_ARRAY ){
+ jsonPrintf(30, &x, "[%d]", p->iRowid);
+ }else{
+ jsonPrintf(pThis->n, &x, ".%.*s", pThis->n-2, pThis->u.zJContent+1);
+ }
+ }
+ jsonResult(&x);
+ break;
+ }
+ case JEACH_PATH: {
+ if( p->bRecursive ){
+ JsonString x;
+ jsonInit(&x, ctx);
+ jsonEachComputePath(p, &x, p->sParse.aUp[p->i]);
+ jsonResult(&x);
+ break;
+ }
+ /* For json_each() path and root are the same so fall through
+ ** into the root case */
+ }
+ case JEACH_ROOT: {
+ const char *zRoot = p->zRoot;
+ if( zRoot==0 ) zRoot = "$";
+ sqlite3_result_text(ctx, zRoot, -1, SQLITE_STATIC);
+ break;
+ }
+ case JEACH_JSON: {
+ assert( i==JEACH_JSON );
+ sqlite3_result_text(ctx, p->sParse.zJson, -1, SQLITE_STATIC);
+ break;
+ }
+ }
+ return SQLITE_OK;
+}
+
+/* Return the current rowid value */
+static int jsonEachRowid(sqlite3_vtab_cursor *cur, sqlite_int64 *pRowid){
+ JsonEachCursor *p = (JsonEachCursor*)cur;
+ *pRowid = p->iRowid;
+ return SQLITE_OK;
+}
+
+/* The query strategy is to look for an equality constraint on the json
+** column. Without such a constraint, the table cannot operate. idxNum is
+** 1 if the constraint is found, 3 if the constraint and zRoot are found,
+** and 0 otherwise.
+*/
+static int jsonEachBestIndex(
+ sqlite3_vtab *tab,
+ sqlite3_index_info *pIdxInfo
+){
+ int i;
+ int jsonIdx = -1;
+ int rootIdx = -1;
+ const struct sqlite3_index_constraint *pConstraint;
+
+ UNUSED_PARAM(tab);
+ pConstraint = pIdxInfo->aConstraint;
+ for(i=0; i<pIdxInfo->nConstraint; i++, pConstraint++){
+ if( pConstraint->usable==0 ) continue;
+ if( pConstraint->op!=SQLITE_INDEX_CONSTRAINT_EQ ) continue;
+ switch( pConstraint->iColumn ){
+ case JEACH_JSON: jsonIdx = i; break;
+ case JEACH_ROOT: rootIdx = i; break;
+ default: /* no-op */ break;
+ }
+ }
+ if( jsonIdx<0 ){
+ pIdxInfo->idxNum = 0;
+ pIdxInfo->estimatedCost = 1e99;
+ }else{
+ pIdxInfo->estimatedCost = 1.0;
+ pIdxInfo->aConstraintUsage[jsonIdx].argvIndex = 1;
+ pIdxInfo->aConstraintUsage[jsonIdx].omit = 1;
+ if( rootIdx<0 ){
+ pIdxInfo->idxNum = 1;
+ }else{
+ pIdxInfo->aConstraintUsage[rootIdx].argvIndex = 2;
+ pIdxInfo->aConstraintUsage[rootIdx].omit = 1;
+ pIdxInfo->idxNum = 3;
+ }
+ }
+ return SQLITE_OK;
+}
+
+/* Start a search on a new JSON string */
+static int jsonEachFilter(
+ sqlite3_vtab_cursor *cur,
+ int idxNum, const char *idxStr,
+ int argc, sqlite3_value **argv
+){
+ JsonEachCursor *p = (JsonEachCursor*)cur;
+ const char *z;
+ const char *zRoot = 0;
+ sqlite3_int64 n;
+
+ UNUSED_PARAM(idxStr);
+ UNUSED_PARAM(argc);
+ jsonEachCursorReset(p);
+ if( idxNum==0 ) return SQLITE_OK;
+ z = (const char*)sqlite3_value_text(argv[0]);
+ if( z==0 ) return SQLITE_OK;
+ n = sqlite3_value_bytes(argv[0]);
+ p->zJson = sqlite3_malloc64( n+1 );
+ if( p->zJson==0 ) return SQLITE_NOMEM;
+ memcpy(p->zJson, z, (size_t)n+1);
+ if( jsonParse(&p->sParse, 0, p->zJson) ){
+ int rc = SQLITE_NOMEM;
+ if( p->sParse.oom==0 ){
+ sqlite3_free(cur->pVtab->zErrMsg);
+ cur->pVtab->zErrMsg = sqlite3_mprintf("malformed JSON");
+ if( cur->pVtab->zErrMsg ) rc = SQLITE_ERROR;
+ }
+ jsonEachCursorReset(p);
+ return rc;
+ }else if( p->bRecursive && jsonParseFindParents(&p->sParse) ){
+ jsonEachCursorReset(p);
+ return SQLITE_NOMEM;
+ }else{
+ JsonNode *pNode = 0;
+ if( idxNum==3 ){
+ const char *zErr = 0;
+ zRoot = (const char*)sqlite3_value_text(argv[1]);
+ if( zRoot==0 ) return SQLITE_OK;
+ n = sqlite3_value_bytes(argv[1]);
+ p->zRoot = sqlite3_malloc64( n+1 );
+ if( p->zRoot==0 ) return SQLITE_NOMEM;
+ memcpy(p->zRoot, zRoot, (size_t)n+1);
+ if( zRoot[0]!='$' ){
+ zErr = zRoot;
+ }else{
+ pNode = jsonLookupStep(&p->sParse, 0, p->zRoot+1, 0, &zErr);
+ }
+ if( zErr ){
+ sqlite3_free(cur->pVtab->zErrMsg);
+ cur->pVtab->zErrMsg = jsonPathSyntaxError(zErr);
+ jsonEachCursorReset(p);
+ return cur->pVtab->zErrMsg ? SQLITE_ERROR : SQLITE_NOMEM;
+ }else if( pNode==0 ){
+ return SQLITE_OK;
+ }
+ }else{
+ pNode = p->sParse.aNode;
+ }
+ p->iBegin = p->i = (int)(pNode - p->sParse.aNode);
+ p->eType = pNode->eType;
+ if( p->eType>=JSON_ARRAY ){
+ pNode->u.iKey = 0;
+ p->iEnd = p->i + pNode->n + 1;
+ if( p->bRecursive ){
+ p->eType = p->sParse.aNode[p->sParse.aUp[p->i]].eType;
+ if( p->i>0 && (p->sParse.aNode[p->i-1].jnFlags & JNODE_LABEL)!=0 ){
+ p->i--;
+ }
+ }else{
+ p->i++;
+ }
+ }else{
+ p->iEnd = p->i+1;
+ }
+ }
+ return SQLITE_OK;
+}
+
+/* The methods of the json_each virtual table */
+static sqlite3_module jsonEachModule = {
+ 0, /* iVersion */
+ 0, /* xCreate */
+ jsonEachConnect, /* xConnect */
+ jsonEachBestIndex, /* xBestIndex */
+ jsonEachDisconnect, /* xDisconnect */
+ 0, /* xDestroy */
+ jsonEachOpenEach, /* xOpen - open a cursor */
+ jsonEachClose, /* xClose - close a cursor */
+ jsonEachFilter, /* xFilter - configure scan constraints */
+ jsonEachNext, /* xNext - advance a cursor */
+ jsonEachEof, /* xEof - check for end of scan */
+ jsonEachColumn, /* xColumn - read data */
+ jsonEachRowid, /* xRowid - read data */
+ 0, /* xUpdate */
+ 0, /* xBegin */
+ 0, /* xSync */
+ 0, /* xCommit */
+ 0, /* xRollback */
+ 0, /* xFindMethod */
+ 0, /* xRename */
+ 0, /* xSavepoint */
+ 0, /* xRelease */
+ 0 /* xRollbackTo */
+};
+
+/* The methods of the json_tree virtual table. */
+static sqlite3_module jsonTreeModule = {
+ 0, /* iVersion */
+ 0, /* xCreate */
+ jsonEachConnect, /* xConnect */
+ jsonEachBestIndex, /* xBestIndex */
+ jsonEachDisconnect, /* xDisconnect */
+ 0, /* xDestroy */
+ jsonEachOpenTree, /* xOpen - open a cursor */
+ jsonEachClose, /* xClose - close a cursor */
+ jsonEachFilter, /* xFilter - configure scan constraints */
+ jsonEachNext, /* xNext - advance a cursor */
+ jsonEachEof, /* xEof - check for end of scan */
+ jsonEachColumn, /* xColumn - read data */
+ jsonEachRowid, /* xRowid - read data */
+ 0, /* xUpdate */
+ 0, /* xBegin */
+ 0, /* xSync */
+ 0, /* xCommit */
+ 0, /* xRollback */
+ 0, /* xFindMethod */
+ 0, /* xRename */
+ 0, /* xSavepoint */
+ 0, /* xRelease */
+ 0 /* xRollbackTo */
+};
+#endif /* SQLITE_OMIT_VIRTUALTABLE */
+
+/****************************************************************************
+** The following routines are the only publically visible identifiers in this
+** file. Call the following routines in order to register the various SQL
+** functions and the virtual table implemented by this file.
+****************************************************************************/
+
+SQLITE_PRIVATE int sqlite3Json1Init(sqlite3 *db){
+ int rc = SQLITE_OK;
+ unsigned int i;
+ static const struct {
+ const char *zName;
+ int nArg;
+ int flag;
+ void (*xFunc)(sqlite3_context*,int,sqlite3_value**);
+ } aFunc[] = {
+ { "json", 1, 0, jsonRemoveFunc },
+ { "json_array", -1, 0, jsonArrayFunc },
+ { "json_array_length", 1, 0, jsonArrayLengthFunc },
+ { "json_array_length", 2, 0, jsonArrayLengthFunc },
+ { "json_extract", -1, 0, jsonExtractFunc },
+ { "json_insert", -1, 0, jsonSetFunc },
+ { "json_object", -1, 0, jsonObjectFunc },
+ { "json_remove", -1, 0, jsonRemoveFunc },
+ { "json_replace", -1, 0, jsonReplaceFunc },
+ { "json_set", -1, 1, jsonSetFunc },
+ { "json_type", 1, 0, jsonTypeFunc },
+ { "json_type", 2, 0, jsonTypeFunc },
+ { "json_valid", 1, 0, jsonValidFunc },
+
+#if SQLITE_DEBUG
+ /* DEBUG and TESTING functions */
+ { "json_parse", 1, 0, jsonParseFunc },
+ { "json_test1", 1, 0, jsonTest1Func },
+#endif
+ };
+ static const struct {
+ const char *zName;
+ int nArg;
+ void (*xStep)(sqlite3_context*,int,sqlite3_value**);
+ void (*xFinal)(sqlite3_context*);
+ } aAgg[] = {
+ { "json_group_array", 1, jsonArrayStep, jsonArrayFinal },
+ { "json_group_object", 2, jsonObjectStep, jsonObjectFinal },
+ };
+#ifndef SQLITE_OMIT_VIRTUALTABLE
+ static const struct {
+ const char *zName;
+ sqlite3_module *pModule;
+ } aMod[] = {
+ { "json_each", &jsonEachModule },
+ { "json_tree", &jsonTreeModule },
+ };
+#endif
+ for(i=0; i<sizeof(aFunc)/sizeof(aFunc[0]) && rc==SQLITE_OK; i++){
+ rc = sqlite3_create_function(db, aFunc[i].zName, aFunc[i].nArg,
+ SQLITE_UTF8 | SQLITE_DETERMINISTIC,
+ (void*)&aFunc[i].flag,
+ aFunc[i].xFunc, 0, 0);
+ }
+ for(i=0; i<sizeof(aAgg)/sizeof(aAgg[0]) && rc==SQLITE_OK; i++){
+ rc = sqlite3_create_function(db, aAgg[i].zName, aAgg[i].nArg,
+ SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+ 0, aAgg[i].xStep, aAgg[i].xFinal);
+ }
+#ifndef SQLITE_OMIT_VIRTUALTABLE
+ for(i=0; i<sizeof(aMod)/sizeof(aMod[0]) && rc==SQLITE_OK; i++){
+ rc = sqlite3_create_module(db, aMod[i].zName, aMod[i].pModule, 0);
+ }
+#endif
+ return rc;
+}
+
+
+#ifndef SQLITE_CORE
+#ifdef _WIN32
+__declspec(dllexport)
+#endif
+SQLITE_API int SQLITE_STDCALL sqlite3_json_init(
+ sqlite3 *db,
+ char **pzErrMsg,
+ const sqlite3_api_routines *pApi
+){
+ SQLITE_EXTENSION_INIT2(pApi);
+ (void)pzErrMsg; /* Unused parameter */
+ return sqlite3Json1Init(db);
+}
+#endif
+#endif /* !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_JSON1) */
+
+/************** End of json1.c ***********************************************/
+/************** Begin file fts5.c ********************************************/
+
+
+#if !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_FTS5)
+
+#if !defined(NDEBUG) && !defined(SQLITE_DEBUG)
+# define NDEBUG 1
+#endif
+#if defined(NDEBUG) && defined(SQLITE_DEBUG)
+# undef NDEBUG
+#endif
+
+/*
+** 2014 May 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.
+**
+******************************************************************************
+**
+** Interfaces to extend FTS5. Using the interfaces defined in this file,
+** FTS5 may be extended with:
+**
+** * custom tokenizers, and
+** * custom auxiliary functions.
+*/
+
+
+#ifndef _FTS5_H
+#define _FTS5_H
+
+/* #include "sqlite3.h" */
+
+#if 0
+extern "C" {
+#endif
+
+/*************************************************************************
+** CUSTOM AUXILIARY FUNCTIONS
+**
+** Virtual table implementations may overload SQL functions by implementing
+** the sqlite3_module.xFindFunction() method.
+*/
+
+typedef struct Fts5ExtensionApi Fts5ExtensionApi;
+typedef struct Fts5Context Fts5Context;
+typedef struct Fts5PhraseIter Fts5PhraseIter;
+
+typedef void (*fts5_extension_function)(
+ const Fts5ExtensionApi *pApi, /* API offered by current FTS version */
+ Fts5Context *pFts, /* First arg to pass to pApi functions */
+ sqlite3_context *pCtx, /* Context for returning result/error */
+ int nVal, /* Number of values in apVal[] array */
+ sqlite3_value **apVal /* Array of trailing arguments */
+);
+
+struct Fts5PhraseIter {
+ const unsigned char *a;
+ const unsigned char *b;
+};
+
+/*
+** EXTENSION API FUNCTIONS
+**
+** xUserData(pFts):
+** Return a copy of the context pointer the extension function was
+** registered with.
+**
+** xColumnTotalSize(pFts, iCol, pnToken):
+** If parameter iCol is less than zero, set output variable *pnToken
+** to the total number of tokens in the FTS5 table. Or, if iCol is
+** non-negative but less than the number of columns in the table, return
+** the total number of tokens in column iCol, considering all rows in
+** the FTS5 table.
+**
+** If parameter iCol is greater than or equal to the number of columns
+** in the table, SQLITE_RANGE is returned. Or, if an error occurs (e.g.
+** an OOM condition or IO error), an appropriate SQLite error code is
+** returned.
+**
+** xColumnCount(pFts):
+** Return the number of columns in the table.
+**
+** xColumnSize(pFts, iCol, pnToken):
+** If parameter iCol is less than zero, set output variable *pnToken
+** to the total number of tokens in the current row. Or, if iCol is
+** non-negative but less than the number of columns in the table, set
+** *pnToken to the number of tokens in column iCol of the current row.
+**
+** If parameter iCol is greater than or equal to the number of columns
+** in the table, SQLITE_RANGE is returned. Or, if an error occurs (e.g.
+** an OOM condition or IO error), an appropriate SQLite error code is
+** returned.
+**
+** xColumnText:
+** This function attempts to retrieve the text of column iCol of the
+** current document. If successful, (*pz) is set to point to a buffer
+** containing the text in utf-8 encoding, (*pn) is set to the size in bytes
+** (not characters) of the buffer and SQLITE_OK is returned. Otherwise,
+** if an error occurs, an SQLite error code is returned and the final values
+** of (*pz) and (*pn) are undefined.
+**
+** xPhraseCount:
+** Returns the number of phrases in the current query expression.
+**
+** xPhraseSize:
+** Returns the number of tokens in phrase iPhrase of the query. Phrases
+** are numbered starting from zero.
+**
+** xInstCount:
+** Set *pnInst to the total number of occurrences of all phrases within
+** the query within the current row. Return SQLITE_OK if successful, or
+** an error code (i.e. SQLITE_NOMEM) if an error occurs.
+**
+** xInst:
+** Query for the details of phrase match iIdx within the current row.
+** Phrase matches are numbered starting from zero, so the iIdx argument
+** should be greater than or equal to zero and smaller than the value
+** output by xInstCount().
+**
+** Returns SQLITE_OK if successful, or an error code (i.e. SQLITE_NOMEM)
+** if an error occurs.
+**
+** xRowid:
+** Returns the rowid of the current row.
+**
+** xTokenize:
+** Tokenize text using the tokenizer belonging to the FTS5 table.
+**
+** xQueryPhrase(pFts5, iPhrase, pUserData, xCallback):
+** This API function is used to query the FTS table for phrase iPhrase
+** of the current query. Specifically, a query equivalent to:
+**
+** ... FROM ftstable WHERE ftstable MATCH $p ORDER BY rowid
+**
+** with $p set to a phrase equivalent to the phrase iPhrase of the
+** current query is executed. For each row visited, the callback function
+** passed as the fourth argument is invoked. The context and API objects
+** passed to the callback function may be used to access the properties of
+** each matched row. Invoking Api.xUserData() returns a copy of the pointer
+** passed as the third argument to pUserData.
+**
+** If the callback function returns any value other than SQLITE_OK, the
+** query is abandoned and the xQueryPhrase function returns immediately.
+** If the returned value is SQLITE_DONE, xQueryPhrase returns SQLITE_OK.
+** Otherwise, the error code is propagated upwards.
+**
+** If the query runs to completion without incident, SQLITE_OK is returned.
+** Or, if some error occurs before the query completes or is aborted by
+** the callback, an SQLite error code is returned.
+**
+**
+** xSetAuxdata(pFts5, pAux, xDelete)
+**
+** Save the pointer passed as the second argument as the extension functions
+** "auxiliary data". The pointer may then be retrieved by the current or any
+** future invocation of the same fts5 extension function made as part of
+** of the same MATCH query using the xGetAuxdata() API.
+**
+** Each extension function is allocated a single auxiliary data slot for
+** each FTS query (MATCH expression). If the extension function is invoked
+** more than once for a single FTS query, then all invocations share a
+** single auxiliary data context.
+**
+** If there is already an auxiliary data pointer when this function is
+** invoked, then it is replaced by the new pointer. If an xDelete callback
+** was specified along with the original pointer, it is invoked at this
+** point.
+**
+** The xDelete callback, if one is specified, is also invoked on the
+** auxiliary data pointer after the FTS5 query has finished.
+**
+** If an error (e.g. an OOM condition) occurs within this function, an
+** the auxiliary data is set to NULL and an error code returned. If the
+** xDelete parameter was not NULL, it is invoked on the auxiliary data
+** pointer before returning.
+**
+**
+** xGetAuxdata(pFts5, bClear)
+**
+** Returns the current auxiliary data pointer for the fts5 extension
+** function. See the xSetAuxdata() method for details.
+**
+** If the bClear argument is non-zero, then the auxiliary data is cleared
+** (set to NULL) before this function returns. In this case the xDelete,
+** if any, is not invoked.
+**
+**
+** xRowCount(pFts5, pnRow)
+**
+** This function is used to retrieve the total number of rows in the table.
+** In other words, the same value that would be returned by:
+**
+** SELECT count(*) FROM ftstable;
+**
+** xPhraseFirst()
+** This function is used, along with type Fts5PhraseIter and the xPhraseNext
+** method, to iterate through all instances of a single query phrase within
+** the current row. This is the same information as is accessible via the
+** xInstCount/xInst APIs. While the xInstCount/xInst APIs are more convenient
+** to use, this API may be faster under some circumstances. To iterate
+** through instances of phrase iPhrase, use the following code:
+**
+** Fts5PhraseIter iter;
+** int iCol, iOff;
+** for(pApi->xPhraseFirst(pFts, iPhrase, &iter, &iCol, &iOff);
+** iOff>=0;
+** pApi->xPhraseNext(pFts, &iter, &iCol, &iOff)
+** ){
+** // An instance of phrase iPhrase at offset iOff of column iCol
+** }
+**
+** The Fts5PhraseIter structure is defined above. Applications should not
+** modify this structure directly - it should only be used as shown above
+** with the xPhraseFirst() and xPhraseNext() API methods.
+**
+** xPhraseNext()
+** See xPhraseFirst above.
+*/
+struct Fts5ExtensionApi {
+ int iVersion; /* Currently always set to 1 */
+
+ void *(*xUserData)(Fts5Context*);
+
+ int (*xColumnCount)(Fts5Context*);
+ int (*xRowCount)(Fts5Context*, sqlite3_int64 *pnRow);
+ int (*xColumnTotalSize)(Fts5Context*, int iCol, sqlite3_int64 *pnToken);
+
+ int (*xTokenize)(Fts5Context*,
+ const char *pText, int nText, /* Text to tokenize */
+ void *pCtx, /* Context passed to xToken() */
+ int (*xToken)(void*, int, const char*, int, int, int) /* Callback */
+ );
+
+ int (*xPhraseCount)(Fts5Context*);
+ int (*xPhraseSize)(Fts5Context*, int iPhrase);
+
+ int (*xInstCount)(Fts5Context*, int *pnInst);
+ int (*xInst)(Fts5Context*, int iIdx, int *piPhrase, int *piCol, int *piOff);
+
+ sqlite3_int64 (*xRowid)(Fts5Context*);
+ int (*xColumnText)(Fts5Context*, int iCol, const char **pz, int *pn);
+ int (*xColumnSize)(Fts5Context*, int iCol, int *pnToken);
+
+ int (*xQueryPhrase)(Fts5Context*, int iPhrase, void *pUserData,
+ int(*)(const Fts5ExtensionApi*,Fts5Context*,void*)
+ );
+ int (*xSetAuxdata)(Fts5Context*, void *pAux, void(*xDelete)(void*));
+ void *(*xGetAuxdata)(Fts5Context*, int bClear);
+
+ void (*xPhraseFirst)(Fts5Context*, int iPhrase, Fts5PhraseIter*, int*, int*);
+ void (*xPhraseNext)(Fts5Context*, Fts5PhraseIter*, int *piCol, int *piOff);
+};
+
+/*
+** CUSTOM AUXILIARY FUNCTIONS
+*************************************************************************/
+
+/*************************************************************************
+** CUSTOM TOKENIZERS
+**
+** Applications may also register custom tokenizer types. A tokenizer
+** is registered by providing fts5 with a populated instance of the
+** following structure. All structure methods must be defined, setting
+** any member of the fts5_tokenizer struct to NULL leads to undefined
+** behaviour. The structure methods are expected to function as follows:
+**
+** xCreate:
+** This function is used to allocate and inititalize a tokenizer instance.
+** A tokenizer instance is required to actually tokenize text.
+**
+** The first argument passed to this function is a copy of the (void*)
+** pointer provided by the application when the fts5_tokenizer object
+** was registered with FTS5 (the third argument to xCreateTokenizer()).
+** The second and third arguments are an array of nul-terminated strings
+** containing the tokenizer arguments, if any, specified following the
+** tokenizer name as part of the CREATE VIRTUAL TABLE statement used
+** to create the FTS5 table.
+**
+** The final argument is an output variable. If successful, (*ppOut)
+** should be set to point to the new tokenizer handle and SQLITE_OK
+** returned. If an error occurs, some value other than SQLITE_OK should
+** be returned. In this case, fts5 assumes that the final value of *ppOut
+** is undefined.
+**
+** xDelete:
+** This function is invoked to delete a tokenizer handle previously
+** allocated using xCreate(). Fts5 guarantees that this function will
+** be invoked exactly once for each successful call to xCreate().
+**
+** xTokenize:
+** This function is expected to tokenize the nText byte string indicated
+** by argument pText. pText may or may not be nul-terminated. The first
+** argument passed to this function is a pointer to an Fts5Tokenizer object
+** returned by an earlier call to xCreate().
+**
+** The second argument indicates the reason that FTS5 is requesting
+** tokenization of the supplied text. This is always one of the following
+** four values:
+**
+** <ul><li> <b>FTS5_TOKENIZE_DOCUMENT</b> - A document is being inserted into
+** or removed from the FTS table. The tokenizer is being invoked to
+** determine the set of tokens to add to (or delete from) the
+** FTS index.
+**
+** <li> <b>FTS5_TOKENIZE_QUERY</b> - A MATCH query is being executed
+** against the FTS index. The tokenizer is being called to tokenize
+** a bareword or quoted string specified as part of the query.
+**
+** <li> <b>(FTS5_TOKENIZE_QUERY | FTS5_TOKENIZE_PREFIX)</b> - Same as
+** FTS5_TOKENIZE_QUERY, except that the bareword or quoted string is
+** followed by a "*" character, indicating that the last token
+** returned by the tokenizer will be treated as a token prefix.
+**
+** <li> <b>FTS5_TOKENIZE_AUX</b> - The tokenizer is being invoked to
+** satisfy an fts5_api.xTokenize() request made by an auxiliary
+** function. Or an fts5_api.xColumnSize() request made by the same
+** on a columnsize=0 database.
+** </ul>
+**
+** For each token in the input string, the supplied callback xToken() must
+** be invoked. The first argument to it should be a copy of the pointer
+** passed as the second argument to xTokenize(). The third and fourth
+** arguments are a pointer to a buffer containing the token text, and the
+** size of the token in bytes. The 4th and 5th arguments are the byte offsets
+** of the first byte of and first byte immediately following the text from
+** which the token is derived within the input.
+**
+** The second argument passed to the xToken() callback ("tflags") should
+** normally be set to 0. The exception is if the tokenizer supports
+** synonyms. In this case see the discussion below for details.
+**
+** FTS5 assumes the xToken() callback is invoked for each token in the
+** order that they occur within the input text.
+**
+** If an xToken() callback returns any value other than SQLITE_OK, then
+** the tokenization should be abandoned and the xTokenize() method should
+** immediately return a copy of the xToken() return value. Or, if the
+** input buffer is exhausted, xTokenize() should return SQLITE_OK. Finally,
+** if an error occurs with the xTokenize() implementation itself, it
+** may abandon the tokenization and return any error code other than
+** SQLITE_OK or SQLITE_DONE.
+**
+** SYNONYM SUPPORT
+**
+** Custom tokenizers may also support synonyms. Consider a case in which a
+** user wishes to query for a phrase such as "first place". Using the
+** built-in tokenizers, the FTS5 query 'first + place' will match instances
+** of "first place" within the document set, but not alternative forms
+** such as "1st place". In some applications, it would be better to match
+** all instances of "first place" or "1st place" regardless of which form
+** the user specified in the MATCH query text.
+**
+** There are several ways to approach this in FTS5:
+**
+** <ol><li> By mapping all synonyms to a single token. In this case, the
+** In the above example, this means that the tokenizer returns the
+** same token for inputs "first" and "1st". Say that token is in
+** fact "first", so that when the user inserts the document "I won
+** 1st place" entries are added to the index for tokens "i", "won",
+** "first" and "place". If the user then queries for '1st + place',
+** the tokenizer substitutes "first" for "1st" and the query works
+** as expected.
+**
+** <li> By adding multiple synonyms for a single term to the FTS index.
+** In this case, when tokenizing query text, the tokenizer may
+** provide multiple synonyms for a single term within the document.
+** FTS5 then queries the index for each synonym individually. For
+** example, faced with the query:
+**
+** <codeblock>
+** ... MATCH 'first place'</codeblock>
+**
+** the tokenizer offers both "1st" and "first" as synonyms for the
+** first token in the MATCH query and FTS5 effectively runs a query
+** similar to:
+**
+** <codeblock>
+** ... MATCH '(first OR 1st) place'</codeblock>
+**
+** except that, for the purposes of auxiliary functions, the query
+** still appears to contain just two phrases - "(first OR 1st)"
+** being treated as a single phrase.
+**
+** <li> By adding multiple synonyms for a single term to the FTS index.
+** Using this method, when tokenizing document text, the tokenizer
+** provides multiple synonyms for each token. So that when a
+** document such as "I won first place" is tokenized, entries are
+** added to the FTS index for "i", "won", "first", "1st" and
+** "place".
+**
+** This way, even if the tokenizer does not provide synonyms
+** when tokenizing query text (it should not - to do would be
+** inefficient), it doesn't matter if the user queries for
+** 'first + place' or '1st + place', as there are entires in the
+** FTS index corresponding to both forms of the first token.
+** </ol>
+**
+** Whether it is parsing document or query text, any call to xToken that
+** specifies a <i>tflags</i> argument with the FTS5_TOKEN_COLOCATED bit
+** is considered to supply a synonym for the previous token. For example,
+** when parsing the document "I won first place", a tokenizer that supports
+** synonyms would call xToken() 5 times, as follows:
+**
+** <codeblock>
+** xToken(pCtx, 0, "i", 1, 0, 1);
+** xToken(pCtx, 0, "won", 3, 2, 5);
+** xToken(pCtx, 0, "first", 5, 6, 11);
+** xToken(pCtx, FTS5_TOKEN_COLOCATED, "1st", 3, 6, 11);
+** xToken(pCtx, 0, "place", 5, 12, 17);
+**</codeblock>
+**
+** It is an error to specify the FTS5_TOKEN_COLOCATED flag the first time
+** xToken() is called. Multiple synonyms may be specified for a single token
+** by making multiple calls to xToken(FTS5_TOKEN_COLOCATED) in sequence.
+** There is no limit to the number of synonyms that may be provided for a
+** single token.
+**
+** In many cases, method (1) above is the best approach. It does not add
+** extra data to the FTS index or require FTS5 to query for multiple terms,
+** so it is efficient in terms of disk space and query speed. However, it
+** does not support prefix queries very well. If, as suggested above, the
+** token "first" is subsituted for "1st" by the tokenizer, then the query:
+**
+** <codeblock>
+** ... MATCH '1s*'</codeblock>
+**
+** will not match documents that contain the token "1st" (as the tokenizer
+** will probably not map "1s" to any prefix of "first").
+**
+** For full prefix support, method (3) may be preferred. In this case,
+** because the index contains entries for both "first" and "1st", prefix
+** queries such as 'fi*' or '1s*' will match correctly. However, because
+** extra entries are added to the FTS index, this method uses more space
+** within the database.
+**
+** Method (2) offers a midpoint between (1) and (3). Using this method,
+** a query such as '1s*' will match documents that contain the literal
+** token "1st", but not "first" (assuming the tokenizer is not able to
+** provide synonyms for prefixes). However, a non-prefix query like '1st'
+** will match against "1st" and "first". This method does not require
+** extra disk space, as no extra entries are added to the FTS index.
+** On the other hand, it may require more CPU cycles to run MATCH queries,
+** as separate queries of the FTS index are required for each synonym.
+**
+** When using methods (2) or (3), it is important that the tokenizer only
+** provide synonyms when tokenizing document text (method (2)) or query
+** text (method (3)), not both. Doing so will not cause any errors, but is
+** inefficient.
+*/
+typedef struct Fts5Tokenizer Fts5Tokenizer;
+typedef struct fts5_tokenizer fts5_tokenizer;
+struct fts5_tokenizer {
+ int (*xCreate)(void*, const char **azArg, int nArg, Fts5Tokenizer **ppOut);
+ void (*xDelete)(Fts5Tokenizer*);
+ int (*xTokenize)(Fts5Tokenizer*,
+ void *pCtx,
+ int flags, /* Mask of FTS5_TOKENIZE_* flags */
+ const char *pText, int nText,
+ int (*xToken)(
+ void *pCtx, /* Copy of 2nd argument to xTokenize() */
+ int tflags, /* Mask of FTS5_TOKEN_* flags */
+ const char *pToken, /* Pointer to buffer containing token */
+ int nToken, /* Size of token in bytes */
+ int iStart, /* Byte offset of token within input text */
+ int iEnd /* Byte offset of end of token within input text */
+ )
+ );
+};
+
+/* Flags that may be passed as the third argument to xTokenize() */
+#define FTS5_TOKENIZE_QUERY 0x0001
+#define FTS5_TOKENIZE_PREFIX 0x0002
+#define FTS5_TOKENIZE_DOCUMENT 0x0004
+#define FTS5_TOKENIZE_AUX 0x0008
+
+/* Flags that may be passed by the tokenizer implementation back to FTS5
+** as the third argument to the supplied xToken callback. */
+#define FTS5_TOKEN_COLOCATED 0x0001 /* Same position as prev. token */
+
+/*
+** END OF CUSTOM TOKENIZERS
+*************************************************************************/
+
+/*************************************************************************
+** FTS5 EXTENSION REGISTRATION API
+*/
+typedef struct fts5_api fts5_api;
+struct fts5_api {
+ int iVersion; /* Currently always set to 2 */
+
+ /* Create a new tokenizer */
+ int (*xCreateTokenizer)(
+ fts5_api *pApi,
+ const char *zName,
+ void *pContext,
+ fts5_tokenizer *pTokenizer,
+ void (*xDestroy)(void*)
+ );
+
+ /* Find an existing tokenizer */
+ int (*xFindTokenizer)(
+ fts5_api *pApi,
+ const char *zName,
+ void **ppContext,
+ fts5_tokenizer *pTokenizer
+ );
+
+ /* Create a new auxiliary function */
+ int (*xCreateFunction)(
+ fts5_api *pApi,
+ const char *zName,
+ void *pContext,
+ fts5_extension_function xFunction,
+ void (*xDestroy)(void*)
+ );
+};
+
+/*
+** END OF REGISTRATION API
+*************************************************************************/
+
+#if 0
+} /* end of the 'extern "C"' block */
+#endif
+
+#endif /* _FTS5_H */
+
+
+/*
+** 2014 May 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.
+**
+******************************************************************************
+**
+*/
+#ifndef _FTS5INT_H
+#define _FTS5INT_H
+
+/* #include "fts5.h" */
+/* #include "sqlite3ext.h" */
+SQLITE_EXTENSION_INIT1
+
+/* #include <string.h> */
+/* #include <assert.h> */
+
+#ifndef SQLITE_AMALGAMATION
+
+typedef unsigned char u8;
+typedef unsigned int u32;
+typedef unsigned short u16;
+typedef sqlite3_int64 i64;
+typedef sqlite3_uint64 u64;
+
+#define ArraySize(x) (sizeof(x) / sizeof(x[0]))
+
+#define testcase(x)
+#define ALWAYS(x) 1
+#define NEVER(x) 0
+
+#define MIN(x,y) (((x) < (y)) ? (x) : (y))
+#define MAX(x,y) (((x) > (y)) ? (x) : (y))
+
+/*
+** Constants for the largest and smallest possible 64-bit signed integers.
+*/
+# define LARGEST_INT64 (0xffffffff|(((i64)0x7fffffff)<<32))
+# define SMALLEST_INT64 (((i64)-1) - LARGEST_INT64)
+
+#endif
+
+
+/*
+** Maximum number of prefix indexes on single FTS5 table. This must be
+** less than 32. If it is set to anything large than that, an #error
+** directive in fts5_index.c will cause the build to fail.
+*/
+#define FTS5_MAX_PREFIX_INDEXES 31
+
+#define FTS5_DEFAULT_NEARDIST 10
+#define FTS5_DEFAULT_RANK "bm25"
+
+/* Name of rank and rowid columns */
+#define FTS5_RANK_NAME "rank"
+#define FTS5_ROWID_NAME "rowid"
+
+#ifdef SQLITE_DEBUG
+# define FTS5_CORRUPT sqlite3Fts5Corrupt()
+static int sqlite3Fts5Corrupt(void);
+#else
+# define FTS5_CORRUPT SQLITE_CORRUPT_VTAB
+#endif
+
+/*
+** The assert_nc() macro is similar to the assert() macro, except that it
+** is used for assert() conditions that are true only if it can be
+** guranteed that the database is not corrupt.
+*/
+#ifdef SQLITE_DEBUG
+SQLITE_API extern int sqlite3_fts5_may_be_corrupt;
+# define assert_nc(x) assert(sqlite3_fts5_may_be_corrupt || (x))
+#else
+# define assert_nc(x) assert(x)
+#endif
+
+typedef struct Fts5Global Fts5Global;
+typedef struct Fts5Colset Fts5Colset;
+
+/* If a NEAR() clump or phrase may only match a specific set of columns,
+** then an object of the following type is used to record the set of columns.
+** Each entry in the aiCol[] array is a column that may be matched.
+**
+** This object is used by fts5_expr.c and fts5_index.c.
+*/
+struct Fts5Colset {
+ int nCol;
+ int aiCol[1];
+};
+
+
+
+/**************************************************************************
+** Interface to code in fts5_config.c. fts5_config.c contains contains code
+** to parse the arguments passed to the CREATE VIRTUAL TABLE statement.
+*/
+
+typedef struct Fts5Config Fts5Config;
+
+/*
+** An instance of the following structure encodes all information that can
+** be gleaned from the CREATE VIRTUAL TABLE statement.
+**
+** And all information loaded from the %_config table.
+**
+** nAutomerge:
+** The minimum number of segments that an auto-merge operation should
+** attempt to merge together. A value of 1 sets the object to use the
+** compile time default. Zero disables auto-merge altogether.
+**
+** zContent:
+**
+** zContentRowid:
+** The value of the content_rowid= option, if one was specified. Or
+** the string "rowid" otherwise. This text is not quoted - if it is
+** used as part of an SQL statement it needs to be quoted appropriately.
+**
+** zContentExprlist:
+**
+** pzErrmsg:
+** This exists in order to allow the fts5_index.c module to return a
+** decent error message if it encounters a file-format version it does
+** not understand.
+**
+** bColumnsize:
+** True if the %_docsize table is created.
+**
+** bPrefixIndex:
+** This is only used for debugging. If set to false, any prefix indexes
+** are ignored. This value is configured using:
+**
+** INSERT INTO tbl(tbl, rank) VALUES('prefix-index', $bPrefixIndex);
+**
+*/
+struct Fts5Config {
+ sqlite3 *db; /* Database handle */
+ char *zDb; /* Database holding FTS index (e.g. "main") */
+ char *zName; /* Name of FTS index */
+ int nCol; /* Number of columns */
+ char **azCol; /* Column names */
+ u8 *abUnindexed; /* True for unindexed columns */
+ int nPrefix; /* Number of prefix indexes */
+ int *aPrefix; /* Sizes in bytes of nPrefix prefix indexes */
+ int eContent; /* An FTS5_CONTENT value */
+ char *zContent; /* content table */
+ char *zContentRowid; /* "content_rowid=" option value */
+ int bColumnsize; /* "columnsize=" option value (dflt==1) */
+ char *zContentExprlist;
+ Fts5Tokenizer *pTok;
+ fts5_tokenizer *pTokApi;
+
+ /* Values loaded from the %_config table */
+ int iCookie; /* Incremented when %_config is modified */
+ int pgsz; /* Approximate page size used in %_data */
+ int nAutomerge; /* 'automerge' setting */
+ int nCrisisMerge; /* Maximum allowed segments per level */
+ int nHashSize; /* Bytes of memory for in-memory hash */
+ char *zRank; /* Name of rank function */
+ char *zRankArgs; /* Arguments to rank function */
+
+ /* If non-NULL, points to sqlite3_vtab.base.zErrmsg. Often NULL. */
+ char **pzErrmsg;
+
+#ifdef SQLITE_DEBUG
+ int bPrefixIndex; /* True to use prefix-indexes */
+#endif
+};
+
+/* Current expected value of %_config table 'version' field */
+#define FTS5_CURRENT_VERSION 4
+
+#define FTS5_CONTENT_NORMAL 0
+#define FTS5_CONTENT_NONE 1
+#define FTS5_CONTENT_EXTERNAL 2
+
+
+
+
+static int sqlite3Fts5ConfigParse(
+ Fts5Global*, sqlite3*, int, const char **, Fts5Config**, char**
+);
+static void sqlite3Fts5ConfigFree(Fts5Config*);
+
+static int sqlite3Fts5ConfigDeclareVtab(Fts5Config *pConfig);
+
+static int sqlite3Fts5Tokenize(
+ Fts5Config *pConfig, /* FTS5 Configuration object */
+ int flags, /* FTS5_TOKENIZE_* flags */
+ const char *pText, int nText, /* Text to tokenize */
+ void *pCtx, /* Context passed to xToken() */
+ int (*xToken)(void*, int, const char*, int, int, int) /* Callback */
+);
+
+static void sqlite3Fts5Dequote(char *z);
+
+/* Load the contents of the %_config table */
+static int sqlite3Fts5ConfigLoad(Fts5Config*, int);
+
+/* Set the value of a single config attribute */
+static int sqlite3Fts5ConfigSetValue(Fts5Config*, const char*, sqlite3_value*, int*);
+
+static int sqlite3Fts5ConfigParseRank(const char*, char**, char**);
+
+/*
+** End of interface to code in fts5_config.c.
+**************************************************************************/
+
+/**************************************************************************
+** Interface to code in fts5_buffer.c.
+*/
+
+/*
+** Buffer object for the incremental building of string data.
+*/
+typedef struct Fts5Buffer Fts5Buffer;
+struct Fts5Buffer {
+ u8 *p;
+ int n;
+ int nSpace;
+};
+
+static int sqlite3Fts5BufferSize(int*, Fts5Buffer*, int);
+static void sqlite3Fts5BufferAppendVarint(int*, Fts5Buffer*, i64);
+static void sqlite3Fts5BufferAppendBlob(int*, Fts5Buffer*, int, const u8*);
+static void sqlite3Fts5BufferAppendString(int *, Fts5Buffer*, const char*);
+static void sqlite3Fts5BufferFree(Fts5Buffer*);
+static void sqlite3Fts5BufferZero(Fts5Buffer*);
+static void sqlite3Fts5BufferSet(int*, Fts5Buffer*, int, const u8*);
+static void sqlite3Fts5BufferAppendPrintf(int *, Fts5Buffer*, char *zFmt, ...);
+
+static char *sqlite3Fts5Mprintf(int *pRc, const char *zFmt, ...);
+
+#define fts5BufferZero(x) sqlite3Fts5BufferZero(x)
+#define fts5BufferAppendVarint(a,b,c) sqlite3Fts5BufferAppendVarint(a,b,c)
+#define fts5BufferFree(a) sqlite3Fts5BufferFree(a)
+#define fts5BufferAppendBlob(a,b,c,d) sqlite3Fts5BufferAppendBlob(a,b,c,d)
+#define fts5BufferSet(a,b,c,d) sqlite3Fts5BufferSet(a,b,c,d)
+
+#define fts5BufferGrow(pRc,pBuf,nn) ( \
+ (pBuf)->n + (nn) <= (pBuf)->nSpace ? 0 : \
+ sqlite3Fts5BufferSize((pRc),(pBuf),(nn)+(pBuf)->n) \
+)
+
+/* Write and decode big-endian 32-bit integer values */
+static void sqlite3Fts5Put32(u8*, int);
+static int sqlite3Fts5Get32(const u8*);
+
+#define FTS5_POS2COLUMN(iPos) (int)(iPos >> 32)
+#define FTS5_POS2OFFSET(iPos) (int)(iPos & 0xFFFFFFFF)
+
+typedef struct Fts5PoslistReader Fts5PoslistReader;
+struct Fts5PoslistReader {
+ /* Variables used only by sqlite3Fts5PoslistIterXXX() functions. */
+ const u8 *a; /* Position list to iterate through */
+ int n; /* Size of buffer at a[] in bytes */
+ int i; /* Current offset in a[] */
+
+ u8 bFlag; /* For client use (any custom purpose) */
+
+ /* Output variables */
+ u8 bEof; /* Set to true at EOF */
+ i64 iPos; /* (iCol<<32) + iPos */
+};
+static int sqlite3Fts5PoslistReaderInit(
+ const u8 *a, int n, /* Poslist buffer to iterate through */
+ Fts5PoslistReader *pIter /* Iterator object to initialize */
+);
+static int sqlite3Fts5PoslistReaderNext(Fts5PoslistReader*);
+
+typedef struct Fts5PoslistWriter Fts5PoslistWriter;
+struct Fts5PoslistWriter {
+ i64 iPrev;
+};
+static int sqlite3Fts5PoslistWriterAppend(Fts5Buffer*, Fts5PoslistWriter*, i64);
+
+static int sqlite3Fts5PoslistNext64(
+ const u8 *a, int n, /* Buffer containing poslist */
+ int *pi, /* IN/OUT: Offset within a[] */
+ i64 *piOff /* IN/OUT: Current offset */
+);
+
+/* Malloc utility */
+static void *sqlite3Fts5MallocZero(int *pRc, int nByte);
+static char *sqlite3Fts5Strndup(int *pRc, const char *pIn, int nIn);
+
+/* Character set tests (like isspace(), isalpha() etc.) */
+static int sqlite3Fts5IsBareword(char t);
+
+/*
+** End of interface to code in fts5_buffer.c.
+**************************************************************************/
+
+/**************************************************************************
+** Interface to code in fts5_index.c. fts5_index.c contains contains code
+** to access the data stored in the %_data table.
+*/
+
+typedef struct Fts5Index Fts5Index;
+typedef struct Fts5IndexIter Fts5IndexIter;
+
+/*
+** Values used as part of the flags argument passed to IndexQuery().
+*/
+#define FTS5INDEX_QUERY_PREFIX 0x0001 /* Prefix query */
+#define FTS5INDEX_QUERY_DESC 0x0002 /* Docs in descending rowid order */
+#define FTS5INDEX_QUERY_TEST_NOIDX 0x0004 /* Do not use prefix index */
+#define FTS5INDEX_QUERY_SCAN 0x0008 /* Scan query (fts5vocab) */
+
+/*
+** Create/destroy an Fts5Index object.
+*/
+static int sqlite3Fts5IndexOpen(Fts5Config *pConfig, int bCreate, Fts5Index**, char**);
+static int sqlite3Fts5IndexClose(Fts5Index *p);
+
+/*
+** for(
+** sqlite3Fts5IndexQuery(p, "token", 5, 0, 0, &pIter);
+** 0==sqlite3Fts5IterEof(pIter);
+** sqlite3Fts5IterNext(pIter)
+** ){
+** i64 iRowid = sqlite3Fts5IterRowid(pIter);
+** }
+*/
+
+/*
+** Open a new iterator to iterate though all rowids that match the
+** specified token or token prefix.
+*/
+static int sqlite3Fts5IndexQuery(
+ Fts5Index *p, /* FTS index to query */
+ const char *pToken, int nToken, /* Token (or prefix) to query for */
+ int flags, /* Mask of FTS5INDEX_QUERY_X flags */
+ Fts5Colset *pColset, /* Match these columns only */
+ Fts5IndexIter **ppIter /* OUT: New iterator object */
+);
+
+/*
+** The various operations on open token or token prefix iterators opened
+** using sqlite3Fts5IndexQuery().
+*/
+static int sqlite3Fts5IterEof(Fts5IndexIter*);
+static int sqlite3Fts5IterNext(Fts5IndexIter*);
+static int sqlite3Fts5IterNextFrom(Fts5IndexIter*, i64 iMatch);
+static i64 sqlite3Fts5IterRowid(Fts5IndexIter*);
+static int sqlite3Fts5IterPoslist(Fts5IndexIter*,Fts5Colset*, const u8**, int*, i64*);
+static int sqlite3Fts5IterPoslistBuffer(Fts5IndexIter *pIter, Fts5Buffer *pBuf);
+
+/*
+** Close an iterator opened by sqlite3Fts5IndexQuery().
+*/
+static void sqlite3Fts5IterClose(Fts5IndexIter*);
+
+/*
+** This interface is used by the fts5vocab module.
+*/
+static const char *sqlite3Fts5IterTerm(Fts5IndexIter*, int*);
+static int sqlite3Fts5IterNextScan(Fts5IndexIter*);
+
+
+/*
+** Insert or remove data to or from the index. Each time a document is
+** added to or removed from the index, this function is called one or more
+** times.
+**
+** For an insert, it must be called once for each token in the new document.
+** If the operation is a delete, it must be called (at least) once for each
+** unique token in the document with an iCol value less than zero. The iPos
+** argument is ignored for a delete.
+*/
+static int sqlite3Fts5IndexWrite(
+ Fts5Index *p, /* Index to write to */
+ int iCol, /* Column token appears in (-ve -> delete) */
+ int iPos, /* Position of token within column */
+ const char *pToken, int nToken /* Token to add or remove to or from index */
+);
+
+/*
+** Indicate that subsequent calls to sqlite3Fts5IndexWrite() pertain to
+** document iDocid.
+*/
+static int sqlite3Fts5IndexBeginWrite(
+ Fts5Index *p, /* Index to write to */
+ int bDelete, /* True if current operation is a delete */
+ i64 iDocid /* Docid to add or remove data from */
+);
+
+/*
+** Flush any data stored in the in-memory hash tables to the database.
+** If the bCommit flag is true, also close any open blob handles.
+*/
+static int sqlite3Fts5IndexSync(Fts5Index *p, int bCommit);
+
+/*
+** Discard any data stored in the in-memory hash tables. Do not write it
+** to the database. Additionally, assume that the contents of the %_data
+** table may have changed on disk. So any in-memory caches of %_data
+** records must be invalidated.
+*/
+static int sqlite3Fts5IndexRollback(Fts5Index *p);
+
+/*
+** Get or set the "averages" values.
+*/
+static int sqlite3Fts5IndexGetAverages(Fts5Index *p, i64 *pnRow, i64 *anSize);
+static int sqlite3Fts5IndexSetAverages(Fts5Index *p, const u8*, int);
+
+/*
+** Functions called by the storage module as part of integrity-check.
+*/
+static u64 sqlite3Fts5IndexCksum(Fts5Config*,i64,int,int,const char*,int);
+static int sqlite3Fts5IndexIntegrityCheck(Fts5Index*, u64 cksum);
+
+/*
+** Called during virtual module initialization to register UDF
+** fts5_decode() with SQLite
+*/
+static int sqlite3Fts5IndexInit(sqlite3*);
+
+static int sqlite3Fts5IndexSetCookie(Fts5Index*, int);
+
+/*
+** Return the total number of entries read from the %_data table by
+** this connection since it was created.
+*/
+static int sqlite3Fts5IndexReads(Fts5Index *p);
+
+static int sqlite3Fts5IndexReinit(Fts5Index *p);
+static int sqlite3Fts5IndexOptimize(Fts5Index *p);
+static int sqlite3Fts5IndexMerge(Fts5Index *p, int nMerge);
+
+static int sqlite3Fts5IndexLoadConfig(Fts5Index *p);
+
+/*
+** End of interface to code in fts5_index.c.
+**************************************************************************/
+
+/**************************************************************************
+** Interface to code in fts5_varint.c.
+*/
+static int sqlite3Fts5GetVarint32(const unsigned char *p, u32 *v);
+static int sqlite3Fts5GetVarintLen(u32 iVal);
+static u8 sqlite3Fts5GetVarint(const unsigned char*, u64*);
+static int sqlite3Fts5PutVarint(unsigned char *p, u64 v);
+
+#define fts5GetVarint32(a,b) sqlite3Fts5GetVarint32(a,(u32*)&b)
+#define fts5GetVarint sqlite3Fts5GetVarint
+
+#define fts5FastGetVarint32(a, iOff, nVal) { \
+ nVal = (a)[iOff++]; \
+ if( nVal & 0x80 ){ \
+ iOff--; \
+ iOff += fts5GetVarint32(&(a)[iOff], nVal); \
+ } \
+}
+
+
+/*
+** End of interface to code in fts5_varint.c.
+**************************************************************************/
+
+
+/**************************************************************************
+** Interface to code in fts5.c.
+*/
+
+static int sqlite3Fts5GetTokenizer(
+ Fts5Global*,
+ const char **azArg,
+ int nArg,
+ Fts5Tokenizer**,
+ fts5_tokenizer**,
+ char **pzErr
+);
+
+static Fts5Index *sqlite3Fts5IndexFromCsrid(Fts5Global*, i64, Fts5Config **);
+
+/*
+** End of interface to code in fts5.c.
+**************************************************************************/
+
+/**************************************************************************
+** Interface to code in fts5_hash.c.
+*/
+typedef struct Fts5Hash Fts5Hash;
+
+/*
+** Create a hash table, free a hash table.
+*/
+static int sqlite3Fts5HashNew(Fts5Hash**, int *pnSize);
+static void sqlite3Fts5HashFree(Fts5Hash*);
+
+static int sqlite3Fts5HashWrite(
+ Fts5Hash*,
+ i64 iRowid, /* Rowid for this entry */
+ int iCol, /* Column token appears in (-ve -> delete) */
+ int iPos, /* Position of token within column */
+ char bByte,
+ const char *pToken, int nToken /* Token to add or remove to or from index */
+);
+
+/*
+** Empty (but do not delete) a hash table.
+*/
+static void sqlite3Fts5HashClear(Fts5Hash*);
+
+static int sqlite3Fts5HashQuery(
+ Fts5Hash*, /* Hash table to query */
+ const char *pTerm, int nTerm, /* Query term */
+ const u8 **ppDoclist, /* OUT: Pointer to doclist for pTerm */
+ int *pnDoclist /* OUT: Size of doclist in bytes */
+);
+
+static int sqlite3Fts5HashScanInit(
+ Fts5Hash*, /* Hash table to query */
+ const char *pTerm, int nTerm /* Query prefix */
+);
+static void sqlite3Fts5HashScanNext(Fts5Hash*);
+static int sqlite3Fts5HashScanEof(Fts5Hash*);
+static void sqlite3Fts5HashScanEntry(Fts5Hash *,
+ const char **pzTerm, /* OUT: term (nul-terminated) */
+ const u8 **ppDoclist, /* OUT: pointer to doclist */
+ int *pnDoclist /* OUT: size of doclist in bytes */
+);
+
+
+/*
+** End of interface to code in fts5_hash.c.
+**************************************************************************/
+
+/**************************************************************************
+** Interface to code in fts5_storage.c. fts5_storage.c contains contains
+** code to access the data stored in the %_content and %_docsize tables.
+*/
+
+#define FTS5_STMT_SCAN_ASC 0 /* SELECT rowid, * FROM ... ORDER BY 1 ASC */
+#define FTS5_STMT_SCAN_DESC 1 /* SELECT rowid, * FROM ... ORDER BY 1 DESC */
+#define FTS5_STMT_LOOKUP 2 /* SELECT rowid, * FROM ... WHERE rowid=? */
+
+typedef struct Fts5Storage Fts5Storage;
+
+static int sqlite3Fts5StorageOpen(Fts5Config*, Fts5Index*, int, Fts5Storage**, char**);
+static int sqlite3Fts5StorageClose(Fts5Storage *p);
+static int sqlite3Fts5StorageRename(Fts5Storage*, const char *zName);
+
+static int sqlite3Fts5DropAll(Fts5Config*);
+static int sqlite3Fts5CreateTable(Fts5Config*, const char*, const char*, int, char **);
+
+static int sqlite3Fts5StorageDelete(Fts5Storage *p, i64);
+static int sqlite3Fts5StorageContentInsert(Fts5Storage *p, sqlite3_value**, i64*);
+static int sqlite3Fts5StorageIndexInsert(Fts5Storage *p, sqlite3_value**, i64);
+
+static int sqlite3Fts5StorageIntegrity(Fts5Storage *p);
+
+static int sqlite3Fts5StorageStmt(Fts5Storage *p, int eStmt, sqlite3_stmt**, char**);
+static void sqlite3Fts5StorageStmtRelease(Fts5Storage *p, int eStmt, sqlite3_stmt*);
+
+static int sqlite3Fts5StorageDocsize(Fts5Storage *p, i64 iRowid, int *aCol);
+static int sqlite3Fts5StorageSize(Fts5Storage *p, int iCol, i64 *pnAvg);
+static int sqlite3Fts5StorageRowCount(Fts5Storage *p, i64 *pnRow);
+
+static int sqlite3Fts5StorageSync(Fts5Storage *p, int bCommit);
+static int sqlite3Fts5StorageRollback(Fts5Storage *p);
+
+static int sqlite3Fts5StorageConfigValue(
+ Fts5Storage *p, const char*, sqlite3_value*, int
+);
+
+static int sqlite3Fts5StorageSpecialDelete(Fts5Storage *p, i64 iDel, sqlite3_value**);
+
+static int sqlite3Fts5StorageDeleteAll(Fts5Storage *p);
+static int sqlite3Fts5StorageRebuild(Fts5Storage *p);
+static int sqlite3Fts5StorageOptimize(Fts5Storage *p);
+static int sqlite3Fts5StorageMerge(Fts5Storage *p, int nMerge);
+
+/*
+** End of interface to code in fts5_storage.c.
+**************************************************************************/
+
+
+/**************************************************************************
+** Interface to code in fts5_expr.c.
+*/
+typedef struct Fts5Expr Fts5Expr;
+typedef struct Fts5ExprNode Fts5ExprNode;
+typedef struct Fts5Parse Fts5Parse;
+typedef struct Fts5Token Fts5Token;
+typedef struct Fts5ExprPhrase Fts5ExprPhrase;
+typedef struct Fts5ExprNearset Fts5ExprNearset;
+
+struct Fts5Token {
+ const char *p; /* Token text (not NULL terminated) */
+ int n; /* Size of buffer p in bytes */
+};
+
+/* Parse a MATCH expression. */
+static int sqlite3Fts5ExprNew(
+ Fts5Config *pConfig,
+ const char *zExpr,
+ Fts5Expr **ppNew,
+ char **pzErr
+);
+
+/*
+** for(rc = sqlite3Fts5ExprFirst(pExpr, pIdx, bDesc);
+** rc==SQLITE_OK && 0==sqlite3Fts5ExprEof(pExpr);
+** rc = sqlite3Fts5ExprNext(pExpr)
+** ){
+** // The document with rowid iRowid matches the expression!
+** i64 iRowid = sqlite3Fts5ExprRowid(pExpr);
+** }
+*/
+static int sqlite3Fts5ExprFirst(Fts5Expr*, Fts5Index *pIdx, i64 iMin, int bDesc);
+static int sqlite3Fts5ExprNext(Fts5Expr*, i64 iMax);
+static int sqlite3Fts5ExprEof(Fts5Expr*);
+static i64 sqlite3Fts5ExprRowid(Fts5Expr*);
+
+static void sqlite3Fts5ExprFree(Fts5Expr*);
+
+/* Called during startup to register a UDF with SQLite */
+static int sqlite3Fts5ExprInit(Fts5Global*, sqlite3*);
+
+static int sqlite3Fts5ExprPhraseCount(Fts5Expr*);
+static int sqlite3Fts5ExprPhraseSize(Fts5Expr*, int iPhrase);
+static int sqlite3Fts5ExprPoslist(Fts5Expr*, int, const u8 **);
+
+static int sqlite3Fts5ExprClonePhrase(Fts5Config*, Fts5Expr*, int, Fts5Expr**);
+
+/*******************************************
+** The fts5_expr.c API above this point is used by the other hand-written
+** C code in this module. The interfaces below this point are called by
+** the parser code in fts5parse.y. */
+
+static void sqlite3Fts5ParseError(Fts5Parse *pParse, const char *zFmt, ...);
+
+static Fts5ExprNode *sqlite3Fts5ParseNode(
+ Fts5Parse *pParse,
+ int eType,
+ Fts5ExprNode *pLeft,
+ Fts5ExprNode *pRight,
+ Fts5ExprNearset *pNear
+);
+
+static Fts5ExprPhrase *sqlite3Fts5ParseTerm(
+ Fts5Parse *pParse,
+ Fts5ExprPhrase *pPhrase,
+ Fts5Token *pToken,
+ int bPrefix
+);
+
+static Fts5ExprNearset *sqlite3Fts5ParseNearset(
+ Fts5Parse*,
+ Fts5ExprNearset*,
+ Fts5ExprPhrase*
+);
+
+static Fts5Colset *sqlite3Fts5ParseColset(
+ Fts5Parse*,
+ Fts5Colset*,
+ Fts5Token *
+);
+
+static void sqlite3Fts5ParsePhraseFree(Fts5ExprPhrase*);
+static void sqlite3Fts5ParseNearsetFree(Fts5ExprNearset*);
+static void sqlite3Fts5ParseNodeFree(Fts5ExprNode*);
+
+static void sqlite3Fts5ParseSetDistance(Fts5Parse*, Fts5ExprNearset*, Fts5Token*);
+static void sqlite3Fts5ParseSetColset(Fts5Parse*, Fts5ExprNearset*, Fts5Colset*);
+static void sqlite3Fts5ParseFinished(Fts5Parse *pParse, Fts5ExprNode *p);
+static void sqlite3Fts5ParseNear(Fts5Parse *pParse, Fts5Token*);
+
+/*
+** End of interface to code in fts5_expr.c.
+**************************************************************************/
+
+
+
+/**************************************************************************
+** Interface to code in fts5_aux.c.
+*/
+
+static int sqlite3Fts5AuxInit(fts5_api*);
+/*
+** End of interface to code in fts5_aux.c.
+**************************************************************************/
+
+/**************************************************************************
+** Interface to code in fts5_tokenizer.c.
+*/
+
+static int sqlite3Fts5TokenizerInit(fts5_api*);
+/*
+** End of interface to code in fts5_tokenizer.c.
+**************************************************************************/
+
+/**************************************************************************
+** Interface to code in fts5_vocab.c.
+*/
+
+static int sqlite3Fts5VocabInit(Fts5Global*, sqlite3*);
+
+/*
+** End of interface to code in fts5_vocab.c.
+**************************************************************************/
+
+
+/**************************************************************************
+** Interface to automatically generated code in fts5_unicode2.c.
+*/
+static int sqlite3Fts5UnicodeIsalnum(int c);
+static int sqlite3Fts5UnicodeIsdiacritic(int c);
+static int sqlite3Fts5UnicodeFold(int c, int bRemoveDiacritic);
+/*
+** End of interface to code in fts5_unicode2.c.
+**************************************************************************/
+
+#endif
+
+#define FTS5_OR 1
+#define FTS5_AND 2
+#define FTS5_NOT 3
+#define FTS5_TERM 4
+#define FTS5_COLON 5
+#define FTS5_LP 6
+#define FTS5_RP 7
+#define FTS5_LCP 8
+#define FTS5_RCP 9
+#define FTS5_STRING 10
+#define FTS5_COMMA 11
+#define FTS5_PLUS 12
+#define FTS5_STAR 13
+
+/*
+** 2000-05-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.
+**
+*************************************************************************
+** Driver template for the LEMON parser generator.
+**
+** The "lemon" program processes an LALR(1) input grammar file, then uses
+** this template to construct a parser. The "lemon" program inserts text
+** at each "%%" line. Also, any "P-a-r-s-e" identifer prefix (without the
+** interstitial "-" characters) contained in this template is changed into
+** the value of the %name directive from the grammar. Otherwise, the content
+** of this template is copied straight through into the generate parser
+** source file.
+**
+** The following is the concatenation of all %include directives from the
+** input grammar file:
+*/
+/* #include <stdio.h> */
+/************ Begin %include sections from the grammar ************************/
+
+/* #include "fts5Int.h" */
+/* #include "fts5parse.h" */
+
+/*
+** Disable all error recovery processing in the parser push-down
+** automaton.
+*/
+#define fts5YYNOERRORRECOVERY 1
+
+/*
+** Make fts5yytestcase() the same as testcase()
+*/
+#define fts5yytestcase(X) testcase(X)
+
+/*
+** Indicate that sqlite3ParserFree() will never be called with a null
+** pointer.
+*/
+#define fts5YYPARSEFREENOTNULL 1
+
+/*
+** Alternative datatype for the argument to the malloc() routine passed
+** into sqlite3ParserAlloc(). The default is size_t.
+*/
+#define fts5YYMALLOCARGTYPE u64
+
+/**************** End of %include directives **********************************/
+/* These constants specify the various numeric values for terminal symbols
+** in a format understandable to "makeheaders". This section is blank unless
+** "lemon" is run with the "-m" command-line option.
+***************** Begin makeheaders token definitions *************************/
+/**************** End makeheaders token definitions ***************************/
+
+/* The next sections is a series of control #defines.
+** various aspects of the generated parser.
+** fts5YYCODETYPE is the data type used to store the integer codes
+** that represent terminal and non-terminal symbols.
+** "unsigned char" is used if there are fewer than
+** 256 symbols. Larger types otherwise.
+** fts5YYNOCODE is a number of type fts5YYCODETYPE that is not used for
+** any terminal or nonterminal symbol.
+** fts5YYFALLBACK If defined, this indicates that one or more tokens
+** (also known as: "terminal symbols") have fall-back
+** values which should be used if the original symbol
+** would not parse. This permits keywords to sometimes
+** be used as identifiers, for example.
+** fts5YYACTIONTYPE is the data type used for "action codes" - numbers
+** that indicate what to do in response to the next
+** token.
+** sqlite3Fts5ParserFTS5TOKENTYPE is the data type used for minor type for terminal
+** symbols. Background: A "minor type" is a semantic
+** value associated with a terminal or non-terminal
+** symbols. For example, for an "ID" terminal symbol,
+** the minor type might be the name of the identifier.
+** Each non-terminal can have a different minor type.
+** Terminal symbols all have the same minor type, though.
+** This macros defines the minor type for terminal
+** symbols.
+** fts5YYMINORTYPE is the data type used for all minor types.
+** This is typically a union of many types, one of
+** which is sqlite3Fts5ParserFTS5TOKENTYPE. The entry in the union
+** for terminal symbols is called "fts5yy0".
+** fts5YYSTACKDEPTH is the maximum depth of the parser's stack. If
+** zero the stack is dynamically sized using realloc()
+** sqlite3Fts5ParserARG_SDECL A static variable declaration for the %extra_argument
+** sqlite3Fts5ParserARG_PDECL A parameter declaration for the %extra_argument
+** sqlite3Fts5ParserARG_STORE Code to store %extra_argument into fts5yypParser
+** sqlite3Fts5ParserARG_FETCH Code to extract %extra_argument from fts5yypParser
+** fts5YYERRORSYMBOL is the code number of the error symbol. If not
+** defined, then do no error processing.
+** fts5YYNSTATE the combined number of states.
+** fts5YYNRULE the number of rules in the grammar
+** fts5YY_MAX_SHIFT Maximum value for shift actions
+** fts5YY_MIN_SHIFTREDUCE Minimum value for shift-reduce actions
+** fts5YY_MAX_SHIFTREDUCE Maximum value for shift-reduce actions
+** fts5YY_MIN_REDUCE Maximum value for reduce actions
+** fts5YY_ERROR_ACTION The fts5yy_action[] code for syntax error
+** fts5YY_ACCEPT_ACTION The fts5yy_action[] code for accept
+** fts5YY_NO_ACTION The fts5yy_action[] code for no-op
+*/
+#ifndef INTERFACE
+# define INTERFACE 1
+#endif
+/************* Begin control #defines *****************************************/
+#define fts5YYCODETYPE unsigned char
+#define fts5YYNOCODE 27
+#define fts5YYACTIONTYPE unsigned char
+#define sqlite3Fts5ParserFTS5TOKENTYPE Fts5Token
+typedef union {
+ int fts5yyinit;
+ sqlite3Fts5ParserFTS5TOKENTYPE fts5yy0;
+ Fts5Colset* fts5yy3;
+ Fts5ExprPhrase* fts5yy11;
+ Fts5ExprNode* fts5yy18;
+ int fts5yy20;
+ Fts5ExprNearset* fts5yy26;
+} fts5YYMINORTYPE;
+#ifndef fts5YYSTACKDEPTH
+#define fts5YYSTACKDEPTH 100
+#endif
+#define sqlite3Fts5ParserARG_SDECL Fts5Parse *pParse;
+#define sqlite3Fts5ParserARG_PDECL ,Fts5Parse *pParse
+#define sqlite3Fts5ParserARG_FETCH Fts5Parse *pParse = fts5yypParser->pParse
+#define sqlite3Fts5ParserARG_STORE fts5yypParser->pParse = pParse
+#define fts5YYNSTATE 26
+#define fts5YYNRULE 24
+#define fts5YY_MAX_SHIFT 25
+#define fts5YY_MIN_SHIFTREDUCE 40
+#define fts5YY_MAX_SHIFTREDUCE 63
+#define fts5YY_MIN_REDUCE 64
+#define fts5YY_MAX_REDUCE 87
+#define fts5YY_ERROR_ACTION 88
+#define fts5YY_ACCEPT_ACTION 89
+#define fts5YY_NO_ACTION 90
+/************* End control #defines *******************************************/
+
+/* The fts5yyzerominor constant is used to initialize instances of
+** fts5YYMINORTYPE objects to zero. */
+static const fts5YYMINORTYPE fts5yyzerominor = { 0 };
+
+/* Define the fts5yytestcase() macro to be a no-op if is not already defined
+** otherwise.
+**
+** Applications can choose to define fts5yytestcase() in the %include section
+** to a macro that can assist in verifying code coverage. For production
+** code the fts5yytestcase() macro should be turned off. But it is useful
+** for testing.
+*/
+#ifndef fts5yytestcase
+# define fts5yytestcase(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 <= fts5YY_MAX_SHIFT Shift N. That is, push the lookahead
+** token onto the stack and goto state N.
+**
+** N between fts5YY_MIN_SHIFTREDUCE Shift to an arbitrary state then
+** and fts5YY_MAX_SHIFTREDUCE reduce by rule N-fts5YY_MIN_SHIFTREDUCE.
+**
+** N between fts5YY_MIN_REDUCE Reduce by rule N-fts5YY_MIN_REDUCE
+** and fts5YY_MAX_REDUCE
+
+** N == fts5YY_ERROR_ACTION A syntax error has occurred.
+**
+** N == fts5YY_ACCEPT_ACTION The parser accepts its input.
+**
+** N == fts5YY_NO_ACTION No such action. Denotes unused
+** slots in the fts5yy_action[] table.
+**
+** The action table is constructed as a single large table named fts5yy_action[].
+** Given state S and lookahead X, the action is computed as
+**
+** fts5yy_action[ fts5yy_shift_ofst[S] + X ]
+**
+** If the index value fts5yy_shift_ofst[S]+X is out of range or if the value
+** fts5yy_lookahead[fts5yy_shift_ofst[S]+X] is not equal to X or if fts5yy_shift_ofst[S]
+** is equal to fts5YY_SHIFT_USE_DFLT, it means that the action is not in the table
+** and that fts5yy_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 fts5yy_reduce_ofst[] array is used in place of
+** the fts5yy_shift_ofst[] array and fts5YY_REDUCE_USE_DFLT is used in place of
+** fts5YY_SHIFT_USE_DFLT.
+**
+** The following are the tables generated in this section:
+**
+** fts5yy_action[] A single table containing all actions.
+** fts5yy_lookahead[] A table containing the lookahead for each entry in
+** fts5yy_action. Used to detect hash collisions.
+** fts5yy_shift_ofst[] For each state, the offset into fts5yy_action for
+** shifting terminals.
+** fts5yy_reduce_ofst[] For each state, the offset into fts5yy_action for
+** shifting non-terminals after a reduce.
+** fts5yy_default[] Default action for each state.
+**
+*********** Begin parsing tables **********************************************/
+#define fts5YY_ACTTAB_COUNT (78)
+static const fts5YYACTIONTYPE fts5yy_action[] = {
+ /* 0 */ 89, 15, 46, 5, 48, 24, 12, 19, 23, 14,
+ /* 10 */ 46, 5, 48, 24, 20, 21, 23, 43, 46, 5,
+ /* 20 */ 48, 24, 6, 18, 23, 17, 46, 5, 48, 24,
+ /* 30 */ 75, 7, 23, 25, 46, 5, 48, 24, 62, 47,
+ /* 40 */ 23, 48, 24, 7, 11, 23, 9, 3, 4, 2,
+ /* 50 */ 62, 50, 52, 44, 64, 3, 4, 2, 49, 4,
+ /* 60 */ 2, 1, 23, 11, 16, 9, 12, 2, 10, 61,
+ /* 70 */ 53, 59, 62, 60, 22, 13, 55, 8,
+};
+static const fts5YYCODETYPE fts5yy_lookahead[] = {
+ /* 0 */ 15, 16, 17, 18, 19, 20, 10, 11, 23, 16,
+ /* 10 */ 17, 18, 19, 20, 23, 24, 23, 16, 17, 18,
+ /* 20 */ 19, 20, 22, 23, 23, 16, 17, 18, 19, 20,
+ /* 30 */ 5, 6, 23, 16, 17, 18, 19, 20, 13, 17,
+ /* 40 */ 23, 19, 20, 6, 8, 23, 10, 1, 2, 3,
+ /* 50 */ 13, 9, 10, 7, 0, 1, 2, 3, 19, 2,
+ /* 60 */ 3, 6, 23, 8, 21, 10, 10, 3, 10, 25,
+ /* 70 */ 10, 10, 13, 25, 12, 10, 7, 5,
+};
+#define fts5YY_SHIFT_USE_DFLT (-5)
+#define fts5YY_SHIFT_COUNT (25)
+#define fts5YY_SHIFT_MIN (-4)
+#define fts5YY_SHIFT_MAX (72)
+static const signed char fts5yy_shift_ofst[] = {
+ /* 0 */ 55, 55, 55, 55, 55, 36, -4, 56, 58, 25,
+ /* 10 */ 37, 60, 59, 59, 46, 54, 42, 57, 62, 61,
+ /* 20 */ 62, 69, 65, 62, 72, 64,
+};
+#define fts5YY_REDUCE_USE_DFLT (-16)
+#define fts5YY_REDUCE_COUNT (13)
+#define fts5YY_REDUCE_MIN (-15)
+#define fts5YY_REDUCE_MAX (48)
+static const signed char fts5yy_reduce_ofst[] = {
+ /* 0 */ -15, -7, 1, 9, 17, 22, -9, 0, 39, 44,
+ /* 10 */ 44, 43, 44, 48,
+};
+static const fts5YYACTIONTYPE fts5yy_default[] = {
+ /* 0 */ 88, 88, 88, 88, 88, 69, 82, 88, 88, 87,
+ /* 10 */ 87, 88, 87, 87, 88, 88, 88, 66, 80, 88,
+ /* 20 */ 81, 88, 88, 78, 88, 65,
+};
+/********** End of lemon-generated parsing tables *****************************/
+
+/* The next table maps tokens (terminal symbols) 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.
+**
+** This feature can be used, for example, to cause some keywords in a language
+** to revert to identifiers if they keyword does not apply in the context where
+** it appears.
+*/
+#ifdef fts5YYFALLBACK
+static const fts5YYCODETYPE fts5yyFallback[] = {
+};
+#endif /* fts5YYFALLBACK */
+
+/* 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.
+**
+** After the "shift" half of a SHIFTREDUCE action, the stateno field
+** actually contains the reduce action for the second half of the
+** SHIFTREDUCE.
+*/
+struct fts5yyStackEntry {
+ fts5YYACTIONTYPE stateno; /* The state-number, or reduce action in SHIFTREDUCE */
+ fts5YYCODETYPE major; /* The major token value. This is the code
+ ** number for the token at this stack level */
+ fts5YYMINORTYPE minor; /* The user-supplied minor token value. This
+ ** is the value of the token */
+};
+typedef struct fts5yyStackEntry fts5yyStackEntry;
+
+/* The state of the parser is completely contained in an instance of
+** the following structure */
+struct fts5yyParser {
+ int fts5yyidx; /* Index of top element in stack */
+#ifdef fts5YYTRACKMAXSTACKDEPTH
+ int fts5yyidxMax; /* Maximum value of fts5yyidx */
+#endif
+ int fts5yyerrcnt; /* Shifts left before out of the error */
+ sqlite3Fts5ParserARG_SDECL /* A place to hold %extra_argument */
+#if fts5YYSTACKDEPTH<=0
+ int fts5yystksz; /* Current side of the stack */
+ fts5yyStackEntry *fts5yystack; /* The parser's stack */
+#else
+ fts5yyStackEntry fts5yystack[fts5YYSTACKDEPTH]; /* The parser's stack */
+#endif
+};
+typedef struct fts5yyParser fts5yyParser;
+
+#ifndef NDEBUG
+/* #include <stdio.h> */
+static FILE *fts5yyTraceFILE = 0;
+static char *fts5yyTracePrompt = 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.
+*/
+static void sqlite3Fts5ParserTrace(FILE *TraceFILE, char *zTracePrompt){
+ fts5yyTraceFILE = TraceFILE;
+ fts5yyTracePrompt = zTracePrompt;
+ if( fts5yyTraceFILE==0 ) fts5yyTracePrompt = 0;
+ else if( fts5yyTracePrompt==0 ) fts5yyTraceFILE = 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 fts5yyTokenName[] = {
+ "$", "OR", "AND", "NOT",
+ "TERM", "COLON", "LP", "RP",
+ "LCP", "RCP", "STRING", "COMMA",
+ "PLUS", "STAR", "error", "input",
+ "expr", "cnearset", "exprlist", "nearset",
+ "colset", "colsetlist", "nearphrases", "phrase",
+ "neardist_opt", "star_opt",
+};
+#endif /* NDEBUG */
+
+#ifndef NDEBUG
+/* For tracing reduce actions, the names of all rules are required.
+*/
+static const char *const fts5yyRuleName[] = {
+ /* 0 */ "input ::= expr",
+ /* 1 */ "expr ::= expr AND expr",
+ /* 2 */ "expr ::= expr OR expr",
+ /* 3 */ "expr ::= expr NOT expr",
+ /* 4 */ "expr ::= LP expr RP",
+ /* 5 */ "expr ::= exprlist",
+ /* 6 */ "exprlist ::= cnearset",
+ /* 7 */ "exprlist ::= exprlist cnearset",
+ /* 8 */ "cnearset ::= nearset",
+ /* 9 */ "cnearset ::= colset COLON nearset",
+ /* 10 */ "colset ::= LCP colsetlist RCP",
+ /* 11 */ "colset ::= STRING",
+ /* 12 */ "colsetlist ::= colsetlist STRING",
+ /* 13 */ "colsetlist ::= STRING",
+ /* 14 */ "nearset ::= phrase",
+ /* 15 */ "nearset ::= STRING LP nearphrases neardist_opt RP",
+ /* 16 */ "nearphrases ::= phrase",
+ /* 17 */ "nearphrases ::= nearphrases phrase",
+ /* 18 */ "neardist_opt ::=",
+ /* 19 */ "neardist_opt ::= COMMA STRING",
+ /* 20 */ "phrase ::= phrase PLUS STRING star_opt",
+ /* 21 */ "phrase ::= STRING star_opt",
+ /* 22 */ "star_opt ::= STAR",
+ /* 23 */ "star_opt ::=",
+};
+#endif /* NDEBUG */
+
+
+#if fts5YYSTACKDEPTH<=0
+/*
+** Try to increase the size of the parser stack.
+*/
+static void fts5yyGrowStack(fts5yyParser *p){
+ int newSize;
+ fts5yyStackEntry *pNew;
+
+ newSize = p->fts5yystksz*2 + 100;
+ pNew = realloc(p->fts5yystack, newSize*sizeof(pNew[0]));
+ if( pNew ){
+ p->fts5yystack = pNew;
+ p->fts5yystksz = newSize;
+#ifndef NDEBUG
+ if( fts5yyTraceFILE ){
+ fprintf(fts5yyTraceFILE,"%sStack grows to %d entries!\n",
+ fts5yyTracePrompt, p->fts5yystksz);
+ }
+#endif
+ }
+}
+#endif
+
+/* Datatype of the argument to the memory allocated passed as the
+** second argument to sqlite3Fts5ParserAlloc() below. This can be changed by
+** putting an appropriate #define in the %include section of the input
+** grammar.
+*/
+#ifndef fts5YYMALLOCARGTYPE
+# define fts5YYMALLOCARGTYPE size_t
+#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 sqlite3Fts5Parser and sqlite3Fts5ParserFree.
+*/
+static void *sqlite3Fts5ParserAlloc(void *(*mallocProc)(fts5YYMALLOCARGTYPE)){
+ fts5yyParser *pParser;
+ pParser = (fts5yyParser*)(*mallocProc)( (fts5YYMALLOCARGTYPE)sizeof(fts5yyParser) );
+ if( pParser ){
+ pParser->fts5yyidx = -1;
+#ifdef fts5YYTRACKMAXSTACKDEPTH
+ pParser->fts5yyidxMax = 0;
+#endif
+#if fts5YYSTACKDEPTH<=0
+ pParser->fts5yystack = NULL;
+ pParser->fts5yystksz = 0;
+ fts5yyGrowStack(pParser);
+#endif
+ }
+ return pParser;
+}
+
+/* The following function deletes the "minor type" or semantic value
+** associated with a symbol. The symbol can be either a terminal
+** or nonterminal. "fts5yymajor" is the symbol code, and "fts5yypminor" is
+** a pointer to the value to be deleted. The code used to do the
+** deletions is derived from the %destructor and/or %token_destructor
+** directives of the input grammar.
+*/
+static void fts5yy_destructor(
+ fts5yyParser *fts5yypParser, /* The parser */
+ fts5YYCODETYPE fts5yymajor, /* Type code for object to destroy */
+ fts5YYMINORTYPE *fts5yypminor /* The object to be destroyed */
+){
+ sqlite3Fts5ParserARG_FETCH;
+ switch( fts5yymajor ){
+ /* 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.
+ */
+/********* Begin destructor definitions ***************************************/
+ case 15: /* input */
+{
+ (void)pParse;
+}
+ break;
+ case 16: /* expr */
+ case 17: /* cnearset */
+ case 18: /* exprlist */
+{
+ sqlite3Fts5ParseNodeFree((fts5yypminor->fts5yy18));
+}
+ break;
+ case 19: /* nearset */
+ case 22: /* nearphrases */
+{
+ sqlite3Fts5ParseNearsetFree((fts5yypminor->fts5yy26));
+}
+ break;
+ case 20: /* colset */
+ case 21: /* colsetlist */
+{
+ sqlite3_free((fts5yypminor->fts5yy3));
+}
+ break;
+ case 23: /* phrase */
+{
+ sqlite3Fts5ParsePhraseFree((fts5yypminor->fts5yy11));
+}
+ break;
+/********* End destructor definitions *****************************************/
+ 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.
+*/
+static void fts5yy_pop_parser_stack(fts5yyParser *pParser){
+ fts5yyStackEntry *fts5yytos;
+ assert( pParser->fts5yyidx>=0 );
+ fts5yytos = &pParser->fts5yystack[pParser->fts5yyidx--];
+#ifndef NDEBUG
+ if( fts5yyTraceFILE ){
+ fprintf(fts5yyTraceFILE,"%sPopping %s\n",
+ fts5yyTracePrompt,
+ fts5yyTokenName[fts5yytos->major]);
+ }
+#endif
+ fts5yy_destructor(pParser, fts5yytos->major, &fts5yytos->minor);
+}
+
+/*
+** Deallocate and destroy a parser. Destructors are called for
+** all stack elements before shutting the parser down.
+**
+** If the fts5YYPARSEFREENEVERNULL macro exists (for example because it
+** is defined in a %include section of the input grammar) then it is
+** assumed that the input pointer is never NULL.
+*/
+static void sqlite3Fts5ParserFree(
+ void *p, /* The parser to be deleted */
+ void (*freeProc)(void*) /* Function used to reclaim memory */
+){
+ fts5yyParser *pParser = (fts5yyParser*)p;
+#ifndef fts5YYPARSEFREENEVERNULL
+ if( pParser==0 ) return;
+#endif
+ while( pParser->fts5yyidx>=0 ) fts5yy_pop_parser_stack(pParser);
+#if fts5YYSTACKDEPTH<=0
+ free(pParser->fts5yystack);
+#endif
+ (*freeProc)((void*)pParser);
+}
+
+/*
+** Return the peak depth of the stack for a parser.
+*/
+#ifdef fts5YYTRACKMAXSTACKDEPTH
+static int sqlite3Fts5ParserStackPeak(void *p){
+ fts5yyParser *pParser = (fts5yyParser*)p;
+ return pParser->fts5yyidxMax;
+}
+#endif
+
+/*
+** Find the appropriate action for a parser given the terminal
+** look-ahead token iLookAhead.
+*/
+static int fts5yy_find_shift_action(
+ fts5yyParser *pParser, /* The parser */
+ fts5YYCODETYPE iLookAhead /* The look-ahead token */
+){
+ int i;
+ int stateno = pParser->fts5yystack[pParser->fts5yyidx].stateno;
+
+ if( stateno>=fts5YY_MIN_REDUCE ) return stateno;
+ assert( stateno <= fts5YY_SHIFT_COUNT );
+ do{
+ i = fts5yy_shift_ofst[stateno];
+ if( i==fts5YY_SHIFT_USE_DFLT ) return fts5yy_default[stateno];
+ assert( iLookAhead!=fts5YYNOCODE );
+ i += iLookAhead;
+ if( i<0 || i>=fts5YY_ACTTAB_COUNT || fts5yy_lookahead[i]!=iLookAhead ){
+ if( iLookAhead>0 ){
+#ifdef fts5YYFALLBACK
+ fts5YYCODETYPE iFallback; /* Fallback token */
+ if( iLookAhead<sizeof(fts5yyFallback)/sizeof(fts5yyFallback[0])
+ && (iFallback = fts5yyFallback[iLookAhead])!=0 ){
+#ifndef NDEBUG
+ if( fts5yyTraceFILE ){
+ fprintf(fts5yyTraceFILE, "%sFALLBACK %s => %s\n",
+ fts5yyTracePrompt, fts5yyTokenName[iLookAhead], fts5yyTokenName[iFallback]);
+ }
+#endif
+ assert( fts5yyFallback[iFallback]==0 ); /* Fallback loop must terminate */
+ iLookAhead = iFallback;
+ continue;
+ }
+#endif
+#ifdef fts5YYWILDCARD
+ {
+ int j = i - iLookAhead + fts5YYWILDCARD;
+ if(
+#if fts5YY_SHIFT_MIN+fts5YYWILDCARD<0
+ j>=0 &&
+#endif
+#if fts5YY_SHIFT_MAX+fts5YYWILDCARD>=fts5YY_ACTTAB_COUNT
+ j<fts5YY_ACTTAB_COUNT &&
+#endif
+ fts5yy_lookahead[j]==fts5YYWILDCARD
+ ){
+#ifndef NDEBUG
+ if( fts5yyTraceFILE ){
+ fprintf(fts5yyTraceFILE, "%sWILDCARD %s => %s\n",
+ fts5yyTracePrompt, fts5yyTokenName[iLookAhead],
+ fts5yyTokenName[fts5YYWILDCARD]);
+ }
+#endif /* NDEBUG */
+ return fts5yy_action[j];
+ }
+ }
+#endif /* fts5YYWILDCARD */
+ }
+ return fts5yy_default[stateno];
+ }else{
+ return fts5yy_action[i];
+ }
+ }while(1);
+}
+
+/*
+** Find the appropriate action for a parser given the non-terminal
+** look-ahead token iLookAhead.
+*/
+static int fts5yy_find_reduce_action(
+ int stateno, /* Current state number */
+ fts5YYCODETYPE iLookAhead /* The look-ahead token */
+){
+ int i;
+#ifdef fts5YYERRORSYMBOL
+ if( stateno>fts5YY_REDUCE_COUNT ){
+ return fts5yy_default[stateno];
+ }
+#else
+ assert( stateno<=fts5YY_REDUCE_COUNT );
+#endif
+ i = fts5yy_reduce_ofst[stateno];
+ assert( i!=fts5YY_REDUCE_USE_DFLT );
+ assert( iLookAhead!=fts5YYNOCODE );
+ i += iLookAhead;
+#ifdef fts5YYERRORSYMBOL
+ if( i<0 || i>=fts5YY_ACTTAB_COUNT || fts5yy_lookahead[i]!=iLookAhead ){
+ return fts5yy_default[stateno];
+ }
+#else
+ assert( i>=0 && i<fts5YY_ACTTAB_COUNT );
+ assert( fts5yy_lookahead[i]==iLookAhead );
+#endif
+ return fts5yy_action[i];
+}
+
+/*
+** The following routine is called if the stack overflows.
+*/
+static void fts5yyStackOverflow(fts5yyParser *fts5yypParser, fts5YYMINORTYPE *fts5yypMinor){
+ sqlite3Fts5ParserARG_FETCH;
+ fts5yypParser->fts5yyidx--;
+#ifndef NDEBUG
+ if( fts5yyTraceFILE ){
+ fprintf(fts5yyTraceFILE,"%sStack Overflow!\n",fts5yyTracePrompt);
+ }
+#endif
+ while( fts5yypParser->fts5yyidx>=0 ) fts5yy_pop_parser_stack(fts5yypParser);
+ /* Here code is inserted which will execute if the parser
+ ** stack every overflows */
+/******** Begin %stack_overflow code ******************************************/
+
+ assert( 0 );
+/******** End %stack_overflow code ********************************************/
+ sqlite3Fts5ParserARG_STORE; /* Suppress warning about unused %extra_argument var */
+}
+
+/*
+** Print tracing information for a SHIFT action
+*/
+#ifndef NDEBUG
+static void fts5yyTraceShift(fts5yyParser *fts5yypParser, int fts5yyNewState){
+ if( fts5yyTraceFILE ){
+ if( fts5yyNewState<fts5YYNSTATE ){
+ fprintf(fts5yyTraceFILE,"%sShift '%s', go to state %d\n",
+ fts5yyTracePrompt,fts5yyTokenName[fts5yypParser->fts5yystack[fts5yypParser->fts5yyidx].major],
+ fts5yyNewState);
+ }else{
+ fprintf(fts5yyTraceFILE,"%sShift '%s'\n",
+ fts5yyTracePrompt,fts5yyTokenName[fts5yypParser->fts5yystack[fts5yypParser->fts5yyidx].major]);
+ }
+ }
+}
+#else
+# define fts5yyTraceShift(X,Y)
+#endif
+
+/*
+** Perform a shift action.
+*/
+static void fts5yy_shift(
+ fts5yyParser *fts5yypParser, /* The parser to be shifted */
+ int fts5yyNewState, /* The new state to shift in */
+ int fts5yyMajor, /* The major token to shift in */
+ fts5YYMINORTYPE *fts5yypMinor /* Pointer to the minor token to shift in */
+){
+ fts5yyStackEntry *fts5yytos;
+ fts5yypParser->fts5yyidx++;
+#ifdef fts5YYTRACKMAXSTACKDEPTH
+ if( fts5yypParser->fts5yyidx>fts5yypParser->fts5yyidxMax ){
+ fts5yypParser->fts5yyidxMax = fts5yypParser->fts5yyidx;
+ }
+#endif
+#if fts5YYSTACKDEPTH>0
+ if( fts5yypParser->fts5yyidx>=fts5YYSTACKDEPTH ){
+ fts5yyStackOverflow(fts5yypParser, fts5yypMinor);
+ return;
+ }
+#else
+ if( fts5yypParser->fts5yyidx>=fts5yypParser->fts5yystksz ){
+ fts5yyGrowStack(fts5yypParser);
+ if( fts5yypParser->fts5yyidx>=fts5yypParser->fts5yystksz ){
+ fts5yyStackOverflow(fts5yypParser, fts5yypMinor);
+ return;
+ }
+ }
+#endif
+ fts5yytos = &fts5yypParser->fts5yystack[fts5yypParser->fts5yyidx];
+ fts5yytos->stateno = (fts5YYACTIONTYPE)fts5yyNewState;
+ fts5yytos->major = (fts5YYCODETYPE)fts5yyMajor;
+ fts5yytos->minor = *fts5yypMinor;
+ fts5yyTraceShift(fts5yypParser, fts5yyNewState);
+}
+
+/* The following table contains information about every rule that
+** is used during the reduce.
+*/
+static const struct {
+ fts5YYCODETYPE lhs; /* Symbol on the left-hand side of the rule */
+ unsigned char nrhs; /* Number of right-hand side symbols in the rule */
+} fts5yyRuleInfo[] = {
+ { 15, 1 },
+ { 16, 3 },
+ { 16, 3 },
+ { 16, 3 },
+ { 16, 3 },
+ { 16, 1 },
+ { 18, 1 },
+ { 18, 2 },
+ { 17, 1 },
+ { 17, 3 },
+ { 20, 3 },
+ { 20, 1 },
+ { 21, 2 },
+ { 21, 1 },
+ { 19, 1 },
+ { 19, 5 },
+ { 22, 1 },
+ { 22, 2 },
+ { 24, 0 },
+ { 24, 2 },
+ { 23, 4 },
+ { 23, 2 },
+ { 25, 1 },
+ { 25, 0 },
+};
+
+static void fts5yy_accept(fts5yyParser*); /* Forward Declaration */
+
+/*
+** Perform a reduce action and the shift that must immediately
+** follow the reduce.
+*/
+static void fts5yy_reduce(
+ fts5yyParser *fts5yypParser, /* The parser */
+ int fts5yyruleno /* Number of the rule by which to reduce */
+){
+ int fts5yygoto; /* The next state */
+ int fts5yyact; /* The next action */
+ fts5YYMINORTYPE fts5yygotominor; /* The LHS of the rule reduced */
+ fts5yyStackEntry *fts5yymsp; /* The top of the parser's stack */
+ int fts5yysize; /* Amount to pop the stack */
+ sqlite3Fts5ParserARG_FETCH;
+ fts5yymsp = &fts5yypParser->fts5yystack[fts5yypParser->fts5yyidx];
+#ifndef NDEBUG
+ if( fts5yyTraceFILE && fts5yyruleno>=0
+ && fts5yyruleno<(int)(sizeof(fts5yyRuleName)/sizeof(fts5yyRuleName[0])) ){
+ fts5yysize = fts5yyRuleInfo[fts5yyruleno].nrhs;
+ fprintf(fts5yyTraceFILE, "%sReduce [%s], go to state %d.\n", fts5yyTracePrompt,
+ fts5yyRuleName[fts5yyruleno], fts5yymsp[-fts5yysize].stateno);
+ }
+#endif /* NDEBUG */
+ fts5yygotominor = fts5yyzerominor;
+
+ switch( fts5yyruleno ){
+ /* Beginning here are the reduction cases. A typical example
+ ** follows:
+ ** case 0:
+ ** #line <lineno> <grammarfile>
+ ** { ... } // User supplied code
+ ** #line <lineno> <thisfile>
+ ** break;
+ */
+/********** Begin reduce actions **********************************************/
+ case 0: /* input ::= expr */
+{ sqlite3Fts5ParseFinished(pParse, fts5yymsp[0].minor.fts5yy18); }
+ break;
+ case 1: /* expr ::= expr AND expr */
+{
+ fts5yygotominor.fts5yy18 = sqlite3Fts5ParseNode(pParse, FTS5_AND, fts5yymsp[-2].minor.fts5yy18, fts5yymsp[0].minor.fts5yy18, 0);
+}
+ break;
+ case 2: /* expr ::= expr OR expr */
+{
+ fts5yygotominor.fts5yy18 = sqlite3Fts5ParseNode(pParse, FTS5_OR, fts5yymsp[-2].minor.fts5yy18, fts5yymsp[0].minor.fts5yy18, 0);
+}
+ break;
+ case 3: /* expr ::= expr NOT expr */
+{
+ fts5yygotominor.fts5yy18 = sqlite3Fts5ParseNode(pParse, FTS5_NOT, fts5yymsp[-2].minor.fts5yy18, fts5yymsp[0].minor.fts5yy18, 0);
+}
+ break;
+ case 4: /* expr ::= LP expr RP */
+{fts5yygotominor.fts5yy18 = fts5yymsp[-1].minor.fts5yy18;}
+ break;
+ case 5: /* expr ::= exprlist */
+ case 6: /* exprlist ::= cnearset */ fts5yytestcase(fts5yyruleno==6);
+{fts5yygotominor.fts5yy18 = fts5yymsp[0].minor.fts5yy18;}
+ break;
+ case 7: /* exprlist ::= exprlist cnearset */
+{
+ fts5yygotominor.fts5yy18 = sqlite3Fts5ParseNode(pParse, FTS5_AND, fts5yymsp[-1].minor.fts5yy18, fts5yymsp[0].minor.fts5yy18, 0);
+}
+ break;
+ case 8: /* cnearset ::= nearset */
+{
+ fts5yygotominor.fts5yy18 = sqlite3Fts5ParseNode(pParse, FTS5_STRING, 0, 0, fts5yymsp[0].minor.fts5yy26);
+}
+ break;
+ case 9: /* cnearset ::= colset COLON nearset */
+{
+ sqlite3Fts5ParseSetColset(pParse, fts5yymsp[0].minor.fts5yy26, fts5yymsp[-2].minor.fts5yy3);
+ fts5yygotominor.fts5yy18 = sqlite3Fts5ParseNode(pParse, FTS5_STRING, 0, 0, fts5yymsp[0].minor.fts5yy26);
+}
+ break;
+ case 10: /* colset ::= LCP colsetlist RCP */
+{ fts5yygotominor.fts5yy3 = fts5yymsp[-1].minor.fts5yy3; }
+ break;
+ case 11: /* colset ::= STRING */
+{
+ fts5yygotominor.fts5yy3 = sqlite3Fts5ParseColset(pParse, 0, &fts5yymsp[0].minor.fts5yy0);
+}
+ break;
+ case 12: /* colsetlist ::= colsetlist STRING */
+{
+ fts5yygotominor.fts5yy3 = sqlite3Fts5ParseColset(pParse, fts5yymsp[-1].minor.fts5yy3, &fts5yymsp[0].minor.fts5yy0); }
+ break;
+ case 13: /* colsetlist ::= STRING */
+{
+ fts5yygotominor.fts5yy3 = sqlite3Fts5ParseColset(pParse, 0, &fts5yymsp[0].minor.fts5yy0);
+}
+ break;
+ case 14: /* nearset ::= phrase */
+{ fts5yygotominor.fts5yy26 = sqlite3Fts5ParseNearset(pParse, 0, fts5yymsp[0].minor.fts5yy11); }
+ break;
+ case 15: /* nearset ::= STRING LP nearphrases neardist_opt RP */
+{
+ sqlite3Fts5ParseNear(pParse, &fts5yymsp[-4].minor.fts5yy0);
+ sqlite3Fts5ParseSetDistance(pParse, fts5yymsp[-2].minor.fts5yy26, &fts5yymsp[-1].minor.fts5yy0);
+ fts5yygotominor.fts5yy26 = fts5yymsp[-2].minor.fts5yy26;
+}
+ break;
+ case 16: /* nearphrases ::= phrase */
+{
+ fts5yygotominor.fts5yy26 = sqlite3Fts5ParseNearset(pParse, 0, fts5yymsp[0].minor.fts5yy11);
+}
+ break;
+ case 17: /* nearphrases ::= nearphrases phrase */
+{
+ fts5yygotominor.fts5yy26 = sqlite3Fts5ParseNearset(pParse, fts5yymsp[-1].minor.fts5yy26, fts5yymsp[0].minor.fts5yy11);
+}
+ break;
+ case 18: /* neardist_opt ::= */
+{ fts5yygotominor.fts5yy0.p = 0; fts5yygotominor.fts5yy0.n = 0; }
+ break;
+ case 19: /* neardist_opt ::= COMMA STRING */
+{ fts5yygotominor.fts5yy0 = fts5yymsp[0].minor.fts5yy0; }
+ break;
+ case 20: /* phrase ::= phrase PLUS STRING star_opt */
+{
+ fts5yygotominor.fts5yy11 = sqlite3Fts5ParseTerm(pParse, fts5yymsp[-3].minor.fts5yy11, &fts5yymsp[-1].minor.fts5yy0, fts5yymsp[0].minor.fts5yy20);
+}
+ break;
+ case 21: /* phrase ::= STRING star_opt */
+{
+ fts5yygotominor.fts5yy11 = sqlite3Fts5ParseTerm(pParse, 0, &fts5yymsp[-1].minor.fts5yy0, fts5yymsp[0].minor.fts5yy20);
+}
+ break;
+ case 22: /* star_opt ::= STAR */
+{ fts5yygotominor.fts5yy20 = 1; }
+ break;
+ case 23: /* star_opt ::= */
+{ fts5yygotominor.fts5yy20 = 0; }
+ break;
+ default:
+ break;
+/********** End reduce actions ************************************************/
+ };
+ assert( fts5yyruleno>=0 && fts5yyruleno<sizeof(fts5yyRuleInfo)/sizeof(fts5yyRuleInfo[0]) );
+ fts5yygoto = fts5yyRuleInfo[fts5yyruleno].lhs;
+ fts5yysize = fts5yyRuleInfo[fts5yyruleno].nrhs;
+ fts5yypParser->fts5yyidx -= fts5yysize;
+ fts5yyact = fts5yy_find_reduce_action(fts5yymsp[-fts5yysize].stateno,(fts5YYCODETYPE)fts5yygoto);
+ if( fts5yyact <= fts5YY_MAX_SHIFTREDUCE ){
+ if( fts5yyact>fts5YY_MAX_SHIFT ) fts5yyact += fts5YY_MIN_REDUCE - fts5YY_MIN_SHIFTREDUCE;
+ /* If 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 fts5yy_shift().
+ ** That gives a significant speed improvement. */
+ if( fts5yysize ){
+ fts5yypParser->fts5yyidx++;
+ fts5yymsp -= fts5yysize-1;
+ fts5yymsp->stateno = (fts5YYACTIONTYPE)fts5yyact;
+ fts5yymsp->major = (fts5YYCODETYPE)fts5yygoto;
+ fts5yymsp->minor = fts5yygotominor;
+ fts5yyTraceShift(fts5yypParser, fts5yyact);
+ }else{
+ fts5yy_shift(fts5yypParser,fts5yyact,fts5yygoto,&fts5yygotominor);
+ }
+ }else{
+ assert( fts5yyact == fts5YY_ACCEPT_ACTION );
+ fts5yy_accept(fts5yypParser);
+ }
+}
+
+/*
+** The following code executes when the parse fails
+*/
+#ifndef fts5YYNOERRORRECOVERY
+static void fts5yy_parse_failed(
+ fts5yyParser *fts5yypParser /* The parser */
+){
+ sqlite3Fts5ParserARG_FETCH;
+#ifndef NDEBUG
+ if( fts5yyTraceFILE ){
+ fprintf(fts5yyTraceFILE,"%sFail!\n",fts5yyTracePrompt);
+ }
+#endif
+ while( fts5yypParser->fts5yyidx>=0 ) fts5yy_pop_parser_stack(fts5yypParser);
+ /* Here code is inserted which will be executed whenever the
+ ** parser fails */
+/************ Begin %parse_failure code ***************************************/
+/************ End %parse_failure code *****************************************/
+ sqlite3Fts5ParserARG_STORE; /* Suppress warning about unused %extra_argument variable */
+}
+#endif /* fts5YYNOERRORRECOVERY */
+
+/*
+** The following code executes when a syntax error first occurs.
+*/
+static void fts5yy_syntax_error(
+ fts5yyParser *fts5yypParser, /* The parser */
+ int fts5yymajor, /* The major type of the error token */
+ fts5YYMINORTYPE fts5yyminor /* The minor type of the error token */
+){
+ sqlite3Fts5ParserARG_FETCH;
+#define FTS5TOKEN (fts5yyminor.fts5yy0)
+/************ Begin %syntax_error code ****************************************/
+
+ sqlite3Fts5ParseError(
+ pParse, "fts5: syntax error near \"%.*s\"",FTS5TOKEN.n,FTS5TOKEN.p
+ );
+/************ End %syntax_error code ******************************************/
+ sqlite3Fts5ParserARG_STORE; /* Suppress warning about unused %extra_argument variable */
+}
+
+/*
+** The following is executed when the parser accepts
+*/
+static void fts5yy_accept(
+ fts5yyParser *fts5yypParser /* The parser */
+){
+ sqlite3Fts5ParserARG_FETCH;
+#ifndef NDEBUG
+ if( fts5yyTraceFILE ){
+ fprintf(fts5yyTraceFILE,"%sAccept!\n",fts5yyTracePrompt);
+ }
+#endif
+ while( fts5yypParser->fts5yyidx>=0 ) fts5yy_pop_parser_stack(fts5yypParser);
+ /* Here code is inserted which will be executed whenever the
+ ** parser accepts */
+/*********** Begin %parse_accept code *****************************************/
+/*********** End %parse_accept code *******************************************/
+ sqlite3Fts5ParserARG_STORE; /* Suppress warning about unused %extra_argument variable */
+}
+
+/* The main parser program.
+** The first argument is a pointer to a structure obtained from
+** "sqlite3Fts5ParserAlloc" 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.
+*/
+static void sqlite3Fts5Parser(
+ void *fts5yyp, /* The parser */
+ int fts5yymajor, /* The major token code number */
+ sqlite3Fts5ParserFTS5TOKENTYPE fts5yyminor /* The value for the token */
+ sqlite3Fts5ParserARG_PDECL /* Optional %extra_argument parameter */
+){
+ fts5YYMINORTYPE fts5yyminorunion;
+ int fts5yyact; /* The parser action. */
+#if !defined(fts5YYERRORSYMBOL) && !defined(fts5YYNOERRORRECOVERY)
+ int fts5yyendofinput; /* True if we are at the end of input */
+#endif
+#ifdef fts5YYERRORSYMBOL
+ int fts5yyerrorhit = 0; /* True if fts5yymajor has invoked an error */
+#endif
+ fts5yyParser *fts5yypParser; /* The parser */
+
+ /* (re)initialize the parser, if necessary */
+ fts5yypParser = (fts5yyParser*)fts5yyp;
+ if( fts5yypParser->fts5yyidx<0 ){
+#if fts5YYSTACKDEPTH<=0
+ if( fts5yypParser->fts5yystksz <=0 ){
+ /*memset(&fts5yyminorunion, 0, sizeof(fts5yyminorunion));*/
+ fts5yyminorunion = fts5yyzerominor;
+ fts5yyStackOverflow(fts5yypParser, &fts5yyminorunion);
+ return;
+ }
+#endif
+ fts5yypParser->fts5yyidx = 0;
+ fts5yypParser->fts5yyerrcnt = -1;
+ fts5yypParser->fts5yystack[0].stateno = 0;
+ fts5yypParser->fts5yystack[0].major = 0;
+#ifndef NDEBUG
+ if( fts5yyTraceFILE ){
+ fprintf(fts5yyTraceFILE,"%sInitialize. Empty stack. State 0\n",
+ fts5yyTracePrompt);
+ }
+#endif
+ }
+ fts5yyminorunion.fts5yy0 = fts5yyminor;
+#if !defined(fts5YYERRORSYMBOL) && !defined(fts5YYNOERRORRECOVERY)
+ fts5yyendofinput = (fts5yymajor==0);
+#endif
+ sqlite3Fts5ParserARG_STORE;
+
+#ifndef NDEBUG
+ if( fts5yyTraceFILE ){
+ fprintf(fts5yyTraceFILE,"%sInput '%s'\n",fts5yyTracePrompt,fts5yyTokenName[fts5yymajor]);
+ }
+#endif
+
+ do{
+ fts5yyact = fts5yy_find_shift_action(fts5yypParser,(fts5YYCODETYPE)fts5yymajor);
+ if( fts5yyact <= fts5YY_MAX_SHIFTREDUCE ){
+ if( fts5yyact > fts5YY_MAX_SHIFT ) fts5yyact += fts5YY_MIN_REDUCE - fts5YY_MIN_SHIFTREDUCE;
+ fts5yy_shift(fts5yypParser,fts5yyact,fts5yymajor,&fts5yyminorunion);
+ fts5yypParser->fts5yyerrcnt--;
+ fts5yymajor = fts5YYNOCODE;
+ }else if( fts5yyact <= fts5YY_MAX_REDUCE ){
+ fts5yy_reduce(fts5yypParser,fts5yyact-fts5YY_MIN_REDUCE);
+ }else{
+ assert( fts5yyact == fts5YY_ERROR_ACTION );
+#ifdef fts5YYERRORSYMBOL
+ int fts5yymx;
+#endif
+#ifndef NDEBUG
+ if( fts5yyTraceFILE ){
+ fprintf(fts5yyTraceFILE,"%sSyntax Error!\n",fts5yyTracePrompt);
+ }
+#endif
+#ifdef fts5YYERRORSYMBOL
+ /* 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( fts5yypParser->fts5yyerrcnt<0 ){
+ fts5yy_syntax_error(fts5yypParser,fts5yymajor,fts5yyminorunion);
+ }
+ fts5yymx = fts5yypParser->fts5yystack[fts5yypParser->fts5yyidx].major;
+ if( fts5yymx==fts5YYERRORSYMBOL || fts5yyerrorhit ){
+#ifndef NDEBUG
+ if( fts5yyTraceFILE ){
+ fprintf(fts5yyTraceFILE,"%sDiscard input token %s\n",
+ fts5yyTracePrompt,fts5yyTokenName[fts5yymajor]);
+ }
+#endif
+ fts5yy_destructor(fts5yypParser, (fts5YYCODETYPE)fts5yymajor,&fts5yyminorunion);
+ fts5yymajor = fts5YYNOCODE;
+ }else{
+ while(
+ fts5yypParser->fts5yyidx >= 0 &&
+ fts5yymx != fts5YYERRORSYMBOL &&
+ (fts5yyact = fts5yy_find_reduce_action(
+ fts5yypParser->fts5yystack[fts5yypParser->fts5yyidx].stateno,
+ fts5YYERRORSYMBOL)) >= fts5YY_MIN_REDUCE
+ ){
+ fts5yy_pop_parser_stack(fts5yypParser);
+ }
+ if( fts5yypParser->fts5yyidx < 0 || fts5yymajor==0 ){
+ fts5yy_destructor(fts5yypParser,(fts5YYCODETYPE)fts5yymajor,&fts5yyminorunion);
+ fts5yy_parse_failed(fts5yypParser);
+ fts5yymajor = fts5YYNOCODE;
+ }else if( fts5yymx!=fts5YYERRORSYMBOL ){
+ fts5YYMINORTYPE u2;
+ u2.fts5YYERRSYMDT = 0;
+ fts5yy_shift(fts5yypParser,fts5yyact,fts5YYERRORSYMBOL,&u2);
+ }
+ }
+ fts5yypParser->fts5yyerrcnt = 3;
+ fts5yyerrorhit = 1;
+#elif defined(fts5YYNOERRORRECOVERY)
+ /* If the fts5YYNOERRORRECOVERY 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.
+ */
+ fts5yy_syntax_error(fts5yypParser,fts5yymajor,fts5yyminorunion);
+ fts5yy_destructor(fts5yypParser,(fts5YYCODETYPE)fts5yymajor,&fts5yyminorunion);
+ fts5yymajor = fts5YYNOCODE;
+
+#else /* fts5YYERRORSYMBOL 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( fts5yypParser->fts5yyerrcnt<=0 ){
+ fts5yy_syntax_error(fts5yypParser,fts5yymajor,fts5yyminorunion);
+ }
+ fts5yypParser->fts5yyerrcnt = 3;
+ fts5yy_destructor(fts5yypParser,(fts5YYCODETYPE)fts5yymajor,&fts5yyminorunion);
+ if( fts5yyendofinput ){
+ fts5yy_parse_failed(fts5yypParser);
+ }
+ fts5yymajor = fts5YYNOCODE;
+#endif
+ }
+ }while( fts5yymajor!=fts5YYNOCODE && fts5yypParser->fts5yyidx>=0 );
+#ifndef NDEBUG
+ if( fts5yyTraceFILE ){
+ int i;
+ fprintf(fts5yyTraceFILE,"%sReturn. Stack=",fts5yyTracePrompt);
+ for(i=1; i<=fts5yypParser->fts5yyidx; i++)
+ fprintf(fts5yyTraceFILE,"%c%s", i==1 ? '[' : ' ',
+ fts5yyTokenName[fts5yypParser->fts5yystack[i].major]);
+ fprintf(fts5yyTraceFILE,"]\n");
+ }
+#endif
+ return;
+}
+
+/*
+** 2014 May 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.
+**
+******************************************************************************
+*/
+
+
+/* #include "fts5Int.h" */
+#include <math.h> /* amalgamator: keep */
+
+/*
+** Object used to iterate through all "coalesced phrase instances" in
+** a single column of the current row. If the phrase instances in the
+** column being considered do not overlap, this object simply iterates
+** through them. Or, if they do overlap (share one or more tokens in
+** common), each set of overlapping instances is treated as a single
+** match. See documentation for the highlight() auxiliary function for
+** details.
+**
+** Usage is:
+**
+** for(rc = fts5CInstIterNext(pApi, pFts, iCol, &iter);
+** (rc==SQLITE_OK && 0==fts5CInstIterEof(&iter);
+** rc = fts5CInstIterNext(&iter)
+** ){
+** printf("instance starts at %d, ends at %d\n", iter.iStart, iter.iEnd);
+** }
+**
+*/
+typedef struct CInstIter CInstIter;
+struct CInstIter {
+ const Fts5ExtensionApi *pApi; /* API offered by current FTS version */
+ Fts5Context *pFts; /* First arg to pass to pApi functions */
+ int iCol; /* Column to search */
+ int iInst; /* Next phrase instance index */
+ int nInst; /* Total number of phrase instances */
+
+ /* Output variables */
+ int iStart; /* First token in coalesced phrase instance */
+ int iEnd; /* Last token in coalesced phrase instance */
+};
+
+/*
+** Advance the iterator to the next coalesced phrase instance. Return
+** an SQLite error code if an error occurs, or SQLITE_OK otherwise.
+*/
+static int fts5CInstIterNext(CInstIter *pIter){
+ int rc = SQLITE_OK;
+ pIter->iStart = -1;
+ pIter->iEnd = -1;
+
+ while( rc==SQLITE_OK && pIter->iInst<pIter->nInst ){
+ int ip; int ic; int io;
+ rc = pIter->pApi->xInst(pIter->pFts, pIter->iInst, &ip, &ic, &io);
+ if( rc==SQLITE_OK ){
+ if( ic==pIter->iCol ){
+ int iEnd = io - 1 + pIter->pApi->xPhraseSize(pIter->pFts, ip);
+ if( pIter->iStart<0 ){
+ pIter->iStart = io;
+ pIter->iEnd = iEnd;
+ }else if( io<=pIter->iEnd ){
+ if( iEnd>pIter->iEnd ) pIter->iEnd = iEnd;
+ }else{
+ break;
+ }
+ }
+ pIter->iInst++;
+ }
+ }
+
+ return rc;
+}
+
+/*
+** Initialize the iterator object indicated by the final parameter to
+** iterate through coalesced phrase instances in column iCol.
+*/
+static int fts5CInstIterInit(
+ const Fts5ExtensionApi *pApi,
+ Fts5Context *pFts,
+ int iCol,
+ CInstIter *pIter
+){
+ int rc;
+
+ memset(pIter, 0, sizeof(CInstIter));
+ pIter->pApi = pApi;
+ pIter->pFts = pFts;
+ pIter->iCol = iCol;
+ rc = pApi->xInstCount(pFts, &pIter->nInst);
+
+ if( rc==SQLITE_OK ){
+ rc = fts5CInstIterNext(pIter);
+ }
+
+ return rc;
+}
+
+
+
+/*************************************************************************
+** Start of highlight() implementation.
+*/
+typedef struct HighlightContext HighlightContext;
+struct HighlightContext {
+ CInstIter iter; /* Coalesced Instance Iterator */
+ int iPos; /* Current token offset in zIn[] */
+ int iRangeStart; /* First token to include */
+ int iRangeEnd; /* If non-zero, last token to include */
+ const char *zOpen; /* Opening highlight */
+ const char *zClose; /* Closing highlight */
+ const char *zIn; /* Input text */
+ int nIn; /* Size of input text in bytes */
+ int iOff; /* Current offset within zIn[] */
+ char *zOut; /* Output value */
+};
+
+/*
+** Append text to the HighlightContext output string - p->zOut. Argument
+** z points to a buffer containing n bytes of text to append. If n is
+** negative, everything up until the first '\0' is appended to the output.
+**
+** If *pRc is set to any value other than SQLITE_OK when this function is
+** called, it is a no-op. If an error (i.e. an OOM condition) is encountered,
+** *pRc is set to an error code before returning.
+*/
+static void fts5HighlightAppend(
+ int *pRc,
+ HighlightContext *p,
+ const char *z, int n
+){
+ if( *pRc==SQLITE_OK ){
+ if( n<0 ) n = (int)strlen(z);
+ p->zOut = sqlite3_mprintf("%z%.*s", p->zOut, n, z);
+ if( p->zOut==0 ) *pRc = SQLITE_NOMEM;
+ }
+}
+
+/*
+** Tokenizer callback used by implementation of highlight() function.
+*/
+static int fts5HighlightCb(
+ void *pContext, /* Pointer to HighlightContext object */
+ int tflags, /* Mask of FTS5_TOKEN_* flags */
+ const char *pToken, /* Buffer containing token */
+ int nToken, /* Size of token in bytes */
+ int iStartOff, /* Start offset of token */
+ int iEndOff /* End offset of token */
+){
+ HighlightContext *p = (HighlightContext*)pContext;
+ int rc = SQLITE_OK;
+ int iPos;
+
+ if( tflags & FTS5_TOKEN_COLOCATED ) return SQLITE_OK;
+ iPos = p->iPos++;
+
+ if( p->iRangeEnd>0 ){
+ if( iPos<p->iRangeStart || iPos>p->iRangeEnd ) return SQLITE_OK;
+ if( p->iRangeStart && iPos==p->iRangeStart ) p->iOff = iStartOff;
+ }
+
+ if( iPos==p->iter.iStart ){
+ fts5HighlightAppend(&rc, p, &p->zIn[p->iOff], iStartOff - p->iOff);
+ fts5HighlightAppend(&rc, p, p->zOpen, -1);
+ p->iOff = iStartOff;
+ }
+
+ if( iPos==p->iter.iEnd ){
+ if( p->iRangeEnd && p->iter.iStart<p->iRangeStart ){
+ fts5HighlightAppend(&rc, p, p->zOpen, -1);
+ }
+ fts5HighlightAppend(&rc, p, &p->zIn[p->iOff], iEndOff - p->iOff);
+ fts5HighlightAppend(&rc, p, p->zClose, -1);
+ p->iOff = iEndOff;
+ if( rc==SQLITE_OK ){
+ rc = fts5CInstIterNext(&p->iter);
+ }
+ }
+
+ if( p->iRangeEnd>0 && iPos==p->iRangeEnd ){
+ fts5HighlightAppend(&rc, p, &p->zIn[p->iOff], iEndOff - p->iOff);
+ p->iOff = iEndOff;
+ if( iPos<p->iter.iEnd ){
+ fts5HighlightAppend(&rc, p, p->zClose, -1);
+ }
+ }
+
+ return rc;
+}
+
+/*
+** Implementation of highlight() function.
+*/
+static void fts5HighlightFunction(
+ const Fts5ExtensionApi *pApi, /* API offered by current FTS version */
+ Fts5Context *pFts, /* First arg to pass to pApi functions */
+ sqlite3_context *pCtx, /* Context for returning result/error */
+ int nVal, /* Number of values in apVal[] array */
+ sqlite3_value **apVal /* Array of trailing arguments */
+){
+ HighlightContext ctx;
+ int rc;
+ int iCol;
+
+ if( nVal!=3 ){
+ const char *zErr = "wrong number of arguments to function highlight()";
+ sqlite3_result_error(pCtx, zErr, -1);
+ return;
+ }
+
+ iCol = sqlite3_value_int(apVal[0]);
+ memset(&ctx, 0, sizeof(HighlightContext));
+ ctx.zOpen = (const char*)sqlite3_value_text(apVal[1]);
+ ctx.zClose = (const char*)sqlite3_value_text(apVal[2]);
+ rc = pApi->xColumnText(pFts, iCol, &ctx.zIn, &ctx.nIn);
+
+ if( ctx.zIn ){
+ if( rc==SQLITE_OK ){
+ rc = fts5CInstIterInit(pApi, pFts, iCol, &ctx.iter);
+ }
+
+ if( rc==SQLITE_OK ){
+ rc = pApi->xTokenize(pFts, ctx.zIn, ctx.nIn, (void*)&ctx,fts5HighlightCb);
+ }
+ fts5HighlightAppend(&rc, &ctx, &ctx.zIn[ctx.iOff], ctx.nIn - ctx.iOff);
+
+ if( rc==SQLITE_OK ){
+ sqlite3_result_text(pCtx, (const char*)ctx.zOut, -1, SQLITE_TRANSIENT);
+ }
+ sqlite3_free(ctx.zOut);
+ }
+ if( rc!=SQLITE_OK ){
+ sqlite3_result_error_code(pCtx, rc);
+ }
+}
+/*
+** End of highlight() implementation.
+**************************************************************************/
+
+/*
+** Implementation of snippet() function.
+*/
+static void fts5SnippetFunction(
+ const Fts5ExtensionApi *pApi, /* API offered by current FTS version */
+ Fts5Context *pFts, /* First arg to pass to pApi functions */
+ sqlite3_context *pCtx, /* Context for returning result/error */
+ int nVal, /* Number of values in apVal[] array */
+ sqlite3_value **apVal /* Array of trailing arguments */
+){
+ HighlightContext ctx;
+ int rc = SQLITE_OK; /* Return code */
+ int iCol; /* 1st argument to snippet() */
+ const char *zEllips; /* 4th argument to snippet() */
+ int nToken; /* 5th argument to snippet() */
+ int nInst = 0; /* Number of instance matches this row */
+ int i; /* Used to iterate through instances */
+ int nPhrase; /* Number of phrases in query */
+ unsigned char *aSeen; /* Array of "seen instance" flags */
+ int iBestCol; /* Column containing best snippet */
+ int iBestStart = 0; /* First token of best snippet */
+ int iBestLast; /* Last token of best snippet */
+ int nBestScore = 0; /* Score of best snippet */
+ int nColSize = 0; /* Total size of iBestCol in tokens */
+
+ if( nVal!=5 ){
+ const char *zErr = "wrong number of arguments to function snippet()";
+ sqlite3_result_error(pCtx, zErr, -1);
+ return;
+ }
+
+ memset(&ctx, 0, sizeof(HighlightContext));
+ iCol = sqlite3_value_int(apVal[0]);
+ ctx.zOpen = (const char*)sqlite3_value_text(apVal[1]);
+ ctx.zClose = (const char*)sqlite3_value_text(apVal[2]);
+ zEllips = (const char*)sqlite3_value_text(apVal[3]);
+ nToken = sqlite3_value_int(apVal[4]);
+ iBestLast = nToken-1;
+
+ iBestCol = (iCol>=0 ? iCol : 0);
+ nPhrase = pApi->xPhraseCount(pFts);
+ aSeen = sqlite3_malloc(nPhrase);
+ if( aSeen==0 ){
+ rc = SQLITE_NOMEM;
+ }
+
+ if( rc==SQLITE_OK ){
+ rc = pApi->xInstCount(pFts, &nInst);
+ }
+ for(i=0; rc==SQLITE_OK && i<nInst; i++){
+ int ip, iSnippetCol, iStart;
+ memset(aSeen, 0, nPhrase);
+ rc = pApi->xInst(pFts, i, &ip, &iSnippetCol, &iStart);
+ if( rc==SQLITE_OK && (iCol<0 || iSnippetCol==iCol) ){
+ int nScore = 1000;
+ int iLast = iStart - 1 + pApi->xPhraseSize(pFts, ip);
+ int j;
+ aSeen[ip] = 1;
+
+ for(j=i+1; rc==SQLITE_OK && j<nInst; j++){
+ int ic; int io; int iFinal;
+ rc = pApi->xInst(pFts, j, &ip, &ic, &io);
+ iFinal = io + pApi->xPhraseSize(pFts, ip) - 1;
+ if( rc==SQLITE_OK && ic==iSnippetCol && iLast<iStart+nToken ){
+ nScore += aSeen[ip] ? 1000 : 1;
+ aSeen[ip] = 1;
+ if( iFinal>iLast ) iLast = iFinal;
+ }
+ }
+
+ if( rc==SQLITE_OK && nScore>nBestScore ){
+ iBestCol = iSnippetCol;
+ iBestStart = iStart;
+ iBestLast = iLast;
+ nBestScore = nScore;
+ }
+ }
+ }
+
+ if( rc==SQLITE_OK ){
+ rc = pApi->xColumnSize(pFts, iBestCol, &nColSize);
+ }
+ if( rc==SQLITE_OK ){
+ rc = pApi->xColumnText(pFts, iBestCol, &ctx.zIn, &ctx.nIn);
+ }
+ if( ctx.zIn ){
+ if( rc==SQLITE_OK ){
+ rc = fts5CInstIterInit(pApi, pFts, iBestCol, &ctx.iter);
+ }
+
+ if( (iBestStart+nToken-1)>iBestLast ){
+ iBestStart -= (iBestStart+nToken-1-iBestLast) / 2;
+ }
+ if( iBestStart+nToken>nColSize ){
+ iBestStart = nColSize - nToken;
+ }
+ if( iBestStart<0 ) iBestStart = 0;
+
+ ctx.iRangeStart = iBestStart;
+ ctx.iRangeEnd = iBestStart + nToken - 1;
+
+ if( iBestStart>0 ){
+ fts5HighlightAppend(&rc, &ctx, zEllips, -1);
+ }
+ if( rc==SQLITE_OK ){
+ rc = pApi->xTokenize(pFts, ctx.zIn, ctx.nIn, (void*)&ctx,fts5HighlightCb);
+ }
+ if( ctx.iRangeEnd>=(nColSize-1) ){
+ fts5HighlightAppend(&rc, &ctx, &ctx.zIn[ctx.iOff], ctx.nIn - ctx.iOff);
+ }else{
+ fts5HighlightAppend(&rc, &ctx, zEllips, -1);
+ }
+
+ if( rc==SQLITE_OK ){
+ sqlite3_result_text(pCtx, (const char*)ctx.zOut, -1, SQLITE_TRANSIENT);
+ }else{
+ sqlite3_result_error_code(pCtx, rc);
+ }
+ sqlite3_free(ctx.zOut);
+ }
+ sqlite3_free(aSeen);
+}
+
+/************************************************************************/
+
+/*
+** The first time the bm25() function is called for a query, an instance
+** of the following structure is allocated and populated.
+*/
+typedef struct Fts5Bm25Data Fts5Bm25Data;
+struct Fts5Bm25Data {
+ int nPhrase; /* Number of phrases in query */
+ double avgdl; /* Average number of tokens in each row */
+ double *aIDF; /* IDF for each phrase */
+ double *aFreq; /* Array used to calculate phrase freq. */
+};
+
+/*
+** Callback used by fts5Bm25GetData() to count the number of rows in the
+** table matched by each individual phrase within the query.
+*/
+static int fts5CountCb(
+ const Fts5ExtensionApi *pApi,
+ Fts5Context *pFts,
+ void *pUserData /* Pointer to sqlite3_int64 variable */
+){
+ sqlite3_int64 *pn = (sqlite3_int64*)pUserData;
+ (*pn)++;
+ return SQLITE_OK;
+}
+
+/*
+** Set *ppData to point to the Fts5Bm25Data object for the current query.
+** If the object has not already been allocated, allocate and populate it
+** now.
+*/
+static int fts5Bm25GetData(
+ const Fts5ExtensionApi *pApi,
+ Fts5Context *pFts,
+ Fts5Bm25Data **ppData /* OUT: bm25-data object for this query */
+){
+ int rc = SQLITE_OK; /* Return code */
+ Fts5Bm25Data *p; /* Object to return */
+
+ p = pApi->xGetAuxdata(pFts, 0);
+ if( p==0 ){
+ int nPhrase; /* Number of phrases in query */
+ sqlite3_int64 nRow = 0; /* Number of rows in table */
+ sqlite3_int64 nToken = 0; /* Number of tokens in table */
+ int nByte; /* Bytes of space to allocate */
+ int i;
+
+ /* Allocate the Fts5Bm25Data object */
+ nPhrase = pApi->xPhraseCount(pFts);
+ nByte = sizeof(Fts5Bm25Data) + nPhrase*2*sizeof(double);
+ p = (Fts5Bm25Data*)sqlite3_malloc(nByte);
+ if( p==0 ){
+ rc = SQLITE_NOMEM;
+ }else{
+ memset(p, 0, nByte);
+ p->nPhrase = nPhrase;
+ p->aIDF = (double*)&p[1];
+ p->aFreq = &p->aIDF[nPhrase];
+ }
+
+ /* Calculate the average document length for this FTS5 table */
+ if( rc==SQLITE_OK ) rc = pApi->xRowCount(pFts, &nRow);
+ if( rc==SQLITE_OK ) rc = pApi->xColumnTotalSize(pFts, -1, &nToken);
+ if( rc==SQLITE_OK ) p->avgdl = (double)nToken / (double)nRow;
+
+ /* Calculate an IDF for each phrase in the query */
+ for(i=0; rc==SQLITE_OK && i<nPhrase; i++){
+ sqlite3_int64 nHit = 0;
+ rc = pApi->xQueryPhrase(pFts, i, (void*)&nHit, fts5CountCb);
+ if( rc==SQLITE_OK ){
+ /* Calculate the IDF (Inverse Document Frequency) for phrase i.
+ ** This is done using the standard BM25 formula as found on wikipedia:
+ **
+ ** IDF = log( (N - nHit + 0.5) / (nHit + 0.5) )
+ **
+ ** where "N" is the total number of documents in the set and nHit
+ ** is the number that contain at least one instance of the phrase
+ ** under consideration.
+ **
+ ** The problem with this is that if (N < 2*nHit), the IDF is
+ ** negative. Which is undesirable. So the mimimum allowable IDF is
+ ** (1e-6) - roughly the same as a term that appears in just over
+ ** half of set of 5,000,000 documents. */
+ double idf = log( (nRow - nHit + 0.5) / (nHit + 0.5) );
+ if( idf<=0.0 ) idf = 1e-6;
+ p->aIDF[i] = idf;
+ }
+ }
+
+ if( rc!=SQLITE_OK ){
+ sqlite3_free(p);
+ }else{
+ rc = pApi->xSetAuxdata(pFts, p, sqlite3_free);
+ }
+ if( rc!=SQLITE_OK ) p = 0;
+ }
+ *ppData = p;
+ return rc;
+}
+
+/*
+** Implementation of bm25() function.
+*/
+static void fts5Bm25Function(
+ const Fts5ExtensionApi *pApi, /* API offered by current FTS version */
+ Fts5Context *pFts, /* First arg to pass to pApi functions */
+ sqlite3_context *pCtx, /* Context for returning result/error */
+ int nVal, /* Number of values in apVal[] array */
+ sqlite3_value **apVal /* Array of trailing arguments */
+){
+ const double k1 = 1.2; /* Constant "k1" from BM25 formula */
+ const double b = 0.75; /* Constant "b" from BM25 formula */
+ int rc = SQLITE_OK; /* Error code */
+ double score = 0.0; /* SQL function return value */
+ Fts5Bm25Data *pData; /* Values allocated/calculated once only */
+ int i; /* Iterator variable */
+ int nInst = 0; /* Value returned by xInstCount() */
+ double D = 0.0; /* Total number of tokens in row */
+ double *aFreq = 0; /* Array of phrase freq. for current row */
+
+ /* Calculate the phrase frequency (symbol "f(qi,D)" in the documentation)
+ ** for each phrase in the query for the current row. */
+ rc = fts5Bm25GetData(pApi, pFts, &pData);
+ if( rc==SQLITE_OK ){
+ aFreq = pData->aFreq;
+ memset(aFreq, 0, sizeof(double) * pData->nPhrase);
+ rc = pApi->xInstCount(pFts, &nInst);
+ }
+ for(i=0; rc==SQLITE_OK && i<nInst; i++){
+ int ip; int ic; int io;
+ rc = pApi->xInst(pFts, i, &ip, &ic, &io);
+ if( rc==SQLITE_OK ){
+ double w = (nVal > ic) ? sqlite3_value_double(apVal[ic]) : 1.0;
+ aFreq[ip] += w;
+ }
+ }
+
+ /* Figure out the total size of the current row in tokens. */
+ if( rc==SQLITE_OK ){
+ int nTok;
+ rc = pApi->xColumnSize(pFts, -1, &nTok);
+ D = (double)nTok;
+ }
+
+ /* Determine the BM25 score for the current row. */
+ for(i=0; rc==SQLITE_OK && i<pData->nPhrase; i++){
+ score += pData->aIDF[i] * (
+ ( aFreq[i] * (k1 + 1.0) ) /
+ ( aFreq[i] + k1 * (1 - b + b * D / pData->avgdl) )
+ );
+ }
+
+ /* If no error has occurred, return the calculated score. Otherwise,
+ ** throw an SQL exception. */
+ if( rc==SQLITE_OK ){
+ sqlite3_result_double(pCtx, -1.0 * score);
+ }else{
+ sqlite3_result_error_code(pCtx, rc);
+ }
+}
+
+static int sqlite3Fts5AuxInit(fts5_api *pApi){
+ struct Builtin {
+ const char *zFunc; /* Function name (nul-terminated) */
+ void *pUserData; /* User-data pointer */
+ fts5_extension_function xFunc;/* Callback function */
+ void (*xDestroy)(void*); /* Destructor function */
+ } aBuiltin [] = {
+ { "snippet", 0, fts5SnippetFunction, 0 },
+ { "highlight", 0, fts5HighlightFunction, 0 },
+ { "bm25", 0, fts5Bm25Function, 0 },
+ };
+ int rc = SQLITE_OK; /* Return code */
+ int i; /* To iterate through builtin functions */
+
+ for(i=0; rc==SQLITE_OK && i<(int)ArraySize(aBuiltin); i++){
+ rc = pApi->xCreateFunction(pApi,
+ aBuiltin[i].zFunc,
+ aBuiltin[i].pUserData,
+ aBuiltin[i].xFunc,
+ aBuiltin[i].xDestroy
+ );
+ }
+
+ return rc;
+}
+
+
+
+/*
+** 2014 May 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.
+**
+******************************************************************************
+*/
+
+
+
+/* #include "fts5Int.h" */
+
+static int sqlite3Fts5BufferSize(int *pRc, Fts5Buffer *pBuf, int nByte){
+ int nNew = pBuf->nSpace ? pBuf->nSpace*2 : 64;
+ u8 *pNew;
+ while( nNew<nByte ){
+ nNew = nNew * 2;
+ }
+ pNew = sqlite3_realloc(pBuf->p, nNew);
+ if( pNew==0 ){
+ *pRc = SQLITE_NOMEM;
+ return 1;
+ }else{
+ pBuf->nSpace = nNew;
+ pBuf->p = pNew;
+ }
+ return 0;
+}
+
+
+/*
+** Encode value iVal as an SQLite varint and append it to the buffer object
+** pBuf. If an OOM error occurs, set the error code in p.
+*/
+static void sqlite3Fts5BufferAppendVarint(int *pRc, Fts5Buffer *pBuf, i64 iVal){
+ if( fts5BufferGrow(pRc, pBuf, 9) ) return;
+ pBuf->n += sqlite3Fts5PutVarint(&pBuf->p[pBuf->n], iVal);
+}
+
+static void sqlite3Fts5Put32(u8 *aBuf, int iVal){
+ aBuf[0] = (iVal>>24) & 0x00FF;
+ aBuf[1] = (iVal>>16) & 0x00FF;
+ aBuf[2] = (iVal>> 8) & 0x00FF;
+ aBuf[3] = (iVal>> 0) & 0x00FF;
+}
+
+static int sqlite3Fts5Get32(const u8 *aBuf){
+ return (aBuf[0] << 24) + (aBuf[1] << 16) + (aBuf[2] << 8) + aBuf[3];
+}
+
+/*
+** Append buffer nData/pData to buffer pBuf. If an OOM error occurs, set
+** the error code in p. If an error has already occurred when this function
+** is called, it is a no-op.
+*/
+static void sqlite3Fts5BufferAppendBlob(
+ int *pRc,
+ Fts5Buffer *pBuf,
+ int nData,
+ const u8 *pData
+){
+ assert( *pRc || nData>=0 );
+ if( fts5BufferGrow(pRc, pBuf, nData) ) return;
+ memcpy(&pBuf->p[pBuf->n], pData, nData);
+ pBuf->n += nData;
+}
+
+/*
+** Append the nul-terminated string zStr to the buffer pBuf. This function
+** ensures that the byte following the buffer data is set to 0x00, even
+** though this byte is not included in the pBuf->n count.
+*/
+static void sqlite3Fts5BufferAppendString(
+ int *pRc,
+ Fts5Buffer *pBuf,
+ const char *zStr
+){
+ int nStr = (int)strlen(zStr);
+ sqlite3Fts5BufferAppendBlob(pRc, pBuf, nStr+1, (const u8*)zStr);
+ pBuf->n--;
+}
+
+/*
+** Argument zFmt is a printf() style format string. This function performs
+** the printf() style processing, then appends the results to buffer pBuf.
+**
+** Like sqlite3Fts5BufferAppendString(), this function ensures that the byte
+** following the buffer data is set to 0x00, even though this byte is not
+** included in the pBuf->n count.
+*/
+static void sqlite3Fts5BufferAppendPrintf(
+ int *pRc,
+ Fts5Buffer *pBuf,
+ char *zFmt, ...
+){
+ if( *pRc==SQLITE_OK ){
+ char *zTmp;
+ va_list ap;
+ va_start(ap, zFmt);
+ zTmp = sqlite3_vmprintf(zFmt, ap);
+ va_end(ap);
+
+ if( zTmp==0 ){
+ *pRc = SQLITE_NOMEM;
+ }else{
+ sqlite3Fts5BufferAppendString(pRc, pBuf, zTmp);
+ sqlite3_free(zTmp);
+ }
+ }
+}
+
+static char *sqlite3Fts5Mprintf(int *pRc, const char *zFmt, ...){
+ char *zRet = 0;
+ if( *pRc==SQLITE_OK ){
+ va_list ap;
+ va_start(ap, zFmt);
+ zRet = sqlite3_vmprintf(zFmt, ap);
+ va_end(ap);
+ if( zRet==0 ){
+ *pRc = SQLITE_NOMEM;
+ }
+ }
+ return zRet;
+}
+
+
+/*
+** Free any buffer allocated by pBuf. Zero the structure before returning.
+*/
+static void sqlite3Fts5BufferFree(Fts5Buffer *pBuf){
+ sqlite3_free(pBuf->p);
+ memset(pBuf, 0, sizeof(Fts5Buffer));
+}
+
+/*
+** Zero the contents of the buffer object. But do not free the associated
+** memory allocation.
+*/
+static void sqlite3Fts5BufferZero(Fts5Buffer *pBuf){
+ pBuf->n = 0;
+}
+
+/*
+** Set the buffer to contain nData/pData. If an OOM error occurs, leave an
+** the error code in p. If an error has already occurred when this function
+** is called, it is a no-op.
+*/
+static void sqlite3Fts5BufferSet(
+ int *pRc,
+ Fts5Buffer *pBuf,
+ int nData,
+ const u8 *pData
+){
+ pBuf->n = 0;
+ sqlite3Fts5BufferAppendBlob(pRc, pBuf, nData, pData);
+}
+
+static int sqlite3Fts5PoslistNext64(
+ const u8 *a, int n, /* Buffer containing poslist */
+ int *pi, /* IN/OUT: Offset within a[] */
+ i64 *piOff /* IN/OUT: Current offset */
+){
+ int i = *pi;
+ if( i>=n ){
+ /* EOF */
+ *piOff = -1;
+ return 1;
+ }else{
+ i64 iOff = *piOff;
+ int iVal;
+ fts5FastGetVarint32(a, i, iVal);
+ if( iVal==1 ){
+ fts5FastGetVarint32(a, i, iVal);
+ iOff = ((i64)iVal) << 32;
+ fts5FastGetVarint32(a, i, iVal);
+ }
+ *piOff = iOff + (iVal-2);
+ *pi = i;
+ return 0;
+ }
+}
+
+
+/*
+** Advance the iterator object passed as the only argument. Return true
+** if the iterator reaches EOF, or false otherwise.
+*/
+static int sqlite3Fts5PoslistReaderNext(Fts5PoslistReader *pIter){
+ if( sqlite3Fts5PoslistNext64(pIter->a, pIter->n, &pIter->i, &pIter->iPos) ){
+ pIter->bEof = 1;
+ }
+ return pIter->bEof;
+}
+
+static int sqlite3Fts5PoslistReaderInit(
+ const u8 *a, int n, /* Poslist buffer to iterate through */
+ Fts5PoslistReader *pIter /* Iterator object to initialize */
+){
+ memset(pIter, 0, sizeof(*pIter));
+ pIter->a = a;
+ pIter->n = n;
+ sqlite3Fts5PoslistReaderNext(pIter);
+ return pIter->bEof;
+}
+
+static int sqlite3Fts5PoslistWriterAppend(
+ Fts5Buffer *pBuf,
+ Fts5PoslistWriter *pWriter,
+ i64 iPos
+){
+ static const i64 colmask = ((i64)(0x7FFFFFFF)) << 32;
+ int rc = SQLITE_OK;
+ if( 0==fts5BufferGrow(&rc, pBuf, 5+5+5) ){
+ if( (iPos & colmask) != (pWriter->iPrev & colmask) ){
+ pBuf->p[pBuf->n++] = 1;
+ pBuf->n += sqlite3Fts5PutVarint(&pBuf->p[pBuf->n], (iPos>>32));
+ pWriter->iPrev = (iPos & colmask);
+ }
+ pBuf->n += sqlite3Fts5PutVarint(&pBuf->p[pBuf->n], (iPos-pWriter->iPrev)+2);
+ pWriter->iPrev = iPos;
+ }
+ return rc;
+}
+
+static void *sqlite3Fts5MallocZero(int *pRc, int nByte){
+ void *pRet = 0;
+ if( *pRc==SQLITE_OK ){
+ pRet = sqlite3_malloc(nByte);
+ if( pRet==0 && nByte>0 ){
+ *pRc = SQLITE_NOMEM;
+ }else{
+ memset(pRet, 0, nByte);
+ }
+ }
+ return pRet;
+}
+
+/*
+** Return a nul-terminated copy of the string indicated by pIn. If nIn
+** is non-negative, then it is the length of the string in bytes. Otherwise,
+** the length of the string is determined using strlen().
+**
+** It is the responsibility of the caller to eventually free the returned
+** buffer using sqlite3_free(). If an OOM error occurs, NULL is returned.
+*/
+static char *sqlite3Fts5Strndup(int *pRc, const char *pIn, int nIn){
+ char *zRet = 0;
+ if( *pRc==SQLITE_OK ){
+ if( nIn<0 ){
+ nIn = (int)strlen(pIn);
+ }
+ zRet = (char*)sqlite3_malloc(nIn+1);
+ if( zRet ){
+ memcpy(zRet, pIn, nIn);
+ zRet[nIn] = '\0';
+ }else{
+ *pRc = SQLITE_NOMEM;
+ }
+ }
+ return zRet;
+}
+
+
+/*
+** Return true if character 't' may be part of an FTS5 bareword, or false
+** otherwise. Characters that may be part of barewords:
+**
+** * All non-ASCII characters,
+** * The 52 upper and lower case ASCII characters, and
+** * The 10 integer ASCII characters.
+** * The underscore character "_" (0x5F).
+** * The unicode "subsitute" character (0x1A).
+*/
+static int sqlite3Fts5IsBareword(char t){
+ u8 aBareword[128] = {
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x00 .. 0x0F */
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, /* 0x10 .. 0x1F */
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x20 .. 0x2F */
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, /* 0x30 .. 0x3F */
+ 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 0x40 .. 0x4F */
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1, /* 0x50 .. 0x5F */
+ 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 0x60 .. 0x6F */
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0 /* 0x70 .. 0x7F */
+ };
+
+ return (t & 0x80) || aBareword[(int)t];
+}
+
+
+
+/*
+** 2014 Jun 09
+**
+** 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.
+*/
+
+
+
+/* #include "fts5Int.h" */
+
+#define FTS5_DEFAULT_PAGE_SIZE 4050
+#define FTS5_DEFAULT_AUTOMERGE 4
+#define FTS5_DEFAULT_CRISISMERGE 16
+#define FTS5_DEFAULT_HASHSIZE (1024*1024)
+
+/* Maximum allowed page size */
+#define FTS5_MAX_PAGE_SIZE (128*1024)
+
+static int fts5_iswhitespace(char x){
+ return (x==' ');
+}
+
+static int fts5_isopenquote(char x){
+ return (x=='"' || x=='\'' || x=='[' || x=='`');
+}
+
+/*
+** Argument pIn points to a character that is part of a nul-terminated
+** string. Return a pointer to the first character following *pIn in
+** the string that is not a white-space character.
+*/
+static const char *fts5ConfigSkipWhitespace(const char *pIn){
+ const char *p = pIn;
+ if( p ){
+ while( fts5_iswhitespace(*p) ){ p++; }
+ }
+ return p;
+}
+
+/*
+** Argument pIn points to a character that is part of a nul-terminated
+** string. Return a pointer to the first character following *pIn in
+** the string that is not a "bareword" character.
+*/
+static const char *fts5ConfigSkipBareword(const char *pIn){
+ const char *p = pIn;
+ while ( sqlite3Fts5IsBareword(*p) ) p++;
+ if( p==pIn ) p = 0;
+ return p;
+}
+
+static int fts5_isdigit(char a){
+ return (a>='0' && a<='9');
+}
+
+
+
+static const char *fts5ConfigSkipLiteral(const char *pIn){
+ const char *p = pIn;
+ switch( *p ){
+ case 'n': case 'N':
+ if( sqlite3_strnicmp("null", p, 4)==0 ){
+ p = &p[4];
+ }else{
+ p = 0;
+ }
+ break;
+
+ case 'x': case 'X':
+ p++;
+ if( *p=='\'' ){
+ p++;
+ while( (*p>='a' && *p<='f')
+ || (*p>='A' && *p<='F')
+ || (*p>='0' && *p<='9')
+ ){
+ p++;
+ }
+ if( *p=='\'' && 0==((p-pIn)%2) ){
+ p++;
+ }else{
+ p = 0;
+ }
+ }else{
+ p = 0;
+ }
+ break;
+
+ case '\'':
+ p++;
+ while( p ){
+ if( *p=='\'' ){
+ p++;
+ if( *p!='\'' ) break;
+ }
+ p++;
+ if( *p==0 ) p = 0;
+ }
+ break;
+
+ default:
+ /* maybe a number */
+ if( *p=='+' || *p=='-' ) p++;
+ while( fts5_isdigit(*p) ) p++;
+
+ /* At this point, if the literal was an integer, the parse is
+ ** finished. Or, if it is a floating point value, it may continue
+ ** with either a decimal point or an 'E' character. */
+ if( *p=='.' && fts5_isdigit(p[1]) ){
+ p += 2;
+ while( fts5_isdigit(*p) ) p++;
+ }
+ if( p==pIn ) p = 0;
+
+ break;
+ }
+
+ return p;
+}
+
+/*
+** The first character of the string pointed to by argument z is guaranteed
+** to be an open-quote character (see function fts5_isopenquote()).
+**
+** This function searches for the corresponding close-quote character within
+** the string and, if found, dequotes the string in place and adds a new
+** nul-terminator byte.
+**
+** If the close-quote is found, the value returned is the byte offset of
+** the character immediately following it. Or, if the close-quote is not
+** found, -1 is returned. If -1 is returned, the buffer is left in an
+** undefined state.
+*/
+static int fts5Dequote(char *z){
+ char q;
+ int iIn = 1;
+ int iOut = 0;
+ q = z[0];
+
+ /* Set stack variable q to the close-quote character */
+ assert( q=='[' || q=='\'' || q=='"' || q=='`' );
+ if( q=='[' ) q = ']';
+
+ while( ALWAYS(z[iIn]) ){
+ if( z[iIn]==q ){
+ if( z[iIn+1]!=q ){
+ /* Character iIn was the close quote. */
+ iIn++;
+ break;
+ }else{
+ /* Character iIn and iIn+1 form an escaped quote character. Skip
+ ** the input cursor past both and copy a single quote character
+ ** to the output buffer. */
+ iIn += 2;
+ z[iOut++] = q;
+ }
+ }else{
+ z[iOut++] = z[iIn++];
+ }
+ }
+
+ z[iOut] = '\0';
+ return iIn;
+}
+
+/*
+** 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
+*/
+static void sqlite3Fts5Dequote(char *z){
+ char quote; /* Quote character (if any ) */
+
+ assert( 0==fts5_iswhitespace(z[0]) );
+ quote = z[0];
+ if( quote=='[' || quote=='\'' || quote=='"' || quote=='`' ){
+ fts5Dequote(z);
+ }
+}
+
+/*
+** Parse a "special" CREATE VIRTUAL TABLE directive and update
+** configuration object pConfig as appropriate.
+**
+** If successful, object pConfig is updated and SQLITE_OK returned. If
+** an error occurs, an SQLite error code is returned and an error message
+** may be left in *pzErr. It is the responsibility of the caller to
+** eventually free any such error message using sqlite3_free().
+*/
+static int fts5ConfigParseSpecial(
+ Fts5Global *pGlobal,
+ Fts5Config *pConfig, /* Configuration object to update */
+ const char *zCmd, /* Special command to parse */
+ const char *zArg, /* Argument to parse */
+ char **pzErr /* OUT: Error message */
+){
+ int rc = SQLITE_OK;
+ int nCmd = (int)strlen(zCmd);
+ if( sqlite3_strnicmp("prefix", zCmd, nCmd)==0 ){
+ const int nByte = sizeof(int) * FTS5_MAX_PREFIX_INDEXES;
+ const char *p;
+ int bFirst = 1;
+ if( pConfig->aPrefix==0 ){
+ pConfig->aPrefix = sqlite3Fts5MallocZero(&rc, nByte);
+ if( rc ) return rc;
+ }
+
+ p = zArg;
+ while( 1 ){
+ int nPre = 0;
+
+ while( p[0]==' ' ) p++;
+ if( bFirst==0 && p[0]==',' ){
+ p++;
+ while( p[0]==' ' ) p++;
+ }else if( p[0]=='\0' ){
+ break;
+ }
+ if( p[0]<'0' || p[0]>'9' ){
+ *pzErr = sqlite3_mprintf("malformed prefix=... directive");
+ rc = SQLITE_ERROR;
+ break;
+ }
+
+ if( pConfig->nPrefix==FTS5_MAX_PREFIX_INDEXES ){
+ *pzErr = sqlite3_mprintf(
+ "too many prefix indexes (max %d)", FTS5_MAX_PREFIX_INDEXES
+ );
+ rc = SQLITE_ERROR;
+ break;
+ }
+
+ while( p[0]>='0' && p[0]<='9' && nPre<1000 ){
+ nPre = nPre*10 + (p[0] - '0');
+ p++;
+ }
+
+ if( rc==SQLITE_OK && (nPre<=0 || nPre>=1000) ){
+ *pzErr = sqlite3_mprintf("prefix length out of range (max 999)");
+ rc = SQLITE_ERROR;
+ break;
+ }
+
+ pConfig->aPrefix[pConfig->nPrefix] = nPre;
+ pConfig->nPrefix++;
+ bFirst = 0;
+ }
+ assert( pConfig->nPrefix<=FTS5_MAX_PREFIX_INDEXES );
+ return rc;
+ }
+
+ if( sqlite3_strnicmp("tokenize", zCmd, nCmd)==0 ){
+ const char *p = (const char*)zArg;
+ int nArg = (int)strlen(zArg) + 1;
+ char **azArg = sqlite3Fts5MallocZero(&rc, sizeof(char*) * nArg);
+ char *pDel = sqlite3Fts5MallocZero(&rc, nArg * 2);
+ char *pSpace = pDel;
+
+ if( azArg && pSpace ){
+ if( pConfig->pTok ){
+ *pzErr = sqlite3_mprintf("multiple tokenize=... directives");
+ rc = SQLITE_ERROR;
+ }else{
+ for(nArg=0; p && *p; nArg++){
+ const char *p2 = fts5ConfigSkipWhitespace(p);
+ if( *p2=='\'' ){
+ p = fts5ConfigSkipLiteral(p2);
+ }else{
+ p = fts5ConfigSkipBareword(p2);
+ }
+ if( p ){
+ memcpy(pSpace, p2, p-p2);
+ azArg[nArg] = pSpace;
+ sqlite3Fts5Dequote(pSpace);
+ pSpace += (p - p2) + 1;
+ p = fts5ConfigSkipWhitespace(p);
+ }
+ }
+ if( p==0 ){
+ *pzErr = sqlite3_mprintf("parse error in tokenize directive");
+ rc = SQLITE_ERROR;
+ }else{
+ rc = sqlite3Fts5GetTokenizer(pGlobal,
+ (const char**)azArg, nArg, &pConfig->pTok, &pConfig->pTokApi,
+ pzErr
+ );
+ }
+ }
+ }
+
+ sqlite3_free(azArg);
+ sqlite3_free(pDel);
+ return rc;
+ }
+
+ if( sqlite3_strnicmp("content", zCmd, nCmd)==0 ){
+ if( pConfig->eContent!=FTS5_CONTENT_NORMAL ){
+ *pzErr = sqlite3_mprintf("multiple content=... directives");
+ rc = SQLITE_ERROR;
+ }else{
+ if( zArg[0] ){
+ pConfig->eContent = FTS5_CONTENT_EXTERNAL;
+ pConfig->zContent = sqlite3Fts5Mprintf(&rc, "%Q.%Q", pConfig->zDb,zArg);
+ }else{
+ pConfig->eContent = FTS5_CONTENT_NONE;
+ }
+ }
+ return rc;
+ }
+
+ if( sqlite3_strnicmp("content_rowid", zCmd, nCmd)==0 ){
+ if( pConfig->zContentRowid ){
+ *pzErr = sqlite3_mprintf("multiple content_rowid=... directives");
+ rc = SQLITE_ERROR;
+ }else{
+ pConfig->zContentRowid = sqlite3Fts5Strndup(&rc, zArg, -1);
+ }
+ return rc;
+ }
+
+ if( sqlite3_strnicmp("columnsize", zCmd, nCmd)==0 ){
+ if( (zArg[0]!='0' && zArg[0]!='1') || zArg[1]!='\0' ){
+ *pzErr = sqlite3_mprintf("malformed columnsize=... directive");
+ rc = SQLITE_ERROR;
+ }else{
+ pConfig->bColumnsize = (zArg[0]=='1');
+ }
+ return rc;
+ }
+
+ *pzErr = sqlite3_mprintf("unrecognized option: \"%.*s\"", nCmd, zCmd);
+ return SQLITE_ERROR;
+}
+
+/*
+** Allocate an instance of the default tokenizer ("simple") at
+** Fts5Config.pTokenizer. Return SQLITE_OK if successful, or an SQLite error
+** code if an error occurs.
+*/
+static int fts5ConfigDefaultTokenizer(Fts5Global *pGlobal, Fts5Config *pConfig){
+ assert( pConfig->pTok==0 && pConfig->pTokApi==0 );
+ return sqlite3Fts5GetTokenizer(
+ pGlobal, 0, 0, &pConfig->pTok, &pConfig->pTokApi, 0
+ );
+}
+
+/*
+** Gobble up the first bareword or quoted word from the input buffer zIn.
+** Return a pointer to the character immediately following the last in
+** the gobbled word if successful, or a NULL pointer otherwise (failed
+** to find close-quote character).
+**
+** Before returning, set pzOut to point to a new buffer containing a
+** nul-terminated, dequoted copy of the gobbled word. If the word was
+** quoted, *pbQuoted is also set to 1 before returning.
+**
+** If *pRc is other than SQLITE_OK when this function is called, it is
+** a no-op (NULL is returned). Otherwise, if an OOM occurs within this
+** function, *pRc is set to SQLITE_NOMEM before returning. *pRc is *not*
+** set if a parse error (failed to find close quote) occurs.
+*/
+static const char *fts5ConfigGobbleWord(
+ int *pRc, /* IN/OUT: Error code */
+ const char *zIn, /* Buffer to gobble string/bareword from */
+ char **pzOut, /* OUT: malloc'd buffer containing str/bw */
+ int *pbQuoted /* OUT: Set to true if dequoting required */
+){
+ const char *zRet = 0;
+
+ int nIn = (int)strlen(zIn);
+ char *zOut = sqlite3_malloc(nIn+1);
+
+ assert( *pRc==SQLITE_OK );
+ *pbQuoted = 0;
+ *pzOut = 0;
+
+ if( zOut==0 ){
+ *pRc = SQLITE_NOMEM;
+ }else{
+ memcpy(zOut, zIn, nIn+1);
+ if( fts5_isopenquote(zOut[0]) ){
+ int ii = fts5Dequote(zOut);
+ zRet = &zIn[ii];
+ *pbQuoted = 1;
+ }else{
+ zRet = fts5ConfigSkipBareword(zIn);
+ zOut[zRet-zIn] = '\0';
+ }
+ }
+
+ if( zRet==0 ){
+ sqlite3_free(zOut);
+ }else{
+ *pzOut = zOut;
+ }
+
+ return zRet;
+}
+
+static int fts5ConfigParseColumn(
+ Fts5Config *p,
+ char *zCol,
+ char *zArg,
+ char **pzErr
+){
+ int rc = SQLITE_OK;
+ if( 0==sqlite3_stricmp(zCol, FTS5_RANK_NAME)
+ || 0==sqlite3_stricmp(zCol, FTS5_ROWID_NAME)
+ ){
+ *pzErr = sqlite3_mprintf("reserved fts5 column name: %s", zCol);
+ rc = SQLITE_ERROR;
+ }else if( zArg ){
+ if( 0==sqlite3_stricmp(zArg, "unindexed") ){
+ p->abUnindexed[p->nCol] = 1;
+ }else{
+ *pzErr = sqlite3_mprintf("unrecognized column option: %s", zArg);
+ rc = SQLITE_ERROR;
+ }
+ }
+
+ p->azCol[p->nCol++] = zCol;
+ return rc;
+}
+
+/*
+** Populate the Fts5Config.zContentExprlist string.
+*/
+static int fts5ConfigMakeExprlist(Fts5Config *p){
+ int i;
+ int rc = SQLITE_OK;
+ Fts5Buffer buf = {0, 0, 0};
+
+ sqlite3Fts5BufferAppendPrintf(&rc, &buf, "T.%Q", p->zContentRowid);
+ if( p->eContent!=FTS5_CONTENT_NONE ){
+ for(i=0; i<p->nCol; i++){
+ if( p->eContent==FTS5_CONTENT_EXTERNAL ){
+ sqlite3Fts5BufferAppendPrintf(&rc, &buf, ", T.%Q", p->azCol[i]);
+ }else{
+ sqlite3Fts5BufferAppendPrintf(&rc, &buf, ", T.c%d", i);
+ }
+ }
+ }
+
+ assert( p->zContentExprlist==0 );
+ p->zContentExprlist = (char*)buf.p;
+ return rc;
+}
+
+/*
+** Arguments nArg/azArg contain the string arguments passed to the xCreate
+** or xConnect method of the virtual table. This function attempts to
+** allocate an instance of Fts5Config containing the results of parsing
+** those arguments.
+**
+** If successful, SQLITE_OK is returned and *ppOut is set to point to the
+** new Fts5Config object. If an error occurs, an SQLite error code is
+** returned, *ppOut is set to NULL and an error message may be left in
+** *pzErr. It is the responsibility of the caller to eventually free any
+** such error message using sqlite3_free().
+*/
+static int sqlite3Fts5ConfigParse(
+ Fts5Global *pGlobal,
+ sqlite3 *db,
+ int nArg, /* Number of arguments */
+ const char **azArg, /* Array of nArg CREATE VIRTUAL TABLE args */
+ Fts5Config **ppOut, /* OUT: Results of parse */
+ char **pzErr /* OUT: Error message */
+){
+ int rc = SQLITE_OK; /* Return code */
+ Fts5Config *pRet; /* New object to return */
+ int i;
+ int nByte;
+
+ *ppOut = pRet = (Fts5Config*)sqlite3_malloc(sizeof(Fts5Config));
+ if( pRet==0 ) return SQLITE_NOMEM;
+ memset(pRet, 0, sizeof(Fts5Config));
+ pRet->db = db;
+ pRet->iCookie = -1;
+
+ nByte = nArg * (sizeof(char*) + sizeof(u8));
+ pRet->azCol = (char**)sqlite3Fts5MallocZero(&rc, nByte);
+ pRet->abUnindexed = (u8*)&pRet->azCol[nArg];
+ pRet->zDb = sqlite3Fts5Strndup(&rc, azArg[1], -1);
+ pRet->zName = sqlite3Fts5Strndup(&rc, azArg[2], -1);
+ pRet->bColumnsize = 1;
+#ifdef SQLITE_DEBUG
+ pRet->bPrefixIndex = 1;
+#endif
+ if( rc==SQLITE_OK && sqlite3_stricmp(pRet->zName, FTS5_RANK_NAME)==0 ){
+ *pzErr = sqlite3_mprintf("reserved fts5 table name: %s", pRet->zName);
+ rc = SQLITE_ERROR;
+ }
+
+ for(i=3; rc==SQLITE_OK && i<nArg; i++){
+ const char *zOrig = azArg[i];
+ const char *z;
+ char *zOne = 0;
+ char *zTwo = 0;
+ int bOption = 0;
+ int bMustBeCol = 0;
+
+ z = fts5ConfigGobbleWord(&rc, zOrig, &zOne, &bMustBeCol);
+ z = fts5ConfigSkipWhitespace(z);
+ if( z && *z=='=' ){
+ bOption = 1;
+ z++;
+ if( bMustBeCol ) z = 0;
+ }
+ z = fts5ConfigSkipWhitespace(z);
+ if( z && z[0] ){
+ int bDummy;
+ z = fts5ConfigGobbleWord(&rc, z, &zTwo, &bDummy);
+ if( z && z[0] ) z = 0;
+ }
+
+ if( rc==SQLITE_OK ){
+ if( z==0 ){
+ *pzErr = sqlite3_mprintf("parse error in \"%s\"", zOrig);
+ rc = SQLITE_ERROR;
+ }else{
+ if( bOption ){
+ rc = fts5ConfigParseSpecial(pGlobal, pRet, zOne, zTwo?zTwo:"", pzErr);
+ }else{
+ rc = fts5ConfigParseColumn(pRet, zOne, zTwo, pzErr);
+ zOne = 0;
+ }
+ }
+ }
+
+ sqlite3_free(zOne);
+ sqlite3_free(zTwo);
+ }
+
+ /* If a tokenizer= option was successfully parsed, the tokenizer has
+ ** already been allocated. Otherwise, allocate an instance of the default
+ ** tokenizer (unicode61) now. */
+ if( rc==SQLITE_OK && pRet->pTok==0 ){
+ rc = fts5ConfigDefaultTokenizer(pGlobal, pRet);
+ }
+
+ /* If no zContent option was specified, fill in the default values. */
+ if( rc==SQLITE_OK && pRet->zContent==0 ){
+ const char *zTail = 0;
+ assert( pRet->eContent==FTS5_CONTENT_NORMAL
+ || pRet->eContent==FTS5_CONTENT_NONE
+ );
+ if( pRet->eContent==FTS5_CONTENT_NORMAL ){
+ zTail = "content";
+ }else if( pRet->bColumnsize ){
+ zTail = "docsize";
+ }
+
+ if( zTail ){
+ pRet->zContent = sqlite3Fts5Mprintf(
+ &rc, "%Q.'%q_%s'", pRet->zDb, pRet->zName, zTail
+ );
+ }
+ }
+
+ if( rc==SQLITE_OK && pRet->zContentRowid==0 ){
+ pRet->zContentRowid = sqlite3Fts5Strndup(&rc, "rowid", -1);
+ }
+
+ /* Formulate the zContentExprlist text */
+ if( rc==SQLITE_OK ){
+ rc = fts5ConfigMakeExprlist(pRet);
+ }
+
+ if( rc!=SQLITE_OK ){
+ sqlite3Fts5ConfigFree(pRet);
+ *ppOut = 0;
+ }
+ return rc;
+}
+
+/*
+** Free the configuration object passed as the only argument.
+*/
+static void sqlite3Fts5ConfigFree(Fts5Config *pConfig){
+ if( pConfig ){
+ int i;
+ if( pConfig->pTok ){
+ pConfig->pTokApi->xDelete(pConfig->pTok);
+ }
+ sqlite3_free(pConfig->zDb);
+ sqlite3_free(pConfig->zName);
+ for(i=0; i<pConfig->nCol; i++){
+ sqlite3_free(pConfig->azCol[i]);
+ }
+ sqlite3_free(pConfig->azCol);
+ sqlite3_free(pConfig->aPrefix);
+ sqlite3_free(pConfig->zRank);
+ sqlite3_free(pConfig->zRankArgs);
+ sqlite3_free(pConfig->zContent);
+ sqlite3_free(pConfig->zContentRowid);
+ sqlite3_free(pConfig->zContentExprlist);
+ sqlite3_free(pConfig);
+ }
+}
+
+/*
+** Call sqlite3_declare_vtab() based on the contents of the configuration
+** object passed as the only argument. Return SQLITE_OK if successful, or
+** an SQLite error code if an error occurs.
+*/
+static int sqlite3Fts5ConfigDeclareVtab(Fts5Config *pConfig){
+ int i;
+ int rc = SQLITE_OK;
+ char *zSql;
+
+ zSql = sqlite3Fts5Mprintf(&rc, "CREATE TABLE x(");
+ for(i=0; zSql && i<pConfig->nCol; i++){
+ const char *zSep = (i==0?"":", ");
+ zSql = sqlite3Fts5Mprintf(&rc, "%z%s%Q", zSql, zSep, pConfig->azCol[i]);
+ }
+ zSql = sqlite3Fts5Mprintf(&rc, "%z, %Q HIDDEN, %s HIDDEN)",
+ zSql, pConfig->zName, FTS5_RANK_NAME
+ );
+
+ assert( zSql || rc==SQLITE_NOMEM );
+ if( zSql ){
+ rc = sqlite3_declare_vtab(pConfig->db, zSql);
+ sqlite3_free(zSql);
+ }
+
+ return rc;
+}
+
+/*
+** Tokenize the text passed via the second and third arguments.
+**
+** The callback is invoked once for each token in the input text. The
+** arguments passed to it are, in order:
+**
+** void *pCtx // Copy of 4th argument to sqlite3Fts5Tokenize()
+** const char *pToken // Pointer to buffer containing token
+** int nToken // Size of token in bytes
+** int iStart // Byte offset of start of token within input text
+** int iEnd // Byte offset of end of token within input text
+** int iPos // Position of token in input (first token is 0)
+**
+** If the callback returns a non-zero value the tokenization is abandoned
+** and no further callbacks are issued.
+**
+** This function returns SQLITE_OK if successful or an SQLite error code
+** if an error occurs. If the tokenization was abandoned early because
+** the callback returned SQLITE_DONE, this is not an error and this function
+** still returns SQLITE_OK. Or, if the tokenization was abandoned early
+** because the callback returned another non-zero value, it is assumed
+** to be an SQLite error code and returned to the caller.
+*/
+static int sqlite3Fts5Tokenize(
+ Fts5Config *pConfig, /* FTS5 Configuration object */
+ int flags, /* FTS5_TOKENIZE_* flags */
+ const char *pText, int nText, /* Text to tokenize */
+ void *pCtx, /* Context passed to xToken() */
+ int (*xToken)(void*, int, const char*, int, int, int) /* Callback */
+){
+ if( pText==0 ) return SQLITE_OK;
+ return pConfig->pTokApi->xTokenize(
+ pConfig->pTok, pCtx, flags, pText, nText, xToken
+ );
+}
+
+/*
+** Argument pIn points to the first character in what is expected to be
+** a comma-separated list of SQL literals followed by a ')' character.
+** If it actually is this, return a pointer to the ')'. Otherwise, return
+** NULL to indicate a parse error.
+*/
+static const char *fts5ConfigSkipArgs(const char *pIn){
+ const char *p = pIn;
+
+ while( 1 ){
+ p = fts5ConfigSkipWhitespace(p);
+ p = fts5ConfigSkipLiteral(p);
+ p = fts5ConfigSkipWhitespace(p);
+ if( p==0 || *p==')' ) break;
+ if( *p!=',' ){
+ p = 0;
+ break;
+ }
+ p++;
+ }
+
+ return p;
+}
+
+/*
+** Parameter zIn contains a rank() function specification. The format of
+** this is:
+**
+** + Bareword (function name)
+** + Open parenthesis - "("
+** + Zero or more SQL literals in a comma separated list
+** + Close parenthesis - ")"
+*/
+static int sqlite3Fts5ConfigParseRank(
+ const char *zIn, /* Input string */
+ char **pzRank, /* OUT: Rank function name */
+ char **pzRankArgs /* OUT: Rank function arguments */
+){
+ const char *p = zIn;
+ const char *pRank;
+ char *zRank = 0;
+ char *zRankArgs = 0;
+ int rc = SQLITE_OK;
+
+ *pzRank = 0;
+ *pzRankArgs = 0;
+
+ if( p==0 ){
+ rc = SQLITE_ERROR;
+ }else{
+ p = fts5ConfigSkipWhitespace(p);
+ pRank = p;
+ p = fts5ConfigSkipBareword(p);
+
+ if( p ){
+ zRank = sqlite3Fts5MallocZero(&rc, 1 + p - pRank);
+ if( zRank ) memcpy(zRank, pRank, p-pRank);
+ }else{
+ rc = SQLITE_ERROR;
+ }
+
+ if( rc==SQLITE_OK ){
+ p = fts5ConfigSkipWhitespace(p);
+ if( *p!='(' ) rc = SQLITE_ERROR;
+ p++;
+ }
+ if( rc==SQLITE_OK ){
+ const char *pArgs;
+ p = fts5ConfigSkipWhitespace(p);
+ pArgs = p;
+ if( *p!=')' ){
+ p = fts5ConfigSkipArgs(p);
+ if( p==0 ){
+ rc = SQLITE_ERROR;
+ }else{
+ zRankArgs = sqlite3Fts5MallocZero(&rc, 1 + p - pArgs);
+ if( zRankArgs ) memcpy(zRankArgs, pArgs, p-pArgs);
+ }
+ }
+ }
+ }
+
+ if( rc!=SQLITE_OK ){
+ sqlite3_free(zRank);
+ assert( zRankArgs==0 );
+ }else{
+ *pzRank = zRank;
+ *pzRankArgs = zRankArgs;
+ }
+ return rc;
+}
+
+static int sqlite3Fts5ConfigSetValue(
+ Fts5Config *pConfig,
+ const char *zKey,
+ sqlite3_value *pVal,
+ int *pbBadkey
+){
+ int rc = SQLITE_OK;
+
+ if( 0==sqlite3_stricmp(zKey, "pgsz") ){
+ int pgsz = 0;
+ if( SQLITE_INTEGER==sqlite3_value_numeric_type(pVal) ){
+ pgsz = sqlite3_value_int(pVal);
+ }
+ if( pgsz<=0 || pgsz>FTS5_MAX_PAGE_SIZE ){
+ *pbBadkey = 1;
+ }else{
+ pConfig->pgsz = pgsz;
+ }
+ }
+
+ else if( 0==sqlite3_stricmp(zKey, "hashsize") ){
+ int nHashSize = -1;
+ if( SQLITE_INTEGER==sqlite3_value_numeric_type(pVal) ){
+ nHashSize = sqlite3_value_int(pVal);
+ }
+ if( nHashSize<=0 ){
+ *pbBadkey = 1;
+ }else{
+ pConfig->nHashSize = nHashSize;
+ }
+ }
+
+ else if( 0==sqlite3_stricmp(zKey, "automerge") ){
+ int nAutomerge = -1;
+ if( SQLITE_INTEGER==sqlite3_value_numeric_type(pVal) ){
+ nAutomerge = sqlite3_value_int(pVal);
+ }
+ if( nAutomerge<0 || nAutomerge>64 ){
+ *pbBadkey = 1;
+ }else{
+ if( nAutomerge==1 ) nAutomerge = FTS5_DEFAULT_AUTOMERGE;
+ pConfig->nAutomerge = nAutomerge;
+ }
+ }
+
+ else if( 0==sqlite3_stricmp(zKey, "crisismerge") ){
+ int nCrisisMerge = -1;
+ if( SQLITE_INTEGER==sqlite3_value_numeric_type(pVal) ){
+ nCrisisMerge = sqlite3_value_int(pVal);
+ }
+ if( nCrisisMerge<0 ){
+ *pbBadkey = 1;
+ }else{
+ if( nCrisisMerge<=1 ) nCrisisMerge = FTS5_DEFAULT_CRISISMERGE;
+ pConfig->nCrisisMerge = nCrisisMerge;
+ }
+ }
+
+ else if( 0==sqlite3_stricmp(zKey, "rank") ){
+ const char *zIn = (const char*)sqlite3_value_text(pVal);
+ char *zRank;
+ char *zRankArgs;
+ rc = sqlite3Fts5ConfigParseRank(zIn, &zRank, &zRankArgs);
+ if( rc==SQLITE_OK ){
+ sqlite3_free(pConfig->zRank);
+ sqlite3_free(pConfig->zRankArgs);
+ pConfig->zRank = zRank;
+ pConfig->zRankArgs = zRankArgs;
+ }else if( rc==SQLITE_ERROR ){
+ rc = SQLITE_OK;
+ *pbBadkey = 1;
+ }
+ }else{
+ *pbBadkey = 1;
+ }
+ return rc;
+}
+
+/*
+** Load the contents of the %_config table into memory.
+*/
+static int sqlite3Fts5ConfigLoad(Fts5Config *pConfig, int iCookie){
+ const char *zSelect = "SELECT k, v FROM %Q.'%q_config'";
+ char *zSql;
+ sqlite3_stmt *p = 0;
+ int rc = SQLITE_OK;
+ int iVersion = 0;
+
+ /* Set default values */
+ pConfig->pgsz = FTS5_DEFAULT_PAGE_SIZE;
+ pConfig->nAutomerge = FTS5_DEFAULT_AUTOMERGE;
+ pConfig->nCrisisMerge = FTS5_DEFAULT_CRISISMERGE;
+ pConfig->nHashSize = FTS5_DEFAULT_HASHSIZE;
+
+ zSql = sqlite3Fts5Mprintf(&rc, zSelect, pConfig->zDb, pConfig->zName);
+ if( zSql ){
+ rc = sqlite3_prepare_v2(pConfig->db, zSql, -1, &p, 0);
+ sqlite3_free(zSql);
+ }
+
+ assert( rc==SQLITE_OK || p==0 );
+ if( rc==SQLITE_OK ){
+ while( SQLITE_ROW==sqlite3_step(p) ){
+ const char *zK = (const char*)sqlite3_column_text(p, 0);
+ sqlite3_value *pVal = sqlite3_column_value(p, 1);
+ if( 0==sqlite3_stricmp(zK, "version") ){
+ iVersion = sqlite3_value_int(pVal);
+ }else{
+ int bDummy = 0;
+ sqlite3Fts5ConfigSetValue(pConfig, zK, pVal, &bDummy);
+ }
+ }
+ rc = sqlite3_finalize(p);
+ }
+
+ if( rc==SQLITE_OK && iVersion!=FTS5_CURRENT_VERSION ){
+ rc = SQLITE_ERROR;
+ if( pConfig->pzErrmsg ){
+ assert( 0==*pConfig->pzErrmsg );
+ *pConfig->pzErrmsg = sqlite3_mprintf(
+ "invalid fts5 file format (found %d, expected %d) - run 'rebuild'",
+ iVersion, FTS5_CURRENT_VERSION
+ );
+ }
+ }
+
+ if( rc==SQLITE_OK ){
+ pConfig->iCookie = iCookie;
+ }
+ return rc;
+}
+
+
+/*
+** 2014 May 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.
+**
+******************************************************************************
+**
+*/
+
+
+
+/* #include "fts5Int.h" */
+/* #include "fts5parse.h" */
+
+/*
+** All token types in the generated fts5parse.h file are greater than 0.
+*/
+#define FTS5_EOF 0
+
+#define FTS5_LARGEST_INT64 (0xffffffff|(((i64)0x7fffffff)<<32))
+
+typedef struct Fts5ExprTerm Fts5ExprTerm;
+
+/*
+** Functions generated by lemon from fts5parse.y.
+*/
+static void *sqlite3Fts5ParserAlloc(void *(*mallocProc)(u64));
+static void sqlite3Fts5ParserFree(void*, void (*freeProc)(void*));
+static void sqlite3Fts5Parser(void*, int, Fts5Token, Fts5Parse*);
+#ifndef NDEBUG
+/* #include <stdio.h> */
+static void sqlite3Fts5ParserTrace(FILE*, char*);
+#endif
+
+
+struct Fts5Expr {
+ Fts5Index *pIndex;
+ Fts5ExprNode *pRoot;
+ int bDesc; /* Iterate in descending rowid order */
+ int nPhrase; /* Number of phrases in expression */
+ Fts5ExprPhrase **apExprPhrase; /* Pointers to phrase objects */
+};
+
+/*
+** eType:
+** Expression node type. Always one of:
+**
+** FTS5_AND (nChild, apChild valid)
+** FTS5_OR (nChild, apChild valid)
+** FTS5_NOT (nChild, apChild valid)
+** FTS5_STRING (pNear valid)
+** FTS5_TERM (pNear valid)
+*/
+struct Fts5ExprNode {
+ int eType; /* Node type */
+ int bEof; /* True at EOF */
+ int bNomatch; /* True if entry is not a match */
+
+ i64 iRowid; /* Current rowid */
+ Fts5ExprNearset *pNear; /* For FTS5_STRING - cluster of phrases */
+
+ /* Child nodes. For a NOT node, this array always contains 2 entries. For
+ ** AND or OR nodes, it contains 2 or more entries. */
+ int nChild; /* Number of child nodes */
+ Fts5ExprNode *apChild[1]; /* Array of child nodes */
+};
+
+#define Fts5NodeIsString(p) ((p)->eType==FTS5_TERM || (p)->eType==FTS5_STRING)
+
+/*
+** An instance of the following structure represents a single search term
+** or term prefix.
+*/
+struct Fts5ExprTerm {
+ int bPrefix; /* True for a prefix term */
+ char *zTerm; /* nul-terminated term */
+ Fts5IndexIter *pIter; /* Iterator for this term */
+ Fts5ExprTerm *pSynonym; /* Pointer to first in list of synonyms */
+};
+
+/*
+** A phrase. One or more terms that must appear in a contiguous sequence
+** within a document for it to match.
+*/
+struct Fts5ExprPhrase {
+ Fts5ExprNode *pNode; /* FTS5_STRING node this phrase is part of */
+ Fts5Buffer poslist; /* Current position list */
+ int nTerm; /* Number of entries in aTerm[] */
+ Fts5ExprTerm aTerm[1]; /* Terms that make up this phrase */
+};
+
+/*
+** One or more phrases that must appear within a certain token distance of
+** each other within each matching document.
+*/
+struct Fts5ExprNearset {
+ int nNear; /* NEAR parameter */
+ Fts5Colset *pColset; /* Columns to search (NULL -> all columns) */
+ int nPhrase; /* Number of entries in aPhrase[] array */
+ Fts5ExprPhrase *apPhrase[1]; /* Array of phrase pointers */
+};
+
+
+/*
+** Parse context.
+*/
+struct Fts5Parse {
+ Fts5Config *pConfig;
+ char *zErr;
+ int rc;
+ int nPhrase; /* Size of apPhrase array */
+ Fts5ExprPhrase **apPhrase; /* Array of all phrases */
+ Fts5ExprNode *pExpr; /* Result of a successful parse */
+};
+
+static void sqlite3Fts5ParseError(Fts5Parse *pParse, const char *zFmt, ...){
+ va_list ap;
+ va_start(ap, zFmt);
+ if( pParse->rc==SQLITE_OK ){
+ pParse->zErr = sqlite3_vmprintf(zFmt, ap);
+ pParse->rc = SQLITE_ERROR;
+ }
+ va_end(ap);
+}
+
+static int fts5ExprIsspace(char t){
+ return t==' ' || t=='\t' || t=='\n' || t=='\r';
+}
+
+/*
+** Read the first token from the nul-terminated string at *pz.
+*/
+static int fts5ExprGetToken(
+ Fts5Parse *pParse,
+ const char **pz, /* IN/OUT: Pointer into buffer */
+ Fts5Token *pToken
+){
+ const char *z = *pz;
+ int tok;
+
+ /* Skip past any whitespace */
+ while( fts5ExprIsspace(*z) ) z++;
+
+ pToken->p = z;
+ pToken->n = 1;
+ switch( *z ){
+ case '(': tok = FTS5_LP; break;
+ case ')': tok = FTS5_RP; break;
+ case '{': tok = FTS5_LCP; break;
+ case '}': tok = FTS5_RCP; break;
+ case ':': tok = FTS5_COLON; break;
+ case ',': tok = FTS5_COMMA; break;
+ case '+': tok = FTS5_PLUS; break;
+ case '*': tok = FTS5_STAR; break;
+ case '\0': tok = FTS5_EOF; break;
+
+ case '"': {
+ const char *z2;
+ tok = FTS5_STRING;
+
+ for(z2=&z[1]; 1; z2++){
+ if( z2[0]=='"' ){
+ z2++;
+ if( z2[0]!='"' ) break;
+ }
+ if( z2[0]=='\0' ){
+ sqlite3Fts5ParseError(pParse, "unterminated string");
+ return FTS5_EOF;
+ }
+ }
+ pToken->n = (z2 - z);
+ break;
+ }
+
+ default: {
+ const char *z2;
+ if( sqlite3Fts5IsBareword(z[0])==0 ){
+ sqlite3Fts5ParseError(pParse, "fts5: syntax error near \"%.1s\"", z);
+ return FTS5_EOF;
+ }
+ tok = FTS5_STRING;
+ for(z2=&z[1]; sqlite3Fts5IsBareword(*z2); z2++);
+ pToken->n = (z2 - z);
+ if( pToken->n==2 && memcmp(pToken->p, "OR", 2)==0 ) tok = FTS5_OR;
+ if( pToken->n==3 && memcmp(pToken->p, "NOT", 3)==0 ) tok = FTS5_NOT;
+ if( pToken->n==3 && memcmp(pToken->p, "AND", 3)==0 ) tok = FTS5_AND;
+ break;
+ }
+ }
+
+ *pz = &pToken->p[pToken->n];
+ return tok;
+}
+
+static void *fts5ParseAlloc(u64 t){ return sqlite3_malloc((int)t); }
+static void fts5ParseFree(void *p){ sqlite3_free(p); }
+
+static int sqlite3Fts5ExprNew(
+ Fts5Config *pConfig, /* FTS5 Configuration */
+ const char *zExpr, /* Expression text */
+ Fts5Expr **ppNew,
+ char **pzErr
+){
+ Fts5Parse sParse;
+ Fts5Token token;
+ const char *z = zExpr;
+ int t; /* Next token type */
+ void *pEngine;
+ Fts5Expr *pNew;
+
+ *ppNew = 0;
+ *pzErr = 0;
+ memset(&sParse, 0, sizeof(sParse));
+ pEngine = sqlite3Fts5ParserAlloc(fts5ParseAlloc);
+ if( pEngine==0 ){ return SQLITE_NOMEM; }
+ sParse.pConfig = pConfig;
+
+ do {
+ t = fts5ExprGetToken(&sParse, &z, &token);
+ sqlite3Fts5Parser(pEngine, t, token, &sParse);
+ }while( sParse.rc==SQLITE_OK && t!=FTS5_EOF );
+ sqlite3Fts5ParserFree(pEngine, fts5ParseFree);
+
+ assert( sParse.rc!=SQLITE_OK || sParse.zErr==0 );
+ if( sParse.rc==SQLITE_OK ){
+ *ppNew = pNew = sqlite3_malloc(sizeof(Fts5Expr));
+ if( pNew==0 ){
+ sParse.rc = SQLITE_NOMEM;
+ sqlite3Fts5ParseNodeFree(sParse.pExpr);
+ }else{
+ pNew->pRoot = sParse.pExpr;
+ pNew->pIndex = 0;
+ pNew->apExprPhrase = sParse.apPhrase;
+ pNew->nPhrase = sParse.nPhrase;
+ sParse.apPhrase = 0;
+ }
+ }
+
+ sqlite3_free(sParse.apPhrase);
+ *pzErr = sParse.zErr;
+ return sParse.rc;
+}
+
+/*
+** Free the expression node object passed as the only argument.
+*/
+static void sqlite3Fts5ParseNodeFree(Fts5ExprNode *p){
+ if( p ){
+ int i;
+ for(i=0; i<p->nChild; i++){
+ sqlite3Fts5ParseNodeFree(p->apChild[i]);
+ }
+ sqlite3Fts5ParseNearsetFree(p->pNear);
+ sqlite3_free(p);
+ }
+}
+
+/*
+** Free the expression object passed as the only argument.
+*/
+static void sqlite3Fts5ExprFree(Fts5Expr *p){
+ if( p ){
+ sqlite3Fts5ParseNodeFree(p->pRoot);
+ sqlite3_free(p->apExprPhrase);
+ sqlite3_free(p);
+ }
+}
+
+/*
+** Argument pTerm must be a synonym iterator. Return the current rowid
+** that it points to.
+*/
+static i64 fts5ExprSynonymRowid(Fts5ExprTerm *pTerm, int bDesc, int *pbEof){
+ i64 iRet = 0;
+ int bRetValid = 0;
+ Fts5ExprTerm *p;
+
+ assert( pTerm->pSynonym );
+ assert( bDesc==0 || bDesc==1 );
+ for(p=pTerm; p; p=p->pSynonym){
+ if( 0==sqlite3Fts5IterEof(p->pIter) ){
+ i64 iRowid = sqlite3Fts5IterRowid(p->pIter);
+ if( bRetValid==0 || (bDesc!=(iRowid<iRet)) ){
+ iRet = iRowid;
+ bRetValid = 1;
+ }
+ }
+ }
+
+ if( pbEof && bRetValid==0 ) *pbEof = 1;
+ return iRet;
+}
+
+/*
+** Argument pTerm must be a synonym iterator.
+*/
+static int fts5ExprSynonymPoslist(
+ Fts5ExprTerm *pTerm,
+ Fts5Colset *pColset,
+ i64 iRowid,
+ int *pbDel, /* OUT: Caller should sqlite3_free(*pa) */
+ u8 **pa, int *pn
+){
+ Fts5PoslistReader aStatic[4];
+ Fts5PoslistReader *aIter = aStatic;
+ int nIter = 0;
+ int nAlloc = 4;
+ int rc = SQLITE_OK;
+ Fts5ExprTerm *p;
+
+ assert( pTerm->pSynonym );
+ for(p=pTerm; p; p=p->pSynonym){
+ Fts5IndexIter *pIter = p->pIter;
+ if( sqlite3Fts5IterEof(pIter)==0 && sqlite3Fts5IterRowid(pIter)==iRowid ){
+ const u8 *a;
+ int n;
+ i64 dummy;
+ rc = sqlite3Fts5IterPoslist(pIter, pColset, &a, &n, &dummy);
+ if( rc!=SQLITE_OK ) goto synonym_poslist_out;
+ if( nIter==nAlloc ){
+ int nByte = sizeof(Fts5PoslistReader) * nAlloc * 2;
+ Fts5PoslistReader *aNew = (Fts5PoslistReader*)sqlite3_malloc(nByte);
+ if( aNew==0 ){
+ rc = SQLITE_NOMEM;
+ goto synonym_poslist_out;
+ }
+ memcpy(aNew, aIter, sizeof(Fts5PoslistReader) * nIter);
+ nAlloc = nAlloc*2;
+ if( aIter!=aStatic ) sqlite3_free(aIter);
+ aIter = aNew;
+ }
+ sqlite3Fts5PoslistReaderInit(a, n, &aIter[nIter]);
+ assert( aIter[nIter].bEof==0 );
+ nIter++;
+ }
+ }
+
+ assert( *pbDel==0 );
+ if( nIter==1 ){
+ *pa = (u8*)aIter[0].a;
+ *pn = aIter[0].n;
+ }else{
+ Fts5PoslistWriter writer = {0};
+ Fts5Buffer buf = {0,0,0};
+ i64 iPrev = -1;
+ while( 1 ){
+ int i;
+ i64 iMin = FTS5_LARGEST_INT64;
+ for(i=0; i<nIter; i++){
+ if( aIter[i].bEof==0 ){
+ if( aIter[i].iPos==iPrev ){
+ if( sqlite3Fts5PoslistReaderNext(&aIter[i]) ) continue;
+ }
+ if( aIter[i].iPos<iMin ){
+ iMin = aIter[i].iPos;
+ }
+ }
+ }
+ if( iMin==FTS5_LARGEST_INT64 || rc!=SQLITE_OK ) break;
+ rc = sqlite3Fts5PoslistWriterAppend(&buf, &writer, iMin);
+ iPrev = iMin;
+ }
+ if( rc ){
+ sqlite3_free(buf.p);
+ }else{
+ *pa = buf.p;
+ *pn = buf.n;
+ *pbDel = 1;
+ }
+ }
+
+ synonym_poslist_out:
+ if( aIter!=aStatic ) sqlite3_free(aIter);
+ return rc;
+}
+
+
+/*
+** All individual term iterators in pPhrase are guaranteed to be valid and
+** pointing to the same rowid when this function is called. This function
+** checks if the current rowid really is a match, and if so populates
+** the pPhrase->poslist buffer accordingly. Output parameter *pbMatch
+** is set to true if this is really a match, or false otherwise.
+**
+** SQLITE_OK is returned if an error occurs, or an SQLite error code
+** otherwise. It is not considered an error code if the current rowid is
+** not a match.
+*/
+static int fts5ExprPhraseIsMatch(
+ Fts5ExprNode *pNode, /* Node pPhrase belongs to */
+ Fts5Colset *pColset, /* Restrict matches to these columns */
+ Fts5ExprPhrase *pPhrase, /* Phrase object to initialize */
+ int *pbMatch /* OUT: Set to true if really a match */
+){
+ Fts5PoslistWriter writer = {0};
+ Fts5PoslistReader aStatic[4];
+ Fts5PoslistReader *aIter = aStatic;
+ int i;
+ int rc = SQLITE_OK;
+
+ fts5BufferZero(&pPhrase->poslist);
+
+ /* If the aStatic[] array is not large enough, allocate a large array
+ ** using sqlite3_malloc(). This approach could be improved upon. */
+ if( pPhrase->nTerm>(int)ArraySize(aStatic) ){
+ int nByte = sizeof(Fts5PoslistReader) * pPhrase->nTerm;
+ aIter = (Fts5PoslistReader*)sqlite3_malloc(nByte);
+ if( !aIter ) return SQLITE_NOMEM;
+ }
+ memset(aIter, 0, sizeof(Fts5PoslistReader) * pPhrase->nTerm);
+
+ /* Initialize a term iterator for each term in the phrase */
+ for(i=0; i<pPhrase->nTerm; i++){
+ Fts5ExprTerm *pTerm = &pPhrase->aTerm[i];
+ i64 dummy;
+ int n = 0;
+ int bFlag = 0;
+ const u8 *a = 0;
+ if( pTerm->pSynonym ){
+ rc = fts5ExprSynonymPoslist(
+ pTerm, pColset, pNode->iRowid, &bFlag, (u8**)&a, &n
+ );
+ }else{
+ rc = sqlite3Fts5IterPoslist(pTerm->pIter, pColset, &a, &n, &dummy);
+ }
+ if( rc!=SQLITE_OK ) goto ismatch_out;
+ sqlite3Fts5PoslistReaderInit(a, n, &aIter[i]);
+ aIter[i].bFlag = (u8)bFlag;
+ if( aIter[i].bEof ) goto ismatch_out;
+ }
+
+ while( 1 ){
+ int bMatch;
+ i64 iPos = aIter[0].iPos;
+ do {
+ bMatch = 1;
+ for(i=0; i<pPhrase->nTerm; i++){
+ Fts5PoslistReader *pPos = &aIter[i];
+ i64 iAdj = iPos + i;
+ if( pPos->iPos!=iAdj ){
+ bMatch = 0;
+ while( pPos->iPos<iAdj ){
+ if( sqlite3Fts5PoslistReaderNext(pPos) ) goto ismatch_out;
+ }
+ if( pPos->iPos>iAdj ) iPos = pPos->iPos-i;
+ }
+ }
+ }while( bMatch==0 );
+
+ /* Append position iPos to the output */
+ rc = sqlite3Fts5PoslistWriterAppend(&pPhrase->poslist, &writer, iPos);
+ if( rc!=SQLITE_OK ) goto ismatch_out;
+
+ for(i=0; i<pPhrase->nTerm; i++){
+ if( sqlite3Fts5PoslistReaderNext(&aIter[i]) ) goto ismatch_out;
+ }
+ }
+
+ ismatch_out:
+ *pbMatch = (pPhrase->poslist.n>0);
+ for(i=0; i<pPhrase->nTerm; i++){
+ if( aIter[i].bFlag ) sqlite3_free((u8*)aIter[i].a);
+ }
+ if( aIter!=aStatic ) sqlite3_free(aIter);
+ return rc;
+}
+
+typedef struct Fts5LookaheadReader Fts5LookaheadReader;
+struct Fts5LookaheadReader {
+ const u8 *a; /* Buffer containing position list */
+ int n; /* Size of buffer a[] in bytes */
+ int i; /* Current offset in position list */
+ i64 iPos; /* Current position */
+ i64 iLookahead; /* Next position */
+};
+
+#define FTS5_LOOKAHEAD_EOF (((i64)1) << 62)
+
+static int fts5LookaheadReaderNext(Fts5LookaheadReader *p){
+ p->iPos = p->iLookahead;
+ if( sqlite3Fts5PoslistNext64(p->a, p->n, &p->i, &p->iLookahead) ){
+ p->iLookahead = FTS5_LOOKAHEAD_EOF;
+ }
+ return (p->iPos==FTS5_LOOKAHEAD_EOF);
+}
+
+static int fts5LookaheadReaderInit(
+ const u8 *a, int n, /* Buffer to read position list from */
+ Fts5LookaheadReader *p /* Iterator object to initialize */
+){
+ memset(p, 0, sizeof(Fts5LookaheadReader));
+ p->a = a;
+ p->n = n;
+ fts5LookaheadReaderNext(p);
+ return fts5LookaheadReaderNext(p);
+}
+
+#if 0
+static int fts5LookaheadReaderEof(Fts5LookaheadReader *p){
+ return (p->iPos==FTS5_LOOKAHEAD_EOF);
+}
+#endif
+
+typedef struct Fts5NearTrimmer Fts5NearTrimmer;
+struct Fts5NearTrimmer {
+ Fts5LookaheadReader reader; /* Input iterator */
+ Fts5PoslistWriter writer; /* Writer context */
+ Fts5Buffer *pOut; /* Output poslist */
+};
+
+/*
+** The near-set object passed as the first argument contains more than
+** one phrase. All phrases currently point to the same row. The
+** Fts5ExprPhrase.poslist buffers are populated accordingly. This function
+** tests if the current row contains instances of each phrase sufficiently
+** close together to meet the NEAR constraint. Non-zero is returned if it
+** does, or zero otherwise.
+**
+** If in/out parameter (*pRc) is set to other than SQLITE_OK when this
+** function is called, it is a no-op. Or, if an error (e.g. SQLITE_NOMEM)
+** occurs within this function (*pRc) is set accordingly before returning.
+** The return value is undefined in both these cases.
+**
+** If no error occurs and non-zero (a match) is returned, the position-list
+** of each phrase object is edited to contain only those entries that
+** meet the constraint before returning.
+*/
+static int fts5ExprNearIsMatch(int *pRc, Fts5ExprNearset *pNear){
+ Fts5NearTrimmer aStatic[4];
+ Fts5NearTrimmer *a = aStatic;
+ Fts5ExprPhrase **apPhrase = pNear->apPhrase;
+
+ int i;
+ int rc = *pRc;
+ int bMatch;
+
+ assert( pNear->nPhrase>1 );
+
+ /* If the aStatic[] array is not large enough, allocate a large array
+ ** using sqlite3_malloc(). This approach could be improved upon. */
+ if( pNear->nPhrase>(int)ArraySize(aStatic) ){
+ int nByte = sizeof(Fts5NearTrimmer) * pNear->nPhrase;
+ a = (Fts5NearTrimmer*)sqlite3Fts5MallocZero(&rc, nByte);
+ }else{
+ memset(aStatic, 0, sizeof(aStatic));
+ }
+ if( rc!=SQLITE_OK ){
+ *pRc = rc;
+ return 0;
+ }
+
+ /* Initialize a lookahead iterator for each phrase. After passing the
+ ** buffer and buffer size to the lookaside-reader init function, zero
+ ** the phrase poslist buffer. The new poslist for the phrase (containing
+ ** the same entries as the original with some entries removed on account
+ ** of the NEAR constraint) is written over the original even as it is
+ ** being read. This is safe as the entries for the new poslist are a
+ ** subset of the old, so it is not possible for data yet to be read to
+ ** be overwritten. */
+ for(i=0; i<pNear->nPhrase; i++){
+ Fts5Buffer *pPoslist = &apPhrase[i]->poslist;
+ fts5LookaheadReaderInit(pPoslist->p, pPoslist->n, &a[i].reader);
+ pPoslist->n = 0;
+ a[i].pOut = pPoslist;
+ }
+
+ while( 1 ){
+ int iAdv;
+ i64 iMin;
+ i64 iMax;
+
+ /* This block advances the phrase iterators until they point to a set of
+ ** entries that together comprise a match. */
+ iMax = a[0].reader.iPos;
+ do {
+ bMatch = 1;
+ for(i=0; i<pNear->nPhrase; i++){
+ Fts5LookaheadReader *pPos = &a[i].reader;
+ iMin = iMax - pNear->apPhrase[i]->nTerm - pNear->nNear;
+ if( pPos->iPos<iMin || pPos->iPos>iMax ){
+ bMatch = 0;
+ while( pPos->iPos<iMin ){
+ if( fts5LookaheadReaderNext(pPos) ) goto ismatch_out;
+ }
+ if( pPos->iPos>iMax ) iMax = pPos->iPos;
+ }
+ }
+ }while( bMatch==0 );
+
+ /* Add an entry to each output position list */
+ for(i=0; i<pNear->nPhrase; i++){
+ i64 iPos = a[i].reader.iPos;
+ Fts5PoslistWriter *pWriter = &a[i].writer;
+ if( a[i].pOut->n==0 || iPos!=pWriter->iPrev ){
+ sqlite3Fts5PoslistWriterAppend(a[i].pOut, pWriter, iPos);
+ }
+ }
+
+ iAdv = 0;
+ iMin = a[0].reader.iLookahead;
+ for(i=0; i<pNear->nPhrase; i++){
+ if( a[i].reader.iLookahead < iMin ){
+ iMin = a[i].reader.iLookahead;
+ iAdv = i;
+ }
+ }
+ if( fts5LookaheadReaderNext(&a[iAdv].reader) ) goto ismatch_out;
+ }
+
+ ismatch_out: {
+ int bRet = a[0].pOut->n>0;
+ *pRc = rc;
+ if( a!=aStatic ) sqlite3_free(a);
+ return bRet;
+ }
+}
+
+/*
+** Advance the first term iterator in the first phrase of pNear. Set output
+** variable *pbEof to true if it reaches EOF or if an error occurs.
+**
+** Return SQLITE_OK if successful, or an SQLite error code if an error
+** occurs.
+*/
+static int fts5ExprNearAdvanceFirst(
+ Fts5Expr *pExpr, /* Expression pPhrase belongs to */
+ Fts5ExprNode *pNode, /* FTS5_STRING or FTS5_TERM node */
+ int bFromValid,
+ i64 iFrom
+){
+ Fts5ExprTerm *pTerm = &pNode->pNear->apPhrase[0]->aTerm[0];
+ int rc = SQLITE_OK;
+
+ if( pTerm->pSynonym ){
+ int bEof = 1;
+ Fts5ExprTerm *p;
+
+ /* Find the firstest rowid any synonym points to. */
+ i64 iRowid = fts5ExprSynonymRowid(pTerm, pExpr->bDesc, 0);
+
+ /* Advance each iterator that currently points to iRowid. Or, if iFrom
+ ** is valid - each iterator that points to a rowid before iFrom. */
+ for(p=pTerm; p; p=p->pSynonym){
+ if( sqlite3Fts5IterEof(p->pIter)==0 ){
+ i64 ii = sqlite3Fts5IterRowid(p->pIter);
+ if( ii==iRowid
+ || (bFromValid && ii!=iFrom && (ii>iFrom)==pExpr->bDesc)
+ ){
+ if( bFromValid ){
+ rc = sqlite3Fts5IterNextFrom(p->pIter, iFrom);
+ }else{
+ rc = sqlite3Fts5IterNext(p->pIter);
+ }
+ if( rc!=SQLITE_OK ) break;
+ if( sqlite3Fts5IterEof(p->pIter)==0 ){
+ bEof = 0;
+ }
+ }else{
+ bEof = 0;
+ }
+ }
+ }
+
+ /* Set the EOF flag if either all synonym iterators are at EOF or an
+ ** error has occurred. */
+ pNode->bEof = (rc || bEof);
+ }else{
+ Fts5IndexIter *pIter = pTerm->pIter;
+
+ assert( Fts5NodeIsString(pNode) );
+ if( bFromValid ){
+ rc = sqlite3Fts5IterNextFrom(pIter, iFrom);
+ }else{
+ rc = sqlite3Fts5IterNext(pIter);
+ }
+
+ pNode->bEof = (rc || sqlite3Fts5IterEof(pIter));
+ }
+
+ return rc;
+}
+
+/*
+** Advance iterator pIter until it points to a value equal to or laster
+** than the initial value of *piLast. If this means the iterator points
+** to a value laster than *piLast, update *piLast to the new lastest value.
+**
+** If the iterator reaches EOF, set *pbEof to true before returning. If
+** an error occurs, set *pRc to an error code. If either *pbEof or *pRc
+** are set, return a non-zero value. Otherwise, return zero.
+*/
+static int fts5ExprAdvanceto(
+ Fts5IndexIter *pIter, /* Iterator to advance */
+ int bDesc, /* True if iterator is "rowid DESC" */
+ i64 *piLast, /* IN/OUT: Lastest rowid seen so far */
+ int *pRc, /* OUT: Error code */
+ int *pbEof /* OUT: Set to true if EOF */
+){
+ i64 iLast = *piLast;
+ i64 iRowid;
+
+ iRowid = sqlite3Fts5IterRowid(pIter);
+ if( (bDesc==0 && iLast>iRowid) || (bDesc && iLast<iRowid) ){
+ int rc = sqlite3Fts5IterNextFrom(pIter, iLast);
+ if( rc || sqlite3Fts5IterEof(pIter) ){
+ *pRc = rc;
+ *pbEof = 1;
+ return 1;
+ }
+ iRowid = sqlite3Fts5IterRowid(pIter);
+ assert( (bDesc==0 && iRowid>=iLast) || (bDesc==1 && iRowid<=iLast) );
+ }
+ *piLast = iRowid;
+
+ return 0;
+}
+
+static int fts5ExprSynonymAdvanceto(
+ Fts5ExprTerm *pTerm, /* Term iterator to advance */
+ int bDesc, /* True if iterator is "rowid DESC" */
+ i64 *piLast, /* IN/OUT: Lastest rowid seen so far */
+ int *pRc /* OUT: Error code */
+){
+ int rc = SQLITE_OK;
+ i64 iLast = *piLast;
+ Fts5ExprTerm *p;
+ int bEof = 0;
+
+ for(p=pTerm; rc==SQLITE_OK && p; p=p->pSynonym){
+ if( sqlite3Fts5IterEof(p->pIter)==0 ){
+ i64 iRowid = sqlite3Fts5IterRowid(p->pIter);
+ if( (bDesc==0 && iLast>iRowid) || (bDesc && iLast<iRowid) ){
+ rc = sqlite3Fts5IterNextFrom(p->pIter, iLast);
+ }
+ }
+ }
+
+ if( rc!=SQLITE_OK ){
+ *pRc = rc;
+ bEof = 1;
+ }else{
+ *piLast = fts5ExprSynonymRowid(pTerm, bDesc, &bEof);
+ }
+ return bEof;
+}
+
+
+static int fts5ExprNearTest(
+ int *pRc,
+ Fts5Expr *pExpr, /* Expression that pNear is a part of */
+ Fts5ExprNode *pNode /* The "NEAR" node (FTS5_STRING) */
+){
+ Fts5ExprNearset *pNear = pNode->pNear;
+ int rc = *pRc;
+ int i;
+
+ /* Check that each phrase in the nearset matches the current row.
+ ** Populate the pPhrase->poslist buffers at the same time. If any
+ ** phrase is not a match, break out of the loop early. */
+ for(i=0; rc==SQLITE_OK && i<pNear->nPhrase; i++){
+ Fts5ExprPhrase *pPhrase = pNear->apPhrase[i];
+ if( pPhrase->nTerm>1 || pPhrase->aTerm[0].pSynonym || pNear->pColset ){
+ int bMatch = 0;
+ rc = fts5ExprPhraseIsMatch(pNode, pNear->pColset, pPhrase, &bMatch);
+ if( bMatch==0 ) break;
+ }else{
+ rc = sqlite3Fts5IterPoslistBuffer(
+ pPhrase->aTerm[0].pIter, &pPhrase->poslist
+ );
+ }
+ }
+
+ *pRc = rc;
+ if( i==pNear->nPhrase && (i==1 || fts5ExprNearIsMatch(pRc, pNear)) ){
+ return 1;
+ }
+
+ return 0;
+}
+
+static int fts5ExprTokenTest(
+ Fts5Expr *pExpr, /* Expression that pNear is a part of */
+ Fts5ExprNode *pNode /* The "NEAR" node (FTS5_TERM) */
+){
+ /* As this "NEAR" object is actually a single phrase that consists
+ ** of a single term only, grab pointers into the poslist managed by the
+ ** fts5_index.c iterator object. This is much faster than synthesizing
+ ** a new poslist the way we have to for more complicated phrase or NEAR
+ ** expressions. */
+ Fts5ExprNearset *pNear = pNode->pNear;
+ Fts5ExprPhrase *pPhrase = pNear->apPhrase[0];
+ Fts5IndexIter *pIter = pPhrase->aTerm[0].pIter;
+ Fts5Colset *pColset = pNear->pColset;
+ int rc;
+
+ assert( pNode->eType==FTS5_TERM );
+ assert( pNear->nPhrase==1 && pPhrase->nTerm==1 );
+ assert( pPhrase->aTerm[0].pSynonym==0 );
+
+ rc = sqlite3Fts5IterPoslist(pIter, pColset,
+ (const u8**)&pPhrase->poslist.p, &pPhrase->poslist.n, &pNode->iRowid
+ );
+ pNode->bNomatch = (pPhrase->poslist.n==0);
+ return rc;
+}
+
+/*
+** All individual term iterators in pNear are guaranteed to be valid when
+** this function is called. This function checks if all term iterators
+** point to the same rowid, and if not, advances them until they do.
+** If an EOF is reached before this happens, *pbEof is set to true before
+** returning.
+**
+** SQLITE_OK is returned if an error occurs, or an SQLite error code
+** otherwise. It is not considered an error code if an iterator reaches
+** EOF.
+*/
+static int fts5ExprNearNextMatch(
+ Fts5Expr *pExpr, /* Expression pPhrase belongs to */
+ Fts5ExprNode *pNode
+){
+ Fts5ExprNearset *pNear = pNode->pNear;
+ Fts5ExprPhrase *pLeft = pNear->apPhrase[0];
+ int rc = SQLITE_OK;
+ i64 iLast; /* Lastest rowid any iterator points to */
+ int i, j; /* Phrase and token index, respectively */
+ int bMatch; /* True if all terms are at the same rowid */
+ const int bDesc = pExpr->bDesc;
+
+ /* Check that this node should not be FTS5_TERM */
+ assert( pNear->nPhrase>1
+ || pNear->apPhrase[0]->nTerm>1
+ || pNear->apPhrase[0]->aTerm[0].pSynonym
+ );
+
+ /* Initialize iLast, the "lastest" rowid any iterator points to. If the
+ ** iterator skips through rowids in the default ascending order, this means
+ ** the maximum rowid. Or, if the iterator is "ORDER BY rowid DESC", then it
+ ** means the minimum rowid. */
+ if( pLeft->aTerm[0].pSynonym ){
+ iLast = fts5ExprSynonymRowid(&pLeft->aTerm[0], bDesc, 0);
+ }else{
+ iLast = sqlite3Fts5IterRowid(pLeft->aTerm[0].pIter);
+ }
+
+ do {
+ bMatch = 1;
+ for(i=0; i<pNear->nPhrase; i++){
+ Fts5ExprPhrase *pPhrase = pNear->apPhrase[i];
+ for(j=0; j<pPhrase->nTerm; j++){
+ Fts5ExprTerm *pTerm = &pPhrase->aTerm[j];
+ if( pTerm->pSynonym ){
+ i64 iRowid = fts5ExprSynonymRowid(pTerm, bDesc, 0);
+ if( iRowid==iLast ) continue;
+ bMatch = 0;
+ if( fts5ExprSynonymAdvanceto(pTerm, bDesc, &iLast, &rc) ){
+ pNode->bEof = 1;
+ return rc;
+ }
+ }else{
+ Fts5IndexIter *pIter = pPhrase->aTerm[j].pIter;
+ i64 iRowid = sqlite3Fts5IterRowid(pIter);
+ if( iRowid==iLast ) continue;
+ bMatch = 0;
+ if( fts5ExprAdvanceto(pIter, bDesc, &iLast, &rc, &pNode->bEof) ){
+ return rc;
+ }
+ }
+ }
+ }
+ }while( bMatch==0 );
+
+ pNode->iRowid = iLast;
+ pNode->bNomatch = (0==fts5ExprNearTest(&rc, pExpr, pNode));
+
+ return rc;
+}
+
+/*
+** Initialize all term iterators in the pNear object. If any term is found
+** to match no documents at all, return immediately without initializing any
+** further iterators.
+*/
+static int fts5ExprNearInitAll(
+ Fts5Expr *pExpr,
+ Fts5ExprNode *pNode
+){
+ Fts5ExprNearset *pNear = pNode->pNear;
+ int i, j;
+ int rc = SQLITE_OK;
+
+ for(i=0; rc==SQLITE_OK && i<pNear->nPhrase; i++){
+ Fts5ExprPhrase *pPhrase = pNear->apPhrase[i];
+ for(j=0; j<pPhrase->nTerm; j++){
+ Fts5ExprTerm *pTerm = &pPhrase->aTerm[j];
+ Fts5ExprTerm *p;
+ int bEof = 1;
+
+ for(p=pTerm; p && rc==SQLITE_OK; p=p->pSynonym){
+ if( p->pIter ){
+ sqlite3Fts5IterClose(p->pIter);
+ p->pIter = 0;
+ }
+ rc = sqlite3Fts5IndexQuery(
+ pExpr->pIndex, p->zTerm, (int)strlen(p->zTerm),
+ (pTerm->bPrefix ? FTS5INDEX_QUERY_PREFIX : 0) |
+ (pExpr->bDesc ? FTS5INDEX_QUERY_DESC : 0),
+ pNear->pColset,
+ &p->pIter
+ );
+ assert( rc==SQLITE_OK || p->pIter==0 );
+ if( p->pIter && 0==sqlite3Fts5IterEof(p->pIter) ){
+ bEof = 0;
+ }
+ }
+
+ if( bEof ){
+ pNode->bEof = 1;
+ return rc;
+ }
+ }
+ }
+
+ return rc;
+}
+
+/* fts5ExprNodeNext() calls fts5ExprNodeNextMatch(). And vice-versa. */
+static int fts5ExprNodeNextMatch(Fts5Expr*, Fts5ExprNode*);
+
+
+/*
+** If pExpr is an ASC iterator, this function returns a value with the
+** same sign as:
+**
+** (iLhs - iRhs)
+**
+** Otherwise, if this is a DESC iterator, the opposite is returned:
+**
+** (iRhs - iLhs)
+*/
+static int fts5RowidCmp(
+ Fts5Expr *pExpr,
+ i64 iLhs,
+ i64 iRhs
+){
+ assert( pExpr->bDesc==0 || pExpr->bDesc==1 );
+ if( pExpr->bDesc==0 ){
+ if( iLhs<iRhs ) return -1;
+ return (iLhs > iRhs);
+ }else{
+ if( iLhs>iRhs ) return -1;
+ return (iLhs < iRhs);
+ }
+}
+
+static void fts5ExprSetEof(Fts5ExprNode *pNode){
+ int i;
+ pNode->bEof = 1;
+ for(i=0; i<pNode->nChild; i++){
+ fts5ExprSetEof(pNode->apChild[i]);
+ }
+}
+
+static void fts5ExprNodeZeroPoslist(Fts5ExprNode *pNode){
+ if( pNode->eType==FTS5_STRING || pNode->eType==FTS5_TERM ){
+ Fts5ExprNearset *pNear = pNode->pNear;
+ int i;
+ for(i=0; i<pNear->nPhrase; i++){
+ Fts5ExprPhrase *pPhrase = pNear->apPhrase[i];
+ pPhrase->poslist.n = 0;
+ }
+ }else{
+ int i;
+ for(i=0; i<pNode->nChild; i++){
+ fts5ExprNodeZeroPoslist(pNode->apChild[i]);
+ }
+ }
+}
+
+
+static int fts5ExprNodeNext(Fts5Expr*, Fts5ExprNode*, int, i64);
+
+/*
+** Argument pNode is an FTS5_AND node.
+*/
+static int fts5ExprAndNextRowid(
+ Fts5Expr *pExpr, /* Expression pPhrase belongs to */
+ Fts5ExprNode *pAnd /* FTS5_AND node to advance */
+){
+ int iChild;
+ i64 iLast = pAnd->iRowid;
+ int rc = SQLITE_OK;
+ int bMatch;
+
+ assert( pAnd->bEof==0 );
+ do {
+ pAnd->bNomatch = 0;
+ bMatch = 1;
+ for(iChild=0; iChild<pAnd->nChild; iChild++){
+ Fts5ExprNode *pChild = pAnd->apChild[iChild];
+ if( 0 && pChild->eType==FTS5_STRING ){
+ /* TODO */
+ }else{
+ int cmp = fts5RowidCmp(pExpr, iLast, pChild->iRowid);
+ if( cmp>0 ){
+ /* Advance pChild until it points to iLast or laster */
+ rc = fts5ExprNodeNext(pExpr, pChild, 1, iLast);
+ if( rc!=SQLITE_OK ) return rc;
+ }
+ }
+
+ /* If the child node is now at EOF, so is the parent AND node. Otherwise,
+ ** the child node is guaranteed to have advanced at least as far as
+ ** rowid iLast. So if it is not at exactly iLast, pChild->iRowid is the
+ ** new lastest rowid seen so far. */
+ assert( pChild->bEof || fts5RowidCmp(pExpr, iLast, pChild->iRowid)<=0 );
+ if( pChild->bEof ){
+ fts5ExprSetEof(pAnd);
+ bMatch = 1;
+ break;
+ }else if( iLast!=pChild->iRowid ){
+ bMatch = 0;
+ iLast = pChild->iRowid;
+ }
+
+ if( pChild->bNomatch ){
+ pAnd->bNomatch = 1;
+ }
+ }
+ }while( bMatch==0 );
+
+ if( pAnd->bNomatch && pAnd!=pExpr->pRoot ){
+ fts5ExprNodeZeroPoslist(pAnd);
+ }
+ pAnd->iRowid = iLast;
+ return SQLITE_OK;
+}
+
+
+/*
+** Compare the values currently indicated by the two nodes as follows:
+**
+** res = (*p1) - (*p2)
+**
+** Nodes that point to values that come later in the iteration order are
+** considered to be larger. Nodes at EOF are the largest of all.
+**
+** This means that if the iteration order is ASC, then numerically larger
+** rowids are considered larger. Or if it is the default DESC, numerically
+** smaller rowids are larger.
+*/
+static int fts5NodeCompare(
+ Fts5Expr *pExpr,
+ Fts5ExprNode *p1,
+ Fts5ExprNode *p2
+){
+ if( p2->bEof ) return -1;
+ if( p1->bEof ) return +1;
+ return fts5RowidCmp(pExpr, p1->iRowid, p2->iRowid);
+}
+
+/*
+** Advance node iterator pNode, part of expression pExpr. If argument
+** bFromValid is zero, then pNode is advanced exactly once. Or, if argument
+** bFromValid is non-zero, then pNode is advanced until it is at or past
+** rowid value iFrom. Whether "past" means "less than" or "greater than"
+** depends on whether this is an ASC or DESC iterator.
+*/
+static int fts5ExprNodeNext(
+ Fts5Expr *pExpr,
+ Fts5ExprNode *pNode,
+ int bFromValid,
+ i64 iFrom
+){
+ int rc = SQLITE_OK;
+
+ if( pNode->bEof==0 ){
+ switch( pNode->eType ){
+ case FTS5_STRING: {
+ rc = fts5ExprNearAdvanceFirst(pExpr, pNode, bFromValid, iFrom);
+ break;
+ };
+
+ case FTS5_TERM: {
+ Fts5IndexIter *pIter = pNode->pNear->apPhrase[0]->aTerm[0].pIter;
+ if( bFromValid ){
+ rc = sqlite3Fts5IterNextFrom(pIter, iFrom);
+ }else{
+ rc = sqlite3Fts5IterNext(pIter);
+ }
+ if( rc==SQLITE_OK && sqlite3Fts5IterEof(pIter)==0 ){
+ assert( rc==SQLITE_OK );
+ rc = fts5ExprTokenTest(pExpr, pNode);
+ }else{
+ pNode->bEof = 1;
+ }
+ return rc;
+ };
+
+ case FTS5_AND: {
+ Fts5ExprNode *pLeft = pNode->apChild[0];
+ rc = fts5ExprNodeNext(pExpr, pLeft, bFromValid, iFrom);
+ break;
+ }
+
+ case FTS5_OR: {
+ int i;
+ i64 iLast = pNode->iRowid;
+
+ for(i=0; rc==SQLITE_OK && i<pNode->nChild; i++){
+ Fts5ExprNode *p1 = pNode->apChild[i];
+ assert( p1->bEof || fts5RowidCmp(pExpr, p1->iRowid, iLast)>=0 );
+ if( p1->bEof==0 ){
+ if( (p1->iRowid==iLast)
+ || (bFromValid && fts5RowidCmp(pExpr, p1->iRowid, iFrom)<0)
+ ){
+ rc = fts5ExprNodeNext(pExpr, p1, bFromValid, iFrom);
+ }
+ }
+ }
+
+ break;
+ }
+
+ default: assert( pNode->eType==FTS5_NOT ); {
+ assert( pNode->nChild==2 );
+ rc = fts5ExprNodeNext(pExpr, pNode->apChild[0], bFromValid, iFrom);
+ break;
+ }
+ }
+
+ if( rc==SQLITE_OK ){
+ rc = fts5ExprNodeNextMatch(pExpr, pNode);
+ }
+ }
+
+ /* Assert that if bFromValid was true, either:
+ **
+ ** a) an error occurred, or
+ ** b) the node is now at EOF, or
+ ** c) the node is now at or past rowid iFrom.
+ */
+ assert( bFromValid==0
+ || rc!=SQLITE_OK /* a */
+ || pNode->bEof /* b */
+ || pNode->iRowid==iFrom || pExpr->bDesc==(pNode->iRowid<iFrom) /* c */
+ );
+
+ return rc;
+}
+
+
+/*
+** If pNode currently points to a match, this function returns SQLITE_OK
+** without modifying it. Otherwise, pNode is advanced until it does point
+** to a match or EOF is reached.
+*/
+static int fts5ExprNodeNextMatch(
+ Fts5Expr *pExpr, /* Expression of which pNode is a part */
+ Fts5ExprNode *pNode /* Expression node to test */
+){
+ int rc = SQLITE_OK;
+ if( pNode->bEof==0 ){
+ switch( pNode->eType ){
+
+ case FTS5_STRING: {
+ /* Advance the iterators until they all point to the same rowid */
+ rc = fts5ExprNearNextMatch(pExpr, pNode);
+ break;
+ }
+
+ case FTS5_TERM: {
+ rc = fts5ExprTokenTest(pExpr, pNode);
+ break;
+ }
+
+ case FTS5_AND: {
+ rc = fts5ExprAndNextRowid(pExpr, pNode);
+ break;
+ }
+
+ case FTS5_OR: {
+ Fts5ExprNode *pNext = pNode->apChild[0];
+ int i;
+
+ for(i=1; i<pNode->nChild; i++){
+ Fts5ExprNode *pChild = pNode->apChild[i];
+ int cmp = fts5NodeCompare(pExpr, pNext, pChild);
+ if( cmp>0 || (cmp==0 && pChild->bNomatch==0) ){
+ pNext = pChild;
+ }
+ }
+ pNode->iRowid = pNext->iRowid;
+ pNode->bEof = pNext->bEof;
+ pNode->bNomatch = pNext->bNomatch;
+ break;
+ }
+
+ default: assert( pNode->eType==FTS5_NOT ); {
+ Fts5ExprNode *p1 = pNode->apChild[0];
+ Fts5ExprNode *p2 = pNode->apChild[1];
+ assert( pNode->nChild==2 );
+
+ while( rc==SQLITE_OK && p1->bEof==0 ){
+ int cmp = fts5NodeCompare(pExpr, p1, p2);
+ if( cmp>0 ){
+ rc = fts5ExprNodeNext(pExpr, p2, 1, p1->iRowid);
+ cmp = fts5NodeCompare(pExpr, p1, p2);
+ }
+ assert( rc!=SQLITE_OK || cmp<=0 );
+ if( cmp || p2->bNomatch ) break;
+ rc = fts5ExprNodeNext(pExpr, p1, 0, 0);
+ }
+ pNode->bEof = p1->bEof;
+ pNode->iRowid = p1->iRowid;
+ break;
+ }
+ }
+ }
+ return rc;
+}
+
+
+/*
+** Set node pNode, which is part of expression pExpr, to point to the first
+** match. If there are no matches, set the Node.bEof flag to indicate EOF.
+**
+** Return an SQLite error code if an error occurs, or SQLITE_OK otherwise.
+** It is not an error if there are no matches.
+*/
+static int fts5ExprNodeFirst(Fts5Expr *pExpr, Fts5ExprNode *pNode){
+ int rc = SQLITE_OK;
+ pNode->bEof = 0;
+
+ if( Fts5NodeIsString(pNode) ){
+ /* Initialize all term iterators in the NEAR object. */
+ rc = fts5ExprNearInitAll(pExpr, pNode);
+ }else{
+ int i;
+ for(i=0; i<pNode->nChild && rc==SQLITE_OK; i++){
+ rc = fts5ExprNodeFirst(pExpr, pNode->apChild[i]);
+ }
+ pNode->iRowid = pNode->apChild[0]->iRowid;
+ }
+
+ if( rc==SQLITE_OK ){
+ rc = fts5ExprNodeNextMatch(pExpr, pNode);
+ }
+ return rc;
+}
+
+
+/*
+** Begin iterating through the set of documents in index pIdx matched by
+** the MATCH expression passed as the first argument. If the "bDesc"
+** parameter is passed a non-zero value, iteration is in descending rowid
+** order. Or, if it is zero, in ascending order.
+**
+** If iterating in ascending rowid order (bDesc==0), the first document
+** visited is that with the smallest rowid that is larger than or equal
+** to parameter iFirst. Or, if iterating in ascending order (bDesc==1),
+** then the first document visited must have a rowid smaller than or
+** equal to iFirst.
+**
+** Return SQLITE_OK if successful, or an SQLite error code otherwise. It
+** is not considered an error if the query does not match any documents.
+*/
+static int sqlite3Fts5ExprFirst(Fts5Expr *p, Fts5Index *pIdx, i64 iFirst, int bDesc){
+ Fts5ExprNode *pRoot = p->pRoot;
+ int rc = SQLITE_OK;
+ if( pRoot ){
+ p->pIndex = pIdx;
+ p->bDesc = bDesc;
+ rc = fts5ExprNodeFirst(p, pRoot);
+
+ /* If not at EOF but the current rowid occurs earlier than iFirst in
+ ** the iteration order, move to document iFirst or later. */
+ if( pRoot->bEof==0 && fts5RowidCmp(p, pRoot->iRowid, iFirst)<0 ){
+ rc = fts5ExprNodeNext(p, pRoot, 1, iFirst);
+ }
+
+ /* If the iterator is not at a real match, skip forward until it is. */
+ while( pRoot->bNomatch && rc==SQLITE_OK && pRoot->bEof==0 ){
+ rc = fts5ExprNodeNext(p, pRoot, 0, 0);
+ }
+ }
+ return rc;
+}
+
+/*
+** Move to the next document
+**
+** Return SQLITE_OK if successful, or an SQLite error code otherwise. It
+** is not considered an error if the query does not match any documents.
+*/
+static int sqlite3Fts5ExprNext(Fts5Expr *p, i64 iLast){
+ int rc;
+ Fts5ExprNode *pRoot = p->pRoot;
+ do {
+ rc = fts5ExprNodeNext(p, pRoot, 0, 0);
+ }while( pRoot->bNomatch && pRoot->bEof==0 && rc==SQLITE_OK );
+ if( fts5RowidCmp(p, pRoot->iRowid, iLast)>0 ){
+ pRoot->bEof = 1;
+ }
+ return rc;
+}
+
+static int sqlite3Fts5ExprEof(Fts5Expr *p){
+ return (p->pRoot==0 || p->pRoot->bEof);
+}
+
+static i64 sqlite3Fts5ExprRowid(Fts5Expr *p){
+ return p->pRoot->iRowid;
+}
+
+static int fts5ParseStringFromToken(Fts5Token *pToken, char **pz){
+ int rc = SQLITE_OK;
+ *pz = sqlite3Fts5Strndup(&rc, pToken->p, pToken->n);
+ return rc;
+}
+
+/*
+** Free the phrase object passed as the only argument.
+*/
+static void fts5ExprPhraseFree(Fts5ExprPhrase *pPhrase){
+ if( pPhrase ){
+ int i;
+ for(i=0; i<pPhrase->nTerm; i++){
+ Fts5ExprTerm *pSyn;
+ Fts5ExprTerm *pNext;
+ Fts5ExprTerm *pTerm = &pPhrase->aTerm[i];
+ sqlite3_free(pTerm->zTerm);
+ sqlite3Fts5IterClose(pTerm->pIter);
+
+ for(pSyn=pTerm->pSynonym; pSyn; pSyn=pNext){
+ pNext = pSyn->pSynonym;
+ sqlite3Fts5IterClose(pSyn->pIter);
+ sqlite3_free(pSyn);
+ }
+ }
+ if( pPhrase->poslist.nSpace>0 ) fts5BufferFree(&pPhrase->poslist);
+ sqlite3_free(pPhrase);
+ }
+}
+
+/*
+** If argument pNear is NULL, then a new Fts5ExprNearset object is allocated
+** and populated with pPhrase. Or, if pNear is not NULL, phrase pPhrase is
+** appended to it and the results returned.
+**
+** If an OOM error occurs, both the pNear and pPhrase objects are freed and
+** NULL returned.
+*/
+static Fts5ExprNearset *sqlite3Fts5ParseNearset(
+ Fts5Parse *pParse, /* Parse context */
+ Fts5ExprNearset *pNear, /* Existing nearset, or NULL */
+ Fts5ExprPhrase *pPhrase /* Recently parsed phrase */
+){
+ const int SZALLOC = 8;
+ Fts5ExprNearset *pRet = 0;
+
+ if( pParse->rc==SQLITE_OK ){
+ if( pPhrase==0 ){
+ return pNear;
+ }
+ if( pNear==0 ){
+ int nByte = sizeof(Fts5ExprNearset) + SZALLOC * sizeof(Fts5ExprPhrase*);
+ pRet = sqlite3_malloc(nByte);
+ if( pRet==0 ){
+ pParse->rc = SQLITE_NOMEM;
+ }else{
+ memset(pRet, 0, nByte);
+ }
+ }else if( (pNear->nPhrase % SZALLOC)==0 ){
+ int nNew = pNear->nPhrase + SZALLOC;
+ int nByte = sizeof(Fts5ExprNearset) + nNew * sizeof(Fts5ExprPhrase*);
+
+ pRet = (Fts5ExprNearset*)sqlite3_realloc(pNear, nByte);
+ if( pRet==0 ){
+ pParse->rc = SQLITE_NOMEM;
+ }
+ }else{
+ pRet = pNear;
+ }
+ }
+
+ if( pRet==0 ){
+ assert( pParse->rc!=SQLITE_OK );
+ sqlite3Fts5ParseNearsetFree(pNear);
+ sqlite3Fts5ParsePhraseFree(pPhrase);
+ }else{
+ pRet->apPhrase[pRet->nPhrase++] = pPhrase;
+ }
+ return pRet;
+}
+
+typedef struct TokenCtx TokenCtx;
+struct TokenCtx {
+ Fts5ExprPhrase *pPhrase;
+ int rc;
+};
+
+/*
+** Callback for tokenizing terms used by ParseTerm().
+*/
+static int fts5ParseTokenize(
+ void *pContext, /* Pointer to Fts5InsertCtx object */
+ int tflags, /* Mask of FTS5_TOKEN_* flags */
+ const char *pToken, /* Buffer containing token */
+ int nToken, /* Size of token in bytes */
+ int iUnused1, /* Start offset of token */
+ int iUnused2 /* End offset of token */
+){
+ int rc = SQLITE_OK;
+ const int SZALLOC = 8;
+ TokenCtx *pCtx = (TokenCtx*)pContext;
+ Fts5ExprPhrase *pPhrase = pCtx->pPhrase;
+
+ /* If an error has already occurred, this is a no-op */
+ if( pCtx->rc!=SQLITE_OK ) return pCtx->rc;
+
+ assert( pPhrase==0 || pPhrase->nTerm>0 );
+ if( pPhrase && (tflags & FTS5_TOKEN_COLOCATED) ){
+ Fts5ExprTerm *pSyn;
+ int nByte = sizeof(Fts5ExprTerm) + nToken+1;
+ pSyn = (Fts5ExprTerm*)sqlite3_malloc(nByte);
+ if( pSyn==0 ){
+ rc = SQLITE_NOMEM;
+ }else{
+ memset(pSyn, 0, nByte);
+ pSyn->zTerm = (char*)&pSyn[1];
+ memcpy(pSyn->zTerm, pToken, nToken);
+ pSyn->pSynonym = pPhrase->aTerm[pPhrase->nTerm-1].pSynonym;
+ pPhrase->aTerm[pPhrase->nTerm-1].pSynonym = pSyn;
+ }
+ }else{
+ Fts5ExprTerm *pTerm;
+ if( pPhrase==0 || (pPhrase->nTerm % SZALLOC)==0 ){
+ Fts5ExprPhrase *pNew;
+ int nNew = SZALLOC + (pPhrase ? pPhrase->nTerm : 0);
+
+ pNew = (Fts5ExprPhrase*)sqlite3_realloc(pPhrase,
+ sizeof(Fts5ExprPhrase) + sizeof(Fts5ExprTerm) * nNew
+ );
+ if( pNew==0 ){
+ rc = SQLITE_NOMEM;
+ }else{
+ if( pPhrase==0 ) memset(pNew, 0, sizeof(Fts5ExprPhrase));
+ pCtx->pPhrase = pPhrase = pNew;
+ pNew->nTerm = nNew - SZALLOC;
+ }
+ }
+
+ if( rc==SQLITE_OK ){
+ pTerm = &pPhrase->aTerm[pPhrase->nTerm++];
+ memset(pTerm, 0, sizeof(Fts5ExprTerm));
+ pTerm->zTerm = sqlite3Fts5Strndup(&rc, pToken, nToken);
+ }
+ }
+
+ pCtx->rc = rc;
+ return rc;
+}
+
+
+/*
+** Free the phrase object passed as the only argument.
+*/
+static void sqlite3Fts5ParsePhraseFree(Fts5ExprPhrase *pPhrase){
+ fts5ExprPhraseFree(pPhrase);
+}
+
+/*
+** Free the phrase object passed as the second argument.
+*/
+static void sqlite3Fts5ParseNearsetFree(Fts5ExprNearset *pNear){
+ if( pNear ){
+ int i;
+ for(i=0; i<pNear->nPhrase; i++){
+ fts5ExprPhraseFree(pNear->apPhrase[i]);
+ }
+ sqlite3_free(pNear->pColset);
+ sqlite3_free(pNear);
+ }
+}
+
+static void sqlite3Fts5ParseFinished(Fts5Parse *pParse, Fts5ExprNode *p){
+ assert( pParse->pExpr==0 );
+ pParse->pExpr = p;
+}
+
+/*
+** This function is called by the parser to process a string token. The
+** string may or may not be quoted. In any case it is tokenized and a
+** phrase object consisting of all tokens returned.
+*/
+static Fts5ExprPhrase *sqlite3Fts5ParseTerm(
+ Fts5Parse *pParse, /* Parse context */
+ Fts5ExprPhrase *pAppend, /* Phrase to append to */
+ Fts5Token *pToken, /* String to tokenize */
+ int bPrefix /* True if there is a trailing "*" */
+){
+ Fts5Config *pConfig = pParse->pConfig;
+ TokenCtx sCtx; /* Context object passed to callback */
+ int rc; /* Tokenize return code */
+ char *z = 0;
+
+ memset(&sCtx, 0, sizeof(TokenCtx));
+ sCtx.pPhrase = pAppend;
+
+ rc = fts5ParseStringFromToken(pToken, &z);
+ if( rc==SQLITE_OK ){
+ int flags = FTS5_TOKENIZE_QUERY | (bPrefix ? FTS5_TOKENIZE_QUERY : 0);
+ int n;
+ sqlite3Fts5Dequote(z);
+ n = (int)strlen(z);
+ rc = sqlite3Fts5Tokenize(pConfig, flags, z, n, &sCtx, fts5ParseTokenize);
+ }
+ sqlite3_free(z);
+ if( rc || (rc = sCtx.rc) ){
+ pParse->rc = rc;
+ fts5ExprPhraseFree(sCtx.pPhrase);
+ sCtx.pPhrase = 0;
+ }else if( sCtx.pPhrase ){
+
+ if( pAppend==0 ){
+ if( (pParse->nPhrase % 8)==0 ){
+ int nByte = sizeof(Fts5ExprPhrase*) * (pParse->nPhrase + 8);
+ Fts5ExprPhrase **apNew;
+ apNew = (Fts5ExprPhrase**)sqlite3_realloc(pParse->apPhrase, nByte);
+ if( apNew==0 ){
+ pParse->rc = SQLITE_NOMEM;
+ fts5ExprPhraseFree(sCtx.pPhrase);
+ return 0;
+ }
+ pParse->apPhrase = apNew;
+ }
+ pParse->nPhrase++;
+ }
+
+ pParse->apPhrase[pParse->nPhrase-1] = sCtx.pPhrase;
+ assert( sCtx.pPhrase->nTerm>0 );
+ sCtx.pPhrase->aTerm[sCtx.pPhrase->nTerm-1].bPrefix = bPrefix;
+ }
+
+ return sCtx.pPhrase;
+}
+
+/*
+** Create a new FTS5 expression by cloning phrase iPhrase of the
+** expression passed as the second argument.
+*/
+static int sqlite3Fts5ExprClonePhrase(
+ Fts5Config *pConfig,
+ Fts5Expr *pExpr,
+ int iPhrase,
+ Fts5Expr **ppNew
+){
+ int rc = SQLITE_OK; /* Return code */
+ Fts5ExprPhrase *pOrig; /* The phrase extracted from pExpr */
+ int i; /* Used to iterate through phrase terms */
+
+ Fts5Expr *pNew = 0; /* Expression to return via *ppNew */
+
+ TokenCtx sCtx = {0,0}; /* Context object for fts5ParseTokenize */
+
+
+ pOrig = pExpr->apExprPhrase[iPhrase];
+
+ pNew = (Fts5Expr*)sqlite3Fts5MallocZero(&rc, sizeof(Fts5Expr));
+ if( rc==SQLITE_OK ){
+ pNew->apExprPhrase = (Fts5ExprPhrase**)sqlite3Fts5MallocZero(&rc,
+ sizeof(Fts5ExprPhrase*));
+ }
+ if( rc==SQLITE_OK ){
+ pNew->pRoot = (Fts5ExprNode*)sqlite3Fts5MallocZero(&rc,
+ sizeof(Fts5ExprNode));
+ }
+ if( rc==SQLITE_OK ){
+ pNew->pRoot->pNear = (Fts5ExprNearset*)sqlite3Fts5MallocZero(&rc,
+ sizeof(Fts5ExprNearset) + sizeof(Fts5ExprPhrase*));
+ }
+
+ for(i=0; rc==SQLITE_OK && i<pOrig->nTerm; i++){
+ int tflags = 0;
+ Fts5ExprTerm *p;
+ for(p=&pOrig->aTerm[i]; p && rc==SQLITE_OK; p=p->pSynonym){
+ const char *zTerm = p->zTerm;
+ rc = fts5ParseTokenize((void*)&sCtx, tflags, zTerm, (int)strlen(zTerm),
+ 0, 0);
+ tflags = FTS5_TOKEN_COLOCATED;
+ }
+ if( rc==SQLITE_OK ){
+ sCtx.pPhrase->aTerm[i].bPrefix = pOrig->aTerm[i].bPrefix;
+ }
+ }
+
+ if( rc==SQLITE_OK ){
+ /* All the allocations succeeded. Put the expression object together. */
+ pNew->pIndex = pExpr->pIndex;
+ pNew->nPhrase = 1;
+ pNew->apExprPhrase[0] = sCtx.pPhrase;
+ pNew->pRoot->pNear->apPhrase[0] = sCtx.pPhrase;
+ pNew->pRoot->pNear->nPhrase = 1;
+ sCtx.pPhrase->pNode = pNew->pRoot;
+
+ if( pOrig->nTerm==1 && pOrig->aTerm[0].pSynonym==0 ){
+ pNew->pRoot->eType = FTS5_TERM;
+ }else{
+ pNew->pRoot->eType = FTS5_STRING;
+ }
+ }else{
+ sqlite3Fts5ExprFree(pNew);
+ fts5ExprPhraseFree(sCtx.pPhrase);
+ pNew = 0;
+ }
+
+ *ppNew = pNew;
+ return rc;
+}
+
+
+/*
+** Token pTok has appeared in a MATCH expression where the NEAR operator
+** is expected. If token pTok does not contain "NEAR", store an error
+** in the pParse object.
+*/
+static void sqlite3Fts5ParseNear(Fts5Parse *pParse, Fts5Token *pTok){
+ if( pTok->n!=4 || memcmp("NEAR", pTok->p, 4) ){
+ sqlite3Fts5ParseError(
+ pParse, "fts5: syntax error near \"%.*s\"", pTok->n, pTok->p
+ );
+ }
+}
+
+static void sqlite3Fts5ParseSetDistance(
+ Fts5Parse *pParse,
+ Fts5ExprNearset *pNear,
+ Fts5Token *p
+){
+ int nNear = 0;
+ int i;
+ if( p->n ){
+ for(i=0; i<p->n; i++){
+ char c = (char)p->p[i];
+ if( c<'0' || c>'9' ){
+ sqlite3Fts5ParseError(
+ pParse, "expected integer, got \"%.*s\"", p->n, p->p
+ );
+ return;
+ }
+ nNear = nNear * 10 + (p->p[i] - '0');
+ }
+ }else{
+ nNear = FTS5_DEFAULT_NEARDIST;
+ }
+ pNear->nNear = nNear;
+}
+
+/*
+** The second argument passed to this function may be NULL, or it may be
+** an existing Fts5Colset object. This function returns a pointer to
+** a new colset object containing the contents of (p) with new value column
+** number iCol appended.
+**
+** If an OOM error occurs, store an error code in pParse and return NULL.
+** The old colset object (if any) is not freed in this case.
+*/
+static Fts5Colset *fts5ParseColset(
+ Fts5Parse *pParse, /* Store SQLITE_NOMEM here if required */
+ Fts5Colset *p, /* Existing colset object */
+ int iCol /* New column to add to colset object */
+){
+ int nCol = p ? p->nCol : 0; /* Num. columns already in colset object */
+ Fts5Colset *pNew; /* New colset object to return */
+
+ assert( pParse->rc==SQLITE_OK );
+ assert( iCol>=0 && iCol<pParse->pConfig->nCol );
+
+ pNew = sqlite3_realloc(p, sizeof(Fts5Colset) + sizeof(int)*nCol);
+ if( pNew==0 ){
+ pParse->rc = SQLITE_NOMEM;
+ }else{
+ int *aiCol = pNew->aiCol;
+ int i, j;
+ for(i=0; i<nCol; i++){
+ if( aiCol[i]==iCol ) return pNew;
+ if( aiCol[i]>iCol ) break;
+ }
+ for(j=nCol; j>i; j--){
+ aiCol[j] = aiCol[j-1];
+ }
+ aiCol[i] = iCol;
+ pNew->nCol = nCol+1;
+
+#ifndef NDEBUG
+ /* Check that the array is in order and contains no duplicate entries. */
+ for(i=1; i<pNew->nCol; i++) assert( pNew->aiCol[i]>pNew->aiCol[i-1] );
+#endif
+ }
+
+ return pNew;
+}
+
+static Fts5Colset *sqlite3Fts5ParseColset(
+ Fts5Parse *pParse, /* Store SQLITE_NOMEM here if required */
+ Fts5Colset *pColset, /* Existing colset object */
+ Fts5Token *p
+){
+ Fts5Colset *pRet = 0;
+ int iCol;
+ char *z; /* Dequoted copy of token p */
+
+ z = sqlite3Fts5Strndup(&pParse->rc, p->p, p->n);
+ if( pParse->rc==SQLITE_OK ){
+ Fts5Config *pConfig = pParse->pConfig;
+ sqlite3Fts5Dequote(z);
+ for(iCol=0; iCol<pConfig->nCol; iCol++){
+ if( 0==sqlite3_stricmp(pConfig->azCol[iCol], z) ) break;
+ }
+ if( iCol==pConfig->nCol ){
+ sqlite3Fts5ParseError(pParse, "no such column: %s", z);
+ }else{
+ pRet = fts5ParseColset(pParse, pColset, iCol);
+ }
+ sqlite3_free(z);
+ }
+
+ if( pRet==0 ){
+ assert( pParse->rc!=SQLITE_OK );
+ sqlite3_free(pColset);
+ }
+
+ return pRet;
+}
+
+static void sqlite3Fts5ParseSetColset(
+ Fts5Parse *pParse,
+ Fts5ExprNearset *pNear,
+ Fts5Colset *pColset
+){
+ if( pNear ){
+ pNear->pColset = pColset;
+ }else{
+ sqlite3_free(pColset);
+ }
+}
+
+static void fts5ExprAddChildren(Fts5ExprNode *p, Fts5ExprNode *pSub){
+ if( p->eType!=FTS5_NOT && pSub->eType==p->eType ){
+ int nByte = sizeof(Fts5ExprNode*) * pSub->nChild;
+ memcpy(&p->apChild[p->nChild], pSub->apChild, nByte);
+ p->nChild += pSub->nChild;
+ sqlite3_free(pSub);
+ }else{
+ p->apChild[p->nChild++] = pSub;
+ }
+}
+
+/*
+** Allocate and return a new expression object. If anything goes wrong (i.e.
+** OOM error), leave an error code in pParse and return NULL.
+*/
+static Fts5ExprNode *sqlite3Fts5ParseNode(
+ Fts5Parse *pParse, /* Parse context */
+ int eType, /* FTS5_STRING, AND, OR or NOT */
+ Fts5ExprNode *pLeft, /* Left hand child expression */
+ Fts5ExprNode *pRight, /* Right hand child expression */
+ Fts5ExprNearset *pNear /* For STRING expressions, the near cluster */
+){
+ Fts5ExprNode *pRet = 0;
+
+ if( pParse->rc==SQLITE_OK ){
+ int nChild = 0; /* Number of children of returned node */
+ int nByte; /* Bytes of space to allocate for this node */
+
+ assert( (eType!=FTS5_STRING && !pNear)
+ || (eType==FTS5_STRING && !pLeft && !pRight)
+ );
+ if( eType==FTS5_STRING && pNear==0 ) return 0;
+ if( eType!=FTS5_STRING && pLeft==0 ) return pRight;
+ if( eType!=FTS5_STRING && pRight==0 ) return pLeft;
+
+ if( eType==FTS5_NOT ){
+ nChild = 2;
+ }else if( eType==FTS5_AND || eType==FTS5_OR ){
+ nChild = 2;
+ if( pLeft->eType==eType ) nChild += pLeft->nChild-1;
+ if( pRight->eType==eType ) nChild += pRight->nChild-1;
+ }
+
+ nByte = sizeof(Fts5ExprNode) + sizeof(Fts5ExprNode*)*(nChild-1);
+ pRet = (Fts5ExprNode*)sqlite3Fts5MallocZero(&pParse->rc, nByte);
+
+ if( pRet ){
+ pRet->eType = eType;
+ pRet->pNear = pNear;
+ if( eType==FTS5_STRING ){
+ int iPhrase;
+ for(iPhrase=0; iPhrase<pNear->nPhrase; iPhrase++){
+ pNear->apPhrase[iPhrase]->pNode = pRet;
+ }
+ if( pNear->nPhrase==1
+ && pNear->apPhrase[0]->nTerm==1
+ && pNear->apPhrase[0]->aTerm[0].pSynonym==0
+ ){
+ pRet->eType = FTS5_TERM;
+ }
+ }else{
+ fts5ExprAddChildren(pRet, pLeft);
+ fts5ExprAddChildren(pRet, pRight);
+ }
+ }
+ }
+
+ if( pRet==0 ){
+ assert( pParse->rc!=SQLITE_OK );
+ sqlite3Fts5ParseNodeFree(pLeft);
+ sqlite3Fts5ParseNodeFree(pRight);
+ sqlite3Fts5ParseNearsetFree(pNear);
+ }
+ return pRet;
+}
+
+static char *fts5ExprTermPrint(Fts5ExprTerm *pTerm){
+ int nByte = 0;
+ Fts5ExprTerm *p;
+ char *zQuoted;
+
+ /* Determine the maximum amount of space required. */
+ for(p=pTerm; p; p=p->pSynonym){
+ nByte += (int)strlen(pTerm->zTerm) * 2 + 3 + 2;
+ }
+ zQuoted = sqlite3_malloc(nByte);
+
+ if( zQuoted ){
+ int i = 0;
+ for(p=pTerm; p; p=p->pSynonym){
+ char *zIn = p->zTerm;
+ zQuoted[i++] = '"';
+ while( *zIn ){
+ if( *zIn=='"' ) zQuoted[i++] = '"';
+ zQuoted[i++] = *zIn++;
+ }
+ zQuoted[i++] = '"';
+ if( p->pSynonym ) zQuoted[i++] = '|';
+ }
+ if( pTerm->bPrefix ){
+ zQuoted[i++] = ' ';
+ zQuoted[i++] = '*';
+ }
+ zQuoted[i++] = '\0';
+ }
+ return zQuoted;
+}
+
+static char *fts5PrintfAppend(char *zApp, const char *zFmt, ...){
+ char *zNew;
+ va_list ap;
+ va_start(ap, zFmt);
+ zNew = sqlite3_vmprintf(zFmt, ap);
+ va_end(ap);
+ if( zApp && zNew ){
+ char *zNew2 = sqlite3_mprintf("%s%s", zApp, zNew);
+ sqlite3_free(zNew);
+ zNew = zNew2;
+ }
+ sqlite3_free(zApp);
+ return zNew;
+}
+
+/*
+** Compose a tcl-readable representation of expression pExpr. Return a
+** pointer to a buffer containing that representation. It is the
+** responsibility of the caller to at some point free the buffer using
+** sqlite3_free().
+*/
+static char *fts5ExprPrintTcl(
+ Fts5Config *pConfig,
+ const char *zNearsetCmd,
+ Fts5ExprNode *pExpr
+){
+ char *zRet = 0;
+ if( pExpr->eType==FTS5_STRING || pExpr->eType==FTS5_TERM ){
+ Fts5ExprNearset *pNear = pExpr->pNear;
+ int i;
+ int iTerm;
+
+ zRet = fts5PrintfAppend(zRet, "%s ", zNearsetCmd);
+ if( zRet==0 ) return 0;
+ if( pNear->pColset ){
+ int *aiCol = pNear->pColset->aiCol;
+ int nCol = pNear->pColset->nCol;
+ if( nCol==1 ){
+ zRet = fts5PrintfAppend(zRet, "-col %d ", aiCol[0]);
+ }else{
+ zRet = fts5PrintfAppend(zRet, "-col {%d", aiCol[0]);
+ for(i=1; i<pNear->pColset->nCol; i++){
+ zRet = fts5PrintfAppend(zRet, " %d", aiCol[i]);
+ }
+ zRet = fts5PrintfAppend(zRet, "} ");
+ }
+ if( zRet==0 ) return 0;
+ }
+
+ if( pNear->nPhrase>1 ){
+ zRet = fts5PrintfAppend(zRet, "-near %d ", pNear->nNear);
+ if( zRet==0 ) return 0;
+ }
+
+ zRet = fts5PrintfAppend(zRet, "--");
+ if( zRet==0 ) return 0;
+
+ for(i=0; i<pNear->nPhrase; i++){
+ Fts5ExprPhrase *pPhrase = pNear->apPhrase[i];
+
+ zRet = fts5PrintfAppend(zRet, " {");
+ for(iTerm=0; zRet && iTerm<pPhrase->nTerm; iTerm++){
+ char *zTerm = pPhrase->aTerm[iTerm].zTerm;
+ zRet = fts5PrintfAppend(zRet, "%s%s", iTerm==0?"":" ", zTerm);
+ }
+
+ if( zRet ) zRet = fts5PrintfAppend(zRet, "}");
+ if( zRet==0 ) return 0;
+ }
+
+ }else{
+ char const *zOp = 0;
+ int i;
+ switch( pExpr->eType ){
+ case FTS5_AND: zOp = "AND"; break;
+ case FTS5_NOT: zOp = "NOT"; break;
+ default:
+ assert( pExpr->eType==FTS5_OR );
+ zOp = "OR";
+ break;
+ }
+
+ zRet = sqlite3_mprintf("%s", zOp);
+ for(i=0; zRet && i<pExpr->nChild; i++){
+ char *z = fts5ExprPrintTcl(pConfig, zNearsetCmd, pExpr->apChild[i]);
+ if( !z ){
+ sqlite3_free(zRet);
+ zRet = 0;
+ }else{
+ zRet = fts5PrintfAppend(zRet, " [%z]", z);
+ }
+ }
+ }
+
+ return zRet;
+}
+
+static char *fts5ExprPrint(Fts5Config *pConfig, Fts5ExprNode *pExpr){
+ char *zRet = 0;
+ if( pExpr->eType==FTS5_STRING || pExpr->eType==FTS5_TERM ){
+ Fts5ExprNearset *pNear = pExpr->pNear;
+ int i;
+ int iTerm;
+
+ if( pNear->pColset ){
+ int iCol = pNear->pColset->aiCol[0];
+ zRet = fts5PrintfAppend(zRet, "%s : ", pConfig->azCol[iCol]);
+ if( zRet==0 ) return 0;
+ }
+
+ if( pNear->nPhrase>1 ){
+ zRet = fts5PrintfAppend(zRet, "NEAR(");
+ if( zRet==0 ) return 0;
+ }
+
+ for(i=0; i<pNear->nPhrase; i++){
+ Fts5ExprPhrase *pPhrase = pNear->apPhrase[i];
+ if( i!=0 ){
+ zRet = fts5PrintfAppend(zRet, " ");
+ if( zRet==0 ) return 0;
+ }
+ for(iTerm=0; iTerm<pPhrase->nTerm; iTerm++){
+ char *zTerm = fts5ExprTermPrint(&pPhrase->aTerm[iTerm]);
+ if( zTerm ){
+ zRet = fts5PrintfAppend(zRet, "%s%s", iTerm==0?"":" + ", zTerm);
+ sqlite3_free(zTerm);
+ }
+ if( zTerm==0 || zRet==0 ){
+ sqlite3_free(zRet);
+ return 0;
+ }
+ }
+ }
+
+ if( pNear->nPhrase>1 ){
+ zRet = fts5PrintfAppend(zRet, ", %d)", pNear->nNear);
+ if( zRet==0 ) return 0;
+ }
+
+ }else{
+ char const *zOp = 0;
+ int i;
+
+ switch( pExpr->eType ){
+ case FTS5_AND: zOp = " AND "; break;
+ case FTS5_NOT: zOp = " NOT "; break;
+ default:
+ assert( pExpr->eType==FTS5_OR );
+ zOp = " OR ";
+ break;
+ }
+
+ for(i=0; i<pExpr->nChild; i++){
+ char *z = fts5ExprPrint(pConfig, pExpr->apChild[i]);
+ if( z==0 ){
+ sqlite3_free(zRet);
+ zRet = 0;
+ }else{
+ int e = pExpr->apChild[i]->eType;
+ int b = (e!=FTS5_STRING && e!=FTS5_TERM);
+ zRet = fts5PrintfAppend(zRet, "%s%s%z%s",
+ (i==0 ? "" : zOp),
+ (b?"(":""), z, (b?")":"")
+ );
+ }
+ if( zRet==0 ) break;
+ }
+ }
+
+ return zRet;
+}
+
+/*
+** The implementation of user-defined scalar functions fts5_expr() (bTcl==0)
+** and fts5_expr_tcl() (bTcl!=0).
+*/
+static void fts5ExprFunction(
+ sqlite3_context *pCtx, /* Function call context */
+ int nArg, /* Number of args */
+ sqlite3_value **apVal, /* Function arguments */
+ int bTcl
+){
+ Fts5Global *pGlobal = (Fts5Global*)sqlite3_user_data(pCtx);
+ sqlite3 *db = sqlite3_context_db_handle(pCtx);
+ const char *zExpr = 0;
+ char *zErr = 0;
+ Fts5Expr *pExpr = 0;
+ int rc;
+ int i;
+
+ const char **azConfig; /* Array of arguments for Fts5Config */
+ const char *zNearsetCmd = "nearset";
+ int nConfig; /* Size of azConfig[] */
+ Fts5Config *pConfig = 0;
+ int iArg = 1;
+
+ if( nArg<1 ){
+ zErr = sqlite3_mprintf("wrong number of arguments to function %s",
+ bTcl ? "fts5_expr_tcl" : "fts5_expr"
+ );
+ sqlite3_result_error(pCtx, zErr, -1);
+ sqlite3_free(zErr);
+ return;
+ }
+
+ if( bTcl && nArg>1 ){
+ zNearsetCmd = (const char*)sqlite3_value_text(apVal[1]);
+ iArg = 2;
+ }
+
+ nConfig = 3 + (nArg-iArg);
+ azConfig = (const char**)sqlite3_malloc(sizeof(char*) * nConfig);
+ if( azConfig==0 ){
+ sqlite3_result_error_nomem(pCtx);
+ return;
+ }
+ azConfig[0] = 0;
+ azConfig[1] = "main";
+ azConfig[2] = "tbl";
+ for(i=3; iArg<nArg; iArg++){
+ azConfig[i++] = (const char*)sqlite3_value_text(apVal[iArg]);
+ }
+
+ zExpr = (const char*)sqlite3_value_text(apVal[0]);
+
+ rc = sqlite3Fts5ConfigParse(pGlobal, db, nConfig, azConfig, &pConfig, &zErr);
+ if( rc==SQLITE_OK ){
+ rc = sqlite3Fts5ExprNew(pConfig, zExpr, &pExpr, &zErr);
+ }
+ if( rc==SQLITE_OK ){
+ char *zText;
+ if( pExpr->pRoot==0 ){
+ zText = sqlite3_mprintf("");
+ }else if( bTcl ){
+ zText = fts5ExprPrintTcl(pConfig, zNearsetCmd, pExpr->pRoot);
+ }else{
+ zText = fts5ExprPrint(pConfig, pExpr->pRoot);
+ }
+ if( zText==0 ){
+ rc = SQLITE_NOMEM;
+ }else{
+ sqlite3_result_text(pCtx, zText, -1, SQLITE_TRANSIENT);
+ sqlite3_free(zText);
+ }
+ }
+
+ if( rc!=SQLITE_OK ){
+ if( zErr ){
+ sqlite3_result_error(pCtx, zErr, -1);
+ sqlite3_free(zErr);
+ }else{
+ sqlite3_result_error_code(pCtx, rc);
+ }
+ }
+ sqlite3_free((void *)azConfig);
+ sqlite3Fts5ConfigFree(pConfig);
+ sqlite3Fts5ExprFree(pExpr);
+}
+
+static void fts5ExprFunctionHr(
+ sqlite3_context *pCtx, /* Function call context */
+ int nArg, /* Number of args */
+ sqlite3_value **apVal /* Function arguments */
+){
+ fts5ExprFunction(pCtx, nArg, apVal, 0);
+}
+static void fts5ExprFunctionTcl(
+ sqlite3_context *pCtx, /* Function call context */
+ int nArg, /* Number of args */
+ sqlite3_value **apVal /* Function arguments */
+){
+ fts5ExprFunction(pCtx, nArg, apVal, 1);
+}
+
+/*
+** The implementation of an SQLite user-defined-function that accepts a
+** single integer as an argument. If the integer is an alpha-numeric
+** unicode code point, 1 is returned. Otherwise 0.
+*/
+static void fts5ExprIsAlnum(
+ sqlite3_context *pCtx, /* Function call context */
+ int nArg, /* Number of args */
+ sqlite3_value **apVal /* Function arguments */
+){
+ int iCode;
+ if( nArg!=1 ){
+ sqlite3_result_error(pCtx,
+ "wrong number of arguments to function fts5_isalnum", -1
+ );
+ return;
+ }
+ iCode = sqlite3_value_int(apVal[0]);
+ sqlite3_result_int(pCtx, sqlite3Fts5UnicodeIsalnum(iCode));
+}
+
+static void fts5ExprFold(
+ sqlite3_context *pCtx, /* Function call context */
+ int nArg, /* Number of args */
+ sqlite3_value **apVal /* Function arguments */
+){
+ if( nArg!=1 && nArg!=2 ){
+ sqlite3_result_error(pCtx,
+ "wrong number of arguments to function fts5_fold", -1
+ );
+ }else{
+ int iCode;
+ int bRemoveDiacritics = 0;
+ iCode = sqlite3_value_int(apVal[0]);
+ if( nArg==2 ) bRemoveDiacritics = sqlite3_value_int(apVal[1]);
+ sqlite3_result_int(pCtx, sqlite3Fts5UnicodeFold(iCode, bRemoveDiacritics));
+ }
+}
+
+/*
+** This is called during initialization to register the fts5_expr() scalar
+** UDF with the SQLite handle passed as the only argument.
+*/
+static int sqlite3Fts5ExprInit(Fts5Global *pGlobal, sqlite3 *db){
+ struct Fts5ExprFunc {
+ const char *z;
+ void (*x)(sqlite3_context*,int,sqlite3_value**);
+ } aFunc[] = {
+ { "fts5_expr", fts5ExprFunctionHr },
+ { "fts5_expr_tcl", fts5ExprFunctionTcl },
+ { "fts5_isalnum", fts5ExprIsAlnum },
+ { "fts5_fold", fts5ExprFold },
+ };
+ int i;
+ int rc = SQLITE_OK;
+ void *pCtx = (void*)pGlobal;
+
+ for(i=0; rc==SQLITE_OK && i<(int)ArraySize(aFunc); i++){
+ struct Fts5ExprFunc *p = &aFunc[i];
+ rc = sqlite3_create_function(db, p->z, -1, SQLITE_UTF8, pCtx, p->x, 0, 0);
+ }
+
+ /* Avoid a warning indicating that sqlite3Fts5ParserTrace() is unused */
+#ifndef NDEBUG
+ (void)sqlite3Fts5ParserTrace;
+#endif
+
+ return rc;
+}
+
+/*
+** Return the number of phrases in expression pExpr.
+*/
+static int sqlite3Fts5ExprPhraseCount(Fts5Expr *pExpr){
+ return (pExpr ? pExpr->nPhrase : 0);
+}
+
+/*
+** Return the number of terms in the iPhrase'th phrase in pExpr.
+*/
+static int sqlite3Fts5ExprPhraseSize(Fts5Expr *pExpr, int iPhrase){
+ if( iPhrase<0 || iPhrase>=pExpr->nPhrase ) return 0;
+ return pExpr->apExprPhrase[iPhrase]->nTerm;
+}
+
+/*
+** This function is used to access the current position list for phrase
+** iPhrase.
+*/
+static int sqlite3Fts5ExprPoslist(Fts5Expr *pExpr, int iPhrase, const u8 **pa){
+ int nRet;
+ Fts5ExprPhrase *pPhrase = pExpr->apExprPhrase[iPhrase];
+ Fts5ExprNode *pNode = pPhrase->pNode;
+ if( pNode->bEof==0 && pNode->iRowid==pExpr->pRoot->iRowid ){
+ *pa = pPhrase->poslist.p;
+ nRet = pPhrase->poslist.n;
+ }else{
+ *pa = 0;
+ nRet = 0;
+ }
+ return nRet;
+}
+
+/*
+** 2014 August 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.
+**
+******************************************************************************
+**
+*/
+
+
+
+/* #include "fts5Int.h" */
+
+typedef struct Fts5HashEntry Fts5HashEntry;
+
+/*
+** This file contains the implementation of an in-memory hash table used
+** to accumuluate "term -> doclist" content before it is flused to a level-0
+** segment.
+*/
+
+
+struct Fts5Hash {
+ int *pnByte; /* Pointer to bytes counter */
+ int nEntry; /* Number of entries currently in hash */
+ int nSlot; /* Size of aSlot[] array */
+ Fts5HashEntry *pScan; /* Current ordered scan item */
+ Fts5HashEntry **aSlot; /* Array of hash slots */
+};
+
+/*
+** Each entry in the hash table is represented by an object of the
+** following type. Each object, its key (zKey[]) and its current data
+** are stored in a single memory allocation. The position list data
+** immediately follows the key data in memory.
+**
+** The data that follows the key is in a similar, but not identical format
+** to the doclist data stored in the database. It is:
+**
+** * Rowid, as a varint
+** * Position list, without 0x00 terminator.
+** * Size of previous position list and rowid, as a 4 byte
+** big-endian integer.
+**
+** iRowidOff:
+** Offset of last rowid written to data area. Relative to first byte of
+** structure.
+**
+** nData:
+** Bytes of data written since iRowidOff.
+*/
+struct Fts5HashEntry {
+ Fts5HashEntry *pHashNext; /* Next hash entry with same hash-key */
+ Fts5HashEntry *pScanNext; /* Next entry in sorted order */
+
+ int nAlloc; /* Total size of allocation */
+ int iSzPoslist; /* Offset of space for 4-byte poslist size */
+ int nData; /* Total bytes of data (incl. structure) */
+ u8 bDel; /* Set delete-flag @ iSzPoslist */
+
+ int iCol; /* Column of last value written */
+ int iPos; /* Position of last value written */
+ i64 iRowid; /* Rowid of last value written */
+ char zKey[8]; /* Nul-terminated entry key */
+};
+
+/*
+** Size of Fts5HashEntry without the zKey[] array.
+*/
+#define FTS5_HASHENTRYSIZE (sizeof(Fts5HashEntry)-8)
+
+
+
+/*
+** Allocate a new hash table.
+*/
+static int sqlite3Fts5HashNew(Fts5Hash **ppNew, int *pnByte){
+ int rc = SQLITE_OK;
+ Fts5Hash *pNew;
+
+ *ppNew = pNew = (Fts5Hash*)sqlite3_malloc(sizeof(Fts5Hash));
+ if( pNew==0 ){
+ rc = SQLITE_NOMEM;
+ }else{
+ int nByte;
+ memset(pNew, 0, sizeof(Fts5Hash));
+ pNew->pnByte = pnByte;
+
+ pNew->nSlot = 1024;
+ nByte = sizeof(Fts5HashEntry*) * pNew->nSlot;
+ pNew->aSlot = (Fts5HashEntry**)sqlite3_malloc(nByte);
+ if( pNew->aSlot==0 ){
+ sqlite3_free(pNew);
+ *ppNew = 0;
+ rc = SQLITE_NOMEM;
+ }else{
+ memset(pNew->aSlot, 0, nByte);
+ }
+ }
+ return rc;
+}
+
+/*
+** Free a hash table object.
+*/
+static void sqlite3Fts5HashFree(Fts5Hash *pHash){
+ if( pHash ){
+ sqlite3Fts5HashClear(pHash);
+ sqlite3_free(pHash->aSlot);
+ sqlite3_free(pHash);
+ }
+}
+
+/*
+** Empty (but do not delete) a hash table.
+*/
+static void sqlite3Fts5HashClear(Fts5Hash *pHash){
+ int i;
+ for(i=0; i<pHash->nSlot; i++){
+ Fts5HashEntry *pNext;
+ Fts5HashEntry *pSlot;
+ for(pSlot=pHash->aSlot[i]; pSlot; pSlot=pNext){
+ pNext = pSlot->pHashNext;
+ sqlite3_free(pSlot);
+ }
+ }
+ memset(pHash->aSlot, 0, pHash->nSlot * sizeof(Fts5HashEntry*));
+ pHash->nEntry = 0;
+}
+
+static unsigned int fts5HashKey(int nSlot, const u8 *p, int n){
+ int i;
+ unsigned int h = 13;
+ for(i=n-1; i>=0; i--){
+ h = (h << 3) ^ h ^ p[i];
+ }
+ return (h % nSlot);
+}
+
+static unsigned int fts5HashKey2(int nSlot, u8 b, const u8 *p, int n){
+ int i;
+ unsigned int h = 13;
+ for(i=n-1; i>=0; i--){
+ h = (h << 3) ^ h ^ p[i];
+ }
+ h = (h << 3) ^ h ^ b;
+ return (h % nSlot);
+}
+
+/*
+** Resize the hash table by doubling the number of slots.
+*/
+static int fts5HashResize(Fts5Hash *pHash){
+ int nNew = pHash->nSlot*2;
+ int i;
+ Fts5HashEntry **apNew;
+ Fts5HashEntry **apOld = pHash->aSlot;
+
+ apNew = (Fts5HashEntry**)sqlite3_malloc(nNew*sizeof(Fts5HashEntry*));
+ if( !apNew ) return SQLITE_NOMEM;
+ memset(apNew, 0, nNew*sizeof(Fts5HashEntry*));
+
+ for(i=0; i<pHash->nSlot; i++){
+ while( apOld[i] ){
+ int iHash;
+ Fts5HashEntry *p = apOld[i];
+ apOld[i] = p->pHashNext;
+ iHash = fts5HashKey(nNew, (u8*)p->zKey, (int)strlen(p->zKey));
+ p->pHashNext = apNew[iHash];
+ apNew[iHash] = p;
+ }
+ }
+
+ sqlite3_free(apOld);
+ pHash->nSlot = nNew;
+ pHash->aSlot = apNew;
+ return SQLITE_OK;
+}
+
+static void fts5HashAddPoslistSize(Fts5HashEntry *p){
+ if( p->iSzPoslist ){
+ u8 *pPtr = (u8*)p;
+ int nSz = (p->nData - p->iSzPoslist - 1); /* Size in bytes */
+ int nPos = nSz*2 + p->bDel; /* Value of nPos field */
+
+ assert( p->bDel==0 || p->bDel==1 );
+ if( nPos<=127 ){
+ pPtr[p->iSzPoslist] = (u8)nPos;
+ }else{
+ int nByte = sqlite3Fts5GetVarintLen((u32)nPos);
+ memmove(&pPtr[p->iSzPoslist + nByte], &pPtr[p->iSzPoslist + 1], nSz);
+ sqlite3Fts5PutVarint(&pPtr[p->iSzPoslist], nPos);
+ p->nData += (nByte-1);
+ }
+ p->bDel = 0;
+ p->iSzPoslist = 0;
+ }
+}
+
+static int sqlite3Fts5HashWrite(
+ Fts5Hash *pHash,
+ i64 iRowid, /* Rowid for this entry */
+ int iCol, /* Column token appears in (-ve -> delete) */
+ int iPos, /* Position of token within column */
+ char bByte, /* First byte of token */
+ const char *pToken, int nToken /* Token to add or remove to or from index */
+){
+ unsigned int iHash;
+ Fts5HashEntry *p;
+ u8 *pPtr;
+ int nIncr = 0; /* Amount to increment (*pHash->pnByte) by */
+
+ /* Attempt to locate an existing hash entry */
+ iHash = fts5HashKey2(pHash->nSlot, (u8)bByte, (const u8*)pToken, nToken);
+ for(p=pHash->aSlot[iHash]; p; p=p->pHashNext){
+ if( p->zKey[0]==bByte
+ && memcmp(&p->zKey[1], pToken, nToken)==0
+ && p->zKey[nToken+1]==0
+ ){
+ break;
+ }
+ }
+
+ /* If an existing hash entry cannot be found, create a new one. */
+ if( p==0 ){
+ int nByte = FTS5_HASHENTRYSIZE + (nToken+1) + 1 + 64;
+ if( nByte<128 ) nByte = 128;
+
+ if( (pHash->nEntry*2)>=pHash->nSlot ){
+ int rc = fts5HashResize(pHash);
+ if( rc!=SQLITE_OK ) return rc;
+ iHash = fts5HashKey2(pHash->nSlot, (u8)bByte, (const u8*)pToken, nToken);
+ }
+
+ p = (Fts5HashEntry*)sqlite3_malloc(nByte);
+ if( !p ) return SQLITE_NOMEM;
+ memset(p, 0, FTS5_HASHENTRYSIZE);
+ p->nAlloc = nByte;
+ p->zKey[0] = bByte;
+ memcpy(&p->zKey[1], pToken, nToken);
+ assert( iHash==fts5HashKey(pHash->nSlot, (u8*)p->zKey, nToken+1) );
+ p->zKey[nToken+1] = '\0';
+ p->nData = nToken+1 + 1 + FTS5_HASHENTRYSIZE;
+ p->nData += sqlite3Fts5PutVarint(&((u8*)p)[p->nData], iRowid);
+ p->iSzPoslist = p->nData;
+ p->nData += 1;
+ p->iRowid = iRowid;
+ p->pHashNext = pHash->aSlot[iHash];
+ pHash->aSlot[iHash] = p;
+ pHash->nEntry++;
+ nIncr += p->nData;
+ }
+
+ /* Check there is enough space to append a new entry. Worst case scenario
+ ** is:
+ **
+ ** + 9 bytes for a new rowid,
+ ** + 4 byte reserved for the "poslist size" varint.
+ ** + 1 byte for a "new column" byte,
+ ** + 3 bytes for a new column number (16-bit max) as a varint,
+ ** + 5 bytes for the new position offset (32-bit max).
+ */
+ if( (p->nAlloc - p->nData) < (9 + 4 + 1 + 3 + 5) ){
+ int nNew = p->nAlloc * 2;
+ Fts5HashEntry *pNew;
+ Fts5HashEntry **pp;
+ pNew = (Fts5HashEntry*)sqlite3_realloc(p, nNew);
+ if( pNew==0 ) return SQLITE_NOMEM;
+ pNew->nAlloc = nNew;
+ for(pp=&pHash->aSlot[iHash]; *pp!=p; pp=&(*pp)->pHashNext);
+ *pp = pNew;
+ p = pNew;
+ }
+ pPtr = (u8*)p;
+ nIncr -= p->nData;
+
+ /* If this is a new rowid, append the 4-byte size field for the previous
+ ** entry, and the new rowid for this entry. */
+ if( iRowid!=p->iRowid ){
+ fts5HashAddPoslistSize(p);
+ p->nData += sqlite3Fts5PutVarint(&pPtr[p->nData], iRowid - p->iRowid);
+ p->iSzPoslist = p->nData;
+ p->nData += 1;
+ p->iCol = 0;
+ p->iPos = 0;
+ p->iRowid = iRowid;
+ }
+
+ if( iCol>=0 ){
+ /* Append a new column value, if necessary */
+ assert( iCol>=p->iCol );
+ if( iCol!=p->iCol ){
+ pPtr[p->nData++] = 0x01;
+ p->nData += sqlite3Fts5PutVarint(&pPtr[p->nData], iCol);
+ p->iCol = iCol;
+ p->iPos = 0;
+ }
+
+ /* Append the new position offset */
+ p->nData += sqlite3Fts5PutVarint(&pPtr[p->nData], iPos - p->iPos + 2);
+ p->iPos = iPos;
+ }else{
+ /* This is a delete. Set the delete flag. */
+ p->bDel = 1;
+ }
+ nIncr += p->nData;
+
+ *pHash->pnByte += nIncr;
+ return SQLITE_OK;
+}
+
+
+/*
+** Arguments pLeft and pRight point to linked-lists of hash-entry objects,
+** each sorted in key order. This function merges the two lists into a
+** single list and returns a pointer to its first element.
+*/
+static Fts5HashEntry *fts5HashEntryMerge(
+ Fts5HashEntry *pLeft,
+ Fts5HashEntry *pRight
+){
+ Fts5HashEntry *p1 = pLeft;
+ Fts5HashEntry *p2 = pRight;
+ Fts5HashEntry *pRet = 0;
+ Fts5HashEntry **ppOut = &pRet;
+
+ while( p1 || p2 ){
+ if( p1==0 ){
+ *ppOut = p2;
+ p2 = 0;
+ }else if( p2==0 ){
+ *ppOut = p1;
+ p1 = 0;
+ }else{
+ int i = 0;
+ while( p1->zKey[i]==p2->zKey[i] ) i++;
+
+ if( ((u8)p1->zKey[i])>((u8)p2->zKey[i]) ){
+ /* p2 is smaller */
+ *ppOut = p2;
+ ppOut = &p2->pScanNext;
+ p2 = p2->pScanNext;
+ }else{
+ /* p1 is smaller */
+ *ppOut = p1;
+ ppOut = &p1->pScanNext;
+ p1 = p1->pScanNext;
+ }
+ *ppOut = 0;
+ }
+ }
+
+ return pRet;
+}
+
+/*
+** Extract all tokens from hash table iHash and link them into a list
+** in sorted order. The hash table is cleared before returning. It is
+** the responsibility of the caller to free the elements of the returned
+** list.
+*/
+static int fts5HashEntrySort(
+ Fts5Hash *pHash,
+ const char *pTerm, int nTerm, /* Query prefix, if any */
+ Fts5HashEntry **ppSorted
+){
+ const int nMergeSlot = 32;
+ Fts5HashEntry **ap;
+ Fts5HashEntry *pList;
+ int iSlot;
+ int i;
+
+ *ppSorted = 0;
+ ap = sqlite3_malloc(sizeof(Fts5HashEntry*) * nMergeSlot);
+ if( !ap ) return SQLITE_NOMEM;
+ memset(ap, 0, sizeof(Fts5HashEntry*) * nMergeSlot);
+
+ for(iSlot=0; iSlot<pHash->nSlot; iSlot++){
+ Fts5HashEntry *pIter;
+ for(pIter=pHash->aSlot[iSlot]; pIter; pIter=pIter->pHashNext){
+ if( pTerm==0 || 0==memcmp(pIter->zKey, pTerm, nTerm) ){
+ Fts5HashEntry *pEntry = pIter;
+ pEntry->pScanNext = 0;
+ for(i=0; ap[i]; i++){
+ pEntry = fts5HashEntryMerge(pEntry, ap[i]);
+ ap[i] = 0;
+ }
+ ap[i] = pEntry;
+ }
+ }
+ }
+
+ pList = 0;
+ for(i=0; i<nMergeSlot; i++){
+ pList = fts5HashEntryMerge(pList, ap[i]);
+ }
+
+ pHash->nEntry = 0;
+ sqlite3_free(ap);
+ *ppSorted = pList;
+ return SQLITE_OK;
+}
+
+/*
+** Query the hash table for a doclist associated with term pTerm/nTerm.
+*/
+static int sqlite3Fts5HashQuery(
+ Fts5Hash *pHash, /* Hash table to query */
+ const char *pTerm, int nTerm, /* Query term */
+ const u8 **ppDoclist, /* OUT: Pointer to doclist for pTerm */
+ int *pnDoclist /* OUT: Size of doclist in bytes */
+){
+ unsigned int iHash = fts5HashKey(pHash->nSlot, (const u8*)pTerm, nTerm);
+ Fts5HashEntry *p;
+
+ for(p=pHash->aSlot[iHash]; p; p=p->pHashNext){
+ if( memcmp(p->zKey, pTerm, nTerm)==0 && p->zKey[nTerm]==0 ) break;
+ }
+
+ if( p ){
+ fts5HashAddPoslistSize(p);
+ *ppDoclist = (const u8*)&p->zKey[nTerm+1];
+ *pnDoclist = p->nData - (FTS5_HASHENTRYSIZE + nTerm + 1);
+ }else{
+ *ppDoclist = 0;
+ *pnDoclist = 0;
+ }
+
+ return SQLITE_OK;
+}
+
+static int sqlite3Fts5HashScanInit(
+ Fts5Hash *p, /* Hash table to query */
+ const char *pTerm, int nTerm /* Query prefix */
+){
+ return fts5HashEntrySort(p, pTerm, nTerm, &p->pScan);
+}
+
+static void sqlite3Fts5HashScanNext(Fts5Hash *p){
+ assert( !sqlite3Fts5HashScanEof(p) );
+ p->pScan = p->pScan->pScanNext;
+}
+
+static int sqlite3Fts5HashScanEof(Fts5Hash *p){
+ return (p->pScan==0);
+}
+
+static void sqlite3Fts5HashScanEntry(
+ Fts5Hash *pHash,
+ const char **pzTerm, /* OUT: term (nul-terminated) */
+ const u8 **ppDoclist, /* OUT: pointer to doclist */
+ int *pnDoclist /* OUT: size of doclist in bytes */
+){
+ Fts5HashEntry *p;
+ if( (p = pHash->pScan) ){
+ int nTerm = (int)strlen(p->zKey);
+ fts5HashAddPoslistSize(p);
+ *pzTerm = p->zKey;
+ *ppDoclist = (const u8*)&p->zKey[nTerm+1];
+ *pnDoclist = p->nData - (FTS5_HASHENTRYSIZE + nTerm + 1);
+ }else{
+ *pzTerm = 0;
+ *ppDoclist = 0;
+ *pnDoclist = 0;
+ }
+}
+
+
+/*
+** 2014 May 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.
+**
+******************************************************************************
+**
+** Low level access to the FTS index stored in the database file. The
+** routines in this file file implement all read and write access to the
+** %_data table. Other parts of the system access this functionality via
+** the interface defined in fts5Int.h.
+*/
+
+
+/* #include "fts5Int.h" */
+
+/*
+** Overview:
+**
+** The %_data table contains all the FTS indexes for an FTS5 virtual table.
+** As well as the main term index, there may be up to 31 prefix indexes.
+** The format is similar to FTS3/4, except that:
+**
+** * all segment b-tree leaf data is stored in fixed size page records
+** (e.g. 1000 bytes). A single doclist may span multiple pages. Care is
+** taken to ensure it is possible to iterate in either direction through
+** the entries in a doclist, or to seek to a specific entry within a
+** doclist, without loading it into memory.
+**
+** * large doclists that span many pages have associated "doclist index"
+** records that contain a copy of the first rowid on each page spanned by
+** the doclist. This is used to speed up seek operations, and merges of
+** large doclists with very small doclists.
+**
+** * extra fields in the "structure record" record the state of ongoing
+** incremental merge operations.
+**
+*/
+
+
+#define FTS5_OPT_WORK_UNIT 1000 /* Number of leaf pages per optimize step */
+#define FTS5_WORK_UNIT 64 /* Number of leaf pages in unit of work */
+
+#define FTS5_MIN_DLIDX_SIZE 4 /* Add dlidx if this many empty pages */
+
+#define FTS5_MAIN_PREFIX '0'
+
+#if FTS5_MAX_PREFIX_INDEXES > 31
+# error "FTS5_MAX_PREFIX_INDEXES is too large"
+#endif
+
+/*
+** Details:
+**
+** The %_data table managed by this module,
+**
+** CREATE TABLE %_data(id INTEGER PRIMARY KEY, block BLOB);
+**
+** , contains the following 5 types of records. See the comments surrounding
+** the FTS5_*_ROWID macros below for a description of how %_data rowids are
+** assigned to each fo them.
+**
+** 1. Structure Records:
+**
+** The set of segments that make up an index - the index structure - are
+** recorded in a single record within the %_data table. The record consists
+** of a single 32-bit configuration cookie value followed by a list of
+** SQLite varints. If the FTS table features more than one index (because
+** there are one or more prefix indexes), it is guaranteed that all share
+** the same cookie value.
+**
+** Immediately following the configuration cookie, the record begins with
+** three varints:
+**
+** + number of levels,
+** + total number of segments on all levels,
+** + value of write counter.
+**
+** Then, for each level from 0 to nMax:
+**
+** + number of input segments in ongoing merge.
+** + total number of segments in level.
+** + for each segment from oldest to newest:
+** + segment id (always > 0)
+** + first leaf page number (often 1, always greater than 0)
+** + final leaf page number
+**
+** 2. The Averages Record:
+**
+** A single record within the %_data table. The data is a list of varints.
+** The first value is the number of rows in the index. Then, for each column
+** from left to right, the total number of tokens in the column for all
+** rows of the table.
+**
+** 3. Segment leaves:
+**
+** TERM/DOCLIST FORMAT:
+**
+** Most of each segment leaf is taken up by term/doclist data. The
+** general format of term/doclist, starting with the first term
+** on the leaf page, is:
+**
+** varint : size of first term
+** blob: first term data
+** doclist: first doclist
+** zero-or-more {
+** varint: number of bytes in common with previous term
+** varint: number of bytes of new term data (nNew)
+** blob: nNew bytes of new term data
+** doclist: next doclist
+** }
+**
+** doclist format:
+**
+** varint: first rowid
+** poslist: first poslist
+** zero-or-more {
+** varint: rowid delta (always > 0)
+** poslist: next poslist
+** }
+**
+** poslist format:
+**
+** varint: size of poslist in bytes multiplied by 2, not including
+** this field. Plus 1 if this entry carries the "delete" flag.
+** collist: collist for column 0
+** zero-or-more {
+** 0x01 byte
+** varint: column number (I)
+** collist: collist for column I
+** }
+**
+** collist format:
+**
+** varint: first offset + 2
+** zero-or-more {
+** varint: offset delta + 2
+** }
+**
+** PAGE FORMAT
+**
+** Each leaf page begins with a 4-byte header containing 2 16-bit
+** unsigned integer fields in big-endian format. They are:
+**
+** * The byte offset of the first rowid on the page, if it exists
+** and occurs before the first term (otherwise 0).
+**
+** * The byte offset of the start of the page footer. If the page
+** footer is 0 bytes in size, then this field is the same as the
+** size of the leaf page in bytes.
+**
+** The page footer consists of a single varint for each term located
+** on the page. Each varint is the byte offset of the current term
+** within the page, delta-compressed against the previous value. In
+** other words, the first varint in the footer is the byte offset of
+** the first term, the second is the byte offset of the second less that
+** of the first, and so on.
+**
+** The term/doclist format described above is accurate if the entire
+** term/doclist data fits on a single leaf page. If this is not the case,
+** the format is changed in two ways:
+**
+** + if the first rowid on a page occurs before the first term, it
+** is stored as a literal value:
+**
+** varint: first rowid
+**
+** + the first term on each page is stored in the same way as the
+** very first term of the segment:
+**
+** varint : size of first term
+** blob: first term data
+**
+** 5. Segment doclist indexes:
+**
+** Doclist indexes are themselves b-trees, however they usually consist of
+** a single leaf record only. The format of each doclist index leaf page
+** is:
+**
+** * Flags byte. Bits are:
+** 0x01: Clear if leaf is also the root page, otherwise set.
+**
+** * Page number of fts index leaf page. As a varint.
+**
+** * First rowid on page indicated by previous field. As a varint.
+**
+** * A list of varints, one for each subsequent termless page. A
+** positive delta if the termless page contains at least one rowid,
+** or an 0x00 byte otherwise.
+**
+** Internal doclist index nodes are:
+**
+** * Flags byte. Bits are:
+** 0x01: Clear for root page, otherwise set.
+**
+** * Page number of first child page. As a varint.
+**
+** * Copy of first rowid on page indicated by previous field. As a varint.
+**
+** * A list of delta-encoded varints - the first rowid on each subsequent
+** child page.
+**
+*/
+
+/*
+** Rowids for the averages and structure records in the %_data table.
+*/
+#define FTS5_AVERAGES_ROWID 1 /* Rowid used for the averages record */
+#define FTS5_STRUCTURE_ROWID 10 /* The structure record */
+
+/*
+** Macros determining the rowids used by segment leaves and dlidx leaves
+** and nodes. All nodes and leaves are stored in the %_data table with large
+** positive rowids.
+**
+** Each segment has a unique non-zero 16-bit id.
+**
+** The rowid for each segment leaf is found by passing the segment id and
+** the leaf page number to the FTS5_SEGMENT_ROWID macro. Leaves are numbered
+** sequentially starting from 1.
+*/
+#define FTS5_DATA_ID_B 16 /* Max seg id number 65535 */
+#define FTS5_DATA_DLI_B 1 /* Doclist-index flag (1 bit) */
+#define FTS5_DATA_HEIGHT_B 5 /* Max dlidx tree height of 32 */
+#define FTS5_DATA_PAGE_B 31 /* Max page number of 2147483648 */
+
+#define fts5_dri(segid, dlidx, height, pgno) ( \
+ ((i64)(segid) << (FTS5_DATA_PAGE_B+FTS5_DATA_HEIGHT_B+FTS5_DATA_DLI_B)) + \
+ ((i64)(dlidx) << (FTS5_DATA_PAGE_B + FTS5_DATA_HEIGHT_B)) + \
+ ((i64)(height) << (FTS5_DATA_PAGE_B)) + \
+ ((i64)(pgno)) \
+)
+
+#define FTS5_SEGMENT_ROWID(segid, pgno) fts5_dri(segid, 0, 0, pgno)
+#define FTS5_DLIDX_ROWID(segid, height, pgno) fts5_dri(segid, 1, height, pgno)
+
+/*
+** Maximum segments permitted in a single index
+*/
+#define FTS5_MAX_SEGMENT 2000
+
+#ifdef SQLITE_DEBUG
+static int sqlite3Fts5Corrupt() { return SQLITE_CORRUPT_VTAB; }
+#endif
+
+
+/*
+** Each time a blob is read from the %_data table, it is padded with this
+** many zero bytes. This makes it easier to decode the various record formats
+** without overreading if the records are corrupt.
+*/
+#define FTS5_DATA_ZERO_PADDING 8
+#define FTS5_DATA_PADDING 20
+
+typedef struct Fts5Data Fts5Data;
+typedef struct Fts5DlidxIter Fts5DlidxIter;
+typedef struct Fts5DlidxLvl Fts5DlidxLvl;
+typedef struct Fts5DlidxWriter Fts5DlidxWriter;
+typedef struct Fts5PageWriter Fts5PageWriter;
+typedef struct Fts5SegIter Fts5SegIter;
+typedef struct Fts5DoclistIter Fts5DoclistIter;
+typedef struct Fts5SegWriter Fts5SegWriter;
+typedef struct Fts5Structure Fts5Structure;
+typedef struct Fts5StructureLevel Fts5StructureLevel;
+typedef struct Fts5StructureSegment Fts5StructureSegment;
+
+struct Fts5Data {
+ u8 *p; /* Pointer to buffer containing record */
+ int nn; /* Size of record in bytes */
+ int szLeaf; /* Size of leaf without page-index */
+};
+
+/*
+** One object per %_data table.
+*/
+struct Fts5Index {
+ Fts5Config *pConfig; /* Virtual table configuration */
+ char *zDataTbl; /* Name of %_data table */
+ int nWorkUnit; /* Leaf pages in a "unit" of work */
+
+ /*
+ ** Variables related to the accumulation of tokens and doclists within the
+ ** in-memory hash tables before they are flushed to disk.
+ */
+ Fts5Hash *pHash; /* Hash table for in-memory data */
+ int nPendingData; /* Current bytes of pending data */
+ i64 iWriteRowid; /* Rowid for current doc being written */
+ int bDelete; /* Current write is a delete */
+
+ /* Error state. */
+ int rc; /* Current error code */
+
+ /* State used by the fts5DataXXX() functions. */
+ sqlite3_blob *pReader; /* RO incr-blob open on %_data table */
+ sqlite3_stmt *pWriter; /* "INSERT ... %_data VALUES(?,?)" */
+ sqlite3_stmt *pDeleter; /* "DELETE FROM %_data ... id>=? AND id<=?" */
+ sqlite3_stmt *pIdxWriter; /* "INSERT ... %_idx VALUES(?,?,?,?)" */
+ sqlite3_stmt *pIdxDeleter; /* "DELETE FROM %_idx WHERE segid=? */
+ sqlite3_stmt *pIdxSelect;
+ int nRead; /* Total number of blocks read */
+};
+
+struct Fts5DoclistIter {
+ u8 *aEof; /* Pointer to 1 byte past end of doclist */
+
+ /* Output variables. aPoslist==0 at EOF */
+ i64 iRowid;
+ u8 *aPoslist;
+ int nPoslist;
+ int nSize;
+};
+
+/*
+** The contents of the "structure" record for each index are represented
+** using an Fts5Structure record in memory. Which uses instances of the
+** other Fts5StructureXXX types as components.
+*/
+struct Fts5StructureSegment {
+ int iSegid; /* Segment id */
+ int pgnoFirst; /* First leaf page number in segment */
+ int pgnoLast; /* Last leaf page number in segment */
+};
+struct Fts5StructureLevel {
+ int nMerge; /* Number of segments in incr-merge */
+ int nSeg; /* Total number of segments on level */
+ Fts5StructureSegment *aSeg; /* Array of segments. aSeg[0] is oldest. */
+};
+struct Fts5Structure {
+ int nRef; /* Object reference count */
+ u64 nWriteCounter; /* Total leaves written to level 0 */
+ int nSegment; /* Total segments in this structure */
+ int nLevel; /* Number of levels in this index */
+ Fts5StructureLevel aLevel[1]; /* Array of nLevel level objects */
+};
+
+/*
+** An object of type Fts5SegWriter is used to write to segments.
+*/
+struct Fts5PageWriter {
+ int pgno; /* Page number for this page */
+ int iPrevPgidx; /* Previous value written into pgidx */
+ Fts5Buffer buf; /* Buffer containing leaf data */
+ Fts5Buffer pgidx; /* Buffer containing page-index */
+ Fts5Buffer term; /* Buffer containing previous term on page */
+};
+struct Fts5DlidxWriter {
+ int pgno; /* Page number for this page */
+ int bPrevValid; /* True if iPrev is valid */
+ i64 iPrev; /* Previous rowid value written to page */
+ Fts5Buffer buf; /* Buffer containing page data */
+};
+struct Fts5SegWriter {
+ int iSegid; /* Segid to write to */
+ Fts5PageWriter writer; /* PageWriter object */
+ i64 iPrevRowid; /* Previous rowid written to current leaf */
+ u8 bFirstRowidInDoclist; /* True if next rowid is first in doclist */
+ u8 bFirstRowidInPage; /* True if next rowid is first in page */
+ /* TODO1: Can use (writer.pgidx.n==0) instead of bFirstTermInPage */
+ u8 bFirstTermInPage; /* True if next term will be first in leaf */
+ int nLeafWritten; /* Number of leaf pages written */
+ int nEmpty; /* Number of contiguous term-less nodes */
+
+ int nDlidx; /* Allocated size of aDlidx[] array */
+ Fts5DlidxWriter *aDlidx; /* Array of Fts5DlidxWriter objects */
+
+ /* Values to insert into the %_idx table */
+ Fts5Buffer btterm; /* Next term to insert into %_idx table */
+ int iBtPage; /* Page number corresponding to btterm */
+};
+
+typedef struct Fts5CResult Fts5CResult;
+struct Fts5CResult {
+ u16 iFirst; /* aSeg[] index of firstest iterator */
+ u8 bTermEq; /* True if the terms are equal */
+};
+
+/*
+** Object for iterating through a single segment, visiting each term/rowid
+** pair in the segment.
+**
+** pSeg:
+** The segment to iterate through.
+**
+** iLeafPgno:
+** Current leaf page number within segment.
+**
+** iLeafOffset:
+** Byte offset within the current leaf that is the first byte of the
+** position list data (one byte passed the position-list size field).
+** rowid field of the current entry. Usually this is the size field of the
+** position list data. The exception is if the rowid for the current entry
+** is the last thing on the leaf page.
+**
+** pLeaf:
+** Buffer containing current leaf page data. Set to NULL at EOF.
+**
+** iTermLeafPgno, iTermLeafOffset:
+** Leaf page number containing the last term read from the segment. And
+** the offset immediately following the term data.
+**
+** flags:
+** Mask of FTS5_SEGITER_XXX values. Interpreted as follows:
+**
+** FTS5_SEGITER_ONETERM:
+** If set, set the iterator to point to EOF after the current doclist
+** has been exhausted. Do not proceed to the next term in the segment.
+**
+** FTS5_SEGITER_REVERSE:
+** This flag is only ever set if FTS5_SEGITER_ONETERM is also set. If
+** it is set, iterate through rowid in descending order instead of the
+** default ascending order.
+**
+** iRowidOffset/nRowidOffset/aRowidOffset:
+** These are used if the FTS5_SEGITER_REVERSE flag is set.
+**
+** For each rowid on the page corresponding to the current term, the
+** corresponding aRowidOffset[] entry is set to the byte offset of the
+** start of the "position-list-size" field within the page.
+**
+** iTermIdx:
+** Index of current term on iTermLeafPgno.
+*/
+struct Fts5SegIter {
+ Fts5StructureSegment *pSeg; /* Segment to iterate through */
+ int flags; /* Mask of configuration flags */
+ int iLeafPgno; /* Current leaf page number */
+ Fts5Data *pLeaf; /* Current leaf data */
+ Fts5Data *pNextLeaf; /* Leaf page (iLeafPgno+1) */
+ int iLeafOffset; /* Byte offset within current leaf */
+
+ /* The page and offset from which the current term was read. The offset
+ ** is the offset of the first rowid in the current doclist. */
+ int iTermLeafPgno;
+ int iTermLeafOffset;
+
+ int iPgidxOff; /* Next offset in pgidx */
+ int iEndofDoclist;
+
+ /* The following are only used if the FTS5_SEGITER_REVERSE flag is set. */
+ int iRowidOffset; /* Current entry in aRowidOffset[] */
+ int nRowidOffset; /* Allocated size of aRowidOffset[] array */
+ int *aRowidOffset; /* Array of offset to rowid fields */
+
+ Fts5DlidxIter *pDlidx; /* If there is a doclist-index */
+
+ /* Variables populated based on current entry. */
+ Fts5Buffer term; /* Current term */
+ i64 iRowid; /* Current rowid */
+ int nPos; /* Number of bytes in current position list */
+ int bDel; /* True if the delete flag is set */
+};
+
+/*
+** Argument is a pointer to an Fts5Data structure that contains a
+** leaf page.
+*/
+#define ASSERT_SZLEAF_OK(x) assert( \
+ (x)->szLeaf==(x)->nn || (x)->szLeaf==fts5GetU16(&(x)->p[2]) \
+)
+
+#define FTS5_SEGITER_ONETERM 0x01
+#define FTS5_SEGITER_REVERSE 0x02
+
+
+/*
+** Argument is a pointer to an Fts5Data structure that contains a leaf
+** page. This macro evaluates to true if the leaf contains no terms, or
+** false if it contains at least one term.
+*/
+#define fts5LeafIsTermless(x) ((x)->szLeaf >= (x)->nn)
+
+#define fts5LeafTermOff(x, i) (fts5GetU16(&(x)->p[(x)->szLeaf + (i)*2]))
+
+#define fts5LeafFirstRowidOff(x) (fts5GetU16((x)->p))
+
+/*
+** Object for iterating through the merged results of one or more segments,
+** visiting each term/rowid pair in the merged data.
+**
+** nSeg is always a power of two greater than or equal to the number of
+** segments that this object is merging data from. Both the aSeg[] and
+** aFirst[] arrays are sized at nSeg entries. The aSeg[] array is padded
+** with zeroed objects - these are handled as if they were iterators opened
+** on empty segments.
+**
+** The results of comparing segments aSeg[N] and aSeg[N+1], where N is an
+** even number, is stored in aFirst[(nSeg+N)/2]. The "result" of the
+** comparison in this context is the index of the iterator that currently
+** points to the smaller term/rowid combination. Iterators at EOF are
+** considered to be greater than all other iterators.
+**
+** aFirst[1] contains the index in aSeg[] of the iterator that points to
+** the smallest key overall. aFirst[0] is unused.
+**
+** poslist:
+** Used by sqlite3Fts5IterPoslist() when the poslist needs to be buffered.
+** There is no way to tell if this is populated or not.
+*/
+struct Fts5IndexIter {
+ Fts5Index *pIndex; /* Index that owns this iterator */
+ Fts5Structure *pStruct; /* Database structure for this iterator */
+ Fts5Buffer poslist; /* Buffer containing current poslist */
+
+ int nSeg; /* Size of aSeg[] array */
+ int bRev; /* True to iterate in reverse order */
+ u8 bSkipEmpty; /* True to skip deleted entries */
+ u8 bEof; /* True at EOF */
+ u8 bFiltered; /* True if column-filter already applied */
+
+ i64 iSwitchRowid; /* Firstest rowid of other than aFirst[1] */
+ Fts5CResult *aFirst; /* Current merge state (see above) */
+ Fts5SegIter aSeg[1]; /* Array of segment iterators */
+};
+
+
+/*
+** An instance of the following type is used to iterate through the contents
+** of a doclist-index record.
+**
+** pData:
+** Record containing the doclist-index data.
+**
+** bEof:
+** Set to true once iterator has reached EOF.
+**
+** iOff:
+** Set to the current offset within record pData.
+*/
+struct Fts5DlidxLvl {
+ Fts5Data *pData; /* Data for current page of this level */
+ int iOff; /* Current offset into pData */
+ int bEof; /* At EOF already */
+ int iFirstOff; /* Used by reverse iterators */
+
+ /* Output variables */
+ int iLeafPgno; /* Page number of current leaf page */
+ i64 iRowid; /* First rowid on leaf iLeafPgno */
+};
+struct Fts5DlidxIter {
+ int nLvl;
+ int iSegid;
+ Fts5DlidxLvl aLvl[1];
+};
+
+static void fts5PutU16(u8 *aOut, u16 iVal){
+ aOut[0] = (iVal>>8);
+ aOut[1] = (iVal&0xFF);
+}
+
+static u16 fts5GetU16(const u8 *aIn){
+ return ((u16)aIn[0] << 8) + aIn[1];
+}
+
+/*
+** Allocate and return a buffer at least nByte bytes in size.
+**
+** If an OOM error is encountered, return NULL and set the error code in
+** the Fts5Index handle passed as the first argument.
+*/
+static void *fts5IdxMalloc(Fts5Index *p, int nByte){
+ return sqlite3Fts5MallocZero(&p->rc, nByte);
+}
+
+/*
+** Compare the contents of the pLeft buffer with the pRight/nRight blob.
+**
+** Return -ve if pLeft is smaller than pRight, 0 if they are equal or
+** +ve if pRight is smaller than pLeft. In other words:
+**
+** res = *pLeft - *pRight
+*/
+#ifdef SQLITE_DEBUG
+static int fts5BufferCompareBlob(
+ Fts5Buffer *pLeft, /* Left hand side of comparison */
+ const u8 *pRight, int nRight /* Right hand side of comparison */
+){
+ int nCmp = MIN(pLeft->n, nRight);
+ int res = memcmp(pLeft->p, pRight, nCmp);
+ return (res==0 ? (pLeft->n - nRight) : res);
+}
+#endif
+
+/*
+** Compare the contents of the two buffers using memcmp(). If one buffer
+** is a prefix of the other, it is considered the lesser.
+**
+** Return -ve if pLeft is smaller than pRight, 0 if they are equal or
+** +ve if pRight is smaller than pLeft. In other words:
+**
+** res = *pLeft - *pRight
+*/
+static int fts5BufferCompare(Fts5Buffer *pLeft, Fts5Buffer *pRight){
+ int nCmp = MIN(pLeft->n, pRight->n);
+ int res = memcmp(pLeft->p, pRight->p, nCmp);
+ return (res==0 ? (pLeft->n - pRight->n) : res);
+}
+
+#ifdef SQLITE_DEBUG
+static int fts5BlobCompare(
+ const u8 *pLeft, int nLeft,
+ const u8 *pRight, int nRight
+){
+ int nCmp = MIN(nLeft, nRight);
+ int res = memcmp(pLeft, pRight, nCmp);
+ return (res==0 ? (nLeft - nRight) : res);
+}
+#endif
+
+static int fts5LeafFirstTermOff(Fts5Data *pLeaf){
+ int ret;
+ fts5GetVarint32(&pLeaf->p[pLeaf->szLeaf], ret);
+ return ret;
+}
+
+/*
+** Close the read-only blob handle, if it is open.
+*/
+static void fts5CloseReader(Fts5Index *p){
+ if( p->pReader ){
+ sqlite3_blob *pReader = p->pReader;
+ p->pReader = 0;
+ sqlite3_blob_close(pReader);
+ }
+}
+
+
+/*
+** Retrieve a record from the %_data table.
+**
+** If an error occurs, NULL is returned and an error left in the
+** Fts5Index object.
+*/
+static Fts5Data *fts5DataRead(Fts5Index *p, i64 iRowid){
+ Fts5Data *pRet = 0;
+ if( p->rc==SQLITE_OK ){
+ int rc = SQLITE_OK;
+
+ if( p->pReader ){
+ /* This call may return SQLITE_ABORT if there has been a savepoint
+ ** rollback since it was last used. In this case a new blob handle
+ ** is required. */
+ sqlite3_blob *pBlob = p->pReader;
+ p->pReader = 0;
+ rc = sqlite3_blob_reopen(pBlob, iRowid);
+ assert( p->pReader==0 );
+ p->pReader = pBlob;
+ if( rc!=SQLITE_OK ){
+ fts5CloseReader(p);
+ }
+ if( rc==SQLITE_ABORT ) rc = SQLITE_OK;
+ }
+
+ /* If the blob handle is not open at this point, open it and seek
+ ** to the requested entry. */
+ if( p->pReader==0 && rc==SQLITE_OK ){
+ Fts5Config *pConfig = p->pConfig;
+ rc = sqlite3_blob_open(pConfig->db,
+ pConfig->zDb, p->zDataTbl, "block", iRowid, 0, &p->pReader
+ );
+ }
+
+ /* If either of the sqlite3_blob_open() or sqlite3_blob_reopen() calls
+ ** above returned SQLITE_ERROR, return SQLITE_CORRUPT_VTAB instead.
+ ** All the reasons those functions might return SQLITE_ERROR - missing
+ ** table, missing row, non-blob/text in block column - indicate
+ ** backing store corruption. */
+ if( rc==SQLITE_ERROR ) rc = FTS5_CORRUPT;
+
+ if( rc==SQLITE_OK ){
+ u8 *aOut = 0; /* Read blob data into this buffer */
+ int nByte = sqlite3_blob_bytes(p->pReader);
+ int nAlloc = sizeof(Fts5Data) + nByte + FTS5_DATA_PADDING;
+ pRet = (Fts5Data*)sqlite3_malloc(nAlloc);
+ if( pRet ){
+ pRet->nn = nByte;
+ aOut = pRet->p = (u8*)&pRet[1];
+ }else{
+ rc = SQLITE_NOMEM;
+ }
+
+ if( rc==SQLITE_OK ){
+ rc = sqlite3_blob_read(p->pReader, aOut, nByte, 0);
+ }
+ if( rc!=SQLITE_OK ){
+ sqlite3_free(pRet);
+ pRet = 0;
+ }else{
+ /* TODO1: Fix this */
+ pRet->szLeaf = fts5GetU16(&pRet->p[2]);
+ }
+ }
+ p->rc = rc;
+ p->nRead++;
+ }
+
+ assert( (pRet==0)==(p->rc!=SQLITE_OK) );
+ return pRet;
+}
+
+/*
+** Release a reference to data record returned by an earlier call to
+** fts5DataRead().
+*/
+static void fts5DataRelease(Fts5Data *pData){
+ sqlite3_free(pData);
+}
+
+static int fts5IndexPrepareStmt(
+ Fts5Index *p,
+ sqlite3_stmt **ppStmt,
+ char *zSql
+){
+ if( p->rc==SQLITE_OK ){
+ if( zSql ){
+ p->rc = sqlite3_prepare_v2(p->pConfig->db, zSql, -1, ppStmt, 0);
+ }else{
+ p->rc = SQLITE_NOMEM;
+ }
+ }
+ sqlite3_free(zSql);
+ return p->rc;
+}
+
+
+/*
+** INSERT OR REPLACE a record into the %_data table.
+*/
+static void fts5DataWrite(Fts5Index *p, i64 iRowid, const u8 *pData, int nData){
+ if( p->rc!=SQLITE_OK ) return;
+
+ if( p->pWriter==0 ){
+ Fts5Config *pConfig = p->pConfig;
+ fts5IndexPrepareStmt(p, &p->pWriter, sqlite3_mprintf(
+ "REPLACE INTO '%q'.'%q_data'(id, block) VALUES(?,?)",
+ pConfig->zDb, pConfig->zName
+ ));
+ if( p->rc ) return;
+ }
+
+ sqlite3_bind_int64(p->pWriter, 1, iRowid);
+ sqlite3_bind_blob(p->pWriter, 2, pData, nData, SQLITE_STATIC);
+ sqlite3_step(p->pWriter);
+ p->rc = sqlite3_reset(p->pWriter);
+}
+
+/*
+** Execute the following SQL:
+**
+** DELETE FROM %_data WHERE id BETWEEN $iFirst AND $iLast
+*/
+static void fts5DataDelete(Fts5Index *p, i64 iFirst, i64 iLast){
+ if( p->rc!=SQLITE_OK ) return;
+
+ if( p->pDeleter==0 ){
+ int rc;
+ Fts5Config *pConfig = p->pConfig;
+ char *zSql = sqlite3_mprintf(
+ "DELETE FROM '%q'.'%q_data' WHERE id>=? AND id<=?",
+ pConfig->zDb, pConfig->zName
+ );
+ if( zSql==0 ){
+ rc = SQLITE_NOMEM;
+ }else{
+ rc = sqlite3_prepare_v2(pConfig->db, zSql, -1, &p->pDeleter, 0);
+ sqlite3_free(zSql);
+ }
+ if( rc!=SQLITE_OK ){
+ p->rc = rc;
+ return;
+ }
+ }
+
+ sqlite3_bind_int64(p->pDeleter, 1, iFirst);
+ sqlite3_bind_int64(p->pDeleter, 2, iLast);
+ sqlite3_step(p->pDeleter);
+ p->rc = sqlite3_reset(p->pDeleter);
+}
+
+/*
+** Remove all records associated with segment iSegid.
+*/
+static void fts5DataRemoveSegment(Fts5Index *p, int iSegid){
+ i64 iFirst = FTS5_SEGMENT_ROWID(iSegid, 0);
+ i64 iLast = FTS5_SEGMENT_ROWID(iSegid+1, 0)-1;
+ fts5DataDelete(p, iFirst, iLast);
+ if( p->pIdxDeleter==0 ){
+ Fts5Config *pConfig = p->pConfig;
+ fts5IndexPrepareStmt(p, &p->pIdxDeleter, sqlite3_mprintf(
+ "DELETE FROM '%q'.'%q_idx' WHERE segid=?",
+ pConfig->zDb, pConfig->zName
+ ));
+ }
+ if( p->rc==SQLITE_OK ){
+ sqlite3_bind_int(p->pIdxDeleter, 1, iSegid);
+ sqlite3_step(p->pIdxDeleter);
+ p->rc = sqlite3_reset(p->pIdxDeleter);
+ }
+}
+
+/*
+** Release a reference to an Fts5Structure object returned by an earlier
+** call to fts5StructureRead() or fts5StructureDecode().
+*/
+static void fts5StructureRelease(Fts5Structure *pStruct){
+ if( pStruct && 0>=(--pStruct->nRef) ){
+ int i;
+ assert( pStruct->nRef==0 );
+ for(i=0; i<pStruct->nLevel; i++){
+ sqlite3_free(pStruct->aLevel[i].aSeg);
+ }
+ sqlite3_free(pStruct);
+ }
+}
+
+static void fts5StructureRef(Fts5Structure *pStruct){
+ pStruct->nRef++;
+}
+
+/*
+** Deserialize and return the structure record currently stored in serialized
+** form within buffer pData/nData.
+**
+** The Fts5Structure.aLevel[] and each Fts5StructureLevel.aSeg[] array
+** are over-allocated by one slot. This allows the structure contents
+** to be more easily edited.
+**
+** If an error occurs, *ppOut is set to NULL and an SQLite error code
+** returned. Otherwise, *ppOut is set to point to the new object and
+** SQLITE_OK returned.
+*/
+static int fts5StructureDecode(
+ const u8 *pData, /* Buffer containing serialized structure */
+ int nData, /* Size of buffer pData in bytes */
+ int *piCookie, /* Configuration cookie value */
+ Fts5Structure **ppOut /* OUT: Deserialized object */
+){
+ int rc = SQLITE_OK;
+ int i = 0;
+ int iLvl;
+ int nLevel = 0;
+ int nSegment = 0;
+ int nByte; /* Bytes of space to allocate at pRet */
+ Fts5Structure *pRet = 0; /* Structure object to return */
+
+ /* Grab the cookie value */
+ if( piCookie ) *piCookie = sqlite3Fts5Get32(pData);
+ i = 4;
+
+ /* Read the total number of levels and segments from the start of the
+ ** structure record. */
+ i += fts5GetVarint32(&pData[i], nLevel);
+ i += fts5GetVarint32(&pData[i], nSegment);
+ nByte = (
+ sizeof(Fts5Structure) + /* Main structure */
+ sizeof(Fts5StructureLevel) * (nLevel-1) /* aLevel[] array */
+ );
+ pRet = (Fts5Structure*)sqlite3Fts5MallocZero(&rc, nByte);
+
+ if( pRet ){
+ pRet->nRef = 1;
+ pRet->nLevel = nLevel;
+ pRet->nSegment = nSegment;
+ i += sqlite3Fts5GetVarint(&pData[i], &pRet->nWriteCounter);
+
+ for(iLvl=0; rc==SQLITE_OK && iLvl<nLevel; iLvl++){
+ Fts5StructureLevel *pLvl = &pRet->aLevel[iLvl];
+ int nTotal;
+ int iSeg;
+
+ i += fts5GetVarint32(&pData[i], pLvl->nMerge);
+ i += fts5GetVarint32(&pData[i], nTotal);
+ assert( nTotal>=pLvl->nMerge );
+ pLvl->aSeg = (Fts5StructureSegment*)sqlite3Fts5MallocZero(&rc,
+ nTotal * sizeof(Fts5StructureSegment)
+ );
+
+ if( rc==SQLITE_OK ){
+ pLvl->nSeg = nTotal;
+ for(iSeg=0; iSeg<nTotal; iSeg++){
+ i += fts5GetVarint32(&pData[i], pLvl->aSeg[iSeg].iSegid);
+ i += fts5GetVarint32(&pData[i], pLvl->aSeg[iSeg].pgnoFirst);
+ i += fts5GetVarint32(&pData[i], pLvl->aSeg[iSeg].pgnoLast);
+ }
+ }else{
+ fts5StructureRelease(pRet);
+ pRet = 0;
+ }
+ }
+ }
+
+ *ppOut = pRet;
+ return rc;
+}
+
+/*
+**
+*/
+static void fts5StructureAddLevel(int *pRc, Fts5Structure **ppStruct){
+ if( *pRc==SQLITE_OK ){
+ Fts5Structure *pStruct = *ppStruct;
+ int nLevel = pStruct->nLevel;
+ int nByte = (
+ sizeof(Fts5Structure) + /* Main structure */
+ sizeof(Fts5StructureLevel) * (nLevel+1) /* aLevel[] array */
+ );
+
+ pStruct = sqlite3_realloc(pStruct, nByte);
+ if( pStruct ){
+ memset(&pStruct->aLevel[nLevel], 0, sizeof(Fts5StructureLevel));
+ pStruct->nLevel++;
+ *ppStruct = pStruct;
+ }else{
+ *pRc = SQLITE_NOMEM;
+ }
+ }
+}
+
+/*
+** Extend level iLvl so that there is room for at least nExtra more
+** segments.
+*/
+static void fts5StructureExtendLevel(
+ int *pRc,
+ Fts5Structure *pStruct,
+ int iLvl,
+ int nExtra,
+ int bInsert
+){
+ if( *pRc==SQLITE_OK ){
+ Fts5StructureLevel *pLvl = &pStruct->aLevel[iLvl];
+ Fts5StructureSegment *aNew;
+ int nByte;
+
+ nByte = (pLvl->nSeg + nExtra) * sizeof(Fts5StructureSegment);
+ aNew = sqlite3_realloc(pLvl->aSeg, nByte);
+ if( aNew ){
+ if( bInsert==0 ){
+ memset(&aNew[pLvl->nSeg], 0, sizeof(Fts5StructureSegment) * nExtra);
+ }else{
+ int nMove = pLvl->nSeg * sizeof(Fts5StructureSegment);
+ memmove(&aNew[nExtra], aNew, nMove);
+ memset(aNew, 0, sizeof(Fts5StructureSegment) * nExtra);
+ }
+ pLvl->aSeg = aNew;
+ }else{
+ *pRc = SQLITE_NOMEM;
+ }
+ }
+}
+
+/*
+** Read, deserialize and return the structure record.
+**
+** The Fts5Structure.aLevel[] and each Fts5StructureLevel.aSeg[] array
+** are over-allocated as described for function fts5StructureDecode()
+** above.
+**
+** If an error occurs, NULL is returned and an error code left in the
+** Fts5Index handle. If an error has already occurred when this function
+** is called, it is a no-op.
+*/
+static Fts5Structure *fts5StructureRead(Fts5Index *p){
+ Fts5Config *pConfig = p->pConfig;
+ Fts5Structure *pRet = 0; /* Object to return */
+ int iCookie; /* Configuration cookie */
+ Fts5Data *pData;
+
+ pData = fts5DataRead(p, FTS5_STRUCTURE_ROWID);
+ if( p->rc ) return 0;
+ /* TODO: Do we need this if the leaf-index is appended? Probably... */
+ memset(&pData->p[pData->nn], 0, FTS5_DATA_PADDING);
+ p->rc = fts5StructureDecode(pData->p, pData->nn, &iCookie, &pRet);
+ if( p->rc==SQLITE_OK && pConfig->iCookie!=iCookie ){
+ p->rc = sqlite3Fts5ConfigLoad(pConfig, iCookie);
+ }
+
+ fts5DataRelease(pData);
+ if( p->rc!=SQLITE_OK ){
+ fts5StructureRelease(pRet);
+ pRet = 0;
+ }
+ return pRet;
+}
+
+/*
+** Return the total number of segments in index structure pStruct. This
+** function is only ever used as part of assert() conditions.
+*/
+#ifdef SQLITE_DEBUG
+static int fts5StructureCountSegments(Fts5Structure *pStruct){
+ int nSegment = 0; /* Total number of segments */
+ if( pStruct ){
+ int iLvl; /* Used to iterate through levels */
+ for(iLvl=0; iLvl<pStruct->nLevel; iLvl++){
+ nSegment += pStruct->aLevel[iLvl].nSeg;
+ }
+ }
+
+ return nSegment;
+}
+#endif
+
+#define fts5BufferSafeAppendBlob(pBuf, pBlob, nBlob) { \
+ assert( (pBuf)->nSpace>=((pBuf)->n+nBlob) ); \
+ memcpy(&(pBuf)->p[(pBuf)->n], pBlob, nBlob); \
+ (pBuf)->n += nBlob; \
+}
+
+#define fts5BufferSafeAppendVarint(pBuf, iVal) { \
+ (pBuf)->n += sqlite3Fts5PutVarint(&(pBuf)->p[(pBuf)->n], (iVal)); \
+ assert( (pBuf)->nSpace>=(pBuf)->n ); \
+}
+
+
+/*
+** Serialize and store the "structure" record.
+**
+** If an error occurs, leave an error code in the Fts5Index object. If an
+** error has already occurred, this function is a no-op.
+*/
+static void fts5StructureWrite(Fts5Index *p, Fts5Structure *pStruct){
+ if( p->rc==SQLITE_OK ){
+ Fts5Buffer buf; /* Buffer to serialize record into */
+ int iLvl; /* Used to iterate through levels */
+ int iCookie; /* Cookie value to store */
+
+ assert( pStruct->nSegment==fts5StructureCountSegments(pStruct) );
+ memset(&buf, 0, sizeof(Fts5Buffer));
+
+ /* Append the current configuration cookie */
+ iCookie = p->pConfig->iCookie;
+ if( iCookie<0 ) iCookie = 0;
+
+ if( 0==sqlite3Fts5BufferSize(&p->rc, &buf, 4+9+9+9) ){
+ sqlite3Fts5Put32(buf.p, iCookie);
+ buf.n = 4;
+ fts5BufferSafeAppendVarint(&buf, pStruct->nLevel);
+ fts5BufferSafeAppendVarint(&buf, pStruct->nSegment);
+ fts5BufferSafeAppendVarint(&buf, (i64)pStruct->nWriteCounter);
+ }
+
+ for(iLvl=0; iLvl<pStruct->nLevel; iLvl++){
+ int iSeg; /* Used to iterate through segments */
+ Fts5StructureLevel *pLvl = &pStruct->aLevel[iLvl];
+ fts5BufferAppendVarint(&p->rc, &buf, pLvl->nMerge);
+ fts5BufferAppendVarint(&p->rc, &buf, pLvl->nSeg);
+ assert( pLvl->nMerge<=pLvl->nSeg );
+
+ for(iSeg=0; iSeg<pLvl->nSeg; iSeg++){
+ fts5BufferAppendVarint(&p->rc, &buf, pLvl->aSeg[iSeg].iSegid);
+ fts5BufferAppendVarint(&p->rc, &buf, pLvl->aSeg[iSeg].pgnoFirst);
+ fts5BufferAppendVarint(&p->rc, &buf, pLvl->aSeg[iSeg].pgnoLast);
+ }
+ }
+
+ fts5DataWrite(p, FTS5_STRUCTURE_ROWID, buf.p, buf.n);
+ fts5BufferFree(&buf);
+ }
+}
+
+#if 0
+static void fts5DebugStructure(int*,Fts5Buffer*,Fts5Structure*);
+static void fts5PrintStructure(const char *zCaption, Fts5Structure *pStruct){
+ int rc = SQLITE_OK;
+ Fts5Buffer buf;
+ memset(&buf, 0, sizeof(buf));
+ fts5DebugStructure(&rc, &buf, pStruct);
+ fprintf(stdout, "%s: %s\n", zCaption, buf.p);
+ fflush(stdout);
+ fts5BufferFree(&buf);
+}
+#else
+# define fts5PrintStructure(x,y)
+#endif
+
+static int fts5SegmentSize(Fts5StructureSegment *pSeg){
+ return 1 + pSeg->pgnoLast - pSeg->pgnoFirst;
+}
+
+/*
+** Return a copy of index structure pStruct. Except, promote as many
+** segments as possible to level iPromote. If an OOM occurs, NULL is
+** returned.
+*/
+static void fts5StructurePromoteTo(
+ Fts5Index *p,
+ int iPromote,
+ int szPromote,
+ Fts5Structure *pStruct
+){
+ int il, is;
+ Fts5StructureLevel *pOut = &pStruct->aLevel[iPromote];
+
+ if( pOut->nMerge==0 ){
+ for(il=iPromote+1; il<pStruct->nLevel; il++){
+ Fts5StructureLevel *pLvl = &pStruct->aLevel[il];
+ if( pLvl->nMerge ) return;
+ for(is=pLvl->nSeg-1; is>=0; is--){
+ int sz = fts5SegmentSize(&pLvl->aSeg[is]);
+ if( sz>szPromote ) return;
+ fts5StructureExtendLevel(&p->rc, pStruct, iPromote, 1, 1);
+ if( p->rc ) return;
+ memcpy(pOut->aSeg, &pLvl->aSeg[is], sizeof(Fts5StructureSegment));
+ pOut->nSeg++;
+ pLvl->nSeg--;
+ }
+ }
+ }
+}
+
+/*
+** A new segment has just been written to level iLvl of index structure
+** pStruct. This function determines if any segments should be promoted
+** as a result. Segments are promoted in two scenarios:
+**
+** a) If the segment just written is smaller than one or more segments
+** within the previous populated level, it is promoted to the previous
+** populated level.
+**
+** b) If the segment just written is larger than the newest segment on
+** the next populated level, then that segment, and any other adjacent
+** segments that are also smaller than the one just written, are
+** promoted.
+**
+** If one or more segments are promoted, the structure object is updated
+** to reflect this.
+*/
+static void fts5StructurePromote(
+ Fts5Index *p, /* FTS5 backend object */
+ int iLvl, /* Index level just updated */
+ Fts5Structure *pStruct /* Index structure */
+){
+ if( p->rc==SQLITE_OK ){
+ int iTst;
+ int iPromote = -1;
+ int szPromote = 0; /* Promote anything this size or smaller */
+ Fts5StructureSegment *pSeg; /* Segment just written */
+ int szSeg; /* Size of segment just written */
+ int nSeg = pStruct->aLevel[iLvl].nSeg;
+
+ if( nSeg==0 ) return;
+ pSeg = &pStruct->aLevel[iLvl].aSeg[pStruct->aLevel[iLvl].nSeg-1];
+ szSeg = (1 + pSeg->pgnoLast - pSeg->pgnoFirst);
+
+ /* Check for condition (a) */
+ for(iTst=iLvl-1; iTst>=0 && pStruct->aLevel[iTst].nSeg==0; iTst--);
+ if( iTst>=0 ){
+ int i;
+ int szMax = 0;
+ Fts5StructureLevel *pTst = &pStruct->aLevel[iTst];
+ assert( pTst->nMerge==0 );
+ for(i=0; i<pTst->nSeg; i++){
+ int sz = pTst->aSeg[i].pgnoLast - pTst->aSeg[i].pgnoFirst + 1;
+ if( sz>szMax ) szMax = sz;
+ }
+ if( szMax>=szSeg ){
+ /* Condition (a) is true. Promote the newest segment on level
+ ** iLvl to level iTst. */
+ iPromote = iTst;
+ szPromote = szMax;
+ }
+ }
+
+ /* If condition (a) is not met, assume (b) is true. StructurePromoteTo()
+ ** is a no-op if it is not. */
+ if( iPromote<0 ){
+ iPromote = iLvl;
+ szPromote = szSeg;
+ }
+ fts5StructurePromoteTo(p, iPromote, szPromote, pStruct);
+ }
+}
+
+
+/*
+** Advance the iterator passed as the only argument. If the end of the
+** doclist-index page is reached, return non-zero.
+*/
+static int fts5DlidxLvlNext(Fts5DlidxLvl *pLvl){
+ Fts5Data *pData = pLvl->pData;
+
+ if( pLvl->iOff==0 ){
+ assert( pLvl->bEof==0 );
+ pLvl->iOff = 1;
+ pLvl->iOff += fts5GetVarint32(&pData->p[1], pLvl->iLeafPgno);
+ pLvl->iOff += fts5GetVarint(&pData->p[pLvl->iOff], (u64*)&pLvl->iRowid);
+ pLvl->iFirstOff = pLvl->iOff;
+ }else{
+ int iOff;
+ for(iOff=pLvl->iOff; iOff<pData->nn; iOff++){
+ if( pData->p[iOff] ) break;
+ }
+
+ if( iOff<pData->nn ){
+ i64 iVal;
+ pLvl->iLeafPgno += (iOff - pLvl->iOff) + 1;
+ iOff += fts5GetVarint(&pData->p[iOff], (u64*)&iVal);
+ pLvl->iRowid += iVal;
+ pLvl->iOff = iOff;
+ }else{
+ pLvl->bEof = 1;
+ }
+ }
+
+ return pLvl->bEof;
+}
+
+/*
+** Advance the iterator passed as the only argument.
+*/
+static int fts5DlidxIterNextR(Fts5Index *p, Fts5DlidxIter *pIter, int iLvl){
+ Fts5DlidxLvl *pLvl = &pIter->aLvl[iLvl];
+
+ assert( iLvl<pIter->nLvl );
+ if( fts5DlidxLvlNext(pLvl) ){
+ if( (iLvl+1) < pIter->nLvl ){
+ fts5DlidxIterNextR(p, pIter, iLvl+1);
+ if( pLvl[1].bEof==0 ){
+ fts5DataRelease(pLvl->pData);
+ memset(pLvl, 0, sizeof(Fts5DlidxLvl));
+ pLvl->pData = fts5DataRead(p,
+ FTS5_DLIDX_ROWID(pIter->iSegid, iLvl, pLvl[1].iLeafPgno)
+ );
+ if( pLvl->pData ) fts5DlidxLvlNext(pLvl);
+ }
+ }
+ }
+
+ return pIter->aLvl[0].bEof;
+}
+static int fts5DlidxIterNext(Fts5Index *p, Fts5DlidxIter *pIter){
+ return fts5DlidxIterNextR(p, pIter, 0);
+}
+
+/*
+** The iterator passed as the first argument has the following fields set
+** as follows. This function sets up the rest of the iterator so that it
+** points to the first rowid in the doclist-index.
+**
+** pData:
+** pointer to doclist-index record,
+**
+** When this function is called pIter->iLeafPgno is the page number the
+** doclist is associated with (the one featuring the term).
+*/
+static int fts5DlidxIterFirst(Fts5DlidxIter *pIter){
+ int i;
+ for(i=0; i<pIter->nLvl; i++){
+ fts5DlidxLvlNext(&pIter->aLvl[i]);
+ }
+ return pIter->aLvl[0].bEof;
+}
+
+
+static int fts5DlidxIterEof(Fts5Index *p, Fts5DlidxIter *pIter){
+ return p->rc!=SQLITE_OK || pIter->aLvl[0].bEof;
+}
+
+static void fts5DlidxIterLast(Fts5Index *p, Fts5DlidxIter *pIter){
+ int i;
+
+ /* Advance each level to the last entry on the last page */
+ for(i=pIter->nLvl-1; p->rc==SQLITE_OK && i>=0; i--){
+ Fts5DlidxLvl *pLvl = &pIter->aLvl[i];
+ while( fts5DlidxLvlNext(pLvl)==0 );
+ pLvl->bEof = 0;
+
+ if( i>0 ){
+ Fts5DlidxLvl *pChild = &pLvl[-1];
+ fts5DataRelease(pChild->pData);
+ memset(pChild, 0, sizeof(Fts5DlidxLvl));
+ pChild->pData = fts5DataRead(p,
+ FTS5_DLIDX_ROWID(pIter->iSegid, i-1, pLvl->iLeafPgno)
+ );
+ }
+ }
+}
+
+/*
+** Move the iterator passed as the only argument to the previous entry.
+*/
+static int fts5DlidxLvlPrev(Fts5DlidxLvl *pLvl){
+ int iOff = pLvl->iOff;
+
+ assert( pLvl->bEof==0 );
+ if( iOff<=pLvl->iFirstOff ){
+ pLvl->bEof = 1;
+ }else{
+ u8 *a = pLvl->pData->p;
+ i64 iVal;
+ int iLimit;
+ int ii;
+ int nZero = 0;
+
+ /* Currently iOff points to the first byte of a varint. This block
+ ** decrements iOff until it points to the first byte of the previous
+ ** varint. Taking care not to read any memory locations that occur
+ ** before the buffer in memory. */
+ iLimit = (iOff>9 ? iOff-9 : 0);
+ for(iOff--; iOff>iLimit; iOff--){
+ if( (a[iOff-1] & 0x80)==0 ) break;
+ }
+
+ fts5GetVarint(&a[iOff], (u64*)&iVal);
+ pLvl->iRowid -= iVal;
+ pLvl->iLeafPgno--;
+
+ /* Skip backwards past any 0x00 varints. */
+ for(ii=iOff-1; ii>=pLvl->iFirstOff && a[ii]==0x00; ii--){
+ nZero++;
+ }
+ if( ii>=pLvl->iFirstOff && (a[ii] & 0x80) ){
+ /* The byte immediately before the last 0x00 byte has the 0x80 bit
+ ** set. So the last 0x00 is only a varint 0 if there are 8 more 0x80
+ ** bytes before a[ii]. */
+ int bZero = 0; /* True if last 0x00 counts */
+ if( (ii-8)>=pLvl->iFirstOff ){
+ int j;
+ for(j=1; j<=8 && (a[ii-j] & 0x80); j++);
+ bZero = (j>8);
+ }
+ if( bZero==0 ) nZero--;
+ }
+ pLvl->iLeafPgno -= nZero;
+ pLvl->iOff = iOff - nZero;
+ }
+
+ return pLvl->bEof;
+}
+
+static int fts5DlidxIterPrevR(Fts5Index *p, Fts5DlidxIter *pIter, int iLvl){
+ Fts5DlidxLvl *pLvl = &pIter->aLvl[iLvl];
+
+ assert( iLvl<pIter->nLvl );
+ if( fts5DlidxLvlPrev(pLvl) ){
+ if( (iLvl+1) < pIter->nLvl ){
+ fts5DlidxIterPrevR(p, pIter, iLvl+1);
+ if( pLvl[1].bEof==0 ){
+ fts5DataRelease(pLvl->pData);
+ memset(pLvl, 0, sizeof(Fts5DlidxLvl));
+ pLvl->pData = fts5DataRead(p,
+ FTS5_DLIDX_ROWID(pIter->iSegid, iLvl, pLvl[1].iLeafPgno)
+ );
+ if( pLvl->pData ){
+ while( fts5DlidxLvlNext(pLvl)==0 );
+ pLvl->bEof = 0;
+ }
+ }
+ }
+ }
+
+ return pIter->aLvl[0].bEof;
+}
+static int fts5DlidxIterPrev(Fts5Index *p, Fts5DlidxIter *pIter){
+ return fts5DlidxIterPrevR(p, pIter, 0);
+}
+
+/*
+** Free a doclist-index iterator object allocated by fts5DlidxIterInit().
+*/
+static void fts5DlidxIterFree(Fts5DlidxIter *pIter){
+ if( pIter ){
+ int i;
+ for(i=0; i<pIter->nLvl; i++){
+ fts5DataRelease(pIter->aLvl[i].pData);
+ }
+ sqlite3_free(pIter);
+ }
+}
+
+static Fts5DlidxIter *fts5DlidxIterInit(
+ Fts5Index *p, /* Fts5 Backend to iterate within */
+ int bRev, /* True for ORDER BY ASC */
+ int iSegid, /* Segment id */
+ int iLeafPg /* Leaf page number to load dlidx for */
+){
+ Fts5DlidxIter *pIter = 0;
+ int i;
+ int bDone = 0;
+
+ for(i=0; p->rc==SQLITE_OK && bDone==0; i++){
+ int nByte = sizeof(Fts5DlidxIter) + i * sizeof(Fts5DlidxLvl);
+ Fts5DlidxIter *pNew;
+
+ pNew = (Fts5DlidxIter*)sqlite3_realloc(pIter, nByte);
+ if( pNew==0 ){
+ p->rc = SQLITE_NOMEM;
+ }else{
+ i64 iRowid = FTS5_DLIDX_ROWID(iSegid, i, iLeafPg);
+ Fts5DlidxLvl *pLvl = &pNew->aLvl[i];
+ pIter = pNew;
+ memset(pLvl, 0, sizeof(Fts5DlidxLvl));
+ pLvl->pData = fts5DataRead(p, iRowid);
+ if( pLvl->pData && (pLvl->pData->p[0] & 0x0001)==0 ){
+ bDone = 1;
+ }
+ pIter->nLvl = i+1;
+ }
+ }
+
+ if( p->rc==SQLITE_OK ){
+ pIter->iSegid = iSegid;
+ if( bRev==0 ){
+ fts5DlidxIterFirst(pIter);
+ }else{
+ fts5DlidxIterLast(p, pIter);
+ }
+ }
+
+ if( p->rc!=SQLITE_OK ){
+ fts5DlidxIterFree(pIter);
+ pIter = 0;
+ }
+
+ return pIter;
+}
+
+static i64 fts5DlidxIterRowid(Fts5DlidxIter *pIter){
+ return pIter->aLvl[0].iRowid;
+}
+static int fts5DlidxIterPgno(Fts5DlidxIter *pIter){
+ return pIter->aLvl[0].iLeafPgno;
+}
+
+/*
+** Load the next leaf page into the segment iterator.
+*/
+static void fts5SegIterNextPage(
+ Fts5Index *p, /* FTS5 backend object */
+ Fts5SegIter *pIter /* Iterator to advance to next page */
+){
+ Fts5Data *pLeaf;
+ Fts5StructureSegment *pSeg = pIter->pSeg;
+ fts5DataRelease(pIter->pLeaf);
+ pIter->iLeafPgno++;
+ if( pIter->pNextLeaf ){
+ pIter->pLeaf = pIter->pNextLeaf;
+ pIter->pNextLeaf = 0;
+ }else if( pIter->iLeafPgno<=pSeg->pgnoLast ){
+ pIter->pLeaf = fts5DataRead(p,
+ FTS5_SEGMENT_ROWID(pSeg->iSegid, pIter->iLeafPgno)
+ );
+ }else{
+ pIter->pLeaf = 0;
+ }
+ pLeaf = pIter->pLeaf;
+
+ if( pLeaf ){
+ pIter->iPgidxOff = pLeaf->szLeaf;
+ if( fts5LeafIsTermless(pLeaf) ){
+ pIter->iEndofDoclist = pLeaf->nn+1;
+ }else{
+ pIter->iPgidxOff += fts5GetVarint32(&pLeaf->p[pIter->iPgidxOff],
+ pIter->iEndofDoclist
+ );
+ }
+ }
+}
+
+/*
+** Argument p points to a buffer containing a varint to be interpreted as a
+** position list size field. Read the varint and return the number of bytes
+** read. Before returning, set *pnSz to the number of bytes in the position
+** list, and *pbDel to true if the delete flag is set, or false otherwise.
+*/
+static int fts5GetPoslistSize(const u8 *p, int *pnSz, int *pbDel){
+ int nSz;
+ int n = 0;
+ fts5FastGetVarint32(p, n, nSz);
+ assert_nc( nSz>=0 );
+ *pnSz = nSz/2;
+ *pbDel = nSz & 0x0001;
+ return n;
+}
+
+/*
+** Fts5SegIter.iLeafOffset currently points to the first byte of a
+** position-list size field. Read the value of the field and store it
+** in the following variables:
+**
+** Fts5SegIter.nPos
+** Fts5SegIter.bDel
+**
+** Leave Fts5SegIter.iLeafOffset pointing to the first byte of the
+** position list content (if any).
+*/
+static void fts5SegIterLoadNPos(Fts5Index *p, Fts5SegIter *pIter){
+ if( p->rc==SQLITE_OK ){
+ int iOff = pIter->iLeafOffset; /* Offset to read at */
+ int nSz;
+ ASSERT_SZLEAF_OK(pIter->pLeaf);
+ fts5FastGetVarint32(pIter->pLeaf->p, iOff, nSz);
+ pIter->bDel = (nSz & 0x0001);
+ pIter->nPos = nSz>>1;
+ pIter->iLeafOffset = iOff;
+ assert_nc( pIter->nPos>=0 );
+ }
+}
+
+static void fts5SegIterLoadRowid(Fts5Index *p, Fts5SegIter *pIter){
+ u8 *a = pIter->pLeaf->p; /* Buffer to read data from */
+ int iOff = pIter->iLeafOffset;
+
+ ASSERT_SZLEAF_OK(pIter->pLeaf);
+ if( iOff>=pIter->pLeaf->szLeaf ){
+ fts5SegIterNextPage(p, pIter);
+ if( pIter->pLeaf==0 ){
+ if( p->rc==SQLITE_OK ) p->rc = FTS5_CORRUPT;
+ return;
+ }
+ iOff = 4;
+ a = pIter->pLeaf->p;
+ }
+ iOff += sqlite3Fts5GetVarint(&a[iOff], (u64*)&pIter->iRowid);
+ pIter->iLeafOffset = iOff;
+}
+
+/*
+** Fts5SegIter.iLeafOffset currently points to the first byte of the
+** "nSuffix" field of a term. Function parameter nKeep contains the value
+** of the "nPrefix" field (if there was one - it is passed 0 if this is
+** the first term in the segment).
+**
+** This function populates:
+**
+** Fts5SegIter.term
+** Fts5SegIter.rowid
+**
+** accordingly and leaves (Fts5SegIter.iLeafOffset) set to the content of
+** the first position list. The position list belonging to document
+** (Fts5SegIter.iRowid).
+*/
+static void fts5SegIterLoadTerm(Fts5Index *p, Fts5SegIter *pIter, int nKeep){
+ u8 *a = pIter->pLeaf->p; /* Buffer to read data from */
+ int iOff = pIter->iLeafOffset; /* Offset to read at */
+ int nNew; /* Bytes of new data */
+
+ iOff += fts5GetVarint32(&a[iOff], nNew);
+ pIter->term.n = nKeep;
+ fts5BufferAppendBlob(&p->rc, &pIter->term, nNew, &a[iOff]);
+ iOff += nNew;
+ pIter->iTermLeafOffset = iOff;
+ pIter->iTermLeafPgno = pIter->iLeafPgno;
+ pIter->iLeafOffset = iOff;
+
+ if( pIter->iPgidxOff>=pIter->pLeaf->nn ){
+ pIter->iEndofDoclist = pIter->pLeaf->nn+1;
+ }else{
+ int nExtra;
+ pIter->iPgidxOff += fts5GetVarint32(&a[pIter->iPgidxOff], nExtra);
+ pIter->iEndofDoclist += nExtra;
+ }
+
+ fts5SegIterLoadRowid(p, pIter);
+}
+
+/*
+** Initialize the iterator object pIter to iterate through the entries in
+** segment pSeg. The iterator is left pointing to the first entry when
+** this function returns.
+**
+** If an error occurs, Fts5Index.rc is set to an appropriate error code. If
+** an error has already occurred when this function is called, it is a no-op.
+*/
+static void fts5SegIterInit(
+ Fts5Index *p, /* FTS index object */
+ Fts5StructureSegment *pSeg, /* Description of segment */
+ Fts5SegIter *pIter /* Object to populate */
+){
+ if( pSeg->pgnoFirst==0 ){
+ /* This happens if the segment is being used as an input to an incremental
+ ** merge and all data has already been "trimmed". See function
+ ** fts5TrimSegments() for details. In this case leave the iterator empty.
+ ** The caller will see the (pIter->pLeaf==0) and assume the iterator is
+ ** at EOF already. */
+ assert( pIter->pLeaf==0 );
+ return;
+ }
+
+ if( p->rc==SQLITE_OK ){
+ memset(pIter, 0, sizeof(*pIter));
+ pIter->pSeg = pSeg;
+ pIter->iLeafPgno = pSeg->pgnoFirst-1;
+ fts5SegIterNextPage(p, pIter);
+ }
+
+ if( p->rc==SQLITE_OK ){
+ pIter->iLeafOffset = 4;
+ assert_nc( pIter->pLeaf->nn>4 );
+ assert( fts5LeafFirstTermOff(pIter->pLeaf)==4 );
+ pIter->iPgidxOff = pIter->pLeaf->szLeaf+1;
+ fts5SegIterLoadTerm(p, pIter, 0);
+ fts5SegIterLoadNPos(p, pIter);
+ }
+}
+
+/*
+** This function is only ever called on iterators created by calls to
+** Fts5IndexQuery() with the FTS5INDEX_QUERY_DESC flag set.
+**
+** The iterator is in an unusual state when this function is called: the
+** Fts5SegIter.iLeafOffset variable is set to the offset of the start of
+** the position-list size field for the first relevant rowid on the page.
+** Fts5SegIter.rowid is set, but nPos and bDel are not.
+**
+** This function advances the iterator so that it points to the last
+** relevant rowid on the page and, if necessary, initializes the
+** aRowidOffset[] and iRowidOffset variables. At this point the iterator
+** is in its regular state - Fts5SegIter.iLeafOffset points to the first
+** byte of the position list content associated with said rowid.
+*/
+static void fts5SegIterReverseInitPage(Fts5Index *p, Fts5SegIter *pIter){
+ int n = pIter->pLeaf->szLeaf;
+ int i = pIter->iLeafOffset;
+ u8 *a = pIter->pLeaf->p;
+ int iRowidOffset = 0;
+
+ if( n>pIter->iEndofDoclist ){
+ n = pIter->iEndofDoclist;
+ }
+
+ ASSERT_SZLEAF_OK(pIter->pLeaf);
+ while( 1 ){
+ i64 iDelta = 0;
+ int nPos;
+ int bDummy;
+
+ i += fts5GetPoslistSize(&a[i], &nPos, &bDummy);
+ i += nPos;
+ if( i>=n ) break;
+ i += fts5GetVarint(&a[i], (u64*)&iDelta);
+ pIter->iRowid += iDelta;
+
+ if( iRowidOffset>=pIter->nRowidOffset ){
+ int nNew = pIter->nRowidOffset + 8;
+ int *aNew = (int*)sqlite3_realloc(pIter->aRowidOffset, nNew*sizeof(int));
+ if( aNew==0 ){
+ p->rc = SQLITE_NOMEM;
+ break;
+ }
+ pIter->aRowidOffset = aNew;
+ pIter->nRowidOffset = nNew;
+ }
+
+ pIter->aRowidOffset[iRowidOffset++] = pIter->iLeafOffset;
+ pIter->iLeafOffset = i;
+ }
+ pIter->iRowidOffset = iRowidOffset;
+ fts5SegIterLoadNPos(p, pIter);
+}
+
+/*
+**
+*/
+static void fts5SegIterReverseNewPage(Fts5Index *p, Fts5SegIter *pIter){
+ assert( pIter->flags & FTS5_SEGITER_REVERSE );
+ assert( pIter->flags & FTS5_SEGITER_ONETERM );
+
+ fts5DataRelease(pIter->pLeaf);
+ pIter->pLeaf = 0;
+ while( p->rc==SQLITE_OK && pIter->iLeafPgno>pIter->iTermLeafPgno ){
+ Fts5Data *pNew;
+ pIter->iLeafPgno--;
+ pNew = fts5DataRead(p, FTS5_SEGMENT_ROWID(
+ pIter->pSeg->iSegid, pIter->iLeafPgno
+ ));
+ if( pNew ){
+ /* iTermLeafOffset may be equal to szLeaf if the term is the last
+ ** thing on the page - i.e. the first rowid is on the following page.
+ ** In this case leave pIter->pLeaf==0, this iterator is at EOF. */
+ if( pIter->iLeafPgno==pIter->iTermLeafPgno ){
+ assert( pIter->pLeaf==0 );
+ if( pIter->iTermLeafOffset<pNew->szLeaf ){
+ pIter->pLeaf = pNew;
+ pIter->iLeafOffset = pIter->iTermLeafOffset;
+ }
+ }else{
+ int iRowidOff;
+ iRowidOff = fts5LeafFirstRowidOff(pNew);
+ if( iRowidOff ){
+ pIter->pLeaf = pNew;
+ pIter->iLeafOffset = iRowidOff;
+ }
+ }
+
+ if( pIter->pLeaf ){
+ u8 *a = &pIter->pLeaf->p[pIter->iLeafOffset];
+ pIter->iLeafOffset += fts5GetVarint(a, (u64*)&pIter->iRowid);
+ break;
+ }else{
+ fts5DataRelease(pNew);
+ }
+ }
+ }
+
+ if( pIter->pLeaf ){
+ pIter->iEndofDoclist = pIter->pLeaf->nn+1;
+ fts5SegIterReverseInitPage(p, pIter);
+ }
+}
+
+/*
+** Return true if the iterator passed as the second argument currently
+** points to a delete marker. A delete marker is an entry with a 0 byte
+** position-list.
+*/
+static int fts5MultiIterIsEmpty(Fts5Index *p, Fts5IndexIter *pIter){
+ Fts5SegIter *pSeg = &pIter->aSeg[pIter->aFirst[1].iFirst];
+ return (p->rc==SQLITE_OK && pSeg->pLeaf && pSeg->nPos==0);
+}
+
+/*
+** Advance iterator pIter to the next entry.
+**
+** If an error occurs, Fts5Index.rc is set to an appropriate error code. It
+** is not considered an error if the iterator reaches EOF. If an error has
+** already occurred when this function is called, it is a no-op.
+*/
+static void fts5SegIterNext(
+ Fts5Index *p, /* FTS5 backend object */
+ Fts5SegIter *pIter, /* Iterator to advance */
+ int *pbNewTerm /* OUT: Set for new term */
+){
+ assert( pbNewTerm==0 || *pbNewTerm==0 );
+ if( p->rc==SQLITE_OK ){
+ if( pIter->flags & FTS5_SEGITER_REVERSE ){
+ assert( pIter->pNextLeaf==0 );
+ if( pIter->iRowidOffset>0 ){
+ u8 *a = pIter->pLeaf->p;
+ int iOff;
+ int nPos;
+ int bDummy;
+ i64 iDelta;
+
+ pIter->iRowidOffset--;
+ pIter->iLeafOffset = iOff = pIter->aRowidOffset[pIter->iRowidOffset];
+ iOff += fts5GetPoslistSize(&a[iOff], &nPos, &bDummy);
+ iOff += nPos;
+ fts5GetVarint(&a[iOff], (u64*)&iDelta);
+ pIter->iRowid -= iDelta;
+ fts5SegIterLoadNPos(p, pIter);
+ }else{
+ fts5SegIterReverseNewPage(p, pIter);
+ }
+ }else{
+ Fts5Data *pLeaf = pIter->pLeaf;
+ int iOff;
+ int bNewTerm = 0;
+ int nKeep = 0;
+
+ /* Search for the end of the position list within the current page. */
+ u8 *a = pLeaf->p;
+ int n = pLeaf->szLeaf;
+
+ ASSERT_SZLEAF_OK(pLeaf);
+ iOff = pIter->iLeafOffset + pIter->nPos;
+
+ if( iOff<n ){
+ /* The next entry is on the current page. */
+ assert_nc( iOff<=pIter->iEndofDoclist );
+ if( iOff>=pIter->iEndofDoclist ){
+ bNewTerm = 1;
+ if( iOff!=fts5LeafFirstTermOff(pLeaf) ){
+ iOff += fts5GetVarint32(&a[iOff], nKeep);
+ }
+ }else{
+ u64 iDelta;
+ iOff += sqlite3Fts5GetVarint(&a[iOff], &iDelta);
+ pIter->iRowid += iDelta;
+ assert_nc( iDelta>0 );
+ }
+ pIter->iLeafOffset = iOff;
+
+ }else if( pIter->pSeg==0 ){
+ const u8 *pList = 0;
+ const char *zTerm = 0;
+ int nList = 0;
+ assert( (pIter->flags & FTS5_SEGITER_ONETERM) || pbNewTerm );
+ if( 0==(pIter->flags & FTS5_SEGITER_ONETERM) ){
+ sqlite3Fts5HashScanNext(p->pHash);
+ sqlite3Fts5HashScanEntry(p->pHash, &zTerm, &pList, &nList);
+ }
+ if( pList==0 ){
+ fts5DataRelease(pIter->pLeaf);
+ pIter->pLeaf = 0;
+ }else{
+ pIter->pLeaf->p = (u8*)pList;
+ pIter->pLeaf->nn = nList;
+ pIter->pLeaf->szLeaf = nList;
+ pIter->iEndofDoclist = nList+1;
+ sqlite3Fts5BufferSet(&p->rc, &pIter->term, (int)strlen(zTerm),
+ (u8*)zTerm);
+ pIter->iLeafOffset = fts5GetVarint(pList, (u64*)&pIter->iRowid);
+ *pbNewTerm = 1;
+ }
+ }else{
+ iOff = 0;
+ /* Next entry is not on the current page */
+ while( iOff==0 ){
+ fts5SegIterNextPage(p, pIter);
+ pLeaf = pIter->pLeaf;
+ if( pLeaf==0 ) break;
+ ASSERT_SZLEAF_OK(pLeaf);
+ if( (iOff = fts5LeafFirstRowidOff(pLeaf)) && iOff<pLeaf->szLeaf ){
+ iOff += sqlite3Fts5GetVarint(&pLeaf->p[iOff], (u64*)&pIter->iRowid);
+ pIter->iLeafOffset = iOff;
+
+ if( pLeaf->nn>pLeaf->szLeaf ){
+ pIter->iPgidxOff = pLeaf->szLeaf + fts5GetVarint32(
+ &pLeaf->p[pLeaf->szLeaf], pIter->iEndofDoclist
+ );
+ }
+
+ }
+ else if( pLeaf->nn>pLeaf->szLeaf ){
+ pIter->iPgidxOff = pLeaf->szLeaf + fts5GetVarint32(
+ &pLeaf->p[pLeaf->szLeaf], iOff
+ );
+ pIter->iLeafOffset = iOff;
+ pIter->iEndofDoclist = iOff;
+ bNewTerm = 1;
+ }
+ if( iOff>=pLeaf->szLeaf ){
+ p->rc = FTS5_CORRUPT;
+ return;
+ }
+ }
+ }
+
+ /* Check if the iterator is now at EOF. If so, return early. */
+ if( pIter->pLeaf ){
+ if( bNewTerm ){
+ if( pIter->flags & FTS5_SEGITER_ONETERM ){
+ fts5DataRelease(pIter->pLeaf);
+ pIter->pLeaf = 0;
+ }else{
+ fts5SegIterLoadTerm(p, pIter, nKeep);
+ fts5SegIterLoadNPos(p, pIter);
+ if( pbNewTerm ) *pbNewTerm = 1;
+ }
+ }else{
+ /* The following could be done by calling fts5SegIterLoadNPos(). But
+ ** this block is particularly performance critical, so equivalent
+ ** code is inlined. */
+ int nSz;
+ assert( p->rc==SQLITE_OK );
+ fts5FastGetVarint32(pIter->pLeaf->p, pIter->iLeafOffset, nSz);
+ pIter->bDel = (nSz & 0x0001);
+ pIter->nPos = nSz>>1;
+ assert_nc( pIter->nPos>=0 );
+ }
+ }
+ }
+ }
+}
+
+#define SWAPVAL(T, a, b) { T tmp; tmp=a; a=b; b=tmp; }
+
+/*
+** Iterator pIter currently points to the first rowid in a doclist. This
+** function sets the iterator up so that iterates in reverse order through
+** the doclist.
+*/
+static void fts5SegIterReverse(Fts5Index *p, Fts5SegIter *pIter){
+ Fts5DlidxIter *pDlidx = pIter->pDlidx;
+ Fts5Data *pLast = 0;
+ int pgnoLast = 0;
+
+ if( pDlidx ){
+ int iSegid = pIter->pSeg->iSegid;
+ pgnoLast = fts5DlidxIterPgno(pDlidx);
+ pLast = fts5DataRead(p, FTS5_SEGMENT_ROWID(iSegid, pgnoLast));
+ }else{
+ Fts5Data *pLeaf = pIter->pLeaf; /* Current leaf data */
+
+ /* Currently, Fts5SegIter.iLeafOffset points to the first byte of
+ ** position-list content for the current rowid. Back it up so that it
+ ** points to the start of the position-list size field. */
+ pIter->iLeafOffset -= sqlite3Fts5GetVarintLen(pIter->nPos*2+pIter->bDel);
+
+ /* If this condition is true then the largest rowid for the current
+ ** term may not be stored on the current page. So search forward to
+ ** see where said rowid really is. */
+ if( pIter->iEndofDoclist>=pLeaf->szLeaf ){
+ int pgno;
+ Fts5StructureSegment *pSeg = pIter->pSeg;
+
+ /* The last rowid in the doclist may not be on the current page. Search
+ ** forward to find the page containing the last rowid. */
+ for(pgno=pIter->iLeafPgno+1; !p->rc && pgno<=pSeg->pgnoLast; pgno++){
+ i64 iAbs = FTS5_SEGMENT_ROWID(pSeg->iSegid, pgno);
+ Fts5Data *pNew = fts5DataRead(p, iAbs);
+ if( pNew ){
+ int iRowid, bTermless;
+ iRowid = fts5LeafFirstRowidOff(pNew);
+ bTermless = fts5LeafIsTermless(pNew);
+ if( iRowid ){
+ SWAPVAL(Fts5Data*, pNew, pLast);
+ pgnoLast = pgno;
+ }
+ fts5DataRelease(pNew);
+ if( bTermless==0 ) break;
+ }
+ }
+ }
+ }
+
+ /* If pLast is NULL at this point, then the last rowid for this doclist
+ ** lies on the page currently indicated by the iterator. In this case
+ ** pIter->iLeafOffset is already set to point to the position-list size
+ ** field associated with the first relevant rowid on the page.
+ **
+ ** Or, if pLast is non-NULL, then it is the page that contains the last
+ ** rowid. In this case configure the iterator so that it points to the
+ ** first rowid on this page.
+ */
+ if( pLast ){
+ int iOff;
+ fts5DataRelease(pIter->pLeaf);
+ pIter->pLeaf = pLast;
+ pIter->iLeafPgno = pgnoLast;
+ iOff = fts5LeafFirstRowidOff(pLast);
+ iOff += fts5GetVarint(&pLast->p[iOff], (u64*)&pIter->iRowid);
+ pIter->iLeafOffset = iOff;
+
+ if( fts5LeafIsTermless(pLast) ){
+ pIter->iEndofDoclist = pLast->nn+1;
+ }else{
+ pIter->iEndofDoclist = fts5LeafFirstTermOff(pLast);
+ }
+
+ }
+
+ fts5SegIterReverseInitPage(p, pIter);
+}
+
+/*
+** Iterator pIter currently points to the first rowid of a doclist.
+** There is a doclist-index associated with the final term on the current
+** page. If the current term is the last term on the page, load the
+** doclist-index from disk and initialize an iterator at (pIter->pDlidx).
+*/
+static void fts5SegIterLoadDlidx(Fts5Index *p, Fts5SegIter *pIter){
+ int iSeg = pIter->pSeg->iSegid;
+ int bRev = (pIter->flags & FTS5_SEGITER_REVERSE);
+ Fts5Data *pLeaf = pIter->pLeaf; /* Current leaf data */
+
+ assert( pIter->flags & FTS5_SEGITER_ONETERM );
+ assert( pIter->pDlidx==0 );
+
+ /* Check if the current doclist ends on this page. If it does, return
+ ** early without loading the doclist-index (as it belongs to a different
+ ** term. */
+ if( pIter->iTermLeafPgno==pIter->iLeafPgno
+ && pIter->iEndofDoclist<pLeaf->szLeaf
+ ){
+ return;
+ }
+
+ pIter->pDlidx = fts5DlidxIterInit(p, bRev, iSeg, pIter->iTermLeafPgno);
+}
+
+#define fts5IndexSkipVarint(a, iOff) { \
+ int iEnd = iOff+9; \
+ while( (a[iOff++] & 0x80) && iOff<iEnd ); \
+}
+
+/*
+** The iterator object passed as the second argument currently contains
+** no valid values except for the Fts5SegIter.pLeaf member variable. This
+** function searches the leaf page for a term matching (pTerm/nTerm).
+**
+** If the specified term is found on the page, then the iterator is left
+** pointing to it. If argument bGe is zero and the term is not found,
+** the iterator is left pointing at EOF.
+**
+** If bGe is non-zero and the specified term is not found, then the
+** iterator is left pointing to the smallest term in the segment that
+** is larger than the specified term, even if this term is not on the
+** current page.
+*/
+static void fts5LeafSeek(
+ Fts5Index *p, /* Leave any error code here */
+ int bGe, /* True for a >= search */
+ Fts5SegIter *pIter, /* Iterator to seek */
+ const u8 *pTerm, int nTerm /* Term to search for */
+){
+ int iOff;
+ const u8 *a = pIter->pLeaf->p;
+ int szLeaf = pIter->pLeaf->szLeaf;
+ int n = pIter->pLeaf->nn;
+
+ int nMatch = 0;
+ int nKeep = 0;
+ int nNew = 0;
+ int iTermOff;
+ int iPgidx; /* Current offset in pgidx */
+ int bEndOfPage = 0;
+
+ assert( p->rc==SQLITE_OK );
+
+ iPgidx = szLeaf;
+ iPgidx += fts5GetVarint32(&a[iPgidx], iTermOff);
+ iOff = iTermOff;
+
+ while( 1 ){
+
+ /* Figure out how many new bytes are in this term */
+ fts5FastGetVarint32(a, iOff, nNew);
+ if( nKeep<nMatch ){
+ goto search_failed;
+ }
+
+ assert( nKeep>=nMatch );
+ if( nKeep==nMatch ){
+ int nCmp;
+ int i;
+ nCmp = MIN(nNew, nTerm-nMatch);
+ for(i=0; i<nCmp; i++){
+ if( a[iOff+i]!=pTerm[nMatch+i] ) break;
+ }
+ nMatch += i;
+
+ if( nTerm==nMatch ){
+ if( i==nNew ){
+ goto search_success;
+ }else{
+ goto search_failed;
+ }
+ }else if( i<nNew && a[iOff+i]>pTerm[nMatch] ){
+ goto search_failed;
+ }
+ }
+
+ if( iPgidx>=n ){
+ bEndOfPage = 1;
+ break;
+ }
+
+ iPgidx += fts5GetVarint32(&a[iPgidx], nKeep);
+ iTermOff += nKeep;
+ iOff = iTermOff;
+
+ /* Read the nKeep field of the next term. */
+ fts5FastGetVarint32(a, iOff, nKeep);
+ }
+
+ search_failed:
+ if( bGe==0 ){
+ fts5DataRelease(pIter->pLeaf);
+ pIter->pLeaf = 0;
+ return;
+ }else if( bEndOfPage ){
+ do {
+ fts5SegIterNextPage(p, pIter);
+ if( pIter->pLeaf==0 ) return;
+ a = pIter->pLeaf->p;
+ if( fts5LeafIsTermless(pIter->pLeaf)==0 ){
+ iPgidx = pIter->pLeaf->szLeaf;
+ iPgidx += fts5GetVarint32(&pIter->pLeaf->p[iPgidx], iOff);
+ if( iOff<4 || iOff>=pIter->pLeaf->szLeaf ){
+ p->rc = FTS5_CORRUPT;
+ }else{
+ nKeep = 0;
+ iTermOff = iOff;
+ n = pIter->pLeaf->nn;
+ iOff += fts5GetVarint32(&a[iOff], nNew);
+ break;
+ }
+ }
+ }while( 1 );
+ }
+
+ search_success:
+
+ pIter->iLeafOffset = iOff + nNew;
+ pIter->iTermLeafOffset = pIter->iLeafOffset;
+ pIter->iTermLeafPgno = pIter->iLeafPgno;
+
+ fts5BufferSet(&p->rc, &pIter->term, nKeep, pTerm);
+ fts5BufferAppendBlob(&p->rc, &pIter->term, nNew, &a[iOff]);
+
+ if( iPgidx>=n ){
+ pIter->iEndofDoclist = pIter->pLeaf->nn+1;
+ }else{
+ int nExtra;
+ iPgidx += fts5GetVarint32(&a[iPgidx], nExtra);
+ pIter->iEndofDoclist = iTermOff + nExtra;
+ }
+ pIter->iPgidxOff = iPgidx;
+
+ fts5SegIterLoadRowid(p, pIter);
+ fts5SegIterLoadNPos(p, pIter);
+}
+
+/*
+** Initialize the object pIter to point to term pTerm/nTerm within segment
+** pSeg. If there is no such term in the index, the iterator is set to EOF.
+**
+** If an error occurs, Fts5Index.rc is set to an appropriate error code. If
+** an error has already occurred when this function is called, it is a no-op.
+*/
+static void fts5SegIterSeekInit(
+ Fts5Index *p, /* FTS5 backend */
+ Fts5Buffer *pBuf, /* Buffer to use for loading pages */
+ const u8 *pTerm, int nTerm, /* Term to seek to */
+ int flags, /* Mask of FTS5INDEX_XXX flags */
+ Fts5StructureSegment *pSeg, /* Description of segment */
+ Fts5SegIter *pIter /* Object to populate */
+){
+ int iPg = 1;
+ int bGe = (flags & FTS5INDEX_QUERY_SCAN);
+ int bDlidx = 0; /* True if there is a doclist-index */
+
+ static int nCall = 0;
+ nCall++;
+
+ assert( bGe==0 || (flags & FTS5INDEX_QUERY_DESC)==0 );
+ assert( pTerm && nTerm );
+ memset(pIter, 0, sizeof(*pIter));
+ pIter->pSeg = pSeg;
+
+ /* This block sets stack variable iPg to the leaf page number that may
+ ** contain term (pTerm/nTerm), if it is present in the segment. */
+ if( p->pIdxSelect==0 ){
+ Fts5Config *pConfig = p->pConfig;
+ fts5IndexPrepareStmt(p, &p->pIdxSelect, sqlite3_mprintf(
+ "SELECT pgno FROM '%q'.'%q_idx' WHERE "
+ "segid=? AND term<=? ORDER BY term DESC LIMIT 1",
+ pConfig->zDb, pConfig->zName
+ ));
+ }
+ if( p->rc ) return;
+ sqlite3_bind_int(p->pIdxSelect, 1, pSeg->iSegid);
+ sqlite3_bind_blob(p->pIdxSelect, 2, pTerm, nTerm, SQLITE_STATIC);
+ if( SQLITE_ROW==sqlite3_step(p->pIdxSelect) ){
+ i64 val = sqlite3_column_int(p->pIdxSelect, 0);
+ iPg = (int)(val>>1);
+ bDlidx = (val & 0x0001);
+ }
+ p->rc = sqlite3_reset(p->pIdxSelect);
+
+ if( iPg<pSeg->pgnoFirst ){
+ iPg = pSeg->pgnoFirst;
+ bDlidx = 0;
+ }
+
+ pIter->iLeafPgno = iPg - 1;
+ fts5SegIterNextPage(p, pIter);
+
+ if( pIter->pLeaf ){
+ fts5LeafSeek(p, bGe, pIter, pTerm, nTerm);
+ }
+
+ if( p->rc==SQLITE_OK && bGe==0 ){
+ pIter->flags |= FTS5_SEGITER_ONETERM;
+ if( pIter->pLeaf ){
+ if( flags & FTS5INDEX_QUERY_DESC ){
+ pIter->flags |= FTS5_SEGITER_REVERSE;
+ }
+ if( bDlidx ){
+ fts5SegIterLoadDlidx(p, pIter);
+ }
+ if( flags & FTS5INDEX_QUERY_DESC ){
+ fts5SegIterReverse(p, pIter);
+ }
+ }
+ }
+
+ /* Either:
+ **
+ ** 1) an error has occurred, or
+ ** 2) the iterator points to EOF, or
+ ** 3) the iterator points to an entry with term (pTerm/nTerm), or
+ ** 4) the FTS5INDEX_QUERY_SCAN flag was set and the iterator points
+ ** to an entry with a term greater than or equal to (pTerm/nTerm).
+ */
+ assert( p->rc!=SQLITE_OK /* 1 */
+ || pIter->pLeaf==0 /* 2 */
+ || fts5BufferCompareBlob(&pIter->term, pTerm, nTerm)==0 /* 3 */
+ || (bGe && fts5BufferCompareBlob(&pIter->term, pTerm, nTerm)>0) /* 4 */
+ );
+}
+
+/*
+** Initialize the object pIter to point to term pTerm/nTerm within the
+** in-memory hash table. If there is no such term in the hash-table, the
+** iterator is set to EOF.
+**
+** If an error occurs, Fts5Index.rc is set to an appropriate error code. If
+** an error has already occurred when this function is called, it is a no-op.
+*/
+static void fts5SegIterHashInit(
+ Fts5Index *p, /* FTS5 backend */
+ const u8 *pTerm, int nTerm, /* Term to seek to */
+ int flags, /* Mask of FTS5INDEX_XXX flags */
+ Fts5SegIter *pIter /* Object to populate */
+){
+ const u8 *pList = 0;
+ int nList = 0;
+ const u8 *z = 0;
+ int n = 0;
+
+ assert( p->pHash );
+ assert( p->rc==SQLITE_OK );
+
+ if( pTerm==0 || (flags & FTS5INDEX_QUERY_SCAN) ){
+ p->rc = sqlite3Fts5HashScanInit(p->pHash, (const char*)pTerm, nTerm);
+ sqlite3Fts5HashScanEntry(p->pHash, (const char**)&z, &pList, &nList);
+ n = (z ? (int)strlen((const char*)z) : 0);
+ }else{
+ pIter->flags |= FTS5_SEGITER_ONETERM;
+ sqlite3Fts5HashQuery(p->pHash, (const char*)pTerm, nTerm, &pList, &nList);
+ z = pTerm;
+ n = nTerm;
+ }
+
+ if( pList ){
+ Fts5Data *pLeaf;
+ sqlite3Fts5BufferSet(&p->rc, &pIter->term, n, z);
+ pLeaf = fts5IdxMalloc(p, sizeof(Fts5Data));
+ if( pLeaf==0 ) return;
+ pLeaf->p = (u8*)pList;
+ pLeaf->nn = pLeaf->szLeaf = nList;
+ pIter->pLeaf = pLeaf;
+ pIter->iLeafOffset = fts5GetVarint(pLeaf->p, (u64*)&pIter->iRowid);
+ pIter->iEndofDoclist = pLeaf->nn+1;
+
+ if( flags & FTS5INDEX_QUERY_DESC ){
+ pIter->flags |= FTS5_SEGITER_REVERSE;
+ fts5SegIterReverseInitPage(p, pIter);
+ }else{
+ fts5SegIterLoadNPos(p, pIter);
+ }
+ }
+}
+
+/*
+** Zero the iterator passed as the only argument.
+*/
+static void fts5SegIterClear(Fts5SegIter *pIter){
+ fts5BufferFree(&pIter->term);
+ fts5DataRelease(pIter->pLeaf);
+ fts5DataRelease(pIter->pNextLeaf);
+ fts5DlidxIterFree(pIter->pDlidx);
+ sqlite3_free(pIter->aRowidOffset);
+ memset(pIter, 0, sizeof(Fts5SegIter));
+}
+
+#ifdef SQLITE_DEBUG
+
+/*
+** This function is used as part of the big assert() procedure implemented by
+** fts5AssertMultiIterSetup(). It ensures that the result currently stored
+** in *pRes is the correct result of comparing the current positions of the
+** two iterators.
+*/
+static void fts5AssertComparisonResult(
+ Fts5IndexIter *pIter,
+ Fts5SegIter *p1,
+ Fts5SegIter *p2,
+ Fts5CResult *pRes
+){
+ int i1 = p1 - pIter->aSeg;
+ int i2 = p2 - pIter->aSeg;
+
+ if( p1->pLeaf || p2->pLeaf ){
+ if( p1->pLeaf==0 ){
+ assert( pRes->iFirst==i2 );
+ }else if( p2->pLeaf==0 ){
+ assert( pRes->iFirst==i1 );
+ }else{
+ int nMin = MIN(p1->term.n, p2->term.n);
+ int res = memcmp(p1->term.p, p2->term.p, nMin);
+ if( res==0 ) res = p1->term.n - p2->term.n;
+
+ if( res==0 ){
+ assert( pRes->bTermEq==1 );
+ assert( p1->iRowid!=p2->iRowid );
+ res = ((p1->iRowid > p2->iRowid)==pIter->bRev) ? -1 : 1;
+ }else{
+ assert( pRes->bTermEq==0 );
+ }
+
+ if( res<0 ){
+ assert( pRes->iFirst==i1 );
+ }else{
+ assert( pRes->iFirst==i2 );
+ }
+ }
+ }
+}
+
+/*
+** This function is a no-op unless SQLITE_DEBUG is defined when this module
+** is compiled. In that case, this function is essentially an assert()
+** statement used to verify that the contents of the pIter->aFirst[] array
+** are correct.
+*/
+static void fts5AssertMultiIterSetup(Fts5Index *p, Fts5IndexIter *pIter){
+ if( p->rc==SQLITE_OK ){
+ Fts5SegIter *pFirst = &pIter->aSeg[ pIter->aFirst[1].iFirst ];
+ int i;
+
+ assert( (pFirst->pLeaf==0)==pIter->bEof );
+
+ /* Check that pIter->iSwitchRowid is set correctly. */
+ for(i=0; i<pIter->nSeg; i++){
+ Fts5SegIter *p1 = &pIter->aSeg[i];
+ assert( p1==pFirst
+ || p1->pLeaf==0
+ || fts5BufferCompare(&pFirst->term, &p1->term)
+ || p1->iRowid==pIter->iSwitchRowid
+ || (p1->iRowid<pIter->iSwitchRowid)==pIter->bRev
+ );
+ }
+
+ for(i=0; i<pIter->nSeg; i+=2){
+ Fts5SegIter *p1 = &pIter->aSeg[i];
+ Fts5SegIter *p2 = &pIter->aSeg[i+1];
+ Fts5CResult *pRes = &pIter->aFirst[(pIter->nSeg + i) / 2];
+ fts5AssertComparisonResult(pIter, p1, p2, pRes);
+ }
+
+ for(i=1; i<(pIter->nSeg / 2); i+=2){
+ Fts5SegIter *p1 = &pIter->aSeg[ pIter->aFirst[i*2].iFirst ];
+ Fts5SegIter *p2 = &pIter->aSeg[ pIter->aFirst[i*2+1].iFirst ];
+ Fts5CResult *pRes = &pIter->aFirst[i];
+ fts5AssertComparisonResult(pIter, p1, p2, pRes);
+ }
+ }
+}
+#else
+# define fts5AssertMultiIterSetup(x,y)
+#endif
+
+/*
+** Do the comparison necessary to populate pIter->aFirst[iOut].
+**
+** If the returned value is non-zero, then it is the index of an entry
+** in the pIter->aSeg[] array that is (a) not at EOF, and (b) pointing
+** to a key that is a duplicate of another, higher priority,
+** segment-iterator in the pSeg->aSeg[] array.
+*/
+static int fts5MultiIterDoCompare(Fts5IndexIter *pIter, int iOut){
+ int i1; /* Index of left-hand Fts5SegIter */
+ int i2; /* Index of right-hand Fts5SegIter */
+ int iRes;
+ Fts5SegIter *p1; /* Left-hand Fts5SegIter */
+ Fts5SegIter *p2; /* Right-hand Fts5SegIter */
+ Fts5CResult *pRes = &pIter->aFirst[iOut];
+
+ assert( iOut<pIter->nSeg && iOut>0 );
+ assert( pIter->bRev==0 || pIter->bRev==1 );
+
+ if( iOut>=(pIter->nSeg/2) ){
+ i1 = (iOut - pIter->nSeg/2) * 2;
+ i2 = i1 + 1;
+ }else{
+ i1 = pIter->aFirst[iOut*2].iFirst;
+ i2 = pIter->aFirst[iOut*2+1].iFirst;
+ }
+ p1 = &pIter->aSeg[i1];
+ p2 = &pIter->aSeg[i2];
+
+ pRes->bTermEq = 0;
+ if( p1->pLeaf==0 ){ /* If p1 is at EOF */
+ iRes = i2;
+ }else if( p2->pLeaf==0 ){ /* If p2 is at EOF */
+ iRes = i1;
+ }else{
+ int res = fts5BufferCompare(&p1->term, &p2->term);
+ if( res==0 ){
+ assert( i2>i1 );
+ assert( i2!=0 );
+ pRes->bTermEq = 1;
+ if( p1->iRowid==p2->iRowid ){
+ p1->bDel = p2->bDel;
+ return i2;
+ }
+ res = ((p1->iRowid > p2->iRowid)==pIter->bRev) ? -1 : +1;
+ }
+ assert( res!=0 );
+ if( res<0 ){
+ iRes = i1;
+ }else{
+ iRes = i2;
+ }
+ }
+
+ pRes->iFirst = (u16)iRes;
+ return 0;
+}
+
+/*
+** Move the seg-iter so that it points to the first rowid on page iLeafPgno.
+** It is an error if leaf iLeafPgno does not exist or contains no rowids.
+*/
+static void fts5SegIterGotoPage(
+ Fts5Index *p, /* FTS5 backend object */
+ Fts5SegIter *pIter, /* Iterator to advance */
+ int iLeafPgno
+){
+ assert( iLeafPgno>pIter->iLeafPgno );
+
+ if( iLeafPgno>pIter->pSeg->pgnoLast ){
+ p->rc = FTS5_CORRUPT;
+ }else{
+ fts5DataRelease(pIter->pNextLeaf);
+ pIter->pNextLeaf = 0;
+ pIter->iLeafPgno = iLeafPgno-1;
+ fts5SegIterNextPage(p, pIter);
+ assert( p->rc!=SQLITE_OK || pIter->iLeafPgno==iLeafPgno );
+
+ if( p->rc==SQLITE_OK ){
+ int iOff;
+ u8 *a = pIter->pLeaf->p;
+ int n = pIter->pLeaf->szLeaf;
+
+ iOff = fts5LeafFirstRowidOff(pIter->pLeaf);
+ if( iOff<4 || iOff>=n ){
+ p->rc = FTS5_CORRUPT;
+ }else{
+ iOff += fts5GetVarint(&a[iOff], (u64*)&pIter->iRowid);
+ pIter->iLeafOffset = iOff;
+ fts5SegIterLoadNPos(p, pIter);
+ }
+ }
+ }
+}
+
+/*
+** Advance the iterator passed as the second argument until it is at or
+** past rowid iFrom. Regardless of the value of iFrom, the iterator is
+** always advanced at least once.
+*/
+static void fts5SegIterNextFrom(
+ Fts5Index *p, /* FTS5 backend object */
+ Fts5SegIter *pIter, /* Iterator to advance */
+ i64 iMatch /* Advance iterator at least this far */
+){
+ int bRev = (pIter->flags & FTS5_SEGITER_REVERSE);
+ Fts5DlidxIter *pDlidx = pIter->pDlidx;
+ int iLeafPgno = pIter->iLeafPgno;
+ int bMove = 1;
+
+ assert( pIter->flags & FTS5_SEGITER_ONETERM );
+ assert( pIter->pDlidx );
+ assert( pIter->pLeaf );
+
+ if( bRev==0 ){
+ while( !fts5DlidxIterEof(p, pDlidx) && iMatch>fts5DlidxIterRowid(pDlidx) ){
+ iLeafPgno = fts5DlidxIterPgno(pDlidx);
+ fts5DlidxIterNext(p, pDlidx);
+ }
+ assert_nc( iLeafPgno>=pIter->iLeafPgno || p->rc );
+ if( iLeafPgno>pIter->iLeafPgno ){
+ fts5SegIterGotoPage(p, pIter, iLeafPgno);
+ bMove = 0;
+ }
+ }else{
+ assert( pIter->pNextLeaf==0 );
+ assert( iMatch<pIter->iRowid );
+ while( !fts5DlidxIterEof(p, pDlidx) && iMatch<fts5DlidxIterRowid(pDlidx) ){
+ fts5DlidxIterPrev(p, pDlidx);
+ }
+ iLeafPgno = fts5DlidxIterPgno(pDlidx);
+
+ assert( fts5DlidxIterEof(p, pDlidx) || iLeafPgno<=pIter->iLeafPgno );
+
+ if( iLeafPgno<pIter->iLeafPgno ){
+ pIter->iLeafPgno = iLeafPgno+1;
+ fts5SegIterReverseNewPage(p, pIter);
+ bMove = 0;
+ }
+ }
+
+ do{
+ if( bMove ) fts5SegIterNext(p, pIter, 0);
+ if( pIter->pLeaf==0 ) break;
+ if( bRev==0 && pIter->iRowid>=iMatch ) break;
+ if( bRev!=0 && pIter->iRowid<=iMatch ) break;
+ bMove = 1;
+ }while( p->rc==SQLITE_OK );
+}
+
+
+/*
+** Free the iterator object passed as the second argument.
+*/
+static void fts5MultiIterFree(Fts5Index *p, Fts5IndexIter *pIter){
+ if( pIter ){
+ int i;
+ for(i=0; i<pIter->nSeg; i++){
+ fts5SegIterClear(&pIter->aSeg[i]);
+ }
+ fts5StructureRelease(pIter->pStruct);
+ fts5BufferFree(&pIter->poslist);
+ sqlite3_free(pIter);
+ }
+}
+
+static void fts5MultiIterAdvanced(
+ Fts5Index *p, /* FTS5 backend to iterate within */
+ Fts5IndexIter *pIter, /* Iterator to update aFirst[] array for */
+ int iChanged, /* Index of sub-iterator just advanced */
+ int iMinset /* Minimum entry in aFirst[] to set */
+){
+ int i;
+ for(i=(pIter->nSeg+iChanged)/2; i>=iMinset && p->rc==SQLITE_OK; i=i/2){
+ int iEq;
+ if( (iEq = fts5MultiIterDoCompare(pIter, i)) ){
+ fts5SegIterNext(p, &pIter->aSeg[iEq], 0);
+ i = pIter->nSeg + iEq;
+ }
+ }
+}
+
+/*
+** Sub-iterator iChanged of iterator pIter has just been advanced. It still
+** points to the same term though - just a different rowid. This function
+** attempts to update the contents of the pIter->aFirst[] accordingly.
+** If it does so successfully, 0 is returned. Otherwise 1.
+**
+** If non-zero is returned, the caller should call fts5MultiIterAdvanced()
+** on the iterator instead. That function does the same as this one, except
+** that it deals with more complicated cases as well.
+*/
+static int fts5MultiIterAdvanceRowid(
+ Fts5Index *p, /* FTS5 backend to iterate within */
+ Fts5IndexIter *pIter, /* Iterator to update aFirst[] array for */
+ int iChanged /* Index of sub-iterator just advanced */
+){
+ Fts5SegIter *pNew = &pIter->aSeg[iChanged];
+
+ if( pNew->iRowid==pIter->iSwitchRowid
+ || (pNew->iRowid<pIter->iSwitchRowid)==pIter->bRev
+ ){
+ int i;
+ Fts5SegIter *pOther = &pIter->aSeg[iChanged ^ 0x0001];
+ pIter->iSwitchRowid = pIter->bRev ? SMALLEST_INT64 : LARGEST_INT64;
+ for(i=(pIter->nSeg+iChanged)/2; 1; i=i/2){
+ Fts5CResult *pRes = &pIter->aFirst[i];
+
+ assert( pNew->pLeaf );
+ assert( pRes->bTermEq==0 || pOther->pLeaf );
+
+ if( pRes->bTermEq ){
+ if( pNew->iRowid==pOther->iRowid ){
+ return 1;
+ }else if( (pOther->iRowid>pNew->iRowid)==pIter->bRev ){
+ pIter->iSwitchRowid = pOther->iRowid;
+ pNew = pOther;
+ }else if( (pOther->iRowid>pIter->iSwitchRowid)==pIter->bRev ){
+ pIter->iSwitchRowid = pOther->iRowid;
+ }
+ }
+ pRes->iFirst = (u16)(pNew - pIter->aSeg);
+ if( i==1 ) break;
+
+ pOther = &pIter->aSeg[ pIter->aFirst[i ^ 0x0001].iFirst ];
+ }
+ }
+
+ return 0;
+}
+
+/*
+** Set the pIter->bEof variable based on the state of the sub-iterators.
+*/
+static void fts5MultiIterSetEof(Fts5IndexIter *pIter){
+ Fts5SegIter *pSeg = &pIter->aSeg[ pIter->aFirst[1].iFirst ];
+ pIter->bEof = pSeg->pLeaf==0;
+ pIter->iSwitchRowid = pSeg->iRowid;
+}
+
+/*
+** Move the iterator to the next entry.
+**
+** If an error occurs, an error code is left in Fts5Index.rc. It is not
+** considered an error if the iterator reaches EOF, or if it is already at
+** EOF when this function is called.
+*/
+static void fts5MultiIterNext(
+ Fts5Index *p,
+ Fts5IndexIter *pIter,
+ int bFrom, /* True if argument iFrom is valid */
+ i64 iFrom /* Advance at least as far as this */
+){
+ if( p->rc==SQLITE_OK ){
+ int bUseFrom = bFrom;
+ do {
+ int iFirst = pIter->aFirst[1].iFirst;
+ int bNewTerm = 0;
+ Fts5SegIter *pSeg = &pIter->aSeg[iFirst];
+ assert( p->rc==SQLITE_OK );
+ if( bUseFrom && pSeg->pDlidx ){
+ fts5SegIterNextFrom(p, pSeg, iFrom);
+ }else{
+ fts5SegIterNext(p, pSeg, &bNewTerm);
+ }
+
+ if( pSeg->pLeaf==0 || bNewTerm
+ || fts5MultiIterAdvanceRowid(p, pIter, iFirst)
+ ){
+ fts5MultiIterAdvanced(p, pIter, iFirst, 1);
+ fts5MultiIterSetEof(pIter);
+ }
+ fts5AssertMultiIterSetup(p, pIter);
+
+ bUseFrom = 0;
+ }while( pIter->bSkipEmpty && fts5MultiIterIsEmpty(p, pIter) );
+ }
+}
+
+static void fts5MultiIterNext2(
+ Fts5Index *p,
+ Fts5IndexIter *pIter,
+ int *pbNewTerm /* OUT: True if *might* be new term */
+){
+ assert( pIter->bSkipEmpty );
+ if( p->rc==SQLITE_OK ){
+ do {
+ int iFirst = pIter->aFirst[1].iFirst;
+ Fts5SegIter *pSeg = &pIter->aSeg[iFirst];
+ int bNewTerm = 0;
+
+ fts5SegIterNext(p, pSeg, &bNewTerm);
+ if( pSeg->pLeaf==0 || bNewTerm
+ || fts5MultiIterAdvanceRowid(p, pIter, iFirst)
+ ){
+ fts5MultiIterAdvanced(p, pIter, iFirst, 1);
+ fts5MultiIterSetEof(pIter);
+ *pbNewTerm = 1;
+ }else{
+ *pbNewTerm = 0;
+ }
+ fts5AssertMultiIterSetup(p, pIter);
+
+ }while( fts5MultiIterIsEmpty(p, pIter) );
+ }
+}
+
+
+static Fts5IndexIter *fts5MultiIterAlloc(
+ Fts5Index *p, /* FTS5 backend to iterate within */
+ int nSeg
+){
+ Fts5IndexIter *pNew;
+ int nSlot; /* Power of two >= nSeg */
+
+ for(nSlot=2; nSlot<nSeg; nSlot=nSlot*2);
+ pNew = fts5IdxMalloc(p,
+ sizeof(Fts5IndexIter) + /* pNew */
+ sizeof(Fts5SegIter) * (nSlot-1) + /* pNew->aSeg[] */
+ sizeof(Fts5CResult) * nSlot /* pNew->aFirst[] */
+ );
+ if( pNew ){
+ pNew->nSeg = nSlot;
+ pNew->aFirst = (Fts5CResult*)&pNew->aSeg[nSlot];
+ pNew->pIndex = p;
+ }
+ return pNew;
+}
+
+/*
+** Allocate a new Fts5IndexIter object.
+**
+** The new object will be used to iterate through data in structure pStruct.
+** If iLevel is -ve, then all data in all segments is merged. Or, if iLevel
+** is zero or greater, data from the first nSegment segments on level iLevel
+** is merged.
+**
+** The iterator initially points to the first term/rowid entry in the
+** iterated data.
+*/
+static void fts5MultiIterNew(
+ Fts5Index *p, /* FTS5 backend to iterate within */
+ Fts5Structure *pStruct, /* Structure of specific index */
+ int bSkipEmpty, /* True to ignore delete-keys */
+ int flags, /* FTS5INDEX_QUERY_XXX flags */
+ const u8 *pTerm, int nTerm, /* Term to seek to (or NULL/0) */
+ int iLevel, /* Level to iterate (-1 for all) */
+ int nSegment, /* Number of segments to merge (iLevel>=0) */
+ Fts5IndexIter **ppOut /* New object */
+){
+ int nSeg = 0; /* Number of segment-iters in use */
+ int iIter = 0; /* */
+ int iSeg; /* Used to iterate through segments */
+ Fts5Buffer buf = {0,0,0}; /* Buffer used by fts5SegIterSeekInit() */
+ Fts5StructureLevel *pLvl;
+ Fts5IndexIter *pNew;
+
+ assert( (pTerm==0 && nTerm==0) || iLevel<0 );
+
+ /* Allocate space for the new multi-seg-iterator. */
+ if( p->rc==SQLITE_OK ){
+ if( iLevel<0 ){
+ assert( pStruct->nSegment==fts5StructureCountSegments(pStruct) );
+ nSeg = pStruct->nSegment;
+ nSeg += (p->pHash ? 1 : 0);
+ }else{
+ nSeg = MIN(pStruct->aLevel[iLevel].nSeg, nSegment);
+ }
+ }
+ *ppOut = pNew = fts5MultiIterAlloc(p, nSeg);
+ if( pNew==0 ) return;
+ pNew->bRev = (0!=(flags & FTS5INDEX_QUERY_DESC));
+ pNew->bSkipEmpty = (u8)bSkipEmpty;
+ pNew->pStruct = pStruct;
+ fts5StructureRef(pStruct);
+
+ /* Initialize each of the component segment iterators. */
+ if( iLevel<0 ){
+ Fts5StructureLevel *pEnd = &pStruct->aLevel[pStruct->nLevel];
+ if( p->pHash ){
+ /* Add a segment iterator for the current contents of the hash table. */
+ Fts5SegIter *pIter = &pNew->aSeg[iIter++];
+ fts5SegIterHashInit(p, pTerm, nTerm, flags, pIter);
+ }
+ for(pLvl=&pStruct->aLevel[0]; pLvl<pEnd; pLvl++){
+ for(iSeg=pLvl->nSeg-1; iSeg>=0; iSeg--){
+ Fts5StructureSegment *pSeg = &pLvl->aSeg[iSeg];
+ Fts5SegIter *pIter = &pNew->aSeg[iIter++];
+ if( pTerm==0 ){
+ fts5SegIterInit(p, pSeg, pIter);
+ }else{
+ fts5SegIterSeekInit(p, &buf, pTerm, nTerm, flags, pSeg, pIter);
+ }
+ }
+ }
+ }else{
+ pLvl = &pStruct->aLevel[iLevel];
+ for(iSeg=nSeg-1; iSeg>=0; iSeg--){
+ fts5SegIterInit(p, &pLvl->aSeg[iSeg], &pNew->aSeg[iIter++]);
+ }
+ }
+ assert( iIter==nSeg );
+
+ /* If the above was successful, each component iterators now points
+ ** to the first entry in its segment. In this case initialize the
+ ** aFirst[] array. Or, if an error has occurred, free the iterator
+ ** object and set the output variable to NULL. */
+ if( p->rc==SQLITE_OK ){
+ for(iIter=pNew->nSeg-1; iIter>0; iIter--){
+ int iEq;
+ if( (iEq = fts5MultiIterDoCompare(pNew, iIter)) ){
+ fts5SegIterNext(p, &pNew->aSeg[iEq], 0);
+ fts5MultiIterAdvanced(p, pNew, iEq, iIter);
+ }
+ }
+ fts5MultiIterSetEof(pNew);
+ fts5AssertMultiIterSetup(p, pNew);
+
+ if( pNew->bSkipEmpty && fts5MultiIterIsEmpty(p, pNew) ){
+ fts5MultiIterNext(p, pNew, 0, 0);
+ }
+ }else{
+ fts5MultiIterFree(p, pNew);
+ *ppOut = 0;
+ }
+ fts5BufferFree(&buf);
+}
+
+/*
+** Create an Fts5IndexIter that iterates through the doclist provided
+** as the second argument.
+*/
+static void fts5MultiIterNew2(
+ Fts5Index *p, /* FTS5 backend to iterate within */
+ Fts5Data *pData, /* Doclist to iterate through */
+ int bDesc, /* True for descending rowid order */
+ Fts5IndexIter **ppOut /* New object */
+){
+ Fts5IndexIter *pNew;
+ pNew = fts5MultiIterAlloc(p, 2);
+ if( pNew ){
+ Fts5SegIter *pIter = &pNew->aSeg[1];
+
+ pNew->bFiltered = 1;
+ pIter->flags = FTS5_SEGITER_ONETERM;
+ if( pData->szLeaf>0 ){
+ pIter->pLeaf = pData;
+ pIter->iLeafOffset = fts5GetVarint(pData->p, (u64*)&pIter->iRowid);
+ pIter->iEndofDoclist = pData->nn;
+ pNew->aFirst[1].iFirst = 1;
+ if( bDesc ){
+ pNew->bRev = 1;
+ pIter->flags |= FTS5_SEGITER_REVERSE;
+ fts5SegIterReverseInitPage(p, pIter);
+ }else{
+ fts5SegIterLoadNPos(p, pIter);
+ }
+ pData = 0;
+ }else{
+ pNew->bEof = 1;
+ }
+
+ *ppOut = pNew;
+ }
+
+ fts5DataRelease(pData);
+}
+
+/*
+** Return true if the iterator is at EOF or if an error has occurred.
+** False otherwise.
+*/
+static int fts5MultiIterEof(Fts5Index *p, Fts5IndexIter *pIter){
+ assert( p->rc
+ || (pIter->aSeg[ pIter->aFirst[1].iFirst ].pLeaf==0)==pIter->bEof
+ );
+ return (p->rc || pIter->bEof);
+}
+
+/*
+** Return the rowid of the entry that the iterator currently points
+** to. If the iterator points to EOF when this function is called the
+** results are undefined.
+*/
+static i64 fts5MultiIterRowid(Fts5IndexIter *pIter){
+ assert( pIter->aSeg[ pIter->aFirst[1].iFirst ].pLeaf );
+ return pIter->aSeg[ pIter->aFirst[1].iFirst ].iRowid;
+}
+
+/*
+** Move the iterator to the next entry at or following iMatch.
+*/
+static void fts5MultiIterNextFrom(
+ Fts5Index *p,
+ Fts5IndexIter *pIter,
+ i64 iMatch
+){
+ while( 1 ){
+ i64 iRowid;
+ fts5MultiIterNext(p, pIter, 1, iMatch);
+ if( fts5MultiIterEof(p, pIter) ) break;
+ iRowid = fts5MultiIterRowid(pIter);
+ if( pIter->bRev==0 && iRowid>=iMatch ) break;
+ if( pIter->bRev!=0 && iRowid<=iMatch ) break;
+ }
+}
+
+/*
+** Return a pointer to a buffer containing the term associated with the
+** entry that the iterator currently points to.
+*/
+static const u8 *fts5MultiIterTerm(Fts5IndexIter *pIter, int *pn){
+ Fts5SegIter *p = &pIter->aSeg[ pIter->aFirst[1].iFirst ];
+ *pn = p->term.n;
+ return p->term.p;
+}
+
+static void fts5ChunkIterate(
+ Fts5Index *p, /* Index object */
+ Fts5SegIter *pSeg, /* Poslist of this iterator */
+ void *pCtx, /* Context pointer for xChunk callback */
+ void (*xChunk)(Fts5Index*, void*, const u8*, int)
+){
+ int nRem = pSeg->nPos; /* Number of bytes still to come */
+ Fts5Data *pData = 0;
+ u8 *pChunk = &pSeg->pLeaf->p[pSeg->iLeafOffset];
+ int nChunk = MIN(nRem, pSeg->pLeaf->szLeaf - pSeg->iLeafOffset);
+ int pgno = pSeg->iLeafPgno;
+ int pgnoSave = 0;
+
+ if( (pSeg->flags & FTS5_SEGITER_REVERSE)==0 ){
+ pgnoSave = pgno+1;
+ }
+
+ while( 1 ){
+ xChunk(p, pCtx, pChunk, nChunk);
+ nRem -= nChunk;
+ fts5DataRelease(pData);
+ if( nRem<=0 ){
+ break;
+ }else{
+ pgno++;
+ pData = fts5DataRead(p, FTS5_SEGMENT_ROWID(pSeg->pSeg->iSegid, pgno));
+ if( pData==0 ) break;
+ pChunk = &pData->p[4];
+ nChunk = MIN(nRem, pData->szLeaf - 4);
+ if( pgno==pgnoSave ){
+ assert( pSeg->pNextLeaf==0 );
+ pSeg->pNextLeaf = pData;
+ pData = 0;
+ }
+ }
+ }
+}
+
+
+
+/*
+** Allocate a new segment-id for the structure pStruct. The new segment
+** id must be between 1 and 65335 inclusive, and must not be used by
+** any currently existing segment. If a free segment id cannot be found,
+** SQLITE_FULL is returned.
+**
+** If an error has already occurred, this function is a no-op. 0 is
+** returned in this case.
+*/
+static int fts5AllocateSegid(Fts5Index *p, Fts5Structure *pStruct){
+ int iSegid = 0;
+
+ if( p->rc==SQLITE_OK ){
+ if( pStruct->nSegment>=FTS5_MAX_SEGMENT ){
+ p->rc = SQLITE_FULL;
+ }else{
+ while( iSegid==0 ){
+ int iLvl, iSeg;
+ sqlite3_randomness(sizeof(u32), (void*)&iSegid);
+ iSegid = iSegid & ((1 << FTS5_DATA_ID_B)-1);
+ for(iLvl=0; iLvl<pStruct->nLevel; iLvl++){
+ for(iSeg=0; iSeg<pStruct->aLevel[iLvl].nSeg; iSeg++){
+ if( iSegid==pStruct->aLevel[iLvl].aSeg[iSeg].iSegid ){
+ iSegid = 0;
+ }
+ }
+ }
+ }
+ }
+ }
+
+ return iSegid;
+}
+
+/*
+** Discard all data currently cached in the hash-tables.
+*/
+static void fts5IndexDiscardData(Fts5Index *p){
+ assert( p->pHash || p->nPendingData==0 );
+ if( p->pHash ){
+ sqlite3Fts5HashClear(p->pHash);
+ p->nPendingData = 0;
+ }
+}
+
+/*
+** Return the size of the prefix, in bytes, that buffer (nNew/pNew) shares
+** with buffer (nOld/pOld).
+*/
+static int fts5PrefixCompress(
+ int nOld, const u8 *pOld,
+ int nNew, const u8 *pNew
+){
+ int i;
+ assert( fts5BlobCompare(pOld, nOld, pNew, nNew)<0 );
+ for(i=0; i<nOld; i++){
+ if( pOld[i]!=pNew[i] ) break;
+ }
+ return i;
+}
+
+static void fts5WriteDlidxClear(
+ Fts5Index *p,
+ Fts5SegWriter *pWriter,
+ int bFlush /* If true, write dlidx to disk */
+){
+ int i;
+ assert( bFlush==0 || (pWriter->nDlidx>0 && pWriter->aDlidx[0].buf.n>0) );
+ for(i=0; i<pWriter->nDlidx; i++){
+ Fts5DlidxWriter *pDlidx = &pWriter->aDlidx[i];
+ if( pDlidx->buf.n==0 ) break;
+ if( bFlush ){
+ assert( pDlidx->pgno!=0 );
+ fts5DataWrite(p,
+ FTS5_DLIDX_ROWID(pWriter->iSegid, i, pDlidx->pgno),
+ pDlidx->buf.p, pDlidx->buf.n
+ );
+ }
+ sqlite3Fts5BufferZero(&pDlidx->buf);
+ pDlidx->bPrevValid = 0;
+ }
+}
+
+/*
+** Grow the pWriter->aDlidx[] array to at least nLvl elements in size.
+** Any new array elements are zeroed before returning.
+*/
+static int fts5WriteDlidxGrow(
+ Fts5Index *p,
+ Fts5SegWriter *pWriter,
+ int nLvl
+){
+ if( p->rc==SQLITE_OK && nLvl>=pWriter->nDlidx ){
+ Fts5DlidxWriter *aDlidx = (Fts5DlidxWriter*)sqlite3_realloc(
+ pWriter->aDlidx, sizeof(Fts5DlidxWriter) * nLvl
+ );
+ if( aDlidx==0 ){
+ p->rc = SQLITE_NOMEM;
+ }else{
+ int nByte = sizeof(Fts5DlidxWriter) * (nLvl - pWriter->nDlidx);
+ memset(&aDlidx[pWriter->nDlidx], 0, nByte);
+ pWriter->aDlidx = aDlidx;
+ pWriter->nDlidx = nLvl;
+ }
+ }
+ return p->rc;
+}
+
+/*
+** If the current doclist-index accumulating in pWriter->aDlidx[] is large
+** enough, flush it to disk and return 1. Otherwise discard it and return
+** zero.
+*/
+static int fts5WriteFlushDlidx(Fts5Index *p, Fts5SegWriter *pWriter){
+ int bFlag = 0;
+
+ /* If there were FTS5_MIN_DLIDX_SIZE or more empty leaf pages written
+ ** to the database, also write the doclist-index to disk. */
+ if( pWriter->aDlidx[0].buf.n>0 && pWriter->nEmpty>=FTS5_MIN_DLIDX_SIZE ){
+ bFlag = 1;
+ }
+ fts5WriteDlidxClear(p, pWriter, bFlag);
+ pWriter->nEmpty = 0;
+ return bFlag;
+}
+
+/*
+** This function is called whenever processing of the doclist for the
+** last term on leaf page (pWriter->iBtPage) is completed.
+**
+** The doclist-index for that term is currently stored in-memory within the
+** Fts5SegWriter.aDlidx[] array. If it is large enough, this function
+** writes it out to disk. Or, if it is too small to bother with, discards
+** it.
+**
+** Fts5SegWriter.btterm currently contains the first term on page iBtPage.
+*/
+static void fts5WriteFlushBtree(Fts5Index *p, Fts5SegWriter *pWriter){
+ int bFlag;
+
+ assert( pWriter->iBtPage || pWriter->nEmpty==0 );
+ if( pWriter->iBtPage==0 ) return;
+ bFlag = fts5WriteFlushDlidx(p, pWriter);
+
+ if( p->rc==SQLITE_OK ){
+ const char *z = (pWriter->btterm.n>0?(const char*)pWriter->btterm.p:"");
+ /* The following was already done in fts5WriteInit(): */
+ /* sqlite3_bind_int(p->pIdxWriter, 1, pWriter->iSegid); */
+ sqlite3_bind_blob(p->pIdxWriter, 2, z, pWriter->btterm.n, SQLITE_STATIC);
+ sqlite3_bind_int64(p->pIdxWriter, 3, bFlag + ((i64)pWriter->iBtPage<<1));
+ sqlite3_step(p->pIdxWriter);
+ p->rc = sqlite3_reset(p->pIdxWriter);
+ }
+ pWriter->iBtPage = 0;
+}
+
+/*
+** This is called once for each leaf page except the first that contains
+** at least one term. Argument (nTerm/pTerm) is the split-key - a term that
+** is larger than all terms written to earlier leaves, and equal to or
+** smaller than the first term on the new leaf.
+**
+** If an error occurs, an error code is left in Fts5Index.rc. If an error
+** has already occurred when this function is called, it is a no-op.
+*/
+static void fts5WriteBtreeTerm(
+ Fts5Index *p, /* FTS5 backend object */
+ Fts5SegWriter *pWriter, /* Writer object */
+ int nTerm, const u8 *pTerm /* First term on new page */
+){
+ fts5WriteFlushBtree(p, pWriter);
+ fts5BufferSet(&p->rc, &pWriter->btterm, nTerm, pTerm);
+ pWriter->iBtPage = pWriter->writer.pgno;
+}
+
+/*
+** This function is called when flushing a leaf page that contains no
+** terms at all to disk.
+*/
+static void fts5WriteBtreeNoTerm(
+ Fts5Index *p, /* FTS5 backend object */
+ Fts5SegWriter *pWriter /* Writer object */
+){
+ /* If there were no rowids on the leaf page either and the doclist-index
+ ** has already been started, append an 0x00 byte to it. */
+ if( pWriter->bFirstRowidInPage && pWriter->aDlidx[0].buf.n>0 ){
+ Fts5DlidxWriter *pDlidx = &pWriter->aDlidx[0];
+ assert( pDlidx->bPrevValid );
+ sqlite3Fts5BufferAppendVarint(&p->rc, &pDlidx->buf, 0);
+ }
+
+ /* Increment the "number of sequential leaves without a term" counter. */
+ pWriter->nEmpty++;
+}
+
+static i64 fts5DlidxExtractFirstRowid(Fts5Buffer *pBuf){
+ i64 iRowid;
+ int iOff;
+
+ iOff = 1 + fts5GetVarint(&pBuf->p[1], (u64*)&iRowid);
+ fts5GetVarint(&pBuf->p[iOff], (u64*)&iRowid);
+ return iRowid;
+}
+
+/*
+** Rowid iRowid has just been appended to the current leaf page. It is the
+** first on the page. This function appends an appropriate entry to the current
+** doclist-index.
+*/
+static void fts5WriteDlidxAppend(
+ Fts5Index *p,
+ Fts5SegWriter *pWriter,
+ i64 iRowid
+){
+ int i;
+ int bDone = 0;
+
+ for(i=0; p->rc==SQLITE_OK && bDone==0; i++){
+ i64 iVal;
+ Fts5DlidxWriter *pDlidx = &pWriter->aDlidx[i];
+
+ if( pDlidx->buf.n>=p->pConfig->pgsz ){
+ /* The current doclist-index page is full. Write it to disk and push
+ ** a copy of iRowid (which will become the first rowid on the next
+ ** doclist-index leaf page) up into the next level of the b-tree
+ ** hierarchy. If the node being flushed is currently the root node,
+ ** also push its first rowid upwards. */
+ pDlidx->buf.p[0] = 0x01; /* Not the root node */
+ fts5DataWrite(p,
+ FTS5_DLIDX_ROWID(pWriter->iSegid, i, pDlidx->pgno),
+ pDlidx->buf.p, pDlidx->buf.n
+ );
+ fts5WriteDlidxGrow(p, pWriter, i+2);
+ pDlidx = &pWriter->aDlidx[i];
+ if( p->rc==SQLITE_OK && pDlidx[1].buf.n==0 ){
+ i64 iFirst = fts5DlidxExtractFirstRowid(&pDlidx->buf);
+
+ /* This was the root node. Push its first rowid up to the new root. */
+ pDlidx[1].pgno = pDlidx->pgno;
+ sqlite3Fts5BufferAppendVarint(&p->rc, &pDlidx[1].buf, 0);
+ sqlite3Fts5BufferAppendVarint(&p->rc, &pDlidx[1].buf, pDlidx->pgno);
+ sqlite3Fts5BufferAppendVarint(&p->rc, &pDlidx[1].buf, iFirst);
+ pDlidx[1].bPrevValid = 1;
+ pDlidx[1].iPrev = iFirst;
+ }
+
+ sqlite3Fts5BufferZero(&pDlidx->buf);
+ pDlidx->bPrevValid = 0;
+ pDlidx->pgno++;
+ }else{
+ bDone = 1;
+ }
+
+ if( pDlidx->bPrevValid ){
+ iVal = iRowid - pDlidx->iPrev;
+ }else{
+ i64 iPgno = (i==0 ? pWriter->writer.pgno : pDlidx[-1].pgno);
+ assert( pDlidx->buf.n==0 );
+ sqlite3Fts5BufferAppendVarint(&p->rc, &pDlidx->buf, !bDone);
+ sqlite3Fts5BufferAppendVarint(&p->rc, &pDlidx->buf, iPgno);
+ iVal = iRowid;
+ }
+
+ sqlite3Fts5BufferAppendVarint(&p->rc, &pDlidx->buf, iVal);
+ pDlidx->bPrevValid = 1;
+ pDlidx->iPrev = iRowid;
+ }
+}
+
+static void fts5WriteFlushLeaf(Fts5Index *p, Fts5SegWriter *pWriter){
+ static const u8 zero[] = { 0x00, 0x00, 0x00, 0x00 };
+ Fts5PageWriter *pPage = &pWriter->writer;
+ i64 iRowid;
+
+ assert( (pPage->pgidx.n==0)==(pWriter->bFirstTermInPage) );
+
+ /* Set the szLeaf header field. */
+ assert( 0==fts5GetU16(&pPage->buf.p[2]) );
+ fts5PutU16(&pPage->buf.p[2], (u16)pPage->buf.n);
+
+ if( pWriter->bFirstTermInPage ){
+ /* No term was written to this page. */
+ assert( pPage->pgidx.n==0 );
+ fts5WriteBtreeNoTerm(p, pWriter);
+ }else{
+ /* Append the pgidx to the page buffer. Set the szLeaf header field. */
+ fts5BufferAppendBlob(&p->rc, &pPage->buf, pPage->pgidx.n, pPage->pgidx.p);
+ }
+
+ /* Write the page out to disk */
+ iRowid = FTS5_SEGMENT_ROWID(pWriter->iSegid, pPage->pgno);
+ fts5DataWrite(p, iRowid, pPage->buf.p, pPage->buf.n);
+
+ /* Initialize the next page. */
+ fts5BufferZero(&pPage->buf);
+ fts5BufferZero(&pPage->pgidx);
+ fts5BufferAppendBlob(&p->rc, &pPage->buf, 4, zero);
+ pPage->iPrevPgidx = 0;
+ pPage->pgno++;
+
+ /* Increase the leaves written counter */
+ pWriter->nLeafWritten++;
+
+ /* The new leaf holds no terms or rowids */
+ pWriter->bFirstTermInPage = 1;
+ pWriter->bFirstRowidInPage = 1;
+}
+
+/*
+** Append term pTerm/nTerm to the segment being written by the writer passed
+** as the second argument.
+**
+** If an error occurs, set the Fts5Index.rc error code. If an error has
+** already occurred, this function is a no-op.
+*/
+static void fts5WriteAppendTerm(
+ Fts5Index *p,
+ Fts5SegWriter *pWriter,
+ int nTerm, const u8 *pTerm
+){
+ int nPrefix; /* Bytes of prefix compression for term */
+ Fts5PageWriter *pPage = &pWriter->writer;
+ Fts5Buffer *pPgidx = &pWriter->writer.pgidx;
+
+ assert( p->rc==SQLITE_OK );
+ assert( pPage->buf.n>=4 );
+ assert( pPage->buf.n>4 || pWriter->bFirstTermInPage );
+
+ /* If the current leaf page is full, flush it to disk. */
+ if( (pPage->buf.n + pPgidx->n + nTerm + 2)>=p->pConfig->pgsz ){
+ if( pPage->buf.n>4 ){
+ fts5WriteFlushLeaf(p, pWriter);
+ }
+ fts5BufferGrow(&p->rc, &pPage->buf, nTerm+FTS5_DATA_PADDING);
+ }
+
+ /* TODO1: Updating pgidx here. */
+ pPgidx->n += sqlite3Fts5PutVarint(
+ &pPgidx->p[pPgidx->n], pPage->buf.n - pPage->iPrevPgidx
+ );
+ pPage->iPrevPgidx = pPage->buf.n;
+#if 0
+ fts5PutU16(&pPgidx->p[pPgidx->n], pPage->buf.n);
+ pPgidx->n += 2;
+#endif
+
+ if( pWriter->bFirstTermInPage ){
+ nPrefix = 0;
+ if( pPage->pgno!=1 ){
+ /* This is the first term on a leaf that is not the leftmost leaf in
+ ** the segment b-tree. In this case it is necessary to add a term to
+ ** the b-tree hierarchy that is (a) larger than the largest term
+ ** already written to the segment and (b) smaller than or equal to
+ ** this term. In other words, a prefix of (pTerm/nTerm) that is one
+ ** byte longer than the longest prefix (pTerm/nTerm) shares with the
+ ** previous term.
+ **
+ ** Usually, the previous term is available in pPage->term. The exception
+ ** is if this is the first term written in an incremental-merge step.
+ ** In this case the previous term is not available, so just write a
+ ** copy of (pTerm/nTerm) into the parent node. This is slightly
+ ** inefficient, but still correct. */
+ int n = nTerm;
+ if( pPage->term.n ){
+ n = 1 + fts5PrefixCompress(pPage->term.n, pPage->term.p, nTerm, pTerm);
+ }
+ fts5WriteBtreeTerm(p, pWriter, n, pTerm);
+ pPage = &pWriter->writer;
+ }
+ }else{
+ nPrefix = fts5PrefixCompress(pPage->term.n, pPage->term.p, nTerm, pTerm);
+ fts5BufferAppendVarint(&p->rc, &pPage->buf, nPrefix);
+ }
+
+ /* Append the number of bytes of new data, then the term data itself
+ ** to the page. */
+ fts5BufferAppendVarint(&p->rc, &pPage->buf, nTerm - nPrefix);
+ fts5BufferAppendBlob(&p->rc, &pPage->buf, nTerm - nPrefix, &pTerm[nPrefix]);
+
+ /* Update the Fts5PageWriter.term field. */
+ fts5BufferSet(&p->rc, &pPage->term, nTerm, pTerm);
+ pWriter->bFirstTermInPage = 0;
+
+ pWriter->bFirstRowidInPage = 0;
+ pWriter->bFirstRowidInDoclist = 1;
+
+ assert( p->rc || (pWriter->nDlidx>0 && pWriter->aDlidx[0].buf.n==0) );
+ pWriter->aDlidx[0].pgno = pPage->pgno;
+}
+
+/*
+** Append a rowid and position-list size field to the writers output.
+*/
+static void fts5WriteAppendRowid(
+ Fts5Index *p,
+ Fts5SegWriter *pWriter,
+ i64 iRowid,
+ int nPos
+){
+ if( p->rc==SQLITE_OK ){
+ Fts5PageWriter *pPage = &pWriter->writer;
+
+ if( (pPage->buf.n + pPage->pgidx.n)>=p->pConfig->pgsz ){
+ fts5WriteFlushLeaf(p, pWriter);
+ }
+
+ /* If this is to be the first rowid written to the page, set the
+ ** rowid-pointer in the page-header. Also append a value to the dlidx
+ ** buffer, in case a doclist-index is required. */
+ if( pWriter->bFirstRowidInPage ){
+ fts5PutU16(pPage->buf.p, (u16)pPage->buf.n);
+ fts5WriteDlidxAppend(p, pWriter, iRowid);
+ }
+
+ /* Write the rowid. */
+ if( pWriter->bFirstRowidInDoclist || pWriter->bFirstRowidInPage ){
+ fts5BufferAppendVarint(&p->rc, &pPage->buf, iRowid);
+ }else{
+ assert( p->rc || iRowid>pWriter->iPrevRowid );
+ fts5BufferAppendVarint(&p->rc, &pPage->buf, iRowid - pWriter->iPrevRowid);
+ }
+ pWriter->iPrevRowid = iRowid;
+ pWriter->bFirstRowidInDoclist = 0;
+ pWriter->bFirstRowidInPage = 0;
+
+ fts5BufferAppendVarint(&p->rc, &pPage->buf, nPos);
+ }
+}
+
+static void fts5WriteAppendPoslistData(
+ Fts5Index *p,
+ Fts5SegWriter *pWriter,
+ const u8 *aData,
+ int nData
+){
+ Fts5PageWriter *pPage = &pWriter->writer;
+ const u8 *a = aData;
+ int n = nData;
+
+ assert( p->pConfig->pgsz>0 );
+ while( p->rc==SQLITE_OK
+ && (pPage->buf.n + pPage->pgidx.n + n)>=p->pConfig->pgsz
+ ){
+ int nReq = p->pConfig->pgsz - pPage->buf.n - pPage->pgidx.n;
+ int nCopy = 0;
+ while( nCopy<nReq ){
+ i64 dummy;
+ nCopy += fts5GetVarint(&a[nCopy], (u64*)&dummy);
+ }
+ fts5BufferAppendBlob(&p->rc, &pPage->buf, nCopy, a);
+ a += nCopy;
+ n -= nCopy;
+ fts5WriteFlushLeaf(p, pWriter);
+ }
+ if( n>0 ){
+ fts5BufferAppendBlob(&p->rc, &pPage->buf, n, a);
+ }
+}
+
+/*
+** Flush any data cached by the writer object to the database. Free any
+** allocations associated with the writer.
+*/
+static void fts5WriteFinish(
+ Fts5Index *p,
+ Fts5SegWriter *pWriter, /* Writer object */
+ int *pnLeaf /* OUT: Number of leaf pages in b-tree */
+){
+ int i;
+ Fts5PageWriter *pLeaf = &pWriter->writer;
+ if( p->rc==SQLITE_OK ){
+ assert( pLeaf->pgno>=1 );
+ if( pLeaf->buf.n>4 ){
+ fts5WriteFlushLeaf(p, pWriter);
+ }
+ *pnLeaf = pLeaf->pgno-1;
+ fts5WriteFlushBtree(p, pWriter);
+ }
+ fts5BufferFree(&pLeaf->term);
+ fts5BufferFree(&pLeaf->buf);
+ fts5BufferFree(&pLeaf->pgidx);
+ fts5BufferFree(&pWriter->btterm);
+
+ for(i=0; i<pWriter->nDlidx; i++){
+ sqlite3Fts5BufferFree(&pWriter->aDlidx[i].buf);
+ }
+ sqlite3_free(pWriter->aDlidx);
+}
+
+static void fts5WriteInit(
+ Fts5Index *p,
+ Fts5SegWriter *pWriter,
+ int iSegid
+){
+ const int nBuffer = p->pConfig->pgsz + FTS5_DATA_PADDING;
+
+ memset(pWriter, 0, sizeof(Fts5SegWriter));
+ pWriter->iSegid = iSegid;
+
+ fts5WriteDlidxGrow(p, pWriter, 1);
+ pWriter->writer.pgno = 1;
+ pWriter->bFirstTermInPage = 1;
+ pWriter->iBtPage = 1;
+
+ assert( pWriter->writer.buf.n==0 );
+ assert( pWriter->writer.pgidx.n==0 );
+
+ /* Grow the two buffers to pgsz + padding bytes in size. */
+ sqlite3Fts5BufferSize(&p->rc, &pWriter->writer.pgidx, nBuffer);
+ sqlite3Fts5BufferSize(&p->rc, &pWriter->writer.buf, nBuffer);
+
+ if( p->pIdxWriter==0 ){
+ Fts5Config *pConfig = p->pConfig;
+ fts5IndexPrepareStmt(p, &p->pIdxWriter, sqlite3_mprintf(
+ "INSERT INTO '%q'.'%q_idx'(segid,term,pgno) VALUES(?,?,?)",
+ pConfig->zDb, pConfig->zName
+ ));
+ }
+
+ if( p->rc==SQLITE_OK ){
+ /* Initialize the 4-byte leaf-page header to 0x00. */
+ memset(pWriter->writer.buf.p, 0, 4);
+ pWriter->writer.buf.n = 4;
+
+ /* Bind the current output segment id to the index-writer. This is an
+ ** optimization over binding the same value over and over as rows are
+ ** inserted into %_idx by the current writer. */
+ sqlite3_bind_int(p->pIdxWriter, 1, pWriter->iSegid);
+ }
+}
+
+/*
+** Iterator pIter was used to iterate through the input segments of on an
+** incremental merge operation. This function is called if the incremental
+** merge step has finished but the input has not been completely exhausted.
+*/
+static void fts5TrimSegments(Fts5Index *p, Fts5IndexIter *pIter){
+ int i;
+ Fts5Buffer buf;
+ memset(&buf, 0, sizeof(Fts5Buffer));
+ for(i=0; i<pIter->nSeg; i++){
+ Fts5SegIter *pSeg = &pIter->aSeg[i];
+ if( pSeg->pSeg==0 ){
+ /* no-op */
+ }else if( pSeg->pLeaf==0 ){
+ /* All keys from this input segment have been transfered to the output.
+ ** Set both the first and last page-numbers to 0 to indicate that the
+ ** segment is now empty. */
+ pSeg->pSeg->pgnoLast = 0;
+ pSeg->pSeg->pgnoFirst = 0;
+ }else{
+ int iOff = pSeg->iTermLeafOffset; /* Offset on new first leaf page */
+ i64 iLeafRowid;
+ Fts5Data *pData;
+ int iId = pSeg->pSeg->iSegid;
+ u8 aHdr[4] = {0x00, 0x00, 0x00, 0x00};
+
+ iLeafRowid = FTS5_SEGMENT_ROWID(iId, pSeg->iTermLeafPgno);
+ pData = fts5DataRead(p, iLeafRowid);
+ if( pData ){
+ fts5BufferZero(&buf);
+ fts5BufferGrow(&p->rc, &buf, pData->nn);
+ fts5BufferAppendBlob(&p->rc, &buf, sizeof(aHdr), aHdr);
+ fts5BufferAppendVarint(&p->rc, &buf, pSeg->term.n);
+ fts5BufferAppendBlob(&p->rc, &buf, pSeg->term.n, pSeg->term.p);
+ fts5BufferAppendBlob(&p->rc, &buf, pData->szLeaf-iOff, &pData->p[iOff]);
+ if( p->rc==SQLITE_OK ){
+ /* Set the szLeaf field */
+ fts5PutU16(&buf.p[2], (u16)buf.n);
+ }
+
+ /* Set up the new page-index array */
+ fts5BufferAppendVarint(&p->rc, &buf, 4);
+ if( pSeg->iLeafPgno==pSeg->iTermLeafPgno
+ && pSeg->iEndofDoclist<pData->szLeaf
+ ){
+ int nDiff = pData->szLeaf - pSeg->iEndofDoclist;
+ fts5BufferAppendVarint(&p->rc, &buf, buf.n - 1 - nDiff - 4);
+ fts5BufferAppendBlob(&p->rc, &buf,
+ pData->nn - pSeg->iPgidxOff, &pData->p[pSeg->iPgidxOff]
+ );
+ }
+
+ fts5DataRelease(pData);
+ pSeg->pSeg->pgnoFirst = pSeg->iTermLeafPgno;
+ fts5DataDelete(p, FTS5_SEGMENT_ROWID(iId, 1), iLeafRowid);
+ fts5DataWrite(p, iLeafRowid, buf.p, buf.n);
+ }
+ }
+ }
+ fts5BufferFree(&buf);
+}
+
+static void fts5MergeChunkCallback(
+ Fts5Index *p,
+ void *pCtx,
+ const u8 *pChunk, int nChunk
+){
+ Fts5SegWriter *pWriter = (Fts5SegWriter*)pCtx;
+ fts5WriteAppendPoslistData(p, pWriter, pChunk, nChunk);
+}
+
+/*
+**
+*/
+static void fts5IndexMergeLevel(
+ Fts5Index *p, /* FTS5 backend object */
+ Fts5Structure **ppStruct, /* IN/OUT: Stucture of index */
+ int iLvl, /* Level to read input from */
+ int *pnRem /* Write up to this many output leaves */
+){
+ Fts5Structure *pStruct = *ppStruct;
+ Fts5StructureLevel *pLvl = &pStruct->aLevel[iLvl];
+ Fts5StructureLevel *pLvlOut;
+ Fts5IndexIter *pIter = 0; /* Iterator to read input data */
+ int nRem = pnRem ? *pnRem : 0; /* Output leaf pages left to write */
+ int nInput; /* Number of input segments */
+ Fts5SegWriter writer; /* Writer object */
+ Fts5StructureSegment *pSeg; /* Output segment */
+ Fts5Buffer term;
+ int bOldest; /* True if the output segment is the oldest */
+
+ assert( iLvl<pStruct->nLevel );
+ assert( pLvl->nMerge<=pLvl->nSeg );
+
+ memset(&writer, 0, sizeof(Fts5SegWriter));
+ memset(&term, 0, sizeof(Fts5Buffer));
+ if( pLvl->nMerge ){
+ pLvlOut = &pStruct->aLevel[iLvl+1];
+ assert( pLvlOut->nSeg>0 );
+ nInput = pLvl->nMerge;
+ pSeg = &pLvlOut->aSeg[pLvlOut->nSeg-1];
+
+ fts5WriteInit(p, &writer, pSeg->iSegid);
+ writer.writer.pgno = pSeg->pgnoLast+1;
+ writer.iBtPage = 0;
+ }else{
+ int iSegid = fts5AllocateSegid(p, pStruct);
+
+ /* Extend the Fts5Structure object as required to ensure the output
+ ** segment exists. */
+ if( iLvl==pStruct->nLevel-1 ){
+ fts5StructureAddLevel(&p->rc, ppStruct);
+ pStruct = *ppStruct;
+ }
+ fts5StructureExtendLevel(&p->rc, pStruct, iLvl+1, 1, 0);
+ if( p->rc ) return;
+ pLvl = &pStruct->aLevel[iLvl];
+ pLvlOut = &pStruct->aLevel[iLvl+1];
+
+ fts5WriteInit(p, &writer, iSegid);
+
+ /* Add the new segment to the output level */
+ pSeg = &pLvlOut->aSeg[pLvlOut->nSeg];
+ pLvlOut->nSeg++;
+ pSeg->pgnoFirst = 1;
+ pSeg->iSegid = iSegid;
+ pStruct->nSegment++;
+
+ /* Read input from all segments in the input level */
+ nInput = pLvl->nSeg;
+ }
+ bOldest = (pLvlOut->nSeg==1 && pStruct->nLevel==iLvl+2);
+
+ assert( iLvl>=0 );
+ for(fts5MultiIterNew(p, pStruct, 0, 0, 0, 0, iLvl, nInput, &pIter);
+ fts5MultiIterEof(p, pIter)==0;
+ fts5MultiIterNext(p, pIter, 0, 0)
+ ){
+ Fts5SegIter *pSegIter = &pIter->aSeg[ pIter->aFirst[1].iFirst ];
+ int nPos; /* position-list size field value */
+ int nTerm;
+ const u8 *pTerm;
+
+ /* Check for key annihilation. */
+ if( pSegIter->nPos==0 && (bOldest || pSegIter->bDel==0) ) continue;
+
+ pTerm = fts5MultiIterTerm(pIter, &nTerm);
+ if( nTerm!=term.n || memcmp(pTerm, term.p, nTerm) ){
+ if( pnRem && writer.nLeafWritten>nRem ){
+ break;
+ }
+
+ /* This is a new term. Append a term to the output segment. */
+ fts5WriteAppendTerm(p, &writer, nTerm, pTerm);
+ fts5BufferSet(&p->rc, &term, nTerm, pTerm);
+ }
+
+ /* Append the rowid to the output */
+ /* WRITEPOSLISTSIZE */
+ nPos = pSegIter->nPos*2 + pSegIter->bDel;
+ fts5WriteAppendRowid(p, &writer, fts5MultiIterRowid(pIter), nPos);
+
+ /* Append the position-list data to the output */
+ fts5ChunkIterate(p, pSegIter, (void*)&writer, fts5MergeChunkCallback);
+ }
+
+ /* Flush the last leaf page to disk. Set the output segment b-tree height
+ ** and last leaf page number at the same time. */
+ fts5WriteFinish(p, &writer, &pSeg->pgnoLast);
+
+ if( fts5MultiIterEof(p, pIter) ){
+ int i;
+
+ /* Remove the redundant segments from the %_data table */
+ for(i=0; i<nInput; i++){
+ fts5DataRemoveSegment(p, pLvl->aSeg[i].iSegid);
+ }
+
+ /* Remove the redundant segments from the input level */
+ if( pLvl->nSeg!=nInput ){
+ int nMove = (pLvl->nSeg - nInput) * sizeof(Fts5StructureSegment);
+ memmove(pLvl->aSeg, &pLvl->aSeg[nInput], nMove);
+ }
+ pStruct->nSegment -= nInput;
+ pLvl->nSeg -= nInput;
+ pLvl->nMerge = 0;
+ if( pSeg->pgnoLast==0 ){
+ pLvlOut->nSeg--;
+ pStruct->nSegment--;
+ }
+ }else{
+ assert( pSeg->pgnoLast>0 );
+ fts5TrimSegments(p, pIter);
+ pLvl->nMerge = nInput;
+ }
+
+ fts5MultiIterFree(p, pIter);
+ fts5BufferFree(&term);
+ if( pnRem ) *pnRem -= writer.nLeafWritten;
+}
+
+/*
+** Do up to nPg pages of automerge work on the index.
+*/
+static void fts5IndexMerge(
+ Fts5Index *p, /* FTS5 backend object */
+ Fts5Structure **ppStruct, /* IN/OUT: Current structure of index */
+ int nPg /* Pages of work to do */
+){
+ int nRem = nPg;
+ Fts5Structure *pStruct = *ppStruct;
+ while( nRem>0 && p->rc==SQLITE_OK ){
+ int iLvl; /* To iterate through levels */
+ int iBestLvl = 0; /* Level offering the most input segments */
+ int nBest = 0; /* Number of input segments on best level */
+
+ /* Set iBestLvl to the level to read input segments from. */
+ assert( pStruct->nLevel>0 );
+ for(iLvl=0; iLvl<pStruct->nLevel; iLvl++){
+ Fts5StructureLevel *pLvl = &pStruct->aLevel[iLvl];
+ if( pLvl->nMerge ){
+ if( pLvl->nMerge>nBest ){
+ iBestLvl = iLvl;
+ nBest = pLvl->nMerge;
+ }
+ break;
+ }
+ if( pLvl->nSeg>nBest ){
+ nBest = pLvl->nSeg;
+ iBestLvl = iLvl;
+ }
+ }
+
+ /* If nBest is still 0, then the index must be empty. */
+#ifdef SQLITE_DEBUG
+ for(iLvl=0; nBest==0 && iLvl<pStruct->nLevel; iLvl++){
+ assert( pStruct->aLevel[iLvl].nSeg==0 );
+ }
+#endif
+
+ if( nBest<p->pConfig->nAutomerge
+ && pStruct->aLevel[iBestLvl].nMerge==0
+ ){
+ break;
+ }
+ fts5IndexMergeLevel(p, &pStruct, iBestLvl, &nRem);
+ if( p->rc==SQLITE_OK && pStruct->aLevel[iBestLvl].nMerge==0 ){
+ fts5StructurePromote(p, iBestLvl+1, pStruct);
+ }
+ }
+ *ppStruct = pStruct;
+}
+
+/*
+** A total of nLeaf leaf pages of data has just been flushed to a level-0
+** segment. This function updates the write-counter accordingly and, if
+** necessary, performs incremental merge work.
+**
+** If an error occurs, set the Fts5Index.rc error code. If an error has
+** already occurred, this function is a no-op.
+*/
+static void fts5IndexAutomerge(
+ Fts5Index *p, /* FTS5 backend object */
+ Fts5Structure **ppStruct, /* IN/OUT: Current structure of index */
+ int nLeaf /* Number of output leaves just written */
+){
+ if( p->rc==SQLITE_OK && p->pConfig->nAutomerge>0 ){
+ Fts5Structure *pStruct = *ppStruct;
+ u64 nWrite; /* Initial value of write-counter */
+ int nWork; /* Number of work-quanta to perform */
+ int nRem; /* Number of leaf pages left to write */
+
+ /* Update the write-counter. While doing so, set nWork. */
+ nWrite = pStruct->nWriteCounter;
+ nWork = (int)(((nWrite + nLeaf) / p->nWorkUnit) - (nWrite / p->nWorkUnit));
+ pStruct->nWriteCounter += nLeaf;
+ nRem = (int)(p->nWorkUnit * nWork * pStruct->nLevel);
+
+ fts5IndexMerge(p, ppStruct, nRem);
+ }
+}
+
+static void fts5IndexCrisismerge(
+ Fts5Index *p, /* FTS5 backend object */
+ Fts5Structure **ppStruct /* IN/OUT: Current structure of index */
+){
+ const int nCrisis = p->pConfig->nCrisisMerge;
+ Fts5Structure *pStruct = *ppStruct;
+ int iLvl = 0;
+
+ assert( p->rc!=SQLITE_OK || pStruct->nLevel>0 );
+ while( p->rc==SQLITE_OK && pStruct->aLevel[iLvl].nSeg>=nCrisis ){
+ fts5IndexMergeLevel(p, &pStruct, iLvl, 0);
+ assert( p->rc!=SQLITE_OK || pStruct->nLevel>(iLvl+1) );
+ fts5StructurePromote(p, iLvl+1, pStruct);
+ iLvl++;
+ }
+ *ppStruct = pStruct;
+}
+
+static int fts5IndexReturn(Fts5Index *p){
+ int rc = p->rc;
+ p->rc = SQLITE_OK;
+ return rc;
+}
+
+typedef struct Fts5FlushCtx Fts5FlushCtx;
+struct Fts5FlushCtx {
+ Fts5Index *pIdx;
+ Fts5SegWriter writer;
+};
+
+/*
+** Buffer aBuf[] contains a list of varints, all small enough to fit
+** in a 32-bit integer. Return the size of the largest prefix of this
+** list nMax bytes or less in size.
+*/
+static int fts5PoslistPrefix(const u8 *aBuf, int nMax){
+ int ret;
+ u32 dummy;
+ ret = fts5GetVarint32(aBuf, dummy);
+ if( ret<nMax ){
+ while( 1 ){
+ int i = fts5GetVarint32(&aBuf[ret], dummy);
+ if( (ret + i) > nMax ) break;
+ ret += i;
+ }
+ }
+ return ret;
+}
+
+/*
+** Flush the contents of in-memory hash table iHash to a new level-0
+** segment on disk. Also update the corresponding structure record.
+**
+** If an error occurs, set the Fts5Index.rc error code. If an error has
+** already occurred, this function is a no-op.
+*/
+static void fts5FlushOneHash(Fts5Index *p){
+ Fts5Hash *pHash = p->pHash;
+ Fts5Structure *pStruct;
+ int iSegid;
+ int pgnoLast = 0; /* Last leaf page number in segment */
+
+ /* Obtain a reference to the index structure and allocate a new segment-id
+ ** for the new level-0 segment. */
+ pStruct = fts5StructureRead(p);
+ iSegid = fts5AllocateSegid(p, pStruct);
+
+ if( iSegid ){
+ const int pgsz = p->pConfig->pgsz;
+
+ Fts5StructureSegment *pSeg; /* New segment within pStruct */
+ Fts5Buffer *pBuf; /* Buffer in which to assemble leaf page */
+ Fts5Buffer *pPgidx; /* Buffer in which to assemble pgidx */
+
+ Fts5SegWriter writer;
+ fts5WriteInit(p, &writer, iSegid);
+
+ pBuf = &writer.writer.buf;
+ pPgidx = &writer.writer.pgidx;
+
+ /* fts5WriteInit() should have initialized the buffers to (most likely)
+ ** the maximum space required. */
+ assert( p->rc || pBuf->nSpace>=(pgsz + FTS5_DATA_PADDING) );
+ assert( p->rc || pPgidx->nSpace>=(pgsz + FTS5_DATA_PADDING) );
+
+ /* Begin scanning through hash table entries. This loop runs once for each
+ ** term/doclist currently stored within the hash table. */
+ if( p->rc==SQLITE_OK ){
+ p->rc = sqlite3Fts5HashScanInit(pHash, 0, 0);
+ }
+ while( p->rc==SQLITE_OK && 0==sqlite3Fts5HashScanEof(pHash) ){
+ const char *zTerm; /* Buffer containing term */
+ const u8 *pDoclist; /* Pointer to doclist for this term */
+ int nDoclist; /* Size of doclist in bytes */
+
+ /* Write the term for this entry to disk. */
+ sqlite3Fts5HashScanEntry(pHash, &zTerm, &pDoclist, &nDoclist);
+ fts5WriteAppendTerm(p, &writer, (int)strlen(zTerm), (const u8*)zTerm);
+
+ assert( writer.bFirstRowidInPage==0 );
+ if( pgsz>=(pBuf->n + pPgidx->n + nDoclist + 1) ){
+ /* The entire doclist will fit on the current leaf. */
+ fts5BufferSafeAppendBlob(pBuf, pDoclist, nDoclist);
+ }else{
+ i64 iRowid = 0;
+ i64 iDelta = 0;
+ int iOff = 0;
+
+ /* The entire doclist will not fit on this leaf. The following
+ ** loop iterates through the poslists that make up the current
+ ** doclist. */
+ while( p->rc==SQLITE_OK && iOff<nDoclist ){
+ int nPos;
+ int nCopy;
+ int bDummy;
+ iOff += fts5GetVarint(&pDoclist[iOff], (u64*)&iDelta);
+ nCopy = fts5GetPoslistSize(&pDoclist[iOff], &nPos, &bDummy);
+ nCopy += nPos;
+ iRowid += iDelta;
+
+ if( writer.bFirstRowidInPage ){
+ fts5PutU16(&pBuf->p[0], (u16)pBuf->n); /* first rowid on page */
+ pBuf->n += sqlite3Fts5PutVarint(&pBuf->p[pBuf->n], iRowid);
+ writer.bFirstRowidInPage = 0;
+ fts5WriteDlidxAppend(p, &writer, iRowid);
+ }else{
+ pBuf->n += sqlite3Fts5PutVarint(&pBuf->p[pBuf->n], iDelta);
+ }
+ assert( pBuf->n<=pBuf->nSpace );
+
+ if( (pBuf->n + pPgidx->n + nCopy) <= pgsz ){
+ /* The entire poslist will fit on the current leaf. So copy
+ ** it in one go. */
+ fts5BufferSafeAppendBlob(pBuf, &pDoclist[iOff], nCopy);
+ }else{
+ /* The entire poslist will not fit on this leaf. So it needs
+ ** to be broken into sections. The only qualification being
+ ** that each varint must be stored contiguously. */
+ const u8 *pPoslist = &pDoclist[iOff];
+ int iPos = 0;
+ while( p->rc==SQLITE_OK ){
+ int nSpace = pgsz - pBuf->n - pPgidx->n;
+ int n = 0;
+ if( (nCopy - iPos)<=nSpace ){
+ n = nCopy - iPos;
+ }else{
+ n = fts5PoslistPrefix(&pPoslist[iPos], nSpace);
+ }
+ assert( n>0 );
+ fts5BufferSafeAppendBlob(pBuf, &pPoslist[iPos], n);
+ iPos += n;
+ if( (pBuf->n + pPgidx->n)>=pgsz ){
+ fts5WriteFlushLeaf(p, &writer);
+ }
+ if( iPos>=nCopy ) break;
+ }
+ }
+ iOff += nCopy;
+ }
+ }
+
+ /* TODO2: Doclist terminator written here. */
+ /* pBuf->p[pBuf->n++] = '\0'; */
+ assert( pBuf->n<=pBuf->nSpace );
+ sqlite3Fts5HashScanNext(pHash);
+ }
+ sqlite3Fts5HashClear(pHash);
+ fts5WriteFinish(p, &writer, &pgnoLast);
+
+ /* Update the Fts5Structure. It is written back to the database by the
+ ** fts5StructureRelease() call below. */
+ if( pStruct->nLevel==0 ){
+ fts5StructureAddLevel(&p->rc, &pStruct);
+ }
+ fts5StructureExtendLevel(&p->rc, pStruct, 0, 1, 0);
+ if( p->rc==SQLITE_OK ){
+ pSeg = &pStruct->aLevel[0].aSeg[ pStruct->aLevel[0].nSeg++ ];
+ pSeg->iSegid = iSegid;
+ pSeg->pgnoFirst = 1;
+ pSeg->pgnoLast = pgnoLast;
+ pStruct->nSegment++;
+ }
+ fts5StructurePromote(p, 0, pStruct);
+ }
+
+ fts5IndexAutomerge(p, &pStruct, pgnoLast);
+ fts5IndexCrisismerge(p, &pStruct);
+ fts5StructureWrite(p, pStruct);
+ fts5StructureRelease(pStruct);
+}
+
+/*
+** Flush any data stored in the in-memory hash tables to the database.
+*/
+static void fts5IndexFlush(Fts5Index *p){
+ /* Unless it is empty, flush the hash table to disk */
+ if( p->nPendingData ){
+ assert( p->pHash );
+ p->nPendingData = 0;
+ fts5FlushOneHash(p);
+ }
+}
+
+
+static int sqlite3Fts5IndexOptimize(Fts5Index *p){
+ Fts5Structure *pStruct;
+ Fts5Structure *pNew = 0;
+ int nSeg = 0;
+
+ assert( p->rc==SQLITE_OK );
+ fts5IndexFlush(p);
+ pStruct = fts5StructureRead(p);
+
+ if( pStruct ){
+ assert( pStruct->nSegment==fts5StructureCountSegments(pStruct) );
+ nSeg = pStruct->nSegment;
+ if( nSeg>1 ){
+ int nByte = sizeof(Fts5Structure);
+ nByte += (pStruct->nLevel+1) * sizeof(Fts5StructureLevel);
+ pNew = (Fts5Structure*)sqlite3Fts5MallocZero(&p->rc, nByte);
+ }
+ }
+ if( pNew ){
+ Fts5StructureLevel *pLvl;
+ int nByte = nSeg * sizeof(Fts5StructureSegment);
+ pNew->nLevel = pStruct->nLevel+1;
+ pNew->nRef = 1;
+ pNew->nWriteCounter = pStruct->nWriteCounter;
+ pLvl = &pNew->aLevel[pStruct->nLevel];
+ pLvl->aSeg = (Fts5StructureSegment*)sqlite3Fts5MallocZero(&p->rc, nByte);
+ if( pLvl->aSeg ){
+ int iLvl, iSeg;
+ int iSegOut = 0;
+ for(iLvl=0; iLvl<pStruct->nLevel; iLvl++){
+ for(iSeg=0; iSeg<pStruct->aLevel[iLvl].nSeg; iSeg++){
+ pLvl->aSeg[iSegOut] = pStruct->aLevel[iLvl].aSeg[iSeg];
+ iSegOut++;
+ }
+ }
+ pNew->nSegment = pLvl->nSeg = nSeg;
+ }else{
+ sqlite3_free(pNew);
+ pNew = 0;
+ }
+ }
+
+ if( pNew ){
+ int iLvl = pNew->nLevel-1;
+ while( p->rc==SQLITE_OK && pNew->aLevel[iLvl].nSeg>0 ){
+ int nRem = FTS5_OPT_WORK_UNIT;
+ fts5IndexMergeLevel(p, &pNew, iLvl, &nRem);
+ }
+
+ fts5StructureWrite(p, pNew);
+ fts5StructureRelease(pNew);
+ }
+
+ fts5StructureRelease(pStruct);
+ return fts5IndexReturn(p);
+}
+
+static int sqlite3Fts5IndexMerge(Fts5Index *p, int nMerge){
+ Fts5Structure *pStruct;
+
+ pStruct = fts5StructureRead(p);
+ if( pStruct && pStruct->nLevel ){
+ fts5IndexMerge(p, &pStruct, nMerge);
+ fts5StructureWrite(p, pStruct);
+ }
+ fts5StructureRelease(pStruct);
+
+ return fts5IndexReturn(p);
+}
+
+static void fts5PoslistCallback(
+ Fts5Index *p,
+ void *pContext,
+ const u8 *pChunk, int nChunk
+){
+ assert_nc( nChunk>=0 );
+ if( nChunk>0 ){
+ fts5BufferSafeAppendBlob((Fts5Buffer*)pContext, pChunk, nChunk);
+ }
+}
+
+typedef struct PoslistCallbackCtx PoslistCallbackCtx;
+struct PoslistCallbackCtx {
+ Fts5Buffer *pBuf; /* Append to this buffer */
+ Fts5Colset *pColset; /* Restrict matches to this column */
+ int eState; /* See above */
+};
+
+/*
+** TODO: Make this more efficient!
+*/
+static int fts5IndexColsetTest(Fts5Colset *pColset, int iCol){
+ int i;
+ for(i=0; i<pColset->nCol; i++){
+ if( pColset->aiCol[i]==iCol ) return 1;
+ }
+ return 0;
+}
+
+static void fts5PoslistFilterCallback(
+ Fts5Index *p,
+ void *pContext,
+ const u8 *pChunk, int nChunk
+){
+ PoslistCallbackCtx *pCtx = (PoslistCallbackCtx*)pContext;
+ assert_nc( nChunk>=0 );
+ if( nChunk>0 ){
+ /* Search through to find the first varint with value 1. This is the
+ ** start of the next columns hits. */
+ int i = 0;
+ int iStart = 0;
+
+ if( pCtx->eState==2 ){
+ int iCol;
+ fts5FastGetVarint32(pChunk, i, iCol);
+ if( fts5IndexColsetTest(pCtx->pColset, iCol) ){
+ pCtx->eState = 1;
+ fts5BufferSafeAppendVarint(pCtx->pBuf, 1);
+ }else{
+ pCtx->eState = 0;
+ }
+ }
+
+ do {
+ while( i<nChunk && pChunk[i]!=0x01 ){
+ while( pChunk[i] & 0x80 ) i++;
+ i++;
+ }
+ if( pCtx->eState ){
+ fts5BufferSafeAppendBlob(pCtx->pBuf, &pChunk[iStart], i-iStart);
+ }
+ if( i<nChunk ){
+ int iCol;
+ iStart = i;
+ i++;
+ if( i>=nChunk ){
+ pCtx->eState = 2;
+ }else{
+ fts5FastGetVarint32(pChunk, i, iCol);
+ pCtx->eState = fts5IndexColsetTest(pCtx->pColset, iCol);
+ if( pCtx->eState ){
+ fts5BufferSafeAppendBlob(pCtx->pBuf, &pChunk[iStart], i-iStart);
+ iStart = i;
+ }
+ }
+ }
+ }while( i<nChunk );
+ }
+}
+
+/*
+** Iterator pIter currently points to a valid entry (not EOF). This
+** function appends the position list data for the current entry to
+** buffer pBuf. It does not make a copy of the position-list size
+** field.
+*/
+static void fts5SegiterPoslist(
+ Fts5Index *p,
+ Fts5SegIter *pSeg,
+ Fts5Colset *pColset,
+ Fts5Buffer *pBuf
+){
+ if( 0==fts5BufferGrow(&p->rc, pBuf, pSeg->nPos) ){
+ if( pColset==0 ){
+ fts5ChunkIterate(p, pSeg, (void*)pBuf, fts5PoslistCallback);
+ }else{
+ PoslistCallbackCtx sCtx;
+ sCtx.pBuf = pBuf;
+ sCtx.pColset = pColset;
+ sCtx.eState = fts5IndexColsetTest(pColset, 0);
+ assert( sCtx.eState==0 || sCtx.eState==1 );
+ fts5ChunkIterate(p, pSeg, (void*)&sCtx, fts5PoslistFilterCallback);
+ }
+ }
+}
+
+/*
+** IN/OUT parameter (*pa) points to a position list n bytes in size. If
+** the position list contains entries for column iCol, then (*pa) is set
+** to point to the sub-position-list for that column and the number of
+** bytes in it returned. Or, if the argument position list does not
+** contain any entries for column iCol, return 0.
+*/
+static int fts5IndexExtractCol(
+ const u8 **pa, /* IN/OUT: Pointer to poslist */
+ int n, /* IN: Size of poslist in bytes */
+ int iCol /* Column to extract from poslist */
+){
+ int iCurrent = 0; /* Anything before the first 0x01 is col 0 */
+ const u8 *p = *pa;
+ const u8 *pEnd = &p[n]; /* One byte past end of position list */
+ u8 prev = 0;
+
+ while( iCol>iCurrent ){
+ /* Advance pointer p until it points to pEnd or an 0x01 byte that is
+ ** not part of a varint */
+ while( (prev & 0x80) || *p!=0x01 ){
+ prev = *p++;
+ if( p==pEnd ) return 0;
+ }
+ *pa = p++;
+ p += fts5GetVarint32(p, iCurrent);
+ }
+ if( iCol!=iCurrent ) return 0;
+
+ /* Advance pointer p until it points to pEnd or an 0x01 byte that is
+ ** not part of a varint */
+ assert( (prev & 0x80)==0 );
+ while( p<pEnd && ((prev & 0x80) || *p!=0x01) ){
+ prev = *p++;
+ }
+ return p - (*pa);
+}
+
+
+/*
+** Iterator pMulti currently points to a valid entry (not EOF). This
+** function appends the following to buffer pBuf:
+**
+** * The varint iDelta, and
+** * the position list that currently points to, including the size field.
+**
+** If argument pColset is NULL, then the position list is filtered according
+** to pColset before being appended to the buffer. If this means there are
+** no entries in the position list, nothing is appended to the buffer (not
+** even iDelta).
+**
+** If an error occurs, an error code is left in p->rc.
+*/
+static int fts5AppendPoslist(
+ Fts5Index *p,
+ i64 iDelta,
+ Fts5IndexIter *pMulti,
+ Fts5Colset *pColset,
+ Fts5Buffer *pBuf
+){
+ if( p->rc==SQLITE_OK ){
+ Fts5SegIter *pSeg = &pMulti->aSeg[ pMulti->aFirst[1].iFirst ];
+ assert( fts5MultiIterEof(p, pMulti)==0 );
+ assert( pSeg->nPos>0 );
+ if( 0==fts5BufferGrow(&p->rc, pBuf, pSeg->nPos+9+9) ){
+
+ if( pSeg->iLeafOffset+pSeg->nPos<=pSeg->pLeaf->szLeaf
+ && (pColset==0 || pColset->nCol==1)
+ ){
+ const u8 *pPos = &pSeg->pLeaf->p[pSeg->iLeafOffset];
+ int nPos;
+ if( pColset ){
+ nPos = fts5IndexExtractCol(&pPos, pSeg->nPos, pColset->aiCol[0]);
+ if( nPos==0 ) return 1;
+ }else{
+ nPos = pSeg->nPos;
+ }
+ assert( nPos>0 );
+ fts5BufferSafeAppendVarint(pBuf, iDelta);
+ fts5BufferSafeAppendVarint(pBuf, nPos*2);
+ fts5BufferSafeAppendBlob(pBuf, pPos, nPos);
+ }else{
+ int iSv1;
+ int iSv2;
+ int iData;
+
+ /* Append iDelta */
+ iSv1 = pBuf->n;
+ fts5BufferSafeAppendVarint(pBuf, iDelta);
+
+ /* WRITEPOSLISTSIZE */
+ iSv2 = pBuf->n;
+ fts5BufferSafeAppendVarint(pBuf, pSeg->nPos*2);
+ iData = pBuf->n;
+
+ fts5SegiterPoslist(p, pSeg, pColset, pBuf);
+
+ if( pColset ){
+ int nActual = pBuf->n - iData;
+ if( nActual!=pSeg->nPos ){
+ if( nActual==0 ){
+ pBuf->n = iSv1;
+ return 1;
+ }else{
+ int nReq = sqlite3Fts5GetVarintLen((u32)(nActual*2));
+ while( iSv2<(iData-nReq) ){ pBuf->p[iSv2++] = 0x80; }
+ sqlite3Fts5PutVarint(&pBuf->p[iSv2], nActual*2);
+ }
+ }
+ }
+ }
+
+ }
+ }
+
+ return 0;
+}
+
+static void fts5DoclistIterNext(Fts5DoclistIter *pIter){
+ u8 *p = pIter->aPoslist + pIter->nSize + pIter->nPoslist;
+
+ assert( pIter->aPoslist );
+ if( p>=pIter->aEof ){
+ pIter->aPoslist = 0;
+ }else{
+ i64 iDelta;
+
+ p += fts5GetVarint(p, (u64*)&iDelta);
+ pIter->iRowid += iDelta;
+
+ /* Read position list size */
+ if( p[0] & 0x80 ){
+ int nPos;
+ pIter->nSize = fts5GetVarint32(p, nPos);
+ pIter->nPoslist = (nPos>>1);
+ }else{
+ pIter->nPoslist = ((int)(p[0])) >> 1;
+ pIter->nSize = 1;
+ }
+
+ pIter->aPoslist = p;
+ }
+}
+
+static void fts5DoclistIterInit(
+ Fts5Buffer *pBuf,
+ Fts5DoclistIter *pIter
+){
+ memset(pIter, 0, sizeof(*pIter));
+ pIter->aPoslist = pBuf->p;
+ pIter->aEof = &pBuf->p[pBuf->n];
+ fts5DoclistIterNext(pIter);
+}
+
+#if 0
+/*
+** Append a doclist to buffer pBuf.
+**
+** This function assumes that space within the buffer has already been
+** allocated.
+*/
+static void fts5MergeAppendDocid(
+ Fts5Buffer *pBuf, /* Buffer to write to */
+ i64 *piLastRowid, /* IN/OUT: Previous rowid written (if any) */
+ i64 iRowid /* Rowid to append */
+){
+ assert( pBuf->n!=0 || (*piLastRowid)==0 );
+ fts5BufferSafeAppendVarint(pBuf, iRowid - *piLastRowid);
+ *piLastRowid = iRowid;
+}
+#endif
+
+#define fts5MergeAppendDocid(pBuf, iLastRowid, iRowid) { \
+ assert( (pBuf)->n!=0 || (iLastRowid)==0 ); \
+ fts5BufferSafeAppendVarint((pBuf), (iRowid) - (iLastRowid)); \
+ (iLastRowid) = (iRowid); \
+}
+
+/*
+** Buffers p1 and p2 contain doclists. This function merges the content
+** of the two doclists together and sets buffer p1 to the result before
+** returning.
+**
+** If an error occurs, an error code is left in p->rc. If an error has
+** already occurred, this function is a no-op.
+*/
+static void fts5MergePrefixLists(
+ Fts5Index *p, /* FTS5 backend object */
+ Fts5Buffer *p1, /* First list to merge */
+ Fts5Buffer *p2 /* Second list to merge */
+){
+ if( p2->n ){
+ i64 iLastRowid = 0;
+ Fts5DoclistIter i1;
+ Fts5DoclistIter i2;
+ Fts5Buffer out;
+ Fts5Buffer tmp;
+ memset(&out, 0, sizeof(out));
+ memset(&tmp, 0, sizeof(tmp));
+
+ sqlite3Fts5BufferSize(&p->rc, &out, p1->n + p2->n);
+ fts5DoclistIterInit(p1, &i1);
+ fts5DoclistIterInit(p2, &i2);
+ while( p->rc==SQLITE_OK && (i1.aPoslist!=0 || i2.aPoslist!=0) ){
+ if( i2.aPoslist==0 || (i1.aPoslist && i1.iRowid<i2.iRowid) ){
+ /* Copy entry from i1 */
+ fts5MergeAppendDocid(&out, iLastRowid, i1.iRowid);
+ fts5BufferSafeAppendBlob(&out, i1.aPoslist, i1.nPoslist+i1.nSize);
+ fts5DoclistIterNext(&i1);
+ }
+ else if( i1.aPoslist==0 || i2.iRowid!=i1.iRowid ){
+ /* Copy entry from i2 */
+ fts5MergeAppendDocid(&out, iLastRowid, i2.iRowid);
+ fts5BufferSafeAppendBlob(&out, i2.aPoslist, i2.nPoslist+i2.nSize);
+ fts5DoclistIterNext(&i2);
+ }
+ else{
+ i64 iPos1 = 0;
+ i64 iPos2 = 0;
+ int iOff1 = 0;
+ int iOff2 = 0;
+ u8 *a1 = &i1.aPoslist[i1.nSize];
+ u8 *a2 = &i2.aPoslist[i2.nSize];
+
+ Fts5PoslistWriter writer;
+ memset(&writer, 0, sizeof(writer));
+
+ /* Merge the two position lists. */
+ fts5MergeAppendDocid(&out, iLastRowid, i2.iRowid);
+ fts5BufferZero(&tmp);
+
+ sqlite3Fts5PoslistNext64(a1, i1.nPoslist, &iOff1, &iPos1);
+ sqlite3Fts5PoslistNext64(a2, i2.nPoslist, &iOff2, &iPos2);
+
+ while( p->rc==SQLITE_OK && (iPos1>=0 || iPos2>=0) ){
+ i64 iNew;
+ if( iPos2<0 || (iPos1>=0 && iPos1<iPos2) ){
+ iNew = iPos1;
+ sqlite3Fts5PoslistNext64(a1, i1.nPoslist, &iOff1, &iPos1);
+ }else{
+ iNew = iPos2;
+ sqlite3Fts5PoslistNext64(a2, i2.nPoslist, &iOff2, &iPos2);
+ if( iPos1==iPos2 ){
+ sqlite3Fts5PoslistNext64(a1, i1.nPoslist, &iOff1,&iPos1);
+ }
+ }
+ p->rc = sqlite3Fts5PoslistWriterAppend(&tmp, &writer, iNew);
+ }
+
+ /* WRITEPOSLISTSIZE */
+ fts5BufferSafeAppendVarint(&out, tmp.n * 2);
+ fts5BufferSafeAppendBlob(&out, tmp.p, tmp.n);
+ fts5DoclistIterNext(&i1);
+ fts5DoclistIterNext(&i2);
+ }
+ }
+
+ fts5BufferSet(&p->rc, p1, out.n, out.p);
+ fts5BufferFree(&tmp);
+ fts5BufferFree(&out);
+ }
+}
+
+static void fts5BufferSwap(Fts5Buffer *p1, Fts5Buffer *p2){
+ Fts5Buffer tmp = *p1;
+ *p1 = *p2;
+ *p2 = tmp;
+}
+
+static void fts5SetupPrefixIter(
+ Fts5Index *p, /* Index to read from */
+ int bDesc, /* True for "ORDER BY rowid DESC" */
+ const u8 *pToken, /* Buffer containing prefix to match */
+ int nToken, /* Size of buffer pToken in bytes */
+ Fts5Colset *pColset, /* Restrict matches to these columns */
+ Fts5IndexIter **ppIter /* OUT: New iterator */
+){
+ Fts5Structure *pStruct;
+ Fts5Buffer *aBuf;
+ const int nBuf = 32;
+
+ aBuf = (Fts5Buffer*)fts5IdxMalloc(p, sizeof(Fts5Buffer)*nBuf);
+ pStruct = fts5StructureRead(p);
+
+ if( aBuf && pStruct ){
+ const int flags = FTS5INDEX_QUERY_SCAN;
+ int i;
+ i64 iLastRowid = 0;
+ Fts5IndexIter *p1 = 0; /* Iterator used to gather data from index */
+ Fts5Data *pData;
+ Fts5Buffer doclist;
+ int bNewTerm = 1;
+
+ memset(&doclist, 0, sizeof(doclist));
+ for(fts5MultiIterNew(p, pStruct, 1, flags, pToken, nToken, -1, 0, &p1);
+ fts5MultiIterEof(p, p1)==0;
+ fts5MultiIterNext2(p, p1, &bNewTerm)
+ ){
+ i64 iRowid = fts5MultiIterRowid(p1);
+ int nTerm;
+ const u8 *pTerm = fts5MultiIterTerm(p1, &nTerm);
+ assert_nc( memcmp(pToken, pTerm, MIN(nToken, nTerm))<=0 );
+ if( bNewTerm ){
+ if( nTerm<nToken || memcmp(pToken, pTerm, nToken) ) break;
+ }
+
+ if( doclist.n>0 && iRowid<=iLastRowid ){
+ for(i=0; p->rc==SQLITE_OK && doclist.n; i++){
+ assert( i<nBuf );
+ if( aBuf[i].n==0 ){
+ fts5BufferSwap(&doclist, &aBuf[i]);
+ fts5BufferZero(&doclist);
+ }else{
+ fts5MergePrefixLists(p, &doclist, &aBuf[i]);
+ fts5BufferZero(&aBuf[i]);
+ }
+ }
+ iLastRowid = 0;
+ }
+
+ if( !fts5AppendPoslist(p, iRowid-iLastRowid, p1, pColset, &doclist) ){
+ iLastRowid = iRowid;
+ }
+ }
+
+ for(i=0; i<nBuf; i++){
+ if( p->rc==SQLITE_OK ){
+ fts5MergePrefixLists(p, &doclist, &aBuf[i]);
+ }
+ fts5BufferFree(&aBuf[i]);
+ }
+ fts5MultiIterFree(p, p1);
+
+ pData = fts5IdxMalloc(p, sizeof(Fts5Data) + doclist.n);
+ if( pData ){
+ pData->p = (u8*)&pData[1];
+ pData->nn = pData->szLeaf = doclist.n;
+ memcpy(pData->p, doclist.p, doclist.n);
+ fts5MultiIterNew2(p, pData, bDesc, ppIter);
+ }
+ fts5BufferFree(&doclist);
+ }
+
+ fts5StructureRelease(pStruct);
+ sqlite3_free(aBuf);
+}
+
+
+/*
+** Indicate that all subsequent calls to sqlite3Fts5IndexWrite() pertain
+** to the document with rowid iRowid.
+*/
+static int sqlite3Fts5IndexBeginWrite(Fts5Index *p, int bDelete, i64 iRowid){
+ assert( p->rc==SQLITE_OK );
+
+ /* Allocate the hash table if it has not already been allocated */
+ if( p->pHash==0 ){
+ p->rc = sqlite3Fts5HashNew(&p->pHash, &p->nPendingData);
+ }
+
+ /* Flush the hash table to disk if required */
+ if( iRowid<p->iWriteRowid
+ || (iRowid==p->iWriteRowid && p->bDelete==0)
+ || (p->nPendingData > p->pConfig->nHashSize)
+ ){
+ fts5IndexFlush(p);
+ }
+
+ p->iWriteRowid = iRowid;
+ p->bDelete = bDelete;
+ return fts5IndexReturn(p);
+}
+
+/*
+** Commit data to disk.
+*/
+static int sqlite3Fts5IndexSync(Fts5Index *p, int bCommit){
+ assert( p->rc==SQLITE_OK );
+ fts5IndexFlush(p);
+ if( bCommit ) fts5CloseReader(p);
+ return fts5IndexReturn(p);
+}
+
+/*
+** Discard any data stored in the in-memory hash tables. Do not write it
+** to the database. Additionally, assume that the contents of the %_data
+** table may have changed on disk. So any in-memory caches of %_data
+** records must be invalidated.
+*/
+static int sqlite3Fts5IndexRollback(Fts5Index *p){
+ fts5CloseReader(p);
+ fts5IndexDiscardData(p);
+ assert( p->rc==SQLITE_OK );
+ return SQLITE_OK;
+}
+
+/*
+** The %_data table is completely empty when this function is called. This
+** function populates it with the initial structure objects for each index,
+** and the initial version of the "averages" record (a zero-byte blob).
+*/
+static int sqlite3Fts5IndexReinit(Fts5Index *p){
+ Fts5Structure s;
+ memset(&s, 0, sizeof(Fts5Structure));
+ fts5DataWrite(p, FTS5_AVERAGES_ROWID, (const u8*)"", 0);
+ fts5StructureWrite(p, &s);
+ return fts5IndexReturn(p);
+}
+
+/*
+** Open a new Fts5Index handle. If the bCreate argument is true, create
+** and initialize the underlying %_data table.
+**
+** If successful, set *pp to point to the new object and return SQLITE_OK.
+** Otherwise, set *pp to NULL and return an SQLite error code.
+*/
+static int sqlite3Fts5IndexOpen(
+ Fts5Config *pConfig,
+ int bCreate,
+ Fts5Index **pp,
+ char **pzErr
+){
+ int rc = SQLITE_OK;
+ Fts5Index *p; /* New object */
+
+ *pp = p = (Fts5Index*)sqlite3Fts5MallocZero(&rc, sizeof(Fts5Index));
+ if( rc==SQLITE_OK ){
+ p->pConfig = pConfig;
+ p->nWorkUnit = FTS5_WORK_UNIT;
+ p->zDataTbl = sqlite3Fts5Mprintf(&rc, "%s_data", pConfig->zName);
+ if( p->zDataTbl && bCreate ){
+ rc = sqlite3Fts5CreateTable(
+ pConfig, "data", "id INTEGER PRIMARY KEY, block BLOB", 0, pzErr
+ );
+ if( rc==SQLITE_OK ){
+ rc = sqlite3Fts5CreateTable(pConfig, "idx",
+ "segid, term, pgno, PRIMARY KEY(segid, term)",
+ 1, pzErr
+ );
+ }
+ if( rc==SQLITE_OK ){
+ rc = sqlite3Fts5IndexReinit(p);
+ }
+ }
+ }
+
+ assert( rc!=SQLITE_OK || p->rc==SQLITE_OK );
+ if( rc ){
+ sqlite3Fts5IndexClose(p);
+ *pp = 0;
+ }
+ return rc;
+}
+
+/*
+** Close a handle opened by an earlier call to sqlite3Fts5IndexOpen().
+*/
+static int sqlite3Fts5IndexClose(Fts5Index *p){
+ int rc = SQLITE_OK;
+ if( p ){
+ assert( p->pReader==0 );
+ sqlite3_finalize(p->pWriter);
+ sqlite3_finalize(p->pDeleter);
+ sqlite3_finalize(p->pIdxWriter);
+ sqlite3_finalize(p->pIdxDeleter);
+ sqlite3_finalize(p->pIdxSelect);
+ sqlite3Fts5HashFree(p->pHash);
+ sqlite3_free(p->zDataTbl);
+ sqlite3_free(p);
+ }
+ return rc;
+}
+
+/*
+** Argument p points to a buffer containing utf-8 text that is n bytes in
+** size. Return the number of bytes in the nChar character prefix of the
+** buffer, or 0 if there are less than nChar characters in total.
+*/
+static int fts5IndexCharlenToBytelen(const char *p, int nByte, int nChar){
+ int n = 0;
+ int i;
+ for(i=0; i<nChar; i++){
+ if( n>=nByte ) return 0; /* Input contains fewer than nChar chars */
+ if( (unsigned char)p[n++]>=0xc0 ){
+ while( (p[n] & 0xc0)==0x80 ) n++;
+ }
+ }
+ return n;
+}
+
+/*
+** pIn is a UTF-8 encoded string, nIn bytes in size. Return the number of
+** unicode characters in the string.
+*/
+static int fts5IndexCharlen(const char *pIn, int nIn){
+ int nChar = 0;
+ int i = 0;
+ while( i<nIn ){
+ if( (unsigned char)pIn[i++]>=0xc0 ){
+ while( i<nIn && (pIn[i] & 0xc0)==0x80 ) i++;
+ }
+ nChar++;
+ }
+ return nChar;
+}
+
+/*
+** Insert or remove data to or from the index. Each time a document is
+** added to or removed from the index, this function is called one or more
+** times.
+**
+** For an insert, it must be called once for each token in the new document.
+** If the operation is a delete, it must be called (at least) once for each
+** unique token in the document with an iCol value less than zero. The iPos
+** argument is ignored for a delete.
+*/
+static int sqlite3Fts5IndexWrite(
+ Fts5Index *p, /* Index to write to */
+ int iCol, /* Column token appears in (-ve -> delete) */
+ int iPos, /* Position of token within column */
+ const char *pToken, int nToken /* Token to add or remove to or from index */
+){
+ int i; /* Used to iterate through indexes */
+ int rc = SQLITE_OK; /* Return code */
+ Fts5Config *pConfig = p->pConfig;
+
+ assert( p->rc==SQLITE_OK );
+ assert( (iCol<0)==p->bDelete );
+
+ /* Add the entry to the main terms index. */
+ rc = sqlite3Fts5HashWrite(
+ p->pHash, p->iWriteRowid, iCol, iPos, FTS5_MAIN_PREFIX, pToken, nToken
+ );
+
+ for(i=0; i<pConfig->nPrefix && rc==SQLITE_OK; i++){
+ int nByte = fts5IndexCharlenToBytelen(pToken, nToken, pConfig->aPrefix[i]);
+ if( nByte ){
+ rc = sqlite3Fts5HashWrite(p->pHash,
+ p->iWriteRowid, iCol, iPos, (char)(FTS5_MAIN_PREFIX+i+1), pToken,
+ nByte
+ );
+ }
+ }
+
+ return rc;
+}
+
+/*
+** Open a new iterator to iterate though all rowid that match the
+** specified token or token prefix.
+*/
+static int sqlite3Fts5IndexQuery(
+ Fts5Index *p, /* FTS index to query */
+ const char *pToken, int nToken, /* Token (or prefix) to query for */
+ int flags, /* Mask of FTS5INDEX_QUERY_X flags */
+ Fts5Colset *pColset, /* Match these columns only */
+ Fts5IndexIter **ppIter /* OUT: New iterator object */
+){
+ Fts5Config *pConfig = p->pConfig;
+ Fts5IndexIter *pRet = 0;
+ int iIdx = 0;
+ Fts5Buffer buf = {0, 0, 0};
+
+ /* If the QUERY_SCAN flag is set, all other flags must be clear. */
+ assert( (flags & FTS5INDEX_QUERY_SCAN)==0 || flags==FTS5INDEX_QUERY_SCAN );
+
+ if( sqlite3Fts5BufferSize(&p->rc, &buf, nToken+1)==0 ){
+ memcpy(&buf.p[1], pToken, nToken);
+
+#ifdef SQLITE_DEBUG
+ /* If the QUERY_TEST_NOIDX flag was specified, then this must be a
+ ** prefix-query. Instead of using a prefix-index (if one exists),
+ ** evaluate the prefix query using the main FTS index. This is used
+ ** for internal sanity checking by the integrity-check in debug
+ ** mode only. */
+ if( pConfig->bPrefixIndex==0 || (flags & FTS5INDEX_QUERY_TEST_NOIDX) ){
+ assert( flags & FTS5INDEX_QUERY_PREFIX );
+ iIdx = 1+pConfig->nPrefix;
+ }else
+#endif
+ if( flags & FTS5INDEX_QUERY_PREFIX ){
+ int nChar = fts5IndexCharlen(pToken, nToken);
+ for(iIdx=1; iIdx<=pConfig->nPrefix; iIdx++){
+ if( pConfig->aPrefix[iIdx-1]==nChar ) break;
+ }
+ }
+
+ if( iIdx<=pConfig->nPrefix ){
+ Fts5Structure *pStruct = fts5StructureRead(p);
+ buf.p[0] = (u8)(FTS5_MAIN_PREFIX + iIdx);
+ if( pStruct ){
+ fts5MultiIterNew(p, pStruct, 1, flags, buf.p, nToken+1, -1, 0, &pRet);
+ fts5StructureRelease(pStruct);
+ }
+ }else{
+ int bDesc = (flags & FTS5INDEX_QUERY_DESC)!=0;
+ buf.p[0] = FTS5_MAIN_PREFIX;
+ fts5SetupPrefixIter(p, bDesc, buf.p, nToken+1, pColset, &pRet);
+ }
+
+ if( p->rc ){
+ sqlite3Fts5IterClose(pRet);
+ pRet = 0;
+ fts5CloseReader(p);
+ }
+ *ppIter = pRet;
+ sqlite3Fts5BufferFree(&buf);
+ }
+ return fts5IndexReturn(p);
+}
+
+/*
+** Return true if the iterator passed as the only argument is at EOF.
+*/
+static int sqlite3Fts5IterEof(Fts5IndexIter *pIter){
+ assert( pIter->pIndex->rc==SQLITE_OK );
+ return pIter->bEof;
+}
+
+/*
+** Move to the next matching rowid.
+*/
+static int sqlite3Fts5IterNext(Fts5IndexIter *pIter){
+ assert( pIter->pIndex->rc==SQLITE_OK );
+ fts5MultiIterNext(pIter->pIndex, pIter, 0, 0);
+ return fts5IndexReturn(pIter->pIndex);
+}
+
+/*
+** Move to the next matching term/rowid. Used by the fts5vocab module.
+*/
+static int sqlite3Fts5IterNextScan(Fts5IndexIter *pIter){
+ Fts5Index *p = pIter->pIndex;
+
+ assert( pIter->pIndex->rc==SQLITE_OK );
+
+ fts5MultiIterNext(p, pIter, 0, 0);
+ if( p->rc==SQLITE_OK ){
+ Fts5SegIter *pSeg = &pIter->aSeg[ pIter->aFirst[1].iFirst ];
+ if( pSeg->pLeaf && pSeg->term.p[0]!=FTS5_MAIN_PREFIX ){
+ fts5DataRelease(pSeg->pLeaf);
+ pSeg->pLeaf = 0;
+ pIter->bEof = 1;
+ }
+ }
+
+ return fts5IndexReturn(pIter->pIndex);
+}
+
+/*
+** Move to the next matching rowid that occurs at or after iMatch. The
+** definition of "at or after" depends on whether this iterator iterates
+** in ascending or descending rowid order.
+*/
+static int sqlite3Fts5IterNextFrom(Fts5IndexIter *pIter, i64 iMatch){
+ fts5MultiIterNextFrom(pIter->pIndex, pIter, iMatch);
+ return fts5IndexReturn(pIter->pIndex);
+}
+
+/*
+** Return the current rowid.
+*/
+static i64 sqlite3Fts5IterRowid(Fts5IndexIter *pIter){
+ return fts5MultiIterRowid(pIter);
+}
+
+/*
+** Return the current term.
+*/
+static const char *sqlite3Fts5IterTerm(Fts5IndexIter *pIter, int *pn){
+ int n;
+ const char *z = (const char*)fts5MultiIterTerm(pIter, &n);
+ *pn = n-1;
+ return &z[1];
+}
+
+
+static int fts5IndexExtractColset (
+ Fts5Colset *pColset, /* Colset to filter on */
+ const u8 *pPos, int nPos, /* Position list */
+ Fts5Buffer *pBuf /* Output buffer */
+){
+ int rc = SQLITE_OK;
+ int i;
+
+ fts5BufferZero(pBuf);
+ for(i=0; i<pColset->nCol; i++){
+ const u8 *pSub = pPos;
+ int nSub = fts5IndexExtractCol(&pSub, nPos, pColset->aiCol[i]);
+ if( nSub ){
+ fts5BufferAppendBlob(&rc, pBuf, nSub, pSub);
+ }
+ }
+ return rc;
+}
+
+
+/*
+** Return a pointer to a buffer containing a copy of the position list for
+** the current entry. Output variable *pn is set to the size of the buffer
+** in bytes before returning.
+**
+** The returned position list does not include the "number of bytes" varint
+** field that starts the position list on disk.
+*/
+static int sqlite3Fts5IterPoslist(
+ Fts5IndexIter *pIter,
+ Fts5Colset *pColset, /* Column filter (or NULL) */
+ const u8 **pp, /* OUT: Pointer to position-list data */
+ int *pn, /* OUT: Size of position-list in bytes */
+ i64 *piRowid /* OUT: Current rowid */
+){
+ Fts5SegIter *pSeg = &pIter->aSeg[ pIter->aFirst[1].iFirst ];
+ assert( pIter->pIndex->rc==SQLITE_OK );
+ *piRowid = pSeg->iRowid;
+ if( pSeg->iLeafOffset+pSeg->nPos<=pSeg->pLeaf->szLeaf ){
+ u8 *pPos = &pSeg->pLeaf->p[pSeg->iLeafOffset];
+ if( pColset==0 || pIter->bFiltered ){
+ *pn = pSeg->nPos;
+ *pp = pPos;
+ }else if( pColset->nCol==1 ){
+ *pp = pPos;
+ *pn = fts5IndexExtractCol(pp, pSeg->nPos, pColset->aiCol[0]);
+ }else{
+ fts5BufferZero(&pIter->poslist);
+ fts5IndexExtractColset(pColset, pPos, pSeg->nPos, &pIter->poslist);
+ *pp = pIter->poslist.p;
+ *pn = pIter->poslist.n;
+ }
+ }else{
+ fts5BufferZero(&pIter->poslist);
+ fts5SegiterPoslist(pIter->pIndex, pSeg, pColset, &pIter->poslist);
+ *pp = pIter->poslist.p;
+ *pn = pIter->poslist.n;
+ }
+ return fts5IndexReturn(pIter->pIndex);
+}
+
+/*
+** This function is similar to sqlite3Fts5IterPoslist(), except that it
+** copies the position list into the buffer supplied as the second
+** argument.
+*/
+static int sqlite3Fts5IterPoslistBuffer(Fts5IndexIter *pIter, Fts5Buffer *pBuf){
+ Fts5Index *p = pIter->pIndex;
+ Fts5SegIter *pSeg = &pIter->aSeg[ pIter->aFirst[1].iFirst ];
+ assert( p->rc==SQLITE_OK );
+ fts5BufferZero(pBuf);
+ fts5SegiterPoslist(p, pSeg, 0, pBuf);
+ return fts5IndexReturn(p);
+}
+
+/*
+** Close an iterator opened by an earlier call to sqlite3Fts5IndexQuery().
+*/
+static void sqlite3Fts5IterClose(Fts5IndexIter *pIter){
+ if( pIter ){
+ Fts5Index *pIndex = pIter->pIndex;
+ fts5MultiIterFree(pIter->pIndex, pIter);
+ fts5CloseReader(pIndex);
+ }
+}
+
+/*
+** Read and decode the "averages" record from the database.
+**
+** Parameter anSize must point to an array of size nCol, where nCol is
+** the number of user defined columns in the FTS table.
+*/
+static int sqlite3Fts5IndexGetAverages(Fts5Index *p, i64 *pnRow, i64 *anSize){
+ int nCol = p->pConfig->nCol;
+ Fts5Data *pData;
+
+ *pnRow = 0;
+ memset(anSize, 0, sizeof(i64) * nCol);
+ pData = fts5DataRead(p, FTS5_AVERAGES_ROWID);
+ if( p->rc==SQLITE_OK && pData->nn ){
+ int i = 0;
+ int iCol;
+ i += fts5GetVarint(&pData->p[i], (u64*)pnRow);
+ for(iCol=0; i<pData->nn && iCol<nCol; iCol++){
+ i += fts5GetVarint(&pData->p[i], (u64*)&anSize[iCol]);
+ }
+ }
+
+ fts5DataRelease(pData);
+ return fts5IndexReturn(p);
+}
+
+/*
+** Replace the current "averages" record with the contents of the buffer
+** supplied as the second argument.
+*/
+static int sqlite3Fts5IndexSetAverages(Fts5Index *p, const u8 *pData, int nData){
+ assert( p->rc==SQLITE_OK );
+ fts5DataWrite(p, FTS5_AVERAGES_ROWID, pData, nData);
+ return fts5IndexReturn(p);
+}
+
+/*
+** Return the total number of blocks this module has read from the %_data
+** table since it was created.
+*/
+static int sqlite3Fts5IndexReads(Fts5Index *p){
+ return p->nRead;
+}
+
+/*
+** Set the 32-bit cookie value stored at the start of all structure
+** records to the value passed as the second argument.
+**
+** Return SQLITE_OK if successful, or an SQLite error code if an error
+** occurs.
+*/
+static int sqlite3Fts5IndexSetCookie(Fts5Index *p, int iNew){
+ int rc; /* Return code */
+ Fts5Config *pConfig = p->pConfig; /* Configuration object */
+ u8 aCookie[4]; /* Binary representation of iNew */
+ sqlite3_blob *pBlob = 0;
+
+ assert( p->rc==SQLITE_OK );
+ sqlite3Fts5Put32(aCookie, iNew);
+
+ rc = sqlite3_blob_open(pConfig->db, pConfig->zDb, p->zDataTbl,
+ "block", FTS5_STRUCTURE_ROWID, 1, &pBlob
+ );
+ if( rc==SQLITE_OK ){
+ sqlite3_blob_write(pBlob, aCookie, 4, 0);
+ rc = sqlite3_blob_close(pBlob);
+ }
+
+ return rc;
+}
+
+static int sqlite3Fts5IndexLoadConfig(Fts5Index *p){
+ Fts5Structure *pStruct;
+ pStruct = fts5StructureRead(p);
+ fts5StructureRelease(pStruct);
+ return fts5IndexReturn(p);
+}
+
+
+/*************************************************************************
+**************************************************************************
+** Below this point is the implementation of the integrity-check
+** functionality.
+*/
+
+/*
+** Return a simple checksum value based on the arguments.
+*/
+static u64 fts5IndexEntryCksum(
+ i64 iRowid,
+ int iCol,
+ int iPos,
+ int iIdx,
+ const char *pTerm,
+ int nTerm
+){
+ int i;
+ u64 ret = iRowid;
+ ret += (ret<<3) + iCol;
+ ret += (ret<<3) + iPos;
+ if( iIdx>=0 ) ret += (ret<<3) + (FTS5_MAIN_PREFIX + iIdx);
+ for(i=0; i<nTerm; i++) ret += (ret<<3) + pTerm[i];
+ return ret;
+}
+
+#ifdef SQLITE_DEBUG
+/*
+** This function is purely an internal test. It does not contribute to
+** FTS functionality, or even the integrity-check, in any way.
+**
+** Instead, it tests that the same set of pgno/rowid combinations are
+** visited regardless of whether the doclist-index identified by parameters
+** iSegid/iLeaf is iterated in forwards or reverse order.
+*/
+static void fts5TestDlidxReverse(
+ Fts5Index *p,
+ int iSegid, /* Segment id to load from */
+ int iLeaf /* Load doclist-index for this leaf */
+){
+ Fts5DlidxIter *pDlidx = 0;
+ u64 cksum1 = 13;
+ u64 cksum2 = 13;
+
+ for(pDlidx=fts5DlidxIterInit(p, 0, iSegid, iLeaf);
+ fts5DlidxIterEof(p, pDlidx)==0;
+ fts5DlidxIterNext(p, pDlidx)
+ ){
+ i64 iRowid = fts5DlidxIterRowid(pDlidx);
+ int pgno = fts5DlidxIterPgno(pDlidx);
+ assert( pgno>iLeaf );
+ cksum1 += iRowid + ((i64)pgno<<32);
+ }
+ fts5DlidxIterFree(pDlidx);
+ pDlidx = 0;
+
+ for(pDlidx=fts5DlidxIterInit(p, 1, iSegid, iLeaf);
+ fts5DlidxIterEof(p, pDlidx)==0;
+ fts5DlidxIterPrev(p, pDlidx)
+ ){
+ i64 iRowid = fts5DlidxIterRowid(pDlidx);
+ int pgno = fts5DlidxIterPgno(pDlidx);
+ assert( fts5DlidxIterPgno(pDlidx)>iLeaf );
+ cksum2 += iRowid + ((i64)pgno<<32);
+ }
+ fts5DlidxIterFree(pDlidx);
+ pDlidx = 0;
+
+ if( p->rc==SQLITE_OK && cksum1!=cksum2 ) p->rc = FTS5_CORRUPT;
+}
+
+static int fts5QueryCksum(
+ Fts5Index *p, /* Fts5 index object */
+ int iIdx,
+ const char *z, /* Index key to query for */
+ int n, /* Size of index key in bytes */
+ int flags, /* Flags for Fts5IndexQuery */
+ u64 *pCksum /* IN/OUT: Checksum value */
+){
+ u64 cksum = *pCksum;
+ Fts5IndexIter *pIdxIter = 0;
+ int rc = sqlite3Fts5IndexQuery(p, z, n, flags, 0, &pIdxIter);
+
+ while( rc==SQLITE_OK && 0==sqlite3Fts5IterEof(pIdxIter) ){
+ i64 dummy;
+ const u8 *pPos;
+ int nPos;
+ i64 rowid = sqlite3Fts5IterRowid(pIdxIter);
+ rc = sqlite3Fts5IterPoslist(pIdxIter, 0, &pPos, &nPos, &dummy);
+ if( rc==SQLITE_OK ){
+ Fts5PoslistReader sReader;
+ for(sqlite3Fts5PoslistReaderInit(pPos, nPos, &sReader);
+ sReader.bEof==0;
+ sqlite3Fts5PoslistReaderNext(&sReader)
+ ){
+ int iCol = FTS5_POS2COLUMN(sReader.iPos);
+ int iOff = FTS5_POS2OFFSET(sReader.iPos);
+ cksum ^= fts5IndexEntryCksum(rowid, iCol, iOff, iIdx, z, n);
+ }
+ rc = sqlite3Fts5IterNext(pIdxIter);
+ }
+ }
+ sqlite3Fts5IterClose(pIdxIter);
+
+ *pCksum = cksum;
+ return rc;
+}
+
+
+/*
+** This function is also purely an internal test. It does not contribute to
+** FTS functionality, or even the integrity-check, in any way.
+*/
+static void fts5TestTerm(
+ Fts5Index *p,
+ Fts5Buffer *pPrev, /* Previous term */
+ const char *z, int n, /* Possibly new term to test */
+ u64 expected,
+ u64 *pCksum
+){
+ int rc = p->rc;
+ if( pPrev->n==0 ){
+ fts5BufferSet(&rc, pPrev, n, (const u8*)z);
+ }else
+ if( rc==SQLITE_OK && (pPrev->n!=n || memcmp(pPrev->p, z, n)) ){
+ u64 cksum3 = *pCksum;
+ const char *zTerm = (const char*)&pPrev->p[1]; /* term sans prefix-byte */
+ int nTerm = pPrev->n-1; /* Size of zTerm in bytes */
+ int iIdx = (pPrev->p[0] - FTS5_MAIN_PREFIX);
+ int flags = (iIdx==0 ? 0 : FTS5INDEX_QUERY_PREFIX);
+ u64 ck1 = 0;
+ u64 ck2 = 0;
+
+ /* Check that the results returned for ASC and DESC queries are
+ ** the same. If not, call this corruption. */
+ rc = fts5QueryCksum(p, iIdx, zTerm, nTerm, flags, &ck1);
+ if( rc==SQLITE_OK ){
+ int f = flags|FTS5INDEX_QUERY_DESC;
+ rc = fts5QueryCksum(p, iIdx, zTerm, nTerm, f, &ck2);
+ }
+ if( rc==SQLITE_OK && ck1!=ck2 ) rc = FTS5_CORRUPT;
+
+ /* If this is a prefix query, check that the results returned if the
+ ** the index is disabled are the same. In both ASC and DESC order.
+ **
+ ** This check may only be performed if the hash table is empty. This
+ ** is because the hash table only supports a single scan query at
+ ** a time, and the multi-iter loop from which this function is called
+ ** is already performing such a scan. */
+ if( p->nPendingData==0 ){
+ if( iIdx>0 && rc==SQLITE_OK ){
+ int f = flags|FTS5INDEX_QUERY_TEST_NOIDX;
+ ck2 = 0;
+ rc = fts5QueryCksum(p, iIdx, zTerm, nTerm, f, &ck2);
+ if( rc==SQLITE_OK && ck1!=ck2 ) rc = FTS5_CORRUPT;
+ }
+ if( iIdx>0 && rc==SQLITE_OK ){
+ int f = flags|FTS5INDEX_QUERY_TEST_NOIDX|FTS5INDEX_QUERY_DESC;
+ ck2 = 0;
+ rc = fts5QueryCksum(p, iIdx, zTerm, nTerm, f, &ck2);
+ if( rc==SQLITE_OK && ck1!=ck2 ) rc = FTS5_CORRUPT;
+ }
+ }
+
+ cksum3 ^= ck1;
+ fts5BufferSet(&rc, pPrev, n, (const u8*)z);
+
+ if( rc==SQLITE_OK && cksum3!=expected ){
+ rc = FTS5_CORRUPT;
+ }
+ *pCksum = cksum3;
+ }
+ p->rc = rc;
+}
+
+#else
+# define fts5TestDlidxReverse(x,y,z)
+# define fts5TestTerm(u,v,w,x,y,z)
+#endif
+
+/*
+** Check that:
+**
+** 1) All leaves of pSeg between iFirst and iLast (inclusive) exist and
+** contain zero terms.
+** 2) All leaves of pSeg between iNoRowid and iLast (inclusive) exist and
+** contain zero rowids.
+*/
+static void fts5IndexIntegrityCheckEmpty(
+ Fts5Index *p,
+ Fts5StructureSegment *pSeg, /* Segment to check internal consistency */
+ int iFirst,
+ int iNoRowid,
+ int iLast
+){
+ int i;
+
+ /* Now check that the iter.nEmpty leaves following the current leaf
+ ** (a) exist and (b) contain no terms. */
+ for(i=iFirst; p->rc==SQLITE_OK && i<=iLast; i++){
+ Fts5Data *pLeaf = fts5DataRead(p, FTS5_SEGMENT_ROWID(pSeg->iSegid, i));
+ if( pLeaf ){
+ if( !fts5LeafIsTermless(pLeaf) ) p->rc = FTS5_CORRUPT;
+ if( i>=iNoRowid && 0!=fts5LeafFirstRowidOff(pLeaf) ) p->rc = FTS5_CORRUPT;
+ }
+ fts5DataRelease(pLeaf);
+ }
+}
+
+static void fts5IntegrityCheckPgidx(Fts5Index *p, Fts5Data *pLeaf){
+ int iTermOff = 0;
+ int ii;
+
+ Fts5Buffer buf1 = {0,0,0};
+ Fts5Buffer buf2 = {0,0,0};
+
+ ii = pLeaf->szLeaf;
+ while( ii<pLeaf->nn && p->rc==SQLITE_OK ){
+ int res;
+ int iOff;
+ int nIncr;
+
+ ii += fts5GetVarint32(&pLeaf->p[ii], nIncr);
+ iTermOff += nIncr;
+ iOff = iTermOff;
+
+ if( iOff>=pLeaf->szLeaf ){
+ p->rc = FTS5_CORRUPT;
+ }else if( iTermOff==nIncr ){
+ int nByte;
+ iOff += fts5GetVarint32(&pLeaf->p[iOff], nByte);
+ if( (iOff+nByte)>pLeaf->szLeaf ){
+ p->rc = FTS5_CORRUPT;
+ }else{
+ fts5BufferSet(&p->rc, &buf1, nByte, &pLeaf->p[iOff]);
+ }
+ }else{
+ int nKeep, nByte;
+ iOff += fts5GetVarint32(&pLeaf->p[iOff], nKeep);
+ iOff += fts5GetVarint32(&pLeaf->p[iOff], nByte);
+ if( nKeep>buf1.n || (iOff+nByte)>pLeaf->szLeaf ){
+ p->rc = FTS5_CORRUPT;
+ }else{
+ buf1.n = nKeep;
+ fts5BufferAppendBlob(&p->rc, &buf1, nByte, &pLeaf->p[iOff]);
+ }
+
+ if( p->rc==SQLITE_OK ){
+ res = fts5BufferCompare(&buf1, &buf2);
+ if( res<=0 ) p->rc = FTS5_CORRUPT;
+ }
+ }
+ fts5BufferSet(&p->rc, &buf2, buf1.n, buf1.p);
+ }
+
+ fts5BufferFree(&buf1);
+ fts5BufferFree(&buf2);
+}
+
+static void fts5IndexIntegrityCheckSegment(
+ Fts5Index *p, /* FTS5 backend object */
+ Fts5StructureSegment *pSeg /* Segment to check internal consistency */
+){
+ Fts5Config *pConfig = p->pConfig;
+ sqlite3_stmt *pStmt = 0;
+ int rc2;
+ int iIdxPrevLeaf = pSeg->pgnoFirst-1;
+ int iDlidxPrevLeaf = pSeg->pgnoLast;
+
+ if( pSeg->pgnoFirst==0 ) return;
+
+ fts5IndexPrepareStmt(p, &pStmt, sqlite3_mprintf(
+ "SELECT segid, term, (pgno>>1), (pgno&1) FROM %Q.'%q_idx' WHERE segid=%d",
+ pConfig->zDb, pConfig->zName, pSeg->iSegid
+ ));
+
+ /* Iterate through the b-tree hierarchy. */
+ while( p->rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pStmt) ){
+ i64 iRow; /* Rowid for this leaf */
+ Fts5Data *pLeaf; /* Data for this leaf */
+
+ int nIdxTerm = sqlite3_column_bytes(pStmt, 1);
+ const char *zIdxTerm = (const char*)sqlite3_column_text(pStmt, 1);
+ int iIdxLeaf = sqlite3_column_int(pStmt, 2);
+ int bIdxDlidx = sqlite3_column_int(pStmt, 3);
+
+ /* If the leaf in question has already been trimmed from the segment,
+ ** ignore this b-tree entry. Otherwise, load it into memory. */
+ if( iIdxLeaf<pSeg->pgnoFirst ) continue;
+ iRow = FTS5_SEGMENT_ROWID(pSeg->iSegid, iIdxLeaf);
+ pLeaf = fts5DataRead(p, iRow);
+ if( pLeaf==0 ) break;
+
+ /* Check that the leaf contains at least one term, and that it is equal
+ ** to or larger than the split-key in zIdxTerm. Also check that if there
+ ** is also a rowid pointer within the leaf page header, it points to a
+ ** location before the term. */
+ if( pLeaf->nn<=pLeaf->szLeaf ){
+ p->rc = FTS5_CORRUPT;
+ }else{
+ int iOff; /* Offset of first term on leaf */
+ int iRowidOff; /* Offset of first rowid on leaf */
+ int nTerm; /* Size of term on leaf in bytes */
+ int res; /* Comparison of term and split-key */
+
+ iOff = fts5LeafFirstTermOff(pLeaf);
+ iRowidOff = fts5LeafFirstRowidOff(pLeaf);
+ if( iRowidOff>=iOff ){
+ p->rc = FTS5_CORRUPT;
+ }else{
+ iOff += fts5GetVarint32(&pLeaf->p[iOff], nTerm);
+ res = memcmp(&pLeaf->p[iOff], zIdxTerm, MIN(nTerm, nIdxTerm));
+ if( res==0 ) res = nTerm - nIdxTerm;
+ if( res<0 ) p->rc = FTS5_CORRUPT;
+ }
+
+ fts5IntegrityCheckPgidx(p, pLeaf);
+ }
+ fts5DataRelease(pLeaf);
+ if( p->rc ) break;
+
+ /* Now check that the iter.nEmpty leaves following the current leaf
+ ** (a) exist and (b) contain no terms. */
+ fts5IndexIntegrityCheckEmpty(
+ p, pSeg, iIdxPrevLeaf+1, iDlidxPrevLeaf+1, iIdxLeaf-1
+ );
+ if( p->rc ) break;
+
+ /* If there is a doclist-index, check that it looks right. */
+ if( bIdxDlidx ){
+ Fts5DlidxIter *pDlidx = 0; /* For iterating through doclist index */
+ int iPrevLeaf = iIdxLeaf;
+ int iSegid = pSeg->iSegid;
+ int iPg = 0;
+ i64 iKey;
+
+ for(pDlidx=fts5DlidxIterInit(p, 0, iSegid, iIdxLeaf);
+ fts5DlidxIterEof(p, pDlidx)==0;
+ fts5DlidxIterNext(p, pDlidx)
+ ){
+
+ /* Check any rowid-less pages that occur before the current leaf. */
+ for(iPg=iPrevLeaf+1; iPg<fts5DlidxIterPgno(pDlidx); iPg++){
+ iKey = FTS5_SEGMENT_ROWID(iSegid, iPg);
+ pLeaf = fts5DataRead(p, iKey);
+ if( pLeaf ){
+ if( fts5LeafFirstRowidOff(pLeaf)!=0 ) p->rc = FTS5_CORRUPT;
+ fts5DataRelease(pLeaf);
+ }
+ }
+ iPrevLeaf = fts5DlidxIterPgno(pDlidx);
+
+ /* Check that the leaf page indicated by the iterator really does
+ ** contain the rowid suggested by the same. */
+ iKey = FTS5_SEGMENT_ROWID(iSegid, iPrevLeaf);
+ pLeaf = fts5DataRead(p, iKey);
+ if( pLeaf ){
+ i64 iRowid;
+ int iRowidOff = fts5LeafFirstRowidOff(pLeaf);
+ ASSERT_SZLEAF_OK(pLeaf);
+ if( iRowidOff>=pLeaf->szLeaf ){
+ p->rc = FTS5_CORRUPT;
+ }else{
+ fts5GetVarint(&pLeaf->p[iRowidOff], (u64*)&iRowid);
+ if( iRowid!=fts5DlidxIterRowid(pDlidx) ) p->rc = FTS5_CORRUPT;
+ }
+ fts5DataRelease(pLeaf);
+ }
+ }
+
+ iDlidxPrevLeaf = iPg;
+ fts5DlidxIterFree(pDlidx);
+ fts5TestDlidxReverse(p, iSegid, iIdxLeaf);
+ }else{
+ iDlidxPrevLeaf = pSeg->pgnoLast;
+ /* TODO: Check there is no doclist index */
+ }
+
+ iIdxPrevLeaf = iIdxLeaf;
+ }
+
+ rc2 = sqlite3_finalize(pStmt);
+ if( p->rc==SQLITE_OK ) p->rc = rc2;
+
+ /* Page iter.iLeaf must now be the rightmost leaf-page in the segment */
+#if 0
+ if( p->rc==SQLITE_OK && iter.iLeaf!=pSeg->pgnoLast ){
+ p->rc = FTS5_CORRUPT;
+ }
+#endif
+}
+
+
+/*
+** Run internal checks to ensure that the FTS index (a) is internally
+** consistent and (b) contains entries for which the XOR of the checksums
+** as calculated by fts5IndexEntryCksum() is cksum.
+**
+** Return SQLITE_CORRUPT if any of the internal checks fail, or if the
+** checksum does not match. Return SQLITE_OK if all checks pass without
+** error, or some other SQLite error code if another error (e.g. OOM)
+** occurs.
+*/
+static int sqlite3Fts5IndexIntegrityCheck(Fts5Index *p, u64 cksum){
+ u64 cksum2 = 0; /* Checksum based on contents of indexes */
+ Fts5Buffer poslist = {0,0,0}; /* Buffer used to hold a poslist */
+ Fts5IndexIter *pIter; /* Used to iterate through entire index */
+ Fts5Structure *pStruct; /* Index structure */
+
+#ifdef SQLITE_DEBUG
+ /* Used by extra internal tests only run if NDEBUG is not defined */
+ u64 cksum3 = 0; /* Checksum based on contents of indexes */
+ Fts5Buffer term = {0,0,0}; /* Buffer used to hold most recent term */
+#endif
+
+ /* Load the FTS index structure */
+ pStruct = fts5StructureRead(p);
+
+ /* Check that the internal nodes of each segment match the leaves */
+ if( pStruct ){
+ int iLvl, iSeg;
+ for(iLvl=0; iLvl<pStruct->nLevel; iLvl++){
+ for(iSeg=0; iSeg<pStruct->aLevel[iLvl].nSeg; iSeg++){
+ Fts5StructureSegment *pSeg = &pStruct->aLevel[iLvl].aSeg[iSeg];
+ fts5IndexIntegrityCheckSegment(p, pSeg);
+ }
+ }
+ }
+
+ /* The cksum argument passed to this function is a checksum calculated
+ ** based on all expected entries in the FTS index (including prefix index
+ ** entries). This block checks that a checksum calculated based on the
+ ** actual contents of FTS index is identical.
+ **
+ ** Two versions of the same checksum are calculated. The first (stack
+ ** variable cksum2) based on entries extracted from the full-text index
+ ** while doing a linear scan of each individual index in turn.
+ **
+ ** As each term visited by the linear scans, a separate query for the
+ ** same term is performed. cksum3 is calculated based on the entries
+ ** extracted by these queries.
+ */
+ for(fts5MultiIterNew(p, pStruct, 0, 0, 0, 0, -1, 0, &pIter);
+ fts5MultiIterEof(p, pIter)==0;
+ fts5MultiIterNext(p, pIter, 0, 0)
+ ){
+ int n; /* Size of term in bytes */
+ i64 iPos = 0; /* Position read from poslist */
+ int iOff = 0; /* Offset within poslist */
+ i64 iRowid = fts5MultiIterRowid(pIter);
+ char *z = (char*)fts5MultiIterTerm(pIter, &n);
+
+ /* If this is a new term, query for it. Update cksum3 with the results. */
+ fts5TestTerm(p, &term, z, n, cksum2, &cksum3);
+
+ poslist.n = 0;
+ fts5SegiterPoslist(p, &pIter->aSeg[pIter->aFirst[1].iFirst] , 0, &poslist);
+ while( 0==sqlite3Fts5PoslistNext64(poslist.p, poslist.n, &iOff, &iPos) ){
+ int iCol = FTS5_POS2COLUMN(iPos);
+ int iTokOff = FTS5_POS2OFFSET(iPos);
+ cksum2 ^= fts5IndexEntryCksum(iRowid, iCol, iTokOff, -1, z, n);
+ }
+ }
+ fts5TestTerm(p, &term, 0, 0, cksum2, &cksum3);
+
+ fts5MultiIterFree(p, pIter);
+ if( p->rc==SQLITE_OK && cksum!=cksum2 ) p->rc = FTS5_CORRUPT;
+
+ fts5StructureRelease(pStruct);
+#ifdef SQLITE_DEBUG
+ fts5BufferFree(&term);
+#endif
+ fts5BufferFree(&poslist);
+ return fts5IndexReturn(p);
+}
+
+
+/*
+** Calculate and return a checksum that is the XOR of the index entry
+** checksum of all entries that would be generated by the token specified
+** by the final 5 arguments.
+*/
+static u64 sqlite3Fts5IndexCksum(
+ Fts5Config *pConfig, /* Configuration object */
+ i64 iRowid, /* Document term appears in */
+ int iCol, /* Column term appears in */
+ int iPos, /* Position term appears in */
+ const char *pTerm, int nTerm /* Term at iPos */
+){
+ u64 ret = 0; /* Return value */
+ int iIdx; /* For iterating through indexes */
+
+ ret = fts5IndexEntryCksum(iRowid, iCol, iPos, 0, pTerm, nTerm);
+
+ for(iIdx=0; iIdx<pConfig->nPrefix; iIdx++){
+ int nByte = fts5IndexCharlenToBytelen(pTerm, nTerm, pConfig->aPrefix[iIdx]);
+ if( nByte ){
+ ret ^= fts5IndexEntryCksum(iRowid, iCol, iPos, iIdx+1, pTerm, nByte);
+ }
+ }
+
+ return ret;
+}
+
+/*************************************************************************
+**************************************************************************
+** Below this point is the implementation of the fts5_decode() scalar
+** function only.
+*/
+
+/*
+** Decode a segment-data rowid from the %_data table. This function is
+** the opposite of macro FTS5_SEGMENT_ROWID().
+*/
+static void fts5DecodeRowid(
+ i64 iRowid, /* Rowid from %_data table */
+ int *piSegid, /* OUT: Segment id */
+ int *pbDlidx, /* OUT: Dlidx flag */
+ int *piHeight, /* OUT: Height */
+ int *piPgno /* OUT: Page number */
+){
+ *piPgno = (int)(iRowid & (((i64)1 << FTS5_DATA_PAGE_B) - 1));
+ iRowid >>= FTS5_DATA_PAGE_B;
+
+ *piHeight = (int)(iRowid & (((i64)1 << FTS5_DATA_HEIGHT_B) - 1));
+ iRowid >>= FTS5_DATA_HEIGHT_B;
+
+ *pbDlidx = (int)(iRowid & 0x0001);
+ iRowid >>= FTS5_DATA_DLI_B;
+
+ *piSegid = (int)(iRowid & (((i64)1 << FTS5_DATA_ID_B) - 1));
+}
+
+static void fts5DebugRowid(int *pRc, Fts5Buffer *pBuf, i64 iKey){
+ int iSegid, iHeight, iPgno, bDlidx; /* Rowid compenents */
+ fts5DecodeRowid(iKey, &iSegid, &bDlidx, &iHeight, &iPgno);
+
+ if( iSegid==0 ){
+ if( iKey==FTS5_AVERAGES_ROWID ){
+ sqlite3Fts5BufferAppendPrintf(pRc, pBuf, "{averages} ");
+ }else{
+ sqlite3Fts5BufferAppendPrintf(pRc, pBuf, "{structure}");
+ }
+ }
+ else{
+ sqlite3Fts5BufferAppendPrintf(pRc, pBuf, "{%ssegid=%d h=%d pgno=%d}",
+ bDlidx ? "dlidx " : "", iSegid, iHeight, iPgno
+ );
+ }
+}
+
+static void fts5DebugStructure(
+ int *pRc, /* IN/OUT: error code */
+ Fts5Buffer *pBuf,
+ Fts5Structure *p
+){
+ int iLvl, iSeg; /* Iterate through levels, segments */
+
+ for(iLvl=0; iLvl<p->nLevel; iLvl++){
+ Fts5StructureLevel *pLvl = &p->aLevel[iLvl];
+ sqlite3Fts5BufferAppendPrintf(pRc, pBuf,
+ " {lvl=%d nMerge=%d nSeg=%d", iLvl, pLvl->nMerge, pLvl->nSeg
+ );
+ for(iSeg=0; iSeg<pLvl->nSeg; iSeg++){
+ Fts5StructureSegment *pSeg = &pLvl->aSeg[iSeg];
+ sqlite3Fts5BufferAppendPrintf(pRc, pBuf, " {id=%d leaves=%d..%d}",
+ pSeg->iSegid, pSeg->pgnoFirst, pSeg->pgnoLast
+ );
+ }
+ sqlite3Fts5BufferAppendPrintf(pRc, pBuf, "}");
+ }
+}
+
+/*
+** This is part of the fts5_decode() debugging aid.
+**
+** Arguments pBlob/nBlob contain a serialized Fts5Structure object. This
+** function appends a human-readable representation of the same object
+** to the buffer passed as the second argument.
+*/
+static void fts5DecodeStructure(
+ int *pRc, /* IN/OUT: error code */
+ Fts5Buffer *pBuf,
+ const u8 *pBlob, int nBlob
+){
+ int rc; /* Return code */
+ Fts5Structure *p = 0; /* Decoded structure object */
+
+ rc = fts5StructureDecode(pBlob, nBlob, 0, &p);
+ if( rc!=SQLITE_OK ){
+ *pRc = rc;
+ return;
+ }
+
+ fts5DebugStructure(pRc, pBuf, p);
+ fts5StructureRelease(p);
+}
+
+/*
+** This is part of the fts5_decode() debugging aid.
+**
+** Arguments pBlob/nBlob contain an "averages" record. This function
+** appends a human-readable representation of record to the buffer passed
+** as the second argument.
+*/
+static void fts5DecodeAverages(
+ int *pRc, /* IN/OUT: error code */
+ Fts5Buffer *pBuf,
+ const u8 *pBlob, int nBlob
+){
+ int i = 0;
+ const char *zSpace = "";
+
+ while( i<nBlob ){
+ u64 iVal;
+ i += sqlite3Fts5GetVarint(&pBlob[i], &iVal);
+ sqlite3Fts5BufferAppendPrintf(pRc, pBuf, "%s%d", zSpace, (int)iVal);
+ zSpace = " ";
+ }
+}
+
+/*
+** Buffer (a/n) is assumed to contain a list of serialized varints. Read
+** each varint and append its string representation to buffer pBuf. Return
+** after either the input buffer is exhausted or a 0 value is read.
+**
+** The return value is the number of bytes read from the input buffer.
+*/
+static int fts5DecodePoslist(int *pRc, Fts5Buffer *pBuf, const u8 *a, int n){
+ int iOff = 0;
+ while( iOff<n ){
+ int iVal;
+ iOff += fts5GetVarint32(&a[iOff], iVal);
+ sqlite3Fts5BufferAppendPrintf(pRc, pBuf, " %d", iVal);
+ }
+ return iOff;
+}
+
+/*
+** The start of buffer (a/n) contains the start of a doclist. The doclist
+** may or may not finish within the buffer. This function appends a text
+** representation of the part of the doclist that is present to buffer
+** pBuf.
+**
+** The return value is the number of bytes read from the input buffer.
+*/
+static int fts5DecodeDoclist(int *pRc, Fts5Buffer *pBuf, const u8 *a, int n){
+ i64 iDocid = 0;
+ int iOff = 0;
+
+ if( n>0 ){
+ iOff = sqlite3Fts5GetVarint(a, (u64*)&iDocid);
+ sqlite3Fts5BufferAppendPrintf(pRc, pBuf, " id=%lld", iDocid);
+ }
+ while( iOff<n ){
+ int nPos;
+ int bDel;
+ iOff += fts5GetPoslistSize(&a[iOff], &nPos, &bDel);
+ sqlite3Fts5BufferAppendPrintf(pRc, pBuf, " nPos=%d%s", nPos, bDel?"*":"");
+ iOff += fts5DecodePoslist(pRc, pBuf, &a[iOff], MIN(n-iOff, nPos));
+ if( iOff<n ){
+ i64 iDelta;
+ iOff += sqlite3Fts5GetVarint(&a[iOff], (u64*)&iDelta);
+ iDocid += iDelta;
+ sqlite3Fts5BufferAppendPrintf(pRc, pBuf, " id=%lld", iDocid);
+ }
+ }
+
+ return iOff;
+}
+
+/*
+** The implementation of user-defined scalar function fts5_decode().
+*/
+static void fts5DecodeFunction(
+ sqlite3_context *pCtx, /* Function call context */
+ int nArg, /* Number of args (always 2) */
+ sqlite3_value **apVal /* Function arguments */
+){
+ i64 iRowid; /* Rowid for record being decoded */
+ int iSegid,iHeight,iPgno,bDlidx;/* Rowid components */
+ const u8 *aBlob; int n; /* Record to decode */
+ u8 *a = 0;
+ Fts5Buffer s; /* Build up text to return here */
+ int rc = SQLITE_OK; /* Return code */
+ int nSpace = 0;
+
+ assert( nArg==2 );
+ memset(&s, 0, sizeof(Fts5Buffer));
+ iRowid = sqlite3_value_int64(apVal[0]);
+
+ /* Make a copy of the second argument (a blob) in aBlob[]. The aBlob[]
+ ** copy is followed by FTS5_DATA_ZERO_PADDING 0x00 bytes, which prevents
+ ** buffer overreads even if the record is corrupt. */
+ n = sqlite3_value_bytes(apVal[1]);
+ aBlob = sqlite3_value_blob(apVal[1]);
+ nSpace = n + FTS5_DATA_ZERO_PADDING;
+ a = (u8*)sqlite3Fts5MallocZero(&rc, nSpace);
+ if( a==0 ) goto decode_out;
+ memcpy(a, aBlob, n);
+
+
+ fts5DecodeRowid(iRowid, &iSegid, &bDlidx, &iHeight, &iPgno);
+
+ fts5DebugRowid(&rc, &s, iRowid);
+ if( bDlidx ){
+ Fts5Data dlidx;
+ Fts5DlidxLvl lvl;
+
+ dlidx.p = a;
+ dlidx.nn = n;
+
+ memset(&lvl, 0, sizeof(Fts5DlidxLvl));
+ lvl.pData = &dlidx;
+ lvl.iLeafPgno = iPgno;
+
+ for(fts5DlidxLvlNext(&lvl); lvl.bEof==0; fts5DlidxLvlNext(&lvl)){
+ sqlite3Fts5BufferAppendPrintf(&rc, &s,
+ " %d(%lld)", lvl.iLeafPgno, lvl.iRowid
+ );
+ }
+ }else if( iSegid==0 ){
+ if( iRowid==FTS5_AVERAGES_ROWID ){
+ fts5DecodeAverages(&rc, &s, a, n);
+ }else{
+ fts5DecodeStructure(&rc, &s, a, n);
+ }
+ }else{
+ Fts5Buffer term; /* Current term read from page */
+ int szLeaf; /* Offset of pgidx in a[] */
+ int iPgidxOff;
+ int iPgidxPrev = 0; /* Previous value read from pgidx */
+ int iTermOff = 0;
+ int iRowidOff = 0;
+ int iOff;
+ int nDoclist;
+
+ memset(&term, 0, sizeof(Fts5Buffer));
+
+ if( n<4 ){
+ sqlite3Fts5BufferSet(&rc, &s, 7, (const u8*)"corrupt");
+ goto decode_out;
+ }else{
+ iRowidOff = fts5GetU16(&a[0]);
+ iPgidxOff = szLeaf = fts5GetU16(&a[2]);
+ if( iPgidxOff<n ){
+ fts5GetVarint32(&a[iPgidxOff], iTermOff);
+ }
+ }
+
+ /* Decode the position list tail at the start of the page */
+ if( iRowidOff!=0 ){
+ iOff = iRowidOff;
+ }else if( iTermOff!=0 ){
+ iOff = iTermOff;
+ }else{
+ iOff = szLeaf;
+ }
+ fts5DecodePoslist(&rc, &s, &a[4], iOff-4);
+
+ /* Decode any more doclist data that appears on the page before the
+ ** first term. */
+ nDoclist = (iTermOff ? iTermOff : szLeaf) - iOff;
+ fts5DecodeDoclist(&rc, &s, &a[iOff], nDoclist);
+
+ while( iPgidxOff<n ){
+ int bFirst = (iPgidxOff==szLeaf); /* True for first term on page */
+ int nByte; /* Bytes of data */
+ int iEnd;
+
+ iPgidxOff += fts5GetVarint32(&a[iPgidxOff], nByte);
+ iPgidxPrev += nByte;
+ iOff = iPgidxPrev;
+
+ if( iPgidxOff<n ){
+ fts5GetVarint32(&a[iPgidxOff], nByte);
+ iEnd = iPgidxPrev + nByte;
+ }else{
+ iEnd = szLeaf;
+ }
+
+ if( bFirst==0 ){
+ iOff += fts5GetVarint32(&a[iOff], nByte);
+ term.n = nByte;
+ }
+ iOff += fts5GetVarint32(&a[iOff], nByte);
+ fts5BufferAppendBlob(&rc, &term, nByte, &a[iOff]);
+ iOff += nByte;
+
+ sqlite3Fts5BufferAppendPrintf(
+ &rc, &s, " term=%.*s", term.n, (const char*)term.p
+ );
+ iOff += fts5DecodeDoclist(&rc, &s, &a[iOff], iEnd-iOff);
+ }
+
+ fts5BufferFree(&term);
+ }
+
+ decode_out:
+ sqlite3_free(a);
+ if( rc==SQLITE_OK ){
+ sqlite3_result_text(pCtx, (const char*)s.p, s.n, SQLITE_TRANSIENT);
+ }else{
+ sqlite3_result_error_code(pCtx, rc);
+ }
+ fts5BufferFree(&s);
+}
+
+/*
+** The implementation of user-defined scalar function fts5_rowid().
+*/
+static void fts5RowidFunction(
+ sqlite3_context *pCtx, /* Function call context */
+ int nArg, /* Number of args (always 2) */
+ sqlite3_value **apVal /* Function arguments */
+){
+ const char *zArg;
+ if( nArg==0 ){
+ sqlite3_result_error(pCtx, "should be: fts5_rowid(subject, ....)", -1);
+ }else{
+ zArg = (const char*)sqlite3_value_text(apVal[0]);
+ if( 0==sqlite3_stricmp(zArg, "segment") ){
+ i64 iRowid;
+ int segid, pgno;
+ if( nArg!=3 ){
+ sqlite3_result_error(pCtx,
+ "should be: fts5_rowid('segment', segid, pgno))", -1
+ );
+ }else{
+ segid = sqlite3_value_int(apVal[1]);
+ pgno = sqlite3_value_int(apVal[2]);
+ iRowid = FTS5_SEGMENT_ROWID(segid, pgno);
+ sqlite3_result_int64(pCtx, iRowid);
+ }
+ }else{
+ sqlite3_result_error(pCtx,
+ "first arg to fts5_rowid() must be 'segment'" , -1
+ );
+ }
+ }
+}
+
+/*
+** This is called as part of registering the FTS5 module with database
+** connection db. It registers several user-defined scalar functions useful
+** with FTS5.
+**
+** If successful, SQLITE_OK is returned. If an error occurs, some other
+** SQLite error code is returned instead.
+*/
+static int sqlite3Fts5IndexInit(sqlite3 *db){
+ int rc = sqlite3_create_function(
+ db, "fts5_decode", 2, SQLITE_UTF8, 0, fts5DecodeFunction, 0, 0
+ );
+ if( rc==SQLITE_OK ){
+ rc = sqlite3_create_function(
+ db, "fts5_rowid", -1, SQLITE_UTF8, 0, fts5RowidFunction, 0, 0
+ );
+ }
+ return rc;
+}
+
+
+/*
+** 2014 Jun 09
+**
+** 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.
+*/
+
+
+/* #include "fts5Int.h" */
+
+/*
+** This variable is set to false when running tests for which the on disk
+** structures should not be corrupt. Otherwise, true. If it is false, extra
+** assert() conditions in the fts5 code are activated - conditions that are
+** only true if it is guaranteed that the fts5 database is not corrupt.
+*/
+SQLITE_API int sqlite3_fts5_may_be_corrupt = 1;
+
+
+typedef struct Fts5Auxdata Fts5Auxdata;
+typedef struct Fts5Auxiliary Fts5Auxiliary;
+typedef struct Fts5Cursor Fts5Cursor;
+typedef struct Fts5Sorter Fts5Sorter;
+typedef struct Fts5Table Fts5Table;
+typedef struct Fts5TokenizerModule Fts5TokenizerModule;
+
+/*
+** NOTES ON TRANSACTIONS:
+**
+** SQLite invokes the following virtual table methods as transactions are
+** opened and closed by the user:
+**
+** xBegin(): Start of a new transaction.
+** xSync(): Initial part of two-phase commit.
+** xCommit(): Final part of two-phase commit.
+** xRollback(): Rollback the transaction.
+**
+** Anything that is required as part of a commit that may fail is performed
+** in the xSync() callback. Current versions of SQLite ignore any errors
+** returned by xCommit().
+**
+** And as sub-transactions are opened/closed:
+**
+** xSavepoint(int S): Open savepoint S.
+** xRelease(int S): Commit and close savepoint S.
+** xRollbackTo(int S): Rollback to start of savepoint S.
+**
+** During a write-transaction the fts5_index.c module may cache some data
+** in-memory. It is flushed to disk whenever xSync(), xRelease() or
+** xSavepoint() is called. And discarded whenever xRollback() or xRollbackTo()
+** is called.
+**
+** Additionally, if SQLITE_DEBUG is defined, an instance of the following
+** structure is used to record the current transaction state. This information
+** is not required, but it is used in the assert() statements executed by
+** function fts5CheckTransactionState() (see below).
+*/
+struct Fts5TransactionState {
+ int eState; /* 0==closed, 1==open, 2==synced */
+ int iSavepoint; /* Number of open savepoints (0 -> none) */
+};
+
+/*
+** A single object of this type is allocated when the FTS5 module is
+** registered with a database handle. It is used to store pointers to
+** all registered FTS5 extensions - tokenizers and auxiliary functions.
+*/
+struct Fts5Global {
+ fts5_api api; /* User visible part of object (see fts5.h) */
+ sqlite3 *db; /* Associated database connection */
+ i64 iNextId; /* Used to allocate unique cursor ids */
+ Fts5Auxiliary *pAux; /* First in list of all aux. functions */
+ Fts5TokenizerModule *pTok; /* First in list of all tokenizer modules */
+ Fts5TokenizerModule *pDfltTok; /* Default tokenizer module */
+ Fts5Cursor *pCsr; /* First in list of all open cursors */
+};
+
+/*
+** Each auxiliary function registered with the FTS5 module is represented
+** by an object of the following type. All such objects are stored as part
+** of the Fts5Global.pAux list.
+*/
+struct Fts5Auxiliary {
+ Fts5Global *pGlobal; /* Global context for this function */
+ char *zFunc; /* Function name (nul-terminated) */
+ void *pUserData; /* User-data pointer */
+ fts5_extension_function xFunc; /* Callback function */
+ void (*xDestroy)(void*); /* Destructor function */
+ Fts5Auxiliary *pNext; /* Next registered auxiliary function */
+};
+
+/*
+** Each tokenizer module registered with the FTS5 module is represented
+** by an object of the following type. All such objects are stored as part
+** of the Fts5Global.pTok list.
+*/
+struct Fts5TokenizerModule {
+ char *zName; /* Name of tokenizer */
+ void *pUserData; /* User pointer passed to xCreate() */
+ fts5_tokenizer x; /* Tokenizer functions */
+ void (*xDestroy)(void*); /* Destructor function */
+ Fts5TokenizerModule *pNext; /* Next registered tokenizer module */
+};
+
+/*
+** Virtual-table object.
+*/
+struct Fts5Table {
+ sqlite3_vtab base; /* Base class used by SQLite core */
+ Fts5Config *pConfig; /* Virtual table configuration */
+ Fts5Index *pIndex; /* Full-text index */
+ Fts5Storage *pStorage; /* Document store */
+ Fts5Global *pGlobal; /* Global (connection wide) data */
+ Fts5Cursor *pSortCsr; /* Sort data from this cursor */
+#ifdef SQLITE_DEBUG
+ struct Fts5TransactionState ts;
+#endif
+};
+
+struct Fts5MatchPhrase {
+ Fts5Buffer *pPoslist; /* Pointer to current poslist */
+ int nTerm; /* Size of phrase in terms */
+};
+
+/*
+** pStmt:
+** SELECT rowid, <fts> FROM <fts> ORDER BY +rank;
+**
+** aIdx[]:
+** There is one entry in the aIdx[] array for each phrase in the query,
+** the value of which is the offset within aPoslist[] following the last
+** byte of the position list for the corresponding phrase.
+*/
+struct Fts5Sorter {
+ sqlite3_stmt *pStmt;
+ i64 iRowid; /* Current rowid */
+ const u8 *aPoslist; /* Position lists for current row */
+ int nIdx; /* Number of entries in aIdx[] */
+ int aIdx[1]; /* Offsets into aPoslist for current row */
+};
+
+
+/*
+** Virtual-table cursor object.
+**
+** iSpecial:
+** If this is a 'special' query (refer to function fts5SpecialMatch()),
+** then this variable contains the result of the query.
+**
+** iFirstRowid, iLastRowid:
+** These variables are only used for FTS5_PLAN_MATCH cursors. Assuming the
+** cursor iterates in ascending order of rowids, iFirstRowid is the lower
+** limit of rowids to return, and iLastRowid the upper. In other words, the
+** WHERE clause in the user's query might have been:
+**
+** <tbl> MATCH <expr> AND rowid BETWEEN $iFirstRowid AND $iLastRowid
+**
+** If the cursor iterates in descending order of rowid, iFirstRowid
+** is the upper limit (i.e. the "first" rowid visited) and iLastRowid
+** the lower.
+*/
+struct Fts5Cursor {
+ sqlite3_vtab_cursor base; /* Base class used by SQLite core */
+ Fts5Cursor *pNext; /* Next cursor in Fts5Cursor.pCsr list */
+ int *aColumnSize; /* Values for xColumnSize() */
+ i64 iCsrId; /* Cursor id */
+
+ /* Zero from this point onwards on cursor reset */
+ int ePlan; /* FTS5_PLAN_XXX value */
+ int bDesc; /* True for "ORDER BY rowid DESC" queries */
+ i64 iFirstRowid; /* Return no rowids earlier than this */
+ i64 iLastRowid; /* Return no rowids later than this */
+ sqlite3_stmt *pStmt; /* Statement used to read %_content */
+ Fts5Expr *pExpr; /* Expression for MATCH queries */
+ Fts5Sorter *pSorter; /* Sorter for "ORDER BY rank" queries */
+ int csrflags; /* Mask of cursor flags (see below) */
+ i64 iSpecial; /* Result of special query */
+
+ /* "rank" function. Populated on demand from vtab.xColumn(). */
+ char *zRank; /* Custom rank function */
+ char *zRankArgs; /* Custom rank function args */
+ Fts5Auxiliary *pRank; /* Rank callback (or NULL) */
+ int nRankArg; /* Number of trailing arguments for rank() */
+ sqlite3_value **apRankArg; /* Array of trailing arguments */
+ sqlite3_stmt *pRankArgStmt; /* Origin of objects in apRankArg[] */
+
+ /* Auxiliary data storage */
+ Fts5Auxiliary *pAux; /* Currently executing extension function */
+ Fts5Auxdata *pAuxdata; /* First in linked list of saved aux-data */
+
+ /* Cache used by auxiliary functions xInst() and xInstCount() */
+ Fts5PoslistReader *aInstIter; /* One for each phrase */
+ int nInstAlloc; /* Size of aInst[] array (entries / 3) */
+ int nInstCount; /* Number of phrase instances */
+ int *aInst; /* 3 integers per phrase instance */
+};
+
+/*
+** Bits that make up the "idxNum" parameter passed indirectly by
+** xBestIndex() to xFilter().
+*/
+#define FTS5_BI_MATCH 0x0001 /* <tbl> MATCH ? */
+#define FTS5_BI_RANK 0x0002 /* rank MATCH ? */
+#define FTS5_BI_ROWID_EQ 0x0004 /* rowid == ? */
+#define FTS5_BI_ROWID_LE 0x0008 /* rowid <= ? */
+#define FTS5_BI_ROWID_GE 0x0010 /* rowid >= ? */
+
+#define FTS5_BI_ORDER_RANK 0x0020
+#define FTS5_BI_ORDER_ROWID 0x0040
+#define FTS5_BI_ORDER_DESC 0x0080
+
+/*
+** Values for Fts5Cursor.csrflags
+*/
+#define FTS5CSR_REQUIRE_CONTENT 0x01
+#define FTS5CSR_REQUIRE_DOCSIZE 0x02
+#define FTS5CSR_REQUIRE_INST 0x04
+#define FTS5CSR_EOF 0x08
+#define FTS5CSR_FREE_ZRANK 0x10
+#define FTS5CSR_REQUIRE_RESEEK 0x20
+
+#define BitFlagAllTest(x,y) (((x) & (y))==(y))
+#define BitFlagTest(x,y) (((x) & (y))!=0)
+
+
+/*
+** Macros to Set(), Clear() and Test() cursor flags.
+*/
+#define CsrFlagSet(pCsr, flag) ((pCsr)->csrflags |= (flag))
+#define CsrFlagClear(pCsr, flag) ((pCsr)->csrflags &= ~(flag))
+#define CsrFlagTest(pCsr, flag) ((pCsr)->csrflags & (flag))
+
+struct Fts5Auxdata {
+ Fts5Auxiliary *pAux; /* Extension to which this belongs */
+ void *pPtr; /* Pointer value */
+ void(*xDelete)(void*); /* Destructor */
+ Fts5Auxdata *pNext; /* Next object in linked list */
+};
+
+#ifdef SQLITE_DEBUG
+#define FTS5_BEGIN 1
+#define FTS5_SYNC 2
+#define FTS5_COMMIT 3
+#define FTS5_ROLLBACK 4
+#define FTS5_SAVEPOINT 5
+#define FTS5_RELEASE 6
+#define FTS5_ROLLBACKTO 7
+static void fts5CheckTransactionState(Fts5Table *p, int op, int iSavepoint){
+ switch( op ){
+ case FTS5_BEGIN:
+ assert( p->ts.eState==0 );
+ p->ts.eState = 1;
+ p->ts.iSavepoint = -1;
+ break;
+
+ case FTS5_SYNC:
+ assert( p->ts.eState==1 );
+ p->ts.eState = 2;
+ break;
+
+ case FTS5_COMMIT:
+ assert( p->ts.eState==2 );
+ p->ts.eState = 0;
+ break;
+
+ case FTS5_ROLLBACK:
+ assert( p->ts.eState==1 || p->ts.eState==2 || p->ts.eState==0 );
+ p->ts.eState = 0;
+ break;
+
+ case FTS5_SAVEPOINT:
+ assert( p->ts.eState==1 );
+ assert( iSavepoint>=0 );
+ assert( iSavepoint>p->ts.iSavepoint );
+ p->ts.iSavepoint = iSavepoint;
+ break;
+
+ case FTS5_RELEASE:
+ assert( p->ts.eState==1 );
+ assert( iSavepoint>=0 );
+ assert( iSavepoint<=p->ts.iSavepoint );
+ p->ts.iSavepoint = iSavepoint-1;
+ break;
+
+ case FTS5_ROLLBACKTO:
+ assert( p->ts.eState==1 );
+ assert( iSavepoint>=0 );
+ assert( iSavepoint<=p->ts.iSavepoint );
+ p->ts.iSavepoint = iSavepoint;
+ break;
+ }
+}
+#else
+# define fts5CheckTransactionState(x,y,z)
+#endif
+
+/*
+** Return true if pTab is a contentless table.
+*/
+static int fts5IsContentless(Fts5Table *pTab){
+ return pTab->pConfig->eContent==FTS5_CONTENT_NONE;
+}
+
+/*
+** Delete a virtual table handle allocated by fts5InitVtab().
+*/
+static void fts5FreeVtab(Fts5Table *pTab){
+ if( pTab ){
+ sqlite3Fts5IndexClose(pTab->pIndex);
+ sqlite3Fts5StorageClose(pTab->pStorage);
+ sqlite3Fts5ConfigFree(pTab->pConfig);
+ sqlite3_free(pTab);
+ }
+}
+
+/*
+** The xDisconnect() virtual table method.
+*/
+static int fts5DisconnectMethod(sqlite3_vtab *pVtab){
+ fts5FreeVtab((Fts5Table*)pVtab);
+ return SQLITE_OK;
+}
+
+/*
+** The xDestroy() virtual table method.
+*/
+static int fts5DestroyMethod(sqlite3_vtab *pVtab){
+ Fts5Table *pTab = (Fts5Table*)pVtab;
+ int rc = sqlite3Fts5DropAll(pTab->pConfig);
+ if( rc==SQLITE_OK ){
+ fts5FreeVtab((Fts5Table*)pVtab);
+ }
+ 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 ("fts5")
+** argv[1] -> database name
+** argv[2] -> table name
+** argv[...] -> "column name" and other module argument fields.
+*/
+static int fts5InitVtab(
+ int bCreate, /* 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 */
+){
+ Fts5Global *pGlobal = (Fts5Global*)pAux;
+ const char **azConfig = (const char**)argv;
+ int rc = SQLITE_OK; /* Return code */
+ Fts5Config *pConfig = 0; /* Results of parsing argc/argv */
+ Fts5Table *pTab = 0; /* New virtual table object */
+
+ /* Allocate the new vtab object and parse the configuration */
+ pTab = (Fts5Table*)sqlite3Fts5MallocZero(&rc, sizeof(Fts5Table));
+ if( rc==SQLITE_OK ){
+ rc = sqlite3Fts5ConfigParse(pGlobal, db, argc, azConfig, &pConfig, pzErr);
+ assert( (rc==SQLITE_OK && *pzErr==0) || pConfig==0 );
+ }
+ if( rc==SQLITE_OK ){
+ pTab->pConfig = pConfig;
+ pTab->pGlobal = pGlobal;
+ }
+
+ /* Open the index sub-system */
+ if( rc==SQLITE_OK ){
+ rc = sqlite3Fts5IndexOpen(pConfig, bCreate, &pTab->pIndex, pzErr);
+ }
+
+ /* Open the storage sub-system */
+ if( rc==SQLITE_OK ){
+ rc = sqlite3Fts5StorageOpen(
+ pConfig, pTab->pIndex, bCreate, &pTab->pStorage, pzErr
+ );
+ }
+
+ /* Call sqlite3_declare_vtab() */
+ if( rc==SQLITE_OK ){
+ rc = sqlite3Fts5ConfigDeclareVtab(pConfig);
+ }
+
+ /* Load the initial configuration */
+ if( rc==SQLITE_OK ){
+ assert( pConfig->pzErrmsg==0 );
+ pConfig->pzErrmsg = pzErr;
+ rc = sqlite3Fts5IndexLoadConfig(pTab->pIndex);
+ sqlite3Fts5IndexRollback(pTab->pIndex);
+ pConfig->pzErrmsg = 0;
+ }
+
+ if( rc!=SQLITE_OK ){
+ fts5FreeVtab(pTab);
+ pTab = 0;
+ }else if( bCreate ){
+ fts5CheckTransactionState(pTab, FTS5_BEGIN, 0);
+ }
+ *ppVTab = (sqlite3_vtab*)pTab;
+ return rc;
+}
+
+/*
+** The xConnect() and xCreate() methods for the virtual table. All the
+** work is done in function fts5InitVtab().
+*/
+static int fts5ConnectMethod(
+ 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 fts5InitVtab(0, db, pAux, argc, argv, ppVtab, pzErr);
+}
+static int fts5CreateMethod(
+ 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 fts5InitVtab(1, db, pAux, argc, argv, ppVtab, pzErr);
+}
+
+/*
+** The different query plans.
+*/
+#define FTS5_PLAN_MATCH 1 /* (<tbl> MATCH ?) */
+#define FTS5_PLAN_SOURCE 2 /* A source cursor for SORTED_MATCH */
+#define FTS5_PLAN_SPECIAL 3 /* An internal query */
+#define FTS5_PLAN_SORTED_MATCH 4 /* (<tbl> MATCH ? ORDER BY rank) */
+#define FTS5_PLAN_SCAN 5 /* No usable constraint */
+#define FTS5_PLAN_ROWID 6 /* (rowid = ?) */
+
+/*
+** Set the SQLITE_INDEX_SCAN_UNIQUE flag in pIdxInfo->flags. Unless this
+** extension is currently being used by a version of SQLite too old to
+** support index-info flags. In that case this function is a no-op.
+*/
+static void fts5SetUniqueFlag(sqlite3_index_info *pIdxInfo){
+#if SQLITE_VERSION_NUMBER>=3008012
+#ifndef SQLITE_CORE
+ if( sqlite3_libversion_number()>=3008012 )
+#endif
+ {
+ pIdxInfo->idxFlags |= SQLITE_INDEX_SCAN_UNIQUE;
+ }
+#endif
+}
+
+/*
+** Implementation of the xBestIndex method for FTS5 tables. Within the
+** WHERE constraint, it searches for the following:
+**
+** 1. A MATCH constraint against the special column.
+** 2. A MATCH constraint against the "rank" column.
+** 3. An == constraint against the rowid column.
+** 4. A < or <= constraint against the rowid column.
+** 5. A > or >= constraint against the rowid column.
+**
+** Within the ORDER BY, either:
+**
+** 5. ORDER BY rank [ASC|DESC]
+** 6. ORDER BY rowid [ASC|DESC]
+**
+** Costs are assigned as follows:
+**
+** a) If an unusable MATCH operator is present in the WHERE clause, the
+** cost is unconditionally set to 1e50 (a really big number).
+**
+** a) If a MATCH operator is present, the cost depends on the other
+** constraints also present. As follows:
+**
+** * No other constraints: cost=1000.0
+** * One rowid range constraint: cost=750.0
+** * Both rowid range constraints: cost=500.0
+** * An == rowid constraint: cost=100.0
+**
+** b) Otherwise, if there is no MATCH:
+**
+** * No other constraints: cost=1000000.0
+** * One rowid range constraint: cost=750000.0
+** * Both rowid range constraints: cost=250000.0
+** * An == rowid constraint: cost=10.0
+**
+** Costs are not modified by the ORDER BY clause.
+*/
+static int fts5BestIndexMethod(sqlite3_vtab *pVTab, sqlite3_index_info *pInfo){
+ Fts5Table *pTab = (Fts5Table*)pVTab;
+ Fts5Config *pConfig = pTab->pConfig;
+ int idxFlags = 0; /* Parameter passed through to xFilter() */
+ int bHasMatch;
+ int iNext;
+ int i;
+
+ struct Constraint {
+ int op; /* Mask against sqlite3_index_constraint.op */
+ int fts5op; /* FTS5 mask for idxFlags */
+ int iCol; /* 0==rowid, 1==tbl, 2==rank */
+ int omit; /* True to omit this if found */
+ int iConsIndex; /* Index in pInfo->aConstraint[] */
+ } aConstraint[] = {
+ {SQLITE_INDEX_CONSTRAINT_MATCH|SQLITE_INDEX_CONSTRAINT_EQ,
+ FTS5_BI_MATCH, 1, 1, -1},
+ {SQLITE_INDEX_CONSTRAINT_MATCH|SQLITE_INDEX_CONSTRAINT_EQ,
+ FTS5_BI_RANK, 2, 1, -1},
+ {SQLITE_INDEX_CONSTRAINT_EQ, FTS5_BI_ROWID_EQ, 0, 0, -1},
+ {SQLITE_INDEX_CONSTRAINT_LT|SQLITE_INDEX_CONSTRAINT_LE,
+ FTS5_BI_ROWID_LE, 0, 0, -1},
+ {SQLITE_INDEX_CONSTRAINT_GT|SQLITE_INDEX_CONSTRAINT_GE,
+ FTS5_BI_ROWID_GE, 0, 0, -1},
+ };
+
+ int aColMap[3];
+ aColMap[0] = -1;
+ aColMap[1] = pConfig->nCol;
+ aColMap[2] = pConfig->nCol+1;
+
+ /* Set idxFlags flags for all WHERE clause terms that will be used. */
+ for(i=0; i<pInfo->nConstraint; i++){
+ struct sqlite3_index_constraint *p = &pInfo->aConstraint[i];
+ int j;
+ for(j=0; j<(int)ArraySize(aConstraint); j++){
+ struct Constraint *pC = &aConstraint[j];
+ if( p->iColumn==aColMap[pC->iCol] && p->op & pC->op ){
+ if( p->usable ){
+ pC->iConsIndex = i;
+ idxFlags |= pC->fts5op;
+ }else if( j==0 ){
+ /* As there exists an unusable MATCH constraint this is an
+ ** unusable plan. Set a prohibitively high cost. */
+ pInfo->estimatedCost = 1e50;
+ return SQLITE_OK;
+ }
+ }
+ }
+ }
+
+ /* Set idxFlags flags for the ORDER BY clause */
+ if( pInfo->nOrderBy==1 ){
+ int iSort = pInfo->aOrderBy[0].iColumn;
+ if( iSort==(pConfig->nCol+1) && BitFlagTest(idxFlags, FTS5_BI_MATCH) ){
+ idxFlags |= FTS5_BI_ORDER_RANK;
+ }else if( iSort==-1 ){
+ idxFlags |= FTS5_BI_ORDER_ROWID;
+ }
+ if( BitFlagTest(idxFlags, FTS5_BI_ORDER_RANK|FTS5_BI_ORDER_ROWID) ){
+ pInfo->orderByConsumed = 1;
+ if( pInfo->aOrderBy[0].desc ){
+ idxFlags |= FTS5_BI_ORDER_DESC;
+ }
+ }
+ }
+
+ /* Calculate the estimated cost based on the flags set in idxFlags. */
+ bHasMatch = BitFlagTest(idxFlags, FTS5_BI_MATCH);
+ if( BitFlagTest(idxFlags, FTS5_BI_ROWID_EQ) ){
+ pInfo->estimatedCost = bHasMatch ? 100.0 : 10.0;
+ if( bHasMatch==0 ) fts5SetUniqueFlag(pInfo);
+ }else if( BitFlagAllTest(idxFlags, FTS5_BI_ROWID_LE|FTS5_BI_ROWID_GE) ){
+ pInfo->estimatedCost = bHasMatch ? 500.0 : 250000.0;
+ }else if( BitFlagTest(idxFlags, FTS5_BI_ROWID_LE|FTS5_BI_ROWID_GE) ){
+ pInfo->estimatedCost = bHasMatch ? 750.0 : 750000.0;
+ }else{
+ pInfo->estimatedCost = bHasMatch ? 1000.0 : 1000000.0;
+ }
+
+ /* Assign argvIndex values to each constraint in use. */
+ iNext = 1;
+ for(i=0; i<(int)ArraySize(aConstraint); i++){
+ struct Constraint *pC = &aConstraint[i];
+ if( pC->iConsIndex>=0 ){
+ pInfo->aConstraintUsage[pC->iConsIndex].argvIndex = iNext++;
+ pInfo->aConstraintUsage[pC->iConsIndex].omit = (unsigned char)pC->omit;
+ }
+ }
+
+ pInfo->idxNum = idxFlags;
+ return SQLITE_OK;
+}
+
+/*
+** Implementation of xOpen method.
+*/
+static int fts5OpenMethod(sqlite3_vtab *pVTab, sqlite3_vtab_cursor **ppCsr){
+ Fts5Table *pTab = (Fts5Table*)pVTab;
+ Fts5Config *pConfig = pTab->pConfig;
+ Fts5Cursor *pCsr; /* New cursor object */
+ int nByte; /* Bytes of space to allocate */
+ int rc = SQLITE_OK; /* Return code */
+
+ nByte = sizeof(Fts5Cursor) + pConfig->nCol * sizeof(int);
+ pCsr = (Fts5Cursor*)sqlite3_malloc(nByte);
+ if( pCsr ){
+ Fts5Global *pGlobal = pTab->pGlobal;
+ memset(pCsr, 0, nByte);
+ pCsr->aColumnSize = (int*)&pCsr[1];
+ pCsr->pNext = pGlobal->pCsr;
+ pGlobal->pCsr = pCsr;
+ pCsr->iCsrId = ++pGlobal->iNextId;
+ }else{
+ rc = SQLITE_NOMEM;
+ }
+ *ppCsr = (sqlite3_vtab_cursor*)pCsr;
+ return rc;
+}
+
+static int fts5StmtType(Fts5Cursor *pCsr){
+ if( pCsr->ePlan==FTS5_PLAN_SCAN ){
+ return (pCsr->bDesc) ? FTS5_STMT_SCAN_DESC : FTS5_STMT_SCAN_ASC;
+ }
+ return FTS5_STMT_LOOKUP;
+}
+
+/*
+** This function is called after the cursor passed as the only argument
+** is moved to point at a different row. It clears all cached data
+** specific to the previous row stored by the cursor object.
+*/
+static void fts5CsrNewrow(Fts5Cursor *pCsr){
+ CsrFlagSet(pCsr,
+ FTS5CSR_REQUIRE_CONTENT
+ | FTS5CSR_REQUIRE_DOCSIZE
+ | FTS5CSR_REQUIRE_INST
+ );
+}
+
+static void fts5FreeCursorComponents(Fts5Cursor *pCsr){
+ Fts5Table *pTab = (Fts5Table*)(pCsr->base.pVtab);
+ Fts5Auxdata *pData;
+ Fts5Auxdata *pNext;
+
+ sqlite3_free(pCsr->aInstIter);
+ sqlite3_free(pCsr->aInst);
+ if( pCsr->pStmt ){
+ int eStmt = fts5StmtType(pCsr);
+ sqlite3Fts5StorageStmtRelease(pTab->pStorage, eStmt, pCsr->pStmt);
+ }
+ if( pCsr->pSorter ){
+ Fts5Sorter *pSorter = pCsr->pSorter;
+ sqlite3_finalize(pSorter->pStmt);
+ sqlite3_free(pSorter);
+ }
+
+ if( pCsr->ePlan!=FTS5_PLAN_SOURCE ){
+ sqlite3Fts5ExprFree(pCsr->pExpr);
+ }
+
+ for(pData=pCsr->pAuxdata; pData; pData=pNext){
+ pNext = pData->pNext;
+ if( pData->xDelete ) pData->xDelete(pData->pPtr);
+ sqlite3_free(pData);
+ }
+
+ sqlite3_finalize(pCsr->pRankArgStmt);
+ sqlite3_free(pCsr->apRankArg);
+
+ if( CsrFlagTest(pCsr, FTS5CSR_FREE_ZRANK) ){
+ sqlite3_free(pCsr->zRank);
+ sqlite3_free(pCsr->zRankArgs);
+ }
+
+ memset(&pCsr->ePlan, 0, sizeof(Fts5Cursor) - ((u8*)&pCsr->ePlan - (u8*)pCsr));
+}
+
+
+/*
+** Close the cursor. For additional information see the documentation
+** on the xClose method of the virtual table interface.
+*/
+static int fts5CloseMethod(sqlite3_vtab_cursor *pCursor){
+ if( pCursor ){
+ Fts5Table *pTab = (Fts5Table*)(pCursor->pVtab);
+ Fts5Cursor *pCsr = (Fts5Cursor*)pCursor;
+ Fts5Cursor **pp;
+
+ fts5FreeCursorComponents(pCsr);
+ /* Remove the cursor from the Fts5Global.pCsr list */
+ for(pp=&pTab->pGlobal->pCsr; (*pp)!=pCsr; pp=&(*pp)->pNext);
+ *pp = pCsr->pNext;
+
+ sqlite3_free(pCsr);
+ }
+ return SQLITE_OK;
+}
+
+static int fts5SorterNext(Fts5Cursor *pCsr){
+ Fts5Sorter *pSorter = pCsr->pSorter;
+ int rc;
+
+ rc = sqlite3_step(pSorter->pStmt);
+ if( rc==SQLITE_DONE ){
+ rc = SQLITE_OK;
+ CsrFlagSet(pCsr, FTS5CSR_EOF);
+ }else if( rc==SQLITE_ROW ){
+ const u8 *a;
+ const u8 *aBlob;
+ int nBlob;
+ int i;
+ int iOff = 0;
+ rc = SQLITE_OK;
+
+ pSorter->iRowid = sqlite3_column_int64(pSorter->pStmt, 0);
+ nBlob = sqlite3_column_bytes(pSorter->pStmt, 1);
+ aBlob = a = sqlite3_column_blob(pSorter->pStmt, 1);
+
+ for(i=0; i<(pSorter->nIdx-1); i++){
+ int iVal;
+ a += fts5GetVarint32(a, iVal);
+ iOff += iVal;
+ pSorter->aIdx[i] = iOff;
+ }
+ pSorter->aIdx[i] = &aBlob[nBlob] - a;
+
+ pSorter->aPoslist = a;
+ fts5CsrNewrow(pCsr);
+ }
+
+ return rc;
+}
+
+
+/*
+** Set the FTS5CSR_REQUIRE_RESEEK flag on all FTS5_PLAN_MATCH cursors
+** open on table pTab.
+*/
+static void fts5TripCursors(Fts5Table *pTab){
+ Fts5Cursor *pCsr;
+ for(pCsr=pTab->pGlobal->pCsr; pCsr; pCsr=pCsr->pNext){
+ if( pCsr->ePlan==FTS5_PLAN_MATCH
+ && pCsr->base.pVtab==(sqlite3_vtab*)pTab
+ ){
+ CsrFlagSet(pCsr, FTS5CSR_REQUIRE_RESEEK);
+ }
+ }
+}
+
+/*
+** If the REQUIRE_RESEEK flag is set on the cursor passed as the first
+** argument, close and reopen all Fts5IndexIter iterators that the cursor
+** is using. Then attempt to move the cursor to a rowid equal to or laster
+** (in the cursors sort order - ASC or DESC) than the current rowid.
+**
+** If the new rowid is not equal to the old, set output parameter *pbSkip
+** to 1 before returning. Otherwise, leave it unchanged.
+**
+** Return SQLITE_OK if successful or if no reseek was required, or an
+** error code if an error occurred.
+*/
+static int fts5CursorReseek(Fts5Cursor *pCsr, int *pbSkip){
+ int rc = SQLITE_OK;
+ assert( *pbSkip==0 );
+ if( CsrFlagTest(pCsr, FTS5CSR_REQUIRE_RESEEK) ){
+ Fts5Table *pTab = (Fts5Table*)(pCsr->base.pVtab);
+ int bDesc = pCsr->bDesc;
+ i64 iRowid = sqlite3Fts5ExprRowid(pCsr->pExpr);
+
+ rc = sqlite3Fts5ExprFirst(pCsr->pExpr, pTab->pIndex, iRowid, bDesc);
+ if( rc==SQLITE_OK && iRowid!=sqlite3Fts5ExprRowid(pCsr->pExpr) ){
+ *pbSkip = 1;
+ }
+
+ CsrFlagClear(pCsr, FTS5CSR_REQUIRE_RESEEK);
+ fts5CsrNewrow(pCsr);
+ if( sqlite3Fts5ExprEof(pCsr->pExpr) ){
+ CsrFlagSet(pCsr, FTS5CSR_EOF);
+ }
+ }
+ return rc;
+}
+
+
+/*
+** Advance the cursor to the next row in the table that matches the
+** search criteria.
+**
+** Return SQLITE_OK if nothing goes wrong. SQLITE_OK is returned
+** even if we reach end-of-file. The fts5EofMethod() will be called
+** subsequently to determine whether or not an EOF was hit.
+*/
+static int fts5NextMethod(sqlite3_vtab_cursor *pCursor){
+ Fts5Cursor *pCsr = (Fts5Cursor*)pCursor;
+ int rc = SQLITE_OK;
+
+ assert( (pCsr->ePlan<3)==
+ (pCsr->ePlan==FTS5_PLAN_MATCH || pCsr->ePlan==FTS5_PLAN_SOURCE)
+ );
+
+ if( pCsr->ePlan<3 ){
+ int bSkip = 0;
+ if( (rc = fts5CursorReseek(pCsr, &bSkip)) || bSkip ) return rc;
+ rc = sqlite3Fts5ExprNext(pCsr->pExpr, pCsr->iLastRowid);
+ if( sqlite3Fts5ExprEof(pCsr->pExpr) ){
+ CsrFlagSet(pCsr, FTS5CSR_EOF);
+ }
+ fts5CsrNewrow(pCsr);
+ }else{
+ switch( pCsr->ePlan ){
+ case FTS5_PLAN_SPECIAL: {
+ CsrFlagSet(pCsr, FTS5CSR_EOF);
+ break;
+ }
+
+ case FTS5_PLAN_SORTED_MATCH: {
+ rc = fts5SorterNext(pCsr);
+ break;
+ }
+
+ default:
+ rc = sqlite3_step(pCsr->pStmt);
+ if( rc!=SQLITE_ROW ){
+ CsrFlagSet(pCsr, FTS5CSR_EOF);
+ rc = sqlite3_reset(pCsr->pStmt);
+ }else{
+ rc = SQLITE_OK;
+ }
+ break;
+ }
+ }
+
+ return rc;
+}
+
+
+static sqlite3_stmt *fts5PrepareStatement(
+ int *pRc,
+ Fts5Config *pConfig,
+ const char *zFmt,
+ ...
+){
+ sqlite3_stmt *pRet = 0;
+ va_list ap;
+ va_start(ap, zFmt);
+
+ if( *pRc==SQLITE_OK ){
+ int rc;
+ char *zSql = sqlite3_vmprintf(zFmt, ap);
+ if( zSql==0 ){
+ rc = SQLITE_NOMEM;
+ }else{
+ rc = sqlite3_prepare_v2(pConfig->db, zSql, -1, &pRet, 0);
+ if( rc!=SQLITE_OK ){
+ *pConfig->pzErrmsg = sqlite3_mprintf("%s", sqlite3_errmsg(pConfig->db));
+ }
+ sqlite3_free(zSql);
+ }
+ *pRc = rc;
+ }
+
+ va_end(ap);
+ return pRet;
+}
+
+static int fts5CursorFirstSorted(Fts5Table *pTab, Fts5Cursor *pCsr, int bDesc){
+ Fts5Config *pConfig = pTab->pConfig;
+ Fts5Sorter *pSorter;
+ int nPhrase;
+ int nByte;
+ int rc = SQLITE_OK;
+ const char *zRank = pCsr->zRank;
+ const char *zRankArgs = pCsr->zRankArgs;
+
+ nPhrase = sqlite3Fts5ExprPhraseCount(pCsr->pExpr);
+ nByte = sizeof(Fts5Sorter) + sizeof(int) * (nPhrase-1);
+ pSorter = (Fts5Sorter*)sqlite3_malloc(nByte);
+ if( pSorter==0 ) return SQLITE_NOMEM;
+ memset(pSorter, 0, nByte);
+ pSorter->nIdx = nPhrase;
+
+ /* TODO: It would be better to have some system for reusing statement
+ ** handles here, rather than preparing a new one for each query. But that
+ ** is not possible as SQLite reference counts the virtual table objects.
+ ** And since the statement required here reads from this very virtual
+ ** table, saving it creates a circular reference.
+ **
+ ** If SQLite a built-in statement cache, this wouldn't be a problem. */
+ pSorter->pStmt = fts5PrepareStatement(&rc, pConfig,
+ "SELECT rowid, rank FROM %Q.%Q ORDER BY %s(%s%s%s) %s",
+ pConfig->zDb, pConfig->zName, zRank, pConfig->zName,
+ (zRankArgs ? ", " : ""),
+ (zRankArgs ? zRankArgs : ""),
+ bDesc ? "DESC" : "ASC"
+ );
+
+ pCsr->pSorter = pSorter;
+ if( rc==SQLITE_OK ){
+ assert( pTab->pSortCsr==0 );
+ pTab->pSortCsr = pCsr;
+ rc = fts5SorterNext(pCsr);
+ pTab->pSortCsr = 0;
+ }
+
+ if( rc!=SQLITE_OK ){
+ sqlite3_finalize(pSorter->pStmt);
+ sqlite3_free(pSorter);
+ pCsr->pSorter = 0;
+ }
+
+ return rc;
+}
+
+static int fts5CursorFirst(Fts5Table *pTab, Fts5Cursor *pCsr, int bDesc){
+ int rc;
+ Fts5Expr *pExpr = pCsr->pExpr;
+ rc = sqlite3Fts5ExprFirst(pExpr, pTab->pIndex, pCsr->iFirstRowid, bDesc);
+ if( sqlite3Fts5ExprEof(pExpr) ){
+ CsrFlagSet(pCsr, FTS5CSR_EOF);
+ }
+ fts5CsrNewrow(pCsr);
+ return rc;
+}
+
+/*
+** Process a "special" query. A special query is identified as one with a
+** MATCH expression that begins with a '*' character. The remainder of
+** the text passed to the MATCH operator are used as the special query
+** parameters.
+*/
+static int fts5SpecialMatch(
+ Fts5Table *pTab,
+ Fts5Cursor *pCsr,
+ const char *zQuery
+){
+ int rc = SQLITE_OK; /* Return code */
+ const char *z = zQuery; /* Special query text */
+ int n; /* Number of bytes in text at z */
+
+ while( z[0]==' ' ) z++;
+ for(n=0; z[n] && z[n]!=' '; n++);
+
+ assert( pTab->base.zErrMsg==0 );
+ pCsr->ePlan = FTS5_PLAN_SPECIAL;
+
+ if( 0==sqlite3_strnicmp("reads", z, n) ){
+ pCsr->iSpecial = sqlite3Fts5IndexReads(pTab->pIndex);
+ }
+ else if( 0==sqlite3_strnicmp("id", z, n) ){
+ pCsr->iSpecial = pCsr->iCsrId;
+ }
+ else{
+ /* An unrecognized directive. Return an error message. */
+ pTab->base.zErrMsg = sqlite3_mprintf("unknown special query: %.*s", n, z);
+ rc = SQLITE_ERROR;
+ }
+
+ return rc;
+}
+
+/*
+** Search for an auxiliary function named zName that can be used with table
+** pTab. If one is found, return a pointer to the corresponding Fts5Auxiliary
+** structure. Otherwise, if no such function exists, return NULL.
+*/
+static Fts5Auxiliary *fts5FindAuxiliary(Fts5Table *pTab, const char *zName){
+ Fts5Auxiliary *pAux;
+
+ for(pAux=pTab->pGlobal->pAux; pAux; pAux=pAux->pNext){
+ if( sqlite3_stricmp(zName, pAux->zFunc)==0 ) return pAux;
+ }
+
+ /* No function of the specified name was found. Return 0. */
+ return 0;
+}
+
+
+static int fts5FindRankFunction(Fts5Cursor *pCsr){
+ Fts5Table *pTab = (Fts5Table*)(pCsr->base.pVtab);
+ Fts5Config *pConfig = pTab->pConfig;
+ int rc = SQLITE_OK;
+ Fts5Auxiliary *pAux = 0;
+ const char *zRank = pCsr->zRank;
+ const char *zRankArgs = pCsr->zRankArgs;
+
+ if( zRankArgs ){
+ char *zSql = sqlite3Fts5Mprintf(&rc, "SELECT %s", zRankArgs);
+ if( zSql ){
+ sqlite3_stmt *pStmt = 0;
+ rc = sqlite3_prepare_v2(pConfig->db, zSql, -1, &pStmt, 0);
+ sqlite3_free(zSql);
+ assert( rc==SQLITE_OK || pCsr->pRankArgStmt==0 );
+ if( rc==SQLITE_OK ){
+ if( SQLITE_ROW==sqlite3_step(pStmt) ){
+ int nByte;
+ pCsr->nRankArg = sqlite3_column_count(pStmt);
+ nByte = sizeof(sqlite3_value*)*pCsr->nRankArg;
+ pCsr->apRankArg = (sqlite3_value**)sqlite3Fts5MallocZero(&rc, nByte);
+ if( rc==SQLITE_OK ){
+ int i;
+ for(i=0; i<pCsr->nRankArg; i++){
+ pCsr->apRankArg[i] = sqlite3_column_value(pStmt, i);
+ }
+ }
+ pCsr->pRankArgStmt = pStmt;
+ }else{
+ rc = sqlite3_finalize(pStmt);
+ assert( rc!=SQLITE_OK );
+ }
+ }
+ }
+ }
+
+ if( rc==SQLITE_OK ){
+ pAux = fts5FindAuxiliary(pTab, zRank);
+ if( pAux==0 ){
+ assert( pTab->base.zErrMsg==0 );
+ pTab->base.zErrMsg = sqlite3_mprintf("no such function: %s", zRank);
+ rc = SQLITE_ERROR;
+ }
+ }
+
+ pCsr->pRank = pAux;
+ return rc;
+}
+
+
+static int fts5CursorParseRank(
+ Fts5Config *pConfig,
+ Fts5Cursor *pCsr,
+ sqlite3_value *pRank
+){
+ int rc = SQLITE_OK;
+ if( pRank ){
+ const char *z = (const char*)sqlite3_value_text(pRank);
+ char *zRank = 0;
+ char *zRankArgs = 0;
+
+ if( z==0 ){
+ if( sqlite3_value_type(pRank)==SQLITE_NULL ) rc = SQLITE_ERROR;
+ }else{
+ rc = sqlite3Fts5ConfigParseRank(z, &zRank, &zRankArgs);
+ }
+ if( rc==SQLITE_OK ){
+ pCsr->zRank = zRank;
+ pCsr->zRankArgs = zRankArgs;
+ CsrFlagSet(pCsr, FTS5CSR_FREE_ZRANK);
+ }else if( rc==SQLITE_ERROR ){
+ pCsr->base.pVtab->zErrMsg = sqlite3_mprintf(
+ "parse error in rank function: %s", z
+ );
+ }
+ }else{
+ if( pConfig->zRank ){
+ pCsr->zRank = (char*)pConfig->zRank;
+ pCsr->zRankArgs = (char*)pConfig->zRankArgs;
+ }else{
+ pCsr->zRank = (char*)FTS5_DEFAULT_RANK;
+ pCsr->zRankArgs = 0;
+ }
+ }
+ return rc;
+}
+
+static i64 fts5GetRowidLimit(sqlite3_value *pVal, i64 iDefault){
+ if( pVal ){
+ int eType = sqlite3_value_numeric_type(pVal);
+ if( eType==SQLITE_INTEGER ){
+ return sqlite3_value_int64(pVal);
+ }
+ }
+ return iDefault;
+}
+
+/*
+** This is the xFilter interface for the virtual table. See
+** the virtual table xFilter method documentation for additional
+** information.
+**
+** There are three possible query strategies:
+**
+** 1. Full-text search using a MATCH operator.
+** 2. A by-rowid lookup.
+** 3. A full-table scan.
+*/
+static int fts5FilterMethod(
+ 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 */
+){
+ Fts5Table *pTab = (Fts5Table*)(pCursor->pVtab);
+ Fts5Config *pConfig = pTab->pConfig;
+ Fts5Cursor *pCsr = (Fts5Cursor*)pCursor;
+ int rc = SQLITE_OK; /* Error code */
+ int iVal = 0; /* Counter for apVal[] */
+ int bDesc; /* True if ORDER BY [rank|rowid] DESC */
+ int bOrderByRank; /* True if ORDER BY rank */
+ sqlite3_value *pMatch = 0; /* <tbl> MATCH ? expression (or NULL) */
+ sqlite3_value *pRank = 0; /* rank MATCH ? expression (or NULL) */
+ sqlite3_value *pRowidEq = 0; /* rowid = ? expression (or NULL) */
+ sqlite3_value *pRowidLe = 0; /* rowid <= ? expression (or NULL) */
+ sqlite3_value *pRowidGe = 0; /* rowid >= ? expression (or NULL) */
+ char **pzErrmsg = pConfig->pzErrmsg;
+
+ if( pCsr->ePlan ){
+ fts5FreeCursorComponents(pCsr);
+ memset(&pCsr->ePlan, 0, sizeof(Fts5Cursor) - ((u8*)&pCsr->ePlan-(u8*)pCsr));
+ }
+
+ assert( pCsr->pStmt==0 );
+ assert( pCsr->pExpr==0 );
+ assert( pCsr->csrflags==0 );
+ assert( pCsr->pRank==0 );
+ assert( pCsr->zRank==0 );
+ assert( pCsr->zRankArgs==0 );
+
+ assert( pzErrmsg==0 || pzErrmsg==&pTab->base.zErrMsg );
+ pConfig->pzErrmsg = &pTab->base.zErrMsg;
+
+ /* Decode the arguments passed through to this function.
+ **
+ ** Note: The following set of if(...) statements must be in the same
+ ** order as the corresponding entries in the struct at the top of
+ ** fts5BestIndexMethod(). */
+ if( BitFlagTest(idxNum, FTS5_BI_MATCH) ) pMatch = apVal[iVal++];
+ if( BitFlagTest(idxNum, FTS5_BI_RANK) ) pRank = apVal[iVal++];
+ if( BitFlagTest(idxNum, FTS5_BI_ROWID_EQ) ) pRowidEq = apVal[iVal++];
+ if( BitFlagTest(idxNum, FTS5_BI_ROWID_LE) ) pRowidLe = apVal[iVal++];
+ if( BitFlagTest(idxNum, FTS5_BI_ROWID_GE) ) pRowidGe = apVal[iVal++];
+ assert( iVal==nVal );
+ bOrderByRank = ((idxNum & FTS5_BI_ORDER_RANK) ? 1 : 0);
+ pCsr->bDesc = bDesc = ((idxNum & FTS5_BI_ORDER_DESC) ? 1 : 0);
+
+ /* Set the cursor upper and lower rowid limits. Only some strategies
+ ** actually use them. This is ok, as the xBestIndex() method leaves the
+ ** sqlite3_index_constraint.omit flag clear for range constraints
+ ** on the rowid field. */
+ if( pRowidEq ){
+ pRowidLe = pRowidGe = pRowidEq;
+ }
+ if( bDesc ){
+ pCsr->iFirstRowid = fts5GetRowidLimit(pRowidLe, LARGEST_INT64);
+ pCsr->iLastRowid = fts5GetRowidLimit(pRowidGe, SMALLEST_INT64);
+ }else{
+ pCsr->iLastRowid = fts5GetRowidLimit(pRowidLe, LARGEST_INT64);
+ pCsr->iFirstRowid = fts5GetRowidLimit(pRowidGe, SMALLEST_INT64);
+ }
+
+ if( pTab->pSortCsr ){
+ /* If pSortCsr is non-NULL, then this call is being made as part of
+ ** processing for a "... MATCH <expr> ORDER BY rank" query (ePlan is
+ ** set to FTS5_PLAN_SORTED_MATCH). pSortCsr is the cursor that will
+ ** return results to the user for this query. The current cursor
+ ** (pCursor) is used to execute the query issued by function
+ ** fts5CursorFirstSorted() above. */
+ assert( pRowidEq==0 && pRowidLe==0 && pRowidGe==0 && pRank==0 );
+ assert( nVal==0 && pMatch==0 && bOrderByRank==0 && bDesc==0 );
+ assert( pCsr->iLastRowid==LARGEST_INT64 );
+ assert( pCsr->iFirstRowid==SMALLEST_INT64 );
+ pCsr->ePlan = FTS5_PLAN_SOURCE;
+ pCsr->pExpr = pTab->pSortCsr->pExpr;
+ rc = fts5CursorFirst(pTab, pCsr, bDesc);
+ }else if( pMatch ){
+ const char *zExpr = (const char*)sqlite3_value_text(apVal[0]);
+ if( zExpr==0 ) zExpr = "";
+
+ rc = fts5CursorParseRank(pConfig, pCsr, pRank);
+ if( rc==SQLITE_OK ){
+ if( zExpr[0]=='*' ){
+ /* The user has issued a query of the form "MATCH '*...'". This
+ ** indicates that the MATCH expression is not a full text query,
+ ** but a request for an internal parameter. */
+ rc = fts5SpecialMatch(pTab, pCsr, &zExpr[1]);
+ }else{
+ char **pzErr = &pTab->base.zErrMsg;
+ rc = sqlite3Fts5ExprNew(pConfig, zExpr, &pCsr->pExpr, pzErr);
+ if( rc==SQLITE_OK ){
+ if( bOrderByRank ){
+ pCsr->ePlan = FTS5_PLAN_SORTED_MATCH;
+ rc = fts5CursorFirstSorted(pTab, pCsr, bDesc);
+ }else{
+ pCsr->ePlan = FTS5_PLAN_MATCH;
+ rc = fts5CursorFirst(pTab, pCsr, bDesc);
+ }
+ }
+ }
+ }
+ }else if( pConfig->zContent==0 ){
+ *pConfig->pzErrmsg = sqlite3_mprintf(
+ "%s: table does not support scanning", pConfig->zName
+ );
+ rc = SQLITE_ERROR;
+ }else{
+ /* This is either a full-table scan (ePlan==FTS5_PLAN_SCAN) or a lookup
+ ** by rowid (ePlan==FTS5_PLAN_ROWID). */
+ pCsr->ePlan = (pRowidEq ? FTS5_PLAN_ROWID : FTS5_PLAN_SCAN);
+ rc = sqlite3Fts5StorageStmt(
+ pTab->pStorage, fts5StmtType(pCsr), &pCsr->pStmt, &pTab->base.zErrMsg
+ );
+ if( rc==SQLITE_OK ){
+ if( pCsr->ePlan==FTS5_PLAN_ROWID ){
+ sqlite3_bind_value(pCsr->pStmt, 1, apVal[0]);
+ }else{
+ sqlite3_bind_int64(pCsr->pStmt, 1, pCsr->iFirstRowid);
+ sqlite3_bind_int64(pCsr->pStmt, 2, pCsr->iLastRowid);
+ }
+ rc = fts5NextMethod(pCursor);
+ }
+ }
+
+ pConfig->pzErrmsg = pzErrmsg;
+ return rc;
+}
+
+/*
+** 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 fts5EofMethod(sqlite3_vtab_cursor *pCursor){
+ Fts5Cursor *pCsr = (Fts5Cursor*)pCursor;
+ return (CsrFlagTest(pCsr, FTS5CSR_EOF) ? 1 : 0);
+}
+
+/*
+** Return the rowid that the cursor currently points to.
+*/
+static i64 fts5CursorRowid(Fts5Cursor *pCsr){
+ assert( pCsr->ePlan==FTS5_PLAN_MATCH
+ || pCsr->ePlan==FTS5_PLAN_SORTED_MATCH
+ || pCsr->ePlan==FTS5_PLAN_SOURCE
+ );
+ if( pCsr->pSorter ){
+ return pCsr->pSorter->iRowid;
+ }else{
+ return sqlite3Fts5ExprRowid(pCsr->pExpr);
+ }
+}
+
+/*
+** This is the xRowid method. The SQLite core calls this routine to
+** retrieve the rowid for the current row of the result set. fts5
+** exposes %_content.rowid as the rowid for the virtual table. The
+** rowid should be written to *pRowid.
+*/
+static int fts5RowidMethod(sqlite3_vtab_cursor *pCursor, sqlite_int64 *pRowid){
+ Fts5Cursor *pCsr = (Fts5Cursor*)pCursor;
+ int ePlan = pCsr->ePlan;
+
+ assert( CsrFlagTest(pCsr, FTS5CSR_EOF)==0 );
+ switch( ePlan ){
+ case FTS5_PLAN_SPECIAL:
+ *pRowid = 0;
+ break;
+
+ case FTS5_PLAN_SOURCE:
+ case FTS5_PLAN_MATCH:
+ case FTS5_PLAN_SORTED_MATCH:
+ *pRowid = fts5CursorRowid(pCsr);
+ break;
+
+ default:
+ *pRowid = sqlite3_column_int64(pCsr->pStmt, 0);
+ break;
+ }
+
+ return SQLITE_OK;
+}
+
+/*
+** If the cursor requires seeking (bSeekRequired flag is set), seek it.
+** Return SQLITE_OK if no error occurs, or an SQLite error code otherwise.
+**
+** If argument bErrormsg is true and an error occurs, an error message may
+** be left in sqlite3_vtab.zErrMsg.
+*/
+static int fts5SeekCursor(Fts5Cursor *pCsr, int bErrormsg){
+ int rc = SQLITE_OK;
+
+ /* If the cursor does not yet have a statement handle, obtain one now. */
+ if( pCsr->pStmt==0 ){
+ Fts5Table *pTab = (Fts5Table*)(pCsr->base.pVtab);
+ int eStmt = fts5StmtType(pCsr);
+ rc = sqlite3Fts5StorageStmt(
+ pTab->pStorage, eStmt, &pCsr->pStmt, (bErrormsg?&pTab->base.zErrMsg:0)
+ );
+ assert( rc!=SQLITE_OK || pTab->base.zErrMsg==0 );
+ assert( CsrFlagTest(pCsr, FTS5CSR_REQUIRE_CONTENT) );
+ }
+
+ if( rc==SQLITE_OK && CsrFlagTest(pCsr, FTS5CSR_REQUIRE_CONTENT) ){
+ assert( pCsr->pExpr );
+ sqlite3_reset(pCsr->pStmt);
+ sqlite3_bind_int64(pCsr->pStmt, 1, fts5CursorRowid(pCsr));
+ rc = sqlite3_step(pCsr->pStmt);
+ if( rc==SQLITE_ROW ){
+ rc = SQLITE_OK;
+ CsrFlagClear(pCsr, FTS5CSR_REQUIRE_CONTENT);
+ }else{
+ rc = sqlite3_reset(pCsr->pStmt);
+ if( rc==SQLITE_OK ){
+ rc = FTS5_CORRUPT;
+ }
+ }
+ }
+ return rc;
+}
+
+static void fts5SetVtabError(Fts5Table *p, const char *zFormat, ...){
+ va_list ap; /* ... printf arguments */
+ va_start(ap, zFormat);
+ assert( p->base.zErrMsg==0 );
+ p->base.zErrMsg = sqlite3_vmprintf(zFormat, ap);
+ va_end(ap);
+}
+
+/*
+** This function is called to handle an FTS INSERT command. In other words,
+** an INSERT statement of the form:
+**
+** INSERT INTO fts(fts) VALUES($pCmd)
+** INSERT INTO fts(fts, rank) VALUES($pCmd, $pVal)
+**
+** Argument pVal is the value assigned to column "fts" by the INSERT
+** statement. This function returns SQLITE_OK if successful, or an SQLite
+** error code if an error occurs.
+**
+** The commands implemented by this function are documented in the "Special
+** INSERT Directives" section of the documentation. It should be updated if
+** more commands are added to this function.
+*/
+static int fts5SpecialInsert(
+ Fts5Table *pTab, /* Fts5 table object */
+ const char *zCmd, /* Text inserted into table-name column */
+ sqlite3_value *pVal /* Value inserted into rank column */
+){
+ Fts5Config *pConfig = pTab->pConfig;
+ int rc = SQLITE_OK;
+ int bError = 0;
+
+ if( 0==sqlite3_stricmp("delete-all", zCmd) ){
+ if( pConfig->eContent==FTS5_CONTENT_NORMAL ){
+ fts5SetVtabError(pTab,
+ "'delete-all' may only be used with a "
+ "contentless or external content fts5 table"
+ );
+ rc = SQLITE_ERROR;
+ }else{
+ rc = sqlite3Fts5StorageDeleteAll(pTab->pStorage);
+ }
+ }else if( 0==sqlite3_stricmp("rebuild", zCmd) ){
+ if( pConfig->eContent==FTS5_CONTENT_NONE ){
+ fts5SetVtabError(pTab,
+ "'rebuild' may not be used with a contentless fts5 table"
+ );
+ rc = SQLITE_ERROR;
+ }else{
+ rc = sqlite3Fts5StorageRebuild(pTab->pStorage);
+ }
+ }else if( 0==sqlite3_stricmp("optimize", zCmd) ){
+ rc = sqlite3Fts5StorageOptimize(pTab->pStorage);
+ }else if( 0==sqlite3_stricmp("merge", zCmd) ){
+ int nMerge = sqlite3_value_int(pVal);
+ rc = sqlite3Fts5StorageMerge(pTab->pStorage, nMerge);
+ }else if( 0==sqlite3_stricmp("integrity-check", zCmd) ){
+ rc = sqlite3Fts5StorageIntegrity(pTab->pStorage);
+#ifdef SQLITE_DEBUG
+ }else if( 0==sqlite3_stricmp("prefix-index", zCmd) ){
+ pConfig->bPrefixIndex = sqlite3_value_int(pVal);
+#endif
+ }else{
+ rc = sqlite3Fts5IndexLoadConfig(pTab->pIndex);
+ if( rc==SQLITE_OK ){
+ rc = sqlite3Fts5ConfigSetValue(pTab->pConfig, zCmd, pVal, &bError);
+ }
+ if( rc==SQLITE_OK ){
+ if( bError ){
+ rc = SQLITE_ERROR;
+ }else{
+ rc = sqlite3Fts5StorageConfigValue(pTab->pStorage, zCmd, pVal, 0);
+ }
+ }
+ }
+ return rc;
+}
+
+static int fts5SpecialDelete(
+ Fts5Table *pTab,
+ sqlite3_value **apVal,
+ sqlite3_int64 *piRowid
+){
+ int rc = SQLITE_OK;
+ int eType1 = sqlite3_value_type(apVal[1]);
+ if( eType1==SQLITE_INTEGER ){
+ sqlite3_int64 iDel = sqlite3_value_int64(apVal[1]);
+ rc = sqlite3Fts5StorageSpecialDelete(pTab->pStorage, iDel, &apVal[2]);
+ }
+ return rc;
+}
+
+static void fts5StorageInsert(
+ int *pRc,
+ Fts5Table *pTab,
+ sqlite3_value **apVal,
+ i64 *piRowid
+){
+ int rc = *pRc;
+ if( rc==SQLITE_OK ){
+ rc = sqlite3Fts5StorageContentInsert(pTab->pStorage, apVal, piRowid);
+ }
+ if( rc==SQLITE_OK ){
+ rc = sqlite3Fts5StorageIndexInsert(pTab->pStorage, apVal, *piRowid);
+ }
+ *pRc = 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.
+**
+** A delete specifies a single argument - the rowid of the row to remove.
+**
+** Update and insert operations pass:
+**
+** 1. The "old" rowid, or NULL.
+** 2. The "new" rowid.
+** 3. Values for each of the nCol matchable columns.
+** 4. Values for the two hidden columns (<tablename> and "rank").
+*/
+static int fts5UpdateMethod(
+ 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 */
+){
+ Fts5Table *pTab = (Fts5Table*)pVtab;
+ Fts5Config *pConfig = pTab->pConfig;
+ int eType0; /* value_type() of apVal[0] */
+ int rc = SQLITE_OK; /* Return code */
+
+ /* A transaction must be open when this is called. */
+ assert( pTab->ts.eState==1 );
+
+ assert( pVtab->zErrMsg==0 );
+ assert( nArg==1 || nArg==(2+pConfig->nCol+2) );
+ assert( nArg==1
+ || sqlite3_value_type(apVal[1])==SQLITE_INTEGER
+ || sqlite3_value_type(apVal[1])==SQLITE_NULL
+ );
+ assert( pTab->pConfig->pzErrmsg==0 );
+ pTab->pConfig->pzErrmsg = &pTab->base.zErrMsg;
+
+ /* Put any active cursors into REQUIRE_SEEK state. */
+ fts5TripCursors(pTab);
+
+ eType0 = sqlite3_value_type(apVal[0]);
+ if( eType0==SQLITE_NULL
+ && sqlite3_value_type(apVal[2+pConfig->nCol])!=SQLITE_NULL
+ ){
+ /* A "special" INSERT op. These are handled separately. */
+ const char *z = (const char*)sqlite3_value_text(apVal[2+pConfig->nCol]);
+ if( pConfig->eContent!=FTS5_CONTENT_NORMAL
+ && 0==sqlite3_stricmp("delete", z)
+ ){
+ rc = fts5SpecialDelete(pTab, apVal, pRowid);
+ }else{
+ rc = fts5SpecialInsert(pTab, z, apVal[2 + pConfig->nCol + 1]);
+ }
+ }else{
+ /* A regular INSERT, UPDATE or DELETE statement. The trick here is that
+ ** any conflict on the rowid value must be detected before any
+ ** modifications are made to the database file. There are 4 cases:
+ **
+ ** 1) DELETE
+ ** 2) UPDATE (rowid not modified)
+ ** 3) UPDATE (rowid modified)
+ ** 4) INSERT
+ **
+ ** Cases 3 and 4 may violate the rowid constraint.
+ */
+ int eConflict = SQLITE_ABORT;
+ if( pConfig->eContent==FTS5_CONTENT_NORMAL ){
+ eConflict = sqlite3_vtab_on_conflict(pConfig->db);
+ }
+
+ assert( eType0==SQLITE_INTEGER || eType0==SQLITE_NULL );
+ assert( nArg!=1 || eType0==SQLITE_INTEGER );
+
+ /* Filter out attempts to run UPDATE or DELETE on contentless tables.
+ ** This is not suported. */
+ if( eType0==SQLITE_INTEGER && fts5IsContentless(pTab) ){
+ pTab->base.zErrMsg = sqlite3_mprintf(
+ "cannot %s contentless fts5 table: %s",
+ (nArg>1 ? "UPDATE" : "DELETE from"), pConfig->zName
+ );
+ rc = SQLITE_ERROR;
+ }
+
+ /* Case 1: DELETE */
+ else if( nArg==1 ){
+ i64 iDel = sqlite3_value_int64(apVal[0]); /* Rowid to delete */
+ rc = sqlite3Fts5StorageDelete(pTab->pStorage, iDel);
+ }
+
+ /* Case 2: INSERT */
+ else if( eType0!=SQLITE_INTEGER ){
+ /* If this is a REPLACE, first remove the current entry (if any) */
+ if( eConflict==SQLITE_REPLACE
+ && sqlite3_value_type(apVal[1])==SQLITE_INTEGER
+ ){
+ i64 iNew = sqlite3_value_int64(apVal[1]); /* Rowid to delete */
+ rc = sqlite3Fts5StorageDelete(pTab->pStorage, iNew);
+ }
+ fts5StorageInsert(&rc, pTab, apVal, pRowid);
+ }
+
+ /* Case 2: UPDATE */
+ else{
+ i64 iOld = sqlite3_value_int64(apVal[0]); /* Old rowid */
+ i64 iNew = sqlite3_value_int64(apVal[1]); /* New rowid */
+ if( iOld!=iNew ){
+ if( eConflict==SQLITE_REPLACE ){
+ rc = sqlite3Fts5StorageDelete(pTab->pStorage, iOld);
+ if( rc==SQLITE_OK ){
+ rc = sqlite3Fts5StorageDelete(pTab->pStorage, iNew);
+ }
+ fts5StorageInsert(&rc, pTab, apVal, pRowid);
+ }else{
+ rc = sqlite3Fts5StorageContentInsert(pTab->pStorage, apVal, pRowid);
+ if( rc==SQLITE_OK ){
+ rc = sqlite3Fts5StorageDelete(pTab->pStorage, iOld);
+ }
+ if( rc==SQLITE_OK ){
+ rc = sqlite3Fts5StorageIndexInsert(pTab->pStorage, apVal, *pRowid);
+ }
+ }
+ }else{
+ rc = sqlite3Fts5StorageDelete(pTab->pStorage, iOld);
+ fts5StorageInsert(&rc, pTab, apVal, pRowid);
+ }
+ }
+ }
+
+ pTab->pConfig->pzErrmsg = 0;
+ return rc;
+}
+
+/*
+** Implementation of xSync() method.
+*/
+static int fts5SyncMethod(sqlite3_vtab *pVtab){
+ int rc;
+ Fts5Table *pTab = (Fts5Table*)pVtab;
+ fts5CheckTransactionState(pTab, FTS5_SYNC, 0);
+ pTab->pConfig->pzErrmsg = &pTab->base.zErrMsg;
+ fts5TripCursors(pTab);
+ rc = sqlite3Fts5StorageSync(pTab->pStorage, 1);
+ pTab->pConfig->pzErrmsg = 0;
+ return rc;
+}
+
+/*
+** Implementation of xBegin() method.
+*/
+static int fts5BeginMethod(sqlite3_vtab *pVtab){
+ fts5CheckTransactionState((Fts5Table*)pVtab, FTS5_BEGIN, 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 fts5SyncMethod().
+*/
+static int fts5CommitMethod(sqlite3_vtab *pVtab){
+ fts5CheckTransactionState((Fts5Table*)pVtab, FTS5_COMMIT, 0);
+ 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 fts5RollbackMethod(sqlite3_vtab *pVtab){
+ int rc;
+ Fts5Table *pTab = (Fts5Table*)pVtab;
+ fts5CheckTransactionState(pTab, FTS5_ROLLBACK, 0);
+ rc = sqlite3Fts5StorageRollback(pTab->pStorage);
+ return rc;
+}
+
+static void *fts5ApiUserData(Fts5Context *pCtx){
+ Fts5Cursor *pCsr = (Fts5Cursor*)pCtx;
+ return pCsr->pAux->pUserData;
+}
+
+static int fts5ApiColumnCount(Fts5Context *pCtx){
+ Fts5Cursor *pCsr = (Fts5Cursor*)pCtx;
+ return ((Fts5Table*)(pCsr->base.pVtab))->pConfig->nCol;
+}
+
+static int fts5ApiColumnTotalSize(
+ Fts5Context *pCtx,
+ int iCol,
+ sqlite3_int64 *pnToken
+){
+ Fts5Cursor *pCsr = (Fts5Cursor*)pCtx;
+ Fts5Table *pTab = (Fts5Table*)(pCsr->base.pVtab);
+ return sqlite3Fts5StorageSize(pTab->pStorage, iCol, pnToken);
+}
+
+static int fts5ApiRowCount(Fts5Context *pCtx, i64 *pnRow){
+ Fts5Cursor *pCsr = (Fts5Cursor*)pCtx;
+ Fts5Table *pTab = (Fts5Table*)(pCsr->base.pVtab);
+ return sqlite3Fts5StorageRowCount(pTab->pStorage, pnRow);
+}
+
+static int fts5ApiTokenize(
+ Fts5Context *pCtx,
+ const char *pText, int nText,
+ void *pUserData,
+ int (*xToken)(void*, int, const char*, int, int, int)
+){
+ Fts5Cursor *pCsr = (Fts5Cursor*)pCtx;
+ Fts5Table *pTab = (Fts5Table*)(pCsr->base.pVtab);
+ return sqlite3Fts5Tokenize(
+ pTab->pConfig, FTS5_TOKENIZE_AUX, pText, nText, pUserData, xToken
+ );
+}
+
+static int fts5ApiPhraseCount(Fts5Context *pCtx){
+ Fts5Cursor *pCsr = (Fts5Cursor*)pCtx;
+ return sqlite3Fts5ExprPhraseCount(pCsr->pExpr);
+}
+
+static int fts5ApiPhraseSize(Fts5Context *pCtx, int iPhrase){
+ Fts5Cursor *pCsr = (Fts5Cursor*)pCtx;
+ return sqlite3Fts5ExprPhraseSize(pCsr->pExpr, iPhrase);
+}
+
+static int fts5CsrPoslist(Fts5Cursor *pCsr, int iPhrase, const u8 **pa){
+ int n;
+ if( pCsr->pSorter ){
+ Fts5Sorter *pSorter = pCsr->pSorter;
+ int i1 = (iPhrase==0 ? 0 : pSorter->aIdx[iPhrase-1]);
+ n = pSorter->aIdx[iPhrase] - i1;
+ *pa = &pSorter->aPoslist[i1];
+ }else{
+ n = sqlite3Fts5ExprPoslist(pCsr->pExpr, iPhrase, pa);
+ }
+ return n;
+}
+
+/*
+** Ensure that the Fts5Cursor.nInstCount and aInst[] variables are populated
+** correctly for the current view. Return SQLITE_OK if successful, or an
+** SQLite error code otherwise.
+*/
+static int fts5CacheInstArray(Fts5Cursor *pCsr){
+ int rc = SQLITE_OK;
+ Fts5PoslistReader *aIter; /* One iterator for each phrase */
+ int nIter; /* Number of iterators/phrases */
+
+ nIter = sqlite3Fts5ExprPhraseCount(pCsr->pExpr);
+ if( pCsr->aInstIter==0 ){
+ int nByte = sizeof(Fts5PoslistReader) * nIter;
+ pCsr->aInstIter = (Fts5PoslistReader*)sqlite3Fts5MallocZero(&rc, nByte);
+ }
+ aIter = pCsr->aInstIter;
+
+ if( aIter ){
+ int nInst = 0; /* Number instances seen so far */
+ int i;
+
+ /* Initialize all iterators */
+ for(i=0; i<nIter; i++){
+ const u8 *a;
+ int n = fts5CsrPoslist(pCsr, i, &a);
+ sqlite3Fts5PoslistReaderInit(a, n, &aIter[i]);
+ }
+
+ while( 1 ){
+ int *aInst;
+ int iBest = -1;
+ for(i=0; i<nIter; i++){
+ if( (aIter[i].bEof==0)
+ && (iBest<0 || aIter[i].iPos<aIter[iBest].iPos)
+ ){
+ iBest = i;
+ }
+ }
+ if( iBest<0 ) break;
+
+ nInst++;
+ if( nInst>=pCsr->nInstAlloc ){
+ pCsr->nInstAlloc = pCsr->nInstAlloc ? pCsr->nInstAlloc*2 : 32;
+ aInst = (int*)sqlite3_realloc(
+ pCsr->aInst, pCsr->nInstAlloc*sizeof(int)*3
+ );
+ if( aInst ){
+ pCsr->aInst = aInst;
+ }else{
+ rc = SQLITE_NOMEM;
+ break;
+ }
+ }
+
+ aInst = &pCsr->aInst[3 * (nInst-1)];
+ aInst[0] = iBest;
+ aInst[1] = FTS5_POS2COLUMN(aIter[iBest].iPos);
+ aInst[2] = FTS5_POS2OFFSET(aIter[iBest].iPos);
+ sqlite3Fts5PoslistReaderNext(&aIter[iBest]);
+ }
+
+ pCsr->nInstCount = nInst;
+ CsrFlagClear(pCsr, FTS5CSR_REQUIRE_INST);
+ }
+ return rc;
+}
+
+static int fts5ApiInstCount(Fts5Context *pCtx, int *pnInst){
+ Fts5Cursor *pCsr = (Fts5Cursor*)pCtx;
+ int rc = SQLITE_OK;
+ if( CsrFlagTest(pCsr, FTS5CSR_REQUIRE_INST)==0
+ || SQLITE_OK==(rc = fts5CacheInstArray(pCsr)) ){
+ *pnInst = pCsr->nInstCount;
+ }
+ return rc;
+}
+
+static int fts5ApiInst(
+ Fts5Context *pCtx,
+ int iIdx,
+ int *piPhrase,
+ int *piCol,
+ int *piOff
+){
+ Fts5Cursor *pCsr = (Fts5Cursor*)pCtx;
+ int rc = SQLITE_OK;
+ if( CsrFlagTest(pCsr, FTS5CSR_REQUIRE_INST)==0
+ || SQLITE_OK==(rc = fts5CacheInstArray(pCsr))
+ ){
+ if( iIdx<0 || iIdx>=pCsr->nInstCount ){
+ rc = SQLITE_RANGE;
+ }else{
+ *piPhrase = pCsr->aInst[iIdx*3];
+ *piCol = pCsr->aInst[iIdx*3 + 1];
+ *piOff = pCsr->aInst[iIdx*3 + 2];
+ }
+ }
+ return rc;
+}
+
+static sqlite3_int64 fts5ApiRowid(Fts5Context *pCtx){
+ return fts5CursorRowid((Fts5Cursor*)pCtx);
+}
+
+static int fts5ApiColumnText(
+ Fts5Context *pCtx,
+ int iCol,
+ const char **pz,
+ int *pn
+){
+ int rc = SQLITE_OK;
+ Fts5Cursor *pCsr = (Fts5Cursor*)pCtx;
+ if( fts5IsContentless((Fts5Table*)(pCsr->base.pVtab)) ){
+ *pz = 0;
+ *pn = 0;
+ }else{
+ rc = fts5SeekCursor(pCsr, 0);
+ if( rc==SQLITE_OK ){
+ *pz = (const char*)sqlite3_column_text(pCsr->pStmt, iCol+1);
+ *pn = sqlite3_column_bytes(pCsr->pStmt, iCol+1);
+ }
+ }
+ return rc;
+}
+
+static int fts5ColumnSizeCb(
+ void *pContext, /* Pointer to int */
+ int tflags,
+ const char *pToken, /* Buffer containing token */
+ int nToken, /* Size of token in bytes */
+ int iStart, /* Start offset of token */
+ int iEnd /* End offset of token */
+){
+ int *pCnt = (int*)pContext;
+ if( (tflags & FTS5_TOKEN_COLOCATED)==0 ){
+ (*pCnt)++;
+ }
+ return SQLITE_OK;
+}
+
+static int fts5ApiColumnSize(Fts5Context *pCtx, int iCol, int *pnToken){
+ Fts5Cursor *pCsr = (Fts5Cursor*)pCtx;
+ Fts5Table *pTab = (Fts5Table*)(pCsr->base.pVtab);
+ Fts5Config *pConfig = pTab->pConfig;
+ int rc = SQLITE_OK;
+
+ if( CsrFlagTest(pCsr, FTS5CSR_REQUIRE_DOCSIZE) ){
+ if( pConfig->bColumnsize ){
+ i64 iRowid = fts5CursorRowid(pCsr);
+ rc = sqlite3Fts5StorageDocsize(pTab->pStorage, iRowid, pCsr->aColumnSize);
+ }else if( pConfig->zContent==0 ){
+ int i;
+ for(i=0; i<pConfig->nCol; i++){
+ if( pConfig->abUnindexed[i]==0 ){
+ pCsr->aColumnSize[i] = -1;
+ }
+ }
+ }else{
+ int i;
+ for(i=0; rc==SQLITE_OK && i<pConfig->nCol; i++){
+ if( pConfig->abUnindexed[i]==0 ){
+ const char *z; int n;
+ void *p = (void*)(&pCsr->aColumnSize[i]);
+ pCsr->aColumnSize[i] = 0;
+ rc = fts5ApiColumnText(pCtx, i, &z, &n);
+ if( rc==SQLITE_OK ){
+ rc = sqlite3Fts5Tokenize(
+ pConfig, FTS5_TOKENIZE_AUX, z, n, p, fts5ColumnSizeCb
+ );
+ }
+ }
+ }
+ }
+ CsrFlagClear(pCsr, FTS5CSR_REQUIRE_DOCSIZE);
+ }
+ if( iCol<0 ){
+ int i;
+ *pnToken = 0;
+ for(i=0; i<pConfig->nCol; i++){
+ *pnToken += pCsr->aColumnSize[i];
+ }
+ }else if( iCol<pConfig->nCol ){
+ *pnToken = pCsr->aColumnSize[iCol];
+ }else{
+ *pnToken = 0;
+ rc = SQLITE_RANGE;
+ }
+ return rc;
+}
+
+/*
+** Implementation of the xSetAuxdata() method.
+*/
+static int fts5ApiSetAuxdata(
+ Fts5Context *pCtx, /* Fts5 context */
+ void *pPtr, /* Pointer to save as auxdata */
+ void(*xDelete)(void*) /* Destructor for pPtr (or NULL) */
+){
+ Fts5Cursor *pCsr = (Fts5Cursor*)pCtx;
+ Fts5Auxdata *pData;
+
+ /* Search through the cursors list of Fts5Auxdata objects for one that
+ ** corresponds to the currently executing auxiliary function. */
+ for(pData=pCsr->pAuxdata; pData; pData=pData->pNext){
+ if( pData->pAux==pCsr->pAux ) break;
+ }
+
+ if( pData ){
+ if( pData->xDelete ){
+ pData->xDelete(pData->pPtr);
+ }
+ }else{
+ int rc = SQLITE_OK;
+ pData = (Fts5Auxdata*)sqlite3Fts5MallocZero(&rc, sizeof(Fts5Auxdata));
+ if( pData==0 ){
+ if( xDelete ) xDelete(pPtr);
+ return rc;
+ }
+ pData->pAux = pCsr->pAux;
+ pData->pNext = pCsr->pAuxdata;
+ pCsr->pAuxdata = pData;
+ }
+
+ pData->xDelete = xDelete;
+ pData->pPtr = pPtr;
+ return SQLITE_OK;
+}
+
+static void *fts5ApiGetAuxdata(Fts5Context *pCtx, int bClear){
+ Fts5Cursor *pCsr = (Fts5Cursor*)pCtx;
+ Fts5Auxdata *pData;
+ void *pRet = 0;
+
+ for(pData=pCsr->pAuxdata; pData; pData=pData->pNext){
+ if( pData->pAux==pCsr->pAux ) break;
+ }
+
+ if( pData ){
+ pRet = pData->pPtr;
+ if( bClear ){
+ pData->pPtr = 0;
+ pData->xDelete = 0;
+ }
+ }
+
+ return pRet;
+}
+
+static void fts5ApiPhraseNext(
+ Fts5Context *pCtx,
+ Fts5PhraseIter *pIter,
+ int *piCol, int *piOff
+){
+ if( pIter->a>=pIter->b ){
+ *piCol = -1;
+ *piOff = -1;
+ }else{
+ int iVal;
+ pIter->a += fts5GetVarint32(pIter->a, iVal);
+ if( iVal==1 ){
+ pIter->a += fts5GetVarint32(pIter->a, iVal);
+ *piCol = iVal;
+ *piOff = 0;
+ pIter->a += fts5GetVarint32(pIter->a, iVal);
+ }
+ *piOff += (iVal-2);
+ }
+}
+
+static void fts5ApiPhraseFirst(
+ Fts5Context *pCtx,
+ int iPhrase,
+ Fts5PhraseIter *pIter,
+ int *piCol, int *piOff
+){
+ Fts5Cursor *pCsr = (Fts5Cursor*)pCtx;
+ int n = fts5CsrPoslist(pCsr, iPhrase, &pIter->a);
+ pIter->b = &pIter->a[n];
+ *piCol = 0;
+ *piOff = 0;
+ fts5ApiPhraseNext(pCtx, pIter, piCol, piOff);
+}
+
+static int fts5ApiQueryPhrase(Fts5Context*, int, void*,
+ int(*)(const Fts5ExtensionApi*, Fts5Context*, void*)
+);
+
+static const Fts5ExtensionApi sFts5Api = {
+ 2, /* iVersion */
+ fts5ApiUserData,
+ fts5ApiColumnCount,
+ fts5ApiRowCount,
+ fts5ApiColumnTotalSize,
+ fts5ApiTokenize,
+ fts5ApiPhraseCount,
+ fts5ApiPhraseSize,
+ fts5ApiInstCount,
+ fts5ApiInst,
+ fts5ApiRowid,
+ fts5ApiColumnText,
+ fts5ApiColumnSize,
+ fts5ApiQueryPhrase,
+ fts5ApiSetAuxdata,
+ fts5ApiGetAuxdata,
+ fts5ApiPhraseFirst,
+ fts5ApiPhraseNext,
+};
+
+
+/*
+** Implementation of API function xQueryPhrase().
+*/
+static int fts5ApiQueryPhrase(
+ Fts5Context *pCtx,
+ int iPhrase,
+ void *pUserData,
+ int(*xCallback)(const Fts5ExtensionApi*, Fts5Context*, void*)
+){
+ Fts5Cursor *pCsr = (Fts5Cursor*)pCtx;
+ Fts5Table *pTab = (Fts5Table*)(pCsr->base.pVtab);
+ int rc;
+ Fts5Cursor *pNew = 0;
+
+ rc = fts5OpenMethod(pCsr->base.pVtab, (sqlite3_vtab_cursor**)&pNew);
+ if( rc==SQLITE_OK ){
+ Fts5Config *pConf = pTab->pConfig;
+ pNew->ePlan = FTS5_PLAN_MATCH;
+ pNew->iFirstRowid = SMALLEST_INT64;
+ pNew->iLastRowid = LARGEST_INT64;
+ pNew->base.pVtab = (sqlite3_vtab*)pTab;
+ rc = sqlite3Fts5ExprClonePhrase(pConf, pCsr->pExpr, iPhrase, &pNew->pExpr);
+ }
+
+ if( rc==SQLITE_OK ){
+ for(rc = fts5CursorFirst(pTab, pNew, 0);
+ rc==SQLITE_OK && CsrFlagTest(pNew, FTS5CSR_EOF)==0;
+ rc = fts5NextMethod((sqlite3_vtab_cursor*)pNew)
+ ){
+ rc = xCallback(&sFts5Api, (Fts5Context*)pNew, pUserData);
+ if( rc!=SQLITE_OK ){
+ if( rc==SQLITE_DONE ) rc = SQLITE_OK;
+ break;
+ }
+ }
+ }
+
+ fts5CloseMethod((sqlite3_vtab_cursor*)pNew);
+ return rc;
+}
+
+static void fts5ApiInvoke(
+ Fts5Auxiliary *pAux,
+ Fts5Cursor *pCsr,
+ sqlite3_context *context,
+ int argc,
+ sqlite3_value **argv
+){
+ assert( pCsr->pAux==0 );
+ pCsr->pAux = pAux;
+ pAux->xFunc(&sFts5Api, (Fts5Context*)pCsr, context, argc, argv);
+ pCsr->pAux = 0;
+}
+
+static Fts5Cursor *fts5CursorFromCsrid(Fts5Global *pGlobal, i64 iCsrId){
+ Fts5Cursor *pCsr;
+ for(pCsr=pGlobal->pCsr; pCsr; pCsr=pCsr->pNext){
+ if( pCsr->iCsrId==iCsrId ) break;
+ }
+ return pCsr;
+}
+
+static void fts5ApiCallback(
+ sqlite3_context *context,
+ int argc,
+ sqlite3_value **argv
+){
+
+ Fts5Auxiliary *pAux;
+ Fts5Cursor *pCsr;
+ i64 iCsrId;
+
+ assert( argc>=1 );
+ pAux = (Fts5Auxiliary*)sqlite3_user_data(context);
+ iCsrId = sqlite3_value_int64(argv[0]);
+
+ pCsr = fts5CursorFromCsrid(pAux->pGlobal, iCsrId);
+ if( pCsr==0 ){
+ char *zErr = sqlite3_mprintf("no such cursor: %lld", iCsrId);
+ sqlite3_result_error(context, zErr, -1);
+ sqlite3_free(zErr);
+ }else{
+ fts5ApiInvoke(pAux, pCsr, context, argc-1, &argv[1]);
+ }
+}
+
+
+/*
+** Given cursor id iId, return a pointer to the corresponding Fts5Index
+** object. Or NULL If the cursor id does not exist.
+**
+** If successful, set *ppConfig to point to the associated config object
+** before returning.
+*/
+static Fts5Index *sqlite3Fts5IndexFromCsrid(
+ Fts5Global *pGlobal, /* FTS5 global context for db handle */
+ i64 iCsrId, /* Id of cursor to find */
+ Fts5Config **ppConfig /* OUT: Configuration object */
+){
+ Fts5Cursor *pCsr;
+ Fts5Table *pTab;
+
+ pCsr = fts5CursorFromCsrid(pGlobal, iCsrId);
+ pTab = (Fts5Table*)pCsr->base.pVtab;
+ *ppConfig = pTab->pConfig;
+
+ return pTab->pIndex;
+}
+
+/*
+** Return a "position-list blob" corresponding to the current position of
+** cursor pCsr via sqlite3_result_blob(). A position-list blob contains
+** the current position-list for each phrase in the query associated with
+** cursor pCsr.
+**
+** A position-list blob begins with (nPhrase-1) varints, where nPhrase is
+** the number of phrases in the query. Following the varints are the
+** concatenated position lists for each phrase, in order.
+**
+** The first varint (if it exists) contains the size of the position list
+** for phrase 0. The second (same disclaimer) contains the size of position
+** list 1. And so on. There is no size field for the final position list,
+** as it can be derived from the total size of the blob.
+*/
+static int fts5PoslistBlob(sqlite3_context *pCtx, Fts5Cursor *pCsr){
+ int i;
+ int rc = SQLITE_OK;
+ int nPhrase = sqlite3Fts5ExprPhraseCount(pCsr->pExpr);
+ Fts5Buffer val;
+
+ memset(&val, 0, sizeof(Fts5Buffer));
+
+ /* Append the varints */
+ for(i=0; i<(nPhrase-1); i++){
+ const u8 *dummy;
+ int nByte = sqlite3Fts5ExprPoslist(pCsr->pExpr, i, &dummy);
+ sqlite3Fts5BufferAppendVarint(&rc, &val, nByte);
+ }
+
+ /* Append the position lists */
+ for(i=0; i<nPhrase; i++){
+ const u8 *pPoslist;
+ int nPoslist;
+ nPoslist = sqlite3Fts5ExprPoslist(pCsr->pExpr, i, &pPoslist);
+ sqlite3Fts5BufferAppendBlob(&rc, &val, nPoslist, pPoslist);
+ }
+
+ sqlite3_result_blob(pCtx, val.p, val.n, sqlite3_free);
+ return rc;
+}
+
+/*
+** This is the xColumn method, called by SQLite to request a value from
+** the row that the supplied cursor currently points to.
+*/
+static int fts5ColumnMethod(
+ 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 */
+){
+ Fts5Table *pTab = (Fts5Table*)(pCursor->pVtab);
+ Fts5Config *pConfig = pTab->pConfig;
+ Fts5Cursor *pCsr = (Fts5Cursor*)pCursor;
+ int rc = SQLITE_OK;
+
+ assert( CsrFlagTest(pCsr, FTS5CSR_EOF)==0 );
+
+ if( pCsr->ePlan==FTS5_PLAN_SPECIAL ){
+ if( iCol==pConfig->nCol ){
+ sqlite3_result_int64(pCtx, pCsr->iSpecial);
+ }
+ }else
+
+ if( iCol==pConfig->nCol ){
+ /* User is requesting the value of the special column with the same name
+ ** as the table. Return the cursor integer id number. This value is only
+ ** useful in that it may be passed as the first argument to an FTS5
+ ** auxiliary function. */
+ sqlite3_result_int64(pCtx, pCsr->iCsrId);
+ }else if( iCol==pConfig->nCol+1 ){
+
+ /* The value of the "rank" column. */
+ if( pCsr->ePlan==FTS5_PLAN_SOURCE ){
+ fts5PoslistBlob(pCtx, pCsr);
+ }else if(
+ pCsr->ePlan==FTS5_PLAN_MATCH
+ || pCsr->ePlan==FTS5_PLAN_SORTED_MATCH
+ ){
+ if( pCsr->pRank || SQLITE_OK==(rc = fts5FindRankFunction(pCsr)) ){
+ fts5ApiInvoke(pCsr->pRank, pCsr, pCtx, pCsr->nRankArg, pCsr->apRankArg);
+ }
+ }
+ }else if( !fts5IsContentless(pTab) ){
+ rc = fts5SeekCursor(pCsr, 1);
+ if( rc==SQLITE_OK ){
+ sqlite3_result_value(pCtx, sqlite3_column_value(pCsr->pStmt, iCol+1));
+ }
+ }
+ return rc;
+}
+
+
+/*
+** This routine implements the xFindFunction method for the FTS3
+** virtual table.
+*/
+static int fts5FindFunctionMethod(
+ 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 /* OUT: User data for *pxFunc */
+){
+ Fts5Table *pTab = (Fts5Table*)pVtab;
+ Fts5Auxiliary *pAux;
+
+ pAux = fts5FindAuxiliary(pTab, zName);
+ if( pAux ){
+ *pxFunc = fts5ApiCallback;
+ *ppArg = (void*)pAux;
+ return 1;
+ }
+
+ /* No function of the specified name was found. Return 0. */
+ return 0;
+}
+
+/*
+** Implementation of FTS5 xRename method. Rename an fts5 table.
+*/
+static int fts5RenameMethod(
+ sqlite3_vtab *pVtab, /* Virtual table handle */
+ const char *zName /* New name of table */
+){
+ Fts5Table *pTab = (Fts5Table*)pVtab;
+ return sqlite3Fts5StorageRename(pTab->pStorage, zName);
+}
+
+/*
+** The xSavepoint() method.
+**
+** Flush the contents of the pending-terms table to disk.
+*/
+static int fts5SavepointMethod(sqlite3_vtab *pVtab, int iSavepoint){
+ Fts5Table *pTab = (Fts5Table*)pVtab;
+ fts5CheckTransactionState(pTab, FTS5_SAVEPOINT, iSavepoint);
+ fts5TripCursors(pTab);
+ return sqlite3Fts5StorageSync(pTab->pStorage, 0);
+}
+
+/*
+** The xRelease() method.
+**
+** This is a no-op.
+*/
+static int fts5ReleaseMethod(sqlite3_vtab *pVtab, int iSavepoint){
+ Fts5Table *pTab = (Fts5Table*)pVtab;
+ fts5CheckTransactionState(pTab, FTS5_RELEASE, iSavepoint);
+ fts5TripCursors(pTab);
+ return sqlite3Fts5StorageSync(pTab->pStorage, 0);
+}
+
+/*
+** The xRollbackTo() method.
+**
+** Discard the contents of the pending terms table.
+*/
+static int fts5RollbackToMethod(sqlite3_vtab *pVtab, int iSavepoint){
+ Fts5Table *pTab = (Fts5Table*)pVtab;
+ fts5CheckTransactionState(pTab, FTS5_ROLLBACKTO, iSavepoint);
+ fts5TripCursors(pTab);
+ return sqlite3Fts5StorageRollback(pTab->pStorage);
+}
+
+/*
+** Register a new auxiliary function with global context pGlobal.
+*/
+static int fts5CreateAux(
+ fts5_api *pApi, /* Global context (one per db handle) */
+ const char *zName, /* Name of new function */
+ void *pUserData, /* User data for aux. function */
+ fts5_extension_function xFunc, /* Aux. function implementation */
+ void(*xDestroy)(void*) /* Destructor for pUserData */
+){
+ Fts5Global *pGlobal = (Fts5Global*)pApi;
+ int rc = sqlite3_overload_function(pGlobal->db, zName, -1);
+ if( rc==SQLITE_OK ){
+ Fts5Auxiliary *pAux;
+ int nName; /* Size of zName in bytes, including \0 */
+ int nByte; /* Bytes of space to allocate */
+
+ nName = (int)strlen(zName) + 1;
+ nByte = sizeof(Fts5Auxiliary) + nName;
+ pAux = (Fts5Auxiliary*)sqlite3_malloc(nByte);
+ if( pAux ){
+ memset(pAux, 0, nByte);
+ pAux->zFunc = (char*)&pAux[1];
+ memcpy(pAux->zFunc, zName, nName);
+ pAux->pGlobal = pGlobal;
+ pAux->pUserData = pUserData;
+ pAux->xFunc = xFunc;
+ pAux->xDestroy = xDestroy;
+ pAux->pNext = pGlobal->pAux;
+ pGlobal->pAux = pAux;
+ }else{
+ rc = SQLITE_NOMEM;
+ }
+ }
+
+ return rc;
+}
+
+/*
+** Register a new tokenizer. This is the implementation of the
+** fts5_api.xCreateTokenizer() method.
+*/
+static int fts5CreateTokenizer(
+ fts5_api *pApi, /* Global context (one per db handle) */
+ const char *zName, /* Name of new function */
+ void *pUserData, /* User data for aux. function */
+ fts5_tokenizer *pTokenizer, /* Tokenizer implementation */
+ void(*xDestroy)(void*) /* Destructor for pUserData */
+){
+ Fts5Global *pGlobal = (Fts5Global*)pApi;
+ Fts5TokenizerModule *pNew;
+ int nName; /* Size of zName and its \0 terminator */
+ int nByte; /* Bytes of space to allocate */
+ int rc = SQLITE_OK;
+
+ nName = (int)strlen(zName) + 1;
+ nByte = sizeof(Fts5TokenizerModule) + nName;
+ pNew = (Fts5TokenizerModule*)sqlite3_malloc(nByte);
+ if( pNew ){
+ memset(pNew, 0, nByte);
+ pNew->zName = (char*)&pNew[1];
+ memcpy(pNew->zName, zName, nName);
+ pNew->pUserData = pUserData;
+ pNew->x = *pTokenizer;
+ pNew->xDestroy = xDestroy;
+ pNew->pNext = pGlobal->pTok;
+ pGlobal->pTok = pNew;
+ if( pNew->pNext==0 ){
+ pGlobal->pDfltTok = pNew;
+ }
+ }else{
+ rc = SQLITE_NOMEM;
+ }
+
+ return rc;
+}
+
+static Fts5TokenizerModule *fts5LocateTokenizer(
+ Fts5Global *pGlobal,
+ const char *zName
+){
+ Fts5TokenizerModule *pMod = 0;
+
+ if( zName==0 ){
+ pMod = pGlobal->pDfltTok;
+ }else{
+ for(pMod=pGlobal->pTok; pMod; pMod=pMod->pNext){
+ if( sqlite3_stricmp(zName, pMod->zName)==0 ) break;
+ }
+ }
+
+ return pMod;
+}
+
+/*
+** Find a tokenizer. This is the implementation of the
+** fts5_api.xFindTokenizer() method.
+*/
+static int fts5FindTokenizer(
+ fts5_api *pApi, /* Global context (one per db handle) */
+ const char *zName, /* Name of new function */
+ void **ppUserData,
+ fts5_tokenizer *pTokenizer /* Populate this object */
+){
+ int rc = SQLITE_OK;
+ Fts5TokenizerModule *pMod;
+
+ pMod = fts5LocateTokenizer((Fts5Global*)pApi, zName);
+ if( pMod ){
+ *pTokenizer = pMod->x;
+ *ppUserData = pMod->pUserData;
+ }else{
+ memset(pTokenizer, 0, sizeof(fts5_tokenizer));
+ rc = SQLITE_ERROR;
+ }
+
+ return rc;
+}
+
+static int sqlite3Fts5GetTokenizer(
+ Fts5Global *pGlobal,
+ const char **azArg,
+ int nArg,
+ Fts5Tokenizer **ppTok,
+ fts5_tokenizer **ppTokApi,
+ char **pzErr
+){
+ Fts5TokenizerModule *pMod;
+ int rc = SQLITE_OK;
+
+ pMod = fts5LocateTokenizer(pGlobal, nArg==0 ? 0 : azArg[0]);
+ if( pMod==0 ){
+ assert( nArg>0 );
+ rc = SQLITE_ERROR;
+ *pzErr = sqlite3_mprintf("no such tokenizer: %s", azArg[0]);
+ }else{
+ rc = pMod->x.xCreate(pMod->pUserData, &azArg[1], (nArg?nArg-1:0), ppTok);
+ *ppTokApi = &pMod->x;
+ if( rc!=SQLITE_OK && pzErr ){
+ *pzErr = sqlite3_mprintf("error in tokenizer constructor");
+ }
+ }
+
+ if( rc!=SQLITE_OK ){
+ *ppTokApi = 0;
+ *ppTok = 0;
+ }
+
+ return rc;
+}
+
+static void fts5ModuleDestroy(void *pCtx){
+ Fts5TokenizerModule *pTok, *pNextTok;
+ Fts5Auxiliary *pAux, *pNextAux;
+ Fts5Global *pGlobal = (Fts5Global*)pCtx;
+
+ for(pAux=pGlobal->pAux; pAux; pAux=pNextAux){
+ pNextAux = pAux->pNext;
+ if( pAux->xDestroy ) pAux->xDestroy(pAux->pUserData);
+ sqlite3_free(pAux);
+ }
+
+ for(pTok=pGlobal->pTok; pTok; pTok=pNextTok){
+ pNextTok = pTok->pNext;
+ if( pTok->xDestroy ) pTok->xDestroy(pTok->pUserData);
+ sqlite3_free(pTok);
+ }
+
+ sqlite3_free(pGlobal);
+}
+
+static void fts5Fts5Func(
+ sqlite3_context *pCtx, /* Function call context */
+ int nArg, /* Number of args */
+ sqlite3_value **apVal /* Function arguments */
+){
+ Fts5Global *pGlobal = (Fts5Global*)sqlite3_user_data(pCtx);
+ char buf[8];
+ assert( nArg==0 );
+ assert( sizeof(buf)>=sizeof(pGlobal) );
+ memcpy(buf, (void*)&pGlobal, sizeof(pGlobal));
+ sqlite3_result_blob(pCtx, buf, sizeof(pGlobal), SQLITE_TRANSIENT);
+}
+
+/*
+** Implementation of fts5_source_id() function.
+*/
+static void fts5SourceIdFunc(
+ sqlite3_context *pCtx, /* Function call context */
+ int nArg, /* Number of args */
+ sqlite3_value **apVal /* Function arguments */
+){
+ assert( nArg==0 );
+ sqlite3_result_text(pCtx, "fts5: 2016-01-20 15:27:19 17efb4209f97fb4971656086b138599a91a75ff9", -1, SQLITE_TRANSIENT);
+}
+
+static int fts5Init(sqlite3 *db){
+ static const sqlite3_module fts5Mod = {
+ /* iVersion */ 2,
+ /* xCreate */ fts5CreateMethod,
+ /* xConnect */ fts5ConnectMethod,
+ /* xBestIndex */ fts5BestIndexMethod,
+ /* xDisconnect */ fts5DisconnectMethod,
+ /* xDestroy */ fts5DestroyMethod,
+ /* xOpen */ fts5OpenMethod,
+ /* xClose */ fts5CloseMethod,
+ /* xFilter */ fts5FilterMethod,
+ /* xNext */ fts5NextMethod,
+ /* xEof */ fts5EofMethod,
+ /* xColumn */ fts5ColumnMethod,
+ /* xRowid */ fts5RowidMethod,
+ /* xUpdate */ fts5UpdateMethod,
+ /* xBegin */ fts5BeginMethod,
+ /* xSync */ fts5SyncMethod,
+ /* xCommit */ fts5CommitMethod,
+ /* xRollback */ fts5RollbackMethod,
+ /* xFindFunction */ fts5FindFunctionMethod,
+ /* xRename */ fts5RenameMethod,
+ /* xSavepoint */ fts5SavepointMethod,
+ /* xRelease */ fts5ReleaseMethod,
+ /* xRollbackTo */ fts5RollbackToMethod,
+ };
+
+ int rc;
+ Fts5Global *pGlobal = 0;
+
+ pGlobal = (Fts5Global*)sqlite3_malloc(sizeof(Fts5Global));
+ if( pGlobal==0 ){
+ rc = SQLITE_NOMEM;
+ }else{
+ void *p = (void*)pGlobal;
+ memset(pGlobal, 0, sizeof(Fts5Global));
+ pGlobal->db = db;
+ pGlobal->api.iVersion = 2;
+ pGlobal->api.xCreateFunction = fts5CreateAux;
+ pGlobal->api.xCreateTokenizer = fts5CreateTokenizer;
+ pGlobal->api.xFindTokenizer = fts5FindTokenizer;
+ rc = sqlite3_create_module_v2(db, "fts5", &fts5Mod, p, fts5ModuleDestroy);
+ if( rc==SQLITE_OK ) rc = sqlite3Fts5IndexInit(db);
+ if( rc==SQLITE_OK ) rc = sqlite3Fts5ExprInit(pGlobal, db);
+ if( rc==SQLITE_OK ) rc = sqlite3Fts5AuxInit(&pGlobal->api);
+ if( rc==SQLITE_OK ) rc = sqlite3Fts5TokenizerInit(&pGlobal->api);
+ if( rc==SQLITE_OK ) rc = sqlite3Fts5VocabInit(pGlobal, db);
+ if( rc==SQLITE_OK ){
+ rc = sqlite3_create_function(
+ db, "fts5", 0, SQLITE_UTF8, p, fts5Fts5Func, 0, 0
+ );
+ }
+ if( rc==SQLITE_OK ){
+ rc = sqlite3_create_function(
+ db, "fts5_source_id", 0, SQLITE_UTF8, p, fts5SourceIdFunc, 0, 0
+ );
+ }
+ }
+ return rc;
+}
+
+/*
+** The following functions are used to register the module with SQLite. If
+** this module is being built as part of the SQLite core (SQLITE_CORE is
+** defined), then sqlite3_open() will call sqlite3Fts5Init() directly.
+**
+** Or, if this module is being built as a loadable extension,
+** sqlite3Fts5Init() is omitted and the two standard entry points
+** sqlite3_fts_init() and sqlite3_fts5_init() defined instead.
+*/
+#ifndef SQLITE_CORE
+#ifdef _WIN32
+__declspec(dllexport)
+#endif
+SQLITE_API int SQLITE_STDCALL sqlite3_fts_init(
+ sqlite3 *db,
+ char **pzErrMsg,
+ const sqlite3_api_routines *pApi
+){
+ SQLITE_EXTENSION_INIT2(pApi);
+ (void)pzErrMsg; /* Unused parameter */
+ return fts5Init(db);
+}
+
+#ifdef _WIN32
+__declspec(dllexport)
+#endif
+SQLITE_API int SQLITE_STDCALL sqlite3_fts5_init(
+ sqlite3 *db,
+ char **pzErrMsg,
+ const sqlite3_api_routines *pApi
+){
+ SQLITE_EXTENSION_INIT2(pApi);
+ (void)pzErrMsg; /* Unused parameter */
+ return fts5Init(db);
+}
+#else
+SQLITE_PRIVATE int sqlite3Fts5Init(sqlite3 *db){
+ return fts5Init(db);
+}
+#endif
+
+/*
+** 2014 May 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.
+**
+******************************************************************************
+**
+*/
+
+
+
+/* #include "fts5Int.h" */
+
+struct Fts5Storage {
+ Fts5Config *pConfig;
+ Fts5Index *pIndex;
+ int bTotalsValid; /* True if nTotalRow/aTotalSize[] are valid */
+ i64 nTotalRow; /* Total number of rows in FTS table */
+ i64 *aTotalSize; /* Total sizes of each column */
+ sqlite3_stmt *aStmt[11];
+};
+
+
+#if FTS5_STMT_SCAN_ASC!=0
+# error "FTS5_STMT_SCAN_ASC mismatch"
+#endif
+#if FTS5_STMT_SCAN_DESC!=1
+# error "FTS5_STMT_SCAN_DESC mismatch"
+#endif
+#if FTS5_STMT_LOOKUP!=2
+# error "FTS5_STMT_LOOKUP mismatch"
+#endif
+
+#define FTS5_STMT_INSERT_CONTENT 3
+#define FTS5_STMT_REPLACE_CONTENT 4
+#define FTS5_STMT_DELETE_CONTENT 5
+#define FTS5_STMT_REPLACE_DOCSIZE 6
+#define FTS5_STMT_DELETE_DOCSIZE 7
+#define FTS5_STMT_LOOKUP_DOCSIZE 8
+#define FTS5_STMT_REPLACE_CONFIG 9
+#define FTS5_STMT_SCAN 10
+
+/*
+** Prepare the two insert statements - Fts5Storage.pInsertContent and
+** Fts5Storage.pInsertDocsize - if they have not already been prepared.
+** Return SQLITE_OK if successful, or an SQLite error code if an error
+** occurs.
+*/
+static int fts5StorageGetStmt(
+ Fts5Storage *p, /* Storage handle */
+ int eStmt, /* FTS5_STMT_XXX constant */
+ sqlite3_stmt **ppStmt, /* OUT: Prepared statement handle */
+ char **pzErrMsg /* OUT: Error message (if any) */
+){
+ int rc = SQLITE_OK;
+
+ /* If there is no %_docsize table, there should be no requests for
+ ** statements to operate on it. */
+ assert( p->pConfig->bColumnsize || (
+ eStmt!=FTS5_STMT_REPLACE_DOCSIZE
+ && eStmt!=FTS5_STMT_DELETE_DOCSIZE
+ && eStmt!=FTS5_STMT_LOOKUP_DOCSIZE
+ ));
+
+ assert( eStmt>=0 && eStmt<ArraySize(p->aStmt) );
+ if( p->aStmt[eStmt]==0 ){
+ const char *azStmt[] = {
+ "SELECT %s FROM %s T WHERE T.%Q >= ? AND T.%Q <= ? ORDER BY T.%Q ASC",
+ "SELECT %s FROM %s T WHERE T.%Q <= ? AND T.%Q >= ? ORDER BY T.%Q DESC",
+ "SELECT %s FROM %s T WHERE T.%Q=?", /* LOOKUP */
+
+ "INSERT INTO %Q.'%q_content' VALUES(%s)", /* INSERT_CONTENT */
+ "REPLACE INTO %Q.'%q_content' VALUES(%s)", /* REPLACE_CONTENT */
+ "DELETE FROM %Q.'%q_content' WHERE id=?", /* DELETE_CONTENT */
+ "REPLACE INTO %Q.'%q_docsize' VALUES(?,?)", /* REPLACE_DOCSIZE */
+ "DELETE FROM %Q.'%q_docsize' WHERE id=?", /* DELETE_DOCSIZE */
+
+ "SELECT sz FROM %Q.'%q_docsize' WHERE id=?", /* LOOKUP_DOCSIZE */
+
+ "REPLACE INTO %Q.'%q_config' VALUES(?,?)", /* REPLACE_CONFIG */
+ "SELECT %s FROM %s AS T", /* SCAN */
+ };
+ Fts5Config *pC = p->pConfig;
+ char *zSql = 0;
+
+ switch( eStmt ){
+ case FTS5_STMT_SCAN:
+ zSql = sqlite3_mprintf(azStmt[eStmt],
+ pC->zContentExprlist, pC->zContent
+ );
+ break;
+
+ case FTS5_STMT_SCAN_ASC:
+ case FTS5_STMT_SCAN_DESC:
+ zSql = sqlite3_mprintf(azStmt[eStmt], pC->zContentExprlist,
+ pC->zContent, pC->zContentRowid, pC->zContentRowid,
+ pC->zContentRowid
+ );
+ break;
+
+ case FTS5_STMT_LOOKUP:
+ zSql = sqlite3_mprintf(azStmt[eStmt],
+ pC->zContentExprlist, pC->zContent, pC->zContentRowid
+ );
+ break;
+
+ case FTS5_STMT_INSERT_CONTENT:
+ case FTS5_STMT_REPLACE_CONTENT: {
+ int nCol = pC->nCol + 1;
+ char *zBind;
+ int i;
+
+ zBind = sqlite3_malloc(1 + nCol*2);
+ if( zBind ){
+ for(i=0; i<nCol; i++){
+ zBind[i*2] = '?';
+ zBind[i*2 + 1] = ',';
+ }
+ zBind[i*2-1] = '\0';
+ zSql = sqlite3_mprintf(azStmt[eStmt], pC->zDb, pC->zName, zBind);
+ sqlite3_free(zBind);
+ }
+ break;
+ }
+
+ default:
+ zSql = sqlite3_mprintf(azStmt[eStmt], pC->zDb, pC->zName);
+ break;
+ }
+
+ if( zSql==0 ){
+ rc = SQLITE_NOMEM;
+ }else{
+ rc = sqlite3_prepare_v2(pC->db, zSql, -1, &p->aStmt[eStmt], 0);
+ sqlite3_free(zSql);
+ if( rc!=SQLITE_OK && pzErrMsg ){
+ *pzErrMsg = sqlite3_mprintf("%s", sqlite3_errmsg(pC->db));
+ }
+ }
+ }
+
+ *ppStmt = p->aStmt[eStmt];
+ return rc;
+}
+
+
+static int fts5ExecPrintf(
+ sqlite3 *db,
+ char **pzErr,
+ const char *zFormat,
+ ...
+){
+ int rc;
+ va_list ap; /* ... printf arguments */
+ char *zSql;
+
+ va_start(ap, zFormat);
+ zSql = sqlite3_vmprintf(zFormat, ap);
+
+ if( zSql==0 ){
+ rc = SQLITE_NOMEM;
+ }else{
+ rc = sqlite3_exec(db, zSql, 0, 0, pzErr);
+ sqlite3_free(zSql);
+ }
+
+ va_end(ap);
+ return rc;
+}
+
+/*
+** Drop all shadow tables. Return SQLITE_OK if successful or an SQLite error
+** code otherwise.
+*/
+static int sqlite3Fts5DropAll(Fts5Config *pConfig){
+ int rc = fts5ExecPrintf(pConfig->db, 0,
+ "DROP TABLE IF EXISTS %Q.'%q_data';"
+ "DROP TABLE IF EXISTS %Q.'%q_idx';"
+ "DROP TABLE IF EXISTS %Q.'%q_config';",
+ pConfig->zDb, pConfig->zName,
+ pConfig->zDb, pConfig->zName,
+ pConfig->zDb, pConfig->zName
+ );
+ if( rc==SQLITE_OK && pConfig->bColumnsize ){
+ rc = fts5ExecPrintf(pConfig->db, 0,
+ "DROP TABLE IF EXISTS %Q.'%q_docsize';",
+ pConfig->zDb, pConfig->zName
+ );
+ }
+ if( rc==SQLITE_OK && pConfig->eContent==FTS5_CONTENT_NORMAL ){
+ rc = fts5ExecPrintf(pConfig->db, 0,
+ "DROP TABLE IF EXISTS %Q.'%q_content';",
+ pConfig->zDb, pConfig->zName
+ );
+ }
+ return rc;
+}
+
+static void fts5StorageRenameOne(
+ Fts5Config *pConfig, /* Current FTS5 configuration */
+ int *pRc, /* IN/OUT: Error code */
+ const char *zTail, /* Tail of table name e.g. "data", "config" */
+ const char *zName /* New name of FTS5 table */
+){
+ if( *pRc==SQLITE_OK ){
+ *pRc = fts5ExecPrintf(pConfig->db, 0,
+ "ALTER TABLE %Q.'%q_%s' RENAME TO '%q_%s';",
+ pConfig->zDb, pConfig->zName, zTail, zName, zTail
+ );
+ }
+}
+
+static int sqlite3Fts5StorageRename(Fts5Storage *pStorage, const char *zName){
+ Fts5Config *pConfig = pStorage->pConfig;
+ int rc = sqlite3Fts5StorageSync(pStorage, 1);
+
+ fts5StorageRenameOne(pConfig, &rc, "data", zName);
+ fts5StorageRenameOne(pConfig, &rc, "idx", zName);
+ fts5StorageRenameOne(pConfig, &rc, "config", zName);
+ if( pConfig->bColumnsize ){
+ fts5StorageRenameOne(pConfig, &rc, "docsize", zName);
+ }
+ if( pConfig->eContent==FTS5_CONTENT_NORMAL ){
+ fts5StorageRenameOne(pConfig, &rc, "content", zName);
+ }
+ return rc;
+}
+
+/*
+** Create the shadow table named zPost, with definition zDefn. Return
+** SQLITE_OK if successful, or an SQLite error code otherwise.
+*/
+static int sqlite3Fts5CreateTable(
+ Fts5Config *pConfig, /* FTS5 configuration */
+ const char *zPost, /* Shadow table to create (e.g. "content") */
+ const char *zDefn, /* Columns etc. for shadow table */
+ int bWithout, /* True for without rowid */
+ char **pzErr /* OUT: Error message */
+){
+ int rc;
+ char *zErr = 0;
+
+ rc = fts5ExecPrintf(pConfig->db, &zErr, "CREATE TABLE %Q.'%q_%q'(%s)%s",
+ pConfig->zDb, pConfig->zName, zPost, zDefn, bWithout?" WITHOUT ROWID":""
+ );
+ if( zErr ){
+ *pzErr = sqlite3_mprintf(
+ "fts5: error creating shadow table %q_%s: %s",
+ pConfig->zName, zPost, zErr
+ );
+ sqlite3_free(zErr);
+ }
+
+ return rc;
+}
+
+/*
+** Open a new Fts5Index handle. If the bCreate argument is true, create
+** and initialize the underlying tables
+**
+** If successful, set *pp to point to the new object and return SQLITE_OK.
+** Otherwise, set *pp to NULL and return an SQLite error code.
+*/
+static int sqlite3Fts5StorageOpen(
+ Fts5Config *pConfig,
+ Fts5Index *pIndex,
+ int bCreate,
+ Fts5Storage **pp,
+ char **pzErr /* OUT: Error message */
+){
+ int rc = SQLITE_OK;
+ Fts5Storage *p; /* New object */
+ int nByte; /* Bytes of space to allocate */
+
+ nByte = sizeof(Fts5Storage) /* Fts5Storage object */
+ + pConfig->nCol * sizeof(i64); /* Fts5Storage.aTotalSize[] */
+ *pp = p = (Fts5Storage*)sqlite3_malloc(nByte);
+ if( !p ) return SQLITE_NOMEM;
+
+ memset(p, 0, nByte);
+ p->aTotalSize = (i64*)&p[1];
+ p->pConfig = pConfig;
+ p->pIndex = pIndex;
+
+ if( bCreate ){
+ if( pConfig->eContent==FTS5_CONTENT_NORMAL ){
+ int nDefn = 32 + pConfig->nCol*10;
+ char *zDefn = sqlite3_malloc(32 + pConfig->nCol * 10);
+ if( zDefn==0 ){
+ rc = SQLITE_NOMEM;
+ }else{
+ int i;
+ int iOff;
+ sqlite3_snprintf(nDefn, zDefn, "id INTEGER PRIMARY KEY");
+ iOff = (int)strlen(zDefn);
+ for(i=0; i<pConfig->nCol; i++){
+ sqlite3_snprintf(nDefn-iOff, &zDefn[iOff], ", c%d", i);
+ iOff += (int)strlen(&zDefn[iOff]);
+ }
+ rc = sqlite3Fts5CreateTable(pConfig, "content", zDefn, 0, pzErr);
+ }
+ sqlite3_free(zDefn);
+ }
+
+ if( rc==SQLITE_OK && pConfig->bColumnsize ){
+ rc = sqlite3Fts5CreateTable(
+ pConfig, "docsize", "id INTEGER PRIMARY KEY, sz BLOB", 0, pzErr
+ );
+ }
+ if( rc==SQLITE_OK ){
+ rc = sqlite3Fts5CreateTable(
+ pConfig, "config", "k PRIMARY KEY, v", 1, pzErr
+ );
+ }
+ if( rc==SQLITE_OK ){
+ rc = sqlite3Fts5StorageConfigValue(p, "version", 0, FTS5_CURRENT_VERSION);
+ }
+ }
+
+ if( rc ){
+ sqlite3Fts5StorageClose(p);
+ *pp = 0;
+ }
+ return rc;
+}
+
+/*
+** Close a handle opened by an earlier call to sqlite3Fts5StorageOpen().
+*/
+static int sqlite3Fts5StorageClose(Fts5Storage *p){
+ int rc = SQLITE_OK;
+ if( p ){
+ int i;
+
+ /* Finalize all SQL statements */
+ for(i=0; i<(int)ArraySize(p->aStmt); i++){
+ sqlite3_finalize(p->aStmt[i]);
+ }
+
+ sqlite3_free(p);
+ }
+ return rc;
+}
+
+typedef struct Fts5InsertCtx Fts5InsertCtx;
+struct Fts5InsertCtx {
+ Fts5Storage *pStorage;
+ int iCol;
+ int szCol; /* Size of column value in tokens */
+};
+
+/*
+** Tokenization callback used when inserting tokens into the FTS index.
+*/
+static int fts5StorageInsertCallback(
+ void *pContext, /* Pointer to Fts5InsertCtx object */
+ int tflags,
+ const char *pToken, /* Buffer containing token */
+ int nToken, /* Size of token in bytes */
+ int iStart, /* Start offset of token */
+ int iEnd /* End offset of token */
+){
+ Fts5InsertCtx *pCtx = (Fts5InsertCtx*)pContext;
+ Fts5Index *pIdx = pCtx->pStorage->pIndex;
+ if( (tflags & FTS5_TOKEN_COLOCATED)==0 || pCtx->szCol==0 ){
+ pCtx->szCol++;
+ }
+ return sqlite3Fts5IndexWrite(pIdx, pCtx->iCol, pCtx->szCol-1, pToken, nToken);
+}
+
+/*
+** If a row with rowid iDel is present in the %_content table, add the
+** delete-markers to the FTS index necessary to delete it. Do not actually
+** remove the %_content row at this time though.
+*/
+static int fts5StorageDeleteFromIndex(Fts5Storage *p, i64 iDel){
+ Fts5Config *pConfig = p->pConfig;
+ sqlite3_stmt *pSeek; /* SELECT to read row iDel from %_data */
+ int rc; /* Return code */
+
+ rc = fts5StorageGetStmt(p, FTS5_STMT_LOOKUP, &pSeek, 0);
+ if( rc==SQLITE_OK ){
+ int rc2;
+ sqlite3_bind_int64(pSeek, 1, iDel);
+ if( sqlite3_step(pSeek)==SQLITE_ROW ){
+ int iCol;
+ Fts5InsertCtx ctx;
+ ctx.pStorage = p;
+ ctx.iCol = -1;
+ rc = sqlite3Fts5IndexBeginWrite(p->pIndex, 1, iDel);
+ for(iCol=1; rc==SQLITE_OK && iCol<=pConfig->nCol; iCol++){
+ if( pConfig->abUnindexed[iCol-1] ) continue;
+ ctx.szCol = 0;
+ rc = sqlite3Fts5Tokenize(pConfig,
+ FTS5_TOKENIZE_DOCUMENT,
+ (const char*)sqlite3_column_text(pSeek, iCol),
+ sqlite3_column_bytes(pSeek, iCol),
+ (void*)&ctx,
+ fts5StorageInsertCallback
+ );
+ p->aTotalSize[iCol-1] -= (i64)ctx.szCol;
+ }
+ p->nTotalRow--;
+ }
+ rc2 = sqlite3_reset(pSeek);
+ if( rc==SQLITE_OK ) rc = rc2;
+ }
+
+ return rc;
+}
+
+
+/*
+** Insert a record into the %_docsize table. Specifically, do:
+**
+** INSERT OR REPLACE INTO %_docsize(id, sz) VALUES(iRowid, pBuf);
+**
+** If there is no %_docsize table (as happens if the columnsize=0 option
+** is specified when the FTS5 table is created), this function is a no-op.
+*/
+static int fts5StorageInsertDocsize(
+ Fts5Storage *p, /* Storage module to write to */
+ i64 iRowid, /* id value */
+ Fts5Buffer *pBuf /* sz value */
+){
+ int rc = SQLITE_OK;
+ if( p->pConfig->bColumnsize ){
+ sqlite3_stmt *pReplace = 0;
+ rc = fts5StorageGetStmt(p, FTS5_STMT_REPLACE_DOCSIZE, &pReplace, 0);
+ if( rc==SQLITE_OK ){
+ sqlite3_bind_int64(pReplace, 1, iRowid);
+ sqlite3_bind_blob(pReplace, 2, pBuf->p, pBuf->n, SQLITE_STATIC);
+ sqlite3_step(pReplace);
+ rc = sqlite3_reset(pReplace);
+ }
+ }
+ return rc;
+}
+
+/*
+** Load the contents of the "averages" record from disk into the
+** p->nTotalRow and p->aTotalSize[] variables. If successful, and if
+** argument bCache is true, set the p->bTotalsValid flag to indicate
+** that the contents of aTotalSize[] and nTotalRow are valid until
+** further notice.
+**
+** Return SQLITE_OK if successful, or an SQLite error code if an error
+** occurs.
+*/
+static int fts5StorageLoadTotals(Fts5Storage *p, int bCache){
+ int rc = SQLITE_OK;
+ if( p->bTotalsValid==0 ){
+ rc = sqlite3Fts5IndexGetAverages(p->pIndex, &p->nTotalRow, p->aTotalSize);
+ p->bTotalsValid = bCache;
+ }
+ return rc;
+}
+
+/*
+** Store the current contents of the p->nTotalRow and p->aTotalSize[]
+** variables in the "averages" record on disk.
+**
+** Return SQLITE_OK if successful, or an SQLite error code if an error
+** occurs.
+*/
+static int fts5StorageSaveTotals(Fts5Storage *p){
+ int nCol = p->pConfig->nCol;
+ int i;
+ Fts5Buffer buf;
+ int rc = SQLITE_OK;
+ memset(&buf, 0, sizeof(buf));
+
+ sqlite3Fts5BufferAppendVarint(&rc, &buf, p->nTotalRow);
+ for(i=0; i<nCol; i++){
+ sqlite3Fts5BufferAppendVarint(&rc, &buf, p->aTotalSize[i]);
+ }
+ if( rc==SQLITE_OK ){
+ rc = sqlite3Fts5IndexSetAverages(p->pIndex, buf.p, buf.n);
+ }
+ sqlite3_free(buf.p);
+
+ return rc;
+}
+
+/*
+** Remove a row from the FTS table.
+*/
+static int sqlite3Fts5StorageDelete(Fts5Storage *p, i64 iDel){
+ Fts5Config *pConfig = p->pConfig;
+ int rc;
+ sqlite3_stmt *pDel = 0;
+
+ rc = fts5StorageLoadTotals(p, 1);
+
+ /* Delete the index records */
+ if( rc==SQLITE_OK ){
+ rc = fts5StorageDeleteFromIndex(p, iDel);
+ }
+
+ /* Delete the %_docsize record */
+ if( rc==SQLITE_OK && pConfig->bColumnsize ){
+ rc = fts5StorageGetStmt(p, FTS5_STMT_DELETE_DOCSIZE, &pDel, 0);
+ if( rc==SQLITE_OK ){
+ sqlite3_bind_int64(pDel, 1, iDel);
+ sqlite3_step(pDel);
+ rc = sqlite3_reset(pDel);
+ }
+ }
+
+ /* Delete the %_content record */
+ if( pConfig->eContent==FTS5_CONTENT_NORMAL ){
+ if( rc==SQLITE_OK ){
+ rc = fts5StorageGetStmt(p, FTS5_STMT_DELETE_CONTENT, &pDel, 0);
+ }
+ if( rc==SQLITE_OK ){
+ sqlite3_bind_int64(pDel, 1, iDel);
+ sqlite3_step(pDel);
+ rc = sqlite3_reset(pDel);
+ }
+ }
+
+ /* Write the averages record */
+ if( rc==SQLITE_OK ){
+ rc = fts5StorageSaveTotals(p);
+ }
+
+ return rc;
+}
+
+static int sqlite3Fts5StorageSpecialDelete(
+ Fts5Storage *p,
+ i64 iDel,
+ sqlite3_value **apVal
+){
+ Fts5Config *pConfig = p->pConfig;
+ int rc;
+ sqlite3_stmt *pDel = 0;
+
+ assert( pConfig->eContent!=FTS5_CONTENT_NORMAL );
+ rc = fts5StorageLoadTotals(p, 1);
+
+ /* Delete the index records */
+ if( rc==SQLITE_OK ){
+ int iCol;
+ Fts5InsertCtx ctx;
+ ctx.pStorage = p;
+ ctx.iCol = -1;
+
+ rc = sqlite3Fts5IndexBeginWrite(p->pIndex, 1, iDel);
+ for(iCol=0; rc==SQLITE_OK && iCol<pConfig->nCol; iCol++){
+ if( pConfig->abUnindexed[iCol] ) continue;
+ ctx.szCol = 0;
+ rc = sqlite3Fts5Tokenize(pConfig,
+ FTS5_TOKENIZE_DOCUMENT,
+ (const char*)sqlite3_value_text(apVal[iCol]),
+ sqlite3_value_bytes(apVal[iCol]),
+ (void*)&ctx,
+ fts5StorageInsertCallback
+ );
+ p->aTotalSize[iCol] -= (i64)ctx.szCol;
+ }
+ p->nTotalRow--;
+ }
+
+ /* Delete the %_docsize record */
+ if( pConfig->bColumnsize ){
+ if( rc==SQLITE_OK ){
+ rc = fts5StorageGetStmt(p, FTS5_STMT_DELETE_DOCSIZE, &pDel, 0);
+ }
+ if( rc==SQLITE_OK ){
+ sqlite3_bind_int64(pDel, 1, iDel);
+ sqlite3_step(pDel);
+ rc = sqlite3_reset(pDel);
+ }
+ }
+
+ /* Write the averages record */
+ if( rc==SQLITE_OK ){
+ rc = fts5StorageSaveTotals(p);
+ }
+
+ return rc;
+}
+
+/*
+** Delete all entries in the FTS5 index.
+*/
+static int sqlite3Fts5StorageDeleteAll(Fts5Storage *p){
+ Fts5Config *pConfig = p->pConfig;
+ int rc;
+
+ /* Delete the contents of the %_data and %_docsize tables. */
+ rc = fts5ExecPrintf(pConfig->db, 0,
+ "DELETE FROM %Q.'%q_data';"
+ "DELETE FROM %Q.'%q_idx';",
+ pConfig->zDb, pConfig->zName,
+ pConfig->zDb, pConfig->zName
+ );
+ if( rc==SQLITE_OK && pConfig->bColumnsize ){
+ rc = fts5ExecPrintf(pConfig->db, 0,
+ "DELETE FROM %Q.'%q_docsize';",
+ pConfig->zDb, pConfig->zName
+ );
+ }
+
+ /* Reinitialize the %_data table. This call creates the initial structure
+ ** and averages records. */
+ if( rc==SQLITE_OK ){
+ rc = sqlite3Fts5IndexReinit(p->pIndex);
+ }
+ if( rc==SQLITE_OK ){
+ rc = sqlite3Fts5StorageConfigValue(p, "version", 0, FTS5_CURRENT_VERSION);
+ }
+ return rc;
+}
+
+static int sqlite3Fts5StorageRebuild(Fts5Storage *p){
+ Fts5Buffer buf = {0,0,0};
+ Fts5Config *pConfig = p->pConfig;
+ sqlite3_stmt *pScan = 0;
+ Fts5InsertCtx ctx;
+ int rc;
+
+ memset(&ctx, 0, sizeof(Fts5InsertCtx));
+ ctx.pStorage = p;
+ rc = sqlite3Fts5StorageDeleteAll(p);
+ if( rc==SQLITE_OK ){
+ rc = fts5StorageLoadTotals(p, 1);
+ }
+
+ if( rc==SQLITE_OK ){
+ rc = fts5StorageGetStmt(p, FTS5_STMT_SCAN, &pScan, 0);
+ }
+
+ while( rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pScan) ){
+ i64 iRowid = sqlite3_column_int64(pScan, 0);
+
+ sqlite3Fts5BufferZero(&buf);
+ rc = sqlite3Fts5IndexBeginWrite(p->pIndex, 0, iRowid);
+ for(ctx.iCol=0; rc==SQLITE_OK && ctx.iCol<pConfig->nCol; ctx.iCol++){
+ ctx.szCol = 0;
+ if( pConfig->abUnindexed[ctx.iCol]==0 ){
+ rc = sqlite3Fts5Tokenize(pConfig,
+ FTS5_TOKENIZE_DOCUMENT,
+ (const char*)sqlite3_column_text(pScan, ctx.iCol+1),
+ sqlite3_column_bytes(pScan, ctx.iCol+1),
+ (void*)&ctx,
+ fts5StorageInsertCallback
+ );
+ }
+ sqlite3Fts5BufferAppendVarint(&rc, &buf, ctx.szCol);
+ p->aTotalSize[ctx.iCol] += (i64)ctx.szCol;
+ }
+ p->nTotalRow++;
+
+ if( rc==SQLITE_OK ){
+ rc = fts5StorageInsertDocsize(p, iRowid, &buf);
+ }
+ }
+ sqlite3_free(buf.p);
+
+ /* Write the averages record */
+ if( rc==SQLITE_OK ){
+ rc = fts5StorageSaveTotals(p);
+ }
+ return rc;
+}
+
+static int sqlite3Fts5StorageOptimize(Fts5Storage *p){
+ return sqlite3Fts5IndexOptimize(p->pIndex);
+}
+
+static int sqlite3Fts5StorageMerge(Fts5Storage *p, int nMerge){
+ return sqlite3Fts5IndexMerge(p->pIndex, nMerge);
+}
+
+/*
+** Allocate a new rowid. This is used for "external content" tables when
+** a NULL value is inserted into the rowid column. The new rowid is allocated
+** by inserting a dummy row into the %_docsize table. The dummy will be
+** overwritten later.
+**
+** If the %_docsize table does not exist, SQLITE_MISMATCH is returned. In
+** this case the user is required to provide a rowid explicitly.
+*/
+static int fts5StorageNewRowid(Fts5Storage *p, i64 *piRowid){
+ int rc = SQLITE_MISMATCH;
+ if( p->pConfig->bColumnsize ){
+ sqlite3_stmt *pReplace = 0;
+ rc = fts5StorageGetStmt(p, FTS5_STMT_REPLACE_DOCSIZE, &pReplace, 0);
+ if( rc==SQLITE_OK ){
+ sqlite3_bind_null(pReplace, 1);
+ sqlite3_bind_null(pReplace, 2);
+ sqlite3_step(pReplace);
+ rc = sqlite3_reset(pReplace);
+ }
+ if( rc==SQLITE_OK ){
+ *piRowid = sqlite3_last_insert_rowid(p->pConfig->db);
+ }
+ }
+ return rc;
+}
+
+/*
+** Insert a new row into the FTS content table.
+*/
+static int sqlite3Fts5StorageContentInsert(
+ Fts5Storage *p,
+ sqlite3_value **apVal,
+ i64 *piRowid
+){
+ Fts5Config *pConfig = p->pConfig;
+ int rc = SQLITE_OK;
+
+ /* Insert the new row into the %_content table. */
+ if( pConfig->eContent!=FTS5_CONTENT_NORMAL ){
+ if( sqlite3_value_type(apVal[1])==SQLITE_INTEGER ){
+ *piRowid = sqlite3_value_int64(apVal[1]);
+ }else{
+ rc = fts5StorageNewRowid(p, piRowid);
+ }
+ }else{
+ sqlite3_stmt *pInsert = 0; /* Statement to write %_content table */
+ int i; /* Counter variable */
+ rc = fts5StorageGetStmt(p, FTS5_STMT_INSERT_CONTENT, &pInsert, 0);
+ for(i=1; rc==SQLITE_OK && i<=pConfig->nCol+1; i++){
+ rc = sqlite3_bind_value(pInsert, i, apVal[i]);
+ }
+ if( rc==SQLITE_OK ){
+ sqlite3_step(pInsert);
+ rc = sqlite3_reset(pInsert);
+ }
+ *piRowid = sqlite3_last_insert_rowid(pConfig->db);
+ }
+
+ return rc;
+}
+
+/*
+** Insert new entries into the FTS index and %_docsize table.
+*/
+static int sqlite3Fts5StorageIndexInsert(
+ Fts5Storage *p,
+ sqlite3_value **apVal,
+ i64 iRowid
+){
+ Fts5Config *pConfig = p->pConfig;
+ int rc = SQLITE_OK; /* Return code */
+ Fts5InsertCtx ctx; /* Tokenization callback context object */
+ Fts5Buffer buf; /* Buffer used to build up %_docsize blob */
+
+ memset(&buf, 0, sizeof(Fts5Buffer));
+ ctx.pStorage = p;
+ rc = fts5StorageLoadTotals(p, 1);
+
+ if( rc==SQLITE_OK ){
+ rc = sqlite3Fts5IndexBeginWrite(p->pIndex, 0, iRowid);
+ }
+ for(ctx.iCol=0; rc==SQLITE_OK && ctx.iCol<pConfig->nCol; ctx.iCol++){
+ ctx.szCol = 0;
+ if( pConfig->abUnindexed[ctx.iCol]==0 ){
+ rc = sqlite3Fts5Tokenize(pConfig,
+ FTS5_TOKENIZE_DOCUMENT,
+ (const char*)sqlite3_value_text(apVal[ctx.iCol+2]),
+ sqlite3_value_bytes(apVal[ctx.iCol+2]),
+ (void*)&ctx,
+ fts5StorageInsertCallback
+ );
+ }
+ sqlite3Fts5BufferAppendVarint(&rc, &buf, ctx.szCol);
+ p->aTotalSize[ctx.iCol] += (i64)ctx.szCol;
+ }
+ p->nTotalRow++;
+
+ /* Write the %_docsize record */
+ if( rc==SQLITE_OK ){
+ rc = fts5StorageInsertDocsize(p, iRowid, &buf);
+ }
+ sqlite3_free(buf.p);
+
+ /* Write the averages record */
+ if( rc==SQLITE_OK ){
+ rc = fts5StorageSaveTotals(p);
+ }
+
+ return rc;
+}
+
+static int fts5StorageCount(Fts5Storage *p, const char *zSuffix, i64 *pnRow){
+ Fts5Config *pConfig = p->pConfig;
+ char *zSql;
+ int rc;
+
+ zSql = sqlite3_mprintf("SELECT count(*) FROM %Q.'%q_%s'",
+ pConfig->zDb, pConfig->zName, zSuffix
+ );
+ if( zSql==0 ){
+ rc = SQLITE_NOMEM;
+ }else{
+ sqlite3_stmt *pCnt = 0;
+ rc = sqlite3_prepare_v2(pConfig->db, zSql, -1, &pCnt, 0);
+ if( rc==SQLITE_OK ){
+ if( SQLITE_ROW==sqlite3_step(pCnt) ){
+ *pnRow = sqlite3_column_int64(pCnt, 0);
+ }
+ rc = sqlite3_finalize(pCnt);
+ }
+ }
+
+ sqlite3_free(zSql);
+ return rc;
+}
+
+/*
+** Context object used by sqlite3Fts5StorageIntegrity().
+*/
+typedef struct Fts5IntegrityCtx Fts5IntegrityCtx;
+struct Fts5IntegrityCtx {
+ i64 iRowid;
+ int iCol;
+ int szCol;
+ u64 cksum;
+ Fts5Config *pConfig;
+};
+
+/*
+** Tokenization callback used by integrity check.
+*/
+static int fts5StorageIntegrityCallback(
+ void *pContext, /* Pointer to Fts5InsertCtx object */
+ int tflags,
+ const char *pToken, /* Buffer containing token */
+ int nToken, /* Size of token in bytes */
+ int iStart, /* Start offset of token */
+ int iEnd /* End offset of token */
+){
+ Fts5IntegrityCtx *pCtx = (Fts5IntegrityCtx*)pContext;
+ if( (tflags & FTS5_TOKEN_COLOCATED)==0 || pCtx->szCol==0 ){
+ pCtx->szCol++;
+ }
+ pCtx->cksum ^= sqlite3Fts5IndexCksum(
+ pCtx->pConfig, pCtx->iRowid, pCtx->iCol, pCtx->szCol-1, pToken, nToken
+ );
+ return SQLITE_OK;
+}
+
+/*
+** Check that the contents of the FTS index match that of the %_content
+** table. Return SQLITE_OK if they do, or SQLITE_CORRUPT if not. Return
+** some other SQLite error code if an error occurs while attempting to
+** determine this.
+*/
+static int sqlite3Fts5StorageIntegrity(Fts5Storage *p){
+ Fts5Config *pConfig = p->pConfig;
+ int rc; /* Return code */
+ int *aColSize; /* Array of size pConfig->nCol */
+ i64 *aTotalSize; /* Array of size pConfig->nCol */
+ Fts5IntegrityCtx ctx;
+ sqlite3_stmt *pScan;
+
+ memset(&ctx, 0, sizeof(Fts5IntegrityCtx));
+ ctx.pConfig = p->pConfig;
+ aTotalSize = (i64*)sqlite3_malloc(pConfig->nCol * (sizeof(int)+sizeof(i64)));
+ if( !aTotalSize ) return SQLITE_NOMEM;
+ aColSize = (int*)&aTotalSize[pConfig->nCol];
+ memset(aTotalSize, 0, sizeof(i64) * pConfig->nCol);
+
+ /* Generate the expected index checksum based on the contents of the
+ ** %_content table. This block stores the checksum in ctx.cksum. */
+ rc = fts5StorageGetStmt(p, FTS5_STMT_SCAN, &pScan, 0);
+ if( rc==SQLITE_OK ){
+ int rc2;
+ while( SQLITE_ROW==sqlite3_step(pScan) ){
+ int i;
+ ctx.iRowid = sqlite3_column_int64(pScan, 0);
+ ctx.szCol = 0;
+ if( pConfig->bColumnsize ){
+ rc = sqlite3Fts5StorageDocsize(p, ctx.iRowid, aColSize);
+ }
+ for(i=0; rc==SQLITE_OK && i<pConfig->nCol; i++){
+ if( pConfig->abUnindexed[i] ) continue;
+ ctx.iCol = i;
+ ctx.szCol = 0;
+ rc = sqlite3Fts5Tokenize(pConfig,
+ FTS5_TOKENIZE_DOCUMENT,
+ (const char*)sqlite3_column_text(pScan, i+1),
+ sqlite3_column_bytes(pScan, i+1),
+ (void*)&ctx,
+ fts5StorageIntegrityCallback
+ );
+ if( pConfig->bColumnsize && ctx.szCol!=aColSize[i] ){
+ rc = FTS5_CORRUPT;
+ }
+ aTotalSize[i] += ctx.szCol;
+ }
+ if( rc!=SQLITE_OK ) break;
+ }
+ rc2 = sqlite3_reset(pScan);
+ if( rc==SQLITE_OK ) rc = rc2;
+ }
+
+ /* Test that the "totals" (sometimes called "averages") record looks Ok */
+ if( rc==SQLITE_OK ){
+ int i;
+ rc = fts5StorageLoadTotals(p, 0);
+ for(i=0; rc==SQLITE_OK && i<pConfig->nCol; i++){
+ if( p->aTotalSize[i]!=aTotalSize[i] ) rc = FTS5_CORRUPT;
+ }
+ }
+
+ /* Check that the %_docsize and %_content tables contain the expected
+ ** number of rows. */
+ if( rc==SQLITE_OK && pConfig->eContent==FTS5_CONTENT_NORMAL ){
+ i64 nRow = 0;
+ rc = fts5StorageCount(p, "content", &nRow);
+ if( rc==SQLITE_OK && nRow!=p->nTotalRow ) rc = FTS5_CORRUPT;
+ }
+ if( rc==SQLITE_OK && pConfig->bColumnsize ){
+ i64 nRow = 0;
+ rc = fts5StorageCount(p, "docsize", &nRow);
+ if( rc==SQLITE_OK && nRow!=p->nTotalRow ) rc = FTS5_CORRUPT;
+ }
+
+ /* Pass the expected checksum down to the FTS index module. It will
+ ** verify, amongst other things, that it matches the checksum generated by
+ ** inspecting the index itself. */
+ if( rc==SQLITE_OK ){
+ rc = sqlite3Fts5IndexIntegrityCheck(p->pIndex, ctx.cksum);
+ }
+
+ sqlite3_free(aTotalSize);
+ return rc;
+}
+
+/*
+** Obtain an SQLite statement handle that may be used to read data from the
+** %_content table.
+*/
+static int sqlite3Fts5StorageStmt(
+ Fts5Storage *p,
+ int eStmt,
+ sqlite3_stmt **pp,
+ char **pzErrMsg
+){
+ int rc;
+ assert( eStmt==FTS5_STMT_SCAN_ASC
+ || eStmt==FTS5_STMT_SCAN_DESC
+ || eStmt==FTS5_STMT_LOOKUP
+ );
+ rc = fts5StorageGetStmt(p, eStmt, pp, pzErrMsg);
+ if( rc==SQLITE_OK ){
+ assert( p->aStmt[eStmt]==*pp );
+ p->aStmt[eStmt] = 0;
+ }
+ return rc;
+}
+
+/*
+** Release an SQLite statement handle obtained via an earlier call to
+** sqlite3Fts5StorageStmt(). The eStmt parameter passed to this function
+** must match that passed to the sqlite3Fts5StorageStmt() call.
+*/
+static void sqlite3Fts5StorageStmtRelease(
+ Fts5Storage *p,
+ int eStmt,
+ sqlite3_stmt *pStmt
+){
+ assert( eStmt==FTS5_STMT_SCAN_ASC
+ || eStmt==FTS5_STMT_SCAN_DESC
+ || eStmt==FTS5_STMT_LOOKUP
+ );
+ if( p->aStmt[eStmt]==0 ){
+ sqlite3_reset(pStmt);
+ p->aStmt[eStmt] = pStmt;
+ }else{
+ sqlite3_finalize(pStmt);
+ }
+}
+
+static int fts5StorageDecodeSizeArray(
+ int *aCol, int nCol, /* Array to populate */
+ const u8 *aBlob, int nBlob /* Record to read varints from */
+){
+ int i;
+ int iOff = 0;
+ for(i=0; i<nCol; i++){
+ if( iOff>=nBlob ) return 1;
+ iOff += fts5GetVarint32(&aBlob[iOff], aCol[i]);
+ }
+ return (iOff!=nBlob);
+}
+
+/*
+** Argument aCol points to an array of integers containing one entry for
+** each table column. This function reads the %_docsize record for the
+** specified rowid and populates aCol[] with the results.
+**
+** An SQLite error code is returned if an error occurs, or SQLITE_OK
+** otherwise.
+*/
+static int sqlite3Fts5StorageDocsize(Fts5Storage *p, i64 iRowid, int *aCol){
+ int nCol = p->pConfig->nCol; /* Number of user columns in table */
+ sqlite3_stmt *pLookup = 0; /* Statement to query %_docsize */
+ int rc; /* Return Code */
+
+ assert( p->pConfig->bColumnsize );
+ rc = fts5StorageGetStmt(p, FTS5_STMT_LOOKUP_DOCSIZE, &pLookup, 0);
+ if( rc==SQLITE_OK ){
+ int bCorrupt = 1;
+ sqlite3_bind_int64(pLookup, 1, iRowid);
+ if( SQLITE_ROW==sqlite3_step(pLookup) ){
+ const u8 *aBlob = sqlite3_column_blob(pLookup, 0);
+ int nBlob = sqlite3_column_bytes(pLookup, 0);
+ if( 0==fts5StorageDecodeSizeArray(aCol, nCol, aBlob, nBlob) ){
+ bCorrupt = 0;
+ }
+ }
+ rc = sqlite3_reset(pLookup);
+ if( bCorrupt && rc==SQLITE_OK ){
+ rc = FTS5_CORRUPT;
+ }
+ }
+
+ return rc;
+}
+
+static int sqlite3Fts5StorageSize(Fts5Storage *p, int iCol, i64 *pnToken){
+ int rc = fts5StorageLoadTotals(p, 0);
+ if( rc==SQLITE_OK ){
+ *pnToken = 0;
+ if( iCol<0 ){
+ int i;
+ for(i=0; i<p->pConfig->nCol; i++){
+ *pnToken += p->aTotalSize[i];
+ }
+ }else if( iCol<p->pConfig->nCol ){
+ *pnToken = p->aTotalSize[iCol];
+ }else{
+ rc = SQLITE_RANGE;
+ }
+ }
+ return rc;
+}
+
+static int sqlite3Fts5StorageRowCount(Fts5Storage *p, i64 *pnRow){
+ int rc = fts5StorageLoadTotals(p, 0);
+ if( rc==SQLITE_OK ){
+ *pnRow = p->nTotalRow;
+ }
+ return rc;
+}
+
+/*
+** Flush any data currently held in-memory to disk.
+*/
+static int sqlite3Fts5StorageSync(Fts5Storage *p, int bCommit){
+ if( bCommit && p->bTotalsValid ){
+ int rc = fts5StorageSaveTotals(p);
+ p->bTotalsValid = 0;
+ if( rc!=SQLITE_OK ) return rc;
+ }
+ return sqlite3Fts5IndexSync(p->pIndex, bCommit);
+}
+
+static int sqlite3Fts5StorageRollback(Fts5Storage *p){
+ p->bTotalsValid = 0;
+ return sqlite3Fts5IndexRollback(p->pIndex);
+}
+
+static int sqlite3Fts5StorageConfigValue(
+ Fts5Storage *p,
+ const char *z,
+ sqlite3_value *pVal,
+ int iVal
+){
+ sqlite3_stmt *pReplace = 0;
+ int rc = fts5StorageGetStmt(p, FTS5_STMT_REPLACE_CONFIG, &pReplace, 0);
+ if( rc==SQLITE_OK ){
+ sqlite3_bind_text(pReplace, 1, z, -1, SQLITE_STATIC);
+ if( pVal ){
+ sqlite3_bind_value(pReplace, 2, pVal);
+ }else{
+ sqlite3_bind_int(pReplace, 2, iVal);
+ }
+ sqlite3_step(pReplace);
+ rc = sqlite3_reset(pReplace);
+ }
+ if( rc==SQLITE_OK && pVal ){
+ int iNew = p->pConfig->iCookie + 1;
+ rc = sqlite3Fts5IndexSetCookie(p->pIndex, iNew);
+ if( rc==SQLITE_OK ){
+ p->pConfig->iCookie = iNew;
+ }
+ }
+ return rc;
+}
+
+
+
+/*
+** 2014 May 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.
+**
+******************************************************************************
+*/
+
+
+/* #include "fts5Int.h" */
+
+/**************************************************************************
+** Start of ascii tokenizer implementation.
+*/
+
+/*
+** For tokenizers with no "unicode" modifier, the set of token characters
+** is the same as the set of ASCII range alphanumeric characters.
+*/
+static unsigned char aAsciiTokenChar[128] = {
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x00..0x0F */
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x10..0x1F */
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x20..0x2F */
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, /* 0x30..0x3F */
+ 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 0x40..0x4F */
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, /* 0x50..0x5F */
+ 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 0x60..0x6F */
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, /* 0x70..0x7F */
+};
+
+typedef struct AsciiTokenizer AsciiTokenizer;
+struct AsciiTokenizer {
+ unsigned char aTokenChar[128];
+};
+
+static void fts5AsciiAddExceptions(
+ AsciiTokenizer *p,
+ const char *zArg,
+ int bTokenChars
+){
+ int i;
+ for(i=0; zArg[i]; i++){
+ if( (zArg[i] & 0x80)==0 ){
+ p->aTokenChar[(int)zArg[i]] = (unsigned char)bTokenChars;
+ }
+ }
+}
+
+/*
+** Delete a "ascii" tokenizer.
+*/
+static void fts5AsciiDelete(Fts5Tokenizer *p){
+ sqlite3_free(p);
+}
+
+/*
+** Create an "ascii" tokenizer.
+*/
+static int fts5AsciiCreate(
+ void *pCtx,
+ const char **azArg, int nArg,
+ Fts5Tokenizer **ppOut
+){
+ int rc = SQLITE_OK;
+ AsciiTokenizer *p = 0;
+ if( nArg%2 ){
+ rc = SQLITE_ERROR;
+ }else{
+ p = sqlite3_malloc(sizeof(AsciiTokenizer));
+ if( p==0 ){
+ rc = SQLITE_NOMEM;
+ }else{
+ int i;
+ memset(p, 0, sizeof(AsciiTokenizer));
+ memcpy(p->aTokenChar, aAsciiTokenChar, sizeof(aAsciiTokenChar));
+ for(i=0; rc==SQLITE_OK && i<nArg; i+=2){
+ const char *zArg = azArg[i+1];
+ if( 0==sqlite3_stricmp(azArg[i], "tokenchars") ){
+ fts5AsciiAddExceptions(p, zArg, 1);
+ }else
+ if( 0==sqlite3_stricmp(azArg[i], "separators") ){
+ fts5AsciiAddExceptions(p, zArg, 0);
+ }else{
+ rc = SQLITE_ERROR;
+ }
+ }
+ if( rc!=SQLITE_OK ){
+ fts5AsciiDelete((Fts5Tokenizer*)p);
+ p = 0;
+ }
+ }
+ }
+
+ *ppOut = (Fts5Tokenizer*)p;
+ return rc;
+}
+
+
+static void asciiFold(char *aOut, const char *aIn, int nByte){
+ int i;
+ for(i=0; i<nByte; i++){
+ char c = aIn[i];
+ if( c>='A' && c<='Z' ) c += 32;
+ aOut[i] = c;
+ }
+}
+
+/*
+** Tokenize some text using the ascii tokenizer.
+*/
+static int fts5AsciiTokenize(
+ Fts5Tokenizer *pTokenizer,
+ void *pCtx,
+ int flags,
+ const char *pText, int nText,
+ int (*xToken)(void*, int, const char*, int nToken, int iStart, int iEnd)
+){
+ AsciiTokenizer *p = (AsciiTokenizer*)pTokenizer;
+ int rc = SQLITE_OK;
+ int ie;
+ int is = 0;
+
+ char aFold[64];
+ int nFold = sizeof(aFold);
+ char *pFold = aFold;
+ unsigned char *a = p->aTokenChar;
+
+ while( is<nText && rc==SQLITE_OK ){
+ int nByte;
+
+ /* Skip any leading divider characters. */
+ while( is<nText && ((pText[is]&0x80)==0 && a[(int)pText[is]]==0) ){
+ is++;
+ }
+ if( is==nText ) break;
+
+ /* Count the token characters */
+ ie = is+1;
+ while( ie<nText && ((pText[ie]&0x80) || a[(int)pText[ie]] ) ){
+ ie++;
+ }
+
+ /* Fold to lower case */
+ nByte = ie-is;
+ if( nByte>nFold ){
+ if( pFold!=aFold ) sqlite3_free(pFold);
+ pFold = sqlite3_malloc(nByte*2);
+ if( pFold==0 ){
+ rc = SQLITE_NOMEM;
+ break;
+ }
+ nFold = nByte*2;
+ }
+ asciiFold(pFold, &pText[is], nByte);
+
+ /* Invoke the token callback */
+ rc = xToken(pCtx, 0, pFold, nByte, is, ie);
+ is = ie+1;
+ }
+
+ if( pFold!=aFold ) sqlite3_free(pFold);
+ if( rc==SQLITE_DONE ) rc = SQLITE_OK;
+ return rc;
+}
+
+/**************************************************************************
+** Start of unicode61 tokenizer implementation.
+*/
+
+
+/*
+** 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++ = (unsigned char)(c&0xFF); \
+ } \
+ else if( c<0x00800 ){ \
+ *zOut++ = 0xC0 + (unsigned char)((c>>6)&0x1F); \
+ *zOut++ = 0x80 + (unsigned char)(c & 0x3F); \
+ } \
+ else if( c<0x10000 ){ \
+ *zOut++ = 0xE0 + (unsigned char)((c>>12)&0x0F); \
+ *zOut++ = 0x80 + (unsigned char)((c>>6) & 0x3F); \
+ *zOut++ = 0x80 + (unsigned char)(c & 0x3F); \
+ }else{ \
+ *zOut++ = 0xF0 + (unsigned char)((c>>18) & 0x07); \
+ *zOut++ = 0x80 + (unsigned char)((c>>12) & 0x3F); \
+ *zOut++ = 0x80 + (unsigned char)((c>>6) & 0x3F); \
+ *zOut++ = 0x80 + (unsigned char)(c & 0x3F); \
+ } \
+}
+
+#endif /* ifndef SQLITE_AMALGAMATION */
+
+typedef struct Unicode61Tokenizer Unicode61Tokenizer;
+struct Unicode61Tokenizer {
+ unsigned char aTokenChar[128]; /* ASCII range token characters */
+ char *aFold; /* Buffer to fold text into */
+ int nFold; /* Size of aFold[] in bytes */
+ int bRemoveDiacritic; /* True if remove_diacritics=1 is set */
+ int nException;
+ int *aiException;
+};
+
+static int fts5UnicodeAddExceptions(
+ Unicode61Tokenizer *p, /* Tokenizer object */
+ const char *z, /* Characters to treat as exceptions */
+ int bTokenChars /* 1 for 'tokenchars', 0 for 'separators' */
+){
+ int rc = SQLITE_OK;
+ int n = (int)strlen(z);
+ int *aNew;
+
+ if( n>0 ){
+ aNew = (int*)sqlite3_realloc(p->aiException, (n+p->nException)*sizeof(int));
+ if( aNew ){
+ int nNew = p->nException;
+ const unsigned char *zCsr = (const unsigned char*)z;
+ const unsigned char *zTerm = (const unsigned char*)&z[n];
+ while( zCsr<zTerm ){
+ int iCode;
+ int bToken;
+ READ_UTF8(zCsr, zTerm, iCode);
+ if( iCode<128 ){
+ p->aTokenChar[iCode] = (unsigned char)bTokenChars;
+ }else{
+ bToken = sqlite3Fts5UnicodeIsalnum(iCode);
+ assert( (bToken==0 || bToken==1) );
+ assert( (bTokenChars==0 || bTokenChars==1) );
+ if( bToken!=bTokenChars && sqlite3Fts5UnicodeIsdiacritic(iCode)==0 ){
+ int i;
+ for(i=0; i<nNew; i++){
+ if( aNew[i]>iCode ) break;
+ }
+ memmove(&aNew[i+1], &aNew[i], (nNew-i)*sizeof(int));
+ aNew[i] = iCode;
+ nNew++;
+ }
+ }
+ }
+ p->aiException = aNew;
+ p->nException = nNew;
+ }else{
+ rc = SQLITE_NOMEM;
+ }
+ }
+
+ return rc;
+}
+
+/*
+** Return true if the p->aiException[] array contains the value iCode.
+*/
+static int fts5UnicodeIsException(Unicode61Tokenizer *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;
+}
+
+/*
+** Delete a "unicode61" tokenizer.
+*/
+static void fts5UnicodeDelete(Fts5Tokenizer *pTok){
+ if( pTok ){
+ Unicode61Tokenizer *p = (Unicode61Tokenizer*)pTok;
+ sqlite3_free(p->aiException);
+ sqlite3_free(p->aFold);
+ sqlite3_free(p);
+ }
+ return;
+}
+
+/*
+** Create a "unicode61" tokenizer.
+*/
+static int fts5UnicodeCreate(
+ void *pCtx,
+ const char **azArg, int nArg,
+ Fts5Tokenizer **ppOut
+){
+ int rc = SQLITE_OK; /* Return code */
+ Unicode61Tokenizer *p = 0; /* New tokenizer object */
+
+ if( nArg%2 ){
+ rc = SQLITE_ERROR;
+ }else{
+ p = (Unicode61Tokenizer*)sqlite3_malloc(sizeof(Unicode61Tokenizer));
+ if( p ){
+ int i;
+ memset(p, 0, sizeof(Unicode61Tokenizer));
+ memcpy(p->aTokenChar, aAsciiTokenChar, sizeof(aAsciiTokenChar));
+ p->bRemoveDiacritic = 1;
+ p->nFold = 64;
+ p->aFold = sqlite3_malloc(p->nFold * sizeof(char));
+ if( p->aFold==0 ){
+ rc = SQLITE_NOMEM;
+ }
+ for(i=0; rc==SQLITE_OK && i<nArg; i+=2){
+ const char *zArg = azArg[i+1];
+ if( 0==sqlite3_stricmp(azArg[i], "remove_diacritics") ){
+ if( (zArg[0]!='0' && zArg[0]!='1') || zArg[1] ){
+ rc = SQLITE_ERROR;
+ }
+ p->bRemoveDiacritic = (zArg[0]=='1');
+ }else
+ if( 0==sqlite3_stricmp(azArg[i], "tokenchars") ){
+ rc = fts5UnicodeAddExceptions(p, zArg, 1);
+ }else
+ if( 0==sqlite3_stricmp(azArg[i], "separators") ){
+ rc = fts5UnicodeAddExceptions(p, zArg, 0);
+ }else{
+ rc = SQLITE_ERROR;
+ }
+ }
+ }else{
+ rc = SQLITE_NOMEM;
+ }
+ if( rc!=SQLITE_OK ){
+ fts5UnicodeDelete((Fts5Tokenizer*)p);
+ p = 0;
+ }
+ *ppOut = (Fts5Tokenizer*)p;
+ }
+ return rc;
+}
+
+/*
+** Return true if, for the purposes of tokenizing with the tokenizer
+** passed as the first argument, codepoint iCode is considered a token
+** character (not a separator).
+*/
+static int fts5UnicodeIsAlnum(Unicode61Tokenizer *p, int iCode){
+ assert( (sqlite3Fts5UnicodeIsalnum(iCode) & 0xFFFFFFFE)==0 );
+ return sqlite3Fts5UnicodeIsalnum(iCode) ^ fts5UnicodeIsException(p, iCode);
+}
+
+static int fts5UnicodeTokenize(
+ Fts5Tokenizer *pTokenizer,
+ void *pCtx,
+ int flags,
+ const char *pText, int nText,
+ int (*xToken)(void*, int, const char*, int nToken, int iStart, int iEnd)
+){
+ Unicode61Tokenizer *p = (Unicode61Tokenizer*)pTokenizer;
+ int rc = SQLITE_OK;
+ unsigned char *a = p->aTokenChar;
+
+ unsigned char *zTerm = (unsigned char*)&pText[nText];
+ unsigned char *zCsr = (unsigned char *)pText;
+
+ /* Output buffer */
+ char *aFold = p->aFold;
+ int nFold = p->nFold;
+ const char *pEnd = &aFold[nFold-6];
+
+ /* Each iteration of this loop gobbles up a contiguous run of separators,
+ ** then the next token. */
+ while( rc==SQLITE_OK ){
+ int iCode; /* non-ASCII codepoint read from input */
+ char *zOut = aFold;
+ int is;
+ int ie;
+
+ /* Skip any separator characters. */
+ while( 1 ){
+ if( zCsr>=zTerm ) goto tokenize_done;
+ if( *zCsr & 0x80 ) {
+ /* A character outside of the ascii range. Skip past it if it is
+ ** a separator character. Or break out of the loop if it is not. */
+ is = zCsr - (unsigned char*)pText;
+ READ_UTF8(zCsr, zTerm, iCode);
+ if( fts5UnicodeIsAlnum(p, iCode) ){
+ goto non_ascii_tokenchar;
+ }
+ }else{
+ if( a[*zCsr] ){
+ is = zCsr - (unsigned char*)pText;
+ goto ascii_tokenchar;
+ }
+ zCsr++;
+ }
+ }
+
+ /* Run through the tokenchars. Fold them into the output buffer along
+ ** the way. */
+ while( zCsr<zTerm ){
+
+ /* Grow the output buffer so that there is sufficient space to fit the
+ ** largest possible utf-8 character. */
+ if( zOut>pEnd ){
+ aFold = sqlite3_malloc(nFold*2);
+ if( aFold==0 ){
+ rc = SQLITE_NOMEM;
+ goto tokenize_done;
+ }
+ zOut = &aFold[zOut - p->aFold];
+ memcpy(aFold, p->aFold, nFold);
+ sqlite3_free(p->aFold);
+ p->aFold = aFold;
+ p->nFold = nFold = nFold*2;
+ pEnd = &aFold[nFold-6];
+ }
+
+ if( *zCsr & 0x80 ){
+ /* An non-ascii-range character. Fold it into the output buffer if
+ ** it is a token character, or break out of the loop if it is not. */
+ READ_UTF8(zCsr, zTerm, iCode);
+ if( fts5UnicodeIsAlnum(p,iCode)||sqlite3Fts5UnicodeIsdiacritic(iCode) ){
+ non_ascii_tokenchar:
+ iCode = sqlite3Fts5UnicodeFold(iCode, p->bRemoveDiacritic);
+ if( iCode ) WRITE_UTF8(zOut, iCode);
+ }else{
+ break;
+ }
+ }else if( a[*zCsr]==0 ){
+ /* An ascii-range separator character. End of token. */
+ break;
+ }else{
+ ascii_tokenchar:
+ if( *zCsr>='A' && *zCsr<='Z' ){
+ *zOut++ = *zCsr + 32;
+ }else{
+ *zOut++ = *zCsr;
+ }
+ zCsr++;
+ }
+ ie = zCsr - (unsigned char*)pText;
+ }
+
+ /* Invoke the token callback */
+ rc = xToken(pCtx, 0, aFold, zOut-aFold, is, ie);
+ }
+
+ tokenize_done:
+ if( rc==SQLITE_DONE ) rc = SQLITE_OK;
+ return rc;
+}
+
+/**************************************************************************
+** Start of porter stemmer implementation.
+*/
+
+/* Any tokens larger than this (in bytes) are passed through without
+** stemming. */
+#define FTS5_PORTER_MAX_TOKEN 64
+
+typedef struct PorterTokenizer PorterTokenizer;
+struct PorterTokenizer {
+ fts5_tokenizer tokenizer; /* Parent tokenizer module */
+ Fts5Tokenizer *pTokenizer; /* Parent tokenizer instance */
+ char aBuf[FTS5_PORTER_MAX_TOKEN + 64];
+};
+
+/*
+** Delete a "porter" tokenizer.
+*/
+static void fts5PorterDelete(Fts5Tokenizer *pTok){
+ if( pTok ){
+ PorterTokenizer *p = (PorterTokenizer*)pTok;
+ if( p->pTokenizer ){
+ p->tokenizer.xDelete(p->pTokenizer);
+ }
+ sqlite3_free(p);
+ }
+}
+
+/*
+** Create a "porter" tokenizer.
+*/
+static int fts5PorterCreate(
+ void *pCtx,
+ const char **azArg, int nArg,
+ Fts5Tokenizer **ppOut
+){
+ fts5_api *pApi = (fts5_api*)pCtx;
+ int rc = SQLITE_OK;
+ PorterTokenizer *pRet;
+ void *pUserdata = 0;
+ const char *zBase = "unicode61";
+
+ if( nArg>0 ){
+ zBase = azArg[0];
+ }
+
+ pRet = (PorterTokenizer*)sqlite3_malloc(sizeof(PorterTokenizer));
+ if( pRet ){
+ memset(pRet, 0, sizeof(PorterTokenizer));
+ rc = pApi->xFindTokenizer(pApi, zBase, &pUserdata, &pRet->tokenizer);
+ }else{
+ rc = SQLITE_NOMEM;
+ }
+ if( rc==SQLITE_OK ){
+ int nArg2 = (nArg>0 ? nArg-1 : 0);
+ const char **azArg2 = (nArg2 ? &azArg[1] : 0);
+ rc = pRet->tokenizer.xCreate(pUserdata, azArg2, nArg2, &pRet->pTokenizer);
+ }
+
+ if( rc!=SQLITE_OK ){
+ fts5PorterDelete((Fts5Tokenizer*)pRet);
+ pRet = 0;
+ }
+ *ppOut = (Fts5Tokenizer*)pRet;
+ return rc;
+}
+
+typedef struct PorterContext PorterContext;
+struct PorterContext {
+ void *pCtx;
+ int (*xToken)(void*, int, const char*, int, int, int);
+ char *aBuf;
+};
+
+typedef struct PorterRule PorterRule;
+struct PorterRule {
+ const char *zSuffix;
+ int nSuffix;
+ int (*xCond)(char *zStem, int nStem);
+ const char *zOutput;
+ int nOutput;
+};
+
+#if 0
+static int fts5PorterApply(char *aBuf, int *pnBuf, PorterRule *aRule){
+ int ret = -1;
+ int nBuf = *pnBuf;
+ PorterRule *p;
+
+ for(p=aRule; p->zSuffix; p++){
+ assert( strlen(p->zSuffix)==p->nSuffix );
+ assert( strlen(p->zOutput)==p->nOutput );
+ if( nBuf<p->nSuffix ) continue;
+ if( 0==memcmp(&aBuf[nBuf - p->nSuffix], p->zSuffix, p->nSuffix) ) break;
+ }
+
+ if( p->zSuffix ){
+ int nStem = nBuf - p->nSuffix;
+ if( p->xCond==0 || p->xCond(aBuf, nStem) ){
+ memcpy(&aBuf[nStem], p->zOutput, p->nOutput);
+ *pnBuf = nStem + p->nOutput;
+ ret = p - aRule;
+ }
+ }
+
+ return ret;
+}
+#endif
+
+static int fts5PorterIsVowel(char c, int bYIsVowel){
+ return (
+ c=='a' || c=='e' || c=='i' || c=='o' || c=='u' || (bYIsVowel && c=='y')
+ );
+}
+
+static int fts5PorterGobbleVC(char *zStem, int nStem, int bPrevCons){
+ int i;
+ int bCons = bPrevCons;
+
+ /* Scan for a vowel */
+ for(i=0; i<nStem; i++){
+ if( 0==(bCons = !fts5PorterIsVowel(zStem[i], bCons)) ) break;
+ }
+
+ /* Scan for a consonent */
+ for(i++; i<nStem; i++){
+ if( (bCons = !fts5PorterIsVowel(zStem[i], bCons)) ) return i+1;
+ }
+ return 0;
+}
+
+/* porter rule condition: (m > 0) */
+static int fts5Porter_MGt0(char *zStem, int nStem){
+ return !!fts5PorterGobbleVC(zStem, nStem, 0);
+}
+
+/* porter rule condition: (m > 1) */
+static int fts5Porter_MGt1(char *zStem, int nStem){
+ int n;
+ n = fts5PorterGobbleVC(zStem, nStem, 0);
+ if( n && fts5PorterGobbleVC(&zStem[n], nStem-n, 1) ){
+ return 1;
+ }
+ return 0;
+}
+
+/* porter rule condition: (m = 1) */
+static int fts5Porter_MEq1(char *zStem, int nStem){
+ int n;
+ n = fts5PorterGobbleVC(zStem, nStem, 0);
+ if( n && 0==fts5PorterGobbleVC(&zStem[n], nStem-n, 1) ){
+ return 1;
+ }
+ return 0;
+}
+
+/* porter rule condition: (*o) */
+static int fts5Porter_Ostar(char *zStem, int nStem){
+ if( zStem[nStem-1]=='w' || zStem[nStem-1]=='x' || zStem[nStem-1]=='y' ){
+ return 0;
+ }else{
+ int i;
+ int mask = 0;
+ int bCons = 0;
+ for(i=0; i<nStem; i++){
+ bCons = !fts5PorterIsVowel(zStem[i], bCons);
+ assert( bCons==0 || bCons==1 );
+ mask = (mask << 1) + bCons;
+ }
+ return ((mask & 0x0007)==0x0005);
+ }
+}
+
+/* porter rule condition: (m > 1 and (*S or *T)) */
+static int fts5Porter_MGt1_and_S_or_T(char *zStem, int nStem){
+ assert( nStem>0 );
+ return (zStem[nStem-1]=='s' || zStem[nStem-1]=='t')
+ && fts5Porter_MGt1(zStem, nStem);
+}
+
+/* porter rule condition: (*v*) */
+static int fts5Porter_Vowel(char *zStem, int nStem){
+ int i;
+ for(i=0; i<nStem; i++){
+ if( fts5PorterIsVowel(zStem[i], i>0) ){
+ return 1;
+ }
+ }
+ return 0;
+}
+
+
+/**************************************************************************
+***************************************************************************
+** GENERATED CODE STARTS HERE (mkportersteps.tcl)
+*/
+
+static int fts5PorterStep4(char *aBuf, int *pnBuf){
+ int ret = 0;
+ int nBuf = *pnBuf;
+ switch( aBuf[nBuf-2] ){
+
+ case 'a':
+ if( nBuf>2 && 0==memcmp("al", &aBuf[nBuf-2], 2) ){
+ if( fts5Porter_MGt1(aBuf, nBuf-2) ){
+ *pnBuf = nBuf - 2;
+ }
+ }
+ break;
+
+ case 'c':
+ if( nBuf>4 && 0==memcmp("ance", &aBuf[nBuf-4], 4) ){
+ if( fts5Porter_MGt1(aBuf, nBuf-4) ){
+ *pnBuf = nBuf - 4;
+ }
+ }else if( nBuf>4 && 0==memcmp("ence", &aBuf[nBuf-4], 4) ){
+ if( fts5Porter_MGt1(aBuf, nBuf-4) ){
+ *pnBuf = nBuf - 4;
+ }
+ }
+ break;
+
+ case 'e':
+ if( nBuf>2 && 0==memcmp("er", &aBuf[nBuf-2], 2) ){
+ if( fts5Porter_MGt1(aBuf, nBuf-2) ){
+ *pnBuf = nBuf - 2;
+ }
+ }
+ break;
+
+ case 'i':
+ if( nBuf>2 && 0==memcmp("ic", &aBuf[nBuf-2], 2) ){
+ if( fts5Porter_MGt1(aBuf, nBuf-2) ){
+ *pnBuf = nBuf - 2;
+ }
+ }
+ break;
+
+ case 'l':
+ if( nBuf>4 && 0==memcmp("able", &aBuf[nBuf-4], 4) ){
+ if( fts5Porter_MGt1(aBuf, nBuf-4) ){
+ *pnBuf = nBuf - 4;
+ }
+ }else if( nBuf>4 && 0==memcmp("ible", &aBuf[nBuf-4], 4) ){
+ if( fts5Porter_MGt1(aBuf, nBuf-4) ){
+ *pnBuf = nBuf - 4;
+ }
+ }
+ break;
+
+ case 'n':
+ if( nBuf>3 && 0==memcmp("ant", &aBuf[nBuf-3], 3) ){
+ if( fts5Porter_MGt1(aBuf, nBuf-3) ){
+ *pnBuf = nBuf - 3;
+ }
+ }else if( nBuf>5 && 0==memcmp("ement", &aBuf[nBuf-5], 5) ){
+ if( fts5Porter_MGt1(aBuf, nBuf-5) ){
+ *pnBuf = nBuf - 5;
+ }
+ }else if( nBuf>4 && 0==memcmp("ment", &aBuf[nBuf-4], 4) ){
+ if( fts5Porter_MGt1(aBuf, nBuf-4) ){
+ *pnBuf = nBuf - 4;
+ }
+ }else if( nBuf>3 && 0==memcmp("ent", &aBuf[nBuf-3], 3) ){
+ if( fts5Porter_MGt1(aBuf, nBuf-3) ){
+ *pnBuf = nBuf - 3;
+ }
+ }
+ break;
+
+ case 'o':
+ if( nBuf>3 && 0==memcmp("ion", &aBuf[nBuf-3], 3) ){
+ if( fts5Porter_MGt1_and_S_or_T(aBuf, nBuf-3) ){
+ *pnBuf = nBuf - 3;
+ }
+ }else if( nBuf>2 && 0==memcmp("ou", &aBuf[nBuf-2], 2) ){
+ if( fts5Porter_MGt1(aBuf, nBuf-2) ){
+ *pnBuf = nBuf - 2;
+ }
+ }
+ break;
+
+ case 's':
+ if( nBuf>3 && 0==memcmp("ism", &aBuf[nBuf-3], 3) ){
+ if( fts5Porter_MGt1(aBuf, nBuf-3) ){
+ *pnBuf = nBuf - 3;
+ }
+ }
+ break;
+
+ case 't':
+ if( nBuf>3 && 0==memcmp("ate", &aBuf[nBuf-3], 3) ){
+ if( fts5Porter_MGt1(aBuf, nBuf-3) ){
+ *pnBuf = nBuf - 3;
+ }
+ }else if( nBuf>3 && 0==memcmp("iti", &aBuf[nBuf-3], 3) ){
+ if( fts5Porter_MGt1(aBuf, nBuf-3) ){
+ *pnBuf = nBuf - 3;
+ }
+ }
+ break;
+
+ case 'u':
+ if( nBuf>3 && 0==memcmp("ous", &aBuf[nBuf-3], 3) ){
+ if( fts5Porter_MGt1(aBuf, nBuf-3) ){
+ *pnBuf = nBuf - 3;
+ }
+ }
+ break;
+
+ case 'v':
+ if( nBuf>3 && 0==memcmp("ive", &aBuf[nBuf-3], 3) ){
+ if( fts5Porter_MGt1(aBuf, nBuf-3) ){
+ *pnBuf = nBuf - 3;
+ }
+ }
+ break;
+
+ case 'z':
+ if( nBuf>3 && 0==memcmp("ize", &aBuf[nBuf-3], 3) ){
+ if( fts5Porter_MGt1(aBuf, nBuf-3) ){
+ *pnBuf = nBuf - 3;
+ }
+ }
+ break;
+
+ }
+ return ret;
+}
+
+
+static int fts5PorterStep1B2(char *aBuf, int *pnBuf){
+ int ret = 0;
+ int nBuf = *pnBuf;
+ switch( aBuf[nBuf-2] ){
+
+ case 'a':
+ if( nBuf>2 && 0==memcmp("at", &aBuf[nBuf-2], 2) ){
+ memcpy(&aBuf[nBuf-2], "ate", 3);
+ *pnBuf = nBuf - 2 + 3;
+ ret = 1;
+ }
+ break;
+
+ case 'b':
+ if( nBuf>2 && 0==memcmp("bl", &aBuf[nBuf-2], 2) ){
+ memcpy(&aBuf[nBuf-2], "ble", 3);
+ *pnBuf = nBuf - 2 + 3;
+ ret = 1;
+ }
+ break;
+
+ case 'i':
+ if( nBuf>2 && 0==memcmp("iz", &aBuf[nBuf-2], 2) ){
+ memcpy(&aBuf[nBuf-2], "ize", 3);
+ *pnBuf = nBuf - 2 + 3;
+ ret = 1;
+ }
+ break;
+
+ }
+ return ret;
+}
+
+
+static int fts5PorterStep2(char *aBuf, int *pnBuf){
+ int ret = 0;
+ int nBuf = *pnBuf;
+ switch( aBuf[nBuf-2] ){
+
+ case 'a':
+ if( nBuf>7 && 0==memcmp("ational", &aBuf[nBuf-7], 7) ){
+ if( fts5Porter_MGt0(aBuf, nBuf-7) ){
+ memcpy(&aBuf[nBuf-7], "ate", 3);
+ *pnBuf = nBuf - 7 + 3;
+ }
+ }else if( nBuf>6 && 0==memcmp("tional", &aBuf[nBuf-6], 6) ){
+ if( fts5Porter_MGt0(aBuf, nBuf-6) ){
+ memcpy(&aBuf[nBuf-6], "tion", 4);
+ *pnBuf = nBuf - 6 + 4;
+ }
+ }
+ break;
+
+ case 'c':
+ if( nBuf>4 && 0==memcmp("enci", &aBuf[nBuf-4], 4) ){
+ if( fts5Porter_MGt0(aBuf, nBuf-4) ){
+ memcpy(&aBuf[nBuf-4], "ence", 4);
+ *pnBuf = nBuf - 4 + 4;
+ }
+ }else if( nBuf>4 && 0==memcmp("anci", &aBuf[nBuf-4], 4) ){
+ if( fts5Porter_MGt0(aBuf, nBuf-4) ){
+ memcpy(&aBuf[nBuf-4], "ance", 4);
+ *pnBuf = nBuf - 4 + 4;
+ }
+ }
+ break;
+
+ case 'e':
+ if( nBuf>4 && 0==memcmp("izer", &aBuf[nBuf-4], 4) ){
+ if( fts5Porter_MGt0(aBuf, nBuf-4) ){
+ memcpy(&aBuf[nBuf-4], "ize", 3);
+ *pnBuf = nBuf - 4 + 3;
+ }
+ }
+ break;
+
+ case 'g':
+ if( nBuf>4 && 0==memcmp("logi", &aBuf[nBuf-4], 4) ){
+ if( fts5Porter_MGt0(aBuf, nBuf-4) ){
+ memcpy(&aBuf[nBuf-4], "log", 3);
+ *pnBuf = nBuf - 4 + 3;
+ }
+ }
+ break;
+
+ case 'l':
+ if( nBuf>3 && 0==memcmp("bli", &aBuf[nBuf-3], 3) ){
+ if( fts5Porter_MGt0(aBuf, nBuf-3) ){
+ memcpy(&aBuf[nBuf-3], "ble", 3);
+ *pnBuf = nBuf - 3 + 3;
+ }
+ }else if( nBuf>4 && 0==memcmp("alli", &aBuf[nBuf-4], 4) ){
+ if( fts5Porter_MGt0(aBuf, nBuf-4) ){
+ memcpy(&aBuf[nBuf-4], "al", 2);
+ *pnBuf = nBuf - 4 + 2;
+ }
+ }else if( nBuf>5 && 0==memcmp("entli", &aBuf[nBuf-5], 5) ){
+ if( fts5Porter_MGt0(aBuf, nBuf-5) ){
+ memcpy(&aBuf[nBuf-5], "ent", 3);
+ *pnBuf = nBuf - 5 + 3;
+ }
+ }else if( nBuf>3 && 0==memcmp("eli", &aBuf[nBuf-3], 3) ){
+ if( fts5Porter_MGt0(aBuf, nBuf-3) ){
+ memcpy(&aBuf[nBuf-3], "e", 1);
+ *pnBuf = nBuf - 3 + 1;
+ }
+ }else if( nBuf>5 && 0==memcmp("ousli", &aBuf[nBuf-5], 5) ){
+ if( fts5Porter_MGt0(aBuf, nBuf-5) ){
+ memcpy(&aBuf[nBuf-5], "ous", 3);
+ *pnBuf = nBuf - 5 + 3;
+ }
+ }
+ break;
+
+ case 'o':
+ if( nBuf>7 && 0==memcmp("ization", &aBuf[nBuf-7], 7) ){
+ if( fts5Porter_MGt0(aBuf, nBuf-7) ){
+ memcpy(&aBuf[nBuf-7], "ize", 3);
+ *pnBuf = nBuf - 7 + 3;
+ }
+ }else if( nBuf>5 && 0==memcmp("ation", &aBuf[nBuf-5], 5) ){
+ if( fts5Porter_MGt0(aBuf, nBuf-5) ){
+ memcpy(&aBuf[nBuf-5], "ate", 3);
+ *pnBuf = nBuf - 5 + 3;
+ }
+ }else if( nBuf>4 && 0==memcmp("ator", &aBuf[nBuf-4], 4) ){
+ if( fts5Porter_MGt0(aBuf, nBuf-4) ){
+ memcpy(&aBuf[nBuf-4], "ate", 3);
+ *pnBuf = nBuf - 4 + 3;
+ }
+ }
+ break;
+
+ case 's':
+ if( nBuf>5 && 0==memcmp("alism", &aBuf[nBuf-5], 5) ){
+ if( fts5Porter_MGt0(aBuf, nBuf-5) ){
+ memcpy(&aBuf[nBuf-5], "al", 2);
+ *pnBuf = nBuf - 5 + 2;
+ }
+ }else if( nBuf>7 && 0==memcmp("iveness", &aBuf[nBuf-7], 7) ){
+ if( fts5Porter_MGt0(aBuf, nBuf-7) ){
+ memcpy(&aBuf[nBuf-7], "ive", 3);
+ *pnBuf = nBuf - 7 + 3;
+ }
+ }else if( nBuf>7 && 0==memcmp("fulness", &aBuf[nBuf-7], 7) ){
+ if( fts5Porter_MGt0(aBuf, nBuf-7) ){
+ memcpy(&aBuf[nBuf-7], "ful", 3);
+ *pnBuf = nBuf - 7 + 3;
+ }
+ }else if( nBuf>7 && 0==memcmp("ousness", &aBuf[nBuf-7], 7) ){
+ if( fts5Porter_MGt0(aBuf, nBuf-7) ){
+ memcpy(&aBuf[nBuf-7], "ous", 3);
+ *pnBuf = nBuf - 7 + 3;
+ }
+ }
+ break;
+
+ case 't':
+ if( nBuf>5 && 0==memcmp("aliti", &aBuf[nBuf-5], 5) ){
+ if( fts5Porter_MGt0(aBuf, nBuf-5) ){
+ memcpy(&aBuf[nBuf-5], "al", 2);
+ *pnBuf = nBuf - 5 + 2;
+ }
+ }else if( nBuf>5 && 0==memcmp("iviti", &aBuf[nBuf-5], 5) ){
+ if( fts5Porter_MGt0(aBuf, nBuf-5) ){
+ memcpy(&aBuf[nBuf-5], "ive", 3);
+ *pnBuf = nBuf - 5 + 3;
+ }
+ }else if( nBuf>6 && 0==memcmp("biliti", &aBuf[nBuf-6], 6) ){
+ if( fts5Porter_MGt0(aBuf, nBuf-6) ){
+ memcpy(&aBuf[nBuf-6], "ble", 3);
+ *pnBuf = nBuf - 6 + 3;
+ }
+ }
+ break;
+
+ }
+ return ret;
+}
+
+
+static int fts5PorterStep3(char *aBuf, int *pnBuf){
+ int ret = 0;
+ int nBuf = *pnBuf;
+ switch( aBuf[nBuf-2] ){
+
+ case 'a':
+ if( nBuf>4 && 0==memcmp("ical", &aBuf[nBuf-4], 4) ){
+ if( fts5Porter_MGt0(aBuf, nBuf-4) ){
+ memcpy(&aBuf[nBuf-4], "ic", 2);
+ *pnBuf = nBuf - 4 + 2;
+ }
+ }
+ break;
+
+ case 's':
+ if( nBuf>4 && 0==memcmp("ness", &aBuf[nBuf-4], 4) ){
+ if( fts5Porter_MGt0(aBuf, nBuf-4) ){
+ *pnBuf = nBuf - 4;
+ }
+ }
+ break;
+
+ case 't':
+ if( nBuf>5 && 0==memcmp("icate", &aBuf[nBuf-5], 5) ){
+ if( fts5Porter_MGt0(aBuf, nBuf-5) ){
+ memcpy(&aBuf[nBuf-5], "ic", 2);
+ *pnBuf = nBuf - 5 + 2;
+ }
+ }else if( nBuf>5 && 0==memcmp("iciti", &aBuf[nBuf-5], 5) ){
+ if( fts5Porter_MGt0(aBuf, nBuf-5) ){
+ memcpy(&aBuf[nBuf-5], "ic", 2);
+ *pnBuf = nBuf - 5 + 2;
+ }
+ }
+ break;
+
+ case 'u':
+ if( nBuf>3 && 0==memcmp("ful", &aBuf[nBuf-3], 3) ){
+ if( fts5Porter_MGt0(aBuf, nBuf-3) ){
+ *pnBuf = nBuf - 3;
+ }
+ }
+ break;
+
+ case 'v':
+ if( nBuf>5 && 0==memcmp("ative", &aBuf[nBuf-5], 5) ){
+ if( fts5Porter_MGt0(aBuf, nBuf-5) ){
+ *pnBuf = nBuf - 5;
+ }
+ }
+ break;
+
+ case 'z':
+ if( nBuf>5 && 0==memcmp("alize", &aBuf[nBuf-5], 5) ){
+ if( fts5Porter_MGt0(aBuf, nBuf-5) ){
+ memcpy(&aBuf[nBuf-5], "al", 2);
+ *pnBuf = nBuf - 5 + 2;
+ }
+ }
+ break;
+
+ }
+ return ret;
+}
+
+
+static int fts5PorterStep1B(char *aBuf, int *pnBuf){
+ int ret = 0;
+ int nBuf = *pnBuf;
+ switch( aBuf[nBuf-2] ){
+
+ case 'e':
+ if( nBuf>3 && 0==memcmp("eed", &aBuf[nBuf-3], 3) ){
+ if( fts5Porter_MGt0(aBuf, nBuf-3) ){
+ memcpy(&aBuf[nBuf-3], "ee", 2);
+ *pnBuf = nBuf - 3 + 2;
+ }
+ }else if( nBuf>2 && 0==memcmp("ed", &aBuf[nBuf-2], 2) ){
+ if( fts5Porter_Vowel(aBuf, nBuf-2) ){
+ *pnBuf = nBuf - 2;
+ ret = 1;
+ }
+ }
+ break;
+
+ case 'n':
+ if( nBuf>3 && 0==memcmp("ing", &aBuf[nBuf-3], 3) ){
+ if( fts5Porter_Vowel(aBuf, nBuf-3) ){
+ *pnBuf = nBuf - 3;
+ ret = 1;
+ }
+ }
+ break;
+
+ }
+ return ret;
+}
+
+/*
+** GENERATED CODE ENDS HERE (mkportersteps.tcl)
+***************************************************************************
+**************************************************************************/
+
+static void fts5PorterStep1A(char *aBuf, int *pnBuf){
+ int nBuf = *pnBuf;
+ if( aBuf[nBuf-1]=='s' ){
+ if( aBuf[nBuf-2]=='e' ){
+ if( (nBuf>4 && aBuf[nBuf-4]=='s' && aBuf[nBuf-3]=='s')
+ || (nBuf>3 && aBuf[nBuf-3]=='i' )
+ ){
+ *pnBuf = nBuf-2;
+ }else{
+ *pnBuf = nBuf-1;
+ }
+ }
+ else if( aBuf[nBuf-2]!='s' ){
+ *pnBuf = nBuf-1;
+ }
+ }
+}
+
+static int fts5PorterCb(
+ void *pCtx,
+ int tflags,
+ const char *pToken,
+ int nToken,
+ int iStart,
+ int iEnd
+){
+ PorterContext *p = (PorterContext*)pCtx;
+
+ char *aBuf;
+ int nBuf;
+
+ if( nToken>FTS5_PORTER_MAX_TOKEN || nToken<3 ) goto pass_through;
+ aBuf = p->aBuf;
+ nBuf = nToken;
+ memcpy(aBuf, pToken, nBuf);
+
+ /* Step 1. */
+ fts5PorterStep1A(aBuf, &nBuf);
+ if( fts5PorterStep1B(aBuf, &nBuf) ){
+ if( fts5PorterStep1B2(aBuf, &nBuf)==0 ){
+ char c = aBuf[nBuf-1];
+ if( fts5PorterIsVowel(c, 0)==0
+ && c!='l' && c!='s' && c!='z' && c==aBuf[nBuf-2]
+ ){
+ nBuf--;
+ }else if( fts5Porter_MEq1(aBuf, nBuf) && fts5Porter_Ostar(aBuf, nBuf) ){
+ aBuf[nBuf++] = 'e';
+ }
+ }
+ }
+
+ /* Step 1C. */
+ if( aBuf[nBuf-1]=='y' && fts5Porter_Vowel(aBuf, nBuf-1) ){
+ aBuf[nBuf-1] = 'i';
+ }
+
+ /* Steps 2 through 4. */
+ fts5PorterStep2(aBuf, &nBuf);
+ fts5PorterStep3(aBuf, &nBuf);
+ fts5PorterStep4(aBuf, &nBuf);
+
+ /* Step 5a. */
+ assert( nBuf>0 );
+ if( aBuf[nBuf-1]=='e' ){
+ if( fts5Porter_MGt1(aBuf, nBuf-1)
+ || (fts5Porter_MEq1(aBuf, nBuf-1) && !fts5Porter_Ostar(aBuf, nBuf-1))
+ ){
+ nBuf--;
+ }
+ }
+
+ /* Step 5b. */
+ if( nBuf>1 && aBuf[nBuf-1]=='l'
+ && aBuf[nBuf-2]=='l' && fts5Porter_MGt1(aBuf, nBuf-1)
+ ){
+ nBuf--;
+ }
+
+ return p->xToken(p->pCtx, tflags, aBuf, nBuf, iStart, iEnd);
+
+ pass_through:
+ return p->xToken(p->pCtx, tflags, pToken, nToken, iStart, iEnd);
+}
+
+/*
+** Tokenize using the porter tokenizer.
+*/
+static int fts5PorterTokenize(
+ Fts5Tokenizer *pTokenizer,
+ void *pCtx,
+ int flags,
+ const char *pText, int nText,
+ int (*xToken)(void*, int, const char*, int nToken, int iStart, int iEnd)
+){
+ PorterTokenizer *p = (PorterTokenizer*)pTokenizer;
+ PorterContext sCtx;
+ sCtx.xToken = xToken;
+ sCtx.pCtx = pCtx;
+ sCtx.aBuf = p->aBuf;
+ return p->tokenizer.xTokenize(
+ p->pTokenizer, (void*)&sCtx, flags, pText, nText, fts5PorterCb
+ );
+}
+
+/*
+** Register all built-in tokenizers with FTS5.
+*/
+static int sqlite3Fts5TokenizerInit(fts5_api *pApi){
+ struct BuiltinTokenizer {
+ const char *zName;
+ fts5_tokenizer x;
+ } aBuiltin[] = {
+ { "unicode61", {fts5UnicodeCreate, fts5UnicodeDelete, fts5UnicodeTokenize}},
+ { "ascii", {fts5AsciiCreate, fts5AsciiDelete, fts5AsciiTokenize }},
+ { "porter", {fts5PorterCreate, fts5PorterDelete, fts5PorterTokenize }},
+ };
+
+ int rc = SQLITE_OK; /* Return code */
+ int i; /* To iterate through builtin functions */
+
+ for(i=0; rc==SQLITE_OK && i<(int)ArraySize(aBuiltin); i++){
+ rc = pApi->xCreateTokenizer(pApi,
+ aBuiltin[i].zName,
+ (void*)pApi,
+ &aBuiltin[i].x,
+ 0
+ );
+ }
+
+ return rc;
+}
+
+
+
+/*
+** 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.
+*/
+
+
+/* #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.
+*/
+static int sqlite3Fts5UnicodeIsalnum(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.
+ */
+ static const 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,
+ 0x037FFC01, 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,
+ };
+ 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 = 0;
+ 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 fts5_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.
+*/
+static int sqlite3Fts5UnicodeIsdiacritic(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.
+*/
+static int sqlite3Fts5UnicodeFold(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( sizeof(unsigned short)==2 && sizeof(unsigned char)==1 );
+
+ if( c<128 ){
+ if( c>='A' && c<='Z' ) ret = c + ('a' - 'A');
+ }else if( c<65536 ){
+ const struct TableEntry *p;
+ int iHi = sizeof(aEntry)/sizeof(aEntry[0]) - 1;
+ int iLo = 0;
+ int iRes = -1;
+
+ assert( c>aEntry[0].iCode );
+ 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 );
+ 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 = fts5_remove_diacritic(ret);
+ }
+
+ else if( c>=66560 && c<66600 ){
+ ret = c + 40;
+ }
+
+ return ret;
+}
+
+/*
+** 2015 May 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.
+**
+******************************************************************************
+**
+** Routines for varint serialization and deserialization.
+*/
+
+
+/* #include "fts5Int.h" */
+
+/*
+** This is a copy of the sqlite3GetVarint32() routine from the SQLite core.
+** Except, this version does handle the single byte case that the core
+** version depends on being handled before its function is called.
+*/
+static int sqlite3Fts5GetVarint32(const unsigned char *p, u32 *v){
+ u32 a,b;
+
+ /* The 1-byte case. Overwhelmingly the most common. */
+ a = *p;
+ /* a: p0 (unmasked) */
+ if (!(a&0x80))
+ {
+ /* Values between 0 and 127 */
+ *v = a;
+ return 1;
+ }
+
+ /* 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.
+ */
+ {
+ u64 v64;
+ u8 n;
+ p -= 2;
+ n = sqlite3Fts5GetVarint(p, &v64);
+ *v = (u32)v64;
+ assert( n>3 && n<=9 );
+ return n;
+ }
+}
+
+
+/*
+** 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.
+*/
+static u8 sqlite3Fts5GetVarint(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;
+}
+
+/*
+** 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
+*/
+
+#ifdef SQLITE_NOINLINE
+# define FTS5_NOINLINE SQLITE_NOINLINE
+#else
+# define FTS5_NOINLINE
+#endif
+
+/*
+** 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.
+*/
+static int FTS5_NOINLINE fts5PutVarint64(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;
+}
+
+static int sqlite3Fts5PutVarint(unsigned char *p, u64 v){
+ if( v<=0x7f ){
+ p[0] = v&0x7f;
+ return 1;
+ }
+ if( v<=0x3fff ){
+ p[0] = ((v>>7)&0x7f)|0x80;
+ p[1] = v&0x7f;
+ return 2;
+ }
+ return fts5PutVarint64(p,v);
+}
+
+
+static int sqlite3Fts5GetVarintLen(u32 iVal){
+ if( iVal<(1 << 7 ) ) return 1;
+ if( iVal<(1 << 14) ) return 2;
+ if( iVal<(1 << 21) ) return 3;
+ if( iVal<(1 << 28) ) return 4;
+ return 5;
+}
+
+
+/*
+** 2015 May 08
+**
+** 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 virtual table module implementing direct access to an
+** existing FTS5 index. The module may create several different types of
+** tables:
+**
+** col:
+** CREATE TABLE vocab(term, col, doc, cnt, PRIMARY KEY(term, col));
+**
+** One row for each term/column combination. The value of $doc is set to
+** the number of fts5 rows that contain at least one instance of term
+** $term within column $col. Field $cnt is set to the total number of
+** instances of term $term in column $col (in any row of the fts5 table).
+**
+** row:
+** CREATE TABLE vocab(term, doc, cnt, PRIMARY KEY(term));
+**
+** One row for each term in the database. The value of $doc is set to
+** the number of fts5 rows that contain at least one instance of term
+** $term. Field $cnt is set to the total number of instances of term
+** $term in the database.
+*/
+
+
+/* #include "fts5Int.h" */
+
+
+typedef struct Fts5VocabTable Fts5VocabTable;
+typedef struct Fts5VocabCursor Fts5VocabCursor;
+
+struct Fts5VocabTable {
+ sqlite3_vtab base;
+ char *zFts5Tbl; /* Name of fts5 table */
+ char *zFts5Db; /* Db containing fts5 table */
+ sqlite3 *db; /* Database handle */
+ Fts5Global *pGlobal; /* FTS5 global object for this database */
+ int eType; /* FTS5_VOCAB_COL or ROW */
+};
+
+struct Fts5VocabCursor {
+ sqlite3_vtab_cursor base;
+ sqlite3_stmt *pStmt; /* Statement holding lock on pIndex */
+ Fts5Index *pIndex; /* Associated FTS5 index */
+
+ int bEof; /* True if this cursor is at EOF */
+ Fts5IndexIter *pIter; /* Term/rowid iterator object */
+
+ int nLeTerm; /* Size of zLeTerm in bytes */
+ char *zLeTerm; /* (term <= $zLeTerm) paramater, or NULL */
+
+ /* These are used by 'col' tables only */
+ Fts5Config *pConfig; /* Fts5 table configuration */
+ int iCol;
+ i64 *aCnt;
+ i64 *aDoc;
+
+ /* Output values used by 'row' and 'col' tables */
+ i64 rowid; /* This table's current rowid value */
+ Fts5Buffer term; /* Current value of 'term' column */
+};
+
+#define FTS5_VOCAB_COL 0
+#define FTS5_VOCAB_ROW 1
+
+#define FTS5_VOCAB_COL_SCHEMA "term, col, doc, cnt"
+#define FTS5_VOCAB_ROW_SCHEMA "term, doc, cnt"
+
+/*
+** Bits for the mask used as the idxNum value by xBestIndex/xFilter.
+*/
+#define FTS5_VOCAB_TERM_EQ 0x01
+#define FTS5_VOCAB_TERM_GE 0x02
+#define FTS5_VOCAB_TERM_LE 0x04
+
+
+/*
+** Translate a string containing an fts5vocab table type to an
+** FTS5_VOCAB_XXX constant. If successful, set *peType to the output
+** value and return SQLITE_OK. Otherwise, set *pzErr to an error message
+** and return SQLITE_ERROR.
+*/
+static int fts5VocabTableType(const char *zType, char **pzErr, int *peType){
+ int rc = SQLITE_OK;
+ char *zCopy = sqlite3Fts5Strndup(&rc, zType, -1);
+ if( rc==SQLITE_OK ){
+ sqlite3Fts5Dequote(zCopy);
+ if( sqlite3_stricmp(zCopy, "col")==0 ){
+ *peType = FTS5_VOCAB_COL;
+ }else
+
+ if( sqlite3_stricmp(zCopy, "row")==0 ){
+ *peType = FTS5_VOCAB_ROW;
+ }else
+ {
+ *pzErr = sqlite3_mprintf("fts5vocab: unknown table type: %Q", zCopy);
+ rc = SQLITE_ERROR;
+ }
+ sqlite3_free(zCopy);
+ }
+
+ return rc;
+}
+
+
+/*
+** The xDisconnect() virtual table method.
+*/
+static int fts5VocabDisconnectMethod(sqlite3_vtab *pVtab){
+ Fts5VocabTable *pTab = (Fts5VocabTable*)pVtab;
+ sqlite3_free(pTab);
+ return SQLITE_OK;
+}
+
+/*
+** The xDestroy() virtual table method.
+*/
+static int fts5VocabDestroyMethod(sqlite3_vtab *pVtab){
+ Fts5VocabTable *pTab = (Fts5VocabTable*)pVtab;
+ sqlite3_free(pTab);
+ return SQLITE_OK;
+}
+
+/*
+** 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 ("fts5vocab")
+** argv[1] -> database name
+** argv[2] -> table name
+**
+** then:
+**
+** argv[3] -> name of fts5 table
+** argv[4] -> type of fts5vocab table
+**
+** or, for tables in the TEMP schema only.
+**
+** argv[3] -> name of fts5 tables database
+** argv[4] -> name of fts5 table
+** argv[5] -> type of fts5vocab table
+*/
+static int fts5VocabInitVtab(
+ sqlite3 *db, /* The SQLite database connection */
+ void *pAux, /* Pointer to Fts5Global object */
+ 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 */
+){
+ const char *azSchema[] = {
+ "CREATE TABlE vocab(" FTS5_VOCAB_COL_SCHEMA ")",
+ "CREATE TABlE vocab(" FTS5_VOCAB_ROW_SCHEMA ")"
+ };
+
+ Fts5VocabTable *pRet = 0;
+ int rc = SQLITE_OK; /* Return code */
+ int bDb;
+
+ bDb = (argc==6 && strlen(argv[1])==4 && memcmp("temp", argv[1], 4)==0);
+
+ if( argc!=5 && bDb==0 ){
+ *pzErr = sqlite3_mprintf("wrong number of vtable arguments");
+ rc = SQLITE_ERROR;
+ }else{
+ int nByte; /* Bytes of space to allocate */
+ const char *zDb = bDb ? argv[3] : argv[1];
+ const char *zTab = bDb ? argv[4] : argv[3];
+ const char *zType = bDb ? argv[5] : argv[4];
+ int nDb = (int)strlen(zDb)+1;
+ int nTab = (int)strlen(zTab)+1;
+ int eType = 0;
+
+ rc = fts5VocabTableType(zType, pzErr, &eType);
+ if( rc==SQLITE_OK ){
+ assert( eType>=0 && eType<sizeof(azSchema)/sizeof(azSchema[0]) );
+ rc = sqlite3_declare_vtab(db, azSchema[eType]);
+ }
+
+ nByte = sizeof(Fts5VocabTable) + nDb + nTab;
+ pRet = sqlite3Fts5MallocZero(&rc, nByte);
+ if( pRet ){
+ pRet->pGlobal = (Fts5Global*)pAux;
+ pRet->eType = eType;
+ pRet->db = db;
+ pRet->zFts5Tbl = (char*)&pRet[1];
+ pRet->zFts5Db = &pRet->zFts5Tbl[nTab];
+ memcpy(pRet->zFts5Tbl, zTab, nTab);
+ memcpy(pRet->zFts5Db, zDb, nDb);
+ sqlite3Fts5Dequote(pRet->zFts5Tbl);
+ sqlite3Fts5Dequote(pRet->zFts5Db);
+ }
+ }
+
+ *ppVTab = (sqlite3_vtab*)pRet;
+ return rc;
+}
+
+
+/*
+** The xConnect() and xCreate() methods for the virtual table. All the
+** work is done in function fts5VocabInitVtab().
+*/
+static int fts5VocabConnectMethod(
+ 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 fts5VocabInitVtab(db, pAux, argc, argv, ppVtab, pzErr);
+}
+static int fts5VocabCreateMethod(
+ 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 fts5VocabInitVtab(db, pAux, argc, argv, ppVtab, pzErr);
+}
+
+/*
+** Implementation of the xBestIndex method.
+*/
+static int fts5VocabBestIndexMethod(
+ sqlite3_vtab *pVTab,
+ sqlite3_index_info *pInfo
+){
+ int i;
+ int iTermEq = -1;
+ int iTermGe = -1;
+ int iTermLe = -1;
+ int idxNum = 0;
+ int nArg = 0;
+
+ for(i=0; i<pInfo->nConstraint; i++){
+ struct sqlite3_index_constraint *p = &pInfo->aConstraint[i];
+ if( p->usable==0 ) continue;
+ if( p->iColumn==0 ){ /* term column */
+ if( p->op==SQLITE_INDEX_CONSTRAINT_EQ ) iTermEq = i;
+ if( p->op==SQLITE_INDEX_CONSTRAINT_LE ) iTermLe = i;
+ if( p->op==SQLITE_INDEX_CONSTRAINT_LT ) iTermLe = i;
+ if( p->op==SQLITE_INDEX_CONSTRAINT_GE ) iTermGe = i;
+ if( p->op==SQLITE_INDEX_CONSTRAINT_GT ) iTermGe = i;
+ }
+ }
+
+ if( iTermEq>=0 ){
+ idxNum |= FTS5_VOCAB_TERM_EQ;
+ pInfo->aConstraintUsage[iTermEq].argvIndex = ++nArg;
+ pInfo->estimatedCost = 100;
+ }else{
+ pInfo->estimatedCost = 1000000;
+ if( iTermGe>=0 ){
+ idxNum |= FTS5_VOCAB_TERM_GE;
+ pInfo->aConstraintUsage[iTermGe].argvIndex = ++nArg;
+ pInfo->estimatedCost = pInfo->estimatedCost / 2;
+ }
+ if( iTermLe>=0 ){
+ idxNum |= FTS5_VOCAB_TERM_LE;
+ pInfo->aConstraintUsage[iTermLe].argvIndex = ++nArg;
+ pInfo->estimatedCost = pInfo->estimatedCost / 2;
+ }
+ }
+
+ pInfo->idxNum = idxNum;
+
+ return SQLITE_OK;
+}
+
+/*
+** Implementation of xOpen method.
+*/
+static int fts5VocabOpenMethod(
+ sqlite3_vtab *pVTab,
+ sqlite3_vtab_cursor **ppCsr
+){
+ Fts5VocabTable *pTab = (Fts5VocabTable*)pVTab;
+ Fts5Index *pIndex = 0;
+ Fts5Config *pConfig = 0;
+ Fts5VocabCursor *pCsr = 0;
+ int rc = SQLITE_OK;
+ sqlite3_stmt *pStmt = 0;
+ char *zSql = 0;
+
+ zSql = sqlite3Fts5Mprintf(&rc,
+ "SELECT t.%Q FROM %Q.%Q AS t WHERE t.%Q MATCH '*id'",
+ pTab->zFts5Tbl, pTab->zFts5Db, pTab->zFts5Tbl, pTab->zFts5Tbl
+ );
+ if( zSql ){
+ rc = sqlite3_prepare_v2(pTab->db, zSql, -1, &pStmt, 0);
+ }
+ sqlite3_free(zSql);
+ assert( rc==SQLITE_OK || pStmt==0 );
+ if( rc==SQLITE_ERROR ) rc = SQLITE_OK;
+
+ if( pStmt && sqlite3_step(pStmt)==SQLITE_ROW ){
+ i64 iId = sqlite3_column_int64(pStmt, 0);
+ pIndex = sqlite3Fts5IndexFromCsrid(pTab->pGlobal, iId, &pConfig);
+ }
+
+ if( rc==SQLITE_OK && pIndex==0 ){
+ rc = sqlite3_finalize(pStmt);
+ pStmt = 0;
+ if( rc==SQLITE_OK ){
+ pVTab->zErrMsg = sqlite3_mprintf(
+ "no such fts5 table: %s.%s", pTab->zFts5Db, pTab->zFts5Tbl
+ );
+ rc = SQLITE_ERROR;
+ }
+ }
+
+ if( rc==SQLITE_OK ){
+ int nByte = pConfig->nCol * sizeof(i64) * 2 + sizeof(Fts5VocabCursor);
+ pCsr = (Fts5VocabCursor*)sqlite3Fts5MallocZero(&rc, nByte);
+ }
+
+ if( pCsr ){
+ pCsr->pIndex = pIndex;
+ pCsr->pStmt = pStmt;
+ pCsr->pConfig = pConfig;
+ pCsr->aCnt = (i64*)&pCsr[1];
+ pCsr->aDoc = &pCsr->aCnt[pConfig->nCol];
+ }else{
+ sqlite3_finalize(pStmt);
+ }
+
+ *ppCsr = (sqlite3_vtab_cursor*)pCsr;
+ return rc;
+}
+
+static void fts5VocabResetCursor(Fts5VocabCursor *pCsr){
+ pCsr->rowid = 0;
+ sqlite3Fts5IterClose(pCsr->pIter);
+ pCsr->pIter = 0;
+ sqlite3_free(pCsr->zLeTerm);
+ pCsr->nLeTerm = -1;
+ pCsr->zLeTerm = 0;
+}
+
+/*
+** Close the cursor. For additional information see the documentation
+** on the xClose method of the virtual table interface.
+*/
+static int fts5VocabCloseMethod(sqlite3_vtab_cursor *pCursor){
+ Fts5VocabCursor *pCsr = (Fts5VocabCursor*)pCursor;
+ fts5VocabResetCursor(pCsr);
+ sqlite3Fts5BufferFree(&pCsr->term);
+ sqlite3_finalize(pCsr->pStmt);
+ sqlite3_free(pCsr);
+ return SQLITE_OK;
+}
+
+
+/*
+** Advance the cursor to the next row in the table.
+*/
+static int fts5VocabNextMethod(sqlite3_vtab_cursor *pCursor){
+ Fts5VocabCursor *pCsr = (Fts5VocabCursor*)pCursor;
+ Fts5VocabTable *pTab = (Fts5VocabTable*)pCursor->pVtab;
+ int rc = SQLITE_OK;
+ int nCol = pCsr->pConfig->nCol;
+
+ pCsr->rowid++;
+
+ if( pTab->eType==FTS5_VOCAB_COL ){
+ for(pCsr->iCol++; pCsr->iCol<nCol; pCsr->iCol++){
+ if( pCsr->aCnt[pCsr->iCol] ) break;
+ }
+ }
+
+ if( pTab->eType==FTS5_VOCAB_ROW || pCsr->iCol>=nCol ){
+ if( sqlite3Fts5IterEof(pCsr->pIter) ){
+ pCsr->bEof = 1;
+ }else{
+ const char *zTerm;
+ int nTerm;
+
+ zTerm = sqlite3Fts5IterTerm(pCsr->pIter, &nTerm);
+ if( pCsr->nLeTerm>=0 ){
+ int nCmp = MIN(nTerm, pCsr->nLeTerm);
+ int bCmp = memcmp(pCsr->zLeTerm, zTerm, nCmp);
+ if( bCmp<0 || (bCmp==0 && pCsr->nLeTerm<nTerm) ){
+ pCsr->bEof = 1;
+ return SQLITE_OK;
+ }
+ }
+
+ sqlite3Fts5BufferSet(&rc, &pCsr->term, nTerm, (const u8*)zTerm);
+ memset(pCsr->aCnt, 0, nCol * sizeof(i64));
+ memset(pCsr->aDoc, 0, nCol * sizeof(i64));
+ pCsr->iCol = 0;
+
+ assert( pTab->eType==FTS5_VOCAB_COL || pTab->eType==FTS5_VOCAB_ROW );
+ while( rc==SQLITE_OK ){
+ i64 dummy;
+ const u8 *pPos; int nPos; /* Position list */
+ i64 iPos = 0; /* 64-bit position read from poslist */
+ int iOff = 0; /* Current offset within position list */
+
+ rc = sqlite3Fts5IterPoslist(pCsr->pIter, 0, &pPos, &nPos, &dummy);
+ if( rc==SQLITE_OK ){
+ if( pTab->eType==FTS5_VOCAB_ROW ){
+ while( 0==sqlite3Fts5PoslistNext64(pPos, nPos, &iOff, &iPos) ){
+ pCsr->aCnt[0]++;
+ }
+ pCsr->aDoc[0]++;
+ }else{
+ int iCol = -1;
+ while( 0==sqlite3Fts5PoslistNext64(pPos, nPos, &iOff, &iPos) ){
+ int ii = FTS5_POS2COLUMN(iPos);
+ pCsr->aCnt[ii]++;
+ if( iCol!=ii ){
+ pCsr->aDoc[ii]++;
+ iCol = ii;
+ }
+ }
+ }
+ rc = sqlite3Fts5IterNextScan(pCsr->pIter);
+ }
+
+ if( rc==SQLITE_OK ){
+ zTerm = sqlite3Fts5IterTerm(pCsr->pIter, &nTerm);
+ if( nTerm!=pCsr->term.n || memcmp(zTerm, pCsr->term.p, nTerm) ){
+ break;
+ }
+ if( sqlite3Fts5IterEof(pCsr->pIter) ) break;
+ }
+ }
+ }
+ }
+
+ if( pCsr->bEof==0 && pTab->eType==FTS5_VOCAB_COL ){
+ while( pCsr->aCnt[pCsr->iCol]==0 ) pCsr->iCol++;
+ assert( pCsr->iCol<pCsr->pConfig->nCol );
+ }
+ return rc;
+}
+
+/*
+** This is the xFilter implementation for the virtual table.
+*/
+static int fts5VocabFilterMethod(
+ 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 */
+){
+ Fts5VocabCursor *pCsr = (Fts5VocabCursor*)pCursor;
+ int rc = SQLITE_OK;
+
+ int iVal = 0;
+ int f = FTS5INDEX_QUERY_SCAN;
+ const char *zTerm = 0;
+ int nTerm = 0;
+
+ sqlite3_value *pEq = 0;
+ sqlite3_value *pGe = 0;
+ sqlite3_value *pLe = 0;
+
+ fts5VocabResetCursor(pCsr);
+ if( idxNum & FTS5_VOCAB_TERM_EQ ) pEq = apVal[iVal++];
+ if( idxNum & FTS5_VOCAB_TERM_GE ) pGe = apVal[iVal++];
+ if( idxNum & FTS5_VOCAB_TERM_LE ) pLe = apVal[iVal++];
+
+ if( pEq ){
+ zTerm = (const char *)sqlite3_value_text(pEq);
+ nTerm = sqlite3_value_bytes(pEq);
+ f = 0;
+ }else{
+ if( pGe ){
+ zTerm = (const char *)sqlite3_value_text(pGe);
+ nTerm = sqlite3_value_bytes(pGe);
+ }
+ if( pLe ){
+ const char *zCopy = (const char *)sqlite3_value_text(pLe);
+ pCsr->nLeTerm = sqlite3_value_bytes(pLe);
+ pCsr->zLeTerm = sqlite3_malloc(pCsr->nLeTerm+1);
+ if( pCsr->zLeTerm==0 ){
+ rc = SQLITE_NOMEM;
+ }else{
+ memcpy(pCsr->zLeTerm, zCopy, pCsr->nLeTerm+1);
+ }
+ }
+ }
+
+
+ if( rc==SQLITE_OK ){
+ rc = sqlite3Fts5IndexQuery(pCsr->pIndex, zTerm, nTerm, f, 0, &pCsr->pIter);
+ }
+ if( rc==SQLITE_OK ){
+ rc = fts5VocabNextMethod(pCursor);
+ }
+
+ return rc;
+}
+
+/*
+** 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 fts5VocabEofMethod(sqlite3_vtab_cursor *pCursor){
+ Fts5VocabCursor *pCsr = (Fts5VocabCursor*)pCursor;
+ return pCsr->bEof;
+}
+
+static int fts5VocabColumnMethod(
+ 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 */
+){
+ Fts5VocabCursor *pCsr = (Fts5VocabCursor*)pCursor;
+
+ if( iCol==0 ){
+ sqlite3_result_text(
+ pCtx, (const char*)pCsr->term.p, pCsr->term.n, SQLITE_TRANSIENT
+ );
+ }
+ else if( ((Fts5VocabTable*)(pCursor->pVtab))->eType==FTS5_VOCAB_COL ){
+ assert( iCol==1 || iCol==2 || iCol==3 );
+ if( iCol==1 ){
+ const char *z = pCsr->pConfig->azCol[pCsr->iCol];
+ sqlite3_result_text(pCtx, z, -1, SQLITE_STATIC);
+ }else if( iCol==2 ){
+ sqlite3_result_int64(pCtx, pCsr->aDoc[pCsr->iCol]);
+ }else{
+ sqlite3_result_int64(pCtx, pCsr->aCnt[pCsr->iCol]);
+ }
+ }else{
+ assert( iCol==1 || iCol==2 );
+ if( iCol==1 ){
+ sqlite3_result_int64(pCtx, pCsr->aDoc[0]);
+ }else{
+ sqlite3_result_int64(pCtx, pCsr->aCnt[0]);
+ }
+ }
+ return SQLITE_OK;
+}
+
+/*
+** This is the xRowid method. The SQLite core calls this routine to
+** retrieve the rowid for the current row of the result set. The
+** rowid should be written to *pRowid.
+*/
+static int fts5VocabRowidMethod(
+ sqlite3_vtab_cursor *pCursor,
+ sqlite_int64 *pRowid
+){
+ Fts5VocabCursor *pCsr = (Fts5VocabCursor*)pCursor;
+ *pRowid = pCsr->rowid;
+ return SQLITE_OK;
+}
+
+static int sqlite3Fts5VocabInit(Fts5Global *pGlobal, sqlite3 *db){
+ static const sqlite3_module fts5Vocab = {
+ /* iVersion */ 2,
+ /* xCreate */ fts5VocabCreateMethod,
+ /* xConnect */ fts5VocabConnectMethod,
+ /* xBestIndex */ fts5VocabBestIndexMethod,
+ /* xDisconnect */ fts5VocabDisconnectMethod,
+ /* xDestroy */ fts5VocabDestroyMethod,
+ /* xOpen */ fts5VocabOpenMethod,
+ /* xClose */ fts5VocabCloseMethod,
+ /* xFilter */ fts5VocabFilterMethod,
+ /* xNext */ fts5VocabNextMethod,
+ /* xEof */ fts5VocabEofMethod,
+ /* xColumn */ fts5VocabColumnMethod,
+ /* xRowid */ fts5VocabRowidMethod,
+ /* xUpdate */ 0,
+ /* xBegin */ 0,
+ /* xSync */ 0,
+ /* xCommit */ 0,
+ /* xRollback */ 0,
+ /* xFindFunction */ 0,
+ /* xRename */ 0,
+ /* xSavepoint */ 0,
+ /* xRelease */ 0,
+ /* xRollbackTo */ 0,
+ };
+ void *p = (void*)pGlobal;
+
+ return sqlite3_create_module_v2(db, "fts5vocab", &fts5Vocab, p, 0);
+}
+
+
+
+
+
+#endif /* !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_FTS5) */
+
+/************** End of fts5.c ************************************************/
diff --git a/nss/lib/sqlite/sqlite3.h b/nss/lib/sqlite/sqlite3.h
index 2cbf621..c6d1e0f 100644
--- a/nss/lib/sqlite/sqlite3.h
+++ b/nss/lib/sqlite/sqlite3.h
@@ -23,7 +23,7 @@
**
** 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.
+** on how SQLite interfaces are supposed 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
@@ -43,21 +43,25 @@ extern "C" {
/*
-** Add the ability to override 'extern'
+** Provide the ability to override linkage features of the interface.
*/
#ifndef SQLITE_EXTERN
# define SQLITE_EXTERN extern
#endif
-
#ifndef SQLITE_API
# define SQLITE_API
#endif
-
+#ifndef SQLITE_CDECL
+# define SQLITE_CDECL
+#endif
+#ifndef SQLITE_STDCALL
+# define SQLITE_STDCALL
+#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
+** should not use deprecated interfaces - they are supported for backwards
** compatibility only. Application writers should be aware that
** experimental interfaces are subject to change in point releases.
**
@@ -107,9 +111,9 @@ extern "C" {
** [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"
+#define SQLITE_VERSION "3.10.2"
+#define SQLITE_VERSION_NUMBER 3010002
+#define SQLITE_SOURCE_ID "2016-01-20 15:27:19 17efb4209f97fb4971656086b138599a91a75ff9"
/*
** CAPI3REF: Run-Time Library Version Numbers
@@ -120,7 +124,7 @@ extern "C" {
** 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
+** the header, and thus ensure that the application is
** compiled with matching library and header files.
**
** <blockquote><pre>
@@ -142,9 +146,9 @@ extern "C" {
** 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);
+SQLITE_API const char *SQLITE_STDCALL sqlite3_libversion(void);
+SQLITE_API const char *SQLITE_STDCALL sqlite3_sourceid(void);
+SQLITE_API int SQLITE_STDCALL sqlite3_libversion_number(void);
/*
** CAPI3REF: Run-Time Library Compilation Options Diagnostics
@@ -169,8 +173,8 @@ SQLITE_API int sqlite3_libversion_number(void);
** [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);
+SQLITE_API int SQLITE_STDCALL sqlite3_compileoption_used(const char *zOptName);
+SQLITE_API const char *SQLITE_STDCALL sqlite3_compileoption_get(int N);
#endif
/*
@@ -201,7 +205,7 @@ SQLITE_API const char *sqlite3_compileoption_get(int N);
** 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
+** or [SQLITE_CONFIG_SERIALIZED]. ^(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()
@@ -209,7 +213,7 @@ SQLITE_API const char *sqlite3_compileoption_get(int N);
**
** See the [threading mode] documentation for additional information.
*/
-SQLITE_API int sqlite3_threadsafe(void);
+SQLITE_API int SQLITE_STDCALL sqlite3_threadsafe(void);
/*
** CAPI3REF: Database Connection Handle
@@ -266,10 +270,11 @@ typedef sqlite_uint64 sqlite3_uint64;
/*
** CAPI3REF: Closing A Database Connection
+** DESTRUCTOR: sqlite3
**
** ^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
+** ^Calls to sqlite3_close() and sqlite3_close_v2() return [SQLITE_OK] if
** the [sqlite3] object is successfully destroyed and all associated
** resources are deallocated.
**
@@ -277,7 +282,7 @@ typedef sqlite_uint64 sqlite3_uint64;
** 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
+** and/or 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
@@ -288,9 +293,9 @@ typedef sqlite_uint64 sqlite3_uint64;
** [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
+** sqlite3_close_v2() 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
+** [sqlite3_backup] objects then it returns [SQLITE_OK] and the deallocation
** of resources is deferred until all [prepared statements], [BLOB handles],
** and [sqlite3_backup] objects are also destroyed.
**
@@ -305,8 +310,8 @@ typedef sqlite_uint64 sqlite3_uint64;
** ^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*);
+SQLITE_API int SQLITE_STDCALL sqlite3_close(sqlite3*);
+SQLITE_API int SQLITE_STDCALL sqlite3_close_v2(sqlite3*);
/*
** The type for a callback function.
@@ -317,6 +322,7 @@ typedef int (*sqlite3_callback)(void*,int,char**, char**);
/*
** CAPI3REF: One-Step Query Execution Interface
+** METHOD: sqlite3
**
** The sqlite3_exec() interface is a convenience wrapper around
** [sqlite3_prepare_v2()], [sqlite3_step()], and [sqlite3_finalize()],
@@ -368,15 +374,15 @@ typedef int (*sqlite3_callback)(void*,int,char**, char**);
** Restrictions:
**
** <ul>
-** <li> The application must insure that the 1st parameter to sqlite3_exec()
+** <li> The application must ensure that the 1st parameter to sqlite3_exec()
** is a valid and open [database connection].
-** <li> The application must not close [database connection] specified by
+** <li> The application must not close the [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(
+SQLITE_API int SQLITE_STDCALL sqlite3_exec(
sqlite3*, /* An open database */
const char *sql, /* SQL to be evaluated */
int (*callback)(void*,int,char**,char**), /* Callback function */
@@ -386,16 +392,14 @@ SQLITE_API int sqlite3_exec(
/*
** CAPI3REF: Result Codes
-** KEYWORDS: SQLITE_OK {error code} {error codes}
-** KEYWORDS: {result code} {result codes}
+** KEYWORDS: {result code definitions}
**
** 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].
+** See also: [extended result code definitions]
*/
#define SQLITE_OK 0 /* Successful result */
/* beginning-of-error-codes */
@@ -425,32 +429,27 @@ SQLITE_API int sqlite3_exec(
#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_NOTICE 27 /* Notifications from sqlite3_log() */
+#define SQLITE_WARNING 28 /* Warnings from sqlite3_log() */
#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}
+** KEYWORDS: {extended result code definitions}
**
-** In its default configuration, SQLite API routines return one of 26 integer
-** [SQLITE_OK | result codes]. However, experience has shown that many of
+** In its default configuration, SQLite API routines return one of 30 integer
+** [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
+** about errors. These [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.
+** [sqlite3_extended_result_codes()] API. Or, the extended code for
+** the most recent error can be obtained using
+** [sqlite3_extended_errcode()].
*/
#define SQLITE_IOERR_READ (SQLITE_IOERR | (1<<8))
#define SQLITE_IOERR_SHORT_READ (SQLITE_IOERR | (2<<8))
@@ -475,15 +474,38 @@ SQLITE_API int sqlite3_exec(
#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_IOERR_MMAP (SQLITE_IOERR | (24<<8))
+#define SQLITE_IOERR_GETTEMPPATH (SQLITE_IOERR | (25<<8))
+#define SQLITE_IOERR_CONVPATH (SQLITE_IOERR | (26<<8))
+#define SQLITE_IOERR_VNODE (SQLITE_IOERR | (27<<8))
+#define SQLITE_IOERR_AUTH (SQLITE_IOERR | (28<<8))
#define SQLITE_LOCKED_SHAREDCACHE (SQLITE_LOCKED | (1<<8))
#define SQLITE_BUSY_RECOVERY (SQLITE_BUSY | (1<<8))
+#define SQLITE_BUSY_SNAPSHOT (SQLITE_BUSY | (2<<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_CANTOPEN_CONVPATH (SQLITE_CANTOPEN | (4<<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_READONLY_ROLLBACK (SQLITE_READONLY | (3<<8))
+#define SQLITE_READONLY_DBMOVED (SQLITE_READONLY | (4<<8))
#define SQLITE_ABORT_ROLLBACK (SQLITE_ABORT | (2<<8))
+#define SQLITE_CONSTRAINT_CHECK (SQLITE_CONSTRAINT | (1<<8))
+#define SQLITE_CONSTRAINT_COMMITHOOK (SQLITE_CONSTRAINT | (2<<8))
+#define SQLITE_CONSTRAINT_FOREIGNKEY (SQLITE_CONSTRAINT | (3<<8))
+#define SQLITE_CONSTRAINT_FUNCTION (SQLITE_CONSTRAINT | (4<<8))
+#define SQLITE_CONSTRAINT_NOTNULL (SQLITE_CONSTRAINT | (5<<8))
+#define SQLITE_CONSTRAINT_PRIMARYKEY (SQLITE_CONSTRAINT | (6<<8))
+#define SQLITE_CONSTRAINT_TRIGGER (SQLITE_CONSTRAINT | (7<<8))
+#define SQLITE_CONSTRAINT_UNIQUE (SQLITE_CONSTRAINT | (8<<8))
+#define SQLITE_CONSTRAINT_VTAB (SQLITE_CONSTRAINT | (9<<8))
+#define SQLITE_CONSTRAINT_ROWID (SQLITE_CONSTRAINT |(10<<8))
+#define SQLITE_NOTICE_RECOVER_WAL (SQLITE_NOTICE | (1<<8))
+#define SQLITE_NOTICE_RECOVER_ROLLBACK (SQLITE_NOTICE | (2<<8))
+#define SQLITE_WARNING_AUTOINDEX (SQLITE_WARNING | (1<<8))
+#define SQLITE_AUTH_USER (SQLITE_AUTH | (1<<8))
/*
** CAPI3REF: Flags For File Open Operations
@@ -537,7 +559,11 @@ SQLITE_API int sqlite3_exec(
** 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.
+** guaranteed to be unchanged. The SQLITE_IOCAP_UNDELETABLE_WHEN_OPEN
+** flag indicate that a file cannot be deleted when open. The
+** SQLITE_IOCAP_IMMUTABLE flag indicates that the file is on
+** read-only media and cannot be changed even by processes with
+** elevated privileges.
*/
#define SQLITE_IOCAP_ATOMIC 0x00000001
#define SQLITE_IOCAP_ATOMIC512 0x00000002
@@ -552,6 +578,7 @@ SQLITE_API int sqlite3_exec(
#define SQLITE_IOCAP_SEQUENTIAL 0x00000400
#define SQLITE_IOCAP_UNDELETABLE_WHEN_OPEN 0x00000800
#define SQLITE_IOCAP_POWERSAFE_OVERWRITE 0x00001000
+#define SQLITE_IOCAP_IMMUTABLE 0x00002000
/*
** CAPI3REF: File Locking Levels
@@ -658,7 +685,7 @@ struct sqlite3_file {
** 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.
+** A [file control opcodes | 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
@@ -723,24 +750,30 @@ struct sqlite3_io_methods {
void (*xShmBarrier)(sqlite3_file*);
int (*xShmUnmap)(sqlite3_file*, int deleteFlag);
/* Methods above are valid for version 2 */
+ int (*xFetch)(sqlite3_file*, sqlite3_int64 iOfst, int iAmt, void **pp);
+ int (*xUnfetch)(sqlite3_file*, sqlite3_int64 iOfst, void *p);
+ /* Methods above are valid for version 3 */
/* Additional methods may be added in future releases */
};
/*
** CAPI3REF: Standard File Control Opcodes
+** KEYWORDS: {file control opcodes} {file control opcode}
**
** These integer constants are opcodes for the xFileControl method
** of the [sqlite3_io_methods] object and for the [sqlite3_file_control()]
** interface.
**
+** <ul>
+** <li>[[SQLITE_FCNTL_LOCKSTATE]]
** 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>
+** is used during testing and is only available when the SQLITE_TEST
+** compile-time option is used.
+**
** <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
@@ -761,19 +794,38 @@ struct sqlite3_io_methods {
** <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.
+** connection. See also [SQLITE_FCNTL_JOURNAL_POINTER].
+**
+** <li>[[SQLITE_FCNTL_JOURNAL_POINTER]]
+** The [SQLITE_FCNTL_JOURNAL_POINTER] opcode is used to obtain a pointer
+** to the [sqlite3_file] object associated with the journal file (either
+** the [rollback journal] or the [write-ahead log]) for a particular database
+** connection. See also [SQLITE_FCNTL_FILE_POINTER].
**
** <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.
+** No longer in use.
+**
+** <li>[[SQLITE_FCNTL_SYNC]]
+** The [SQLITE_FCNTL_SYNC] opcode is generated internally by SQLite and
+** sent to the VFS immediately before the xSync method is invoked on a
+** database file descriptor. Or, if the xSync method is not invoked
+** because the user has configured SQLite with
+** [PRAGMA synchronous | PRAGMA synchronous=OFF] it is invoked in place
+** of the xSync method. In most cases, the pointer argument passed with
+** this file-control is NULL. However, if the database file is being synced
+** as part of a multi-database commit, the argument points to a nul-terminated
+** string containing the transactions master-journal file name. VFSes that
+** do not need this signal 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_COMMIT_PHASETWO]]
+** The [SQLITE_FCNTL_COMMIT_PHASETWO] opcode is generated internally by SQLite
+** and sent to the VFS after a transaction has been committed immediately
+** but before the database is unlocked. VFSes that do not need this signal
+** 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
@@ -835,6 +887,15 @@ struct sqlite3_io_methods {
** pointer in case this file-control is not implemented. This file-control
** is intended for diagnostic use only.
**
+** <li>[[SQLITE_FCNTL_VFS_POINTER]]
+** ^The [SQLITE_FCNTL_VFS_POINTER] opcode finds a pointer to the top-level
+** [VFSes] currently in use. ^(The argument X in
+** sqlite3_file_control(db,SQLITE_FCNTL_VFS_POINTER,X) must be
+** of type "[sqlite3_vfs] **". This opcodes will set *X
+** to a pointer to the top-level VFS.)^
+** ^When there are multiple VFS shims in the stack, this opcode finds the
+** upper-most shim 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
@@ -851,7 +912,9 @@ struct sqlite3_io_methods {
** [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
+** prepared statement if result string is NULL, or that returns a copy
+** of the result string if the string is non-NULL.
+** ^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]
@@ -859,7 +922,8 @@ struct sqlite3_io_methods {
** 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
+** ^The [SQLITE_FCNTL_BUSYHANDLER]
+** 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
@@ -870,19 +934,65 @@ struct sqlite3_io_methods {
** current operation.
**
** <li>[[SQLITE_FCNTL_TEMPFILENAME]]
-** ^Application can invoke this file-control to have SQLite generate a
+** ^Application can invoke the [SQLITE_FCNTL_TEMPFILENAME] 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.
**
+** <li>[[SQLITE_FCNTL_MMAP_SIZE]]
+** The [SQLITE_FCNTL_MMAP_SIZE] file control is used to query or set the
+** maximum number of bytes that will be used for memory-mapped I/O.
+** The argument is a pointer to a value of type sqlite3_int64 that
+** is an advisory maximum number of bytes in the file to memory map. The
+** pointer is overwritten with the old value. The limit is not changed if
+** the value originally pointed to is negative, and so the current limit
+** can be queried by passing in a pointer to a negative number. This
+** file-control is used internally to implement [PRAGMA mmap_size].
+**
+** <li>[[SQLITE_FCNTL_TRACE]]
+** The [SQLITE_FCNTL_TRACE] file control provides advisory information
+** to the VFS about what the higher layers of the SQLite stack are doing.
+** This file control is used by some VFS activity tracing [shims].
+** The argument is a zero-terminated string. Higher layers in the
+** SQLite stack may generate instances of this file control if
+** the [SQLITE_USE_FCNTL_TRACE] compile-time option is enabled.
+**
+** <li>[[SQLITE_FCNTL_HAS_MOVED]]
+** The [SQLITE_FCNTL_HAS_MOVED] file control interprets its argument as a
+** pointer to an integer and it writes a boolean into that integer depending
+** on whether or not the file has been renamed, moved, or deleted since it
+** was first opened.
+**
+** <li>[[SQLITE_FCNTL_WIN32_SET_HANDLE]]
+** The [SQLITE_FCNTL_WIN32_SET_HANDLE] opcode is used for debugging. This
+** opcode causes the xFileControl method to swap the file handle with the one
+** pointed to by the pArg argument. This capability is used during testing
+** and only needs to be supported when SQLITE_TEST is defined.
+**
+** <li>[[SQLITE_FCNTL_WAL_BLOCK]]
+** The [SQLITE_FCNTL_WAL_BLOCK] is a signal to the VFS layer that it might
+** be advantageous to block on the next WAL lock if the lock is not immediately
+** available. The WAL subsystem issues this signal during rare
+** circumstances in order to fix a problem with priority inversion.
+** Applications should <em>not</em> use this file-control.
+**
+** <li>[[SQLITE_FCNTL_ZIPVFS]]
+** The [SQLITE_FCNTL_ZIPVFS] opcode is implemented by zipvfs only. All other
+** VFS should return SQLITE_NOTFOUND for this opcode.
+**
+** <li>[[SQLITE_FCNTL_RBU]]
+** The [SQLITE_FCNTL_RBU] opcode is implemented by the special VFS used by
+** the RBU extension only. All other VFS should return SQLITE_NOTFOUND for
+** this opcode.
** </ul>
*/
#define SQLITE_FCNTL_LOCKSTATE 1
-#define SQLITE_GET_LOCKPROXYFILE 2
-#define SQLITE_SET_LOCKPROXYFILE 3
-#define SQLITE_LAST_ERRNO 4
+#define SQLITE_FCNTL_GET_LOCKPROXYFILE 2
+#define SQLITE_FCNTL_SET_LOCKPROXYFILE 3
+#define SQLITE_FCNTL_LAST_ERRNO 4
#define SQLITE_FCNTL_SIZE_HINT 5
#define SQLITE_FCNTL_CHUNK_SIZE 6
#define SQLITE_FCNTL_FILE_POINTER 7
@@ -895,6 +1005,23 @@ struct sqlite3_io_methods {
#define SQLITE_FCNTL_PRAGMA 14
#define SQLITE_FCNTL_BUSYHANDLER 15
#define SQLITE_FCNTL_TEMPFILENAME 16
+#define SQLITE_FCNTL_MMAP_SIZE 18
+#define SQLITE_FCNTL_TRACE 19
+#define SQLITE_FCNTL_HAS_MOVED 20
+#define SQLITE_FCNTL_SYNC 21
+#define SQLITE_FCNTL_COMMIT_PHASETWO 22
+#define SQLITE_FCNTL_WIN32_SET_HANDLE 23
+#define SQLITE_FCNTL_WAL_BLOCK 24
+#define SQLITE_FCNTL_ZIPVFS 25
+#define SQLITE_FCNTL_RBU 26
+#define SQLITE_FCNTL_VFS_POINTER 27
+#define SQLITE_FCNTL_JOURNAL_POINTER 28
+
+/* deprecated names */
+#define SQLITE_GET_LOCKPROXYFILE SQLITE_FCNTL_GET_LOCKPROXYFILE
+#define SQLITE_SET_LOCKPROXYFILE SQLITE_FCNTL_SET_LOCKPROXYFILE
+#define SQLITE_LAST_ERRNO SQLITE_FCNTL_LAST_ERRNO
+
/*
** CAPI3REF: Mutex Handle
@@ -1146,7 +1273,7 @@ struct sqlite3_vfs {
** </ul>
**
** When unlocking, the same SHARED or EXCLUSIVE flag must be supplied as
-** was given no the corresponding lock.
+** was given on the corresponding lock.
**
** The xShmLock method can transition between unlocked and SHARED or
** between unlocked and EXCLUSIVE. It cannot transition between SHARED
@@ -1243,10 +1370,10 @@ struct sqlite3_vfs {
** 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);
+SQLITE_API int SQLITE_STDCALL sqlite3_initialize(void);
+SQLITE_API int SQLITE_STDCALL sqlite3_shutdown(void);
+SQLITE_API int SQLITE_STDCALL sqlite3_os_init(void);
+SQLITE_API int SQLITE_STDCALL sqlite3_os_end(void);
/*
** CAPI3REF: Configuring The SQLite Library
@@ -1257,9 +1384,11 @@ SQLITE_API int sqlite3_os_end(void);
** 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()
+** <b>The sqlite3_config() interface is not threadsafe. The application
+** must ensure that no other SQLite interfaces are invoked by other
+** threads while sqlite3_config() is running.</b>
+**
+** The sqlite3_config() interface
** 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
@@ -1277,10 +1406,11 @@ SQLITE_API int sqlite3_os_end(void);
** ^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, ...);
+SQLITE_API int SQLITE_CDECL sqlite3_config(int, ...);
/*
** CAPI3REF: Configure database connections
+** METHOD: sqlite3
**
** The sqlite3_db_config() interface is used to make configuration
** changes to a [database connection]. The interface is similar to
@@ -1295,7 +1425,7 @@ SQLITE_API int sqlite3_config(int, ...);
** ^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, ...);
+SQLITE_API int SQLITE_CDECL sqlite3_db_config(sqlite3*, int op, ...);
/*
** CAPI3REF: Memory Allocation Routines
@@ -1339,7 +1469,7 @@ SQLITE_API int sqlite3_db_config(sqlite3*, int op, ...);
** 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,
+** 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
@@ -1429,31 +1559,33 @@ struct sqlite3_mem_methods {
** 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
+** <dd> ^(The SQLITE_CONFIG_MALLOC 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]
+** <dd> ^(The SQLITE_CONFIG_GETMALLOC 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:
+** <dd> ^The SQLITE_CONFIG_MEMSTATUS 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()]
+** <li> [sqlite3_status64()]
** </ul>)^
** ^Memory allocation statistics are enabled by default unless SQLite is
** compiled with [SQLITE_DEFAULT_MEMSTATUS]=0 in which case memory
@@ -1461,53 +1593,72 @@ struct sqlite3_mem_methods {
** </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
+** <dd> ^The SQLITE_CONFIG_SCRATCH option specifies a static memory buffer
+** that SQLite can use for scratch memory. ^(There are three arguments
+** to SQLITE_CONFIG_SCRATCH: 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.
+** and the maximum number of scratch allocations (N).)^
** 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
+** ^SQLite will not use more than one scratch buffers per thread.
+** ^SQLite will never request 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>
+** [sqlite3_malloc()] will be used to obtain the memory needed.<p>
+** ^When the application provides any amount of scratch memory using
+** SQLITE_CONFIG_SCRATCH, SQLite avoids unnecessary large
+** [sqlite3_malloc|heap allocations].
+** This can help [Robson proof|prevent memory allocation failures] due to heap
+** fragmentation in low-memory embedded systems.
+** </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).
+** <dd> ^The SQLITE_CONFIG_PAGECACHE option specifies a memory pool
+** that SQLite can use for the database page cache with the default page
+** cache implementation.
+** This configuration option is a no-op if an application-define page
+** cache implementation is loaded using the [SQLITE_CONFIG_PCACHE2].
+** ^There are three arguments to SQLITE_CONFIG_PAGECACHE: A pointer to
+** 8-byte aligned memory (pMem), the size of each page cache line (sz),
+** and the number of cache lines (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>
+** (a power of two between 512 and 65536) plus some extra bytes for each
+** page header. ^The number of extra bytes needed by the page header
+** can be determined using [SQLITE_CONFIG_PCACHE_HDRSZ].
+** ^It is harmless, apart from the wasted memory,
+** for the sz parameter to be larger than necessary. The pMem
+** argument must be either a NULL pointer or a pointer to an 8-byte
+** aligned block of memory of at least sz*N bytes, otherwise
+** subsequent behavior is undefined.
+** ^When pMem is not NULL, SQLite will strive to use the memory provided
+** to satisfy page cache needs, falling back to [sqlite3_malloc()] if
+** a page cache line is larger than sz bytes or if all of the pMem buffer
+** is exhausted.
+** ^If pMem is NULL and N is non-zero, then each database connection
+** does an initial bulk allocation for page cache memory
+** from [sqlite3_malloc()] sufficient for N cache lines if N is positive or
+** of -1024*N bytes if N is negative, . ^If additional
+** page cache memory is needed beyond what is provided by the initial
+** allocation, then SQLite goes to [sqlite3_malloc()] separately for each
+** additional cache line. </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,
+** <dd> ^The SQLITE_CONFIG_HEAP 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].
+** ^The SQLITE_CONFIG_HEAP option is only available if SQLite is compiled
+** with either [SQLITE_ENABLE_MEMSYS3] or [SQLITE_ENABLE_MEMSYS5] and returns
+** [SQLITE_ERROR] if invoked otherwise.
+** ^There are three arguments to SQLITE_CONFIG_HEAP:
+** 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
+** memory pointer is not NULL 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.
@@ -1515,11 +1666,11 @@ struct sqlite3_mem_methods {
** 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
+** <dd> ^(The SQLITE_CONFIG_MUTEX 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
@@ -1527,8 +1678,8 @@ struct sqlite3_mem_methods {
** 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
+** <dd> ^(The SQLITE_CONFIG_GETMUTEX 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
@@ -1540,28 +1691,30 @@ struct sqlite3_mem_methods {
** 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
+** <dd> ^(The SQLITE_CONFIG_LOOKASIDE option takes two arguments that determine
+** the default size of lookaside memory 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
+** slots allocated to each database connection.)^ ^(SQLITE_CONFIG_LOOKASIDE
+** sets the <i>default</i> lookaside size. The [SQLITE_DBCONFIG_LOOKASIDE]
+** option 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>
+** <dd> ^(The SQLITE_CONFIG_PCACHE2 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 [sqlite3_pcache_methods2] object.</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>
+** <dd> ^(The SQLITE_CONFIG_GETPCACHE2 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
+** <dd> The SQLITE_CONFIG_LOG option is used to configure the SQLite
+** global [error log].
+** (^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
@@ -1579,27 +1732,29 @@ struct sqlite3_mem_methods {
** 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
+** <dd>^(The SQLITE_CONFIG_URI 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
+** 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
+** 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_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
+** <dd>^The SQLITE_CONFIG_COVERING_INDEX_SCAN 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
+** 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.
**
@@ -1607,12 +1762,12 @@ struct sqlite3_mem_methods {
** <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>
+** </dd>
**
** [[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
+** [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
@@ -1622,7 +1777,49 @@ struct sqlite3_mem_methods {
** 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.
+** third parameter is passed NULL In this case. An example of using this
+** configuration option can be seen in the "test_sqllog.c" source file in
+** the canonical SQLite source tree.</dd>
+**
+** [[SQLITE_CONFIG_MMAP_SIZE]]
+** <dt>SQLITE_CONFIG_MMAP_SIZE
+** <dd>^SQLITE_CONFIG_MMAP_SIZE takes two 64-bit integer (sqlite3_int64) values
+** that are the default mmap size limit (the default setting for
+** [PRAGMA mmap_size]) and the maximum allowed mmap size limit.
+** ^The default setting can be overridden by each database connection using
+** either the [PRAGMA mmap_size] command, or by using the
+** [SQLITE_FCNTL_MMAP_SIZE] file control. ^(The maximum allowed mmap size
+** will be silently truncated if necessary so that it does not exceed the
+** compile-time maximum mmap size set by the
+** [SQLITE_MAX_MMAP_SIZE] compile-time option.)^
+** ^If either argument to this option is negative, then that argument is
+** changed to its compile-time default.
+**
+** [[SQLITE_CONFIG_WIN32_HEAPSIZE]]
+** <dt>SQLITE_CONFIG_WIN32_HEAPSIZE
+** <dd>^The SQLITE_CONFIG_WIN32_HEAPSIZE option is only available if SQLite is
+** compiled for Windows with the [SQLITE_WIN32_MALLOC] pre-processor macro
+** defined. ^SQLITE_CONFIG_WIN32_HEAPSIZE takes a 32-bit unsigned integer value
+** that specifies the maximum size of the created heap.
+**
+** [[SQLITE_CONFIG_PCACHE_HDRSZ]]
+** <dt>SQLITE_CONFIG_PCACHE_HDRSZ
+** <dd>^The SQLITE_CONFIG_PCACHE_HDRSZ option takes a single parameter which
+** is a pointer to an integer and writes into that integer the number of extra
+** bytes per page required for each page in [SQLITE_CONFIG_PAGECACHE].
+** The amount of extra space required can change depending on the compiler,
+** target platform, and SQLite version.
+**
+** [[SQLITE_CONFIG_PMASZ]]
+** <dt>SQLITE_CONFIG_PMASZ
+** <dd>^The SQLITE_CONFIG_PMASZ option takes a single parameter which
+** is an unsigned integer and sets the "Minimum PMA Size" for the multithreaded
+** sorter to that integer. The default minimum PMA Size is set by the
+** [SQLITE_SORTER_PMASZ] compile-time option. New threads are launched
+** to help with sort operations when multithreaded sorting
+** is enabled (using the [PRAGMA threads] command) and the amount of content
+** to be sorted exceeds the page size times the minimum of the
+** [PRAGMA cache_size] setting and this value.
** </dl>
*/
#define SQLITE_CONFIG_SINGLETHREAD 1 /* nil */
@@ -1646,6 +1843,10 @@ struct sqlite3_mem_methods {
#define SQLITE_CONFIG_GETPCACHE2 19 /* sqlite3_pcache_methods2* */
#define SQLITE_CONFIG_COVERING_INDEX_SCAN 20 /* int */
#define SQLITE_CONFIG_SQLLOG 21 /* xSqllog, void* */
+#define SQLITE_CONFIG_MMAP_SIZE 22 /* sqlite3_int64, sqlite3_int64 */
+#define SQLITE_CONFIG_WIN32_HEAPSIZE 23 /* int nByte */
+#define SQLITE_CONFIG_PCACHE_HDRSZ 24 /* int *psz */
+#define SQLITE_CONFIG_PMASZ 25 /* unsigned int szPma */
/*
** CAPI3REF: Database Connection Configuration Options
@@ -1712,29 +1913,33 @@ struct sqlite3_mem_methods {
/*
** CAPI3REF: Enable Or Disable Extended Result Codes
+** METHOD: sqlite3
**
** ^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);
+SQLITE_API int SQLITE_STDCALL sqlite3_extended_result_codes(sqlite3*, int onoff);
/*
** CAPI3REF: Last Insert Rowid
+** METHOD: sqlite3
**
-** ^Each entry in an SQLite table has a unique 64-bit signed
+** ^Each entry in most SQLite tables (except for [WITHOUT ROWID] tables)
+** 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.
+** ^The sqlite3_last_insert_rowid(D) interface returns the [rowid] of the
+** most recent successful [INSERT] into a rowid table or [virtual table]
+** on database connection D.
+** ^Inserts into [WITHOUT ROWID] tables are not recorded.
+** ^If no successful [INSERT]s into rowid tables
+** have ever occurred on the database connection D,
+** then sqlite3_last_insert_rowid(D) returns zero.
**
** ^(If an [INSERT] occurs within a trigger or within a [virtual table]
** method, then this routine will return the [rowid] of the inserted
@@ -1766,52 +1971,51 @@ SQLITE_API int sqlite3_extended_result_codes(sqlite3*, int onoff);
** unpredictable and might not equal either the old or the new
** last insert [rowid].
*/
-SQLITE_API sqlite3_int64 sqlite3_last_insert_rowid(sqlite3*);
+SQLITE_API sqlite3_int64 SQLITE_STDCALL sqlite3_last_insert_rowid(sqlite3*);
/*
** CAPI3REF: Count The Number Of Rows Modified
+** METHOD: sqlite3
**
-** ^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.)^
+** ^This function returns the number of rows modified, inserted or
+** deleted by the most recently completed INSERT, UPDATE or DELETE
+** statement on the database connection specified by the only parameter.
+** ^Executing any other type of SQL statement does not modify the value
+** returned by this function.
+**
+** ^Only changes made directly by the INSERT, UPDATE or DELETE statement are
+** considered - auxiliary changes caused by [CREATE TRIGGER | triggers],
+** [foreign key actions] or [REPLACE] constraint resolution are not counted.
+**
+** Changes to a view that are intercepted by
+** [INSTEAD OF trigger | INSTEAD OF triggers] are not counted. ^The value
+** returned by sqlite3_changes() immediately after an INSERT, UPDATE or
+** DELETE statement run on a view is always zero. Only changes made to real
+** tables are counted.
+**
+** Things are more complicated if the sqlite3_changes() function is
+** executed while a trigger program is running. This may happen if the
+** program uses the [changes() SQL function], or if some other callback
+** function invokes sqlite3_changes() directly. Essentially:
+**
+** <ul>
+** <li> ^(Before entering a trigger program the value returned by
+** sqlite3_changes() function is saved. After the trigger program
+** has finished, the original value is restored.)^
+**
+** <li> ^(Within a trigger program each INSERT, UPDATE and DELETE
+** statement sets the value returned by sqlite3_changes()
+** upon completion as normal. Of course, this value will not include
+** any changes performed by sub-triggers, as the sqlite3_changes()
+** value will be saved and restored after each sub-trigger has run.)^
+** </ul>
+**
+** ^This means that if the changes() SQL function (or similar) is used
+** by the first INSERT, UPDATE or DELETE statement within a trigger, it
+** returns the value as set when the calling statement began executing.
+** ^If it is used by the second or subsequent such statement within a trigger
+** program, the value returned reflects the number of rows modified by the
+** previous INSERT, UPDATE or DELETE statement within the same trigger.
**
** See also the [sqlite3_total_changes()] interface, the
** [count_changes pragma], and the [changes() SQL function].
@@ -1820,25 +2024,23 @@ SQLITE_API sqlite3_int64 sqlite3_last_insert_rowid(sqlite3*);
** while [sqlite3_changes()] is running then the value returned
** is unpredictable and not meaningful.
*/
-SQLITE_API int sqlite3_changes(sqlite3*);
+SQLITE_API int SQLITE_STDCALL sqlite3_changes(sqlite3*);
/*
** CAPI3REF: Total Number Of Rows Modified
+** METHOD: sqlite3
**
-** ^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()]).
-**
+** ^This function returns the total number of rows inserted, modified or
+** deleted by all [INSERT], [UPDATE] or [DELETE] statements completed
+** since the database connection was opened, including those executed as
+** part of trigger programs. ^Executing any other type of SQL statement
+** does not affect the value returned by sqlite3_total_changes().
+**
+** ^Changes made as part of [foreign key actions] are included in the
+** count, but those made as part of REPLACE constraint resolution are
+** not. ^Changes to a view that are intercepted by INSTEAD OF triggers
+** are not counted.
+**
** See also the [sqlite3_changes()] interface, the
** [count_changes pragma], and the [total_changes() SQL function].
**
@@ -1846,10 +2048,11 @@ SQLITE_API int sqlite3_changes(sqlite3*);
** while [sqlite3_total_changes()] is running then the value
** returned is unpredictable and not meaningful.
*/
-SQLITE_API int sqlite3_total_changes(sqlite3*);
+SQLITE_API int SQLITE_STDCALL sqlite3_total_changes(sqlite3*);
/*
** CAPI3REF: Interrupt A Long-Running Query
+** METHOD: sqlite3
**
** ^This function causes any pending database operation to abort and
** return at its earliest opportunity. This routine is typically
@@ -1885,7 +2088,7 @@ SQLITE_API int sqlite3_total_changes(sqlite3*);
** If the database connection closes while [sqlite3_interrupt()]
** is running then bad things will likely happen.
*/
-SQLITE_API void sqlite3_interrupt(sqlite3*);
+SQLITE_API void SQLITE_STDCALL sqlite3_interrupt(sqlite3*);
/*
** CAPI3REF: Determine If An SQL Statement Is Complete
@@ -1920,33 +2123,41 @@ SQLITE_API void sqlite3_interrupt(sqlite3*);
** 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);
+SQLITE_API int SQLITE_STDCALL sqlite3_complete(const char *sql);
+SQLITE_API int SQLITE_STDCALL 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]
+** KEYWORDS: {busy-handler callback} {busy handler}
+** METHOD: sqlite3
+**
+** ^The sqlite3_busy_handler(D,X,P) routine sets a callback function X
+** that might be invoked with argument P whenever
+** an attempt is made to access a database table associated with
+** [database connection] D when another thread
+** or process has the table locked.
+** The sqlite3_busy_handler() interface is used to implement
+** [sqlite3_busy_timeout()] and [PRAGMA busy_timeout].
+**
+** ^If the busy callback is NULL, then [SQLITE_BUSY]
** 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
+** been invoked previously for the same 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.
+** access the database and [SQLITE_BUSY] is returned
+** to the application.
** ^If the callback returns non-zero, then another attempt
-** is made to open the database for reading and the cycle repeats.
+** is made to access the database 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.
+** to the application 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
@@ -1960,57 +2171,48 @@ SQLITE_API int sqlite3_complete16(const void *sql);
**
** ^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.
+** or evaluating [PRAGMA busy_timeout=N] will change the
+** busy handler and thus clear any previously set busy handler.
**
** The busy callback should not take any actions which modify the
-** database connection that invoked the busy handler. Any such actions
+** database connection that invoked the busy handler. In other words,
+** the busy handler is not reentrant. 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*);
+SQLITE_API int SQLITE_STDCALL sqlite3_busy_handler(sqlite3*, int(*)(void*,int), void*);
/*
** CAPI3REF: Set A Busy Timeout
+** METHOD: sqlite3
**
** ^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].
+** [SQLITE_BUSY].
**
** ^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
+** [database connection] at any given moment. If another busy handler
** was defined (using [sqlite3_busy_handler()]) prior to calling
** this routine, that other busy handler is cleared.)^
+**
+** See also: [PRAGMA busy_timeout]
*/
-SQLITE_API int sqlite3_busy_timeout(sqlite3*, int ms);
+SQLITE_API int SQLITE_STDCALL sqlite3_busy_timeout(sqlite3*, int ms);
/*
** CAPI3REF: Convenience Routines For Running Queries
+** METHOD: sqlite3
**
** This is a legacy interface that is preserved for backwards compatibility.
** Use of this interface is not recommended.
@@ -2081,7 +2283,7 @@ SQLITE_API int sqlite3_busy_timeout(sqlite3*, int ms);
** reflected in subsequent calls to [sqlite3_errcode()] or
** [sqlite3_errmsg()].
*/
-SQLITE_API int sqlite3_get_table(
+SQLITE_API int SQLITE_STDCALL sqlite3_get_table(
sqlite3 *db, /* An open database */
const char *zSql, /* SQL to be evaluated */
char ***pazResult, /* Results of the query */
@@ -2089,13 +2291,17 @@ SQLITE_API int sqlite3_get_table(
int *pnColumn, /* Number of result columns written here */
char **pzErrmsg /* Error msg written here */
);
-SQLITE_API void sqlite3_free_table(char **result);
+SQLITE_API void SQLITE_STDCALL 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.
+** These routines understand most of the common K&R formatting options,
+** plus some additional non-standard formats, detailed below.
+** Note that some of the more obscure formatting options from recent
+** C-library standards are omitted from this implementation.
**
** ^The sqlite3_mprintf() and sqlite3_vmprintf() routines write their
** results into memory obtained from [sqlite3_malloc()].
@@ -2128,7 +2334,7 @@ SQLITE_API void sqlite3_free_table(char **result);
** 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.
+** is are "%q", "%Q", "%w" 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.
@@ -2181,14 +2387,20 @@ SQLITE_API void sqlite3_free_table(char **result);
** The code above will render a correct SQL statement in the zSQL
** variable even if the zText variable is a NULL pointer.
**
+** ^(The "%w" formatting option is like "%q" except that it expects to
+** be contained within double-quotes instead of single quotes, and it
+** escapes the double-quote character instead of the single-quote
+** character.)^ The "%w" formatting option is intended for safely inserting
+** table and column names into a constructed SQL statement.
+**
** ^(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);
+SQLITE_API char *SQLITE_CDECL sqlite3_mprintf(const char*,...);
+SQLITE_API char *SQLITE_STDCALL sqlite3_vmprintf(const char*, va_list);
+SQLITE_API char *SQLITE_CDECL sqlite3_snprintf(int,char*,const char*, ...);
+SQLITE_API char *SQLITE_STDCALL sqlite3_vsnprintf(int,char*,const char*, va_list);
/*
** CAPI3REF: Memory Allocation Subsystem
@@ -2205,6 +2417,10 @@ SQLITE_API char *sqlite3_vsnprintf(int,char*,const char*, va_list);
** sqlite3_malloc() is zero or negative then sqlite3_malloc() returns
** a NULL pointer.
**
+** ^The sqlite3_malloc64(N) routine works just like
+** sqlite3_malloc(N) except that N is an unsigned 64-bit integer instead
+** of a signed 32-bit integer.
+**
** ^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
@@ -2216,24 +2432,38 @@ SQLITE_API char *sqlite3_vsnprintf(int,char*,const char*, va_list);
** 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()
+** ^The sqlite3_realloc(X,N) interface attempts to resize a
+** prior memory allocation X to be at least N bytes.
+** ^If the X parameter to sqlite3_realloc(X,N)
** 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
+** sqlite3_malloc(N).
+** ^If the N parameter to sqlite3_realloc(X,N) 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.
+** sqlite3_free(X).
+** ^sqlite3_realloc(X,N) returns a pointer to a memory allocation
+** of at least N bytes in size or NULL if insufficient memory is available.
** ^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()
+** by sqlite3_realloc(X,N) and the prior allocation is freed.
+** ^If sqlite3_realloc(X,N) returns NULL and N is positive, then the
+** prior allocation is not freed.
+**
+** ^The sqlite3_realloc64(X,N) interfaces works the same as
+** sqlite3_realloc(X,N) except that N is a 64-bit unsigned integer instead
+** of a 32-bit signed integer.
+**
+** ^If X is a memory allocation previously obtained from sqlite3_malloc(),
+** sqlite3_malloc64(), sqlite3_realloc(), or sqlite3_realloc64(), then
+** sqlite3_msize(X) returns the size of that memory allocation in bytes.
+** ^The value returned by sqlite3_msize(X) might be larger than the number
+** of bytes requested when X was allocated. ^If X is a NULL pointer then
+** sqlite3_msize(X) returns zero. If X points to something that is not
+** the beginning of memory allocation, or if it points to a formerly
+** valid memory allocation that has now been freed, then the behavior
+** of sqlite3_msize(X) is undefined and possibly harmful.
+**
+** ^The memory returned by sqlite3_malloc(), sqlite3_realloc(),
+** sqlite3_malloc64(), and sqlite3_realloc64()
** 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.
@@ -2260,9 +2490,12 @@ SQLITE_API char *sqlite3_vsnprintf(int,char*,const char*, va_list);
** 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*);
+SQLITE_API void *SQLITE_STDCALL sqlite3_malloc(int);
+SQLITE_API void *SQLITE_STDCALL sqlite3_malloc64(sqlite3_uint64);
+SQLITE_API void *SQLITE_STDCALL sqlite3_realloc(void*, int);
+SQLITE_API void *SQLITE_STDCALL sqlite3_realloc64(void*, sqlite3_uint64);
+SQLITE_API void SQLITE_STDCALL sqlite3_free(void*);
+SQLITE_API sqlite3_uint64 SQLITE_STDCALL sqlite3_msize(void*);
/*
** CAPI3REF: Memory Allocator Statistics
@@ -2287,8 +2520,8 @@ SQLITE_API void sqlite3_free(void*);
** 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);
+SQLITE_API sqlite3_int64 SQLITE_STDCALL sqlite3_memory_used(void);
+SQLITE_API sqlite3_int64 SQLITE_STDCALL sqlite3_memory_highwater(int resetFlag);
/*
** CAPI3REF: Pseudo-Random Number Generator
@@ -2300,18 +2533,22 @@ SQLITE_API sqlite3_int64 sqlite3_memory_highwater(int resetFlag);
** 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
+** ^The P parameter can be a NULL pointer.
+**
+** ^If this routine has not been previously called or if the previous
+** call had N less than one or a NULL pointer for P, then the PRNG is
+** seeded using randomness obtained from the xRandomness method of
+** the default [sqlite3_vfs] object.
+** ^If the previous call to this routine had an N of 1 or more and a
+** non-NULL P then the pseudo-randomness is generated
** internally and without recourse to the [sqlite3_vfs] xRandomness
** method.
*/
-SQLITE_API void sqlite3_randomness(int N, void *P);
+SQLITE_API void SQLITE_STDCALL sqlite3_randomness(int N, void *P);
/*
** CAPI3REF: Compile-Time Authorization Callbacks
+** METHOD: sqlite3
**
** ^This routine registers an authorizer callback with a particular
** [database connection], supplied in the first argument.
@@ -2390,7 +2627,7 @@ SQLITE_API void sqlite3_randomness(int N, void *P);
** 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(
+SQLITE_API int SQLITE_STDCALL sqlite3_set_authorizer(
sqlite3*,
int (*xAuth)(void*,int,const char*,const char*,const char*,const char*),
void *pUserData
@@ -2405,8 +2642,8 @@ SQLITE_API int sqlite3_set_authorizer(
** [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.
+** Note that SQLITE_IGNORE is also used as a [conflict resolution mode]
+** returned 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 */
@@ -2464,9 +2701,11 @@ SQLITE_API int sqlite3_set_authorizer(
#define SQLITE_FUNCTION 31 /* NULL Function Name */
#define SQLITE_SAVEPOINT 32 /* Operation Savepoint Name */
#define SQLITE_COPY 0 /* No longer used */
+#define SQLITE_RECURSIVE 33 /* NULL NULL */
/*
** CAPI3REF: Tracing And Profiling Functions
+** METHOD: sqlite3
**
** These routines register callback functions that can be used for
** tracing and profiling the execution of SQL statements.
@@ -2479,6 +2718,9 @@ SQLITE_API int sqlite3_set_authorizer(
** as each triggered subprogram is entered. The callbacks for triggers
** contain a UTF-8 SQL comment that identifies the trigger.)^
**
+** The [SQLITE_TRACE_SIZE_LIMIT] compile-time option can be used to limit
+** the length of [bound parameter] expansion in the output of sqlite3_trace().
+**
** ^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
@@ -2490,12 +2732,13 @@ SQLITE_API int sqlite3_set_authorizer(
** 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*,
+SQLITE_API void *SQLITE_STDCALL sqlite3_trace(sqlite3*, void(*xTrace)(void*,const char*), void*);
+SQLITE_API SQLITE_EXPERIMENTAL void *SQLITE_STDCALL sqlite3_profile(sqlite3*,
void(*xProfile)(void*,const char*,sqlite3_uint64), void*);
/*
** CAPI3REF: Query Progress Callbacks
+** METHOD: sqlite3
**
** ^The sqlite3_progress_handler(D,N,X,P) interface causes the callback
** function X to be invoked periodically during long running calls to
@@ -2504,9 +2747,10 @@ SQLITE_API SQLITE_EXPERIMENTAL void *sqlite3_profile(sqlite3*,
** 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
+** callback function X. ^The parameter N is the approximate number of
** [virtual machine instructions] that are evaluated between successive
-** invocations of the callback X.
+** invocations of the callback X. ^If N is less than one then the progress
+** handler is disabled.
**
** ^Only a single progress handler may be defined at one time per
** [database connection]; setting a new progress handler cancels the
@@ -2524,10 +2768,11 @@ SQLITE_API SQLITE_EXPERIMENTAL void *sqlite3_profile(sqlite3*,
** database connections for the meaning of "modify" in this paragraph.
**
*/
-SQLITE_API void sqlite3_progress_handler(sqlite3*, int, int(*)(void*), void*);
+SQLITE_API void SQLITE_STDCALL sqlite3_progress_handler(sqlite3*, int, int(*)(void*), void*);
/*
** CAPI3REF: Opening A New Database Connection
+** CONSTRUCTOR: sqlite3
**
** ^These routines open an SQLite database file as specified by the
** filename argument. ^The filename argument is interpreted as UTF-8 for
@@ -2542,9 +2787,9 @@ SQLITE_API void sqlite3_progress_handler(sqlite3*, int, int(*)(void*), void*);
** 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.
+** ^The default encoding will be UTF-8 for databases created using
+** sqlite3_open() or sqlite3_open_v2(). ^The default encoding for databases
+** created using sqlite3_open16() will be UTF-16 in the native byte order.
**
** Whether or not an error occurs when it is opened, resources
** associated with the [database connection] handle should be released by
@@ -2632,13 +2877,14 @@ SQLITE_API void sqlite3_progress_handler(sqlite3*, int, int(*)(void*), void*);
** 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:").
+** ^(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:
+** SQLite and its built-in [VFSes] interpret the
+** following query parameters:
**
** <ul>
** <li> <b>vfs</b>: ^The "vfs" parameter may be used to specify the name of
@@ -2670,8 +2916,30 @@ SQLITE_API void sqlite3_progress_handler(sqlite3*, int, int(*)(void*), void*);
** 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
+** a URI filename, its value overrides any behavior requested by setting
** SQLITE_OPEN_PRIVATECACHE or SQLITE_OPEN_SHAREDCACHE flag.
+**
+** <li> <b>psow</b>: ^The psow parameter indicates whether or not the
+** [powersafe overwrite] property does or does not apply to the
+** storage media on which the database file resides.
+**
+** <li> <b>nolock</b>: ^The nolock parameter is a boolean query parameter
+** which if set disables file locking in rollback journal modes. This
+** is useful for accessing a database on a filesystem that does not
+** support locking. Caution: Database corruption might result if two
+** or more processes write to the same database and any one of those
+** processes uses nolock=1.
+**
+** <li> <b>immutable</b>: ^The immutable parameter is a boolean query
+** parameter that indicates that the database file is stored on
+** read-only media. ^When immutable is set, SQLite assumes that the
+** database file cannot be changed, even by a process with higher
+** privilege, and so the database is opened read-only and all locking
+** and change detection is disabled. Caution: Setting the immutable
+** property on a database file that does in fact change can result
+** in incorrect query results and/or [SQLITE_CORRUPT] errors.
+** See also: [SQLITE_IOCAP_IMMUTABLE].
+**
** </ul>
**
** ^Specifying an unknown parameter in the query component of a URI is not an
@@ -2701,8 +2969,9 @@ SQLITE_API void sqlite3_progress_handler(sqlite3*, int, int(*)(void*), void*);
** 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:/home/fred/data.db?vfs=unix-dotfile <td>
+** Open file "/home/fred/data.db". Use the special VFS "unix-dotfile"
+** that uses dot-files in place of posix advisory locking.
** <tr><td> file:data.db?mode=readonly <td>
** An error. "readonly" is not a valid option for the "mode" parameter.
** </table>
@@ -2728,15 +2997,15 @@ SQLITE_API void sqlite3_progress_handler(sqlite3*, int, int(*)(void*), void*);
**
** See also: [sqlite3_temp_directory]
*/
-SQLITE_API int sqlite3_open(
+SQLITE_API int SQLITE_STDCALL sqlite3_open(
const char *filename, /* Database filename (UTF-8) */
sqlite3 **ppDb /* OUT: SQLite db handle */
);
-SQLITE_API int sqlite3_open16(
+SQLITE_API int SQLITE_STDCALL sqlite3_open16(
const void *filename, /* Database filename (UTF-16) */
sqlite3 **ppDb /* OUT: SQLite db handle */
);
-SQLITE_API int sqlite3_open_v2(
+SQLITE_API int SQLITE_STDCALL sqlite3_open_v2(
const char *filename, /* Database filename (UTF-8) */
sqlite3 **ppDb, /* OUT: SQLite db handle */
int flags, /* Flags */
@@ -2782,19 +3051,22 @@ SQLITE_API int sqlite3_open_v2(
** 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);
+SQLITE_API const char *SQLITE_STDCALL sqlite3_uri_parameter(const char *zFilename, const char *zParam);
+SQLITE_API int SQLITE_STDCALL sqlite3_uri_boolean(const char *zFile, const char *zParam, int bDefault);
+SQLITE_API sqlite3_int64 SQLITE_STDCALL 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()
+** METHOD: sqlite3
+**
+** ^If the most recent sqlite3_* API call associated with
+** [database connection] D failed, then the sqlite3_errcode(D) interface
+** returns the numeric [result code] or [extended result code] for that
+** API call.
+** If the most recent API call was successful,
+** then 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.
@@ -2825,40 +3097,41 @@ SQLITE_API sqlite3_int64 sqlite3_uri_int64(const char*, const char*, sqlite3_int
** 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);
+SQLITE_API int SQLITE_STDCALL sqlite3_errcode(sqlite3 *db);
+SQLITE_API int SQLITE_STDCALL sqlite3_extended_errcode(sqlite3 *db);
+SQLITE_API const char *SQLITE_STDCALL sqlite3_errmsg(sqlite3*);
+SQLITE_API const void *SQLITE_STDCALL sqlite3_errmsg16(sqlite3*);
+SQLITE_API const char *SQLITE_STDCALL sqlite3_errstr(int);
/*
-** CAPI3REF: SQL Statement Object
+** CAPI3REF: Prepared 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".
+** An instance of this object represents a single SQL statement that
+** has been compiled into binary form and is ready to be evaluated.
+**
+** Think of each SQL statement as a separate computer program. The
+** original SQL text is source code. A prepared statement object
+** is the compiled object code. All SQL must be converted into a
+** prepared statement before it can be run.
**
-** The life of a statement object goes something like this:
+** The life-cycle of a prepared statement object usually goes 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_*()
+** <li> Create the prepared statement object using [sqlite3_prepare_v2()].
+** <li> Bind values to [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
+** <li> Reset the prepared 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
+** METHOD: sqlite3
**
** ^(This interface allows the size of various constructs to be limited
** on a connection by connection basis. The first parameter is the
@@ -2896,7 +3169,7 @@ typedef struct sqlite3_stmt sqlite3_stmt;
**
** New run-time limit categories may be added in future releases.
*/
-SQLITE_API int sqlite3_limit(sqlite3*, int id, int newVal);
+SQLITE_API int SQLITE_STDCALL sqlite3_limit(sqlite3*, int id, int newVal);
/*
** CAPI3REF: Run-Time Limit Categories
@@ -2948,6 +3221,10 @@ SQLITE_API int sqlite3_limit(sqlite3*, int id, int newVal);
**
** [[SQLITE_LIMIT_TRIGGER_DEPTH]] ^(<dt>SQLITE_LIMIT_TRIGGER_DEPTH</dt>
** <dd>The maximum depth of recursion for triggers.</dd>)^
+**
+** [[SQLITE_LIMIT_WORKER_THREADS]] ^(<dt>SQLITE_LIMIT_WORKER_THREADS</dt>
+** <dd>The maximum number of auxiliary worker threads that a single
+** [prepared statement] may start.</dd>)^
** </dl>
*/
#define SQLITE_LIMIT_LENGTH 0
@@ -2961,10 +3238,13 @@ SQLITE_API int sqlite3_limit(sqlite3*, int id, int newVal);
#define SQLITE_LIMIT_LIKE_PATTERN_LENGTH 8
#define SQLITE_LIMIT_VARIABLE_NUMBER 9
#define SQLITE_LIMIT_TRIGGER_DEPTH 10
+#define SQLITE_LIMIT_WORKER_THREADS 11
/*
** CAPI3REF: Compiling An SQL Statement
** KEYWORDS: {SQL statement compiler}
+** METHOD: sqlite3
+** CONSTRUCTOR: sqlite3_stmt
**
** To execute an SQL query, it must first be compiled into a byte-code
** program using one of these routines.
@@ -2978,16 +3258,14 @@ SQLITE_API int sqlite3_limit(sqlite3*, int id, int newVal);
** 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 the nByte argument is negative, then zSql is read up to the
+** first zero terminator. ^If nByte is positive, then it is the
+** number of bytes read from zSql. ^If nByte is zero, then no prepared
+** statement is generated.
+** If the caller knows that the supplied string is nul-terminated, then
+** there is a small performance advantage to passing an nByte parameter that
+** is the number of bytes in the input string <i>including</i>
+** the nul-terminator.
**
** ^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
@@ -3017,7 +3295,8 @@ SQLITE_API int sqlite3_limit(sqlite3*, int id, int newVal);
** <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.
+** statement and try to run it again. As many as [SQLITE_MAX_SCHEMA_RETRY]
+** retries will occur before sqlite3_step() gives up and returns an error.
** </li>
**
** <li>
@@ -3039,32 +3318,31 @@ SQLITE_API int sqlite3_limit(sqlite3*, int id, int newVal);
** 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(
+SQLITE_API int SQLITE_STDCALL 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(
+SQLITE_API int SQLITE_STDCALL 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(
+SQLITE_API int SQLITE_STDCALL 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(
+SQLITE_API int SQLITE_STDCALL sqlite3_prepare16_v2(
sqlite3 *db, /* Database handle */
const void *zSql, /* SQL statement, UTF-16 encoded */
int nByte, /* Maximum length of zSql in bytes. */
@@ -3074,15 +3352,17 @@ SQLITE_API int sqlite3_prepare16_v2(
/*
** CAPI3REF: Retrieving Statement SQL
+** METHOD: sqlite3_stmt
**
** ^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);
+SQLITE_API const char *SQLITE_STDCALL sqlite3_sql(sqlite3_stmt *pStmt);
/*
** CAPI3REF: Determine If An SQL Statement Writes The Database
+** METHOD: sqlite3_stmt
**
** ^The sqlite3_stmt_readonly(X) interface returns true (non-zero) if
** and only if the [prepared statement] X makes no direct changes to
@@ -3110,14 +3390,16 @@ SQLITE_API const char *sqlite3_sql(sqlite3_stmt *pStmt);
** 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);
+SQLITE_API int SQLITE_STDCALL sqlite3_stmt_readonly(sqlite3_stmt *pStmt);
/*
** CAPI3REF: Determine If A Prepared Statement Has Been Reset
+** METHOD: sqlite3_stmt
**
** ^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
+** [sqlite3_step(S)] but has neither run to completion (returned
+** [SQLITE_DONE] from [sqlite3_step(S)]) nor
** 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]
@@ -3129,7 +3411,7 @@ SQLITE_API int sqlite3_stmt_readonly(sqlite3_stmt *pStmt);
** for example, in diagnostic routines to search for prepared
** statements that are holding a transaction open.
*/
-SQLITE_API int sqlite3_stmt_busy(sqlite3_stmt*);
+SQLITE_API int SQLITE_STDCALL sqlite3_stmt_busy(sqlite3_stmt*);
/*
** CAPI3REF: Dynamically Typed Value Object
@@ -3144,7 +3426,9 @@ SQLITE_API int sqlite3_stmt_busy(sqlite3_stmt*);
** 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.
+** whether or not it requires a protected sqlite3_value. The
+** [sqlite3_value_dup()] interface can be used to construct a new
+** protected sqlite3_value from an unprotected sqlite3_value.
**
** The terms "protected" and "unprotected" refer to whether or not
** a mutex is held. An internal mutex is held for a protected
@@ -3188,6 +3472,7 @@ 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}
+** METHOD: sqlite3_stmt
**
** ^(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
@@ -3221,6 +3506,9 @@ typedef struct sqlite3_context sqlite3_context;
** parameter [SQLITE_LIMIT_VARIABLE_NUMBER] (default value: 999).
**
** ^The third argument is the value to bind to the parameter.
+** ^If the third parameter to sqlite3_bind_text() or sqlite3_bind_text16()
+** or sqlite3_bind_blob() is a NULL pointer then the fourth parameter
+** is ignored and the end result is the same as sqlite3_bind_null().
**
** ^(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
@@ -3231,18 +3519,18 @@ typedef struct sqlite3_context sqlite3_context;
** 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
+** or sqlite3_bind_text16() or sqlite3_bind_text64() 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
+** ^The fifth argument to the BLOB and string binding interfaces
+** 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.
+** to dispose of the BLOB or string even if the call to bind API 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.
@@ -3250,6 +3538,14 @@ typedef struct sqlite3_context sqlite3_context;
** SQLite makes its own private copy of the data immediately, before
** the sqlite3_bind_*() routine returns.
**
+** ^The sixth argument to sqlite3_bind_text64() must be one of
+** [SQLITE_UTF8], [SQLITE_UTF16], [SQLITE_UTF16BE], or [SQLITE_UTF16LE]
+** to specify the encoding of the text in the third parameter. If
+** the sixth argument to sqlite3_bind_text64() is not one of the
+** allowed values shown above, or if the text encoding is different
+** from the encoding specified by the sixth parameter, then the behavior
+** is undefined.
+**
** ^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.
@@ -3270,24 +3566,33 @@ typedef struct sqlite3_context sqlite3_context;
**
** ^The sqlite3_bind_* routines return [SQLITE_OK] on success or an
** [error code] if anything goes wrong.
+** ^[SQLITE_TOOBIG] might be returned if the size of a string or BLOB
+** exceeds limits imposed by [sqlite3_limit]([SQLITE_LIMIT_LENGTH]) or
+** [SQLITE_MAX_LENGTH].
** ^[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);
+SQLITE_API int SQLITE_STDCALL sqlite3_bind_blob(sqlite3_stmt*, int, const void*, int n, void(*)(void*));
+SQLITE_API int SQLITE_STDCALL sqlite3_bind_blob64(sqlite3_stmt*, int, const void*, sqlite3_uint64,
+ void(*)(void*));
+SQLITE_API int SQLITE_STDCALL sqlite3_bind_double(sqlite3_stmt*, int, double);
+SQLITE_API int SQLITE_STDCALL sqlite3_bind_int(sqlite3_stmt*, int, int);
+SQLITE_API int SQLITE_STDCALL sqlite3_bind_int64(sqlite3_stmt*, int, sqlite3_int64);
+SQLITE_API int SQLITE_STDCALL sqlite3_bind_null(sqlite3_stmt*, int);
+SQLITE_API int SQLITE_STDCALL sqlite3_bind_text(sqlite3_stmt*,int,const char*,int,void(*)(void*));
+SQLITE_API int SQLITE_STDCALL sqlite3_bind_text16(sqlite3_stmt*, int, const void*, int, void(*)(void*));
+SQLITE_API int SQLITE_STDCALL sqlite3_bind_text64(sqlite3_stmt*, int, const char*, sqlite3_uint64,
+ void(*)(void*), unsigned char encoding);
+SQLITE_API int SQLITE_STDCALL sqlite3_bind_value(sqlite3_stmt*, int, const sqlite3_value*);
+SQLITE_API int SQLITE_STDCALL sqlite3_bind_zeroblob(sqlite3_stmt*, int, int n);
+SQLITE_API int SQLITE_STDCALL sqlite3_bind_zeroblob64(sqlite3_stmt*, int, sqlite3_uint64);
/*
** CAPI3REF: Number Of SQL Parameters
+** METHOD: sqlite3_stmt
**
** ^This routine can be used to find the number of [SQL parameters]
** in a [prepared statement]. SQL parameters are tokens of the
@@ -3304,10 +3609,11 @@ SQLITE_API int sqlite3_bind_zeroblob(sqlite3_stmt*, int, int n);
** [sqlite3_bind_parameter_name()], and
** [sqlite3_bind_parameter_index()].
*/
-SQLITE_API int sqlite3_bind_parameter_count(sqlite3_stmt*);
+SQLITE_API int SQLITE_STDCALL sqlite3_bind_parameter_count(sqlite3_stmt*);
/*
** CAPI3REF: Name Of A Host Parameter
+** METHOD: sqlite3_stmt
**
** ^The sqlite3_bind_parameter_name(P,N) interface returns
** the name of the N-th [SQL parameter] in the [prepared statement] P.
@@ -3331,10 +3637,11 @@ SQLITE_API int sqlite3_bind_parameter_count(sqlite3_stmt*);
** [sqlite3_bind_parameter_count()], and
** [sqlite3_bind_parameter_index()].
*/
-SQLITE_API const char *sqlite3_bind_parameter_name(sqlite3_stmt*, int);
+SQLITE_API const char *SQLITE_STDCALL sqlite3_bind_parameter_name(sqlite3_stmt*, int);
/*
** CAPI3REF: Index Of A Parameter With A Given Name
+** METHOD: sqlite3_stmt
**
** ^Return the index of an SQL parameter given its name. ^The
** index value returned is suitable for use as the second
@@ -3345,21 +3652,23 @@ SQLITE_API const char *sqlite3_bind_parameter_name(sqlite3_stmt*, int);
**
** See also: [sqlite3_bind_blob|sqlite3_bind()],
** [sqlite3_bind_parameter_count()], and
-** [sqlite3_bind_parameter_index()].
+** [sqlite3_bind_parameter_name()].
*/
-SQLITE_API int sqlite3_bind_parameter_index(sqlite3_stmt*, const char *zName);
+SQLITE_API int SQLITE_STDCALL sqlite3_bind_parameter_index(sqlite3_stmt*, const char *zName);
/*
** CAPI3REF: Reset All Bindings On A Prepared Statement
+** METHOD: sqlite3_stmt
**
** ^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*);
+SQLITE_API int SQLITE_STDCALL sqlite3_clear_bindings(sqlite3_stmt*);
/*
** CAPI3REF: Number Of Columns In A Result Set
+** METHOD: sqlite3_stmt
**
** ^Return the number of columns in the result set returned by the
** [prepared statement]. ^This routine returns 0 if pStmt is an SQL
@@ -3367,10 +3676,11 @@ SQLITE_API int sqlite3_clear_bindings(sqlite3_stmt*);
**
** See also: [sqlite3_data_count()]
*/
-SQLITE_API int sqlite3_column_count(sqlite3_stmt *pStmt);
+SQLITE_API int SQLITE_STDCALL sqlite3_column_count(sqlite3_stmt *pStmt);
/*
** CAPI3REF: Column Names In A Result Set
+** METHOD: sqlite3_stmt
**
** ^These routines return the name assigned to a particular column
** in the result set of a [SELECT] statement. ^The sqlite3_column_name()
@@ -3395,11 +3705,12 @@ SQLITE_API int sqlite3_column_count(sqlite3_stmt *pStmt);
** 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);
+SQLITE_API const char *SQLITE_STDCALL sqlite3_column_name(sqlite3_stmt*, int N);
+SQLITE_API const void *SQLITE_STDCALL sqlite3_column_name16(sqlite3_stmt*, int N);
/*
** CAPI3REF: Source Of Data In A Query Result
+** METHOD: sqlite3_stmt
**
** ^These routines provide a means to determine the database, table, and
** table column that is the origin of a particular result column in
@@ -3443,15 +3754,16 @@ SQLITE_API const void *sqlite3_column_name16(sqlite3_stmt*, int N);
** 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);
+SQLITE_API const char *SQLITE_STDCALL sqlite3_column_database_name(sqlite3_stmt*,int);
+SQLITE_API const void *SQLITE_STDCALL sqlite3_column_database_name16(sqlite3_stmt*,int);
+SQLITE_API const char *SQLITE_STDCALL sqlite3_column_table_name(sqlite3_stmt*,int);
+SQLITE_API const void *SQLITE_STDCALL sqlite3_column_table_name16(sqlite3_stmt*,int);
+SQLITE_API const char *SQLITE_STDCALL sqlite3_column_origin_name(sqlite3_stmt*,int);
+SQLITE_API const void *SQLITE_STDCALL sqlite3_column_origin_name16(sqlite3_stmt*,int);
/*
** CAPI3REF: Declared Datatype Of A Query Result
+** METHOD: sqlite3_stmt
**
** ^(The first parameter is a [prepared statement].
** If this statement is a [SELECT] statement and the Nth column of the
@@ -3479,11 +3791,12 @@ SQLITE_API const void *sqlite3_column_origin_name16(sqlite3_stmt*,int);
** 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);
+SQLITE_API const char *SQLITE_STDCALL sqlite3_column_decltype(sqlite3_stmt*,int);
+SQLITE_API const void *SQLITE_STDCALL sqlite3_column_decltype16(sqlite3_stmt*,int);
/*
** CAPI3REF: Evaluate An SQL Statement
+** METHOD: sqlite3_stmt
**
** After a [prepared statement] has been prepared using either
** [sqlite3_prepare_v2()] or [sqlite3_prepare16_v2()] or one of the legacy
@@ -3559,10 +3872,11 @@ SQLITE_API const void *sqlite3_column_decltype16(sqlite3_stmt*,int);
** 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*);
+SQLITE_API int SQLITE_STDCALL sqlite3_step(sqlite3_stmt*);
/*
** CAPI3REF: Number of columns in a result set
+** METHOD: sqlite3_stmt
**
** ^The sqlite3_data_count(P) interface returns the number of columns in the
** current row of the result set of [prepared statement] P.
@@ -3579,7 +3893,7 @@ SQLITE_API int sqlite3_step(sqlite3_stmt*);
**
** See also: [sqlite3_column_count()]
*/
-SQLITE_API int sqlite3_data_count(sqlite3_stmt *pStmt);
+SQLITE_API int SQLITE_STDCALL sqlite3_data_count(sqlite3_stmt *pStmt);
/*
** CAPI3REF: Fundamental Datatypes
@@ -3616,8 +3930,7 @@ SQLITE_API int sqlite3_data_count(sqlite3_stmt *pStmt);
/*
** CAPI3REF: Result Values From A Query
** KEYWORDS: {column access functions}
-**
-** These routines form the "result set" interface.
+** METHOD: sqlite3_stmt
**
** ^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
@@ -3678,13 +3991,14 @@ SQLITE_API int sqlite3_data_count(sqlite3_stmt *pStmt);
** 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()].
+** <b>Warning:</b> ^The object returned by [sqlite3_column_value()] is an
+** [unprotected sqlite3_value] object. In a multithreaded environment,
+** an unprotected sqlite3_value object may only be used safely 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.
+** or [sqlite3_value_bytes()], the behavior is not threadsafe.
**
** These routines attempt to convert the value where appropriate. ^For
** example, if the internal representation is FLOAT and a text result
@@ -3698,29 +4012,23 @@ SQLITE_API int sqlite3_data_count(sqlite3_stmt *pStmt);
**
** <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> NULL <td> TEXT <td> Result is a NULL pointer
+** <tr><td> NULL <td> BLOB <td> Result is a 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> INTEGER <td> [CAST] 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> FLOAT <td> BLOB <td> [CAST] to BLOB
+** <tr><td> TEXT <td> INTEGER <td> [CAST] to INTEGER
+** <tr><td> TEXT <td> FLOAT <td> [CAST] to REAL
** <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> INTEGER <td> [CAST] to INTEGER
+** <tr><td> BLOB <td> FLOAT <td> [CAST] to REAL
** <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.
@@ -3745,7 +4053,7 @@ SQLITE_API int sqlite3_data_count(sqlite3_stmt *pStmt);
** 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
+** The safest policy is to invoke these routines
** in one of the following ways:
**
** <ul>
@@ -3765,8 +4073,8 @@ SQLITE_API int sqlite3_data_count(sqlite3_stmt *pStmt);
** ^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
+** and BLOBs is freed automatically. Do <em>not</em> pass the pointers returned
+** from [sqlite3_column_blob()], [sqlite3_column_text()], etc. into
** [sqlite3_free()].
**
** ^(If a memory allocation error occurs during the evaluation of any
@@ -3775,19 +4083,20 @@ SQLITE_API int sqlite3_data_count(sqlite3_stmt *pStmt);
** 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);
+SQLITE_API const void *SQLITE_STDCALL sqlite3_column_blob(sqlite3_stmt*, int iCol);
+SQLITE_API int SQLITE_STDCALL sqlite3_column_bytes(sqlite3_stmt*, int iCol);
+SQLITE_API int SQLITE_STDCALL sqlite3_column_bytes16(sqlite3_stmt*, int iCol);
+SQLITE_API double SQLITE_STDCALL sqlite3_column_double(sqlite3_stmt*, int iCol);
+SQLITE_API int SQLITE_STDCALL sqlite3_column_int(sqlite3_stmt*, int iCol);
+SQLITE_API sqlite3_int64 SQLITE_STDCALL sqlite3_column_int64(sqlite3_stmt*, int iCol);
+SQLITE_API const unsigned char *SQLITE_STDCALL sqlite3_column_text(sqlite3_stmt*, int iCol);
+SQLITE_API const void *SQLITE_STDCALL sqlite3_column_text16(sqlite3_stmt*, int iCol);
+SQLITE_API int SQLITE_STDCALL sqlite3_column_type(sqlite3_stmt*, int iCol);
+SQLITE_API sqlite3_value *SQLITE_STDCALL sqlite3_column_value(sqlite3_stmt*, int iCol);
/*
** CAPI3REF: Destroy A Prepared Statement Object
+** DESTRUCTOR: sqlite3_stmt
**
** ^The sqlite3_finalize() function is called to delete a [prepared statement].
** ^If the most recent evaluation of the statement encountered no errors
@@ -3811,10 +4120,11 @@ SQLITE_API sqlite3_value *sqlite3_column_value(sqlite3_stmt*, int iCol);
** 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);
+SQLITE_API int SQLITE_STDCALL sqlite3_finalize(sqlite3_stmt *pStmt);
/*
** CAPI3REF: Reset A Prepared Statement Object
+** METHOD: sqlite3_stmt
**
** The sqlite3_reset() function is called to reset a [prepared statement]
** object back to its initial state, ready to be re-executed.
@@ -3837,13 +4147,14 @@ SQLITE_API int sqlite3_finalize(sqlite3_stmt *pStmt);
** ^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);
+SQLITE_API int SQLITE_STDCALL 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}
+** METHOD: sqlite3
**
** ^These functions (collectively known as "function creation routines")
** are used to add SQL functions or aggregates or to redefine the behavior
@@ -3875,15 +4186,24 @@ SQLITE_API int sqlite3_reset(sqlite3_stmt *pStmt);
**
** ^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.
+** its parameters. The application should set this parameter to
+** [SQLITE_UTF16LE] if the function implementation invokes
+** [sqlite3_value_text16le()] on an input, or [SQLITE_UTF16BE] if the
+** implementation invokes [sqlite3_value_text16be()] on an input, or
+** [SQLITE_UTF16] if [sqlite3_value_text16()] is used, or [SQLITE_UTF8]
+** otherwise. ^The same SQL function may be registered multiple times using
+** different preferred text encodings, with different implementations for
+** each encoding.
** ^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 fourth parameter may optionally be ORed with [SQLITE_DETERMINISTIC]
+** to signal that the function will always return the same result given
+** the same inputs within a single SQL statement. Most SQL functions are
+** deterministic. The built-in [random()] SQL function is an example of a
+** function that is not deterministic. The SQLite query planner is able to
+** perform additional optimizations on deterministic functions, so use
+** of the [SQLITE_DETERMINISTIC] flag is recommended where possible.
**
** ^(The fifth parameter is an arbitrary pointer. The implementation of the
** function can gain access to this pointer using [sqlite3_user_data()].)^
@@ -3927,7 +4247,7 @@ SQLITE_API int sqlite3_reset(sqlite3_stmt *pStmt);
** close the database connection nor finalize or reset the prepared
** statement in which the function is running.
*/
-SQLITE_API int sqlite3_create_function(
+SQLITE_API int SQLITE_STDCALL sqlite3_create_function(
sqlite3 *db,
const char *zFunctionName,
int nArg,
@@ -3937,7 +4257,7 @@ SQLITE_API int sqlite3_create_function(
void (*xStep)(sqlite3_context*,int,sqlite3_value**),
void (*xFinal)(sqlite3_context*)
);
-SQLITE_API int sqlite3_create_function16(
+SQLITE_API int SQLITE_STDCALL sqlite3_create_function16(
sqlite3 *db,
const void *zFunctionName,
int nArg,
@@ -3947,7 +4267,7 @@ SQLITE_API int sqlite3_create_function16(
void (*xStep)(sqlite3_context*,int,sqlite3_value**),
void (*xFinal)(sqlite3_context*)
);
-SQLITE_API int sqlite3_create_function_v2(
+SQLITE_API int SQLITE_STDCALL sqlite3_create_function_v2(
sqlite3 *db,
const char *zFunctionName,
int nArg,
@@ -3965,38 +4285,50 @@ SQLITE_API int sqlite3_create_function_v2(
** 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_UTF8 1 /* IMP: R-37514-35566 */
+#define SQLITE_UTF16LE 2 /* IMP: R-03371-37637 */
+#define SQLITE_UTF16BE 3 /* IMP: R-51971-34154 */
#define SQLITE_UTF16 4 /* Use native byte order */
-#define SQLITE_ANY 5 /* sqlite3_create_function only */
+#define SQLITE_ANY 5 /* Deprecated */
#define SQLITE_UTF16_ALIGNED 8 /* sqlite3_create_collation only */
/*
+** CAPI3REF: Function Flags
+**
+** These constants may be ORed together with the
+** [SQLITE_UTF8 | preferred text encoding] as the fourth argument
+** to [sqlite3_create_function()], [sqlite3_create_function16()], or
+** [sqlite3_create_function_v2()].
+*/
+#define SQLITE_DETERMINISTIC 0x800
+
+/*
** 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.
+** the use of these functions. To encourage programmers to avoid
+** these functions, we will not explain 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);
+SQLITE_API SQLITE_DEPRECATED int SQLITE_STDCALL sqlite3_aggregate_count(sqlite3_context*);
+SQLITE_API SQLITE_DEPRECATED int SQLITE_STDCALL sqlite3_expired(sqlite3_stmt*);
+SQLITE_API SQLITE_DEPRECATED int SQLITE_STDCALL sqlite3_transfer_bindings(sqlite3_stmt*, sqlite3_stmt*);
+SQLITE_API SQLITE_DEPRECATED int SQLITE_STDCALL sqlite3_global_recover(void);
+SQLITE_API SQLITE_DEPRECATED void SQLITE_STDCALL sqlite3_thread_cleanup(void);
+SQLITE_API SQLITE_DEPRECATED int SQLITE_STDCALL sqlite3_memory_alarm(void(*)(void*,sqlite3_int64,int),
+ void*,sqlite3_int64);
#endif
/*
-** CAPI3REF: Obtaining SQL Function Parameter Values
+** CAPI3REF: Obtaining SQL Values
+** METHOD: sqlite3_value
**
** 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 function or aggregate.
**
** The xFunc (for scalar functions) or xStep (for aggregates) parameters
** to [sqlite3_create_function()] and [sqlite3_create_function16()]
@@ -4011,7 +4343,7 @@ SQLITE_API SQLITE_DEPRECATED int sqlite3_memory_alarm(void(*)(void*,sqlite3_int6
** 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
+** 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
@@ -4036,21 +4368,55 @@ SQLITE_API SQLITE_DEPRECATED int sqlite3_memory_alarm(void(*)(void*,sqlite3_int6
** 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*);
+SQLITE_API const void *SQLITE_STDCALL sqlite3_value_blob(sqlite3_value*);
+SQLITE_API int SQLITE_STDCALL sqlite3_value_bytes(sqlite3_value*);
+SQLITE_API int SQLITE_STDCALL sqlite3_value_bytes16(sqlite3_value*);
+SQLITE_API double SQLITE_STDCALL sqlite3_value_double(sqlite3_value*);
+SQLITE_API int SQLITE_STDCALL sqlite3_value_int(sqlite3_value*);
+SQLITE_API sqlite3_int64 SQLITE_STDCALL sqlite3_value_int64(sqlite3_value*);
+SQLITE_API const unsigned char *SQLITE_STDCALL sqlite3_value_text(sqlite3_value*);
+SQLITE_API const void *SQLITE_STDCALL sqlite3_value_text16(sqlite3_value*);
+SQLITE_API const void *SQLITE_STDCALL sqlite3_value_text16le(sqlite3_value*);
+SQLITE_API const void *SQLITE_STDCALL sqlite3_value_text16be(sqlite3_value*);
+SQLITE_API int SQLITE_STDCALL sqlite3_value_type(sqlite3_value*);
+SQLITE_API int SQLITE_STDCALL sqlite3_value_numeric_type(sqlite3_value*);
+
+/*
+** CAPI3REF: Finding The Subtype Of SQL Values
+** METHOD: sqlite3_value
+**
+** The sqlite3_value_subtype(V) function returns the subtype for
+** an [application-defined SQL function] argument V. The subtype
+** information can be used to pass a limited amount of context from
+** one SQL function to another. Use the [sqlite3_result_subtype()]
+** routine to set the subtype for the return value of an SQL function.
+**
+** SQLite makes no use of subtype itself. It merely passes the subtype
+** from the result of one [application-defined SQL function] into the
+** input of another.
+*/
+SQLITE_API unsigned int SQLITE_STDCALL sqlite3_value_subtype(sqlite3_value*);
+
+/*
+** CAPI3REF: Copy And Free SQL Values
+** METHOD: sqlite3_value
+**
+** ^The sqlite3_value_dup(V) interface makes a copy of the [sqlite3_value]
+** object D and returns a pointer to that copy. ^The [sqlite3_value] returned
+** is a [protected sqlite3_value] object even if the input is not.
+** ^The sqlite3_value_dup(V) interface returns NULL if V is NULL or if a
+** memory allocation fails.
+**
+** ^The sqlite3_value_free(V) interface frees an [sqlite3_value] object
+** previously obtained from [sqlite3_value_dup()]. ^If V is a NULL pointer
+** then sqlite3_value_free(V) is a harmless no-op.
+*/
+SQLITE_API sqlite3_value *SQLITE_STDCALL sqlite3_value_dup(const sqlite3_value*);
+SQLITE_API void SQLITE_STDCALL sqlite3_value_free(sqlite3_value*);
/*
** CAPI3REF: Obtain Aggregate Function Context
+** METHOD: sqlite3_context
**
** Implementations of aggregate SQL functions use this
** routine to allocate memory for storing their state.
@@ -4068,14 +4434,17 @@ SQLITE_API int sqlite3_value_numeric_type(sqlite3_value*);
** 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 sqlite3_aggregate_context(C,N) routine returns a NULL pointer
+** when first called 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.)^
+** allocation.)^ Within the xFinal callback, it is customary to set
+** N=0 in calls to sqlite3_aggregate_context(C,N) so that no
+** pointless memory allocations occur.
**
** ^SQLite automatically frees the memory allocated by
** sqlite3_aggregate_context() when the aggregate query concludes.
@@ -4088,10 +4457,11 @@ SQLITE_API int sqlite3_value_numeric_type(sqlite3_value*);
** 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);
+SQLITE_API void *SQLITE_STDCALL sqlite3_aggregate_context(sqlite3_context*, int nBytes);
/*
** CAPI3REF: User Data For Functions
+** METHOD: sqlite3_context
**
** ^The sqlite3_user_data() interface returns a copy of
** the pointer that was the pUserData parameter (the 5th parameter)
@@ -4102,10 +4472,11 @@ SQLITE_API void *sqlite3_aggregate_context(sqlite3_context*, int nBytes);
** 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*);
+SQLITE_API void *SQLITE_STDCALL sqlite3_user_data(sqlite3_context*);
/*
** CAPI3REF: Database Connection For Functions
+** METHOD: sqlite3_context
**
** ^The sqlite3_context_db_handle() interface returns a copy of
** the pointer to the [database connection] (the 1st parameter)
@@ -4113,52 +4484,61 @@ SQLITE_API void *sqlite3_user_data(sqlite3_context*);
** and [sqlite3_create_function16()] routines that originally
** registered the application defined function.
*/
-SQLITE_API sqlite3 *sqlite3_context_db_handle(sqlite3_context*);
+SQLITE_API sqlite3 *SQLITE_STDCALL sqlite3_context_db_handle(sqlite3_context*);
/*
** CAPI3REF: Function Auxiliary Data
+** METHOD: sqlite3_context
**
-** The following two functions may be used by scalar SQL functions to
+** These functions may be used by (non-aggregate) 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.
+** some circumstances the associated metadata may be preserved. An example
+** of where this might be useful is in a regular-expression matching
+** function. The compiled version of the regular expression can be stored as
+** metadata associated with the pattern string.
+** Then as long as the pattern string remains the same,
+** the compiled regular expression can be reused on multiple
+** invocations of the same function.
**
** ^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.
+** value to the application-defined function. ^If there is no metadata
+** associated with the function argument, this sqlite3_get_auxdata() interface
+** returns a NULL pointer.
+**
+** ^The sqlite3_set_auxdata(C,N,P,X) interface saves P as metadata for the N-th
+** argument of the application-defined function. ^Subsequent
+** calls to sqlite3_get_auxdata(C,N) return P from the most recent
+** sqlite3_set_auxdata(C,N,P,X) call if the metadata is still valid or
+** NULL if the metadata has been discarded.
+** ^After each call to sqlite3_set_auxdata(C,N,P,X) where X is not NULL,
+** SQLite will invoke the destructor function X with parameter P exactly
+** once, when the metadata is discarded.
+** SQLite is free to discard the metadata at any time, including: <ul>
+** <li> when the corresponding function parameter changes, or
+** <li> when [sqlite3_reset()] or [sqlite3_finalize()] is called for the
+** SQL statement, or
+** <li> when sqlite3_set_auxdata() is invoked again on the same parameter, or
+** <li> during the original sqlite3_set_auxdata() call when a memory
+** allocation error occurs. </ul>)^
+**
+** Note the last bullet in particular. The destructor X in
+** sqlite3_set_auxdata(C,N,P,X) might be called immediately, before the
+** sqlite3_set_auxdata() interface even returns. Hence sqlite3_set_auxdata()
+** should be called near the end of the function implementation and the
+** function implementation should not make any use of P after
+** sqlite3_set_auxdata() has been called.
**
** ^(In practice, metadata is preserved between function calls for
-** expressions that are constant at compile time. This includes literal
-** values and [parameters].)^
+** function parameters that are compile-time constants, including literal
+** values and [parameters] and expressions composed from the same.)^
**
** 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*));
+SQLITE_API void *SQLITE_STDCALL sqlite3_get_auxdata(sqlite3_context*, int N);
+SQLITE_API void SQLITE_STDCALL sqlite3_set_auxdata(sqlite3_context*, int N, void*, void (*)(void*));
/*
@@ -4173,7 +4553,7 @@ SQLITE_API void sqlite3_set_auxdata(sqlite3_context*, int N, void*, void (*)(voi
** the content before returning.
**
** The typedef is necessary to work around problems in certain
-** C++ compilers. See ticket #2191.
+** C++ compilers.
*/
typedef void (*sqlite3_destructor_type)(void*);
#define SQLITE_STATIC ((sqlite3_destructor_type)0)
@@ -4181,6 +4561,7 @@ typedef void (*sqlite3_destructor_type)(void*);
/*
** CAPI3REF: Setting The Result Of An SQL Function
+** METHOD: sqlite3_context
**
** These routines are used by the xFunc or xFinal callbacks that
** implement SQL functions and aggregates. See
@@ -4196,9 +4577,9 @@ typedef void (*sqlite3_destructor_type)(void*);
** 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_zeroblob(C,N) and sqlite3_result_zeroblob64(C,N)
+** interfaces set the result of the application-defined function to be
+** a BLOB containing all zero bytes and N bytes in size.
**
** ^The sqlite3_result_double() interface sets the result from
** an application-defined function to be a floating point value specified
@@ -4247,6 +4628,10 @@ typedef void (*sqlite3_destructor_type)(void*);
** 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.
+** ^The sqlite3_result_text64() interface sets the return value of an
+** application-defined function to be a text string in an encoding
+** specified by the fifth (and last) parameter, which must be one
+** of [SQLITE_UTF8], [SQLITE_UTF16], [SQLITE_UTF16BE], or [SQLITE_UTF16LE].
** ^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
@@ -4276,7 +4661,7 @@ typedef void (*sqlite3_destructor_type)(void*);
** from [sqlite3_malloc()] before it returns.
**
** ^The sqlite3_result_value() interface sets the result of
-** the application-defined function to be a copy the
+** the application-defined function to be a copy of 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
@@ -4289,25 +4674,46 @@ typedef void (*sqlite3_destructor_type)(void*);
** 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);
+SQLITE_API void SQLITE_STDCALL sqlite3_result_blob(sqlite3_context*, const void*, int, void(*)(void*));
+SQLITE_API void SQLITE_STDCALL sqlite3_result_blob64(sqlite3_context*,const void*,
+ sqlite3_uint64,void(*)(void*));
+SQLITE_API void SQLITE_STDCALL sqlite3_result_double(sqlite3_context*, double);
+SQLITE_API void SQLITE_STDCALL sqlite3_result_error(sqlite3_context*, const char*, int);
+SQLITE_API void SQLITE_STDCALL sqlite3_result_error16(sqlite3_context*, const void*, int);
+SQLITE_API void SQLITE_STDCALL sqlite3_result_error_toobig(sqlite3_context*);
+SQLITE_API void SQLITE_STDCALL sqlite3_result_error_nomem(sqlite3_context*);
+SQLITE_API void SQLITE_STDCALL sqlite3_result_error_code(sqlite3_context*, int);
+SQLITE_API void SQLITE_STDCALL sqlite3_result_int(sqlite3_context*, int);
+SQLITE_API void SQLITE_STDCALL sqlite3_result_int64(sqlite3_context*, sqlite3_int64);
+SQLITE_API void SQLITE_STDCALL sqlite3_result_null(sqlite3_context*);
+SQLITE_API void SQLITE_STDCALL sqlite3_result_text(sqlite3_context*, const char*, int, void(*)(void*));
+SQLITE_API void SQLITE_STDCALL sqlite3_result_text64(sqlite3_context*, const char*,sqlite3_uint64,
+ void(*)(void*), unsigned char encoding);
+SQLITE_API void SQLITE_STDCALL sqlite3_result_text16(sqlite3_context*, const void*, int, void(*)(void*));
+SQLITE_API void SQLITE_STDCALL sqlite3_result_text16le(sqlite3_context*, const void*, int,void(*)(void*));
+SQLITE_API void SQLITE_STDCALL sqlite3_result_text16be(sqlite3_context*, const void*, int,void(*)(void*));
+SQLITE_API void SQLITE_STDCALL sqlite3_result_value(sqlite3_context*, sqlite3_value*);
+SQLITE_API void SQLITE_STDCALL sqlite3_result_zeroblob(sqlite3_context*, int n);
+SQLITE_API int SQLITE_STDCALL sqlite3_result_zeroblob64(sqlite3_context*, sqlite3_uint64 n);
+
+
+/*
+** CAPI3REF: Setting The Subtype Of An SQL Function
+** METHOD: sqlite3_context
+**
+** The sqlite3_result_subtype(C,T) function causes the subtype of
+** the result from the [application-defined SQL function] with
+** [sqlite3_context] C to be the value T. Only the lower 8 bits
+** of the subtype T are preserved in current versions of SQLite;
+** higher order bits are discarded.
+** The number of subtype bytes preserved by SQLite might increase
+** in future releases of SQLite.
+*/
+SQLITE_API void SQLITE_STDCALL sqlite3_result_subtype(sqlite3_context*,unsigned int);
/*
** CAPI3REF: Define New Collating Sequences
+** METHOD: sqlite3
**
** ^These functions add, remove, or modify a [collation] associated
** with the [database connection] specified as the first argument.
@@ -4385,14 +4791,14 @@ SQLITE_API void sqlite3_result_zeroblob(sqlite3_context*, int n);
**
** See also: [sqlite3_collation_needed()] and [sqlite3_collation_needed16()].
*/
-SQLITE_API int sqlite3_create_collation(
+SQLITE_API int SQLITE_STDCALL 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(
+SQLITE_API int SQLITE_STDCALL sqlite3_create_collation_v2(
sqlite3*,
const char *zName,
int eTextRep,
@@ -4400,7 +4806,7 @@ SQLITE_API int sqlite3_create_collation_v2(
int(*xCompare)(void*,int,const void*,int,const void*),
void(*xDestroy)(void*)
);
-SQLITE_API int sqlite3_create_collation16(
+SQLITE_API int SQLITE_STDCALL sqlite3_create_collation16(
sqlite3*,
const void *zName,
int eTextRep,
@@ -4410,6 +4816,7 @@ SQLITE_API int sqlite3_create_collation16(
/*
** CAPI3REF: Collation Needed Callbacks
+** METHOD: sqlite3
**
** ^To avoid having to register all collation sequences before a database
** can be used, a single callback function may be registered with the
@@ -4434,12 +4841,12 @@ SQLITE_API int sqlite3_create_collation16(
** [sqlite3_create_collation()], [sqlite3_create_collation16()], or
** [sqlite3_create_collation_v2()].
*/
-SQLITE_API int sqlite3_collation_needed(
+SQLITE_API int SQLITE_STDCALL sqlite3_collation_needed(
sqlite3*,
void*,
void(*)(void*,sqlite3*,int eTextRep,const char*)
);
-SQLITE_API int sqlite3_collation_needed16(
+SQLITE_API int SQLITE_STDCALL sqlite3_collation_needed16(
sqlite3*,
void*,
void(*)(void*,sqlite3*,int eTextRep,const void*)
@@ -4453,8 +4860,13 @@ SQLITE_API int sqlite3_collation_needed16(
** The code to implement this API is not available in the public release
** of SQLite.
*/
-SQLITE_API int sqlite3_key(
+SQLITE_API int SQLITE_STDCALL sqlite3_key(
+ sqlite3 *db, /* Database to be rekeyed */
+ const void *pKey, int nKey /* The key */
+);
+SQLITE_API int SQLITE_STDCALL sqlite3_key_v2(
sqlite3 *db, /* Database to be rekeyed */
+ const char *zDbName, /* Name of the database */
const void *pKey, int nKey /* The key */
);
@@ -4466,8 +4878,13 @@ SQLITE_API int sqlite3_key(
** The code to implement this API is not available in the public release
** of SQLite.
*/
-SQLITE_API int sqlite3_rekey(
+SQLITE_API int SQLITE_STDCALL sqlite3_rekey(
+ sqlite3 *db, /* Database to be rekeyed */
+ const void *pKey, int nKey /* The new key */
+);
+SQLITE_API int SQLITE_STDCALL sqlite3_rekey_v2(
sqlite3 *db, /* Database to be rekeyed */
+ const char *zDbName, /* Name of the database */
const void *pKey, int nKey /* The new key */
);
@@ -4475,7 +4892,7 @@ SQLITE_API int sqlite3_rekey(
** Specify the activation key for a SEE database. Unless
** activated, none of the SEE routines will work.
*/
-SQLITE_API void sqlite3_activate_see(
+SQLITE_API void SQLITE_STDCALL sqlite3_activate_see(
const char *zPassPhrase /* Activation phrase */
);
#endif
@@ -4485,7 +4902,7 @@ SQLITE_API void sqlite3_activate_see(
** Specify the activation key for a CEROD database. Unless
** activated, none of the CEROD routines will work.
*/
-SQLITE_API void sqlite3_activate_cerod(
+SQLITE_API void SQLITE_STDCALL sqlite3_activate_cerod(
const char *zPassPhrase /* Activation phrase */
);
#endif
@@ -4507,7 +4924,7 @@ SQLITE_API void sqlite3_activate_cerod(
** all, then the behavior of sqlite3_sleep() may deviate from the description
** in the previous paragraphs.
*/
-SQLITE_API int sqlite3_sleep(int);
+SQLITE_API int SQLITE_STDCALL sqlite3_sleep(int);
/*
** CAPI3REF: Name Of The Folder Holding Temporary Files
@@ -4519,6 +4936,13 @@ SQLITE_API int sqlite3_sleep(int);
** is a NULL pointer, then SQLite performs a search for an appropriate
** temporary file directory.
**
+** Applications are strongly discouraged from using this global variable.
+** It is required to set a temporary folder on Windows Runtime (WinRT).
+** But for all other platforms, it is highly recommended that applications
+** neither read nor write this variable. This global variable is a relic
+** that exists for backwards compatibility of legacy applications and should
+** be avoided in new projects.
+**
** 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
@@ -4537,6 +4961,11 @@ SQLITE_API int sqlite3_sleep(int);
** 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.
+** Except when requested by the [temp_store_directory pragma], SQLite
+** does not free the memory that sqlite3_temp_directory points to. If
+** the application wants that memory to be freed, it must do
+** so itself, taking care to only do so after all [database connection]
+** objects have been destroyed.
**
** <b>Note to Windows Runtime users:</b> The temporary directory must be set
** prior to calling [sqlite3_open] or [sqlite3_open_v2]. Otherwise, various
@@ -4595,6 +5024,7 @@ SQLITE_API SQLITE_EXTERN char *sqlite3_data_directory;
/*
** CAPI3REF: Test For Auto-Commit Mode
** KEYWORDS: {autocommit mode}
+** METHOD: sqlite3
**
** ^The sqlite3_get_autocommit() interface returns non-zero or
** zero if the given database connection is or is not in autocommit mode,
@@ -4613,10 +5043,11 @@ SQLITE_API SQLITE_EXTERN char *sqlite3_data_directory;
** connection while this routine is running, then the return value
** is undefined.
*/
-SQLITE_API int sqlite3_get_autocommit(sqlite3*);
+SQLITE_API int SQLITE_STDCALL sqlite3_get_autocommit(sqlite3*);
/*
** CAPI3REF: Find The Database Handle Of A Prepared Statement
+** METHOD: sqlite3_stmt
**
** ^The sqlite3_db_handle interface returns the [database connection] handle
** to which a [prepared statement] belongs. ^The [database connection]
@@ -4625,10 +5056,11 @@ SQLITE_API int sqlite3_get_autocommit(sqlite3*);
** 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*);
+SQLITE_API sqlite3 *SQLITE_STDCALL sqlite3_db_handle(sqlite3_stmt*);
/*
** CAPI3REF: Return The Filename For A Database Connection
+** METHOD: sqlite3
**
** ^The sqlite3_db_filename(D,N) interface returns a pointer to a filename
** associated with database N of connection D. ^The main database file
@@ -4641,19 +5073,21 @@ SQLITE_API sqlite3 *sqlite3_db_handle(sqlite3_stmt*);
** 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);
+SQLITE_API const char *SQLITE_STDCALL sqlite3_db_filename(sqlite3 *db, const char *zDbName);
/*
** CAPI3REF: Determine if a database is read-only
+** METHOD: sqlite3
**
** ^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);
+SQLITE_API int SQLITE_STDCALL sqlite3_db_readonly(sqlite3 *db, const char *zDbName);
/*
** CAPI3REF: Find the next prepared statement
+** METHOD: sqlite3
**
** ^This interface returns a pointer to the next [prepared statement] after
** pStmt associated with the [database connection] pDb. ^If pStmt is NULL
@@ -4665,10 +5099,11 @@ SQLITE_API int sqlite3_db_readonly(sqlite3 *db, const char *zDbName);
** [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);
+SQLITE_API sqlite3_stmt *SQLITE_STDCALL sqlite3_next_stmt(sqlite3 *pDb, sqlite3_stmt *pStmt);
/*
** CAPI3REF: Commit And Rollback Notification Callbacks
+** METHOD: sqlite3
**
** ^The sqlite3_commit_hook() interface registers a callback
** function to be invoked whenever a transaction is [COMMIT | committed].
@@ -4713,20 +5148,22 @@ SQLITE_API sqlite3_stmt *sqlite3_next_stmt(sqlite3 *pDb, sqlite3_stmt *pStmt);
**
** 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*);
+SQLITE_API void *SQLITE_STDCALL sqlite3_commit_hook(sqlite3*, int(*)(void*), void*);
+SQLITE_API void *SQLITE_STDCALL sqlite3_rollback_hook(sqlite3*, void(*)(void *), void*);
/*
** CAPI3REF: Data Change Notification Callbacks
+** METHOD: sqlite3
**
** ^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.
+** to be invoked whenever a row is updated, inserted or deleted in
+** a rowid table.
** ^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.
+** row is updated, inserted or deleted in a rowid table.
** ^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],
@@ -4739,6 +5176,7 @@ SQLITE_API void *sqlite3_rollback_hook(sqlite3*, void(*)(void *), void*);
**
** ^(The update hook is not invoked when internal system tables are
** modified (i.e. sqlite_master and sqlite_sequence).)^
+** ^The update hook is not invoked when [WITHOUT ROWID] tables are modified.
**
** ^In the current implementation, the update hook
** is not invoked when duplication rows are deleted because of an
@@ -4762,7 +5200,7 @@ SQLITE_API void *sqlite3_rollback_hook(sqlite3*, void(*)(void *), void*);
** See also the [sqlite3_commit_hook()] and [sqlite3_rollback_hook()]
** interfaces.
*/
-SQLITE_API void *sqlite3_update_hook(
+SQLITE_API void *SQLITE_STDCALL sqlite3_update_hook(
sqlite3*,
void(*)(void *,int ,char const *,char const *,sqlite3_int64),
void*
@@ -4792,12 +5230,17 @@ SQLITE_API void *sqlite3_update_hook(
** future releases of SQLite. Applications that care about shared
** cache setting should set it explicitly.
**
+** Note: This method is disabled on MacOS X 10.7 and iOS version 5.0
+** and will always return SQLITE_MISUSE. On those systems,
+** shared cache mode should be enabled per-database connection via
+** [sqlite3_open_v2()] with [SQLITE_OPEN_SHAREDCACHE].
+**
** 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);
+SQLITE_API int SQLITE_STDCALL sqlite3_enable_shared_cache(int);
/*
** CAPI3REF: Attempt To Free Heap Memory
@@ -4813,20 +5256,21 @@ SQLITE_API int sqlite3_enable_shared_cache(int);
**
** See also: [sqlite3_db_release_memory()]
*/
-SQLITE_API int sqlite3_release_memory(int);
+SQLITE_API int SQLITE_STDCALL sqlite3_release_memory(int);
/*
** CAPI3REF: Free Memory Used By A Database Connection
+** METHOD: sqlite3
**
** ^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
+** [sqlite3_release_memory()] interface, this interface is in effect even
+** when the [SQLITE_ENABLE_MEMORY_MANAGEMENT] compile-time option is
** omitted.
**
** See also: [sqlite3_release_memory()]
*/
-SQLITE_API int sqlite3_db_release_memory(sqlite3*);
+SQLITE_API int SQLITE_STDCALL sqlite3_db_release_memory(sqlite3*);
/*
** CAPI3REF: Impose A Limit On Heap Size
@@ -4878,7 +5322,7 @@ SQLITE_API int sqlite3_db_release_memory(sqlite3*);
** 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);
+SQLITE_API sqlite3_int64 SQLITE_STDCALL sqlite3_soft_heap_limit64(sqlite3_int64 N);
/*
** CAPI3REF: Deprecated Soft Heap Limit Interface
@@ -4889,26 +5333,34 @@ SQLITE_API sqlite3_int64 sqlite3_soft_heap_limit64(sqlite3_int64 N);
** 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);
+SQLITE_API SQLITE_DEPRECATED void SQLITE_STDCALL 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.
+** METHOD: sqlite3
+**
+** ^(The sqlite3_table_column_metadata(X,D,T,C,....) routine returns
+** information about column C of table T in database D
+** on [database connection] X.)^ ^The sqlite3_table_column_metadata()
+** interface returns SQLITE_OK and fills in the non-NULL pointers in
+** the final five arguments with appropriate values if the specified
+** column exists. ^The sqlite3_table_column_metadata() interface returns
+** SQLITE_ERROR and if the specified column does not exist.
+** ^If the column-name parameter to sqlite3_table_column_metadata() is a
+** NULL pointer, then this routine simply checks for the existance of the
+** table and returns SQLITE_OK if the table exists and SQLITE_ERROR if it
+** does not.
**
** ^The column is identified by the second, third and fourth parameters to
-** this function. ^The second parameter is either the name of the database
+** 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
+** 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.
+** name of the desired column, respectively.
**
** ^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
@@ -4927,16 +5379,17 @@ SQLITE_API SQLITE_DEPRECATED void sqlite3_soft_heap_limit(int N);
** </blockquote>)^
**
** ^The memory pointed to by the character pointers returned for the
-** declaration type and collation sequence is valid only until the next
+** declaration type and collation sequence is valid 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
+** ^If the specified column is "rowid", "oid" or "_rowid_" and the table
+** is not a [WITHOUT ROWID] table 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:
+** [INTEGER PRIMARY KEY] column, then the outputs
+** for the [rowid] are set as follows:
**
** <pre>
** data type: "INTEGER"
@@ -4946,15 +5399,11 @@ SQLITE_API SQLITE_DEPRECATED void sqlite3_soft_heap_limit(int N);
** 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.
+** ^This function causes all database schemas to be read from disk and
+** parsed, if that has not already been done, and returns an error if
+** any errors are encountered while loading the schema.
*/
-SQLITE_API int sqlite3_table_column_metadata(
+SQLITE_API int SQLITE_STDCALL sqlite3_table_column_metadata(
sqlite3 *db, /* Connection handle */
const char *zDbName, /* Database name or NULL */
const char *zTableName, /* Table name */
@@ -4968,15 +5417,25 @@ SQLITE_API int sqlite3_table_column_metadata(
/*
** CAPI3REF: Load An Extension
+** METHOD: sqlite3
**
** ^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.
+** [SQLite extension] library contained in the file zFile. If
+** the file cannot be loaded directly, attempts are made to load
+** with various operating-system specific extensions added.
+** So for example, if "samplelib" cannot be loaded, then names like
+** "samplelib.so" or "samplelib.dylib" or "samplelib.dll" might
+** be tried also.
**
** ^The entry point is zProc.
-** ^zProc may be 0, in which case the name of the entry point
-** defaults to "sqlite3_extension_init".
+** ^(zProc may be 0, in which case SQLite will try to come up with an
+** entry point name on its own. It first tries "sqlite3_extension_init".
+** If that does not work, it constructs a name "sqlite3_X_init" where the
+** X is consists of the lower-case equivalent of all ASCII alphabetic
+** characters in the filename from the last "/" to the first following
+** "." and omitting any initial "lib".)^
** ^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
@@ -4991,7 +5450,7 @@ SQLITE_API int sqlite3_table_column_metadata(
**
** See also the [load_extension() SQL function].
*/
-SQLITE_API int sqlite3_load_extension(
+SQLITE_API int SQLITE_STDCALL 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 */
@@ -5000,25 +5459,26 @@ SQLITE_API int sqlite3_load_extension(
/*
** CAPI3REF: Enable Or Disable Extension Loading
+** METHOD: sqlite3
**
** ^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
+** 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.
+** ^Extension loading is off by default.
** ^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);
+SQLITE_API int SQLITE_STDCALL 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
+** 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
@@ -5046,9 +5506,22 @@ SQLITE_API int sqlite3_enable_load_extension(sqlite3 *db, int onoff);
** 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()].
+** See also: [sqlite3_reset_auto_extension()]
+** and [sqlite3_cancel_auto_extension()]
+*/
+SQLITE_API int SQLITE_STDCALL sqlite3_auto_extension(void (*xEntryPoint)(void));
+
+/*
+** CAPI3REF: Cancel Automatic Extension Loading
+**
+** ^The [sqlite3_cancel_auto_extension(X)] interface unregisters the
+** initialization routine X that was registered using a prior call to
+** [sqlite3_auto_extension(X)]. ^The [sqlite3_cancel_auto_extension(X)]
+** routine returns 1 if initialization routine X was successfully
+** unregistered and it returns 0 if X was not on the list of initialization
+** routines.
*/
-SQLITE_API int sqlite3_auto_extension(void (*xEntryPoint)(void));
+SQLITE_API int SQLITE_STDCALL sqlite3_cancel_auto_extension(void (*xEntryPoint)(void));
/*
** CAPI3REF: Reset Automatic Extension Loading
@@ -5056,7 +5529,7 @@ SQLITE_API int sqlite3_auto_extension(void (*xEntryPoint)(void));
** ^This interface disables all automatic extensions previously
** registered using [sqlite3_auto_extension()].
*/
-SQLITE_API void sqlite3_reset_auto_extension(void);
+SQLITE_API void SQLITE_STDCALL sqlite3_reset_auto_extension(void);
/*
** The interface to the virtual-table mechanism is currently considered
@@ -5158,6 +5631,17 @@ struct sqlite3_module {
** ^Information about the ORDER BY clause is stored in aOrderBy[].
** ^Each term of aOrderBy records a column of the ORDER BY clause.
**
+** The colUsed field indicates which columns of the virtual table may be
+** required by the current scan. Virtual table columns are numbered from
+** zero in the order in which they appear within the CREATE TABLE statement
+** passed to sqlite3_declare_vtab(). For the first 63 columns (columns 0-62),
+** the corresponding bit is set within the colUsed mask if the column may be
+** required by SQLite. If the table has at least 64 columns and any column
+** to the right of the first 63 is required, then bit 63 of colUsed is also
+** set. In other words, column iCol may be required if the expression
+** (colUsed & ((sqlite3_uint64)1 << (iCol>=63 ? 63 : iCol))) evaluates to
+** non-zero.
+**
** 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
@@ -5174,10 +5658,40 @@ struct sqlite3_module {
** 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).
+** ^The estimatedCost value is an estimate of the cost of a particular
+** strategy. A cost of N indicates that the cost of the strategy is similar
+** to a linear scan of an SQLite table with N rows. A cost of log(N)
+** indicates that the expense of the operation is similar to that of a
+** binary search on a unique indexed field of an SQLite table with N rows.
+**
+** ^The estimatedRows value is an estimate of the number of rows that
+** will be returned by the strategy.
+**
+** The xBestIndex method may optionally populate the idxFlags field with a
+** mask of SQLITE_INDEX_SCAN_* flags. Currently there is only one such flag -
+** SQLITE_INDEX_SCAN_UNIQUE. If the xBestIndex method sets this flag, SQLite
+** assumes that the strategy may visit at most one row.
+**
+** Additionally, if xBestIndex sets the SQLITE_INDEX_SCAN_UNIQUE flag, then
+** SQLite also assumes that if a call to the xUpdate() method is made as
+** part of the same statement to delete or update a virtual table row and the
+** implementation returns SQLITE_CONSTRAINT, then there is no need to rollback
+** any database changes. In other words, if the xUpdate() returns
+** SQLITE_CONSTRAINT, the database contents must be exactly as they were
+** before xUpdate was called. By contrast, if SQLITE_INDEX_SCAN_UNIQUE is not
+** set and xUpdate returns SQLITE_CONSTRAINT, any database changes made by
+** the xUpdate method are automatically rolled back by SQLite.
+**
+** IMPORTANT: The estimatedRows field was added to the sqlite3_index_info
+** structure for SQLite version 3.8.2. If a virtual table extension is
+** used with an SQLite version earlier than 3.8.2, the results of attempting
+** to read or write the estimatedRows field are undefined (but are likely
+** to included crashing the application). The estimatedRows field should
+** therefore only be used if [sqlite3_libversion_number()] returns a
+** value greater than or equal to 3008002. Similarly, the idxFlags field
+** was added for version 3.9.0. It may therefore only be used if
+** sqlite3_libversion_number() returns a value greater than or equal to
+** 3009000.
*/
struct sqlite3_index_info {
/* Inputs */
@@ -5202,10 +5716,21 @@ struct sqlite3_index_info {
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 */
+ double estimatedCost; /* Estimated cost of using this index */
+ /* Fields below are only available in SQLite 3.8.2 and later */
+ sqlite3_int64 estimatedRows; /* Estimated number of rows returned */
+ /* Fields below are only available in SQLite 3.9.0 and later */
+ int idxFlags; /* Mask of SQLITE_INDEX_SCAN_* flags */
+ /* Fields below are only available in SQLite 3.10.0 and later */
+ sqlite3_uint64 colUsed; /* Input: Mask of columns used by statement */
};
/*
+** CAPI3REF: Virtual Table Scan Flags
+*/
+#define SQLITE_INDEX_SCAN_UNIQUE 1 /* Scan visits at most 1 row */
+
+/*
** CAPI3REF: Virtual Table Constraint Operator Codes
**
** These macros defined the allowed values for the
@@ -5213,15 +5738,19 @@ struct sqlite3_index_info {
** 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
+#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
+#define SQLITE_INDEX_CONSTRAINT_LIKE 65
+#define SQLITE_INDEX_CONSTRAINT_GLOB 66
+#define SQLITE_INDEX_CONSTRAINT_REGEXP 67
/*
** CAPI3REF: Register A Virtual Table Implementation
+** METHOD: sqlite3
**
** ^These routines are used to register a new [virtual table module] name.
** ^Module names must be registered before
@@ -5245,13 +5774,13 @@ struct sqlite3_index_info {
** interface is equivalent to sqlite3_create_module_v2() with a NULL
** destructor.
*/
-SQLITE_API int sqlite3_create_module(
+SQLITE_API int SQLITE_STDCALL 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(
+SQLITE_API int SQLITE_STDCALL 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 */
@@ -5279,7 +5808,7 @@ SQLITE_API int sqlite3_create_module_v2(
*/
struct sqlite3_vtab {
const sqlite3_module *pModule; /* The module for this virtual table */
- int nRef; /* NO LONGER USED */
+ int nRef; /* Number of open cursors */
char *zErrMsg; /* Error message from sqlite3_mprintf() */
/* Virtual table implementations will typically add additional fields */
};
@@ -5314,10 +5843,11 @@ struct sqlite3_vtab_cursor {
** 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);
+SQLITE_API int SQLITE_STDCALL sqlite3_declare_vtab(sqlite3*, const char *zSQL);
/*
** CAPI3REF: Overload A Function For A Virtual Table
+** METHOD: sqlite3
**
** ^(Virtual tables can provide alternative implementations of functions
** using the [xFindFunction] method of the [virtual table module].
@@ -5332,7 +5862,7 @@ SQLITE_API int sqlite3_declare_vtab(sqlite3*, const char *zSQL);
** 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);
+SQLITE_API int SQLITE_STDCALL sqlite3_overload_function(sqlite3*, const char *zFuncName, int nArg);
/*
** The interface to the virtual-table mechanism defined above (back up
@@ -5360,6 +5890,8 @@ typedef struct sqlite3_blob sqlite3_blob;
/*
** CAPI3REF: Open A BLOB For Incremental I/O
+** METHOD: sqlite3
+** CONSTRUCTOR: sqlite3_blob
**
** ^(This interfaces opens a [BLOB handle | handle] to the BLOB located
** in row iRow, column zColumn, table zTable in database zDb;
@@ -5369,26 +5901,42 @@ typedef struct sqlite3_blob sqlite3_blob;
** SELECT zColumn FROM zDb.zTable WHERE [rowid] = iRow;
** </pre>)^
**
+** ^(Parameter zDb is not the filename that contains the database, but
+** rather the symbolic name of the database. For attached databases, this is
+** the name that appears after the AS keyword in the [ATTACH] statement.
+** For the main database file, the database name is "main". For TEMP
+** tables, the database name is "temp".)^
+**
** ^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.
+** and write access. ^If the flags parameter is zero, the BLOB is opened for
+** read-only access.
+**
+** ^(On success, [SQLITE_OK] is returned and the new [BLOB handle] is stored
+** in *ppBlob. Otherwise an [error code] is returned and, unless the error
+** code is SQLITE_MISUSE, *ppBlob is set to NULL.)^ ^This means that, provided
+** the API is not misused, it is always safe to call [sqlite3_blob_close()]
+** on *ppBlob after this function it returns.
+**
+** This function fails with SQLITE_ERROR if any of the following are true:
+** <ul>
+** <li> ^(Database zDb does not exist)^,
+** <li> ^(Table zTable does not exist within database zDb)^,
+** <li> ^(Table zTable is a WITHOUT ROWID table)^,
+** <li> ^(Column zColumn does not exist)^,
+** <li> ^(Row iRow is not present in the table)^,
+** <li> ^(The specified column of row iRow contains a value that is not
+** a TEXT or BLOB value)^,
+** <li> ^(Column zColumn is part of an index, PRIMARY KEY or UNIQUE
+** constraint and the blob is being opened for read/write access)^,
+** <li> ^([foreign key constraints | Foreign key constraints] are enabled,
+** column zColumn is part of a [child key] definition and the blob is
+** being opened for read/write access)^.
+** </ul>
+**
+** ^Unless it returns SQLITE_MISUSE, this function sets the
+** [database connection] error code and message accessible via
+** [sqlite3_errcode()] and [sqlite3_errmsg()] and related functions.
+**
**
** ^(If the row that a BLOB handle points to is modified by an
** [UPDATE], [DELETE], or by [ON CONFLICT] side-effects
@@ -5407,14 +5955,13 @@ typedef struct sqlite3_blob sqlite3_blob;
** 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.
+** and the built-in [zeroblob] SQL function may be used to create a
+** zero-filled blob to read or write using the incremental-blob 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(
+SQLITE_API int SQLITE_STDCALL sqlite3_blob_open(
sqlite3*,
const char *zDb,
const char *zTable,
@@ -5426,6 +5973,7 @@ SQLITE_API int sqlite3_blob_open(
/*
** CAPI3REF: Move a BLOB Handle to a New Row
+** METHOD: sqlite3_blob
**
** ^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
@@ -5446,34 +5994,34 @@ SQLITE_API int sqlite3_blob_open(
**
** ^This function sets the database handle error code and message.
*/
-SQLITE_API SQLITE_EXPERIMENTAL int sqlite3_blob_reopen(sqlite3_blob *, sqlite3_int64);
+SQLITE_API int SQLITE_STDCALL sqlite3_blob_reopen(sqlite3_blob *, sqlite3_int64);
/*
** CAPI3REF: Close A BLOB Handle
+** DESTRUCTOR: sqlite3_blob
**
-** ^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.
+** ^This function closes an open [BLOB handle]. ^(The BLOB handle is closed
+** unconditionally. Even if this routine returns an error code, the
+** handle is still closed.)^
**
-** ^(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.)^
+** ^If the blob handle being closed was opened for read-write access, and if
+** the database is in auto-commit mode and there are no other open read-write
+** blob handles or active write statements, the current transaction is
+** committed. ^If an error occurs while committing the transaction, an error
+** code is returned and the transaction rolled back.
**
-** ^(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.
+** Calling this function with an argument that is not a NULL pointer or an
+** open blob handle results in undefined behaviour. ^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. ^Otherwise, if this function
+** is passed a valid open blob handle, the values returned by the
+** sqlite3_errcode() and sqlite3_errmsg() functions are set before returning.
*/
-SQLITE_API int sqlite3_blob_close(sqlite3_blob *);
+SQLITE_API int SQLITE_STDCALL sqlite3_blob_close(sqlite3_blob *);
/*
** CAPI3REF: Return The Size Of An Open BLOB
+** METHOD: sqlite3_blob
**
** ^Returns the size in bytes of the BLOB accessible via the
** successfully opened [BLOB handle] in its only argument. ^The
@@ -5485,10 +6033,11 @@ SQLITE_API int sqlite3_blob_close(sqlite3_blob *);
** 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 *);
+SQLITE_API int SQLITE_STDCALL sqlite3_blob_bytes(sqlite3_blob *);
/*
** CAPI3REF: Read Data From A BLOB Incrementally
+** METHOD: sqlite3_blob
**
** ^(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
@@ -5513,26 +6062,33 @@ SQLITE_API int sqlite3_blob_bytes(sqlite3_blob *);
**
** See also: [sqlite3_blob_write()].
*/
-SQLITE_API int sqlite3_blob_read(sqlite3_blob *, void *Z, int N, int iOffset);
+SQLITE_API int SQLITE_STDCALL sqlite3_blob_read(sqlite3_blob *, void *Z, int N, int iOffset);
/*
** CAPI3REF: Write Data Into A BLOB Incrementally
+** METHOD: sqlite3_blob
**
-** ^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.
+** ^(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.)^
+**
+** ^(On success, sqlite3_blob_write() returns SQLITE_OK.
+** Otherwise, an [error code] or an [extended error code] is returned.)^
+** ^Unless SQLITE_MISUSE is returned, this function sets the
+** [database connection] error code and message accessible via
+** [sqlite3_errcode()] and [sqlite3_errmsg()] and related functions.
**
** ^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
+** 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.
+** [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. ^If N or iOffset are less
+** than zero [SQLITE_ERROR] is returned and no data is written.
**
** ^An attempt to write to an expired [BLOB handle] fails with an
** error code of [SQLITE_ABORT]. ^Writes to the BLOB that occurred
@@ -5541,9 +6097,6 @@ SQLITE_API int sqlite3_blob_read(sqlite3_blob *, void *Z, int N, int iOffset);
** 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
@@ -5551,7 +6104,7 @@ SQLITE_API int sqlite3_blob_read(sqlite3_blob *, void *Z, int N, int iOffset);
**
** See also: [sqlite3_blob_read()].
*/
-SQLITE_API int sqlite3_blob_write(sqlite3_blob *, const void *z, int n, int iOffset);
+SQLITE_API int SQLITE_STDCALL sqlite3_blob_write(sqlite3_blob *, const void *z, int n, int iOffset);
/*
** CAPI3REF: Virtual File System Objects
@@ -5582,9 +6135,9 @@ SQLITE_API int sqlite3_blob_write(sqlite3_blob *, const void *z, int n, int iOff
** ^(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*);
+SQLITE_API sqlite3_vfs *SQLITE_STDCALL sqlite3_vfs_find(const char *zVfsName);
+SQLITE_API int SQLITE_STDCALL sqlite3_vfs_register(sqlite3_vfs*, int makeDflt);
+SQLITE_API int SQLITE_STDCALL sqlite3_vfs_unregister(sqlite3_vfs*);
/*
** CAPI3REF: Mutexes
@@ -5596,45 +6149,51 @@ SQLITE_API int sqlite3_vfs_unregister(sqlite3_vfs*);
**
** The SQLite source code contains multiple implementations
** of these mutex routines. An appropriate implementation
-** is selected automatically at compile-time. ^(The following
+** 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>)^
+** </ul>
**
-** ^The SQLITE_MUTEX_NOOP implementation is a set of routines
+** 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
+** 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
+** 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().)^
+** 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:
+** mutex and returns a pointer to it. ^The sqlite3_mutex_alloc()
+** routine returns NULL if it is unable to allocate the requested
+** mutex. The argument to sqlite3_mutex_alloc() must 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_OPEN
** <li> SQLITE_MUTEX_STATIC_PRNG
** <li> SQLITE_MUTEX_STATIC_LRU
-** <li> SQLITE_MUTEX_STATIC_LRU2
-** </ul>)^
+** <li> SQLITE_MUTEX_STATIC_PMEM
+** <li> SQLITE_MUTEX_STATIC_APP1
+** <li> SQLITE_MUTEX_STATIC_APP2
+** <li> SQLITE_MUTEX_STATIC_APP3
+** <li> SQLITE_MUTEX_STATIC_VFS1
+** <li> SQLITE_MUTEX_STATIC_VFS2
+** <li> SQLITE_MUTEX_STATIC_VFS3
+** </ul>
**
** ^The first two constants (SQLITE_MUTEX_FAST and SQLITE_MUTEX_RECURSIVE)
** cause sqlite3_mutex_alloc() to create
@@ -5642,14 +6201,14 @@ SQLITE_API int sqlite3_vfs_unregister(sqlite3_vfs*);
** 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
+** 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
+** a pointer to a static preexisting mutex. ^Nine 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
@@ -5658,16 +6217,13 @@ SQLITE_API int sqlite3_vfs_unregister(sqlite3_vfs*);
**
** ^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
+** returns a different mutex on every call. ^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.
+** allocated dynamic mutex. Attempting to deallocate a static
+** mutex results in undefined behavior.
**
** ^The sqlite3_mutex_enter() and sqlite3_mutex_try() routines attempt
** to enter a mutex. ^If another thread is already within the mutex,
@@ -5675,23 +6231,21 @@ SQLITE_API int sqlite3_vfs_unregister(sqlite3_vfs*);
** 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,
+** 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.)^
+** can enter.)^ If the same thread tries to enter any mutex other
+** than an SQLITE_MUTEX_RECURSIVE more than once, the behavior is undefined.
**
** ^(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.)^
+** 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
+** 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.)^
+** calling thread or is not currently allocated.
**
** ^If the argument to sqlite3_mutex_enter(), sqlite3_mutex_try(), or
** sqlite3_mutex_leave() is a NULL pointer, then all three routines
@@ -5699,11 +6253,11 @@ SQLITE_API int sqlite3_vfs_unregister(sqlite3_vfs*);
**
** 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*);
+SQLITE_API sqlite3_mutex *SQLITE_STDCALL sqlite3_mutex_alloc(int);
+SQLITE_API void SQLITE_STDCALL sqlite3_mutex_free(sqlite3_mutex*);
+SQLITE_API void SQLITE_STDCALL sqlite3_mutex_enter(sqlite3_mutex*);
+SQLITE_API int SQLITE_STDCALL sqlite3_mutex_try(sqlite3_mutex*);
+SQLITE_API void SQLITE_STDCALL sqlite3_mutex_leave(sqlite3_mutex*);
/*
** CAPI3REF: Mutex Methods Object
@@ -5712,9 +6266,9 @@ SQLITE_API void sqlite3_mutex_leave(sqlite3_mutex*);
** 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
+** sufficient, however the application 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
+** does not provide a suitable implementation. In this case, the application
** 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
@@ -5755,13 +6309,13 @@ SQLITE_API void sqlite3_mutex_leave(sqlite3_mutex*);
** (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
+** 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
+** 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.
**
@@ -5787,34 +6341,34 @@ struct sqlite3_mutex_methods {
** CAPI3REF: Mutex Verification Routines
**
** The sqlite3_mutex_held() and sqlite3_mutex_notheld() routines
-** are intended for use inside assert() statements. ^The SQLite core
+** 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
+** 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
+** 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
+** 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
+** 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
+** 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()
+** 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*);
+SQLITE_API int SQLITE_STDCALL sqlite3_mutex_held(sqlite3_mutex*);
+SQLITE_API int SQLITE_STDCALL sqlite3_mutex_notheld(sqlite3_mutex*);
#endif
/*
@@ -5837,9 +6391,16 @@ SQLITE_API int sqlite3_mutex_notheld(sqlite3_mutex*);
#define SQLITE_MUTEX_STATIC_LRU 6 /* lru page list */
#define SQLITE_MUTEX_STATIC_LRU2 7 /* NOT USED */
#define SQLITE_MUTEX_STATIC_PMEM 7 /* sqlite3PageMalloc() */
+#define SQLITE_MUTEX_STATIC_APP1 8 /* For use by application */
+#define SQLITE_MUTEX_STATIC_APP2 9 /* For use by application */
+#define SQLITE_MUTEX_STATIC_APP3 10 /* For use by application */
+#define SQLITE_MUTEX_STATIC_VFS1 11 /* For use by built-in VFS */
+#define SQLITE_MUTEX_STATIC_VFS2 12 /* For use by extension VFS */
+#define SQLITE_MUTEX_STATIC_VFS3 13 /* For use by application VFS */
/*
** CAPI3REF: Retrieve the mutex for a database connection
+** METHOD: sqlite3
**
** ^This interface returns a pointer the [sqlite3_mutex] object that
** serializes access to the [database connection] given in the argument
@@ -5847,10 +6408,11 @@ SQLITE_API int sqlite3_mutex_notheld(sqlite3_mutex*);
** ^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*);
+SQLITE_API sqlite3_mutex *SQLITE_STDCALL sqlite3_db_mutex(sqlite3*);
/*
** CAPI3REF: Low-Level Control Of Database Files
+** METHOD: sqlite3
**
** ^The [sqlite3_file_control()] interface makes a direct call to the
** xFileControl method for the [sqlite3_io_methods] object associated
@@ -5881,7 +6443,7 @@ SQLITE_API sqlite3_mutex *sqlite3_db_mutex(sqlite3*);
**
** See also: [SQLITE_FCNTL_LOCKSTATE]
*/
-SQLITE_API int sqlite3_file_control(sqlite3*, const char *zDbName, int op, void*);
+SQLITE_API int SQLITE_STDCALL sqlite3_file_control(sqlite3*, const char *zDbName, int op, void*);
/*
** CAPI3REF: Testing Interface
@@ -5900,7 +6462,7 @@ SQLITE_API int sqlite3_file_control(sqlite3*, const char *zDbName, int op, void*
** 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, ...);
+SQLITE_API int SQLITE_CDECL sqlite3_test_control(int op, ...);
/*
** CAPI3REF: Testing Interface Operation Codes
@@ -5928,13 +6490,19 @@ SQLITE_API int sqlite3_test_control(int op, ...);
#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
+#define SQLITE_TESTCTRL_EXPLAIN_STMT 19 /* NOT USED */
+#define SQLITE_TESTCTRL_NEVER_CORRUPT 20
+#define SQLITE_TESTCTRL_VDBE_COVERAGE 21
+#define SQLITE_TESTCTRL_BYTEORDER 22
+#define SQLITE_TESTCTRL_ISINIT 23
+#define SQLITE_TESTCTRL_SORTER_MMAP 24
+#define SQLITE_TESTCTRL_IMPOSTER 25
+#define SQLITE_TESTCTRL_LAST 25
/*
** CAPI3REF: SQLite Runtime Status
**
-** ^This interface is used to retrieve runtime status information
+** ^These interfaces are 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
@@ -5948,19 +6516,22 @@ SQLITE_API int sqlite3_test_control(int op, ...);
** ^(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.
+** ^The sqlite3_status() and sqlite3_status64() routines return
+** 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.
+** If either the current value or the highwater mark is too large to
+** be represented by a 32-bit integer, then the values returned by
+** sqlite3_status() are undefined.
**
** See also: [sqlite3_db_status()]
*/
-SQLITE_API int sqlite3_status(int op, int *pCurrent, int *pHighwater, int resetFlag);
+SQLITE_API int SQLITE_STDCALL sqlite3_status(int op, int *pCurrent, int *pHighwater, int resetFlag);
+SQLITE_API int SQLITE_STDCALL sqlite3_status64(
+ int op,
+ sqlite3_int64 *pCurrent,
+ sqlite3_int64 *pHighwater,
+ int resetFlag
+);
/*
@@ -6039,7 +6610,8 @@ SQLITE_API int sqlite3_status(int op, int *pCurrent, int *pHighwater, int resetF
** 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
+** <dd>The *pHighwater parameter records the deepest parser stack.
+** The *pCurrent value is undefined. The *pHighwater value is only
** meaningful if SQLite is compiled with [YYTRACKMAXSTACKDEPTH].</dd>)^
** </dl>
**
@@ -6058,6 +6630,7 @@ SQLITE_API int sqlite3_status(int op, int *pCurrent, int *pHighwater, int resetF
/*
** CAPI3REF: Database Connection Status
+** METHOD: sqlite3
**
** ^This interface is used to retrieve runtime status information
** about a single [database connection]. ^The first argument is the
@@ -6078,7 +6651,7 @@ SQLITE_API int sqlite3_status(int op, int *pCurrent, int *pHighwater, int resetF
**
** See also: [sqlite3_status()] and [sqlite3_stmt_status()].
*/
-SQLITE_API int sqlite3_db_status(sqlite3*, int op, int *pCur, int *pHiwtr, int resetFlg);
+SQLITE_API int SQLITE_STDCALL sqlite3_db_status(sqlite3*, int op, int *pCur, int *pHiwtr, int resetFlg);
/*
** CAPI3REF: Status Parameters for database connections
@@ -6120,12 +6693,12 @@ SQLITE_API int sqlite3_db_status(sqlite3*, int op, int *pCur, int *pHiwtr, int r
** 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
+** <dd>This parameter returns the approximate number 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
+** <dd>This parameter returns the approximate number 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
@@ -6134,7 +6707,7 @@ SQLITE_API int sqlite3_db_status(sqlite3*, int op, int *pCur, int *pHiwtr, int r
** ^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
+** <dd>This parameter returns the approximate number 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.
@@ -6162,6 +6735,12 @@ SQLITE_API int sqlite3_db_status(sqlite3*, int op, int *pCur, int *pHiwtr, int r
** on subsequent SQLITE_DBSTATUS_CACHE_WRITE requests is undefined.)^ ^The
** highwater mark associated with SQLITE_DBSTATUS_CACHE_WRITE is always 0.
** </dd>
+**
+** [[SQLITE_DBSTATUS_DEFERRED_FKS]] ^(<dt>SQLITE_DBSTATUS_DEFERRED_FKS</dt>
+** <dd>This parameter returns zero for the current value if and only if
+** all foreign key constraints (deferred or immediate) have been
+** resolved.)^ ^The highwater mark is always 0.
+** </dd>
** </dl>
*/
#define SQLITE_DBSTATUS_LOOKASIDE_USED 0
@@ -6174,11 +6753,13 @@ SQLITE_API int sqlite3_db_status(sqlite3*, int op, int *pCur, int *pHiwtr, int r
#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 */
+#define SQLITE_DBSTATUS_DEFERRED_FKS 10
+#define SQLITE_DBSTATUS_MAX 10 /* Largest defined DBSTATUS */
/*
** CAPI3REF: Prepared Statement Status
+** METHOD: sqlite3_stmt
**
** ^(Each prepared statement maintains various
** [SQLITE_STMTSTATUS counters] that measure the number
@@ -6200,7 +6781,7 @@ SQLITE_API int sqlite3_db_status(sqlite3*, int op, int *pCur, int *pHiwtr, int r
**
** See also: [sqlite3_status()] and [sqlite3_db_status()].
*/
-SQLITE_API int sqlite3_stmt_status(sqlite3_stmt*, int op,int resetFlg);
+SQLITE_API int SQLITE_STDCALL sqlite3_stmt_status(sqlite3_stmt*, int op,int resetFlg);
/*
** CAPI3REF: Status Parameters for prepared statements
@@ -6228,11 +6809,21 @@ SQLITE_API int sqlite3_stmt_status(sqlite3_stmt*, int op,int resetFlg);
** 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>
+**
+** [[SQLITE_STMTSTATUS_VM_STEP]] <dt>SQLITE_STMTSTATUS_VM_STEP</dt>
+** <dd>^This is the number of virtual machine operations executed
+** by the prepared statement if that number is less than or equal
+** to 2147483647. The number of virtual machine operations can be
+** used as a proxy for the total work done by the prepared statement.
+** If the number of virtual machine operations exceeds 2147483647
+** then the value returned by this statement status code is undefined.
+** </dd>
** </dl>
*/
#define SQLITE_STMTSTATUS_FULLSCAN_STEP 1
#define SQLITE_STMTSTATUS_SORT 2
#define SQLITE_STMTSTATUS_AUTOINDEX 3
+#define SQLITE_STMTSTATUS_VM_STEP 4
/*
** CAPI3REF: Custom Page Cache Object
@@ -6369,7 +6960,7 @@ struct sqlite3_pcache_page {
** 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><th> createFlag <th> Behavior 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.
@@ -6517,6 +7108,10 @@ typedef struct sqlite3_backup sqlite3_backup;
** must be different or else sqlite3_backup_init(D,N,S,M) will fail with
** an error.
**
+** ^A call to sqlite3_backup_init() will fail, returning SQLITE_ERROR, if
+** there is already a read or read-write transaction open on the
+** destination database.
+**
** ^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.
@@ -6609,20 +7204,20 @@ typedef struct sqlite3_backup sqlite3_backup;
** is not a permanent error and does not affect the return value of
** sqlite3_backup_finish().
**
-** [[sqlite3_backup__remaining()]] [[sqlite3_backup_pagecount()]]
+** [[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.
+** ^The sqlite3_backup_remaining() routine returns the number of pages still
+** to be backed up at the conclusion of the most recent sqlite3_backup_step().
+** ^The sqlite3_backup_pagecount() routine returns the total number of pages
+** in the source database at the conclusion of the most recent
+** sqlite3_backup_step().
+** ^(The values returned by these functions are only updated by
+** sqlite3_backup_step(). If the source database is modified in a way that
+** changes the size of the source database or the number of pages remaining,
+** those changes are not reflected in the output of sqlite3_backup_pagecount()
+** and sqlite3_backup_remaining() until after the next
+** sqlite3_backup_step().)^
**
** <b>Concurrent Usage of Database Handles</b>
**
@@ -6655,19 +7250,20 @@ typedef struct sqlite3_backup sqlite3_backup;
** 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(
+SQLITE_API sqlite3_backup *SQLITE_STDCALL 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);
+SQLITE_API int SQLITE_STDCALL sqlite3_backup_step(sqlite3_backup *p, int nPage);
+SQLITE_API int SQLITE_STDCALL sqlite3_backup_finish(sqlite3_backup *p);
+SQLITE_API int SQLITE_STDCALL sqlite3_backup_remaining(sqlite3_backup *p);
+SQLITE_API int SQLITE_STDCALL sqlite3_backup_pagecount(sqlite3_backup *p);
/*
** CAPI3REF: Unlock Notification
+** METHOD: sqlite3
**
** ^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
@@ -6780,7 +7376,7 @@ SQLITE_API int sqlite3_backup_pagecount(sqlite3_backup *p);
** the special "DROP TABLE/INDEX" case, the extended error code is just
** SQLITE_LOCKED.)^
*/
-SQLITE_API int sqlite3_unlock_notify(
+SQLITE_API int SQLITE_STDCALL sqlite3_unlock_notify(
sqlite3 *pBlocked, /* Waiting connection */
void (*xNotify)(void **apArg, int nArg), /* Callback function to invoke */
void *pNotifyArg /* Argument to pass to xNotify */
@@ -6795,13 +7391,53 @@ SQLITE_API int sqlite3_unlock_notify(
** 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);
+SQLITE_API int SQLITE_STDCALL sqlite3_stricmp(const char *, const char *);
+SQLITE_API int SQLITE_STDCALL sqlite3_strnicmp(const char *, const char *, int);
+
+/*
+** CAPI3REF: String Globbing
+*
+** ^The [sqlite3_strglob(P,X)] interface returns zero if and only if
+** string X matches the [GLOB] pattern P.
+** ^The definition of [GLOB] pattern matching used in
+** [sqlite3_strglob(P,X)] is the same as for the "X GLOB P" operator in the
+** SQL dialect understood by SQLite. ^The [sqlite3_strglob(P,X)] function
+** is case sensitive.
+**
+** Note that this routine returns zero on a match and non-zero if the strings
+** do not match, the same as [sqlite3_stricmp()] and [sqlite3_strnicmp()].
+**
+** See also: [sqlite3_strlike()].
+*/
+SQLITE_API int SQLITE_STDCALL sqlite3_strglob(const char *zGlob, const char *zStr);
+
+/*
+** CAPI3REF: String LIKE Matching
+*
+** ^The [sqlite3_strlike(P,X,E)] interface returns zero if and only if
+** string X matches the [LIKE] pattern P with escape character E.
+** ^The definition of [LIKE] pattern matching used in
+** [sqlite3_strlike(P,X,E)] is the same as for the "X LIKE P ESCAPE E"
+** operator in the SQL dialect understood by SQLite. ^For "X LIKE P" without
+** the ESCAPE clause, set the E parameter of [sqlite3_strlike(P,X,E)] to 0.
+** ^As with the LIKE operator, the [sqlite3_strlike(P,X,E)] function is case
+** insensitive - equivalent upper and lower case ASCII characters match
+** one another.
+**
+** ^The [sqlite3_strlike(P,X,E)] function matches Unicode characters, though
+** only ASCII characters are case folded.
+**
+** Note that this routine returns zero on a match and non-zero if the strings
+** do not match, the same as [sqlite3_stricmp()] and [sqlite3_strnicmp()].
+**
+** See also: [sqlite3_strglob()].
+*/
+SQLITE_API int SQLITE_STDCALL sqlite3_strlike(const char *zGlob, const char *zStr, unsigned int cEsc);
/*
** CAPI3REF: Error Logging Interface
**
-** ^The [sqlite3_log()] interface writes a message into the error log
+** ^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.
@@ -6819,18 +7455,17 @@ SQLITE_API int sqlite3_strnicmp(const char *, const char *, int);
** a few hundred characters, it will be truncated to the length of the
** buffer.
*/
-SQLITE_API void sqlite3_log(int iErrCode, const char *zFormat, ...);
+SQLITE_API void SQLITE_CDECL sqlite3_log(int iErrCode, const char *zFormat, ...);
/*
** CAPI3REF: Write-Ahead Log Commit Hook
+** METHOD: sqlite3
**
** ^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]).
+** is invoked each time data is committed to a database in 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
+** ^(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
@@ -6856,7 +7491,7 @@ SQLITE_API void sqlite3_log(int iErrCode, const char *zFormat, ...);
** [wal_autocheckpoint pragma] both invoke [sqlite3_wal_hook()] and will
** those overwrite any prior [sqlite3_wal_hook()] settings.
*/
-SQLITE_API void *sqlite3_wal_hook(
+SQLITE_API void *SQLITE_STDCALL sqlite3_wal_hook(
sqlite3*,
int(*)(void *,sqlite3*,const char*,int),
void*
@@ -6864,6 +7499,7 @@ SQLITE_API void *sqlite3_wal_hook(
/*
** CAPI3REF: Configure an auto-checkpoint
+** METHOD: sqlite3
**
** ^The [sqlite3_wal_autocheckpoint(D,N)] is a wrapper around
** [sqlite3_wal_hook()] that causes any database on [database connection] D
@@ -6881,103 +7517,132 @@ SQLITE_API void *sqlite3_wal_hook(
** ^The [wal_autocheckpoint pragma] can be used to invoke this interface
** from SQL.
**
+** ^Checkpoints initiated by this mechanism are
+** [sqlite3_wal_checkpoint_v2|PASSIVE].
+**
** ^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);
+SQLITE_API int SQLITE_STDCALL sqlite3_wal_autocheckpoint(sqlite3 *db, int N);
/*
** CAPI3REF: Checkpoint a database
+** METHOD: sqlite3
**
-** ^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 sqlite3_wal_checkpoint(D,X) is equivalent to
+** [sqlite3_wal_checkpoint_v2](D,X,[SQLITE_CHECKPOINT_PASSIVE],0,0).)^
**
-** ^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.
+** In brief, sqlite3_wal_checkpoint(D,X) causes the content in the
+** [write-ahead log] for database X on [database connection] D to be
+** transferred into the database file and for the write-ahead log to
+** be reset. See the [checkpointing] documentation for addition
+** information.
**
-** See also: [sqlite3_wal_checkpoint_v2()]
+** This interface used to be the only way to cause a checkpoint to
+** occur. But then the newer and more powerful [sqlite3_wal_checkpoint_v2()]
+** interface was added. This interface is retained for backwards
+** compatibility and as a convenience for applications that need to manually
+** start a callback but which do not need the full power (and corresponding
+** complication) of [sqlite3_wal_checkpoint_v2()].
*/
-SQLITE_API int sqlite3_wal_checkpoint(sqlite3 *db, const char *zDb);
+SQLITE_API int SQLITE_STDCALL sqlite3_wal_checkpoint(sqlite3 *db, const char *zDb);
/*
** CAPI3REF: Checkpoint a database
+** METHOD: sqlite3
**
-** 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:
+** ^(The sqlite3_wal_checkpoint_v2(D,X,M,L,C) interface runs a checkpoint
+** operation on database X of [database connection] D in mode M. Status
+** information is written back into integers pointed to by L and C.)^
+** ^(The M parameter must be a valid [checkpoint mode]:)^
**
** <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.
+** ^Checkpoint as many frames as possible without waiting for any database
+** readers or writers to finish, then sync the database file if all frames
+** in the log were checkpointed. ^The [busy-handler callback]
+** is never invoked in the SQLITE_CHECKPOINT_PASSIVE mode.
+** ^On the other hand, passive mode might leave the checkpoint unfinished
+** if there are concurrent readers or writers.
**
** <dt>SQLITE_CHECKPOINT_FULL<dd>
-** This mode blocks (calls the busy-handler callback) until there is no
+** ^This mode blocks (it invokes the
+** [sqlite3_busy_handler|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.
+** snapshot. ^It then checkpoints all frames in the log file and syncs the
+** database file. ^This mode blocks new database writers while it is pending,
+** but new database readers are allowed to continue unimpeded.
**
** <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.
+** ^This mode works the same way as SQLITE_CHECKPOINT_FULL with the addition
+** that 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 writer will restart the log file from the beginning.
+** ^Like SQLITE_CHECKPOINT_FULL, this mode blocks new
+** database writer attempts while it is pending, but does not impede readers.
+**
+** <dt>SQLITE_CHECKPOINT_TRUNCATE<dd>
+** ^This mode works the same way as SQLITE_CHECKPOINT_RESTART with the
+** addition that it also truncates the log file to zero bytes just prior
+** to a successful return.
** </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
+** ^If pnLog is not NULL, then *pnLog is set to the total number of frames in
+** the log file or to -1 if the checkpoint could not run because
+** of an error or because the database is not in [WAL mode]. ^If pnCkpt is not
+** NULL,then *pnCkpt is set to the total number of checkpointed frames in the
+** log file (including any that were already checkpointed before the function
+** was called) or to -1 if the checkpoint could not run due to an error or
+** because the database is not in WAL mode. ^Note that upon successful
+** completion of an SQLITE_CHECKPOINT_TRUNCATE, the log file will have been
+** truncated to zero bytes and so both *pnLog and *pnCkpt will be set to zero.
+**
+** ^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
+** 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 SQLITE_CHECKPOINT_FULL, RESTART and TRUNCATE 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.
+** 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
+** ^If parameter zDb is NULL or points to a zero length string, then the
+** specified operation is attempted on all WAL databases [attached] to
+** [database connection] db. 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
+** attached databases and SQLITE_BUSY is returned at the end. ^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
+** and the error code is 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
+** ^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.
+**
+** ^Unless it returns SQLITE_MISUSE,
+** the sqlite3_wal_checkpoint_v2() interface
+** sets the error information that is queried by
+** [sqlite3_errcode()] and [sqlite3_errmsg()].
+**
+** ^The [PRAGMA wal_checkpoint] command can be used to invoke this interface
+** from SQL.
*/
-SQLITE_API int sqlite3_wal_checkpoint_v2(
+SQLITE_API int SQLITE_STDCALL sqlite3_wal_checkpoint_v2(
sqlite3 *db, /* Database handle */
const char *zDb, /* Name of attached database (or NULL) */
int eMode, /* SQLITE_CHECKPOINT_* value */
@@ -6986,16 +7651,18 @@ SQLITE_API int sqlite3_wal_checkpoint_v2(
);
/*
-** CAPI3REF: Checkpoint operation parameters
+** CAPI3REF: Checkpoint Mode Values
+** KEYWORDS: {checkpoint mode}
**
-** 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.
+** These constants define all valid values for the "checkpoint mode" passed
+** as the third parameter to the [sqlite3_wal_checkpoint_v2()] interface.
+** See the [sqlite3_wal_checkpoint_v2()] documentation for details on the
+** meaning of each of these checkpoint modes.
*/
-#define SQLITE_CHECKPOINT_PASSIVE 0
-#define SQLITE_CHECKPOINT_FULL 1
-#define SQLITE_CHECKPOINT_RESTART 2
+#define SQLITE_CHECKPOINT_PASSIVE 0 /* Do as much as possible w/o blocking */
+#define SQLITE_CHECKPOINT_FULL 1 /* Wait for writers, then checkpoint */
+#define SQLITE_CHECKPOINT_RESTART 2 /* Like FULL but wait for for readers */
+#define SQLITE_CHECKPOINT_TRUNCATE 3 /* Like RESTART but also truncate WAL */
/*
** CAPI3REF: Virtual Table Interface Configuration
@@ -7011,7 +7678,7 @@ SQLITE_API int sqlite3_wal_checkpoint_v2(
** this function. (See [SQLITE_VTAB_CONSTRAINT_SUPPORT].) Further options
** may be added in the future.
*/
-SQLITE_API int sqlite3_vtab_config(sqlite3*, int op, ...);
+SQLITE_API int SQLITE_CDECL sqlite3_vtab_config(sqlite3*, int op, ...);
/*
** CAPI3REF: Virtual Table Configuration Options
@@ -7064,10 +7731,11 @@ SQLITE_API int sqlite3_vtab_config(sqlite3*, int op, ...);
** of the SQL statement that triggered the call to the [xUpdate] method of the
** [virtual table].
*/
-SQLITE_API int sqlite3_vtab_on_conflict(sqlite3 *);
+SQLITE_API int SQLITE_STDCALL sqlite3_vtab_on_conflict(sqlite3 *);
/*
** CAPI3REF: Conflict resolution modes
+** KEYWORDS: {conflict resolution mode}
**
** These constants are returned by [sqlite3_vtab_on_conflict()] to
** inform a [virtual table] implementation what the [ON CONFLICT] mode
@@ -7083,7 +7751,232 @@ SQLITE_API int sqlite3_vtab_on_conflict(sqlite3 *);
/* #define SQLITE_ABORT 4 // Also an error code */
#define SQLITE_REPLACE 5
+/*
+** CAPI3REF: Prepared Statement Scan Status Opcodes
+** KEYWORDS: {scanstatus options}
+**
+** The following constants can be used for the T parameter to the
+** [sqlite3_stmt_scanstatus(S,X,T,V)] interface. Each constant designates a
+** different metric for sqlite3_stmt_scanstatus() to return.
+**
+** When the value returned to V is a string, space to hold that string is
+** managed by the prepared statement S and will be automatically freed when
+** S is finalized.
+**
+** <dl>
+** [[SQLITE_SCANSTAT_NLOOP]] <dt>SQLITE_SCANSTAT_NLOOP</dt>
+** <dd>^The [sqlite3_int64] variable pointed to by the T parameter will be
+** set to the total number of times that the X-th loop has run.</dd>
+**
+** [[SQLITE_SCANSTAT_NVISIT]] <dt>SQLITE_SCANSTAT_NVISIT</dt>
+** <dd>^The [sqlite3_int64] variable pointed to by the T parameter will be set
+** to the total number of rows examined by all iterations of the X-th loop.</dd>
+**
+** [[SQLITE_SCANSTAT_EST]] <dt>SQLITE_SCANSTAT_EST</dt>
+** <dd>^The "double" variable pointed to by the T parameter will be set to the
+** query planner's estimate for the average number of rows output from each
+** iteration of the X-th loop. If the query planner's estimates was accurate,
+** then this value will approximate the quotient NVISIT/NLOOP and the
+** product of this value for all prior loops with the same SELECTID will
+** be the NLOOP value for the current loop.
+**
+** [[SQLITE_SCANSTAT_NAME]] <dt>SQLITE_SCANSTAT_NAME</dt>
+** <dd>^The "const char *" variable pointed to by the T parameter will be set
+** to a zero-terminated UTF-8 string containing the name of the index or table
+** used for the X-th loop.
+**
+** [[SQLITE_SCANSTAT_EXPLAIN]] <dt>SQLITE_SCANSTAT_EXPLAIN</dt>
+** <dd>^The "const char *" variable pointed to by the T parameter will be set
+** to a zero-terminated UTF-8 string containing the [EXPLAIN QUERY PLAN]
+** description for the X-th loop.
+**
+** [[SQLITE_SCANSTAT_SELECTID]] <dt>SQLITE_SCANSTAT_SELECT</dt>
+** <dd>^The "int" variable pointed to by the T parameter will be set to the
+** "select-id" for the X-th loop. The select-id identifies which query or
+** subquery the loop is part of. The main query has a select-id of zero.
+** The select-id is the same value as is output in the first column
+** of an [EXPLAIN QUERY PLAN] query.
+** </dl>
+*/
+#define SQLITE_SCANSTAT_NLOOP 0
+#define SQLITE_SCANSTAT_NVISIT 1
+#define SQLITE_SCANSTAT_EST 2
+#define SQLITE_SCANSTAT_NAME 3
+#define SQLITE_SCANSTAT_EXPLAIN 4
+#define SQLITE_SCANSTAT_SELECTID 5
+
+/*
+** CAPI3REF: Prepared Statement Scan Status
+** METHOD: sqlite3_stmt
+**
+** This interface returns information about the predicted and measured
+** performance for pStmt. Advanced applications can use this
+** interface to compare the predicted and the measured performance and
+** issue warnings and/or rerun [ANALYZE] if discrepancies are found.
+**
+** Since this interface is expected to be rarely used, it is only
+** available if SQLite is compiled using the [SQLITE_ENABLE_STMT_SCANSTATUS]
+** compile-time option.
+**
+** The "iScanStatusOp" parameter determines which status information to return.
+** The "iScanStatusOp" must be one of the [scanstatus options] or the behavior
+** of this interface is undefined.
+** ^The requested measurement is written into a variable pointed to by
+** the "pOut" parameter.
+** Parameter "idx" identifies the specific loop to retrieve statistics for.
+** Loops are numbered starting from zero. ^If idx is out of range - less than
+** zero or greater than or equal to the total number of loops used to implement
+** the statement - a non-zero value is returned and the variable that pOut
+** points to is unchanged.
+**
+** ^Statistics might not be available for all loops in all statements. ^In cases
+** where there exist loops with no available statistics, this function behaves
+** as if the loop did not exist - it returns non-zero and leave the variable
+** that pOut points to unchanged.
+**
+** See also: [sqlite3_stmt_scanstatus_reset()]
+*/
+SQLITE_API int SQLITE_STDCALL sqlite3_stmt_scanstatus(
+ sqlite3_stmt *pStmt, /* Prepared statement for which info desired */
+ int idx, /* Index of loop to report on */
+ int iScanStatusOp, /* Information desired. SQLITE_SCANSTAT_* */
+ void *pOut /* Result written here */
+);
+
+/*
+** CAPI3REF: Zero Scan-Status Counters
+** METHOD: sqlite3_stmt
+**
+** ^Zero all [sqlite3_stmt_scanstatus()] related event counters.
+**
+** This API is only available if the library is built with pre-processor
+** symbol [SQLITE_ENABLE_STMT_SCANSTATUS] defined.
+*/
+SQLITE_API void SQLITE_STDCALL sqlite3_stmt_scanstatus_reset(sqlite3_stmt*);
+
+/*
+** CAPI3REF: Flush caches to disk mid-transaction
+**
+** ^If a write-transaction is open on [database connection] D when the
+** [sqlite3_db_cacheflush(D)] interface invoked, any dirty
+** pages in the pager-cache that are not currently in use are written out
+** to disk. A dirty page may be in use if a database cursor created by an
+** active SQL statement is reading from it, or if it is page 1 of a database
+** file (page 1 is always "in use"). ^The [sqlite3_db_cacheflush(D)]
+** interface flushes caches for all schemas - "main", "temp", and
+** any [attached] databases.
+**
+** ^If this function needs to obtain extra database locks before dirty pages
+** can be flushed to disk, it does so. ^If those locks cannot be obtained
+** immediately and there is a busy-handler callback configured, it is invoked
+** in the usual manner. ^If the required lock still cannot be obtained, then
+** the database is skipped and an attempt made to flush any dirty pages
+** belonging to the next (if any) database. ^If any databases are skipped
+** because locks cannot be obtained, but no other error occurs, this
+** function returns SQLITE_BUSY.
+**
+** ^If any other error occurs while flushing dirty pages to disk (for
+** example an IO error or out-of-memory condition), then processing is
+** abandoned and an SQLite [error code] is returned to the caller immediately.
+**
+** ^Otherwise, if no error occurs, [sqlite3_db_cacheflush()] returns SQLITE_OK.
+**
+** ^This function does not set the database handle error code or message
+** returned by the [sqlite3_errcode()] and [sqlite3_errmsg()] functions.
+*/
+SQLITE_API int SQLITE_STDCALL sqlite3_db_cacheflush(sqlite3*);
+/*
+** CAPI3REF: Database Snapshot
+** KEYWORDS: {snapshot}
+** EXPERIMENTAL
+**
+** An instance of the snapshot object records the state of a [WAL mode]
+** database for some specific point in history.
+**
+** In [WAL mode], multiple [database connections] that are open on the
+** same database file can each be reading a different historical version
+** of the database file. When a [database connection] begins a read
+** transaction, that connection sees an unchanging copy of the database
+** as it existed for the point in time when the transaction first started.
+** Subsequent changes to the database from other connections are not seen
+** by the reader until a new read transaction is started.
+**
+** The sqlite3_snapshot object records state information about an historical
+** version of the database file so that it is possible to later open a new read
+** transaction that sees that historical version of the database rather than
+** the most recent version.
+**
+** The constructor for this object is [sqlite3_snapshot_get()]. The
+** [sqlite3_snapshot_open()] method causes a fresh read transaction to refer
+** to an historical snapshot (if possible). The destructor for
+** sqlite3_snapshot objects is [sqlite3_snapshot_free()].
+*/
+typedef struct sqlite3_snapshot sqlite3_snapshot;
+
+/*
+** CAPI3REF: Record A Database Snapshot
+** EXPERIMENTAL
+**
+** ^The [sqlite3_snapshot_get(D,S,P)] interface attempts to make a
+** new [sqlite3_snapshot] object that records the current state of
+** schema S in database connection D. ^On success, the
+** [sqlite3_snapshot_get(D,S,P)] interface writes a pointer to the newly
+** created [sqlite3_snapshot] object into *P and returns SQLITE_OK.
+** ^If schema S of [database connection] D is not a [WAL mode] database
+** that is in a read transaction, then [sqlite3_snapshot_get(D,S,P)]
+** leaves the *P value unchanged and returns an appropriate [error code].
+**
+** The [sqlite3_snapshot] object returned from a successful call to
+** [sqlite3_snapshot_get()] must be freed using [sqlite3_snapshot_free()]
+** to avoid a memory leak.
+**
+** The [sqlite3_snapshot_get()] interface is only available when the
+** SQLITE_ENABLE_SNAPSHOT compile-time option is used.
+*/
+SQLITE_API SQLITE_EXPERIMENTAL int SQLITE_STDCALL sqlite3_snapshot_get(
+ sqlite3 *db,
+ const char *zSchema,
+ sqlite3_snapshot **ppSnapshot
+);
+
+/*
+** CAPI3REF: Start a read transaction on an historical snapshot
+** EXPERIMENTAL
+**
+** ^The [sqlite3_snapshot_open(D,S,P)] interface attempts to move the
+** read transaction that is currently open on schema S of
+** [database connection] D so that it refers to historical [snapshot] P.
+** ^The [sqlite3_snapshot_open()] interface returns SQLITE_OK on success
+** or an appropriate [error code] if it fails.
+**
+** ^In order to succeed, a call to [sqlite3_snapshot_open(D,S,P)] must be
+** the first operation, apart from other sqlite3_snapshot_open() calls,
+** following the [BEGIN] that starts a new read transaction.
+** ^A [snapshot] will fail to open if it has been overwritten by a
+** [checkpoint].
+**
+** The [sqlite3_snapshot_open()] interface is only available when the
+** SQLITE_ENABLE_SNAPSHOT compile-time option is used.
+*/
+SQLITE_API SQLITE_EXPERIMENTAL int SQLITE_STDCALL sqlite3_snapshot_open(
+ sqlite3 *db,
+ const char *zSchema,
+ sqlite3_snapshot *pSnapshot
+);
+
+/*
+** CAPI3REF: Destroy a snapshot
+** EXPERIMENTAL
+**
+** ^The [sqlite3_snapshot_free(P)] interface destroys [sqlite3_snapshot] P.
+** The application must eventually free every [sqlite3_snapshot] object
+** using this routine to avoid a memory leak.
+**
+** The [sqlite3_snapshot_free()] interface is only available when the
+** SQLITE_ENABLE_SNAPSHOT compile-time option is used.
+*/
+SQLITE_API SQLITE_EXPERIMENTAL void SQLITE_STDCALL sqlite3_snapshot_free(sqlite3_snapshot*);
/*
** Undo the hack that converts floating point types to integer for
@@ -7096,7 +7989,7 @@ SQLITE_API int sqlite3_vtab_on_conflict(sqlite3 *);
#ifdef __cplusplus
} /* End of the 'extern "C"' block */
#endif
-#endif
+#endif /* _SQLITE3_H_ */
/*
** 2010 August 30
@@ -7120,6 +8013,16 @@ extern "C" {
#endif
typedef struct sqlite3_rtree_geometry sqlite3_rtree_geometry;
+typedef struct sqlite3_rtree_query_info sqlite3_rtree_query_info;
+
+/* The double-precision datatype used by RTree depends on the
+** SQLITE_RTREE_INT_ONLY compile-time option.
+*/
+#ifdef SQLITE_RTREE_INT_ONLY
+ typedef sqlite3_int64 sqlite3_rtree_dbl;
+#else
+ typedef double sqlite3_rtree_dbl;
+#endif
/*
** Register a geometry callback named zGeom that can be used as part of an
@@ -7127,14 +8030,10 @@ typedef struct sqlite3_rtree_geometry sqlite3_rtree_geometry;
**
** SELECT ... FROM <rtree> WHERE <rtree col> MATCH $zGeom(... params ...)
*/
-SQLITE_API int sqlite3_rtree_geometry_callback(
+SQLITE_API int SQLITE_STDCALL 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
+ int (*xGeom)(sqlite3_rtree_geometry*, int, sqlite3_rtree_dbl*,int*),
void *pContext
);
@@ -7146,11 +8045,62 @@ SQLITE_API int sqlite3_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 */
+ sqlite3_rtree_dbl *aParam; /* Parameters passed to SQL geom function */
void *pUser; /* Callback implementation user data */
void (*xDelUser)(void *); /* Called by SQLite to clean up pUser */
};
+/*
+** Register a 2nd-generation geometry callback named zScore that can be
+** used as part of an R-Tree geometry query as follows:
+**
+** SELECT ... FROM <rtree> WHERE <rtree col> MATCH $zQueryFunc(... params ...)
+*/
+SQLITE_API int SQLITE_STDCALL sqlite3_rtree_query_callback(
+ sqlite3 *db,
+ const char *zQueryFunc,
+ int (*xQueryFunc)(sqlite3_rtree_query_info*),
+ void *pContext,
+ void (*xDestructor)(void*)
+);
+
+
+/*
+** A pointer to a structure of the following type is passed as the
+** argument to scored geometry callback registered using
+** sqlite3_rtree_query_callback().
+**
+** Note that the first 5 fields of this structure are identical to
+** sqlite3_rtree_geometry. This structure is a subclass of
+** sqlite3_rtree_geometry.
+*/
+struct sqlite3_rtree_query_info {
+ void *pContext; /* pContext from when function registered */
+ int nParam; /* Number of function parameters */
+ sqlite3_rtree_dbl *aParam; /* value of function parameters */
+ void *pUser; /* callback can use this, if desired */
+ void (*xDelUser)(void*); /* function to free pUser */
+ sqlite3_rtree_dbl *aCoord; /* Coordinates of node or entry to check */
+ unsigned int *anQueue; /* Number of pending entries in the queue */
+ int nCoord; /* Number of coordinates */
+ int iLevel; /* Level of current node or entry */
+ int mxLevel; /* The largest iLevel value in the tree */
+ sqlite3_int64 iRowid; /* Rowid for current entry */
+ sqlite3_rtree_dbl rParentScore; /* Score of parent node */
+ int eParentWithin; /* Visibility of parent node */
+ int eWithin; /* OUT: Visiblity */
+ sqlite3_rtree_dbl rScore; /* OUT: Write the score here */
+ /* The following fields are only available in 3.8.11 and later */
+ sqlite3_value **apSqlParam; /* Original SQL values of parameters */
+};
+
+/*
+** Allowed values for sqlite3_rtree_query.eWithin and .eParentWithin.
+*/
+#define NOT_WITHIN 0 /* Object completely outside of query region */
+#define PARTLY_WITHIN 1 /* Object partially overlaps query region */
+#define FULLY_WITHIN 2 /* Object fully contained within query region */
+
#ifdef __cplusplus
} /* end of the 'extern "C"' block */
@@ -7158,3 +8108,523 @@ struct sqlite3_rtree_geometry {
#endif /* ifndef _SQLITE3RTREE_H_ */
+/*
+** 2014 May 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.
+**
+******************************************************************************
+**
+** Interfaces to extend FTS5. Using the interfaces defined in this file,
+** FTS5 may be extended with:
+**
+** * custom tokenizers, and
+** * custom auxiliary functions.
+*/
+
+
+#ifndef _FTS5_H
+#define _FTS5_H
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*************************************************************************
+** CUSTOM AUXILIARY FUNCTIONS
+**
+** Virtual table implementations may overload SQL functions by implementing
+** the sqlite3_module.xFindFunction() method.
+*/
+
+typedef struct Fts5ExtensionApi Fts5ExtensionApi;
+typedef struct Fts5Context Fts5Context;
+typedef struct Fts5PhraseIter Fts5PhraseIter;
+
+typedef void (*fts5_extension_function)(
+ const Fts5ExtensionApi *pApi, /* API offered by current FTS version */
+ Fts5Context *pFts, /* First arg to pass to pApi functions */
+ sqlite3_context *pCtx, /* Context for returning result/error */
+ int nVal, /* Number of values in apVal[] array */
+ sqlite3_value **apVal /* Array of trailing arguments */
+);
+
+struct Fts5PhraseIter {
+ const unsigned char *a;
+ const unsigned char *b;
+};
+
+/*
+** EXTENSION API FUNCTIONS
+**
+** xUserData(pFts):
+** Return a copy of the context pointer the extension function was
+** registered with.
+**
+** xColumnTotalSize(pFts, iCol, pnToken):
+** If parameter iCol is less than zero, set output variable *pnToken
+** to the total number of tokens in the FTS5 table. Or, if iCol is
+** non-negative but less than the number of columns in the table, return
+** the total number of tokens in column iCol, considering all rows in
+** the FTS5 table.
+**
+** If parameter iCol is greater than or equal to the number of columns
+** in the table, SQLITE_RANGE is returned. Or, if an error occurs (e.g.
+** an OOM condition or IO error), an appropriate SQLite error code is
+** returned.
+**
+** xColumnCount(pFts):
+** Return the number of columns in the table.
+**
+** xColumnSize(pFts, iCol, pnToken):
+** If parameter iCol is less than zero, set output variable *pnToken
+** to the total number of tokens in the current row. Or, if iCol is
+** non-negative but less than the number of columns in the table, set
+** *pnToken to the number of tokens in column iCol of the current row.
+**
+** If parameter iCol is greater than or equal to the number of columns
+** in the table, SQLITE_RANGE is returned. Or, if an error occurs (e.g.
+** an OOM condition or IO error), an appropriate SQLite error code is
+** returned.
+**
+** xColumnText:
+** This function attempts to retrieve the text of column iCol of the
+** current document. If successful, (*pz) is set to point to a buffer
+** containing the text in utf-8 encoding, (*pn) is set to the size in bytes
+** (not characters) of the buffer and SQLITE_OK is returned. Otherwise,
+** if an error occurs, an SQLite error code is returned and the final values
+** of (*pz) and (*pn) are undefined.
+**
+** xPhraseCount:
+** Returns the number of phrases in the current query expression.
+**
+** xPhraseSize:
+** Returns the number of tokens in phrase iPhrase of the query. Phrases
+** are numbered starting from zero.
+**
+** xInstCount:
+** Set *pnInst to the total number of occurrences of all phrases within
+** the query within the current row. Return SQLITE_OK if successful, or
+** an error code (i.e. SQLITE_NOMEM) if an error occurs.
+**
+** xInst:
+** Query for the details of phrase match iIdx within the current row.
+** Phrase matches are numbered starting from zero, so the iIdx argument
+** should be greater than or equal to zero and smaller than the value
+** output by xInstCount().
+**
+** Returns SQLITE_OK if successful, or an error code (i.e. SQLITE_NOMEM)
+** if an error occurs.
+**
+** xRowid:
+** Returns the rowid of the current row.
+**
+** xTokenize:
+** Tokenize text using the tokenizer belonging to the FTS5 table.
+**
+** xQueryPhrase(pFts5, iPhrase, pUserData, xCallback):
+** This API function is used to query the FTS table for phrase iPhrase
+** of the current query. Specifically, a query equivalent to:
+**
+** ... FROM ftstable WHERE ftstable MATCH $p ORDER BY rowid
+**
+** with $p set to a phrase equivalent to the phrase iPhrase of the
+** current query is executed. For each row visited, the callback function
+** passed as the fourth argument is invoked. The context and API objects
+** passed to the callback function may be used to access the properties of
+** each matched row. Invoking Api.xUserData() returns a copy of the pointer
+** passed as the third argument to pUserData.
+**
+** If the callback function returns any value other than SQLITE_OK, the
+** query is abandoned and the xQueryPhrase function returns immediately.
+** If the returned value is SQLITE_DONE, xQueryPhrase returns SQLITE_OK.
+** Otherwise, the error code is propagated upwards.
+**
+** If the query runs to completion without incident, SQLITE_OK is returned.
+** Or, if some error occurs before the query completes or is aborted by
+** the callback, an SQLite error code is returned.
+**
+**
+** xSetAuxdata(pFts5, pAux, xDelete)
+**
+** Save the pointer passed as the second argument as the extension functions
+** "auxiliary data". The pointer may then be retrieved by the current or any
+** future invocation of the same fts5 extension function made as part of
+** of the same MATCH query using the xGetAuxdata() API.
+**
+** Each extension function is allocated a single auxiliary data slot for
+** each FTS query (MATCH expression). If the extension function is invoked
+** more than once for a single FTS query, then all invocations share a
+** single auxiliary data context.
+**
+** If there is already an auxiliary data pointer when this function is
+** invoked, then it is replaced by the new pointer. If an xDelete callback
+** was specified along with the original pointer, it is invoked at this
+** point.
+**
+** The xDelete callback, if one is specified, is also invoked on the
+** auxiliary data pointer after the FTS5 query has finished.
+**
+** If an error (e.g. an OOM condition) occurs within this function, an
+** the auxiliary data is set to NULL and an error code returned. If the
+** xDelete parameter was not NULL, it is invoked on the auxiliary data
+** pointer before returning.
+**
+**
+** xGetAuxdata(pFts5, bClear)
+**
+** Returns the current auxiliary data pointer for the fts5 extension
+** function. See the xSetAuxdata() method for details.
+**
+** If the bClear argument is non-zero, then the auxiliary data is cleared
+** (set to NULL) before this function returns. In this case the xDelete,
+** if any, is not invoked.
+**
+**
+** xRowCount(pFts5, pnRow)
+**
+** This function is used to retrieve the total number of rows in the table.
+** In other words, the same value that would be returned by:
+**
+** SELECT count(*) FROM ftstable;
+**
+** xPhraseFirst()
+** This function is used, along with type Fts5PhraseIter and the xPhraseNext
+** method, to iterate through all instances of a single query phrase within
+** the current row. This is the same information as is accessible via the
+** xInstCount/xInst APIs. While the xInstCount/xInst APIs are more convenient
+** to use, this API may be faster under some circumstances. To iterate
+** through instances of phrase iPhrase, use the following code:
+**
+** Fts5PhraseIter iter;
+** int iCol, iOff;
+** for(pApi->xPhraseFirst(pFts, iPhrase, &iter, &iCol, &iOff);
+** iOff>=0;
+** pApi->xPhraseNext(pFts, &iter, &iCol, &iOff)
+** ){
+** // An instance of phrase iPhrase at offset iOff of column iCol
+** }
+**
+** The Fts5PhraseIter structure is defined above. Applications should not
+** modify this structure directly - it should only be used as shown above
+** with the xPhraseFirst() and xPhraseNext() API methods.
+**
+** xPhraseNext()
+** See xPhraseFirst above.
+*/
+struct Fts5ExtensionApi {
+ int iVersion; /* Currently always set to 1 */
+
+ void *(*xUserData)(Fts5Context*);
+
+ int (*xColumnCount)(Fts5Context*);
+ int (*xRowCount)(Fts5Context*, sqlite3_int64 *pnRow);
+ int (*xColumnTotalSize)(Fts5Context*, int iCol, sqlite3_int64 *pnToken);
+
+ int (*xTokenize)(Fts5Context*,
+ const char *pText, int nText, /* Text to tokenize */
+ void *pCtx, /* Context passed to xToken() */
+ int (*xToken)(void*, int, const char*, int, int, int) /* Callback */
+ );
+
+ int (*xPhraseCount)(Fts5Context*);
+ int (*xPhraseSize)(Fts5Context*, int iPhrase);
+
+ int (*xInstCount)(Fts5Context*, int *pnInst);
+ int (*xInst)(Fts5Context*, int iIdx, int *piPhrase, int *piCol, int *piOff);
+
+ sqlite3_int64 (*xRowid)(Fts5Context*);
+ int (*xColumnText)(Fts5Context*, int iCol, const char **pz, int *pn);
+ int (*xColumnSize)(Fts5Context*, int iCol, int *pnToken);
+
+ int (*xQueryPhrase)(Fts5Context*, int iPhrase, void *pUserData,
+ int(*)(const Fts5ExtensionApi*,Fts5Context*,void*)
+ );
+ int (*xSetAuxdata)(Fts5Context*, void *pAux, void(*xDelete)(void*));
+ void *(*xGetAuxdata)(Fts5Context*, int bClear);
+
+ void (*xPhraseFirst)(Fts5Context*, int iPhrase, Fts5PhraseIter*, int*, int*);
+ void (*xPhraseNext)(Fts5Context*, Fts5PhraseIter*, int *piCol, int *piOff);
+};
+
+/*
+** CUSTOM AUXILIARY FUNCTIONS
+*************************************************************************/
+
+/*************************************************************************
+** CUSTOM TOKENIZERS
+**
+** Applications may also register custom tokenizer types. A tokenizer
+** is registered by providing fts5 with a populated instance of the
+** following structure. All structure methods must be defined, setting
+** any member of the fts5_tokenizer struct to NULL leads to undefined
+** behaviour. The structure methods are expected to function as follows:
+**
+** xCreate:
+** This function is used to allocate and inititalize a tokenizer instance.
+** A tokenizer instance is required to actually tokenize text.
+**
+** The first argument passed to this function is a copy of the (void*)
+** pointer provided by the application when the fts5_tokenizer object
+** was registered with FTS5 (the third argument to xCreateTokenizer()).
+** The second and third arguments are an array of nul-terminated strings
+** containing the tokenizer arguments, if any, specified following the
+** tokenizer name as part of the CREATE VIRTUAL TABLE statement used
+** to create the FTS5 table.
+**
+** The final argument is an output variable. If successful, (*ppOut)
+** should be set to point to the new tokenizer handle and SQLITE_OK
+** returned. If an error occurs, some value other than SQLITE_OK should
+** be returned. In this case, fts5 assumes that the final value of *ppOut
+** is undefined.
+**
+** xDelete:
+** This function is invoked to delete a tokenizer handle previously
+** allocated using xCreate(). Fts5 guarantees that this function will
+** be invoked exactly once for each successful call to xCreate().
+**
+** xTokenize:
+** This function is expected to tokenize the nText byte string indicated
+** by argument pText. pText may or may not be nul-terminated. The first
+** argument passed to this function is a pointer to an Fts5Tokenizer object
+** returned by an earlier call to xCreate().
+**
+** The second argument indicates the reason that FTS5 is requesting
+** tokenization of the supplied text. This is always one of the following
+** four values:
+**
+** <ul><li> <b>FTS5_TOKENIZE_DOCUMENT</b> - A document is being inserted into
+** or removed from the FTS table. The tokenizer is being invoked to
+** determine the set of tokens to add to (or delete from) the
+** FTS index.
+**
+** <li> <b>FTS5_TOKENIZE_QUERY</b> - A MATCH query is being executed
+** against the FTS index. The tokenizer is being called to tokenize
+** a bareword or quoted string specified as part of the query.
+**
+** <li> <b>(FTS5_TOKENIZE_QUERY | FTS5_TOKENIZE_PREFIX)</b> - Same as
+** FTS5_TOKENIZE_QUERY, except that the bareword or quoted string is
+** followed by a "*" character, indicating that the last token
+** returned by the tokenizer will be treated as a token prefix.
+**
+** <li> <b>FTS5_TOKENIZE_AUX</b> - The tokenizer is being invoked to
+** satisfy an fts5_api.xTokenize() request made by an auxiliary
+** function. Or an fts5_api.xColumnSize() request made by the same
+** on a columnsize=0 database.
+** </ul>
+**
+** For each token in the input string, the supplied callback xToken() must
+** be invoked. The first argument to it should be a copy of the pointer
+** passed as the second argument to xTokenize(). The third and fourth
+** arguments are a pointer to a buffer containing the token text, and the
+** size of the token in bytes. The 4th and 5th arguments are the byte offsets
+** of the first byte of and first byte immediately following the text from
+** which the token is derived within the input.
+**
+** The second argument passed to the xToken() callback ("tflags") should
+** normally be set to 0. The exception is if the tokenizer supports
+** synonyms. In this case see the discussion below for details.
+**
+** FTS5 assumes the xToken() callback is invoked for each token in the
+** order that they occur within the input text.
+**
+** If an xToken() callback returns any value other than SQLITE_OK, then
+** the tokenization should be abandoned and the xTokenize() method should
+** immediately return a copy of the xToken() return value. Or, if the
+** input buffer is exhausted, xTokenize() should return SQLITE_OK. Finally,
+** if an error occurs with the xTokenize() implementation itself, it
+** may abandon the tokenization and return any error code other than
+** SQLITE_OK or SQLITE_DONE.
+**
+** SYNONYM SUPPORT
+**
+** Custom tokenizers may also support synonyms. Consider a case in which a
+** user wishes to query for a phrase such as "first place". Using the
+** built-in tokenizers, the FTS5 query 'first + place' will match instances
+** of "first place" within the document set, but not alternative forms
+** such as "1st place". In some applications, it would be better to match
+** all instances of "first place" or "1st place" regardless of which form
+** the user specified in the MATCH query text.
+**
+** There are several ways to approach this in FTS5:
+**
+** <ol><li> By mapping all synonyms to a single token. In this case, the
+** In the above example, this means that the tokenizer returns the
+** same token for inputs "first" and "1st". Say that token is in
+** fact "first", so that when the user inserts the document "I won
+** 1st place" entries are added to the index for tokens "i", "won",
+** "first" and "place". If the user then queries for '1st + place',
+** the tokenizer substitutes "first" for "1st" and the query works
+** as expected.
+**
+** <li> By adding multiple synonyms for a single term to the FTS index.
+** In this case, when tokenizing query text, the tokenizer may
+** provide multiple synonyms for a single term within the document.
+** FTS5 then queries the index for each synonym individually. For
+** example, faced with the query:
+**
+** <codeblock>
+** ... MATCH 'first place'</codeblock>
+**
+** the tokenizer offers both "1st" and "first" as synonyms for the
+** first token in the MATCH query and FTS5 effectively runs a query
+** similar to:
+**
+** <codeblock>
+** ... MATCH '(first OR 1st) place'</codeblock>
+**
+** except that, for the purposes of auxiliary functions, the query
+** still appears to contain just two phrases - "(first OR 1st)"
+** being treated as a single phrase.
+**
+** <li> By adding multiple synonyms for a single term to the FTS index.
+** Using this method, when tokenizing document text, the tokenizer
+** provides multiple synonyms for each token. So that when a
+** document such as "I won first place" is tokenized, entries are
+** added to the FTS index for "i", "won", "first", "1st" and
+** "place".
+**
+** This way, even if the tokenizer does not provide synonyms
+** when tokenizing query text (it should not - to do would be
+** inefficient), it doesn't matter if the user queries for
+** 'first + place' or '1st + place', as there are entires in the
+** FTS index corresponding to both forms of the first token.
+** </ol>
+**
+** Whether it is parsing document or query text, any call to xToken that
+** specifies a <i>tflags</i> argument with the FTS5_TOKEN_COLOCATED bit
+** is considered to supply a synonym for the previous token. For example,
+** when parsing the document "I won first place", a tokenizer that supports
+** synonyms would call xToken() 5 times, as follows:
+**
+** <codeblock>
+** xToken(pCtx, 0, "i", 1, 0, 1);
+** xToken(pCtx, 0, "won", 3, 2, 5);
+** xToken(pCtx, 0, "first", 5, 6, 11);
+** xToken(pCtx, FTS5_TOKEN_COLOCATED, "1st", 3, 6, 11);
+** xToken(pCtx, 0, "place", 5, 12, 17);
+**</codeblock>
+**
+** It is an error to specify the FTS5_TOKEN_COLOCATED flag the first time
+** xToken() is called. Multiple synonyms may be specified for a single token
+** by making multiple calls to xToken(FTS5_TOKEN_COLOCATED) in sequence.
+** There is no limit to the number of synonyms that may be provided for a
+** single token.
+**
+** In many cases, method (1) above is the best approach. It does not add
+** extra data to the FTS index or require FTS5 to query for multiple terms,
+** so it is efficient in terms of disk space and query speed. However, it
+** does not support prefix queries very well. If, as suggested above, the
+** token "first" is subsituted for "1st" by the tokenizer, then the query:
+**
+** <codeblock>
+** ... MATCH '1s*'</codeblock>
+**
+** will not match documents that contain the token "1st" (as the tokenizer
+** will probably not map "1s" to any prefix of "first").
+**
+** For full prefix support, method (3) may be preferred. In this case,
+** because the index contains entries for both "first" and "1st", prefix
+** queries such as 'fi*' or '1s*' will match correctly. However, because
+** extra entries are added to the FTS index, this method uses more space
+** within the database.
+**
+** Method (2) offers a midpoint between (1) and (3). Using this method,
+** a query such as '1s*' will match documents that contain the literal
+** token "1st", but not "first" (assuming the tokenizer is not able to
+** provide synonyms for prefixes). However, a non-prefix query like '1st'
+** will match against "1st" and "first". This method does not require
+** extra disk space, as no extra entries are added to the FTS index.
+** On the other hand, it may require more CPU cycles to run MATCH queries,
+** as separate queries of the FTS index are required for each synonym.
+**
+** When using methods (2) or (3), it is important that the tokenizer only
+** provide synonyms when tokenizing document text (method (2)) or query
+** text (method (3)), not both. Doing so will not cause any errors, but is
+** inefficient.
+*/
+typedef struct Fts5Tokenizer Fts5Tokenizer;
+typedef struct fts5_tokenizer fts5_tokenizer;
+struct fts5_tokenizer {
+ int (*xCreate)(void*, const char **azArg, int nArg, Fts5Tokenizer **ppOut);
+ void (*xDelete)(Fts5Tokenizer*);
+ int (*xTokenize)(Fts5Tokenizer*,
+ void *pCtx,
+ int flags, /* Mask of FTS5_TOKENIZE_* flags */
+ const char *pText, int nText,
+ int (*xToken)(
+ void *pCtx, /* Copy of 2nd argument to xTokenize() */
+ int tflags, /* Mask of FTS5_TOKEN_* flags */
+ const char *pToken, /* Pointer to buffer containing token */
+ int nToken, /* Size of token in bytes */
+ int iStart, /* Byte offset of token within input text */
+ int iEnd /* Byte offset of end of token within input text */
+ )
+ );
+};
+
+/* Flags that may be passed as the third argument to xTokenize() */
+#define FTS5_TOKENIZE_QUERY 0x0001
+#define FTS5_TOKENIZE_PREFIX 0x0002
+#define FTS5_TOKENIZE_DOCUMENT 0x0004
+#define FTS5_TOKENIZE_AUX 0x0008
+
+/* Flags that may be passed by the tokenizer implementation back to FTS5
+** as the third argument to the supplied xToken callback. */
+#define FTS5_TOKEN_COLOCATED 0x0001 /* Same position as prev. token */
+
+/*
+** END OF CUSTOM TOKENIZERS
+*************************************************************************/
+
+/*************************************************************************
+** FTS5 EXTENSION REGISTRATION API
+*/
+typedef struct fts5_api fts5_api;
+struct fts5_api {
+ int iVersion; /* Currently always set to 2 */
+
+ /* Create a new tokenizer */
+ int (*xCreateTokenizer)(
+ fts5_api *pApi,
+ const char *zName,
+ void *pContext,
+ fts5_tokenizer *pTokenizer,
+ void (*xDestroy)(void*)
+ );
+
+ /* Find an existing tokenizer */
+ int (*xFindTokenizer)(
+ fts5_api *pApi,
+ const char *zName,
+ void **ppContext,
+ fts5_tokenizer *pTokenizer
+ );
+
+ /* Create a new auxiliary function */
+ int (*xCreateFunction)(
+ fts5_api *pApi,
+ const char *zName,
+ void *pContext,
+ fts5_extension_function xFunction,
+ void (*xDestroy)(void*)
+ );
+};
+
+/*
+** END OF REGISTRATION API
+*************************************************************************/
+
+#ifdef __cplusplus
+} /* end of the 'extern "C"' block */
+#endif
+
+#endif /* _FTS5_H */
+
+
diff --git a/nss/lib/ssl/Makefile b/nss/lib/ssl/Makefile
index d56cbf2..24fccc5 100644
--- a/nss/lib/ssl/Makefile
+++ b/nss/lib/ssl/Makefile
@@ -18,8 +18,8 @@ include $(CORE_DEPTH)/coreconf/config.mk
#######################################################################
# (3) Include "component" configuration information. (OPTIONAL) #
-#######################################################################
-
+######################################################################
+#
#######################################################################
@@ -39,6 +39,13 @@ CSRCS += unix_err.c
endif
endif
+# Enable key logging by default in debug builds, but not opt builds.
+# Logging still needs to be enabled at runtime through env vars.
+NSS_ALLOW_SSLKEYLOGFILE ?= $(if $(BUILD_OPT),0,1)
+ifeq (1,$(NSS_ALLOW_SSLKEYLOGFILE))
+DEFINES += -DNSS_ALLOW_SSLKEYLOGFILE=1
+endif
+
#######################################################################
# (5) Execute "global" rules. (OPTIONAL) #
#######################################################################
@@ -56,8 +63,3 @@ include $(CORE_DEPTH)/coreconf/rules.mk
#######################################################################
export:: private_export
-
-ifndef NSS_NO_PKCS11_BYPASS
-# indicates dependency on freebl static lib
-$(SHARED_LIBRARY): $(CRYPTOLIB)
-endif
diff --git a/nss/lib/ssl/SSLerrs.h b/nss/lib/ssl/SSLerrs.h
index 6028396..b0319b8 100644
--- a/nss/lib/ssl/SSLerrs.h
+++ b/nss/lib/ssl/SSLerrs.h
@@ -2,441 +2,506 @@
* License, v. 2.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 UNUSED_ERROR(x) ER3(SSL_ERROR_UNUSED_##x, (SSL_ERROR_BASE + x), \
+ "Unrecognized SSL error_code.")
+
/* 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_EXPORT_ONLY_SERVER, SSL_ERROR_BASE + 0,
+ "Unable to communicate securely. Peer does not support high-grade encryption.")
-ER3(SSL_ERROR_NO_CYPHER_OVERLAP, SSL_ERROR_BASE + 2,
-"Cannot communicate securely with peer: no common encryption algorithm(s).")
+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_CERTIFICATE, SSL_ERROR_BASE + 3,
-"Unable to find the certificate or key necessary for authentication.")
+ER3(SSL_ERROR_NO_CYPHER_OVERLAP, SSL_ERROR_BASE + 2,
+ "Cannot communicate securely with peer: no common encryption algorithm(s).")
-ER3(SSL_ERROR_BAD_CERTIFICATE, SSL_ERROR_BASE + 4,
-"Unable to communicate securely with peer: peers's certificate was rejected.")
+ER3(SSL_ERROR_NO_CERTIFICATE, SSL_ERROR_BASE + 3,
+ "Unable to find the certificate or key necessary for authentication.")
-ER3(SSL_ERROR_UNUSED_5, SSL_ERROR_BASE + 5,
-"Unrecognized SSL error code.")
+ER3(SSL_ERROR_BAD_CERTIFICATE, SSL_ERROR_BASE + 4,
+ "Unable to communicate securely with peer: peers's certificate was rejected.")
-ER3(SSL_ERROR_BAD_CLIENT, SSL_ERROR_BASE + 6,
-"The server has encountered bad data from the client.")
+UNUSED_ERROR(5)
-ER3(SSL_ERROR_BAD_SERVER, SSL_ERROR_BASE + 7,
-"The client has encountered bad data from the server.")
+ER3(SSL_ERROR_BAD_CLIENT, SSL_ERROR_BASE + 6,
+ "The server has encountered bad data from the client.")
-ER3(SSL_ERROR_UNSUPPORTED_CERTIFICATE_TYPE, SSL_ERROR_BASE + 8,
-"Unsupported certificate type.")
+ER3(SSL_ERROR_BAD_SERVER, SSL_ERROR_BASE + 7,
+ "The client has encountered bad data from the server.")
-ER3(SSL_ERROR_UNSUPPORTED_VERSION, SSL_ERROR_BASE + 9,
-"Peer using unsupported version of security protocol.")
+ER3(SSL_ERROR_UNSUPPORTED_CERTIFICATE_TYPE, SSL_ERROR_BASE + 8,
+ "Unsupported certificate type.")
-ER3(SSL_ERROR_UNUSED_10, SSL_ERROR_BASE + 10,
-"Unrecognized SSL error code.")
+ER3(SSL_ERROR_UNSUPPORTED_VERSION, SSL_ERROR_BASE + 9,
+ "Peer using unsupported version of security protocol.")
-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.")
+UNUSED_ERROR(10)
-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_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_POST_WARNING, SSL_ERROR_BASE + 13,
-"Unrecognized SSL error code.")
+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_SSL2_DISABLED, (SSL_ERROR_BASE + 14),
-"Peer only supports SSL version 2, which is locally disabled.")
+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_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_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_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_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_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_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_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_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_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_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_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.")
+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_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_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_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_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_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_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_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_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_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.")
+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_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_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_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.")
+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_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_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_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_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_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_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_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_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_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.")
+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_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_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_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.")
+ "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_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_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.")
+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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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 authentication type.")
-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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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.")
+ "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.")
+ "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_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_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_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.")
+ "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_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_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_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.")
+ "SSL feature not supported for servers.")
ER3(SSL_ERROR_FEATURE_NOT_SUPPORTED_FOR_CLIENTS, (SSL_ERROR_BASE + 119),
-"SSL feature not supported for clients.")
+ "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_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_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.")
+ "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.")
+ "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.")
+ "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.")
+ER3(SSL_ERROR_RX_UNEXPECTED_CERT_STATUS, (SSL_ERROR_BASE + 125),
+ "SSL received an unexpected Certificate Status handshake message.")
ER3(SSL_ERROR_UNSUPPORTED_HASH_ALGORITHM, (SSL_ERROR_BASE + 126),
-"Unsupported hash algorithm used by TLS peer.")
+ "Unsupported hash algorithm used by TLS peer.")
ER3(SSL_ERROR_DIGEST_FAILURE, (SSL_ERROR_BASE + 127),
-"Digest function failed.")
+ "Digest function failed.")
ER3(SSL_ERROR_INCORRECT_SIGNATURE_ALGORITHM, (SSL_ERROR_BASE + 128),
-"Incorrect signature algorithm specified in a digitally-signed element.")
+ "Incorrect signature algorithm specified in a digitally-signed element.")
ER3(SSL_ERROR_NEXT_PROTOCOL_NO_CALLBACK, (SSL_ERROR_BASE + 129),
-"The next protocol negotiation extension was enabled, but the callback was cleared prior to being needed.")
+ "The next protocol negotiation extension was enabled, but the callback was cleared prior to being needed.")
ER3(SSL_ERROR_NEXT_PROTOCOL_NO_PROTOCOL, (SSL_ERROR_BASE + 130),
-"The server supports no protocols that the client advertises in the ALPN extension.")
+ "The server supports no protocols that the client advertises in the ALPN extension.")
ER3(SSL_ERROR_INAPPROPRIATE_FALLBACK_ALERT, (SSL_ERROR_BASE + 131),
-"The server rejected the handshake because the client downgraded to a lower "
-"TLS version than the server supports.")
+ "The server rejected the handshake because the client downgraded to a lower "
+ "TLS version than the server supports.")
ER3(SSL_ERROR_WEAK_SERVER_CERT_KEY, (SSL_ERROR_BASE + 132),
-"The server certificate included a public key that was too weak.")
+ "The server certificate included a public key that was too weak.")
ER3(SSL_ERROR_RX_SHORT_DTLS_READ, (SSL_ERROR_BASE + 133),
-"Not enough room in buffer for DTLS record.")
+ "Not enough room in buffer for DTLS record.")
ER3(SSL_ERROR_NO_SUPPORTED_SIGNATURE_ALGORITHM, (SSL_ERROR_BASE + 134),
-"No supported TLS signature algorithm was configured.")
+ "No supported TLS signature algorithm was configured.")
ER3(SSL_ERROR_UNSUPPORTED_SIGNATURE_ALGORITHM, (SSL_ERROR_BASE + 135),
-"The peer used an unsupported combination of signature and hash algorithm.")
+ "The peer used an unsupported combination of signature and hash algorithm.")
ER3(SSL_ERROR_MISSING_EXTENDED_MASTER_SECRET, (SSL_ERROR_BASE + 136),
-"The peer tried to resume without a correct extended_master_secret extension")
+ "The peer tried to resume without a correct extended_master_secret extension")
ER3(SSL_ERROR_UNEXPECTED_EXTENDED_MASTER_SECRET, (SSL_ERROR_BASE + 137),
-"The peer tried to resume with an unexpected extended_master_secret extension")
+ "The peer tried to resume with an unexpected extended_master_secret extension")
+
+ER3(SSL_ERROR_RX_MALFORMED_KEY_SHARE, (SSL_ERROR_BASE + 138),
+ "SSL received a malformed Key Share extension.")
+
+ER3(SSL_ERROR_MISSING_KEY_SHARE, (SSL_ERROR_BASE + 139),
+ "SSL expected a Key Share extension.")
+
+ER3(SSL_ERROR_RX_MALFORMED_ECDHE_KEY_SHARE, (SSL_ERROR_BASE + 140),
+ "SSL received a malformed ECDHE key share handshake extension.")
+
+ER3(SSL_ERROR_RX_MALFORMED_DHE_KEY_SHARE, (SSL_ERROR_BASE + 141),
+ "SSL received a malformed DHE key share handshake extension.")
+
+ER3(SSL_ERROR_RX_UNEXPECTED_ENCRYPTED_EXTENSIONS, (SSL_ERROR_BASE + 142),
+ "SSL received an unexpected Encrypted Extensions handshake message.")
+
+ER3(SSL_ERROR_MISSING_EXTENSION_ALERT, (SSL_ERROR_BASE + 143),
+ "SSL received a missing_extension alert.")
+
+ER3(SSL_ERROR_KEY_EXCHANGE_FAILURE, (SSL_ERROR_BASE + 144),
+ "SSL had an error performing key exchange.")
+
+ER3(SSL_ERROR_EXTENSION_DISALLOWED_FOR_VERSION, (SSL_ERROR_BASE + 145),
+ "SSL received an extension that is not permitted for this version.")
+
+ER3(SSL_ERROR_RX_MALFORMED_ENCRYPTED_EXTENSIONS, (SSL_ERROR_BASE + 146),
+ "SSL received a malformed Encrypted Extensions handshake message.")
+
+ER3(SSL_ERROR_RX_MALFORMED_PRE_SHARED_KEY, (SSL_ERROR_BASE + 147),
+ "SSL received an invalid PreSharedKey extension.")
+
+ER3(SSL_ERROR_RX_MALFORMED_EARLY_DATA, (SSL_ERROR_BASE + 148),
+ "SSL received an invalid EarlyData extension.")
+
+ER3(SSL_ERROR_END_OF_EARLY_DATA_ALERT, (SSL_ERROR_BASE + 149),
+ "SSL received an unexpected end of early data alert.")
+
+ER3(SSL_ERROR_MISSING_ALPN_EXTENSION, (SSL_ERROR_BASE + 150),
+ "SSL didn't receive an expected ALPN extension.")
+
+ER3(SSL_ERROR_RX_UNEXPECTED_EXTENSION, (SSL_ERROR_BASE + 151),
+ "SSL received an unexpected extension.")
+
+ER3(SSL_ERROR_MISSING_SUPPORTED_GROUPS, (SSL_ERROR_BASE + 152),
+ "SSL expected a supported groups extension.")
+
+ER3(SSL_ERROR_TOO_MANY_RECORDS, (SSL_ERROR_BASE + 153),
+ "SSL sent or received too many records with the same symmetric key.")
+
+ER3(SSL_ERROR_RX_UNEXPECTED_HELLO_RETRY_REQUEST, (SSL_ERROR_BASE + 154),
+ "SSL received an unexpected Hello Retry Request handshake message.")
+
+ER3(SSL_ERROR_RX_MALFORMED_HELLO_RETRY_REQUEST, (SSL_ERROR_BASE + 155),
+ "SSL received a malformed Hello Retry Request handshake message.")
+
+ER3(SSL_ERROR_BAD_2ND_CLIENT_HELLO, (SSL_ERROR_BASE + 156),
+ "SSL received a second Client Hello message without a usable key share.")
+
+ER3(SSL_ERROR_MISSING_SIGNATURE_ALGORITHMS_EXTENSION, (SSL_ERROR_BASE + 157),
+ "SSL expected a signature algorithms extension.")
+
+ER3(SSL_ERROR_MALFORMED_PSK_KEY_EXCHANGE_MODES, (SSL_ERROR_BASE + 158),
+ "SSL received a malformed PSK key exchange modes extension.")
+
+ER3(SSL_ERROR_MISSING_PSK_KEY_EXCHANGE_MODES, (SSL_ERROR_BASE + 159),
+ "SSL expected a missing PSK key exchange modes extension.")
diff --git a/nss/lib/ssl/authcert.c b/nss/lib/ssl/authcert.c
index bd0f6ed..88c7c08 100644
--- a/nss/lib/ssl/authcert.c
+++ b/nss/lib/ssl/authcert.c
@@ -16,74 +16,74 @@
#include "key.h"
#include "nss.h"
#include "ssl.h"
-#include "pk11func.h" /* for PK11_ function calls */
+#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)
+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);
- }
+ 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);
+ }
}
- } 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;
}
- }
- if (rv == SECSuccess) {
- *pRetCert = cert;
- *pRetKey = privkey;
- }
- return rv;
+ return rv;
}
-
diff --git a/nss/lib/ssl/cmpcert.c b/nss/lib/ssl/cmpcert.c
index 6d84238..e6edbee 100644
--- a/nss/lib/ssl/cmpcert.c
+++ b/nss/lib/ssl/cmpcert.c
@@ -18,73 +18,72 @@
/*
* Look to see if any of the signers in the cert chain for "cert" are found
- * in the list of caNames.
+ * 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;
+ 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;
+ 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;
-
+ rv = SECFailure;
+
done:
- return rv;
+ return rv;
}
-
diff --git a/nss/lib/ssl/config.mk b/nss/lib/ssl/config.mk
index 40b1c30..339cc80 100644
--- a/nss/lib/ssl/config.mk
+++ b/nss/lib/ssl/config.mk
@@ -7,21 +7,6 @@ ifdef NISCC_TEST
DEFINES += -DNISCC_TEST
endif
-# Allow build-time configuration of TLS 1.3 (Experimental)
-ifdef NSS_ENABLE_TLS_1_3
-DEFINES += -DNSS_ENABLE_TLS_1_3
-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
@@ -72,22 +57,15 @@ 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
+ifdef NSS_SSL_ENABLE_ZLIB
+DEFINES += -DNSS_SSL_ENABLE_ZLIB
+include $(CORE_DEPTH)/coreconf/zlib.mk
+endif
-# 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)
+ifndef NSS_ENABLE_TLS_1_3
+NSS_DISABLE_TLS_1_3=1
endif
+ifdef NSS_DISABLE_TLS_1_3
+DEFINES += -DNSS_DISABLE_TLS_1_3
endif
diff --git a/nss/lib/ssl/derive.c b/nss/lib/ssl/derive.c
deleted file mode 100644
index 8b58b80..0000000
--- a/nss/lib/ssl/derive.c
+++ /dev/null
@@ -1,896 +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/. */
-
-#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 */
- PRBool explicitIV = PR_FALSE;
- SECStatus rv = SECFailure;
- SECStatus status = SECSuccess;
- PRBool isFIPS = PR_FALSE;
- PRBool isTLS12 = pwSpec->version >= SSL_LIBRARY_VERSION_TLS_1_2;
-
- 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 */
- }
- if (cipher_def->type == type_block &&
- pwSpec->version >= SSL_LIBRARY_VERSION_TLS_1_1) {
- /* Block ciphers in >= TLS 1.1 use a per-record, explicit IV. */
- explicitIV = PR_TRUE;
- }
- block_needed =
- 2 * (macSize + effKeySize + ((!isExport && !explicitIV) * 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;
-
- if (isTLS12) {
- status = TLS_P_hash(HASH_AlgSHA256, &pwSpec->msItem,
- "key expansion", &srcr, &keyblk, isFIPS);
- } else {
- 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) {
- if (explicitIV) {
- static unsigned char zero_block[32];
- PORT_Assert(IVSize <= sizeof zero_block);
- buildSSLKey(&zero_block[0], IVSize, \
- &pwSpec->client.write_iv_item, \
- "Domestic Client Write IV");
- buildSSLKey(&zero_block[0], IVSize, \
- &pwSpec->server.write_iv_item, \
- "Domestic Server Write IV");
- } else {
- /*
- ** 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_MasterSecretDeriveBypass(
- 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;
- PRBool isTLS12 = pwSpec->version >= SSL_LIBRARY_VERSION_TLS_1_2;
-
- 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;
-
- if (isTLS12) {
- rv = TLS_P_hash(HASH_AlgSHA256, pms, "master secret", &crsr,
- &master, isFIPS);
- } else {
- 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;
-#ifndef NSS_DISABLE_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 (TLS_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 TLS_RSA_EXPORT_WITH_RC4_40_MD5:
- case TLS_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);
- }
-#ifndef NSS_DISABLE_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_GetSupportedECCurveMask(NULL),
- 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_DISABLE_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);
- }
-#ifndef NSS_DISABLE_ECC
- if (ecParams.data != NULL) {
- PORT_Free(ecParams.data);
- ecParams.data = NULL;
- }
-#endif /* NSS_DISABLE_ECC */
-
- if (srvPubkey) {
- SECKEY_DestroyPublicKey(srvPubkey);
- srvPubkey = NULL;
- }
-
-
- return rv;
-#endif /* NO_PKCS11_BYPASS */
-}
-
diff --git a/nss/lib/ssl/dhe-param.c b/nss/lib/ssl/dhe-param.c
index ac0942e..ad87cc4 100644
--- a/nss/lib/ssl/dhe-param.c
+++ b/nss/lib/ssl/dhe-param.c
@@ -39,7 +39,8 @@ static const unsigned char ff_dhe_2048_p[] = {
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
};
-static const ssl3DHParams ff_dhe_2048 = {
+static const ssl3DHParams ff_dhe_2048_params = {
+ ssl_grp_ffdhe_2048,
{ siBuffer, (unsigned char *)ff_dhe_2048_p, sizeof(ff_dhe_2048_p) },
{ siBuffer, (unsigned char *)ff_dhe_g2, sizeof(ff_dhe_g2) },
};
@@ -95,7 +96,8 @@ static const unsigned char ff_dhe_3072_p[] = {
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
};
-static const ssl3DHParams ff_dhe_3072 = {
+static const ssl3DHParams ff_dhe_3072_params = {
+ ssl_grp_ffdhe_3072,
{ siBuffer, (unsigned char *)ff_dhe_3072_p, sizeof(ff_dhe_3072_p) },
{ siBuffer, (unsigned char *)ff_dhe_g2, sizeof(ff_dhe_g2) },
};
@@ -167,7 +169,8 @@ static const unsigned char ff_dhe_4096_p[] = {
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
};
-static const ssl3DHParams ff_dhe_4096 = {
+static const ssl3DHParams ff_dhe_4096_params = {
+ ssl_grp_ffdhe_4096,
{ siBuffer, (unsigned char *)ff_dhe_4096_p, sizeof(ff_dhe_4096_p) },
{ siBuffer, (unsigned char *)ff_dhe_g2, sizeof(ff_dhe_g2) },
};
@@ -271,7 +274,8 @@ static const unsigned char ff_dhe_6144_p[] = {
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
};
-static const ssl3DHParams ff_dhe_6144 = {
+static const ssl3DHParams ff_dhe_6144_params = {
+ ssl_grp_ffdhe_6144,
{ siBuffer, (unsigned char *)ff_dhe_6144_p, sizeof(ff_dhe_6144_p) },
{ siBuffer, (unsigned char *)ff_dhe_g2, sizeof(ff_dhe_g2) },
};
@@ -407,7 +411,8 @@ static const unsigned char ff_dhe_8192_p[] = {
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
};
-static const ssl3DHParams ff_dhe_8192 = {
+static const ssl3DHParams ff_dhe_8192_params = {
+ ssl_grp_ffdhe_8192,
{ siBuffer, (unsigned char *)ff_dhe_8192_p, sizeof(ff_dhe_8192_p) },
{ siBuffer, (unsigned char *)ff_dhe_g2, sizeof(ff_dhe_g2) },
};
diff --git a/nss/lib/ssl/dtlscon.c b/nss/lib/ssl/dtlscon.c
index 1b21107..09ceeac 100644
--- a/nss/lib/ssl/dtlscon.c
+++ b/nss/lib/ssl/dtlscon.c
@@ -1,3 +1,4 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
@@ -11,38 +12,34 @@
#include "sslproto.h"
#ifndef PR_ARRAY_SIZE
-#define PR_ARRAY_SIZE(a) (sizeof(a)/sizeof((a)[0]))
+#define PR_ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0]))
#endif
static SECStatus dtls_TransmitMessageFlight(sslSocket *ss);
+static SECStatus dtls_StartRetransmitTimer(sslSocket *ss);
static void dtls_RetransmitTimerExpiredCb(sslSocket *ss);
static SECStatus dtls_SendSavedWriteData(sslSocket *ss);
+static void dtls_FinishedTimerCb(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 */
+ 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[] = {
-#ifndef NSS_DISABLE_ECC
TLS_ECDHE_ECDSA_WITH_RC4_128_SHA,
TLS_ECDHE_RSA_WITH_RC4_128_SHA,
-#endif /* NSS_DISABLE_ECC */
TLS_DHE_DSS_WITH_RC4_128_SHA,
-#ifndef NSS_DISABLE_ECC
TLS_ECDH_RSA_WITH_RC4_128_SHA,
TLS_ECDH_ECDSA_WITH_RC4_128_SHA,
-#endif /* NSS_DISABLE_ECC */
TLS_RSA_WITH_RC4_128_MD5,
TLS_RSA_WITH_RC4_128_SHA,
- TLS_RSA_EXPORT1024_WITH_RC4_56_SHA,
- TLS_RSA_EXPORT_WITH_RC4_40_MD5,
0 /* End of list marker */
};
@@ -86,6 +83,11 @@ dtls_DTLSVersionToTLSVersion(SSL3ProtocolVersion dtlsv)
if (dtlsv == SSL_LIBRARY_VERSION_DTLS_1_0_WIRE) {
return SSL_LIBRARY_VERSION_TLS_1_1;
}
+ /* Handle the skipped version of DTLS 1.1 by returning
+ * an error. */
+ if (dtlsv == ((~0x0101) & 0xffff)) {
+ return 0;
+ }
if (dtlsv == SSL_LIBRARY_VERSION_DTLS_1_2_WIRE) {
return SSL_LIBRARY_VERSION_TLS_1_2;
}
@@ -94,14 +96,14 @@ dtls_DTLSVersionToTLSVersion(SSL3ProtocolVersion dtlsv)
}
/* Return a fictional higher version than we know of */
- return SSL_LIBRARY_VERSION_TLS_1_2 + 1;
+ return SSL_LIBRARY_VERSION_MAX_SUPPORTED + 1;
}
/* On this socket, Disable non-DTLS cipher suites in the argument's list */
SECStatus
-ssl3_DisableNonDTLSSuites(sslSocket * ss)
+ssl3_DisableNonDTLSSuites(sslSocket *ss)
{
- const ssl3CipherSuite * suite;
+ const ssl3CipherSuite *suite;
for (suite = nonDTLSSuites; *suite; ++suite) {
PORT_CheckSuccess(ssl3_CipherPrefSet(ss, *suite, PR_FALSE));
@@ -114,7 +116,7 @@ ssl3_DisableNonDTLSSuites(sslSocket * ss)
* Called from dtls_QueueMessage()
*/
static DTLSQueuedMessage *
-dtls_AllocQueuedMessage(PRUint16 epoch, SSL3ContentType type,
+dtls_AllocQueuedMessage(ssl3CipherSpec *cwSpec, SSL3ContentType type,
const unsigned char *data, PRUint32 len)
{
DTLSQueuedMessage *msg = NULL;
@@ -131,8 +133,11 @@ dtls_AllocQueuedMessage(PRUint16 epoch, SSL3ContentType type,
PORT_Memcpy(msg->data, data, len);
msg->len = len;
- msg->epoch = epoch;
+ msg->cwSpec = cwSpec;
msg->type = type;
+ /* Safe if we are < 1.3, since the refct is
+ * already very high. */
+ tls13_CipherSpecAddRef(cwSpec);
return msg;
}
@@ -142,12 +147,15 @@ dtls_AllocQueuedMessage(PRUint16 epoch, SSL3ContentType type,
*
* Called from dtls_FreeHandshakeMessages()
*/
-static void
+void
dtls_FreeHandshakeMessage(DTLSQueuedMessage *msg)
{
if (!msg)
return;
+ /* Safe if we are < 1.3, since the refct is
+ * already very high. */
+ tls13_CipherSpecRelease(msg->cwSpec);
PORT_ZFree(msg->data, msg->len);
PORT_Free(msg);
}
@@ -171,6 +179,62 @@ dtls_FreeHandshakeMessages(PRCList *list)
}
}
+/* Called by dtls_HandleHandshake() and dtls_MaybeRetransmitHandshake() if a
+ * handshake message retransmission is detected. */
+static SECStatus
+dtls_RetransmitDetected(sslSocket *ss)
+{
+ SECStatus rv = SECSuccess;
+
+ PORT_Assert(ss->opt.noLocks || ssl_HaveRecvBufLock(ss));
+ PORT_Assert(ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss));
+
+ if (ss->ssl3.hs.rtTimerCb == dtls_RetransmitTimerExpiredCb) {
+ /* 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 it 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);
+ } else {
+ SSL_TRC(30,
+ ("%d: SSL3[%d]: Ignoring retransmission: "
+ "last retransmission %dms ago, suppressed for %dms",
+ SSL_GETPID(), ss->fd,
+ PR_IntervalNow() - ss->ssl3.hs.rtTimerStarted,
+ ss->ssl3.hs.rtTimeoutMs / 4));
+ }
+
+ } else if (ss->ssl3.hs.rtTimerCb == dtls_FinishedTimerCb) {
+ SSL_TRC(30, ("%d: SSL3[%d]: Retransmit detected in holddown",
+ SSL_GETPID(), ss->fd));
+ /* 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_StartHolddownTimer(ss);
+ }
+
+ } else {
+ PORT_Assert(ss->ssl3.hs.rtTimerCb == NULL);
+ /* ... and ignore it. */
+ }
+ return rv;
+}
+
/* 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
@@ -185,8 +249,8 @@ dtls_FreeHandshakeMessages(PRCList *list)
* 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))
+#define OFFSET_BYTE(o) (o / 8)
+#define OFFSET_MASK(o) (1 << (o % 8))
SECStatus
dtls_HandleHandshake(sslSocket *ss, sslBuffer *origBuf)
@@ -224,7 +288,7 @@ dtls_HandleHandshake(sslSocket *ss, sslBuffer *origBuf)
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 */
+#define MAX_HANDSHAKE_MSG_LEN 0x1ffff /* 128k - 1 */
if (message_length > MAX_HANDSHAKE_MSG_LEN) {
(void)ssl3_DecodeError(ss);
PORT_SetError(SSL_ERROR_RX_MALFORMED_HANDSHAKE);
@@ -258,9 +322,9 @@ dtls_HandleHandshake(sslSocket *ss, sslBuffer *origBuf)
* 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)) {
+ 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;
@@ -274,10 +338,11 @@ dtls_HandleHandshake(sslSocket *ss, sslBuffer *origBuf)
/* 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;
+ ss->ssl3.hs.rtTimeoutMs = DTLS_RETRANSMIT_INITIAL_MS;
}
- rv = ssl3_HandleHandshakeMessage(ss, buf.buf, ss->ssl3.hs.msg_len);
+ rv = ssl3_HandleHandshakeMessage(ss, buf.buf, ss->ssl3.hs.msg_len,
+ buf.len == fragment_length);
if (rv == SECFailure) {
/* Do not attempt to process rest of messages in this record */
break;
@@ -285,52 +350,9 @@ dtls_HandleHandshake(sslSocket *ss, sslBuffer *origBuf)
} 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;
- }
+ * in a waiting state. */
+ rv = dtls_RetransmitDetected(ss);
+ break;
} else if (message_seq > ss->ssl3.hs.recvMessageSeq) {
/* Case 2
*
@@ -426,9 +448,10 @@ dtls_HandleHandshake(sslSocket *ss, sslBuffer *origBuf)
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);
+ rv = ssl3_HandleHandshakeMessage(
+ ss,
+ ss->ssl3.hs.msg_body.buf, ss->ssl3.hs.msg_len,
+ buf.len == fragment_length);
if (rv == SECFailure)
break; /* Skip rest of record */
@@ -440,7 +463,7 @@ dtls_HandleHandshake(sslSocket *ss, sslBuffer *origBuf)
/* 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;
+ ss->ssl3.hs.rtTimeoutMs = DTLS_RETRANSMIT_INITIAL_MS;
}
}
}
@@ -450,7 +473,7 @@ dtls_HandleHandshake(sslSocket *ss, sslBuffer *origBuf)
buf.len -= fragment_length;
}
- origBuf->len = 0; /* So ssl3_GatherAppDataRecord will keep looping. */
+ 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 */
@@ -463,16 +486,19 @@ dtls_HandleHandshake(sslSocket *ss, sslBuffer *origBuf)
* dtls_StageHandshakeMessage()
* ssl3_SendChangeCipherSpecs()
*/
-SECStatus dtls_QueueMessage(sslSocket *ss, SSL3ContentType type,
- const SSL3Opaque *pIn, PRInt32 nIn)
+SECStatus
+dtls_QueueMessage(sslSocket *ss, SSL3ContentType type,
+ const SSL3Opaque *pIn, PRInt32 nIn)
{
SECStatus rv = SECSuccess;
DTLSQueuedMessage *msg = NULL;
+ ssl3CipherSpec *spec;
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);
+ spec = ss->ssl3.cwSpec;
+ msg = dtls_AllocQueuedMessage(spec, type, pIn, nIn);
if (!msg) {
PORT_SetError(SEC_ERROR_NO_MEMORY);
@@ -534,12 +560,12 @@ dtls_FlushHandshakeMessages(sslSocket *ss, PRInt32 flags)
if (!(flags & ssl_SEND_FLAG_FORCE_INTO_BUFFER)) {
rv = dtls_TransmitMessageFlight(ss);
- if (rv != SECSuccess)
+ if (rv != SECSuccess) {
return rv;
+ }
if (!(flags & ssl_SEND_FLAG_NO_RETRANSMIT)) {
- ss->ssl3.hs.rtRetries = 0;
- rv = dtls_StartTimer(ss, dtls_RetransmitTimerExpiredCb);
+ rv = dtls_StartRetransmitTimer(ss);
}
}
@@ -555,7 +581,7 @@ dtls_FlushHandshakeMessages(sslSocket *ss, PRInt32 flags)
static void
dtls_RetransmitTimerExpiredCb(sslSocket *ss)
{
- SECStatus rv = SECFailure;
+ SECStatus rv;
ss->ssl3.hs.rtRetries++;
@@ -568,15 +594,22 @@ dtls_RetransmitTimerExpiredCb(sslSocket *ss)
rv = dtls_TransmitMessageFlight(ss);
if (rv == SECSuccess) {
-
/* Re-arm the timer */
- rv = dtls_RestartTimer(ss, PR_TRUE, dtls_RetransmitTimerExpiredCb);
- }
+ ss->ssl3.hs.rtTimeoutMs *= 2;
+ if (ss->ssl3.hs.rtTimeoutMs > DTLS_RETRANSMIT_MAX_MS) {
+ ss->ssl3.hs.rtTimeoutMs = DTLS_RETRANSMIT_MAX_MS;
+ }
- 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 */
+ ss->ssl3.hs.rtTimerStarted = PR_IntervalNow();
+ ss->ssl3.hs.rtTimerCb = dtls_RetransmitTimerExpiredCb;
+
+ SSL_TRC(30,
+ ("%d: SSL3[%d]: Retransmit #%d, next in %d",
+ SSL_GETPID(), ss->fd,
+ ss->ssl3.hs.rtRetries, ss->ssl3.hs.rtTimeoutMs));
}
+ /* else: 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
@@ -631,10 +664,9 @@ dtls_TransmitMessageFlight(sslSocket *ss)
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,
+ sent = ssl3_SendRecord(ss, msg->cwSpec, msg->type,
msg->data, msg->len,
- ssl_SEND_FLAG_FORCE_INTO_BUFFER |
- ssl_SEND_FLAG_USE_EPOCH);
+ ssl_SEND_FLAG_FORCE_INTO_BUFFER);
if (sent != msg->len) {
rv = SECFailure;
if (sent != -1) {
@@ -694,12 +726,12 @@ dtls_TransmitMessageFlight(sslSocket *ss)
/* Offset */
fragment[6] = (fragment_offset >> 16) & 0xff;
fragment[7] = (fragment_offset >> 8) & 0xff;
- fragment[8] = (fragment_offset) & 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;
+ fragment[11] = (fragment_len)&0xff;
PORT_Memcpy(fragment + 12, content + fragment_offset,
fragment_len);
@@ -708,10 +740,9 @@ dtls_TransmitMessageFlight(sslSocket *ss)
* Send the record. We do this in two stages
* 1. Encrypt
*/
- sent = ssl3_SendRecord(ss, msg->epoch, msg->type,
+ sent = ssl3_SendRecord(ss, msg->cwSpec, msg->type,
fragment, fragment_len + 12,
- ssl_SEND_FLAG_FORCE_INTO_BUFFER |
- ssl_SEND_FLAG_USE_EPOCH);
+ ssl_SEND_FLAG_FORCE_INTO_BUFFER);
if (sent != (fragment_len + 12)) {
rv = SECFailure;
if (sent != -1) {
@@ -747,8 +778,8 @@ dtls_TransmitMessageFlight(sslSocket *ss)
*
* Called from dtls_TransmitMessageFlight()
*/
-static
-SECStatus dtls_SendSavedWriteData(sslSocket *ss)
+static SECStatus
+dtls_SendSavedWriteData(sslSocket *ss)
{
PRInt32 sent;
@@ -771,93 +802,32 @@ SECStatus dtls_SendSavedWriteData(sslSocket *ss)
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)
+static SECStatus
+dtls_StartTimer(sslSocket *ss, PRUint32 time, DTLSTimerCb cb)
{
PORT_Assert(ss->ssl3.hs.rtTimerCb == NULL);
+ ss->ssl3.hs.rtRetries = 0;
ss->ssl3.hs.rtTimerStarted = PR_IntervalNow();
+ ss->ssl3.hs.rtTimeoutMs = time;
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)
+/* Start a timer for retransmission. */
+static SECStatus
+dtls_StartRetransmitTimer(sslSocket *ss)
{
- 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, DTLS_RETRANSMIT_INITIAL_MS,
+ dtls_RetransmitTimerExpiredCb);
+}
- return dtls_StartTimer(ss, cb);
+/* Start a timer for holding an old cipher spec. */
+SECStatus
+dtls_StartHolddownTimer(sslSocket *ss)
+{
+ return dtls_StartTimer(ss, DTLS_RETRANSMIT_FINISHED_MS,
+ dtls_FinishedTimerCb);
}
/* Cancel a pending timer
@@ -881,8 +851,11 @@ dtls_CancelTimer(sslSocket *ss)
void
dtls_CheckTimer(sslSocket *ss)
{
- if (!ss->ssl3.hs.rtTimerCb)
+ ssl_GetSSL3HandshakeLock(ss);
+ if (!ss->ssl3.hs.rtTimerCb) {
+ ssl_ReleaseSSL3HandshakeLock(ss);
return;
+ }
if ((PR_IntervalNow() - ss->ssl3.hs.rtTimerStarted) >
PR_MillisecondsToInterval(ss->ssl3.hs.rtTimeoutMs)) {
@@ -895,6 +868,7 @@ dtls_CheckTimer(sslSocket *ss)
/* Now call the CB */
cb(ss);
}
+ ssl_ReleaseSSL3HandshakeLock(ss);
}
/* The callback to fire when the holddown timer for the Finished
@@ -902,10 +876,13 @@ dtls_CheckTimer(sslSocket *ss)
*
* Called from dtls_CheckTimer()
*/
-void
+static void
dtls_FinishedTimerCb(sslSocket *ss)
{
- ssl3_DestroyCipherSpec(ss->ssl3.pwSpec, PR_FALSE);
+ dtls_FreeHandshakeMessages(&ss->ssl3.hs.lastMessageFlight);
+ if (ss->version < SSL_LIBRARY_VERSION_TLS_1_3) {
+ ssl3_DestroyCipherSpec(ss->ssl3.pwSpec, PR_FALSE);
+ }
}
/* Cancel the Finished hold-down timer and destroy the
@@ -919,6 +896,11 @@ dtls_FinishedTimerCb(sslSocket *ss)
void
dtls_RehandshakeCleanup(sslSocket *ss)
{
+ /* Skip this if we are handling a second ClientHello. */
+ if (ss->ssl3.hs.helloRetry) {
+ return;
+ }
+ PORT_Assert((ss->version < SSL_LIBRARY_VERSION_TLS_1_3));
dtls_CancelTimer(ss);
ssl3_DestroyCipherSpec(ss->ssl3.pwSpec, PR_FALSE);
ss->ssl3.hs.sendMessageSeq = 0;
@@ -956,7 +938,7 @@ dtls_SetMTU(sslSocket *ss, PRUint16 advertised)
}
/* Fallback */
- ss->ssl3.mtu = COMMON_MTU_VALUES[PR_ARRAY_SIZE(COMMON_MTU_VALUES)-1];
+ ss->ssl3.mtu = COMMON_MTU_VALUES[PR_ARRAY_SIZE(COMMON_MTU_VALUES) - 1];
SSL_TRC(30, ("Resetting MTU to %d", ss->ssl3.mtu));
}
@@ -967,54 +949,58 @@ dtls_SetMTU(sslSocket *ss, PRUint16 advertised)
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;
+ int errCode = SSL_ERROR_RX_MALFORMED_HELLO_VERIFY_REQUEST;
+ SECStatus rv;
+ SSL3ProtocolVersion temp;
+ SSL3AlertDescription desc = illegal_parameter;
SSL_TRC(3, ("%d: SSL3[%d]: handle hello_verify_request handshake",
- SSL_GETPID(), ss->fd));
+ 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;
+ 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 &&
- temp != SSL_LIBRARY_VERSION_DTLS_1_2_WIRE) {
- goto alert_loser;
+ /* The version.
+ *
+ * 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 do anything to enforce a match, just
+ * read and check that this value is sane.
+ */
+ rv = ssl_ClientReadVersion(ss, &b, &length, &temp);
+ if (rv != SECSuccess) {
+ goto loser; /* alert has been sent */
}
- /* The cookie */
- rv = ssl3_ConsumeHandshakeVariable(ss, &cookie, 1, &b, &length);
+ /* Read the cookie.
+ * IMPORTANT: The value of ss->ssl3.hs.cookie is only valid while the
+ * HelloVerifyRequest message remains valid. */
+ rv = ssl3_ConsumeHandshakeVariable(ss, &ss->ssl3.hs.cookie, 1, &b, &length);
if (rv != SECSuccess) {
- goto loser; /* alert has been sent */
+ goto loser; /* alert has been sent */
}
- if (cookie.len > DTLS_COOKIE_BYTES) {
+ if (ss->ssl3.hs.cookie.len > DTLS_COOKIE_BYTES) {
desc = decode_error;
- goto alert_loser; /* malformed. */
+ goto alert_loser; /* malformed. */
}
- PORT_Memcpy(ss->ssl3.hs.cookie, cookie.data, cookie.len);
- ss->ssl3.hs.cookieLen = cookie.len;
-
-
- ssl_GetXmitBufLock(ss); /*******************************/
+ ssl_GetXmitBufLock(ss); /*******************************/
/* Now re-send the client hello */
- rv = ssl3_SendClientHello(ss, PR_TRUE);
+ rv = ssl3_SendClientHello(ss, client_hello_retransmit);
- ssl_ReleaseXmitBufLock(ss); /*******************************/
+ ssl_ReleaseXmitBufLock(ss); /*******************************/
if (rv == SECSuccess)
return rv;
@@ -1023,7 +1009,7 @@ alert_loser:
(void)SSL3_SendAlert(ss, alert_fatal, desc);
loser:
- errCode = ssl_MapLowLevelError(errCode);
+ ssl_MapLowLevelError(errCode);
return SECFailure;
}
@@ -1047,10 +1033,10 @@ dtls_InitRecvdRecords(DTLSRecvdRecords *records)
* 0 -- not received yet
* 1 -- replay
*
- * Called from: dtls_HandleRecord()
+ * Called from: ssl3_HandleRecord()
*/
int
-dtls_RecordGetRecvd(DTLSRecvdRecords *records, PRUint64 seq)
+dtls_RecordGetRecvd(const DTLSRecvdRecords *records, sslSequenceNumber seq)
{
PRUint64 offset;
@@ -1075,7 +1061,7 @@ dtls_RecordGetRecvd(DTLSRecvdRecords *records, PRUint64 seq)
* Called from ssl3_HandleRecord()
*/
void
-dtls_RecordSetRecvd(DTLSRecvdRecords *records, PRUint64 seq)
+dtls_RecordSetRecvd(DTLSRecvdRecords *records, sslSequenceNumber seq)
{
PRUint64 offset;
@@ -1083,9 +1069,9 @@ dtls_RecordSetRecvd(DTLSRecvdRecords *records, PRUint64 seq)
return;
if (seq > records->right) {
- PRUint64 new_left;
- PRUint64 new_right;
- PRUint64 right;
+ sslSequenceNumber new_left;
+ sslSequenceNumber new_right;
+ sslSequenceNumber right;
/* Slide to the right; this is the tricky part
*
@@ -1101,9 +1087,13 @@ dtls_RecordSetRecvd(DTLSRecvdRecords *records, PRUint64 seq)
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;
+ if (new_right > records->right + DTLS_RECVD_RECORDS_WINDOW) {
+ PORT_Memset(records->data, 0, sizeof(records->data));
+ } else {
+ 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;
@@ -1118,7 +1108,7 @@ dtls_RecordSetRecvd(DTLSRecvdRecords *records, PRUint64 seq)
SECStatus
DTLS_GetHandshakeTimeout(PRFileDesc *socket, PRIntervalTime *timeout)
{
- sslSocket * ss = NULL;
+ sslSocket *ss = NULL;
PRIntervalTime elapsed;
PRIntervalTime desired;
@@ -1144,3 +1134,81 @@ DTLS_GetHandshakeTimeout(PRFileDesc *socket, PRIntervalTime *timeout)
return SECSuccess;
}
+
+/*
+ * 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 the packet is not relevant, this function returns PR_FALSE.
+ * If the packet is relevant, this function returns PR_TRUE
+ * and sets |*seqNum| to the packet sequence number.
+ */
+PRBool
+dtls_IsRelevant(sslSocket *ss, const SSL3Ciphertext *cText,
+ PRBool *sameEpoch, PRUint64 *seqNum)
+{
+ const ssl3CipherSpec *crSpec = ss->ssl3.crSpec;
+ DTLSEpoch epoch;
+ sslSequenceNumber dtls_seq_num;
+
+ epoch = cText->seq_num >> 48;
+ *sameEpoch = crSpec->epoch == epoch;
+ if (!*sameEpoch) {
+ SSL_DBG(("%d: SSL3[%d]: dtls_IsRelevant, received packet "
+ "from irrelevant epoch %d",
+ SSL_GETPID(), ss->fd, epoch));
+ return PR_FALSE;
+ }
+
+ dtls_seq_num = cText->seq_num & RECORD_SEQ_MAX;
+ if (dtls_RecordGetRecvd(&crSpec->recvdRecords, dtls_seq_num) != 0) {
+ SSL_DBG(("%d: SSL3[%d]: dtls_IsRelevant, rejecting "
+ "potentially replayed packet",
+ SSL_GETPID(), ss->fd));
+ return PR_FALSE;
+ }
+
+ *seqNum = dtls_seq_num;
+ return PR_TRUE;
+}
+
+/* In TLS 1.3, a client that receives a retransmission of the server's first
+ * flight will reject that message and discard it (see dtls_IsRelevant() above).
+ * However, we need to trigger retransmission to prevent loss of the client's
+ * last flight from causing the connection to fail.
+ *
+ * This only triggers for a retransmitted ServerHello. Other (encrypted)
+ * handshake messages do not trigger retransmission, so we are a little more
+ * exposed to loss than is ideal.
+ *
+ * Note: This isn't an issue in earlier versions because the second-to-last
+ * flight (sent by the server) includes the Finished message, which is not
+ * dropped because it has the same epoch that the client currently expects.
+ */
+SECStatus
+dtls_MaybeRetransmitHandshake(sslSocket *ss, const SSL3Ciphertext *cText,
+ PRBool sameEpoch)
+{
+ SECStatus rv = SECSuccess;
+ DTLSEpoch messageEpoch = cText->seq_num >> 48;
+
+ /* Drop messages from other epochs if we are ignoring things. */
+ if (!sameEpoch && ss->ssl3.hs.zeroRttIgnore != ssl_0rtt_ignore_none) {
+ return SECSuccess;
+ }
+
+ if (!ss->sec.isServer && ss->version >= SSL_LIBRARY_VERSION_TLS_1_3 &&
+ messageEpoch == 0 && cText->type == content_handshake) {
+ ssl_GetSSL3HandshakeLock(ss);
+ if (ss->ssl3.hs.rtTimerCb == dtls_FinishedTimerCb &&
+ ss->ssl3.hs.ws == idle_handshake) {
+ rv = dtls_RetransmitDetected(ss);
+ }
+ ssl_ReleaseSSL3HandshakeLock(ss);
+ }
+ return rv;
+}
diff --git a/nss/lib/ssl/exports.gyp b/nss/lib/ssl/exports.gyp
new file mode 100644
index 0000000..e2123af
--- /dev/null
+++ b/nss/lib/ssl/exports.gyp
@@ -0,0 +1,29 @@
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+{
+ 'includes': [
+ '../../coreconf/config.gypi'
+ ],
+ 'targets': [
+ {
+ 'target_name': 'lib_ssl_exports',
+ 'type': 'none',
+ 'copies': [
+ {
+ 'files': [
+ 'preenc.h',
+ 'ssl.h',
+ 'sslerr.h',
+ 'sslproto.h',
+ 'sslt.h'
+ ],
+ 'destination': '<(nss_public_dist_dir)/<(module)'
+ }
+ ]
+ }
+ ],
+ 'variables': {
+ 'module': 'nss'
+ }
+}
diff --git a/nss/lib/ssl/manifest.mn b/nss/lib/ssl/manifest.mn
index 4d46d46..e7564ed 100644
--- a/nss/lib/ssl/manifest.mn
+++ b/nss/lib/ssl/manifest.mn
@@ -1,4 +1,4 @@
-#
+#
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
@@ -7,44 +7,48 @@ CORE_DEPTH = ../..
# DEFINES = -DTRACE
EXPORTS = \
- ssl.h \
- sslt.h \
- sslerr.h \
- sslproto.h \
- preenc.h \
- $(NULL)
+ 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)
+ dtlscon.c \
+ prelib.c \
+ ssl3con.c \
+ ssl3gthr.c \
+ sslauth.c \
+ sslcon.c \
+ ssldef.c \
+ sslenum.c \
+ sslerr.c \
+ sslerrstrs.c \
+ sslinit.c \
+ ssl3ext.c \
+ ssl3exthandle.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 \
+ tls13con.c \
+ tls13exthandle.c \
+ tls13hkdf.c \
+ sslcert.c \
+ sslgrp.c \
+ $(NULL)
LIBRARY_NAME = ssl
LIBRARY_VERSION = 3
diff --git a/nss/lib/ssl/notes.txt b/nss/lib/ssl/notes.txt
index a71c08e..7a8998a 100644
--- a/nss/lib/ssl/notes.txt
+++ b/nss/lib/ssl/notes.txt
@@ -10,49 +10,47 @@ 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->inbuf 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.
+gs->buf 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.msg_body 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.
+hs.msgState 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 = 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.
+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.
+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->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.
+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
+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.
---------------------------------------------------------------------------
@@ -65,70 +63,42 @@ 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:
+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
-SSL2: (in ssl2_GatherData)
- gs->* (locked by recvBufLock )
- sec->dec
- sec->readcx
- sec->hash* (ptr and data)
- sec->hashcx (ptr and data)
+crypto and hash data that must be protected while turning ciphertext into
+plaintext:
-SSL3: (in ssl3_HandleRecord )
- ssl3->current_read* (the pointer and all data refernced)
- ss->sec->isServer
+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)
+ss->saveBuf.* (which is dead)
in ssl3_sendPlainText
ss->ssl3->current_write-> (spec)
ss->sec->writeBuf.*
-ss->sec->isServer
+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".
+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
+cipherSuites[] ssl3con.c
diff --git a/nss/lib/ssl/os2_err.c b/nss/lib/ssl/os2_err.c
index a69ca91..6e3d423 100644
--- a/nss/lib/ssl/os2_err.c
+++ b/nss/lib/ssl/os2_err.c
@@ -1,12 +1,12 @@
/* -*- 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
+ * 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/. */
@@ -15,7 +15,6 @@
#include "prlog.h"
#include <errno.h>
-
/*
* Based on win32err.c
* OS2TODO Stub everything for now to build. HCT
@@ -24,79 +23,94 @@
/* forward declaration. */
void nss_MD_os2_map_default_error(PRInt32 err);
-void nss_MD_os2_map_opendir_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)
+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)
+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)
+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)
+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)
+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)
+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)
+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)
+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)
+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)
+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)
+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)
+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)
+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)
+void
+nss_MD_os2_map_fsync_error(PRInt32 err)
{
nss_MD_os2_map_default_error(err);
}
@@ -104,177 +118,213 @@ void nss_MD_os2_map_fsync_error(PRInt32 err)
/*
* For both CloseHandle() and closesocket().
*/
-void nss_MD_os2_map_close_error(PRInt32 err)
+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)
+void
+nss_MD_os2_map_socket_error(PRInt32 err)
{
-// PR_ASSERT(err != WSANOTINITIALISED);
+ // PR_ASSERT(err != WSANOTINITIALISED);
nss_MD_os2_map_default_error(err);
}
-void nss_MD_os2_map_recv_error(PRInt32 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)
+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)
+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;
+ // 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)
+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;
+ // 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)
+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;
+ // 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)
+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)
+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;
+ // 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)
+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;
+ // 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)
+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;
+ // 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)
+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)
+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;
+ // 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)
+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)
+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)
+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)
+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)
+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.
+** context, WSAENOTSOCK is equivalent to EBADF on Unix.
*/
-void nss_MD_os2_map_select_error(PRInt32 err)
+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;
+ // 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)
+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)
+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 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_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;
+// 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;
+// case ERROR_FILE_NOT_FOUND: prError = PR_FILE_NOT_FOUND_ERROR; break;
#endif
- default: prError = PR_UNKNOWN_ERROR; break;
+ default:
+ prError = PR_UNKNOWN_ERROR;
+ break;
}
PR_SetError(prError, err);
}
-
diff --git a/nss/lib/ssl/os2_err.h b/nss/lib/ssl/os2_err.h
index 3052d54..15e4741 100644
--- a/nss/lib/ssl/os2_err.h
+++ b/nss/lib/ssl/os2_err.h
@@ -1,11 +1,11 @@
/*
* This file essentially replicates NSPR's source for the functions that
- * map system-specific error codes to NSPR error codes. We would use
+ * 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/. */
diff --git a/nss/lib/ssl/preenc.h b/nss/lib/ssl/preenc.h
index af2475d..bebff89 100644
--- a/nss/lib/ssl/preenc.h
+++ b/nss/lib/ssl/preenc.h
@@ -25,89 +25,89 @@ 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];
+ 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];
+ 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];
+ 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];
+ 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 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)])
+#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];
+ unsigned char magic[2];
+ unsigned char len[2];
+ unsigned char type[2];
+ unsigned char version[2];
union {
- PEFortezzaHeader fortezza;
+ PEFortezzaHeader fortezza;
PEFortezzaGeneratedHeader g_fortezza;
- PEFixedKeyHeader fixed;
- PERSAKeyHeader rsa;
+ 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 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
+#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);
+ int *headerSize);
PEHeader *SSL_PreencryptedFileToStream(PRFileDesc *fd, PEHeader *,
- int *headerSize);
-
+ int *headerSize);
diff --git a/nss/lib/ssl/prelib.c b/nss/lib/ssl/prelib.c
index a15174a..4db9ffe 100644
--- a/nss/lib/ssl/prelib.c
+++ b/nss/lib/ssl/prelib.c
@@ -17,18 +17,18 @@
#include "preenc.h"
#include "pk11func.h"
-PEHeader *SSL_PreencryptedStreamToFile(PRFileDesc *fd, PEHeader *inHeader,
- int *headerSize)
+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)
+PEHeader *
+SSL_PreencryptedFileToStream(PRFileDesc *fd, PEHeader *header,
+ int *headerSize)
{
PORT_SetError(PR_NOT_IMPLEMENTED_ERROR);
return NULL;
}
-
-
diff --git a/nss/lib/ssl/ssl.def b/nss/lib/ssl/ssl.def
index 44db4e5..6aa8b64 100644
--- a/nss/lib/ssl/ssl.def
+++ b/nss/lib/ssl/ssl.def
@@ -5,7 +5,7 @@
;+#
;+# 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
+;+# 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.
@@ -187,3 +187,37 @@ SSL_SignatureMaxCount;
;+ local:
;+*;
;+};
+;+NSS_3.22 { # NSS 3.22 release
+;+ global:
+SSL_PeerSignedCertTimestamps;
+SSL_SetSignedCertTimestamps;
+;+ local:
+;+*;
+;+};
+;+NSS_3.23 { # NSS 3.23 release
+;+ global:
+SSL_SetDowngradeCheckVersion;
+;+ local:
+;+*;
+;+};
+;+NSS_3.24 { # NSS 3.24 release
+;+ global:
+SSL_ConfigServerCert;
+;+ local:
+;+*;
+;+};
+;+NSS_3.27 { # NSS 3.27 release
+;+ global:
+SSL_NamedGroupConfig;
+;+ local:
+;+*;
+;+};
+;+NSS_3.28 { # NSS 3.28 release
+;+ global:
+SSL_ExportEarlyKeyingMaterial;
+SSL_SendAdditionalKeyShares;
+SSL_SignatureSchemePrefSet;
+SSL_SignatureSchemePrefGet;
+;+ local:
+;+*;
+;+};
diff --git a/nss/lib/ssl/ssl.gyp b/nss/lib/ssl/ssl.gyp
new file mode 100644
index 0000000..0306ab6
--- /dev/null
+++ b/nss/lib/ssl/ssl.gyp
@@ -0,0 +1,98 @@
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+{
+ 'includes': [
+ '../../coreconf/config.gypi'
+ ],
+ 'targets': [
+ {
+ 'target_name': 'ssl',
+ 'type': 'static_library',
+ 'sources': [
+ 'authcert.c',
+ 'cmpcert.c',
+ 'dtlscon.c',
+ 'prelib.c',
+ 'ssl3con.c',
+ 'ssl3ecc.c',
+ 'ssl3ext.c',
+ 'ssl3exthandle.c',
+ 'ssl3gthr.c',
+ 'sslauth.c',
+ 'sslcert.c',
+ 'sslcon.c',
+ 'ssldef.c',
+ 'sslenum.c',
+ 'sslerr.c',
+ 'sslerrstrs.c',
+ 'sslgrp.c',
+ 'sslinfo.c',
+ 'sslinit.c',
+ 'sslmutex.c',
+ 'sslnonce.c',
+ 'sslreveal.c',
+ 'sslsecur.c',
+ 'sslsnce.c',
+ 'sslsock.c',
+ 'ssltrace.c',
+ 'sslver.c',
+ 'tls13con.c',
+ 'tls13exthandle.c',
+ 'tls13hkdf.c',
+ ],
+ 'conditions': [
+ [ 'OS=="win"', {
+ 'sources': [
+ 'win32err.c',
+ ],
+ 'defines': [
+ 'IN_LIBSSL',
+ ],
+ }, {
+ # Not Windows.
+ 'sources': [
+ 'unix_err.c'
+ ],
+ }],
+ [ 'ssl_enable_zlib==1', {
+ 'dependencies': [
+ '<(DEPTH)/lib/zlib/zlib.gyp:nss_zlib'
+ ],
+ 'defines': [
+ 'NSS_SSL_ENABLE_ZLIB',
+ ],
+ }],
+ [ 'fuzz==1', {
+ 'defines': [
+ 'UNSAFE_FUZZER_MODE',
+ ],
+ }],
+ ],
+ 'dependencies': [
+ '<(DEPTH)/exports.gyp:nss_exports',
+ '<(DEPTH)/lib/freebl/freebl.gyp:freebl',
+ ],
+ },
+ {
+ 'target_name': 'ssl3',
+ 'type': 'shared_library',
+ 'dependencies': [
+ 'ssl',
+ '<(DEPTH)/lib/nss/nss.gyp:nss3',
+ '<(DEPTH)/lib/util/util.gyp:nssutil3',
+ ],
+ 'variables': {
+ 'mapfile': 'ssl.def'
+ }
+ }
+ ],
+ 'target_defaults': {
+ 'defines': [
+ 'NSS_ALLOW_SSLKEYLOGFILE=1'
+ ]
+ },
+ 'variables': {
+ 'module': 'nss'
+ }
+}
diff --git a/nss/lib/ssl/ssl.h b/nss/lib/ssl/ssl.h
index 2a52769..b4af0e1 100644
--- a/nss/lib/ssl/ssl.h
+++ b/nss/lib/ssl/ssl.h
@@ -15,7 +15,7 @@
#include "cert.h"
#include "keyt.h"
-#include "sslt.h" /* public ssl data types */
+#include "sslt.h" /* public ssl data types */
#if defined(_WIN32) && !defined(IN_LIBSSL) && !defined(NSS_USE_STATIC_LIBS)
#define SSL_IMPORT extern __declspec(dllimport)
@@ -25,7 +25,7 @@
SEC_BEGIN_PROTOS
-/* constant table enumerating all implemented SSL 2 and 3 cipher suites. */
+/* constant table enumerating all implemented cipher suites. */
SSL_IMPORT const PRUint16 SSL_ImplementedCiphers[];
/* the same as the above, but is a function */
@@ -38,7 +38,7 @@ SSL_IMPORT const PRUint16 SSL_NumImplementedCiphers;
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)
+#define SSL_IS_SSL2_CIPHER(which) (((which)&0xfff0) == 0xff00)
/*
** Imports fd into SSL, returning a new socket. Copies SSL configuration
@@ -55,72 +55,69 @@ 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_SECURITY:
+** enable/disable use of SSL security protocol before connect
**
-** SSL_SOCKS:
-** enable/disable use of socks before connect
-** (No longer supported).
+** SSL_SOCKS:
+** enable/disable use of socks before connect
+** (No longer supported).
**
-** SSL_REQUEST_CERTIFICATE:
-** require a certificate during secure connect
+** 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) */
+#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) */
+#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_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) */
+#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) */
+#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 */
+#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 /* (unsupported, deprecated, off) */
+#define SSL_BYPASS_PKCS11 16 /* (unsupported, deprecated, off) */
+#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
@@ -160,7 +157,7 @@ SSL_IMPORT PRFileDesc *DTLS_ImportFD(PRFileDesc *model, PRFileDesc *fd);
* accept fragmented alerts).
*/
#define SSL_CBC_RANDOM_IV 23
-#define SSL_ENABLE_OCSP_STAPLING 24 /* Request OCSP stapling (client) */
+#define SSL_ENABLE_OCSP_STAPLING 24 /* Request OCSP stapling (client) */
/* SSL_ENABLE_NPN controls whether the NPN extension is enabled for the initial
* handshake when application layer protocol negotiation is used.
@@ -189,8 +186,8 @@ SSL_IMPORT PRFileDesc *DTLS_ImportFD(PRFileDesc *model, PRFileDesc *fd);
*/
#define SSL_REUSE_SERVER_ECDHE_KEY 27
-#define SSL_ENABLE_FALLBACK_SCSV 28 /* Send fallback SCSV in
- * handshakes. */
+#define SSL_ENABLE_FALLBACK_SCSV 28 /* Send fallback SCSV in \
+ * handshakes. */
/* SSL_ENABLE_SERVER_DHE controls whether DHE is enabled for the server socket.
*/
@@ -203,8 +200,46 @@ SSL_IMPORT PRFileDesc *DTLS_ImportFD(PRFileDesc *model, PRFileDesc *fd);
*/
#define SSL_ENABLE_EXTENDED_MASTER_SECRET 30
+/* Request Signed Certificate Timestamps via TLS extension (client) */
+#define SSL_ENABLE_SIGNED_CERT_TIMESTAMPS 31
-#ifdef SSL_DEPRECATED_FUNCTION
+/* Ordinarily, when negotiating a TLS_DHE_* cipher suite the server picks the
+ * group. draft-ietf-tls-negotiated-ff-dhe changes this to use supported_groups
+ * (formerly supported_curves) to signal which pre-defined groups are OK.
+ *
+ * This option causes an NSS client to use this extension and demand that those
+ * groups be used. A client will signal any enabled DHE groups in the
+ * supported_groups extension and reject groups that don't match what it has
+ * enabled. A server will only negotiate TLS_DHE_* cipher suites if the
+ * client includes the extension.
+ *
+ * See SSL_NamedGroupConfig() for how to control which groups are enabled.
+ *
+ * This option cannot be enabled if NSS is not compiled with ECC support.
+ */
+#define SSL_REQUIRE_DH_NAMED_GROUPS 32
+
+/* Allow 0-RTT data (for TLS 1.3).
+ *
+ * When this option is set, the server's session tickets will contain
+ * a flag indicating that it accepts 0-RTT. When resuming such a
+ * session, PR_Write() on the client will be allowed immediately after
+ * starting the handshake and PR_Read() on the server will be allowed
+ * on the server to read that data. Calls to
+ * SSL_GetPreliminaryChannelInfo() and SSL_GetNextProto()
+ * can be made used during this period to learn about the channel
+ * parameters [TODO(ekr@rtfm.com): This hasn't landed yet].
+ *
+ * The transition between the 0-RTT and 1-RTT modes is marked by the
+ * handshake callback.
+ *
+ * WARNING: 0-RTT data has different anti-replay and PFS properties than
+ * the rest of the TLS data. See [draft-ietf-tls-tls13; Section 6.2.3]
+ * for more details.
+ */
+#define SSL_ENABLE_0RTT_DATA 33
+
+#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);
@@ -227,13 +262,13 @@ SSL_IMPORT SECStatus SSL_CertDBHandleSet(PRFileDesc *fd, CERTCertDBHandle *dbHan
*
* The callback must return SECFailure or SECSuccess (not SECWouldBlock).
*/
-typedef SECStatus (PR_CALLBACK *SSLNextProtoCallback)(
+typedef SECStatus(PR_CALLBACK *SSLNextProtoCallback)(
void *arg,
PRFileDesc *fd,
- const unsigned char* protos,
+ const unsigned char *protos,
unsigned int protosLen,
- unsigned char* protoOut,
- unsigned int* protoOutLen,
+ unsigned char *protoOut,
+ unsigned int *protoOutLen,
unsigned int protoMaxOut);
/* SSL_SetNextProtoCallback sets a callback function to handle Next Protocol
@@ -261,14 +296,15 @@ SSL_IMPORT SECStatus SSL_SetNextProtoCallback(PRFileDesc *fd,
* 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 */
- SSL_NEXT_PROTO_SELECTED = 3 /* Server selected proto (ALPN) */
+ 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 */
+ SSL_NEXT_PROTO_SELECTED = 3, /* Server selected proto (ALPN) */
+ SSL_NEXT_PROTO_EARLY_VALUE = 4 /* We are in 0-RTT using this value. */
} SSLNextProtoState;
/* SSL_GetNextProto can be used in the HandshakeCallback or any time after
@@ -279,19 +315,19 @@ typedef enum SSLNextProtoState {
* 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);
+ 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.
+** 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
+#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);
@@ -306,46 +342,87 @@ SSL_IMPORT SECStatus SSL_CipherPolicySet(PRInt32 cipher, PRInt32 policy);
SSL_IMPORT SECStatus SSL_CipherPolicyGet(PRInt32 cipher, PRInt32 *policy);
/*
-** Control for TLS signature algorithms for TLS 1.2 only.
+** Control for TLS signature schemes for TLS 1.2 and 1.3.
**
-** This governs what signature algorithms are sent by a client in the
-** signature_algorithms extension. A client will not accept a signature from a
-** server unless it uses an enabled algorithm.
+** This governs what signature schemes (or algorithms) are sent by a client in
+** the signature_algorithms extension. A client will not accept a signature
+** from a server unless it uses an enabled algorithm.
**
** This also governs what the server sends in the supported_signature_algorithms
-** field of a CertificateRequest. It also changes what the server uses to sign
-** ServerKeyExchange: a server uses the first entry from this list that is
-** compatible with the client's advertised signature_algorithms extension and
-** the selected server certificate.
+** field of a CertificateRequest.
+**
+** This changes what the server uses to sign ServerKeyExchange and
+** CertificateVerify messages. An endpoint uses the first entry from this list
+** that is compatible with both its certificate and its peer's supported
+** values.
+**
+** NSS uses the strict signature schemes from TLS 1.3 in TLS 1.2. That means
+** that if a peer indicates support for SHA-384 and ECDSA, NSS will not
+** generate a signature if it has a P-256 key, even though that is permitted in
+** TLS 1.2.
**
-** Omitting SHA-256 from this list might be foolish. Support is mandatory in
-** TLS 1.2 and there might be interoperability issues. For a server, NSS only
-** supports SHA-256 for verifying a TLS 1.2 CertificateVerify. This list needs
-** to include SHA-256 if client authentication is requested or required, or
-** creating a CertificateRequest will fail.
+** Omitting SHA-256 schemes from this list might be foolish. Support is
+** mandatory in TLS 1.2 and 1.3 and there might be interoperability issues.
*/
+SSL_IMPORT SECStatus SSL_SignatureSchemePrefSet(
+ PRFileDesc *fd, const SSLSignatureScheme *schemes, unsigned int count);
+
+/* Deprecated, use SSL_SignatureSchemePrefSet() instead. */
SSL_IMPORT SECStatus SSL_SignaturePrefSet(
PRFileDesc *fd, const SSLSignatureAndHashAlg *algorithms,
unsigned int count);
/*
-** Get the currently configured signature algorithms.
+** Get the currently configured signature schemes.
**
-** The algorithms are written to |algorithms| but not if there are more than
-** |maxCount| values configured. The number of algorithms that are in use are
+** The schemes are written to |schemes| but not if there are more than
+** |maxCount| values configured. The number of schemes that are in use are
** written to |count|. This fails if |maxCount| is insufficiently large.
*/
+SSL_IMPORT SECStatus SSL_SignatureSchemePrefGet(
+ PRFileDesc *fd, SSLSignatureScheme *algorithms, unsigned int *count,
+ unsigned int maxCount);
+
+/* Deprecated, use SSL_SignatureSchemePrefGet() instead. */
SSL_IMPORT SECStatus SSL_SignaturePrefGet(
PRFileDesc *fd, SSLSignatureAndHashAlg *algorithms, unsigned int *count,
unsigned int maxCount);
/*
** Returns the maximum number of signature algorithms that are supported and
-** can be set or retrieved using SSL_SignaturePrefSet or SSL_SignaturePrefGet.
+** can be set or retrieved using SSL_SignatureSchemePrefSet or
+** SSL_SignatureSchemePrefGet.
*/
SSL_IMPORT unsigned int SSL_SignatureMaxCount();
-/* SSL_DHEGroupPrefSet is used to configure the set of allowed/enabled DHE group
+/*
+** Define custom priorities for EC and FF groups used in DH key exchange and EC
+** groups for ECDSA. This only changes the order of enabled lists (and thus
+** their priorities) and enables all groups in |groups| while disabling all other
+** groups.
+*/
+SSL_IMPORT SECStatus SSL_NamedGroupConfig(PRFileDesc *fd,
+ const SSLNamedGroup *groups,
+ unsigned int num_groups);
+
+/*
+** Configure the socket to configure additional key shares. Normally when a TLS
+** 1.3 ClientHello is sent, just one key share is included using the first
+** preference group (as set by SSL_NamedGroupConfig). If the server decides to
+** pick a different group for key exchange, it is forced to send a
+** HelloRetryRequest, which adds an entire round trip of latency.
+**
+** This function can be used to configure libssl to generate additional key
+** shares when sending a TLS 1.3 ClientHello. If |count| is set to a non-zero
+** value, then additional key shares are generated. Shares are added in the
+** preference order set in SSL_NamedGroupConfig. |count| can be set to any
+** value; NSS limits the number of shares to the number of supported groups.
+*/
+SSL_IMPORT SECStatus SSL_SendAdditionalKeyShares(PRFileDesc *fd,
+ unsigned int count);
+
+/* Deprecated: use SSL_NamedGroupConfig() instead.
+** SSL_DHEGroupPrefSet is used to configure the set of allowed/enabled DHE group
** parameters that can be used by NSS for the given server socket.
** The first item in the array is used as the default group, if no other
** selection criteria can be used by NSS.
@@ -354,7 +431,7 @@ SSL_IMPORT unsigned int SSL_SignatureMaxCount();
** For example, a TLS extension sent by the client might indicate a preference.
*/
SSL_IMPORT SECStatus SSL_DHEGroupPrefSet(PRFileDesc *fd,
- SSLDHEGroupType *groups,
+ const SSLDHEGroupType *groups,
PRUint16 num_groups);
/* Enable the use of a DHE group that's smaller than the library default,
@@ -375,13 +452,11 @@ SSL_IMPORT SECStatus SSL_DHEGroupPrefSet(PRFileDesc *fd,
** on sockets. The function needs to be called again for every socket that
** should use the weak group.
**
-** It is allowed to use this API in combination with the SSL_DHEGroupPrefSet API.
-** If both APIs have been called, the weakest group will be used,
-** unless it is certain that the client supports larger group parameters.
-** The weak group will be used as the default group, overriding the preference
-** for the first group potentially set with a call to SSL_DHEGroupPrefSet
-** (The first group set using SSL_DHEGroupPrefSet will still be enabled, but
-** it's no longer the default group.)
+** It is allowed to use this API in combination with the SSL_NamedGroupConfig API.
+** If both APIs have been called, the weakest group will be used, unless it is
+** certain that the client supports larger group parameters. The weak group will
+** be used as the default group for TLS <= 1.2, overriding the preference for
+** the first group potentially set with a call to SSL_NamedGroupConfig.
*/
SSL_IMPORT SECStatus SSL_EnableWeakDHEPrimeGroup(PRFileDesc *fd, PRBool enabled);
@@ -449,34 +524,46 @@ SSL_IMPORT SECStatus SSL_VersionRangeSetDefault(
/* Returns, in |*vrange|, the range of enabled SSL3/TLS versions for |fd|. */
SSL_IMPORT SECStatus SSL_VersionRangeGet(PRFileDesc *fd,
- SSLVersionRange *vrange);
+ SSLVersionRange *vrange);
/* Sets the range of enabled SSL3/TLS versions for |fd| to |*vrange|. */
SSL_IMPORT SECStatus SSL_VersionRangeSet(PRFileDesc *fd,
- const SSLVersionRange *vrange);
-
+ const SSLVersionRange *vrange);
+
+/* Sets the version to check the server random against for the
+ * fallback check defined in [draft-ietf-tls-tls13-11 Section 6.3.1.1].
+ * This function is provided to allow for detection of forced downgrade
+ * attacks against client-side reconnect-and-fallback outside of TLS
+ * by setting |version| to be that of the original connection, rather
+ * than that of the new connection.
+ *
+ * The default, which can also be enabled by setting |version| to
+ * zero, is just to check against the max version in the
+ * version range (see SSL_VersionRangeSet). */
+SSL_IMPORT SECStatus SSL_SetDowngradeCheckVersion(PRFileDesc *fd,
+ PRUint16 version);
/* Values for "policy" argument to SSL_CipherPolicySet */
/* 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. */
+#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_NEVER ((PRBool)0)
+#define SSL_REQUIRE_ALWAYS ((PRBool)1)
#define SSL_REQUIRE_FIRST_HANDSHAKE ((PRBool)2)
-#define SSL_REQUIRE_NO_ERROR ((PRBool)3)
+#define SSL_REQUIRE_NO_ERROR ((PRBool)3)
/* Values for "on" with SSL_ENABLE_RENEGOTIATION */
/* Never renegotiate at all. */
-#define SSL_RENEGOTIATE_NEVER ((PRBool)0)
+#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)
+#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 */
@@ -514,22 +601,22 @@ SSL_IMPORT SECStatus SSL_ForceHandshakeWithTimeout(PRFileDesc *fd,
** 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);
+ 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 */
+#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
+** "fd" the socket "file" descriptor
*/
SSL_IMPORT CERTCertificate *SSL_PeerCertificate(PRFileDesc *fd);
@@ -538,7 +625,7 @@ SSL_IMPORT CERTCertificate *SSL_PeerCertificate(PRFileDesc *fd);
** did not present certificates, return NULL with the
** SSL_ERROR_NO_CERTIFICATE error. On failure, return NULL with an error
** code other than SSL_ERROR_NO_CERTIFICATE.
-** "fd" the socket "file" descriptor
+** "fd" the socket "file" descriptor
*/
SSL_IMPORT CERTCertList *SSL_PeerCertificateChain(PRFileDesc *fd);
@@ -558,17 +645,50 @@ SSL_IMPORT CERTCertList *SSL_PeerCertificateChain(PRFileDesc *fd);
* 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_IMPORT const SECItemArray *SSL_PeerStapledOCSPResponses(PRFileDesc *fd);
+
+/* SSL_PeerSignedCertTimestamps returns the signed_certificate_timestamp
+ * extension data provided by the TLS server. The return value is a pointer
+ * to an internal SECItem that contains the returned response (as a serialized
+ * SignedCertificateTimestampList, see RFC 6962). The returned pointer is only
+ * valid until the callback function that calls SSL_PeerSignedCertTimestamps
+ * (e.g. the authenticate certificate hook, or the handshake callback) returns.
+ *
+ * If no Signed Certificate Timestamps 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_SIGNED_CERT_TIMESTAMPS option to indicate support
+ * for Signed Certificate Timestamps to a server.
+ *
+ * libssl does not do any parsing or validation of the response itself.
+ */
+SSL_IMPORT const SECItem *SSL_PeerSignedCertTimestamps(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. Parameter |responses| is for the server certificate of
* the key exchange type |kea|.
* The function will duplicate the responses array.
+ *
+ * Deprecated: see SSL_ConfigSecureServer for details.
*/
SSL_IMPORT SECStatus
SSL_SetStapledOCSPResponses(PRFileDesc *fd, const SECItemArray *responses,
- SSLKEAType kea);
+ SSLKEAType kea);
+
+/*
+ * SSL_SetSignedCertTimestamps stores serialized signed_certificate_timestamp
+ * extension data in the fd. The signed_certificate_timestamp data is sent
+ * during the handshake (if requested by the client). Parameter |scts|
+ * is for the server certificate of the key exchange type |kea|.
+ * The function will duplicate the provided data item. To clear previously
+ * set data for a given key exchange type |kea|, pass NULL to |scts|.
+ *
+ * Deprecated: see SSL_ConfigSecureServer for details.
+ */
+SSL_IMPORT SECStatus
+SSL_SetSignedCertTimestamps(PRFileDesc *fd, const SECItem *scts,
+ SSLKEAType kea);
/*
** Authenticate certificate hook. Called when a certificate comes in
@@ -601,41 +721,40 @@ SSL_SetStapledOCSPResponses(PRFileDesc *fd, const SECItemArray *responses,
** 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);
+typedef SECStatus(PR_CALLBACK *SSLAuthCertificate)(void *arg, PRFileDesc *fd,
+ PRBool checkSig,
+ PRBool isServer);
-SSL_IMPORT SECStatus SSL_AuthCertificateHook(PRFileDesc *fd,
- SSLAuthCertificate f,
- void *arg);
+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);
+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
+ * 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 */
+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
+ * 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);
-
+SSL_IMPORT SECStatus SSL_GetClientAuthDataHook(PRFileDesc *fd,
+ SSLGetClientAuthData f, void *a);
/*
** SNI extension processing callback function.
@@ -663,10 +782,10 @@ SSL_IMPORT SECStatus SSL_GetClientAuthDataHook(PRFileDesc *fd,
** 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);
+typedef PRInt32(PR_CALLBACK *SSLSNISocketConfig)(PRFileDesc *fd,
+ const SECItem *srvNameArr,
+ PRUint32 srvNameArrSize,
+ void *arg);
/*
** SSLSNISocketConfig should return an index within 0 and srvNameArrSize-1
@@ -675,13 +794,13 @@ typedef PRInt32 (PR_CALLBACK *SSLSNISocketConfig)(PRFileDesc *fd,
** 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
+#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,
+SSL_IMPORT SECStatus SSL_SNISocketConfigHook(PRFileDesc *fd,
SSLSNISocketConfig f,
void *arg);
@@ -694,8 +813,8 @@ 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
+ * fd - the file descriptor for the connection in question
+ * a - pkcs11 application specific data
*/
SSL_IMPORT SECStatus SSL_SetPKCS11PinArg(PRFileDesc *fd, void *a);
@@ -714,22 +833,80 @@ SSL_IMPORT SECStatus SSL_SetPKCS11PinArg(PRFileDesc *fd, void *a);
** 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);
+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.
+**
+** This method should be used in preference to SSL_ConfigSecureServer,
+** SSL_ConfigSecureServerWithCertChain, SSL_SetStapledOCSPResponses, and
+** SSL_SetSignedCertTimestamps.
+**
+** The authentication method is determined from the certificate and private key
+** based on how libssl authenticates peers. Primarily, this uses the value of
+** the SSLAuthType enum and is derived from the type of public key in the
+** certificate. For example, different RSA certificates might be saved for
+** signing (ssl_auth_rsa_sign) and key encipherment
+** (ssl_auth_rsa_decrypt). Unique to RSA, the same certificate can be used for
+** both usages. Additional information about the authentication method is also
+** used: EC keys with different curves are separately stored.
+**
+** Only one certificate is stored for each authentication method.
+**
+** The optional |data| argument contains additional information about the
+** certificate:
+**
+** - |authType| (with a value other than ssl_auth_null) limits the
+** authentication method; this is primarily useful in limiting the use of an
+** RSA certificate to one particular key usage (either signing or key
+** encipherment) when its key usages indicate support for both.
+**
+** - |certChain| provides an explicit certificate chain, rather than relying on
+** NSS functions for finding a certificate chain.
+**
+** - |stapledOCSPResponses| provides a response for OCSP stapling.
+**
+** - |signedCertTimestamps| provides a value for the
+** signed_certificate_timestamp extension used in certificate transparency.
+**
+** The |data_len| argument provides the length of the data. This should be set
+** to |sizeof(data)|.
+**
+** This function allows an application to provide certificates with narrow key
+** usages attached to them. For instance, RSA keys can be provided that are
+** limited to signing or decryption only. Multiple EC certificates with keys on
+** different named curves can be provided.
+**
+** Unlike SSL_ConfigSecureServer(WithCertChain), this function does not accept
+** NULL for the |cert| and |key| arguments. It will replace certificates that
+** have the same type, but it cannot be used to remove certificates that have
+** already been configured.
+*/
+SSL_IMPORT SECStatus SSL_ConfigServerCert(
+ PRFileDesc *fd, CERTCertificate *cert, SECKEYPrivateKey *key,
+ const SSLExtraServerCertData *data, unsigned int data_len);
+
+/*
+** Deprecated variant of SSL_ConfigServerCert.
+**
+** This uses values from the SSLKEAType to identify the type of |key| that the
+** |cert| contains. This is incorrect, since key exchange and authentication
+** are separated in some cipher suites (in particular, ECDHE_RSA_* suites).
+**
+** Providing a |kea| parameter of ssl_kea_ecdh (or kt_ecdh) is interpreted as
+** providing both ECDH and ECDSA certificates.
*/
SSL_IMPORT SECStatus SSL_ConfigSecureServer(
- PRFileDesc *fd, CERTCertificate *cert,
- SECKEYPrivateKey *key, SSLKEAType kea);
+ 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.
+** Deprecated variant of SSL_ConfigSecureServerCert. The |data| argument to
+** SSL_ConfigSecureServerCert can be used to pass a certificate chain.
*/
SSL_IMPORT SECStatus
SSL_ConfigSecureServerWithCertChain(PRFileDesc *fd, CERTCertificate *cert,
@@ -739,63 +916,63 @@ SSL_ConfigSecureServerWithCertChain(PRFileDesc *fd, CERTCertificate *cert,
/*
** 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
+** 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
+** 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);
+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);
+ 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
+** 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
+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
+** 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 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"
+#define SSL_ENV_VAR_NAME "SSL_INHERITANCE"
-/* called in child to inherit SID Cache variables.
+/* 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
+ * variable "SSL_INHERITANCE", otherwise the string value passed in will be
* used.
*/
-SSL_IMPORT SECStatus SSL_InheritMPServerSIDCache(const char * envString);
+SSL_IMPORT SECStatus SSL_InheritMPServerSIDCache(const char *envString);
/*
** Set the callback that gets called when a TLS handshake is complete. The
@@ -807,10 +984,10 @@ SSL_IMPORT SECStatus SSL_InheritMPServerSIDCache(const char * envString);
** before the handshake callback is called. If we did not false start then the
** callback will get called before any application data is sent.
*/
-typedef void (PR_CALLBACK *SSLHandshakeCallback)(PRFileDesc *fd,
- void *client_data);
-SSL_IMPORT SECStatus SSL_HandshakeCallback(PRFileDesc *fd,
- SSLHandshakeCallback cb, void *client_data);
+typedef void(PR_CALLBACK *SSLHandshakeCallback)(PRFileDesc *fd,
+ void *client_data);
+SSL_IMPORT SECStatus SSL_HandshakeCallback(PRFileDesc *fd,
+ SSLHandshakeCallback cb, void *client_data);
/* Applications that wish to enable TLS false start must set this callback
** function. NSS will invoke the functon to determine if a particular
@@ -823,7 +1000,7 @@ SSL_IMPORT SECStatus SSL_HandshakeCallback(PRFileDesc *fd,
** If no false start callback is registered then false start will never be
** done, even if the SSL_ENABLE_FALSE_START option is enabled.
**/
-typedef SECStatus (PR_CALLBACK *SSLCanFalseStartCallback)(
+typedef SECStatus(PR_CALLBACK *SSLCanFalseStartCallback)(
PRFileDesc *fd, void *arg, PRBool *canFalseStart);
SSL_IMPORT SECStatus SSL_SetCanFalseStartCallback(
@@ -839,10 +1016,10 @@ SSL_IMPORT SECStatus SSL_RecommendedCanFalseStart(PRFileDesc *fd,
/*
** 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
+** 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
+** 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);
@@ -854,12 +1031,11 @@ SSL_IMPORT SECStatus SSL_ReHandshakeWithTimeout(PRFileDesc *fd,
PRBool flushCache,
PRIntervalTime timeout);
-
-#ifdef SSL_DEPRECATED_FUNCTION
+#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.
+** 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);
@@ -909,11 +1085,11 @@ SSL_IMPORT SECStatus SSL_ShutdownServerSessionIDCache(void);
SSL_IMPORT SECStatus SSL_SetSockPeerID(PRFileDesc *fd, const char *peerID);
/*
-** Reveal the security information for the peer.
+** 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);
+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.
@@ -921,14 +1097,14 @@ SSL_IMPORT char * SSL_RevealURL(PRFileDesc * socket);
* (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
+ * 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,
+NSS_GetClientAuthData(void *arg,
+ PRFileDesc *socket,
+ struct CERTDistNamesStr *caNames,
+ struct CERTCertificateStr **pRetCert,
struct SECKEYPrivateKeyStr **pRetKey);
/*
@@ -942,8 +1118,8 @@ NSS_GetClientAuthData(void * arg,
** Otherwise returns SECFailure.
*/
SSL_IMPORT SECStatus SSL_SetSRTPCiphers(PRFileDesc *fd,
- const PRUint16 *ciphers,
- unsigned int numCiphers);
+ const PRUint16 *ciphers,
+ unsigned int numCiphers);
/*
** Get the selected DTLS-SRTP cipher suite (if any).
@@ -951,21 +1127,22 @@ SSL_IMPORT SECStatus SSL_SetSRTPCiphers(PRFileDesc *fd,
** Returns SECFailure if not negotiated.
*/
SSL_IMPORT SECStatus SSL_GetSRTPCipher(PRFileDesc *fd,
- PRUint16 *cipher);
+ PRUint16 *cipher);
/*
* Look to see if any of the signers in the cert chain for "cert" are found
- * in the list of caNames.
+ * 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);
+SSL_IMPORT SECStatus NSS_CmpCertChainWCANames(CERTCertificate *cert,
+ CERTDistNames *caNames);
-/*
+/* Deprecated. This reports a misleading value for certificates that might
+ * be used for signing rather than key exchange.
* Returns key exchange type of the keys in an SSL server certificate.
*/
-SSL_IMPORT SSLKEAType NSS_FindCertKEAType(CERTCertificate * cert);
+SSL_IMPORT SSLKEAType NSS_FindCertKEAType(CERTCertificate *cert);
/* Set cipher policies to a predefined Domestic (U.S.A.) policy.
* This essentially allows all supported ciphers.
@@ -979,16 +1156,18 @@ SSL_IMPORT SECStatus NSS_SetDomesticPolicy(void);
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
+ * according to present U.S. policies as we understand them, and that the
* nation of France will permit to be imported into their country.
* It is the same as NSS_SetDomesticPolicy now.
*/
SSL_IMPORT SECStatus NSS_SetFrancePolicy(void);
-SSL_IMPORT SSL3Statistics * SSL_GetStatistics(void);
+SSL_IMPORT SSL3Statistics *SSL_GetStatistics(void);
/* Report more information than SSL_SecurityStatus.
- * Caller supplies the info struct. This function fills it in.
+ * Caller supplies the info struct. This function fills it in. Caller should
+ * pass sizeof(SSLChannelInfo) as the |len| argument.
+ *
* The information here will be zeroed prior to details being confirmed. The
* details are confirmed either when a Finished message is received, or - for a
* client - when the second flight of messages have been sent. This function
@@ -998,6 +1177,9 @@ SSL_IMPORT SSL3Statistics * SSL_GetStatistics(void);
SSL_IMPORT SECStatus SSL_GetChannelInfo(PRFileDesc *fd, SSLChannelInfo *info,
PRUintn len);
/* Get preliminary information about a channel.
+ * Caller supplies the info struct. This function fills it in. Caller should
+ * pass sizeof(SSLPreliminaryChannelInfo) as the |len| argument.
+ *
* This function can be called prior to handshake details being confirmed (see
* SSL_GetChannelInfo above for what that means). Thus, information provided by
* this function is available to SSLAuthCertificate, SSLGetClientAuthData,
@@ -1009,8 +1191,12 @@ SSL_IMPORT SECStatus
SSL_GetPreliminaryChannelInfo(PRFileDesc *fd,
SSLPreliminaryChannelInfo *info,
PRUintn len);
-SSL_IMPORT SECStatus SSL_GetCipherSuiteInfo(PRUint16 cipherSuite,
- SSLCipherSuiteInfo *info, PRUintn len);
+/* Get information about cipher suite with id of |cipherSuite|.
+ * Caller supplies the info struct. This function fills it in. Caller should
+ * pass sizeof(SSLCipherSuiteInfo) as the |len| argument.
+ */
+SSL_IMPORT SECStatus SSL_GetCipherSuiteInfo(PRUint16 cipherSuite,
+ SSLCipherSuiteInfo *info, PRUintn len);
/* Returnes negotiated through SNI host info. */
SSL_IMPORT SECItem *SSL_GetNegotiatedHostInfo(PRFileDesc *fd);
@@ -1030,48 +1216,38 @@ SSL_IMPORT SECStatus SSL_ExportKeyingMaterial(PRFileDesc *fd,
unsigned char *out,
unsigned int outLen);
+/* Early exporters are used if 0-RTT is enabled. This is TLS 1.3 only. Note
+ * that in TLS 1.3, an empty context is equivalent to an absent context. */
+SSL_IMPORT SECStatus SSL_ExportEarlyKeyingMaterial(PRFileDesc *fd,
+ const char *label,
+ unsigned int labelLen,
+ 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.
-**/
+SSL_IMPORT CERTCertificate *SSL_LocalCertificate(PRFileDesc *fd);
-/* protocol mask bits */
-#define SSL_CBP_SSL3 0x0001 /* test SSL v3 mechanisms */
-#define SSL_CBP_TLS1_0 0x0002 /* test TLS v1.0 mechanisms */
+#define SSL_CBP_SSL3 0x0001 /* (deprecated) */
+#define SSL_CBP_TLS1_0 0x0002 /* (deprecated) */
+/* DEPRECATED: The PKCS#11 bypass has been removed.
+** This function will now always return false. */
SSL_IMPORT SECStatus SSL_CanBypass(CERTCertificate *cert,
SECKEYPrivateKey *privKey,
- PRUint32 protocolmask,
- PRUint16 *ciphers, int nciphers,
+ 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,
+SSL_IMPORT SECStatus SSL_HandshakeNegotiatedExtension(PRFileDesc *socket,
SSLExtensionType extId,
PRBool *yes);
@@ -1161,7 +1337,7 @@ extern const char *NSSSSL_GetVersion(void);
* connection.
*/
SSL_IMPORT SECStatus SSL_AuthCertificateComplete(PRFileDesc *fd,
- PRErrorCode error);
+ PRErrorCode error);
SEC_END_PROTOS
#endif /* __ssl_h_ */
diff --git a/nss/lib/ssl/ssl3con.c b/nss/lib/ssl/ssl3con.c
index 8f1c547..154d22a 100644
--- a/nss/lib/ssl/ssl3con.c
+++ b/nss/lib/ssl/ssl3con.c
@@ -10,7 +10,7 @@
#include "cert.h"
#include "ssl.h"
-#include "cryptohi.h" /* for DSAU_ stuff */
+#include "cryptohi.h" /* for DSAU_ stuff */
#include "keyhi.h"
#include "secder.h"
#include "secitem.h"
@@ -19,6 +19,8 @@
#include "sslimpl.h"
#include "sslproto.h"
#include "sslerr.h"
+#include "ssl3ext.h"
+#include "ssl3exthandle.h"
#include "prtime.h"
#include "prinrval.h"
#include "prerror.h"
@@ -29,59 +31,54 @@
#include "pk11func.h"
#include "secmod.h"
-#ifndef NO_PKCS11_BYPASS
#include "blapi.h"
-#endif
#include <stdio.h>
-#ifdef NSS_ENABLE_ZLIB
+#ifdef NSS_SSL_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);
+#define PK11_SETATTRS(x, id, v, l) \
+ (x)->type = (id); \
+ (x)->pValue = (v); \
+ (x)->ulValueLen = (l);
#endif
-static SECStatus ssl3_AuthCertificate(sslSocket *ss);
-static void ssl3_CleanupPeerCerts(sslSocket *ss);
static PK11SymKey *ssl3_GenerateRSAPMS(sslSocket *ss, ssl3CipherSpec *spec,
- PK11SlotInfo * serverKeySlot);
+ 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_DeriveConnectionKeys(sslSocket *ss);
+static SECStatus ssl3_HandshakeFailure(sslSocket *ss);
+static SECStatus ssl3_SendCertificate(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_UpdateHandshakeHashes( sslSocket *ss,
- const unsigned char *b,
- unsigned int l);
-static SECStatus ssl3_ComputeHandshakeHashes(sslSocket *ss,
- ssl3CipherSpec *spec,
- SSL3Hashes *hashes,
- PRUint32 sender);
+static SECStatus ssl3_SendNextProto(sslSocket *ss);
+static SECStatus ssl3_SendFinished(sslSocket *ss, PRInt32 flags);
+static SECStatus ssl3_SendServerHelloDone(sslSocket *ss);
+static SECStatus ssl3_SendServerKeyExchange(sslSocket *ss);
+static SECStatus ssl3_HandleClientHelloPart2(sslSocket *ss,
+ SECItem *suites,
+ SECItem *comps,
+ sslSessionID *sid);
+static SECStatus ssl3_HandleServerHelloPart2(sslSocket *ss,
+ const SECItem *sidBytes,
+ int *retErrCode);
+static SECStatus ssl3_HandlePostHelloHandshakeMessage(sslSocket *ss,
+ SSL3Opaque *b,
+ PRUint32 length,
+ SSL3Hashes *hashesPtr);
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);
-#ifndef NO_PKCS11_BYPASS
-static SECStatus ssl3_AESGCMBypass(ssl3KeyMaterial *keys, PRBool doDecrypt,
- unsigned char *out, int *outlen, int maxout,
- const unsigned char *in, int inlen,
- const unsigned char *additionalData,
- int additionalDataLen);
-#endif
+ int maxOutputLen, const unsigned char *input,
+ int inputLen);
+
+static CK_MECHANISM_TYPE ssl3_GetHashMechanismByHashType(SSLHashType hashType);
+static CK_MECHANISM_TYPE ssl3_GetMgfMechanismByHashType(SSLHashType hash);
+PRBool ssl_IsRsaPssSignatureScheme(SSLSignatureScheme scheme);
#define MAX_SEND_BUF_LENGTH 32000 /* watch for 16-bit integer overflow */
-#define MIN_SEND_BUF_LENGTH 4000
+#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.
@@ -91,12 +88,20 @@ static SECStatus ssl3_AESGCMBypass(ssl3KeyMaterial *keys, PRBool doDecrypt,
* Important: See bug 946147 before enabling, reordering, or adding any cipher
* suites to this list.
*/
+/* clang-format off */
static ssl3CipherSuiteCfg cipherSuites[ssl_V3_SUITES_IMPLEMENTED] = {
/* cipher_suite policy enabled isPresent */
+ /* Special TLS 1.3 suites. */
+ { TLS_AES_128_GCM_SHA256, SSL_ALLOWED, PR_TRUE, PR_FALSE },
+ { TLS_CHACHA20_POLY1305_SHA256, SSL_ALLOWED, PR_TRUE, PR_FALSE },
+ { TLS_AES_256_GCM_SHA384, SSL_ALLOWED, PR_TRUE, PR_FALSE },
-#ifndef NSS_DISABLE_ECC
{ TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, SSL_ALLOWED, PR_TRUE, PR_FALSE},
{ TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, SSL_ALLOWED, PR_TRUE, PR_FALSE},
+ { TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256, SSL_ALLOWED, PR_TRUE, PR_FALSE},
+ { TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256, SSL_ALLOWED, PR_TRUE, PR_FALSE},
+ { TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384, SSL_ALLOWED, PR_FALSE, PR_FALSE},
+ { TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384, SSL_ALLOWED, PR_FALSE, PR_FALSE},
/* TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA is out of order to work around
* bug 946147.
*/
@@ -106,14 +111,18 @@ static ssl3CipherSuiteCfg cipherSuites[ssl_V3_SUITES_IMPLEMENTED] = {
{ TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256, SSL_ALLOWED, PR_TRUE, PR_FALSE},
{ TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256, SSL_ALLOWED, PR_TRUE, PR_FALSE},
{ TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA, SSL_ALLOWED, PR_TRUE, PR_FALSE},
+ { TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384, SSL_ALLOWED, PR_FALSE, PR_FALSE},
+ { TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384, SSL_ALLOWED, PR_FALSE, PR_FALSE},
{ TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA, SSL_ALLOWED, PR_FALSE, PR_FALSE},
{ TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA, SSL_ALLOWED, PR_FALSE, PR_FALSE},
{ TLS_ECDHE_ECDSA_WITH_RC4_128_SHA, SSL_ALLOWED, PR_FALSE, PR_FALSE},
{ TLS_ECDHE_RSA_WITH_RC4_128_SHA, SSL_ALLOWED, PR_FALSE, PR_FALSE},
-#endif /* NSS_DISABLE_ECC */
{ TLS_DHE_RSA_WITH_AES_128_GCM_SHA256, SSL_ALLOWED, PR_TRUE, PR_FALSE},
+ { TLS_DHE_RSA_WITH_CHACHA20_POLY1305_SHA256,SSL_ALLOWED,PR_TRUE, PR_FALSE},
{ TLS_DHE_DSS_WITH_AES_128_GCM_SHA256, SSL_ALLOWED, PR_FALSE, PR_FALSE},
+ { TLS_DHE_RSA_WITH_AES_256_GCM_SHA384, SSL_ALLOWED, PR_FALSE, PR_FALSE},
+ { TLS_DHE_DSS_WITH_AES_256_GCM_SHA384, SSL_ALLOWED, PR_FALSE, PR_FALSE},
{ TLS_DHE_RSA_WITH_AES_128_CBC_SHA, SSL_ALLOWED, PR_TRUE, PR_FALSE},
{ TLS_DHE_DSS_WITH_AES_128_CBC_SHA, SSL_ALLOWED, PR_TRUE, PR_FALSE},
{ TLS_DHE_RSA_WITH_AES_128_CBC_SHA256, SSL_ALLOWED, PR_TRUE, PR_FALSE},
@@ -130,7 +139,6 @@ static ssl3CipherSuiteCfg cipherSuites[ssl_V3_SUITES_IMPLEMENTED] = {
{ TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA, SSL_ALLOWED, PR_TRUE, PR_FALSE},
{ TLS_DHE_DSS_WITH_RC4_128_SHA, SSL_ALLOWED, PR_FALSE, PR_FALSE},
-#ifndef NSS_DISABLE_ECC
{ TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA, SSL_ALLOWED, PR_FALSE, PR_FALSE},
{ TLS_ECDH_RSA_WITH_AES_128_CBC_SHA, SSL_ALLOWED, PR_FALSE, PR_FALSE},
{ TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA, SSL_ALLOWED, PR_FALSE, PR_FALSE},
@@ -139,10 +147,10 @@ static ssl3CipherSuiteCfg cipherSuites[ssl_V3_SUITES_IMPLEMENTED] = {
{ TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA, SSL_ALLOWED, PR_FALSE, PR_FALSE},
{ TLS_ECDH_ECDSA_WITH_RC4_128_SHA, SSL_ALLOWED, PR_FALSE, PR_FALSE},
{ TLS_ECDH_RSA_WITH_RC4_128_SHA, SSL_ALLOWED, PR_FALSE, PR_FALSE},
-#endif /* NSS_DISABLE_ECC */
/* RSA */
{ TLS_RSA_WITH_AES_128_GCM_SHA256, SSL_ALLOWED, PR_TRUE, PR_FALSE},
+ { TLS_RSA_WITH_AES_256_GCM_SHA384, SSL_ALLOWED, PR_FALSE, PR_FALSE},
{ TLS_RSA_WITH_AES_128_CBC_SHA, SSL_ALLOWED, PR_TRUE, PR_FALSE},
{ TLS_RSA_WITH_AES_128_CBC_SHA256, SSL_ALLOWED, PR_TRUE, PR_FALSE},
{ TLS_RSA_WITH_CAMELLIA_128_CBC_SHA, SSL_ALLOWED, PR_FALSE, PR_FALSE},
@@ -150,7 +158,6 @@ static ssl3CipherSuiteCfg cipherSuites[ssl_V3_SUITES_IMPLEMENTED] = {
{ TLS_RSA_WITH_AES_256_CBC_SHA256, SSL_ALLOWED, PR_TRUE, PR_FALSE},
{ TLS_RSA_WITH_CAMELLIA_256_CBC_SHA, SSL_ALLOWED, PR_FALSE, PR_FALSE},
{ TLS_RSA_WITH_SEED_CBC_SHA, SSL_ALLOWED, PR_FALSE, PR_FALSE},
- { SSL_RSA_FIPS_WITH_3DES_EDE_CBC_SHA, SSL_ALLOWED, PR_FALSE, PR_FALSE},
{ TLS_RSA_WITH_3DES_EDE_CBC_SHA, SSL_ALLOWED, PR_TRUE, PR_FALSE},
{ TLS_RSA_WITH_RC4_128_SHA, SSL_ALLOWED, PR_TRUE, PR_FALSE},
{ TLS_RSA_WITH_RC4_128_MD5, SSL_ALLOWED, PR_TRUE, PR_FALSE},
@@ -158,57 +165,55 @@ static ssl3CipherSuiteCfg cipherSuites[ssl_V3_SUITES_IMPLEMENTED] = {
/* 56-bit DES "domestic" cipher suites */
{ TLS_DHE_RSA_WITH_DES_CBC_SHA, SSL_ALLOWED, PR_FALSE, PR_FALSE},
{ TLS_DHE_DSS_WITH_DES_CBC_SHA, SSL_ALLOWED, PR_FALSE, PR_FALSE},
- { SSL_RSA_FIPS_WITH_DES_CBC_SHA, SSL_ALLOWED, PR_FALSE, PR_FALSE},
{ TLS_RSA_WITH_DES_CBC_SHA, SSL_ALLOWED, PR_FALSE, PR_FALSE},
- /* export ciphersuites with 1024-bit public key exchange keys */
- { TLS_RSA_EXPORT1024_WITH_RC4_56_SHA, SSL_ALLOWED, PR_FALSE, PR_FALSE},
- { TLS_RSA_EXPORT1024_WITH_DES_CBC_SHA, SSL_ALLOWED, PR_FALSE, PR_FALSE},
-
- /* export ciphersuites with 512-bit public key exchange keys */
- { TLS_RSA_EXPORT_WITH_RC4_40_MD5, SSL_ALLOWED, PR_FALSE, PR_FALSE},
- { TLS_RSA_EXPORT_WITH_RC2_CBC_40_MD5, SSL_ALLOWED, PR_FALSE, PR_FALSE},
-
/* ciphersuites with no encryption */
-#ifndef NSS_DISABLE_ECC
{ TLS_ECDHE_ECDSA_WITH_NULL_SHA, SSL_ALLOWED, PR_FALSE, PR_FALSE},
{ TLS_ECDHE_RSA_WITH_NULL_SHA, SSL_ALLOWED, PR_FALSE, PR_FALSE},
{ TLS_ECDH_RSA_WITH_NULL_SHA, SSL_ALLOWED, PR_FALSE, PR_FALSE},
{ TLS_ECDH_ECDSA_WITH_NULL_SHA, SSL_ALLOWED, PR_FALSE, PR_FALSE},
-#endif /* NSS_DISABLE_ECC */
{ TLS_RSA_WITH_NULL_SHA, SSL_ALLOWED, PR_FALSE, PR_FALSE},
{ TLS_RSA_WITH_NULL_SHA256, SSL_ALLOWED, PR_FALSE, PR_FALSE},
{ TLS_RSA_WITH_NULL_MD5, SSL_ALLOWED, PR_FALSE, PR_FALSE},
};
-
-static const SSLSignatureAndHashAlg defaultSignatureAlgorithms[] = {
- {ssl_hash_sha256, ssl_sign_rsa},
- {ssl_hash_sha384, ssl_sign_rsa},
- {ssl_hash_sha512, ssl_sign_rsa},
- {ssl_hash_sha1, ssl_sign_rsa},
-#ifndef NSS_DISABLE_ECC
- {ssl_hash_sha256, ssl_sign_ecdsa},
- {ssl_hash_sha384, ssl_sign_ecdsa},
- {ssl_hash_sha512, ssl_sign_ecdsa},
- {ssl_hash_sha1, ssl_sign_ecdsa},
-#endif
- {ssl_hash_sha256, ssl_sign_dsa},
- {ssl_hash_sha1, ssl_sign_dsa}
+/* clang-format on */
+
+/* This is the default supported set of signature schemes. The order of the
+ * hashes here is all that is important, since that will (sometimes) determine
+ * which hash we use. The key pair (i.e., cert) is the primary thing that
+ * determines what we use and this doesn't affect how we select key pairs. The
+ * order of signature types is based on the same rules for ordering we use for
+ * cipher suites just for consistency.
+ */
+static const SSLSignatureScheme defaultSignatureSchemes[] = {
+ ssl_sig_ecdsa_secp256r1_sha256,
+ ssl_sig_ecdsa_secp384r1_sha384,
+ ssl_sig_ecdsa_secp521r1_sha512,
+ ssl_sig_ecdsa_sha1,
+ ssl_sig_rsa_pss_sha256,
+ ssl_sig_rsa_pss_sha384,
+ ssl_sig_rsa_pss_sha512,
+ ssl_sig_rsa_pkcs1_sha256,
+ ssl_sig_rsa_pkcs1_sha384,
+ ssl_sig_rsa_pkcs1_sha512,
+ ssl_sig_rsa_pkcs1_sha1,
+ ssl_sig_dsa_sha256,
+ ssl_sig_dsa_sha384,
+ ssl_sig_dsa_sha512,
+ ssl_sig_dsa_sha1
};
-PR_STATIC_ASSERT(PR_ARRAY_SIZE(defaultSignatureAlgorithms) <=
- MAX_SIGNATURE_ALGORITHMS);
+PR_STATIC_ASSERT(PR_ARRAY_SIZE(defaultSignatureSchemes) <=
+ MAX_SIGNATURE_SCHEMES);
/* Verify that SSL_ImplementedCiphers and cipherSuites are in consistent order.
*/
#ifdef DEBUG
-void ssl3_CheckCipherSuiteOrderConsistency()
+void
+ssl3_CheckCipherSuiteOrderConsistency()
{
unsigned int i;
- /* Note that SSL_ImplementedCiphers has more elements than cipherSuites
- * because it SSL_ImplementedCiphers includes SSL 2.0 cipher suites.
- */
- PORT_Assert(SSL_NumImplementedCiphers >= PR_ARRAY_SIZE(cipherSuites));
+ PORT_Assert(SSL_NumImplementedCiphers == PR_ARRAY_SIZE(cipherSuites));
for (i = 0; i < PR_ARRAY_SIZE(cipherSuites); ++i) {
PORT_Assert(SSL_ImplementedCiphers[i] == cipherSuites[i].cipher_suite);
@@ -220,363 +225,391 @@ void ssl3_CheckCipherSuiteOrderConsistency()
* precedence (desirability). It only includes compression methods we
* implement.
*/
-static const /*SSLCompressionMethod*/ PRUint8 compressions [] = {
-#ifdef NSS_ENABLE_ZLIB
+static const SSLCompressionMethod ssl_compression_methods[] = {
+#ifdef NSS_SSL_ENABLE_ZLIB
ssl_compression_deflate,
#endif
ssl_compression_null
};
-static const int compressionMethodsCount =
- sizeof(compressions) / sizeof(compressions[0]);
+static const unsigned int ssl_compression_method_count =
+ PR_ARRAY_SIZE(ssl_compression_methods);
/* compressionEnabled returns true iff the compression algorithm is enabled
* for the given SSL socket. */
static PRBool
-compressionEnabled(sslSocket *ss, SSLCompressionMethod compression)
+ssl_CompressionEnabled(sslSocket *ss, SSLCompressionMethod compression)
{
- switch (compression) {
- case ssl_compression_null:
- return PR_TRUE; /* Always enabled */
-#ifdef NSS_ENABLE_ZLIB
- case ssl_compression_deflate:
- if (ss->version < SSL_LIBRARY_VERSION_TLS_1_3) {
- return ss->opt.enableDeflate;
- }
+ SSL3ProtocolVersion version;
+
+ if (compression == ssl_compression_null) {
+ return PR_TRUE; /* Always enabled */
+ }
+ if (ss->sec.isServer) {
+ /* We can't easily check that the client didn't attempt TLS 1.3,
+ * so this will have to do. */
+ PORT_Assert(ss->version < SSL_LIBRARY_VERSION_TLS_1_3);
+ version = ss->version;
+ } else {
+ version = ss->vrange.max;
+ }
+ if (version >= SSL_LIBRARY_VERSION_TLS_1_3) {
return PR_FALSE;
-#endif
- default:
- return PR_FALSE;
}
+#ifdef NSS_SSL_ENABLE_ZLIB
+ if (compression == ssl_compression_deflate) {
+ if (IS_DTLS(ss)) {
+ return PR_FALSE;
+ }
+ return ss->opt.enableDeflate;
+ }
+#endif
+ return PR_FALSE;
}
-static const /*SSL3ClientCertificateType */ PRUint8 certificate_types [] = {
+static const /*SSL3ClientCertificateType */ PRUint8 certificate_types[] = {
ct_RSA_sign,
-#ifndef NSS_DISABLE_ECC
ct_ECDSA_sign,
-#endif /* NSS_DISABLE_ECC */
ct_DSS_sign,
};
-#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 */
+/* Record protection algorithms, indexed by SSL3BulkCipher.
+ *
+ * The |max_records| field (|mr| below) is set to a number that is higher than
+ * recommended in some literature (esp. TLS 1.3) because we currently abort the
+ * connection when this limit is reached and we want to ensure that we only
+ * rarely hit this limit. See bug 1268745 for details.
+ */
+#define MR_MAX RECORD_SEQ_MAX /* 2^48-1 */
+#define MR_128 (0x5aULL << 28) /* For AES and similar. */
+#define MR_LOW (1ULL << 20) /* For weak ciphers. */
+/* clang-format off */
static const ssl3BulkCipherDef bulk_cipher_defs[] = {
- /* |--------- Lengths --------| */
- /* cipher calg k s type i b t n */
- /* e e v l a o */
- /* y c | o g n */
- /* | r | c | c */
- /* | e | k | e */
- /* | t | | | | */
- {cipher_null, calg_null, 0, 0, type_stream, 0, 0, 0, 0},
- {cipher_rc4, calg_rc4, 16,16, type_stream, 0, 0, 0, 0},
- {cipher_rc4_40, calg_rc4, 16, 5, type_stream, 0, 0, 0, 0},
- {cipher_rc4_56, calg_rc4, 16, 7, type_stream, 0, 0, 0, 0},
- {cipher_rc2, calg_rc2, 16,16, type_block, 8, 8, 0, 0},
- {cipher_rc2_40, calg_rc2, 16, 5, type_block, 8, 8, 0, 0},
- {cipher_des, calg_des, 8, 8, type_block, 8, 8, 0, 0},
- {cipher_3des, calg_3des, 24,24, type_block, 8, 8, 0, 0},
- {cipher_des40, calg_des, 8, 5, type_block, 8, 8, 0, 0},
- {cipher_idea, calg_idea, 16,16, type_block, 8, 8, 0, 0},
- {cipher_aes_128, calg_aes, 16,16, type_block, 16,16, 0, 0},
- {cipher_aes_256, calg_aes, 32,32, type_block, 16,16, 0, 0},
- {cipher_camellia_128, calg_camellia, 16,16, type_block, 16,16, 0, 0},
- {cipher_camellia_256, calg_camellia, 32,32, type_block, 16,16, 0, 0},
- {cipher_seed, calg_seed, 16,16, type_block, 16,16, 0, 0},
- {cipher_aes_128_gcm, calg_aes_gcm, 16,16, type_aead, 4, 0,16, 8},
- {cipher_missing, calg_null, 0, 0, type_stream, 0, 0, 0, 0},
+ /* |--------- Lengths ---------| */
+ /* cipher calg : s : */
+ /* : e b n */
+ /* oid short_name mr : l o */
+ /* k r o t n */
+ /* e e i c a c */
+ /* y t type v k g e */
+ {cipher_null, calg_null, 0, 0, type_stream, 0, 0, 0, 0,
+ SEC_OID_NULL_CIPHER, "NULL", MR_MAX},
+ {cipher_rc4, calg_rc4, 16,16, type_stream, 0, 0, 0, 0,
+ SEC_OID_RC4, "RC4", MR_LOW},
+ {cipher_des, calg_des, 8, 8, type_block, 8, 8, 0, 0,
+ SEC_OID_DES_CBC, "DES-CBC", MR_LOW},
+ {cipher_3des, calg_3des, 24,24, type_block, 8, 8, 0, 0,
+ SEC_OID_DES_EDE3_CBC, "3DES-EDE-CBC", MR_LOW},
+ {cipher_aes_128, calg_aes, 16,16, type_block, 16,16, 0, 0,
+ SEC_OID_AES_128_CBC, "AES-128", MR_128},
+ {cipher_aes_256, calg_aes, 32,32, type_block, 16,16, 0, 0,
+ SEC_OID_AES_256_CBC, "AES-256", MR_128},
+ {cipher_camellia_128, calg_camellia, 16,16, type_block, 16,16, 0, 0,
+ SEC_OID_CAMELLIA_128_CBC, "Camellia-128", MR_128},
+ {cipher_camellia_256, calg_camellia, 32,32, type_block, 16,16, 0, 0,
+ SEC_OID_CAMELLIA_256_CBC, "Camellia-256", MR_128},
+ {cipher_seed, calg_seed, 16,16, type_block, 16,16, 0, 0,
+ SEC_OID_SEED_CBC, "SEED-CBC", MR_128},
+ {cipher_aes_128_gcm, calg_aes_gcm, 16,16, type_aead, 4, 0,16, 8,
+ SEC_OID_AES_128_GCM, "AES-128-GCM", MR_128},
+ {cipher_aes_256_gcm, calg_aes_gcm, 32,32, type_aead, 4, 0,16, 8,
+ SEC_OID_AES_256_GCM, "AES-256-GCM", MR_128},
+ {cipher_chacha20, calg_chacha20, 32,32, type_aead, 12, 0,16, 0,
+ SEC_OID_CHACHA20_POLY1305, "ChaCha20-Poly1305", MR_MAX},
+ {cipher_missing, calg_null, 0, 0, type_stream, 0, 0, 0, 0,
+ SEC_OID_UNKNOWN, "missing", 0U},
};
static const ssl3KEADef kea_defs[] =
{ /* indexed by SSL3KeyExchangeAlgorithm */
- /* kea exchKeyType signKeyType is_limited limit tls_keygen ephemeral */
- {kea_null, kt_null, sign_null, PR_FALSE, 0, PR_FALSE, PR_FALSE},
- {kea_rsa, kt_rsa, sign_rsa, PR_FALSE, 0, PR_FALSE, PR_FALSE},
- {kea_rsa_export, kt_rsa, sign_rsa, PR_TRUE, 512, PR_FALSE, PR_FALSE},
- {kea_rsa_export_1024,kt_rsa, sign_rsa, PR_TRUE, 1024, PR_FALSE, PR_FALSE},
- {kea_dh_dss, kt_dh, sign_dsa, PR_FALSE, 0, PR_FALSE, PR_FALSE},
- {kea_dh_dss_export, kt_dh, sign_dsa, PR_TRUE, 512, PR_FALSE, PR_FALSE},
- {kea_dh_rsa, kt_dh, sign_rsa, PR_FALSE, 0, PR_FALSE, PR_FALSE},
- {kea_dh_rsa_export, kt_dh, sign_rsa, PR_TRUE, 512, PR_FALSE, PR_FALSE},
- {kea_dhe_dss, kt_dh, sign_dsa, PR_FALSE, 0, PR_FALSE, PR_TRUE},
- {kea_dhe_dss_export, kt_dh, sign_dsa, PR_TRUE, 512, PR_FALSE, PR_TRUE},
- {kea_dhe_rsa, kt_dh, sign_rsa, PR_FALSE, 0, PR_FALSE, PR_TRUE},
- {kea_dhe_rsa_export, kt_dh, sign_rsa, PR_TRUE, 512, PR_FALSE, PR_TRUE},
- {kea_dh_anon, kt_dh, sign_null, PR_FALSE, 0, PR_FALSE, PR_TRUE},
- {kea_dh_anon_export, kt_dh, sign_null, PR_TRUE, 512, PR_FALSE, PR_TRUE},
- {kea_rsa_fips, kt_rsa, sign_rsa, PR_FALSE, 0, PR_TRUE, PR_FALSE},
-#ifndef NSS_DISABLE_ECC
- {kea_ecdh_ecdsa, kt_ecdh, sign_ecdsa, PR_FALSE, 0, PR_FALSE, PR_FALSE},
- {kea_ecdhe_ecdsa, kt_ecdh, sign_ecdsa, PR_FALSE, 0, PR_FALSE, PR_TRUE},
- {kea_ecdh_rsa, kt_ecdh, sign_rsa, PR_FALSE, 0, PR_FALSE, PR_FALSE},
- {kea_ecdhe_rsa, kt_ecdh, sign_rsa, PR_FALSE, 0, PR_FALSE, PR_TRUE},
- {kea_ecdh_anon, kt_ecdh, sign_null, PR_FALSE, 0, PR_FALSE, PR_TRUE},
-#endif /* NSS_DISABLE_ECC */
+ /* kea exchKeyType signKeyType authKeyType ephemeral oid */
+ {kea_null, ssl_kea_null, nullKey, ssl_auth_null, PR_FALSE, 0},
+ {kea_rsa, ssl_kea_rsa, nullKey, ssl_auth_rsa_decrypt, PR_FALSE, SEC_OID_TLS_RSA},
+ {kea_dh_dss, ssl_kea_dh, dsaKey, ssl_auth_dsa, PR_FALSE, SEC_OID_TLS_DH_DSS},
+ {kea_dh_rsa, ssl_kea_dh, rsaKey, ssl_auth_rsa_sign, PR_FALSE, SEC_OID_TLS_DH_RSA},
+ {kea_dhe_dss, ssl_kea_dh, dsaKey, ssl_auth_dsa, PR_TRUE, SEC_OID_TLS_DHE_DSS},
+ {kea_dhe_rsa, ssl_kea_dh, rsaKey, ssl_auth_rsa_sign, PR_TRUE, SEC_OID_TLS_DHE_RSA},
+ {kea_dh_anon, ssl_kea_dh, nullKey, ssl_auth_null, PR_TRUE, SEC_OID_TLS_DH_ANON},
+ {kea_ecdh_ecdsa, ssl_kea_ecdh, nullKey, ssl_auth_ecdh_ecdsa, PR_FALSE, SEC_OID_TLS_ECDH_ECDSA},
+ {kea_ecdhe_ecdsa, ssl_kea_ecdh, ecKey, ssl_auth_ecdsa, PR_TRUE, SEC_OID_TLS_ECDHE_ECDSA},
+ {kea_ecdh_rsa, ssl_kea_ecdh, nullKey, ssl_auth_ecdh_rsa, PR_FALSE, SEC_OID_TLS_ECDH_RSA},
+ {kea_ecdhe_rsa, ssl_kea_ecdh, rsaKey, ssl_auth_rsa_sign, PR_TRUE, SEC_OID_TLS_ECDHE_RSA},
+ {kea_ecdh_anon, ssl_kea_ecdh, nullKey, ssl_auth_null, PR_TRUE, SEC_OID_TLS_ECDH_ANON},
+ {kea_ecdhe_psk, ssl_kea_ecdh_psk, nullKey, ssl_auth_psk, PR_TRUE, SEC_OID_TLS_ECDHE_PSK},
+ {kea_dhe_psk, ssl_kea_dh_psk, nullKey, ssl_auth_psk, PR_TRUE, SEC_OID_TLS_DHE_PSK},
+ {kea_tls13_any, ssl_kea_tls13_any, nullKey, ssl_auth_tls13_any, PR_TRUE, SEC_OID_TLS13_KEA_ANY},
};
/* must use ssl_LookupCipherSuiteDef to access */
-static const ssl3CipherSuiteDef cipher_suite_defs[] =
-{
-/* cipher_suite bulk_cipher_alg mac_alg key_exchange_alg */
-
- {TLS_NULL_WITH_NULL_NULL, cipher_null, mac_null, kea_null},
- {TLS_RSA_WITH_NULL_MD5, cipher_null, mac_md5, kea_rsa},
- {TLS_RSA_WITH_NULL_SHA, cipher_null, mac_sha, kea_rsa},
- {TLS_RSA_WITH_NULL_SHA256, cipher_null, hmac_sha256, kea_rsa},
- {TLS_RSA_EXPORT_WITH_RC4_40_MD5,cipher_rc4_40, mac_md5, kea_rsa_export},
- {TLS_RSA_WITH_RC4_128_MD5, cipher_rc4, mac_md5, kea_rsa},
- {TLS_RSA_WITH_RC4_128_SHA, cipher_rc4, mac_sha, kea_rsa},
- {TLS_RSA_EXPORT_WITH_RC2_CBC_40_MD5,
- cipher_rc2_40, mac_md5, kea_rsa_export},
-#if 0 /* not implemented */
- {TLS_RSA_WITH_IDEA_CBC_SHA, cipher_idea, mac_sha, kea_rsa},
- {TLS_RSA_EXPORT_WITH_DES40_CBC_SHA,
- cipher_des40, mac_sha, kea_rsa_export},
-#endif
- {TLS_RSA_WITH_DES_CBC_SHA, cipher_des, mac_sha, kea_rsa},
- {TLS_RSA_WITH_3DES_EDE_CBC_SHA, cipher_3des, mac_sha, kea_rsa},
- {TLS_DHE_DSS_WITH_DES_CBC_SHA, cipher_des, mac_sha, kea_dhe_dss},
+static const ssl3CipherSuiteDef cipher_suite_defs[] =
+{
+/* cipher_suite bulk_cipher_alg mac_alg key_exchange_alg prf_hash */
+/* Note that the prf_hash_alg is the hash function used by the PRF, see sslimpl.h. */
+
+ {TLS_NULL_WITH_NULL_NULL, cipher_null, mac_null, kea_null, ssl_hash_none},
+ {TLS_RSA_WITH_NULL_MD5, cipher_null, mac_md5, kea_rsa, ssl_hash_none},
+ {TLS_RSA_WITH_NULL_SHA, cipher_null, mac_sha, kea_rsa, ssl_hash_none},
+ {TLS_RSA_WITH_NULL_SHA256, cipher_null, hmac_sha256, kea_rsa, ssl_hash_sha256},
+ {TLS_RSA_WITH_RC4_128_MD5, cipher_rc4, mac_md5, kea_rsa, ssl_hash_none},
+ {TLS_RSA_WITH_RC4_128_SHA, cipher_rc4, mac_sha, kea_rsa, ssl_hash_none},
+ {TLS_RSA_WITH_DES_CBC_SHA, cipher_des, mac_sha, kea_rsa, ssl_hash_none},
+ {TLS_RSA_WITH_3DES_EDE_CBC_SHA, cipher_3des, mac_sha, kea_rsa, ssl_hash_none},
+ {TLS_DHE_DSS_WITH_DES_CBC_SHA, cipher_des, mac_sha, kea_dhe_dss, ssl_hash_none},
{TLS_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 */
- {TLS_DH_DSS_EXPORT_WITH_DES40_CBC_SHA,
- cipher_des40, mac_sha, kea_dh_dss_export},
- {TLS_DH_DSS_DES_CBC_SHA, cipher_des, mac_sha, kea_dh_dss},
- {TLS_DH_DSS_3DES_CBC_SHA, cipher_3des, mac_sha, kea_dh_dss},
- {TLS_DH_RSA_EXPORT_WITH_DES40_CBC_SHA,
- cipher_des40, mac_sha, kea_dh_rsa_export},
- {TLS_DH_RSA_DES_CBC_SHA, cipher_des, mac_sha, kea_dh_rsa},
- {TLS_DH_RSA_3DES_CBC_SHA, cipher_3des, mac_sha, kea_dh_rsa},
- {TLS_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA,
- cipher_des40, mac_sha, kea_dh_dss_export},
- {TLS_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA,
- cipher_des40, mac_sha, kea_dh_rsa_export},
-#endif
- {TLS_DHE_RSA_WITH_DES_CBC_SHA, cipher_des, mac_sha, kea_dhe_rsa},
+ cipher_3des, mac_sha, kea_dhe_dss, ssl_hash_none},
+ {TLS_DHE_DSS_WITH_RC4_128_SHA, cipher_rc4, mac_sha, kea_dhe_dss, ssl_hash_none},
+ {TLS_DHE_RSA_WITH_DES_CBC_SHA, cipher_des, mac_sha, kea_dhe_rsa, ssl_hash_none},
{TLS_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},
- {TLS_DH_anon_EXPORT_WITH_DES40_CBC_SHA,
- cipher_des40, mac_sha, kea_dh_anon_export},
- {TLS_DH_anon_WITH_DES_CBC_SHA, cipher_des, mac_sha, kea_dh_anon},
- {TLS_DH_anon_WITH_3DES_CBC_SHA, cipher_3des, mac_sha, kea_dh_anon},
-#endif
+ cipher_3des, mac_sha, kea_dhe_rsa, ssl_hash_none},
/* New TLS cipher suites */
- {TLS_RSA_WITH_AES_128_CBC_SHA, cipher_aes_128, mac_sha, kea_rsa},
- {TLS_RSA_WITH_AES_128_CBC_SHA256, cipher_aes_128, hmac_sha256, 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_DHE_RSA_WITH_AES_128_CBC_SHA256, cipher_aes_128, hmac_sha256, kea_dhe_rsa},
- {TLS_RSA_WITH_AES_256_CBC_SHA, cipher_aes_256, mac_sha, kea_rsa},
- {TLS_RSA_WITH_AES_256_CBC_SHA256, cipher_aes_256, hmac_sha256, 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},
- {TLS_DHE_RSA_WITH_AES_256_CBC_SHA256, cipher_aes_256, hmac_sha256, 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_RSA_WITH_AES_128_CBC_SHA, cipher_aes_128, mac_sha, kea_rsa, ssl_hash_none},
+ {TLS_RSA_WITH_AES_128_CBC_SHA256, cipher_aes_128, hmac_sha256, kea_rsa, ssl_hash_sha256},
+ {TLS_DHE_DSS_WITH_AES_128_CBC_SHA, cipher_aes_128, mac_sha, kea_dhe_dss, ssl_hash_none},
+ {TLS_DHE_RSA_WITH_AES_128_CBC_SHA, cipher_aes_128, mac_sha, kea_dhe_rsa, ssl_hash_none},
+ {TLS_DHE_RSA_WITH_AES_128_CBC_SHA256, cipher_aes_128, hmac_sha256, kea_dhe_rsa, ssl_hash_sha256},
+ {TLS_RSA_WITH_AES_256_CBC_SHA, cipher_aes_256, mac_sha, kea_rsa, ssl_hash_none},
+ {TLS_RSA_WITH_AES_256_CBC_SHA256, cipher_aes_256, hmac_sha256, kea_rsa, ssl_hash_sha256},
+ {TLS_DHE_DSS_WITH_AES_256_CBC_SHA, cipher_aes_256, mac_sha, kea_dhe_dss, ssl_hash_none},
+ {TLS_DHE_RSA_WITH_AES_256_CBC_SHA, cipher_aes_256, mac_sha, kea_dhe_rsa, ssl_hash_none},
+ {TLS_DHE_RSA_WITH_AES_256_CBC_SHA256, cipher_aes_256, hmac_sha256, kea_dhe_rsa, ssl_hash_sha256},
+ {TLS_DHE_RSA_WITH_AES_256_GCM_SHA384, cipher_aes_256_gcm, mac_aead, kea_dhe_rsa, ssl_hash_sha384},
+
+ {TLS_RSA_WITH_SEED_CBC_SHA, cipher_seed, mac_sha, kea_rsa, ssl_hash_none},
+
+ {TLS_RSA_WITH_CAMELLIA_128_CBC_SHA, cipher_camellia_128, mac_sha, kea_rsa, ssl_hash_none},
{TLS_DHE_DSS_WITH_CAMELLIA_128_CBC_SHA,
- cipher_camellia_128, mac_sha, kea_dhe_dss},
+ cipher_camellia_128, mac_sha, kea_dhe_dss, ssl_hash_none},
{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},
+ cipher_camellia_128, mac_sha, kea_dhe_rsa, ssl_hash_none},
+ {TLS_RSA_WITH_CAMELLIA_256_CBC_SHA, cipher_camellia_256, mac_sha, kea_rsa, ssl_hash_none},
{TLS_DHE_DSS_WITH_CAMELLIA_256_CBC_SHA,
- cipher_camellia_256, mac_sha, kea_dhe_dss},
+ cipher_camellia_256, mac_sha, kea_dhe_dss, ssl_hash_none},
{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},
-
- {TLS_DHE_RSA_WITH_AES_128_GCM_SHA256, cipher_aes_128_gcm, mac_aead, kea_dhe_rsa},
- {TLS_RSA_WITH_AES_128_GCM_SHA256, cipher_aes_128_gcm, mac_aead, kea_rsa},
- {TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, cipher_aes_128_gcm, mac_aead, kea_ecdhe_rsa},
- {TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, cipher_aes_128_gcm, mac_aead, kea_ecdhe_ecdsa},
-
- {TLS_DHE_DSS_WITH_AES_128_GCM_SHA256, cipher_aes_128_gcm, mac_aead, kea_dhe_dss},
- {TLS_DHE_DSS_WITH_AES_128_CBC_SHA256, cipher_aes_128, hmac_sha256, kea_dhe_dss},
- {TLS_DHE_DSS_WITH_AES_256_CBC_SHA256, cipher_aes_256, hmac_sha256, kea_dhe_dss},
-
-#ifndef NSS_DISABLE_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_128_CBC_SHA256, cipher_aes_128, hmac_sha256, 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_128_CBC_SHA256, cipher_aes_128, hmac_sha256, 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_DISABLE_ECC */
+ cipher_camellia_256, mac_sha, kea_dhe_rsa, ssl_hash_none},
+
+ {TLS_DHE_RSA_WITH_AES_128_GCM_SHA256, cipher_aes_128_gcm, mac_aead, kea_dhe_rsa, ssl_hash_sha256},
+ {TLS_RSA_WITH_AES_128_GCM_SHA256, cipher_aes_128_gcm, mac_aead, kea_rsa, ssl_hash_sha256},
+
+ {TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, cipher_aes_128_gcm, mac_aead, kea_ecdhe_rsa, ssl_hash_sha256},
+ {TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, cipher_aes_128_gcm, mac_aead, kea_ecdhe_ecdsa, ssl_hash_sha256},
+ {TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384, cipher_aes_256_gcm, mac_aead, kea_ecdhe_ecdsa, ssl_hash_sha384},
+ {TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384, cipher_aes_256_gcm, mac_aead, kea_ecdhe_rsa, ssl_hash_sha384},
+ {TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384, cipher_aes_256, hmac_sha384, kea_ecdhe_ecdsa, ssl_hash_sha384},
+ {TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384, cipher_aes_256, hmac_sha384, kea_ecdhe_rsa, ssl_hash_sha384},
+ {TLS_DHE_DSS_WITH_AES_128_GCM_SHA256, cipher_aes_128_gcm, mac_aead, kea_dhe_dss, ssl_hash_sha256},
+ {TLS_DHE_DSS_WITH_AES_128_CBC_SHA256, cipher_aes_128, hmac_sha256, kea_dhe_dss, ssl_hash_sha256},
+ {TLS_DHE_DSS_WITH_AES_256_CBC_SHA256, cipher_aes_256, hmac_sha256, kea_dhe_dss, ssl_hash_sha256},
+ {TLS_DHE_DSS_WITH_AES_256_GCM_SHA384, cipher_aes_256_gcm, mac_aead, kea_dhe_dss, ssl_hash_sha384},
+ {TLS_RSA_WITH_AES_256_GCM_SHA384, cipher_aes_256_gcm, mac_aead, kea_rsa, ssl_hash_sha384},
+
+ {TLS_DHE_RSA_WITH_CHACHA20_POLY1305_SHA256, cipher_chacha20, mac_aead, kea_dhe_rsa, ssl_hash_sha256},
+
+ {TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256, cipher_chacha20, mac_aead, kea_ecdhe_rsa, ssl_hash_sha256},
+ {TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256, cipher_chacha20, mac_aead, kea_ecdhe_ecdsa, ssl_hash_sha256},
+
+ {TLS_ECDH_ECDSA_WITH_NULL_SHA, cipher_null, mac_sha, kea_ecdh_ecdsa, ssl_hash_none},
+ {TLS_ECDH_ECDSA_WITH_RC4_128_SHA, cipher_rc4, mac_sha, kea_ecdh_ecdsa, ssl_hash_none},
+ {TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA, cipher_3des, mac_sha, kea_ecdh_ecdsa, ssl_hash_none},
+ {TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA, cipher_aes_128, mac_sha, kea_ecdh_ecdsa, ssl_hash_none},
+ {TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA, cipher_aes_256, mac_sha, kea_ecdh_ecdsa, ssl_hash_none},
+
+ {TLS_ECDHE_ECDSA_WITH_NULL_SHA, cipher_null, mac_sha, kea_ecdhe_ecdsa, ssl_hash_none},
+ {TLS_ECDHE_ECDSA_WITH_RC4_128_SHA, cipher_rc4, mac_sha, kea_ecdhe_ecdsa, ssl_hash_none},
+ {TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA, cipher_3des, mac_sha, kea_ecdhe_ecdsa, ssl_hash_none},
+ {TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA, cipher_aes_128, mac_sha, kea_ecdhe_ecdsa, ssl_hash_none},
+ {TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256, cipher_aes_128, hmac_sha256, kea_ecdhe_ecdsa, ssl_hash_sha256},
+ {TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA, cipher_aes_256, mac_sha, kea_ecdhe_ecdsa, ssl_hash_none},
+
+ {TLS_ECDH_RSA_WITH_NULL_SHA, cipher_null, mac_sha, kea_ecdh_rsa, ssl_hash_none},
+ {TLS_ECDH_RSA_WITH_RC4_128_SHA, cipher_rc4, mac_sha, kea_ecdh_rsa, ssl_hash_none},
+ {TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA, cipher_3des, mac_sha, kea_ecdh_rsa, ssl_hash_none},
+ {TLS_ECDH_RSA_WITH_AES_128_CBC_SHA, cipher_aes_128, mac_sha, kea_ecdh_rsa, ssl_hash_none},
+ {TLS_ECDH_RSA_WITH_AES_256_CBC_SHA, cipher_aes_256, mac_sha, kea_ecdh_rsa, ssl_hash_none},
+
+ {TLS_ECDHE_RSA_WITH_NULL_SHA, cipher_null, mac_sha, kea_ecdhe_rsa, ssl_hash_none},
+ {TLS_ECDHE_RSA_WITH_RC4_128_SHA, cipher_rc4, mac_sha, kea_ecdhe_rsa, ssl_hash_none},
+ {TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA, cipher_3des, mac_sha, kea_ecdhe_rsa, ssl_hash_none},
+ {TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA, cipher_aes_128, mac_sha, kea_ecdhe_rsa, ssl_hash_none},
+ {TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256, cipher_aes_128, hmac_sha256, kea_ecdhe_rsa, ssl_hash_sha256},
+ {TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA, cipher_aes_256, mac_sha, kea_ecdhe_rsa, ssl_hash_none},
+
+ {TLS_AES_128_GCM_SHA256, cipher_aes_128_gcm, mac_aead, kea_tls13_any, ssl_hash_sha256},
+ {TLS_CHACHA20_POLY1305_SHA256, cipher_chacha20, mac_aead, kea_tls13_any, ssl_hash_sha256},
+ {TLS_AES_256_GCM_SHA384, cipher_aes_256_gcm, mac_aead, kea_tls13_any, ssl_hash_sha384},
+};
+/* clang-format on */
+
+static const CK_MECHANISM_TYPE auth_alg_defs[] = {
+ CKM_INVALID_MECHANISM, /* ssl_auth_null */
+ CKM_RSA_PKCS, /* ssl_auth_rsa_decrypt */
+ CKM_DSA, /* ? _SHA1 */ /* ssl_auth_dsa */
+ CKM_INVALID_MECHANISM, /* ssl_auth_kea (unused) */
+ CKM_ECDSA, /* ssl_auth_ecdsa */
+ CKM_ECDH1_DERIVE, /* ssl_auth_ecdh_rsa */
+ CKM_ECDH1_DERIVE, /* ssl_auth_ecdh_ecdsa */
+ CKM_RSA_PKCS, /* ssl_auth_rsa_sign */
+ CKM_RSA_PKCS_PSS, /* ssl_auth_rsa_pss */
+ CKM_NSS_HKDF_SHA256, /* ssl_auth_psk (just check for HKDF) */
+ CKM_INVALID_MECHANISM /* ssl_auth_tls13_any */
};
+PR_STATIC_ASSERT(PR_ARRAY_SIZE(auth_alg_defs) == ssl_auth_size);
static const CK_MECHANISM_TYPE kea_alg_defs[] = {
- 0x80000000L,
- CKM_RSA_PKCS,
- CKM_DH_PKCS_DERIVE,
- CKM_KEA_KEY_DERIVE,
- CKM_ECDH1_DERIVE
+ CKM_INVALID_MECHANISM, /* ssl_kea_null */
+ CKM_RSA_PKCS, /* ssl_kea_rsa */
+ CKM_DH_PKCS_DERIVE, /* ssl_kea_dh */
+ CKM_INVALID_MECHANISM, /* ssl_kea_fortezza (unused) */
+ CKM_ECDH1_DERIVE, /* ssl_kea_ecdh */
+ CKM_ECDH1_DERIVE, /* ssl_kea_ecdh_psk */
+ CKM_DH_PKCS_DERIVE, /* ssl_kea_dh_psk */
+ CKM_INVALID_MECHANISM, /* ssl_kea_tls13_any */
};
+PR_STATIC_ASSERT(PR_ARRAY_SIZE(kea_alg_defs) == ssl_kea_size);
typedef struct SSLCipher2MechStr {
- SSLCipherAlgorithm calg;
- CK_MECHANISM_TYPE cmech;
+ 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_aes_gcm , CKM_AES_GCM },
-/* { calg_init , (CK_MECHANISM_TYPE)0x7fffffffL } */
+ { 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_aes_gcm, CKM_AES_GCM },
+ { calg_chacha20, CKM_NSS_CHACHA20_POLY1305 },
+ /* { calg_init , (CK_MECHANISM_TYPE)0x7fffffffL } */
};
-#define mmech_invalid (CK_MECHANISM_TYPE)0x80000000L
-#define mmech_md5 CKM_SSL3_MD5_MAC
-#define mmech_sha CKM_SSL3_SHA1_MAC
+#define mmech_invalid (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
#define mmech_sha256_hmac CKM_SHA256_HMAC
+#define mmech_sha384_hmac CKM_SHA384_HMAC
+/* clang-format off */
static const ssl3MACDef mac_defs[] = { /* indexed by SSL3MACAlgorithm */
/* pad_size is only used for SSL 3.0 MAC. See RFC 6101 Sec. 5.2.3.1. */
/* mac mmech pad_size mac_size */
- { mac_null, mmech_invalid, 0, 0 },
- { mac_md5, mmech_md5, 48, MD5_LENGTH },
- { mac_sha, mmech_sha, 40, SHA1_LENGTH},
- {hmac_md5, mmech_md5_hmac, 0, MD5_LENGTH },
- {hmac_sha, mmech_sha_hmac, 0, SHA1_LENGTH},
- {hmac_sha256, mmech_sha256_hmac, 0, SHA256_LENGTH},
- { mac_aead, mmech_invalid, 0, 0 },
-};
-
-/* 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",
- "AES-128-GCM",
- "missing"
+ { mac_null, mmech_invalid, 0, 0 , 0},
+ { mac_md5, mmech_md5, 48, MD5_LENGTH, SEC_OID_HMAC_MD5 },
+ { mac_sha, mmech_sha, 40, SHA1_LENGTH, SEC_OID_HMAC_SHA1},
+ {hmac_md5, mmech_md5_hmac, 0, MD5_LENGTH, SEC_OID_HMAC_MD5},
+ {hmac_sha, mmech_sha_hmac, 0, SHA1_LENGTH, SEC_OID_HMAC_SHA1},
+ {hmac_sha256, mmech_sha256_hmac, 0, SHA256_LENGTH, SEC_OID_HMAC_SHA256},
+ { mac_aead, mmech_invalid, 0, 0, 0 },
+ {hmac_sha384, mmech_sha384_hmac, 0, SHA384_LENGTH, SEC_OID_HMAC_SHA384}
};
-
-#ifndef NSS_DISABLE_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
+/* clang-format on */
+
+const PRUint8 tls13_downgrade_random[] = { 0x44, 0x4F, 0x57, 0x4E,
+ 0x47, 0x52, 0x44, 0x01 };
+const PRUint8 tls12_downgrade_random[] = { 0x44, 0x4F, 0x57, 0x4E,
+ 0x47, 0x52, 0x44, 0x00 };
+PR_STATIC_ASSERT(sizeof(tls13_downgrade_random) ==
+ sizeof(tls13_downgrade_random));
+
+/* 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
+ * 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
+#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 */
+ 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_DISABLE_ECC */
+
+CK_MECHANISM_TYPE
+ssl3_Alg2Mech(SSLCipherAlgorithm calg)
+{
+ PORT_Assert(alg2Mech[calg].calg == calg);
+ return alg2Mech[calg].cmech;
+}
#if defined(TRACE)
static char *
ssl3_DecodeHandshakeType(int msgType)
{
- char * rv;
+ 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;
+ 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 new_session_ticket:
+ rv = "session_ticket (4)";
+ break;
+ case hello_retry_request:
+ rv = "hello_retry_request (6)";
+ break;
+ case encrypted_extensions:
+ rv = "encrypted_extensions (8)";
+ 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;
}
@@ -584,26 +617,32 @@ ssl3_DecodeHandshakeType(int msgType)
static char *
ssl3_DecodeContentType(int msgType)
{
- char * rv;
+ 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;
+ 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 *
+SSL3Statistics *
SSL_GetStatistics(void)
{
return &ssl3stats;
@@ -619,14 +658,15 @@ typedef struct tooLongStr {
#endif
} tooLong;
-void SSL_AtomicIncrementLong(long * x)
+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);
+ tooLong *tl = (tooLong *)x;
+ if (PR_ATOMIC_INCREMENT(&tl->low) == 0)
+ PR_ATOMIC_INCREMENT(&tl->high);
}
}
@@ -636,84 +676,82 @@ ssl3_CipherSuiteAllowedForVersionRange(
const SSLVersionRange *vrange)
{
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 TLS_RSA_EXPORT_WITH_RC4_40_MD5:
- case TLS_RSA_EXPORT_WITH_RC2_CBC_40_MD5:
- /* TLS_RSA_EXPORT_WITH_DES40_CBC_SHA: never implemented
- * TLS_DH_DSS_EXPORT_WITH_DES40_CBC_SHA: never implemented
- * TLS_DH_RSA_EXPORT_WITH_DES40_CBC_SHA: never implemented
- * TLS_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA: never implemented
- * TLS_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA: never implemented
- * TLS_DH_anon_EXPORT_WITH_RC4_40_MD5: never implemented
- * TLS_DH_anon_EXPORT_WITH_DES40_CBC_SHA: never implemented
- */
- return vrange->min <= SSL_LIBRARY_VERSION_TLS_1_0;
-
- case TLS_DHE_RSA_WITH_AES_256_CBC_SHA256:
- case TLS_RSA_WITH_AES_256_CBC_SHA256:
- case TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256:
- case TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256:
- case TLS_DHE_RSA_WITH_AES_128_CBC_SHA256:
- case TLS_RSA_WITH_AES_128_CBC_SHA256:
- case TLS_RSA_WITH_AES_128_GCM_SHA256:
- case TLS_DHE_DSS_WITH_AES_128_CBC_SHA256:
- case TLS_DHE_DSS_WITH_AES_256_CBC_SHA256:
- case TLS_RSA_WITH_NULL_SHA256:
- return vrange->max == SSL_LIBRARY_VERSION_TLS_1_2;
-
- case TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256:
- case TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256:
- case TLS_DHE_RSA_WITH_AES_128_GCM_SHA256:
- case TLS_DHE_DSS_WITH_AES_128_GCM_SHA256:
- return vrange->max >= SSL_LIBRARY_VERSION_TLS_1_2;
-
- /* RFC 4492: ECC cipher suites need TLS extensions to negotiate curves and
- * point formats.*/
- case TLS_ECDH_ECDSA_WITH_NULL_SHA:
- case TLS_ECDH_ECDSA_WITH_RC4_128_SHA:
- case TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA:
- case TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA:
- case TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA:
- case TLS_ECDHE_ECDSA_WITH_NULL_SHA:
- case TLS_ECDHE_ECDSA_WITH_RC4_128_SHA:
- case TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA:
- case TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA:
- case TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA:
- case TLS_ECDH_RSA_WITH_NULL_SHA:
- case TLS_ECDH_RSA_WITH_RC4_128_SHA:
- case TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA:
- case TLS_ECDH_RSA_WITH_AES_128_CBC_SHA:
- case TLS_ECDH_RSA_WITH_AES_256_CBC_SHA:
- case TLS_ECDHE_RSA_WITH_NULL_SHA:
- case TLS_ECDHE_RSA_WITH_RC4_128_SHA:
- case TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA:
- case TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA:
- case TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA:
- return vrange->max >= SSL_LIBRARY_VERSION_TLS_1_0 &&
- vrange->min < SSL_LIBRARY_VERSION_TLS_1_3;
-
- default:
- return vrange->min < SSL_LIBRARY_VERSION_TLS_1_3;
+ case TLS_DHE_RSA_WITH_AES_256_CBC_SHA256:
+ case TLS_RSA_WITH_AES_256_CBC_SHA256:
+ case TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256:
+ case TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384:
+ case TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256:
+ case TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384:
+ case TLS_DHE_RSA_WITH_AES_128_CBC_SHA256:
+ case TLS_RSA_WITH_AES_128_CBC_SHA256:
+ case TLS_RSA_WITH_AES_128_GCM_SHA256:
+ case TLS_RSA_WITH_AES_256_GCM_SHA384:
+ case TLS_DHE_DSS_WITH_AES_128_CBC_SHA256:
+ case TLS_DHE_DSS_WITH_AES_256_CBC_SHA256:
+ case TLS_RSA_WITH_NULL_SHA256:
+ case TLS_DHE_DSS_WITH_AES_128_GCM_SHA256:
+ case TLS_DHE_DSS_WITH_AES_256_GCM_SHA384:
+ case TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256:
+ case TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384:
+ case TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256:
+ case TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384:
+ case TLS_DHE_RSA_WITH_AES_128_GCM_SHA256:
+ case TLS_DHE_RSA_WITH_AES_256_GCM_SHA384:
+ case TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256:
+ case TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256:
+ case TLS_DHE_RSA_WITH_CHACHA20_POLY1305_SHA256:
+ return vrange->max >= SSL_LIBRARY_VERSION_TLS_1_2 &&
+ vrange->min < SSL_LIBRARY_VERSION_TLS_1_3;
+
+ /* RFC 4492: ECC cipher suites need TLS extensions to negotiate curves and
+ * point formats.*/
+ case TLS_ECDH_ECDSA_WITH_NULL_SHA:
+ case TLS_ECDH_ECDSA_WITH_RC4_128_SHA:
+ case TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA:
+ case TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA:
+ case TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA:
+ case TLS_ECDHE_ECDSA_WITH_NULL_SHA:
+ case TLS_ECDHE_ECDSA_WITH_RC4_128_SHA:
+ case TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA:
+ case TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA:
+ case TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA:
+ case TLS_ECDH_RSA_WITH_NULL_SHA:
+ case TLS_ECDH_RSA_WITH_RC4_128_SHA:
+ case TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA:
+ case TLS_ECDH_RSA_WITH_AES_128_CBC_SHA:
+ case TLS_ECDH_RSA_WITH_AES_256_CBC_SHA:
+ case TLS_ECDHE_RSA_WITH_NULL_SHA:
+ case TLS_ECDHE_RSA_WITH_RC4_128_SHA:
+ case TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA:
+ case TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA:
+ case TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA:
+ return vrange->max >= SSL_LIBRARY_VERSION_TLS_1_0 &&
+ vrange->min < SSL_LIBRARY_VERSION_TLS_1_3;
+
+ case TLS_AES_128_GCM_SHA256:
+ case TLS_AES_256_GCM_SHA384:
+ case TLS_CHACHA20_POLY1305_SHA256:
+ return vrange->max >= SSL_LIBRARY_VERSION_TLS_1_3;
+
+ default:
+ return vrange->min < SSL_LIBRARY_VERSION_TLS_1_3;
}
}
/* return pointer to ssl3CipherSuiteDef for suite, or NULL */
/* XXX This does a linear search. A binary search would be better. */
-static const ssl3CipherSuiteDef *
+const ssl3CipherSuiteDef *
ssl_LookupCipherSuiteDef(ssl3CipherSuite suite)
{
int cipher_suite_def_len =
- sizeof(cipher_suite_defs) / sizeof(cipher_suite_defs[0]);
+ 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];
+ if (cipher_suite_defs[i].cipher_suite == suite)
+ return &cipher_suite_defs[i];
}
- PORT_Assert(PR_FALSE); /* We should never get here. */
+ PORT_Assert(PR_FALSE); /* We should never get here. */
PORT_SetError(SSL_ERROR_UNKNOWN_CIPHER_SUITE);
return NULL;
}
@@ -721,19 +759,141 @@ ssl_LookupCipherSuiteDef(ssl3CipherSuite suite)
/* 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)
+ssl_LookupCipherSuiteCfgMutable(ssl3CipherSuite suite,
+ ssl3CipherSuiteCfg *suites)
{
int i;
for (i = 0; i < ssl_V3_SUITES_IMPLEMENTED; i++) {
- if (suites[i].cipher_suite == suite)
- return &suites[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;
}
+const static ssl3CipherSuiteCfg *
+ssl_LookupCipherSuiteCfg(ssl3CipherSuite suite, const ssl3CipherSuiteCfg *suites)
+{
+ return ssl_LookupCipherSuiteCfgMutable(suite,
+ CONST_CAST(ssl3CipherSuiteCfg, suites));
+}
+
+static PRBool
+ssl_NamedGroupTypeEnabled(const sslSocket *ss, SSLKEAType keaType)
+{
+ unsigned int i;
+ for (i = 0; i < SSL_NAMED_GROUP_COUNT; ++i) {
+ if (ss->namedGroupPreferences[i] &&
+ ss->namedGroupPreferences[i]->keaType == keaType) {
+ return PR_TRUE;
+ }
+ }
+ return PR_FALSE;
+}
+
+static PRBool
+ssl_KEAEnabled(const sslSocket *ss, SSLKEAType keaType)
+{
+ switch (keaType) {
+ case ssl_kea_rsa:
+ return PR_TRUE;
+
+ case ssl_kea_dh:
+ case ssl_kea_dh_psk: {
+ if (ss->sec.isServer && !ss->opt.enableServerDhe) {
+ return PR_FALSE;
+ }
+
+ if (ss->sec.isServer) {
+ /* If the server requires named FFDHE groups, then the client
+ * must have included an FFDHE group. peerSupportsFfdheGroups
+ * is set to true in ssl_HandleSupportedGroupsXtn(). */
+ if (ss->opt.requireDHENamedGroups &&
+ !ss->xtnData.peerSupportsFfdheGroups) {
+ return PR_FALSE;
+ }
+
+ /* We can use the weak DH group if all of these are true:
+ * 1. We don't require named groups.
+ * 2. The peer doesn't support named groups.
+ * 3. This isn't TLS 1.3.
+ * 4. The weak group is enabled. */
+ if (!ss->opt.requireDHENamedGroups &&
+ !ss->xtnData.peerSupportsFfdheGroups &&
+ ss->version < SSL_LIBRARY_VERSION_TLS_1_3 &&
+ ss->ssl3.dheWeakGroupEnabled) {
+ return PR_TRUE;
+ }
+ } else {
+ if (ss->version < SSL_LIBRARY_VERSION_TLS_1_3 &&
+ !ss->opt.requireDHENamedGroups) {
+ /* The client enables DHE cipher suites even if no DHE groups
+ * are enabled. Only if this isn't TLS 1.3 and named groups
+ * are not required. */
+ return PR_TRUE;
+ }
+ }
+ return ssl_NamedGroupTypeEnabled(ss, ssl_kea_dh);
+ }
+
+ case ssl_kea_ecdh:
+ case ssl_kea_ecdh_psk:
+ return ssl_NamedGroupTypeEnabled(ss, ssl_kea_ecdh);
+
+ case ssl_kea_tls13_any:
+ return PR_TRUE;
+
+ case ssl_kea_fortezza:
+ default:
+ PORT_Assert(0);
+ }
+ return PR_FALSE;
+}
+
+static PRBool
+ssl_HasCert(const sslSocket *ss, SSLAuthType authType)
+{
+ PRCList *cursor;
+ if (authType == ssl_auth_null || authType == ssl_auth_psk || authType == ssl_auth_tls13_any) {
+ return PR_TRUE;
+ }
+ for (cursor = PR_NEXT_LINK(&ss->serverCerts);
+ cursor != &ss->serverCerts;
+ cursor = PR_NEXT_LINK(cursor)) {
+ sslServerCert *cert = (sslServerCert *)cursor;
+ if (cert->certType.authType != authType) {
+ continue;
+ }
+ if (!cert->serverKeyPair ||
+ !cert->serverKeyPair->privKey ||
+ !cert->serverCertChain) {
+ continue;
+ }
+ /* When called from ssl3_config_match_init(), all the EC curves will be
+ * enabled, so this will essentially do nothing (unless we implement
+ * curve configuration). However, once we have seen the
+ * supported_groups extension and this is called from config_match(),
+ * this will filter out certificates with an unsupported curve. */
+ if ((authType == ssl_auth_ecdsa ||
+ authType == ssl_auth_ecdh_ecdsa ||
+ authType == ssl_auth_ecdh_rsa) &&
+ !ssl_NamedGroupEnabled(ss, cert->certType.namedCurve)) {
+ continue;
+ }
+ return PR_TRUE;
+ }
+ return PR_FALSE;
+}
+
+const ssl3BulkCipherDef *
+ssl_GetBulkCipherDef(const ssl3CipherSuiteDef *cipher_def)
+{
+ PORT_Assert(cipher_def->bulk_cipher_alg < PR_ARRAY_SIZE(bulk_cipher_defs));
+ PORT_Assert(bulk_cipher_defs[cipher_def->bulk_cipher_alg].cipher == cipher_def->bulk_cipher_alg);
+ return &bulk_cipher_defs[cipher_def->bulk_cipher_alg];
+}
/* Initialize the suite->isPresent value for config_match
* Returns count of enabled ciphers supported by extant tokens,
@@ -743,148 +903,130 @@ ssl_LookupCipherSuiteCfg(ssl3CipherSuite suite, ssl3CipherSuiteCfg *suites)
int
ssl3_config_match_init(sslSocket *ss)
{
- ssl3CipherSuiteCfg * suite;
+ 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;
+ SSLCipherAlgorithm cipher_alg;
+ CK_MECHANISM_TYPE cipher_mech;
+ SSLAuthType authType;
+ SSLKEAType keaType;
+ int i;
+ int numPresent = 0;
+ int numEnabled = 0;
PORT_Assert(ss);
if (!ss) {
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- return 0;
+ PORT_SetError(SEC_ERROR_INVALID_ARGS);
+ return 0;
}
- if (SSL3_ALL_VERSIONS_DISABLED(&ss->vrange)) {
- return 0;
+ if (SSL_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;
-#ifdef NSS_DISABLE_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_dhe_dss:
- svrAuth = ss->serverCerts + ssl_kea_dh;
- break;
- case kea_ecdhe_rsa:
- case kea_dhe_rsa:
- 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
- */
- case kea_dhe_dss_export:
- case kea_dhe_rsa_export:
- default:
- svrAuth = ss->serverCerts + exchKeyType;
- break;
- }
-#endif /* NSS_DISABLE_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;
- }
+ 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 = ssl_GetBulkCipherDef(cipher_def)->calg;
+ cipher_mech = ssl3_Alg2Mech(cipher_alg);
+
+ /* Mark the suites that are backed by real tokens, certs and keys */
+ suite->isPresent = PR_TRUE;
+
+ authType = kea_defs[cipher_def->key_exchange_alg].authKeyType;
+ if (authType != ssl_auth_null && authType != ssl_auth_tls13_any) {
+ if (ss->sec.isServer && !ssl_HasCert(ss, authType)) {
+ suite->isPresent = PR_FALSE;
+ }
+ if (!PK11_TokenExists(auth_alg_defs[authType])) {
+ suite->isPresent = PR_FALSE;
+ }
+ }
+
+ keaType = kea_defs[cipher_def->key_exchange_alg].exchKeyType;
+ if (keaType != ssl_kea_null &&
+ keaType != ssl_kea_tls13_any &&
+ !PK11_TokenExists(kea_alg_defs[keaType])) {
+ suite->isPresent = PR_FALSE;
+ }
+
+ if (cipher_alg != calg_null &&
+ !PK11_TokenExists(cipher_mech)) {
+ suite->isPresent = PR_FALSE;
+ }
+
+ if (suite->isPresent) {
+ ++numPresent;
+ }
+ }
}
PORT_Assert(numPresent > 0 || numEnabled == 0);
if (numPresent <= 0) {
- PORT_SetError(SSL_ERROR_NO_CIPHERS_SUPPORTED);
+ PORT_SetError(SSL_ERROR_NO_CIPHERS_SUPPORTED);
}
return numPresent;
}
-
-/* return PR_TRUE if suite matches policy, enabled state and is applicable to
- * the given version range. */
-/* 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. */
+/* Return PR_TRUE if suite is usable. This if the suite is permitted by policy,
+ * enabled, has a certificate (as needed), has a viable key agreement method, is
+ * usable with the negotiated TLS version, and is otherwise usable. */
static PRBool
-config_match(ssl3CipherSuiteCfg *suite, int policy, PRBool enabled,
- const SSLVersionRange *vrange, const sslSocket *ss)
+config_match(const ssl3CipherSuiteCfg *suite, int policy,
+ const SSLVersionRange *vrange, const sslSocket *ss)
{
const ssl3CipherSuiteDef *cipher_def;
+ const ssl3KEADef *kea_def;
+
+ PORT_Assert(policy != SSL_NOT_ALLOWED);
+ if (policy == SSL_NOT_ALLOWED)
+ return PR_FALSE;
- PORT_Assert(policy != SSL_NOT_ALLOWED && enabled != PR_FALSE);
- if (policy == SSL_NOT_ALLOWED || !enabled)
- return PR_FALSE;
+ if (!suite->enabled || !suite->isPresent)
+ return PR_FALSE;
+ if ((suite->policy == SSL_NOT_ALLOWED) ||
+ (suite->policy > policy))
+ return PR_FALSE;
+
+ PORT_Assert(ss != NULL);
cipher_def = ssl_LookupCipherSuiteDef(suite->cipher_suite);
PORT_Assert(cipher_def != NULL);
+ kea_def = &kea_defs[cipher_def->key_exchange_alg];
+ PORT_Assert(kea_def != NULL);
+ if (!ssl_KEAEnabled(ss, kea_def->exchKeyType)) {
+ return PR_FALSE;
+ }
- PORT_Assert(ss != NULL);
- if (ss->sec.isServer && !ss->opt.enableServerDhe &&
- kea_defs[cipher_def->key_exchange_alg].exchKeyType == ssl_kea_dh)
- return PR_FALSE;
+ if (ss->sec.isServer && !ssl_HasCert(ss, kea_def->authKeyType)) {
+ return PR_FALSE;
+ }
- return (PRBool)(suite->enabled &&
- suite->isPresent &&
- suite->policy != SSL_NOT_ALLOWED &&
- suite->policy <= policy &&
- ssl3_CipherSuiteAllowedForVersionRange(
- suite->cipher_suite, vrange));
+ return ssl3_CipherSuiteAllowedForVersionRange(suite->cipher_suite, vrange);
}
-/* return number of cipher suites that match policy, enabled state and are
- * applicable for the configured protocol version range. */
-/* called from ssl3_SendClientHello and ssl3_ConstructV2CipherSpecsHack */
+/* Return the number of cipher suites that are usable. */
+/* called from ssl3_SendClientHello */
static int
-count_cipher_suites(sslSocket *ss, int policy, PRBool enabled)
+count_cipher_suites(sslSocket *ss, int policy)
{
int i, count = 0;
- if (SSL3_ALL_VERSIONS_DISABLED(&ss->vrange)) {
- return 0;
+ if (SSL_ALL_VERSIONS_DISABLED(&ss->vrange)) {
+ return 0;
}
for (i = 0; i < ssl_V3_SUITES_IMPLEMENTED; i++) {
- if (config_match(&ss->cipherSuites[i], policy, enabled, &ss->vrange, ss))
- count++;
+ if (config_match(&ss->cipherSuites[i], policy, &ss->vrange, ss))
+ count++;
}
if (count <= 0) {
- PORT_SetError(SSL_ERROR_SSL_DISABLED);
+ PORT_SetError(SSL_ERROR_SSL_DISABLED);
}
return count;
}
@@ -892,19 +1034,18 @@ count_cipher_suites(sslSocket *ss, int policy, PRBool enabled)
/*
* 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)
+ const unsigned char *input, int inputLen)
{
if (inputLen > maxOutputLen) {
- *outputLen = 0; /* Match PK11_CipherOp in setting outputLen */
+ *outputLen = 0; /* Match PK11_CipherOp in setting outputLen */
PORT_SetError(SEC_ERROR_OUTPUT_LEN);
return SECFailure;
}
*outputLen = inputLen;
if (input != output)
- PORT_Memcpy(output, input, inputLen);
+ PORT_Memcpy(output, input, inputLen);
return SECSuccess;
}
@@ -921,17 +1062,17 @@ Null_Cipher(void *ctx, unsigned char *output, int *outputLen, int maxOutputLen,
*/
SECStatus
ssl3_NegotiateVersion(sslSocket *ss, SSL3ProtocolVersion peerVersion,
- PRBool allowLargerPeerVersion)
+ PRBool allowLargerPeerVersion)
{
- if (SSL3_ALL_VERSIONS_DISABLED(&ss->vrange)) {
- PORT_SetError(SSL_ERROR_SSL_DISABLED);
- return SECFailure;
+ if (SSL_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_UNSUPPORTED_VERSION);
- return SECFailure;
+ (peerVersion > ss->vrange.max && !allowLargerPeerVersion)) {
+ PORT_SetError(SSL_ERROR_UNSUPPORTED_VERSION);
+ return SECFailure;
}
ss->version = PR_MIN(peerVersion, ss->vrange.max);
@@ -940,469 +1081,473 @@ ssl3_NegotiateVersion(sslSocket *ss, SSL3ProtocolVersion peerVersion,
return SECSuccess;
}
+/* Used by the client when the server produces a version number.
+ * This reads, validates, and normalizes the value. */
+SECStatus
+ssl_ClientReadVersion(sslSocket *ss, SSL3Opaque **b, unsigned int *len,
+ SSL3ProtocolVersion *version)
+{
+ SSL3ProtocolVersion v;
+ PRInt32 temp;
+
+ temp = ssl3_ConsumeHandshakeNumber(ss, 2, b, len);
+ if (temp < 0) {
+ return SECFailure; /* alert has been sent */
+ }
+
+#ifdef TLS_1_3_DRAFT_VERSION
+ if (temp == SSL_LIBRARY_VERSION_TLS_1_3) {
+ (void)SSL3_SendAlert(ss, alert_fatal, protocol_version);
+ PORT_SetError(SSL_ERROR_UNSUPPORTED_VERSION);
+ return SECFailure;
+ }
+ if (temp == tls13_EncodeDraftVersion(SSL_LIBRARY_VERSION_TLS_1_3)) {
+ v = SSL_LIBRARY_VERSION_TLS_1_3;
+ } else {
+ v = (SSL3ProtocolVersion)temp;
+ }
+#else
+ v = (SSL3ProtocolVersion)temp;
+#endif
+
+ if (IS_DTLS(ss)) {
+ /* If this fails, we get 0 back and the next check to fails. */
+ v = dtls_DTLSVersionToTLSVersion(v);
+ }
+
+ PORT_Assert(!SSL_ALL_VERSIONS_DISABLED(&ss->vrange));
+ if (ss->vrange.min > v || ss->vrange.max < v) {
+ (void)SSL3_SendAlert(ss, alert_fatal,
+ (v > SSL_LIBRARY_VERSION_3_0) ? protocol_version
+ : handshake_failure);
+ PORT_SetError(SSL_ERROR_UNSUPPORTED_VERSION);
+ return SECFailure;
+ }
+ *version = v;
+ return SECSuccess;
+}
+
static SECStatus
ssl3_GetNewRandom(SSL3Random *random)
{
SECStatus rv;
- /* first 4 bytes are reserverd for time */
rv = PK11_GenerateRandom(random->rand, SSL3_RANDOM_LENGTH);
if (rv != SECSuccess) {
- ssl_MapLowLevelError(SSL_ERROR_GENERATE_RANDOM_FAILURE);
+ 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;
-
- switch (key->keyType) {
- case rsaKey:
- hashItem.data = hash->u.raw;
- hashItem.len = hash->len;
- break;
- case dsaKey:
- doDerEncode = isTLS;
- /* ssl_hash_none is used to specify the MD5/SHA1 concatenated hash.
- * In that case, we use just the SHA1 part. */
- if (hash->hashAlg == ssl_hash_none) {
- hashItem.data = hash->u.s.sha;
- hashItem.len = sizeof(hash->u.s.sha);
- } else {
- hashItem.data = hash->u.raw;
- hashItem.len = hash->len;
- }
- break;
-#ifndef NSS_DISABLE_ECC
- case ecKey:
- doDerEncode = PR_TRUE;
- /* ssl_hash_none is used to specify the MD5/SHA1 concatenated hash.
- * In that case, we use just the SHA1 part. */
- if (hash->hashAlg == ssl_hash_none) {
- hashItem.data = hash->u.s.sha;
- hashItem.len = sizeof(hash->u.s.sha);
- } else {
- hashItem.data = hash->u.raw;
- hashItem.len = hash->len;
- }
- break;
-#endif /* NSS_DISABLE_ECC */
- default:
- PORT_SetError(SEC_ERROR_INVALID_KEY);
- goto done;
+ssl3_SignHashes(sslSocket *ss, SSL3Hashes *hash, SECKEYPrivateKey *key,
+ SECItem *buf)
+{
+ SECStatus rv = SECFailure;
+ PRBool doDerEncode = PR_FALSE;
+ PRBool isTLS = (PRBool)(ss->ssl3.pwSpec->version > SSL_LIBRARY_VERSION_3_0);
+ PRBool useRsaPss = ssl_IsRsaPssSignatureScheme(ss->ssl3.hs.signatureScheme);
+ SECItem hashItem;
+
+ buf->data = NULL;
+
+ switch (SECKEY_GetPrivateKeyType(key)) {
+ case rsaKey:
+ hashItem.data = hash->u.raw;
+ hashItem.len = hash->len;
+ break;
+ case dsaKey:
+ doDerEncode = isTLS;
+ /* ssl_hash_none is used to specify the MD5/SHA1 concatenated hash.
+ * In that case, we use just the SHA1 part. */
+ if (hash->hashAlg == ssl_hash_none) {
+ hashItem.data = hash->u.s.sha;
+ hashItem.len = sizeof(hash->u.s.sha);
+ } else {
+ hashItem.data = hash->u.raw;
+ hashItem.len = hash->len;
+ }
+ break;
+ case ecKey:
+ doDerEncode = PR_TRUE;
+ /* ssl_hash_none is used to specify the MD5/SHA1 concatenated hash.
+ * In that case, we use just the SHA1 part. */
+ if (hash->hashAlg == ssl_hash_none) {
+ hashItem.data = hash->u.s.sha;
+ hashItem.len = sizeof(hash->u.s.sha);
+ } else {
+ hashItem.data = hash->u.raw;
+ hashItem.len = hash->len;
+ }
+ break;
+ default:
+ PORT_SetError(SEC_ERROR_INVALID_KEY);
+ goto done;
}
PRINT_BUF(60, (NULL, "hash(es) to be signed", hashItem.data, hashItem.len));
- if (hash->hashAlg == ssl_hash_none) {
- signatureLen = PK11_SignatureLen(key);
- if (signatureLen <= 0) {
- PORT_SetError(SEC_ERROR_INVALID_KEY);
- goto done;
- }
+ if (useRsaPss || hash->hashAlg == ssl_hash_none) {
+ CK_MECHANISM_TYPE mech = PK11_MapSignKeyType(key->keyType);
+ int signatureLen = PK11_SignatureLen(key);
+
+ SECItem *params = NULL;
+ CK_RSA_PKCS_PSS_PARAMS pssParams;
+ SECItem pssParamsItem = { siBuffer,
+ (unsigned char *)&pssParams,
+ sizeof(pssParams) };
- buf->len = (unsigned)signatureLen;
- buf->data = (unsigned char *)PORT_Alloc(signatureLen);
- if (!buf->data)
- goto done; /* error code was set. */
+ 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. */
+
+ if (useRsaPss) {
+ pssParams.hashAlg = ssl3_GetHashMechanismByHashType(hash->hashAlg);
+ pssParams.mgf = ssl3_GetMgfMechanismByHashType(hash->hashAlg);
+ pssParams.sLen = hashItem.len;
+ params = &pssParamsItem;
+ mech = CKM_RSA_PKCS_PSS;
+ }
- rv = PK11_Sign(key, buf, &hashItem);
+ rv = PK11_SignWithMechanism(key, mech, params, buf, &hashItem);
} else {
- SECOidTag hashOID = ssl3_TLSHashAlgorithmToOID(hash->hashAlg);
+ SECOidTag hashOID = ssl3_HashTypeToOID(hash->hashAlg);
rv = SGN_Digest(key, hashOID, buf, &hashItem);
}
if (rv != SECSuccess) {
- ssl_MapLowLevelError(SSL_ERROR_SIGN_HASHES_FAILURE);
+ ssl_MapLowLevelError(SSL_ERROR_SIGN_HASHES_FAILURE);
} else if (doDerEncode) {
- SECItem derSig = {siBuffer, NULL, 0};
+ 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);
- }
+ /* 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));
+ if (ss->sec.isServer) {
+ ss->sec.signatureScheme = ss->ssl3.hs.signatureScheme;
+ }
+ 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;
+ 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)
+ssl3_VerifySignedHashes(sslSocket *ss, SSLSignatureScheme scheme, SSL3Hashes *hash,
+ SECItem *buf)
{
- SECKEYPublicKey * key;
- SECItem * signature = NULL;
- SECStatus rv;
- SECItem hashItem;
- SECOidTag encAlg;
- SECOidTag hashAlg;
-
+ SECKEYPublicKey *key;
+ SECItem *signature = NULL;
+ SECStatus rv = SECFailure;
+ SECItem hashItem;
+ SECOidTag encAlg;
+ SECOidTag hashAlg;
+ void *pwArg = ss->pkcs11PinArg;
+ PRBool isRsaPssScheme = ssl_IsRsaPssSignatureScheme(scheme);
PRINT_BUF(60, (NULL, "check signed hashes",
- buf->data, buf->len));
+ buf->data, buf->len));
- key = CERT_ExtractPublicKey(cert);
+ key = CERT_ExtractPublicKey(ss->sec.peerCert);
if (key == NULL) {
- ssl_MapLowLevelError(SSL_ERROR_EXTRACT_PUBLIC_KEY_FAILURE);
- return SECFailure;
- }
-
- hashAlg = ssl3_TLSHashAlgorithmToOID(hash->hashAlg);
- switch (key->keyType) {
- case rsaKey:
- encAlg = SEC_OID_PKCS1_RSA_ENCRYPTION;
- hashItem.data = hash->u.raw;
- hashItem.len = hash->len;
- break;
- case dsaKey:
- encAlg = SEC_OID_ANSIX9_DSA_SIGNATURE;
- /* ssl_hash_none is used to specify the MD5/SHA1 concatenated hash.
- * In that case, we use just the SHA1 part. */
- if (hash->hashAlg == ssl_hash_none) {
- hashItem.data = hash->u.s.sha;
- hashItem.len = sizeof(hash->u.s.sha);
- } else {
- hashItem.data = hash->u.raw;
- hashItem.len = hash->len;
- }
- /* Allow DER encoded DSA signatures in SSL 3.0 */
- if (isTLS || buf->len != SECKEY_SignatureLen(key)) {
- signature = DSAU_DecodeDerSigToLen(buf, SECKEY_SignatureLen(key));
- if (!signature) {
- PORT_SetError(SSL_ERROR_BAD_HANDSHAKE_HASH_VALUE);
- return SECFailure;
- }
- buf = signature;
- }
- break;
-
-#ifndef NSS_DISABLE_ECC
- case ecKey:
- encAlg = SEC_OID_ANSIX962_EC_PUBLIC_KEY;
- /* ssl_hash_none is used to specify the MD5/SHA1 concatenated hash.
- * In that case, we use just the SHA1 part.
- * ECDSA signatures always encode the integers r and s using ASN.1
- * (unlike DSA where ASN.1 encoding is used with TLS but not with
- * SSL3). So we can use VFY_VerifyDigestDirect for ECDSA.
- */
- if (hash->hashAlg == ssl_hash_none) {
- hashAlg = SEC_OID_SHA1;
- hashItem.data = hash->u.s.sha;
- hashItem.len = sizeof(hash->u.s.sha);
- } else {
- hashItem.data = hash->u.raw;
- hashItem.len = hash->len;
- }
- break;
-#endif /* NSS_DISABLE_ECC */
-
- default:
- SECKEY_DestroyPublicKey(key);
- PORT_SetError(SEC_ERROR_UNSUPPORTED_KEYALG);
- return SECFailure;
+ ssl_MapLowLevelError(SSL_ERROR_EXTRACT_PUBLIC_KEY_FAILURE);
+ return SECFailure;
+ }
+
+ hashAlg = ssl3_HashTypeToOID(hash->hashAlg);
+ switch (SECKEY_GetPublicKeyType(key)) {
+ case rsaKey:
+ encAlg = SEC_OID_PKCS1_RSA_ENCRYPTION;
+ hashItem.data = hash->u.raw;
+ hashItem.len = hash->len;
+ if (scheme == ssl_sig_none) {
+ scheme = ssl_sig_rsa_pkcs1_sha1md5;
+ }
+ break;
+ case dsaKey:
+ encAlg = SEC_OID_ANSIX9_DSA_SIGNATURE;
+ /* ssl_hash_none is used to specify the MD5/SHA1 concatenated hash.
+ * In that case, we use just the SHA1 part. */
+ if (hash->hashAlg == ssl_hash_none) {
+ hashItem.data = hash->u.s.sha;
+ hashItem.len = sizeof(hash->u.s.sha);
+ } else {
+ hashItem.data = hash->u.raw;
+ hashItem.len = hash->len;
+ }
+ /* Allow DER encoded DSA signatures in SSL 3.0 */
+ if (ss->ssl3.prSpec->version > SSL_LIBRARY_VERSION_3_0 ||
+ buf->len != SECKEY_SignatureLen(key)) {
+ signature = DSAU_DecodeDerSigToLen(buf, SECKEY_SignatureLen(key));
+ if (!signature) {
+ PORT_SetError(SSL_ERROR_BAD_HANDSHAKE_HASH_VALUE);
+ goto loser;
+ }
+ buf = signature;
+ }
+ if (scheme == ssl_sig_none) {
+ scheme = ssl_sig_dsa_sha1;
+ }
+ break;
+
+ case ecKey:
+ encAlg = SEC_OID_ANSIX962_EC_PUBLIC_KEY;
+ /* ssl_hash_none is used to specify the MD5/SHA1 concatenated hash.
+ * In that case, we use just the SHA1 part.
+ * ECDSA signatures always encode the integers r and s using ASN.1
+ * (unlike DSA where ASN.1 encoding is used with TLS but not with
+ * SSL3). So we can use VFY_VerifyDigestDirect for ECDSA.
+ */
+ if (hash->hashAlg == ssl_hash_none) {
+ hashAlg = SEC_OID_SHA1;
+ hashItem.data = hash->u.s.sha;
+ hashItem.len = sizeof(hash->u.s.sha);
+ } else {
+ hashItem.data = hash->u.raw;
+ hashItem.len = hash->len;
+ }
+ if (scheme == ssl_sig_none) {
+ scheme = ssl_sig_ecdsa_sha1;
+ }
+ break;
+
+ default:
+ PORT_SetError(SEC_ERROR_UNSUPPORTED_KEYALG);
+ goto loser;
}
PRINT_BUF(60, (NULL, "hash(es) to be verified",
- hashItem.data, hashItem.len));
-
- if (hashAlg == SEC_OID_UNKNOWN || key->keyType == dsaKey) {
- /* VFY_VerifyDigestDirect requires DSA signatures to be DER-encoded.
- * DSA signatures are DER-encoded in TLS but not in SSL3 and the code
- * above always removes the DER encoding of DSA signatures when
- * present. Thus DSA signatures are always verified with PK11_Verify.
- */
- rv = PK11_Verify(key, buf, &hashItem, pwArg);
+ hashItem.data, hashItem.len));
+
+ if (isRsaPssScheme ||
+ hashAlg == SEC_OID_UNKNOWN ||
+ SECKEY_GetPublicKeyType(key) == dsaKey) {
+ /* VFY_VerifyDigestDirect requires DSA signatures to be DER-encoded.
+ * DSA signatures are DER-encoded in TLS but not in SSL3 and the code
+ * above always removes the DER encoding of DSA signatures when
+ * present. Thus DSA signatures are always verified with PK11_Verify.
+ */
+ CK_MECHANISM_TYPE mech = PK11_MapSignKeyType(key->keyType);
+
+ SECItem *params = NULL;
+ CK_RSA_PKCS_PSS_PARAMS pssParams;
+ SECItem pssParamsItem = { siBuffer,
+ (unsigned char *)&pssParams,
+ sizeof(pssParams) };
+
+ if (isRsaPssScheme) {
+ pssParams.hashAlg = ssl3_GetHashMechanismByHashType(hash->hashAlg);
+ pssParams.mgf = ssl3_GetMgfMechanismByHashType(hash->hashAlg);
+ pssParams.sLen = hashItem.len;
+ params = &pssParamsItem;
+ mech = CKM_RSA_PKCS_PSS;
+ }
+
+ rv = PK11_VerifyWithMechanism(key, mech, params, buf, &hashItem, pwArg);
} else {
rv = VFY_VerifyDigestDirect(&hashItem, key, buf, encAlg, hashAlg,
pwArg);
}
- SECKEY_DestroyPublicKey(key);
if (signature) {
- SECITEM_FreeItem(signature, PR_TRUE);
+ SECITEM_FreeItem(signature, PR_TRUE);
}
if (rv != SECSuccess) {
- ssl_MapLowLevelError(SSL_ERROR_BAD_HANDSHAKE_HASH_VALUE);
+ ssl_MapLowLevelError(SSL_ERROR_BAD_HANDSHAKE_HASH_VALUE);
+ }
+ if (!ss->sec.isServer) {
+ ss->sec.signatureScheme = scheme;
}
+
+loser:
+ SECKEY_DestroyPublicKey(key);
+#ifdef UNSAFE_FUZZER_MODE
+ rv = SECSuccess;
+ PORT_SetError(0);
+#endif
return rv;
}
-
/* Caller must set hiLevel error code. */
-/* Called from ssl3_ComputeExportRSAKeyHash
- * ssl3_ComputeDHKeyHash
+/* Called from ssl3_ComputeDHKeyHash
* which are called from ssl3_HandleServerKeyExchange.
*
* hashAlg: ssl_hash_none indicates the pre-1.2, MD5/SHA1 combination hash.
*/
SECStatus
ssl3_ComputeCommonKeyHash(SSLHashType hashAlg,
- PRUint8 * hashBuf, unsigned int bufLen,
- SSL3Hashes *hashes, PRBool bypassPKCS11)
+ PRUint8 *hashBuf, unsigned int bufLen,
+ SSL3Hashes *hashes)
{
SECStatus rv;
SECOidTag hashOID;
-#ifndef NO_PKCS11_BYPASS
- if (bypassPKCS11) {
- if (hashAlg == ssl_hash_none) {
- MD5_HashBuf (hashes->u.s.md5, hashBuf, bufLen);
- SHA1_HashBuf(hashes->u.s.sha, hashBuf, bufLen);
- hashes->len = MD5_LENGTH + SHA1_LENGTH;
- } else if (hashAlg == ssl_hash_sha1) {
- SHA1_HashBuf(hashes->u.raw, hashBuf, bufLen);
- hashes->len = SHA1_LENGTH;
- } else if (hashAlg == ssl_hash_sha256) {
- SHA256_HashBuf(hashes->u.raw, hashBuf, bufLen);
- hashes->len = SHA256_LENGTH;
- } else if (hashAlg == ssl_hash_sha384) {
- SHA384_HashBuf(hashes->u.raw, hashBuf, bufLen);
- hashes->len = SHA384_LENGTH;
- } else if (hashAlg == ssl_hash_sha512) {
- SHA512_HashBuf(hashes->u.raw, hashBuf, bufLen);
- hashes->len = SHA512_LENGTH;
- } else {
- PORT_SetError(SSL_ERROR_UNSUPPORTED_HASH_ALGORITHM);
+ if (hashAlg == ssl_hash_none) {
+ rv = PK11_HashBuf(SEC_OID_MD5, hashes->u.s.md5, hashBuf, bufLen);
+ if (rv != SECSuccess) {
+ ssl_MapLowLevelError(SSL_ERROR_MD5_DIGEST_FAILURE);
+ return rv;
+ }
+ rv = PK11_HashBuf(SEC_OID_SHA1, hashes->u.s.sha, hashBuf, bufLen);
+ if (rv != SECSuccess) {
+ ssl_MapLowLevelError(SSL_ERROR_SHA_DIGEST_FAILURE);
+ return rv;
+ }
+ hashes->len = MD5_LENGTH + SHA1_LENGTH;
+ } else {
+ hashOID = ssl3_HashTypeToOID(hashAlg);
+ hashes->len = HASH_ResultLenByOidTag(hashOID);
+ if (hashes->len == 0 || hashes->len > sizeof(hashes->u.raw)) {
+ ssl_MapLowLevelError(SSL_ERROR_UNSUPPORTED_HASH_ALGORITHM);
return SECFailure;
}
- } else
-#endif
- {
- if (hashAlg == ssl_hash_none) {
- rv = PK11_HashBuf(SEC_OID_MD5, hashes->u.s.md5, hashBuf, bufLen);
- if (rv != SECSuccess) {
- ssl_MapLowLevelError(SSL_ERROR_MD5_DIGEST_FAILURE);
- return rv;
- }
- rv = PK11_HashBuf(SEC_OID_SHA1, hashes->u.s.sha, hashBuf, bufLen);
- if (rv != SECSuccess) {
- ssl_MapLowLevelError(SSL_ERROR_SHA_DIGEST_FAILURE);
- return rv;
- }
- hashes->len = MD5_LENGTH + SHA1_LENGTH;
- } else {
- hashOID = ssl3_TLSHashAlgorithmToOID(hashAlg);
- hashes->len = HASH_ResultLenByOidTag(hashOID);
- if (hashes->len == 0 || hashes->len > sizeof(hashes->u.raw)) {
- ssl_MapLowLevelError(SSL_ERROR_UNSUPPORTED_HASH_ALGORITHM);
- return SECFailure;
- }
- rv = PK11_HashBuf(hashOID, hashes->u.raw, hashBuf, bufLen);
- if (rv != SECSuccess) {
- ssl_MapLowLevelError(SSL_ERROR_DIGEST_FAILURE);
- return rv;
- }
+ rv = PK11_HashBuf(hashOID, hashes->u.raw, hashBuf, bufLen);
+ if (rv != SECSuccess) {
+ ssl_MapLowLevelError(SSL_ERROR_DIGEST_FAILURE);
+ return rv;
}
}
hashes->hashAlg = hashAlg;
return SECSuccess;
}
-/* Caller must set hiLevel error code.
-** Called from ssl3_SendServerKeyExchange and
-** ssl3_HandleServerKeyExchange.
-*/
-static SECStatus
-ssl3_ComputeExportRSAKeyHash(SSLHashType hashAlg,
- 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(hashAlg, hashBuf, bufLen, hashes,
- bypassPKCS11);
-
- PRINT_BUF(95, (NULL, "RSAkey hash: ", hashBuf, bufLen));
- if (hashAlg == ssl_hash_none) {
- PRINT_BUF(95, (NULL, "RSAkey hash: MD5 result",
- hashes->u.s.md5, MD5_LENGTH));
- PRINT_BUF(95, (NULL, "RSAkey hash: SHA1 result",
- hashes->u.s.sha, SHA1_LENGTH));
- } else {
- PRINT_BUF(95, (NULL, "RSAkey hash: result",
- hashes->u.raw, hashes->len));
- }
-
- if (hashBuf != buf && hashBuf != NULL)
- PORT_Free(hashBuf);
- return rv;
-}
-
/* Caller must set hiLevel error code. */
/* Called from ssl3_HandleServerKeyExchange. */
static SECStatus
-ssl3_ComputeDHKeyHash(SSLHashType hashAlg,
- 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;
+ssl3_ComputeDHKeyHash(sslSocket *ss, SSLHashType hashAlg, SSL3Hashes *hashes,
+ SECItem dh_p, SECItem dh_g, SECItem dh_Ys, PRBool padY)
+{
+ PRUint8 *hashBuf;
+ PRUint8 *pBuf;
+ SECStatus rv = SECSuccess;
+ unsigned int bufLen, yLen;
+ PRUint8 buf[2 * SSL3_RANDOM_LENGTH + 2 + 4096 / 8 + 2 + 4096 / 8];
+
+ PORT_Assert(dh_p.data);
+ PORT_Assert(dh_g.data);
+ PORT_Assert(dh_Ys.data);
+
+ yLen = padY ? dh_p.len : dh_Ys.len;
+ bufLen = 2 * SSL3_RANDOM_LENGTH +
+ 2 + dh_p.len +
+ 2 + dh_g.len +
+ 2 + yLen;
if (bufLen <= sizeof buf) {
- hashBuf = 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;
+ hashBuf = PORT_Alloc(bufLen);
+ if (!hashBuf) {
+ return SECFailure;
+ }
+ }
+
+ memcpy(hashBuf, &ss->ssl3.hs.client_random, SSL3_RANDOM_LENGTH);
+ pBuf = hashBuf + SSL3_RANDOM_LENGTH;
+ memcpy(pBuf, &ss->ssl3.hs.server_random, SSL3_RANDOM_LENGTH);
+ pBuf += SSL3_RANDOM_LENGTH;
+ pBuf = ssl_EncodeUintX(dh_p.len, 2, pBuf);
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;
+ pBuf += dh_p.len;
+ pBuf = ssl_EncodeUintX(dh_g.len, 2, pBuf);
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;
+ pBuf += dh_g.len;
+ pBuf = ssl_EncodeUintX(yLen, 2, pBuf);
+ if (padY && dh_p.len > dh_Ys.len) {
+ memset(pBuf, 0, dh_p.len - dh_Ys.len);
+ pBuf += dh_p.len - dh_Ys.len;
+ }
+ /* If we're padding Y, dh_Ys can't be longer than dh_p. */
+ PORT_Assert(!padY || dh_p.len >= dh_Ys.len);
memcpy(pBuf, dh_Ys.data, dh_Ys.len);
- pBuf += dh_Ys.len;
+ pBuf += dh_Ys.len;
PORT_Assert((unsigned int)(pBuf - hashBuf) == bufLen);
- rv = ssl3_ComputeCommonKeyHash(hashAlg, hashBuf, bufLen, hashes,
- bypassPKCS11);
+ rv = ssl3_ComputeCommonKeyHash(hashAlg, hashBuf, bufLen, hashes);
PRINT_BUF(95, (NULL, "DHkey hash: ", hashBuf, bufLen));
- if (hashAlg == ssl_hash_none) {
- PRINT_BUF(95, (NULL, "DHkey hash: MD5 result",
- hashes->u.s.md5, MD5_LENGTH));
- PRINT_BUF(95, (NULL, "DHkey hash: SHA1 result",
- hashes->u.s.sha, SHA1_LENGTH));
- } else {
- PRINT_BUF(95, (NULL, "DHkey hash: result",
- hashes->u.raw, hashes->len));
+ if (rv == SECSuccess) {
+ if (hashAlg == ssl_hash_none) {
+ PRINT_BUF(95, (NULL, "DHkey hash: MD5 result",
+ hashes->u.s.md5, MD5_LENGTH));
+ PRINT_BUF(95, (NULL, "DHkey hash: SHA1 result",
+ hashes->u.s.sha, SHA1_LENGTH));
+ } else {
+ PRINT_BUF(95, (NULL, "DHkey hash: result",
+ hashes->u.raw, hashes->len));
+ }
}
if (hashBuf != buf && hashBuf != NULL)
- PORT_Free(hashBuf);
+ 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;
+ 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;
+ 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;
+ PK11_DestroyContext(mat->write_mac_context, PR_TRUE);
+ mat->write_mac_context = NULL;
}
}
-/* Called from ssl3_SendChangeCipherSpecs() and
-** ssl3_HandleChangeCipherSpecs()
+/* 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;
+ /* PORT_Assert( ss->opt.noLocks || ssl_HaveSpecWriteLock(ss)); Don't have ss! */
+ if (spec->encodeContext) {
+ PK11_DestroyContext(spec->encodeContext, PR_TRUE);
+ spec->encodeContext = NULL;
+ }
+ if (spec->decodeContext) {
+ PK11_DestroyContext(spec->decodeContext, PR_TRUE);
+ spec->decodeContext = NULL;
}
if (spec->destroyCompressContext && spec->compressContext) {
- spec->destroyCompressContext(spec->compressContext, 1);
- spec->compressContext = NULL;
+ 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);
+ spec->destroyDecompressContext(spec->decompressContext, 1);
+ spec->decompressContext = NULL;
}
if (spec->master_secret != NULL) {
- PK11_FreeSymKey(spec->master_secret);
- spec->master_secret = NULL;
+ PK11_FreeSymKey(spec->master_secret);
+ spec->master_secret = NULL;
}
spec->msItem.data = NULL;
- spec->msItem.len = 0;
+ 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;
}
@@ -1413,21 +1558,21 @@ ssl3_DestroyCipherSpec(ssl3CipherSpec *spec, PRBool freeSrvName)
** Caller must hold the ssl3 handshake lock.
** Acquires & releases SpecWriteLock.
*/
-static SECStatus
+SECStatus
ssl3_SetupPendingCipherSpec(sslSocket *ss)
{
- ssl3CipherSpec * pwSpec;
- ssl3CipherSpec * cwSpec;
- ssl3CipherSuite suite = ss->ssl3.hs.cipher_suite;
- SSL3MACAlgorithm mac;
- SSL3BulkCipher cipher;
- SSL3KeyExchangeAlgorithm kea;
+ ssl3CipherSpec *pwSpec;
+ ssl3CipherSpec *cwSpec;
+ ssl3CipherSuite suite = ss->ssl3.hs.cipher_suite;
+ SSL3MACAlgorithm mac;
+ SSL3KeyExchangeAlgorithm kea;
const ssl3CipherSuiteDef *suite_def;
- PRBool isTLS;
+ PRBool isTLS;
- PORT_Assert( ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss));
+ PORT_Assert(ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss));
+ PORT_Assert(ss->version < SSL_LIBRARY_VERSION_TLS_1_3);
- ssl_GetSpecWriteLock(ss); /*******************************/
+ ssl_GetSpecWriteLock(ss); /*******************************/
pwSpec = ss->ssl3.pwSpec;
PORT_Assert(pwSpec == ss->ssl3.prSpec);
@@ -1435,49 +1580,41 @@ ssl3_SetupPendingCipherSpec(sslSocket *ss)
/* 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;
+ /* SSL records are not being MACed. */
+ cwSpec->version = ss->version;
}
- pwSpec->version = ss->version;
- isTLS = (PRBool)(pwSpec->version > SSL_LIBRARY_VERSION_3_0);
+ 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));
+ 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 */
+ 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));
+ /* Double-check that we did not pick an RC4 suite */
+ PORT_Assert(suite_def->bulk_cipher_alg != cipher_rc4);
}
- cipher = suite_def->bulk_cipher_alg;
- kea = suite_def->key_exchange_alg;
- mac = suite_def->mac_alg;
+ kea = suite_def->key_exchange_alg;
+ mac = suite_def->mac_alg;
if (mac <= ssl_mac_sha && mac != ssl_mac_null && isTLS)
- mac += 2;
+ mac += 2;
ss->ssl3.hs.suite_def = suite_def;
- ss->ssl3.hs.kea_def = &kea_defs[kea];
+ 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->cipher_def = ssl_GetBulkCipherDef(suite_def);
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;
@@ -1487,21 +1624,25 @@ ssl3_SetupPendingCipherSpec(sslSocket *ss)
pwSpec->compressContext = NULL;
pwSpec->decompressContext = NULL;
- ssl_ReleaseSpecWriteLock(ss); /*******************************/
+ if (ss->version >= SSL_LIBRARY_VERSION_TLS_1_3) {
+ PORT_Assert(ss->ssl3.hs.kea_def->ephemeral);
+ PORT_Assert(pwSpec->cipher_def->type == type_aead);
+ }
+ ssl_ReleaseSpecWriteLock(ss); /*******************************/
return SECSuccess;
}
-#ifdef NSS_ENABLE_ZLIB
+#ifdef NSS_SSL_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;
+ case Z_OK:
+ return SECSuccess;
+ default:
+ return SECFailure;
}
}
@@ -1540,7 +1681,7 @@ ssl3_DeflateCompress(void *void_context, unsigned char *out, int *out_len,
return SECSuccess;
}
- context->next_in = (unsigned char*) in;
+ context->next_in = (unsigned char *)in;
context->avail_in = inlen;
context->next_out = out;
context->avail_out = maxout;
@@ -1569,7 +1710,7 @@ ssl3_DeflateDecompress(void *void_context, unsigned char *out, int *out_len,
return SECSuccess;
}
- context->next_in = (unsigned char*) in;
+ context->next_in = (unsigned char *)in;
context->avail_in = inlen;
context->next_out = out;
context->avail_out = maxout;
@@ -1598,7 +1739,7 @@ ssl3_DestroyDecompressContext(void *void_context, PRBool unused)
return SECSuccess;
}
-#endif /* NSS_ENABLE_ZLIB */
+#endif /* NSS_SSL_ENABLE_ZLIB */
/* Initialize the compression functions and contexts for the given
* CipherSpec. */
@@ -1607,227 +1748,54 @@ 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 contexts for pending spec.
- * MAC contexts are set up when computing the mac, not here.
- * 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;
- SSLCipherAlgorithm calg;
- 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;
-
- calg = cipher_def->calg;
-
- if (calg == ssl_calg_aes_gcm) {
- pwSpec->encode = NULL;
- pwSpec->decode = NULL;
- pwSpec->destroy = NULL;
- pwSpec->encodeContext = NULL;
- pwSpec->decodeContext = NULL;
- pwSpec->aead = ssl3_AESGCMBypass;
- ssl3_InitCompressionContext(pwSpec);
- return SECSuccess;
- }
-
- 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:
- case ssl_calg_aes_gcm:
- 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;
+ 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_SSL_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_SSL_ENABLE_ZLIB */
+ default:
+ PORT_Assert(0);
+ PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
+ return SECFailure;
}
- 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
+/* 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;
- }
+ 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;
}
@@ -1846,40 +1814,40 @@ ssl3_ParamFromIV(CK_MECHANISM_TYPE mtype, SECItem *iv, CK_ULONG ulEffectiveBits)
*/
static unsigned int
ssl3_BuildRecordPseudoHeader(unsigned char *out,
- SSL3SequenceNumber seq_num,
- SSL3ContentType type,
- PRBool includesVersion,
- SSL3ProtocolVersion version,
- PRBool isDTLS,
- int length)
-{
- out[0] = (unsigned char)(seq_num.high >> 24);
- out[1] = (unsigned char)(seq_num.high >> 16);
- out[2] = (unsigned char)(seq_num.high >> 8);
- out[3] = (unsigned char)(seq_num.high >> 0);
- out[4] = (unsigned char)(seq_num.low >> 24);
- out[5] = (unsigned char)(seq_num.low >> 16);
- out[6] = (unsigned char)(seq_num.low >> 8);
- out[7] = (unsigned char)(seq_num.low >> 0);
+ sslSequenceNumber seq_num,
+ SSL3ContentType type,
+ PRBool includesVersion,
+ SSL3ProtocolVersion version,
+ PRBool isDTLS,
+ int length)
+{
+ out[0] = (unsigned char)(seq_num >> 56);
+ out[1] = (unsigned char)(seq_num >> 48);
+ out[2] = (unsigned char)(seq_num >> 40);
+ out[3] = (unsigned char)(seq_num >> 32);
+ out[4] = (unsigned char)(seq_num >> 24);
+ out[5] = (unsigned char)(seq_num >> 16);
+ out[6] = (unsigned char)(seq_num >> 8);
+ out[7] = (unsigned char)(seq_num >> 0);
out[8] = type;
/* SSL3 MAC doesn't include the record's version field. */
if (!includesVersion) {
- out[9] = MSB(length);
- out[10] = LSB(length);
- return 11;
+ out[9] = MSB(length);
+ out[10] = LSB(length);
+ return 11;
}
/* TLS MAC and AEAD additional data include version. */
if (isDTLS) {
- SSL3ProtocolVersion dtls_version;
+ SSL3ProtocolVersion dtls_version;
- dtls_version = dtls_TLSVersionToDTLSVersion(version);
- out[9] = MSB(dtls_version);
- out[10] = LSB(dtls_version);
+ dtls_version = dtls_TLSVersionToDTLSVersion(version);
+ out[9] = MSB(dtls_version);
+ out[10] = LSB(dtls_version);
} else {
- out[9] = MSB(version);
- out[10] = LSB(version);
+ out[9] = MSB(version);
+ out[10] = LSB(version);
}
out[11] = MSB(length);
out[12] = LSB(length);
@@ -1888,265 +1856,251 @@ ssl3_BuildRecordPseudoHeader(unsigned char *out,
static SECStatus
ssl3_AESGCM(ssl3KeyMaterial *keys,
- PRBool doDecrypt,
- unsigned char *out,
- int *outlen,
- int maxout,
- const unsigned char *in,
- int inlen,
- const unsigned char *additionalData,
- int additionalDataLen)
-{
- SECItem param;
- SECStatus rv = SECFailure;
- unsigned char nonce[12];
- unsigned int uOutLen;
- CK_GCM_PARAMS gcmParams;
-
- static const int tagSize = 16;
- static const int explicitNonceLen = 8;
+ PRBool doDecrypt,
+ unsigned char *out,
+ int *outlen,
+ int maxout,
+ const unsigned char *in,
+ int inlen,
+ const unsigned char *additionalData,
+ int additionalDataLen)
+{
+ SECItem param;
+ SECStatus rv = SECFailure;
+ unsigned char nonce[12];
+ unsigned int uOutLen;
+ CK_GCM_PARAMS gcmParams;
+
+ const int tagSize = bulk_cipher_defs[cipher_aes_128_gcm].tag_size;
+ const int explicitNonceLen =
+ bulk_cipher_defs[cipher_aes_128_gcm].explicit_nonce_size;
/* See https://tools.ietf.org/html/rfc5288#section-3 for details of how the
* nonce is formed. */
memcpy(nonce, keys->write_iv, 4);
if (doDecrypt) {
- memcpy(nonce + 4, in, explicitNonceLen);
- in += explicitNonceLen;
- inlen -= explicitNonceLen;
- *outlen = 0;
+ memcpy(nonce + 4, in, explicitNonceLen);
+ in += explicitNonceLen;
+ inlen -= explicitNonceLen;
+ *outlen = 0;
} else {
- if (maxout < explicitNonceLen) {
- PORT_SetError(SEC_ERROR_INPUT_LEN);
- return SECFailure;
+ if (maxout < explicitNonceLen) {
+ PORT_SetError(SEC_ERROR_INPUT_LEN);
+ return SECFailure;
}
- /* Use the 64-bit sequence number as the explicit nonce. */
- memcpy(nonce + 4, additionalData, explicitNonceLen);
- memcpy(out, additionalData, explicitNonceLen);
- out += explicitNonceLen;
- maxout -= explicitNonceLen;
- *outlen = explicitNonceLen;
+ /* Use the 64-bit sequence number as the explicit nonce. */
+ memcpy(nonce + 4, additionalData, explicitNonceLen);
+ memcpy(out, additionalData, explicitNonceLen);
+ out += explicitNonceLen;
+ maxout -= explicitNonceLen;
+ *outlen = explicitNonceLen;
}
param.type = siBuffer;
- param.data = (unsigned char *) &gcmParams;
+ param.data = (unsigned char *)&gcmParams;
param.len = sizeof(gcmParams);
gcmParams.pIv = nonce;
gcmParams.ulIvLen = sizeof(nonce);
- gcmParams.pAAD = (unsigned char *)additionalData; /* const cast */
+ gcmParams.pAAD = (unsigned char *)additionalData; /* const cast */
gcmParams.ulAADLen = additionalDataLen;
gcmParams.ulTagBits = tagSize * 8;
if (doDecrypt) {
- rv = PK11_Decrypt(keys->write_key, CKM_AES_GCM, &param, out, &uOutLen,
- maxout, in, inlen);
+ rv = PK11_Decrypt(keys->write_key, CKM_AES_GCM, &param, out, &uOutLen,
+ maxout, in, inlen);
} else {
- rv = PK11_Encrypt(keys->write_key, CKM_AES_GCM, &param, out, &uOutLen,
- maxout, in, inlen);
+ rv = PK11_Encrypt(keys->write_key, CKM_AES_GCM, &param, out, &uOutLen,
+ maxout, in, inlen);
}
- *outlen += (int) uOutLen;
+ *outlen += (int)uOutLen;
return rv;
}
-#ifndef NO_PKCS11_BYPASS
static SECStatus
-ssl3_AESGCMBypass(ssl3KeyMaterial *keys,
- PRBool doDecrypt,
- unsigned char *out,
- int *outlen,
- int maxout,
- const unsigned char *in,
- int inlen,
- const unsigned char *additionalData,
- int additionalDataLen)
-{
- SECStatus rv = SECFailure;
- unsigned char nonce[12];
- unsigned int uOutLen;
- AESContext *cx;
- CK_GCM_PARAMS gcmParams;
-
- static const int tagSize = 16;
- static const int explicitNonceLen = 8;
+ssl3_ChaCha20Poly1305(ssl3KeyMaterial *keys, PRBool doDecrypt,
+ unsigned char *out, int *outlen, int maxout,
+ const unsigned char *in, int inlen,
+ const unsigned char *additionalData,
+ int additionalDataLen)
+{
+ size_t i;
+ SECItem param;
+ SECStatus rv = SECFailure;
+ unsigned int uOutLen;
+ unsigned char nonce[12];
+ CK_NSS_AEAD_PARAMS aeadParams;
- /* See https://tools.ietf.org/html/rfc5288#section-3 for details of how the
- * nonce is formed. */
- PORT_Assert(keys->write_iv_item.len == 4);
- if (keys->write_iv_item.len != 4) {
- PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
- return SECFailure;
- }
- memcpy(nonce, keys->write_iv_item.data, 4);
- if (doDecrypt) {
- memcpy(nonce + 4, in, explicitNonceLen);
- in += explicitNonceLen;
- inlen -= explicitNonceLen;
- *outlen = 0;
- } else {
- if (maxout < explicitNonceLen) {
- PORT_SetError(SEC_ERROR_INPUT_LEN);
- return SECFailure;
- }
- /* Use the 64-bit sequence number as the explicit nonce. */
- memcpy(nonce + 4, additionalData, explicitNonceLen);
- memcpy(out, additionalData, explicitNonceLen);
- out += explicitNonceLen;
- maxout -= explicitNonceLen;
- *outlen = explicitNonceLen;
- }
+ const int tagSize = bulk_cipher_defs[cipher_chacha20].tag_size;
- gcmParams.pIv = nonce;
- gcmParams.ulIvLen = sizeof(nonce);
- gcmParams.pAAD = (unsigned char *)additionalData; /* const cast */
- gcmParams.ulAADLen = additionalDataLen;
- gcmParams.ulTagBits = tagSize * 8;
+ /* See
+ * https://tools.ietf.org/html/draft-ietf-tls-chacha20-poly1305-04#section-2
+ * for details of how the nonce is formed. */
+ PORT_Memcpy(nonce, keys->write_iv, 12);
- cx = (AESContext *)keys->cipher_context;
- rv = AES_InitContext(cx, keys->write_key_item.data,
- keys->write_key_item.len,
- (unsigned char *)&gcmParams, NSS_AES_GCM, !doDecrypt,
- AES_BLOCK_SIZE);
- if (rv != SECSuccess) {
- return rv;
+ /* XOR the last 8 bytes of the IV with the sequence number. */
+ PORT_Assert(additionalDataLen >= 8);
+ for (i = 0; i < 8; ++i) {
+ nonce[4 + i] ^= additionalData[i];
}
+
+ param.type = siBuffer;
+ param.len = sizeof(aeadParams);
+ param.data = (unsigned char *)&aeadParams;
+ memset(&aeadParams, 0, sizeof(aeadParams));
+ aeadParams.pNonce = nonce;
+ aeadParams.ulNonceLen = sizeof(nonce);
+ aeadParams.pAAD = (unsigned char *)additionalData;
+ aeadParams.ulAADLen = additionalDataLen;
+ aeadParams.ulTagLen = tagSize;
+
if (doDecrypt) {
- rv = AES_Decrypt(cx, out, &uOutLen, maxout, in, inlen);
+ rv = PK11_Decrypt(keys->write_key, CKM_NSS_CHACHA20_POLY1305, &param,
+ out, &uOutLen, maxout, in, inlen);
} else {
- rv = AES_Encrypt(cx, out, &uOutLen, maxout, in, inlen);
+ rv = PK11_Encrypt(keys->write_key, CKM_NSS_CHACHA20_POLY1305, &param,
+ out, &uOutLen, maxout, in, inlen);
}
- AES_DestroyContext(cx, PR_FALSE);
- *outlen += (int) uOutLen;
+ *outlen = (int)uOutLen;
return rv;
}
-#endif
/* 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));
+ssl3_InitPendingContexts(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;
- calg = cipher_def->calg;
+ pwSpec = ss->ssl3.pwSpec;
+ cipher_def = pwSpec->cipher_def;
+ macLength = pwSpec->mac_size;
+ calg = cipher_def->calg;
PORT_Assert(alg2Mech[calg].calg == calg);
pwSpec->client.write_mac_context = NULL;
pwSpec->server.write_mac_context = NULL;
- if (calg == calg_aes_gcm) {
- pwSpec->encode = NULL;
- pwSpec->decode = NULL;
- pwSpec->destroy = NULL;
- pwSpec->encodeContext = NULL;
- pwSpec->decodeContext = NULL;
- pwSpec->aead = ssl3_AESGCM;
- return SECSuccess;
+ if (cipher_def->type == type_aead) {
+ pwSpec->encode = NULL;
+ pwSpec->decode = NULL;
+ pwSpec->encodeContext = NULL;
+ pwSpec->decodeContext = NULL;
+ switch (calg) {
+ case calg_aes_gcm:
+ pwSpec->aead = ssl3_AESGCM;
+ break;
+ case calg_chacha20:
+ pwSpec->aead = ssl3_ChaCha20Poly1305;
+ break;
+ default:
+ PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
+ return SECFailure;
+ }
+ return SECSuccess;
}
- /*
- ** Now setup the MAC contexts,
+ /*
+ ** Now setup the MAC contexts,
** crypto contexts are setup below.
*/
- mac_mech = pwSpec->mac_def->mmech;
+ mac_mech = pwSpec->mac_def->mmech;
mac_param.data = (unsigned char *)&macLength;
- mac_param.len = sizeof(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;
+ 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);
+ 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;
+ ssl_MapLowLevelError(SSL_ERROR_SYM_KEY_CONTEXT_FAILURE);
+ goto fail;
}
- /*
+ /*
** Now setup the crypto contexts.
*/
if (calg == calg_null) {
- pwSpec->encode = Null_Cipher;
- pwSpec->decode = Null_Cipher;
- pwSpec->destroy = NULL;
- return SECSuccess;
+ pwSpec->encode = Null_Cipher;
+ pwSpec->decode = Null_Cipher;
+ return SECSuccess;
}
- mechanism = alg2Mech[calg].cmech;
+ mechanism = ssl3_Alg2Mech(calg);
effKeyBits = cipher_def->key_size * BPB;
/*
* build the server context
*/
iv.data = pwSpec->server.write_iv;
- iv.len = cipher_def->iv_size;
+ iv.len = cipher_def->iv_size;
param = ssl3_ParamFromIV(mechanism, &iv, effKeyBits);
if (param == NULL) {
- ssl_MapLowLevelError(SSL_ERROR_IV_PARAM_FAILURE);
- goto fail;
+ 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);
+ (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);
+ 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;
+ 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;
+ iv.len = cipher_def->iv_size;
param = ssl3_ParamFromIV(mechanism, &iv, effKeyBits);
if (param == NULL) {
- ssl_MapLowLevelError(SSL_ERROR_IV_PARAM_FAILURE);
- goto fail;
+ 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);
+ (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);
+ 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;
+ 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->encode = (SSLCipher)PK11_CipherOp;
+ pwSpec->decode = (SSLCipher)PK11_CipherOp;
pwSpec->encodeContext = (ss->sec.isServer) ? serverContext : clientContext;
pwSpec->decodeContext = (ss->sec.isServer) ? clientContext : serverContext;
@@ -2159,122 +2113,120 @@ ssl3_InitPendingContextsPKCS11(sslSocket *ss)
return SECSuccess;
fail:
- if (serverContext != NULL) PK11_DestroyContext(serverContext, PR_TRUE);
- if (clientContext != NULL) PK11_DestroyContext(clientContext, PR_TRUE);
+ if (serverContext != NULL)
+ PK11_DestroyContext(serverContext, PR_TRUE);
if (pwSpec->client.write_mac_context != NULL) {
- PK11_DestroyContext(pwSpec->client.write_mac_context,PR_TRUE);
- 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;
+ PK11_DestroyContext(pwSpec->server.write_mac_context, PR_TRUE);
+ pwSpec->server.write_mac_context = NULL;
}
return SECFailure;
}
+HASH_HashType
+ssl3_GetTls12HashType(sslSocket *ss)
+{
+ if (ss->ssl3.pwSpec->version < SSL_LIBRARY_VERSION_TLS_1_2) {
+ return HASH_AlgNULL;
+ }
+
+ switch (ss->ssl3.hs.suite_def->prf_hash) {
+ case ssl_hash_sha384:
+ return HASH_AlgSHA384;
+ case ssl_hash_sha256:
+ case ssl_hash_none:
+ /* ssl_hash_none is for pre-1.2 suites, which use SHA-256. */
+ return HASH_AlgSHA256;
+ default:
+ PORT_Assert(0);
+ }
+ return HASH_AlgSHA256;
+}
+
/* 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)
+ * 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. If the old master secret is reused,
- * pms is NULL and the master secret is already in either
- * pwSpec->msItem.len (the bypass case) or pwSpec->master_secret.
- *
- * For the bypass case, pms is NULL.
+ * If the old master secret is reused, pms is NULL and the master secret is
+ * already in pwSpec->master_secret.
*/
SECStatus
ssl3_InitPendingCipherSpec(sslSocket *ss, PK11SymKey *pms)
{
- ssl3CipherSpec * pwSpec;
- ssl3CipherSpec * cwSpec;
- SECStatus rv;
+ ssl3CipherSpec *pwSpec;
+ ssl3CipherSpec *cwSpec;
+ SECStatus rv;
- PORT_Assert( ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss));
+ PORT_Assert(ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss));
- ssl_GetSpecWriteLock(ss); /**************************************/
+ ssl_GetSpecWriteLock(ss); /**************************************/
PORT_Assert(ss->ssl3.prSpec == ss->ssl3.pwSpec);
- pwSpec = ss->ssl3.pwSpec;
- cwSpec = ss->ssl3.cwSpec;
+ 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
+ rv = ssl3_DeriveMasterSecret(ss, pms);
+ if (rv != SECSuccess) {
+ goto done; /* err code set by ssl3_DeriveMasterSecret */
+ }
+ }
if (pwSpec->master_secret) {
- rv = ssl3_DeriveConnectionKeysPKCS11(ss);
- if (rv == SECSuccess) {
- rv = ssl3_InitPendingContextsPKCS11(ss);
- }
+ rv = ssl3_DeriveConnectionKeys(ss);
+ if (rv == SECSuccess) {
+ rv = ssl3_InitPendingContexts(ss);
+ }
} else {
- PORT_Assert(pwSpec->master_secret);
- PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
- rv = SECFailure;
+ PORT_Assert(pwSpec->master_secret);
+ PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
+ rv = SECFailure;
}
if (rv != SECSuccess) {
- goto done;
+ goto done;
}
/* Generic behaviors -- common to all crypto methods */
if (!IS_DTLS(ss)) {
- pwSpec->read_seq_num.high = pwSpec->write_seq_num.high = 0;
+ pwSpec->read_seq_num = pwSpec->write_seq_num = 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;
+ 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 = pwSpec->write_seq_num =
+ (sslSequenceNumber)pwSpec->epoch << 48;
+
+ dtls_InitRecvdRecords(&pwSpec->recvdRecords);
+ }
done:
- ssl_ReleaseSpecWriteLock(ss); /******************************/
+ ssl_ReleaseSpecWriteLock(ss); /******************************/
if (rv != SECSuccess)
- ssl_MapLowLevelError(SSL_ERROR_SESSION_KEY_GEN_FAILURE);
+ 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] = {
+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,
@@ -2284,7 +2236,7 @@ static const unsigned char mac_pad_1 [60] = {
0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
0x36, 0x36, 0x36, 0x36
};
-static const unsigned char mac_pad_2 [60] = {
+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,
@@ -2300,135 +2252,41 @@ static const unsigned char mac_pad_2 [60] = {
*/
static SECStatus
ssl3_ComputeRecordMAC(
- ssl3CipherSpec * spec,
- PRBool useServerMacKey,
+ ssl3CipherSpec *spec,
+ PRBool useServerMacKey,
const unsigned char *header,
- unsigned int headerLen,
- const SSL3Opaque * input,
- int inputLength,
- unsigned char * outbuf,
- unsigned int * outLength)
+ unsigned int headerLen,
+ const SSL3Opaque *input,
+ int inputLength,
+ unsigned char *outbuf,
+ unsigned int *outLength)
{
- const ssl3MACDef * mac_def;
- SECStatus rv;
+ const ssl3MACDef *mac_def;
+ SECStatus rv;
PRINT_BUF(95, (NULL, "frag hash1: header", header, headerLen));
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;
- case ssl_hmac_sha256: /* used with TLS */
- hashObj = HASH_GetRawHashObject(HASH_AlgSHA256);
- break;
- default:
- break;
- }
- if (!hashObj) {
- PORT_Assert(0);
- PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
- return SECFailure;
- }
-
- if (spec->version <= SSL_LIBRARY_VERSION_3_0) {
- unsigned int tempLen;
- unsigned char temp[MAX_MAC_LENGTH];
-
- /* 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, header, headerLen);
- 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, header, headerLen);
- 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, header, headerLen);
- rv |= PK11_DigestOp(mac_context, input, inputLength);
- rv |= PK11_DigestFinal(mac_context, outbuf, outLength, spec->mac_size);
+ *outLength = 0;
+ return SECSuccess;
}
+ PK11Context *mac_context =
+ (useServerMacKey ? spec->server.write_mac_context
+ : spec->client.write_mac_context);
+ rv = PK11_DigestBegin(mac_context);
+ rv |= PK11_DigestOp(mac_context, header, headerLen);
+ 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);
+ rv = SECFailure;
+ ssl_MapLowLevelError(SSL_ERROR_MAC_COMPUTATION_FAILURE);
}
return rv;
}
@@ -2441,51 +2299,45 @@ ssl3_ComputeRecordMAC(
*/
static SECStatus
ssl3_ComputeRecordMACConstantTime(
- ssl3CipherSpec * spec,
- PRBool useServerMacKey,
+ ssl3CipherSpec *spec,
+ PRBool useServerMacKey,
const unsigned char *header,
- unsigned int headerLen,
- const SSL3Opaque * input,
- int inputLen,
- int originalLen,
- unsigned char * outbuf,
- unsigned int * outLen)
-{
- CK_MECHANISM_TYPE macType;
+ unsigned int headerLen,
+ 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;
- PK11SymKey * key;
+ SECItem param, inputItem, outputItem;
+ SECStatus rv;
+ PK11SymKey *key;
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;
+ *outLen = 0;
+ return SECSuccess;
}
macType = CKM_NSS_HMAC_CONSTANT_TIME;
- if (spec->version <= SSL_LIBRARY_VERSION_3_0) {
- macType = CKM_NSS_SSL3_MAC_CONSTANT_TIME;
+ if (spec->version == SSL_LIBRARY_VERSION_3_0) {
+ macType = CKM_NSS_SSL3_MAC_CONSTANT_TIME;
}
params.macAlg = spec->mac_def->mmech;
params.ulBodyTotalLen = originalLen;
- params.pHeader = (unsigned char *) header; /* const cast */
+ params.pHeader = (unsigned char *)header; /* const cast */
params.ulHeaderLen = headerLen;
- param.data = (unsigned char*) &params;
+ param.data = (unsigned char *)&params;
param.len = sizeof(params);
param.type = 0;
- inputItem.data = (unsigned char *) input;
+ inputItem.data = (unsigned char *)input;
inputItem.len = inputLen;
inputItem.type = 0;
@@ -2495,279 +2347,322 @@ ssl3_ComputeRecordMACConstantTime(
key = spec->server.write_mac_key;
if (!useServerMacKey) {
- key = spec->client.write_mac_key;
+ 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;
- }
+ if (PORT_GetError() == SEC_ERROR_INVALID_ALGORITHM) {
+ /* ssl3_ComputeRecordMAC() expects the MAC to have been removed
+ * from the input length already. */
+ return ssl3_ComputeRecordMAC(spec, useServerMacKey,
+ header, headerLen,
+ input, inputLen - spec->mac_size,
+ outbuf, outLen);
+ }
- *outLen = 0;
- rv = SECFailure;
- ssl_MapLowLevelError(SSL_ERROR_MAC_COMPUTATION_FAILURE);
- return rv;
+ *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, header, headerLen,
- input, inputLen, outbuf, outLen);
}
static PRBool
-ssl3_ClientAuthTokenPresent(sslSessionID *sid) {
+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;
+ return PR_TRUE;
}
/* get the slot */
slot = SECMOD_LookupSlot(sid->u.ssl3.clAuthModuleID,
- sid->u.ssl3.clAuthSlotID);
+ 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;
- }
+ !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);
+ 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;
+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;
unsigned int ivLen = 0;
- int cipherBytes = 0;
- unsigned char pseudoHeader[13];
- unsigned int pseudoHeaderLen;
+ unsigned char pseudoHeader[13];
+ unsigned int pseudoHeaderLen;
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;
- }
+ 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) {
+ PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
+ return SECFailure;
+ }
+ rv = PK11_GenerateRandom(wrBuf->buf, ivLen);
+ if (rv != SECSuccess) {
+ ssl_MapLowLevelError(SSL_ERROR_GENERATE_RANDOM_FAILURE);
+ return rv;
+ }
+ rv = cwSpec->encode(cwSpec->encodeContext,
+ wrBuf->buf, /* output */
+ (int *)&wrBuf->len, /* outlen */
+ ivLen, /* max outlen */
+ wrBuf->buf, /* input */
+ ivLen); /* input len */
+ if (rv != SECSuccess || wrBuf->len != 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;
+ int outlen;
+ rv = cwSpec->compressor(cwSpec->compressContext, wrBuf->buf + ivLen,
+ &outlen, wrBuf->space - ivLen, pIn, contentLen);
+ if (rv != SECSuccess)
+ return rv;
+ pIn = wrBuf->buf + ivLen;
+ contentLen = outlen;
}
pseudoHeaderLen = ssl3_BuildRecordPseudoHeader(
- pseudoHeader, cwSpec->write_seq_num, type,
- cwSpec->version >= SSL_LIBRARY_VERSION_TLS_1_0, cwSpec->version,
- isDTLS, contentLen);
+ pseudoHeader, cwSpec->write_seq_num, type,
+ cwSpec->version >= SSL_LIBRARY_VERSION_TLS_1_0, cwSpec->version,
+ isDTLS, contentLen);
PORT_Assert(pseudoHeaderLen <= sizeof(pseudoHeader));
if (cipher_def->type == type_aead) {
- const int nonceLen = cipher_def->explicit_nonce_size;
- const int tagLen = cipher_def->tag_size;
-
- if (headerLen + nonceLen + contentLen + tagLen > wrBuf->space) {
- PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
- return SECFailure;
- }
-
- cipherBytes = contentLen;
- rv = cwSpec->aead(
- isServer ? &cwSpec->server : &cwSpec->client,
- PR_FALSE, /* do encrypt */
- wrBuf->buf + headerLen, /* output */
- &cipherBytes, /* out len */
- wrBuf->space - headerLen, /* max out */
- pIn, contentLen, /* input */
- pseudoHeader, pseudoHeaderLen);
- if (rv != SECSuccess) {
- PORT_SetError(SSL_ERROR_ENCRYPTION_FAILURE);
- return SECFailure;
- }
+ const int nonceLen = cipher_def->explicit_nonce_size;
+ const int tagLen = cipher_def->tag_size;
+
+ if (nonceLen + contentLen + tagLen > wrBuf->space) {
+ PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
+ return SECFailure;
+ }
+
+ rv = cwSpec->aead(
+ isServer ? &cwSpec->server : &cwSpec->client,
+ PR_FALSE, /* do encrypt */
+ wrBuf->buf, /* output */
+ (int *)&wrBuf->len, /* out len */
+ wrBuf->space, /* max out */
+ pIn, contentLen, /* input */
+ pseudoHeader, pseudoHeaderLen);
+ if (rv != SECSuccess) {
+ PORT_SetError(SSL_ERROR_ENCRYPTION_FAILURE);
+ return SECFailure;
+ }
} else {
- /*
- * Add the MAC
- */
- rv = ssl3_ComputeRecordMAC(cwSpec, isServer,
- pseudoHeader, pseudoHeaderLen, 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);
+ /*
+ * Add the MAC
+ */
+ rv = ssl3_ComputeRecordMAC(cwSpec, isServer, pseudoHeader,
+ pseudoHeaderLen, pIn, contentLen,
+ wrBuf->buf + 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[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 + ivLen + p1Len, pIn + p1Len, oddLen);
+ }
+ if (p1Len > 0) {
+ int cipherBytesPart1 = -1;
+ rv = cwSpec->encode(cwSpec->encodeContext,
+ wrBuf->buf + 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;
+ }
+ wrBuf->len += cipherBytesPart1;
+ }
+ if (p2Len > 0) {
+ int cipherBytesPart2 = -1;
+ rv = cwSpec->encode(cwSpec->encodeContext,
+ wrBuf->buf + ivLen + p1Len,
+ &cipherBytesPart2, /* output and actual outLen */
+ p2Len, /* max outlen */
+ wrBuf->buf + 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;
+ }
+ wrBuf->len += cipherBytesPart2;
+ }
+ }
+
+ return SECSuccess;
+}
+
+SECStatus
+ssl_ProtectRecord(sslSocket *ss, ssl3CipherSpec *cwSpec,
+ PRBool capRecordVersion, SSL3ContentType type,
+ const SSL3Opaque *pIn, PRUint32 contentLen, sslBuffer *wrBuf)
+{
+ const ssl3BulkCipherDef *cipher_def = cwSpec->cipher_def;
+ PRUint16 headerLen;
+ sslBuffer protBuf;
+ SSL3ProtocolVersion version = cwSpec->version;
+ PRBool isTLS13;
+ PRUint8 *ptr = wrBuf->buf;
+ SECStatus rv;
+
+ if (ss->ssl3.hs.shortHeaders) {
+ PORT_Assert(!IS_DTLS(ss));
+ PORT_Assert(ss->version >= SSL_LIBRARY_VERSION_TLS_1_3);
+ headerLen = TLS13_RECORD_HEADER_LENGTH_SHORT;
} else {
- SSL3ProtocolVersion version = cwSpec->version;
+ headerLen = IS_DTLS(ss) ? DTLS_RECORD_HEADER_LENGTH : SSL3_RECORD_HEADER_LENGTH;
+ }
+ protBuf.buf = wrBuf->buf + headerLen;
+ protBuf.len = 0;
+ protBuf.space = wrBuf->space - headerLen;
+
+ PORT_Assert(cipher_def->max_records <= RECORD_SEQ_MAX);
+ if ((cwSpec->write_seq_num & RECORD_SEQ_MAX) >= cipher_def->max_records) {
+ SSL_TRC(3, ("%d: SSL[-]: write sequence number at limit 0x%0llx",
+ SSL_GETPID(), cwSpec->write_seq_num));
+ PORT_SetError(SSL_ERROR_TOO_MANY_RECORDS);
+ return SECFailure;
+ }
- 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);
+ isTLS13 = (PRBool)(cwSpec->version >= SSL_LIBRARY_VERSION_TLS_1_3);
+
+#ifdef UNSAFE_FUZZER_MODE
+ rv = Null_Cipher(NULL, protBuf.buf, (int *)&protBuf.len, protBuf.space,
+ pIn, contentLen);
+#else
+ if (isTLS13) {
+ rv = tls13_ProtectRecord(ss, cwSpec, type, pIn, contentLen, &protBuf);
+ } else {
+ rv = ssl3_CompressMACEncryptRecord(cwSpec, ss->sec.isServer,
+ IS_DTLS(ss), capRecordVersion, type,
+ pIn, contentLen, &protBuf);
+ }
+#endif
+ if (rv != SECSuccess) {
+ return SECFailure; /* error was set */
}
- ssl3_BumpSequenceNumber(&cwSpec->write_seq_num);
+ PORT_Assert(protBuf.len <= MAX_FRAGMENT_LENGTH + (isTLS13 ? 256 : 1024));
+ wrBuf->len = protBuf.len + headerLen;
+
+ if (ss->ssl3.hs.shortHeaders) {
+ PORT_Assert(!IS_DTLS(ss)); /* Decoder not yet implemented. */
+ (void)ssl_EncodeUintX(0x8000 | protBuf.len, 2, ptr);
+ } else {
+#ifndef UNSAFE_FUZZER_MODE
+ if (isTLS13 && cipher_def->calg != ssl_calg_null) {
+ *ptr++ = content_application_data;
+ } else
+#endif
+ {
+ *ptr++ = type;
+ }
+
+ if (IS_DTLS(ss)) {
+ version = isTLS13 ? SSL_LIBRARY_VERSION_TLS_1_1 : version;
+ version = dtls_TLSVersionToDTLSVersion(version);
+
+ ptr = ssl_EncodeUintX(version, 2, ptr);
+ ptr = ssl_EncodeUintX(cwSpec->write_seq_num, 8, ptr);
+ } else {
+ if (capRecordVersion || isTLS13) {
+ version = PR_MIN(SSL_LIBRARY_VERSION_TLS_1_0, version);
+ }
+ ptr = ssl_EncodeUintX(version, 2, ptr);
+ }
+ (void)ssl_EncodeUintX(protBuf.len, 2, ptr);
+ }
+ ++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.
+ * 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.
*
@@ -2796,24 +2691,24 @@ ssl3_CompressMACEncryptRecord(ssl3CipherSpec * cwSpec,
* 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;
+ssl3_SendRecord(sslSocket *ss,
+ ssl3CipherSpec *cwSpec, /* non-NULL for DTLS retransmits */
+ 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));
+ SSL_GETPID(), ss->fd, ssl3_DecodeContentType(type),
+ nIn));
PRINT_BUF(50, (ss, "Send record (plain text)", pIn, nIn));
- PORT_Assert( ss->opt.noLocks || ssl_HaveXmitBufLock(ss) );
+ PORT_Assert(ss->opt.noLocks || ssl_HaveXmitBufLock(ss));
if (ss->ssl3.fatalAlertSent) {
SSL_TRC(3, ("%d: SSL3[%d] Suppress write, fatal alert already sent",
@@ -2824,180 +2719,172 @@ ssl3_SendRecord( sslSocket * 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);
+ /* 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. */
- }
+ /* 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;
+ 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;
+ 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 = ssl_ProtectRecord(ss, ss->ssl3.cwSpec, 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 = ssl_ProtectRecord(ss, ss->ssl3.cwSpec, 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 (cwSpec) {
+ /* cwSpec can only be set for retransmissions of DTLS handshake
+ * messages. */
+ PORT_Assert(IS_DTLS(ss) &&
+ (type == content_handshake ||
+ type == content_change_cipher_spec));
+ } else {
+ cwSpec = ss->ssl3.cwSpec;
+ }
+
+ rv = ssl_ProtectRecord(ss, cwSpec, !IS_DTLS(ss) && capRecordVersion,
+ 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;
}
@@ -3009,87 +2896,86 @@ spec_locked_loser:
*/
int
ssl3_SendApplicationData(sslSocket *ss, const unsigned char *in,
- PRInt32 len, PRInt32 flags)
+ PRInt32 len, PRInt32 flags)
{
- PRInt32 totalSent = 0;
- PRInt32 discarded = 0;
+ PRInt32 totalSent = 0;
+ PRInt32 discarded = 0;
- PORT_Assert( ss->opt.noLocks || ssl_HaveXmitBufLock(ss) );
+ 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)));
+ PORT_Assert(!(flags & ssl_SEND_FLAG_NO_RETRANSMIT));
if (len < 0 || !in) {
- PORT_SetError(PR_INVALID_ARGUMENT_ERROR);
- return SECFailure;
+ 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;
+ 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;
+ 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;
- }
+ 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, NULL, 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;
- }
+ /* 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;
}
@@ -3108,7 +2994,7 @@ ssl3_SendApplicationData(sslSocket *ss, const unsigned char *in,
* ssl3_SendHelloRequest(), ssl3_SendServerHelloDone(),
* ssl3_SendFinished(),
*/
-static SECStatus
+SECStatus
ssl3_FlushHandshake(sslSocket *ss, PRInt32 flags)
{
if (IS_DTLS(ss)) {
@@ -3130,37 +3016,37 @@ ssl3_FlushHandshakeMessages(sslSocket *ss, PRInt32 flags)
static const PRInt32 allowedFlags = ssl_SEND_FLAG_FORCE_INTO_BUFFER |
ssl_SEND_FLAG_CAP_RECORD_VERSION;
PRInt32 count = -1;
- SECStatus rv = SECSuccess;
+ SECStatus rv;
- PORT_Assert( ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss));
- PORT_Assert( ss->opt.noLocks || ssl_HaveXmitBufLock(ss) );
+ 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;
+ return SECSuccess;
/* only these flags are allowed */
PORT_Assert(!(flags & ~allowedFlags));
if ((flags & ~allowedFlags) != 0) {
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- rv = SECFailure;
- } else {
- count = ssl3_SendRecord(ss, 0, content_handshake, ss->sec.ci.sendBuf.buf,
- ss->sec.ci.sendBuf.len, flags);
+ PORT_SetError(SEC_ERROR_INVALID_ARGS);
+ return SECFailure;
}
+ count = ssl3_SendRecord(ss, NULL, content_handshake,
+ ss->sec.ci.sendBuf.buf,
+ ss->sec.ci.sendBuf.len, flags);
if (count < 0) {
- int err = PORT_GetError();
- PORT_Assert(err != PR_WOULD_BLOCK_ERROR);
- if (err == PR_WOULD_BLOCK_ERROR) {
- PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
- }
+ int err = PORT_GetError();
+ PORT_Assert(err != PR_WOULD_BLOCK_ERROR);
+ if (err == PR_WOULD_BLOCK_ERROR) {
+ PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
+ }
rv = SECFailure;
} else if ((unsigned int)count < ss->sec.ci.sendBuf.len) {
- /* short write should never happen */
- PORT_Assert((unsigned int)count >= ss->sec.ci.sendBuf.len);
- PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
- rv = SECFailure;
+ /* short write should never happen */
+ PORT_Assert((unsigned int)count >= ss->sec.ci.sendBuf.len);
+ PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
+ rv = SECFailure;
} else {
- rv = SECSuccess;
+ rv = SECSuccess;
}
/* Whether we succeeded or failed, toss the old handshake data. */
@@ -3174,43 +3060,34 @@ ssl3_FlushHandshakeMessages(sslSocket *ss, PRInt32 flags)
* Returns SECFailure if the application has required client auth.
* SECSuccess otherwise.
*/
-static SECStatus
+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
+ * 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;
+ (!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);
+ ss->sec.uncache(ss->sec.ci.sid);
+ SSL3_SendAlert(ss, alert_fatal, bad_certificate);
- lower = ss->fd->lower;
+ lower = ss->fd->lower;
#ifdef _WIN32
- lower->methods->shutdown(lower, PR_SHUTDOWN_SEND);
+ lower->methods->shutdown(lower, PR_SHUTDOWN_SEND);
#else
- lower->methods->shutdown(lower, PR_SHUTDOWN_BOTH);
+ lower->methods->shutdown(lower, PR_SHUTDOWN_BOTH);
#endif
- PORT_SetError(SSL_ERROR_NO_CERTIFICATE);
- return SECFailure;
+ PORT_SetError(SSL_ERROR_NO_CERTIFICATE);
+ return SECFailure;
}
return SECSuccess;
}
@@ -3221,59 +3098,59 @@ ssl3_HandleNoCertificate(sslSocket *ss)
/*
** Acquires both handshake and XmitBuf locks.
-** Called from: ssl3_IllegalParameter <-
-** ssl3_HandshakeFailure <-
-** ssl3_HandleAlert <- ssl3_HandleRecord.
+** Called from: ssl3_IllegalParameter <-
+** ssl3_HandshakeFailure <-
+** ssl3_HandleAlert <- ssl3_HandleRecord.
** ssl3_HandleChangeCipherSpecs <- ssl3_HandleRecord
** ssl3_ConsumeHandshakeVariable <-
-** ssl3_HandleHelloRequest <-
-** ssl3_HandleServerHello <-
+** ssl3_HandleHelloRequest <-
+** ssl3_HandleServerHello <-
** ssl3_HandleServerKeyExchange <-
** ssl3_HandleCertificateRequest <-
** ssl3_HandleServerHelloDone <-
-** ssl3_HandleClientHello <-
+** ssl3_HandleClientHello <-
** ssl3_HandleV2ClientHello <-
** ssl3_HandleCertificateVerify <-
** ssl3_HandleClientKeyExchange <-
-** ssl3_HandleCertificate <-
-** ssl3_HandleFinished <-
+** ssl3_HandleCertificate <-
+** ssl3_HandleFinished <-
** ssl3_HandleHandshakeMessage <-
-** ssl3_HandleRecord <-
+** ssl3_HandlePostHelloHandshakeMessage <-
+** ssl3_HandleRecord <-
**
*/
SECStatus
SSL3_SendAlert(sslSocket *ss, SSL3AlertLevel level, SSL3AlertDescription desc)
{
- PRUint8 bytes[2];
- SECStatus rv;
+ PRUint8 bytes[2];
+ SECStatus rv;
SSL_TRC(3, ("%d: SSL3[%d]: send alert record, level=%d desc=%d",
- SSL_GETPID(), ss->fd, level, desc));
+ 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);
- }
+ if (!ss->opt.noCache && ss->sec.ci.sid) {
+ 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;
+ PRInt32 sent;
+ sent = ssl3_SendRecord(ss, NULL, content_alert, bytes, 2,
+ (desc == no_certificate) ? ssl_SEND_FLAG_FORCE_INTO_BUFFER : 0);
+ rv = (sent >= 0) ? SECSuccess : (SECStatus)sent;
}
if (level == alert_fatal) {
ss->ssl3.fatalAlertSent = PR_TRUE;
}
ssl_ReleaseXmitBufLock(ss);
ssl_ReleaseSSL3HandshakeLock(ss);
- return rv; /* error set by ssl3_FlushHandshake or ssl3_SendRecord */
+ return rv; /* error set by ssl3_FlushHandshake or ssl3_SendRecord */
}
/*
@@ -3284,7 +3161,7 @@ ssl3_IllegalParameter(sslSocket *ss)
{
(void)SSL3_SendAlert(ss, alert_fatal, illegal_parameter);
PORT_SetError(ss->sec.isServer ? SSL_ERROR_BAD_CLIENT
- : SSL_ERROR_BAD_SERVER );
+ : SSL_ERROR_BAD_SERVER);
return SECFailure;
}
@@ -3295,56 +3172,67 @@ 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 );
+ PORT_SetError(ss->sec.isServer ? SSL_ERROR_BAD_CLIENT
+ : SSL_ERROR_BAD_SERVER);
return SECFailure;
}
-static void
-ssl3_SendAlertForCertError(sslSocket * ss, PRErrorCode errCode)
+void
+ssl3_SendAlertForCertError(sslSocket *ss, PRErrorCode errCode)
{
- SSL3AlertDescription desc = bad_certificate;
+ 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;
+ 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));
+ SSL_GETPID(), ss->fd, errCode));
- (void) SSL3_SendAlert(ss, alert_fatal, desc);
+ (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 );
+ (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;
}
@@ -3354,102 +3242,170 @@ ssl3_DecodeError(sslSocket *ss)
static SECStatus
ssl3_HandleAlert(sslSocket *ss, sslBuffer *buf)
{
- SSL3AlertLevel level;
+ SSL3AlertLevel level;
SSL3AlertDescription desc;
- int error;
+ int error;
- PORT_Assert( ss->opt.noLocks || ssl_HaveRecvBufLock(ss) );
- PORT_Assert( ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss) );
+ 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;
+ (void)ssl3_DecodeError(ss);
+ PORT_SetError(SSL_ERROR_RX_MALFORMED_ALERT);
+ return SECFailure;
}
level = (SSL3AlertLevel)buf->buf[0];
- desc = (SSL3AlertDescription)buf->buf[1];
+ 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));
+ 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;
- case inappropriate_fallback:
- error = SSL_ERROR_INAPPROPRIATE_FALLBACK_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;
+ 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;
+ case inappropriate_fallback:
+ error = SSL_ERROR_INAPPROPRIATE_FALLBACK_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 missing_extension:
+ error = SSL_ERROR_MISSING_EXTENSION_ALERT;
+ break;
+ 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;
+ case end_of_early_data:
+ error = SSL_ERROR_END_OF_EARLY_DATA_ALERT;
+ break;
+ default:
+ error = SSL_ERROR_RX_UNKNOWN_ALERT;
+ break;
+ }
+ if ((ss->version >= SSL_LIBRARY_VERSION_TLS_1_3) &&
+ (ss->ssl3.hs.ws != wait_server_hello)) {
+ /* TLS 1.3 requires all but "end of data" alerts to be
+ * treated as fatal. */
+ switch (desc) {
+ case close_notify:
+ case user_canceled:
+ case end_of_early_data:
+ break;
+ default:
+ level = alert_fatal;
+ }
}
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 (!ss->opt.noCache) {
+ 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 == end_of_early_data) {
+ return tls13_HandleEndOfEarlyData(ss);
}
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;
+ /* 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;
+ PORT_Assert(ss->sec.isServer);
+ ss->ssl3.hs.ws = wait_client_key;
+ rv = ssl3_HandleNoCertificate(ss);
+ return rv;
}
return SECSuccess;
}
@@ -3467,61 +3423,60 @@ ssl3_HandleAlert(sslSocket *ss, sslBuffer *buf)
static SECStatus
ssl3_SendChangeCipherSpecs(sslSocket *ss)
{
- PRUint8 change = change_cipher_spec_choice;
- ssl3CipherSpec * pwSpec;
- SECStatus rv;
- PRInt32 sent;
+ PRUint8 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));
+ SSL_GETPID(), ss->fd));
- PORT_Assert( ss->opt.noLocks || ssl_HaveXmitBufLock(ss) );
- PORT_Assert( ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss));
+ 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 */
+ 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 */
- }
+ sent = ssl3_SendRecord(ss, NULL, 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;
- }
+ 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;
+ 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 ));
+ 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);
- }
+ 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 */
+ rv = dtls_StartHolddownTimer(ss);
+ }
}
ssl_ReleaseSpecWriteLock(ss); /**************************************/
- return SECSuccess;
+ return rv;
}
/* Called from ssl3_HandleRecord.
@@ -3533,65 +3488,124 @@ ssl3_SendChangeCipherSpecs(sslSocket *ss)
static SECStatus
ssl3_HandleChangeCipherSpecs(sslSocket *ss, sslBuffer *buf)
{
- ssl3CipherSpec * prSpec;
- SSL3WaitState ws = ss->ssl3.hs.ws;
+ 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) );
+ 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));
+ SSL_GETPID(), ss->fd));
if (ws != wait_change_cipher) {
- if (IS_DTLS(ss)) {
- /* Ignore this because it's out of order. */
- SSL_TRC(3, ("%d: SSL3[%d]: discard out of order "
- "DTLS change_cipher_spec",
- SSL_GETPID(), ss->fd));
- buf->len = 0;
- return SECSuccess;
- }
- (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;
+ if (IS_DTLS(ss)) {
+ /* Ignore this because it's out of order. */
+ SSL_TRC(3, ("%d: SSL3[%d]: discard out of order "
+ "DTLS change_cipher_spec",
+ SSL_GETPID(), ss->fd));
+ buf->len = 0;
+ return SECSuccess;
+ }
+ (void)SSL3_SendAlert(ss, alert_fatal, unexpected_message);
+ PORT_SetError(SSL_ERROR_RX_UNEXPECTED_CHANGE_CIPHER);
+ return SECFailure;
+ }
+ /* Handshake messages should not span ChangeCipherSpec. */
+ if (ss->ssl3.hs.header_bytes) {
+ (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;
+ /* 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;
+ ssl_GetSpecWriteLock(ss); /*************************************/
+ prSpec = ss->ssl3.prSpec;
- ss->ssl3.prSpec = ss->ssl3.crSpec;
- ss->ssl3.crSpec = prSpec;
- ss->ssl3.hs.ws = wait_finished;
+ 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 ));
+ 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*/);
+ ssl3_DestroyCipherSpec(ss->ssl3.prSpec, PR_FALSE /*freeSrvName*/);
}
- ssl_ReleaseSpecWriteLock(ss); /*************************************/
+ ssl_ReleaseSpecWriteLock(ss); /*************************************/
return SECSuccess;
}
+static CK_MECHANISM_TYPE
+ssl3_GetMgfMechanismByHashType(SSLHashType hash)
+{
+ switch (hash) {
+ case ssl_hash_sha256:
+ return CKG_MGF1_SHA256;
+ case ssl_hash_sha384:
+ return CKG_MGF1_SHA384;
+ case ssl_hash_sha512:
+ return CKG_MGF1_SHA512;
+ default:
+ PORT_Assert(0);
+ }
+ return CKG_MGF1_SHA256;
+}
+
+/* Function valid for >= TLS 1.2, only. */
+static CK_MECHANISM_TYPE
+ssl3_GetHashMechanismByHashType(SSLHashType hashType)
+{
+ switch (hashType) {
+ case ssl_hash_sha512:
+ return CKM_SHA512;
+ case ssl_hash_sha384:
+ return CKM_SHA384;
+ case ssl_hash_sha256:
+ case ssl_hash_none:
+ /* ssl_hash_none is for pre-1.2 suites, which use SHA-256. */
+ return CKM_SHA256;
+ case ssl_hash_sha1:
+ return CKM_SHA_1;
+ default:
+ PORT_Assert(0);
+ }
+ return CKM_SHA256;
+}
+
+/* Function valid for >= TLS 1.2, only. */
+static CK_MECHANISM_TYPE
+ssl3_GetPrfHashMechanism(sslSocket *ss)
+{
+ return ssl3_GetHashMechanismByHashType(ss->ssl3.hs.suite_def->prf_hash);
+}
+
+static SSLHashType
+ssl3_GetSuitePrfHash(sslSocket *ss)
+{
+ /* ssl_hash_none is for pre-1.2 suites, which use SHA-256. */
+ if (ss->ssl3.hs.suite_def->prf_hash == ssl_hash_none) {
+ return ssl_hash_sha256;
+ }
+ return ss->ssl3.hs.suite_def->prf_hash;
+}
+
/* This method completes the derivation of the MS from the PMS.
**
** 1. Derive the MS, if possible, else return an error.
@@ -3657,67 +3671,71 @@ static SECStatus
ssl3_ComputeMasterSecretInt(sslSocket *ss, PK11SymKey *pms,
PK11SymKey **msp)
{
- 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));
- PRBool isTLS12=
- (PRBool)(isTLS && pwSpec->version >= SSL_LIBRARY_VERSION_TLS_1_2);
+ ssl3CipherSpec *pwSpec = ss->ssl3.pwSpec;
+ unsigned char *cr = (unsigned char *)&ss->ssl3.hs.client_random;
+ unsigned char *sr = (unsigned char *)&ss->ssl3.hs.server_random;
+ PRBool isTLS = (PRBool)(pwSpec->version > SSL_LIBRARY_VERSION_3_0);
+ PRBool isTLS12 =
+ (PRBool)(isTLS && pwSpec->version >= SSL_LIBRARY_VERSION_TLS_1_2);
/*
* 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, and does not expect to return the version.
*/
- PRBool isDH = (PRBool) ((ss->ssl3.hs.kea_def->exchKeyType == kt_dh) ||
- (ss->ssl3.hs.kea_def->exchKeyType == kt_ecdh));
+ PRBool isDH = (PRBool)((ss->ssl3.hs.kea_def->exchKeyType == ssl_kea_dh) ||
+ (ss->ssl3.hs.kea_def->exchKeyType == ssl_kea_ecdh));
CK_MECHANISM_TYPE master_derive;
CK_MECHANISM_TYPE key_derive;
- SECItem params;
- CK_FLAGS keyFlags;
- CK_VERSION pms_version;
- CK_VERSION *pms_version_ptr = NULL;
+ SECItem params;
+ CK_FLAGS keyFlags;
+ CK_VERSION pms_version;
+ CK_VERSION *pms_version_ptr = NULL;
/* master_params may be used as a CK_SSL3_MASTER_KEY_DERIVE_PARAMS */
CK_TLS12_MASTER_KEY_DERIVE_PARAMS master_params;
- unsigned int master_params_len;
+ unsigned int master_params_len;
if (isTLS12) {
- if(isDH) master_derive = CKM_TLS12_MASTER_KEY_DERIVE_DH;
- else master_derive = CKM_TLS12_MASTER_KEY_DERIVE;
- key_derive = CKM_TLS12_KEY_AND_MAC_DERIVE;
- keyFlags = CKF_SIGN | CKF_VERIFY;
+ if (isDH)
+ master_derive = CKM_TLS12_MASTER_KEY_DERIVE_DH;
+ else
+ master_derive = CKM_TLS12_MASTER_KEY_DERIVE;
+ key_derive = CKM_TLS12_KEY_AND_MAC_DERIVE;
+ keyFlags = CKF_SIGN | CKF_VERIFY;
} else 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;
+ 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 (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 (!isDH) {
pms_version_ptr = &pms_version;
}
- master_params.pVersion = pms_version_ptr;
- master_params.RandomInfo.pClientRandom = cr;
+ master_params.pVersion = pms_version_ptr;
+ master_params.RandomInfo.pClientRandom = cr;
master_params.RandomInfo.ulClientRandomLen = SSL3_RANDOM_LENGTH;
- master_params.RandomInfo.pServerRandom = sr;
+ master_params.RandomInfo.pServerRandom = sr;
master_params.RandomInfo.ulServerRandomLen = SSL3_RANDOM_LENGTH;
if (isTLS12) {
- master_params.prfHashMechanism = CKM_SHA256;
+ master_params.prfHashMechanism = ssl3_GetPrfHashMechanism(ss);
master_params_len = sizeof(CK_TLS12_MASTER_KEY_DERIVE_PARAMS);
} else {
/* prfHashMechanism is not relevant with this PRF */
master_params_len = sizeof(CK_SSL3_MASTER_KEY_DERIVE_PARAMS);
}
- params.data = (unsigned char *) &master_params;
- params.len = master_params_len;
+ params.data = (unsigned char *)&master_params;
+ params.len = master_params_len;
return ssl3_ComputeMasterSecretFinish(ss, master_derive, key_derive,
pms_version_ptr, &params,
@@ -3742,8 +3760,8 @@ tls_ComputeExtendedMasterSecretInt(sslSocket *ss, PK11SymKey *pms,
/*
* TODO(ekr@rtfm.com): Verify that the slot can handle this key expansion
* mode. Bug 1198298 */
- PRBool isDH = (PRBool) ((ss->ssl3.hs.kea_def->exchKeyType == kt_dh) ||
- (ss->ssl3.hs.kea_def->exchKeyType == kt_ecdh));
+ PRBool isDH = (PRBool)((ss->ssl3.hs.kea_def->exchKeyType == ssl_kea_dh) ||
+ (ss->ssl3.hs.kea_def->exchKeyType == ssl_kea_ecdh));
CK_MECHANISM_TYPE master_derive;
CK_MECHANISM_TYPE key_derive;
SECItem params;
@@ -3754,7 +3772,7 @@ tls_ComputeExtendedMasterSecretInt(sslSocket *ss, PK11SymKey *pms,
rv = ssl3_ComputeHandshakeHashes(ss, pwSpec, &hashes, 0);
if (rv != SECSuccess) {
- PORT_Assert(0); /* Should never fail */
+ PORT_Assert(0); /* Should never fail */
ssl_MapLowLevelError(SSL_ERROR_SESSION_KEY_GEN_FAILURE);
return SECFailure;
}
@@ -3767,20 +3785,20 @@ tls_ComputeExtendedMasterSecretInt(sslSocket *ss, PK11SymKey *pms,
}
if (pwSpec->version >= SSL_LIBRARY_VERSION_TLS_1_2) {
- /* TLS 1.2 */
- extended_master_params.prfHashMechanism = CKM_SHA256;
+ /* TLS 1.2+ */
+ extended_master_params.prfHashMechanism = ssl3_GetPrfHashMechanism(ss);
key_derive = CKM_TLS12_KEY_AND_MAC_DERIVE;
} else {
/* TLS < 1.2 */
extended_master_params.prfHashMechanism = CKM_TLS_PRF;
- key_derive = CKM_TLS_KEY_AND_MAC_DERIVE;
+ key_derive = CKM_TLS_KEY_AND_MAC_DERIVE;
}
extended_master_params.pVersion = pms_version_ptr;
extended_master_params.pSessionHash = hashes.u.raw;
extended_master_params.ulSessionHashLen = hashes.len;
- params.data = (unsigned char *) &extended_master_params;
+ params.data = (unsigned char *)&extended_master_params;
params.len = sizeof extended_master_params;
return ssl3_ComputeMasterSecretFinish(ss, master_derive, key_derive,
@@ -3788,7 +3806,6 @@ tls_ComputeExtendedMasterSecretInt(sslSocket *ss, PK11SymKey *pms,
keyFlags, pms, msp);
}
-
/* Wrapper method to compute the master secret and return it in |*msp|.
**
** Called from ssl3_ComputeMasterSecret
@@ -3821,11 +3838,11 @@ static SECStatus
ssl3_DeriveMasterSecret(sslSocket *ss, PK11SymKey *pms)
{
SECStatus rv;
- PK11SymKey* ms = NULL;
+ PK11SymKey *ms = NULL;
ssl3CipherSpec *pwSpec = ss->ssl3.pwSpec;
- PORT_Assert( ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss));
- PORT_Assert( ss->opt.noLocks || ssl_HaveSpecWriteLock(ss));
+ 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 (pms) {
@@ -3835,43 +3852,17 @@ ssl3_DeriveMasterSecret(sslSocket *ss, PK11SymKey *pms)
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) {
- 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_SendRSAClientKeyExchange (for Full handshake)
+ * ssl3_SendDHClientKeyExchange (for Full handshake)
* ssl3_HandleClientKeyExchange (for Full handshake)
* ssl3_HandleServerHello (for session restart)
* ssl3_HandleClientHello (for session restart)
@@ -3880,279 +3871,239 @@ ssl3_DeriveMasterSecret(sslSocket *ss, PK11SymKey *pms)
*
*/
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));
- PRBool isTLS12=
- (PRBool)(isTLS && pwSpec->version >= SSL_LIBRARY_VERSION_TLS_1_2);
- /* following variables used in PKCS11 path */
+ssl3_DeriveConnectionKeys(sslSocket *ss)
+{
+ ssl3CipherSpec *pwSpec = ss->ssl3.pwSpec;
+ unsigned char *cr = (unsigned char *)&ss->ssl3.hs.client_random;
+ unsigned char *sr = (unsigned char *)&ss->ssl3.hs.server_random;
+ PRBool isTLS = (PRBool)(pwSpec->version > SSL_LIBRARY_VERSION_3_0);
+ PRBool isTLS12 =
+ (PRBool)(isTLS && pwSpec->version >= SSL_LIBRARY_VERSION_TLS_1_2);
const ssl3BulkCipherDef *cipher_def = pwSpec->cipher_def;
- PK11SlotInfo * slot = NULL;
- PK11SymKey * symKey = NULL;
- void * pwArg = ss->pkcs11PinArg;
- int keySize;
+ PK11SlotInfo *slot = NULL;
+ PK11SymKey *symKey = NULL;
+ void *pwArg = ss->pkcs11PinArg;
+ int keySize;
CK_TLS12_KEY_MAT_PARAMS key_material_params; /* may be used as a
- * CK_SSL3_KEY_MAT_PARAMS */
- unsigned int key_material_params_len;
- 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));
+ * CK_SSL3_KEY_MAT_PARAMS */
+ unsigned int key_material_params_len;
+ 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;
+ 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.ulMacSizeInBits = pwSpec->mac_size * BPB;
+ key_material_params.ulKeySizeInBits = cipher_def->secret_key_size * BPB;
+ key_material_params.ulIVSizeInBits = cipher_def->iv_size * BPB;
if (cipher_def->type == type_block &&
- pwSpec->version >= SSL_LIBRARY_VERSION_TLS_1_1) {
- /* Block ciphers in >= TLS 1.1 use a per-record, explicit IV. */
- key_material_params.ulIVSizeInBits = 0;
- memset(pwSpec->client.write_iv, 0, cipher_def->iv_size);
- memset(pwSpec->server.write_iv, 0, cipher_def->iv_size);
+ pwSpec->version >= SSL_LIBRARY_VERSION_TLS_1_1) {
+ /* Block ciphers in >= TLS 1.1 use a per-record, explicit IV. */
+ key_material_params.ulIVSizeInBits = 0;
+ memset(pwSpec->client.write_iv, 0, cipher_def->iv_size);
+ memset(pwSpec->server.write_iv, 0, cipher_def->iv_size);
}
- key_material_params.bIsExport = (CK_BBOOL)(kea_def->is_limited);
-
- key_material_params.RandomInfo.pClientRandom = cr;
+ key_material_params.bIsExport = PR_FALSE;
+ key_material_params.RandomInfo.pClientRandom = cr;
key_material_params.RandomInfo.ulClientRandomLen = SSL3_RANDOM_LENGTH;
- key_material_params.RandomInfo.pServerRandom = sr;
+ key_material_params.RandomInfo.pServerRandom = sr;
key_material_params.RandomInfo.ulServerRandomLen = SSL3_RANDOM_LENGTH;
- key_material_params.pReturnedKeyMaterial = &returnedKeys;
+ key_material_params.pReturnedKeyMaterial = &returnedKeys;
returnedKeys.pIVClient = pwSpec->client.write_iv;
returnedKeys.pIVServer = pwSpec->server.write_iv;
- keySize = cipher_def->key_size;
+ keySize = cipher_def->key_size;
if (skipKeysAndIVs) {
- keySize = 0;
+ keySize = 0;
key_material_params.ulKeySizeInBits = 0;
- key_material_params.ulIVSizeInBits = 0;
- returnedKeys.pIVClient = NULL;
- returnedKeys.pIVServer = NULL;
+ 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;
+ bulk_mechanism = ssl3_Alg2Mech(calg);
if (isTLS12) {
- key_derive = CKM_TLS12_KEY_AND_MAC_DERIVE;
- key_material_params.prfHashMechanism = CKM_SHA256;
- key_material_params_len = sizeof(CK_TLS12_KEY_MAT_PARAMS);
+ key_derive = CKM_TLS12_KEY_AND_MAC_DERIVE;
+ key_material_params.prfHashMechanism = ssl3_GetPrfHashMechanism(ss);
+ key_material_params_len = sizeof(CK_TLS12_KEY_MAT_PARAMS);
} else if (isTLS) {
- key_derive = CKM_TLS_KEY_AND_MAC_DERIVE;
- key_material_params_len = sizeof(CK_SSL3_KEY_MAT_PARAMS);
+ key_derive = CKM_TLS_KEY_AND_MAC_DERIVE;
+ key_material_params_len = sizeof(CK_SSL3_KEY_MAT_PARAMS);
} else {
- key_derive = CKM_SSL3_KEY_AND_MAC_DERIVE;
- key_material_params_len = sizeof(CK_SSL3_KEY_MAT_PARAMS);
+ key_derive = CKM_SSL3_KEY_AND_MAC_DERIVE;
+ key_material_params_len = sizeof(CK_SSL3_KEY_MAT_PARAMS);
}
params.data = (unsigned char *)&key_material_params;
- params.len = key_material_params_len;
+ params.len = key_material_params_len;
/* 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;
+ 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);
+ 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 */
+ 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 */
+ 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 */
- }
+ 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);
+ if (symKey)
+ PK11_FreeSymKey(symKey);
ssl_MapLowLevelError(SSL_ERROR_SESSION_KEY_GEN_FAILURE);
return SECFailure;
}
/* ssl3_InitHandshakeHashes creates handshake hash contexts and hashes in
- * buffered messages in ss->ssl3.hs.messages. */
-static SECStatus
+ * buffered messages in ss->ssl3.hs.messages. Called from
+ * ssl3_NegotiateCipherSuite(), tls13_HandleClientHelloPart2(),
+ * and ssl3_HandleServerHello. */
+SECStatus
ssl3_InitHandshakeHashes(sslSocket *ss)
{
- SSL_TRC(30,("%d: SSL3[%d]: start handshake hashes", SSL_GETPID(), ss->fd));
+ SSL_TRC(30, ("%d: SSL3[%d]: start handshake hashes", SSL_GETPID(), ss->fd));
PORT_Assert(ss->ssl3.hs.hashType == handshake_hash_unknown);
-#ifndef NO_PKCS11_BYPASS
- if (ss->opt.bypassPKCS11) {
- PORT_Assert(!ss->ssl3.hs.sha_obj && !ss->ssl3.hs.sha_clone);
- if (ss->version >= SSL_LIBRARY_VERSION_TLS_1_2) {
- /* If we ever support ciphersuites where the PRF hash isn't SHA-256
- * then this will need to be updated. */
- ss->ssl3.hs.sha_obj = HASH_GetRawHashObject(HASH_AlgSHA256);
- if (!ss->ssl3.hs.sha_obj) {
- ssl_MapLowLevelError(SSL_ERROR_DIGEST_FAILURE);
- return SECFailure;
- }
- ss->ssl3.hs.sha_clone = (void (*)(void *, void *))SHA256_Clone;
- ss->ssl3.hs.hashType = handshake_hash_single;
- ss->ssl3.hs.sha_obj->begin(ss->ssl3.hs.sha_cx);
- } else {
- ss->ssl3.hs.hashType = handshake_hash_combo;
- MD5_Begin((MD5Context *)ss->ssl3.hs.md5_cx);
- SHA1_Begin((SHA1Context *)ss->ssl3.hs.sha_cx);
- }
- } else
-#endif
- {
- PORT_Assert(!ss->ssl3.hs.md5 && !ss->ssl3.hs.sha);
- /*
- * 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 ...
- */
- if (ss->version >= SSL_LIBRARY_VERSION_TLS_1_2) {
- /* If we ever support ciphersuites where the PRF hash isn't SHA-256
- * then this will need to be updated. */
- ss->ssl3.hs.sha = PK11_CreateDigestContext(SEC_OID_SHA256);
- if (ss->ssl3.hs.sha == NULL) {
- ssl_MapLowLevelError(SSL_ERROR_SHA_DIGEST_FAILURE);
- return SECFailure;
- }
- ss->ssl3.hs.hashType = handshake_hash_single;
-
- if (PK11_DigestBegin(ss->ssl3.hs.sha) != SECSuccess) {
- ssl_MapLowLevelError(SSL_ERROR_DIGEST_FAILURE);
- return SECFailure;
- }
-
- /* Create a backup SHA-1 hash for a potential client auth
- * signature.
- *
- * In TLS 1.2, ssl3_ComputeHandshakeHashes always uses the
- * handshake hash function (SHA-256). If the server or the client
- * does not support SHA-256 as a signature hash, we can either
- * maintain a backup SHA-1 handshake hash or buffer all handshake
- * messages.
- */
- if (!ss->sec.isServer) {
- ss->ssl3.hs.backupHash = PK11_CreateDigestContext(SEC_OID_SHA1);
- if (ss->ssl3.hs.backupHash == NULL) {
- ssl_MapLowLevelError(SSL_ERROR_SHA_DIGEST_FAILURE);
- return SECFailure;
- }
-
- if (PK11_DigestBegin(ss->ssl3.hs.backupHash) != SECSuccess) {
- ssl_MapLowLevelError(SSL_ERROR_SHA_DIGEST_FAILURE);
- return SECFailure;
- }
- }
- } else {
- /* Both ss->ssl3.hs.md5 and ss->ssl3.hs.sha should be NULL or
- * created successfully. */
- ss->ssl3.hs.md5 = PK11_CreateDigestContext(SEC_OID_MD5);
- if (ss->ssl3.hs.md5 == NULL) {
- ssl_MapLowLevelError(SSL_ERROR_MD5_DIGEST_FAILURE);
- return SECFailure;
- }
- ss->ssl3.hs.sha = PK11_CreateDigestContext(SEC_OID_SHA1);
- if (ss->ssl3.hs.sha == NULL) {
- PK11_DestroyContext(ss->ssl3.hs.md5, PR_TRUE);
- ss->ssl3.hs.md5 = NULL;
- ssl_MapLowLevelError(SSL_ERROR_SHA_DIGEST_FAILURE);
- return SECFailure;
- }
- ss->ssl3.hs.hashType = handshake_hash_combo;
-
- if (PK11_DigestBegin(ss->ssl3.hs.md5) != SECSuccess) {
- ssl_MapLowLevelError(SSL_ERROR_MD5_DIGEST_FAILURE);
- return SECFailure;
- }
- if (PK11_DigestBegin(ss->ssl3.hs.sha) != SECSuccess) {
- ssl_MapLowLevelError(SSL_ERROR_SHA_DIGEST_FAILURE);
- return SECFailure;
- }
- }
- }
-
- if (ss->ssl3.hs.messages.len > 0) {
- if (ssl3_UpdateHandshakeHashes(ss, ss->ssl3.hs.messages.buf,
- ss->ssl3.hs.messages.len) !=
- SECSuccess) {
- return SECFailure;
- }
- 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;
+ if (ss->version == SSL_LIBRARY_VERSION_TLS_1_2) {
+ ss->ssl3.hs.hashType = handshake_hash_record;
+ } else {
+ PORT_Assert(!ss->ssl3.hs.md5 && !ss->ssl3.hs.sha);
+ /*
+ * 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 ...
+ */
+ if (ss->version >= SSL_LIBRARY_VERSION_TLS_1_3) {
+ /* determine the hash from the prf */
+ const SECOidData *hash_oid =
+ SECOID_FindOIDByMechanism(ssl3_GetPrfHashMechanism(ss));
+
+ /* Get the PKCS #11 mechanism for the Hash from the cipher suite (prf_hash)
+ * Convert that to the OidTag. We can then use that OidTag to create our
+ * PK11Context */
+ PORT_Assert(hash_oid != NULL);
+ if (hash_oid == NULL) {
+ ssl_MapLowLevelError(SSL_ERROR_DIGEST_FAILURE);
+ return SECFailure;
+ }
+
+ ss->ssl3.hs.sha = PK11_CreateDigestContext(hash_oid->offset);
+ if (ss->ssl3.hs.sha == NULL) {
+ ssl_MapLowLevelError(SSL_ERROR_SHA_DIGEST_FAILURE);
+ return SECFailure;
+ }
+ ss->ssl3.hs.hashType = handshake_hash_single;
+
+ if (PK11_DigestBegin(ss->ssl3.hs.sha) != SECSuccess) {
+ ssl_MapLowLevelError(SSL_ERROR_DIGEST_FAILURE);
+ return SECFailure;
+ }
+ } else {
+ /* Both ss->ssl3.hs.md5 and ss->ssl3.hs.sha should be NULL or
+ * created successfully. */
+ ss->ssl3.hs.md5 = PK11_CreateDigestContext(SEC_OID_MD5);
+ if (ss->ssl3.hs.md5 == NULL) {
+ ssl_MapLowLevelError(SSL_ERROR_MD5_DIGEST_FAILURE);
+ return SECFailure;
+ }
+ ss->ssl3.hs.sha = PK11_CreateDigestContext(SEC_OID_SHA1);
+ if (ss->ssl3.hs.sha == NULL) {
+ PK11_DestroyContext(ss->ssl3.hs.md5, PR_TRUE);
+ ss->ssl3.hs.md5 = NULL;
+ ssl_MapLowLevelError(SSL_ERROR_SHA_DIGEST_FAILURE);
+ return SECFailure;
+ }
+ ss->ssl3.hs.hashType = handshake_hash_combo;
+
+ if (PK11_DigestBegin(ss->ssl3.hs.md5) != SECSuccess) {
+ ssl_MapLowLevelError(SSL_ERROR_MD5_DIGEST_FAILURE);
+ return SECFailure;
+ }
+ if (PK11_DigestBegin(ss->ssl3.hs.sha) != SECSuccess) {
+ ssl_MapLowLevelError(SSL_ERROR_SHA_DIGEST_FAILURE);
+ return SECFailure;
+ }
+ }
+ }
+
+ if (ss->ssl3.hs.hashType != handshake_hash_record &&
+ ss->ssl3.hs.messages.len > 0) {
+ if (ssl3_UpdateHandshakeHashes(ss, ss->ssl3.hs.messages.buf,
+ ss->ssl3.hs.messages.len) != SECSuccess) {
+ return SECFailure;
+ }
+ sslBuffer_Clear(&ss->ssl3.hs.messages);
}
return SECSuccess;
}
-static SECStatus
+SECStatus
ssl3_RestartHandshakeHashes(sslSocket *ss)
{
SECStatus rv = SECSuccess;
- SSL_TRC(30,("%d: SSL3[%d]: reset handshake hashes",
- SSL_GETPID(), ss->fd ));
+ SSL_TRC(30, ("%d: SSL3[%d]: reset handshake hashes",
+ SSL_GETPID(), ss->fd));
ss->ssl3.hs.hashType = handshake_hash_unknown;
ss->ssl3.hs.messages.len = 0;
-#ifndef NO_PKCS11_BYPASS
- ss->ssl3.hs.sha_obj = NULL;
- ss->ssl3.hs.sha_clone = NULL;
-#endif
if (ss->ssl3.hs.md5) {
- PK11_DestroyContext(ss->ssl3.hs.md5,PR_TRUE);
- ss->ssl3.hs.md5 = NULL;
+ PK11_DestroyContext(ss->ssl3.hs.md5, PR_TRUE);
+ ss->ssl3.hs.md5 = NULL;
}
if (ss->ssl3.hs.sha) {
- PK11_DestroyContext(ss->ssl3.hs.sha,PR_TRUE);
- ss->ssl3.hs.sha = NULL;
+ PK11_DestroyContext(ss->ssl3.hs.sha, PR_TRUE);
+ ss->ssl3.hs.sha = NULL;
}
return rv;
}
@@ -4160,64 +4111,56 @@ ssl3_RestartHandshakeHashes(sslSocket *ss)
/*
* Handshake messages
*/
-/* Called from ssl3_InitHandshakeHashes()
-** ssl3_AppendHandshake()
-** ssl3_StartHandshakeHash()
-** ssl3_HandleV2ClientHello()
-** ssl3_HandleHandshakeMessage()
+/* Called from ssl3_InitHandshakeHashes()
+** ssl3_AppendHandshake()
+** ssl3_HandleV2ClientHello()
+** ssl3_HandleHandshakeMessage()
** Caller must hold the ssl3Handshake lock.
*/
-static SECStatus
-ssl3_UpdateHandshakeHashes(sslSocket *ss, const unsigned char *b,
- unsigned int l)
+SECStatus
+ssl3_UpdateHandshakeHashes(sslSocket *ss, const unsigned char *b, unsigned int l)
{
- SECStatus rv = SECSuccess;
+ SECStatus rv = SECSuccess;
- PORT_Assert( ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss) );
+ PORT_Assert(ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss));
- /* We need to buffer the handshake messages until we have established
- * which handshake hash function to use. */
- if (ss->ssl3.hs.hashType == handshake_hash_unknown) {
- return sslBuffer_Append(&ss->ssl3.hs.messages, b, l);
+ /* With TLS 1.3, and versions TLS.1.1 and older, we keep the hash(es)
+ * always up to date. However, we must initially buffer the handshake
+ * messages, until we know what to do.
+ * If ss->ssl3.hs.hashType != handshake_hash_unknown,
+ * it means we know what to do. We calculate (hash our input),
+ * and we stop appending to the buffer.
+ *
+ * With TLS 1.2, we always append all handshake messages,
+ * and never update the hash, because the hash function we must use for
+ * certificate_verify might be different from the hash function we use
+ * when signing other handshake hashes. */
+
+ if (ss->ssl3.hs.hashType == handshake_hash_unknown ||
+ ss->ssl3.hs.hashType == handshake_hash_record) {
+ return sslBuffer_Append(&ss->ssl3.hs.messages, b, l);
}
PRINT_BUF(90, (NULL, "handshake hash input:", b, l));
-#ifndef NO_PKCS11_BYPASS
- if (ss->opt.bypassPKCS11) {
- if (ss->ssl3.hs.hashType == handshake_hash_single) {
- ss->ssl3.hs.sha_obj->update(ss->ssl3.hs.sha_cx, b, l);
- } else {
- MD5_Update((MD5Context *)ss->ssl3.hs.md5_cx, b, l);
- SHA1_Update((SHA1Context *)ss->ssl3.hs.sha_cx, b, l);
- }
- return rv;
- }
-#endif
if (ss->ssl3.hs.hashType == handshake_hash_single) {
- rv = PK11_DigestOp(ss->ssl3.hs.sha, b, l);
- if (rv != SECSuccess) {
- ssl_MapLowLevelError(SSL_ERROR_DIGEST_FAILURE);
- return rv;
- }
- if (ss->ssl3.hs.backupHash) {
- rv = PK11_DigestOp(ss->ssl3.hs.backupHash, b, l);
- if (rv != SECSuccess) {
- ssl_MapLowLevelError(SSL_ERROR_SHA_DIGEST_FAILURE);
- return rv;
- }
- }
- } else {
- 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;
- }
+ PORT_Assert(ss->version >= SSL_LIBRARY_VERSION_TLS_1_3);
+ rv = PK11_DigestOp(ss->ssl3.hs.sha, b, l);
+ if (rv != SECSuccess) {
+ ssl_MapLowLevelError(SSL_ERROR_DIGEST_FAILURE);
+ return rv;
+ }
+ } else if (ss->ssl3.hs.hashType == handshake_hash_combo) {
+ 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;
}
@@ -4230,40 +4173,40 @@ ssl3_UpdateHandshakeHashes(sslSocket *ss, const unsigned char *b,
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;
+ 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. */
+ PORT_Assert(ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss)); /* protects sendBuf. */
if (!bytes)
- return SECSuccess;
+ 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;
+ 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));
+ 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 */
+ 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);
+ 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;
@@ -4274,8 +4217,8 @@ SECStatus
ssl3_AppendHandshakeNumber(sslSocket *ss, PRInt32 num, PRInt32 lenSize)
{
SECStatus rv;
- PRUint8 b[4];
- PRUint8 * p = b;
+ PRUint8 b[4];
+ PRUint8 *p = b;
PORT_Assert(lenSize <= 4 && lenSize > 0);
if (lenSize < 4 && num >= (1L << (lenSize * 8))) {
@@ -4284,18 +4227,18 @@ ssl3_AppendHandshakeNumber(sslSocket *ss, PRInt32 num, PRInt32 lenSize)
}
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;
+ 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. */
+ return rv; /* error code set by AppendHandshake, if applicable. */
}
SECStatus
@@ -4304,18 +4247,18 @@ ssl3_AppendHandshakeVariable(
{
SECStatus rv;
- PORT_Assert((bytes < (1<<8) && lenSize == 1) ||
- (bytes < (1L<<16) && lenSize == 2) ||
- (bytes < (1L<<24) && lenSize == 3));
+ 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()));
+ 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. */
+ 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. */
+ return rv; /* error code set by AppendHandshake, if applicable. */
}
SECStatus
@@ -4328,61 +4271,47 @@ ssl3_AppendHandshakeHeader(sslSocket *ss, SSL3HandshakeType t, PRUint32 length)
* dtls_StageHandshakeMessage to mark the message boundary.
*/
if (IS_DTLS(ss)) {
- rv = dtls_StageHandshakeMessage(ss);
- if (rv != SECSuccess) {
- return rv;
- }
+ 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)));
+ SSL_TRC(30, ("%d: SSL3[%d]: append handshake header: type %s",
+ SSL_GETPID(), ss->fd, ssl3_DecodeHandshakeType(t)));
rv = ssl3_AppendHandshakeNumber(ss, t, 1);
if (rv != SECSuccess) {
- return rv; /* error code set by AppendHandshake, if applicable. */
+ 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. */
+ 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++;
+ /* 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. */
- }
+ /* 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. */
- }
+ /* 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. */
-}
-
-/* ssl3_AppendSignatureAndHashAlgorithm appends the serialisation of
- * |sigAndHash| to the current handshake message. */
-SECStatus
-ssl3_AppendSignatureAndHashAlgorithm(
- sslSocket *ss, const SSLSignatureAndHashAlg* sigAndHash)
-{
- PRUint8 serialized[2];
-
- serialized[0] = (PRUint8)sigAndHash->hashAlg;
- serialized[1] = (PRUint8)sigAndHash->sigAlg;
-
- return ssl3_AppendHandshake(ss, serialized, sizeof(serialized));
+ return rv; /* error code set by AppendHandshake, if applicable. */
}
/**************************************************************************
@@ -4402,17 +4331,17 @@ ssl3_AppendSignatureAndHashAlgorithm(
*/
SECStatus
ssl3_ConsumeHandshake(sslSocket *ss, void *v, PRInt32 bytes, SSL3Opaque **b,
- PRUint32 *length)
+ PRUint32 *length)
{
- PORT_Assert( ss->opt.noLocks || ssl_HaveRecvBufLock(ss) );
- PORT_Assert( ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss) );
+ PORT_Assert(ss->opt.noLocks || ssl_HaveRecvBufLock(ss));
+ PORT_Assert(ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss));
if ((PRUint32)bytes > *length) {
- return ssl3_DecodeError(ss);
+ return ssl3_DecodeError(ss);
}
PORT_Memcpy(v, *b, bytes);
PRINT_BUF(60, (ss, "consume bytes:", *b, bytes));
- *b += bytes;
+ *b += bytes;
*length -= bytes;
return SECSuccess;
}
@@ -4430,24 +4359,24 @@ ssl3_ConsumeHandshake(sslSocket *ss, void *v, PRInt32 bytes, SSL3Opaque **b,
*/
PRInt32
ssl3_ConsumeHandshakeNumber(sslSocket *ss, PRInt32 bytes, SSL3Opaque **b,
- PRUint32 *length)
+ PRUint32 *length)
{
- PRUint8 *buf = *b;
- int i;
- PRInt32 num = 0;
+ PRUint8 *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);
+ 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);
+ 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;
+ num = (num << 8) + buf[i];
+ *b += bytes;
*length -= bytes;
return num;
}
@@ -4461,134 +4390,236 @@ ssl3_ConsumeHandshakeNumber(sslSocket *ss, PRInt32 bytes, SSL3Opaque **b,
* 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
+ * 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
+ * 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)
+ SSL3Opaque **b, PRUint32 *length)
{
- PRInt32 count;
+ PRInt32 count;
PORT_Assert(bytes <= 3);
- i->len = 0;
+ i->len = 0;
i->data = NULL;
i->type = siBuffer;
count = ssl3_ConsumeHandshakeNumber(ss, bytes, b, length);
- if (count < 0) { /* Can't test for SECSuccess here. */
- return SECFailure;
+ 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;
+ if ((PRUint32)count > *length) {
+ return ssl3_DecodeError(ss);
+ }
+ i->data = *b;
+ i->len = count;
+ *b += count;
+ *length -= count;
}
return SECSuccess;
}
-/* tlsHashOIDMap contains the mapping between TLS hash identifiers and the
- * SECOidTag used internally by NSS. */
-static const struct {
- SSLHashType tlsHash;
- SECOidTag oid;
-} tlsHashOIDMap[] = {
- { ssl_hash_sha1, SEC_OID_SHA1 },
- { ssl_hash_sha256, SEC_OID_SHA256 },
- { ssl_hash_sha384, SEC_OID_SHA384 },
- { ssl_hash_sha512, SEC_OID_SHA512 }
-};
+/* Helper function to encode an unsigned integer into a buffer. */
+PRUint8 *
+ssl_EncodeUintX(PRUint64 value, unsigned int bytes, PRUint8 *to)
+{
+ PRUint64 encoded;
+
+ PORT_Assert(bytes > 0 && bytes <= sizeof(encoded));
+
+ encoded = PR_htonll(value);
+ memcpy(to, ((unsigned char *)(&encoded)) + (sizeof(encoded) - bytes), bytes);
+ return to + bytes;
+}
/* ssl3_TLSHashAlgorithmToOID converts a TLS hash identifier into an OID value.
* If the hash is not recognised, SEC_OID_UNKNOWN is returned.
*
* See https://tools.ietf.org/html/rfc5246#section-7.4.1.4.1 */
SECOidTag
-ssl3_TLSHashAlgorithmToOID(SSLHashType hashFunc)
-{
- unsigned int i;
-
- for (i = 0; i < PR_ARRAY_SIZE(tlsHashOIDMap); i++) {
- if (hashFunc == tlsHashOIDMap[i].tlsHash) {
- return tlsHashOIDMap[i].oid;
- }
+ssl3_HashTypeToOID(SSLHashType hashType)
+{
+ switch (hashType) {
+ case ssl_hash_sha1:
+ return SEC_OID_SHA1;
+ case ssl_hash_sha256:
+ return SEC_OID_SHA256;
+ case ssl_hash_sha384:
+ return SEC_OID_SHA384;
+ case ssl_hash_sha512:
+ return SEC_OID_SHA512;
+ default:
+ break;
}
return SEC_OID_UNKNOWN;
}
-/* ssl3_TLSSignatureAlgorithmForKeyType returns the TLS 1.2 signature algorithm
- * identifier for a given KeyType. */
-static SECStatus
-ssl3_TLSSignatureAlgorithmForKeyType(KeyType keyType, SSLSignType *out)
-{
- switch (keyType) {
- case rsaKey:
- *out = ssl_sign_rsa;
- return SECSuccess;
- case dsaKey:
- *out = ssl_sign_dsa;
- return SECSuccess;
- case ecKey:
- *out = ssl_sign_ecdsa;
- return SECSuccess;
- default:
- PORT_SetError(SEC_ERROR_INVALID_KEY);
- return SECFailure;
+SSLHashType
+ssl_SignatureSchemeToHashType(SSLSignatureScheme scheme)
+{
+ switch (scheme) {
+ case ssl_sig_rsa_pkcs1_sha1:
+ case ssl_sig_dsa_sha1:
+ case ssl_sig_ecdsa_sha1:
+ return ssl_hash_sha1;
+ case ssl_sig_rsa_pkcs1_sha256:
+ case ssl_sig_ecdsa_secp256r1_sha256:
+ case ssl_sig_rsa_pss_sha256:
+ case ssl_sig_dsa_sha256:
+ return ssl_hash_sha256;
+ case ssl_sig_rsa_pkcs1_sha384:
+ case ssl_sig_ecdsa_secp384r1_sha384:
+ case ssl_sig_rsa_pss_sha384:
+ case ssl_sig_dsa_sha384:
+ return ssl_hash_sha384;
+ case ssl_sig_rsa_pkcs1_sha512:
+ case ssl_sig_ecdsa_secp521r1_sha512:
+ case ssl_sig_rsa_pss_sha512:
+ case ssl_sig_dsa_sha512:
+ return ssl_hash_sha512;
+ case ssl_sig_rsa_pkcs1_sha1md5:
+ return ssl_hash_none; /* Special for TLS 1.0/1.1. */
+ case ssl_sig_none:
+ case ssl_sig_ed25519:
+ case ssl_sig_ed448:
+ break;
}
+ PORT_Assert(0);
+ return ssl_hash_none;
+}
+
+KeyType
+ssl_SignatureSchemeToKeyType(SSLSignatureScheme scheme)
+{
+ switch (scheme) {
+ case ssl_sig_rsa_pkcs1_sha256:
+ case ssl_sig_rsa_pkcs1_sha384:
+ case ssl_sig_rsa_pkcs1_sha512:
+ case ssl_sig_rsa_pkcs1_sha1:
+ case ssl_sig_rsa_pss_sha256:
+ case ssl_sig_rsa_pss_sha384:
+ case ssl_sig_rsa_pss_sha512:
+ case ssl_sig_rsa_pkcs1_sha1md5:
+ return rsaKey;
+ case ssl_sig_ecdsa_secp256r1_sha256:
+ case ssl_sig_ecdsa_secp384r1_sha384:
+ case ssl_sig_ecdsa_secp521r1_sha512:
+ case ssl_sig_ecdsa_sha1:
+ return ecKey;
+ case ssl_sig_dsa_sha256:
+ case ssl_sig_dsa_sha384:
+ case ssl_sig_dsa_sha512:
+ case ssl_sig_dsa_sha1:
+ return dsaKey;
+ case ssl_sig_none:
+ case ssl_sig_ed25519:
+ case ssl_sig_ed448:
+ break;
+ }
+ PORT_Assert(0);
+ return nullKey;
}
-/* ssl3_TLSSignatureAlgorithmForCertificate returns the TLS 1.2 signature
- * algorithm identifier for the given certificate. */
-static SECStatus
-ssl3_TLSSignatureAlgorithmForCertificate(CERTCertificate *cert,
- SSLSignType *out)
+static SSLNamedGroup
+ssl_NamedGroupForSignatureScheme(SSLSignatureScheme scheme)
{
- SECKEYPublicKey *key;
- KeyType keyType;
-
- key = CERT_ExtractPublicKey(cert);
- if (key == NULL) {
- ssl_MapLowLevelError(SSL_ERROR_EXTRACT_PUBLIC_KEY_FAILURE);
- return SECFailure;
+ switch (scheme) {
+ case ssl_sig_ecdsa_secp256r1_sha256:
+ return ssl_grp_ec_secp256r1;
+ case ssl_sig_ecdsa_secp384r1_sha384:
+ return ssl_grp_ec_secp384r1;
+ case ssl_sig_ecdsa_secp521r1_sha512:
+ return ssl_grp_ec_secp521r1;
+ default:
+ break;
}
+ PORT_Assert(0);
+ return 0;
+}
- keyType = key->keyType;
- SECKEY_DestroyPublicKey(key);
- return ssl3_TLSSignatureAlgorithmForKeyType(keyType, out);
+/* Validate that the signature scheme works for the given key.
+ * If |allowSha1| is set, we allow the use of SHA-1.
+ * If |matchGroup| is set, we also check that the group and hash match. */
+static PRBool
+ssl_SignatureSchemeValidForKey(PRBool allowSha1, PRBool matchGroup,
+ KeyType keyType,
+ const sslNamedGroupDef *ecGroup,
+ SSLSignatureScheme scheme)
+{
+ if (!ssl_IsSupportedSignatureScheme(scheme)) {
+ return PR_FALSE;
+ }
+ if (keyType != ssl_SignatureSchemeToKeyType(scheme)) {
+ return PR_FALSE;
+ }
+ if (!allowSha1 && ssl_SignatureSchemeToHashType(scheme) == ssl_hash_sha1) {
+ return PR_FALSE;
+ }
+ if (keyType != ecKey) {
+ return PR_TRUE;
+ }
+ if (!ecGroup) {
+ return PR_FALSE;
+ }
+ /* If |allowSha1| is present and the scheme is ssl_sig_ecdsa_sha1, it's OK.
+ * This scheme isn't bound to a specific group. */
+ if (allowSha1 && (scheme == ssl_sig_ecdsa_sha1)) {
+ return PR_TRUE;
+ }
+ if (!matchGroup) {
+ return PR_TRUE;
+ }
+ return ecGroup->name == ssl_NamedGroupForSignatureScheme(scheme);
}
-/* ssl3_CheckSignatureAndHashAlgorithmConsistency checks that the signature
+/* ssl3_CheckSignatureSchemeConsistency checks that the signature
* algorithm identifier in |sigAndHash| is consistent with the public key in
* |cert|. It also checks the hash algorithm against the configured signature
* algorithms. If all the tests pass, SECSuccess is returned. Otherwise,
* PORT_SetError is called and SECFailure is returned. */
SECStatus
-ssl3_CheckSignatureAndHashAlgorithmConsistency(
- sslSocket *ss, const SSLSignatureAndHashAlg *sigAndHash,
- CERTCertificate* cert)
+ssl_CheckSignatureSchemeConsistency(
+ sslSocket *ss, SSLSignatureScheme scheme, CERTCertificate *cert)
{
- SECStatus rv;
- SSLSignType sigAlg;
unsigned int i;
+ const sslNamedGroupDef *group = NULL;
+ SECKEYPublicKey *key;
+ KeyType keyType;
+ PRBool isTLS13 = ss->version == SSL_LIBRARY_VERSION_TLS_1_3;
- rv = ssl3_TLSSignatureAlgorithmForCertificate(cert, &sigAlg);
- if (rv != SECSuccess) {
- return rv;
+ key = CERT_ExtractPublicKey(cert);
+ if (key == NULL) {
+ ssl_MapLowLevelError(SSL_ERROR_EXTRACT_PUBLIC_KEY_FAILURE);
+ return SECFailure;
+ }
+
+ keyType = SECKEY_GetPublicKeyType(key);
+ if (keyType == ecKey) {
+ group = ssl_ECPubKey2NamedGroup(key);
+ }
+ SECKEY_DestroyPublicKey(key);
+
+ /* If we're a client, check that the signature algorithm matches the signing
+ * key type of the cipher suite. */
+ if (!isTLS13 &&
+ !ss->sec.isServer &&
+ ss->ssl3.hs.kea_def->signKeyType != keyType) {
+ PORT_SetError(SSL_ERROR_INCORRECT_SIGNATURE_ALGORITHM);
+ return SECFailure;
}
- if (sigAlg != sigAndHash->sigAlg) {
+
+ /* Verify that the signature scheme matches the signing key. */
+ if (!ssl_SignatureSchemeValidForKey(!isTLS13 /* allowSha1 */,
+ isTLS13 /* matchGroup */,
+ keyType, group, scheme)) {
PORT_SetError(SSL_ERROR_INCORRECT_SIGNATURE_ALGORITHM);
return SECFailure;
}
- for (i = 0; i < ss->ssl3.signatureAlgorithmCount; ++i) {
- const SSLSignatureAndHashAlg *alg = &ss->ssl3.signatureAlgorithms[i];
- if (sigAndHash->sigAlg == alg->sigAlg &&
- sigAndHash->hashAlg == alg->hashAlg) {
+ for (i = 0; i < ss->ssl3.signatureSchemeCount; ++i) {
+ if (scheme == ss->ssl3.signatureSchemes[i]) {
return SECSuccess;
}
}
@@ -4597,69 +4628,70 @@ ssl3_CheckSignatureAndHashAlgorithmConsistency(
}
PRBool
-ssl3_IsSupportedSignatureAlgorithm(const SSLSignatureAndHashAlg *alg)
-{
- static const SSLHashType supportedHashes[] = {
- ssl_hash_sha1,
- ssl_hash_sha256,
- ssl_hash_sha384,
- ssl_hash_sha512
- };
-
- static const SSLSignType supportedSigAlgs[] = {
- ssl_sign_rsa,
-#ifndef NSS_DISABLE_ECC
- ssl_sign_ecdsa,
-#endif
- ssl_sign_dsa
- };
-
- unsigned int i;
- PRBool hashOK = PR_FALSE;
- PRBool signOK = PR_FALSE;
+ssl_IsSupportedSignatureScheme(SSLSignatureScheme scheme)
+{
+ switch (scheme) {
+ case ssl_sig_rsa_pkcs1_sha1:
+ case ssl_sig_rsa_pkcs1_sha256:
+ case ssl_sig_rsa_pkcs1_sha384:
+ case ssl_sig_rsa_pkcs1_sha512:
+ case ssl_sig_rsa_pss_sha256:
+ case ssl_sig_rsa_pss_sha384:
+ case ssl_sig_rsa_pss_sha512:
+ case ssl_sig_ecdsa_secp256r1_sha256:
+ case ssl_sig_ecdsa_secp384r1_sha384:
+ case ssl_sig_ecdsa_secp521r1_sha512:
+ case ssl_sig_dsa_sha1:
+ case ssl_sig_dsa_sha256:
+ case ssl_sig_dsa_sha384:
+ case ssl_sig_dsa_sha512:
+ case ssl_sig_ecdsa_sha1:
+ return PR_TRUE;
+
+ case ssl_sig_rsa_pkcs1_sha1md5:
+ case ssl_sig_none:
+ case ssl_sig_ed25519:
+ case ssl_sig_ed448:
+ return PR_FALSE;
+ }
+ return PR_FALSE;
+}
- for (i = 0; i < PR_ARRAY_SIZE(supportedHashes); ++i) {
- if (alg->hashAlg == supportedHashes[i]) {
- hashOK = PR_TRUE;
- break;
- }
- }
+PRBool
+ssl_IsRsaPssSignatureScheme(SSLSignatureScheme scheme)
+{
+ switch (scheme) {
+ case ssl_sig_rsa_pss_sha256:
+ case ssl_sig_rsa_pss_sha384:
+ case ssl_sig_rsa_pss_sha512:
+ return PR_TRUE;
- for (i = 0; i < PR_ARRAY_SIZE(supportedSigAlgs); ++i) {
- if (alg->sigAlg == supportedSigAlgs[i]) {
- signOK = PR_TRUE;
- break;
- }
+ default:
+ return PR_FALSE;
}
-
- return hashOK && signOK;
+ return PR_FALSE;
}
-/* ssl3_ConsumeSignatureAndHashAlgorithm reads a SignatureAndHashAlgorithm
- * structure from |b| and puts the resulting value into |out|. |b| and |length|
- * are updated accordingly.
+/* ssl_ConsumeSignatureScheme reads a SSLSignatureScheme (formerly
+ * SignatureAndHashAlgorithm) structure from |b| and puts the resulting value
+ * into |out|. |b| and |length| are updated accordingly.
*
* See https://tools.ietf.org/html/rfc5246#section-7.4.1.4.1 */
SECStatus
-ssl3_ConsumeSignatureAndHashAlgorithm(sslSocket *ss,
- SSL3Opaque **b,
- PRUint32 *length,
- SSLSignatureAndHashAlg *out)
+ssl_ConsumeSignatureScheme(sslSocket *ss, SSL3Opaque **b,
+ PRUint32 *length, SSLSignatureScheme *out)
{
- PRUint8 bytes[2];
- SECStatus rv;
+ PRInt32 tmp;
- rv = ssl3_ConsumeHandshake(ss, bytes, sizeof(bytes), b, length);
- if (rv != SECSuccess) {
- return rv;
+ tmp = ssl3_ConsumeHandshakeNumber(ss, 2, b, length);
+ if (tmp < 0) {
+ return SECFailure; /* Error code set already. */
}
-
- out->hashAlg = (SSLHashType)bytes[0];
- out->sigAlg = (SSLSignType)bytes[1];
- if (!ssl3_IsSupportedSignatureAlgorithm(out)) {
+ if (!ssl_IsSupportedSignatureScheme((SSLSignatureScheme)tmp)) {
PORT_SetError(SSL_ERROR_UNSUPPORTED_SIGNATURE_ALGORITHM);
return SECFailure;
}
+ *out = (SSLSignatureScheme)tmp;
return SECSuccess;
}
@@ -4667,6 +4699,32 @@ ssl3_ConsumeSignatureAndHashAlgorithm(sslSocket *ss,
* end of Consume Handshake functions.
**************************************************************************/
+static SECStatus
+ssl3_ComputeHandshakeHash(unsigned char *buf, unsigned int len,
+ SSLHashType hashAlg, SSL3Hashes *hashes)
+{
+ SECStatus rv = SECFailure;
+ PK11Context *hashContext = PK11_CreateDigestContext(
+ ssl3_HashTypeToOID(hashAlg));
+
+ if (!hashContext) {
+ return rv;
+ }
+ rv = PK11_DigestBegin(hashContext);
+ if (rv == SECSuccess) {
+ rv = PK11_DigestOp(hashContext, buf, len);
+ }
+ if (rv == SECSuccess) {
+ rv = PK11_DigestFinal(hashContext, hashes->u.raw, &hashes->len,
+ sizeof(hashes->u.raw));
+ }
+ if (rv == SECSuccess) {
+ hashes->hashAlg = hashAlg;
+ }
+ PK11_DestroyContext(hashContext, PR_TRUE);
+ return rv;
+}
+
/* Extract the hashes of handshake messages to this point.
* Called from ssl3_SendCertificateVerify
* ssl3_SendFinished
@@ -4674,21 +4732,21 @@ ssl3_ConsumeSignatureAndHashAlgorithm(sslSocket *ss,
*
* 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.)
+ * (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) );
+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));
if (ss->ssl3.hs.hashType == handshake_hash_unknown) {
PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
return SECFailure;
@@ -4696,406 +4754,288 @@ ssl3_ComputeHandshakeHashes(sslSocket * ss,
hashes->hashAlg = ssl_hash_none;
-#ifndef NO_PKCS11_BYPASS
- if (ss->opt.bypassPKCS11 &&
- ss->ssl3.hs.hashType == handshake_hash_single) {
- /* compute them without PKCS11 */
- PRUint64 sha_cx[MAX_MAC_CONTEXT_LLONGS];
-
- ss->ssl3.hs.sha_clone(sha_cx, ss->ssl3.hs.sha_cx);
- ss->ssl3.hs.sha_obj->end(sha_cx, hashes->u.raw, &hashes->len,
- sizeof(hashes->u.raw));
-
- PRINT_BUF(60, (NULL, "SHA-256: result", hashes->u.raw, hashes->len));
+ if (ss->ssl3.hs.hashType == handshake_hash_single) {
+ PK11Context *h;
+ unsigned int stateLen;
+ unsigned char stackBuf[1024];
+ unsigned char *stateBuf = NULL;
+
+ h = ss->ssl3.hs.sha;
+ stateBuf = PK11_SaveContextAlloc(h, stackBuf,
+ sizeof(stackBuf), &stateLen);
+ if (stateBuf == NULL) {
+ ssl_MapLowLevelError(SSL_ERROR_DIGEST_FAILURE);
+ goto tls12_loser;
+ }
+ rv |= PK11_DigestFinal(h, hashes->u.raw, &hashes->len,
+ sizeof(hashes->u.raw));
+ if (rv != SECSuccess) {
+ ssl_MapLowLevelError(SSL_ERROR_DIGEST_FAILURE);
+ rv = SECFailure;
+ goto tls12_loser;
+ }
- /* If we ever support ciphersuites where the PRF hash isn't SHA-256
- * then this will need to be updated. */
- hashes->hashAlg = ssl_hash_sha256;
- rv = SECSuccess;
- } else if (ss->opt.bypassPKCS11) {
- /* compute them without PKCS11 */
- PRUint64 md5_cx[MAX_MAC_CONTEXT_LLONGS];
- PRUint64 sha_cx[MAX_MAC_CONTEXT_LLONGS];
+ hashes->hashAlg = ssl3_GetSuitePrfHash(ss);
+ rv = SECSuccess;
-#define md5cx ((MD5Context *)md5_cx)
-#define shacx ((SHA1Context *)sha_cx)
+ tls12_loser:
+ if (stateBuf) {
+ if (PK11_RestoreContext(h, stateBuf, stateLen) != SECSuccess) {
+ ssl_MapLowLevelError(SSL_ERROR_DIGEST_FAILURE);
+ rv = SECFailure;
+ }
+ if (stateBuf != stackBuf) {
+ PORT_ZFree(stateBuf, stateLen);
+ }
+ }
+ } else if (ss->ssl3.hs.hashType == handshake_hash_record) {
+ rv = ssl3_ComputeHandshakeHash(ss->ssl3.hs.messages.buf,
+ ss->ssl3.hs.messages.len,
+ ssl3_GetSuitePrfHash(ss),
+ hashes);
+ } else {
+ 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];
+
+ 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;
- MD5_Clone (md5cx, (MD5Context *)ss->ssl3.hs.md5_cx);
- SHA1_Clone(shacx, (SHA1Context *)ss->ssl3.hs.sha_cx);
+ 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];
+ if (!isTLS) {
+ /* compute hashes for SSL3. */
+ unsigned char s[4];
- if (!spec->msItem.data) {
+ if (!spec->master_secret) {
PORT_SetError(SSL_ERROR_RX_UNEXPECTED_HANDSHAKE);
- return SECFailure;
+ rv = SECFailure;
+ goto loser;
}
- s[0] = (unsigned char)(sender >> 24);
- s[1] = (unsigned char)(sender >> 16);
- s[2] = (unsigned char)(sender >> 8);
- s[3] = (unsigned char)sender;
+ 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));
- }
+ 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));
+ 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);
+ 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));
+ 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));
- }
+ 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));
+ 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);
+ 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));
+ PRINT_BUF(95, (NULL, "SHA inner: result", sha_inner, outLength));
- 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->u.s.md5, &outLength, MD5_LENGTH);
+ 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));
- PRINT_BUF(60, (NULL, "MD5 outer: result", hashes->u.s.md5, 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->u.s.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;
+ }
- 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));
+ PRINT_BUF(60, (NULL, "MD5 outer: result", hashes->u.s.md5, MD5_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->u.s.sha, &outLength, SHA1_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));
- PRINT_BUF(60, (NULL, "SHA outer: result", hashes->u.s.sha, 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->u.s.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;
+ }
- hashes->len = MD5_LENGTH + SHA1_LENGTH;
- rv = SECSuccess;
-#undef md5cx
-#undef shacx
- } else
-#endif
- if (ss->ssl3.hs.hashType == handshake_hash_single) {
- /* compute hashes with PKCS11 */
- PK11Context *h;
- unsigned int stateLen;
- unsigned char stackBuf[1024];
- unsigned char *stateBuf = NULL;
-
- h = ss->ssl3.hs.sha;
- stateBuf = PK11_SaveContextAlloc(h, stackBuf,
- sizeof(stackBuf), &stateLen);
- if (stateBuf == NULL) {
- ssl_MapLowLevelError(SSL_ERROR_DIGEST_FAILURE);
- goto tls12_loser;
- }
- rv |= PK11_DigestFinal(h, hashes->u.raw, &hashes->len,
- sizeof(hashes->u.raw));
- if (rv != SECSuccess) {
- ssl_MapLowLevelError(SSL_ERROR_DIGEST_FAILURE);
- rv = SECFailure;
- goto tls12_loser;
- }
- /* If we ever support ciphersuites where the PRF hash isn't SHA-256
- * then this will need to be updated. */
- hashes->hashAlg = ssl_hash_sha256;
- rv = SECSuccess;
-
-tls12_loser:
- if (stateBuf) {
- if (PK11_RestoreContext(h, stateBuf, stateLen) != SECSuccess) {
- ssl_MapLowLevelError(SSL_ERROR_DIGEST_FAILURE);
- rv = SECFailure;
- }
- if (stateBuf != stackBuf) {
- PORT_ZFree(stateBuf, stateLen);
- }
- }
- } else {
- /* compute hashes 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];
-
- 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];
+ PRINT_BUF(60, (NULL, "SHA outer: result", hashes->u.s.sha, SHA1_LENGTH));
- if (!spec->master_secret) {
- PORT_SetError(SSL_ERROR_RX_UNEXPECTED_HANDSHAKE);
- return SECFailure;
- }
-
- 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->u.s.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->u.s.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->u.s.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->u.s.sha, SHA1_LENGTH));
-
- hashes->len = MD5_LENGTH + SHA1_LENGTH;
- rv = SECSuccess;
+ hashes->len = MD5_LENGTH + 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);
- }
- }
+ 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;
}
-static SECStatus
-ssl3_ComputeBackupHandshakeHashes(sslSocket * ss,
- SSL3Hashes * hashes) /* output goes here. */
-{
- SECStatus rv = SECSuccess;
+/**************************************************************************
+ * end of Handshake Hash functions.
+ * Begin Send and Handle functions for handshakes.
+ **************************************************************************/
- PORT_Assert( ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss) );
- PORT_Assert( !ss->sec.isServer );
- PORT_Assert( ss->ssl3.hs.hashType == handshake_hash_single );
+#ifdef TRACE
+#define CHTYPE(t) \
+ case client_hello_##t: \
+ return #t;
- rv = PK11_DigestFinal(ss->ssl3.hs.backupHash, hashes->u.raw, &hashes->len,
- sizeof(hashes->u.raw));
- if (rv != SECSuccess) {
- ssl_MapLowLevelError(SSL_ERROR_SHA_DIGEST_FAILURE);
- rv = SECFailure;
- goto loser;
+static const char *
+ssl_ClientHelloTypeName(sslClientHelloType type)
+{
+ switch (type) {
+ CHTYPE(initial);
+ CHTYPE(retry);
+ CHTYPE(retransmit); /* DTLS only */
+ CHTYPE(renegotiation); /* TLS <= 1.2 only */
}
- hashes->hashAlg = ssl_hash_sha1;
-
-loser:
- PK11_DestroyContext(ss->ssl3.hs.backupHash, PR_TRUE);
- ss->ssl3.hs.backupHash = NULL;
- return rv;
+ PORT_Assert(0);
+ return NULL;
}
+#undef CHTYPE
+#endif
-/*
- * SSL 2 based implementations pass in the initial outbound buffer
- * so that the handshake hash can contain the included information.
+/* Called from ssl3_HandleHelloRequest(),
+ * ssl3_RedoHandshake()
+ * ssl_BeginClientHandshake (when resuming ssl3 session)
+ * dtls_HandleHelloVerifyRequest(with resending=PR_TRUE)
*
- * Called from ssl2_BeginClientHandshake() in sslcon.c
+ * The |type| argument indicates what is going on here:
+ * - client_hello_initial is set for the very first ClientHello
+ * - client_hello_retry indicates that this is a second attempt after receiving
+ * a HelloRetryRequest (in TLS 1.3)
+ * - client_hello_retransmit is used in DTLS when resending
+ * - client_hello_renegotiation is used to renegotiate (in TLS <1.3)
*/
SECStatus
-ssl3_StartHandshakeHash(sslSocket *ss, unsigned char * buf, int length)
+ssl3_SendClientHello(sslSocket *ss, sslClientHelloType type)
{
+ 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, fallbackSCSV = PR_FALSE;
+ PRInt32 total_exten_len = 0;
+ unsigned paddingExtensionLen;
+ unsigned numCompressionMethods;
+ PRUint16 version;
+ PRInt32 flags;
+
+ SSL_TRC(3, ("%d: SSL3[%d]: send %s ClientHello handshake", SSL_GETPID(),
+ ss->fd, ssl_ClientHelloTypeName(type)));
- ssl_GetSSL3HandshakeLock(ss); /**************************************/
+ PORT_Assert(ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss));
+ PORT_Assert(ss->opt.noLocks || ssl_HaveXmitBufLock(ss));
- rv = ssl3_InitState(ss);
- if (rv != SECSuccess) {
- goto done; /* ssl3_InitState has set the error code. */
- }
- rv = ssl3_RestartHandshakeHashes(ss);
- if (rv != SECSuccess) {
- goto done;
+ /* shouldn't get here if SSL3 is disabled, but ... */
+ if (SSL_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;
}
- 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, fallbackSCSV = PR_FALSE;
- PRInt32 total_exten_len = 0;
- unsigned paddingExtensionLen;
- 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) );
+ /* If we are responding to a HelloRetryRequest, don't reinitialize. We need
+ * to maintain the handshake hashes. */
+ if (ss->ssl3.hs.helloRetry) {
+ PORT_Assert(type == client_hello_retry);
+ } else {
+ rv = ssl3_InitState(ss);
+ if (rv != SECSuccess) {
+ return rv; /* ssl3_InitState has set the error code. */
+ }
- rv = ssl3_InitState(ss);
- if (rv != SECSuccess) {
- return rv; /* ssl3_InitState has set the error code. */
+ rv = ssl3_RestartHandshakeHashes(ss);
+ if (rv != SECSuccess) {
+ return rv;
+ }
}
+
/* These must be reset every handshake. */
ss->ssl3.hs.sendingSCSV = PR_FALSE;
ss->ssl3.hs.preliminaryInfo = 0;
- PORT_Assert(IS_DTLS(ss) || !resending);
-
+ PORT_Assert(IS_DTLS(ss) || type != client_hello_retransmit);
SECITEM_FreeItem(&ss->ssl3.hs.newSessionTicket.ticket, PR_FALSE);
ss->ssl3.hs.receivedNewSessionTicket = PR_FALSE;
+ ssl3_ResetExtensionData(&ss->xtnData);
- /* We might be starting a session renegotiation in which case we should
- * clear previous state.
- */
- PORT_Memset(&ss->xtnData, 0, sizeof(TLSExtensionData));
-
- rv = ssl3_RestartHandshakeHashes(ss);
- if (rv != SECSuccess) {
- return rv;
+ /* 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. */
}
/*
@@ -5103,25 +5043,26 @@ ssl3_SendClientHello(sslSocket *ss, PRBool resending)
* 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;
- }
+ PORT_Assert(type != client_hello_initial);
+ if (SSL_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;
- }
+ 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
+ * XXX If we've been called from ssl_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);
+ : 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 ...
@@ -5129,161 +5070,152 @@ ssl3_SendClientHello(sslSocket *ss, PRBool resending)
* 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;
- }
-
- if (sidOK) {
- /* Set ss->version based on the session cache */
- if (ss->firstHsDone) {
- /*
- * 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.
- *
- * 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 {
+ PRBool sidOK = PR_TRUE;
+ const ssl3CipherSuiteCfg *suite;
+
+ /* Check that the cipher suite we need is enabled. */
+ suite = ssl_LookupCipherSuiteCfg(sid->u.ssl3.cipherSuite,
+ ss->cipherSuites);
+ PORT_Assert(suite);
+ if (!suite || !config_match(suite, ss->ssl3.policy, &ss->vrange, ss)) {
+ sidOK = PR_FALSE;
+ }
+
+ /* Check that we can recover the master secret. */
+ if (sidOK && sid->u.ssl3.keys.msIsWrapped) {
+ PK11SlotInfo *slot = NULL;
+ if (sid->u.ssl3.masterValid) {
+ 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;
+ }
+
+ if (sidOK) {
+ /* Set version based on the sid. */
+ if (ss->firstHsDone) {
+ /*
+ * 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.
+ *
+ * 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) {
+ version = ss->clientHelloVersion;
+ } else {
+ sidOK = PR_FALSE;
+ }
+ } else {
/*
* Check sid->version is OK first.
* Previously, we would cap the version based on sid->version,
* but that prevents negotiation of a higher version if the
* previous session was reduced (e.g., with version fallback)
*/
- if (sid->version < ss->vrange.min ||
+ if (sid->version < ss->vrange.min ||
sid->version > ss->vrange.max) {
- sidOK = PR_FALSE;
- } else {
- rv = ssl3_NegotiateVersion(ss, SSL_LIBRARY_VERSION_MAX_SUPPORTED,
- PR_TRUE);
- if (rv != SECSuccess) {
- return rv; /* error code was set */
- }
- }
- }
- }
+ sidOK = PR_FALSE;
+ } else {
+ version = ss->vrange.max;
+ }
+ }
+ }
- if (!sidOK) {
- SSL_AtomicIncrementLong(& ssl3stats.sch_sid_cache_not_ok );
- if (ss->sec.uncache)
- (*ss->sec.uncache)(sid);
- ssl_FreeSID(sid);
- sid = NULL;
- }
+ if (!sidOK) {
+ SSL_AtomicIncrementLong(&ssl3stats.sch_sid_cache_not_ok);
+ ss->sec.uncache(sid);
+ ssl_FreeSID(sid);
+ sid = NULL;
+ }
}
if (sid) {
- requestingResume = PR_TRUE;
- SSL_AtomicIncrementLong(& ssl3stats.sch_sid_cache_hits );
+ requestingResume = PR_TRUE;
+ SSL_AtomicIncrementLong(&ssl3stats.sch_sid_cache_hits);
- PRINT_BUF(4, (ss, "client, found session-id:", sid->u.ssl3.sessionID,
- sid->u.ssl3.sessionIDLength));
+ PRINT_BUF(4, (ss, "client, found session-id:", sid->u.ssl3.sessionID,
+ sid->u.ssl3.sessionIDLength));
- ss->ssl3.policy = sid->u.ssl3.policy;
+ 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 */
+ 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) {
+ version = ss->clientHelloVersion;
+ } else {
+ version = ss->vrange.max;
+ }
+
+ sid = ssl3_NewSessionID(ss, PR_FALSE);
+ if (!sid) {
+ return SECFailure; /* memory error is set */
}
+ /* ss->version isn't set yet, but the sid needs a sane value. */
+ sid->version = version;
}
- isTLS = (ss->version > SSL_LIBRARY_VERSION_3_0);
+ isTLS = (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 records are not being MACed. */
+ cwSpec->version = version;
}
ssl_ReleaseSpecWriteLock(ss);
if (ss->sec.ci.sid != NULL) {
- ssl_FreeSID(ss->sec.ci.sid); /* decrement ref count, free if zero */
+ 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 TLS is disabled.
*/
if (!ss->firstHsDone && !isTLS) {
- /* Must set this before calling Hello Extension Senders,
- * to suppress sending of empty RI extension.
- */
- ss->ssl3.hs.sendingSCSV = PR_TRUE;
+ /* Must set this before calling Hello Extension Senders,
+ * to suppress sending of empty RI extension.
+ */
+ ss->ssl3.hs.sendingSCSV = PR_TRUE;
}
/* When we attempt session resumption (only), we must lock the sid to
@@ -5297,62 +5229,68 @@ ssl3_SendClientHello(sslSocket *ss, PRBool resending)
PR_RWLock_Rlock(sid->u.ssl3.lock);
}
+ if (ss->vrange.max >= SSL_LIBRARY_VERSION_TLS_1_3 &&
+ type == client_hello_initial) {
+ rv = tls13_SetupClientHello(ss);
+ if (rv != SECSuccess) {
+ return SECFailure;
+ }
+ }
if (isTLS || (ss->firstHsDone && ss->peerRequestedProtection)) {
- PRUint32 maxBytes = 65535; /* 2^16 - 1 */
- PRInt32 extLen;
+ PRUint32 maxBytes = 65535; /* 2^16 - 1 */
+ PRInt32 extLen;
- extLen = ssl3_CallHelloExtensionSenders(ss, PR_FALSE, maxBytes, NULL);
- if (extLen < 0) {
- if (sid->u.ssl3.lock) { PR_RWLock_Unlock(sid->u.ssl3.lock); }
- return SECFailure;
- }
- total_exten_len += extLen;
-
- if (total_exten_len > 0)
- total_exten_len += 2;
- }
+ extLen = ssl3_CallHelloExtensionSenders(ss, PR_FALSE, maxBytes, NULL);
+ if (extLen < 0) {
+ if (sid->u.ssl3.lock) {
+ PR_RWLock_Unlock(sid->u.ssl3.lock);
+ }
+ return SECFailure;
+ }
+ total_exten_len += extLen;
-#ifndef NSS_DISABLE_ECC
- if (!total_exten_len || !isTLS) {
- /* not sending the elliptic_curves and ec_point_formats extensions */
- ssl3_DisableECCSuites(ss, NULL); /* disable all ECC suites */
+ if (total_exten_len > 0)
+ total_exten_len += 2;
}
-#endif /* NSS_DISABLE_ECC */
if (IS_DTLS(ss)) {
- ssl3_DisableNonDTLSSuites(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);
+ num_suites = count_cipher_suites(ss, ss->ssl3.policy);
if (!num_suites) {
- if (sid->u.ssl3.lock) { PR_RWLock_Unlock(sid->u.ssl3.lock); }
- return SECFailure; /* count_cipher_suites has set error code. */
+ if (sid->u.ssl3.lock) {
+ PR_RWLock_Unlock(sid->u.ssl3.lock);
+ }
+ return SECFailure; /* count_cipher_suites has set error code. */
}
fallbackSCSV = ss->opt.enableFallbackSCSV && (!requestingResume ||
- ss->version < sid->version);
+ version < sid->version);
/* make room for SCSV */
if (ss->ssl3.hs.sendingSCSV) {
- ++num_suites;
+ ++num_suites;
}
if (fallbackSCSV) {
- ++num_suites;
+ ++num_suites;
}
/* count compression methods */
numCompressionMethods = 0;
- for (i = 0; i < compressionMethodsCount; i++) {
- if (compressionEnabled(ss, compressions[i]))
- numCompressionMethods++;
+ for (i = 0; i < ssl_compression_method_count; i++) {
+ if (ssl_CompressionEnabled(ss, ssl_compression_methods[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;
+ 1 + (sid->version >= SSL_LIBRARY_VERSION_TLS_1_3
+ ? 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;
+ length += 1 + ss->ssl3.hs.cookie.len;
}
/* A padding extension may be included to ensure that the record containing
@@ -5360,8 +5298,9 @@ ssl3_SendClientHello(sslSocket *ss, PRBool resending)
* (inclusive). Initial, ClientHello records with such lengths trigger bugs
* in F5 devices.
*
- * This is not done for DTLS nor for renegotiation. */
- if (!IS_DTLS(ss) && isTLS && !ss->firstHsDone) {
+ * This is not done for DTLS, for renegotiation, or when there are no
+ * extensions. */
+ if (!IS_DTLS(ss) && isTLS && !ss->firstHsDone && total_exten_len) {
paddingExtensionLen = ssl3_CalculatePaddingExtensionLength(length);
total_exten_len += paddingExtensionLen;
length += paddingExtensionLen;
@@ -5371,157 +5310,192 @@ ssl3_SendClientHello(sslSocket *ss, PRBool resending)
rv = ssl3_AppendHandshakeHeader(ss, client_hello, length);
if (rv != SECSuccess) {
- if (sid->u.ssl3.lock) { PR_RWLock_Unlock(sid->u.ssl3.lock); }
- return rv; /* err set by ssl3_AppendHandshake* */
+ if (sid->u.ssl3.lock) {
+ PR_RWLock_Unlock(sid->u.ssl3.lock);
+ }
+ 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);
+ /* The client hello version must stay unchanged to work around
+ * the Windows SChannel bug described above. */
+ PORT_Assert(version == ss->clientHelloVersion);
}
- ss->clientHelloVersion = ss->version;
+ ss->clientHelloVersion = PR_MIN(version, SSL_LIBRARY_VERSION_TLS_1_2);
if (IS_DTLS(ss)) {
- PRUint16 version;
+ PRUint16 dtlsVersion;
- version = dtls_TLSVersionToDTLSVersion(ss->clientHelloVersion);
- rv = ssl3_AppendHandshakeNumber(ss, version, 2);
+ dtlsVersion = dtls_TLSVersionToDTLSVersion(ss->clientHelloVersion);
+ rv = ssl3_AppendHandshakeNumber(ss, dtlsVersion, 2);
} else {
- rv = ssl3_AppendHandshakeNumber(ss, ss->clientHelloVersion, 2);
+ rv = ssl3_AppendHandshakeNumber(ss, ss->clientHelloVersion, 2);
}
if (rv != SECSuccess) {
- if (sid->u.ssl3.lock) { PR_RWLock_Unlock(sid->u.ssl3.lock); }
- return rv; /* err set by ssl3_AppendHandshake* */
+ if (sid->u.ssl3.lock) {
+ PR_RWLock_Unlock(sid->u.ssl3.lock);
+ }
+ 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) {
- if (sid->u.ssl3.lock) { PR_RWLock_Unlock(sid->u.ssl3.lock); }
- return rv; /* err set by GetNewRandom. */
- }
+ /* Generate a new random if this is the first attempt. */
+ if (type == client_hello_initial) {
+ rv = ssl3_GetNewRandom(&ss->ssl3.hs.client_random);
+ if (rv != SECSuccess) {
+ if (sid->u.ssl3.lock) {
+ PR_RWLock_Unlock(sid->u.ssl3.lock);
+ }
+ return rv; /* err set by GetNewRandom. */
+ }
}
rv = ssl3_AppendHandshake(ss, &ss->ssl3.hs.client_random,
SSL3_RANDOM_LENGTH);
if (rv != SECSuccess) {
- if (sid->u.ssl3.lock) { PR_RWLock_Unlock(sid->u.ssl3.lock); }
- return rv; /* err set by ssl3_AppendHandshake* */
+ if (sid->u.ssl3.lock) {
+ PR_RWLock_Unlock(sid->u.ssl3.lock);
+ }
+ return rv; /* err set by ssl3_AppendHandshake* */
}
- if (sid)
- rv = ssl3_AppendHandshakeVariable(
- ss, sid->u.ssl3.sessionID, sid->u.ssl3.sessionIDLength, 1);
+ if (sid->version < SSL_LIBRARY_VERSION_TLS_1_3)
+ rv = ssl3_AppendHandshakeVariable(
+ ss, sid->u.ssl3.sessionID, sid->u.ssl3.sessionIDLength, 1);
else
- rv = ssl3_AppendHandshakeNumber(ss, 0, 1);
+ rv = ssl3_AppendHandshakeNumber(ss, 0, 1);
if (rv != SECSuccess) {
- if (sid->u.ssl3.lock) { PR_RWLock_Unlock(sid->u.ssl3.lock); }
- return rv; /* err set by ssl3_AppendHandshake* */
+ if (sid->u.ssl3.lock) {
+ PR_RWLock_Unlock(sid->u.ssl3.lock);
+ }
+ 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) {
- if (sid->u.ssl3.lock) { PR_RWLock_Unlock(sid->u.ssl3.lock); }
- return rv; /* err set by ssl3_AppendHandshake* */
- }
+ rv = ssl3_AppendHandshakeVariable(
+ ss, ss->ssl3.hs.cookie.data, ss->ssl3.hs.cookie.len, 1);
+ if (rv != SECSuccess) {
+ if (sid->u.ssl3.lock) {
+ PR_RWLock_Unlock(sid->u.ssl3.lock);
+ }
+ return rv; /* err set by ssl3_AppendHandshake* */
+ }
}
- rv = ssl3_AppendHandshakeNumber(ss, num_suites*sizeof(ssl3CipherSuite), 2);
+ rv = ssl3_AppendHandshakeNumber(ss, num_suites * sizeof(ssl3CipherSuite), 2);
if (rv != SECSuccess) {
- if (sid->u.ssl3.lock) { PR_RWLock_Unlock(sid->u.ssl3.lock); }
- return rv; /* err set by ssl3_AppendHandshake* */
+ if (sid->u.ssl3.lock) {
+ PR_RWLock_Unlock(sid->u.ssl3.lock);
+ }
+ 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) {
- if (sid->u.ssl3.lock) { PR_RWLock_Unlock(sid->u.ssl3.lock); }
- return rv; /* err set by ssl3_AppendHandshake* */
- }
- actual_count++;
+ /* Add the actual SCSV */
+ rv = ssl3_AppendHandshakeNumber(ss, TLS_EMPTY_RENEGOTIATION_INFO_SCSV,
+ sizeof(ssl3CipherSuite));
+ if (rv != SECSuccess) {
+ if (sid->u.ssl3.lock) {
+ PR_RWLock_Unlock(sid->u.ssl3.lock);
+ }
+ return rv; /* err set by ssl3_AppendHandshake* */
+ }
+ actual_count++;
}
if (fallbackSCSV) {
- rv = ssl3_AppendHandshakeNumber(ss, TLS_FALLBACK_SCSV,
- sizeof(ssl3CipherSuite));
- if (rv != SECSuccess) {
- if (sid->u.ssl3.lock) { PR_RWLock_Unlock(sid->u.ssl3.lock); }
- return rv; /* err set by ssl3_AppendHandshake* */
- }
- actual_count++;
+ rv = ssl3_AppendHandshakeNumber(ss, TLS_FALLBACK_SCSV,
+ sizeof(ssl3CipherSuite));
+ if (rv != SECSuccess) {
+ if (sid->u.ssl3.lock) {
+ PR_RWLock_Unlock(sid->u.ssl3.lock);
+ }
+ 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, &ss->vrange, ss)) {
- actual_count++;
- if (actual_count > num_suites) {
- if (sid->u.ssl3.lock) { PR_RWLock_Unlock(sid->u.ssl3.lock); }
- /* 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) {
- if (sid->u.ssl3.lock) { PR_RWLock_Unlock(sid->u.ssl3.lock); }
- return rv; /* err set by ssl3_AppendHandshake* */
- }
- }
+ ssl3CipherSuiteCfg *suite = &ss->cipherSuites[i];
+ if (config_match(suite, ss->ssl3.policy, &ss->vrange, ss)) {
+ actual_count++;
+ if (actual_count > num_suites) {
+ if (sid->u.ssl3.lock) {
+ PR_RWLock_Unlock(sid->u.ssl3.lock);
+ }
+ /* 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) {
+ if (sid->u.ssl3.lock) {
+ PR_RWLock_Unlock(sid->u.ssl3.lock);
+ }
+ 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 */
- if (sid->u.ssl3.lock) { PR_RWLock_Unlock(sid->u.ssl3.lock); }
- PORT_SetError(SSL_ERROR_TOKEN_INSERTION_REMOVAL);
- return SECFailure;
+ /* Card removal/insertion error */
+ if (sid->u.ssl3.lock) {
+ PR_RWLock_Unlock(sid->u.ssl3.lock);
+ }
+ PORT_SetError(SSL_ERROR_TOKEN_INSERTION_REMOVAL);
+ return SECFailure;
}
rv = ssl3_AppendHandshakeNumber(ss, numCompressionMethods, 1);
if (rv != SECSuccess) {
- if (sid->u.ssl3.lock) { PR_RWLock_Unlock(sid->u.ssl3.lock); }
- return rv; /* err set by ssl3_AppendHandshake* */
+ if (sid->u.ssl3.lock) {
+ PR_RWLock_Unlock(sid->u.ssl3.lock);
+ }
+ 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) {
- if (sid->u.ssl3.lock) { PR_RWLock_Unlock(sid->u.ssl3.lock); }
- return rv; /* err set by ssl3_AppendHandshake* */
- }
+ for (i = 0; i < ssl_compression_method_count; i++) {
+ if (!ssl_CompressionEnabled(ss, ssl_compression_methods[i]))
+ continue;
+ rv = ssl3_AppendHandshakeNumber(ss, ssl_compression_methods[i], 1);
+ if (rv != SECSuccess) {
+ if (sid->u.ssl3.lock) {
+ PR_RWLock_Unlock(sid->u.ssl3.lock);
+ }
+ 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) {
- if (sid->u.ssl3.lock) { PR_RWLock_Unlock(sid->u.ssl3.lock); }
- return rv; /* err set by AppendHandshake. */
- }
-
- extLen = ssl3_CallHelloExtensionSenders(ss, PR_TRUE, maxBytes, NULL);
- if (extLen < 0) {
- if (sid->u.ssl3.lock) { PR_RWLock_Unlock(sid->u.ssl3.lock); }
- return SECFailure;
- }
- maxBytes -= extLen;
-
- extLen = ssl3_AppendPaddingExtension(ss, paddingExtensionLen, maxBytes);
- if (extLen < 0) {
- if (sid->u.ssl3.lock) { PR_RWLock_Unlock(sid->u.ssl3.lock); }
- return SECFailure;
- }
- maxBytes -= extLen;
-
- PORT_Assert(!maxBytes);
- }
+ PRUint32 maxBytes = total_exten_len - 2;
+ PRInt32 extLen;
+
+ rv = ssl3_AppendHandshakeNumber(ss, maxBytes, 2);
+ if (rv != SECSuccess) {
+ if (sid->u.ssl3.lock) {
+ PR_RWLock_Unlock(sid->u.ssl3.lock);
+ }
+ return rv; /* err set by AppendHandshake. */
+ }
+
+ extLen = ssl3_AppendPaddingExtension(ss, paddingExtensionLen, maxBytes);
+ if (extLen < 0) {
+ if (sid->u.ssl3.lock) {
+ PR_RWLock_Unlock(sid->u.ssl3.lock);
+ }
+ return SECFailure;
+ }
+ maxBytes -= extLen;
+
+ extLen = ssl3_CallHelloExtensionSenders(ss, PR_TRUE, maxBytes, NULL);
+ if (extLen < 0) {
+ if (sid->u.ssl3.lock) {
+ PR_RWLock_Unlock(sid->u.ssl3.lock);
+ }
+ return SECFailure;
+ }
+ maxBytes -= extLen;
+
+ PORT_Assert(!maxBytes);
+ }
if (sid->u.ssl3.lock) {
PR_RWLock_Unlock(sid->u.ssl3.lock);
@@ -5532,68 +5506,74 @@ ssl3_SendClientHello(sslSocket *ss, PRBool resending)
}
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;
+ /* 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 && !IS_DTLS(ss)) {
- flags |= ssl_SEND_FLAG_CAP_RECORD_VERSION;
+ flags |= ssl_SEND_FLAG_CAP_RECORD_VERSION;
}
rv = ssl3_FlushHandshake(ss, flags);
if (rv != SECSuccess) {
- return rv; /* error code set by ssl3_FlushHandshake */
+ return rv; /* error code set by ssl3_FlushHandshake */
+ }
+
+ if (version >= SSL_LIBRARY_VERSION_TLS_1_3) {
+ rv = tls13_MaybeDo0RTTHandshake(ss);
+ if (rv != SECSuccess) {
+ return SECFailure; /* error code set already. */
+ }
}
ss->ssl3.hs.ws = wait_server_hello;
- return rv;
+ return SECSuccess;
}
-
-/* Called from ssl3_HandleHandshakeMessage() when it has deciphered a complete
- * ssl3 Hello Request.
+/* Called from ssl3_HandlePostHelloHandshakeMessage() 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;
+ SECStatus rv;
SSL_TRC(3, ("%d: SSL3[%d]: handle hello_request handshake",
- SSL_GETPID(), ss->fd));
+ SSL_GETPID(), ss->fd));
- PORT_Assert( ss->opt.noLocks || ssl_HaveRecvBufLock(ss) );
- PORT_Assert( ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss) );
+ PORT_Assert(ss->opt.noLocks || ssl_HaveRecvBufLock(ss));
+ PORT_Assert(ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss));
+ PORT_Assert(ss->version < SSL_LIBRARY_VERSION_TLS_1_3);
if (ss->ssl3.hs.ws == wait_server_hello)
- return SECSuccess;
+ 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;
+ (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) {
- (void)SSL3_SendAlert(ss, alert_warning, no_renegotiation);
- PORT_SetError(SSL_ERROR_RENEGOTIATION_NOT_ALLOWED);
- return SECFailure;
+ (void)SSL3_SendAlert(ss, alert_warning, no_renegotiation);
+ 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;
+ ss->sec.uncache(sid);
+ ssl_FreeSID(sid);
+ ss->sec.ci.sid = NULL;
}
if (IS_DTLS(ss)) {
- dtls_RehandshakeCleanup(ss);
+ dtls_RehandshakeCleanup(ss);
}
ssl_GetXmitBufLock(ss);
- rv = ssl3_SendClientHello(ss, PR_FALSE);
+ rv = ssl3_SendClientHello(ss, client_hello_renegotiation);
ssl_ReleaseXmitBufLock(ss);
return rv;
@@ -5626,7 +5606,7 @@ ssl_FindIndexByWrapMechanism(CK_MECHANISM_TYPE mech)
const CK_MECHANISM_TYPE *pMech = wrapMechanismList;
while (mech != *pMech && *pMech != UNKNOWN_WRAP_MECHANISM) {
- ++pMech;
+ ++pMech;
}
return (*pMech == UNKNOWN_WRAP_MECHANISM) ? -1
: (pMech - wrapMechanismList);
@@ -5634,116 +5614,118 @@ ssl_FindIndexByWrapMechanism(CK_MECHANISM_TYPE mech)
static PK11SymKey *
ssl_UnwrapSymWrappingKey(
- SSLWrappedSymWrappingKey *pWswk,
- SECKEYPrivateKey * svrPrivKey,
- SSL3KEAType exchKeyType,
- CK_MECHANISM_TYPE masterWrapMech,
- void * pwArg)
-{
- PK11SymKey * unwrappedWrappingKey = NULL;
- SECItem wrappedKey;
-#ifndef NSS_DISABLE_ECC
- PK11SymKey * Ks;
- SECKEYPublicKey pubWrapKey;
- ECCWrappedKeyInfo *ecWrapped;
-#endif /* NSS_DISABLE_ECC */
+ SSLWrappedSymWrappingKey *pWswk,
+ SECKEYPrivateKey *svrPrivKey,
+ SSLAuthType authType,
+ CK_MECHANISM_TYPE masterWrapMech,
+ void *pwArg)
+{
+ PK11SymKey *unwrappedWrappingKey = NULL;
+ SECItem wrappedKey;
+ PK11SymKey *Ks;
+ SECKEYPublicKey pubWrapKey;
+ ECCWrappedKeyInfo *ecWrapped;
/* found the wrapping key on disk. */
PORT_Assert(pWswk->symWrapMechanism == masterWrapMech);
- PORT_Assert(pWswk->exchKeyType == exchKeyType);
+ PORT_Assert(pWswk->authType == authType);
if (pWswk->symWrapMechanism != masterWrapMech ||
- pWswk->exchKeyType != exchKeyType) {
- goto loser;
+ pWswk->authType != authType) {
+ goto loser;
}
wrappedKey.type = siBuffer;
wrappedKey.data = pWswk->wrappedSymmetricWrappingkey;
- wrappedKey.len = pWswk->wrappedSymKeyLen;
+ 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;
-
-#ifndef NSS_DISABLE_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;
+ switch (authType) {
- PORT_Assert(ecWrapped->encodedParamLen + ecWrapped->pubValueLen +
- ecWrapped->wrappedKeyLen <= MAX_EC_WRAPPED_KEY_BUFLEN);
+ case ssl_auth_rsa_decrypt:
+ case ssl_auth_rsa_sign: /* bad: see Bug 1248320 */
+ unwrappedWrappingKey =
+ PK11_PubUnwrapSymKey(svrPrivKey, &wrappedKey,
+ masterWrapMech, CKA_UNWRAP, 0);
+ break;
- if (ecWrapped->encodedParamLen + ecWrapped->pubValueLen +
- ecWrapped->wrappedKeyLen > MAX_EC_WRAPPED_KEY_BUFLEN) {
- PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
- goto loser;
- }
+ case ssl_auth_ecdsa:
+ case ssl_auth_ecdh_rsa:
+ case ssl_auth_ecdh_ecdsa:
+ /*
+ * For ssl_auth_ecd*, 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;
- }
+ 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
+ /* Use Ks to unwrap the wrapping key */
+ unwrappedWrappingKey = PK11_UnwrapSymKey(Ks, masterWrapMech, NULL,
+ &wrappedKey, masterWrapMech,
+ CKA_UNWRAP, 0);
+ PK11_FreeSymKey(Ks);
- default:
- /* Assert? */
- SET_ERROR_CODE
- goto loser;
+ break;
+
+ default:
+ PORT_Assert(0);
+ PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
+ 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
+/* 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 authentication type. These Symkeys
* correspond to the wrapped SymKeys kept in the server session cache.
*/
typedef struct {
- PK11SymKey * symWrapKey[kt_kea_size];
+ PK11SymKey *symWrapKey[ssl_auth_size];
} ssl3SymWrapKey;
-static PZLock * symWrapKeysLock = NULL;
-static ssl3SymWrapKey symWrapKeys[SSL_NUM_WRAP_MECHS];
+static PZLock *symWrapKeysLock = NULL;
+static ssl3SymWrapKey symWrapKeys[SSL_NUM_WRAP_MECHS];
-SECStatus ssl_FreeSymWrapKeysLock(void)
+SECStatus
+ssl_FreeSymWrapKeysLock(void)
{
if (symWrapKeysLock) {
PZ_DestroyLock(symWrapKeysLock);
@@ -5757,21 +5739,21 @@ SECStatus ssl_FreeSymWrapKeysLock(void)
SECStatus
SSL3_ShutdownServerCache(void)
{
- int i, j;
+ int i, j;
if (!symWrapKeysLock)
- return SECSuccess; /* lock was never initialized */
+ 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;
- }
- }
+ for (j = 0; j < ssl_auth_size; ++j) {
+ PK11SymKey **pSymWrapKey;
+ pSymWrapKey = &symWrapKeys[i].symWrapKey[j];
+ if (*pSymWrapKey) {
+ PK11_FreeSymKey(*pSymWrapKey);
+ *pSymWrapKey = NULL;
+ }
+ }
}
PZ_Unlock(symWrapKeysLock);
@@ -5779,7 +5761,8 @@ SSL3_ShutdownServerCache(void)
return SECSuccess;
}
-SECStatus ssl_InitSymWrapKeysLock(void)
+SECStatus
+ssl_InitSymWrapKeysLock(void)
{
symWrapKeysLock = PZ_NewLock(nssILockOther);
return symWrapKeysLock ? SECSuccess : SECFailure;
@@ -5789,43 +5772,53 @@ SECStatus ssl_InitSymWrapKeysLock(void)
* 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.
+ *
+ * Note that this function performs some fairly inadvisable functions with
+ * certificate private keys. ECDSA keys are used with ECDH; similarly, RSA
+ * signing keys are used to encrypt. Bug 1248320.
*/
-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;
+PK11SymKey *
+ssl3_GetWrappingKey(sslSocket *ss,
+ PK11SlotInfo *masterSecretSlot,
+ const sslServerCert *serverCert,
+ CK_MECHANISM_TYPE masterWrapMech,
+ void *pwArg)
+{
+ SSLAuthType authType;
+ 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;
-#ifndef NSS_DISABLE_ECC
- PK11SymKey * Ks = NULL;
- SECKEYPublicKey *pubWrapKey = NULL;
- SECKEYPrivateKey *privWrapKey = NULL;
+ PK11SymKey *Ks = NULL;
+ SECKEYPublicKey *pubWrapKey = NULL;
+ SECKEYPrivateKey *privWrapKey = NULL;
ECCWrappedKeyInfo *ecWrapped;
-#endif /* NSS_DISABLE_ECC */
- svrPrivKey = ss->serverCerts[exchKeyType].SERVERKEY;
- PORT_Assert(svrPrivKey != NULL);
- if (!svrPrivKey) {
- return NULL; /* why are we here?!? */
+ PORT_Assert(serverCert);
+ PORT_Assert(serverCert->serverKeyPair);
+ PORT_Assert(serverCert->serverKeyPair->privKey);
+ PORT_Assert(serverCert->serverKeyPair->pubKey);
+ if (!serverCert || !serverCert->serverKeyPair ||
+ !serverCert->serverKeyPair->privKey ||
+ !serverCert->serverKeyPair->pubKey) {
+ PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
+ return NULL; /* hmm */
}
+ authType = serverCert->certType.authType;
+ svrPrivKey = serverCert->serverKeyPair->privKey;
symWrapMechIndex = ssl_FindIndexByWrapMechanism(masterWrapMech);
PORT_Assert(symWrapMechIndex >= 0);
if (symWrapMechIndex < 0)
- return NULL; /* invalid masterWrapMech. */
+ return NULL; /* invalid masterWrapMech. */
- pSymWrapKey = &symWrapKeys[symWrapMechIndex].symWrapKey[exchKeyType];
+ pSymWrapKey = &symWrapKeys[symWrapMechIndex].symWrapKey[authType];
ssl_InitSessionCacheLocks(PR_TRUE);
@@ -5833,29 +5826,29 @@ getWrappingKey( sslSocket * ss,
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;
+ 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,
+ if (ssl_GetWrappingKey(symWrapMechIndex, authType, &wswk)) {
+ /* found the wrapped sym wrapping key on disk. */
+ unwrappedWrappingKey =
+ ssl_UnwrapSymWrappingKey(&wswk, svrPrivKey, authType,
masterWrapMech, pwArg);
- if (unwrappedWrappingKey) {
- goto install;
- }
+ if (unwrappedWrappingKey) {
+ goto install;
+ }
}
- if (!masterSecretSlot) /* caller doesn't want to create a new one. */
- goto loser;
+ 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.
@@ -5864,163 +5857,163 @@ getWrappingKey( sslSocket * ss,
unwrappedWrappingKey = PK11_KeyGen(masterSecretSlot, masterWrapMech, NULL,
length, pwArg);
if (!unwrappedWrappingKey) {
- goto loser;
+ 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. */
+ 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;
- }
+ svrPubKey = serverCert->serverKeyPair->pubKey;
wrappedKey.type = siBuffer;
- wrappedKey.len = SECKEY_PublicKeyStrength(svrPubKey);
+ wrappedKey.len = SECKEY_PublicKeyStrength(svrPubKey);
wrappedKey.data = wswk.wrappedSymmetricWrappingkey;
PORT_Assert(wrappedKey.len <= sizeof wswk.wrappedSymmetricWrappingkey);
if (wrappedKey.len > sizeof wswk.wrappedSymmetricWrappingkey)
- goto loser;
+ 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;
-
-#ifndef NSS_DISABLE_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_DISABLE_ECC */
-
- default:
- rv = SECFailure;
- break;
+ switch (authType) {
+ case ssl_auth_rsa_decrypt:
+ case ssl_auth_rsa_sign: /* bad: see Bug 1248320 */
+ asymWrapMechanism = CKM_RSA_PKCS;
+ rv = PK11_PubWrapSymKey(asymWrapMechanism, svrPubKey,
+ unwrappedWrappingKey, &wrappedKey);
+ break;
+
+ case ssl_auth_ecdsa:
+ case ssl_auth_ecdh_rsa:
+ case ssl_auth_ecdh_ecdsa:
+ /*
+ * 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(SECKEY_GetPublicKeyType(svrPubKey) == ecKey);
+ if (SECKEY_GetPublicKeyType(svrPubKey) != 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;
+
+ default:
+ rv = SECFailure;
+ break;
}
if (rv != SECSuccess) {
- ssl_MapLowLevelError(SSL_ERROR_CLIENT_KEY_EXCHANGE_FAILURE);
- goto loser;
+ ssl_MapLowLevelError(SSL_ERROR_CLIENT_KEY_EXCHANGE_FAILURE);
+ goto loser;
}
PORT_Assert(asymWrapMechanism != CKM_INVALID_MECHANISM);
- wswk.symWrapMechanism = masterWrapMech;
- wswk.symWrapMechIndex = symWrapMechIndex;
+ wswk.symWrapMechanism = masterWrapMech;
+ wswk.symWrapMechIndex = symWrapMechIndex;
wswk.asymWrapMechanism = asymWrapMechanism;
- wswk.exchKeyType = exchKeyType;
- wswk.wrappedSymKeyLen = wrappedKey.len;
+ wswk.authType = authType;
+ 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
+ /* 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,
+ /* 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, authType,
masterWrapMech, pwArg);
}
install:
if (unwrappedWrappingKey) {
- *pSymWrapKey = PK11_ReferenceSymKey(unwrappedWrappingKey);
+ *pSymWrapKey = PK11_ReferenceSymKey(unwrappedWrappingKey);
}
loser:
@@ -6029,6 +6022,7 @@ done:
return unwrappedWrappingKey;
}
+#ifdef NSS_ALLOW_SSLKEYLOGFILE
/* hexEncode hex encodes |length| bytes from |in| and writes it as |length*2|
* bytes to |out|. */
static void
@@ -6038,23 +6032,23 @@ hexEncode(char *out, const unsigned char *in, unsigned int length)
unsigned int i;
for (i = 0; i < length; i++) {
- *(out++) = hextable[in[i] >> 4];
- *(out++) = hextable[in[i] & 15];
+ *(out++) = hextable[in[i] >> 4];
+ *(out++) = hextable[in[i] & 15];
}
}
+#endif
/* Called from ssl3_SendClientKeyExchange(). */
-/* Presently, this always uses PKCS11. There is no bypass for this. */
static SECStatus
-sendRSAClientKeyExchange(sslSocket * ss, SECKEYPublicKey * svrPubKey)
+ssl3_SendRSAClientKeyExchange(sslSocket *ss, SECKEYPublicKey *svrPubKey)
{
- PK11SymKey * pms = NULL;
- SECStatus rv = SECFailure;
- SECItem enc_pms = {siBuffer, NULL, 0};
- PRBool isTLS;
+ 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));
+ PORT_Assert(ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss));
+ PORT_Assert(ss->opt.noLocks || ssl_HaveXmitBufLock(ss));
/* Generate the pre-master secret ... */
ssl_GetSpecWriteLock(ss);
@@ -6063,68 +6057,71 @@ sendRSAClientKeyExchange(sslSocket * ss, SECKEYPublicKey * svrPubKey)
pms = ssl3_GenerateRSAPMS(ss, ss->ssl3.pwSpec, NULL);
ssl_ReleaseSpecWriteLock(ss);
if (pms == NULL) {
- ssl_MapLowLevelError(SSL_ERROR_CLIENT_KEY_EXCHANGE_FAILURE);
- goto loser;
+ 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);
+ 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 */
+ 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;
+ ssl_MapLowLevelError(SSL_ERROR_CLIENT_KEY_EXCHANGE_FAILURE);
+ goto loser;
}
+#ifdef NSS_ALLOW_SSLKEYLOGFILE
if (ssl_keylog_iob) {
- SECStatus extractRV = PK11_ExtractKeyValue(pms);
- if (extractRV == SECSuccess) {
- SECItem * keyData = PK11_GetKeyData(pms);
- if (keyData && keyData->data && keyData->len) {
+ 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);
- }
+ 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);
- }
- }
- }
+ 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);
+ }
+ }
+ }
}
+#endif
- rv = ssl3_AppendHandshakeHeader(ss, client_key_exchange,
- isTLS ? enc_pms.len + 2 : enc_pms.len);
+ 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* */
+ goto loser; /* err set by ssl3_AppendHandshake* */
}
if (isTLS) {
- rv = ssl3_AppendHandshakeVariable(ss, enc_pms.data, enc_pms.len, 2);
+ rv = ssl3_AppendHandshakeVariable(ss, enc_pms.data, enc_pms.len, 2);
} else {
- rv = ssl3_AppendHandshake(ss, enc_pms.data, enc_pms.len);
+ rv = ssl3_AppendHandshake(ss, enc_pms.data, enc_pms.len);
}
if (rv != SECSuccess) {
- goto loser; /* err set by ssl3_AppendHandshake* */
+ goto loser; /* err set by ssl3_AppendHandshake* */
}
rv = ssl3_InitPendingCipherSpec(ss, pms);
@@ -6132,278 +6129,476 @@ sendRSAClientKeyExchange(sslSocket * ss, SECKEYPublicKey * svrPubKey)
pms = NULL;
if (rv != SECSuccess) {
- ssl_MapLowLevelError(SSL_ERROR_CLIENT_KEY_EXCHANGE_FAILURE);
- goto loser;
+ ssl_MapLowLevelError(SSL_ERROR_CLIENT_KEY_EXCHANGE_FAILURE);
+ goto loser;
}
rv = SECSuccess;
loser:
if (enc_pms.data != NULL) {
- PORT_Free(enc_pms.data);
+ PORT_Free(enc_pms.data);
}
if (pms != NULL) {
- PK11_FreeSymKey(pms);
+ PK11_FreeSymKey(pms);
}
return rv;
}
+/* DH shares need to be padded to the size of their prime. Some implementations
+ * require this. TLS 1.3 also requires this. */
+SECStatus
+ssl_AppendPaddedDHKeyShare(const sslSocket *ss, const SECKEYPublicKey *pubKey,
+ PRBool appendLength)
+{
+ SECStatus rv;
+ unsigned int pad = pubKey->u.dh.prime.len - pubKey->u.dh.publicValue.len;
+
+ if (appendLength) {
+ rv = ssl3_ExtAppendHandshakeNumber(ss, pubKey->u.dh.prime.len, 2);
+ if (rv != SECSuccess) {
+ return rv;
+ }
+ }
+ while (pad) {
+ rv = ssl3_ExtAppendHandshakeNumber(ss, 0, 1);
+ if (rv != SECSuccess) {
+ return rv;
+ }
+ --pad;
+ }
+ rv = ssl3_ExtAppendHandshake(ss, pubKey->u.dh.publicValue.data,
+ pubKey->u.dh.publicValue.len);
+ if (rv != SECSuccess) {
+ return rv;
+ }
+ return SECSuccess;
+}
+
/* Called from ssl3_SendClientKeyExchange(). */
-/* Presently, this always uses PKCS11. There is no bypass for this. */
static SECStatus
-sendDHClientKeyExchange(sslSocket * ss, SECKEYPublicKey * svrPubKey)
+ssl3_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 */
+ PK11SymKey *pms = NULL;
+ SECStatus rv;
+ PRBool isTLS;
+ CK_MECHANISM_TYPE target;
+
+ const ssl3DHParams *params;
+ ssl3DHParams customParams;
+ const sslNamedGroupDef *groupDef;
+ static const sslNamedGroupDef customGroupDef = {
+ ssl_grp_ffdhe_custom, 0, ssl_kea_dh, SEC_OID_TLS_DHE_CUSTOM, PR_FALSE
+ };
+ sslEphemeralKeyPair *keyPair = NULL;
+ SECKEYPublicKey *pubKey;
- PORT_Assert( ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss) );
- PORT_Assert( ss->opt.noLocks || ssl_HaveXmitBufLock(ss));
+ 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;
+ if (SECKEY_GetPublicKeyType(svrPubKey) != dhKey) {
+ PORT_SetError(SEC_ERROR_BAD_KEY);
+ return SECFailure;
}
- 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;
+ /* Work out the parameters. */
+ rv = ssl_ValidateDHENamedGroup(ss, &svrPubKey->u.dh.prime,
+ &svrPubKey->u.dh.base,
+ &groupDef, &params);
+ if (rv != SECSuccess) {
+ /* If we require named groups, we will have already validated the group
+ * in ssl_HandleDHServerKeyExchange() */
+ PORT_Assert(!ss->opt.requireDHENamedGroups &&
+ !ss->xtnData.peerSupportsFfdheGroups);
+
+ customParams.name = ssl_grp_ffdhe_custom;
+ customParams.prime.data = svrPubKey->u.dh.prime.data;
+ customParams.prime.len = svrPubKey->u.dh.prime.len;
+ customParams.base.data = svrPubKey->u.dh.base.data;
+ customParams.base.len = svrPubKey->u.dh.base.len;
+ params = &customParams;
+ groupDef = &customGroupDef;
+ }
+ ss->sec.keaGroup = groupDef;
+
+ rv = ssl_CreateDHEKeyPair(groupDef, params, &keyPair);
+ if (rv != SECSuccess) {
+ ssl_MapLowLevelError(SEC_ERROR_KEYGEN_FAIL);
+ goto loser;
}
+ pubKey = keyPair->keys->pubKey;
PRINT_BUF(50, (ss, "DH public value:",
- pubKey->u.dh.publicValue.data,
- pubKey->u.dh.publicValue.len));
+ 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;
+ 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);
+ pms = PK11_PubDerive(keyPair->keys->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;
+ ssl_MapLowLevelError(SSL_ERROR_CLIENT_KEY_EXCHANGE_FAILURE);
+ goto loser;
}
- SECKEY_DestroyPrivateKey(privKey);
- privKey = NULL;
-
- rv = ssl3_AppendHandshakeHeader(ss, client_key_exchange,
- pubKey->u.dh.publicValue.len + 2);
+ /* Note: send the DH share padded to avoid triggering bugs. */
+ rv = ssl3_AppendHandshakeHeader(ss, client_key_exchange,
+ params->prime.len + 2);
if (rv != SECSuccess) {
- goto loser; /* err set by ssl3_AppendHandshake* */
+ 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;
-
+ rv = ssl_AppendPaddedDHKeyShare(ss, pubKey, PR_TRUE);
if (rv != SECSuccess) {
- goto loser; /* err set by ssl3_AppendHandshake* */
+ goto loser; /* err set by ssl_AppendPaddedDHKeyShare */
}
rv = ssl3_InitPendingCipherSpec(ss, pms);
- PK11_FreeSymKey(pms);
- pms = NULL;
-
if (rv != SECSuccess) {
- ssl_MapLowLevelError(SSL_ERROR_CLIENT_KEY_EXCHANGE_FAILURE);
- goto loser;
+ ssl_MapLowLevelError(SSL_ERROR_CLIENT_KEY_EXCHANGE_FAILURE);
+ goto loser;
}
- rv = SECSuccess;
+ PK11_FreeSymKey(pms);
+ ssl_FreeEphemeralKeyPair(keyPair);
+ return SECSuccess;
loser:
-
- if(pms) PK11_FreeSymKey(pms);
- if(privKey) SECKEY_DestroyPrivateKey(privKey);
- if(pubKey) SECKEY_DestroyPublicKey(pubKey);
- return rv;
+ if (pms)
+ PK11_FreeSymKey(pms);
+ if (keyPair)
+ ssl_FreeEphemeralKeyPair(keyPair);
+ return SECFailure;
}
-
-
-
-
/* Called from ssl3_HandleServerHelloDone(). */
static SECStatus
ssl3_SendClientKeyExchange(sslSocket *ss)
{
- SECKEYPublicKey * serverKey = NULL;
- SECStatus rv = SECFailure;
- PRBool isTLS;
+ SECKEYPublicKey *serverKey = NULL;
+ SECStatus rv = SECFailure;
SSL_TRC(3, ("%d: SSL3[%d]: send client_key_exchange handshake",
- SSL_GETPID(), ss->fd));
+ SSL_GETPID(), ss->fd));
- PORT_Assert( ss->opt.noLocks || ssl_HaveXmitBufLock(ss));
- PORT_Assert( ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss));
+ 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;
- }
+ 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 */
+ 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) {
- unsigned int keyLen = SECKEY_PublicKeyStrengthInBits(serverKey);
-
- if (keyLen > 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.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 ssl_kea_rsa:
+ rv = ssl3_SendRSAClientKeyExchange(ss, serverKey);
+ break;
- case kt_dh:
- rv = sendDHClientKeyExchange(ss, serverKey);
- break;
+ case ssl_kea_dh:
+ rv = ssl3_SendDHClientKeyExchange(ss, serverKey);
+ break;
-#ifndef NSS_DISABLE_ECC
- case kt_ecdh:
- rv = ssl3_SendECDHClientKeyExchange(ss, serverKey);
- break;
-#endif /* NSS_DISABLE_ECC */
+ case ssl_kea_ecdh:
+ rv = ssl3_SendECDHClientKeyExchange(ss, serverKey);
+ break;
- default:
- /* got an unknown or unsupported Key Exchange Algorithm. */
- SEND_ALERT
- PORT_SetError(SEC_ERROR_UNSUPPORTED_KEYALG);
- break;
+ default:
+ PORT_Assert(0);
+ PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
+ break;
}
SSL_TRC(3, ("%d: SSL3[%d]: DONE sending client_key_exchange",
- SSL_GETPID(), ss->fd));
+ SSL_GETPID(), ss->fd));
-loser:
- if (serverKey)
- SECKEY_DestroyPublicKey(serverKey);
- return rv; /* err code already set. */
+ SECKEY_DestroyPublicKey(serverKey);
+ return rv; /* err code already set. */
+}
+
+SECStatus
+ssl_PickSignatureScheme(sslSocket *ss,
+ SECKEYPublicKey *pubKey,
+ SECKEYPrivateKey *privKey,
+ const SSLSignatureScheme *peerSchemes,
+ unsigned int peerSchemeCount,
+ PRBool requireSha1)
+{
+ unsigned int i, j;
+ const sslNamedGroupDef *group = NULL;
+ KeyType keyType;
+ PK11SlotInfo *slot;
+ PRBool slotDoesPss;
+ PRBool isTLS13 = ss->version >= SSL_LIBRARY_VERSION_TLS_1_3;
+
+ /* We can't require SHA-1 in TLS 1.3. */
+ PORT_Assert(!(requireSha1 && isTLS13));
+ if (!pubKey || !privKey) {
+ PORT_Assert(0);
+ PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
+ return SECFailure;
+ }
+
+ slot = PK11_GetSlotFromPrivateKey(privKey);
+ if (!slot) {
+ PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
+ return SECFailure;
+ }
+ slotDoesPss = PK11_DoesMechanism(slot, auth_alg_defs[ssl_auth_rsa_pss]);
+ PK11_FreeSlot(slot);
+
+ keyType = SECKEY_GetPublicKeyType(pubKey);
+ if (keyType == ecKey) {
+ group = ssl_ECPubKey2NamedGroup(pubKey);
+ }
+
+ /* Here we look for the first local preference that the client has
+ * indicated support for in their signature_algorithms extension. */
+ for (i = 0; i < ss->ssl3.signatureSchemeCount; ++i) {
+ SSLHashType hashType;
+ SECOidTag hashOID;
+ SSLSignatureScheme preferred = ss->ssl3.signatureSchemes[i];
+ PRUint32 policy;
+
+ if (!ssl_SignatureSchemeValidForKey(!isTLS13 /* allowSha1 */,
+ PR_TRUE /* matchGroup */,
+ keyType, group, preferred)) {
+ continue;
+ }
+
+ /* Skip RSA-PSS schemes when the certificate's private key slot does
+ * not support this signature mechanism. */
+ if (ssl_IsRsaPssSignatureScheme(preferred) && !slotDoesPss) {
+ continue;
+ }
+
+ hashType = ssl_SignatureSchemeToHashType(preferred);
+ if (requireSha1 && (hashType != ssl_hash_sha1)) {
+ continue;
+ }
+ hashOID = ssl3_HashTypeToOID(hashType);
+ if ((NSS_GetAlgorithmPolicy(hashOID, &policy) == SECSuccess) &&
+ !(policy & NSS_USE_ALG_IN_SSL_KX)) {
+ /* we ignore hashes we don't support */
+ continue;
+ }
+
+ for (j = 0; j < peerSchemeCount; j++) {
+ if (peerSchemes[j] == preferred) {
+ ss->ssl3.hs.signatureScheme = preferred;
+ return SECSuccess;
+ }
+ }
+ }
+
+ PORT_SetError(SSL_ERROR_UNSUPPORTED_SIGNATURE_ALGORITHM);
+ return SECFailure;
+}
+
+/* ssl3_PickServerSignatureScheme selects a signature scheme for signing the
+ * handshake. Most of this is determined by the key pair we are using.
+ * Prior to TLS 1.2, the MD5/SHA1 combination is always used. With TLS 1.2, a
+ * client may advertise its support for signature and hash combinations. */
+static SECStatus
+ssl3_PickServerSignatureScheme(sslSocket *ss)
+{
+ sslKeyPair *keyPair = ss->sec.serverCert->serverKeyPair;
+ PRBool isTLS12 = ss->version >= SSL_LIBRARY_VERSION_TLS_1_2;
+
+ if (!isTLS12 || !ssl3_ExtensionNegotiated(ss, ssl_signature_algorithms_xtn)) {
+ /* If the client didn't provide any signature_algorithms extension then
+ * we can assume that they support SHA-1: RFC5246, Section 7.4.1.4.1. */
+ switch (SECKEY_GetPublicKeyType(keyPair->pubKey)) {
+ case rsaKey:
+ if (isTLS12) {
+ ss->ssl3.hs.signatureScheme = ssl_sig_rsa_pkcs1_sha1;
+ } else {
+ ss->ssl3.hs.signatureScheme = ssl_sig_rsa_pkcs1_sha1md5;
+ }
+ break;
+ case ecKey:
+ ss->ssl3.hs.signatureScheme = ssl_sig_ecdsa_sha1;
+ break;
+ case dsaKey:
+ ss->ssl3.hs.signatureScheme = ssl_sig_dsa_sha1;
+ break;
+ default:
+ PORT_Assert(0);
+ PORT_SetError(SEC_ERROR_INVALID_KEY);
+ return SECFailure;
+ }
+ return SECSuccess;
+ }
+
+ /* Sets error code, if needed. */
+ return ssl_PickSignatureScheme(ss, keyPair->pubKey, keyPair->privKey,
+ ss->xtnData.clientSigSchemes,
+ ss->xtnData.numClientSigScheme,
+ PR_FALSE /* requireSha1 */);
+}
+
+static SECStatus
+ssl_PickClientSignatureScheme(sslSocket *ss, const SSLSignatureScheme *schemes,
+ unsigned int numSchemes)
+{
+ SECKEYPrivateKey *privKey = ss->ssl3.clientPrivateKey;
+ SECKEYPublicKey *pubKey;
+ SECStatus rv;
+
+ pubKey = CERT_ExtractPublicKey(ss->ssl3.clientCertificate);
+ PORT_Assert(pubKey);
+ if (ss->version < SSL_LIBRARY_VERSION_TLS_1_3 &&
+ (SECKEY_GetPublicKeyType(pubKey) == rsaKey ||
+ SECKEY_GetPublicKeyType(pubKey) == dsaKey) &&
+ SECKEY_PublicKeyStrengthInBits(pubKey) <= 1024) {
+ /* If the key is a 1024-bit RSA or DSA key, assume conservatively that
+ * it may be unable to sign SHA-256 hashes. This is the case for older
+ * Estonian ID cards that have 1024-bit RSA keys. In FIPS 186-2 and
+ * older, DSA key size is at most 1024 bits and the hash function must
+ * be SHA-1.
+ */
+ rv = ssl_PickSignatureScheme(ss, pubKey, privKey, schemes, numSchemes,
+ PR_TRUE /* requireSha1 */);
+ if (rv == SECSuccess) {
+ SECKEY_DestroyPublicKey(pubKey);
+ return SECSuccess;
+ }
+ /* If this fails, that's because the peer doesn't advertise SHA-1,
+ * so fall back to the full negotiation. */
+ }
+ rv = ssl_PickSignatureScheme(ss, pubKey, privKey, schemes, numSchemes,
+ PR_FALSE /* requireSha1 */);
+ SECKEY_DestroyPublicKey(pubKey);
+ return rv;
}
/* Called from ssl3_HandleServerHelloDone(). */
static SECStatus
-ssl3_SendCertificateVerify(sslSocket *ss)
+ssl3_SendCertificateVerify(sslSocket *ss, SECKEYPrivateKey *privKey)
{
- SECStatus rv = SECFailure;
- PRBool isTLS;
- PRBool isTLS12;
- SECItem buf = {siBuffer, NULL, 0};
- SSL3Hashes hashes;
- KeyType keyType;
- unsigned int len;
- SSLSignatureAndHashAlg sigAndHash;
+ SECStatus rv = SECFailure;
+ PRBool isTLS12;
+ SECItem buf = { siBuffer, NULL, 0 };
+ SSL3Hashes hashes;
+ unsigned int len;
+ SSLHashType hashAlg;
- PORT_Assert( ss->opt.noLocks || ssl_HaveXmitBufLock(ss));
- PORT_Assert( ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss));
+ 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_GETPID(), ss->fd));
ssl_GetSpecReadLock(ss);
- if (ss->ssl3.hs.hashType == handshake_hash_single &&
- ss->ssl3.hs.backupHash) {
- rv = ssl3_ComputeBackupHandshakeHashes(ss, &hashes);
- PORT_Assert(!ss->ssl3.hs.backupHash);
+
+ if (ss->ssl3.hs.hashType == handshake_hash_record) {
+ hashAlg = ssl_SignatureSchemeToHashType(ss->ssl3.hs.signatureScheme);
} else {
- rv = ssl3_ComputeHandshakeHashes(ss, ss->ssl3.pwSpec, &hashes, 0);
+ /* Use ssl_hash_none to represent the MD5+SHA1 combo. */
+ hashAlg = ssl_hash_none;
+ }
+ if (ss->ssl3.hs.hashType == handshake_hash_record &&
+ hashAlg != ssl3_GetSuitePrfHash(ss)) {
+ rv = ssl3_ComputeHandshakeHash(ss->ssl3.hs.messages.buf,
+ ss->ssl3.hs.messages.len,
+ hashAlg, &hashes);
+ if (rv != SECSuccess) {
+ ssl_MapLowLevelError(SSL_ERROR_DIGEST_FAILURE);
+ }
+ } else {
+ rv = ssl3_ComputeHandshakeHashes(ss, ss->ssl3.pwSpec, &hashes, 0);
}
ssl_ReleaseSpecReadLock(ss);
if (rv != SECSuccess) {
- goto done; /* err code was set by ssl3_ComputeHandshakeHashes */
+ goto done; /* err code was set by ssl3_ComputeHandshakeHash(es) */
}
- isTLS = (PRBool)(ss->ssl3.pwSpec->version > SSL_LIBRARY_VERSION_3_0);
- isTLS12 = (PRBool)(ss->ssl3.pwSpec->version >= SSL_LIBRARY_VERSION_TLS_1_2);
- keyType = ss->ssl3.clientPrivateKey->keyType;
- 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;
+ isTLS12 = (PRBool)(ss->version == SSL_LIBRARY_VERSION_TLS_1_2);
+ PORT_Assert(ss->version <= SSL_LIBRARY_VERSION_TLS_1_2);
+
+ rv = ssl3_SignHashes(ss, &hashes, privKey, &buf);
+ if (rv == SECSuccess && !ss->sec.isServer) {
+ /* 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.
+ */
+ PK11SlotInfo *slot;
+ sslSessionID *sid = ss->sec.ci.sid;
+
+ slot = PK11_GetSlotFromPrivateKey(privKey);
+ 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);
+ }
if (rv != SECSuccess) {
- goto done; /* err code was set by ssl3_SignHashes */
+ goto done; /* err code was set by ssl3_SignHashes */
}
len = buf.len + 2 + (isTLS12 ? 2 : 0);
rv = ssl3_AppendHandshakeHeader(ss, certificate_verify, len);
if (rv != SECSuccess) {
- goto done; /* error code set by AppendHandshake */
+ goto done; /* error code set by AppendHandshake */
}
if (isTLS12) {
- rv = ssl3_TLSSignatureAlgorithmForKeyType(keyType,
- &sigAndHash.sigAlg);
- if (rv != SECSuccess) {
- goto done;
- }
- sigAndHash.hashAlg = hashes.hashAlg;
-
- rv = ssl3_AppendSignatureAndHashAlgorithm(ss, &sigAndHash);
- if (rv != SECSuccess) {
- goto done; /* err set by AppendHandshake. */
- }
+ rv = ssl3_AppendHandshakeNumber(ss, ss->ssl3.hs.signatureScheme, 2);
+ if (rv != SECSuccess) {
+ goto done; /* err set by AppendHandshake. */
+ }
}
rv = ssl3_AppendHandshakeVariable(ss, buf.data, buf.len, 2);
if (rv != SECSuccess) {
- goto done; /* error code set by AppendHandshake */
+ goto done; /* error code set by AppendHandshake */
}
done:
if (buf.data)
- PORT_Free(buf.data);
+ PORT_Free(buf.data);
return rv;
}
+/* Once a cipher suite has been selected, make sure that the necessary secondary
+ * information is properly set. */
+SECStatus
+ssl3_SetCipherSuite(sslSocket *ss, ssl3CipherSuite chosenSuite,
+ PRBool initHashes)
+{
+ ss->ssl3.hs.cipher_suite = chosenSuite;
+ ss->ssl3.hs.suite_def = ssl_LookupCipherSuiteDef(chosenSuite);
+ if (!ss->ssl3.hs.suite_def) {
+ PORT_Assert(0);
+ PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
+ return SECFailure;
+ }
+
+ ss->ssl3.hs.kea_def = &kea_defs[ss->ssl3.hs.suite_def->key_exchange_alg];
+ ss->ssl3.hs.preliminaryInfo |= ssl_preinfo_cipher_suite;
+
+ if (!initHashes) {
+ return SECSuccess;
+ }
+ /* Now we've have a cipher suite, initialize the handshake hashes. */
+ return ssl3_InitHandshakeHashes(ss);
+}
+
/* Called from ssl3_HandleHandshakeMessage() when it has deciphered a complete
* ssl3 ServerHello message.
* Caller must hold Handshake and RecvBuf locks.
@@ -6411,162 +6606,190 @@ done:
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;
+ 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 isTLS = PR_FALSE;
+ SSL3AlertDescription desc = illegal_parameter;
+#ifndef TLS_1_3_DRAFT_VERSION
+ SSL3ProtocolVersion downgradeCheckVersion;
+#endif
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) );
- PORT_Assert( ss->ssl3.initialized );
+ SSL_GETPID(), ss->fd));
+ PORT_Assert(ss->opt.noLocks || ssl_HaveRecvBufLock(ss));
+ PORT_Assert(ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss));
+ PORT_Assert(ss->ssl3.initialized);
if (ss->ssl3.hs.ws != wait_server_hello) {
errCode = SSL_ERROR_RX_UNEXPECTED_SERVER_HELLO;
- desc = unexpected_message;
- goto alert_loser;
+ 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;
+ CERT_DestroyCertificateList(ss->ssl3.clientCertChain);
+ ss->ssl3.clientCertChain = NULL;
}
if (ss->ssl3.clientCertificate != NULL) {
- CERT_DestroyCertificate(ss->ssl3.clientCertificate);
- 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;
+ 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 */
+ rv = ssl_ClientReadVersion(ss, &b, &length, &ss->version);
+ if (rv != SECSuccess) {
+ 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;
- }
+ /* We got a HelloRetryRequest, but the server didn't pick 1.3. Scream. */
+ if (ss->ssl3.hs.helloRetry && ss->version < SSL_LIBRARY_VERSION_TLS_1_3) {
+ desc = illegal_parameter;
+ errCode = SSL_ERROR_RX_MALFORMED_SERVER_HELLO;
+ 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_UNSUPPORTED_VERSION;
- goto alert_loser;
+ /* Check that the server negotiated the same version as it did
+ * in the first handshake. This isn't really the best place for
+ * us to be getting this version number, but it's what we have.
+ * (1294697). */
+ if (ss->firstHsDone && (ss->version != ss->ssl3.crSpec->version)) {
+ desc = illegal_parameter;
+ errCode = SSL_ERROR_UNSUPPORTED_VERSION;
+ goto alert_loser;
}
ss->ssl3.hs.preliminaryInfo |= ssl_preinfo_version;
isTLS = (ss->version > SSL_LIBRARY_VERSION_3_0);
- rv = ssl3_InitHandshakeHashes(ss);
- if (rv != SECSuccess) {
- desc = internal_error;
- errCode = PORT_GetError();
- goto alert_loser;
- }
-
rv = ssl3_ConsumeHandshake(
- ss, &ss->ssl3.hs.server_random, SSL3_RANDOM_LENGTH, &b, &length);
+ ss, &ss->ssl3.hs.server_random, SSL3_RANDOM_LENGTH, &b, &length);
if (rv != SECSuccess) {
- goto loser; /* alert has been sent */
+ goto loser; /* alert has been sent */
}
- rv = ssl3_ConsumeHandshakeVariable(ss, &sidBytes, 1, &b, &length);
- if (rv != SECSuccess) {
- goto loser; /* alert has been sent */
+#ifndef TLS_1_3_DRAFT_VERSION
+ /* Check the ServerHello.random per
+ * [draft-ietf-tls-tls13-11 Section 6.3.1.1].
+ *
+ * TLS 1.3 clients receiving a TLS 1.2 or below ServerHello MUST check
+ * that the top eight octets are not equal to either of these values.
+ * TLS 1.2 clients SHOULD also perform this check if the ServerHello
+ * indicates TLS 1.1 or below. If a match is found the client MUST
+ * abort the handshake with a fatal "illegal_parameter" alert.
+ *
+ * Disable this test during the TLS 1.3 draft version period.
+ */
+ downgradeCheckVersion = ss->ssl3.downgradeCheckVersion ? ss->ssl3.downgradeCheckVersion
+ : ss->vrange.max;
+
+ if (downgradeCheckVersion >= SSL_LIBRARY_VERSION_TLS_1_2 &&
+ downgradeCheckVersion > ss->version) {
+ /* Both sections use the same sentinel region. */
+ unsigned char *downgrade_sentinel =
+ ss->ssl3.hs.server_random.rand +
+ SSL3_RANDOM_LENGTH - sizeof(tls13_downgrade_random);
+ if (!PORT_Memcmp(downgrade_sentinel,
+ tls13_downgrade_random,
+ sizeof(tls13_downgrade_random)) ||
+ !PORT_Memcmp(downgrade_sentinel,
+ tls12_downgrade_random,
+ sizeof(tls12_downgrade_random))) {
+ desc = illegal_parameter;
+ errCode = SSL_ERROR_RX_MALFORMED_SERVER_HELLO;
+ goto alert_loser;
+ }
}
- if (sidBytes.len > SSL3_SESSIONID_BYTES) {
- if (isTLS)
- desc = decode_error;
- goto alert_loser; /* malformed. */
+#endif
+
+ if (ss->version < SSL_LIBRARY_VERSION_TLS_1_3) {
+ 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 */
+ goto loser; /* alert has been sent */
+ }
+ i = ssl3_config_match_init(ss);
+ PORT_Assert(i > 0);
+ if (i <= 0) {
+ errCode = PORT_GetError();
+ goto loser;
}
- ssl3_config_match_init(ss);
for (i = 0; i < ssl_V3_SUITES_IMPLEMENTED; i++) {
- ssl3CipherSuiteCfg *suite = &ss->cipherSuites[i];
- if (temp == suite->cipher_suite) {
- SSLVersionRange vrange = {ss->version, ss->version};
- if (!config_match(suite, ss->ssl3.policy, PR_TRUE, &vrange, ss)) {
- /* config_match already checks whether the cipher suite is
- * acceptable for the version, but the check is repeated here
- * in order to give a more precise error code. */
- if (!ssl3_CipherSuiteAllowedForVersionRange(temp, &vrange)) {
- desc = handshake_failure;
- errCode = SSL_ERROR_CIPHER_DISALLOWED_FOR_VERSION;
- goto alert_loser;
- }
-
- break; /* failure */
- }
-
- suite_found = PR_TRUE;
- break; /* success */
- }
+ ssl3CipherSuiteCfg *suite = &ss->cipherSuites[i];
+ if (temp == suite->cipher_suite) {
+ SSLVersionRange vrange = { ss->version, ss->version };
+ if (!config_match(suite, ss->ssl3.policy, &vrange, ss)) {
+ /* config_match already checks whether the cipher suite is
+ * acceptable for the version, but the check is repeated here
+ * in order to give a more precise error code. */
+ if (!ssl3_CipherSuiteAllowedForVersionRange(temp, &vrange)) {
+ desc = handshake_failure;
+ errCode = SSL_ERROR_CIPHER_DISALLOWED_FOR_VERSION;
+ goto alert_loser;
+ }
+
+ break; /* failure */
+ }
+
+ 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);
- ss->ssl3.hs.preliminaryInfo |= ssl_preinfo_cipher_suite;
- 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. */
+ desc = handshake_failure;
+ errCode = SSL_ERROR_NO_CYPHER_OVERLAP;
+ goto alert_loser;
}
- /* 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 */
- }
+ rv = ssl3_SetCipherSuite(ss, (ssl3CipherSuite)temp, PR_TRUE);
+ if (rv != SECSuccess) {
+ desc = internal_error;
+ errCode = PORT_GetError();
+ goto alert_loser;
}
- if (!suite_found) {
- desc = handshake_failure;
- errCode = SSL_ERROR_NO_COMPRESSION_OVERLAP;
- goto alert_loser;
+
+ if (ss->version < SSL_LIBRARY_VERSION_TLS_1_3) {
+ /* 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 < ssl_compression_method_count; i++) {
+ if (temp == ssl_compression_methods[i]) {
+ if (!ssl_CompressionEnabled(ss, ssl_compression_methods[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;
+ } else {
+ ss->ssl3.hs.compression = ssl_compression_null;
}
- ss->ssl3.hs.compression = (SSLCompressionMethod)temp;
/* Note that if !isTLS and the extra stuff is not extensions, we
* do NOT goto alert_loser.
@@ -6578,36 +6801,72 @@ ssl3_HandleServerHello(sslSocket *ss, SSL3Opaque *b, PRUint32 length)
* 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 ||
+ SECItem extensions;
+ rv = ssl3_ConsumeHandshakeVariable(ss, &extensions, 2, &b, &length);
+ if (rv != SECSuccess || length != 0) {
+ if (isTLS)
+ goto alert_loser;
+ } else {
+ rv = ssl3_HandleExtensions(ss, &extensions.data,
+ &extensions.len, server_hello);
+ if (rv != SECSuccess)
+ goto alert_loser;
+ }
+ }
+
+ if (ss->version >= SSL_LIBRARY_VERSION_TLS_1_3) {
+ rv = tls13_HandleServerHelloPart2(ss);
+ if (rv != SECSuccess) {
+ errCode = PORT_GetError();
+ goto loser;
+ }
+ } else {
+ rv = ssl3_HandleServerHelloPart2(ss, &sidBytes, &errCode);
+ if (rv != SECSuccess)
+ goto loser;
+ }
+
+ return SECSuccess;
+
+alert_loser:
+ (void)SSL3_SendAlert(ss, alert_fatal, desc);
+
+loser:
+ /* Clean up the temporary pointer to the handshake buffer. */
+ ss->xtnData.signedCertTimestamps.len = 0;
+ ssl_MapLowLevelError(errCode);
+ return SECFailure;
+}
+
+static SECStatus
+ssl3_HandleServerHelloPart2(sslSocket *ss, const SECItem *sidBytes,
+ int *retErrCode)
+{
+ SSL3AlertDescription desc = handshake_failure;
+ int errCode = SSL_ERROR_RX_MALFORMED_SERVER_HELLO;
+ SECStatus rv;
+ PRBool sid_match;
+ sslSessionID *sid = ss->sec.ci.sid;
+
+ 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;
+ 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;
+ 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. */
+ goto alert_loser; /* error code is set. */
}
/* We may or may not have sent a session id, we may get one back or
@@ -6615,179 +6874,174 @@ ssl3_HandleServerHello(sslSocket *ss, SSL3Opaque *b, PRUint32 length)
* 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. */
-
- /* [draft-ietf-tls-session-hash-06; Section 5.3]
- *
- * o If the original session did not use the "extended_master_secret"
- * extension but the new ServerHello contains the extension, the
- * client MUST abort the handshake.
- */
- if (!sid->u.ssl3.keys.extendedMasterSecretUsed &&
- ssl3_ExtensionNegotiated(ss, ssl_extended_master_secret_xtn)) {
- errCode = SSL_ERROR_UNEXPECTED_EXTENDED_MASTER_SECRET;
+ 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) {
+ if (sid->version != ss->version ||
+ sid->u.ssl3.cipherSuite != ss->ssl3.hs.cipher_suite) {
+ errCode = SSL_ERROR_RX_MALFORMED_SERVER_HELLO;
goto alert_loser;
}
+ do {
+ ssl3CipherSpec *pwSpec = ss->ssl3.pwSpec;
+
+ SECItem wrappedMS; /* wrapped master secret. */
+
+ /* [draft-ietf-tls-session-hash-06; Section 5.3]
+ *
+ * o If the original session did not use the "extended_master_secret"
+ * extension but the new ServerHello contains the extension, the
+ * client MUST abort the handshake.
+ */
+ if (!sid->u.ssl3.keys.extendedMasterSecretUsed &&
+ ssl3_ExtensionNegotiated(ss, ssl_extended_master_secret_xtn)) {
+ errCode = SSL_ERROR_UNEXPECTED_EXTENDED_MASTER_SECRET;
+ goto alert_loser;
+ }
- /*
- * o If the original session used an extended master secret but the new
- * ServerHello does not contain the "extended_master_secret"
- * extension, the client SHOULD abort the handshake.
- *
- * TODO(ekr@rtfm.com): Add option to refuse to resume when EMS is not
- * used at all (bug 1176526).
- */
- if (sid->u.ssl3.keys.extendedMasterSecretUsed &&
- !ssl3_ExtensionNegotiated(ss, ssl_extended_master_secret_xtn)) {
- errCode = SSL_ERROR_MISSING_EXTENDED_MASTER_SECRET;
- goto alert_loser;
- }
+ /*
+ * o If the original session used an extended master secret but the new
+ * ServerHello does not contain the "extended_master_secret"
+ * extension, the client SHOULD abort the handshake.
+ *
+ * TODO(ekr@rtfm.com): Add option to refuse to resume when EMS is not
+ * used at all (bug 1176526).
+ */
+ if (sid->u.ssl3.keys.extendedMasterSecretUsed &&
+ !ssl3_ExtensionNegotiated(ss, ssl_extended_master_secret_xtn)) {
+ errCode = SSL_ERROR_MISSING_EXTENDED_MASTER_SECRET;
+ goto alert_loser;
+ }
- 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 (ss->xtnData.sentSessionTicketInClientHello)
- 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 because we are reusing the old MS */
- rv = ssl3_InitPendingCipherSpec(ss, NULL);
- if (rv != SECSuccess) {
- goto alert_loser; /* err code was set */
- }
- return SECSuccess;
- } while (0);
+ ss->sec.authType = sid->authType;
+ ss->sec.authKeyBits = sid->authKeyBits;
+ ss->sec.keaType = sid->keaType;
+ ss->sec.keaKeyBits = sid->keaKeyBits;
+
+ if (sid->u.ssl3.keys.msIsWrapped) {
+ PK11SlotInfo *slot;
+ PK11SymKey *wrapKey; /* wrapping key */
+ CK_FLAGS keyFlags = 0;
+
+ /* unwrap master secret */
+ 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. */
+ }
+ } else {
+ /* 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 (ss->xtnData.sentSessionTicketInClientHello)
+ 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 because we are reusing 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 );
+ SSL_AtomicIncrementLong(&ssl3stats.hsh_sid_cache_not_ok);
else
- SSL_AtomicIncrementLong(& ssl3stats.hsh_sid_cache_misses );
+ 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);
+ 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. */
+ 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);
+ sid->u.ssl3.sessionIDLength = sidBytes->len;
+ if (sidBytes->len > 0) {
+ PORT_Memcpy(sid->u.ssl3.sessionID, sidBytes->data, sidBytes->len);
+ }
sid->u.ssl3.keys.extendedMasterSecretUsed =
- ssl3_ExtensionNegotiated(ss, ssl_extended_master_secret_xtn);
+ ssl3_ExtensionNegotiated(ss, ssl_extended_master_secret_xtn);
+
+ /* Copy Signed Certificate Timestamps, if any. */
+ if (ss->xtnData.signedCertTimestamps.len) {
+ rv = SECITEM_CopyItem(NULL, &sid->u.ssl3.signedCertTimestamps,
+ &ss->xtnData.signedCertTimestamps);
+ ss->xtnData.signedCertTimestamps.len = 0;
+ if (rv != SECSuccess)
+ goto loser;
+ }
ss->ssl3.hs.isResuming = PR_FALSE;
- if (ss->ssl3.hs.kea_def->signKeyType != sign_null) {
- /* All current cipher suites other than those with sign_null (i.e.,
+ if (ss->ssl3.hs.kea_def->authKeyType != ssl_auth_null) {
+ /* All current cipher suites other than those with ssl_auth_null (i.e.,
* (EC)DH_anon_* suites) require a certificate, so use that signal. */
ss->ssl3.hs.ws = wait_server_cert;
} else {
@@ -6803,413 +7057,376 @@ alert_loser:
(void)SSL3_SendAlert(ss, alert_fatal, desc);
loser:
- errCode = ssl_MapLowLevelError(errCode);
+ *retErrCode = errCode;
return SECFailure;
}
-
-/* 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)
+ssl_HandleDHServerKeyExchange(sslSocket *ss, SSL3Opaque *b, PRUint32 length)
{
- PLArenaPool * arena = NULL;
- SECKEYPublicKey *peerKey = NULL;
- PRBool isTLS, isTLS12;
- SECStatus rv;
- int errCode = SSL_ERROR_RX_MALFORMED_SERVER_KEY_EXCH;
- SSL3AlertDescription desc = illegal_parameter;
- SSL3Hashes hashes;
- SECItem signature = {siBuffer, NULL, 0};
- SSLSignatureAndHashAlg sigAndHash;
+ SECStatus rv;
+ int errCode = SSL_ERROR_RX_MALFORMED_SERVER_KEY_EXCH;
+ SSL3AlertDescription desc = illegal_parameter;
+ SSLHashType hashAlg;
+ PRBool isTLS = ss->ssl3.prSpec->version > SSL_LIBRARY_VERSION_3_0;
+ SSLSignatureScheme sigScheme;
+
+ SECItem dh_p = { siBuffer, NULL, 0 };
+ SECItem dh_g = { siBuffer, NULL, 0 };
+ SECItem dh_Ys = { siBuffer, NULL, 0 };
+ unsigned dh_p_bits;
+ unsigned dh_g_bits;
+ PRInt32 minDH;
- sigAndHash.hashAlg = ssl_hash_none;
+ SSL3Hashes hashes;
+ SECItem signature = { siBuffer, NULL, 0 };
+ PLArenaPool *arena = NULL;
+ SECKEYPublicKey *peerKey = NULL;
- 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) );
+ rv = ssl3_ConsumeHandshakeVariable(ss, &dh_p, 2, &b, &length);
+ if (rv != SECSuccess) {
+ goto loser; /* malformed. */
+ }
- if (ss->ssl3.hs.ws != wait_server_key) {
- errCode = SSL_ERROR_RX_UNEXPECTED_SERVER_KEY_EXCH;
- desc = unexpected_message;
+ rv = NSS_OptionGet(NSS_DH_MIN_KEY_SIZE, &minDH);
+ if (rv != SECSuccess) {
+ minDH = SSL_DH_MIN_P_BITS;
+ }
+ dh_p_bits = SECKEY_BigIntegerBitLength(&dh_p);
+ if (dh_p_bits < minDH) {
+ errCode = SSL_ERROR_WEAK_SERVER_EPHEMERAL_DH_KEY;
goto alert_loser;
}
-
- isTLS = (PRBool)(ss->ssl3.prSpec->version > SSL_LIBRARY_VERSION_3_0);
- isTLS12 = (PRBool)(ss->ssl3.prSpec->version >= SSL_LIBRARY_VERSION_TLS_1_2);
-
- 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. */
- }
- /* This exchange method is only used by export cipher suites.
- * Those are broken and so this code will eventually be removed. */
- if (SECKEY_BigIntegerBitLength(&modulus) < 512) {
- desc = isTLS ? insufficient_security : illegal_parameter;
+ rv = ssl3_ConsumeHandshakeVariable(ss, &dh_g, 2, &b, &length);
+ if (rv != SECSuccess) {
+ goto loser; /* malformed. */
+ }
+ /* Abort if dh_g is 0, 1, or obviously too big. */
+ dh_g_bits = SECKEY_BigIntegerBitLength(&dh_g);
+ if (dh_g_bits > dh_p_bits || dh_g_bits <= 1) {
+ goto alert_loser;
+ }
+ if (ss->opt.requireDHENamedGroups) {
+ /* If we're doing named groups, make sure it's good. */
+ rv = ssl_ValidateDHENamedGroup(ss, &dh_p, &dh_g, NULL, NULL);
+ if (rv != SECSuccess) {
+ errCode = SSL_ERROR_WEAK_SERVER_EPHEMERAL_DH_KEY;
goto alert_loser;
}
- rv = ssl3_ConsumeHandshakeVariable(ss, &exponent, 2, &b, &length);
- if (rv != SECSuccess) {
- goto loser; /* malformed. */
- }
- if (isTLS12) {
- rv = ssl3_ConsumeSignatureAndHashAlgorithm(ss, &b, &length,
- &sigAndHash);
- if (rv != SECSuccess) {
- goto loser; /* malformed or unsupported. */
- }
- rv = ssl3_CheckSignatureAndHashAlgorithmConsistency(ss,
- &sigAndHash, ss->sec.peerCert);
- if (rv != SECSuccess) {
- goto 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. */
- }
-
- /* 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(sigAndHash.hashAlg, modulus, exponent,
- &ss->ssl3.hs.client_random,
- &ss->ssl3.hs.server_random,
- &hashes, ss->opt.bypassPKCS11);
+ }
+
+ rv = ssl3_ConsumeHandshakeVariable(ss, &dh_Ys, 2, &b, &length);
+ if (rv != SECSuccess) {
+ goto loser; /* malformed. */
+ }
+ if (!ssl_IsValidDHEShare(&dh_p, &dh_Ys)) {
+ errCode = SSL_ERROR_RX_MALFORMED_DHE_KEY_SHARE;
+ goto alert_loser;
+ }
+
+ if (ss->version >= SSL_LIBRARY_VERSION_TLS_1_2) {
+ rv = ssl_ConsumeSignatureScheme(ss, &b, &length, &sigScheme);
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) {
- 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))
- {
- 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};
- unsigned dh_p_bits;
- unsigned dh_g_bits;
- unsigned dh_Ys_bits;
- PRInt32 minDH;
-
- rv = ssl3_ConsumeHandshakeVariable(ss, &dh_p, 2, &b, &length);
- if (rv != SECSuccess) {
- goto loser; /* malformed. */
- }
-
- rv = NSS_OptionGet(NSS_DH_MIN_KEY_SIZE, &minDH);
- if (rv != SECSuccess) {
- minDH = SSL_DH_MIN_P_BITS;
- }
- dh_p_bits = SECKEY_BigIntegerBitLength(&dh_p);
- if (dh_p_bits < minDH) {
- 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. */
- }
- /* Abort if dh_g is 0, 1, or obviously too big. */
- dh_g_bits = SECKEY_BigIntegerBitLength(&dh_g);
- if (dh_g_bits > dh_p_bits || dh_g_bits <= 1)
- goto alert_loser;
- rv = ssl3_ConsumeHandshakeVariable(ss, &dh_Ys, 2, &b, &length);
- if (rv != SECSuccess) {
- goto loser; /* malformed. */
- }
- dh_Ys_bits = SECKEY_BigIntegerBitLength(&dh_Ys);
- if (dh_Ys_bits > dh_p_bits || dh_Ys_bits <= 1)
- goto alert_loser;
- if (isTLS12) {
- rv = ssl3_ConsumeSignatureAndHashAlgorithm(ss, &b, &length,
- &sigAndHash);
- if (rv != SECSuccess) {
- goto loser; /* malformed or unsupported. */
- }
- rv = ssl3_CheckSignatureAndHashAlgorithmConsistency(ss,
- &sigAndHash, ss->sec.peerCert);
- if (rv != SECSuccess) {
- goto 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(sigAndHash.hashAlg, dh_p, dh_g, dh_Ys,
- &ss->ssl3.hs.client_random,
- &ss->ssl3.hs.server_random,
- &hashes, ss->opt.bypassPKCS11);
+ goto loser; /* malformed or unsupported. */
+ }
+ rv = ssl_CheckSignatureSchemeConsistency(ss, sigScheme,
+ ss->sec.peerCert);
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) {
- 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))
- {
- goto no_memory;
- }
- ss->sec.peerKey = peerKey;
- ss->ssl3.hs.ws = wait_cert_request;
- return SECSuccess;
- }
-
-#ifndef NSS_DISABLE_ECC
- case kt_ecdh:
- rv = ssl3_HandleECDHServerKeyExchange(ss, b, length);
- return rv;
-#endif /* NSS_DISABLE_ECC */
-
- default:
- desc = handshake_failure;
- errCode = SEC_ERROR_UNSUPPORTED_KEYALG;
- break; /* goto alert_loser; */
+ goto loser;
+ }
+ hashAlg = ssl_SignatureSchemeToHashType(sigScheme);
+ } else {
+ /* Use ssl_hash_none to represent the MD5+SHA1 combo. */
+ hashAlg = ssl_hash_none;
+ sigScheme = ssl_sig_none;
+ }
+ 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(ss, hashAlg, &hashes,
+ dh_p, dh_g, dh_Ys, PR_FALSE /* padY */);
+ if (rv != SECSuccess) {
+ errCode =
+ ssl_MapLowLevelError(SSL_ERROR_SERVER_KEY_EXCHANGE_FAILURE);
+ goto alert_loser;
+ }
+ rv = ssl3_VerifySignedHashes(ss, sigScheme, &hashes, &signature);
+ 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) {
+ errCode = SEC_ERROR_NO_MEMORY;
+ goto loser;
+ }
+
+ peerKey = PORT_ArenaZNew(arena, SECKEYPublicKey);
+ if (peerKey == NULL) {
+ errCode = SEC_ERROR_NO_MEMORY;
+ goto loser;
+ }
+
+ 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)) {
+ errCode = SEC_ERROR_NO_MEMORY;
+ goto loser;
+ }
+ ss->sec.peerKey = peerKey;
+ return SECSuccess;
+
alert_loser:
(void)SSL3_SendAlert(ss, alert_fatal, desc);
loser:
if (arena) {
PORT_FreeArena(arena, PR_FALSE);
}
- PORT_SetError( errCode );
- return SECFailure;
-
-no_memory: /* no-memory error has already been set. */
- if (arena) {
- PORT_FreeArena(arena, PR_FALSE);
- }
- ssl_MapLowLevelError(SSL_ERROR_SERVER_KEY_EXCHANGE_FAILURE);
+ PORT_SetError(ssl_MapLowLevelError(errCode));
return SECFailure;
}
-/*
- * Returns the TLS signature algorithm for the client authentication key and
- * whether it is an RSA or DSA key that may be able to sign only SHA-1 hashes.
+/* Called from ssl3_HandlePostHelloHandshakeMessage() when it has deciphered a
+ * complete ssl3 ServerKeyExchange message.
+ * Caller must hold Handshake and RecvBuf locks.
*/
static SECStatus
-ssl3_ExtractClientKeyInfo(sslSocket *ss,
- SSLSignType *sigAlg,
- PRBool *preferSha1)
+ssl3_HandleServerKeyExchange(sslSocket *ss, SSL3Opaque *b, PRUint32 length)
{
- SECStatus rv = SECSuccess;
- SECKEYPublicKey *pubk;
+ SECStatus rv;
- pubk = CERT_ExtractPublicKey(ss->ssl3.clientCertificate);
- if (pubk == NULL) {
- rv = SECFailure;
- goto done;
- }
+ 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));
- rv = ssl3_TLSSignatureAlgorithmForKeyType(pubk->keyType, sigAlg);
- if (rv != SECSuccess) {
- goto done;
+ if (ss->ssl3.hs.ws != wait_server_key) {
+ SSL3_SendAlert(ss, alert_fatal, unexpected_message);
+ PORT_SetError(SSL_ERROR_RX_UNEXPECTED_SERVER_KEY_EXCH);
+ return SECFailure;
}
- /* If the key is a 1024-bit RSA or DSA key, assume conservatively that
- * it may be unable to sign SHA-256 hashes. This is the case for older
- * Estonian ID cards that have 1024-bit RSA keys. In FIPS 186-2 and
- * older, DSA key size is at most 1024 bits and the hash function must
- * be SHA-1.
- */
- if (pubk->keyType == rsaKey || pubk->keyType == dsaKey) {
- *preferSha1 = SECKEY_PublicKeyStrength(pubk) <= 128;
- } else {
- *preferSha1 = PR_FALSE;
+ switch (ss->ssl3.hs.kea_def->exchKeyType) {
+ case ssl_kea_dh:
+ rv = ssl_HandleDHServerKeyExchange(ss, b, length);
+ break;
+
+ case ssl_kea_ecdh:
+ rv = ssl3_HandleECDHServerKeyExchange(ss, b, length);
+ break;
+
+ default:
+ SSL3_SendAlert(ss, alert_fatal, handshake_failure);
+ PORT_SetError(SEC_ERROR_UNSUPPORTED_KEYALG);
+ rv = SECFailure;
+ break;
}
-done:
- if (pubk)
- SECKEY_DestroyPublicKey(pubk);
+ if (rv == SECSuccess) {
+ ss->ssl3.hs.ws = wait_cert_request;
+ }
+ /* All Handle*ServerKeyExchange functions set the error code. */
return rv;
}
-/* Destroys the backup handshake hash context if we don't need it. Note that
- * this function selects the hash algorithm for client authentication
- * signatures; ssl3_SendCertificateVerify uses the presence of the backup hash
- * to determine whether to use SHA-1 or SHA-256. */
-static void
-ssl3_DestroyBackupHandshakeHashIfNotNeeded(sslSocket *ss,
- const SECItem *algorithms)
+typedef struct dnameNode {
+ struct dnameNode *next;
+ SECItem name;
+} dnameNode;
+
+/*
+ * Parse the ca_list structure in a CertificateRequest.
+ *
+ * Called from:
+ * ssl3_HandleCertificateRequest
+ * tls13_HandleCertificateRequest
+ */
+SECStatus
+ssl3_ParseCertificateRequestCAs(sslSocket *ss, SSL3Opaque **b, PRUint32 *length,
+ PLArenaPool *arena, CERTDistNames *ca_list)
{
- SECStatus rv;
- SSLSignType sigAlg;
- PRBool preferSha1;
- PRBool supportsSha1 = PR_FALSE;
- PRBool supportsSha256 = PR_FALSE;
- PRBool needBackupHash = PR_FALSE;
- unsigned int i;
+ PRInt32 remaining;
+ int nnames = 0;
+ dnameNode *node;
+ int i;
+
+ remaining = ssl3_ConsumeHandshakeNumber(ss, 2, b, length);
+ if (remaining < 0)
+ return SECFailure; /* 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 */
-#ifndef NO_PKCS11_BYPASS
- /* Backup handshake hash is not supported in PKCS #11 bypass mode. */
- if (ss->opt.bypassPKCS11) {
- PORT_Assert(!ss->ssl3.hs.backupHash);
- return;
+ node->name.len = len = ssl3_ConsumeHandshakeNumber(ss, 2, b, length);
+ if (len <= 0)
+ return SECFailure; /* 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;
}
-#endif
- PORT_Assert(ss->ssl3.hs.backupHash);
- /* Determine the key's signature algorithm and whether it prefers SHA-1. */
- rv = ssl3_ExtractClientKeyInfo(ss, &sigAlg, &preferSha1);
+ 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;
+ }
+
+ return SECSuccess;
+
+no_mem:
+ PORT_SetError(SEC_ERROR_NO_MEMORY);
+ return SECFailure;
+
+alert_loser:
+ (void)SSL3_SendAlert(ss, alert_fatal,
+ ss->version < SSL_LIBRARY_VERSION_TLS_1_0 ? illegal_parameter
+ : decode_error);
+ PORT_SetError(SSL_ERROR_RX_MALFORMED_CERT_REQUEST);
+ return SECFailure;
+}
+
+SECStatus
+ssl_ParseSignatureSchemes(const sslSocket *ss, PLArenaPool *arena,
+ SSLSignatureScheme **schemesOut,
+ unsigned int *numSchemesOut,
+ unsigned char **b, unsigned int *len)
+{
+ SECStatus rv;
+ SECItem buf;
+ SSLSignatureScheme *schemes;
+ unsigned int numSchemes = 0;
+ unsigned int max;
+
+ rv = ssl3_ExtConsumeHandshakeVariable(ss, &buf, 2, b, len);
if (rv != SECSuccess) {
- goto done;
+ return SECFailure;
+ }
+ /* An empty or odd-length value is invalid. */
+ if (buf.len == 0 || (buf.len & 1) != 0) {
+ ssl3_ExtSendAlert(ss, alert_fatal, decode_error);
+ return SECFailure;
}
- /* Determine the server's hash support for that signature algorithm. */
- for (i = 0; i < algorithms->len; i += 2) {
- if (algorithms->data[i+1] == sigAlg) {
- if (algorithms->data[i] == ssl_hash_sha1) {
- supportsSha1 = PR_TRUE;
- } else if (algorithms->data[i] == ssl_hash_sha256) {
- supportsSha256 = PR_TRUE;
- }
- }
+ /* Limit the number of schemes we read. */
+ max = PR_MIN(buf.len / 2, MAX_SIGNATURE_SCHEMES);
+
+ if (arena) {
+ schemes = PORT_ArenaZNewArray(arena, SSLSignatureScheme, max);
+ } else {
+ schemes = PORT_ZNewArray(SSLSignatureScheme, max);
+ }
+ if (!schemes) {
+ ssl3_ExtSendAlert(ss, alert_fatal, internal_error);
+ return SECFailure;
}
- /* If either the server does not support SHA-256 or the client key prefers
- * SHA-1, leave the backup hash. */
- if (supportsSha1 && (preferSha1 || !supportsSha256)) {
- needBackupHash = PR_TRUE;
+ for (; max; --max) {
+ PRInt32 tmp;
+ tmp = ssl3_ExtConsumeHandshakeNumber(ss, 2, &buf.data, &buf.len);
+ if (tmp < 0) {
+ PORT_Assert(0);
+ PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
+ return SECFailure;
+ }
+ if (ssl_IsSupportedSignatureScheme((SSLSignatureScheme)tmp)) {
+ schemes[numSchemes++] = (SSLSignatureScheme)tmp;
+ }
}
-done:
- if (!needBackupHash) {
- PK11_DestroyContext(ss->ssl3.hs.backupHash, PR_TRUE);
- ss->ssl3.hs.backupHash = NULL;
+ if (!numSchemes) {
+ if (!arena) {
+ PORT_Free(schemes);
+ }
+ schemes = NULL;
}
-}
-typedef struct dnameNode {
- struct dnameNode *next;
- SECItem name;
-} dnameNode;
+ *schemesOut = schemes;
+ *numSchemesOut = numSchemes;
+ return SECSuccess;
+}
-/* Called from ssl3_HandleHandshakeMessage() when it has deciphered a complete
- * ssl3 Certificate Request message.
+/* Called from ssl3_HandlePostHelloHandshakeMessage() 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)
{
- PLArenaPool * arena = NULL;
- dnameNode * node;
- PRInt32 remaining;
- PRBool isTLS = PR_FALSE;
- PRBool isTLS12 = 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};
- SECItem algorithms = {siBuffer, NULL, 0};
- CERTDistNames ca_list;
+ PLArenaPool *arena = NULL;
+ PRBool isTLS = PR_FALSE;
+ PRBool isTLS12 = PR_FALSE;
+ int errCode = SSL_ERROR_RX_MALFORMED_CERT_REQUEST;
+ SECStatus rv;
+ SSL3AlertDescription desc = illegal_parameter;
+ SECItem cert_types = { siBuffer, NULL, 0 };
+ SSLSignatureScheme *signatureSchemes = NULL;
+ unsigned int signatureSchemeCount = 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) );
+ 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) {
desc = unexpected_message;
@@ -7225,140 +7442,39 @@ ssl3_HandleCertificateRequest(sslSocket *ss, SSL3Opaque *b, PRUint32 length)
isTLS12 = (PRBool)(ss->ssl3.prSpec->version >= SSL_LIBRARY_VERSION_TLS_1_2);
rv = ssl3_ConsumeHandshakeVariable(ss, &cert_types, 1, &b, &length);
if (rv != SECSuccess)
- goto loser; /* malformed, alert has been sent */
-
- if (isTLS12) {
- rv = ssl3_ConsumeHandshakeVariable(ss, &algorithms, 2, &b, &length);
- if (rv != SECSuccess)
- goto loser; /* malformed, alert has been sent */
- /* An empty or odd-length value is invalid.
- * SignatureAndHashAlgorithm
- * supported_signature_algorithms<2..2^16-2>;
- */
- if (algorithms.len == 0 || (algorithms.len & 1) != 0)
- goto alert_loser;
- }
+ 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 (isTLS12) {
+ rv = ssl_ParseSignatureSchemes(ss, arena,
+ &signatureSchemes,
+ &signatureSchemeCount,
+ &b, &length);
+ if (rv != SECSuccess) {
+ PORT_SetError(SSL_ERROR_RX_MALFORMED_CERT_REQUEST);
+ goto loser; /* malformed, alert has been sent */
+ }
}
+ rv = ssl3_ParseCertificateRequestCAs(ss, &b, &length, arena, &ca_list);
+ if (rv != SECSuccess)
+ goto done; /* alert sent in ssl3_ParseCertificateRequestCAs */
+
if (length != 0)
- goto alert_loser; /* malformed */
+ goto alert_loser; /* malformed */
- desc = no_certificate;
ss->ssl3.hs.ws = wait_hello_done;
- if (ss->getClientAuthData != NULL) {
- PORT_Assert((ss->ssl3.hs.preliminaryInfo & ssl_preinfo_all) ==
- ssl_preinfo_all);
- /* XXX Should pass cert_types and algorithms 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) {
- CERT_DestroyCertificate(ss->ssl3.clientCertificate);
- ss->ssl3.clientCertificate = NULL;
- SECKEY_DestroyPrivateKey(ss->ssl3.clientPrivateKey);
- ss->ssl3.clientPrivateKey = NULL;
- goto send_no_certificate;
- }
- if (ss->ssl3.hs.hashType == handshake_hash_single) {
- ssl3_DestroyBackupHandshakeHashIfNotNeeded(ss, &algorithms);
- }
- 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;
+ rv = ssl3_CompleteHandleCertificateRequest(ss, signatureSchemes,
+ signatureSchemeCount, &ca_list);
+ if (rv == SECFailure) {
+ PORT_Assert(0);
+ errCode = SEC_ERROR_LIBRARY_FAILURE;
+ desc = internal_error;
+ goto alert_loser;
}
goto done;
@@ -7369,59 +7485,135 @@ no_mem:
alert_loser:
if (isTLS && desc == illegal_parameter)
- desc = decode_error;
+ 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);
+ PORT_FreeArena(arena, PR_FALSE);
+ return rv;
+}
+
+SECStatus
+ssl3_CompleteHandleCertificateRequest(sslSocket *ss,
+ const SSLSignatureScheme *signatureSchemes,
+ unsigned int signatureSchemeCount,
+ CERTDistNames *ca_list)
+{
+ SECStatus rv;
+
+ if (ss->getClientAuthData != NULL) {
+ PORT_Assert((ss->ssl3.hs.preliminaryInfo & ssl_preinfo_all) ==
+ ssl_preinfo_all);
+ /* XXX Should pass cert_types and algorithms 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) {
+ CERT_DestroyCertificate(ss->ssl3.clientCertificate);
+ ss->ssl3.clientCertificate = NULL;
+ SECKEY_DestroyPrivateKey(ss->ssl3.clientPrivateKey);
+ ss->ssl3.clientPrivateKey = NULL;
+ goto send_no_certificate;
+ }
+ if (ss->ssl3.hs.hashType == handshake_hash_record ||
+ ss->ssl3.hs.hashType == handshake_hash_single) {
+ rv = ssl_PickClientSignatureScheme(ss, signatureSchemes,
+ signatureSchemeCount);
+ }
+ break; /* not an error */
+
+ case SECFailure:
+ default:
+ send_no_certificate:
+ if (ss->ssl3.prSpec->version > SSL_LIBRARY_VERSION_3_0) {
+ ss->ssl3.sendEmptyCert = PR_TRUE;
+ } else {
+ (void)SSL3_SendAlert(ss, alert_warning, no_certificate);
+ }
+ rv = SECSuccess;
+ break;
+ }
+
return rv;
}
static SECStatus
ssl3_CheckFalseStart(sslSocket *ss)
{
- PORT_Assert( ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss) );
- PORT_Assert( !ss->ssl3.hs.authCertificatePending );
- PORT_Assert( !ss->ssl3.hs.canFalseStart );
+ PORT_Assert(ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss));
+ PORT_Assert(!ss->ssl3.hs.authCertificatePending);
+ PORT_Assert(!ss->ssl3.hs.canFalseStart);
if (!ss->canFalseStartCallback) {
- SSL_TRC(3, ("%d: SSL[%d]: no false start callback so no false start",
- SSL_GETPID(), ss->fd));
+ SSL_TRC(3, ("%d: SSL[%d]: no false start callback so no false start",
+ SSL_GETPID(), ss->fd));
} else {
- PRBool maybeFalseStart;
- SECStatus rv;
+ PRBool maybeFalseStart;
+ SECStatus rv;
- /* 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 always require an 80-bit cipher. */
+ /* 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 always require an 80-bit cipher. */
ssl_GetSpecReadLock(ss);
maybeFalseStart = ss->ssl3.cwSpec->cipher_def->secret_key_size >= 10;
ssl_ReleaseSpecReadLock(ss);
- if (!maybeFalseStart) {
- SSL_TRC(3, ("%d: SSL[%d]: no false start due to weak cipher",
- SSL_GETPID(), ss->fd));
- } else {
+ if (!maybeFalseStart) {
+ SSL_TRC(3, ("%d: SSL[%d]: no false start due to weak cipher",
+ SSL_GETPID(), ss->fd));
+ } else {
PORT_Assert((ss->ssl3.hs.preliminaryInfo & ssl_preinfo_all) ==
ssl_preinfo_all);
- rv = (ss->canFalseStartCallback)(ss->fd,
- ss->canFalseStartCallbackData,
- &ss->ssl3.hs.canFalseStart);
- if (rv == SECSuccess) {
- SSL_TRC(3, ("%d: SSL[%d]: false start callback returned %s",
- SSL_GETPID(), ss->fd,
- ss->ssl3.hs.canFalseStart ? "TRUE" : "FALSE"));
- } else {
- SSL_TRC(3, ("%d: SSL[%d]: false start callback failed (%s)",
- SSL_GETPID(), ss->fd,
- PR_ErrorToName(PR_GetError())));
- }
- return rv;
- }
+ rv = (ss->canFalseStartCallback)(ss->fd,
+ ss->canFalseStartCallbackData,
+ &ss->ssl3.hs.canFalseStart);
+ if (rv == SECSuccess) {
+ SSL_TRC(3, ("%d: SSL[%d]: false start callback returned %s",
+ SSL_GETPID(), ss->fd,
+ ss->ssl3.hs.canFalseStart ? "TRUE"
+ : "FALSE"));
+ } else {
+ SSL_TRC(3, ("%d: SSL[%d]: false start callback failed (%s)",
+ SSL_GETPID(), ss->fd,
+ PR_ErrorToName(PR_GetError())));
+ }
+ return rv;
+ }
}
ss->ssl3.hs.canFalseStart = PR_FALSE;
@@ -7429,22 +7621,21 @@ ssl3_CheckFalseStart(sslSocket *ss)
}
PRBool
-ssl3_WaitingForStartOfServerSecondRound(sslSocket *ss)
+ssl3_WaitingForServerSecondRound(sslSocket *ss)
{
PRBool result;
- PORT_Assert( ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss) );
+ PORT_Assert(ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss));
switch (ss->ssl3.hs.ws) {
- case wait_new_session_ticket:
- result = PR_TRUE;
- break;
- case wait_change_cipher:
- result = !ssl3_ExtensionNegotiated(ss, ssl_session_ticket_xtn);
- break;
- default:
- result = PR_FALSE;
- break;
+ case wait_new_session_ticket:
+ case wait_change_cipher:
+ case wait_finished:
+ result = PR_TRUE;
+ break;
+ default:
+ result = PR_FALSE;
+ break;
}
return result;
@@ -7452,27 +7643,27 @@ ssl3_WaitingForStartOfServerSecondRound(sslSocket *ss)
static SECStatus ssl3_SendClientSecondRound(sslSocket *ss);
-/* Called from ssl3_HandleHandshakeMessage() when it has deciphered a complete
- * ssl3 Server Hello Done message.
+/* Called from ssl3_HandlePostHelloHandshakeMessage() 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;
+ 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) );
+ SSL_GETPID(), ss->fd));
+ PORT_Assert(ss->opt.noLocks || ssl_HaveRecvBufLock(ss));
+ PORT_Assert(ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss));
/* Skipping CertificateRequest is always permitted. */
- if (ws != wait_hello_done &&
- ws != wait_cert_request) {
- SSL3_SendAlert(ss, alert_fatal, unexpected_message);
- PORT_SetError(SSL_ERROR_RX_UNEXPECTED_HELLO_DONE);
- return SECFailure;
+ if (ws != wait_hello_done &&
+ 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);
@@ -7490,20 +7681,12 @@ ssl3_SendClientSecondRound(sslSocket *ss)
SECStatus rv;
PRBool sendClientCert;
- PORT_Assert( ss->opt.noLocks || ssl_HaveRecvBufLock(ss) );
- PORT_Assert( ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss) );
+ 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;
-
- if (!sendClientCert &&
- ss->ssl3.hs.hashType == handshake_hash_single &&
- ss->ssl3.hs.backupHash) {
- /* Don't need the backup handshake hash. */
- PK11_DestroyContext(ss->ssl3.hs.backupHash, PR_TRUE);
- ss->ssl3.hs.backupHash = NULL;
- }
+ 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
@@ -7530,50 +7713,52 @@ ssl3_SendClientSecondRound(sslSocket *ss)
* application data.
*/
if (ss->ssl3.hs.restartTarget) {
- PR_NOT_REACHED("unexpected ss->ssl3.hs.restartTarget");
- PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
- return SECFailure;
+ 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)) {
- SSL_TRC(3, ("%d: SSL3[%p]: deferring ssl3_SendClientSecondRound because"
- " certificate authentication is still pending.",
- SSL_GETPID(), ss->fd));
- ss->ssl3.hs.restartTarget = ssl3_SendClientSecondRound;
- return SECWouldBlock;
+ (sendClientCert || ss->ssl3.sendEmptyCert || ss->firstHsDone)) {
+ SSL_TRC(3, ("%d: SSL3[%p]: deferring ssl3_SendClientSecondRound because"
+ " certificate authentication is still pending.",
+ SSL_GETPID(), ss->fd));
+ ss->ssl3.hs.restartTarget = ssl3_SendClientSecondRound;
+ return SECWouldBlock;
}
- ssl_GetXmitBufLock(ss); /*******************************/
+ 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. */
- }
+ 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_SendCertificate(ss);
+ if (rv != SECSuccess) {
+ goto loser; /* error code is set. */
+ }
}
rv = ssl3_SendClientKeyExchange(ss);
if (rv != SECSuccess) {
- goto loser; /* err is set. */
+ goto loser; /* err is set. */
}
if (sendClientCert) {
- rv = ssl3_SendCertificateVerify(ss);
- if (rv != SECSuccess) {
- goto loser; /* err is set. */
+ rv = ssl3_SendCertificateVerify(ss, ss->ssl3.clientPrivateKey);
+ SECKEY_DestroyPrivateKey(ss->ssl3.clientPrivateKey);
+ ss->ssl3.clientPrivateKey = NULL;
+ if (rv != SECSuccess) {
+ goto loser; /* err is set. */
}
}
rv = ssl3_SendChangeCipherSpecs(ss);
if (rv != SECSuccess) {
- goto loser; /* err code was set. */
+ goto loser; /* err code was set. */
}
/* This must be done after we've set ss->ssl3.cwSpec in
@@ -7585,56 +7770,56 @@ ssl3_SendClientSecondRound(sslSocket *ss)
ss->enoughFirstHsDone = PR_TRUE;
if (!ss->firstHsDone) {
- /* XXX: If the server's certificate hasn't been authenticated by this
- * point, then we may be leaking this NPN message to an attacker.
- */
- rv = ssl3_SendNextProto(ss);
- if (rv != SECSuccess) {
- goto loser; /* err code was set. */
- }
-
- if (ss->opt.enableFalseStart) {
- if (!ss->ssl3.hs.authCertificatePending) {
- /* When we fix bug 589047, we will need to know whether we are
- * false starting before we try to flush the client second
- * round to the network. With that in mind, we purposefully
- * call ssl3_CheckFalseStart before calling ssl3_SendFinished,
- * which includes a call to ssl3_FlushHandshake, so that
- * no application develops a reliance on such flushing being
- * done before its false start callback is called.
- */
- ssl_ReleaseXmitBufLock(ss);
- rv = ssl3_CheckFalseStart(ss);
- ssl_GetXmitBufLock(ss);
- if (rv != SECSuccess) {
- goto loser;
- }
- } else {
- /* The certificate authentication and the server's Finished
- * message are racing each other. If the certificate
- * authentication wins, then we will try to false start in
- * ssl3_AuthCertificateComplete.
- */
- SSL_TRC(3, ("%d: SSL3[%p]: deferring false start check because"
- " certificate authentication is still pending.",
- SSL_GETPID(), ss->fd));
- }
- }
+ /* XXX: If the server's certificate hasn't been authenticated by this
+ * point, then we may be leaking this NPN message to an attacker.
+ */
+ rv = ssl3_SendNextProto(ss);
+ if (rv != SECSuccess) {
+ goto loser; /* err code was set. */
+ }
+
+ if (ss->opt.enableFalseStart) {
+ if (!ss->ssl3.hs.authCertificatePending) {
+ /* When we fix bug 589047, we will need to know whether we are
+ * false starting before we try to flush the client second
+ * round to the network. With that in mind, we purposefully
+ * call ssl3_CheckFalseStart before calling ssl3_SendFinished,
+ * which includes a call to ssl3_FlushHandshake, so that
+ * no application develops a reliance on such flushing being
+ * done before its false start callback is called.
+ */
+ ssl_ReleaseXmitBufLock(ss);
+ rv = ssl3_CheckFalseStart(ss);
+ ssl_GetXmitBufLock(ss);
+ if (rv != SECSuccess) {
+ goto loser;
+ }
+ } else {
+ /* The certificate authentication and the server's Finished
+ * message are racing each other. If the certificate
+ * authentication wins, then we will try to false start in
+ * ssl3_AuthCertificateComplete.
+ */
+ SSL_TRC(3, ("%d: SSL3[%p]: deferring false start check because"
+ " certificate authentication is still pending.",
+ SSL_GETPID(), ss->fd));
+ }
+ }
}
rv = ssl3_SendFinished(ss, 0);
if (rv != SECSuccess) {
- goto loser; /* err code was set. */
+ goto loser; /* err code was set. */
}
- ssl_ReleaseXmitBufLock(ss); /*******************************/
+ ssl_ReleaseXmitBufLock(ss); /*******************************/
if (ssl3_ExtensionNegotiated(ss, ssl_session_ticket_xtn))
- ss->ssl3.hs.ws = wait_new_session_ticket;
+ ss->ssl3.hs.ws = wait_new_session_ticket;
else
- ss->ssl3.hs.ws = wait_change_cipher;
+ ss->ssl3.hs.ws = wait_change_cipher;
- PORT_Assert(ssl3_WaitingForStartOfServerSecondRound(ss));
+ PORT_Assert(ssl3_WaitingForServerSecondRound(ss));
return SECSuccess;
@@ -7652,18 +7837,18 @@ ssl3_SendHelloRequest(sslSocket *ss)
SECStatus rv;
SSL_TRC(3, ("%d: SSL3[%d]: send hello_request handshake", SSL_GETPID(),
- ss->fd));
+ ss->fd));
- PORT_Assert( ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss) );
- PORT_Assert( ss->opt.noLocks || ssl_HaveXmitBufLock(ss) );
+ 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 */
+ return rv; /* err set by AppendHandshake */
}
rv = ssl3_FlushHandshake(ss, 0);
if (rv != SECSuccess) {
- return rv; /* error code set by ssl3_FlushHandshake */
+ return rv; /* error code set by ssl3_FlushHandshake */
}
ss->ssl3.hs.ws = wait_client_hello;
return SECSuccess;
@@ -7671,7 +7856,7 @@ ssl3_SendHelloRequest(sslSocket *ss)
/*
* Called from:
- * ssl3_HandleClientHello()
+ * ssl3_HandleClientHello()
*/
static SECComparison
ssl3_ServerNameCompare(const SECItem *name1, const SECItem *name2)
@@ -7690,10 +7875,10 @@ ssl3_ServerNameCompare(const SECItem *name1, const SECItem *name2)
/* Sets memory error when returning NULL.
* Called from:
- * ssl3_SendClientHello()
- * ssl3_HandleServerHello()
- * ssl3_HandleClientHello()
- * ssl3_HandleV2ClientHello()
+ * ssl3_SendClientHello()
+ * ssl3_HandleServerHello()
+ * ssl3_HandleClientHello()
+ * ssl3_HandleV2ClientHello()
*/
sslSessionID *
ssl3_NewSessionID(sslSocket *ss, PRBool is_server)
@@ -7702,14 +7887,14 @@ ssl3_NewSessionID(sslSocket *ss, PRBool is_server)
sid = PORT_ZNew(sslSessionID);
if (sid == NULL)
- return sid;
+ return sid;
if (is_server) {
- const SECItem * srvName;
- SECStatus rv = SECSuccess;
+ const SECItem *srvName;
+ SECStatus rv = SECSuccess;
- ssl_GetSpecReadLock(ss); /********************************/
- srvName = &ss->ssl3.prSpec->srvVirtName;
+ ssl_GetSpecReadLock(ss); /********************************/
+ srvName = &ss->ssl3.hs.srvVirtName;
if (srvName->len && srvName->data) {
rv = SECITEM_CopyItem(NULL, &sid->u.ssl3.srvName, srvName);
}
@@ -7719,34 +7904,34 @@ ssl3_NewSessionID(sslSocket *ss, PRBool is_server)
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->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.policy = SSL_ALLOWED;
sid->u.ssl3.clientWriteKey = NULL;
sid->u.ssl3.serverWriteKey = NULL;
sid->u.ssl3.keys.extendedMasterSecretUsed = PR_FALSE;
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;
- }
+ 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;
}
@@ -7756,95 +7941,302 @@ static SECStatus
ssl3_SendServerHelloSequence(sslSocket *ss)
{
const ssl3KEADef *kea_def;
- SECStatus rv;
+ SECStatus rv;
SSL_TRC(3, ("%d: SSL3[%d]: begin send server_hello sequence",
- SSL_GETPID(), ss->fd));
+ SSL_GETPID(), ss->fd));
- PORT_Assert( ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss) );
- PORT_Assert( ss->opt.noLocks || ssl_HaveXmitBufLock(ss) );
+ 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. */
+ return rv; /* err code is set. */
}
rv = ssl3_SendCertificate(ss);
if (rv != SECSuccess) {
- return rv; /* error code is set. */
+ return rv; /* error code is set. */
}
rv = ssl3_SendCertificateStatus(ss);
if (rv != SECSuccess) {
- return rv; /* error code is set. */
+ 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. */
- unsigned 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
- }
- } else if (kea_def->ephemeral) {
+
+ if (kea_def->ephemeral) {
rv = ssl3_SendServerKeyExchange(ss);
if (rv != SECSuccess) {
- return rv; /* err code was set. */
+ return rv; /* err code was set. */
}
}
if (ss->opt.requestCertificate) {
- rv = ssl3_SendCertificateRequest(ss);
- if (rv != SECSuccess) {
- return rv; /* err code is set. */
- }
+ 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. */
+ return rv; /* err code is set. */
}
ss->ssl3.hs.ws = (ss->opt.requestCertificate) ? wait_client_cert
- : wait_client_key;
+ : wait_client_key;
return SECSuccess;
}
/* An empty TLS Renegotiation Info (RI) extension */
-static const PRUint8 emptyRIext[5] = {0xff, 0x01, 0x00, 0x01, 0x00};
+static const PRUint8 emptyRIext[5] = { 0xff, 0x01, 0x00, 0x01, 0x00 };
static PRBool
-ssl3_KEAAllowsSessionTicket(SSL3KeyExchangeAlgorithm kea)
-{
- switch (kea) {
- case kea_dhe_dss:
- case kea_dhe_dss_export:
- case kea_dh_dss_export:
- case kea_dh_dss:
- /* TODO: Fix session tickets for DSS. The server code rejects the
- * session ticket received from the client. Bug 1174677 */
- return PR_FALSE;
- default:
- return PR_TRUE;
- };
+ssl3_KEASupportsTickets(const ssl3KEADef *kea_def)
+{
+ if (kea_def->signKeyType == dsaKey) {
+ /* TODO: Fix session tickets for DSS. The server code rejects the
+ * session ticket received from the client. Bug 1174677 */
+ return PR_FALSE;
+ }
+ return PR_TRUE;
+}
+
+/* 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.
+*/
+SECStatus
+ssl3_NegotiateCipherSuite(sslSocket *ss, const SECItem *suites,
+ PRBool initHashes)
+{
+ int j;
+ int i;
+
+ for (j = 0; j < ssl_V3_SUITES_IMPLEMENTED; j++) {
+ ssl3CipherSuiteCfg *suite = &ss->cipherSuites[j];
+ SSLVersionRange vrange = { ss->version, ss->version };
+ if (!config_match(suite, ss->ssl3.policy, &vrange, ss)) {
+ 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) {
+ return ssl3_SetCipherSuite(ss, suite_i, initHashes);
+ }
+ }
+ }
+ return SECFailure;
+}
+
+/*
+ * Call the SNI config hook.
+ *
+ * Called from:
+ * ssl3_HandleClientHello
+ * tls13_HandleClientHelloPart2
+ */
+SECStatus
+ssl3_ServerCallSNICallback(sslSocket *ss)
+{
+ int errCode = SSL_ERROR_RX_MALFORMED_CLIENT_HELLO;
+ SSL3AlertDescription desc = illegal_parameter;
+ int ret = 0;
+
+#ifdef SSL_SNI_ALLOW_NAME_CHANGE_2HS
+#error("No longer allowed to set SSL_SNI_ALLOW_NAME_CHANGE_2HS")
+#endif
+ if (!ssl3_ExtensionNegotiated(ss, ssl_server_name_xtn)) {
+ 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.hs.srvVirtName.data) {
+ passed = PR_FALSE;
+ }
+ ssl_ReleaseSpecReadLock(ss); /***************************/
+ if (!passed) {
+ errCode = SSL_ERROR_UNRECOGNIZED_NAME_ALERT;
+ desc = handshake_failure;
+ goto alert_loser;
+ }
+ }
+ return SECSuccess;
+ }
+
+ if (ss->sniSocketConfig)
+ do { /* not a loop */
+ PORT_Assert((ss->ssl3.hs.preliminaryInfo & ssl_preinfo_all) ==
+ ssl_preinfo_all);
+
+ 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 pwsNameBuf = { 0, NULL, 0 };
+ SECItem *pwsName = &pwsNameBuf;
+ SECItem *cwsName;
+
+ ssl_GetSpecWriteLock(ss); /*******************************/
+ cwsName = &ss->ssl3.hs.srvVirtName;
+ /* 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;
+ }
+ }
+ 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 ((unsigned int)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); /*******************************/
+ /* not allow name change on the 2d HS */
+ if (ss->firstHsDone) {
+ SECItem *cwsName = &ss->ssl3.hs.srvVirtName;
+ if (ssl3_ServerNameCompare(name, cwsName)) {
+ ssl_ReleaseSpecWriteLock(ss); /******************/
+ errCode = SSL_ERROR_UNRECOGNIZED_NAME_ALERT;
+ desc = handshake_failure;
+ ret = SSL_SNI_SEND_ALERT;
+ break;
+ }
+ }
+ pwsName = &ss->ssl3.hs.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_RegisterExtensionSender(ss, &ss->xtnData, ssl_server_name_xtn,
+ ssl3_SendServerNameXtn);
+ } else {
+ /* Callback returned index outside of the boundary. */
+ PORT_Assert((unsigned int)ret < ss->xtnData.sniNameArrSize);
+ errCode = SSL_ERROR_INTERNAL_ERROR_ALERT;
+ desc = internal_error;
+ ret = SSL_SNI_SEND_ALERT;
+ break;
+ }
+ } while (0);
+ ssl3_FreeSniNameArray(&ss->xtnData);
+ if (ret <= SSL_SNI_SEND_ALERT) {
+ /* desc and errCode should be set. */
+ goto alert_loser;
+ }
+
+ return SECSuccess;
+
+alert_loser:
+ (void)SSL3_SendAlert(ss, alert_fatal, desc);
+ PORT_SetError(errCode);
+ return SECFailure;
+}
+
+SECStatus
+ssl3_SelectServerCert(sslSocket *ss)
+{
+ const ssl3KEADef *kea_def = ss->ssl3.hs.kea_def;
+ PRCList *cursor;
+
+ /* This picks the first certificate that has:
+ * a) the right authentication method, and
+ * b) the right named curve (EC only)
+ *
+ * We might want to do some sort of ranking here later. For now, it's all
+ * based on what order they are configured in. */
+ for (cursor = PR_NEXT_LINK(&ss->serverCerts);
+ cursor != &ss->serverCerts;
+ cursor = PR_NEXT_LINK(cursor)) {
+ sslServerCert *cert = (sslServerCert *)cursor;
+ if (cert->certType.authType != kea_def->authKeyType) {
+ continue;
+ }
+ if ((cert->certType.authType == ssl_auth_ecdsa ||
+ cert->certType.authType == ssl_auth_ecdh_rsa ||
+ cert->certType.authType == ssl_auth_ecdh_ecdsa) &&
+ !ssl_NamedGroupEnabled(ss, cert->certType.namedCurve)) {
+ continue;
+ }
+
+ /* Found one. */
+ ss->sec.serverCert = cert;
+ ss->sec.authType = cert->certType.authType;
+ ss->sec.authKeyBits = cert->serverKeyBits;
+
+ /* Don't pick a signature scheme if we aren't going to use it. */
+ if (kea_def->signKeyType == nullKey) {
+ return SECSuccess;
+ }
+ return ssl3_PickServerSignatureScheme(ss);
+ }
+
+ PORT_SetError(SSL_ERROR_NO_CYPHER_OVERLAP);
+ return SECFailure;
}
/* Called from ssl3_HandleHandshakeMessage() when it has deciphered a complete
@@ -7854,29 +8246,27 @@ ssl3_KEAAllowsSessionTicket(SSL3KeyExchangeAlgorithm kea)
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;
+ sslSessionID *sid = NULL;
+ PRInt32 tmp;
+ unsigned int i;
+ 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;
- PRBool canOfferSessionTicket = PR_FALSE;
+ TLSExtension *versionExtension;
+ SECItem sidBytes = { siBuffer, NULL, 0 };
+ SECItem cookieBytes = { siBuffer, NULL, 0 };
+ SECItem suites = { siBuffer, NULL, 0 };
+ SECItem comps = { siBuffer, NULL, 0 };
+ PRBool isTLS13;
SSL_TRC(3, ("%d: SSL3[%d]: handle client_hello handshake",
- SSL_GETPID(), ss->fd));
+ SSL_GETPID(), ss->fd));
- PORT_Assert( ss->opt.noLocks || ssl_HaveRecvBufLock(ss) );
- PORT_Assert( ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss));
- PORT_Assert( ss->ssl3.initialized );
+ PORT_Assert(ss->opt.noLocks || ssl_HaveRecvBufLock(ss));
+ PORT_Assert(ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss));
+ PORT_Assert(ss->ssl3.initialized);
ss->ssl3.hs.preliminaryInfo = 0;
if (!ss->sec.isServer ||
@@ -7886,126 +8276,82 @@ ssl3_HandleClientHello(sslSocket *ss, SSL3Opaque *b, PRUint32 length)
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 (ss->ssl3.hs.ws == idle_handshake) {
+ /* Refuse re-handshake when we have already negotiated TLS 1.3. */
+ if (ss->version >= SSL_LIBRARY_VERSION_TLS_1_3) {
+ desc = unexpected_message;
+ errCode = SSL_ERROR_RENEGOTIATION_NOT_ALLOWED;
+ goto alert_loser;
+ }
+ if (ss->opt.enableRenegotiation == SSL_RENEGOTIATE_NEVER) {
+ desc = no_renegotiation;
+ level = alert_warning;
+ errCode = SSL_ERROR_RENEGOTIATION_NOT_ALLOWED;
+ goto alert_loser;
+ }
}
/* 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;
+ return rv; /* error code is set. */
}
/* We might be starting session renegotiation in which case we should
* clear previous state.
*/
- PORT_Memset(&ss->xtnData, 0, sizeof(TLSExtensionData));
+ ssl3_ResetExtensionData(&ss->xtnData);
ss->statelessResume = PR_FALSE;
if (IS_DTLS(ss)) {
- dtls_RehandshakeCleanup(ss);
+ dtls_RehandshakeCleanup(ss);
}
tmp = ssl3_ConsumeHandshakeNumber(ss, 2, &b, &length);
if (tmp < 0)
- goto loser; /* malformed, alert already sent */
+ goto loser; /* malformed, alert already sent */
- /* Translate the version */
+ /* Translate the version. */
if (IS_DTLS(ss)) {
- ss->clientHelloVersion = version =
- dtls_DTLSVersionToTLSVersion((SSL3ProtocolVersion)tmp);
+ ss->clientHelloVersion = version =
+ dtls_DTLSVersionToTLSVersion((SSL3ProtocolVersion)tmp);
} else {
- ss->clientHelloVersion = version = (SSL3ProtocolVersion)tmp;
+ 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_UNSUPPORTED_VERSION;
- goto alert_loser;
- }
- ss->ssl3.hs.preliminaryInfo |= ssl_preinfo_version;
-
- rv = ssl3_InitHandshakeHashes(ss);
- if (rv != SECSuccess) {
- desc = internal_error;
- errCode = PORT_GetError();
- goto alert_loser;
- }
-
- /* grab the client random data. */
+ /* Grab the client random data. */
rv = ssl3_ConsumeHandshake(
- ss, &ss->ssl3.hs.client_random, SSL3_RANDOM_LENGTH, &b, &length);
+ ss, &ss->ssl3.hs.client_random, SSL3_RANDOM_LENGTH, &b, &length);
if (rv != SECSuccess) {
- goto loser; /* malformed */
+ goto loser; /* malformed */
}
- /* grab the client's SID, if present. */
+ /* Grab the client's SID, if present. */
rv = ssl3_ConsumeHandshakeVariable(ss, &sidBytes, 1, &b, &length);
if (rv != SECSuccess) {
- goto loser; /* malformed */
+ goto loser; /* malformed */
}
- /* grab the client's cookie, if present. */
+ /* 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 */
- }
+ rv = ssl3_ConsumeHandshakeVariable(ss, &cookieBytes, 1, &b, &length);
+ if (rv != SECSuccess) {
+ goto loser; /* malformed */
+ }
}
- /* grab the list of cipher suites. */
+ /* Grab the list of cipher suites. */
rv = ssl3_ConsumeHandshakeVariable(ss, &suites, 2, &b, &length);
if (rv != SECSuccess) {
- goto loser; /* malformed */
+ goto loser; /* malformed */
}
- /* If the ClientHello version is less than our maximum version, check for a
- * TLS_FALLBACK_SCSV and reject the connection if found. */
- if (ss->vrange.max > ss->clientHelloVersion) {
- for (i = 0; i + 1 < suites.len; i += 2) {
- PRUint16 suite_i = (suites.data[i] << 8) | suites.data[i + 1];
- if (suite_i != TLS_FALLBACK_SCSV)
- continue;
- desc = inappropriate_fallback;
- errCode = SSL_ERROR_INAPPROPRIATE_FALLBACK_ALERT;
- goto alert_loser;
- }
- }
-
- /* grab the list of compression methods. */
+ /* Grab the list of compression methods. */
rv = ssl3_ConsumeHandshakeVariable(ss, &comps, 1, &b, &length);
if (rv != SECSuccess) {
- goto loser; /* malformed */
+ goto loser; /* malformed */
}
- /* TLS 1.3 requires that compression be empty */
- if (ss->version >= SSL_LIBRARY_VERSION_TLS_1_3) {
- if (comps.len != 1 || comps.data[0] != ssl_compression_null) {
- goto loser;
- }
- }
- 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.
@@ -8014,280 +8360,384 @@ ssl3_HandleClientHello(sslSocket *ss, SSL3Opaque *b, PRUint32 length)
*/
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 */
- }
+ /* 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_ParseExtensions(ss, &b, &length);
+ if (rv != SECSuccess) {
+ goto loser; /* malformed */
+ }
}
+
+ versionExtension = ssl3_FindExtension(ss, ssl_tls13_supported_versions_xtn);
+ if (versionExtension) {
+ rv = tls13_NegotiateVersion(ss, versionExtension);
+ if (rv != SECSuccess) {
+ errCode = PORT_GetError();
+ desc = (errCode == SSL_ERROR_UNSUPPORTED_VERSION) ? protocol_version : illegal_parameter;
+ goto alert_loser;
+ }
+ } else {
+ /* The PR_MIN here ensures that we never negotiate 1.3 if the
+ * peer didn't offer "supported_versions". */
+ rv = ssl3_NegotiateVersion(ss,
+ PR_MIN(version,
+ SSL_LIBRARY_VERSION_TLS_1_2),
+ PR_TRUE);
+ if (rv != SECSuccess) {
+ desc = (version > SSL_LIBRARY_VERSION_3_0) ? protocol_version
+ : handshake_failure;
+ errCode = SSL_ERROR_UNSUPPORTED_VERSION;
+ goto alert_loser;
+ }
+ }
+ isTLS13 = ss->version >= SSL_LIBRARY_VERSION_TLS_1_3;
+ ss->ssl3.hs.preliminaryInfo |= ssl_preinfo_version;
+
+ /* You can't resume TLS 1.3 like this. */
+ if (isTLS13 && sidBytes.len) {
+ goto alert_loser;
+ }
+
+ /* Generate the Server Random now so it is available
+ * when we process the ClientKeyShare in TLS 1.3 */
+ rv = ssl3_GetNewRandom(&ss->ssl3.hs.server_random);
+ if (rv != SECSuccess) {
+ errCode = SSL_ERROR_GENERATE_RANDOM_FAILURE;
+ goto loser;
+ }
+
+#ifndef TLS_1_3_DRAFT_VERSION
+ /*
+ * [draft-ietf-tls-tls13-11 Section 6.3.1.1].
+ * TLS 1.3 server implementations which respond to a ClientHello with a
+ * client_version indicating TLS 1.2 or below MUST set the last eight
+ * bytes of their Random value to the bytes:
+ *
+ * 44 4F 57 4E 47 52 44 01
+ *
+ * TLS 1.2 server implementations which respond to a ClientHello with a
+ * client_version indicating TLS 1.1 or below SHOULD set the last eight
+ * bytes of their Random value to the bytes:
+ *
+ * 44 4F 57 4E 47 52 44 00
+ *
+ * TODO(ekr@rtfm.com): Note this change was not added in the SSLv2
+ * compat processing code since that will most likely be removed before
+ * we ship the final version of TLS 1.3. Bug 1306672.
+ */
+ if (ss->vrange.max > ss->version) {
+ unsigned char *downgrade_sentinel =
+ ss->ssl3.hs.server_random.rand +
+ SSL3_RANDOM_LENGTH - sizeof(tls13_downgrade_random);
+
+ switch (ss->vrange.max) {
+ case SSL_LIBRARY_VERSION_TLS_1_3:
+ PORT_Memcpy(downgrade_sentinel,
+ tls13_downgrade_random,
+ sizeof(tls13_downgrade_random));
+ break;
+ case SSL_LIBRARY_VERSION_TLS_1_2:
+ PORT_Memcpy(downgrade_sentinel,
+ tls12_downgrade_random,
+ sizeof(tls12_downgrade_random));
+ break;
+ default:
+ /* Do not change random. */
+ break;
+ }
+ }
+#endif
+
+ /* Now parse the rest of the extensions. */
+ rv = ssl3_HandleParsedExtensions(ss, client_hello);
+ if (rv != SECSuccess) {
+ goto loser; /* malformed */
+ }
+
+ /* If the ClientHello version is less than our maximum version, check for a
+ * TLS_FALLBACK_SCSV and reject the connection if found. */
+ if (ss->vrange.max > ss->clientHelloVersion) {
+ for (i = 0; i + 1 < suites.len; i += 2) {
+ PRUint16 suite_i = (suites.data[i] << 8) | suites.data[i + 1];
+ if (suite_i != TLS_FALLBACK_SCSV)
+ continue;
+ desc = inappropriate_fallback;
+ errCode = SSL_ERROR_INAPPROPRIATE_FALLBACK_ALERT;
+ goto alert_loser;
+ }
+ }
+
+ /* TLS 1.3 requires that compression only include null. */
+ if (isTLS13) {
+ if (comps.len != 1 || comps.data[0] != ssl_compression_null) {
+ goto alert_loser;
+ }
+ }
+
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 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_HandleExtensions(ss, &b2, &L2, client_hello);
+ break;
+ }
+ }
+ }
+ /* This is a second check for TLS 1.3 and re-handshake to stop us
+ * from re-handshake up to TLS 1.3, so it happens after version
+ * negotiation. */
+ if (ss->firstHsDone && ss->version >= SSL_LIBRARY_VERSION_TLS_1_3) {
+ desc = unexpected_message;
+ errCode = SSL_ERROR_RENEGOTIATION_NOT_ALLOWED;
+ goto alert_loser;
}
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->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;
+ !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.
+ /* We do stateful resumes only if we are in TLS < 1.3 and
+ * 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;
- }
- }
+ if ((ss->version < SSL_LIBRARY_VERSION_TLS_1_3) &&
+ (!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;
+ /* Fill in the client's session ID if doing a stateless resume.
+ * (When doing stateless resumes, server echos client's SessionID.)
+ * This branch also handles TLS 1.3 resumption-PSK.
+ */
+ 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) {
- canOfferSessionTicket = PR_TRUE;
+ /* Free a potentially leftover session ID from a previous handshake. */
+ if (ss->sec.ci.sid) {
+ ssl_FreeSID(ss->sec.ci.sid);
+ ss->sec.ci.sid = NULL;
}
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;
- }
- }
-
-#ifndef NSS_DISABLE_ECC
- /* Disable any ECC cipher suites for which we have no cert. */
- ssl3_FilterECCipherSuitesByServerCerts(ss);
-#endif
+ /* 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);
+ ss->sec.uncache(sid);
+ ssl_FreeSID(sid);
+ sid = NULL;
+ }
+ }
if (IS_DTLS(ss)) {
- ssl3_DisableNonDTLSSuites(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;
+ if (j <= 0) { /* no ciphers are working/supported by PK11 */
+ errCode = PORT_GetError(); /* error code is already set. */
+ goto alert_loser;
}
#endif
+ if (ss->version >= SSL_LIBRARY_VERSION_TLS_1_3) {
+ rv = tls13_HandleClientHelloPart2(ss, &suites, sid);
+ } else {
+ rv = ssl3_HandleClientHelloPart2(ss, &suites, &comps, sid);
+ }
+ if (rv != SECSuccess) {
+ errCode = PORT_GetError();
+ goto loser;
+ }
+ return SECSuccess;
+
+alert_loser:
+ (void)SSL3_SendAlert(ss, level, desc);
+/* FALLTHRU */
+loser:
+ PORT_SetError(errCode);
+ return SECFailure;
+}
+
+static SECStatus
+ssl3_HandleClientHelloPart2(sslSocket *ss,
+ SECItem *suites,
+ SECItem *comps,
+ sslSessionID *sid)
+{
+ PRBool haveSpecWriteLock = PR_FALSE;
+ PRBool haveXmitBufLock = PR_FALSE;
+ int errCode = SSL_ERROR_RX_MALFORMED_CLIENT_HELLO;
+ SSL3AlertDescription desc = illegal_parameter;
+ SECStatus rv;
+ unsigned int i;
+ int j;
+
/* 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;
+ if (sid)
+ do {
+ ssl3CipherSuiteCfg *suite;
#ifdef PARANOID
- SSLVersionRange vrange = {ss->version, ss->version};
+ SSLVersionRange vrange = { ss->version, ss->version };
#endif
- /* 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;
+ /* Check that the cached compression method is still enabled. */
+ if (!ssl_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, &vrange, ss))
- break;
+ /* 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, &vrange, ss))
+ break;
#else
- if (!suite->enabled)
- break;
+ 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);
- ss->ssl3.hs.preliminaryInfo |= ssl_preinfo_cipher_suite;
-
- /* Use the cached compression method. */
- ss->ssl3.hs.compression = sid->u.ssl3.compression;
- goto compression_found;
- }
- }
- } while (0);
-
- /* START A NEW SESSION */
+ /* Double check that the cached cipher suite is in the client's
+ * list. If it isn't, fall through and start a new session. */
+ 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) {
+ rv = ssl3_SetCipherSuite(ss, suite_i, PR_TRUE);
+ if (rv != SECSuccess) {
+ desc = internal_error;
+ errCode = PORT_GetError();
+ goto alert_loser;
+ }
+
+ /* 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;
+ if (j <= 0) { /* no ciphers are working/supported by PK11 */
+ desc = internal_error;
+ 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];
- SSLVersionRange vrange = {ss->version, ss->version};
- if (!config_match(suite, ss->ssl3.policy, PR_TRUE, &vrange, ss)) {
- 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);
- ss->ssl3.hs.preliminaryInfo |= ssl_preinfo_cipher_suite;
- goto suite_found;
- }
- }
- }
- errCode = SSL_ERROR_NO_CYPHER_OVERLAP;
- goto alert_loser;
-
-suite_found:
- if (canOfferSessionTicket)
- canOfferSessionTicket = ssl3_KEAAllowsSessionTicket(
- ss->ssl3.hs.suite_def->key_exchange_alg);
-
- if (canOfferSessionTicket) {
- ssl3_RegisterServerHelloExtensionSender(ss,
- ssl_session_ticket_xtn, ssl3_SendSessionTicketXtn);
+ rv = ssl3_NegotiateCipherSuite(ss, suites, PR_TRUE);
+ if (rv != SECSuccess) {
+ desc = handshake_failure;
+ errCode = SSL_ERROR_NO_CYPHER_OVERLAP;
+ goto alert_loser;
}
/* Select a 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;
- }
- }
+ for (i = 0; i < comps->len; i++) {
+ SSLCompressionMethod method = (SSLCompressionMethod)comps->data[i];
+ if (!ssl_CompressionEnabled(ss, method))
+ continue;
+ for (j = 0; j < ssl_compression_method_count; j++) {
+ if (method == ssl_compression_methods[j]) {
+ ss->ssl3.hs.compression = ssl_compression_methods[j];
+ goto compression_found;
+ }
+ }
}
errCode = SSL_ERROR_NO_COMPRESSION_OVERLAP;
- /* null compression must be supported */
+ /* null compression must be supported */
goto alert_loser;
compression_found:
- suites.data = NULL;
- comps.data = NULL;
-
- ss->sec.send = ssl3_SendApplicationData;
+ suites->data = NULL;
+ comps->data = NULL;
/* If there are any failures while processing the old sid,
* we don't consider them to be errors. Instead, We just behave
@@ -8295,374 +8745,249 @@ compression_found:
* The exception here is attempts to resume extended_master_secret
* sessions without the extension, which causes an alert.
*/
- 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 */
- }
-
- /* [draft-ietf-tls-session-hash-06; Section 5.3]
- * o If the original session did not use the "extended_master_secret"
- * extension but the new ClientHello contains the extension, then the
- * server MUST NOT perform the abbreviated handshake. Instead, it
- * SHOULD continue with a full handshake (as described in
- * Section 5.2) to negotiate a new session.
- *
- * o If the original session used the "extended_master_secret"
- * extension but the new ClientHello does not contain the extension,
- * the server MUST abort the abbreviated handshake.
- */
- if (ssl3_ExtensionNegotiated(ss, ssl_extended_master_secret_xtn)) {
- if (!sid->u.ssl3.keys.extendedMasterSecretUsed) {
- break; /* not an error */
- }
- } else {
- if (sid->u.ssl3.keys.extendedMasterSecretUsed) {
- /* Note: we do not destroy the session */
- desc = handshake_failure;
- errCode = SSL_ERROR_MISSING_EXTENDED_MASTER_SECRET;
- goto alert_loser;
- }
- }
-
- 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;
+ if (sid != NULL)
+ do {
+ ssl3CipherSpec *pwSpec;
+ SECItem wrappedMS; /* wrapped key */
+ const sslServerCert *serverCert;
+
+ 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 */
}
- }
-
- /* 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 because we are re-using 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 */
- PORT_Assert((ss->ssl3.hs.preliminaryInfo & ssl_preinfo_all) ==
- ssl_preinfo_all);
- 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;
+ serverCert = ssl_FindServerCert(ss, &sid->certType);
+ if (!serverCert || !serverCert->serverCert) {
+ /* A compatible certificate must not have been configured. It
+ * might not be the same certificate, but we only find that out
+ * when the ticket fails to decrypt. */
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;
- }
+ /* [draft-ietf-tls-session-hash-06; Section 5.3]
+ * o If the original session did not use the "extended_master_secret"
+ * extension but the new ClientHello contains the extension, then the
+ * server MUST NOT perform the abbreviated handshake. Instead, it
+ * SHOULD continue with a full handshake (as described in
+ * Section 5.2) to negotiate a new session.
+ *
+ * o If the original session used the "extended_master_secret"
+ * extension but the new ClientHello does not contain the extension,
+ * the server MUST abort the abbreviated handshake.
+ */
+ if (ssl3_ExtensionNegotiated(ss, ssl_extended_master_secret_xtn)) {
+ if (!sid->u.ssl3.keys.extendedMasterSecretUsed) {
+ break; /* not an error */
}
-#endif
- if (pwsName->data) {
- SECITEM_FreeItem(pwsName, PR_FALSE);
+ } else {
+ if (sid->u.ssl3.keys.extendedMasterSecretUsed) {
+ /* Note: we do not destroy the session */
+ desc = handshake_failure;
+ errCode = SSL_ERROR_MISSING_EXTENDED_MASTER_SECRET;
+ goto alert_loser;
}
- if (cwsName->data) {
- rv = SECITEM_CopyItem(NULL, pwsName, cwsName);
+ }
+
+ if (ss->sec.ci.sid) {
+ 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);
}
- ssl_ReleaseSpecWriteLock(ss); /**************************/
- if (rv != SECSuccess) {
- errCode = SSL_ERROR_INTERNAL_ERROR_ALERT;
- desc = internal_error;
- ret = SSL_SNI_SEND_ALERT;
+ 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;
+
+ wrapKey = ssl3_GetWrappingKey(ss, NULL, serverCert,
+ sid->u.ssl3.masterWrapMech,
+ ss->pkcs11PinArg);
+ if (!wrapKey) {
+ /* we have a SID cache entry, but no wrapping key for it??? */
break;
}
- } else if ((unsigned int)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;
- }
+ if (ss->version > SSL_LIBRARY_VERSION_3_0) { /* isTLS */
+ keyFlags = CKF_SIGN | CKF_VERIFY;
}
-#endif
- pwsName = &ss->ssl3.pwSpec->srvVirtName;
+
+ 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 */
+ }
+ } else {
+ /* 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.authType = sid->authType;
+ 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 slot 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.serverCert = serverCert;
+ ss->sec.localCert = CERT_DupCertificate(serverCert->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.hs.srvVirtName;
if (pwsName->data) {
SECITEM_FreeItem(pwsName, PR_FALSE);
}
- rv = SECITEM_CopyItem(NULL, pwsName, name);
- ssl_ReleaseSpecWriteLock(ss); /***************************/
+ rv = SECITEM_CopyItem(NULL, pwsName, sidName);
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;
+ desc = internal_error;
+ goto alert_loser;
}
- /* 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((unsigned int)ret < ss->xtnData.sniNameArrSize);
- errCode = SSL_ERROR_INTERNAL_ERROR_ALERT;
- desc = internal_error;
- ret = SSL_SNI_SEND_ALERT;
- break;
}
+
+ /* Clean up sni name array */
+ ssl3_FreeSniNameArray(&ss->xtnData);
+
+ 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 because we are re-using 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);
+ }
+
+ return SECSuccess;
} 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;
- }
+
+ if (haveSpecWriteLock) {
+ ssl_ReleaseSpecWriteLock(ss);
+ haveSpecWriteLock = PR_FALSE;
}
-#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;
- }
+
+ if (sid) { /* we had a sid, but it's no longer valid, free it */
+ SSL_AtomicIncrementLong(&ssl3stats.hch_sid_cache_not_ok);
+ ss->sec.uncache(sid);
+ ssl_FreeSID(sid);
+ sid = NULL;
+ }
+ SSL_AtomicIncrementLong(&ssl3stats.hch_sid_cache_misses);
+
+ /* We only send a session ticket extension if the client supports
+ * the extension and we are unable to 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) &&
+ ssl3_KEASupportsTickets(ss->ssl3.hs.kea_def)) {
+ ssl3_RegisterExtensionSender(ss, &ss->xtnData,
+ ssl_session_ticket_xtn,
+ ssl3_SendSessionTicketXtn);
+ }
+
+ rv = ssl3_ServerCallSNICallback(ss);
+ if (rv != SECSuccess) {
+ /* The alert has already been sent. */
+ errCode = PORT_GetError();
+ goto loser;
+ }
+
+ rv = ssl3_SelectServerCert(ss);
+ if (rv != SECSuccess) {
+ errCode = PORT_GetError();
+ 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. */
+ errCode = PORT_GetError();
+ goto loser; /* memory error is set. */
}
ss->sec.ci.sid = sid;
sid->u.ssl3.keys.extendedMasterSecretUsed =
- ssl3_ExtensionNegotiated(ss, ssl_extended_master_secret_xtn);
+ ssl3_ExtensionNegotiated(ss, ssl_extended_master_secret_xtn);
ss->ssl3.hs.isResuming = PR_FALSE;
+
ssl_GetXmitBufLock(ss);
rv = ssl3_SendServerHelloSequence(ss);
ssl_ReleaseXmitBufLock(ss);
@@ -8673,28 +8998,30 @@ compression_found:
}
if (haveXmitBufLock) {
- ssl_ReleaseXmitBufLock(ss);
- haveXmitBufLock = PR_FALSE;
+ ssl_ReleaseXmitBufLock(ss);
}
return SECSuccess;
alert_loser:
if (haveSpecWriteLock) {
- ssl_ReleaseSpecWriteLock(ss);
- haveSpecWriteLock = PR_FALSE;
+ ssl_ReleaseSpecWriteLock(ss);
+ haveSpecWriteLock = PR_FALSE;
}
- (void)SSL3_SendAlert(ss, level, desc);
- /* FALLTHRU */
+ (void)SSL3_SendAlert(ss, alert_fatal, desc);
+/* FALLTHRU */
loser:
+ if (sid && sid != ss->sec.ci.sid) {
+ ss->sec.uncache(sid);
+ ssl_FreeSID(sid);
+ }
+
if (haveSpecWriteLock) {
- ssl_ReleaseSpecWriteLock(ss);
- haveSpecWriteLock = PR_FALSE;
+ ssl_ReleaseSpecWriteLock(ss);
}
if (haveXmitBufLock) {
- ssl_ReleaseXmitBufLock(ss);
- haveXmitBufLock = PR_FALSE;
+ ssl_ReleaseXmitBufLock(ss);
}
PORT_SetError(errCode);
@@ -8704,107 +9031,111 @@ loser:
/*
* 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)
+ssl3_HandleV2ClientHello(sslSocket *ss, unsigned char *buffer, int length,
+ PRUint8 padding)
{
- sslSessionID * sid = NULL;
- unsigned char * suites;
- unsigned char * random;
+ 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;
+ 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;
+ unsigned int total = SSL_HL_CLIENT_HELLO_HBYTES;
SSL_TRC(3, ("%d: SSL3[%d]: handle v2 client_hello", SSL_GETPID(), ss->fd));
- PORT_Assert( ss->opt.noLocks || ssl_HaveRecvBufLock(ss) );
+ PORT_Assert(ss->opt.noLocks || ssl_HaveRecvBufLock(ss));
ssl_GetSSL3HandshakeLock(ss);
- PORT_Memset(&ss->xtnData, 0, sizeof(TLSExtensionData));
+ ssl3_ResetExtensionData(&ss->xtnData);
+
+ version = (buffer[1] << 8) | buffer[2];
+ if (version < SSL_LIBRARY_VERSION_3_0) {
+ goto loser;
+ }
rv = ssl3_InitState(ss);
if (rv != SECSuccess) {
- ssl_ReleaseSSL3HandshakeLock(ss);
- return rv; /* ssl3_InitState has set the error code. */
+ ssl_ReleaseSSL3HandshakeLock(ss);
+ return rv; /* ssl3_InitState has set the error code. */
}
rv = ssl3_RestartHandshakeHashes(ss);
if (rv != SECSuccess) {
- ssl_ReleaseSSL3HandshakeLock(ss);
- return rv;
+ ssl_ReleaseSSL3HandshakeLock(ss);
+ return rv;
}
if (ss->ssl3.hs.ws != wait_client_hello) {
- desc = unexpected_message;
- errCode = SSL_ERROR_RX_UNEXPECTED_CLIENT_HELLO;
- goto loser; /* alert_loser */
+ desc = unexpected_message;
+ errCode = SSL_ERROR_RX_UNEXPECTED_CLIENT_HELLO;
+ goto 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];
+ total += suite_length = (buffer[3] << 8) | buffer[4];
+ total += sid_length = (buffer[5] << 8) | buffer[6];
+ total += rand_length = (buffer[7] << 8) | buffer[8];
+ total += padding;
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_UNSUPPORTED_VERSION;
- goto alert_loser;
+ if (version >= SSL_LIBRARY_VERSION_TLS_1_3) {
+ /* [draft-ietf-tls-tls-11; C.3] forbids sending a TLS 1.3
+ * ClientHello using the backwards-compatible format. */
+ desc = illegal_parameter;
+ errCode = SSL_ERROR_RX_MALFORMED_CLIENT_HELLO;
+ goto alert_loser;
}
- ss->ssl3.hs.preliminaryInfo |= ssl_preinfo_version;
- rv = ssl3_InitHandshakeHashes(ss);
+ rv = ssl3_NegotiateVersion(ss, version, PR_TRUE);
if (rv != SECSuccess) {
- desc = internal_error;
- errCode = PORT_GetError();
- goto alert_loser;
+ /* send back which ever alert client will understand. */
+ desc = (version > SSL_LIBRARY_VERSION_3_0) ? protocol_version
+ : handshake_failure;
+ errCode = SSL_ERROR_UNSUPPORTED_VERSION;
+ goto alert_loser;
}
+ ss->ssl3.hs.preliminaryInfo |= ssl_preinfo_version;
/* 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 */
+ if (length != total) {
+ SSL_DBG(("%d: SSL3[%d]: bad v2 client hello message, len=%d should=%d",
+ SSL_GETPID(), ss->fd, length, total));
+ desc = illegal_parameter;
+ errCode = SSL_ERROR_RX_MALFORMED_CLIENT_HELLO;
+ goto 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 */
+ rand_length > SSL_MAX_CHALLENGE_BYTES) {
+ desc = illegal_parameter;
+ errCode = SSL_ERROR_RX_MALFORMED_CLIENT_HELLO;
+ goto 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);
+ &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));
-#ifndef NSS_DISABLE_ECC
- /* Disable any ECC cipher suites for which we have no cert. */
- ssl3_FilterECCipherSuitesByServerCerts(ss);
-#endif
+ SSL3_RANDOM_LENGTH));
i = ssl3_config_match_init(ss);
if (i <= 0) {
- errCode = PORT_GetError(); /* error code is already set. */
- goto alert_loser;
+ errCode = PORT_GetError(); /* error code is already set. */
+ goto alert_loser;
}
/* Select a cipher suite.
@@ -8815,56 +9146,77 @@ ssl3_HandleV2ClientHello(sslSocket *ss, unsigned char *buffer, int length)
** See the comments about export cipher suites in ssl3_HandleClientHello().
*/
for (j = 0; j < ssl_V3_SUITES_IMPLEMENTED; j++) {
- ssl3CipherSuiteCfg *suite = &ss->cipherSuites[j];
- SSLVersionRange vrange = {ss->version, ss->version};
- if (!config_match(suite, ss->ssl3.policy, PR_TRUE, &vrange, ss)) {
- 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);
- ss->ssl3.hs.preliminaryInfo |= ssl_preinfo_cipher_suite;
- goto suite_found;
- }
- }
+ ssl3CipherSuiteCfg *suite = &ss->cipherSuites[j];
+ SSLVersionRange vrange = { ss->version, ss->version };
+ if (!config_match(suite, ss->ssl3.policy, &vrange, ss)) {
+ 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) {
+ rv = ssl3_SetCipherSuite(ss, suite_i, PR_TRUE);
+ if (rv != SECSuccess) {
+ desc = internal_error;
+ errCode = PORT_GetError();
+ goto alert_loser;
+ }
+ 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
+ /* If the ClientHello version is less than our maximum version, check for a
+ * TLS_FALLBACK_SCSV and reject the connection if found. */
+ if (ss->vrange.max > ss->clientHelloVersion) {
+ for (i = 0; i + 2 < suite_length; i += 3) {
+ PRUint16 suite_i = (suites[i] << 16) | (suites[i + 1] << 8) | suites[i + 2];
+ if (suite_i == TLS_FALLBACK_SCSV) {
+ desc = inappropriate_fallback;
+ errCode = SSL_ERROR_INAPPROPRIATE_FALLBACK_ALERT;
+ goto alert_loser;
+ }
+ }
+ }
+
+ /* 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;
- }
+ 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_HandleExtensions(ss, &b2, &L2, client_hello);
+ break;
+ }
}
if (ss->opt.requireSafeNegotiation &&
- !ssl3_ExtensionNegotiated(ss, ssl_renegotiation_info_xtn)) {
- desc = handshake_failure;
- errCode = SSL_ERROR_UNSAFE_NEGOTIATION;
- goto alert_loser;
+ !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;
+
+ rv = ssl3_SelectServerCert(ss);
+ if (rv != SECSuccess) {
+ errCode = PORT_GetError();
+ desc = handshake_failure;
+ goto alert_loser;
+ }
/* we don't even search for a cache hit here. It's just a miss. */
- SSL_AtomicIncrementLong(& ssl3stats.hch_sid_cache_misses );
+ 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. */
+ 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 */
@@ -8872,25 +9224,18 @@ suite_found:
/* 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;
+ errCode = PORT_GetError();
+ goto loser;
}
ssl_GetXmitBufLock(ss);
rv = ssl3_SendServerHelloSequence(ss);
ssl_ReleaseXmitBufLock(ss);
if (rv != SECSuccess) {
- errCode = PORT_GetError();
- goto loser;
+ 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;
@@ -8905,150 +9250,135 @@ loser:
/* 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)
+** ssl3_SendServerHelloSequence <- ssl3_HandleClientHello (new session),
+** ssl3_SendServerHelloSequence <- ssl3_HandleV2ClientHello (new session)
*/
-static SECStatus
+SECStatus
ssl3_SendServerHello(sslSocket *ss)
{
sslSessionID *sid;
- SECStatus rv;
- PRUint32 maxBytes = 65535;
- PRUint32 length;
- PRInt32 extensions_len = 0;
+ 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));
+ 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));
+ PORT_Assert(ss->opt.noLocks || ssl_HaveXmitBufLock(ss));
+ PORT_Assert(ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss));
- if (MSB(ss->version) != MSB(SSL_LIBRARY_VERSION_DTLS_1_0)) {
- PORT_SetError(SSL_ERROR_NO_CYPHER_OVERLAP);
- return SECFailure;
- }
+ 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;
}
sid = ss->sec.ci.sid;
- extensions_len = ssl3_CallHelloExtensionSenders(ss, PR_FALSE, maxBytes,
- &ss->xtnData.serverSenders[0]);
+ extensions_len = ssl3_CallHelloExtensionSenders(
+ ss, PR_FALSE, maxBytes, &ss->xtnData.serverHelloSenders[0]);
if (extensions_len > 0)
- extensions_len += 2; /* Add sizeof total extension length */
+ extensions_len += 2; /* Add sizeof total extension length */
+
+ /* TLS 1.3 doesn't use the session_id or compression_method
+ * fields in the ServerHello. */
+ length = sizeof(SSL3ProtocolVersion) + SSL3_RANDOM_LENGTH;
+ if (ss->version < SSL_LIBRARY_VERSION_TLS_1_3) {
+ length += 1 + ((sid == NULL) ? 0 : sid->u.ssl3.sessionIDLength);
+ }
+ length += sizeof(ssl3CipherSuite);
+ if (ss->version < SSL_LIBRARY_VERSION_TLS_1_3) {
+ length += 1; /* Compression */
+ }
+ length += extensions_len;
- 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. */
+ return rv; /* err set by AppendHandshake. */
}
- if (IS_DTLS(ss)) {
- version = dtls_TLSVersionToDTLSVersion(ss->version);
+ if (IS_DTLS(ss) && ss->version < SSL_LIBRARY_VERSION_TLS_1_3) {
+ version = dtls_TLSVersionToDTLSVersion(ss->version);
} else {
- version = ss->version;
+ version = tls13_EncodeDraftVersion(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;
+ return rv; /* err set by AppendHandshake. */
}
+ /* Random already generated in ssl3_HandleClientHello */
rv = ssl3_AppendHandshake(
- ss, &ss->ssl3.hs.server_random, SSL3_RANDOM_LENGTH);
+ ss, &ss->ssl3.hs.server_random, SSL3_RANDOM_LENGTH);
if (rv != SECSuccess) {
- return rv; /* err set by AppendHandshake. */
+ return rv; /* err set by AppendHandshake. */
}
- if (sid)
- rv = ssl3_AppendHandshakeVariable(
- ss, sid->u.ssl3.sessionID, sid->u.ssl3.sessionIDLength, 1);
- else
- rv = ssl3_AppendHandshakeNumber(ss, 0, 1);
- if (rv != SECSuccess) {
- return rv; /* err set by AppendHandshake. */
+ if (ss->version < SSL_LIBRARY_VERSION_TLS_1_3) {
+ if (sid) {
+ rv = ssl3_AppendHandshakeVariable(
+ ss, sid->u.ssl3.sessionID, sid->u.ssl3.sessionIDLength, 1);
+ } else {
+ rv = ssl3_AppendHandshakeNumber(ss, 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. */
+ 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 (ss->version < SSL_LIBRARY_VERSION_TLS_1_3) {
+ 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]);
+ PRInt32 sent_len;
+
+ extensions_len -= 2;
+ rv = ssl3_AppendHandshakeNumber(ss, extensions_len, 2);
+ if (rv != SECSuccess)
+ return rv; /* err set by ssl3_AppendHandshakeNumber */
+ sent_len = ssl3_CallHelloExtensionSenders(ss, PR_TRUE, extensions_len,
+ &ss->xtnData.serverHelloSenders[0]);
PORT_Assert(sent_len == extensions_len);
- if (sent_len != extensions_len) {
- if (sent_len >= 0)
- PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
- return SECFailure;
- }
+ 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 */
+
+ if (ss->version < SSL_LIBRARY_VERSION_TLS_1_3) {
+ rv = ssl3_SetupPendingCipherSpec(ss);
+ if (rv != SECSuccess) {
+ return rv; /* err set by ssl3_SetupPendingCipherSpec */
+ }
}
return SECSuccess;
}
-static SECStatus
-ssl3_PickSignatureHashAlgorithm(sslSocket *ss,
- SSLSignatureAndHashAlg* out);
-
-static SECStatus
-ssl3_SendDHServerKeyExchange(sslSocket *ss)
+SECStatus
+ssl_CreateDHEKeyPair(const sslNamedGroupDef *groupDef,
+ const ssl3DHParams *params,
+ sslEphemeralKeyPair **keyPair)
{
- const ssl3KEADef * kea_def = ss->ssl3.hs.kea_def;
- SECStatus rv = SECFailure;
- int length;
- PRBool isTLS;
- SECItem signed_hash = {siBuffer, NULL, 0};
- SSL3Hashes hashes;
- SSLSignatureAndHashAlg sigAndHash;
SECKEYDHParams dhParam;
-
- ssl3KeyPair *keyPair = NULL;
- SECKEYPublicKey *pubKey = NULL; /* Ephemeral DH key */
+ SECKEYPublicKey *pubKey = NULL; /* Ephemeral DH key */
SECKEYPrivateKey *privKey = NULL; /* Ephemeral DH key */
- int certIndex = -1;
-
- if (kea_def->kea != kea_dhe_dss && kea_def->kea != kea_dhe_rsa) {
- /* TODO: Support DH_anon. It might be sufficient to drop the signature.
- See bug 1170510. */
- PORT_SetError(SSL_ERROR_SERVER_KEY_EXCHANGE_FAILURE);
- return SECFailure;
- }
+ sslEphemeralKeyPair *pair;
- dhParam.prime.data = ss->dheParams->prime.data;
- dhParam.prime.len = ss->dheParams->prime.len;
- dhParam.base.data = ss->dheParams->base.data;
- dhParam.base.len = ss->dheParams->base.len;
+ dhParam.prime.data = params->prime.data;
+ dhParam.prime.len = params->prime.len;
+ dhParam.base.data = params->base.data;
+ dhParam.base.len = params->base.len;
PRINT_BUF(60, (NULL, "Server DH p", dhParam.prime.data,
dhParam.prime.len));
@@ -9059,395 +9389,265 @@ ssl3_SendDHServerKeyExchange(sslSocket *ss)
privKey = SECKEY_CreateDHPrivateKey(&dhParam, &pubKey, NULL);
if (!privKey || !pubKey) {
ssl_MapLowLevelError(SEC_ERROR_KEYGEN_FAIL);
- rv = SECFailure;
- goto loser;
+ return SECFailure;
}
- keyPair = ssl3_NewKeyPair(privKey, pubKey);
- if (!keyPair) {
- ssl_MapLowLevelError(SEC_ERROR_KEYGEN_FAIL);
- goto loser;
+ pair = ssl_NewEphemeralKeyPair(groupDef, privKey, pubKey);
+ if (!pair) {
+ SECKEY_DestroyPrivateKey(privKey);
+ SECKEY_DestroyPublicKey(pubKey);
+
+ return SECFailure;
}
- PRINT_BUF(50, (ss, "DH public value:",
- pubKey->u.dh.publicValue.data,
- pubKey->u.dh.publicValue.len));
+ *keyPair = pair;
+ return SECSuccess;
+}
- if (ssl3_PickSignatureHashAlgorithm(ss, &sigAndHash) != SECSuccess) {
+static SECStatus
+ssl3_SendDHServerKeyExchange(sslSocket *ss)
+{
+ const ssl3KEADef *kea_def = ss->ssl3.hs.kea_def;
+ SECStatus rv = SECFailure;
+ int length;
+ SECItem signed_hash = { siBuffer, NULL, 0 };
+ SSL3Hashes hashes;
+ SSLHashType hashAlg;
+
+ const ssl3DHParams *params;
+ sslEphemeralKeyPair *keyPair;
+ SECKEYPublicKey *pubKey;
+ SECKEYPrivateKey *certPrivateKey;
+ const sslNamedGroupDef *groupDef;
+
+ if (kea_def->kea != kea_dhe_dss && kea_def->kea != kea_dhe_rsa) {
+ /* TODO: Support DH_anon. It might be sufficient to drop the signature.
+ See bug 1170510. */
+ PORT_SetError(SSL_ERROR_SERVER_KEY_EXCHANGE_FAILURE);
+ return SECFailure;
+ }
+
+ rv = ssl_SelectDHEGroup(ss, &groupDef);
+ if (rv == SECFailure) {
+ PORT_SetError(SSL_ERROR_NO_CYPHER_OVERLAP);
+ return SECFailure;
+ }
+ ss->sec.keaGroup = groupDef;
+
+ params = ssl_GetDHEParams(groupDef);
+ rv = ssl_CreateDHEKeyPair(groupDef, params, &keyPair);
+ if (rv == SECFailure) {
ssl_MapLowLevelError(SEC_ERROR_KEYGEN_FAIL);
- goto loser;
+ return SECFailure;
+ }
+ PR_APPEND_LINK(&keyPair->link, &ss->ephemeralKeyPairs);
+
+ if (ss->ssl3.pwSpec->version == SSL_LIBRARY_VERSION_TLS_1_2) {
+ hashAlg = ssl_SignatureSchemeToHashType(ss->ssl3.hs.signatureScheme);
+ } else {
+ /* Use ssl_hash_none to represent the MD5+SHA1 combo. */
+ hashAlg = ssl_hash_none;
}
- rv = ssl3_ComputeDHKeyHash(sigAndHash.hashAlg,
+ pubKey = keyPair->keys->pubKey;
+ PRINT_BUF(50, (ss, "DH public value:",
+ pubKey->u.dh.publicValue.data,
+ pubKey->u.dh.publicValue.len));
+ rv = ssl3_ComputeDHKeyHash(ss, hashAlg, &hashes,
pubKey->u.dh.prime,
pubKey->u.dh.base,
pubKey->u.dh.publicValue,
- &ss->ssl3.hs.client_random,
- &ss->ssl3.hs.server_random,
- &hashes, ss->opt.bypassPKCS11);
+ PR_TRUE /* padY */);
if (rv != SECSuccess) {
ssl_MapLowLevelError(SSL_ERROR_SERVER_KEY_EXCHANGE_FAILURE);
goto loser;
}
- /* It has been suggested to test kea_def->signKeyType instead, and to use
- * ssl_auth_* instead. Investigate what to do. See bug 102794. */
- if (kea_def->kea == kea_dhe_rsa)
- certIndex = ssl_kea_rsa;
- else
- certIndex = ssl_kea_dh;
-
- isTLS = (PRBool)(ss->ssl3.pwSpec->version > SSL_LIBRARY_VERSION_3_0);
- rv = ssl3_SignHashes(&hashes, ss->serverCerts[certIndex].SERVERKEY,
- &signed_hash, isTLS);
+ certPrivateKey = ss->sec.serverCert->serverKeyPair->privKey;
+ rv = ssl3_SignHashes(ss, &hashes, certPrivateKey, &signed_hash);
if (rv != SECSuccess) {
- goto loser; /* ssl3_SignHashes has set err. */
- }
- if (signed_hash.data == NULL) {
- PORT_SetError(SSL_ERROR_SERVER_KEY_EXCHANGE_FAILURE);
- goto loser;
+ goto loser; /* ssl3_SignHashes has set err. */
}
+
length = 2 + pubKey->u.dh.prime.len +
- 2 + pubKey->u.dh.base.len +
- 2 + pubKey->u.dh.publicValue.len +
- 2 + signed_hash.len;
+ 2 + pubKey->u.dh.base.len +
+ 2 + pubKey->u.dh.prime.len +
+ 2 + signed_hash.len;
if (ss->ssl3.pwSpec->version >= SSL_LIBRARY_VERSION_TLS_1_2) {
- length += 2;
+ length += 2;
}
rv = ssl3_AppendHandshakeHeader(ss, server_key_exchange, length);
if (rv != SECSuccess) {
- goto loser; /* err set by AppendHandshake. */
+ goto loser; /* err set by AppendHandshake. */
}
rv = ssl3_AppendHandshakeVariable(ss, pubKey->u.dh.prime.data,
pubKey->u.dh.prime.len, 2);
if (rv != SECSuccess) {
- goto loser; /* err set by AppendHandshake. */
+ goto loser; /* err set by AppendHandshake. */
}
rv = ssl3_AppendHandshakeVariable(ss, pubKey->u.dh.base.data,
pubKey->u.dh.base.len, 2);
if (rv != SECSuccess) {
- goto loser; /* err set by AppendHandshake. */
+ goto loser; /* err set by AppendHandshake. */
}
- rv = ssl3_AppendHandshakeVariable(ss, pubKey->u.dh.publicValue.data,
- pubKey->u.dh.publicValue.len, 2);
+ rv = ssl_AppendPaddedDHKeyShare(ss, pubKey, PR_TRUE);
if (rv != SECSuccess) {
- goto loser; /* err set by AppendHandshake. */
+ goto loser; /* err set by AppendHandshake. */
}
if (ss->ssl3.pwSpec->version >= SSL_LIBRARY_VERSION_TLS_1_2) {
- rv = ssl3_AppendSignatureAndHashAlgorithm(ss, &sigAndHash);
- if (rv != SECSuccess) {
- goto loser; /* err set by AppendHandshake. */
- }
+ rv = ssl3_AppendHandshakeNumber(ss, ss->ssl3.hs.signatureScheme, 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. */
+ goto loser; /* err set by AppendHandshake. */
}
PORT_Free(signed_hash.data);
- ss->dheKeyPair = keyPair;
return SECSuccess;
loser:
if (signed_hash.data)
PORT_Free(signed_hash.data);
- if (privKey)
- SECKEY_DestroyPrivateKey(privKey);
- if (pubKey)
- SECKEY_DestroyPublicKey(pubKey);
return SECFailure;
}
-/* ssl3_PickSignatureHashAlgorithm selects a hash algorithm to use when signing
- * elements of the handshake. (The negotiated cipher suite determines the
- * signature algorithm.) Prior to TLS 1.2, the MD5/SHA1 combination is always
- * used. With TLS 1.2, a client may advertise its support for signature and
- * hash combinations. */
-static SECStatus
-ssl3_PickSignatureHashAlgorithm(sslSocket *ss,
- SSLSignatureAndHashAlg* out)
-{
- SSLSignType sigAlg;
- PRUint32 policy;
- unsigned int i, j;
-
- switch (ss->ssl3.hs.kea_def->kea) {
- case kea_rsa:
- case kea_rsa_export:
- case kea_rsa_export_1024:
- case kea_dh_rsa:
- case kea_dh_rsa_export:
- case kea_dhe_rsa:
- case kea_dhe_rsa_export:
- case kea_rsa_fips:
- case kea_ecdh_rsa:
- case kea_ecdhe_rsa:
- sigAlg = ssl_sign_rsa;
- break;
- case kea_dh_dss:
- case kea_dh_dss_export:
- case kea_dhe_dss:
- case kea_dhe_dss_export:
- sigAlg = ssl_sign_dsa;
- break;
- case kea_ecdh_ecdsa:
- case kea_ecdhe_ecdsa:
- sigAlg = ssl_sign_ecdsa;
- break;
- default:
- PORT_SetError(SEC_ERROR_UNSUPPORTED_KEYALG);
- return SECFailure;
- }
- out->sigAlg = sigAlg;
-
- if (ss->version <= SSL_LIBRARY_VERSION_TLS_1_1) {
- /* SEC_OID_UNKNOWN means the MD5/SHA1 combo hash used in TLS 1.1 and
- * prior. */
- out->hashAlg = ssl_hash_none;
- return SECSuccess;
- }
-
- if (ss->ssl3.hs.numClientSigAndHash == 0) {
- /* If the client didn't provide any signature_algorithms extension then
- * we can assume that they support SHA-1:
- * https://tools.ietf.org/html/rfc5246#section-7.4.1.4.1 */
- out->hashAlg = ssl_hash_sha1;
- return SECSuccess;
- }
-
- /* Here we look for the first server preference that the client has
- * indicated support for in their signature_algorithms extension. */
- for (i = 0; i < ss->ssl3.signatureAlgorithmCount; ++i) {
- const SSLSignatureAndHashAlg *serverPref =
- &ss->ssl3.signatureAlgorithms[i];
- SECOidTag hashOID;
- if (serverPref->sigAlg != sigAlg) {
- continue;
- }
- hashOID = ssl3_TLSHashAlgorithmToOID(serverPref->hashAlg);
- if ((NSS_GetAlgorithmPolicy(hashOID, &policy) != SECSuccess)
- || !(policy & NSS_USE_ALG_IN_SSL_KX)) {
- /* we ignore hashes we don't support */
- continue;
- }
- for (j = 0; j < ss->ssl3.hs.numClientSigAndHash; j++) {
- const SSLSignatureAndHashAlg *clientPref =
- &ss->ssl3.hs.clientSigAndHash[j];
- if (clientPref->hashAlg == serverPref->hashAlg &&
- clientPref->sigAlg == sigAlg) {
- out->hashAlg = serverPref->hashAlg;
- return SECSuccess;
- }
- }
- }
-
- PORT_SetError(SSL_ERROR_UNSUPPORTED_HASH_ALGORITHM);
- return SECFailure;
-}
-
-
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 */
- SSLSignatureAndHashAlg sigAndHash;
+ const ssl3KEADef *kea_def = ss->ssl3.hs.kea_def;
SSL_TRC(3, ("%d: SSL3[%d]: send server_key_exchange handshake",
- SSL_GETPID(), ss->fd));
+ SSL_GETPID(), ss->fd));
- PORT_Assert( ss->opt.noLocks || ssl_HaveXmitBufLock(ss));
- PORT_Assert( ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss));
-
- if (ssl3_PickSignatureHashAlgorithm(ss, &sigAndHash) != SECSuccess) {
- return SECFailure;
- }
+ 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(sigAndHash.hashAlg,
- 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;
- }
+ case ssl_kea_dh: {
+ return ssl3_SendDHServerKeyExchange(ss);
+ }
- 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;
-
- if (ss->ssl3.pwSpec->version >= SSL_LIBRARY_VERSION_TLS_1_2) {
- length += 2;
- }
-
- 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. */
- }
-
- if (ss->ssl3.pwSpec->version >= SSL_LIBRARY_VERSION_TLS_1_2) {
- rv = ssl3_AppendSignatureAndHashAlgorithm(ss, &sigAndHash);
- 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;
-
- case ssl_kea_dh: {
- rv = ssl3_SendDHServerKeyExchange(ss);
- return rv;
- }
-
-#ifndef NSS_DISABLE_ECC
- case kt_ecdh: {
- rv = ssl3_SendECDHServerKeyExchange(ss, &sigAndHash);
- return rv;
- }
-#endif /* NSS_DISABLE_ECC */
-
- case kt_null:
- default:
- PORT_SetError(SEC_ERROR_UNSUPPORTED_KEYALG);
- break;
+ case ssl_kea_ecdh: {
+ return ssl3_SendECDHServerKeyExchange(ss);
+ }
+
+ case ssl_kea_rsa:
+ case ssl_kea_null:
+ default:
+ PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
+ break;
}
-loser:
- if (signed_hash.data != NULL)
- PORT_Free(signed_hash.data);
+
return SECFailure;
}
-static SECStatus
-ssl3_EncodeCertificateRequestSigAlgs(sslSocket *ss, PRUint8 *buf,
- unsigned maxLen, PRUint32 *len)
+SECStatus
+ssl3_EncodeSigAlgs(const sslSocket *ss, PRUint8 *buf, unsigned maxLen, PRUint32 *len)
{
unsigned int i;
+ PRUint8 *p = buf;
- PORT_Assert(maxLen >= ss->ssl3.signatureAlgorithmCount * 2);
- if (maxLen < ss->ssl3.signatureAlgorithmCount * 2) {
+ PORT_Assert(maxLen >= ss->ssl3.signatureSchemeCount * 2);
+ if (maxLen < ss->ssl3.signatureSchemeCount * 2) {
PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
return SECFailure;
}
- *len = 0;
- for (i = 0; i < ss->ssl3.signatureAlgorithmCount; ++i) {
- const SSLSignatureAndHashAlg *alg = &ss->ssl3.signatureAlgorithms[i];
- /* Note that we don't support a handshake hash with anything other than
- * SHA-256, so asking for a signature from clients for something else
- * would be inviting disaster. */
- if (alg->hashAlg == ssl_hash_sha256) {
- buf[(*len)++] = (PRUint8)alg->hashAlg;
- buf[(*len)++] = (PRUint8)alg->sigAlg;
+ for (i = 0; i < ss->ssl3.signatureSchemeCount; ++i) {
+ PRUint32 policy = 0;
+ SSLHashType hashType = ssl_SignatureSchemeToHashType(
+ ss->ssl3.signatureSchemes[i]);
+ SECOidTag hashOID = ssl3_HashTypeToOID(hashType);
+
+ /* Skip RSA-PSS schemes if there are no tokens to verify them. */
+ if (ssl_IsRsaPssSignatureScheme(ss->ssl3.signatureSchemes[i]) &&
+ !PK11_TokenExists(auth_alg_defs[ssl_auth_rsa_pss])) {
+ continue;
+ }
+
+ if ((NSS_GetAlgorithmPolicy(hashOID, &policy) != SECSuccess) ||
+ (policy & NSS_USE_ALG_IN_SSL_KX)) {
+ p = ssl_EncodeUintX((PRUint32)ss->ssl3.signatureSchemes[i], 2, p);
}
}
- if (*len == 0) {
+ if (p == buf) {
PORT_SetError(SSL_ERROR_NO_SUPPORTED_SIGNATURE_ALGORITHM);
return SECFailure;
}
+ *len = p - buf;
return SECSuccess;
}
-static SECStatus
-ssl3_SendCertificateRequest(sslSocket *ss)
+void
+ssl3_GetCertificateRequestCAs(sslSocket *ss, int *calen, SECItem **names,
+ int *nnames)
{
- PRBool isTLS12;
- SECItem * name;
+ SECItem *name;
CERTDistNames *ca_list;
- const PRUint8 *certTypes;
- SECItem * names = NULL;
- SECStatus rv;
- int length;
- int i;
- int calen = 0;
- int nnames = 0;
- int certTypesLength;
- PRUint8 sigAlgs[MAX_SIGNATURE_ALGORITHMS * 2];
- unsigned int sigAlgsLength = 0;
-
- 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));
+ int i;
- isTLS12 = (PRBool)(ss->ssl3.pwSpec->version >= SSL_LIBRARY_VERSION_TLS_1_2);
+ *calen = 0;
+ *names = NULL;
+ *nnames = 0;
/* 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;
+ ca_list = ssl3_server_ca_list;
}
if (ca_list != NULL) {
- names = ca_list->names;
- nnames = ca_list->nnames;
+ *names = ca_list->names;
+ *nnames = ca_list->nnames;
}
- for (i = 0, name = names; i < nnames; i++, name++) {
- calen += 2 + name->len;
+ for (i = 0, name = *names; i < *nnames; i++, name++) {
+ *calen += 2 + name->len;
}
+}
+
+static SECStatus
+ssl3_SendCertificateRequest(sslSocket *ss)
+{
+ PRBool isTLS12;
+ const PRUint8 *certTypes;
+ SECStatus rv;
+ int length;
+ SECItem *names;
+ int calen;
+ int nnames;
+ SECItem *name;
+ int i;
+ int certTypesLength;
+ PRUint8 sigAlgs[MAX_SIGNATURE_SCHEMES * 2];
+ unsigned int sigAlgsLength = 0;
+
+ SSL_TRC(3, ("%d: SSL3[%d]: send certificate_request handshake",
+ SSL_GETPID(), ss->fd));
- certTypes = certificate_types;
+ PORT_Assert(ss->opt.noLocks || ssl_HaveXmitBufLock(ss));
+ PORT_Assert(ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss));
+
+ isTLS12 = (PRBool)(ss->ssl3.pwSpec->version >= SSL_LIBRARY_VERSION_TLS_1_2);
+
+ ssl3_GetCertificateRequestCAs(ss, &calen, &names, &nnames);
+ certTypes = certificate_types;
certTypesLength = sizeof certificate_types;
length = 1 + certTypesLength + 2 + calen;
if (isTLS12) {
- rv = ssl3_EncodeCertificateRequestSigAlgs(ss, sigAlgs, sizeof(sigAlgs),
- &sigAlgsLength);
+ rv = ssl3_EncodeSigAlgs(ss, sigAlgs, sizeof(sigAlgs), &sigAlgsLength);
if (rv != SECSuccess) {
return rv;
}
@@ -9456,27 +9656,27 @@ ssl3_SendCertificateRequest(sslSocket *ss)
rv = ssl3_AppendHandshakeHeader(ss, certificate_request, length);
if (rv != SECSuccess) {
- return rv; /* err set by AppendHandshake. */
+ return rv; /* err set by AppendHandshake. */
}
rv = ssl3_AppendHandshakeVariable(ss, certTypes, certTypesLength, 1);
if (rv != SECSuccess) {
- return rv; /* err set by AppendHandshake. */
+ return rv; /* err set by AppendHandshake. */
}
if (isTLS12) {
- rv = ssl3_AppendHandshakeVariable(ss, sigAlgs, sigAlgsLength, 2);
- if (rv != SECSuccess) {
- return rv; /* err set by AppendHandshake. */
- }
+ rv = ssl3_AppendHandshakeVariable(ss, sigAlgs, sigAlgsLength, 2);
+ if (rv != SECSuccess) {
+ return rv; /* err set by AppendHandshake. */
+ }
}
rv = ssl3_AppendHandshakeNumber(ss, calen, 2);
if (rv != SECSuccess) {
- return rv; /* err set by AppendHandshake. */
+ 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. */
- }
+ rv = ssl3_AppendHandshakeVariable(ss, name->data, name->len, 2);
+ if (rv != SECSuccess) {
+ return rv; /* err set by AppendHandshake. */
+ }
}
return SECSuccess;
@@ -9488,100 +9688,116 @@ ssl3_SendServerHelloDone(sslSocket *ss)
SECStatus rv;
SSL_TRC(3, ("%d: SSL3[%d]: send server_hello_done handshake",
- SSL_GETPID(), ss->fd));
+ SSL_GETPID(), ss->fd));
- PORT_Assert( ss->opt.noLocks || ssl_HaveXmitBufLock(ss));
- PORT_Assert( ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss));
+ 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. */
+ return rv; /* err set by AppendHandshake. */
}
rv = ssl3_FlushHandshake(ss, 0);
if (rv != SECSuccess) {
- return rv; /* error code set by ssl3_FlushHandshake */
+ return rv; /* error code set by ssl3_FlushHandshake */
}
return SECSuccess;
}
-/* Called from ssl3_HandleHandshakeMessage() when it has deciphered a complete
- * ssl3 Certificate Verify message
+/* Called from ssl3_HandlePostHelloHandshakeMessage() 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)
+ SSL3Hashes *hashes)
{
- SECItem signed_hash = {siBuffer, NULL, 0};
- SECStatus rv;
- int errCode = SSL_ERROR_RX_MALFORMED_CERT_VERIFY;
- SSL3AlertDescription desc = handshake_failure;
- PRBool isTLS, isTLS12;
- SSLSignatureAndHashAlg sigAndHash;
+ SECItem signed_hash = { siBuffer, NULL, 0 };
+ SECStatus rv;
+ int errCode = SSL_ERROR_RX_MALFORMED_CERT_VERIFY;
+ SSL3AlertDescription desc = handshake_failure;
+ PRBool isTLS;
+ SSLSignatureScheme sigScheme;
+ SSLHashType hashAlg;
+ SSL3Hashes localHashes;
+ SSL3Hashes *hashesForVerify = NULL;
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) );
+ SSL_GETPID(), ss->fd));
+ PORT_Assert(ss->opt.noLocks || ssl_HaveRecvBufLock(ss));
+ PORT_Assert(ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss));
+
+ /* TLS 1.3 is handled by tls13_HandleCertificateVerify */
+ PORT_Assert(ss->ssl3.prSpec->version <= SSL_LIBRARY_VERSION_TLS_1_2);
isTLS = (PRBool)(ss->ssl3.prSpec->version > SSL_LIBRARY_VERSION_3_0);
- isTLS12 = (PRBool)(ss->ssl3.prSpec->version >= SSL_LIBRARY_VERSION_TLS_1_2);
if (ss->ssl3.hs.ws != wait_cert_verify) {
- desc = unexpected_message;
- errCode = SSL_ERROR_RX_UNEXPECTED_CERT_VERIFY;
- goto alert_loser;
+ desc = unexpected_message;
+ errCode = SSL_ERROR_RX_UNEXPECTED_CERT_VERIFY;
+ goto alert_loser;
}
if (!hashes) {
PORT_Assert(0);
- desc = internal_error;
- errCode = SEC_ERROR_LIBRARY_FAILURE;
- goto alert_loser;
+ desc = internal_error;
+ errCode = SEC_ERROR_LIBRARY_FAILURE;
+ goto alert_loser;
}
- if (isTLS12) {
- rv = ssl3_ConsumeSignatureAndHashAlgorithm(ss, &b, &length,
- &sigAndHash);
- if (rv != SECSuccess) {
- goto loser; /* malformed or unsupported. */
- }
- rv = ssl3_CheckSignatureAndHashAlgorithmConsistency(
- ss, &sigAndHash, ss->sec.peerCert);
- if (rv != SECSuccess) {
- errCode = PORT_GetError();
- desc = decrypt_error;
- goto alert_loser;
- }
-
- /* We only support CertificateVerify messages that use the handshake
- * hash. */
- if (sigAndHash.hashAlg != hashes->hashAlg) {
- errCode = SSL_ERROR_UNSUPPORTED_HASH_ALGORITHM;
- desc = decrypt_error;
- goto alert_loser;
- }
+ if (ss->ssl3.hs.hashType == handshake_hash_record) {
+ rv = ssl_ConsumeSignatureScheme(ss, &b, &length, &sigScheme);
+ if (rv != SECSuccess) {
+ goto loser; /* malformed or unsupported. */
+ }
+ rv = ssl_CheckSignatureSchemeConsistency(ss, sigScheme,
+ ss->sec.peerCert);
+ if (rv != SECSuccess) {
+ errCode = PORT_GetError();
+ desc = decrypt_error;
+ goto alert_loser;
+ }
+
+ hashAlg = ssl_SignatureSchemeToHashType(sigScheme);
+
+ if (hashes->u.pointer_to_hash_input.data) {
+ rv = ssl3_ComputeHandshakeHash(hashes->u.pointer_to_hash_input.data,
+ hashes->u.pointer_to_hash_input.len,
+ hashAlg, &localHashes);
+ } else {
+ rv = SECFailure;
+ }
+
+ if (rv == SECSuccess) {
+ hashesForVerify = &localHashes;
+ } else {
+ errCode = SSL_ERROR_DIGEST_FAILURE;
+ desc = decrypt_error;
+ goto alert_loser;
+ }
+ } else {
+ hashesForVerify = hashes;
+ sigScheme = ssl_sig_none;
}
rv = ssl3_ConsumeHandshakeVariable(ss, &signed_hash, 2, &b, &length);
if (rv != SECSuccess) {
- goto loser; /* malformed. */
+ goto loser; /* malformed. */
}
/* XXX verify that the key & kea match */
- rv = ssl3_VerifySignedHashes(hashes, ss->sec.peerCert, &signed_hash,
- isTLS, ss->pkcs11PinArg);
+ rv = ssl3_VerifySignedHashes(ss, sigScheme, hashesForVerify, &signed_hash);
if (rv != SECSuccess) {
- errCode = PORT_GetError();
- desc = isTLS ? decrypt_error : handshake_failure;
- goto alert_loser;
+ 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 */
+ desc = isTLS ? decode_error : illegal_parameter;
+ goto alert_loser; /* malformed */
}
ss->ssl3.hs.ws = wait_change_cipher;
return SECSuccess;
@@ -9593,78 +9809,76 @@ loser:
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)
+ * Called from ssl3_DeriveConnectionKeys() (above)
+ * ssl3_SendRSAClientKeyExchange() (above)
+ * ssl3_HandleRSAClientKeyExchange() (below)
* Caller must hold the SpecWriteLock, the SSL3HandshakeLock
*/
static PK11SymKey *
ssl3_GenerateRSAPMS(sslSocket *ss, ssl3CipherSpec *spec,
- PK11SlotInfo * serverKeySlot)
+ PK11SlotInfo *serverKeySlot)
{
- PK11SymKey * pms = NULL;
- PK11SlotInfo * slot = serverKeySlot;
- void * pwArg = ss->pkcs11PinArg;
- SECItem param;
- CK_VERSION version;
+ 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) );
+ 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);
+ 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 */
- }
- }
+ /* First get an appropriate slot. */
+ mechanism_array[0] = CKM_SSL3_PRE_MASTER_KEY_GEN;
+ mechanism_array[1] = CKM_RSA_PKCS;
+ mechanism_array[2] = ssl3_Alg2Mech(calg);
+
+ 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;
+ SSL3ProtocolVersion temp;
- temp = dtls_TLSVersionToDTLSVersion(ss->clientHelloVersion);
- version.major = MSB(temp);
- version.minor = LSB(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);
+ version.major = MSB(ss->clientHelloVersion);
+ version.minor = LSB(ss->clientHelloVersion);
}
param.data = (unsigned char *)&version;
- param.len = sizeof version;
+ param.len = sizeof version;
pms = PK11_KeyGen(slot, CKM_SSL3_PRE_MASTER_KEY_GEN, &param, 0, pwArg);
if (!serverKeySlot)
- PK11_FreeSlot(slot);
+ PK11_FreeSlot(slot);
if (pms == NULL) {
- ssl_MapLowLevelError(SSL_ERROR_CLIENT_KEY_EXCHANGE_FAILURE);
+ ssl_MapLowLevelError(SSL_ERROR_CLIENT_KEY_EXCHANGE_FAILURE);
}
return pms;
}
@@ -9684,192 +9898,120 @@ ssl3_GenerateRSAPMS(sslSocket *ss, ssl3CipherSpec *spec,
static SECStatus
ssl3_HandleRSAClientKeyExchange(sslSocket *ss,
SSL3Opaque *b,
- PRUint32 length,
- SECKEYPrivateKey *serverKey)
-{
-#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;
- PRBool isTLS = PR_FALSE;
- SECItem pmsItem = {siBuffer, NULL, 0};
- unsigned char rsaPmsBuf[SSL3_RSA_PMS_LENGTH];
-#endif
- SECStatus rv;
- SECItem enc_pms;
+ PRUint32 length,
+ sslKeyPair *serverKeyPair)
+{
+ SECStatus rv;
+ SECItem enc_pms;
+ PK11SymKey *tmpPms[2] = { NULL, NULL };
+ PK11SlotInfo *slot;
+ int useFauxPms = 0;
- PORT_Assert( ss->opt.noLocks || ssl_HaveRecvBufLock(ss) );
- PORT_Assert( ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss) );
- PORT_Assert( ss->ssl3.prSpec == ss->ssl3.pwSpec );
+ PORT_Assert(ss->opt.noLocks || ssl_HaveRecvBufLock(ss));
+ PORT_Assert(ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss));
+ PORT_Assert(ss->ssl3.prSpec == ss->ssl3.pwSpec);
enc_pms.data = b;
- enc_pms.len = length;
-#ifndef NO_PKCS11_BYPASS
- pmsItem.data = rsaPmsBuf;
- pmsItem.len = sizeof rsaPmsBuf;
-#endif
+ enc_pms.len = length;
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;
- }
-#ifndef NO_PKCS11_BYPASS
- isTLS = PR_TRUE;
-#endif
- } else {
-#ifndef NO_PKCS11_BYPASS
- isTLS = (PRBool)(ss->ssl3.hs.kea_def->tls_keygen != 0);
-#endif
+ 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;
+ }
}
-#ifndef NO_PKCS11_BYPASS
- if (ss->opt.bypassPKCS11) {
- /* We have not implemented a tls_ExtendedMasterKeyDeriveBypass
- * and will not negotiate this extension in bypass mode. This
- * assert just double-checks that.
- */
- PORT_Assert(
- !ssl3_ExtensionNegotiated(ss, ssl_extended_master_secret_xtn));
-
- /* 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_MasterSecretDeriveBypass(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
- {
- PK11SymKey *tmpPms[2] = {NULL, NULL};
- PK11SlotInfo *slot;
- int useFauxPms = 0;
#define currentPms tmpPms[!useFauxPms]
-#define unusedPms tmpPms[useFauxPms]
-#define realPms tmpPms[1]
-#define fauxPms tmpPms[0]
+#define unusedPms tmpPms[useFauxPms]
+#define realPms tmpPms[1]
+#define fauxPms tmpPms[0]
-#ifndef NO_PKCS11_BYPASS
-double_bypass:
-#endif
+ /*
+ * Get as close to algorithm 2 from RFC 5246; Section 7.4.7.1
+ * as we can within the constraints of the PKCS#11 interface.
+ *
+ * 1. Unconditionally generate a bogus PMS (what RFC 5246
+ * calls R).
+ * 2. Attempt the RSA decryption to recover the PMS (what
+ * RFC 5246 calls M).
+ * 3. Set PMS = (M == NULL) ? R : M
+ * 4. Use ssl3_ComputeMasterSecret(PMS) to attempt to derive
+ * the MS from PMS. This includes performing the version
+ * check and length check.
+ * 5. If either the initial RSA decryption failed or
+ * ssl3_ComputeMasterSecret(PMS) failed, then discard
+ * M and set PMS = R. Else, discard R and set PMS = M.
+ *
+ * We do two derivations here because we can't rely on having
+ * a function that only performs the PMS version and length
+ * check. The only redundant cost is that this runs the PRF,
+ * which isn't necessary here.
+ */
- /*
- * Get as close to algorithm 2 from RFC 5246; Section 7.4.7.1
- * as we can within the constraints of the PKCS#11 interface.
- *
- * 1. Unconditionally generate a bogus PMS (what RFC 5246
- * calls R).
- * 2. Attempt the RSA decryption to recover the PMS (what
- * RFC 5246 calls M).
- * 3. Set PMS = (M == NULL) ? R : M
- * 4. Use ssl3_ComputeMasterSecret(PMS) to attempt to derive
- * the MS from PMS. This includes performing the version
- * check and length check.
- * 5. If either the initial RSA decryption failed or
- * ssl3_ComputeMasterSecret(PMS) failed, then discard
- * M and set PMS = R. Else, discard R and set PMS = M.
- *
- * We do two derivations here because we can't rely on having
- * a function that only performs the PMS version and length
- * check. The only redundant cost is that this runs the PRF,
- * which isn't necessary here.
- */
+ /* Generate the bogus PMS (R) */
+ slot = PK11_GetSlotFromPrivateKey(serverKeyPair->privKey);
+ if (!slot) {
+ PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
+ return SECFailure;
+ }
- /* Generate the bogus PMS (R) */
- slot = PK11_GetSlotFromPrivateKey(serverKey);
+ if (!PK11_DoesMechanism(slot, CKM_SSL3_MASTER_KEY_DERIVE)) {
+ PK11_FreeSlot(slot);
+ slot = PK11_GetBestSlot(CKM_SSL3_MASTER_KEY_DERIVE, NULL);
if (!slot) {
PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
return SECFailure;
}
+ }
- if (!PK11_DoesMechanism(slot, CKM_SSL3_MASTER_KEY_DERIVE)) {
- PK11_FreeSlot(slot);
- slot = PK11_GetBestSlot(CKM_SSL3_MASTER_KEY_DERIVE, NULL);
- if (!slot) {
- PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
- return SECFailure;
- }
- }
-
- ssl_GetSpecWriteLock(ss);
- fauxPms = ssl3_GenerateRSAPMS(ss, ss->ssl3.prSpec, slot);
- ssl_ReleaseSpecWriteLock(ss);
- PK11_FreeSlot(slot);
-
- if (fauxPms == NULL) {
- ssl_MapLowLevelError(SSL_ERROR_CLIENT_KEY_EXCHANGE_FAILURE);
- return SECFailure;
- }
+ ssl_GetSpecWriteLock(ss);
+ fauxPms = ssl3_GenerateRSAPMS(ss, ss->ssl3.prSpec, slot);
+ ssl_ReleaseSpecWriteLock(ss);
+ PK11_FreeSlot(slot);
- /*
- * 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.
- */
- realPms = PK11_PubUnwrapSymKey(serverKey, &enc_pms,
- CKM_SSL3_MASTER_KEY_DERIVE, CKA_DERIVE, 0);
- /* Temporarily use the PMS if unwrapping the real PMS fails. */
- useFauxPms |= (realPms == NULL);
+ if (fauxPms == NULL) {
+ ssl_MapLowLevelError(SSL_ERROR_CLIENT_KEY_EXCHANGE_FAILURE);
+ return SECFailure;
+ }
- /* Attempt to derive the MS from the PMS. This is the only way to
- * check the version field in the RSA PMS. If this fails, we
- * then use the faux PMS in place of the PMS. Note that this
- * operation should never fail if we are using the faux PMS
- * since it is correctly formatted. */
- rv = ssl3_ComputeMasterSecret(ss, currentPms, NULL);
+ /*
+ * 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.
+ */
+ realPms = PK11_PubUnwrapSymKey(serverKeyPair->privKey, &enc_pms,
+ CKM_SSL3_MASTER_KEY_DERIVE, CKA_DERIVE, 0);
+ /* Temporarily use the PMS if unwrapping the real PMS fails. */
+ useFauxPms |= (realPms == NULL);
- /* If we succeeded, then select the true PMS and discard the
- * FPMS. Else, select the FPMS and select the true PMS */
- useFauxPms |= (rv != SECSuccess);
+ /* Attempt to derive the MS from the PMS. This is the only way to
+ * check the version field in the RSA PMS. If this fails, we
+ * then use the faux PMS in place of the PMS. Note that this
+ * operation should never fail if we are using the faux PMS
+ * since it is correctly formatted. */
+ rv = ssl3_ComputeMasterSecret(ss, currentPms, NULL);
- if (unusedPms) {
- PK11_FreeSymKey(unusedPms);
- }
+ /* If we succeeded, then select the true PMS and discard the
+ * FPMS. Else, select the FPMS and select the true PMS */
+ useFauxPms |= (rv != SECSuccess);
- /* This step will derive the MS from the PMS, among other things. */
- rv = ssl3_InitPendingCipherSpec(ss, currentPms);
- PK11_FreeSymKey(currentPms);
+ if (unusedPms) {
+ PK11_FreeSymKey(unusedPms);
}
+ /* This step will derive the MS from the PMS, among other things. */
+ rv = ssl3_InitPendingCipherSpec(ss, currentPms);
+ PK11_FreeSymKey(currentPms);
+
if (rv != SECSuccess) {
- SEND_ALERT
- return SECFailure; /* error code set by ssl3_InitPendingCipherSpec */
+ (void)SSL3_SendAlert(ss, alert_fatal, handshake_failure);
+ return SECFailure; /* error code set by ssl3_InitPendingCipherSpec */
}
#undef currentPms
@@ -9884,238 +10026,231 @@ static SECStatus
ssl3_HandleDHClientKeyExchange(sslSocket *ss,
SSL3Opaque *b,
PRUint32 length,
- SECKEYPublicKey *srvrPubKey,
- SECKEYPrivateKey *serverKey)
+ sslKeyPair *serverKeyPair)
{
- PK11SymKey *pms;
- SECStatus rv;
- SECKEYPublicKey clntPubKey;
- CK_MECHANISM_TYPE target;
- PRBool isTLS;
+ 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) );
- PORT_Assert( srvrPubKey );
+ PORT_Assert(ss->opt.noLocks || ssl_HaveRecvBufLock(ss));
+ PORT_Assert(ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss));
clntPubKey.keyType = dhKey;
- clntPubKey.u.dh.prime.len = srvrPubKey->u.dh.prime.len;
- clntPubKey.u.dh.prime.data = srvrPubKey->u.dh.prime.data;
- clntPubKey.u.dh.base.len = srvrPubKey->u.dh.base.len;
- clntPubKey.u.dh.base.data = srvrPubKey->u.dh.base.data;
+ clntPubKey.u.dh.prime.len = serverKeyPair->pubKey->u.dh.prime.len;
+ clntPubKey.u.dh.prime.data = serverKeyPair->pubKey->u.dh.prime.data;
+ clntPubKey.u.dh.base.len = serverKeyPair->pubKey->u.dh.base.len;
+ clntPubKey.u.dh.base.data = serverKeyPair->pubKey->u.dh.base.data;
rv = ssl3_ConsumeHandshakeVariable(ss, &clntPubKey.u.dh.publicValue,
- 2, &b, &length);
+ 2, &b, &length);
if (rv != SECSuccess) {
- goto loser;
+ return SECFailure;
+ }
+
+ if (!ssl_IsValidDHEShare(&serverKeyPair->pubKey->u.dh.prime,
+ &clntPubKey.u.dh.publicValue)) {
+ PORT_SetError(SSL_ERROR_RX_MALFORMED_DHE_KEY_SHARE);
+ return SECFailure;
}
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;
+ if (isTLS)
+ target = CKM_TLS_MASTER_KEY_DERIVE_DH;
+ else
+ target = CKM_SSL3_MASTER_KEY_DERIVE_DH;
- /* Determine the PMS */
- pms = PK11_PubDerive(serverKey, &clntPubKey, PR_FALSE, NULL, NULL,
+ /* Determine the PMS */
+ pms = PK11_PubDerive(serverKeyPair->privKey, &clntPubKey, 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;
+ ssl_FreeEphemeralKeyPairs(ss);
+ ssl_MapLowLevelError(SSL_ERROR_CLIENT_KEY_EXCHANGE_FAILURE);
+ return SECFailure;
}
- rv = ssl3_InitPendingCipherSpec(ss, pms);
- PK11_FreeSymKey(pms); pms = NULL;
-
-loser:
- if (ss->dheKeyPair) {
- ssl3_FreeKeyPair(ss->dheKeyPair);
- ss->dheKeyPair = NULL;
- }
+ rv = ssl3_InitPendingCipherSpec(ss, pms);
+ PK11_FreeSymKey(pms);
+ ssl_FreeEphemeralKeyPairs(ss);
return rv;
}
-
-/* Called from ssl3_HandleHandshakeMessage() when it has deciphered a complete
- * ssl3 ClientKeyExchange message from the remote client
+/* Called from ssl3_HandlePostHelloHandshakeMessage() 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;
+ sslKeyPair *serverKeyPair = NULL;
+ SECStatus rv;
const ssl3KEADef *kea_def;
- ssl3KeyPair *serverKeyPair = NULL;
- SECKEYPublicKey *serverPubKey = NULL;
SSL_TRC(3, ("%d: SSL3[%d]: handle client_key_exchange handshake",
- SSL_GETPID(), ss->fd));
+ SSL_GETPID(), ss->fd));
- PORT_Assert( ss->opt.noLocks || ssl_HaveRecvBufLock(ss) );
- PORT_Assert( ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss) );
+ 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:
- if (kea_def->kea == kea_dhe_dss ||
- kea_def->kea == kea_dhe_rsa) {
- if (ss->dheKeyPair) {
- serverKeyPair = ss->dheKeyPair;
- if (serverKeyPair->pubKey) {
- ss->sec.keaKeyBits =
- SECKEY_PublicKeyStrengthInBits(serverKeyPair->pubKey);
- }
- }
- } else
-#ifndef NSS_DISABLE_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;
+ SSL3_SendAlert(ss, alert_fatal, unexpected_message);
+ PORT_SetError(SSL_ERROR_RX_UNEXPECTED_CLIENT_KEY_EXCH);
+ return SECFailure;
}
- if (serverKeyPair) {
- serverKey = serverKeyPair->privKey;
+ kea_def = ss->ssl3.hs.kea_def;
+
+ if (kea_def->ephemeral) {
+ sslEphemeralKeyPair *keyPair;
+ /* There should be exactly one pair. */
+ PORT_Assert(!PR_CLIST_IS_EMPTY(&ss->ephemeralKeyPairs));
+ PORT_Assert(PR_PREV_LINK(&ss->ephemeralKeyPairs) ==
+ PR_NEXT_LINK(&ss->ephemeralKeyPairs));
+ keyPair = (sslEphemeralKeyPair *)PR_NEXT_LINK(&ss->ephemeralKeyPairs);
+ serverKeyPair = keyPair->keys;
+ ss->sec.keaKeyBits =
+ SECKEY_PublicKeyStrengthInBits(serverKeyPair->pubKey);
+ } else {
+ serverKeyPair = ss->sec.serverCert->serverKeyPair;
+ ss->sec.keaKeyBits = ss->sec.serverCert->serverKeyBits;
}
- if (serverKey == NULL) {
- SEND_ALERT
- PORT_SetError(SSL_ERROR_NO_SERVER_KEY_FOR_ALG);
- return SECFailure;
+ if (!serverKeyPair) {
+ SSL3_SendAlert(ss, alert_fatal, handshake_failure);
+ PORT_SetError(SSL_ERROR_NO_SERVER_KEY_FOR_ALG);
+ return SECFailure;
}
+ PORT_Assert(serverKeyPair->pubKey);
+ PORT_Assert(serverKeyPair->privKey);
- ss->sec.keaType = kea_def->exchKeyType;
+ 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;
-
- case ssl_kea_dh:
- if (ss->dheKeyPair && ss->dheKeyPair->pubKey) {
- serverPubKey = ss->dheKeyPair->pubKey;
- }
- if (!serverPubKey) {
- PORT_SetError(SSL_ERROR_EXTRACT_PUBLIC_KEY_FAILURE);
- return SECFailure;
- }
- rv = ssl3_HandleDHClientKeyExchange(ss, b, length,
- serverPubKey, serverKey);
- if (rv != SECSuccess) {
- SSL3_SendAlert(ss, alert_fatal, handshake_failure);
- return SECFailure; /* error code set */
- }
- break;
-
-#ifndef NSS_DISABLE_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 (ss->ephemeralECDHKeyPair) {
- ssl3_FreeKeyPair(ss->ephemeralECDHKeyPair);
- ss->ephemeralECDHKeyPair = NULL;
- }
- if (rv != SECSuccess) {
- return SECFailure; /* error code set */
- }
- break;
-#endif /* NSS_DISABLE_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;
+ case ssl_kea_rsa:
+ rv = ssl3_HandleRSAClientKeyExchange(ss, b, length, serverKeyPair);
+ break;
+
+ case ssl_kea_dh:
+ rv = ssl3_HandleDHClientKeyExchange(ss, b, length, serverKeyPair);
+ break;
+
+ case ssl_kea_ecdh:
+ rv = ssl3_HandleECDHClientKeyExchange(ss, b, length, serverKeyPair);
+ break;
+ default:
+ (void)ssl3_HandshakeFailure(ss);
+ PORT_SetError(SEC_ERROR_UNSUPPORTED_KEYALG);
+ return SECFailure;
+ }
+ ssl_FreeEphemeralKeyPairs(ss);
+ if (rv == SECSuccess) {
+ ss->ssl3.hs.ws = ss->sec.peerCert ? wait_cert_verify : wait_change_cipher;
+ } else {
+ /* PORT_SetError has been called by all the Handle*ClientKeyExchange
+ * functions above. However, not all error paths result in an alert, so
+ * this ensures that the server knows about the error. Note that if an
+ * alert was already sent, SSL3_SendAlert() is a noop. */
+ PRErrorCode errCode = PORT_GetError();
+ (void)SSL3_SendAlert(ss, alert_fatal, handshake_failure);
+ PORT_SetError(errCode);
+ }
+ return rv;
}
/* This is TLS's equivalent of sending a no_certificate alert. */
-static SECStatus
+SECStatus
ssl3_SendEmptyCertificate(sslSocket *ss)
{
- SECStatus rv;
+ SECStatus rv;
+ unsigned int len = 0;
+ PRBool isTLS13 = PR_FALSE;
+ const SECItem *context;
- rv = ssl3_AppendHandshakeHeader(ss, certificate, 3);
- if (rv == SECSuccess) {
- rv = ssl3_AppendHandshakeNumber(ss, 0, 3);
+ if (ss->version >= SSL_LIBRARY_VERSION_TLS_1_3) {
+ PORT_Assert(ss->ssl3.hs.certificateRequest);
+ context = &ss->ssl3.hs.certificateRequest->context;
+ len = context->len + 1;
+ isTLS13 = PR_TRUE;
}
- return rv; /* error, if any, set by functions called above. */
+
+ rv = ssl3_AppendHandshakeHeader(ss, certificate, len + 3);
+ if (rv != SECSuccess) {
+ return rv;
+ }
+
+ if (isTLS13) {
+ rv = ssl3_AppendHandshakeVariable(ss, context->data, context->len, 1);
+ if (rv != SECSuccess) {
+ return rv;
+ }
+ }
+
+ return ssl3_AppendHandshakeNumber(ss, 0, 3);
}
-SECStatus
+/*
+ * NewSessionTicket
+ * Called from ssl3_HandleFinished
+ */
+static SECStatus
+ssl3_SendNewSessionTicket(sslSocket *ss)
+{
+ SECItem ticket = { 0, NULL, 0 };
+ SECStatus rv;
+ NewSessionTicket nticket = { 0 };
+
+ rv = ssl3_EncodeSessionTicket(ss, &nticket, &ticket);
+ if (rv != SECSuccess)
+ goto loser;
+
+ /* Serialize the handshake message. Length =
+ * lifetime (4) + ticket length (2) + ticket. */
+ rv = ssl3_AppendHandshakeHeader(ss, new_session_ticket,
+ 4 + 2 + ticket.len);
+ if (rv != SECSuccess)
+ goto loser;
+
+ /* This is a fixed value. */
+ rv = ssl3_AppendHandshakeNumber(ss, TLS_EX_SESS_TICKET_LIFETIME_HINT, 4);
+ if (rv != SECSuccess)
+ goto loser;
+
+ /* Encode the ticket. */
+ rv = ssl3_AppendHandshakeVariable(ss, ticket.data, ticket.len, 2);
+ if (rv != SECSuccess)
+ goto loser;
+
+ rv = SECSuccess;
+
+loser:
+ if (ticket.data) {
+ SECITEM_FreeItem(&ticket, PR_FALSE);
+ }
+ return rv;
+}
+
+static SECStatus
ssl3_HandleNewSessionTicket(sslSocket *ss, SSL3Opaque *b, PRUint32 length)
{
SECStatus rv;
SECItem ticketData;
SSL_TRC(3, ("%d: SSL3[%d]: handle session_ticket handshake",
- SSL_GETPID(), ss->fd));
+ SSL_GETPID(), ss->fd));
- PORT_Assert( ss->opt.noLocks || ssl_HaveRecvBufLock(ss) );
- PORT_Assert( ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss) );
+ PORT_Assert(ss->opt.noLocks || ssl_HaveRecvBufLock(ss));
+ PORT_Assert(ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss));
PORT_Assert(!ss->ssl3.hs.newSessionTicket.ticket.data);
PORT_Assert(!ss->ssl3.hs.receivedNewSessionTicket);
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;
+ SSL3_SendAlert(ss, alert_fatal, unexpected_message);
+ PORT_SetError(SSL_ERROR_RX_UNEXPECTED_NEW_SESSION_TICKET);
+ return SECFailure;
}
/* RFC5077 Section 3.3: "The client MUST NOT treat the ticket as valid
@@ -10124,28 +10259,28 @@ ssl3_HandleNewSessionTicket(sslSocket *ss, SSL3Opaque *b, PRUint32 length)
*/
ss->ssl3.hs.newSessionTicket.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;
+ (void)SSL3_SendAlert(ss, alert_fatal, decode_error);
+ PORT_SetError(SSL_ERROR_RX_MALFORMED_NEW_SESSION_TICKET);
+ return SECFailure;
}
ss->ssl3.hs.newSessionTicket.ticket_lifetime_hint =
- (PRUint32)ssl3_ConsumeHandshakeNumber(ss, 4, &b, &length);
+ (PRUint32)ssl3_ConsumeHandshakeNumber(ss, 4, &b, &length);
rv = ssl3_ConsumeHandshakeVariable(ss, &ticketData, 2, &b, &length);
if (rv != SECSuccess || length != 0) {
- (void)SSL3_SendAlert(ss, alert_fatal, decode_error);
- PORT_SetError(SSL_ERROR_RX_MALFORMED_NEW_SESSION_TICKET);
- return SECFailure; /* malformed */
+ (void)SSL3_SendAlert(ss, alert_fatal, decode_error);
+ PORT_SetError(SSL_ERROR_RX_MALFORMED_NEW_SESSION_TICKET);
+ return SECFailure; /* malformed */
}
/* If the server sent a zero-length ticket, ignore it and keep the
* existing ticket. */
if (ticketData.len != 0) {
- rv = SECITEM_CopyItem(NULL, &ss->ssl3.hs.newSessionTicket.ticket,
- &ticketData);
- if (rv != SECSuccess) {
- return rv;
- }
- ss->ssl3.hs.receivedNewSessionTicket = PR_TRUE;
+ rv = SECITEM_CopyItem(NULL, &ss->ssl3.hs.newSessionTicket.ticket,
+ &ticketData);
+ if (rv != SECSuccess) {
+ return rv;
+ }
+ ss->ssl3.hs.receivedNewSessionTicket = PR_TRUE;
}
ss->ssl3.hs.ws = wait_change_cipher;
@@ -10155,54 +10290,54 @@ ssl3_HandleNewSessionTicket(sslSocket *ss, SSL3Opaque *b, PRUint32 length)
#ifdef NISCC_TEST
static PRInt32 connNum = 0;
-static SECStatus
+static SECStatus
get_fake_cert(SECItem *pCertItem, int *pIndex)
{
PRFileDesc *cf;
- char * testdir;
- char * startat;
- char * stopat;
+ char *testdir;
+ char *startat;
+ char *stopat;
const char *extension;
- int fileNum;
- PRInt32 numBytes = 0;
- PRStatus prStatus;
- PRFileInfo info;
- char cfn[100];
+ int fileNum;
+ PRInt32 numBytes = 0;
+ PRStatus prStatus;
+ PRFileInfo info;
+ char cfn[100];
pCertItem->data = 0;
- if ((testdir = PR_GetEnv("NISCC_TEST")) == NULL) {
- return SECSuccess;
+ if ((testdir = PR_GetEnvSecure("NISCC_TEST")) == NULL) {
+ return SECSuccess;
}
- *pIndex = (NULL != strstr(testdir, "root"));
+ *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);
+ fileNum = PR_ATOMIC_INCREMENT(&connNum) - 1;
+ if ((startat = PR_GetEnvSecure("START_AT")) != NULL) {
+ fileNum += atoi(startat);
}
- if ((stopat = PR_GetEnv("STOP_AT")) != NULL &&
- fileNum >= atoi(stopat)) {
- *pIndex = -1;
- return SECSuccess;
+ if ((stopat = PR_GetEnvSecure("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;
+ goto loser;
}
prStatus = PR_GetOpenFileInfo(cf, &info);
if (prStatus != PR_SUCCESS) {
- PR_Close(cf);
- goto loser;
+ PR_Close(cf);
+ goto loser;
}
pCertItem = SECITEM_AllocItem(NULL, pCertItem, info.size);
if (pCertItem) {
- numBytes = PR_Read(cf, pCertItem->data, info.size);
+ 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;
+ SECITEM_FreeItem(pCertItem, PR_FALSE);
+ PORT_SetError(SEC_ERROR_IO);
+ goto loser;
}
fprintf(stderr, "using %s\n", cfn);
return SECSuccess;
@@ -10221,76 +10356,80 @@ loser:
static SECStatus
ssl3_SendCertificate(sslSocket *ss)
{
- SECStatus rv;
+ SECStatus rv;
CERTCertificateList *certChain;
- int len = 0;
- int i;
- SSL3KEAType certIndex;
+ int certChainLen = 0;
+ int i;
#ifdef NISCC_TEST
- SECItem fakeCert;
- int ndex = -1;
+ SECItem fakeCert;
+ int ndex = -1;
#endif
+ PRBool isTLS13 = ss->version >= SSL_LIBRARY_VERSION_TLS_1_3;
+ SECItem context = { siBuffer, NULL, 0 };
+ unsigned int contextLen = 0;
SSL_TRC(3, ("%d: SSL3[%d]: send certificate handshake",
- SSL_GETPID(), ss->fd));
+ SSL_GETPID(), ss->fd));
- PORT_Assert( ss->opt.noLocks || ssl_HaveXmitBufLock(ss));
- PORT_Assert( ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss));
+ 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);
+ 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);
+ /* A server certificate is selected in ssl3_HandleClientHello. */
+ PORT_Assert(ss->sec.serverCert);
+
+ certChain = ss->sec.serverCert->serverCertChain;
+ ss->sec.localCert = CERT_DupCertificate(ss->sec.serverCert->serverCert);
} else {
- certChain = ss->ssl3.clientCertChain;
- ss->sec.localCert = CERT_DupCertificate(ss->ssl3.clientCertificate);
+ certChain = ss->ssl3.clientCertChain;
+ ss->sec.localCert = CERT_DupCertificate(ss->ssl3.clientCertificate);
}
#ifdef NISCC_TEST
rv = get_fake_cert(&fakeCert, &ndex);
#endif
+ if (isTLS13) {
+ contextLen = 1; /* Size of the context length */
+ if (!ss->sec.isServer) {
+ PORT_Assert(ss->ssl3.hs.certificateRequest);
+ context = ss->ssl3.hs.certificateRequest->context;
+ contextLen += context.len;
+ }
+ }
if (certChain) {
- for (i = 0; i < certChain->len; i++) {
+ 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;
- }
+ if (fakeCert.len > 0 && i == ndex) {
+ certChainLen += fakeCert.len + 3;
+ } else {
+ certChainLen += certChain->certs[i].len + 3;
+ }
#else
- len += certChain->certs[i].len + 3;
+ certChainLen += certChain->certs[i].len + 3;
#endif
- }
+ }
}
- rv = ssl3_AppendHandshakeHeader(ss, certificate, len + 3);
+ rv = ssl3_AppendHandshakeHeader(ss, certificate,
+ contextLen + certChainLen + 3);
if (rv != SECSuccess) {
- return rv; /* err set by AppendHandshake. */
+ return rv; /* err set by AppendHandshake. */
+ }
+
+ if (isTLS13) {
+ rv = ssl3_AppendHandshakeVariable(ss, context.data,
+ context.len, 1);
+ if (rv != SECSuccess) {
+ return rv; /* err set by AppendHandshake. */
+ }
}
- rv = ssl3_AppendHandshakeNumber(ss, len, 3);
+
+ rv = ssl3_AppendHandshakeNumber(ss, certChainLen, 3);
if (rv != SECSuccess) {
- return rv; /* err set by AppendHandshake. */
+ return rv; /* err set by AppendHandshake. */
}
if (certChain) {
for (i = 0; i < certChain->len; i++) {
@@ -10308,7 +10447,7 @@ ssl3_SendCertificate(sslSocket *ss)
certChain->certs[i].len, 3);
#endif
if (rv != SECSuccess) {
- return rv; /* err set by AppendHandshake. */
+ return rv; /* err set by AppendHandshake. */
}
}
}
@@ -10320,54 +10459,49 @@ ssl3_SendCertificate(sslSocket *ss)
* Used by server only.
* single-stapling, send only a single cert status
*/
-static SECStatus
+SECStatus
ssl3_SendCertificateStatus(sslSocket *ss)
{
SECStatus rv;
int len = 0;
SECItemArray *statusToSend = NULL;
- SSL3KEAType certIndex;
+ const sslServerCert *serverCert;
SSL_TRC(3, ("%d: SSL3[%d]: send certificate status handshake",
- SSL_GETPID(), ss->fd));
+ SSL_GETPID(), ss->fd));
- PORT_Assert( ss->opt.noLocks || ssl_HaveXmitBufLock(ss));
- PORT_Assert( ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss));
- PORT_Assert( ss->sec.isServer);
+ PORT_Assert(ss->opt.noLocks || ssl_HaveXmitBufLock(ss));
+ PORT_Assert(ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss));
+ PORT_Assert(ss->sec.isServer);
if (!ssl3_ExtensionNegotiated(ss, ssl_cert_status_xtn))
- return SECSuccess;
+ return SECSuccess;
/* Use certStatus based on the cert being used. */
- 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;
- }
- if (ss->certStatusArray[certIndex] && ss->certStatusArray[certIndex]->len) {
- statusToSend = ss->certStatusArray[certIndex];
+ serverCert = ss->sec.serverCert;
+ if (serverCert->certStatusArray && serverCert->certStatusArray->len) {
+ statusToSend = serverCert->certStatusArray;
}
if (!statusToSend)
- return SECSuccess;
+ return SECSuccess;
/* Use the array's first item only (single stapling) */
len = 1 + statusToSend->items[0].len + 3;
rv = ssl3_AppendHandshakeHeader(ss, certificate_status, len);
if (rv != SECSuccess) {
- return rv; /* err set by AppendHandshake. */
+ return rv; /* err set by AppendHandshake. */
}
rv = ssl3_AppendHandshakeNumber(ss, 1 /*ocsp*/, 1);
if (rv != SECSuccess)
- return rv; /* err set by AppendHandshake. */
+ return rv; /* err set by AppendHandshake. */
rv = ssl3_AppendHandshakeVariable(ss,
- statusToSend->items[0].data,
- statusToSend->items[0].len,
- 3);
+ statusToSend->items[0].data,
+ statusToSend->items[0].len,
+ 3);
if (rv != SECSuccess)
- return rv; /* err set by AppendHandshake. */
+ return rv; /* err set by AppendHandshake. */
return SECSuccess;
}
@@ -10375,30 +10509,38 @@ ssl3_SendCertificateStatus(sslSocket *ss)
/* This is used to delete the CA certificates in the peer certificate chain
* from the cert database after they've been validated.
*/
-static void
+void
ssl3_CleanupPeerCerts(sslSocket *ss)
{
- PLArenaPool * arena = ss->ssl3.peerCertArena;
+ PLArenaPool *arena = ss->ssl3.peerCertArena;
ssl3CertNode *certs = (ssl3CertNode *)ss->ssl3.peerCertChain;
for (; certs; certs = certs->next) {
- CERT_DestroyCertificate(certs->cert);
+ CERT_DestroyCertificate(certs->cert);
}
- if (arena) PORT_FreeArena(arena, PR_FALSE);
+ if (arena)
+ PORT_FreeArena(arena, PR_FALSE);
ss->ssl3.peerCertArena = NULL;
ss->ssl3.peerCertChain = NULL;
+
+ 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;
+ }
}
-/* Called from ssl3_HandleHandshakeMessage() when it has deciphered a complete
- * ssl3 CertificateStatus message.
+/* Called from ssl3_HandlePostHelloHandshakeMessage() 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;
+ SECStatus rv;
if (ss->ssl3.hs.ws != wait_certificate_status) {
(void)SSL3_SendAlert(ss, alert_fatal, unexpected_message);
@@ -10406,84 +10548,96 @@ ssl3_HandleCertificateStatus(sslSocket *ss, SSL3Opaque *b, PRUint32 length)
return SECFailure;
}
+ rv = ssl_ReadCertificateStatus(ss, b, length);
+ if (rv != SECSuccess) {
+ return SECFailure; /* code already set */
+ }
+
+ return ssl3_AuthCertificate(ss);
+}
+
+SECStatus
+ssl_ReadCertificateStatus(sslSocket *ss, SSL3Opaque *b, PRUint32 length)
+{
+ PRInt32 status, len;
+
PORT_Assert(!ss->sec.isServer);
/* Consume the CertificateStatusType enum */
status = ssl3_ConsumeHandshakeNumber(ss, 1, &b, &length);
if (status != 1 /* ocsp */) {
- goto format_loser;
+ ssl3_DecodeError(ss); /* sets error code */
+ return SECFailure;
}
len = ssl3_ConsumeHandshakeNumber(ss, 3, &b, &length);
if (len != length) {
- goto format_loser;
+ ssl3_DecodeError(ss); /* sets error code */
+ return SECFailure;
}
-#define MAX_CERTSTATUS_LEN 0x1ffff /* 128k - 1 */
- if (length > MAX_CERTSTATUS_LEN)
- goto format_loser;
+#define MAX_CERTSTATUS_LEN 0x1ffff /* 128k - 1 */
+ if (length > MAX_CERTSTATUS_LEN) {
+ ssl3_DecodeError(ss); /* sets error code */
+ return SECFailure;
+ }
#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;
+ return SECFailure; /* code already set */
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;
+ return SECFailure; /* code already set */
}
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 ssl3_AuthCertificate(ss);
-
-format_loser:
- return ssl3_DecodeError(ss);
+ return SECSuccess;
}
-/* Called from ssl3_HandleHandshakeMessage() when it has deciphered a complete
- * ssl3 Certificate message.
+/* Called from ssl3_HandlePostHelloHandshakeMessage() 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) );
+ SSL_GETPID(), ss->fd));
+ PORT_Assert(ss->opt.noLocks || ssl_HaveRecvBufLock(ss));
+ PORT_Assert(ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss));
- if ((isServer && ss->ssl3.hs.ws != wait_client_cert) ||
- (!isServer && ss->ssl3.hs.ws != wait_server_cert)) {
- desc = unexpected_message;
- errCode = SSL_ERROR_RX_UNEXPECTED_CERTIFICATE;
- goto alert_loser;
+ if ((ss->sec.isServer && ss->ssl3.hs.ws != wait_client_cert) ||
+ (!ss->sec.isServer && ss->ssl3.hs.ws != wait_server_cert)) {
+ (void)SSL3_SendAlert(ss, alert_fatal, unexpected_message);
+ PORT_SetError(SSL_ERROR_RX_UNEXPECTED_CERTIFICATE);
+ return SECFailure;
}
- 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;
- }
+ return ssl3_CompleteHandleCertificate(ss, b, length);
+}
+
+/* Called from ssl3_HandleCertificate
+ */
+SECStatus
+ssl3_CompleteHandleCertificate(sslSocket *ss, SSL3Opaque *b, PRUint32 length)
+{
+ ssl3CertNode *c;
+ ssl3CertNode *lastCert = NULL;
+ PRInt32 remaining = 0;
+ PRInt32 size;
+ SECStatus rv;
+ PRBool isServer = ss->sec.isServer;
+ PRBool isTLS;
+ SSL3AlertDescription desc;
+ int errCode = SSL_ERROR_RX_MALFORMED_CERTIFICATE;
+ SECItem certItem;
ssl3_CleanupPeerCerts(ss);
isTLS = (PRBool)(ss->ssl3.prSpec->version > SSL_LIBRARY_VERSION_3_0);
@@ -10493,98 +10647,103 @@ ssl3_HandleCertificate(sslSocket *ss, SSL3Opaque *b, PRUint32 length)
** 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;
+ 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;
+ 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;
+ }
+
+ if (ss->version < SSL_LIBRARY_VERSION_TLS_1_3) {
+ ss->ssl3.hs.ws = wait_client_key;
+ } else {
+ TLS13_SET_HS_STATE(ss, wait_finished);
+ }
+ return SECSuccess;
}
ss->ssl3.peerCertArena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
if (ss->ssl3.peerCertArena == NULL) {
- goto loser; /* don't send alerts on memory errors */
+ goto loser; /* don't send alerts on memory errors */
}
/* First get the peer cert. */
remaining -= 3;
if (remaining < 0)
- goto decode_loser;
+ goto decode_loser;
size = ssl3_ConsumeHandshakeNumber(ss, 3, &b, &length);
if (size <= 0)
- goto loser; /* fatal alert already sent by ConsumeHandshake. */
+ goto loser; /* fatal alert already sent by ConsumeHandshake. */
if (remaining < size)
- goto decode_loser;
+ goto decode_loser;
certItem.data = b;
certItem.len = size;
- b += size;
+ b += size;
length -= size;
remaining -= size;
ss->sec.peerCert = CERT_NewTempCertificate(ss->dbHandle, &certItem, NULL,
- PR_FALSE, PR_TRUE);
+ 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;
+ /* 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;
+ 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)
@@ -10592,11 +10751,13 @@ ssl3_HandleCertificate(sslSocket *ss, SSL3Opaque *b, PRUint32 length)
SECKEY_UpdateCertPQG(ss->sec.peerCert);
- if (!isServer && ssl3_ExtensionNegotiated(ss, ssl_cert_status_xtn)) {
- ss->ssl3.hs.ws = wait_certificate_status;
- rv = SECSuccess;
+ if (!isServer &&
+ ss->version < SSL_LIBRARY_VERSION_TLS_1_3 &&
+ 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 */
+ rv = ssl3_AuthCertificate(ss); /* sets ss->ssl3.hs.ws */
}
return rv;
@@ -10604,14 +10765,14 @@ ssl3_HandleCertificate(sslSocket *ss, SSL3Opaque *b, PRUint32 length)
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;
+ 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;
@@ -10627,12 +10788,12 @@ loser:
return SECFailure;
}
-static SECStatus
+SECStatus
ssl3_AuthCertificate(sslSocket *ss)
{
- SECStatus rv;
- PRBool isServer = (PRBool)(!!ss->sec.isServer);
- int errCode;
+ SECStatus rv;
+ PRBool isServer = ss->sec.isServer;
+ int errCode;
ss->ssl3.hs.authCertificatePending = PR_FALSE;
@@ -10642,30 +10803,29 @@ ssl3_AuthCertificate(sslSocket *ss)
* 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;
- }
-
- if (rv != SECSuccess) {
- ssl3_SendAlertForCertError(ss, errCode);
- goto loser;
- }
+ PR_TRUE, isServer);
+ if (rv != SECSuccess) {
+ 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;
+ goto loser;
+ }
+
+ ss->ssl3.hs.authCertificatePending = PR_TRUE;
+ rv = SECSuccess;
+ }
+
+ if (rv != SECSuccess) {
+ ssl3_SendAlertForCertError(ss, errCode);
+ goto loser;
+ }
}
ss->sec.ci.sid->peerCert = CERT_DupCertificate(ss->sec.peerCert);
@@ -10673,84 +10833,106 @@ ssl3_AuthCertificate(sslSocket *ss)
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) {
- KeyType pubKeyType;
- PRInt32 minKey;
- ss->sec.keaKeyBits = ss->sec.authKeyBits =
- SECKEY_PublicKeyStrengthInBits(pubKey);
+ /* set the server authentication type and size from the value
+ ** in the cert. */
+ SECKEYPublicKey *pubKey = CERT_ExtractPublicKey(cert);
+ if (ss->version < SSL_LIBRARY_VERSION_TLS_1_3) {
+ /* These are filled in in tls13_HandleCertificateVerify and
+ * tls13_HandleServerKeyShare. */
+ ss->sec.authType = ss->ssl3.hs.kea_def->authKeyType;
+ ss->sec.keaType = ss->ssl3.hs.kea_def->exchKeyType;
+ }
+ if (pubKey) {
+ KeyType pubKeyType;
+ PRInt32 minKey;
+ /* This partly fixes Bug 124230 and may cause problems for
+ * callers which depend on the old (wrong) behavior. */
+ ss->sec.authKeyBits = SECKEY_PublicKeyStrengthInBits(pubKey);
pubKeyType = SECKEY_GetPublicKeyType(pubKey);
- minKey = ss->sec.authKeyBits;
- switch (pubKeyType) {
- case rsaKey:
- case rsaPssKey:
- case rsaOaepKey:
- rv = NSS_OptionGet(NSS_RSA_MIN_KEY_SIZE, &minKey);
- if (rv != SECSuccess) {
- minKey = SSL_RSA_MIN_MODULUS_BITS;
- }
- break;
- case dsaKey:
- rv = NSS_OptionGet(NSS_DSA_MIN_KEY_SIZE, &minKey);
- if (rv != SECSuccess) {
- minKey = SSL_DSA_MIN_P_BITS;
- }
- break;
- case dhKey:
- rv = NSS_OptionGet(NSS_DH_MIN_KEY_SIZE, &minKey);
- if (rv != SECSuccess) {
- minKey = SSL_DH_MIN_P_BITS;
- }
- break;
- default:
- break;
- }
+ minKey = ss->sec.authKeyBits;
+ switch (pubKeyType) {
+ case rsaKey:
+ case rsaPssKey:
+ case rsaOaepKey:
+ rv =
+ NSS_OptionGet(NSS_RSA_MIN_KEY_SIZE, &minKey);
+ if (rv !=
+ SECSuccess) {
+ minKey =
+ SSL_RSA_MIN_MODULUS_BITS;
+ }
+ break;
+ case dsaKey:
+ rv =
+ NSS_OptionGet(NSS_DSA_MIN_KEY_SIZE, &minKey);
+ if (rv !=
+ SECSuccess) {
+ minKey =
+ SSL_DSA_MIN_P_BITS;
+ }
+ break;
+ case dhKey:
+ rv =
+ NSS_OptionGet(NSS_DH_MIN_KEY_SIZE, &minKey);
+ if (rv !=
+ SECSuccess) {
+ minKey =
+ SSL_DH_MIN_P_BITS;
+ }
+ break;
+ default:
+ break;
+ }
/* Too small: not good enough. Send a fatal alert. */
/* We aren't checking EC here on the understanding that we only
* support curves we like, a decision that might need revisiting. */
- if ( ss->sec.authKeyBits < minKey) {
+ if (ss->sec.authKeyBits < minKey) {
PORT_SetError(SSL_ERROR_WEAK_SERVER_CERT_KEY);
(void)SSL3_SendAlert(ss, alert_fatal,
ss->version >= SSL_LIBRARY_VERSION_TLS_1_0
- ? insufficient_security
- : illegal_parameter);
+ ? insufficient_security
+ : illegal_parameter);
SECKEY_DestroyPublicKey(pubKey);
return SECFailure;
}
- SECKEY_DestroyPublicKey(pubKey);
- pubKey = NULL;
- }
-
- /* Ephemeral suites require ServerKeyExchange. Export cipher suites
- * with RSA key exchange also require ServerKeyExchange if the
- * authentication key exceeds the key size limit. */
- if (ss->ssl3.hs.kea_def->ephemeral ||
- (ss->ssl3.hs.kea_def->is_limited &&
- ss->ssl3.hs.kea_def->exchKeyType == ssl_kea_rsa &&
- ss->sec.authKeyBits > ss->ssl3.hs.kea_def->key_size_limit)) {
- ss->ssl3.hs.ws = wait_server_key; /* require server_key_exchange */
+ SECKEY_DestroyPublicKey(pubKey);
+ pubKey = NULL;
+ }
+
+ if (ss->version >= SSL_LIBRARY_VERSION_TLS_1_3) {
+ TLS13_SET_HS_STATE(ss, wait_cert_verify);
} else {
- ss->ssl3.hs.ws = wait_cert_request; /* disallow server_key_exchange */
+ /* Ephemeral suites require ServerKeyExchange. */
+ if (ss->ssl3.hs.kea_def->ephemeral) {
+ /* require server_key_exchange */
+ ss->ssl3.hs.ws = wait_server_key;
+ } else {
+ /* disallow server_key_exchange */
+ ss->ssl3.hs.ws = wait_cert_request;
+ /* This is static RSA key exchange so set the key exchange
+ * details to compensate for that. */
+ ss->sec.keaKeyBits = ss->sec.authKeyBits;
+ ss->sec.signatureScheme = ssl_sig_none;
+ ss->sec.keaGroup = NULL;
+ }
}
} else {
- ss->ssl3.hs.ws = wait_client_key;
+ /* Server */
+ if (ss->version < SSL_LIBRARY_VERSION_TLS_1_3) {
+ ss->ssl3.hs.ws = wait_client_key;
+ } else {
+ TLS13_SET_HS_STATE(ss, wait_cert_verify);
+ }
}
PORT_Assert(rv == SECSuccess);
if (rv != SECSuccess) {
- errCode = SEC_ERROR_LIBRARY_FAILURE;
- rv = SECFailure;
- goto loser;
+ errCode = SEC_ERROR_LIBRARY_FAILURE;
+ goto loser;
}
- return rv;
+ return SECSuccess;
loser:
(void)ssl_MapLowLevelError(errCode);
@@ -10760,7 +10942,7 @@ loser:
static SECStatus ssl3_FinishHandshake(sslSocket *ss);
static SECStatus
-ssl3_AlwaysFail(sslSocket * ss)
+ssl3_AlwaysFail(sslSocket *ss)
{
PORT_SetError(PR_INVALID_STATE_ERROR);
return SECFailure;
@@ -10776,61 +10958,63 @@ ssl3_AuthCertificateComplete(sslSocket *ss, PRErrorCode error)
PORT_Assert(ss->opt.noLocks || ssl_Have1stHandshakeLock(ss));
if (ss->sec.isServer) {
- PORT_SetError(SSL_ERROR_FEATURE_NOT_SUPPORTED_FOR_SERVERS);
- return SECFailure;
+ 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;
+ 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;
+ 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;
-
- if (target == ssl3_FinishHandshake) {
- SSL_TRC(3,("%d: SSL3[%p]: certificate authentication lost the race"
- " with peer's finished message", SSL_GETPID(), ss->fd));
- }
-
- 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;
- }
+ sslRestartTarget target = ss->ssl3.hs.restartTarget;
+ ss->ssl3.hs.restartTarget = NULL;
+
+ if (target == ssl3_FinishHandshake) {
+ SSL_TRC(3, ("%d: SSL3[%p]: certificate authentication lost the race"
+ " with peer's finished message",
+ SSL_GETPID(), ss->fd));
+ }
+
+ 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 {
- SSL_TRC(3, ("%d: SSL3[%p]: certificate authentication won the race with"
- " peer's finished message", SSL_GETPID(), ss->fd));
-
- PORT_Assert(!ss->ssl3.hs.isResuming);
- PORT_Assert(ss->ssl3.hs.ws != idle_handshake);
-
- if (ss->opt.enableFalseStart &&
- !ss->firstHsDone &&
- !ss->ssl3.hs.isResuming &&
- ssl3_WaitingForStartOfServerSecondRound(ss)) {
- /* ssl3_SendClientSecondRound deferred the false start check because
- * certificate authentication was pending, so we do it now if we still
- * haven't received any of the server's second round yet.
- */
- rv = ssl3_CheckFalseStart(ss);
- } else {
- rv = SECSuccess;
- }
+ SSL_TRC(3, ("%d: SSL3[%p]: certificate authentication won the race with"
+ " peer's finished message",
+ SSL_GETPID(), ss->fd));
+
+ PORT_Assert(!ss->ssl3.hs.isResuming);
+ PORT_Assert(ss->ssl3.hs.ws != idle_handshake);
+
+ if (ss->opt.enableFalseStart &&
+ !ss->firstHsDone &&
+ !ss->ssl3.hs.isResuming &&
+ ssl3_WaitingForServerSecondRound(ss)) {
+ /* ssl3_SendClientSecondRound deferred the false start check because
+ * certificate authentication was pending, so we do it now if we still
+ * haven't received all of the server's second round yet.
+ */
+ rv = ssl3_CheckFalseStart(ss);
+ } else {
+ rv = SECSuccess;
+ }
}
done:
@@ -10841,44 +11025,44 @@ done:
}
static SECStatus
-ssl3_ComputeTLSFinished(ssl3CipherSpec *spec,
- PRBool isServer,
- const SSL3Hashes * hashes,
- TLSFinished * tlsFinished)
+ssl3_ComputeTLSFinished(sslSocket *ss, ssl3CipherSpec *spec,
+ PRBool isServer,
+ const SSL3Hashes *hashes,
+ TLSFinished *tlsFinished)
{
SECStatus rv;
CK_TLS_MAC_PARAMS tls_mac_params;
- SECItem param = {siBuffer, NULL, 0};
+ SECItem param = { siBuffer, NULL, 0 };
PK11Context *prf_context;
unsigned int retLen;
- if (!spec->master_secret || spec->bypassCiphers) {
- const char *label = isServer ? "server finished" : "client finished";
- unsigned int len = 15;
-
- return ssl3_TLSPRFWithMasterSecret(spec, label, len, hashes->u.raw,
- hashes->len, tlsFinished->verify_data,
- sizeof tlsFinished->verify_data);
+ if (!spec->master_secret) {
+ const char *label = isServer ? "server finished" : "client finished";
+ unsigned int len = 15;
+ HASH_HashType hashType = ssl3_GetTls12HashType(ss);
+ return ssl3_TLSPRFWithMasterSecret(spec, label, len, hashes->u.raw,
+ hashes->len, tlsFinished->verify_data,
+ sizeof tlsFinished->verify_data, hashType);
}
if (spec->version < SSL_LIBRARY_VERSION_TLS_1_2) {
- tls_mac_params.prfMechanism = CKM_TLS_PRF;
+ tls_mac_params.prfMechanism = CKM_TLS_PRF;
} else {
- tls_mac_params.prfMechanism = CKM_SHA256;
+ tls_mac_params.prfMechanism = ssl3_GetPrfHashMechanism(ss);
}
tls_mac_params.ulMacLength = 12;
tls_mac_params.ulServerOrClient = isServer ? 1 : 2;
param.data = (unsigned char *)&tls_mac_params;
param.len = sizeof(tls_mac_params);
prf_context = PK11_CreateContextBySymKey(CKM_TLS_MAC, CKA_SIGN,
- spec->master_secret, &param);
+ spec->master_secret, &param);
if (!prf_context)
- return SECFailure;
+ return SECFailure;
- rv = PK11_DigestBegin(prf_context);
+ rv = PK11_DigestBegin(prf_context);
rv |= PK11_DigestOp(prf_context, hashes->u.raw, hashes->len);
rv |= PK11_DigestFinal(prf_context, tlsFinished->verify_data, &retLen,
- sizeof tlsFinished->verify_data);
+ sizeof tlsFinished->verify_data);
PORT_Assert(rv != SECSuccess || retLen == sizeof tlsFinished->verify_data);
PK11_DestroyContext(prf_context, PR_TRUE);
@@ -10892,55 +11076,36 @@ ssl3_ComputeTLSFinished(ssl3CipherSpec *spec,
*/
SECStatus
ssl3_TLSPRFWithMasterSecret(ssl3CipherSpec *spec, const char *label,
- unsigned int labelLen, const unsigned char *val, unsigned int valLen,
- unsigned char *out, unsigned int outLen)
+ unsigned int labelLen, const unsigned char *val, unsigned int valLen,
+ unsigned char *out, unsigned int outLen, HASH_HashType tls12HashType)
{
SECStatus rv = SECSuccess;
- if (spec->master_secret && !spec->bypassCiphers) {
- SECItem param = {siBuffer, NULL, 0};
- CK_MECHANISM_TYPE mech = CKM_TLS_PRF_GENERAL;
- PK11Context *prf_context;
- unsigned int retLen;
-
- if (spec->version >= SSL_LIBRARY_VERSION_TLS_1_2) {
- mech = CKM_NSS_TLS_PRF_GENERAL_SHA256;
- }
- prf_context = PK11_CreateContextBySymKey(mech, CKA_SIGN,
- spec->master_secret, &param);
- 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);
+ if (spec->master_secret) {
+ SECItem param = { siBuffer, NULL, 0 };
+ CK_MECHANISM_TYPE mech = CKM_TLS_PRF_GENERAL;
+ PK11Context *prf_context;
+ unsigned int retLen;
+
+ if (spec->version >= SSL_LIBRARY_VERSION_TLS_1_2) {
+ mech = CKM_NSS_TLS_PRF_GENERAL_SHA256;
+ }
+ prf_context = PK11_CreateContextBySymKey(mech, CKA_SIGN,
+ spec->master_secret, &param);
+ 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;
- if (spec->version >= SSL_LIBRARY_VERSION_TLS_1_2) {
- rv = TLS_P_hash(HASH_AlgSHA256, &spec->msItem, label, &inData,
- &outData, isFIPS);
- } else {
- rv = TLS_PRF(&spec->msItem, label, &inData, &outData, isFIPS);
- }
- PORT_Assert(rv != SECSuccess || outData.len == outLen);
-#endif
+ PORT_Assert(spec->master_secret);
+ PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
+ rv = SECFailure;
}
return rv;
}
@@ -10953,31 +11118,32 @@ ssl3_SendNextProto(sslSocket *ss)
{
SECStatus rv;
int padding_len;
- static const unsigned char padding[32] = {0};
+ static const unsigned char padding[32] = { 0 };
- if (ss->ssl3.nextProto.len == 0 ||
- ss->ssl3.nextProtoState == SSL_NEXT_PROTO_SELECTED) {
- return SECSuccess;
+ if (ss->xtnData.nextProto.len == 0 ||
+ ss->xtnData.nextProtoState == SSL_NEXT_PROTO_SELECTED) {
+ return SECSuccess;
}
- PORT_Assert( ss->opt.noLocks || ssl_HaveXmitBufLock(ss));
- PORT_Assert( ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss));
+ 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);
+ padding_len = 32 - ((ss->xtnData.nextProto.len + 2) % 32);
- rv = ssl3_AppendHandshakeHeader(ss, next_proto, ss->ssl3.nextProto.len +
- 2 + padding_len);
+ rv = ssl3_AppendHandshakeHeader(ss, next_proto, ss->xtnData.nextProto.len +
+ 2 +
+ padding_len);
if (rv != SECSuccess) {
- return rv; /* error code set by AppendHandshakeHeader */
+ return rv; /* error code set by AppendHandshakeHeader */
}
- rv = ssl3_AppendHandshakeVariable(ss, ss->ssl3.nextProto.data,
- ss->ssl3.nextProto.len, 1);
+ rv = ssl3_AppendHandshakeVariable(ss, ss->xtnData.nextProto.data,
+ ss->xtnData.nextProto.len, 1);
if (rv != SECSuccess) {
- return rv; /* error code set by AppendHandshake */
+ 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; /* error code set by AppendHandshake */
}
return rv;
}
@@ -10989,31 +11155,32 @@ ssl3_SendNextProto(sslSocket *ss)
static void
ssl3_RecordKeyLog(sslSocket *ss)
{
+#ifdef NSS_ALLOW_SSLKEYLOGFILE
SECStatus rv;
SECItem *keyData;
char buf[14 /* "CLIENT_RANDOM " */ +
- SSL3_RANDOM_LENGTH*2 /* client_random */ +
- 1 /* " " */ +
- 48*2 /* master secret */ +
+ 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));
+ PORT_Assert(ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss));
if (!ssl_keylog_iob)
- return;
+ return;
rv = PK11_ExtractKeyValue(ss->ssl3.cwSpec->master_secret);
if (rv != SECSuccess)
- return;
+ 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;
+ ssl_ReleaseSpecReadLock(ss);
+ return;
}
/* https://developer.mozilla.org/en/NSS_Key_Log_Format */
@@ -11025,10 +11192,10 @@ ssl3_RecordKeyLog(sslSocket *ss)
memcpy(buf, "CLIENT_RANDOM ", 14);
j = 14;
hexEncode(buf + j, ss->ssl3.hs.client_random.rand, SSL3_RANDOM_LENGTH);
- j += SSL3_RANDOM_LENGTH*2;
+ j += SSL3_RANDOM_LENGTH * 2;
buf[j++] = ' ';
hexEncode(buf + j, keyData->data, 48);
- j += 48*2;
+ j += 48 * 2;
buf[j++] = '\n';
PORT_Assert(j == sizeof(buf));
@@ -11039,6 +11206,7 @@ ssl3_RecordKeyLog(sslSocket *ss)
return;
fflush(ssl_keylog_iob);
return;
+#endif
}
/* called from ssl3_SendClientSecondRound
@@ -11049,59 +11217,59 @@ 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;
- SSL3Hashes hashes;
- TLSFinished tlsFinished;
+ PRBool isTLS;
+ PRBool isServer = ss->sec.isServer;
+ SECStatus rv;
+ SSL3Sender sender = isServer ? sender_server : sender_client;
+ SSL3Hashes 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));
+ 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);
+ rv = ssl3_ComputeTLSFinished(ss, cwSpec, isServer, &hashes, &tlsFinished);
}
ssl_ReleaseSpecReadLock(ss);
if (rv != SECSuccess) {
- goto fail; /* err code was set by ssl3_ComputeHandshakeHashes */
+ 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. */
+ 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.u.s;
- else
- ss->ssl3.hs.finishedMsgs.sFinished[0] = hashes.u.s;
- PORT_Assert(hashes.len == sizeof hashes.u.s);
- ss->ssl3.hs.finishedBytes = sizeof hashes.u.s;
- rv = ssl3_AppendHandshakeHeader(ss, finished, sizeof hashes.u.s);
- if (rv != SECSuccess)
- goto fail; /* err set by AppendHandshake. */
- rv = ssl3_AppendHandshake(ss, &hashes.u.s, sizeof hashes.u.s);
- if (rv != SECSuccess)
- goto fail; /* err set by AppendHandshake. */
+ if (isServer)
+ ss->ssl3.hs.finishedMsgs.sFinished[1] = hashes.u.s;
+ else
+ ss->ssl3.hs.finishedMsgs.sFinished[0] = hashes.u.s;
+ PORT_Assert(hashes.len == sizeof hashes.u.s);
+ ss->ssl3.hs.finishedBytes = sizeof hashes.u.s;
+ rv = ssl3_AppendHandshakeHeader(ss, finished, sizeof hashes.u.s);
+ if (rv != SECSuccess)
+ goto fail; /* err set by AppendHandshake. */
+ rv = ssl3_AppendHandshake(ss, &hashes.u.s, sizeof hashes.u.s);
+ 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 */
+ goto fail; /* error code set by ssl3_FlushHandshake */
}
ssl3_RecordKeyLog(ss);
@@ -11117,298 +11285,315 @@ fail:
*/
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;
+ ssl3CipherSpec *spec, SSLAuthType authType)
+{
+ 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);
- }
- }
+ 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. */
- }
- }
+ /* server socket using session cache. */
+ mechanism = PK11_GetBestWrapMechanism(symKeySlot);
+ if (mechanism != CKM_INVALID_MECHANISM) {
+ wrappingKey =
+ ssl3_GetWrappingKey(ss, symKeySlot, ss->sec.serverCert,
+ mechanism, pwArg);
+ if (wrappingKey) {
+ mechanism = PK11_GetMechanism(wrappingKey); /* can't fail. */
+ }
+ }
}
sid->u.ssl3.masterWrapMech = mechanism;
PK11_FreeSlot(symKeySlot);
if (wrappingKey) {
- SECItem wmsItem;
+ 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);
+ 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.
+/* Called from ssl3_HandlePostHelloHandshakeMessage() 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)
+ const SSL3Hashes *hashes)
{
- sslSessionID * sid = ss->sec.ci.sid;
- SECStatus rv = SECSuccess;
- PRBool isServer = ss->sec.isServer;
- PRBool isTLS;
- SSL3KEAType effectiveExchKeyType;
+ sslSessionID *sid = ss->sec.ci.sid;
+ SECStatus rv = SECSuccess;
+ PRBool isServer = ss->sec.isServer;
+ PRBool isTLS;
- PORT_Assert( ss->opt.noLocks || ssl_HaveRecvBufLock(ss) );
- PORT_Assert( ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss) );
+ 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));
+ 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;
+ SSL3_SendAlert(ss, alert_fatal, unexpected_message);
+ PORT_SetError(SSL_ERROR_RX_UNEXPECTED_FINISHED);
+ return SECFailure;
}
if (!hashes) {
PORT_Assert(0);
- SSL3_SendAlert(ss, alert_fatal, internal_error);
+ SSL3_SendAlert(ss, alert_fatal, internal_error);
PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
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;
- }
+ TLSFinished tlsFinished;
+
+ if (length != sizeof(tlsFinished)) {
+#ifndef UNSAFE_FUZZER_MODE
+ (void)SSL3_SendAlert(ss, alert_fatal, decode_error);
+ PORT_SetError(SSL_ERROR_RX_MALFORMED_FINISHED);
+ return SECFailure;
+#endif
+ }
+ rv = ssl3_ComputeTLSFinished(ss, 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,
+ PR_MIN(length, ss->ssl3.hs.finishedBytes))) {
+#ifndef UNSAFE_FUZZER_MODE
+ (void)SSL3_SendAlert(ss, alert_fatal, decrypt_error);
+ PORT_SetError(SSL_ERROR_BAD_HANDSHAKE_HASH_VALUE);
+ return SECFailure;
+#endif
+ }
} else {
- if (length != sizeof(SSL3Finished)) {
- (void)ssl3_IllegalParameter(ss);
- PORT_SetError(SSL_ERROR_RX_MALFORMED_FINISHED);
- return SECFailure;
- }
-
- if (!isServer)
- ss->ssl3.hs.finishedMsgs.sFinished[1] = hashes->u.s;
- else
- ss->ssl3.hs.finishedMsgs.sFinished[0] = hashes->u.s;
- PORT_Assert(hashes->len == sizeof hashes->u.s);
- ss->ssl3.hs.finishedBytes = sizeof hashes->u.s;
- if (0 != NSS_SecureMemcmp(&hashes->u.s, b, length)) {
- (void)ssl3_HandshakeFailure(ss);
- PORT_SetError(SSL_ERROR_BAD_HANDSHAKE_HASH_VALUE);
- return SECFailure;
- }
- }
-
- ssl_GetXmitBufLock(ss); /*************************************/
+ if (length != sizeof(SSL3Finished)) {
+ (void)ssl3_IllegalParameter(ss);
+ PORT_SetError(SSL_ERROR_RX_MALFORMED_FINISHED);
+ return SECFailure;
+ }
+
+ if (!isServer)
+ ss->ssl3.hs.finishedMsgs.sFinished[1] = hashes->u.s;
+ else
+ ss->ssl3.hs.finishedMsgs.sFinished[0] = hashes->u.s;
+ PORT_Assert(hashes->len == sizeof hashes->u.s);
+ ss->ssl3.hs.finishedBytes = sizeof hashes->u.s;
+ if (0 != NSS_SecureMemcmp(&hashes->u.s, 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) &&
- ssl3_KEAAllowsSessionTicket(ss->ssl3.hs.suite_def->key_exchange_alg)) {
- /* RFC 5077 Section 3.3: "In the case of a full handshake, the
- * server MUST verify the client's Finished message before sending
- * the ticket." Presumably, this also means that the client's
- * certificate, if any, must be verified beforehand too.
- */
- 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. */
- }
+ (!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) &&
+ ssl3_KEASupportsTickets(ss->ssl3.hs.kea_def)) {
+ /* RFC 5077 Section 3.3: "In the case of a full handshake, the
+ * server MUST verify the client's Finished message before sending
+ * the ticket." Presumably, this also means that the client's
+ * certificate, if any, must be verified beforehand too.
+ */
+ 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); /*************************************/
+ ssl_ReleaseXmitBufLock(ss); /*************************************/
if (rv != SECSuccess) {
return rv;
}
- if (ss->ssl3.hs.kea_def->kea == kea_ecdhe_rsa ||
- ss->ssl3.hs.kea_def->kea == kea_dhe_rsa) {
- effectiveExchKeyType = kt_rsa;
- } else {
- effectiveExchKeyType = ss->ssl3.hs.kea_def->exchKeyType;
- }
+ if (sid->cached == never_cached && !ss->opt.noCache) {
+ rv = ssl3_FillInCachedSID(ss, sid);
- 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;
-#ifndef NSS_DISABLE_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 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;
- }
+ 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;
+ ss->ssl3.hs.restartTarget = ssl3_FinishHandshake;
+ return SECWouldBlock;
}
rv = ssl3_FinishHandshake(ss);
return rv;
}
+SECStatus
+ssl3_FillInCachedSID(sslSocket *ss, sslSessionID *sid)
+{
+ SECStatus rv;
+
+ /* 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;
+ sid->version = ss->version;
+ sid->authType = ss->sec.authType;
+ 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);
+ if (ss->sec.isServer) {
+ memcpy(&sid->certType, &ss->sec.serverCert->certType, sizeof(sid->certType));
+ } else {
+ sid->certType.authType = ssl_auth_null;
+ }
+
+ if (ss->xtnData.nextProtoState != SSL_NEXT_PROTO_NO_SUPPORT &&
+ ss->xtnData.nextProto.data) {
+ if (SECITEM_CopyItem(
+ NULL, &sid->u.ssl3.alpnSelection, &ss->xtnData.nextProto) != SECSuccess) {
+ return SECFailure; /* error already set. */
+ }
+ }
+
+ 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,
+ ss->ssl3.hs.kea_def->authKeyType);
+ sid->u.ssl3.keys.msIsWrapped = PR_TRUE;
+ }
+ ssl_ReleaseSpecReadLock(ss); /*************************************/
+
+ return rv;
+}
+
/* The return type is SECStatus instead of void because this function needs
* to have type sslRestartTarget.
*/
SECStatus
-ssl3_FinishHandshake(sslSocket * ss)
+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 );
+ 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->handshake = NULL;
/* RFC 5077 Section 3.3: "The client MUST NOT treat the ticket as valid
* until it has verified the server's Finished message." When the server
@@ -11416,23 +11601,23 @@ ssl3_FinishHandshake(sslSocket * ss)
* the handshake is finished (we have verified the server's Finished
* AND the server's certificate) before we update the ticket in the sid.
*
- * This must be done before we call (*ss->sec.cache)(ss->sec.ci.sid)
+ * This must be done before we call ss->sec.cache(ss->sec.ci.sid)
* because CacheSID requires the session ticket to already be set, and also
* because of the lazy lock creation scheme used by CacheSID and
* ssl3_SetSIDSessionTicket.
*/
if (ss->ssl3.hs.receivedNewSessionTicket) {
- PORT_Assert(!ss->sec.isServer);
- ssl3_SetSIDSessionTicket(ss->sec.ci.sid, &ss->ssl3.hs.newSessionTicket);
- /* The sid took over the ticket data */
- PORT_Assert(!ss->ssl3.hs.newSessionTicket.ticket.data);
+ PORT_Assert(!ss->sec.isServer);
+ ssl3_SetSIDSessionTicket(ss->sec.ci.sid, &ss->ssl3.hs.newSessionTicket);
+ /* The sid took over the ticket data */
+ PORT_Assert(!ss->ssl3.hs.newSessionTicket.ticket.data);
ss->ssl3.hs.receivedNewSessionTicket = PR_FALSE;
}
if (ss->ssl3.hs.cacheSID) {
- PORT_Assert(ss->sec.ci.sid->cached == never_cached);
- (*ss->sec.cache)(ss->sec.ci.sid);
- ss->ssl3.hs.cacheSID = PR_FALSE;
+ PORT_Assert(ss->sec.ci.sid->cached == never_cached);
+ ss->sec.cache(ss->sec.ci.sid);
+ ss->ssl3.hs.cacheSID = PR_FALSE;
}
ss->ssl3.hs.canFalseStart = PR_FALSE; /* False Start phase is complete */
@@ -11448,89 +11633,134 @@ ssl3_FinishHandshake(sslSocket * ss)
* Caller must hold Handshake and RecvBuf locks.
*/
SECStatus
-ssl3_HandleHandshakeMessage(sslSocket *ss, SSL3Opaque *b, PRUint32 length)
+ssl3_HandleHandshakeMessage(sslSocket *ss, SSL3Opaque *b, PRUint32 length,
+ PRBool endOfRecord)
{
- SECStatus rv = SECSuccess;
- SSL3HandshakeType type = ss->ssl3.hs.msg_type;
- SSL3Hashes hashes; /* computed hashes are put here. */
- SSL3Hashes *hashesPtr = NULL; /* Set when hashes are computed */
- PRUint8 hdr[4];
- PRUint8 dtlsData[8];
-
- PORT_Assert( ss->opt.noLocks || ssl_HaveRecvBufLock(ss) );
- PORT_Assert( ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss) );
+ SECStatus rv = SECSuccess;
+ SSL3HandshakeType type = ss->ssl3.hs.msg_type;
+ SSL3Hashes hashes; /* computed hashes are put here. */
+ SSL3Hashes *hashesPtr = NULL; /* Set when hashes are computed */
+ PRUint8 hdr[4];
+ PRUint8 dtlsData[8];
+ PRBool computeHashes = PR_FALSE;
+ PRUint16 epoch;
+
+ 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) && (ss->ssl3.hs.ws == wait_finished)) ||
- ((type == certificate_verify) && (ss->ssl3.hs.ws == wait_cert_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);
+ if (ss->version < SSL_LIBRARY_VERSION_TLS_1_3) {
+ if ((type == finished) && (ss->ssl3.hs.ws == wait_finished)) {
+ computeHashes = PR_TRUE;
+ } else if ((type == certificate_verify) && (ss->ssl3.hs.ws == wait_cert_verify)) {
+ if (ss->ssl3.hs.hashType == handshake_hash_record) {
+ /* We cannot compute the hash yet. We must wait until we have
+ * decoded the certificate_verify message in
+ * ssl3_HandleCertificateVerify, which will tell us which
+ * hash function we must use.
+ *
+ * (ssl3_HandleCertificateVerify cannot simply look at the
+ * buffer length itself, because at the time we reach it,
+ * additional handshake messages will have been added to the
+ * buffer, e.g. the certificate_verify message itself.)
+ *
+ * Therefore, we use SSL3Hashes.u.pointer_to_hash_input
+ * to signal the current state of the buffer.
+ *
+ * ssl3_HandleCertificateVerify will detect
+ * hashType == handshake_hash_record
+ * and use that information to calculate the hash.
+ */
+ hashes.u.pointer_to_hash_input.data = ss->ssl3.hs.messages.buf;
+ hashes.u.pointer_to_hash_input.len = ss->ssl3.hs.messages.len;
+ hashesPtr = &hashes;
+ } else {
+ computeHashes = PR_TRUE;
+ }
+ }
+ } else {
+ if (type == certificate_verify) {
+ computeHashes = TLS13_IN_HS_STATE(ss, wait_cert_verify);
+ } else if (type == finished) {
+ computeHashes =
+ TLS13_IN_HS_STATE(ss, wait_cert_request, wait_finished);
+ }
+ }
+
+ ssl_GetSpecReadLock(ss); /************************************/
+ if (computeHashes) {
+ SSL3Sender sender = (SSL3Sender)0;
+ ssl3CipherSpec *rSpec = ss->version >= SSL_LIBRARY_VERSION_TLS_1_3 ? ss->ssl3.crSpec
+ : 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);
if (rv == SECSuccess) {
hashesPtr = &hashes;
}
}
ssl_ReleaseSpecReadLock(ss); /************************************/
if (rv != SECSuccess) {
- return rv; /* error code was set by ssl3_ComputeHandshakeHashes*/
+ 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)));
+ SSL_TRC(30, ("%d: SSL3[%d]: handle handshake message: %s", SSL_GETPID(),
+ ss->fd, ssl3_DecodeHandshakeType(ss->ssl3.hs.msg_type)));
hdr[0] = (PRUint8)ss->ssl3.hs.msg_type;
hdr[1] = (PRUint8)(length >> 16);
- hdr[2] = (PRUint8)(length >> 8);
- hdr[3] = (PRUint8)(length );
+ 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) {
- rv = ssl3_RestartHandshakeHashes(ss);
- if (rv != SECSuccess) {
- return rv;
- }
+ /* Start new handshake hashes when we start a new handshake. Unless this is
+ * TLS 1.3 and we sent a HelloRetryRequest. */
+ if (ss->ssl3.hs.msg_type == client_hello && !ss->ssl3.hs.helloRetry) {
+ 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 );
+ (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. */
- rv = ssl3_UpdateHandshakeHashes(ss, (unsigned char*) dtlsData,
- sizeof(dtlsData));
- 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. */
+ /* 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. */
+ PORT_SetError(0); /* each message starts with no error. */
if (ss->ssl3.hs.ws == wait_certificate_status &&
ss->ssl3.hs.msg_type != certificate_status) {
@@ -11548,115 +11778,151 @@ ssl3_HandleHandshakeMessage(sslSocket *ss, SSL3Opaque *b, PRUint32 length)
}
}
+ epoch = ss->ssl3.crSpec->epoch;
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:
- rv = ssl3_HandleCertificateStatus(ss, b, length);
- 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, hashesPtr);
- 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, hashesPtr);
- break;
- default:
- (void)SSL3_SendAlert(ss, alert_fatal, unexpected_message);
- PORT_SetError(SSL_ERROR_RX_UNKNOWN_HANDSHAKE);
- rv = SECFailure;
+ 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;
+ default:
+ if (ss->version < SSL_LIBRARY_VERSION_TLS_1_3) {
+ rv = ssl3_HandlePostHelloHandshakeMessage(ss, b, length, hashesPtr);
+ } else {
+ rv = tls13_HandlePostHelloHandshakeMessage(ss, b, length,
+ hashesPtr);
+ }
+ break;
+ }
+ if (ss->version >= SSL_LIBRARY_VERSION_TLS_1_3 &&
+ (epoch != ss->ssl3.crSpec->epoch) && !endOfRecord) {
+ /* If we changed read cipher states, there must not be any
+ * data in the input queue. */
+ (void)SSL3_SendAlert(ss, alert_fatal, unexpected_message);
+ PORT_SetError(SSL_ERROR_RX_UNEXPECTED_HANDSHAKE);
+ return SECFailure;
}
if (IS_DTLS(ss) && (rv != SECFailure)) {
- /* Increment the expected sequence number */
- ss->ssl3.hs.recvMessageSeq++;
+ /* Increment the expected sequence number */
+ ss->ssl3.hs.recvMessageSeq++;
+ }
+ return rv;
+}
+
+static SECStatus
+ssl3_HandlePostHelloHandshakeMessage(sslSocket *ss, SSL3Opaque *b,
+ PRUint32 length, SSL3Hashes *hashesPtr)
+{
+ SECStatus rv;
+ PORT_Assert(ss->version < SSL_LIBRARY_VERSION_TLS_1_3);
+
+ 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 hello_retry_request:
+ /* This arrives here because - as a client - we haven't received a
+ * final decision on the version from the server. */
+ rv = tls13_HandleHelloRetryRequest(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:
+ rv = ssl3_HandleCertificateStatus(ss, b, length);
+ 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, hashesPtr);
+ 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, hashesPtr);
+ break;
+ default:
+ (void)SSL3_SendAlert(ss, alert_fatal, unexpected_message);
+ PORT_SetError(SSL_ERROR_RX_UNKNOWN_HANDSHAKE);
+ rv = SECFailure;
}
return rv;
@@ -11680,109 +11946,111 @@ ssl3_HandleHandshake(sslSocket *ss, sslBuffer *origBuf)
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) );
+ PORT_Assert(ss->opt.noLocks || ssl_HaveRecvBufLock(ss));
+ PORT_Assert(ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss));
if (buf->buf == NULL) {
- *buf = *origBuf;
+ *buf = *origBuf;
}
while (buf->len > 0) {
- if (ss->ssl3.hs.header_bytes < 4) {
- PRUint8 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_MALFORMED_HANDSHAKE);
- return SECFailure;
- }
+ if (ss->ssl3.hs.header_bytes < 4) {
+ PRUint8 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_MALFORMED_HANDSHAKE);
+ 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. */
+ /* 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,
+ buf->len == 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,
+ buf->len == 0);
+ 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;
}
@@ -11790,7 +12058,7 @@ ssl3_HandleHandshake(sslSocket *ss, sslBuffer *origBuf)
* 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(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
@@ -11823,10 +12091,17 @@ ssl_ConstantTimeEQ8(unsigned char a, unsigned char b)
return DUPLICATE_MSB_TO_ALL_8(c);
}
+/* ssl_constantTimeSelect return a if mask is 0xFF and b if mask is 0x00 */
+static unsigned char
+ssl_constantTimeSelect(unsigned char mask, unsigned char a, unsigned char b)
+{
+ return (mask & a) | (~mask & b);
+}
+
static SECStatus
ssl_RemoveSSLv3CBCPadding(sslBuffer *plaintext,
- unsigned int blockSize,
- unsigned int macSize)
+ unsigned int blockSize,
+ unsigned int macSize)
{
unsigned int paddingLength, good, t;
const unsigned int overhead = 1 /* padding length byte */ + macSize;
@@ -11834,23 +12109,23 @@ ssl_RemoveSSLv3CBCPadding(sslBuffer *plaintext,
/* These lengths are all public so we can test them in non-constant
* time. */
if (overhead > plaintext->len) {
- return SECFailure;
+ return SECFailure;
}
- paddingLength = plaintext->buf[plaintext->len-1];
+ paddingLength = plaintext->buf[plaintext->len - 1];
/* SSLv3 padding bytes are random and cannot be checked. */
t = plaintext->len;
- t -= paddingLength+overhead;
+ t -= paddingLength + overhead;
/* If len >= paddingLength+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);
+ t = blockSize - (paddingLength + 1);
good &= DUPLICATE_MSB_TO_ALL(~t);
- plaintext->len -= good & (paddingLength+1);
+ plaintext->len -= good & (paddingLength + 1);
return (good & SECSuccess) | (~good & SECFailure);
}
-static SECStatus
+SECStatus
ssl_RemoveTLSCBCPadding(sslBuffer *plaintext, unsigned int macSize)
{
unsigned int paddingLength, good, t, toCheck, i;
@@ -11859,12 +12134,12 @@ ssl_RemoveTLSCBCPadding(sslBuffer *plaintext, unsigned int macSize)
/* These lengths are all public so we can test them in non-constant
* time. */
if (overhead > plaintext->len) {
- return SECFailure;
+ return SECFailure;
}
- paddingLength = plaintext->buf[plaintext->len-1];
+ paddingLength = plaintext->buf[plaintext->len - 1];
t = plaintext->len;
- t -= paddingLength+overhead;
+ t -= paddingLength + overhead;
/* If len >= paddingLength+overhead then the MSB of t is zero. */
good = DUPLICATE_MSB_TO_ALL(~t);
@@ -11877,20 +12152,20 @@ ssl_RemoveTLSCBCPadding(sslBuffer *plaintext, unsigned int macSize)
* 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;
+ toCheck = 256; /* maximum amount of padding + 1. */
+ if (toCheck > plaintext->len) {
+ toCheck = plaintext->len;
}
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));
+ 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,
@@ -11900,10 +12175,10 @@ ssl_RemoveTLSCBCPadding(sslBuffer *plaintext, unsigned int macSize)
good &= good >> 4;
good &= good >> 2;
good &= good >> 1;
- good <<= sizeof(good)*8-1;
+ good <<= sizeof(good) * 8 - 1;
good = DUPLICATE_MSB_TO_ALL(good);
- plaintext->len -= good & (paddingLength+1);
+ plaintext->len -= good & (paddingLength + 1);
return (good & SECSuccess) | (~good & SECFailure);
}
@@ -11914,9 +12189,9 @@ ssl_RemoveTLSCBCPadding(sslBuffer *plaintext, unsigned int macSize)
*/
static void
ssl_CBCExtractMAC(sslBuffer *plaintext,
- unsigned int originalLength,
- SSL3Opaque* out,
- unsigned int macSize)
+ 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
@@ -11926,44 +12201,280 @@ ssl_CBCExtractMAC(sslBuffer *plaintext,
/* 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 i, j;
unsigned char rotateOffset;
- if (originalLength > macSize + 255 + 1)
- scanStart = originalLength - (macSize + 255 + 1);
+ 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;
+ /* We want to compute
+ * rotateOffset = (macStart - scanStart) % macSize
+ * But the time to compute this varies based on the amount of padding. Thus
+ * we explicitely handle all mac sizes with (hopefully) constant time modulo
+ * using Barrett reduction:
+ * q := (rotateOffset * m) >> k
+ * rotateOffset -= q * n
+ * if (n <= rotateOffset) rotateOffset -= n
+ */
+ rotateOffset = macStart - scanStart;
+ /* rotateOffset < 255 + 1 + 48 = 304 */
+ if (macSize == 16) {
+ rotateOffset &= 15;
+ } else if (macSize == 20) {
+ /*
+ * Correctness: rotateOffset * ( 1/20 - 25/2^9 ) < 1
+ * with rotateOffset <= 853
+ */
+ unsigned q = (rotateOffset * 25) >> 9;
+ rotateOffset -= q * 20;
+ rotateOffset -= ssl_constantTimeSelect(ssl_ConstantTimeGE(rotateOffset, 20),
+ 20, 0);
+ } else if (macSize == 32) {
+ rotateOffset &= 31;
+ } else if (macSize == 48) {
+ /*
+ * Correctness: rotateOffset * ( 1/48 - 10/2^9 ) < 1
+ * with rotateOffset < 768
+ */
+ unsigned q = (rotateOffset * 10) >> 9;
+ rotateOffset -= q * 48;
+ rotateOffset -= ssl_constantTimeSelect(ssl_ConstantTimeGE(rotateOffset, 48),
+ 48, 0);
+ } else {
+ /*
+ * SHA384 (macSize == 48) is the largest we support. We should never
+ * get here.
+ */
+ PORT_Assert(0);
+ rotateOffset = rotateOffset % 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;
- }
+ 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);
+ rotateOffset = macSize - rotateOffset;
+ rotateOffset = ssl_constantTimeSelect(ssl_ConstantTimeGE(rotateOffset, macSize),
+ 0, rotateOffset);
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);
- }
+ for (j = 0; j < macSize; j++) {
+ out[j] |= rotatedMac[i] & ssl_ConstantTimeEQ8(j, rotateOffset);
+ }
+ rotateOffset++;
+ rotateOffset = ssl_constantTimeSelect(ssl_ConstantTimeGE(rotateOffset, macSize),
+ 0, rotateOffset);
+ }
+}
+
+/* Unprotect an SSL3 record and leave the result in plaintext.
+ *
+ * If SECFailure is returned, we:
+ * 1. Set |*alert| to the alert to be sent.
+ * 2. Call PORT_SetError() with an appropriate code.
+ *
+ * Called by ssl3_HandleRecord. Caller must hold the spec read lock.
+ * Therefore, we MUST not call SSL3_SendAlert().
+ *
+ */
+static SECStatus
+ssl3_UnprotectRecord(sslSocket *ss, SSL3Ciphertext *cText, sslBuffer *plaintext,
+ SSL3AlertDescription *alert)
+{
+ ssl3CipherSpec *crSpec = ss->ssl3.crSpec;
+ const ssl3BulkCipherDef *cipher_def = crSpec->cipher_def;
+ PRBool isTLS;
+ unsigned int good;
+ unsigned int ivLen = 0;
+ SSL3ContentType rType;
+ unsigned int minLength;
+ unsigned int originalLen = 0;
+ unsigned char header[13];
+ unsigned int headerLen;
+ SSL3Opaque hash[MAX_MAC_LENGTH];
+ SSL3Opaque givenHashBuf[MAX_MAC_LENGTH];
+ SSL3Opaque *givenHash;
+ unsigned int hashBytes = MAX_MAC_LENGTH + 1;
+ SECStatus rv;
+
+ good = ~0U;
+ 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;
+ }
+ } else if (cipher_def->type == type_aead) {
+ minLength = cipher_def->explicit_nonce_size + cipher_def->tag_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) {
+ goto decrypt_loser;
+ }
+
+ 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)) {
+ *alert = internal_error;
+ 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);
+ }
+
+ 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)) {
+ *alert = record_overflow;
+ PORT_SetError(SSL_ERROR_RX_RECORD_TOO_LONG);
+ return SECFailure;
+ }
+
+ rType = cText->type;
+ if (cipher_def->type == type_aead) {
+ /* XXX For many AEAD ciphers, the plaintext is shorter than the
+ * ciphertext by a fixed byte count, but it is not true in general.
+ * Each AEAD cipher should provide a function that returns the
+ * plaintext length for a given ciphertext. */
+ unsigned int decryptedLen =
+ cText->buf->len - cipher_def->explicit_nonce_size -
+ cipher_def->tag_size;
+ headerLen = ssl3_BuildRecordPseudoHeader(
+ header, IS_DTLS(ss) ? cText->seq_num : crSpec->read_seq_num,
+ rType, isTLS, cText->version, IS_DTLS(ss), decryptedLen);
+ PORT_Assert(headerLen <= sizeof(header));
+ rv = crSpec->aead(
+ ss->sec.isServer ? &crSpec->client : &crSpec->server,
+ PR_TRUE, /* do decrypt */
+ plaintext->buf, /* out */
+ (int *)&plaintext->len, /* outlen */
+ plaintext->space, /* maxout */
+ cText->buf->buf, /* in */
+ cText->buf->len, /* inlen */
+ header, headerLen);
+ if (rv != SECSuccess) {
+ good = 0;
+ }
+ } else {
+ if (cipher_def->type == type_block &&
+ ((cText->buf->len - ivLen) % cipher_def->block_size) != 0) {
+ goto decrypt_loser;
+ }
+
+ /* 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);
+ if (rv != SECSuccess) {
+ goto decrypt_loser;
+ }
+
+ 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->block_size;
+ const unsigned int macSize = crSpec->mac_size;
+
+ if (!isTLS) {
+ good &= SECStatusToMask(ssl_RemoveSSLv3CBCPadding(
+ plaintext, blockSize, macSize));
+ } else {
+ good &= SECStatusToMask(ssl_RemoveTLSCBCPadding(
+ plaintext, macSize));
+ }
+ }
+
+ /* compute the MAC */
+ headerLen = ssl3_BuildRecordPseudoHeader(
+ header, IS_DTLS(ss) ? cText->seq_num : crSpec->read_seq_num,
+ rType, isTLS, cText->version, IS_DTLS(ss),
+ plaintext->len - crSpec->mac_size);
+ PORT_Assert(headerLen <= sizeof(header));
+ if (cipher_def->type == type_block) {
+ rv = ssl3_ComputeRecordMACConstantTime(
+ crSpec, (PRBool)(!ss->sec.isServer), header, headerLen,
+ 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), header, headerLen,
+ 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) {
+ decrypt_loser:
+ /* always log mac error, in case attacker can read server logs. */
+ PORT_SetError(SSL_ERROR_BAD_MAC_READ);
+ *alert = bad_record_mac;
+ return SECFailure;
}
+ return SECSuccess;
}
/* if cText is non-null, then decipher, check MAC, and decompress the
@@ -11991,40 +12502,29 @@ ssl_CBCExtractMAC(sslBuffer *plaintext,
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 = 0;
- unsigned int ivLen = 0;
- unsigned int originalLen = 0;
- unsigned int good;
- unsigned int minLength;
- unsigned char header[13];
- unsigned int headerLen;
-
- PORT_Assert( ss->opt.noLocks || ssl_HaveRecvBufLock(ss) );
+ SECStatus rv;
+ PRBool isTLS;
+ sslSequenceNumber seq_num = 0;
+ ssl3CipherSpec *crSpec;
+ SSL3ContentType rType;
+ sslBuffer *plaintext;
+ sslBuffer temp_buf;
+ SSL3AlertDescription alert = internal_error;
+ 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. */
- }
+ 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;
+ PORT_SetError(SSL_ERROR_TOKEN_INSERTION_REMOVAL);
+ return SECFailure;
}
/* cText is NULL when we're called from ssl3_RestartHandshakeAfterXXX().
@@ -12032,257 +12532,113 @@ ssl3_HandleRecord(sslSocket *ss, SSL3Ciphertext *cText, sslBuffer *databuf)
* message.
*/
if (cText == NULL) {
- SSL_DBG(("%d: SSL3[%d]: HandleRecord, resuming handshake",
- SSL_GETPID(), ss->fd));
- rType = content_handshake;
- goto process_it;
+ 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;
- }
- }
+ isTLS = (PRBool)(crSpec->version > SSL_LIBRARY_VERSION_3_0);
- good = ~0U;
- 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;
- }
- } else if (cipher_def->type == type_aead) {
- minLength = cipher_def->explicit_nonce_size + cipher_def->tag_size;
- }
+ if (IS_DTLS(ss)) {
+ PRBool sameEpoch;
+ if (!dtls_IsRelevant(ss, cText, &sameEpoch, &seq_num)) {
+ ssl_ReleaseSpecReadLock(ss); /*****************************/
+ databuf->len = 0; /* Needed to ensure data not left around */
- /* 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) {
- goto decrypt_loser;
+ /* Maybe retransmit if needed. */
+ return dtls_MaybeRetransmitHandshake(ss, cText, sameEpoch);
+ }
+ } else {
+ seq_num = crSpec->read_seq_num + 1;
}
-
- 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 (seq_num >= crSpec->cipher_def->max_records) {
+ ssl_ReleaseSpecReadLock(ss); /*****************************/
+ SSL_TRC(3, ("%d: SSL[%d]: read sequence number at limit 0x%0llx",
+ SSL_GETPID(), ss->fd, seq_num));
+ PORT_SetError(SSL_ERROR_TOO_MANY_RECORDS);
+ return SECFailure;
}
/* 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;
+ temp_buf.buf = NULL;
+ temp_buf.space = 0;
+ plaintext = &temp_buf;
} else {
- plaintext = databuf;
+ plaintext = databuf;
}
- plaintext->len = 0; /* filled in by decode call below. */
+ plaintext->len = 0; /* filled in by Unprotect 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;
- }
+ 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;
+ /* We're waiting for another ClientHello, which will appear unencrypted.
+ * Use the content type to tell whether this is should be discarded.
+ *
+ * XXX If we decide to remove the content type from encrypted records, this
+ * will become much more difficult to manage. */
+ if (ss->ssl3.hs.zeroRttIgnore == ssl_0rtt_ignore_hrr &&
+ cText->type == content_application_data) {
+ ssl_ReleaseSpecReadLock(ss); /*****************************/
+ PORT_Assert(ss->ssl3.hs.ws == wait_client_hello);
+ databuf->len = 0;
+ return SECSuccess;
}
- rType = cText->type;
- if (cipher_def->type == type_aead) {
- /* XXX For many AEAD ciphers, the plaintext is shorter than the
- * ciphertext by a fixed byte count, but it is not true in general.
- * Each AEAD cipher should provide a function that returns the
- * plaintext length for a given ciphertext. */
- unsigned int decryptedLen =
- cText->buf->len - cipher_def->explicit_nonce_size -
- cipher_def->tag_size;
- headerLen = ssl3_BuildRecordPseudoHeader(
- header, IS_DTLS(ss) ? cText->seq_num : crSpec->read_seq_num,
- rType, isTLS, cText->version, IS_DTLS(ss), decryptedLen);
- PORT_Assert(headerLen <= sizeof(header));
- rv = crSpec->aead(
- ss->sec.isServer ? &crSpec->client : &crSpec->server,
- PR_TRUE, /* do decrypt */
- plaintext->buf, /* out */
- (int*) &plaintext->len, /* outlen */
- plaintext->space, /* maxout */
- cText->buf->buf, /* in */
- cText->buf->len, /* inlen */
- header, headerLen);
- if (rv != SECSuccess) {
- good = 0;
- }
+#ifdef UNSAFE_FUZZER_MODE
+ rv = Null_Cipher(NULL, plaintext->buf, (int *)&plaintext->len,
+ plaintext->space, cText->buf->buf, cText->buf->len);
+#else
+ /* IMPORTANT: Unprotect functions MUST NOT send alerts
+ * because we still hold the spec read lock. Instead, if they
+ * return SECFailure, they set *alert to the alert to be sent. */
+ if (crSpec->version < SSL_LIBRARY_VERSION_TLS_1_3 ||
+ crSpec->cipher_def->calg == ssl_calg_null) {
+ /* Unencrypted TLS 1.3 records use the pre-TLS 1.3 format. */
+ rv = ssl3_UnprotectRecord(ss, cText, plaintext, &alert);
} else {
- if (cipher_def->type == type_block &&
- ((cText->buf->len - ivLen) % cipher_def->block_size) != 0) {
- goto decrypt_loser;
- }
-
- /* 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);
- if (rv != SECSuccess) {
- goto decrypt_loser;
- }
-
- 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->block_size;
- const unsigned int macSize = crSpec->mac_size;
-
- if (!isTLS) {
- good &= SECStatusToMask(ssl_RemoveSSLv3CBCPadding(
- plaintext, blockSize, macSize));
- } else {
- good &= SECStatusToMask(ssl_RemoveTLSCBCPadding(
- plaintext, macSize));
- }
- }
-
- /* compute the MAC */
- headerLen = ssl3_BuildRecordPseudoHeader(
- header, IS_DTLS(ss) ? cText->seq_num : crSpec->read_seq_num,
- rType, isTLS, cText->version, IS_DTLS(ss),
- plaintext->len - crSpec->mac_size);
- PORT_Assert(headerLen <= sizeof(header));
- if (cipher_def->type == type_block) {
- rv = ssl3_ComputeRecordMACConstantTime(
- crSpec, (PRBool)(!ss->sec.isServer), header, headerLen,
- 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), header, headerLen,
- 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;
- }
+ rv = tls13_UnprotectRecord(ss, cText, plaintext, &alert);
}
+#endif
- if (good == 0) {
-decrypt_loser:
- /* must not hold spec lock when calling SSL3_SendAlert. */
- ssl_ReleaseSpecReadLock(ss);
-
- SSL_DBG(("%d: SSL3[%d]: decryption 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 */
+ if (rv != SECSuccess) {
+ ssl_ReleaseSpecReadLock(ss); /***************************/
+
+ SSL_DBG(("%d: SSL3[%d]: decryption failed", SSL_GETPID(), ss->fd));
+
+ if (IS_DTLS(ss) ||
+ (ss->sec.isServer &&
+ ss->ssl3.hs.zeroRttIgnore == ssl_0rtt_ignore_trial)) {
+ /* Silently drop the packet */
databuf->len = 0; /* Needed to ensure data not left around */
- return SECSuccess;
- }
+ return SECSuccess;
+ } else {
+ int errCode = PORT_GetError();
+ SSL3_SendAlert(ss, alert_fatal, alert);
+ /* Reset the error code in case SSL3_SendAlert called
+ * PORT_SetError(). */
+ PORT_SetError(errCode);
+ return SECFailure;
+ }
}
- if (!IS_DTLS(ss)) {
- ssl3_BumpSequenceNumber(&crSpec->read_seq_num);
- } else {
- dtls_RecordSetRecvd(&crSpec->recvdRecords, dtls_seq_num);
+ /* SECSuccess */
+ crSpec->read_seq_num = seq_num;
+ if (IS_DTLS(ss)) {
+ dtls_RecordSetRecvd(&crSpec->recvdRecords, seq_num);
}
ssl_ReleaseSpecReadLock(ss); /*****************************************/
@@ -12290,86 +12646,95 @@ decrypt_loser:
/*
* The decrypted data is now in plaintext.
*/
+ rType = cText->type; /* This must go after decryption because TLS 1.3
+ * has encrypted content types. */
/* 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);
+ 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.
+ ** 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;
+ 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;
+ if (ss->firstHsDone)
+ return SECSuccess;
+ if (ss->version >= SSL_LIBRARY_VERSION_TLS_1_3 &&
+ ss->sec.isServer &&
+ ss->ssl3.hs.zeroRttState == ssl_0rtt_accepted) {
+ return tls13_HandleEarlyApplicationData(ss, databuf);
+ }
+ (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.
+/* 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
@@ -12381,29 +12746,29 @@ process_it:
** 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;
+ 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));
+ PORT_SetError(SSL_ERROR_RX_UNKNOWN_RECORD_TYPE);
+ ssl3_DecodeError(ss);
+ rv = SECFailure;
+ break;
}
ssl_ReleaseSSL3HandshakeLock(ss);
@@ -12414,94 +12779,113 @@ process_it:
* Initialization functions
*/
+void
+ssl_InitSecState(sslSecurityInfo *sec)
+{
+ sec->authType = ssl_auth_null;
+ sec->authKeyBits = 0;
+ sec->signatureScheme = ssl_sig_none;
+ sec->keaType = ssl_kea_null;
+ sec->keaKeyBits = 0;
+ sec->keaGroup = NULL;
+}
+
/* Called from ssl3_InitState, immediately below. */
/* Caller must hold the SpecWriteLock. */
-static void
-ssl3_InitCipherSpec(sslSocket *ss, ssl3CipherSpec *spec)
+void
+ssl3_InitCipherSpec(ssl3CipherSpec *spec)
{
- spec->cipher_def = &bulk_cipher_defs[cipher_null];
+ spec->cipher_def = &bulk_cipher_defs[cipher_null];
PORT_Assert(spec->cipher_def->cipher == cipher_null);
- spec->mac_def = &mac_defs[mac_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->encode = Null_Cipher;
+ spec->decode = Null_Cipher;
+ 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->mac_size = 0;
+ spec->master_secret = NULL;
- spec->msItem.data = NULL;
- spec->msItem.len = 0;
+ spec->msItem.data = NULL;
+ spec->msItem.len = 0;
- spec->client.write_key = NULL;
- spec->client.write_mac_key = NULL;
+ 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_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->write_seq_num = 0;
+ spec->read_seq_num = 0;
+ spec->epoch = 0;
- spec->epoch = 0;
+ spec->refCt = 128; /* Arbitrarily high number to prevent
+ * non-TLS 1.3 cipherSpecs from being
+ * GCed. This will be overwritten with
+ * a valid refCt for TLS 1.3. */
dtls_InitRecvdRecords(&spec->recvdRecords);
-
- spec->version = ss->vrange.max;
}
-/* Called from: ssl3_SendRecord
-** ssl3_StartHandshakeHash() <- ssl2_BeginClientHandshake()
-** ssl3_SendClientHello()
-** ssl3_HandleV2ClientHello()
-** ssl3_HandleRecord()
+/* Called from: ssl3_SendRecord
+** ssl3_SendClientHello()
+** ssl3_HandleV2ClientHello()
+** ssl3_HandleRecord()
**
** This function should perhaps acquire and release the SpecWriteLock.
**
**
*/
-static SECStatus
+SECStatus
ssl3_InitState(sslSocket *ss)
{
- PORT_Assert( ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss));
+ PORT_Assert(ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss));
if (ss->ssl3.initialized)
- return SECSuccess; /* Function should be idempotent */
+ return SECSuccess; /* Function should be idempotent */
ss->ssl3.policy = SSL_ALLOWED;
+ ssl_InitSecState(&ss->sec);
+
ssl_GetSpecWriteLock(ss);
ss->ssl3.crSpec = ss->ssl3.cwSpec = &ss->ssl3.specs[0];
ss->ssl3.prSpec = ss->ssl3.pwSpec = &ss->ssl3.specs[1];
+ ssl3_InitCipherSpec(ss->ssl3.crSpec);
+ ssl3_InitCipherSpec(ss->ssl3.prSpec);
+ ss->ssl3.crSpec->version = ss->ssl3.prSpec->version = ss->vrange.max;
+ ssl_ReleaseSpecWriteLock(ss);
+
ss->ssl3.hs.sendingSCSV = PR_FALSE;
- ssl3_InitCipherSpec(ss, ss->ssl3.crSpec);
- ssl3_InitCipherSpec(ss, ss->ssl3.prSpec);
ss->ssl3.hs.preliminaryInfo = 0;
-
ss->ssl3.hs.ws = (ss->sec.isServer) ? wait_client_hello : wait_server_hello;
-#ifndef NSS_DISABLE_ECC
- ss->ssl3.hs.negotiatedECCurves = ssl3_GetSupportedECCurveMask(ss);
-#endif
- ssl_ReleaseSpecWriteLock(ss);
-
- PORT_Memset(&ss->xtnData, 0, sizeof(TLSExtensionData));
+ ssl3_ResetExtensionData(&ss->xtnData);
+ PR_INIT_CLIST(&ss->ssl3.hs.remoteExtensions);
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 */
- }
+ ss->ssl3.hs.sendMessageSeq = 0;
+ ss->ssl3.hs.recvMessageSeq = 0;
+ ss->ssl3.hs.rtTimeoutMs = DTLS_RETRANSMIT_INITIAL_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 */
+ }
+
+ ss->ssl3.hs.currentSecret = NULL;
+ ss->ssl3.hs.resumptionMasterSecret = NULL;
+ ss->ssl3.hs.dheSecret = NULL;
+ ss->ssl3.hs.pskBinderKey = NULL;
+ ss->ssl3.hs.clientEarlyTrafficSecret = NULL;
+ ss->ssl3.hs.clientHsTrafficSecret = NULL;
+ ss->ssl3.hs.serverHsTrafficSecret = NULL;
+ ss->ssl3.hs.clientTrafficSecret = NULL;
+ ss->ssl3.hs.serverTrafficSecret = NULL;
+ ss->ssl3.hs.certificateRequest = NULL;
+ PR_INIT_CLIST(&ss->ssl3.hs.cipherSpecs);
PORT_Assert(!ss->ssl3.hs.messages.buf && !ss->ssl3.hs.messages.space);
ss->ssl3.hs.messages.buf = NULL;
@@ -12509,83 +12893,14 @@ ssl3_InitState(sslSocket *ss)
ss->ssl3.hs.receivedNewSessionTicket = PR_FALSE;
PORT_Memset(&ss->ssl3.hs.newSessionTicket, 0,
- sizeof(ss->ssl3.hs.newSessionTicket));
+ sizeof(ss->ssl3.hs.newSessionTicket));
- ss->ssl3.initialized = PR_TRUE;
- return SECSuccess;
-}
-
-/* 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;
+ ss->ssl3.hs.zeroRttState = ssl_0rtt_none;
- 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;
-}
+ ssl_FilterSupportedGroups(ss);
-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;
+ ss->ssl3.initialized = PR_TRUE;
+ return SECSuccess;
}
/* record the export policy for this cipher suite */
@@ -12594,9 +12909,9 @@ ssl3_SetPolicy(ssl3CipherSuite which, int policy)
{
ssl3CipherSuiteCfg *suite;
- suite = ssl_LookupCipherSuiteCfg(which, cipherSuites);
+ suite = ssl_LookupCipherSuiteCfgMutable(which, cipherSuites);
if (suite == NULL) {
- return SECFailure; /* err code was set by ssl_LookupCipherSuiteCfg */
+ return SECFailure; /* err code was set by ssl_LookupCipherSuiteCfg */
}
suite->policy = policy;
@@ -12606,17 +12921,17 @@ ssl3_SetPolicy(ssl3CipherSuite which, int policy)
SECStatus
ssl3_GetPolicy(ssl3CipherSuite which, PRInt32 *oPolicy)
{
- ssl3CipherSuiteCfg *suite;
- PRInt32 policy;
- SECStatus rv;
+ const ssl3CipherSuiteCfg *suite;
+ PRInt32 policy;
+ SECStatus rv;
suite = ssl_LookupCipherSuiteCfg(which, cipherSuites);
if (suite) {
- policy = suite->policy;
- rv = SECSuccess;
+ policy = suite->policy;
+ rv = SECSuccess;
} else {
- policy = SSL_NOT_ALLOWED;
- rv = SECFailure; /* err code was set by Lookup. */
+ policy = SSL_NOT_ALLOWED;
+ rv = SECFailure; /* err code was set by Lookup. */
}
*oPolicy = policy;
return rv;
@@ -12628,9 +12943,9 @@ ssl3_CipherPrefSetDefault(ssl3CipherSuite which, PRBool enabled)
{
ssl3CipherSuiteCfg *suite;
- suite = ssl_LookupCipherSuiteCfg(which, cipherSuites);
+ suite = ssl_LookupCipherSuiteCfgMutable(which, cipherSuites);
if (suite == NULL) {
- return SECFailure; /* err code was set by ssl_LookupCipherSuiteCfg */
+ return SECFailure; /* err code was set by ssl_LookupCipherSuiteCfg */
}
suite->enabled = enabled;
return SECSuccess;
@@ -12640,17 +12955,17 @@ ssl3_CipherPrefSetDefault(ssl3CipherSuite which, PRBool enabled)
SECStatus
ssl3_CipherPrefGetDefault(ssl3CipherSuite which, PRBool *enabled)
{
- ssl3CipherSuiteCfg *suite;
- PRBool pref;
- SECStatus rv;
+ const ssl3CipherSuiteCfg *suite;
+ PRBool pref;
+ SECStatus rv;
suite = ssl_LookupCipherSuiteCfg(which, cipherSuites);
if (suite) {
- pref = suite->enabled;
- rv = SECSuccess;
+ pref = suite->enabled;
+ rv = SECSuccess;
} else {
- pref = SSL_NOT_ALLOWED;
- rv = SECFailure; /* err code was set by Lookup. */
+ pref = SSL_NOT_ALLOWED;
+ rv = SECFailure; /* err code was set by Lookup. */
}
*enabled = pref;
return rv;
@@ -12661,67 +12976,77 @@ ssl3_CipherPrefSet(sslSocket *ss, ssl3CipherSuite which, PRBool enabled)
{
ssl3CipherSuiteCfg *suite;
- suite = ssl_LookupCipherSuiteCfg(which, ss->cipherSuites);
+ suite = ssl_LookupCipherSuiteCfgMutable(which, ss->cipherSuites);
if (suite == NULL) {
- return SECFailure; /* err code was set by ssl_LookupCipherSuiteCfg */
+ return SECFailure; /* err code was set by ssl_LookupCipherSuiteCfg */
}
suite->enabled = enabled;
return SECSuccess;
}
SECStatus
-ssl3_CipherPrefGet(sslSocket *ss, ssl3CipherSuite which, PRBool *enabled)
+ssl3_CipherPrefGet(const sslSocket *ss, ssl3CipherSuite which, PRBool *enabled)
{
- ssl3CipherSuiteCfg *suite;
- PRBool pref;
- SECStatus rv;
+ const ssl3CipherSuiteCfg *suite;
+ PRBool pref;
+ SECStatus rv;
suite = ssl_LookupCipherSuiteCfg(which, ss->cipherSuites);
if (suite) {
- pref = suite->enabled;
- rv = SECSuccess;
+ pref = suite->enabled;
+ rv = SECSuccess;
} else {
- pref = SSL_NOT_ALLOWED;
- rv = SECFailure; /* err code was set by Lookup. */
+ pref = SSL_NOT_ALLOWED;
+ rv = SECFailure; /* err code was set by Lookup. */
}
*enabled = pref;
return rv;
}
SECStatus
-SSL_SignaturePrefSet(PRFileDesc *fd, const SSLSignatureAndHashAlg *algorithms,
- unsigned int count)
+SSL_SignatureSchemePrefSet(PRFileDesc *fd, const SSLSignatureScheme *schemes,
+ unsigned int count)
{
sslSocket *ss;
unsigned int i;
+ unsigned int supported = 0;
ss = ssl_FindSocket(fd);
if (!ss) {
- SSL_DBG(("%d: SSL[%d]: bad socket in SSL_SignaturePrefSet",
+ SSL_DBG(("%d: SSL[%d]: bad socket in SSL_SignatureSchemePrefSet",
SSL_GETPID(), fd));
PORT_SetError(SEC_ERROR_INVALID_ARGS);
return SECFailure;
}
- if (!count || count > MAX_SIGNATURE_ALGORITHMS) {
+ if (!count) {
+ PORT_SetError(SEC_ERROR_INVALID_ARGS);
+ return SECFailure;
+ }
+
+ for (i = 0; i < count; ++i) {
+ if (ssl_IsSupportedSignatureScheme(schemes[i])) {
+ ++supported;
+ }
+ }
+ /* We don't check for duplicates, so it's possible to get too many. */
+ if (supported > MAX_SIGNATURE_SCHEMES) {
PORT_SetError(SEC_ERROR_INVALID_ARGS);
return SECFailure;
}
- ss->ssl3.signatureAlgorithmCount = 0;
+ ss->ssl3.signatureSchemeCount = 0;
for (i = 0; i < count; ++i) {
- if (!ssl3_IsSupportedSignatureAlgorithm(&algorithms[i])) {
- SSL_DBG(("%d: SSL[%d]: invalid signature algorithm set %d/%d",
- SSL_GETPID(), fd, algorithms[i].sigAlg,
- algorithms[i].hashAlg));
+ if (!ssl_IsSupportedSignatureScheme(schemes[i])) {
+ SSL_DBG(("%d: SSL[%d]: invalid signature scheme %d ignored",
+ SSL_GETPID(), fd, schemes[i]));
continue;
}
- ss->ssl3.signatureAlgorithms[ss->ssl3.signatureAlgorithmCount++] =
- algorithms[i];
+ ss->ssl3.signatureSchemes[ss->ssl3.signatureSchemeCount++] = schemes[i];
}
- if (ss->ssl3.signatureAlgorithmCount == 0) {
+ if (ss->ssl3.signatureSchemeCount == 0) {
PORT_SetError(SSL_ERROR_NO_SUPPORTED_SIGNATURE_ALGORITHM);
return SECFailure;
}
@@ -12729,11 +13054,51 @@ SSL_SignaturePrefSet(PRFileDesc *fd, const SSLSignatureAndHashAlg *algorithms,
}
SECStatus
+SSL_SignaturePrefSet(PRFileDesc *fd, const SSLSignatureAndHashAlg *algorithms,
+ unsigned int count)
+{
+ SSLSignatureScheme schemes[MAX_SIGNATURE_SCHEMES];
+ unsigned int i;
+
+ count = PR_MIN(PR_ARRAY_SIZE(schemes), count);
+ for (i = 0; i < count; ++i) {
+ schemes[i] = (algorithms[i].hashAlg << 8) | algorithms[i].sigAlg;
+ }
+ return SSL_SignatureSchemePrefSet(fd, schemes, count);
+}
+
+SECStatus
+SSL_SignatureSchemePrefGet(PRFileDesc *fd, SSLSignatureScheme *schemes,
+ unsigned int *count, unsigned int maxCount)
+{
+ sslSocket *ss;
+
+ ss = ssl_FindSocket(fd);
+ if (!ss) {
+ SSL_DBG(("%d: SSL[%d]: bad socket in SSL_SignatureSchemePrefGet",
+ SSL_GETPID(), fd));
+ PORT_SetError(SEC_ERROR_INVALID_ARGS);
+ return SECFailure;
+ }
+
+ if (!schemes || !count ||
+ maxCount < ss->ssl3.signatureSchemeCount) {
+ PORT_SetError(SEC_ERROR_INVALID_ARGS);
+ return SECFailure;
+ }
+
+ PORT_Memcpy(schemes, ss->ssl3.signatureSchemes,
+ ss->ssl3.signatureSchemeCount * sizeof(SSLSignatureScheme));
+ *count = ss->ssl3.signatureSchemeCount;
+ return SECSuccess;
+}
+
+SECStatus
SSL_SignaturePrefGet(PRFileDesc *fd, SSLSignatureAndHashAlg *algorithms,
unsigned int *count, unsigned int maxCount)
{
sslSocket *ss;
- unsigned int requiredSpace;
+ unsigned int i;
ss = ssl_FindSocket(fd);
if (!ss) {
@@ -12744,73 +13109,37 @@ SSL_SignaturePrefGet(PRFileDesc *fd, SSLSignatureAndHashAlg *algorithms,
}
if (!algorithms || !count ||
- maxCount < ss->ssl3.signatureAlgorithmCount) {
+ maxCount < ss->ssl3.signatureSchemeCount) {
PORT_SetError(SEC_ERROR_INVALID_ARGS);
return SECFailure;
}
- requiredSpace =
- ss->ssl3.signatureAlgorithmCount * sizeof(SSLSignatureAndHashAlg);
- PORT_Memcpy(algorithms, ss->ssl3.signatureAlgorithms, requiredSpace);
- *count = ss->ssl3.signatureAlgorithmCount;
+ for (i = 0; i < ss->ssl3.signatureSchemeCount; ++i) {
+ algorithms[i].hashAlg = (ss->ssl3.signatureSchemes[i] >> 8) & 0xff;
+ algorithms[i].sigAlg = ss->ssl3.signatureSchemes[i] & 0xff;
+ }
+ *count = ss->ssl3.signatureSchemeCount;
return SECSuccess;
}
unsigned int
-SSL_SignatureMaxCount() {
- return MAX_SIGNATURE_ALGORITHMS;
+SSL_SignatureMaxCount()
+{
+ return MAX_SIGNATURE_SCHEMES;
}
/* copy global default policy into socket. */
void
ssl3_InitSocketPolicy(sslSocket *ss)
{
- PORT_Memcpy(ss->cipherSuites, cipherSuites, sizeof cipherSuites);
- PORT_Memcpy(ss->ssl3.signatureAlgorithms, defaultSignatureAlgorithms,
- sizeof(defaultSignatureAlgorithms));
- ss->ssl3.signatureAlgorithmCount = PR_ARRAY_SIZE(defaultSignatureAlgorithms);
-}
-
-/* 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, &ss->vrange, ss)) {
- if (cs != NULL) {
- *cs++ = 0x00;
- *cs++ = (suite->cipher_suite >> 8) & 0xFF;
- *cs++ = suite->cipher_suite & 0xFF;
- }
- count++;
- }
- }
- *size = count;
- return SECSuccess;
+ PORT_Memcpy(ss->cipherSuites, cipherSuites, sizeof(cipherSuites));
+ PORT_Memcpy(ss->ssl3.signatureSchemes, defaultSignatureSchemes,
+ sizeof(defaultSignatureSchemes));
+ ss->ssl3.signatureSchemeCount = PR_ARRAY_SIZE(defaultSignatureSchemes);
}
/*
-** If ssl3 socket has completed the first handshake, and is in idle state,
+** 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.
@@ -12820,41 +13149,42 @@ ssl3_ConstructV2CipherSpecsHack(sslSocket *ss, unsigned char *cs, int *size)
SECStatus
ssl3_RedoHandshake(sslSocket *ss, PRBool flushCache)
{
- sslSessionID * sid = ss->sec.ci.sid;
- SECStatus rv;
+ sslSessionID *sid = ss->sec.ci.sid;
+ SECStatus rv;
- PORT_Assert( ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss) );
+ 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;
+ (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);
+ dtls_RehandshakeCleanup(ss);
}
- if (ss->opt.enableRenegotiation == SSL_RENEGOTIATE_NEVER) {
- PORT_SetError(SSL_ERROR_RENEGOTIATION_NOT_ALLOWED);
- return SECFailure;
+ if (ss->opt.enableRenegotiation == SSL_RENEGOTIATE_NEVER ||
+ ss->version >= SSL_LIBRARY_VERSION_TLS_1_3) {
+ 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;
+ 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); /**************************************/
+ ssl_GetXmitBufLock(ss); /**************************************/
/* start off a new handshake. */
- rv = (ss->sec.isServer) ? ssl3_SendHelloRequest(ss)
- : ssl3_SendClientHello(ss, PR_FALSE);
+ if (ss->sec.isServer) {
+ rv = ssl3_SendHelloRequest(ss);
+ } else {
+ rv = ssl3_SendClientHello(ss, client_hello_renegotiation);
+ }
- ssl_ReleaseXmitBufLock(ss); /**************************************/
+ ssl_ReleaseXmitBufLock(ss); /**************************************/
return rv;
}
@@ -12864,70 +13194,146 @@ ssl3_DestroySSL3Info(sslSocket *ss)
{
if (ss->ssl3.clientCertificate != NULL)
- CERT_DestroyCertificate(ss->ssl3.clientCertificate);
+ CERT_DestroyCertificate(ss->ssl3.clientCertificate);
if (ss->ssl3.clientPrivateKey != NULL)
- SECKEY_DestroyPrivateKey(ss->ssl3.clientPrivateKey);
+ SECKEY_DestroyPrivateKey(ss->ssl3.clientPrivateKey);
if (ss->ssl3.peerCertArena != NULL)
- ssl3_CleanupPeerCerts(ss);
+ ssl3_CleanupPeerCerts(ss);
if (ss->ssl3.clientCertChain != NULL) {
- CERT_DestroyCertificateList(ss->ssl3.clientCertChain);
- ss->ssl3.clientCertChain = NULL;
+ CERT_DestroyCertificateList(ss->ssl3.clientCertChain);
+ ss->ssl3.clientCertChain = NULL;
+ }
+ if (ss->ssl3.ca_list) {
+ CERT_FreeDistNames(ss->ssl3.ca_list);
}
/* clean up handshake */
-#ifndef NO_PKCS11_BYPASS
- if (ss->opt.bypassPKCS11) {
- if (ss->ssl3.hs.hashType == handshake_hash_combo) {
- SHA1_DestroyContext((SHA1Context *)ss->ssl3.hs.sha_cx, PR_FALSE);
- MD5_DestroyContext((MD5Context *)ss->ssl3.hs.md5_cx, PR_FALSE);
- } else if (ss->ssl3.hs.hashType == handshake_hash_single) {
- ss->ssl3.hs.sha_obj->destroy(ss->ssl3.hs.sha_cx, PR_FALSE);
- }
- }
-#endif
if (ss->ssl3.hs.md5) {
- PK11_DestroyContext(ss->ssl3.hs.md5,PR_TRUE);
+ 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.clientSigAndHash) {
- PORT_Free(ss->ssl3.hs.clientSigAndHash);
+ 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;
+ sslBuffer_Clear(&ss->ssl3.hs.messages);
}
/* free the SSL3Buffer (msg_body) */
PORT_Free(ss->ssl3.hs.msg_body.buf);
SECITEM_FreeItem(&ss->ssl3.hs.newSessionTicket.ticket, PR_FALSE);
+ SECITEM_FreeItem(&ss->ssl3.hs.srvVirtName, PR_FALSE);
+
+ if (ss->ssl3.hs.certificateRequest) {
+ PORT_FreeArena(ss->ssl3.hs.certificateRequest->arena, PR_FALSE);
+ ss->ssl3.hs.certificateRequest = NULL;
+ }
/* free up the CipherSpecs */
- ssl3_DestroyCipherSpec(&ss->ssl3.specs[0], PR_TRUE/*freeSrvName*/);
- ssl3_DestroyCipherSpec(&ss->ssl3.specs[1], PR_TRUE/*freeSrvName*/);
+ 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);
- }
+ dtls_FreeHandshakeMessages(&ss->ssl3.hs.lastMessageFlight);
+ if (ss->ssl3.hs.recvdFragments.buf) {
+ PORT_Free(ss->ssl3.hs.recvdFragments.buf);
+ }
}
- if (ss->ssl3.dheGroups) {
- PORT_Free(ss->ssl3.dheGroups);
- }
+ /* Destroy remote extensions */
+ ssl3_DestroyRemoteExtensions(&ss->ssl3.hs.remoteExtensions);
+ ssl3_ResetExtensionData(&ss->xtnData);
+
+ /* Destroy TLS 1.3 cipher specs */
+ tls13_DestroyCipherSpecs(&ss->ssl3.hs.cipherSpecs);
+
+ /* Destroy TLS 1.3 keys */
+ if (ss->ssl3.hs.currentSecret)
+ PK11_FreeSymKey(ss->ssl3.hs.currentSecret);
+ if (ss->ssl3.hs.resumptionMasterSecret)
+ PK11_FreeSymKey(ss->ssl3.hs.resumptionMasterSecret);
+ if (ss->ssl3.hs.dheSecret)
+ PK11_FreeSymKey(ss->ssl3.hs.dheSecret);
+ if (ss->ssl3.hs.pskBinderKey)
+ PK11_FreeSymKey(ss->ssl3.hs.pskBinderKey);
+ if (ss->ssl3.hs.clientEarlyTrafficSecret)
+ PK11_FreeSymKey(ss->ssl3.hs.clientEarlyTrafficSecret);
+ if (ss->ssl3.hs.clientHsTrafficSecret)
+ PK11_FreeSymKey(ss->ssl3.hs.clientHsTrafficSecret);
+ if (ss->ssl3.hs.serverHsTrafficSecret)
+ PK11_FreeSymKey(ss->ssl3.hs.serverHsTrafficSecret);
+ if (ss->ssl3.hs.clientTrafficSecret)
+ PK11_FreeSymKey(ss->ssl3.hs.clientTrafficSecret);
+ if (ss->ssl3.hs.serverTrafficSecret)
+ PK11_FreeSymKey(ss->ssl3.hs.serverTrafficSecret);
+ if (ss->ssl3.hs.earlyExporterSecret)
+ PK11_FreeSymKey(ss->ssl3.hs.earlyExporterSecret);
+ if (ss->ssl3.hs.exporterSecret)
+ PK11_FreeSymKey(ss->ssl3.hs.exporterSecret);
+
+ ss->ssl3.hs.zeroRttState = ssl_0rtt_none;
+ /* Destroy TLS 1.3 buffered early data. */
+ tls13_DestroyEarlyData(&ss->ssl3.hs.bufferedEarlyData);
ss->ssl3.initialized = PR_FALSE;
- SECITEM_FreeItem(&ss->ssl3.nextProto, PR_FALSE);
+ SECITEM_FreeItem(&ss->xtnData.nextProto, PR_FALSE);
+}
+
+#define MAP_NULL(x) (((x) != 0) ? (x) : SEC_OID_NULL_CIPHER)
+
+SECStatus
+ssl3_ApplyNSSPolicy(void)
+{
+ unsigned i;
+ SECStatus rv;
+ PRUint32 policy = 0;
+
+ rv = NSS_GetAlgorithmPolicy(SEC_OID_APPLY_SSL_POLICY, &policy);
+ if (rv != SECSuccess || !(policy & NSS_USE_POLICY_IN_SSL)) {
+ return SECSuccess; /* do nothing */
+ }
+
+ /* disable every ciphersuite */
+ for (i = 1; i < PR_ARRAY_SIZE(cipher_suite_defs); ++i) {
+ const ssl3CipherSuiteDef *suite = &cipher_suite_defs[i];
+ SECOidTag policyOid;
+
+ policyOid = MAP_NULL(kea_defs[suite->key_exchange_alg].oid);
+ rv = NSS_GetAlgorithmPolicy(policyOid, &policy);
+ if (rv == SECSuccess && !(policy & NSS_USE_ALG_IN_SSL_KX)) {
+ ssl_CipherPrefSetDefault(suite->cipher_suite, PR_FALSE);
+ ssl_CipherPolicySet(suite->cipher_suite, SSL_NOT_ALLOWED);
+ continue;
+ }
+
+ policyOid = MAP_NULL(ssl_GetBulkCipherDef(suite)->oid);
+ rv = NSS_GetAlgorithmPolicy(policyOid, &policy);
+ if (rv == SECSuccess && !(policy & NSS_USE_ALG_IN_SSL)) {
+ ssl_CipherPrefSetDefault(suite->cipher_suite, PR_FALSE);
+ ssl_CipherPolicySet(suite->cipher_suite, SSL_NOT_ALLOWED);
+ continue;
+ }
+
+ if (ssl_GetBulkCipherDef(suite)->type != type_aead) {
+ policyOid = MAP_NULL(mac_defs[suite->mac_alg].oid);
+ rv = NSS_GetAlgorithmPolicy(policyOid, &policy);
+ if (rv == SECSuccess && !(policy & NSS_USE_ALG_IN_SSL)) {
+ ssl_CipherPrefSetDefault(suite->cipher_suite, PR_FALSE);
+ ssl_CipherPolicySet(suite->cipher_suite,
+ SSL_NOT_ALLOWED);
+ continue;
+ }
+ }
+ }
+
+ rv = ssl3_ConstrainRangeByPolicy();
+
+ return rv;
}
/* End of ssl3con.c */
diff --git a/nss/lib/ssl/ssl3ecc.c b/nss/lib/ssl/ssl3ecc.c
index 94008a0..72c4ba5 100644
--- a/nss/lib/ssl/ssl3ecc.c
+++ b/nss/lib/ssl/ssl3ecc.c
@@ -8,10 +8,9 @@
/* ECC code moved here from ssl3con.c */
-#include "nss.h"
#include "cert.h"
#include "ssl.h"
-#include "cryptohi.h" /* for DSAU_ stuff */
+#include "cryptohi.h" /* for DSAU_ stuff */
#include "keyhi.h"
#include "secder.h"
#include "secitem.h"
@@ -19,6 +18,7 @@
#include "sslimpl.h"
#include "sslproto.h"
#include "sslerr.h"
+#include "ssl3ext.h"
#include "prtime.h"
#include "prinrval.h"
#include "prerror.h"
@@ -31,145 +31,36 @@
#include <stdio.h>
-#ifndef NSS_DISABLE_ECC
-
#ifndef PK11_SETATTRS
-#define PK11_SETATTRS(x,id,v,l) (x)->type = (id); \
- (x)->pValue=(v); (x)->ulValueLen = (l);
+#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(PLArenaPool * arena, ECName curve, SECKEYECParams * params)
+ssl_NamedGroup2ECParams(PLArenaPool *arena, const sslNamedGroupDef *ecGroup,
+ SECKEYECParams *params)
{
SECOidData *oidData = NULL;
- if ((curve <= ec_noName) || (curve >= ec_pastLastName) ||
- ((oidData = SECOID_FindOIDByTag(ecName2OIDTag[curve])) == NULL)) {
+ if (!params) {
+ PORT_Assert(0);
+ PORT_SetError(SEC_ERROR_INVALID_ARGS);
+ return SECFailure;
+ }
+
+ if (!ecGroup || ecGroup->keaType != ssl_kea_ecdh ||
+ (oidData = SECOID_FindOIDByTag(ecGroup->oidTag)) == NULL) {
PORT_SetError(SEC_ERROR_UNSUPPORTED_ELLIPTIC_CURVE);
return SECFailure;
}
- SECITEM_AllocItem(arena, params, (2 + oidData->oid.len));
+ if (SECITEM_AllocItem(arena, params, (2 + oidData->oid.len)) == NULL) {
+ PORT_SetError(SEC_ERROR_NO_MEMORY);
+ return SECFailure;
+ }
+
/*
* params->data needs to contain the ASN encoding of an object ID (OID)
* representing the named curve. The actual OID is in
@@ -182,28 +73,45 @@ ssl3_ECName2Params(PLArenaPool * arena, ECName curve, SECKEYECParams * params)
return SECSuccess;
}
-static ECName
-params2ecName(SECKEYECParams * params)
+const sslNamedGroupDef *
+ssl_ECPubKey2NamedGroup(const SECKEYPublicKey *pubKey)
{
- SECItem oid = { siBuffer, NULL, 0};
+ SECItem oid = { siBuffer, NULL, 0 };
SECOidData *oidData = NULL;
- ECName i;
+ PRUint32 policyFlags = 0;
+ unsigned int i;
+ const SECKEYECParams *params;
+
+ if (pubKey->keyType != ecKey) {
+ PORT_Assert(0);
+ return NULL;
+ }
+
+ params = &pubKey->u.ec.DEREncodedParams;
/*
* 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;
+ if (params->data[0] != SEC_ASN1_OBJECT_ID)
+ return NULL;
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;
+ if ((oidData = SECOID_FindOID(&oid)) == NULL)
+ return NULL;
+ if ((NSS_GetAlgorithmPolicy(oidData->offset, &policyFlags) ==
+ SECSuccess) &&
+ !(policyFlags & NSS_USE_ALG_IN_SSL_KX)) {
+ return NULL;
+ }
+ for (i = 0; i < SSL_NAMED_GROUP_COUNT; ++i) {
+ if (ssl_named_groups[i].oidTag == oidData->offset) {
+ return &ssl_named_groups[i];
+ }
}
- return ec_noName;
+ return NULL;
}
/* Caller must set hiLevel error code. */
@@ -211,21 +119,20 @@ static SECStatus
ssl3_ComputeECDHKeyHash(SSLHashType hashAlg,
SECItem ec_params, SECItem server_ecpoint,
SSL3Random *client_rand, SSL3Random *server_rand,
- SSL3Hashes *hashes, PRBool bypassPKCS11)
+ SSL3Hashes *hashes)
{
- PRUint8 * hashBuf;
- PRUint8 * pBuf;
- SECStatus rv = SECSuccess;
- unsigned int bufLen;
+ 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)
+ * 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];
+ PRUint8 buf[2 * SSL3_RANDOM_LENGTH + 2 + 1 + 256];
- bufLen = 2*SSL3_RANDOM_LENGTH + ec_params.len + 1 + server_ecpoint.len;
+ bufLen = 2 * SSL3_RANDOM_LENGTH + ec_params.len + 1 + server_ecpoint.len;
if (bufLen <= sizeof buf) {
hashBuf = buf;
} else {
@@ -236,45 +143,44 @@ ssl3_ComputeECDHKeyHash(SSLHashType hashAlg,
}
memcpy(hashBuf, client_rand, SSL3_RANDOM_LENGTH);
- pBuf = hashBuf + SSL3_RANDOM_LENGTH;
+ pBuf = hashBuf + SSL3_RANDOM_LENGTH;
memcpy(pBuf, server_rand, SSL3_RANDOM_LENGTH);
- pBuf += SSL3_RANDOM_LENGTH;
+ pBuf += SSL3_RANDOM_LENGTH;
memcpy(pBuf, ec_params.data, ec_params.len);
- pBuf += 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;
+ pBuf += server_ecpoint.len;
PORT_Assert((unsigned int)(pBuf - hashBuf) == bufLen);
- rv = ssl3_ComputeCommonKeyHash(hashAlg, hashBuf, bufLen, hashes,
- bypassPKCS11);
+ rv = ssl3_ComputeCommonKeyHash(hashAlg, hashBuf, bufLen, hashes);
PRINT_BUF(95, (NULL, "ECDHkey hash: ", hashBuf, bufLen));
PRINT_BUF(95, (NULL, "ECDHkey hash: MD5 result",
- hashes->u.s.md5, MD5_LENGTH));
+ hashes->u.s.md5, MD5_LENGTH));
PRINT_BUF(95, (NULL, "ECDHkey hash: SHA1 result",
- hashes->u.s.sha, SHA1_LENGTH));
+ hashes->u.s.sha, SHA1_LENGTH));
if (hashBuf != buf)
PORT_Free(hashBuf);
return rv;
}
-
/* Called from ssl3_SendClientKeyExchange(). */
SECStatus
-ssl3_SendECDHClientKeyExchange(sslSocket * ss, SECKEYPublicKey * svrPubKey)
+ssl3_SendECDHClientKeyExchange(sslSocket *ss, SECKEYPublicKey *svrPubKey)
{
- PK11SymKey * pms = NULL;
- SECStatus rv = SECFailure;
- PRBool isTLS, isTLS12;
- CK_MECHANISM_TYPE target;
- SECKEYPublicKey *pubKey = NULL; /* Ephemeral ECDH key */
- SECKEYPrivateKey *privKey = NULL; /* Ephemeral ECDH key */
+ PK11SymKey *pms = NULL;
+ SECStatus rv = SECFailure;
+ PRBool isTLS, isTLS12;
+ CK_MECHANISM_TYPE target;
+ const sslNamedGroupDef *groupDef;
+ sslEphemeralKeyPair *keyPair = NULL;
+ SECKEYPublicKey *pubKey;
- PORT_Assert( ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss) );
- PORT_Assert( ss->opt.noLocks || ssl_HaveXmitBufLock(ss));
+ 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);
isTLS12 = (PRBool)(ss->ssl3.pwSpec->version >= SSL_LIBRARY_VERSION_TLS_1_2);
@@ -284,17 +190,22 @@ ssl3_SendECDHClientKeyExchange(sslSocket * ss, SECKEYPublicKey * svrPubKey)
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;
+ groupDef = ssl_ECPubKey2NamedGroup(svrPubKey);
+ if (!groupDef) {
+ PORT_SetError(SEC_ERROR_BAD_KEY);
+ goto loser;
}
+ ss->sec.keaGroup = groupDef;
+ rv = ssl_CreateECDHEphemeralKeyPair(ss, groupDef, &keyPair);
+ if (rv != SECSuccess) {
+ ssl_MapLowLevelError(SEC_ERROR_KEYGEN_FAIL);
+ goto loser;
+ }
+
+ pubKey = keyPair->keys->pubKey;
PRINT_BUF(50, (ss, "ECDH public value:",
- pubKey->u.ec.publicValue.data,
- pubKey->u.ec.publicValue.len));
+ pubKey->u.ec.publicValue.data,
+ pubKey->u.ec.publicValue.len));
if (isTLS12) {
target = CKM_TLS12_MASTER_KEY_DERIVE_DH;
@@ -304,84 +215,108 @@ ssl3_SendECDHClientKeyExchange(sslSocket * ss, SECKEYPublicKey * svrPubKey)
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);
+ /* Determine the PMS */
+ pms = PK11_PubDeriveWithKDF(keyPair->keys->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);
+ (void)SSL3_SendAlert(ss, alert_fatal, illegal_parameter);
ssl_MapLowLevelError(SSL_ERROR_CLIENT_KEY_EXCHANGE_FAILURE);
goto loser;
}
- SECKEY_DestroyPrivateKey(privKey);
- privKey = NULL;
-
rv = ssl3_AppendHandshakeHeader(ss, client_key_exchange,
- pubKey->u.ec.publicValue.len + 1);
+ pubKey->u.ec.publicValue.len + 1);
if (rv != SECSuccess) {
- goto loser; /* err set by ssl3_AppendHandshake* */
+ 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;
+ rv = ssl3_AppendHandshakeVariable(ss, pubKey->u.ec.publicValue.data,
+ pubKey->u.ec.publicValue.len, 1);
if (rv != SECSuccess) {
- goto loser; /* err set by ssl3_AppendHandshake* */
+ goto loser; /* err set by ssl3_AppendHandshake* */
}
- rv = ssl3_InitPendingCipherSpec(ss, pms);
- PK11_FreeSymKey(pms); pms = NULL;
-
+ rv = ssl3_InitPendingCipherSpec(ss, pms);
if (rv != SECSuccess) {
ssl_MapLowLevelError(SSL_ERROR_CLIENT_KEY_EXCHANGE_FAILURE);
goto loser;
}
- rv = SECSuccess;
+ PK11_FreeSymKey(pms);
+ ssl_FreeEphemeralKeyPair(keyPair);
+ return SECSuccess;
loser:
- if(pms) PK11_FreeSymKey(pms);
- if(privKey) SECKEY_DestroyPrivateKey(privKey);
- if(pubKey) SECKEY_DestroyPublicKey(pubKey);
- return rv;
+ if (pms)
+ PK11_FreeSymKey(pms);
+ if (keyPair)
+ ssl_FreeEphemeralKeyPair(keyPair);
+ return SECFailure;
+}
+
+/* This function returns the size of the key_exchange field in
+ * the KeyShareEntry structure, i.e.:
+ * opaque point <1..2^8-1>; */
+unsigned int
+tls13_SizeOfECDHEKeyShareKEX(const SECKEYPublicKey *pubKey)
+{
+ PORT_Assert(pubKey->keyType == ecKey);
+ return pubKey->u.ec.publicValue.len;
}
+/* This function encodes the key_exchange field in
+ * the KeyShareEntry structure. */
+SECStatus
+tls13_EncodeECDHEKeyShareKEX(const sslSocket *ss, const SECKEYPublicKey *pubKey)
+{
+ PORT_Assert(ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss));
+ PORT_Assert(ss->opt.noLocks || ssl_HaveXmitBufLock(ss));
+ PORT_Assert(pubKey->keyType == ecKey);
+
+ return ssl3_ExtAppendHandshake(ss, pubKey->u.ec.publicValue.data,
+ pubKey->u.ec.publicValue.len);
+}
/*
** Called from ssl3_HandleClientKeyExchange()
*/
SECStatus
ssl3_HandleECDHClientKeyExchange(sslSocket *ss, SSL3Opaque *b,
- PRUint32 length,
- SECKEYPublicKey *srvrPubKey,
- SECKEYPrivateKey *srvrPrivKey)
+ PRUint32 length,
+ sslKeyPair *serverKeyPair)
{
- PK11SymKey * pms;
- SECStatus rv;
- SECKEYPublicKey clntPubKey;
- CK_MECHANISM_TYPE target;
+ PK11SymKey *pms;
+ SECStatus rv;
+ SECKEYPublicKey clntPubKey;
+ CK_MECHANISM_TYPE target;
PRBool isTLS, isTLS12;
+ int errCode = SSL_ERROR_RX_MALFORMED_CLIENT_KEY_EXCH;
- PORT_Assert( ss->opt.noLocks || ssl_HaveRecvBufLock(ss) );
- PORT_Assert( ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss) );
+ 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;
+ serverKeyPair->pubKey->u.ec.DEREncodedParams.len;
clntPubKey.u.ec.DEREncodedParams.data =
- srvrPubKey->u.ec.DEREncodedParams.data;
+ serverKeyPair->pubKey->u.ec.DEREncodedParams.data;
+ clntPubKey.u.ec.encoding = serverKeyPair->pubKey->u.ec.encoding;
rv = ssl3_ConsumeHandshakeVariable(ss, &clntPubKey.u.ec.publicValue,
1, &b, &length);
if (rv != SECSuccess) {
- SEND_ALERT
- return SECFailure; /* XXX Who sets the error code?? */
+ PORT_SetError(errCode);
+ return SECFailure;
+ }
+
+ /* we have to catch the case when the client's public key has length 0. */
+ if (!clntPubKey.u.ec.publicValue.len) {
+ (void)SSL3_SendAlert(ss, alert_fatal, illegal_parameter);
+ PORT_SetError(errCode);
+ return SECFailure;
}
isTLS = (PRBool)(ss->ssl3.prSpec->version > SSL_LIBRARY_VERSION_3_0);
@@ -396,131 +331,166 @@ ssl3_HandleECDHClientKeyExchange(sslSocket *ss, SSL3Opaque *b,
}
/* Determine the PMS */
- pms = PK11_PubDeriveWithKDF(srvrPrivKey, &clntPubKey, PR_FALSE, NULL, NULL,
- CKM_ECDH1_DERIVE, target, CKA_DERIVE, 0,
- CKD_NULL, NULL, NULL);
+ pms = PK11_PubDeriveWithKDF(serverKeyPair->privKey, &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);
+ errCode = ssl_MapLowLevelError(SSL_ERROR_CLIENT_KEY_EXCHANGE_FAILURE);
+ PORT_SetError(errCode);
return SECFailure;
}
- rv = ssl3_InitPendingCipherSpec(ss, pms);
+ rv = ssl3_InitPendingCipherSpec(ss, pms);
PK11_FreeSymKey(pms);
if (rv != SECSuccess) {
- SEND_ALERT
- return SECFailure; /* error code set by ssl3_InitPendingCipherSpec */
+ /* error code set by ssl3_InitPendingCipherSpec */
+ return SECFailure;
}
+ ss->sec.keaGroup = ssl_ECPubKey2NamedGroup(&clntPubKey);
return SECSuccess;
}
-ECName
-ssl3_GetCurveWithECKeyStrength(PRUint32 curvemsk, int requiredECCbits)
+/*
+** Take an encoded key share and make a public key out of it.
+*/
+SECStatus
+ssl_ImportECDHKeyShare(sslSocket *ss, SECKEYPublicKey *peerKey,
+ SSL3Opaque *b, PRUint32 length,
+ const sslNamedGroupDef *ecGroup)
{
- int i;
+ SECStatus rv;
+ SECItem ecPoint = { siBuffer, NULL, 0 };
- 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_Assert(ss->opt.noLocks || ssl_HaveRecvBufLock(ss));
+ PORT_Assert(ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss));
+
+ if (!length) {
+ PORT_SetError(SSL_ERROR_RX_MALFORMED_ECDHE_KEY_SHARE);
+ return SECFailure;
}
- 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;
+ /* Fail if the ec point uses compressed representation */
+ if (b[0] != EC_POINT_FORM_UNCOMPRESSED &&
+ ecGroup->name != ssl_grp_ec_curve25519) {
+ PORT_SetError(SEC_ERROR_UNSUPPORTED_EC_POINT_FORM);
+ return SECFailure;
+ }
- svrPublicKey = SSL_GET_SERVER_PUBLIC_KEY(ss, kt_rsa);
- if (!svrPublicKey) {
- PORT_SetError(SSL_ERROR_NO_CYPHER_OVERLAP);
- return ec_noName;
- }
+ peerKey->keyType = ecKey;
+ /* Set up the encoded params */
+ rv = ssl_NamedGroup2ECParams(peerKey->arena, ecGroup,
+ &peerKey->u.ec.DEREncodedParams);
+ if (rv != SECSuccess) {
+ ssl_MapLowLevelError(SSL_ERROR_RX_MALFORMED_ECDHE_KEY_SHARE);
+ return SECFailure;
+ }
+ if (ecGroup->name == ssl_grp_ec_curve25519) {
+ peerKey->u.ec.encoding = ECPoint_XOnly;
+ } else {
+ peerKey->u.ec.encoding = ECPoint_Uncompressed;
+ }
- /* 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;
+ /* copy publicValue in peerKey */
+ ecPoint.data = b;
+ ecPoint.len = length;
- signatureKeyStrength =
- SSL_RSASTRENGTH_TO_ECSTRENGTH(serverKeyStrengthInBits);
+ rv = SECITEM_CopyItem(peerKey->arena, &peerKey->u.ec.publicValue, &ecPoint);
+ if (rv != SECSuccess) {
+ return SECFailure;
}
- if ( requiredECCbits > signatureKeyStrength )
- requiredECCbits = signatureKeyStrength;
- return ssl3_GetCurveWithECKeyStrength(ss->ssl3.hs.negotiatedECCurves,
- requiredECCbits);
+ return SECSuccess;
}
-/* function to clear out the lists */
-static SECStatus
-ssl3_ShutdownECDHECurves(void *appData, void *nssData)
+const sslNamedGroupDef *
+ssl_GetECGroupWithStrength(sslSocket *ss, unsigned int requiredECCbits)
{
int i;
- ECDHEKeyPair *keyPair = &gECDHEKeyPairs[0];
- for (i=0; i < ec_pastLastName; i++, keyPair++) {
- if (keyPair->pair) {
- ssl3_FreeKeyPair(keyPair->pair);
+ PORT_Assert(ss);
+
+ for (i = 0; i < SSL_NAMED_GROUP_COUNT; ++i) {
+ const sslNamedGroupDef *group = ss->namedGroupPreferences[i];
+ if (group && group->keaType == ssl_kea_ecdh &&
+ group->bits >= requiredECCbits) {
+ return group;
}
}
- memset(gECDHEKeyPairs, 0, sizeof gECDHEKeyPairs);
- return SECSuccess;
+
+ PORT_SetError(SSL_ERROR_NO_CYPHER_OVERLAP);
+ return NULL;
}
-static PRStatus
-ssl3_ECRegister(void)
+/* Find the "weakest link". Get the strength of the signature and symmetric
+ * keys and choose a curve based on the weakest of those two. */
+const sslNamedGroupDef *
+ssl_GetECGroupForServerSocket(sslSocket *ss)
{
- SECStatus rv;
- rv = NSS_RegisterShutdown(ssl3_ShutdownECDHECurves, gECDHEKeyPairs);
- if (rv != SECSuccess) {
- gECDHEKeyPairs[ec_noName].error = PORT_GetError();
+ const sslServerCert *cert = ss->sec.serverCert;
+ unsigned int certKeySize;
+ const ssl3BulkCipherDef *bulkCipher;
+ unsigned int requiredECCbits;
+
+ PORT_Assert(cert);
+ if (!cert || !cert->serverKeyPair || !cert->serverKeyPair->pubKey) {
+ PORT_SetError(SSL_ERROR_NO_CYPHER_OVERLAP);
+ return NULL;
+ }
+
+ if (cert->certType.authType == ssl_auth_rsa_sign) {
+ certKeySize = SECKEY_PublicKeyStrengthInBits(cert->serverKeyPair->pubKey);
+ certKeySize =
+ SSL_RSASTRENGTH_TO_ECSTRENGTH(certKeySize);
+ } else if (cert->certType.authType == ssl_auth_ecdsa ||
+ cert->certType.authType == ssl_auth_ecdh_rsa ||
+ cert->certType.authType == ssl_auth_ecdh_ecdsa) {
+ const sslNamedGroupDef *groupDef = cert->certType.namedCurve;
+
+ /* We won't select a certificate unless the named curve has been
+ * negotiated (or supported_curves was absent), double check that. */
+ PORT_Assert(groupDef->keaType == ssl_kea_ecdh);
+ PORT_Assert(ssl_NamedGroupEnabled(ss, groupDef));
+ if (!ssl_NamedGroupEnabled(ss, groupDef)) {
+ return NULL;
+ }
+ certKeySize = groupDef->bits;
+ } else {
+ PORT_Assert(0);
+ return NULL;
}
- return (PRStatus)rv;
+ bulkCipher = ssl_GetBulkCipherDef(ss->ssl3.hs.suite_def);
+ requiredECCbits = bulkCipher->key_size * BPB * 2;
+ PORT_Assert(requiredECCbits ||
+ ss->ssl3.hs.suite_def->bulk_cipher_alg == cipher_null);
+ if (requiredECCbits > certKeySize) {
+ requiredECCbits = certKeySize;
+ }
+
+ return ssl_GetECGroupWithStrength(ss, requiredECCbits);
}
/* Create an ECDHE key pair for a given curve */
-static SECStatus
-ssl3_CreateECDHEphemeralKeyPair(ECName ec_curve, ssl3KeyPair** keyPair)
+SECStatus
+ssl_CreateECDHEphemeralKeyPair(const sslSocket *ss,
+ const sslNamedGroupDef *ecGroup,
+ sslEphemeralKeyPair **keyPair)
{
- SECKEYPrivateKey * privKey = NULL;
- SECKEYPublicKey * pubKey = NULL;
- SECKEYECParams ecParams = { siBuffer, NULL, 0 };
+ SECKEYPrivateKey *privKey = NULL;
+ SECKEYPublicKey *pubKey = NULL;
+ SECKEYECParams ecParams = { siBuffer, NULL, 0 };
+ sslEphemeralKeyPair *pair;
- if (ssl3_ECName2Params(NULL, ec_curve, &ecParams) != SECSuccess) {
+ if (ssl_NamedGroup2ECParams(NULL, ecGroup, &ecParams) != SECSuccess) {
return SECFailure;
}
- privKey = SECKEY_CreateECPrivateKey(&ecParams, &pubKey, NULL);
+ privKey = SECKEY_CreateECPrivateKey(&ecParams, &pubKey, ss->pkcs11PinArg);
SECITEM_FreeItem(&ecParams, PR_FALSE);
- if (!privKey || !pubKey || !(*keyPair = ssl3_NewKeyPair(privKey, pubKey))) {
+ if (!privKey || !pubKey ||
+ !(pair = ssl_NewEphemeralKeyPair(ecGroup, privKey, pubKey))) {
if (privKey) {
SECKEY_DestroyPrivateKey(privKey);
}
@@ -531,147 +501,117 @@ ssl3_CreateECDHEphemeralKeyPair(ECName ec_curve, ssl3KeyPair** keyPair)
return SECFailure;
}
- return SECSuccess;
-}
-
-/* CallOnce function, called once for each named curve. */
-static PRStatus
-ssl3_CreateECDHEphemeralKeyPairOnce(void * arg)
-{
- ECName ec_curve = (ECName)arg;
- ssl3KeyPair * keyPair = NULL;
-
- PORT_Assert(gECDHEKeyPairs[ec_curve].pair == NULL);
-
- /* ok, no one has generated a global key for this curve yet, do so */
- if (ssl3_CreateECDHEphemeralKeyPair(ec_curve, &keyPair) != SECSuccess) {
- 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_CreateECDHEphemeralKeyPairOnce,
- (void *)ec_curve);
- if (status != PR_SUCCESS) {
- PORT_SetError(gECDHEKeyPairs[ec_curve].error);
- return SECFailure;
+ *keyPair = pair;
+ SSL_TRC(50, ("%d: SSL[%d]: Create ECDH ephemeral key %d",
+ SSL_GETPID(), ss ? ss->fd : NULL, ecGroup->name));
+ PRINT_BUF(50, (ss, "Public Key", pubKey->u.ec.publicValue.data,
+ pubKey->u.ec.publicValue.len));
+#ifdef TRACE
+ if (ssl_trace >= 50) {
+ SECItem d = { siBuffer, NULL, 0 };
+ SECStatus rv = PK11_ReadRawAttribute(PK11_TypePrivKey, privKey,
+ CKA_VALUE, &d);
+ if (rv == SECSuccess) {
+ PRINT_BUF(50, (ss, "Private Key", d.data, d.len));
+ SECITEM_FreeItem(&d, PR_FALSE);
+ } else {
+ SSL_TRC(50, ("Error extracting private key"));
}
}
-
- keyPair = gECDHEKeyPairs[ec_curve].pair;
- PORT_Assert(keyPair != NULL);
- if (!keyPair)
- return SECFailure;
- ss->ephemeralECDHKeyPair = ssl3_GetKeyPairRef(keyPair);
-
+#endif
return SECSuccess;
}
SECStatus
ssl3_HandleECDHServerKeyExchange(sslSocket *ss, SSL3Opaque *b, PRUint32 length)
{
- PLArenaPool * arena = NULL;
- SECKEYPublicKey *peerKey = NULL;
- PRBool isTLS, isTLS12;
- 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 */
- SSLSignatureAndHashAlg sigAndHash;
-
- sigAndHash.hashAlg = ssl_hash_none;
+ PLArenaPool *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 };
+ SSLHashType hashAlg;
+ SSLSignatureScheme sigScheme;
+
+ SECItem ec_params = { siBuffer, NULL, 0 };
+ SECItem ec_point = { siBuffer, NULL, 0 };
+ unsigned char paramBuf[3];
+ const sslNamedGroupDef *ecGroup;
isTLS = (PRBool)(ss->ssl3.prSpec->version > SSL_LIBRARY_VERSION_3_0);
- isTLS12 = (PRBool)(ss->ssl3.prSpec->version >= SSL_LIBRARY_VERSION_TLS_1_2);
- /* XXX This works only for named curves, revisit this when
- * we support generic curves.
- */
- ec_params.len = sizeof paramBuf;
+ 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. */
+ 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;
+ if (ec_params.data[0] != ec_type_named) {
+ errCode = SEC_ERROR_UNSUPPORTED_ELLIPTIC_CURVE;
+ desc = handshake_failure;
+ goto alert_loser;
+ }
+ ecGroup = ssl_LookupNamedGroup(ec_params.data[1] << 8 | ec_params.data[2]);
+ if (!ecGroup || ecGroup->keaType != ssl_kea_ecdh) {
+ 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. */
+ 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;
+
+ /* Fail if the provided point has length 0. */
+ if (!ec_point.len) {
+ /* desc and errCode are initialized already */
+ goto alert_loser;
}
- if (isTLS12) {
- rv = ssl3_ConsumeSignatureAndHashAlgorithm(ss, &b, &length,
- &sigAndHash);
+ /* Fail if the ec point is not uncompressed for any curve that's not 25519. */
+ if (ecGroup->name != ssl_grp_ec_curve25519 &&
+ ec_point.data[0] != EC_POINT_FORM_UNCOMPRESSED) {
+ errCode = SEC_ERROR_UNSUPPORTED_EC_POINT_FORM;
+ desc = handshake_failure;
+ goto alert_loser;
+ }
+
+ PORT_Assert(ss->ssl3.prSpec->version <= SSL_LIBRARY_VERSION_TLS_1_2);
+ if (ss->ssl3.prSpec->version == SSL_LIBRARY_VERSION_TLS_1_2) {
+ rv = ssl_ConsumeSignatureScheme(ss, &b, &length, &sigScheme);
if (rv != SECSuccess) {
- goto loser; /* malformed or unsupported. */
+ goto loser; /* malformed or unsupported. */
}
- rv = ssl3_CheckSignatureAndHashAlgorithmConsistency(
- ss, &sigAndHash, ss->sec.peerCert);
+ rv = ssl_CheckSignatureSchemeConsistency(ss, sigScheme,
+ ss->sec.peerCert);
if (rv != SECSuccess) {
goto loser;
}
+ hashAlg = ssl_SignatureSchemeToHashType(sigScheme);
+ } else {
+ /* Use ssl_hash_none to represent the MD5+SHA1 combo. */
+ hashAlg = ssl_hash_none;
+ sigScheme = ssl_sig_none;
}
rv = ssl3_ConsumeHandshakeVariable(ss, &signature, 2, &b, &length);
if (rv != SECSuccess) {
- goto loser; /* malformed. */
+ goto loser; /* malformed. */
}
if (length != 0) {
if (isTLS)
desc = decode_error;
- goto alert_loser; /* malformed. */
+ goto alert_loser; /* malformed. */
}
- PRINT_BUF(60, (NULL, "Server EC params", ec_params.data,
- ec_params.len));
+ 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. */
@@ -681,19 +621,18 @@ ssl3_HandleECDHServerKeyExchange(sslSocket *ss, SSL3Opaque *b, PRUint32 length)
/*
* check to make sure the hash is signed by right guy
*/
- rv = ssl3_ComputeECDHKeyHash(sigAndHash.hashAlg, ec_params, ec_point,
+ rv = ssl3_ComputeECDHKeyHash(hashAlg, ec_params, ec_point,
&ss->ssl3.hs.client_random,
&ss->ssl3.hs.server_random,
- &hashes, ss->opt.bypassPKCS11);
+ &hashes);
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) {
+ rv = ssl3_VerifySignedHashes(ss, sigScheme, &hashes, &signature);
+ if (rv != SECSuccess) {
errCode =
ssl_MapLowLevelError(SSL_ERROR_SERVER_KEY_EXCHANGE_FAILURE);
goto alert_loser;
@@ -701,38 +640,30 @@ ssl3_HandleECDHServerKeyExchange(sslSocket *ss, SSL3Opaque *b, PRUint32 length)
arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
if (arena == NULL) {
- goto no_memory;
+ errCode = SEC_ERROR_NO_MEMORY;
+ goto loser;
}
peerKey = PORT_ArenaZNew(arena, SECKEYPublicKey);
if (peerKey == NULL) {
- goto no_memory;
+ errCode = SEC_ERROR_NO_MEMORY;
+ goto loser;
}
+ peerKey->arena = arena;
- 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;
+ /* create public key from point data */
+ rv = ssl_ImportECDHKeyShare(ss, peerKey, ec_point.data, ec_point.len,
+ ecGroup);
+ if (rv != SECSuccess) {
+ /* error code is set */
+ desc = handshake_failure;
+ errCode = PORT_GetError();
goto alert_loser;
}
-
- /* copy publicValue in peerKey */
- if (SECITEM_CopyItem(arena, &peerKey->u.ec.publicValue, &ec_point))
- {
- goto no_memory;
- }
- peerKey->pkcs11Slot = NULL;
- peerKey->pkcs11ID = CK_INVALID_HANDLE;
+ peerKey->pkcs11Slot = NULL;
+ peerKey->pkcs11ID = CK_INVALID_HANDLE;
ss->sec.peerKey = peerKey;
- ss->ssl3.hs.ws = wait_cert_request;
-
return SECSuccess;
alert_loser:
@@ -741,134 +672,117 @@ loser:
if (arena) {
PORT_FreeArena(arena, PR_FALSE);
}
- PORT_SetError( errCode );
- return SECFailure;
-
-no_memory: /* no-memory error has already been set. */
- if (arena) {
- PORT_FreeArena(arena, PR_FALSE);
- }
- ssl_MapLowLevelError(SSL_ERROR_SERVER_KEY_EXCHANGE_FAILURE);
+ PORT_SetError(errCode);
return SECFailure;
}
SECStatus
-ssl3_SendECDHServerKeyExchange(
- sslSocket *ss,
- const SSLSignatureAndHashAlg *sigAndHash)
+ssl3_SendECDHServerKeyExchange(sslSocket *ss)
{
- const ssl3KEADef * kea_def = ss->ssl3.hs.kea_def;
- SECStatus rv = SECFailure;
- int length;
- PRBool isTLS, isTLS12;
- SECItem signed_hash = {siBuffer, NULL, 0};
- SSL3Hashes hashes;
-
- SECKEYPublicKey * ecdhePub;
- SECItem ec_params = {siBuffer, NULL, 0};
- unsigned char paramBuf[3];
- ECName curve;
- SSL3KEAType certIndex;
+ SECStatus rv = SECFailure;
+ int length;
+ PRBool isTLS12;
+ SECItem signed_hash = { siBuffer, NULL, 0 };
+ SSLHashType hashAlg;
+ SSL3Hashes hashes;
+
+ SECItem ec_params = { siBuffer, NULL, 0 };
+ unsigned char paramBuf[3];
+ const sslNamedGroupDef *ecGroup;
+ sslEphemeralKeyPair *keyPair;
+ SECKEYPublicKey *pubKey;
/* Generate ephemeral ECDH key pair and send the public key */
- curve = ssl3_GetCurveNameForServerSocket(ss);
- if (curve == ec_noName) {
+ ecGroup = ssl_GetECGroupForServerSocket(ss);
+ if (!ecGroup) {
goto loser;
}
+ PORT_Assert(PR_CLIST_IS_EMPTY(&ss->ephemeralKeyPairs));
if (ss->opt.reuseServerECDHEKey) {
- rv = ssl3_CreateECDHEphemeralKeys(ss, curve);
+ rv = ssl_CreateStaticECDHEKey(ss, ecGroup);
+ if (rv != SECSuccess) {
+ goto loser;
+ }
+ keyPair = (sslEphemeralKeyPair *)PR_NEXT_LINK(&ss->ephemeralKeyPairs);
} else {
- rv = ssl3_CreateECDHEphemeralKeyPair(curve, &ss->ephemeralECDHKeyPair);
- }
- if (rv != SECSuccess) {
- goto loser;
+ rv = ssl_CreateECDHEphemeralKeyPair(ss, ecGroup, &keyPair);
+ if (rv != SECSuccess) {
+ goto loser;
+ }
+ PR_APPEND_LINK(&keyPair->link, &ss->ephemeralKeyPairs);
}
- ecdhePub = ss->ephemeralECDHKeyPair->pubKey;
- PORT_Assert(ecdhePub != NULL);
- if (!ecdhePub) {
+ PORT_Assert(keyPair);
+ if (!keyPair) {
PORT_SetError(SSL_ERROR_SERVER_KEY_EXCHANGE_FAILURE);
return SECFailure;
}
- ec_params.len = sizeof paramBuf;
+ 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;
+ PORT_Assert(keyPair->group);
+ PORT_Assert(keyPair->group->keaType == ssl_kea_ecdh);
+ ec_params.data[0] = ec_type_named;
+ ec_params.data[1] = keyPair->group->name >> 8;
+ ec_params.data[2] = keyPair->group->name & 0xff;
+
+ pubKey = keyPair->keys->pubKey;
+ if (ss->ssl3.pwSpec->version == SSL_LIBRARY_VERSION_TLS_1_2) {
+ hashAlg = ssl_SignatureSchemeToHashType(ss->ssl3.hs.signatureScheme);
} else {
- PORT_SetError(SEC_ERROR_UNSUPPORTED_ELLIPTIC_CURVE);
- goto loser;
+ /* Use ssl_hash_none to represent the MD5+SHA1 combo. */
+ hashAlg = ssl_hash_none;
}
-
- rv = ssl3_ComputeECDHKeyHash(sigAndHash->hashAlg,
- ec_params,
- ecdhePub->u.ec.publicValue,
+ rv = ssl3_ComputeECDHKeyHash(hashAlg, ec_params,
+ pubKey->u.ec.publicValue,
&ss->ssl3.hs.client_random,
&ss->ssl3.hs.server_random,
- &hashes, ss->opt.bypassPKCS11);
+ &hashes);
if (rv != SECSuccess) {
ssl_MapLowLevelError(SSL_ERROR_SERVER_KEY_EXCHANGE_FAILURE);
goto loser;
}
- isTLS = (PRBool)(ss->ssl3.pwSpec->version > SSL_LIBRARY_VERSION_3_0);
isTLS12 = (PRBool)(ss->ssl3.pwSpec->version >= SSL_LIBRARY_VERSION_TLS_1_2);
- /* 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);
+ rv = ssl3_SignHashes(ss, &hashes,
+ ss->sec.serverCert->serverKeyPair->privKey, &signed_hash);
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;
+ goto loser; /* ssl3_SignHashes has set err. */
}
length = ec_params.len +
- 1 + ecdhePub->u.ec.publicValue.len +
+ 1 + pubKey->u.ec.publicValue.len +
(isTLS12 ? 2 : 0) + 2 + signed_hash.len;
rv = ssl3_AppendHandshakeHeader(ss, server_key_exchange, length);
if (rv != SECSuccess) {
- goto loser; /* err set by AppendHandshake. */
+ 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. */
+ goto loser; /* err set by AppendHandshake. */
}
- rv = ssl3_AppendHandshakeVariable(ss, ecdhePub->u.ec.publicValue.data,
- ecdhePub->u.ec.publicValue.len, 1);
+ rv = ssl3_AppendHandshakeVariable(ss, pubKey->u.ec.publicValue.data,
+ pubKey->u.ec.publicValue.len, 1);
if (rv != SECSuccess) {
- goto loser; /* err set by AppendHandshake. */
+ goto loser; /* err set by AppendHandshake. */
}
if (isTLS12) {
- rv = ssl3_AppendSignatureAndHashAlgorithm(ss, sigAndHash);
+ rv = ssl3_AppendHandshakeNumber(ss, ss->ssl3.hs.signatureScheme, 2);
if (rv != SECSuccess) {
- goto loser; /* err set by AppendHandshake. */
+ 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. */
+ goto loser; /* err set by AppendHandshake. */
}
PORT_Free(signed_hash.data);
@@ -880,76 +794,26 @@ loser:
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_128_CBC_SHA256,
- TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,
- 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_128_CBC_SHA256,
- TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
- 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[] = {
+static const ssl3CipherSuite ssl_all_ec_suites[] = {
TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA,
TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA,
TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256,
TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,
TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA,
+ TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256,
TLS_ECDHE_ECDSA_WITH_NULL_SHA,
TLS_ECDHE_ECDSA_WITH_RC4_128_SHA,
+ TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384,
+ TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,
TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA,
TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA,
TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256,
TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
+ TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,
TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA,
+ TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384,
+ TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256,
TLS_ECDHE_RSA_WITH_NULL_SHA,
TLS_ECDHE_RSA_WITH_RC4_128_SHA,
TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA,
@@ -965,195 +829,151 @@ static const ssl3CipherSuite ecSuites[] = {
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) {
- PORT_CheckSuccess(ssl3_CipherPrefSet(ss, *suite, PR_FALSE));
- }
- return SECSuccess;
-}
+static const ssl3CipherSuite ssl_dhe_suites[] = {
+ TLS_DHE_RSA_WITH_AES_128_GCM_SHA256,
+ TLS_DHE_RSA_WITH_AES_256_GCM_SHA384,
+ TLS_DHE_RSA_WITH_CHACHA20_POLY1305_SHA256,
+ TLS_DHE_DSS_WITH_AES_128_GCM_SHA256,
+ TLS_DHE_RSA_WITH_AES_128_CBC_SHA,
+ TLS_DHE_DSS_WITH_AES_128_CBC_SHA,
+ TLS_DHE_RSA_WITH_AES_128_CBC_SHA256,
+ TLS_DHE_DSS_WITH_AES_128_CBC_SHA256,
+ TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA,
+ TLS_DHE_DSS_WITH_CAMELLIA_128_CBC_SHA,
+ TLS_DHE_RSA_WITH_AES_256_CBC_SHA,
+ TLS_DHE_DSS_WITH_AES_256_CBC_SHA,
+ TLS_DHE_RSA_WITH_AES_256_CBC_SHA256,
+ TLS_DHE_DSS_WITH_AES_256_CBC_SHA256,
+ TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA,
+ TLS_DHE_DSS_WITH_CAMELLIA_256_CBC_SHA,
+ TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA,
+ TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA,
+ TLS_DHE_DSS_WITH_RC4_128_SHA,
+ TLS_DHE_RSA_WITH_DES_CBC_SHA,
+ TLS_DHE_DSS_WITH_DES_CBC_SHA,
+ 0
+};
-/* 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)
+/* Order(N^2). Yuk. */
+static PRBool
+ssl_IsSuiteEnabled(const sslSocket *ss, const ssl3CipherSuite *list)
{
- CERTCertificate * svrCert;
+ const ssl3CipherSuite *suite;
- svrCert = ss->serverCerts[kt_rsa].serverCert;
- if (!svrCert) {
- ssl3_DisableECCSuites(ss, ecdhe_rsa_suites);
- }
+ for (suite = list; *suite; ++suite) {
+ PRBool enabled = PR_FALSE;
+ SECStatus rv = ssl3_CipherPrefGet(ss, *suite, &enabled);
- 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;
- }
+ PORT_Assert(rv == SECSuccess); /* else is coding error */
+ if (rv == SECSuccess && enabled)
+ return PR_TRUE;
}
+ return PR_FALSE;
}
/* Ask: is ANY ECC cipher suite enabled on this socket? */
-/* Order(N^2). Yuk. Also, this ignores export policy. */
PRBool
-ssl3_IsECCEnabled(sslSocket * ss)
+ssl_IsECCEnabled(const sslSocket *ss)
{
- const ssl3CipherSuite * suite;
PK11SlotInfo *slot;
/* make sure we can do ECC */
- slot = PK11_GetBestSlot(CKM_ECDH1_DERIVE, ss->pkcs11PinArg);
+ slot = PK11_GetBestSlot(CKM_ECDH1_DERIVE, ss->pkcs11PinArg);
if (!slot) {
return PR_FALSE;
}
PK11_FreeSlot(slot);
/* make sure an ECC cipher is enabled */
- 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;
+ return ssl_IsSuiteEnabled(ss, ssl_all_ec_suites);
}
-#define BE(n) 0, n
-
-/* Prefabricated TLS client hello extension, Elliptic Curves List,
- * offers only 3 curves, the Suite B curves, 23-25
- */
-static const PRUint8 suiteBECList[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)
-};
-
-/* Prefabricated TLS client hello extension, Elliptic Curves List,
- * offers curves 1-25.
- */
-static const PRUint8 tlsECList[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)
-};
-
-static const PRUint8 ecPtFmt[6] = {
- BE(11), /* Extension type */
- BE( 2), /* octets that follow */
- 1, /* octets that follow */
- 0 /* uncompressed type only */
-};
-
-/* This function already presumes we can do ECC, ssl3_IsECCEnabled must be
- * called before this function. It looks to see if we have a token which
- * is capable of doing smaller than SuiteB curves. If the token can, we
- * presume the token can do the whole SSL suite of curves. If it can't we
- * presume the token that allowed ECC to be enabled can only do suite B
- * curves. */
-static PRBool
-ssl3_SuiteBOnly(sslSocket *ss)
+PRBool
+ssl_IsDHEEnabled(const sslSocket *ss)
{
- /* See if we can support small curves (like 163). If not, assume we can
- * only support Suite-B curves (P-256, P-384, P-521). */
- PK11SlotInfo *slot =
- PK11_GetBestSlotWithAttributes(CKM_ECDH1_DERIVE, 0, 163,
- ss ? ss->pkcs11PinArg : NULL);
-
- if (!slot) {
- /* nope, presume we can only do suite B */
- return PR_TRUE;
- }
- /* we can, presume we can do all curves */
- PK11_FreeSlot(slot);
- return PR_FALSE;
+ return ssl_IsSuiteEnabled(ss, ssl_dhe_suites);
}
-/* Send our "canned" (precompiled) Supported Elliptic Curves extension,
- * which says that we support all TLS-defined named curves.
- */
+/* Send our Supported Groups extension. */
PRInt32
-ssl3_SendSupportedCurvesXtn(
- sslSocket * ss,
- PRBool append,
- PRUint32 maxBytes)
+ssl_SendSupportedGroupsXtn(const sslSocket *ss,
+ TLSExtensionData *xtnData,
+ PRBool append, PRUint32 maxBytes)
{
- PRInt32 ecListSize = 0;
- const PRUint8 *ecList = NULL;
-
- if (!ss || !ssl3_IsECCEnabled(ss))
+ PRInt32 extension_length;
+ unsigned char enabledGroups[64];
+ unsigned int enabledGroupsLen = 0;
+ unsigned int i;
+ PRBool ec;
+ PRBool ff = PR_FALSE;
+
+ if (!ss)
return 0;
- if (ssl3_SuiteBOnly(ss)) {
- ecListSize = sizeof suiteBECList;
- ecList = suiteBECList;
+ /* We only send FF supported groups if we require DH named groups
+ * or if TLS 1.3 is a possibility. */
+ if (ss->vrange.max < SSL_LIBRARY_VERSION_TLS_1_3) {
+ ec = ssl_IsECCEnabled(ss);
+ if (ss->opt.requireDHENamedGroups) {
+ ff = ssl_IsDHEEnabled(ss);
+ }
+ if (!ec && !ff)
+ return 0;
} else {
- ecListSize = sizeof tlsECList;
- ecList = tlsECList;
+ ec = ff = PR_TRUE;
+ }
+
+ PORT_Assert(sizeof(enabledGroups) > SSL_NAMED_GROUP_COUNT * 2);
+ for (i = 0; i < SSL_NAMED_GROUP_COUNT; ++i) {
+ const sslNamedGroupDef *group = ss->namedGroupPreferences[i];
+ if (!group) {
+ continue;
+ }
+ if (group->keaType == ssl_kea_ecdh && !ec) {
+ continue;
+ }
+ if (group->keaType == ssl_kea_dh && !ff) {
+ continue;
+ }
+
+ if (append) {
+ (void)ssl_EncodeUintX(group->name, 2, &enabledGroups[enabledGroupsLen]);
+ }
+ enabledGroupsLen += 2;
+ }
+
+ if (enabledGroupsLen == 0) {
+ return 0;
}
- if (maxBytes < (PRUint32)ecListSize) {
+ extension_length =
+ 2 /* extension type */ +
+ 2 /* extension length */ +
+ 2 /* enabled groups length */ +
+ enabledGroupsLen;
+
+ if (maxBytes < (PRUint32)extension_length) {
return 0;
}
+
if (append) {
- SECStatus rv = ssl3_AppendHandshake(ss, ecList, ecListSize);
+ SECStatus rv;
+ rv = ssl3_ExtAppendHandshakeNumber(ss, ssl_supported_groups_xtn, 2);
+ if (rv != SECSuccess)
+ return -1;
+ rv = ssl3_ExtAppendHandshakeNumber(ss, extension_length - 4, 2);
+ if (rv != SECSuccess)
+ return -1;
+ rv = ssl3_ExtAppendHandshakeVariable(ss, enabledGroups,
+ enabledGroupsLen, 2);
if (rv != SECSuccess)
return -1;
if (!ss->sec.isServer) {
- TLSExtensionData *xtnData = &ss->xtnData;
xtnData->advertised[xtnData->numAdvertised++] =
- ssl_elliptic_curves_xtn;
+ ssl_supported_groups_xtn;
}
}
- return ecListSize;
-}
-
-PRUint32
-ssl3_GetSupportedECCurveMask(sslSocket *ss)
-{
- if (ssl3_SuiteBOnly(ss)) {
- return SSL3_SUITE_B_SUPPORTED_CURVES_MASK;
- }
- return SSL3_ALL_SUPPORTED_CURVES_MASK;
+ return extension_length;
}
/* Send our "canned" (precompiled) Supported Point Formats extension,
@@ -1161,126 +981,33 @@ ssl3_GetSupportedECCurveMask(sslSocket *ss)
*/
PRInt32
ssl3_SendSupportedPointFormatsXtn(
- sslSocket * ss,
- PRBool append,
- PRUint32 maxBytes)
+ const sslSocket *ss,
+ TLSExtensionData *xtnData,
+ PRBool append,
+ PRUint32 maxBytes)
{
- if (!ss || !ssl3_IsECCEnabled(ss))
+ static const PRUint8 ecPtFmt[6] = {
+ 0, 11, /* Extension type */
+ 0, 2, /* octets that follow */
+ 1, /* octets that follow */
+ 0 /* uncompressed type only */
+ };
+
+ /* No point in doing this unless we have a socket that supports ECC.
+ * Similarly, no point if we are going to do TLS 1.3 only or we have already
+ * picked TLS 1.3 (server) given that it doesn't use point formats. */
+ if (!ss || !ssl_IsECCEnabled(ss) ||
+ ss->vrange.min >= SSL_LIBRARY_VERSION_TLS_1_3 ||
+ (ss->sec.isServer && ss->version >= SSL_LIBRARY_VERSION_TLS_1_3))
return 0;
if (append && maxBytes >= (sizeof ecPtFmt)) {
- SECStatus rv = ssl3_AppendHandshake(ss, ecPtFmt, (sizeof ecPtFmt));
+ SECStatus rv = ssl3_ExtAppendHandshake(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) {
- return ssl3_DecodeError(ss);
- }
- 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;
- }
- }
-
- /* evil client doesn't support uncompressed */
- ssl3_DisableECCSuites(ss, ecSuites);
- return SECSuccess;
-}
-
-
-#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 supported
- * 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) {
- (void)ssl3_DecodeError(ss);
- return SECFailure;
- }
-
- /* 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) {
- (void)ssl3_DecodeError(ss);
- return SECFailure;
- }
- /* 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 < 0) {
- return SECFailure; /* fatal alert already sent */
- }
- 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, disable ECC */
- ssl3_DisableECCSuites(ss, ecSuites);
- return SECSuccess;
- }
-
- /* 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 SECSuccess;
+ return sizeof(ecPtFmt);
}
-
-#endif /* NSS_DISABLE_ECC */
diff --git a/nss/lib/ssl/ssl3ext.c b/nss/lib/ssl/ssl3ext.c
index cf04aba..0da41be 100644
--- a/nss/lib/ssl/ssl3ext.c
+++ b/nss/lib/ssl/ssl3ext.c
@@ -11,308 +11,123 @@
#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_ClientHandleAppProtoXtn(sslSocket *ss,
- PRUint16 ex_type, SECItem *data);
-static SECStatus ssl3_ServerHandleNextProtoNegoXtn(sslSocket *ss,
- PRUint16 ex_type, SECItem *data);
-static SECStatus ssl3_ServerHandleAppProtoXtn(sslSocket *ss, PRUint16 ex_type,
- SECItem *data);
-static PRInt32 ssl3_ClientSendNextProtoNegoXtn(sslSocket *ss, PRBool append,
- PRUint32 maxBytes);
-static PRInt32 ssl3_ClientSendAppProtoXtn(sslSocket *ss, PRBool append,
- PRUint32 maxBytes);
-static PRInt32 ssl3_ServerSendAppProtoXtn(sslSocket *ss, PRBool append,
- PRUint32 maxBytes);
-static PRInt32 ssl3_ClientSendUseSRTPXtn(sslSocket *ss, PRBool append,
- PRUint32 maxBytes);
-static PRInt32 ssl3_ServerSendUseSRTPXtn(sslSocket *ss, PRBool append,
- PRUint32 maxBytes);
-static SECStatus ssl3_ClientHandleUseSRTPXtn(sslSocket * ss, PRUint16 ex_type,
- SECItem *data);
-static SECStatus ssl3_ServerHandleUseSRTPXtn(sslSocket * ss, PRUint16 ex_type,
- SECItem *data);
-static PRInt32 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);
-static PRInt32 ssl3_ClientSendSigAlgsXtn(sslSocket *ss, PRBool append,
- PRUint32 maxBytes);
-static SECStatus ssl3_ServerHandleSigAlgsXtn(sslSocket *ss, PRUint16 ex_type,
- SECItem *data);
-
-static PRInt32 ssl3_ClientSendDraftVersionXtn(sslSocket *ss, PRBool append,
- PRUint32 maxBytes);
-static SECStatus ssl3_ServerHandleDraftVersionXtn(sslSocket *ss, PRUint16 ex_type,
- SECItem *data);
-static PRInt32 ssl3_SendExtendedMasterSecretXtn(sslSocket *ss, PRBool append,
- PRUint32 maxBytes);
-static SECStatus ssl3_HandleExtendedMasterSecretXtn(sslSocket *ss,
- PRUint16 ex_type,
- SECItem *data);
-
-
-/*
- * 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;
- PRUint8 b[4];
- PRUint8 * p = b;
-
- switch (lenSize) {
- case 4:
- *p++ = (PRUint8) (num >> 24);
- case 3:
- *p++ = (PRUint8) (num >> 16);
- case 2:
- *p++ = (PRUint8) (num >> 8);
- case 1:
- *p = (PRUint8) 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) != PR_SUCCESS)
- 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
+#include "sslproto.h"
+#include "ssl3exthandle.h"
+#include "tls13exthandle.h"
/* 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 },
-#ifndef NSS_DISABLE_ECC
- { ssl_elliptic_curves_xtn, &ssl3_HandleSupportedCurvesXtn },
- { ssl_ec_point_formats_xtn, &ssl3_HandleSupportedPointFormatsXtn },
-#endif
- { ssl_session_ticket_xtn, &ssl3_ServerHandleSessionTicketXtn },
+static const ssl3ExtensionHandler clientHelloHandlers[] = {
+ { ssl_server_name_xtn, &ssl3_HandleServerNameXtn },
+ { ssl_supported_groups_xtn, &ssl_HandleSupportedGroupsXtn },
+ { ssl_ec_point_formats_xtn, &ssl3_HandleSupportedPointFormatsXtn },
+ { ssl_session_ticket_xtn, &ssl3_ServerHandleSessionTicketXtn },
{ ssl_renegotiation_info_xtn, &ssl3_HandleRenegotiationInfoXtn },
- { ssl_next_proto_nego_xtn, &ssl3_ServerHandleNextProtoNegoXtn },
+ { ssl_next_proto_nego_xtn, &ssl3_ServerHandleNextProtoNegoXtn },
{ ssl_app_layer_protocol_xtn, &ssl3_ServerHandleAppProtoXtn },
- { ssl_use_srtp_xtn, &ssl3_ServerHandleUseSRTPXtn },
- { ssl_cert_status_xtn, &ssl3_ServerHandleStatusRequestXtn },
+ { ssl_use_srtp_xtn, &ssl3_ServerHandleUseSRTPXtn },
+ { ssl_cert_status_xtn, &ssl3_ServerHandleStatusRequestXtn },
{ ssl_signature_algorithms_xtn, &ssl3_ServerHandleSigAlgsXtn },
- { ssl_tls13_draft_version_xtn, &ssl3_ServerHandleDraftVersionXtn },
{ ssl_extended_master_secret_xtn, &ssl3_HandleExtendedMasterSecretXtn },
+ { ssl_signed_cert_timestamp_xtn, &ssl3_ServerHandleSignedCertTimestampXtn },
+ { ssl_tls13_key_share_xtn, &tls13_ServerHandleKeyShareXtn },
+ { ssl_tls13_pre_shared_key_xtn, &tls13_ServerHandlePreSharedKeyXtn },
+ { ssl_tls13_early_data_xtn, &tls13_ServerHandleEarlyDataXtn },
+ { ssl_tls13_psk_key_exchange_modes_xtn,
+ &tls13_ServerHandlePskKeyExchangeModesXtn },
+ { ssl_tls13_short_header_xtn, &tls13_HandleShortHeaderXtn },
{ -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 },
+static const ssl3ExtensionHandler serverHelloHandlersTLS[] = {
+ { ssl_server_name_xtn, &ssl3_HandleServerNameXtn },
/* TODO: add a handler for ssl_ec_point_formats_xtn */
- { ssl_session_ticket_xtn, &ssl3_ClientHandleSessionTicketXtn },
+ { ssl_session_ticket_xtn, &ssl3_ClientHandleSessionTicketXtn },
{ ssl_renegotiation_info_xtn, &ssl3_HandleRenegotiationInfoXtn },
- { ssl_next_proto_nego_xtn, &ssl3_ClientHandleNextProtoNegoXtn },
+ { ssl_next_proto_nego_xtn, &ssl3_ClientHandleNextProtoNegoXtn },
{ ssl_app_layer_protocol_xtn, &ssl3_ClientHandleAppProtoXtn },
- { ssl_use_srtp_xtn, &ssl3_ClientHandleUseSRTPXtn },
- { ssl_cert_status_xtn, &ssl3_ClientHandleStatusRequestXtn },
+ { ssl_use_srtp_xtn, &ssl3_ClientHandleUseSRTPXtn },
+ { ssl_cert_status_xtn, &ssl3_ClientHandleStatusRequestXtn },
{ ssl_extended_master_secret_xtn, &ssl3_HandleExtendedMasterSecretXtn },
+ { ssl_signed_cert_timestamp_xtn, &ssl3_ClientHandleSignedCertTimestampXtn },
+ { ssl_tls13_key_share_xtn, &tls13_ClientHandleKeyShareXtn },
+ { ssl_tls13_pre_shared_key_xtn, &tls13_ClientHandlePreSharedKeyXtn },
+ { ssl_tls13_early_data_xtn, &tls13_ClientHandleEarlyDataXtn },
+ { ssl_tls13_short_header_xtn, &tls13_HandleShortHeaderXtn },
{ -1, NULL }
};
-static const ssl3HelloExtensionHandler serverHelloHandlersSSL3[] = {
+static const ssl3ExtensionHandler helloRetryRequestHandlers[] = {
+ { ssl_tls13_key_share_xtn, tls13_ClientHandleKeyShareXtnHrr },
+ { ssl_tls13_cookie_xtn, tls13_ClientHandleHrrCookie },
+ { -1, NULL }
+};
+
+static const ssl3ExtensionHandler serverHelloHandlersSSL3[] = {
{ ssl_renegotiation_info_xtn, &ssl3_HandleRenegotiationInfoXtn },
{ -1, NULL }
};
+static const ssl3ExtensionHandler newSessionTicketHandlers[] = {
+ { ssl_tls13_ticket_early_data_info_xtn,
+ &tls13_ClientHandleTicketEarlyDataInfoXtn },
+ { -1, NULL }
+};
+
+/* This table is used by the client to handle server certificates in TLS 1.3 */
+static const ssl3ExtensionHandler serverCertificateHandlers[] = {
+ { ssl_signed_cert_timestamp_xtn, &ssl3_ClientHandleSignedCertTimestampXtn },
+ { ssl_cert_status_xtn, &ssl3_ClientHandleStatusRequestXtn },
+ { -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.
+ * NB: the order of these extensions can have an impact on compatibility. Some
+ * servers (e.g. Tomcat) will terminate the connection if the last extension in
+ * the client hello is empty (for example, the extended master secret
+ * extension, if it were listed last). See bug 1243641.
*/
-static const
-ssl3HelloExtensionSender clientHelloSendersTLS[SSL_MAX_EXTENSIONS] = {
- { ssl_server_name_xtn, &ssl3_SendServerNameXtn },
- { ssl_renegotiation_info_xtn, &ssl3_SendRenegotiationInfoXtn },
-#ifndef NSS_DISABLE_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_app_layer_protocol_xtn, &ssl3_ClientSendAppProtoXtn },
- { ssl_use_srtp_xtn, &ssl3_ClientSendUseSRTPXtn },
- { ssl_cert_status_xtn, &ssl3_ClientSendStatusRequestXtn },
- { ssl_signature_algorithms_xtn, &ssl3_ClientSendSigAlgsXtn },
- { ssl_tls13_draft_version_xtn, &ssl3_ClientSendDraftVersionXtn },
- { ssl_extended_master_secret_xtn, &ssl3_SendExtendedMasterSecretXtn},
- /* any extra entries will appear as { 0, NULL } */
-};
-
-static const
-ssl3HelloExtensionSender clientHelloSendersSSL3[SSL_MAX_EXTENSIONS] = {
+static const ssl3HelloExtensionSender clientHelloSendersTLS[SSL_MAX_EXTENSIONS] =
+ {
+ { ssl_server_name_xtn, &ssl3_SendServerNameXtn },
+ { ssl_extended_master_secret_xtn, &ssl3_SendExtendedMasterSecretXtn },
+ { ssl_renegotiation_info_xtn, &ssl3_SendRenegotiationInfoXtn },
+ { ssl_supported_groups_xtn, &ssl_SendSupportedGroupsXtn },
+ { ssl_ec_point_formats_xtn, &ssl3_SendSupportedPointFormatsXtn },
+ { ssl_session_ticket_xtn, &ssl3_SendSessionTicketXtn },
+ { ssl_next_proto_nego_xtn, &ssl3_ClientSendNextProtoNegoXtn },
+ { ssl_app_layer_protocol_xtn, &ssl3_ClientSendAppProtoXtn },
+ { ssl_use_srtp_xtn, &ssl3_ClientSendUseSRTPXtn },
+ { ssl_cert_status_xtn, &ssl3_ClientSendStatusRequestXtn },
+ { ssl_signed_cert_timestamp_xtn, &ssl3_ClientSendSignedCertTimestampXtn },
+ { ssl_tls13_key_share_xtn, &tls13_ClientSendKeyShareXtn },
+ { ssl_tls13_early_data_xtn, &tls13_ClientSendEarlyDataXtn },
+ /* Some servers (e.g. WebSphere Application Server 7.0 and Tomcat) will
+ * time out or terminate the connection if the last extension in the
+ * client hello is empty. They are not intolerant of TLS 1.2, so list
+ * signature_algorithms at the end. See bug 1243641. */
+ { ssl_tls13_supported_versions_xtn, &tls13_ClientSendSupportedVersionsXtn },
+ { ssl_tls13_short_header_xtn, &tls13_SendShortHeaderXtn },
+ { ssl_signature_algorithms_xtn, &ssl3_ClientSendSigAlgsXtn },
+ { ssl_tls13_cookie_xtn, &tls13_ClientSendHrrCookieXtn },
+ { ssl_tls13_psk_key_exchange_modes_xtn,
+ &tls13_ClientSendPskKeyExchangeModesXtn },
+ /* The pre_shared_key extension MUST be last. */
+ { ssl_tls13_pre_shared_key_xtn, &tls13_ClientSendPreSharedKeyXtn },
+ /* 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 } */
};
@@ -329,1638 +144,193 @@ arrayContainsExtension(const PRUint16 *array, PRUint32 len, PRUint16 ex_type)
}
PRBool
-ssl3_ExtensionNegotiated(sslSocket *ss, PRUint16 ex_type) {
- TLSExtensionData *xtnData = &ss->xtnData;
+ssl3_ExtensionNegotiated(const sslSocket *ss, PRUint16 ex_type)
+{
+ const 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;
+PRBool
+ssl3_ClientExtensionAdvertised(const sslSocket *ss, PRUint16 ex_type)
+{
+ const 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.
+/* Go through hello extensions in |b| and deserialize
+ * them into the list in |ss->ssl3.hs.remoteExtensions|.
+ * The only checking we do in this point is for duplicates.
+ *
+ * IMPORTANT: This list just contains pointers to the incoming
+ * buffer so they can only be used during ClientHello processing.
*/
-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)
+ssl3_ParseExtensions(sslSocket *ss, SSL3Opaque **b, PRUint32 *length)
{
- SECItem *names = NULL;
- PRUint32 listCount = 0, namesPos = 0, i;
- TLSExtensionData *xtnData = &ss->xtnData;
- SECItem ldata;
- PRInt32 listLenBytes = 0;
-
- if (!ss->sec.isServer) {
- return SECSuccess; /* ignore extension */
- }
-
- /* 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) {
- return SECFailure;
- }
- if (listLenBytes == 0 || listLenBytes != data->len) {
- (void)ssl3_DecodeError(ss);
- return SECFailure;
- }
- ldata = *data;
- /* Calculate the size of the array.*/
- while (listLenBytes > 0) {
- SECItem litem;
- SECStatus rv;
- PRInt32 type;
- /* Skip Name Type (sni_host_name); checks are on the second pass */
- type = ssl3_ConsumeHandshakeNumber(ss, 1, &ldata.data, &ldata.len);
- if (type < 0) { /* i.e., SECFailure cast to PRint32 */
- return SECFailure;
- }
- rv = ssl3_ConsumeHandshakeVariable(ss, &litem, 2, &ldata.data, &ldata.len);
- if (rv != SECSuccess) {
- return rv;
- }
- /* Adjust total length for consumed item, item len and type.*/
- listLenBytes -= litem.len + 3;
- if (listLenBytes > 0 && !ldata.len) {
- (void)ssl3_DecodeError(ss);
- return SECFailure;
- }
- listCount += 1;
- }
- names = PORT_ZNewArray(SECItem, listCount);
- if (!names) {
- return SECFailure;
- }
- for (i = 0;i < listCount;i++) {
- unsigned 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++) {
- /* TODO bug 998524: .type is not assigned a value */
- 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) {
- PORT_Assert(0);
- PORT_Free(names);
- PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
- return rv;
- }
- 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;
-}
-
-/* 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;
- sslSessionID *sid = ss->sec.ci.sid;
-
- /* 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) {
- /* The caller must be holding sid->u.ssl3.lock for reading. We cannot
- * just acquire and release the lock within this function because the
- * caller will call this function twice, and we need the inputs to be
- * consistent between the two calls. Note that currently the caller
- * will only be holding the lock when we are the client and when we're
- * attempting to resume an existing session.
- */
-
- session_ticket = &sid->u.ssl3.locked.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;
- }
- }
- }
+ /* Clean out the extensions list. */
+ ssl3_DestroyRemoteExtensions(&ss->ssl3.hs.remoteExtensions);
- if (maxBytes < (PRUint32)extension_length) {
- PORT_Assert(0);
- return 0;
- }
- if (append) {
+ while (*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;
- ss->xtnData.sentSessionTicketInClientHello = PR_TRUE;
- } 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;
- }
- }
- 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) {
- return SECFailure;
- }
- offset = newOffset;
- }
-
- return SECSuccess;
-}
-
-/* protocol selection handler for ALPN (server side) and NPN (client side) */
-static SECStatus
-ssl3_SelectAppProtocol(sslSocket *ss, PRUint16 ex_type, SECItem *data)
-{
- SECStatus rv;
- unsigned char resultBuffer[255];
- SECItem result = { siBuffer, resultBuffer, 0 };
-
- rv = ssl3_ValidateNextProtoNego(data->data, data->len);
- if (rv != SECSuccess) {
- (void)SSL3_SendAlert(ss, alert_fatal, decode_error);
- PORT_SetError(SSL_ERROR_NEXT_PROTOCOL_DATA_INVALID);
- return rv;
- }
-
- PORT_Assert(ss->nextProtoCallback);
- /* For ALPN, the cipher suite isn't selected yet. Note that extensions
- * sometimes affect what cipher suite is selected, e.g., for ECC. */
- PORT_Assert((ss->ssl3.hs.preliminaryInfo &
- ssl_preinfo_all & ~ssl_preinfo_cipher_suite) ==
- (ssl_preinfo_all & ~ssl_preinfo_cipher_suite));
- rv = ss->nextProtoCallback(ss->nextProtoArg, ss->fd, data->data, data->len,
- result.data, &result.len, sizeof(resultBuffer));
- if (rv != SECSuccess) {
- /* Expect callback to call PORT_SetError() */
- (void)SSL3_SendAlert(ss, alert_fatal, internal_error);
- return SECFailure;
- }
-
- /* 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);
- /* TODO: crash */
- return SECFailure;
- }
-
- SECITEM_FreeItem(&ss->ssl3.nextProto, PR_FALSE);
+ PRInt32 extension_type;
+ SECItem extension_data = { siBuffer, NULL, 0 };
+ TLSExtension *extension;
+ PRCList *cursor;
- if (ex_type == ssl_app_layer_protocol_xtn &&
- ss->ssl3.nextProtoState != SSL_NEXT_PROTO_NEGOTIATED) {
- /* The callback might say OK, but then it picks a default value - one
- * that was not listed. That's OK for NPN, but not ALPN. */
- (void)SSL3_SendAlert(ss, alert_fatal, no_application_protocol);
- PORT_SetError(SSL_ERROR_NEXT_PROTOCOL_NO_PROTOCOL);
- return SECFailure;
- }
-
- ss->xtnData.negotiated[ss->xtnData.numNegotiated++] = ex_type;
- return SECITEM_CopyItem(NULL, &ss->ssl3.nextProto, &result);
-}
-
-/* handle an incoming ALPN extension at the server */
-static SECStatus
-ssl3_ServerHandleAppProtoXtn(sslSocket *ss, PRUint16 ex_type, SECItem *data)
-{
- int count;
- SECStatus rv;
-
- /* We expressly don't want to allow ALPN on renegotiation,
- * despite it being permitted by the spec. */
- if (ss->firstHsDone || data->len == 0) {
- /* Clients MUST send a non-empty ALPN extension. */
- (void)SSL3_SendAlert(ss, alert_fatal, illegal_parameter);
- PORT_SetError(SSL_ERROR_NEXT_PROTOCOL_DATA_INVALID);
- return SECFailure;
- }
-
- /* Unlike NPN, ALPN has extra redundant length information so that
- * the extension is the same in both ClientHello and ServerHello. */
- count = ssl3_ConsumeHandshakeNumber(ss, 2, &data->data, &data->len);
- if (count != data->len) {
- (void)ssl3_DecodeError(ss);
- return SECFailure;
- }
-
- if (!ss->nextProtoCallback) {
- /* we're not configured for it */
- return SECSuccess;
- }
-
- rv = ssl3_SelectAppProtocol(ss, ex_type, data);
- if (rv != SECSuccess) {
- return rv;
- }
-
- /* prepare to send back a response, if we negotiated */
- if (ss->ssl3.nextProtoState == SSL_NEXT_PROTO_NEGOTIATED) {
- rv = ssl3_RegisterServerHelloExtensionSender(
- ss, ex_type, ssl3_ServerSendAppProtoXtn);
- if (rv != SECSuccess) {
- (void)SSL3_SendAlert(ss, alert_fatal, internal_error);
- PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
- return rv;
+ /* 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 */
}
- }
- return SECSuccess;
-}
-
-static SECStatus
-ssl3_ClientHandleNextProtoNegoXtn(sslSocket *ss, PRUint16 ex_type,
- SECItem *data)
-{
- PORT_Assert(!ss->firstHsDone);
- if (ssl3_ExtensionNegotiated(ss, ssl_app_layer_protocol_xtn)) {
- /* If the server negotiated ALPN then it has already told us what
- * protocol to use, so it doesn't make sense for us to try to negotiate
- * a different one by sending the NPN handshake message. However, if
- * we've negotiated NPN then we're required to send the NPN handshake
- * message. Thus, these two extensions cannot both be negotiated on the
- * same connection. */
- (void)SSL3_SendAlert(ss, alert_fatal, illegal_parameter);
- PORT_SetError(SSL_ERROR_BAD_SERVER);
- return SECFailure;
- }
-
- /* We should only get this call if we sent the extension, so
- * ss->nextProtoCallback needs to be non-NULL. However, it is possible
- * that an application erroneously cleared the callback between the time
- * we sent the ClientHello and now. */
- if (!ss->nextProtoCallback) {
- PORT_Assert(0);
- (void)SSL3_SendAlert(ss, alert_fatal, internal_error);
- PORT_SetError(SSL_ERROR_NEXT_PROTOCOL_NO_CALLBACK);
- return SECFailure;
- }
-
- return ssl3_SelectAppProtocol(ss, ex_type, data);
-}
-
-static SECStatus
-ssl3_ClientHandleAppProtoXtn(sslSocket *ss, PRUint16 ex_type, SECItem *data)
-{
- SECStatus rv;
- PRInt32 list_len;
- SECItem protocol_name;
-
- if (ssl3_ExtensionNegotiated(ss, ssl_next_proto_nego_xtn)) {
- PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
- return SECFailure;
- }
-
- /* The extension data from the server has the following format:
- * uint16 name_list_len;
- * uint8 len; // where len >= 1
- * uint8 protocol_name[len]; */
- if (data->len < 4 || data->len > 2 + 1 + 255) {
- (void)SSL3_SendAlert(ss, alert_fatal, decode_error);
- PORT_SetError(SSL_ERROR_NEXT_PROTOCOL_DATA_INVALID);
- return SECFailure;
- }
-
- list_len = ssl3_ConsumeHandshakeNumber(ss, 2, &data->data, &data->len);
- /* The list has to be the entire extension. */
- if (list_len != data->len) {
- (void)SSL3_SendAlert(ss, alert_fatal, decode_error);
- PORT_SetError(SSL_ERROR_NEXT_PROTOCOL_DATA_INVALID);
- return SECFailure;
- }
-
- rv = ssl3_ConsumeHandshakeVariable(ss, &protocol_name, 1,
- &data->data, &data->len);
- /* The list must have exactly one value. */
- if (rv != SECSuccess || data->len != 0) {
- (void)SSL3_SendAlert(ss, alert_fatal, decode_error);
- PORT_SetError(SSL_ERROR_NEXT_PROTOCOL_DATA_INVALID);
- return SECFailure;
- }
-
- SECITEM_FreeItem(&ss->ssl3.nextProto, PR_FALSE);
- ss->ssl3.nextProtoState = SSL_NEXT_PROTO_SELECTED;
- ss->xtnData.negotiated[ss->xtnData.numNegotiated++] = ex_type;
- return SECITEM_CopyItem(NULL, &ss->ssl3.nextProto, &protocol_name);
-}
-
-static PRInt32
-ssl3_ClientSendNextProtoNegoXtn(sslSocket * ss, PRBool append,
- PRUint32 maxBytes)
-{
- PRInt32 extension_length;
-
- /* Renegotiations do not send this extension. */
- if (!ss->opt.enableNPN || !ss->nextProtoCallback || ss->firstHsDone) {
- return 0;
- }
-
- extension_length = 4;
-
- if (maxBytes < (PRUint32)extension_length) {
- return 0;
- }
- if (append) {
- 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;
- }
-
- return extension_length;
-
-loser:
- return -1;
-}
-
-static PRInt32
-ssl3_ClientSendAppProtoXtn(sslSocket * ss, PRBool append, PRUint32 maxBytes)
-{
- PRInt32 extension_length;
- unsigned char *alpn_protos = NULL;
-
- /* Renegotiations do not send this extension. */
- if (!ss->opt.enableALPN || !ss->opt.nextProtoNego.data || ss->firstHsDone) {
- return 0;
- }
-
- extension_length = 2 /* extension type */ + 2 /* extension length */ +
- 2 /* protocol name list length */ +
- ss->opt.nextProtoNego.len;
-
- if (maxBytes < (PRUint32)extension_length) {
- return 0;
- }
- if (append) {
- /* NPN requires that the client's fallback protocol is first in the
- * list. However, ALPN sends protocols in preference order. So we
- * allocate a buffer and move the first protocol to the end of the
- * list. */
- SECStatus rv;
- const unsigned int len = ss->opt.nextProtoNego.len;
-
- alpn_protos = PORT_Alloc(len);
- if (alpn_protos == NULL) {
- return SECFailure;
- }
- if (len > 0) {
- /* Each protocol string is prefixed with a single byte length. */
- unsigned int i = ss->opt.nextProtoNego.data[0] + 1;
- if (i <= len) {
- memcpy(alpn_protos, &ss->opt.nextProtoNego.data[i], len - i);
- memcpy(alpn_protos + len - i, ss->opt.nextProtoNego.data, i);
- } else {
- /* This seems to be invalid data so we'll send as-is. */
- memcpy(alpn_protos, ss->opt.nextProtoNego.data, len);
+ SSL_TRC(10, ("%d: SSL3[%d]: parsing extension %d",
+ SSL_GETPID(), ss->fd, extension_type));
+ /* Check whether an extension has been sent multiple times. */
+ for (cursor = PR_NEXT_LINK(&ss->ssl3.hs.remoteExtensions);
+ cursor != &ss->ssl3.hs.remoteExtensions;
+ cursor = PR_NEXT_LINK(cursor)) {
+ if (((TLSExtension *)cursor)->type == extension_type) {
+ (void)SSL3_SendAlert(ss, alert_fatal, illegal_parameter);
+ PORT_SetError(SSL_ERROR_RX_UNEXPECTED_EXTENSION);
+ return SECFailure;
}
}
- rv = ssl3_AppendHandshakeNumber(ss, ssl_app_layer_protocol_xtn, 2);
- if (rv != SECSuccess) {
- goto loser;
- }
- rv = ssl3_AppendHandshakeNumber(ss, extension_length - 4, 2);
- if (rv != SECSuccess) {
- goto loser;
- }
- rv = ssl3_AppendHandshakeVariable(ss, alpn_protos, len, 2);
- PORT_Free(alpn_protos);
- alpn_protos = NULL;
- if (rv != SECSuccess) {
- goto loser;
- }
- ss->xtnData.advertised[ss->xtnData.numAdvertised++] =
- ssl_app_layer_protocol_xtn;
- }
-
- return extension_length;
-
-loser:
- if (alpn_protos) {
- PORT_Free(alpn_protos);
- }
- return -1;
-}
-
-static PRInt32
-ssl3_ServerSendAppProtoXtn(sslSocket * ss, PRBool append, PRUint32 maxBytes)
-{
- PRInt32 extension_length;
-
- /* we're in over our heads if any of these fail */
- PORT_Assert(ss->opt.enableALPN);
- PORT_Assert(ss->ssl3.nextProto.data);
- PORT_Assert(ss->ssl3.nextProto.len > 0);
- PORT_Assert(ss->ssl3.nextProtoState == SSL_NEXT_PROTO_NEGOTIATED);
- PORT_Assert(!ss->firstHsDone);
-
- extension_length = 2 /* extension type */ + 2 /* extension length */ +
- 2 /* protocol name list */ + 1 /* name length */ +
- ss->ssl3.nextProto.len;
-
- if (maxBytes < (PRUint32)extension_length) {
- return 0;
- }
- if (append) {
- SECStatus rv;
- rv = ssl3_AppendHandshakeNumber(ss, ssl_app_layer_protocol_xtn, 2);
- if (rv != SECSuccess) {
- return -1;
- }
- rv = ssl3_AppendHandshakeNumber(ss, extension_length - 4, 2);
- if (rv != SECSuccess) {
- return -1;
- }
- rv = ssl3_AppendHandshakeNumber(ss, ss->ssl3.nextProto.len + 1, 2);
- if (rv != SECSuccess) {
- return -1;
- }
- rv = ssl3_AppendHandshakeVariable(ss, ss->ssl3.nextProto.data,
- ss->ssl3.nextProto.len, 1);
+ /* 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 -1;
- }
- }
-
- return extension_length;
-}
-
-static SECStatus
-ssl3_ClientHandleStatusRequestXtn(sslSocket *ss, PRUint16 ex_type,
- SECItem *data)
-{
- /* The echoed extension must be empty. */
- if (data->len != 0) {
- return SECSuccess; /* Ignore the extension. */
- }
-
- /* 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;
- int i;
- PRBool haveStatus = PR_FALSE;
-
- for (i = kt_null; i < kt_kea_size; i++) {
- /* TODO: This is a temporary workaround.
- * The correct code needs to see if we have an OCSP response for
- * the server certificate being used, rather than if we have any
- * OCSP response. See also ssl3_SendCertificateStatus.
- */
- if (ss->certStatusArray[i] && ss->certStatusArray[i]->len) {
- haveStatus = PR_TRUE;
- break;
- }
- }
- if (!haveStatus)
- return 0;
-
- extension_length = 2 + 2;
- if (maxBytes < (PRUint32)extension_length) {
- return 0;
- }
- if (append) {
- /* 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 (maxBytes < (PRUint32)extension_length) {
- PORT_Assert(0);
- return 0;
- }
- if (append) {
- 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;
- }
- return extension_length;
-}
-
-/*
- * NewSessionTicket
- * Called from ssl3_HandleFinished
- */
-SECStatus
-ssl3_SendNewSessionTicket(sslSocket *ss)
-{
- PRUint32 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;
- PRUint8 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 = NULL;
- 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 ||
- ss->ssl3.hs.kea_def->kea == kea_dhe_rsa) {
- effectiveExchKeyType = kt_rsa;
- } else {
- effectiveExchKeyType = ss->ssl3.hs.kea_def->exchKeyType;
+ return rv; /* alert already sent */
}
- 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;
+ extension = PORT_ZNew(TLSExtension);
+ if (!extension) {
+ return SECFailure;
}
- 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 */
- + 1 /* extendedMasterSecretUsed */
- + 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;
- }
-
- /* extendedMasterSecretUsed */
- rv = ssl3_AppendNumberToItem(
- &plaintext, ss->sec.ci.sid->u.ssl3.keys.extendedMasterSecretUsed, 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);
- if (rv != SECSuccess) goto loser;
- rv = PK11_DigestOp(hmac_ctx_pkcs11, key_name,
- SESS_TICKET_KEY_NAME_LEN);
- if (rv != SECSuccess) goto loser;
- rv = PK11_DigestOp(hmac_ctx_pkcs11, iv, sizeof(iv));
- if (rv != SECSuccess) goto loser;
- rv = PK11_DigestOp(hmac_ctx_pkcs11, (unsigned char *)length_buf, 2);
- if (rv != SECSuccess) goto loser;
- rv = PK11_DigestOp(hmac_ctx_pkcs11, ciphertext.data, ciphertext.len);
- if (rv != SECSuccess) goto loser;
- rv = PK11_DigestFinal(hmac_ctx_pkcs11, computed_mac,
- &computed_mac_length, sizeof(computed_mac));
- 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 (hmac_ctx_pkcs11)
- PK11_DestroyContext(hmac_ctx_pkcs11, PR_TRUE);
- 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 SECSuccess; /* Ignore the extension. */
+ extension->type = (PRUint16)extension_type;
+ extension->data = extension_data;
+ PR_APPEND_LINK(&extension->link, &ss->ssl3.hs.remoteExtensions);
}
- /* 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)
+TLSExtension *
+ssl3_FindExtension(sslSocket *ss, SSLExtensionType extension_type)
{
- 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;
+ PRCList *cursor;
- /* 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 {
- PRUint32 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 SECSuccess; /* Pretend it isn't there */
- }
-
- /* 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;
- }
+ for (cursor = PR_NEXT_LINK(&ss->ssl3.hs.remoteExtensions);
+ cursor != &ss->ssl3.hs.remoteExtensions;
+ cursor = PR_NEXT_LINK(cursor)) {
+ TLSExtension *extension = (TLSExtension *)cursor;
- /* 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;
+ if (extension->type == extension_type) {
+ return extension;
}
-
- /* 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 and reject if the version is wrong */
- temp = ssl3_ConsumeHandshakeNumber(ss, 2, &buffer, &buffer_len);
- if (temp != TLS_EX_SESS_TICKET_VERSION) 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 < parsed_session_ticket->ms_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;
- }
-
- /* Read extendedMasterSecretUsed */
- temp = ssl3_ConsumeHandshakeNumber(ss, 1, &buffer, &buffer_len);
- if (temp < 0)
- goto no_ticket;
- PORT_Assert(temp == PR_TRUE || temp == PR_FALSE);
- parsed_session_ticket->extendedMasterSecretUsed = (PRBool)temp;
-
- /* 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;
- sid->u.ssl3.keys.extendedMasterSecretUsed = parsed_session_ticket->
- extendedMasterSecretUsed;
-
- /* 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;
+ return NULL;
}
-/*
- * 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".
+/* Go through the hello extensions in |ss->ssl3.hs.remoteExtensions|.
* 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.
+ * Clients reject any extensions with unadvertised extension types
+ *
+ * In TLS >= 1.3, the client checks that extensions appear in the
+ * right phase.
*/
SECStatus
-ssl3_HandleHelloExtensions(sslSocket *ss, SSL3Opaque **b, PRUint32 *length)
+ssl3_HandleParsedExtensions(sslSocket *ss,
+ SSL3HandshakeType handshakeMessage)
{
- const ssl3HelloExtensionHandler * handlers;
+ const ssl3ExtensionHandler *handlers;
+ PRBool isTLS13 = ss->version >= SSL_LIBRARY_VERSION_TLS_1_3;
+ PRCList *cursor;
- if (ss->sec.isServer) {
- handlers = clientHelloHandlers;
- } else if (ss->version > SSL_LIBRARY_VERSION_3_0) {
- handlers = serverHelloHandlersTLS;
- } else {
- handlers = serverHelloHandlersSSL3;
+ switch (handshakeMessage) {
+ case client_hello:
+ handlers = clientHelloHandlers;
+ break;
+ case new_session_ticket:
+ PORT_Assert(ss->version >= SSL_LIBRARY_VERSION_TLS_1_3);
+ handlers = newSessionTicketHandlers;
+ break;
+ case hello_retry_request:
+ handlers = helloRetryRequestHandlers;
+ break;
+ case encrypted_extensions:
+ PORT_Assert(ss->version >= SSL_LIBRARY_VERSION_TLS_1_3);
+ /* fall through */
+ case server_hello:
+ if (ss->version > SSL_LIBRARY_VERSION_3_0) {
+ handlers = serverHelloHandlersTLS;
+ } else {
+ handlers = serverHelloHandlersSSL3;
+ }
+ break;
+ case certificate:
+ PORT_Assert(!ss->sec.isServer);
+ handlers = serverCertificateHandlers;
+ break;
+ default:
+ PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
+ PORT_Assert(0);
+ return SECFailure;
}
- 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; /* alert already sent */
+ for (cursor = PR_NEXT_LINK(&ss->ssl3.hs.remoteExtensions);
+ cursor != &ss->ssl3.hs.remoteExtensions;
+ cursor = PR_NEXT_LINK(cursor)) {
+ TLSExtension *extension = (TLSExtension *)cursor;
+ const ssl3ExtensionHandler *handler;
/* Check whether the server sent an extension which was not advertised
- * in the ClientHello.
- */
+ * in the ClientHello */
if (!ss->sec.isServer &&
- !ssl3_ClientExtensionAdvertised(ss, extension_type)) {
+ !ssl3_ClientExtensionAdvertised(ss, extension->type) &&
+ (handshakeMessage != new_session_ticket) &&
+ (extension->type != ssl_tls13_cookie_xtn)) {
(void)SSL3_SendAlert(ss, alert_fatal, unsupported_extension);
+ PORT_SetError(SSL_ERROR_RX_UNEXPECTED_EXTENSION);
return SECFailure;
}
- /* Check whether an extension has been sent multiple times. */
- if (ssl3_ExtensionNegotiated(ss, extension_type)) {
- (void)SSL3_SendAlert(ss, alert_fatal, illegal_parameter);
+ /* Check that this is a legal extension in TLS 1.3 */
+ if (isTLS13 && !tls13_ExtensionAllowed(extension->type, handshakeMessage)) {
+ if (handshakeMessage == client_hello) {
+ /* Skip extensions not used in TLS 1.3 */
+ continue;
+ }
+ tls13_FatalError(ss, SSL_ERROR_EXTENSION_DISALLOWED_FOR_VERSION,
+ unsupported_extension);
+ return SECFailure;
+ }
+
+ /* Special check for this being the last extension if it's
+ * PreSharedKey */
+ if (ss->sec.isServer && isTLS13 &&
+ (extension->type == ssl_tls13_pre_shared_key_xtn) &&
+ (PR_NEXT_LINK(cursor) != &ss->ssl3.hs.remoteExtensions)) {
+ tls13_FatalError(ss,
+ SSL_ERROR_RX_MALFORMED_CLIENT_HELLO,
+ illegal_parameter);
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);
+ if (handler->ex_type == extension->type) {
+ SECStatus rv;
+
+ rv = (*handler->ex_handler)(ss, &ss->xtnData,
+ (PRUint16)extension->type,
+ &extension->data);
if (rv != SECSuccess) {
if (!ss->ssl3.fatalAlertSent) {
/* send a generic alert if the handler didn't already */
@@ -1974,18 +344,53 @@ ssl3_HandleHelloExtensions(sslSocket *ss, SSL3Opaque **b, PRUint32 *length)
return SECSuccess;
}
+/* Syntactic sugar around ssl3_ParseExtensions and
+ * ssl3_HandleParsedExtensions. */
+SECStatus
+ssl3_HandleExtensions(sslSocket *ss,
+ SSL3Opaque **b, PRUint32 *length,
+ SSL3HandshakeType handshakeMessage)
+{
+ SECStatus rv;
+
+ rv = ssl3_ParseExtensions(ss, b, length);
+ if (rv != SECSuccess)
+ return rv;
+
+ rv = ssl3_HandleParsedExtensions(ss, handshakeMessage);
+ if (rv != SECSuccess)
+ return rv;
+
+ ssl3_DestroyRemoteExtensions(&ss->ssl3.hs.remoteExtensions);
+ 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)
+ssl3_RegisterExtensionSender(const sslSocket *ss,
+ TLSExtensionData *xtnData,
+ PRUint16 ex_type,
+ ssl3HelloExtensionSenderFunc cb)
{
int i;
- ssl3HelloExtensionSender *sender = &ss->xtnData.serverSenders[0];
-
+ ssl3HelloExtensionSender *sender;
+ if (ss->version < SSL_LIBRARY_VERSION_TLS_1_3) {
+ sender = &xtnData->serverHelloSenders[0];
+ } else {
+ if (tls13_ExtensionAllowed(ex_type, server_hello)) {
+ PORT_Assert(!tls13_ExtensionAllowed(ex_type, encrypted_extensions));
+ sender = &xtnData->serverHelloSenders[0];
+ } else if (tls13_ExtensionAllowed(ex_type, certificate)) {
+ sender = &xtnData->certificateSenders[0];
+ } else {
+ PORT_Assert(tls13_ExtensionAllowed(ex_type, encrypted_extensions));
+ sender = &xtnData->encryptedExtensionsSenders[0];
+ }
+ }
for (i = 0; i < SSL_MAX_EXTENSIONS; ++i, ++sender) {
if (!sender->ex_sender) {
- sender->ex_type = ex_type;
+ sender->ex_type = ex_type;
sender->ex_sender = cb;
return SECSuccess;
}
@@ -2010,675 +415,116 @@ ssl3_CallHelloExtensionSenders(sslSocket *ss, PRBool append, PRUint32 maxBytes,
int i;
if (!sender) {
- sender = ss->version > SSL_LIBRARY_VERSION_3_0 ?
- &clientHelloSendersTLS[0] : &clientHelloSendersSSL3[0];
+ if (ss->vrange.max > SSL_LIBRARY_VERSION_3_0) {
+ sender = &clientHelloSendersTLS[0];
+ } else {
+ sender = &clientHelloSendersSSL3[0];
+ }
}
for (i = 0; i < SSL_MAX_EXTENSIONS; ++i, ++sender) {
if (sender->ex_sender) {
- PRInt32 extLen = (*sender->ex_sender)(ss, append, maxBytes);
+ PRInt32 extLen = (*sender->ex_sender)(ss, &ss->xtnData, append, maxBytes);
if (extLen < 0)
return -1;
- maxBytes -= extLen;
+ 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)
+void
+ssl3_DestroyRemoteExtensions(PRCList *list)
{
- PRInt32 len, needed;
+ PRCList *cur_p;
- /* 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 (maxBytes < (PRUint32)needed) {
- return 0;
- }
- if (append) {
- 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;
- }
+ while (!PR_CLIST_IS_EMPTY(list)) {
+ cur_p = PR_LIST_TAIL(list);
+ PR_REMOVE_LINK(cur_p);
+ PORT_Free(cur_p);
}
- return needed;
-}
-
-static SECStatus
-ssl3_ServerHandleStatusRequestXtn(sslSocket *ss, PRUint16 ex_type,
- SECItem *data)
-{
- SECStatus rv = SECSuccess;
-
- /* 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)
+/* Initialize the extension data block. */
+void
+ssl3_InitExtensionData(TLSExtensionData *xtnData)
{
- 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 ) {
- (void)ssl3_DecodeError(ss);
- return SECFailure;
- }
- if (len && NSS_SecureMemcmp(ss->ssl3.hs.finishedMsgs.data,
- data->data + 1, len)) {
- (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;
+ /* Set things up to the right starting state. */
+ PORT_Memset(xtnData, 0, sizeof(*xtnData));
+ xtnData->peerSupportsFfdheGroups = PR_FALSE;
+ PR_INIT_CLIST(&xtnData->remoteKeyShares);
}
-static PRInt32
-ssl3_ClientSendUseSRTPXtn(sslSocket *ss, PRBool append, PRUint32 maxBytes)
+/* Free everything that has been allocated and then reset back to
+ * the starting state. */
+void
+ssl3_ResetExtensionData(TLSExtensionData *xtnData)
{
- PRUint32 ext_data_len;
- PRInt16 i;
- SECStatus rv;
-
- if (!ss)
- return 0;
-
- 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);
+ /* Clean up. */
+ ssl3_FreeSniNameArray(xtnData);
+ PORT_Free(xtnData->clientSigSchemes);
+ SECITEM_FreeItem(&xtnData->nextProto, PR_FALSE);
+ tls13_DestroyKeyShares(&xtnData->remoteKeyShares);
- ss->xtnData.advertised[ss->xtnData.numAdvertised++] =
- ssl_use_srtp_xtn;
- }
-
- return 4 + ext_data_len;
+ /* Now reinit. */
+ ssl3_InitExtensionData(xtnData);
}
-static PRInt32
-ssl3_ServerSendUseSRTPXtn(sslSocket *ss, PRBool append, PRUint32 maxBytes)
+/* Thunks to let extension handlers operate on const sslSocket* objects. */
+SECStatus
+ssl3_ExtAppendHandshake(const sslSocket *ss, const void *void_src,
+ PRInt32 bytes)
{
- SECStatus rv;
-
- /* Server side */
- if (!append || maxBytes < 9) {
- return 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;
+ return ssl3_AppendHandshake((sslSocket *)ss, void_src, bytes);
}
-static SECStatus
-ssl3_ClientHandleUseSRTPXtn(sslSocket * ss, PRUint16 ex_type, SECItem *data)
+SECStatus
+ssl3_ExtAppendHandshakeNumber(const sslSocket *ss, PRInt32 num,
+ PRInt32 lenSize)
{
- SECStatus rv;
- SECItem ciphers = {siBuffer, NULL, 0};
- PRUint16 i;
- PRUint16 cipher = 0;
- PRBool found = PR_FALSE;
- SECItem litem;
-
- if (!data->data || !data->len) {
- (void)ssl3_DecodeError(ss);
- return SECFailure;
- }
-
- /* Get the cipher list */
- rv = ssl3_ConsumeHandshakeVariable(ss, &ciphers, 2,
- &data->data, &data->len);
- if (rv != SECSuccess) {
- return SECFailure; /* fatal alert already sent */
- }
- /* Now check that the server has picked just 1 (i.e., len = 2) */
- if (ciphers.len != 2) {
- (void)ssl3_DecodeError(ss);
- 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) {
- (void)SSL3_SendAlert(ss, alert_fatal, illegal_parameter);
- PORT_SetError(SSL_ERROR_RX_MALFORMED_SERVER_HELLO);
- return SECFailure;
- }
-
- /* Get the srtp_mki value */
- rv = ssl3_ConsumeHandshakeVariable(ss, &litem, 1,
- &data->data, &data->len);
- if (rv != SECSuccess) {
- return SECFailure; /* alert already sent */
- }
-
- /* We didn't offer an MKI, so this must be 0 length */
- if (litem.len != 0) {
- (void)SSL3_SendAlert(ss, alert_fatal, illegal_parameter);
- PORT_SetError(SSL_ERROR_RX_MALFORMED_SERVER_HELLO);
- return SECFailure;
- }
-
- /* extra trailing bytes */
- if (data->len != 0) {
- (void)ssl3_DecodeError(ss);
- return SECFailure;
- }
-
- /* OK, this looks fine. */
- ss->xtnData.negotiated[ss->xtnData.numNegotiated++] = ssl_use_srtp_xtn;
- ss->ssl3.dtlsSRTPCipherSuite = cipher;
- return SECSuccess;
+ return ssl3_AppendHandshakeNumber((sslSocket *)ss, num, lenSize);
}
-static SECStatus
-ssl3_ServerHandleUseSRTPXtn(sslSocket * ss, PRUint16 ex_type, SECItem *data)
+SECStatus
+ssl3_ExtAppendHandshakeVariable(const sslSocket *ss,
+ const SSL3Opaque *src, PRInt32 bytes,
+ PRInt32 lenSize)
{
- SECStatus rv;
- SECItem ciphers = {siBuffer, NULL, 0};
- PRUint16 i;
- unsigned int j;
- PRUint16 cipher = 0;
- PRBool found = PR_FALSE;
- SECItem litem;
-
- 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) {
- (void)ssl3_DecodeError(ss);
- return SECFailure;
- }
-
- /* Get the cipher list */
- rv = ssl3_ConsumeHandshakeVariable(ss, &ciphers, 2,
- &data->data, &data->len);
- if (rv != SECSuccess) {
- return SECFailure; /* alert already sent */
- }
- /* Check that the list is even length */
- if (ciphers.len % 2) {
- (void)ssl3_DecodeError(ss);
- 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) {
- (void)ssl3_DecodeError(ss); /* trailing bytes */
- return SECFailure;
- }
-
- /* Now figure out what to do */
- if (!found) {
- /* No matching ciphers, pretend we don't support use_srtp */
- 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_ServerSendUseSRTPXtn);
+ return ssl3_AppendHandshakeVariable((sslSocket *)ss, src, bytes, lenSize);
}
-/* ssl3_ServerHandleSigAlgsXtn handles the signature_algorithms extension
- * from a client.
- * See https://tools.ietf.org/html/rfc5246#section-7.4.1.4.1 */
-static SECStatus
-ssl3_ServerHandleSigAlgsXtn(sslSocket * ss, PRUint16 ex_type, SECItem *data)
+void
+ssl3_ExtSendAlert(const sslSocket *ss, SSL3AlertLevel level,
+ SSL3AlertDescription desc)
{
- SECStatus rv;
- SECItem algorithms;
- const unsigned char *b;
- unsigned int numAlgorithms, i;
-
- /* Ignore this extension if we aren't doing TLS 1.2 or greater. */
- if (ss->version < SSL_LIBRARY_VERSION_TLS_1_2) {
- return SECSuccess;
- }
-
- rv = ssl3_ConsumeHandshakeVariable(ss, &algorithms, 2, &data->data,
- &data->len);
- if (rv != SECSuccess) {
- return SECFailure;
- }
- /* Trailing data, empty value, or odd-length value is invalid. */
- if (data->len != 0 || algorithms.len == 0 || (algorithms.len & 1) != 0) {
- (void)SSL3_SendAlert(ss, alert_fatal, decode_error);
- PORT_SetError(SSL_ERROR_RX_MALFORMED_CLIENT_HELLO);
- return SECFailure;
- }
-
- numAlgorithms = algorithms.len/2;
-
- /* We don't care to process excessive numbers of algorithms. */
- if (numAlgorithms > 512) {
- numAlgorithms = 512;
- }
-
- ss->ssl3.hs.clientSigAndHash =
- PORT_NewArray(SSLSignatureAndHashAlg, numAlgorithms);
- if (!ss->ssl3.hs.clientSigAndHash) {
- (void)SSL3_SendAlert(ss, alert_fatal, internal_error);
- PORT_SetError(SSL_ERROR_RX_MALFORMED_CLIENT_HELLO);
- return SECFailure;
- }
- ss->ssl3.hs.numClientSigAndHash = 0;
-
- b = algorithms.data;
- ss->ssl3.hs.numClientSigAndHash = 0;
- for (i = 0; i < numAlgorithms; i++) {
- SSLSignatureAndHashAlg *sigAndHash =
- &ss->ssl3.hs.clientSigAndHash[ss->ssl3.hs.numClientSigAndHash];
- sigAndHash->hashAlg = (SSLHashType)*(b++);
- sigAndHash->sigAlg = (SSLSignType)*(b++);
- if (ssl3_IsSupportedSignatureAlgorithm(sigAndHash)) {
- ++ss->ssl3.hs.numClientSigAndHash;
- }
- }
-
- if (!ss->ssl3.hs.numClientSigAndHash) {
- /* We didn't understand any of the client's requested signature
- * formats. We'll use the defaults. */
- PORT_Free(ss->ssl3.hs.clientSigAndHash);
- ss->ssl3.hs.clientSigAndHash = NULL;
- }
-
- /* Keep track of negotiated extensions. */
- ss->xtnData.negotiated[ss->xtnData.numNegotiated++] = ex_type;
- return SECSuccess;
+ (void)SSL3_SendAlert((sslSocket *)ss, level, desc);
}
-/* ssl3_ClientSendSigAlgsXtn sends the signature_algorithm extension for TLS
- * 1.2 ClientHellos. */
-static PRInt32
-ssl3_ClientSendSigAlgsXtn(sslSocket *ss, PRBool append, PRUint32 maxBytes)
+void
+ssl3_ExtDecodeError(const sslSocket *ss)
{
- PRInt32 extension_length;
- unsigned int i;
- PRInt32 pos=0;
- PRUint32 policy;
- PRUint8 buf[MAX_SIGNATURE_ALGORITHMS * 2];
-
- if (ss->version < SSL_LIBRARY_VERSION_TLS_1_2) {
- return 0;
- }
-
- for (i=0; i < ss->ssl3.signatureAlgorithmCount; i++) {
- SECOidTag hashOID = ssl3_TLSHashAlgorithmToOID(
- ss->ssl3.signatureAlgorithms[i].hashAlg);
- if ((NSS_GetAlgorithmPolicy(hashOID, & policy) != SECSuccess) ||
- (policy & NSS_USE_ALG_IN_SSL_KX)) {
- buf[pos++] = ss->ssl3.signatureAlgorithms[i].hashAlg;
- buf[pos++] = ss->ssl3.signatureAlgorithms[i].sigAlg;
- }
- }
-
- extension_length =
- 2 /* extension type */ +
- 2 /* extension length */ +
- 2 /* supported_signature_algorithms length */ +
- pos;
-
- if (maxBytes < extension_length) {
- PORT_Assert(0);
- return 0;
- }
-
- if (append) {
- SECStatus rv;
- rv = ssl3_AppendHandshakeNumber(ss, ssl_signature_algorithms_xtn, 2);
- if (rv != SECSuccess) {
- return -1;
- }
- rv = ssl3_AppendHandshakeNumber(ss, extension_length - 4, 2);
- if (rv != SECSuccess) {
- return -1;
- }
-
- rv = ssl3_AppendHandshakeVariable(ss, buf, extension_length - 6, 2);
- if (rv != SECSuccess) {
- return -1;
- }
-
- ss->xtnData.advertised[ss->xtnData.numAdvertised++] =
- ssl_signature_algorithms_xtn;
- }
-
- return extension_length;
+ (void)ssl3_DecodeError((sslSocket *)ss);
}
-unsigned int
-ssl3_CalculatePaddingExtensionLength(unsigned int clientHelloLength)
+SECStatus
+ssl3_ExtConsumeHandshake(const sslSocket *ss, void *v, PRInt32 bytes,
+ SSL3Opaque **b, PRUint32 *length)
{
- unsigned int recordLength = 1 /* handshake message type */ +
- 3 /* handshake message length */ +
- clientHelloLength;
- unsigned int extensionLength;
-
- if (recordLength < 256 || recordLength >= 512) {
- return 0;
- }
-
- extensionLength = 512 - recordLength;
- /* Extensions take at least four bytes to encode. */
- if (extensionLength < 4) {
- extensionLength = 4;
- }
-
- return extensionLength;
+ return ssl3_ConsumeHandshake((sslSocket *)ss, v, bytes, b, length);
}
-/* ssl3_AppendPaddingExtension possibly adds an extension which ensures that a
- * ClientHello record is either < 256 bytes or is >= 512 bytes. This ensures
- * that we don't trigger bugs in F5 products. */
PRInt32
-ssl3_AppendPaddingExtension(sslSocket *ss, unsigned int extensionLen,
- PRUint32 maxBytes)
-{
- unsigned int paddingLen = extensionLen - 4;
- static unsigned char padding[256];
-
- if (extensionLen == 0) {
- return 0;
- }
-
- if (extensionLen < 4 ||
- extensionLen > maxBytes ||
- paddingLen > sizeof(padding)) {
- PORT_Assert(0);
- return -1;
- }
-
- if (SECSuccess != ssl3_AppendHandshakeNumber(ss, ssl_padding_xtn, 2))
- return -1;
- if (SECSuccess != ssl3_AppendHandshakeNumber(ss, paddingLen, 2))
- return -1;
- if (SECSuccess != ssl3_AppendHandshake(ss, padding, paddingLen))
- return -1;
-
- return extensionLen;
-}
-
-/* ssl3_ClientSendDraftVersionXtn sends the TLS 1.3 temporary draft
- * version extension.
- * TODO(ekr@rtfm.com): Remove when TLS 1.3 is published. */
-static PRInt32
-ssl3_ClientSendDraftVersionXtn(sslSocket * ss, PRBool append, PRUint32 maxBytes)
-{
- PRInt32 extension_length;
-
- if (ss->version != SSL_LIBRARY_VERSION_TLS_1_3) {
- return 0;
- }
-
- extension_length = 6; /* Type + length + number */
- if (maxBytes < (PRUint32)extension_length) {
- PORT_Assert(0);
- return 0;
- }
- if (append) {
- SECStatus rv;
- rv = ssl3_AppendHandshakeNumber(ss, ssl_tls13_draft_version_xtn, 2);
- if (rv != SECSuccess)
- goto loser;
- rv = ssl3_AppendHandshakeNumber(ss, extension_length - 4, 2);
- if (rv != SECSuccess)
- goto loser;
- rv = ssl3_AppendHandshakeNumber(ss, TLS_1_3_DRAFT_VERSION, 2);
- if (rv != SECSuccess)
- goto loser;
- ss->xtnData.advertised[ss->xtnData.numAdvertised++] =
- ssl_tls13_draft_version_xtn;
- }
-
- return extension_length;
-
-loser:
- return -1;
-}
-
-/* ssl3_ServerHandleDraftVersionXtn handles the TLS 1.3 temporary draft
- * version extension.
- * TODO(ekr@rtfm.com): Remove when TLS 1.3 is published. */
-static SECStatus
-ssl3_ServerHandleDraftVersionXtn(sslSocket * ss, PRUint16 ex_type,
- SECItem *data)
+ssl3_ExtConsumeHandshakeNumber(const sslSocket *ss, PRInt32 bytes,
+ SSL3Opaque **b, PRUint32 *length)
{
- PRInt32 draft_version;
-
- /* Ignore this extension if we aren't doing TLS 1.3 */
- if (ss->version != SSL_LIBRARY_VERSION_TLS_1_3) {
- return SECSuccess;
- }
-
- if (data->len != 2) {
- (void)ssl3_DecodeError(ss);
- return SECFailure;
- }
-
- /* Get the draft version out of the handshake */
- draft_version = ssl3_ConsumeHandshakeNumber(ss, 2,
- &data->data, &data->len);
- if (draft_version < 0) {
- return SECFailure;
- }
-
- /* Keep track of negotiated extensions. */
- ss->xtnData.negotiated[ss->xtnData.numNegotiated++] = ex_type;
-
- if (draft_version != TLS_1_3_DRAFT_VERSION) {
- /*
- * Incompatible/broken TLS 1.3 implementation. Fall back to TLS 1.2.
- * TODO(ekr@rtfm.com): It's not entirely clear it's safe to roll back
- * here. Need to double-check.
- */
- SSL_TRC(30, ("%d: SSL3[%d]: Incompatible version of TLS 1.3 (%d), "
- "expected %d",
- SSL_GETPID(), ss->fd, draft_version, TLS_1_3_DRAFT_VERSION));
- ss->version = SSL_LIBRARY_VERSION_TLS_1_2;
- }
-
- return SECSuccess;
+ return ssl3_ConsumeHandshakeNumber((sslSocket *)ss, bytes, b, length);
}
-static PRInt32
-ssl3_SendExtendedMasterSecretXtn(sslSocket * ss, PRBool append,
- PRUint32 maxBytes)
-{
- PRInt32 extension_length;
-
- if (!ss->opt.enableExtendedMS) {
- return 0;
- }
-
-#ifndef NO_PKCS11_BYPASS
- /* Extended MS can only be used w/o bypass mode */
- if (ss->opt.bypassPKCS11) {
- PORT_Assert(0);
- PORT_SetError(PR_NOT_IMPLEMENTED_ERROR);
- return -1;
- }
-#endif
-
- /* Always send the extension in this function, since the
- * client always sends it and this function is only called on
- * the server if we negotiated the extension. */
- extension_length = 4; /* Type + length (0) */
- if (maxBytes < extension_length) {
- PORT_Assert(0);
- return 0;
- }
-
- if (append) {
- SECStatus rv;
- rv = ssl3_AppendHandshakeNumber(ss, ssl_extended_master_secret_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_extended_master_secret_xtn;
- }
-
- return extension_length;
-
-loser:
- return -1;
-}
-
-
-static SECStatus
-ssl3_HandleExtendedMasterSecretXtn(sslSocket * ss, PRUint16 ex_type,
- SECItem *data)
+SECStatus
+ssl3_ExtConsumeHandshakeVariable(const sslSocket *ss, SECItem *i,
+ PRInt32 bytes, SSL3Opaque **b,
+ PRUint32 *length)
{
- if (ss->version < SSL_LIBRARY_VERSION_TLS_1_0) {
- return SECSuccess;
- }
-
- if (!ss->opt.enableExtendedMS) {
- return SECSuccess;
- }
-
-#ifndef NO_PKCS11_BYPASS
- /* Extended MS can only be used w/o bypass mode */
- if (ss->opt.bypassPKCS11) {
- PORT_Assert(0);
- PORT_SetError(PR_NOT_IMPLEMENTED_ERROR);
- return SECFailure;
- }
-#endif
-
- if (data->len != 0) {
- SSL_TRC(30, ("%d: SSL3[%d]: Bogus extended master secret extension",
- SSL_GETPID(), ss->fd));
- return SECFailure;
- }
-
- SSL_DBG(("%d: SSL[%d]: Negotiated extended master secret extension.",
- SSL_GETPID(), ss->fd));
-
- /* Keep track of negotiated extensions. */
- ss->xtnData.negotiated[ss->xtnData.numNegotiated++] = ex_type;
-
- if (ss->sec.isServer) {
- return ssl3_RegisterServerHelloExtensionSender(
- ss, ex_type, ssl3_SendExtendedMasterSecretXtn);
- }
- return SECSuccess;
+ return ssl3_ConsumeHandshakeVariable((sslSocket *)ss, i, bytes, b, length);
}
diff --git a/nss/lib/ssl/ssl3ext.h b/nss/lib/ssl/ssl3ext.h
new file mode 100644
index 0000000..f93ad65
--- /dev/null
+++ b/nss/lib/ssl/ssl3ext.h
@@ -0,0 +1,156 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is PRIVATE to SSL.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.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 __ssl3ext_h_
+#define __ssl3ext_h_
+
+typedef enum {
+ sni_nametype_hostname
+} SNINameType;
+typedef struct TLSExtensionDataStr TLSExtensionData;
+
+/* registerable callback function that either appends extension to buffer
+ * or returns length of data that it would have appended.
+ */
+typedef PRInt32 (*ssl3HelloExtensionSenderFunc)(const sslSocket *ss,
+ TLSExtensionData *xtnData,
+ PRBool append,
+ PRUint32 maxBytes);
+
+/* registerable callback function that handles a received extension,
+ * of the given type.
+ */
+typedef SECStatus (*ssl3ExtensionHandlerFunc)(const sslSocket *ss,
+ TLSExtensionData *xtnData,
+ 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;
+ ssl3ExtensionHandlerFunc ex_handler;
+} ssl3ExtensionHandler;
+
+struct TLSExtensionDataStr {
+ /* registered callbacks that send server hello extensions */
+ ssl3HelloExtensionSender serverHelloSenders[SSL_MAX_EXTENSIONS];
+ ssl3HelloExtensionSender encryptedExtensionsSenders[SSL_MAX_EXTENSIONS];
+ ssl3HelloExtensionSender certificateSenders[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;
+ PRBool sentSessionTicketInClientHello;
+ SECItem psk_ke_modes;
+ PRUint32 max_early_data_size;
+
+ /* 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;
+
+ /* Signed Certificate Timestamps extracted from the TLS extension.
+ * (client only).
+ * This container holds a temporary pointer to the extension data,
+ * until a session structure (the sec.ci.sid of an sslSocket) is setup
+ * that can hold a permanent copy of the data
+ * (in sec.ci.sid.u.ssl3.signedCertTimestamps).
+ * The data pointed to by this structure is neither explicitly allocated
+ * nor copied: the pointer points to the handshake message buffer and is
+ * only valid in the scope of ssl3_HandleServerHello.
+ */
+ SECItem signedCertTimestamps;
+
+ PRBool peerSupportsFfdheGroups; /* if the peer supports named ffdhe groups */
+
+ /* clientSigAndHash contains the contents of the signature_algorithms
+ * extension (if any) from the client. This is only valid for TLS 1.2
+ * or later. */
+ SSLSignatureScheme *clientSigSchemes;
+ unsigned int numClientSigScheme;
+
+ /* In a client: if the server supports Next Protocol Negotiation, then
+ * this is the protocol that was negotiated.
+ */
+ SECItem nextProto;
+ SSLNextProtoState nextProtoState;
+
+ PRUint16 dtlsSRTPCipherSuite; /* 0 if not selected */
+
+ SECItem pskBinder; /* The PSK binder for the first PSK (TLS 1.3) */
+ unsigned long pskBinderPrefixLen; /* The length of the binder input. */
+ PRCList remoteKeyShares; /* The other side's public keys (TLS 1.3) */
+};
+
+typedef struct TLSExtensionStr {
+ PRCList link; /* The linked list link */
+ PRUint16 type; /* Extension type */
+ SECItem data; /* Pointers into the handshake data. */
+} TLSExtension;
+
+SECStatus ssl3_HandleExtensions(sslSocket *ss,
+ SSL3Opaque **b, PRUint32 *length,
+ SSL3HandshakeType handshakeMessage);
+SECStatus ssl3_ParseExtensions(sslSocket *ss,
+ SSL3Opaque **b, PRUint32 *length);
+SECStatus ssl3_HandleParsedExtensions(sslSocket *ss,
+ SSL3HandshakeType handshakeMessage);
+TLSExtension *ssl3_FindExtension(sslSocket *ss,
+ SSLExtensionType extension_type);
+void ssl3_DestroyRemoteExtensions(PRCList *list);
+void ssl3_InitExtensionData(TLSExtensionData *xtnData);
+void ssl3_ResetExtensionData(TLSExtensionData *xtnData);
+
+PRBool ssl3_ExtensionNegotiated(const sslSocket *ss, PRUint16 ex_type);
+PRBool ssl3_ClientExtensionAdvertised(const sslSocket *ss, PRUint16 ex_type);
+
+SECStatus ssl3_RegisterExtensionSender(const sslSocket *ss,
+ TLSExtensionData *xtnData,
+ PRUint16 ex_type,
+ ssl3HelloExtensionSenderFunc cb);
+PRInt32 ssl3_CallHelloExtensionSenders(sslSocket *ss, PRBool append, PRUint32 maxBytes,
+ const ssl3HelloExtensionSender *sender);
+
+unsigned int ssl3_CalculatePaddingExtensionLength(unsigned int clientHelloLength);
+PRInt32 ssl3_AppendPaddingExtension(sslSocket *ss, unsigned int extensionLen,
+ PRUint32 maxBytes);
+
+/* Thunks to let us operate on const sslSocket* objects. */
+SECStatus ssl3_ExtAppendHandshake(const sslSocket *ss, const void *void_src,
+ PRInt32 bytes);
+SECStatus ssl3_ExtAppendHandshakeNumber(const sslSocket *ss, PRInt32 num,
+ PRInt32 lenSize);
+SECStatus ssl3_ExtAppendHandshakeVariable(const sslSocket *ss,
+ const SSL3Opaque *src, PRInt32 bytes,
+ PRInt32 lenSize);
+void ssl3_ExtSendAlert(const sslSocket *ss, SSL3AlertLevel level,
+ SSL3AlertDescription desc);
+void ssl3_ExtDecodeError(const sslSocket *ss);
+SECStatus ssl3_ExtConsumeHandshake(const sslSocket *ss, void *v, PRInt32 bytes,
+ SSL3Opaque **b, PRUint32 *length);
+PRInt32 ssl3_ExtConsumeHandshakeNumber(const sslSocket *ss, PRInt32 bytes,
+ SSL3Opaque **b, PRUint32 *length);
+SECStatus ssl3_ExtConsumeHandshakeVariable(const sslSocket *ss, SECItem *i,
+ PRInt32 bytes, SSL3Opaque **b,
+ PRUint32 *length);
+
+#endif
diff --git a/nss/lib/ssl/ssl3exthandle.c b/nss/lib/ssl/ssl3exthandle.c
new file mode 100644
index 0000000..2a80e26
--- /dev/null
+++ b/nss/lib/ssl/ssl3exthandle.c
@@ -0,0 +1,2579 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.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 "nss.h"
+#include "ssl.h"
+#include "sslproto.h"
+#include "sslimpl.h"
+#include "pk11pub.h"
+#include "blapit.h"
+#include "prinit.h"
+#include "ssl3ext.h"
+#include "ssl3exthandle.h"
+#include "tls13exthandle.h" /* For tls13_ServerSendStatusRequestXtn. */
+
+static unsigned char key_name[SESS_TICKET_KEY_NAME_LEN];
+static PK11SymKey *session_ticket_enc_key = NULL;
+static PK11SymKey *session_ticket_mac_key = NULL;
+
+static PRCallOnceType generate_session_keys_once;
+
+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_ConsumeFromItem(SECItem *item, unsigned char **buf, PRUint32 bytes);
+static SECStatus ssl3_AppendNumberToItem(SECItem *item, PRUint32 num,
+ PRInt32 lenSize);
+static SECStatus ssl3_GetSessionTicketKeys(sslSocket *ss,
+ PK11SymKey **aes_key, PK11SymKey **mac_key);
+static SECStatus ssl3_ConsumeFromItem(SECItem *item, unsigned char **buf, PRUint32 bytes);
+
+/*
+ * 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;
+ PRUint8 b[4];
+ PRUint8 *p = b;
+
+ switch (lenSize) {
+ case 4:
+ *p++ = (PRUint8)(num >> 24);
+ case 3:
+ *p++ = (PRUint8)(num >> 16);
+ case 2:
+ *p++ = (PRUint8)(num >> 8);
+ case 1:
+ *p = (PRUint8)num;
+ }
+ rv = ssl3_AppendToItem(item, &b[0], lenSize);
+ return rv;
+}
+
+SECStatus
+ssl3_SessionTicketShutdown(void *appData, void *nssData)
+{
+ if (session_ticket_enc_key) {
+ PK11_FreeSymKey(session_ticket_enc_key);
+ session_ticket_enc_key = NULL;
+ }
+ if (session_ticket_mac_key) {
+ PK11_FreeSymKey(session_ticket_mac_key);
+ session_ticket_mac_key = NULL;
+ }
+ PORT_Memset(&generate_session_keys_once, 0,
+ sizeof(generate_session_keys_once));
+ return SECSuccess;
+}
+
+static PRStatus
+ssl3_GenerateSessionTicketKeys(void *data)
+{
+ SECStatus rv;
+ sslSocket *ss = (sslSocket *)data;
+ sslServerCertType certType = { ssl_auth_rsa_decrypt, NULL };
+ const sslServerCert *sc;
+ SECKEYPrivateKey *svrPrivKey;
+ SECKEYPublicKey *svrPubKey;
+
+ sc = ssl_FindServerCert(ss, &certType);
+ if (!sc || !sc->serverKeyPair) {
+ SSL_DBG(("%d: SSL[%d]: No ssl_auth_rsa_decrypt cert and key pair",
+ SSL_GETPID(), ss->fd));
+ goto loser;
+ }
+ svrPrivKey = sc->serverKeyPair->privKey;
+ svrPubKey = sc->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_GetSessionTicketKeys(svrPrivKey, svrPubKey, ss->pkcs11PinArg,
+ &key_name[SESS_TICKET_KEY_NAME_PREFIX_LEN],
+ &session_ticket_enc_key, &session_ticket_mac_key))
+ 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_GetSessionTicketKeys(sslSocket *ss, PK11SymKey **aes_key,
+ PK11SymKey **mac_key)
+{
+ if (PR_CallOnceWithArg(&generate_session_keys_once,
+ ssl3_GenerateSessionTicketKeys, ss) !=
+ PR_SUCCESS)
+ return SECFailure;
+
+ if (session_ticket_enc_key == NULL ||
+ session_ticket_mac_key == NULL)
+ return SECFailure;
+
+ *aes_key = session_ticket_enc_key;
+ *mac_key = session_ticket_mac_key;
+ return SECSuccess;
+}
+
+/* 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(const sslSocket *ss, TLSExtensionData *xtnData, 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_ExtAppendHandshakeNumber(ss, ssl_server_name_xtn, 2);
+ if (rv != SECSuccess)
+ return -1;
+ /* length of extension_data */
+ rv = ssl3_ExtAppendHandshakeNumber(ss, len + 5, 2);
+ if (rv != SECSuccess)
+ return -1;
+ /* length of server_name_list */
+ rv = ssl3_ExtAppendHandshakeNumber(ss, len + 3, 2);
+ if (rv != SECSuccess)
+ return -1;
+ /* Name Type (sni_host_name) */
+ rv = ssl3_ExtAppendHandshake(ss, "\0", 1);
+ if (rv != SECSuccess)
+ return -1;
+ /* HostName (length and value) */
+ rv = ssl3_ExtAppendHandshakeVariable(ss, (PRUint8 *)ss->url, len, 2);
+ if (rv != SECSuccess)
+ return -1;
+ if (!ss->sec.isServer) {
+ xtnData->advertised[xtnData->numAdvertised++] =
+ ssl_server_name_xtn;
+ }
+ }
+ return len + 9;
+ }
+ /* Server side */
+ if (append && maxBytes >= 4) {
+ rv = ssl3_ExtAppendHandshakeNumber(ss, ssl_server_name_xtn, 2);
+ if (rv != SECSuccess)
+ return -1;
+ /* length of extension_data */
+ rv = ssl3_ExtAppendHandshakeNumber(ss, 0, 2);
+ if (rv != SECSuccess)
+ return -1;
+ }
+ return 4;
+}
+
+/* Handle an incoming SNI extension. */
+SECStatus
+ssl3_HandleServerNameXtn(const sslSocket *ss, TLSExtensionData *xtnData, PRUint16 ex_type, SECItem *data)
+{
+ SECItem *names = NULL;
+ PRInt32 listLenBytes = 0;
+
+ if (!ss->sec.isServer) {
+ return SECSuccess; /* ignore extension */
+ }
+
+ /* 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_ExtConsumeHandshakeNumber(ss, 2, &data->data, &data->len);
+ if (listLenBytes < 0) {
+ goto loser; /* alert already sent */
+ }
+ if (listLenBytes == 0 || listLenBytes != data->len) {
+ goto alert_loser;
+ }
+
+ /* Read ServerNameList. */
+ while (data->len > 0) {
+ SECItem tmp;
+ SECStatus rv;
+ PRInt32 type;
+
+ /* Read Name Type. */
+ type = ssl3_ExtConsumeHandshakeNumber(ss, 1, &data->data, &data->len);
+ if (type < 0) { /* i.e., SECFailure cast to PRint32 */
+ /* alert sent in ConsumeHandshakeNumber */
+ goto loser;
+ }
+
+ /* Read ServerName (length and value). */
+ rv = ssl3_ExtConsumeHandshakeVariable(ss, &tmp, 2, &data->data, &data->len);
+ if (rv != SECSuccess) {
+ goto loser;
+ }
+
+ /* Record the value for host_name(0). */
+ if (type == sni_nametype_hostname) {
+ /* Fail if we encounter a second host_name entry. */
+ if (names) {
+ goto alert_loser;
+ }
+
+ /* Create an array for the only supported NameType. */
+ names = PORT_ZNewArray(SECItem, 1);
+ if (!names) {
+ goto loser;
+ }
+
+ /* Copy ServerName into the array. */
+ if (SECITEM_CopyItem(NULL, &names[0], &tmp) != SECSuccess) {
+ goto loser;
+ }
+ }
+
+ /* Even if we don't support NameTypes other than host_name at the
+ * moment, we continue parsing the whole list to check its validity.
+ * We do not check for duplicate entries with NameType != host_name(0).
+ */
+ }
+ if (names) {
+ /* Free old and set the new data. */
+ ssl3_FreeSniNameArray(xtnData);
+ xtnData->sniNameArr = names;
+ xtnData->sniNameArrSize = 1;
+ xtnData->negotiated[xtnData->numNegotiated++] = ssl_server_name_xtn;
+ }
+ return SECSuccess;
+
+alert_loser:
+ ssl3_ExtDecodeError(ss);
+loser:
+ if (names) {
+ PORT_Free(names);
+ }
+ return SECFailure;
+}
+
+/* Frees a given xtnData->sniNameArr and its elements. */
+void
+ssl3_FreeSniNameArray(TLSExtensionData *xtnData)
+{
+ PRUint32 i;
+
+ if (!xtnData->sniNameArr) {
+ return;
+ }
+
+ for (i = 0; i < xtnData->sniNameArrSize; i++) {
+ SECITEM_FreeItem(&xtnData->sniNameArr[i], PR_FALSE);
+ }
+
+ PORT_Free(xtnData->sniNameArr);
+ xtnData->sniNameArr = NULL;
+ xtnData->sniNameArrSize = 0;
+}
+
+/* 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(
+ const sslSocket *ss,
+ TLSExtensionData *xtnData,
+ PRBool append,
+ PRUint32 maxBytes)
+{
+ PRInt32 extension_length;
+ NewSessionTicket *session_ticket = NULL;
+ sslSessionID *sid = ss->sec.ci.sid;
+
+ /* Never send an extension with a ticket for TLS 1.3, but
+ * OK to send the empty one in case the server does 1.2. */
+ if (sid->cached == in_client_cache &&
+ sid->version >= SSL_LIBRARY_VERSION_TLS_1_3) {
+ return 0;
+ }
+
+ /* 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) {
+ /* The caller must be holding sid->u.ssl3.lock for reading. We cannot
+ * just acquire and release the lock within this function because the
+ * caller will call this function twice, and we need the inputs to be
+ * consistent between the two calls. Note that currently the caller
+ * will only be holding the lock when we are the client and when we're
+ * attempting to resume an existing session.
+ */
+
+ session_ticket = &sid->u.ssl3.locked.sessionTicket;
+ if (session_ticket->ticket.data) {
+ if (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;
+ xtnData->ticketTimestampVerified = PR_TRUE;
+ }
+ }
+ }
+
+ if (maxBytes < (PRUint32)extension_length) {
+ PORT_Assert(0);
+ return 0;
+ }
+ if (append) {
+ SECStatus rv;
+ /* extension_type */
+ rv = ssl3_ExtAppendHandshakeNumber(ss, ssl_session_ticket_xtn, 2);
+ if (rv != SECSuccess)
+ goto loser;
+ if (session_ticket && session_ticket->ticket.data &&
+ xtnData->ticketTimestampVerified) {
+ rv = ssl3_ExtAppendHandshakeVariable(ss, session_ticket->ticket.data,
+ session_ticket->ticket.len, 2);
+ xtnData->ticketTimestampVerified = PR_FALSE;
+ xtnData->sentSessionTicketInClientHello = PR_TRUE;
+ } else {
+ rv = ssl3_ExtAppendHandshakeNumber(ss, 0, 2);
+ }
+ if (rv != SECSuccess)
+ goto loser;
+
+ if (!ss->sec.isServer) {
+ xtnData->advertised[xtnData->numAdvertised++] =
+ ssl_session_ticket_xtn;
+ }
+ }
+ return extension_length;
+
+loser:
+ xtnData->ticketTimestampVerified = PR_FALSE;
+ return -1;
+}
+
+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;
+}
+
+/* handle an incoming Next Protocol Negotiation extension. */
+SECStatus
+ssl3_ServerHandleNextProtoNegoXtn(const sslSocket *ss, TLSExtensionData *xtnData, 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;
+ }
+
+ xtnData->negotiated[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) {
+ return SECFailure;
+ }
+ offset = newOffset;
+ }
+
+ return SECSuccess;
+}
+
+/* protocol selection handler for ALPN (server side) and NPN (client side) */
+static SECStatus
+ssl3_SelectAppProtocol(const sslSocket *ss, TLSExtensionData *xtnData,
+ PRUint16 ex_type, SECItem *data)
+{
+ SECStatus rv;
+ unsigned char resultBuffer[255];
+ SECItem result = { siBuffer, resultBuffer, 0 };
+
+ rv = ssl3_ValidateNextProtoNego(data->data, data->len);
+ if (rv != SECSuccess) {
+ ssl3_ExtSendAlert(ss, alert_fatal, decode_error);
+ PORT_SetError(SSL_ERROR_NEXT_PROTOCOL_DATA_INVALID);
+ return rv;
+ }
+
+ PORT_Assert(ss->nextProtoCallback);
+ /* For ALPN, the cipher suite isn't selected yet. Note that extensions
+ * sometimes affect what cipher suite is selected, e.g., for ECC. */
+ PORT_Assert((ss->ssl3.hs.preliminaryInfo &
+ ssl_preinfo_all & ~ssl_preinfo_cipher_suite) ==
+ (ssl_preinfo_all & ~ssl_preinfo_cipher_suite));
+ rv = ss->nextProtoCallback(ss->nextProtoArg, ss->fd, data->data, data->len,
+ result.data, &result.len, sizeof(resultBuffer));
+ if (rv != SECSuccess) {
+ /* Expect callback to call PORT_SetError() */
+ ssl3_ExtSendAlert(ss, alert_fatal, internal_error);
+ return SECFailure;
+ }
+
+ /* 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);
+ /* TODO: crash */
+ return SECFailure;
+ }
+
+ SECITEM_FreeItem(&xtnData->nextProto, PR_FALSE);
+
+ if (ex_type == ssl_app_layer_protocol_xtn &&
+ xtnData->nextProtoState != SSL_NEXT_PROTO_NEGOTIATED) {
+ /* The callback might say OK, but then it picks a default value - one
+ * that was not listed. That's OK for NPN, but not ALPN. */
+ ssl3_ExtSendAlert(ss, alert_fatal, no_application_protocol);
+ PORT_SetError(SSL_ERROR_NEXT_PROTOCOL_NO_PROTOCOL);
+ return SECFailure;
+ }
+
+ xtnData->negotiated[xtnData->numNegotiated++] = ex_type;
+ return SECITEM_CopyItem(NULL, &xtnData->nextProto, &result);
+}
+
+/* handle an incoming ALPN extension at the server */
+SECStatus
+ssl3_ServerHandleAppProtoXtn(const sslSocket *ss, TLSExtensionData *xtnData, PRUint16 ex_type, SECItem *data)
+{
+ int count;
+ SECStatus rv;
+
+ /* We expressly don't want to allow ALPN on renegotiation,
+ * despite it being permitted by the spec. */
+ if (ss->firstHsDone || data->len == 0) {
+ /* Clients MUST send a non-empty ALPN extension. */
+ ssl3_ExtSendAlert(ss, alert_fatal, illegal_parameter);
+ PORT_SetError(SSL_ERROR_NEXT_PROTOCOL_DATA_INVALID);
+ return SECFailure;
+ }
+
+ /* Unlike NPN, ALPN has extra redundant length information so that
+ * the extension is the same in both ClientHello and ServerHello. */
+ count = ssl3_ExtConsumeHandshakeNumber(ss, 2, &data->data, &data->len);
+ if (count != data->len) {
+ ssl3_ExtDecodeError(ss);
+ return SECFailure;
+ }
+
+ if (!ss->nextProtoCallback) {
+ /* we're not configured for it */
+ return SECSuccess;
+ }
+
+ rv = ssl3_SelectAppProtocol(ss, xtnData, ex_type, data);
+ if (rv != SECSuccess) {
+ return rv;
+ }
+
+ /* prepare to send back a response, if we negotiated */
+ if (xtnData->nextProtoState == SSL_NEXT_PROTO_NEGOTIATED) {
+ rv = ssl3_RegisterExtensionSender(
+ ss, xtnData, ex_type, ssl3_ServerSendAppProtoXtn);
+ if (rv != SECSuccess) {
+ ssl3_ExtSendAlert(ss, alert_fatal, internal_error);
+ PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
+ return rv;
+ }
+ }
+ return SECSuccess;
+}
+
+SECStatus
+ssl3_ClientHandleNextProtoNegoXtn(const sslSocket *ss, TLSExtensionData *xtnData, PRUint16 ex_type,
+ SECItem *data)
+{
+ PORT_Assert(!ss->firstHsDone);
+
+ if (ssl3_ExtensionNegotiated(ss, ssl_app_layer_protocol_xtn)) {
+ /* If the server negotiated ALPN then it has already told us what
+ * protocol to use, so it doesn't make sense for us to try to negotiate
+ * a different one by sending the NPN handshake message. However, if
+ * we've negotiated NPN then we're required to send the NPN handshake
+ * message. Thus, these two extensions cannot both be negotiated on the
+ * same connection. */
+ ssl3_ExtSendAlert(ss, alert_fatal, illegal_parameter);
+ PORT_SetError(SSL_ERROR_BAD_SERVER);
+ return SECFailure;
+ }
+
+ /* We should only get this call if we sent the extension, so
+ * ss->nextProtoCallback needs to be non-NULL. However, it is possible
+ * that an application erroneously cleared the callback between the time
+ * we sent the ClientHello and now. */
+ if (!ss->nextProtoCallback) {
+ PORT_Assert(0);
+ ssl3_ExtSendAlert(ss, alert_fatal, internal_error);
+ PORT_SetError(SSL_ERROR_NEXT_PROTOCOL_NO_CALLBACK);
+ return SECFailure;
+ }
+
+ return ssl3_SelectAppProtocol(ss, xtnData, ex_type, data);
+}
+
+SECStatus
+ssl3_ClientHandleAppProtoXtn(const sslSocket *ss, TLSExtensionData *xtnData, PRUint16 ex_type, SECItem *data)
+{
+ SECStatus rv;
+ PRInt32 list_len;
+ SECItem protocol_name;
+
+ if (ssl3_ExtensionNegotiated(ss, ssl_next_proto_nego_xtn)) {
+ PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
+ return SECFailure;
+ }
+
+ /* The extension data from the server has the following format:
+ * uint16 name_list_len;
+ * uint8 len; // where len >= 1
+ * uint8 protocol_name[len]; */
+ if (data->len < 4 || data->len > 2 + 1 + 255) {
+ ssl3_ExtSendAlert(ss, alert_fatal, decode_error);
+ PORT_SetError(SSL_ERROR_NEXT_PROTOCOL_DATA_INVALID);
+ return SECFailure;
+ }
+
+ list_len = ssl3_ExtConsumeHandshakeNumber(ss, 2, &data->data, &data->len);
+ /* The list has to be the entire extension. */
+ if (list_len != data->len) {
+ ssl3_ExtSendAlert(ss, alert_fatal, decode_error);
+ PORT_SetError(SSL_ERROR_NEXT_PROTOCOL_DATA_INVALID);
+ return SECFailure;
+ }
+
+ rv = ssl3_ExtConsumeHandshakeVariable(ss, &protocol_name, 1,
+ &data->data, &data->len);
+ /* The list must have exactly one value. */
+ if (rv != SECSuccess || data->len != 0) {
+ ssl3_ExtSendAlert(ss, alert_fatal, decode_error);
+ PORT_SetError(SSL_ERROR_NEXT_PROTOCOL_DATA_INVALID);
+ return SECFailure;
+ }
+
+ SECITEM_FreeItem(&xtnData->nextProto, PR_FALSE);
+ xtnData->nextProtoState = SSL_NEXT_PROTO_SELECTED;
+ xtnData->negotiated[xtnData->numNegotiated++] = ex_type;
+ return SECITEM_CopyItem(NULL, &xtnData->nextProto, &protocol_name);
+}
+
+PRInt32
+ssl3_ClientSendNextProtoNegoXtn(const sslSocket *ss, TLSExtensionData *xtnData, PRBool append,
+ PRUint32 maxBytes)
+{
+ PRInt32 extension_length;
+
+ /* Renegotiations do not send this extension. */
+ if (!ss->opt.enableNPN || !ss->nextProtoCallback || ss->firstHsDone) {
+ return 0;
+ }
+
+ extension_length = 4;
+
+ if (maxBytes < (PRUint32)extension_length) {
+ return 0;
+ }
+ if (append) {
+ SECStatus rv;
+ rv = ssl3_ExtAppendHandshakeNumber(ss, ssl_next_proto_nego_xtn, 2);
+ if (rv != SECSuccess)
+ goto loser;
+ rv = ssl3_ExtAppendHandshakeNumber(ss, 0, 2);
+ if (rv != SECSuccess)
+ goto loser;
+ xtnData->advertised[xtnData->numAdvertised++] =
+ ssl_next_proto_nego_xtn;
+ }
+
+ return extension_length;
+
+loser:
+ return -1;
+}
+
+PRInt32
+ssl3_ClientSendAppProtoXtn(const sslSocket *ss, TLSExtensionData *xtnData, PRBool append, PRUint32 maxBytes)
+{
+ PRInt32 extension_length;
+ unsigned char *alpn_protos = NULL;
+
+ /* Renegotiations do not send this extension. */
+ if (!ss->opt.enableALPN || !ss->opt.nextProtoNego.data || ss->firstHsDone) {
+ return 0;
+ }
+
+ extension_length = 2 /* extension type */ + 2 /* extension length */ +
+ 2 /* protocol name list length */ +
+ ss->opt.nextProtoNego.len;
+
+ if (maxBytes < (PRUint32)extension_length) {
+ return 0;
+ }
+ if (append) {
+ /* NPN requires that the client's fallback protocol is first in the
+ * list. However, ALPN sends protocols in preference order. So we
+ * allocate a buffer and move the first protocol to the end of the
+ * list. */
+ SECStatus rv;
+ const unsigned int len = ss->opt.nextProtoNego.len;
+
+ alpn_protos = PORT_Alloc(len);
+ if (alpn_protos == NULL) {
+ return SECFailure;
+ }
+ if (len > 0) {
+ /* Each protocol string is prefixed with a single byte length. */
+ unsigned int i = ss->opt.nextProtoNego.data[0] + 1;
+ if (i <= len) {
+ memcpy(alpn_protos, &ss->opt.nextProtoNego.data[i], len - i);
+ memcpy(alpn_protos + len - i, ss->opt.nextProtoNego.data, i);
+ } else {
+ /* This seems to be invalid data so we'll send as-is. */
+ memcpy(alpn_protos, ss->opt.nextProtoNego.data, len);
+ }
+ }
+
+ rv = ssl3_ExtAppendHandshakeNumber(ss, ssl_app_layer_protocol_xtn, 2);
+ if (rv != SECSuccess) {
+ goto loser;
+ }
+ rv = ssl3_ExtAppendHandshakeNumber(ss, extension_length - 4, 2);
+ if (rv != SECSuccess) {
+ goto loser;
+ }
+ rv = ssl3_ExtAppendHandshakeVariable(ss, alpn_protos, len, 2);
+ PORT_Free(alpn_protos);
+ alpn_protos = NULL;
+ if (rv != SECSuccess) {
+ goto loser;
+ }
+ xtnData->advertised[xtnData->numAdvertised++] =
+ ssl_app_layer_protocol_xtn;
+ }
+
+ return extension_length;
+
+loser:
+ if (alpn_protos) {
+ PORT_Free(alpn_protos);
+ }
+ return -1;
+}
+
+PRInt32
+ssl3_ServerSendAppProtoXtn(const sslSocket *ss, TLSExtensionData *xtnData, PRBool append, PRUint32 maxBytes)
+{
+ PRInt32 extension_length;
+
+ /* we're in over our heads if any of these fail */
+ PORT_Assert(ss->opt.enableALPN);
+ PORT_Assert(xtnData->nextProto.data);
+ PORT_Assert(xtnData->nextProto.len > 0);
+ PORT_Assert(xtnData->nextProtoState == SSL_NEXT_PROTO_NEGOTIATED);
+ PORT_Assert(!ss->firstHsDone);
+
+ extension_length = 2 /* extension type */ + 2 /* extension length */ +
+ 2 /* protocol name list */ + 1 /* name length */ +
+ xtnData->nextProto.len;
+
+ if (maxBytes < (PRUint32)extension_length) {
+ return 0;
+ }
+ if (append) {
+ SECStatus rv;
+ rv = ssl3_ExtAppendHandshakeNumber(ss, ssl_app_layer_protocol_xtn, 2);
+ if (rv != SECSuccess) {
+ return -1;
+ }
+ rv = ssl3_ExtAppendHandshakeNumber(ss, extension_length - 4, 2);
+ if (rv != SECSuccess) {
+ return -1;
+ }
+ rv = ssl3_ExtAppendHandshakeNumber(ss, xtnData->nextProto.len + 1, 2);
+ if (rv != SECSuccess) {
+ return -1;
+ }
+ rv = ssl3_ExtAppendHandshakeVariable(ss, xtnData->nextProto.data,
+ xtnData->nextProto.len, 1);
+ if (rv != SECSuccess) {
+ return -1;
+ }
+ }
+
+ return extension_length;
+}
+
+SECStatus
+ssl3_ServerHandleStatusRequestXtn(const sslSocket *ss, TLSExtensionData *xtnData, PRUint16 ex_type,
+ SECItem *data)
+{
+ ssl3HelloExtensionSenderFunc sender;
+
+ PORT_Assert(ss->sec.isServer);
+
+ /* remember that we got this extension. */
+ xtnData->negotiated[xtnData->numNegotiated++] = ex_type;
+
+ if (ss->version >= SSL_LIBRARY_VERSION_TLS_1_3) {
+ sender = tls13_ServerSendStatusRequestXtn;
+ } else {
+ sender = ssl3_ServerSendStatusRequestXtn;
+ }
+ return ssl3_RegisterExtensionSender(ss, xtnData, ex_type, sender);
+}
+
+PRInt32
+ssl3_ServerSendStatusRequestXtn(
+ const sslSocket *ss,
+ TLSExtensionData *xtnData,
+ PRBool append,
+ PRUint32 maxBytes)
+{
+ PRInt32 extension_length;
+ const sslServerCert *serverCert = ss->sec.serverCert;
+ SECStatus rv;
+
+ if (!serverCert->certStatusArray ||
+ !serverCert->certStatusArray->len) {
+ return 0;
+ }
+
+ extension_length = 2 + 2;
+ if (maxBytes < (PRUint32)extension_length) {
+ return 0;
+ }
+ if (append) {
+ /* extension_type */
+ rv = ssl3_ExtAppendHandshakeNumber(ss, ssl_cert_status_xtn, 2);
+ if (rv != SECSuccess)
+ return -1;
+ /* length of extension_data */
+ rv = ssl3_ExtAppendHandshakeNumber(ss, 0, 2);
+ if (rv != SECSuccess)
+ return -1;
+ /* The certificate status data is sent in ssl3_SendCertificateStatus. */
+ }
+
+ return extension_length;
+}
+
+/* ssl3_ClientSendStatusRequestXtn builds the status_request extension on the
+ * client side. See RFC 6066 section 8. */
+PRInt32
+ssl3_ClientSendStatusRequestXtn(const sslSocket *ss, TLSExtensionData *xtnData, 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 (maxBytes < (PRUint32)extension_length) {
+ PORT_Assert(0);
+ return 0;
+ }
+ if (append) {
+ SECStatus rv;
+
+ /* extension_type */
+ rv = ssl3_ExtAppendHandshakeNumber(ss, ssl_cert_status_xtn, 2);
+ if (rv != SECSuccess)
+ return -1;
+ rv = ssl3_ExtAppendHandshakeNumber(ss, extension_length - 4, 2);
+ if (rv != SECSuccess)
+ return -1;
+ rv = ssl3_ExtAppendHandshakeNumber(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_ExtAppendHandshakeNumber(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_ExtAppendHandshakeNumber(ss, 0, 2);
+ if (rv != SECSuccess)
+ return -1;
+
+ xtnData->advertised[xtnData->numAdvertised++] = ssl_cert_status_xtn;
+ }
+ return extension_length;
+}
+
+SECStatus
+ssl3_ClientHandleStatusRequestXtn(const sslSocket *ss, TLSExtensionData *xtnData, PRUint16 ex_type,
+ SECItem *data)
+{
+ /* In TLS 1.3, the extension carries the OCSP response. */
+ if (ss->version >= SSL_LIBRARY_VERSION_TLS_1_3) {
+ SECStatus rv;
+ rv = ssl_ReadCertificateStatus(CONST_CAST(sslSocket, ss),
+ data->data, data->len);
+ if (rv != SECSuccess) {
+ return SECFailure; /* code already set */
+ }
+ } else if (data->len != 0) {
+ ssl3_ExtSendAlert(ss, alert_fatal, illegal_parameter);
+ PORT_SetError(SSL_ERROR_RX_MALFORMED_SERVER_HELLO);
+ return SECFailure;
+ }
+
+ /* Keep track of negotiated extensions. */
+ xtnData->negotiated[xtnData->numNegotiated++] = ex_type;
+ return SECSuccess;
+}
+
+/*
+ * Called from ssl3_SendNewSessionTicket, tls13_SendNewSessionTicket
+ */
+SECStatus
+ssl3_EncodeSessionTicket(sslSocket *ss,
+ const NewSessionTicket *ticket,
+ SECItem *ticket_data)
+{
+ PRUint32 i;
+ SECStatus rv;
+ SECItem plaintext;
+ SECItem plaintext_item = { 0, NULL, 0 };
+ SECItem ciphertext = { 0, NULL, 0 };
+ PRUint32 ciphertext_length;
+ SECItem ticket_buf = { 0, NULL, 0 };
+ SECItem ticket_tmp = { 0, NULL, 0 };
+ SECItem macParam = { 0, NULL, 0 };
+ PRBool ms_is_wrapped;
+ unsigned char wrapped_ms[SSL3_MASTER_SECRET_LENGTH];
+ SECItem ms_item = { 0, NULL, 0 };
+ PRUint32 padding_length;
+ PRUint32 ticket_length;
+ PRUint32 cert_length = 0;
+ PRUint8 length_buf[4];
+ PRUint32 now;
+ PK11SymKey *aes_key = NULL;
+ PK11SymKey *mac_key = NULL;
+ CK_MECHANISM_TYPE cipherMech = CKM_AES_CBC;
+ PK11Context *aes_ctx;
+ CK_MECHANISM_TYPE macMech = CKM_SHA256_HMAC;
+ PK11Context *hmac_ctx = NULL;
+ 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 */
+ ssl3CipherSpec *spec;
+ const sslServerCertType *certType;
+ SECItem alpnSelection = { siBuffer, NULL, 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));
+
+ if (ss->opt.requestCertificate && ss->sec.ci.sid->peerCert) {
+ cert_length = 3 + ss->sec.ci.sid->peerCert->derCert.len;
+ }
+
+ /* Get IV and encryption keys */
+ ivItem.data = iv;
+ ivItem.len = sizeof(iv);
+ rv = PK11_GenerateRandom(iv, sizeof(iv));
+ if (rv != SECSuccess)
+ goto loser;
+
+ rv = ssl3_GetSessionTicketKeys(ss, &aes_key, &mac_key);
+ if (rv != SECSuccess)
+ goto loser;
+
+ if (ss->version >= SSL_LIBRARY_VERSION_TLS_1_3) {
+ spec = ss->ssl3.cwSpec;
+ } else {
+ spec = ss->ssl3.pwSpec;
+ }
+ if (spec->msItem.len && spec->msItem.data) {
+ /* The master secret is available unwrapped. */
+ ms_item.data = spec->msItem.data;
+ ms_item.len = spec->msItem.len;
+ ms_is_wrapped = PR_FALSE;
+ } else {
+ /* Extract the master secret wrapped. */
+ sslSessionID sid;
+ PORT_Memset(&sid, 0, sizeof(sslSessionID));
+
+ rv = ssl3_CacheWrappedMasterSecret(ss, &sid, spec,
+ ss->ssl3.hs.kea_def->authKeyType);
+ 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->sec.ci.sid->u.ssl3.srvName;
+ if (srvName->data && srvName->len) {
+ srvNameLen = 2 + srvName->len; /* len bytes + name len */
+ }
+
+ if (ss->xtnData.nextProtoState != SSL_NEXT_PROTO_NO_SUPPORT &&
+ ss->xtnData.nextProto.data) {
+ alpnSelection = ss->xtnData.nextProto;
+ }
+
+ ciphertext_length =
+ sizeof(PRUint16) /* ticket_version */
+ + sizeof(SSL3ProtocolVersion) /* ssl_version */
+ + sizeof(ssl3CipherSuite) /* ciphersuite */
+ + 1 /* compression */
+ + 10 /* cipher spec parameters */
+ + 1 /* certType arguments */
+ + 1 /* SessionTicket.ms_is_wrapped */
+ + 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 */
+ + 1 /* extendedMasterSecretUsed */
+ + sizeof(ticket->ticket_lifetime_hint) /* ticket lifetime hint */
+ + sizeof(ticket->flags) /* ticket flags */
+ + 1 + alpnSelection.len; /* npn value + length field. */
+ padding_length = AES_BLOCK_SIZE -
+ (ciphertext_length %
+ AES_BLOCK_SIZE);
+ ciphertext_length += padding_length;
+
+ 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.authType, 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;
+
+ /* certificate type */
+ certType = &ss->sec.serverCert->certType;
+ PORT_Assert(certType->authType == ss->sec.authType);
+ switch (ss->sec.authType) {
+ case ssl_auth_ecdsa:
+ case ssl_auth_ecdh_rsa:
+ case ssl_auth_ecdh_ecdsa:
+ PORT_Assert(certType->namedCurve);
+ PORT_Assert(certType->namedCurve->keaType == ssl_kea_ecdh);
+ /* EC curves only use the second of the two bytes. */
+ PORT_Assert(certType->namedCurve->name < 256);
+ rv = ssl3_AppendNumberToItem(&plaintext,
+ certType->namedCurve->name, 1);
+ break;
+ default:
+ rv = ssl3_AppendNumberToItem(&plaintext, 0, 1);
+ break;
+ }
+ if (rv != SECSuccess)
+ goto loser;
+
+ /* master_secret */
+ rv = ssl3_AppendNumberToItem(&plaintext, ms_is_wrapped, 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;
+ }
+
+ /* extendedMasterSecretUsed */
+ rv = ssl3_AppendNumberToItem(
+ &plaintext, ss->sec.ci.sid->u.ssl3.keys.extendedMasterSecretUsed, 1);
+ if (rv != SECSuccess)
+ goto loser;
+
+ /* Flags */
+ rv = ssl3_AppendNumberToItem(&plaintext, ticket->flags,
+ sizeof(ticket->flags));
+ if (rv != SECSuccess)
+ goto loser;
+
+ /* NPN value. */
+ PORT_Assert(alpnSelection.len < 256);
+ rv = ssl3_AppendNumberToItem(&plaintext, alpnSelection.len, 1);
+ if (rv != SECSuccess)
+ goto loser;
+ if (alpnSelection.len) {
+ rv = ssl3_AppendToItem(&plaintext, alpnSelection.data, alpnSelection.len);
+ 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. */
+ PORT_Assert(aes_key);
+ aes_ctx = PK11_CreateContextBySymKey(cipherMech, CKA_ENCRYPT, aes_key, &ivItem);
+ if (!aes_ctx)
+ goto loser;
+
+ rv = PK11_CipherOp(aes_ctx, ciphertext.data,
+ (int *)&ciphertext.len, ciphertext.len,
+ plaintext_item.data, plaintext_item.len);
+ PK11_Finalize(aes_ctx);
+ PK11_DestroyContext(aes_ctx, 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. */
+ PORT_Assert(mac_key);
+ hmac_ctx = PK11_CreateContextBySymKey(macMech, CKA_SIGN, mac_key, &macParam);
+ if (!hmac_ctx)
+ goto loser;
+
+ rv = PK11_DigestBegin(hmac_ctx);
+ if (rv != SECSuccess)
+ goto loser;
+ rv = PK11_DigestOp(hmac_ctx, key_name, SESS_TICKET_KEY_NAME_LEN);
+ if (rv != SECSuccess)
+ goto loser;
+ rv = PK11_DigestOp(hmac_ctx, iv, sizeof(iv));
+ if (rv != SECSuccess)
+ goto loser;
+ rv = PK11_DigestOp(hmac_ctx, (unsigned char *)length_buf, 2);
+ if (rv != SECSuccess)
+ goto loser;
+ rv = PK11_DigestOp(hmac_ctx, ciphertext.data, ciphertext.len);
+ if (rv != SECSuccess)
+ goto loser;
+ rv = PK11_DigestFinal(hmac_ctx, computed_mac,
+ &computed_mac_length, sizeof(computed_mac));
+ if (rv != SECSuccess)
+ goto loser;
+
+ ticket_length =
+ +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, &ticket_buf, ticket_length) == NULL) {
+ rv = SECFailure;
+ goto loser;
+ }
+ ticket_tmp = ticket_buf; /* Shallow copy because AppendToItem is
+ * destructive. */
+
+ rv = ssl3_AppendToItem(&ticket_tmp, key_name, SESS_TICKET_KEY_NAME_LEN);
+ if (rv != SECSuccess)
+ goto loser;
+
+ rv = ssl3_AppendToItem(&ticket_tmp, iv, sizeof(iv));
+ if (rv != SECSuccess)
+ goto loser;
+
+ rv = ssl3_AppendNumberToItem(&ticket_tmp, ciphertext.len, 2);
+ if (rv != SECSuccess)
+ goto loser;
+
+ rv = ssl3_AppendToItem(&ticket_tmp, ciphertext.data, ciphertext.len);
+ if (rv != SECSuccess)
+ goto loser;
+
+ rv = ssl3_AppendToItem(&ticket_tmp, computed_mac, computed_mac_length);
+ if (rv != SECSuccess)
+ goto loser;
+
+ /* Give ownership of memory to caller. */
+ *ticket_data = ticket_buf;
+ ticket_buf.data = NULL;
+
+loser:
+ if (hmac_ctx) {
+ PK11_DestroyContext(hmac_ctx, PR_TRUE);
+ }
+ if (plaintext_item.data) {
+ SECITEM_FreeItem(&plaintext_item, PR_FALSE);
+ }
+ if (ciphertext.data) {
+ SECITEM_FreeItem(&ciphertext, PR_FALSE);
+ }
+ if (ticket_buf.data) {
+ SECITEM_FreeItem(&ticket_buf, PR_FALSE);
+ }
+
+ return rv;
+}
+
+/* When a client receives a SessionTicket extension a NewSessionTicket
+ * message is expected during the handshake.
+ */
+SECStatus
+ssl3_ClientHandleSessionTicketXtn(const sslSocket *ss, TLSExtensionData *xtnData, PRUint16 ex_type,
+ SECItem *data)
+{
+ if (data->len != 0) {
+ return SECSuccess; /* Ignore the extension. */
+ }
+
+ /* Keep track of negotiated extensions. */
+ xtnData->negotiated[xtnData->numNegotiated++] = ex_type;
+ return SECSuccess;
+}
+
+/* Generic ticket processing code, common to TLS 1.0-1.2 and
+ * TLS 1.3. */
+SECStatus
+ssl3_ProcessSessionTicketCommon(sslSocket *ss, SECItem *data)
+{
+ SECStatus rv;
+ SECItem *decrypted_state = NULL;
+ SessionTicket *parsed_session_ticket = NULL;
+ sslSessionID *sid = NULL;
+ SSL3Statistics *ssl3stats;
+ PRUint32 i;
+ SECItem extension_data;
+ EncryptedSessionTicket enc_session_ticket;
+ unsigned char computed_mac[TLS_EX_SESS_TICKET_MAC_LENGTH];
+ unsigned int computed_mac_length;
+ PK11SymKey *aes_key = NULL;
+ PK11SymKey *mac_key = NULL;
+ PK11Context *hmac_ctx;
+ CK_MECHANISM_TYPE macMech = CKM_SHA256_HMAC;
+ PK11Context *aes_ctx;
+ 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;
+ SECItem macParam = { siBuffer, NULL, 0 };
+ SECItem alpn_item;
+ SECItem ivItem;
+
+ /* 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) {
+ 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 SECSuccess; /* Pretend it isn't there */
+ }
+
+ /* Get session ticket keys. */
+ rv = ssl3_GetSessionTicketKeys(ss, &aes_key, &mac_key);
+ 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.
+ */
+ PORT_Assert(mac_key);
+ hmac_ctx = PK11_CreateContextBySymKey(macMech, CKA_SIGN, mac_key, &macParam);
+ if (!hmac_ctx) {
+ 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);
+ if (rv != SECSuccess) {
+ PK11_DestroyContext(hmac_ctx, PR_TRUE);
+ goto no_ticket;
+ }
+ rv = PK11_DigestOp(hmac_ctx, extension_data.data,
+ extension_data.len -
+ TLS_EX_SESS_TICKET_MAC_LENGTH);
+ if (rv != SECSuccess) {
+ PK11_DestroyContext(hmac_ctx, PR_TRUE);
+ goto no_ticket;
+ }
+ rv = PK11_DigestFinal(hmac_ctx, computed_mac,
+ &computed_mac_length, sizeof(computed_mac));
+ PK11_DestroyContext(hmac_ctx, 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);
+
+ PORT_Assert(aes_key);
+ ivItem.data = enc_session_ticket.iv;
+ ivItem.len = AES_BLOCK_SIZE;
+ aes_ctx = PK11_CreateContextBySymKey(cipherMech, CKA_DECRYPT,
+ aes_key, &ivItem);
+ if (!aes_ctx) {
+ SSL_DBG(("%d: SSL[%d]: Unable to create AES context.",
+ SSL_GETPID(), ss->fd));
+ goto no_ticket;
+ }
+
+ rv = PK11_CipherOp(aes_ctx, 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);
+ PK11_DestroyContext(aes_ctx, 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 and reject if the version is wrong */
+ temp = ssl3_ExtConsumeHandshakeNumber(ss, 2, &buffer, &buffer_len);
+ if (temp != TLS_EX_SESS_TICKET_VERSION)
+ goto no_ticket;
+
+ parsed_session_ticket->ticket_version = (SSL3ProtocolVersion)temp;
+
+ /* Read SSLVersion. */
+ temp = ssl3_ExtConsumeHandshakeNumber(ss, 2, &buffer, &buffer_len);
+ if (temp < 0)
+ goto no_ticket;
+ parsed_session_ticket->ssl_version = (SSL3ProtocolVersion)temp;
+
+ /* Read cipher_suite. */
+ temp = ssl3_ExtConsumeHandshakeNumber(ss, 2, &buffer, &buffer_len);
+ if (temp < 0)
+ goto no_ticket;
+ parsed_session_ticket->cipher_suite = (ssl3CipherSuite)temp;
+
+ /* Read compression_method. */
+ temp = ssl3_ExtConsumeHandshakeNumber(ss, 1, &buffer, &buffer_len);
+ if (temp < 0)
+ goto no_ticket;
+ parsed_session_ticket->compression_method = (SSLCompressionMethod)temp;
+
+ /* Read cipher spec parameters. */
+ temp = ssl3_ExtConsumeHandshakeNumber(ss, 1, &buffer, &buffer_len);
+ if (temp < 0)
+ goto no_ticket;
+ parsed_session_ticket->authType = (SSLAuthType)temp;
+ temp = ssl3_ExtConsumeHandshakeNumber(ss, 4, &buffer, &buffer_len);
+ if (temp < 0)
+ goto no_ticket;
+ parsed_session_ticket->authKeyBits = (PRUint32)temp;
+ temp = ssl3_ExtConsumeHandshakeNumber(ss, 1, &buffer, &buffer_len);
+ if (temp < 0)
+ goto no_ticket;
+ parsed_session_ticket->keaType = (SSLKEAType)temp;
+ temp = ssl3_ExtConsumeHandshakeNumber(ss, 4, &buffer, &buffer_len);
+ if (temp < 0)
+ goto no_ticket;
+ parsed_session_ticket->keaKeyBits = (PRUint32)temp;
+
+ /* Read certificate slot */
+ parsed_session_ticket->certType.authType = parsed_session_ticket->authType;
+ temp = ssl3_ExtConsumeHandshakeNumber(ss, 1, &buffer, &buffer_len);
+ if (temp < 0)
+ goto no_ticket;
+ switch (parsed_session_ticket->authType) {
+ case ssl_auth_ecdsa:
+ case ssl_auth_ecdh_rsa:
+ case ssl_auth_ecdh_ecdsa: {
+ const sslNamedGroupDef *group =
+ ssl_LookupNamedGroup((SSLNamedGroup)temp);
+ if (!group || group->keaType != ssl_kea_ecdh) {
+ goto no_ticket;
+ }
+ parsed_session_ticket->certType.namedCurve = group;
+ } break;
+ default:
+ break;
+ }
+
+ /* Read wrapped master_secret. */
+ temp = ssl3_ExtConsumeHandshakeNumber(ss, 1, &buffer, &buffer_len);
+ if (temp < 0)
+ goto no_ticket;
+ parsed_session_ticket->ms_is_wrapped = (PRBool)temp;
+
+ temp = ssl3_ExtConsumeHandshakeNumber(ss, 4, &buffer, &buffer_len);
+ if (temp < 0)
+ goto no_ticket;
+ parsed_session_ticket->msWrapMech = (CK_MECHANISM_TYPE)temp;
+
+ temp = ssl3_ExtConsumeHandshakeNumber(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 < parsed_session_ticket->ms_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_ExtConsumeHandshakeNumber(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_ExtConsumeHandshakeVariable(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_ExtConsumeHandshakeNumber(ss, 4, &buffer, &buffer_len);
+ if (temp < 0)
+ goto no_ticket;
+ parsed_session_ticket->timestamp = (PRUint32)temp;
+
+ /* Read server name */
+ nameType =
+ ssl3_ExtConsumeHandshakeNumber(ss, 1, &buffer, &buffer_len);
+ if (nameType != TLS_STE_NO_SERVER_NAME) {
+ SECItem name_item;
+ rv = ssl3_ExtConsumeHandshakeVariable(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;
+ }
+
+ /* Read extendedMasterSecretUsed */
+ temp = ssl3_ExtConsumeHandshakeNumber(ss, 1, &buffer, &buffer_len);
+ if (temp < 0)
+ goto no_ticket;
+ PORT_Assert(temp == PR_TRUE || temp == PR_FALSE);
+ parsed_session_ticket->extendedMasterSecretUsed = (PRBool)temp;
+
+ rv = ssl3_ExtConsumeHandshake(ss, &parsed_session_ticket->flags, 4,
+ &buffer, &buffer_len);
+ if (rv != SECSuccess)
+ goto no_ticket;
+ parsed_session_ticket->flags = PR_ntohl(parsed_session_ticket->flags);
+
+ rv = ssl3_ExtConsumeHandshakeVariable(ss, &alpn_item, 1, &buffer, &buffer_len);
+ if (rv != SECSuccess)
+ goto no_ticket;
+ if (alpn_item.len != 0) {
+ rv = SECITEM_CopyItem(NULL, &parsed_session_ticket->alpnSelection,
+ &alpn_item);
+ if (rv != SECSuccess)
+ goto no_ticket;
+ if (alpn_item.len >= 256)
+ goto no_ticket;
+ }
+
+ /* 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->authType = parsed_session_ticket->authType;
+ sid->authKeyBits = parsed_session_ticket->authKeyBits;
+ sid->keaType = parsed_session_ticket->keaType;
+ sid->keaKeyBits = parsed_session_ticket->keaKeyBits;
+ memcpy(&sid->certType, &parsed_session_ticket->certType,
+ sizeof(sslServerCertType));
+
+ if (SECITEM_CopyItem(NULL, &sid->u.ssl3.locked.sessionTicket.ticket,
+ &extension_data) != SECSuccess)
+ goto no_ticket;
+ sid->u.ssl3.locked.sessionTicket.flags = parsed_session_ticket->flags;
+
+ 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.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;
+ sid->u.ssl3.keys.extendedMasterSecretUsed = parsed_session_ticket->extendedMasterSecretUsed;
+
+ /* 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) {
+ if (sid->u.ssl3.srvName.data) {
+ SECITEM_FreeItem(&sid->u.ssl3.srvName, PR_FALSE);
+ }
+ sid->u.ssl3.srvName = parsed_session_ticket->srvName;
+ }
+ if (parsed_session_ticket->alpnSelection.data != NULL) {
+ sid->u.ssl3.alpnSelection = parsed_session_ticket->alpnSelection;
+ /* So we don't free below. */
+ parsed_session_ticket->alpnSelection.data = NULL;
+ }
+ 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);
+ }
+ if (parsed_session_ticket->alpnSelection.data) {
+ SECITEM_FreeItem(&parsed_session_ticket->alpnSelection, PR_FALSE);
+ }
+ PORT_ZFree(parsed_session_ticket, sizeof(SessionTicket));
+ }
+
+ return rv;
+}
+
+SECStatus
+ssl3_ServerHandleSessionTicketXtn(const sslSocket *ss, TLSExtensionData *xtnData, PRUint16 ex_type,
+ SECItem *data)
+{
+
+ /* Ignore the SessionTicket extension if processing is disabled. */
+ if (!ss->opt.enableSessionTickets) {
+ return SECSuccess;
+ }
+
+ /* If we are doing TLS 1.3, then ignore this. */
+ if (ss->version >= SSL_LIBRARY_VERSION_TLS_1_3) {
+ return SECSuccess;
+ }
+
+ /* Keep track of negotiated extensions. */
+ xtnData->negotiated[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) {
+ xtnData->emptySessionTicket = PR_TRUE;
+ return SECSuccess;
+ }
+
+ return ssl3_ProcessSessionTicketCommon(CONST_CAST(sslSocket, ss), data);
+}
+
+/*
+ * 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;
+}
+
+/* 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)
+ */
+PRInt32
+ssl3_SendRenegotiationInfoXtn(
+ const sslSocket *ss,
+ TLSExtensionData *xtnData,
+ PRBool append,
+ PRUint32 maxBytes)
+{
+ PRInt32 len = 0;
+ PRInt32 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;
+ if (ss->firstHsDone) {
+ len = ss->sec.isServer ? ss->ssl3.hs.finishedBytes * 2
+ : ss->ssl3.hs.finishedBytes;
+ }
+ needed = 5 + len;
+ if (maxBytes < (PRUint32)needed) {
+ return 0;
+ }
+ if (append) {
+ SECStatus rv;
+ /* extension_type */
+ rv = ssl3_ExtAppendHandshakeNumber(ss, ssl_renegotiation_info_xtn, 2);
+ if (rv != SECSuccess)
+ return -1;
+ /* length of extension_data */
+ rv = ssl3_ExtAppendHandshakeNumber(ss, len + 1, 2);
+ if (rv != SECSuccess)
+ return -1;
+ /* verify_Data from previous Finished message(s) */
+ rv = ssl3_ExtAppendHandshakeVariable(ss,
+ ss->ssl3.hs.finishedMsgs.data, len, 1);
+ if (rv != SECSuccess)
+ return -1;
+ if (!ss->sec.isServer) {
+ xtnData->advertised[xtnData->numAdvertised++] =
+ ssl_renegotiation_info_xtn;
+ }
+ }
+ return needed;
+}
+
+/* This function runs in both the client and server. */
+SECStatus
+ssl3_HandleRenegotiationInfoXtn(const sslSocket *ss, TLSExtensionData *xtnData, 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) {
+ ssl3_ExtDecodeError(ss);
+ return SECFailure;
+ }
+ if (len && NSS_SecureMemcmp(ss->ssl3.hs.finishedMsgs.data,
+ data->data + 1, len)) {
+ ssl3_ExtSendAlert(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. */
+ CONST_CAST(sslSocket, ss)
+ ->peerRequestedProtection = 1;
+ xtnData->negotiated[xtnData->numNegotiated++] = ex_type;
+ if (ss->sec.isServer) {
+ /* prepare to send back the appropriate response */
+ rv = ssl3_RegisterExtensionSender(ss, xtnData, ex_type,
+ ssl3_SendRenegotiationInfoXtn);
+ }
+ return rv;
+}
+
+PRInt32
+ssl3_ClientSendUseSRTPXtn(const sslSocket *ss, TLSExtensionData *xtnData, PRBool append, PRUint32 maxBytes)
+{
+ PRUint32 ext_data_len;
+ PRInt16 i;
+ SECStatus rv;
+
+ if (!ss)
+ return 0;
+
+ 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_ExtAppendHandshakeNumber(ss, ssl_use_srtp_xtn, 2);
+ if (rv != SECSuccess)
+ return -1;
+ /* Length of extension data */
+ rv = ssl3_ExtAppendHandshakeNumber(ss, ext_data_len, 2);
+ if (rv != SECSuccess)
+ return -1;
+ /* Length of the SRTP cipher list */
+ rv = ssl3_ExtAppendHandshakeNumber(ss,
+ 2 * ss->ssl3.dtlsSRTPCipherCount,
+ 2);
+ if (rv != SECSuccess)
+ return -1;
+ /* The SRTP ciphers */
+ for (i = 0; i < ss->ssl3.dtlsSRTPCipherCount; i++) {
+ rv = ssl3_ExtAppendHandshakeNumber(ss,
+ ss->ssl3.dtlsSRTPCiphers[i],
+ 2);
+ if (rv != SECSuccess)
+ return -1;
+ }
+ /* Empty MKI value */
+ ssl3_ExtAppendHandshakeVariable(ss, NULL, 0, 1);
+
+ xtnData->advertised[xtnData->numAdvertised++] =
+ ssl_use_srtp_xtn;
+ }
+
+ return 4 + ext_data_len;
+}
+
+PRInt32
+ssl3_ServerSendUseSRTPXtn(const sslSocket *ss, TLSExtensionData *xtnData, PRBool append, PRUint32 maxBytes)
+{
+ SECStatus rv;
+
+ /* Server side */
+ if (!append || maxBytes < 9) {
+ return 9;
+ }
+
+ /* Extension type */
+ rv = ssl3_ExtAppendHandshakeNumber(ss, ssl_use_srtp_xtn, 2);
+ if (rv != SECSuccess)
+ return -1;
+ /* Length of extension data */
+ rv = ssl3_ExtAppendHandshakeNumber(ss, 5, 2);
+ if (rv != SECSuccess)
+ return -1;
+ /* Length of the SRTP cipher list */
+ rv = ssl3_ExtAppendHandshakeNumber(ss, 2, 2);
+ if (rv != SECSuccess)
+ return -1;
+ /* The selected cipher */
+ rv = ssl3_ExtAppendHandshakeNumber(ss, xtnData->dtlsSRTPCipherSuite, 2);
+ if (rv != SECSuccess)
+ return -1;
+ /* Empty MKI value */
+ ssl3_ExtAppendHandshakeVariable(ss, NULL, 0, 1);
+
+ return 9;
+}
+
+SECStatus
+ssl3_ClientHandleUseSRTPXtn(const sslSocket *ss, TLSExtensionData *xtnData, PRUint16 ex_type, SECItem *data)
+{
+ SECStatus rv;
+ SECItem ciphers = { siBuffer, NULL, 0 };
+ PRUint16 i;
+ PRUint16 cipher = 0;
+ PRBool found = PR_FALSE;
+ SECItem litem;
+
+ if (!data->data || !data->len) {
+ ssl3_ExtDecodeError(ss);
+ return SECFailure;
+ }
+
+ /* Get the cipher list */
+ rv = ssl3_ExtConsumeHandshakeVariable(ss, &ciphers, 2,
+ &data->data, &data->len);
+ if (rv != SECSuccess) {
+ return SECFailure; /* fatal alert already sent */
+ }
+ /* Now check that the server has picked just 1 (i.e., len = 2) */
+ if (ciphers.len != 2) {
+ ssl3_ExtDecodeError(ss);
+ 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) {
+ ssl3_ExtSendAlert(ss, alert_fatal, illegal_parameter);
+ PORT_SetError(SSL_ERROR_RX_MALFORMED_SERVER_HELLO);
+ return SECFailure;
+ }
+
+ /* Get the srtp_mki value */
+ rv = ssl3_ExtConsumeHandshakeVariable(ss, &litem, 1,
+ &data->data, &data->len);
+ if (rv != SECSuccess) {
+ return SECFailure; /* alert already sent */
+ }
+
+ /* We didn't offer an MKI, so this must be 0 length */
+ if (litem.len != 0) {
+ ssl3_ExtSendAlert(ss, alert_fatal, illegal_parameter);
+ PORT_SetError(SSL_ERROR_RX_MALFORMED_SERVER_HELLO);
+ return SECFailure;
+ }
+
+ /* extra trailing bytes */
+ if (data->len != 0) {
+ ssl3_ExtDecodeError(ss);
+ return SECFailure;
+ }
+
+ /* OK, this looks fine. */
+ xtnData->negotiated[xtnData->numNegotiated++] = ssl_use_srtp_xtn;
+ xtnData->dtlsSRTPCipherSuite = cipher;
+ return SECSuccess;
+}
+
+SECStatus
+ssl3_ServerHandleUseSRTPXtn(const sslSocket *ss, TLSExtensionData *xtnData, 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 (!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) {
+ ssl3_ExtDecodeError(ss);
+ return SECFailure;
+ }
+
+ /* Get the cipher list */
+ rv = ssl3_ExtConsumeHandshakeVariable(ss, &ciphers, 2,
+ &data->data, &data->len);
+ if (rv != SECSuccess) {
+ return SECFailure; /* alert already sent */
+ }
+ /* Check that the list is even length */
+ if (ciphers.len % 2) {
+ ssl3_ExtDecodeError(ss);
+ 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_ExtConsumeHandshakeVariable(ss, &litem, 1, &data->data, &data->len);
+ if (rv != SECSuccess) {
+ return SECFailure;
+ }
+
+ if (data->len != 0) {
+ ssl3_ExtDecodeError(ss); /* trailing bytes */
+ return SECFailure;
+ }
+
+ /* Now figure out what to do */
+ if (!found) {
+ /* No matching ciphers, pretend we don't support use_srtp */
+ return SECSuccess;
+ }
+
+ /* OK, we have a valid cipher and we've selected it */
+ xtnData->dtlsSRTPCipherSuite = cipher;
+ xtnData->negotiated[xtnData->numNegotiated++] = ssl_use_srtp_xtn;
+
+ return ssl3_RegisterExtensionSender(ss, xtnData,
+ ssl_use_srtp_xtn,
+ ssl3_ServerSendUseSRTPXtn);
+}
+
+/* ssl3_ServerHandleSigAlgsXtn handles the signature_algorithms extension
+ * from a client.
+ * See https://tools.ietf.org/html/rfc5246#section-7.4.1.4.1 */
+SECStatus
+ssl3_ServerHandleSigAlgsXtn(const sslSocket *ss, TLSExtensionData *xtnData, PRUint16 ex_type, SECItem *data)
+{
+ SECStatus rv;
+
+ /* Ignore this extension if we aren't doing TLS 1.2 or greater. */
+ if (ss->version < SSL_LIBRARY_VERSION_TLS_1_2) {
+ return SECSuccess;
+ }
+
+ if (xtnData->clientSigSchemes) {
+ PORT_Free(xtnData->clientSigSchemes);
+ xtnData->clientSigSchemes = NULL;
+ }
+ rv = ssl_ParseSignatureSchemes(ss, NULL,
+ &xtnData->clientSigSchemes,
+ &xtnData->numClientSigScheme,
+ &data->data, &data->len);
+ if (rv != SECSuccess) {
+ PORT_SetError(SSL_ERROR_RX_MALFORMED_CLIENT_HELLO);
+ return SECFailure;
+ }
+ /* Check for trailing data. */
+ if (data->len != 0) {
+ ssl3_ExtSendAlert(ss, alert_fatal, decode_error);
+ PORT_SetError(SSL_ERROR_RX_MALFORMED_CLIENT_HELLO);
+ return SECFailure;
+ }
+
+ /* Keep track of negotiated extensions. */
+ xtnData->negotiated[xtnData->numNegotiated++] = ex_type;
+ return SECSuccess;
+}
+
+/* ssl3_ClientSendSigAlgsXtn sends the signature_algorithm extension for TLS
+ * 1.2 ClientHellos. */
+PRInt32
+ssl3_ClientSendSigAlgsXtn(const sslSocket *ss, TLSExtensionData *xtnData, PRBool append, PRUint32 maxBytes)
+{
+ PRInt32 extension_length;
+ PRUint8 buf[MAX_SIGNATURE_SCHEMES * 2];
+ PRUint32 len;
+ SECStatus rv;
+
+ if (ss->vrange.max < SSL_LIBRARY_VERSION_TLS_1_2) {
+ return 0;
+ }
+
+ rv = ssl3_EncodeSigAlgs(ss, buf, sizeof(buf), &len);
+ if (rv != SECSuccess) {
+ return -1;
+ }
+
+ extension_length =
+ 2 /* extension type */ +
+ 2 /* extension length */ +
+ 2 /* supported_signature_algorithms length */ +
+ len;
+
+ if (maxBytes < extension_length) {
+ PORT_Assert(0);
+ return 0;
+ }
+
+ if (append) {
+ SECStatus rv;
+ rv = ssl3_ExtAppendHandshakeNumber(ss, ssl_signature_algorithms_xtn, 2);
+ if (rv != SECSuccess) {
+ return -1;
+ }
+ rv = ssl3_ExtAppendHandshakeNumber(ss, len + 2, 2);
+ if (rv != SECSuccess) {
+ return -1;
+ }
+
+ rv = ssl3_ExtAppendHandshakeVariable(ss, buf, len, 2);
+ if (rv != SECSuccess) {
+ return -1;
+ }
+
+ xtnData->advertised[xtnData->numAdvertised++] =
+ ssl_signature_algorithms_xtn;
+ }
+
+ return extension_length;
+}
+
+/* Takes the size of the ClientHello, less the record header, and determines how
+ * much padding is required. */
+unsigned int
+ssl3_CalculatePaddingExtensionLength(unsigned int clientHelloLength)
+{
+ unsigned int recordLength = 1 /* handshake message type */ +
+ 3 /* handshake message length */ +
+ clientHelloLength;
+ unsigned int extensionLength;
+
+ if (recordLength < 256 || recordLength >= 512) {
+ return 0;
+ }
+
+ extensionLength = 512 - recordLength;
+ /* Extensions take at least four bytes to encode. Always include at least
+ * one byte of data if including the extension. Some servers (e.g.
+ * WebSphere Application Server 7.0 and Tomcat) will time out or terminate
+ * the connection if the last extension in the client hello is empty. */
+ if (extensionLength < 4 + 1) {
+ extensionLength = 4 + 1;
+ }
+
+ return extensionLength;
+}
+
+/* ssl3_AppendPaddingExtension possibly adds an extension which ensures that a
+ * ClientHello record is either < 256 bytes or is >= 512 bytes. This ensures
+ * that we don't trigger bugs in F5 products. */
+PRInt32
+ssl3_AppendPaddingExtension(sslSocket *ss, unsigned int extensionLen,
+ PRUint32 maxBytes)
+{
+ unsigned int paddingLen = extensionLen - 4;
+ static unsigned char padding[252];
+
+ if (extensionLen == 0) {
+ return 0;
+ }
+
+ if (extensionLen > maxBytes ||
+ !paddingLen ||
+ paddingLen > sizeof(padding)) {
+ PORT_Assert(0);
+ return -1;
+ }
+
+ if (SECSuccess != ssl3_ExtAppendHandshakeNumber(ss, ssl_padding_xtn, 2))
+ return -1;
+ if (SECSuccess != ssl3_ExtAppendHandshakeVariable(ss, padding, paddingLen, 2))
+ return -1;
+
+ return extensionLen;
+}
+
+PRInt32
+ssl3_SendExtendedMasterSecretXtn(const sslSocket *ss, TLSExtensionData *xtnData, PRBool append,
+ PRUint32 maxBytes)
+{
+ PRInt32 extension_length;
+
+ if (!ss->opt.enableExtendedMS) {
+ return 0;
+ }
+
+ /* Always send the extension in this function, since the
+ * client always sends it and this function is only called on
+ * the server if we negotiated the extension. */
+ extension_length = 4; /* Type + length (0) */
+ if (maxBytes < extension_length) {
+ PORT_Assert(0);
+ return 0;
+ }
+
+ if (append) {
+ SECStatus rv;
+ rv = ssl3_ExtAppendHandshakeNumber(ss, ssl_extended_master_secret_xtn, 2);
+ if (rv != SECSuccess)
+ goto loser;
+ rv = ssl3_ExtAppendHandshakeNumber(ss, 0, 2);
+ if (rv != SECSuccess)
+ goto loser;
+ xtnData->advertised[xtnData->numAdvertised++] =
+ ssl_extended_master_secret_xtn;
+ }
+
+ return extension_length;
+
+loser:
+ return -1;
+}
+
+SECStatus
+ssl3_HandleExtendedMasterSecretXtn(const sslSocket *ss, TLSExtensionData *xtnData, PRUint16 ex_type,
+ SECItem *data)
+{
+ if (ss->version < SSL_LIBRARY_VERSION_TLS_1_0) {
+ return SECSuccess;
+ }
+
+ if (!ss->opt.enableExtendedMS) {
+ return SECSuccess;
+ }
+
+ if (data->len != 0) {
+ SSL_TRC(30, ("%d: SSL3[%d]: Bogus extended master secret extension",
+ SSL_GETPID(), ss->fd));
+ return SECFailure;
+ }
+
+ SSL_DBG(("%d: SSL[%d]: Negotiated extended master secret extension.",
+ SSL_GETPID(), ss->fd));
+
+ /* Keep track of negotiated extensions. */
+ xtnData->negotiated[xtnData->numNegotiated++] = ex_type;
+
+ if (ss->sec.isServer) {
+ return ssl3_RegisterExtensionSender(
+ ss, xtnData, ex_type, ssl3_SendExtendedMasterSecretXtn);
+ }
+ return SECSuccess;
+}
+
+/* ssl3_ClientSendSignedCertTimestampXtn sends the signed_certificate_timestamp
+ * extension for TLS ClientHellos. */
+PRInt32
+ssl3_ClientSendSignedCertTimestampXtn(const sslSocket *ss, TLSExtensionData *xtnData, PRBool append,
+ PRUint32 maxBytes)
+{
+ PRInt32 extension_length = 2 /* extension_type */ +
+ 2 /* length(extension_data) */;
+
+ /* Only send the extension if processing is enabled. */
+ if (!ss->opt.enableSignedCertTimestamps)
+ return 0;
+
+ if (append && maxBytes >= extension_length) {
+ SECStatus rv;
+ /* extension_type */
+ rv = ssl3_ExtAppendHandshakeNumber(ss,
+ ssl_signed_cert_timestamp_xtn,
+ 2);
+ if (rv != SECSuccess)
+ goto loser;
+ /* zero length */
+ rv = ssl3_ExtAppendHandshakeNumber(ss, 0, 2);
+ if (rv != SECSuccess)
+ goto loser;
+ xtnData->advertised[xtnData->numAdvertised++] =
+ ssl_signed_cert_timestamp_xtn;
+ } else if (maxBytes < extension_length) {
+ PORT_Assert(0);
+ return 0;
+ }
+
+ return extension_length;
+loser:
+ return -1;
+}
+
+SECStatus
+ssl3_ClientHandleSignedCertTimestampXtn(const sslSocket *ss, TLSExtensionData *xtnData, PRUint16 ex_type,
+ SECItem *data)
+{
+ /* We do not yet know whether we'll be resuming a session or creating
+ * a new one, so we keep a pointer to the data in the TLSExtensionData
+ * structure. This pointer is only valid in the scope of
+ * ssl3_HandleServerHello, and, if not resuming a session, the data is
+ * copied once a new session structure has been set up.
+ * All parsing is currently left to the application and we accept
+ * everything, including empty data.
+ */
+ SECItem *scts = &xtnData->signedCertTimestamps;
+ PORT_Assert(!scts->data && !scts->len);
+
+ if (!data->len) {
+ /* Empty extension data: RFC 6962 mandates non-empty contents. */
+ return SECFailure;
+ }
+ *scts = *data;
+ /* Keep track of negotiated extensions. */
+ xtnData->negotiated[xtnData->numNegotiated++] = ex_type;
+ return SECSuccess;
+}
+
+PRInt32
+ssl3_ServerSendSignedCertTimestampXtn(const sslSocket *ss, TLSExtensionData *xtnData,
+ PRBool append,
+ PRUint32 maxBytes)
+{
+ PRInt32 extension_length;
+ const SECItem *scts = &ss->sec.serverCert->signedCertTimestamps;
+
+ if (!scts->len) {
+ /* No timestamps to send */
+ return 0;
+ }
+
+ extension_length = 2 /* extension_type */ +
+ 2 /* length(extension_data) */ +
+ scts->len;
+
+ if (maxBytes < extension_length) {
+ PORT_Assert(0);
+ return 0;
+ }
+ if (append) {
+ SECStatus rv;
+ /* extension_type */
+ rv = ssl3_ExtAppendHandshakeNumber(ss,
+ ssl_signed_cert_timestamp_xtn,
+ 2);
+ if (rv != SECSuccess) {
+ return -1;
+ }
+ /* extension_data */
+ rv = ssl3_ExtAppendHandshakeVariable(ss, scts->data, scts->len, 2);
+ if (rv != SECSuccess) {
+ return -1;
+ }
+ }
+
+ return extension_length;
+}
+
+SECStatus
+ssl3_ServerHandleSignedCertTimestampXtn(const sslSocket *ss,
+ TLSExtensionData *xtnData,
+ PRUint16 ex_type,
+ SECItem *data)
+{
+ xtnData->negotiated[xtnData->numNegotiated++] = ex_type;
+ PORT_Assert(ss->sec.isServer);
+ return ssl3_RegisterExtensionSender(
+ ss, xtnData, ex_type, ssl3_ServerSendSignedCertTimestampXtn);
+}
+
+/* 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(const sslSocket *ss, TLSExtensionData *xtnData,
+ PRUint16 ex_type,
+ SECItem *data)
+{
+ int i;
+
+ if (data->len < 2 || data->len > 255 || !data->data ||
+ data->len != (unsigned int)data->data[0] + 1) {
+ ssl3_ExtDecodeError(ss);
+ return SECFailure;
+ }
+ for (i = data->len; --i > 0;) {
+ if (data->data[i] == 0) {
+ /* indicate that we should send a reply */
+ SECStatus rv;
+ rv = ssl3_RegisterExtensionSender(ss, xtnData, ex_type,
+ &ssl3_SendSupportedPointFormatsXtn);
+ return rv;
+ }
+ }
+
+ /* Poor client doesn't support uncompressed points. */
+ PORT_SetError(SSL_ERROR_RX_MALFORMED_HANDSHAKE);
+ return SECFailure;
+}
+
+static SECStatus
+ssl_UpdateSupportedGroups(sslSocket *ss, SECItem *data)
+{
+ PRInt32 list_len;
+ unsigned int i;
+ const sslNamedGroupDef *enabled[SSL_NAMED_GROUP_COUNT] = { 0 };
+ PORT_Assert(SSL_NAMED_GROUP_COUNT == PR_ARRAY_SIZE(enabled));
+
+ if (!data->data || data->len < 4) {
+ (void)ssl3_DecodeError(ss);
+ return SECFailure;
+ }
+
+ /* 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) {
+ (void)ssl3_DecodeError(ss);
+ return SECFailure;
+ }
+
+ /* disable all groups and remember the enabled groups */
+ for (i = 0; i < SSL_NAMED_GROUP_COUNT; ++i) {
+ enabled[i] = ss->namedGroupPreferences[i];
+ ss->namedGroupPreferences[i] = NULL;
+ }
+
+ /* Read groups from data and enable if in |enabled| */
+ while (data->len) {
+ const sslNamedGroupDef *group;
+ PRInt32 curve_name =
+ ssl3_ConsumeHandshakeNumber(ss, 2, &data->data, &data->len);
+ if (curve_name < 0) {
+ return SECFailure; /* fatal alert already sent */
+ }
+ group = ssl_LookupNamedGroup(curve_name);
+ if (group) {
+ for (i = 0; i < SSL_NAMED_GROUP_COUNT; ++i) {
+ if (enabled[i] && group == enabled[i]) {
+ ss->namedGroupPreferences[i] = enabled[i];
+ break;
+ }
+ }
+ }
+
+ /* "Codepoints in the NamedCurve registry with a high byte of 0x01 (that
+ * is, between 256 and 511 inclusive) are set aside for FFDHE groups,"
+ * -- https://tools.ietf.org/html/draft-ietf-tls-negotiated-ff-dhe-10
+ */
+ if ((curve_name & 0xff00) == 0x0100) {
+ ss->xtnData.peerSupportsFfdheGroups = PR_TRUE;
+ }
+ }
+
+ /* Note: if ss->opt.requireDHENamedGroups is set, we disable DHE cipher
+ * suites, but we do that in ssl3_config_match(). */
+ if (ss->version < SSL_LIBRARY_VERSION_TLS_1_3 &&
+ !ss->opt.requireDHENamedGroups && !ss->xtnData.peerSupportsFfdheGroups) {
+ /* If we don't require that DHE use named groups, and no FFDHE was
+ * included, we pretend that they support all the FFDHE groups we do. */
+ for (i = 0; i < SSL_NAMED_GROUP_COUNT; ++i) {
+ if (enabled[i] && enabled[i]->keaType == ssl_kea_dh) {
+ ss->namedGroupPreferences[i] = enabled[i];
+ }
+ }
+ }
+
+ return SECSuccess;
+}
+
+/* Ensure that the curve in our server cert is one of the ones supported
+ * by the remote client, and disable all ECC cipher suites if not.
+ */
+SECStatus
+ssl_HandleSupportedGroupsXtn(const sslSocket *ss, TLSExtensionData *xtnData,
+ PRUint16 ex_type, SECItem *data)
+{
+ SECStatus rv;
+
+ rv = ssl_UpdateSupportedGroups(CONST_CAST(sslSocket, ss), data);
+ if (rv != SECSuccess)
+ return SECFailure;
+
+ /* TLS 1.3 permits the server to send this extension so make it so. */
+ if (ss->sec.isServer && ss->version >= SSL_LIBRARY_VERSION_TLS_1_3) {
+ rv = ssl3_RegisterExtensionSender(ss, xtnData, ex_type,
+ &ssl_SendSupportedGroupsXtn);
+ if (rv != SECSuccess) {
+ return SECFailure; /* error already set. */
+ }
+ }
+
+ /* Remember that we negotiated this extension. */
+ xtnData->negotiated[xtnData->numNegotiated++] = ex_type;
+
+ return SECSuccess;
+}
diff --git a/nss/lib/ssl/ssl3exthandle.h b/nss/lib/ssl/ssl3exthandle.h
new file mode 100644
index 0000000..65223d6
--- /dev/null
+++ b/nss/lib/ssl/ssl3exthandle.h
@@ -0,0 +1,95 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is PRIVATE to SSL.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.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 __ssl3exthandle_h_
+#define __ssl3exthandle_h_
+
+PRInt32 ssl3_SendRenegotiationInfoXtn(const sslSocket *ss, TLSExtensionData *xtnData,
+ PRBool append, PRUint32 maxBytes);
+SECStatus ssl3_HandleRenegotiationInfoXtn(const sslSocket *ss, TLSExtensionData *xtnData,
+ PRUint16 ex_type, SECItem *data);
+SECStatus ssl3_ClientHandleNextProtoNegoXtn(const sslSocket *ss, TLSExtensionData *xtnData,
+ PRUint16 ex_type, SECItem *data);
+SECStatus ssl3_ClientHandleAppProtoXtn(const sslSocket *ss, TLSExtensionData *xtnData,
+ PRUint16 ex_type, SECItem *data);
+SECStatus ssl3_ServerHandleNextProtoNegoXtn(const sslSocket *ss, TLSExtensionData *xtnData,
+ PRUint16 ex_type, SECItem *data);
+SECStatus ssl3_ServerHandleAppProtoXtn(const sslSocket *ss, TLSExtensionData *xtnData, PRUint16 ex_type,
+ SECItem *data);
+PRInt32 ssl3_ClientSendNextProtoNegoXtn(const sslSocket *ss, TLSExtensionData *xtnData, PRBool append,
+ PRUint32 maxBytes);
+PRInt32 ssl3_ClientSendAppProtoXtn(const sslSocket *ss, TLSExtensionData *xtnData, PRBool append,
+ PRUint32 maxBytes);
+PRInt32 ssl3_ServerSendAppProtoXtn(const sslSocket *ss, TLSExtensionData *xtnData, PRBool append,
+ PRUint32 maxBytes);
+PRInt32 ssl3_ClientSendUseSRTPXtn(const sslSocket *ss, TLSExtensionData *xtnData, PRBool append,
+ PRUint32 maxBytes);
+PRInt32 ssl3_ServerSendUseSRTPXtn(const sslSocket *ss, TLSExtensionData *xtnData, PRBool append,
+ PRUint32 maxBytes);
+SECStatus ssl3_ClientHandleUseSRTPXtn(const sslSocket *ss, TLSExtensionData *xtnData, PRUint16 ex_type,
+ SECItem *data);
+SECStatus ssl3_ServerHandleUseSRTPXtn(const sslSocket *ss, TLSExtensionData *xtnData, PRUint16 ex_type,
+ SECItem *data);
+PRInt32 ssl3_ServerSendStatusRequestXtn(const sslSocket *ss, TLSExtensionData *xtnData,
+ PRBool append, PRUint32 maxBytes);
+SECStatus ssl3_ServerHandleStatusRequestXtn(const sslSocket *ss, TLSExtensionData *xtnData,
+ PRUint16 ex_type, SECItem *data);
+SECStatus ssl3_ClientHandleStatusRequestXtn(const sslSocket *ss, TLSExtensionData *xtnData,
+ PRUint16 ex_type,
+ SECItem *data);
+PRInt32 ssl3_ClientSendStatusRequestXtn(const sslSocket *ss, TLSExtensionData *xtnData, PRBool append,
+ PRUint32 maxBytes);
+PRInt32 ssl3_ClientSendSigAlgsXtn(const sslSocket *ss, TLSExtensionData *xtnData, PRBool append,
+ PRUint32 maxBytes);
+SECStatus ssl3_ServerHandleSigAlgsXtn(const sslSocket *ss, TLSExtensionData *xtnData, PRUint16 ex_type,
+ SECItem *data);
+
+PRInt32 ssl3_ClientSendSignedCertTimestampXtn(const sslSocket *ss, TLSExtensionData *xtnData,
+ PRBool append,
+ PRUint32 maxBytes);
+SECStatus ssl3_ClientHandleSignedCertTimestampXtn(const sslSocket *ss, TLSExtensionData *xtnData,
+ PRUint16 ex_type,
+ SECItem *data);
+PRInt32 ssl3_ServerSendSignedCertTimestampXtn(const sslSocket *ss, TLSExtensionData *xtnData,
+ PRBool append,
+ PRUint32 maxBytes);
+SECStatus ssl3_ServerHandleSignedCertTimestampXtn(const sslSocket *ss, TLSExtensionData *xtnData,
+ PRUint16 ex_type,
+ SECItem *data);
+PRInt32 ssl3_SendExtendedMasterSecretXtn(const sslSocket *ss, TLSExtensionData *xtnData, PRBool append,
+ PRUint32 maxBytes);
+SECStatus ssl3_HandleExtendedMasterSecretXtn(const sslSocket *ss, TLSExtensionData *xtnData,
+ PRUint16 ex_type,
+ SECItem *data);
+SECStatus ssl3_ProcessSessionTicketCommon(sslSocket *ss, SECItem *data);
+PRInt32 ssl3_SendServerNameXtn(const sslSocket *ss,
+ TLSExtensionData *xtnData,
+ PRBool append,
+ PRUint32 maxBytes);
+SECStatus ssl3_HandleServerNameXtn(const sslSocket *ss, TLSExtensionData *xtnData,
+ PRUint16 ex_type, SECItem *data);
+SECStatus ssl_HandleSupportedGroupsXtn(const sslSocket *ss, TLSExtensionData *xtnData,
+ PRUint16 ex_type, SECItem *data);
+SECStatus ssl3_HandleSupportedPointFormatsXtn(const sslSocket *ss, TLSExtensionData *xtnData,
+ PRUint16 ex_type, SECItem *data);
+SECStatus ssl3_ClientHandleSessionTicketXtn(const sslSocket *ss, TLSExtensionData *xtnData,
+ PRUint16 ex_type, SECItem *data);
+SECStatus ssl3_ServerHandleSessionTicketXtn(const sslSocket *ss, TLSExtensionData *xtnData,
+ PRUint16 ex_type, SECItem *data);
+PRInt32 ssl3_SendSessionTicketXtn(const sslSocket *ss,
+ TLSExtensionData *xtnData,
+ PRBool append,
+ PRUint32 maxBytes);
+
+PRInt32 ssl_SendSupportedGroupsXtn(const sslSocket *ss,
+ TLSExtensionData *xtnData,
+ PRBool append, PRUint32 maxBytes);
+PRInt32 ssl3_SendSupportedPointFormatsXtn(const sslSocket *ss,
+ TLSExtensionData *xtnData,
+ PRBool append, PRUint32 maxBytes);
+#endif
diff --git a/nss/lib/ssl/ssl3gthr.c b/nss/lib/ssl/ssl3gthr.c
index 23b9755..2bcc1d0 100644
--- a/nss/lib/ssl/ssl3gthr.c
+++ b/nss/lib/ssl/ssl3gthr.c
@@ -1,5 +1,5 @@
/*
- * Gather (Read) entire SSL3 records from socket into buffer.
+ * 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
@@ -8,17 +8,70 @@
#include "cert.h"
#include "ssl.h"
#include "sslimpl.h"
+#include "sslproto.h"
#include "ssl3prot.h"
-/*
+struct ssl2GatherStr {
+ /* true when ssl3_GatherData encounters an SSLv2 handshake */
+ PRBool isV2;
+
+ /* number of bytes of padding appended to the message content */
+ PRUint8 padding;
+};
+
+typedef struct ssl2GatherStr ssl2Gather;
+
+/* Caller should hold RecvBufLock. */
+SECStatus
+ssl3_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
+ssl3_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);
+ }
+}
+
+/* Checks whether a given buffer is likely an SSLv3 record header. */
+PRBool
+ssl3_isLikelyV3Hello(const unsigned char *buf)
+{
+ /* Even if this was a V2 record header we couldn't possibly parse it
+ * correctly as the second bit denotes a vaguely-defined security escape. */
+ if (buf[0] & 0x40) {
+ return PR_TRUE;
+ }
+
+ /* Check for a typical V3 record header. */
+ return (PRBool)(buf[0] >= content_change_cipher_spec &&
+ buf[0] <= content_application_data &&
+ buf[1] == MSB(SSL_LIBRARY_VERSION_3_0));
+}
+
+/*
* 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.
+ * 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)
+ * 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.
*
@@ -28,108 +81,147 @@
*
* This loop returns when either
* (a) an error or EOF occurs,
- * (b) PR_WOULD_BLOCK_ERROR,
- * (c) data (entire SSL3 record) has been received.
+ * (b) PR_WOULD_BLOCK_ERROR,
+ * (c) data (entire SSL3 record) has been received.
*/
static int
-ssl3_GatherData(sslSocket *ss, sslGather *gs, int flags)
+ssl3_GatherData(sslSocket *ss, sslGather *gs, int flags, ssl2Gather *ssl2gs)
{
unsigned char *bp;
unsigned char *lbp;
- int nb;
- int err;
- int rv = 1;
+ int nb;
+ int err;
+ int rv = 1;
+ PRUint8 v2HdrLength = 0;
- PORT_Assert( ss->opt.noLocks || ssl_HaveRecvBufLock(ss) );
+ 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;
+ gs->state = GS_HEADER;
+ gs->remainder = ss->ssl3.hs.shortHeaders ? 2 : 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( (unsigned int)nb <= gs->remainder );
- if ((unsigned int)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;
- }
+ 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((unsigned int)nb <= gs->remainder);
+ if ((unsigned int)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:
+ /* Check for SSLv2 handshakes. Always assume SSLv3 on clients,
+ * support SSLv2 handshakes only when ssl2gs != NULL. */
+ if (!ssl2gs || ssl3_isLikelyV3Hello(gs->hdr)) {
+ /* Should have a non-SSLv2 record header in gs->hdr. Extract
+ * the length of the following encrypted data, and then
+ * read in the rest of the record into gs->inbuf. */
+ if (ss->ssl3.hs.shortHeaders) {
+ PRUint16 len = (gs->hdr[0] << 8) | gs->hdr[1];
+ if (!(len & 0x8000)) {
+ SSL_DBG(("%d: SSL3[%d]: incorrectly formatted header"));
+ SSL3_SendAlert(ss, alert_fatal, illegal_parameter);
+ gs->state = GS_INIT;
+ PORT_SetError(SSL_ERROR_BAD_MAC_READ);
+ return SECFailure;
+ }
+ gs->remainder = len & ~0x8000;
+ } else {
+ gs->remainder = (gs->hdr[3] << 8) | gs->hdr[4];
+ }
+ } else {
+ /* Probably an SSLv2 record header. No need to handle any
+ * security escapes (gs->hdr[0] & 0x40) as we wouldn't get
+ * here if one was set. See ssl3_isLikelyV3Hello(). */
+ gs->remainder = ((gs->hdr[0] & 0x7f) << 8) | gs->hdr[1];
+ ssl2gs->isV2 = PR_TRUE;
+ v2HdrLength = 2;
+
+ /* Is it a 3-byte header with padding? */
+ if (!(gs->hdr[0] & 0x80)) {
+ ssl2gs->padding = gs->hdr[2];
+ v2HdrLength++;
+ }
+ }
+
+ /* This is the max length for an encrypted SSLv3+ fragment. */
+ if (!v2HdrLength &&
+ gs->remainder > (MAX_FRAGMENT_LENGTH + 2048)) {
+ 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;
+ }
+
+ /* When we encounter an SSLv2 hello we've read 2 or 3 bytes too
+ * many into the gs->hdr[] buffer. Copy them over into inbuf so
+ * that we can properly process the hello record later. */
+ if (v2HdrLength) {
+ gs->inbuf.len = 5 - v2HdrLength;
+ PORT_Memcpy(lbp, gs->hdr + v2HdrLength, gs->inbuf.len);
+ gs->remainder -= gs->inbuf.len;
+ lbp += gs->inbuf.len;
+ }
+
+ break; /* End this case. Continue around the loop. */
+
+ case GS_DATA:
+ /*
+ ** SSL3 record has been completely received.
+ */
+ SSL_TRC(10, ("%d: SSL[%d]: got record of %d bytes",
+ SSL_GETPID(), ss->fd, gs->inbuf.len));
+ gs->state = GS_INIT;
+ return 1;
+ }
}
return rv;
@@ -139,7 +231,7 @@ ssl3_GatherData(sslSocket *ss, sslGather *gs, int flags)
* Read in an entire DTLS record.
*
* Blocks here for blocking sockets, otherwise returns -1 with
- * PR_WOULD_BLOCK_ERROR when socket would block.
+ * 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.
@@ -147,43 +239,43 @@ ssl3_GatherData(sslSocket *ss, sslGather *gs, int flags)
* 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)
+ * (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.
+ * (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;
+ int nb;
+ int err;
+ int rv = 1;
SSL_TRC(30, ("dtls_GatherData"));
- PORT_Assert( ss->opt.noLocks || ssl_HaveRecvBufLock(ss) );
+ PORT_Assert(ss->opt.noLocks || ssl_HaveRecvBufLock(ss));
gs->state = GS_HEADER;
gs->offset = 0;
- if (gs->dtlsPacketOffset == gs->dtlsPacket.len) { /* No data left */
+ 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).
- */
+ /* 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. */
+ MAX_FRAGMENT_LENGTH + 2048 + 13);
+ if (err) { /* realloc has set error code to no mem. */
return err;
}
}
@@ -213,7 +305,8 @@ dtls_GatherData(sslSocket *ss, sslGather *gs, int flags)
*/
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));
+ "too short to contain header",
+ SSL_GETPID(), ss->fd));
PR_SetError(PR_WOULD_BLOCK_ERROR, 0);
gs->dtlsPacketOffset = 0;
gs->dtlsPacket.len = 0;
@@ -228,7 +321,8 @@ dtls_GatherData(sslSocket *ss, sslGather *gs, int flags)
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));
+ "to contain rest of body",
+ SSL_GETPID(), ss->fd));
PR_SetError(PR_WOULD_BLOCK_ERROR, 0);
gs->dtlsPacketOffset = 0;
gs->dtlsPacket.len = 0;
@@ -238,14 +332,14 @@ dtls_GatherData(sslSocket *ss, sslGather *gs, int flags)
/* 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;
- }
+ 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->remainder);
gs->inbuf.len = gs->remainder;
gs->offset = gs->remainder;
gs->dtlsPacketOffset += gs->remainder;
@@ -255,16 +349,16 @@ dtls_GatherData(sslSocket *ss, sslGather *gs, int flags)
}
/* Gather in a record and when complete, Handle that record.
- * Repeat this until the handshake is complete,
+ * Repeat this until the handshake is complete,
* or until application data is available.
*
- * Returns 1 when the handshake is completed without error, or
+ * 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,
+ * Called from ssl_GatherRecord1stHandshake in sslcon.c,
* and from SSL_ForceHandshake in sslsecur.c
* and from ssl3_GatherAppDataRecord below (<- DoRecv in sslsecur.c).
*
@@ -273,9 +367,9 @@ dtls_GatherData(sslSocket *ss, sslGather *gs, int flags)
int
ssl3_GatherCompleteHandshake(sslSocket *ss, int flags)
{
+ int rv;
SSL3Ciphertext cText;
- int rv;
- PRBool keepGoing = PR_TRUE;
+ PRBool keepGoing = PR_TRUE;
SSL_TRC(30, ("ssl3_GatherCompleteHandshake"));
@@ -283,145 +377,169 @@ ssl3_GatherCompleteHandshake(sslSocket *ss, int flags)
* which requires the 1stHandshakeLock, which must be acquired before the
* RecvBufLock.
*/
- PORT_Assert( ss->opt.noLocks || ssl_Have1stHandshakeLock(ss) );
- PORT_Assert( ss->opt.noLocks || ssl_HaveRecvBufLock(ss) );
+ PORT_Assert(ss->opt.noLocks || ssl_Have1stHandshakeLock(ss));
+ PORT_Assert(ss->opt.noLocks || ssl_HaveRecvBufLock(ss));
do {
- PRBool handleRecordNow = PR_FALSE;
-
- ssl_GetSSL3HandshakeLock(ss);
-
- /* 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.
- */
- if (ss->ssl3.hs.restartTarget) {
- ssl_ReleaseSSL3HandshakeLock(ss);
- 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) {
- if (ss->ssl3.hs.msgState.len == 0) {
- ss->ssl3.hs.msgState.buf = NULL;
- } else {
- handleRecordNow = PR_TRUE;
- }
- }
-
- ssl_ReleaseSSL3HandshakeLock(ss);
-
- if (handleRecordNow) {
- /* 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 (ss->recvdCloseNotify) {
- /* RFC 5246 Section 7.2.1:
- * Any data received after a closure alert is ignored.
- */
- return 0;
- }
- 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 (ss->gs.buf.len > 0) {
- /* We have application data to return to the application. This
- * prioritizes returning application data to the application over
- * completing any renegotiation handshake we may be doing.
- */
- PORT_Assert(ss->firstHsDone);
- PORT_Assert(cText.type == content_application_data);
- break;
- }
-
- PORT_Assert(keepGoing);
- ssl_GetSSL3HandshakeLock(ss);
- if (ss->ssl3.hs.ws == idle_handshake) {
- /* We are done with the current handshake so stop trying to
- * handshake. Note that it would be safe to test ss->firstHsDone
- * instead of ss->ssl3.hs.ws. By testing ss->ssl3.hs.ws instead,
- * we prioritize completing a renegotiation handshake over sending
- * application data.
- */
- PORT_Assert(ss->firstHsDone);
- PORT_Assert(!ss->ssl3.hs.canFalseStart);
- keepGoing = PR_FALSE;
- } else if (ss->ssl3.hs.canFalseStart) {
- /* Prioritize sending application data over trying to complete
- * the handshake if we're false starting.
- *
- * If we were to do this check at the beginning of the loop instead
- * of here, then this function would become be a no-op after
- * receiving the ServerHelloDone in the false start case, and we
- * would never complete the handshake.
- */
- PORT_Assert(!ss->firstHsDone);
-
- if (ssl3_WaitingForStartOfServerSecondRound(ss)) {
- keepGoing = PR_FALSE;
- } else {
- ss->ssl3.hs.canFalseStart = PR_FALSE;
- }
- }
- ssl_ReleaseSSL3HandshakeLock(ss);
+ PRBool handleRecordNow = PR_FALSE;
+
+ ssl_GetSSL3HandshakeLock(ss);
+
+ /* 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.
+ */
+ if (ss->ssl3.hs.restartTarget) {
+ ssl_ReleaseSSL3HandshakeLock(ss);
+ 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) {
+ if (ss->ssl3.hs.msgState.len == 0) {
+ ss->ssl3.hs.msgState.buf = NULL;
+ } else {
+ handleRecordNow = PR_TRUE;
+ }
+ }
+
+ ssl_ReleaseSSL3HandshakeLock(ss);
+
+ if (handleRecordNow) {
+ /* 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 {
+ /* State for SSLv2 client hello support. */
+ ssl2Gather ssl2gs = { PR_FALSE, 0 };
+ ssl2Gather *ssl2gs_ptr = NULL;
+
+ /* If we're a server and waiting for a client hello, accept v2. */
+ if (ss->sec.isServer && ss->ssl3.hs.ws == wait_client_hello) {
+ ssl2gs_ptr = &ssl2gs;
+ }
+
+ /* bring in the next sslv3 record. */
+ if (ss->recvdCloseNotify) {
+ /* RFC 5246 Section 7.2.1:
+ * Any data received after a closure alert is ignored.
+ */
+ return 0;
+ }
+
+ if (!IS_DTLS(ss)) {
+ /* If we're a server waiting for a ClientHello then pass
+ * ssl2gs to support SSLv2 ClientHello messages. */
+ rv = ssl3_GatherData(ss, &ss->gs, flags, ssl2gs_ptr);
+ } 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)) {
+ dtls_CheckTimer(ss);
+ /* Restore the error in case something succeeded */
+ PORT_SetError(PR_WOULD_BLOCK_ERROR);
+ }
+ }
+
+ if (rv <= 0) {
+ return rv;
+ }
+
+ if (ssl2gs.isV2) {
+ rv = ssl3_HandleV2ClientHello(ss, ss->gs.inbuf.buf,
+ ss->gs.inbuf.len,
+ ssl2gs.padding);
+ if (rv < 0) {
+ return rv;
+ }
+ } else {
+ /* 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.
+ */
+ if (ss->ssl3.hs.shortHeaders) {
+ cText.type = content_application_data;
+ cText.version = SSL_LIBRARY_VERSION_TLS_1_0;
+ } else {
+ cText.type = (SSL3ContentType)ss->gs.hdr[0];
+ cText.version = (ss->gs.hdr[1] << 8) | ss->gs.hdr[2];
+ }
+
+ if (IS_DTLS(ss)) {
+ sslSequenceNumber seq_num;
+
+ cText.version = dtls_DTLSVersionToTLSVersion(cText.version);
+ /* DTLS sequence number */
+ PORT_Memcpy(&seq_num, &ss->gs.hdr[3], sizeof(seq_num));
+ cText.seq_num = PR_ntohll(seq_num);
+ }
+
+ cText.buf = &ss->gs.inbuf;
+ rv = ssl3_HandleRecord(ss, &cText, &ss->gs.buf);
+ }
+ }
+ if (rv < 0) {
+ return ss->recvdCloseNotify ? 0 : rv;
+ }
+ if (ss->gs.buf.len > 0) {
+ /* We have application data to return to the application. This
+ * prioritizes returning application data to the application over
+ * completing any renegotiation handshake we may be doing.
+ */
+ PORT_Assert(ss->firstHsDone);
+ PORT_Assert(cText.type == content_application_data);
+ break;
+ }
+
+ PORT_Assert(keepGoing);
+ ssl_GetSSL3HandshakeLock(ss);
+ if (ss->ssl3.hs.ws == idle_handshake) {
+ /* We are done with the current handshake so stop trying to
+ * handshake. Note that it would be safe to test ss->firstHsDone
+ * instead of ss->ssl3.hs.ws. By testing ss->ssl3.hs.ws instead,
+ * we prioritize completing a renegotiation handshake over sending
+ * application data.
+ */
+ PORT_Assert(ss->firstHsDone);
+ PORT_Assert(!ss->ssl3.hs.canFalseStart);
+ keepGoing = PR_FALSE;
+ } else if (ss->ssl3.hs.canFalseStart) {
+ /* Prioritize sending application data over trying to complete
+ * the handshake if we're false starting.
+ *
+ * If we were to do this check at the beginning of the loop instead
+ * of here, then this function would become be a no-op after
+ * receiving the ServerHelloDone in the false start case, and we
+ * would never complete the handshake.
+ */
+ PORT_Assert(!ss->firstHsDone);
+
+ if (ssl3_WaitingForServerSecondRound(ss)) {
+ keepGoing = PR_FALSE;
+ } else {
+ ss->ssl3.hs.canFalseStart = PR_FALSE;
+ }
+ }
+ ssl_ReleaseSSL3HandshakeLock(ss);
} while (keepGoing);
+ /* Service the DTLS timer so that the holddown timer eventually fires. */
+ if (IS_DTLS(ss)) {
+ dtls_CheckTimer(ss);
+ }
ss->gs.readOffset = 0;
ss->gs.writeOffset = ss->gs.buf.len;
return 1;
@@ -441,14 +559,14 @@ ssl3_GatherCompleteHandshake(sslSocket *ss, int flags)
int
ssl3_GatherAppDataRecord(sslSocket *ss, int flags)
{
- int rv;
+ int rv;
/* ssl3_GatherCompleteHandshake requires both of these locks. */
- PORT_Assert( ss->opt.noLocks || ssl_Have1stHandshakeLock(ss) );
- PORT_Assert( ss->opt.noLocks || ssl_HaveRecvBufLock(ss) );
+ PORT_Assert(ss->opt.noLocks || ssl_Have1stHandshakeLock(ss));
+ PORT_Assert(ss->opt.noLocks || ssl_HaveRecvBufLock(ss));
do {
- rv = ssl3_GatherCompleteHandshake(ss, flags);
+ rv = ssl3_GatherCompleteHandshake(ss, flags);
} while (rv > 0 && ss->gs.buf.len == 0);
return rv;
diff --git a/nss/lib/ssl/ssl3prot.h b/nss/lib/ssl/ssl3prot.h
index a93bef1..146cba4 100644
--- a/nss/lib/ssl/ssl3prot.h
+++ b/nss/lib/ssl/ssl3prot.h
@@ -1,3 +1,4 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/* 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.
@@ -17,57 +18,58 @@ typedef PRUint16 SSL3ProtocolVersion;
/* The TLS 1.3 draft version. Used to avoid negotiating
* between incompatible pre-standard TLS 1.3 drafts.
* TODO(ekr@rtfm.com): Remove when TLS 1.3 is published. */
-#define TLS_1_3_DRAFT_VERSION 3
+#define TLS_1_3_DRAFT_VERSION 18
typedef PRUint16 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 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
+#define SSL3_RECORD_HEADER_LENGTH 5
+#define TLS13_RECORD_HEADER_LENGTH_SHORT 2
/* SSL3_RECORD_HEADER_LENGTH + epoch/sequence_number */
-#define DTLS_RECORD_HEADER_LENGTH 13
+#define DTLS_RECORD_HEADER_LENGTH 13
-#define MAX_FRAGMENT_LENGTH 16384
+#define MAX_FRAGMENT_LENGTH 16384
typedef enum {
content_change_cipher_spec = 20,
- content_alert = 21,
- content_handshake = 22,
- content_application_data = 23
+ content_alert = 21,
+ content_handshake = 22,
+ content_application_data = 23
} SSL3ContentType;
typedef struct {
- SSL3ContentType type;
+ SSL3ContentType type;
SSL3ProtocolVersion version;
- PRUint16 length;
- SECItem fragment;
+ PRUint16 length;
+ SECItem fragment;
} SSL3Plaintext;
typedef struct {
- SSL3ContentType type;
+ SSL3ContentType type;
SSL3ProtocolVersion version;
- PRUint16 length;
- SECItem fragment;
+ PRUint16 length;
+ SECItem fragment;
} SSL3Compressed;
typedef struct {
- SECItem content;
+ SECItem content;
SSL3Opaque MAC[MAX_MAC_LENGTH];
} SSL3GenericStreamCipher;
typedef struct {
- SECItem content;
+ SECItem content;
SSL3Opaque MAC[MAX_MAC_LENGTH];
- PRUint8 padding[MAX_PADDING_LENGTH];
- PRUint8 padding_length;
+ PRUint8 padding[MAX_PADDING_LENGTH];
+ PRUint8 padding_length;
} SSL3GenericBlockCipher;
typedef enum { change_cipher_spec_choice = 1 } SSL3ChangeCipherSpecChoice;
@@ -76,67 +78,74 @@ typedef struct {
SSL3ChangeCipherSpecChoice choice;
} SSL3ChangeCipherSpec;
-typedef enum { alert_warning = 1, alert_fatal = 2 } SSL3AlertLevel;
+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,
+ close_notify = 0,
+ end_of_early_data = 1, /* TLS 1.3 */
+ 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,
- inappropriate_fallback = 86, /* could also be sent for SSLv3 */
- user_canceled = 90,
- no_renegotiation = 100,
-
-/* Alerts for client hello extensions */
- unsupported_extension = 110,
- certificate_unobtainable = 111,
- unrecognized_name = 112,
+ 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,
+ inappropriate_fallback = 86, /* could also be sent for SSLv3 */
+ user_canceled = 90,
+ no_renegotiation = 100,
+
+ /* Alerts for client hello extensions */
+ missing_extension = 109,
+ unsupported_extension = 110,
+ certificate_unobtainable = 111,
+ unrecognized_name = 112,
bad_certificate_status_response = 113,
- bad_certificate_hash_value = 114,
- no_application_protocol = 120
+ bad_certificate_hash_value = 114,
+ no_application_protocol = 120,
+ /* invalid alert */
+ no_alert = 256
} SSL3AlertDescription;
typedef struct {
- SSL3AlertLevel level;
+ SSL3AlertLevel level;
SSL3AlertDescription description;
} SSL3Alert;
typedef enum {
- hello_request = 0,
- client_hello = 1,
- server_hello = 2,
+ hello_request = 0,
+ client_hello = 1,
+ server_hello = 2,
hello_verify_request = 3,
- new_session_ticket = 4,
- certificate = 11,
+ new_session_ticket = 4,
+ hello_retry_request = 6,
+ encrypted_extensions = 8,
+ certificate = 11,
server_key_exchange = 12,
certificate_request = 13,
- server_hello_done = 14,
- certificate_verify = 15,
+ server_hello_done = 14,
+ certificate_verify = 15,
client_key_exchange = 16,
- finished = 20,
- certificate_status = 22,
- next_proto = 67
+ finished = 20,
+ certificate_status = 22,
+ next_proto = 67
} SSL3HandshakeType;
typedef struct {
@@ -153,20 +162,20 @@ typedef struct {
} SSL3SessionID;
typedef struct {
- SSL3ProtocolVersion client_version;
- SSL3Random random;
- SSL3SessionID session_id;
- SECItem cipher_suites;
- PRUint8 cm_count;
- SSLCompressionMethod compression_methods[MAX_COMPRESSION_METHODS];
+ SSL3ProtocolVersion client_version;
+ SSL3Random random;
+ SSL3SessionID session_id;
+ SECItem cipher_suites;
+ PRUint8 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;
+typedef struct {
+ SSL3ProtocolVersion server_version;
+ SSL3Random random;
+ SSL3SessionID session_id;
+ ssl3CipherSuite cipher_suite;
+ SSLCompressionMethod compression_method;
} SSL3ServerHello;
typedef struct {
@@ -179,24 +188,19 @@ typedef struct {
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
+ kea_ecdh_anon,
+ kea_ecdhe_psk,
+ kea_dhe_psk,
+ kea_tls13_any,
} SSL3KeyExchangeAlgorithm;
typedef struct {
@@ -233,6 +237,7 @@ typedef struct {
union {
PRUint8 raw[64];
SSL3HashesIndividually s;
+ SECItem pointer_to_hash_input;
} u;
} SSL3Hashes;
@@ -244,50 +249,25 @@ typedef struct {
} 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
+ 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
@@ -309,11 +289,19 @@ typedef struct {
typedef struct {
PRUint32 received_timestamp;
PRUint32 ticket_lifetime_hint;
- SECItem ticket;
+ PRUint32 flags;
+ PRUint32 ticket_age_add;
+ PRUint32 max_early_data_size;
+ SECItem ticket;
} NewSessionTicket;
typedef enum {
- CLIENT_AUTH_ANONYMOUS = 0,
+ tls13_psk_ke = 0,
+ tls13_psk_dh_ke = 1
+} TLS13PskKEModes;
+
+typedef enum {
+ CLIENT_AUTH_ANONYMOUS = 0,
CLIENT_AUTH_CERTIFICATE = 1
} ClientAuthenticationType;
@@ -324,10 +312,10 @@ typedef struct {
} identity;
} ClientIdentity;
-#define SESS_TICKET_KEY_NAME_LEN 16
-#define SESS_TICKET_KEY_NAME_PREFIX "NSS!"
+#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
+#define SESS_TICKET_KEY_VAR_NAME_LEN 12
typedef struct {
unsigned char *key_name;
@@ -338,6 +326,6 @@ typedef struct {
#define TLS_EX_SESS_TICKET_MAC_LENGTH 32
-#define TLS_STE_NO_SERVER_NAME -1
+#define TLS_STE_NO_SERVER_NAME -1
#endif /* __ssl3proto_h_ */
diff --git a/nss/lib/ssl/sslauth.c b/nss/lib/ssl/sslauth.c
index b144336..5b5f672 100644
--- a/nss/lib/ssl/sslauth.c
+++ b/nss/lib/ssl/sslauth.c
@@ -1,3 +1,4 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
@@ -17,12 +18,12 @@ SSL_PeerCertificate(PRFileDesc *fd)
ss = ssl_FindSocket(fd);
if (!ss) {
- SSL_DBG(("%d: SSL[%d]: bad socket in PeerCertificate",
- SSL_GETPID(), fd));
- return 0;
+ 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 CERT_DupCertificate(ss->sec.peerCert);
}
return 0;
}
@@ -38,27 +39,27 @@ SSL_PeerCertificateChain(PRFileDesc *fd)
ss = ssl_FindSocket(fd);
if (!ss) {
- SSL_DBG(("%d: SSL[%d]: bad socket in PeerCertificateChain",
- SSL_GETPID(), fd));
- return NULL;
+ SSL_DBG(("%d: SSL[%d]: bad socket in PeerCertificateChain",
+ SSL_GETPID(), fd));
+ return NULL;
}
if (!ss->opt.useSecurity || !ss->sec.peerCert) {
- PORT_SetError(SSL_ERROR_NO_CERTIFICATE);
- return NULL;
+ PORT_SetError(SSL_ERROR_NO_CERTIFICATE);
+ return NULL;
}
chain = CERT_NewCertList();
if (!chain) {
- return NULL;
+ return NULL;
}
cert = CERT_DupCertificate(ss->sec.peerCert);
if (CERT_AddCertToListTail(chain, cert) != SECSuccess) {
- goto loser;
+ goto loser;
}
for (cur = ss->ssl3.peerCertChain; cur; cur = cur->next) {
- cert = CERT_DupCertificate(cur->cert);
- if (CERT_AddCertToListTail(chain, cert) != SECSuccess) {
- goto loser;
- }
+ cert = CERT_DupCertificate(cur->cert);
+ if (CERT_AddCertToListTail(chain, cert) != SECSuccess) {
+ goto loser;
+ }
}
return chain;
@@ -75,102 +76,101 @@ SSL_LocalCertificate(PRFileDesc *fd)
ss = ssl_FindSocket(fd);
if (!ss) {
- SSL_DBG(("%d: SSL[%d]: bad socket in PeerCertificate",
- SSL_GETPID(), fd));
- return NULL;
+ 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);
- }
+ 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)
+ char **ip, char **sp)
{
sslSocket *ss;
- const char *cipherName;
- PRBool isDes = PR_FALSE;
ss = ssl_FindSocket(fd);
if (!ss) {
- SSL_DBG(("%d: SSL[%d]: bad socket in SecurityStatus",
- SSL_GETPID(), fd));
- return SECFailure;
+ 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 (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;
+ *op = SSL_SECURITY_STATUS_OFF;
}
if (ss->opt.useSecurity && ss->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);
+ const ssl3BulkCipherDef *bulkCipherDef;
+ PRBool isDes = PR_FALSE;
+
+ bulkCipherDef = ssl_GetBulkCipherDef(ss->ssl3.hs.suite_def);
+ if (cp) {
+ *cp = PORT_Strdup(bulkCipherDef->short_name);
+ }
+ if (PORT_Strstr(bulkCipherDef->short_name, "DES")) {
+ isDes = PR_TRUE;
+ }
+
+ if (kp0) {
+ *kp0 = bulkCipherDef->key_size * 8;
+ if (isDes)
+ *kp0 = (*kp0 * 7) / 8;
+ }
+ if (kp1) {
+ *kp1 = bulkCipherDef->secret_key_size * 8;
+ if (isDes)
+ *kp1 = (*kp1 * 7) / 8;
+ }
+ if (op) {
+ if (bulkCipherDef->key_size == 0) {
+ *op = SSL_SECURITY_STATUS_OFF;
+ } else if (bulkCipherDef->secret_key_size * 8 < 90) {
+ *op = SSL_SECURITY_STATUS_ON_LOW;
+ } else {
+ *op = SSL_SECURITY_STATUS_ON_HIGH;
}
}
- 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");
- }
- }
- }
+ 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;
@@ -186,9 +186,9 @@ SSL_AuthCertificateHook(PRFileDesc *s, SSLAuthCertificate func, void *arg)
ss = ssl_FindSocket(s);
if (!ss) {
- SSL_DBG(("%d: SSL[%d]: bad socket in AuthCertificateHook",
- SSL_GETPID(), s));
- return SECFailure;
+ SSL_DBG(("%d: SSL[%d]: bad socket in AuthCertificateHook",
+ SSL_GETPID(), s));
+ return SECFailure;
}
ss->authCertificate = func;
@@ -198,17 +198,17 @@ SSL_AuthCertificateHook(PRFileDesc *s, SSLAuthCertificate func, void *arg)
}
/* NEED LOCKS IN HERE. */
-SECStatus
+SECStatus
SSL_GetClientAuthDataHook(PRFileDesc *s, SSLGetClientAuthData func,
- void *arg)
+ void *arg)
{
sslSocket *ss;
ss = ssl_FindSocket(s);
if (!ss) {
- SSL_DBG(("%d: SSL[%d]: bad socket in GetClientAuthDataHook",
- SSL_GETPID(), s));
- return SECFailure;
+ SSL_DBG(("%d: SSL[%d]: bad socket in GetClientAuthDataHook",
+ SSL_GETPID(), s));
+ return SECFailure;
}
ss->getClientAuthData = func;
@@ -217,77 +217,76 @@ SSL_GetClientAuthDataHook(PRFileDesc *s, SSLGetClientAuthData func,
}
/* NEED LOCKS IN HERE. */
-SECStatus
+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;
+ 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
+/* 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;
-
+ SECStatus rv;
+ CERTCertDBHandle *handle;
+ sslSocket *ss;
+ SECCertUsage certUsage;
+ const char *hostname = NULL;
+ PRTime now = PR_Now();
+ SECItemArray *certStatusArray;
+
ss = ssl_FindSocket(fd);
PORT_Assert(ss != NULL);
if (!ss) {
- return SECFailure;
+ return SECFailure;
}
handle = (CERTCertDBHandle *)arg;
certStatusArray = &ss->sec.ci.sid->peerCertStatus;
if (certStatusArray->len) {
- PORT_SetError(0);
- if (CERT_CacheOCSPResponseFromSideChannel(handle, ss->sec.peerCert, now,
- &certStatusArray->items[0],
- ss->pkcs11PinArg)
- != SECSuccess) {
- PORT_Assert(PR_GetError() != 0);
- }
+ PORT_SetError(0);
+ if (CERT_CacheOCSPResponseFromSideChannel(handle, ss->sec.peerCert, now,
+ &certStatusArray->items[0],
+ ss->pkcs11PinArg) !=
+ SECSuccess) {
+ PORT_Assert(PR_GetError() != 0);
+ }
}
/* this may seem backwards, but isn't. */
certUsage = isServer ? certUsageSSLClient : certUsageSSLServer;
rv = CERT_VerifyCert(handle, ss->sec.peerCert, checkSig, certUsage,
- now, ss->pkcs11PinArg, NULL);
+ now, ss->pkcs11PinArg, NULL);
+
+ if (rv != SECSuccess || isServer)
+ return rv;
- 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;
+ rv = CERT_VerifyCertName(ss->sec.peerCert, hostname);
+ else
+ rv = SECFailure;
if (rv != SECSuccess)
- PORT_SetError(SSL_ERROR_BAD_CERT_DOMAIN);
+ PORT_SetError(SSL_ERROR_BAD_CERT_DOMAIN);
return rv;
}
diff --git a/nss/lib/ssl/sslcert.c b/nss/lib/ssl/sslcert.c
new file mode 100644
index 0000000..ea52455
--- /dev/null
+++ b/nss/lib/ssl/sslcert.c
@@ -0,0 +1,992 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * SSL server certificate configuration 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 "ssl.h"
+#include "sslimpl.h"
+#include "secoid.h" /* for SECOID_GetAlgorithmTag */
+#include "pk11func.h" /* for PK11_ReferenceSlot */
+#include "nss.h" /* for NSS_RegisterShutdown */
+#include "prinit.h" /* for PR_CallOnceWithArg */
+
+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;
+}
+
+sslServerCert *
+ssl_NewServerCert(const sslServerCertType *certType)
+{
+ sslServerCert *sc = PORT_ZNew(sslServerCert);
+ if (!sc) {
+ return NULL;
+ }
+ memcpy(&sc->certType, certType, sizeof(sc->certType));
+ sc->serverCert = NULL;
+ sc->serverCertChain = NULL;
+ sc->certStatusArray = NULL;
+ sc->signedCertTimestamps.len = 0;
+ return sc;
+}
+
+sslServerCert *
+ssl_CopyServerCert(const sslServerCert *oc)
+{
+ sslServerCert *sc;
+
+ sc = ssl_NewServerCert(&oc->certType);
+ if (!sc) {
+ return NULL;
+ }
+
+ if (oc->serverCert && oc->serverCertChain) {
+ sc->serverCert = CERT_DupCertificate(oc->serverCert);
+ if (!sc->serverCert)
+ goto loser;
+ sc->serverCertChain = CERT_DupCertList(oc->serverCertChain);
+ if (!sc->serverCertChain)
+ goto loser;
+ } else {
+ sc->serverCert = NULL;
+ sc->serverCertChain = NULL;
+ }
+
+ if (oc->serverKeyPair) {
+ sc->serverKeyPair = ssl_GetKeyPairRef(oc->serverKeyPair);
+ if (!sc->serverKeyPair)
+ goto loser;
+ } else {
+ sc->serverKeyPair = NULL;
+ }
+ sc->serverKeyBits = oc->serverKeyBits;
+
+ if (oc->certStatusArray) {
+ sc->certStatusArray = SECITEM_DupArray(NULL, oc->certStatusArray);
+ if (!sc->certStatusArray)
+ goto loser;
+ } else {
+ sc->certStatusArray = NULL;
+ }
+
+ if (SECITEM_CopyItem(NULL, &sc->signedCertTimestamps,
+ &oc->signedCertTimestamps) != SECSuccess)
+ goto loser;
+ return sc;
+loser:
+ ssl_FreeServerCert(sc);
+ return NULL;
+}
+
+void
+ssl_FreeServerCert(sslServerCert *sc)
+{
+ if (!sc) {
+ return;
+ }
+
+ if (sc->serverCert) {
+ CERT_DestroyCertificate(sc->serverCert);
+ }
+ if (sc->serverCertChain) {
+ CERT_DestroyCertificateList(sc->serverCertChain);
+ }
+ if (sc->serverKeyPair) {
+ ssl_FreeKeyPair(sc->serverKeyPair);
+ }
+ if (sc->certStatusArray) {
+ SECITEM_FreeArray(sc->certStatusArray, PR_TRUE);
+ }
+ if (sc->signedCertTimestamps.len) {
+ SECITEM_FreeItem(&sc->signedCertTimestamps, PR_FALSE);
+ }
+ PORT_ZFree(sc, sizeof(*sc));
+}
+
+sslServerCert *
+ssl_FindServerCert(const sslSocket *ss,
+ const sslServerCertType *certType)
+{
+ PRCList *cursor;
+
+ for (cursor = PR_NEXT_LINK(&ss->serverCerts);
+ cursor != &ss->serverCerts;
+ cursor = PR_NEXT_LINK(cursor)) {
+ sslServerCert *cert = (sslServerCert *)cursor;
+ if (cert->certType.authType != certType->authType) {
+ continue;
+ }
+ switch (cert->certType.authType) {
+ case ssl_auth_ecdsa:
+ case ssl_auth_ecdh_rsa:
+ case ssl_auth_ecdh_ecdsa:
+ /* Note: For deprecated APIs, we need to be able to find and
+ match a slot with any named curve. */
+ if (certType->namedCurve &&
+ cert->certType.namedCurve != certType->namedCurve) {
+ continue;
+ }
+ break;
+ default:
+ break;
+ }
+ return cert;
+ }
+ return NULL;
+}
+
+sslServerCert *
+ssl_FindServerCertByAuthType(const sslSocket *ss, SSLAuthType authType)
+{
+ sslServerCertType certType;
+ certType.authType = authType;
+ /* Setting the named curve to NULL ensures that all EC certificates
+ * are matched when searching for this slot. */
+ certType.namedCurve = NULL;
+ return ssl_FindServerCert(ss, &certType);
+}
+
+SECStatus
+ssl_OneTimeCertSetup(sslSocket *ss, const sslServerCert *sc)
+{
+ if (PR_SUCCESS != PR_CallOnceWithArg(&setupServerCAListOnce,
+ &serverCAListSetup,
+ (void *)(ss->dbHandle))) {
+ return SECFailure;
+ }
+ return SECSuccess;
+}
+
+/* Determine which slot a certificate fits into. SSLAuthType is known, but
+ * extra information needs to be worked out from the cert and key. */
+static void
+ssl_PopulateCertType(sslServerCertType *certType, SSLAuthType authType,
+ CERTCertificate *cert, sslKeyPair *keyPair)
+{
+ certType->authType = authType;
+ switch (authType) {
+ case ssl_auth_ecdsa:
+ case ssl_auth_ecdh_rsa:
+ case ssl_auth_ecdh_ecdsa:
+ certType->namedCurve = ssl_ECPubKey2NamedGroup(keyPair->pubKey);
+ break;
+ default:
+ break;
+ }
+}
+
+static SECStatus
+ssl_PopulateServerCert(sslServerCert *sc, CERTCertificate *cert,
+ const CERTCertificateList *certChain)
+{
+ if (sc->serverCert) {
+ CERT_DestroyCertificate(sc->serverCert);
+ }
+ if (sc->serverCertChain) {
+ CERT_DestroyCertificateList(sc->serverCertChain);
+ }
+
+ if (!cert) {
+ sc->serverCert = NULL;
+ sc->serverCertChain = NULL;
+ return SECSuccess;
+ }
+
+ sc->serverCert = CERT_DupCertificate(cert);
+ if (certChain) {
+ sc->serverCertChain = CERT_DupCertList(certChain);
+ } else {
+ sc->serverCertChain =
+ CERT_CertChainFromCert(sc->serverCert, certUsageSSLServer,
+ PR_TRUE);
+ }
+ return sc->serverCertChain ? SECSuccess : SECFailure;
+}
+
+static SECStatus
+ssl_PopulateKeyPair(sslServerCert *sc, sslKeyPair *keyPair)
+{
+ /* Copy over the key pair. */
+ if (sc->serverKeyPair) {
+ ssl_FreeKeyPair(sc->serverKeyPair);
+ }
+ if (keyPair) {
+ /* Get the size of the cert's public key, and remember it. */
+ sc->serverKeyBits = SECKEY_PublicKeyStrengthInBits(keyPair->pubKey);
+ if (sc->serverKeyBits == 0) {
+ return SECFailure;
+ }
+
+ SECKEY_CacheStaticFlags(keyPair->privKey);
+ sc->serverKeyPair = ssl_GetKeyPairRef(keyPair);
+ } else {
+ sc->serverKeyPair = NULL;
+ }
+ return SECSuccess;
+}
+
+static SECStatus
+ssl_PopulateOCSPResponses(sslServerCert *sc,
+ const SECItemArray *stapledOCSPResponses)
+{
+ if (sc->certStatusArray) {
+ SECITEM_FreeArray(sc->certStatusArray, PR_TRUE);
+ }
+ if (stapledOCSPResponses) {
+ sc->certStatusArray = SECITEM_DupArray(NULL, stapledOCSPResponses);
+ return sc->certStatusArray ? SECSuccess : SECFailure;
+ } else {
+ sc->certStatusArray = NULL;
+ }
+ return SECSuccess;
+}
+
+static SECStatus
+ssl_PopulateSignedCertTimestamps(sslServerCert *sc,
+ const SECItem *signedCertTimestamps)
+{
+ if (sc->signedCertTimestamps.len) {
+ SECITEM_FreeItem(&sc->signedCertTimestamps, PR_FALSE);
+ }
+ if (signedCertTimestamps && signedCertTimestamps->len) {
+ return SECITEM_CopyItem(NULL, &sc->signedCertTimestamps,
+ signedCertTimestamps);
+ }
+ return SECSuccess;
+}
+
+static SECStatus
+ssl_ConfigCert(sslSocket *ss, CERTCertificate *cert,
+ sslKeyPair *keyPair, const SSLExtraServerCertData *data)
+{
+ sslServerCert *oldsc;
+ sslServerCertType certType;
+ SECStatus rv;
+ sslServerCert *sc = NULL;
+ int error_code = SEC_ERROR_NO_MEMORY;
+
+ PORT_Assert(cert);
+ PORT_Assert(keyPair);
+ PORT_Assert(data);
+ PORT_Assert(data->authType != ssl_auth_null);
+
+ if (!cert || !keyPair || !data || data->authType == ssl_auth_null) {
+ error_code = SEC_ERROR_INVALID_ARGS;
+ goto loser;
+ }
+
+ ssl_PopulateCertType(&certType, data->authType, cert, keyPair);
+
+ /* Delete any existing certificate that matches this one, since we can only
+ * use one certificate of a given type. */
+ oldsc = ssl_FindServerCert(ss, &certType);
+ if (oldsc) {
+ PR_REMOVE_LINK(&oldsc->link);
+ ssl_FreeServerCert(oldsc);
+ }
+ sc = ssl_NewServerCert(&certType);
+ if (!sc) {
+ goto loser;
+ }
+
+ rv = ssl_PopulateServerCert(sc, cert, data->certChain);
+ if (rv != SECSuccess) {
+ goto loser;
+ }
+ rv = ssl_PopulateKeyPair(sc, keyPair);
+ if (rv != SECSuccess) {
+ error_code = SEC_ERROR_INVALID_ARGS;
+ goto loser;
+ }
+ rv = ssl_PopulateOCSPResponses(sc, data->stapledOCSPResponses);
+ if (rv != SECSuccess) {
+ goto loser;
+ }
+ rv = ssl_PopulateSignedCertTimestamps(sc, data->signedCertTimestamps);
+ if (rv != SECSuccess) {
+ goto loser;
+ }
+ PR_APPEND_LINK(&sc->link, &ss->serverCerts);
+
+ /* This one-time setup depends on having the certificate in place. */
+ rv = ssl_OneTimeCertSetup(ss, sc);
+ if (rv != SECSuccess) {
+ PR_REMOVE_LINK(&sc->link);
+ error_code = PORT_GetError();
+ goto loser;
+ }
+ return SECSuccess;
+
+loser:
+ if (sc) {
+ ssl_FreeServerCert(sc);
+ }
+ /* This is the only way any of the calls above can fail, except the one time
+ * setup, which doesn't land here. */
+ PORT_SetError(error_code);
+ return SECFailure;
+}
+
+static SSLAuthType
+ssl_GetEcdhAuthType(CERTCertificate *cert)
+{
+ SECOidTag sigTag = SECOID_GetAlgorithmTag(&cert->signature);
+ switch (sigTag) {
+ case SEC_OID_PKCS1_RSA_ENCRYPTION:
+ case SEC_OID_PKCS1_RSA_PSS_SIGNATURE:
+ 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:
+ return ssl_auth_ecdh_rsa;
+ 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:
+ return ssl_auth_ecdh_ecdsa;
+ default:
+ return ssl_auth_null;
+ }
+}
+
+/* This function examines the key usages of the given RSA-PKCS1 certificate
+ * and configures one or multiple server certificates based on that data.
+ *
+ * If the data argument contains an authType value other than ssl_auth_null,
+ * then only that slot will be used. If that choice is invalid,
+ * then this will fail. */
+static SECStatus
+ssl_ConfigRsaPkcs1CertByUsage(sslSocket *ss, CERTCertificate *cert,
+ sslKeyPair *keyPair,
+ SSLExtraServerCertData *data)
+{
+ SECStatus rv = SECFailure;
+
+ PRBool ku_sig = (PRBool)(cert->keyUsage & KU_DIGITAL_SIGNATURE);
+ PRBool ku_enc = (PRBool)(cert->keyUsage & KU_KEY_ENCIPHERMENT);
+
+ if ((data->authType == ssl_auth_rsa_sign && ku_sig) ||
+ (data->authType == ssl_auth_rsa_pss && ku_sig) ||
+ (data->authType == ssl_auth_rsa_decrypt && ku_enc)) {
+ return ssl_ConfigCert(ss, cert, keyPair, data);
+ }
+
+ if (data->authType != ssl_auth_null || !(ku_sig || ku_enc)) {
+ PORT_SetError(SEC_ERROR_INVALID_ARGS);
+ return SECFailure;
+ }
+
+ if (ku_sig) {
+ data->authType = ssl_auth_rsa_sign;
+ rv = ssl_ConfigCert(ss, cert, keyPair, data);
+ if (rv != SECSuccess) {
+ return rv;
+ }
+
+ /* This certificate is RSA, assume that it's also PSS. */
+ data->authType = ssl_auth_rsa_pss;
+ rv = ssl_ConfigCert(ss, cert, keyPair, data);
+ if (rv != SECSuccess) {
+ return rv;
+ }
+ }
+
+ if (ku_enc) {
+ /* If ku_sig=true we configure signature and encryption slots with the
+ * same cert. This is bad form, but there are enough dual-usage RSA
+ * certs that we can't really break by limiting this to one type. */
+ data->authType = ssl_auth_rsa_decrypt;
+ rv = ssl_ConfigCert(ss, cert, keyPair, data);
+ if (rv != SECSuccess) {
+ return rv;
+ }
+ }
+
+ return rv;
+}
+
+/* This function examines the type of certificate and its key usage and
+ * configures a certificate based on that information. For some certificates
+ * this can mean that multiple server certificates are configured.
+ *
+ * If the data argument contains an authType value other than ssl_auth_null,
+ * then only that slot will be used. If that choice is invalid,
+ * then this will fail. */
+static SECStatus
+ssl_ConfigCertByUsage(sslSocket *ss, CERTCertificate *cert,
+ sslKeyPair *keyPair, const SSLExtraServerCertData *data)
+{
+ SECStatus rv = SECFailure;
+ SSLExtraServerCertData arg;
+ SECOidTag tag;
+
+ PORT_Assert(data);
+ /* Take a (shallow) copy so that we can play with it */
+ memcpy(&arg, data, sizeof(arg));
+
+ tag = SECOID_GetAlgorithmTag(&cert->subjectPublicKeyInfo.algorithm);
+ switch (tag) {
+ case SEC_OID_X500_RSA_ENCRYPTION:
+ case SEC_OID_PKCS1_RSA_ENCRYPTION:
+ return ssl_ConfigRsaPkcs1CertByUsage(ss, cert, keyPair, &arg);
+
+ case SEC_OID_PKCS1_RSA_PSS_SIGNATURE:
+ if (cert->keyUsage & KU_DIGITAL_SIGNATURE) {
+ arg.authType = ssl_auth_rsa_pss;
+ }
+ break;
+
+ case SEC_OID_ANSIX9_DSA_SIGNATURE:
+ if (cert->keyUsage & KU_DIGITAL_SIGNATURE) {
+ arg.authType = ssl_auth_dsa;
+ }
+ break;
+
+ case SEC_OID_ANSIX962_EC_PUBLIC_KEY:
+ if (cert->keyUsage & KU_KEY_ENCIPHERMENT) {
+ if ((cert->keyUsage & KU_DIGITAL_SIGNATURE) &&
+ arg.authType == ssl_auth_null) {
+ /* See above regarding bad practice. */
+ arg.authType = ssl_auth_ecdsa;
+ rv = ssl_ConfigCert(ss, cert, keyPair, &arg);
+ if (rv != SECSuccess) {
+ return rv;
+ }
+ }
+
+ arg.authType = ssl_GetEcdhAuthType(cert);
+ } else if (cert->keyUsage & KU_DIGITAL_SIGNATURE) {
+ arg.authType = ssl_auth_ecdsa;
+ }
+ break;
+
+ default:
+ break;
+ }
+
+ /* Check that we successfully picked an authType */
+ if (arg.authType == ssl_auth_null) {
+ PORT_SetError(SEC_ERROR_INVALID_ARGS);
+ return SECFailure;
+ }
+ /* |data->authType| has to either agree or be ssl_auth_null. */
+ if (data && data->authType != ssl_auth_null &&
+ data->authType != arg.authType) {
+ PORT_SetError(SEC_ERROR_INVALID_ARGS);
+ return SECFailure;
+ }
+ return ssl_ConfigCert(ss, cert, keyPair, &arg);
+}
+
+/* This function adopts pubKey and destroys it if things go wrong. */
+static sslKeyPair *
+ssl_MakeKeyPairForCert(SECKEYPrivateKey *key, SECKEYPublicKey *pubKey)
+{
+ sslKeyPair *keyPair = NULL;
+ SECKEYPrivateKey *privKeyCopy = NULL;
+ PK11SlotInfo *bestSlot;
+
+ if (key->pkcs11Slot) {
+ bestSlot = PK11_ReferenceSlot(key->pkcs11Slot);
+ if (bestSlot) {
+ privKeyCopy = PK11_CopyTokenPrivKeyToSessionPrivKey(bestSlot, key);
+ PK11_FreeSlot(bestSlot);
+ }
+ }
+ if (!privKeyCopy) {
+ CK_MECHANISM_TYPE keyMech = PK11_MapSignKeyType(key->keyType);
+ /* XXX Maybe should be bestSlotMultiple? */
+ bestSlot = PK11_GetBestSlot(keyMech, NULL /* wincx */);
+ if (bestSlot) {
+ privKeyCopy = PK11_CopyTokenPrivKeyToSessionPrivKey(bestSlot, key);
+ PK11_FreeSlot(bestSlot);
+ }
+ }
+ if (!privKeyCopy) {
+ privKeyCopy = SECKEY_CopyPrivateKey(key);
+ }
+ if (privKeyCopy) {
+ keyPair = ssl_NewKeyPair(privKeyCopy, pubKey);
+ }
+ if (!keyPair) {
+ if (privKeyCopy) {
+ SECKEY_DestroyPrivateKey(privKeyCopy);
+ }
+ /* We adopted the public key, so we're responsible. */
+ if (pubKey) {
+ SECKEY_DestroyPublicKey(pubKey);
+ }
+ }
+ return keyPair;
+}
+
+/* Configure a certificate and private key.
+ *
+ * This function examines the certificate and key to determine which slot (or
+ * slots) to place the information in. As long as certificates are different
+ * (based on having different values of sslServerCertType), then this function
+ * can be called multiple times and the certificates will all be remembered.
+ */
+SECStatus
+SSL_ConfigServerCert(PRFileDesc *fd, CERTCertificate *cert,
+ SECKEYPrivateKey *key,
+ const SSLExtraServerCertData *data, unsigned int data_len)
+{
+ sslSocket *ss;
+ SECKEYPublicKey *pubKey;
+ sslKeyPair *keyPair;
+ SECStatus rv;
+ SSLExtraServerCertData dataCopy = {
+ ssl_auth_null, NULL, NULL, NULL
+ };
+
+ ss = ssl_FindSocket(fd);
+ if (!ss) {
+ return SECFailure;
+ }
+
+ if (!cert || !key) {
+ PORT_SetError(SEC_ERROR_INVALID_ARGS);
+ return SECFailure;
+ }
+
+ if (data) {
+ if (data_len > sizeof(dataCopy)) {
+ PORT_SetError(SEC_ERROR_INVALID_ARGS);
+ return SECFailure;
+ }
+ PORT_Memcpy(&dataCopy, data, data_len);
+ }
+
+ pubKey = CERT_ExtractPublicKey(cert);
+ if (!pubKey) {
+ return SECFailure;
+ }
+
+ keyPair = ssl_MakeKeyPairForCert(key, pubKey);
+ if (!keyPair) {
+ /* pubKey is adopted by ssl_MakeKeyPairForCert() */
+ PORT_SetError(SEC_ERROR_NO_MEMORY);
+ return SECFailure;
+ }
+
+ rv = ssl_ConfigCertByUsage(ss, cert, keyPair, &dataCopy);
+ ssl_FreeKeyPair(keyPair);
+ return rv;
+}
+
+/*******************************************************************/
+/* Deprecated functions.
+ *
+ * The remainder of this file contains deprecated functions for server
+ * certificate configuration. These configure certificates incorrectly, but in
+ * a way that allows old code to continue working without change. All these
+ * functions create certificate slots based on SSLKEAType values. Some values
+ * of SSLKEAType cause multiple certificates to be configured.
+ */
+
+SECStatus
+SSL_ConfigSecureServer(PRFileDesc *fd, CERTCertificate *cert,
+ SECKEYPrivateKey *key, SSLKEAType kea)
+{
+ return SSL_ConfigSecureServerWithCertChain(fd, cert, NULL, key, kea);
+}
+
+/* This implements a limited check that is consistent with the checks performed
+ * by older versions of NSS. This is less rigorous than the checks in
+ * ssl_ConfigCertByUsage(), only checking against the type of key and ignoring
+ * things like usage. */
+static PRBool
+ssl_CertSuitableForAuthType(CERTCertificate *cert, SSLAuthType authType)
+{
+ SECOidTag tag = SECOID_GetAlgorithmTag(&cert->subjectPublicKeyInfo.algorithm);
+ switch (authType) {
+ case ssl_auth_rsa_decrypt:
+ case ssl_auth_rsa_sign:
+ return tag == SEC_OID_X500_RSA_ENCRYPTION ||
+ tag == SEC_OID_PKCS1_RSA_ENCRYPTION;
+ case ssl_auth_dsa:
+ return tag == SEC_OID_ANSIX9_DSA_SIGNATURE;
+ case ssl_auth_ecdsa:
+ case ssl_auth_ecdh_rsa:
+ case ssl_auth_ecdh_ecdsa:
+ return tag == SEC_OID_ANSIX962_EC_PUBLIC_KEY;
+ case ssl_auth_null:
+ case ssl_auth_kea:
+ case ssl_auth_rsa_pss: /* not supported with deprecated APIs */
+ return PR_FALSE;
+ default:
+ PORT_Assert(0);
+ return PR_FALSE;
+ }
+}
+
+/* This finds an existing server cert slot and unlinks it, or it makes a new
+ * server cert slot of the right type. */
+static sslServerCert *
+ssl_FindOrMakeCertType(sslSocket *ss, SSLAuthType authType)
+{
+ sslServerCert *sc;
+ sslServerCertType certType;
+
+ certType.authType = authType;
+ /* Setting the named curve to NULL ensures that all EC certificates
+ * are matched when searching for this slot. */
+ certType.namedCurve = NULL;
+ sc = ssl_FindServerCert(ss, &certType);
+ if (sc) {
+ PR_REMOVE_LINK(&sc->link);
+ return sc;
+ }
+
+ return ssl_NewServerCert(&certType);
+}
+
+static void
+ssl_RemoveCertAndKeyByAuthType(sslSocket *ss, SSLAuthType authType)
+{
+ sslServerCert *sc;
+
+ sc = ssl_FindServerCertByAuthType(ss, authType);
+ if (sc) {
+ (void)ssl_PopulateServerCert(sc, NULL, NULL);
+ (void)ssl_PopulateKeyPair(sc, NULL);
+ /* Leave the entry linked here because the old API expects that. There
+ * might be OCSP stapling values or signed certificate timestamps still
+ * present that will subsequently be used. */
+ /* For ECC certificates, also leave the namedCurve parameter on the slot
+ * unchanged; the value will be updated when a key is added. */
+ }
+}
+
+static SECStatus
+ssl_AddCertAndKeyByAuthType(sslSocket *ss, SSLAuthType authType,
+ CERTCertificate *cert,
+ const CERTCertificateList *certChainOpt,
+ sslKeyPair *keyPair)
+{
+ sslServerCert *sc;
+ SECStatus rv;
+
+ if (!ssl_CertSuitableForAuthType(cert, authType)) {
+ PORT_SetError(SEC_ERROR_INVALID_ARGS);
+ return SECFailure;
+ }
+
+ sc = ssl_FindOrMakeCertType(ss, authType);
+ if (!sc) {
+ PORT_SetError(SEC_ERROR_NO_MEMORY);
+ return SECFailure;
+ }
+ rv = ssl_PopulateKeyPair(sc, keyPair);
+ if (rv != SECSuccess) {
+ PORT_SetError(SEC_ERROR_INVALID_ARGS);
+ goto loser;
+ }
+ /* Now that we have a key pair, update the details of the slot. Many of the
+ * legacy functions create a slot with a namedCurve of NULL, which
+ * makes the slot unusable; this corrects that. */
+ ssl_PopulateCertType(&sc->certType, authType, cert, keyPair);
+ rv = ssl_PopulateServerCert(sc, cert, certChainOpt);
+ if (rv != SECSuccess) {
+ PORT_SetError(SEC_ERROR_NO_MEMORY);
+ goto loser;
+ }
+ PR_APPEND_LINK(&sc->link, &ss->serverCerts);
+ return ssl_OneTimeCertSetup(ss, sc);
+loser:
+ ssl_FreeServerCert(sc);
+ return SECFailure;
+}
+
+static SECStatus
+ssl_AddCertsByKEA(sslSocket *ss, CERTCertificate *cert,
+ const CERTCertificateList *certChainOpt,
+ SECKEYPrivateKey *key, SSLKEAType certType)
+{
+ SECKEYPublicKey *pubKey;
+ sslKeyPair *keyPair;
+ SECStatus rv;
+
+ pubKey = CERT_ExtractPublicKey(cert);
+ if (!pubKey) {
+ return SECFailure;
+ }
+
+ keyPair = ssl_MakeKeyPairForCert(key, pubKey);
+ if (!keyPair) {
+ /* Note: pubKey is adopted or freed by ssl_MakeKeyPairForCert()
+ * depending on whether it succeeds or not. */
+ PORT_SetError(SEC_ERROR_NO_MEMORY);
+ return SECFailure;
+ }
+
+ switch (certType) {
+ case ssl_kea_rsa:
+ rv = ssl_AddCertAndKeyByAuthType(ss, ssl_auth_rsa_decrypt,
+ cert, certChainOpt, keyPair);
+ if (rv != SECSuccess) {
+ return SECFailure;
+ }
+ rv = ssl_AddCertAndKeyByAuthType(ss, ssl_auth_rsa_sign,
+ cert, certChainOpt, keyPair);
+ break;
+
+ case ssl_kea_dh:
+ rv = ssl_AddCertAndKeyByAuthType(ss, ssl_auth_dsa,
+ cert, certChainOpt, keyPair);
+ break;
+
+ case ssl_kea_ecdh:
+ rv = ssl_AddCertAndKeyByAuthType(ss, ssl_auth_ecdsa,
+ cert, certChainOpt, keyPair);
+ if (rv != SECSuccess) {
+ return SECFailure;
+ }
+ rv = ssl_AddCertAndKeyByAuthType(ss, ssl_GetEcdhAuthType(cert),
+ cert, certChainOpt, keyPair);
+ break;
+
+ default:
+ PORT_SetError(SEC_ERROR_INVALID_ARGS);
+ rv = SECFailure;
+ break;
+ }
+
+ ssl_FreeKeyPair(keyPair);
+ return rv;
+}
+
+/* Public deprecated function */
+SECStatus
+SSL_ConfigSecureServerWithCertChain(PRFileDesc *fd, CERTCertificate *cert,
+ const CERTCertificateList *certChainOpt,
+ SECKEYPrivateKey *key, SSLKEAType certType)
+{
+ sslSocket *ss;
+
+ ss = ssl_FindSocket(fd);
+ if (!ss) {
+ return SECFailure;
+ }
+
+ if (!cert != !key) { /* Configure both, or neither */
+ PORT_SetError(SEC_ERROR_INVALID_ARGS);
+ return SECFailure;
+ }
+
+ if (!cert) {
+ switch (certType) {
+ case ssl_kea_rsa:
+ ssl_RemoveCertAndKeyByAuthType(ss, ssl_auth_rsa_decrypt);
+ ssl_RemoveCertAndKeyByAuthType(ss, ssl_auth_rsa_sign);
+ break;
+
+ case ssl_kea_dh:
+ ssl_RemoveCertAndKeyByAuthType(ss, ssl_auth_dsa);
+ break;
+
+ case ssl_kea_ecdh:
+ ssl_RemoveCertAndKeyByAuthType(ss, ssl_auth_ecdsa);
+ ssl_RemoveCertAndKeyByAuthType(ss, ssl_auth_ecdh_rsa);
+ ssl_RemoveCertAndKeyByAuthType(ss, ssl_auth_ecdh_ecdsa);
+ break;
+
+ default:
+ PORT_SetError(SEC_ERROR_INVALID_ARGS);
+ return SECFailure;
+ }
+ return SECSuccess;
+ }
+
+ return ssl_AddCertsByKEA(ss, cert, certChainOpt, key, certType);
+}
+
+static SECStatus
+ssl_SetOCSPResponsesInSlot(sslSocket *ss, SSLAuthType authType,
+ const SECItemArray *responses)
+{
+ sslServerCert *sc;
+ SECStatus rv;
+
+ sc = ssl_FindOrMakeCertType(ss, authType);
+ if (!sc) {
+ PORT_SetError(SEC_ERROR_NO_MEMORY);
+ return SECFailure;
+ }
+ rv = ssl_PopulateOCSPResponses(sc, responses);
+ if (rv == SECSuccess) {
+ PR_APPEND_LINK(&sc->link, &ss->serverCerts);
+ } else {
+ ssl_FreeServerCert(sc);
+ }
+ return rv;
+}
+
+/* Public deprecated function */
+SECStatus
+SSL_SetStapledOCSPResponses(PRFileDesc *fd, const SECItemArray *responses,
+ SSLKEAType certType)
+{
+ sslSocket *ss;
+ SECStatus rv;
+
+ ss = ssl_FindSocket(fd);
+ if (!ss) {
+ SSL_DBG(("%d: SSL[%d]: bad socket in SSL_SetStapledOCSPResponses",
+ SSL_GETPID(), fd));
+ return SECFailure;
+ }
+
+ switch (certType) {
+ case ssl_kea_rsa:
+ rv = ssl_SetOCSPResponsesInSlot(ss, ssl_auth_rsa_decrypt, responses);
+ if (rv != SECSuccess) {
+ return SECFailure;
+ }
+ return ssl_SetOCSPResponsesInSlot(ss, ssl_auth_rsa_sign, responses);
+
+ case ssl_kea_dh:
+ return ssl_SetOCSPResponsesInSlot(ss, ssl_auth_dsa, responses);
+
+ case ssl_kea_ecdh:
+ rv = ssl_SetOCSPResponsesInSlot(ss, ssl_auth_ecdsa, responses);
+ if (rv != SECSuccess) {
+ return SECFailure;
+ }
+ rv = ssl_SetOCSPResponsesInSlot(ss, ssl_auth_ecdh_rsa, responses);
+ if (rv != SECSuccess) {
+ return SECFailure;
+ }
+ return ssl_SetOCSPResponsesInSlot(ss, ssl_auth_ecdh_ecdsa, responses);
+
+ default:
+ SSL_DBG(("%d: SSL[%d]: invalid cert type in SSL_SetStapledOCSPResponses",
+ SSL_GETPID(), fd));
+ PORT_SetError(SEC_ERROR_INVALID_ARGS);
+ return SECFailure;
+ }
+}
+
+static SECStatus
+ssl_SetSignedTimestampsInSlot(sslSocket *ss, SSLAuthType authType,
+ const SECItem *scts)
+{
+ sslServerCert *sc;
+ SECStatus rv;
+
+ sc = ssl_FindOrMakeCertType(ss, authType);
+ if (!sc) {
+ PORT_SetError(SEC_ERROR_NO_MEMORY);
+ return SECFailure;
+ }
+ rv = ssl_PopulateSignedCertTimestamps(sc, scts);
+ if (rv == SECSuccess) {
+ PR_APPEND_LINK(&sc->link, &ss->serverCerts);
+ } else {
+ ssl_FreeServerCert(sc);
+ }
+ return rv;
+}
+
+/* Public deprecated function */
+SECStatus
+SSL_SetSignedCertTimestamps(PRFileDesc *fd, const SECItem *scts,
+ SSLKEAType certType)
+{
+ sslSocket *ss;
+ SECStatus rv;
+
+ ss = ssl_FindSocket(fd);
+ if (!ss) {
+ SSL_DBG(("%d: SSL[%d]: bad socket in SSL_SetSignedCertTimestamps",
+ SSL_GETPID(), fd));
+ return SECFailure;
+ }
+
+ switch (certType) {
+ case ssl_kea_rsa:
+ rv = ssl_SetSignedTimestampsInSlot(ss, ssl_auth_rsa_decrypt, scts);
+ if (rv != SECSuccess) {
+ return SECFailure;
+ }
+ return ssl_SetSignedTimestampsInSlot(ss, ssl_auth_rsa_sign, scts);
+
+ case ssl_kea_dh:
+ return ssl_SetSignedTimestampsInSlot(ss, ssl_auth_dsa, scts);
+
+ case ssl_kea_ecdh:
+ rv = ssl_SetSignedTimestampsInSlot(ss, ssl_auth_ecdsa, scts);
+ if (rv != SECSuccess) {
+ return SECFailure;
+ }
+ rv = ssl_SetSignedTimestampsInSlot(ss, ssl_auth_ecdh_rsa, scts);
+ if (rv != SECSuccess) {
+ return SECFailure;
+ }
+ return ssl_SetSignedTimestampsInSlot(ss, ssl_auth_ecdh_ecdsa, scts);
+
+ default:
+ SSL_DBG(("%d: SSL[%d]: invalid cert type in SSL_SetSignedCertTimestamps",
+ SSL_GETPID(), fd));
+ PORT_SetError(SEC_ERROR_INVALID_ARGS);
+ return SECFailure;
+ }
+}
+
+/* Public deprecated function. */
+SSLKEAType
+NSS_FindCertKEAType(CERTCertificate *cert)
+{
+ int tag;
+
+ if (!cert)
+ return ssl_kea_null;
+
+ tag = SECOID_GetAlgorithmTag(&(cert->subjectPublicKeyInfo.algorithm));
+ switch (tag) {
+ case SEC_OID_X500_RSA_ENCRYPTION:
+ case SEC_OID_PKCS1_RSA_ENCRYPTION:
+ return ssl_kea_rsa;
+ case SEC_OID_ANSIX9_DSA_SIGNATURE: /* hah, signature, not a key? */
+ case SEC_OID_X942_DIFFIE_HELMAN_KEY:
+ return ssl_kea_dh;
+ case SEC_OID_ANSIX962_EC_PUBLIC_KEY:
+ return ssl_kea_ecdh;
+ default:
+ return ssl_kea_null;
+ }
+}
diff --git a/nss/lib/ssl/sslcert.h b/nss/lib/ssl/sslcert.h
new file mode 100644
index 0000000..052c7d6
--- /dev/null
+++ b/nss/lib/ssl/sslcert.h
@@ -0,0 +1,59 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is PRIVATE to SSL.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.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 __sslcert_h_
+#define __sslcert_h_
+
+#include "cert.h"
+#include "secitem.h"
+#include "keyhi.h"
+
+/* The following struct identifies a single slot into which a certificate can be
+** loaded. The authType field determines the basic slot, then additional
+** parameters further narrow the slot.
+**
+** An EC key (ssl_auth_ecdsa or ssl_auth_ecdh_*) is assigned to a slot based on
+** the named curve of the key.
+*/
+typedef struct sslServerCertTypeStr {
+ SSLAuthType authType;
+ /* For ssl_auth_ecdsa and ssl_auth_ecdh_*. This is only the named curve
+ * of the end-entity certificate key. The keys in other certificates in
+ * the chain aren't directly relevant to the operation of TLS (though it
+ * might make certificate validation difficult, libssl doesn't care). */
+ const sslNamedGroupDef *namedCurve;
+} sslServerCertType;
+
+typedef struct sslServerCertStr {
+ PRCList link; /* The linked list link */
+
+ sslServerCertType certType; /* The certificate slot this occupies */
+
+ /* Configuration state for server sockets */
+ CERTCertificate *serverCert;
+ CERTCertificateList *serverCertChain;
+ sslKeyPair *serverKeyPair;
+ unsigned int serverKeyBits;
+ /* Each certificate needs its own status. */
+ SECItemArray *certStatusArray;
+ /* Serialized signed certificate timestamps to be sent to the client
+ ** in a TLS extension (server only). Each certificate needs its own
+ ** timestamps item.
+ */
+ SECItem signedCertTimestamps;
+} sslServerCert;
+
+extern sslServerCert *ssl_NewServerCert(const sslServerCertType *slot);
+extern sslServerCert *ssl_CopyServerCert(const sslServerCert *oc);
+extern sslServerCert *ssl_FindServerCert(const sslSocket *ss,
+ const sslServerCertType *slot);
+extern sslServerCert *ssl_FindServerCertByAuthType(const sslSocket *ss,
+ SSLAuthType authType);
+extern void ssl_FreeServerCert(sslServerCert *sc);
+
+#endif /* __sslcert_h_ */
diff --git a/nss/lib/ssl/sslcon.c b/nss/lib/ssl/sslcon.c
index ccd0026..4481706 100644
--- a/nss/lib/ssl/sslcon.c
+++ b/nss/lib/ssl/sslcon.c
@@ -1,5 +1,5 @@
-/*
- * SSL v2 handshake functions, and functions common to SSL2 and SSL3.
+/*
+ * Basic SSL handshake 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
@@ -9,8 +9,8 @@
#include "cert.h"
#include "secitem.h"
#include "sechash.h"
-#include "cryptohi.h" /* for SGN_ funcs */
-#include "keyhi.h" /* for SECKEY_ high level functions. */
+#include "cryptohi.h" /* for SGN_ funcs */
+#include "keyhi.h" /* for SECKEY_ high level functions. */
#include "ssl.h"
#include "sslimpl.h"
#include "sslproto.h"
@@ -18,2965 +18,118 @@
#include "sslerr.h"
#include "pk11func.h"
#include "prinit.h"
-#include "prtime.h" /* for PR_Now() */
-
-static PRBool policyWasSet;
-
-#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 */
+#include "prtime.h" /* for PR_Now() */
/*
** 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"
+ " +us"
+ " +export"
#ifdef TRACE
- " +trace"
+ " +trace"
#endif
#ifdef DEBUG
- " +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);
- if (SECITEM_CopyItem(0, &sec->sendSecret, writeKey) ||
- SECITEM_CopyItem(0, &sec->rcvSecret, readKey)) {
- return SECFailure;
- }
- 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) {
- if (sid->cached == never_cached) {
- (*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;
- unsigned 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;
- unsigned 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. */
- unsigned 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.
+ * Gathers in and handles records/messages until either the handshake is
+ * complete or application data is available.
*
* 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 SECWouldBlock when that value is returned by
+ * ssl3_GatherCompleteHandshake().
* returns SECFailure on all other errors.
*
- * The gather functions called by ssl_GatherRecord1stHandshake are expected
- * to return values interpreted as follows:
+ * 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.
+ * -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().
+ * 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
+ * ssl_BeginClientHandshake
+ * ssl3_RestartHandshakeAfterCertReq
+ * ssl3_RestartHandshakeAfterServerCert
+ * ssl_BeginServerHandshake
*/
SECStatus
ssl_GatherRecord1stHandshake(sslSocket *ss)
{
int rv;
- PORT_Assert( ss->opt.noLocks || ssl_Have1stHandshakeLock(ss) );
+ 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);
- }
+ /* Wait for handshake to complete, or application data to arrive. */
+ rv = ssl3_GatherCompleteHandshake(ss, 0);
SSL_TRC(10, ("%d: SSL[%d]: handshake gathering, rv=%d",
- SSL_GETPID(), ss->fd, rv));
+ 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 < 0) {
- /* XXX If the key is bad, then PK11_PubDecryptRaw will fail below. */
- modulusLen = ekLen;
- }
- if (ekLen > (unsigned int)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 && sid->cached == never_cached)
- (*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 (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 (key) {
- /* got a key, but no cert - free it */
- SECKEY_DestroyPrivateKey(key);
- key = NULL;
+ if (rv == 0) {
+ /* EOF. Loser */
+ PORT_SetError(PR_END_OF_FILE_ERROR);
}
- 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);
+ return SECFailure; /* rv is < 0 here. */
}
- 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;
-
- 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) {
- (void)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;
+ ss->handshake = NULL;
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)
+/* This function is called at the beginning of a handshake to ensure that at
+ * least one SSL/TLS version is enabled. */
+static SECStatus
+ssl_CheckConfigSanity(sslSocket *ss)
{
- sslSessionID * sid;
- PRUint8 * cert;
- PRUint8 * cs;
- PRUint8 * data;
- SECStatus rv;
- unsigned 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;
+ if (SSL_ALL_VERSIONS_DISABLED(&ss->vrange)) {
+ SSL_DBG(("%d: SSL[%d]: Can't handshake! all versions disabled.",
+ SSL_GETPID(), ss->fd));
+ PORT_SetError(SSL_ERROR_SSL_DISABLED);
+ return SECFailure;
}
-
- /* 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)
+ssl_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;
+ sslSessionID *sid;
+ SECStatus rv;
- PORT_Assert( ss->opt.noLocks || ssl_Have1stHandshakeLock(ss) );
+ PORT_Assert(ss->opt.noLocks || ssl_Have1stHandshakeLock(ss));
- ss->sec.isServer = 0;
- ss->sec.sendSequence = 0;
- ss->sec.rcvSequence = 0;
+ ss->sec.isServer = PR_FALSE;
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);
+ rv = ssl_CheckConfigSanity(ss);
if (rv != SECSuccess)
- goto loser;
+ goto loser;
/* Get peer name of server */
rv = ssl_GetPeerInfo(ss);
@@ -2990,14 +143,14 @@ ssl2_BeginClientHandshake(sslSocket *ss)
*/
if (PR_GetError() == PR_NOT_CONNECTED_ERROR) {
char dummy;
- (void) PR_Write(ss->fd->lower, &dummy, 0);
+ (void)PR_Write(ss->fd->lower, &dummy, 0);
rv = ssl_GetPeerInfo(ss);
if (rv < 0) {
goto loser;
}
}
#else
- goto loser;
+ goto loser;
#endif
}
@@ -3005,643 +158,73 @@ ssl2_BeginClientHandshake(sslSocket *ss)
/* Try to find server in our session-id cache */
if (ss->opt.noCache) {
- sid = NULL;
+ sid = NULL;
} else {
- sid = ssl_LookupSID(&ss->sec.ci.peer, ss->sec.ci.port, ss->peerID,
- ss->url);
+ sid = ssl_LookupSID(&ss->sec.ci.peer, ss->sec.ci.port, ss->peerID,
+ ss->url);
+ }
+ if (sid) {
+ if (sid->version >= ss->vrange.min && sid->version <= ss->vrange.max) {
+ PORT_Assert(!ss->sec.localCert);
+ ss->sec.localCert = CERT_DupCertificate(sid->localCert);
+ } else {
+ ss->sec.uncache(sid);
+ ssl_FreeSID(sid);
+ sid = NULL;
+ }
}
- 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);
- }
+ 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;
- }
-#ifndef NSS_DISABLE_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 /* NSS_DISABLE_ECC */
-
- 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->gs.state = GS_INIT;
+ ss->handshake = ssl_GatherRecord1stHandshake;
- ss->handshake = ssl_GatherRecord1stHandshake;
- ss->nextHandshake = ssl2_HandleServerHelloMessage;
- return SECSuccess;
+ /* ssl3_SendClientHello will override this if it succeeds. */
+ ss->version = SSL_LIBRARY_VERSION_3_0;
-unlock_loser:
+ ssl_GetSSL3HandshakeLock(ss);
+ ssl_GetXmitBufLock(ss);
+ rv = ssl3_SendClientHello(ss, client_hello_initial);
ssl_ReleaseXmitBufLock(ss);
-loser:
- return SECFailure;
-}
-
-/************************************************************************/
+ ssl_ReleaseSSL3HandshakeLock(ss);
-/* 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 */
+ return rv;
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)
+ssl_BeginServerHandshake(sslSocket *ss)
{
- SECStatus rv;
- sslServerCerts * rsaAuth = ss->serverCerts + kt_rsa;
+ SECStatus rv;
- ss->sec.isServer = 1;
+ ss->sec.isServer = PR_TRUE;
+ ss->ssl3.hs.ws = wait_client_hello;
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);
+ rv = ssl_CheckConfigSanity(ss);
if (rv != SECSuccess)
- goto loser;
+ 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;
+ ss->handshake = ssl_GatherRecord1stHandshake;
return SECSuccess;
loser:
@@ -3649,7 +232,7 @@ loser:
}
/* This function doesn't really belong in this file.
-** It's here to keep AIX compilers from optimizing it away,
+** It's here to keep AIX compilers from optimizing it away,
** and not including it in the DSO.
*/
diff --git a/nss/lib/ssl/ssldef.c b/nss/lib/ssl/ssldef.c
index cc3ecc8..77a744c 100644
--- a/nss/lib/ssl/ssldef.c
+++ b/nss/lib/ssl/ssldef.c
@@ -10,14 +10,18 @@
#include "sslimpl.h"
#if defined(WIN32)
-#define MAP_ERROR(from,to) if (err == from) { PORT_SetError(to); }
-#define DEFINE_ERROR PRErrorCode err = PR_GetError();
+#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 MAP_ERROR(from, to)
#define DEFINE_ERROR
#endif
-int ssl_DefConnect(sslSocket *ss, const PRNetAddr *sa)
+int
+ssl_DefConnect(sslSocket *ss, const PRNetAddr *sa)
{
PRFileDesc *lower = ss->fd->lower;
int rv;
@@ -26,7 +30,8 @@ int ssl_DefConnect(sslSocket *ss, const PRNetAddr *sa)
return rv;
}
-int ssl_DefBind(sslSocket *ss, const PRNetAddr *addr)
+int
+ssl_DefBind(sslSocket *ss, const PRNetAddr *addr)
{
PRFileDesc *lower = ss->fd->lower;
int rv;
@@ -35,7 +40,8 @@ int ssl_DefBind(sslSocket *ss, const PRNetAddr *addr)
return rv;
}
-int ssl_DefListen(sslSocket *ss, int backlog)
+int
+ssl_DefListen(sslSocket *ss, int backlog)
{
PRFileDesc *lower = ss->fd->lower;
int rv;
@@ -44,7 +50,8 @@ int ssl_DefListen(sslSocket *ss, int backlog)
return rv;
}
-int ssl_DefShutdown(sslSocket *ss, int how)
+int
+ssl_DefShutdown(sslSocket *ss, int how)
{
PRFileDesc *lower = ss->fd->lower;
int rv;
@@ -53,19 +60,20 @@ int ssl_DefShutdown(sslSocket *ss, int how)
return rv;
}
-int ssl_DefRecv(sslSocket *ss, unsigned char *buf, int len, int flags)
+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)
+ 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;
+ PORT_Assert(rv <= len);
+ PORT_SetError(PR_BUFFER_OVERFLOW_ERROR);
+ rv = SECFailure;
}
return rv;
}
@@ -73,87 +81,91 @@ int ssl_DefRecv(sslSocket *ss, unsigned char *buf, int len, int flags)
/* 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.
+ * 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)
+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
+ /* 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;
+ 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;
- }
+ 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)
+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)
+ 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)
+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;
+ 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)
+int
+ssl_DefGetpeername(sslSocket *ss, PRNetAddr *name)
{
PRFileDesc *lower = ss->fd->lower;
int rv;
@@ -162,7 +174,8 @@ int ssl_DefGetpeername(sslSocket *ss, PRNetAddr *name)
return rv;
}
-int ssl_DefGetsockname(sslSocket *ss, PRNetAddr *name)
+int
+ssl_DefGetsockname(sslSocket *ss, PRNetAddr *name)
{
PRFileDesc *lower = ss->fd->lower;
int rv;
@@ -171,22 +184,23 @@ int ssl_DefGetsockname(sslSocket *ss, PRNetAddr *name)
return rv;
}
-int ssl_DefClose(sslSocket *ss)
+int
+ssl_DefClose(sslSocket *ss)
{
PRFileDesc *fd;
PRFileDesc *popped;
- int rv;
+ int rv;
- fd = ss->fd;
+ fd = ss->fd;
- /* First, remove the SSL layer PRFileDesc from the socket's stack,
+ /* 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;
+ PORT_SetError(PR_BAD_DESCRIPTOR_ERROR);
+ return SECFailure;
}
ss->fd = NULL;
@@ -194,17 +208,17 @@ int ssl_DefClose(sslSocket *ss)
** 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 = 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.
+ ** 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()));
+ SSL_GETPID(), fd, rv, PORT_GetError()));
return rv;
}
diff --git a/nss/lib/ssl/sslenum.c b/nss/lib/ssl/sslenum.c
index f69aed2..b5272d4 100644
--- a/nss/lib/ssl/sslenum.c
+++ b/nss/lib/ssl/sslenum.c
@@ -22,7 +22,11 @@
* * No-encryption cipher suites last
* * Export/weak/obsolete cipher suites before no-encryption cipher suites
* * Order by key exchange algorithm: ECDHE, then DHE, then ECDH, RSA.
- * * Within key agreement sections, order by symmetric encryption algorithm:
+ * * Within key agreement sections, prefer AEAD over non-AEAD cipher suites.
+ * * Within AEAD sections, order by symmetric encryption algorithm which
+ * integrates message authentication algorithm: AES-128-GCM, then
+ * ChaCha20-Poly1305, then AES-256-GCM,
+ * * Within non-AEAD sections, order by symmetric encryption algorithm:
* AES-128, then Camellia-128, then AES-256, then Camellia-256, then SEED,
* then FIPS-3DES, then 3DES, then RC4. AES is commonly accepted as a
* strong cipher internationally, and is often hardware-accelerated.
@@ -30,16 +34,20 @@
* organizations. SEED is only recommended by the Korean government. 3DES
* only provides 112 bits of security. RC4 is now deprecated or forbidden
* by many standards organizations.
+ * * Within non-AEAD symmetric algorithm sections, order by message
+ * authentication algorithm: HMAC-SHA256, then HMAC-SHA384, then HMAC-SHA1,
+ * then HMAC-MD5.
* * Within symmetric algorithm sections, order by message authentication
* algorithm: GCM, then HMAC-SHA1, then HMAC-SHA256, then HMAC-MD5.
* * Within message authentication algorithm sections, order by asymmetric
* signature algorithm: ECDSA, then RSA, then DSS.
+ * * As a special case, the PSK ciphers, which are only enabled when
+ * TLS 1.3 PSK-resumption is in use, come first.
*
* Exception: Because some servers ignore the high-order byte of the cipher
* suite ID, we must be careful about adding cipher suites with IDs larger
- * than 0x00ff; see bug 946147. For these broken servers, the first four cipher
- * suites, with the MSB zeroed, look like:
- * TLS_KRB5_EXPORT_WITH_RC4_40_MD5 { 0x00,0x2B }
+ * than 0x00ff; see bug 946147. For these broken servers, the first three
+ * cipher suites, with the MSB zeroed, look like:
* TLS_RSA_WITH_AES_128_CBC_SHA { 0x00,0x2F }
* TLS_RSA_WITH_3DES_EDE_CBC_SHA { 0x00,0x0A }
* TLS_RSA_WITH_DES_CBC_SHA { 0x00,0x09 }
@@ -47,9 +55,16 @@
* the third one.
*/
const PRUint16 SSL_ImplementedCiphers[] = {
-#ifndef NSS_DISABLE_ECC
+ TLS_AES_128_GCM_SHA256,
+ TLS_CHACHA20_POLY1305_SHA256,
+ TLS_AES_256_GCM_SHA384,
+
TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,
TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
+ TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256,
+ TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256,
+ TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,
+ TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,
/* TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA must appear before
* TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA to work around bug 946147.
*/
@@ -59,14 +74,18 @@ const PRUint16 SSL_ImplementedCiphers[] = {
TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256,
TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256,
TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA,
+ TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384,
+ TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384,
TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA,
TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA,
TLS_ECDHE_ECDSA_WITH_RC4_128_SHA,
TLS_ECDHE_RSA_WITH_RC4_128_SHA,
-#endif /* NSS_DISABLE_ECC */
TLS_DHE_RSA_WITH_AES_128_GCM_SHA256,
+ TLS_DHE_RSA_WITH_CHACHA20_POLY1305_SHA256,
TLS_DHE_DSS_WITH_AES_128_GCM_SHA256,
+ TLS_DHE_RSA_WITH_AES_256_GCM_SHA384,
+ TLS_DHE_DSS_WITH_AES_256_GCM_SHA384,
TLS_DHE_RSA_WITH_AES_128_CBC_SHA,
TLS_DHE_DSS_WITH_AES_128_CBC_SHA,
TLS_DHE_RSA_WITH_AES_128_CBC_SHA256,
@@ -83,7 +102,6 @@ const PRUint16 SSL_ImplementedCiphers[] = {
TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA,
TLS_DHE_DSS_WITH_RC4_128_SHA,
-#ifndef NSS_DISABLE_ECC
TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA,
TLS_ECDH_RSA_WITH_AES_128_CBC_SHA,
TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA,
@@ -92,9 +110,9 @@ const PRUint16 SSL_ImplementedCiphers[] = {
TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA,
TLS_ECDH_ECDSA_WITH_RC4_128_SHA,
TLS_ECDH_RSA_WITH_RC4_128_SHA,
-#endif /* NSS_DISABLE_ECC */
TLS_RSA_WITH_AES_128_GCM_SHA256,
+ TLS_RSA_WITH_AES_256_GCM_SHA384,
TLS_RSA_WITH_AES_128_CBC_SHA,
TLS_RSA_WITH_AES_128_CBC_SHA256,
TLS_RSA_WITH_CAMELLIA_128_CBC_SHA,
@@ -102,7 +120,6 @@ const PRUint16 SSL_ImplementedCiphers[] = {
TLS_RSA_WITH_AES_256_CBC_SHA256,
TLS_RSA_WITH_CAMELLIA_256_CBC_SHA,
TLS_RSA_WITH_SEED_CBC_SHA,
- SSL_RSA_FIPS_WITH_3DES_EDE_CBC_SHA,
TLS_RSA_WITH_3DES_EDE_CBC_SHA,
TLS_RSA_WITH_RC4_128_SHA,
TLS_RSA_WITH_RC4_128_MD5,
@@ -110,44 +127,24 @@ const PRUint16 SSL_ImplementedCiphers[] = {
/* 56-bit DES "domestic" cipher suites */
TLS_DHE_RSA_WITH_DES_CBC_SHA,
TLS_DHE_DSS_WITH_DES_CBC_SHA,
- SSL_RSA_FIPS_WITH_DES_CBC_SHA,
TLS_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 */
- TLS_RSA_EXPORT_WITH_RC4_40_MD5,
- TLS_RSA_EXPORT_WITH_RC2_CBC_40_MD5,
-
/* ciphersuites with no encryption */
-#ifndef NSS_DISABLE_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_DISABLE_ECC */
TLS_RSA_WITH_NULL_SHA,
TLS_RSA_WITH_NULL_SHA256,
TLS_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 =
+const PRUint16 SSL_NumImplementedCiphers =
(sizeof SSL_ImplementedCiphers) / (sizeof SSL_ImplementedCiphers[0]) - 1;
-const PRUint16 *
+const PRUint16*
SSL_GetImplementedCiphers(void)
{
return SSL_ImplementedCiphers;
diff --git a/nss/lib/ssl/sslerr.c b/nss/lib/ssl/sslerr.c
index f827221..edb9412 100644
--- a/nss/lib/ssl/sslerr.c
+++ b/nss/lib/ssl/sslerr.c
@@ -1,5 +1,5 @@
/*
- * Function to set error code only when meaningful error has not already
+ * 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
@@ -12,30 +12,30 @@
#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 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();
+ 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;
+ 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;
+ default: /* leave the majority of error codes alone. */
+ return oldErr;
}
}
diff --git a/nss/lib/ssl/sslerr.h b/nss/lib/ssl/sslerr.h
index 192a107..751c335 100644
--- a/nss/lib/ssl/sslerr.h
+++ b/nss/lib/ssl/sslerr.h
@@ -7,6 +7,7 @@
#ifndef __SSL_ERR_H_
#define __SSL_ERR_H_
+/* clang-format off */
#define SSL_ERROR_BASE (-0x3000)
#define SSL_ERROR_LIMIT (SSL_ERROR_BASE + 1000)
@@ -16,200 +17,237 @@
#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_UNSUPPORTED_HASH_ALGORITHM = (SSL_ERROR_BASE + 126),
-SSL_ERROR_DIGEST_FAILURE = (SSL_ERROR_BASE + 127),
-SSL_ERROR_INCORRECT_SIGNATURE_ALGORITHM = (SSL_ERROR_BASE + 128),
-
-SSL_ERROR_NEXT_PROTOCOL_NO_CALLBACK = (SSL_ERROR_BASE + 129),
-SSL_ERROR_NEXT_PROTOCOL_NO_PROTOCOL = (SSL_ERROR_BASE + 130),
-
-SSL_ERROR_INAPPROPRIATE_FALLBACK_ALERT = (SSL_ERROR_BASE + 131),
-
-SSL_ERROR_WEAK_SERVER_CERT_KEY = (SSL_ERROR_BASE + 132),
-
-SSL_ERROR_RX_SHORT_DTLS_READ = (SSL_ERROR_BASE + 133),
-
-SSL_ERROR_NO_SUPPORTED_SIGNATURE_ALGORITHM = (SSL_ERROR_BASE + 134),
-SSL_ERROR_UNSUPPORTED_SIGNATURE_ALGORITHM = (SSL_ERROR_BASE + 135),
-
-SSL_ERROR_MISSING_EXTENDED_MASTER_SECRET = (SSL_ERROR_BASE + 136),
-SSL_ERROR_UNEXPECTED_EXTENDED_MASTER_SECRET = (SSL_ERROR_BASE + 137),
-
-SSL_ERROR_END_OF_LIST /* let the c compiler determine the value of this. */
+ SSL_ERROR_EXPORT_ONLY_SERVER = (SSL_ERROR_BASE + 0),
+ /* error 0 is obsolete */
+ SSL_ERROR_US_ONLY_SERVER = (SSL_ERROR_BASE + 1),
+ /* error 1 is obsolete */
+ 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),
+ /* error 4 is obsolete */
+ 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),
+ /* error 8 is obsolete */
+ 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),
+ /* error 11 is obsolete */
+ SSL_ERROR_BAD_CERT_DOMAIN = (SSL_ERROR_BASE + 12),
+ SSL_ERROR_POST_WARNING = (SSL_ERROR_BASE + 13),
+ /* error 13 is obsolete */
+ SSL_ERROR_SSL2_DISABLED = (SSL_ERROR_BASE + 14),
+ /* error 14 is obsolete */
+ 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),
+ /* error 21 is obsolete */
+ 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),
+ /* error 71 is obsolete */
+ 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),
+ /* error 78 is obsolete */
+ 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 = (SSL_ERROR_BASE + 89),
+ /* error 89 is obsolete */
+ 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),
+ /* error 117 is obsolete */
+ 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_UNSUPPORTED_HASH_ALGORITHM = (SSL_ERROR_BASE + 126),
+ SSL_ERROR_DIGEST_FAILURE = (SSL_ERROR_BASE + 127),
+ SSL_ERROR_INCORRECT_SIGNATURE_ALGORITHM = (SSL_ERROR_BASE + 128),
+
+ SSL_ERROR_NEXT_PROTOCOL_NO_CALLBACK = (SSL_ERROR_BASE + 129),
+ SSL_ERROR_NEXT_PROTOCOL_NO_PROTOCOL = (SSL_ERROR_BASE + 130),
+
+ SSL_ERROR_INAPPROPRIATE_FALLBACK_ALERT = (SSL_ERROR_BASE + 131),
+
+ SSL_ERROR_WEAK_SERVER_CERT_KEY = (SSL_ERROR_BASE + 132),
+
+ SSL_ERROR_RX_SHORT_DTLS_READ = (SSL_ERROR_BASE + 133),
+
+ SSL_ERROR_NO_SUPPORTED_SIGNATURE_ALGORITHM = (SSL_ERROR_BASE + 134),
+ SSL_ERROR_UNSUPPORTED_SIGNATURE_ALGORITHM = (SSL_ERROR_BASE + 135),
+
+ SSL_ERROR_MISSING_EXTENDED_MASTER_SECRET = (SSL_ERROR_BASE + 136),
+ SSL_ERROR_UNEXPECTED_EXTENDED_MASTER_SECRET = (SSL_ERROR_BASE + 137),
+
+ SSL_ERROR_RX_MALFORMED_KEY_SHARE = (SSL_ERROR_BASE + 138),
+ SSL_ERROR_MISSING_KEY_SHARE = (SSL_ERROR_BASE + 139),
+ SSL_ERROR_RX_MALFORMED_ECDHE_KEY_SHARE = (SSL_ERROR_BASE + 140),
+ SSL_ERROR_RX_MALFORMED_DHE_KEY_SHARE = (SSL_ERROR_BASE + 141),
+
+ SSL_ERROR_RX_UNEXPECTED_ENCRYPTED_EXTENSIONS = (SSL_ERROR_BASE + 142),
+ SSL_ERROR_MISSING_EXTENSION_ALERT = (SSL_ERROR_BASE + 143),
+
+ SSL_ERROR_KEY_EXCHANGE_FAILURE = (SSL_ERROR_BASE + 144),
+ SSL_ERROR_EXTENSION_DISALLOWED_FOR_VERSION = (SSL_ERROR_BASE + 145),
+ SSL_ERROR_RX_MALFORMED_ENCRYPTED_EXTENSIONS = (SSL_ERROR_BASE + 146),
+ SSL_ERROR_MALFORMED_PRE_SHARED_KEY = (SSL_ERROR_BASE + 147),
+ SSL_ERROR_MALFORMED_EARLY_DATA = (SSL_ERROR_BASE + 148),
+ SSL_ERROR_END_OF_EARLY_DATA_ALERT = (SSL_ERROR_BASE + 149),
+ SSL_ERROR_MISSING_ALPN_EXTENSION = (SSL_ERROR_BASE + 150),
+ SSL_ERROR_RX_UNEXPECTED_EXTENSION = (SSL_ERROR_BASE + 151),
+ SSL_ERROR_MISSING_SUPPORTED_GROUPS_EXTENSION = (SSL_ERROR_BASE + 152),
+ SSL_ERROR_TOO_MANY_RECORDS = (SSL_ERROR_BASE + 153),
+ SSL_ERROR_RX_UNEXPECTED_HELLO_RETRY_REQUEST = (SSL_ERROR_BASE + 154),
+ SSL_ERROR_RX_MALFORMED_HELLO_RETRY_REQUEST = (SSL_ERROR_BASE + 155),
+ SSL_ERROR_BAD_2ND_CLIENT_HELLO = (SSL_ERROR_BASE + 156),
+ SSL_ERROR_MISSING_SIGNATURE_ALGORITHMS_EXTENSION = (SSL_ERROR_BASE + 157),
+ SSL_ERROR_MALFORMED_PSK_KEY_EXCHANGE_MODES = (SSL_ERROR_BASE + 158),
+ SSL_ERROR_MISSING_PSK_KEY_EXCHANGE_MODES = (SSL_ERROR_BASE + 159),
+ SSL_ERROR_END_OF_LIST /* let the c compiler determine the value of this. */
} SSLErrorCodes;
#endif /* NO_SECURITY_ERROR_ENUM */
+/* clang-format on */
+
#endif /* __SSL_ERR_H_ */
diff --git a/nss/lib/ssl/sslerrstrs.c b/nss/lib/ssl/sslerrstrs.c
index 34f4ea9..4e3db6d 100644
--- a/nss/lib/ssl/sslerrstrs.c
+++ b/nss/lib/ssl/sslerrstrs.c
@@ -7,20 +7,21 @@
#include "nssutil.h"
#include "ssl.h"
-#define ER3(name, value, str) {#name, str},
+#define ER3(name, value, str) { #name, str },
static const struct PRErrorMessage ssltext[] = {
#include "SSLerrs.h"
- {0,0}
+ { 0, 0 }
};
static const struct PRErrorTable ssl_et = {
ssltext, "sslerr", SSL_ERROR_BASE,
- (sizeof ssltext)/(sizeof ssltext[0])
+ (sizeof ssltext) / (sizeof ssltext[0])
};
static PRStatus
-ssl_InitializePRErrorTableOnce(void) {
+ssl_InitializePRErrorTableOnce(void)
+{
return PR_ErrorInstallTable(&ssl_et);
}
@@ -30,5 +31,6 @@ SECStatus
ssl_InitializePRErrorTable(void)
{
return (PR_SUCCESS == PR_CallOnce(&once, ssl_InitializePRErrorTableOnce))
- ? SECSuccess : SECFailure;
+ ? SECSuccess
+ : SECFailure;
}
diff --git a/nss/lib/ssl/sslgathr.c b/nss/lib/ssl/sslgathr.c
deleted file mode 100644
index bdf470b..0000000
--- a/nss/lib/ssl/sslgathr.c
+++ /dev/null
@@ -1,425 +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/. */
-#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);
-}
-
-/* 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/nss/lib/ssl/sslgrp.c b/nss/lib/ssl/sslgrp.c
new file mode 100644
index 0000000..eb53ad3
--- /dev/null
+++ b/nss/lib/ssl/sslgrp.c
@@ -0,0 +1,164 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * 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/. */
+
+#include "nss.h"
+#include "pk11func.h"
+#include "ssl.h"
+#include "sslimpl.h"
+
+struct {
+ sslEphemeralKeyPair *keyPair;
+ PRCallOnceType once;
+} gECDHEKeyPairs[SSL_NAMED_GROUP_COUNT];
+
+typedef struct sslSocketAndGroupArgStr {
+ const sslNamedGroupDef *group;
+ const sslSocket *ss;
+} sslSocketAndGroupArg;
+
+/* Function to clear out the ECDHE keys. */
+static SECStatus
+ssl_CleanupECDHEKeys(void *appData, void *nssData)
+{
+ unsigned int i;
+
+ for (i = 0; i < SSL_NAMED_GROUP_COUNT; i++) {
+ if (gECDHEKeyPairs[i].keyPair) {
+ ssl_FreeEphemeralKeyPair(gECDHEKeyPairs[i].keyPair);
+ }
+ }
+ memset(gECDHEKeyPairs, 0, sizeof(gECDHEKeyPairs));
+ return SECSuccess;
+}
+
+/* Only run the cleanup once. */
+static PRCallOnceType cleanupECDHEKeysOnce;
+static PRStatus
+ssl_SetupCleanupECDHEKeysOnce(void)
+{
+ SECStatus rv = NSS_RegisterShutdown(ssl_CleanupECDHEKeys, NULL);
+ return (rv != SECSuccess) ? PR_FAILURE : PR_SUCCESS;
+}
+
+/* This creates a key pair for each of the supported EC groups. If that works,
+ * we assume that the token supports that group. Since this is relatively
+ * expensive, this is only done for the first socket that is used. That means
+ * that if tokens are added or removed, then this will not pick up any changes.
+ */
+static PRStatus
+ssl_CreateStaticECDHEKeyPair(void *arg)
+{
+ const sslSocketAndGroupArg *typed_arg = (sslSocketAndGroupArg *)arg;
+ const sslNamedGroupDef *group = typed_arg->group;
+ const sslSocket *ss = typed_arg->ss;
+ unsigned int i = group - ssl_named_groups;
+ SECStatus rv;
+
+ PORT_Assert(group->keaType == ssl_kea_ecdh);
+ PORT_Assert(i < SSL_NAMED_GROUP_COUNT);
+ rv = ssl_CreateECDHEphemeralKeyPair(ss, group,
+ &gECDHEKeyPairs[i].keyPair);
+ if (rv != SECSuccess) {
+ gECDHEKeyPairs[i].keyPair = NULL;
+ SSL_TRC(5, ("%d: SSL[-]: disabling group %d",
+ SSL_GETPID(), group->name));
+ }
+
+ return PR_SUCCESS;
+}
+
+void
+ssl_FilterSupportedGroups(sslSocket *ss)
+{
+ unsigned int i;
+ PRStatus prv;
+ sslSocketAndGroupArg arg = { NULL, ss };
+
+ prv = PR_CallOnce(&cleanupECDHEKeysOnce, ssl_SetupCleanupECDHEKeysOnce);
+ PORT_Assert(prv == PR_SUCCESS);
+ if (prv != PR_SUCCESS) {
+ return;
+ }
+
+ for (i = 0; i < SSL_NAMED_GROUP_COUNT; ++i) {
+ PRUint32 policy;
+ SECStatus srv;
+ unsigned int index;
+ const sslNamedGroupDef *group = ss->namedGroupPreferences[i];
+ if (!group) {
+ continue;
+ }
+
+ srv = NSS_GetAlgorithmPolicy(group->oidTag, &policy);
+ if (srv == SECSuccess && !(policy & NSS_USE_ALG_IN_SSL_KX)) {
+ ss->namedGroupPreferences[i] = NULL;
+ continue;
+ }
+
+ if (group->assumeSupported) {
+ continue;
+ }
+
+ /* For EC groups, we have to test that a key pair can be created. This
+ * is gross, and expensive, so only do it once. */
+ index = group - ssl_named_groups;
+ PORT_Assert(index < SSL_NAMED_GROUP_COUNT);
+
+ arg.group = group;
+ prv = PR_CallOnceWithArg(&gECDHEKeyPairs[index].once,
+ ssl_CreateStaticECDHEKeyPair,
+ (void *)&arg);
+ PORT_Assert(prv == PR_SUCCESS);
+ if (prv != PR_SUCCESS) {
+ continue;
+ }
+
+ if (!gECDHEKeyPairs[index].keyPair) {
+ ss->namedGroupPreferences[i] = NULL;
+ }
+ }
+}
+
+/*
+ * Creates the static "ephemeral" public and private ECDH keys used by server in
+ * ECDHE_RSA and ECDHE_ECDSA handshakes when we reuse the same key.
+ */
+SECStatus
+ssl_CreateStaticECDHEKey(sslSocket *ss, const sslNamedGroupDef *ecGroup)
+{
+ sslEphemeralKeyPair *keyPair;
+ /* We index gECDHEKeyPairs by the named group. Pointer arithmetic! */
+ unsigned int index = ecGroup - ssl_named_groups;
+ PRStatus prv;
+ sslSocketAndGroupArg arg = { ecGroup, ss };
+
+ prv = PR_CallOnceWithArg(&gECDHEKeyPairs[index].once,
+ ssl_CreateStaticECDHEKeyPair,
+ (void *)&arg);
+ PORT_Assert(prv == PR_SUCCESS);
+ if (prv != PR_SUCCESS) {
+ PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
+ return SECFailure;
+ }
+
+ keyPair = gECDHEKeyPairs[index].keyPair;
+ if (!keyPair) {
+ /* Attempting to use a key pair for an unsupported group. */
+ PORT_Assert(keyPair);
+ PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
+ return SECFailure;
+ }
+
+ keyPair = ssl_CopyEphemeralKeyPair(keyPair);
+ if (!keyPair)
+ return SECFailure;
+
+ PORT_Assert(PR_CLIST_IS_EMPTY(&ss->ephemeralKeyPairs));
+ PR_APPEND_LINK(&keyPair->link, &ss->ephemeralKeyPairs);
+ return SECSuccess;
+}
diff --git a/nss/lib/ssl/sslimpl.h b/nss/lib/ssl/sslimpl.h
index ad31aae..09c3783 100644
--- a/nss/lib/ssl/sslimpl.h
+++ b/nss/lib/ssl/sslimpl.h
@@ -29,46 +29,41 @@
#include "nssrwlk.h"
#include "prthread.h"
#include "prclist.h"
+#include "private/pprthred.h"
#include "sslt.h" /* for some formerly private types, now public */
+typedef struct sslSocketStr sslSocket;
+
+#include "ssl3ext.h"
+
/* 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 calg_aes_gcm ssl_calg_aes_gcm
-
-#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 hmac_sha256 ssl_hmac_sha256
-#define mac_aead ssl_mac_aead
-
-#define SET_ERROR_CODE /* reminder */
-#define SEND_ALERT /* reminder */
-#define TEST_FOR_FAILURE /* reminder */
-#define DEAL_WITH_FAILURE /* reminder */
+
+#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 calg_aes_gcm ssl_calg_aes_gcm
+#define calg_chacha20 ssl_calg_chacha20
+
+#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 hmac_sha256 ssl_hmac_sha256
+#define hmac_sha384 ssl_hmac_sha384
+#define mac_aead ssl_mac_aead
#if defined(DEBUG) || defined(TRACE)
#ifdef __cplusplus
@@ -85,192 +80,162 @@ extern int Debug;
#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
+#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 PRINT_KEY(a, b) \
+ if (ssl_trace >= (a)) \
+ ssl_PrintKey b
#else
-#define SSL_TRC(a,b)
-#define PRINT_BUF(a,b)
-#define DUMP_MSG(a,b)
+#define SSL_TRC(a, b)
+#define PRINT_BUF(a, b)
+#define PRINT_KEY(a, b)
#endif
#ifdef DEBUG
-#define SSL_DBG(b) if (ssl_debug) ssl_Trace b
+#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))
-#define LSB(x) ((unsigned char) ((x) & 0xff))
-#define MSB(x) ((unsigned char) (((unsigned)(x)) >> 8))
+#define CONST_CAST(T, X) ((T *)(X))
/************************************************************************/
typedef enum { SSLAppOpRead = 0,
- SSLAppOpWrite,
- SSLAppOpRDWR,
- SSLAppOpPost,
- SSLAppOpHeader
+ 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 SSL3_SESSIONID_BYTES 32
-#define SSL_CONNECTIONID_BYTES 16
+#define SSL_MIN_CHALLENGE_BYTES 16
+#define SSL_MAX_CHALLENGE_BYTES 32
-#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
+#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. */
-#define SSL3_ALL_SUPPORTED_CURVES_MASK 0x3fffffe
-/* Mask of only 3 curves, suite B */
-#define SSL3_SUITE_B_SUPPORTED_CURVES_MASK 0x3800000
+#define SSL_MAX_CACHED_CERT_LEN 4060
#ifndef BPB
#define BPB 8 /* Bits Per Byte */
#endif
-#define EXPORT_RSA_KEY_LENGTH 64 /* bytes */
+/* The default value from RFC 4347 is 1s, which is too slow. */
+#define DTLS_RETRANSMIT_INITIAL_MS 50
+/* The maximum time to wait between retransmissions. */
+#define DTLS_RETRANSMIT_MAX_MS 10000
+/* Time to wait in FINISHED state for retransmissions. */
+#define DTLS_RETRANSMIT_FINISHED_MS 30000
-#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 */
+/* default number of entries in namedGroupPreferences */
+#define SSL_NAMED_GROUP_COUNT 31
-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;
+/* Types and names of elliptic curves used in TLS */
+typedef enum {
+ ec_type_explicitPrime = 1, /* not supported */
+ ec_type_explicitChar2Curve = 2, /* not supported */
+ ec_type_named = 3
+} ECType;
-typedef struct ssl3StateStr ssl3State;
-typedef struct ssl3CertNodeStr ssl3CertNode;
-typedef struct ssl3BulkCipherDefStr ssl3BulkCipherDef;
-typedef struct ssl3MACDefStr ssl3MACDef;
-typedef struct ssl3KeyPairStr ssl3KeyPair;
-typedef struct ssl3DHParamsStr ssl3DHParams;
+typedef enum {
+ ticket_allow_early_data = 1,
+ ticket_allow_psk_ke = 2,
+ ticket_allow_psk_dhe_ke = 4,
+ ticket_allow_psk_auth = 8,
+ ticket_allow_psk_sign_auth = 16
+} TLS13SessionTicketFlags;
+
+typedef struct {
+ /* The name is the value that is encoded on the wire in TLS. */
+ SSLNamedGroup name;
+ /* The number of bits in the group. */
+ unsigned int bits;
+ /* The key exchange algorithm this group provides. */
+ SSLKEAType keaType;
+ /* The OID that identifies the group to PKCS11. This also determines
+ * whether the group is enabled in policy. */
+ SECOidTag oidTag;
+ /* Assume that the group is always supported. */
+ PRBool assumeSupported;
+} sslNamedGroupDef;
+
+typedef struct sslBufferStr sslBuffer;
+typedef struct sslConnectInfoStr sslConnectInfo;
+typedef struct sslGatherStr sslGather;
+typedef struct sslSecurityInfoStr sslSecurityInfo;
+typedef struct sslSessionIDStr sslSessionID;
+typedef struct sslSocketOpsStr sslSocketOps;
+
+typedef struct ssl3StateStr ssl3State;
+typedef struct ssl3CertNodeStr ssl3CertNode;
+typedef struct ssl3BulkCipherDefStr ssl3BulkCipherDef;
+typedef struct ssl3MACDefStr ssl3MACDef;
+typedef struct sslKeyPairStr sslKeyPair;
+typedef struct ssl3DHParamsStr ssl3DHParams;
struct ssl3CertNodeStr {
struct ssl3CertNodeStr *next;
- CERTCertificate * cert;
+ 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);
-
-extern unsigned int
-ssl3_CalculatePaddingExtensionLength(unsigned int clientHelloLength);
-
-extern PRInt32
-ssl3_AppendPaddingExtension(sslSocket *ss, unsigned int extensionLen,
- PRUint32 maxBytes);
+typedef void (*sslSessionIDCacheFunc)(sslSessionID *sid);
+typedef void (*sslSessionIDUncacheFunc)(sslSessionID *sid);
+typedef sslSessionID *(*sslSessionIDLookupFunc)(const PRIPv6Addr *addr,
+ unsigned char *sid,
+ unsigned int sidLen,
+ CERTCertDBHandle *dbHandle);
/* 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 (*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);
+ 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 (*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 *);
+ 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_FORCE_INTO_BUFFER 0x40000000
+#define ssl_SEND_FLAG_NO_BUFFER 0x20000000
+#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
+ 0x04000000 /* TLS only */
+#define ssl_SEND_FLAG_MASK 0x7f000000
/*
** A buffer object.
*/
struct sslBufferStr {
- unsigned char * buf;
- unsigned int len;
- unsigned int space;
+ unsigned char *buf;
+ unsigned int len;
+ unsigned int space;
};
/*
@@ -278,96 +243,76 @@ struct sslBufferStr {
*/
typedef struct {
#if !defined(_WIN32)
- unsigned int cipher_suite : 16;
- unsigned int policy : 8;
- unsigned int enabled : 1;
- unsigned int isPresent : 1;
+ 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;
+ PRUint8 policy;
+ unsigned char enabled : 1;
+ unsigned char isPresent : 1;
#endif
} ssl3CipherSuiteCfg;
-#ifndef NSS_DISABLE_ECC
-#define ssl_V3_SUITES_IMPLEMENTED 64
-#else
-#define ssl_V3_SUITES_IMPLEMENTED 40
-#endif /* NSS_DISABLE_ECC */
+#define ssl_V3_SUITES_IMPLEMENTED 71
#define MAX_DTLS_SRTP_CIPHER_SUITES 4
-/* MAX_SIGNATURE_ALGORITHMS allows for a large number of combinations of
- * SSLSignType and SSLHashType, but not all combinations (specifically, this
- * doesn't allow space for combinations with MD5). */
-#define MAX_SIGNATURE_ALGORITHMS 15
-
+/* MAX_SIGNATURE_SCHEMES allows for all the values we support. */
+#define MAX_SIGNATURE_SCHEMES 15
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 */
- unsigned int enableNPN : 1; /* 26 */
- unsigned int enableALPN : 1; /* 27 */
- unsigned int reuseServerECDHEKey : 1; /* 28 */
- unsigned int enableFallbackSCSV : 1; /* 29 */
- unsigned int enableServerDhe : 1; /* 30 */
- unsigned int enableExtendedMS : 1; /* 31 */
+ unsigned int useSecurity : 1;
+ unsigned int useSocks : 1;
+ unsigned int requestCertificate : 1;
+ unsigned int requireCertificate : 2;
+ unsigned int handshakeAsClient : 1;
+ unsigned int handshakeAsServer : 1;
+ unsigned int noCache : 1;
+ unsigned int fdx : 1;
+ unsigned int detectRollBack : 1;
+ unsigned int noLocks : 1;
+ unsigned int enableSessionTickets : 1;
+ unsigned int enableDeflate : 1;
+ unsigned int enableRenegotiation : 2;
+ unsigned int requireSafeNegotiation : 1;
+ unsigned int enableFalseStart : 1;
+ unsigned int cbcRandomIV : 1;
+ unsigned int enableOCSPStapling : 1;
+ unsigned int enableNPN : 1;
+ unsigned int enableALPN : 1;
+ unsigned int reuseServerECDHEKey : 1;
+ unsigned int enableFallbackSCSV : 1;
+ unsigned int enableServerDhe : 1;
+ unsigned int enableExtendedMS : 1;
+ unsigned int enableSignedCertTimestamps : 1;
+ unsigned int requireDHENamedGroups : 1;
+ unsigned int enable0RttData : 1;
+ unsigned int enableShortHeaders : 1;
} sslOptions;
typedef enum { sslHandshakingUndetermined = 0,
- sslHandshakingAsClient,
- sslHandshakingAsServer
+ 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_SPEC 255
-#define SSL_LOCK_RANK_GLOBAL NSS_RWLOCK_RANK_NONE
-
-/* These are the valid values for shutdownHow.
+/* 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
+** 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 */
+#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
@@ -375,85 +320,59 @@ typedef struct sslServerCertsStr {
** Everything in here is protected by the recvBufLock.
*/
struct sslGatherStr {
- int state; /* see GS_ values below. */ /* ssl 2 & 3 */
+ int state; /* see GS_ values below. */
/* "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.
+ * recv'd ciphertext records are put in inbuf (see below), then decrypted
+ * into buf.
*/
- sslBuffer buf; /*recvBufLock*/ /* ssl 2 & 3 */
+ sslBuffer buf; /*recvBufLock*/
- /* number of bytes previously read into hdr or buf(ssl2) or inbuf (ssl3).
- ** (offset - writeOffset) is the number of ciphertext bytes read in but
+ /* number of bytes previously read into hdr or inbuf.
+ ** (offset - writeOffset) is the number of ciphertext bytes read in but
** not yet deciphered.
*/
- unsigned int offset; /* ssl 2 & 3 */
+ unsigned int offset;
/* 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 */
+ unsigned int remainder;
- /* 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
+ /* DoRecv uses the next two values 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
+ ** In the current implementation, this is made available before the
** MAC is checked!!
*/
- unsigned int readOffset; /* Spot where DATA reader (e.g. application
+ 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;
+ unsigned int writeOffset;
/* Buffer for ssl3 to read (encrypted) data from the socket */
- sslBuffer inbuf; /*recvBufLock*/ /* ssl3 only */
+ sslBuffer inbuf; /*recvBufLock*/
/* 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
+ ** 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.
+ ** For SSL3/TLS, the plaintext portion is 5 bytes long. For DTLS it is 13.
*/
- unsigned char hdr[13]; /* ssl 2 & 3 or dtls */
+ unsigned char hdr[13];
/* Buffer for DTLS data read off the wire as a single datagram */
- sslBuffer dtlsPacket;
+ sslBuffer dtlsPacket;
/* the start of the buffered DTLS record in dtlsPacket */
- unsigned int dtlsPacketOffset;
+ 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
-
-
+#define GS_INIT 0
+#define GS_HEADER 1
+#define GS_DATA 2
/*
** ssl3State and CipherSpec structs
@@ -462,104 +381,87 @@ struct sslGatherStr {
/* 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_rc4,
+ cipher_des,
+ cipher_3des,
cipher_aes_128,
cipher_aes_256,
cipher_camellia_128,
cipher_camellia_256,
cipher_seed,
cipher_aes_128_gcm,
- cipher_missing /* reserved for no such supported cipher */
+ cipher_aes_256_gcm,
+ cipher_chacha20,
+ cipher_missing /* reserved for no such supported cipher */
/* This enum must match ssl3_cipherName[] in ssl3con.c. */
} SSL3BulkCipher;
-typedef enum { type_stream, type_block, type_aead } CipherType;
+typedef enum { type_stream,
+ type_block,
+ type_aead } 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 PRUint64 sslSequenceNumber;
typedef PRUint16 DTLSEpoch;
typedef void (*DTLSTimerCb)(sslSocket *);
-#define MAX_MAC_CONTEXT_BYTES 400 /* 400 is large enough for MD5, SHA-1, and
- * SHA-256. For SHA-384 support, increase
- * it to 712. */
-#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;
- PRUint8 extendedMasterSecretUsed;
+ SSL3Opaque wrapped_master_secret[48];
+ PRUint16 wrapped_master_secret_len;
+ PRUint8 msIsWrapped;
+ PRUint8 resumable;
+ PRUint8 extendedMasterSecretUsed;
} ssl3SidKeys; /* 52 bytes */
typedef struct {
- PK11SymKey *write_key;
- PK11SymKey *write_mac_key;
+ 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];
+ SECItem write_key_item;
+ SECItem write_iv_item;
+ SECItem write_mac_key_item;
+ SSL3Opaque write_iv[MAX_IV_LENGTH];
} ssl3KeyMaterial;
-typedef SECStatus (*SSLCipher)(void * context,
- unsigned char * out,
- int * outlen,
- int maxout,
- const unsigned char *in,
- int inlen);
+typedef SECStatus (*SSLCipher)(void *context,
+ unsigned char *out,
+ int *outlen,
+ int maxout,
+ const unsigned char *in,
+ int inlen);
typedef SECStatus (*SSLAEADCipher)(
- ssl3KeyMaterial * keys,
- PRBool doDecrypt,
- unsigned char * out,
- int * outlen,
- int maxout,
- const unsigned char *in,
- int inlen,
- const unsigned char *additionalData,
- int additionalDataLen);
-typedef SECStatus (*SSLCompressor)(void * context,
- unsigned char * out,
- int * outlen,
- int maxout,
+ ssl3KeyMaterial *keys,
+ PRBool doDecrypt,
+ unsigned char *out,
+ int *outlen,
+ int maxout,
+ const unsigned char *in,
+ int inlen,
+ const unsigned char *additionalData,
+ int additionalDataLen);
+typedef SECStatus (*SSLCompressor)(void *context,
+ unsigned char *out,
+ int *outlen,
+ int maxout,
const unsigned char *in,
- int inlen);
+ int inlen);
typedef SECStatus (*SSLDestroy)(void *context, PRBool freeit);
-/* 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.
+/* The DTLS anti-replay window in number of packets. 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
- */
+#define DTLS_RECVD_RECORDS_WINDOW 1024
+#define RECORD_SEQ_MAX ((1ULL << 48) - 1)
+PR_STATIC_ASSERT(DTLS_RECVD_RECORDS_WINDOW % 8 == 0);
+
typedef struct DTLSRecvdRecordsStr {
- unsigned char data[DTLS_RECVD_RECORDS_WINDOW/8];
- PRUint64 left;
- PRUint64 right;
+ unsigned char data[DTLS_RECVD_RECORDS_WINDOW / 8];
+ sslSequenceNumber left;
+ sslSequenceNumber right;
} DTLSRecvdRecords;
/*
@@ -568,198 +470,199 @@ typedef struct DTLSRecvdRecordsStr {
** (direct and indirect) is protected by the reader/writer lock ss->specLock.
*/
typedef struct {
+ PRCList link;
const ssl3BulkCipherDef *cipher_def;
- const ssl3MACDef * mac_def;
+ const ssl3MACDef *mac_def;
SSLCompressionMethod compression_method;
- int mac_size;
- SSLCipher encode;
- SSLCipher decode;
- SSLAEADCipher aead;
- 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;
+ int mac_size;
+ SSLCipher encode;
+ SSLCipher decode;
+ SSLAEADCipher aead;
+ 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;
+ PK11SymKey *master_secret;
+ sslSequenceNumber write_seq_num;
+ sslSequenceNumber 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;
+ ssl3KeyMaterial client;
+ ssl3KeyMaterial server;
+ SECItem msItem;
+ DTLSEpoch epoch;
+ DTLSRecvdRecords recvdRecords;
+
+ PRUint8 refCt;
+ const char *phase;
} ssl3CipherSpec;
-typedef enum { never_cached,
- in_client_cache,
- in_server_cache,
- invalid_cache /* no longer in any cache. */
+typedef enum { never_cached,
+ in_client_cache,
+ in_server_cache,
+ invalid_cache /* no longer in any cache. */
} Cached;
+#include "sslcert.h"
+
struct sslSessionIDStr {
/* The global cache lock must be held when accessing these members when the
* sid is in any cache.
*/
- sslSessionID * next; /* chain used for client sockets, only */
- Cached cached;
- int references;
- PRUint32 lastAccessTime; /* seconds since Jan 1, 1970 */
+ sslSessionID *next; /* chain used for client sockets, only */
+ Cached cached;
+ int references;
+ PRUint32 lastAccessTime; /* seconds since Jan 1, 1970 */
/* The rest of the members, except for the members of u.ssl3.locked, may
* be modified only when the sid is not in any cache.
*/
- CERTCertificate * peerCert;
- SECItemArray peerCertStatus; /* client only */
- const char * peerID; /* client only */
- const char * urlSvrName; /* client only */
- CERTCertificate * localCert;
+ CERTCertificate *peerCert;
+ SECItemArray peerCertStatus; /* client only */
+ const char *peerID; /* client only */
+ const char *urlSvrName; /* client only */
+ sslServerCertType certType;
+ CERTCertificate *localCert;
- PRIPv6Addr addr;
- PRUint16 port;
+ PRIPv6Addr addr;
+ PRUint16 port;
- SSL3ProtocolVersion version;
+ SSL3ProtocolVersion version;
- PRUint32 creationTime; /* seconds since Jan 1, 1970 */
- PRUint32 expirationTime; /* seconds since Jan 1, 1970 */
+ PRUint32 creationTime; /* seconds since Jan 1, 1970 */
+ PRUint32 expirationTime; /* seconds since Jan 1, 1970 */
- SSLSignType authAlgorithm;
- PRUint32 authKeyBits;
- SSLKEAType keaType;
- PRUint32 keaKeyBits;
+ SSLAuthType authType;
+ 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. */
- PRUint8 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. */
-#ifndef NSS_DISABLE_ECC
- PRUint32 negotiatedECCurves;
-#endif /* NSS_DISABLE_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;
-
- SECItem srvName;
-
- /* This lock is lazily initialized by CacheSID when a sid is first
- * cached. Before then, there is no need to lock anything because
- * the sid isn't being shared by anything.
- */
- PRRWLock *lock;
-
- /* The lock must be held while reading or writing these members
- * because they change while the sid is cached.
- */
- struct {
- /* The session ticket, if we have one, is sent as an extension
- * in the ClientHello message. This field is used only by
- * clients. It is protected by lock when lock is non-null
- * (after the sid has been added to the client session cache).
- */
- NewSessionTicket sessionTicket;
- } locked;
- } ssl3;
+ struct {
+ /* values that are copied into the server's on-disk SID cache. */
+ PRUint8 sessionIDLength;
+ SSL3Opaque sessionID[SSL3_SESSIONID_BYTES];
+
+ ssl3CipherSuite cipherSuite;
+ SSLCompressionMethod compression;
+ int policy;
+ ssl3SidKeys keys;
+ /* mechanism used to wrap master secret */
+ CK_MECHANISM_TYPE masterWrapMech;
+
+ /* 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;
+
+ SECItem srvName;
+
+ /* Signed certificate timestamps received in a TLS extension.
+ ** (used only in client).
+ */
+ SECItem signedCertTimestamps;
+
+ /* The NPN/ALPN value negotiated in the original connection.
+ * Used for TLS 1.3. */
+ SECItem alpnSelection;
+
+ /* This lock is lazily initialized by CacheSID when a sid is first
+ * cached. Before then, there is no need to lock anything because
+ * the sid isn't being shared by anything.
+ */
+ PRRWLock *lock;
+
+ /* The lock must be held while reading or writing these members
+ * because they change while the sid is cached.
+ */
+ struct {
+ /* The session ticket, if we have one, is sent as an extension
+ * in the ClientHello message. This field is used only by
+ * clients. It is protected by lock when lock is non-null
+ * (after the sid has been added to the client session cache).
+ */
+ NewSessionTicket sessionTicket;
+ } locked;
+ } ssl3;
} u;
};
typedef struct ssl3CipherSuiteDefStr {
- ssl3CipherSuite cipher_suite;
- SSL3BulkCipher bulk_cipher_alg;
- SSL3MACAlgorithm mac_alg;
+ ssl3CipherSuite cipher_suite;
+ SSL3BulkCipher bulk_cipher_alg;
+ SSL3MACAlgorithm mac_alg;
SSL3KeyExchangeAlgorithm key_exchange_alg;
+ SSLHashType prf_hash;
} ssl3CipherSuiteDef;
/*
** There are tables of these, all const.
*/
typedef struct {
+ /* An identifier for this struct. */
SSL3KeyExchangeAlgorithm kea;
- SSL3KEAType exchKeyType;
- SSL3SignType signKeyType;
- /* For export cipher suites:
- * is_limited identifies a suite as having a limit on the key size.
- * key_size_limit provides the corresponding limit. */
- PRBool is_limited;
- unsigned int key_size_limit;
- PRBool tls_keygen;
+ /* The type of key exchange used by the cipher suite. */
+ SSLKEAType exchKeyType;
+ /* If the cipher suite uses a signature, the type of key used in the
+ * signature. */
+ KeyType signKeyType;
+ /* In most cases, cipher suites depend on their signature type for
+ * authentication, ECDH certificates being the exception. */
+ SSLAuthType authKeyType;
/* True if the key exchange for the suite is ephemeral. Or to be more
* precise: true if the ServerKeyExchange message is always required. */
- PRBool ephemeral;
+ PRBool ephemeral;
+ /* An OID describing the key exchange */
+ SECOidTag oid;
} ssl3KEADef;
/*
** There are tables of these, all const.
*/
struct ssl3BulkCipherDefStr {
- SSL3BulkCipher cipher;
+ SSL3BulkCipher cipher;
SSLCipherAlgorithm calg;
- int key_size;
- int secret_key_size;
- CipherType type;
- int iv_size;
- int block_size;
- int tag_size; /* authentication tag size for AEAD ciphers. */
- int explicit_nonce_size; /* for AEAD ciphers. */
+ unsigned int key_size;
+ unsigned int secret_key_size;
+ CipherType type;
+ unsigned int iv_size;
+ unsigned int block_size;
+ unsigned int tag_size; /* for AEAD ciphers. */
+ unsigned int explicit_nonce_size; /* for AEAD ciphers. */
+ SECOidTag oid;
+ const char *short_name;
+ /* The maximum number of records that can be sent/received with the same
+ * symmetric key before the connection will be terminated. */
+ PRUint64 max_records;
};
/*
@@ -768,54 +671,52 @@ struct ssl3BulkCipherDefStr {
struct ssl3MACDefStr {
SSL3MACAlgorithm mac;
CK_MECHANISM_TYPE mmech;
- int pad_size;
- int mac_size;
+ int pad_size;
+ int mac_size;
+ SECOidTag oid;
};
typedef enum {
- wait_client_hello,
- wait_client_cert,
+ ssl_0rtt_none, /* 0-RTT not present */
+ ssl_0rtt_sent, /* 0-RTT sent (no decision yet) */
+ ssl_0rtt_accepted, /* 0-RTT sent and accepted */
+ ssl_0rtt_ignored, /* 0-RTT sent but rejected/ignored */
+ ssl_0rtt_done /* 0-RTT accepted, but finished */
+} sslZeroRttState;
+
+typedef enum {
+ ssl_0rtt_ignore_none, /* not ignoring */
+ ssl_0rtt_ignore_trial, /* ignoring with trial decryption */
+ ssl_0rtt_ignore_hrr /* ignoring until ClientHello (due to HRR) */
+} sslZeroRttIgnore;
+
+typedef enum {
+ idle_handshake,
+ wait_client_hello,
+ wait_client_cert,
wait_client_key,
- wait_cert_verify,
- wait_change_cipher,
+ wait_cert_verify,
+ wait_change_cipher,
wait_finished,
- wait_server_hello,
+ wait_server_hello,
wait_certificate_status,
- wait_server_cert,
+ wait_server_cert,
wait_server_key,
- wait_cert_request,
+ wait_cert_request,
wait_hello_done,
wait_new_session_ticket,
- idle_handshake
+ wait_encrypted_extensions,
+ wait_invalid /* Invalid value. There is no handshake message "invalid". */
} 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;
- PRBool sentSessionTicketInClientHello;
-
- /* 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 enum {
+ client_hello_initial, /* The first attempt. */
+ client_hello_retry, /* If we receive HelloRetryRequest. */
+ client_hello_retransmit, /* In DTLS, if we receive HelloVerifyRequest. */
+ client_hello_renegotiation /* A renegotiation attempt. */
+} sslClientHelloType;
+
+typedef struct SessionTicketDataStr SessionTicketData;
typedef SECStatus (*sslRestartTarget)(sslSocket *);
@@ -823,252 +724,283 @@ 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 */
+ PRCList link; /* The linked list link */
+ ssl3CipherSpec *cwSpec; /* The cipher spec to use, null for none */
+ SSL3ContentType type; /* The message type */
+ unsigned char *data; /* The data */
+ PRUint16 len; /* The data length */
} DTLSQueuedMessage;
+typedef struct TLS13KeyShareEntryStr {
+ PRCList link; /* The linked list link */
+ const sslNamedGroupDef *group; /* The group for the entry */
+ SECItem key_exchange; /* The share itself */
+} TLS13KeyShareEntry;
+
+typedef struct TLS13EarlyDataStr {
+ PRCList link; /* The linked list link */
+ SECItem data; /* The data */
+} TLS13EarlyData;
+
typedef enum {
handshake_hash_unknown = 0,
handshake_hash_combo = 1, /* The MD5/SHA-1 combination */
- handshake_hash_single = 2 /* A single hash */
+ handshake_hash_single = 2, /* A single hash */
+ handshake_hash_record
} SSL3HandshakeHashType;
+/* This holds state for TLS 1.3 CertificateRequest handling. */
+typedef struct TLS13CertificateRequestStr {
+ PLArenaPool *arena;
+ SECItem context;
+ SSLSignatureScheme *signatureSchemes;
+ unsigned int signatureSchemeCount;
+ CERTDistNames ca_list;
+} TLS13CertificateRequest;
+
/*
** 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;
+ SSL3Random server_random;
+ SSL3Random client_random;
+ SSL3WaitState ws; /* May also contain SSL3WaitState | 0x80 for TLS 1.3 */
/* This group of members is used for handshake running hashes. */
SSL3HandshakeHashType hashType;
- sslBuffer messages; /* Accumulated handshake messages */
-#ifndef NO_PKCS11_BYPASS
- /* Bypass mode:
- * SSL 3.0 - TLS 1.1 use both |md5_cx| and |sha_cx|. |md5_cx| is used for
- * MD5 and |sha_cx| for SHA-1.
- * TLS 1.2 and later use only |sha_cx|, for SHA-256. NOTE: When we support
- * SHA-384, increase MAX_MAC_CONTEXT_BYTES to 712. */
- PRUint64 md5_cx[MAX_MAC_CONTEXT_LLONGS];
- PRUint64 sha_cx[MAX_MAC_CONTEXT_LLONGS];
- const SECHashObject * sha_obj;
- /* The function prototype of sha_obj->clone() does not match the prototype
- * of the freebl <HASH>_Clone functions, so we need a dedicated function
- * pointer for the <HASH>_Clone function. */
- void (*sha_clone)(void *dest, void *src);
-#endif
+ sslBuffer messages; /* Accumulated handshake messages */
/* PKCS #11 mode:
* SSL 3.0 - TLS 1.1 use both |md5| and |sha|. |md5| is used for MD5 and
* |sha| for SHA-1.
* TLS 1.2 and later use only |sha|, for SHA-256. */
- /* NOTE: On the client side, TLS 1.2 and later use |md5| as a backup
- * handshake hash for generating client auth signatures. Confusingly, the
- * backup hash function is SHA-1. */
-#define backupHash md5
- PK11Context * md5;
- 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 */
+ PK11Context *md5;
+ PK11Context *sha;
+ SSLSignatureScheme signatureScheme;
+ 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;
+ PRBool isResuming; /* we are resuming (not used in TLS 1.3) */
+ PRBool sendingSCSV; /* instead of empty RI */
+ sslBuffer msgState; /* current state for handshake messages*/
+ /* protected by recvBufLock */
/* The session ticket received in a NewSessionTicket message is temporarily
* stored in newSessionTicket until the handshake is finished; then it is
* moved to the sid.
*/
- PRBool receivedNewSessionTicket;
- NewSessionTicket newSessionTicket;
+ PRBool receivedNewSessionTicket;
+ NewSessionTicket newSessionTicket;
- PRUint16 finishedBytes; /* size of single finished below */
+ PRUint16 finishedBytes; /* size of single finished below */
union {
- TLSFinished tFinished[2]; /* client, then server */
- SSL3Finished sFinished[2];
- SSL3Opaque data[72];
- } finishedMsgs;
-#ifndef NSS_DISABLE_ECC
- PRUint32 negotiatedECCurves; /* bit mask */
-#endif /* NSS_DISABLE_ECC */
-
- PRBool authCertificatePending;
+ TLSFinished tFinished[2]; /* client, then server */
+ SSL3Finished sFinished[2];
+ SSL3Opaque data[72];
+ } finishedMsgs;
+
+ PRBool authCertificatePending;
/* Which function should SSL_RestartHandshake* call if we're blocked?
* One of NULL, ssl3_SendClientSecondRound, ssl3_FinishHandshake,
* or ssl3_AlwaysFail */
- sslRestartTarget restartTarget;
+ sslRestartTarget restartTarget;
/* Shared state between ssl3_HandleFinished and ssl3_FinishHandshake */
- PRBool cacheSID;
+ PRBool cacheSID;
- PRBool canFalseStart; /* Can/did we False Start */
+ PRBool canFalseStart; /* Can/did we False Start */
/* Which preliminaryinfo values have been set. */
- PRUint32 preliminaryInfo;
+ PRUint32 preliminaryInfo;
- /* clientSigAndHash contains the contents of the signature_algorithms
- * extension (if any) from the client. This is only valid for TLS 1.2
- * or later. */
- SSLSignatureAndHashAlg *clientSigAndHash;
- unsigned int numClientSigAndHash;
+ /* Parsed extensions */
+ PRCList remoteExtensions; /* Parsed incoming extensions */
/* 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 */
+ 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. */
+ SECItem cookie; /* The Hello(Retry|Verify)Request 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 */
+ SECItem srvVirtName; /* for server: name that was negotiated
+ * with a client. For client - is
+ * always set to NULL.*/
+
+ /* This group of values is used for TLS 1.3 and above */
+ PK11SymKey *currentSecret; /* The secret down the "left hand side"
+ * of the TLS 1.3 key schedule. */
+ PK11SymKey *resumptionMasterSecret; /* The resumption PSK. */
+ PK11SymKey *dheSecret; /* The (EC)DHE shared secret. */
+ PK11SymKey *pskBinderKey; /* Used to compute the PSK binder. */
+ PK11SymKey *clientEarlyTrafficSecret; /* The secret we use for 0-RTT. */
+ PK11SymKey *clientHsTrafficSecret; /* The source keys for handshake */
+ PK11SymKey *serverHsTrafficSecret; /* traffic keys. */
+ PK11SymKey *clientTrafficSecret; /* The source keys for application */
+ PK11SymKey *serverTrafficSecret; /* traffic keys */
+ PK11SymKey *earlyExporterSecret; /* for 0-RTT exporters */
+ PK11SymKey *exporterSecret; /* for exporters */
+ /* The certificate request from the server. */
+ TLS13CertificateRequest *certificateRequest;
+ PRCList cipherSpecs; /* The cipher specs in the sequence they
+ * will be applied. */
+ ssl3CipherSpec *nullSpec; /* In case 0-RTT is rejected. */
+ sslZeroRttState zeroRttState; /* Are we doing a 0-RTT handshake? */
+ sslZeroRttIgnore zeroRttIgnore; /* Are we ignoring 0-RTT? */
+ ssl3CipherSuite zeroRttSuite; /* The cipher suite we used for 0-RTT. */
+ PRCList bufferedEarlyData; /* Buffered TLS 1.3 early data
+ * on server.*/
+ PRBool helloRetry; /* True if HelloRetryRequest has been sent
+ * or received. */
+ ssl3KEADef kea_def_mutable; /* Used to hold the writable kea_def
+ * we use for TLS 1.3 */
+ PRBool shortHeaders; /* Assigned if we are doing short headers. */
} SSL3HandshakeState;
-
-
/*
** This is the "ssl3" struct, as in "ss->ssl3".
** note:
-** usually, crSpec == cwSpec and prSpec == pwSpec.
+** usually, crSpec == cwSpec and prSpec == pwSpec.
** Sometimes, crSpec == pwSpec and prSpec == cwSpec.
-** But there are never more than 2 actual specs.
+** 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
+ ** 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
- */
- PLArenaPool * 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.
+ 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
*/
- SECItem nextProto;
- SSLNextProtoState nextProtoState;
-
- PRUint16 mtu; /* Our estimate of the MTU */
+ PLArenaPool *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. */
+
+ 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 */
- PRBool fatalAlertSent;
- PRUint16 numDHEGroups; /* used by server */
- SSLDHEGroupType * dheGroups; /* used by server */
- PRBool dheWeakGroupEnabled; /* used by server */
+ PRUint16 dtlsSRTPCiphers[MAX_DTLS_SRTP_CIPHER_SUITES];
+ PRUint16 dtlsSRTPCipherCount;
+ PRBool fatalAlertSent;
+ PRBool dheWeakGroupEnabled; /* used by server */
+ const sslNamedGroupDef *dhePreferredGroup;
/* TLS 1.2 introduces separate signature algorithm negotiation.
+ * TLS 1.3 combined signature and hash into a single enum.
* This is our preference order. */
- SSLSignatureAndHashAlg signatureAlgorithms[MAX_SIGNATURE_ALGORITHMS];
- unsigned int signatureAlgorithmCount;
+ SSLSignatureScheme signatureSchemes[MAX_SIGNATURE_SCHEMES];
+ unsigned int signatureSchemeCount;
+
+ /* The version to check if we fell back from our highest version
+ * of TLS. Default is 0 in which case we check against the maximum
+ * configured version for this socket. Used only on the client. */
+ SSL3ProtocolVersion downgradeCheckVersion;
};
-#define DTLS_MAX_MTU 1500U /* Ethernet MTU but without subtracting the
- * headers, so slightly larger than expected */
+/* Ethernet MTU but without subtracting the headers,
+ * so slightly larger than expected */
+#define DTLS_MAX_MTU 1500U
#define IS_DTLS(ss) (ss->protocolVariant == ssl_variant_datagram)
typedef struct {
- SSL3ContentType type;
- SSL3ProtocolVersion version;
- SSL3SequenceNumber seq_num; /* DTLS only */
- sslBuffer * buf;
+ SSL3ContentType type;
+ SSL3ProtocolVersion version;
+ sslSequenceNumber seq_num; /* DTLS only */
+ sslBuffer *buf;
} SSL3Ciphertext;
-struct ssl3KeyPairStr {
- SECKEYPrivateKey * privKey;
- SECKEYPublicKey * pubKey;
- PRInt32 refCount; /* use PR_Atomic calls for this. */
+struct sslKeyPairStr {
+ SECKEYPrivateKey *privKey;
+ SECKEYPublicKey *pubKey;
+ PRInt32 refCount; /* use PR_Atomic calls for this. */
};
+typedef struct {
+ PRCList link;
+ const sslNamedGroupDef *group;
+ sslKeyPair *keys;
+} sslEphemeralKeyPair;
+
struct ssl3DHParamsStr {
+ SSLNamedGroup name;
SECItem prime; /* p */
- SECItem base; /* g */
+ SECItem base; /* g */
};
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;
+ 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. */
+ SSLAuthType authType; /* type of keys used to wrap SymWrapKey*/
+ PRInt32 symWrapMechIndex;
+ PRUint16 wrappedSymKeyLen;
} SSLWrappedSymWrappingKey;
typedef struct SessionTicketStr {
- PRUint16 ticket_version;
- SSL3ProtocolVersion ssl_version;
- ssl3CipherSuite cipher_suite;
- SSLCompressionMethod compression_method;
- SSLSignType authAlgorithm;
- PRUint32 authKeyBits;
- SSLKEAType keaType;
- PRUint32 keaKeyBits;
+ PRUint16 ticket_version;
+ SSL3ProtocolVersion ssl_version;
+ ssl3CipherSuite cipher_suite;
+ SSLCompressionMethod compression_method;
+ SSLAuthType authType;
+ PRUint32 authKeyBits;
+ SSLKEAType keaType;
+ PRUint32 keaKeyBits;
+ sslServerCertType certType;
/*
- * exchKeyType and msWrapMech contain meaningful values only if
- * ms_is_wrapped is true.
+ * msWrapMech contains a meaningful value only if ms_is_wrapped is true.
*/
- PRUint8 ms_is_wrapped;
- SSLKEAType exchKeyType; /* XXX(wtc): same as keaType above? */
- CK_MECHANISM_TYPE msWrapMech;
- PRUint16 ms_length;
- SSL3Opaque master_secret[48];
- PRBool extendedMasterSecretUsed;
- ClientIdentity client_identity;
- SECItem peer_cert;
- PRUint32 timestamp;
- SECItem srvName; /* negotiated server name */
-} SessionTicket;
+ PRUint8 ms_is_wrapped;
+ CK_MECHANISM_TYPE msWrapMech;
+ PRUint16 ms_length;
+ SSL3Opaque master_secret[48];
+ PRBool extendedMasterSecretUsed;
+ ClientIdentity client_identity;
+ SECItem peer_cert;
+ PRUint32 timestamp;
+ PRUint32 flags;
+ SECItem srvName; /* negotiated server name */
+ SECItem alpnSelection;
+} SessionTicket;
/*
* SSL2 buffers used in SSL3.
@@ -1081,112 +1013,55 @@ typedef struct SessionTicketStr {
/*
** This is "ci", as in "ss->sec.ci".
**
-** Protection: All the variables in here are protected by
-** firstHandshakeLock AND (in ssl3) ssl3HandshakeLock
+** Protection: All the variables in here are protected by
+** firstHandshakeLock AND 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 */
+ sslBuffer sendBuf; /*xmitBufLock*/
- char sentFinished; /* ssl2 only */
+ PRIPv6Addr peer;
+ unsigned short port;
- /* 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 */
+ sslSessionID *sid;
};
-/* 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.
+ * Unless otherwise specified below, the contents of this struct are
+ * protected by firstHandshakeLock AND 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 */
+#define SSL_ROLE(ss) (ss->sec.isServer ? "server" : "client")
- /*
- ** 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 */
+ PRBool isServer;
+ sslBuffer writeBuf; /*xmitBufLock*/
- SECItem sendSecret; /* Spec Lock */ /* ssl2 only */
- SECItem rcvSecret; /* Spec Lock */ /* ssl2 only */
+ CERTCertificate *localCert;
+ CERTCertificate *peerCert;
+ SECKEYPublicKey *peerKey;
- /* 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 */
+ SSLAuthType authType;
+ PRUint32 authKeyBits;
+ SSLSignatureScheme signatureScheme;
+ SSLKEAType keaType;
+ PRUint32 keaKeyBits;
+ const sslNamedGroupDef *keaGroup;
+ /* The selected certificate (for servers only). */
+ const sslServerCert *serverCert;
- /* Blocking information for the session cypher */
- int blockShift; /* Spec Lock */ /* ssl2 only */
- int blockSize; /* Spec Lock */ /* ssl2 only */
+ /*
+ ** Procs used for SID cache (nonce) management.
+ ** Different implementations exist for clients/servers
+ ** The lookup proc is only used for servers. Baloney!
+ */
+ sslSessionIDCacheFunc cache;
+ sslSessionIDUncacheFunc uncache;
/* These are used during a connection handshake */
- sslConnectInfo ci; /* ssl 2 & 3 */
-
+ sslConnectInfo ci;
};
/*
@@ -1195,164 +1070,164 @@ struct sslSecurityInfoStr {
** Protection: XXX
*/
struct sslSocketStr {
- PRFileDesc * fd;
+ PRFileDesc *fd;
/* Pointer to operations vector for this socket */
- const sslSocketOps * ops;
+ const sslSocketOps *ops;
/* SSL socket options */
- sslOptions opt;
+ sslOptions opt;
/* Enabled version range */
- SSLVersionRange vrange;
+ SSLVersionRange vrange;
/* State flags */
- unsigned long clientAuthRequested;
- unsigned long delayDisabled; /* Nagle delay disabled */
- unsigned long firstHsDone; /* first handshake is complete. */
- unsigned long enoughFirstHsDone; /* enough of the first handshake is
- * done for callbacks to be able to
- * retrieve channel security
- * parameters from the SSL socket. */
- unsigned long handshakeBegun;
- unsigned long lastWriteBlocked;
- unsigned long recvdCloseNotify; /* received SSL EOF. */
- unsigned long TCPconnected;
- unsigned long appDataBuffered;
- unsigned long peerRequestedProtection; /* from old renegotiation */
+ unsigned long clientAuthRequested;
+ unsigned long delayDisabled; /* Nagle delay disabled */
+ unsigned long firstHsDone; /* first handshake is complete. */
+ unsigned long enoughFirstHsDone; /* enough of the first handshake is
+ * done for callbacks to be able to
+ * retrieve channel security
+ * parameters from the SSL socket. */
+ 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 */
+ sslSecurityInfo sec; /* not a pointer any more */
- /* protected by firstHandshakeLock AND (in ssl3) ssl3HandshakeLock. */
- const char *url; /* ssl 2 & 3 */
+ /* protected by firstHandshakeLock AND ssl3HandshakeLock. */
+ const char *url;
- sslHandshakeFunc handshake; /*firstHandshakeLock*/
- sslHandshakeFunc nextHandshake; /*firstHandshakeLock*/
- sslHandshakeFunc securityHandshake; /*firstHandshakeLock*/
+ sslHandshakeFunc handshake; /*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;
+ char *peerID; /* String uniquely identifies target server. */
- ssl3KeyPair * stepDownKeyPair; /* RSA step down keys */
-
- const ssl3DHParams *dheParams; /* DHE param */
- ssl3KeyPair * dheKeyPair; /* DHE keys */
+ /* ECDHE and DHE keys: In TLS 1.3, we might have to maintain multiple of
+ * these on the client side. The server inserts a single value into this
+ * list for all versions. */
+ PRCList /*<sslEphemeralKeyPair>*/ ephemeralKeyPairs;
/* Callbacks */
- SSLAuthCertificate authCertificate;
- void *authCertificateArg;
- SSLGetClientAuthData getClientAuthData;
- void *getClientAuthDataArg;
- SSLSNISocketConfig sniSocketConfig;
- void *sniSocketConfigArg;
- SSLBadCertHandler handleBadCert;
- void *badCertArg;
- SSLHandshakeCallback handshakeCallback;
- void *handshakeCallbackData;
- SSLCanFalseStartCallback canFalseStartCallback;
- void *canFalseStartCallbackData;
- 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. */
+ SSLAuthCertificate authCertificate;
+ void *authCertificateArg;
+ SSLGetClientAuthData getClientAuthData;
+ void *getClientAuthDataArg;
+ SSLSNISocketConfig sniSocketConfig;
+ void *sniSocketConfigArg;
+ SSLBadCertHandler handleBadCert;
+ void *badCertArg;
+ SSLHandshakeCallback handshakeCallback;
+ void *handshakeCallbackData;
+ SSLCanFalseStartCallback canFalseStartCallback;
+ void *canFalseStartCallbackData;
+ 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;
+ 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;
+ PZMonitor *ssl3HandshakeLock;
/* reader/writer lock, protects the secret data needed to encrypt and MAC
- ** outgoing records, and to decrypt and MAC check incoming ciphertext
+ ** outgoing records, and to decrypt and MAC check incoming ciphertext
** records. */
- NSSRWLock * specLock;
+ NSSRWLock *specLock;
- /* handle to perm cert db (and implicitly to the temp cert db) used
- ** with this socket.
+ /* 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 */
+ CERTCertDBHandle *dbHandle;
- PRUint16 shutdownHow; /* See ssl_SHUTDOWN defines below. */
+ PRThread *writerThread; /* thread holds SSL_LOCK_WRITER lock */
- PRUint16 allowedByPolicy; /* copy of global policy bits. */
- PRUint16 maybeAllowedByPolicy; /* copy of global policy bits. */
- PRUint16 chosenPreference; /* SSL2 cipher preferences. */
+ PRUint16 shutdownHow; /* See ssl_SHUTDOWN defines below. */
sslHandshakingType handshaking;
/* Gather object used for gathering data */
- sslGather gs; /*recvBufLock*/
+ sslGather gs; /*recvBufLock*/
- sslBuffer saveBuf; /*xmitBufLock*/
- sslBuffer pendingBuf; /*xmitBufLock*/
+ sslBuffer saveBuf; /*xmitBufLock*/
+ sslBuffer pendingBuf; /*xmitBufLock*/
/* Configuration state for server sockets */
- /* server cert and key for each KEA type */
- sslServerCerts serverCerts[kt_kea_size];
- /* each cert needs its own status */
- SECItemArray * certStatusArray[kt_kea_size];
+ /* One server cert and key for each authentication type. */
+ PRCList /* <sslServerCert> */ serverCerts;
ssl3CipherSuiteCfg cipherSuites[ssl_V3_SUITES_IMPLEMENTED];
- ssl3KeyPair * ephemeralECDHKeyPair; /* for ECDHE-* handshake */
+
+ /* A list of groups that are sorted according to user preferences pointing
+ * to entries of ssl_named_groups. By default this list contains pointers
+ * to all elements in ssl_named_groups in the default order.
+ * This list also determines which groups are enabled. This
+ * starts with all being enabled and can be modified either by negotiation
+ * (in which case groups not supported by a peer are masked off), or by
+ * calling SSL_DHEGroupPrefSet().
+ * Note that renegotiation will ignore groups that were disabled in the
+ * first handshake.
+ */
+ const sslNamedGroupDef *namedGroupPreferences[SSL_NAMED_GROUP_COUNT];
+ /* The number of additional shares to generate for the TLS 1.3 ClientHello */
+ unsigned int additionalShares;
/* SSL3 state info. Formerly was a pointer */
- ssl3State ssl3;
+ ssl3State ssl3;
/*
* TLS extension related data.
*/
/* True when the current session is a stateless resume. */
- PRBool statelessResume;
- TLSExtensionData xtnData;
+ PRBool statelessResume;
+ TLSExtensionData xtnData;
/* Whether we are doing stream or datagram mode */
- SSLProtocolVariant protocolVariant;
+ SSLProtocolVariant protocolVariant;
};
-
-
-/* All the global data items declared here should be protected using the
+/* 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 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 ssl3_cipherName[];
+
+extern sslSessionIDLookupFunc ssl_sid_lookup;
+extern sslSessionIDCacheFunc ssl_sid_cache;
extern sslSessionIDUncacheFunc ssl_sid_uncache;
+extern const sslNamedGroupDef ssl_named_groups[];
+
/************************************************************************/
SEC_BEGIN_PROTOS
@@ -1370,15 +1245,15 @@ 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);
+ 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);
+ void *optval, PRInt32 *optlen);
extern int ssl_DefSetsockopt(sslSocket *ss, PRSockOption optname,
- const void *optval, PRInt32 optlen);
+ const void *optval, PRInt32 optlen);
/* Implementation of ops for socks only case */
extern int ssl_SocksConnect(sslSocket *ss, const PRNetAddr *addr);
@@ -1388,7 +1263,7 @@ 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);
+ 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);
@@ -1396,9 +1271,9 @@ extern int ssl_SocksWrite(sslSocket *ss, const unsigned char *buf, int len);
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);
+ int len, int flags);
extern int ssl_SecureSend(sslSocket *ss, const unsigned char *buf,
- int len, int flags);
+ 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);
@@ -1410,88 +1285,83 @@ 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 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 sslGather *ssl_NewGather(void);
+extern SECStatus ssl3_InitGather(sslGather *gs);
+extern void ssl3_DestroyGather(sslGather *gs);
+extern SECStatus ssl_GatherRecord1stHandshake(sslSocket *ss);
+
+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(const sslSocket *ss, const char *msg, const void *cp,
+ int len);
+extern void ssl_PrintKey(const sslSocket *ss, const char *msg, PK11SymKey *key);
+
+extern int ssl_SendSavedWriteData(sslSocket *ss);
+extern SECStatus ssl_SaveWriteData(sslSocket *ss,
+ const void *p, unsigned int l);
+extern SECStatus ssl_BeginClientHandshake(sslSocket *ss);
+extern SECStatus ssl_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 SECStatus sslBuffer_Append(sslBuffer *b, const void *data,
+ unsigned int len);
+extern void sslBuffer_Clear(sslBuffer *b);
-extern void ssl2_UseClearSendFunc(sslSocket *ss);
-extern void ssl_ChooseSessionIDProcs(sslSecurityInfo *sec);
+extern void ssl_ChooseSessionIDProcs(sslSecurityInfo *sec);
+extern void ssl3_InitCipherSpec(ssl3CipherSpec *spec);
extern sslSessionID *ssl3_NewSessionID(sslSocket *ss, PRBool is_server);
-extern sslSessionID *ssl_LookupSID(const PRIPv6Addr *addr, PRUint16 port,
+extern sslSessionID *ssl_LookupSID(const PRIPv6Addr *addr, PRUint16 port,
const char *peerID, const char *urlSvrName);
-extern void ssl_FreeSID(sslSessionID *sid);
+extern void ssl_FreeSID(sslSessionID *sid);
-extern int ssl3_SendApplicationData(sslSocket *ss, const PRUint8 *in,
- int len, int flags);
+extern int ssl3_SendApplicationData(sslSocket *ss, const PRUint8 *in,
+ int len, int flags);
-extern PRBool ssl_FdIsBlocking(PRFileDesc *fd);
+extern PRBool ssl_FdIsBlocking(PRFileDesc *fd);
-extern PRBool ssl_SocketIsBlocking(sslSocket *ss);
+extern PRBool ssl_SocketIsBlocking(sslSocket *ss);
-extern void ssl3_SetAlwaysBlock(sslSocket *ss);
+extern void ssl3_SetAlwaysBlock(sslSocket *ss);
extern SECStatus ssl_EnableNagleDelay(sslSocket *ss, PRBool enabled);
-extern void ssl_FinishHandshake(sslSocket *ss);
+extern void ssl_FinishHandshake(sslSocket *ss);
+
+extern SECStatus ssl_CipherPolicySet(PRInt32 which, PRInt32 policy);
+
+extern SECStatus ssl_CipherPrefSetDefault(PRInt32 which, PRBool enabled);
+
+extern SECStatus ssl3_ConstrainRangeByPolicy(void);
-/* Returns PR_TRUE if we are still waiting for the server to respond to our
- * client second round. Once we've received any part of the server's second
- * round then we don't bother trying to false start since it is almost always
- * the case that the NewSessionTicket, ChangeCipherSoec, and Finished messages
- * were sent in the same packet and we want to process them all at the same
- * time. If we were to try to false start in the middle of the server's second
- * round, then we would increase the number of I/O operations
- * (SSL_ForceHandshake/PR_Recv/PR_Send/etc.) needed to finish the handshake.
+extern SECStatus ssl3_InitState(sslSocket *ss);
+extern SECStatus ssl3_RestartHandshakeHashes(sslSocket *ss);
+extern SECStatus ssl3_UpdateHandshakeHashes(sslSocket *ss,
+ const unsigned char *b,
+ unsigned int l);
+
+/* Returns PR_TRUE if we are still waiting for the server to complete its
+ * response to our client second round. Once we've received the Finished from
+ * the server then there is no need to check false start.
*/
-extern PRBool ssl3_WaitingForStartOfServerSecondRound(sslSocket *ss);
+extern PRBool ssl3_WaitingForServerSecondRound(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
+extern PRInt32 ssl3_SendRecord(sslSocket *ss, ssl3CipherSpec *cwSpec,
+ SSL3ContentType type,
+ const SSL3Opaque *pIn, PRInt32 nIn,
+ PRInt32 flags);
+
+#ifdef NSS_SSL_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 */
+#else /* !NSS_SSL_ENABLE_ZLIB */
#define SSL3_COMPRESSION_MAX_EXPANSION 0
#endif
@@ -1499,68 +1369,109 @@ extern PRInt32 ssl3_SendRecord(sslSocket *ss, DTLSEpoch epoch,
* 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)
+#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) \
+#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) \
+#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); }
+#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) \
+#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) \
+#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) \
+#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
@@ -1568,42 +1479,33 @@ extern PRInt32 ssl3_SendRecord(sslSocket *ss, DTLSEpoch epoch,
*/
#define SSL_LIBRARY_VERSION_NONE 0
-/* SSL_LIBRARY_VERSION_MAX_SUPPORTED is the maximum version that this version
+/* 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.
*/
-#ifdef NSS_ENABLE_TLS_1_3
+#ifndef NSS_DISABLE_TLS_1_3
#define SSL_LIBRARY_VERSION_MAX_SUPPORTED SSL_LIBRARY_VERSION_TLS_1_3
#else
#define SSL_LIBRARY_VERSION_MAX_SUPPORTED SSL_LIBRARY_VERSION_TLS_1_2
#endif
-/* Rename this macro SSL_ALL_VERSIONS_DISABLED when SSL 2.0 is removed. */
-#define SSL3_ALL_VERSIONS_DISABLED(vrange) \
+#define SSL_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_MasterSecretDeriveBypass( ssl3CipherSpec * pwSpec,
- const unsigned char * cr, const unsigned char * sr,
- const SECItem * pms, PRBool isTLS, PRBool isRSA);
+ SSL3ProtocolVersion version);
/* 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);
+ 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);
+ SSL3AlertDescription desc);
extern SECStatus ssl3_DecodeError(sslSocket *ss);
extern SECStatus ssl3_AuthCertificateComplete(sslSocket *ss, PRErrorCode error);
@@ -1612,238 +1514,185 @@ 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);
+ sslSocket *ss, unsigned char *buffer, int length, PRUint8 padding);
-/*
- * SSL3 specific routines
- */
-SECStatus ssl3_SendClientHello(sslSocket *ss, PRBool resending);
+SECStatus ssl3_SendClientHello(sslSocket *ss, sslClientHelloType type);
/*
* input into the SSL3 machinery from the actualy network reading code
*/
SECStatus ssl3_HandleRecord(
sslSocket *ss, SSL3Ciphertext *cipher, sslBuffer *out);
+SECStatus ssl_RemoveTLSCBCPadding(sslBuffer *plaintext, unsigned int macSize);
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);
-extern SECStatus ssl3_SelectDHParams(sslSocket *ss);
+/* Create a new ref counted key pair object from two keys. */
+extern sslKeyPair *ssl_NewKeyPair(SECKEYPrivateKey *privKey,
+ SECKEYPublicKey *pubKey);
-#ifndef NSS_DISABLE_ECC
-extern void ssl3_FilterECCipherSuitesByServerCerts(sslSocket *ss);
-extern PRBool ssl3_IsECCEnabled(sslSocket *ss);
-extern SECStatus ssl3_DisableECCSuites(sslSocket * ss,
- const ssl3CipherSuite * suite);
-extern PRUint32 ssl3_GetSupportedECCurveMask(sslSocket *ss);
+/* get a new reference (bump ref count) to an ssl3KeyPair. */
+extern sslKeyPair *ssl_GetKeyPairRef(sslKeyPair *keyPair);
+/* Decrement keypair's ref count and free if zero. */
+extern void ssl_FreeKeyPair(sslKeyPair *keyPair);
+
+extern sslEphemeralKeyPair *ssl_NewEphemeralKeyPair(
+ const sslNamedGroupDef *group,
+ SECKEYPrivateKey *privKey, SECKEYPublicKey *pubKey);
+extern sslEphemeralKeyPair *ssl_CopyEphemeralKeyPair(
+ sslEphemeralKeyPair *keyPair);
+extern void ssl_FreeEphemeralKeyPair(sslEphemeralKeyPair *keyPair);
+extern sslEphemeralKeyPair *ssl_LookupEphemeralKeyPair(
+ sslSocket *ss, const sslNamedGroupDef *groupDef);
+extern PRBool ssl_HaveEphemeralKeyPair(const sslSocket *ss,
+ const sslNamedGroupDef *groupDef);
+extern void ssl_FreeEphemeralKeyPairs(sslSocket *ss);
+
+extern SECStatus ssl_AppendPaddedDHKeyShare(const sslSocket *ss,
+ const SECKEYPublicKey *pubKey,
+ PRBool appendLength);
+extern const ssl3DHParams *ssl_GetDHEParams(const sslNamedGroupDef *groupDef);
+extern SECStatus ssl_SelectDHEGroup(sslSocket *ss,
+ const sslNamedGroupDef **groupDef);
+extern SECStatus ssl_CreateDHEKeyPair(const sslNamedGroupDef *groupDef,
+ const ssl3DHParams *params,
+ sslEphemeralKeyPair **keyPair);
+extern PRBool ssl_IsValidDHEShare(const SECItem *dh_p, const SECItem *dh_Ys);
+extern SECStatus ssl_ValidateDHENamedGroup(sslSocket *ss,
+ const SECItem *dh_p,
+ const SECItem *dh_g,
+ const sslNamedGroupDef **groupDef,
+ const ssl3DHParams **dhParams);
+
+extern PRBool ssl_IsECCEnabled(const sslSocket *ss);
+extern PRBool ssl_IsDHEEnabled(const sslSocket *ss);
/* 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(PLArenaPool *arena, ECName curve,
- SECKEYECParams *params);
-ECName ssl3_GetCurveWithECKeyStrength(PRUint32 curvemsk, int requiredECCbits);
-
-
-#endif /* NSS_DISABLE_ECC */
+#define SSL_RSASTRENGTH_TO_ECSTRENGTH(s) \
+ ((s <= 1024) ? 160 \
+ : ((s <= 2048) ? 224 \
+ : ((s <= 3072) ? 256 \
+ : ((s <= 7168) ? 384 \
+ : 521))))
+
+extern const sslNamedGroupDef *ssl_LookupNamedGroup(SSLNamedGroup group);
+extern PRBool ssl_NamedGroupEnabled(const sslSocket *ss, const sslNamedGroupDef *group);
+extern SECStatus ssl_NamedGroup2ECParams(PLArenaPool *arena,
+ const sslNamedGroupDef *curve,
+ SECKEYECParams *params);
+extern const sslNamedGroupDef *ssl_ECPubKey2NamedGroup(
+ const SECKEYPublicKey *pubKey);
+
+extern const sslNamedGroupDef *ssl_GetECGroupForServerSocket(sslSocket *ss);
+extern void ssl_FilterSupportedGroups(sslSocket *ss);
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_CipherPrefGet(const sslSocket *ss, ssl3CipherSuite which, PRBool *on);
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 void ssl3_InitSocketPolicy(sslSocket *ss);
extern SECStatus ssl3_RedoHandshake(sslSocket *ss, PRBool flushCache);
-extern SECStatus ssl3_HandleHandshakeMessage(sslSocket *ss, SSL3Opaque *b,
- PRUint32 length);
+extern SECStatus ssl3_HandleHandshakeMessage(sslSocket *ss, SSL3Opaque *b,
+ PRUint32 length,
+ PRBool endOfRecord);
extern void ssl3_DestroySSL3Info(sslSocket *ss);
-extern SECStatus ssl3_NegotiateVersion(sslSocket *ss,
- SSL3ProtocolVersion peerVersion,
- PRBool allowLargerPeerVersion);
+extern SECStatus ssl_ClientReadVersion(sslSocket *ss, SSL3Opaque **b,
+ PRUint32 *length,
+ SSL3ProtocolVersion *version);
+extern SECStatus ssl3_NegotiateVersion(sslSocket *ss,
+ SSL3ProtocolVersion peerVersion,
+ PRBool allowLargerPeerVersion);
extern SECStatus ssl_GetPeerInfo(sslSocket *ss);
-#ifndef NSS_DISABLE_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, const SSLSignatureAndHashAlg *sigAndHash);
-#endif
+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,
+ sslKeyPair *serverKeys);
+extern SECStatus ssl3_SendECDHServerKeyExchange(sslSocket *ss);
+extern SECStatus ssl_ImportECDHKeyShare(
+ sslSocket *ss, SECKEYPublicKey *peerKey,
+ SSL3Opaque *b, PRUint32 length, const sslNamedGroupDef *curve);
+unsigned int tls13_SizeOfECDHEKeyShareKEX(const SECKEYPublicKey *pubKey);
+SECStatus tls13_EncodeECDHEKeyShareKEX(const sslSocket *ss,
+ const SECKEYPublicKey *pubKey);
extern SECStatus ssl3_ComputeCommonKeyHash(SSLHashType hashAlg,
- PRUint8 * hashBuf,
- unsigned int bufLen, SSL3Hashes *hashes,
- PRBool bypassPKCS11);
+ PRUint8 *hashBuf,
+ unsigned int bufLen,
+ SSL3Hashes *hashes);
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_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_AppendSignatureAndHashAlgorithm(
- sslSocket *ss, const SSLSignatureAndHashAlg* sigAndHash);
-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 PRBool ssl3_IsSupportedSignatureAlgorithm(
- const SSLSignatureAndHashAlg *alg);
-extern SECStatus ssl3_CheckSignatureAndHashAlgorithmConsistency(
- sslSocket *ss, const SSLSignatureAndHashAlg *sigAndHash,
- CERTCertificate* cert);
-extern SECStatus ssl3_ConsumeSignatureAndHashAlgorithm(
- sslSocket *ss, SSL3Opaque **b, PRUint32 *length,
- SSLSignatureAndHashAlg *out);
-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);
-
-#ifndef NSS_DISABLE_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);
+ sslSocket *ss, const SSLSignatureAndHashAlg *sigAndHash);
+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 PRUint8 *ssl_EncodeUintX(PRUint64 value, unsigned int bytes,
+ PRUint8 *to);
+extern PRBool ssl_IsSupportedSignatureScheme(SSLSignatureScheme scheme);
+extern SECStatus ssl_CheckSignatureSchemeConsistency(
+ sslSocket *ss, SSLSignatureScheme scheme, CERTCertificate *cert);
+extern SECStatus ssl_ParseSignatureSchemes(const sslSocket *ss, PLArenaPool *arena,
+ SSLSignatureScheme **schemesOut,
+ unsigned int *numSchemesOut,
+ unsigned char **b,
+ unsigned int *len);
+extern SECStatus ssl_ConsumeSignatureScheme(
+ sslSocket *ss, SSL3Opaque **b, PRUint32 *length, SSLSignatureScheme *out);
+extern SECStatus ssl3_SignHashes(sslSocket *ss, SSL3Hashes *hash,
+ SECKEYPrivateKey *key, SECItem *buf);
+extern SECStatus ssl3_VerifySignedHashes(sslSocket *ss, SSLSignatureScheme scheme,
+ SSL3Hashes *hash, SECItem *buf);
+extern SECStatus ssl3_CacheWrappedMasterSecret(
+ sslSocket *ss, sslSessionID *sid,
+ ssl3CipherSpec *spec, SSLAuthType authType);
+extern void ssl3_FreeSniNameArray(TLSExtensionData *xtnData);
/* Hello Extension related routines. */
-extern PRBool ssl3_ExtensionNegotiated(sslSocket *ss, PRUint16 ex_type);
extern void ssl3_SetSIDSessionTicket(sslSessionID *sid,
- /*in/out*/ 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);
+ /*in/out*/ NewSessionTicket *session_ticket);
+SECStatus ssl3_EncodeSessionTicket(sslSocket *ss,
+ const NewSessionTicket *ticket_input,
+ SECItem *ticket_data);
+extern PRBool ssl_GetSessionTicketKeys(SECKEYPrivateKey *svrPrivKey,
+ SECKEYPublicKey *svrPubKey, void *pwArg,
+ unsigned char *keyName, PK11SymKey **aesKey,
+ PK11SymKey **macKey);
+extern SECStatus ssl3_SessionTicketShutdown(void *appData, void *nssData);
/* 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 (0x0101)
+#define TLS_EX_SESS_TICKET_LIFETIME_HINT (2 * 24 * 60 * 60) /* 2 days */
+#define TLS_EX_SESS_TICKET_VERSION (0x0103)
-extern SECStatus ssl3_ValidateNextProtoNego(const unsigned char* data,
- unsigned int length);
+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);
@@ -1853,30 +1702,18 @@ extern void ssl_FreePRSocket(PRFileDesc *fd);
* 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);
+ssl_GetWrappingKey(PRInt32 symWrapMechIndex, SSLAuthType authType,
+ 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
+ * 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
@@ -1893,42 +1730,101 @@ 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_FreeHandshakeMessage(DTLSQueuedMessage *msg);
extern void dtls_FreeHandshakeMessages(PRCList *lst);
extern SECStatus dtls_HandleHandshake(sslSocket *ss, sslBuffer *origBuf);
extern SECStatus dtls_HandleHelloVerifyRequest(sslSocket *ss,
- SSL3Opaque *b, PRUint32 length);
+ SSL3Opaque *b, PRUint32 length);
extern SECStatus dtls_StageHandshakeMessage(sslSocket *ss);
extern SECStatus dtls_QueueMessage(sslSocket *ss, SSL3ContentType type,
- const SSL3Opaque *pIn, PRInt32 nIn);
+ 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);
+SECStatus ssl3_DisableNonDTLSSuites(sslSocket *ss);
+extern SECStatus dtls_StartHolddownTimer(sslSocket *ss);
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 int dtls_RecordGetRecvd(const DTLSRecvdRecords *records,
+ sslSequenceNumber seq);
+extern void dtls_RecordSetRecvd(DTLSRecvdRecords *records,
+ sslSequenceNumber seq);
extern void dtls_RehandshakeCleanup(sslSocket *ss);
extern SSL3ProtocolVersion
dtls_TLSVersionToDTLSVersion(SSL3ProtocolVersion tlsv);
extern SSL3ProtocolVersion
dtls_DTLSVersionToTLSVersion(SSL3ProtocolVersion dtlsv);
+extern PRBool dtls_IsRelevant(sslSocket *ss, const SSL3Ciphertext *cText,
+ PRBool *sameEpoch, PRUint64 *seqNum);
+extern SECStatus dtls_MaybeRetransmitHandshake(sslSocket *ss,
+ const SSL3Ciphertext *cText,
+ PRBool sameEpoch);
+
+CK_MECHANISM_TYPE ssl3_Alg2Mech(SSLCipherAlgorithm calg);
+SECStatus ssl3_NegotiateCipherSuite(sslSocket *ss, const SECItem *suites,
+ PRBool initHashes);
+SECStatus ssl3_InitHandshakeHashes(sslSocket *ss);
+SECStatus ssl3_ServerCallSNICallback(sslSocket *ss);
+SECStatus ssl3_SetupPendingCipherSpec(sslSocket *ss);
+SECStatus ssl3_FlushHandshake(sslSocket *ss, PRInt32 flags);
+SECStatus ssl3_CompleteHandleCertificate(sslSocket *ss,
+ SSL3Opaque *b, PRUint32 length);
+void ssl3_SendAlertForCertError(sslSocket *ss, PRErrorCode errCode);
+SECStatus ssl3_HandleNoCertificate(sslSocket *ss);
+SECStatus ssl3_SendEmptyCertificate(sslSocket *ss);
+void ssl3_CleanupPeerCerts(sslSocket *ss);
+SECStatus ssl3_SendCertificateStatus(sslSocket *ss);
+SECStatus ssl3_AuthCertificate(sslSocket *ss);
+SECStatus ssl_ReadCertificateStatus(sslSocket *ss, SSL3Opaque *b,
+ PRUint32 length);
+SECStatus ssl3_EncodeSigAlgs(const sslSocket *ss, PRUint8 *buf,
+ unsigned maxLen, PRUint32 *len);
+void ssl3_GetCertificateRequestCAs(sslSocket *ss, int *calenp, SECItem **namesp,
+ int *nnamesp);
+SECStatus ssl3_ParseCertificateRequestCAs(sslSocket *ss, SSL3Opaque **b,
+ PRUint32 *length, PLArenaPool *arena,
+ CERTDistNames *ca_list);
+SECStatus ssl3_CompleteHandleCertificateRequest(
+ sslSocket *ss, const SSLSignatureScheme *signatureSchemes,
+ unsigned int signatureSchemeCount, CERTDistNames *ca_list);
+SECStatus ssl3_SendServerHello(sslSocket *ss);
+SECStatus ssl3_ComputeHandshakeHashes(sslSocket *ss,
+ ssl3CipherSpec *spec,
+ SSL3Hashes *hashes,
+ PRUint32 sender);
+SECStatus ssl_CreateECDHEphemeralKeyPair(const sslSocket *ss,
+ const sslNamedGroupDef *ecGroup,
+ sslEphemeralKeyPair **keyPair);
+SECStatus ssl_CreateStaticECDHEKey(sslSocket *ss,
+ const sslNamedGroupDef *ecGroup);
+SECStatus ssl3_FlushHandshake(sslSocket *ss, PRInt32 flags);
+PK11SymKey *ssl3_GetWrappingKey(sslSocket *ss,
+ PK11SlotInfo *masterSecretSlot,
+ const sslServerCert *serverCert,
+ CK_MECHANISM_TYPE masterWrapMech,
+ void *pwArg);
+SECStatus ssl3_FillInCachedSID(sslSocket *ss, sslSessionID *sid);
+const ssl3CipherSuiteDef *ssl_LookupCipherSuiteDef(ssl3CipherSuite suite);
+const ssl3BulkCipherDef *
+ssl_GetBulkCipherDef(const ssl3CipherSuiteDef *cipher_def);
+SECStatus ssl3_SelectServerCert(sslSocket *ss);
+SECStatus ssl_PickSignatureScheme(sslSocket *ss,
+ SECKEYPublicKey *pubKey,
+ SECKEYPrivateKey *privKey,
+ const SSLSignatureScheme *peerSchemes,
+ unsigned int peerSchemeCount,
+ PRBool requireSha1);
+SECOidTag ssl3_HashTypeToOID(SSLHashType hashType);
+SSLHashType ssl_SignatureSchemeToHashType(SSLSignatureScheme scheme);
+KeyType ssl_SignatureSchemeToKeyType(SSLSignatureScheme scheme);
+
+SECStatus ssl3_SetCipherSuite(sslSocket *ss, ssl3CipherSuite chosenSuite,
+ PRBool initHashes);
+
+/* Pull in TLS 1.3 functions */
+#include "tls13con.h"
/********************** misc calls *********************/
@@ -1940,19 +1836,19 @@ extern int ssl_MapLowLevelError(int hiLevelError);
extern PRUint32 ssl_Time(void);
-extern void SSL_AtomicIncrementLong(long * x);
+extern void SSL_AtomicIncrementLong(long *x);
+
+SECStatus ssl3_ApplyNSSPolicy(void);
-SECStatus SSL_DisableDefaultExportCipherSuites(void);
-SECStatus SSL_DisableExportCipherSuites(PRFileDesc * fd);
-PRBool SSL_IsExportCipherSuite(PRUint16 cipherSuite);
+extern HASH_HashType
+ssl3_GetTls12HashType(sslSocket *ss);
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);
-extern SECOidTag
-ssl3_TLSHashAlgorithmToOID(SSLHashType hashFunc);
+ unsigned char *out, unsigned int outLen,
+ HASH_HashType tls12HashType);
#ifdef TRACE
#define SSL_TRACE(msg) ssl_Trace msg
diff --git a/nss/lib/ssl/sslinfo.c b/nss/lib/ssl/sslinfo.c
index 216ab0f..665109d 100644
--- a/nss/lib/ssl/sslinfo.c
+++ b/nss/lib/ssl/sslinfo.c
@@ -1,42 +1,47 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.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 "ssl.h"
#include "sslimpl.h"
#include "sslproto.h"
+#include "tls13hkdf.h"
static const char *
ssl_GetCompressionMethodName(SSLCompressionMethod compression)
{
switch (compression) {
- case ssl_compression_null:
- return "NULL";
+ case ssl_compression_null:
+ return "NULL";
#ifdef NSS_ENABLE_ZLIB
- case ssl_compression_deflate:
- return "DEFLATE";
+ case ssl_compression_deflate:
+ return "DEFLATE";
#endif
- default:
- return "???";
+ default:
+ return "???";
}
}
-SECStatus
+SECStatus
SSL_GetChannelInfo(PRFileDesc *fd, SSLChannelInfo *info, PRUintn len)
{
- sslSocket * ss;
- SSLChannelInfo inf;
- sslSessionID * sid;
+ sslSocket *ss;
+ SSLChannelInfo inf;
+ sslSessionID *sid;
- if (!info || len < sizeof inf.length) {
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- return SECFailure;
+ /* Check if we can properly return the length of data written and that
+ * we're not asked to return more information than we know how to provide.
+ */
+ if (!info || len < sizeof inf.length || len > sizeof inf) {
+ 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;
+ SSL_DBG(("%d: SSL[%d]: bad socket in SSL_GetChannelInfo",
+ SSL_GETPID(), fd));
+ return SECFailure;
}
memset(&inf, 0, sizeof inf);
@@ -44,42 +49,61 @@ SSL_GetChannelInfo(PRFileDesc *fd, SSLChannelInfo *info, PRUintn len)
if (ss->opt.useSecurity && ss->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;
- inf.extendedMasterSecretUsed = sid->u.ssl3.keys.extendedMasterSecretUsed;
-
- 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);
- }
- }
+ inf.protocolVersion = ss->version;
+ inf.authKeyBits = ss->sec.authKeyBits;
+ inf.keaKeyBits = ss->sec.keaKeyBits;
+ if (ss->ssl3.initialized) {
+ SSLCipherSuiteInfo cinfo;
+ SECStatus rv;
+
+ 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);
+
+ /* Fill in the cipher details from the cipher suite. */
+ rv = SSL_GetCipherSuiteInfo(inf.cipherSuite,
+ &cinfo, sizeof(cinfo));
+ if (rv != SECSuccess) {
+ return SECFailure; /* Error code already set. */
+ }
+ inf.symCipher = cinfo.symCipher;
+ inf.macAlgorithm = cinfo.macAlgorithm;
+ /* Get these fromm |ss->sec| because that is accurate
+ * even with TLS 1.3 disaggregated cipher suites. */
+ inf.keaType = ss->sec.keaType;
+ inf.keaGroup = ss->sec.keaGroup ? ss->sec.keaGroup->name : ssl_grp_none;
+ inf.keaKeyBits = ss->sec.keaKeyBits;
+ inf.authType = ss->sec.authType;
+ inf.authKeyBits = ss->sec.authKeyBits;
+ inf.signatureScheme = ss->sec.signatureScheme;
+ }
+ if (sid) {
+ unsigned int sidLen;
+
+ inf.creationTime = sid->creationTime;
+ inf.lastAccessTime = sid->lastAccessTime;
+ inf.expirationTime = sid->expirationTime;
+ inf.extendedMasterSecretUsed =
+ (ss->version >= SSL_LIBRARY_VERSION_TLS_1_3 ||
+ sid->u.ssl3.keys.extendedMasterSecretUsed)
+ ? PR_TRUE
+ : PR_FALSE;
+
+ inf.earlyDataAccepted =
+ (ss->ssl3.hs.zeroRttState == ssl_0rtt_accepted ||
+ ss->ssl3.hs.zeroRttState == ssl_0rtt_done);
+ 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);
@@ -95,7 +119,10 @@ SSL_GetPreliminaryChannelInfo(PRFileDesc *fd,
sslSocket *ss;
SSLPreliminaryChannelInfo inf;
- if (!info || len < sizeof inf.length) {
+ /* Check if we can properly return the length of data written and that
+ * we're not asked to return more information than we know how to provide.
+ */
+ if (!info || len < sizeof inf.length || len > sizeof inf) {
PORT_SetError(SEC_ERROR_INVALID_ARGS);
return SECFailure;
}
@@ -107,11 +134,6 @@ SSL_GetPreliminaryChannelInfo(PRFileDesc *fd,
return SECFailure;
}
- if (ss->version < SSL_LIBRARY_VERSION_3_0) {
- PORT_SetError(SSL_ERROR_FEATURE_NOT_SUPPORTED_FOR_VERSION);
- return SECFailure;
- }
-
memset(&inf, 0, sizeof(inf));
inf.length = PR_MIN(sizeof(inf), len);
@@ -123,212 +145,197 @@ SSL_GetPreliminaryChannelInfo(PRFileDesc *fd,
return SECSuccess;
}
+/* name */
+#define CS_(x) x, #x
+#define CS(x) CS_(TLS_##x)
-#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
+/* legacy values for authAlgorithm */
+#define S_DSA "DSA", ssl_auth_dsa
+/* S_RSA is incorrect for signature-based suites */
+/* ECDH suites incorrectly report S_RSA or S_ECDSA */
+#define S_RSA "RSA", ssl_auth_rsa_decrypt
#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 S_PSK "PSK", ssl_auth_psk
+#define S_ANY "TLS 1.3", ssl_auth_tls13_any
+
+/* real authentication algorithm */
+#define A_DSA ssl_auth_dsa
+#define A_RSAD ssl_auth_rsa_decrypt
+#define A_RSAS ssl_auth_rsa_sign
+#define A_ECDSA ssl_auth_ecdsa
+#define A_ECDH_R ssl_auth_ecdh_rsa
+#define A_ECDH_E ssl_auth_ecdh_ecdsa
+#define A_PSK ssl_auth_psk
+/* Report ssl_auth_null for export suites that can't decide between
+ * ssl_auth_rsa_sign and ssl_auth_rsa_decrypt. */
+#define A_EXP ssl_auth_null
+#define A_ANY ssl_auth_tls13_any
+
+/* key exchange */
+#define K_DHE "DHE", ssl_kea_dh
+#define K_RSA "RSA", ssl_kea_rsa
+#define K_KEA "KEA", ssl_kea_kea
+#define K_ECDH "ECDH", ssl_kea_ecdh
+#define K_ECDHE "ECDHE", ssl_kea_ecdh
+#define K_ECDHE_PSK "ECDHE-PSK", ssl_kea_ecdh_psk
+#define K_DHE_PSK "DHE-PSK", ssl_kea_dh_psk
+#define K_ANY "TLS 1.3", ssl_kea_tls13_any
+
+/* record protection cipher */
+#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 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 C_AESGCM "AES-GCM", calg_aes_gcm
-
-#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 C_CHACHA20 "CHACHA20POLY1305", calg_chacha20
+
+/* "block cipher" sizes */
+#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
+
+/* "mac algorithm" and size */
#define M_AEAD_128 "AEAD", ssl_mac_aead, 128
+#define M_SHA384 "SHA384", ssl_hmac_sha384, 384
#define M_SHA256 "SHA256", ssl_hmac_sha256, 256
-#define M_SHA "SHA1", ssl_mac_sha, 160
-#define M_MD5 "MD5", ssl_mac_md5, 128
-#define M_NULL "NULL", ssl_mac_null, 0
+#define M_SHA "SHA1", ssl_mac_sha, 160
+#define M_MD5 "MD5", ssl_mac_md5, 128
+#define M_NULL "NULL", ssl_mac_null, 0
+
+/* flags: FIPS, exportable, nonstandard, reserved */
+#define F_FIPS_STD 1, 0, 0, 0
+#define F_FIPS_NSTD 1, 0, 1, 0
+#define F_NFIPS_STD 0, 0, 0, 0
+#define F_NFIPS_NSTD 0, 0, 1, 0 /* i.e., trash */
+#define F_EXPORT 0, 1, 0, 0 /* i.e., trash */
static const SSLCipherSuiteInfo suiteInfo[] = {
-/* <------ Cipher suite --------------------> <auth> <KEA> <bulk cipher> <MAC> <FIPS> */
-{0,CS(TLS_RSA_WITH_AES_128_GCM_SHA256), S_RSA, K_RSA, C_AESGCM, B_128, M_AEAD_128, 1, 0, 0, },
-
-{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_SHA256), S_RSA, K_DHE, C_AES, B_256, M_SHA256, 1, 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_DHE_DSS_WITH_AES_256_CBC_SHA256), S_DSA, K_DHE, C_AES, B_256, M_SHA256, 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_SHA256), S_RSA, K_RSA, C_AES, B_256, M_SHA256, 1, 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_SHA256), S_RSA, K_DHE, C_AES, B_128, M_SHA256, 1, 0, 0, },
-{0,CS(TLS_DHE_RSA_WITH_AES_128_GCM_SHA256), S_RSA, K_DHE, C_AESGCM, B_128, M_AEAD_128, 1, 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_GCM_SHA256), S_DSA, K_DHE, C_AESGCM, B_128, M_AEAD_128, 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_DHE_DSS_WITH_AES_128_CBC_SHA256), S_DSA, K_DHE, C_AES, B_128, M_SHA256, 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(TLS_RSA_WITH_RC4_128_SHA), S_RSA, K_RSA, C_RC4, B_128, M_SHA, 0, 0, 0, },
-{0,CS(TLS_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_SHA256), S_RSA, K_RSA, C_AES, B_128, M_SHA256, 1, 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(TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA), S_RSA, K_DHE, C_3DES,B_3DES,M_SHA, 1, 0, 0, },
-{0,CS(TLS_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(TLS_RSA_WITH_3DES_EDE_CBC_SHA), S_RSA, K_RSA, C_3DES,B_3DES,M_SHA, 1, 0, 0, },
-
-{0,CS(TLS_DHE_RSA_WITH_DES_CBC_SHA), S_RSA, K_DHE, C_DES, B_DES, M_SHA, 0, 0, 0, },
-{0,CS(TLS_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(TLS_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(TLS_RSA_EXPORT_WITH_RC4_40_MD5), S_RSA, K_RSA, C_RC4, B_40, M_MD5, 0, 1, 0, },
-{0,CS(TLS_RSA_EXPORT_WITH_RC2_CBC_40_MD5), S_RSA, K_RSA, C_RC2, B_40, M_MD5, 0, 1, 0, },
-{0,CS(TLS_RSA_WITH_NULL_SHA256), S_RSA, K_RSA, C_NULL,B_0, M_SHA256, 0, 1, 0, },
-{0,CS(TLS_RSA_WITH_NULL_SHA), S_RSA, K_RSA, C_NULL,B_0, M_SHA, 0, 1, 0, },
-{0,CS(TLS_RSA_WITH_NULL_MD5), S_RSA, K_RSA, C_NULL,B_0, M_MD5, 0, 1, 0, },
-
-#ifndef NSS_DISABLE_ECC
-/* ECC cipher suites */
-{0,CS(TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256), S_RSA, K_ECDHE, C_AESGCM, B_128, M_AEAD_128, 1, 0, 0, },
-{0,CS(TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256), S_ECDSA, K_ECDHE, C_AESGCM, B_128, M_AEAD_128, 1, 0, 0, },
-
-{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_128_CBC_SHA256), S_ECDSA, K_ECDHE, C_AES, B_128, M_SHA256, 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_128_CBC_SHA256), S_RSA, K_ECDHE, C_AES, B_128, M_SHA256, 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_DISABLE_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, }
+ /* <------ Cipher suite --------------------> <auth> <KEA> <bulk cipher> <MAC> <FIPS> */
+ { 0, CS_(TLS_AES_128_GCM_SHA256), S_ANY, K_ANY, C_AESGCM, B_128, M_AEAD_128, F_FIPS_STD, A_ANY },
+ { 0, CS_(TLS_CHACHA20_POLY1305_SHA256), S_ANY, K_ANY, C_CHACHA20, B_256, M_AEAD_128, F_NFIPS_STD, A_ANY },
+ { 0, CS_(TLS_AES_256_GCM_SHA384), S_ANY, K_ANY, C_AESGCM, B_256, M_AEAD_128, F_NFIPS_STD, A_ANY },
+
+ { 0, CS(RSA_WITH_AES_128_GCM_SHA256), S_RSA, K_RSA, C_AESGCM, B_128, M_AEAD_128, F_FIPS_STD, A_RSAD },
+ { 0, CS(DHE_RSA_WITH_CHACHA20_POLY1305_SHA256), S_RSA, K_DHE, C_CHACHA20, B_256, M_AEAD_128, F_NFIPS_STD, A_RSAS },
+
+ { 0, CS(DHE_RSA_WITH_CAMELLIA_256_CBC_SHA), S_RSA, K_DHE, C_CAMELLIA, B_256, M_SHA, F_NFIPS_STD, A_RSAS },
+ { 0, CS(DHE_DSS_WITH_CAMELLIA_256_CBC_SHA), S_DSA, K_DHE, C_CAMELLIA, B_256, M_SHA, F_NFIPS_STD, A_DSA },
+ { 0, CS(DHE_RSA_WITH_AES_256_CBC_SHA256), S_RSA, K_DHE, C_AES, B_256, M_SHA256, F_FIPS_STD, A_RSAS },
+ { 0, CS(DHE_RSA_WITH_AES_256_CBC_SHA), S_RSA, K_DHE, C_AES, B_256, M_SHA, F_FIPS_STD, A_RSAS },
+ { 0, CS(DHE_DSS_WITH_AES_256_CBC_SHA), S_DSA, K_DHE, C_AES, B_256, M_SHA, F_FIPS_STD, A_DSA },
+ { 0, CS(DHE_DSS_WITH_AES_256_CBC_SHA256), S_DSA, K_DHE, C_AES, B_256, M_SHA256, F_FIPS_STD, A_DSA },
+ { 0, CS(RSA_WITH_CAMELLIA_256_CBC_SHA), S_RSA, K_RSA, C_CAMELLIA, B_256, M_SHA, F_NFIPS_STD, A_RSAD },
+ { 0, CS(RSA_WITH_AES_256_CBC_SHA256), S_RSA, K_RSA, C_AES, B_256, M_SHA256, F_FIPS_STD, A_RSAD },
+ { 0, CS(RSA_WITH_AES_256_CBC_SHA), S_RSA, K_RSA, C_AES, B_256, M_SHA, F_FIPS_STD, A_RSAD },
+
+ { 0, CS(DHE_RSA_WITH_CAMELLIA_128_CBC_SHA), S_RSA, K_DHE, C_CAMELLIA, B_128, M_SHA, F_NFIPS_STD, A_RSAS },
+ { 0, CS(DHE_DSS_WITH_CAMELLIA_128_CBC_SHA), S_DSA, K_DHE, C_CAMELLIA, B_128, M_SHA, F_NFIPS_STD, A_DSA },
+ { 0, CS(DHE_DSS_WITH_RC4_128_SHA), S_DSA, K_DHE, C_RC4, B_128, M_SHA, F_NFIPS_STD, A_DSA },
+ { 0, CS(DHE_RSA_WITH_AES_128_CBC_SHA256), S_RSA, K_DHE, C_AES, B_128, M_SHA256, F_FIPS_STD, A_RSAS },
+ { 0, CS(DHE_RSA_WITH_AES_128_GCM_SHA256), S_RSA, K_DHE, C_AESGCM, B_128, M_AEAD_128, F_FIPS_STD, A_RSAS },
+ { 0, CS(DHE_RSA_WITH_AES_128_CBC_SHA), S_RSA, K_DHE, C_AES, B_128, M_SHA, F_FIPS_STD, A_RSAS },
+ { 0, CS(DHE_DSS_WITH_AES_128_GCM_SHA256), S_DSA, K_DHE, C_AESGCM, B_128, M_AEAD_128, F_FIPS_STD, A_DSA },
+ { 0, CS(DHE_DSS_WITH_AES_128_CBC_SHA), S_DSA, K_DHE, C_AES, B_128, M_SHA, F_FIPS_STD, A_DSA },
+ { 0, CS(DHE_DSS_WITH_AES_128_CBC_SHA256), S_DSA, K_DHE, C_AES, B_128, M_SHA256, F_FIPS_STD, A_DSA },
+ { 0, CS(RSA_WITH_SEED_CBC_SHA), S_RSA, K_RSA, C_SEED, B_128, M_SHA, F_FIPS_STD, A_RSAD },
+ { 0, CS(RSA_WITH_CAMELLIA_128_CBC_SHA), S_RSA, K_RSA, C_CAMELLIA, B_128, M_SHA, F_NFIPS_STD, A_RSAD },
+ { 0, CS(RSA_WITH_RC4_128_SHA), S_RSA, K_RSA, C_RC4, B_128, M_SHA, F_NFIPS_STD, A_RSAD },
+ { 0, CS(RSA_WITH_RC4_128_MD5), S_RSA, K_RSA, C_RC4, B_128, M_MD5, F_NFIPS_STD, A_RSAD },
+ { 0, CS(RSA_WITH_AES_128_CBC_SHA256), S_RSA, K_RSA, C_AES, B_128, M_SHA256, F_FIPS_STD, A_RSAD },
+ { 0, CS(RSA_WITH_AES_128_CBC_SHA), S_RSA, K_RSA, C_AES, B_128, M_SHA, F_FIPS_STD, A_RSAD },
+
+ { 0, CS(DHE_RSA_WITH_3DES_EDE_CBC_SHA), S_RSA, K_DHE, C_3DES, B_3DES, M_SHA, F_FIPS_STD, A_RSAS },
+ { 0, CS(DHE_DSS_WITH_3DES_EDE_CBC_SHA), S_DSA, K_DHE, C_3DES, B_3DES, M_SHA, F_FIPS_STD, A_DSA },
+ { 0, CS(RSA_WITH_3DES_EDE_CBC_SHA), S_RSA, K_RSA, C_3DES, B_3DES, M_SHA, F_FIPS_STD, A_RSAD },
+
+ { 0, CS(DHE_RSA_WITH_DES_CBC_SHA), S_RSA, K_DHE, C_DES, B_DES, M_SHA, F_NFIPS_STD, A_RSAS },
+ { 0, CS(DHE_DSS_WITH_DES_CBC_SHA), S_DSA, K_DHE, C_DES, B_DES, M_SHA, F_NFIPS_STD, A_DSA },
+ { 0, CS(RSA_WITH_DES_CBC_SHA), S_RSA, K_RSA, C_DES, B_DES, M_SHA, F_NFIPS_STD, A_RSAD },
+
+ { 0, CS(RSA_WITH_NULL_SHA256), S_RSA, K_RSA, C_NULL, B_0, M_SHA256, F_EXPORT, A_RSAD },
+ { 0, CS(RSA_WITH_NULL_SHA), S_RSA, K_RSA, C_NULL, B_0, M_SHA, F_EXPORT, A_RSAD },
+ { 0, CS(RSA_WITH_NULL_MD5), S_RSA, K_RSA, C_NULL, B_0, M_MD5, F_EXPORT, A_RSAD },
+
+ /* ECC cipher suites */
+ { 0, CS(ECDHE_RSA_WITH_AES_128_GCM_SHA256), S_RSA, K_ECDHE, C_AESGCM, B_128, M_AEAD_128, F_FIPS_STD, A_RSAS },
+ { 0, CS(ECDHE_ECDSA_WITH_AES_128_GCM_SHA256), S_ECDSA, K_ECDHE, C_AESGCM, B_128, M_AEAD_128, F_FIPS_STD, A_ECDSA },
+ { 0, CS(ECDH_ECDSA_WITH_NULL_SHA), S_ECDSA, K_ECDH, C_NULL, B_0, M_SHA, F_NFIPS_STD, A_ECDH_E },
+ { 0, CS(ECDH_ECDSA_WITH_RC4_128_SHA), S_ECDSA, K_ECDH, C_RC4, B_128, M_SHA, F_NFIPS_STD, A_ECDH_E },
+ { 0, CS(ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA), S_ECDSA, K_ECDH, C_3DES, B_3DES, M_SHA, F_FIPS_STD, A_ECDH_E },
+ { 0, CS(ECDH_ECDSA_WITH_AES_128_CBC_SHA), S_ECDSA, K_ECDH, C_AES, B_128, M_SHA, F_FIPS_STD, A_ECDH_E },
+ { 0, CS(ECDH_ECDSA_WITH_AES_256_CBC_SHA), S_ECDSA, K_ECDH, C_AES, B_256, M_SHA, F_FIPS_STD, A_ECDH_E },
+
+ { 0, CS(ECDHE_ECDSA_WITH_NULL_SHA), S_ECDSA, K_ECDHE, C_NULL, B_0, M_SHA, F_NFIPS_STD, A_ECDSA },
+ { 0, CS(ECDHE_ECDSA_WITH_RC4_128_SHA), S_ECDSA, K_ECDHE, C_RC4, B_128, M_SHA, F_NFIPS_STD, A_ECDSA },
+ { 0, CS(ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA), S_ECDSA, K_ECDHE, C_3DES, B_3DES, M_SHA, F_FIPS_STD, A_ECDSA },
+ { 0, CS(ECDHE_ECDSA_WITH_AES_128_CBC_SHA), S_ECDSA, K_ECDHE, C_AES, B_128, M_SHA, F_FIPS_STD, A_ECDSA },
+ { 0, CS(ECDHE_ECDSA_WITH_AES_128_CBC_SHA256), S_ECDSA, K_ECDHE, C_AES, B_128, M_SHA256, F_FIPS_STD, A_ECDSA },
+ { 0, CS(ECDHE_ECDSA_WITH_AES_256_CBC_SHA), S_ECDSA, K_ECDHE, C_AES, B_256, M_SHA, F_FIPS_STD, A_ECDSA },
+ { 0, CS(ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256), S_ECDSA, K_ECDHE, C_CHACHA20, B_256, M_AEAD_128, F_NFIPS_STD, A_ECDSA },
+
+ { 0, CS(ECDH_RSA_WITH_NULL_SHA), S_RSA, K_ECDH, C_NULL, B_0, M_SHA, F_NFIPS_STD, A_ECDH_R },
+ { 0, CS(ECDH_RSA_WITH_RC4_128_SHA), S_RSA, K_ECDH, C_RC4, B_128, M_SHA, F_NFIPS_STD, A_ECDH_R },
+ { 0, CS(ECDH_RSA_WITH_3DES_EDE_CBC_SHA), S_RSA, K_ECDH, C_3DES, B_3DES, M_SHA, F_FIPS_STD, A_ECDH_R },
+ { 0, CS(ECDH_RSA_WITH_AES_128_CBC_SHA), S_RSA, K_ECDH, C_AES, B_128, M_SHA, F_FIPS_STD, A_ECDH_R },
+ { 0, CS(ECDH_RSA_WITH_AES_256_CBC_SHA), S_RSA, K_ECDH, C_AES, B_256, M_SHA, F_FIPS_STD, A_ECDH_R },
+
+ { 0, CS(ECDHE_RSA_WITH_NULL_SHA), S_RSA, K_ECDHE, C_NULL, B_0, M_SHA, F_NFIPS_STD, A_RSAS },
+ { 0, CS(ECDHE_RSA_WITH_RC4_128_SHA), S_RSA, K_ECDHE, C_RC4, B_128, M_SHA, F_NFIPS_STD, A_RSAS },
+ { 0, CS(ECDHE_RSA_WITH_3DES_EDE_CBC_SHA), S_RSA, K_ECDHE, C_3DES, B_3DES, M_SHA, F_FIPS_STD, A_RSAS },
+ { 0, CS(ECDHE_RSA_WITH_AES_128_CBC_SHA), S_RSA, K_ECDHE, C_AES, B_128, M_SHA, F_FIPS_STD, A_RSAS },
+ { 0, CS(ECDHE_RSA_WITH_AES_128_CBC_SHA256), S_RSA, K_ECDHE, C_AES, B_128, M_SHA256, F_FIPS_STD, A_RSAS },
+ { 0, CS(ECDHE_RSA_WITH_AES_256_CBC_SHA), S_RSA, K_ECDHE, C_AES, B_256, M_SHA, F_FIPS_STD, A_RSAS },
+ { 0, CS(ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256), S_RSA, K_ECDHE, C_CHACHA20, B_256, M_AEAD_128, F_NFIPS_STD, A_RSAS },
+ { 0, CS(ECDHE_RSA_WITH_AES_256_CBC_SHA384), S_RSA, K_ECDHE, C_AES, B_256, M_SHA384, F_FIPS_STD, A_RSAS },
+ { 0, CS(ECDHE_ECDSA_WITH_AES_256_CBC_SHA384), S_ECDSA, K_ECDHE, C_AES, B_256, M_SHA384, F_FIPS_STD, A_ECDSA },
+ { 0, CS(ECDHE_ECDSA_WITH_AES_256_GCM_SHA384), S_ECDSA, K_ECDHE, C_AESGCM, B_256, M_AEAD_128, F_FIPS_STD, A_ECDSA },
+ { 0, CS(ECDHE_RSA_WITH_AES_256_GCM_SHA384), S_RSA, K_ECDHE, C_AESGCM, B_256, M_AEAD_128, F_FIPS_STD, A_RSAS },
+
+ { 0, CS(DHE_DSS_WITH_AES_256_GCM_SHA384), S_DSA, K_DHE, C_AESGCM, B_256, M_AEAD_128, F_FIPS_STD, A_DSA },
+ { 0, CS(DHE_RSA_WITH_AES_256_GCM_SHA384), S_RSA, K_DHE, C_AESGCM, B_256, M_AEAD_128, F_FIPS_STD, A_RSAS },
+ { 0, CS(RSA_WITH_AES_256_GCM_SHA384), S_RSA, K_RSA, C_AESGCM, B_256, M_AEAD_128, F_FIPS_STD, A_RSAD },
};
#define NUM_SUITEINFOS ((sizeof suiteInfo) / (sizeof suiteInfo[0]))
-
-SECStatus SSL_GetCipherSuiteInfo(PRUint16 cipherSuite,
- SSLCipherSuiteInfo *info, PRUintn len)
+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;
+ /* Check if we can properly return the length of data written and that
+ * we're not asked to return more information than we know how to provide.
+ */
+ if (!info || len < sizeof suiteInfo[0].length ||
+ len > sizeof suiteInfo[0]) {
+ PORT_SetError(SEC_ERROR_INVALID_ARGS);
+ return SECFailure;
}
+ len = PR_MIN(len, sizeof suiteInfo[0]);
for (i = 0; i < NUM_SUITEINFOS; i++) {
- if (suiteInfo[i].cipherSuite == cipherSuite) {
- memcpy(info, &suiteInfo[i], len);
- info->length = len;
- return SECSuccess;
- }
+ 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;
-
- for (i = 0; i < NUM_SUITEINFOS; ++i, ++pInfo) {
- if (pInfo->isExportable) {
- PORT_CheckSuccess(SSL_CipherPrefSetDefault(pInfo->cipherSuite, PR_FALSE));
- }
- }
- 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;
-
- for (i = 0; i < NUM_SUITEINFOS; ++i, ++pInfo) {
- if (pInfo->isExportable) {
- PORT_CheckSuccess(SSL_CipherPrefSet(fd, pInfo->cipherSuite, PR_FALSE));
- }
- }
- 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*
+SECItem *
SSL_GetNegotiatedHostInfo(PRFileDesc *fd)
{
SECItem *sniName = NULL;
@@ -337,9 +344,9 @@ SSL_GetNegotiatedHostInfo(PRFileDesc *fd)
ss = ssl_FindSocket(fd);
if (!ss) {
- SSL_DBG(("%d: SSL[%d]: bad socket in SSL_GetNegotiatedHostInfo",
- SSL_GETPID(), fd));
- return NULL;
+ SSL_DBG(("%d: SSL[%d]: bad socket in SSL_GetNegotiatedHostInfo",
+ SSL_GETPID(), fd));
+ return NULL;
}
if (ss->sec.isServer) {
@@ -347,14 +354,14 @@ SSL_GetNegotiatedHostInfo(PRFileDesc *fd)
ss->ssl3.initialized) { /* TLS */
SECItem *crsName;
ssl_GetSpecReadLock(ss); /*********************************/
- crsName = &ss->ssl3.cwSpec->srvVirtName;
+ crsName = &ss->ssl3.hs.srvVirtName;
if (crsName->data) {
sniName = SECITEM_DupItem(crsName);
}
ssl_ReleaseSpecReadLock(ss); /*----------------------------*/
}
return sniName;
- }
+ }
name = SSL_RevealURL(fd);
if (name) {
sniName = PORT_ZNew(SECItem);
@@ -362,12 +369,30 @@ SSL_GetNegotiatedHostInfo(PRFileDesc *fd)
PORT_Free(name);
return NULL;
}
- sniName->data = (void*)name;
- sniName->len = PORT_Strlen(name);
+ sniName->data = (void *)name;
+ sniName->len = PORT_Strlen(name);
}
return sniName;
}
+static SECStatus
+tls13_Exporter(sslSocket *ss, PK11SymKey *secret,
+ const char *label, unsigned int labelLen,
+ const unsigned char *context, unsigned int contextLen,
+ unsigned char *out, unsigned int outLen)
+{
+ if (!secret) {
+ PORT_SetError(SEC_ERROR_INVALID_ARGS);
+ return SECFailure;
+ }
+
+ return tls13_HkdfExpandLabelRaw(secret,
+ tls13_GetHash(ss),
+ context, contextLen,
+ label, labelLen,
+ out, outLen);
+}
+
SECStatus
SSL_ExportKeyingMaterial(PRFileDesc *fd,
const char *label, unsigned int labelLen,
@@ -382,24 +407,32 @@ SSL_ExportKeyingMaterial(PRFileDesc *fd,
ss = ssl_FindSocket(fd);
if (!ss) {
- SSL_DBG(("%d: SSL[%d]: bad socket in ExportKeyingMaterial",
- SSL_GETPID(), fd));
- return SECFailure;
+ SSL_DBG(("%d: SSL[%d]: bad socket in ExportKeyingMaterial",
+ SSL_GETPID(), fd));
+ return SECFailure;
+ }
+
+ if (!label || !labelLen || !out || !outLen ||
+ (hasContext && (!context || !contextLen))) {
+ PORT_SetError(SEC_ERROR_INVALID_ARGS);
+ return SECFailure;
}
- if (ss->version < SSL_LIBRARY_VERSION_3_1_TLS) {
- PORT_SetError(SSL_ERROR_FEATURE_NOT_SUPPORTED_FOR_VERSION);
- return SECFailure;
+ if (ss->version >= SSL_LIBRARY_VERSION_TLS_1_3) {
+ return tls13_Exporter(ss, ss->ssl3.hs.exporterSecret,
+ label, labelLen,
+ context, hasContext ? contextLen : 0,
+ out, outLen);
}
/* construct PRF arguments */
valLen = SSL3_RANDOM_LENGTH * 2;
if (hasContext) {
- valLen += 2 /* PRUint16 length */ + contextLen;
+ valLen += 2 /* PRUint16 length */ + contextLen;
}
val = PORT_Alloc(valLen);
if (!val) {
- return SECFailure;
+ return SECFailure;
}
i = 0;
PORT_Memcpy(val + i, &ss->ssl3.hs.client_random.rand, SSL3_RANDOM_LENGTH);
@@ -407,10 +440,10 @@ SSL_ExportKeyingMaterial(PRFileDesc *fd,
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;
+ val[i++] = contextLen >> 8;
+ val[i++] = contextLen;
+ PORT_Memcpy(val + i, context, contextLen);
+ i += contextLen;
}
PORT_Assert(i == valLen);
@@ -419,14 +452,42 @@ SSL_ExportKeyingMaterial(PRFileDesc *fd,
*/
ssl_GetSpecReadLock(ss);
if (!ss->ssl3.cwSpec->master_secret && !ss->ssl3.cwSpec->msItem.len) {
- PORT_SetError(SSL_ERROR_HANDSHAKE_NOT_COMPLETED);
- rv = SECFailure;
+ PORT_SetError(SSL_ERROR_HANDSHAKE_NOT_COMPLETED);
+ rv = SECFailure;
} else {
- rv = ssl3_TLSPRFWithMasterSecret(ss->ssl3.cwSpec, label, labelLen, val,
- valLen, out, outLen);
+ HASH_HashType ht = ssl3_GetTls12HashType(ss);
+ rv = ssl3_TLSPRFWithMasterSecret(ss->ssl3.cwSpec, label, labelLen, val,
+ valLen, out, outLen, ht);
}
ssl_ReleaseSpecReadLock(ss);
PORT_ZFree(val, valLen);
return rv;
}
+
+SECStatus
+SSL_ExportEarlyKeyingMaterial(PRFileDesc *fd,
+ const char *label, unsigned int labelLen,
+ const unsigned char *context,
+ unsigned int contextLen,
+ unsigned char *out, unsigned int outLen)
+{
+ sslSocket *ss;
+
+ ss = ssl_FindSocket(fd);
+ if (!ss) {
+ SSL_DBG(("%d: SSL[%d]: bad socket in SSL_ExportEarlyKeyingMaterial",
+ SSL_GETPID(), fd));
+ return SECFailure;
+ }
+
+ if (!label || !labelLen || !out || !outLen ||
+ (!context && contextLen)) {
+ PORT_SetError(SEC_ERROR_INVALID_ARGS);
+ return SECFailure;
+ }
+
+ return tls13_Exporter(ss, ss->ssl3.hs.earlyExporterSecret,
+ label, labelLen, context, contextLen,
+ out, outLen);
+}
diff --git a/nss/lib/ssl/sslinit.c b/nss/lib/ssl/sslinit.c
index bb9df25..0f38c0b 100644
--- a/nss/lib/ssl/sslinit.c
+++ b/nss/lib/ssl/sslinit.c
@@ -11,23 +11,49 @@
#include "secerr.h"
#include "ssl.h"
#include "sslimpl.h"
+#include "sslproto.h"
-static int ssl_inited = 0;
+static int ssl_isInited = 0;
+static PRCallOnceType ssl_init = { 0 };
-SECStatus
-ssl_Init(void)
+PRStatus
+ssl_InitCallOnce(void *arg)
{
- if (!ssl_inited) {
- if (ssl_InitializePRErrorTable() != SECSuccess) {
- PORT_SetError(SEC_ERROR_NO_MEMORY);
- return (SECFailure);
- }
+ int *error = (int *)arg;
+ SECStatus rv;
+ rv = ssl_InitializePRErrorTable();
+ if (rv != SECSuccess) {
+ *error = SEC_ERROR_NO_MEMORY;
+ return PR_FAILURE;
+ }
#ifdef DEBUG
- ssl3_CheckCipherSuiteOrderConsistency();
+ ssl3_CheckCipherSuiteOrderConsistency();
#endif
- ssl_inited = 1;
+ rv = ssl3_ApplyNSSPolicy();
+ if (rv != SECSuccess) {
+ *error = PORT_GetError();
+ return PR_FAILURE;
+ }
+ return PR_SUCCESS;
+}
+
+SECStatus
+ssl_Init(void)
+{
+ PRStatus nrv;
+
+ /* short circuit test if we are already inited */
+ if (!ssl_isInited) {
+ int error;
+ /* only do this once at init time, block all others until we are done */
+ nrv = PR_CallOnceWithArg(&ssl_init, ssl_InitCallOnce, &error);
+ if (nrv != PR_SUCCESS) {
+ PORT_SetError(error);
+ return SECFailure;
+ }
+ ssl_isInited = 1;
}
return SECSuccess;
}
diff --git a/nss/lib/ssl/sslmutex.c b/nss/lib/ssl/sslmutex.c
index af683da..560a9e8 100644
--- a/nss/lib/ssl/sslmutex.c
+++ b/nss/lib/ssl/sslmutex.c
@@ -4,15 +4,16 @@
#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)
+#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)
+static SECStatus
+single_process_sslMutex_Init(sslMutex* pMutex)
{
- PR_ASSERT(pMutex != 0 && pMutex->u.sslLock == 0 );
-
+ PR_ASSERT(pMutex != 0 && pMutex->u.sslLock == 0);
+
pMutex->u.sslLock = PR_NewLock();
if (!pMutex->u.sslLock) {
return SECFailure;
@@ -20,10 +21,11 @@ static SECStatus single_process_sslMutex_Init(sslMutex* pMutex)
return SECSuccess;
}
-static SECStatus single_process_sslMutex_Destroy(sslMutex* pMutex)
+static SECStatus
+single_process_sslMutex_Destroy(sslMutex* pMutex)
{
PR_ASSERT(pMutex != 0);
- PR_ASSERT(pMutex->u.sslLock!= 0);
+ PR_ASSERT(pMutex->u.sslLock != 0);
if (!pMutex->u.sslLock) {
PORT_SetError(PR_INVALID_ARGUMENT_ERROR);
return SECFailure;
@@ -32,10 +34,11 @@ static SECStatus single_process_sslMutex_Destroy(sslMutex* pMutex)
return SECSuccess;
}
-static SECStatus single_process_sslMutex_Unlock(sslMutex* pMutex)
+static SECStatus
+single_process_sslMutex_Unlock(sslMutex* pMutex)
{
- PR_ASSERT(pMutex != 0 );
- PR_ASSERT(pMutex->u.sslLock !=0);
+ PR_ASSERT(pMutex != 0);
+ PR_ASSERT(pMutex->u.sslLock != 0);
if (!pMutex->u.sslLock) {
PORT_SetError(PR_INVALID_ARGUMENT_ERROR);
return SECFailure;
@@ -44,10 +47,11 @@ static SECStatus single_process_sslMutex_Unlock(sslMutex* pMutex)
return SECSuccess;
}
-static SECStatus single_process_sslMutex_Lock(sslMutex* pMutex)
+static SECStatus
+single_process_sslMutex_Lock(sslMutex* pMutex)
{
PR_ASSERT(pMutex != 0);
- PR_ASSERT(pMutex->u.sslLock != 0 );
+ PR_ASSERT(pMutex->u.sslLock != 0);
if (!pMutex->u.sslLock) {
PORT_SetError(PR_INVALID_ARGUMENT_ERROR);
return SECFailure;
@@ -66,7 +70,7 @@ static SECStatus single_process_sslMutex_Lock(sslMutex* pMutex)
#include "pratom.h"
#define SSL_MUTEX_MAGIC 0xfeedfd
-#define NONBLOCKING_POSTS 1 /* maybe this is faster */
+#define NONBLOCKING_POSTS 1 /* maybe this is faster */
#if NONBLOCKING_POSTS
@@ -82,20 +86,20 @@ setNonBlocking(int fd, int nonBlocking)
flags = fcntl(fd, F_GETFL, 0);
if (0 > flags)
- return flags;
+ return flags;
if (nonBlocking)
- flags |= FNONBLOCK;
+ flags |= FNONBLOCK;
else
- flags &= ~FNONBLOCK;
+ flags &= ~FNONBLOCK;
err = fcntl(fd, F_SETFL, flags);
return err;
}
#endif
SECStatus
-sslMutex_Init(sslMutex *pMutex, int shared)
+sslMutex_Init(sslMutex* pMutex, int shared)
{
- int err;
+ int err;
PR_ASSERT(pMutex);
pMutex->isMultiProcess = (PRBool)(shared != 0);
if (!shared) {
@@ -104,17 +108,17 @@ sslMutex_Init(sslMutex *pMutex, int shared)
pMutex->u.pipeStr.mPipes[0] = -1;
pMutex->u.pipeStr.mPipes[1] = -1;
pMutex->u.pipeStr.mPipes[2] = -1;
- pMutex->u.pipeStr.nWaiters = 0;
+ pMutex->u.pipeStr.nWaiters = 0;
err = pipe(pMutex->u.pipeStr.mPipes);
if (err) {
- nss_MD_unix_map_default_error(errno);
- return 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;
+ goto loser;
#endif
pMutex->u.pipeStr.mPipes[2] = SSL_MUTEX_MAGIC;
@@ -135,26 +139,26 @@ loser:
}
SECStatus
-sslMutex_Destroy(sslMutex *pMutex, PRBool processLocal)
+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;
+ PORT_SetError(PR_INVALID_ARGUMENT_ERROR);
+ return SECFailure;
}
close(pMutex->u.pipeStr.mPipes[0]);
close(pMutex->u.pipeStr.mPipes[1]);
if (processLocal) {
- return SECSuccess;
+ 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;
+ pMutex->u.pipeStr.nWaiters = 0;
return SECSuccess;
}
@@ -164,13 +168,12 @@ sslMutex_Destroy(sslMutex *pMutex, PRBool processLocal)
/* 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
+** 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)
+SECStatus
+sslMutex_Unlock(sslMutex* pMutex)
{
PRInt32 newValue;
if (PR_FALSE == pMutex->isMultiProcess) {
@@ -178,30 +181,30 @@ sslMutex_Unlock(sslMutex *pMutex)
}
if (pMutex->u.pipeStr.mPipes[2] != SSL_MUTEX_MAGIC) {
- PORT_SetError(PR_INVALID_ARGUMENT_ERROR);
- return SECFailure;
+ 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;
- }
+ 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)
+SECStatus
+sslMutex_Lock(sslMutex* pMutex)
{
PRInt32 newValue;
if (PR_FALSE == pMutex->isMultiProcess) {
@@ -209,88 +212,88 @@ sslMutex_Lock(sslMutex *pMutex)
}
if (pMutex->u.pipeStr.mPipes[2] != SSL_MUTEX_MAGIC) {
- PORT_SetError(PR_INVALID_ARGUMENT_ERROR);
- return SECFailure;
+ 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;
- }
+ 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
+/* 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.
+** So, we don't use them on those platforms.
*/
-SECStatus
-sslMutex_Unlock(sslMutex *pMutex)
+SECStatus
+sslMutex_Unlock(sslMutex* pMutex)
{
- int cc;
- char c = 1;
+ 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;
+ PORT_SetError(PR_INVALID_ARGUMENT_ERROR);
+ return SECFailure;
}
do {
- cc = write(pMutex->u.pipeStr.mPipes[1], &c, 1);
+ 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;
+ 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)
+SECStatus
+sslMutex_Lock(sslMutex* pMutex)
{
- int cc;
- char c;
+ 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;
+ PORT_SetError(PR_INVALID_ARGUMENT_ERROR);
+ return SECFailure;
}
do {
- cc = read(pMutex->u.pipeStr.mPipes[0], &c, 1);
+ 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;
+ if (cc < 0)
+ nss_MD_unix_map_default_error(errno);
+ else
+ PORT_SetError(PR_UNKNOWN_ERROR);
+ return SECFailure;
}
return SECSuccess;
@@ -314,7 +317,8 @@ sslMutex_Lock(sslMutex *pMutex)
#ifdef WINNT
-SECStatus sslMutex_2LevelInit(sslMutex *sem)
+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
@@ -330,7 +334,8 @@ SECStatus sslMutex_2LevelInit(sslMutex *sem)
return single_process_sslMutex_Init(sem);
}
-static SECStatus sslMutex_2LevelDestroy(sslMutex *sem)
+static SECStatus
+sslMutex_2LevelDestroy(sslMutex *sem)
{
return single_process_sslMutex_Destroy(sem);
}
@@ -345,26 +350,28 @@ sslMutex_Init(sslMutex *pMutex, int shared)
#endif
HANDLE hMutex;
SECURITY_ATTRIBUTES attributes =
- { sizeof(SECURITY_ATTRIBUTES), NULL, TRUE };
+ { sizeof(SECURITY_ATTRIBUTES), NULL, TRUE };
+
+ PR_ASSERT(pMutex != 0 && (pMutex->u.sslMutx == 0 ||
+ pMutex->u.sslMutx ==
+ INVALID_HANDLE_VALUE));
- 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)) {
+
+ if (!pMutex || ((hMutex = pMutex->u.sslMutx) != 0 &&
+ hMutex !=
+ INVALID_HANDLE_VALUE)) {
PORT_SetError(PR_INVALID_ARGUMENT_ERROR);
return SECFailure;
}
@@ -383,28 +390,32 @@ SECStatus
sslMutex_Destroy(sslMutex *pMutex, PRBool processLocal)
{
HANDLE hMutex;
- int rv;
+ int rv;
int retvalue = SECSuccess;
PR_ASSERT(pMutex != 0);
+ if (!pMutex) {
+ PORT_SetError(PR_INVALID_ARGUMENT_ERROR);
+ return SECFailure;
+ }
+
if (PR_FALSE == pMutex->isMultiProcess) {
return single_process_sslMutex_Destroy(pMutex);
}
- /* multi-process mode */
+/* 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) {
+
+ PR_ASSERT(pMutex->u.sslMutx != 0 &&
+ pMutex->u.sslMutx != INVALID_HANDLE_VALUE);
+ if ((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;
@@ -416,21 +427,25 @@ sslMutex_Destroy(sslMutex *pMutex, PRBool processLocal)
return retvalue;
}
-int
+int
sslMutex_Unlock(sslMutex *pMutex)
{
- BOOL success = FALSE;
+ BOOL success = FALSE;
HANDLE hMutex;
- PR_ASSERT(pMutex != 0 );
+ PR_ASSERT(pMutex != 0);
+ if (!pMutex) {
+ PORT_SetError(PR_INVALID_ARGUMENT_ERROR);
+ return SECFailure;
+ }
+
if (PR_FALSE == pMutex->isMultiProcess) {
return single_process_sslMutex_Unlock(pMutex);
}
-
- PR_ASSERT(pMutex->u.sslMutx != 0 &&
+
+ PR_ASSERT(pMutex->u.sslMutx != 0 &&
pMutex->u.sslMutx != INVALID_HANDLE_VALUE);
- if (!pMutex || (hMutex = pMutex->u.sslMutx) == 0 ||
- hMutex == INVALID_HANDLE_VALUE) {
+ if ((hMutex = pMutex->u.sslMutx) == 0 || hMutex == INVALID_HANDLE_VALUE) {
PORT_SetError(PR_INVALID_ARGUMENT_ERROR);
return SECFailure;
}
@@ -441,66 +456,69 @@ sslMutex_Unlock(sslMutex *pMutex)
}
#ifdef WINNT
return single_process_sslMutex_Unlock(pMutex);
- /* release PRLock for other fibers in the process */
+/* release PRLock for other fibers in the process */
#else
return SECSuccess;
#endif
}
-int
+int
sslMutex_Lock(sslMutex *pMutex)
{
- HANDLE hMutex;
- DWORD event;
- DWORD lastError;
+ HANDLE hMutex;
+ DWORD event;
+ DWORD lastError;
SECStatus rv;
SECStatus retvalue = SECSuccess;
+
PR_ASSERT(pMutex != 0);
+ if (!pMutex) {
+ PORT_SetError(PR_INVALID_ARGUMENT_ERROR);
+ return SECFailure;
+ }
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 */
+ /* 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 &&
+ PR_ASSERT(pMutex->u.sslMutx != 0 &&
pMutex->u.sslMutx != INVALID_HANDLE_VALUE);
- if (!pMutex || (hMutex = pMutex->u.sslMutx) == 0 ||
- hMutex == INVALID_HANDLE_VALUE) {
+ if ((hMutex = pMutex->u.sslMutx) == 0 || hMutex == INVALID_HANDLE_VALUE) {
PORT_SetError(PR_INVALID_ARGUMENT_ERROR);
- return SECFailure; /* what else ? */
+ 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_OBJECT_0:
+ case WAIT_ABANDONED:
+ rv = SECSuccess;
+ break;
- case WAIT_TIMEOUT:
+ case WAIT_TIMEOUT:
#if defined(WAIT_IO_COMPLETION)
- case 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;
+ 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;
+ 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)) {
+ if (!(SECSuccess == retvalue && SECSuccess == rv)) {
return SECFailure;
}
-
+
return SECSuccess;
}
@@ -509,8 +527,8 @@ sslMutex_Lock(sslMutex *pMutex)
#include <errno.h>
#include "unix_err.h"
-SECStatus
-sslMutex_Init(sslMutex *pMutex, int shared)
+SECStatus
+sslMutex_Init(sslMutex* pMutex, int shared)
{
int rv;
PR_ASSERT(pMutex);
@@ -528,8 +546,8 @@ sslMutex_Init(sslMutex *pMutex, int shared)
return SECSuccess;
}
-SECStatus
-sslMutex_Destroy(sslMutex *pMutex, PRBool processLocal)
+SECStatus
+sslMutex_Destroy(sslMutex* pMutex, PRBool processLocal)
{
int rv;
if (PR_FALSE == pMutex->isMultiProcess) {
@@ -538,56 +556,56 @@ sslMutex_Destroy(sslMutex *pMutex, PRBool processLocal)
/* semaphores are global resources. See SEM_DESTROY(3) man page */
if (processLocal) {
- return SECSuccess;
+ return SECSuccess;
}
do {
- rv = sem_destroy(&pMutex->u.sem);
+ rv = sem_destroy(&pMutex->u.sem);
} while (rv < 0 && errno == EINTR);
if (rv < 0) {
- nss_MD_unix_map_default_error(errno);
- return SECFailure;
+ nss_MD_unix_map_default_error(errno);
+ return SECFailure;
}
return SECSuccess;
}
-SECStatus
-sslMutex_Unlock(sslMutex *pMutex)
+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);
+ rv = sem_post(&pMutex->u.sem);
} while (rv < 0 && errno == EINTR);
if (rv < 0) {
- nss_MD_unix_map_default_error(errno);
- return SECFailure;
+ nss_MD_unix_map_default_error(errno);
+ return SECFailure;
}
return SECSuccess;
}
-SECStatus
-sslMutex_Lock(sslMutex *pMutex)
+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);
+ rv = sem_wait(&pMutex->u.sem);
} while (rv < 0 && errno == EINTR);
if (rv < 0) {
- nss_MD_unix_map_default_error(errno);
- return SECFailure;
+ nss_MD_unix_map_default_error(errno);
+ return SECFailure;
}
return SECSuccess;
}
#else
-SECStatus
-sslMutex_Init(sslMutex *pMutex, int shared)
+SECStatus
+sslMutex_Init(sslMutex* pMutex, int shared)
{
PR_ASSERT(pMutex);
pMutex->isMultiProcess = (PRBool)(shared != 0);
@@ -599,8 +617,8 @@ sslMutex_Init(sslMutex *pMutex, int shared)
return SECFailure;
}
-SECStatus
-sslMutex_Destroy(sslMutex *pMutex, PRBool processLocal)
+SECStatus
+sslMutex_Destroy(sslMutex* pMutex, PRBool processLocal)
{
PR_ASSERT(pMutex);
if (PR_FALSE == pMutex->isMultiProcess) {
@@ -611,8 +629,8 @@ sslMutex_Destroy(sslMutex *pMutex, PRBool processLocal)
return SECFailure;
}
-SECStatus
-sslMutex_Unlock(sslMutex *pMutex)
+SECStatus
+sslMutex_Unlock(sslMutex* pMutex)
{
PR_ASSERT(pMutex);
if (PR_FALSE == pMutex->isMultiProcess) {
@@ -623,8 +641,8 @@ sslMutex_Unlock(sslMutex *pMutex)
return SECFailure;
}
-SECStatus
-sslMutex_Lock(sslMutex *pMutex)
+SECStatus
+sslMutex_Lock(sslMutex* pMutex)
{
PR_ASSERT(pMutex);
if (PR_FALSE == pMutex->isMultiProcess) {
diff --git a/nss/lib/ssl/sslmutex.h b/nss/lib/ssl/sslmutex.h
index d374a88..7611148 100644
--- a/nss/lib/ssl/sslmutex.h
+++ b/nss/lib/ssl/sslmutex.h
@@ -4,20 +4,20 @@
#ifndef __SSLMUTEX_H_
#define __SSLMUTEX_H_ 1
-/* What SSL really wants is portable process-shared unnamed mutexes in
+/* 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.
+ * 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.
@@ -34,8 +34,7 @@
#include <wtypes.h>
-typedef struct
-{
+typedef struct {
PRBool isMultiProcess;
#ifdef WINNT
/* on WINNT we need both the PRLock and the Win32 mutex for fibers */
@@ -43,25 +42,25 @@ typedef struct
#else
union {
#endif
- PRLock* sslLock;
+ PRLock *sslLock;
HANDLE sslMutx;
} u;
} sslMutex;
-typedef int sslPID;
+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 {
+typedef struct {
PRBool isMultiProcess;
union {
- PRLock* sslLock;
+ PRLock *sslLock;
struct {
- int mPipes[3];
- PRInt32 nWaiters;
+ int mPipes[3];
+ PRInt32 nWaiters;
} pipeStr;
} u;
} sslMutex;
@@ -70,15 +69,14 @@ typedef pid_t sslPID;
/* other types of unix, except OS X */
#elif defined(XP_UNIX) && !defined(DARWIN)
-#include <sys/types.h> /* for pid_t */
-#include <semaphore.h> /* for sem_t, and sem_* functions */
+#include <sys/types.h> /* for pid_t */
+#include <semaphore.h> /* for sem_t, and sem_* functions */
-typedef struct
-{
+typedef struct {
PRBool isMultiProcess;
union {
- PRLock* sslLock;
- sem_t sem;
+ PRLock *sslLock;
+ sem_t sem;
} u;
} sslMutex;
@@ -88,10 +86,10 @@ typedef pid_t sslPID;
/* what platform is this ?? */
-typedef struct {
+typedef struct {
PRBool isMultiProcess;
union {
- PRLock* sslLock;
+ PRLock *sslLock;
/* include cross-process locking mechanism here */
} u;
} sslMutex;
@@ -111,7 +109,7 @@ 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
+ * with the current process. Leave any shared resources (including the state of
* shared memory) intact. */
extern SECStatus sslMutex_Destroy(sslMutex *sem, PRBool processLocal);
diff --git a/nss/lib/ssl/sslnonce.c b/nss/lib/ssl/sslnonce.c
index 2e861f1..91cc870 100644
--- a/nss/lib/ssl/sslnonce.c
+++ b/nss/lib/ssl/sslnonce.c
@@ -1,5 +1,5 @@
-/*
- * This file implements the CLIENT Session ID cache.
+/*
+ * 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
@@ -22,18 +22,18 @@ PRUint32 ssl_sid_timeout = 100;
PRUint32 ssl3_sid_timeout = 86400L; /* 24 hours */
static sslSessionID *cache = NULL;
-static PZLock * cacheLock = 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.
+ * 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)
+#define LOCK_CACHE lock_cache()
+#define UNLOCK_CACHE PZ_Unlock(cacheLock)
static SECStatus
ssl_InitClientSessionCacheLock(void)
@@ -62,7 +62,7 @@ FreeSessionCacheLocks()
SECStatus rv1, rv2;
rv1 = ssl_FreeSymWrapKeysLock();
rv2 = ssl_FreeClientSessionCacheLock();
- if ( (SECSuccess == rv1) && (SECSuccess == rv2) ) {
+ if ((SECSuccess == rv1) && (SECSuccess == rv2)) {
return SECSuccess;
}
return SECFailure;
@@ -75,7 +75,7 @@ InitSessionCacheLocks(void)
PRErrorCode rc;
rv1 = ssl_InitSymWrapKeysLock();
rv2 = ssl_InitClientSessionCacheLock();
- if ( (SECSuccess == rv1) && (SECSuccess == rv2) ) {
+ if ((SECSuccess == rv1) && (SECSuccess == rv2)) {
return SECSuccess;
}
rc = PORT_GetError();
@@ -101,7 +101,8 @@ ssl_FreeSessionCacheLocks()
static PRCallOnceType lockOnce;
/* free the session cache locks if they were initialized lazily */
-static SECStatus ssl_ShutdownLocks(void* appData, void* nssData)
+static SECStatus
+ssl_ShutdownLocks(void *appData, void *nssData)
{
PORT_Assert(PR_FALSE == LocksInitializedEarly);
if (LocksInitializedEarly) {
@@ -113,7 +114,8 @@ static SECStatus ssl_ShutdownLocks(void* appData, void* nssData)
return SECSuccess;
}
-static PRStatus initSessionCacheLocksLazily(void)
+static PRStatus
+initSessionCacheLocksLazily(void)
{
SECStatus rv = InitSessionCacheLocks();
if (SECSuccess != rv) {
@@ -139,10 +141,11 @@ ssl_InitSessionCacheLocks(PRBool lazyInit)
if (lazyInit) {
return (PR_SUCCESS ==
- PR_CallOnce(&lockOnce, initSessionCacheLocksLazily)) ?
- SECSuccess : SECFailure;
+ PR_CallOnce(&lockOnce, initSessionCacheLocksLazily))
+ ? SECSuccess
+ : SECFailure;
}
-
+
if (SECSuccess == InitSessionCacheLocks()) {
LocksInitializedEarly = PR_TRUE;
return SECSuccess;
@@ -151,7 +154,7 @@ ssl_InitSessionCacheLocks(PRBool lazyInit)
return SECFailure;
}
-static void
+static void
lock_cache(void)
{
ssl_InitSessionCacheLocks(PR_TRUE);
@@ -168,63 +171,63 @@ ssl_DestroySID(sslSessionID *sid)
PORT_Assert(sid->references == 0);
PORT_Assert(sid->cached != in_client_cache);
- if (sid->version < SSL_LIBRARY_VERSION_3_0) {
- SECITEM_ZfreeItem(&sid->u.ssl2.masterKey, PR_FALSE);
- SECITEM_ZfreeItem(&sid->u.ssl2.cipherArg, PR_FALSE);
- } else {
- if (sid->u.ssl3.locked.sessionTicket.ticket.data) {
- SECITEM_FreeItem(&sid->u.ssl3.locked.sessionTicket.ticket,
- PR_FALSE);
- }
- if (sid->u.ssl3.srvName.data) {
- SECITEM_FreeItem(&sid->u.ssl3.srvName, PR_FALSE);
- }
+ if (sid->u.ssl3.locked.sessionTicket.ticket.data) {
+ SECITEM_FreeItem(&sid->u.ssl3.locked.sessionTicket.ticket,
+ PR_FALSE);
+ }
+ if (sid->u.ssl3.srvName.data) {
+ SECITEM_FreeItem(&sid->u.ssl3.srvName, PR_FALSE);
+ }
+ if (sid->u.ssl3.signedCertTimestamps.data) {
+ SECITEM_FreeItem(&sid->u.ssl3.signedCertTimestamps, PR_FALSE);
+ }
- if (sid->u.ssl3.lock) {
- PR_DestroyRWLock(sid->u.ssl3.lock);
- }
+ if (sid->u.ssl3.lock) {
+ PR_DestroyRWLock(sid->u.ssl3.lock);
}
if (sid->peerID != NULL)
- PORT_Free((void *)sid->peerID); /* CONST */
+ PORT_Free((void *)sid->peerID); /* CONST */
if (sid->urlSvrName != NULL)
- PORT_Free((void *)sid->urlSvrName); /* CONST */
+ PORT_Free((void *)sid->urlSvrName); /* CONST */
- if ( sid->peerCert ) {
- CERT_DestroyCertificate(sid->peerCert);
+ if (sid->peerCert) {
+ CERT_DestroyCertificate(sid->peerCert);
}
if (sid->peerCertStatus.items) {
SECITEM_FreeArray(&sid->peerCertStatus, PR_FALSE);
}
- if ( sid->localCert ) {
- CERT_DestroyCertificate(sid->localCert);
+ if (sid->localCert) {
+ CERT_DestroyCertificate(sid->localCert);
}
-
+
+ SECITEM_FreeItem(&sid->u.ssl3.alpnSelection, 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.
+ * 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
+static void
ssl_FreeLockedSID(sslSessionID *sid)
{
PORT_Assert(sid->references >= 1);
if (--sid->references == 0) {
- ssl_DestroySID(sid);
+ 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.
+ * 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
@@ -244,57 +247,53 @@ ssl_FreeSID(sslSessionID *sid)
*/
sslSessionID *
-ssl_LookupSID(const PRIPv6Addr *addr, PRUint16 port, const char *peerID,
- const char * urlSvrName)
+ssl_LookupSID(const PRIPv6Addr *addr, PRUint16 port, const char *peerID,
+ const char *urlSvrName)
{
sslSessionID **sidp;
- sslSessionID * sid;
- PRUint32 now;
+ sslSessionID *sid;
+ PRUint32 now;
if (!urlSvrName)
- return NULL;
+ 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) {
- /*
- ** This session-id timed out.
- ** 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. */
- 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;
- }
+ 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) {
+ /*
+ ** This session-id timed out.
+ ** 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. */
+ 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->u.ssl3.keys.resumable) &&
+ /* server hostname matches. */
+ (sid->urlSvrName != NULL) &&
+ (0 == PORT_Strcmp(urlSvrName, sid->urlSvrName))) {
+ /* Hit */
+ sid->lastAccessTime = now;
+ sid->references++;
+ break;
+ } else {
+ sidp = &sid->next;
+ }
}
UNLOCK_CACHE;
return sid;
@@ -304,62 +303,51 @@ ssl_LookupSID(const PRIPv6Addr *addr, PRUint16 port, const char *peerID,
** 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
+static void
CacheSID(sslSessionID *sid)
{
- PRUint32 expirationPeriod;
+ PRUint32 expirationPeriod;
PORT_Assert(sid->cached == never_cached);
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));
+ "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->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.locked.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));
-
- sid->u.ssl3.lock = PR_NewRWLock(PR_RWLOCK_RANK_NONE, NULL);
- if (!sid->u.ssl3.lock) {
- return;
- }
+ if (sid->u.ssl3.sessionIDLength == 0 &&
+ sid->u.ssl3.locked.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));
+
+ sid->u.ssl3.lock = PR_NewRWLock(PR_RWLOCK_RANK_NONE, NULL);
+ if (!sid->u.ssl3.lock) {
+ return;
}
PORT_Assert(sid->creationTime != 0 && sid->expirationTime != 0);
if (!sid->creationTime)
- sid->lastAccessTime = sid->creationTime = ssl_Time();
+ sid->lastAccessTime = sid->creationTime = ssl_Time();
if (!sid->expirationTime)
- sid->expirationTime = sid->creationTime + expirationPeriod;
+ sid->expirationTime = sid->creationTime + expirationPeriod;
/*
* Put sid into the cache. Bump reference count to indicate that
@@ -369,12 +357,12 @@ CacheSID(sslSessionID *sid)
LOCK_CACHE;
sid->references++;
sid->cached = in_client_cache;
- sid->next = cache;
- cache = sid;
+ 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.
@@ -386,43 +374,35 @@ UncacheSID(sslSessionID *zap)
sslSessionID *sid;
if (zap->cached != in_client_cache) {
- return;
+ 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));
- }
+ SSL_TRC(8, ("SSL: Uncache: zap=0x%x cached=%d addr=0x%08x%08x%08x%08x port=0x%04x "
+ "time=%x cipherSuite=%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.ssl3.cipherSuite));
/* 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) {
+ /*
+ ** 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
+ * Although this function is static, it is called externally via
* ss->sec.uncache().
*/
static void
@@ -431,19 +411,18 @@ LockAndUncacheSID(sslSessionID *zap)
LOCK_CACHE;
UncacheSID(zap);
UNLOCK_CACHE;
-
}
/* choose client or server cache functions for this sslsocket. */
-void
+void
ssl_ChooseSessionIDProcs(sslSecurityInfo *sec)
{
if (sec->isServer) {
- sec->cache = ssl_sid_cache;
- sec->uncache = ssl_sid_uncache;
+ sec->cache = ssl_sid_cache;
+ sec->uncache = ssl_sid_uncache;
} else {
- sec->cache = CacheSID;
- sec->uncache = LockAndUncacheSID;
+ sec->cache = CacheSID;
+ sec->uncache = LockAndUncacheSID;
}
}
@@ -452,8 +431,8 @@ void
SSL_ClearSessionCache(void)
{
LOCK_CACHE;
- while(cache != NULL)
- UncacheSID(cache);
+ while (cache != NULL)
+ UncacheSID(cache);
UNLOCK_CACHE;
}
@@ -461,9 +440,13 @@ SSL_ClearSessionCache(void)
PRUint32
ssl_Time(void)
{
+#ifdef UNSAFE_FUZZER_MODE
+ return 1234;
+#endif
+
PRUint32 myTime;
#if defined(XP_UNIX) || defined(XP_WIN) || defined(_WINDOWS) || defined(XP_BEOS)
- myTime = time(NULL); /* accurate until the year 2038. */
+ myTime = time(NULL); /* accurate until the year 2038. */
#else
/* portable, but possibly slower */
PRTime now;
@@ -492,11 +475,11 @@ ssl3_SetSIDSessionTicket(sslSessionID *sid,
* yet, so no locking is needed.
*/
if (sid->u.ssl3.lock) {
- PR_RWLock_Wlock(sid->u.ssl3.lock);
- if (sid->u.ssl3.locked.sessionTicket.ticket.data) {
- SECITEM_FreeItem(&sid->u.ssl3.locked.sessionTicket.ticket,
- PR_FALSE);
- }
+ PR_RWLock_Wlock(sid->u.ssl3.lock);
+ if (sid->u.ssl3.locked.sessionTicket.ticket.data) {
+ SECITEM_FreeItem(&sid->u.ssl3.locked.sessionTicket.ticket,
+ PR_FALSE);
+ }
}
PORT_Assert(!sid->u.ssl3.locked.sessionTicket.ticket.data);
@@ -507,6 +490,6 @@ ssl3_SetSIDSessionTicket(sslSessionID *sid,
newSessionTicket->ticket.len = 0;
if (sid->u.ssl3.lock) {
- PR_RWLock_Unlock(sid->u.ssl3.lock);
+ PR_RWLock_Unlock(sid->u.ssl3.lock);
}
}
diff --git a/nss/lib/ssl/sslproto.h b/nss/lib/ssl/sslproto.h
index 2db47a5..70daea0 100644
--- a/nss/lib/ssl/sslproto.h
+++ b/nss/lib/ssl/sslproto.h
@@ -1,6 +1,6 @@
/*
* Various and sundry protocol constants. DON'T CHANGE THESE. These values
- * are mostly defined by the SSL2, SSL3, or TLS protocol specifications.
+ * are mostly defined by the 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
@@ -10,6 +10,8 @@
#ifndef __sslproto_h_
#define __sslproto_h_
+/* clang-format off */
+
/* 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
@@ -19,9 +21,9 @@
#define SSL_LIBRARY_VERSION_TLS_1_3 0x0304
/* Note: this is the internal format, not the wire format */
-#define SSL_LIBRARY_VERSION_DTLS_1_0 0x0302
-#define SSL_LIBRARY_VERSION_DTLS_1_2 0x0303
-#define SSL_LIBRARY_VERSION_DTLS_1_3 0x0304
+#define SSL_LIBRARY_VERSION_DTLS_1_0 SSL_LIBRARY_VERSION_TLS_1_1
+#define SSL_LIBRARY_VERSION_DTLS_1_2 SSL_LIBRARY_VERSION_TLS_1_2
+#define SSL_LIBRARY_VERSION_DTLS_1_3 SSL_LIBRARY_VERSION_TLS_1_3
/* deprecated old name */
#define SSL_LIBRARY_VERSION_3_1_TLS SSL_LIBRARY_VERSION_TLS_1_0
@@ -29,29 +31,7 @@
/* The DTLS versions used in the spec */
#define SSL_LIBRARY_VERSION_DTLS_1_0_WIRE ((~0x0100) & 0xffff)
#define SSL_LIBRARY_VERSION_DTLS_1_2_WIRE ((~0x0102) & 0xffff)
-#define SSL_LIBRARY_VERSION_DTLS_1_3_WIRE ((~0x0103) & 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
+#define SSL_LIBRARY_VERSION_DTLS_1_3_WIRE SSL_LIBRARY_VERSION_DTLS_1_3
/* Certificate types */
#define SSL_CT_X509_CERTIFICATE 0x01
@@ -66,57 +46,27 @@
#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
-
/* Deprecated SSL 3.0 & libssl names replaced by IANA-registered TLS names. */
#ifndef SSL_DISABLE_DEPRECATED_CIPHER_SUITE_NAMES
#define SSL_NULL_WITH_NULL_NULL TLS_NULL_WITH_NULL_NULL
#define SSL_RSA_WITH_NULL_MD5 TLS_RSA_WITH_NULL_MD5
#define SSL_RSA_WITH_NULL_SHA TLS_RSA_WITH_NULL_SHA
-#define SSL_RSA_EXPORT_WITH_RC4_40_MD5 TLS_RSA_EXPORT_WITH_RC4_40_MD5
#define SSL_RSA_WITH_RC4_128_MD5 TLS_RSA_WITH_RC4_128_MD5
#define SSL_RSA_WITH_RC4_128_SHA TLS_RSA_WITH_RC4_128_SHA
-#define SSL_RSA_EXPORT_WITH_RC2_CBC_40_MD5 TLS_RSA_EXPORT_WITH_RC2_CBC_40_MD5
#define SSL_RSA_WITH_IDEA_CBC_SHA TLS_RSA_WITH_IDEA_CBC_SHA
-#define SSL_RSA_EXPORT_WITH_DES40_CBC_SHA TLS_RSA_EXPORT_WITH_DES40_CBC_SHA
#define SSL_RSA_WITH_DES_CBC_SHA TLS_RSA_WITH_DES_CBC_SHA
#define SSL_RSA_WITH_3DES_EDE_CBC_SHA TLS_RSA_WITH_3DES_EDE_CBC_SHA
-#define SSL_DH_DSS_EXPORT_WITH_DES40_CBC_SHA TLS_DH_DSS_EXPORT_WITH_DES40_CBC_SHA
#define SSL_DH_DSS_WITH_DES_CBC_SHA TLS_DH_DSS_WITH_DES_CBC_SHA
#define SSL_DH_DSS_WITH_3DES_EDE_CBC_SHA TLS_DH_DSS_WITH_3DES_EDE_CBC_SHA
-#define SSL_DH_RSA_EXPORT_WITH_DES40_CBC_SHA TLS_DH_RSA_EXPORT_WITH_DES40_CBC_SHA
#define SSL_DH_RSA_WITH_DES_CBC_SHA TLS_DH_RSA_WITH_DES_CBC_SHA
#define SSL_DH_RSA_WITH_3DES_EDE_CBC_SHA TLS_DH_RSA_WITH_3DES_EDE_CBC_SHA
-#define SSL_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA TLS_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA
#define SSL_DHE_DSS_WITH_DES_CBC_SHA TLS_DHE_DSS_WITH_DES_CBC_SHA
#define SSL_DHE_DSS_WITH_3DES_EDE_CBC_SHA TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA
-#define SSL_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA TLS_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA
#define SSL_DHE_RSA_WITH_DES_CBC_SHA TLS_DHE_RSA_WITH_DES_CBC_SHA
#define SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA
#define SSL_DH_ANON_WITH_RC4_128_MD5 TLS_DH_anon_WITH_RC4_128_MD5
-#define SSL_DH_ANON_EXPORT_WITH_DES40_CBC_SHA TLS_DH_anon_EXPORT_WITH_DES40_CBC_SHA
#define SSL_DH_ANON_WITH_DES_CBC_SHA TLS_DH_anon_WITH_DES_CBC_SHA
#define SSL_DH_ANON_WITH_3DES_EDE_CBC_SHA TLS_DH_anon_WITH_3DES_EDE_CBC_SHA
-#define SSL_DH_ANON_EXPORT_WITH_RC4_40_MD5 TLS_DH_anon_EXPORT_WITH_RC4_40_MD5
#define TLS_DH_ANON_WITH_AES_128_CBC_SHA TLS_DH_anon_WITH_AES_128_CBC_SHA
#define TLS_DH_ANON_WITH_AES_256_CBC_SHA TLS_DH_anon_WITH_AES_256_CBC_SHA
#define TLS_DH_ANON_WITH_CAMELLIA_128_CBC_SHA TLS_DH_anon_WITH_CAMELLIA_128_CBC_SHA
@@ -127,39 +77,26 @@
#define TLS_RSA_WITH_NULL_MD5 0x0001
#define TLS_RSA_WITH_NULL_SHA 0x0002
-#define TLS_RSA_EXPORT_WITH_RC4_40_MD5 0x0003
#define TLS_RSA_WITH_RC4_128_MD5 0x0004
#define TLS_RSA_WITH_RC4_128_SHA 0x0005
-#define TLS_RSA_EXPORT_WITH_RC2_CBC_40_MD5 0x0006
#define TLS_RSA_WITH_IDEA_CBC_SHA 0x0007
-#define TLS_RSA_EXPORT_WITH_DES40_CBC_SHA 0x0008
#define TLS_RSA_WITH_DES_CBC_SHA 0x0009
#define TLS_RSA_WITH_3DES_EDE_CBC_SHA 0x000a
-#define TLS_DH_DSS_EXPORT_WITH_DES40_CBC_SHA 0x000b
#define TLS_DH_DSS_WITH_DES_CBC_SHA 0x000c
#define TLS_DH_DSS_WITH_3DES_EDE_CBC_SHA 0x000d
-#define TLS_DH_RSA_EXPORT_WITH_DES40_CBC_SHA 0x000e
#define TLS_DH_RSA_WITH_DES_CBC_SHA 0x000f
#define TLS_DH_RSA_WITH_3DES_EDE_CBC_SHA 0x0010
-#define TLS_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA 0x0011
#define TLS_DHE_DSS_WITH_DES_CBC_SHA 0x0012
#define TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA 0x0013
-#define TLS_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA 0x0014
#define TLS_DHE_RSA_WITH_DES_CBC_SHA 0x0015
#define TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA 0x0016
-#define TLS_DH_anon_EXPORT_WITH_RC4_40_MD5 0x0017
#define TLS_DH_anon_WITH_RC4_128_MD5 0x0018
-#define TLS_DH_anon_EXPORT_WITH_DES40_CBC_SHA 0x0019
#define TLS_DH_anon_WITH_DES_CBC_SHA 0x001a
#define TLS_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 */
-
#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
@@ -185,11 +122,6 @@
#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_DHE_RSA_WITH_AES_128_CBC_SHA256 0x0067
#define TLS_DHE_DSS_WITH_AES_256_CBC_SHA256 0x006A
@@ -205,8 +137,11 @@
#define TLS_RSA_WITH_SEED_CBC_SHA 0x0096
#define TLS_RSA_WITH_AES_128_GCM_SHA256 0x009C
+#define TLS_RSA_WITH_AES_256_GCM_SHA384 0x009D
#define TLS_DHE_RSA_WITH_AES_128_GCM_SHA256 0x009E
+#define TLS_DHE_RSA_WITH_AES_256_GCM_SHA384 0x009F
#define TLS_DHE_DSS_WITH_AES_128_GCM_SHA256 0x00A2
+#define TLS_DHE_DSS_WITH_AES_256_GCM_SHA384 0x00A3
/* TLS "Signaling Cipher Suite Value" (SCSV). May be requested by client.
* Must NEVER be chosen by server. SSL 3.0 server acknowledges by sending
@@ -253,20 +188,36 @@
#define TLS_ECDH_anon_WITH_AES_256_CBC_SHA 0xC019
#define TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256 0xC023
+#define TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384 0xC024
#define TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256 0xC027
+#define TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384 0xC028
#define TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 0xC02B
+#define TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384 0xC02C
#define TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256 0xC02D
#define TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 0xC02F
+#define TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 0xC030
#define TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256 0xC031
-/* 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
+/* draft-ietf-tls-chacha20-poly1305-04 */
+#define TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256 0xCCA8
+#define TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256 0xCCA9
+#define TLS_DHE_RSA_WITH_CHACHA20_POLY1305_SHA256 0xCCAA
+
+/* Special TLS 1.3 cipher suites that really just specify AEAD */
+#define TLS_AES_128_GCM_SHA256 0x1301
+#define TLS_AES_256_GCM_SHA384 0x1302
+#define TLS_CHACHA20_POLY1305_SHA256 0x1303
+
+/* PSK cipher suites. NSS doesn't actually support these, but we
+ * exposed them when TLS 1.3 used them so we need to keep them
+ * in the API. */
+#define TLS_ECDHE_PSK_WITH_CHACHA20_POLY1305_SHA256 0xCCAC
+#define TLS_DHE_PSK_WITH_CHACHA20_POLY1305_SHA256 0xCCAD
+#define TLS_ECDHE_PSK_WITH_AES_128_GCM_SHA256 0xD001
+#define TLS_ECDHE_PSK_WITH_AES_256_GCM_SHA384 0xD002
+#define TLS_DHE_PSK_WITH_AES_128_GCM_SHA256 0x00AA /* RFC 5487 */
+#define TLS_DHE_PSK_WITH_AES_256_GCM_SHA384 0x00AB /* RFC 5487 */
/* DTLS-SRTP cipher suites from RFC 5764 */
/* If you modify this, also modify MAX_DTLS_SRTP_CIPHER_SUITES in sslimpl.h */
@@ -275,4 +226,69 @@
#define SRTP_NULL_HMAC_SHA1_80 0x0005
#define SRTP_NULL_HMAC_SHA1_32 0x0006
+/* DO NOT USE. (deprecated, will be removed) */
+#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
+#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
+#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
+#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
+#define TLS_RSA_EXPORT_WITH_RC4_40_MD5 0x0003
+#define TLS_RSA_EXPORT_WITH_RC2_CBC_40_MD5 0x0006
+#define TLS_RSA_EXPORT_WITH_DES40_CBC_SHA 0x0008
+#define TLS_RSA_EXPORT1024_WITH_DES_CBC_SHA 0x0062
+#define TLS_RSA_EXPORT1024_WITH_RC4_56_SHA 0x0064
+#define TLS_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA 0x0014
+#define TLS_DH_RSA_EXPORT_WITH_DES40_CBC_SHA 0x000e
+#define TLS_DHE_DSS_EXPORT1024_WITH_DES_CBC_SHA 0x0063
+#define TLS_DHE_DSS_EXPORT1024_WITH_RC4_56_SHA 0x0065
+#define TLS_DH_DSS_EXPORT_WITH_DES40_CBC_SHA 0x000b
+#define TLS_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA 0x0011
+#define TLS_DH_anon_EXPORT_WITH_RC4_40_MD5 0x0017
+#define TLS_DH_anon_EXPORT_WITH_DES40_CBC_SHA 0x0019
+#define SSL_FORTEZZA_DMS_WITH_NULL_SHA 0x001c
+#define SSL_FORTEZZA_DMS_WITH_FORTEZZA_CBC_SHA 0x001d
+#define SSL_FORTEZZA_DMS_WITH_RC4_128_SHA 0x001e
+#define SSL_RSA_OLDFIPS_WITH_3DES_EDE_CBC_SHA 0xffe0
+#define SSL_RSA_OLDFIPS_WITH_DES_CBC_SHA 0xffe1
+#define SSL_RSA_FIPS_WITH_3DES_EDE_CBC_SHA 0xfeff
+#define SSL_RSA_FIPS_WITH_DES_CBC_SHA 0xfefe
+#define SSL_RSA_EXPORT_WITH_RC4_40_MD5 TLS_RSA_EXPORT_WITH_RC4_40_MD5
+#define SSL_RSA_EXPORT_WITH_RC2_CBC_40_MD5 TLS_RSA_EXPORT_WITH_RC2_CBC_40_MD5
+#define SSL_RSA_EXPORT_WITH_DES40_CBC_SHA TLS_RSA_EXPORT_WITH_DES40_CBC_SHA
+#define SSL_DH_RSA_EXPORT_WITH_DES40_CBC_SHA TLS_DH_RSA_EXPORT_WITH_DES40_CBC_SHA
+#define SSL_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA TLS_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA
+#define SSL_DH_DSS_EXPORT_WITH_DES40_CBC_SHA TLS_DH_DSS_EXPORT_WITH_DES40_CBC_SHA
+#define SSL_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA TLS_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA
+#define SSL_DH_ANON_EXPORT_WITH_DES40_CBC_SHA TLS_DH_anon_EXPORT_WITH_DES40_CBC_SHA
+#define SSL_DH_ANON_EXPORT_WITH_RC4_40_MD5 TLS_DH_anon_EXPORT_WITH_RC4_40_MD5
+
+/* clang-format on */
+
#endif /* __sslproto_h_ */
diff --git a/nss/lib/ssl/sslreveal.c b/nss/lib/ssl/sslreveal.c
index d972998..4c124a1 100644
--- a/nss/lib/ssl/sslreveal.c
+++ b/nss/lib/ssl/sslreveal.c
@@ -1,4 +1,4 @@
-/*
+/*
* Accessor functions for SSLSocket private members.
*
* This Source Code Form is subject to the terms of the Mozilla Public
@@ -13,100 +13,98 @@
/* 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 *
+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;
+ 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)
+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;
-}
+ 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)
+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;
-}
+ sslSocket *sslsocket = NULL;
+ char *url = NULL;
+
+ sslsocket = ssl_FindSocket(fd);
+ if (sslsocket && sslsocket->url)
+ url = PL_strdup(sslsocket->url);
-/* given PRFileDesc, returns status information related to extensions
+ return url;
+}
+
+/* given PRFileDesc, returns status information related to extensions
* negotiated with peer during the handshake.
*/
SECStatus
-SSL_HandshakeNegotiatedExtension(PRFileDesc * socket,
+SSL_HandshakeNegotiatedExtension(PRFileDesc *socket,
SSLExtensionType extId,
PRBool *pYes)
{
- /* some decisions derived from SSL_GetChannelInfo */
- sslSocket * sslsocket = NULL;
-
- if (!pYes) {
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- return SECFailure;
- }
-
- sslsocket = ssl_FindSocket(socket);
- if (!sslsocket) {
- SSL_DBG(("%d: SSL[%d]: bad socket in HandshakeNegotiatedExtension",
- SSL_GETPID(), socket));
- return SECFailure;
- }
-
- *pYes = PR_FALSE;
-
- /* according to public API SSL_GetChannelInfo, this doesn't need a lock */
- if (sslsocket->opt.useSecurity) {
- 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);
+ /* some decisions derived from SSL_GetChannelInfo */
+ sslSocket *sslsocket = NULL;
+
+ if (!pYes) {
+ PORT_SetError(SEC_ERROR_INVALID_ARGS);
+ return SECFailure;
+ }
+
+ sslsocket = ssl_FindSocket(socket);
+ if (!sslsocket) {
+ SSL_DBG(("%d: SSL[%d]: bad socket in HandshakeNegotiatedExtension",
+ SSL_GETPID(), socket));
+ return SECFailure;
+ }
+
+ *pYes = PR_FALSE;
+
+ /* according to public API SSL_GetChannelInfo, this doesn't need a lock */
+ if (sslsocket->opt.useSecurity) {
+ 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);
+ }
}
- }
- return SECSuccess;
+ return SECSuccess;
}
diff --git a/nss/lib/ssl/sslsecur.c b/nss/lib/ssl/sslsecur.c
index 53b4885..eecf443 100644
--- a/nss/lib/ssl/sslsecur.c
+++ b/nss/lib/ssl/sslsecur.c
@@ -10,116 +10,68 @@
#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 */
+#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.
- *
+/* Returns a SECStatus: SECSuccess or SECFailure, NOT SECWouldBlock.
+ *
* Currently, the list of functions called through ss->handshake is:
- *
+ *
* In sslsocks.c:
* SocksGatherRecord
- * SocksHandleReply
+ * 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.
+ * ssl_BeginClientHandshake
+ * ssl_BeginServerHandshake
*
- * 2. ssl2_HandleClientHelloMessage discovered version 3.0 in the incoming
- * v2 client hello msg, and called ssl3_HandleV2ClientHello which
- * returned SECWouldBlock.
+ * The ss->handshake function returns SECWouldBlock if it was returned by
+ * one of the callback functions, via one of these paths:
*
- * 3. SECWouldBlock was returned by one of the callback functions, via
- * one of these paths:
- * - ssl2_HandleMessage() -> ssl2_HandleRequestCertificate() ->
- * ss->getClientAuthData()
+ * - ssl_GatherRecord1stHandshake() -> ssl3_GatherCompleteHandshake() ->
+ * ssl3_HandleRecord() -> ssl3_HandleHandshake() ->
+ * ssl3_HandleHandshakeMessage() -> ssl3_HandleCertificate() ->
+ * ss->handleBadCert()
*
- * - ssl2_HandleServerHelloMessage() -> ss->handleBadCert()
+ * - ssl_GatherRecord1stHandshake() -> ssl3_GatherCompleteHandshake() ->
+ * ssl3_HandleRecord() -> ssl3_HandleHandshake() ->
+ * ssl3_HandleHandshakeMessage() -> ssl3_HandleCertificateRequest() ->
+ * ss->getClientAuthData()
*
- * - 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
+ * 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
+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) {
- /* for v3 this is done in ssl3_FinishHandshake */
- if (!ss->firstHsDone && ss->version < SSL_LIBRARY_VERSION_3_0) {
- ssl_GetRecvBufLock(ss);
- ss->gs.recordLen = 0;
- ssl_FinishHandshake(ss);
- ssl_ReleaseRecvBufLock(ss);
- }
- 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 */
+ int rv = SECSuccess;
+
+ while (ss->handshake && rv == SECSuccess) {
+ 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));
+
+ rv = (*ss->handshake)(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 (rv == SECWouldBlock) {
- PORT_SetError(PR_WOULD_BLOCK_ERROR);
- rv = SECFailure;
+ PORT_SetError(PR_WOULD_BLOCK_ERROR);
+ rv = SECFailure;
}
return rv;
}
@@ -127,22 +79,23 @@ ssl_Do1stHandshake(sslSocket *ss)
void
ssl_FinishHandshake(sslSocket *ss)
{
- PORT_Assert( ss->opt.noLocks || ssl_Have1stHandshakeLock(ss) );
- PORT_Assert( ss->opt.noLocks || ssl_HaveRecvBufLock(ss) );
+ PORT_Assert(ss->opt.noLocks || ssl_Have1stHandshakeLock(ss));
+ PORT_Assert(ss->opt.noLocks || ssl_HaveRecvBufLock(ss));
SSL_TRC(3, ("%d: SSL[%d]: handshake is completed", SSL_GETPID(), ss->fd));
ss->firstHsDone = PR_TRUE;
ss->enoughFirstHsDone = PR_TRUE;
ss->gs.writeOffset = 0;
- ss->gs.readOffset = 0;
+ ss->gs.readOffset = 0;
if (ss->handshakeCallback) {
- PORT_Assert(ss->version < SSL_LIBRARY_VERSION_3_0 ||
- (ss->ssl3.hs.preliminaryInfo & ssl_preinfo_all) ==
- ssl_preinfo_all);
- (ss->handshakeCallback)(ss->fd, ss->handshakeCallbackData);
+ PORT_Assert((ss->ssl3.hs.preliminaryInfo & ssl_preinfo_all) ==
+ ssl_preinfo_all);
+ (ss->handshakeCallback)(ss->fd, ss->handshakeCallbackData);
}
+
+ ssl_FreeEphemeralKeyPairs(ss);
}
/*
@@ -152,7 +105,7 @@ ssl_FinishHandshake(sslSocket *ss)
static SECStatus
ssl3_AlwaysBlock(sslSocket *ss)
{
- PORT_SetError(PR_WOULD_BLOCK_ERROR); /* perhaps redundant. */
+ PORT_SetError(PR_WOULD_BLOCK_ERROR); /* perhaps redundant. */
return SECWouldBlock;
}
@@ -163,20 +116,19 @@ void
ssl3_SetAlwaysBlock(sslSocket *ss)
{
if (!ss->firstHsDone) {
- ss->handshake = ssl3_AlwaysBlock;
- ss->nextHandshake = 0;
+ ss->handshake = ssl3_AlwaysBlock;
}
}
-static SECStatus
+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_DBG(("%d: SSL[%d]: bad socket in SetTimeout", SSL_GETPID(), fd));
+ return SECFailure;
}
SSL_LOCK_READER(ss);
ss->rTimeout = timeout;
@@ -202,13 +154,13 @@ SSL_ResetHandshake(PRFileDesc *s, PRBool asServer)
ss = ssl_FindSocket(s);
if (!ss) {
- SSL_DBG(("%d: SSL[%d]: bad socket in ResetHandshake", SSL_GETPID(), s));
- return SECFailure;
+ 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;
+ return SECSuccess;
SSL_LOCK_READER(ss);
SSL_LOCK_WRITER(ss);
@@ -218,19 +170,19 @@ SSL_ResetHandshake(PRFileDesc *s, PRBool asServer)
ss->firstHsDone = PR_FALSE;
ss->enoughFirstHsDone = PR_FALSE;
- if ( asServer ) {
- ss->handshake = ssl2_BeginServerHandshake;
- ss->handshaking = sslHandshakingAsServer;
+ if (asServer) {
+ ss->handshake = ssl_BeginServerHandshake;
+ ss->handshaking = sslHandshakingAsServer;
} else {
- ss->handshake = ssl2_BeginClientHandshake;
- ss->handshaking = sslHandshakingAsClient;
+ ss->handshake = ssl_BeginClientHandshake;
+ ss->handshaking = sslHandshakingAsClient;
}
- ss->nextHandshake = 0;
- ss->securityHandshake = 0;
ssl_GetRecvBufLock(ss);
- status = ssl_InitGather(&ss->gs);
+ status = ssl3_InitGather(&ss->gs);
ssl_ReleaseRecvBufLock(ss);
+ if (status != SECSuccess)
+ goto loser;
ssl_GetSSL3HandshakeLock(ss);
ss->ssl3.hs.canFalseStart = PR_FALSE;
@@ -239,17 +191,21 @@ SSL_ResetHandshake(PRFileDesc *s, PRBool asServer)
/*
** Blow away old security state and get a fresh setup.
*/
- ssl_GetXmitBufLock(ss);
+ ssl_GetXmitBufLock(ss);
ssl_ResetSecurityInfo(&ss->sec, PR_TRUE);
status = ssl_CreateSecurityInfo(ss);
- ssl_ReleaseXmitBufLock(ss);
+ ssl_ReleaseXmitBufLock(ss);
ssl_ReleaseSSL3HandshakeLock(ss);
ssl_Release1stHandshakeLock(ss);
+ ssl3_DestroyRemoteExtensions(&ss->ssl3.hs.remoteExtensions);
+ ssl3_ResetExtensionData(&ss->xtnData);
+
if (!ss->TCPconnected)
- ss->TCPconnected = (PR_SUCCESS == ssl_DefGetpeername(ss, &addr));
+ ss->TCPconnected = (PR_SUCCESS == ssl_DefGetpeername(ss, &addr));
+loser:
SSL_UNLOCK_WRITER(ss);
SSL_UNLOCK_READER(ss);
@@ -265,28 +221,22 @@ SECStatus
SSL_ReHandshake(PRFileDesc *fd, PRBool flushCache)
{
sslSocket *ss;
- SECStatus rv;
-
+ SECStatus rv;
+
ss = ssl_FindSocket(fd);
if (!ss) {
- SSL_DBG(("%d: SSL[%d]: bad socket in RedoHandshake", SSL_GETPID(), fd));
- return SECFailure;
+ SSL_DBG(("%d: SSL[%d]: bad socket in RedoHandshake", SSL_GETPID(), fd));
+ return SECFailure;
}
if (!ss->opt.useSecurity)
- return SECSuccess;
-
+ return SECSuccess;
+
ssl_Get1stHandshakeLock(ss);
- /* SSL v2 protocol does not support subsequent handshakes. */
- if (ss->version < SSL_LIBRARY_VERSION_3_0) {
- PORT_SetError(SSL_ERROR_FEATURE_NOT_SUPPORTED_FOR_SSL2);
- rv = SECFailure;
- } else {
- ssl_GetSSL3HandshakeLock(ss);
- rv = ssl3_RedoHandshake(ss, flushCache); /* force full handshake. */
- ssl_ReleaseSSL3HandshakeLock(ss);
- }
+ ssl_GetSSL3HandshakeLock(ss);
+ rv = ssl3_RedoHandshake(ss, flushCache); /* force full handshake. */
+ ssl_ReleaseSSL3HandshakeLock(ss);
ssl_Release1stHandshakeLock(ss);
@@ -296,9 +246,10 @@ 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)
+SSL_IMPORT SECStatus
+SSL_ReHandshakeWithTimeout(PRFileDesc *fd,
+ PRBool flushCache,
+ PRIntervalTime timeout)
{
if (SECSuccess != ssl_SetTimeout(fd, timeout)) {
return SECFailure;
@@ -317,26 +268,26 @@ SSL_RedoHandshake(PRFileDesc *fd)
*/
SECStatus
SSL_HandshakeCallback(PRFileDesc *fd, SSLHandshakeCallback cb,
- void *client_data)
+ 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;
+ 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;
+ PORT_SetError(SEC_ERROR_INVALID_ARGS);
+ return SECFailure;
}
ssl_Get1stHandshakeLock(ss);
ssl_GetSSL3HandshakeLock(ss);
- ss->handshakeCallback = cb;
+ ss->handshakeCallback = cb;
ss->handshakeCallbackData = client_data;
ssl_ReleaseSSL3HandshakeLock(ss);
@@ -350,26 +301,26 @@ SSL_HandshakeCallback(PRFileDesc *fd, SSLHandshakeCallback cb,
*/
SECStatus
SSL_SetCanFalseStartCallback(PRFileDesc *fd, SSLCanFalseStartCallback cb,
- void *arg)
+ void *arg)
{
sslSocket *ss;
ss = ssl_FindSocket(fd);
if (!ss) {
- SSL_DBG(("%d: SSL[%d]: bad socket in SSL_SetCanFalseStartCallback",
- SSL_GETPID(), fd));
- return SECFailure;
+ SSL_DBG(("%d: SSL[%d]: bad socket in SSL_SetCanFalseStartCallback",
+ SSL_GETPID(), fd));
+ return SECFailure;
}
if (!ss->opt.useSecurity) {
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- return SECFailure;
+ PORT_SetError(SEC_ERROR_INVALID_ARGS);
+ return SECFailure;
}
ssl_Get1stHandshakeLock(ss);
ssl_GetSSL3HandshakeLock(ss);
- ss->canFalseStartCallback = cb;
+ ss->canFalseStartCallback = cb;
ss->canFalseStartCallbackData = arg;
ssl_ReleaseSSL3HandshakeLock(ss);
@@ -386,90 +337,81 @@ SSL_RecommendedCanFalseStart(PRFileDesc *fd, PRBool *canFalseStart)
*canFalseStart = PR_FALSE;
ss = ssl_FindSocket(fd);
if (!ss) {
- SSL_DBG(("%d: SSL[%d]: bad socket in SSL_RecommendedCanFalseStart",
- SSL_GETPID(), fd));
- return SECFailure;
+ SSL_DBG(("%d: SSL[%d]: bad socket in SSL_RecommendedCanFalseStart",
+ SSL_GETPID(), fd));
+ return SECFailure;
}
if (!ss->ssl3.initialized) {
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- return SECFailure;
- }
-
- if (ss->version < SSL_LIBRARY_VERSION_3_0) {
- PORT_SetError(SSL_ERROR_FEATURE_NOT_SUPPORTED_FOR_SSL2);
- return SECFailure;
+ PORT_SetError(SEC_ERROR_INVALID_ARGS);
+ return SECFailure;
}
/* Require a forward-secret key exchange. */
*canFalseStart = 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;
+ 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;
return SECSuccess;
}
-/* Try to make progress on an SSL handshake by attempting to read the
+/* 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
+** 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,
+** 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.
+** Application should use handshake completion callback to tell which.
*/
SECStatus
SSL_ForceHandshake(PRFileDesc *fd)
{
sslSocket *ss;
- SECStatus rv = SECFailure;
+ SECStatus rv = SECFailure;
ss = ssl_FindSocket(fd);
if (!ss) {
- SSL_DBG(("%d: SSL[%d]: bad socket in ForceHandshake",
- SSL_GETPID(), fd));
- return rv;
+ 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 (!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_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);
+ 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 {
- /* tried to force handshake on an SSL 2 socket that has
- ** already completed the handshake. */
- rv = SECSuccess; /* just pretend we did it. */
+ PORT_Assert(!ss->firstHsDone);
+ rv = ssl_Do1stHandshake(ss);
}
ssl_Release1stHandshakeLock(ss);
@@ -480,8 +422,9 @@ SSL_ForceHandshake(PRFileDesc *fd)
/*
** Same as above, but with an I/O timeout.
*/
-SSL_IMPORT SECStatus SSL_ForceHandshakeWithTimeout(PRFileDesc *fd,
- PRIntervalTime timeout)
+SSL_IMPORT SECStatus
+SSL_ForceHandshakeWithTimeout(PRFileDesc *fd,
+ PRIntervalTime timeout)
{
if (SECSuccess != ssl_SetTimeout(fd, timeout)) {
return SECFailure;
@@ -489,7 +432,6 @@ SSL_IMPORT SECStatus SSL_ForceHandshakeWithTimeout(PRFileDesc *fd,
return SSL_ForceHandshake(fd);
}
-
/************************************************************************/
/*
@@ -502,52 +444,63 @@ 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;
+ 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)
+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;
+ return rv;
PORT_Memcpy(b->buf + b->len, data, len);
b->len += len;
return SECSuccess;
}
+void
+sslBuffer_Clear(sslBuffer *b)
+{
+ if (b->len > 0) {
+ PORT_Free(b->buf);
+ b->buf = NULL;
+ b->len = 0;
+ b->space = 0;
+ }
+}
+
/*
** 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
+SECStatus
ssl_SaveWriteData(sslSocket *ss, const void *data, unsigned int len)
{
- SECStatus rv;
+ SECStatus rv;
- PORT_Assert( ss->opt.noLocks || ssl_HaveXmitBufLock(ss) );
+ 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));
+ SSL_GETPID(), ss->fd, len, ss->pendingBuf.len));
return rv;
}
@@ -557,25 +510,25 @@ ssl_SaveWriteData(sslSocket *ss, const void *data, unsigned int len)
** Returns count of the bytes sent, NOT a SECStatus.
** Caller must hold xmitBufLock
*/
-int
+int
ssl_SendSavedWriteData(sslSocket *ss)
{
- int rv = 0;
+ int rv = 0;
- PORT_Assert( ss->opt.noLocks || ssl_HaveXmitBufLock(ss) );
+ 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);
- }
+ 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;
}
@@ -589,19 +542,18 @@ ssl_SendSavedWriteData(sslSocket *ss)
**
** 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
+** The call to ssl3_GatherAppDataRecord may encounter handshake
** messages from a subsequent handshake.
**
-** This code is similar to, and easily confused with,
+** This code is similar to, and easily confused with,
** ssl_GatherRecord1stHandshake() in sslcon.c
*/
-static int
+static int
DoRecv(sslSocket *ss, unsigned char *out, int len, int flags)
{
- int rv;
- int amount;
- int available;
+ int rv;
+ int amount;
+ int available;
/* ssl3_GatherAppDataRecord may call ssl_FinishHandshake, which needs the
* 1stHandshakeLock. */
@@ -610,51 +562,45 @@ DoRecv(sslSocket *ss, unsigned char *out, int len, int flags)
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));
+ /* Wait for application data to arrive. */
+ rv = ssl3_GatherAppDataRecord(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));
}
if (IS_DTLS(ss) && (len < available)) {
@@ -671,13 +617,13 @@ DoRecv(sslSocket *ss, unsigned char *out, int len, int flags)
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;
+ 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));
+ SSL_GETPID(), ss->fd, amount, available));
PRINT_BUF(4, (ss, "DoRecv receiving plaintext:", out, amount));
done:
@@ -688,271 +634,14 @@ done:
/************************************************************************/
-/*
-** 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_ANSIX9_DSA_SIGNATURE: /* hah, signature, not a key? */
- case SEC_OID_X942_DIFFIE_HELMAN_KEY:
- keaType = kt_dh;
- break;
-#ifndef NSS_DISABLE_ECC
- case SEC_OID_ANSIX962_EC_PUBLIC_KEY:
- keaType = kt_ecdh;
- break;
-#endif /* NSS_DISABLE_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;
- }
- }
- if (kea == ssl_kea_dh || kea == ssl_kea_rsa) {
- if (ssl3_SelectDHParams(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);
+ ssl_GetXmitBufLock(ss);
status = sslBuffer_Grow(&ss->sec.writeBuf, 4096);
- ssl_ReleaseXmitBufLock(ss);
+ ssl_ReleaseXmitBufLock(ss);
return status;
}
@@ -960,50 +649,14 @@ ssl_CreateSecurityInfo(sslSocket *ss)
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.isServer = os->sec.isServer;
- ss->sec.peerCert = CERT_DupCertificate(os->sec.peerCert);
+ 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;
- }
-
- if (SECITEM_CopyItem(0, &ss->sec.sendSecret, &os->sec.sendSecret))
- goto loser;
- if (SECITEM_CopyItem(0, &ss->sec.rcvSecret, &os->sec.rcvSecret))
- 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;
+ goto loser;
- ss->sec.blockShift = os->sec.blockShift;
- ss->sec.blockSize = os->sec.blockSize;
+ ss->sec.cache = os->sec.cache;
+ ss->sec.uncache = os->sec.uncache;
return SECSuccess;
@@ -1014,61 +667,38 @@ loser:
/* Reset sec back to its initial state.
** Caller holds any relevant locks.
*/
-void
+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;
+ CERT_DestroyCertificate(sec->localCert);
+ sec->localCert = NULL;
}
if (sec->peerCert) {
- CERT_DestroyCertificate(sec->peerCert);
- sec->peerCert = NULL;
+ CERT_DestroyCertificate(sec->peerCert);
+ sec->peerCert = NULL;
}
if (sec->peerKey) {
- SECKEY_DestroyPublicKey(sec->peerKey);
- sec->peerKey = NULL;
+ SECKEY_DestroyPublicKey(sec->peerKey);
+ sec->peerKey = NULL;
}
/* cleanup the ci */
if (sec->ci.sid != NULL) {
- ssl_FreeSID(sec->ci.sid);
+ 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
+** Called from SSL_ResetHandshake (above), and
** from ssl_FreeSocket in sslsock.c
** Caller should hold relevant locks (e.g. XmitBufLock)
*/
-void
+void
ssl_DestroySecurityInfo(sslSecurityInfo *sec)
{
ssl_ResetSecurityInfo(sec, PR_FALSE);
@@ -1081,35 +711,35 @@ ssl_DestroySecurityInfo(sslSecurityInfo *sec)
/************************************************************************/
-int
+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;
+ if (ss->opt.handshakeAsServer) {
+ ss->handshake = ssl_BeginServerHandshake;
+ ss->handshaking = sslHandshakingAsServer;
} else {
- ss->securityHandshake = ssl2_BeginClientHandshake;
- ss->handshaking = sslHandshakingAsClient;
+ ss->handshake = ssl_BeginClientHandshake;
+ ss->handshaking = sslHandshakingAsClient;
}
/* connect to server */
rv = osfd->methods->connect(osfd, sa, ss->cTimeout);
if (rv == PR_SUCCESS) {
- ss->TCPconnected = 1;
+ 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;
- }
+ 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));
+ SSL_GETPID(), ss->fd, rv));
return rv;
}
@@ -1142,19 +772,18 @@ 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) {
+ if (!(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;
- }
+ /* 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);
+ (void)SSL3_SendAlert(ss, alert_warning, close_notify);
}
rv = ssl_DefClose(ss);
return rv;
@@ -1165,22 +794,21 @@ int
ssl_SecureShutdown(sslSocket *ss, int nsprHow)
{
PRFileDesc *osfd = ss->fd->lower;
- int rv;
- PRIntn sslHow = nsprHow + 1;
+ int rv;
+ PRIntn sslHow = nsprHow + 1;
if ((unsigned)nsprHow > PR_SHUTDOWN_BOTH) {
- PORT_SetError(PR_INVALID_ARGUMENT_ERROR);
- return PR_FAILURE;
+ 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) {
+ if ((sslHow & ssl_SHUTDOWN_SEND) != 0 &&
+ !(ss->shutdownHow & ssl_SHUTDOWN_SEND) &&
+ ss->firstHsDone &&
+ !ss->recvdCloseNotify &&
+ ss->ssl3.initialized) {
- (void) SSL3_SendAlert(ss, alert_warning, close_notify);
+ (void)SSL3_SendAlert(ss, alert_warning, close_notify);
}
rv = osfd->methods->shutdown(osfd, nsprHow);
@@ -1192,51 +820,56 @@ ssl_SecureShutdown(sslSocket *ss, int nsprHow)
/************************************************************************/
-
int
ssl_SecureRecv(sslSocket *ss, unsigned char *buf, int len, int flags)
{
- int rv = 0;
+ int rv = 0;
if (ss->shutdownHow & ssl_SHUTDOWN_RCV) {
- PORT_SetError(PR_SOCKET_SHUTDOWN_ERROR);
- return PR_FAILURE;
+ PORT_SetError(PR_SOCKET_SHUTDOWN_ERROR);
+ return PR_FAILURE;
}
if (flags & ~PR_MSG_PEEK) {
- PORT_SetError(PR_INVALID_ARGUMENT_ERROR);
- return PR_FAILURE;
+ 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);
- }
-
+ 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 (!PR_CLIST_IS_EMPTY(&ss->ssl3.hs.bufferedEarlyData)) {
+ PORT_Assert(ss->version >= SSL_LIBRARY_VERSION_TLS_1_3);
+ return tls13_Read0RttData(ss, buf, len);
+ }
+
/* 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);
+ ssl_Get1stHandshakeLock(ss);
+ if (ss->handshake) {
+ rv = ssl_Do1stHandshake(ss);
+ }
+ ssl_Release1stHandshakeLock(ss);
}
if (rv < 0) {
- return rv;
+ return rv;
}
- if (len == 0) return 0;
+ if (len == 0)
+ return 0;
- rv = DoRecv(ss, (unsigned char*) buf, len, flags);
+ 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()));
+ SSL_GETPID(), ss->fd, rv, PORT_GetError()));
return rv;
}
@@ -1253,97 +886,103 @@ 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));
+ SSL_GETPID(), ss->fd, len));
if (ss->shutdownHow & ssl_SHUTDOWN_SEND) {
- PORT_SetError(PR_SOCKET_SHUTDOWN_ERROR);
- rv = PR_FAILURE;
- goto done;
+ PORT_SetError(PR_SOCKET_SHUTDOWN_ERROR);
+ rv = PR_FAILURE;
+ goto done;
}
if (flags) {
- PORT_SetError(PR_INVALID_ARGUMENT_ERROR);
- rv = PR_FAILURE;
- goto done;
+ 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;
- }
+ 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;
+ goto done;
}
- if (len > 0)
- ss->writerThread = PR_GetCurrentThread();
- /* If any of these is non-zero, the initial handshake is not done. */
+ if (len > 0)
+ ss->writerThread = PR_GetCurrentThread();
+
+ /* Check to see if we can write even though we're not finished.
+ *
+ * Case 1: False start
+ * Case 2: TLS 1.3 0-RTT
+ */
if (!ss->firstHsDone) {
- PRBool falseStart = PR_FALSE;
- ssl_Get1stHandshakeLock(ss);
- if (ss->opt.enableFalseStart &&
- ss->version >= SSL_LIBRARY_VERSION_3_0) {
- ssl_GetSSL3HandshakeLock(ss);
- falseStart = ss->ssl3.hs.canFalseStart;
- ssl_ReleaseSSL3HandshakeLock(ss);
- }
- if (!falseStart &&
- (ss->handshake || ss->nextHandshake || ss->securityHandshake)) {
- rv = ssl_Do1stHandshake(ss);
- }
- ssl_Release1stHandshakeLock(ss);
+ PRBool falseStart = PR_FALSE;
+ ssl_Get1stHandshakeLock(ss);
+ if (ss->opt.enableFalseStart ||
+ (ss->opt.enable0RttData && !ss->sec.isServer)) {
+ ssl_GetSSL3HandshakeLock(ss);
+ /* The client can sometimes send before the handshake is fully
+ * complete. In TLS 1.2: false start; in TLS 1.3: 0-RTT. */
+ falseStart = ss->ssl3.hs.canFalseStart ||
+ ss->ssl3.hs.zeroRttState == ssl_0rtt_sent ||
+ ss->ssl3.hs.zeroRttState == ssl_0rtt_accepted;
+ ssl_ReleaseSSL3HandshakeLock(ss);
+ }
+ if (!falseStart && ss->handshake) {
+ rv = ssl_Do1stHandshake(ss);
+ }
+ ssl_Release1stHandshakeLock(ss);
}
if (rv < 0) {
- ss->writerThread = NULL;
- goto done;
+ 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;
+ rv = 0;
+ goto done;
}
PORT_Assert(buf != NULL);
if (!buf) {
- PORT_SetError(PR_INVALID_ARGUMENT_ERROR);
- rv = PR_FAILURE;
- goto done;
+ PORT_SetError(PR_INVALID_ARGUMENT_ERROR);
+ rv = PR_FAILURE;
+ goto done;
}
if (!ss->firstHsDone) {
- PORT_Assert(ss->version >= SSL_LIBRARY_VERSION_3_0);
#ifdef DEBUG
- ssl_GetSSL3HandshakeLock(ss);
- PORT_Assert(ss->ssl3.hs.canFalseStart);
- ssl_ReleaseSSL3HandshakeLock(ss);
+ ssl_GetSSL3HandshakeLock(ss);
+ PORT_Assert(!ss->sec.isServer &&
+ (ss->ssl3.hs.canFalseStart ||
+ ss->ssl3.hs.zeroRttState == ssl_0rtt_sent ||
+ ss->ssl3.hs.zeroRttState == ssl_0rtt_accepted));
+ ssl_ReleaseSSL3HandshakeLock(ss);
#endif
- SSL_TRC(3, ("%d: SSL[%d]: SecureSend: sending data due to false start",
- SSL_GETPID(), ss->fd));
+ SSL_TRC(3, ("%d: SSL[%d]: SecureSend: sending data due to false start",
+ SSL_GETPID(), ss->fd));
}
- /* 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);
+ rv = ssl3_SendApplicationData(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()));
+ 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));
+ SSL_TRC(2, ("%d: SSL[%d]: SecureSend: returning %d count",
+ SSL_GETPID(), ss->fd, rv));
}
return rv;
}
@@ -1358,12 +997,12 @@ 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;
+ SSL_DBG(("%d: SSL[%d]: bad socket in SSLBadCertHook",
+ SSL_GETPID(), fd));
+ return SECFailure;
}
ss->handleBadCert = f;
@@ -1380,24 +1019,24 @@ SSL_BadCertHook(PRFileDesc *fd, SSLBadCertHandler f, void *arg)
SECStatus
SSL_SetURL(PRFileDesc *fd, const char *url)
{
- sslSocket * ss = ssl_FindSocket(fd);
- SECStatus rv = SECSuccess;
+ 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_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 */
+ if (ss->url) {
+ PORT_Free((void *)ss->url); /* CONST */
}
ss->url = (const char *)PORT_Strdup(url);
- if ( ss->url == NULL ) {
- rv = SECFailure;
+ if (ss->url == NULL) {
+ rv = SECFailure;
}
ssl_ReleaseSSL3HandshakeLock(ss);
@@ -1412,7 +1051,7 @@ SSL_SetURL(PRFileDesc *fd, const char *url)
SECStatus
SSL_SetTrustAnchors(PRFileDesc *fd, CERTCertList *certList)
{
- sslSocket * ss = ssl_FindSocket(fd);
+ sslSocket *ss = ssl_FindSocket(fd);
CERTDistNames *names = NULL;
if (!certList) {
@@ -1420,9 +1059,9 @@ SSL_SetTrustAnchors(PRFileDesc *fd, CERTCertList *certList)
return SECFailure;
}
if (!ss) {
- SSL_DBG(("%d: SSL[%d]: bad socket in SSL_SetTrustAnchors",
- SSL_GETPID(), fd));
- return SECFailure;
+ SSL_DBG(("%d: SSL[%d]: bad socket in SSL_SetTrustAnchors",
+ SSL_GETPID(), fd));
+ return SECFailure;
}
names = CERT_DistNamesFromCertList(certList);
@@ -1449,14 +1088,14 @@ int
SSL_DataPending(PRFileDesc *fd)
{
sslSocket *ss;
- int rv = 0;
+ 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);
+ ssl_GetRecvBufLock(ss);
+ rv = ss->gs.writeOffset - ss->gs.readOffset;
+ ssl_ReleaseRecvBufLock(ss);
}
return rv;
@@ -1465,20 +1104,20 @@ SSL_DataPending(PRFileDesc *fd)
SECStatus
SSL_InvalidateSession(PRFileDesc *fd)
{
- sslSocket * ss = ssl_FindSocket(fd);
- SECStatus rv = SECFailure;
+ sslSocket *ss = ssl_FindSocket(fd);
+ SECStatus rv = SECFailure;
if (ss) {
- ssl_Get1stHandshakeLock(ss);
- ssl_GetSSL3HandshakeLock(ss);
+ ssl_Get1stHandshakeLock(ss);
+ ssl_GetSSL3HandshakeLock(ss);
- if (ss->sec.ci.sid && ss->sec.uncache) {
- ss->sec.uncache(ss->sec.ci.sid);
- rv = SECSuccess;
- }
+ if (ss->sec.ci.sid) {
+ ss->sec.uncache(ss->sec.ci.sid);
+ rv = SECSuccess;
+ }
- ssl_ReleaseSSL3HandshakeLock(ss);
- ssl_Release1stHandshakeLock(ss);
+ ssl_ReleaseSSL3HandshakeLock(ss);
+ ssl_Release1stHandshakeLock(ss);
}
return rv;
}
@@ -1486,32 +1125,26 @@ SSL_InvalidateSession(PRFileDesc *fd)
SECItem *
SSL_GetSessionID(PRFileDesc *fd)
{
- sslSocket * ss;
- SECItem * item = NULL;
+ 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);
+ 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;
+ 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;
}
@@ -1519,14 +1152,14 @@ SSL_GetSessionID(PRFileDesc *fd)
SECStatus
SSL_CertDBHandleSet(PRFileDesc *fd, CERTCertDBHandle *dbHandle)
{
- sslSocket * ss;
+ sslSocket *ss;
ss = ssl_FindSocket(fd);
if (!ss)
- return SECFailure;
+ return SECFailure;
if (!dbHandle) {
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- return SECFailure;
+ PORT_SetError(SEC_ERROR_INVALID_ARGS);
+ return SECFailure;
}
ss->dbHandle = dbHandle;
return SECSuccess;
@@ -1536,10 +1169,10 @@ SSL_CertDBHandleSet(PRFileDesc *fd, CERTCertDBHandle *dbHandle)
* this implementation exists to maintain link-time compatibility.
*/
int
-SSL_RestartHandshakeAfterCertReq(sslSocket * ss,
- CERTCertificate * cert,
- SECKEYPrivateKey * key,
- CERTCertificateList *certChain)
+SSL_RestartHandshakeAfterCertReq(sslSocket *ss,
+ CERTCertificate *cert,
+ SECKEYPrivateKey *key,
+ CERTCertificateList *certChain)
{
PORT_SetError(PR_NOT_IMPLEMENTED_ERROR);
return -1;
@@ -1549,7 +1182,7 @@ SSL_RestartHandshakeAfterCertReq(sslSocket * ss,
* this implementation exists to maintain link-time compatibility.
*/
int
-SSL_RestartHandshakeAfterServerCert(sslSocket * ss)
+SSL_RestartHandshakeAfterServerCert(sslSocket *ss)
{
PORT_SetError(PR_NOT_IMPLEMENTED_ERROR);
return -1;
@@ -1563,21 +1196,18 @@ SSL_AuthCertificateComplete(PRFileDesc *fd, PRErrorCode error)
sslSocket *ss = ssl_FindSocket(fd);
if (!ss) {
- SSL_DBG(("%d: SSL[%d]: bad socket in SSL_AuthCertificateComplete",
- SSL_GETPID(), fd));
- return SECFailure;
+ 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;
+ PORT_SetError(SEC_ERROR_INVALID_ARGS);
+ rv = SECFailure;
} else {
- rv = ssl3_AuthCertificateComplete(ss, error);
+ rv = ssl3_AuthCertificateComplete(ss, error);
}
ssl_Release1stHandshakeLock(ss);
@@ -1586,7 +1216,7 @@ SSL_AuthCertificateComplete(PRFileDesc *fd, PRErrorCode error)
}
/* For more info see ssl.h */
-SECStatus
+SECStatus
SSL_SNISocketConfigHook(PRFileDesc *fd, SSLSNISocketConfig func,
void *arg)
{
@@ -1594,9 +1224,9 @@ SSL_SNISocketConfigHook(PRFileDesc *fd, SSLSNISocketConfig func,
ss = ssl_FindSocket(fd);
if (!ss) {
- SSL_DBG(("%d: SSL[%d]: bad socket in SNISocketConfigHook",
- SSL_GETPID(), fd));
- return SECFailure;
+ SSL_DBG(("%d: SSL[%d]: bad socket in SNISocketConfigHook",
+ SSL_GETPID(), fd));
+ return SECFailure;
}
ss->sniSocketConfig = func;
diff --git a/nss/lib/ssl/sslsnce.c b/nss/lib/ssl/sslsnce.c
index f31b2e9..4a4005c 100644
--- a/nss/lib/ssl/sslsnce.c
+++ b/nss/lib/ssl/sslsnce.c
@@ -1,23 +1,23 @@
-/* This file implements the SERVER Session ID cache.
+/* 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/. */
-/* Note: ssl_FreeSID() in sslnonce.c gets used for both client and server
+/* 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.
+ * 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.
+ * 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.
@@ -33,10 +33,10 @@
* sidCacheSet sidCacheSets[ numSIDCacheSets ];
* sidCacheEntry sidCacheData[ numSIDCacheEntries];
* certCacheEntry certCacheData[numCertCacheEntries];
- * SSLWrappedSymWrappingKey keyCacheData[kt_kea_size][SSL_NUM_WRAP_MECHS];
+ * SSLWrappedSymWrappingKey keyCacheData[ssl_auth_size][SSL_NUM_WRAP_MECHS];
* PRUint8 keyNameSuffix[SESS_TICKET_KEY_VAR_NAME_LEN]
- * encKeyCacheEntry ticketEncKey; // Wrapped in non-bypass mode
- * encKeyCacheEntry ticketMacKey; // Wrapped in non-bypass mode
+ * encKeyCacheEntry ticketEncKey; // Wrapped
+ * encKeyCacheEntry ticketMacKey; // Wrapped
* PRBool ticketKeysValid;
* sidCacheLock srvNameCacheLock;
* srvNameCacheEntry srvNameData[ numSrvNameCacheEntries ];
@@ -44,7 +44,7 @@
*/
#include "seccomon.h"
-#if defined(XP_UNIX) || defined(XP_WIN32) || defined (XP_OS2) || defined(XP_BEOS)
+#if defined(XP_UNIX) || defined(XP_WIN32) || defined(XP_OS2) || defined(XP_BEOS)
#include "cert.h"
#include "ssl.h"
@@ -53,12 +53,8 @@
#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>
@@ -78,156 +74,142 @@
#include "win32err.h"
#endif
-#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 */
+ /* 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 authType;
+ /* 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 */
-
-/* 54 */ 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 */
-/*108 */} 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;
+ /* 2 */ ssl3CipherSuite cipherSuite;
+ /* 2 */ PRUint16 compression; /* SSLCompressionMethod */
+
+ /* 54 */ ssl3SidKeys keys; /* keys, wrapped as needed. */
+
+ /* 4 */ PRUint32 masterWrapMech;
+ /* 4 */ PRInt32 certIndex;
+ /* 4 */ PRInt32 srvNameIndex;
+ /* 32 */ PRUint8 srvNameHash[SHA256_LENGTH]; /* SHA256 name hash */
+ /* 2 */ PRUint16 certTypeArgs;
+/*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 */
+ 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;
+ PRUint32 timeStamp;
+ sslMutex mutex;
+ sslPID pid;
};
typedef struct sidCacheLockStr sidCacheLock;
struct sidCacheSetStr {
- PRIntn next;
+ PRIntn next;
};
typedef struct sidCacheSetStr sidCacheSet;
struct encKeyCacheEntryStr {
- PRUint8 bytes[512];
- PRInt32 length;
+ PRUint8 bytes[512];
+ PRInt32 length;
};
typedef struct encKeyCacheEntryStr encKeyCacheEntry;
-#define SSL_MAX_DNS_HOST_NAME 1024
+#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 */
+ 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 cacheMemSize;
- PRUint32 numSIDCacheLocks;
- PRUint32 numSIDCacheSets;
- PRUint32 numSIDCacheSetsPerLock;
+ PRUint32 numSIDCacheLocks;
+ PRUint32 numSIDCacheSets;
+ PRUint32 numSIDCacheSetsPerLock;
- PRUint32 numSIDCacheEntries;
- PRUint32 sidCacheSize;
+ PRUint32 numSIDCacheEntries;
+ PRUint32 sidCacheSize;
- PRUint32 numCertCacheEntries;
- PRUint32 certCacheSize;
+ PRUint32 numCertCacheEntries;
+ PRUint32 certCacheSize;
- PRUint32 numKeyCacheEntries;
- PRUint32 keyCacheSize;
+ PRUint32 numKeyCacheEntries;
+ PRUint32 keyCacheSize;
- PRUint32 numSrvNameCacheEntries;
- PRUint32 srvNameCacheSize;
+ PRUint32 numSrvNameCacheEntries;
+ PRUint32 srvNameCacheSize;
- PRUint32 ssl2Timeout;
- PRUint32 ssl3Timeout;
+ PRUint32 ssl3Timeout;
- PRUint32 numSIDCacheLocksInitialized;
+ PRUint32 numSIDCacheLocksInitialized;
/* These values are volatile, and are accessed through sharedCache-> */
- PRUint32 nextCertCacheEntry; /* certCacheLock protects */
- PRBool stopPolling;
- PRBool everInherited;
+ 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;
- PRUint8 * ticketKeyNameSuffix;
- encKeyCacheEntry * ticketEncKey;
- encKeyCacheEntry * ticketMacKey;
- PRUint32 * ticketKeysValid;
- srvNameCacheEntry * srvNameCacheData;
+ sidCacheLock *sidCacheLocks;
+ sidCacheLock *keyCacheLock;
+ sidCacheLock *certCacheLock;
+ sidCacheLock *srvNameCacheLock;
+ sidCacheSet *sidCacheSets;
+ sidCacheEntry *sidCacheData;
+ certCacheEntry *certCacheData;
+ SSLWrappedSymWrappingKey *keyCacheData;
+ PRUint8 *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;
+ char *cacheMem;
+ struct cacheDescStr *sharedCache; /* shared copy of this struct */
+ PRFileMap *cacheMemMap;
+ PRThread *poller;
+ PRUint32 mutexTimeout;
+ PRBool shared;
};
typedef struct cacheDescStr cacheDesc;
@@ -235,48 +217,41 @@ static cacheDesc globalCache;
static const char envVarName[] = { SSL_ENV_VAR_NAME };
-static PRBool isMultiProcess = PR_FALSE;
-
+static PRBool isMultiProcess = PR_FALSE;
-#define DEF_SID_CACHE_ENTRIES 10000
+#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 DEF_KEY_CACHE_ENTRIES 250
+#define DEF_NAME_CACHE_ENTRIES 1000
-#define SID_CACHE_ENTRIES_PER_SET 128
-#define SID_ALIGNMENT 16
+#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 */
+#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 */
+#define MAX_SID_CACHE_LOCKS 8 /* two FDs per lock */
#elif defined(OSF1)
-#define MAX_SID_CACHE_LOCKS 16 /* one FD per lock */
+#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)))
-
+#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;
+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,
+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;
@@ -296,29 +271,28 @@ typedef struct inheritanceStr inheritance;
#endif /* XP_UNIX || XP_BEOS */
-
/************************************************************************/
static PRUint32
LockSidCacheLock(sidCacheLock *lock, PRUint32 now)
{
- SECStatus rv = sslMutex_Lock(&lock->mutex);
+ SECStatus rv = sslMutex_Lock(&lock->mutex);
if (rv != SECSuccess)
- return 0;
+ return 0;
if (!now)
- now = ssl_Time();
+ now = ssl_Time();
lock->timeStamp = now;
- lock->pid = myPid;
+ lock->pid = myPid;
return now;
}
static SECStatus
UnlockSidCacheLock(sidCacheLock *lock)
{
- SECStatus rv;
+ SECStatus rv;
lock->pid = 0;
- rv = sslMutex_Unlock(&lock->mutex);
+ rv = sslMutex_Unlock(&lock->mutex);
return rv;
}
@@ -326,8 +300,8 @@ UnlockSidCacheLock(sidCacheLock *lock)
static PRUint32
LockSet(cacheDesc *cache, PRUint32 set, PRUint32 now)
{
- PRUint32 lockNum = set % cache->numSIDCacheLocks;
- sidCacheLock * lock = cache->sidCacheLocks + lockNum;
+ PRUint32 lockNum = set % cache->numSIDCacheLocks;
+ sidCacheLock *lock = cache->sidCacheLocks + lockNum;
return LockSidCacheLock(lock, now);
}
@@ -335,28 +309,27 @@ LockSet(cacheDesc *cache, PRUint32 set, PRUint32 now)
static SECStatus
UnlockSet(cacheDesc *cache, PRUint32 set)
{
- PRUint32 lockNum = set % cache->numSIDCacheLocks;
- sidCacheLock * lock = cache->sidCacheLocks + lockNum;
+ 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)
+CacheCert(cacheDesc *cache, CERTCertificate *cert, sidCacheEntry *sce)
{
- PRUint32 now;
- certCacheEntry cce;
+ 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;
+ (cert->derCert.data == NULL)) {
+ PORT_SetError(SEC_ERROR_INVALID_ARGS);
+ return 0;
}
cce.sessionIDLength = sce->sessionIDLength;
@@ -369,24 +342,23 @@ CacheCert(cacheDesc * cache, CERTCertificate *cert, sidCacheEntry *sce)
now = LockSidCacheLock(cache->certCacheLock, 0);
if (now) {
- /* Find where to place the next cert cache entry. */
- cacheDesc * sharedCache = cache->sharedCache;
- PRUint32 ndx = sharedCache->nextCertCacheEntry;
+ /* Find where to place the next cert cache entry. */
+ cacheDesc *sharedCache = cache->sharedCache;
+ PRUint32 ndx = sharedCache->nextCertCacheEntry;
- /* write the entry */
- cache->certCacheData[ndx] = cce;
+ /* write the entry */
+ cache->certCacheData[ndx] = cce;
- /* remember where we put it. */
- sce->u.ssl3.certIndex = ndx;
+ /* remember where we put it. */
+ sce->u.ssl3.certIndex = ndx;
- /* update the "next" cache entry index */
- sharedCache->nextCertCacheEntry =
- (ndx + 1) % cache->numCertCacheEntries;
+ /* update the "next" cache entry index */
+ sharedCache->nextCertCacheEntry =
+ (ndx + 1) % cache->numCertCacheEntries;
- UnlockSidCacheLock(cache->certCacheLock);
+ UnlockSidCacheLock(cache->certCacheLock);
}
return now;
-
}
/* Server configuration hash tables need to account the SECITEM.type
@@ -395,9 +367,9 @@ static PLHashNumber
Get32BitNameHash(const SECItem *name)
{
PLHashNumber rv = SECITEM_Hash(name);
-
+
PRUint8 *rvc = (PRUint8 *)&rv;
- rvc[ name->len % sizeof(rv) ] ^= name->type;
+ rvc[name->len % sizeof(rv)] ^= name->type;
return rv;
}
@@ -405,27 +377,23 @@ Get32BitNameHash(const SECItem *name)
/* Put a name in the cache. Update the cert index in the sce.
*/
static PRUint32
-CacheSrvName(cacheDesc * cache, SECItem *name, sidCacheEntry *sce)
+CacheSrvName(cacheDesc *cache, SECItem *name, sidCacheEntry *sce)
{
- PRUint32 now;
- PRUint32 ndx;
- srvNameCacheEntry snce;
+ 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;
+ 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 */
@@ -441,7 +409,7 @@ CacheSrvName(cacheDesc * cache, SECItem *name, sidCacheEntry *sce)
/* Copy hash into sid hash */
PORT_Memcpy(sce->u.ssl3.srvNameHash, snce.nameHash, SHA256_LENGTH);
}
- UnlockSidCacheLock(cache->srvNameCacheLock);
+ UnlockSidCacheLock(cache->srvNameCacheLock);
}
return now;
}
@@ -449,73 +417,47 @@ CacheSrvName(cacheDesc * cache, SECItem *name, sidCacheEntry *sce)
/*
** Convert local SID to shared memory one
*/
-static void
+static void
ConvertFromSID(sidCacheEntry *to, sslSessionID *from)
{
- to->valid = 1;
+ 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 = (PRUint16)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));
- }
+ to->addr = from->addr;
+ to->creationTime = from->creationTime;
+ to->lastAccessTime = from->lastAccessTime;
+ to->expirationTime = from->expirationTime;
+ to->authType = from->authType;
+ to->authKeyBits = from->authKeyBits;
+ to->keaType = from->keaType;
+ to->keaKeyBits = from->keaKeyBits;
+
+ to->u.ssl3.cipherSuite = from->u.ssl3.cipherSuite;
+ to->u.ssl3.compression = (PRUint16)from->u.ssl3.compression;
+ to->u.ssl3.keys = from->u.ssl3.keys;
+ to->u.ssl3.masterWrapMech = from->u.ssl3.masterWrapMech;
+ 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);
+ to->u.ssl3.certTypeArgs = 0U;
+ switch (from->authType) {
+ case ssl_auth_ecdsa:
+ case ssl_auth_ecdh_rsa:
+ case ssl_auth_ecdh_ecdsa:
+ PORT_Assert(from->certType.namedCurve);
+ to->u.ssl3.certTypeArgs =
+ (PRUint16)from->certType.namedCurve->name;
+ break;
+ default:
+ break;
+ }
+
+ 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));
}
/*
@@ -523,144 +465,106 @@ ConvertFromSID(sidCacheEntry *to, sslSessionID *from)
** This is only called from ServerSessionIDLookup().
*/
static sslSessionID *
-ConvertToSID(sidCacheEntry * from,
- certCacheEntry * pcce,
+ConvertToSID(sidCacheEntry *from,
+ certCacheEntry *pcce,
srvNameCacheEntry *psnce,
- CERTCertDBHandle * dbHandle)
+ CERTCertDBHandle *dbHandle)
{
sslSessionID *to;
- PRUint16 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;
- }
+ return 0;
+ }
+
+ 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;
+ 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);
+ 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;
+ /* 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->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.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;
+ 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;
+ if (from->u.ssl3.certIndex != -1 && pcce) {
+ SECItem derCert;
- derCert.len = pcce->certLength;
- derCert.data = pcce->cert;
+ 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->peerCert = CERT_NewTempCertificate(dbHandle, &derCert, NULL,
+ PR_FALSE, PR_TRUE);
+ if (to->peerCert == NULL)
+ goto loser;
+ }
+ to->certType.authType = from->authType;
+ switch (from->authType) {
+ case ssl_auth_ecdsa:
+ case ssl_auth_ecdh_rsa:
+ case ssl_auth_ecdh_ecdsa:
+ to->certType.namedCurve =
+ ssl_LookupNamedGroup((SSLNamedGroup)from->u.ssl3.certTypeArgs);
+ break;
+ default:
+ break;
}
- 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;
+ 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->authType = from->authType;
+ to->authKeyBits = from->authKeyBits;
+ to->keaType = from->keaType;
+ to->keaKeyBits = from->keaKeyBits;
return to;
- loser:
+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);
+ 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
+static PRUint32
SIDindex(cacheDesc *cache, const PRIPv6Addr *addr, PRUint8 *s, unsigned nl)
{
PRUint32 rv;
@@ -668,18 +572,16 @@ SIDindex(cacheDesc *cache, const PRIPv6Addr *addr, PRUint8 *s, unsigned nl)
memset(x, 0, sizeof x);
if (nl > sizeof x)
- 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;
+ 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!
@@ -688,45 +590,45 @@ SIDindex(cacheDesc *cache, const PRIPv6Addr *addr, PRUint8 *s, unsigned nl)
static sidCacheEntry *
FindSID(cacheDesc *cache, PRUint32 setNum, PRUint32 now,
const PRIPv6Addr *addr, unsigned char *sessionID,
- unsigned sessionIDLength)
+ unsigned sessionIDLength)
{
- PRUint32 ndx = cache->sidCacheSets[setNum].next;
- int i;
+ PRUint32 ndx = cache->sidCacheSets[setNum].next;
+ int i;
- sidCacheEntry * set = cache->sidCacheData +
- (setNum * SID_CACHE_ENTRIES_PER_SET);
+ 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;
- }
+ 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);
@@ -736,245 +638,206 @@ FindSID(cacheDesc *cache, PRUint32 setNum, PRUint32 now,
/************************************************************************/
/* 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
+ * 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)
+ unsigned char *sessionID,
+ unsigned int sessionIDLength,
+ CERTCertDBHandle *dbHandle)
{
- sslSessionID * sid = 0;
- sidCacheEntry * psce;
- certCacheEntry *pcce = 0;
+ sslSessionID *sid = 0;
+ sidCacheEntry *psce;
+ certCacheEntry *pcce = 0;
srvNameCacheEntry *psnce = 0;
- cacheDesc * cache = &globalCache;
- PRUint32 now;
- PRUint32 set;
- PRInt32 cndx;
- sidCacheEntry sce;
- certCacheEntry cce;
+ 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;
+ 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);
+ 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 {
- /* what the ??. Didn't get the cert cache lock.
- ** Don't invalidate the SID cache entry, but don't find it.
+ /* The cert doesen't match the SID cache entry,
+ ** so invalidate the SID cache entry.
*/
- PORT_Assert(!("Didn't get cert Cache Lock!"));
+ 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);
+ }
+ 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 {
- /* what the ??. Didn't get the cert cache lock.
- ** Don't invalidate the SID cache entry, but don't find it.
+ /* The name doesen't match the SID cache entry,
+ ** so invalidate the SID cache entry.
*/
- PORT_Assert(!("Didn't get name Cache Lock!"));
+ 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 */
- }
+ 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);
+ /* 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.
+** Place a sid into the cache, if it isn't already there.
*/
-static void
+static void
ServerSessionIDCache(sslSessionID *sid)
{
sidCacheEntry sce;
- PRUint32 now = 0;
- PRUint16 version = sid->version;
- cacheDesc * cache = &globalCache;
+ PRUint32 now = 0;
+ cacheDesc *cache = &globalCache;
- if ((version >= SSL_LIBRARY_VERSION_3_0) &&
- (sid->u.ssl3.sessionIDLength == 0)) {
- return;
+ if (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);
- }
- }
+ PRUint32 set;
+ SECItem *name;
+
+ PORT_Assert(sid->creationTime != 0);
+ if (!sid->creationTime)
+ sid->lastAccessTime = sid->creationTime = ssl_Time();
+ /* 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);
+
+ 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;
+ 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;
+ /* Write out new cache entry */
+ cache->sidCacheData[ndx] = sce;
- cache->sidCacheSets[set].next =
- (next + 1) % SID_CACHE_ENTRIES_PER_SET;
+ cache->sidCacheSets[set].next =
+ (next + 1) % SID_CACHE_ENTRIES_PER_SET;
- UnlockSet(cache, set);
- sid->cached = in_server_cache;
- }
+ 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.
+** ssl_sid_uncache. This invalidates the referenced cache entry.
*/
-static void
+static void
ServerSessionIDUncache(sslSessionID *sid)
{
- cacheDesc * cache = &globalCache;
- PRUint8 * sessionID;
- unsigned int sessionIDLength;
- PRErrorCode err;
- PRUint32 set;
- PRUint32 now;
+ 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.
+ 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));
- }
+ 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);
+ psce = FindSID(cache, set, now, &sid->addr, sessionID, sessionIDLength);
+ if (psce) {
+ psce->valid = 0;
+ }
+ UnlockSet(cache, set);
}
sid->cached = invalid_cache;
PORT_SetError(err);
@@ -985,7 +848,8 @@ ServerSessionIDUncache(sslSessionID *sid)
#define INCL_DOSPROCESS
#include <os2.h>
-long gettid(void)
+long
+gettid(void)
{
PTIB ptib;
PPIB ppib;
@@ -1000,59 +864,59 @@ 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->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;
+ 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)
+ int maxSrvNameCacheEntries, PRUint32 ssl3_timeout,
+ const char *directory, PRBool shared)
{
- ptrdiff_t ptr;
+ 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) ) {
+ 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;
+ /* Already done */
+ return SECSuccess;
}
/* make sure loser can clean up properly */
cache->shared = shared;
- cache->cacheMem = cacheMem = NULL;
+ cache->cacheMem = cacheMem = NULL;
cache->cacheMemMap = cacheMemMap = NULL;
cache->sharedCache = (cacheDesc *)0;
@@ -1063,71 +927,71 @@ InitCache(cacheDesc *cache, int maxCacheEntries, int maxCertCacheEntries,
cache->poller = NULL;
cache->mutexTimeout = 0;
- cache->numSIDCacheEntries = maxCacheEntries ? maxCacheEntries
+ cache->numSIDCacheEntries = maxCacheEntries ? maxCacheEntries
: DEF_SID_CACHE_ENTRIES;
- cache->numSIDCacheSets =
- SID_HOWMANY(cache->numSIDCacheEntries, SID_CACHE_ENTRIES_PER_SET);
+ cache->numSIDCacheSets =
+ SID_HOWMANY(cache->numSIDCacheEntries, SID_CACHE_ENTRIES_PER_SET);
- cache->numSIDCacheEntries =
- cache->numSIDCacheSets * 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->numSIDCacheLocks =
+ PR_MIN(cache->numSIDCacheSets, ssl_max_sid_cache_locks);
- cache->numSIDCacheSetsPerLock =
- SID_HOWMANY(cache->numSIDCacheSets, cache->numSIDCacheLocks);
+ cache->numSIDCacheSetsPerLock =
+ SID_HOWMANY(cache->numSIDCacheSets, cache->numSIDCacheLocks);
- cache->numCertCacheEntries = (maxCertCacheEntries > 0) ?
- maxCertCacheEntries : 0;
- cache->numSrvNameCacheEntries = (maxSrvNameCacheEntries >= 0) ?
- maxSrvNameCacheEntries : DEF_NAME_CACHE_ENTRIES;
+ 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;
+ 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;
+ 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;
+ cache->sidCacheSets = (sidCacheSet *)ptr;
ptr = (ptrdiff_t)(cache->sidCacheSets + cache->numSIDCacheSets);
ptr = SID_ROUNDUP(ptr, SID_ALIGNMENT);
- cache->sidCacheData = (sidCacheEntry *)ptr;
+ 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;
+ 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;
+ 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->keyCacheData = (SSLWrappedSymWrappingKey *)ptr;
+ cache->certCacheSize =
+ (char *)cache->keyCacheData - (char *)cache->certCacheData;
- cache->numKeyCacheEntries = kt_kea_size * SSL_NUM_WRAP_MECHS;
+ cache->numKeyCacheEntries = ssl_auth_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->keyCacheSize = (char *)ptr - (char *)cache->keyCacheData;
cache->ticketKeyNameSuffix = (PRUint8 *)ptr;
ptr = (ptrdiff_t)(cache->ticketKeyNameSuffix +
- SESS_TICKET_KEY_VAR_NAME_LEN);
+ SESS_TICKET_KEY_VAR_NAME_LEN);
ptr = SID_ROUNDUP(ptr, SID_ALIGNMENT);
cache->ticketEncKey = (encKeyCacheEntry *)ptr;
@@ -1150,66 +1014,54 @@ InitCache(cacheDesc *cache, int maxCacheEntries, int maxCertCacheEntries,
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;
+ 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;
+ cache->ssl3Timeout = DEF_SSL3_TIMEOUT;
}
if (shared) {
- /* Create file names */
+/* 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);
+ /* 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());
+ 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());
+ 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;
- }
+ if (!cfn) {
+ goto loser;
+ }
- /* Create cache */
- cacheMemMap = PR_OpenAnonFileMap(cfn, cache->cacheMemSize,
- PR_PROT_READWRITE);
+ /* Create cache */
+ cacheMemMap = PR_OpenAnonFileMap(cfn, cache->cacheMemSize,
+ PR_PROT_READWRITE);
- PR_smprintf_free(cfn);
- if(!cacheMemMap) {
- goto loser;
- }
+ PR_smprintf_free(cfn);
+ if (!cacheMemMap) {
+ goto loser;
+ }
cacheMem = PR_MemMap(cacheMemMap, 0, cache->cacheMemSize);
} else {
cacheMem = PORT_Alloc(cache->cacheMemSize);
}
-
- if (! cacheMem) {
+
+ if (!cacheMem) {
goto loser;
}
@@ -1221,53 +1073,40 @@ InitCache(cacheDesc *cache, int maxCacheEntries, int maxCertCacheEntries,
/* save private copies of these values */
cache->cacheMemMap = cacheMemMap;
- cache->cacheMem = cacheMem;
+ cache->cacheMem = cacheMem;
cache->sharedCache = (cacheDesc *)cacheMem;
- /* Fix pointers in our private copy of cache descriptor to point to
- ** spaces in shared memory
+ /* Fix pointers in our private copy of cache descriptor to point to
+ ** spaces in shared memory
*/
- cache->sidCacheLocks = (sidCacheLock *)
- (cache->cacheMem + (ptrdiff_t)cache->sidCacheLocks);
- cache->keyCacheLock = (sidCacheLock *)
- (cache->cacheMem + (ptrdiff_t)cache->keyCacheLock);
- cache->certCacheLock = (sidCacheLock *)
- (cache->cacheMem + (ptrdiff_t)cache->certCacheLock);
- cache->srvNameCacheLock = (sidCacheLock *)
- (cache->cacheMem + (ptrdiff_t)cache->srvNameCacheLock);
- cache->sidCacheSets = (sidCacheSet *)
- (cache->cacheMem + (ptrdiff_t)cache->sidCacheSets);
- cache->sidCacheData = (sidCacheEntry *)
- (cache->cacheMem + (ptrdiff_t)cache->sidCacheData);
- cache->certCacheData = (certCacheEntry *)
- (cache->cacheMem + (ptrdiff_t)cache->certCacheData);
- cache->keyCacheData = (SSLWrappedSymWrappingKey *)
- (cache->cacheMem + (ptrdiff_t)cache->keyCacheData);
- cache->ticketKeyNameSuffix = (PRUint8 *)
- (cache->cacheMem + (ptrdiff_t)cache->ticketKeyNameSuffix);
- cache->ticketEncKey = (encKeyCacheEntry *)
- (cache->cacheMem + (ptrdiff_t)cache->ticketEncKey);
- cache->ticketMacKey = (encKeyCacheEntry *)
- (cache->cacheMem + (ptrdiff_t)cache->ticketMacKey);
- cache->ticketKeysValid = (PRUint32 *)
- (cache->cacheMem + (ptrdiff_t)cache->ticketKeysValid);
- cache->srvNameCacheData = (srvNameCacheEntry *)
- (cache->cacheMem + (ptrdiff_t)cache->srvNameCacheData);
+ cache->sidCacheLocks = (sidCacheLock *)(cache->cacheMem + (ptrdiff_t)cache->sidCacheLocks);
+ cache->keyCacheLock = (sidCacheLock *)(cache->cacheMem + (ptrdiff_t)cache->keyCacheLock);
+ cache->certCacheLock = (sidCacheLock *)(cache->cacheMem + (ptrdiff_t)cache->certCacheLock);
+ cache->srvNameCacheLock = (sidCacheLock *)(cache->cacheMem + (ptrdiff_t)cache->srvNameCacheLock);
+ cache->sidCacheSets = (sidCacheSet *)(cache->cacheMem + (ptrdiff_t)cache->sidCacheSets);
+ cache->sidCacheData = (sidCacheEntry *)(cache->cacheMem + (ptrdiff_t)cache->sidCacheData);
+ cache->certCacheData = (certCacheEntry *)(cache->cacheMem + (ptrdiff_t)cache->certCacheData);
+ cache->keyCacheData = (SSLWrappedSymWrappingKey *)(cache->cacheMem + (ptrdiff_t)cache->keyCacheData);
+ cache->ticketKeyNameSuffix = (PRUint8 *)(cache->cacheMem + (ptrdiff_t)cache->ticketKeyNameSuffix);
+ cache->ticketEncKey = (encKeyCacheEntry *)(cache->cacheMem + (ptrdiff_t)cache->ticketEncKey);
+ cache->ticketMacKey = (encKeyCacheEntry *)(cache->cacheMem + (ptrdiff_t)cache->ticketMacKey);
+ cache->ticketKeysValid = (PRUint32 *)(cache->cacheMem + (ptrdiff_t)cache->ticketKeysValid);
+ cache->srvNameCacheData = (srvNameCacheEntry *)(cache->cacheMem + (ptrdiff_t)cache->srvNameCacheData);
/* 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;
- }
+ 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;
+ pLock->pid = 0;
}
cache->numSIDCacheLocksInitialized = locks_initialized;
@@ -1275,6 +1114,7 @@ InitCache(cacheDesc *cache, int maxCacheEntries, int maxCertCacheEntries,
loser:
CloseCache(cache);
+ PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
return SECFailure;
}
@@ -1294,8 +1134,8 @@ SSL_SetMaxServerCacheLocks(PRUint32 maxLocks)
** the maximum, other than trial and error.
*/
if (maxLocks < 3) {
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- return SECFailure;
+ 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. */
@@ -1304,13 +1144,12 @@ SSL_SetMaxServerCacheLocks(PRUint32 maxLocks)
static SECStatus
ssl_ConfigServerSessionIDCacheInstanceWithOpt(cacheDesc *cache,
- PRUint32 ssl2_timeout,
- PRUint32 ssl3_timeout,
- const char * directory,
+ PRUint32 ssl3_timeout,
+ const char *directory,
PRBool shared,
- int maxCacheEntries,
- int maxCertCacheEntries,
- int maxSrvNameCacheEntries)
+ int maxCacheEntries,
+ int maxCertCacheEntries,
+ int maxSrvNameCacheEntries)
{
SECStatus rv;
@@ -1320,52 +1159,49 @@ ssl_ConfigServerSessionIDCacheInstanceWithOpt(cacheDesc *cache,
rv = ssl_Init();
if (rv != SECSuccess) {
- return rv;
+ return rv;
}
myPid = SSL_GETPID();
if (!directory) {
- directory = DEFAULT_CACHE_DIRECTORY;
+ directory = DEFAULT_CACHE_DIRECTORY;
}
rv = InitCache(cache, maxCacheEntries, maxCertCacheEntries,
- maxSrvNameCacheEntries, ssl2_timeout, ssl3_timeout,
- directory, shared);
+ maxSrvNameCacheEntries, ssl3_timeout, directory, shared);
if (rv) {
- SET_ERROR_CODE
- return SECFailure;
+ return SECFailure;
}
- ssl_sid_lookup = ServerSessionIDLookup;
- ssl_sid_cache = ServerSessionIDCache;
+ 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)
+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,
+ maxCacheEntries,
-1, -1);
}
SECStatus
-SSL_ConfigServerSessionIDCache( int maxCacheEntries,
- PRUint32 ssl2_timeout,
- PRUint32 ssl3_timeout,
- const char * directory)
+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);
+ return SSL_ConfigServerSessionIDCacheInstance(&globalCache,
+ maxCacheEntries, ssl2_timeout, ssl3_timeout, directory, PR_FALSE);
}
SECStatus
@@ -1390,56 +1226,55 @@ SSL_ShutdownServerSessionIDCache(void)
* 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)
+ssl_ConfigMPServerSIDCacheWithOpt(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;
+ char *envValue;
+ char *inhValue;
+ cacheDesc *cache = &globalCache;
+ PRUint32 fmStrLen;
+ SECStatus result;
+ PRStatus prStatus;
+ SECStatus putEnvFailed;
inheritance inherit;
- char fmString[PR_FILEMAP_STRING_BUFSIZE];
+ 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)
+ ssl3_timeout, directory, PR_TRUE,
+ maxCacheEntries, maxCacheEntries, maxSrvNameCacheEntries);
+ if (result != SECSuccess)
return result;
- prStatus = PR_ExportFileMapAsString(cache->cacheMemMap,
+ prStatus = PR_ExportFileMapAsString(cache->cacheMemMap,
sizeof fmString, fmString);
if ((prStatus != PR_SUCCESS) || !(fmStrLen = strlen(fmString))) {
- SET_ERROR_CODE
- return SECFailure;
+ PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
+ return SECFailure;
}
- inherit.cacheMemSize = cache->cacheMemSize;
- inherit.fmStrLen = fmStrLen;
+ inherit.cacheMemSize = cache->cacheMemSize;
+ inherit.fmStrLen = fmStrLen;
inhValue = BTOA_DataToAscii((unsigned char *)&inherit, sizeof inherit);
if (!inhValue || !strlen(inhValue)) {
- SET_ERROR_CODE
- return SECFailure;
+ PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
+ return SECFailure;
}
envValue = PR_smprintf("%s,%s", inhValue, fmString);
if (!envValue || !strlen(envValue)) {
- SET_ERROR_CODE
- return SECFailure;
+ PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
+ return SECFailure;
}
PORT_Free(inhValue);
putEnvFailed = (SECStatus)NSS_PutEnv(envVarName, envValue);
PR_smprintf_free(envValue);
if (putEnvFailed) {
- SET_ERROR_CODE
+ PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
result = SECFailure;
}
@@ -1454,13 +1289,12 @@ ssl_ConfigMPServerSIDCacheWithOpt( PRUint32 ssl2_timeout,
* if the cache will be shared by multiple processes.
*/
SECStatus
-SSL_ConfigMPServerSIDCache( int maxCacheEntries,
- PRUint32 ssl2_timeout,
- PRUint32 ssl3_timeout,
- const char * directory)
+SSL_ConfigMPServerSIDCache(int maxCacheEntries,
+ PRUint32 ssl2_timeout,
+ PRUint32 ssl3_timeout,
+ const char *directory)
{
- return ssl_ConfigMPServerSIDCacheWithOpt(ssl2_timeout,
- ssl3_timeout,
+ return ssl_ConfigMPServerSIDCacheWithOpt(ssl3_timeout,
directory,
maxCacheEntries,
-1, -1);
@@ -1468,44 +1302,43 @@ SSL_ConfigMPServerSIDCache( int maxCacheEntries,
SECStatus
SSL_ConfigServerSessionIDCacheWithOpt(
- PRUint32 ssl2_timeout,
- PRUint32 ssl3_timeout,
- const char * directory,
- int maxCacheEntries,
- int maxCertCacheEntries,
- int maxSrvNameCacheEntries,
- PRBool enableMPCache)
+ 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);
+ return ssl_ConfigServerSessionIDCacheInstanceWithOpt(&globalCache,
+ ssl3_timeout, directory, PR_FALSE,
+ maxCacheEntries, maxCertCacheEntries, maxSrvNameCacheEntries);
} else {
- return ssl_ConfigMPServerSIDCacheWithOpt(ssl2_timeout, ssl3_timeout,
- directory, maxCacheEntries, maxCertCacheEntries,
- maxSrvNameCacheEntries);
+ return ssl_ConfigMPServerSIDCacheWithOpt(ssl3_timeout, directory,
+ maxCacheEntries, maxCertCacheEntries, maxSrvNameCacheEntries);
}
}
SECStatus
-SSL_InheritMPServerSIDCacheInstance(cacheDesc *cache, const char * envString)
+SSL_InheritMPServerSIDCacheInstance(cacheDesc *cache, const char *envString)
{
- unsigned char * decoString = NULL;
- char * fmString = NULL;
- char * myEnvString = NULL;
- unsigned int decoLen;
- inheritance inherit;
- cacheDesc my;
+ unsigned char *decoString = NULL;
+ char *fmString = NULL;
+ char *myEnvString = NULL;
+ unsigned int decoLen;
+ inheritance inherit;
+ cacheDesc my;
#ifdef WINNT
- sidCacheLock* newLocks;
- int locks_initialized = 0;
- int locks_to_initialize = 0;
+ sidCacheLock *newLocks;
+ int locks_initialized = 0;
+ int locks_to_initialize = 0;
#endif
- SECStatus status = ssl_Init();
+ SECStatus status = ssl_Init();
if (status != SECSuccess) {
- return status;
+ return status;
}
myPid = SSL_GETPID();
@@ -1515,110 +1348,94 @@ SSL_InheritMPServerSIDCacheInstance(cacheDesc *cache, const char * envString)
** If not, we'll set it below.
*/
if (isMultiProcess) {
- if (cache && cache->sharedCache) {
- cache->sharedCache->everInherited = PR_TRUE;
- }
- return SECSuccess; /* already done. */
+ 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_lookup = ServerSessionIDLookup;
+ ssl_sid_cache = ServerSessionIDCache;
ssl_sid_uncache = ServerSessionIDUncache;
if (!envString) {
- envString = getenv(envVarName);
- if (!envString) {
- SET_ERROR_CODE
- return SECFailure;
- }
+ envString = PR_GetEnvSecure(envVarName);
+ if (!envString) {
+ PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
+ return SECFailure;
+ }
}
myEnvString = PORT_Strdup(envString);
- if (!myEnvString)
- return SECFailure;
+ if (!myEnvString)
+ return SECFailure;
fmString = strchr(myEnvString, ',');
- if (!fmString)
- goto loser;
+ if (!fmString)
+ goto loser;
*fmString++ = 0;
decoString = ATOB_AsciiToData(myEnvString, &decoLen);
if (!decoString) {
- SET_ERROR_CODE
- goto loser;
+ goto loser;
}
if (decoLen != sizeof inherit) {
- SET_ERROR_CODE
- goto loser;
+ goto loser;
}
PORT_Memcpy(&inherit, decoString, sizeof inherit);
- if (strlen(fmString) != inherit.fmStrLen ) {
- goto loser;
+ if (strlen(fmString) != inherit.fmStrLen) {
+ goto loser;
}
memset(cache, 0, sizeof *cache);
- cache->cacheMemSize = inherit.cacheMemSize;
+ cache->cacheMemSize = inherit.cacheMemSize;
/* Create cache */
cache->cacheMemMap = PR_ImportFileMapFromString(fmString);
- if(! cache->cacheMemMap) {
- goto loser;
+ if (!cache->cacheMemMap) {
+ goto loser;
}
cache->cacheMem = PR_MemMap(cache->cacheMemMap, 0, cache->cacheMemSize);
- if (! cache->cacheMem) {
- goto loser;
+ if (!cache->cacheMem) {
+ goto loser;
}
- cache->sharedCache = (cacheDesc *)cache->cacheMem;
+ cache->sharedCache = (cacheDesc *)cache->cacheMem;
if (cache->sharedCache->cacheMemSize != cache->cacheMemSize) {
- SET_ERROR_CODE
- goto loser;
+ 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
+ /* 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. */
+ 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
+ /* Fix pointers in our private copy of cache descriptor to point to
** spaces in shared memory, whose address is now in "my".
*/
- cache->sidCacheLocks = (sidCacheLock *)
- (my.cacheMem + (ptrdiff_t)cache->sidCacheLocks);
- cache->keyCacheLock = (sidCacheLock *)
- (my.cacheMem + (ptrdiff_t)cache->keyCacheLock);
- cache->certCacheLock = (sidCacheLock *)
- (my.cacheMem + (ptrdiff_t)cache->certCacheLock);
- cache->srvNameCacheLock = (sidCacheLock *)
- (my.cacheMem + (ptrdiff_t)cache->srvNameCacheLock);
- cache->sidCacheSets = (sidCacheSet *)
- (my.cacheMem + (ptrdiff_t)cache->sidCacheSets);
- cache->sidCacheData = (sidCacheEntry *)
- (my.cacheMem + (ptrdiff_t)cache->sidCacheData);
- cache->certCacheData = (certCacheEntry *)
- (my.cacheMem + (ptrdiff_t)cache->certCacheData);
- cache->keyCacheData = (SSLWrappedSymWrappingKey *)
- (my.cacheMem + (ptrdiff_t)cache->keyCacheData);
- cache->ticketKeyNameSuffix = (PRUint8 *)
- (my.cacheMem + (ptrdiff_t)cache->ticketKeyNameSuffix);
- cache->ticketEncKey = (encKeyCacheEntry *)
- (my.cacheMem + (ptrdiff_t)cache->ticketEncKey);
- cache->ticketMacKey = (encKeyCacheEntry *)
- (my.cacheMem + (ptrdiff_t)cache->ticketMacKey);
- cache->ticketKeysValid = (PRUint32 *)
- (my.cacheMem + (ptrdiff_t)cache->ticketKeysValid);
- cache->srvNameCacheData = (srvNameCacheEntry *)
- (my.cacheMem + (ptrdiff_t)cache->srvNameCacheData);
+ cache->sidCacheLocks = (sidCacheLock *)(my.cacheMem + (ptrdiff_t)cache->sidCacheLocks);
+ cache->keyCacheLock = (sidCacheLock *)(my.cacheMem + (ptrdiff_t)cache->keyCacheLock);
+ cache->certCacheLock = (sidCacheLock *)(my.cacheMem + (ptrdiff_t)cache->certCacheLock);
+ cache->srvNameCacheLock = (sidCacheLock *)(my.cacheMem + (ptrdiff_t)cache->srvNameCacheLock);
+ cache->sidCacheSets = (sidCacheSet *)(my.cacheMem + (ptrdiff_t)cache->sidCacheSets);
+ cache->sidCacheData = (sidCacheEntry *)(my.cacheMem + (ptrdiff_t)cache->sidCacheData);
+ cache->certCacheData = (certCacheEntry *)(my.cacheMem + (ptrdiff_t)cache->certCacheData);
+ cache->keyCacheData = (SSLWrappedSymWrappingKey *)(my.cacheMem + (ptrdiff_t)cache->keyCacheData);
+ cache->ticketKeyNameSuffix = (PRUint8 *)(my.cacheMem + (ptrdiff_t)cache->ticketKeyNameSuffix);
+ cache->ticketEncKey = (encKeyCacheEntry *)(my.cacheMem + (ptrdiff_t)cache->ticketEncKey);
+ cache->ticketMacKey = (encKeyCacheEntry *)(my.cacheMem + (ptrdiff_t)cache->ticketMacKey);
+ cache->ticketKeysValid = (PRUint32 *)(my.cacheMem + (ptrdiff_t)cache->ticketKeysValid);
+ cache->srvNameCacheData = (srvNameCacheEntry *)(my.cacheMem + (ptrdiff_t)cache->srvNameCacheData);
cache->cacheMemMap = my.cacheMemMap;
- cache->cacheMem = my.cacheMem;
+ cache->cacheMem = my.cacheMem;
cache->sharedCache = (cacheDesc *)cache->cacheMem;
#ifdef WINNT
@@ -1633,34 +1450,34 @@ SSL_InheritMPServerSIDCacheInstance(cacheDesc *cache, const char * envString)
** 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.
+ ** 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;
+ goto loser;
/* copy the old locks */
- memcpy(newLocks, cache->sidCacheLocks,
+ memcpy(newLocks, cache->sidCacheLocks,
locks_to_initialize * sizeof(sidCacheLock));
cache->sidCacheLocks = newLocks;
- /* fix the locks */
+ /* 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;
+ SECStatus err;
err = sslMutex_2LevelInit(&newLocks[locks_initialized].mutex);
- if (err != SECSuccess) {
- cache->numSIDCacheLocksInitialized = locks_initialized;
- goto loser;
- }
+ 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;
+ cache->keyCacheLock = cache->sidCacheLocks + cache->numSIDCacheLocks;
+ cache->certCacheLock = cache->keyCacheLock + 1;
+ cache->srvNameCacheLock = cache->certCacheLock + 1;
#endif
PORT_Free(myEnvString);
@@ -1674,112 +1491,113 @@ SSL_InheritMPServerSIDCacheInstance(cacheDesc *cache, const char * envString)
loser:
PORT_Free(myEnvString);
- if (decoString)
- PORT_Free(decoString);
+ if (decoString)
+ PORT_Free(decoString);
CloseCache(cache);
+ PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
return SECFailure;
}
SECStatus
-SSL_InheritMPServerSIDCache(const char * envString)
+SSL_InheritMPServerSIDCache(const char *envString)
{
return SSL_InheritMPServerSIDCacheInstance(&globalCache, envString);
}
#if defined(XP_UNIX) || defined(XP_BEOS)
-#define SID_LOCK_EXPIRATION_TIMEOUT 30 /* seconds */
+#define SID_LOCK_EXPIRATION_TIMEOUT 30 /* seconds */
static void
-LockPoller(void * arg)
+LockPoller(void *arg)
{
- cacheDesc * cache = (cacheDesc *)arg;
- cacheDesc * sharedCache = cache->sharedCache;
- sidCacheLock * pLock;
+ 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;
+ 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 */
+ 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
+static SECStatus
LaunchLockPoller(cacheDesc *cache)
{
- const char * timeoutString;
- PRThread * pollerThread;
+ const char *timeoutString;
+ PRThread *pollerThread;
cache->mutexTimeout = SID_LOCK_EXPIRATION_TIMEOUT;
- timeoutString = getenv("NSS_SSL_SERVER_CACHE_MUTEX_TIMEOUT");
+ timeoutString = PR_GetEnvSecure("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 */
+ 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);
+ pollerThread =
+ PR_CreateThread(PR_USER_THREAD, LockPoller, cache, PR_PRIORITY_NORMAL,
+ PR_GLOBAL_THREAD, PR_JOINABLE_THREAD, 0);
if (!pollerThread) {
- return SECFailure;
+ return SECFailure;
}
cache->poller = pollerThread;
return SECSuccess;
}
/* Stop the thread that polls cache for expired locks */
-static SECStatus
+static SECStatus
StopLockPoller(cacheDesc *cache)
{
if (!cache->poller) {
- return SECSuccess;
+ return SECSuccess;
}
cache->sharedCache->stopPolling = PR_TRUE;
if (PR_Interrupt(cache->poller) != PR_SUCCESS) {
- return SECFailure;
+ return SECFailure;
}
if (PR_JoinThread(cache->poller) != PR_SUCCESS) {
- return SECFailure;
+ return SECFailure;
}
cache->poller = NULL;
return SECSuccess;
@@ -1790,58 +1608,58 @@ StopLockPoller(cacheDesc *cache)
* 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.
+/* 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)
+getSvrWrappingKey(PRInt32 symWrapMechIndex,
+ SSLAuthType authType,
+ 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;
+ PRUint32 ndx = (authType * 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;
+ PORT_SetError(SSL_ERROR_SERVER_CACHE_NOT_CONFIGURED);
+ return rv;
}
if (!lockTime) {
- lockTime = now = LockSidCacheLock(cache->keyCacheLock, now);
- if (!lockTime) {
- return rv;
- }
+ 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 (pwswk->authType == authType &&
+ pwswk->symWrapMechIndex == symWrapMechIndex &&
+ pwswk->wrappedSymKeyLen != 0) {
+ *wswk = *pwswk;
+ rv = PR_TRUE;
}
if (now) {
- UnlockSidCacheLock(cache->keyCacheLock);
+ UnlockSidCacheLock(cache->keyCacheLock);
}
return rv;
}
PRBool
-ssl_GetWrappingKey( PRInt32 symWrapMechIndex,
- SSL3KEAType exchKeyType,
- SSLWrappedSymWrappingKey *wswk)
+ssl_GetWrappingKey(PRInt32 symWrapMechIndex,
+ SSLAuthType authType,
+ 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 &&
+ PORT_Assert((unsigned)authType < ssl_auth_size);
+ PORT_Assert((unsigned)symWrapMechIndex < SSL_NUM_WRAP_MECHS);
+ if ((unsigned)authType < ssl_auth_size &&
(unsigned)symWrapMechIndex < SSL_NUM_WRAP_MECHS) {
- rv = getSvrWrappingKey(symWrapMechIndex, exchKeyType, wswk,
- &globalCache, 0);
+ rv = getSvrWrappingKey(symWrapMechIndex, authType, wswk,
+ &globalCache, 0);
} else {
- rv = PR_FALSE;
+ rv = PR_FALSE;
}
return rv;
@@ -1850,21 +1668,21 @@ ssl_GetWrappingKey( PRInt32 symWrapMechIndex,
/* Wrap and cache a session ticket key. */
static PRBool
WrapTicketKey(SECKEYPublicKey *svrPubKey, PK11SymKey *symKey,
- const char *keyName, encKeyCacheEntry* cacheEntry)
+ const char *keyName, encKeyCacheEntry *cacheEntry)
{
- SECItem wrappedKey = {siBuffer, NULL, 0};
+ 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;
+ 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;
+ 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;
@@ -1890,10 +1708,11 @@ GenerateTicketKeys(void *pwArg, unsigned char *keyName, PK11SymKey **aesKey,
}
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;
+ 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;
@@ -1901,17 +1720,17 @@ GenerateTicketKeys(void *pwArg, unsigned char *keyName, PK11SymKey **aesKey,
slot = PK11_GetBestSlotMultiple(mechanismArray, 2, pwArg);
if (slot) {
- aesKeyTmp = PK11_KeyGen(slot, mechanismArray[0], NULL,
+ aesKeyTmp = PK11_KeyGen(slot, mechanismArray[0], NULL,
AES_256_KEY_LENGTH, pwArg);
- macKeyTmp = PK11_KeyGen(slot, mechanismArray[1], NULL,
+ macKeyTmp = PK11_KeyGen(slot, mechanismArray[1], NULL,
SHA256_LENGTH, pwArg);
- PK11_FreeSlot(slot);
+ PK11_FreeSlot(slot);
}
if (aesKeyTmp == NULL || macKeyTmp == NULL) {
- SSL_DBG(("%d: SSL[%s]: Unable to generate session ticket keys.",
- SSL_GETPID(), "unknown"));
- goto loser;
+ 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;
@@ -1920,9 +1739,9 @@ GenerateTicketKeys(void *pwArg, unsigned char *keyName, PK11SymKey **aesKey,
loser:
if (aesKeyTmp)
- PK11_FreeSymKey(aesKeyTmp);
+ PK11_FreeSymKey(aesKeyTmp);
if (macKeyTmp)
- PK11_FreeSymKey(macKeyTmp);
+ PK11_FreeSymKey(macKeyTmp);
return PR_FALSE;
}
@@ -1952,9 +1771,9 @@ GenerateAndWrapTicketKeys(SECKEYPublicKey *svrPubKey, void *pwArg,
loser:
if (aesKeyTmp)
- PK11_FreeSymKey(aesKeyTmp);
+ PK11_FreeSymKey(aesKeyTmp);
if (macKeyTmp)
- PK11_FreeSymKey(macKeyTmp);
+ PK11_FreeSymKey(macKeyTmp);
return PR_FALSE;
}
@@ -1962,7 +1781,7 @@ static PRBool
UnwrapCachedTicketKeys(SECKEYPrivateKey *svrPrivKey, unsigned char *keyName,
PK11SymKey **aesKey, PK11SymKey **macKey)
{
- SECItem wrappedKey = {siBuffer, NULL, 0};
+ SECItem wrappedKey = { siBuffer, NULL, 0 };
PK11SymKey *aesKeyTmp = NULL;
PK11SymKey *macKeyTmp = NULL;
cacheDesc *cache = &globalCache;
@@ -1971,41 +1790,41 @@ UnwrapCachedTicketKeys(SECKEYPrivateKey *svrPrivKey, unsigned char *keyName,
wrappedKey.len = cache->ticketEncKey->length;
PORT_Assert(wrappedKey.len <= sizeof(cache->ticketEncKey->bytes));
aesKeyTmp = PK11_PubUnwrapSymKey(svrPrivKey, &wrappedKey,
- CKM_AES_CBC, CKA_DECRYPT, 0);
+ 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);
+ 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]: Unable to unwrap session ticket keys.",
+ SSL_GETPID(), "unknown"));
+ goto loser;
}
SSL_DBG(("%d: SSL[%s]: Successfully unwrapped session ticket keys.",
- SSL_GETPID(), "unknown"));
+ SSL_GETPID(), "unknown"));
PORT_Memcpy(keyName, cache->ticketKeyNameSuffix,
- SESS_TICKET_KEY_VAR_NAME_LEN);
+ SESS_TICKET_KEY_VAR_NAME_LEN);
*aesKey = aesKeyTmp;
*macKey = macKeyTmp;
return PR_TRUE;
loser:
if (aesKeyTmp)
- PK11_FreeSymKey(aesKeyTmp);
+ PK11_FreeSymKey(aesKeyTmp);
if (macKeyTmp)
- PK11_FreeSymKey(macKeyTmp);
+ PK11_FreeSymKey(macKeyTmp);
return PR_FALSE;
}
PRBool
-ssl_GetSessionTicketKeysPKCS11(SECKEYPrivateKey *svrPrivKey,
- SECKEYPublicKey *svrPubKey, void *pwArg,
- unsigned char *keyName, PK11SymKey **aesKey,
- PK11SymKey **macKey)
+ssl_GetSessionTicketKeys(SECKEYPrivateKey *svrPrivKey,
+ SECKEYPublicKey *svrPubKey, void *pwArg,
+ unsigned char *keyName, PK11SymKey **aesKey,
+ PK11SymKey **macKey)
{
PRUint32 now = 0;
PRBool rv = PR_FALSE;
@@ -2020,143 +1839,80 @@ ssl_GetSessionTicketKeysPKCS11(SECKEYPrivateKey *svrPrivKey,
now = LockSidCacheLock(cache->keyCacheLock, now);
if (!now)
- return rv;
+ 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;
+ /* 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:
+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;
- PRUint8 ticketMacKey[SHA256_LENGTH], ticketEncKey[AES_256_KEY_LENGTH];
- PRUint8 ticketKeyNameSuffixLocal[SESS_TICKET_KEY_VAR_NAME_LEN];
- PRUint8 *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);
- }
+ rv = UnwrapCachedTicketKeys(svrPrivKey, keyName, aesKey, macKey);
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
+ * 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;
+ cacheDesc *cache = &globalCache;
+ PRBool rv = PR_FALSE;
+ SSLAuthType authType = wswk->authType;
+ /* 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_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)authType < ssl_auth_size);
+ if ((unsigned)authType >= ssl_auth_size)
+ return 0;
- PORT_Assert( (unsigned)symWrapMechIndex < SSL_NUM_WRAP_MECHS);
- if ((unsigned)symWrapMechIndex >= SSL_NUM_WRAP_MECHS)
- 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. */
+ ndx = (authType * 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);
+ rv = getSvrWrappingKey(wswk->symWrapMechIndex, wswk->authType,
+ &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 */
+#else /* MAC version or other platform */
#include "seccomon.h"
#include "cert.h"
@@ -2164,67 +1920,67 @@ ssl_SetWrappingKey(SSLWrappedSymWrappingKey *wswk)
#include "sslimpl.h"
SECStatus
-SSL_ConfigServerSessionIDCache( int maxCacheEntries,
- PRUint32 ssl2_timeout,
- PRUint32 ssl3_timeout,
- const char * directory)
+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)");
+ 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)
+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)");
+ PR_ASSERT(!"SSL servers are not supported on this platform. (SSL_ConfigMPServerSIDCache)");
return SECFailure;
}
SECStatus
-SSL_InheritMPServerSIDCache(const char * envString)
+SSL_InheritMPServerSIDCache(const char *envString)
{
- PR_ASSERT(!"SSL servers are not supported on this platform. (SSL_InheritMPServerSIDCache)");
+ PR_ASSERT(!"SSL servers are not supported on this platform. (SSL_InheritMPServerSIDCache)");
return SECFailure;
}
PRBool
-ssl_GetWrappingKey( PRInt32 symWrapMechIndex,
- SSL3KEAType exchKeyType,
- SSLWrappedSymWrappingKey *wswk)
+ssl_GetWrappingKey(PRInt32 symWrapMechIndex,
+ SSLAuthType authType,
+ SSLWrappedSymWrappingKey *wswk)
{
PRBool rv = PR_FALSE;
- PR_ASSERT(!"SSL servers are not supported on this platform. (ssl_GetWrappingKey)");
+ 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
+ * 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;
+ PRBool rv = PR_FALSE;
PR_ASSERT(!"SSL servers are not supported on this platform. (ssl_SetWrappingKey)");
return rv;
}
-PRUint32
+PRUint32
SSL_GetMaxServerCacheLocks(void)
{
PR_ASSERT(!"SSL servers are not supported on this platform. (SSL_GetMaxServerCacheLocks)");
return -1;
}
-SECStatus
+SECStatus
SSL_SetMaxServerCacheLocks(PRUint32 maxLocks)
{
PR_ASSERT(!"SSL servers are not supported on this platform. (SSL_SetMaxServerCacheLocks)");
diff --git a/nss/lib/ssl/sslsock.c b/nss/lib/ssl/sslsock.c
index f735009..626f4a9 100644
--- a/nss/lib/ssl/sslsock.c
+++ b/nss/lib/ssl/sslsock.c
@@ -1,3 +1,4 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
* vtables (and methods that call through them) for the 4 types of
* SSLSockets supported. Only one type is still supported.
@@ -14,42 +15,37 @@
#include "sslproto.h"
#include "nspr.h"
#include "private/pprio.h"
-#ifndef NO_PKCS11_BYPASS
-#include "blapi.h"
-#endif
#include "nss.h"
#include "pk11pqg.h"
-#define SET_ERROR_CODE /* reminder */
-
-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_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
+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
};
/*
@@ -57,35 +53,37 @@ static const sslSocketOps ssl_secure_ops = { /* SSL. */
*/
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 */
- PR_TRUE, /* enableNPN */
- PR_FALSE, /* enableALPN */
- PR_TRUE, /* reuseServerECDHEKey */
- PR_FALSE, /* enableFallbackSCSV */
- PR_TRUE, /* enableServerDhe */
- PR_FALSE /* enableExtendedMS */
+ PR_TRUE, /* useSecurity */
+ PR_FALSE, /* useSocks */
+ PR_FALSE, /* requestCertificate */
+ 2, /* requireCertificate */
+ PR_FALSE, /* handshakeAsClient */
+ PR_FALSE, /* handshakeAsServer */
+ PR_FALSE, /* noCache */
+ PR_FALSE, /* fdx */
+ PR_TRUE, /* detectRollBack */
+ 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 */
+ PR_FALSE, /* enableNPN */
+ PR_TRUE, /* enableALPN */
+ PR_TRUE, /* reuseServerECDHEKey */
+ PR_FALSE, /* enableFallbackSCSV */
+ PR_TRUE, /* enableServerDhe */
+ PR_FALSE, /* enableExtendedMS */
+ PR_FALSE, /* enableSignedCertTimestamps */
+ PR_FALSE, /* requireDHENamedGroups */
+ PR_FALSE, /* enable0RttData */
+#ifdef NSS_ENABLE_TLS13_SHORT_HEADERS
+ PR_TRUE /* enableShortHeaders */
+#else
+ PR_FALSE /* enableShortHeaders */
+#endif
};
/*
@@ -102,23 +100,30 @@ static SSLVersionRange versions_defaults_datagram = {
};
#define VERSIONS_DEFAULTS(variant) \
- (variant == ssl_variant_stream ? &versions_defaults_stream : \
- &versions_defaults_datagram)
-
-sslSessionIDLookupFunc ssl_sid_lookup;
-sslSessionIDCacheFunc ssl_sid_cache;
+ (variant == ssl_variant_stream ? &versions_defaults_stream : &versions_defaults_datagram)
+#define VERSIONS_POLICY_MIN(variant) \
+ (variant == ssl_variant_stream ? NSS_TLS_VERSION_MIN_POLICY : NSS_DTLS_VERSION_MIN_POLICY)
+#define VERSIONS_POLICY_MAX(variant) \
+ (variant == ssl_variant_stream ? NSS_TLS_VERSION_MAX_POLICY : NSS_DTLS_VERSION_MAX_POLICY)
+
+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;
+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;
+
+#ifdef NSS_ALLOW_SSLKEYLOGFILE
+FILE *ssl_keylog_iob;
+#endif
+
char lockStatus[] = "Locks are ENABLED. ";
#define LOCKSTATUS_OFFSET 10 /* offset of ENABLED */
@@ -129,12 +134,66 @@ static const PRUint16 srtpCiphers[] = {
0
};
+/* This list is in preference order. Note that while some smaller groups appear
+ * early in the list, smaller groups are generally ignored when iterating
+ * through this list. ffdhe_custom must not appear in this list. */
+#define ECGROUP(name, size, oid, assumeSupported) \
+ { \
+ ssl_grp_ec_##name, size, ssl_kea_ecdh, \
+ SEC_OID_SECG_EC_##oid, assumeSupported \
+ }
+#define FFGROUP(size) \
+ { \
+ ssl_grp_ffdhe_##size, size, ssl_kea_dh, \
+ SEC_OID_TLS_FFDHE_##size, PR_TRUE \
+ }
+
+const sslNamedGroupDef ssl_named_groups[] = {
+ /* Note that 256 for 25519 is a lie, but we only use it for checking bit
+ * security and expect 256 bits there (not 255). */
+ { ssl_grp_ec_curve25519, 256, ssl_kea_ecdh, SEC_OID_CURVE25519, PR_TRUE },
+ ECGROUP(secp256r1, 256, SECP256R1, PR_TRUE),
+ ECGROUP(secp384r1, 384, SECP384R1, PR_TRUE),
+ ECGROUP(secp521r1, 521, SECP521R1, PR_TRUE),
+ FFGROUP(2048),
+ FFGROUP(3072),
+ FFGROUP(4096),
+ FFGROUP(6144),
+ FFGROUP(8192),
+ ECGROUP(secp192r1, 192, SECP192R1, PR_FALSE),
+ ECGROUP(secp160r2, 160, SECP160R2, PR_FALSE),
+ ECGROUP(secp160k1, 160, SECP160K1, PR_FALSE),
+ ECGROUP(secp160r1, 160, SECP160R1, PR_FALSE),
+ ECGROUP(sect163k1, 163, SECT163K1, PR_FALSE),
+ ECGROUP(sect163r1, 163, SECT163R1, PR_FALSE),
+ ECGROUP(sect163r2, 163, SECT163R2, PR_FALSE),
+ ECGROUP(secp192k1, 192, SECP192K1, PR_FALSE),
+ ECGROUP(sect193r1, 193, SECT193R1, PR_FALSE),
+ ECGROUP(sect193r2, 193, SECT193R2, PR_FALSE),
+ ECGROUP(secp224r1, 224, SECP224R1, PR_FALSE),
+ ECGROUP(secp224k1, 224, SECP224K1, PR_FALSE),
+ ECGROUP(sect233k1, 233, SECT233K1, PR_FALSE),
+ ECGROUP(sect233r1, 233, SECT233R1, PR_FALSE),
+ ECGROUP(sect239k1, 239, SECT239K1, PR_FALSE),
+ ECGROUP(secp256k1, 256, SECP256K1, PR_FALSE),
+ ECGROUP(sect283k1, 283, SECT283K1, PR_FALSE),
+ ECGROUP(sect283r1, 283, SECT283R1, PR_FALSE),
+ ECGROUP(sect409k1, 409, SECT409K1, PR_FALSE),
+ ECGROUP(sect409r1, 409, SECT409R1, PR_FALSE),
+ ECGROUP(sect571k1, 571, SECT571K1, PR_FALSE),
+ ECGROUP(sect571r1, 571, SECT571R1, PR_FALSE),
+};
+PR_STATIC_ASSERT(SSL_NAMED_GROUP_COUNT == PR_ARRAY_SIZE(ssl_named_groups));
+
+#undef ECGROUP
+#undef FFGROUP
+
/* 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);
+static SECStatus ssl_MakeLocks(sslSocket *ss);
+static void ssl_SetDefaultsFromEnvironment(void);
+static PRStatus ssl_PushIOLayer(sslSocket *ns, PRFileDesc *stack,
+ PRDescIdentity id);
/************************************************************************/
@@ -205,116 +264,90 @@ ssl_DupSocket(sslSocket *os)
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;
- PORT_Memcpy(ss->ssl3.signatureAlgorithms, os->ssl3.signatureAlgorithms,
- sizeof(ss->ssl3.signatureAlgorithms[0]) *
- os->ssl3.signatureAlgorithmCount);
- ss->ssl3.signatureAlgorithmCount = os->ssl3.signatureAlgorithmCount;
-
- ss->ssl3.dheWeakGroupEnabled = os->ssl3.dheWeakGroupEnabled;
- ss->ssl3.numDHEGroups = os->ssl3.numDHEGroups;
- if (os->ssl3.dheGroups) {
- ss->ssl3.dheGroups = PORT_NewArray(SSLDHEGroupType,
- os->ssl3.numDHEGroups);
- if (!ss->ssl3.dheGroups) {
+ if (!ss) {
+ return NULL;
+ }
+
+ ss->opt = os->opt;
+ ss->opt.useSocks = PR_FALSE;
+ rv = SECITEM_CopyItem(NULL, &ss->opt.nextProtoNego, &os->opt.nextProtoNego);
+ if (rv != SECSuccess) {
+ goto loser;
+ }
+ 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) */
+ 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;
+ PORT_Memcpy(ss->ssl3.signatureSchemes, os->ssl3.signatureSchemes,
+ sizeof(ss->ssl3.signatureSchemes[0]) *
+ os->ssl3.signatureSchemeCount);
+ ss->ssl3.signatureSchemeCount = os->ssl3.signatureSchemeCount;
+ ss->ssl3.downgradeCheckVersion = os->ssl3.downgradeCheckVersion;
+
+ ss->ssl3.dheWeakGroupEnabled = os->ssl3.dheWeakGroupEnabled;
+
+ if (ss->opt.useSecurity) {
+ PRCList *cursor;
+ for (cursor = PR_NEXT_LINK(&os->serverCerts);
+ cursor != &os->serverCerts;
+ cursor = PR_NEXT_LINK(cursor)) {
+ sslServerCert *sc = ssl_CopyServerCert((sslServerCert *)cursor);
+ if (!sc)
goto loser;
- }
- PORT_Memcpy(ss->ssl3.dheGroups, os->ssl3.dheGroups,
- sizeof(SSLDHEGroupType) * os->ssl3.numDHEGroups);
- } else {
- ss->ssl3.dheGroups = NULL;
+ PR_APPEND_LINK(&sc->link, &ss->serverCerts);
}
- 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;
+ PR_INIT_CLIST(&ss->ephemeralKeyPairs);
+ for (cursor = PR_NEXT_LINK(&os->ephemeralKeyPairs);
+ cursor != &os->ephemeralKeyPairs;
+ cursor = PR_NEXT_LINK(cursor)) {
+ sslEphemeralKeyPair *okp = (sslEphemeralKeyPair *)cursor;
+ sslEphemeralKeyPair *skp = ssl_CopyEphemeralKeyPair(okp);
+ if (!skp)
+ goto loser;
+ PR_APPEND_LINK(&skp->link, &ss->ephemeralKeyPairs);
}
- 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->certStatusArray[i] = !os->certStatusArray[i] ? NULL :
- SECITEM_DupArray(NULL, os->certStatusArray[i]);
- }
- ss->stepDownKeyPair = !os->stepDownKeyPair ? NULL :
- ssl3_GetKeyPairRef(os->stepDownKeyPair);
- ss->ephemeralECDHKeyPair = !os->ephemeralECDHKeyPair ? NULL :
- ssl3_GetKeyPairRef(os->ephemeralECDHKeyPair);
- ss->dheKeyPair = !os->dheKeyPair ? NULL :
- ssl3_GetKeyPairRef(os->dheKeyPair);
- ss->dheParams = os->dheParams;
-/*
- * 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->canFalseStartCallback = os->canFalseStartCallback;
- ss->canFalseStartCallbackData = os->canFalseStartCallbackData;
- ss->pkcs11PinArg = os->pkcs11PinArg;
-
- /* Create security data */
- rv = ssl_CopySecurityInfo(ss, os);
- if (rv != SECSuccess) {
- goto loser;
- }
+ /*
+ * 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->canFalseStartCallback = os->canFalseStartCallback;
+ ss->canFalseStartCallbackData = os->canFalseStartCallbackData;
+ ss->pkcs11PinArg = os->pkcs11PinArg;
+ ss->nextProtoCallback = os->nextProtoCallback;
+ ss->nextProtoArg = os->nextProtoArg;
+ PORT_Memcpy((void *)ss->namedGroupPreferences,
+ os->namedGroupPreferences,
+ sizeof(ss->namedGroupPreferences));
+ ss->additionalShares = os->additionalShares;
+
+ /* Create security data */
+ rv = ssl_CopySecurityInfo(ss, os);
+ if (rv != SECSuccess) {
+ goto loser;
}
}
return ss;
@@ -363,10 +396,7 @@ ssl_DestroyLocks(sslSocket *ss)
static void
ssl_DestroySocketContents(sslSocket *ss)
{
- /* "i" should be of type SSLKEAType, but CC on IRIX complains during
- * the for loop.
- */
- int i;
+ PRCList *cursor;
/* Free up socket */
ssl_DestroySecurityInfo(&ss->sec);
@@ -375,49 +405,22 @@ ssl_DestroySocketContents(sslSocket *ss)
PORT_Free(ss->saveBuf.buf);
PORT_Free(ss->pendingBuf.buf);
- ssl_DestroyGather(&ss->gs);
+ ssl3_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->certStatusArray[i] != NULL) {
- SECITEM_FreeArray(ss->certStatusArray[i], PR_TRUE);
- ss->certStatusArray[i] = NULL;
- }
- }
- if (ss->stepDownKeyPair) {
- ssl3_FreeKeyPair(ss->stepDownKeyPair);
- ss->stepDownKeyPair = NULL;
- }
- if (ss->ephemeralECDHKeyPair) {
- ssl3_FreeKeyPair(ss->ephemeralECDHKeyPair);
- ss->ephemeralECDHKeyPair = NULL;
- }
- if (ss->dheKeyPair) {
- ssl3_FreeKeyPair(ss->dheKeyPair);
- ss->dheKeyPair = NULL;
+ PORT_Free((void *)ss->url); /* CONST */
+
+ /* Clean up server certificates and sundries. */
+ while (!PR_CLIST_IS_EMPTY(&ss->serverCerts)) {
+ cursor = PR_LIST_TAIL(&ss->serverCerts);
+ PR_REMOVE_LINK(cursor);
+ ssl_FreeServerCert((sslServerCert *)cursor);
}
+ ssl_FreeEphemeralKeyPairs(ss);
SECITEM_FreeItem(&ss->opt.nextProtoNego, PR_FALSE);
- if (ss->xtnData.sniNameArr) {
- PORT_Free(ss->xtnData.sniNameArr);
- ss->xtnData.sniNameArr = NULL;
- }
+ ssl3_FreeSniNameArray(&ss->xtnData);
}
/*
@@ -426,11 +429,11 @@ ssl_DestroySocketContents(sslSocket *ss)
void
ssl_FreeSocket(sslSocket *ss)
{
-/* Get every lock you can imagine!
-** Caller already holds these:
-** SSL_LOCK_READER(ss);
-** SSL_LOCK_WRITER(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);
@@ -461,15 +464,15 @@ ssl_FreeSocket(sslSocket *ss)
SECStatus
ssl_EnableNagleDelay(sslSocket *ss, PRBool enabled)
{
- PRFileDesc * osfd = ss->fd->lower;
- SECStatus rv = SECFailure;
+ PRFileDesc *osfd = ss->fd->lower;
+ SECStatus rv = SECFailure;
PRSocketOptionData opt;
- opt.option = PR_SockOpt_NoDelay;
+ opt.option = PR_SockOpt_NoDelay;
opt.value.no_delay = (PRBool)!enabled;
if (osfd->methods->setsocketoption) {
- rv = (SECStatus) osfd->methods->setsocketoption(osfd, &opt);
+ rv = (SECStatus)osfd->methods->setsocketoption(osfd, &opt);
} else {
PR_SetError(PR_NOT_IMPLEMENTED_ERROR, 0);
}
@@ -487,7 +490,7 @@ ssl_ChooseOps(sslSocket *ss)
static SECStatus
PrepareSocket(sslSocket *ss)
{
- SECStatus rv = SECSuccess;
+ SECStatus rv = SECSuccess;
ssl_ChooseOps(ss);
return rv;
@@ -499,35 +502,8 @@ 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
-}
+static PRBool ssl_VersionIsSupportedByPolicy(
+ SSLProtocolVariant protocolVariant, SSL3ProtocolVersion version);
/* Implements the semantics for SSL_OptionSet(SSL_ENABLE_TLS, on) described in
* ssl.h in the section "SSL version range setting API".
@@ -535,7 +511,14 @@ static PRStatus SSL_BypassSetup(void)
static void
ssl_EnableTLS(SSLVersionRange *vrange, PRBool on)
{
- if (SSL3_ALL_VERSIONS_DISABLED(vrange)) {
+ if (on) {
+ /* don't turn it on if tls1.0 disallowed by by policy */
+ if (!ssl_VersionIsSupportedByPolicy(ssl_variant_stream,
+ SSL_LIBRARY_VERSION_TLS_1_0)) {
+ return;
+ }
+ }
+ if (SSL_ALL_VERSIONS_DISABLED(vrange)) {
if (on) {
vrange->min = SSL_LIBRARY_VERSION_TLS_1_0;
vrange->max = SSL_LIBRARY_VERSION_TLS_1_0;
@@ -565,7 +548,14 @@ ssl_EnableTLS(SSLVersionRange *vrange, PRBool on)
static void
ssl_EnableSSL3(SSLVersionRange *vrange, PRBool on)
{
- if (SSL3_ALL_VERSIONS_DISABLED(vrange)) {
+ if (on) {
+ /* don't turn it on if ssl3 disallowed by by policy */
+ if (!ssl_VersionIsSupportedByPolicy(ssl_variant_stream,
+ SSL_LIBRARY_VERSION_3_0)) {
+ return;
+ }
+ }
+ if (SSL_ALL_VERSIONS_DISABLED(vrange)) {
if (on) {
vrange->min = SSL_LIBRARY_VERSION_3_0;
vrange->max = SSL_LIBRARY_VERSION_3_0;
@@ -573,13 +563,13 @@ ssl_EnableSSL3(SSLVersionRange *vrange, PRBool on)
return;
}
- if (on) {
+ 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 {
+ } 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);
@@ -595,8 +585,8 @@ SECStatus
SSL_OptionSet(PRFileDesc *fd, PRInt32 which, PRBool on)
{
sslSocket *ss = ssl_FindSocket(fd);
- SECStatus rv = SECSuccess;
- PRBool holdingLocks;
+ SECStatus rv = SECSuccess;
+ PRBool holdingLocks;
if (!ss) {
SSL_DBG(("%d: SSL[%d]: bad socket in Enable", SSL_GETPID(), fd));
@@ -608,231 +598,192 @@ SSL_OptionSet(PRFileDesc *fd, PRInt32 which, PRBool on)
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_SOCKS:
+ ss->opt.useSocks = PR_FALSE;
+ rv = PrepareSocket(ss);
+ if (on) {
+ PORT_SetError(SEC_ERROR_INVALID_ARGS);
+ rv = SECFailure;
+ }
+ break;
- case SSL_REQUIRE_CERTIFICATE:
- ss->opt.requireCertificate = on;
- break;
+ case SSL_SECURITY:
+ ss->opt.useSecurity = on;
+ rv = PrepareSocket(ss);
+ break;
- case SSL_HANDSHAKE_AS_CLIENT:
- if ( ss->opt.handshakeAsServer && on ) {
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- rv = SECFailure;
+ case SSL_REQUEST_CERTIFICATE:
+ ss->opt.requestCertificate = on;
break;
- }
- ss->opt.handshakeAsClient = on;
- break;
- case SSL_HANDSHAKE_AS_SERVER:
- if ( ss->opt.handshakeAsClient && on ) {
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- rv = SECFailure;
+ case SSL_REQUIRE_CERTIFICATE:
+ ss->opt.requireCertificate = on;
break;
- }
- ss->opt.handshakeAsServer = on;
- break;
- case SSL_ENABLE_TLS:
- if (IS_DTLS(ss)) {
- if (on) {
+ case SSL_HANDSHAKE_AS_CLIENT:
+ if (ss->opt.handshakeAsServer && on) {
PORT_SetError(SEC_ERROR_INVALID_ARGS);
- rv = SECFailure; /* not allowed */
+ rv = SECFailure;
+ break;
}
+ ss->opt.handshakeAsClient = on;
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) {
+ case SSL_HANDSHAKE_AS_SERVER:
+ if (ss->opt.handshakeAsClient && on) {
PORT_SetError(SEC_ERROR_INVALID_ARGS);
- rv = SECFailure; /* not allowed */
+ rv = SECFailure;
+ break;
}
+ ss->opt.handshakeAsServer = on;
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)) {
+ 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);
+ 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);
+ break;
+
+ case SSL_ENABLE_SSL2:
+ case SSL_V2_COMPATIBLE_HELLO:
+ /* We no longer support SSL v2.
+ * However, if an old application requests to disable SSL v2,
+ * we shouldn't fail.
+ */
if (on) {
PORT_SetError(SEC_ERROR_INVALID_ARGS);
- rv = SECFailure; /* not allowed */
+ rv = SECFailure;
}
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_NO_CACHE:
+ ss->opt.noCache = on;
+ break;
- case SSL_V2_COMPATIBLE_HELLO:
- if (IS_DTLS(ss)) {
- if (on) {
+ case SSL_ENABLE_FDX:
+ if (on && ss->opt.noLocks) {
PORT_SetError(SEC_ERROR_INVALID_ARGS);
- rv = SECFailure; /* not allowed */
+ rv = SECFailure;
}
+ ss->opt.fdx = on;
break;
- }
- ss->opt.v2CompatibleHello = on;
- if (!on) {
- ss->opt.enableSSL2 = on;
- }
- break;
- case SSL_ROLLBACK_DETECTION:
- ss->opt.detectRollBack = 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_NO_STEP_DOWN:
+ 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;
+ case SSL_BYPASS_PKCS11:
+ 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;
}
- } else {
- ss->opt.bypassPKCS11 = PR_FALSE;
}
- }
- break;
+ 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;
+ case SSL_ENABLE_SESSION_TICKETS:
+ ss->opt.enableSessionTickets = on;
+ break;
+
+ case SSL_ENABLE_DEFLATE:
+ ss->opt.enableDeflate = on;
+ break;
+
+ case SSL_ENABLE_RENEGOTIATION:
+ if (IS_DTLS(ss) && on != SSL_RENEGOTIATE_NEVER) {
+ PORT_SetError(SEC_ERROR_INVALID_ARGS);
+ rv = SECFailure;
+ break;
}
- }
- break;
+ ss->opt.enableRenegotiation = on;
+ break;
- case SSL_ENABLE_SESSION_TICKETS:
- ss->opt.enableSessionTickets = on;
- break;
+ case SSL_REQUIRE_SAFE_NEGOTIATION:
+ ss->opt.requireSafeNegotiation = on;
+ break;
- case SSL_ENABLE_DEFLATE:
- ss->opt.enableDeflate = on;
- break;
+ case SSL_ENABLE_FALSE_START:
+ ss->opt.enableFalseStart = on;
+ break;
- case SSL_ENABLE_RENEGOTIATION:
- ss->opt.enableRenegotiation = on;
- break;
+ case SSL_CBC_RANDOM_IV:
+ ss->opt.cbcRandomIV = on;
+ break;
- case SSL_REQUIRE_SAFE_NEGOTIATION:
- ss->opt.requireSafeNegotiation = on;
- break;
+ case SSL_ENABLE_OCSP_STAPLING:
+ ss->opt.enableOCSPStapling = on;
+ break;
- case SSL_ENABLE_FALSE_START:
- ss->opt.enableFalseStart = on;
- break;
+ case SSL_ENABLE_NPN:
+ break;
- case SSL_CBC_RANDOM_IV:
- ss->opt.cbcRandomIV = on;
- break;
+ case SSL_ENABLE_ALPN:
+ ss->opt.enableALPN = on;
+ break;
- case SSL_ENABLE_OCSP_STAPLING:
- ss->opt.enableOCSPStapling = on;
- break;
+ case SSL_REUSE_SERVER_ECDHE_KEY:
+ ss->opt.reuseServerECDHEKey = on;
+ break;
- case SSL_ENABLE_NPN:
- ss->opt.enableNPN = on;
- break;
+ case SSL_ENABLE_FALLBACK_SCSV:
+ ss->opt.enableFallbackSCSV = on;
+ break;
- case SSL_ENABLE_ALPN:
- ss->opt.enableALPN = on;
- break;
+ case SSL_ENABLE_SERVER_DHE:
+ ss->opt.enableServerDhe = on;
+ break;
- case SSL_REUSE_SERVER_ECDHE_KEY:
- ss->opt.reuseServerECDHEKey = on;
- break;
+ case SSL_ENABLE_EXTENDED_MASTER_SECRET:
+ ss->opt.enableExtendedMS = on;
+ break;
- case SSL_ENABLE_FALLBACK_SCSV:
- ss->opt.enableFallbackSCSV = on;
- break;
+ case SSL_ENABLE_SIGNED_CERT_TIMESTAMPS:
+ ss->opt.enableSignedCertTimestamps = on;
+ break;
- case SSL_ENABLE_SERVER_DHE:
- ss->opt.enableServerDhe = on;
- break;
+ case SSL_REQUIRE_DH_NAMED_GROUPS:
+ ss->opt.requireDHENamedGroups = on;
+ break;
- case SSL_ENABLE_EXTENDED_MASTER_SECRET:
- ss->opt.enableExtendedMS = on;
- break;
+ case SSL_ENABLE_0RTT_DATA:
+ ss->opt.enable0RttData = on;
+ break;
- default:
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- rv = SECFailure;
+ default:
+ PORT_SetError(SEC_ERROR_INVALID_ARGS);
+ rv = SECFailure;
}
/* We can't use the macros for releasing the locks here,
@@ -852,8 +803,8 @@ SECStatus
SSL_OptionGet(PRFileDesc *fd, PRInt32 which, PRBool *pOn)
{
sslSocket *ss = ssl_FindSocket(fd);
- SECStatus rv = SECSuccess;
- PRBool on = PR_FALSE;
+ SECStatus rv = SECSuccess;
+ PRBool on = PR_FALSE;
if (!pOn) {
PORT_SetError(SEC_ERROR_INVALID_ARGS);
@@ -869,49 +820,103 @@ SSL_OptionGet(PRFileDesc *fd, PRInt32 which, PRBool *pOn)
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;
- case SSL_ENABLE_NPN: on = ss->opt.enableNPN; break;
- case SSL_ENABLE_ALPN: on = ss->opt.enableALPN; break;
- case SSL_REUSE_SERVER_ECDHE_KEY:
- on = ss->opt.reuseServerECDHEKey; break;
- case SSL_ENABLE_FALLBACK_SCSV: on = ss->opt.enableFallbackSCSV; break;
- case SSL_ENABLE_SERVER_DHE: on = ss->opt.enableServerDhe; break;
- case SSL_ENABLE_EXTENDED_MASTER_SECRET:
- on = ss->opt.enableExtendedMS; break;
-
- default:
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- rv = SECFailure;
+ 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:
+ case SSL_V2_COMPATIBLE_HELLO:
+ on = PR_FALSE;
+ break;
+ case SSL_NO_CACHE:
+ on = ss->opt.noCache;
+ break;
+ case SSL_ENABLE_FDX:
+ on = ss->opt.fdx;
+ break;
+ case SSL_ROLLBACK_DETECTION:
+ on = ss->opt.detectRollBack;
+ break;
+ case SSL_NO_STEP_DOWN:
+ on = PR_FALSE;
+ break;
+ case SSL_BYPASS_PKCS11:
+ on = PR_FALSE;
+ 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;
+ case SSL_ENABLE_NPN:
+ on = ss->opt.enableNPN;
+ break;
+ case SSL_ENABLE_ALPN:
+ on = ss->opt.enableALPN;
+ break;
+ case SSL_REUSE_SERVER_ECDHE_KEY:
+ on = ss->opt.reuseServerECDHEKey;
+ break;
+ case SSL_ENABLE_FALLBACK_SCSV:
+ on = ss->opt.enableFallbackSCSV;
+ break;
+ case SSL_ENABLE_SERVER_DHE:
+ on = ss->opt.enableServerDhe;
+ break;
+ case SSL_ENABLE_EXTENDED_MASTER_SECRET:
+ on = ss->opt.enableExtendedMS;
+ break;
+ case SSL_ENABLE_SIGNED_CERT_TIMESTAMPS:
+ on = ss->opt.enableSignedCertTimestamps;
+ break;
+ case SSL_REQUIRE_DH_NAMED_GROUPS:
+ on = ss->opt.requireDHENamedGroups;
+ break;
+ case SSL_ENABLE_0RTT_DATA:
+ on = ss->opt.enable0RttData;
+ break;
+ default:
+ PORT_SetError(SEC_ERROR_INVALID_ARGS);
+ rv = SECFailure;
}
ssl_ReleaseSSL3HandshakeLock(ss);
@@ -924,8 +929,8 @@ SSL_OptionGet(PRFileDesc *fd, PRInt32 which, PRBool *pOn)
SECStatus
SSL_OptionGetDefault(PRInt32 which, PRBool *pOn)
{
- SECStatus rv = SECSuccess;
- PRBool on = PR_FALSE;
+ SECStatus rv = SECSuccess;
+ PRBool on = PR_FALSE;
if (!pOn) {
PORT_SetError(SEC_ERROR_INVALID_ARGS);
@@ -935,58 +940,100 @@ SSL_OptionGetDefault(PRInt32 which, PRBool *pOn)
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;
- case SSL_ENABLE_NPN: on = ssl_defaults.enableNPN; break;
- case SSL_ENABLE_ALPN: on = ssl_defaults.enableALPN; break;
- case SSL_REUSE_SERVER_ECDHE_KEY:
- on = ssl_defaults.reuseServerECDHEKey;
- break;
- case SSL_ENABLE_FALLBACK_SCSV:
- on = ssl_defaults.enableFallbackSCSV;
- break;
- case SSL_ENABLE_SERVER_DHE:
- on = ssl_defaults.enableServerDhe;
- break;
- case SSL_ENABLE_EXTENDED_MASTER_SECRET:
- on = ssl_defaults.enableExtendedMS;
- break;
-
- default:
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- rv = SECFailure;
+ 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:
+ case SSL_V2_COMPATIBLE_HELLO:
+ on = PR_FALSE;
+ break;
+ case SSL_NO_CACHE:
+ on = ssl_defaults.noCache;
+ break;
+ case SSL_ENABLE_FDX:
+ on = ssl_defaults.fdx;
+ break;
+ case SSL_ROLLBACK_DETECTION:
+ on = ssl_defaults.detectRollBack;
+ break;
+ case SSL_NO_STEP_DOWN:
+ on = PR_FALSE;
+ break;
+ case SSL_BYPASS_PKCS11:
+ on = PR_FALSE;
+ 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;
+ case SSL_ENABLE_NPN:
+ on = ssl_defaults.enableNPN;
+ break;
+ case SSL_ENABLE_ALPN:
+ on = ssl_defaults.enableALPN;
+ break;
+ case SSL_REUSE_SERVER_ECDHE_KEY:
+ on = ssl_defaults.reuseServerECDHEKey;
+ break;
+ case SSL_ENABLE_FALLBACK_SCSV:
+ on = ssl_defaults.enableFallbackSCSV;
+ break;
+ case SSL_ENABLE_SERVER_DHE:
+ on = ssl_defaults.enableServerDhe;
+ break;
+ case SSL_ENABLE_EXTENDED_MASTER_SECRET:
+ on = ssl_defaults.enableExtendedMS;
+ break;
+ case SSL_ENABLE_SIGNED_CERT_TIMESTAMPS:
+ on = ssl_defaults.enableSignedCertTimestamps;
+ break;
+ case SSL_ENABLE_0RTT_DATA:
+ on = ssl_defaults.enable0RttData;
+ break;
+ default:
+ PORT_SetError(SEC_ERROR_INVALID_ARGS);
+ rv = SECFailure;
}
*pOn = on;
@@ -1012,171 +1059,160 @@ SSL_OptionSetDefault(PRInt32 which, PRBool on)
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_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_SECURITY:
+ ssl_defaults.useSecurity = on;
+ break;
- case SSL_REQUEST_CERTIFICATE:
- ssl_defaults.requestCertificate = on;
- break;
+ case SSL_REQUEST_CERTIFICATE:
+ ssl_defaults.requestCertificate = on;
+ break;
- case SSL_REQUIRE_CERTIFICATE:
- ssl_defaults.requireCertificate = 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_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_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_TLS:
+ ssl_EnableTLS(&versions_defaults_stream, on);
+ break;
- case SSL_ENABLE_SSL3:
- ssl_EnableSSL3(&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_ENABLE_SSL2:
+ case SSL_V2_COMPATIBLE_HELLO:
+ /* We no longer support SSL v2.
+ * However, if an old application requests to disable SSL v2,
+ * we shouldn't fail.
+ */
+ if (on) {
+ PORT_SetError(SEC_ERROR_INVALID_ARGS);
+ return SECFailure;
+ }
+ break;
- case SSL_NO_CACHE:
- ssl_defaults.noCache = 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_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 {
+ case SSL_ROLLBACK_DETECTION:
+ ssl_defaults.detectRollBack = on;
+ break;
+
+ case SSL_NO_STEP_DOWN:
+ break;
+
+ case SSL_BYPASS_PKCS11:
+ break;
+
+ case SSL_NO_LOCKS:
+ if (on && ssl_defaults.fdx) {
+ PORT_SetError(SEC_ERROR_INVALID_ARGS);
return SECFailure;
}
- } else {
- ssl_defaults.bypassPKCS11 = PR_FALSE;
- }
- break;
+ 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_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_SESSION_TICKETS:
- ssl_defaults.enableSessionTickets = on;
- break;
+ case SSL_ENABLE_DEFLATE:
+ ssl_defaults.enableDeflate = on;
+ break;
- case SSL_ENABLE_DEFLATE:
- ssl_defaults.enableDeflate = on;
- break;
+ case SSL_ENABLE_RENEGOTIATION:
+ ssl_defaults.enableRenegotiation = on;
+ break;
- case SSL_ENABLE_RENEGOTIATION:
- ssl_defaults.enableRenegotiation = on;
- break;
+ case SSL_REQUIRE_SAFE_NEGOTIATION:
+ ssl_defaults.requireSafeNegotiation = on;
+ break;
- case SSL_REQUIRE_SAFE_NEGOTIATION:
- ssl_defaults.requireSafeNegotiation = on;
- break;
+ case SSL_ENABLE_FALSE_START:
+ ssl_defaults.enableFalseStart = on;
+ break;
- case SSL_ENABLE_FALSE_START:
- ssl_defaults.enableFalseStart = on;
- break;
+ case SSL_CBC_RANDOM_IV:
+ ssl_defaults.cbcRandomIV = on;
+ break;
- case SSL_CBC_RANDOM_IV:
- ssl_defaults.cbcRandomIV = on;
- break;
+ case SSL_ENABLE_OCSP_STAPLING:
+ ssl_defaults.enableOCSPStapling = on;
+ break;
- case SSL_ENABLE_OCSP_STAPLING:
- ssl_defaults.enableOCSPStapling = on;
- break;
+ case SSL_ENABLE_NPN:
+ break;
- case SSL_ENABLE_NPN:
- ssl_defaults.enableNPN = on;
- break;
+ case SSL_ENABLE_ALPN:
+ ssl_defaults.enableALPN = on;
+ break;
- case SSL_ENABLE_ALPN:
- ssl_defaults.enableALPN = on;
- break;
+ case SSL_REUSE_SERVER_ECDHE_KEY:
+ ssl_defaults.reuseServerECDHEKey = on;
+ break;
- case SSL_REUSE_SERVER_ECDHE_KEY:
- ssl_defaults.reuseServerECDHEKey = on;
- break;
+ case SSL_ENABLE_FALLBACK_SCSV:
+ ssl_defaults.enableFallbackSCSV = on;
+ break;
- case SSL_ENABLE_FALLBACK_SCSV:
- ssl_defaults.enableFallbackSCSV = on;
- break;
+ case SSL_ENABLE_SERVER_DHE:
+ ssl_defaults.enableServerDhe = on;
+ break;
+
+ case SSL_ENABLE_EXTENDED_MASTER_SECRET:
+ ssl_defaults.enableExtendedMS = on;
+ break;
- case SSL_ENABLE_SERVER_DHE:
- ssl_defaults.enableServerDhe = on;
- break;
+ case SSL_ENABLE_SIGNED_CERT_TIMESTAMPS:
+ ssl_defaults.enableSignedCertTimestamps = on;
+ break;
- case SSL_ENABLE_EXTENDED_MASTER_SECRET:
- ssl_defaults.enableExtendedMS = on;
- break;
+ case SSL_ENABLE_0RTT_DATA:
+ ssl_defaults.enable0RttData = on;
+ break;
- default:
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- return SECFailure;
+ default:
+ PORT_SetError(SEC_ERROR_INVALID_ARGS);
+ return SECFailure;
}
return SECSuccess;
}
@@ -1186,12 +1222,12 @@ 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;
+ 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;
}
}
@@ -1202,36 +1238,33 @@ ssl_IsRemovedCipherSuite(PRInt32 suite)
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)
+ssl_CipherPolicySet(PRInt32 which, PRInt32 policy)
{
- SECStatus rv = ssl_Init();
-
- if (rv != SECSuccess) {
- return rv;
- }
+ SECStatus rv = SECSuccess;
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_CipherPolicySet(PRInt32 which, PRInt32 policy)
+{
+ SECStatus rv = ssl_Init();
+
+ if (rv != SECSuccess) {
+ return rv;
+ }
+ return ssl_CipherPolicySet(which, policy);
+}
SECStatus
SSL_CipherPolicyGet(PRInt32 which, PRInt32 *oPolicy)
@@ -1245,8 +1278,6 @@ SSL_CipherPolicyGet(PRInt32 which, PRInt32 *oPolicy)
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);
}
@@ -1261,19 +1292,20 @@ SSL_CipherPolicyGet(PRInt32 which, PRInt32 *oPolicy)
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)
+{
+ if (ssl_IsRemovedCipherSuite(which))
+ return SECSuccess;
+ return ssl3_CipherPrefSetDefault((ssl3CipherSuite)which, enabled);
+}
+
+SECStatus
SSL_CipherPrefSetDefault(PRInt32 which, PRBool enabled)
{
SECStatus rv = ssl_Init();
@@ -1281,25 +1313,13 @@ SSL_CipherPrefSetDefault(PRInt32 which, PRBool enabled)
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;
+ return ssl_CipherPrefSetDefault(which, enabled);
}
SECStatus
SSL_CipherPrefGetDefault(PRInt32 which, PRBool *enabled)
{
- SECStatus rv;
+ SECStatus rv;
if (!enabled) {
PORT_SetError(SEC_ERROR_INVALID_ARGS);
@@ -1308,8 +1328,6 @@ SSL_CipherPrefGetDefault(PRInt32 which, PRBool *enabled)
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);
}
@@ -1319,7 +1337,6 @@ SSL_CipherPrefGetDefault(PRInt32 which, PRBool *enabled)
SECStatus
SSL_CipherPrefSet(PRFileDesc *fd, PRInt32 which, PRBool enabled)
{
- SECStatus rv;
sslSocket *ss = ssl_FindSocket(fd);
if (!ss) {
@@ -1328,22 +1345,13 @@ SSL_CipherPrefSet(PRFileDesc *fd, PRInt32 which, PRBool enabled)
}
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;
+ return ssl3_CipherPrefSet(ss, (ssl3CipherSuite)which, enabled);
}
SECStatus
SSL_CipherPrefGet(PRFileDesc *fd, PRInt32 which, PRBool *enabled)
{
- SECStatus rv;
+ SECStatus rv;
sslSocket *ss = ssl_FindSocket(fd);
if (!enabled) {
@@ -1358,8 +1366,6 @@ SSL_CipherPrefGet(PRFileDesc *fd, PRInt32 which, PRBool *enabled)
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);
}
@@ -1369,8 +1375,16 @@ SSL_CipherPrefGet(PRFileDesc *fd, PRInt32 which, PRBool *enabled)
SECStatus
NSS_SetDomesticPolicy(void)
{
- SECStatus status = SECSuccess;
+ SECStatus status = SECSuccess;
const PRUint16 *cipher;
+ SECStatus rv;
+ PRUint32 policy;
+
+ /* If we've already defined some policy oids, skip changing them */
+ rv = NSS_GetAlgorithmPolicy(SEC_OID_APPLY_SSL_POLICY, &policy);
+ if ((rv == SECSuccess) && (policy & NSS_USE_POLICY_IN_SSL)) {
+ return ssl_Init(); /* make sure the policies have bee loaded */
+ }
for (cipher = SSL_ImplementedCiphers; *cipher != 0; ++cipher) {
status = SSL_SetPolicy(*cipher, SSL_ALLOWED);
@@ -1393,13 +1407,54 @@ NSS_SetFrancePolicy(void)
}
SECStatus
-SSL_DHEGroupPrefSet(PRFileDesc *fd,
- SSLDHEGroupType *groups,
+SSL_NamedGroupConfig(PRFileDesc *fd, const SSLNamedGroup *groups,
+ unsigned int numGroups)
+{
+ unsigned int i;
+ unsigned int j = 0;
+ sslSocket *ss = ssl_FindSocket(fd);
+
+ if (!ss) {
+ PORT_SetError(SEC_ERROR_NOT_INITIALIZED);
+ return SECFailure;
+ }
+
+ if (!groups) {
+ PORT_SetError(SEC_ERROR_INVALID_ARGS);
+ return SECFailure;
+ }
+ if (numGroups > SSL_NAMED_GROUP_COUNT) {
+ PORT_SetError(SEC_ERROR_INVALID_ARGS);
+ return SECFailure;
+ }
+
+ memset((void *)ss->namedGroupPreferences, 0,
+ sizeof(ss->namedGroupPreferences));
+ for (i = 0; i < numGroups; ++i) {
+ const sslNamedGroupDef *groupDef = ssl_LookupNamedGroup(groups[i]);
+ if (!ssl_NamedGroupEnabled(ss, groupDef)) {
+ ss->namedGroupPreferences[j++] = groupDef;
+ }
+ }
+
+ return SECSuccess;
+}
+
+SECStatus
+SSL_DHEGroupPrefSet(PRFileDesc *fd, const SSLDHEGroupType *groups,
PRUint16 num_groups)
{
sslSocket *ss;
-
- if ((num_groups && !groups) || (!num_groups && groups)) {
+ const SSLDHEGroupType *list;
+ unsigned int count;
+ int i, k, j;
+ const sslNamedGroupDef *enabled[SSL_NAMED_GROUP_COUNT] = { 0 };
+ static const SSLDHEGroupType default_dhe_groups[] = {
+ ssl_ff_dhe_2048_group
+ };
+
+ if ((num_groups && !groups) || (!num_groups && groups) ||
+ num_groups > SSL_NAMED_GROUP_COUNT) {
PORT_SetError(SEC_ERROR_INVALID_ARGS);
return SECFailure;
}
@@ -1410,25 +1465,73 @@ SSL_DHEGroupPrefSet(PRFileDesc *fd,
return SECFailure;
}
- if (ss->ssl3.dheGroups) {
- PORT_Free(ss->ssl3.dheGroups);
- ss->ssl3.dheGroups = NULL;
- ss->ssl3.numDHEGroups = 0;
+ if (groups) {
+ list = groups;
+ count = num_groups;
+ } else {
+ list = default_dhe_groups;
+ count = PR_ARRAY_SIZE(default_dhe_groups);
+ }
+
+ /* save enabled ec groups and clear ss->namedGroupPreferences */
+ k = 0;
+ for (i = 0; i < SSL_NAMED_GROUP_COUNT; ++i) {
+ if (ss->namedGroupPreferences[i] &&
+ ss->namedGroupPreferences[i]->keaType != ssl_kea_dh) {
+ enabled[k++] = ss->namedGroupPreferences[i];
+ }
+ ss->namedGroupPreferences[i] = NULL;
}
- if (groups) {
- ss->ssl3.dheGroups = PORT_NewArray(SSLDHEGroupType, num_groups);
- if (!ss->ssl3.dheGroups) {
- PORT_SetError(SEC_ERROR_NO_MEMORY);
- return SECFailure;
+ ss->ssl3.dhePreferredGroup = NULL;
+ for (i = 0; i < count; ++i) {
+ PRBool duplicate = PR_FALSE;
+ SSLNamedGroup name;
+ const sslNamedGroupDef *groupDef;
+ switch (list[i]) {
+ case ssl_ff_dhe_2048_group:
+ name = ssl_grp_ffdhe_2048;
+ break;
+ case ssl_ff_dhe_3072_group:
+ name = ssl_grp_ffdhe_3072;
+ break;
+ case ssl_ff_dhe_4096_group:
+ name = ssl_grp_ffdhe_4096;
+ break;
+ case ssl_ff_dhe_6144_group:
+ name = ssl_grp_ffdhe_6144;
+ break;
+ case ssl_ff_dhe_8192_group:
+ name = ssl_grp_ffdhe_8192;
+ break;
+ default:
+ PORT_SetError(SEC_ERROR_INVALID_ARGS);
+ return SECFailure;
+ }
+ groupDef = ssl_LookupNamedGroup(name);
+ PORT_Assert(groupDef);
+ if (!ss->ssl3.dhePreferredGroup) {
+ ss->ssl3.dhePreferredGroup = groupDef;
+ }
+ PORT_Assert(k < SSL_NAMED_GROUP_COUNT);
+ for (j = 0; j < k; ++j) {
+ /* skip duplicates */
+ if (enabled[j] == groupDef) {
+ duplicate = PR_TRUE;
+ break;
+ }
}
- PORT_Memcpy(ss->ssl3.dheGroups, groups,
- sizeof(SSLDHEGroupType) * num_groups);
+ if (!duplicate) {
+ enabled[k++] = groupDef;
+ }
+ }
+ for (i = 0; i < k; ++i) {
+ ss->namedGroupPreferences[i] = enabled[i];
}
+
return SECSuccess;
}
-
PRCallOnceType gWeakDHParamsRegisterOnce;
int gWeakDHParamsRegisterError;
@@ -1438,6 +1541,7 @@ int gWeakDHParamsError;
* even though we only make use of it's parameters through gWeakDHParam. */
static PQGParams *gWeakParamsPQG;
static ssl3DHParams *gWeakDHParams;
+#define WEAK_DHE_SIZE 1024
static PRStatus
ssl3_CreateWeakDHParams(void)
@@ -1447,7 +1551,7 @@ ssl3_CreateWeakDHParams(void)
PORT_Assert(!gWeakDHParams && !gWeakParamsPQG);
- rv = PK11_PQG_ParamGenV2(1024, 160, 64 /*maximum seed that will work*/,
+ rv = PK11_PQG_ParamGenV2(WEAK_DHE_SIZE, 160, 64 /*maximum seed that will work*/,
&gWeakParamsPQG, &vfy);
if (rv != SECSuccess) {
gWeakDHParamsError = PORT_GetError();
@@ -1457,7 +1561,7 @@ ssl3_CreateWeakDHParams(void)
rv = PK11_PQG_VerifyParams(gWeakParamsPQG, vfy, &passed);
if (rv != SECSuccess || passed != SECSuccess) {
SSL_DBG(("%d: PK11_PQG_VerifyParams failed in ssl3_CreateWeakDHParams",
- SSL_GETPID()));
+ SSL_GETPID()));
gWeakDHParamsError = PORT_GetError();
return PR_FAILURE;
}
@@ -1468,6 +1572,7 @@ ssl3_CreateWeakDHParams(void)
return PR_FAILURE;
}
+ gWeakDHParams->name = ssl_grp_ffdhe_custom;
gWeakDHParams->prime.data = gWeakParamsPQG->prime.data;
gWeakDHParams->prime.len = gWeakParamsPQG->prime.len;
gWeakDHParams->base.data = gWeakParamsPQG->base.data;
@@ -1536,69 +1641,163 @@ SSL_EnableWeakDHEPrimeGroup(PRFileDesc *fd, PRBool enabled)
#include "dhe-param.c"
-static const SSLDHEGroupType ssl_default_dhe_groups[] = {
- ssl_ff_dhe_2048_group
-};
-
-/* Keep this array synchronized with the index definitions in SSLDHEGroupType */
-static const ssl3DHParams *all_ssl3DHParams[] = {
- NULL, /* ssl_dhe_group_none */
- &ff_dhe_2048,
- &ff_dhe_3072,
- &ff_dhe_4096,
- &ff_dhe_6144,
- &ff_dhe_8192,
-};
+const ssl3DHParams *
+ssl_GetDHEParams(const sslNamedGroupDef *groupDef)
+{
+ switch (groupDef->name) {
+ case ssl_grp_ffdhe_2048:
+ return &ff_dhe_2048_params;
+ case ssl_grp_ffdhe_3072:
+ return &ff_dhe_3072_params;
+ case ssl_grp_ffdhe_4096:
+ return &ff_dhe_4096_params;
+ case ssl_grp_ffdhe_6144:
+ return &ff_dhe_6144_params;
+ case ssl_grp_ffdhe_8192:
+ return &ff_dhe_8192_params;
+ case ssl_grp_ffdhe_custom:
+ PORT_Assert(gWeakDHParams);
+ return gWeakDHParams;
+ default:
+ PORT_Assert(0);
+ }
+ return NULL;
+}
-static SSLDHEGroupType
-selectDHEGroup(sslSocket *ss, const SSLDHEGroupType *groups, PRUint16 num_groups)
+/* This validates dh_Ys against the group prime. */
+PRBool
+ssl_IsValidDHEShare(const SECItem *dh_p, const SECItem *dh_Ys)
{
- if (!groups || !num_groups)
- return ssl_dhe_group_none;
+ unsigned int size_p = SECKEY_BigIntegerBitLength(dh_p);
+ unsigned int size_y = SECKEY_BigIntegerBitLength(dh_Ys);
+ unsigned int commonPart;
+ int cmp;
- /* We don't have automatic group parameter selection yet
- * (potentially) based on socket parameters, e.g. key sizes.
- * For now, we return the first available group from the allowed list. */
- return groups[0];
+ if (dh_p->len == 0 || dh_Ys->len == 0) {
+ return PR_FALSE;
+ }
+ /* Check that the prime is at least odd. */
+ if ((dh_p->data[dh_p->len - 1] & 0x01) == 0) {
+ return PR_FALSE;
+ }
+ /* dh_Ys can't be 1, or bigger than dh_p. */
+ if (size_y <= 1 || size_y > size_p) {
+ return PR_FALSE;
+ }
+ /* If dh_Ys is shorter, then it's definitely smaller than p-1. */
+ if (size_y < size_p) {
+ return PR_TRUE;
+ }
+
+ /* Compare the common part of each, minus the final octet. */
+ commonPart = (size_p + 7) / 8;
+ PORT_Assert(commonPart <= dh_Ys->len);
+ PORT_Assert(commonPart <= dh_p->len);
+ cmp = PORT_Memcmp(dh_Ys->data + dh_Ys->len - commonPart,
+ dh_p->data + dh_p->len - commonPart, commonPart - 1);
+ if (cmp < 0) {
+ return PR_TRUE;
+ }
+ if (cmp > 0) {
+ return PR_FALSE;
+ }
+
+ /* The last octet of the prime is the only thing that is different and that
+ * has to be two greater than the share, otherwise we have Ys == p - 1,
+ * and that means small subgroups. */
+ if (dh_Ys->data[dh_Ys->len - 1] >= (dh_p->data[dh_p->len - 1] - 1)) {
+ return PR_FALSE;
+ }
+
+ return PR_TRUE;
}
-/* Ensure DH parameters have been selected */
+/* Checks that the provided DH parameters match those in one of the named groups
+ * that we have enabled. The groups are defined in dhe-param.c and are those
+ * defined in Appendix A of draft-ietf-tls-negotiated-ff-dhe.
+ *
+ * |groupDef| and |dhParams| are optional outparams that identify the group and
+ * its parameters respectively (if this is successful). */
SECStatus
-ssl3_SelectDHParams(sslSocket *ss)
+ssl_ValidateDHENamedGroup(sslSocket *ss,
+ const SECItem *dh_p,
+ const SECItem *dh_g,
+ const sslNamedGroupDef **groupDef,
+ const ssl3DHParams **dhParams)
{
- SSLDHEGroupType selectedGroup = ssl_dhe_group_none;
+ unsigned int i;
- if (ss->ssl3.dheWeakGroupEnabled) {
- ss->dheParams = gWeakDHParams;
- } else {
- if (ss->ssl3.dheGroups) {
- selectedGroup = selectDHEGroup(ss, ss->ssl3.dheGroups,
- ss->ssl3.numDHEGroups);
- } else {
- size_t number_of_default_groups = PR_ARRAY_SIZE(ssl_default_dhe_groups);
- selectedGroup = selectDHEGroup(ss, ssl_default_dhe_groups,
- number_of_default_groups);
+ for (i = 0; i < SSL_NAMED_GROUP_COUNT; ++i) {
+ const ssl3DHParams *params;
+ if (!ss->namedGroupPreferences[i]) {
+ continue;
+ }
+ if (ss->namedGroupPreferences[i]->keaType != ssl_kea_dh) {
+ continue;
}
- if (selectedGroup == ssl_dhe_group_none ||
- selectedGroup >= ssl_dhe_group_max) {
- return SECFailure;
+ params = ssl_GetDHEParams(ss->namedGroupPreferences[i]);
+ PORT_Assert(params);
+ if (SECITEM_ItemsAreEqual(&params->prime, dh_p)) {
+ if (!SECITEM_ItemsAreEqual(&params->base, dh_g)) {
+ return SECFailure;
+ }
+ if (groupDef)
+ *groupDef = ss->namedGroupPreferences[i];
+ if (dhParams)
+ *dhParams = params;
+ return SECSuccess;
}
+ }
- ss->dheParams = all_ssl3DHParams[selectedGroup];
+ return SECFailure;
+}
+
+/* Ensure DH parameters have been selected. This just picks the first enabled
+ * FFDHE group in ssl_named_groups, or the weak one if it was enabled. */
+SECStatus
+ssl_SelectDHEGroup(sslSocket *ss, const sslNamedGroupDef **groupDef)
+{
+ unsigned int i;
+ static const sslNamedGroupDef weak_group_def = {
+ ssl_grp_ffdhe_custom, WEAK_DHE_SIZE, ssl_kea_dh,
+ SEC_OID_TLS_DHE_CUSTOM, PR_TRUE
+ };
+
+ /* Only select weak groups in TLS 1.2 and earlier, but not if the client has
+ * indicated that it supports an FFDHE named group. */
+ if (ss->ssl3.dheWeakGroupEnabled &&
+ ss->version < SSL_LIBRARY_VERSION_TLS_1_3 &&
+ !ss->xtnData.peerSupportsFfdheGroups) {
+ *groupDef = &weak_group_def;
+ return SECSuccess;
+ }
+ if (ss->ssl3.dhePreferredGroup &&
+ ssl_NamedGroupEnabled(ss, ss->ssl3.dhePreferredGroup)) {
+ *groupDef = ss->ssl3.dhePreferredGroup;
+ return SECSuccess;
+ }
+ for (i = 0; i < SSL_NAMED_GROUP_COUNT; ++i) {
+ if (ss->namedGroupPreferences[i] &&
+ ss->namedGroupPreferences[i]->keaType == ssl_kea_dh) {
+ *groupDef = ss->namedGroupPreferences[i];
+ return SECSuccess;
+ }
}
- return SECSuccess;
+ *groupDef = NULL;
+ PORT_SetError(SSL_ERROR_NO_CYPHER_OVERLAP);
+ return SECFailure;
}
/* LOCKS ??? XXX */
static PRFileDesc *
ssl_ImportFD(PRFileDesc *model, PRFileDesc *fd, SSLProtocolVariant variant)
{
- sslSocket * ns = NULL;
- PRStatus rv;
- PRNetAddr addr;
- SECStatus status = ssl_Init();
+ sslSocket *ns = NULL;
+ PRStatus rv;
+ PRNetAddr addr;
+ SECStatus status = ssl_Init();
if (status != SECSuccess) {
return NULL;
@@ -1608,10 +1807,10 @@ ssl_ImportFD(PRFileDesc *model, PRFileDesc *fd, SSLProtocolVariant variant)
/* 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);
+ 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));
+ SSL_GETPID(), model));
return NULL;
}
ns = ssl_DupSocket(ss);
@@ -1622,12 +1821,12 @@ ssl_ImportFD(PRFileDesc *model, PRFileDesc *fd, SSLProtocolVariant variant)
rv = ssl_PushIOLayer(ns, fd, PR_TOP_IO_LAYER);
if (rv != PR_SUCCESS) {
ssl_FreeSocket(ns);
- SET_ERROR_CODE
+ PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
return NULL;
}
#if defined(DEBUG) || defined(FORCE_PR_ASSERT)
{
- sslSocket * ss = ssl_FindSocket(fd);
+ sslSocket *ss = ssl_FindSocket(fd);
PORT_Assert(ss == ns);
}
#endif
@@ -1692,13 +1891,13 @@ ssl_NextProtoNegoCallback(void *arg, PRFileDesc *fd,
}
/* 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; ) {
+ 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) {
+ 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;
+ ss->xtnData.nextProtoState = SSL_NEXT_PROTO_NEGOTIATED;
result = &protos[i];
goto found;
}
@@ -1711,7 +1910,7 @@ ssl_NextProtoNegoCallback(void *arg, PRFileDesc *fd,
* protocols configured, or none of its options match ours. In this case we
* request our favoured protocol. */
/* This will be treated as a failure for ALPN. */
- ss->ssl3.nextProtoState = SSL_NEXT_PROTO_NO_OVERLAP;
+ ss->xtnData.nextProtoState = SSL_NEXT_PROTO_NO_OVERLAP;
result = ss->opt.nextProtoNego.data;
found:
@@ -1730,7 +1929,7 @@ SSL_SetNextProtoNego(PRFileDesc *fd, const unsigned char *data,
{
sslSocket *ss;
SECStatus rv;
- SECItem dataItem = { siBuffer, (unsigned char *) data, length };
+ SECItem dataItem = { siBuffer, (unsigned char *)data, length };
ss = ssl_FindSocket(fd);
if (!ss) {
@@ -1770,16 +1969,16 @@ SSL_GetNextProto(PRFileDesc *fd, SSLNextProtoState *state, unsigned char *buf,
return SECFailure;
}
- *state = ss->ssl3.nextProtoState;
+ *state = ss->xtnData.nextProtoState;
- if (ss->ssl3.nextProtoState != SSL_NEXT_PROTO_NO_SUPPORT &&
- ss->ssl3.nextProto.data) {
- if (ss->ssl3.nextProto.len > bufLenMax) {
+ if (ss->xtnData.nextProtoState != SSL_NEXT_PROTO_NO_SUPPORT &&
+ ss->xtnData.nextProto.data) {
+ if (ss->xtnData.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;
+ PORT_Memcpy(buf, ss->xtnData.nextProto.data, ss->xtnData.nextProto.len);
+ *bufLen = ss->xtnData.nextProto.len;
} else {
*bufLen = 0;
}
@@ -1787,9 +1986,10 @@ SSL_GetNextProto(PRFileDesc *fd, SSLNextProtoState *state, unsigned char *buf,
return SECSuccess;
}
-SECStatus SSL_SetSRTPCiphers(PRFileDesc *fd,
- const PRUint16 *ciphers,
- unsigned int numCiphers)
+SECStatus
+SSL_SetSRTPCiphers(PRFileDesc *fd,
+ const PRUint16 *ciphers,
+ unsigned int numCiphers)
{
sslSocket *ss;
unsigned int i;
@@ -1821,8 +2021,9 @@ SECStatus SSL_SetSRTPCiphers(PRFileDesc *fd,
ciphers[i];
} else {
SSL_DBG(("%d: SSL[%d]: invalid or unimplemented SRTP cipher "
- "suite specified: 0x%04hx", SSL_GETPID(), fd,
- ciphers[i]));
+ "suite specified: 0x%04hx",
+ SSL_GETPID(), fd,
+ ciphers[i]));
}
}
@@ -1837,7 +2038,7 @@ SECStatus SSL_SetSRTPCiphers(PRFileDesc *fd,
SECStatus
SSL_GetSRTPCipher(PRFileDesc *fd, PRUint16 *cipher)
{
- sslSocket * ss;
+ sslSocket *ss;
ss = ssl_FindSocket(fd);
if (!ss) {
@@ -1847,22 +2048,20 @@ SSL_GetSRTPCipher(PRFileDesc *fd, PRUint16 *cipher)
return SECFailure;
}
- if (!ss->ssl3.dtlsSRTPCipherSuite) {
+ if (!ss->xtnData.dtlsSRTPCipherSuite) {
PORT_SetError(SEC_ERROR_INVALID_ARGS);
return SECFailure;
}
- *cipher = ss->ssl3.dtlsSRTPCipherSuite;
+ *cipher = ss->xtnData.dtlsSRTPCipherSuite;
return SECSuccess;
}
PRFileDesc *
SSL_ReconfigFD(PRFileDesc *model, PRFileDesc *fd)
{
- sslSocket * sm = NULL, *ss = NULL;
- int i;
- sslServerCerts * mc = NULL;
- sslServerCerts * sc = NULL;
+ sslSocket *sm = NULL, *ss = NULL;
+ PRCList *cursor;
if (model == NULL) {
PR_SetError(SEC_ERROR_INVALID_ARGS, 0);
@@ -1881,69 +2080,51 @@ SSL_ReconfigFD(PRFileDesc *model, PRFileDesc *fd)
return NULL;
}
- ss->opt = sm->opt;
+ 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;
- PORT_Memcpy(ss->ssl3.signatureAlgorithms, sm->ssl3.signatureAlgorithms,
- sizeof(ss->ssl3.signatureAlgorithms[0]) *
- sm->ssl3.signatureAlgorithmCount);
- ss->ssl3.signatureAlgorithmCount = sm->ssl3.signatureAlgorithmCount;
+ PORT_Memcpy(ss->ssl3.signatureSchemes, sm->ssl3.signatureSchemes,
+ sizeof(ss->ssl3.signatureSchemes[0]) *
+ sm->ssl3.signatureSchemeCount);
+ ss->ssl3.signatureSchemeCount = sm->ssl3.signatureSchemeCount;
+ ss->ssl3.downgradeCheckVersion = sm->ssl3.downgradeCheckVersion;
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 (sm->certStatusArray[i]) {
- if (ss->certStatusArray[i]) {
- SECITEM_FreeArray(ss->certStatusArray[i], PR_TRUE);
- ss->certStatusArray[i] = NULL;
- }
- ss->certStatusArray[i] = SECITEM_DupArray(NULL, sm->certStatusArray[i]);
- if (!ss->certStatusArray[i])
- goto loser;
- }
- }
- if (mc->serverKeyPair) {
- if (sc->serverKeyPair) {
- ssl3_FreeKeyPair(sc->serverKeyPair);
- }
- sc->serverKeyPair = ssl3_GetKeyPairRef(mc->serverKeyPair);
- sc->serverKeyBits = mc->serverKeyBits;
- }
+ while (!PR_CLIST_IS_EMPTY(&ss->serverCerts)) {
+ cursor = PR_LIST_TAIL(&ss->serverCerts);
+ PR_REMOVE_LINK(cursor);
+ ssl_FreeServerCert((sslServerCert *)cursor);
}
- if (sm->stepDownKeyPair) {
- if (ss->stepDownKeyPair) {
- ssl3_FreeKeyPair(ss->stepDownKeyPair);
- }
- ss->stepDownKeyPair = ssl3_GetKeyPairRef(sm->stepDownKeyPair);
+ for (cursor = PR_NEXT_LINK(&sm->serverCerts);
+ cursor != &sm->serverCerts;
+ cursor = PR_NEXT_LINK(cursor)) {
+ sslServerCert *sc = ssl_CopyServerCert((sslServerCert *)cursor);
+ if (!sc)
+ return NULL;
+ PR_APPEND_LINK(&sc->link, &ss->serverCerts);
}
- if (sm->ephemeralECDHKeyPair) {
- if (ss->ephemeralECDHKeyPair) {
- ssl3_FreeKeyPair(ss->ephemeralECDHKeyPair);
- }
- ss->ephemeralECDHKeyPair =
- ssl3_GetKeyPairRef(sm->ephemeralECDHKeyPair);
+
+ ssl_FreeEphemeralKeyPairs(ss);
+ for (cursor = PR_NEXT_LINK(&sm->ephemeralKeyPairs);
+ cursor != &sm->ephemeralKeyPairs;
+ cursor = PR_NEXT_LINK(cursor)) {
+ sslEphemeralKeyPair *mkp = (sslEphemeralKeyPair *)cursor;
+ sslEphemeralKeyPair *skp = ssl_CopyEphemeralKeyPair(mkp);
+ if (!skp)
+ return NULL;
+ PR_APPEND_LINK(&skp->link, &ss->ephemeralKeyPairs);
}
+ PORT_Memcpy((void *)ss->namedGroupPreferences,
+ sm->namedGroupPreferences,
+ sizeof(ss->namedGroupPreferences));
+ ss->additionalShares = sm->additionalShares;
+
/* copy trust anchor names */
if (sm->ssl3.ca_list) {
if (ss->ssl3.ca_list) {
@@ -1951,53 +2132,147 @@ SSL_ReconfigFD(PRFileDesc *model, PRFileDesc *fd)
}
ss->ssl3.ca_list = CERT_DupDistNames(sm->ssl3.ca_list);
if (!ss->ssl3.ca_list) {
- goto loser;
+ return NULL;
}
}
if (sm->authCertificate)
- ss->authCertificate = sm->authCertificate;
+ ss->authCertificate = sm->authCertificate;
if (sm->authCertificateArg)
- ss->authCertificateArg = sm->authCertificateArg;
+ ss->authCertificateArg = sm->authCertificateArg;
if (sm->getClientAuthData)
- ss->getClientAuthData = sm->getClientAuthData;
+ ss->getClientAuthData = sm->getClientAuthData;
if (sm->getClientAuthDataArg)
- ss->getClientAuthDataArg = sm->getClientAuthDataArg;
+ ss->getClientAuthDataArg = sm->getClientAuthDataArg;
if (sm->sniSocketConfig)
- ss->sniSocketConfig = sm->sniSocketConfig;
+ ss->sniSocketConfig = sm->sniSocketConfig;
if (sm->sniSocketConfigArg)
- ss->sniSocketConfigArg = sm->sniSocketConfigArg;
+ ss->sniSocketConfigArg = sm->sniSocketConfigArg;
if (sm->handleBadCert)
- ss->handleBadCert = sm->handleBadCert;
+ ss->handleBadCert = sm->handleBadCert;
if (sm->badCertArg)
- ss->badCertArg = sm->badCertArg;
+ ss->badCertArg = sm->badCertArg;
if (sm->handshakeCallback)
- ss->handshakeCallback = sm->handshakeCallback;
+ ss->handshakeCallback = sm->handshakeCallback;
if (sm->handshakeCallbackData)
ss->handshakeCallbackData = sm->handshakeCallbackData;
if (sm->pkcs11PinArg)
- ss->pkcs11PinArg = sm->pkcs11PinArg;
+ ss->pkcs11PinArg = sm->pkcs11PinArg;
return fd;
-loser:
- return NULL;
+}
+
+/*
+ * Get the user supplied range
+ */
+static SECStatus
+ssl3_GetRangePolicy(SSLProtocolVariant protocolVariant, SSLVersionRange *prange)
+{
+ SECStatus rv;
+ PRUint32 policy;
+ PRInt32 option;
+
+ /* only use policy constraints if we've set the apply ssl policy bit */
+ rv = NSS_GetAlgorithmPolicy(SEC_OID_APPLY_SSL_POLICY, &policy);
+ if ((rv != SECSuccess) || !(policy & NSS_USE_POLICY_IN_SSL)) {
+ return SECFailure;
+ }
+ rv = NSS_OptionGet(VERSIONS_POLICY_MIN(protocolVariant), &option);
+ if (rv != SECSuccess) {
+ return rv;
+ }
+ prange->min = (PRUint16)option;
+ rv = NSS_OptionGet(VERSIONS_POLICY_MAX(protocolVariant), &option);
+ if (rv != SECSuccess) {
+ return rv;
+ }
+ prange->max = (PRUint16)option;
+ if (prange->max < prange->min) {
+ return SECFailure; /* don't accept an invalid policy */
+ }
+ return SECSuccess;
+}
+
+/*
+ * Constrain a single protocol variant's range based on the user policy
+ */
+static SECStatus
+ssl3_ConstrainVariantRangeByPolicy(SSLProtocolVariant protocolVariant)
+{
+ SSLVersionRange vrange;
+ SSLVersionRange pvrange;
+ SECStatus rv;
+
+ vrange = *VERSIONS_DEFAULTS(protocolVariant);
+ rv = ssl3_GetRangePolicy(protocolVariant, &pvrange);
+ if (rv != SECSuccess) {
+ return SECSuccess; /* we don't have any policy */
+ }
+ vrange.min = PR_MAX(vrange.min, pvrange.min);
+ vrange.max = PR_MIN(vrange.max, pvrange.max);
+ if (vrange.max >= vrange.min) {
+ *VERSIONS_DEFAULTS(protocolVariant) = vrange;
+ } else {
+ /* there was no overlap, turn off range altogether */
+ pvrange.min = pvrange.max = SSL_LIBRARY_VERSION_NONE;
+ *VERSIONS_DEFAULTS(protocolVariant) = pvrange;
+ }
+ return SECSuccess;
+}
+
+static PRBool
+ssl_VersionIsSupportedByPolicy(SSLProtocolVariant protocolVariant,
+ SSL3ProtocolVersion version)
+{
+ SSLVersionRange pvrange;
+ SECStatus rv;
+
+ rv = ssl3_GetRangePolicy(protocolVariant, &pvrange);
+ if (rv == SECSuccess) {
+ if ((version > pvrange.max) || (version < pvrange.min)) {
+ return PR_FALSE; /* disallowed by policy */
+ }
+ }
+ return PR_TRUE;
+}
+
+/*
+ * This is called at SSL init time to constrain the existing range based
+ * on user supplied policy.
+ */
+SECStatus
+ssl3_ConstrainRangeByPolicy(void)
+{
+ SECStatus rv;
+ rv = ssl3_ConstrainVariantRangeByPolicy(ssl_variant_stream);
+ if (rv != SECSuccess) {
+ return rv;
+ }
+ rv = ssl3_ConstrainVariantRangeByPolicy(ssl_variant_datagram);
+ if (rv != SECSuccess) {
+ return rv;
+ }
+ return SECSuccess;
}
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);
+ if (!ssl_VersionIsSupportedByPolicy(protocolVariant, version)) {
return PR_FALSE;
}
+ 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
@@ -2010,7 +2285,28 @@ ssl3_VersionRangeIsValid(SSLProtocolVariant protocolVariant,
return vrange &&
vrange->min <= vrange->max &&
ssl3_VersionIsSupported(protocolVariant, vrange->min) &&
- ssl3_VersionIsSupported(protocolVariant, vrange->max);
+ ssl3_VersionIsSupported(protocolVariant, vrange->max) &&
+ (vrange->min > SSL_LIBRARY_VERSION_3_0 ||
+ vrange->max < SSL_LIBRARY_VERSION_TLS_1_3);
+}
+
+const SECItem *
+SSL_PeerSignedCertTimestamps(PRFileDesc *fd)
+{
+ sslSocket *ss = ssl_FindSocket(fd);
+
+ if (!ss) {
+ SSL_DBG(("%d: SSL[%d]: bad socket in SSL_PeerSignedCertTimestamps",
+ SSL_GETPID(), fd));
+ return NULL;
+ }
+
+ if (!ss->sec.ci.sid) {
+ PORT_SetError(SEC_ERROR_NOT_INITIALIZED);
+ return NULL;
+ }
+
+ return &ss->sec.ci.sid->u.ssl3.signedCertTimestamps;
}
SECStatus
@@ -2023,17 +2319,21 @@ SSL_VersionRangeGetSupported(SSLProtocolVariant protocolVariant,
}
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;
+ case ssl_variant_stream:
+ vrange->min = SSL_LIBRARY_VERSION_3_0;
+ vrange->max = SSL_LIBRARY_VERSION_MAX_SUPPORTED;
+ // We don't allow SSLv3 and TLSv1.3 together.
+ if (vrange->max == SSL_LIBRARY_VERSION_TLS_1_3) {
+ vrange->min = SSL_LIBRARY_VERSION_TLS_1_0;
+ }
+ 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;
@@ -2044,7 +2344,8 @@ SSL_VersionRangeGetDefault(SSLProtocolVariant protocolVariant,
SSLVersionRange *vrange)
{
if ((protocolVariant != ssl_variant_stream &&
- protocolVariant != ssl_variant_datagram) || !vrange) {
+ protocolVariant != ssl_variant_datagram) ||
+ !vrange) {
PORT_SetError(SEC_ERROR_INVALID_ARGS);
return SECFailure;
}
@@ -2074,8 +2375,8 @@ 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));
+ SSL_DBG(("%d: SSL[%d]: bad socket in SSL_VersionRangeGet",
+ SSL_GETPID(), fd));
return SECFailure;
}
@@ -2101,8 +2402,8 @@ 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));
+ SSL_DBG(("%d: SSL[%d]: bad socket in SSL_VersionRangeSet",
+ SSL_GETPID(), fd));
return SECFailure;
}
@@ -2114,6 +2415,14 @@ SSL_VersionRangeSet(PRFileDesc *fd, const SSLVersionRange *vrange)
ssl_Get1stHandshakeLock(ss);
ssl_GetSSL3HandshakeLock(ss);
+ if (ss->ssl3.downgradeCheckVersion &&
+ ss->vrange.max > ss->ssl3.downgradeCheckVersion) {
+ PORT_SetError(SSL_ERROR_INVALID_VERSION_RANGE);
+ ssl_ReleaseSSL3HandshakeLock(ss);
+ ssl_Release1stHandshakeLock(ss);
+ return SECFailure;
+ }
+
ss->vrange = *vrange;
ssl_ReleaseSSL3HandshakeLock(ss);
@@ -2122,20 +2431,54 @@ SSL_VersionRangeSet(PRFileDesc *fd, const SSLVersionRange *vrange)
return SECSuccess;
}
+SECStatus
+SSL_SetDowngradeCheckVersion(PRFileDesc *fd, PRUint16 version)
+{
+ sslSocket *ss = ssl_FindSocket(fd);
+ SECStatus rv = SECFailure;
+
+ if (!ss) {
+ SSL_DBG(("%d: SSL[%d]: bad socket in SSL_SetDowngradeCheckVersion",
+ SSL_GETPID(), fd));
+ return SECFailure;
+ }
+
+ if (version && !ssl3_VersionIsSupported(ss->protocolVariant, version)) {
+ PORT_SetError(SEC_ERROR_INVALID_ARGS);
+ return SECFailure;
+ }
+
+ ssl_Get1stHandshakeLock(ss);
+ ssl_GetSSL3HandshakeLock(ss);
+
+ if (version && version < ss->vrange.max) {
+ PORT_SetError(SEC_ERROR_INVALID_ARGS);
+ goto loser;
+ }
+ ss->ssl3.downgradeCheckVersion = version;
+ rv = SECSuccess;
+
+loser:
+ ssl_ReleaseSSL3HandshakeLock(ss);
+ ssl_Release1stHandshakeLock(ss);
+
+ return rv;
+}
+
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;
+ 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;
+ PORT_SetError(SEC_ERROR_NOT_INITIALIZED);
+ return NULL;
}
return &ss->sec.ci.sid->peerCertStatus;
@@ -2146,14 +2489,14 @@ SSL_PeerStapledOCSPResponses(PRFileDesc *fd)
** They all get called through the NSPRIOMethods table below.
*/
-static PRFileDesc * PR_CALLBACK
+static PRFileDesc *PR_CALLBACK
ssl_Accept(PRFileDesc *fd, PRNetAddr *sockaddr, PRIntervalTime timeout)
{
- sslSocket *ss;
- sslSocket *ns = NULL;
- PRFileDesc *newfd = NULL;
+ sslSocket *ss;
+ sslSocket *ns = NULL;
+ PRFileDesc *newfd = NULL;
PRFileDesc *osfd;
- PRStatus status;
+ PRStatus status;
ss = ssl_GetPrivate(fd);
if (!ss) {
@@ -2184,7 +2527,7 @@ ssl_Accept(PRFileDesc *fd, PRNetAddr *sockaddr, PRIntervalTime timeout)
ssl_ReleaseSSL3HandshakeLock(ss);
ssl_Release1stHandshakeLock(ss);
SSL_UNLOCK_WRITER(ss);
- SSL_UNLOCK_READER(ss); /* ss isn't used below here. */
+ SSL_UNLOCK_READER(ss); /* ss isn't used below here. */
if (ns == NULL)
goto loser;
@@ -2197,12 +2540,12 @@ ssl_Accept(PRFileDesc *fd, PRNetAddr *sockaddr, PRIntervalTime timeout)
/* 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;
+ if (ns->opt.useSecurity) {
+ if (ns->opt.handshakeAsClient) {
+ ns->handshake = ssl_BeginClientHandshake;
ss->handshaking = sslHandshakingAsClient;
} else {
- ns->handshake = ssl2_BeginServerHandshake;
+ ns->handshake = ssl_BeginServerHandshake;
ss->handshaking = sslHandshakingAsServer;
}
}
@@ -2221,7 +2564,7 @@ static PRStatus PR_CALLBACK
ssl_Connect(PRFileDesc *fd, const PRNetAddr *sockaddr, PRIntervalTime timeout)
{
sslSocket *ss;
- PRStatus rv;
+ PRStatus rv;
ss = ssl_GetPrivate(fd);
if (!ss) {
@@ -2245,8 +2588,8 @@ ssl_Connect(PRFileDesc *fd, const PRNetAddr *sockaddr, PRIntervalTime timeout)
static PRStatus PR_CALLBACK
ssl_Bind(PRFileDesc *fd, const PRNetAddr *addr)
{
- sslSocket * ss = ssl_GetPrivate(fd);
- PRStatus rv;
+ sslSocket *ss = ssl_GetPrivate(fd);
+ PRStatus rv;
if (!ss) {
SSL_DBG(("%d: SSL[%d]: bad socket in bind", SSL_GETPID(), fd));
@@ -2265,8 +2608,8 @@ ssl_Bind(PRFileDesc *fd, const PRNetAddr *addr)
static PRStatus PR_CALLBACK
ssl_Listen(PRFileDesc *fd, PRIntn backlog)
{
- sslSocket * ss = ssl_GetPrivate(fd);
- PRStatus rv;
+ sslSocket *ss = ssl_GetPrivate(fd);
+ PRStatus rv;
if (!ss) {
SSL_DBG(("%d: SSL[%d]: bad socket in listen", SSL_GETPID(), fd));
@@ -2285,8 +2628,8 @@ ssl_Listen(PRFileDesc *fd, PRIntn backlog)
static PRStatus PR_CALLBACK
ssl_Shutdown(PRFileDesc *fd, PRIntn how)
{
- sslSocket * ss = ssl_GetPrivate(fd);
- PRStatus rv;
+ sslSocket *ss = ssl_GetPrivate(fd);
+ PRStatus rv;
if (!ss) {
SSL_DBG(("%d: SSL[%d]: bad socket in shutdown", SSL_GETPID(), fd));
@@ -2314,7 +2657,7 @@ static PRStatus PR_CALLBACK
ssl_Close(PRFileDesc *fd)
{
sslSocket *ss;
- PRStatus rv;
+ PRStatus rv;
ss = ssl_GetPrivate(fd);
if (!ss) {
@@ -2342,7 +2685,7 @@ ssl_Recv(PRFileDesc *fd, void *buf, PRInt32 len, PRIntn flags,
PRIntervalTime timeout)
{
sslSocket *ss;
- int rv;
+ int rv;
ss = ssl_GetPrivate(fd);
if (!ss) {
@@ -2353,7 +2696,7 @@ ssl_Recv(PRFileDesc *fd, void *buf, PRInt32 len, PRIntn flags,
ss->rTimeout = timeout;
if (!ss->opt.fdx)
ss->wTimeout = timeout;
- rv = (*ss->ops->recv)(ss, (unsigned char*)buf, len, flags);
+ rv = (*ss->ops->recv)(ss, (unsigned char *)buf, len, flags);
SSL_UNLOCK_READER(ss);
return rv;
}
@@ -2363,7 +2706,7 @@ ssl_Send(PRFileDesc *fd, const void *buf, PRInt32 len, PRIntn flags,
PRIntervalTime timeout)
{
sslSocket *ss;
- int rv;
+ int rv;
ss = ssl_GetPrivate(fd);
if (!ss) {
@@ -2374,7 +2717,7 @@ ssl_Send(PRFileDesc *fd, const void *buf, PRInt32 len, PRIntn flags,
ss->wTimeout = timeout;
if (!ss->opt.fdx)
ss->rTimeout = timeout;
- rv = (*ss->ops->send)(ss, (const unsigned char*)buf, len, flags);
+ rv = (*ss->ops->send)(ss, (const unsigned char *)buf, len, flags);
SSL_UNLOCK_WRITER(ss);
return rv;
}
@@ -2383,7 +2726,7 @@ static int PR_CALLBACK
ssl_Read(PRFileDesc *fd, void *buf, PRInt32 len)
{
sslSocket *ss;
- int rv;
+ int rv;
ss = ssl_GetPrivate(fd);
if (!ss) {
@@ -2394,7 +2737,7 @@ ssl_Read(PRFileDesc *fd, void *buf, PRInt32 len)
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);
+ rv = (*ss->ops->read)(ss, (unsigned char *)buf, len);
SSL_UNLOCK_READER(ss);
return rv;
}
@@ -2403,7 +2746,7 @@ static int PR_CALLBACK
ssl_Write(PRFileDesc *fd, const void *buf, PRInt32 len)
{
sslSocket *ss;
- int rv;
+ int rv;
ss = ssl_GetPrivate(fd);
if (!ss) {
@@ -2414,7 +2757,7 @@ ssl_Write(PRFileDesc *fd, const void *buf, PRInt32 len)
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);
+ rv = (*ss->ops->write)(ss, (const unsigned char *)buf, len);
SSL_UNLOCK_WRITER(ss);
return rv;
}
@@ -2437,9 +2780,9 @@ ssl_GetPeerName(PRFileDesc *fd, PRNetAddr *addr)
SECStatus
ssl_GetPeerInfo(sslSocket *ss)
{
- PRFileDesc * osfd;
- int rv;
- PRNetAddr sin;
+ PRFileDesc *osfd;
+ int rv;
+ PRNetAddr sin;
osfd = ss->fd->lower;
@@ -2476,35 +2819,6 @@ ssl_GetSockName(PRFileDesc *fd, PRNetAddr *name)
}
SECStatus
-SSL_SetStapledOCSPResponses(PRFileDesc *fd, const SECItemArray *responses,
- SSLKEAType kea)
-{
- sslSocket *ss;
-
- ss = ssl_FindSocket(fd);
- if (!ss) {
- SSL_DBG(("%d: SSL[%d]: bad socket in SSL_SetStapledOCSPResponses",
- SSL_GETPID(), fd));
- return SECFailure;
- }
-
- if ( kea <= 0 || kea >= kt_kea_size) {
- SSL_DBG(("%d: SSL[%d]: invalid key in SSL_SetStapledOCSPResponses",
- SSL_GETPID(), fd));
- return SECFailure;
- }
-
- if (ss->certStatusArray[kea]) {
- SECITEM_FreeArray(ss->certStatusArray[kea], PR_TRUE);
- ss->certStatusArray[kea] = NULL;
- }
- if (responses) {
- ss->certStatusArray[kea] = SECITEM_DupArray(NULL, responses);
- }
- return (ss->certStatusArray[kea] || !responses) ? SECSuccess : SECFailure;
-}
-
-SECStatus
SSL_SetSockPeerID(PRFileDesc *fd, const char *peerID)
{
sslSocket *ss;
@@ -2531,15 +2845,15 @@ 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;
+ 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 */
+ return 0; /* don't poll on this socket */
}
if (ss->opt.useSecurity &&
@@ -2565,40 +2879,38 @@ ssl_Poll(PRFileDesc *fd, PRInt16 how_flags, PRInt16 *p_out_flags)
new_flags |= PR_POLL_READ;
}
} else
- /* First handshake is in progress */
- if (ss->lastWriteBlocked) {
+ /* 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. */
+ 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
- ** unless we did false start.
- */
- if (!(ss->version >= SSL_LIBRARY_VERSION_3_0 &&
- ss->ssl3.hs.canFalseStart)) {
- new_flags ^= PR_POLL_WRITE; /* don't select on write. */
- }
- new_flags |= PR_POLL_READ; /* do select on read. */
+ /* 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
+ ** unless we did false start.
+ */
+ if (!ss->ssl3.hs.canFalseStart) {
+ 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. */
+ *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. */
+ new_flags |= PR_POLL_WRITE; /* also select on write. */
}
- if (ss->version >= SSL_LIBRARY_VERSION_3_0 &&
- ss->ssl3.hs.restartTarget != NULL) {
+ if (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.
@@ -2626,8 +2938,8 @@ ssl_Poll(PRFileDesc *fd, PRInt16 how_flags, PRInt16 *p_out_flags)
}
if (new_flags && (fd->lower->methods->poll != NULL)) {
- PRInt16 lower_out_flags = 0;
- PRInt16 lower_new_flags;
+ 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)) {
@@ -2640,7 +2952,7 @@ ssl_Poll(PRFileDesc *fd, PRInt16 how_flags, PRInt16 *p_out_flags)
new_flags = how_flags;
} else {
*p_out_flags = lower_out_flags;
- new_flags = lower_new_flags;
+ new_flags = lower_new_flags;
}
}
@@ -2665,14 +2977,13 @@ ssl_TransmitFile(PRFileDesc *sd, PRFileDesc *fd,
return sd->methods->sendfile(sd, &sfd, flags, timeout);
}
-
PRBool
ssl_FdIsBlocking(PRFileDesc *fd)
{
PRSocketOptionData opt;
- PRStatus status;
+ PRStatus status;
- opt.option = PR_SockOpt_Nonblocking;
+ opt.option = PR_SockOpt_Nonblocking;
opt.value.non_blocking = PR_FALSE;
status = PR_GetSocketOption(fd, &opt);
if (status != PR_SUCCESS)
@@ -2686,23 +2997,23 @@ ssl_SocketIsBlocking(sslSocket *ss)
return ssl_FdIsBlocking(ss->fd);
}
-PRInt32 sslFirstBufSize = 8 * 1024;
-PRInt32 sslCopyLimit = 1024;
+PRInt32 sslFirstBufSize = 8 * 1024;
+PRInt32 sslCopyLimit = 1024;
static PRInt32 PR_CALLBACK
ssl_WriteV(PRFileDesc *fd, const PRIOVec *iov, PRInt32 vectors,
PRIntervalTime timeout)
{
- PRInt32 i;
- 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];
+ PRInt32 i;
+ PRInt32 bufLen;
+ PRInt32 left;
+ PRInt32 rv;
+ PRInt32 sent = 0;
+ const PRInt32 first_len = sslFirstBufSize;
+ const PRInt32 limit = sslCopyLimit;
+ PRBool blocking;
+ PRIOVec myIov;
+ char buf[MAX_FRAGMENT_LENGTH];
if (vectors < 0) {
PORT_SetError(PR_INVALID_ARGUMENT_ERROR);
@@ -2721,28 +3032,37 @@ ssl_WriteV(PRFileDesc *fd, const PRIOVec *iov, PRInt32 vectors,
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; \
- } \
- } \
+#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; \
+ PR_ASSERT(!blocking); \
+ return sent + rv; \
}
-#define SEND(bfr, len) \
- do { \
+#define SEND(bfr, len) \
+ do { \
rv = ssl_Send(fd, bfr, len, 0, timeout); \
- HANDLE_ERR(rv, len) \
- sent += len; \
+ HANDLE_ERR(rv, len) \
+ sent += len; \
} while (0)
/* Make sure the first write is at least 8 KB, if possible. */
@@ -2762,23 +3082,23 @@ ssl_WriteV(PRFileDesc *fd, const PRIOVec *iov, PRInt32 vectors,
GET_VECTOR;
toCopy = PR_MIN(left, myIov.iov_len);
PORT_Memcpy(buf + bufLen, myIov.iov_base, toCopy);
- bufLen += toCopy;
- left -= toCopy;
+ bufLen += toCopy;
+ left -= toCopy;
myIov.iov_base += toCopy;
- myIov.iov_len -= toCopy;
+ myIov.iov_len -= toCopy;
}
- SEND( buf, bufLen );
+ SEND(buf, bufLen);
}
while (vectors || myIov.iov_len) {
- PRInt32 addLen;
+ 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;
+ myIov.iov_len -= K16;
}
if (!myIov.iov_len)
continue;
@@ -2788,13 +3108,13 @@ ssl_WriteV(PRFileDesc *fd, const PRIOVec *iov, PRInt32 vectors,
} 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;
+ 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 );
+ SEND(myIov.iov_base, myIov.iov_len);
myIov.iov_len = 0;
continue;
}
@@ -2804,25 +3124,24 @@ ssl_WriteV(PRFileDesc *fd, const PRIOVec *iov, PRInt32 vectors,
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. */
- ) {
+ 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;
+ iov[1].iov_len % K16 + addLen <= left + limit) {
+ addLen = left;
} else
addLen = 0;
} while (addLen);
- SEND( buf, bufLen );
+ SEND(buf, bufLen);
}
return sent;
}
@@ -2859,14 +3178,16 @@ ssl_FSync(PRFileDesc *fd)
}
static PRInt32 PR_CALLBACK
-ssl_Seek(PRFileDesc *fd, PRInt32 offset, PRSeekWhence how) {
+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) {
+ssl_Seek64(PRFileDesc *fd, PRInt64 offset, PRSeekWhence how)
+{
PRInt64 res;
PORT_Assert(0);
@@ -2911,85 +3232,83 @@ ssl_SendTo(PRFileDesc *fd, const void *buf, PRInt32 amount, PRIntn flags,
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 */
+ 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;
+ PRIOMethods *new_methods = &combined_methods;
const PRIOMethods *nspr_methods = PR_GetDefaultIOMethods();
- const PRIOMethods *my_methods = &ssl_methods;
+ 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;
-
+ 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;
@@ -3006,8 +3325,8 @@ ssl_InitIOLayer(void)
static PRStatus
ssl_PushIOLayer(sslSocket *ns, PRFileDesc *stack, PRDescIdentity id)
{
- PRFileDesc *layer = NULL;
- PRStatus status;
+ PRFileDesc *layer = NULL;
+ PRStatus status;
if (!ssl_inited) {
status = PR_CallOnce(&initIoLayerOnce, &ssl_InitIOLayer);
@@ -3055,24 +3374,24 @@ ssl_MakeLocks(sslSocket *ss)
ss->firstHandshakeLock = PZ_NewMonitor(nssILockSSL);
if (!ss->firstHandshakeLock)
goto loser;
- ss->ssl3HandshakeLock = PZ_NewMonitor(nssILockSSL);
+ ss->ssl3HandshakeLock = PZ_NewMonitor(nssILockSSL);
if (!ss->ssl3HandshakeLock)
goto loser;
- ss->specLock = NSSRWLock_New(SSL_LOCK_RANK_SPEC, NULL);
+ ss->specLock = NSSRWLock_New(SSL_LOCK_RANK_SPEC, NULL);
if (!ss->specLock)
goto loser;
- ss->recvBufLock = PZ_NewMonitor(nssILockSSL);
+ ss->recvBufLock = PZ_NewMonitor(nssILockSSL);
if (!ss->recvBufLock)
goto loser;
- ss->xmitBufLock = PZ_NewMonitor(nssILockSSL);
+ ss->xmitBufLock = PZ_NewMonitor(nssILockSSL);
if (!ss->xmitBufLock)
goto loser;
- ss->writerThread = NULL;
+ ss->writerThread = NULL;
if (ssl_lock_readers) {
- ss->recvLock = PZ_NewLock(nssILockSSL);
+ ss->recvLock = PZ_NewLock(nssILockSSL);
if (!ss->recvLock)
goto loser;
- ss->sendLock = PZ_NewLock(nssILockSSL);
+ ss->sendLock = PZ_NewLock(nssILockSSL);
if (!ss->sendLock)
goto loser;
}
@@ -3086,19 +3405,19 @@ loser:
#define NSS_HAVE_GETENV 1
#endif
-#define LOWER(x) (x | 0x20) /* cheap ToLower function ignores LOCALE */
+#define LOWER(x) (x | 0x20) /* cheap ToLower function ignores LOCALE */
static void
ssl_SetDefaultsFromEnvironment(void)
{
-#if defined( NSS_HAVE_GETENV )
+#if defined(NSS_HAVE_GETENV)
static int firsttime = 1;
if (firsttime) {
- char * ev;
+ char *ev;
firsttime = 0;
#ifdef DEBUG
- ev = getenv("SSLDEBUGFILE");
+ ev = PR_GetEnvSecure("SSLDEBUGFILE");
if (ev && ev[0]) {
ssl_trace_iob = fopen(ev, "w");
}
@@ -3106,19 +3425,20 @@ ssl_SetDefaultsFromEnvironment(void)
ssl_trace_iob = stderr;
}
#ifdef TRACE
- ev = getenv("SSLTRACE");
+ ev = PR_GetEnvSecure("SSLTRACE");
if (ev && ev[0]) {
ssl_trace = atoi(ev);
SSL_TRACE(("SSL: tracing set to %d", ssl_trace));
}
#endif /* TRACE */
- ev = getenv("SSLDEBUG");
+ ev = PR_GetEnvSecure("SSLDEBUG");
if (ev && ev[0]) {
ssl_debug = atoi(ev);
SSL_TRACE(("SSL: debugging set to %d", ssl_debug));
}
#endif /* DEBUG */
- ev = getenv("SSLKEYLOGFILE");
+#ifdef NSS_ALLOW_SSLKEYLOGFILE
+ ev = PR_GetEnvSecure("SSLKEYLOGFILE");
if (ev && ev[0]) {
ssl_keylog_iob = fopen(ev, "a");
if (!ssl_keylog_iob) {
@@ -3131,22 +3451,15 @@ ssl_SetDefaultsFromEnvironment(void)
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");
+#endif
+ ev = PR_GetEnvSecure("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");
+ ev = PR_GetEnvSecure("NSS_SSL_ENABLE_RENEGOTIATION");
if (ev) {
if (ev[0] == '1' || LOWER(ev[0]) == 'u')
ssl_defaults.enableRenegotiation = SSL_RENEGOTIATE_UNRESTRICTED;
@@ -3159,13 +3472,13 @@ ssl_SetDefaultsFromEnvironment(void)
SSL_TRACE(("SSL: enableRenegotiation set to %d",
ssl_defaults.enableRenegotiation));
}
- ev = getenv("NSS_SSL_REQUIRE_SAFE_NEGOTIATION");
+ ev = PR_GetEnvSecure("NSS_SSL_REQUIRE_SAFE_NEGOTIATION");
if (ev && ev[0] == '1') {
ssl_defaults.requireSafeNegotiation = PR_TRUE;
SSL_TRACE(("SSL: requireSafeNegotiation set to %d",
- PR_TRUE));
+ PR_TRUE));
}
- ev = getenv("NSS_SSL_CBC_RANDOM_IV");
+ ev = PR_GetEnvSecure("NSS_SSL_CBC_RANDOM_IV");
if (ev && ev[0] == '0') {
ssl_defaults.cbcRandomIV = PR_FALSE;
SSL_TRACE(("SSL: cbcRandomIV set to 0"));
@@ -3174,13 +3487,172 @@ ssl_SetDefaultsFromEnvironment(void)
#endif /* NSS_HAVE_GETENV */
}
+const sslNamedGroupDef *
+ssl_LookupNamedGroup(SSLNamedGroup group)
+{
+ unsigned int i;
+
+ for (i = 0; i < SSL_NAMED_GROUP_COUNT; ++i) {
+ if (ssl_named_groups[i].name == group) {
+ return &ssl_named_groups[i];
+ }
+ }
+ return NULL;
+}
+
+PRBool
+ssl_NamedGroupEnabled(const sslSocket *ss, const sslNamedGroupDef *groupDef)
+{
+ unsigned int i;
+
+ if (!groupDef) {
+ return PR_FALSE;
+ }
+
+ for (i = 0; i < SSL_NAMED_GROUP_COUNT; ++i) {
+ if (ss->namedGroupPreferences[i] &&
+ ss->namedGroupPreferences[i] == groupDef) {
+ return PR_TRUE;
+ }
+ }
+ return PR_FALSE;
+}
+
+/* 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. Adopts the keys given.
+ */
+sslKeyPair *
+ssl_NewKeyPair(SECKEYPrivateKey *privKey, SECKEYPublicKey *pubKey)
+{
+ sslKeyPair *pair;
+
+ if (!privKey || !pubKey) {
+ PORT_SetError(PR_INVALID_ARGUMENT_ERROR);
+ return NULL;
+ }
+ pair = PORT_ZNew(sslKeyPair);
+ if (!pair)
+ return NULL; /* error code is set. */
+ pair->privKey = privKey;
+ pair->pubKey = pubKey;
+ pair->refCount = 1;
+ return pair; /* success */
+}
+
+sslKeyPair *
+ssl_GetKeyPairRef(sslKeyPair *keyPair)
+{
+ PR_ATOMIC_INCREMENT(&keyPair->refCount);
+ return keyPair;
+}
+
+void
+ssl_FreeKeyPair(sslKeyPair *keyPair)
+{
+ PRInt32 newCount = PR_ATOMIC_DECREMENT(&keyPair->refCount);
+ if (!newCount) {
+ SECKEY_DestroyPrivateKey(keyPair->privKey);
+ SECKEY_DestroyPublicKey(keyPair->pubKey);
+ PORT_Free(keyPair);
+ }
+}
+
+/* Ephemeral key handling. */
+sslEphemeralKeyPair *
+ssl_NewEphemeralKeyPair(const sslNamedGroupDef *group,
+ SECKEYPrivateKey *privKey, SECKEYPublicKey *pubKey)
+{
+ sslKeyPair *keys;
+ sslEphemeralKeyPair *pair;
+
+ if (!group) {
+ PORT_SetError(PR_INVALID_ARGUMENT_ERROR);
+ return NULL;
+ }
+
+ keys = ssl_NewKeyPair(privKey, pubKey);
+ if (!keys) {
+ return NULL;
+ }
+
+ pair = PORT_ZNew(sslEphemeralKeyPair);
+ if (!pair) {
+ ssl_FreeKeyPair(keys);
+ return NULL; /* error already set */
+ }
+
+ PR_INIT_CLIST(&pair->link);
+ pair->group = group;
+ pair->keys = keys;
+
+ return pair;
+}
+
+sslEphemeralKeyPair *
+ssl_CopyEphemeralKeyPair(sslEphemeralKeyPair *keyPair)
+{
+ sslEphemeralKeyPair *pair;
+
+ pair = PORT_ZNew(sslEphemeralKeyPair);
+ if (!pair) {
+ return NULL; /* error already set */
+ }
+
+ PR_INIT_CLIST(&pair->link);
+ pair->group = keyPair->group;
+ pair->keys = ssl_GetKeyPairRef(keyPair->keys);
+
+ return pair;
+}
+
+void
+ssl_FreeEphemeralKeyPair(sslEphemeralKeyPair *keyPair)
+{
+ ssl_FreeKeyPair(keyPair->keys);
+ PR_REMOVE_LINK(&keyPair->link);
+ PORT_Free(keyPair);
+}
+
+PRBool
+ssl_HaveEphemeralKeyPair(const sslSocket *ss, const sslNamedGroupDef *groupDef)
+{
+ return ssl_LookupEphemeralKeyPair((sslSocket *)ss, groupDef) != NULL;
+}
+
+sslEphemeralKeyPair *
+ssl_LookupEphemeralKeyPair(sslSocket *ss, const sslNamedGroupDef *groupDef)
+{
+ PRCList *cursor;
+ for (cursor = PR_NEXT_LINK(&ss->ephemeralKeyPairs);
+ cursor != &ss->ephemeralKeyPairs;
+ cursor = PR_NEXT_LINK(cursor)) {
+ sslEphemeralKeyPair *keyPair = (sslEphemeralKeyPair *)cursor;
+ if (keyPair->group == groupDef) {
+ return keyPair;
+ }
+ }
+ return NULL;
+}
+
+void
+ssl_FreeEphemeralKeyPairs(sslSocket *ss)
+{
+ while (!PR_CLIST_IS_EMPTY(&ss->ephemeralKeyPairs)) {
+ PRCList *cursor = PR_LIST_TAIL(&ss->ephemeralKeyPairs);
+ ssl_FreeEphemeralKeyPair((sslEphemeralKeyPair *)cursor);
+ }
+}
+
/*
** Create a newsocket structure for a file descriptor.
*/
static sslSocket *
ssl_NewSocket(PRBool makeLocks, SSLProtocolVariant protocolVariant)
{
+ SECStatus rv;
sslSocket *ss;
+ int i;
ssl_SetDefaultsFromEnvironment();
@@ -3188,76 +3660,83 @@ ssl_NewSocket(PRBool makeLocks, SSLProtocolVariant protocolVariant)
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->protocolVariant = 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->certStatusArray[i] = NULL;
- }
- ss->stepDownKeyPair = NULL;
-
- ss->dheParams = NULL;
- ss->dheKeyPair = NULL;
-
- ss->dbHandle = CERT_GetDefaultCertDB();
-
- /* 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;
- ss->ephemeralECDHKeyPair = 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)
+ ss = (sslSocket *)PORT_ZAlloc(sizeof(sslSocket));
+ if (!ss) {
+ return NULL;
+ }
+ ss->opt = ssl_defaults;
+ if (protocolVariant == ssl_variant_datagram) {
+ ss->opt.enableRenegotiation = SSL_RENEGOTIATE_NEVER;
+ }
+ ss->opt.useSocks = PR_FALSE;
+ ss->opt.noLocks = !makeLocks;
+ ss->vrange = *VERSIONS_DEFAULTS(protocolVariant);
+ ss->protocolVariant = protocolVariant;
+
+ ss->peerID = NULL;
+ ss->rTimeout = PR_INTERVAL_NO_TIMEOUT;
+ ss->wTimeout = PR_INTERVAL_NO_TIMEOUT;
+ ss->cTimeout = PR_INTERVAL_NO_TIMEOUT;
+ ss->url = NULL;
+
+ PR_INIT_CLIST(&ss->serverCerts);
+ PR_INIT_CLIST(&ss->ephemeralKeyPairs);
+
+ ss->dbHandle = CERT_GetDefaultCertDB();
+
+ /* 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);
+ ssl3_InitSocketPolicy(ss);
+ for (i = 0; i < SSL_NAMED_GROUP_COUNT; ++i) {
+ ss->namedGroupPreferences[i] = &ssl_named_groups[i];
+ }
+ ss->additionalShares = 0;
+ PR_INIT_CLIST(&ss->ssl3.hs.remoteExtensions);
+ PR_INIT_CLIST(&ss->ssl3.hs.lastMessageFlight);
+ PR_INIT_CLIST(&ss->ssl3.hs.cipherSpecs);
+ PR_INIT_CLIST(&ss->ssl3.hs.bufferedEarlyData);
+ if (makeLocks) {
+ rv = ssl_MakeLocks(ss);
+ if (rv != SECSuccess)
goto loser;
- status = ssl_InitGather(&ss->gs);
- if (status != SECSuccess) {
-loser:
- ssl_DestroySocketContents(ss);
- ssl_DestroyLocks(ss);
- PORT_Free(ss);
- ss = NULL;
- }
}
+ rv = ssl_CreateSecurityInfo(ss);
+ if (rv != SECSuccess)
+ goto loser;
+ rv = ssl3_InitGather(&ss->gs);
+ if (rv != SECSuccess)
+ goto loser;
+ ssl3_InitExtensionData(&ss->xtnData);
return ss;
+
+loser:
+ ssl_DestroySocketContents(ss);
+ ssl_DestroyLocks(ss);
+ PORT_Free(ss);
+ return NULL;
+}
+
+/**
+ * DEPRECATED: Will always return false.
+ */
+SECStatus
+SSL_CanBypass(CERTCertificate *cert, SECKEYPrivateKey *srvPrivkey,
+ PRUint32 protocolmask, PRUint16 *ciphersuites, int nsuites,
+ PRBool *pcanbypass, void *pwArg)
+{
+ if (!pcanbypass) {
+ PORT_SetError(SEC_ERROR_INVALID_ARGS);
+ return SECFailure;
+ }
+ *pcanbypass = PR_FALSE;
+ return SECSuccess;
}
diff --git a/nss/lib/ssl/sslt.h b/nss/lib/ssl/sslt.h
index cd742bb..506b78d 100644
--- a/nss/lib/ssl/sslt.h
+++ b/nss/lib/ssl/sslt.h
@@ -10,6 +10,8 @@
#define __sslt_h_
#include "prtypes.h"
+#include "secitem.h"
+#include "certt.h"
typedef struct SSL3StatisticsStr {
/* statistics from ssl3_SendClientHello (sch) */
@@ -36,12 +38,15 @@ typedef struct SSL3StatisticsStr {
/* 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 */
+ 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_ecdh_psk = 5,
+ ssl_kea_dh_psk = 6,
+ ssl_kea_tls13_any = 7,
+ ssl_kea_size /* number of ssl_kea_ algorithms */
} SSLKEAType;
/* The following defines are for backwards compatibility.
@@ -49,21 +54,20 @@ typedef enum {
** 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
-
+#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
/* Values of this enum match the SignatureAlgorithm enum from
* https://tools.ietf.org/html/rfc5246#section-7.4.1.4.1 */
typedef enum {
- ssl_sign_null = 0, /* "anonymous" in TLS */
- ssl_sign_rsa = 1,
- ssl_sign_dsa = 2,
- ssl_sign_ecdsa = 3
+ ssl_sign_null = 0, /* "anonymous" in TLS */
+ ssl_sign_rsa = 1,
+ ssl_sign_dsa = 2,
+ ssl_sign_ecdsa = 3
} SSLSignType;
/* Values of this enum match the HashAlgorithm enum from
@@ -80,86 +84,211 @@ typedef enum {
ssl_hash_sha512 = 6
} SSLHashType;
+/* Deprecated */
typedef struct SSLSignatureAndHashAlgStr {
SSLHashType hashAlg;
SSLSignType sigAlg;
} SSLSignatureAndHashAlg;
typedef enum {
- ssl_auth_null = 0,
- ssl_auth_rsa = 1,
- ssl_auth_dsa = 2,
- ssl_auth_kea = 3,
- ssl_auth_ecdsa = 4
+ ssl_sig_none = 0,
+ ssl_sig_rsa_pkcs1_sha1 = 0x0201,
+ ssl_sig_rsa_pkcs1_sha256 = 0x0401,
+ ssl_sig_rsa_pkcs1_sha384 = 0x0501,
+ ssl_sig_rsa_pkcs1_sha512 = 0x0601,
+ /* For ECDSA, the pairing of the hash with a specific curve is only enforced
+ * in TLS 1.3; in TLS 1.2 any curve can be used with each of these. */
+ ssl_sig_ecdsa_secp256r1_sha256 = 0x0403,
+ ssl_sig_ecdsa_secp384r1_sha384 = 0x0503,
+ ssl_sig_ecdsa_secp521r1_sha512 = 0x0603,
+ ssl_sig_rsa_pss_sha256 = 0x0804,
+ ssl_sig_rsa_pss_sha384 = 0x0805,
+ ssl_sig_rsa_pss_sha512 = 0x0806,
+ ssl_sig_ed25519 = 0x0807,
+ ssl_sig_ed448 = 0x0808,
+
+ ssl_sig_dsa_sha1 = 0x0202,
+ ssl_sig_dsa_sha256 = 0x0402,
+ ssl_sig_dsa_sha384 = 0x0502,
+ ssl_sig_dsa_sha512 = 0x0602,
+ ssl_sig_ecdsa_sha1 = 0x0203,
+
+ /* The following value (which can't be used in the protocol), represents
+ * the RSA signature using SHA-1 and MD5 that is used in TLS 1.0 and 1.1.
+ * This is reported as a signature scheme when TLS 1.0 or 1.1 is used.
+ * This should not be passed to SSL_SignatureSchemePrefSet(); this
+ * signature scheme is always used and cannot be disabled. */
+ ssl_sig_rsa_pkcs1_sha1md5 = 0x10101,
+} SSLSignatureScheme;
+
+/*
+** SSLAuthType describes the type of key that is used to authenticate a
+** connection. That is, the type of key in the end-entity certificate.
+*/
+typedef enum {
+ ssl_auth_null = 0,
+ ssl_auth_rsa_decrypt = 1, /* static RSA */
+ ssl_auth_dsa = 2,
+ ssl_auth_kea = 3, /* unused */
+ ssl_auth_ecdsa = 4,
+ ssl_auth_ecdh_rsa = 5, /* ECDH cert with an RSA signature */
+ ssl_auth_ecdh_ecdsa = 6, /* ECDH cert with an ECDSA signature */
+ ssl_auth_rsa_sign = 7, /* RSA PKCS#1.5 signing */
+ ssl_auth_rsa_pss = 8,
+ ssl_auth_psk = 9,
+ ssl_auth_tls13_any = 10,
+ ssl_auth_size /* number of authentication types */
} SSLAuthType;
+/* This is defined for backward compatibility reasons */
+#define ssl_auth_rsa ssl_auth_rsa_decrypt
+
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,
+ 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,
ssl_calg_camellia = 8,
- ssl_calg_seed = 9,
- ssl_calg_aes_gcm = 10
+ ssl_calg_seed = 9,
+ ssl_calg_aes_gcm = 10,
+ ssl_calg_chacha20 = 11
} 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 */
- ssl_hmac_sha256 = 5,
- ssl_mac_aead = 6
+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 */
+ ssl_hmac_sha256 = 5,
+ ssl_mac_aead = 6,
+ ssl_hmac_sha384 = 7
} SSLMACAlgorithm;
typedef enum {
ssl_compression_null = 0,
- ssl_compression_deflate = 1 /* RFC 3749 */
+ ssl_compression_deflate = 1 /* RFC 3749 */
} SSLCompressionMethod;
+typedef enum {
+ ssl_grp_ec_sect163k1 = 1,
+ ssl_grp_ec_sect163r1 = 2,
+ ssl_grp_ec_sect163r2 = 3,
+ ssl_grp_ec_sect193r1 = 4,
+ ssl_grp_ec_sect193r2 = 5,
+ ssl_grp_ec_sect233k1 = 6,
+ ssl_grp_ec_sect233r1 = 7,
+ ssl_grp_ec_sect239k1 = 8,
+ ssl_grp_ec_sect283k1 = 9,
+ ssl_grp_ec_sect283r1 = 10,
+ ssl_grp_ec_sect409k1 = 11,
+ ssl_grp_ec_sect409r1 = 12,
+ ssl_grp_ec_sect571k1 = 13,
+ ssl_grp_ec_sect571r1 = 14,
+ ssl_grp_ec_secp160k1 = 15,
+ ssl_grp_ec_secp160r1 = 16,
+ ssl_grp_ec_secp160r2 = 17,
+ ssl_grp_ec_secp192k1 = 18,
+ ssl_grp_ec_secp192r1 = 19,
+ ssl_grp_ec_secp224k1 = 20,
+ ssl_grp_ec_secp224r1 = 21,
+ ssl_grp_ec_secp256k1 = 22,
+ ssl_grp_ec_secp256r1 = 23,
+ ssl_grp_ec_secp384r1 = 24,
+ ssl_grp_ec_secp521r1 = 25,
+ ssl_grp_ec_curve25519 = 29, /* RFC4492 */
+ ssl_grp_ffdhe_2048 = 256, /* RFC7919 */
+ ssl_grp_ffdhe_3072 = 257,
+ ssl_grp_ffdhe_4096 = 258,
+ ssl_grp_ffdhe_6144 = 259,
+ ssl_grp_ffdhe_8192 = 260,
+ ssl_grp_none = 65537, /* special value */
+ ssl_grp_ffdhe_custom = 65538 /* special value */
+} SSLNamedGroup;
+
+typedef struct SSLExtraServerCertDataStr {
+ /* When this struct is passed to SSL_ConfigServerCert, and authType is set
+ * to a value other than ssl_auth_null, this limits the use of the key to
+ * the type defined; otherwise, the certificate is configured for all
+ * compatible types. */
+ SSLAuthType authType;
+ /* The remainder of the certificate chain. */
+ const CERTCertificateList* certChain;
+ /* A set of one or more stapled OCSP responses for the certificate. This is
+ * used to generate the OCSP stapling answer provided by the server. */
+ const SECItemArray* stapledOCSPResponses;
+ /* A serialized sign_certificate_timestamp extension, used to answer
+ * requests from clients for this data. */
+ const SECItem* signedCertTimestamps;
+} SSLExtraServerCertData;
+
typedef struct SSLChannelInfoStr {
- PRUint32 length;
- PRUint16 protocolVersion;
- PRUint16 cipherSuite;
+ /* On return, SSL_GetChannelInfo sets |length| to the smaller of
+ * the |len| argument and the length of the struct used by NSS.
+ * Callers must ensure the application uses a version of NSS that
+ * isn't older than the version used at compile time. */
+ PRUint32 length;
+ PRUint16 protocolVersion;
+ PRUint16 cipherSuite;
/* server authentication info */
- PRUint32 authKeyBits;
+ PRUint32 authKeyBits;
/* key exchange algorithm info */
- PRUint32 keaKeyBits;
+ 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];
+ 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;
+ const char* compressionMethodName;
SSLCompressionMethod compressionMethod;
/* The following fields are added in NSS 3.21.
* This field only has meaning in TLS < 1.3 and will be set to
* PR_FALSE in TLS 1.3.
*/
- PRBool extendedMasterSecretUsed;
+ PRBool extendedMasterSecretUsed;
+
+ /* The following fields were added in NSS 3.25.
+ * This field only has meaning in TLS >= 1.3, and indicates on the
+ * client side that the server accepted early (0-RTT) data.
+ */
+ PRBool earlyDataAccepted;
+
+ /* The following fields were added in NSS 3.28. */
+ /* These fields have the same meaning as in SSLCipherSuiteInfo. */
+ SSLKEAType keaType;
+ SSLNamedGroup keaGroup;
+ SSLCipherAlgorithm symCipher;
+ SSLMACAlgorithm macAlgorithm;
+ SSLAuthType authType;
+ SSLSignatureScheme signatureScheme;
+
+ /* When adding new fields to this structure, please document the
+ * NSS version in which they were added. */
} SSLChannelInfo;
/* Preliminary channel info */
#define ssl_preinfo_version (1U << 0)
#define ssl_preinfo_cipher_suite (1U << 1)
-#define ssl_preinfo_all (ssl_preinfo_version|ssl_preinfo_cipher_suite)
+#define ssl_preinfo_all (ssl_preinfo_version | ssl_preinfo_cipher_suite)
typedef struct SSLPreliminaryChannelInfoStr {
- /* This is set to the length of the struct. */
+ /* On return, SSL_GetPreliminaryChannelInfo sets |length| to the smaller of
+ * the |len| argument and the length of the struct used by NSS.
+ * Callers must ensure the application uses a version of NSS that
+ * isn't older than the version used at compile time. */
PRUint32 length;
/* A bitfield over SSLPreliminaryValueSet that describes which
* preliminary values are set (see ssl_preinfo_*). */
@@ -168,43 +297,57 @@ typedef struct SSLPreliminaryChannelInfoStr {
PRUint16 protocolVersion;
/* Cipher suite: test (valuesSet & ssl_preinfo_cipher_suite) */
PRUint16 cipherSuite;
+
+ /* When adding new fields to this structure, please document the
+ * NSS version in which they were added. */
} SSLPreliminaryChannelInfo;
typedef struct SSLCipherSuiteInfoStr {
- PRUint16 length;
- PRUint16 cipherSuite;
+ /* On return, SSL_GetCipherSuitelInfo sets |length| to the smaller of
+ * the |len| argument and the length of the struct used by NSS.
+ * Callers must ensure the application uses a version of NSS that
+ * isn't older than the version used at compile time. */
+ PRUint16 length;
+ PRUint16 cipherSuite;
/* Cipher Suite Name */
- const char * cipherSuiteName;
+ const char* cipherSuiteName;
/* server authentication info */
- const char * authAlgorithmName;
- SSLAuthType authAlgorithm;
+ const char* authAlgorithmName;
+ SSLAuthType authAlgorithm; /* deprecated, use |authType| */
/* key exchange algorithm info */
- const char * keaTypeName;
- SSLKEAType keaType;
+ const char* keaTypeName;
+ SSLKEAType keaType;
/* symmetric encryption info */
- const char * symCipherName;
- SSLCipherAlgorithm symCipher;
- PRUint16 symKeyBits;
- PRUint16 symKeySpace;
- PRUint16 effectiveKeyBits;
+ const char* symCipherName;
+ SSLCipherAlgorithm symCipher;
+ PRUint16 symKeyBits;
+ PRUint16 symKeySpace;
+ PRUint16 effectiveKeyBits;
/* MAC info */
/* AEAD ciphers don't have a MAC. For an AEAD cipher, macAlgorithmName
* is "AEAD", macAlgorithm is ssl_mac_aead, and macBits is the length in
* bits of the authentication tag. */
- const char * macAlgorithmName;
- SSLMACAlgorithm macAlgorithm;
- PRUint16 macBits;
-
- PRUintn isFIPS : 1;
- PRUintn isExportable : 1;
- PRUintn nonStandard : 1;
- PRUintn reservedBits :29;
-
+ const char* macAlgorithmName;
+ SSLMACAlgorithm macAlgorithm;
+ PRUint16 macBits;
+
+ PRUintn isFIPS : 1;
+ PRUintn isExportable : 1; /* deprecated, don't use */
+ PRUintn nonStandard : 1;
+ PRUintn reservedBits : 29;
+
+ /* The following fields were added in NSS 3.24. */
+ /* This reports the correct authentication type for the cipher suite, use
+ * this instead of |authAlgorithm|. */
+ SSLAuthType authType;
+
+ /* When adding new fields to this structure, please document the
+ * NSS version in which they were added. */
} SSLCipherSuiteInfo;
typedef enum {
@@ -218,32 +361,47 @@ typedef struct SSLVersionRangeStr {
} SSLVersionRange;
typedef enum {
- SSL_sni_host_name = 0,
+ 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,
-#ifndef NSS_DISABLE_ECC
- ssl_elliptic_curves_xtn = 10,
- ssl_ec_point_formats_xtn = 11,
-#endif
- ssl_signature_algorithms_xtn = 13,
- ssl_use_srtp_xtn = 14,
- ssl_app_layer_protocol_xtn = 16,
- ssl_padding_xtn = 21,
- ssl_extended_master_secret_xtn = 23,
- ssl_session_ticket_xtn = 35,
- ssl_next_proto_nego_xtn = 13172,
- ssl_renegotiation_info_xtn = 0xff01,
- ssl_tls13_draft_version_xtn = 0xff02 /* experimental number */
+ ssl_server_name_xtn = 0,
+ ssl_cert_status_xtn = 5,
+ ssl_supported_groups_xtn = 10,
+ ssl_ec_point_formats_xtn = 11,
+ ssl_signature_algorithms_xtn = 13,
+ ssl_use_srtp_xtn = 14,
+ ssl_app_layer_protocol_xtn = 16,
+ /* signed_certificate_timestamp extension, RFC 6962 */
+ ssl_signed_cert_timestamp_xtn = 18,
+ ssl_padding_xtn = 21,
+ ssl_extended_master_secret_xtn = 23,
+ ssl_session_ticket_xtn = 35,
+ ssl_tls13_key_share_xtn = 40,
+ ssl_tls13_pre_shared_key_xtn = 41,
+ ssl_tls13_early_data_xtn = 42,
+ ssl_tls13_supported_versions_xtn = 43,
+ ssl_tls13_cookie_xtn = 44,
+ ssl_tls13_psk_key_exchange_modes_xtn = 45,
+ ssl_tls13_ticket_early_data_info_xtn = 46,
+ ssl_next_proto_nego_xtn = 13172,
+ ssl_renegotiation_info_xtn = 0xff01,
+ ssl_tls13_short_header_xtn = 0xff03
} SSLExtensionType;
-#define SSL_MAX_EXTENSIONS 12 /* doesn't include ssl_padding_xtn. */
+/* This is the old name for the supported_groups extensions. */
+#define ssl_elliptic_curves_xtn ssl_supported_groups_xtn
+
+/* SSL_MAX_EXTENSIONS doesn't include ssl_padding_xtn. It includes the maximum
+ * number of extensions that are supported for any single message type. That
+ * is, a ClientHello; ServerHello and TLS 1.3 NewSessionTicket and
+ * HelloRetryRequest extensions are smaller. */
+#define SSL_MAX_EXTENSIONS 19
+/* Deprecated */
typedef enum {
ssl_dhe_group_none = 0,
ssl_ff_dhe_2048_group = 1,
diff --git a/nss/lib/ssl/ssltrace.c b/nss/lib/ssl/ssltrace.c
index ee540d5..b1fdde7 100644
--- a/nss/lib/ssl/ssltrace.c
+++ b/nss/lib/ssl/ssltrace.c
@@ -6,6 +6,7 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include <stdarg.h>
#include "cert.h"
+#include "pk11func.h"
#include "ssl.h"
#include "sslimpl.h"
#include "sslproto.h"
@@ -15,25 +16,26 @@
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 */
+ "................" /* 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)
+void
+ssl_PrintBuf(const sslSocket *ss, const char *msg, const void *vp, int len)
{
const unsigned char *cp = (const unsigned char *)vp;
char buf[80];
@@ -41,203 +43,72 @@ void ssl_PrintBuf(sslSocket *ss, const char *msg, const void *vp, int len)
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));
+ SSL_TRACE(("%d: SSL[%d]: %s [Len: %d]", SSL_GETPID(), ss->fd,
+ msg, len));
} else {
- SSL_TRACE(("%d: SSL: dump-msg: %s", SSL_GETPID(), msg));
+ SSL_TRACE(("%d: SSL: %s [Len: %d]", SSL_GETPID(), msg, len));
}
-}
-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));
+ if (!cp) {
+ SSL_TRACE((" <NULL>"));
+ return;
}
-}
-/* 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));
- }
+ 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++ = ' ';
- 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;
- }
+ 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) {
- *bp = 0;
- if (ss) {
- SSL_TRACE(("%d: SSL[%d]: %s",
- SSL_GETPID(), ss->fd, buf));
- } else {
- SSL_TRACE(("%d: SSL: %s", SSL_GETPID(), buf));
- }
+ *ap = 0;
+ SSL_TRACE((" %s", buf));
}
}
-void ssl_DumpMsg(sslSocket *ss, unsigned char *bp, unsigned len)
+void
+ssl_Trace(const char *format, ...)
{
- 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);
+ char buf[2000];
+ va_list args;
- PrintType(ss, "Server-Hello");
+ if (ssl_trace_iob) {
+ va_start(args, format);
+ PR_vsnprintf(buf, sizeof(buf), format, args);
+ va_end(args);
- 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;
+ fputs(buf, ssl_trace_iob);
+ fputs("\n", ssl_trace_iob);
}
}
void
-ssl_Trace(const char *format, ... )
+ssl_PrintKey(const sslSocket *ss, const char *msg, PK11SymKey *key)
{
- char buf[2000];
- va_list args;
+ SECStatus rv;
+ SECItem *rawkey;
- 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);
+ rv = PK11_ExtractKeyValue(key);
+ if (rv != SECSuccess) {
+ ssl_Trace("Could not extract key for %s", msg);
+ return;
+ }
+ rawkey = PK11_GetKeyData(key);
+ if (!rawkey) {
+ ssl_Trace("Could not extract key for %s", msg);
+ return;
}
+ ssl_PrintBuf(ss, msg, rawkey->data, rawkey->len);
}
#endif
diff --git a/nss/lib/ssl/tls13con.c b/nss/lib/ssl/tls13con.c
new file mode 100644
index 0000000..68a2a2c
--- /dev/null
+++ b/nss/lib/ssl/tls13con.c
@@ -0,0 +1,4509 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * TLS 1.3 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/. */
+
+#include "stdarg.h"
+#include "cert.h"
+#include "ssl.h"
+#include "keyhi.h"
+#include "pk11func.h"
+#include "prerr.h"
+#include "secitem.h"
+#include "secmod.h"
+#include "sslimpl.h"
+#include "sslproto.h"
+#include "sslerr.h"
+#include "tls13hkdf.h"
+#include "tls13con.h"
+#include "tls13exthandle.h"
+
+typedef enum {
+ TrafficKeyEarlyApplicationData,
+ TrafficKeyHandshake,
+ TrafficKeyApplicationData
+} TrafficKeyType;
+
+typedef enum {
+ CipherSpecRead,
+ CipherSpecWrite,
+} CipherSpecDirection;
+
+static SECStatus tls13_SetCipherSpec(sslSocket *ss, TrafficKeyType type,
+ CipherSpecDirection install,
+ PRBool deleteSecret);
+static SECStatus tls13_AESGCM(
+ ssl3KeyMaterial *keys,
+ PRBool doDecrypt,
+ unsigned char *out, int *outlen, int maxout,
+ const unsigned char *in, int inlen,
+ const unsigned char *additionalData, int additionalDataLen);
+static SECStatus tls13_ChaCha20Poly1305(
+ ssl3KeyMaterial *keys,
+ PRBool doDecrypt,
+ unsigned char *out, int *outlen, int maxout,
+ const unsigned char *in, int inlen,
+ const unsigned char *additionalData, int additionalDataLen);
+static SECStatus tls13_SendServerHelloSequence(sslSocket *ss);
+static SECStatus tls13_SendEncryptedExtensions(sslSocket *ss);
+static void tls13_SetKeyExchangeType(sslSocket *ss, const sslNamedGroupDef *group);
+static SECStatus tls13_HandleClientKeyShare(sslSocket *ss,
+ TLS13KeyShareEntry *peerShare);
+static SECStatus tls13_SendHelloRetryRequest(sslSocket *ss,
+ const sslNamedGroupDef *selectedGroup);
+
+static SECStatus tls13_HandleServerKeyShare(sslSocket *ss);
+static SECStatus tls13_HandleEncryptedExtensions(sslSocket *ss, SSL3Opaque *b,
+ PRUint32 length);
+static SECStatus tls13_SendCertificate(sslSocket *ss);
+static SECStatus tls13_HandleCertificate(
+ sslSocket *ss, SSL3Opaque *b, PRUint32 length);
+static SECStatus tls13_HandleCertificateRequest(sslSocket *ss, SSL3Opaque *b,
+ PRUint32 length);
+static SECStatus
+tls13_SendCertificateVerify(sslSocket *ss, SECKEYPrivateKey *privKey);
+static SECStatus tls13_HandleCertificateVerify(
+ sslSocket *ss, SSL3Opaque *b, PRUint32 length,
+ SSL3Hashes *hashes);
+static SECStatus tls13_RecoverWrappedSharedSecret(sslSocket *ss,
+ sslSessionID *sid);
+static SECStatus
+tls13_DeriveSecret(sslSocket *ss, PK11SymKey *key,
+ const char *prefix,
+ const char *suffix,
+ const SSL3Hashes *hashes,
+ PK11SymKey **dest);
+static void tls13_SetNullCipherSpec(sslSocket *ss, ssl3CipherSpec **specp);
+static SECStatus tls13_SendEndOfEarlyData(sslSocket *ss);
+static SECStatus tls13_SendFinished(sslSocket *ss, PK11SymKey *baseKey);
+static SECStatus tls13_ComputePskBinderHash(sslSocket *ss,
+ unsigned long prefixLength,
+ SSL3Hashes *hashes);
+static SECStatus tls13_VerifyFinished(sslSocket *ss, SSL3HandshakeType message,
+ PK11SymKey *secret,
+ SSL3Opaque *b, PRUint32 length,
+ const SSL3Hashes *hashes);
+static SECStatus tls13_ClientHandleFinished(sslSocket *ss,
+ SSL3Opaque *b, PRUint32 length,
+ const SSL3Hashes *hashes);
+static SECStatus tls13_ServerHandleFinished(sslSocket *ss,
+ SSL3Opaque *b, PRUint32 length,
+ const SSL3Hashes *hashes);
+static SECStatus tls13_HandleNewSessionTicket(sslSocket *ss, SSL3Opaque *b,
+ PRUint32 length);
+static SECStatus tls13_ComputeHandshakeHashes(sslSocket *ss,
+ SSL3Hashes *hashes);
+static SECStatus tls13_ComputeEarlySecrets(sslSocket *ss);
+static SECStatus tls13_ComputeHandshakeSecrets(sslSocket *ss);
+static SECStatus tls13_ComputeApplicationSecrets(sslSocket *ss);
+static SECStatus tls13_ComputeFinalSecrets(sslSocket *ss);
+static SECStatus tls13_ComputeFinished(
+ sslSocket *ss, PK11SymKey *baseKey, const SSL3Hashes *hashes,
+ PRBool sending, PRUint8 *output, unsigned int *outputLen,
+ unsigned int maxOutputLen);
+static SECStatus tls13_SendClientSecondRound(sslSocket *ss);
+static SECStatus tls13_FinishHandshake(sslSocket *ss);
+
+const char kHkdfLabelClient[] = "client";
+const char kHkdfLabelServer[] = "server";
+const char kHkdfLabelPskBinderKey[] = "resumption psk binder key";
+const char kHkdfLabelEarlyTrafficSecret[] = "early traffic secret";
+const char kHkdfLabelEarlyExporterSecret[] = "early exporter master secret";
+const char kHkdfLabelHandshakeTrafficSecret[] = "handshake traffic secret";
+const char kHkdfLabelApplicationTrafficSecret[] = "application traffic secret";
+const char kHkdfLabelFinishedSecret[] = "finished";
+const char kHkdfLabelResumptionMasterSecret[] = "resumption master secret";
+const char kHkdfLabelExporterMasterSecret[] = "exporter master secret";
+const char kHkdfPurposeKey[] = "key";
+const char kHkdfPurposeIv[] = "iv";
+
+#define TRAFFIC_SECRET(ss, dir, name) ((ss->sec.isServer ^ \
+ (dir == CipherSpecWrite)) \
+ ? ss->ssl3.hs.client##name \
+ : ss->ssl3.hs.server##name)
+
+const SSL3ProtocolVersion kTlsRecordVersion = SSL_LIBRARY_VERSION_TLS_1_0;
+const SSL3ProtocolVersion kDtlsRecordVersion = SSL_LIBRARY_VERSION_TLS_1_1;
+
+/* Belt and suspenders in case we ever add a TLS 1.4. */
+PR_STATIC_ASSERT(SSL_LIBRARY_VERSION_MAX_SUPPORTED <=
+ SSL_LIBRARY_VERSION_TLS_1_3);
+
+/* Use this instead of FATAL_ERROR when an alert isn't possible. */
+#define LOG_ERROR(ss, prError) \
+ do { \
+ SSL_TRC(3, ("%d: TLS13[%d]: fatal error %d in %s (%s:%d)", \
+ SSL_GETPID(), ss->fd, prError, __func__, __FILE__, __LINE__)); \
+ PORT_SetError(prError); \
+ } while (0)
+
+/* Log an error and generate an alert because something is irreparably wrong. */
+#define FATAL_ERROR(ss, prError, desc) \
+ do { \
+ LOG_ERROR(ss, prError); \
+ tls13_FatalError(ss, prError, desc); \
+ } while (0)
+
+void
+tls13_FatalError(sslSocket *ss, PRErrorCode prError, SSL3AlertDescription desc)
+{
+ PORT_Assert(desc != internal_error); /* These should never happen */
+ (void)SSL3_SendAlert(ss, alert_fatal, desc);
+ PORT_SetError(prError);
+}
+
+#ifdef TRACE
+#define STATE_CASE(a) \
+ case a: \
+ return #a
+static char *
+tls13_HandshakeState(SSL3WaitState st)
+{
+ switch (st) {
+ STATE_CASE(wait_client_hello);
+ STATE_CASE(wait_client_cert);
+ STATE_CASE(wait_cert_verify);
+ STATE_CASE(wait_finished);
+ STATE_CASE(wait_server_hello);
+ STATE_CASE(wait_server_cert);
+ STATE_CASE(wait_cert_request);
+ STATE_CASE(wait_encrypted_extensions);
+ STATE_CASE(idle_handshake);
+ default:
+ break;
+ }
+ PORT_Assert(0);
+ return "unknown";
+}
+#endif
+
+#define TLS13_WAIT_STATE_MASK 0x80
+
+#define TLS13_BASE_WAIT_STATE(ws) (ws & ~TLS13_WAIT_STATE_MASK)
+/* We don't mask idle_handshake because other parts of the code use it*/
+#define TLS13_WAIT_STATE(ws) (((ws == idle_handshake) || (ws == wait_server_hello)) ? ws : ws | TLS13_WAIT_STATE_MASK)
+#define TLS13_CHECK_HS_STATE(ss, err, ...) \
+ tls13_CheckHsState(ss, err, #err, __func__, __FILE__, __LINE__, \
+ __VA_ARGS__, \
+ wait_invalid)
+void
+tls13_SetHsState(sslSocket *ss, SSL3WaitState ws,
+ const char *func, const char *file, int line)
+{
+#ifdef TRACE
+ const char *new_state_name =
+ tls13_HandshakeState(ws);
+
+ SSL_TRC(3, ("%d: TLS13[%d]: %s state change from %s->%s in %s (%s:%d)",
+ SSL_GETPID(), ss->fd, SSL_ROLE(ss),
+ tls13_HandshakeState(TLS13_BASE_WAIT_STATE(ss->ssl3.hs.ws)),
+ new_state_name,
+ func, file, line));
+#endif
+
+ ss->ssl3.hs.ws = TLS13_WAIT_STATE(ws);
+}
+
+static PRBool
+tls13_InHsStateV(sslSocket *ss, va_list ap)
+{
+ SSL3WaitState ws;
+
+ while ((ws = va_arg(ap, SSL3WaitState)) != wait_invalid) {
+ if (TLS13_WAIT_STATE(ws) == ss->ssl3.hs.ws) {
+ return PR_TRUE;
+ }
+ }
+ return PR_FALSE;
+}
+
+PRBool
+tls13_InHsState(sslSocket *ss, ...)
+{
+ PRBool found;
+ va_list ap;
+
+ va_start(ap, ss);
+ found = tls13_InHsStateV(ss, ap);
+ va_end(ap);
+
+ return found;
+}
+
+static SECStatus
+tls13_CheckHsState(sslSocket *ss, int err, const char *error_name,
+ const char *func, const char *file, int line,
+ ...)
+{
+ va_list ap;
+ va_start(ap, line);
+ if (tls13_InHsStateV(ss, ap)) {
+ va_end(ap);
+ return SECSuccess;
+ }
+ va_end(ap);
+
+ SSL_TRC(3, ("%d: TLS13[%d]: error %s state is (%s) at %s (%s:%d)",
+ SSL_GETPID(), ss->fd,
+ error_name,
+ tls13_HandshakeState(TLS13_BASE_WAIT_STATE(ss->ssl3.hs.ws)),
+ func, file, line));
+ tls13_FatalError(ss, err, unexpected_message);
+ return SECFailure;
+}
+
+SSLHashType
+tls13_GetHashForCipherSuite(ssl3CipherSuite suite)
+{
+ const ssl3CipherSuiteDef *cipherDef =
+ ssl_LookupCipherSuiteDef(suite);
+ PORT_Assert(cipherDef);
+ if (!cipherDef) {
+ return ssl_hash_none;
+ }
+ return cipherDef->prf_hash;
+}
+
+SSLHashType
+tls13_GetHash(const sslSocket *ss)
+{
+ /* All TLS 1.3 cipher suites must have an explict PRF hash. */
+ PORT_Assert(ss->ssl3.hs.suite_def->prf_hash != ssl_hash_none);
+ return ss->ssl3.hs.suite_def->prf_hash;
+}
+
+unsigned int
+tls13_GetHashSizeForHash(SSLHashType hash)
+{
+ switch (hash) {
+ case ssl_hash_sha256:
+ return 32;
+ case ssl_hash_sha384:
+ return 48;
+ default:
+ PORT_Assert(0);
+ }
+ return 32;
+}
+
+unsigned int
+tls13_GetHashSize(const sslSocket *ss)
+{
+ return tls13_GetHashSizeForHash(tls13_GetHash(ss));
+}
+
+static CK_MECHANISM_TYPE
+tls13_GetHkdfMechanismForHash(SSLHashType hash)
+{
+ switch (hash) {
+ case ssl_hash_sha256:
+ return CKM_NSS_HKDF_SHA256;
+ case ssl_hash_sha384:
+ return CKM_NSS_HKDF_SHA384;
+ default:
+ PORT_Assert(0);
+ }
+ return CKM_NSS_HKDF_SHA256;
+}
+
+CK_MECHANISM_TYPE
+tls13_GetHkdfMechanism(sslSocket *ss)
+{
+ return tls13_GetHkdfMechanismForHash(tls13_GetHash(ss));
+}
+
+static CK_MECHANISM_TYPE
+tls13_GetHmacMechanism(sslSocket *ss)
+{
+ switch (tls13_GetHash(ss)) {
+ case ssl_hash_sha256:
+ return CKM_SHA256_HMAC;
+ case ssl_hash_sha384:
+ return CKM_SHA384_HMAC;
+ default:
+ PORT_Assert(0);
+ }
+ return CKM_SHA256_HMAC;
+}
+
+SECStatus
+tls13_CreateKeyShare(sslSocket *ss, const sslNamedGroupDef *groupDef)
+{
+ SECStatus rv;
+ sslEphemeralKeyPair *keyPair = NULL;
+ const ssl3DHParams *params;
+
+ PORT_Assert(groupDef);
+ switch (groupDef->keaType) {
+ case ssl_kea_ecdh:
+ rv = ssl_CreateECDHEphemeralKeyPair(ss, groupDef, &keyPair);
+ if (rv != SECSuccess) {
+ return SECFailure;
+ }
+ break;
+ case ssl_kea_dh:
+ params = ssl_GetDHEParams(groupDef);
+ PORT_Assert(params->name != ssl_grp_ffdhe_custom);
+ rv = ssl_CreateDHEKeyPair(groupDef, params, &keyPair);
+ if (rv != SECSuccess) {
+ return SECFailure;
+ }
+ break;
+ default:
+ PORT_Assert(0);
+ PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
+ return SECFailure;
+ }
+
+ PR_APPEND_LINK(&keyPair->link, &ss->ephemeralKeyPairs);
+ return rv;
+}
+
+SECStatus
+SSL_SendAdditionalKeyShares(PRFileDesc *fd, unsigned int count)
+{
+ sslSocket *ss = ssl_FindSocket(fd);
+ if (!ss) {
+ PORT_SetError(SEC_ERROR_INVALID_ARGS);
+ return SECFailure;
+ }
+
+ ss->additionalShares = count;
+ return SECSuccess;
+}
+
+/*
+ * Generate shares for ECDHE and FFDHE. This picks the first enabled group of
+ * the requisite type and creates a share for that.
+ *
+ * Called from ssl3_SendClientHello.
+ */
+SECStatus
+tls13_SetupClientHello(sslSocket *ss)
+{
+ unsigned int i;
+ SSL3Statistics *ssl3stats = SSL_GetStatistics();
+ NewSessionTicket *session_ticket = NULL;
+ sslSessionID *sid = ss->sec.ci.sid;
+ unsigned int numShares = 0;
+
+ PORT_Assert(ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss));
+ PORT_Assert(ss->opt.noLocks || ssl_HaveXmitBufLock(ss));
+ PORT_Assert(PR_CLIST_IS_EMPTY(&ss->ephemeralKeyPairs));
+
+ /* Select the first enabled group.
+ * TODO(ekr@rtfm.com): be smarter about offering the group
+ * that the other side negotiated if we are resuming. */
+ for (i = 0; i < SSL_NAMED_GROUP_COUNT; ++i) {
+ SECStatus rv;
+ if (!ss->namedGroupPreferences[i]) {
+ continue;
+ }
+ rv = tls13_CreateKeyShare(ss, ss->namedGroupPreferences[i]);
+ if (rv != SECSuccess) {
+ return SECFailure;
+ }
+ if (++numShares > ss->additionalShares) {
+ break;
+ }
+ }
+
+ if (PR_CLIST_IS_EMPTY(&ss->ephemeralKeyPairs)) {
+ PORT_SetError(SSL_ERROR_NO_CIPHERS_SUPPORTED);
+ return SECFailure;
+ }
+
+ /* Below here checks if we can do stateless resumption. */
+ if (sid->cached == never_cached ||
+ sid->version < SSL_LIBRARY_VERSION_TLS_1_3) {
+ return SECSuccess;
+ }
+
+ /* The caller must be holding sid->u.ssl3.lock for reading. */
+ session_ticket = &sid->u.ssl3.locked.sessionTicket;
+ PORT_Assert(session_ticket && session_ticket->ticket.data);
+
+ if (session_ticket->ticket_lifetime_hint == 0 ||
+ (session_ticket->ticket_lifetime_hint +
+ session_ticket->received_timestamp >
+ ssl_Time())) {
+ ss->statelessResume = PR_TRUE;
+ }
+
+ if (ss->statelessResume) {
+ SECStatus rv;
+
+ PORT_Assert(ss->sec.ci.sid);
+ rv = tls13_RecoverWrappedSharedSecret(ss, ss->sec.ci.sid);
+ if (rv != SECSuccess) {
+ FATAL_ERROR(ss, SEC_ERROR_LIBRARY_FAILURE, internal_error);
+ SSL_AtomicIncrementLong(&ssl3stats->sch_sid_cache_not_ok);
+ ss->sec.uncache(ss->sec.ci.sid);
+ ssl_FreeSID(ss->sec.ci.sid);
+ ss->sec.ci.sid = NULL;
+ return SECFailure;
+ }
+
+ rv = ssl3_SetCipherSuite(ss, ss->sec.ci.sid->u.ssl3.cipherSuite, PR_FALSE);
+ if (rv != SECSuccess) {
+ FATAL_ERROR(ss, PORT_GetError(), internal_error);
+ return SECFailure;
+ }
+
+ rv = tls13_ComputeEarlySecrets(ss);
+ if (rv != SECSuccess) {
+ FATAL_ERROR(ss, SEC_ERROR_LIBRARY_FAILURE, internal_error);
+ return SECFailure;
+ }
+ }
+
+ return SECSuccess;
+}
+
+static SECStatus
+tls13_ImportDHEKeyShare(sslSocket *ss, SECKEYPublicKey *peerKey,
+ SSL3Opaque *b, PRUint32 length,
+ SECKEYPublicKey *pubKey)
+{
+ SECStatus rv;
+ SECItem publicValue = { siBuffer, NULL, 0 };
+
+ publicValue.data = b;
+ publicValue.len = length;
+ if (!ssl_IsValidDHEShare(&pubKey->u.dh.prime, &publicValue)) {
+ PORT_SetError(SSL_ERROR_RX_MALFORMED_DHE_KEY_SHARE);
+ return SECFailure;
+ }
+
+ peerKey->keyType = dhKey;
+ rv = SECITEM_CopyItem(peerKey->arena, &peerKey->u.dh.prime,
+ &pubKey->u.dh.prime);
+ if (rv != SECSuccess)
+ return SECFailure;
+ rv = SECITEM_CopyItem(peerKey->arena, &peerKey->u.dh.base,
+ &pubKey->u.dh.base);
+ if (rv != SECSuccess)
+ return SECFailure;
+ rv = SECITEM_CopyItem(peerKey->arena, &peerKey->u.dh.publicValue,
+ &publicValue);
+ if (rv != SECSuccess)
+ return SECFailure;
+
+ return SECSuccess;
+}
+
+static SECStatus
+tls13_HandleKeyShare(sslSocket *ss,
+ TLS13KeyShareEntry *entry,
+ sslKeyPair *keyPair)
+{
+ PORTCheapArenaPool arena;
+ SECKEYPublicKey *peerKey;
+ CK_MECHANISM_TYPE mechanism;
+ PRErrorCode errorCode;
+ SECStatus rv;
+
+ PORT_InitCheapArena(&arena, DER_DEFAULT_CHUNKSIZE);
+ peerKey = PORT_ArenaZNew(&arena.arena, SECKEYPublicKey);
+ if (peerKey == NULL) {
+ goto loser;
+ }
+ peerKey->arena = &arena.arena;
+ peerKey->pkcs11Slot = NULL;
+ peerKey->pkcs11ID = CK_INVALID_HANDLE;
+
+ switch (entry->group->keaType) {
+ case ssl_kea_ecdh:
+ rv = ssl_ImportECDHKeyShare(ss, peerKey,
+ entry->key_exchange.data,
+ entry->key_exchange.len,
+ entry->group);
+ mechanism = CKM_ECDH1_DERIVE;
+ break;
+ case ssl_kea_dh:
+ rv = tls13_ImportDHEKeyShare(ss, peerKey,
+ entry->key_exchange.data,
+ entry->key_exchange.len,
+ keyPair->pubKey);
+ mechanism = CKM_DH_PKCS_DERIVE;
+ break;
+ default:
+ PORT_Assert(0);
+ goto loser;
+ }
+ if (rv != SECSuccess) {
+ goto loser;
+ }
+
+ ss->ssl3.hs.dheSecret = PK11_PubDeriveWithKDF(
+ keyPair->privKey, peerKey, PR_FALSE, NULL, NULL, mechanism,
+ tls13_GetHkdfMechanism(ss), CKA_DERIVE, 0, CKD_NULL, NULL, NULL);
+ if (!ss->ssl3.hs.dheSecret) {
+ ssl_MapLowLevelError(SSL_ERROR_KEY_EXCHANGE_FAILURE);
+ goto loser;
+ }
+ PORT_DestroyCheapArena(&arena);
+ return SECSuccess;
+
+loser:
+ PORT_DestroyCheapArena(&arena);
+ errorCode = PORT_GetError(); /* don't overwrite the error code */
+ tls13_FatalError(ss, errorCode, illegal_parameter);
+ return SECFailure;
+}
+
+SECStatus
+tls13_HandlePostHelloHandshakeMessage(sslSocket *ss, SSL3Opaque *b,
+ PRUint32 length, SSL3Hashes *hashesPtr)
+{
+ if (ss->sec.isServer && ss->ssl3.hs.zeroRttIgnore != ssl_0rtt_ignore_none) {
+ SSL_TRC(3, ("%d: TLS13[%d]: %s successfully decrypted handshake after"
+ "failed 0-RTT",
+ SSL_GETPID(), ss->fd));
+ ss->ssl3.hs.zeroRttIgnore = ssl_0rtt_ignore_none;
+ }
+
+ /* TODO(ekr@rtfm.com): Would it be better to check all the states here? */
+ switch (ss->ssl3.hs.msg_type) {
+ case certificate:
+ return tls13_HandleCertificate(ss, b, length);
+
+ case certificate_request:
+ return tls13_HandleCertificateRequest(ss, b, length);
+
+ case certificate_verify:
+ if (!hashesPtr) {
+ FATAL_ERROR(ss, SSL_ERROR_RX_UNEXPECTED_CERT_VERIFY, unexpected_message);
+ return SECFailure;
+ }
+ return tls13_HandleCertificateVerify(ss, b, length, hashesPtr);
+
+ case encrypted_extensions:
+ return tls13_HandleEncryptedExtensions(ss, b, length);
+
+ case new_session_ticket:
+ return tls13_HandleNewSessionTicket(ss, b, length);
+
+ case finished:
+ if (!hashesPtr) {
+ FATAL_ERROR(ss, SSL_ERROR_RX_UNEXPECTED_FINISHED, unexpected_message);
+ return SECFailure;
+ }
+ if (ss->sec.isServer) {
+ return tls13_ServerHandleFinished(ss, b, length, hashesPtr);
+ } else {
+ return tls13_ClientHandleFinished(ss, b, length, hashesPtr);
+ }
+
+ default:
+ FATAL_ERROR(ss, SSL_ERROR_RX_UNKNOWN_HANDSHAKE, unexpected_message);
+ return SECFailure;
+ }
+
+ PORT_Assert(0); /* Unreached */
+ return SECFailure;
+}
+
+static SECStatus
+tls13_RecoverWrappedSharedSecret(sslSocket *ss, sslSessionID *sid)
+{
+ PK11SymKey *wrapKey; /* wrapping key */
+ SECItem wrappedMS = { siBuffer, NULL, 0 };
+ SSLHashType hashType;
+
+ SSL_TRC(3, ("%d: TLS13[%d]: recovering static secret (%s)",
+ SSL_GETPID(), ss->fd, SSL_ROLE(ss)));
+ if (!sid->u.ssl3.keys.msIsWrapped) {
+ PORT_Assert(0); /* I think this can't happen. */
+ return SECFailure;
+ }
+
+ /* Now find the hash used as the PRF for the previous handshake. */
+ hashType = tls13_GetHashForCipherSuite(sid->u.ssl3.cipherSuite);
+
+ /* If we are the server, we compute the wrapping key, but if we
+ * are the client, it's coordinates are stored with the ticket. */
+ if (ss->sec.isServer) {
+ const sslServerCert *serverCert;
+
+ serverCert = ssl_FindServerCert(ss, &sid->certType);
+ PORT_Assert(serverCert);
+ wrapKey = ssl3_GetWrappingKey(ss, NULL, serverCert,
+ sid->u.ssl3.masterWrapMech,
+ ss->pkcs11PinArg);
+ } else {
+ PK11SlotInfo *slot = SECMOD_LookupSlot(sid->u.ssl3.masterModuleID,
+ sid->u.ssl3.masterSlotID);
+ if (!slot)
+ return SECFailure;
+
+ wrapKey = PK11_GetWrapKey(slot,
+ sid->u.ssl3.masterWrapIndex,
+ sid->u.ssl3.masterWrapMech,
+ sid->u.ssl3.masterWrapSeries,
+ ss->pkcs11PinArg);
+ PK11_FreeSlot(slot);
+ }
+ if (!wrapKey) {
+ return SECFailure;
+ }
+
+ wrappedMS.data = sid->u.ssl3.keys.wrapped_master_secret;
+ wrappedMS.len = sid->u.ssl3.keys.wrapped_master_secret_len;
+
+ /* unwrap the "master secret" which is actually RMS. */
+ ss->ssl3.hs.resumptionMasterSecret = PK11_UnwrapSymKeyWithFlags(
+ wrapKey, sid->u.ssl3.masterWrapMech,
+ NULL, &wrappedMS,
+ CKM_SSL3_MASTER_KEY_DERIVE,
+ CKA_DERIVE,
+ tls13_GetHashSizeForHash(hashType),
+ CKF_SIGN | CKF_VERIFY);
+ PK11_FreeSymKey(wrapKey);
+ if (!ss->ssl3.hs.resumptionMasterSecret) {
+ return SECFailure;
+ }
+
+ PRINT_KEY(50, (ss, "Recovered RMS", ss->ssl3.hs.resumptionMasterSecret));
+
+ return SECSuccess;
+}
+
+/* Key Derivation Functions.
+ *
+ * Below is the key schedule from [draft-ietf-tls-tls13].
+ *
+ * * The relevant functions from this file are indicated by tls13_Foo().
+ * 0
+ * |
+ * v
+ * PSK -> HKDF-Extract
+ * |
+ * v
+ * Early Secret ---> Derive-Secret(., "client early traffic secret",
+ * | ClientHello)
+ * | = client_early_traffic_secret
+ * v
+ * (EC)DHE -> HKDF-Extract
+ * |
+ * v
+ * Handshake Secret
+ * |
+ * +---------> Derive-Secret(., "client handshake traffic secret",
+ * | ClientHello...ServerHello)
+ * | = client_handshake_traffic_secret
+ * |
+ * +---------> Derive-Secret(., "server handshake traffic secret",
+ * | ClientHello...ServerHello)
+ * | = server_handshake_traffic_secret
+ * |
+ * v
+ * 0 -> HKDF-Extract
+ * |
+ * v
+ * Master Secret
+ * |
+ * +---------> Derive-Secret(., "client application traffic secret",
+ * | ClientHello...Server Finished)
+ * | = client_traffic_secret_0
+ * |
+ * +---------> Derive-Secret(., "server application traffic secret",
+ * | ClientHello...Server Finished)
+ * | = server_traffic_secret_0
+ * |
+ * +---------> Derive-Secret(., "exporter master secret",
+ * | ClientHello...Client Finished)
+ * | = exporter_secret
+ * |
+ * +---------> Derive-Secret(., "resumption master secret",
+ * ClientHello...Client Finished)
+ * = resumption_secret
+ *
+ */
+
+static SECStatus
+tls13_ComputeEarlySecrets(sslSocket *ss)
+{
+ SECStatus rv = SECSuccess;
+
+ SSL_TRC(5, ("%d: TLS13[%d]: compute early secrets (%s)",
+ SSL_GETPID(), ss->fd, SSL_ROLE(ss)));
+
+ /* Extract off the resumptionMasterSecret (if present), else pass the NULL
+ * resumptionMasterSecret which will be internally translated to zeroes. */
+ PORT_Assert(!ss->ssl3.hs.currentSecret);
+ rv = tls13_HkdfExtract(NULL, ss->ssl3.hs.resumptionMasterSecret,
+ tls13_GetHash(ss), &ss->ssl3.hs.currentSecret);
+ if (rv != SECSuccess) {
+ return SECFailure;
+ }
+
+ PORT_Assert(ss->statelessResume == (ss->ssl3.hs.resumptionMasterSecret != NULL));
+ if (ss->statelessResume) {
+ PRUint8 buf[1] = { 0 };
+ SSL3Hashes hashes;
+
+ PK11_FreeSymKey(ss->ssl3.hs.resumptionMasterSecret);
+ ss->ssl3.hs.resumptionMasterSecret = NULL;
+
+ rv = PK11_HashBuf(ssl3_HashTypeToOID(tls13_GetHash(ss)),
+ hashes.u.raw, buf, 0);
+ if (rv != SECSuccess) {
+ FATAL_ERROR(ss, SEC_ERROR_LIBRARY_FAILURE, internal_error);
+ return SECFailure;
+ }
+ hashes.len = tls13_GetHashSize(ss);
+
+ rv = tls13_DeriveSecret(ss, ss->ssl3.hs.currentSecret,
+ NULL, kHkdfLabelPskBinderKey, &hashes,
+ &ss->ssl3.hs.pskBinderKey);
+ if (rv != SECSuccess) {
+ return SECFailure;
+ }
+
+ rv = tls13_DeriveSecret(ss, ss->ssl3.hs.currentSecret,
+ NULL, kHkdfLabelEarlyExporterSecret,
+ &hashes, &ss->ssl3.hs.earlyExporterSecret);
+ if (rv != SECSuccess) {
+ return SECFailure;
+ }
+ } else {
+ PORT_Assert(!ss->ssl3.hs.resumptionMasterSecret);
+ }
+
+ return SECSuccess;
+}
+
+static SECStatus
+tls13_ComputeHandshakeSecrets(sslSocket *ss)
+{
+ SECStatus rv;
+ PK11SymKey *newSecret = NULL;
+
+ SSL_TRC(5, ("%d: TLS13[%d]: compute handshake secrets (%s)",
+ SSL_GETPID(), ss->fd, SSL_ROLE(ss)));
+
+ /* First update |currentSecret| to add |dheSecret|, if any. */
+ PORT_Assert(ss->ssl3.hs.currentSecret);
+ PORT_Assert(ss->ssl3.hs.dheSecret);
+ rv = tls13_HkdfExtract(ss->ssl3.hs.currentSecret, ss->ssl3.hs.dheSecret,
+ tls13_GetHash(ss), &newSecret);
+ if (rv != SECSuccess) {
+ LOG_ERROR(ss, SEC_ERROR_LIBRARY_FAILURE);
+ return rv;
+ }
+ PK11_FreeSymKey(ss->ssl3.hs.dheSecret);
+ ss->ssl3.hs.dheSecret = NULL;
+ PK11_FreeSymKey(ss->ssl3.hs.currentSecret);
+ ss->ssl3.hs.currentSecret = newSecret;
+
+ /* Now compute |*HsTrafficSecret| */
+ rv = tls13_DeriveSecret(ss, ss->ssl3.hs.currentSecret,
+ kHkdfLabelClient,
+ kHkdfLabelHandshakeTrafficSecret, NULL,
+ &ss->ssl3.hs.clientHsTrafficSecret);
+ if (rv != SECSuccess) {
+ LOG_ERROR(ss, SEC_ERROR_LIBRARY_FAILURE);
+ return rv;
+ }
+ rv = tls13_DeriveSecret(ss, ss->ssl3.hs.currentSecret,
+ kHkdfLabelServer,
+ kHkdfLabelHandshakeTrafficSecret, NULL,
+ &ss->ssl3.hs.serverHsTrafficSecret);
+ if (rv != SECSuccess) {
+ LOG_ERROR(ss, SEC_ERROR_LIBRARY_FAILURE);
+ return rv;
+ }
+
+ SSL_TRC(5, ("%d: TLS13[%d]: compute master secret (%s)",
+ SSL_GETPID(), ss->fd, SSL_ROLE(ss)));
+
+ /* Crank HKDF forward to make master secret, which we
+ * stuff in current secret. */
+ rv = tls13_HkdfExtract(ss->ssl3.hs.currentSecret,
+ NULL,
+ tls13_GetHash(ss),
+ &newSecret);
+
+ if (rv != SECSuccess) {
+ LOG_ERROR(ss, SEC_ERROR_LIBRARY_FAILURE);
+ return SECFailure;
+ }
+ PK11_FreeSymKey(ss->ssl3.hs.currentSecret);
+ ss->ssl3.hs.currentSecret = newSecret;
+
+ return SECSuccess;
+}
+
+static SECStatus
+tls13_ComputeApplicationSecrets(sslSocket *ss)
+{
+ SECStatus rv;
+
+ rv = tls13_DeriveSecret(ss, ss->ssl3.hs.currentSecret,
+ kHkdfLabelClient,
+ kHkdfLabelApplicationTrafficSecret,
+ NULL,
+ &ss->ssl3.hs.clientTrafficSecret);
+ if (rv != SECSuccess) {
+ return SECFailure;
+ }
+ rv = tls13_DeriveSecret(ss, ss->ssl3.hs.currentSecret,
+ kHkdfLabelServer,
+ kHkdfLabelApplicationTrafficSecret,
+ NULL,
+ &ss->ssl3.hs.serverTrafficSecret);
+ if (rv != SECSuccess) {
+ return SECFailure;
+ }
+
+ rv = tls13_DeriveSecret(ss, ss->ssl3.hs.currentSecret,
+ NULL, kHkdfLabelExporterMasterSecret,
+ NULL, &ss->ssl3.hs.exporterSecret);
+ if (rv != SECSuccess) {
+ return SECFailure;
+ }
+
+ return SECSuccess;
+}
+
+static SECStatus
+tls13_ComputeFinalSecrets(sslSocket *ss)
+{
+ SECStatus rv;
+ PK11SymKey *resumptionMasterSecret = NULL;
+
+ PORT_Assert(!ss->ssl3.crSpec->master_secret);
+ PORT_Assert(!ss->ssl3.cwSpec->master_secret);
+
+ rv = tls13_DeriveSecret(ss, ss->ssl3.hs.currentSecret,
+ NULL, kHkdfLabelResumptionMasterSecret,
+ NULL, &resumptionMasterSecret);
+ PK11_FreeSymKey(ss->ssl3.hs.currentSecret);
+ ss->ssl3.hs.currentSecret = NULL;
+ if (rv != SECSuccess) {
+ return SECFailure;
+ }
+
+ /* This is pretty gross. TLS 1.3 uses a number of master secrets:
+ * The master secret to generate the keys and then the resumption
+ * master secret for future connections. To make this work without
+ * refactoring too much of the SSLv3 code, we store the RMS in
+ * |crSpec->master_secret| and |cwSpec->master_secret|.
+ */
+ ss->ssl3.crSpec->master_secret = resumptionMasterSecret;
+ ss->ssl3.cwSpec->master_secret =
+ PK11_ReferenceSymKey(ss->ssl3.crSpec->master_secret);
+
+ return SECSuccess;
+}
+
+static void
+tls13_RestoreCipherInfo(sslSocket *ss, sslSessionID *sid)
+{
+ /* Set these to match the cached value.
+ * TODO(ekr@rtfm.com): Make a version with the "true" values.
+ * Bug 1256137.
+ */
+ ss->sec.authType = sid->authType;
+ ss->sec.authKeyBits = sid->authKeyBits;
+}
+
+/* Check whether resumption-PSK is allowed. */
+static PRBool
+tls13_CanResume(sslSocket *ss, const sslSessionID *sid)
+{
+ const sslServerCert *sc;
+
+ if (!sid) {
+ return PR_FALSE;
+ }
+
+ if (sid->version != ss->version) {
+ return PR_FALSE;
+ }
+
+ if (tls13_GetHashForCipherSuite(sid->u.ssl3.cipherSuite) != tls13_GetHashForCipherSuite(ss->ssl3.hs.cipher_suite)) {
+ return PR_FALSE;
+ }
+
+ /* Server sids don't remember the server cert we previously sent, but they
+ * do remember the type of certificate 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. */
+ sc = ssl_FindServerCert(ss, &sid->certType);
+ if (!sc || !sc->serverCert) {
+ return PR_FALSE;
+ }
+
+ return PR_TRUE;
+}
+
+static PRBool
+tls13_AlpnTagAllowed(const sslSocket *ss, const SECItem *tag)
+{
+ const unsigned char *data = ss->opt.nextProtoNego.data;
+ unsigned int length = ss->opt.nextProtoNego.len;
+ unsigned int offset = 0;
+
+ if (!tag->len)
+ return PR_TRUE;
+
+ while (offset < length) {
+ unsigned int taglen = (unsigned int)data[offset];
+ if ((taglen == tag->len) &&
+ !PORT_Memcmp(data + offset + 1, tag->data, tag->len))
+ return PR_TRUE;
+ offset += 1 + taglen;
+ }
+
+ return PR_FALSE;
+}
+
+static PRBool
+tls13_CanNegotiateZeroRtt(sslSocket *ss, const sslSessionID *sid)
+{
+ PORT_Assert(ss->ssl3.hs.zeroRttState == ssl_0rtt_sent);
+
+ if (!sid)
+ return PR_FALSE;
+ PORT_Assert(ss->statelessResume);
+ if (!ss->statelessResume)
+ return PR_FALSE;
+ if (ss->ssl3.hs.cipher_suite != sid->u.ssl3.cipherSuite)
+ return PR_FALSE;
+ if (!ss->opt.enable0RttData)
+ return PR_FALSE;
+ if (!(sid->u.ssl3.locked.sessionTicket.flags & ticket_allow_early_data))
+ return PR_FALSE;
+ if (SECITEM_CompareItem(&ss->xtnData.nextProto,
+ &sid->u.ssl3.alpnSelection) != 0)
+ return PR_FALSE;
+
+ return PR_TRUE;
+}
+
+/* Called from tls13_HandleClientHelloPart2 to update the state of 0-RTT handling.
+ *
+ * 0-RTT is only permitted if:
+ * 1. The early data extension was present.
+ * 2. We are resuming a session.
+ * 3. The 0-RTT option is set.
+ * 4. The ticket allowed 0-RTT.
+ * 5. We negotiated the same ALPN value as in the ticket.
+ */
+static void
+tls13_NegotiateZeroRtt(sslSocket *ss, const sslSessionID *sid)
+{
+ SSL_TRC(3, ("%d: TLS13[%d]: negotiate 0-RTT %p",
+ SSL_GETPID(), ss->fd, sid));
+
+ /* tls13_ServerHandleEarlyDataXtn sets this to ssl_0rtt_sent, so this will
+ * be ssl_0rtt_none unless early_data is present. */
+ if (ss->ssl3.hs.zeroRttState == ssl_0rtt_none) {
+ return;
+ }
+
+ /* If we rejected 0-RTT on the first ClientHello, then we can just say that
+ * there is no 0-RTT for the second. We shouldn't get any more. Reset the
+ * ignore state so that we treat decryption failure normally. */
+ if (ss->ssl3.hs.zeroRttIgnore == ssl_0rtt_ignore_hrr) {
+ PORT_Assert(ss->ssl3.hs.helloRetry);
+ ss->ssl3.hs.zeroRttState = ssl_0rtt_none;
+ ss->ssl3.hs.zeroRttIgnore = ssl_0rtt_ignore_none;
+ return;
+ }
+
+ if (!tls13_CanNegotiateZeroRtt(ss, sid)) {
+ SSL_TRC(3, ("%d: TLS13[%d]: ignore 0-RTT",
+ SSL_GETPID(), ss->fd));
+ ss->ssl3.hs.zeroRttState = ssl_0rtt_ignored;
+ ss->ssl3.hs.zeroRttIgnore = ssl_0rtt_ignore_trial;
+ return;
+ }
+
+ SSL_TRC(3, ("%d: TLS13[%d]: enable 0-RTT",
+ SSL_GETPID(), ss->fd));
+ PORT_Assert(ss->statelessResume);
+ ss->ssl3.hs.zeroRttState = ssl_0rtt_accepted;
+ ss->ssl3.hs.zeroRttIgnore = ssl_0rtt_ignore_none;
+}
+
+/* Check if the offered group is acceptable. */
+static PRBool
+tls13_isGroupAcceptable(const sslNamedGroupDef *offered,
+ const sslNamedGroupDef *preferredGroup)
+{
+ /* We accept epsilon (e) bits around the offered group size. */
+ const unsigned int e = 2;
+
+ PORT_Assert(offered);
+ PORT_Assert(preferredGroup);
+
+ if (offered->bits >= preferredGroup->bits - e &&
+ offered->bits <= preferredGroup->bits + e) {
+ return PR_TRUE;
+ }
+
+ return PR_FALSE;
+}
+
+/* Find remote key share for given group and return it.
+ * Returns NULL if no key share is found. */
+static TLS13KeyShareEntry *
+tls13_FindKeyShareEntry(sslSocket *ss, const sslNamedGroupDef *group)
+{
+ PRCList *cur_p = PR_NEXT_LINK(&ss->xtnData.remoteKeyShares);
+ while (cur_p != &ss->xtnData.remoteKeyShares) {
+ TLS13KeyShareEntry *offer = (TLS13KeyShareEntry *)cur_p;
+ if (offer->group == group) {
+ return offer;
+ }
+ cur_p = PR_NEXT_LINK(cur_p);
+ }
+ return NULL;
+}
+
+static SECStatus
+tls13_NegotiateKeyExchange(sslSocket *ss, TLS13KeyShareEntry **clientShare)
+{
+ unsigned int index;
+ TLS13KeyShareEntry *entry = NULL;
+ const sslNamedGroupDef *preferredGroup = NULL;
+
+ /* We insist on DHE. */
+ if (ss->statelessResume) {
+ if (!ssl3_ExtensionNegotiated(ss, ssl_tls13_psk_key_exchange_modes_xtn)) {
+ FATAL_ERROR(ss, SSL_ERROR_MISSING_PSK_KEY_EXCHANGE_MODES,
+ missing_extension);
+ return SECFailure;
+ }
+ if (!memchr(ss->xtnData.psk_ke_modes.data, tls13_psk_dh_ke,
+ ss->xtnData.psk_ke_modes.len)) {
+ SSL_TRC(3, ("%d: TLS13[%d]: client offered PSK without DH",
+ SSL_GETPID(), ss->fd));
+ ss->statelessResume = PR_FALSE;
+ }
+ }
+
+ /* Now figure out which key share we like the best out of the
+ * mutually supported groups, regardless of what the client offered
+ * for key shares.
+ */
+ if (!ssl3_ExtensionNegotiated(ss, ssl_supported_groups_xtn)) {
+ FATAL_ERROR(ss, SSL_ERROR_MISSING_SUPPORTED_GROUPS_EXTENSION,
+ missing_extension);
+ return SECFailure;
+ }
+
+ SSL_TRC(3, ("%d: TLS13[%d]: selected KE = %s",
+ SSL_GETPID(), ss->fd, ss->statelessResume ? "PSK + (EC)DHE" : "(EC)DHE"));
+
+ /* Find the preferred group and an according client key share available. */
+ for (index = 0; index < SSL_NAMED_GROUP_COUNT; ++index) {
+ /* Continue to the next group if this one is not enabled. */
+ if (!ss->namedGroupPreferences[index]) {
+ /* There's a gap in the preferred groups list. Assume this is a group
+ * that's not supported by the client but preferred by the server. */
+ if (preferredGroup) {
+ entry = NULL;
+ break;
+ }
+ continue;
+ }
+
+ /* Check if the client sent a key share for this group. */
+ entry = tls13_FindKeyShareEntry(ss, ss->namedGroupPreferences[index]);
+
+ if (preferredGroup) {
+ /* We already found our preferred group but the group didn't have a share. */
+ if (entry) {
+ /* The client sent a key share with group ss->namedGroupPreferences[index] */
+ if (tls13_isGroupAcceptable(ss->namedGroupPreferences[index],
+ preferredGroup)) {
+ /* This is not the preferred group, but it's acceptable */
+ preferredGroup = ss->namedGroupPreferences[index];
+ } else {
+ /* The proposed group is not acceptable. */
+ entry = NULL;
+ }
+ }
+ break;
+ } else {
+ /* The first enabled group is the preferred group. */
+ preferredGroup = ss->namedGroupPreferences[index];
+ if (entry) {
+ break;
+ }
+ }
+ }
+
+ if (!preferredGroup) {
+ FATAL_ERROR(ss, SSL_ERROR_NO_CYPHER_OVERLAP, handshake_failure);
+ return SECFailure;
+ }
+ SSL_TRC(3, ("%d: TLS13[%d]: group = %d", SSL_GETPID(), ss->fd,
+ preferredGroup->name));
+
+ if (!entry) {
+ return tls13_SendHelloRetryRequest(ss, preferredGroup);
+ }
+
+ PORT_Assert(preferredGroup == entry->group);
+ *clientShare = entry;
+
+ return SECSuccess;
+}
+
+SECStatus
+tls13_SelectServerCert(sslSocket *ss)
+{
+ PRCList *cursor;
+ SECStatus rv;
+
+ if (!ssl3_ExtensionNegotiated(ss, ssl_signature_algorithms_xtn)) {
+ FATAL_ERROR(ss, SSL_ERROR_MISSING_SIGNATURE_ALGORITHMS_EXTENSION,
+ missing_extension);
+ return SECFailure;
+ }
+
+ /* This picks the first certificate that has:
+ * a) the right authentication method, and
+ * b) the right named curve (EC only)
+ *
+ * We might want to do some sort of ranking here later. For now, it's all
+ * based on what order they are configured in. */
+ for (cursor = PR_NEXT_LINK(&ss->serverCerts);
+ cursor != &ss->serverCerts;
+ cursor = PR_NEXT_LINK(cursor)) {
+ sslServerCert *cert = (sslServerCert *)cursor;
+
+ if (cert->certType.authType == ssl_auth_rsa_pss ||
+ cert->certType.authType == ssl_auth_rsa_decrypt) {
+ continue;
+ }
+
+ rv = ssl_PickSignatureScheme(ss,
+ cert->serverKeyPair->pubKey,
+ cert->serverKeyPair->privKey,
+ ss->xtnData.clientSigSchemes,
+ ss->xtnData.numClientSigScheme,
+ PR_FALSE);
+ if (rv == SECSuccess) {
+ /* Found one. */
+ ss->sec.serverCert = cert;
+ ss->sec.authType = cert->certType.authType;
+ ss->ssl3.hs.kea_def_mutable.authKeyType = cert->certType.authType;
+ ss->sec.authKeyBits = cert->serverKeyBits;
+ return SECSuccess;
+ }
+ }
+
+ FATAL_ERROR(ss, SSL_ERROR_UNSUPPORTED_SIGNATURE_ALGORITHM,
+ handshake_failure);
+ return SECFailure;
+}
+
+static SECStatus
+tls13_NegotiateAuthentication(sslSocket *ss)
+{
+ SECStatus rv;
+
+ if (ss->statelessResume) {
+ SSL_TRC(3, ("%d: TLS13[%d]: selected PSK authentication",
+ SSL_GETPID(), ss->fd));
+ ss->ssl3.hs.signatureScheme = ssl_sig_none;
+ ss->ssl3.hs.kea_def_mutable.authKeyType = ssl_auth_psk;
+ return SECSuccess;
+ }
+
+ SSL_TRC(3, ("%d: TLS13[%d]: selected certificate authentication",
+ SSL_GETPID(), ss->fd));
+ /* We've now established that we need to sign.... */
+ rv = tls13_SelectServerCert(ss);
+ if (rv != SECSuccess) {
+ return SECFailure;
+ }
+ ss->ssl3.hs.kea_def_mutable.authKeyType =
+ ss->sec.serverCert->certType.authType;
+ return SECSuccess;
+}
+
+/* Called from ssl3_HandleClientHello after we have parsed the
+ * ClientHello and are sure that we are going to do TLS 1.3
+ * or fail. */
+SECStatus
+tls13_HandleClientHelloPart2(sslSocket *ss,
+ const SECItem *suites,
+ sslSessionID *sid)
+{
+ SECStatus rv;
+ SSL3Statistics *ssl3stats = SSL_GetStatistics();
+ TLS13KeyShareEntry *clientShare = NULL;
+ int j;
+ ssl3CipherSuite previousCipherSuite;
+
+ if (ssl3_ExtensionNegotiated(ss, ssl_tls13_early_data_xtn)) {
+ ss->ssl3.hs.zeroRttState = ssl_0rtt_sent;
+
+ if (IS_DTLS(ss)) {
+ /* Save the null spec, which we should be currently reading. We will
+ * use this when 0-RTT sending is over. */
+ ssl_GetSpecReadLock(ss);
+ ss->ssl3.hs.nullSpec = ss->ssl3.crSpec;
+ tls13_CipherSpecAddRef(ss->ssl3.hs.nullSpec);
+ PORT_Assert(ss->ssl3.hs.nullSpec->cipher_def->cipher == cipher_null);
+ ssl_ReleaseSpecReadLock(ss);
+ }
+ }
+
+#ifndef PARANOID
+ /* Look for a matching cipher suite. */
+ j = ssl3_config_match_init(ss);
+ if (j <= 0) { /* no ciphers are working/supported by PK11 */
+ FATAL_ERROR(ss, PORT_GetError(), internal_error);
+ goto loser;
+ }
+#endif
+
+ previousCipherSuite = ss->ssl3.hs.cipher_suite;
+ rv = ssl3_NegotiateCipherSuite(ss, suites, PR_FALSE);
+ if (rv != SECSuccess) {
+ FATAL_ERROR(ss, SSL_ERROR_NO_CYPHER_OVERLAP, handshake_failure);
+ goto loser;
+ }
+ /* If we are going around again, then we should make sure that the cipher
+ * suite selection doesn't change. That's a sign of client shennanigans. */
+ if (ss->ssl3.hs.helloRetry &&
+ ss->ssl3.hs.cipher_suite != previousCipherSuite) {
+ FATAL_ERROR(ss, SSL_ERROR_RX_MALFORMED_CLIENT_HELLO, handshake_failure);
+ goto loser;
+ }
+
+ /* Now create a synthetic kea_def that we can tweak. */
+ ss->ssl3.hs.kea_def_mutable = *ss->ssl3.hs.kea_def;
+ ss->ssl3.hs.kea_def = &ss->ssl3.hs.kea_def_mutable;
+
+ /* Note: We call this quite a bit earlier than with TLS 1.2 and
+ * before. */
+ rv = ssl3_ServerCallSNICallback(ss);
+ if (rv != SECSuccess) {
+ goto loser; /* An alert has already been sent. */
+ }
+
+ /* Check if we could in principle resume. */
+ if (ss->statelessResume) {
+ PORT_Assert(sid);
+ if (!sid) {
+ FATAL_ERROR(ss, SEC_ERROR_LIBRARY_FAILURE, internal_error);
+ return SECFailure;
+ }
+ if (!tls13_CanResume(ss, sid)) {
+ ss->statelessResume = PR_FALSE;
+ }
+ }
+
+ /* Select key exchange. */
+ rv = tls13_NegotiateKeyExchange(ss, &clientShare);
+ if (rv != SECSuccess) {
+ goto loser;
+ }
+
+ /* If we didn't find a client key share, we have to retry. */
+ if (!clientShare) {
+ if (sid) { /* Free the sid. */
+ ss->sec.uncache(sid);
+ ssl_FreeSID(sid);
+ }
+ PORT_Assert(ss->ssl3.hs.helloRetry);
+ return SECSuccess;
+ }
+
+ /* Select the authentication (this is also handshake shape). */
+ rv = tls13_NegotiateAuthentication(ss);
+ if (rv != SECSuccess) {
+ goto loser;
+ }
+
+ if (ss->statelessResume) {
+ /* We are now committed to trying to resume. */
+ PORT_Assert(sid);
+
+ /* Check that the negotiated SNI and the cached SNI match. */
+ if (SECITEM_CompareItem(&sid->u.ssl3.srvName,
+ &ss->ssl3.hs.srvVirtName) != SECEqual) {
+ FATAL_ERROR(ss, SSL_ERROR_RX_MALFORMED_CLIENT_HELLO,
+ handshake_failure);
+ goto loser;
+ }
+
+ rv = tls13_RecoverWrappedSharedSecret(ss, sid);
+ if (rv != SECSuccess) {
+ SSL_AtomicIncrementLong(&ssl3stats->hch_sid_cache_not_ok);
+ FATAL_ERROR(ss, SEC_ERROR_LIBRARY_FAILURE, internal_error);
+ goto loser;
+ }
+ tls13_RestoreCipherInfo(ss, sid);
+
+ ss->sec.serverCert = ssl_FindServerCert(ss, &sid->certType);
+ PORT_Assert(ss->sec.serverCert);
+ ss->sec.localCert = CERT_DupCertificate(ss->sec.serverCert->serverCert);
+ if (sid->peerCert != NULL) {
+ ss->sec.peerCert = CERT_DupCertificate(sid->peerCert);
+ }
+ ssl3_RegisterExtensionSender(
+ ss, &ss->xtnData,
+ ssl_tls13_pre_shared_key_xtn, tls13_ServerSendPreSharedKeyXtn);
+
+ tls13_NegotiateZeroRtt(ss, sid);
+ } else {
+ 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;
+ }
+ tls13_NegotiateZeroRtt(ss, NULL);
+ }
+
+ /* Need to compute early secrets. */
+ rv = tls13_ComputeEarlySecrets(ss);
+ if (rv != SECSuccess) {
+ FATAL_ERROR(ss, SEC_ERROR_LIBRARY_FAILURE, internal_error);
+ return SECFailure;
+ }
+
+ /* Now that we have the binder key check the binder. */
+ if (ss->statelessResume) {
+ SSL3Hashes hashes;
+
+ rv = tls13_ComputePskBinderHash(ss, ss->xtnData.pskBinderPrefixLen,
+ &hashes);
+ if (rv != SECSuccess) {
+ FATAL_ERROR(ss, SEC_ERROR_LIBRARY_FAILURE, internal_error);
+ goto loser;
+ }
+
+ rv = tls13_VerifyFinished(ss, client_hello,
+ ss->ssl3.hs.pskBinderKey,
+ ss->xtnData.pskBinder.data,
+ ss->xtnData.pskBinder.len,
+ &hashes);
+ if (rv != SECSuccess) {
+ goto loser;
+ }
+ }
+
+ /* This needs to go after we verify the psk binder. */
+ rv = ssl3_InitHandshakeHashes(ss);
+ if (rv != SECSuccess) {
+ goto loser;
+ }
+
+ /* If this is TLS 1.3 we are expecting a ClientKeyShare
+ * extension. Missing/absent extension cause failure
+ * below. */
+ rv = tls13_HandleClientKeyShare(ss, clientShare);
+ if (rv != SECSuccess) {
+ goto loser; /* An alert was sent already. */
+ }
+
+ /* From this point we are either committed to resumption, or not. */
+ if (ss->statelessResume) {
+ SSL_AtomicIncrementLong(&ssl3stats->hch_sid_cache_hits);
+ SSL_AtomicIncrementLong(&ssl3stats->hch_sid_stateless_resumes);
+ } else {
+ if (sid) {
+ /* We had a sid, but it's no longer valid, free it. */
+ SSL_AtomicIncrementLong(&ssl3stats->hch_sid_cache_not_ok);
+ ss->sec.uncache(sid);
+ ssl_FreeSID(sid);
+ } else {
+ SSL_AtomicIncrementLong(&ssl3stats->hch_sid_cache_misses);
+ }
+
+ sid = ssl3_NewSessionID(ss, PR_TRUE);
+ if (!sid) {
+ FATAL_ERROR(ss, PORT_GetError(), internal_error);
+ return SECFailure;
+ }
+ }
+ /* Take ownership of the session. */
+ ss->sec.ci.sid = sid;
+ sid = NULL;
+
+ if (ss->ssl3.hs.zeroRttState == ssl_0rtt_accepted) {
+ rv = tls13_DeriveSecret(ss, ss->ssl3.hs.currentSecret,
+ kHkdfLabelClient,
+ kHkdfLabelEarlyTrafficSecret,
+ NULL, /* Current running hash. */
+ &ss->ssl3.hs.clientEarlyTrafficSecret);
+ if (rv != SECSuccess) {
+ FATAL_ERROR(ss, SEC_ERROR_LIBRARY_FAILURE, internal_error);
+ return SECFailure;
+ }
+ }
+
+ ssl_GetXmitBufLock(ss);
+ rv = tls13_SendServerHelloSequence(ss);
+ ssl_ReleaseXmitBufLock(ss);
+ if (rv != SECSuccess) {
+ FATAL_ERROR(ss, PORT_GetError(), handshake_failure);
+ return SECFailure;
+ }
+
+ return SECSuccess;
+
+loser:
+ if (sid) {
+ ss->sec.uncache(sid);
+ ssl_FreeSID(sid);
+ }
+ return SECFailure;
+}
+
+static SECStatus
+tls13_SendHelloRetryRequest(sslSocket *ss, const sslNamedGroupDef *selectedGroup)
+{
+ SECStatus rv;
+
+ SSL_TRC(3, ("%d: TLS13[%d]: send hello retry request handshake",
+ SSL_GETPID(), ss->fd));
+
+ PORT_Assert(ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss));
+
+ /* We asked already, but made no progress. */
+ if (ss->ssl3.hs.helloRetry) {
+ FATAL_ERROR(ss, SSL_ERROR_BAD_2ND_CLIENT_HELLO, illegal_parameter);
+ return SECFailure;
+ }
+
+ ssl_GetXmitBufLock(ss);
+ rv = ssl3_AppendHandshakeHeader(ss, hello_retry_request,
+ 2 + /* version */
+ 2 + /* extension length */
+ 2 + /* group extension id */
+ 2 + /* group extension length */
+ 2 /* group */);
+ if (rv != SECSuccess) {
+ FATAL_ERROR(ss, SEC_ERROR_LIBRARY_FAILURE, internal_error);
+ goto loser;
+ }
+
+ rv = ssl3_AppendHandshakeNumber(
+ ss, tls13_EncodeDraftVersion(ss->version), 2);
+ if (rv != SECSuccess) {
+ FATAL_ERROR(ss, SEC_ERROR_LIBRARY_FAILURE, internal_error);
+ goto loser;
+ }
+
+ /* Length of extensions. */
+ rv = ssl3_AppendHandshakeNumber(ss, 2 + 2 + 2, 2);
+ if (rv != SECSuccess) {
+ FATAL_ERROR(ss, SEC_ERROR_LIBRARY_FAILURE, internal_error);
+ goto loser;
+ }
+
+ /* Key share extension - currently the only reason we send this. */
+ rv = ssl3_AppendHandshakeNumber(ss, ssl_tls13_key_share_xtn, 2);
+ if (rv != SECSuccess) {
+ FATAL_ERROR(ss, SEC_ERROR_LIBRARY_FAILURE, internal_error);
+ goto loser;
+ }
+ /* Key share extension length. */
+ rv = ssl3_AppendHandshakeNumber(ss, 2, 2);
+ if (rv != SECSuccess) {
+ FATAL_ERROR(ss, SEC_ERROR_LIBRARY_FAILURE, internal_error);
+ goto loser;
+ }
+ rv = ssl3_AppendHandshakeNumber(ss, selectedGroup->name, 2);
+ if (rv != SECSuccess) {
+ FATAL_ERROR(ss, SEC_ERROR_LIBRARY_FAILURE, internal_error);
+ goto loser;
+ }
+
+ rv = ssl3_FlushHandshake(ss, 0);
+ if (rv != SECSuccess) {
+ goto loser; /* error code set by ssl3_FlushHandshake */
+ }
+ ssl_ReleaseXmitBufLock(ss);
+
+ ss->ssl3.hs.helloRetry = PR_TRUE;
+
+ /* We received early data but have to ignore it because we sent a retry. */
+ if (ss->ssl3.hs.zeroRttState == ssl_0rtt_sent) {
+ ss->ssl3.hs.zeroRttState = ssl_0rtt_ignored;
+ ss->ssl3.hs.zeroRttIgnore = ssl_0rtt_ignore_hrr;
+ }
+
+ return SECSuccess;
+
+loser:
+ ssl_ReleaseXmitBufLock(ss);
+ return SECFailure;
+}
+
+/* Called from tls13_HandleClientHello.
+ *
+ * Caller must hold Handshake and RecvBuf locks.
+ */
+
+static SECStatus
+tls13_HandleClientKeyShare(sslSocket *ss, TLS13KeyShareEntry *peerShare)
+{
+ SECStatus rv;
+ sslEphemeralKeyPair *keyPair; /* ours */
+
+ SSL_TRC(3, ("%d: TLS13[%d]: handle client_key_share handshake",
+ SSL_GETPID(), ss->fd));
+
+ PORT_Assert(ss->opt.noLocks || ssl_HaveRecvBufLock(ss));
+ PORT_Assert(ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss));
+ PORT_Assert(peerShare);
+
+ tls13_SetKeyExchangeType(ss, peerShare->group);
+
+ /* Generate our key */
+ rv = tls13_CreateKeyShare(ss, peerShare->group);
+ if (rv != SECSuccess) {
+ return rv;
+ }
+
+ /* We should have exactly one key share. */
+ PORT_Assert(!PR_CLIST_IS_EMPTY(&ss->ephemeralKeyPairs));
+ PORT_Assert(PR_PREV_LINK(&ss->ephemeralKeyPairs) ==
+ PR_NEXT_LINK(&ss->ephemeralKeyPairs));
+
+ keyPair = ((sslEphemeralKeyPair *)PR_NEXT_LINK(&ss->ephemeralKeyPairs));
+ ss->sec.keaKeyBits = SECKEY_PublicKeyStrengthInBits(keyPair->keys->pubKey);
+
+ /* Register the sender */
+ rv = ssl3_RegisterExtensionSender(ss, &ss->xtnData, ssl_tls13_key_share_xtn,
+ tls13_ServerSendKeyShareXtn);
+ if (rv != SECSuccess) {
+ return SECFailure; /* Error code set already. */
+ }
+
+ rv = tls13_HandleKeyShare(ss, peerShare, keyPair->keys);
+ return rv; /* Error code set already. */
+}
+
+/*
+ * [draft-ietf-tls-tls13-11] Section 6.3.3.2
+ *
+ * opaque DistinguishedName<1..2^16-1>;
+ *
+ * struct {
+ * opaque certificate_extension_oid<1..2^8-1>;
+ * opaque certificate_extension_values<0..2^16-1>;
+ * } CertificateExtension;
+ *
+ * struct {
+ * opaque certificate_request_context<0..2^8-1>;
+ * SignatureAndHashAlgorithm
+ * supported_signature_algorithms<2..2^16-2>;
+ * DistinguishedName certificate_authorities<0..2^16-1>;
+ * CertificateExtension certificate_extensions<0..2^16-1>;
+ * } CertificateRequest;
+ */
+static SECStatus
+tls13_SendCertificateRequest(sslSocket *ss)
+{
+ SECStatus rv;
+ int calen;
+ SECItem *names;
+ int nnames;
+ SECItem *name;
+ int i;
+ PRUint8 sigSchemes[MAX_SIGNATURE_SCHEMES * 2];
+ unsigned int sigSchemesLength = 0;
+ int length;
+
+ SSL_TRC(3, ("%d: TLS13[%d]: begin send certificate_request",
+ SSL_GETPID(), ss->fd));
+
+ rv = ssl3_EncodeSigAlgs(ss, sigSchemes, sizeof(sigSchemes),
+ &sigSchemesLength);
+ if (rv != SECSuccess) {
+ return rv;
+ }
+
+ ssl3_GetCertificateRequestCAs(ss, &calen, &names, &nnames);
+ length = 1 + 0 /* length byte for empty request context */ +
+ 2 + sigSchemesLength + 2 + calen + 2;
+
+ rv = ssl3_AppendHandshakeHeader(ss, certificate_request, length);
+ if (rv != SECSuccess) {
+ return rv; /* err set by AppendHandshake. */
+ }
+ rv = ssl3_AppendHandshakeNumber(ss, 0, 1);
+ if (rv != SECSuccess) {
+ return rv; /* err set by AppendHandshake. */
+ }
+ rv = ssl3_AppendHandshakeVariable(ss, sigSchemes, sigSchemesLength, 2);
+ 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. */
+ }
+ }
+ rv = ssl3_AppendHandshakeNumber(ss, 0, 2);
+ if (rv != SECSuccess) {
+ return rv; /* err set by AppendHandshake. */
+ }
+
+ return SECSuccess;
+}
+
+SECStatus
+tls13_HandleHelloRetryRequest(sslSocket *ss, SSL3Opaque *b, PRUint32 length)
+{
+ SECStatus rv;
+ PRInt32 tmp;
+ SSL3ProtocolVersion version;
+
+ SSL_TRC(3, ("%d: TLS13[%d]: handle hello retry request",
+ SSL_GETPID(), ss->fd));
+
+ PORT_Assert(ss->opt.noLocks || ssl_HaveRecvBufLock(ss));
+ PORT_Assert(ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss));
+
+ if (ss->vrange.max < SSL_LIBRARY_VERSION_TLS_1_3) {
+ FATAL_ERROR(ss, SSL_ERROR_RX_UNEXPECTED_HELLO_RETRY_REQUEST,
+ unexpected_message);
+ return SECFailure;
+ }
+
+ /* Client only. */
+ rv = TLS13_CHECK_HS_STATE(ss, SSL_ERROR_RX_UNEXPECTED_HELLO_RETRY_REQUEST,
+ wait_server_hello);
+ if (rv != SECSuccess) {
+ return SECFailure;
+ }
+
+ /* Fool me once, shame on you; fool me twice... */
+ if (ss->ssl3.hs.helloRetry) {
+ FATAL_ERROR(ss, SSL_ERROR_RX_UNEXPECTED_HELLO_RETRY_REQUEST,
+ unexpected_message);
+ return SECFailure;
+ }
+
+ if (ss->ssl3.hs.zeroRttState == ssl_0rtt_sent) {
+ /* Oh well, back to the start. */
+ tls13_SetNullCipherSpec(ss, &ss->ssl3.cwSpec);
+ ss->ssl3.hs.zeroRttState = ssl_0rtt_ignored;
+ } else {
+ PORT_Assert(ss->ssl3.hs.zeroRttState == ssl_0rtt_none);
+ }
+
+ /* Version. */
+ rv = ssl_ClientReadVersion(ss, &b, &length, &version);
+ if (rv != SECSuccess) {
+ return SECFailure; /* alert already sent */
+ }
+ if (version > ss->vrange.max || version < SSL_LIBRARY_VERSION_TLS_1_3) {
+ FATAL_ERROR(ss, SSL_ERROR_RX_MALFORMED_HELLO_RETRY_REQUEST,
+ protocol_version);
+ return SECFailure;
+ }
+
+ /* Extensions. */
+ tmp = ssl3_ConsumeHandshakeNumber(ss, 2, &b, &length);
+ if (tmp < 0) {
+ return SECFailure; /* error code already set */
+ }
+ /* Extensions must be non-empty and use the remainder of the message.
+ * This means that a HelloRetryRequest cannot be a no-op: we must have an
+ * extension, it must be one that we understand and recognize as being valid
+ * for HelloRetryRequest, and all the extensions we permit cause us to
+ * modify our ClientHello in some way. */
+ if (!tmp || tmp != length) {
+ FATAL_ERROR(ss, SSL_ERROR_RX_MALFORMED_HELLO_RETRY_REQUEST,
+ decode_error);
+ return SECFailure;
+ }
+
+ rv = ssl3_HandleExtensions(ss, &b, &length, hello_retry_request);
+ if (rv != SECSuccess) {
+ return SECFailure; /* Error code set below */
+ }
+
+ ss->ssl3.hs.helloRetry = PR_TRUE;
+
+ ssl_GetXmitBufLock(ss);
+ rv = ssl3_SendClientHello(ss, client_hello_retry);
+ ssl_ReleaseXmitBufLock(ss);
+ if (rv != SECSuccess) {
+ return SECFailure;
+ }
+
+ return SECSuccess;
+}
+
+static SECStatus
+tls13_HandleCertificateRequest(sslSocket *ss, SSL3Opaque *b, PRUint32 length)
+{
+ SECStatus rv;
+ TLS13CertificateRequest *certRequest = NULL;
+ SECItem context = { siBuffer, NULL, 0 };
+ PLArenaPool *arena;
+ PRInt32 extensionsLength;
+
+ SSL_TRC(3, ("%d: TLS13[%d]: handle certificate_request sequence",
+ SSL_GETPID(), ss->fd));
+
+ PORT_Assert(ss->opt.noLocks || ssl_HaveRecvBufLock(ss));
+ PORT_Assert(ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss));
+
+ /* Client */
+ rv = TLS13_CHECK_HS_STATE(ss, SSL_ERROR_RX_UNEXPECTED_CERT_REQUEST,
+ wait_cert_request);
+ if (rv != SECSuccess) {
+ return SECFailure;
+ }
+
+ PORT_Assert(ss->ssl3.clientCertChain == NULL);
+ PORT_Assert(ss->ssl3.clientCertificate == NULL);
+ PORT_Assert(ss->ssl3.clientPrivateKey == NULL);
+ PORT_Assert(ss->ssl3.hs.certificateRequest == NULL);
+
+ arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
+ if (!arena) {
+ FATAL_ERROR(ss, SEC_ERROR_LIBRARY_FAILURE, internal_error);
+ return SECFailure;
+ }
+
+ rv = ssl3_ConsumeHandshakeVariable(ss, &context, 1, &b, &length);
+ if (rv != SECSuccess)
+ goto loser;
+
+ /* We don't support post-handshake client auth, the certificate request
+ * context must always be null. */
+ if (context.len > 0) {
+ FATAL_ERROR(ss, SSL_ERROR_RX_MALFORMED_CERT_REQUEST, illegal_parameter);
+ goto loser;
+ }
+
+ certRequest = PORT_ArenaZNew(arena, TLS13CertificateRequest);
+ if (!certRequest)
+ goto loser;
+ certRequest->arena = arena;
+ certRequest->ca_list.arena = arena;
+
+ rv = ssl_ParseSignatureSchemes(ss, arena,
+ &certRequest->signatureSchemes,
+ &certRequest->signatureSchemeCount,
+ &b, &length);
+ if (rv != SECSuccess) {
+ FATAL_ERROR(ss, SSL_ERROR_RX_MALFORMED_CERT_REQUEST,
+ decode_error);
+ goto loser;
+ }
+
+ rv = ssl3_ParseCertificateRequestCAs(ss, &b, &length, arena,
+ &certRequest->ca_list);
+ if (rv != SECSuccess)
+ goto loser; /* alert already sent */
+
+ /* Verify that the extensions length is correct. */
+ extensionsLength = ssl3_ConsumeHandshakeNumber(ss, 2, &b, &length);
+ if (extensionsLength < 0) {
+ goto loser; /* alert already sent */
+ }
+ if (extensionsLength != length) {
+ FATAL_ERROR(ss, SSL_ERROR_RX_MALFORMED_CERT_REQUEST,
+ illegal_parameter);
+ goto loser;
+ }
+
+ rv = SECITEM_CopyItem(arena, &certRequest->context, &context);
+ if (rv != SECSuccess)
+ goto loser;
+
+ TLS13_SET_HS_STATE(ss, wait_server_cert);
+ ss->ssl3.hs.certificateRequest = certRequest;
+
+ return SECSuccess;
+
+loser:
+ PORT_FreeArena(arena, PR_FALSE);
+ return SECFailure;
+}
+
+static SECStatus
+tls13_SendEncryptedServerSequence(sslSocket *ss)
+{
+ SECStatus rv;
+
+ rv = tls13_ComputeHandshakeSecrets(ss);
+ if (rv != SECSuccess) {
+ return SECFailure; /* error code is set. */
+ }
+
+ rv = tls13_SetCipherSpec(ss, TrafficKeyHandshake,
+ CipherSpecWrite, PR_FALSE);
+ if (rv != SECSuccess) {
+ LOG_ERROR(ss, SEC_ERROR_LIBRARY_FAILURE);
+ return SECFailure;
+ }
+
+ ss->ssl3.hs.shortHeaders = ssl3_ExtensionNegotiated(
+ ss, ssl_tls13_short_header_xtn);
+
+ if (ss->ssl3.hs.zeroRttState == ssl_0rtt_accepted) {
+ rv = ssl3_RegisterExtensionSender(ss, &ss->xtnData, ssl_tls13_early_data_xtn,
+ tls13_ServerSendEarlyDataXtn);
+ if (rv != SECSuccess) {
+ return SECFailure; /* Error code set already. */
+ }
+ }
+
+ rv = tls13_SendEncryptedExtensions(ss);
+ if (rv != SECSuccess) {
+ return SECFailure; /* error code is set. */
+ }
+
+ if (ss->opt.requestCertificate) {
+ rv = tls13_SendCertificateRequest(ss);
+ if (rv != SECSuccess) {
+ return SECFailure; /* error code is set. */
+ }
+ }
+ if (ss->ssl3.hs.signatureScheme != ssl_sig_none) {
+ SECKEYPrivateKey *svrPrivKey;
+
+ rv = tls13_SendCertificate(ss);
+ if (rv != SECSuccess) {
+ return SECFailure; /* error code is set. */
+ }
+
+ svrPrivKey = ss->sec.serverCert->serverKeyPair->privKey;
+ rv = tls13_SendCertificateVerify(ss, svrPrivKey);
+ if (rv != SECSuccess) {
+ return SECFailure; /* err code is set. */
+ }
+ }
+
+ rv = tls13_SendFinished(ss, ss->ssl3.hs.serverHsTrafficSecret);
+ if (rv != SECSuccess) {
+ return SECFailure; /* error code is set. */
+ }
+
+ return SECSuccess;
+}
+
+/* Called from: ssl3_HandleClientHello */
+static SECStatus
+tls13_SendServerHelloSequence(sslSocket *ss)
+{
+ SECStatus rv;
+ PRErrorCode err = 0;
+
+ SSL_TRC(3, ("%d: TLS13[%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 = tls13_SendEncryptedServerSequence(ss);
+ if (rv != SECSuccess) {
+ err = PORT_GetError();
+ }
+ /* Even if we get an error, since the ServerHello was successfully
+ * serialized, we should give it a chance to reach the network. This gives
+ * the client a chance to perform the key exchange and decrypt the alert
+ * we're about to send. */
+ rv |= ssl3_FlushHandshake(ss, 0);
+ if (rv != SECSuccess) {
+ if (err) {
+ PORT_SetError(err);
+ }
+ return SECFailure;
+ }
+
+ /* Compute the rest of the secrets except for the resumption
+ * and exporter secret. */
+ rv = tls13_ComputeApplicationSecrets(ss);
+ if (rv != SECSuccess) {
+ LOG_ERROR(ss, PORT_GetError());
+ return SECFailure;
+ }
+
+ rv = tls13_SetCipherSpec(ss, TrafficKeyApplicationData,
+ CipherSpecWrite, PR_FALSE);
+ if (rv != SECSuccess) {
+ LOG_ERROR(ss, SEC_ERROR_LIBRARY_FAILURE);
+ return SECFailure;
+ }
+
+ if (ss->ssl3.hs.zeroRttState == ssl_0rtt_accepted) {
+ rv = tls13_SetCipherSpec(ss,
+ TrafficKeyEarlyApplicationData,
+ CipherSpecRead, PR_TRUE);
+ if (rv != SECSuccess) {
+ LOG_ERROR(ss, SEC_ERROR_LIBRARY_FAILURE);
+ return SECFailure;
+ }
+ } else {
+ PORT_Assert(ss->ssl3.hs.zeroRttState == ssl_0rtt_none ||
+ ss->ssl3.hs.zeroRttState == ssl_0rtt_ignored);
+
+ rv = tls13_SetCipherSpec(ss,
+ TrafficKeyHandshake,
+ CipherSpecRead, PR_FALSE);
+ if (rv != SECSuccess) {
+ LOG_ERROR(ss, SEC_ERROR_LIBRARY_FAILURE);
+ return SECFailure;
+ }
+ }
+
+ TLS13_SET_HS_STATE(ss,
+ ss->opt.requestCertificate ? wait_client_cert
+ : wait_finished);
+ return SECSuccess;
+}
+
+SECStatus
+tls13_HandleServerHelloPart2(sslSocket *ss)
+{
+ SECStatus rv;
+ sslSessionID *sid = ss->sec.ci.sid;
+ SSL3Statistics *ssl3stats = SSL_GetStatistics();
+
+ if (ssl3_ExtensionNegotiated(ss, ssl_tls13_pre_shared_key_xtn)) {
+ PORT_Assert(ss->statelessResume);
+ } else {
+ if (ss->ssl3.hs.currentSecret) {
+ PORT_Assert(ss->statelessResume);
+ PK11_FreeSymKey(ss->ssl3.hs.currentSecret);
+ ss->ssl3.hs.currentSecret = NULL;
+ }
+ ss->statelessResume = PR_FALSE;
+ }
+
+ if (ss->statelessResume) {
+ if (tls13_GetHash(ss) !=
+ tls13_GetHashForCipherSuite(sid->u.ssl3.cipherSuite)) {
+ FATAL_ERROR(ss, SSL_ERROR_RX_MALFORMED_SERVER_HELLO,
+ illegal_parameter);
+ return SECFailure;
+ }
+ }
+
+ /* Now create a synthetic kea_def that we can tweak. */
+ ss->ssl3.hs.kea_def_mutable = *ss->ssl3.hs.kea_def;
+ ss->ssl3.hs.kea_def = &ss->ssl3.hs.kea_def_mutable;
+
+ if (ss->statelessResume) {
+ /* PSK */
+ ss->ssl3.hs.kea_def_mutable.authKeyType = ssl_auth_psk;
+ tls13_RestoreCipherInfo(ss, sid);
+ if (sid->peerCert) {
+ ss->sec.peerCert = CERT_DupCertificate(sid->peerCert);
+ }
+
+ SSL_AtomicIncrementLong(&ssl3stats->hsh_sid_cache_hits);
+ SSL_AtomicIncrementLong(&ssl3stats->hsh_sid_stateless_resumes);
+ } else {
+ /* !PSK */
+ if (ssl3_ClientExtensionAdvertised(ss, ssl_tls13_pre_shared_key_xtn)) {
+ SSL_AtomicIncrementLong(&ssl3stats->hsh_sid_cache_misses);
+ }
+ if (sid->cached == in_client_cache) {
+ /* If we tried to resume and failed, let's not try again. */
+ ss->sec.uncache(sid);
+ }
+ }
+
+ if (!ss->ssl3.hs.currentSecret) {
+ PORT_Assert(!ss->statelessResume);
+
+ /* If we don't already have the Early Secret we need to make it
+ * now. */
+ rv = tls13_ComputeEarlySecrets(ss);
+ if (rv != SECSuccess) {
+ FATAL_ERROR(ss, SEC_ERROR_LIBRARY_FAILURE, internal_error);
+ return SECFailure;
+ }
+ }
+
+ /* Discard current SID and make a new one, though it may eventually
+ * end up looking a lot like the old one.
+ */
+ ssl_FreeSID(sid);
+ ss->sec.ci.sid = sid = ssl3_NewSessionID(ss, PR_FALSE);
+ if (sid == NULL) {
+ FATAL_ERROR(ss, PORT_GetError(), internal_error);
+ return SECFailure;
+ }
+ if (ss->statelessResume) {
+ PORT_Assert(ss->sec.peerCert);
+ sid->peerCert = CERT_DupCertificate(ss->sec.peerCert);
+ }
+ sid->version = ss->version;
+
+ rv = tls13_HandleServerKeyShare(ss);
+ if (rv != SECSuccess) {
+ return SECFailure;
+ }
+ rv = tls13_ComputeHandshakeSecrets(ss);
+ if (rv != SECSuccess) {
+ return SECFailure; /* error code is set. */
+ }
+
+ ss->ssl3.hs.shortHeaders = ssl3_ExtensionNegotiated(
+ ss, ssl_tls13_short_header_xtn);
+
+ rv = tls13_SetCipherSpec(ss, TrafficKeyHandshake,
+ CipherSpecRead, PR_FALSE);
+ if (rv != SECSuccess) {
+ FATAL_ERROR(ss, SSL_ERROR_INIT_CIPHER_SUITE_FAILURE, internal_error);
+ return SECFailure;
+ }
+ TLS13_SET_HS_STATE(ss, wait_encrypted_extensions);
+
+ return SECSuccess;
+}
+
+static void
+tls13_SetKeyExchangeType(sslSocket *ss, const sslNamedGroupDef *group)
+{
+ ss->sec.keaGroup = group;
+ switch (group->keaType) {
+ /* Note: These overwrite on resumption.... so if you start with ECDH
+ * and resume with DH, we report DH. That's fine, since no answer
+ * is really right. */
+ case ssl_kea_ecdh:
+ ss->ssl3.hs.kea_def_mutable.exchKeyType =
+ ss->statelessResume ? ssl_kea_ecdh_psk : ssl_kea_ecdh;
+ ss->sec.keaType = ssl_kea_ecdh;
+ break;
+ case ssl_kea_dh:
+ ss->ssl3.hs.kea_def_mutable.exchKeyType =
+ ss->statelessResume ? ssl_kea_dh_psk : ssl_kea_dh;
+ ss->sec.keaType = ssl_kea_dh;
+ break;
+ default:
+ PORT_Assert(0);
+ }
+}
+
+/*
+ * Called from ssl3_HandleServerHello.
+ *
+ * Caller must hold Handshake and RecvBuf locks.
+ */
+static SECStatus
+tls13_HandleServerKeyShare(sslSocket *ss)
+{
+ SECStatus rv;
+ TLS13KeyShareEntry *entry;
+ sslEphemeralKeyPair *keyPair;
+
+ SSL_TRC(3, ("%d: TLS13[%d]: handle server_key_share handshake",
+ SSL_GETPID(), ss->fd));
+ PORT_Assert(ss->opt.noLocks || ssl_HaveRecvBufLock(ss));
+ PORT_Assert(ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss));
+
+ /* This list should have one entry. */
+ if (PR_CLIST_IS_EMPTY(&ss->xtnData.remoteKeyShares)) {
+ FATAL_ERROR(ss, SSL_ERROR_MISSING_KEY_SHARE, missing_extension);
+ return SECFailure;
+ }
+
+ entry = (TLS13KeyShareEntry *)PR_NEXT_LINK(&ss->xtnData.remoteKeyShares);
+ PORT_Assert(PR_NEXT_LINK(&entry->link) == &ss->xtnData.remoteKeyShares);
+
+ /* Now get our matching key. */
+ keyPair = ssl_LookupEphemeralKeyPair(ss, entry->group);
+ if (!keyPair) {
+ FATAL_ERROR(ss, SSL_ERROR_RX_MALFORMED_KEY_SHARE, illegal_parameter);
+ return SECFailure;
+ }
+
+ PORT_Assert(ssl_NamedGroupEnabled(ss, entry->group));
+
+ rv = tls13_HandleKeyShare(ss, entry, keyPair->keys);
+ if (rv != SECSuccess)
+ return SECFailure; /* Error code set by caller. */
+
+ tls13_SetKeyExchangeType(ss, entry->group);
+ ss->sec.keaKeyBits = SECKEY_PublicKeyStrengthInBits(keyPair->keys->pubKey);
+
+ return SECSuccess;
+}
+
+/*
+ * opaque ASN1Cert<1..2^24-1>;
+ *
+ * struct {
+ * ASN1Cert cert_data;
+ * Extension extensions<0..2^16-1>;
+ * } CertificateEntry;
+ *
+ * struct {
+ * opaque certificate_request_context<0..2^8-1>;
+ * CertificateEntry certificate_list<0..2^24-1>;
+ * } Certificate;
+ */
+static SECStatus
+tls13_SendCertificate(sslSocket *ss)
+{
+ SECStatus rv;
+ CERTCertificateList *certChain;
+ int certChainLen = 0;
+ int i;
+ SECItem context = { siBuffer, NULL, 0 };
+ PRInt32 extensionsLen = 0;
+ PRUint32 maxBytes = 65535;
+
+ SSL_TRC(3, ("%d: TLS1.3[%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.isServer) {
+ PORT_Assert(!ss->sec.localCert);
+ /* A server certificate is selected in tls13_SelectServerCert(). */
+ PORT_Assert(ss->sec.serverCert);
+
+ certChain = ss->sec.serverCert->serverCertChain;
+ ss->sec.localCert = CERT_DupCertificate(ss->sec.serverCert->serverCert);
+ } else {
+ if (ss->sec.localCert)
+ CERT_DestroyCertificate(ss->sec.localCert);
+
+ certChain = ss->ssl3.clientCertChain;
+ ss->sec.localCert = CERT_DupCertificate(ss->ssl3.clientCertificate);
+ }
+
+ /* Get the extensions length. This only applies to the leaf cert,
+ * because we don't yet send extensions for non-leaf certs. */
+ extensionsLen = ssl3_CallHelloExtensionSenders(
+ ss, PR_FALSE, maxBytes, &ss->xtnData.certificateSenders[0]);
+
+ if (!ss->sec.isServer) {
+ PORT_Assert(ss->ssl3.hs.certificateRequest);
+ context = ss->ssl3.hs.certificateRequest->context;
+ }
+ if (certChain) {
+ for (i = 0; i < certChain->len; i++) {
+ certChainLen +=
+ 3 + certChain->certs[i].len + /* cert length + cert */
+ 2 + (!i ? extensionsLen : 0); /* extensions length + extensions */
+ }
+ }
+
+ rv = ssl3_AppendHandshakeHeader(ss, certificate,
+ 1 + context.len +
+ 3 + certChainLen);
+ if (rv != SECSuccess) {
+ return SECFailure; /* err set by AppendHandshake. */
+ }
+
+ rv = ssl3_AppendHandshakeVariable(ss, context.data,
+ context.len, 1);
+ if (rv != SECSuccess) {
+ return SECFailure; /* err set by AppendHandshake. */
+ }
+
+ rv = ssl3_AppendHandshakeNumber(ss, certChainLen, 3);
+ if (rv != SECSuccess) {
+ return SECFailure; /* err set by AppendHandshake. */
+ }
+ if (certChain) {
+ for (i = 0; i < certChain->len; i++) {
+ PRInt32 sentLen;
+
+ rv = ssl3_AppendHandshakeVariable(ss, certChain->certs[i].data,
+ certChain->certs[i].len, 3);
+ if (rv != SECSuccess) {
+ return SECFailure; /* err set by AppendHandshake. */
+ }
+
+ if (i) {
+ /* Not end-entity. */
+ rv = ssl3_AppendHandshakeNumber(ss, 0, 2);
+ if (rv != SECSuccess) {
+ return SECFailure; /* err set by AppendHandshake. */
+ }
+ continue;
+ }
+
+ /* End-entity, send extensions. */
+ rv = ssl3_AppendHandshakeNumber(ss, extensionsLen, 2);
+ if (rv != SECSuccess) {
+ return SECFailure; /* err set by AppendHandshake. */
+ }
+
+ sentLen = ssl3_CallHelloExtensionSenders(
+ ss, PR_TRUE, extensionsLen,
+ &ss->xtnData.certificateSenders[0]);
+ PORT_Assert(sentLen == extensionsLen);
+ if (sentLen != extensionsLen) {
+ LOG_ERROR(ss, SEC_ERROR_LIBRARY_FAILURE);
+ return SECFailure;
+ }
+ }
+ }
+
+ return SECSuccess;
+}
+
+static SECStatus
+tls13_HandleCertificateEntry(sslSocket *ss, SECItem *data, PRBool first,
+ CERTCertificate **certp)
+{
+ SECStatus rv;
+ SECItem certData;
+ SECItem extensionsData;
+ CERTCertificate *cert = NULL;
+
+ rv = ssl3_ConsumeHandshakeVariable(ss, &certData,
+ 3, &data->data, &data->len);
+ if (rv != SECSuccess) {
+ return SECFailure;
+ }
+
+ rv = ssl3_ConsumeHandshakeVariable(ss, &extensionsData,
+ 2, &data->data, &data->len);
+ if (rv != SECSuccess) {
+ return SECFailure;
+ }
+
+ /* Parse all the extensions. */
+ if (first && !ss->sec.isServer) {
+ rv = ssl3_HandleExtensions(ss, &extensionsData.data,
+ &extensionsData.len,
+ certificate);
+ if (rv != SECSuccess) {
+ return SECFailure;
+ }
+
+ /* TODO(ekr@rtfm.com): Copy out SCTs. Bug 1315727. */
+ }
+
+ cert = CERT_NewTempCertificate(ss->dbHandle, &certData, NULL,
+ PR_FALSE, PR_TRUE);
+
+ if (!cert) {
+ PRErrorCode errCode = PORT_GetError();
+ switch (errCode) {
+ case PR_OUT_OF_MEMORY_ERROR:
+ case SEC_ERROR_BAD_DATABASE:
+ case SEC_ERROR_NO_MEMORY:
+ FATAL_ERROR(ss, errCode, internal_error);
+ return SECFailure;
+ default:
+ ssl3_SendAlertForCertError(ss, errCode);
+ return SECFailure;
+ }
+ }
+
+ *certp = cert;
+
+ return SECSuccess;
+}
+
+/* Called from tls13_CompleteHandleHandshakeMessage() when it has deciphered a complete
+ * tls13 Certificate message.
+ * Caller must hold Handshake and RecvBuf locks.
+ */
+static SECStatus
+tls13_HandleCertificate(sslSocket *ss, SSL3Opaque *b, PRUint32 length)
+{
+ SECStatus rv;
+ SECItem context = { siBuffer, NULL, 0 };
+ SECItem certList;
+ PRBool first = PR_TRUE;
+ ssl3CertNode *lastCert = NULL;
+
+ SSL_TRC(3, ("%d: TLS13[%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->sec.isServer) {
+ rv = TLS13_CHECK_HS_STATE(ss, SSL_ERROR_RX_UNEXPECTED_CERTIFICATE,
+ wait_client_cert);
+ } else {
+ rv = TLS13_CHECK_HS_STATE(ss, SSL_ERROR_RX_UNEXPECTED_CERTIFICATE,
+ wait_cert_request, wait_server_cert);
+ }
+ if (rv != SECSuccess)
+ return SECFailure;
+
+ /* Process the context string */
+ rv = ssl3_ConsumeHandshakeVariable(ss, &context, 1, &b, &length);
+ if (rv != SECSuccess)
+ return SECFailure;
+
+ if (context.len) {
+ /* The context string MUST be empty */
+ FATAL_ERROR(ss, SSL_ERROR_RX_MALFORMED_CERTIFICATE, illegal_parameter);
+ return SECFailure;
+ }
+
+ rv = ssl3_ConsumeHandshakeVariable(ss, &certList, 3, &b, &length);
+ if (rv != SECSuccess) {
+ return SECFailure;
+ }
+ if (length) {
+ FATAL_ERROR(ss, SSL_ERROR_RX_MALFORMED_CERTIFICATE, illegal_parameter);
+ return SECFailure;
+ }
+
+ if (!certList.len) {
+ if (!ss->sec.isServer) {
+ /* Servers always need to send some cert. */
+ FATAL_ERROR(ss, SSL_ERROR_RX_MALFORMED_CERTIFICATE, bad_certificate);
+ return SECFailure;
+ } else {
+ /* 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) {
+ return SECFailure;
+ }
+
+ TLS13_SET_HS_STATE(ss, wait_finished);
+ return SECSuccess;
+ }
+ }
+
+ /* Now clean up. */
+ ssl3_CleanupPeerCerts(ss);
+ ss->ssl3.peerCertArena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
+ if (ss->ssl3.peerCertArena == NULL) {
+ FATAL_ERROR(ss, SEC_ERROR_NO_MEMORY, internal_error);
+ return SECFailure;
+ }
+
+ while (certList.len) {
+ CERTCertificate *cert;
+
+ rv = tls13_HandleCertificateEntry(ss, &certList, first,
+ &cert);
+ if (rv != SECSuccess) {
+ ss->xtnData.signedCertTimestamps.len = 0;
+ return SECFailure;
+ }
+
+ if (first) {
+ ss->sec.peerCert = cert;
+
+ if (ss->xtnData.signedCertTimestamps.len) {
+ sslSessionID *sid = ss->sec.ci.sid;
+ rv = SECITEM_CopyItem(NULL, &sid->u.ssl3.signedCertTimestamps,
+ &ss->xtnData.signedCertTimestamps);
+ ss->xtnData.signedCertTimestamps.len = 0;
+ if (rv != SECSuccess) {
+ FATAL_ERROR(ss, SEC_ERROR_NO_MEMORY, internal_error);
+ return SECFailure;
+ }
+ }
+ } else {
+ ssl3CertNode *c = PORT_ArenaNew(ss->ssl3.peerCertArena,
+ ssl3CertNode);
+ if (!c) {
+ FATAL_ERROR(ss, SEC_ERROR_NO_MEMORY, internal_error);
+ return SECFailure;
+ }
+ c->cert = cert;
+ c->next = NULL;
+
+ if (lastCert) {
+ lastCert->next = c;
+ } else {
+ ss->ssl3.peerCertChain = c;
+ }
+ lastCert = c;
+ }
+
+ first = PR_FALSE;
+ }
+ SECKEY_UpdateCertPQG(ss->sec.peerCert);
+
+ return ssl3_AuthCertificate(ss); /* sets ss->ssl3.hs.ws */
+}
+
+void
+tls13_CipherSpecAddRef(ssl3CipherSpec *spec)
+{
+ ++spec->refCt;
+ SSL_TRC(10, ("%d: TLS13[-]: Increment ref ct for spec %d. new ct = %d",
+ SSL_GETPID(), spec, spec->refCt));
+}
+
+/* This function is never called on a spec which is on the
+ * cipherSpecs list. */
+void
+tls13_CipherSpecRelease(ssl3CipherSpec *spec)
+{
+ PORT_Assert(spec->refCt > 0);
+ --spec->refCt;
+ SSL_TRC(10, ("%d: TLS13[-]: decrement refct for spec %d. phase=%s new ct = %d",
+ SSL_GETPID(), spec, spec->phase, spec->refCt));
+ if (!spec->refCt) {
+ SSL_TRC(10, ("%d: TLS13[-]: Freeing spec %d. phase=%s",
+ SSL_GETPID(), spec, spec->phase));
+ PR_REMOVE_LINK(&spec->link);
+ ssl3_DestroyCipherSpec(spec, PR_TRUE);
+ PORT_Free(spec);
+ }
+}
+
+/* Add context to the hash functions as described in
+ [draft-ietf-tls-tls13; Section 4.9.1] */
+SECStatus
+tls13_AddContextToHashes(sslSocket *ss, const SSL3Hashes *hashes,
+ SSLHashType algorithm, PRBool sending,
+ SSL3Hashes *tbsHash)
+{
+ SECStatus rv = SECSuccess;
+ PK11Context *ctx;
+ const unsigned char context_padding[] = {
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+ };
+
+ const char *client_cert_verify_string = "TLS 1.3, client CertificateVerify";
+ const char *server_cert_verify_string = "TLS 1.3, server CertificateVerify";
+ const char *context_string = (sending ^ ss->sec.isServer) ? client_cert_verify_string
+ : server_cert_verify_string;
+ unsigned int hashlength;
+
+ /* Double check that we are doing the same hash.*/
+ PORT_Assert(hashes->len == tls13_GetHashSize(ss));
+
+ ctx = PK11_CreateDigestContext(ssl3_HashTypeToOID(algorithm));
+ if (!ctx) {
+ PORT_SetError(SEC_ERROR_NO_MEMORY);
+ goto loser;
+ }
+
+ PORT_Assert(SECFailure);
+ PORT_Assert(!SECSuccess);
+
+ PRINT_BUF(50, (ss, "TLS 1.3 hash without context", hashes->u.raw, hashes->len));
+ PRINT_BUF(50, (ss, "Context string", context_string, strlen(context_string)));
+ rv |= PK11_DigestBegin(ctx);
+ rv |= PK11_DigestOp(ctx, context_padding, sizeof(context_padding));
+ rv |= PK11_DigestOp(ctx, (unsigned char *)context_string,
+ strlen(context_string) + 1); /* +1 includes the terminating 0 */
+ rv |= PK11_DigestOp(ctx, hashes->u.raw, hashes->len);
+ /* Update the hash in-place */
+ rv |= PK11_DigestFinal(ctx, tbsHash->u.raw, &hashlength, sizeof(tbsHash->u.raw));
+ PK11_DestroyContext(ctx, PR_TRUE);
+ PRINT_BUF(50, (ss, "TLS 1.3 hash with context", tbsHash->u.raw, hashlength));
+
+ tbsHash->len = hashlength;
+ tbsHash->hashAlg = algorithm;
+
+ if (rv) {
+ ssl_MapLowLevelError(SSL_ERROR_SHA_DIGEST_FAILURE);
+ goto loser;
+ }
+ return SECSuccess;
+
+loser:
+ return SECFailure;
+}
+
+/*
+ * Derive-Secret(Secret, Label, Messages) =
+ * HKDF-Expand-Label(Secret, Label,
+ * Hash(Messages) + Hash(resumption_context), L))
+ */
+static SECStatus
+tls13_DeriveSecret(sslSocket *ss, PK11SymKey *key,
+ const char *prefix,
+ const char *suffix,
+ const SSL3Hashes *hashes,
+ PK11SymKey **dest)
+{
+ SECStatus rv;
+ SSL3Hashes hashesTmp;
+ char buf[100];
+ const char *label;
+
+ if (prefix) {
+ if ((strlen(prefix) + strlen(suffix) + 2) > sizeof(buf)) {
+ PORT_Assert(0);
+ PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
+ return SECFailure;
+ }
+ (void)PR_snprintf(buf, sizeof(buf), "%s %s",
+ prefix, suffix);
+ label = buf;
+ } else {
+ label = suffix;
+ }
+
+ SSL_TRC(3, ("%d: TLS13[%d]: deriving secret '%s'",
+ SSL_GETPID(), ss->fd, label));
+ if (!hashes) {
+ rv = tls13_ComputeHandshakeHashes(ss, &hashesTmp);
+ if (rv != SECSuccess) {
+ PORT_Assert(0); /* Should never fail */
+ ssl_MapLowLevelError(SEC_ERROR_LIBRARY_FAILURE);
+ return SECFailure;
+ }
+ hashes = &hashesTmp;
+ }
+
+ rv = tls13_HkdfExpandLabel(key, tls13_GetHash(ss),
+ hashes->u.raw, hashes->len,
+ label, strlen(label),
+ tls13_GetHkdfMechanism(ss),
+ tls13_GetHashSize(ss), dest);
+ if (rv != SECSuccess) {
+ LOG_ERROR(ss, SEC_ERROR_LIBRARY_FAILURE);
+ return SECFailure;
+ }
+ return SECSuccess;
+}
+
+/* Derive traffic keys for the next cipher spec in the queue. */
+static SECStatus
+tls13_DeriveTrafficKeys(sslSocket *ss, ssl3CipherSpec *spec,
+ TrafficKeyType type,
+ CipherSpecDirection direction,
+ PRBool deleteSecret)
+{
+ size_t keySize = spec->cipher_def->key_size;
+ size_t ivSize = spec->cipher_def->iv_size +
+ spec->cipher_def->explicit_nonce_size; /* This isn't always going to
+ * work, but it does for
+ * AES-GCM */
+ CK_MECHANISM_TYPE bulkAlgorithm = ssl3_Alg2Mech(spec->cipher_def->calg);
+ PK11SymKey **prkp = NULL;
+ PK11SymKey *prk = NULL;
+ PRBool clientKey;
+ ssl3KeyMaterial *target;
+ const char *phase;
+ SECStatus rv;
+ /* These labels are just used for debugging. */
+ static const char kHkdfPhaseEarlyApplicationDataKeys[] = "early application data";
+ static const char kHkdfPhaseHandshakeKeys[] = "handshake data";
+ static const char kHkdfPhaseApplicationDataKeys[] = "application data";
+
+ if (ss->sec.isServer ^ (direction == CipherSpecWrite)) {
+ clientKey = PR_TRUE;
+ target = &spec->client;
+ } else {
+ clientKey = PR_FALSE;
+ target = &spec->server;
+ }
+
+ PORT_Assert(ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss));
+
+ switch (type) {
+ case TrafficKeyEarlyApplicationData:
+ PORT_Assert(clientKey);
+ phase = kHkdfPhaseEarlyApplicationDataKeys;
+ prkp = &ss->ssl3.hs.clientEarlyTrafficSecret;
+ break;
+ case TrafficKeyHandshake:
+ phase = kHkdfPhaseHandshakeKeys;
+ prkp = clientKey ? &ss->ssl3.hs.clientHsTrafficSecret : &ss->ssl3.hs.serverHsTrafficSecret;
+ break;
+ case TrafficKeyApplicationData:
+ phase = kHkdfPhaseApplicationDataKeys;
+ prkp = clientKey ? &ss->ssl3.hs.clientTrafficSecret : &ss->ssl3.hs.serverTrafficSecret;
+ break;
+ default:
+ LOG_ERROR(ss, SEC_ERROR_LIBRARY_FAILURE);
+ PORT_Assert(0);
+ return SECFailure;
+ }
+ PORT_Assert(prkp != NULL);
+ prk = *prkp;
+
+ SSL_TRC(3, ("%d: TLS13[%d]: deriving %s traffic keys phase='%s'",
+ SSL_GETPID(), ss->fd,
+ (direction == CipherSpecWrite) ? "write" : "read", phase));
+ PORT_Assert(phase);
+ spec->phase = phase;
+
+ rv = tls13_HkdfExpandLabel(prk, tls13_GetHash(ss),
+ NULL, 0,
+ kHkdfPurposeKey, strlen(kHkdfPurposeKey),
+ bulkAlgorithm, keySize,
+ &target->write_key);
+ if (rv != SECSuccess) {
+ LOG_ERROR(ss, SEC_ERROR_LIBRARY_FAILURE);
+ PORT_Assert(0);
+ goto loser;
+ }
+
+ rv = tls13_HkdfExpandLabelRaw(prk, tls13_GetHash(ss),
+ NULL, 0,
+ kHkdfPurposeIv, strlen(kHkdfPurposeIv),
+ target->write_iv, ivSize);
+ if (rv != SECSuccess) {
+ LOG_ERROR(ss, SEC_ERROR_LIBRARY_FAILURE);
+ PORT_Assert(0);
+ goto loser;
+ }
+
+ if (deleteSecret) {
+ PK11_FreeSymKey(prk);
+ *prkp = NULL;
+ }
+ return SECSuccess;
+
+loser:
+ return SECFailure;
+}
+
+static SECStatus
+tls13_SetupPendingCipherSpec(sslSocket *ss)
+{
+ ssl3CipherSpec *pSpec;
+ ssl3CipherSuite suite = ss->ssl3.hs.cipher_suite;
+ const ssl3BulkCipherDef *bulk = ssl_GetBulkCipherDef(
+ ssl_LookupCipherSuiteDef(suite));
+
+ PORT_Assert(ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss));
+
+ ssl_GetSpecWriteLock(ss); /*******************************/
+
+ pSpec = ss->ssl3.pwSpec;
+ /* Version isn't set when we send 0-RTT data. */
+ pSpec->version = PR_MAX(SSL_LIBRARY_VERSION_TLS_1_3, ss->version);
+
+ SSL_TRC(3, ("%d: TLS13[%d]: Set Pending Cipher Suite to 0x%04x",
+ SSL_GETPID(), ss->fd, suite));
+ pSpec->cipher_def = bulk;
+
+ ssl_ReleaseSpecWriteLock(ss); /*******************************/
+ return SECSuccess;
+}
+
+/* Install a new cipher spec for this direction. */
+static SECStatus
+tls13_SetCipherSpec(sslSocket *ss, TrafficKeyType type,
+ CipherSpecDirection direction, PRBool deleteSecret)
+{
+ SECStatus rv;
+ ssl3CipherSpec *spec = NULL;
+ ssl3CipherSpec **specp = (direction == CipherSpecRead) ? &ss->ssl3.crSpec : &ss->ssl3.cwSpec;
+ /* Flush out old handshake data. */
+ ssl_GetXmitBufLock(ss);
+ rv = ssl3_FlushHandshake(ss, ssl_SEND_FLAG_FORCE_INTO_BUFFER);
+ ssl_ReleaseXmitBufLock(ss);
+ if (rv != SECSuccess) {
+ return SECFailure;
+ }
+
+ /* Create the new spec. */
+ spec = PORT_ZNew(ssl3CipherSpec);
+ if (!spec) {
+ PORT_SetError(SEC_ERROR_NO_MEMORY);
+ return SECFailure;
+ }
+ spec->refCt = 1;
+ PR_APPEND_LINK(&spec->link, &ss->ssl3.hs.cipherSpecs);
+ ss->ssl3.pwSpec = ss->ssl3.prSpec = spec;
+
+ rv = tls13_SetupPendingCipherSpec(ss);
+ if (rv != SECSuccess)
+ return SECFailure;
+
+ switch (spec->cipher_def->calg) {
+ case calg_aes_gcm:
+ spec->aead = tls13_AESGCM;
+ break;
+ case calg_chacha20:
+ spec->aead = tls13_ChaCha20Poly1305;
+ break;
+ default:
+ PORT_Assert(0);
+ return SECFailure;
+ break;
+ }
+
+ rv = tls13_DeriveTrafficKeys(ss, spec, type, direction,
+ deleteSecret);
+ if (rv != SECSuccess) {
+ return SECFailure;
+ }
+
+ /* We use the epoch for cipher suite identification, so increment
+ * it in both TLS and DTLS. */
+ if ((*specp)->epoch == PR_UINT16_MAX) {
+ return SECFailure;
+ }
+ spec->epoch = (*specp)->epoch + 1;
+
+ if (!IS_DTLS(ss)) {
+ spec->read_seq_num = spec->write_seq_num = 0;
+ } else {
+ /* The sequence number has the high 16 bits as the epoch. */
+ spec->read_seq_num = spec->write_seq_num =
+ (sslSequenceNumber)spec->epoch << 48;
+
+ dtls_InitRecvdRecords(&spec->recvdRecords);
+ }
+
+ /* Now that we've set almost everything up, finally cut over. */
+ ssl_GetSpecWriteLock(ss);
+ tls13_CipherSpecRelease(*specp); /* May delete old cipher. */
+ *specp = spec; /* Overwrite. */
+ ssl_ReleaseSpecWriteLock(ss);
+
+ SSL_TRC(3, ("%d: TLS13[%d]: %s installed key for phase='%s'.%d dir=%s",
+ SSL_GETPID(), ss->fd, SSL_ROLE(ss),
+ spec->phase, spec->epoch,
+ direction == CipherSpecRead ? "read" : "write"));
+
+ return SECSuccess;
+}
+
+static SECStatus
+tls13_ComputeHandshakeHashes(sslSocket *ss,
+ SSL3Hashes *hashes)
+{
+ SECStatus rv;
+ PK11Context *ctx = NULL;
+
+ PORT_Assert(ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss));
+ if (ss->ssl3.hs.hashType == handshake_hash_unknown) {
+ /* Backup: if we haven't done any hashing, then hash now.
+ * This happens when we are doing 0-RTT on the client. */
+ ctx = PK11_CreateDigestContext(ssl3_HashTypeToOID(tls13_GetHash(ss)));
+ if (!ctx) {
+ ssl_MapLowLevelError(SSL_ERROR_SHA_DIGEST_FAILURE);
+ return SECFailure;
+ }
+
+ if (PK11_DigestBegin(ctx) != SECSuccess) {
+ ssl_MapLowLevelError(SSL_ERROR_SHA_DIGEST_FAILURE);
+ goto loser;
+ }
+
+ PRINT_BUF(10, (NULL, "Handshake hash computed over saved messages",
+ ss->ssl3.hs.messages.buf,
+ ss->ssl3.hs.messages.len));
+
+ if (PK11_DigestOp(ctx,
+ ss->ssl3.hs.messages.buf,
+ ss->ssl3.hs.messages.len) != SECSuccess) {
+ ssl_MapLowLevelError(SSL_ERROR_SHA_DIGEST_FAILURE);
+ goto loser;
+ }
+ } else {
+ ctx = PK11_CloneContext(ss->ssl3.hs.sha);
+ if (!ctx) {
+ ssl_MapLowLevelError(SSL_ERROR_SHA_DIGEST_FAILURE);
+ return SECFailure;
+ }
+ }
+
+ rv = PK11_DigestFinal(ctx, hashes->u.raw,
+ &hashes->len,
+ sizeof(hashes->u.raw));
+ if (rv != SECSuccess) {
+ ssl_MapLowLevelError(SSL_ERROR_DIGEST_FAILURE);
+ goto loser;
+ }
+ PORT_Assert(hashes->len == tls13_GetHashSize(ss));
+ PK11_DestroyContext(ctx, PR_TRUE);
+
+ return SECSuccess;
+
+loser:
+ PK11_DestroyContext(ctx, PR_TRUE);
+ return SECFailure;
+}
+
+void
+tls13_DestroyKeyShareEntry(TLS13KeyShareEntry *offer)
+{
+ SECITEM_ZfreeItem(&offer->key_exchange, PR_FALSE);
+ PORT_ZFree(offer, sizeof(*offer));
+}
+
+void
+tls13_DestroyKeyShares(PRCList *list)
+{
+ PRCList *cur_p;
+
+ while (!PR_CLIST_IS_EMPTY(list)) {
+ cur_p = PR_LIST_TAIL(list);
+ PR_REMOVE_LINK(cur_p);
+ tls13_DestroyKeyShareEntry((TLS13KeyShareEntry *)cur_p);
+ }
+}
+
+void
+tls13_DestroyEarlyData(PRCList *list)
+{
+ PRCList *cur_p;
+
+ while (!PR_CLIST_IS_EMPTY(list)) {
+ TLS13EarlyData *msg;
+
+ cur_p = PR_LIST_TAIL(list);
+ msg = (TLS13EarlyData *)cur_p;
+
+ PR_REMOVE_LINK(cur_p);
+ SECITEM_ZfreeItem(&msg->data, PR_FALSE);
+ PORT_ZFree(msg, sizeof(*msg));
+ }
+}
+
+void
+tls13_DestroyCipherSpecs(PRCList *list)
+{
+ PRCList *cur_p;
+
+ while (!PR_CLIST_IS_EMPTY(list)) {
+ cur_p = PR_LIST_TAIL(list);
+ PR_REMOVE_LINK(cur_p);
+ ssl3_DestroyCipherSpec((ssl3CipherSpec *)cur_p, PR_FALSE);
+ PORT_Free(cur_p);
+ }
+}
+
+/* draft-ietf-tls-tls13 Section 5.2.2 specifies the following
+ * nonce algorithm:
+ *
+ * The length of the per-record nonce (iv_length) is set to max(8 bytes,
+ * N_MIN) for the AEAD algorithm (see [RFC5116] Section 4). An AEAD
+ * algorithm where N_MAX is less than 8 bytes MUST NOT be used with TLS.
+ * The per-record nonce for the AEAD construction is formed as follows:
+ *
+ * 1. The 64-bit record sequence number is padded to the left with
+ * zeroes to iv_length.
+ *
+ * 2. The padded sequence number is XORed with the static
+ * client_write_iv or server_write_iv, depending on the role.
+ *
+ * The resulting quantity (of length iv_length) is used as the per-
+ * record nonce.
+ *
+ * Existing suites have the same nonce size: N_MIN = N_MAX = 12 bytes
+ *
+ * See RFC 5288 and https://tools.ietf.org/html/draft-ietf-tls-chacha20-poly1305-04#section-2
+ */
+static void
+tls13_WriteNonce(ssl3KeyMaterial *keys,
+ const unsigned char *seqNumBuf, unsigned int seqNumLen,
+ unsigned char *nonce, unsigned int nonceLen)
+{
+ size_t i;
+
+ PORT_Assert(nonceLen == 12);
+ memcpy(nonce, keys->write_iv, 12);
+
+ /* XOR the last 8 bytes of the IV with the sequence number. */
+ PORT_Assert(seqNumLen == 8);
+ for (i = 0; i < 8; ++i) {
+ nonce[4 + i] ^= seqNumBuf[i];
+ }
+}
+
+/* Implement the SSLAEADCipher interface defined in sslimpl.h.
+ *
+ * That interface takes the additional data (see below) and reinterprets that as
+ * a sequence number. In TLS 1.3 there is no additional data so this value is
+ * just the encoded sequence number.
+ */
+static SECStatus
+tls13_AEAD(ssl3KeyMaterial *keys, PRBool doDecrypt,
+ unsigned char *out, int *outlen, int maxout,
+ const unsigned char *in, int inlen,
+ CK_MECHANISM_TYPE mechanism,
+ unsigned char *aeadParams, unsigned int aeadParamLength)
+{
+ SECStatus rv;
+ unsigned int uOutLen = 0;
+ SECItem param = {
+ siBuffer, aeadParams, aeadParamLength
+ };
+
+ if (doDecrypt) {
+ rv = PK11_Decrypt(keys->write_key, mechanism, &param,
+ out, &uOutLen, maxout, in, inlen);
+ } else {
+ rv = PK11_Encrypt(keys->write_key, mechanism, &param,
+ out, &uOutLen, maxout, in, inlen);
+ }
+ *outlen = (int)uOutLen;
+
+ return rv;
+}
+
+static SECStatus
+tls13_AESGCM(ssl3KeyMaterial *keys,
+ PRBool doDecrypt,
+ unsigned char *out,
+ int *outlen,
+ int maxout,
+ const unsigned char *in,
+ int inlen,
+ const unsigned char *additionalData,
+ int additionalDataLen)
+{
+ CK_GCM_PARAMS gcmParams;
+ unsigned char nonce[12];
+
+ memset(&gcmParams, 0, sizeof(gcmParams));
+ gcmParams.pIv = nonce;
+ gcmParams.ulIvLen = sizeof(nonce);
+ gcmParams.pAAD = NULL;
+ gcmParams.ulAADLen = 0;
+ gcmParams.ulTagBits = 128; /* GCM measures tag length in bits. */
+
+ tls13_WriteNonce(keys, additionalData, additionalDataLen,
+ nonce, sizeof(nonce));
+ return tls13_AEAD(keys, doDecrypt, out, outlen, maxout, in, inlen,
+ CKM_AES_GCM,
+ (unsigned char *)&gcmParams, sizeof(gcmParams));
+}
+
+static SECStatus
+tls13_ChaCha20Poly1305(ssl3KeyMaterial *keys, PRBool doDecrypt,
+ unsigned char *out, int *outlen, int maxout,
+ const unsigned char *in, int inlen,
+ const unsigned char *additionalData,
+ int additionalDataLen)
+{
+ CK_NSS_AEAD_PARAMS aeadParams;
+ unsigned char nonce[12];
+
+ memset(&aeadParams, 0, sizeof(aeadParams));
+ aeadParams.pNonce = nonce;
+ aeadParams.ulNonceLen = sizeof(nonce);
+ aeadParams.pAAD = NULL; /* No AAD in TLS 1.3. */
+ aeadParams.ulAADLen = 0;
+ aeadParams.ulTagLen = 16; /* The Poly1305 tag is 16 octets. */
+
+ tls13_WriteNonce(keys, additionalData, additionalDataLen,
+ nonce, sizeof(nonce));
+ return tls13_AEAD(keys, doDecrypt, out, outlen, maxout, in, inlen,
+ CKM_NSS_CHACHA20_POLY1305,
+ (unsigned char *)&aeadParams, sizeof(aeadParams));
+}
+
+static SECStatus
+tls13_HandleEncryptedExtensions(sslSocket *ss, SSL3Opaque *b, PRUint32 length)
+{
+ SECStatus rv;
+ PRInt32 innerLength;
+ SECItem oldNpn = { siBuffer, NULL, 0 };
+
+ PORT_Assert(ss->opt.noLocks || ssl_HaveRecvBufLock(ss));
+ PORT_Assert(ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss));
+
+ SSL_TRC(3, ("%d: TLS13[%d]: handle encrypted extensions",
+ SSL_GETPID(), ss->fd));
+
+ rv = TLS13_CHECK_HS_STATE(ss, SSL_ERROR_RX_UNEXPECTED_ENCRYPTED_EXTENSIONS,
+ wait_encrypted_extensions);
+ if (rv != SECSuccess) {
+ return SECFailure;
+ }
+
+ innerLength = ssl3_ConsumeHandshakeNumber(ss, 2, &b, &length);
+ if (innerLength < 0) {
+ return SECFailure; /* Alert already sent. */
+ }
+ if (innerLength != length) {
+ FATAL_ERROR(ss, SSL_ERROR_RX_MALFORMED_ENCRYPTED_EXTENSIONS,
+ illegal_parameter);
+ return SECFailure;
+ }
+
+ /* If we are doing 0-RTT, then we already have an NPN value. Stash
+ * it for comparison. */
+ if (ss->ssl3.hs.zeroRttState == ssl_0rtt_sent &&
+ ss->xtnData.nextProtoState == SSL_NEXT_PROTO_EARLY_VALUE) {
+ oldNpn = ss->xtnData.nextProto;
+ ss->xtnData.nextProto.data = NULL;
+ ss->xtnData.nextProtoState = SSL_NEXT_PROTO_NO_SUPPORT;
+ }
+ rv = ssl3_HandleExtensions(ss, &b, &length, encrypted_extensions);
+ if (rv != SECSuccess) {
+ return SECFailure; /* Error code set below */
+ }
+
+ /* We can only get here if we offered 0-RTT. */
+ if (ssl3_ExtensionNegotiated(ss, ssl_tls13_early_data_xtn)) {
+ PORT_Assert(ss->ssl3.hs.zeroRttState == ssl_0rtt_sent);
+ if (!ss->statelessResume) {
+ /* Illegal to accept 0-RTT without also accepting PSK. */
+ FATAL_ERROR(ss, SSL_ERROR_RX_MALFORMED_ENCRYPTED_EXTENSIONS,
+ illegal_parameter);
+ }
+ ss->ssl3.hs.zeroRttState = ssl_0rtt_accepted;
+
+ /* Check that the server negotiated the same ALPN (if any). */
+ if (SECITEM_CompareItem(&oldNpn, &ss->xtnData.nextProto)) {
+ SECITEM_FreeItem(&oldNpn, PR_FALSE);
+ FATAL_ERROR(ss, SSL_ERROR_NEXT_PROTOCOL_DATA_INVALID,
+ illegal_parameter);
+ return SECFailure;
+ }
+ /* Check that the server negotiated the same cipher suite. */
+ if (ss->ssl3.hs.cipher_suite != ss->ssl3.hs.zeroRttSuite) {
+ FATAL_ERROR(ss, SSL_ERROR_RX_MALFORMED_ENCRYPTED_EXTENSIONS,
+ illegal_parameter);
+ return SECFailure;
+ }
+ } else if (ss->ssl3.hs.zeroRttState == ssl_0rtt_sent) {
+ /* Though we sent 0-RTT, the early_data extension wasn't present so the
+ * state is unmodified; the server must have rejected 0-RTT. */
+ ss->ssl3.hs.zeroRttState = ssl_0rtt_ignored;
+ ss->ssl3.hs.zeroRttIgnore = ssl_0rtt_ignore_trial;
+ } else {
+ PORT_Assert(ss->ssl3.hs.zeroRttState == ssl_0rtt_none ||
+ (ss->ssl3.hs.helloRetry &&
+ ss->ssl3.hs.zeroRttState == ssl_0rtt_ignored));
+ }
+
+ SECITEM_FreeItem(&oldNpn, PR_FALSE);
+ if (ss->ssl3.hs.kea_def->authKeyType == ssl_auth_psk) {
+ TLS13_SET_HS_STATE(ss, wait_finished);
+ } else {
+ TLS13_SET_HS_STATE(ss, wait_cert_request);
+ }
+
+ return SECSuccess;
+}
+
+static SECStatus
+tls13_SendEncryptedExtensions(sslSocket *ss)
+{
+ SECStatus rv;
+ PRInt32 extensions_len = 0;
+ PRInt32 sent_len = 0;
+ PRUint32 maxBytes = 65535;
+
+ SSL_TRC(3, ("%d: TLS13[%d]: send encrypted extensions handshake",
+ SSL_GETPID(), ss->fd));
+
+ PORT_Assert(ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss));
+ PORT_Assert(ss->opt.noLocks || ssl_HaveXmitBufLock(ss));
+
+ extensions_len = ssl3_CallHelloExtensionSenders(
+ ss, PR_FALSE, maxBytes, &ss->xtnData.encryptedExtensionsSenders[0]);
+
+ rv = ssl3_AppendHandshakeHeader(ss, encrypted_extensions,
+ extensions_len + 2);
+ if (rv != SECSuccess) {
+ LOG_ERROR(ss, SEC_ERROR_LIBRARY_FAILURE);
+ return SECFailure;
+ }
+ rv = ssl3_AppendHandshakeNumber(ss, extensions_len, 2);
+ if (rv != SECSuccess) {
+ LOG_ERROR(ss, SEC_ERROR_LIBRARY_FAILURE);
+ return SECFailure;
+ }
+ sent_len = ssl3_CallHelloExtensionSenders(
+ ss, PR_TRUE, extensions_len,
+ &ss->xtnData.encryptedExtensionsSenders[0]);
+ PORT_Assert(sent_len == extensions_len);
+ if (sent_len != extensions_len) {
+ LOG_ERROR(ss, SEC_ERROR_LIBRARY_FAILURE);
+ PORT_Assert(sent_len == 0);
+ return SECFailure;
+ }
+
+ return SECSuccess;
+}
+
+SECStatus
+tls13_SendCertificateVerify(sslSocket *ss, SECKEYPrivateKey *privKey)
+{
+ SECStatus rv = SECFailure;
+ SECItem buf = { siBuffer, NULL, 0 };
+ unsigned int len;
+ SSLHashType hashAlg;
+ SSL3Hashes hash;
+ SSL3Hashes tbsHash; /* The hash "to be signed". */
+
+ PORT_Assert(ss->opt.noLocks || ssl_HaveXmitBufLock(ss));
+ PORT_Assert(ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss));
+
+ SSL_TRC(3, ("%d: TLS13[%d]: send certificate_verify handshake",
+ SSL_GETPID(), ss->fd));
+
+ PORT_Assert(ss->ssl3.hs.hashType == handshake_hash_single);
+ rv = tls13_ComputeHandshakeHashes(ss, &hash);
+ if (rv != SECSuccess) {
+ return SECFailure;
+ }
+
+ /* We should have picked a signature scheme when we received a
+ * CertificateRequest, or when we picked a server certificate. */
+ PORT_Assert(ss->ssl3.hs.signatureScheme != ssl_sig_none);
+ if (ss->ssl3.hs.signatureScheme == ssl_sig_none) {
+ PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
+ return SECFailure;
+ }
+ hashAlg = ssl_SignatureSchemeToHashType(ss->ssl3.hs.signatureScheme);
+ rv = tls13_AddContextToHashes(ss, &hash, hashAlg,
+ PR_TRUE, &tbsHash);
+ if (rv != SECSuccess) {
+ return SECFailure;
+ }
+
+ rv = ssl3_SignHashes(ss, &tbsHash, privKey, &buf);
+ if (rv == SECSuccess && !ss->sec.isServer) {
+ /* 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.
+ */
+ PK11SlotInfo *slot;
+ sslSessionID *sid = ss->sec.ci.sid;
+
+ slot = PK11_GetSlotFromPrivateKey(privKey);
+ 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);
+ }
+ if (rv != SECSuccess) {
+ goto done; /* err code was set by ssl3_SignHashes */
+ }
+
+ len = buf.len + 2 + 2;
+
+ rv = ssl3_AppendHandshakeHeader(ss, certificate_verify, len);
+ if (rv != SECSuccess) {
+ goto done; /* error code set by AppendHandshake */
+ }
+
+ rv = ssl3_AppendHandshakeNumber(ss, ss->ssl3.hs.signatureScheme, 2);
+ if (rv != SECSuccess) {
+ goto done; /* err set by AppendHandshakeNumber */
+ }
+
+ rv = ssl3_AppendHandshakeVariable(ss, buf.data, buf.len, 2);
+ if (rv != SECSuccess) {
+ goto done; /* error code set by AppendHandshake */
+ }
+
+done:
+ /* For parity with the allocation functions, which don't use
+ * SECITEM_AllocItem(). */
+ if (buf.data)
+ PORT_Free(buf.data);
+ return rv;
+}
+
+/* Called from tls13_CompleteHandleHandshakeMessage() when it has deciphered a complete
+ * tls13 CertificateVerify message
+ * Caller must hold Handshake and RecvBuf locks.
+ */
+SECStatus
+tls13_HandleCertificateVerify(sslSocket *ss, SSL3Opaque *b, PRUint32 length,
+ SSL3Hashes *hashes)
+{
+ SECItem signed_hash = { siBuffer, NULL, 0 };
+ SECStatus rv;
+ SSLSignatureScheme sigScheme;
+ SSLHashType hashAlg;
+ SSL3Hashes tbsHash;
+
+ SSL_TRC(3, ("%d: TLS13[%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));
+
+ rv = TLS13_CHECK_HS_STATE(ss, SSL_ERROR_RX_UNEXPECTED_CERT_VERIFY,
+ wait_cert_verify);
+ if (rv != SECSuccess) {
+ return SECFailure;
+ }
+ PORT_Assert(hashes);
+
+ rv = ssl_ConsumeSignatureScheme(ss, &b, &length, &sigScheme);
+ if (rv != SECSuccess) {
+ PORT_SetError(SSL_ERROR_RX_MALFORMED_CERT_VERIFY);
+ return SECFailure;
+ }
+
+ rv = ssl_CheckSignatureSchemeConsistency(ss, sigScheme, ss->sec.peerCert);
+ if (rv != SECSuccess) {
+ /* Error set already */
+ return SECFailure;
+ }
+ hashAlg = ssl_SignatureSchemeToHashType(sigScheme);
+
+ rv = tls13_AddContextToHashes(ss, hashes, hashAlg, PR_FALSE, &tbsHash);
+ if (rv != SECSuccess) {
+ FATAL_ERROR(ss, SSL_ERROR_DIGEST_FAILURE, internal_error);
+ return SECFailure;
+ }
+
+ rv = ssl3_ConsumeHandshakeVariable(ss, &signed_hash, 2, &b, &length);
+ if (rv != SECSuccess) {
+ PORT_SetError(SSL_ERROR_RX_MALFORMED_CERT_VERIFY);
+ return SECFailure;
+ }
+
+ if (length != 0) {
+ FATAL_ERROR(ss, SSL_ERROR_RX_MALFORMED_CERT_VERIFY, decode_error);
+ return SECFailure;
+ }
+
+ rv = ssl3_VerifySignedHashes(ss, sigScheme, &tbsHash, &signed_hash);
+ if (rv != SECSuccess) {
+ FATAL_ERROR(ss, PORT_GetError(), decrypt_error);
+ return SECFailure;
+ }
+
+ /* Set the auth type. */
+ if (!ss->sec.isServer) {
+ switch (ssl_SignatureSchemeToKeyType(sigScheme)) {
+ case rsaKey:
+ ss->sec.authType = ssl_auth_rsa_sign;
+ break;
+ case ecKey:
+ ss->sec.authType = ssl_auth_ecdsa;
+ break;
+ default:
+ PORT_Assert(PR_FALSE);
+ }
+ }
+
+ /* Request a client certificate now if one was requested. */
+ if (ss->ssl3.hs.certificateRequest) {
+ TLS13CertificateRequest *req = ss->ssl3.hs.certificateRequest;
+
+ PORT_Assert(!ss->sec.isServer);
+ rv = ssl3_CompleteHandleCertificateRequest(ss, req->signatureSchemes,
+ req->signatureSchemeCount,
+ &req->ca_list);
+ if (rv != SECSuccess) {
+ FATAL_ERROR(ss, SEC_ERROR_LIBRARY_FAILURE, internal_error);
+ return rv;
+ }
+ }
+
+ TLS13_SET_HS_STATE(ss, wait_finished);
+
+ return SECSuccess;
+}
+
+static SECStatus
+tls13_ComputePskBinderHash(sslSocket *ss, unsigned long prefixLength,
+ SSL3Hashes *hashes)
+{
+ SECStatus rv;
+
+ PORT_Assert(ss->ssl3.hs.hashType == handshake_hash_unknown);
+ PORT_Assert(ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss));
+ PORT_Assert(prefixLength <= ss->ssl3.hs.messages.len);
+
+ PRINT_BUF(10, (NULL, "Handshake hash computed over ClientHello prefix",
+ ss->ssl3.hs.messages.buf, prefixLength));
+ rv = PK11_HashBuf(ssl3_HashTypeToOID(tls13_GetHash(ss)),
+ hashes->u.raw,
+ ss->ssl3.hs.messages.buf, prefixLength);
+ if (rv != SECSuccess) {
+ ssl_MapLowLevelError(SSL_ERROR_SHA_DIGEST_FAILURE);
+ goto loser;
+ }
+ hashes->len = tls13_GetHashSize(ss);
+
+ PRINT_BUF(10, (NULL, "PSK Binder hash",
+ hashes->u.raw, hashes->len));
+
+ return SECSuccess;
+
+loser:
+ return SECFailure;
+}
+/* Compute the PSK Binder This is kind of sneaky.*/
+SECStatus
+tls13_ComputePskBinder(sslSocket *ss, PRBool sending,
+ unsigned int prefixLength,
+ PRUint8 *output, unsigned int *outputLen,
+ unsigned int maxOutputLen)
+{
+ SSL3Hashes hashes;
+ SECStatus rv;
+
+ rv = tls13_ComputePskBinderHash(ss, prefixLength, &hashes);
+ if (rv != SECSuccess)
+ return SECFailure;
+
+ return tls13_ComputeFinished(ss, ss->ssl3.hs.pskBinderKey, &hashes,
+ sending, output, outputLen, maxOutputLen);
+}
+
+static SECStatus
+tls13_ComputeFinished(sslSocket *ss, PK11SymKey *baseKey,
+ const SSL3Hashes *hashes,
+ PRBool sending, PRUint8 *output, unsigned int *outputLen,
+ unsigned int maxOutputLen)
+{
+ SECStatus rv;
+ PK11Context *hmacCtx = NULL;
+ CK_MECHANISM_TYPE macAlg = tls13_GetHmacMechanism(ss);
+ SECItem param = { siBuffer, NULL, 0 };
+ unsigned int outputLenUint;
+ const char *label = kHkdfLabelFinishedSecret;
+ PK11SymKey *secret = NULL;
+
+ PORT_Assert(baseKey);
+ SSL_TRC(3, ("%d: TLS13[%d]: %s calculate finished",
+ SSL_GETPID(), ss->fd, SSL_ROLE(ss)));
+ PRINT_BUF(50, (ss, "Handshake hash", hashes->u.raw, hashes->len));
+
+ /* Now derive the appropriate finished secret from the base secret. */
+ rv = tls13_HkdfExpandLabel(baseKey,
+ tls13_GetHash(ss),
+ NULL, 0,
+ label, strlen(label),
+ tls13_GetHmacMechanism(ss),
+ tls13_GetHashSize(ss), &secret);
+ if (rv != SECSuccess) {
+ goto abort;
+ }
+
+ PORT_Assert(hashes->len == tls13_GetHashSize(ss));
+ hmacCtx = PK11_CreateContextBySymKey(macAlg, CKA_SIGN,
+ secret, &param);
+ if (!hmacCtx) {
+ goto abort;
+ }
+
+ rv = PK11_DigestBegin(hmacCtx);
+ if (rv != SECSuccess)
+ goto abort;
+
+ rv = PK11_DigestOp(hmacCtx, hashes->u.raw, hashes->len);
+ if (rv != SECSuccess)
+ goto abort;
+
+ PORT_Assert(maxOutputLen >= tls13_GetHashSize(ss));
+ rv = PK11_DigestFinal(hmacCtx, output, &outputLenUint, maxOutputLen);
+ if (rv != SECSuccess)
+ goto abort;
+ *outputLen = outputLenUint;
+
+ PK11_FreeSymKey(secret);
+ PK11_DestroyContext(hmacCtx, PR_TRUE);
+ return SECSuccess;
+
+abort:
+ if (secret) {
+ PK11_FreeSymKey(secret);
+ }
+
+ if (hmacCtx) {
+ PK11_DestroyContext(hmacCtx, PR_TRUE);
+ }
+
+ PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
+ return SECFailure;
+}
+
+static SECStatus
+tls13_SendFinished(sslSocket *ss, PK11SymKey *baseKey)
+{
+ SECStatus rv;
+ PRUint8 finishedBuf[TLS13_MAX_FINISHED_SIZE];
+ unsigned int finishedLen;
+ SSL3Hashes hashes;
+
+ SSL_TRC(3, ("%d: TLS13[%d]: send finished handshake", SSL_GETPID(), ss->fd));
+
+ PORT_Assert(ss->opt.noLocks || ssl_HaveXmitBufLock(ss));
+ PORT_Assert(ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss));
+
+ rv = tls13_ComputeHandshakeHashes(ss, &hashes);
+ if (rv != SECSuccess) {
+ LOG_ERROR(ss, SEC_ERROR_LIBRARY_FAILURE);
+ return SECFailure;
+ }
+
+ ssl_GetSpecReadLock(ss);
+ rv = tls13_ComputeFinished(ss, baseKey, &hashes, PR_TRUE,
+ finishedBuf, &finishedLen, sizeof(finishedBuf));
+ ssl_ReleaseSpecReadLock(ss);
+ if (rv != SECSuccess) {
+ LOG_ERROR(ss, SEC_ERROR_LIBRARY_FAILURE);
+ return SECFailure;
+ }
+
+ rv = ssl3_AppendHandshakeHeader(ss, finished, finishedLen);
+ if (rv != SECSuccess) {
+ return SECFailure; /* Error code already set. */
+ }
+
+ rv = ssl3_AppendHandshake(ss, finishedBuf, finishedLen);
+ if (rv != SECSuccess) {
+ return SECFailure; /* Error code already set. */
+ }
+
+ /* TODO(ekr@rtfm.com): Record key log */
+ return SECSuccess;
+}
+
+static SECStatus
+tls13_VerifyFinished(sslSocket *ss, SSL3HandshakeType message,
+ PK11SymKey *secret,
+ SSL3Opaque *b, PRUint32 length,
+ const SSL3Hashes *hashes)
+{
+ SECStatus rv;
+ PRUint8 finishedBuf[TLS13_MAX_FINISHED_SIZE];
+ unsigned int finishedLen;
+
+ if (!hashes) {
+ FATAL_ERROR(ss, SEC_ERROR_LIBRARY_FAILURE, internal_error);
+ return SECFailure;
+ }
+
+ rv = tls13_ComputeFinished(ss, secret, hashes, PR_FALSE,
+ finishedBuf, &finishedLen, sizeof(finishedBuf));
+ if (rv != SECSuccess) {
+ FATAL_ERROR(ss, SEC_ERROR_LIBRARY_FAILURE, internal_error);
+ return SECFailure;
+ }
+
+ if (length != finishedLen) {
+#ifndef UNSAFE_FUZZER_MODE
+ FATAL_ERROR(ss, message == finished ? SSL_ERROR_RX_MALFORMED_FINISHED : SSL_ERROR_RX_MALFORMED_CLIENT_HELLO, illegal_parameter);
+ return SECFailure;
+#endif
+ }
+
+ if (NSS_SecureMemcmp(b, finishedBuf, finishedLen) != 0) {
+#ifndef UNSAFE_FUZZER_MODE
+ FATAL_ERROR(ss, SSL_ERROR_BAD_HANDSHAKE_HASH_VALUE,
+ decrypt_error);
+ return SECFailure;
+#endif
+ }
+
+ return SECSuccess;
+}
+
+static SECStatus
+tls13_ClientHandleFinished(sslSocket *ss, SSL3Opaque *b, PRUint32 length,
+ const SSL3Hashes *hashes)
+{
+ SECStatus rv;
+
+ PORT_Assert(ss->opt.noLocks || ssl_HaveRecvBufLock(ss));
+ PORT_Assert(ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss));
+
+ SSL_TRC(3, ("%d: TLS13[%d]: client handle finished handshake",
+ SSL_GETPID(), ss->fd));
+
+ rv = TLS13_CHECK_HS_STATE(ss, SSL_ERROR_RX_UNEXPECTED_FINISHED,
+ wait_finished);
+ if (rv != SECSuccess) {
+ return SECFailure;
+ }
+
+ rv = tls13_VerifyFinished(ss, finished,
+ ss->ssl3.hs.serverHsTrafficSecret,
+ b, length, hashes);
+ if (rv != SECSuccess)
+ return SECFailure;
+
+ return tls13_SendClientSecondRound(ss);
+}
+
+static SECStatus
+tls13_ServerHandleFinished(sslSocket *ss, SSL3Opaque *b, PRUint32 length,
+ const SSL3Hashes *hashes)
+{
+ SECStatus rv;
+ PK11SymKey *secret;
+
+ PORT_Assert(ss->opt.noLocks || ssl_HaveRecvBufLock(ss));
+ PORT_Assert(ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss));
+
+ SSL_TRC(3, ("%d: TLS13[%d]: server handle finished handshake",
+ SSL_GETPID(), ss->fd));
+
+ rv = TLS13_CHECK_HS_STATE(ss, SSL_ERROR_RX_UNEXPECTED_FINISHED, wait_finished);
+ if (rv != SECSuccess) {
+ return SECFailure;
+ }
+
+ if (TLS13_IN_HS_STATE(ss, wait_finished)) {
+ secret = ss->ssl3.hs.clientHsTrafficSecret;
+ } else {
+ secret = ss->ssl3.hs.clientEarlyTrafficSecret;
+ }
+
+ rv = tls13_VerifyFinished(ss, finished, secret, b, length, hashes);
+ if (rv != SECSuccess)
+ return SECFailure;
+
+ rv = tls13_SetCipherSpec(ss, TrafficKeyApplicationData,
+ CipherSpecRead, PR_TRUE);
+ if (rv != SECSuccess) {
+ FATAL_ERROR(ss, SEC_ERROR_LIBRARY_FAILURE, internal_error);
+ return SECFailure;
+ }
+
+ rv = tls13_FinishHandshake(ss);
+ if (rv != SECSuccess) {
+ return SECFailure; /* Error code and alerts handled below */
+ }
+ ssl_GetXmitBufLock(ss);
+ if (ss->opt.enableSessionTickets) {
+ rv = tls13_SendNewSessionTicket(ss);
+ if (rv != SECSuccess) {
+ ssl_ReleaseXmitBufLock(ss);
+ return SECFailure; /* Error code and alerts handled below */
+ }
+ rv = ssl3_FlushHandshake(ss, 0);
+ }
+ ssl_ReleaseXmitBufLock(ss);
+ if (rv != SECSuccess)
+ return SECFailure;
+
+ return SECSuccess;
+}
+
+static SECStatus
+tls13_FinishHandshake(sslSocket *ss)
+{
+ SECStatus rv;
+
+ PORT_Assert(ss->opt.noLocks || ssl_HaveRecvBufLock(ss));
+ PORT_Assert(ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss));
+ PORT_Assert(ss->ssl3.hs.restartTarget == NULL);
+
+ rv = tls13_ComputeFinalSecrets(ss);
+ if (rv != SECSuccess)
+ return SECFailure;
+
+ /* The first handshake is now completed. */
+ ss->handshake = NULL;
+
+ /* Don't need this. */
+ PK11_FreeSymKey(ss->ssl3.hs.clientHsTrafficSecret);
+ ss->ssl3.hs.clientHsTrafficSecret = NULL;
+ PK11_FreeSymKey(ss->ssl3.hs.serverHsTrafficSecret);
+ ss->ssl3.hs.serverHsTrafficSecret = NULL;
+
+ TLS13_SET_HS_STATE(ss, idle_handshake);
+
+ ssl_FinishHandshake(ss);
+
+ return SECSuccess;
+}
+
+/* Do the parts of sending the client's second round that require
+ * the XmitBuf lock. */
+static SECStatus
+tls13_SendClientSecondFlight(sslSocket *ss, PRBool sendClientCert,
+ SSL3AlertDescription *sendAlert)
+{
+ SECStatus rv;
+
+ PORT_Assert(ss->opt.noLocks || ssl_HaveXmitBufLock(ss));
+
+ *sendAlert = internal_error;
+
+ if (ss->ssl3.sendEmptyCert) {
+ ss->ssl3.sendEmptyCert = PR_FALSE;
+ rv = ssl3_SendEmptyCertificate(ss);
+ /* Don't send verify */
+ if (rv != SECSuccess) {
+ return SECFailure; /* error code is set. */
+ }
+ } else if (sendClientCert) {
+ rv = tls13_SendCertificate(ss);
+ if (rv != SECSuccess) {
+ return SECFailure; /* error code is set. */
+ }
+ }
+ if (ss->ssl3.hs.certificateRequest) {
+ PORT_FreeArena(ss->ssl3.hs.certificateRequest->arena, PR_FALSE);
+ ss->ssl3.hs.certificateRequest = NULL;
+ }
+
+ if (sendClientCert) {
+ rv = tls13_SendCertificateVerify(ss, ss->ssl3.clientPrivateKey);
+ SECKEY_DestroyPrivateKey(ss->ssl3.clientPrivateKey);
+ ss->ssl3.clientPrivateKey = NULL;
+ if (rv != SECSuccess) {
+ return SECFailure; /* err is set. */
+ }
+ }
+
+ rv = tls13_SendFinished(ss, ss->ssl3.hs.clientHsTrafficSecret);
+ if (rv != SECSuccess) {
+ return SECFailure; /* err code was set. */
+ }
+ rv = ssl3_FlushHandshake(ss, IS_DTLS(ss) ? ssl_SEND_FLAG_NO_RETRANSMIT : 0);
+ if (rv != SECSuccess) {
+ /* No point in sending an alert here because we're not going to
+ * be able to send it if we couldn't flush the handshake. */
+ *sendAlert = no_alert;
+ return SECFailure;
+ }
+
+ rv = dtls_StartHolddownTimer(ss);
+ if (rv != SECSuccess) {
+ return SECFailure; /* err code was set. */
+ }
+
+ return SECSuccess;
+}
+
+static SECStatus
+tls13_SendClientSecondRound(sslSocket *ss)
+{
+ SECStatus rv;
+ PRBool sendClientCert;
+ SSL3AlertDescription sendAlert = no_alert;
+
+ 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;
+
+ /* Defer client authentication sending if we are still waiting for server
+ * authentication. This avoids unnecessary disclosure of client credentials
+ * to an unauthenticated server.
+ */
+ 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) {
+ SSL_TRC(3, ("%d: TLS13[%d]: deferring ssl3_SendClientSecondRound because"
+ " certificate authentication is still pending.",
+ SSL_GETPID(), ss->fd));
+ ss->ssl3.hs.restartTarget = tls13_SendClientSecondRound;
+ return SECWouldBlock;
+ }
+
+ if (ss->ssl3.hs.zeroRttState != ssl_0rtt_none) {
+ if (ss->ssl3.hs.zeroRttState == ssl_0rtt_accepted) {
+ rv = tls13_SendEndOfEarlyData(ss);
+ if (rv != SECSuccess) {
+ return SECFailure; /* Error code already set. */
+ }
+ }
+ if (IS_DTLS(ss) && !ss->ssl3.hs.helloRetry) {
+ /* Reset the counters so that the next epoch isn't set
+ * incorrectly. */
+ tls13_SetNullCipherSpec(ss, &ss->ssl3.cwSpec);
+ }
+ }
+
+ rv = tls13_SetCipherSpec(ss, TrafficKeyHandshake,
+ CipherSpecWrite, PR_FALSE);
+ if (rv != SECSuccess) {
+ FATAL_ERROR(ss, SSL_ERROR_INIT_CIPHER_SUITE_FAILURE, internal_error);
+ return SECFailure;
+ }
+
+ rv = tls13_ComputeApplicationSecrets(ss);
+ if (rv != SECSuccess) {
+ FATAL_ERROR(ss, SEC_ERROR_LIBRARY_FAILURE, internal_error);
+ return SECFailure;
+ }
+
+ rv = tls13_SetCipherSpec(ss, TrafficKeyApplicationData,
+ CipherSpecRead, PR_FALSE);
+ if (rv != SECSuccess) {
+ FATAL_ERROR(ss, SEC_ERROR_LIBRARY_FAILURE, internal_error);
+ return SECFailure;
+ }
+
+ ssl_GetXmitBufLock(ss); /*******************************/
+ rv = tls13_SendClientSecondFlight(ss, sendClientCert, &sendAlert);
+ ssl_ReleaseXmitBufLock(ss); /*******************************/
+ if (rv != SECSuccess) {
+ if (sendAlert != no_alert) {
+ FATAL_ERROR(ss, PORT_GetError(), sendAlert);
+ } else {
+ LOG_ERROR(ss, PORT_GetError());
+ }
+ return SECFailure;
+ }
+ rv = tls13_SetCipherSpec(ss, TrafficKeyApplicationData,
+ CipherSpecWrite, PR_TRUE);
+ if (rv != SECSuccess) {
+ PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
+ return SECFailure;
+ }
+
+ /* The handshake is now finished */
+ return tls13_FinishHandshake(ss);
+}
+
+/*
+ * enum { (65535) } TicketExtensionType;
+ *
+ * struct {
+ * TicketExtensionType extension_type;
+ * opaque extension_data<0..2^16-1>;
+ * } TicketExtension;
+ *
+ * struct {
+ * uint32 ticket_lifetime;
+ * uint32 ticket_age_add;
+ * opaque ticket<1..2^16-1>;
+ * TicketExtension extensions<0..2^16-2>;
+ * } NewSessionTicket;
+ */
+
+#define MAX_EARLY_DATA_SIZE (2 << 16) /* Arbitrary limit. */
+
+SECStatus
+tls13_SendNewSessionTicket(sslSocket *ss)
+{
+ PRUint16 message_length;
+ SECItem ticket_data = { 0, NULL, 0 };
+ SECStatus rv;
+ NewSessionTicket ticket = { 0 };
+ PRUint32 max_early_data_size_len = 0;
+ ticket.flags = 0;
+ if (ss->opt.enable0RttData) {
+ ticket.flags |= ticket_allow_early_data;
+ max_early_data_size_len = 8; /* type + len + value. */
+ }
+ ticket.ticket_lifetime_hint = TLS_EX_SESS_TICKET_LIFETIME_HINT;
+
+ rv = ssl3_EncodeSessionTicket(ss, &ticket, &ticket_data);
+ if (rv != SECSuccess)
+ goto loser;
+
+ message_length =
+ 4 + /* lifetime */
+ 4 + /* ticket_age_add */
+ 2 + max_early_data_size_len + /* max_early_data_size_len */
+ 2 + /* ticket length */
+ ticket_data.len;
+
+ rv = ssl3_AppendHandshakeHeader(ss, new_session_ticket,
+ message_length);
+ if (rv != SECSuccess)
+ goto loser;
+
+ /* This is a fixed value. */
+ rv = ssl3_AppendHandshakeNumber(ss, TLS_EX_SESS_TICKET_LIFETIME_HINT, 4);
+ if (rv != SECSuccess)
+ goto loser;
+
+ /* The ticket age obfuscator. */
+ rv = PK11_GenerateRandom((PRUint8 *)&ticket.ticket_age_add,
+ sizeof(ticket.ticket_age_add));
+ if (rv != SECSuccess)
+ goto loser;
+
+ rv = ssl3_AppendHandshakeNumber(ss, ticket.ticket_age_add, 4);
+ if (rv != SECSuccess)
+ goto loser;
+
+ /* Encode the ticket. */
+ rv = ssl3_AppendHandshakeVariable(
+ ss, ticket_data.data, ticket_data.len, 2);
+ if (rv != SECSuccess)
+ goto loser;
+
+ /* Extensions. */
+ rv = ssl3_AppendHandshakeNumber(ss, max_early_data_size_len, 2);
+ if (rv != SECSuccess)
+ goto loser;
+
+ if (max_early_data_size_len) {
+ rv = ssl3_AppendHandshakeNumber(
+ ss, ssl_tls13_ticket_early_data_info_xtn, 2);
+ if (rv != SECSuccess)
+ goto loser;
+
+ /* Length */
+ rv = ssl3_AppendHandshakeNumber(ss, 4, 2);
+ if (rv != SECSuccess)
+ goto loser;
+
+ rv = ssl3_AppendHandshakeNumber(ss, MAX_EARLY_DATA_SIZE, 4);
+ if (rv != SECSuccess)
+ goto loser;
+ }
+
+ SECITEM_FreeItem(&ticket_data, PR_FALSE);
+ return SECSuccess;
+
+loser:
+ if (ticket_data.data) {
+ SECITEM_FreeItem(&ticket_data, PR_FALSE);
+ }
+ return SECFailure;
+}
+
+static SECStatus
+tls13_HandleNewSessionTicket(sslSocket *ss, SSL3Opaque *b, PRUint32 length)
+{
+ SECStatus rv;
+ PRInt32 tmp;
+ PRUint32 utmp;
+ NewSessionTicket ticket = { 0 };
+ SECItem data;
+ SECItem ticket_data;
+
+ SSL_TRC(3, ("%d: TLS13[%d]: handle new session ticket message",
+ SSL_GETPID(), ss->fd));
+
+ rv = TLS13_CHECK_HS_STATE(ss, SSL_ERROR_RX_UNEXPECTED_NEW_SESSION_TICKET,
+ idle_handshake);
+ if (rv != SECSuccess) {
+ return SECFailure;
+ }
+ if (!ss->firstHsDone || ss->sec.isServer) {
+ FATAL_ERROR(ss, SSL_ERROR_RX_UNEXPECTED_NEW_SESSION_TICKET,
+ unexpected_message);
+ return SECFailure;
+ }
+
+ ticket.received_timestamp = ssl_Time();
+ tmp = ssl3_ConsumeHandshakeNumber(ss, 4, &b, &length);
+ if (tmp < 0) {
+ FATAL_ERROR(ss, SSL_ERROR_RX_MALFORMED_NEW_SESSION_TICKET,
+ decode_error);
+ return SECFailure;
+ }
+ ticket.ticket_lifetime_hint = (PRUint32)tmp;
+ ticket.ticket.type = siBuffer;
+
+ rv = ssl3_ConsumeHandshake(ss, &utmp, sizeof(utmp),
+ &b, &length);
+ if (rv != SECSuccess) {
+ PORT_SetError(SSL_ERROR_RX_MALFORMED_NEW_SESSION_TICKET);
+ return SECFailure;
+ }
+ ticket.ticket_age_add = PR_ntohl(utmp);
+
+ /* Get the ticket value. */
+ rv = ssl3_ConsumeHandshakeVariable(ss, &ticket_data, 2, &b, &length);
+ if (rv != SECSuccess || !ticket_data.len) {
+ FATAL_ERROR(ss, SSL_ERROR_RX_MALFORMED_NEW_SESSION_TICKET,
+ decode_error);
+ return SECFailure;
+ }
+
+ /* Parse extensions. */
+ rv = ssl3_ConsumeHandshakeVariable(ss, &data, 2, &b, &length);
+ if (rv != SECSuccess) {
+ FATAL_ERROR(ss, SSL_ERROR_RX_MALFORMED_NEW_SESSION_TICKET,
+ decode_error);
+ return SECFailure;
+ }
+
+ rv = ssl3_HandleExtensions(ss, &data.data,
+ &data.len, new_session_ticket);
+ if (rv != SECSuccess) {
+ FATAL_ERROR(ss, SSL_ERROR_RX_MALFORMED_NEW_SESSION_TICKET,
+ decode_error);
+ return SECFailure;
+ }
+ if (ss->xtnData.max_early_data_size) {
+ ticket.flags |= ticket_allow_early_data;
+ ticket.max_early_data_size = ss->xtnData.max_early_data_size;
+ }
+
+ if (length != 0) {
+ FATAL_ERROR(ss, SSL_ERROR_RX_MALFORMED_NEW_SESSION_TICKET,
+ decode_error);
+ return SECFailure;
+ }
+
+ if (!ss->opt.noCache) {
+ PORT_Assert(ss->sec.ci.sid);
+ rv = SECITEM_CopyItem(NULL, &ticket.ticket, &ticket_data);
+ if (rv != SECSuccess) {
+ FATAL_ERROR(ss, SEC_ERROR_NO_MEMORY, internal_error);
+ return SECFailure;
+ }
+ PRINT_BUF(50, (ss, "Caching session ticket",
+ ticket.ticket.data,
+ ticket.ticket.len));
+
+ /* Replace a previous session ticket when
+ * we receive a second NewSessionTicket message. */
+ if (ss->sec.ci.sid->cached == in_client_cache) {
+ /* Create a new session ID. */
+ sslSessionID *sid = ssl3_NewSessionID(ss, PR_FALSE);
+ if (!sid) {
+ return SECFailure;
+ }
+
+ /* Copy over the peerCert. */
+ PORT_Assert(ss->sec.ci.sid->peerCert);
+ sid->peerCert = CERT_DupCertificate(ss->sec.ci.sid->peerCert);
+ if (!sid->peerCert) {
+ ssl_FreeSID(sid);
+ return SECFailure;
+ }
+
+ /* Destroy the old SID. */
+ ss->sec.uncache(ss->sec.ci.sid);
+ ssl_FreeSID(ss->sec.ci.sid);
+ ss->sec.ci.sid = sid;
+ }
+
+ ssl3_SetSIDSessionTicket(ss->sec.ci.sid, &ticket);
+ PORT_Assert(!ticket.ticket.data);
+
+ rv = ssl3_FillInCachedSID(ss, ss->sec.ci.sid);
+ if (rv != SECSuccess)
+ return SECFailure;
+
+ /* Cache the session. */
+ ss->sec.cache(ss->sec.ci.sid);
+ }
+
+ return SECSuccess;
+}
+
+typedef enum {
+ ExtensionNotUsed,
+ ExtensionClientOnly,
+ ExtensionSendClear,
+ ExtensionSendClearOrHrr,
+ ExtensionSendHrr,
+ ExtensionSendEncrypted,
+ ExtensionSendCertificate,
+ ExtensionNewSessionTicket
+} Tls13ExtensionStatus;
+
+static const struct {
+ PRUint16 ex_value;
+ Tls13ExtensionStatus status;
+} KnownExtensions[] = {
+ { ssl_server_name_xtn, ExtensionSendEncrypted },
+ { ssl_supported_groups_xtn, ExtensionSendEncrypted },
+ { ssl_ec_point_formats_xtn, ExtensionNotUsed },
+ { ssl_signature_algorithms_xtn, ExtensionClientOnly },
+ { ssl_use_srtp_xtn, ExtensionSendEncrypted },
+ { ssl_app_layer_protocol_xtn, ExtensionSendEncrypted },
+ { ssl_padding_xtn, ExtensionNotUsed },
+ { ssl_extended_master_secret_xtn, ExtensionNotUsed },
+ { ssl_session_ticket_xtn, ExtensionClientOnly },
+ { ssl_tls13_key_share_xtn, ExtensionSendClearOrHrr },
+ { ssl_tls13_pre_shared_key_xtn, ExtensionSendClear },
+ { ssl_tls13_early_data_xtn, ExtensionSendEncrypted },
+ { ssl_next_proto_nego_xtn, ExtensionNotUsed },
+ { ssl_renegotiation_info_xtn, ExtensionNotUsed },
+ { ssl_signed_cert_timestamp_xtn, ExtensionSendCertificate },
+ { ssl_cert_status_xtn, ExtensionSendCertificate },
+ { ssl_tls13_ticket_early_data_info_xtn, ExtensionNewSessionTicket },
+ { ssl_tls13_cookie_xtn, ExtensionSendHrr },
+ { ssl_tls13_short_header_xtn, ExtensionSendClear }
+};
+
+PRBool
+tls13_ExtensionAllowed(PRUint16 extension, SSL3HandshakeType message)
+{
+ unsigned int i;
+
+ PORT_Assert((message == client_hello) ||
+ (message == server_hello) ||
+ (message == hello_retry_request) ||
+ (message == encrypted_extensions) ||
+ (message == new_session_ticket) ||
+ (message == certificate));
+
+ for (i = 0; i < PR_ARRAY_SIZE(KnownExtensions); i++) {
+ if (KnownExtensions[i].ex_value == extension)
+ break;
+ }
+ if (i == PR_ARRAY_SIZE(KnownExtensions)) {
+ /* We have never heard of this extension which is OK
+ * in client_hello and new_session_ticket. */
+ return (message == client_hello) ||
+ (message == new_session_ticket);
+ }
+
+ switch (KnownExtensions[i].status) {
+ case ExtensionNotUsed:
+ return PR_FALSE;
+ case ExtensionClientOnly:
+ return message == client_hello;
+ case ExtensionSendClear:
+ return message == client_hello ||
+ message == server_hello;
+ case ExtensionSendClearOrHrr:
+ return message == client_hello ||
+ message == server_hello ||
+ message == hello_retry_request;
+ case ExtensionSendHrr:
+ return message == client_hello ||
+ message == hello_retry_request;
+ case ExtensionSendEncrypted:
+ return message == client_hello ||
+ message == encrypted_extensions;
+ case ExtensionNewSessionTicket:
+ return message == new_session_ticket;
+ case ExtensionSendCertificate:
+ return message == client_hello ||
+ message == certificate;
+ }
+
+ PORT_Assert(0);
+
+ /* Not reached */
+ return PR_TRUE;
+}
+
+/* TLS 1.3 doesn't actually have additional data but the aead function
+ * signature overloads additional data to carry the record sequence
+ * number and that's what we put here. The TLS 1.3 AEAD functions
+ * just use this input as the sequence number and not as additional
+ * data. */
+static void
+tls13_FormatAdditionalData(PRUint8 *aad, unsigned int length,
+ sslSequenceNumber seqNum)
+{
+ PRUint8 *ptr = aad;
+
+ PORT_Assert(length == 8);
+ ptr = ssl_EncodeUintX(seqNum, 8, ptr);
+ PORT_Assert((ptr - aad) == length);
+}
+
+SECStatus
+tls13_ProtectRecord(sslSocket *ss,
+ ssl3CipherSpec *cwSpec,
+ SSL3ContentType type,
+ const SSL3Opaque *pIn,
+ PRUint32 contentLen,
+ sslBuffer *wrBuf)
+{
+ const ssl3BulkCipherDef *cipher_def = cwSpec->cipher_def;
+ const int tagLen = cipher_def->tag_size;
+ SECStatus rv;
+
+ SSL_TRC(3, ("%d: TLS13[%d]: spec=%d (%s) protect record 0x%0llx len=%u",
+ SSL_GETPID(), ss->fd, cwSpec, cwSpec->phase,
+ cwSpec->write_seq_num, contentLen));
+
+ if (contentLen + 1 + tagLen > wrBuf->space) {
+ PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
+ return SECFailure;
+ }
+
+ /* Copy the data into the wrBuf. We're going to encrypt in-place
+ * in the AEAD branch anyway */
+ PORT_Memcpy(wrBuf->buf, pIn, contentLen);
+
+ if (cipher_def->calg == ssl_calg_null) {
+ /* Shortcut for plaintext */
+ wrBuf->len = contentLen;
+ } else {
+ PRUint8 aad[8];
+ PORT_Assert(cipher_def->type == type_aead);
+
+ /* Add the content type at the end. */
+ wrBuf->buf[contentLen] = type;
+
+ tls13_FormatAdditionalData(aad, sizeof(aad), cwSpec->write_seq_num);
+ rv = cwSpec->aead(
+ ss->sec.isServer ? &cwSpec->server : &cwSpec->client,
+ PR_FALSE, /* do encrypt */
+ wrBuf->buf, /* output */
+ (int *)&wrBuf->len, /* out len */
+ wrBuf->space, /* max out */
+ wrBuf->buf, contentLen + 1, /* input */
+ aad, sizeof(aad));
+ if (rv != SECSuccess) {
+ PORT_SetError(SSL_ERROR_ENCRYPTION_FAILURE);
+ return SECFailure;
+ }
+ }
+
+ return SECSuccess;
+}
+
+/* Unprotect a TLS 1.3 record and leave the result in plaintext.
+ *
+ * Called by ssl3_HandleRecord. Caller must hold the spec read lock.
+ * Therefore, we MUST not call SSL3_SendAlert().
+ *
+ * If SECFailure is returned, we:
+ * 1. Set |*alert| to the alert to be sent.
+ * 2. Call PORT_SetError() witn an appropriate code.
+ */
+SECStatus
+tls13_UnprotectRecord(sslSocket *ss, SSL3Ciphertext *cText, sslBuffer *plaintext,
+ SSL3AlertDescription *alert)
+{
+ ssl3CipherSpec *crSpec = ss->ssl3.crSpec;
+ const ssl3BulkCipherDef *cipher_def = crSpec->cipher_def;
+ PRUint8 aad[8];
+ SECStatus rv;
+
+ *alert = bad_record_mac; /* Default alert for most issues. */
+
+ SSL_TRC(3, ("%d: TLS13[%d]: spec=%d (%s) unprotect record 0x%0llx len=%u",
+ SSL_GETPID(), ss->fd, crSpec, crSpec->phase,
+ crSpec->read_seq_num, cText->buf->len));
+
+ /* 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 < cipher_def->tag_size) {
+ SSL_TRC(3,
+ ("%d: TLS13[%d]: record too short to contain valid AEAD data",
+ SSL_GETPID(), ss->fd));
+ PORT_SetError(SSL_ERROR_BAD_MAC_READ);
+ return SECFailure;
+ }
+
+ /* Verify that the content type is right, even though we overwrite it. */
+ if (cText->type != content_application_data) {
+ SSL_TRC(3,
+ ("%d: TLS13[%d]: record has invalid exterior content type=%d",
+ SSL_GETPID(), ss->fd, cText->type));
+ /* Do we need a better error here? */
+ PORT_SetError(SSL_ERROR_BAD_MAC_READ);
+ return SECFailure;
+ }
+
+ /* Check the version number in the record */
+ if ((IS_DTLS(ss) && cText->version != kDtlsRecordVersion) ||
+ (!IS_DTLS(ss) && cText->version != kTlsRecordVersion)) {
+ /* Do we need a better error here? */
+ SSL_TRC(3,
+ ("%d: TLS13[%d]: record has bogus version",
+ SSL_GETPID(), ss->fd));
+ return SECFailure;
+ }
+
+ /* Decrypt */
+ PORT_Assert(cipher_def->type == type_aead);
+ tls13_FormatAdditionalData(aad, sizeof(aad),
+ IS_DTLS(ss) ? cText->seq_num
+ : crSpec->read_seq_num);
+ rv = crSpec->aead(
+ ss->sec.isServer ? &crSpec->client : &crSpec->server,
+ PR_TRUE, /* do decrypt */
+ plaintext->buf, /* out */
+ (int *)&plaintext->len, /* outlen */
+ plaintext->space, /* maxout */
+ cText->buf->buf, /* in */
+ cText->buf->len, /* inlen */
+ aad, sizeof(aad));
+ if (rv != SECSuccess) {
+ SSL_TRC(3,
+ ("%d: TLS13[%d]: record has bogus MAC",
+ SSL_GETPID(), ss->fd));
+ PORT_SetError(SSL_ERROR_BAD_MAC_READ);
+ return SECFailure;
+ }
+
+ /* The record is right-padded with 0s, followed by the true
+ * content type, so read from the right until we receive a
+ * nonzero byte. */
+ while (plaintext->len > 0 && !(plaintext->buf[plaintext->len - 1])) {
+ --plaintext->len;
+ }
+
+ /* Bogus padding. */
+ if (plaintext->len < 1) {
+ SSL_TRC(3,
+ ("%d: TLS13[%d]: empty record",
+ SSL_GETPID(), ss->fd, cText->type));
+ /* It's safe to report this specifically because it happened
+ * after the MAC has been verified. */
+ PORT_SetError(SSL_ERROR_BAD_BLOCK_PADDING);
+ return SECFailure;
+ }
+
+ /* Record the type. */
+ cText->type = plaintext->buf[plaintext->len - 1];
+ --plaintext->len;
+
+ SSL_TRC(10,
+ ("%d: TLS13[%d]: %s received record of length=%d type=%d",
+ SSL_GETPID(), ss->fd, SSL_ROLE(ss),
+ plaintext->len, cText->type));
+
+ return SECSuccess;
+}
+
+/* 0-RTT is only permitted if:
+ *
+ * 1. We are doing TLS 1.3
+ * 2. This isn't a second ClientHello (in response to HelloRetryRequest)
+ * 3. The 0-RTT option is set.
+ * 4. We have a valid ticket.
+ * 5. The server is willing to accept 0-RTT.
+ * 6. We have not changed our ALPN settings to disallow the ALPN tag
+ * in the ticket.
+ *
+ * Called from tls13_ClientSendEarlyDataXtn().
+ */
+PRBool
+tls13_ClientAllow0Rtt(const sslSocket *ss, const sslSessionID *sid)
+{
+ /* We checked that the cipher suite was still allowed back in
+ * ssl3_SendClientHello. */
+ if (sid->version < SSL_LIBRARY_VERSION_TLS_1_3)
+ return PR_FALSE;
+ if (ss->ssl3.hs.helloRetry)
+ return PR_FALSE;
+ if (!ss->opt.enable0RttData)
+ return PR_FALSE;
+ if (!ss->statelessResume)
+ return PR_FALSE;
+ if ((sid->u.ssl3.locked.sessionTicket.flags & ticket_allow_early_data) == 0)
+ return PR_FALSE;
+ return tls13_AlpnTagAllowed(ss, &sid->u.ssl3.alpnSelection);
+}
+
+SECStatus
+tls13_MaybeDo0RTTHandshake(sslSocket *ss)
+{
+ SECStatus rv;
+
+ /* Don't do anything if there is no early_data xtn, which means we're
+ * not doing early data. */
+ if (!ssl3_ClientExtensionAdvertised(ss, ssl_tls13_early_data_xtn)) {
+ return SECSuccess;
+ }
+
+ ss->ssl3.hs.zeroRttState = ssl_0rtt_sent;
+ ss->ssl3.hs.zeroRttSuite = ss->ssl3.hs.cipher_suite;
+
+ SSL_TRC(3, ("%d: TLS13[%d]: in 0-RTT mode", SSL_GETPID(), ss->fd));
+
+ /* Set the ALPN data as if it was negotiated. We check in the ServerHello
+ * handler that the server negotiates the same value. */
+ if (ss->sec.ci.sid->u.ssl3.alpnSelection.len) {
+ ss->xtnData.nextProtoState = SSL_NEXT_PROTO_EARLY_VALUE;
+ rv = SECITEM_CopyItem(NULL, &ss->xtnData.nextProto,
+ &ss->sec.ci.sid->u.ssl3.alpnSelection);
+ if (rv != SECSuccess)
+ return rv;
+ }
+
+ /* Null spec... */
+ ssl_GetSpecReadLock(ss);
+ ss->ssl3.hs.nullSpec = ss->ssl3.cwSpec;
+ tls13_CipherSpecAddRef(ss->ssl3.hs.nullSpec);
+ ssl_ReleaseSpecReadLock(ss);
+
+ /* Cipher suite already set in tls13_SetupClientHello. */
+ ss->ssl3.hs.preliminaryInfo = 0; /* TODO(ekr@rtfm.com) Fill this in.
+ * bug 1281255. */
+
+ rv = tls13_DeriveSecret(ss, ss->ssl3.hs.currentSecret,
+ kHkdfLabelClient,
+ kHkdfLabelEarlyTrafficSecret,
+ NULL,
+ &ss->ssl3.hs.clientEarlyTrafficSecret);
+ if (rv != SECSuccess)
+ return SECFailure;
+
+ rv = tls13_SetCipherSpec(ss, TrafficKeyEarlyApplicationData,
+ CipherSpecWrite, PR_TRUE);
+ if (rv != SECSuccess) {
+ return rv;
+ }
+
+ return SECSuccess;
+}
+
+PRInt32
+tls13_Read0RttData(sslSocket *ss, void *buf, PRInt32 len)
+{
+ TLS13EarlyData *msg;
+
+ PORT_Assert(!PR_CLIST_IS_EMPTY(&ss->ssl3.hs.bufferedEarlyData));
+ msg = (TLS13EarlyData *)PR_NEXT_LINK(&ss->ssl3.hs.bufferedEarlyData);
+
+ PR_REMOVE_LINK(&msg->link);
+ if (msg->data.len > len) {
+ PORT_SetError(SSL_ERROR_ILLEGAL_PARAMETER_ALERT);
+ return SECFailure;
+ }
+ len = msg->data.len;
+
+ PORT_Memcpy(buf, msg->data.data, msg->data.len);
+ SECITEM_ZfreeItem(&msg->data, PR_FALSE);
+ PORT_ZFree(msg, sizeof(*msg));
+
+ return len;
+}
+
+/* 0-RTT data will be followed by a different cipher spec; this resets the
+ * current spec to the null spec so that the following state can be set as
+ * though 0-RTT didn't happen. TODO: work out if this is the best plan. */
+static void
+tls13_SetNullCipherSpec(sslSocket *ss, ssl3CipherSpec **specp)
+{
+ PORT_Assert(ss->ssl3.hs.nullSpec);
+
+ ssl_GetSpecWriteLock(ss);
+ tls13_CipherSpecRelease(*specp);
+ *specp = ss->ssl3.hs.nullSpec;
+ ssl_ReleaseSpecWriteLock(ss);
+ ss->ssl3.hs.nullSpec = NULL;
+}
+
+static SECStatus
+tls13_SendEndOfEarlyData(sslSocket *ss)
+{
+ SECStatus rv;
+
+ SSL_TRC(3, ("%d: TLS13[%d]: send end_of_early_data extension",
+ SSL_GETPID(), ss->fd));
+
+ rv = SSL3_SendAlert(ss, alert_warning, end_of_early_data);
+ if (rv != SECSuccess) {
+ FATAL_ERROR(ss, SEC_ERROR_LIBRARY_FAILURE, internal_error);
+ return SECFailure;
+ }
+
+ ss->ssl3.hs.zeroRttState = ssl_0rtt_done;
+ return SECSuccess;
+}
+
+SECStatus
+tls13_HandleEndOfEarlyData(sslSocket *ss)
+{
+ SECStatus rv;
+
+ if (ss->version < SSL_LIBRARY_VERSION_TLS_1_3 ||
+ ss->ssl3.hs.zeroRttState != ssl_0rtt_accepted) {
+ (void)SSL3_SendAlert(ss, alert_fatal, unexpected_message);
+ PORT_SetError(SSL_ERROR_END_OF_EARLY_DATA_ALERT);
+ return SECFailure;
+ }
+
+ PORT_Assert(TLS13_IN_HS_STATE(ss, ss->opt.requestCertificate ? wait_client_cert : wait_finished));
+
+ if (IS_DTLS(ss)) {
+ /* Reset the cipher spec so that the epoch counter is properly reset. */
+ tls13_SetNullCipherSpec(ss, &ss->ssl3.crSpec);
+ }
+
+ rv = tls13_SetCipherSpec(ss, TrafficKeyHandshake,
+ CipherSpecRead, PR_FALSE);
+ if (rv != SECSuccess) {
+ PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
+ return SECFailure;
+ }
+
+ ss->ssl3.hs.zeroRttState = ssl_0rtt_done;
+ return SECSuccess;
+}
+
+SECStatus
+tls13_HandleEarlyApplicationData(sslSocket *ss, sslBuffer *origBuf)
+{
+ TLS13EarlyData *ed;
+ SECItem it = { siBuffer, NULL, 0 };
+
+ PORT_Assert(ss->sec.isServer);
+ PORT_Assert(ss->ssl3.hs.zeroRttState == ssl_0rtt_accepted);
+ if (ss->ssl3.hs.zeroRttState != ssl_0rtt_accepted) {
+ /* Belt and suspenders. */
+ FATAL_ERROR(ss, SEC_ERROR_LIBRARY_FAILURE, internal_error);
+ return SECFailure;
+ }
+
+ PRINT_BUF(3, (NULL, "Received early application data",
+ origBuf->buf, origBuf->len));
+ ed = PORT_ZNew(TLS13EarlyData);
+ if (!ed) {
+ FATAL_ERROR(ss, SEC_ERROR_NO_MEMORY, internal_error);
+ return SECFailure;
+ }
+ it.data = origBuf->buf;
+ it.len = origBuf->len;
+ if (SECITEM_CopyItem(NULL, &ed->data, &it) != SECSuccess) {
+ FATAL_ERROR(ss, SEC_ERROR_NO_MEMORY, internal_error);
+ return SECFailure;
+ }
+ PR_APPEND_LINK(&ed->link, &ss->ssl3.hs.bufferedEarlyData);
+
+ origBuf->len = 0; /* So ssl3_GatherAppDataRecord will keep looping. */
+
+ return SECSuccess;
+}
+
+PRUint16
+tls13_EncodeDraftVersion(SSL3ProtocolVersion version)
+{
+#ifdef TLS_1_3_DRAFT_VERSION
+ if (version == SSL_LIBRARY_VERSION_TLS_1_3) {
+ return 0x7f00 | TLS_1_3_DRAFT_VERSION;
+ }
+#endif
+ return (PRUint16)version;
+}
+
+/* Pick the highest version we support that is also advertised. */
+SECStatus
+tls13_NegotiateVersion(sslSocket *ss, const TLSExtension *supported_versions)
+{
+ PRUint16 version;
+ /* Make a copy so we're nondestructive*/
+ SECItem data = supported_versions->data;
+ SECItem versions;
+ SECStatus rv;
+
+ rv = ssl3_ConsumeHandshakeVariable(ss, &versions, 1,
+ &data.data, &data.len);
+ if (rv != SECSuccess) {
+ return SECFailure;
+ }
+ if (data.len || !versions.len || (versions.len & 1)) {
+ FATAL_ERROR(ss, SSL_ERROR_RX_MALFORMED_CLIENT_HELLO, illegal_parameter);
+ return SECFailure;
+ }
+ for (version = ss->vrange.max; version >= ss->vrange.min; --version) {
+ PRUint16 wire = tls13_EncodeDraftVersion(version);
+ unsigned long offset;
+
+ for (offset = 0; offset < versions.len; offset += 2) {
+ PRUint16 supported =
+ (versions.data[offset] << 8) | versions.data[offset + 1];
+ if (supported == wire) {
+ ss->version = version;
+ return SECSuccess;
+ }
+ }
+ }
+
+ FATAL_ERROR(ss, SSL_ERROR_UNSUPPORTED_VERSION, protocol_version);
+ return SECFailure;
+}
diff --git a/nss/lib/ssl/tls13con.h b/nss/lib/ssl/tls13con.h
new file mode 100644
index 0000000..c39c62a
--- /dev/null
+++ b/nss/lib/ssl/tls13con.h
@@ -0,0 +1,88 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is PRIVATE to SSL.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.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 __tls13con_h_
+#define __tls13con_h_
+
+typedef enum {
+ StaticSharedSecret,
+ EphemeralSharedSecret
+} SharedSecretType;
+
+#define TLS13_MAX_FINISHED_SIZE 64
+
+SECStatus tls13_UnprotectRecord(
+ sslSocket *ss, SSL3Ciphertext *cText, sslBuffer *plaintext,
+ SSL3AlertDescription *alert);
+
+#if defined(WIN32)
+#define __func__ __FUNCTION__
+#endif
+
+void tls13_SetHsState(sslSocket *ss, SSL3WaitState ws,
+ const char *func, const char *file, int line);
+#define TLS13_SET_HS_STATE(ss, ws) \
+ tls13_SetHsState(ss, ws, __func__, __FILE__, __LINE__)
+
+/* Return PR_TRUE if the socket is in one of the given states, else return
+ * PR_FALSE. Only call the macro not the function, because the trailing
+ * wait_invalid is needed to terminate the argument list. */
+PRBool tls13_InHsState(sslSocket *ss, ...);
+#define TLS13_IN_HS_STATE(ss, ...) \
+ tls13_InHsState(ss, __VA_ARGS__, wait_invalid)
+
+SSLHashType tls13_GetHashForCipherSuite(ssl3CipherSuite suite);
+SSLHashType tls13_GetHash(const sslSocket *ss);
+unsigned int tls13_GetHashSizeForHash(SSLHashType hash);
+unsigned int tls13_GetHashSize(const sslSocket *ss);
+CK_MECHANISM_TYPE tls13_GetHkdfMechanism(sslSocket *ss);
+void tls13_FatalError(sslSocket *ss, PRErrorCode prError,
+ SSL3AlertDescription desc);
+SECStatus tls13_SetupClientHello(sslSocket *ss);
+SECStatus tls13_MaybeDo0RTTHandshake(sslSocket *ss);
+PRBool tls13_AllowPskCipher(const sslSocket *ss,
+ const ssl3CipherSuiteDef *cipher_def);
+PRBool tls13_PskSuiteEnabled(sslSocket *ss);
+SECStatus tls13_ComputePskBinder(sslSocket *ss, PRBool sending,
+ unsigned int prefixLength,
+ PRUint8 *output, unsigned int *outputLen,
+ unsigned int maxOutputLen);
+SECStatus tls13_HandleClientHelloPart2(sslSocket *ss,
+ const SECItem *suites,
+ sslSessionID *sid);
+SECStatus tls13_HandleServerHelloPart2(sslSocket *ss);
+SECStatus tls13_HandlePostHelloHandshakeMessage(sslSocket *ss, SSL3Opaque *b,
+ PRUint32 length,
+ SSL3Hashes *hashesPtr);
+SECStatus tls13_HandleHelloRetryRequest(sslSocket *ss, SSL3Opaque *b,
+ PRUint32 length);
+void tls13_DestroyKeyShareEntry(TLS13KeyShareEntry *entry);
+void tls13_DestroyKeyShares(PRCList *list);
+SECStatus tls13_CreateKeyShare(sslSocket *ss, const sslNamedGroupDef *groupDef);
+void tls13_DestroyEarlyData(PRCList *list);
+void tls13_CipherSpecAddRef(ssl3CipherSpec *spec);
+void tls13_CipherSpecRelease(ssl3CipherSpec *spec);
+void tls13_DestroyCipherSpecs(PRCList *list);
+PRBool tls13_ExtensionAllowed(PRUint16 extension, SSL3HandshakeType message);
+SECStatus tls13_ProtectRecord(sslSocket *ss,
+ ssl3CipherSpec *cwSpec,
+ SSL3ContentType type,
+ const SSL3Opaque *pIn,
+ PRUint32 contentLen,
+ sslBuffer *wrBuf);
+PRInt32 tls13_Read0RttData(sslSocket *ss, void *buf, PRInt32 len);
+SECStatus tls13_HandleEndOfEarlyData(sslSocket *ss);
+SECStatus tls13_HandleEarlyApplicationData(sslSocket *ss, sslBuffer *origBuf);
+PRBool tls13_ClientAllow0Rtt(const sslSocket *ss, const sslSessionID *sid);
+PRUint16 tls13_EncodeDraftVersion(SSL3ProtocolVersion version);
+PRUint16 tls13_DecodeDraftVersion(PRUint16 version);
+SECStatus tls13_NegotiateVersion(sslSocket *ss,
+ const TLSExtension *supported_versions);
+SECStatus tls13_SendNewSessionTicket(sslSocket *ss);
+
+#endif /* __tls13con_h_ */
diff --git a/nss/lib/ssl/tls13exthandle.c b/nss/lib/ssl/tls13exthandle.c
new file mode 100644
index 0000000..be93b97
--- /dev/null
+++ b/nss/lib/ssl/tls13exthandle.c
@@ -0,0 +1,1169 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.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 "nss.h"
+#include "ssl.h"
+#include "sslproto.h"
+#include "sslimpl.h"
+#include "pk11pub.h"
+#include "ssl3ext.h"
+#include "ssl3exthandle.h"
+#include "tls13exthandle.h"
+
+PRInt32
+tls13_ServerSendStatusRequestXtn(
+ const sslSocket *ss,
+ TLSExtensionData *xtnData,
+ PRBool append,
+ PRUint32 maxBytes)
+{
+ PRInt32 extension_length;
+ const sslServerCert *serverCert = ss->sec.serverCert;
+ const SECItem *item;
+ SECStatus rv;
+
+ if (!serverCert->certStatusArray ||
+ !serverCert->certStatusArray->len) {
+ return 0;
+ }
+
+ item = &serverCert->certStatusArray->items[0];
+
+ /* Only send the first entry. */
+ extension_length = 2 + 2 + 1 /* status_type */ + 3 + item->len;
+ if (maxBytes < (PRUint32)extension_length) {
+ return 0;
+ }
+ if (append) {
+ /* extension_type */
+ rv = ssl3_ExtAppendHandshakeNumber(ss, ssl_cert_status_xtn, 2);
+ if (rv != SECSuccess)
+ return -1;
+ /* length of extension_data */
+ rv = ssl3_ExtAppendHandshakeNumber(ss, extension_length - 4, 2);
+ if (rv != SECSuccess)
+ return -1;
+ /* status_type == ocsp */
+ rv = ssl3_ExtAppendHandshakeNumber(ss, 1 /*ocsp*/, 1);
+ if (rv != SECSuccess)
+ return rv; /* err set by AppendHandshake. */
+ /* opaque OCSPResponse<1..2^24-1> */
+ rv = ssl3_ExtAppendHandshakeVariable(ss, item->data, item->len, 3);
+ if (rv != SECSuccess)
+ return rv; /* err set by AppendHandshake. */
+ }
+
+ return extension_length;
+}
+
+/*
+ * [draft-ietf-tls-tls13-11] Section 6.3.2.3.
+ *
+ * struct {
+ * NamedGroup group;
+ * opaque key_exchange<1..2^16-1>;
+ * } KeyShareEntry;
+ *
+ * struct {
+ * select (role) {
+ * case client:
+ * KeyShareEntry client_shares<4..2^16-1>;
+ *
+ * case server:
+ * KeyShareEntry server_share;
+ * }
+ * } KeyShare;
+ *
+ * DH is Section 6.3.2.3.1.
+ *
+ * opaque dh_Y<1..2^16-1>;
+ *
+ * ECDH is Section 6.3.2.3.2.
+ *
+ * opaque point <1..2^8-1>;
+ */
+static PRUint32
+tls13_SizeOfKeyShareEntry(const SECKEYPublicKey *pubKey)
+{
+ /* Size = NamedGroup(2) + length(2) + opaque<?> share */
+ switch (pubKey->keyType) {
+ case ecKey:
+ return 2 + 2 + pubKey->u.ec.publicValue.len;
+ case dhKey:
+ return 2 + 2 + pubKey->u.dh.prime.len;
+ default:
+ PORT_Assert(0);
+ }
+ return 0;
+}
+
+static PRUint32
+tls13_SizeOfClientKeyShareExtension(const sslSocket *ss)
+{
+ PRCList *cursor;
+ /* Size is: extension(2) + extension_len(2) + client_shares(2) */
+ PRUint32 size = 2 + 2 + 2;
+ for (cursor = PR_NEXT_LINK(&ss->ephemeralKeyPairs);
+ cursor != &ss->ephemeralKeyPairs;
+ cursor = PR_NEXT_LINK(cursor)) {
+ sslEphemeralKeyPair *keyPair = (sslEphemeralKeyPair *)cursor;
+ size += tls13_SizeOfKeyShareEntry(keyPair->keys->pubKey);
+ }
+ return size;
+}
+
+static SECStatus
+tls13_EncodeKeyShareEntry(const sslSocket *ss, const sslEphemeralKeyPair *keyPair)
+{
+ SECStatus rv;
+ SECKEYPublicKey *pubKey = keyPair->keys->pubKey;
+ unsigned int size = tls13_SizeOfKeyShareEntry(pubKey);
+
+ rv = ssl3_ExtAppendHandshakeNumber(ss, keyPair->group->name, 2);
+ if (rv != SECSuccess)
+ return rv;
+ rv = ssl3_ExtAppendHandshakeNumber(ss, size - 4, 2);
+ if (rv != SECSuccess)
+ return rv;
+
+ switch (pubKey->keyType) {
+ case ecKey:
+ rv = tls13_EncodeECDHEKeyShareKEX(ss, pubKey);
+ break;
+ case dhKey:
+ rv = ssl_AppendPaddedDHKeyShare(ss, pubKey, PR_FALSE);
+ break;
+ default:
+ PORT_Assert(0);
+ PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
+ break;
+ }
+
+ return rv;
+}
+
+PRInt32
+tls13_ClientSendKeyShareXtn(const sslSocket *ss, TLSExtensionData *xtnData, PRBool append,
+ PRUint32 maxBytes)
+{
+ PRUint32 extension_length;
+
+ if (ss->vrange.max < SSL_LIBRARY_VERSION_TLS_1_3) {
+ return 0;
+ }
+
+ /* Optimistically try to send an ECDHE key using the
+ * preexisting key (in future will be keys) */
+ SSL_TRC(3, ("%d: TLS13[%d]: send client key share xtn",
+ SSL_GETPID(), ss->fd));
+
+ extension_length = tls13_SizeOfClientKeyShareExtension(ss);
+ if (maxBytes < extension_length) {
+ PORT_Assert(0);
+ return 0;
+ }
+
+ if (append) {
+ SECStatus rv;
+ PRCList *cursor;
+
+ rv = ssl3_ExtAppendHandshakeNumber(ss, ssl_tls13_key_share_xtn, 2);
+ if (rv != SECSuccess)
+ goto loser;
+
+ /* The extension length */
+ rv = ssl3_ExtAppendHandshakeNumber(ss, extension_length - 4, 2);
+ if (rv != SECSuccess)
+ goto loser;
+
+ /* The length of KeyShares */
+ rv = ssl3_ExtAppendHandshakeNumber(ss, extension_length - 6, 2);
+ if (rv != SECSuccess)
+ goto loser;
+
+ for (cursor = PR_NEXT_LINK(&ss->ephemeralKeyPairs);
+ cursor != &ss->ephemeralKeyPairs;
+ cursor = PR_NEXT_LINK(cursor)) {
+ sslEphemeralKeyPair *keyPair = (sslEphemeralKeyPair *)cursor;
+ rv = tls13_EncodeKeyShareEntry(ss, keyPair);
+ if (rv != SECSuccess)
+ goto loser;
+ }
+
+ xtnData->advertised[xtnData->numAdvertised++] =
+ ssl_tls13_key_share_xtn;
+ }
+
+ return extension_length;
+
+loser:
+ return -1;
+}
+
+static SECStatus
+tls13_HandleKeyShareEntry(const sslSocket *ss, TLSExtensionData *xtnData, SECItem *data)
+{
+ SECStatus rv;
+ PRInt32 group;
+ const sslNamedGroupDef *groupDef;
+ TLS13KeyShareEntry *ks = NULL;
+ SECItem share = { siBuffer, NULL, 0 };
+
+ group = ssl3_ExtConsumeHandshakeNumber(ss, 2, &data->data, &data->len);
+ if (group < 0) {
+ PORT_SetError(SSL_ERROR_RX_MALFORMED_KEY_SHARE);
+ goto loser;
+ }
+ groupDef = ssl_LookupNamedGroup(group);
+ rv = ssl3_ExtConsumeHandshakeVariable(ss, &share, 2, &data->data,
+ &data->len);
+ if (rv != SECSuccess) {
+ goto loser;
+ }
+ /* If the group is disabled, continue. */
+ if (!groupDef) {
+ return SECSuccess;
+ }
+
+ ks = PORT_ZNew(TLS13KeyShareEntry);
+ if (!ks)
+ goto loser;
+ ks->group = groupDef;
+
+ rv = SECITEM_CopyItem(NULL, &ks->key_exchange, &share);
+ if (rv != SECSuccess)
+ goto loser;
+
+ PR_APPEND_LINK(&ks->link, &xtnData->remoteKeyShares);
+ return SECSuccess;
+
+loser:
+ if (ks)
+ tls13_DestroyKeyShareEntry(ks);
+ return SECFailure;
+}
+/* Handle an incoming KeyShare extension at the client and copy to
+ * |xtnData->remoteKeyShares| for future use. The key
+ * share is processed in tls13_HandleServerKeyShare(). */
+SECStatus
+tls13_ClientHandleKeyShareXtn(const sslSocket *ss, TLSExtensionData *xtnData, PRUint16 ex_type, SECItem *data)
+{
+ SECStatus rv;
+ PORT_Assert(PR_CLIST_IS_EMPTY(&xtnData->remoteKeyShares));
+
+ PORT_Assert(!ss->sec.isServer);
+ if (ss->version < SSL_LIBRARY_VERSION_TLS_1_3) {
+ /* This can't happen because the extension processing
+ * code filters out TLS 1.3 extensions when not in
+ * TLS 1.3 mode. */
+ PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
+ return SECFailure;
+ }
+
+ SSL_TRC(3, ("%d: SSL3[%d]: handle key_share extension",
+ SSL_GETPID(), ss->fd));
+
+ rv = tls13_HandleKeyShareEntry(ss, xtnData, data);
+ if (rv != SECSuccess) {
+ PORT_SetError(SSL_ERROR_RX_MALFORMED_KEY_SHARE);
+ return SECFailure;
+ }
+
+ if (data->len) {
+ PORT_SetError(SSL_ERROR_RX_MALFORMED_KEY_SHARE);
+ return SECFailure;
+ }
+
+ return SECSuccess;
+}
+
+SECStatus
+tls13_ClientHandleKeyShareXtnHrr(const sslSocket *ss, TLSExtensionData *xtnData, PRUint16 ex_type, SECItem *data)
+{
+ SECStatus rv;
+ PRInt32 tmp;
+ const sslNamedGroupDef *group;
+
+ PORT_Assert(!ss->sec.isServer);
+ PORT_Assert(ss->vrange.max >= SSL_LIBRARY_VERSION_TLS_1_3);
+
+ SSL_TRC(3, ("%d: SSL3[%d]: handle key_share extension in HRR",
+ SSL_GETPID(), ss->fd));
+
+ tmp = ssl3_ExtConsumeHandshakeNumber(ss, 2, &data->data, &data->len);
+ if (tmp < 0) {
+ return SECFailure; /* error code already set */
+ }
+ if (data->len) {
+ ssl3_ExtSendAlert(ss, alert_fatal, decode_error);
+ PORT_SetError(SSL_ERROR_RX_MALFORMED_HELLO_RETRY_REQUEST);
+ return SECFailure;
+ }
+
+ group = ssl_LookupNamedGroup((SSLNamedGroup)tmp);
+ /* If the group is not enabled, or we already have a share for the
+ * requested group, abort. */
+ if (!ssl_NamedGroupEnabled(ss, group) ||
+ ssl_HaveEphemeralKeyPair(ss, group)) {
+ ssl3_ExtSendAlert(ss, alert_fatal, illegal_parameter);
+ PORT_SetError(SSL_ERROR_RX_MALFORMED_HELLO_RETRY_REQUEST);
+ return SECFailure;
+ }
+
+ /* Now delete all the key shares per [draft-ietf-tls-tls13 S 4.1.2] */
+ ssl_FreeEphemeralKeyPairs(CONST_CAST(sslSocket, ss));
+
+ /* And replace with our new share. */
+ rv = tls13_CreateKeyShare(CONST_CAST(sslSocket, ss), group);
+ if (rv != SECSuccess) {
+ ssl3_ExtSendAlert(ss, alert_fatal, internal_error);
+ PORT_SetError(SEC_ERROR_KEYGEN_FAIL);
+ return SECFailure;
+ }
+
+ return SECSuccess;
+}
+
+/* Handle an incoming KeyShare extension at the server and copy to
+ * |xtnData->remoteKeyShares| for future use. The key
+ * share is processed in tls13_HandleClientKeyShare(). */
+SECStatus
+tls13_ServerHandleKeyShareXtn(const sslSocket *ss, TLSExtensionData *xtnData, PRUint16 ex_type, SECItem *data)
+{
+ SECStatus rv;
+ PRInt32 length;
+
+ PORT_Assert(ss->sec.isServer);
+ PORT_Assert(PR_CLIST_IS_EMPTY(&xtnData->remoteKeyShares));
+
+ if (ss->version < SSL_LIBRARY_VERSION_TLS_1_3) {
+ return SECSuccess;
+ }
+
+ SSL_TRC(3, ("%d: SSL3[%d]: handle key_share extension",
+ SSL_GETPID(), ss->fd));
+
+ /* Redundant length because of TLS encoding (this vector consumes
+ * the entire extension.) */
+ length = ssl3_ExtConsumeHandshakeNumber(ss, 2, &data->data,
+ &data->len);
+ if (length < 0)
+ goto loser;
+ if (length != data->len) {
+ /* Check for consistency */
+ PORT_SetError(SSL_ERROR_RX_MALFORMED_KEY_SHARE);
+ goto loser;
+ }
+
+ while (data->len) {
+ rv = tls13_HandleKeyShareEntry(ss, xtnData, data);
+ if (rv != SECSuccess)
+ goto loser;
+ }
+
+ /* Check that the client only offered one share if this is
+ * after HRR. */
+ if (ss->ssl3.hs.helloRetry) {
+ if (PR_PREV_LINK(&xtnData->remoteKeyShares) !=
+ PR_NEXT_LINK(&xtnData->remoteKeyShares)) {
+ PORT_SetError(SSL_ERROR_RX_MALFORMED_CLIENT_HELLO);
+ goto loser;
+ }
+ }
+
+ return SECSuccess;
+
+loser:
+ tls13_DestroyKeyShares(&xtnData->remoteKeyShares);
+ return SECFailure;
+}
+
+PRInt32
+tls13_ServerSendKeyShareXtn(const sslSocket *ss, TLSExtensionData *xtnData, PRBool append,
+ PRUint32 maxBytes)
+{
+ PRUint32 extension_length;
+ PRUint32 entry_length;
+ SECStatus rv;
+ sslEphemeralKeyPair *keyPair;
+
+ /* There should be exactly one key share. */
+ PORT_Assert(!PR_CLIST_IS_EMPTY(&ss->ephemeralKeyPairs));
+ PORT_Assert(PR_PREV_LINK(&ss->ephemeralKeyPairs) ==
+ PR_NEXT_LINK(&ss->ephemeralKeyPairs));
+
+ keyPair = (sslEphemeralKeyPair *)PR_NEXT_LINK(&ss->ephemeralKeyPairs);
+
+ entry_length = tls13_SizeOfKeyShareEntry(keyPair->keys->pubKey);
+ extension_length = 2 + 2 + entry_length; /* Type + length + entry_length */
+ if (maxBytes < extension_length) {
+ PORT_Assert(0);
+ return 0;
+ }
+
+ if (append) {
+ rv = ssl3_ExtAppendHandshakeNumber(ss, ssl_tls13_key_share_xtn, 2);
+ if (rv != SECSuccess)
+ goto loser;
+
+ rv = ssl3_ExtAppendHandshakeNumber(ss, entry_length, 2);
+ if (rv != SECSuccess)
+ goto loser;
+
+ rv = tls13_EncodeKeyShareEntry(ss, keyPair);
+ if (rv != SECSuccess)
+ goto loser;
+ }
+
+ return extension_length;
+
+loser:
+ return -1;
+}
+
+/* Called by clients.
+ *
+ * struct {
+ * opaque identity<0..2^16-1>;
+ * uint32 obfuscated_ticket_age;
+ * } PskIdentity;
+ *
+ * opaque PskBinderEntry<32..255>;
+ *
+ * struct {
+ * select (Handshake.msg_type) {
+ * case client_hello:
+ * PskIdentity identities<6..2^16-1>;
+ * PskBinderEntry binders<33..2^16-1>;
+ *
+ * case server_hello:
+ * uint16 selected_identity;
+ * };
+ *
+ * } PreSharedKeyExtension;
+
+ * Presently the only way to get a PSK is by resumption, so this is
+ * really a ticket label and there will be at most one.
+ */
+PRInt32
+tls13_ClientSendPreSharedKeyXtn(const sslSocket *ss, TLSExtensionData *xtnData,
+ PRBool append,
+ PRUint32 maxBytes)
+{
+ PRInt32 extension_length;
+ PRInt32 identities_length;
+ PRInt32 binders_length;
+ NewSessionTicket *session_ticket;
+
+ /* We only set statelessResume on the client in TLS 1.3 code. */
+ if (!ss->statelessResume)
+ return 0;
+
+ PORT_Assert(ss->vrange.max >= SSL_LIBRARY_VERSION_TLS_1_3);
+
+ /* The length computations are simplified by the fact that there
+ * is just one ticket at most. */
+ session_ticket = &ss->sec.ci.sid->u.ssl3.locked.sessionTicket;
+ identities_length =
+ 2 + /* vector length */
+ 2 + session_ticket->ticket.len + /* identity length + ticket len */
+ 4; /* obfuscated_ticket_age */
+ binders_length =
+ 2 + /* vector length */
+ 1 + tls13_GetHashSizeForHash(
+ tls13_GetHashForCipherSuite(ss->sec.ci.sid->u.ssl3.cipherSuite));
+ extension_length =
+ 2 + 2 + /* Type + length */
+ identities_length + binders_length;
+
+ if (maxBytes < (PRUint32)extension_length) {
+ PORT_Assert(0);
+ return 0;
+ }
+
+ if (append) {
+ SECStatus rv;
+ PRUint32 age;
+ unsigned int prefixLength;
+ PRUint8 binder[TLS13_MAX_FINISHED_SIZE];
+ unsigned int binderLen;
+
+ /* extension_type */
+ rv = ssl3_ExtAppendHandshakeNumber(ss, ssl_tls13_pre_shared_key_xtn, 2);
+ if (rv != SECSuccess)
+ goto loser;
+ rv = ssl3_ExtAppendHandshakeNumber(ss, extension_length - 4, 2);
+ if (rv != SECSuccess)
+ goto loser;
+ rv = ssl3_ExtAppendHandshakeNumber(ss, identities_length - 2, 2);
+ if (rv != SECSuccess)
+ goto loser;
+ rv = ssl3_ExtAppendHandshakeVariable(ss, session_ticket->ticket.data,
+ session_ticket->ticket.len, 2);
+ if (rv != SECSuccess)
+ goto loser;
+
+ /* Obfuscated age. */
+ age = ssl_Time() - session_ticket->received_timestamp;
+ age += session_ticket->ticket_age_add;
+ rv = ssl3_ExtAppendHandshakeNumber(ss, age, 4);
+ if (rv != SECSuccess)
+ goto loser;
+
+ /* Now the binders. */
+ prefixLength = ss->ssl3.hs.messages.len;
+ rv = tls13_ComputePskBinder(CONST_CAST(sslSocket, ss), PR_TRUE,
+ prefixLength, binder, &binderLen,
+ sizeof(binder));
+ if (rv != SECSuccess)
+ goto loser;
+ PORT_Assert(binderLen == tls13_GetHashSize(ss));
+ rv = ssl3_ExtAppendHandshakeNumber(ss, binders_length - 2, 2);
+ if (rv != SECSuccess)
+ goto loser;
+ rv = ssl3_ExtAppendHandshakeVariable(ss,
+ binder, binderLen, 1);
+ if (rv != SECSuccess)
+ goto loser;
+
+ PRINT_BUF(50, (ss, "Sending PreSharedKey value",
+ session_ticket->ticket.data,
+ session_ticket->ticket.len));
+
+ xtnData->sentSessionTicketInClientHello = PR_TRUE;
+ xtnData->advertised[xtnData->numAdvertised++] =
+ ssl_tls13_pre_shared_key_xtn;
+ }
+ return extension_length;
+
+loser:
+ xtnData->ticketTimestampVerified = PR_FALSE;
+ return -1;
+}
+
+/* Handle a TLS 1.3 PreSharedKey Extension. We only accept PSKs
+ * that contain session tickets. */
+SECStatus
+tls13_ServerHandlePreSharedKeyXtn(const sslSocket *ss, TLSExtensionData *xtnData, PRUint16 ex_type,
+ SECItem *data)
+{
+ SECItem inner;
+ SECStatus rv;
+ unsigned int numIdentities = 0;
+ unsigned int numBinders = 0;
+
+ SSL_TRC(3, ("%d: SSL3[%d]: handle pre_shared_key extension",
+ SSL_GETPID(), ss->fd));
+
+ /* If we are doing < TLS 1.3, then ignore this. */
+ if (ss->version < SSL_LIBRARY_VERSION_TLS_1_3) {
+ return SECSuccess;
+ }
+
+ /* Parse the identities list. */
+ rv = ssl3_ExtConsumeHandshakeVariable(ss,
+ &inner, 2, &data->data, &data->len);
+ if (rv != SECSuccess) {
+ return SECFailure;
+ }
+
+ while (inner.len) {
+ SECItem label;
+ PRUint32 utmp;
+
+ rv = ssl3_ExtConsumeHandshakeVariable(ss, &label, 2,
+ &inner.data, &inner.len);
+ if (rv != SECSuccess)
+ return rv;
+ if (!label.len) {
+ goto alert_loser;
+ }
+
+ /* Read and discard session ticket age. Bug 1295163 */
+ rv = ssl3_ExtConsumeHandshake(ss, &utmp, 4,
+ &inner.data, &inner.len);
+ if (rv != SECSuccess)
+ return rv;
+
+ if (!numIdentities) {
+ PRINT_BUF(50, (ss, "Handling PreSharedKey value",
+ label.data, label.len));
+ rv = ssl3_ProcessSessionTicketCommon(
+ CONST_CAST(sslSocket, ss), &label);
+ /* This only happens if we have an internal error, not
+ * a malformed ticket. Bogus tickets just don't resume
+ * and return SECSuccess. */
+ if (rv != SECSuccess)
+ return SECFailure;
+ }
+ ++numIdentities;
+ }
+
+ xtnData->pskBinderPrefixLen = ss->ssl3.hs.messages.len - data->len;
+
+ /* Parse the binders list. */
+ rv = ssl3_ExtConsumeHandshakeVariable(ss,
+ &inner, 2, &data->data, &data->len);
+ if (rv != SECSuccess)
+ return SECFailure;
+ if (data->len) {
+ goto alert_loser;
+ }
+
+ while (inner.len) {
+ SECItem binder;
+ rv = ssl3_ExtConsumeHandshakeVariable(ss, &binder, 1,
+ &inner.data, &inner.len);
+ if (rv != SECSuccess)
+ return rv;
+ if (binder.len < 32) {
+ goto alert_loser;
+ }
+
+ if (!numBinders) {
+ xtnData->pskBinder = binder;
+ }
+ ++numBinders;
+ }
+
+ if (numBinders != numIdentities)
+ goto alert_loser;
+
+ /* Keep track of negotiated extensions. Note that this does not
+ * mean we are resuming. */
+ xtnData->negotiated[xtnData->numNegotiated++] = ex_type;
+
+ return SECSuccess;
+
+alert_loser:
+ ssl3_ExtSendAlert(ss, alert_fatal, illegal_parameter);
+ PORT_SetError(SSL_ERROR_MALFORMED_PRE_SHARED_KEY);
+ return SECFailure;
+}
+
+PRInt32
+tls13_ServerSendPreSharedKeyXtn(const sslSocket *ss, TLSExtensionData *xtnData,
+ PRBool append,
+ PRUint32 maxBytes)
+{
+ PRInt32 extension_length =
+ 2 + 2 + 2; /* type + len + index */
+ SECStatus rv;
+
+ if (maxBytes < (PRUint32)extension_length) {
+ PORT_Assert(0);
+ return 0;
+ }
+
+ if (append) {
+ rv = ssl3_ExtAppendHandshakeNumber(ss, ssl_tls13_pre_shared_key_xtn, 2);
+ if (rv != SECSuccess)
+ return -1;
+
+ rv = ssl3_ExtAppendHandshakeNumber(ss, 2, 2);
+ if (rv != SECSuccess)
+ return -1;
+
+ /* We only process the first session ticket the client sends,
+ * so the index is always 0. */
+ rv = ssl3_ExtAppendHandshakeNumber(ss, 0, 2);
+ if (rv != SECSuccess)
+ return -1;
+ }
+
+ return extension_length;
+}
+
+/* Handle a TLS 1.3 PreSharedKey Extension. We only accept PSKs
+ * that contain session tickets. */
+SECStatus
+tls13_ClientHandlePreSharedKeyXtn(const sslSocket *ss, TLSExtensionData *xtnData, PRUint16 ex_type,
+ SECItem *data)
+{
+ PRInt32 index;
+
+ SSL_TRC(3, ("%d: SSL3[%d]: handle pre_shared_key extension",
+ SSL_GETPID(), ss->fd));
+
+ /* If we are doing < TLS 1.3, then ignore this. */
+ if (ss->version < SSL_LIBRARY_VERSION_TLS_1_3) {
+ return SECSuccess;
+ }
+
+ index = ssl3_ExtConsumeHandshakeNumber(ss, 2, &data->data, &data->len);
+ if (index < 0)
+ return SECFailure;
+
+ /* This should be the end of the extension. */
+ if (data->len) {
+ PORT_SetError(SSL_ERROR_MALFORMED_PRE_SHARED_KEY);
+ return SECFailure;
+ }
+
+ /* We only sent one PSK label so index must be equal to 0 */
+ if (index) {
+ PORT_SetError(SSL_ERROR_MALFORMED_PRE_SHARED_KEY);
+ return SECFailure;
+ }
+
+ /* Keep track of negotiated extensions. */
+ xtnData->negotiated[xtnData->numNegotiated++] = ex_type;
+
+ return SECSuccess;
+}
+
+/*
+ * struct { } EarlyDataIndication;
+ */
+PRInt32
+tls13_ClientSendEarlyDataXtn(const sslSocket *ss, TLSExtensionData *xtnData,
+ PRBool append,
+ PRUint32 maxBytes)
+{
+ SECStatus rv;
+ PRInt32 extension_length;
+
+ if (!tls13_ClientAllow0Rtt(ss, ss->sec.ci.sid))
+ return 0;
+
+ /* type + length */
+ extension_length = 2 + 2;
+
+ if (maxBytes < (PRUint32)extension_length) {
+ PORT_Assert(0);
+ return 0;
+ }
+
+ if (append) {
+ rv = ssl3_ExtAppendHandshakeNumber(ss, ssl_tls13_early_data_xtn, 2);
+ if (rv != SECSuccess)
+ return -1;
+
+ rv = ssl3_ExtAppendHandshakeNumber(ss, 0, 2);
+ if (rv != SECSuccess)
+ return -1;
+ }
+
+ xtnData->advertised[xtnData->numAdvertised++] =
+ ssl_tls13_early_data_xtn;
+
+ return extension_length;
+}
+
+SECStatus
+tls13_ServerHandleEarlyDataXtn(const sslSocket *ss, TLSExtensionData *xtnData, PRUint16 ex_type,
+ SECItem *data)
+{
+ SSL_TRC(3, ("%d: TLS13[%d]: handle early_data extension",
+ SSL_GETPID(), ss->fd));
+
+ /* If we are doing < TLS 1.3, then ignore this. */
+ if (ss->version < SSL_LIBRARY_VERSION_TLS_1_3) {
+ return SECSuccess;
+ }
+
+ if (data->len) {
+ PORT_SetError(SSL_ERROR_MALFORMED_EARLY_DATA);
+ return SECFailure;
+ }
+
+ xtnData->negotiated[xtnData->numNegotiated++] = ex_type;
+
+ return SECSuccess;
+}
+
+/* This is only registered if we are sending it. */
+PRInt32
+tls13_ServerSendEarlyDataXtn(const sslSocket *ss, TLSExtensionData *xtnData,
+ PRBool append,
+ PRUint32 maxBytes)
+{
+ SSL_TRC(3, ("%d: TLS13[%d]: send early_data extension",
+ SSL_GETPID(), ss->fd));
+
+ PORT_Assert(ss->ssl3.hs.zeroRttState == ssl_0rtt_accepted);
+ if (maxBytes < 4) {
+ PORT_Assert(0);
+ return 0;
+ }
+
+ if (append) {
+ SECStatus rv;
+
+ rv = ssl3_ExtAppendHandshakeNumber(ss, ssl_tls13_early_data_xtn, 2);
+ if (rv != SECSuccess)
+ return -1;
+
+ rv = ssl3_ExtAppendHandshakeNumber(ss, 0, 2);
+ if (rv != SECSuccess)
+ return -1;
+ }
+
+ return 4;
+}
+
+/* This will only be called if we also offered the extension. */
+SECStatus
+tls13_ClientHandleEarlyDataXtn(const sslSocket *ss, TLSExtensionData *xtnData, PRUint16 ex_type,
+ SECItem *data)
+{
+ SSL_TRC(3, ("%d: TLS13[%d]: handle early_data extension",
+ SSL_GETPID(), ss->fd));
+
+ /* If we are doing < TLS 1.3, then ignore this. */
+ if (ss->version < SSL_LIBRARY_VERSION_TLS_1_3) {
+ PORT_SetError(SSL_ERROR_EXTENSION_DISALLOWED_FOR_VERSION);
+ return SECFailure;
+ }
+
+ if (data->len) {
+ PORT_SetError(SSL_ERROR_MALFORMED_EARLY_DATA);
+ return SECFailure;
+ }
+
+ /* Keep track of negotiated extensions. */
+ xtnData->negotiated[xtnData->numNegotiated++] = ex_type;
+
+ return SECSuccess;
+}
+
+SECStatus
+tls13_ClientHandleTicketEarlyDataInfoXtn(const sslSocket *ss, TLSExtensionData *xtnData, PRUint16 ex_type,
+ SECItem *data)
+{
+ PRUint32 utmp;
+ SECStatus rv;
+
+ SSL_TRC(3, ("%d: TLS13[%d]: handle early_data_info extension",
+ SSL_GETPID(), ss->fd));
+
+ /* If we are doing < TLS 1.3, then ignore this. */
+ if (ss->version < SSL_LIBRARY_VERSION_TLS_1_3) {
+ PORT_SetError(SSL_ERROR_EXTENSION_DISALLOWED_FOR_VERSION);
+ return SECFailure;
+ }
+
+ rv = ssl3_ExtConsumeHandshake(ss, &utmp, sizeof(utmp),
+ &data->data, &data->len);
+ if (rv != SECSuccess) {
+ PORT_SetError(SSL_ERROR_RX_MALFORMED_NEW_SESSION_TICKET);
+ return SECFailure;
+ }
+ if (data->len) {
+ PORT_SetError(SSL_ERROR_RX_MALFORMED_NEW_SESSION_TICKET);
+ return SECFailure;
+ }
+
+ xtnData->max_early_data_size = PR_ntohl(utmp);
+
+ return SECSuccess;
+}
+
+/*
+ * struct {
+ * ProtocolVersion versions<2..254>;
+ * } SupportedVersions;
+ */
+PRInt32
+tls13_ClientSendSupportedVersionsXtn(const sslSocket *ss, TLSExtensionData *xtnData, PRBool append,
+ PRUint32 maxBytes)
+{
+ PRInt32 extensions_len;
+ PRUint16 version;
+ SECStatus rv;
+
+ if (ss->vrange.max < SSL_LIBRARY_VERSION_TLS_1_3) {
+ return 0;
+ }
+
+ SSL_TRC(3, ("%d: TLS13[%d]: send supported_versions extension",
+ SSL_GETPID(), ss->fd));
+
+ /* Extension type, extension len fiels, vector len field,
+ * length of the values. */
+ extensions_len = 2 + 2 + 1 +
+ 2 * (ss->vrange.max - ss->vrange.min + 1);
+
+ if (maxBytes < (PRUint32)extensions_len) {
+ PORT_Assert(0);
+ return 0;
+ }
+
+ if (append) {
+ rv = ssl3_ExtAppendHandshakeNumber(ss, ssl_tls13_supported_versions_xtn, 2);
+ if (rv != SECSuccess)
+ return -1;
+
+ rv = ssl3_ExtAppendHandshakeNumber(ss, extensions_len - 4, 2);
+ if (rv != SECSuccess)
+ return -1;
+
+ rv = ssl3_ExtAppendHandshakeNumber(ss, extensions_len - 5, 1);
+ if (rv != SECSuccess)
+ return -1;
+
+ for (version = ss->vrange.max; version >= ss->vrange.min; --version) {
+ rv = ssl3_ExtAppendHandshakeNumber(
+ ss, tls13_EncodeDraftVersion(version), 2);
+ if (rv != SECSuccess)
+ return -1;
+ }
+ }
+
+ return extensions_len;
+}
+
+/*
+ * struct {
+ * opaque cookie<1..2^16-1>;
+ * } Cookie;
+ */
+SECStatus
+tls13_ClientHandleHrrCookie(const sslSocket *ss, TLSExtensionData *xtnData, PRUint16 ex_type, SECItem *data)
+{
+ SECStatus rv;
+
+ SSL_TRC(3, ("%d: TLS13[%d]: handle cookie extension",
+ SSL_GETPID(), ss->fd));
+
+ PORT_Assert(ss->vrange.max >= SSL_LIBRARY_VERSION_TLS_1_3);
+
+ /* IMPORTANT: this is only valid while the HelloRetryRequest is still valid. */
+ rv = ssl3_ExtConsumeHandshakeVariable(
+ ss, &CONST_CAST(sslSocket, ss)->ssl3.hs.cookie, 2,
+ &data->data, &data->len);
+ if (rv != SECSuccess) {
+ PORT_SetError(SSL_ERROR_RX_MALFORMED_HELLO_RETRY_REQUEST);
+ return SECFailure;
+ }
+ if (!ss->ssl3.hs.cookie.len || data->len) {
+ ssl3_ExtSendAlert(ss, alert_fatal, decode_error);
+ PORT_SetError(SSL_ERROR_RX_MALFORMED_HELLO_RETRY_REQUEST);
+ return SECFailure;
+ }
+
+ return SECSuccess;
+}
+
+PRInt32
+tls13_ClientSendHrrCookieXtn(const sslSocket *ss, TLSExtensionData *xtnData, PRBool append, PRUint32 maxBytes)
+{
+ PRInt32 extension_len;
+
+ if (ss->vrange.max < SSL_LIBRARY_VERSION_TLS_1_3 ||
+ !ss->ssl3.hs.cookie.len) {
+ return 0;
+ }
+
+ SSL_TRC(3, ("%d: TLS13[%d]: send cookie extension", SSL_GETPID(), ss->fd));
+
+ /* Extension type, length, cookie length, cookie value. */
+ extension_len = 2 + 2 + 2 + ss->ssl3.hs.cookie.len;
+
+ if (maxBytes < (PRUint32)extension_len) {
+ PORT_Assert(0);
+ return 0;
+ }
+
+ if (append) {
+ SECStatus rv = ssl3_ExtAppendHandshakeNumber(ss, ssl_tls13_cookie_xtn, 2);
+ if (rv != SECSuccess)
+ return -1;
+
+ rv = ssl3_ExtAppendHandshakeNumber(ss, extension_len - 4, 2);
+ if (rv != SECSuccess)
+ return -1;
+
+ rv = ssl3_ExtAppendHandshakeVariable(ss, ss->ssl3.hs.cookie.data,
+ ss->ssl3.hs.cookie.len, 2);
+ if (rv != SECSuccess)
+ return -1;
+ }
+ return extension_len;
+}
+
+/*
+ * enum { psk_ke(0), psk_dhe_ke(1), (255) } PskKeyExchangeMode;
+ *
+ * struct {
+ * PskKeyExchangeMode ke_modes<1..255>;
+ * } PskKeyExchangeModes;
+ */
+PRInt32
+tls13_ClientSendPskKeyExchangeModesXtn(const sslSocket *ss,
+ TLSExtensionData *xtnData,
+ PRBool append, PRUint32 maxBytes)
+{
+ static const PRUint8 ke_modes[] = { tls13_psk_dh_ke };
+ static const unsigned long ke_modes_len = sizeof(ke_modes);
+ PRInt32 extension_len;
+
+ if (ss->vrange.max < SSL_LIBRARY_VERSION_TLS_1_3 ||
+ ss->opt.noCache) {
+ return 0;
+ }
+
+ extension_len =
+ 2 + 2 + /* Type + length */
+ 1 + ke_modes_len; /* key exchange modes vector */
+
+ SSL_TRC(3, ("%d: TLS13[%d]: send psk key exchange modes extension",
+ SSL_GETPID(), ss->fd));
+
+ if (maxBytes < (PRUint32)extension_len) {
+ PORT_Assert(0);
+ return 0;
+ }
+
+ if (append) {
+ SECStatus rv = ssl3_ExtAppendHandshakeNumber(
+ ss, ssl_tls13_psk_key_exchange_modes_xtn, 2);
+ if (rv != SECSuccess)
+ return -1;
+
+ rv = ssl3_ExtAppendHandshakeNumber(ss, extension_len - 4, 2);
+ if (rv != SECSuccess)
+ return -1;
+
+ rv = ssl3_ExtAppendHandshakeVariable(
+ ss, ke_modes, ke_modes_len, 1);
+ if (rv != SECSuccess)
+ return -1;
+ }
+ return extension_len;
+}
+
+SECStatus
+tls13_ServerHandlePskKeyExchangeModesXtn(const sslSocket *ss,
+ TLSExtensionData *xtnData,
+ PRUint16 ex_type, SECItem *data)
+{
+ SECStatus rv;
+
+ /* If we are doing < TLS 1.3, then ignore this. */
+ if (ss->version < SSL_LIBRARY_VERSION_TLS_1_3) {
+ return SECSuccess;
+ }
+
+ SSL_TRC(3, ("%d: TLS13[%d]: handle PSK key exchange modes extension",
+ SSL_GETPID(), ss->fd));
+
+ /* IMPORTANT: We aren't copying these values, just setting pointers.
+ * They will only be valid as long as the ClientHello is in memory. */
+ rv = ssl3_ExtConsumeHandshakeVariable(ss,
+ &xtnData->psk_ke_modes, 1,
+ &data->data, &data->len);
+ if (rv != SECSuccess)
+ return rv;
+ if (!xtnData->psk_ke_modes.len || data->len) {
+ PORT_SetError(SSL_ERROR_MALFORMED_PSK_KEY_EXCHANGE_MODES);
+ return SECFailure;
+ }
+
+ /* Keep track of negotiated extensions. */
+ xtnData->negotiated[xtnData->numNegotiated++] = ex_type;
+
+ return SECSuccess;
+}
+
+PRInt32
+tls13_SendShortHeaderXtn(const sslSocket *ss,
+ TLSExtensionData *xtnData,
+ PRBool append, PRUint32 maxBytes)
+{
+ PRUint32 extension_len = 2 + 2; /* Type + length (0). */
+
+ if (!ss->opt.enableShortHeaders) {
+ return 0;
+ }
+
+ /* Presently this is incompatible with 0-RTT. We will fix if
+ * it becomes more than an experiment. */
+ if (ss->opt.enable0RttData) {
+ return 0;
+ }
+
+ if (IS_DTLS(ss)) {
+ return 0;
+ }
+
+ SSL_TRC(3, ("%d: TLS13[%d]: send short_header extension",
+ SSL_GETPID(), ss->fd));
+
+ if (maxBytes < extension_len) {
+ PORT_Assert(0);
+ return 0;
+ }
+
+ if (append) {
+ SECStatus rv;
+
+ rv = ssl3_ExtAppendHandshakeNumber(ss, ssl_tls13_short_header_xtn, 2);
+ if (rv != SECSuccess)
+ return -1;
+
+ rv = ssl3_ExtAppendHandshakeNumber(ss, 0, 2);
+ if (rv != SECSuccess)
+ return -1;
+
+ xtnData->advertised[xtnData->numAdvertised++] =
+ ssl_tls13_short_header_xtn;
+ }
+
+ return extension_len;
+}
+
+SECStatus
+tls13_HandleShortHeaderXtn(
+ const sslSocket *ss, TLSExtensionData *xtnData, PRUint16 ex_type,
+ SECItem *data)
+{
+ SSL_TRC(3, ("%d: TLS13[%d]: handle early_data extension",
+ SSL_GETPID(), ss->fd));
+
+ /* If we are doing < TLS 1.3, then ignore this. */
+ if (ss->version < SSL_LIBRARY_VERSION_TLS_1_3) {
+ return SECSuccess;
+ }
+
+ /* Presently this is incompatible with 0-RTT. We will fix if
+ * it becomes more than an experiment. */
+ if (ss->opt.enable0RttData) {
+ return SECSuccess;
+ }
+
+ if (IS_DTLS(ss)) {
+ PORT_SetError(SSL_ERROR_EXTENSION_DISALLOWED_FOR_VERSION);
+ return SECFailure;
+ }
+
+ if (data->len) {
+ PORT_SetError(SSL_ERROR_RX_MALFORMED_HANDSHAKE);
+ return SECFailure;
+ }
+
+ if (!ss->opt.enableShortHeaders) {
+ /* Ignore. */
+ return SECSuccess;
+ }
+
+ /* Keep track of negotiated extensions. */
+ xtnData->negotiated[xtnData->numNegotiated++] = ex_type;
+
+ if (ss->sec.isServer) {
+ SECStatus rv;
+
+ rv = ssl3_RegisterExtensionSender(ss, xtnData,
+ ssl_tls13_short_header_xtn,
+ tls13_SendShortHeaderXtn);
+ if (rv != SECSuccess) {
+ return SECFailure;
+ }
+ }
+
+ return SECSuccess;
+}
diff --git a/nss/lib/ssl/tls13exthandle.h b/nss/lib/ssl/tls13exthandle.h
new file mode 100644
index 0000000..b798c6b
--- /dev/null
+++ b/nss/lib/ssl/tls13exthandle.h
@@ -0,0 +1,74 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is PRIVATE to SSL.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.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 __tls13exthandle_h_
+#define __tls13exthandle_h_
+
+PRInt32 tls13_ServerSendStatusRequestXtn(const sslSocket *ss, TLSExtensionData *xtnData,
+ PRBool append, PRUint32 maxBytes);
+PRInt32 tls13_ClientSendKeyShareXtn(const sslSocket *ss, TLSExtensionData *xtnData, PRBool append,
+ PRUint32 maxBytes);
+SECStatus tls13_ClientHandleKeyShareXtn(const sslSocket *ss, TLSExtensionData *xtnData,
+ PRUint16 ex_type,
+ SECItem *data);
+SECStatus tls13_ClientHandleKeyShareXtnHrr(const sslSocket *ss, TLSExtensionData *xtnData,
+ PRUint16 ex_type,
+ SECItem *data);
+SECStatus tls13_ServerHandleKeyShareXtn(const sslSocket *ss, TLSExtensionData *xtnData,
+ PRUint16 ex_type,
+ SECItem *data);
+PRInt32 tls13_ServerSendKeyShareXtn(const sslSocket *ss,
+ TLSExtensionData *xtnData,
+ PRBool append,
+ PRUint32 maxBytes);
+PRInt32 tls13_ClientSendPreSharedKeyXtn(const sslSocket *ss, TLSExtensionData *xtnData, PRBool append,
+ PRUint32 maxBytes);
+SECStatus tls13_ServerHandlePreSharedKeyXtn(const sslSocket *ss, TLSExtensionData *xtnData,
+ PRUint16 ex_type,
+ SECItem *data);
+SECStatus tls13_ClientHandlePreSharedKeyXtn(const sslSocket *ss, TLSExtensionData *xtnData,
+ PRUint16 ex_type,
+ SECItem *data);
+PRInt32 tls13_ServerSendPreSharedKeyXtn(const sslSocket *ss, TLSExtensionData *xtnData,
+ PRBool append,
+ PRUint32 maxBytes);
+PRInt32 tls13_ClientSendEarlyDataXtn(const sslSocket *ss, TLSExtensionData *xtnData,
+ PRBool append,
+ PRUint32 maxBytes);
+SECStatus tls13_ServerHandleEarlyDataXtn(const sslSocket *ss, TLSExtensionData *xtnData, PRUint16 ex_type,
+ SECItem *data);
+SECStatus tls13_ClientHandleEarlyDataXtn(const sslSocket *ss, TLSExtensionData *xtnData, PRUint16 ex_type,
+ SECItem *data);
+PRInt32 tls13_ServerSendEarlyDataXtn(const sslSocket *ss, TLSExtensionData *xtnData,
+ PRBool append,
+ PRUint32 maxBytes);
+SECStatus tls13_ClientHandleTicketEarlyDataInfoXtn(
+ const sslSocket *ss, TLSExtensionData *xtnData, PRUint16 ex_type,
+ SECItem *data);
+PRInt32 tls13_ClientSendSupportedVersionsXtn(const sslSocket *ss, TLSExtensionData *xtnData,
+ PRBool append,
+ PRUint32 maxBytes);
+SECStatus tls13_ClientHandleHrrCookie(const sslSocket *ss, TLSExtensionData *xtnData, PRUint16 ex_type,
+ SECItem *data);
+PRInt32 tls13_ClientSendHrrCookieXtn(const sslSocket *ss, TLSExtensionData *xtnData,
+ PRBool append,
+ PRUint32 maxBytes);
+PRInt32 tls13_ClientSendPskKeyExchangeModesXtn(const sslSocket *ss,
+ TLSExtensionData *xtnData,
+ PRBool append, PRUint32 maxBytes);
+SECStatus tls13_ServerHandlePskKeyExchangeModesXtn(const sslSocket *ss,
+ TLSExtensionData *xtnData,
+ PRUint16 ex_type, SECItem *data);
+PRInt32 tls13_SendShortHeaderXtn(const sslSocket *ss,
+ TLSExtensionData *xtnData,
+ PRBool append, PRUint32 maxBytes);
+SECStatus tls13_HandleShortHeaderXtn(
+ const sslSocket *ss, TLSExtensionData *xtnData, PRUint16 ex_type,
+ SECItem *data);
+
+#endif
diff --git a/nss/lib/ssl/tls13hkdf.c b/nss/lib/ssl/tls13hkdf.c
new file mode 100644
index 0000000..7e69bb8
--- /dev/null
+++ b/nss/lib/ssl/tls13hkdf.c
@@ -0,0 +1,270 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * TLS 1.3 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/. */
+
+#include "keyhi.h"
+#include "pk11func.h"
+#include "secitem.h"
+#include "ssl.h"
+#include "sslt.h"
+#include "sslerr.h"
+#include "sslimpl.h"
+
+/* This table contains the mapping between TLS hash identifiers and the
+ * PKCS#11 identifiers */
+static const struct {
+ SSLHashType hash;
+ CK_MECHANISM_TYPE pkcs11Mech;
+ unsigned int hashSize;
+} kTlsHkdfInfo[] = {
+ { ssl_hash_none, 0, 0 },
+ { ssl_hash_md5, 0, 0 },
+ { ssl_hash_sha1, 0, 0 },
+ { ssl_hash_sha224, 0 },
+ { ssl_hash_sha256, CKM_NSS_HKDF_SHA256, 32 },
+ { ssl_hash_sha384, CKM_NSS_HKDF_SHA384, 48 },
+ { ssl_hash_sha512, CKM_NSS_HKDF_SHA512, 64 }
+};
+
+SECStatus
+tls13_HkdfExtract(PK11SymKey *ikm1, PK11SymKey *ikm2in, SSLHashType baseHash,
+ PK11SymKey **prkp)
+{
+ CK_NSS_HKDFParams params;
+ SECItem paramsi;
+ SECStatus rv;
+ SECItem *salt;
+ PK11SymKey *prk;
+ static const PRUint8 zeroKeyBuf[HASH_LENGTH_MAX];
+ PK11SymKey *zeroKey = NULL;
+ PK11SlotInfo *slot = NULL;
+ PK11SymKey *ikm2;
+
+ params.bExtract = CK_TRUE;
+ params.bExpand = CK_FALSE;
+ params.pInfo = NULL;
+ params.ulInfoLen = 0UL;
+
+ if (ikm1) {
+ /* TODO(ekr@rtfm.com): This violates the PKCS#11 key boundary
+ * but is imposed on us by the present HKDF interface. */
+ rv = PK11_ExtractKeyValue(ikm1);
+ if (rv != SECSuccess)
+ return rv;
+
+ salt = PK11_GetKeyData(ikm1);
+ if (!salt)
+ return SECFailure;
+
+ params.pSalt = salt->data;
+ params.ulSaltLen = salt->len;
+ PORT_Assert(salt->len > 0);
+ } else {
+ /* Per documentation for CKM_NSS_HKDF_*:
+ *
+ * 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.
+ */
+ params.pSalt = NULL;
+ params.ulSaltLen = 0UL;
+ }
+ paramsi.data = (unsigned char *)&params;
+ paramsi.len = sizeof(params);
+
+ PORT_Assert(kTlsHkdfInfo[baseHash].pkcs11Mech);
+ PORT_Assert(kTlsHkdfInfo[baseHash].hashSize);
+ PORT_Assert(kTlsHkdfInfo[baseHash].hash == baseHash);
+
+ /* A zero ikm2 is a key of hash-length 0s. */
+ if (!ikm2in) {
+ SECItem zeroItem = {
+ siBuffer,
+ (unsigned char *)zeroKeyBuf,
+ kTlsHkdfInfo[baseHash].hashSize
+ };
+ slot = PK11_GetInternalSlot();
+ if (!slot) {
+ return SECFailure;
+ }
+ zeroKey = PK11_ImportSymKey(slot,
+ kTlsHkdfInfo[baseHash].pkcs11Mech,
+ PK11_OriginUnwrap,
+ CKA_DERIVE, &zeroItem, NULL);
+ if (!zeroKey)
+ return SECFailure;
+ ikm2 = zeroKey;
+ } else {
+ ikm2 = ikm2in;
+ }
+ PORT_Assert(ikm2);
+
+ PRINT_BUF(50, (NULL, "HKDF Extract: IKM1/Salt", params.pSalt, params.ulSaltLen));
+ PRINT_KEY(50, (NULL, "HKDF Extract: IKM2", ikm2));
+
+ prk = PK11_Derive(ikm2, kTlsHkdfInfo[baseHash].pkcs11Mech,
+ &paramsi, kTlsHkdfInfo[baseHash].pkcs11Mech,
+ CKA_DERIVE, kTlsHkdfInfo[baseHash].hashSize);
+ if (zeroKey)
+ PK11_FreeSymKey(zeroKey);
+ if (slot)
+ PK11_FreeSlot(slot);
+ if (!prk)
+ return SECFailure;
+
+ PRINT_KEY(50, (NULL, "HKDF Extract", prk));
+ *prkp = prk;
+
+ return SECSuccess;
+}
+
+SECStatus
+tls13_HkdfExpandLabel(PK11SymKey *prk, SSLHashType baseHash,
+ const PRUint8 *handshakeHash, unsigned int handshakeHashLen,
+ const char *label, unsigned int labelLen,
+ CK_MECHANISM_TYPE algorithm, unsigned int keySize,
+ PK11SymKey **keyp)
+{
+ CK_NSS_HKDFParams params;
+ SECItem paramsi = { siBuffer, NULL, 0 };
+ /* Size of info array needs to be big enough to hold the maximum Prefix,
+ * Label, plus HandshakeHash. If it's ever to small, the code will abort.
+ */
+ PRUint8 info[256];
+ PRUint8 *ptr = info;
+ unsigned int infoLen;
+ PK11SymKey *derived;
+ const char *kLabelPrefix = "TLS 1.3, ";
+ const unsigned int kLabelPrefixLen = strlen(kLabelPrefix);
+
+ if (handshakeHash) {
+ if (handshakeHashLen > 255) {
+ PORT_Assert(0);
+ PORT_SetError(SEC_ERROR_INVALID_ARGS);
+ return SECFailure;
+ }
+ } else {
+ PORT_Assert(!handshakeHashLen);
+ }
+
+ /*
+ * [draft-ietf-tls-tls13-11] Section 7.1:
+ *
+ * HKDF-Expand-Label(Secret, Label, HashValue, Length) =
+ * HKDF-Expand(Secret, HkdfLabel, Length)
+ *
+ * Where HkdfLabel is specified as:
+ *
+ * struct HkdfLabel {
+ * uint16 length;
+ * opaque label<9..255>;
+ * opaque hash_value<0..255>;
+ * };
+ *
+ * Where:
+ * - HkdfLabel.length is Length
+ * - HkdfLabel.hash_value is HashValue.
+ * - HkdfLabel.label is "TLS 1.3, " + Label
+ *
+ */
+ infoLen = 2 + 1 + kLabelPrefixLen + labelLen + 1 + handshakeHashLen;
+ if (infoLen > sizeof(info)) {
+ PORT_Assert(0);
+ goto abort;
+ }
+
+ ptr = ssl_EncodeUintX(keySize, 2, ptr);
+ ptr = ssl_EncodeUintX(labelLen + kLabelPrefixLen, 1, ptr);
+ PORT_Memcpy(ptr, kLabelPrefix, kLabelPrefixLen);
+ ptr += kLabelPrefixLen;
+ PORT_Memcpy(ptr, label, labelLen);
+ ptr += labelLen;
+ ptr = ssl_EncodeUintX(handshakeHashLen, 1, ptr);
+ if (handshakeHash) {
+ PORT_Memcpy(ptr, handshakeHash, handshakeHashLen);
+ ptr += handshakeHashLen;
+ }
+ PORT_Assert((ptr - info) == infoLen);
+
+ params.bExtract = CK_FALSE;
+ params.bExpand = CK_TRUE;
+ params.pInfo = info;
+ params.ulInfoLen = infoLen;
+ paramsi.data = (unsigned char *)&params;
+ paramsi.len = sizeof(params);
+
+ derived = PK11_DeriveWithFlags(prk, kTlsHkdfInfo[baseHash].pkcs11Mech,
+ &paramsi, algorithm,
+ CKA_DERIVE, keySize,
+ CKF_SIGN | CKF_VERIFY);
+ if (!derived)
+ return SECFailure;
+
+ *keyp = derived;
+
+#ifdef TRACE
+ if (ssl_trace >= 10) {
+ /* Make sure the label is null terminated. */
+ char labelStr[100];
+ PORT_Memcpy(labelStr, label, labelLen);
+ labelStr[labelLen] = 0;
+ SSL_TRC(50, ("HKDF Expand: label=[TLS 1.3, ] + '%s',requested length=%d",
+ labelStr, keySize));
+ }
+ PRINT_KEY(50, (NULL, "PRK", prk));
+ PRINT_BUF(50, (NULL, "Hash", handshakeHash, handshakeHashLen));
+ PRINT_BUF(50, (NULL, "Info", info, infoLen));
+ PRINT_KEY(50, (NULL, "Derived key", derived));
+#endif
+
+ return SECSuccess;
+
+abort:
+ PORT_SetError(SSL_ERROR_SYM_KEY_CONTEXT_FAILURE);
+ return SECFailure;
+}
+
+SECStatus
+tls13_HkdfExpandLabelRaw(PK11SymKey *prk, SSLHashType baseHash,
+ const PRUint8 *handshakeHash, unsigned int handshakeHashLen,
+ const char *label, unsigned int labelLen,
+ unsigned char *output, unsigned int outputLen)
+{
+ PK11SymKey *derived = NULL;
+ SECItem *rawkey;
+ SECStatus rv;
+
+ rv = tls13_HkdfExpandLabel(prk, baseHash, handshakeHash, handshakeHashLen,
+ label, labelLen,
+ kTlsHkdfInfo[baseHash].pkcs11Mech, outputLen,
+ &derived);
+ if (rv != SECSuccess || !derived) {
+ goto abort;
+ }
+
+ rv = PK11_ExtractKeyValue(derived);
+ if (rv != SECSuccess) {
+ goto abort;
+ }
+
+ rawkey = PK11_GetKeyData(derived);
+ if (!rawkey) {
+ goto abort;
+ }
+
+ PORT_Assert(rawkey->len == outputLen);
+ memcpy(output, rawkey->data, outputLen);
+ PK11_FreeSymKey(derived);
+
+ return SECSuccess;
+
+abort:
+ if (derived) {
+ PK11_FreeSymKey(derived);
+ }
+ PORT_SetError(SSL_ERROR_SYM_KEY_CONTEXT_FAILURE);
+ return SECFailure;
+}
diff --git a/nss/lib/ssl/tls13hkdf.h b/nss/lib/ssl/tls13hkdf.h
new file mode 100644
index 0000000..78347a1
--- /dev/null
+++ b/nss/lib/ssl/tls13hkdf.h
@@ -0,0 +1,38 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is PRIVATE to SSL.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.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 __tls13hkdf_h_
+#define __tls13hkdf_h_
+
+#include "keyhi.h"
+#include "sslt.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+SECStatus tls13_HkdfExtract(
+ PK11SymKey *ikm1, PK11SymKey *ikm2, SSLHashType baseHash,
+ PK11SymKey **prkp);
+SECStatus tls13_HkdfExpandLabelRaw(
+ PK11SymKey *prk, SSLHashType baseHash,
+ const PRUint8 *handshakeHash, unsigned int handshakeHashLen,
+ const char *label, unsigned int labelLen,
+ unsigned char *output, unsigned int outputLen);
+SECStatus tls13_HkdfExpandLabel(
+ PK11SymKey *prk, SSLHashType baseHash,
+ const PRUint8 *handshakeHash, unsigned int handshakeHashLen,
+ const char *label, unsigned int labelLen,
+ CK_MECHANISM_TYPE algorithm, unsigned int keySize,
+ PK11SymKey **keyp);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/nss/lib/ssl/unix_err.c b/nss/lib/ssl/unix_err.c
index 1857cfe..d4390b8 100644
--- a/nss/lib/ssl/unix_err.c
+++ b/nss/lib/ssl/unix_err.c
@@ -1,12 +1,12 @@
/* -*- 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
+ * 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/. */
@@ -18,7 +18,7 @@
#include "prerror.h"
#endif
-#if defined (__bsdi__) || defined(NTO) || defined(DARWIN) || defined(BEOS)
+#if defined(__bsdi__) || defined(NTO) || defined(DARWIN) || defined(BEOS)
#undef _PR_POLL_AVAILABLE
#endif
@@ -30,357 +30,547 @@
/* forward declarations. */
void nss_MD_unix_map_default_error(int err);
-void nss_MD_unix_map_opendir_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)
+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;
+ 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)
+void
+nss_MD_unix_readdir_error(int err)
{
PRErrorCode prError;
switch (err) {
- case ENOENT: prError = PR_NO_MORE_FILES_ERROR; break;
+ case ENOENT:
+ prError = PR_NO_MORE_FILES_ERROR;
+ break;
#ifdef EOVERFLOW
- case EOVERFLOW: prError = PR_IO_ERROR; break;
+ 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;
+ 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)
+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;
+ 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)
+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;
+ 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)
+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;
+ 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)
+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;
+ 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)
+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;
+ 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)
+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)
+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;
+ 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)
+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;
+ 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)
+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;
+ 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)
+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)
+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;
+ 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)
+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;
+ 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)
+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;
+ 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)
+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)
+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)
+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)
+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)
+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)
+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)
+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;
+ 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)
+void
+nss_MD_unix_map_connect_error(int err)
{
PRErrorCode prError;
switch (err) {
- case EACCES: prError = PR_ADDRESS_NOT_SUPPORTED_ERROR; break;
+ 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;
+ /*
+ * 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;
+ 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)
+void
+nss_MD_unix_map_bind_error(int err)
{
PRErrorCode prError;
switch (err) {
- case EINVAL: prError = PR_SOCKET_ADDRESS_IS_BOUND_ERROR; break;
+ 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;
+ * 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)
+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)
+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)
+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;
+ 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)
+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;
+ 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)
+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;
+ 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)
+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;
+ 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)
+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;
+ 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)
+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;
+ 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)
+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;
+ 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)
+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)
+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)
+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;
+ 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)
+void
+nss_MD_unix_map_poll_revents_error(int err)
{
if (err & POLLNVAL)
PR_SetError(PR_BAD_DESCRIPTOR_ERROR, EBADF);
@@ -393,125 +583,255 @@ void nss_MD_unix_map_poll_revents_error(int err)
}
#endif /* _PR_POLL_AVAILABLE */
-
-void nss_MD_unix_map_flock_error(int err)
+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;
+ 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)
+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;
+ 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)
+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)
+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;
- /*
+ 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;
+ case EALREADY:
+ prError = PR_ALREADY_INITIATED_ERROR;
+ break;
#endif
- case EBADF: prError = PR_BAD_DESCRIPTOR_ERROR; break;
+ case EBADF:
+ prError = PR_BAD_DESCRIPTOR_ERROR;
+ break;
#ifdef EBADMSG
- case EBADMSG: prError = PR_IO_ERROR; break;
+ 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;
+ 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;
+ case EDIRCORRUPTED:
+ prError = PR_DIRECTORY_CORRUPTED_ERROR;
+ break;
#endif
#ifdef EDQUOT
- case EDQUOT: prError = PR_NO_DEVICE_SPACE_ERROR; break;
+ 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;
+ 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;
+ 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;
+ 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;
+ 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;
+ 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;
+ 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;
+ 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;
+ 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;
+ 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;
+ 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;
+ 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;
+ case EWOULDBLOCK:
+ prError = PR_WOULD_BLOCK_ERROR;
+ break;
#endif
- case EXDEV: prError = PR_NOT_SAME_DEVICE_ERROR; break;
+ case EXDEV:
+ prError = PR_NOT_SAME_DEVICE_ERROR;
+ break;
- default: prError = PR_UNKNOWN_ERROR; break;
+ default:
+ prError = PR_UNKNOWN_ERROR;
+ break;
}
PR_SetError(prError, err);
}
diff --git a/nss/lib/ssl/unix_err.h b/nss/lib/ssl/unix_err.h
index be7fe29..5d7d547 100644
--- a/nss/lib/ssl/unix_err.h
+++ b/nss/lib/ssl/unix_err.h
@@ -1,11 +1,11 @@
/*
* This file essentially replicates NSPR's source for the functions that
- * map system-specific error codes to NSPR error codes. We would use
+ * 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/. */
diff --git a/nss/lib/ssl/win32err.c b/nss/lib/ssl/win32err.c
index a70010d..caa12b9 100644
--- a/nss/lib/ssl/win32err.c
+++ b/nss/lib/ssl/win32err.c
@@ -1,12 +1,12 @@
/* -*- 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
+ * 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/. */
@@ -33,79 +33,94 @@
/* forward declaration. */
void nss_MD_win32_map_default_error(PRInt32 err);
-void nss_MD_win32_map_opendir_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)
+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)
+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)
+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)
+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)
+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)
+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)
+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)
+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)
+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)
+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)
+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)
+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)
+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)
+void
+nss_MD_win32_map_fsync_error(PRInt32 err)
{
nss_MD_win32_map_default_error(err);
}
@@ -113,231 +128,423 @@ void nss_MD_win32_map_fsync_error(PRInt32 err)
/*
* For both CloseHandle() and closesocket().
*/
-void nss_MD_win32_map_close_error(PRInt32 err)
+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)
+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)
+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)
+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)
+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;
+ 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)
+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;
+ 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)
+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;
+ 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)
+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)
+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;
+ 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)
+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;
+ 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)
+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;
+ 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)
+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)
+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;
+ 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)
+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)
+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)
+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)
+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)
+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.
+** context, WSAENOTSOCK is equivalent to EBADF on Unix.
*/
-void nss_MD_win32_map_select_error(PRInt32 err)
+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;
+ 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)
+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)
+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;
+ 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;
+ 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;
+ 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/nss/lib/ssl/win32err.h b/nss/lib/ssl/win32err.h
index 8ce588e..a698849 100644
--- a/nss/lib/ssl/win32err.h
+++ b/nss/lib/ssl/win32err.h
@@ -1,11 +1,11 @@
/*
* This file essentially replicates NSPR's source for the functions that
- * map system-specific error codes to NSPR error codes. We would use
+ * 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/. */
diff --git a/nss/lib/sysinit/nsssysinit.c b/nss/lib/sysinit/nsssysinit.c
index 60015dd..39e2ad7 100644
--- a/nss/lib/sysinit/nsssysinit.c
+++ b/nss/lib/sysinit/nsssysinit.c
@@ -5,6 +5,7 @@
#include "prio.h"
#include "prprf.h"
#include "plhash.h"
+#include "prenv.h"
/*
* The following provides a default example for operating systems to set up
@@ -23,17 +24,17 @@
#include <sys/stat.h>
#include <sys/types.h>
-static int
+static int
testdir(char *dir)
{
- struct stat buf;
- memset(&buf, 0, sizeof(buf));
+ struct stat buf;
+ memset(&buf, 0, sizeof(buf));
- if (stat(dir,&buf) < 0) {
- return 0;
- }
+ if (stat(dir, &buf) < 0) {
+ return 0;
+ }
- return S_ISDIR(buf.st_mode);
+ return S_ISDIR(buf.st_mode);
}
#define NSS_USER_PATH1 "/.pki"
@@ -41,55 +42,55 @@ testdir(char *dir)
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;
+ char *userdir = PR_GetEnvSecure("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);
+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;
+ /* 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);
+ return (access(NSS_DEFAULT_SYSTEM, W_OK) == 0);
}
#else
@@ -97,32 +98,32 @@ userCanModifySystemDB()
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;
+ /* 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;
+ /* 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;
+ /* 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
+ /* use the registry to find if the user has administrative privilege
* to modify the system's nss database. */
- return PR_FALSE;
+ return PR_FALSE;
}
#else
@@ -130,24 +131,24 @@ userCanModifySystemDB()
#endif
#endif
-static PRBool
+static PRBool
getFIPSEnv(void)
{
- char *fipsEnv = getenv("NSS_FIPS");
+ char *fipsEnv = PR_GetEnvSecure("NSS_FIPS");
if (!fipsEnv) {
- return PR_FALSE;
+ return PR_FALSE;
}
- if ((strcasecmp(fipsEnv,"fips") == 0) ||
- (strcasecmp(fipsEnv,"true") == 0) ||
- (strcasecmp(fipsEnv,"on") == 0) ||
- (strcasecmp(fipsEnv,"1") == 0)) {
- return PR_TRUE;
+ 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
+static PRBool
getFIPSMode(void)
{
FILE *f;
@@ -156,9 +157,9 @@ getFIPSMode(void)
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();
+ /* if we don't have a proc flag, fall back to the
+ * environment variable */
+ return getFIPSEnv();
}
size = fread(&d, 1, 1, f);
@@ -171,14 +172,13 @@ getFIPSMode(void)
}
#else
-static PRBool
+static PRBool
getFIPSMode(void)
{
return getFIPSEnv();
}
#endif
-
#define NSS_DEFAULT_FLAGS "flags=readonly"
/* configuration flags according to
@@ -190,15 +190,15 @@ getFIPSMode(void)
* 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 ]"
-
+#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 " } ";
+ CIPHER_ORDER_FLAGS " slotParams={0x00000001=" SLOT_FLAGS " } ";
static const char *nssDefaultFIPSFlags =
- CIPHER_ORDER_FLAGS " slotParams={0x00000003=" SLOT_FLAGS " } ";
+ CIPHER_ORDER_FLAGS " slotParams={0x00000003=" SLOT_FLAGS " } ";
/*
* This function builds the list of databases and modules to load, and sets
@@ -209,7 +209,7 @@ static const char *nssDefaultFIPSFlags =
*
* 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
+ * 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.
*
@@ -225,7 +225,7 @@ get_list(char *filename, char *stripped_parameters)
/* can't get any space */
if (module_list == NULL) {
- return NULL;
+ return NULL;
}
sysdb = getSystemDB();
@@ -233,33 +233,34 @@ get_list(char *filename, char *stripped_parameters)
/* 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);
- }
+ /* 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);
+ 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 */
@@ -278,28 +279,27 @@ release_list(char **arg)
int next;
for (next = 0; arg[next]; next++) {
- free(arg[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; \
- }
+#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
@@ -309,7 +309,7 @@ static void
overlapstrcpy(char *target, char *src)
{
while (*src) {
- *target++ = *src++;
+ *target++ = *src++;
}
*target = 0;
}
@@ -318,41 +318,41 @@ overlapstrcpy(char *target, char *src)
/* 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)
+parse_parameters(const char *parameters, char **filename, char **stripped)
{
- char *sourcePrev;
- char *sourceCurr;
+ const char *sourcePrev;
+ const char *sourceCurr;
char *targetCurr;
char *newStripped;
*filename = NULL;
*stripped = NULL;
- newStripped = PORT_Alloc(PORT_Strlen(parameters)+2);
+ 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);
+ 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;
+ PORT_Free(newStripped);
+ return SECFailure;
}
/* strip off any directives from the filename */
if (strncmp("sql:", *filename, 4) == 0) {
- overlapstrcpy(*filename, (*filename)+4);
+ overlapstrcpy(*filename, (*filename) + 4);
} else if (strncmp("dbm:", *filename, 4) == 0) {
- overlapstrcpy(*filename, (*filename)+4);
+ overlapstrcpy(*filename, (*filename) + 4);
} else if (strncmp("extern:", *filename, 7) == 0) {
- overlapstrcpy(*filename, (*filename)+7);
+ overlapstrcpy(*filename, (*filename) + 7);
}
*stripped = newStripped;
return SECSuccess;
@@ -369,32 +369,32 @@ NSS_ReturnModuleSpecData(unsigned long function, char *parameters, void *args)
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;
- }
+ /* 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;
+ 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);
diff --git a/nss/lib/sysinit/sysinit.gyp b/nss/lib/sysinit/sysinit.gyp
new file mode 100644
index 0000000..e961325
--- /dev/null
+++ b/nss/lib/sysinit/sysinit.gyp
@@ -0,0 +1,31 @@
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+{
+ 'includes': [
+ '../../coreconf/config.gypi'
+ ],
+ 'targets': [
+ {
+ 'target_name': 'nsssysinit_static',
+ 'type': 'static_library',
+ 'sources': [
+ 'nsssysinit.c'
+ ],
+ 'dependencies': [
+ '<(DEPTH)/exports.gyp:nss_exports',
+ '<(DEPTH)/lib/util/util.gyp:nssutil3'
+ ]
+ },
+ {
+ 'target_name': 'nsssysinit',
+ 'type': 'shared_library',
+ 'dependencies': [
+ 'nsssysinit_static'
+ ]
+ }
+ ],
+ 'variables': {
+ 'module': 'nss'
+ }
+} \ No newline at end of file
diff --git a/nss/lib/util/Makefile b/nss/lib/util/Makefile
index 0a9b749..97ec934 100644
--- a/nss/lib/util/Makefile
+++ b/nss/lib/util/Makefile
@@ -48,9 +48,3 @@ include $(CORE_DEPTH)/coreconf/rules.mk
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/nss/lib/util/SECerrs.h b/nss/lib/util/SECerrs.h
index 8b6b36f..6d6f1b8 100644
--- a/nss/lib/util/SECerrs.h
+++ b/nss/lib/util/SECerrs.h
@@ -5,549 +5,547 @@
/* 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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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, (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_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_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_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_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_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_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_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_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_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_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_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_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_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_CA_CERT_INVALID, (SEC_ERROR_BASE + 36),
+ "Issuer certificate is invalid.")
-ER3(SEC_ERROR_CERT_USAGES_INVALID, (SEC_ERROR_BASE + 38),
-"Certificate usages field is invalid.")
+ER3(SEC_ERROR_PATH_LEN_CONSTRAINT_INVALID, (SEC_ERROR_BASE + 37),
+ "Certificate path length constraint is invalid.")
-ER3(SEC_INTERNAL_ONLY, (SEC_ERROR_BASE + 39),
-"**Internal ONLY module**")
+ER3(SEC_ERROR_CERT_USAGES_INVALID, (SEC_ERROR_BASE + 38),
+ "Certificate usages field is invalid.")
-ER3(SEC_ERROR_INVALID_KEY, (SEC_ERROR_BASE + 40),
-"The key does not support the requested operation.")
+ER3(SEC_INTERNAL_ONLY, (SEC_ERROR_BASE + 39),
+ "**Internal ONLY module**")
-ER3(SEC_ERROR_UNKNOWN_CRITICAL_EXTENSION, (SEC_ERROR_BASE + 41),
-"Certificate contains unknown critical extension.")
+ER3(SEC_ERROR_INVALID_KEY, (SEC_ERROR_BASE + 40),
+ "The key does not support the requested operation.")
-ER3(SEC_ERROR_OLD_CRL, (SEC_ERROR_BASE + 42),
-"New CRL is not later than the current one.")
+ER3(SEC_ERROR_UNKNOWN_CRITICAL_EXTENSION, (SEC_ERROR_BASE + 41),
+ "Certificate contains unknown critical extension.")
-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_OLD_CRL, (SEC_ERROR_BASE + 42),
+ "New CRL is not later than the current one.")
-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_NO_EMAIL_CERT, (SEC_ERROR_BASE + 43),
+ "Not encrypted or signed: you do not yet have an email certificate.")
-ER3(SEC_ERROR_NOT_A_RECIPIENT, (SEC_ERROR_BASE + 45),
-"Cannot decrypt: you are not a recipient, or matching certificate and \
+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_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, \
+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.")
+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. \
+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_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_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_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_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_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_BAD_PIN, (SEC_ERROR_BASE + 56),
+ "Invalid Pin")
-ER3(XP_SEC_FORTEZZA_PERSON_ERROR, (SEC_ERROR_BASE + 57),
-"Couldn't initialize Fortezza personalities.")
+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_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_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_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_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_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_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_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_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_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_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_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_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_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(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_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_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(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_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_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_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_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_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_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_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_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.")
+ "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_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_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_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_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_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_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_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_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_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_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_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.")
+ "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_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_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_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.")
+ "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_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_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_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_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_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_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_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_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_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_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_OLD_KRL, (SEC_ERROR_BASE + 110),
+ "New KRL is not later than the current one.")
-ER3(SEC_ERROR_CERT_NOT_IN_NAME_SPACE, (SEC_ERROR_BASE + 112),
-"The Certifying Authority for this certificate is not permitted to issue a \
+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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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 \
+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_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_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_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_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_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_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_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 \
+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_BUSY, (SEC_ERROR_BASE + 139),
+ "NSS could not shutdown. Objects are still in use.")
-ER3(SEC_ERROR_UNSUPPORTED_ELLIPTIC_CURVE, (SEC_ERROR_BASE + 141),
-"Unsupported elliptic curve.")
+ER3(SEC_ERROR_EXTRA_INPUT, (SEC_ERROR_BASE + 140),
+ "DER-encoded message contained extra unused data.")
-ER3(SEC_ERROR_UNSUPPORTED_EC_POINT_FORM, (SEC_ERROR_BASE + 142),
-"Unsupported elliptic curve point form.")
+ER3(SEC_ERROR_UNSUPPORTED_ELLIPTIC_CURVE, (SEC_ERROR_BASE + 141),
+ "Unsupported elliptic curve.")
-ER3(SEC_ERROR_UNRECOGNIZED_OID, (SEC_ERROR_BASE + 143),
-"Unrecognized Object Identifier.")
+ER3(SEC_ERROR_UNSUPPORTED_EC_POINT_FORM, (SEC_ERROR_BASE + 142),
+ "Unsupported elliptic curve point form.")
-ER3(SEC_ERROR_OCSP_INVALID_SIGNING_CERT, (SEC_ERROR_BASE + 144),
-"Invalid OCSP signing certificate in OCSP response.")
+ER3(SEC_ERROR_UNRECOGNIZED_OID, (SEC_ERROR_BASE + 143),
+ "Unrecognized Object Identifier.")
-ER3(SEC_ERROR_REVOKED_CERTIFICATE_CRL, (SEC_ERROR_BASE + 145),
-"Certificate is revoked in issuer's certificate revocation list.")
+ER3(SEC_ERROR_OCSP_INVALID_SIGNING_CERT, (SEC_ERROR_BASE + 144),
+ "Invalid OCSP signing certificate in OCSP response.")
-ER3(SEC_ERROR_REVOKED_CERTIFICATE_OCSP, (SEC_ERROR_BASE + 146),
-"Issuer's OCSP responder reports certificate is revoked.")
+ER3(SEC_ERROR_REVOKED_CERTIFICATE_CRL, (SEC_ERROR_BASE + 145),
+ "Certificate is revoked in issuer's certificate revocation list.")
-ER3(SEC_ERROR_CRL_INVALID_VERSION, (SEC_ERROR_BASE + 147),
-"Issuer's Certificate Revocation List has an unknown version number.")
+ER3(SEC_ERROR_REVOKED_CERTIFICATE_OCSP, (SEC_ERROR_BASE + 146),
+ "Issuer's OCSP responder reports certificate is revoked.")
-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_INVALID_VERSION, (SEC_ERROR_BASE + 147),
+ "Issuer's Certificate Revocation List has an unknown version number.")
-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_CRL_V1_CRITICAL_EXTENSION, (SEC_ERROR_BASE + 148),
+ "Issuer's V1 Certificate Revocation List has a critical extension.")
-ER3(SEC_ERROR_UNKNOWN_OBJECT_TYPE, (SEC_ERROR_BASE + 150),
-"Unknown object type specified.")
+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_INCOMPATIBLE_PKCS11, (SEC_ERROR_BASE + 151),
-"PKCS #11 driver violates the spec in an incompatible way.")
+ER3(SEC_ERROR_UNKNOWN_OBJECT_TYPE, (SEC_ERROR_BASE + 150),
+ "Unknown object type specified.")
-ER3(SEC_ERROR_NO_EVENT, (SEC_ERROR_BASE + 152),
-"No new slot event is available at this time.")
+ER3(SEC_ERROR_INCOMPATIBLE_PKCS11, (SEC_ERROR_BASE + 151),
+ "PKCS #11 driver violates the spec in an incompatible way.")
-ER3(SEC_ERROR_CRL_ALREADY_EXISTS, (SEC_ERROR_BASE + 153),
-"CRL already exists.")
+ER3(SEC_ERROR_NO_EVENT, (SEC_ERROR_BASE + 152),
+ "No new slot event is available at this time.")
-ER3(SEC_ERROR_NOT_INITIALIZED, (SEC_ERROR_BASE + 154),
-"NSS is not initialized.")
+ER3(SEC_ERROR_CRL_ALREADY_EXISTS, (SEC_ERROR_BASE + 153),
+ "CRL already exists.")
-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_NOT_INITIALIZED, (SEC_ERROR_BASE + 154),
+ "NSS is not initialized.")
-ER3(SEC_ERROR_OCSP_RESPONDER_CERT_INVALID, (SEC_ERROR_BASE + 156),
-"Configured OCSP responder's certificate is invalid.")
+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_BAD_SIGNATURE, (SEC_ERROR_BASE + 157),
-"OCSP response has an invalid signature.")
+ER3(SEC_ERROR_OCSP_RESPONDER_CERT_INVALID, (SEC_ERROR_BASE + 156),
+ "Configured OCSP responder's certificate is invalid.")
-ER3(SEC_ERROR_OUT_OF_SEARCH_LIMITS, (SEC_ERROR_BASE + 158),
-"Cert validation search is out of search limits")
+ER3(SEC_ERROR_OCSP_BAD_SIGNATURE, (SEC_ERROR_BASE + 157),
+ "OCSP response has an invalid signature.")
-ER3(SEC_ERROR_INVALID_POLICY_MAPPING, (SEC_ERROR_BASE + 159),
-"Policy mapping contains anypolicy")
+ER3(SEC_ERROR_OUT_OF_SEARCH_LIMITS, (SEC_ERROR_BASE + 158),
+ "Cert validation search is out of search limits")
-ER3(SEC_ERROR_POLICY_VALIDATION_FAILED, (SEC_ERROR_BASE + 160),
-"Cert chain fails policy validation")
+ER3(SEC_ERROR_INVALID_POLICY_MAPPING, (SEC_ERROR_BASE + 159),
+ "Policy mapping contains anypolicy")
-ER3(SEC_ERROR_UNKNOWN_AIA_LOCATION_TYPE, (SEC_ERROR_BASE + 161),
-"Unknown location type in cert AIA extension")
+ER3(SEC_ERROR_POLICY_VALIDATION_FAILED, (SEC_ERROR_BASE + 160),
+ "Cert chain fails policy validation")
-ER3(SEC_ERROR_BAD_HTTP_RESPONSE, (SEC_ERROR_BASE + 162),
-"Server returned bad HTTP response")
+ER3(SEC_ERROR_UNKNOWN_AIA_LOCATION_TYPE, (SEC_ERROR_BASE + 161),
+ "Unknown location type in cert AIA extension")
-ER3(SEC_ERROR_BAD_LDAP_RESPONSE, (SEC_ERROR_BASE + 163),
-"Server returned bad LDAP response")
+ER3(SEC_ERROR_BAD_HTTP_RESPONSE, (SEC_ERROR_BASE + 162),
+ "Server returned bad HTTP response")
-ER3(SEC_ERROR_FAILED_TO_ENCODE_DATA, (SEC_ERROR_BASE + 164),
-"Failed to encode data with ASN1 encoder")
+ER3(SEC_ERROR_BAD_LDAP_RESPONSE, (SEC_ERROR_BASE + 163),
+ "Server returned bad LDAP response")
-ER3(SEC_ERROR_BAD_INFO_ACCESS_LOCATION, (SEC_ERROR_BASE + 165),
-"Bad information access location in cert extension")
+ER3(SEC_ERROR_FAILED_TO_ENCODE_DATA, (SEC_ERROR_BASE + 164),
+ "Failed to encode data with ASN1 encoder")
-ER3(SEC_ERROR_LIBPKIX_INTERNAL, (SEC_ERROR_BASE + 166),
-"Libpkix internal error occurred during cert validation.")
+ER3(SEC_ERROR_BAD_INFO_ACCESS_LOCATION, (SEC_ERROR_BASE + 165),
+ "Bad information access location in cert extension")
-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_LIBPKIX_INTERNAL, (SEC_ERROR_BASE + 166),
+ "Libpkix internal error occurred during cert validation.")
-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_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_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_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_BAD_INFO_ACCESS_METHOD, (SEC_ERROR_BASE + 170),
-"Unknown information access method in certificate extension.")
+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_CRL_IMPORT_FAILED, (SEC_ERROR_BASE + 171),
-"Error attempting to import a CRL.")
+ER3(SEC_ERROR_BAD_INFO_ACCESS_METHOD, (SEC_ERROR_BASE + 170),
+ "Unknown information access method in certificate extension.")
-ER3(SEC_ERROR_EXPIRED_PASSWORD, (SEC_ERROR_BASE + 172),
-"The password expired.")
+ER3(SEC_ERROR_CRL_IMPORT_FAILED, (SEC_ERROR_BASE + 171),
+ "Error attempting to import a CRL.")
-ER3(SEC_ERROR_LOCKED_PASSWORD, (SEC_ERROR_BASE + 173),
-"The password is locked.")
+ER3(SEC_ERROR_EXPIRED_PASSWORD, (SEC_ERROR_BASE + 172),
+ "The password expired.")
-ER3(SEC_ERROR_UNKNOWN_PKCS11_ERROR, (SEC_ERROR_BASE + 174),
-"Unknown PKCS #11 error.")
+ER3(SEC_ERROR_LOCKED_PASSWORD, (SEC_ERROR_BASE + 173),
+ "The password is locked.")
-ER3(SEC_ERROR_BAD_CRL_DP_URL, (SEC_ERROR_BASE + 175),
-"Invalid or unsupported URL in CRL distribution point name.")
+ER3(SEC_ERROR_UNKNOWN_PKCS11_ERROR, (SEC_ERROR_BASE + 174),
+ "Unknown PKCS #11 error.")
-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_BAD_CRL_DP_URL, (SEC_ERROR_BASE + 175),
+ "Invalid or unsupported URL in CRL distribution point name.")
-ER3(SEC_ERROR_LEGACY_DATABASE, (SEC_ERROR_BASE + 177),
-"The certificate/key database is in an old, unsupported format.")
+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_APPLICATION_CALLBACK_ERROR, (SEC_ERROR_BASE + 178),
-"The certificate was rejected by extra checks in the application.")
+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/nss/lib/util/base64.h b/nss/lib/util/base64.h
index 37ca874..ddc2db6 100644
--- a/nss/lib/util/base64.h
+++ b/nss/lib/util/base64.h
@@ -25,7 +25,7 @@ extern char *BTOA_DataToAscii(const unsigned char *data, unsigned int len);
** 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.
*/
diff --git a/nss/lib/util/ciferfam.h b/nss/lib/util/ciferfam.h
index 78fc169..559e92f 100644
--- a/nss/lib/util/ciferfam.h
+++ b/nss/lib/util/ciferfam.h
@@ -12,18 +12,18 @@
#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
+#define CIPHER_FAMILY_PKCS12 "PKCS12"
+#define CIPHER_FAMILY_SMIME "SMIME"
+#define CIPHER_FAMILY_SSL2 "SSLv2" /* deprecated */
+#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" */
/*
@@ -32,28 +32,28 @@
* 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)
+#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)
+#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
+#define SMIME_LIBRARY_VERSION_1_0 -0x0100
#endif /* _CIFERFAM_H_ */
diff --git a/nss/lib/util/derdec.c b/nss/lib/util/derdec.c
index 2c17ce9..2e3312b 100644
--- a/nss/lib/util/derdec.c
+++ b/nss/lib/util/derdec.c
@@ -13,57 +13,57 @@ der_indefinite_length(unsigned char *buf, unsigned char *end)
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;
- }
+ 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;
+ }
}
}
@@ -73,7 +73,7 @@ der_indefinite_length(unsigned char *buf, unsigned char *end)
*/
static SECStatus
der_capture(unsigned char *buf, unsigned char *end,
- int *header_len_p, PRUint32 *contents_len_p)
+ int *header_len_p, PRUint32 *contents_len_p)
{
unsigned char *bp;
unsigned char whole_tag;
@@ -81,11 +81,11 @@ der_capture(unsigned char *buf, unsigned char *end,
int tag_number;
if ((buf + 2) > end) {
- *header_len_p = 0;
- *contents_len_p = 0;
- if (buf == end)
- return SECSuccess;
- return SECFailure;
+ *header_len_p = 0;
+ *contents_len_p = 0;
+ if (buf == end)
+ return SECSuccess;
+ return SECFailure;
}
bp = buf;
@@ -98,32 +98,32 @@ der_capture(unsigned char *buf, unsigned char *end,
* 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;
+ 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;
- }
+ /* 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;
+ }
}
/*
@@ -136,43 +136,43 @@ der_capture(unsigned char *buf, unsigned char *end,
* 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;
- }
+ 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;
+ /* Ran past end of buffer */
+ PORT_SetError(SEC_ERROR_BAD_DER);
+ return SECFailure;
}
*header_len_p = (int)(bp - buf);
@@ -184,6 +184,6 @@ der_capture(unsigned char *buf, unsigned char *end,
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));
+ return (der_capture(item->data, &item->data[item->len], header_len_p,
+ contents_len_p));
}
diff --git a/nss/lib/util/derenc.c b/nss/lib/util/derenc.c
index 4a02e1a..da9fc4e 100644
--- a/nss/lib/util/derenc.c
+++ b/nss/lib/util/derenc.c
@@ -79,44 +79,45 @@ header_length(DERTemplate *dtemplate, PRUint32 contents_len)
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;
+ ? PR_TRUE
+ : PR_FALSE;
- PORT_Assert (!(explicit && universal)); /* bad templates */
+ 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;
- }
+ 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;
- }
+ PORT_Assert(dtemplate->sub != NULL);
+ under_kind = dtemplate->sub->kind;
+ if (universal) {
+ encode_kind = under_kind;
+ }
} else if (universal) {
- under_kind = encode_kind;
+ under_kind = encode_kind;
} else {
- under_kind = dtemplate->arg;
+ under_kind = dtemplate->arg;
}
/* This is only used in decoding; it plays no part in encoding. */
if (under_kind & DER_DERPTR)
- return 0;
+ return 0;
/* No header at all for an "empty" optional. */
if ((contents_len == 0) && optional)
- return 0;
+ return 0;
/* And no header for a full DER_ANY. */
if (encode_kind & DER_ANY)
- return 0;
+ return 0;
/*
* The common case: one octet for identifier and as many octets
@@ -126,15 +127,15 @@ header_length(DERTemplate *dtemplate, PRUint32 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.
- */
+#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.
@@ -143,13 +144,12 @@ header_length(DERTemplate *dtemplate, PRUint32 contents_len)
PORT_Assert (under_kind != DER_SET);
#endif
- len += 1 + DER_LengthLength(len + contents_len);
+ len += 1 + DER_LengthLength(len + contents_len);
}
return len;
}
-
static PRUint32
contents_length(DERTemplate *dtemplate, void *src)
{
@@ -157,122 +157,118 @@ contents_length(DERTemplate *dtemplate, void *src)
unsigned long encode_kind, under_kind;
PRBool universal;
-
- PORT_Assert (src != NULL);
+ PORT_Assert(src != NULL);
encode_kind = dtemplate->kind;
universal = ((encode_kind & DER_CLASS_MASK) == DER_UNIVERSAL)
- ? PR_TRUE : PR_FALSE;
+ ? 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;
- }
+ 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);
+ 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;
+ under_kind = encode_kind;
} else {
- under_kind = dtemplate->arg;
+ 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);
+ 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;
+ 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;
+ 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;
+ 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)
{
@@ -281,14 +277,13 @@ der_encode(unsigned char *buf, DERTemplate *dtemplate, void *src)
unsigned long encode_kind, under_kind;
PRBool explicit, 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);
+ contents_len = contents_length(dtemplate, src);
+ header_len = header_length(dtemplate, contents_len);
/*
* Enough smarts was involved already, so that if both the
@@ -296,151 +291,144 @@ der_encode(unsigned char *buf, DERTemplate *dtemplate, void *src)
* are not doing any encoding for this element.
*/
if (header_len == 0 && contents_len == 0)
- return buf;
+ return buf;
encode_kind = dtemplate->kind;
explicit = (encode_kind & DER_EXPLICIT) ? PR_TRUE : PR_FALSE;
encode_kind &= ~DER_OPTIONAL;
universal = ((encode_kind & DER_CLASS_MASK) == DER_UNIVERSAL)
- ? PR_TRUE : PR_FALSE;
+ ? 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;
- }
+ 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);
+ 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;
+ under_kind = encode_kind;
} else {
- under_kind = dtemplate->arg;
+ under_kind = dtemplate->arg;
}
if (explicit) {
- buf = DER_StoreHeader (buf, encode_kind,
- (1 + DER_LengthLength(contents_len)
- + contents_len));
- encode_kind = under_kind;
+ 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 ((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;
+ 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;
+ 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;
+ 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(PLArenaPool *arena, SECItem *dest, DERTemplate *dtemplate, void *src)
{
@@ -453,20 +441,20 @@ DER_Encode(PLArenaPool *arena, SECItem *dest, DERTemplate *dtemplate, void *src)
* 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);
+ 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);
+ dest->data = (unsigned char *)PORT_ArenaAlloc(arena, dest->len);
if (dest->data == NULL) {
- PORT_SetError(SEC_ERROR_NO_MEMORY);
- return SECFailure;
+ PORT_SetError(SEC_ERROR_NO_MEMORY);
+ return SECFailure;
}
/* Now encode into the buffer */
- (void) der_encode (dest->data, dtemplate, src);
+ (void)der_encode(dest->data, dtemplate, src);
return SECSuccess;
}
diff --git a/nss/lib/util/dersubr.c b/nss/lib/util/dersubr.c
index 0f4c6d9..03d070a 100644
--- a/nss/lib/util/dersubr.c
+++ b/nss/lib/util/dersubr.c
@@ -10,21 +10,21 @@ 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;
- }
+ if (len > 255) {
+ if (len > 65535L) {
+ if (len > 16777215L) {
+ return 5;
+ } else {
+ return 4;
+ }
+ } else {
+ return 3;
+ }
+ } else {
+ return 2;
+ }
} else {
- return 1;
+ return 1;
}
}
@@ -37,36 +37,35 @@ DER_StoreHeader(unsigned char *buf, unsigned int code, PRUint32 len)
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;
+ 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];
- }
+ 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];
+ *buf++ = b[3];
}
return buf;
}
@@ -81,41 +80,41 @@ DER_SetInteger(PLArenaPool *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);
+ 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;
- }
+ 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;
- }
+ if (i > 32767L) {
+ if (i > 8388607L) {
+ len = 4;
+ } else {
+ len = 3;
+ }
+ } else {
+ len = 2;
+ }
} else {
- len = 1;
+ len = 1;
}
- it->data = (unsigned char*) PORT_ArenaAlloc(arena, len);
+ it->data = (unsigned char *)PORT_ArenaAlloc(arena, len);
if (!it->data) {
- return SECFailure;
+ return SECFailure;
}
it->len = len;
PORT_Memcpy(it->data, bb + (4 - len), len);
@@ -133,36 +132,36 @@ DER_SetUInteger(PLArenaPool *arena, SECItem *it, PRUint32 ui)
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);
+ 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;
- }
+ if (ui > 0x7fff) {
+ if (ui > 0x7fffffL) {
+ if (ui >= 0x80000000L) {
+ len = 5;
+ } else {
+ len = 4;
+ }
+ } else {
+ len = 3;
+ }
+ } else {
+ len = 2;
+ }
} else {
- len = 1;
+ len = 1;
}
it->data = (unsigned char *)PORT_ArenaAlloc(arena, len);
if (it->data == NULL) {
- return SECFailure;
+ return SECFailure;
}
it->len = len;
@@ -178,34 +177,38 @@ DER_SetUInteger(PLArenaPool *arena, SECItem *it, PRUint32 ui)
long
DER_GetInteger(const SECItem *it)
{
- long ival = 0;
- unsigned len = it->len;
+ unsigned long ival;
+ PRBool negative;
+ unsigned int len = it->len;
unsigned char *cp = it->data;
- unsigned long overflow = 0x1ffUL << (((sizeof(ival) - 1) * 8) - 1);
- unsigned long ofloinit;
+ size_t lsize = sizeof(ival);
PORT_Assert(len);
if (!len) {
- PORT_SetError(SEC_ERROR_INPUT_LEN);
- return 0;
+ PORT_SetError(SEC_ERROR_INPUT_LEN);
+ return 0;
}
- if (*cp & 0x80)
- ival = -1L;
- ofloinit = ival & overflow;
+ negative = (PRBool)(*cp & 0x80);
+ ival = negative ? ~0 : 0;
- 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;
+ /* Ignore leading zeros/ones. */
+ while (len && *cp == (unsigned char)ival) {
+ len--;
+ cp++;
+ }
+
+ /* Check for overflow/underflow. */
+ if (len > lsize || (len == lsize && (*cp & 0x80) != negative)) {
+ PORT_SetError(SEC_ERROR_BAD_DER);
+ return negative ? LONG_MIN : LONG_MAX;
+ }
+
+ while (len--) {
+ ival <<= 8;
+ ival |= *cp++;
}
+
return ival;
}
@@ -223,24 +226,24 @@ DER_GetUInteger(SECItem *it)
PORT_Assert(len);
if (!len) {
- PORT_SetError(SEC_ERROR_INPUT_LEN);
- return 0;
+ 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;
+ 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;
+ if (ival & overflow) {
+ PORT_SetError(SEC_ERROR_BAD_DER);
+ return ULONG_MAX;
+ }
+ ival = ival << 8;
+ ival |= *cp++;
+ --len;
}
return ival;
}
diff --git a/nss/lib/util/dertime.c b/nss/lib/util/dertime.c
index 3a27827..f58fc18 100644
--- a/nss/lib/util/dertime.c
+++ b/nss/lib/util/dertime.c
@@ -12,39 +12,40 @@
#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; \
-}
+#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);
+static const PRTime January1st1 = PR_INT64(0xff23400100d44000);
+static const PRTime January1st1950 = PR_INT64(0xfffdc1f8793da000);
+static const PRTime January1st2050 = PR_INT64(0x0008f81e1b098000);
+static const PRTime January1st10000 = PR_INT64(0x0384440ccc736000);
/* gmttime must contains UTC time in micro-seconds unit */
SECStatus
-DER_TimeToUTCTimeArena(PLArenaPool* arenaOpt, SECItem *dst, PRTime gmttime)
+DER_TimeToUTCTimeArena(PLArenaPool *arenaOpt, SECItem *dst, PRTime gmttime)
{
PRExplodedTime printableTime;
unsigned char *d;
- if ( (gmttime < January1st1950) || (gmttime >= January1st2050) ) {
+ 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);
+ dst->data = d = (unsigned char *)PORT_ArenaAlloc(arenaOpt, dst->len);
} else {
- dst->data = d = (unsigned char*) PORT_Alloc(dst->len);
+ dst->data = d = (unsigned char *)PORT_Alloc(dst->len);
}
dst->type = siUTCTime;
if (!d) {
- return SECFailure;
+ return SECFailure;
}
/* Convert a PRTime to a printable format. */
@@ -53,9 +54,9 @@ DER_TimeToUTCTimeArena(PLArenaPool* arenaOpt, SECItem *dst, PRTime gmttime)
/* The month in UTC time is base one */
printableTime.tm_month++;
- /* remove the century since it's added to the tm_year by the
+ /* 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;
+ printableTime.tm_year %= 100;
d[0] = HIDIGIT(printableTime.tm_year);
d[1] = LODIGIT(printableTime.tm_year);
@@ -80,15 +81,15 @@ DER_TimeToUTCTime(SECItem *dst, PRTime gmttime)
}
static SECStatus /* forward */
-der_TimeStringToTime(PRTime *dst, const char *string, int generalized,
- const char **endptr);
+ 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,
+** 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.
@@ -103,9 +104,9 @@ DER_AsciiToTime(PRTime *dst, const char *string)
SECStatus
DER_UTCTimeToTime(PRTime *dst, const SECItem *time)
{
- /* Minimum valid UTCTime is yymmddhhmmZ which is 11 bytes.
+ /* 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.
+ ** 20 should be large enough for all valid encoded times.
*/
unsigned int i;
char localBuf[20];
@@ -113,23 +114,23 @@ DER_UTCTimeToTime(PRTime *dst, const SECItem *time)
SECStatus rv;
if (!time || !time->data || time->len < 11 || time->len > 17) {
- PORT_SetError(SEC_ERROR_INVALID_TIME);
- return SECFailure;
+ 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];
+ 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;
+ PORT_SetError(SEC_ERROR_INVALID_TIME);
+ return SECFailure;
}
return rv;
}
@@ -140,27 +141,27 @@ DER_UTCTimeToTime(PRTime *dst, const SECItem *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.
+ certificate extension, which does not have this restriction.
*/
SECStatus
-DER_TimeToGeneralizedTimeArena(PLArenaPool* arenaOpt, SECItem *dst, PRTime gmttime)
+DER_TimeToGeneralizedTimeArena(PLArenaPool *arenaOpt, SECItem *dst, PRTime gmttime)
{
PRExplodedTime printableTime;
unsigned char *d;
- if ( (gmttime<January1st1) || (gmttime>=January1st10000) ) {
+ 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);
+ dst->data = d = (unsigned char *)PORT_ArenaAlloc(arenaOpt, dst->len);
} else {
- dst->data = d = (unsigned char*) PORT_Alloc(dst->len);
+ dst->data = d = (unsigned char *)PORT_Alloc(dst->len);
}
dst->type = siGeneralizedTime;
if (!d) {
- return SECFailure;
+ return SECFailure;
}
/* Convert a PRTime to a printable format. */
@@ -169,7 +170,7 @@ DER_TimeToGeneralizedTimeArena(PLArenaPool* arenaOpt, SECItem *dst, PRTime gmtti
/* The month in Generalized time is base one */
printableTime.tm_month++;
- d[0] = (printableTime.tm_year /1000) + '0';
+ 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';
@@ -193,13 +194,12 @@ DER_TimeToGeneralizedTime(SECItem *dst, PRTime gmttime)
return DER_TimeToGeneralizedTimeArena(NULL, dst, gmttime);
}
-
SECStatus
DER_GeneralizedTimeToTime(PRTime *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.
+ ** 20 should be large enough for all valid encoded times.
*/
unsigned int i;
char localBuf[20];
@@ -207,23 +207,23 @@ DER_GeneralizedTimeToTime(PRTime *dst, const SECItem *time)
SECStatus rv;
if (!time || !time->data || time->len < 13 || time->len > 19) {
- PORT_SetError(SEC_ERROR_INVALID_TIME);
- return SECFailure;
+ 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];
+ 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;
+ PORT_SetError(SEC_ERROR_INVALID_TIME);
+ return SECFailure;
}
return rv;
}
@@ -238,64 +238,64 @@ der_TimeStringToTime(PRTime *dst, const char *string, int generalized,
char signum;
if (string == NULL || dst == NULL) {
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- return SECFailure;
+ 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;
+ CAPTURE(genTime.tm_year, string, loser);
+ century = (genTime.tm_year < 50) ? 20 : 19;
} else {
- CAPTURE(century, string, loser);
- CAPTURE(genTime.tm_year, string, loser);
+ 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;
+ 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;
-
+ if ((genTime.tm_mday == 0) || (genTime.tm_mday > 31))
+ goto loser;
+
CAPTURE(genTime.tm_hour, string, loser);
- if (genTime.tm_hour > 23)
- goto loser;
-
+ if (genTime.tm_hour > 23)
+ goto loser;
+
CAPTURE(genTime.tm_min, string, loser);
- if (genTime.tm_min > 59)
- goto 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;
+ 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;
- }
+ 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;
+ goto loser;
}
if (endptr)
- *endptr = string;
+ *endptr = string;
/* Convert the GMT offset to seconds and save it in genTime
* for the implode time call.
diff --git a/nss/lib/util/eccutil.h b/nss/lib/util/eccutil.h
new file mode 100644
index 0000000..0d4caad
--- /dev/null
+++ b/nss/lib/util/eccutil.h
@@ -0,0 +1,14 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.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 _FREEBL_H_
+#define _FREEBL_H_
+
+/* point encoding type */
+typedef enum {
+ ECPoint_Uncompressed,
+ ECPoint_XOnly
+} ECPointEncoding;
+
+#endif /* _FREEBL_H_ */
diff --git a/nss/lib/util/errstrs.c b/nss/lib/util/errstrs.c
index a47554d..138ee39 100644
--- a/nss/lib/util/errstrs.c
+++ b/nss/lib/util/errstrs.c
@@ -12,20 +12,21 @@
#include "nssutil.h"
#include <string.h>
-#define ER3(name, value, str) {#name, str},
+#define ER3(name, value, str) { #name, str },
static const struct PRErrorMessage sectext[] = {
#include "SECerrs.h"
- {0,0}
+ { 0, 0 }
};
static const struct PRErrorTable sec_et = {
- sectext, "secerrstrings", SEC_ERROR_BASE,
- (sizeof sectext)/(sizeof sectext[0])
+ sectext, "secerrstrings", SEC_ERROR_BASE,
+ (sizeof sectext) / (sizeof sectext[0])
};
-static PRStatus
-nss_InitializePRErrorTableOnce(void) {
+static PRStatus
+nss_InitializePRErrorTableOnce(void)
+{
return PR_ErrorInstallTable(&sec_et);
}
@@ -35,6 +36,6 @@ SECStatus
NSS_InitializePRErrorTable(void)
{
return (PR_SUCCESS == PR_CallOnce(&once, nss_InitializePRErrorTableOnce))
- ? SECSuccess : SECFailure;
+ ? SECSuccess
+ : SECFailure;
}
-
diff --git a/nss/lib/util/exports.gyp b/nss/lib/util/exports.gyp
new file mode 100644
index 0000000..eb220d2
--- /dev/null
+++ b/nss/lib/util/exports.gyp
@@ -0,0 +1,67 @@
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+{
+ 'includes': [
+ '../../coreconf/config.gypi'
+ ],
+ 'targets': [
+ {
+ 'target_name': 'lib_util_exports',
+ 'type': 'none',
+ 'copies': [
+ {
+ 'files': [
+ 'base64.h',
+ 'ciferfam.h',
+ 'eccutil.h',
+ 'hasht.h',
+ 'nssb64.h',
+ 'nssb64t.h',
+ 'nssilckt.h',
+ 'nssilock.h',
+ 'nsslocks.h',
+ 'nssrwlk.h',
+ 'nssrwlkt.h',
+ 'nssutil.h',
+ 'pkcs11.h',
+ 'pkcs11f.h',
+ 'pkcs11n.h',
+ 'pkcs11p.h',
+ 'pkcs11t.h',
+ 'pkcs11u.h',
+ 'pkcs1sig.h',
+ 'portreg.h',
+ 'secasn1.h',
+ 'secasn1t.h',
+ 'seccomon.h',
+ 'secder.h',
+ 'secdert.h',
+ 'secdig.h',
+ 'secdigt.h',
+ 'secerr.h',
+ 'secitem.h',
+ 'secoid.h',
+ 'secoidt.h',
+ 'secport.h',
+ 'utilmodt.h',
+ 'utilpars.h',
+ 'utilparst.h',
+ 'utilrename.h'
+ ],
+ 'destination': '<(nss_public_dist_dir)/<(module)'
+ },
+ {
+ 'files': [
+ 'templates.c',
+ 'verref.h'
+ ],
+ 'destination': '<(nss_private_dist_dir)/<(module)'
+ }
+ ]
+ }
+ ],
+ 'variables': {
+ 'module': 'nss'
+ }
+}
diff --git a/nss/lib/util/hasht.h b/nss/lib/util/hasht.h
index 12c8040..536d34c 100644
--- a/nss/lib/util/hasht.h
+++ b/nss/lib/util/hasht.h
@@ -16,10 +16,10 @@ typedef struct HASHContextStr HASHContext;
* NOTE the order must match the definition of SECHashObjects[]!
*/
typedef enum {
- HASH_AlgNULL = 0,
- HASH_AlgMD2 = 1,
- HASH_AlgMD5 = 2,
- HASH_AlgSHA1 = 3,
+ HASH_AlgNULL = 0,
+ HASH_AlgMD2 = 1,
+ HASH_AlgMD5 = 2,
+ HASH_AlgSHA1 = 3,
HASH_AlgSHA256 = 4,
HASH_AlgSHA384 = 5,
HASH_AlgSHA512 = 6,
@@ -30,27 +30,27 @@ typedef enum {
/*
* 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 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 *);
+ 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) */
+ unsigned int blocklength; /* hash input block size (in bytes) */
HASH_HashType type;
void (*end_raw)(void *, unsigned char *, unsigned int *, unsigned int);
};
diff --git a/nss/lib/util/manifest.mn b/nss/lib/util/manifest.mn
index 36c2d1d..f0a9fd0 100644
--- a/nss/lib/util/manifest.mn
+++ b/nss/lib/util/manifest.mn
@@ -7,6 +7,7 @@ CORE_DEPTH = ../..
EXPORTS = \
base64.h \
ciferfam.h \
+ eccutil.h \
hasht.h \
nssb64.h \
nssb64t.h \
diff --git a/nss/lib/util/nssb64.h b/nss/lib/util/nssb64.h
index 1090744..7882c3b 100644
--- a/nss/lib/util/nssb64.h
+++ b/nss/lib/util/nssb64.h
@@ -19,13 +19,13 @@ SEC_BEGIN_PROTOS
*/
extern NSSBase64Decoder *
-NSSBase64Decoder_Create (PRInt32 (*output_fn) (void *, const unsigned char *,
- PRInt32),
- void *output_arg);
+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);
+NSSBase64Encoder_Create(PRInt32 (*output_fn)(void *, const char *, PRInt32),
+ void *output_arg);
/*
* Push data through the decoder/encoder, causing the output_fn (provided
@@ -33,12 +33,12 @@ NSSBase64Encoder_Create (PRInt32 (*output_fn) (void *, const char *, PRInt32),
*/
extern SECStatus
-NSSBase64Decoder_Update (NSSBase64Decoder *data, const char *buffer,
- PRUint32 size);
+NSSBase64Decoder_Update(NSSBase64Decoder *data, const char *buffer,
+ PRUint32 size);
extern SECStatus
-NSSBase64Encoder_Update (NSSBase64Encoder *data, const unsigned char *buffer,
- PRUint32 size);
+NSSBase64Encoder_Update(NSSBase64Encoder *data, const unsigned char *buffer,
+ PRUint32 size);
/*
* When you're done processing, call this to close the context.
@@ -47,10 +47,10 @@ NSSBase64Encoder_Update (NSSBase64Encoder *data, const unsigned char *buffer,
*/
extern SECStatus
-NSSBase64Decoder_Destroy (NSSBase64Decoder *data, PRBool abort_p);
+NSSBase64Decoder_Destroy(NSSBase64Decoder *data, PRBool abort_p);
extern SECStatus
-NSSBase64Encoder_Destroy (NSSBase64Encoder *data, PRBool abort_p);
+NSSBase64Encoder_Destroy(NSSBase64Encoder *data, PRBool abort_p);
/*
* Perform base64 decoding from an ascii string "inStr" to an Item.
@@ -66,8 +66,8 @@ NSSBase64Encoder_Destroy (NSSBase64Encoder *data, PRBool abort_p);
* 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);
+NSSBase64_DecodeBuffer(PLArenaPool *arenaOpt, SECItem *outItemOpt,
+ const char *inStr, unsigned int inLen);
/*
* Perform base64 encoding of binary data "inItem" to an ascii string.
@@ -86,8 +86,8 @@ NSSBase64_DecodeBuffer (PLArenaPool *arenaOpt, SECItem *outItemOpt,
* otherwise.
*/
extern char *
-NSSBase64_EncodeItem (PLArenaPool *arenaOpt, char *outStrOpt,
- unsigned int maxOutLen, SECItem *inItem);
+NSSBase64_EncodeItem(PLArenaPool *arenaOpt, char *outStrOpt,
+ unsigned int maxOutLen, SECItem *inItem);
SEC_END_PROTOS
diff --git a/nss/lib/util/nssb64d.c b/nss/lib/util/nssb64d.c
index 375fd50..6544393 100644
--- a/nss/lib/util/nssb64d.c
+++ b/nss/lib/util/nssb64d.c
@@ -17,16 +17,16 @@
* 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)
+ * (though I tried to choose ones that would work without modification)
* - exporting the functions (remove static declarations and add
- * to nssutil.def as necessary)
+ * 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)
+ * 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)
+ * (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",
@@ -75,8 +75,8 @@ struct PLBase64DecoderStr {
*
* Note that this definition is chosen to be compatible with PR_Write.
*/
- PRInt32 (*output_fn) (void *output_arg, const unsigned char *buf,
- PRInt32 size);
+ PRInt32 (*output_fn)(void *output_arg, const unsigned char *buf,
+ PRInt32 size);
void *output_arg;
/*
@@ -85,13 +85,12 @@ struct PLBase64DecoderStr {
* 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 */
+ 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
@@ -101,50 +100,49 @@ PR_END_EXTERN_C
* 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 */
+ /* 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 '='
-
+#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)
+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);
+ 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);
+ out[0] = (unsigned char)(num >> 16);
+ out[1] = (unsigned char)((num >> 8) & 0xFF);
+ out[2] = (unsigned char)(num & 0xFF);
return 3;
}
@@ -154,7 +152,7 @@ pl_base64_decode_4to3 (const unsigned char *in, unsigned char *out)
* Returns bytes written; -1 on error (unexpected character).
*/
static int
-pl_base64_decode_3to2 (const unsigned char *in, unsigned char *out)
+pl_base64_decode_3to2(const unsigned char *in, unsigned char *out)
{
PRUint32 num = 0;
unsigned char bits1, bits2, bits3;
@@ -164,14 +162,14 @@ pl_base64_decode_3to2 (const unsigned char *in, unsigned char *out)
bits3 = base64_codetovaluep1[in[2]];
if ((bits1 == 0) || (bits2 == 0) || (bits3 == 0))
- return -1;
+ 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);
+ out[0] = (unsigned char)(num >> 8);
+ out[1] = (unsigned char)(num & 0xFF);
return 2;
}
@@ -181,7 +179,7 @@ pl_base64_decode_3to2 (const unsigned char *in, unsigned char *out)
* Returns bytes written; -1 on error (unexpected character).
*/
static int
-pl_base64_decode_2to1 (const unsigned char *in, unsigned char *out)
+pl_base64_decode_2to1(const unsigned char *in, unsigned char *out)
{
PRUint32 num = 0;
unsigned char bits1, bits2;
@@ -190,12 +188,12 @@ pl_base64_decode_2to1 (const unsigned char *in, unsigned char *out)
bits2 = base64_codetovaluep1[in[1]];
if ((bits1 == 0) || (bits2 == 0))
- return -1;
+ return -1;
num = ((PRUint32)(bits1 - 1)) << 2;
num |= ((PRUint32)(bits2 - 1)) >> 4;
- out[0] = (unsigned char) num;
+ out[0] = (unsigned char)num;
return 1;
}
@@ -205,20 +203,20 @@ pl_base64_decode_2to1 (const unsigned char *in, unsigned char *out)
* (Writes less than 3 only at (presumed) EOF.)
*/
static int
-pl_base64_decode_token (const unsigned char *in, unsigned char *out)
+pl_base64_decode_token(const unsigned char *in, unsigned char *out)
{
if (in[3] != B64_PAD)
- return pl_base64_decode_4to3 (in, out);
+ return pl_base64_decode_4to3(in, out);
if (in[2] == B64_PAD)
- return pl_base64_decode_2to1 (in, out);
+ return pl_base64_decode_2to1(in, out);
- return pl_base64_decode_3to2 (in, out);
+ return pl_base64_decode_3to2(in, out);
}
static PRStatus
-pl_base64_decode_buffer (PLBase64Decoder *data, const unsigned char *in,
- PRUint32 length)
+pl_base64_decode_buffer(PLBase64Decoder *data, const unsigned char *in,
+ PRUint32 length)
{
unsigned char *out = data->output_buffer;
unsigned char *token = data->token;
@@ -228,52 +226,52 @@ pl_base64_decode_buffer (PLBase64Decoder *data, const unsigned char *in,
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;
+ 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;
}
/*
@@ -284,11 +282,11 @@ pl_base64_decode_buffer (PLBase64Decoder *data, const unsigned char *in,
* have bad input and give up.
*/
if (n < 0) {
- n = pl_base64_decode_token (token, out);
- if (n < 0)
- return PR_FAILURE;
+ n = pl_base64_decode_token(token, out);
+ if (n < 0)
+ return PR_FAILURE;
- out += n;
+ out += n;
}
/*
@@ -300,14 +298,14 @@ pl_base64_decode_buffer (PLBase64Decoder *data, const unsigned char *in,
* we would expect to decode, something is wrong.
*/
while (length > 0) {
- if (base64_codetovaluep1[*in] > 0)
- return PR_FAILURE;
- in++;
- length--;
+ 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);
+ data->output_length = (PRUint32)(out - data->output_buffer);
return PR_SUCCESS;
}
@@ -318,7 +316,7 @@ pl_base64_decode_buffer (PLBase64Decoder *data, const unsigned char *in,
* behind -- we will tolerate that by adding the padding for them.
*/
static PRStatus
-pl_base64_decode_flush (PLBase64Decoder *data)
+pl_base64_decode_flush(PLBase64Decoder *data)
{
int count;
@@ -328,21 +326,21 @@ pl_base64_decode_flush (PLBase64Decoder *data)
* is considered successful.)
*/
if (data->token_size == 0 || data->token[0] == B64_PAD)
- return PR_SUCCESS;
+ 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[data->token_size++] = B64_PAD;
- data->token_size = 0; /* so a subsequent flush call is a no-op */
+ 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);
+ count = pl_base64_decode_token(data->token,
+ data->output_buffer + data->output_length);
if (count < 0)
- return PR_FAILURE;
+ return PR_FAILURE;
/*
* If there is an output function, call it with this last bit of data.
@@ -350,33 +348,31 @@ pl_base64_decode_flush (PLBase64Decoder *data)
* 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;
+ 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;
+ 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)
+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
@@ -384,7 +380,7 @@ PL_Base64MaxDecodedLength (PRUint32 size)
* of the decoding context needs to be done, it should be done *here*.
*/
static PLBase64Decoder *
-pl_base64_create_decoder (void)
+pl_base64_create_decoder(void)
{
return PR_NEWZAP(PLBase64Decoder);
}
@@ -394,119 +390,116 @@ pl_base64_create_decoder (void)
* 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)
+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;
+ PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0);
+ return NULL;
}
- data = pl_base64_create_decoder ();
+ data = pl_base64_create_decoder();
if (data != NULL) {
- data->output_fn = output_fn;
- data->output_arg = output_arg;
+ 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)
+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;
+ 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);
+ 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;
+ 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)
+ 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;
+ if (output_buffer == NULL)
+ return PR_FAILURE;
- data->output_buffer = output_buffer;
- data->output_buflen = need_length;
+ 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);
+ 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;
+ 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)
+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;
+ 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);
+ status = pl_base64_decode_flush(data);
if (data->output_buffer != NULL)
- PR_Free(data->output_buffer);
+ 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
@@ -520,8 +513,8 @@ PL_DestroyBase64Decoder (PLBase64Decoder *data, PRBool abort_p)
* otherwise.
*/
static unsigned char *
-PL_Base64DecodeBuffer (const char *src, PRUint32 srclen, unsigned char *dest,
- PRUint32 maxdestlen, PRUint32 *output_destlen)
+PL_Base64DecodeBuffer(const char *src, PRUint32 srclen, unsigned char *dest,
+ PRUint32 maxdestlen, PRUint32 *output_destlen)
{
PRUint32 need_length;
unsigned char *output_buffer = NULL;
@@ -530,71 +523,70 @@ PL_Base64DecodeBuffer (const char *src, PRUint32 srclen, unsigned char *dest,
PR_ASSERT(srclen > 0);
if (srclen == 0) {
- PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0);
- return NULL;
+ 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);
+ 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;
+ 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;
+ 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;
+ goto loser;
data->output_buflen = maxdestlen;
data->output_buffer = output_buffer;
- status = pl_base64_decode_buffer (data, (const unsigned char *) src,
- srclen);
+ 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);
+ 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;
+ *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);
+ PR_Free(output_buffer);
if (data != NULL)
- (void) PL_DestroyBase64Decoder (data, PR_TRUE);
+ (void)PL_DestroyBase64Decoder(data, PR_TRUE);
return NULL;
}
-
/*
* XXX End of base64 decoding code to be moved into NSPR.
********************************************************
@@ -607,7 +599,6 @@ loser:
* we want to do, etc.
*/
-
PR_BEGIN_EXTERN_C
/*
@@ -620,84 +611,80 @@ struct NSSBase64DecoderStr {
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)
+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;
+ return NULL;
- pl_data = PL_CreateBase64Decoder (output_fn, output_arg);
+ pl_data = PL_CreateBase64Decoder(output_fn, output_arg);
if (pl_data == NULL) {
- PORT_Free(nss_data);
- return 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)
+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;
+ PORT_SetError(SEC_ERROR_INVALID_ARGS);
+ return SECFailure;
}
- pr_status = PL_UpdateBase64Decoder (data->pl_data, buffer, size);
+ pr_status = PL_UpdateBase64Decoder(data->pl_data, buffer, size);
if (pr_status == PR_FAILURE)
- return SECFailure;
+ 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)
+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;
+ PORT_SetError(SEC_ERROR_INVALID_ARGS);
+ return SECFailure;
}
- pr_status = PL_DestroyBase64Decoder (data->pl_data, abort_p);
+ pr_status = PL_DestroyBase64Decoder(data->pl_data, abort_p);
PORT_Free(data);
if (pr_status == PR_FAILURE)
- return SECFailure;
+ 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
@@ -712,8 +699,8 @@ NSSBase64Decoder_Destroy (NSSBase64Decoder *data, PRBool abort_p)
* Return value is NULL on error, the Item (allocated or provided) otherwise.
*/
SECItem *
-NSSBase64_DecodeBuffer (PLArenaPool *arenaOpt, SECItem *outItemOpt,
- const char *inStr, unsigned int inLen)
+NSSBase64_DecodeBuffer(PLArenaPool *arenaOpt, SECItem *outItemOpt,
+ const char *inStr, unsigned int inLen)
{
SECItem *out_item = NULL;
PRUint32 max_out_len = 0;
@@ -722,44 +709,43 @@ NSSBase64_DecodeBuffer (PLArenaPool *arenaOpt, SECItem *outItemOpt,
unsigned char *dummy;
if ((outItemOpt != NULL && outItemOpt->data != NULL) || inLen == 0) {
- PORT_SetError (SEC_ERROR_INVALID_ARGS);
- return NULL;
+ PORT_SetError(SEC_ERROR_INVALID_ARGS);
+ return NULL;
}
if (arenaOpt != NULL)
- mark = PORT_ArenaMark (arenaOpt);
+ mark = PORT_ArenaMark(arenaOpt);
- max_out_len = PL_Base64MaxDecodedLength (inLen);
- out_item = SECITEM_AllocItem (arenaOpt, outItemOpt, max_out_len);
+ 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;
+ if (arenaOpt != NULL)
+ PORT_ArenaRelease(arenaOpt, mark);
+ return NULL;
}
- dummy = PL_Base64DecodeBuffer (inStr, inLen, out_item->data,
- max_out_len, &out_len);
+ 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_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);
+ 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.
@@ -792,17 +778,17 @@ ATOB_AsciiToData(const char *string, unsigned int *lenp)
binary_item.data = NULL;
binary_item.len = 0;
- dummy = NSSBase64_DecodeBuffer (NULL, &binary_item, string,
- (PRUint32) PORT_Strlen(string));
+ dummy = NSSBase64_DecodeBuffer(NULL, &binary_item, string,
+ (PRUint32)PORT_Strlen(string));
if (dummy == NULL)
- return NULL;
+ return NULL;
PORT_Assert(dummy == &binary_item);
*lenp = dummy->len;
return dummy->data;
}
-
+
/*
** Convert from ascii to binary encoding of an item.
*/
@@ -812,8 +798,8 @@ ATOB_ConvertAsciiToItem(SECItem *binary_item, const char *ascii)
SECItem *dummy;
if (binary_item == NULL) {
- PORT_SetError (SEC_ERROR_INVALID_ARGS);
- return SECFailure;
+ PORT_SetError(SEC_ERROR_INVALID_ARGS);
+ return SECFailure;
}
/*
@@ -826,11 +812,11 @@ ATOB_ConvertAsciiToItem(SECItem *binary_item, const char *ascii)
binary_item->data = NULL;
binary_item->len = 0;
- dummy = NSSBase64_DecodeBuffer (NULL, binary_item, ascii,
- (PRUint32) PORT_Strlen(ascii));
+ dummy = NSSBase64_DecodeBuffer(NULL, binary_item, ascii,
+ (PRUint32)PORT_Strlen(ascii));
if (dummy == NULL)
- return SECFailure;
+ return SECFailure;
return SECSuccess;
}
diff --git a/nss/lib/util/nssb64e.c b/nss/lib/util/nssb64e.c
index 5959982..50402c3 100644
--- a/nss/lib/util/nssb64e.c
+++ b/nss/lib/util/nssb64e.c
@@ -15,14 +15,13 @@
* 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;
@@ -74,7 +73,7 @@ struct PLBase64EncoderStr {
* 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;
@@ -84,7 +83,7 @@ struct PLBase64EncoderStr {
*
* Note that this definition is chosen to be compatible with PR_Write.
*/
- PRInt32 (*output_fn) (void *output_arg, const char *buf, PRInt32 size);
+ PRInt32 (*output_fn)(void *output_arg, const char *buf, PRInt32 size);
void *output_arg;
/*
@@ -93,26 +92,25 @@ struct PLBase64EncoderStr {
* 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 */
+ 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'
+#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)
+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;
@@ -123,31 +121,31 @@ pl_base64_encode_buffer (PLBase64Encoder *data, const unsigned char *in,
/* 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;
+ 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;
+ 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;
+ 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;
@@ -157,123 +155,122 @@ pl_base64_encode_buffer (PLBase64Encoder *data, const unsigned char *in,
* 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;
- }
- }
- }
+ 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)
+pl_base64_encode_flush(PLBase64Encoder *data)
{
int i = data->in_buffer_count;
if (i == 0 && data->output_length == 0)
- return PR_SUCCESS;
+ 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;
+ 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;
+ PRInt32 output_result;
- output_result = data->output_fn (data->output_arg, data->output_buffer,
- (PRInt32) data->output_length);
- data->output_length = 0;
+ 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;
+ 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
@@ -281,29 +278,28 @@ pl_base64_encode_flush (PLBase64Encoder *data)
* There is no trailing CRLF.
*/
static PRUint32
-PL_Base64MaxEncodedLength (PRUint32 size, PRUint32 line_length)
+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;
+ return tokens * 4;
- if (line_length < 4) /* too small! */
- line_length = 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;
+ 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
@@ -315,35 +311,35 @@ PL_Base64MaxEncodedLength (PRUint32 size, PRUint32 line_length)
* 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)
+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;
+ return NULL;
- if (line_length > 0 && line_length < 4) /* too small! */
- line_length = 4;
+ 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;
- }
+ 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;
@@ -360,19 +356,19 @@ pl_base64_create_encoder (PRUint32 line_length, char *output_buffer,
* 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)
+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;
+ PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0);
+ return NULL;
}
- data = pl_base64_create_encoder (line_length, NULL, 0);
+ data = pl_base64_create_encoder(line_length, NULL, 0);
if (data == NULL)
- return NULL;
+ return NULL;
data->output_fn = output_fn;
data->output_arg = output_arg;
@@ -380,53 +376,50 @@ PL_CreateBase64Encoder (PRInt32 (*output_fn) (void *, const char *, PRInt32),
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)
+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;
+ PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0);
+ return PR_FAILURE;
}
- return pl_base64_encode_buffer (data, buffer, size);
+ 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)
+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;
+ 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);
+ status = pl_base64_encode_flush(data);
if (data->output_buffer != NULL)
- PR_Free(data->output_buffer);
+ 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
@@ -445,9 +438,9 @@ PL_DestroyBase64Encoder (PLBase64Encoder *data, PRBool abort_p)
* otherwise.
*/
static char *
-PL_Base64EncodeBuffer (const unsigned char *src, PRUint32 srclen,
- PRUint32 line_length, char *dest, PRUint32 maxdestlen,
- PRUint32 *output_destlen)
+PL_Base64EncodeBuffer(const unsigned char *src, PRUint32 srclen,
+ PRUint32 line_length, char *dest, PRUint32 maxdestlen,
+ PRUint32 *output_destlen)
{
PRUint32 need_length;
PLBase64Encoder *data = NULL;
@@ -455,42 +448,42 @@ PL_Base64EncodeBuffer (const unsigned char *src, PRUint32 srclen,
PR_ASSERT(srclen > 0);
if (srclen == 0)
- return dest;
+ return dest;
/*
* How much space could we possibly need for encoding this input?
*/
- need_length = PL_Base64MaxEncodedLength (srclen, line_length);
+ 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;
- }
+ PR_ASSERT(maxdestlen >= need_length);
+ if (maxdestlen < need_length) {
+ PR_SetError(PR_BUFFER_OVERFLOW_ERROR, 0);
+ return NULL;
+ }
} else {
- maxdestlen = need_length;
+ maxdestlen = need_length;
}
data = pl_base64_create_encoder(line_length, dest, maxdestlen);
if (data == NULL)
- return NULL;
+ return NULL;
- status = pl_base64_encode_buffer (data, src, srclen);
+ 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);
+ status = pl_base64_encode_flush(data);
if (status != PR_SUCCESS) {
- (void) PL_DestroyBase64Encoder (data, PR_TRUE);
- return NULL;
+ (void)PL_DestroyBase64Encoder(data, PR_TRUE);
+ return NULL;
}
dest = data->output_buffer;
@@ -499,10 +492,10 @@ PL_Base64EncodeBuffer (const unsigned char *src, PRUint32 srclen,
data->output_buffer = NULL;
*output_destlen = data->output_length;
- status = PL_DestroyBase64Encoder (data, PR_FALSE);
+ status = PL_DestroyBase64Encoder(data, PR_FALSE);
if (status == PR_FAILURE) {
- PR_Free(dest);
- return NULL;
+ PR_Free(dest);
+ return NULL;
}
return dest;
@@ -520,7 +513,6 @@ PL_Base64EncodeBuffer (const unsigned char *src, PRUint32 srclen,
* we want to do, etc.
*/
-
PR_BEGIN_EXTERN_C
/*
@@ -533,83 +525,79 @@ struct NSSBase64EncoderStr {
PR_END_EXTERN_C
-
/*
* Function to start a base64 encoding context.
*/
NSSBase64Encoder *
-NSSBase64Encoder_Create (PRInt32 (*output_fn) (void *, const char *, PRInt32),
- void *output_arg)
+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;
+ return NULL;
- pl_data = PL_CreateBase64Encoder (output_fn, output_arg, 64);
+ pl_data = PL_CreateBase64Encoder(output_fn, output_arg, 64);
if (pl_data == NULL) {
- PORT_Free(nss_data);
- return 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)
+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;
+ PORT_SetError(SEC_ERROR_INVALID_ARGS);
+ return SECFailure;
}
- pr_status = PL_UpdateBase64Encoder (data->pl_data, buffer, size);
+ pr_status = PL_UpdateBase64Encoder(data->pl_data, buffer, size);
if (pr_status == PR_FAILURE)
- return SECFailure;
+ 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)
+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;
+ PORT_SetError(SEC_ERROR_INVALID_ARGS);
+ return SECFailure;
}
- pr_status = PL_DestroyBase64Encoder (data->pl_data, abort_p);
+ pr_status = PL_DestroyBase64Encoder(data->pl_data, abort_p);
PORT_Free(data);
if (pr_status == PR_FAILURE)
- return SECFailure;
+ 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
@@ -627,8 +615,8 @@ NSSBase64Encoder_Destroy (NSSBase64Encoder *data, PRBool abort_p)
* otherwise.
*/
char *
-NSSBase64_EncodeItem (PLArenaPool *arenaOpt, char *outStrOpt,
- unsigned int maxOutLen, SECItem *inItem)
+NSSBase64_EncodeItem(PLArenaPool *arenaOpt, char *outStrOpt,
+ unsigned int maxOutLen, SECItem *inItem)
{
char *out_string = outStrOpt;
PRUint32 max_out_len;
@@ -638,54 +626,52 @@ NSSBase64_EncodeItem (PLArenaPool *arenaOpt, char *outStrOpt,
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;
+ PORT_SetError(SEC_ERROR_INVALID_ARGS);
+ return NULL;
}
- max_out_len = PL_Base64MaxEncodedLength (inItem->len, 64);
+ max_out_len = PL_Base64MaxEncodedLength(inItem->len, 64);
if (arenaOpt != NULL)
- mark = PORT_ArenaMark (arenaOpt);
+ 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;
- }
+ 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;
+ 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);
+ 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_ArenaRelease(arenaOpt, mark);
+ } else {
+ PORT_Free(out_string);
+ }
+ return NULL;
}
if (arenaOpt != NULL)
- PORT_ArenaUnmark (arenaOpt, mark);
+ 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.
@@ -718,14 +704,14 @@ BTOA_DataToAscii(const unsigned char *data, unsigned int len)
binary_item.data = (unsigned char *)data;
binary_item.len = len;
- return NSSBase64_EncodeItem (NULL, NULL, 0, &binary_item);
+ return NSSBase64_EncodeItem(NULL, NULL, 0, &binary_item);
}
/*
** Convert from binary encoding of an item to ascii.
*/
char *
-BTOA_ConvertItemToAscii (SECItem *binary_item)
+BTOA_ConvertItemToAscii(SECItem *binary_item)
{
- return NSSBase64_EncodeItem (NULL, NULL, 0, binary_item);
+ return NSSBase64_EncodeItem(NULL, NULL, 0, binary_item);
}
diff --git a/nss/lib/util/nssilckt.h b/nss/lib/util/nssilckt.h
index 7108e0c..417f96f 100644
--- a/nss/lib/util/nssilckt.h
+++ b/nss/lib/util/nssilckt.h
@@ -13,8 +13,8 @@
** 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
+**
+** 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.
@@ -56,28 +56,28 @@
** 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
@@ -85,13 +85,13 @@
** 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.
-**
+**
*/
/*
@@ -122,12 +122,12 @@ typedef enum {
nssILockFreelist = 11,
nssILockOID = 12,
nssILockAttribute = 13,
- nssILockPK11cxt = 14, /* pk11context */
+ nssILockPK11cxt = 14, /* pk11context */
nssILockRWLock = 15,
nssILockOther = 16,
nssILockSelfServ = 17,
nssILockKeyDB = 18,
- nssILockLast /* don't use this one! */
+ nssILockLast /* don't use this one! */
} nssILockType;
/*
@@ -139,7 +139,7 @@ typedef enum {
** Declare operation type enumerator
** enumerations identify the function being performed
*/
-typedef enum {
+typedef enum {
FlushTT = 0,
NewLock = 1,
Lock = 2,
@@ -163,14 +163,14 @@ typedef enum {
** 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 */
+ 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 */
};
/*
@@ -182,10 +182,10 @@ typedef struct pzmonitor_s PZMonitor;
#else /* NEED_NSS_ILOCK */
-#define PZLock PRLock
-#define PZCondVar PRCondVar
-#define PZMonitor PRMonitor
-
+#define PZLock PRLock
+#define PZCondVar PRCondVar
+#define PZMonitor PRMonitor
+
#endif /* NEED_NSS_ILOCK */
#endif /* _NSSILCKT_H_ */
diff --git a/nss/lib/util/nssilock.c b/nss/lib/util/nssilock.c
index 2799635..d767209 100644
--- a/nss/lib/util/nssilock.c
+++ b/nss/lib/util/nssilock.c
@@ -28,19 +28,19 @@
#include "nssilock.h"
/*
-** Declare the instrumented PZLock
+** Declare the instrumented PZLock
*/
struct pzlock_s {
- PRLock *lock; /* the PZLock to be instrumented */
+ PRLock *lock; /* the PZLock to be instrumented */
PRIntervalTime time; /* timestamp when the lock was aquired */
nssILockType ltype;
};
/*
-** Declare the instrumented PZMonitor
+** Declare the instrumented PZMonitor
*/
struct pzmonitor_s {
- PRMonitor *mon; /* the PZMonitor to be instrumented */
+ PRMonitor *mon; /* the PZMonitor to be instrumented */
PRIntervalTime time; /* timestamp when the monitor was aquired */
nssILockType ltype;
};
@@ -48,27 +48,25 @@ struct pzmonitor_s {
/*
** Declare the instrumented PZCondVar
*/
-struct pzcondvar_s {
- PRCondVar *cvar; /* the PZCondVar to be instrumented */
+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 */
-
+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 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 */
+static PRLock *ttLock;
+static PRFileDesc *ttfd; /* trace table file */
/*
** Vtrace() -- Trace events, write events to external media
@@ -80,32 +78,33 @@ static PRFileDesc *ttfd; /* trace table file */
** data can be lost!
**
*/
-static void Vtrace(
- nssILockOp op,
- nssILockType ltype,
- PRIntervalTime callTime,
- PRIntervalTime heldTime,
- void *lock,
- PRIntn line,
- char *file
-) {
+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 ) {
+ 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 );
+ PR_Write(ttfd, tt, writeSize);
traceIndex = -1;
- PR_NotifyAllCondVar( ttCVar );
+ PR_NotifyAllCondVar(ttCVar);
PR_Unlock(ttLock);
goto RetryTrace;
} else {
PR_Lock(ttLock);
- while( NUM_TT_ENTRIES < idx )
+ while (NUM_TT_ENTRIES < idx)
PR_WaitCondVar(ttCVar, PR_INTERVAL_NO_WAIT);
PR_Unlock(ttLock);
goto RetryTrace;
@@ -120,8 +119,8 @@ RetryTrace:
tp->callTime = callTime;
tp->heldTime = heldTime;
tp->lock = lock;
- tp ->line = line;
- strcpy(tp->file, file );
+ tp->line = line;
+ strcpy(tp->file, file);
return;
} /* --- end Vtrace() --- */
@@ -129,9 +128,10 @@ RetryTrace:
** pz_TraceFlush() -- Force trace table write to file
**
*/
-extern void pz_TraceFlush( void )
+extern void
+pz_TraceFlush(void)
{
- Vtrace( FlushTT, nssILockSelfServ, 0, 0, NULL, 0, "" );
+ Vtrace(FlushTT, nssILockSelfServ, 0, 0, NULL, 0, "");
return;
} /* --- end pz_TraceFlush() --- */
@@ -141,357 +141,338 @@ extern void pz_TraceFlush( void )
** This function is called from the CallOnce mechanism.
*/
static PRStatus
- nssILockInit( void )
-{
+nssILockInit(void)
+{
int i;
nssILockInitialized = 1;
/* new log module */
nssILog = PR_NewLogModule("nssilock");
- if ( NULL == nssILog ) {
- return(PR_FAILURE);
+ if (NULL == nssILog) {
+ return (PR_FAILURE);
}
- tt = PR_Calloc( NUM_TT_ENTRIES, sizeof(struct pzTrace_s));
- if (NULL == tt ) {
+ 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");
+ 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);
+ return (PR_SUCCESS);
} /* --- end nssILockInit() --- */
-extern PZLock * pz_NewLock(
+extern PZLock *
+pz_NewLock(
nssILockType ltype,
- char *file,
- PRIntn line )
+ char *file,
+ PRIntn line)
{
PRStatus rc;
- PZLock *lock;
-
+ 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 );
+ 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 = PR_NEWZAP(PZLock);
+ if (NULL != lock) {
lock->ltype = ltype;
lock->lock = PR_NewLock();
- if ( NULL == lock->lock ) {
- PR_DELETE( lock );
+ if (NULL == lock->lock) {
+ PR_DELETE(lock);
PORT_SetError(SEC_ERROR_NO_MEMORY);
}
} else {
- PORT_SetError(SEC_ERROR_NO_MEMORY);
+ PORT_SetError(SEC_ERROR_NO_MEMORY);
}
- Vtrace( NewLock, ltype, 0, 0, lock, line, file );
- return(lock);
+ Vtrace(NewLock, ltype, 0, 0, lock, line, file);
+ return (lock);
} /* --- end pz_NewLock() --- */
extern void
- pz_Lock(
- PZLock *lock,
- char *file,
- PRIntn line
- )
-{
+pz_Lock(
+ PZLock *lock,
+ char *file,
+ PRIntn line)
+{
PRIntervalTime callTime;
callTime = PR_IntervalNow();
- PR_Lock( lock->lock );
+ PR_Lock(lock->lock);
lock->time = PR_IntervalNow();
callTime = lock->time - callTime;
- Vtrace( Lock, lock->ltype, callTime, 0, lock, line, file );
+ Vtrace(Lock, lock->ltype, callTime, 0, lock, line, file);
return;
} /* --- end pz_Lock() --- */
extern PRStatus
- pz_Unlock(
- PZLock *lock,
- char *file,
- PRIntn line
- )
+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();
+ 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 );
+ Vtrace(Unlock, lock->ltype, callTime, heldTime, lock, line, file);
+ return (rc);
} /* --- end pz_Unlock() --- */
extern void
- pz_DestroyLock(
- PZLock *lock,
- char *file,
- PRIntn line
- )
+pz_DestroyLock(
+ PZLock *lock,
+ char *file,
+ PRIntn line)
{
- Vtrace( DestroyLock, lock->ltype, 0, 0, lock, line, file );
- PR_DestroyLock( lock->lock );
- PR_DELETE( lock );
+ 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
- )
+pz_NewCondVar(
+ PZLock *lock,
+ char *file,
+ PRIntn line)
{
PZCondVar *cvar;
- cvar = PR_NEWZAP( PZCondVar );
- if ( NULL == 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 );
+ 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 );
+ Vtrace(NewCondVar, lock->ltype, 0, 0, cvar, line, file);
+ return (cvar);
} /* --- end pz_NewCondVar() --- */
extern void
- pz_DestroyCondVar(
- PZCondVar *cvar,
- char *file,
- PRIntn line
- )
+pz_DestroyCondVar(
+ PZCondVar *cvar,
+ char *file,
+ PRIntn line)
{
- Vtrace( DestroyCondVar, cvar->ltype, 0, 0, cvar, line, file );
- PR_DestroyCondVar( cvar->cvar );
- PR_DELETE( cvar );
+ 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
- )
+pz_WaitCondVar(
+ PZCondVar *cvar,
+ PRIntervalTime timeout,
+ char *file,
+ PRIntn line)
{
- PRStatus rc;
+ PRStatus rc;
PRIntervalTime callTime;
callTime = PR_IntervalNow();
- rc = PR_WaitCondVar( cvar->cvar, timeout );
+ rc = PR_WaitCondVar(cvar->cvar, timeout);
callTime = PR_IntervalNow() - callTime;
-
- Vtrace( WaitCondVar, cvar->ltype, callTime, 0, cvar, line, file );
- return(rc);
+
+ Vtrace(WaitCondVar, cvar->ltype, callTime, 0, cvar, line, file);
+ return (rc);
} /* --- end pz_WaitCondVar() --- */
extern PRStatus
- pz_NotifyCondVar(
- PZCondVar *cvar,
- char *file,
- PRIntn line
- )
+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);
+ 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
- )
+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);
+ 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
- )
+pz_NewMonitor(
+ nssILockType ltype,
+ char *file,
+ PRIntn line)
{
PRStatus rc;
- PZMonitor *mon;
+ 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 );
+ 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 = PR_NEWZAP(PZMonitor);
+ if (NULL != mon) {
mon->ltype = ltype;
mon->mon = PR_NewMonitor();
- if ( NULL == mon->mon ) {
- PR_DELETE( mon );
+ 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);
+ Vtrace(NewMonitor, ltype, 0, 0, mon, line, file);
+ return (mon);
} /* --- end pz_NewMonitor() --- */
extern void
- pz_DestroyMonitor(
- PZMonitor *mon,
- char *file,
- PRIntn line
- )
+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;
+ 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
- )
+pz_EnterMonitor(
+ PZMonitor *mon,
+ char *file,
+ PRIntn line)
{
PRIntervalTime callTime, now;
callTime = PR_IntervalNow();
- PR_EnterMonitor( mon->mon );
+ PR_EnterMonitor(mon->mon);
now = PR_IntervalNow();
callTime = now - callTime;
- if ( PR_GetMonitorEntryCount(mon->mon) == 1 ) {
+ if (PR_GetMonitorEntryCount(mon->mon) == 1) {
mon->time = now;
}
- Vtrace( EnterMonitor, mon->ltype, callTime, 0, mon, line, file );
+ Vtrace(EnterMonitor, mon->ltype, callTime, 0, mon, line, file);
return;
} /* --- end pz_EnterMonitor() --- */
extern PRStatus
- pz_ExitMonitor(
- PZMonitor *mon,
- char *file,
- PRIntn line
- )
+pz_ExitMonitor(
+ PZMonitor *mon,
+ char *file,
+ PRIntn line)
{
PRStatus rc;
PRIntervalTime callTime, now, heldTime;
- PRIntn mec = PR_GetMonitorEntryCount( mon->mon );
-
- heldTime = (PRIntervalTime)-1;
+ PRIntn mec = PR_GetMonitorEntryCount(mon->mon);
+
+ heldTime = (PRIntervalTime)-1;
callTime = PR_IntervalNow();
- rc = PR_ExitMonitor( mon->mon );
+ rc = PR_ExitMonitor(mon->mon);
now = PR_IntervalNow();
callTime = now - callTime;
- if ( mec == 1 )
+ if (mec == 1)
heldTime = now - mon->time;
- Vtrace( ExitMonitor, mon->ltype, callTime, heldTime, mon, line, file );
- return( rc );
+ Vtrace(ExitMonitor, mon->ltype, callTime, heldTime, mon, line, file);
+ return (rc);
} /* --- end pz_ExitMonitor() --- */
extern PRIntn
- pz_GetMonitorEntryCount(
- PZMonitor *mon,
- char *file,
- PRIntn line
- )
+pz_GetMonitorEntryCount(
+ PZMonitor *mon,
+ char *file,
+ PRIntn line)
{
- return( PR_GetMonitorEntryCount(mon->mon));
+ return (PR_GetMonitorEntryCount(mon->mon));
} /* --- end pz_GetMonitorEntryCount() --- */
-
extern PRStatus
- pz_Wait(
- PZMonitor *mon,
- PRIntervalTime ticks,
- char *file,
- PRIntn line
- )
+pz_Wait(
+ PZMonitor *mon,
+ PRIntervalTime ticks,
+ char *file,
+ PRIntn line)
{
PRStatus rc;
PRIntervalTime callTime;
callTime = PR_IntervalNow();
- rc = PR_Wait( mon->mon, ticks );
+ rc = PR_Wait(mon->mon, ticks);
callTime = PR_IntervalNow() - callTime;
- Vtrace( Wait, mon->ltype, callTime, 0, mon, line, file );
- return( rc );
+ Vtrace(Wait, mon->ltype, callTime, 0, mon, line, file);
+ return (rc);
} /* --- end pz_Wait() --- */
extern PRStatus
- pz_Notify(
- PZMonitor *mon,
- char *file,
- PRIntn line
- )
+pz_Notify(
+ PZMonitor *mon,
+ char *file,
+ PRIntn line)
{
PRStatus rc;
PRIntervalTime callTime;
callTime = PR_IntervalNow();
- rc = PR_Notify( mon->mon );
+ rc = PR_Notify(mon->mon);
callTime = PR_IntervalNow() - callTime;
- Vtrace( Notify, mon->ltype, callTime, 0, mon, line, file );
- return( rc );
+ Vtrace(Notify, mon->ltype, callTime, 0, mon, line, file);
+ return (rc);
} /* --- end pz_Notify() --- */
extern PRStatus
- pz_NotifyAll(
- PZMonitor *mon,
- char *file,
- PRIntn line
- )
+pz_NotifyAll(
+ PZMonitor *mon,
+ char *file,
+ PRIntn line)
{
PRStatus rc;
PRIntervalTime callTime;
callTime = PR_IntervalNow();
- rc = PR_NotifyAll( mon->mon );
+ rc = PR_NotifyAll(mon->mon);
callTime = PR_IntervalNow() - callTime;
- Vtrace( NotifyAll, mon->ltype, callTime, 0, mon, line, file );
- return( rc );
+ Vtrace(NotifyAll, mon->ltype, callTime, 0, mon, line, file);
+ return (rc);
} /* --- end pz_NotifyAll() --- */
#endif /* NEED_NSS_ILOCK */
diff --git a/nss/lib/util/nssilock.h b/nss/lib/util/nssilock.h
index a796e4a..01f666a 100644
--- a/nss/lib/util/nssilock.h
+++ b/nss/lib/util/nssilock.h
@@ -13,8 +13,8 @@
** 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
+**
+** 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.
@@ -56,28 +56,28 @@
** 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
@@ -85,13 +85,13 @@
** 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.
-**
+**
*/
/*
@@ -113,175 +113,154 @@ 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_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__)
+#define PZ_Lock(k) pz_Lock((k), __FILE__, __LINE__)
extern void
- pz_Lock(
- PZLock *lock,
- char *file,
- PRIntn line
- );
+pz_Lock(
+ PZLock *lock,
+ char *file,
+ PRIntn line);
-#define PZ_Unlock(k) pz_Unlock((k),__FILE__,__LINE__)
+#define PZ_Unlock(k) pz_Unlock((k), __FILE__, __LINE__)
extern PRStatus
- pz_Unlock(
- PZLock *lock,
- char *file,
- PRIntn line
- );
+pz_Unlock(
+ PZLock *lock,
+ char *file,
+ PRIntn line);
-#define PZ_DestroyLock(k) pz_DestroyLock((k),__FILE__,__LINE__)
+#define PZ_DestroyLock(k) pz_DestroyLock((k), __FILE__, __LINE__)
extern void
- pz_DestroyLock(
- PZLock *lock,
- char *file,
- PRIntn line
- );
-
+pz_DestroyLock(
+ PZLock *lock,
+ char *file,
+ PRIntn line);
-#define PZ_NewCondVar(l) pz_NewCondVar((l),__FILE__,__LINE__)
+#define PZ_NewCondVar(l) pz_NewCondVar((l), __FILE__, __LINE__)
extern PZCondVar *
- pz_NewCondVar(
- PZLock *lock,
- char *file,
- PRIntn line
- );
+pz_NewCondVar(
+ PZLock *lock,
+ char *file,
+ PRIntn line);
-#define PZ_DestroyCondVar(v) pz_DestroyCondVar((v),__FILE__,__LINE__)
+#define PZ_DestroyCondVar(v) pz_DestroyCondVar((v), __FILE__, __LINE__)
extern void
- pz_DestroyCondVar(
- PZCondVar *cvar,
- char *file,
- PRIntn line
- );
+pz_DestroyCondVar(
+ PZCondVar *cvar,
+ char *file,
+ PRIntn line);
-#define PZ_WaitCondVar(v,t) pz_WaitCondVar((v),(t),__FILE__,__LINE__)
+#define PZ_WaitCondVar(v, t) pz_WaitCondVar((v), (t), __FILE__, __LINE__)
extern PRStatus
- pz_WaitCondVar(
- PZCondVar *cvar,
- PRIntervalTime timeout,
- char *file,
- PRIntn line
- );
+pz_WaitCondVar(
+ PZCondVar *cvar,
+ PRIntervalTime timeout,
+ char *file,
+ PRIntn line);
-#define PZ_NotifyCondVar(v) pz_NotifyCondVar((v),__FILE__,__LINE__)
+#define PZ_NotifyCondVar(v) pz_NotifyCondVar((v), __FILE__, __LINE__)
extern PRStatus
- pz_NotifyCondVar(
- PZCondVar *cvar,
- char *file,
- PRIntn line
- );
+pz_NotifyCondVar(
+ PZCondVar *cvar,
+ char *file,
+ PRIntn line);
-#define PZ_NotifyAllCondVar(v) pz_NotifyAllCondVar((v),__FILE__,__LINE__)
+#define PZ_NotifyAllCondVar(v) pz_NotifyAllCondVar((v), __FILE__, __LINE__)
extern PRStatus
- pz_NotifyAllCondVar(
- PZCondVar *cvar,
- char *file,
- PRIntn line
- );
+pz_NotifyAllCondVar(
+ PZCondVar *cvar,
+ char *file,
+ PRIntn line);
-
-#define PZ_NewMonitor(t) pz_NewMonitor((t),__FILE__,__LINE__)
+#define PZ_NewMonitor(t) pz_NewMonitor((t), __FILE__, __LINE__)
extern PZMonitor *
- pz_NewMonitor(
- nssILockType ltype,
- char *file,
- PRIntn line
- );
+pz_NewMonitor(
+ nssILockType ltype,
+ char *file,
+ PRIntn line);
-#define PZ_DestroyMonitor(m) pz_DestroyMonitor((m),__FILE__,__LINE__)
+#define PZ_DestroyMonitor(m) pz_DestroyMonitor((m), __FILE__, __LINE__)
extern void
- pz_DestroyMonitor(
- PZMonitor *mon,
- char *file,
- PRIntn line
- );
+pz_DestroyMonitor(
+ PZMonitor *mon,
+ char *file,
+ PRIntn line);
-#define PZ_EnterMonitor(m) pz_EnterMonitor((m),__FILE__,__LINE__)
+#define PZ_EnterMonitor(m) pz_EnterMonitor((m), __FILE__, __LINE__)
extern void
- pz_EnterMonitor(
- PZMonitor *mon,
- char *file,
- PRIntn line
- );
-
+pz_EnterMonitor(
+ PZMonitor *mon,
+ char *file,
+ PRIntn line);
-#define PZ_ExitMonitor(m) pz_ExitMonitor((m),__FILE__,__LINE__)
+#define PZ_ExitMonitor(m) pz_ExitMonitor((m), __FILE__, __LINE__)
extern PRStatus
- pz_ExitMonitor(
- PZMonitor *mon,
- char *file,
- PRIntn line
- );
+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__)
+#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
- );
+pz_GetMonitorEntryCount(
+ PZMonitor *mon,
+ char *file,
+ PRIntn line);
-#define PZ_Wait(m,i) pz_Wait((m),((i)),__FILE__,__LINE__)
+#define PZ_Wait(m, i) pz_Wait((m), ((i)), __FILE__, __LINE__)
extern PRStatus
- pz_Wait(
- PZMonitor *mon,
- PRIntervalTime ticks,
- char *file,
- PRIntn line
- );
+pz_Wait(
+ PZMonitor *mon,
+ PRIntervalTime ticks,
+ char *file,
+ PRIntn line);
-#define PZ_Notify(m) pz_Notify((m),__FILE__,__LINE__)
+#define PZ_Notify(m) pz_Notify((m), __FILE__, __LINE__)
extern PRStatus
- pz_Notify(
- PZMonitor *mon,
- char *file,
- PRIntn line
- );
+pz_Notify(
+ PZMonitor *mon,
+ char *file,
+ PRIntn line);
-#define PZ_NotifyAll(m) pz_NotifyAll((m),__FILE__,__LINE__)
+#define PZ_NotifyAll(m) pz_NotifyAll((m), __FILE__, __LINE__)
extern PRStatus
- pz_NotifyAll(
- PZMonitor *mon,
- char *file,
- PRIntn line
- );
+pz_NotifyAll(
+ PZMonitor *mon,
+ char *file,
+ PRIntn line);
#define PZ_TraceFlush() pz_TraceFlush()
-extern void pz_TraceFlush( void );
+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 */
+#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
diff --git a/nss/lib/util/nssrwlk.c b/nss/lib/util/nssrwlk.c
index fbbfbd6..dbaeca2 100644
--- a/nss/lib/util/nssrwlk.c
+++ b/nss/lib/util/nssrwlk.c
@@ -11,18 +11,18 @@ 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. */
+ 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
@@ -30,34 +30,34 @@ 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
+#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;
+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
+ 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);
+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))
+#define UNTIL(x) while (!(x))
/*
* Reader/Writer Locks
@@ -80,36 +80,36 @@ NSSRWLock_New(PRUint32 lock_rank, const char *lock_name)
rwlock->rw_lock = PZ_NewLock(nssILockRWLock);
if (rwlock->rw_lock == NULL) {
- goto loser;
+ goto loser;
}
rwlock->rw_reader_waitq = PZ_NewCondVar(rwlock->rw_lock);
if (rwlock->rw_reader_waitq == NULL) {
- goto loser;
+ goto loser;
}
rwlock->rw_writer_waitq = PZ_NewCondVar(rwlock->rw_lock);
if (rwlock->rw_writer_waitq == NULL) {
- goto loser;
+ goto loser;
}
if (lock_name != NULL) {
- rwlock->rw_name = (char*) PR_Malloc((PRUint32)strlen(lock_name) + 1);
+ rwlock->rw_name = (char *)PR_Malloc((PRUint32)strlen(lock_name) + 1);
if (rwlock->rw_name == NULL) {
- goto loser;
+ goto loser;
}
strcpy(rwlock->rw_name, lock_name);
} else {
rwlock->rw_name = NULL;
}
- rwlock->rw_rank = lock_rank;
+ 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;
+ rwlock->rw_reader_locks = 0;
+ rwlock->rw_writer_locks = 0;
return rwlock;
loser:
NSSRWLock_Destroy(rwlock);
- return(NULL);
+ return (NULL);
}
/*
@@ -124,13 +124,13 @@ NSSRWLock_Destroy(NSSRWLock *rwlock)
/* XXX Shouldn't we lock the PZLock before destroying this?? */
if (rwlock->rw_name)
- PR_Free(rwlock->rw_name);
+ PR_Free(rwlock->rw_name);
if (rwlock->rw_reader_waitq)
- PZ_DestroyCondVar(rwlock->rw_reader_waitq);
+ PZ_DestroyCondVar(rwlock->rw_reader_waitq);
if (rwlock->rw_writer_waitq)
- PZ_DestroyCondVar(rwlock->rw_writer_waitq);
+ PZ_DestroyCondVar(rwlock->rw_writer_waitq);
if (rwlock->rw_lock)
- PZ_DestroyLock(rwlock->rw_lock);
+ PZ_DestroyLock(rwlock->rw_lock);
PR_DELETE(rwlock);
}
@@ -156,20 +156,21 @@ NSSRWLock_LockRead(NSSRWLock *rwlock)
/*
* 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--;
+ 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 */
+ 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 */
+ nssRWLock_SetThreadRank(me, rwlock); /* update thread's lock rank */
#endif
}
@@ -182,12 +183,12 @@ NSSRWLock_UnlockRead(NSSRWLock *rwlock)
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. */
+ 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_NotifyCondVar(rwlock->rw_writer_waitq); /* wake him up. */
}
PZ_Unlock(rwlock->rw_lock);
@@ -217,7 +218,7 @@ NSSRWLock_LockWrite(NSSRWLock *rwlock)
* the thread.
*/
PR_ASSERT((rwlock->rw_rank == NSS_RWLOCK_RANK_NONE) ||
- (rwlock->rw_rank >= nssRWLock_GetThreadRank(me)));
+ (rwlock->rw_rank >= nssRWLock_GetThreadRank(me)));
#endif
/*
* wait if read locked or write locked.
@@ -225,14 +226,15 @@ NSSRWLock_LockWrite(NSSRWLock *rwlock)
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. */
+ 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);
}
PR_ASSERT(rwlock->rw_reader_locks == 0);
@@ -240,7 +242,7 @@ NSSRWLock_LockWrite(NSSRWLock *rwlock)
* apply write lock
*/
rwlock->rw_owner = me;
- rwlock->rw_writer_locks++; /* Increment write-lock count */
+ rwlock->rw_writer_locks++; /* Increment write-lock count */
PZ_Unlock(rwlock->rw_lock);
@@ -248,7 +250,7 @@ NSSRWLock_LockWrite(NSSRWLock *rwlock)
/*
* update thread's lock rank
*/
- nssRWLock_SetThreadRank(me,rwlock);
+ nssRWLock_SetThreadRank(me, rwlock);
#endif
}
@@ -260,22 +262,22 @@ 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_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 */
+ 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. */
+ 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);
- }
+ /* 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);
@@ -290,18 +292,19 @@ NSSRWLock_UnlockWrite(NSSRWLock *rwlock)
/* This is primarily for debugging, i.e. for inclusion in ASSERT calls. */
PRBool
-NSSRWLock_HaveWriteLock(NSSRWLock *rwlock) {
+NSSRWLock_HaveWriteLock(NSSRWLock *rwlock)
+{
PRBool ownWriteLock;
PRThread *me = PR_GetCurrentThread();
- /* This lock call isn't really necessary.
+/* 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 this thread is NOT the owner, the owner could change, but it
+ ** could not become this thread.
*/
#if UNNECESSARY
- PZ_Lock(rwlock->rw_lock);
+ PZ_Lock(rwlock->rw_lock);
#endif
ownWriteLock = (PRBool)(me == rwlock->rw_owner);
#if UNNECESSARY
@@ -334,8 +337,7 @@ nssRWLock_SetThreadRank(PRThread *me, NSSRWLock *rwlock)
*/
if (!nss_thread_rwlock_alloc_failed) {
if (PR_NewThreadPrivateIndex(&nss_thread_rwlock,
- nssRWLock_ReleaseLockStack)
- == PR_FAILURE) {
+ nssRWLock_ReleaseLockStack) == PR_FAILURE) {
nss_thread_rwlock_alloc_failed = 1;
return;
}
@@ -347,7 +349,7 @@ nssRWLock_SetThreadRank(PRThread *me, NSSRWLock *rwlock)
*/
if ((lock_stack = PR_GetThreadPrivate(nss_thread_rwlock)) == NULL) {
lock_stack = (thread_rwlock_stack *)
- PR_CALLOC(1 * sizeof(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) {
@@ -393,10 +395,10 @@ nssRWLock_GetThreadRank(PRThread *me)
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);
+ return (lock_stack->trs_stack[lock_stack->trs_index - 1]->rw_rank);
} else
- return (NSS_RWLOCK_RANK_NONE);
+ return (NSS_RWLOCK_RANK_NONE);
}
/*
@@ -421,7 +423,7 @@ nssRWLock_UnsetThreadRank(PRThread *me, NSSRWLock *rwlock)
index = lock_stack->trs_index - 1;
while (index-- >= 0) {
- if ((lock_stack->trs_stack[index] == rwlock) && !done) {
+ if ((lock_stack->trs_stack[index] == rwlock) && !done) {
/*
* reset the slot for rwlock
*/
@@ -441,7 +443,6 @@ nssRWLock_UnsetThreadRank(PRThread *me, NSSRWLock *rwlock)
* set top of stack to highest numbered empty slot
*/
lock_stack->trs_index = new_index;
-
}
-#endif /* NSS_RWLOCK_RANK_ORDER_DEBUG */
+#endif /* NSS_RWLOCK_RANK_ORDER_DEBUG */
diff --git a/nss/lib/util/nssrwlk.h b/nss/lib/util/nssrwlk.h
index 3402c82..2ae6931 100644
--- a/nss/lib/util/nssrwlk.h
+++ b/nss/lib/util/nssrwlk.h
@@ -3,14 +3,14 @@
* 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.
+** 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.
+** 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.
@@ -25,7 +25,7 @@
#include "prtypes.h"
#include "nssrwlkt.h"
-#define NSS_RWLOCK_RANK_NONE 0
+#define NSS_RWLOCK_RANK_NONE 0
/* SEC_BEGIN_PROTOS */
PR_BEGIN_EXTERN_C
@@ -35,35 +35,35 @@ PR_BEGIN_EXTERN_C
** DESCRIPTION:
** Returns a pointer to a newly created reader-writer lock object.
** INPUTS: Lock rank
-** Lock name
+** 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);
+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,
+** 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
+** Lock name
** OUTPUTS: NSSRWLock*
** RETURN: NSSRWLock*
-** If the lock cannot be created because of resource constraints,
+** 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);
+nssRWLock_AtomicCreate(NSSRWLock **prwlock,
+ PRUint32 lock_rank,
+ const char *lock_name);
/***********************************************************************
** FUNCTION: NSSRWLock_Destroy
@@ -121,7 +121,7 @@ extern void NSSRWLock_UnlockWrite(NSSRWLock *lock);
** 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.
+** RETURN: PRBool PR_TRUE IFF the current thread holds the write lock.
***********************************************************************/
extern PRBool NSSRWLock_HaveWriteLock(NSSRWLock *rwlock);
diff --git a/nss/lib/util/nssrwlkt.h b/nss/lib/util/nssrwlkt.h
index 5725103..50a4112 100644
--- a/nss/lib/util/nssrwlkt.h
+++ b/nss/lib/util/nssrwlkt.h
@@ -10,11 +10,10 @@
/*
* 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.
+ * 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/nss/lib/util/nssutil.def b/nss/lib/util/nssutil.def
index 631a499..e4a6572 100644
--- a/nss/lib/util/nssutil.def
+++ b/nss/lib/util/nssutil.def
@@ -5,13 +5,13 @@
;+#
;+# 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
+;+# 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.
+;+# 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.
+;+# 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 ";-"
@@ -283,3 +283,10 @@ NSSUTIL_ArgParseModuleSpecEx;
;+ local:
;+ *;
;+};
+;+NSSUTIL_3.24 { # NSS Utilities 3.24 release
+;+ global:
+PORT_InitCheapArena;
+PORT_DestroyCheapArena;
+;+ local:
+;+ *;
+;+};
diff --git a/nss/lib/util/nssutil.h b/nss/lib/util/nssutil.h
index 0c8b480..53b96a0 100644
--- a/nss/lib/util/nssutil.h
+++ b/nss/lib/util/nssutil.h
@@ -19,12 +19,12 @@
* The format of the version string should be
* "<major version>.<minor version>[.<patch level>[.<build number>]][ <Beta>]"
*/
-#define NSSUTIL_VERSION "3.21"
-#define NSSUTIL_VMAJOR 3
-#define NSSUTIL_VMINOR 21
-#define NSSUTIL_VPATCH 0
-#define NSSUTIL_VBUILD 0
-#define NSSUTIL_BETA PR_FALSE
+#define NSSUTIL_VERSION "3.28.1"
+#define NSSUTIL_VMAJOR 3
+#define NSSUTIL_VMINOR 28
+#define NSSUTIL_VPATCH 1
+#define NSSUTIL_VBUILD 0
+#define NSSUTIL_BETA PR_FALSE
SEC_BEGIN_PROTOS
diff --git a/nss/lib/util/oidstring.c b/nss/lib/util/oidstring.c
index 8bb963e..58c8be1 100644
--- a/nss/lib/util/oidstring.c
+++ b/nss/lib/util/oidstring.c
@@ -10,13 +10,13 @@
/* 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
+ * 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
+ * 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'.
*/
@@ -30,85 +30,85 @@ SEC_StringToOID(PLArenaPool *pool, SECItem *to, const char *from, PRUint32 len)
PRUint8 result[1024];
static const PRUint32 max_decimal = (0xffffffff / 10);
- static const char OIDstring[] = {"OID."};
+ static const char OIDstring[] = { "OID." };
if (!from || !to) {
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- return SECFailure;
+ PORT_SetError(SEC_ERROR_INVALID_ARGS);
+ return SECFailure;
}
if (!len) {
- len = PL_strlen(from);
+ len = PL_strlen(from);
}
if (len >= 4 && !PL_strncasecmp(from, OIDstring, 4)) {
- from += 4; /* skip leading "OID." if present */
- len -= 4;
+ from += 4; /* skip leading "OID." if present */
+ len -= 4;
}
if (!len) {
-bad_data:
- PORT_SetError(SEC_ERROR_BAD_DATA);
- return SECFailure;
+ bad_data:
+ PORT_SetError(SEC_ERROR_BAD_DATA);
+ return SECFailure;
}
do {
- PRUint32 decimal = 0;
+ 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;
- }
+ 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;
+ 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);
+ 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/nss/lib/util/pkcs11.h b/nss/lib/util/pkcs11.h
index 74ac250..bd98126 100644
--- a/nss/lib/util/pkcs11.h
+++ b/nss/lib/util/pkcs11.h
@@ -173,13 +173,11 @@ extern "C" {
* #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
-
+#define __PASTE(x, y) x##y
/* packing defines */
#include "pkcs11p.h"
@@ -188,9 +186,9 @@ extern "C" {
* ==============================================================
*/
-#define CK_NEED_ARG_LIST 1
+#define CK_NEED_ARG_LIST 1
#define CK_PKCS11_FUNCTION_INFO(name) \
- CK_DECLARE_FUNCTION(CK_RV, name)
+ CK_DECLARE_FUNCTION(CK_RV, name)
/* pkcs11f.h has all the information about the PKCS #11
* function prototypes. */
@@ -199,7 +197,6 @@ extern "C" {
#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
@@ -207,9 +204,9 @@ extern "C" {
* ==============================================================
*/
-#define CK_NEED_ARG_LIST 1
+#define CK_NEED_ARG_LIST 1
#define CK_PKCS11_FUNCTION_INFO(name) \
- typedef CK_DECLARE_FUNCTION_POINTER(CK_RV, __PASTE(CK_,name))
+ typedef CK_DECLARE_FUNCTION_POINTER(CK_RV, __PASTE(CK_, name))
/* pkcs11f.h has all the information about the PKCS #11
* function prototypes. */
@@ -218,7 +215,6 @@ extern "C" {
#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
@@ -229,22 +225,21 @@ extern "C" {
*/
#define CK_PKCS11_FUNCTION_INFO(name) \
- __PASTE(CK_,name) name;
-
+ __PASTE(CK_, name) \
+ name;
+
struct CK_FUNCTION_LIST {
- CK_VERSION version; /* PKCS #11 version */
+ 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"
-
+#include "pkcs11f.h"
};
#undef CK_PKCS11_FUNCTION_INFO
-
#undef __PASTE
/* unpack */
diff --git a/nss/lib/util/pkcs11f.h b/nss/lib/util/pkcs11f.h
index 732b1a1..e79e125 100644
--- a/nss/lib/util/pkcs11f.h
+++ b/nss/lib/util/pkcs11f.h
@@ -13,148 +13,132 @@
/* 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 */
-);
+ 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 */
-);
+ 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 */
-);
+ 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 */
-);
+ 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 */
-);
+ 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 */
-);
+ 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 */
-);
+ 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. */
-);
+ 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 */
-);
+ 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) */
-);
+ 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 */
-);
+ 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 */
-);
+ 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
@@ -162,369 +146,335 @@ CK_PKCS11_FUNCTION_INFO(C_SetPIN)
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 */
-);
+ 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 */
-);
+ 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 */
-);
+ 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 */
-);
+ 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 */
-);
+ 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 */
-);
+ 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 */
-);
+ 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 */
-);
+ 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. */
-);
+ 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 */
-);
+ 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 */
-);
+ 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 */
-);
+ 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 */
-);
+ 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 */
-);
+ 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 */
-);
+ 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 */
-);
+ 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 */
-);
+ 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 */
-);
+ 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 */
-);
+ 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 */
-);
+ 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 */
-);
+ 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 */
-);
+ 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 */
-);
+ 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 */
-);
+ 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 */
-);
+ 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 */
-);
+ 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 */
-);
+ 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 */
-);
+ 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 */
-);
+ 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 */
-);
+ 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)
@@ -534,80 +484,73 @@ CK_PKCS11_FUNCTION_INFO(C_DigestFinal)
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 */
-);
+ 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 */
-);
+ 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,
+ * 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 */
-);
+ 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,
+/* 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 */
-);
+ 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 */
-);
+ 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 */
-);
+ 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
@@ -616,80 +559,73 @@ CK_PKCS11_FUNCTION_INFO(C_SignRecover)
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 */
-);
+ 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,
+/* 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*/
-);
+ 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,
+ * 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 */
-);
+ 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 */
-);
+ 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 */
-);
+ 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 */
-);
+ 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
@@ -697,58 +633,53 @@ CK_PKCS11_FUNCTION_INFO(C_VerifyRecover)
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 */
-);
+ 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 */
-);
+ 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 */
-);
+ 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 */
-);
+ 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
@@ -756,91 +687,73 @@ CK_PKCS11_FUNCTION_INFO(C_DecryptVerifyUpdate)
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 */
-);
+ 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,
+/* 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 */
-);
+ 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 */
-);
+ 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 */
-);
+ 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 */
-);
+ 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
@@ -848,25 +761,22 @@ CK_PKCS11_FUNCTION_INFO(C_DeriveKey)
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 */
-);
+ 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 */
-);
+ 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
@@ -875,22 +785,19 @@ CK_PKCS11_FUNCTION_INFO(C_GenerateRandom)
CK_PKCS11_FUNCTION_INFO(C_GetFunctionStatus)
#ifdef CK_NEED_ARG_LIST
(
- CK_SESSION_HANDLE hSession /* the session's handle */
-);
+ 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 */
-);
+ 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,
@@ -898,8 +805,8 @@ CK_PKCS11_FUNCTION_INFO(C_CancelFunction)
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 */
-);
+ 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/nss/lib/util/pkcs11n.h b/nss/lib/util/pkcs11n.h
index 5e13784..ebb8122 100644
--- a/nss/lib/util/pkcs11n.h
+++ b/nss/lib/util/pkcs11n.h
@@ -30,67 +30,68 @@
* 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)
+#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 (CKK_VENDOR_DEFINED | NSSCK_VENDOR_NSS)
+
+#define CKK_NSS_PKCS8 (CKK_NSS + 1)
-#define CKK_NSS_PKCS8 (CKK_NSS + 1)
+#define CKK_NSS_JPAKE_ROUND1 (CKK_NSS + 2)
+#define CKK_NSS_JPAKE_ROUND2 (CKK_NSS + 3)
-#define CKK_NSS_JPAKE_ROUND1 (CKK_NSS + 2)
-#define CKK_NSS_JPAKE_ROUND2 (CKK_NSS + 3)
+#define CKK_NSS_CHACHA20 (CKK_NSS + 4)
/*
* NSS-defined certificate types
*
*/
-#define CKC_NSS (CKC_VENDOR_DEFINED|NSSCK_VENDOR_NSS)
+#define CKC_NSS (CKC_VENDOR_DEFINED | NSSCK_VENDOR_NSS)
/* FAKE PKCS #11 defines */
-#define CKA_DIGEST 0x81000000L
-#define CKA_FLAGS_ONLY 0 /* CKA_CLASS */
+#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)
+#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:
@@ -102,52 +103,52 @@
#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)
+#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)
+#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
+#define CKA_NETSCAPE_DB 0xD5A0DB00L
+#define CKA_NETSCAPE_TRUST 0x80000001L
/* FAKE PKCS #11 defines */
-#define CKM_FAKE_RANDOM 0x80000efeUL
+#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 (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)
+#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)
+#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.
*
@@ -158,7 +159,7 @@
* Parameter type: CK_NSS_JPAKERound1Params
*
*/
-#define CKM_NSS_JPAKE_ROUND1_SHA1 (CKM_NSS + 7)
+#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)
@@ -171,7 +172,7 @@
* 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_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)
@@ -186,10 +187,10 @@
* 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)
+#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:
*
@@ -205,44 +206,47 @@
*
* 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)
+#define CKM_NSS_HMAC_CONSTANT_TIME (CKM_NSS + 19)
+#define CKM_NSS_SSL3_MAC_CONSTANT_TIME (CKM_NSS + 20)
/* TLS 1.2 mechanisms */
-#define CKM_NSS_TLS_PRF_GENERAL_SHA256 (CKM_NSS + 21)
-#define CKM_NSS_TLS_MASTER_KEY_DERIVE_SHA256 (CKM_NSS + 22)
-#define CKM_NSS_TLS_KEY_AND_MAC_DERIVE_SHA256 (CKM_NSS + 23)
+#define CKM_NSS_TLS_PRF_GENERAL_SHA256 (CKM_NSS + 21)
+#define CKM_NSS_TLS_MASTER_KEY_DERIVE_SHA256 (CKM_NSS + 22)
+#define CKM_NSS_TLS_KEY_AND_MAC_DERIVE_SHA256 (CKM_NSS + 23)
#define CKM_NSS_TLS_MASTER_KEY_DERIVE_DH_SHA256 (CKM_NSS + 24)
/* TLS extended master secret derivation */
-#define CKM_NSS_TLS_EXTENDED_MASTER_KEY_DERIVE (CKM_NSS + 25)
+#define CKM_NSS_TLS_EXTENDED_MASTER_KEY_DERIVE (CKM_NSS + 25)
#define CKM_NSS_TLS_EXTENDED_MASTER_KEY_DERIVE_DH (CKM_NSS + 26)
+#define CKM_NSS_CHACHA20_KEY_GEN (CKM_NSS + 27)
+#define CKM_NSS_CHACHA20_POLY1305 (CKM_NSS + 28)
+
/*
* 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
+#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_BYTE *pGX;
CK_ULONG ulGXLen;
- CK_BYTE * pGV;
+ CK_BYTE *pGV;
CK_ULONG ulGVLen;
- CK_BYTE * pR;
+ CK_BYTE *pR;
CK_ULONG ulRLen;
} CK_NSS_JPAKEPublicValue;
@@ -252,7 +256,7 @@ typedef struct CK_NSS_JPAKERound1Params {
} CK_NSS_JPAKERound1Params;
typedef struct CK_NSS_JPAKERound2Params {
- CK_BYTE * pSharedKey; /* in */
+ CK_BYTE *pSharedKey; /* in */
CK_ULONG ulSharedKeyLen; /* in */
CK_NSS_JPAKEPublicValue gx3; /* in */
CK_NSS_JPAKEPublicValue gx4; /* in */
@@ -279,20 +283,28 @@ typedef struct CK_NSS_JPAKEFinalParams {
* 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_MECHANISM_TYPE macAlg; /* in */
+ CK_ULONG ulBodyTotalLen; /* in */
+ CK_BYTE *pHeader; /* in */
+ CK_ULONG ulHeaderLen; /* in */
} CK_NSS_MAC_CONSTANT_TIME_PARAMS;
+typedef struct CK_NSS_AEAD_PARAMS {
+ CK_BYTE_PTR pNonce;
+ CK_ULONG ulNonceLen;
+ CK_BYTE_PTR pAAD;
+ CK_ULONG ulAADLen;
+ CK_ULONG ulTagLen;
+} CK_NSS_AEAD_PARAMS;
+
/*
* NSS-defined return values
*
*/
-#define CKR_NSS (CKM_VENDOR_DEFINED|NSSCK_VENDOR_NSS)
+#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)
+#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.
@@ -345,7 +357,6 @@ typedef struct CK_NSS_TLS_EXTENDED_MASTER_KEY_DERIVE_PARAMS {
CK_VERSION_PTR pVersion;
} CK_NSS_TLS_EXTENDED_MASTER_KEY_DERIVE_PARAMS;
-
/*
* Trust info
*
@@ -356,26 +367,25 @@ typedef struct CK_NSS_TLS_EXTENDED_MASTER_KEY_DERIVE_PARAMS {
* vendor space, like everything else.
*/
-typedef CK_ULONG CK_TRUST;
+typedef CK_ULONG CK_TRUST;
/* The following trust types are defined: */
-#define CKT_VENDOR_DEFINED 0x80000000
+#define CKT_VENDOR_DEFINED 0x80000000
-#define CKT_NSS (CKT_VENDOR_DEFINED|NSSCK_VENDOR_NSS)
+#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 */
+#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)
-
+#define CKT_NSS_VALID_DELEGATOR (CKT_NSS + 11)
/*
* old definitions. They still exist, but the plain meaning of the
@@ -398,26 +408,23 @@ typedef CK_ULONG CK_TRUST;
* 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)
+#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_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")));
+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)
+#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))
+#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
@@ -425,47 +432,47 @@ typedef CK_TRUST __CKT_NSS_MUST_VERIFY __attribute__((deprecated
#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
+#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
+#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*/
+#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
+#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'
@@ -478,12 +485,12 @@ typedef CK_TRUST __CKT_NSS_MUST_VERIFY __attribute__((deprecated
* 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_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);
+typedef char **(PR_CALLBACK *SECMODModuleDBFunc)(unsigned long function,
+ char *parameters, void *moduleSpec);
/* softoken slot ID's */
#define SFTK_MIN_USER_SLOT_ID 4
@@ -491,5 +498,4 @@ typedef char ** (PR_CALLBACK *SECMODModuleDBFunc)(unsigned long function,
#define SFTK_MIN_FIPS_USER_SLOT_ID 101
#define SFTK_MAX_FIPS_USER_SLOT_ID 127
-
#endif /* _PKCS11N_H_ */
diff --git a/nss/lib/util/pkcs11p.h b/nss/lib/util/pkcs11p.h
index 744c820..2e904ee 100644
--- a/nss/lib/util/pkcs11p.h
+++ b/nss/lib/util/pkcs11p.h
@@ -15,8 +15,7 @@
#if defined(_WIN32)
#ifdef _MSC_VER
-#pragma warning(disable:4103)
+#pragma warning(disable : 4103)
#endif
#pragma pack(push, cryptoki, 1)
#endif
-
diff --git a/nss/lib/util/pkcs11t.h b/nss/lib/util/pkcs11t.h
index 2393141..c945f31 100644
--- a/nss/lib/util/pkcs11t.h
+++ b/nss/lib/util/pkcs11t.h
@@ -16,7 +16,6 @@
* warranty of any kind.
*/
-
#ifndef _PKCS11T_H_
#define _PKCS11T_H_ 1
@@ -27,171 +26,162 @@
#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_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
+#define CK_INVALID_SESSION 0
/* an unsigned 8-bit value */
-typedef unsigned char CK_BYTE;
+typedef unsigned char CK_BYTE;
/* an unsigned 8-bit character */
-typedef CK_BYTE CK_CHAR;
+typedef CK_BYTE CK_CHAR;
/* an 8-bit UTF-8 character */
-typedef CK_BYTE CK_UTF8CHAR;
+typedef CK_BYTE CK_UTF8CHAR;
/* a BYTE-sized Boolean flag */
-typedef CK_BYTE CK_BBOOL;
+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;
+typedef long int CK_LONG;
/* at least 32 bits; each bit is a Boolean flag */
-typedef CK_ULONG CK_FLAGS;
-
+typedef CK_ULONG CK_FLAGS;
/* some special values for certain CK_ULONG variables */
#define CK_UNAVAILABLE_INFORMATION (~0UL)
-#define CK_EFFECTIVELY_INFINITE 0
+#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;
+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_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
+ /* 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 */
+ 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 */
+ /* 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;
-
+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
+#define CKN_SURRENDER 0
-
-typedef CK_ULONG CK_SLOT_ID;
+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 */
+ /* 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 */
+#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 */
+ /* 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 */
+#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
+#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
+#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
@@ -203,950 +193,936 @@ typedef struct CK_TOKEN_INFO {
* dual simultaneous cryptographic operations (digest and
* encrypt; decrypt and digest; sign and encrypt; and decrypt
* and sign) */
-#define CKF_DUAL_CRYPTO_OPERATIONS 0x00000200
+#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
+#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
+#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
+#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
+#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
+#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
+#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
+#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
+#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
+#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
+#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_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;
+typedef CK_ULONG CK_USER_TYPE;
/* Security Officer */
-#define CKU_SO 0
+#define CKU_SO 0
/* Normal user */
-#define CKU_USER 1
+#define CKU_USER 1
/* Context specific (added in v2.20) */
-#define CKU_CONTEXT_SPECIFIC 2
+#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
-
+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 */
+ 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 */
+ /* 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 */
+#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_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;
+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_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
+#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;
+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
+#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;
+typedef CK_ULONG CK_KEY_TYPE;
/* the following key types are defined: */
-#define CKK_RSA 0x00000000
-#define CKK_DSA 0x00000001
-#define CKK_DH 0x00000002
+#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
+#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
+#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
+#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
+#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_CAMELLIA 0x00000025
-#define CKK_VENDOR_DEFINED 0x80000000
+#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;
+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 0x00000000
#define CKC_X_509_ATTR_CERT 0x00000001
-#define CKC_WTLS 0x00000002
-#define CKC_VENDOR_DEFINED 0x80000000
-
+#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;
+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
+#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
+#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_OBJECT_ID 0x00000012
-#define CKA_CERTIFICATE_TYPE 0x00000080
-#define CKA_ISSUER 0x00000081
-#define CKA_SERIAL_NUMBER 0x00000082
+#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
+#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
+#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
+#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
+#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
+#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
+#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_KEY_GEN_MECHANISM 0x00000166
-#define CKA_MODIFIABLE 0x00000170
+#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_ECDSA_PARAMS 0x00000180
+#define CKA_EC_PARAMS 0x00000180
-#define CKA_EC_POINT 0x00000181
+#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
+#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_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)
+#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
+#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
-
+#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;
+ CK_ATTRIBUTE_TYPE type;
+ CK_VOID_PTR pValue;
- /* ulValueLen went from CK_USHORT to CK_ULONG for v2.0 */
- CK_ULONG ulValueLen; /* in bytes */
+ /* 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") */
+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;
+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
+#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
+#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
+#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
+#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
+#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
+#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_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
+#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_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
+#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_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
+#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
+#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_DES_OFB64 0x00000150
+#define CKM_DES_OFB8 0x00000151
+#define CKM_DES_CFB64 0x00000152
+#define CKM_DES_CFB8 0x00000153
-#define CKM_MD2 0x00000200
+#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_MD2_HMAC 0x00000201
+#define CKM_MD2_HMAC_GENERAL 0x00000202
-#define CKM_MD5 0x00000210
+#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_MD5_HMAC 0x00000211
+#define CKM_MD5_HMAC_GENERAL 0x00000212
-#define CKM_SHA_1 0x00000220
+#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
+#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
+#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
+#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
+#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
+#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
+#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_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
+#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
+#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
+#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_PKCS5_PBKD2 0x000003B0
-#define CKM_PBA_SHA1_WITH_SHA1_HMAC 0x000003C0
+#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_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
/* TLS 1.2 mechanisms are new for v2.40 */
-#define CKM_TLS12_MASTER_KEY_DERIVE 0x000003E0
-#define CKM_TLS12_KEY_AND_MAC_DERIVE 0x000003E1
-#define CKM_TLS12_MASTER_KEY_DERIVE_DH 0x000003E2
-#define CKM_TLS12_KEY_SAFE_DERIVE 0x000003E3
-#define CKM_TLS_MAC 0x000003E4
-#define CKM_TLS_KDF 0x000003E5
+#define CKM_TLS12_MASTER_KEY_DERIVE 0x000003E0
+#define CKM_TLS12_KEY_AND_MAC_DERIVE 0x000003E1
+#define CKM_TLS12_MASTER_KEY_DERIVE_DH 0x000003E2
+#define CKM_TLS12_KEY_SAFE_DERIVE 0x000003E3
+#define CKM_TLS12_MAC 0x000003E4
+#define CKM_TLS_MAC 0x000003E4
+#define CKM_TLS_KDF 0x000003E5
-#define CKM_KEY_WRAP_LYNKS 0x00000400
-#define CKM_KEY_WRAP_SET_OAEP 0x00000401
+#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
+#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
+#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_KEY_PAIR_GEN 0x00001040
+#define CKM_EC_KEY_PAIR_GEN 0x00001040
-#define CKM_ECDSA 0x00001041
-#define CKM_ECDSA_SHA1 0x00001042
+#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
+#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
+#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
+#define CKM_AES_CTR 0x00001086
/* new for v2.30 */
-#define CKM_AES_GCM 0x00001087
-#define CKM_AES_CCM 0x00001088
-#define CKM_AES_CTS 0x00001089
+#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
+#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
+#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_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_DSA_PARAMETER_GEN 0x00002000
+#define CKM_DH_PKCS_PARAMETER_GEN 0x00002001
+#define CKM_X9_42_DH_PARAMETER_GEN 0x00002002
-#define CKM_VENDOR_DEFINED 0x80000000
+#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;
+ 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 */
+ /* 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_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 */
+#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
+#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_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 */
+#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;
+typedef CK_ULONG CK_RV;
-#define CKR_OK 0x00000000
-#define CKR_CANCEL 0x00000001
-#define CKR_HOST_MEMORY 0x00000002
-#define CKR_SLOT_ID_INVALID 0x00000003
+#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
+#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
+#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_FUNCTION_NOT_SUPPORTED 0x00000054
-#define CKR_KEY_HANDLE_INVALID 0x00000060
+#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
+#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_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
+#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
+#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_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
+#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
+#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_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
+#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
+#define CKR_RANDOM_NO_RNG 0x00000121
/* These are new to v2.11 */
-#define CKR_DOMAIN_PARAMS_INVALID 0x00000130
+#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
+#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
+#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
+#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_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
@@ -1158,69 +1134,63 @@ 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_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_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_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_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_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
+#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
+#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
@@ -1234,13 +1204,13 @@ 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
+#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
+#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
@@ -1251,17 +1221,17 @@ 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
+#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_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;
@@ -1270,9 +1240,9 @@ typedef CK_RSA_PKCS_OAEP_PARAMS CK_PTR CK_RSA_PKCS_OAEP_PARAMS_PTR;
* 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_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;
@@ -1281,12 +1251,12 @@ typedef CK_RSA_PKCS_PSS_PARAMS CK_PTR CK_RSA_PKCS_PSS_PARAMS_PTR;
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
+#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
@@ -1294,44 +1264,43 @@ typedef CK_ULONG CK_EC_KDF_TYPE;
* 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_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_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_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;
@@ -1343,7 +1312,7 @@ 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_ASN1 0x00000003
#define CKD_SHA1_KDF_CONCATENATE 0x00000004
/* CK_X9_42_DH1_DERIVE_PARAMS is new for v2.11.
@@ -1351,11 +1320,11 @@ typedef CK_X9_42_DH_KDF_TYPE CK_PTR CK_X9_42_DH_KDF_TYPE_PTR;
* 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_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;
@@ -1365,30 +1334,30 @@ typedef struct CK_X9_42_DH1_DERIVE_PARAMS CK_PTR CK_X9_42_DH1_DERIVE_PARAMS_PTR;
* 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_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_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;
@@ -1397,139 +1366,132 @@ typedef CK_X9_42_MQV_DERIVE_PARAMS CK_PTR CK_X9_42_MQV_DERIVE_PARAMS_PTR;
* 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_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_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
+ /* ulEffectiveBits was changed from CK_USHORT to CK_ULONG for
* v2.0 */
- CK_ULONG ulEffectiveBits; /* effective bits (1-1024) */
+ CK_ULONG ulEffectiveBits; /* effective bits (1-1024) */
- CK_BYTE iv[8]; /* IV for CBC mode */
+ 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_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;
-
+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_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_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_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;
-
+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_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_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_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_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_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_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;
@@ -1538,237 +1500,229 @@ typedef CK_CCM_PARAMS CK_PTR CK_CCM_PARAMS_PTR;
* 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_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;
-
+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_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 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_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_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 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_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_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_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_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_ULONG ulMacSizeInBits;
+ CK_ULONG ulKeySizeInBits;
+ CK_ULONG ulIVSizeInBits;
+ CK_BBOOL bIsExport; /* Unused. Must be set to CK_FALSE. */
+ 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_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;
/* TLS 1.2 is new for version 2.40 */
typedef struct CK_TLS12_MASTER_KEY_DERIVE_PARAMS {
- CK_SSL3_RANDOM_DATA RandomInfo;
- CK_VERSION_PTR pVersion;
- CK_MECHANISM_TYPE prfHashMechanism;
+ CK_SSL3_RANDOM_DATA RandomInfo;
+ CK_VERSION_PTR pVersion;
+ CK_MECHANISM_TYPE prfHashMechanism;
} CK_TLS12_MASTER_KEY_DERIVE_PARAMS;
-typedef CK_TLS12_MASTER_KEY_DERIVE_PARAMS CK_PTR \
- CK_TLS12_MASTER_KEY_DERIVE_PARAMS_PTR;
+typedef CK_TLS12_MASTER_KEY_DERIVE_PARAMS CK_PTR
+ CK_TLS12_MASTER_KEY_DERIVE_PARAMS_PTR;
typedef struct CK_TLS12_KEY_MAT_PARAMS {
- CK_ULONG ulMacSizeInBits;
- CK_ULONG ulKeySizeInBits;
- CK_ULONG ulIVSizeInBits;
- CK_BBOOL bIsExport; /* Unused. Must be set to CK_FALSE. */
- CK_SSL3_RANDOM_DATA RandomInfo;
- CK_SSL3_KEY_MAT_OUT_PTR pReturnedKeyMaterial;
- CK_MECHANISM_TYPE prfHashMechanism;
+ CK_ULONG ulMacSizeInBits;
+ CK_ULONG ulKeySizeInBits;
+ CK_ULONG ulIVSizeInBits;
+ CK_BBOOL bIsExport; /* Unused. Must be set to CK_FALSE. */
+ CK_SSL3_RANDOM_DATA RandomInfo;
+ CK_SSL3_KEY_MAT_OUT_PTR pReturnedKeyMaterial;
+ CK_MECHANISM_TYPE prfHashMechanism;
} CK_TLS12_KEY_MAT_PARAMS;
typedef CK_TLS12_KEY_MAT_PARAMS CK_PTR CK_TLS12_KEY_MAT_PARAMS_PTR;
typedef struct CK_TLS_KDF_PARAMS {
- CK_MECHANISM_TYPE prfMechanism;
- CK_BYTE_PTR pLabel;
- CK_ULONG ulLabelLength;
- CK_SSL3_RANDOM_DATA RandomInfo;
- CK_BYTE_PTR pContextData;
- CK_ULONG ulContextDataLength;
+ CK_MECHANISM_TYPE prfMechanism;
+ CK_BYTE_PTR pLabel;
+ CK_ULONG ulLabelLength;
+ CK_SSL3_RANDOM_DATA RandomInfo;
+ CK_BYTE_PTR pContextData;
+ CK_ULONG ulContextDataLength;
} CK_TLS_KDF_PARAMS;
typedef struct CK_TLS_MAC_PARAMS {
- CK_MECHANISM_TYPE prfMechanism;
- CK_ULONG ulMacLength;
- CK_ULONG ulServerOrClient;
+ CK_MECHANISM_TYPE prfMechanism;
+ CK_ULONG ulMacLength;
+ CK_ULONG ulServerOrClient;
} CK_TLS_MAC_PARAMS;
typedef CK_TLS_MAC_PARAMS CK_PTR CK_TLS_MAC_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_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_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 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_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_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_MECHANISM_TYPE DigestMechanism;
+ CK_ULONG ulMacSizeInBits;
+ CK_ULONG ulKeySizeInBits;
+ CK_ULONG ulIVSizeInBits;
+ CK_ULONG ulSequenceNumber;
+ CK_BBOOL bIsExport; /* Unused. Must be set to CK_FALSE. */
+ 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_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_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;
-
+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
@@ -1787,9 +1741,15 @@ 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. */
+/* The following PRFs are defined in PKCS #5 v2.1. */
#define CKP_PKCS5_PBKD2_HMAC_SHA1 0x00000001
-
+#define CKP_PKCS5_PBKD2_HMAC_GOSTR3411 0x00000002
+#define CKP_PKCS5_PBKD2_HMAC_SHA224 0x00000003
+#define CKP_PKCS5_PBKD2_HMAC_SHA256 0x00000004
+#define CKP_PKCS5_PBKD2_HMAC_SHA384 0x00000005
+#define CKP_PKCS5_PBKD2_HMAC_SHA512 0x00000006
+#define CKP_PKCS5_PBKD2_HMAC_SHA512_224 0x00000007
+#define CKP_PKCS5_PBKD2_HMAC_SHA512_256 0x00000008
/* CK_PKCS5_PBKDF2_SALT_SOURCE_TYPE is new for v2.10.
* CK_PKCS5_PBKDF2_SALT_SOURCE_TYPE is used to indicate the
@@ -1800,21 +1760,21 @@ 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
+#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_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;
@@ -1823,14 +1783,14 @@ typedef CK_PKCS5_PBKD2_PARAMS CK_PTR CK_PKCS5_PBKD2_PARAMS_PTR;
/* 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
+#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
+#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
+#define CKK_INVALID_KEY_TYPE 0xffffffff
#include "pkcs11n.h"
diff --git a/nss/lib/util/pkcs11u.h b/nss/lib/util/pkcs11u.h
index f670094..be949bc 100644
--- a/nss/lib/util/pkcs11u.h
+++ b/nss/lib/util/pkcs11u.h
@@ -11,10 +11,9 @@
* reset any packing set by pkcs11p.h
*/
-#if defined (_WIN32)
+#if defined(_WIN32)
#ifdef _MSC_VER
-#pragma warning(disable:4103)
+#pragma warning(disable : 4103)
#endif
#pragma pack(pop, cryptoki)
#endif
-
diff --git a/nss/lib/util/pkcs1sig.c b/nss/lib/util/pkcs1sig.c
index 03b16f5..502119a 100644
--- a/nss/lib/util/pkcs1sig.c
+++ b/nss/lib/util/pkcs1sig.c
@@ -77,9 +77,9 @@ encodePrefix(const SECOidData *hashOid, unsigned int digestLen,
return SECFailure;
}
- prefix->data[0] = SEC_ASN1_SEQUENCE|SEC_ASN1_CONSTRUCTED;
+ prefix->data[0] = SEC_ASN1_SEQUENCE | SEC_ASN1_CONSTRUCTED;
prefix->data[1] = outerSeqLen;
- prefix->data[2] = SEC_ASN1_SEQUENCE|SEC_ASN1_CONSTRUCTED;
+ prefix->data[2] = SEC_ASN1_SEQUENCE | SEC_ASN1_CONSTRUCTED;
prefix->data[3] = innerSeqLen;
prefix->data[4] = SEC_ASN1_OBJECT_ID;
prefix->data[5] = hashOid->oid.len;
@@ -96,13 +96,13 @@ encodePrefix(const SECOidData *hashOid, unsigned int digestLen,
SECStatus
_SGN_VerifyPKCS1DigestInfo(SECOidTag digestAlg,
- const SECItem* digest,
- const SECItem* dataRecoveredFromSignature,
+ const SECItem *digest,
+ const SECItem *dataRecoveredFromSignature,
PRBool unsafeAllowMissingParameters)
{
SECOidData *hashOid;
pkcs1Prefixes pp;
- const pkcs1Prefix* expectedPrefix;
+ const pkcs1Prefix *expectedPrefix;
SECStatus rv, rv2, rv3;
if (!digest || !digest->data ||
@@ -136,11 +136,11 @@ _SGN_VerifyPKCS1DigestInfo(SECOidTag digestAlg,
*/
if (dataRecoveredFromSignature->len ==
- pp.prefixWithParams.len + pp.digestLen) {
+ pp.prefixWithParams.len + pp.digestLen) {
expectedPrefix = &pp.prefixWithParams;
} else if (unsafeAllowMissingParameters &&
dataRecoveredFromSignature->len ==
- pp.prefixWithoutParams.len + pp.digestLen) {
+ pp.prefixWithoutParams.len + pp.digestLen) {
expectedPrefix = &pp.prefixWithoutParams;
} else {
PORT_SetError(SEC_ERROR_BAD_SIGNATURE);
diff --git a/nss/lib/util/portreg.c b/nss/lib/util/portreg.c
index ba2b3ce..bf77672 100644
--- a/nss/lib/util/portreg.c
+++ b/nss/lib/util/portreg.c
@@ -2,7 +2,7 @@
* License, v. 2.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.
@@ -13,81 +13,80 @@
/* ----------------------------- shexp_valid ------------------------------ */
-
-static int
-_valid_subexp(const char *exp, char stop1, char stop2)
+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 */
+ 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])
+ switch (exp[x]) {
+ case '~':
+ if (tld) /* at most one exclusion */
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)
+ if (stop1) /* no exclusions within unions */
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])
+ 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;
- break;
- default:
- break;
+ case '\\':
+ ++nsc;
+ if (!exp[++x])
+ return INVALID_SXP;
+ break;
+ default:
+ break;
}
}
- if((!stop1) && (!nsc)) /* must be at least one special character */
+ 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
+PORT_RegExpValid(const char *exp)
{
int x;
@@ -95,49 +94,47 @@ PORT_RegExpValid(const char *exp)
return (x < 0 ? x : VALID_SXP);
}
-
/* ----------------------------- shexp_match ----------------------------- */
-
#define MATCH 0
#define NOMATCH 1
#define ABORTED -1
-static int
+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
+/* 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
+static int
_scan_and_copy(const char *exp, char stop1, char stop2, char *dest)
{
- register int sx; /* source index */
+ 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 (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;
+ /* Copy all but the closing delimiter. */
+ memcpy(dest, exp, sx);
+ dest[sx] = 0;
}
return cc ? sx : ABORTED; /* index of closing delimiter */
}
@@ -145,47 +142,47 @@ _scan_and_copy(const char *exp, char stop1, char stop2, char *dest)
/* 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
+ * 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.
+ * matches the input string. Repeat this until some alternative matches,
+ * or we have an abort.
*/
-static int
+static int
_handle_union(const char *str, const char *exp, PRBool case_insensitive,
- unsigned int level)
+ unsigned int level)
{
- register int sx; /* source index */
- int cp; /* source index of closing parenthesis */
+ register int sx; /* source index */
+ int cp; /* source index of closing parenthesis */
int count;
- int ret = NOMATCH;
+ 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));
+ 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);
+ 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] == ')')
+ if (ret != NOMATCH || !exp[sx] || exp[sx] == ')')
break;
}
PORT_Free(e2);
if (sx < 2)
- ret = ABORTED;
+ ret = ABORTED;
return ret;
}
@@ -196,182 +193,183 @@ _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;
+ map[tolower(start++)] = 1;
return map[tolower(val)];
}
-static int
-_shexp_match(const char *str, const char *exp, PRBool case_insensitive,
- unsigned int level)
+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;
+ 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] != '*')) {
+ 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;
- }
+ }
+ 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)
+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);
+ return _shexp_match(str, xp, case_insensitive, 0);
exp = PORT_Strdup(xp);
- if(!exp)
- return NOMATCH;
+ 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;
+ 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);
+ ret = _shexp_match(str, exp, case_insensitive, 0);
PORT_Free(exp);
return ret;
}
-
/* ------------------------------ shexp_cmp ------------------------------- */
-int
+int
PORT_RegExpSearch(const char *str, const char *exp)
{
- switch(PORT_RegExpValid(exp))
- {
+ switch (PORT_RegExpValid(exp)) {
case INVALID_SXP:
return -1;
case NON_SXP:
- return (strcmp(exp,str) ? 1 : 0);
+ 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))
- {
+ switch (PORT_RegExpValid(exp)) {
case INVALID_SXP:
return -1;
case NON_SXP:
- return (PORT_Strcasecmp(exp,str) ? 1 : 0);
+ return (PORT_Strcasecmp(exp, str) ? 1 : 0);
default:
return port_RegExpMatch(str, exp, PR_TRUE);
- }
+ }
}
-
diff --git a/nss/lib/util/portreg.h b/nss/lib/util/portreg.h
index 811f045..14bd9e7 100644
--- a/nss/lib/util/portreg.h
+++ b/nss/lib/util/portreg.h
@@ -4,19 +4,19 @@
/*
* 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 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.
+ * 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.
@@ -26,9 +26,9 @@
* 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
+ * 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.
+ * 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
@@ -41,25 +41,23 @@
* 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.
+ * 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
diff --git a/nss/lib/util/quickder.c b/nss/lib/util/quickder.c
index fe72b29..49ff14d 100644
--- a/nss/lib/util/quickder.c
+++ b/nss/lib/util/quickder.c
@@ -4,7 +4,6 @@
/*
Optimized ASN.1 DER decoder
-
*/
#include "secerr.h"
@@ -15,10 +14,11 @@
* simple definite-length ASN.1 decoder
*/
-static unsigned char* definite_length_decoder(const unsigned char *buf,
- const unsigned int buf_length,
- unsigned int *out_data_length,
- PRBool includeTag)
+static unsigned char*
+definite_length_decoder(const unsigned char* buf,
+ const unsigned int buf_length,
+ unsigned int* out_data_length,
+ PRBool includeTag)
{
unsigned char tag;
unsigned int used_length = 0;
@@ -27,80 +27,64 @@ static unsigned char* definite_length_decoder(const unsigned char *buf,
unsigned char byte;
unsigned int i;
- if (used_length >= buf_length)
- {
+ if (used_length >= buf_length) {
/* Tag field was not found! */
return NULL;
}
tag = buf[used_length++];
- if (tag == 0)
- {
+ if (tag == 0) {
/* End-of-contents octects should not be present in DER because
DER doesn't use the indefinite length form. */
return NULL;
}
- if ((tag & 0x1F) == 0x1F)
- {
+ if ((tag & 0x1F) == 0x1F) {
/* High tag number (a tag number > 30) is not supported */
return NULL;
}
- if (used_length >= buf_length)
- {
+ if (used_length >= buf_length) {
/* Length field was not found! */
return NULL;
}
byte = buf[used_length++];
- if (!(byte & 0x80))
- {
+ if (!(byte & 0x80)) {
/* Short form: The high bit is not set. */
data_length = byte; /* clarity; we're returning a 32-bit int. */
- }
- else
- {
+ } else {
/* Long form. Extract the field length */
length_field_len = byte & 0x7F;
- if (length_field_len == 0)
- {
+ if (length_field_len == 0) {
/* DER doesn't use the indefinite length form. */
return NULL;
}
- if (length_field_len > sizeof(data_length))
- {
+ if (length_field_len > sizeof(data_length)) {
/* We don't support an extended length field longer than
4 bytes (2^32) */
return NULL;
}
- if (length_field_len > (buf_length - used_length))
- {
+ if (length_field_len > (buf_length - used_length)) {
/* Extended length field was not found */
return NULL;
}
/* Iterate across the extended length field */
- for (i = 0; i < length_field_len; i++)
- {
+ for (i = 0; i < length_field_len; i++) {
byte = buf[used_length++];
data_length = (data_length << 8) | byte;
- if (i == 0)
- {
+ if (i == 0) {
PRBool too_long = PR_FALSE;
- if (length_field_len == 1)
- {
+ if (length_field_len == 1) {
too_long = ((byte & 0x80) == 0); /* Short form suffices */
- }
- else
- {
+ } else {
too_long = (byte == 0); /* This zero byte can be omitted */
}
- if (too_long)
- {
+ if (too_long) {
/* The length is longer than needed. */
return NULL;
}
@@ -108,14 +92,12 @@ static unsigned char* definite_length_decoder(const unsigned char *buf,
}
}
- if (data_length > (buf_length - used_length))
- {
+ if (data_length > (buf_length - used_length)) {
/* The decoded length exceeds the available buffer */
return NULL;
}
- if (includeTag)
- {
+ if (includeTag) {
data_length += used_length;
}
@@ -123,26 +105,24 @@ static unsigned char* definite_length_decoder(const unsigned char *buf,
return ((unsigned char*)buf + (includeTag ? 0 : used_length));
}
-static SECStatus GetItem(SECItem* src, SECItem* dest, PRBool includeTag)
+static SECStatus
+GetItem(SECItem* src, SECItem* dest, PRBool includeTag)
{
- if ( (!src) || (!dest) || (!src->data && src->len) )
- {
+ if ((!src) || (!dest) || (!src->data && src->len)) {
PORT_SetError(SEC_ERROR_INVALID_ARGS);
return SECFailure;
}
- if (!src->len)
- {
+ 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)
- {
+ dest->data = definite_length_decoder(src->data, src->len, &dest->len,
+ includeTag);
+ if (dest->data == NULL) {
PORT_SetError(SEC_ERROR_BAD_DER);
return SECFailure;
}
@@ -153,57 +133,50 @@ static SECStatus GetItem(SECItem* src, SECItem* dest, PRBool includeTag)
/* 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)
+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) )
- {
+ if ((!item) || (!item->data && item->len) || (!templateEntry) || (!match)) {
PORT_SetError(SEC_ERROR_INVALID_ARGS);
return SECFailure;
}
- if (!item->len)
- {
+ if (!item->len) {
*match = PR_FALSE;
return SECSuccess;
}
kind = templateEntry->kind;
- tag = *(unsigned char*) item->data;
+ tag = *(unsigned char*)item->data;
- if ( ( (kind & SEC_ASN1_INLINE) ||
- (kind & SEC_ASN1_POINTER) ) &&
- (0 == (kind & SEC_ASN1_TAG_MASK) ) )
- {
+ 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))
- {
+ 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
- {
+ } 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)
- {
+ 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) )
- {
+ 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
@@ -217,8 +190,7 @@ static SECStatus MatchComponentType(const SEC_ASN1Template* templateEntry,
}
}
- if (kind & SEC_ASN1_CHOICE)
- {
+ 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
@@ -227,35 +199,29 @@ static SECStatus MatchComponentType(const SEC_ASN1Template* templateEntry,
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) )
- {
+ 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. */
+ /* no match, caller must decide if this is BAD DER, or not. */
*match = PR_FALSE;
return SECSuccess;
}
- if (kind & SEC_ASN1_ANY)
- {
+ 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))
- )
- )
- {
+ 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
@@ -267,9 +233,8 @@ static SECStatus MatchComponentType(const SEC_ASN1Template* templateEntry,
}
/* first, do a class check */
- if ( (tag & SEC_ASN1_CLASS_MASK) !=
- (((unsigned char)kind) & SEC_ASN1_CLASS_MASK) )
- {
+ if ((tag & SEC_ASN1_CLASS_MASK) !=
+ (((unsigned char)kind) & SEC_ASN1_CLASS_MASK)) {
/* 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; */
@@ -278,54 +243,48 @@ static SECStatus MatchComponentType(const SEC_ASN1Template* templateEntry,
}
/* now do a tag check */
- if ( ((unsigned char)kind & SEC_ASN1_TAGNUM_MASK) !=
- (tag & SEC_ASN1_TAGNUM_MASK))
- {
+ 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;
+ 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:
- /* this component must be a primitive type */
- if (! (tag & SEC_ASN1_CONSTRUCTED))
- {
+ /* 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;
- }
- 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;
@@ -334,7 +293,8 @@ static SECStatus MatchComponentType(const SEC_ASN1Template* templateEntry,
#ifdef DEBUG
-static SECStatus CheckSequenceTemplate(const SEC_ASN1Template* sequenceTemplate)
+static SECStatus
+CheckSequenceTemplate(const SEC_ASN1Template* sequenceTemplate)
{
SECStatus rv = SECSuccess;
const SEC_ASN1Template* sequenceEntry = NULL;
@@ -343,19 +303,16 @@ static SECStatus CheckSequenceTemplate(const SEC_ASN1Template* sequenceTemplate)
unsigned long ambiguityIndex = 0;
PRBool foundAmbiguity = PR_FALSE;
- do
- {
+ do {
sequenceEntry = &sequenceTemplate[seqIndex++];
- if (sequenceEntry->kind)
- {
+ 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) )
- {
+ if ((PR_FALSE == foundAmbiguity) &&
+ (sequenceEntry->kind & SEC_ASN1_OPTIONAL) &&
+ (sequenceEntry->kind & SEC_ASN1_ANY)) {
foundAmbiguity = PR_TRUE;
ambiguityIndex = seqIndex - 1;
}
@@ -364,10 +321,8 @@ static SECStatus CheckSequenceTemplate(const SEC_ASN1Template* sequenceTemplate)
lastEntryIndex = seqIndex - 2;
- if (PR_FALSE != foundAmbiguity)
- {
- if (ambiguityIndex < lastEntryIndex)
- {
+ if (PR_FALSE != foundAmbiguity) {
+ if (ambiguityIndex < lastEntryIndex) {
/* ambiguity can only be tolerated on the last entry */
PORT_SetError(SEC_ERROR_BAD_TEMPLATE);
rv = SECFailure;
@@ -383,12 +338,13 @@ static SECStatus CheckSequenceTemplate(const SEC_ASN1Template* sequenceTemplate)
#endif
static SECStatus DecodeItem(void* dest,
- const SEC_ASN1Template* templateEntry,
- SECItem* src, PLArenaPool* arena, PRBool checkTag);
+ const SEC_ASN1Template* templateEntry,
+ SECItem* src, PLArenaPool* arena, PRBool checkTag);
-static SECStatus DecodeSequence(void* dest,
- const SEC_ASN1Template* templateEntry,
- SECItem* src, PLArenaPool* arena)
+static SECStatus
+DecodeSequence(void* dest,
+ const SEC_ASN1Template* templateEntry,
+ SECItem* src, PLArenaPool* arena)
{
SECStatus rv = SECSuccess;
SECItem source;
@@ -405,29 +361,25 @@ static SECStatus DecodeSequence(void* dest,
source = *src;
/* get the sequence */
- if (SECSuccess == rv)
- {
+ 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) );
+ 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)
- {
+ 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 */
@@ -438,54 +390,52 @@ static SECStatus DecodeSequence(void* dest,
return rv;
}
-static SECStatus DecodeInline(void* dest,
- const SEC_ASN1Template* templateEntry,
- SECItem* src, PLArenaPool* arena, PRBool checkTag)
+static SECStatus
+DecodeInline(void* dest,
+ const SEC_ASN1Template* templateEntry,
+ SECItem* src, PLArenaPool* arena, PRBool checkTag)
{
- const SEC_ASN1Template* inlineTemplate =
- SEC_ASN1GetSubtemplate (templateEntry, dest, PR_FALSE);
+ const SEC_ASN1Template* inlineTemplate =
+ SEC_ASN1GetSubtemplate(templateEntry, dest, PR_FALSE);
return DecodeItem((void*)((char*)dest + templateEntry->offset),
- inlineTemplate, src, arena, checkTag);
+ inlineTemplate, src, arena, checkTag);
}
-static SECStatus DecodePointer(void* dest,
- const SEC_ASN1Template* templateEntry,
- SECItem* src, PLArenaPool* arena, PRBool checkTag)
+static SECStatus
+DecodePointer(void* dest,
+ const SEC_ASN1Template* templateEntry,
+ SECItem* src, PLArenaPool* arena, PRBool checkTag)
{
- const SEC_ASN1Template* ptrTemplate =
- SEC_ASN1GetSubtemplate (templateEntry, dest, PR_FALSE);
+ 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)
- {
+ if (subdata) {
return DecodeItem(subdata, ptrTemplate, src, arena, checkTag);
- }
- else
- {
+ } else {
PORT_SetError(SEC_ERROR_NO_MEMORY);
return SECFailure;
}
}
-static SECStatus DecodeImplicit(void* dest,
- const SEC_ASN1Template* templateEntry,
- SECItem* src, PLArenaPool* arena)
+static SECStatus
+DecodeImplicit(void* dest,
+ const SEC_ASN1Template* templateEntry,
+ SECItem* src, PLArenaPool* arena)
{
- if (templateEntry->kind & SEC_ASN1_POINTER)
- {
- return DecodePointer((void*)((char*)dest ),
- templateEntry, src, arena, PR_FALSE);
- }
- else
- {
- return DecodeInline((void*)((char*)dest ),
+ 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, PLArenaPool* arena)
+static SECStatus
+DecodeChoice(void* dest,
+ const SEC_ASN1Template* templateEntry,
+ SECItem* src, PLArenaPool* arena)
{
SECStatus rv = SECSuccess;
SECItem choice;
@@ -499,32 +449,26 @@ static SECStatus DecodeChoice(void* dest,
/* rv = CheckChoiceTemplate(sequenceTemplate); */
/* process it */
- do
- {
+ do {
choice = *src;
choiceEntry = &choiceTemplate[choiceindex++];
- if (choiceEntry->kind)
- {
+ if (choiceEntry->kind) {
rv = DecodeItem(dest, choiceEntry, &choice, arena, PR_TRUE);
}
- } while ( (SECFailure == rv) && (choiceEntry->kind));
+ } while ((SECFailure == rv) && (choiceEntry->kind));
- if (SECFailure == rv)
- {
+ if (SECFailure == rv) {
/* the component didn't match any of the choices */
PORT_SetError(SEC_ERROR_BAD_DER);
- }
- else
- {
+ } else {
/* set the type in the union here */
- int *which = (int *)((char *)dest + templateEntry->offset);
+ 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)
- {
+ if (SECSuccess == rv && choice.len) {
/* there is extra data that isn't listed in the template */
PORT_SetError(SEC_ERROR_BAD_DER);
rv = SECFailure;
@@ -532,9 +476,10 @@ static SECStatus DecodeChoice(void* dest,
return rv;
}
-static SECStatus DecodeGroup(void* dest,
- const SEC_ASN1Template* templateEntry,
- SECItem* src, PLArenaPool* arena)
+static SECStatus
+DecodeGroup(void* dest,
+ const SEC_ASN1Template* templateEntry,
+ SECItem* src, PLArenaPool* arena)
{
SECStatus rv = SECSuccess;
SECItem source;
@@ -544,85 +489,74 @@ static SECStatus DecodeGroup(void* dest,
void** entries = NULL;
const SEC_ASN1Template* subTemplate =
- SEC_ASN1GetSubtemplate (templateEntry, dest, PR_FALSE);
+ SEC_ASN1GetSubtemplate(templateEntry, dest, PR_FALSE);
source = *src;
/* get the group */
- if (SECSuccess == rv)
- {
+ if (SECSuccess == rv) {
rv = GetItem(&source, &group, PR_FALSE);
}
/* XXX we should check the subtemplate in debug builds */
- if (SECSuccess == rv)
- {
+ 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
- {
+ do {
SECItem anitem;
rv = GetItem(&counter, &anitem, PR_TRUE);
- if (SECSuccess == rv && (anitem.len) )
- {
+ if (SECSuccess == rv && (anitem.len)) {
totalEntries++;
}
- } while ( (SECSuccess == rv) && (counter.len) );
+ } while ((SECSuccess == rv) && (counter.len));
- if (SECSuccess == rv)
- {
+ 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);
+ entries = (void**)PORT_ArenaZAlloc(arena, sizeof(void*) *
+ (totalEntries + 1) + /* the extra one is for NULL termination */
+ subTemplate->size * totalEntries);
- if (entries)
- {
+ if (entries) {
entries[totalEntries] = NULL; /* terminate the array */
- }
- else
- {
+ } else {
PORT_SetError(SEC_ERROR_NO_MEMORY);
rv = SECFailure;
}
- if (SECSuccess == rv)
- {
- void* entriesData = (unsigned char*)entries + (unsigned long)(sizeof(void*)*(totalEntries + 1 ));
+ 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++)
- {
+ for (entriesIndex = 0; entriesIndex < totalEntries; entriesIndex++) {
entries[entriesIndex] =
- (char*)entriesData + (subTemplate->size*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 */
+ 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, PLArenaPool* arena)
+static SECStatus
+DecodeExplicit(void* dest,
+ const SEC_ASN1Template* templateEntry,
+ SECItem* src, PLArenaPool* arena)
{
SECStatus rv = SECSuccess;
SECItem subItem;
@@ -630,14 +564,10 @@ static SECStatus DecodeExplicit(void* dest,
rv = GetItem(&constructed, &subItem, PR_FALSE);
- if (SECSuccess == rv)
- {
- if (templateEntry->kind & SEC_ASN1_POINTER)
- {
+ if (SECSuccess == rv) {
+ if (templateEntry->kind & SEC_ASN1_POINTER) {
rv = DecodePointer(dest, templateEntry, &subItem, arena, PR_TRUE);
- }
- else
- {
+ } else {
rv = DecodeInline(dest, templateEntry, &subItem, arena, PR_TRUE);
}
}
@@ -647,13 +577,14 @@ static SECStatus DecodeExplicit(void* dest,
/* new decoder implementation. This is a recursive function */
-static SECStatus DecodeItem(void* dest,
- const SEC_ASN1Template* templateEntry,
- SECItem* src, PLArenaPool* arena, PRBool checkTag)
+static SECStatus
+DecodeItem(void* dest,
+ const SEC_ASN1Template* templateEntry,
+ SECItem* src, PLArenaPool* arena, PRBool checkTag)
{
SECStatus rv = SECSuccess;
SECItem temp;
- SECItem mark = {siBuffer, NULL, 0};
+ SECItem mark = { siBuffer, NULL, 0 };
PRBool pop = PR_FALSE;
PRBool decode = PR_TRUE;
PRBool save = PR_FALSE;
@@ -669,22 +600,18 @@ static SECStatus DecodeItem(void* dest,
}
#endif
- if (SECSuccess == rv)
- {
+ if (SECSuccess == rv) {
/* do the template validation */
kind = templateEntry->kind;
- if (!kind)
- {
+ if (!kind) {
PORT_SetError(SEC_ERROR_BAD_TEMPLATE);
rv = SECFailure;
}
}
- if (SECSuccess == rv)
- {
+ if (SECSuccess == rv) {
#ifdef DEBUG
- if (kind & SEC_ASN1_DEBUG_BREAK)
- {
+ 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.
@@ -698,22 +625,18 @@ static SECStatus DecodeItem(void* dest,
#endif
if ((kind & SEC_ASN1_SKIP) ||
- (kind & SEC_ASN1_SAVE))
- {
+ (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 (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)
- {
+ if (kind & SEC_ASN1_SAVE) {
save = PR_TRUE;
- if (0 == (kind & SEC_ASN1_SKIP))
- {
+ 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
@@ -727,8 +650,7 @@ static SECStatus DecodeItem(void* dest,
rv = GetItem(src, &temp, PR_TRUE);
}
- if (SECSuccess == rv)
- {
+ if (SECSuccess == rv) {
/* now check if the component matches what we expect in the template */
if (PR_TRUE == checkTag)
@@ -737,19 +659,15 @@ static SECStatus DecodeItem(void* dest,
rv = MatchComponentType(templateEntry, &temp, &match, dest);
}
- if ( (SECSuccess == rv) && (PR_TRUE != match) )
- {
- if (kind & SEC_ASN1_OPTIONAL)
- {
+ 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
- {
+ } else {
/* a required component is missing. abort */
PORT_SetError(SEC_ERROR_BAD_DER);
rv = SECFailure;
@@ -757,158 +675,116 @@ static SECStatus DecodeItem(void* dest,
}
}
- if ((SECSuccess == rv) && (PR_TRUE == decode))
- {
+ 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)
- {
+ if (kind & SEC_ASN1_INLINE) {
/* decode inline template */
- rv = DecodeInline(dest, templateEntry, &temp , arena, PR_TRUE);
+ rv = DecodeInline(dest, templateEntry, &temp, arena, PR_TRUE);
}
- else
- if (kind & SEC_ASN1_EXPLICIT)
- {
+ else if (kind & SEC_ASN1_EXPLICIT) {
rv = DecodeExplicit(dest, templateEntry, &temp, arena);
- }
- else
- if ( (SEC_ASN1_UNIVERSAL != (kind & SEC_ASN1_CLASS_MASK)) &&
+ } else if ((SEC_ASN1_UNIVERSAL != (kind & SEC_ASN1_CLASS_MASK)) &&
- (!(kind & SEC_ASN1_EXPLICIT)))
- {
+ (!(kind & SEC_ASN1_EXPLICIT))) {
/* decode implicitly tagged components */
- rv = DecodeImplicit(dest, templateEntry, &temp , arena);
- }
- else
- if (kind & SEC_ASN1_POINTER)
- {
+ 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)
- {
+ } else if (kind & SEC_ASN1_CHOICE) {
rv = DecodeChoice(dest, templateEntry, &temp, arena);
- }
- else
- if (kind & SEC_ASN1_ANY)
- {
+ } else if (kind & SEC_ASN1_ANY) {
/* catch-all ANY type, don't decode */
save = PR_TRUE;
- if (kind & SEC_ASN1_INNER)
- {
+ 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
- {
+ } 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))
- {
+ } else if (SEC_ASN1_SEQUENCE == (kind & SEC_ASN1_TAGNUM_MASK)) {
/* plain SEQUENCE */
- rv = DecodeSequence(dest, templateEntry, &temp , arena);
- }
- else
- {
+ 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))
- {
+ 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) )
- {
+ 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--;
+ } 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;
}
- 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;
- }
+ 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;
+ default: {
+ break;
+ }
}
- }
}
}
}
- if ((SECSuccess == rv) && (PR_TRUE == save))
- {
- SECItem* destItem = (SECItem*) ((char*)dest + templateEntry->offset);
- if (destItem)
- {
+ 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
- {
+ } else {
PORT_SetError(SEC_ERROR_INVALID_ARGS);
rv = SECFailure;
}
}
- if (PR_TRUE == pop)
- {
+ if (PR_TRUE == pop) {
/* we don't want to move ahead, so restore the position */
*src = mark;
}
@@ -917,25 +793,23 @@ static SECStatus DecodeItem(void* dest,
/* the function below is the public one */
-SECStatus SEC_QuickDERDecodeItem(PLArenaPool* arena, void* dest,
- const SEC_ASN1Template* templateEntry,
- const SECItem* src)
+SECStatus
+SEC_QuickDERDecodeItem(PLArenaPool* arena, void* dest,
+ const SEC_ASN1Template* templateEntry,
+ const SECItem* src)
{
SECStatus rv = SECSuccess;
SECItem newsrc;
- if (!arena || !templateEntry || !src)
- {
+ if (!arena || !templateEntry || !src) {
PORT_SetError(SEC_ERROR_INVALID_ARGS);
rv = SECFailure;
}
- if (SECSuccess == rv)
- {
+ if (SECSuccess == rv) {
newsrc = *src;
rv = DecodeItem(dest, templateEntry, &newsrc, arena, PR_TRUE);
- if (SECSuccess == rv && newsrc.len)
- {
+ if (SECSuccess == rv && newsrc.len) {
rv = SECFailure;
PORT_SetError(SEC_ERROR_EXTRA_INPUT);
}
@@ -943,4 +817,3 @@ SECStatus SEC_QuickDERDecodeItem(PLArenaPool* arena, void* dest,
return rv;
}
-
diff --git a/nss/lib/util/secalgid.c b/nss/lib/util/secalgid.c
index b60f8df..718bb03 100644
--- a/nss/lib/util/secalgid.c
+++ b/nss/lib/util/secalgid.c
@@ -3,7 +3,7 @@
* 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 "secder.h" /* XXX remove this when remove the DERTemplate */
#include "secasn1.h"
#include "secitem.h"
#include "secerr.h"
@@ -12,85 +12,83 @@ SECOidTag
SECOID_GetAlgorithmTag(const SECAlgorithmID *id)
{
if (id == NULL || id->algorithm.data == NULL)
- return SEC_OID_UNKNOWN;
+ return SEC_OID_UNKNOWN;
- return SECOID_FindOIDTag (&(id->algorithm));
+ return SECOID_FindOIDTag(&(id->algorithm));
}
SECStatus
SECOID_SetAlgorithmID(PLArenaPool *arena, SECAlgorithmID *id, SECOidTag which,
- SECItem *params)
+ SECItem *params)
{
SECOidData *oiddata;
PRBool add_null_param;
oiddata = SECOID_FindOIDByTag(which);
- if ( !oiddata ) {
- PORT_SetError(SEC_ERROR_INVALID_ALGORITHM);
- return SECFailure;
+ if (!oiddata) {
+ PORT_SetError(SEC_ERROR_INVALID_ALGORITHM);
+ return SECFailure;
}
if (SECITEM_CopyItem(arena, &id->algorithm, &oiddata->oid))
- return SECFailure;
+ 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;
+ 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;
- }
+ /*
+ * 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);
+ /*
+ * 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;
- }
+ 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;
@@ -103,16 +101,18 @@ SECOID_CopyAlgorithmID(PLArenaPool *arena, SECAlgorithmID *to,
SECStatus rv;
rv = SECITEM_CopyItem(arena, &to->algorithm, &from->algorithm);
- if (rv) return rv;
+ if (rv)
+ return rv;
rv = SECITEM_CopyItem(arena, &to->parameters, &from->parameters);
return rv;
}
-void SECOID_DestroyAlgorithmID(SECAlgorithmID *algid, PRBool freeit)
+void
+SECOID_DestroyAlgorithmID(SECAlgorithmID *algid, PRBool freeit)
{
SECITEM_FreeItem(&algid->parameters, PR_FALSE);
SECITEM_FreeItem(&algid->algorithm, PR_FALSE);
- if(freeit == PR_TRUE)
+ if (freeit == PR_TRUE)
PORT_Free(algid);
}
@@ -122,7 +122,8 @@ SECOID_CompareAlgorithmID(SECAlgorithmID *a, SECAlgorithmID *b)
SECComparison rv;
rv = SECITEM_CompareItem(&a->algorithm, &b->algorithm);
- if (rv) return rv;
+ if (rv)
+ return rv;
rv = SECITEM_CompareItem(&a->parameters, &b->parameters);
return rv;
}
diff --git a/nss/lib/util/secasn1.h b/nss/lib/util/secasn1.h
index 3232277..b6292cd 100644
--- a/nss/lib/util/secasn1.h
+++ b/nss/lib/util/secasn1.h
@@ -17,7 +17,6 @@
#include "seccomon.h"
#include "secasn1t.h"
-
/************************************************************************/
SEC_BEGIN_PROTOS
@@ -30,13 +29,13 @@ SEC_BEGIN_PROTOS
*/
extern SEC_ASN1DecoderContext *SEC_ASN1DecoderStart(PLArenaPool *pool,
- void *dest,
- const SEC_ASN1Template *t);
+ void *dest,
+ const SEC_ASN1Template *t);
/* XXX char or unsigned char? */
extern SECStatus SEC_ASN1DecoderUpdate(SEC_ASN1DecoderContext *cx,
- const char *buf,
- unsigned long len);
+ const char *buf,
+ unsigned long len);
extern SECStatus SEC_ASN1DecoderFinish(SEC_ASN1DecoderContext *cx);
@@ -44,20 +43,20 @@ extern SECStatus SEC_ASN1DecoderFinish(SEC_ASN1DecoderContext *cx);
extern void SEC_ASN1DecoderAbort(SEC_ASN1DecoderContext *cx, int error);
extern void SEC_ASN1DecoderSetFilterProc(SEC_ASN1DecoderContext *cx,
- SEC_ASN1WriteProc fn,
- void *arg, PRBool no_store);
+ 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);
+ 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);
+ 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
@@ -67,26 +66,26 @@ extern SECStatus SEC_ASN1Decode(PLArenaPool *pool, void *dest,
field to siBuffer. */
extern SECStatus SEC_ASN1DecodeItem(PLArenaPool *pool, void *dest,
- const SEC_ASN1Template *t,
- const SECItem *src);
+ const SEC_ASN1Template *t,
+ const SECItem *src);
-extern SECStatus SEC_QuickDERDecodeItem(PLArenaPool* arena, void* dest,
- const SEC_ASN1Template* templateEntry,
- 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);
+ 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);
+ const char *buf,
+ unsigned long len);
extern void SEC_ASN1EncoderFinish(SEC_ASN1EncoderContext *cx);
@@ -94,8 +93,8 @@ extern void SEC_ASN1EncoderFinish(SEC_ASN1EncoderContext *cx);
extern void SEC_ASN1EncoderAbort(SEC_ASN1EncoderContext *cx, int error);
extern void SEC_ASN1EncoderSetNotifyProc(SEC_ASN1EncoderContext *cx,
- SEC_ASN1NotifyProc fn,
- void *arg);
+ SEC_ASN1NotifyProc fn,
+ void *arg);
extern void SEC_ASN1EncoderClearNotifyProc(SEC_ASN1EncoderContext *cx);
@@ -112,8 +111,8 @@ 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);
+ SEC_ASN1WriteProc output_proc,
+ void *output_arg);
/*
* If both pool and dest are NULL, the caller should free the returned SECItem
@@ -121,18 +120,18 @@ extern SECStatus SEC_ASN1Encode(const void *src, const SEC_ASN1Template *t,
* 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_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_ASN1EncodeInteger(PLArenaPool *pool,
+ SECItem *dest, long value);
-extern SECItem * SEC_ASN1EncodeUnsignedInteger(PLArenaPool *pool,
- SECItem *dest,
- unsigned long value);
+extern SECItem *SEC_ASN1EncodeUnsignedInteger(PLArenaPool *pool,
+ SECItem *dest,
+ unsigned long value);
extern SECStatus SEC_ASN1DecodeInteger(SECItem *src,
- unsigned long *value);
+ unsigned long *value);
/*
** Utilities.
@@ -142,11 +141,11 @@ extern SECStatus SEC_ASN1DecodeInteger(SECItem *src,
* We have a length that needs to be encoded; how many bytes will the
* encoding take?
*/
-extern int SEC_ASN1LengthLength (unsigned long len);
+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);
+extern int SEC_ASN1EncodeLength(unsigned char *buf, int value);
/*
* Find the appropriate subtemplate for the given template.
@@ -157,11 +156,11 @@ extern int SEC_ASN1EncodeLength(unsigned char *buf,int value);
*
* "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)
+ * (as opposed to in the process of decoding)
*/
extern const SEC_ASN1Template *
-SEC_ASN1GetSubtemplate (const SEC_ASN1Template *inTemplate, void *thing,
- PRBool encoding);
+SEC_ASN1GetSubtemplate(const SEC_ASN1Template *inTemplate, void *thing,
+ PRBool encoding);
/* whether the template is for a primitive type or a choice of
* primitive types
@@ -173,9 +172,9 @@ 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
+ * - 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.
diff --git a/nss/lib/util/secasn1d.c b/nss/lib/util/secasn1d.c
index 7a5bcfd..797640d 100644
--- a/nss/lib/util/secasn1d.c
+++ b/nss/lib/util/secasn1d.c
@@ -14,6 +14,8 @@
#define PR_Assert sec_asn1d_Assert
#endif
+#include <limits.h>
+
#include "secasn1.h"
#include "secerr.h"
@@ -48,7 +50,7 @@ typedef enum {
} sec_asn1d_parse_place;
#ifdef DEBUG_ASN1D_STATES
-static const char * const place_names[] = {
+static const char *const place_names[] = {
"beforeIdentifier",
"duringIdentifier",
"afterIdentifier",
@@ -78,16 +80,16 @@ static const char * const place_names[] = {
"notInUse"
};
-static const char * const class_names[] = {
+static const char *const class_names[] = {
"UNIVERSAL",
"APPLICATION",
"CONTEXT_SPECIFIC",
"PRIVATE"
};
-static const char * const method_names[] = { "PRIMITIVE", "CONSTRUCTED" };
+static const char *const method_names[] = { "PRIMITIVE", "CONSTRUCTED" };
-static const char * const type_names[] = {
+static const char *const type_names[] = {
"END_OF_CONTENTS",
"BOOLEAN",
"INTEGER",
@@ -122,7 +124,8 @@ static const char * const type_names[] = {
"HIGH_TAG_VALUE"
};
-static const char * const flag_names[] = { /* flags, right to left */
+static const char *const flag_names[] = {
+ /* flags, right to left */
"OPTIONAL",
"EXPLICIT",
"ANY",
@@ -133,7 +136,7 @@ static const char * const flag_names[] = { /* flags, right to left */
"SKIP",
"INNER",
"SAVE",
- "", /* decoder ignores "MAY_STREAM", */
+ "", /* decoder ignores "MAY_STREAM", */
"SKIP_REST",
"CHOICE",
"NO_STREAM",
@@ -146,16 +149,16 @@ static const char * const flag_names[] = { /* flags, right to left */
};
static int /* bool */
-formatKind(unsigned long kind, char * buf)
+ 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);
+ 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] );
+ sprintf(buf, " %s", class_names[(kind & SEC_ASN1_CLASS_MASK) >> 6]);
buf += strlen(buf);
}
if (kind & SEC_ASN1_METHOD_MASK) {
@@ -164,7 +167,7 @@ formatKind(unsigned long kind, char * buf)
}
if ((kind & SEC_ASN1_CLASS_MASK) == SEC_ASN1_UNIVERSAL) {
if (k || !notag) {
- sprintf(buf, " %s", type_names[k] );
+ sprintf(buf, " %s", type_names[k]);
if ((k == SEC_ASN1_SET || k == SEC_ASN1_SEQUENCE) &&
(kind & SEC_ASN1_GROUP)) {
buf += strlen(buf);
@@ -196,7 +199,7 @@ typedef enum {
struct subitem {
const void *data;
- unsigned long len; /* only used for substrings */
+ unsigned long len; /* only used for substrings */
struct subitem *next;
};
@@ -205,10 +208,10 @@ typedef struct sec_asn1d_state_struct {
const SEC_ASN1Template *theTemplate;
void *dest;
- void *our_mark; /* free on completion */
+ void *our_mark; /* free on completion */
- struct sec_asn1d_state_struct *parent; /* aka prev */
- struct sec_asn1d_state_struct *child; /* aka next */
+ struct sec_asn1d_state_struct *parent; /* aka prev */
+ struct sec_asn1d_state_struct *child; /* aka next */
sec_asn1d_parse_place place;
@@ -244,26 +247,25 @@ typedef struct sec_asn1d_state_struct {
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 */
+ 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 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 HIGH_BITS(field,cnt) ((field) >> ((sizeof(field) * 8) - (cnt)))
+#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
@@ -272,111 +274,108 @@ typedef struct sec_asn1d_state_struct {
* SEC_ASN1DecoderFinish().
*/
struct sec_DecoderContext_struct {
- PLArenaPool *our_pool; /* for our internal allocs */
- PLArenaPool *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)
- */
+ PLArenaPool *our_pool; /* for our internal allocs */
+ PLArenaPool *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 */
+ 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_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 */
+ 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 (PLArenaPool *poolp, unsigned long len)
+sec_asn1d_alloc(PLArenaPool *poolp, unsigned long len)
{
void *thing;
if (poolp != NULL) {
- /*
- * Allocate from the pool.
- */
- thing = PORT_ArenaAlloc (poolp, len);
+ /*
+ * Allocate from the pool.
+ */
+ thing = PORT_ArenaAlloc(poolp, len);
} else {
- /*
- * Allocate generically.
- */
- thing = PORT_Alloc (len);
+ /*
+ * Allocate generically.
+ */
+ thing = PORT_Alloc(len);
}
return thing;
}
-
/*
* XXX this is a fairly generic function that may belong elsewhere
*/
static void *
-sec_asn1d_zalloc (PLArenaPool *poolp, unsigned long len)
+sec_asn1d_zalloc(PLArenaPool *poolp, unsigned long len)
{
void *thing;
- thing = sec_asn1d_alloc (poolp, len);
+ thing = sec_asn1d_alloc(poolp, len);
if (thing != NULL)
- PORT_Memset (thing, 0, len);
+ 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_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);
+ PORT_Assert(state == NULL || state->child == NULL);
if (state != NULL) {
- PORT_Assert (state->our_mark == NULL);
- state->our_mark = PORT_ArenaMark (cx->our_pool);
+ 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));
+ new_state = (sec_asn1d_state *)sec_asn1d_zalloc(cx->our_pool,
+ sizeof(*new_state));
if (new_state == NULL) {
- goto loser;
+ goto loser;
}
- new_state->top = cx;
- new_state->parent = state;
+ new_state->top = cx;
+ new_state->parent = state;
new_state->theTemplate = theTemplate;
- new_state->place = notInUse;
+ new_state->place = notInUse;
if (dest != NULL)
- new_state->dest = (char *)dest + theTemplate->offset;
+ 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;
+ 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;
@@ -385,15 +384,14 @@ sec_asn1d_push_state (SEC_ASN1DecoderContext *cx,
loser:
cx->status = decodeError;
if (state != NULL) {
- PORT_ArenaRelease(cx->our_pool, state->our_mark);
- state->our_mark = 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)
+sec_asn1d_scrub_state(sec_asn1d_state *state)
{
/*
* Some default "scrubbing".
@@ -403,94 +401,90 @@ sec_asn1d_scrub_state (sec_asn1d_state *state)
state->endofcontents = PR_FALSE;
state->indefinite = PR_FALSE;
state->missing = PR_FALSE;
- PORT_Assert (state->consumed == 0);
+ PORT_Assert(state->consumed == 0);
}
-
static void
-sec_asn1d_notify_before (SEC_ASN1DecoderContext *cx, void *dest, int depth)
+sec_asn1d_notify_before(SEC_ASN1DecoderContext *cx, void *dest, int depth)
{
if (cx->notify_proc == NULL)
- return;
+ return;
cx->during_notify = PR_TRUE;
- (* cx->notify_proc) (cx->notify_arg, PR_TRUE, dest, depth);
+ (*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)
+sec_asn1d_notify_after(SEC_ASN1DecoderContext *cx, void *dest, int depth)
{
if (cx->notify_proc == NULL)
- return;
+ return;
cx->during_notify = PR_TRUE;
- (* cx->notify_proc) (cx->notify_arg, PR_FALSE, dest, depth);
+ (*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)
+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;
+ 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;
- }
+ /*
+ * 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;
+ ? PR_TRUE
+ : PR_FALSE;
explicit = (encode_kind & SEC_ASN1_EXPLICIT) ? PR_TRUE : PR_FALSE;
encode_kind &= ~SEC_ASN1_EXPLICIT;
@@ -498,13 +492,13 @@ sec_asn1d_init_state_based_on_template (sec_asn1d_state *state)
optional = (encode_kind & SEC_ASN1_OPTIONAL) ? PR_TRUE : PR_FALSE;
encode_kind &= ~SEC_ASN1_OPTIONAL;
- PORT_Assert (!(explicit && universal)); /* bad templates */
+ 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? */
+#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;
@@ -514,169 +508,164 @@ sec_asn1d_init_state_based_on_template (sec_asn1d_state *state)
child->place = beforeChoice;
return child;
#else
- state->place = beforeChoice;
- return state;
+ 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;
+ 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;
+ /*
+ * 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;
+ /*
+ * 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);
+ 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;
+ 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;
- }
+ 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;
@@ -686,7 +675,7 @@ sec_asn1d_init_state_based_on_template (sec_asn1d_state *state)
state->explicit = explicit;
state->optional = optional;
- sec_asn1d_scrub_state (state);
+ sec_asn1d_scrub_state(state);
return state;
}
@@ -695,19 +684,19 @@ 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) {
+ 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.
- */
+ ** the enclosing construct.
+ */
break;
- }
+ }
}
return state;
}
@@ -718,32 +707,32 @@ 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;
+ 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;
+ 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)
+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);
+ PORT_Assert(state->place == beforeIdentifier);
if (len == 0) {
- state->top->status = needBytes;
- return 0;
+ state->top->status = needBytes;
+ return 0;
}
- byte = (unsigned char) *buf;
+ byte = (unsigned char)*buf;
#ifdef DEBUG_ASN1D_STATES
{
char kindBuf[256];
@@ -753,128 +742,122 @@ sec_asn1d_parse_identifier (sec_asn1d_state *state,
#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;
+ 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;
+ 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)
+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);
+ PORT_Assert(state->pending == 1);
+ PORT_Assert(state->place == duringIdentifier);
if (len == 0) {
- state->top->status = needBytes;
- return 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;
- }
+ 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;
+ state->found_tag_number <<= TAG_NUMBER_BITS;
- byte = (unsigned char) buf[count++];
- state->found_tag_number |= (byte & TAG_NUMBER_MASK);
+ byte = (unsigned char)buf[count++];
+ state->found_tag_number |= (byte & TAG_NUMBER_MASK);
- len--;
- if (LAST_TAG_NUMBER_BYTE (byte))
- state->pending = 0;
+ len--;
+ if (LAST_TAG_NUMBER_BYTE(byte))
+ state->pending = 0;
}
if (state->pending == 0)
- state->place = afterIdentifier;
+ state->place = afterIdentifier;
return count;
}
-
static void
-sec_asn1d_confirm_identifier (sec_asn1d_state *state)
+sec_asn1d_confirm_identifier(sec_asn1d_state *state)
{
PRBool match;
- PORT_Assert (state->place == afterIdentifier);
+ 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));
+ 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;
+ 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;
- }
+ 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)
+sec_asn1d_parse_length(sec_asn1d_state *state,
+ const char *buf, unsigned long len)
{
unsigned char byte;
- PORT_Assert (state->place == beforeLength);
+ PORT_Assert(state->place == beforeLength);
if (len == 0) {
- state->top->status = needBytes;
- return 0;
+ state->top->status = needBytes;
+ return 0;
}
/*
@@ -882,71 +865,70 @@ sec_asn1d_parse_length (sec_asn1d_state *state,
*/
state->place = afterLength;
- byte = (unsigned char) *buf;
+ byte = (unsigned char)*buf;
- if (LENGTH_IS_SHORT_FORM (byte)) {
- state->contents_length = byte;
+ 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;
- }
+ 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,
+ /* 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;
+ (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)
+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);
+ PORT_Assert(state->pending > 0);
+ PORT_Assert(state->place == duringLength);
if (len == 0) {
- state->top->status = needBytes;
- return 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;
- }
+ 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++];
+ state->contents_length <<= 8;
+ state->contents_length |= (unsigned char)buf[count++];
- len--;
- state->pending--;
+ len--;
+ state->pending--;
}
if (state->pending == 0)
- state->place = afterLength;
+ state->place = afterLength;
return count;
}
@@ -959,19 +941,19 @@ sec_asn1d_parse_more_length (sec_asn1d_state *state,
* decoding error in the given SEC_ASN1DecoderContext, and returns PR_FALSE.
*/
static PRBool
-sec_asn1d_check_and_subtract_length (unsigned long *remaining,
- unsigned long consumed,
- SEC_ASN1DecoderContext *cx)
+sec_asn1d_check_and_subtract_length(unsigned long *remaining,
+ unsigned long consumed,
+ SEC_ASN1DecoderContext *cx)
{
PORT_Assert(remaining);
PORT_Assert(cx);
if (!remaining || !cx) {
- PORT_SetError (SEC_ERROR_INVALID_ARGS);
+ PORT_SetError(SEC_ERROR_INVALID_ARGS);
cx->status = decodeError;
return PR_FALSE;
}
if (*remaining < consumed) {
- PORT_SetError (SEC_ERROR_BAD_DER);
+ PORT_SetError(SEC_ERROR_BAD_DER);
cx->status = decodeError;
return PR_FALSE;
}
@@ -980,7 +962,7 @@ sec_asn1d_check_and_subtract_length (unsigned long *remaining,
}
static void
-sec_asn1d_prepare_for_contents (sec_asn1d_state *state)
+sec_asn1d_prepare_for_contents(sec_asn1d_state *state)
{
SECItem *item;
PLArenaPool *poolp;
@@ -1034,15 +1016,14 @@ sec_asn1d_prepare_for_contents (sec_asn1d_state *state)
parent = state;
do {
if (!sec_asn1d_check_and_subtract_length(
- &remaining, parent->consumed, state->top) ||
+ &remaining, parent->consumed, state->top) ||
/* If parent->indefinite is true, parent->contents_length is
* zero and this is a no-op. */
!sec_asn1d_check_and_subtract_length(
- &remaining, parent->contents_length, state->top) ||
+ &remaining, parent->contents_length, state->top) ||
/* If parent->indefinite is true, then ensure there is enough
* space for an EOC tag of 2 bytes. */
- (parent->indefinite && !sec_asn1d_check_and_subtract_length(
- &remaining, 2, state->top))) {
+ (parent->indefinite && !sec_asn1d_check_and_subtract_length(&remaining, 2, state->top))) {
/* This element is larger than its enclosing element, which is
* invalid. */
return;
@@ -1056,34 +1037,34 @@ sec_asn1d_prepare_for_contents (sec_asn1d_state *state)
* 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;
- }
+ 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;
+ }
}
/*
@@ -1098,15 +1079,16 @@ sec_asn1d_prepare_for_contents (sec_asn1d_state *state)
* 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;
+ 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) {
+ (void)sec_asn1d_init_state_based_on_template(state);
+ }
+ return;
}
/*
@@ -1117,367 +1099,361 @@ sec_asn1d_prepare_for_contents (sec_asn1d_state *state)
* 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;
+ /* 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);
+ (void)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;
- }
+ 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);
+ (void)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? */
+ (void)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)
+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.
+ 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;
+ */
+ }
+ 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);
+ /*
+ * 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
+/* 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.
@@ -1488,34 +1464,33 @@ sec_asn1d_free_child (sec_asn1d_state *state, PRBool error)
** done in the caller of this function, immediately after it returns.
*/
static void
-sec_asn1d_reuse_encoding (sec_asn1d_state *state)
+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);
+ PORT_Assert(child != NULL);
consumed = child->consumed;
child->consumed = 0;
item = (SECItem *)(state->dest);
- PORT_Assert (item != NULL);
+ PORT_Assert(item != NULL);
- PORT_Assert (item->len == consumed);
+ PORT_Assert(item->len == consumed);
/*
* Free any grandchild.
*/
- sec_asn1d_free_child (child, PR_FALSE);
+ sec_asn1d_free_child(child, PR_FALSE);
/*
* Notify after the SAVE field.
*/
- sec_asn1d_notify_after (state->top, state->dest, state->depth);
+ sec_asn1d_notify_after(state->top, state->dest, state->depth);
/*
* Adjust to get new dest and move forward.
@@ -1528,8 +1503,8 @@ sec_asn1d_reuse_encoding (sec_asn1d_state *state)
/*
* Notify before the "real" field.
*/
- PORT_Assert (state->depth == child->depth);
- sec_asn1d_notify_before (state->top, child->dest, child->depth);
+ 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.
@@ -1544,25 +1519,25 @@ sec_asn1d_reuse_encoding (sec_asn1d_state *state)
/*
* And initialize it so it is ready to parse.
*/
- (void) sec_asn1d_init_state_based_on_template(child);
+ (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 (SEC_ASN1DecoderUpdate(state->top,
+ (char *)item->data, item->len) != SECSuccess)
+ return;
if (state->top->status == needBytes) {
- return;
+ return;
}
- PORT_Assert (state->top->current == state);
- PORT_Assert (state->child == child);
+ PORT_Assert(state->top->current == state);
+ PORT_Assert(state->child == child);
/*
* That should have consumed what we consumed before.
*/
- PORT_Assert (consumed == child->consumed);
+ PORT_Assert(consumed == child->consumed);
child->consumed = 0;
/*
@@ -1573,76 +1548,109 @@ sec_asn1d_reuse_encoding (sec_asn1d_state *state)
state->place = afterEndOfContents;
}
-
static unsigned long
-sec_asn1d_parse_leaf (sec_asn1d_state *state,
- const char *buf, unsigned long len)
+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;
+ state->top->status = needBytes;
+ return 0;
}
if (state->pending < len)
- len = state->pending;
+ 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;
+ unsigned long offset;
+ /* 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--;
+ }
+ }
+ offset = item->len;
+ if (state->underlying_kind == SEC_ASN1_BIT_STRING) {
+ // The previous bit string must have no unused bits.
+ if (item->len & 0x7) {
+ PORT_SetError(SEC_ERROR_BAD_DER);
+ state->top->status = decodeError;
+ return 0;
+ }
+ // If this is a bit string, the length is bits, not bytes.
+ offset = item->len >> 3;
+ }
+ if (state->underlying_kind == SEC_ASN1_BIT_STRING) {
+ unsigned long len_in_bits;
+ // Protect against overflow during the bytes-to-bits conversion.
+ if (len >= (ULONG_MAX >> 3) + 1) {
+ PORT_SetError(SEC_ERROR_BAD_DER);
+ state->top->status = decodeError;
+ return 0;
+ }
+ len_in_bits = (len << 3) - state->bit_string_unused_bits;
+ // Protect against overflow when computing the total length in bits.
+ if (UINT_MAX - item->len < len_in_bits) {
+ PORT_SetError(SEC_ERROR_BAD_DER);
+ state->top->status = decodeError;
+ return 0;
+ }
+ item->len += len_in_bits;
+ } else {
+ if (UINT_MAX - item->len < len) {
+ PORT_SetError(SEC_ERROR_BAD_DER);
+ state->top->status = decodeError;
+ return 0;
+ }
+ item->len += len;
+ }
+ PORT_Memcpy(item->data + offset, buf, len);
}
state->pending -= bufLen;
if (state->pending == 0)
- state->place = beforeEndOfContents;
+ state->place = beforeEndOfContents;
return bufLen;
}
-
static unsigned long
-sec_asn1d_parse_bit_string (sec_asn1d_state *state,
- const char *buf, unsigned long len)
+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);
+ 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 (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;
+ state->top->status = needBytes;
+ return 0;
}
- byte = (unsigned char) *buf;
+ byte = (unsigned char)*buf;
if (byte > 7) {
- PORT_SetError (SEC_ERROR_BAD_DER);
- state->top->status = decodeError;
- return 0;
+ PORT_SetError(SEC_ERROR_BAD_DER);
+ state->top->status = decodeError;
+ return 0;
}
state->bit_string_unused_bits = byte;
@@ -1652,102 +1660,90 @@ sec_asn1d_parse_bit_string (sec_asn1d_state *state,
return 1;
}
-
static unsigned long
-sec_asn1d_parse_more_bit_string (sec_asn1d_state *state,
- const char *buf, unsigned long len)
+sec_asn1d_parse_more_bit_string(sec_asn1d_state *state,
+ const char *buf, unsigned long len)
{
- PORT_Assert (state->place == duringBitString);
+ 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;
+ /* 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);
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)
+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));
+ thing = (struct subitem *)sec_asn1d_zalloc(state->top->our_pool,
+ sizeof(struct subitem));
if (thing == NULL) {
- state->top->status = decodeError;
- return 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;
+ 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->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;
+ PORT_Assert(state->subitems_tail == NULL);
+ state->subitems_head = state->subitems_tail = thing;
} else {
- state->subitems_tail->next = thing;
- state->subitems_tail = thing;
+ 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)
+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;
+ 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);
+ 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
@@ -1755,20 +1751,20 @@ sec_asn1d_record_any_header (sec_asn1d_state *state,
* 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)
+ * - 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_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);
+ PORT_Assert(state->place == duringConstructedString);
+ PORT_Assert(state->child != NULL);
child = state->child;
@@ -1779,161 +1775,160 @@ sec_asn1d_next_substring (sec_asn1d_state *state)
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;
+ 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 {
- PRBool preallocatedString;
- sec_asn1d_state *temp_state;
- PORT_Assert (state->indefinite);
-
- item = (SECItem *)(child->dest);
-
- /**
- * At this point, there's three states at play:
- * child: The element that was just parsed
- * state: The currently processed element
- * 'parent' (aka state->parent): The enclosing construct
- * of state, or NULL if this is the top-most element.
- *
- * This state handles both substrings of a constructed string AND
- * child elements of items whose template type was that of
- * SEC_ASN1_ANY, SEC_ASN1_SAVE, SEC_ASN1_ANY_CONTENTS, SEC_ASN1_SKIP
- * template, as described in sec_asn1d_prepare_for_contents. For
- * brevity, these will be referred to as 'string' and 'any' types.
- *
- * This leads to the following possibilities:
- * 1: This element is an indefinite length string, part of a
- * definite length string.
- * 2: This element is an indefinite length string, part of an
- * indefinite length string.
- * 3: This element is an indefinite length any, part of a
- * definite length any.
- * 4: This element is an indefinite length any, part of an
- * indefinite length any.
- * 5: This element is an indefinite length any and does not
- * meet any of the above criteria. Note that this would include
- * an indefinite length string type matching an indefinite
- * length any template.
- *
- * In Cases #1 and #3, the definite length 'parent' element will
- * have allocated state->dest based on the parent elements definite
- * size. During the processing of 'child', sec_asn1d_parse_leaf will
- * have copied the (string, any) data directly into the offset of
- * dest, as appropriate, so there's no need for this class to still
- * store the child - it's already been processed.
- *
- * In Cases #2 and #4, dest will be set to the parent element's dest,
- * but dest->data will not have been allocated yet, due to the
- * indefinite length encoding. In this situation, it's necessary to
- * hold onto child (and all other children) until the EOC, at which
- * point, it becomes possible to compute 'state's overall length. Once
- * 'state' has a computed length, this can then be fed to 'parent' (via
- * this state), and then 'parent' can similarly compute the length of
- * all of its children up to the EOC, which will ultimately transit to
- * sec_asn1d_concat_substrings, determine the overall size needed,
- * allocate, and copy the contents (of all of parent's children, which
- * would include 'state', just as 'state' will have copied all of its
- * children via sec_asn1d_concat_substrings)
- *
- * The final case, Case #5, will manifest in that item->data and
- * item->len will be NULL/0, respectively, since this element was
- * indefinite-length encoded. In that case, both the tag and length will
- * already exist in state's subitems, via sec_asn1d_record_any_header,
- * and so the contents (aka 'child') should be added to that list of
- * items to concatenate in sec_asn1d_concat_substrings once the EOC
- * is encountered.
- *
- * To distinguish #2/#4 from #1/#3, it's sufficient to walk the ancestor
- * tree. If the current type is a string type, then the enclosing
- * construct will be that same type (#1/#2). If the current type is an
- * any type, then the enclosing construct is either an any type (#3/#4)
- * or some other type (#5). Since this is BER, this nesting relationship
- * between 'state' and 'parent' may go through several levels of
- * constructed encoding, so continue walking the ancestor chain until a
- * clear determination can be made.
- *
- * The variable preallocatedString is used to indicate Case #1/#3,
- * indicating an in-place copy has already occurred, and Cases #2, #4,
- * and #5 all have the same behaviour of adding a new substring.
- */
- preallocatedString = PR_FALSE;
- temp_state = state;
- while (temp_state && item == temp_state->dest && temp_state->indefinite) {
- sec_asn1d_state *parent = sec_asn1d_get_enclosing_construct(temp_state);
- if (!parent || parent->underlying_kind != temp_state->underlying_kind) {
- /* Case #5 - Either this is a top-level construct or it is part
- * of some other element (e.g. a SEQUENCE), in which case, a
- * new item should be allocated. */
- break;
- }
- if (!parent->indefinite) {
- /* Cases #1 / #3 - A definite length ancestor exists, for which
- * this is a substring that has already copied into dest. */
- preallocatedString = PR_TRUE;
- break;
- }
- if (!parent->substring) {
- /* Cases #2 / #4 - If the parent is not a substring, but is
- * indefinite, then there's nothing further up that may have
- * preallocated dest, thus child will not have already
- * been copied in place, therefore it's necessary to save child
- * as a subitem. */
- break;
- }
- temp_state = parent;
- }
- if (item != NULL && item->data != NULL && !preallocatedString) {
- /*
- * 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;
+ PRBool preallocatedString;
+ sec_asn1d_state *temp_state;
+ PORT_Assert(state->indefinite);
+
+ item = (SECItem *)(child->dest);
+
+ /**
+ * At this point, there's three states at play:
+ * child: The element that was just parsed
+ * state: The currently processed element
+ * 'parent' (aka state->parent): The enclosing construct
+ * of state, or NULL if this is the top-most element.
+ *
+ * This state handles both substrings of a constructed string AND
+ * child elements of items whose template type was that of
+ * SEC_ASN1_ANY, SEC_ASN1_SAVE, SEC_ASN1_ANY_CONTENTS, SEC_ASN1_SKIP
+ * template, as described in sec_asn1d_prepare_for_contents. For
+ * brevity, these will be referred to as 'string' and 'any' types.
+ *
+ * This leads to the following possibilities:
+ * 1: This element is an indefinite length string, part of a
+ * definite length string.
+ * 2: This element is an indefinite length string, part of an
+ * indefinite length string.
+ * 3: This element is an indefinite length any, part of a
+ * definite length any.
+ * 4: This element is an indefinite length any, part of an
+ * indefinite length any.
+ * 5: This element is an indefinite length any and does not
+ * meet any of the above criteria. Note that this would include
+ * an indefinite length string type matching an indefinite
+ * length any template.
+ *
+ * In Cases #1 and #3, the definite length 'parent' element will
+ * have allocated state->dest based on the parent elements definite
+ * size. During the processing of 'child', sec_asn1d_parse_leaf will
+ * have copied the (string, any) data directly into the offset of
+ * dest, as appropriate, so there's no need for this class to still
+ * store the child - it's already been processed.
+ *
+ * In Cases #2 and #4, dest will be set to the parent element's dest,
+ * but dest->data will not have been allocated yet, due to the
+ * indefinite length encoding. In this situation, it's necessary to
+ * hold onto child (and all other children) until the EOC, at which
+ * point, it becomes possible to compute 'state's overall length. Once
+ * 'state' has a computed length, this can then be fed to 'parent' (via
+ * this state), and then 'parent' can similarly compute the length of
+ * all of its children up to the EOC, which will ultimately transit to
+ * sec_asn1d_concat_substrings, determine the overall size needed,
+ * allocate, and copy the contents (of all of parent's children, which
+ * would include 'state', just as 'state' will have copied all of its
+ * children via sec_asn1d_concat_substrings)
+ *
+ * The final case, Case #5, will manifest in that item->data and
+ * item->len will be NULL/0, respectively, since this element was
+ * indefinite-length encoded. In that case, both the tag and length will
+ * already exist in state's subitems, via sec_asn1d_record_any_header,
+ * and so the contents (aka 'child') should be added to that list of
+ * items to concatenate in sec_asn1d_concat_substrings once the EOC
+ * is encountered.
+ *
+ * To distinguish #2/#4 from #1/#3, it's sufficient to walk the ancestor
+ * tree. If the current type is a string type, then the enclosing
+ * construct will be that same type (#1/#2). If the current type is an
+ * any type, then the enclosing construct is either an any type (#3/#4)
+ * or some other type (#5). Since this is BER, this nesting relationship
+ * between 'state' and 'parent' may go through several levels of
+ * constructed encoding, so continue walking the ancestor chain until a
+ * clear determination can be made.
+ *
+ * The variable preallocatedString is used to indicate Case #1/#3,
+ * indicating an in-place copy has already occurred, and Cases #2, #4,
+ * and #5 all have the same behaviour of adding a new substring.
+ */
+ preallocatedString = PR_FALSE;
+ temp_state = state;
+ while (temp_state && item == temp_state->dest && temp_state->indefinite) {
+ sec_asn1d_state *parent = sec_asn1d_get_enclosing_construct(temp_state);
+ if (!parent || parent->underlying_kind != temp_state->underlying_kind) {
+ /* Case #5 - Either this is a top-level construct or it is part
+ * of some other element (e.g. a SEQUENCE), in which case, a
+ * new item should be allocated. */
+ break;
+ }
+ if (!parent->indefinite) {
+ /* Cases #1 / #3 - A definite length ancestor exists, for which
+ * this is a substring that has already copied into dest. */
+ preallocatedString = PR_TRUE;
+ break;
+ }
+ if (!parent->substring) {
+ /* Cases #2 / #4 - If the parent is not a substring, but is
+ * indefinite, then there's nothing further up that may have
+ * preallocated dest, thus child will not have already
+ * been copied in place, therefore it's necessary to save child
+ * as a subitem. */
+ break;
+ }
+ temp_state = parent;
+ }
+ if (item != NULL && item->data != NULL && !preallocatedString) {
+ /*
+ * 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;
+ child->place = notInUse;
+ state->place = afterConstructedString;
} else {
- sec_asn1d_scrub_state (child);
- state->top->current = child;
+ 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_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);
+ PORT_Assert(state->place == duringGroup);
+ PORT_Assert(state->child != NULL);
child = state->child;
@@ -1945,80 +1940,80 @@ sec_asn1d_next_in_group (sec_asn1d_state *state)
* 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;
- }
-
- /*
+ /* 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);
+ sec_asn1d_notify_after(state->top, child->dest, child->depth);
/*
* Save it away (unless we are not storing).
*/
if (child->dest != NULL) {
- void *dest;
+ void *dest;
- dest = child->dest;
- dest = (char *)dest - child->theTemplate->offset;
- sec_asn1d_add_to_subitems (state, dest, 0, PR_FALSE);
- child->dest = NULL;
+ 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;
- }
+ 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;
- }
+ 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);
+ sec_asn1d_notify_before(state->top, child->dest, child->depth);
/*
* Now we do the next one.
*/
- sec_asn1d_scrub_state (child);
+ sec_asn1d_scrub_state(child);
/* Initialize child state from the template */
sec_asn1d_init_state_based_on_template(child);
@@ -2026,30 +2021,29 @@ sec_asn1d_next_in_group (sec_asn1d_state *state)
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_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);
+ 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);
+ sec_asn1d_notify_after(state->top, child->dest, child->depth);
- child_missing = (PRBool) child->missing;
+ child_missing = (PRBool)child->missing;
child_consumed = child->consumed;
child->consumed = 0;
@@ -2057,36 +2051,36 @@ sec_asn1d_next_in_sequence (sec_asn1d_state *state)
* Take care of accounting.
*/
if (child_missing) {
- PORT_Assert (child->optional);
+ 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;
- }
- }
+ 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;
+ }
+ }
}
/*
@@ -2094,239 +2088,235 @@ sec_asn1d_next_in_sequence (sec_asn1d_state *state)
*/
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;
- }
+ /*
+ * 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);
- }
- }
+ 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)
+sec_asn1d_concat_substrings(sec_asn1d_state *state)
{
- PORT_Assert (state->place == afterConstructedString);
+ 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;
+ 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)
+sec_asn1d_concat_group(sec_asn1d_state *state)
{
const void ***placep;
- PORT_Assert (state->place == afterGroup);
+ PORT_Assert(state->place == afterGroup);
- placep = (const void***)state->dest;
+ 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;
+ 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)
+sec_asn1d_absorb_child(sec_asn1d_state *state)
{
/*
* There is absolutely supposed to be a child there.
*/
- PORT_Assert (state->child != NULL);
+ PORT_Assert(state->child != NULL);
/*
* Inherit the missing status of our child, and do the ugly
@@ -2334,16 +2324,16 @@ sec_asn1d_absorb_child (sec_asn1d_state *state)
*/
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;
+ 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);
+ PORT_Assert(state->place == afterExplicit || state->consumed == 0);
state->consumed += state->child->consumed;
/*
@@ -2351,34 +2341,34 @@ sec_asn1d_absorb_child (sec_asn1d_state *state)
* 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;
+ 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;
}
/*
@@ -2392,90 +2382,87 @@ sec_asn1d_absorb_child (sec_asn1d_state *state)
* 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));
+ PORT_Assert(state->place == afterExplicit || (!state->indefinite));
state->place = beforeEndOfContents;
}
-
static void
-sec_asn1d_prepare_for_end_of_contents (sec_asn1d_state *state)
+sec_asn1d_prepare_for_end_of_contents(sec_asn1d_state *state)
{
- PORT_Assert (state->place == beforeEndOfContents);
+ PORT_Assert(state->place == beforeEndOfContents);
if (state->indefinite) {
- state->place = duringEndOfContents;
- state->pending = 2;
+ state->place = duringEndOfContents;
+ state->pending = 2;
} else {
- state->place = afterEndOfContents;
+ state->place = afterEndOfContents;
}
}
-
static unsigned long
-sec_asn1d_parse_end_of_contents (sec_asn1d_state *state,
- const char *buf, unsigned long len)
+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);
+ PORT_Assert(state->pending <= 2);
+ PORT_Assert(state->place == duringEndOfContents);
if (len == 0) {
- state->top->status = needBytes;
- return 0;
+ state->top->status = needBytes;
+ return 0;
}
if (state->pending < len)
- len = state->pending;
+ 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;
- }
+ 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;
+ state->place = afterEndOfContents;
+ state->endofcontents = PR_TRUE;
}
return len;
}
-
static void
-sec_asn1d_pop_state (sec_asn1d_state *state)
+sec_asn1d_pop_state(sec_asn1d_state *state)
{
-#if 0 /* XXX I think this should always be handled explicitly by parent? */
+#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 */
+ 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);
+ sec_asn1d_free_child(state, PR_FALSE);
/*
* Just make my parent be the current state. It will then clean
@@ -2485,33 +2472,33 @@ sec_asn1d_pop_state (sec_asn1d_state *state)
}
static sec_asn1d_state *
-sec_asn1d_before_choice (sec_asn1d_state *state)
+sec_asn1d_before_choice(sec_asn1d_state *state)
{
sec_asn1d_state *child;
if (state->allocate) {
- void *dest;
+ 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;
- }
+ 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;
+ 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);
+ 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;
+ 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;
+ return (sec_asn1d_state *)NULL;
}
child->optional = PR_TRUE;
@@ -2522,94 +2509,94 @@ sec_asn1d_before_choice (sec_asn1d_state *state)
}
static sec_asn1d_state *
-sec_asn1d_during_choice (sec_asn1d_state *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;
- }
+ 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;
+ /* Store the enum */
+ int *which = (int *)state->dest;
+ *which = (int)child->theTemplate->size;
}
child->place = notInUse;
@@ -2619,7 +2606,7 @@ sec_asn1d_during_choice (sec_asn1d_state *state)
}
static void
-sec_asn1d_after_choice (sec_asn1d_state *state)
+sec_asn1d_after_choice(sec_asn1d_state *state)
{
state->consumed += state->child->consumed;
state->child->consumed = 0;
@@ -2634,13 +2621,13 @@ sec_asn1d_uinteger(SECItem *src)
int len;
if (src->len > 5 || (src->len > 4 && src->data[0] == 0))
- return 0;
+ return 0;
value = 0;
len = src->len;
while (len) {
- value <<= 8;
- value |= src->data[--len];
+ value <<= 8;
+ value |= src->data[--len];
}
return value;
}
@@ -2650,31 +2637,31 @@ SEC_ASN1DecodeInteger(SECItem *src, unsigned long *value)
{
unsigned long v;
unsigned int i;
-
+
if (src == NULL) {
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- return SECFailure;
+ PORT_SetError(SEC_ERROR_INVALID_ARGS);
+ return SECFailure;
}
if (src->len > sizeof(unsigned long)) {
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- return SECFailure;
+ PORT_SetError(SEC_ERROR_INVALID_ARGS);
+ return SECFailure;
}
if (src->data == NULL) {
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- return SECFailure;
+ PORT_SetError(SEC_ERROR_INVALID_ARGS);
+ return SECFailure;
}
if (src->data[0] & 0x80)
- v = -1; /* signed and negative - start with all 1's */
+ v = -1; /* signed and negative - start with all 1's */
else
- v = 0;
+ v = 0;
- for (i= 0; i < src->len; i++) {
- /* shift in next byte */
- v <<= 8;
- v |= src->data[i];
+ for (i = 0; i < src->len; i++) {
+ /* shift in next byte */
+ v <<= 8;
+ v |= src->data[i];
}
*value = v;
return SECSuccess;
@@ -2703,18 +2690,17 @@ dump_states(SEC_ASN1DecoderContext *cx)
state->theTemplate,
kindBuf);
printf(" %s", (state->place >= 0 && state->place <= notInUse)
- ? place_names[ state->place ]
- : "(undefined)");
+ ? 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
- );
+ state->indefinite ? ", indef" : "",
+ state->missing ? ", miss" : "",
+ state->endofcontents ? ", EOC" : "",
+ state->pending);
}
return;
@@ -2722,8 +2708,8 @@ dump_states(SEC_ASN1DecoderContext *cx)
#endif /* DEBUG_ASN1D_STATES */
SECStatus
-SEC_ASN1DecoderUpdate (SEC_ASN1DecoderContext *cx,
- const char *buf, unsigned long len)
+SEC_ASN1DecoderUpdate(SEC_ASN1DecoderContext *cx,
+ const char *buf, unsigned long len)
{
sec_asn1d_state *state = NULL;
unsigned long consumed;
@@ -2731,341 +2717,328 @@ SEC_ASN1DecoderUpdate (SEC_ASN1DecoderContext *cx,
sec_asn1d_state *stateEnd = cx->current;
if (cx->status == needBytes)
- cx->status = keepGoing;
+ cx->status = keepGoing;
while (cx->status == keepGoing) {
- state = cx->current;
- what = SEC_ASN1_Contents;
- consumed = 0;
+ 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 ],
+ (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);
+ 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;
- case afterChoice:
- sec_asn1d_after_choice(state);
+
+ /* 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;
- 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
+ }
+
+ /* 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;
+ 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);
- cx->their_mark = NULL;
- }
+ 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);
+ cx->their_mark = NULL;
+ }
#endif
- return SECFailure;
+ 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.
- */
+#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));
+ && (cx->status == needBytes || cx->status == allDone));
#else
- PORT_Assert ((len == 0 && cx->status == needBytes)
- || cx->status == allDone);
+ PORT_Assert((len == 0 && cx->status == needBytes) || cx->status == allDone);
#endif
return SECSuccess;
}
-
SECStatus
-SEC_ASN1DecoderFinish (SEC_ASN1DecoderContext *cx)
+SEC_ASN1DecoderFinish(SEC_ASN1DecoderContext *cx)
{
SECStatus rv;
if (cx->status == needBytes) {
- PORT_SetError (SEC_ERROR_BAD_DER);
- rv = SECFailure;
+ PORT_SetError(SEC_ERROR_BAD_DER);
+ rv = SECFailure;
} else {
- rv = SECSuccess;
+ rv = SECSuccess;
}
/*
* XXX anything else that needs to be finished?
*/
- PORT_FreeArena (cx->our_pool, PR_TRUE);
+ PORT_FreeArena(cx->our_pool, PR_TRUE);
return rv;
}
-
SEC_ASN1DecoderContext *
-SEC_ASN1DecoderStart (PLArenaPool *their_pool, void *dest,
- const SEC_ASN1Template *theTemplate)
+SEC_ASN1DecoderStart(PLArenaPool *their_pool, void *dest,
+ const SEC_ASN1Template *theTemplate)
{
PLArenaPool *our_pool;
SEC_ASN1DecoderContext *cx;
- our_pool = PORT_NewArena (SEC_ASN1_DEFAULT_ARENA_SIZE);
+ our_pool = PORT_NewArena(SEC_ASN1_DEFAULT_ARENA_SIZE);
if (our_pool == NULL)
- return NULL;
+ return NULL;
- cx = (SEC_ASN1DecoderContext*)PORT_ArenaZAlloc (our_pool, sizeof(*cx));
+ cx = (SEC_ASN1DecoderContext *)PORT_ArenaZAlloc(our_pool, sizeof(*cx));
if (cx == NULL) {
- PORT_FreeArena (our_pool, PR_FALSE);
- return NULL;
+ PORT_FreeArena(our_pool, PR_FALSE);
+ return NULL;
}
cx->our_pool = our_pool;
if (their_pool != NULL) {
- cx->their_pool = their_pool;
+ cx->their_pool = their_pool;
#ifdef SEC_ASN1D_FREE_ON_ERROR
- cx->their_mark = PORT_ArenaMark (their_pool);
+ 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;
+ 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)
+SEC_ASN1DecoderSetFilterProc(SEC_ASN1DecoderContext *cx,
+ SEC_ASN1WriteProc fn, void *arg,
+ PRBool only)
{
/* check that we are "between" fields here */
- PORT_Assert (cx->during_notify);
+ PORT_Assert(cx->during_notify);
cx->filter_proc = fn;
cx->filter_arg = arg;
cx->filter_only = only;
}
-
void
-SEC_ASN1DecoderClearFilterProc (SEC_ASN1DecoderContext *cx)
+SEC_ASN1DecoderClearFilterProc(SEC_ASN1DecoderContext *cx)
{
/* check that we are "between" fields here */
- PORT_Assert (cx->during_notify);
+ 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)
+SEC_ASN1DecoderSetNotifyProc(SEC_ASN1DecoderContext *cx,
+ SEC_ASN1NotifyProc fn, void *arg)
{
cx->notify_proc = fn;
cx->notify_arg = arg;
}
-
void
-SEC_ASN1DecoderClearNotifyProc (SEC_ASN1DecoderContext *cx)
+SEC_ASN1DecoderClearNotifyProc(SEC_ASN1DecoderContext *cx)
{
cx->notify_proc = NULL;
- cx->notify_arg = NULL; /* not necessary; just being clean */
+ cx->notify_arg = NULL; /* not necessary; just being clean */
}
void
@@ -3076,40 +3049,39 @@ SEC_ASN1DecoderAbort(SEC_ASN1DecoderContext *cx, int error)
cx->status = decodeError;
}
-
SECStatus
-SEC_ASN1Decode (PLArenaPool *poolp, void *dest,
- const SEC_ASN1Template *theTemplate,
- const char *buf, long len)
+SEC_ASN1Decode(PLArenaPool *poolp, void *dest,
+ const SEC_ASN1Template *theTemplate,
+ const char *buf, long len)
{
SEC_ASN1DecoderContext *dcx;
SECStatus urv, frv;
- dcx = SEC_ASN1DecoderStart (poolp, dest, theTemplate);
+ dcx = SEC_ASN1DecoderStart(poolp, dest, theTemplate);
if (dcx == NULL)
- return SECFailure;
+ return SECFailure;
- urv = SEC_ASN1DecoderUpdate (dcx, buf, len);
- frv = SEC_ASN1DecoderFinish (dcx);
+ urv = SEC_ASN1DecoderUpdate(dcx, buf, len);
+ frv = SEC_ASN1DecoderFinish(dcx);
if (urv != SECSuccess)
- return urv;
+ return urv;
return frv;
}
-
SECStatus
-SEC_ASN1DecodeItem (PLArenaPool *poolp, void *dest,
- const SEC_ASN1Template *theTemplate,
- const SECItem *src)
+SEC_ASN1DecodeItem(PLArenaPool *poolp, void *dest,
+ const SEC_ASN1Template *theTemplate,
+ const SECItem *src)
{
- return SEC_ASN1Decode (poolp, dest, theTemplate,
- (const char *)src->data, src->len);
+ 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)
+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);
@@ -3121,15 +3093,15 @@ void sec_asn1d_Assert(const char *s, const char *file, PRIntn ln)
* 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.
+ * - 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[] = {
@@ -3273,7 +3245,7 @@ const SEC_ASN1Template SEC_SetOfOctetStringTemplate[] = {
#endif
const SEC_ASN1Template SEC_PrintableStringTemplate[] = {
- { SEC_ASN1_PRINTABLE_STRING | SEC_ASN1_MAY_STREAM, 0, NULL, sizeof(SECItem)}
+ { SEC_ASN1_PRINTABLE_STRING | SEC_ASN1_MAY_STREAM, 0, NULL, sizeof(SECItem) }
};
#if 0
@@ -3313,7 +3285,7 @@ const SEC_ASN1Template SEC_SetOfT61StringTemplate[] = {
#endif
const SEC_ASN1Template SEC_UniversalStringTemplate[] = {
- { SEC_ASN1_UNIVERSAL_STRING | SEC_ASN1_MAY_STREAM, 0, NULL, sizeof(SECItem)}
+ { SEC_ASN1_UNIVERSAL_STRING | SEC_ASN1_MAY_STREAM, 0, NULL, sizeof(SECItem) }
};
#if 0
@@ -3387,7 +3359,6 @@ 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.
*/
@@ -3400,4 +3371,3 @@ 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/nss/lib/util/secasn1e.c b/nss/lib/util/secasn1e.c
index 1f85dfc..fb3feef 100644
--- a/nss/lib/util/secasn1e.c
+++ b/nss/lib/util/secasn1e.c
@@ -30,11 +30,11 @@ typedef enum {
} 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 */
+ 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 {
@@ -42,10 +42,10 @@ typedef struct sec_asn1e_state_struct {
const SEC_ASN1Template *theTemplate;
void *src;
- struct sec_asn1e_state_struct *parent; /* aka prev */
- struct sec_asn1e_state_struct *child; /* aka next */
+ 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 */
+ sec_asn1e_parse_place place; /* where we are in encoding process */
/*
* XXX explain the next fields as clearly as possible...
@@ -56,12 +56,12 @@ typedef struct sec_asn1e_state_struct {
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 */
+ 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;
/*
@@ -71,7 +71,7 @@ typedef struct sec_asn1e_state_struct {
* it is passed to SEC_ASN1EncoderFinish().
*/
struct sec_EncoderContext_struct {
- PLArenaPool *our_pool; /* for our internal allocs */
+ PLArenaPool *our_pool; /* for our internal allocs */
sec_asn1e_state *current;
sec_asn1e_parse_status status;
@@ -79,29 +79,28 @@ struct sec_EncoderContext_struct {
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_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 */
+ 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_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));
+ new_state = (sec_asn1e_state *)PORT_ArenaZAlloc(cx->our_pool,
+ sizeof(*new_state));
if (new_state == NULL) {
- cx->status = encodeError;
- return NULL;
+ cx->status = encodeError;
+ return NULL;
}
new_state->top = cx;
@@ -109,22 +108,21 @@ sec_asn1e_push_state (SEC_ASN1EncoderContext *cx,
new_state->theTemplate = theTemplate;
new_state->place = notInUse;
if (src != NULL)
- new_state->src = (char *)src + theTemplate->offset;
+ 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;
+ 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)
+sec_asn1e_scrub_state(sec_asn1e_state *state)
{
/*
* Some default "scrubbing".
@@ -134,46 +132,43 @@ sec_asn1e_scrub_state (sec_asn1e_state *state)
state->indefinite = PR_FALSE;
}
-
static void
-sec_asn1e_notify_before (SEC_ASN1EncoderContext *cx, void *src, int depth)
+sec_asn1e_notify_before(SEC_ASN1EncoderContext *cx, void *src, int depth)
{
if (cx->notify_proc == NULL)
- return;
+ return;
cx->during_notify = PR_TRUE;
- (* cx->notify_proc) (cx->notify_arg, PR_TRUE, src, depth);
+ (*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)
+sec_asn1e_notify_after(SEC_ASN1EncoderContext *cx, void *src, int depth)
{
if (cx->notify_proc == NULL)
- return;
+ return;
cx->during_notify = PR_TRUE;
- (* cx->notify_proc) (cx->notify_arg, PR_FALSE, src, depth);
+ (*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)
+sec_asn1e_init_state_based_on_template(sec_asn1e_state *state)
{
- PRBool isExplicit, is_string, may_stream, optional, universal;
+ 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;
+ ? PR_TRUE
+ : PR_FALSE;
isExplicit = (encode_kind & SEC_ASN1_EXPLICIT) ? PR_TRUE : PR_FALSE;
encode_kind &= ~SEC_ASN1_EXPLICIT;
@@ -181,7 +176,7 @@ sec_asn1e_init_state_based_on_template (sec_asn1e_state *state)
optional = (encode_kind & SEC_ASN1_OPTIONAL) ? PR_TRUE : PR_FALSE;
encode_kind &= ~SEC_ASN1_OPTIONAL;
- PORT_Assert (!(isExplicit && universal)); /* bad templates */
+ PORT_Assert(!(isExplicit && universal)); /* bad templates */
may_stream = (encode_kind & SEC_ASN1_MAY_STREAM) ? PR_TRUE : PR_FALSE;
encode_kind &= ~SEC_ASN1_MAY_STREAM;
@@ -192,169 +187,166 @@ sec_asn1e_init_state_based_on_template (sec_asn1e_state *state)
/* 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);
+ 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;
+ 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)
+#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);
+ 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;
+ 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;
- }
+ 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;
@@ -366,117 +358,112 @@ sec_asn1e_init_state_based_on_template (sec_asn1e_state *state)
state->optional = optional;
state->disallowStreaming = disallowStreaming;
- sec_asn1e_scrub_state (state);
+ 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_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);
+ (*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)
+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);
+ byte = (char)value;
+ sec_asn1e_write_part(state, &byte, 1, SEC_ASN1_Identifier);
}
int
-SEC_ASN1EncodeLength(unsigned char *buf,int value) {
+SEC_ASN1EncodeLength(unsigned char *buf, int value)
+{
int lenlen;
- lenlen = SEC_ASN1LengthLength (value);
+ lenlen = SEC_ASN1LengthLength(value);
if (lenlen == 1) {
- buf[0] = value;
+ buf[0] = value;
} else {
- int i;
-
- i = lenlen - 1;
- buf[0] = 0x80 | i;
- while (i) {
- buf[i--] = value;
- value >>= 8;
- }
- PORT_Assert (value == 0);
+ 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)
+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;
+ PORT_Assert(value == 0);
+ buf[0] = 0x80;
+ lenlen = 1;
} else {
- lenlen = SEC_ASN1EncodeLength(buf,value);
+ lenlen = SEC_ASN1EncodeLength(buf, value);
}
- sec_asn1e_write_part (state, (char *) buf, lenlen, SEC_ASN1_Length);
+ 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_contents_bytes(sec_asn1e_state *state,
+ const char *buf, unsigned long len)
{
- sec_asn1e_write_part (state, buf, len, SEC_ASN1_Contents);
+ sec_asn1e_write_part(state, buf, len, SEC_ASN1_Contents);
}
-
static void
-sec_asn1e_write_end_of_contents_bytes (sec_asn1e_state *state)
+sec_asn1e_write_end_of_contents_bytes(sec_asn1e_state *state)
{
- const char eoc[2] = {0, 0};
+ const char eoc[2] = { 0, 0 };
- sec_asn1e_write_part (state, eoc, 2, SEC_ASN1_EndOfContents);
+ sec_asn1e_write_part(state, eoc, 2, SEC_ASN1_EndOfContents);
}
static int
-sec_asn1e_which_choice
-(
- void *src,
- const SEC_ASN1Template *theTemplate
-)
+sec_asn1e_which_choice(
+ void *src,
+ const SEC_ASN1Template *theTemplate)
{
- int rv;
- unsigned int which = *(unsigned int *)src;
+ int rv;
+ unsigned int which = *(unsigned int *)src;
- for( rv = 1, theTemplate++; theTemplate->kind != 0; rv++, theTemplate++ ) {
- if( which == theTemplate->size ) {
- return rv;
+ for (rv = 1, theTemplate++; theTemplate->kind != 0; rv++, theTemplate++) {
+ if (which == theTemplate->size) {
+ return rv;
+ }
}
- }
- return 0;
+ return 0;
}
static unsigned long
-sec_asn1e_contents_length (const SEC_ASN1Template *theTemplate, void *src,
- PRBool disallowStreaming, PRBool insideIndefinite,
- sec_asn1e_hdr_encoding *pHdrException)
+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;
@@ -484,14 +471,14 @@ sec_asn1e_contents_length (const SEC_ASN1Template *theTemplate, void *src,
/*
* This function currently calculates the length in all cases
- * except the following: when writing out the contents of a
+ * 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
+ * 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
+ * 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
@@ -500,7 +487,8 @@ sec_asn1e_contents_length (const SEC_ASN1Template *theTemplate, void *src,
encode_kind = theTemplate->kind;
universal = ((encode_kind & SEC_ASN1_CLASS_MASK) == SEC_ASN1_UNIVERSAL)
- ? PR_TRUE : PR_FALSE;
+ ? PR_TRUE
+ : PR_FALSE;
isExplicit = (encode_kind & SEC_ASN1_EXPLICIT) ? PR_TRUE : PR_FALSE;
encode_kind &= ~SEC_ASN1_EXPLICIT;
@@ -508,7 +496,7 @@ sec_asn1e_contents_length (const SEC_ASN1Template *theTemplate, void *src,
optional = (encode_kind & SEC_ASN1_OPTIONAL) ? PR_TRUE : PR_FALSE;
encode_kind &= ~SEC_ASN1_OPTIONAL;
- PORT_Assert (!(isExplicit && universal)); /* bad templates */
+ PORT_Assert(!(isExplicit && universal)); /* bad templates */
may_stream = (encode_kind & SEC_ASN1_MAY_STREAM) ? PR_TRUE : PR_FALSE;
encode_kind &= ~SEC_ASN1_MAY_STREAM;
@@ -517,342 +505,331 @@ sec_asn1e_contents_length (const SEC_ASN1Template *theTemplate, void *src,
encode_kind &= ~SEC_ASN1_DYNAMIC;
if (encode_kind & SEC_ASN1_NO_STREAM) {
- disallowStreaming = PR_TRUE;
+ 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);
+ 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
+ /* 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;
+ }
+ }
+ }
+
+ 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;
+ /* 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)
+#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);
+ 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);
+ 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 */
+ 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;
- }
+ /* 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 */
+ } /* end else */
if (len == 0 && optional)
- *pHdrException = hdr_optional;
+ *pHdrException = hdr_optional;
else if (underlying_kind == SEC_ASN1_ANY)
- *pHdrException = hdr_any;
- else
- *pHdrException = hdr_normal;
+ *pHdrException = hdr_any;
+ else
+ *pHdrException = hdr_normal;
return len;
}
-
static void
-sec_asn1e_write_header (sec_asn1e_state *state)
+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);
+ 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;
+ 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;
+ 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);
+ (void)sec_asn1e_init_state_based_on_template(state);
+ }
+ return;
}
- /* The !isString test below is apparently intended to ensure that all
+ /* 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));
+ 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
+ * 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
+ * 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);
+ 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 (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;
+ /*
+ * 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);
+ 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;
+ /*
+ * If no real contents to encode, then we are done with this field.
+ */
+ state->place = afterContents;
+ return;
}
/*
@@ -860,77 +837,78 @@ sec_asn1e_write_header (sec_asn1e_state *state)
* 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;
+ 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) {
+ (void)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;
+ 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) {
+ (void)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);
+ (void)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)
+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);
+ 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
@@ -938,8 +916,8 @@ sec_asn1e_write_contents_from_buf (sec_asn1e_state *state,
* then we have nothing to do but return and wait.
*/
if (buf == NULL || len == 0) {
- state->top->status = needBytes;
- return;
+ state->top->status = needBytes;
+ return;
}
/*
* We are streaming, reading from a passed-in buffer.
@@ -949,154 +927,148 @@ sec_asn1e_write_contents_from_buf (sec_asn1e_state *state,
* out as is (our caller is required to ensure that it
* is a properly encoded entity).
*/
- PORT_Assert (state->is_string); /* includes ANY */
+ 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);
- }
+ 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);
+ sec_asn1e_write_contents_bytes(state, buf, len);
state->top->status = needBytes;
}
static void
-sec_asn1e_write_contents (sec_asn1e_state *state)
+sec_asn1e_write_contents(sec_asn1e_state *state)
{
unsigned long len = 0;
- PORT_Assert (state->place == duringContents);
+ 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;
+ 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;
}
@@ -1105,14 +1077,14 @@ process_string:
* 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_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);
+ PORT_Assert(state->place == duringGroup);
+ PORT_Assert(state->child != NULL);
child = state->child;
@@ -1123,60 +1095,59 @@ sec_asn1e_next_in_group (sec_asn1e_state *state)
*/
member = (char *)(state->child->src) - child->theTemplate->offset;
while (*group != member)
- group++;
+ 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;
+ /*
+ * 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);
+ 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_next_in_sequence(sec_asn1e_state *state)
{
sec_asn1e_state *child;
- PORT_Assert (state->place == duringSequence);
- PORT_Assert (state->child != NULL);
+ 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);
+ 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;
+ /*
+ * We are done with this sequence.
+ */
+ child->place = notInUse;
+ state->place = afterContents;
+ return;
}
/*
@@ -1188,20 +1159,19 @@ sec_asn1e_next_in_sequence (sec_asn1e_state *state)
/*
* Do the "before" field notification.
*/
- sec_asn1e_notify_before (state->top, child->src, child->depth);
+ sec_asn1e_notify_before(state->top, child->src, child->depth);
state->top->current = child;
- (void) sec_asn1e_init_state_based_on_template (child);
+ (void)sec_asn1e_init_state_based_on_template(child);
}
-
static void
-sec_asn1e_after_contents (sec_asn1e_state *state)
+sec_asn1e_after_contents(sec_asn1e_state *state)
{
- PORT_Assert (state->place == afterContents);
+ PORT_Assert(state->place == afterContents);
if (state->indefinite)
- sec_asn1e_write_end_of_contents_bytes (state);
+ sec_asn1e_write_end_of_contents_bytes(state);
/*
* Just make my parent be the current state. It will then clean
@@ -1210,7 +1180,6 @@ sec_asn1e_after_contents (sec_asn1e_state *state)
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
@@ -1223,102 +1192,100 @@ sec_asn1e_after_contents (sec_asn1e_state *state)
* (for now) with the buffer.
*/
SECStatus
-SEC_ASN1EncoderUpdate (SEC_ASN1EncoderContext *cx,
- const char *buf, unsigned long len)
+SEC_ASN1EncoderUpdate(SEC_ASN1EncoderContext *cx,
+ const char *buf, unsigned long len)
{
sec_asn1e_state *state;
if (cx->status == needBytes) {
- cx->status = keepGoing;
+ 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;
- }
+ 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 SECFailure;
}
return SECSuccess;
}
-
void
-SEC_ASN1EncoderFinish (SEC_ASN1EncoderContext *cx)
+SEC_ASN1EncoderFinish(SEC_ASN1EncoderContext *cx)
{
/*
* XXX anything else that needs to be finished?
*/
- PORT_FreeArena (cx->our_pool, PR_FALSE);
+ 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)
+SEC_ASN1EncoderStart(const void *src, const SEC_ASN1Template *theTemplate,
+ SEC_ASN1WriteProc output_proc, void *output_arg)
{
PLArenaPool *our_pool;
SEC_ASN1EncoderContext *cx;
- our_pool = PORT_NewArena (SEC_ASN1_DEFAULT_ARENA_SIZE);
+ our_pool = PORT_NewArena(SEC_ASN1_DEFAULT_ARENA_SIZE);
if (our_pool == NULL)
- return NULL;
+ return NULL;
- cx = (SEC_ASN1EncoderContext*)PORT_ArenaZAlloc (our_pool, sizeof(*cx));
+ cx = (SEC_ASN1EncoderContext *)PORT_ArenaZAlloc(our_pool, sizeof(*cx));
if (cx == NULL) {
- PORT_FreeArena (our_pool, PR_FALSE);
- return NULL;
+ PORT_FreeArena(our_pool, PR_FALSE);
+ return NULL;
}
cx->our_pool = our_pool;
@@ -1327,39 +1294,36 @@ SEC_ASN1EncoderStart (const void *src, const SEC_ASN1Template *theTemplate,
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;
+ 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)
+SEC_ASN1EncoderSetNotifyProc(SEC_ASN1EncoderContext *cx,
+ SEC_ASN1NotifyProc fn, void *arg)
{
cx->notify_proc = fn;
cx->notify_arg = arg;
}
-
void
-SEC_ASN1EncoderClearNotifyProc (SEC_ASN1EncoderContext *cx)
+SEC_ASN1EncoderClearNotifyProc(SEC_ASN1EncoderContext *cx)
{
cx->notify_proc = NULL;
- cx->notify_arg = NULL; /* not necessary; just being clean */
+ cx->notify_arg = NULL; /* not necessary; just being clean */
}
void
@@ -1371,104 +1335,99 @@ SEC_ASN1EncoderAbort(SEC_ASN1EncoderContext *cx, int error)
}
void
-SEC_ASN1EncoderSetStreaming (SEC_ASN1EncoderContext *cx)
+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)
+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)
+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);
+ PORT_Assert(cx->streaming);
cx->from_buf = PR_TRUE;
}
-
void
-SEC_ASN1EncoderClearTakeFromBuf (SEC_ASN1EncoderContext *cx)
+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;
+ 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;
+ 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_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);
+ ecx = SEC_ASN1EncoderStart(src, theTemplate, output_proc, output_arg);
if (ecx == NULL)
- return SECFailure;
+ return SECFailure;
- rv = SEC_ASN1EncoderUpdate (ecx, NULL, 0);
+ rv = SEC_ASN1EncoderUpdate(ecx, NULL, 0);
- SEC_ASN1EncoderFinish (ecx);
+ 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)
+ * (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)
+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 = (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)
+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);
+ dest = (SECItem *)arg;
+ PORT_Assert(dest != NULL);
- PORT_Memcpy (dest->data + dest->len, buf, len);
- dest->len += len;
+ if (len > 0) {
+ 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,
@@ -1477,83 +1436,81 @@ sec_asn1e_encode_item_store (void *arg, const char *buf, unsigned long len,
* XXX This seems like a reasonable general-purpose function (for SECITEM_)?
*/
static SECItem *
-sec_asn1e_allocate_item (PLArenaPool *poolp, SECItem *dest, unsigned long len)
+sec_asn1e_allocate_item(PLArenaPool *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);
- }
+ 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;
- }
- }
+ 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 (PLArenaPool *poolp, SECItem *dest, const void *src,
- const SEC_ASN1Template *theTemplate)
+SEC_ASN1EncodeItem(PLArenaPool *poolp, SECItem *dest, const void *src,
+ const SEC_ASN1Template *theTemplate)
{
unsigned long encoding_length;
SECStatus rv;
- PORT_Assert (dest == NULL || dest->data == NULL);
+ PORT_Assert(dest == NULL || dest->data == NULL);
encoding_length = 0;
- rv = SEC_ASN1Encode (src, theTemplate,
- sec_asn1e_encode_item_count, &encoding_length);
+ rv = SEC_ASN1Encode(src, theTemplate,
+ sec_asn1e_encode_item_count, &encoding_length);
if (rv != SECSuccess)
- return NULL;
+ return NULL;
- dest = sec_asn1e_allocate_item (poolp, dest, encoding_length);
+ dest = sec_asn1e_allocate_item(poolp, dest, encoding_length);
if (dest == NULL)
- return NULL;
+ return NULL;
/* XXX necessary? This really just checks for a bug in the allocate fn */
- PORT_Assert (dest->data != NULL);
+ PORT_Assert(dest->data != NULL);
if (dest->data == NULL)
- return NULL;
+ return NULL;
dest->len = 0;
- (void) SEC_ASN1Encode (src, theTemplate, sec_asn1e_encode_item_store, dest);
+ (void)SEC_ASN1Encode(src, theTemplate, sec_asn1e_encode_item_store, dest);
- PORT_Assert (encoding_length == dest->len);
+ PORT_Assert(encoding_length == dest->len);
return dest;
}
-
static SECItem *
sec_asn1e_integer(PLArenaPool *poolp, SECItem *dest, unsigned long value,
- PRBool is_unsigned)
+ PRBool is_unsigned)
{
unsigned long copy;
unsigned char sign;
@@ -1564,9 +1521,9 @@ sec_asn1e_integer(PLArenaPool *poolp, SECItem *dest, unsigned long value,
*/
copy = value;
do {
- len++;
- sign = (unsigned char)(copy & 0x80);
- copy >>= 8;
+ len++;
+ sign = (unsigned char)(copy & 0x80);
+ copy >>= 8;
} while (copy);
/*
@@ -1575,39 +1532,37 @@ sec_asn1e_integer(PLArenaPool *poolp, SECItem *dest, unsigned long value,
* we put a high-order zero byte in the encoding.
*/
if (sign && (is_unsigned || (long)value >= 0))
- len++;
+ len++;
/*
* Allocate the item (if necessary) and the data pointer within.
*/
- dest = sec_asn1e_allocate_item (poolp, dest, len);
+ dest = sec_asn1e_allocate_item(poolp, dest, len);
if (dest == NULL)
- return 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;
+ dest->data[--len] = (unsigned char)value;
+ value >>= 8;
}
- PORT_Assert (value == 0);
+ PORT_Assert(value == 0);
return dest;
}
-
SECItem *
SEC_ASN1EncodeInteger(PLArenaPool *poolp, SECItem *dest, long value)
{
- return sec_asn1e_integer (poolp, dest, (unsigned long) value, PR_FALSE);
+ return sec_asn1e_integer(poolp, dest, (unsigned long)value, PR_FALSE);
}
-
SECItem *
SEC_ASN1EncodeUnsignedInteger(PLArenaPool *poolp,
- SECItem *dest, unsigned long value)
+ SECItem *dest, unsigned long value)
{
- return sec_asn1e_integer (poolp, dest, value, PR_TRUE);
+ return sec_asn1e_integer(poolp, dest, value, PR_TRUE);
}
diff --git a/nss/lib/util/secasn1t.h b/nss/lib/util/secasn1t.h
index 738eef8..0d1a6ae 100644
--- a/nss/lib/util/secasn1t.h
+++ b/nss/lib/util/secasn1t.h
@@ -55,15 +55,14 @@ typedef struct sec_ASN1Template_struct {
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)
+#define SEC_ASN1_DEFAULT_ARENA_SIZE (2048)
/*
** BER/DER values for ASN.1 identifier octets.
*/
-#define SEC_ASN1_TAG_MASK 0xff
+#define SEC_ASN1_TAG_MASK 0xff
/*
* BER/DER universal type tag numbers.
@@ -74,54 +73,54 @@ typedef struct sec_ASN1Template_struct {
* 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
+#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
+#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
+#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
+#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_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
+#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.
@@ -129,46 +128,44 @@ typedef struct sec_ASN1Template_struct {
** 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 */
-
-
+#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)
+#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
@@ -178,28 +175,30 @@ typedef struct sec_ASN1Template_struct {
** "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;
+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_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;
+ 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)
+#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);
+ 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; }
+#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.
@@ -227,9 +226,9 @@ typedef enum {
/*
* 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);
+ */
+typedef void (*SEC_ASN1NotifyProc)(void *arg, PRBool before,
+ void *dest, int real_depth);
/*
* Type of the function pointer used for grabbing encoded bytes.
@@ -260,9 +259,9 @@ typedef void (* SEC_ASN1NotifyProc)(void *arg, PRBool before,
* 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);
+ */
+typedef void (*SEC_ASN1WriteProc)(void *arg,
+ const char *data, unsigned long len,
+ int depth, SEC_ASN1EncodingPart data_kind);
#endif /* _SECASN1T_H_ */
diff --git a/nss/lib/util/secasn1u.c b/nss/lib/util/secasn1u.c
index a8e106b..7d086fb 100644
--- a/nss/lib/util/secasn1u.c
+++ b/nss/lib/util/secasn1u.c
@@ -8,7 +8,6 @@
#include "secasn1.h"
-
/*
* We have a length that needs to be encoded; how many bytes will the
* encoding take?
@@ -18,27 +17,25 @@
* in the length.
*/
int
-SEC_ASN1LengthLength (unsigned long len)
+SEC_ASN1LengthLength(unsigned long len)
{
int lenlen = 1;
if (len > 0x7f) {
- do {
- lenlen++;
- len >>= 8;
- } while (len);
+ 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
@@ -51,47 +48,47 @@ SEC_ASN1LengthLength (unsigned long len)
* (as opposed to in the process of decoding)
*/
const SEC_ASN1Template *
-SEC_ASN1GetSubtemplate (const SEC_ASN1Template *theTemplate, void *thing,
- PRBool encoding)
+SEC_ASN1GetSubtemplate(const SEC_ASN1Template *theTemplate, void *thing,
+ PRBool encoding)
{
const SEC_ASN1Template *subt = NULL;
- PORT_Assert (theTemplate->sub != NULL);
+ PORT_Assert(theTemplate->sub != NULL);
if (theTemplate->sub != NULL) {
- if (theTemplate->kind & SEC_ASN1_DYNAMIC) {
- SEC_ASN1TemplateChooserPtr chooserp;
+ 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;
- }
+ 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)
+PRBool
+SEC_ASN1IsTemplateSimple(const SEC_ASN1Template *theTemplate)
{
if (!theTemplate) {
- return PR_TRUE; /* it doesn't get any simpler than NULL */
+ 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_TAGNUM_MASK))) {
+ return PR_TRUE; /* primitive type */
}
if (!(theTemplate->kind & SEC_ASN1_CHOICE)) {
- return PR_FALSE; /* no choice means not simple */
+ return PR_FALSE; /* no choice means not simple */
}
while (++theTemplate && theTemplate->kind) {
- if (theTemplate->kind & (~SEC_ASN1_TAGNUM_MASK)) {
- return PR_FALSE; /* complex type */
- }
+ if (theTemplate->kind & (~SEC_ASN1_TAGNUM_MASK)) {
+ return PR_FALSE; /* complex type */
+ }
}
return PR_TRUE; /* choice of primitive types */
}
-
diff --git a/nss/lib/util/seccomon.h b/nss/lib/util/seccomon.h
index 4414974..edd5c53 100644
--- a/nss/lib/util/seccomon.h
+++ b/nss/lib/util/seccomon.h
@@ -16,13 +16,12 @@
#include "utilrename.h"
#include "prtypes.h"
-
-#ifdef __cplusplus
-# define SEC_BEGIN_PROTOS extern "C" {
-# define SEC_END_PROTOS }
+#ifdef __cplusplus
+#define SEC_BEGIN_PROTOS extern "C" {
+#define SEC_END_PROTOS }
#else
-# define SEC_BEGIN_PROTOS
-# define SEC_END_PROTOS
+#define SEC_BEGIN_PROTOS
+#define SEC_END_PROTOS
#endif
#include "secport.h"
@@ -66,10 +65,10 @@ struct SECItemArrayStr {
** 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();
+** SECStatus rv;
+** rv = some_function (some_argument);
+** if (rv != SECSuccess)
+** do_an_error_thing();
**
*/
typedef enum _SECStatus {
diff --git a/nss/lib/util/secder.h b/nss/lib/util/secder.h
index 0da1b34..dbc3580 100644
--- a/nss/lib/util/secder.h
+++ b/nss/lib/util/secder.h
@@ -9,7 +9,7 @@
/*
* secder.h - public data structures and prototypes for the DER encoding and
- * decoding utilities library
+ * decoding utilities library
*/
#include <time.h>
@@ -25,14 +25,14 @@ 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
+** "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);
+ void *src);
extern SECStatus DER_Lengths(SECItem *item, int *header_len_p,
PRUint32 *contents_len_p);
@@ -41,13 +41,13 @@ extern SECStatus DER_Lengths(SECItem *item, int *header_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
+** "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);
+ PRUint32 encodingLen);
/*
** Return the number of bytes it will take to hold a der encoded length.
@@ -82,23 +82,22 @@ 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).
+** "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,
+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
+** "result" the resulting NSPR time
+** "string" the der notation ascii value to decode
*/
extern SECStatus DER_AsciiToTime(PRTime *result, const char *string);
@@ -117,7 +116,7 @@ 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.
+** "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);
@@ -132,13 +131,13 @@ extern char *DER_TimeChoiceDayToAscii(SECItem *timechoice);
** before January 1, 10000.
*/
extern SECStatus DER_TimeToGeneralizedTime(SECItem *dst, PRTime gmttime);
-extern SECStatus DER_TimeToGeneralizedTimeArena(PLArenaPool* arenaOpt,
+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
+** "dst" the resulting NSPR time
+** "string" the der notation ascii value to decode
*/
extern SECStatus DER_GeneralizedTimeToTime(PRTime *dst, const SECItem *time);
@@ -146,29 +145,28 @@ 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);
+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);
+extern char *CERT_GenTime2FormattedAscii(PRTime genTime, char *format);
/*
-** decode a SECItem containing either a SEC_ASN1_GENERALIZED_TIME
+** 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);
+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);
+extern SECStatus DER_EncodeTimeChoice(PLArenaPool *arena, SECItem *output,
+ PRTime input);
SEC_END_PROTOS
#endif /* _SECDER_H_ */
-
diff --git a/nss/lib/util/secdert.h b/nss/lib/util/secdert.h
index 92936e6..de67eaf 100644
--- a/nss/lib/util/secdert.h
+++ b/nss/lib/util/secdert.h
@@ -6,7 +6,7 @@
#define _SECDERT_H_
/*
* secdert.h - public data structures for the DER encoding and
- * decoding utilities library
+ * decoding utilities library
*/
#include "utilrename.h"
@@ -43,13 +43,13 @@ struct DERTemplateStr {
/*
** 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 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.
+ ** 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;
};
@@ -62,7 +62,7 @@ struct DERTemplateStr {
/*
** BER/DER values for ASN.1 identifier octets.
*/
-#define DER_TAG_MASK 0xff
+#define DER_TAG_MASK 0xff
/*
* BER/DER universal type tag numbers.
@@ -70,60 +70,60 @@ struct DERTemplateStr {
* 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
+#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_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
+#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 */
+#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; \
-}
+#define DER_ConvertBitString(item) \
+ { \
+ (item)->len = ((item)->len + 7) >> 3; \
+ }
#endif /* _SECDERT_H_ */
diff --git a/nss/lib/util/secdig.c b/nss/lib/util/secdig.c
index 3226d4f..f4deec5 100644
--- a/nss/lib/util/secdig.c
+++ b/nss/lib/util/secdig.c
@@ -4,12 +4,12 @@
#include "secdig.h"
#include "secoid.h"
-#include "secasn1.h"
+#include "secasn1.h"
#include "secerr.h"
/*
* XXX Want to have a SGN_DecodeDigestInfo, like:
- * SGNDigestInfo *SGN_DecodeDigestInfo(SECItem *didata);
+ * 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
@@ -25,7 +25,7 @@
SECItem *
SGN_EncodeDigestInfo(PLArenaPool *poolp, SECItem *dest, SGNDigestInfo *diginfo)
{
- return SEC_ASN1EncodeItem (poolp, dest, diginfo, sgn_DigestInfoTemplate);
+ return SEC_ASN1EncodeItem(poolp, dest, diginfo, sgn_DigestInfoTemplate);
}
SGNDigestInfo *
@@ -39,28 +39,28 @@ SGN_CreateDigestInfo(SECOidTag algorithm, const unsigned char *sig,
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;
+ 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;
+ return NULL;
}
- di = (SGNDigestInfo *) PORT_ArenaZAlloc(arena, sizeof(SGNDigestInfo));
+ di = (SGNDigestInfo *)PORT_ArenaZAlloc(arena, sizeof(SGNDigestInfo));
if (di == NULL) {
- PORT_FreeArena(arena, PR_FALSE);
- return NULL;
+ PORT_FreeArena(arena, PR_FALSE);
+ return NULL;
}
di->arena = arena;
@@ -73,28 +73,28 @@ SGN_CreateDigestInfo(SECOidTag algorithm, const unsigned char *sig,
dummy_value.len = 0;
null_param = SEC_ASN1EncodeItem(NULL, NULL, &dummy_value, SEC_NullTemplate);
if (null_param == NULL) {
- goto loser;
+ goto loser;
}
rv = SECOID_SetAlgorithmID(arena, &di->digestAlgorithm, algorithm,
- null_param);
+ null_param);
SECITEM_FreeItem(null_param, PR_TRUE);
if (rv != SECSuccess) {
- goto loser;
+ goto loser;
}
- di->digest.data = (unsigned char *) PORT_ArenaAlloc(arena, len);
+ di->digest.data = (unsigned char *)PORT_ArenaAlloc(arena, len);
if (di->digest.data == NULL) {
- goto loser;
+ goto loser;
}
di->digest.len = len;
PORT_Memcpy(di->digest.data, sig, len);
return di;
- loser:
+loser:
SGN_DestroyDigestInfo(di);
return NULL;
}
@@ -105,27 +105,27 @@ SGN_DecodeDigestInfo(SECItem *didata)
PLArenaPool *arena;
SGNDigestInfo *di;
SECStatus rv = SECFailure;
- SECItem diCopy = {siBuffer, NULL, 0};
+ SECItem diCopy = { siBuffer, NULL, 0 };
arena = PORT_NewArena(SEC_ASN1_DEFAULT_ARENA_SIZE);
- if(arena == NULL)
- return NULL;
+ if (arena == NULL)
+ return NULL;
rv = SECITEM_CopyItem(arena, &diCopy, didata);
if (rv != SECSuccess) {
- PORT_FreeArena(arena, PR_FALSE);
- return NULL;
+ 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);
+ di->arena = arena;
+ rv = SEC_QuickDERDecodeItem(arena, di, sgn_DigestInfoTemplate, &diCopy);
}
-
+
if ((di == NULL) || (rv != SECSuccess)) {
- PORT_FreeArena(arena, PR_FALSE);
- di = NULL;
+ PORT_FreeArena(arena, PR_FALSE);
+ di = NULL;
}
return di;
@@ -135,32 +135,32 @@ void
SGN_DestroyDigestInfo(SGNDigestInfo *di)
{
if (di && di->arena) {
- PORT_FreeArena(di->arena, PR_FALSE);
+ PORT_FreeArena(di->arena, PR_FALSE);
}
return;
}
-SECStatus
+SECStatus
SGN_CopyDigestInfo(PLArenaPool *poolp, SGNDigestInfo *a, SGNDigestInfo *b)
{
SECStatus rv;
void *mark;
- if((poolp == NULL) || (a == NULL) || (b == NULL))
- return SECFailure;
+ if ((poolp == NULL) || (a == NULL) || (b == NULL))
+ return SECFailure;
mark = PORT_ArenaMark(poolp);
a->arena = poolp;
- rv = SECOID_CopyAlgorithmID(poolp, &a->digestAlgorithm,
- &b->digestAlgorithm);
+ rv = SECOID_CopyAlgorithmID(poolp, &a->digestAlgorithm,
+ &b->digestAlgorithm);
if (rv == SECSuccess)
- rv = SECITEM_CopyItem(poolp, &a->digest, &b->digest);
+ rv = SECITEM_CopyItem(poolp, &a->digest, &b->digest);
if (rv != SECSuccess) {
- PORT_ArenaRelease(poolp, mark);
+ PORT_ArenaRelease(poolp, mark);
} else {
- PORT_ArenaUnmark(poolp, mark);
+ PORT_ArenaUnmark(poolp, mark);
}
return rv;
@@ -173,7 +173,8 @@ SGN_CompareDigestInfo(SGNDigestInfo *a, SGNDigestInfo *b)
/* Check signature algorithm's */
rv = SECOID_CompareAlgorithmID(&a->digestAlgorithm, &b->digestAlgorithm);
- if (rv) return rv;
+ if (rv)
+ return rv;
/* Compare signature block length's */
rv = SECITEM_CompareItem(&a->digest, &b->digest);
diff --git a/nss/lib/util/secdig.h b/nss/lib/util/secdig.h
index 6f218ec..1531bf1 100644
--- a/nss/lib/util/secdig.h
+++ b/nss/lib/util/secdig.h
@@ -12,12 +12,11 @@
#include "secdigt.h"
#include "seccomon.h"
-#include "secasn1t.h"
+#include "secasn1t.h"
#include "secdert.h"
SEC_BEGIN_PROTOS
-
extern const SEC_ASN1Template sgn_DigestInfoTemplate[];
SEC_ASN1_CHOOSER_DECLARE(sgn_DigestInfoTemplate)
@@ -29,9 +28,9 @@ SEC_ASN1_CHOOSER_DECLARE(sgn_DigestInfoTemplate)
/*
** 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
+** "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.
@@ -40,8 +39,8 @@ SEC_ASN1_CHOOSER_DECLARE(sgn_DigestInfoTemplate)
** I think that is all anybody ever wants to do anyway.
*/
extern SGNDigestInfo *SGN_CreateDigestInfo(SECOidTag algorithm,
- const unsigned char *sig,
- unsigned int sigLen);
+ const unsigned char *sig,
+ unsigned int sigLen);
/*
** Destroy a digest-info object
@@ -50,11 +49,11 @@ 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
+** "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).
**
@@ -62,11 +61,11 @@ extern void SGN_DestroyDigestInfo(SGNDigestInfo *info);
** I think that is all anybody ever wants to do anyway.
*/
extern SECItem *SGN_EncodeDigestInfo(PLArenaPool *poolp, SECItem *dest,
- SGNDigestInfo *diginfo);
+ SGNDigestInfo *diginfo);
/*
** Decode a DER encoded digest info objct.
-** didata is thr source of the encoded digest.
+** 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
@@ -74,7 +73,6 @@ extern SECItem *SGN_EncodeDigestInfo(PLArenaPool *poolp, SECItem *dest,
*/
extern SGNDigestInfo *SGN_DecodeDigestInfo(SECItem *didata);
-
/*
** Copy digest info.
** poolp is the arena to which the digest will be copied.
@@ -83,13 +81,13 @@ extern SGNDigestInfo *SGN_DecodeDigestInfo(SECItem *didata);
** 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.
+** 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);
+extern SECStatus SGN_CopyDigestInfo(PLArenaPool *poolp,
+ SGNDigestInfo *a,
+ SGNDigestInfo *b);
/*
** Compare two digest-info objects, returning the difference between
@@ -97,7 +95,6 @@ extern SECStatus SGN_CopyDigestInfo(PLArenaPool *poolp,
*/
extern SECComparison SGN_CompareDigestInfo(SGNDigestInfo *a, SGNDigestInfo *b);
-
SEC_END_PROTOS
#endif /* _SECDIG_H_ */
diff --git a/nss/lib/util/secdigt.h b/nss/lib/util/secdigt.h
index 2414d79..4553434 100644
--- a/nss/lib/util/secdigt.h
+++ b/nss/lib/util/secdigt.h
@@ -17,9 +17,9 @@
** A PKCS#1 digest-info object
*/
struct SGNDigestInfoStr {
- PLArenaPool * arena;
+ PLArenaPool* arena;
SECAlgorithmID digestAlgorithm;
- SECItem digest;
+ SECItem digest;
};
typedef struct SGNDigestInfoStr SGNDigestInfo;
diff --git a/nss/lib/util/secerr.h b/nss/lib/util/secerr.h
index adca22a..4fe1d8e 100644
--- a/nss/lib/util/secerr.h
+++ b/nss/lib/util/secerr.h
@@ -7,211 +7,211 @@
#include "utilrename.h"
-#define SEC_ERROR_BASE (-0x2000)
-#define SEC_ERROR_LIMIT (SEC_ERROR_BASE + 1000)
+#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
+ 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 */
diff --git a/nss/lib/util/secitem.c b/nss/lib/util/secitem.c
index 49364c7..22c5b1f 100644
--- a/nss/lib/util/secitem.c
+++ b/nss/lib/util/secitem.c
@@ -18,98 +18,98 @@ SECITEM_AllocItem(PLArenaPool *arena, SECItem *item, unsigned int len)
void *mark = NULL;
if (arena != NULL) {
- mark = PORT_ArenaMark(arena);
+ 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;
- }
+ 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;
+ 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;
- }
+ 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;
+ result->data = NULL;
}
if (mark) {
- PORT_ArenaUnmark(arena, mark);
+ PORT_ArenaUnmark(arena, mark);
}
- return(result);
+ return (result);
loser:
- if ( arena != NULL ) {
- if (mark) {
- PORT_ArenaRelease(arena, mark);
- }
- if (item != NULL) {
- item->data = NULL;
- item->len = 0;
- }
+ 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);
+ 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(PLArenaPool *arena, SECItem *item, unsigned int oldlen,
- unsigned int newlen)
+ unsigned int newlen)
{
PORT_Assert(item != NULL);
if (item == NULL) {
- /* XXX Set error. But to what? */
- return SECFailure;
+ /* 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);
- }
+ 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 (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 SECFailure;
}
return SECSuccess;
@@ -122,52 +122,52 @@ SECITEM_ReallocItemV2(PLArenaPool *arena, SECItem *item, unsigned int newlen)
PORT_Assert(item);
if (!item) {
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- return SECFailure;
+ PORT_SetError(SEC_ERROR_INVALID_ARGS);
+ return SECFailure;
}
-
+
if (item->len == newlen) {
- return SECSuccess;
+ return SECSuccess;
}
if (!newlen) {
- if (!arena) {
- PORT_Free(item->data);
- }
- item->data = NULL;
- item->len = 0;
- return SECSuccess;
- }
-
+ if (!arena) {
+ PORT_Free(item->data);
+ }
+ item->data = NULL;
+ item->len = 0;
+ return SECSuccess;
+ }
+
if (!item->data) {
- /* allocate fresh block of memory */
- PORT_Assert(!item->len);
- if (arena) {
- newdata = PORT_ArenaAlloc(arena, newlen);
- } else {
- newdata = PORT_Alloc(newlen);
- }
+ /* allocate fresh block of memory */
+ PORT_Assert(!item->len);
+ if (arena) {
+ newdata = PORT_ArenaAlloc(arena, newlen);
+ } else {
+ newdata = PORT_Alloc(newlen);
+ }
} else {
- /* reallocate or adjust existing block of memory */
- if (arena) {
- if (item->len > newlen) {
- /* There's no need to realloc a shorter block from the arena,
- * because it would result in using even more memory!
- * Therefore we'll continue to use the old block and
- * set the item to the shorter size.
- */
- item->len = newlen;
- return SECSuccess;
- }
- newdata = PORT_ArenaGrow(arena, item->data, item->len, newlen);
- } else {
- newdata = PORT_Realloc(item->data, newlen);
- }
+ /* reallocate or adjust existing block of memory */
+ if (arena) {
+ if (item->len > newlen) {
+ /* There's no need to realloc a shorter block from the arena,
+ * because it would result in using even more memory!
+ * Therefore we'll continue to use the old block and
+ * set the item to the shorter size.
+ */
+ item->len = newlen;
+ return SECSuccess;
+ }
+ newdata = PORT_ArenaGrow(arena, item->data, item->len, newlen);
+ } else {
+ newdata = PORT_Realloc(item->data, newlen);
+ }
}
if (!newdata) {
- PORT_SetError(SEC_ERROR_NO_MEMORY);
- return SECFailure;
+ PORT_SetError(SEC_ERROR_NO_MEMORY);
+ return SECFailure;
}
item->len = newlen;
@@ -182,23 +182,23 @@ SECITEM_CompareItem(const SECItem *a, const SECItem *b)
int rv;
if (a == b)
- return SECEqual;
- if (!a || !a->len || !a->data)
+ return SECEqual;
+ if (!a || !a->len || !a->data)
return (!b || !b->len || !b->data) ? SECEqual : SECLessThan;
- if (!b || !b->len || !b->data)
- return SECGreaterThan;
+ if (!b || !b->len || !b->data)
+ return SECGreaterThan;
+
+ m = ((a->len < b->len) ? a->len : b->len);
- m = ( ( a->len < b->len ) ? a->len : b->len );
-
rv = PORT_Memcmp(a->data, b->data, m);
if (rv) {
- return rv < 0 ? SECLessThan : SECGreaterThan;
+ return rv < 0 ? SECLessThan : SECGreaterThan;
}
if (a->len < b->len) {
- return SECLessThan;
+ return SECLessThan;
}
if (a->len == b->len) {
- return SECEqual;
+ return SECEqual;
}
return SECGreaterThan;
}
@@ -209,10 +209,10 @@ SECITEM_ItemsAreEqual(const SECItem *a, const SECItem *b)
if (a->len != b->len)
return PR_FALSE;
if (!a->len)
- return PR_TRUE;
+ return PR_TRUE;
if (!a->data || !b->data) {
/* avoid null pointer crash. */
- return (PRBool)(a->data == b->data);
+ return (PRBool)(a->data == b->data);
}
return (PRBool)!PORT_Memcmp(a->data, b->data, a->len);
}
@@ -227,37 +227,37 @@ SECItem *
SECITEM_ArenaDupItem(PLArenaPool *arena, const SECItem *from)
{
SECItem *to;
-
- if ( from == NULL ) {
- return(NULL);
+
+ if (from == NULL) {
+ return (NULL);
}
-
- if ( arena != NULL ) {
- to = (SECItem *)PORT_ArenaAlloc(arena, sizeof(SECItem));
+
+ if (arena != NULL) {
+ to = (SECItem *)PORT_ArenaAlloc(arena, sizeof(SECItem));
} else {
- to = (SECItem *)PORT_Alloc(sizeof(SECItem));
+ to = (SECItem *)PORT_Alloc(sizeof(SECItem));
}
- if ( to == NULL ) {
- return(NULL);
+ if (to == NULL) {
+ return (NULL);
}
- if ( arena != NULL ) {
- to->data = (unsigned char *)PORT_ArenaAlloc(arena, from->len);
+ if (arena != NULL) {
+ to->data = (unsigned char *)PORT_ArenaAlloc(arena, from->len);
} else {
- to->data = (unsigned char *)PORT_Alloc(from->len);
+ to->data = (unsigned char *)PORT_Alloc(from->len);
}
- if ( to->data == NULL ) {
- PORT_Free(to);
- return(NULL);
+ 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);
+ if (to->len) {
+ PORT_Memcpy(to->data, from->data, to->len);
}
-
- return(to);
+
+ return (to);
}
SECStatus
@@ -265,24 +265,24 @@ SECITEM_CopyItem(PLArenaPool *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;
+ 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;
+ /*
+ * 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;
}
@@ -291,12 +291,12 @@ void
SECITEM_FreeItem(SECItem *zap, PRBool freeit)
{
if (zap) {
- PORT_Free(zap->data);
- zap->data = 0;
- zap->len = 0;
- if (freeit) {
- PORT_Free(zap);
- }
+ PORT_Free(zap->data);
+ zap->data = 0;
+ zap->len = 0;
+ if (freeit) {
+ PORT_Free(zap);
+ }
}
}
@@ -304,12 +304,12 @@ 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));
- }
+ 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
@@ -321,7 +321,7 @@ SECITEM_ZfreeItem(SECItem *zap, PRBool freeit)
* inclined student.
*/
PLHashNumber PR_CALLBACK
-SECITEM_Hash ( const void *key)
+SECITEM_Hash(const void *key)
{
const SECItem *item = (const SECItem *)key;
PLHashNumber rv = 0;
@@ -330,8 +330,8 @@ SECITEM_Hash ( const void *key)
PRUint32 i;
PRUint8 *rvc = (PRUint8 *)&rv;
- for( i = 0; i < item->len; i++ ) {
- rvc[ i % sizeof(rv) ] ^= *data;
+ for (i = 0; i < item->len; i++) {
+ rvc[i % sizeof(rv)] ^= *data;
data++;
}
@@ -345,12 +345,12 @@ SECITEM_Hash ( const void *key)
* but heck it's only used internally by the hash table anyway.
*/
PRIntn PR_CALLBACK
-SECITEM_HashCompare ( const void *k1, const void *k2)
+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);
+ return SECITEM_ItemsAreEqual(i1, i2);
}
SECItemArray *
@@ -402,7 +402,7 @@ SECITEM_AllocArray(PLArenaPool *arena, SECItemArray *array, unsigned int len)
return result;
loser:
- if ( arena != NULL ) {
+ if (arena != NULL) {
if (mark) {
PORT_ArenaRelease(arena, mark);
}
@@ -445,12 +445,14 @@ secitem_FreeArray(SECItemArray *array, PRBool zero_items, PRBool freeit)
PORT_Free(array);
}
-void SECITEM_FreeArray(SECItemArray *array, PRBool freeit)
+void
+SECITEM_FreeArray(SECItemArray *array, PRBool freeit)
{
secitem_FreeArray(array, PR_FALSE, freeit);
}
-void SECITEM_ZfreeArray(SECItemArray *array, PRBool freeit)
+void
+SECITEM_ZfreeArray(SECItemArray *array, PRBool freeit)
{
secitem_FreeArray(array, PR_TRUE, freeit);
}
diff --git a/nss/lib/util/secitem.h b/nss/lib/util/secitem.h
index 290f2e5..5b9d0e1 100644
--- a/nss/lib/util/secitem.h
+++ b/nss/lib/util/secitem.h
@@ -9,7 +9,7 @@
/*
* secitem.h - public data structures and prototypes for handling
- * SECItems
+ * SECItems
*/
#include "plarena.h"
@@ -33,12 +33,12 @@ SEC_BEGIN_PROTOS
** unused and our improved APIs (aka Stan) are looming, I left it out.
*/
extern SECItem *SECITEM_AllocItem(PLArenaPool *arena, SECItem *item,
- unsigned int len);
+ unsigned int len);
/*
** This is a legacy function containing bugs. It doesn't update item->len,
** and it has other issues as described in bug 298649 and bug 298938.
-** However, the function is kept unchanged for consumers that might depend
+** However, the function is kept unchanged for consumers that might depend
** on the broken behaviour. New code should call SECITEM_ReallocItemV2.
**
** Reallocate the data for the specified "item". If "arena" is not NULL,
@@ -48,9 +48,9 @@ extern SECItem *SECITEM_AllocItem(PLArenaPool *arena, SECItem *item,
** SECFailure is returned if it is not. If the allocation succeeds,
** SECSuccess is returned.
*/
-extern SECStatus SECITEM_ReallocItem( /* deprecated function */
- PLArenaPool *arena, SECItem *item,
- unsigned int oldlen, unsigned int newlen);
+extern SECStatus SECITEM_ReallocItem(/* deprecated function */
+ PLArenaPool *arena, SECItem *item,
+ unsigned int oldlen, unsigned int newlen);
/*
** Reallocate the data for the specified "item". If "arena" is not NULL,
@@ -61,7 +61,7 @@ extern SECStatus SECITEM_ReallocItem( /* deprecated function */
** If the allocation succeeds, the item is updated and SECSuccess is returned.
*/
extern SECStatus SECITEM_ReallocItemV2(PLArenaPool *arena, SECItem *item,
- unsigned int newlen);
+ unsigned int newlen);
/*
** Compare two items returning the difference between them.
@@ -76,7 +76,7 @@ extern PRBool SECITEM_ItemsAreEqual(const SECItem *a, const SECItem *b);
/*
** Copy "from" to "to"
*/
-extern SECStatus SECITEM_CopyItem(PLArenaPool *arena, SECItem *to,
+extern SECStatus SECITEM_CopyItem(PLArenaPool *arena, SECItem *to,
const SECItem *from);
/*
@@ -85,7 +85,7 @@ extern SECStatus SECITEM_CopyItem(PLArenaPool *arena, SECItem *to,
extern SECItem *SECITEM_DupItem(const SECItem *from);
/*
-** Allocate an item and copy "from" into it. The item itself and the
+** 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.
*/
@@ -101,9 +101,9 @@ extern void SECITEM_FreeItem(SECItem *zap, PRBool freeit);
*/
extern void SECITEM_ZfreeItem(SECItem *zap, PRBool freeit);
-PLHashNumber PR_CALLBACK SECITEM_Hash ( const void *key);
+PLHashNumber PR_CALLBACK SECITEM_Hash(const void *key);
-PRIntn PR_CALLBACK SECITEM_HashCompare ( const void *k1, const void *k2);
+PRIntn PR_CALLBACK SECITEM_HashCompare(const void *k1, const void *k2);
extern SECItemArray *SECITEM_AllocArray(PLArenaPool *arena,
SECItemArray *array,
diff --git a/nss/lib/util/secload.c b/nss/lib/util/secload.c
index eb8a9ec..12efd2f 100644
--- a/nss/lib/util/secload.c
+++ b/nss/lib/util/secload.c
@@ -16,7 +16,8 @@
* The caller should call PR_Free to free the string returned by this
* function.
*/
-static char* loader_GetOriginalPathname(const char* link)
+static char*
+loader_GetOriginalPathname(const char* link)
{
char* resolved = NULL;
char* input = NULL;
@@ -39,8 +40,8 @@ static char* loader_GetOriginalPathname(const char* link)
return NULL;
}
strcpy(input, link);
- while ( (iterations++ < BL_MAXSYMLINKS) &&
- ( (retlen = readlink(input, resolved, len - 1)) > 0) ) {
+ while ((iterations++ < BL_MAXSYMLINKS) &&
+ ((retlen = readlink(input, resolved, len - 1)) > 0)) {
char* tmp = input;
resolved[retlen] = '\0'; /* NULL termination */
input = resolved;
@@ -59,11 +60,11 @@ static char* loader_GetOriginalPathname(const char* link)
* 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)
+static PRLibrary*
+loader_LoadLibInReferenceDir(const char* referencePath, const char* name)
{
- PRLibrary *dlh = NULL;
- char *fullName = NULL;
+ PRLibrary* dlh = NULL;
+ char* fullName = NULL;
char* c;
PRLibSpec libSpec;
@@ -71,21 +72,21 @@ loader_LoadLibInReferenceDir(const char *referencePath, const char *name)
c = strrchr(referencePath, PR_GetDirectorySeparator());
if (c) {
size_t referencePathSize = 1 + c - referencePath;
- fullName = (char*) PORT_Alloc(strlen(name) + referencePathSize + 1);
+ fullName = (char*)PORT_Alloc(strlen(name) + referencePathSize + 1);
if (fullName) {
memcpy(fullName, referencePath, referencePathSize);
- strcpy(fullName + referencePathSize, name);
+ strcpy(fullName + referencePathSize, name);
#ifdef DEBUG_LOADER
- PR_fprintf(PR_STDOUT, "\nAttempting to load fully-qualified %s\n",
+ 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
+ /* 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);
@@ -101,7 +102,7 @@ loader_LoadLibInReferenceDir(const char *referencePath, const char *name)
* staticShLibFunc, is required.
*
* existingShLibName:
- * The file name of the shared library that shall be used as the
+ * 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.
*
@@ -111,7 +112,7 @@ loader_LoadLibInReferenceDir(const char *referencePath, const char *name)
* newShLibName:
* The simple file name of the new shared library to be loaded.
*
- * We use PR_GetLibraryFilePathname to get the pathname of the 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.
@@ -126,12 +127,12 @@ loader_LoadLibInReferenceDir(const char *referencePath, const char *name)
*
*/
-PRLibrary *
+PRLibrary*
PORT_LoadLibraryFromOrigin(const char* existingShLibName,
- PRFuncPtr staticShLibFunc,
- const char *newShLibName)
+ PRFuncPtr staticShLibFunc,
+ const char* newShLibName)
{
- PRLibrary *lib = NULL;
+ PRLibrary* lib = NULL;
char* fullPath = NULL;
PRLibSpec libSpec;
@@ -179,4 +180,3 @@ PORT_LoadLibraryFromOrigin(const char* existingShLibName,
}
return lib;
}
-
diff --git a/nss/lib/util/secoid.c b/nss/lib/util/secoid.c
index 0020992..da03b7c 100644
--- a/nss/lib/util/secoid.c
+++ b/nss/lib/util/secoid.c
@@ -26,19 +26,19 @@ const char __nss_util_version[] = "Version: NSS " NSSUTIL_VERSION _DEBUG_STRING;
/* 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
+#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
@@ -47,455 +47,463 @@ const char __nss_util_version[] = "Version: NSS " NSSUTIL_VERSION _DEBUG_STRING;
/* 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
+#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_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_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
+#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
+#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
+#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
+/** X.509 v3 Extension OID
** {joint-iso-ccitt (2) ds(5) 29}
**/
-#define ID_CE_OID X500, 0x1d
+#define ID_CE_OID X500, 0x1d
-#define RFC1274_ATTR_TYPE 0x09, 0x92, 0x26, 0x89, 0x93, 0xf2, 0x2c, 0x64, 0x1
+#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
+#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
+#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 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 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_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
+#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
+#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
+#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 MS_CRYPTO_EKU MS_CRYPTO_20, 3
-#define CERTICOM_OID 0x2b, 0x81, 0x04
-#define SECG_OID CERTICOM_OID, 0x00
+#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_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
+#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
+#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 IDEA: 1.3.6.1.4.1.188.7.1.1
+ */
+#define ASCOM_OID 0x2b, 0x6, 0x1, 0x4, 0x1, 0xbc
+#define ASCOM_IDEA_ALG ASCOM_OID, 0x7, 0x1, 0x1
/* for SEED : iso(1) member-body(2) korea(410)
* kisa(200004) algorithm(1)
*/
-#define SEED_OID 0x2a,0x83,0x1a,0x8c,0x9a,0x44,0x01
+#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 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 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 };
+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 };
+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 x520Name[] = { X520_ATTRIBUTE_TYPE, 41 };
-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 };
+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 x520Name[] = { X520_ATTRIBUTE_TYPE, 41 };
+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 };
+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 };
+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 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 };
+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 };
+CONST_OID nsKeyUsageGovtApproved[] = { NETSCAPE_POLICY, 0x01 };
/* Netscape other name types */
-CONST_OID netscapeNickname[] = { NETSCAPE_NAME_COMPONENTS, 0x01 };
-CONST_OID netscapeAOLScreenname[] = { NETSCAPE_NAME_COMPONENTS, 0x02 };
+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 };
-
+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};
+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 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 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 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 };
+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 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 };
+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 };
+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 };
+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 };
+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 };
+CONST_OID skipjackCBC[] = { MISSI, 0x04 };
+CONST_OID dhPublicKey[] = { ANSI_X942_ALGORITHM, 0x1 };
+
+CONST_OID idea_CBC[] = { ASCOM_IDEA_ALG, 2 };
+CONST_OID aes128_GCM[] = { AES, 0x6 };
+CONST_OID aes192_GCM[] = { AES, 0x1a };
+CONST_OID aes256_GCM[] = { AES, 0x2e };
+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 };
+CONST_OID aes128_OFB[] = { AES, 3 };
+CONST_OID aes128_CFB[] = { AES, 4 };
#endif
-CONST_OID aes128_KEY_WRAP[] = { AES, 5 };
+CONST_OID aes128_KEY_WRAP[] = { AES, 5 };
-CONST_OID aes192_ECB[] = { AES, 21 };
-CONST_OID aes192_CBC[] = { AES, 22 };
+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 };
+CONST_OID aes192_OFB[] = { AES, 23 };
+CONST_OID aes192_CFB[] = { AES, 24 };
#endif
-CONST_OID aes192_KEY_WRAP[] = { AES, 25 };
+CONST_OID aes192_KEY_WRAP[] = { AES, 25 };
-CONST_OID aes256_ECB[] = { AES, 41 };
-CONST_OID aes256_CBC[] = { AES, 42 };
+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 };
+CONST_OID aes256_OFB[] = { AES, 43 };
+CONST_OID aes256_CFB[] = { AES, 44 };
#endif
-CONST_OID aes256_KEY_WRAP[] = { AES, 45 };
+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_CBC[] = { CAMELLIA_ENCRYPT_OID, 2 };
+CONST_OID camellia192_CBC[] = { CAMELLIA_ENCRYPT_OID, 3 };
+CONST_OID camellia256_CBC[] = { CAMELLIA_ENCRYPT_OID, 4 };
-CONST_OID sha256[] = { SHAXXX, 1 };
-CONST_OID sha384[] = { SHAXXX, 2 };
-CONST_OID sha512[] = { SHAXXX, 3 };
-CONST_OID sha224[] = { SHAXXX, 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 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 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 };
@@ -505,86 +513,110 @@ CONST_OID ansix962SignaturewithSHA512Digest[] = { ANSI_X962_SPECIFY_OID, 0x04 };
/* 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 ansiX962prime192v1[] = { ANSI_X962_GFp_OID, 0x01 }; /* unsupported by freebl */
+CONST_OID ansiX962prime192v2[] = { ANSI_X962_GFp_OID, 0x02 }; /* unsupported by freebl */
+CONST_OID ansiX962prime192v3[] = { ANSI_X962_GFp_OID, 0x03 }; /* unsupported by freebl */
+CONST_OID ansiX962prime239v1[] = { ANSI_X962_GFp_OID, 0x04 }; /* unsupported by freebl */
+CONST_OID ansiX962prime239v2[] = { ANSI_X962_GFp_OID, 0x05 }; /* unsupported by freebl */
+CONST_OID ansiX962prime239v3[] = { ANSI_X962_GFp_OID, 0x06 }; /* unsupported by freebl */
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 secgECsecp112r1[] = { SECG_OID, 0x06 }; /* unsupported by freebl */
+CONST_OID secgECsecp112r2[] = { SECG_OID, 0x07 }; /* unsupported by freebl */
+CONST_OID secgECsecp128r1[] = { SECG_OID, 0x1c }; /* unsupported by freebl */
+CONST_OID secgECsecp128r2[] = { SECG_OID, 0x1d }; /* unsupported by freebl */
+CONST_OID secgECsecp160k1[] = { SECG_OID, 0x09 }; /* unsupported by freebl */
+CONST_OID secgECsecp160r1[] = { SECG_OID, 0x08 }; /* unsupported by freebl */
+CONST_OID secgECsecp160r2[] = { SECG_OID, 0x1e }; /* unsupported by freebl */
+CONST_OID secgECsecp192k1[] = { SECG_OID, 0x1f }; /* unsupported by freebl */
+CONST_OID secgECsecp224k1[] = { SECG_OID, 0x20 }; /* unsupported by freebl */
+CONST_OID secgECsecp224r1[] = { SECG_OID, 0x21 }; /* unsupported by freebl */
+CONST_OID secgECsecp256k1[] = { SECG_OID, 0x0a }; /* unsupported by freebl */
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 };
+CONST_OID ansiX962c2pnb163v1[] = { ANSI_X962_GF2m_OID, 0x01 }; /* unsupported by freebl */
+CONST_OID ansiX962c2pnb163v2[] = { ANSI_X962_GF2m_OID, 0x02 }; /* unsupported by freebl */
+CONST_OID ansiX962c2pnb163v3[] = { ANSI_X962_GF2m_OID, 0x03 }; /* unsupported by freebl */
+CONST_OID ansiX962c2pnb176v1[] = { ANSI_X962_GF2m_OID, 0x04 }; /* unsupported by freebl */
+CONST_OID ansiX962c2tnb191v1[] = { ANSI_X962_GF2m_OID, 0x05 }; /* unsupported by freebl */
+CONST_OID ansiX962c2tnb191v2[] = { ANSI_X962_GF2m_OID, 0x06 }; /* unsupported by freebl */
+CONST_OID ansiX962c2tnb191v3[] = { ANSI_X962_GF2m_OID, 0x07 }; /* unsupported by freebl */
+CONST_OID ansiX962c2onb191v4[] = { ANSI_X962_GF2m_OID, 0x08 }; /* unsupported by freebl */
+CONST_OID ansiX962c2onb191v5[] = { ANSI_X962_GF2m_OID, 0x09 }; /* unsupported by freebl */
+CONST_OID ansiX962c2pnb208w1[] = { ANSI_X962_GF2m_OID, 0x0a }; /* unsupported by freebl */
+CONST_OID ansiX962c2tnb239v1[] = { ANSI_X962_GF2m_OID, 0x0b }; /* unsupported by freebl */
+CONST_OID ansiX962c2tnb239v2[] = { ANSI_X962_GF2m_OID, 0x0c }; /* unsupported by freebl */
+CONST_OID ansiX962c2tnb239v3[] = { ANSI_X962_GF2m_OID, 0x0d }; /* unsupported by freebl */
+CONST_OID ansiX962c2onb239v4[] = { ANSI_X962_GF2m_OID, 0x0e }; /* unsupported by freebl */
+CONST_OID ansiX962c2onb239v5[] = { ANSI_X962_GF2m_OID, 0x0f }; /* unsupported by freebl */
+CONST_OID ansiX962c2pnb272w1[] = { ANSI_X962_GF2m_OID, 0x10 }; /* unsupported by freebl */
+CONST_OID ansiX962c2pnb304w1[] = { ANSI_X962_GF2m_OID, 0x11 }; /* unsupported by freebl */
+CONST_OID ansiX962c2tnb359v1[] = { ANSI_X962_GF2m_OID, 0x12 }; /* unsupported by freebl */
+CONST_OID ansiX962c2pnb368w1[] = { ANSI_X962_GF2m_OID, 0x13 }; /* unsupported by freebl */
+CONST_OID ansiX962c2tnb431r1[] = { ANSI_X962_GF2m_OID, 0x14 }; /* unsupported by freebl */
/* 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 }
+CONST_OID secgECsect113r1[] = { SECG_OID, 0x04 }; /* unsupported by freebl */
+CONST_OID secgECsect113r2[] = { SECG_OID, 0x05 }; /* unsupported by freebl */
+CONST_OID secgECsect131r1[] = { SECG_OID, 0x16 }; /* unsupported by freebl */
+CONST_OID secgECsect131r2[] = { SECG_OID, 0x17 }; /* unsupported by freebl */
+CONST_OID secgECsect163k1[] = { SECG_OID, 0x01 }; /* unsupported by freebl */
+CONST_OID secgECsect163r1[] = { SECG_OID, 0x02 }; /* unsupported by freebl */
+CONST_OID secgECsect163r2[] = { SECG_OID, 0x0f }; /* unsupported by freebl */
+CONST_OID secgECsect193r1[] = { SECG_OID, 0x18 }; /* unsupported by freebl */
+CONST_OID secgECsect193r2[] = { SECG_OID, 0x19 }; /* unsupported by freebl */
+CONST_OID secgECsect233k1[] = { SECG_OID, 0x1a }; /* unsupported by freebl */
+CONST_OID secgECsect233r1[] = { SECG_OID, 0x1b }; /* unsupported by freebl */
+CONST_OID secgECsect239k1[] = { SECG_OID, 0x03 }; /* unsupported by freebl */
+CONST_OID secgECsect283k1[] = { SECG_OID, 0x10 }; /* unsupported by freebl */
+CONST_OID secgECsect283r1[] = { SECG_OID, 0x11 }; /* unsupported by freebl */
+CONST_OID secgECsect409k1[] = { SECG_OID, 0x24 }; /* unsupported by freebl */
+CONST_OID secgECsect409r1[] = { SECG_OID, 0x25 }; /* unsupported by freebl */
+CONST_OID secgECsect571k1[] = { SECG_OID, 0x26 }; /* unsupported by freebl */
+CONST_OID secgECsect571r1[] = { SECG_OID, 0x27 }; /* unsupported by freebl */
+
+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 };
+
+/* https://tools.ietf.org/html/draft-josefsson-pkix-newcurves-01
+ * 1.3.6.1.4.1.11591.15.1
+ */
+CONST_OID curve25519[] = { 0x2B, 0x06, 0x01, 0x04, 0x01, 0xDA, 0x47, 0x0F, 0x01 };
+
+#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 }
+#define OD(oid, tag, desc, mech, ext) \
+ { \
+ OI(oid) \
+ , tag, desc, mech, ext \
+ }
+#define ODE(tag, desc, mech, ext) \
+ { \
+ { siDEROID, NULL, 0 }, tag, desc, mech, ext \
+ }
#else
-#define OD(oid,tag,desc,mech,ext) { OI(oid), tag, 0, mech, ext }
+#define OD(oid, tag, desc, mech, ext) \
+ { \
+ OI(oid) \
+ , tag, 0, mech, ext \
+ }
+#define ODE(tag, desc, mech, ext) \
+ { \
+ { siDEROID, NULL, 0 }, tag, 0, mech, ext \
+ }
#endif
#if defined(NSS_ALLOW_UNSUPPORTED_CRITICAL)
-#define FAKE_SUPPORTED_CERT_EXTENSION SUPPORTED_CERT_EXTENSION
+#define FAKE_SUPPORTED_CERT_EXTENSION SUPPORTED_CERT_EXTENSION
#else
#define FAKE_SUPPORTED_CERT_EXTENSION UNSUPPORTED_CERT_EXTENSION
#endif
@@ -593,1053 +625,1135 @@ CONST_OID evIncorporationCountry[] = { EV_NAME_ATTRIBUTE, 3 };
* 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 ),
+ { { 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 ),
+ 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 ),
-
+ 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 ),
+ 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 ),
+ 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 ),
+ 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 ),
+ 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 ),
+ 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 ),
+ 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),
+ 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 ),
+ 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 ),
+ /* 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 ),
+ 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(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(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 ),
+ 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 ),
+ 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 ),
+ 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),
+ 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 ),
+ 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 */
+ /* NOTE: Only P256, P384, P521, and 25519 are supported by softoken.
+ * Using other curves requires an appropriate token. */
/* 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 ),
+ 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 ),
+ 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 ),
+ 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 ),
+ 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 ),
+ 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 ),
+ 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 ),
+ 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 ),
+ 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 ),
+ 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(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 ),
+ 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 ),
- OD( x520Name, SEC_OID_AVA_NAME,
- "X520 Name", CKM_INVALID_MECHANISM, INVALID_CERT_EXTENSION )
+ 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),
+ OD(x520Name, SEC_OID_AVA_NAME,
+ "X520 Name", CKM_INVALID_MECHANISM, INVALID_CERT_EXTENSION),
+
+ OD(aes128_GCM, SEC_OID_AES_128_GCM,
+ "AES-128-GCM", CKM_AES_GCM, INVALID_CERT_EXTENSION),
+ OD(aes192_GCM, SEC_OID_AES_192_GCM,
+ "AES-192-GCM", CKM_AES_GCM, INVALID_CERT_EXTENSION),
+ OD(aes256_GCM, SEC_OID_AES_256_GCM,
+ "AES-256-GCM", CKM_AES_GCM, INVALID_CERT_EXTENSION),
+ OD(idea_CBC, SEC_OID_IDEA_CBC,
+ "IDEA_CBC", CKM_INVALID_MECHANISM, INVALID_CERT_EXTENSION),
+
+ ODE(SEC_OID_RC2_40_CBC,
+ "RC2-40-CBC", CKM_RC2_CBC, INVALID_CERT_EXTENSION),
+ ODE(SEC_OID_DES_40_CBC,
+ "DES-40-CBC", CKM_RC2_CBC, INVALID_CERT_EXTENSION),
+ ODE(SEC_OID_RC4_40,
+ "RC4-40", CKM_RC4, INVALID_CERT_EXTENSION),
+ ODE(SEC_OID_RC4_56,
+ "RC4-56", CKM_RC4, INVALID_CERT_EXTENSION),
+ ODE(SEC_OID_NULL_CIPHER,
+ "NULL cipher", CKM_INVALID_MECHANISM, INVALID_CERT_EXTENSION),
+ ODE(SEC_OID_HMAC_MD5,
+ "HMAC-MD5", CKM_MD5_HMAC, INVALID_CERT_EXTENSION),
+ ODE(SEC_OID_TLS_RSA,
+ "TLS RSA key exchange", CKM_INVALID_MECHANISM, INVALID_CERT_EXTENSION),
+ ODE(SEC_OID_TLS_DHE_RSA,
+ "TLS DHE-RSA key exchange", CKM_INVALID_MECHANISM, INVALID_CERT_EXTENSION),
+ ODE(SEC_OID_TLS_DHE_DSS,
+ "TLS DHE-DSS key exchange", CKM_INVALID_MECHANISM, INVALID_CERT_EXTENSION),
+ ODE(SEC_OID_TLS_DH_RSA,
+ "TLS DH-RSA key exchange", CKM_INVALID_MECHANISM, INVALID_CERT_EXTENSION),
+ ODE(SEC_OID_TLS_DH_DSS,
+ "TLS DH-DSS key exchange", CKM_INVALID_MECHANISM, INVALID_CERT_EXTENSION),
+ ODE(SEC_OID_TLS_DH_ANON,
+ "TLS DH-ANON key exchange", CKM_INVALID_MECHANISM, INVALID_CERT_EXTENSION),
+ ODE(SEC_OID_TLS_ECDHE_ECDSA,
+ "TLS ECDHE-ECDSA key exchange", CKM_INVALID_MECHANISM, INVALID_CERT_EXTENSION),
+ ODE(SEC_OID_TLS_ECDHE_RSA,
+ "TLS ECDHE-RSA key exchange", CKM_INVALID_MECHANISM, INVALID_CERT_EXTENSION),
+ ODE(SEC_OID_TLS_ECDH_ECDSA,
+ "TLS ECDH-ECDSA key exchange", CKM_INVALID_MECHANISM, INVALID_CERT_EXTENSION),
+ ODE(SEC_OID_TLS_ECDH_RSA,
+ "TLS ECDH-RSA key exchange", CKM_INVALID_MECHANISM, INVALID_CERT_EXTENSION),
+ ODE(SEC_OID_TLS_ECDH_ANON,
+ "TLS ECDH-ANON key exchange", CKM_INVALID_MECHANISM, INVALID_CERT_EXTENSION),
+ ODE(SEC_OID_TLS_RSA_EXPORT,
+ "TLS RSA-EXPORT key exchange", CKM_INVALID_MECHANISM, INVALID_CERT_EXTENSION),
+ ODE(SEC_OID_TLS_DHE_RSA_EXPORT,
+ "TLS DHE-RSA-EXPORT key exchange", CKM_INVALID_MECHANISM, INVALID_CERT_EXTENSION),
+ ODE(SEC_OID_TLS_DHE_DSS_EXPORT,
+ "TLS DHE-DSS-EXPORT key exchange", CKM_INVALID_MECHANISM, INVALID_CERT_EXTENSION),
+ ODE(SEC_OID_TLS_DH_RSA_EXPORT,
+ "TLS DH-RSA-EXPORT key exchange", CKM_INVALID_MECHANISM, INVALID_CERT_EXTENSION),
+ ODE(SEC_OID_TLS_DH_DSS_EXPORT,
+ "TLS DH-DSS-EXPORT key exchange", CKM_INVALID_MECHANISM, INVALID_CERT_EXTENSION),
+ ODE(SEC_OID_TLS_DH_ANON_EXPORT,
+ "TLS DH-ANON-EXPORT key exchange", CKM_INVALID_MECHANISM, INVALID_CERT_EXTENSION),
+ ODE(SEC_OID_APPLY_SSL_POLICY,
+ "Apply SSL policy (pseudo-OID)", CKM_INVALID_MECHANISM, INVALID_CERT_EXTENSION),
+ ODE(SEC_OID_CHACHA20_POLY1305,
+ "ChaCha20-Poly1305", CKM_NSS_CHACHA20_POLY1305, INVALID_CERT_EXTENSION),
+
+ ODE(SEC_OID_TLS_ECDHE_PSK,
+ "TLS ECHDE-PSK key exchange", CKM_INVALID_MECHANISM, INVALID_CERT_EXTENSION),
+ ODE(SEC_OID_TLS_DHE_PSK,
+ "TLS DHE-PSK key exchange", CKM_INVALID_MECHANISM, INVALID_CERT_EXTENSION),
+
+ ODE(SEC_OID_TLS_FFDHE_2048,
+ "TLS FFDHE 2048-bit key exchange", CKM_INVALID_MECHANISM, INVALID_CERT_EXTENSION),
+ ODE(SEC_OID_TLS_FFDHE_3072,
+ "TLS FFDHE 3072-bit key exchange", CKM_INVALID_MECHANISM, INVALID_CERT_EXTENSION),
+ ODE(SEC_OID_TLS_FFDHE_4096,
+ "TLS FFDHE 4096-bit key exchange", CKM_INVALID_MECHANISM, INVALID_CERT_EXTENSION),
+ ODE(SEC_OID_TLS_FFDHE_6144,
+ "TLS FFDHE 6144-bit key exchange", CKM_INVALID_MECHANISM, INVALID_CERT_EXTENSION),
+ ODE(SEC_OID_TLS_FFDHE_8192,
+ "TLS FFDHE 8192-bit key exchange", CKM_INVALID_MECHANISM, INVALID_CERT_EXTENSION),
+ ODE(SEC_OID_TLS_DHE_CUSTOM,
+ "TLS DHE custom group key exchange", CKM_INVALID_MECHANISM, INVALID_CERT_EXTENSION),
+ OD(curve25519, SEC_OID_CURVE25519,
+ "Curve25519", CKM_INVALID_MECHANISM, INVALID_CERT_EXTENSION),
+ ODE(SEC_OID_TLS13_KEA_ANY,
+ "TLS 1.3 fake key exchange", CKM_INVALID_MECHANISM, INVALID_CERT_EXTENSION),
};
/* PRIVATE EXTENDED SECOID Table
@@ -1647,11 +1761,11 @@ const static SECOidData oids[SEC_OID_TOTAL] = {
* 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
+ * 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 */
+ PRUint32 notPolicyFlags; /* ones complement of policy flags */
} privXOid;
static privXOid xOids[SEC_OID_TOTAL];
@@ -1660,37 +1774,37 @@ 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
+ * 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.
+ * 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;
+ 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;
+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;
+ SECStatus rv = SECSuccess;
dynOidLock = NSSRWLock_New(1, "dynamic OID data");
if (!dynOidLock) {
- return SECFailure; /* Error code should already be set. */
+ return SECFailure; /* Error code should already be set. */
}
dynOidPool = PORT_NewArena(2048);
if (!dynOidPool) {
@@ -1701,42 +1815,41 @@ secoid_InitDynOidData(void)
/* Add oidData to hash table. Caller holds write lock dynOidLock. */
static SECStatus
-secoid_HashDynamicOiddata(const SECOidData * oid)
+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;
- }
+ PL_CompareValues, NULL, NULL);
+ if (!dynOidHash) {
+ return SECFailure;
+ }
}
- entry = PL_HashTableAdd( dynOidHash, &oid->oid, (void *)oid );
+ 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.
+ * each time.
*/
static SECOidData *
-secoid_FindDynamic(const SECItem *key)
+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);
+ 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);
+ PORT_SetError(SEC_ERROR_UNRECOGNIZED_OID);
}
return ret;
}
@@ -1748,21 +1861,21 @@ secoid_FindDynamicByTag(SECOidTag tagnum)
int tagNumDiff;
if (tagnum < SEC_OID_TOTAL) {
- PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
- return NULL;
+ 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);
+ 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);
+ PORT_SetError(SEC_ERROR_UNRECOGNIZED_OID);
}
return dxo;
}
@@ -1771,99 +1884,98 @@ secoid_FindDynamicByTag(SECOidTag tagnum)
* This routine is thread safe now.
*/
SECOidTag
-SECOID_AddEntry(const SECOidData * src)
+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 || \
+ 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;
+ 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 (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;
+ 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
+ ** 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;
+ /* 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;
+ table = dynOidTable;
tableEntries = dynOidEntriesAllocated;
- used = dynOidEntriesUsed;
+ 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;
+ 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;
+ goto done;
}
- rv = SECITEM_CopyItem(dynOidPool, &dst->oid, &src->oid);
+ rv = SECITEM_CopyItem(dynOidPool, &dst->oid, &src->oid);
if (rv != SECSuccess) {
- goto done;
+ goto done;
}
dst->desc = PORT_ArenaStrdup(dynOidPool, src->desc);
if (!dst->desc) {
- goto done;
+ goto done;
}
- dst->offset = (SECOidTag)(used + SEC_OID_TOTAL);
- dst->mechanism = src->mechanism;
+ 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;
+ 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 *oidhash = NULL;
static PLHashTable *oidmechhash = NULL;
static PLHashNumber
@@ -1872,35 +1984,36 @@ secoid_HashNumber(const void *key)
return (PLHashNumber)((char *)key - (char *)NULL);
}
+#define DEF_FLAGS (NSS_USE_ALG_IN_CERT_SIGNATURE | NSS_USE_ALG_IN_SSL_KX | NSS_USE_ALG_IN_SSL_KX)
static void
-handleHashAlgSupport(char * envVal)
+handleHashAlgSupport(char *envVal)
{
- char * myVal = PORT_Strdup(envVal); /* Get a copy we can alter */
- char * arg = myVal;
+ 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|NSS_USE_ALG_IN_SSL_KX) : 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|NSS_USE_ALG_IN_SSL_KX));
- }
- }
- }
- arg = nextArg;
+ char *nextArg = PL_strpbrk(arg, ";");
+ PRUint32 notEnable;
+
+ if (nextArg) {
+ while (*nextArg == ';') {
+ *nextArg++ = '\0';
+ }
+ }
+ notEnable = (*arg == '-') ? (DEF_FLAGS) : 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 & ~(DEF_FLAGS));
+ }
+ }
+ }
+ arg = nextArg;
}
- PORT_Free(myVal); /* can handle NULL argument OK */
+ PORT_Free(myVal); /* can handle NULL argument OK */
}
SECStatus
@@ -1909,74 +2022,77 @@ SECOID_Init(void)
PLHashEntry *entry;
const SECOidData *oid;
int i;
- char * envVal;
+ char *envVal;
#define NSS_VERSION_VARIABLE __nss_util_version
#include "verref.h"
if (oidhash) {
- return SECSuccess; /* already initialized */
+ 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;
+ if (!PR_GetEnvSecure("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");
+ /* turn off NSS_USE_POLICY_IN_SSL by default */
+ xOids[SEC_OID_APPLY_SSL_POLICY].notPolicyFlags = NSS_USE_POLICY_IN_SSL;
+
+ envVal = PR_GetEnvSecure("NSS_HASH_ALG_SUPPORT");
if (envVal)
- handleHashAlgSupport(envVal);
+ handleHashAlgSupport(envVal);
if (secoid_InitDynOidData() != SECSuccess) {
PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
PORT_Assert(0); /* this function should never fail */
- return SECFailure;
+ return SECFailure;
}
-
+
oidhash = PL_NewHashTable(0, SECITEM_Hash, SECITEM_HashCompare,
- PL_CompareValues, NULL, NULL);
+ PL_CompareValues, NULL, NULL);
oidmechhash = PL_NewHashTable(0, secoid_HashNumber, PL_CompareValues,
- PL_CompareValues, NULL, NULL);
+ PL_CompareValues, NULL, NULL);
- if ( !oidhash || !oidmechhash) {
- PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
- PORT_Assert(0); /*This function should never fail. */
- return(SECFailure);
+ 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];
+ for (i = 0; i < SEC_OID_TOTAL; i++) {
+ oid = &oids[i];
- PORT_Assert ( oid->offset == i );
+ PORT_Assert(oid->offset == i);
- entry = PL_HashTableAdd( oidhash, &oid->oid, (void *)oid );
- if ( entry == NULL ) {
- PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
+ 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);
+ 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);
- }
- }
+ return (SECFailure);
+ }
+ }
}
- PORT_Assert (i == SEC_OID_TOTAL);
+ PORT_Assert(i == SEC_OID_TOTAL);
- return(SECSuccess);
+ return (SECSuccess);
}
SECOidData *
@@ -1986,8 +2102,8 @@ SECOID_FindOIDByMechanism(unsigned long mechanism)
PR_ASSERT(oidhash != NULL);
- ret = PL_HashTableLookupConst ( oidmechhash, (void *)mechanism);
- if ( ret == NULL ) {
+ ret = PL_HashTableLookupConst(oidmechhash, (void *)mechanism);
+ if (ret == NULL) {
PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
}
@@ -2000,16 +2116,16 @@ 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);
- }
+
+ ret = PL_HashTableLookupConst(oidhash, oid);
+ if (ret == NULL) {
+ ret = secoid_FindDynamic(oid);
+ if (ret == NULL) {
+ PORT_SetError(SEC_ERROR_UNRECOGNIZED_OID);
+ }
}
- return(ret);
+ return (ret);
}
SECOidTag
@@ -2017,9 +2133,9 @@ SECOID_FindOIDTag(const SECItem *oid)
{
SECOidData *oiddata;
- oiddata = SECOID_FindOID (oid);
+ oiddata = SECOID_FindOID(oid);
if (oiddata == NULL)
- return SEC_OID_UNKNOWN;
+ return SEC_OID_UNKNOWN;
return oiddata->offset;
}
@@ -2029,35 +2145,34 @@ SECOidData *
SECOID_FindOIDByTag(SECOidTag tagnum)
{
if (tagnum >= SEC_OID_TOTAL) {
- return (SECOidData *)secoid_FindDynamicByTag(tagnum);
+ return (SECOidData *)secoid_FindDynamicByTag(tagnum);
}
PORT_Assert((unsigned int)tagnum < SEC_OID_TOTAL);
return (SECOidData *)(&oids[tagnum]);
}
-PRBool SECOID_KnownCertExtenOID (SECItem *extenOid)
+PRBool
+SECOID_KnownCertExtenOID(SECItem *extenOid)
{
- SECOidData * oidData;
+ SECOidData *oidData;
- oidData = SECOID_FindOID (extenOid);
+ oidData = SECOID_FindOID(extenOid);
if (oidData == (SECOidData *)NULL)
- return (PR_FALSE);
- return ((oidData->supportedExtension == SUPPORTED_CERT_EXTENSION) ?
- PR_TRUE : PR_FALSE);
+ 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;
+ 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
+ * 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.
*/
@@ -2065,8 +2180,8 @@ static privXOid *
secoid_FindXOidByTag(SECOidTag tagnum)
{
if (tagnum >= SEC_OID_TOTAL) {
- dynXOid *dxo = secoid_FindDynamicByTag(tagnum);
- return (dxo ? &dxo->priv : NULL);
+ dynXOid *dxo = secoid_FindDynamicByTag(tagnum);
+ return (dxo ? &dxo->priv : NULL);
}
PORT_Assert((unsigned int)tagnum < SEC_OID_TOTAL);
@@ -2078,15 +2193,15 @@ secoid_FindXOidByTag(SECOidTag tagnum)
* Default value for any algorithm is 0xffffffff (enabled for all purposes).
* No value is output if function returns SECFailure.
*/
-SECStatus
+SECStatus
NSS_GetAlgorithmPolicy(SECOidTag tag, PRUint32 *pValue)
{
- privXOid * pxo = secoid_FindXOidByTag(tag);
+ privXOid *pxo = secoid_FindXOidByTag(tag);
if (!pxo)
- return SECFailure;
+ return SECFailure;
if (!pValue) {
PORT_SetError(SEC_ERROR_INVALID_ARGS);
- return SECFailure;
+ return SECFailure;
}
*pValue = ~(pxo->notPolicyFlags);
return SECSuccess;
@@ -2099,13 +2214,13 @@ NSS_GetAlgorithmPolicy(SECOidTag tag, PRUint32 *pValue)
SECStatus
NSS_SetAlgorithmPolicy(SECOidTag tag, PRUint32 setBits, PRUint32 clearBits)
{
- privXOid * pxo = secoid_FindXOidByTag(tag);
- PRUint32 policyFlags;
+ 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.
+ 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;
@@ -2118,7 +2233,9 @@ NSS_SetAlgorithmPolicy(SECOidTag tag, PRUint32 setBits, PRUint32 clearBits)
/* 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
+#define SKIP_AFTER_FORK(x) \
+ if (!parentForkedAfterC_Initialize) \
+ x
/*
* free up the oid tables.
@@ -2127,56 +2244,57 @@ SECStatus
SECOID_Shutdown(void)
{
if (oidhash) {
- PL_HashTableDestroy(oidhash);
- oidhash = NULL;
+ PL_HashTableDestroy(oidhash);
+ oidhash = NULL;
}
if (oidmechhash) {
- PL_HashTableDestroy(oidmechhash);
- oidmechhash = NULL;
+ PL_HashTableDestroy(oidmechhash);
+ oidmechhash = NULL;
}
/* Have to handle the case where the lock was created, but
- ** the pool wasn't.
+ ** 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;
+ 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;
+ /* 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)
+void
+UTIL_SetForkState(PRBool forked)
{
parentForkedAfterC_Initialize = forked;
}
diff --git a/nss/lib/util/secoid.h b/nss/lib/util/secoid.h
index 1908744..e6eaa8c 100644
--- a/nss/lib/util/secoid.h
+++ b/nss/lib/util/secoid.h
@@ -27,7 +27,7 @@ SEC_ASN1_CHOOSER_DECLARE(SECOID_AlgorithmIDTemplate)
/*
* OID handling routines
*/
-extern SECOidData *SECOID_FindOID( const SECItem *oid);
+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);
@@ -39,13 +39,13 @@ extern SECOidData *SECOID_FindOIDByMechanism(unsigned long mechanism);
/*
** 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
+** "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);
+ SECOidTag tag, SECItem *params);
/*
** Copy the "src" object to "dest". Memory is allocated in "dest" for
@@ -54,7 +54,7 @@ extern SECStatus SECOID_SetAlgorithmID(PLArenaPool *arena, SECAlgorithmID *aid,
** to do that).
*/
extern SECStatus SECOID_CopyAlgorithmID(PLArenaPool *arena, SECAlgorithmID *dest,
- const SECAlgorithmID *src);
+ const SECAlgorithmID *src);
/*
** Get the tag number for the given algorithm-id object.
@@ -63,8 +63,8 @@ extern SECOidTag SECOID_GetAlgorithmTag(const 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
+** "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);
@@ -73,9 +73,9 @@ extern void SECOID_DestroyAlgorithmID(SECAlgorithmID *aid, PRBool freeit);
** them.
*/
extern SECComparison SECOID_CompareAlgorithmID(SECAlgorithmID *a,
- SECAlgorithmID *b);
+ SECAlgorithmID *b);
-extern PRBool SECOID_KnownCertExtenOID (SECItem *extenOid);
+extern PRBool SECOID_KnownCertExtenOID(SECItem *extenOid);
/* Given a tag number, return a string describing it.
*/
@@ -85,7 +85,7 @@ extern const char *SECOID_FindOIDTagDescription(SECOidTag tagnum);
** 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);
+extern SECOidTag SECOID_AddEntry(const SECOidData *src);
/*
* initialize the oid data structures.
@@ -100,24 +100,24 @@ 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
+ * 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
+ * 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,
+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
+ * 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.
*/
@@ -135,7 +135,6 @@ extern SECStatus NSS_GetAlgorithmPolicy(SECOidTag tag, PRUint32 *pValue);
extern SECStatus
NSS_SetAlgorithmPolicy(SECOidTag tag, PRUint32 setBits, PRUint32 clearBits);
-
SEC_END_PROTOS
#endif /* _SECOID_H_ */
diff --git a/nss/lib/util/secoidt.h b/nss/lib/util/secoidt.h
index 747450e..0a40f29 100644
--- a/nss/lib/util/secoidt.h
+++ b/nss/lib/util/secoidt.h
@@ -135,7 +135,7 @@ typedef enum {
SEC_OID_X509_CRL_NUMBER = 94,
SEC_OID_X509_REASON_CODE = 95,
SEC_OID_X509_INVALID_DATE = 96,
- /* End of x.509 v3 Extensions */
+ /* End of x.509 v3 Extensions */
SEC_OID_X500_RSA_ENCRYPTION = 97,
@@ -153,7 +153,7 @@ typedef enum {
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_OFFLINE_TRANSPORT_MODE,
SEC_OID_PKCS12_ONLINE_TRANSPORT_MODE, */
SEC_OID_PKCS12_PKCS8_KEY_SHROUDING = 109,
SEC_OID_PKCS12_KEY_BAG_ID = 110,
@@ -250,7 +250,7 @@ typedef enum {
/* 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,
@@ -260,122 +260,122 @@ typedef enum {
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_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_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,
+ 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_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
+ 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,
+ 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_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_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,
+ 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,
+ 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_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,
+ 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,
+ SEC_OID_PKIX_CA_ISSUERS = 273,
+ SEC_OID_PKCS9_EXTENSION_REQUEST = 274,
/* new EC Signature oids */
SEC_OID_ANSIX962_ECDSA_SIGNATURE_RECOMMENDED_DIGEST = 275,
@@ -386,69 +386,120 @@ typedef enum {
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_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,
+ 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,
+ 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_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_PKIX_TIMESTAMPING = 299,
+ SEC_OID_PKIX_CA_REPOSITORY = 300,
- SEC_OID_ISO_SHA1_WITH_RSA_SIGNATURE = 301,
+ SEC_OID_ISO_SHA1_WITH_RSA_SIGNATURE = 301,
- SEC_OID_SEED_CBC = 302,
+ SEC_OID_SEED_CBC = 302,
- SEC_OID_X509_ANY_POLICY = 303,
+ 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_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_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_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,
+ 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
+ * szOID_KP_CTL_USAGE_SIGNING
* where KP stands for Key Purpose
*/
- SEC_OID_MS_EXT_KEY_USAGE_CTL_SIGNING = 316,
+ SEC_OID_MS_EXT_KEY_USAGE_CTL_SIGNING = 316,
/* The 'name' attribute type in X.520 */
- SEC_OID_AVA_NAME = 317,
+ SEC_OID_AVA_NAME = 317,
+
+ SEC_OID_AES_128_GCM = 318,
+ SEC_OID_AES_192_GCM = 319,
+ SEC_OID_AES_256_GCM = 320,
+ SEC_OID_IDEA_CBC = 321,
+
+ /* pseudo - OIDs */
+
+ SEC_OID_RC2_40_CBC = 322,
+ SEC_OID_DES_40_CBC = 323,
+ SEC_OID_RC4_40 = 324,
+ SEC_OID_RC4_56 = 325,
+ SEC_OID_NULL_CIPHER = 326,
+
+ SEC_OID_HMAC_MD5 = 327,
+
+ SEC_OID_TLS_RSA = 328,
+ SEC_OID_TLS_DHE_RSA = 329,
+ SEC_OID_TLS_DHE_DSS = 330,
+ SEC_OID_TLS_DH_RSA = 331,
+ SEC_OID_TLS_DH_DSS = 332,
+ SEC_OID_TLS_DH_ANON = 333,
+ SEC_OID_TLS_ECDHE_ECDSA = 334,
+ SEC_OID_TLS_ECDHE_RSA = 335,
+ SEC_OID_TLS_ECDH_ECDSA = 336,
+ SEC_OID_TLS_ECDH_RSA = 337,
+ SEC_OID_TLS_ECDH_ANON = 338,
+ SEC_OID_TLS_RSA_EXPORT = 339,
+
+ SEC_OID_TLS_DHE_RSA_EXPORT = 340,
+ SEC_OID_TLS_DHE_DSS_EXPORT = 341,
+ SEC_OID_TLS_DH_RSA_EXPORT = 342,
+ SEC_OID_TLS_DH_DSS_EXPORT = 343,
+ SEC_OID_TLS_DH_ANON_EXPORT = 344,
+ SEC_OID_APPLY_SSL_POLICY = 345,
+
+ SEC_OID_CHACHA20_POLY1305 = 346,
+
+ SEC_OID_TLS_ECDHE_PSK = 347,
+ SEC_OID_TLS_DHE_PSK = 348,
+
+ SEC_OID_TLS_FFDHE_2048 = 349,
+ SEC_OID_TLS_FFDHE_3072 = 350,
+ SEC_OID_TLS_FFDHE_4096 = 351,
+ SEC_OID_TLS_FFDHE_6144 = 352,
+ SEC_OID_TLS_FFDHE_8192 = 353,
+ SEC_OID_TLS_DHE_CUSTOM = 354,
+
+ SEC_OID_CURVE25519 = 355,
+
+ SEC_OID_TLS13_KEA_ANY = 356,
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
+#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
@@ -460,29 +511,30 @@ typedef enum {
} 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 */
+ 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.
+/* 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_IN_SSL_KX 0x00000004 /* used in SSL key exchange */
-#define NSS_USE_ALG_RESERVED 0xfffffffc /* may be used in future */
+#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_IN_SSL_KX 0x00000004 /* used in SSL key exchange */
+#define NSS_USE_ALG_IN_SSL 0x00000008 /* used in SSL record protocol */
+#define NSS_USE_POLICY_IN_SSL 0x00000010 /* enable policy in SSL protocol */
+#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/nss/lib/util/secplcy.c b/nss/lib/util/secplcy.c
index 3b55234..0c784d0 100644
--- a/nss/lib/util/secplcy.c
+++ b/nss/lib/util/secplcy.c
@@ -5,81 +5,79 @@
#include "secplcy.h"
#include "prmem.h"
-SECCipherFind *sec_CipherFindInit(PRBool onlyAllowed,
- secCPStruct *policy,
- long *ciphers)
+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;
+ SECCipherFind *find = PR_NEWZAP(SECCipherFind);
+ if (find) {
+ find->policy = policy;
+ find->ciphers = ciphers;
+ find->onlyAllowed = onlyAllowed;
+ find->index = -1;
}
- return find;
+ return find;
}
-long sec_CipherFindNext(SECCipherFind *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;
+ 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];
+ 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 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++;
- }
- }
+ /* If this cipher isn't allowed by policy, continue. */
+ if (!(*policy)) {
+ rv = -1;
+ find->index++;
+ }
+ }
}
- return rv;
+ return rv;
}
-char sec_IsCipherAllowed(long cipher, secCPStruct *policies,
- long *ciphers)
+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;
+ 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;
+ if (i < numCiphers) {
+ /* Found the cipher, get the policy value. */
+ result = *policy;
}
- return result;
+ return result;
}
-void sec_CipherFindEnd(SECCipherFind *find)
+void
+sec_CipherFindEnd(SECCipherFind *find)
{
- PR_FREEIF(find);
+ PR_FREEIF(find);
}
diff --git a/nss/lib/util/secplcy.h b/nss/lib/util/secplcy.h
index a34e233..6a85e03 100644
--- a/nss/lib/util/secplcy.h
+++ b/nss/lib/util/secplcy.h
@@ -19,10 +19,10 @@
#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 */
+#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.
+/* 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
@@ -42,7 +42,7 @@
#if defined(SEC_POLICY_USE_MD5_STRINGS)
-/* We're not testing.
+/* We're not testing.
Use md5 checksums of the strings. */
#define SEC_POLICY_SSL_HEADER \
@@ -56,7 +56,7 @@
#else
-/* We're testing.
+/* 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. "
@@ -68,22 +68,20 @@
#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. */
+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;
+struct SECCipherFindStr {
+ /* (policy) and (ciphers) are opaque to the outside world */
+ void *policy;
+ void *ciphers;
+ long index;
+ PRBool onlyAllowed;
};
typedef struct SECCipherFindStr SECCipherFind;
@@ -91,13 +89,13 @@ typedef struct SECCipherFindStr SECCipherFind;
SEC_BEGIN_PROTOS
SECCipherFind *sec_CipherFindInit(PRBool onlyAllowed,
- secCPStruct *policy,
- long *ciphers);
+ secCPStruct *policy,
+ long *ciphers);
long sec_CipherFindNext(SECCipherFind *find);
char sec_IsCipherAllowed(long cipher, secCPStruct *policies,
- long *ciphers);
+ long *ciphers);
void sec_CipherFindEnd(SECCipherFind *find);
diff --git a/nss/lib/util/secport.c b/nss/lib/util/secport.c
index 723d89b..0eea0cd 100644
--- a/nss/lib/util/secport.c
+++ b/nss/lib/util/secport.c
@@ -6,7 +6,7 @@
* secport.c - portability interfaces for security libraries
*
* This file abstracts out libc functionality that libsec depends on
- *
+ *
* NOTE - These are not public interfaces
*/
@@ -19,6 +19,7 @@
#include "nssilock.h"
#include "secport.h"
#include "prenv.h"
+#include "prinit.h"
#ifdef DEBUG
#define THREADMARK
@@ -34,40 +35,38 @@
#include "wtypes.h"
#endif
-#define SET_ERROR_CODE /* place holder for code to set PR error code. */
+#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;
+ 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
+#define ARENAPOOL_MAGIC 0xB8AC9BDF
+
+#define CHEAP_ARENAPOOL_MAGIC 0x3F16BB09
typedef struct PORTArenaPool_str {
- PLArenaPool arena;
- PRUint32 magic;
- PRLock * lock;
+ PLArenaPool arena;
+ PRUint32 magic;
+ PRLock *lock;
#ifdef THREADMARK
- PRThread *marking_thread;
- threadmark_mark *first_mark;
+ PRThread *marking_thread;
+ threadmark_mark *first_mark;
#endif
} PORTArenaPool;
-
-/* count of allocation failures. */
-unsigned long port_allocFailures;
-
-/* locations for registering Unicode conversion functions.
+/* 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;
+PORTCharConversionWSwapFunc ucs2AsciiConvertFunc;
/* NSPR memory allocation functions (PR_Malloc, PR_Calloc, and PR_Realloc)
* use the PRUint32 type for the size parameter. Before we pass a size_t or
@@ -82,12 +81,11 @@ PORT_Alloc(size_t bytes)
void *rv = NULL;
if (bytes <= MAX_SIZE) {
- /* Always allocate a non-zero amount of bytes */
- rv = PR_Malloc(bytes ? bytes : 1);
+ /* Always allocate a non-zero amount of bytes */
+ rv = PR_Malloc(bytes ? bytes : 1);
}
if (!rv) {
- ++port_allocFailures;
- PORT_SetError(SEC_ERROR_NO_MEMORY);
+ PORT_SetError(SEC_ERROR_NO_MEMORY);
}
return rv;
}
@@ -98,11 +96,10 @@ PORT_Realloc(void *oldptr, size_t bytes)
void *rv = NULL;
if (bytes <= MAX_SIZE) {
- rv = PR_Realloc(oldptr, bytes);
+ rv = PR_Realloc(oldptr, bytes);
}
if (!rv) {
- ++port_allocFailures;
- PORT_SetError(SEC_ERROR_NO_MEMORY);
+ PORT_SetError(SEC_ERROR_NO_MEMORY);
}
return rv;
}
@@ -113,12 +110,11 @@ PORT_ZAlloc(size_t bytes)
void *rv = NULL;
if (bytes <= MAX_SIZE) {
- /* Always allocate a non-zero amount of bytes */
- rv = PR_Calloc(1, bytes ? bytes : 1);
+ /* Always allocate a non-zero amount of bytes */
+ rv = PR_Calloc(1, bytes ? bytes : 1);
}
if (!rv) {
- ++port_allocFailures;
- PORT_SetError(SEC_ERROR_NO_MEMORY);
+ PORT_SetError(SEC_ERROR_NO_MEMORY);
}
return rv;
}
@@ -127,7 +123,7 @@ void
PORT_Free(void *ptr)
{
if (ptr) {
- PR_Free(ptr);
+ PR_Free(ptr);
}
}
@@ -135,15 +131,15 @@ void
PORT_ZFree(void *ptr, size_t len)
{
if (ptr) {
- memset(ptr, 0, len);
- PR_Free(ptr);
+ memset(ptr, 0, len);
+ PR_Free(ptr);
}
}
char *
PORT_Strdup(const char *str)
{
- size_t len = PORT_Strlen(str)+1;
+ size_t len = PORT_Strlen(str) + 1;
char *newstr;
newstr = (char *)PORT_Alloc(len);
@@ -155,7 +151,7 @@ PORT_Strdup(const char *str)
void
PORT_SetError(int value)
-{
+{
#ifdef DEBUG_jp96085
PORT_Assert(value != SEC_ERROR_REUSED_ISSUER_AND_SERIAL);
#endif
@@ -166,7 +162,7 @@ PORT_SetError(int value)
int
PORT_GetError(void)
{
- return(PR_GetError());
+ return (PR_GetError());
}
/********************* Arena code follows *****************************
@@ -221,24 +217,30 @@ PLArenaPool *
PORT_NewArena(unsigned long chunksize)
{
PORTArenaPool *pool;
-
+
if (chunksize > MAX_SIZE) {
- PORT_SetError(SEC_ERROR_NO_MEMORY);
- return NULL;
+ PORT_SetError(SEC_ERROR_NO_MEMORY);
+ return NULL;
}
pool = PORT_ZNew(PORTArenaPool);
if (!pool) {
- return NULL;
+ return NULL;
}
pool->magic = ARENAPOOL_MAGIC;
pool->lock = PZ_NewLock(nssILockArena);
if (!pool->lock) {
- ++port_allocFailures;
- PORT_Free(pool);
- return NULL;
+ PORT_Free(pool);
+ return NULL;
}
PL_InitArenaPool(&pool->arena, "security", chunksize, sizeof(double));
- return(&pool->arena);
+ return (&pool->arena);
+}
+
+void
+PORT_InitCheapArena(PORTCheapArenaPool *pool, unsigned long chunksize)
+{
+ pool->magic = CHEAP_ARENAPOOL_MAGIC;
+ PL_InitArenaPool(&pool->arena, "security", chunksize, sizeof(double));
}
void *
@@ -249,38 +251,37 @@ PORT_ArenaAlloc(PLArenaPool *arena, size_t size)
PORTArenaPool *pool = (PORTArenaPool *)arena;
if (size <= 0) {
- size = 1;
+ 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);
+ /* 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);
+ 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);
+ PL_ARENA_ALLOCATE(p, arena, size);
}
if (!p) {
- ++port_allocFailures;
- PORT_SetError(SEC_ERROR_NO_MEMORY);
+ PORT_SetError(SEC_ERROR_NO_MEMORY);
}
- return(p);
+ return (p);
}
void *
@@ -294,10 +295,20 @@ PORT_ArenaZAlloc(PLArenaPool *arena, size_t size)
p = PORT_ArenaAlloc(arena, size);
if (p) {
- PORT_Memset(p, 0, size);
+ PORT_Memset(p, 0, size);
}
- return(p);
+ return (p);
+}
+
+static PRCallOnceType setupUseFreeListOnce;
+static PRBool useFreeList;
+
+static PRStatus
+SetupUseFreeList(void)
+{
+ useFreeList = (PR_GetEnvSecure("NSS_DISABLE_ARENA_FREE_LIST") == NULL);
+ return PR_SUCCESS;
}
/*
@@ -307,35 +318,40 @@ 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;
+ PRLock *lock = (PRLock *)0;
+ size_t len = sizeof *arena;
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;
+ return;
+ if (ARENAPOOL_MAGIC == pool->magic) {
+ len = sizeof *pool;
+ lock = pool->lock;
+ PZ_Lock(lock);
}
if (zero) {
- PL_ClearArenaPool(arena, 0);
+ PL_ClearArenaPool(arena, 0);
}
- if (doFreeArenaPool) {
- PL_FreeArenaPool(arena);
+ (void)PR_CallOnce(&setupUseFreeListOnce, &SetupUseFreeList);
+ if (useFreeList) {
+ PL_FreeArenaPool(arena);
} else {
- PL_FinishArenaPool(arena);
+ PL_FinishArenaPool(arena);
}
PORT_ZFree(arena, len);
if (lock) {
- PZ_Unlock(lock);
- PZ_DestroyLock(lock);
+ PZ_Unlock(lock);
+ PZ_DestroyLock(lock);
+ }
+}
+
+void
+PORT_DestroyCheapArena(PORTCheapArenaPool *pool)
+{
+ (void)PR_CallOnce(&setupUseFreeListOnce, &SetupUseFreeList);
+ if (useFreeList) {
+ PL_FreeArenaPool(&pool->arena);
+ } else {
+ PL_FinishArenaPool(&pool->arena);
}
}
@@ -344,72 +360,72 @@ PORT_ArenaGrow(PLArenaPool *arena, void *ptr, size_t oldsize, size_t newsize)
{
PORTArenaPool *pool = (PORTArenaPool *)arena;
PORT_Assert(newsize >= oldsize);
-
+
if (newsize > MAX_SIZE) {
- PORT_SetError(SEC_ERROR_NO_MEMORY);
- return NULL;
+ PORT_SetError(SEC_ERROR_NO_MEMORY);
+ return NULL;
}
- 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);
+ 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 ) );
+ PL_ARENA_GROW(ptr, arena, oldsize, (newsize - oldsize));
}
-
- return(ptr);
+
+ return (ptr);
}
void *
PORT_ArenaMark(PLArenaPool *arena)
{
- void * result;
+ void *result;
PORTArenaPool *pool = (PORTArenaPool *)arena;
- if (ARENAPOOL_MAGIC == pool->magic ) {
- PZ_Lock(pool->lock);
+ 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);
+ {
+ 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);
+ PZ_Unlock(pool->lock);
} else {
- /* a "pure" NSPR arena */
- result = PL_ARENA_MARK(arena);
+ /* a "pure" NSPR arena */
+ result = PL_ARENA_MARK(arena);
}
return result;
}
@@ -430,31 +446,31 @@ 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 */
+/* fast path: mark falls in the current arena */
#ifdef PL_MAKE_MEM_UNDEFINED
- PL_MAKE_MEM_UNDEFINED(mark, a->avail - (PRUword)mark);
+ PL_MAKE_MEM_UNDEFINED(mark, a->avail - (PRUword)mark);
#endif
- memset(mark, 0, a->avail - (PRUword)mark);
+ 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) {
+ /* 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) {
#ifdef PL_MAKE_MEM_UNDEFINED
- PL_MAKE_MEM_UNDEFINED(mark, a->avail - (PRUword)mark);
+ PL_MAKE_MEM_UNDEFINED(mark, a->avail - (PRUword)mark);
#endif
- 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(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);
#ifdef PL_MAKE_MEM_UNDEFINED
- PL_MAKE_MEM_UNDEFINED((void *)a->base, a->avail - a->base);
+ PL_MAKE_MEM_UNDEFINED((void *)a->base, a->avail - a->base);
#endif
- memset((void *)a->base, 0, a->avail - a->base);
- }
+ memset((void *)a->base, 0, a->avail - a->base);
+ }
}
}
@@ -462,55 +478,55 @@ static void
port_ArenaRelease(PLArenaPool *arena, void *mark, PRBool zero)
{
PORTArenaPool *pool = (PORTArenaPool *)arena;
- if (ARENAPOOL_MAGIC == pool->magic ) {
- PZ_Lock(pool->lock);
+ if (ARENAPOOL_MAGIC == pool->magic) {
+ PZ_Lock(pool->lock);
#ifdef THREADMARK
- {
- threadmark_mark **pw;
-
- 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 */ ;
- }
-
- *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);
+ {
+ threadmark_mark **pw;
+
+ 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 */;
+ }
+
+ *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);
+ PZ_Unlock(pool->lock);
} else {
- if (zero) {
- port_ArenaZeroAfterMark(arena, mark);
- }
- PL_ARENA_RELEASE(arena, mark);
+ if (zero) {
+ port_ArenaZeroAfterMark(arena, mark);
+ }
+ PL_ARENA_RELEASE(arena, mark);
}
}
@@ -534,50 +550,51 @@ PORT_ArenaUnmark(PLArenaPool *arena, void *mark)
{
#ifdef THREADMARK
PORTArenaPool *pool = (PORTArenaPool *)arena;
- if (ARENAPOOL_MAGIC == pool->magic ) {
- threadmark_mark **pw;
+ if (ARENAPOOL_MAGIC == pool->magic) {
+ threadmark_mark **pw;
- PZ_Lock(pool->lock);
+ 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 */ ;
- }
+ 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;
- }
+ 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 */ ;
- }
+ 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 */;
+ }
- *pw = (threadmark_mark *)NULL;
+ *pw = (threadmark_mark *)NULL;
- if (! pool->first_mark ) {
- pool->marking_thread = (PRThread *)NULL;
- }
+ if (!pool->first_mark) {
+ pool->marking_thread = (PRThread *)NULL;
+ }
- PZ_Unlock(pool->lock);
+ PZ_Unlock(pool->lock);
}
#endif /* THREADMARK */
}
char *
-PORT_ArenaStrdup(PLArenaPool *arena, const char *str) {
- int len = PORT_Strlen(str)+1;
+PORT_ArenaStrdup(PLArenaPool *arena, const char *str)
+{
+ int len = PORT_Strlen(str) + 1;
char *newstr;
- newstr = (char*)PORT_ArenaAlloc(arena,len);
+ newstr = (char *)PORT_ArenaAlloc(arena, len);
if (newstr) {
- PORT_Memcpy(newstr,str,len);
+ PORT_Memcpy(newstr, str, len);
}
return newstr;
}
@@ -595,85 +612,84 @@ PORT_ArenaStrdup(PLArenaPool *arena, const char *str) {
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
+PRBool
PORT_UCS4_UTF8Conversion(PRBool toUnicode, unsigned char *inBuf,
- unsigned int inBufLen, unsigned char *outBuf,
- unsigned int maxOutBufLen, unsigned int *outBufLen)
+ 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);
+ if (!ucs4Utf8ConvertFunc) {
+ return sec_port_ucs4_utf8_conversion_function(toUnicode,
+ inBuf, inBufLen, outBuf, maxOutBufLen, outBufLen);
}
- return (*ucs4Utf8ConvertFunc)(toUnicode, inBuf, inBufLen, outBuf,
- maxOutBufLen, outBufLen);
+ return (*ucs4Utf8ConvertFunc)(toUnicode, inBuf, inBufLen, outBuf,
+ maxOutBufLen, outBufLen);
}
-PRBool
+PRBool
PORT_UCS2_UTF8Conversion(PRBool toUnicode, unsigned char *inBuf,
- unsigned int inBufLen, unsigned char *outBuf,
- unsigned int maxOutBufLen, unsigned int *outBufLen)
+ 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);
+ if (!ucs2Utf8ConvertFunc) {
+ return sec_port_ucs2_utf8_conversion_function(toUnicode,
+ inBuf, inBufLen, outBuf, maxOutBufLen, outBufLen);
}
- return (*ucs2Utf8ConvertFunc)(toUnicode, inBuf, inBufLen, outBuf,
- maxOutBufLen, outBufLen);
+ return (*ucs2Utf8ConvertFunc)(toUnicode, inBuf, inBufLen, outBuf,
+ maxOutBufLen, outBufLen);
}
-PRBool
+PRBool
PORT_ISO88591_UTF8Conversion(const unsigned char *inBuf,
- unsigned int inBufLen, unsigned char *outBuf,
- unsigned int maxOutBufLen, unsigned int *outBufLen)
+ unsigned int inBufLen, unsigned char *outBuf,
+ unsigned int maxOutBufLen, unsigned int *outBufLen)
{
return sec_port_iso88591_utf8_conversion_function(inBuf, inBufLen,
- outBuf, maxOutBufLen, outBufLen);
+ outBuf, maxOutBufLen, outBufLen);
}
-PRBool
+PRBool
PORT_UCS2_ASCIIConversion(PRBool toUnicode, unsigned char *inBuf,
- unsigned int inBufLen, unsigned char *outBuf,
- unsigned int maxOutBufLen, unsigned int *outBufLen,
- PRBool swapBytes)
+ unsigned int inBufLen, unsigned char *outBuf,
+ unsigned int maxOutBufLen, unsigned int *outBufLen,
+ PRBool swapBytes)
{
- if(!ucs2AsciiConvertFunc) {
- return PR_FALSE;
+ if (!ucs2AsciiConvertFunc) {
+ return PR_FALSE;
}
- return (*ucs2AsciiConvertFunc)(toUnicode, inBuf, inBufLen, outBuf,
- maxOutBufLen, outBufLen, swapBytes);
+ 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)
+NSS_PutEnv(const char *envVarName, const char *envValue)
{
SECStatus result = SECSuccess;
- char * encoded;
- int putEnvFailed;
+ char *encoded;
+ int putEnvFailed;
#ifdef _WIN32
- PRBool setOK;
+ PRBool setOK;
setOK = SetEnvironmentVariable(envVarName, envValue);
if (!setOK) {
@@ -703,8 +719,8 @@ NSS_PutEnv(const char * envVarName, const char * envValue)
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;
+ const unsigned char *a = (const unsigned char *)ia;
+ const unsigned char *b = (const unsigned char *)ib;
size_t i;
unsigned char r = 0;
diff --git a/nss/lib/util/secport.h b/nss/lib/util/secport.h
index 7d2f5e0..0f4b08f 100644
--- a/nss/lib/util/secport.h
+++ b/nss/lib/util/secport.h
@@ -17,26 +17,26 @@
* by anyone else
*/
#ifdef _WINDOWS
-# ifndef XP_WIN
-# define XP_WIN
-# endif
+#ifndef XP_WIN
+#define XP_WIN
+#endif
#if defined(_WIN32) || defined(WIN32)
-# ifndef XP_WIN32
-# define XP_WIN32
-# endif
+#ifndef XP_WIN32
+#define XP_WIN32
+#endif
#endif
#endif
#ifdef __BEOS__
-# ifndef XP_BEOS
-# define XP_BEOS
-# endif
+#ifndef XP_BEOS
+#define XP_BEOS
+#endif
#endif
#ifdef unix
-# ifndef XP_UNIX
-# define XP_UNIX
-# endif
+#ifndef XP_UNIX
+#define XP_UNIX
+#endif
#endif
#include <sys/types.h>
@@ -46,7 +46,7 @@
#include <stddef.h>
#include <stdlib.h>
#include "prtypes.h"
-#include "prlog.h" /* for PR_ASSERT */
+#include "prlog.h" /* for PR_ASSERT */
#include "plarena.h"
#include "plstr.h"
@@ -57,27 +57,57 @@
#include "seccomon.h"
#endif
+/*
+ * The PORT_*Arena* function signatures mostly involve PLArenaPool* arguments.
+ * But this is misleading! It's not actually safe to use vanilla PLArenaPools
+ * with them. There are two "subclasses" of PLArenaPool that should be used
+ * instead.
+ *
+ * - PORTArenaPool (defined in secport.c): this "subclass" is always
+ * heap-allocated and uses a (heap-allocated) lock to protect all accesses.
+ * Use PORT_NewArena() and PORT_FreeArena() to create and destroy
+ * PORTArenaPools.
+ *
+ * - PORTCheapArenaPool (defined here): this "subclass" can be stack-allocated
+ * and does not use a lock to protect accesses. This makes it cheaper but
+ * less general. It is best used for arena pools that (a) are hot, (b) have
+ * lifetimes bounded within a single function, and (c) don't need locking.
+ * Use PORT_InitArena() and PORT_DestroyArena() to initialize and finalize
+ * PORTCheapArenaPools.
+ *
+ * All the other PORT_Arena* functions will operate safely with either
+ * subclass.
+ */
+typedef struct PORTCheapArenaPool_str {
+ PLArenaPool arena;
+ PRUint32 magic; /* This is used to distinguish the two subclasses. */
+} PORTCheapArenaPool;
+
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);
+/* These functions are for use with PORTArenaPools. */
extern PLArenaPool *PORT_NewArena(unsigned long chunksize);
+extern void PORT_FreeArena(PLArenaPool *arena, PRBool zero);
+
+/* These functions are for use with PORTCheapArenaPools. */
+extern void PORT_InitCheapArena(PORTCheapArenaPool *arena,
+ unsigned long chunksize);
+extern void PORT_DestroyCheapArena(PORTCheapArenaPool *arena);
+
+/* These functions work with both kinds of arena pool. */
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);
+ 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);
@@ -100,24 +130,24 @@ SEC_END_PROTOS
#else
#define PORT_CheckSuccess(f) (f)
#endif
-#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))
+#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)
+#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
@@ -129,97 +159,91 @@ SEC_END_PROTOS
#define PORT_ErrorToName PR_ErrorToName
-#define PORT_Memcmp memcmp
-#define PORT_Memcpy memcpy
+#define PORT_Memcmp memcmp
+#define PORT_Memcpy memcpy
#ifndef SUNOS4
-#define PORT_Memmove memmove
+#define PORT_Memmove memmove
#else /*SUNOS4*/
-#define PORT_Memmove(s,ct,n) bcopy ((ct), (s), (n))
-#endif/*SUNOS4*/
-#define PORT_Memset memset
+#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_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_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
+#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 *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);
+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);
+ 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);
+ 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);
+ 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);
+ 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
-);
+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
-);
+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
-);
+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_PutEnv(const char *envVarName, const char *envValue);
extern int NSS_SecureMemcmp(const void *a, const void *b, size_t n);
@@ -230,7 +254,7 @@ extern int NSS_SecureMemcmp(const void *a, const void *b, size_t n);
* staticShLibFunc, is required.
*
* existingShLibName:
- * The file name of the shared library that shall be used as the
+ * 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.
*
@@ -240,7 +264,7 @@ extern int NSS_SecureMemcmp(const void *a, const void *b, size_t n);
* newShLibName:
* The simple file name of the new shared library to be loaded.
*
- * We use PR_GetLibraryFilePathname to get the pathname of the 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.
@@ -254,9 +278,9 @@ extern int NSS_SecureMemcmp(const void *a, const void *b, size_t n);
* library, it will then be loaded from the normal system library path.
*/
PRLibrary *
-PORT_LoadLibraryFromOrigin(const char* existingShLibName,
- PRFuncPtr staticShLibFunc,
- const char *newShLibName);
+PORT_LoadLibraryFromOrigin(const char *existingShLibName,
+ PRFuncPtr staticShLibFunc,
+ const char *newShLibName);
SEC_END_PROTOS
diff --git a/nss/lib/util/sectime.c b/nss/lib/util/sectime.c
index 0ce700c..11ee5ff 100644
--- a/nss/lib/util/sectime.c
+++ b/nss/lib/util/sectime.c
@@ -7,21 +7,21 @@
#include "secitem.h"
#include "secerr.h"
-static char *DecodeUTCTime2FormattedAscii (SECItem *utcTimeDER, char *format);
-static char *DecodeGeneralizedTime2FormattedAscii (SECItem *generalizedTimeDER, char *format);
+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"));
+ 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"));
+ return (DecodeUTCTime2FormattedAscii(utctime, "%a %b %d, %Y"));
}
/* convert DER generalized time to ascii time string, only include day,
@@ -29,7 +29,7 @@ DER_UTCDayToAscii(SECItem *utctime)
char *
DER_GeneralizedDayToAscii(SECItem *gentime)
{
- return (DecodeGeneralizedTime2FormattedAscii (gentime, "%a %b %d, %Y"));
+ return (DecodeGeneralizedTime2FormattedAscii(gentime, "%a %b %d, %Y"));
}
/* convert DER generalized or UTC time to ascii time string, only include
@@ -39,98 +39,99 @@ DER_TimeChoiceDayToAscii(SECItem *timechoice)
{
switch (timechoice->type) {
- case siUTCTime:
- return DER_UTCDayToAscii(timechoice);
+ case siUTCTime:
+ return DER_UTCDayToAscii(timechoice);
- case siGeneralizedTime:
- return DER_GeneralizedDayToAscii(timechoice);
+ case siGeneralizedTime:
+ return DER_GeneralizedDayToAscii(timechoice);
- default:
- PORT_Assert(0);
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- return NULL;
+ default:
+ PORT_Assert(0);
+ PORT_SetError(SEC_ERROR_INVALID_ARGS);
+ return NULL;
}
}
char *
CERT_UTCTime2FormattedAscii(PRTime utcTime, char *format)
{
- PRExplodedTime printableTime;
+ 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 )) {
+ if (timeString) {
+ if (!PR_FormatTime(timeString, 256, format, &printableTime)) {
PORT_Free(timeString);
timeString = NULL;
}
}
-
+
return (timeString);
}
-char *CERT_GenTime2FormattedAscii(PRTime genTime, char *format)
+char *
+CERT_GenTime2FormattedAscii(PRTime genTime, char *format)
{
- PRExplodedTime printableTime;
+ 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 )) {
+ 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)
+DecodeUTCTime2FormattedAscii(SECItem *utcTimeDER, char *format)
{
PRTime utcTime;
int rv;
-
+
rv = DER_UTCTimeToTime(&utcTime, utcTimeDER);
if (rv) {
- return(NULL);
+ return (NULL);
}
- return (CERT_UTCTime2FormattedAscii (utcTime, format));
+ 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)
+DecodeGeneralizedTime2FormattedAscii(SECItem *generalizedTimeDER, char *format)
{
PRTime generalizedTime;
int rv;
-
+
rv = DER_GeneralizedTimeToTime(&generalizedTime, generalizedTimeDER);
if (rv) {
- return(NULL);
+ return (NULL);
}
- return (CERT_GeneralizedTime2FormattedAscii (generalizedTime, format));
+ return (CERT_GeneralizedTime2FormattedAscii(generalizedTime, format));
}
-/* decode a SECItem containing either a SEC_ASN1_GENERALIZED_TIME
+/* decode a SECItem containing either a SEC_ASN1_GENERALIZED_TIME
or a SEC_ASN1_UTC_TIME */
-SECStatus DER_DecodeTimeChoice(PRTime* output, const SECItem* input)
+SECStatus
+DER_DecodeTimeChoice(PRTime *output, const SECItem *input)
{
switch (input->type) {
case siGeneralizedTime:
@@ -149,7 +150,8 @@ 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 */
-SECStatus DER_EncodeTimeChoice(PLArenaPool* arena, SECItem* output, PRTime input)
+SECStatus
+DER_EncodeTimeChoice(PLArenaPool *arena, SECItem *output, PRTime input)
{
SECStatus rv;
diff --git a/nss/lib/util/templates.c b/nss/lib/util/templates.c
index e5f1ebc..6118aee 100644
--- a/nss/lib/util/templates.c
+++ b/nss/lib/util/templates.c
@@ -20,12 +20,12 @@
const SEC_ASN1Template SECOID_AlgorithmIDTemplate[] = {
{ SEC_ASN1_SEQUENCE,
- 0, NULL, sizeof(SECAlgorithmID) },
+ 0, NULL, sizeof(SECAlgorithmID) },
{ SEC_ASN1_OBJECT_ID,
- offsetof(SECAlgorithmID,algorithm), },
+ offsetof(SECAlgorithmID, algorithm) },
{ SEC_ASN1_OPTIONAL | SEC_ASN1_ANY,
- offsetof(SECAlgorithmID,parameters), },
- { 0, }
+ offsetof(SECAlgorithmID, parameters) },
+ { 0 }
};
SEC_ASN1_CHOOSER_IMPLEMENT(SECOID_AlgorithmIDTemplate)
@@ -55,7 +55,7 @@ const SEC_ASN1Template SEC_BooleanTemplate[] = {
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_GENERALIZED_TIME | SEC_ASN1_MAY_STREAM, 0, NULL, sizeof(SECItem) }
};
SEC_ASN1_CHOOSER_IMPLEMENT(SEC_GeneralizedTimeTemplate)
@@ -115,7 +115,7 @@ const SEC_ASN1Template SEC_UTCTimeTemplate[] = {
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_UTF8_STRING | SEC_ASN1_MAY_STREAM, 0, NULL, sizeof(SECItem) }
};
SEC_ASN1_CHOOSER_IMPLEMENT(SEC_UTF8StringTemplate)
@@ -124,12 +124,12 @@ SEC_ASN1_CHOOSER_IMPLEMENT(SEC_UTF8StringTemplate)
/* XXX Changed from static -- need to change name? */
const SEC_ASN1Template sgn_DigestInfoTemplate[] = {
{ SEC_ASN1_SEQUENCE,
- 0, NULL, sizeof(SGNDigestInfo) },
+ 0, NULL, sizeof(SGNDigestInfo) },
{ SEC_ASN1_INLINE,
- offsetof(SGNDigestInfo,digestAlgorithm),
- SECOID_AlgorithmIDTemplate },
+ offsetof(SGNDigestInfo, digestAlgorithm),
+ SECOID_AlgorithmIDTemplate },
{ SEC_ASN1_OCTET_STRING,
- offsetof(SGNDigestInfo,digest) },
+ offsetof(SGNDigestInfo, digest) },
{ 0 }
};
diff --git a/nss/lib/util/utf8.c b/nss/lib/util/utf8.c
index 2895dc1..7bdd714 100644
--- a/nss/lib/util/utf8.c
+++ b/nss/lib/util/utf8.c
@@ -5,12 +5,6 @@
#include "seccomon.h"
#include "secport.h"
-#ifdef TEST_UTF8
-#include <assert.h>
-#undef PORT_Assert
-#define PORT_Assert assert
-#endif
-
/*
* From RFC 2044:
*
@@ -21,7 +15,7 @@
* 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
@@ -85,1712 +79,367 @@
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;
+ 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;
}
- 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;
+ while (bytes_left--) {
+ if (i >= inBufLen || (inBuf[i] & 0xC0) != 0x80)
+ return BAD_UTF8;
+ result = (result << 6) | (inBuf[i++] & 0x3F);
}
- if( len > maxOutBufLen ) {
- *outBufLen = len;
- return PR_FALSE;
+ /* Check for overlong sequences, surrogates, and outside unicode range */
+ if (result < min_value || (result & 0xFFFFF800) == 0xD800 || result > 0x10FFFF) {
+ return BAD_UTF8;
}
- 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;
- }
+ *index = i;
+ return result;
}
PRBool
-sec_port_ucs2_utf8_conversion_function
-(
- PRBool toUnicode,
- unsigned char *inBuf,
- unsigned int inBufLen,
- unsigned char *outBuf,
- unsigned int maxOutBufLen,
- unsigned int *outBufLen
-)
+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;
- 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;
+ 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;
}
- }
- 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;
+ if (len > maxOutBufLen) {
+ *outBufLen = len;
+ return PR_FALSE;
+ }
- PORT_Assert((unsigned int *)NULL != outBufLen);
+ len = 0;
- for( i = 0; i < inBufLen; i++) {
- if( (inBuf[i] & 0x80) == 0x00 ) len += 1;
- else len += 2;
- }
+ for (i = 0; i < inBufLen;) {
+ PRUint32 ucs4 = sec_port_read_utf8(&i, inBuf, inBufLen);
- if( len > maxOutBufLen ) {
- *outBufLen = len;
- return PR_FALSE;
- }
+ if (ucs4 == BAD_UTF8)
+ return PR_FALSE;
- len = 0;
+ 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;
- for( i = 0; i < inBufLen; i++) {
- if( (inBuf[i] & 0x80) == 0x00 ) {
- /* 00-7F -> 0xxxxxxx */
- /* 0abcdefg -> 0abcdefg */
+ len += 4;
+ }
- outBuf[len] = inBuf[i];
- len += 1;
+ *outBufLen = len;
+ return PR_TRUE;
} 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;
-};
+ unsigned int i, len = 0;
+ PORT_Assert((inBufLen % 4) == 0);
+ if ((inBufLen % 4) != 0) {
+ *outBufLen = 0;
+ return PR_FALSE;
+ }
-/*
- * UCS-2 vectors
- */
+ 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;
+ }
-struct ucs2 {
- PRUint16 c;
- char *utf8;
-};
+ if (len > maxOutBufLen) {
+ *outBufLen = len;
+ return PR_FALSE;
+ }
-/*
- * UTF-16 vectors
- */
+ len = 0;
-struct utf16 {
- PRUint32 c;
- PRUint16 w[2];
-};
+ 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);
-/*
- * UCS-4 vectors
- */
+ len += 4;
+ } else if (inBuf[i + L_2] >= 0x08) {
+ /* 0000 0800-0000 FFFF -> 1110xxxx 10xxxxxx 10xxxxxx */
+ /* 00000000 00000000 abcdefgh ijklmnop ->
+ 1110abcd 10efghij 10klmnop */
-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" },
-};
+ 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);
-/*
- * UCS-2 vectors
- */
+ 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 */
-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" }
-
-};
+ 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);
-/*
- * UTF-16 vectors
- */
+ len += 2;
+ } else {
+ /* 0000 0000-0000 007F -> 0xxxxxx */
+ /* 00000000 00000000 00000000 0abcdefg ->
+ 0abcdefg */
-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);
-}
+ outBuf[len + 0] = (inBuf[i + L_3] & 0x7F);
-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;
- }
+ len += 1;
+ }
+ }
- 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;
+ *outBufLen = len;
+ return PR_TRUE;
}
- }
-
- return rv;
}
-static PRBool
-test_ucs2_chars
-(
- void
-)
+PRBool
+sec_port_ucs2_utf8_conversion_function(
+ PRBool toUnicode,
+ unsigned char *inBuf,
+ unsigned int inBufLen,
+ unsigned char *outBuf,
+ unsigned int maxOutBufLen,
+ unsigned int *outBufLen)
{
- 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;
- }
+ 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 >= 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;
- }
+ if (len > maxOutBufLen) {
+ *outBufLen = len;
+ return PR_FALSE;
+ }
- result = sec_port_ucs2_utf8_conversion_function(PR_TRUE,
- utf8, len, (unsigned char *)&back, sizeof(back), &len);
+ 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;
+ }
+ }
- if( !result ) {
- dump_utf8("Failed to convert UTF-8", utf8, "to UCS-2\n");
- rv = PR_FALSE;
- continue;
- }
+ *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;
+ }
- 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;
- }
- }
+ for (i = 0; i < inBufLen; i += 2) {
+ if ((inBuf[i + H_0] == 0x00) && ((inBuf[i + H_1] & 0x80) == 0x00))
+ len += 1;
+ else if (inBuf[i + H_0] < 0x08)
+ len += 2;
+ else if (((inBuf[i + H_0] & 0xFC) == 0xD8)) {
+ if (((inBufLen - i) > 2) && ((inBuf[i + 2 + H_0] & 0xFC) == 0xDC)) {
+ i += 2;
+ len += 4;
+ } else {
+ return PR_FALSE;
+ }
+ } else if ((inBuf[i + H_0] & 0xFC) == 0xDC) {
+ return PR_FALSE;
+ } else {
+ len += 3;
+ }
+ }
- return rv;
-}
+ if (len > maxOutBufLen) {
+ *outBufLen = len;
+ return PR_FALSE;
+ }
-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;
- }
+ len = 0;
- result = sec_port_ucs4_utf8_conversion_function(PR_TRUE,
- utf8, len, (unsigned char *)&back32, sizeof(back32), &len);
+ 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 */
- 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;
- }
+ outBuf[len] = inBuf[i + H_1] & 0x7F;
- utf8[len] = '\0'; /* null-terminate for printing */
+ len += 1;
+ } else if (inBuf[i + H_0] < 0x08) {
+ /* 0080-07FF -> 110xxxxx 10xxxxxx */
+ /* 00000abc defghijk -> 110abcde 10fghijk */
- if( !result ) {
- dump_utf8("Failed to convert UTF-8", utf8, "to UCS-4 (utf-16 test)\n");
- rv = PR_FALSE;
- continue;
- }
+ 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);
- 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;
- }
+ len += 2;
+ } else if ((inBuf[i + H_0] & 0xFC) == 0xD8) {
+ int abcde, BCDE;
- (void)memset(utf8, 0, sizeof(utf8));
- back[0] = back[1] = 0;
+ PORT_Assert(((inBufLen - i) > 2) && ((inBuf[i + 2 + H_0] & 0xFC) == 0xDC));
- result = sec_port_ucs4_utf8_conversion_function(PR_FALSE,
- (unsigned char *)&e->c, sizeof(e->c), utf8, sizeof(utf8), &len);
+ /* D800-DBFF DC00-DFFF -> 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx */
+ /* 110110BC DEfghijk 110111lm nopqrstu ->
+ { Let abcde = BCDE + 1 }
+ 11110abc 10defghi 10jklmno 10pqrstu */
- 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;
- }
+ BCDE = ((inBuf[i + H_0] & 0x03) << 2) | ((inBuf[i + H_1] & 0xC0) >> 6);
+ abcde = BCDE + 1;
- result = sec_port_ucs2_utf8_conversion_function(PR_TRUE,
- utf8, len, (unsigned char *)&back[0], sizeof(back), &len);
+ 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);
- 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;
- }
+ i += 2;
+ len += 4;
+ } else {
+ /* 0800-FFFF -> 1110xxxx 10xxxxxx 10xxxxxx */
+ /* abcdefgh ijklmnop -> 1110abcd 10efghij 10klmnop */
- utf8[len] = '\0'; /* null-terminate for printing */
+ 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);
- if( !result ) {
- dump_utf8("Failed to convert UTF-8", utf8, "to UTF-16\n");
- rv = PR_FALSE;
- continue;
- }
+ len += 3;
+ }
+ }
- 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;
+ *outBufLen = len;
+ return PR_TRUE;
}
- }
-
- return rv;
}
-static PRBool
-test_utf8_bad_chars
-(
- void
-)
+PRBool
+sec_port_iso88591_utf8_conversion_function(
+ const unsigned char *inBuf,
+ unsigned int inBufLen,
+ unsigned char *outBuf,
+ unsigned int maxOutBufLen,
+ unsigned int *outBufLen)
{
- 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;
- }
-
- }
+ unsigned int i, len = 0;
- return rv;
-}
+ PORT_Assert((unsigned int *)NULL != outBufLen);
-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;
+ for (i = 0; i < inBufLen; i++) {
+ if ((inBuf[i] & 0x80) == 0x00)
+ len += 1;
+ else
+ len += 2;
}
- 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;
+ if (len > maxOutBufLen) {
+ *outBufLen = len;
+ return PR_FALSE;
}
- }
+ len = 0;
- return rv;
-}
+ for (i = 0; i < inBufLen; i++) {
+ if ((inBuf[i] & 0x80) == 0x00) {
+ /* 00-7F -> 0xxxxxxx */
+ /* 0abcdefg -> 0abcdefg */
-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;
-}
+ outBuf[len] = inBuf[i];
+ len += 1;
+ } else {
+ /* 80-FF <- 110xxxxx 10xxxxxx */
+ /* 00000000 abcdefgh -> 110000ab 10cdefgh */
-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;
-}
+ outBuf[len + 0] = 0xC0 | ((inBuf[i] & 0xC0) >> 6);
+ outBuf[len + 1] = 0x80 | ((inBuf[i] & 0x3F) >> 0);
-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;
-}
+ len += 2;
+ }
+ }
-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;
- }
+ *outBufLen = len;
+ return PR_TRUE;
}
-
-#endif /* TEST_UTF8 */
diff --git a/nss/lib/util/util.gyp b/nss/lib/util/util.gyp
new file mode 100644
index 0000000..9f3a74b
--- /dev/null
+++ b/nss/lib/util/util.gyp
@@ -0,0 +1,59 @@
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+{
+ 'includes': [
+ '../../coreconf/config.gypi'
+ ],
+ 'targets': [
+ {
+ 'target_name': 'nssutil',
+ 'type': 'static_library',
+ 'sources': [
+ 'derdec.c',
+ 'derenc.c',
+ 'dersubr.c',
+ 'dertime.c',
+ 'errstrs.c',
+ 'nssb64d.c',
+ 'nssb64e.c',
+ 'nssilock.c',
+ 'nssrwlk.c',
+ 'oidstring.c',
+ 'pkcs1sig.c',
+ 'portreg.c',
+ 'quickder.c',
+ 'secalgid.c',
+ 'secasn1d.c',
+ 'secasn1e.c',
+ 'secasn1u.c',
+ 'secdig.c',
+ 'secitem.c',
+ 'secload.c',
+ 'secoid.c',
+ 'secport.c',
+ 'sectime.c',
+ 'templates.c',
+ 'utf8.c',
+ 'utilmod.c',
+ 'utilpars.c'
+ ],
+ 'dependencies': [
+ '<(DEPTH)/exports.gyp:nss_exports'
+ ]
+ },
+ {
+ 'target_name': 'nssutil3',
+ 'type': 'shared_library',
+ 'dependencies': [
+ 'nssutil'
+ ],
+ 'variables': {
+ 'mapfile': 'nssutil.def'
+ }
+ }
+ ],
+ 'variables': {
+ 'module': 'nss'
+ }
+} \ No newline at end of file
diff --git a/nss/lib/util/utilmod.c b/nss/lib/util/utilmod.c
index 4be99ad..e056806 100644
--- a/nss/lib/util/utilmod.c
+++ b/nss/lib/util/utilmod.c
@@ -1,28 +1,28 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.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
+ * 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
+ * represents the underlying physical database. These objects are not
* reference counted, and are 'owned' by their respective SFTKDBHandles.
*/
-#include "prprf.h"
+#include "prprf.h"
#include "prsystem.h"
#include "secport.h"
-#include "utilpars.h"
+#include "utilpars.h"
#include "secerr.h"
-#if defined (_WIN32)
+#if defined(_WIN32)
#include <io.h>
#endif
#ifdef XP_UNIX
@@ -33,12 +33,12 @@
#include <sys/stat.h>
#include <fcntl.h>
-#if defined (_WIN32)
+#if defined(_WIN32)
#define os_open _open
#define os_fdopen _fdopen
#define os_stat _stat
-#define os_truncate_open_flags _O_CREAT|_O_RDWR|_O_TRUNC
-#define os_append_open_flags _O_CREAT|_O_RDWR|_O_APPEND
+#define os_truncate_open_flags _O_CREAT | _O_RDWR | _O_TRUNC
+#define os_append_open_flags _O_CREAT | _O_RDWR | _O_APPEND
#define os_open_permissions_type int
#define os_open_permissions_default _S_IREAD | _S_IWRITE
#define os_stat_type struct _stat
@@ -46,8 +46,8 @@
#define os_open open
#define os_fdopen fdopen
#define os_stat stat
-#define os_truncate_open_flags O_CREAT|O_RDWR|O_TRUNC
-#define os_append_open_flags O_CREAT|O_RDWR|O_APPEND
+#define os_truncate_open_flags O_CREAT | O_RDWR | O_TRUNC
+#define os_append_open_flags O_CREAT | O_RDWR | O_APPEND
#define os_open_permissions_type mode_t
#define os_open_permissions_default 0600
#define os_stat_type struct stat
@@ -67,15 +67,14 @@
* 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 destination string. If it's null, we
+ * The first parameter is the destination string. If it's null, we
* allocate memory for it. If it's not, we reallocate memory
* so the the concanenated string fits.
*/
@@ -87,10 +86,10 @@ nssutil_DupnCat(char *baseString, const char *str, int str_len)
char *newString;
len += str_len;
- newString = (char *) PORT_Realloc(baseString,len);
+ newString = (char *)PORT_Realloc(baseString, len);
if (newString == NULL) {
- PORT_Free(baseString);
- return NULL;
+ PORT_Free(baseString);
+ return NULL;
}
PORT_Memcpy(&newString[baseStringLen], str, str_len);
newString[len - 1] = 0;
@@ -111,11 +110,11 @@ static SECStatus
nssutil_releaseSpecList(char **moduleSpecList)
{
if (moduleSpecList) {
- char **index;
- for(index = moduleSpecList; *index; index++) {
- PORT_Free(*index);
- }
- PORT_Free(moduleSpecList);
+ char **index;
+ for (index = moduleSpecList; *index; index++) {
+ PORT_Free(*index);
+ }
+ PORT_Free(moduleSpecList);
}
return SECSuccess;
}
@@ -128,35 +127,35 @@ nssutil_growList(char ***pModuleList, int *useCount, int last)
*useCount += SECMOD_STEP;
newModuleList = (char **)PORT_Realloc(*pModuleList,
- *useCount*sizeof(char *));
+ *useCount * sizeof(char *));
if (newModuleList == NULL) {
- return SECFailure;
+ return SECFailure;
}
- PORT_Memset(&newModuleList[last],0, sizeof(char *)*SECMOD_STEP);
+ PORT_Memset(&newModuleList[last], 0, sizeof(char *) * SECMOD_STEP);
*pModuleList = newModuleList;
return SECSuccess;
}
-static
-char *_NSSUTIL_GetOldSecmodName(const char *dbname,const char *filename)
+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);
+ 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,'\\');
+ /* 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);
+ *sep = 0;
+ file = PR_smprintf("%s" NSSUTIL_PATH_SEPARATOR "%s", dirPath, filename);
} else {
- file = PR_smprintf("%s", filename);
+ file = PR_smprintf("%s", filename);
}
PORT_Free(dirPath);
return file;
@@ -165,9 +164,10 @@ char *_NSSUTIL_GetOldSecmodName(const char *dbname,const char *filename)
static SECStatus nssutil_AddSecmodDBEntry(const char *appName,
const char *filename,
const char *dbname,
- char *module, PRBool rw);
+ const char *module, PRBool rw);
-enum lfopen_mode { lfopen_truncate, lfopen_append };
+enum lfopen_mode { lfopen_truncate,
+ lfopen_append };
FILE *
lfopen(const char *name, enum lfopen_mode om, os_open_permissions_type open_perms)
@@ -179,11 +179,11 @@ lfopen(const char *name, enum lfopen_mode om, os_open_permissions_type open_perm
(om == lfopen_truncate) ? os_truncate_open_flags : os_append_open_flags,
open_perms);
if (fd < 0) {
- return NULL;
+ return NULL;
}
file = os_fdopen(fd, (om == lfopen_truncate) ? "w+" : "a+");
if (!file) {
- close(fd);
+ close(fd);
}
/* file inherits fd */
return file;
@@ -195,9 +195,9 @@ lfopen(const char *name, enum lfopen_mode om, os_open_permissions_type open_perm
* 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)
+nssutil_ReadSecmodDB(const char *appName,
+ const char *filename, const char *dbname,
+ char *params, PRBool rw)
{
FILE *fd = NULL;
char **moduleList = NULL;
@@ -207,218 +207,236 @@ nssutil_ReadSecmodDB(const char *appName,
PRBool internal = PR_FALSE;
PRBool skipParams = PR_FALSE;
char *moduleString = NULL;
- char *paramsValue=NULL;
+ char *paramsValue = NULL;
PRBool failed = PR_TRUE;
- moduleList = (char **) PORT_ZAlloc(useCount*sizeof(char **));
- if (moduleList == NULL) return NULL;
+ moduleList = (char **)PORT_ZAlloc(useCount * sizeof(char *));
+ if (moduleList == NULL)
+ return NULL;
if (dbname == NULL) {
- goto return_default;
+ goto return_default;
}
/* do we really want to use streams here */
fd = fopen(dbname, "r");
- if (fd == NULL) goto done;
+ 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;
- }
+ 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;
+ 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;
+ char *olddbname = _NSSUTIL_GetOldSecmodName(dbname, filename);
+ PRStatus status;
- /* couldn't get the old name */
- if (!olddbname) {
- goto bail;
- }
+ /* 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_ZFree(moduleList, useCount*sizeof(char **));
- PORT_SetError(SEC_ERROR_LEGACY_DATABASE);
- return NULL;
- }
+ /* old one exists */
+ status = PR_Access(olddbname, PR_ACCESS_EXISTS);
+ if (status == PR_SUCCESS) {
+ PR_smprintf_free(olddbname);
+ PORT_ZFree(moduleList, useCount * sizeof(char *));
+ PORT_SetError(SEC_ERROR_LEGACY_DATABASE);
+ return NULL;
+ }
-bail:
- if (olddbname) {
- PR_smprintf_free(olddbname);
- }
+ 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;
+ 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;
@@ -428,40 +446,39 @@ loser:
*/
/* deal with trust cert db here */
if (moduleString) {
- PORT_Free(moduleString);
- moduleString = NULL;
+ PORT_Free(moduleString);
+ moduleString = NULL;
}
if (paramsValue) {
- PORT_Free(paramsValue);
- paramsValue = NULL;
+ PORT_Free(paramsValue);
+ paramsValue = NULL;
}
if (failed || (moduleList[0] == NULL)) {
- /* This is wrong! FIXME */
- nssutil_releaseSpecList(moduleList);
- moduleList = NULL;
- failed = PR_TRUE;
+ /* This is wrong! FIXME */
+ nssutil_releaseSpecList(moduleList);
+ moduleList = NULL;
+ failed = PR_TRUE;
}
if (fd != NULL) {
- fclose(fd);
+ fclose(fd);
} else if (!failed && rw) {
- /* update our internal module */
- nssutil_AddSecmodDBEntry(appName, filename, dbname, moduleList[0], rw);
+ /* update our internal module */
+ nssutil_AddSecmodDBEntry(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)
+nssutil_ReleaseSecmodDBData(const char *appName,
+ const char *filename, const char *dbname,
+ char **moduleSpecList, PRBool rw)
{
if (moduleSpecList) {
- nssutil_releaseSpecList(moduleSpecList);
+ nssutil_releaseSpecList(moduleSpecList);
}
return SECSuccess;
}
-
/*
* Delete a module from the Data Base
*/
@@ -469,7 +486,7 @@ static SECStatus
nssutil_DeleteSecmodDBEntry(const char *appName,
const char *filename,
const char *dbname,
- char *args,
+ const char *args,
PRBool rw)
{
/* SHDB_FIXME implement */
@@ -487,44 +504,46 @@ nssutil_DeleteSecmodDBEntry(const char *appName,
PRBool found = PR_FALSE;
if (dbname == NULL) {
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- return SECFailure;
+ PORT_SetError(SEC_ERROR_INVALID_ARGS);
+ return SECFailure;
}
if (!rw) {
- PORT_SetError(SEC_ERROR_READ_ONLY);
- return SECFailure;
+ PORT_SetError(SEC_ERROR_READ_ONLY);
+ return SECFailure;
}
dbname2 = PORT_Strdup(dbname);
- if (dbname2 == NULL) goto loser;
- dbname2[strlen(dbname)-1]++;
+ if (dbname2 == NULL)
+ goto loser;
+ dbname2[strlen(dbname) - 1]++;
/* get the permissions of the existing file, or use the default */
if (!os_stat(dbname, &stat_existing)) {
- file_mode = stat_existing.st_mode;
+ file_mode = stat_existing.st_mode;
} else {
- file_mode = os_open_permissions_default;
+ file_mode = os_open_permissions_default;
}
/* do we really want to use streams here */
fd = fopen(dbname, "r");
- if (fd == NULL) goto loser;
+ if (fd == NULL)
+ goto loser;
fd2 = lfopen(dbname2, lfopen_truncate, file_mode);
- if (fd2 == NULL) goto loser;
+ if (fd2 == NULL)
+ goto loser;
- name = NSSUTIL_ArgGetParamValue("name",args);
+ name = NSSUTIL_ArgGetParamValue("name", args);
if (name) {
- name_len = PORT_Strlen(name);
+ name_len = PORT_Strlen(name);
}
- lib = NSSUTIL_ArgGetParamValue("library",args);
+ lib = NSSUTIL_ArgGetParamValue("library", args);
if (lib) {
- lib_len = PORT_Strlen(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.
@@ -532,55 +551,55 @@ nssutil_DeleteSecmodDBEntry(const char *appName,
/* 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;
- }
+ 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);
+ /* rename dbname2 to dbname */
+ PR_Delete(dbname);
+ PR_Rename(dbname2, dbname);
} else {
- PR_Delete(dbname2);
+ PR_Delete(dbname2);
}
PORT_Free(dbname2);
PORT_Free(lib);
@@ -590,14 +609,14 @@ nssutil_DeleteSecmodDBEntry(const char *appName,
loser:
if (fd != NULL) {
- fclose(fd);
+ fclose(fd);
}
if (fd2 != NULL) {
- fclose(fd2);
+ fclose(fd2);
}
if (dbname2) {
- PR_Delete(dbname2);
- PORT_Free(dbname2);
+ PR_Delete(dbname2);
+ PORT_Free(dbname2);
}
PORT_Free(lib);
PORT_Free(name);
@@ -605,12 +624,12 @@ loser:
}
/*
- * Add a module to the Data base
+ * Add a module to the Data base
*/
static SECStatus
nssutil_AddSecmodDBEntry(const char *appName,
- const char *filename, const char *dbname,
- char *module, PRBool rw)
+ const char *filename, const char *dbname,
+ const char *module, PRBool rw)
{
os_stat_type stat_existing;
os_open_permissions_type file_mode;
@@ -619,63 +638,67 @@ nssutil_AddSecmodDBEntry(const char *appName,
PRBool libFound = PR_FALSE;
if (dbname == NULL) {
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- return SECFailure;
+ 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;
+ PORT_SetError(SEC_ERROR_READ_ONLY);
+ return SECFailure;
}
/* remove the previous version if it exists */
- (void) nssutil_DeleteSecmodDBEntry(appName, filename, dbname, module, rw);
+ (void)nssutil_DeleteSecmodDBEntry(appName, filename, dbname, module, rw);
/* get the permissions of the existing file, or use the default */
if (!os_stat(dbname, &stat_existing)) {
- file_mode = stat_existing.st_mode;
+ file_mode = stat_existing.st_mode;
} else {
- file_mode = os_open_permissions_default;
+ file_mode = os_open_permissions_default;
}
fd = lfopen(dbname, lfopen_append, file_mode);
if (fd == NULL) {
- return SECFailure;
+ 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);
+ 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;
+ 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;
@@ -685,54 +708,58 @@ loser:
fclose(fd);
return SECFailure;
}
-
char **
-NSSUTIL_DoModuleDBFunction(unsigned long function,char *parameters, void *args)
+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";
+ 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;
+ &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_AddSecmodDBEntry(appName, filename,
- secmod, (char *)args, rw)
- == SECSuccess) ? &success: NULL;
- break;
- case SECMOD_MODULE_DB_FUNCTION_DEL:
- rvstr = (nssutil_DeleteSecmodDBEntry(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;
+ case SECMOD_MODULE_DB_FUNCTION_FIND:
+ rvstr = nssutil_ReadSecmodDB(appName, filename,
+ secmod, (char *)parameters, rw);
+ break;
+ case SECMOD_MODULE_DB_FUNCTION_ADD:
+ rvstr = (nssutil_AddSecmodDBEntry(appName, filename,
+ secmod, (char *)args, rw) == SECSuccess)
+ ? &success
+ : NULL;
+ break;
+ case SECMOD_MODULE_DB_FUNCTION_DEL:
+ rvstr = (nssutil_DeleteSecmodDBEntry(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);
+ if (secmod)
+ PR_smprintf_free(secmod);
+ if (appName)
+ PORT_Free(appName);
+ if (filename)
+ PORT_Free(filename);
return rvstr;
}
diff --git a/nss/lib/util/utilmodt.h b/nss/lib/util/utilmodt.h
index 6adc5fb..e1555f3 100644
--- a/nss/lib/util/utilmodt.h
+++ b/nss/lib/util/utilmodt.h
@@ -9,35 +9,35 @@
* 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 /* also for SHA224 */
-#define SECMOD_SHA512_FLAG 0x00008000L /* also for SHA384 */
-#define SECMOD_CAMELLIA_FLAG 0x00010000L /* = PUBLIC_MECH_CAMELLIA_FLAG */
-#define SECMOD_SEED_FLAG 0x00020000L
-#define SECMOD_ECC_FLAG 0x00040000L
+#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 /* also for SHA224 */
+#define SECMOD_SHA512_FLAG 0x00008000L /* also for SHA384 */
+#define SECMOD_CAMELLIA_FLAG 0x00010000L /* = PUBLIC_MECH_CAMELLIA_FLAG */
+#define SECMOD_SEED_FLAG 0x00020000L
+#define SECMOD_ECC_FLAG 0x00040000L
/* reserved bit for future, do not use */
-#define SECMOD_RESERVED_FLAG 0X08000000L
-#define SECMOD_FRIENDLY_FLAG 0x10000000L
-#define SECMOD_RANDOM_FLAG 0x80000000L
+#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
+#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
+#define SECMOD_DISABLE_FLAG PK11_DISABLE_FLAG
#endif /* _UTILMODT_H_ */
diff --git a/nss/lib/util/utilpars.c b/nss/lib/util/utilpars.c
index 278f9c4..7116d26 100644
--- a/nss/lib/util/utilpars.c
+++ b/nss/lib/util/utilpars.c
@@ -1,13 +1,13 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.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 "prprf.h"
#include "prenv.h"
#include "utilpars.h"
#include "utilmodt.h"
@@ -15,72 +15,94 @@
/*
* return the expected matching quote value for the one specified
*/
-PRBool NSSUTIL_ArgGetPair(char c) {
+PRBool
+NSSUTIL_ArgGetPair(char c)
+{
switch (c) {
- case '\'': return c;
- case '\"': return c;
- case '<': return '>';
- case '{': return '}';
- case '[': return ']';
- case '(': return ')';
- default: break;
+ 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_ArgIsBlank(char c)
+{
+ return isspace((unsigned char)c);
}
-PRBool NSSUTIL_ArgIsEscape(char c) {
+PRBool
+NSSUTIL_ArgIsEscape(char c)
+{
return c == '\\';
}
-PRBool NSSUTIL_ArgIsQuote(char 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;
+ 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;
+const char *
+NSSUTIL_ArgStrip(const 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) {
+const char *
+NSSUTIL_ArgFindEnd(const char *string)
+{
char endChar = ' ';
PRBool lastEscape = PR_FALSE;
if (NSSUTIL_ArgIsQuote(*string)) {
- endChar = NSSUTIL_ArgGetPair(*string);
- 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;
- }
+ 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;
@@ -91,34 +113,36 @@ NSSUTIL_ArgFindEnd(char *string) {
* the equal sign.
*/
char *
-NSSUTIL_ArgFetchValue(char *string, int *pcount)
+NSSUTIL_ArgFetchValue(const char *string, int *pcount)
{
- char *end = NSSUTIL_ArgFindEnd(string);
+ const char *end = NSSUTIL_ArgFindEnd(string);
char *retString, *copyString;
PRBool lastEscape = PR_FALSE;
int len;
len = end - string;
if (len == 0) {
- *pcount = 0;
- return NULL;
+ *pcount = 0;
+ return NULL;
}
- copyString = retString = (char *)PORT_Alloc(len+1);
+ copyString = retString = (char *)PORT_Alloc(len + 1);
- if (*end) len++;
+ if (*end)
+ len++;
*pcount = len;
- if (retString == NULL) return NULL;
-
+ if (retString == NULL)
+ return NULL;
- if (NSSUTIL_ArgIsQuote(*string)) string++;
+ if (NSSUTIL_ArgIsQuote(*string))
+ string++;
for (; string < end; string++) {
- if (NSSUTIL_ArgIsEscape(*string) && !lastEscape) {
- lastEscape = PR_TRUE;
- continue;
- }
- lastEscape = PR_FALSE;
- *copyString++ = *string;
+ if (NSSUTIL_ArgIsEscape(*string) && !lastEscape) {
+ lastEscape = PR_TRUE;
+ continue;
+ }
+ lastEscape = PR_FALSE;
+ *copyString++ = *string;
}
*copyString = 0;
return retString;
@@ -127,62 +151,68 @@ NSSUTIL_ArgFetchValue(char *string, int *pcount)
/*
* point to the next parameter in string
*/
-char *
-NSSUTIL_ArgSkipParameter(char *string)
+const char *
+NSSUTIL_ArgSkipParameter(const 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;
+ const 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)
+NSSUTIL_ArgGetParamValue(const char *paramName, const char *parameters)
{
char searchValue[256];
int paramLen = strlen(paramName);
char *returnValue = NULL;
int next;
- if ((parameters == NULL) || (*parameters == 0)) return NULL;
+ if ((parameters == NULL) || (*parameters == 0))
+ return NULL;
- PORT_Assert(paramLen+2 < sizeof(searchValue));
+ PORT_Assert(paramLen + 2 < sizeof(searchValue));
- PORT_Strcpy(searchValue,paramName);
- PORT_Strcat(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;
+ 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)
+ */
+const char *
+NSSUTIL_ArgNextFlag(const char *flags)
{
- for (; *flags ; flags++) {
- if (*flags == ',') {
- flags++;
- break;
- }
+ for (; *flags; flags++) {
+ if (*flags == ',') {
+ flags++;
+ break;
+ }
}
return flags;
}
@@ -191,20 +221,22 @@ NSSUTIL_ArgNextFlag(char *flags)
* return true if the flag is set in the label parameter.
*/
PRBool
-NSSUTIL_ArgHasFlag(char *label, char *flag, char *parameters)
+NSSUTIL_ArgHasFlag(const char *label, const char *flag, const char *parameters)
{
- char *flags,*index;
+ char *flags;
+ const char *index;
int len = strlen(flag);
PRBool found = PR_FALSE;
- flags = NSSUTIL_ArgGetParamValue(label,parameters);
- if (flags == NULL) return 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;
- }
+ for (index = flags; *index; index = NSSUTIL_ArgNextFlag(index)) {
+ if (PORT_Strncasecmp(index, flag, len) == 0) {
+ found = PR_TRUE;
+ break;
+ }
}
PORT_Free(flags);
return found;
@@ -214,48 +246,49 @@ NSSUTIL_ArgHasFlag(char *label, char *flag, char *parameters)
* decode a number. handle octal (leading '0'), hex (leading '0x') or decimal
*/
long
-NSSUTIL_ArgDecodeNumber(char *num)
+NSSUTIL_ArgDecodeNumber(const char *num)
{
- int radix = 10;
+ int radix = 10;
unsigned long value = 0;
long retValue = 0;
int sign = 1;
int digit;
- if (num == NULL) return retValue;
+ if (num == NULL)
+ return retValue;
num = NSSUTIL_ArgStrip(num);
if (*num == '-') {
- sign = -1;
- 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;
+ 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;
}
@@ -264,26 +297,30 @@ NSSUTIL_ArgDecodeNumber(char *num)
* value before the equal size.
*/
char *
-NSSUTIL_ArgGetLabel(char *inString, int *next)
+NSSUTIL_ArgGetLabel(const char *inString, int *next)
{
- char *name=NULL;
- char *string;
+ char *name = NULL;
+ const char *string;
int len;
/* look for the end of the <label>= */
- for (string = inString;*string; string++) {
- if (*string == '=') { break; }
- if (NSSUTIL_ArgIsBlank(*string)) break;
+ for (string = inString; *string; string++) {
+ if (*string == '=') {
+ break;
+ }
+ if (NSSUTIL_ArgIsBlank(*string))
+ break;
}
len = string - inString;
- *next = len;
- if (*string == '=') (*next) += 1;
+ *next = len;
+ if (*string == '=')
+ (*next) += 1;
if (len > 0) {
- name = PORT_Alloc(len+1);
- PORT_Strncpy(name,inString,len);
- name[len] = 0;
+ name = PORT_Alloc(len + 1);
+ PORT_Strncpy(name, inString, len);
+ name[len] = 0;
}
return name;
}
@@ -292,24 +329,27 @@ NSSUTIL_ArgGetLabel(char *inString, int *next)
* read an argument at a Long integer
*/
long
-NSSUTIL_ArgReadLong(char *label,char *params, long defValue, PRBool *isdefault)
+NSSUTIL_ArgReadLong(const char *label, const char *params,
+ long defValue, PRBool *isdefault)
{
char *value;
long retValue;
- if (isdefault) *isdefault = PR_FALSE;
+ if (isdefault)
+ *isdefault = PR_FALSE;
- value = NSSUTIL_ArgGetParamValue(label,params);
+ value = NSSUTIL_ArgGetParamValue(label, params);
if (value == NULL) {
- if (isdefault) *isdefault = PR_TRUE;
- return defValue;
+ if (isdefault)
+ *isdefault = PR_TRUE;
+ return defValue;
}
retValue = NSSUTIL_ArgDecodeNumber(value);
- if (value) PORT_Free(value);
+ if (value)
+ PORT_Free(value);
return retValue;
}
-
/*
* prepare a string to be quoted with 'quote' marks. We do that by adding
* appropriate escapes.
@@ -320,13 +360,13 @@ 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++;
+ size = addquotes ? 2 : 0;
+ for (src = string; *src; src++) {
+ if ((*src == quote) || (*src == '\\'))
+ escapes++;
+ size++;
}
- return size+escapes+1;
-
+ return size + escapes + 1;
}
static char *
@@ -339,19 +379,21 @@ nssutil_escapeQuotes(const char *string, char quote, PRBool addquotes)
size = nssutil_escapeQuotesSize(string, quote, addquotes);
- dest = newString = PORT_ZAlloc(size);
+ dest = newString = PORT_ZAlloc(size);
if (newString == NULL) {
- return NULL;
+ return NULL;
}
- if (addquotes) *dest++=quote;
- for (src=string; *src; src++,dest++) {
- if ((*src == '\\') || (*src == quote)) {
- *dest++ = '\\';
- }
- *dest = *src;
+ if (addquotes)
+ *dest++ = quote;
+ for (src = string; *src; src++, dest++) {
+ if ((*src == '\\') || (*src == quote)) {
+ *dest++ = '\\';
+ }
+ *dest = *src;
}
- if (addquotes) *dest=quote;
+ if (addquotes)
+ *dest = quote;
return newString;
}
@@ -359,7 +401,7 @@ nssutil_escapeQuotes(const char *string, char quote, PRBool addquotes)
int
NSSUTIL_EscapeSize(const char *string, char quote)
{
- return nssutil_escapeQuotesSize(string, quote, PR_FALSE);
+ return nssutil_escapeQuotesSize(string, quote, PR_FALSE);
}
char *
@@ -368,11 +410,10 @@ 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);
+ return nssutil_escapeQuotesSize(string, quote, PR_TRUE);
}
char *
@@ -386,14 +427,17 @@ 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 */
+ 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;
+ return escapes + size + 1;
}
char *
@@ -417,7 +461,6 @@ done:
return retValue;
}
-
/************************************************************************
* These functions are used in contructing strings.
* NOTE: they will always return a string, but sometimes it will return
@@ -430,43 +473,48 @@ static char *nssutil_nullString = "";
static char *
nssutil_formatValue(PLArenaPool *arena, char *value, char quote)
{
- char *vp,*vp2,*retval;
+ char *vp, *vp2, *retval;
int size = 0, escapes = 0;
- for (vp=value; *vp ;vp++) {
- if ((*vp == quote) || (*vp == NSSUTIL_ARG_ESCAPE)) escapes++;
- size++;
+ for (vp = value; *vp; vp++) {
+ if ((*vp == quote) || (*vp == NSSUTIL_ARG_ESCAPE))
+ escapes++;
+ size++;
}
if (arena) {
- retval = PORT_ArenaZAlloc(arena,size+escapes+1);
+ retval = PORT_ArenaZAlloc(arena, size + escapes + 1);
} else {
- retval = PORT_ZAlloc(size+escapes+1);
+ retval = PORT_ZAlloc(size + escapes + 1);
}
- if (retval == NULL) return NULL;
+ 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;
+ 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)
+static PRBool
+nssutil_argHasChar(char *v, char c)
{
- for ( ;*v; v++) {
- if (*v == c) return PR_TRUE;
- }
- return PR_FALSE;
+ for (; *v; v++) {
+ if (*v == c)
+ return PR_TRUE;
+ }
+ return PR_FALSE;
}
-static PRBool nssutil_argHasBlanks(char *v)
+static PRBool
+nssutil_argHasBlanks(char *v)
{
- for ( ;*v; v++) {
- if (NSSUTIL_ArgIsBlank(*v)) return PR_TRUE;
- }
- return PR_FALSE;
+ for (; *v; v++) {
+ if (NSSUTIL_ArgIsBlank(*v))
+ return PR_TRUE;
+ }
+ return PR_FALSE;
}
static char *
@@ -478,36 +526,41 @@ nssutil_formatPair(char *name, char *value, char quote)
char *returnValue;
PRBool need_quote = PR_FALSE;
- if (!value || (*value == 0)) return nssutil_nullString;
+ if (!value || (*value == 0))
+ return nssutil_nullString;
if (nssutil_argHasBlanks(value) || NSSUTIL_ArgIsQuote(value[0]))
- need_quote=PR_TRUE;
+ 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 && 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);
+ returnValue = PR_smprintf("%s=%c%s%c", name, openQuote, value, closeQuote);
} else {
- returnValue = PR_smprintf("%s=%s",name,value);
+ returnValue = PR_smprintf("%s=%s", name, value);
}
- if (returnValue == NULL) returnValue = nssutil_nullString;
+ if (returnValue == NULL)
+ returnValue = nssutil_nullString;
- if (newValue) PORT_Free(newValue);
+ if (newValue)
+ PORT_Free(newValue);
return returnValue;
}
-static char *nssutil_formatIntPair(char *name, unsigned long value,
- unsigned long def)
+static char *
+nssutil_formatIntPair(char *name, unsigned long value,
+ unsigned long def)
{
char *returnValue;
- if (value == def) return nssutil_nullString;
+ if (value == def)
+ return nssutil_nullString;
- returnValue = PR_smprintf("%s=%d",name,value);
+ returnValue = PR_smprintf("%s=%d", name, value);
return returnValue;
}
@@ -516,11 +569,10 @@ static void
nssutil_freePair(char *pair)
{
if (pair && pair != nssutil_nullString) {
- PR_smprintf_free(pair);
+ PR_smprintf_free(pair);
}
}
-
/************************************************************************
* Parse the Slot specific parameters in the NSS params.
*/
@@ -531,194 +583,202 @@ struct nssutilArgSlotFlagTable {
unsigned long value;
};
-#define NSSUTIL_ARG_ENTRY(arg,flag) \
-{ #arg , sizeof(#arg)-1, flag }
+#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),
+ 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]);
-
+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)
+NSSUTIL_ArgParseSlotFlags(const char *label, const char *params)
{
- char *flags,*index;
+ char *flags;
+ const char *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;
- }
- }
+ 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)
+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);
+ slotInfo->slotID = NSSUTIL_ArgDecodeNumber(name);
+ slotInfo->defaultFlags = NSSUTIL_ArgParseSlotFlags("slotFlags", params);
+ slotInfo->timeout = NSSUTIL_ArgReadLong("timeout", params, 0, NULL);
- askpw = NSSUTIL_ArgGetParamValue("askpw",params);
+ 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);
+ 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(PLArenaPool *arena, char *slotParams, int *retCount)
+NSSUTIL_ArgParseSlotInfo(PLArenaPool *arena, const char *slotParams,
+ int *retCount)
{
- char *slotIndex;
+ const char *slotIndex;
struct NSSUTILPreSlotInfoStr *slotInfo = NULL;
- int i=0,count = 0,next;
+ int i = 0, count = 0, next;
*retCount = 0;
- if ((slotParams == NULL) || (*slotParams == 0)) return NULL;
+ 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++;
+ 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);
+ 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);
+ 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
+ * 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 & (1UL <<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);
- }
- }
- }
+ char *flags = NULL;
+ unsigned int i;
+ int j;
+
+ for (i = 0; i < sizeof(defaultFlags) * 8; i++) {
+ if (defaultFlags & (1UL << 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")
+#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);
+ char *flags = (char *)PORT_ZAlloc(NSSUTIL_MAX_ROOT_FLAG_SIZE);
PRBool first = PR_TRUE;
- PORT_Memset(flags,0,NSSUTIL_MAX_ROOT_FLAG_SIZE);
+ PORT_Memset(flags, 0, NSSUTIL_MAX_ROOT_FLAG_SIZE);
if (hasRootCerts) {
- PORT_Strcat(flags,"hasRootCerts");
- first = PR_FALSE;
+ PORT_Strcat(flags, "hasRootCerts");
+ first = PR_FALSE;
}
if (hasRootTrust) {
- if (!first) PORT_Strcat(flags,",");
- PORT_Strcat(flags,"hasRootTrust");
- first = PR_FALSE;
+ if (!first)
+ PORT_Strcat(flags, ",");
+ PORT_Strcat(flags, "hasRootTrust");
}
return flags;
}
@@ -726,50 +786,52 @@ nssutil_mkRootFlags(PRBool hasRootCerts, PRBool hasRootTrust)
/* 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;
-
+ 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;
+ 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);
+ 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);
+ 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);
+ 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_ArgParseModuleSpecEx(char *modulespec, char **lib, char **mod,
- char **parameters, char **nss,
- char **config)
+NSSUTIL_ArgParseModuleSpecEx(const char *modulespec, char **lib, char **mod,
+ char **parameters, char **nss,
+ char **config)
{
int next;
modulespec = NSSUTIL_ArgStrip(modulespec);
@@ -777,14 +839,14 @@ NSSUTIL_ArgParseModuleSpecEx(char *modulespec, char **lib, char **mod,
*lib = *mod = *parameters = *nss = *config = 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_STRING_ARG(modulespec,*config,"config=",;)
- NSSUTIL_HANDLE_FINAL_ARG(modulespec)
- }
- return SECSuccess;
+ 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_STRING_ARG(modulespec, *config, "config=", ;)
+ NSSUTIL_HANDLE_FINAL_ARG(modulespec)
+ }
+ return SECSuccess;
}
/************************************************************************
@@ -792,8 +854,8 @@ NSSUTIL_ArgParseModuleSpecEx(char *modulespec, char **lib, char **mod,
* and NSS specifi parameters.
*/
SECStatus
-NSSUTIL_ArgParseModuleSpec(char *modulespec, char **lib, char **mod,
- char **parameters, char **nss)
+NSSUTIL_ArgParseModuleSpec(const char *modulespec, char **lib, char **mod,
+ char **parameters, char **nss)
{
int next;
modulespec = NSSUTIL_ArgStrip(modulespec);
@@ -801,38 +863,38 @@ NSSUTIL_ArgParseModuleSpec(char *modulespec, char **lib, char **mod,
*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;
+ 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_MkModuleSpecEx(char *dllName, char *commonName, char *parameters,
- char *NSS,
- char *config)
+NSSUTIL_MkModuleSpecEx(char *dllName, char *commonName, char *parameters,
+ char *NSS,
+ char *config)
{
char *moduleSpec;
- char *lib,*name,*param,*nss,*conf;
+ char *lib, *name, *param, *nss, *conf;
/*
* now the final spec
*/
- lib = nssutil_formatPair("library",dllName,'\"');
- name = nssutil_formatPair("name",commonName,'\"');
- param = nssutil_formatPair("parameters",parameters,'\"');
- nss = nssutil_formatPair("NSS",NSS,'\"');
+ lib = nssutil_formatPair("library", dllName, '\"');
+ name = nssutil_formatPair("name", commonName, '\"');
+ param = nssutil_formatPair("parameters", parameters, '\"');
+ nss = nssutil_formatPair("NSS", NSS, '\"');
if (config) {
- conf = nssutil_formatPair("config",config,'\"');
- moduleSpec = PR_smprintf("%s %s %s %s %s", lib,name,param,nss,conf);
+ conf = nssutil_formatPair("config", config, '\"');
+ moduleSpec = PR_smprintf("%s %s %s %s %s", lib, name, param, nss, conf);
nssutil_freePair(conf);
} else {
- moduleSpec = PR_smprintf("%s %s %s %s", lib,name,param,nss);
+ moduleSpec = PR_smprintf("%s %s %s %s", lib, name, param, nss);
}
nssutil_freePair(lib);
nssutil_freePair(name);
@@ -844,121 +906,122 @@ NSSUTIL_MkModuleSpecEx(char *dllName, char *commonName, char *parameters,
/************************************************************************
* make a new module spec from it's components */
char *
-NSSUTIL_MkModuleSpec(char *dllName, char *commonName, char *parameters,
- char *NSS)
+NSSUTIL_MkModuleSpec(char *dllName, char *commonName, char *parameters,
+ char *NSS)
{
return NSSUTIL_MkModuleSpecEx(dllName, commonName, parameters, NSS, NULL);
}
-
#define NSSUTIL_ARG_FORTEZZA_FLAG "FORTEZZA"
/******************************************************************************
* Parse the cipher flags from the NSS parameter
*/
void
-NSSUTIL_ArgParseCipherFlags(unsigned long *newCiphers,char *cipherList)
+NSSUTIL_ArgParseCipherFlags(unsigned long *newCiphers, const 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]);
- }
- }
+ 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")
+#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)
+ 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);
+ PORT_Memset(flags, 0, MAX_FLAG_SIZE);
if (internal) {
- PORT_Strcat(flags,"internal");
- first = PR_FALSE;
+ PORT_Strcat(flags, "internal");
+ first = PR_FALSE;
}
if (isFIPS) {
- if (!first) PORT_Strcat(flags,",");
- PORT_Strcat(flags,"FIPS");
- first = PR_FALSE;
+ 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 (!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 (!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;
+ if (!first)
+ PORT_Strcat(flags, ",");
+ PORT_Strcat(flags, "critical");
}
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 & (1UL <<i)) {
- char *string;
- if ((1UL <<i) == SECMOD_FORTEZZA_FLAG) {
- string = PR_smprintf("%s",NSSUTIL_ARG_FORTEZZA_FLAG);
- } else {
- string = PR_smprintf("0h0x%08lx", 1UL <<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 & (1UL <<i)) {
- if (cipher) {
- char *tmp;
- tmp = PR_smprintf("%s,0l0x%08lx",cipher, 1UL <<i);
- PR_smprintf_free(cipher);
- cipher = tmp;
- } else {
- cipher = PR_smprintf("0l0x%08lx", 1UL <<i);
- }
- }
+ unsigned int i;
+
+ for (i = 0; i < sizeof(ssl0) * 8; i++) {
+ if (ssl0 & (1UL << i)) {
+ char *string;
+ if ((1UL << i) == SECMOD_FORTEZZA_FLAG) {
+ string = PR_smprintf("%s", NSSUTIL_ARG_FORTEZZA_FLAG);
+ } else {
+ string = PR_smprintf("0h0x%08lx", 1UL << 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 & (1UL << i)) {
+ if (cipher) {
+ char *tmp;
+ tmp = PR_smprintf("%s,0l0x%08lx", cipher, 1UL << i);
+ PR_smprintf_free(cipher);
+ cipher = tmp;
+ } else {
+ cipher = PR_smprintf("0l0x%08lx", 1UL << i);
+ }
+ }
}
return cipher;
@@ -966,54 +1029,57 @@ nssutil_mkCipherFlags(unsigned long ssl0, unsigned long ssl1)
/* 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)
+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;
-
+ char *slotParams, *ciphers, *nss, *nssFlags;
+ const char *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 = 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;
- }
-
+ 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 */
+ 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);
+ 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);
@@ -1021,8 +1087,8 @@ NSSUTIL_MkNSSString(char **slotStrings, int slotCount, PRBool internal,
nssutil_freePair(flagPair);
tmp = NSSUTIL_ArgStrip(nss);
if (*tmp == '\0') {
- PR_smprintf_free(nss);
- nss = NULL;
+ PR_smprintf_free(nss);
+ nss = NULL;
}
return nss;
}
@@ -1038,10 +1104,11 @@ NSSUTIL_MkNSSString(char **slotStrings, int slotCount, PRBool internal,
#define MULTIACCESS "multiaccess:"
#define SECMOD_DB "secmod.db"
const char *
-_NSSUTIL_EvaluateConfigDir(const char *configdir,
- NSSDBType *pdbType, char **appName)
+_NSSUTIL_EvaluateConfigDir(const char *configdir,
+ NSSDBType *pdbType, char **appName)
{
NSSDBType dbType;
+ PRBool checkEnvDefaultDB = PR_FALSE;
*appName = NULL;
/* force the default */
#ifdef NSS_DISABLE_DBM
@@ -1049,110 +1116,116 @@ _NSSUTIL_EvaluateConfigDir(const char *configdir,
#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;
+ if (configdir == NULL) {
+ checkEnvDefaultDB = PR_TRUE;
+ } else 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;
- }
- }
+ checkEnvDefaultDB = PR_TRUE;
+ }
+
+ /* look up the default from the environment */
+ if (checkEnvDefaultDB) {
+ char *defaultType = PR_GetEnvSecure("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;
+ *pdbType = dbType;
}
return configdir;
}
char *
-_NSSUTIL_GetSecmodName(char *param, NSSDBType *dbType, char **appName,
- char **filename, PRBool *rw)
+_NSSUTIL_GetSecmodName(const 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 *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;
+ 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;
- }
-
- /* 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;
-}
+ }
+ 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) &&
+ !NSSUTIL_ArgHasFlag("flags", "forceSecmodChoice", save_params)) {
+ 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/nss/lib/util/utilpars.h b/nss/lib/util/utilpars.h
index 7562bb6..7076726 100644
--- a/nss/lib/util/utilpars.h
+++ b/nss/lib/util/utilpars.h
@@ -9,19 +9,20 @@
#include "plarena.h"
/* handle a module db request */
-char ** NSSUTIL_DoModuleDBFunction(unsigned long function,char *parameters, void *args);
+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);
+char *NSSUTIL_ArgFetchValue(const char *string, int *pcount);
+const char *NSSUTIL_ArgStrip(const char *c);
+char *NSSUTIL_ArgGetParamValue(const char *paramName, const char *parameters);
+const char *NSSUTIL_ArgSkipParameter(const char *string);
+char *NSSUTIL_ArgGetLabel(const char *inString, int *next);
+long NSSUTIL_ArgDecodeNumber(const 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);
+PRBool NSSUTIL_ArgHasFlag(const char *label, const char *flag,
+ const char *parameters);
+long NSSUTIL_ArgReadLong(const char *label, const char *params, long defValue,
+ PRBool *isdefault);
/* quoting functions */
int NSSUTIL_EscapeSize(const char *string, char quote);
@@ -31,30 +32,32 @@ 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);
+unsigned long NSSUTIL_ArgParseSlotFlags(const char *label, const char *params);
struct NSSUTILPreSlotInfoStr *NSSUTIL_ArgParseSlotInfo(PLArenaPool *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);
-SECStatus NSSUTIL_ArgParseModuleSpecEx(char *modulespec, char **lib, char **mod,
- char **parameters, char **nss, char **config);
-char *NSSUTIL_MkModuleSpec(char *dllName, char *commonName,
- char *parameters, char *NSS);
-char *NSSUTIL_MkModuleSpecEx(char *dllName, char *commonName,
- char *parameters, char *NSS, char *config);
-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);
+ const 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(const char *modulespec, char **lib,
+ char **mod, char **parameters, char **nss);
+SECStatus NSSUTIL_ArgParseModuleSpecEx(const char *modulespec, char **lib,
+ char **mod, char **parameters, char **nss, char **config);
+char *NSSUTIL_MkModuleSpec(char *dllName, char *commonName,
+ char *parameters, char *NSS);
+char *NSSUTIL_MkModuleSpecEx(char *dllName, char *commonName,
+ char *parameters, char *NSS, char *config);
+void NSSUTIL_ArgParseCipherFlags(unsigned long *newCiphers,
+ const 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);
+char *_NSSUTIL_GetSecmodName(const 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/nss/lib/util/utilparst.h b/nss/lib/util/utilparst.h
index 01d87ad..f2148e6 100644
--- a/nss/lib/util/utilparst.h
+++ b/nss/lib/util/utilparst.h
@@ -2,13 +2,13 @@
* License, v. 2.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
+#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
+ * 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
@@ -17,60 +17,62 @@
* 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 ;\
+#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_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_INIT1 \
+ "library= name=\"NSS Internal PKCS #11 Module\" parameters="
#define NSSUTIL_DEFAULT_INTERNAL_INIT2 \
- " NSS=\"Flags=internal,critical trustOrder=75 cipherOrder=100 slotParams=(1={"
+ " NSS=\"Flags=internal,critical trustOrder=75 cipherOrder=100 slotParams=(1={"
#define NSSUTIL_DEFAULT_INTERNAL_INIT3 \
- " askpw=any timeout=30})\""
+ " 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]"
+ "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 */
+ 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];
+ * 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
+ 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/nss/lib/util/verref.h b/nss/lib/util/verref.h
index 2d141bb..efbcb03 100644
--- a/nss/lib/util/verref.h
+++ b/nss/lib/util/verref.h
@@ -15,7 +15,7 @@
/* Suppress unused variable warnings. */
#ifdef _MSC_VER
#pragma warning(push)
-#pragma warning(disable: 4101)
+#pragma warning(disable : 4101)
#endif
/* This works for both gcc and clang */
#if defined(__GNUC__) && !defined(NSS_NO_GCC48)
@@ -28,6 +28,9 @@
#endif
{
extern const char NSS_VERSION_VARIABLE[];
+#if defined(__GNUC__)
+ __attribute__((unused))
+#endif
volatile const char _nss_version_c = NSS_VERSION_VARIABLE[0];
}
#undef NSS_VERSION_VARIABLE
diff --git a/nss/lib/zlib/exports.gyp b/nss/lib/zlib/exports.gyp
new file mode 100644
index 0000000..b557218
--- /dev/null
+++ b/nss/lib/zlib/exports.gyp
@@ -0,0 +1,33 @@
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+{
+ 'includes': [
+ '../../coreconf/config.gypi'
+ ],
+ 'variables': {
+ 'module': 'nss',
+ },
+ 'conditions': [
+ ['use_system_zlib==1', {
+ 'targets': [{
+ 'target_name': 'lib_zlib_exports',
+ 'type': 'none',
+ }],
+ }, {
+ 'targets': [{
+ 'target_name': 'lib_zlib_exports',
+ 'type': 'none',
+ 'copies': [
+ {
+ 'files': [
+ 'zlib.h',
+ 'zconf.h',
+ ],
+ 'destination': '<(nss_private_dist_dir)/<(module)'
+ }
+ ]
+ }],
+ }],
+ ],
+}
diff --git a/nss/lib/zlib/zlib.gyp b/nss/lib/zlib/zlib.gyp
new file mode 100644
index 0000000..c89dbd9
--- /dev/null
+++ b/nss/lib/zlib/zlib.gyp
@@ -0,0 +1,49 @@
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+{
+ 'includes': [
+ "../../coreconf/config.gypi"
+ ],
+ 'variables': {
+ 'module': 'nss',
+ },
+ 'conditions': [
+ ['use_system_zlib==1', {
+ 'targets': [{
+ 'target_name': 'nss_zlib',
+ 'type': 'none',
+ 'link_settings': {
+ 'libraries': ['<@(zlib_libs)'],
+ },
+ }],
+ }, {
+ 'targets': [{
+ 'target_name': 'nss_zlib',
+ 'type': 'static_library',
+ 'sources': [
+ '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',
+ ],
+ 'defines': [
+ # Define verbose as -1 to turn off all zlib trace messages in
+ # debug builds.
+ 'verbose=-1',
+ ],
+ }],
+ }]
+ ],
+}